From b3cfa3431db02413a8e6b0e44c02c8945e08fc81 Mon Sep 17 00:00:00 2001 From: "Liu, Ruokun" Date: Tue, 9 Dec 2014 20:47:55 -0800 Subject: [PATCH 0001/2165] Initial branch. [git-p4: depot-paths = "//mrl/sw/intel/": change = 308528] --- async-toolkit/jtools/cad/all/all.package | 37 + .../jtools/cad/all/javafiles-custom.mk | 23 + .../cadence/virtuoso/assura.package | 14 + .../cadence/virtuoso/cdsp4.package | 20 + .../virtuoso/dfII_split_subtypes.package | 17 + .../virtuoso/doc/updatenetlist/calls.dot | 138 + .../virtuoso/doc/updatenetlist/index.html | 450 + .../cadence/virtuoso/fulcrum_cds_setup.inc | 58 + .../cadence/virtuoso/gdsIIWrite.package | 52 + .../cadence/virtuoso/javafiles-custom.mk | 23 + .../cadence/virtuoso/lefdef.package | 27 + .../cadence/virtuoso/mk_instance.package | 15 + .../cadence/virtuoso/nano.package | 45 + .../cadence/virtuoso/script/perl/cdl2snp.pl | 229 + .../virtuoso/script/perl/checkpgvia.pl | 432 + .../cadence/virtuoso/script/perl/cmpdef.pl | 695 ++ .../cadence/virtuoso/script/perl/dangling.pl | 210 + .../virtuoso/script/perl/def_rename.pl | 147 + .../cadence/virtuoso/script/perl/dfIIhier.pl | 177 + .../cadence/virtuoso/script/perl/gds2cdl.pl | 167 + .../cadence/virtuoso/script/perl/importGDS.pl | 681 ++ .../cadence/virtuoso/script/perl/importQ.pl | 1379 +++ .../cadence/virtuoso/script/perl/lef2rp.pl | 118 + .../virtuoso/script/perl/lef_rename.pl | 100 + .../virtuoso/script/perl/mk_instance_multi.pl | 135 + .../cadence/virtuoso/script/perl/mkhvt.pl | 41 + .../cadence/virtuoso/script/perl/mkhvt_all.pl | 206 + .../cadence/virtuoso/script/perl/mklvt.pl | 41 + .../cadence/virtuoso/script/perl/mksvt.pl | 189 + .../cadence/virtuoso/script/perl/mosaicify.pl | 179 + .../script/perl/nano/createAbstract.pl | 938 ++ .../script/perl/nano/createAbstractCellLog.pl | 410 + .../virtuoso/script/perl/nano/defNets.pl | 207 + .../script/perl/nano/exportDesignLef.pl | 1225 +++ .../virtuoso/script/perl/nano/genTracks.pl | 406 + .../script/perl/nano/initNanoroute.pl | 702 ++ .../script/perl/nano/listMissingAbstracts.pl | 426 + .../virtuoso/script/perl/plotdensity.pl | 436 + .../cadence/virtuoso/script/perl/signoff.pl | 54 + .../virtuoso/script/perl/util/cdl2cast2 | 1025 ++ .../virtuoso/script/perl/util/compilemem.pl | 789 ++ .../virtuoso/script/perl/util/fixcdl.pl | 351 + .../virtuoso/script/perl/util/fixgds.pl | 74 + .../script/perl/util/fixportdirection | 259 + .../script/perl/util/gen_sram_scan_wrap.pl | 212 + .../virtuoso/script/perl/util/importIP.pl | 680 ++ .../virtuoso/script/perl/util/importSR.pl | 700 ++ .../virtuoso/script/perl/ve/back-end/Lvbe.pm | 278 + .../perl/ve/back-end/LvbeAlwaysError.pm | 24 + .../script/perl/ve/back-end/LvbeAssura.pm | 527 + .../script/perl/ve/back-end/LvbeAssuraDrc.pm | 56 + .../script/perl/ve/back-end/LvbeAssuraLvs.pm | 56 + .../script/perl/ve/back-end/LvbeAssuraNvn.pm | 56 + .../script/perl/ve/back-end/LvbeDrc.pm | 53 + .../script/perl/ve/back-end/LvbeLvs.pm | 54 + .../script/perl/ve/back-end/LvbeSignOff.pm | 214 + .../perl/ve/back-end/LvbeSignOffInclude.pm | 38 + .../virtuoso/script/perl/ve/front-end/Lvfe.pm | 395 + .../virtuoso/script/perl/ve/front-end/vfe | 312 + .../virtuoso/script/perl/ve/ve.package | 21 + .../virtuoso/script/perl/vs2calibre.pl | 890 ++ .../cadence/virtuoso/script/perl/vs2cast.pl | 3110 ++++++ .../cadence/virtuoso/script/perl/vs2et.pl | 232 + .../sh/cell-automation/lib_commands/getlibs | 30 + .../sh/cell-automation/lib_commands/mkcdslib | 157 + .../sh/cell-automation/lib_commands/mkcdslibs | 126 + .../multi_cell_commands/custom.mk | 10 + .../multi_cell_commands/density.sh | 207 + .../multi_cell_commands/dfIIflat2tree.sh | 134 + .../multi_cell_commands/gen_abstract_views.sh | 328 + .../gen_instantiator_views.sh | 347 + .../multi_cell_commands/gen_leaf_cells.sh | 527 + .../multi_cell_commands/gen_mid_cells.sh | 212 + .../multi_cell_commands/updatenetlist.sh | 566 ++ .../one_cell_commands/Tapeout.pl | 808 ++ .../one_cell_commands/cdlsize265.pl | 87 + .../one_cell_commands/ensurecelllib | 125 + .../one_cell_commands/gdsIIWrite.pl | 1204 +++ .../one_cell_commands/genIP.sh | 748 ++ .../one_cell_commands/size265.pl | 309 + .../one_cell_commands/writegds | 236 + .../templates/leaf_cell.il.template | 228 + .../script/sh/floorplan/initFloorplan.sh | 263 + .../virtuoso/script/sh/lefdef/lefdefWrite.sh | 269 + .../script/sh/nano/createFlattenView.sh | 275 + .../script/sh/nano/exportDesignDef.sh | 282 + .../cadence/virtuoso/script/sh/p4/cdsp4.sh | 266 + .../cadence/virtuoso/script/sh/p4/cdsp4add.sh | 430 + .../virtuoso/script/sh/p4/cdsp4addlibs.sh | 285 + .../virtuoso/script/sh/p4/cdsp4celllog.sh | 176 + .../virtuoso/script/sh/p4/cdsp4delete.sh | 234 + .../virtuoso/script/sh/p4/cdsp4edit.sh | 272 + .../virtuoso/script/sh/p4/cdsp4opened.sh | 207 + .../virtuoso/script/sh/p4/cdsp4revert.sh | 249 + .../virtuoso/script/sh/p4/cdsp4smartedit.sh | 417 + .../virtuoso/script/sh/p4/cdsp4submit.sh | 122 + .../virtuoso/script/sh/p4/cdsp4sync.sh | 306 + .../script/sh/p4/change_list_template.txt | 26 + .../virtuoso/script/sh/p4/gen_branch_spec.sh | 156 + .../virtuoso/script/sh/setup/cds_wd.package | 11 + .../cds_wd_default_template/assura_tech.lib | 1 + .../cds_wd_default_template/autoload/bindkeys | 0 .../setup/cds_wd_default_template/display.drf | 2106 ++++ .../cds_wd_default_template/usermenu/.menu | 1 + .../virtuoso/script/sh/setup/fakelib.sh | 19 + .../virtuoso/script/sh/setup/lmwait.pl | 111 + .../virtuoso/script/sh/setup/mkcdswd.sh | 292 + .../virtuoso/script/sh/setup/runincdswd.sh | 83 + .../sh/subtyping/dfII_split_subtypes.sh | 317 + .../script/sh/util/findclosestwithlayout.sh | 177 + .../virtuoso/script/sh/util/importPR.sh | 819 ++ .../virtuoso/script/sh/util/mk_instance | 116 + .../cadence/virtuoso/script/sh/util/mkcdslib | 179 + .../virtuoso/script/sh/util/mktestcase | 493 + .../virtuoso/script/sh/util/parsecellname | 504 + .../virtuoso/script/sh/util/verilog2cdl.sh | 225 + .../cadence/virtuoso/script/sh/util/vip.sh | 28 + .../virtuoso/script/sh/vnc/.fvwm2/Main-8-bit | 643 ++ .../virtuoso/script/sh/vnc/.vnc/xstartup | 4 + .../virtuoso/script/sh/vnc/getvncserver.sh | 38 + .../cadence/virtuoso/script/sh/vnc/nograph.sh | 38 + .../cadence/virtuoso/skill/gen_autoload | 143 + .../virtuoso/skill/layout/aspice/aspice.il | 427 + .../virtuoso/skill/layout/assura/area.rul | 64 + .../virtuoso/skill/layout/assura/assura.il | 880 ++ .../virtuoso/skill/layout/assura/drc.il | 90 + .../virtuoso/skill/layout/assura/lvs.il | 54 + .../cadence/virtuoso/skill/layout/bus/bus.il | 1933 ++++ .../virtuoso/skill/layout/bus/bus28.il | 151 + .../virtuoso/skill/layout/bus/bus65.il | 114 + .../cadence/virtuoso/skill/layout/bus/fat.il | 980 ++ .../cadence/virtuoso/skill/layout/bus/obs.il | 142 + .../virtuoso/skill/layout/bus/patterns.il | 135 + .../virtuoso/skill/layout/bus/shield.il | 486 + .../cadence/virtuoso/skill/layout/bus/util.il | 679 ++ .../virtuoso/skill/layout/cable/GndSheild.il | 98 + .../skill/layout/cable/Obstruction.il | 85 + .../virtuoso/skill/layout/cable/cdc_insts.txt | 76 + .../virtuoso/skill/layout/cable/optimus.il | 25 + .../virtuoso/skill/layout/cable/placer.il | 416 + .../skill/layout/cable/routedbuffers.il | 364 + .../virtuoso/skill/layout/cable/router.il | 759 ++ .../skill/layout/cable/sync_placer.il | 800 ++ .../virtuoso/skill/layout/cable/templates.il | 539 + .../virtuoso/skill/layout/cable/util.il | 1156 +++ .../virtuoso/skill/layout/cell/cellinfo.il | 151 + .../virtuoso/skill/layout/cell/constraints.il | 307 + .../virtuoso/skill/layout/chain/chain.il | 227 + .../skill/layout/chain/compactsuperstacks.il | 380 + .../skill/layout/chain/componentinfo.il | 366 + .../skill/layout/chain/createsuperstacks.il | 58 + .../virtuoso/skill/layout/chain/domain.il | 212 + .../virtuoso/skill/layout/chain/domino.il | 472 + .../skill/layout/chain/foldandchain.il | 82 + .../virtuoso/skill/layout/chain/group.il | 416 + .../skill/layout/chain/inlinesuperstacks.il | 46 + .../virtuoso/skill/layout/chain/refold.il | 407 + .../virtuoso/skill/layout/chain/superstack.il | 609 ++ .../skill/layout/chain/superstack_tools.il | 882 ++ .../virtuoso/skill/layout/chain/unstack.il | 495 + .../virtuoso/skill/layout/density/density.il | 543 + .../virtuoso/skill/layout/distort/distort.il | 1471 +++ .../cadence/virtuoso/skill/layout/fig/fig.il | 130 + .../skill/layout/filler/SpareCellFill.il | 239 + .../virtuoso/skill/layout/filler/filler.il | 476 + .../virtuoso/skill/layout/filler/filler.txt | 118 + .../skill/layout/floorplanning/align.il | 474 + .../skill/layout/floorplanning/anchor.il | 115 + .../floorplanning/floorplanTemplating.il | 139 + .../floorplanning/import/getcellmappings.il | 96 + .../floorplanning/import/importfloorplan.il | 495 + .../layout/floorplanning/initFloorplan.il | 202 + .../skill/layout/floorplanning/optimizeXY.il | 99 + .../layout/floorplanning/resolveOverlap.il | 858 ++ .../layout/floorplanning/updatefloorplan.il | 430 + .../layout/floorplanning/updatefromlayout.il | 93 + .../skill/layout/floorplanning/util.il | 90 + .../skill/layout/fulcrum_setup/AlignCells.il | 55 + .../fulcrum_setup/AlignCellsDataPath.il | 149 + .../fulcrum_setup/AlignCellsNonOverlap.il | 70 + .../layout/fulcrum_setup/AnalysisLayout.il | 333 + .../layout/fulcrum_setup/CompactCells.il | 900 ++ .../skill/layout/fulcrum_setup/DrawIO.il | 1669 ++++ .../layout/fulcrum_setup/DrawWellPlugs.il | 280 + .../layout/fulcrum_setup/ExtraBasicSkills.il | 540 + .../skill/layout/fulcrum_setup/FL_Overlap.il | 53 + .../layout/fulcrum_setup/FloorplanCells.il | 273 + .../layout/fulcrum_setup/Floorplanner.il | 178 + .../skill/layout/fulcrum_setup/FulcrumLoad.il | 29 + .../layout/fulcrum_setup/FulcrumSetup.il | 130 + .../skill/layout/fulcrum_setup/GetOverlaps.il | 45 + .../layout/fulcrum_setup/GlobalHiliteStack.il | 67 + .../skill/layout/fulcrum_setup/IO.input.x6 | 1303 +++ .../layout/fulcrum_setup/IO.input.x6.alias | 861 ++ .../skill/layout/fulcrum_setup/IO.map.x6 | 88 + .../skill/layout/fulcrum_setup/M_Floorplan.il | 31 + .../skill/layout/fulcrum_setup/M_Main.il | 64 + .../skill/layout/fulcrum_setup/M_Verify.il | 49 + .../layout/fulcrum_setup/ManageWindows.il | 35 + .../layout/fulcrum_setup/MapConnectivity.il | 91 + .../skill/layout/fulcrum_setup/MoveToSnap.il | 169 + .../skill/layout/fulcrum_setup/PathFinder.il | 724 ++ .../layout/fulcrum_setup/SelectSameMaster.il | 36 + .../fulcrum_setup/SetDeleteViewLevels.il | 38 + .../skill/layout/fulcrum_setup/SetSnapping.il | 74 + .../skill/layout/fulcrum_setup/ShowName.il | 50 + .../layout/fulcrum_setup/StandardBindKeys.il | 15 + .../layout/fulcrum_setup/TR_ChangeInstName.il | 67 + .../layout/fulcrum_setup/TR_CountNets.il | 171 + .../skill/layout/fulcrum_setup/TR_CrawFish.il | 97 + .../skill/layout/fulcrum_setup/TR_DrawIO.il | 2397 +++++ .../fulcrum_setup/TR_DrawIO_Globals_x6.il | 175 + .../skill/layout/fulcrum_setup/TR_DrawPins.il | 1199 +++ .../fulcrum_setup/TR_ExtendConnDepth.il | 186 + .../layout/fulcrum_setup/TR_FindInstance.il | 227 + .../layout/fulcrum_setup/TR_FloorplanArray.il | 241 + .../layout/fulcrum_setup/TR_Floorplanner.il | 1156 +++ .../fulcrum_setup/TR_GenerateBindingFile.il | 91 + .../fulcrum_setup/TR_GetManhattanDistance.il | 98 + .../layout/fulcrum_setup/TR_HiLiteLabels.il | 336 + .../layout/fulcrum_setup/TR_MoveAndSnap.il | 504 + .../skill/layout/fulcrum_setup/TrackRouter.il | 882 ++ .../skill/layout/fulcrum_setup/trZoom.il | 183 + .../virtuoso/skill/layout/gdsII/gdsIIhier.il | 1527 +++ .../layout/genfromsource/genfromsource.il | 85 + .../virtuoso/skill/layout/geometry/area.il | 283 + .../virtuoso/skill/layout/geometry/bbox.il | 160 + .../virtuoso/skill/layout/geometry/corner.il | 48 + .../virtuoso/skill/layout/geometry/fig.il | 68 + .../virtuoso/skill/layout/geometry/line.il | 311 + .../virtuoso/skill/layout/geometry/path.il | 153 + .../virtuoso/skill/layout/geometry/point.il | 30 + .../virtuoso/skill/layout/geometry/polygon.il | 840 ++ .../virtuoso/skill/layout/geometry/range.il | 173 + .../virtuoso/skill/layout/geometry/rect.il | 791 ++ .../skill/layout/geometry/segmenttree.il | 165 + .../virtuoso/skill/layout/hand/checklength.il | 625 ++ .../virtuoso/skill/layout/hand/deletepins.il | 17 + .../virtuoso/skill/layout/hand/length.il | 252 + .../virtuoso/skill/layout/hand/rectonpitch.il | 132 + .../virtuoso/skill/layout/hand/wiring.il | 349 + .../skill/layout/hierarchy/hierarchy.il | 805 ++ .../virtuoso/skill/layout/hierarchy/inline.il | 363 + .../skill/layout/hierarchy/instance.il | 88 + .../skill/layout/hierarchy/instantiator.il | 516 + .../virtuoso/skill/layout/import/fp.il | 100 + .../virtuoso/skill/layout/import/import.il | 215 + .../skill/layout/instancesfile/instance.il | 175 + .../virtuoso/skill/layout/keepout/abstract.il | 758 ++ .../virtuoso/skill/layout/keepout/bus.il | 1882 ++++ .../virtuoso/skill/layout/keepout/bus28.il | 151 + .../virtuoso/skill/layout/keepout/bus65.il | 114 + .../skill/layout/keepout/conductor.il | 276 + .../layout/keepout/drawdirectivekeepout.il | 37 + .../virtuoso/skill/layout/keepout/fat.il | 980 ++ .../virtuoso/skill/layout/keepout/keepout.il | 709 ++ .../virtuoso/skill/layout/keepout/obs.il | 142 + .../virtuoso/skill/layout/keepout/patterns.il | 135 + .../virtuoso/skill/layout/keepout/shield.il | 444 + .../virtuoso/skill/layout/keepout/util.il | 679 ++ .../virtuoso/skill/layout/laygen/import.il | 219 + .../virtuoso/skill/layout/laygen/pr.il | 117 + .../virtuoso/skill/layout/leaf/AddBlkCell.il | 91 + .../skill/layout/leaf/BufferCreator.il | 5047 ++++++++++ .../skill/layout/leaf/BufferCreatorTwo.il | 1149 +++ .../skill/layout/leaf/CtreeGenerator.il | 680 ++ .../virtuoso/skill/layout/leaf/DrawImplant.il | 788 ++ .../virtuoso/skill/layout/leaf/Implant.il | 653 ++ .../skill/layout/leaf/LayoutGridPoly.il | 274 + .../skill/layout/leaf/decompact/decompact.il | 282 + .../layout/leaf/decompact/spacestacks.il | 153 + .../virtuoso/skill/layout/leaf/fill.il | 70 + .../skill/layout/leaf/implant/drawimplant.il | 244 + .../leaf/implant/findplugingateinstance.il | 126 + .../virtuoso/skill/layout/leaf/lvsnodes.il | 64 + .../virtuoso/skill/layout/leaf/open.il | 53 + .../skill/layout/leaf/placer/foldgates.il | 71 + .../skill/layout/leaf/placer/foldgates.rp | 31 + .../leaf/placer/guessplacementregions.il | 108 + .../skill/layout/leaf/placer/initnp.il | 243 + .../skill/layout/leaf/placer/npsearch.il | 949 ++ .../layout/leaf/placer/placementregions.il | 843 ++ .../skill/layout/leaf/placer/placer.il | 202 + .../skill/layout/leaf/placer/placer.pl | 49 + .../skill/layout/leaf/placer/placercheck.il | 33 + .../skill/layout/leaf/placer/placerhack.il | 426 + .../skill/layout/leaf/placer/placersearch.il | 88 + .../skill/layout/leaf/placer/placersearch.rpl | 36 + .../layout/leaf/placer/placersearchdone.il | 246 + .../skill/layout/leaf/placer/runplacer.il | 155 + .../skill/layout/leaf/placer/runplacer.inst | 39 + .../skill/layout/leaf/placer/runplacer.sh | 260 + .../skill/layout/leaf/placer/squish.il | 336 + .../skill/layout/leaf/plugs/addplugs.il | 133 + .../layout/leaf/plugs/connectwellplugs.il | 46 + .../virtuoso/skill/layout/leaf/plugs/plugs.il | 574 ++ .../skill/layout/leaf/plugs/wellplugsoff.il | 32 + .../virtuoso/skill/layout/leaf/property.il | 85 + .../skill/layout/leaf/removeinvalidlayers.il | 20 + .../layout/leaf/router/PreroutePowerVia.il | 77 + .../skill/layout/leaf/router/checkpolygons.il | 34 + .../layout/leaf/router/delextrapolycontact.il | 81 + .../skill/layout/leaf/router/importccar.sh | 66 + .../skill/layout/leaf/router/lvsnodes.il | 21 + .../skill/layout/leaf/router/router.il | 253 + .../skill/layout/leaf/router/routercheck.il | 75 + .../skill/layout/leaf/router/routersearch.il | 80 + .../layout/leaf/router/routersearchdone.il | 290 + .../layout/leaf/router/routersearchinit.il | 44 + .../skill/layout/leaf/router/routerwidth.il | 171 + .../skill/layout/leaf/router/runccar.sh | 270 + .../skill/layout/leaf/router/runrouter.il | 40 + .../skill/layout/leaf/router/setglcparams.il | 54 + .../skill/layout/leaf/router/snapFatPins.il | 52 + .../skill/layout/leaf/router/swapvias.il | 175 + .../virtuoso/skill/layout/leaf/template.il | 49 + .../skill/layout/leaf/well/drawregionwell.il | 34 + .../skill/layout/leaf/well/regionwell.il | 125 + .../skill/layout/lefdef/apr_lefdef.il | 494 + .../virtuoso/skill/layout/lefdef/lefdef.il | 1140 +++ .../virtuoso/skill/layout/mid/compact.il | 268 + .../cadence/virtuoso/skill/layout/mid/mid.il | 740 ++ .../skill/layout/notches/fillnotches.il | 295 + .../virtuoso/skill/layout/notches/notches.il | 117 + .../skill/layout/pins/ScanPinToAutoPinFile.il | 127 + .../virtuoso/skill/layout/pins/abstractpin.il | 976 ++ .../virtuoso/skill/layout/pins/autopin.il | 1614 +++ .../skill/layout/pins/canonicalize.il | 123 + .../skill/layout/pins/channels/e1ofn.il | 308 + .../skill/layout/pins/detailed_abstract.il | 187 + .../virtuoso/skill/layout/pins/expand_pins.il | 52 + .../virtuoso/skill/layout/pins/leafpins.il | 856 ++ .../skill/layout/pins/midlevelpins.il | 222 + .../virtuoso/skill/layout/pins/pinlayer.il | 43 + .../virtuoso/skill/layout/pins/pinplace.il | 725 ++ .../skill/layout/pins/pintemplates.il | 108 + .../virtuoso/skill/layout/pins/pinutil.il | 612 ++ .../virtuoso/skill/layout/pins/sync_pins.il | 157 + .../virtuoso/skill/layout/pins/vstruts.il | 1141 +++ .../skill/layout/power_grid/power_grid.il | 160 + .../layout/powergrid/AutoGeneratePowerGrid.il | 391 + .../skill/layout/powergrid/powergrid.il | 542 + .../virtuoso/skill/layout/proteus/proteus.il | 586 ++ .../virtuoso/skill/layout/route/abstract.il | 108 + .../skill/layout/route/canonicalize.il | 241 + .../virtuoso/skill/layout/route/flatten.il | 750 ++ .../virtuoso/skill/layout/route/ground.il | 159 + .../virtuoso/skill/layout/route/layout.il | 18 + .../virtuoso/skill/layout/route/nanoroute.il | 585 ++ .../virtuoso/skill/layout/route/prelayout.il | 157 + .../virtuoso/skill/layout/route/reset.il | 198 + .../virtuoso/skill/layout/route/route.il | 235 + .../virtuoso/skill/layout/route/routepath.il | 8851 +++++++++++++++++ .../virtuoso/skill/layout/route/sync.il | 69 + .../virtuoso/skill/layout/route/trim.il | 247 + .../virtuoso/skill/layout/tech/spacing.il | 98 + .../skill/layout/transform/transform.il | 163 + .../virtuoso/skill/layout/vlvs/vlvs.il | 1208 +++ .../skill/layout/vlvs/vlvs.state.template | 957 ++ .../cadence/virtuoso/skill/nano/cellview.il | 115 + .../cadence/virtuoso/skill/nano/flatten.il | 318 + .../cadence/virtuoso/skill/nano/floorplan.il | 80 + .../cadence/virtuoso/skill/nano/routed.il | 178 + .../cadence/virtuoso/skill/nano/sync.il | 16 + .../cadence/virtuoso/skill/nano/util.il | 100 + .../cadence/virtuoso/skill/p4/p4.il | 507 + .../virtuoso/skill/schematic/distinst.il | 62 + .../skill/schematic/inlineconnections.il | 348 + .../virtuoso/skill/schematic/lvsnodes.il | 71 + .../virtuoso/skill/schematic/netlisttable.il | 297 + .../virtuoso/skill/schematic/swapmasters.il | 124 + .../virtuoso/skill/schematic/syncnetlist.il | 483 + .../skill/schematic/update_floorplan.il | 267 + .../virtuoso/skill/schematic/updatenetlist.il | 4521 +++++++++ .../cadence/virtuoso/skill/ui/Floorplan/.menu | 1 + .../virtuoso/skill/ui/Floorplan/ArrayCells.il | 58 + .../virtuoso/skill/ui/Floorplan/FLOverlap.il | 13 + .../ui/Floorplan/FloorplanAllSubcells.il | 216 + .../skill/ui/Floorplan/FloorplanTemplate.il | 101 + .../skill/ui/Floorplan/InitFloorplan.il | 76 + .../skill/ui/Floorplan/LoadFloorplan.il | 69 + .../skill/ui/Floorplan/PromoteInplacePins.il | 89 + .../skill/ui/Floorplan/ReplaceSubcells.il | 8 + .../skill/ui/Floorplan/ResolveOverlap.il | 181 + .../skill/ui/Floorplan/SaveFloorplan.il | 64 + .../cadence/virtuoso/skill/ui/Fulcrum/.menu | 1 + .../virtuoso/skill/ui/Fulcrum/Align/.menu | 1 + .../skill/ui/Fulcrum/Align/CheckAlignment.il | 13 + .../skill/ui/Fulcrum/Align/FixAlignment.il | 13 + .../skill/ui/Fulcrum/Align/SetAlignment.il | 48 + .../skill/ui/Fulcrum/AutoPowerGrid.il | 88 + .../skill/ui/Fulcrum/AutoPowerGridAbstract.il | 77 + .../virtuoso/skill/ui/Fulcrum/Bus/.menu | 1 + .../Fulcrum/Bus/CopyBusGuidesToPrelayout.il | 20 + .../skill/ui/Fulcrum/Bus/CreateGuideInst.il | 74 + .../skill/ui/Fulcrum/Bus/DeleteBusWires.il | 20 + .../ui/Fulcrum/Bus/DeleteOverlapMarkers.il | 19 + .../skill/ui/Fulcrum/Bus/DeleteWires.il | 20 + .../skill/ui/Fulcrum/Bus/DrawAllPins.il | 20 + .../skill/ui/Fulcrum/Bus/DrawWires.il | 20 + .../skill/ui/Fulcrum/Bus/FindCopies.il | 26 + .../skill/ui/Fulcrum/Bus/FindOverlaps.il | 20 + .../ui/Fulcrum/Bus/MoveGuidesToBuswires.il | 20 + .../skill/ui/Fulcrum/Bus/RefreshAll.il | 20 + .../skill/ui/Fulcrum/Bus/RoundGuidePaths.il | 49 + .../skill/ui/Fulcrum/Bus/SetBusPattern.il | 51 + .../cadence/virtuoso/skill/ui/Fulcrum/CCAR.il | 145 + .../virtuoso/skill/ui/Fulcrum/CheckSubcell.il | 64 + .../virtuoso/skill/ui/Fulcrum/CreateCDL.il | 81 + .../skill/ui/Fulcrum/CreateFloorplan.il | 58 + .../virtuoso/skill/ui/Fulcrum/CreateLib.il | 82 + .../skill/ui/Fulcrum/CreatePrBound.il | 46 + .../skill/ui/Fulcrum/DeleteAllShapes.il | 17 + .../virtuoso/skill/ui/Fulcrum/DiffLayout.il | 207 + .../skill/ui/Fulcrum/EstimateWireDistance.il | 94 + .../virtuoso/skill/ui/Fulcrum/Fiji/.menu | 1 + .../skill/ui/Fulcrum/Fiji/AttachPinShape.il | 116 + .../skill/ui/Fulcrum/Fiji/CheckSubcellPins.il | 98 + .../skill/ui/Fulcrum/Fiji/ShrinkBaliToFiji.il | 250 + .../skill/ui/Fulcrum/Fiji/ShrinkPrelayout.il | 215 + .../skill/ui/Fulcrum/Fiji/SnapPowerGrid.il | 64 + .../cadence/virtuoso/skill/ui/Fulcrum/Fill.il | 47 + .../skill/ui/Fulcrum/FillSpareGate.il | 138 + .../virtuoso/skill/ui/Fulcrum/GetCellArea.il | 11 + .../virtuoso/skill/ui/Fulcrum/GetFigArea.il | 17 + .../cadence/virtuoso/skill/ui/Fulcrum/GoTo.il | 88 + .../skill/ui/Fulcrum/HandLayout/.menu | 1 + .../ui/Fulcrum/HandLayout/DeleteNotHand.il | 16 + .../skill/ui/Fulcrum/HandLayout/SetHandAll.il | 16 + .../ui/Fulcrum/HandLayout/SetHandSelected.il | 16 + .../skill/ui/Fulcrum/HandLayout/Struts.il | 94 + .../virtuoso/skill/ui/Fulcrum/Hierarchy/.menu | 1 + .../skill/ui/Fulcrum/Hierarchy/Inline.il | 69 + .../ui/Fulcrum/Hierarchy/Instanciators.il | 131 + .../ui/Fulcrum/Hierarchy/ReplaceSubcells.il | 50 + .../ui/Fulcrum/Hierarchy/ReportInstances.il | 16 + .../virtuoso/skill/ui/Fulcrum/Leaf/.menu | 1 + .../virtuoso/skill/ui/Fulcrum/Leaf/Clean.il | 300 + .../skill/ui/Fulcrum/Leaf/DrawImplant.il | 14 + .../skill/ui/Fulcrum/Leaf/DrawPins.il | 14 + .../skill/ui/Fulcrum/Leaf/DrawPoly.il | 14 + .../skill/ui/Fulcrum/Leaf/DrawStruts.il | 14 + .../skill/ui/Fulcrum/Leaf/GroupChains.il | 14 + .../skill/ui/Fulcrum/Leaf/MakeAbstract.il | 17 + .../skill/ui/Fulcrum/Leaf/PlaceGates.il | 14 + .../skill/ui/Fulcrum/Leaf/PlacePlugs.il | 14 + .../skill/ui/Fulcrum/Leaf/RouteLeaf.il | 14 + .../skill/ui/Fulcrum/Leaf/SyncToNetlist.il | 14 + .../skill/ui/Fulcrum/LeafAbstractList.il | 100 + .../virtuoso/skill/ui/Fulcrum/LockFolds.il | 22 + .../virtuoso/skill/ui/Fulcrum/MidLevel/.menu | 1 + .../skill/ui/Fulcrum/MidLevel/Clean.il | 300 + .../skill/ui/Fulcrum/MidLevel/MakeAbstract.il | 17 + .../skill/ui/Fulcrum/MidLevel/MakeFlatten.il | 56 + .../skill/ui/Fulcrum/MidLevel/MakeLayout.il | 15 + .../ui/Fulcrum/MidLevel/MakePrelayout.il | 56 + .../virtuoso/skill/ui/Fulcrum/Options.il | 32 + .../virtuoso/skill/ui/Fulcrum/P4/.menu | 1 + .../virtuoso/skill/ui/Fulcrum/P4/P4Cell.il | 151 + .../skill/ui/Fulcrum/P4/P4EditAllSubcells.il | 115 + .../virtuoso/skill/ui/Fulcrum/P4/cdsp4add.il | 26 + .../virtuoso/skill/ui/Fulcrum/P4/cdsp4edit.il | 26 + .../skill/ui/Fulcrum/P4/cdsp4revert.il | 26 + .../skill/ui/Fulcrum/P4/cdsp4submit.il | 41 + .../virtuoso/skill/ui/Fulcrum/Pins/.menu | 1 + .../skill/ui/Fulcrum/Pins/CanonicalizePins.il | 18 + .../skill/ui/Fulcrum/Pins/DrawPins.il | 245 + .../skill/ui/Fulcrum/Pins/DrawResetPins.il | 192 + .../skill/ui/Fulcrum/Pins/DrawSubPins.il | 243 + .../virtuoso/skill/ui/Fulcrum/PreroutePins.il | 108 + .../virtuoso/skill/ui/Fulcrum/Route/.menu | 1 + .../virtuoso/skill/ui/Fulcrum/Route/Clean.il | 292 + .../ui/Fulcrum/Route/CreateMidAbstract.il | 307 + .../skill/ui/Fulcrum/Route/DrawPlugs.il | 170 + .../skill/ui/Fulcrum/Route/Keepout.il | 170 + .../virtuoso/skill/ui/Fulcrum/Route/Route.il | 58 + .../skill/ui/Fulcrum/Route/ViaExtension.il | 101 + .../virtuoso/skill/ui/Fulcrum/Stacks/.menu | 1 + .../virtuoso/skill/ui/Fulcrum/Stacks/Fold.il | 87 + .../skill/ui/Fulcrum/Stacks/Inline.il | 179 + .../virtuoso/skill/ui/Fulcrum/Stacks/Stack.il | 156 + .../virtuoso/skill/ui/Fulcrum/StartVLVS.il | 8 + .../skill/ui/Fulcrum/SyncToNetList.il | 13 + .../virtuoso/skill/ui/Fulcrum/Verify/.menu | 1 + .../skill/ui/Fulcrum/Verify/Signoff.il | 89 + .../skill/ui/Fulcrum/Verify/SignoffInclude.il | 63 + .../virtuoso/skill/ui/Fulcrum/Wiring/.menu | 1 + .../skill/ui/Fulcrum/Wiring/CheckBusWires.il | 25 + .../ui/Fulcrum/Wiring/InteractiveReport.il | 19 + .../ui/Fulcrum/Wiring/ReportMBUFChannels.il | 20 + .../ui/Fulcrum/Wiring/ReportWirelengths.il | 24 + .../cadence/virtuoso/skill/ui/Hercules/.menu | 5 + .../skill/ui/Hercules/clearHighlights.il | 7 + .../skill/ui/Hercules/createTagView.il | 11 + .../virtuoso/skill/ui/Hercules/runVue.il | 146 + .../skill/ui/Hercules/setVueWindow.il | 18 + .../cadence/virtuoso/skill/ui/Nano/.menu | 1 + .../virtuoso/skill/ui/Nano/Abstracts/.menu | 1 + .../ui/Nano/Abstracts/CreateLeafAbstract.il | 292 + .../ui/Nano/Abstracts/CreateMidAbstract.il | 12 + .../Nano/Abstracts/CreatePowerGridAbstract.il | 11 + .../skill/ui/Nano/Abstracts/CreatePrBound.il | 12 + .../ui/Nano/Abstracts/ListMissingAbstracts.il | 135 + .../virtuoso/skill/ui/Nano/Export/.menu | 1 + .../skill/ui/Nano/Export/CreateTracksDef.il | 126 + .../skill/ui/Nano/Export/ExportDesignDef.il | 136 + .../skill/ui/Nano/Export/ExportDesignLef.il | 93 + .../ui/Nano/Export/ExportNondefaultRuleDef.il | 107 + .../skill/ui/Nano/Export/ExportVerilog.il | 87 + .../virtuoso/skill/ui/Nano/Flatten/.menu | 1 + .../Nano/Flatten/CopyBusGuidesToPrelayout.il | 12 + .../skill/ui/Nano/Flatten/CreateCellList.il | 79 + .../skill/ui/Nano/Flatten/CreatePowerGrid.il | 12 + .../skill/ui/Nano/Flatten/DrawPins.il | 12 + .../skill/ui/Nano/Flatten/FlattenView.il | 312 + .../virtuoso/skill/ui/Nano/Import/.menu | 1 + .../skill/ui/Nano/Import/CreateLayoutView.il | 102 + .../skill/ui/Nano/Import/ImportDef.il | 72 + .../skill/ui/Nano/Import/SaveFiles.il | 98 + .../virtuoso/skill/ui/Nano/Nanoroute/.menu | 1 + .../skill/ui/Nano/Nanoroute/InitNanoroute.il | 55 + .../skill/ui/Nano/Nanoroute/RunNanoroute.il | 190 + .../virtuoso/skill/ui/Nano/NanorouteDoc.il | 125 + .../virtuoso/skill/ui/Nano/Prelayout/.menu | 1 + .../skill/ui/Nano/Prelayout/CheckAlignment.il | 6 + .../virtuoso/skill/ui/Nano/Prelayout/Clean.il | 12 + .../skill/ui/Nano/Prelayout/CreatePrBound.il | 8 + .../ui/Nano/Prelayout/CreatePrelayout.il | 146 + .../skill/ui/Nano/Prelayout/ResolveOverlap.il | 12 + .../virtuoso/skill/ui/Nano/Preroute/.menu | 1 + .../ui/Nano/Preroute/DeleteOverlapMarkers.il | 20 + .../skill/ui/Nano/Preroute/DeleteWires.il | 20 + .../skill/ui/Nano/Preroute/DrawBusWire.il | 20 + .../skill/ui/Nano/Preroute/FindBusOverlaps.il | 20 + .../skill/ui/Nano/Preroute/SetBusPattern.il | 55 + .../cadence/virtuoso/skill/ui/Proteus/.menu | 1 + .../virtuoso/skill/ui/Proteus/Abstracts/.menu | 1 + .../Proteus/Abstracts/CreateLeafAbstract.il | 6 + .../ui/Proteus/Abstracts/CreateMidAbstract.il | 12 + .../Abstracts/CreatePowerGridAbstract.il | 11 + .../ui/Proteus/Abstracts/CreatePrBound.il | 12 + .../Proteus/Abstracts/ListMissingAbstracts.il | 10 + .../virtuoso/skill/ui/Proteus/Export/.menu | 1 + .../ui/Proteus/Export/CreateTracksDef.il | 126 + .../ui/Proteus/Export/ExportDesignLef.il | 119 + .../Proteus/Export/ExportNondefaultRuleDef.il | 10 + .../Export/ExportProteusFloorplanDef.il | 201 + .../virtuoso/skill/ui/Proteus/Flatten/.menu | 1 + .../ui/Proteus/Flatten/CreateCellList.il | 10 + .../ui/Proteus/Flatten/CreatePowerGrid.il | 12 + .../skill/ui/Proteus/Flatten/DrawPins.il | 12 + .../skill/ui/Proteus/Flatten/FlattenView.il | 47 + .../virtuoso/skill/ui/Proteus/Prelayout/.menu | 1 + .../ui/Proteus/Prelayout/CreatePrBound.il | 8 + .../ui/Proteus/Prelayout/CreatePrelayout.il | 10 + .../skill/ui/Proteus/Prelayout/DrawWires.il | 13 + .../ui/Proteus/Prelayout/FlushAndSync.il | 15 + .../skill/ui/Proteus/Prelayout/GetCellArea.il | 8 + .../virtuoso/skill/ui/Proteus/Synch/.menu | 1 + .../skill/ui/Proteus/Synch/AllSync.il | 345 + .../skill/ui/Proteus/Synch/CreateCellList.il | 101 + .../skill/ui/Proteus/Synch/CreateGuideInst.il | 71 + .../skill/ui/Proteus/Synch/ExportDesignDef.il | 127 + .../skill/ui/Proteus/Synch/ExportDesignLef.il | 106 + .../Proteus/Synch/ExportNondefaultRuleDef.il | 87 + .../virtuoso/skill/ui/Proteus/Synch/Flush.il | 15 + .../virtuoso/skill/ui/autoload/bindkeys | 151 + .../virtuoso/skill/ui/autoload/bindkeys_hand | 71 + .../virtuoso/skill/ui/automation/copyview.il | 49 + .../cadence/virtuoso/skill/ui/ui.il | 506 + .../cadence/virtuoso/skill/ui/ui.package | 287 + .../cadence/virtuoso/skill/ui/util/license.il | 48 + .../skill/util/binarysearch/binarysearch.il | 139 + .../skill/util/binarysearch/search.il | 59 + .../virtuoso/skill/util/cache/cache.il | 49 + .../cadence/virtuoso/skill/util/cellview.il | 123 + .../cadence/virtuoso/skill/util/counter.il | 83 + .../cadence/virtuoso/skill/util/db.il | 17 + .../cadence/virtuoso/skill/util/defaults.il | 13 + .../skill/util/expression/expression.il | 31 + .../virtuoso/skill/util/file/configfile.il | 57 + .../virtuoso/skill/util/file/dirtree.il | 33 + .../virtuoso/skill/util/file/fileutil.il | 65 + .../virtuoso/skill/util/file/libcellview.il | 69 + .../cadence/virtuoso/skill/util/file/path.il | 68 + .../virtuoso/skill/util/file/readfile.il | 27 + .../virtuoso/skill/util/file/tempfile.il | 55 + .../cadence/virtuoso/skill/util/lib.il | 52 + .../cadence/virtuoso/skill/util/list/list.il | 657 ++ .../virtuoso/skill/util/list/partition.il | 40 + .../virtuoso/skill/util/makelayouttag.il | 513 + .../virtuoso/skill/util/makemidlayouttag.il | 375 + .../cadence/virtuoso/skill/util/math/math.il | 8 + .../cadence/virtuoso/skill/util/name.il | 592 ++ .../virtuoso/skill/util/package/package.il | 12 + .../skill/util/package/package.il.inst | 26 + .../virtuoso/skill/util/pcell/pcell.il | 90 + .../cadence/virtuoso/skill/util/profile.il | 29 + .../cadence/virtuoso/skill/util/prop/prop.il | 57 + .../cadence/virtuoso/skill/util/recurse.il | 27 + .../virtuoso/skill/util/stack/stack.il | 16 + .../skill/util/string/escapestring.il | 116 + .../virtuoso/skill/util/string/strutil.il | 234 + .../virtuoso/skill/util/table/table.il | 40 + .../cadence/virtuoso/skill/util/version.il | 7 + .../cadence/virtuoso/updatenetlist.package | 63 + .../virtuoso/virtuoso-integration.package | 410 + async-toolkit/jtools/cad/java/Makefile | 297 + .../build/antlr-grammers/CDL/antlrrules.mk | 10 + .../build/antlr-grammers/Cast/antlrrules.mk | 27 + .../antlr-grammers/CastQuery/antlrrules.mk | 10 + .../antlr-grammers/CastTwo/antlrrules.mk | 71 + .../CellHierarchyDump/antlrrules.mk | 9 + .../build/antlr-grammers/CoSim/antlrrules.mk | 9 + .../build/antlr-grammers/Csp/antlrrules.mk | 9 + .../MathExpression/antlrrules.mk | 11 + .../build/antlr-grammers/Shape/antlrrules.mk | 11 + .../StringExpression/antlrrules.mk | 11 + .../cad/java/build/apps/dsim/apprules.mk | 18 + .../cad/java/build/apps/jauto/apprules.mk | 17 + async-toolkit/jtools/cad/java/custom.mk | 1 + .../jtools/cad/java/scripts/cadencize | 227 + .../jtools/cad/java/scripts/cdl2aspice | 20 + .../jtools/cad/java/scripts/csp2java | 9 + .../jtools/cad/java/scripts/ext2aspice | 24 + .../jtools/cad/java/scripts/fakecadencize | 145 + .../cad/java/scripts/fulcrum-java.sh.template | 323 + .../java/scripts/fulcrum-rename.sh.template | 323 + .../jtools/cad/java/scripts/gen-build-id | 2 + .../cad/java/scripts/grabRegisterData.pl | 115 + async-toolkit/jtools/cad/java/scripts/iosim | 26 + async-toolkit/jtools/cad/java/scripts/jauto | 9 + .../jtools/cad/java/scripts/jauto_espresso | 5 + .../jtools/cad/java/scripts/jespresso | 5 + async-toolkit/jtools/cad/java/scripts/jflat | 19 + async-toolkit/jtools/cad/java/scripts/jlvs | 67 + .../cad/java/scripts/make_subdir_makefile | 42 + async-toolkit/jtools/cad/java/scripts/mgn | 34 + .../jtools/cad/java/scripts/mips-dis | 1 + .../cad/java/scripts/output-source-files | 3 + .../jtools/cad/java/scripts/run-all-tests | 45 + .../jtools/cad/java/scripts/run-one-test | 30 + .../jtools/cad/java/src/cfiles-custom.mk | 6 + .../com/avlsi/benchmarks/JavaSyncCost.java | 364 + .../src/com/avlsi/cast/CastCacheManager.java | 110 + .../cad/java/src/com/avlsi/cast/CastFile.java | 180 + .../src/com/avlsi/cast/CastFileParser.java | 323 + .../com/avlsi/cast/CastSemanticException.java | 71 + .../com/avlsi/cast/CastSyntaxException.java | 67 + .../src/com/avlsi/cast/impl/ASTWithInfo.java | 97 + .../impl/AbstractSplicingEnvironment.java | 66 + .../com/avlsi/cast/impl/AlintFaninValue.java | 60 + .../cast/impl/AmbiguousLookupException.java | 41 + .../com/avlsi/cast/impl/AnonymousValue.java | 49 + .../src/com/avlsi/cast/impl/ArrayValue.java | 733 ++ .../com/avlsi/cast/impl/BlockEnvironment.java | 111 + .../src/com/avlsi/cast/impl/BoolValue.java | 189 + .../cad/java/src/com/avlsi/cast/impl/Cast.g | 839 ++ .../avlsi/cast/impl/CastLexerInterface.java | 20 + .../cast/impl/CastParserEnvironment.java | 840 ++ .../avlsi/cast/impl/CastParserInterface.java | 27 + .../java/src/com/avlsi/cast/impl/CastTree.g | 1176 +++ .../cast/impl/CastTreeParserInterface.java | 30 + .../impl/CellInterfaceCollectionIterator.java | 36 + .../com/avlsi/cast/impl/ChainEnvironment.java | 90 + .../impl/ChainedEnvironmentEntryIterator.java | 96 + .../cast/impl/ChainedEnvironmentIterator.java | 54 + .../cast/impl/CircularImportException.java | 41 + .../src/com/avlsi/cast/impl/ClassType.java | 50 + .../avlsi/cast/impl/DenseSubscriptSpec.java | 214 + .../cad/java/src/com/avlsi/cast/impl/Dumb.g | 131 + .../avlsi/cast/impl/DumbLexerInterface.java | 20 + .../avlsi/cast/impl/DumbParserInterface.java | 15 + .../src/com/avlsi/cast/impl/Environment.java | 43 + .../com/avlsi/cast/impl/EnvironmentEntry.java | 38 + .../cast/impl/EnvironmentEntryIterator.java | 34 + .../avlsi/cast/impl/EnvironmentIterator.java | 32 + .../cast/impl/FieldedValueInterface.java | 18 + .../cast/impl/FixedBlockEnvironment.java | 40 + .../src/com/avlsi/cast/impl/FloatValue.java | 217 + .../avlsi/cast/impl/ImportEnvironment.java | 201 + .../com/avlsi/cast/impl/InstanceValue.java | 432 + .../src/com/avlsi/cast/impl/IntValue.java | 305 + .../avlsi/cast/impl/InvalidBindException.java | 33 + .../cast/impl/InvalidOperationException.java | 41 + .../cast/impl/JavaChannelContainerValue.java | 128 + .../com/avlsi/cast/impl/JavaChannelValue.java | 62 + .../com/avlsi/cast/impl/LocalEnvironment.java | 179 + .../com/avlsi/cast/impl/LoopEnvironment.java | 117 + .../cast/impl/MetaParamValueInterface.java | 26 + .../src/com/avlsi/cast/impl/NodeValue.java | 107 + .../com/avlsi/cast/impl/NullEnvironment.java | 73 + .../avlsi/cast/impl/PRSExpressionValue.java | 124 + .../java/src/com/avlsi/cast/impl/Range.java | 81 + .../avlsi/cast/impl/SelfImportException.java | 25 + .../cast/impl/SemanticWrapperException.java | 91 + .../avlsi/cast/impl/SparseSubscriptSpec.java | 215 + .../avlsi/cast/impl/SplicingEnvironment.java | 65 + .../cast/impl/SubscriptSpecInterface.java | 70 + .../java/src/com/avlsi/cast/impl/Symbol.java | 76 + .../cast/impl/SymbolRedeclaredException.java | 40 + .../cast/impl/TestDenseSubscriptSpec.java | 100 + .../com/avlsi/cast/impl/TokenWithInfo.java | 53 + .../avlsi/cast/impl/TopLevelEnvironment.java | 131 + .../com/avlsi/cast/impl/TupleGroupValue.java | 51 + .../src/com/avlsi/cast/impl/TupleValue.java | 145 + .../java/src/com/avlsi/cast/impl/Type.java | 20 + .../com/avlsi/cast/impl/UserDefinedValue.java | 452 + .../java/src/com/avlsi/cast/impl/Value.java | 178 + .../java/src/com/avlsi/cast/impl/custom.mk | 27 + .../cast2/directive/DirectiveConstants.java | 254 + .../cast2/directive/DirectiveInterface.java | 97 + .../directive/DirectiveInterfaceFactory.java | 5 + .../directive/UnknownDirectiveException.java | 18 + .../cast2/directive/impl/CastEmitter.java | 61 + .../cast2/directive/impl/DefaultCallback.java | 195 + .../directive/impl/DirectiveCallback.java | 27 + .../directive/impl/DirectiveComparator.java | 23 + .../directive/impl/DirectiveConditional.java | 30 + .../directive/impl/DirectiveDefinition.java | 38 + .../directive/impl/DirectiveDifference.java | 92 + .../directive/impl/DirectiveEmitter.java | 22 + .../directive/impl/DirectiveFactory.java | 43 + .../impl/DirectiveFactoryInterface.java | 44 + .../cast2/directive/impl/DirectiveImpl.java | 319 + .../cast2/directive/impl/DirectiveLoop.java | 32 + .../cast2/directive/impl/DirectiveParser.java | 420 + .../cast2/directive/impl/DirectiveSource.java | 71 + .../directive/impl/DirectiveStatement.java | 14 + .../impl/DirectiveSyntaxException.java | 17 + .../cast2/directive/impl/DirectiveTable.java | 1471 +++ .../directive/impl/DirectiveVisitor.java | 23 + .../avlsi/cast2/directive/impl/TokenInfo.java | 26 + .../src/com/avlsi/cast2/impl/CastAliases.g | 69 + .../src/com/avlsi/cast2/impl/CastAssert.g | 83 + .../java/src/com/avlsi/cast2/impl/CastInfo.g | 52 + .../avlsi/cast2/impl/CastParsingOption.java | 95 + .../java/src/com/avlsi/cast2/impl/CastPrs.g | 147 + .../src/com/avlsi/cast2/impl/CastSubcells.g | 83 + .../src/com/avlsi/cast2/impl/CastSubtypes.g | 85 + .../java/src/com/avlsi/cast2/impl/CastTwo.g | 1420 +++ .../cast2/impl/CastTwoParserCallback.java | 19 + .../cast2/impl/CastTwoParserInterface.java | 17 + .../src/com/avlsi/cast2/impl/CastTwoTree.g | 4519 +++++++++ .../src/com/avlsi/cast2/impl/CastTwoUtil.java | 239 + .../java/src/com/avlsi/cast2/impl/DumbTwo.g | 139 + .../src/com/avlsi/cast2/impl/Functions.java | 147 + .../src/com/avlsi/cast2/impl/PrsCallback.java | 188 + .../java/src/com/avlsi/cast2/impl/custom.mk | 113 + .../src/com/avlsi/cast2/impl/package.html | 187 + .../com/avlsi/cast2/util/CastFileServer.java | 181 + .../cast2/util/DirectiveActionFilter.java | 21 + .../cast2/util/DirectiveActionInterface.java | 36 + .../com/avlsi/cast2/util/DirectiveFilter.java | 146 + .../avlsi/cast2/util/DirectiveOverride.java | 102 + .../com/avlsi/cast2/util/DirectiveUtils.java | 1001 ++ .../com/avlsi/cast2/util/DirectiveWalker.java | 102 + .../src/com/avlsi/cast2/util/NetProperty.java | 281 + .../cast2/util/StandardParsingOption.java | 194 + .../java/src/com/avlsi/cast2/util/custom.mk | 5 + .../avlsi/cast2/util/fileserver.package.inc | 3 + .../cell/AttributeInheritanceException.java | 29 + .../com/avlsi/cell/BadCSPPortException.java | 15 + .../java/src/com/avlsi/cell/CellDelay.java | 227 + .../cad/java/src/com/avlsi/cell/CellImpl.java | 2932 ++++++ .../src/com/avlsi/cell/CellInterface.java | 500 + .../java/src/com/avlsi/cell/CellUtils.java | 2010 ++++ .../ChildrenFirstCellInterfaceIterator.java | 124 + .../src/com/avlsi/cell/ExclusiveNodeSet.java | 170 + .../src/com/avlsi/cell/ExclusiveNodeSets.java | 117 + .../com/avlsi/cell/HierarchyInterface.java | 7 + .../src/com/avlsi/cell/InstanceTrace.java | 84 + .../cell/NoSuchEnvironmentException.java | 57 + .../avlsi/cell/NoSuchSubcellException.java | 31 + .../com/avlsi/cell/RefinementException.java | 26 + .../avlsi/cell/SubcellCreationException.java | 22 + .../com/avlsi/cell/TestExclusiveNodeSet.java | 78 + .../com/avlsi/circuit/AbstractCircuit.java | 363 + .../src/com/avlsi/circuit/AbstractNode.java | 578 ++ .../java/src/com/avlsi/circuit/CapDevice.java | 100 + .../java/src/com/avlsi/circuit/Capacitor.java | 58 + .../com/avlsi/circuit/CapacitorInterface.java | 40 + .../src/com/avlsi/circuit/CircuitGraph.java | 374 + .../com/avlsi/circuit/ConjunctivePath.java | 159 + .../avlsi/circuit/CullingCircuitGraph.java | 404 + .../cad/java/src/com/avlsi/circuit/Diode.java | 83 + .../src/com/avlsi/circuit/DiodeDevice.java | 73 + .../src/com/avlsi/circuit/DiodeInterface.java | 46 + .../src/com/avlsi/circuit/DriverNode.java | 133 + .../src/com/avlsi/circuit/LumpedNode.java | 154 + .../src/com/avlsi/circuit/LumpedRCGraph.java | 401 + .../java/src/com/avlsi/circuit/MosDevice.java | 96 + .../cad/java/src/com/avlsi/circuit/Node.java | 156 + .../java/src/com/avlsi/circuit/ResDevice.java | 58 + .../com/avlsi/circuit/ResistiveSubnet.java | 407 + .../java/src/com/avlsi/circuit/Resistor.java | 58 + .../com/avlsi/circuit/ResistorInterface.java | 40 + .../java/src/com/avlsi/circuit/Source.java | 59 + .../com/avlsi/circuit/SourceInterface.java | 36 + .../src/com/avlsi/circuit/TestSubnet.java | 922 ++ .../src/com/avlsi/circuit/Transistor.java | 76 + .../avlsi/circuit/TransistorInterface.java | 43 + .../com/avlsi/csp/ast/AbstractASTNode.java | 113 + .../csp/ast/AbstractASTNodeInterface.java | 89 + .../csp/ast/AbstractBinaryExpression.java | 65 + .../csp/ast/AbstractChannelExpression.java | 44 + .../csp/ast/AbstractChannelStatement.java | 67 + .../csp/ast/AbstractCompositeStatement.java | 61 + .../csp/ast/AbstractGuardedStatement.java | 92 + .../src/com/avlsi/csp/ast/AbstractLoop.java | 88 + .../csp/ast/AbstractRepetitionStatement.java | 26 + .../csp/ast/AbstractSelectionStatement.java | 30 + .../csp/ast/AbstractUnaryExpression.java | 44 + .../src/com/avlsi/csp/ast/AddExpression.java | 42 + .../src/com/avlsi/csp/ast/AndExpression.java | 43 + .../avlsi/csp/ast/ArrayAccessExpression.java | 69 + .../java/src/com/avlsi/csp/ast/ArrayType.java | 66 + .../avlsi/csp/ast/AssignmentStatement.java | 131 + .../com/avlsi/csp/ast/BitRangeExpression.java | 153 + .../com/avlsi/csp/ast/BooleanExpression.java | 12 + .../src/com/avlsi/csp/ast/BooleanType.java | 55 + .../src/com/avlsi/csp/ast/CSPProgram.java | 221 + .../avlsi/csp/ast/ChannelStructureType.java | 74 + .../src/com/avlsi/csp/ast/ChannelType.java | 71 + .../csp/ast/ConditionalAndExpression.java | 37 + .../csp/ast/ConditionalOrExpression.java | 37 + .../src/com/avlsi/csp/ast/Declaration.java | 107 + .../com/avlsi/csp/ast/DeclarationList.java | 40 + .../src/com/avlsi/csp/ast/Declarator.java | 122 + .../src/com/avlsi/csp/ast/DeclaratorList.java | 40 + .../ast/DeterministicRepetitionStatement.java | 31 + .../ast/DeterministicSelectionStatement.java | 31 + .../com/avlsi/csp/ast/DivideExpression.java | 43 + .../com/avlsi/csp/ast/EqualityExpression.java | 43 + .../src/com/avlsi/csp/ast/ErrorStatement.java | 75 + .../avlsi/csp/ast/ExponentialExpression.java | 43 + .../avlsi/csp/ast/ExpressionInterface.java | 28 + .../avlsi/csp/ast/ExpressionStatement.java | 50 + .../avlsi/csp/ast/FunctionCallExpression.java | 89 + .../avlsi/csp/ast/FunctionDeclaration.java | 97 + .../avlsi/csp/ast/GreaterEqualExpression.java | 43 + .../avlsi/csp/ast/GreaterThanExpression.java | 43 + .../src/com/avlsi/csp/ast/GuardedCommand.java | 91 + .../csp/ast/GuardedCommandInterface.java | 25 + .../csp/ast/GuardedCommandWithStatement.java | 55 + .../avlsi/csp/ast/IdentifierExpression.java | 54 + .../src/com/avlsi/csp/ast/IdentifierList.java | 47 + .../com/avlsi/csp/ast/IncDecStatement.java | 80 + .../avlsi/csp/ast/InequalityExpression.java | 43 + .../com/avlsi/csp/ast/IntegerExpression.java | 91 + .../src/com/avlsi/csp/ast/IntegerType.java | 138 + .../avlsi/csp/ast/LeftShiftExpression.java | 43 + .../avlsi/csp/ast/LessEqualExpression.java | 43 + .../com/avlsi/csp/ast/LessThanExpression.java | 43 + .../csp/ast/LinkageArrayAccessExpression.java | 45 + .../csp/ast/LinkageExpressionInterface.java | 19 + .../avlsi/csp/ast/LinkageExpressionTerm.java | 44 + .../csp/ast/LinkageIdentifierExpression.java | 36 + .../com/avlsi/csp/ast/LinkageLoopTerm.java | 45 + .../ast/LinkageStructureAccessExpression.java | 45 + .../avlsi/csp/ast/LinkageTermInterface.java | 19 + .../src/com/avlsi/csp/ast/LinkageTerms.java | 35 + .../src/com/avlsi/csp/ast/LoopExpression.java | 81 + .../java/src/com/avlsi/csp/ast/LoopGuard.java | 72 + .../src/com/avlsi/csp/ast/LoopStatement.java | 61 + .../avlsi/csp/ast/MemberAccessExpression.java | 68 + .../com/avlsi/csp/ast/MultiplyExpression.java | 43 + .../com/avlsi/csp/ast/NegateExpression.java | 40 + .../java/src/com/avlsi/csp/ast/NodeType.java | 64 + .../NonDeterministicRepetitionStatement.java | 42 + .../NonDeterministicSelectionStatement.java | 42 + .../src/com/avlsi/csp/ast/NotExpression.java | 40 + .../src/com/avlsi/csp/ast/OrExpression.java | 43 + .../com/avlsi/csp/ast/ParallelStatement.java | 31 + .../src/com/avlsi/csp/ast/PeekExpression.java | 38 + .../src/com/avlsi/csp/ast/PortDirection.java | 51 + .../com/avlsi/csp/ast/ProbeExpression.java | 39 + .../cad/java/src/com/avlsi/csp/ast/Range.java | 60 + .../com/avlsi/csp/ast/ReceiveExpression.java | 38 + .../com/avlsi/csp/ast/ReceiveStatement.java | 43 + .../avlsi/csp/ast/RemainderExpression.java | 43 + .../avlsi/csp/ast/RightShiftExpression.java | 43 + .../src/com/avlsi/csp/ast/SendStatement.java | 41 + .../avlsi/csp/ast/SequentialStatement.java | 30 + .../src/com/avlsi/csp/ast/SkipStatement.java | 32 + .../com/avlsi/csp/ast/StatementInterface.java | 24 + .../com/avlsi/csp/ast/StringExpression.java | 57 + .../src/com/avlsi/csp/ast/StringType.java | 58 + .../csp/ast/StructureAccessExpression.java | 68 + .../avlsi/csp/ast/StructureDeclaration.java | 84 + .../src/com/avlsi/csp/ast/StructureType.java | 68 + .../com/avlsi/csp/ast/SubtractExpression.java | 43 + .../avlsi/csp/ast/TemporaryIntegerType.java | 7 + .../cad/java/src/com/avlsi/csp/ast/Type.java | 47 + .../src/com/avlsi/csp/ast/VarStatement.java | 58 + .../com/avlsi/csp/ast/VisitorException.java | 29 + .../com/avlsi/csp/ast/VisitorInterface.java | 130 + .../src/com/avlsi/csp/ast/XorExpression.java | 37 + .../src/com/avlsi/csp/coverage/Monitor.java | 343 + .../avlsi/csp/coverage/ParseException.java | 25 + .../src/com/avlsi/csp/coverage/ProbeInfo.java | 49 + .../src/com/avlsi/csp/csp2gma/Csp2Gma.java | 148 + .../src/com/avlsi/csp/csp2gma/GmaEmitter.java | 1032 ++ .../java/src/com/avlsi/csp/csp2java/.empty | 0 .../avlsi/csp/csp2java/ArbiterVisitor.java | 820 ++ .../src/com/avlsi/csp/csp2java/CSP2Class.java | 450 + .../src/com/avlsi/csp/csp2java/CSP2Java.java | 236 + .../com/avlsi/csp/csp2java/JavaEmitter.java | 3172 ++++++ .../csp/csp2java/NoCSPBlockException.java | 23 + .../avlsi/csp/csp2java/SemanticException.java | 37 + .../csp2java/SymbolRedefinedException.java | 30 + .../com/avlsi/csp/csp2java/SymbolTable.java | 199 + .../csp2java/SymbolUndefinedException.java | 30 + .../src/com/avlsi/csp/csp2java/csp2java.html | 98 + .../com/avlsi/csp/csp2java/csp2java.package | 10 + .../java/src/com/avlsi/csp/csp2java/custom.mk | 6 + .../avlsi/csp/csp2java/runtime/CspArray.java | 188 + .../runtime/CspArrayBoundsException.java | 17 + .../csp/csp2java/runtime/CspBoolean.java | 23 + .../csp2java/runtime/CspChannelInArray1.java | 80 + .../csp2java/runtime/CspChannelInArray2.java | 70 + .../csp2java/runtime/CspChannelOutArray1.java | 81 + .../csp2java/runtime/CspChannelOutArray2.java | 70 + .../csp2java/runtime/CspCloneableValue.java | 7 + .../csp/csp2java/runtime/CspInteger.java | 301 + .../csp2java/runtime/CspMetaParamArray1.java | 45 + .../avlsi/csp/csp2java/runtime/CspNode.java | 42 + .../csp/csp2java/runtime/CspNodeArray1.java | 47 + .../runtime/CspRuntimeAbstractDevice.java | 823 ++ .../runtime/CspSnoopingInterface.java | 48 + .../avlsi/csp/csp2java/runtime/CspString.java | 52 + .../csp/csp2java/runtime/CspStructure.java | 6 + .../avlsi/csp/csp2java/runtime/CspValue.java | 8 + .../csp2java/runtime/FiniteCspInteger.java | 46 + .../com/avlsi/csp/csp2java/runtime/Fold.java | 139 + .../csp/csp2java/runtime/LinkageHelper.java | 36 + .../csp/csp2java/runtime/LoggedCspArray.java | 153 + .../runtime/NonDeterminismException.java | 17 + .../avlsi/csp/csp2java/runtime/Packable.java | 6 + .../csp2java/runtime/ShadowCspInteger.java | 59 + .../csp/csp2java/runtime/StackFrame.java | 32 + .../csp2java/runtime/cspruntime.package.inc | 27 + .../java/src/com/avlsi/csp/csp2tt/Csp2TT.java | 448 + .../avlsi/csp/csp2tt/PlayingChannelInput.java | 146 + .../csp/csp2tt/RecordingChannelOutput.java | 137 + .../avlsi/csp/csp2verilog/CommonEmitter.java | 237 + .../avlsi/csp/csp2verilog/Csp2Verilog.java | 279 + .../csp/csp2verilog/SystemVerilogEmitter.java | 2157 ++++ .../avlsi/csp/csp2verilog/VerilogEmitter.java | 2281 +++++ .../src/com/avlsi/csp/csp2xml/Csp2Xml.java | 157 + .../src/com/avlsi/csp/csp2xml/XmlTourist.java | 767 ++ .../cad/java/src/com/avlsi/csp/grammar/Csp.g | 835 ++ .../com/avlsi/csp/grammar/ParsePosition.java | 111 + .../src/com/avlsi/csp/grammar/ParseRange.java | 83 + .../java/src/com/avlsi/csp/grammar/custom.mk | 7 + .../avlsi/csp/grammar/test/level_0/assign.csp | 1 + .../csp/grammar/test/level_0/det_select.csp | 3 + .../grammar/test/level_0/det_select_else.csp | 4 + .../grammar/test/level_0/loop_bar_stmt.csp | 1 + .../grammar/test/level_0/loop_comma_stmt.csp | 1 + .../grammar/test/level_0/loop_seq_stmt.csp | 1 + .../csp/grammar/test/level_0/loop_stmt.csp | 1 + .../csp/grammar/test/level_0/nd_select.csp | 3 + .../grammar/test/level_0/nd_select_else.csp | 5 + .../csp/grammar/test/level_0/par_bars.csp | 1 + .../csp/grammar/test/level_0/par_comma.csp | 1 + .../csp/grammar/test/level_0/paren_proc.csp | 1 + .../avlsi/csp/grammar/test/level_0/peek.csp | 1 + .../avlsi/csp/grammar/test/level_0/recv.csp | 1 + .../csp/grammar/test/level_0/recv_var.csp | 1 + .../avlsi/csp/grammar/test/level_0/repeat.csp | 1 + .../csp/grammar/test/level_0/repeat_det.csp | 1 + .../grammar/test/level_0/repeat_det_else.csp | 1 + .../csp/grammar/test/level_0/repeat_nd.csp | 1 + .../grammar/test/level_0/repeat_nd_else.csp | 1 + .../csp/grammar/test/level_0/repeat_true.csp | 1 + .../csp/grammar/test/level_0/sel_expr_add.csp | 1 + .../csp/grammar/test/level_0/sel_expr_and.csp | 1 + .../grammar/test/level_0/sel_expr_array.csp | 1 + .../test/level_0/sel_expr_array_2d.csp | 1 + .../csp/grammar/test/level_0/sel_expr_div.csp | 1 + .../csp/grammar/test/level_0/sel_expr_eq.csp | 1 + .../csp/grammar/test/level_0/sel_expr_geq.csp | 1 + .../csp/grammar/test/level_0/sel_expr_gt.csp | 1 + .../csp/grammar/test/level_0/sel_expr_hex.csp | 1 + .../csp/grammar/test/level_0/sel_expr_leq.csp | 1 + .../test/level_0/sel_expr_loop_add.csp | 1 + .../test/level_0/sel_expr_loop_and.csp | 1 + .../test/level_0/sel_expr_loop_mul.csp | 1 + .../grammar/test/level_0/sel_expr_loop_or.csp | 1 + .../csp/grammar/test/level_0/sel_expr_lt.csp | 1 + .../csp/grammar/test/level_0/sel_expr_mod.csp | 1 + .../csp/grammar/test/level_0/sel_expr_mul.csp | 1 + .../csp/grammar/test/level_0/sel_expr_neg.csp | 1 + .../csp/grammar/test/level_0/sel_expr_neq.csp | 1 + .../csp/grammar/test/level_0/sel_expr_not.csp | 1 + .../grammar/test/level_0/sel_expr_octal.csp | 1 + .../csp/grammar/test/level_0/sel_expr_or.csp | 1 + .../grammar/test/level_0/sel_expr_paren.csp | 1 + .../grammar/test/level_0/sel_expr_peek.csp | 1 + .../grammar/test/level_0/sel_expr_probe.csp | 1 + .../grammar/test/level_0/sel_expr_recv.csp | 1 + .../csp/grammar/test/level_0/sel_expr_shl.csp | 1 + .../csp/grammar/test/level_0/sel_expr_shr.csp | 1 + .../csp/grammar/test/level_0/sel_expr_sub.csp | 1 + .../grammar/test/level_0/select_wait_id.csp | 1 + .../grammar/test/level_0/select_wait_true.csp | 1 + .../test/level_0/select_wait_true_skip.csp | 1 + .../avlsi/csp/grammar/test/level_0/send.csp | 1 + .../csp/grammar/test/level_0/send_expr.csp | 1 + .../csp/grammar/test/level_0/send_var.csp | 1 + .../avlsi/csp/grammar/test/level_0/seq.csp | 1 + .../avlsi/csp/grammar/test/level_0/skip.csp | 1 + .../avlsi/csp/grammar/test/level_1/alt.csp | 7 + .../csp/grammar/test/level_1/bit_bucket.csp | 1 + .../csp/grammar/test/level_1/bit_gen.csp | 1 + .../avlsi/csp/resources/csp2rtl.properties | 14 + .../csp/resources/preprocessor.properties | 2 + .../avlsi/csp/resources/resources.package.inc | 4 + .../csp/resources/typechecker.properties | 113 + .../avlsi/csp/util/ArithmeticOperator.java | 61 + .../src/com/avlsi/csp/util/CSPCellInfo.java | 63 + .../com/avlsi/csp/util/ConstantEvaluator.java | 1517 +++ .../src/com/avlsi/csp/util/CspCallback.java | 173 + .../java/src/com/avlsi/csp/util/CspUtils.java | 33 + .../avlsi/csp/util/DeclarationProcessor.java | 27 + .../avlsi/csp/util/FilterInitializers.java | 43 + .../avlsi/csp/util/FunctionPreprocessor.java | 1396 +++ .../java/src/com/avlsi/csp/util/Interval.java | 670 ++ .../avlsi/csp/util/NullResourceBundle.java | 9 + .../java/src/com/avlsi/csp/util/Problem.java | 12 + .../src/com/avlsi/csp/util/ProblemFilter.java | 90 + .../avlsi/csp/util/RefinementResolver.java | 453 + .../src/com/avlsi/csp/util/RemoveScalars.java | 67 + .../src/com/avlsi/csp/util/SimpleProblem.java | 41 + .../src/com/avlsi/csp/util/SymbolTable.java | 57 + .../src/com/avlsi/csp/util/UniqueLabel.java | 22 + .../csp/util/VariableAnalysisException.java | 22 + .../com/avlsi/csp/util/VariableAnalyzer.java | 2196 ++++ .../com/avlsi/csp/util/VisitorByCategory.java | 432 + .../util/VisitorExceptionWithLocation.java | 47 + .../fast/AnonymousInstanceException.java | 16 + .../java/src/com/avlsi/fast/AssertBlock.java | 78 + .../java/src/com/avlsi/fast/BlockCommon.java | 127 + .../src/com/avlsi/fast/BlockInterface.java | 79 + .../src/com/avlsi/fast/BlockIterator.java | 34 + .../java/src/com/avlsi/fast/CastDesign.java | 1478 +++ .../java/src/com/avlsi/fast/CellBlock.java | 30 + .../cad/java/src/com/avlsi/fast/CellNet.java | 1143 +++ .../cad/java/src/com/avlsi/fast/CellType.java | 1928 ++++ .../src/com/avlsi/fast/CellTypeProcessor.java | 26 + .../java/src/com/avlsi/fast/ChannelNet.java | 57 + .../src/com/avlsi/fast/ConnectionInfo.java | 423 + .../cad/java/src/com/avlsi/fast/CspBlock.java | 133 + .../src/com/avlsi/fast/DirectiveBlock.java | 96 + .../cad/java/src/com/avlsi/fast/EnvBlock.java | 162 + .../java/src/com/avlsi/fast/HalfOperator.java | 677 ++ .../java/src/com/avlsi/fast/JavaBlock.java | 28 + .../src/com/avlsi/fast/MergeDirective.java | 138 + .../NamedEnvironmentRedeclaredException.java | 28 + .../src/com/avlsi/fast/NetlistAdapter.java | 996 ++ .../java/src/com/avlsi/fast/NetlistBlock.java | 113 + .../com/avlsi/fast/ParamTypeInterface.java | 24 + .../cad/java/src/com/avlsi/fast/PrsBlock.java | 55 + .../java/src/com/avlsi/fast/PrsDirective.java | 438 + .../java/src/com/avlsi/fast/SubcellBlock.java | 49 + .../java/src/com/avlsi/fast/VerilogBlock.java | 312 + .../fast/metaparameters/ArrayMetaParam.java | 97 + .../fast/metaparameters/BooleanMetaParam.java | 26 + .../fast/metaparameters/FloatMetaParam.java | 25 + .../fast/metaparameters/IntegerMetaParam.java | 27 + .../metaparameters/MetaParamDefinition.java | 64 + .../MetaParamTypeInterface.java | 26 + .../src/com/avlsi/fast/ports/ArrayType.java | 77 + .../src/com/avlsi/fast/ports/ChannelType.java | 120 + .../src/com/avlsi/fast/ports/NodeType.java | 53 + .../com/avlsi/fast/ports/PortDefinition.java | 184 + .../avlsi/fast/ports/PortTypeInterface.java | 25 + .../com/avlsi/fast/ports/StructureType.java | 79 + .../shapes/ArgumentMismatchException.java | 17 + .../java/src/com/avlsi/fast/shapes/Point.java | 29 + .../src/com/avlsi/fast/shapes/Polygon.java | 24 + .../avlsi/fast/shapes/PolygonIterator.java | 30 + .../java/src/com/avlsi/fast/shapes/Shape.java | 80 + .../avlsi/fast/shapes/ShapeCollection.java | 22 + .../fast/shapes/ShapeCollectionIterator.java | 30 + .../com/avlsi/fast/shapes/ShapeFactory.java | 33 + .../com/avlsi/fast/shapes/ShapeFunction.java | 69 + .../ShapeFunctionRedefinedException.java | 15 + .../avlsi/fast/shapes/ShapeFunctionTable.java | 26 + .../ShapeFunctionUndefinedException.java | 15 + .../com/avlsi/fast/shapes/ShapeIterator.java | 30 + .../com/avlsi/fast/shapes/ShapesBlock.java | 22 + .../fast/shapes/ShapesBlockIterator.java | 28 + .../com/avlsi/fast/shapes/WriteablePoint.java | 25 + .../com/avlsi/fast/shapes/WriteableShape.java | 27 + .../fast/shapes/WriteableShapeCollection.java | 31 + .../WriteableShapeCollectionIterator.java | 38 + .../shapes/WriteableShapeFunctionTable.java | 26 + .../fast/shapes/WriteableShapesBlock.java | 34 + .../avlsi/fast/shapes/impl/PolygonImpl.java | 68 + .../fast/shapes/impl/ShapeFactoryImpl.java | 46 + .../fast/shapes/impl/ShapeFunctionImpl.java | 310 + .../avlsi/fast/shapes/impl/SkillExporter.java | 151 + .../fast/shapes/impl/WriteablePointImpl.java | 58 + .../impl/WriteableShapeCollectionImpl.java | 92 + .../impl/WriteableShapeFunctionTableImpl.java | 47 + .../fast/shapes/impl/WriteableShapeImpl.java | 118 + .../shapes/impl/WriteableShapesBlockImpl.java | 67 + .../com/avlsi/fast/shapes/impl/parser/Shape.g | 712 ++ .../avlsi/fast/shapes/impl/parser/custom.mk | 5 + .../stringexpression/StringExpression.java | 68 + .../StringExpressionCollection.java | 37 + .../StringExpressionCollectionIterator.java | 61 + .../StringExpressionFactory.java | 68 + .../stringexpression/StringVisitor.java | 28 + .../WriteableStringExpressionCollection.java | 40 + ...bleStringExpressionCollectionIterator.java | 40 + .../stringexpression/impl/ConcatOperator.java | 214 + .../stringexpression/impl/Constant.java | 55 + .../stringexpression/impl/OperatorCommon.java | 71 + .../impl/SkillStringVisitor.java | 75 + .../impl/StringExpressionFactoryImpl.java | 50 + .../impl/SubExpressionReference.java | 152 + .../impl/VariableReference.java | 58 + ...iteableStringExpressionCollectionImpl.java | 171 + .../impl/parser/StringExpression.g | 185 + .../stringexpression/impl/parser/custom.mk | 5 + .../variable/StringVariable.java | 28 + .../variable/StringVariableDictionary.java | 38 + .../StringVariableDictionaryIterator.java | 37 + .../variable/StringVariableUtil.java | 70 + .../variable/WriteableStringVariable.java | 25 + .../WriteableStringVariableDictionary.java | 46 + ...eableStringVariableDictionaryIterator.java | 40 + ...WriteableStringVariableDictionaryImpl.java | 156 + .../avlsi/file/aspice/AbstractDeviceTest.java | 109 + .../src/com/avlsi/file/aspice/AspiceCell.java | 585 ++ .../src/com/avlsi/file/aspice/AspiceFile.java | 646 ++ .../src/com/avlsi/file/aspice/BSim3Model.java | 1623 +++ .../src/com/avlsi/file/aspice/Capacitor.java | 157 + .../com/avlsi/file/aspice/CapacitorTest.java | 66 + .../file/aspice/CastTestEnvironment.java | 144 + .../avlsi/file/aspice/DeviceInterface.java | 38 + .../java/src/com/avlsi/file/aspice/Diode.java | 333 + .../src/com/avlsi/file/aspice/DiodeTest.java | 75 + .../com/avlsi/file/aspice/GraphCharge.java | 40 + .../file/aspice/GraphChargeDerivative.java | 53 + .../com/avlsi/file/aspice/GraphCurrent.java | 40 + .../file/aspice/GraphCurrentDerivative.java | 53 + .../com/avlsi/file/aspice/GraphPortData.java | 67 + .../avlsi/file/aspice/NoModelException.java | 23 + .../src/com/avlsi/file/aspice/PortData.java | 151 + .../src/com/avlsi/file/aspice/Resistor.java | 152 + .../com/avlsi/file/aspice/ResistorTest.java | 67 + .../src/com/avlsi/file/aspice/SizedModel.java | 731 ++ .../src/com/avlsi/file/aspice/Tester.java | 46 + .../src/com/avlsi/file/aspice/Transistor.java | 2209 ++++ .../com/avlsi/file/aspice/TransistorTest.java | 81 + .../java/src/com/avlsi/file/aspice/Wire.java | 89 + .../file/cdl/CDLFileFormatException.java | 34 + .../src/com/avlsi/file/cdl/CDLParser.java | 844 ++ .../file/cdl/parser/AspiceCellAdapter.java | 228 + .../java/src/com/avlsi/file/cdl/parser/CDL.g | 1291 +++ .../com/avlsi/file/cdl/parser/CDLAliases.java | 419 + .../file/cdl/parser/CDLDeviceNameFilter.java | 88 + .../file/cdl/parser/CDLFactoryAdaptor.java | 58 + .../file/cdl/parser/CDLFactoryEmitter.java | 382 + .../file/cdl/parser/CDLFactoryFilter.java | 79 + .../file/cdl/parser/CDLFactoryInterface.java | 130 + .../file/cdl/parser/CDLInlineFactory.java | 348 + .../cdl/parser/CDLInterfaceSimplifier.java | 152 + .../file/cdl/parser/CDLNodeNameFilter.java | 95 + .../avlsi/file/cdl/parser/CDLScaleBali.java | 265 + .../file/cdl/parser/CDLScalingFactory.java | 187 + .../file/cdl/parser/CDLSimpleFilter.java | 68 + .../avlsi/file/cdl/parser/CDLSimpleImpl.java | 43 + .../file/cdl/parser/CDLSimpleInterface.java | 107 + .../com/avlsi/file/cdl/parser/CDLstat.java | 634 ++ .../file/cdl/parser/CanonicalizeCDL.java | 89 + .../avlsi/file/cdl/parser/CellSetFactory.java | 30 + .../parser/ChildrenFirstTemplateIterator.java | 268 + .../src/com/avlsi/file/cdl/parser/Inline.java | 328 + .../com/avlsi/file/cdl/parser/Inliner.java | 66 + .../cdl/parser/InternalNodeFilterFactory.java | 38 + .../file/cdl/parser/LVSNodesCDLFactory.java | 270 + .../file/cdl/parser/LVSNodesHandler.java | 28 + .../file/cdl/parser/LVSNodesNullHandler.java | 31 + .../file/cdl/parser/NetlistBlockFactory.java | 355 + .../file/cdl/parser/ReadCDLIntoFactory.java | 64 + .../cdl/parser/RemoveLVSNodesCDLFactory.java | 394 + .../file/cdl/parser/RenumberFactory.java | 313 + .../file/cdl/parser/SplittingFactory.java | 94 + .../com/avlsi/file/cdl/parser/Template.java | 894 ++ .../file/cdl/parser/TemplateIterator.java | 22 + .../cdl/parser/TemplateSplitterFactory.java | 153 + .../src/com/avlsi/file/cdl/parser/custom.mk | 16 + .../avlsi/file/cdl/parser/javafiles-custom.mk | 5 + .../com/avlsi/file/cdl/util/CDLWriter.java | 156 + .../rename/BindRulNameInterfaceFactory.java | 387 + .../cdl/util/rename/CDLNameInterface.java | 30 + .../file/cdl/util/rename/CDLNameInterface.py | 17 + .../util/rename/CDLNameInterfaceFactory.java | 20 + .../cdl/util/rename/CDLRenameException.java | 38 + .../cdl/util/rename/CDLRenameFactory.java | 201 + .../file/cdl/util/rename/CDLRenamer.java | 343 + .../cdl/util/rename/CDLRenamerFactory.java | 491 + .../cdl/util/rename/CachingNameInterface.java | 159 + .../cdl/util/rename/CadenceNameInterface.java | 248 + .../cdl/util/rename/CadenceNames2CastNames.py | 117 + .../rename/CadenceReverseNameInterface.java | 200 + .../cdl/util/rename/CastNames2CadenceNames.py | 116 + .../cdl/util/rename/CastNames2GDSIINames.py | 50 + .../rename/CompositeCDLNameInterface.java | 47 + .../CompositeCDLNameInterfaceFactory.java | 35 + .../file/cdl/util/rename/CompositeNames.py | 22 + .../cdl/util/rename/GDS2NameInterface.java | 114 + .../util/rename/GDS2ReverseNameInterface.java | 137 + .../cdl/util/rename/GDSIINames2CastNames.py | 80 + .../util/rename/IdentityNameInterface.java | 42 + .../file/cdl/util/rename/IdentityNames.py | 17 + .../cdl/util/rename/PMCHackNameInterface.java | 64 + .../cdl/util/rename/RCXHackNameInterface.java | 206 + .../util/rename/ReloadableNameInterface.java | 185 + .../avlsi/file/cdl/util/rename/Rename.java | 415 + .../TrivialCDLNameInterfaceFactory.java | 28 + .../avlsi/file/cdl/util/rename/__init__.py | 0 .../file/cdl/util/rename/cdlrenamer.package | 9 + .../com/avlsi/file/cdl/util/rename/custom.mk | 12 + .../com/avlsi/file/cdl/util/rename/rename.py | 94 + .../com/avlsi/file/cdl/util/rename/rename.sh | 4 + .../src/com/avlsi/file/common/Capacitor.java | 116 + .../com/avlsi/file/common/DeviceTypes.java | 37 + .../src/com/avlsi/file/common/HierName.java | 1040 ++ .../file/common/InvalidHierNameException.java | 36 + .../com/avlsi/file/common/TestHierName.java | 56 + .../src/com/avlsi/file/ext/Environment.java | 105 + .../java/src/com/avlsi/file/ext/ExtCell.java | 419 + .../cad/java/src/com/avlsi/file/ext/FET.java | 100 + .../cad/java/src/com/avlsi/file/ext/Node.java | 132 + .../ResistanceClassOutOfBoundsException.java | 43 + .../java/src/com/avlsi/file/ext/Terminal.java | 45 + .../com/avlsi/file/ext/parse/ArraySpec.java | 178 + .../ext/parse/ExtFileFormatException.java | 51 + .../com/avlsi/file/ext/parse/ExtParser.java | 1109 +++ .../avlsi/file/spice/SimulatorInterface.java | 33 + .../file/spice/SpiceFileFormatException.java | 33 + .../src/com/avlsi/file/spice/SpiceParser.java | 1016 ++ .../file/verilog/grammar/PortDeclaration.g | 139 + .../com/avlsi/file/verilog/grammar/custom.mk | 13 + .../com/avlsi/file/verilog/grammar/verilog.g | 1201 +++ .../com/avlsi/floorplanning/CellListFile.java | 98 + .../GenerateFloorPlanningData.java | 1322 +++ .../avlsi/floorplanning/PCellTypeInfo.java | 19 + .../avlsi/floorplanning/PCellTypesInfo.java | 31 + .../floorplanning/PCellTypesInfoImpl.java | 146 + .../PropertyFilePCellTypeInfo.java | 56 + .../PropertyFileTransistorTypeInfo.java | 58 + .../floorplanning/TransistorTypeInfo.java | 21 + .../src/com/avlsi/geometry/BoundingBox.java | 180 + .../java/src/com/avlsi/geometry/Point.java | 58 + .../src/com/avlsi/geometry/SteinnerTree.java | 63 + .../src/com/avlsi/geometry/Transform.java | 107 + .../src/com/avlsi/io/CopyingOutputStream.java | 51 + .../avlsi/io/EmptyPositionStackException.java | 36 + .../java/src/com/avlsi/io/FileSearchPath.java | 550 + .../cad/java/src/com/avlsi/io/FileUtil.java | 67 + .../src/com/avlsi/io/IndentPrintWriter.java | 107 + .../java/src/com/avlsi/io/IndentWriter.java | 102 + .../com/avlsi/io/LineContinuationStream.java | 72 + .../cad/java/src/com/avlsi/io/NullWriter.java | 35 + .../java/src/com/avlsi/io/OutputPumper.java | 33 + .../src/com/avlsi/io/PositionStackReader.java | 404 + .../cad/java/src/com/avlsi/io/Printable.java | 87 + .../cad/java/src/com/avlsi/io/SearchPath.java | 88 + .../src/com/avlsi/io/SearchPathDirectory.java | 45 + .../avlsi/io/SearchPathDirectoryIterator.java | 27 + .../java/src/com/avlsi/io/SearchPathFile.java | 58 + .../com/avlsi/io/SearchPathFileFilter.java | 22 + .../com/avlsi/io/SearchPathFileIterator.java | 26 + .../java/src/com/avlsi/io/StreamLexer.java | 1282 +++ .../src/com/avlsi/io/StringBuilderWriter.java | 68 + .../com/avlsi/io/TestPositionStackReader.java | 246 + .../src/com/avlsi/io/TestStreamLexer.java | 50 + .../java/src/com/avlsi/io/TokenException.java | 41 + .../com/avlsi/io/TokenNotDoubleException.java | 36 + .../com/avlsi/io/TokenNotEOFException.java | 32 + .../avlsi/io/TokenNotIdentifierException.java | 32 + .../com/avlsi/io/TokenNotIntException.java | 42 + .../avlsi/io/TokenNotLiteralException.java | 32 + .../io/TokenNotQuotedStringException.java | 32 + .../com/avlsi/io/TokenNotSymbolException.java | 41 + .../avlsi/io/TokenNotWhitespaceException.java | 32 + .../com/avlsi/io/TrivialSearchPathFile.java | 121 + .../src/com/avlsi/io/WrapPrintStream.java | 82 + .../src/com/avlsi/io/WrapPrintWriter.java | 82 + .../java/src/com/avlsi/layout/AP1ofNDef.java | 194 + .../src/com/avlsi/layout/APChannelDef.java | 85 + .../avlsi/layout/APDefaultPortDefFactory.java | 68 + .../avlsi/layout/APHorizontalStrutDef.java | 27 + .../com/avlsi/layout/APInPlaceChannelDef.java | 36 + .../com/avlsi/layout/APInPlaceNodeDef.java | 28 + .../avlsi/layout/APInPlacePortDefFactory.java | 43 + .../java/src/com/avlsi/layout/APLocale.java | 504 + .../java/src/com/avlsi/layout/APNodeDef.java | 23 + .../com/avlsi/layout/APPitchedNodeDef.java | 79 + .../java/src/com/avlsi/layout/APPortDef.java | 61 + .../com/avlsi/layout/APPortDefFactory.java | 28 + .../src/com/avlsi/layout/APPowerGridDef.java | 75 + .../java/src/com/avlsi/layout/AutoPins.java | 252 + .../src/com/avlsi/layout/CellDirs2Skill.java | 175 + .../layout/CellInterfaceActionInterface.java | 16 + .../layout/CellInterfacePortCollector.java | 132 + .../src/com/avlsi/layout/CellProcessor.java | 352 + .../avlsi/layout/CellProcessorException.java | 20 + .../avlsi/layout/CellProcessorInterface.java | 22 + .../HierarchicalDirectiveInterface.java | 87 + .../com/avlsi/layout/InstanceCallback.java | 124 + .../java/src/com/avlsi/layout/LVSNodes.java | 51 + .../com/avlsi/layout/LVSNodesForExtract.java | 322 + .../avlsi/layout/LVSNodesForHierarchy.java | 312 + .../src/com/avlsi/layout/LayerCallback.java | 67 + .../java/src/com/avlsi/layout/MapUtils.java | 40 + .../java/src/com/avlsi/layout/PinGlobal.java | 31 + .../com/avlsi/layout/PinPlaceException.java | 15 + .../avlsi/layout/SkillDirectiveEmitter.java | 200 + .../avlsi/layout/SkillStringInterface.java | 11 + .../AssuraBindRulTableEmitterFactory.java | 226 + .../layout/gdsII/CachingTableEmitter.java | 73 + ...ilterInternalNodesTableEmitterFactory.java | 119 + .../layout/gdsII/GDSIILVSNodesHandler.java | 325 + .../avlsi/layout/gdsII/GenerateGDSIIData.java | 480 + .../gdsII/GenerateGDSIIDataFactory.java | 240 + .../gdsII/SharedTableEmitterFactory.java | 113 + .../gdsII/SkillTableEmitterFactory.java | 207 + .../gdsII/SplittingTableEmitterFactory.java | 96 + .../layout/gdsII/TableEmitterException.java | 15 + .../gdsII/TableEmitterFactoryInterface.java | 20 + .../layout/gdsII/TableEmitterInterface.java | 30 + .../java/src/com/avlsi/layout/gdsII/custom.mk | 3 + .../src/com/avlsi/layout/javafiles-custom.mk | 1 + .../src/com/avlsi/netlist/AbstractDevice.java | 22 + .../avlsi/netlist/AbstractDeviceIterator.java | 31 + .../com/avlsi/netlist/AbstractNetlist.java | 58 + .../netlist/AbstractNetlistIterator.java | 31 + .../src/com/avlsi/netlist/AbstractNode.java | 38 + .../avlsi/netlist/AbstractNodeIterator.java | 31 + .../java/src/com/avlsi/netlist/Visitor.java | 144 + .../com/avlsi/netlist/impl/CDLEmitter.java | 256 + .../impl/ConcatAbstractDeviceIterator.java | 94 + .../avlsi/netlist/impl/DeviceProcessor.java | 226 + .../impl/DeviceProcessorInterface.java | 160 + .../avlsi/netlist/impl/FactoryEmitter.java | 163 + .../avlsi/netlist/impl/FoldTransistor.java | 161 + .../avlsi/netlist/impl/NetlistFormatter.java | 52 + .../netlist/impl/NumberedNodeNetlist.java | 320 + .../impl/SimpleAbstractDeviceIterator.java | 29 + .../impl/SimpleAbstractNetlistIterator.java | 29 + .../impl/SimpleAbstractNodeIterator.java | 29 + .../com/avlsi/netlist/impl/SkillEmitter.java | 161 + .../com/avlsi/netlist/impl/VisitorImpl.java | 68 + .../impl/simple/CDLReaderToNetlist.java | 50 + .../com/avlsi/netlist/impl/simple/Device.java | 29 + .../com/avlsi/netlist/impl/simple/FET.java | 110 + .../com/avlsi/netlist/impl/simple/Net.java | 89 + .../netlist/impl/simple/SimpleNetlist.java | 125 + .../impl/simple/SimpleNetlistFactory.java | 205 + .../avlsi/netlist/impl/simple/SubCircuit.java | 91 + .../util/ChildrenFirstNetlistIterator.java | 142 + .../netlist/util/CombiningNodeIterator.java | 42 + .../com/avlsi/netlist/util/FETIterator.java | 181 + .../netlist/util/FlatteningIterator.java | 305 + .../avlsi/netlist/util/SubcellIterator.java | 150 + .../src/com/avlsi/prs/ProductionRule.java | 547 + .../src/com/avlsi/prs/ProductionRuleSet.java | 88 + ...nimplementableProductionRuleException.java | 37 + .../java/src/com/avlsi/sync/Semaphore.java | 52 + .../src/com/avlsi/test/AbstractTestCase.java | 68 + .../src/com/avlsi/test/TestEverything.java | 82 + .../src/com/avlsi/test/TestFailedError.java | 30 + .../avlsi/tools/aspice/AbstractDevice.java | 108 + .../tools/aspice/AnalogTraceInterface.java | 38 + .../com/avlsi/tools/aspice/AnalogWatcher.java | 26 + .../com/avlsi/tools/aspice/BSim3Model.java | 1692 ++++ .../src/com/avlsi/tools/aspice/Capacitor.java | 132 + .../src/com/avlsi/tools/aspice/Circuit.java | 221 + .../com/avlsi/tools/aspice/CurrentSource.java | 118 + .../avlsi/tools/aspice/DefaultCallback.java | 286 + .../src/com/avlsi/tools/aspice/DevTester.java | 66 + .../com/avlsi/tools/aspice/DigitalDriver.java | 86 + .../src/com/avlsi/tools/aspice/Diode.java | 414 + .../avlsi/tools/aspice/ExpVoltageSource.java | 81 + .../com/avlsi/tools/aspice/GroundNode.java | 95 + .../src/com/avlsi/tools/aspice/Jaspice.java | 584 ++ .../aspice/JaspiceCallbackInterface.java | 31 + .../avlsi/tools/aspice/JaspiceCircuit.java | 692 ++ .../avlsi/tools/aspice/JaspiceException.java | 30 + .../com/avlsi/tools/aspice/JaspiceModule.java | 536 + .../com/avlsi/tools/aspice/JaspiceProp.java | 55 + .../com/avlsi/tools/aspice/NativeAspice.java | 162 + .../tools/aspice/NativeAspiceCircuit.java | 180 + .../avlsi/tools/aspice/NativeAspiceUtil.java | 264 + .../java/src/com/avlsi/tools/aspice/Node.java | 343 + .../avlsi/tools/aspice/PWLVoltageSource.java | 246 + .../tools/aspice/PulseVoltageSource.java | 95 + .../src/com/avlsi/tools/aspice/Resistor.java | 134 + .../avlsi/tools/aspice/SinVoltageSource.java | 86 + .../com/avlsi/tools/aspice/SizedModel.java | 731 ++ .../com/avlsi/tools/aspice/SourceHandler.java | 236 + .../com/avlsi/tools/aspice/TestCircuit.java | 255 + .../com/avlsi/tools/aspice/TraceElement.java | 72 + .../src/com/avlsi/tools/aspice/TraceFile.java | 232 + .../tools/aspice/TraceFileException.java | 28 + .../com/avlsi/tools/aspice/Transistor.java | 2285 +++++ .../com/avlsi/tools/aspice/VoltageSource.java | 149 + .../com/avlsi/tools/cadalyze/Cadalyze.java | 797 ++ .../src/com/avlsi/tools/cadalyze/Cell.java | 943 ++ .../tools/cadalyze/DoubleDistribution.java | 240 + .../com/avlsi/tools/cadalyze/HtmlPage.java | 218 + .../com/avlsi/tools/cadalyze/LayoutInfo.java | 256 + .../com/avlsi/tools/cadalyze/LeafStats.java | 658 ++ .../tools/cadalyze/NetGraphAnalyzer.java | 1697 ++++ .../com/avlsi/tools/cadalyze/NodeProps.java | 341 + .../com/avlsi/tools/cadalyze/cadalyze.package | 8 + .../src/com/avlsi/tools/cadalyze/custom.mk | 5 + .../cadencize/CadenceActionInterface.java | 72 + .../tools/cadencize/CadenceDataInterface.java | 115 + .../cadencize/CadenceDataTreeMapImpl.java | 208 + .../avlsi/tools/cadencize/CadenceInfo.java | 335 + .../com/avlsi/tools/cadencize/Cadencize.java | 929 ++ .../CadencizeDataInterfaceActionHandler.java | 85 + .../cadencize/CadencizeOutputToSkill.java | 303 + .../avlsi/tools/cadencize/SubCellFile.java | 177 + .../com/avlsi/tools/cast2def/Cast2Def.java | 539 + .../avlsi/tools/cast2def/cast2def.package.inc | 8 + .../src/com/avlsi/tools/cast2def/custom.mk | 5 + .../avlsi/tools/cast2skill/Cast2Skill.java | 763 ++ .../src/com/avlsi/tools/cast2skill/custom.mk | 9 + .../tools/cast2verilog/Cast2Verilog.java | 3325 +++++++ .../tools/cast2verilog/cast2verilog.package | 13 + .../com/avlsi/tools/cast2verilog/custom.mk | 9 + .../tools/cast2verilog/verilog_filelist.pl | 38 + .../avlsi/tools/cdl2aspice/CDL2Aspice.java | 88 + .../com/avlsi/tools/cdl2cast/CDL2Cast.java | 1528 +++ .../com/avlsi/tools/cdl2cast/cdl2cast.package | 8 + .../src/com/avlsi/tools/cdl2cast/custom.mk | 9 + .../com/avlsi/tools/cdl2skill/CDL2Skill.java | 189 + .../tools/cdl2skill/CDL2SkillException.java | 19 + .../tools/cdl2skill/CDL2SkillFactory.java | 745 ++ .../com/avlsi/tools/cell/CellConstants.java | 105 + .../cad/java/src/com/avlsi/tools/cosim/.empty | 0 .../com/avlsi/tools/cosim/CSPCoSimInfo.java | 57 + .../avlsi/tools/cosim/ChannelDictionary.java | 54 + .../tools/cosim/ChannelFactoryInterface.java | 53 + .../tools/cosim/ChannelParameterDict.java | 116 + .../avlsi/tools/cosim/ChannelTimingInfo.java | 43 + .../cosim/CoSimChannelArrayInterface.java | 17 + .../tools/cosim/CoSimChannelInputArray.java | 115 + .../avlsi/tools/cosim/CoSimChannelNames.java | 100 + .../tools/cosim/CoSimChannelOutputArray.java | 122 + .../com/avlsi/tools/cosim/CoSimHelper.java | 670 ++ .../src/com/avlsi/tools/cosim/CoSimInfo.java | 651 ++ .../avlsi/tools/cosim/CoSimParameters.java | 224 + .../cosim/DeviceConstructionException.java | 60 + .../avlsi/tools/cosim/DeviceParameters.java | 233 + .../tools/cosim/InternalChannelInfo.java | 68 + .../avlsi/tools/cosim/JavaClassParameter.java | 83 + .../avlsi/tools/cosim/JavaCoSimDevice.java | 198 + .../com/avlsi/tools/cosim/JavaCoSimInfo.java | 157 + .../tools/cosim/NodeFactoryInterface.java | 23 + .../tools/cosim/NodeLinkageInterface.java | 36 + .../tools/cosim/spec/AcceptorInterface.java | 5 + .../src/com/avlsi/tools/cosim/spec/CoSim.g | 305 + .../src/com/avlsi/tools/cosim/spec/CoSim.java | 136 + .../tools/cosim/spec/CoSimLevelSpec.java | 75 + .../com/avlsi/tools/cosim/spec/CoSimSpec.java | 71 + .../tools/cosim/spec/CoSimSpecCallback.java | 37 + .../avlsi/tools/cosim/spec/CoSimSpecList.java | 72 + .../spec/DuplicateInstanceSpecException.java | 57 + .../spec/ExtraInstanceSpecException.java | 60 + .../cosim/spec/HierarchyDepthException.java | 62 + .../com/avlsi/tools/cosim/spec/InstSpec.java | 68 + .../avlsi/tools/cosim/spec/InstSpecList.java | 62 + .../tools/cosim/spec/LevelSpecInterface.java | 21 + .../src/com/avlsi/tools/cosim/spec/Mode.java | 118 + .../com/avlsi/tools/cosim/spec/ModeList.java | 80 + .../tools/cosim/spec/ModeListLevelSpec.java | 51 + .../cosim/spec/NoSuchInstanceException.java | 69 + .../tools/cosim/spec/VisitorInterface.java | 12 + .../src/com/avlsi/tools/cosim/spec/custom.mk | 6 + .../com/avlsi/tools/difflayout/DiffLayer.java | 70 + .../avlsi/tools/difflayout/DiffLayers.java | 72 + .../com/avlsi/tools/difflayout/GDSIIFile.java | 95 + .../com/avlsi/tools/difflayout/LayerInfo.java | 47 + .../tools/difflayout/LayeredPolygon.java | 44 + .../avlsi/tools/difflayout/PolygonUtils.java | 34 + .../com/avlsi/tools/dsim/BinningQueue.java | 244 + .../com/avlsi/tools/dsim/CutoffChecker.java | 171 + .../java/src/com/avlsi/tools/dsim/DSim.java | 5847 +++++++++++ .../src/com/avlsi/tools/dsim/DSimDebug.java | 43 + .../src/com/avlsi/tools/dsim/DSimMain.java | 47 + .../avlsi/tools/dsim/DSimSynchronizer.java | 97 + .../src/com/avlsi/tools/dsim/DSimUtil.java | 618 ++ .../avlsi/tools/dsim/DigitalScheduler.java | 760 ++ .../java/src/com/avlsi/tools/dsim/Event.java | 57 + .../src/com/avlsi/tools/dsim/EventQueue.java | 410 + .../avlsi/tools/dsim/EventQueueInterface.java | 120 + .../tools/dsim/ExceptionPrettyPrinter.java | 218 + .../java/src/com/avlsi/tools/dsim/HalfOp.java | 211 + .../src/com/avlsi/tools/dsim/HalfOpEdge.java | 117 + .../src/com/avlsi/tools/dsim/HalfOpGraph.java | 155 + .../com/avlsi/tools/dsim/InputSlewCheck.java | 110 + .../com/avlsi/tools/dsim/InstanceData.java | 865 ++ .../tools/dsim/NoBehaviorFoundException.java | 26 + .../avlsi/tools/dsim/NoSuchCellException.java | 34 + .../java/src/com/avlsi/tools/dsim/Node.java | 778 ++ .../src/com/avlsi/tools/dsim/NodeWatcher.java | 31 + .../com/avlsi/tools/dsim/OutputSlewCheck.java | 37 + .../tools/dsim/ProcessMeasuredDelay.java | 517 + .../com/avlsi/tools/dsim/ProgressMeter.java | 77 + .../avlsi/tools/dsim/RandomEventQueue.java | 168 + .../src/com/avlsi/tools/dsim/Resetable.java | 27 + .../java/src/com/avlsi/tools/dsim/Rule.java | 555 ++ .../com/avlsi/tools/dsim/RunSlewChecks.java | 94 + .../com/avlsi/tools/dsim/RunStaticTiming.java | 1805 ++++ .../com/avlsi/tools/dsim/SchedulerRunner.java | 74 + .../com/avlsi/tools/dsim/SequencedEvent.java | 44 + .../src/com/avlsi/tools/dsim/SlewCheck.java | 145 + .../src/com/avlsi/tools/dsim/SlewChecker.java | 270 + .../com/avlsi/tools/dsim/SlewViolation.java | 100 + .../avlsi/tools/dsim/StaticizerSlewCheck.java | 146 + .../java/src/com/avlsi/tools/dsim/WakeAt.java | 75 + .../tools/dsim/dsim-readlineonly.package | 9 + .../src/com/avlsi/tools/dsim/dsim.package | 14 + .../com/avlsi/tools/dsim/javafiles-custom.mk | 18 + .../avlsi/tools/ext2aspice/Ext2Aspice.java | 422 + .../src/com/avlsi/tools/ext2cdl/Ext2Cdl.java | 215 + .../java/src/com/avlsi/tools/ilg/Edge.java | 204 + .../cad/java/src/com/avlsi/tools/ilg/GA.java | 146 + .../cad/java/src/com/avlsi/tools/ilg/ILG.java | 1068 ++ .../java/src/com/avlsi/tools/ilg/Layer.java | 366 + .../src/com/avlsi/tools/ilg/PlugEntry.java | 83 + .../java/src/com/avlsi/tools/ilg/Poly.java | 255 + .../src/com/avlsi/tools/ilg/PolyOperator.java | 245 + .../com/avlsi/tools/ilg/SortableVector.java | 65 + .../src/com/avlsi/tools/ilg/SortedEdges.java | 279 + .../java/src/com/avlsi/tools/ilg/Span.java | 116 + .../src/com/avlsi/tools/ilg/SpanList.java | 216 + .../java/src/com/avlsi/tools/ilg/Util.java | 117 + .../src/com/avlsi/tools/ilg/WellPlugData.java | 57 + .../com/avlsi/tools/ipgen/GenerateIPData.java | 659 ++ .../tools/ipgen/HashMapTableEmitter.java | 228 + .../ipgen/HashMapTableEmitterFactory.java | 76 + .../tools/ipgen/PMCNameInterfaceFactory.java | 239 + .../tools/ipgen/RenamingVerilogFactory.java | 277 + .../ipgen/TablifyingNameInterfaceFactory.java | 165 + .../java/src/com/avlsi/tools/ipgen/custom.mk | 8 + .../com/avlsi/tools/jauto/AbstractPath.java | 186 + .../com/avlsi/tools/jauto/AdditiveTerms.java | 42 + .../com/avlsi/tools/jauto/AutoThreshold.java | 553 + .../src/com/avlsi/tools/jauto/CDLOutput.java | 155 + .../tools/jauto/CGTransistorSizingTool.java | 231 + .../src/com/avlsi/tools/jauto/Cast2Cdl.java | 709 ++ .../src/com/avlsi/tools/jauto/CastQuery.g | 176 + .../src/com/avlsi/tools/jauto/CastQuery.java | 4092 ++++++++ .../src/com/avlsi/tools/jauto/CastStat.java | 319 + .../src/com/avlsi/tools/jauto/CatPath.java | 1556 +++ .../com/avlsi/tools/jauto/CellHierarchyDump.g | 191 + .../avlsi/tools/jauto/CheckChargeTools.java | 177 + .../tools/jauto/ConjugateGradientSolver.java | 301 + .../src/com/avlsi/tools/jauto/CountPrs.java | 403 + .../com/avlsi/tools/jauto/DebugOption.java | 26 + .../avlsi/tools/jauto/DelayCalculator.java | 403 + .../src/com/avlsi/tools/jauto/Floorplan.java | 395 + .../avlsi/tools/jauto/FunctionSimplifier.java | 248 + .../com/avlsi/tools/jauto/FunctionTerm.java | 373 + .../jauto/GenerateChargeSharingTests.java | 997 ++ .../tools/jauto/GeneratePLTSubtypes.java | 317 + .../src/com/avlsi/tools/jauto/GlobalNet.java | 2569 +++++ .../avlsi/tools/jauto/IdleStateSolver.java | 196 + .../java/src/com/avlsi/tools/jauto/Jauto.java | 2298 +++++ .../com/avlsi/tools/jauto/JautoMessage.java | 127 + .../avlsi/tools/jauto/JautoMessageCenter.java | 173 + .../com/avlsi/tools/jauto/JautoSolver.java | 379 + .../src/com/avlsi/tools/jauto/JautoUI.java | 2956 ++++++ .../src/com/avlsi/tools/jauto/JautoUtil.java | 176 + .../src/com/avlsi/tools/jauto/Jtimer.java | 2278 +++++ .../src/com/avlsi/tools/jauto/LeafSpec.java | 425 + .../src/com/avlsi/tools/jauto/MergeHint.java | 1389 +++ .../tools/jauto/NegativeDelayBudget.java | 932 ++ .../src/com/avlsi/tools/jauto/NetSink.java | 350 + .../src/com/avlsi/tools/jauto/NetSource.java | 308 + .../src/com/avlsi/tools/jauto/NetType.java | 28 + .../avlsi/tools/jauto/NetlistDistance.java | 708 ++ .../com/avlsi/tools/jauto/PartialExtract.java | 635 ++ .../avlsi/tools/jauto/SizeStaticizers.java | 516 + .../src/com/avlsi/tools/jauto/SizingPath.java | 760 ++ .../avlsi/tools/jauto/SubcellProcessor.java | 19 + .../jauto/SubprocessFailedException.java | 10 + .../com/avlsi/tools/jauto/SubtypeMerge.java | 680 ++ .../com/avlsi/tools/jauto/SubtypeOutput.java | 2578 +++++ .../com/avlsi/tools/jauto/SubtypeSplit.java | 499 + .../com/avlsi/tools/jauto/TechnologyData.java | 1763 ++++ .../src/com/avlsi/tools/jauto/Transistor.java | 105 + .../tools/jauto/TransistorSizingTool.java | 1804 ++++ .../com/avlsi/tools/jauto/cast2cdl.package | 13 + .../com/avlsi/tools/jauto/countprs.package | 8 + .../java/src/com/avlsi/tools/jauto/custom.mk | 65 + .../src/com/avlsi/tools/jauto/jauto.package | 37 + .../com/avlsi/tools/jauto/javafiles-custom.mk | 1 + .../java/src/com/avlsi/tools/jauto/jtimer.sh | 327 + .../com/avlsi/tools/jfast/AbstractDevice.java | 74 + .../com/avlsi/tools/jfast/BenchMarkJfast.java | 85 + .../src/com/avlsi/tools/jfast/TestDevice.java | 126 + .../java/src/com/avlsi/tools/jflat/JFlat.java | 4999 ++++++++++ .../java/src/com/avlsi/tools/jflat/custom.mk | 5 + .../com/avlsi/tools/jflat/javafiles-custom.mk | 4 + .../src/com/avlsi/tools/jflat/jflat.package | 10 + .../cad/java/src/com/avlsi/tools/lvs/Dnf.java | 295 + .../cad/java/src/com/avlsi/tools/lvs/LVS.java | 1477 +++ .../src/com/avlsi/tools/lvs/LVSProblem.java | 49 + .../src/com/avlsi/tools/lvs/LvsOperators.java | 465 + .../src/com/avlsi/tools/lvs/NetGraph.java | 3462 +++++++ .../src/com/avlsi/tools/lvs/NetToPrs.java | 149 + .../src/com/avlsi/tools/lvs/PrsToNet.java | 382 + .../src/com/avlsi/tools/lvs/Staticizer.java | 44 + .../src/com/avlsi/tools/lvs/SubtypeInfo.java | 86 + .../java/src/com/avlsi/tools/lvs/custom.mk | 10 + .../java/src/com/avlsi/tools/lvs/jlvs.package | 10 + .../src/com/avlsi/tools/presto/02-09-03.html | 901 ++ .../com/avlsi/tools/presto/ChannelName.java | 29 + .../avlsi/tools/presto/ChannelNameImpl.java | 74 + .../avlsi/tools/presto/LogicFileReader.java | 173 + .../src/com/avlsi/tools/presto/PReSto.java | 160 + .../src/com/avlsi/tools/presto/Presto2.java | 127 + .../com/avlsi/tools/presto/TruthTable.java | 31 + .../avlsi/tools/presto/TruthTableImpl.java | 100 + .../tools/presto/WarningAccumulator.java | 99 + .../avlsi/tools/presto/complete/Emitter.java | 11 + .../tools/presto/complete/GreedyComplete.java | 268 + .../com/avlsi/tools/presto/complete/Node.java | 129 + .../tools/presto/complete/NodeBuilder.java | 10 + .../tools/presto/complete/TreeMunger.java | 20 + .../tools/presto/complete/TreeReadjuster.java | 123 + .../java/src/com/avlsi/tools/presto/custom.mk | 9 + .../tools/presto/output/AbstractPrsLine.java | 41 + .../presto/output/AliasNodeExpression.java | 92 + .../tools/presto/output/And2C2Expression.java | 90 + .../output/ArbitraryNodeExpression.java | 304 + .../presto/output/CElementExpression.java | 60 + .../avlsi/tools/presto/output/Direction.java | 24 + .../tools/presto/output/LineAndSection.java | 16 + .../tools/presto/output/NandExpression.java | 64 + .../presto/output/NodeCanonicalizer.java | 15 + .../tools/presto/output/NodeExpression.java | 29 + .../avlsi/tools/presto/output/NodeName.java | 15 + .../tools/presto/output/NorExpression.java | 64 + .../avlsi/tools/presto/output/Organizer.java | 132 + .../presto/output/ParameterizedNodeName.java | 39 + .../com/avlsi/tools/presto/output/Power.java | 48 + .../avlsi/tools/presto/output/PrsLine.java | 22 + .../avlsi/tools/presto/output/PrsPrinter.java | 155 + .../avlsi/tools/presto/output/Section.java | 26 + .../tools/presto/output/SectionImpl.java | 55 + .../output/ShorthandNodeExpression.java | 164 + .../tools/presto/output/Simplification.java | 27 + .../presto/output/TwoAnd2C2Expression.java | 109 + .../output/UnparameterizedNodeName.java | 43 + .../tools/presto/output/WholeOperator.java | 52 + .../presto/output/WholeOperatorSink.java | 10 + .../src/com/avlsi/tools/presto/presto.package | 10 + .../tools/presto/template/CompletionInfo.java | 24 + .../tools/presto/template/Declarations.java | 34 + .../presto/template/DeclarationsImpl.java | 210 + .../tools/presto/template/DoCompletion.java | 355 + .../avlsi/tools/presto/template/DoLogic.java | 126 + .../avlsi/tools/presto/template/Doodad.java | 144 + .../tools/presto/template/SectionFactory.java | 91 + .../avlsi/tools/presto/template/Template.java | 599 ++ .../tools/presto/template/TestOutput.java | 110 + .../com/avlsi/tools/presto/test-one-cell.pl | 103 + .../com/avlsi/tools/presto/test-summary.txt | 7 + .../java/src/com/avlsi/tools/presto/test.cast | 217 + .../java/src/com/avlsi/tools/presto/test.pl | 47 + .../tools/prs2verilog/AbstractConverter.java | 594 ++ .../tools/prs2verilog/ConverterConstants.java | 26 + .../tools/prs2verilog/ConverterInterface.java | 43 + .../tools/prs2verilog/GateConverter.java | 298 + .../prs2verilog/GeneratePortMapping.java | 317 + .../tools/prs2verilog/GenerateWrapper.java | 379 + .../tools/prs2verilog/NetgraphConverter.java | 651 ++ .../prs2verilog/NetgraphGateConverter.java | 369 + .../tools/prs2verilog/NetlistConverter.java | 351 + .../avlsi/tools/prs2verilog/Prs2Verilog.java | 1149 +++ .../avlsi/tools/prs2verilog/TriConverter.java | 196 + .../src/com/avlsi/tools/prs2verilog/custom.mk | 15 + .../tools/prs2verilog/prs2verilog.package | 12 + .../prs2verilog/verilog/ArrayAccess.java | 22 + .../tools/prs2verilog/verilog/BinaryOp.java | 25 + .../prs2verilog/verilog/CompilationUnit.java | 21 + .../tools/prs2verilog/verilog/ConcatOp.java | 21 + .../prs2verilog/verilog/ContinuousAssign.java | 29 + .../tools/prs2verilog/verilog/Delay.java | 31 + .../avlsi/tools/prs2verilog/verilog/Expr.java | 21 + .../tools/prs2verilog/verilog/HierIdent.java | 21 + .../tools/prs2verilog/verilog/Ident.java | 26 + .../prs2verilog/verilog/LineComment.java | 21 + .../tools/prs2verilog/verilog/MacroUse.java | 23 + .../tools/prs2verilog/verilog/Module.java | 27 + .../tools/prs2verilog/verilog/ModuleInst.java | 30 + .../tools/prs2verilog/verilog/NamedPort.java | 23 + .../tools/prs2verilog/verilog/NetDecl.java | 35 + .../tools/prs2verilog/verilog/Parameter.java | 24 + .../prs2verilog/verilog/ParameterDecl.java | 23 + .../tools/prs2verilog/verilog/Primitive.java | 30 + .../verilog/SimpleRenamingVerilogFactory.java | 189 + .../prs2verilog/verilog/TrivialVisitor.java | 52 + .../tools/prs2verilog/verilog/UnaryOp.java | 23 + .../prs2verilog/verilog/VerilogEmitter.java | 249 + .../verilog/VerilogFactoryImpl.java | 112 + .../verilog/VerilogFactoryInterface.java | 56 + .../prs2verilog/verilog/VerilogObject.java | 12 + .../prs2verilog/verilog/VerilogUtil.java | 309 + .../prs2verilog/verilog/VerilogVisitor.java | 67 + .../com/avlsi/tools/rte/AutoSimulateCell.java | 2052 ++++ .../avlsi/tools/rte/ClientHandlerThread.java | 162 + .../src/com/avlsi/tools/rte/DSimHelper.java | 103 + .../src/com/avlsi/tools/rte/RTEClient.java | 311 + .../src/com/avlsi/tools/rte/RTEServer.java | 121 + .../avlsi/tools/rte/RegressionTestEngine.java | 776 ++ .../src/com/avlsi/tools/rte/SimResults.java | 359 + .../tools/rte/htmlWriter/FrameMaker.java | 61 + .../rte/htmlWriter/HtmlStandardWriter.java | 229 + .../tools/rte/htmlWriter/WriteCellList.java | 86 + .../tools/rte/htmlWriter/WriteSimResults.java | 80 + .../tools/rte/htmlWriter/WriteStatistics.java | 426 + .../tools/rte/htmlWriter/WriteTestList.java | 92 + .../tools/rte/htmlWriter/WriteTreeHier.java | 118 + .../com/avlsi/tools/rte/javafiles-custom.mk | 33 + .../java/src/com/avlsi/tools/rte/man/rte.1 | 177 + .../cad/java/src/com/avlsi/tools/rte/rte | 243 + .../java/src/com/avlsi/tools/rte/rte.package | 28 + .../avlsi/tools/rte/scripts/job_netbatch.pm | 551 + .../com/avlsi/tools/rte/scripts/pltReporter | 695 ++ .../java/src/com/avlsi/tools/rte/scripts/rte | 440 + .../avlsi/tools/rte/scripts/rteCellListGen | 584 ++ .../com/avlsi/tools/rte/scripts/rteDbMerge | 186 + .../com/avlsi/tools/rte/scripts/rteLauncher | 698 ++ .../src/com/avlsi/tools/rte/scripts/rteLib.pm | 1244 +++ .../com/avlsi/tools/rte/scripts/rteReporter | 604 ++ .../src/com/avlsi/tools/rte/scripts/util.pm | 708 ++ .../com/avlsi/tools/rte/scripts/verif_util.pm | 1338 +++ .../com/avlsi/tools/rte/share/examples.html | 441 + .../com/avlsi/tools/rte/share/help-doc.html | 144 + .../src/com/avlsi/tools/rte/share/logo.png | Bin 0 -> 11404 bytes .../com/avlsi/tools/rte/share/stylesheet.css | 54 + .../com/avlsi/tools/rte/share/test-info.html | 349 + .../com/avlsi/tools/sigscan/AnalogTrace.java | 114 + .../com/avlsi/tools/sigscan/Attribute.java | 199 + .../avlsi/tools/sigscan/AttributeEvent.java | 37 + .../avlsi/tools/sigscan/AttributeValue.java | 90 + .../avlsi/tools/sigscan/BeginTranEvent.java | 98 + .../avlsi/tools/sigscan/BooleanAttribute.java | 97 + .../avlsi/tools/sigscan/ChannelSigscan.java | 61 + .../com/avlsi/tools/sigscan/DebugOpts.java | 152 + .../com/avlsi/tools/sigscan/EndTranEvent.java | 61 + .../com/avlsi/tools/sigscan/GrowingArray.java | 54 + .../com/avlsi/tools/sigscan/IntAttribute.java | 89 + .../com/avlsi/tools/sigscan/LinkEvent.java | 50 + .../src/com/avlsi/tools/sigscan/LogEvent.java | 151 + .../com/avlsi/tools/sigscan/LoggedDouble.java | 79 + .../com/avlsi/tools/sigscan/LoggedInt.java | 79 + .../avlsi/tools/sigscan/LoggedLogicArray.java | 77 + .../com/avlsi/tools/sigscan/LoggedLong.java | 77 + .../com/avlsi/tools/sigscan/LoggedString.java | 79 + .../com/avlsi/tools/sigscan/LoggedVar.java | 111 + .../avlsi/tools/sigscan/LoggedVarEvent.java | 33 + .../avlsi/tools/sigscan/LoggingObject.java | 263 + .../avlsi/tools/sigscan/LongAttribute.java | 90 + .../com/avlsi/tools/sigscan/NativeHandle.java | 39 + .../com/avlsi/tools/sigscan/NodeLogger.java | 72 + .../com/avlsi/tools/sigscan/ObjectHandle.java | 38 + .../src/com/avlsi/tools/sigscan/README.html | 271 + .../src/com/avlsi/tools/sigscan/Sigscan.java | 974 ++ .../avlsi/tools/sigscan/SigscanException.java | 35 + .../avlsi/tools/sigscan/StringAttribute.java | 90 + .../com/avlsi/tools/sigscan/Transaction.java | 53 + .../avlsi/tools/sigscan/TransactionFiber.java | 281 + .../avlsi/tools/sigscan/TransactionType.java | 92 + .../avlsi/tools/sigscan/cppfiles-custom.mk | 8 + .../src/com/avlsi/tools/sigscan/custom.mk | 10 + .../avlsi/tools/sigscan/progfiles-custom.mk | 22 + .../src/com/avlsi/tools/sigscan/sigscan.cpp | 468 + .../avlsi/tools/sigscan/sigscan.package.inc | 36 + .../src/com/avlsi/tools/slacker/Cast.java | 602 ++ .../src/com/avlsi/tools/slacker/Channel.java | 155 + .../avlsi/tools/slacker/ObjectiveTerm.java | 33 + .../src/com/avlsi/tools/slacker/Slacker.java | 266 + .../src/com/avlsi/tools/slacker/Subcell.java | 52 + .../src/com/avlsi/tools/slacker/Type.java | 738 ++ .../src/com/avlsi/tools/slacker/custom.mk | 6 + .../com/avlsi/tools/slacker/slacker.package | 9 + .../avlsi/tools/spice2spice/Spice2Spice.java | 235 + .../avlsi/tools/spicemine/NetStatistics.java | 125 + .../spicemine/ProgressUpdateCallback.java | 38 + .../com/avlsi/tools/spicemine/SpiceMine.java | 988 ++ .../avlsi/tools/spicemine/test/maxpath.spice | 123 + .../tools/spicemine/test/testsubnet1.spice | 166 + .../tools/spicemine/test/testsubnet2.spice | 169 + .../tools/spicemine/test/testsubnet3.spice | 180 + .../tools/spicemine/test/testsubnet5.spice | 2196 ++++ .../com/avlsi/tools/spicemine/test/vdn.spice | 82 + .../cad/java/src/com/avlsi/tools/svs/SVS.java | 329 + .../com/avlsi/tools/synthesis/CellTiming.java | 1060 ++ .../synthesis/CellTimingProteusVCSetup.java | 248 + .../com/avlsi/tools/synthesis/Espresso.java | 150 + .../avlsi/tools/synthesis/GenerateCast.java | 147 + .../avlsi/tools/synthesis/GenerateLib.java | 1729 ++++ .../tools/synthesis/GenerateLogicLibrary.java | 215 + .../tools/synthesis/GenerateVerilog.java | 142 + .../com/avlsi/tools/synthesis/Karnaugh.java | 302 + .../com/avlsi/tools/synthesis/PathTiming.java | 477 + .../src/com/avlsi/tools/synthesis/Test.java | 146 + .../avlsi/tools/synthesis/TimingBlock.java | 405 + .../src/com/avlsi/tools/synthesis/Vector.java | 153 + .../src/com/avlsi/tools/synthesis/custom.mk | 9 + .../com/avlsi/tools/synthesis/synthesis.inc | 9 + .../avlsi/tools/synthesis/synthesis.package | 9 + .../com/avlsi/tools/tsim/AbstractDevice.java | 1332 +++ .../tools/tsim/AbstractDeviceThread.java | 64 + .../tsim/AbstractSingleThreadedDevice.java | 273 + .../avlsi/tools/tsim/AbstractSyncDevice.java | 206 + .../com/avlsi/tools/tsim/AccurateWait.java | 839 ++ .../src/com/avlsi/tools/tsim/Arbiter.java | 1081 ++ .../com/avlsi/tools/tsim/BenchMarkTsim.java | 82 + .../avlsi/tools/tsim/BitBucketChannel.java | 116 + .../com/avlsi/tools/tsim/BufferedChannel.java | 1509 +++ .../avlsi/tools/tsim/BufferedNodeChannel.java | 266 + .../tools/tsim/BufferedNodeReadChannel.java | 513 + .../tools/tsim/BufferedNodeWriteChannel.java | 550 + .../com/avlsi/tools/tsim/BusConnector.java | 63 + .../src/com/avlsi/tools/tsim/BusDriver.java | 33 + .../src/com/avlsi/tools/tsim/BusWatcher.java | 45 + .../src/com/avlsi/tools/tsim/ChanSetup.java | 186 + .../com/avlsi/tools/tsim/ChannelBundle.java | 91 + .../tools/tsim/ChannelCreationInterface.java | 20 + .../tools/tsim/ChannelFullException.java | 42 + .../src/com/avlsi/tools/tsim/ChannelIO.java | 34 + .../com/avlsi/tools/tsim/ChannelInput.java | 137 + .../avlsi/tools/tsim/ChannelInputAdapter.java | 44 + .../avlsi/tools/tsim/ChannelInputBundle.java | 254 + .../tools/tsim/ChannelInputListener.java | 61 + .../tools/tsim/ChannelInputUnfilter.java | 185 + .../com/avlsi/tools/tsim/ChannelOutput.java | 195 + .../tools/tsim/ChannelOutputAdapter.java | 46 + .../avlsi/tools/tsim/ChannelOutputBundle.java | 185 + .../avlsi/tools/tsim/ChannelOutputFilter.java | 159 + .../tools/tsim/ChannelOutputListener.java | 46 + .../com/avlsi/tools/tsim/ChannelStatus.java | 23 + .../java/src/com/avlsi/tools/tsim/Clock.java | 98 + .../src/com/avlsi/tools/tsim/ClockDriver.java | 122 + .../com/avlsi/tools/tsim/ClockWatcher.java | 35 + .../com/avlsi/tools/tsim/ClockedDevice.java | 178 + .../avlsi/tools/tsim/ConvenientDevice.java | 97 + .../java/src/com/avlsi/tools/tsim/Data.java | 529 + .../com/avlsi/tools/tsim/DelayElement.java | 57 + .../com/avlsi/tools/tsim/DelayedSetEvent.java | 69 + .../com/avlsi/tools/tsim/DeviceLogger.java | 222 + .../tools/tsim/EmptyWaitSetException.java | 52 + .../src/com/avlsi/tools/tsim/ExitEvent.java | 54 + .../src/com/avlsi/tools/tsim/ForceDriver.java | 22 + .../tools/tsim/IllegalSlackException.java | 57 + .../com/avlsi/tools/tsim/InaccurateWait.java | 49 + .../com/avlsi/tools/tsim/MergeConflict.java | 67 + .../src/com/avlsi/tools/tsim/MergeDevice.java | 158 + .../src/com/avlsi/tools/tsim/Message.java | 528 + .../com/avlsi/tools/tsim/NativeBusDriver.java | 28 + .../avlsi/tools/tsim/NoSuchNodeException.java | 46 + .../src/com/avlsi/tools/tsim/NodeChannel.java | 33 + .../com/avlsi/tools/tsim/NodeReadChannel.java | 239 + .../avlsi/tools/tsim/NodeWriteChannel.java | 204 + .../cad/java/src/com/avlsi/tools/tsim/README | 7 + .../src/com/avlsi/tools/tsim/RailList.java | 87 + .../com/avlsi/tools/tsim/SchedulerRunner.java | 51 + .../src/com/avlsi/tools/tsim/SharedBus.java | 870 ++ .../com/avlsi/tools/tsim/SharedBusEvent.java | 77 + .../tools/tsim/SlacklessNodeChannel.java | 214 + .../tools/tsim/SlacklessNodeReadChannel.java | 442 + .../tools/tsim/SlacklessNodeWriteChannel.java | 484 + .../src/com/avlsi/tools/tsim/SplitDevice.java | 89 + .../src/com/avlsi/tools/tsim/Startable.java | 28 + .../com/avlsi/tools/tsim/StateMachine.java | 79 + .../src/com/avlsi/tools/tsim/Statistics.java | 301 + .../src/com/avlsi/tools/tsim/Statusable.java | 11 + .../tools/tsim/SynchronousConverter.java | 184 + .../src/com/avlsi/tools/tsim/TSimDebug.java | 45 + .../avlsi/tools/tsim/TestChannelBundle.java | 74 + .../tools/tsim/TestChannelOutputBundle.java | 126 + .../com/avlsi/tools/tsim/TimingBuffer.java | 588 ++ .../tools/tsim/UnservicedEventException.java | 49 + .../java/src/com/avlsi/tools/tsim/Wait.java | 594 ++ .../src/com/avlsi/tools/tsim/WaitFactory.java | 121 + .../src/com/avlsi/tools/tsim/Waitable.java | 37 + .../com/avlsi/tools/tsim/WaiterInterface.java | 36 + .../src/com/avlsi/tools/tsim/WideNode.java | 48 + .../com/avlsi/tools/tsim/WideNodeImpl.java | 114 + .../com/avlsi/tools/tsim/channellib.package | 19 + .../avlsi/tools/tsim/examples/BusExample.java | 280 + .../tsim/examples/ConverterExample.java_ | 142 + .../tools/tsim/examples/MixedExample.java | 138 + .../src/com/avlsi/tools/tsim/package.html | 241 + .../com/avlsi/tools/tsim/test/Alternator.java | 87 + .../tools/tsim/test/BUFFERED_CHANNEL.cast | 28 + .../avlsi/tools/tsim/test/BenchMarkTsim.java | 83 + .../src/com/avlsi/tools/tsim/test/Buffer.java | 53 + .../src/com/avlsi/tools/tsim/test/Copy.java | 52 + .../avlsi/tools/tsim/test/DataGenerator.java | 87 + .../tools/tsim/test/NodeChannelTest.java | 134 + .../com/avlsi/tools/tsim/test/TestDevice.java | 95 + .../com/avlsi/tools/tsim/test/TestLoop.java | 58 + .../com/avlsi/tools/tsim/test/TokenRelay.java | 76 + .../tsim/test/buffered_channel_timing.txt | 6 + .../cad/java/src/com/avlsi/tools/tsim/test/go | 3 + .../com/avlsi/tools/tsim/test/histogram.pl | 36 + .../src/com/avlsi/tools/tsim/test/loopgraph | 14 + .../tsim/test/perf/AsyncBufferDevice.java | 46 + .../tools/tsim/test/perf/AsyncFIFOTest.java | 50 + .../tools/tsim/test/perf/AsyncSinkDevice.java | 58 + .../tsim/test/perf/AsyncSourceDevice.java | 54 + .../tools/tsim/test/perf/SyncFIFODevice.java | 74 + .../tools/tsim/test/perf/SyncFIFOTest.java | 68 + .../avlsi/tools/tsim/test/sync/SyncSink.java | 80 + .../tools/tsim/test/sync/SyncSource.java | 73 + .../avlsi/tools/tsim/test/sync/SyncTest.java | 39 + .../src/com/avlsi/tools/tsim/test/testloop | 3 + .../src/com/avlsi/tools/tsim/tsim.package.inc | 69 + .../tools/tsim/verilog/DeviceHandler.java | 20 + .../avlsi/tools/tsim/verilog/DeviceInfo.java | 56 + .../com/avlsi/tools/tsim/verilog/Server.java | 82 + .../tsim/verilog/SignalNotFoundException.java | 17 + .../tools/tsim/verilog/VerilogConnection.java | 251 + .../tools/tsim/verilog/VerilogInterface.java | 106 + .../tools/tsim/verilog/VerilogServer.java | 58 + .../tools/tsim/verilog/VerilogSharedBus.java | 156 + .../tools/tsim/verilog/VerilogTestClient.java | 109 + .../avlsi/tools/tsim/verilog/VerilogUtil.java | 70 + .../tools/tsim/verilog/VpiInterface.java | 358 + .../tools/tsim/verilog/verilog.package.inc | 9 + .../tools/verification/gen/Distribution.java | 116 + .../tools/verification/gen/FilePacket.java | 123 + .../avlsi/tools/verification/gen/GrabBag.java | 19 + .../avlsi/tools/verification/gen/LFSR.java | 177 + .../tools/verification/gen/LFSRPacket.java | 126 + .../verification/gen/OrderedGrabBag.java | 62 + .../avlsi/tools/verification/gen/Packet.java | 124 + .../tools/verification/gen/RandomGrabBag.java | 274 + .../tools/verification/gen/RandomPacket.java | 129 + .../tools/verification/gen/Streamable.java | 16 + .../tools/verification/gen/TestBags.java | 154 + .../avlsi/tools/verification/gen/TestGen.java | 115 + .../verification/gen/WeightedElement.java | 43 + .../bool/AbstractAtomicBooleanExpression.java | 71 + .../util/bool/AbstractBooleanExpression.java | 113 + .../avlsi/util/bool/AndBooleanExpression.java | 223 + .../bool/AndBooleanExpressionInterface.java | 42 + .../util/bool/BooleanExpressionInterface.java | 62 + .../BooleanExpressionVisitorInterface.java | 30 + .../src/com/avlsi/util/bool/BooleanUtils.java | 198 + .../bool/HierNameAtomicBooleanExpression.java | 91 + .../avlsi/util/bool/OrBooleanExpression.java | 218 + .../bool/OrBooleanExpressionInterface.java | 37 + .../src/com/avlsi/util/bool/TestBooleans.java | 213 + .../classloader/ConfigurableClassLoader.java | 112 + .../com/avlsi/util/cmdline/ADsimModule.java | 136 + .../com/avlsi/util/cmdline/CmdCommand.java | 299 + .../src/com/avlsi/util/cmdline/CmdLine.java | 665 ++ .../src/com/avlsi/util/cmdline/CmdModule.java | 30 + .../com/avlsi/util/cmdline/DSimModule.java | 4096 ++++++++ .../com/avlsi/util/cmdline/EchoModule.java | 28 + .../com/avlsi/util/cmdline/RssSampler.java | 82 + .../java/src/com/avlsi/util/cmdline/Signal.c | 195 + .../java/src/com/avlsi/util/cmdline/Signal.h | 20 + .../src/com/avlsi/util/cmdline/Signal.java | 68 + .../avlsi/util/cmdline/cmdline.package.inc | 7 + .../src/com/avlsi/util/cmdline/submakefile | 31 + .../util/cmdlineargs/CommandLineArg.java | 27 + .../CommandLineArgFormatException.java | 60 + .../util/cmdlineargs/CommandLineArgs.java | 83 + .../cmdlineargs/CommandLineArgsIterator.java | 37 + .../util/cmdlineargs/CommandLineArgsUtil.java | 452 + .../InvalidCommandLineArgException.java | 57 + .../MissingCommandLineArgException.java | 45 + .../defimpl/CachingCommandLineArgs.java | 169 + .../defimpl/CommandLineArgDefImpl.java | 38 + .../CommandLineArgWithNoValueDefImpl.java | 37 + .../defimpl/CommandLineArgsBaseImpl.java | 47 + .../defimpl/CommandLineArgsDefImpl.java | 216 + .../CommandLineArgsWithConfigFiles.java | 332 + .../defimpl/ConfigFileListAdapter.java | 79 + .../defimpl/PedanticCommandLineArgs.java | 136 + .../defimpl/TransformCommandLineArgs.java | 94 + .../defimpl/UnionCommandLineArgs.java | 121 + .../cmdlineargs/defimpl/defimpl.package.inc | 10 + .../src/com/avlsi/util/container/Alias.java | 330 + .../com/avlsi/util/container/AliasedMap.java | 439 + .../com/avlsi/util/container/AliasedSet.java | 198 + .../avlsi/util/container/Array2DIterator.java | 52 + .../util/container/BigIntegerReference.java | 38 + .../BigIntegerReferenceInterface.java | 32 + .../com/avlsi/util/container/BoundedSet.java | 172 + .../avlsi/util/container/CollectionUtils.java | 359 + .../src/com/avlsi/util/container/Counter.java | 60 + .../avlsi/util/container/DefaultedMap.java | 77 + .../EnumerationToIteratorAdapter.java | 44 + .../util/container/FilteringIterator.java | 88 + .../util/container/FlatteningIterator.java | 76 + .../com/avlsi/util/container/FullTable.java | 81 + .../com/avlsi/util/container/HashCounter.java | 44 + .../util/container/IntArrayComparator.java | 19 + .../com/avlsi/util/container/Interpolate.java | 42 + .../util/container/IterableIterator.java | 13 + ...erator2StringContainerIteratorAdapter.java | 33 + .../util/container/LinearInterpolatable.java | 25 + .../avlsi/util/container/Map2SetAdapter.java | 42 + .../avlsi/util/container/MappingIterator.java | 59 + .../com/avlsi/util/container/MultiMap.java | 219 + .../com/avlsi/util/container/MultiSet.java | 389 + .../avlsi/util/container/MutableDouble.java | 28 + .../com/avlsi/util/container/MutableInt.java | 33 + .../com/avlsi/util/container/Namespace.java | 187 + .../container/NaturalOrderComparator.java | 57 + .../com/avlsi/util/container/ObjectUtils.java | 73 + .../src/com/avlsi/util/container/Pair.java | 86 + .../com/avlsi/util/container/Partition.java | 135 + .../avlsi/util/container/PriorityQueue.java | 202 + .../src/com/avlsi/util/container/Queue.java | 112 + .../com/avlsi/util/container/RandomQueue.java | 125 + .../avlsi/util/container/ReverseArray.java | 29 + .../avlsi/util/container/SortingIterator.java | 50 + .../com/avlsi/util/container/SparseTable.java | 43 + .../container/StringContainerIterator.java | 36 + .../util/container/StringRepComparator.java | 17 + .../com/avlsi/util/container/TestAlias.java | 108 + .../avlsi/util/container/TestAliasedMap.java | 125 + .../avlsi/util/container/TestAliasedSet.java | 95 + .../util/container/TestCollectionUtils.java | 126 + .../avlsi/util/container/TestMultiSet.java | 115 + .../util/container/TestPriorityQueue.java | 46 + .../src/com/avlsi/util/container/TriMap.java | 412 + .../src/com/avlsi/util/container/TriTree.java | 161 + .../src/com/avlsi/util/container/Triplet.java | 93 + .../util/container/UnmodifiableIterator.java | 47 + .../com/avlsi/util/container/WeakHashSet.java | 199 + .../util/container/container.package.inc | 33 + .../java/src/com/avlsi/util/debug/Debug.java | 120 + .../java/src/com/avlsi/util/debug/GetTime.c | 43 + .../src/com/avlsi/util/debug/GetTime.java | 27 + .../com/avlsi/util/debug/SimpleProfiler.java | 311 + .../src/com/avlsi/util/debug/VersionInfo.java | 28 + .../src/com/avlsi/util/debug/cfiles-custom.mk | 12 + .../java/src/com/avlsi/util/debug/custom.mk | 7 + .../com/avlsi/util/debug/gettime.package.inc | 3 + .../com/avlsi/util/debug/progfiles-custom.mk | 22 + .../util/exception/AssertionFailure.java | 39 + .../avlsi/util/exception/ExceptionUtils.java | 35 + .../cad/java/src/com/avlsi/util/ext/Exec.java | 199 + .../java/src/com/avlsi/util/ext/TestExec.java | 21 + .../avlsi/util/functions/BinaryAction.java | 24 + .../avlsi/util/functions/BinaryFunction.java | 24 + .../avlsi/util/functions/BinaryPredicate.java | 34 + .../com/avlsi/util/functions/Functional.java | 156 + .../src/com/avlsi/util/functions/NonNull.java | 16 + .../avlsi/util/functions/NullaryAction.java | 18 + .../util/functions/NullaryPredicate.java | 18 + .../util/functions/NumericPredicate.java | 44 + .../com/avlsi/util/functions/UnaryAction.java | 24 + .../avlsi/util/functions/UnaryFunction.java | 24 + .../avlsi/util/functions/UnaryPredicate.java | 44 + .../java/src/com/avlsi/util/graph/Edge.java | 16 + .../java/src/com/avlsi/util/graph/Graph.java | 15 + .../src/com/avlsi/util/graph/GraphUtil.java | 93 + .../com/avlsi/util/graph/ShortestPaths.java | 58 + .../java/src/com/avlsi/util/graph/Vertex.java | 22 + .../com/avlsi/util/graph/WeightedVertex.java | 50 + .../avlsi/util/htmlWriter/HtmlDocWriter.java | 173 + .../com/avlsi/util/htmlWriter/HtmlWriter.java | 1014 ++ .../com/avlsi/util/logging/Configurator.java | 20 + .../avlsi/util/logging/ConsoleHandler.java | 53 + .../avlsi/util/logging/SimpleFormatter.java | 10 + .../com/avlsi/util/logging/StderrHandler.java | 7 + .../com/avlsi/util/logging/StdoutHandler.java | 7 + .../avlsi/util/logging/logging.package.inc | 7 + .../com/avlsi/util/logging/logging.properties | 54 + .../com/avlsi/util/math/BigIntegerUtil.java | 51 + .../avlsi/util/math/LinearInterpolation.java | 97 + .../java/src/com/avlsi/util/math/Math.java | 141 + .../util/math/QuadraticInterpolation.java | 149 + .../cad/java/src/com/avlsi/util/math/test.in | 16 + .../cad/java/src/com/avlsi/util/math/test2.in | 14 + .../mathexpression/ExpressionCollection.java | 37 + .../ExpressionCollectionIterator.java | 57 + .../util/mathexpression/MathExpression.java | 117 + .../mathexpression/MathExpressionFactory.java | 281 + .../NotAConstantValueException.java | 36 + .../avlsi/util/mathexpression/Visitor.java | 250 + .../WriteableExpressionCollection.java | 40 + ...WriteableExpressionCollectionIterator.java | 40 + .../mathexpression/impl/ArccosFunction.java | 80 + .../mathexpression/impl/ArcsinFunction.java | 80 + .../mathexpression/impl/ArctanFunction.java | 79 + .../mathexpression/impl/CeilFunction.java | 79 + .../util/mathexpression/impl/Constant.java | 67 + .../util/mathexpression/impl/CosFunction.java | 80 + .../mathexpression/impl/DivideOperator.java | 85 + .../mathexpression/impl/DottyVisitor.java | 226 + .../mathexpression/impl/DoubleCommon.java | 27 + .../impl/DoubleOperatorCommon.java | 99 + .../util/mathexpression/impl/ExpFunction.java | 79 + .../mathexpression/impl/FloorFunction.java | 79 + .../mathexpression/impl/LessThanOperator.java | 125 + .../util/mathexpression/impl/LogFunction.java | 79 + .../impl/MathExpressionFactoryImpl.java | 162 + .../mathexpression/impl/MinusOperator.java | 84 + .../util/mathexpression/impl/ModOperator.java | 86 + .../mathexpression/impl/NegationOperator.java | 79 + .../mathexpression/impl/PlusOperator.java | 219 + .../mathexpression/impl/RoundFunction.java | 79 + .../util/mathexpression/impl/SinFunction.java | 80 + .../mathexpression/impl/SkillVisitor.java | 188 + .../impl/SubExpressionReference.java | 154 + .../util/mathexpression/impl/SumOperator.java | 179 + .../util/mathexpression/impl/TanFunction.java | 80 + .../mathexpression/impl/TimesOperator.java | 220 + .../impl/VariableReference.java | 74 + .../WriteableExpressionCollectionImpl.java | 181 + .../impl/parser/MathExpression.g | 420 + .../util/mathexpression/impl/parser/custom.mk | 5 + .../impl/parser/parser.package.inc | 3 + .../mathexpression/variable/Variable.java | 27 + .../variable/VariableDictionary.java | 39 + .../variable/VariableDictionaryIterator.java | 34 + .../mathexpression/variable/VariableUtil.java | 70 + .../variable/WriteableVariable.java | 24 + .../variable/WriteableVariableDictionary.java | 41 + .../WriteableVariableDictionaryIterator.java | 41 + .../variable/impl/EnvironmentAdapter.java | 73 + .../impl/WriteableVariableDictionaryImpl.java | 160 + .../java/src/com/avlsi/util/readline/Bind.c | 129 + .../src/com/avlsi/util/readline/Completion.c | 205 + .../java/src/com/avlsi/util/readline/Keymap.c | 90 + .../java/src/com/avlsi/util/readline/Modify.c | 53 + .../src/com/avlsi/util/readline/Readline.c | 105 + .../src/com/avlsi/util/readline/Readline.java | 264 + .../avlsi/util/readline/Readline_CPFunction.h | 13 + .../util/readline/Readline_CPPFunction.h | 13 + .../readline/Readline_CompletionFunction.h | 13 + .../avlsi/util/readline/Readline_Function.h | 13 + .../avlsi/util/readline/Readline_Function2.h | 13 + .../util/readline/Readline_KeyboardFunction.h | 13 + .../com/avlsi/util/readline/Readline_Keymap.h | 24 + .../util/readline/Readline_Keymap_Entry.h | 13 + .../avlsi/util/readline/Readline_VFunction.h | 13 + .../src/com/avlsi/util/readline/Redisplay.c | 85 + .../java/src/com/avlsi/util/readline/Table.h | 531 + .../src/com/avlsi/util/readline/Test.java | 20 + .../java/src/com/avlsi/util/readline/Undo.c | 65 + .../src/com/avlsi/util/readline/Wrapper.h | 26 + .../com/avlsi/util/readline/cfiles-custom.mk | 8 + .../src/com/avlsi/util/readline/custom.mk | 15 + .../avlsi/util/readline/progfiles-custom.mk | 23 + .../avlsi/util/readline/readline.package.inc | 3 + .../src/com/avlsi/util/readline/submakefile | 31 + .../avlsi/util/recalc/AbstractBinaryOp.java | 70 + .../avlsi/util/recalc/AbstractUnaryOp.java | 62 + .../avlsi/util/recalc/AbstractVariable.java | 108 + .../avlsi/util/recalc/DependantVariable.java | 82 + .../java/src/com/avlsi/util/recalc/DivOp.java | 39 + .../util/recalc/ExpressionInterface.java | 45 + .../src/com/avlsi/util/recalc/Function.java | 193 + .../util/recalc/IndependantVariable.java | 57 + .../src/com/avlsi/util/recalc/Literal.java | 63 + .../src/com/avlsi/util/recalc/MinusOp.java | 39 + .../java/src/com/avlsi/util/recalc/ModOp.java | 39 + .../src/com/avlsi/util/recalc/MultOp.java | 39 + .../src/com/avlsi/util/recalc/NegateOp.java | 37 + .../src/com/avlsi/util/recalc/PlusOp.java | 39 + .../java/src/com/avlsi/util/recalc/PowOp.java | 39 + .../src/com/avlsi/util/recalc/TestRecalc.java | 132 + .../avlsi/util/text/BitFieldFormatter.java | 160 + .../com/avlsi/util/text/ByteArrayString.java | 182 + .../util/text/NaturalStringComparator.java | 176 + .../com/avlsi/util/text/NumberFormatter.java | 172 + .../src/com/avlsi/util/text/PrintfFormat.java | 3095 ++++++ .../src/com/avlsi/util/text/StringUtil.java | 473 + .../text/UnrepresentableCharException.java | 44 + .../src/com/avlsi/util/text/text.package.inc | 6 + .../java/src/com/avlsi/util/tree/Forest.java | 111 + .../java/src/com/avlsi/util/tree/Node.java | 169 + .../java/src/com/avlsi/util/tree/Tree.java | 84 + .../jtools/cad/java/src/cppfiles-custom.mk | 3 + .../jtools/cad/java/src/javafiles-custom.mk | 68 + .../jtools/cad/java/src/libfiles-custom.mk | 1 + .../jtools/cad/lve/build-system/lveMakefile | 20 + async-toolkit/jtools/cad/lve/doc/dag.html | 133 + .../jtools/cad/lve/doc/data_mining.html | 303 + .../jtools/cad/lve/doc/directives.html | 329 + async-toolkit/jtools/cad/lve/doc/dot | 18 + async-toolkit/jtools/cad/lve/doc/faq.html | 109 + async-toolkit/jtools/cad/lve/doc/hackers.html | 112 + async-toolkit/jtools/cad/lve/doc/intro.html | 292 + async-toolkit/jtools/cad/lve/doc/logo.png | Bin 0 -> 11404 bytes async-toolkit/jtools/cad/lve/doc/lve.css | 2 + async-toolkit/jtools/cad/lve/doc/lve.dot | 148 + async-toolkit/jtools/cad/lve/doc/lve.png | Bin 0 -> 63025 bytes .../jtools/cad/lve/doc/resources.html | 340 + async-toolkit/jtools/cad/lve/doc/table.css | 25 + .../jtools/cad/lve/javafiles-custom.mk | 23 + .../jtools/cad/lve/lib/perl/LveAspice.pm | 2176 ++++ .../jtools/cad/lve/lib/perl/LveDB.pm | 275 + .../jtools/cad/lve/lib/perl/LveDelay.pm | 242 + .../jtools/cad/lve/lib/perl/LveStatus.pm | 90 + .../jtools/cad/lve/lib/perl/LveSummarize.pm | 1936 ++++ .../jtools/cad/lve/lib/perl/LveUtil.pm | 566 ++ .../jtools/cad/lve/lib/perl/Pathalyze.pm | 459 + .../cad/lve/lib/perl/Pathalyze/Measurement.pm | 1168 +++ .../cad/lve/lib/perl/Pathalyze/Parameter.pm | 584 ++ .../cad/lve/lib/perl/Pathalyze/Parser.pm | 608 ++ .../jtools/cad/lve/lib/perl/rename.pm | 76 + .../jtools/cad/lve/lib/perl/rvp/LICENCE.TXT | 67 + .../jtools/cad/lve/lib/perl/rvp/hier_print.pl | 103 + .../jtools/cad/lve/lib/perl/rvp/rvp.pm | 4254 ++++++++ .../jtools/cad/lve/lib/perl/rvp/rvp.pod.html | 747 ++ .../jtools/cad/lve/lib/perl/rvp/rvp_test.pl | 102 + .../cad/lve/lib/perl/rvp/simple_hier_print.pl | 61 + .../cad/lve/lib/perl/rvp/strip_comments.pl | 13 + .../jtools/cad/lve/lib/perl/rvp/synth_make.pl | 188 + async-toolkit/jtools/cad/lve/lve.package | 299 + .../cad/lve/script/perl/analyze_coupling | 850 ++ .../script/perl/canonicalizing_spice2aspice | 106 + .../jtools/cad/lve/script/perl/captally.pl | 882 ++ .../jtools/cad/lve/script/perl/cell_lef.pl | 267 + .../cad/lve/script/perl/char_cadence_lib.pl | 1756 ++++ .../cad/lve/script/perl/check_dummy_pin.pl | 215 + .../jtools/cad/lve/script/perl/checkdb.pl | 187 + .../jtools/cad/lve/script/perl/chkdupdef.pl | 47 + .../jtools/cad/lve/script/perl/chkdupname.pl | 60 + .../jtools/cad/lve/script/perl/db2table.pl | 82 + .../jtools/cad/lve/script/perl/def2vddgnd.pl | 100 + .../cad/lve/script/perl/deletetracefile | 91 + .../jtools/cad/lve/script/perl/df2d.pl | 176 + .../jtools/cad/lve/script/perl/donvn2 | 224 + .../jtools/cad/lve/script/perl/find_bumps | 53 + .../jtools/cad/lve/script/perl/find_envs | 49 + .../jtools/cad/lve/script/perl/find_layout | 24 + .../jtools/cad/lve/script/perl/fix_alint_raw | 702 ++ .../jtools/cad/lve/script/perl/fix_pinswap.pl | 231 + .../jtools/cad/lve/script/perl/fixhdrc.pl | 98 + .../jtools/cad/lve/script/perl/fixnames.pl | 78 + .../jtools/cad/lve/script/perl/flatcdl.pl | 592 ++ .../jtools/cad/lve/script/perl/frc.pl | 219 + .../jtools/cad/lve/script/perl/gds2def.pl | 677 ++ .../jtools/cad/lve/script/perl/genlib.pl | 2172 ++++ .../jtools/cad/lve/script/perl/genliberty.pl | 2290 +++++ .../jtools/cad/lve/script/perl/getslack.pl | 98 + .../jtools/cad/lve/script/perl/hdrc.pl | 199 + .../jtools/cad/lve/script/perl/histogram | 49 + .../jtools/cad/lve/script/perl/importSync.pl | 321 + .../jtools/cad/lve/script/perl/importV.pl | 96 + .../jtools/cad/lve/script/perl/isgds | 45 + .../jtools/cad/lve/script/perl/lefWrite.pl | 141 + .../jtools/cad/lve/script/perl/local_aspice | 311 + async-toolkit/jtools/cad/lve/script/perl/lve | 3455 +++++++ .../jtools/cad/lve/script/perl/lve_apl | 317 + .../jtools/cad/lve/script/perl/lve_em | 539 + .../jtools/cad/lve/script/perl/lve_jobs | 26 + .../jtools/cad/lve/script/perl/lve_query | 327 + .../jtools/cad/lve/script/perl/lve_raw | 3358 +++++++ .../cad/lve/script/perl/lve_resummarize | 453 + .../jtools/cad/lve/script/perl/lve_sram | 808 ++ .../jtools/cad/lve/script/perl/lve_sram_130nm | 746 ++ .../jtools/cad/lve/script/perl/lve_summarize | 43 + .../jtools/cad/lve/script/perl/lve_threshresp | 188 + .../jtools/cad/lve/script/perl/lve_tracking | 509 + .../cad/lve/script/perl/lveextractgray.pl | 231 + .../jtools/cad/lve/script/perl/lveliblef2p4 | 275 + .../jtools/cad/lve/script/perl/make_alint_in | 380 + .../jtools/cad/lve/script/perl/make_aspice_in | 106 + .../jtools/cad/lve/script/perl/make_asta_in | 53 + .../jtools/cad/lve/script/perl/make_slint_in | 47 + .../cad/lve/script/perl/merge_alint_out | 70 + .../jtools/cad/lve/script/perl/mkbind.pl | 56 + .../jtools/cad/lve/script/perl/mkpinassign.pl | 605 ++ .../jtools/cad/lve/script/perl/mksigs.pl | 85 + .../jtools/cad/lve/script/perl/mmonitor | 55 + .../jtools/cad/lve/script/perl/pathalyze.pl | 285 + .../cad/lve/script/perl/pathalyze_HitChan | 300 + .../cad/lve/script/perl/plt_scenarios.pl | 622 ++ .../cad/lve/script/perl/proteus_characterize | 1307 +++ .../jtools/cad/lve/script/perl/qsub/qb | 393 + .../jtools/cad/lve/script/perl/qsub/qbwrapper | 74 + .../jtools/cad/lve/script/perl/raw2db.pl | 144 + .../cad/lve/script/perl/rc_spice2aspice | 883 ++ .../cad/lve/script/perl/recursive_graybox | 122 + .../cad/lve/script/perl/rehierverilog.pl | 82 + .../jtools/cad/lve/script/perl/remote/lve_pmc | 345 + .../lve/script/perl/remote/pmc_jobcancel.sh | 178 + .../lve/script/perl/remote/pmc_jobsubmit.pl | 568 ++ .../cad/lve/script/perl/rte_summarize.pl | 198 + .../jtools/cad/lve/script/perl/run_cmm.pl | 397 + .../jtools/cad/lve/script/perl/run_totem.pl | 327 + .../jtools/cad/lve/script/perl/runincdswd.pl | 38 + .../jtools/cad/lve/script/perl/shmoo | 118 + .../jtools/cad/lve/script/perl/signoff_check | 60 + .../jtools/cad/lve/script/perl/snarf | 115 + .../jtools/cad/lve/script/perl/spefrename.pl | 102 + .../cad/lve/script/perl/spice/extractCDC.pl | 1329 +++ .../lve/script/perl/spice/extract_starRC.pl | 1790 ++++ .../jtools/cad/lve/script/perl/spice/hlvs.pl | 482 + .../cad/lve/script/perl/spice/hlvsrename.pl | 33 + .../jtools/cad/lve/script/perl/spice/hsim.pl | 484 + .../cad/lve/script/perl/spice/parse_hlvs.pl | 116 + .../cad/lve/script/perl/spice/spice2spice.pl | 341 + .../cad/lve/script/perl/spice/spice_reduce.pl | 386 + .../jtools/cad/lve/script/perl/splitcast.pl | 90 + .../jtools/cad/lve/script/perl/splitfill.pl | 162 + .../jtools/cad/lve/script/perl/tapeout | 104 + .../cad/lve/script/perl/tcam/tcam_aplot | 210 + .../jtools/cad/lve/script/perl/tcam/tcam_cap | 7 + .../jtools/cad/lve/script/perl/tcam/tcam_lib | 599 ++ .../jtools/cad/lve/script/perl/tcam/tcam_todo | 167 + .../jtools/cad/lve/script/perl/tracescan.pl | 578 ++ .../cad/lve/script/perl/update_delay_and_cap | 130 + .../jtools/cad/lve/script/perl/vstorm | 932 ++ .../jtools/cad/lve/script/perl/vstorm_async | 1151 +++ .../jtools/cad/lve/script/perl/wirelen.pl | 379 + .../jtools/cad/lve/script/perl/wrapspec.pl | 359 + .../cad/lve/script/perl/wwc_tcam/rename_aplot | 31 + .../cad/lve/script/perl/wwc_tcam/run_all | 174 + .../cad/lve/script/perl/wwc_tcam/run_tcam | 523 + .../cad/lve/script/perl/wwc_tcam/tcam_lib | 1245 +++ .../lve/script/perl/wwc_tcam/write_tcam_init | 52 + .../jtools/cad/lve/script/php/index.php | 527 + .../jtools/cad/lve/scripts/php/alint.php | 203 + .../jtools/cad/lve/scripts/php/antenna.php | 1 + .../jtools/cad/lve/scripts/php/aspice.php | 160 + .../jtools/cad/lve/scripts/php/asta.php | 135 + .../jtools/cad/lve/scripts/php/bumps.php | 65 + .../jtools/cad/lve/scripts/php/cell.php | 145 + .../jtools/cad/lve/scripts/php/common.php | 1413 +++ .../jtools/cad/lve/scripts/php/commonSC.php | 1319 +++ .../jtools/cad/lve/scripts/php/commonnm28.php | 1335 +++ .../jtools/cad/lve/scripts/php/delays.php | 65 + .../jtools/cad/lve/scripts/php/doc/dag.html | 133 + .../cad/lve/scripts/php/doc/data_mining.html | 301 + .../cad/lve/scripts/php/doc/directives.html | 327 + .../jtools/cad/lve/scripts/php/doc/faq.html | 107 + .../cad/lve/scripts/php/doc/hackers.html | 110 + .../jtools/cad/lve/scripts/php/doc/index.html | 290 + .../jtools/cad/lve/scripts/php/doc/logo.png | Bin 0 -> 11404 bytes .../jtools/cad/lve/scripts/php/doc/lve.css | 2 + .../jtools/cad/lve/scripts/php/doc/lve.png | Bin 0 -> 63025 bytes .../cad/lve/scripts/php/doc/resources.html | 338 + .../jtools/cad/lve/scripts/php/doc/table.css | 25 + .../scripts/php/doc/updatenetlist/calls.dot | 138 + .../scripts/php/doc/updatenetlist/index.html | 450 + .../jtools/cad/lve/scripts/php/em.php | 67 + .../jtools/cad/lve/scripts/php/extract.php | 1 + .../jtools/cad/lve/scripts/php/frc.php | 1 + .../jtools/cad/lve/scripts/php/getlvedirs.pl | 71 + .../cad/lve/scripts/php/getlvedirsSC.pl | 61 + .../jtools/cad/lve/scripts/php/hdrc.php | 1 + .../jtools/cad/lve/scripts/php/hlvs.php | 1 + .../jtools/cad/lve/scripts/php/hsim.php | 1 + .../jtools/cad/lve/scripts/php/hspice.php | 1 + .../jtools/cad/lve/scripts/php/index.php | 646 ++ .../jtools/cad/lve/scripts/php/jlvs.php | 44 + .../jtools/cad/lve/scripts/php/leakage.php | 63 + .../jtools/cad/lve/scripts/php/lib.php | 99 + .../jtools/cad/lve/scripts/php/libdelays.php | 64 + .../jtools/cad/lve/scripts/php/lve.css | 2 + .../jtools/cad/lve/scripts/php/lvedirs.txt | 269 + .../jtools/cad/lve/scripts/php/newbumps.php | 70 + .../jtools/cad/lve/scripts/php/rte.php | 133 + .../jtools/cad/lve/scripts/php/rteSummary.php | 276 + .../jtools/cad/lve/scripts/php/site.php | 10 + .../jtools/cad/lve/scripts/php/siteSC.php | 10 + .../jtools/cad/lve/scripts/php/sitenm28.php | 12 + .../jtools/cad/lve/scripts/php/slint.php | 98 + .../jtools/cad/lve/scripts/php/statistics.php | 41 + .../jtools/cad/lve/scripts/php/table.css | 25 + .../jtools/cad/lve/scripts/php/totem.php | 126 + .../jtools/cad/lve/scripts/php/unzip.php | 7 + .../jtools/cad/lve/scripts/php/xa.php | 44 + .../cad/perl/perlmod/Cast/JavaServer.pm | 352 + .../cad/perl/perlmod/Cast/NodeAliasing.pm | 140 + .../perl/perlmod/Cast/QA/TestNodeAliasing.pl | 103 + .../cad/perl/perlmod/Cast/SourceControl.pm | 262 + .../jtools/cad/perl/perlmod/Util/Numeric.pm | 40 + async-toolkit/jtools/cad/scripts/apply_fixes | 160 + .../jtools/cad/scripts/cad_bin_install | 20 + async-toolkit/jtools/cad/scripts/captally | 220 + .../jtools/cad/scripts/cast_signoff_report | 627 ++ async-toolkit/jtools/cad/scripts/cdl2dot | 478 + .../cad/scripts/charge_sharing_postprocess | 158 + .../jtools/cad/scripts/charge_sharing_report | 268 + .../jtools/cad/scripts/check_hierarchy.pl | 99 + .../jtools/cad/scripts/compile_lib.sh | 59 + async-toolkit/jtools/cad/scripts/custom.mk | 8 + async-toolkit/jtools/cad/scripts/df2instances | 49 + .../cad/scripts/doc_utils/serialtree2ps.pl | 280 + .../jtools/cad/scripts/fix_charge_sharing | 873 ++ .../jtools/cad/scripts/graph_netlist | 226 + .../jtools/cad/scripts/graph_netlist.inc | 5 + .../jtools/cad/scripts/group_members | 2 + async-toolkit/jtools/cad/scripts/html_diff | 58 + .../jtools/cad/scripts/install_scripts | 22 + .../jtools/cad/scripts/integrate_views | 240 + async-toolkit/jtools/cad/scripts/layout_spice | 764 ++ .../scripts/layout_spice_stuff/call_spice.scr | 135 + .../layout_spice_stuff/change_char2spice.scr | 99 + .../chrg_shr_post_processing.scr | 209 + .../scripts/layout_spice_stuff/hsim_tds.scr | 22 + .../layout_spice_stuff/post_process_tds.scr | 26 + async-toolkit/jtools/cad/scripts/ldg/Graph.pm | 43 + .../jtools/cad/scripts/ldg/LDGUtils.pm | 998 ++ .../jtools/cad/scripts/ldg/Ldgd/Cells.pm | 1134 +++ .../jtools/cad/scripts/ldg/Ldgd/Dbaccess.pm | 1281 +++ .../jtools/cad/scripts/ldg/Ldgd/Errorcodes.pm | 24 + .../jtools/cad/scripts/ldg/Ldgd/Filter.pm | 164 + .../jtools/cad/scripts/ldg/Ldgd/Flows.pm | 478 + .../jtools/cad/scripts/ldg/Ldgd/Libraries.pm | 54 + .../jtools/cad/scripts/ldg/Ldgd/Locks.pm | 158 + .../jtools/cad/scripts/ldg/Ldgd/Projects.pm | 239 + .../jtools/cad/scripts/ldg/Ldgd/Session.pm | 23 + .../jtools/cad/scripts/ldg/Ldgd/Socket.pm | 236 + .../jtools/cad/scripts/ldg/Ldgd/Sort.pm | 125 + .../jtools/cad/scripts/ldg/Ldgd/Tests.pm | 220 + .../jtools/cad/scripts/ldg/Ldgd/Users.pm | 387 + async-toolkit/jtools/cad/scripts/ldg/Msg.pm | 318 + .../jtools/cad/scripts/ldg/basic_client.pl | 33 + async-toolkit/jtools/cad/scripts/ldg/clean_db | 100 + .../jtools/cad/scripts/ldg/find_cell.pl | 43 + .../jtools/cad/scripts/ldg/get_parents.pl | 60 + .../cad/scripts/ldg/ldg_layout_client.pl | 409 + .../jtools/cad/scripts/ldg/ldg_p4_review.pl | 54 + .../cad/scripts/ldg/ldg_verify_client.pl | 139 + async-toolkit/jtools/cad/scripts/ldg/ldgd.pl | 142 + async-toolkit/jtools/cad/scripts/ldg/sql.pl | 25 + .../jtools/cad/scripts/lib/CadenceLib.pm | 149 + .../jtools/cad/scripts/lib/CastLib.pm | 1730 ++++ .../jtools/cad/scripts/lib/CastParser.pm | 825 ++ .../jtools/cad/scripts/lib/CastParserLib.pm | 390 + .../jtools/cad/scripts/license/checklic.pl | 795 ++ async-toolkit/jtools/cad/scripts/lmusage | 163 + async-toolkit/jtools/cad/scripts/measure | 8 + async-toolkit/jtools/cad/scripts/minmaxv | 29 + async-toolkit/jtools/cad/scripts/mk_instance | 37 + async-toolkit/jtools/cad/scripts/p2n | 200 + async-toolkit/jtools/cad/scripts/p4_html_diff | 75 + async-toolkit/jtools/cad/scripts/postlayout | 558 ++ .../jtools/cad/scripts/power_grid_sag | 115 + .../jtools/cad/scripts/progfiles-custom.mk | 17 + async-toolkit/jtools/cad/scripts/r4 | 52 + .../jtools/cad/scripts/rc_spice2aspice | 739 ++ async-toolkit/jtools/cad/scripts/rescuedb.c | 20 + async-toolkit/jtools/cad/scripts/rtlwait | 258 + async-toolkit/jtools/cad/scripts/spec_stats | 33 + async-toolkit/jtools/cad/scripts/spice | 305 + async-toolkit/jtools/cad/scripts/spice2spice | 421 + async-toolkit/jtools/cad/scripts/spice_batch | 103 + async-toolkit/jtools/cad/scripts/spice_new | 352 + .../jtools/cad/scripts/support/bugmonitor | 198 + .../jtools/cad/scripts/support/bugproduct | 47 + .../jtools/cad/scripts/support/bugzillauser | 51 + .../jtools/cad/scripts/support/caljul | 45 + async-toolkit/jtools/cad/scripts/support/cwd | 5 + .../jtools/cad/scripts/support/date2time | 106 + .../jtools/cad/scripts/support/date2time.pm | 70 + .../jtools/cad/scripts/support/drawlef | 310 + .../jtools/cad/scripts/support/gds2strings | 51 + .../jtools/cad/scripts/support/genconfig.pl | 64 + .../jtools/cad/scripts/support/getquo | 42 + .../jtools/cad/scripts/support/getquoa | 42 + .../jtools/cad/scripts/support/getquob | 42 + .../jtools/cad/scripts/support/getquoh | 42 + .../jtools/cad/scripts/support/getquol | 42 + .../jtools/cad/scripts/support/getquos | 42 + .../jtools/cad/scripts/support/getquot | 42 + .../jtools/cad/scripts/support/gettmp.sh | 7 + .../jtools/cad/scripts/support/graph | 336 + .../jtools/cad/scripts/support/hencrypt | 58 + .../jtools/cad/scripts/support/julian.pl | 44 + .../jtools/cad/scripts/support/lmgraph | 401 + .../jtools/cad/scripts/support/longlines | 64 + .../jtools/cad/scripts/support/maxlen | 40 + async-toolkit/jtools/cad/scripts/support/myqs | 765 ++ .../jtools/cad/scripts/support/p4monitor | 214 + .../jtools/cad/scripts/support/p5check | 163 + async-toolkit/jtools/cad/scripts/support/qacc | 289 + .../jtools/cad/scripts/support/qresource | 95 + .../jtools/cad/scripts/support/qtrace | 229 + .../jtools/cad/scripts/support/quotacmp | 441 + .../jtools/cad/scripts/support/quotagraph | 396 + .../jtools/cad/scripts/support/s2aplt | 191 + .../jtools/cad/scripts/support/s2iplt | 186 + .../cad/scripts/support/support.package | 44 + .../jtools/cad/scripts/support/tgraph | 406 + .../jtools/cad/scripts/support/time2date | 28 + .../jtools/cad/scripts/support/unwrap | 32 + .../jtools/cad/scripts/support/userinfo | 37 + async-toolkit/jtools/cad/scripts/support/wide | 87 + .../cad/scripts/synthesis/add_rough_power.pl | 240 + .../cad/scripts/synthesis/custom.config | 7 + .../jtools/cad/scripts/synthesis/sizing.pl | 168 + async-toolkit/jtools/cad/scripts/tidier | 30 + .../cad/scripts/time_domain_postprocess | 29 + async-toolkit/jtools/cad/scripts/trace_deriv | 15 + .../jtools/cad/ubersize/javafiles-custom.mk | 23 + .../jtools/cad/ubersize/lib/perl/Perforce.pm | 79 + .../lib/perl/Supersize/DensityFactor.pm | 1136 +++ .../cad/ubersize/lib/perl/Supersize/FileIO.pm | 133 + .../lib/perl/Supersize/FulcrumIntegration.pm | 744 ++ .../ubersize/lib/perl/Supersize/JavaUtil.pm | 582 ++ .../lib/perl/Supersize/LayoutIntegration.pm | 1494 +++ .../lib/perl/Supersize/LayoutModeling.pm | 193 + .../lib/perl/Supersize/MergeLibrary.pm | 799 ++ .../ubersize/lib/perl/Supersize/Merging.pm | 1484 +++ .../cad/ubersize/lib/perl/Supersize/Misc.pm | 190 + .../lib/perl/Supersize/ModifySubtypes.pm | 1437 +++ .../ubersize/lib/perl/Supersize/Netlist.pm | 285 + .../lib/perl/Supersize/PerforceIntegration.pm | 725 ++ .../ubersize/lib/perl/Supersize/PostLayout.pm | 461 + .../cad/ubersize/lib/perl/Supersize/Sizing.pm | 378 + .../lib/perl/Supersize/SizingDebug.pm | 943 ++ .../ubersize/lib/perl/Supersize/SizingDrop.pm | 373 + .../lib/perl/Supersize/SubtypeSpace.pm | 1778 ++++ .../ubersize/lib/perl/Supersize/TypeOps.pm | 580 ++ .../ubersize/lib/perl/Supersize/TypeUtil.pm | 656 ++ .../ubersize/lib/perl/Supersize/Unmerging.pm | 1732 ++++ .../cad/ubersize/lib/perl/Supersize/Util.pm | 932 ++ .../cad/ubersize/script/perl/cast2sync.pl | 2213 +++++ .../cad/ubersize/script/perl/cells2html | 95 + .../cad/ubersize/script/perl/check_cutoff | 104 + .../cad/ubersize/script/perl/compare_cells | 60 + .../cad/ubersize/script/perl/compare_sizes | 60 + .../cad/ubersize/script/perl/compile_cdc.pl | 881 ++ .../cad/ubersize/script/perl/floorplan_init | 85 + .../ubersize/script/perl/generate_sdcinfo.pl | 153 + .../cad/ubersize/script/perl/mkdefaultlib.pl | 124 + .../jtools/cad/ubersize/script/perl/supersize | 1853 ++++ .../jtools/cad/ubersize/script/perl/ubersize | 1535 +++ .../jtools/cad/ubersize/ubersize.package | 59 + .../build-and-test.package | 9 + .../buildandtestfromp4.sh | 245 + .../build-and-test-scripts/buildfromsource.sh | 169 + .../build-and-test-scripts/gdsII/gdsII2xml.pl | 820 ++ .../build-and-test-scripts/runmake.sh | 158 + .../runtestsfromsource.sh | 254 + .../util/p4/clientroot.sh | 18 + .../util/p4/map_depot_to_disk.sh | 33 + .../infrastructure/build-system/Makefile | 138 + .../infrastructure/build-system/System.mk | 78 + .../build-system/bin/antlr-2.7.2 | 6 + .../build-system/build-system.package | 84 + .../build-system/calc_sub_dirs_info.mk | 42 + .../calc_sub_target_mk_include_info.mk | 29 + .../infrastructure/build-system/commands.mk | 3 + .../build-system/cononicalizepath.zsh | 11 + .../infrastructure/build-system/custom.mk | 2 + .../build-system/defaults.clean.mk | 43 + .../build-system/defaults.common.mk | 43 + .../build-system/defaults.dir.mk | 30 + .../build-system/defaults.mk.gen | 17 + .../build-system/defaults.mk.tmpl | 6 + .../build-system/defaults.subincludes.mk | 9 + .../infrastructure/build-system/dir_exit.mk | 6 + .../build-system/doc/index.html | 1050 ++ .../filetypes/antlrfiles/mkantlrrules.mk | 30 + .../filetypes/castfiles/annotatecond | 48 + .../build-system/filetypes/castfiles/dir.mk | 252 + .../filetypes/castfiles/dirout.mk | 16 + .../build-system/filetypes/castfiles/env.mk | 1829 ++++ .../filetypes/castfiles/getcellname | 7 + .../build-system/filetypes/castfiles/once.mk | 2501 +++++ .../filetypes/castfiles/slurp_cell_view.mk | 80 + .../build-system/filetypes/cdbfiles/cdbdep.sh | 97 + .../filetypes/cdbfiles/cdbdiff.pl | 72 + .../filetypes/cdbfiles/cdbdiff.sh | 8 + .../build-system/filetypes/cdbfiles/dir.mk | 186 + .../build-system/filetypes/cdbfiles/dirout.mk | 16 + .../build-system/filetypes/cdbfiles/drcdep.sh | 21 + .../filetypes/cdbfiles/mysql_status | 58 + .../build-system/filetypes/cdbfiles/once.mk | 29 + .../build-system/filetypes/cfiles/dir.mk | 108 + .../build-system/filetypes/cfiles/dirout.mk | 26 + .../build-system/filetypes/cfiles/once.mk | 22 + .../build-system/filetypes/cppfiles/dir.mk | 123 + .../build-system/filetypes/cppfiles/dirout.mk | 27 + .../build-system/filetypes/cppfiles/once.mk | 8 + .../build-system/filetypes/dotfiles/dir.mk | 13 + .../build-system/filetypes/dotfiles/dirout.mk | 0 .../build-system/filetypes/dotfiles/once.mk | 9 + .../javafiles/BuildIdentifier.template | 7 + .../build-system/filetypes/javafiles/dir.mk | 446 + .../filetypes/javafiles/dirout.mk | 102 + .../filetypes/javafiles/jarcombine.sh | 66 + .../filetypes/javafiles/java2package | 13 + .../filetypes/javafiles/javadep.sh | 66 + .../filetypes/javafiles/mkTopLevelJava.pl | 260 + .../build-system/filetypes/javafiles/once.mk | 40 + .../build-system/filetypes/libfiles/dir.mk | 79 + .../build-system/filetypes/libfiles/dirout.mk | 17 + .../build-system/filetypes/libfiles/once.mk | 1 + .../filetypes/packagingfiles/dir.mk | 51 + .../filetypes/packagingfiles/mkpackage.pl | 714 ++ .../filetypes/packagingfiles/once.mk | 40 + .../build-system/filetypes/progfiles/dir.mk | 70 + .../filetypes/progfiles/dirout.mk | 22 + .../filetypes/progfiles/mklinkrule.mk | 8 + .../filetypes/progfiles/mksolinkrule.mk | 12 + .../build-system/filetypes/progfiles/once.mk | 3 + .../build-system/filetypes/pyfiles/dir.mk | 8 + .../build-system/filetypes/pyfiles/dirout.mk | 0 .../build-system/filetypes/pyfiles/once.mk | 0 .../build-system/filetypes/texfiles/dir.mk | 36 + .../build-system/filetypes/texfiles/dirout.mk | 0 .../build-system/filetypes/texfiles/once.mk | 27 + .../filetypes/texfiles/texdep.zsh | 19 + .../infrastructure/build-system/functions.mk | 63 + .../build-system/generatedir.zsh | 9 + .../include-functions/linkprogram.mk | 2 + .../include-functions/popscopedvar.mk | 8 + .../include-functions/pushscopedvar.mk | 5 + .../build-system/infrastructure.mk | 52 + .../infrastructure/build-system/runindir.bash | 8 + .../infrastructure/build-system/safemkdir.zsh | 7 + .../infrastructure/build-system/subdir.mk.gen | 53 + .../build-system/systems/romulite.mk | 15 + .../build-system/systemtypes/Linux-i686.mk | 7 + .../build-system/systemtypes/Linux-x86_64.mk | 7 + .../build-system/systemtypes/SunOS-sun4u.mk | 33 + .../build-system/systemtypes/default.mk | 42 + .../autodep/autodep-0.2.1-fulcrum.tar.gz | Bin 0 -> 15043 bytes .../build-system/tools/autodep/rules.mk | 60 + .../build-system/tools/autodep/vars.mk | 7 + .../infrastructure/build-system/var_reset.mk | 31 + .../build-system/vortexfiles.mk | 49 + .../jtools/infrastructure/java/Makefile | 177 + .../java/scripts/compute_class_path | 34 + .../java/scripts/make_obfuscated_jar.pl | 139 + .../java/scripts/make_subdir_makefile | 41 + .../infrastructure/java/scripts/unkeyword.pl | 64 + .../util/cmdline/ArgProcessingInterface.java | 15 + .../util/cmdline/CommandLineIterator.java | 90 + .../util/cmdline/PropCommandLineIterator.java | 54 + .../java/util/cmdline/PropertyArg.java | 27 + .../util/misc/JepMathExpressionParser.java | 178 + .../java/util/misc/Utility.java | 104 + .../util/properties/BadPropertyException.java | 8 + .../properties/ExpansionErrorException.java | 8 + .../properties/MalformedSubstException.java | 8 + .../properties/PropCommandLineParser.java | 124 + .../util/properties/PropConfigFileParser.java | 221 + .../properties/PropConfigParserException.java | 8 + .../java/util/properties/PropReader.java | 1099 ++ .../util/properties/PropReaderInterface.java | 23 + .../java/util/properties/SubstExpr.java | 121 + .../util/properties/TypeErrorException.java | 8 + .../java/util/properties/testcases/common.xml | 10 + .../util/properties/testcases/options.xml | 1127 +++ .../java/util/properties/testcases/t0001.args | 1 + .../util/properties/testcases/t0001.expected | 1 + .../java/util/properties/testcases/t0001.test | 3 + .../util/properties/testcases/t0002.expected | 5 + .../java/util/properties/testcases/t0002.test | 8 + .../util/properties/testcases/t0003.expected | 3 + .../java/util/properties/testcases/t0003.test | 22 + .../java/util/properties/testcases/t0003.xml | 6 + .../java/util/properties/testcases/t0004.args | 1 + .../util/properties/testcases/t0004.expected | 4 + .../java/util/properties/testcases/t0004.test | 37 + .../java/util/properties/testcases/t0004.xml | 7 + .../java/util/properties/testcases/t0005/args | 1 + .../util/properties/testcases/t0005/expected | 11 + .../java/util/properties/testcases/t0005/test | 6 + .../java/util/properties/testcases/t0006/args | 4 + .../util/properties/testcases/t0006/expected | 12 + .../java/util/properties/testcases/t0006/test | 11 + .../java/util/properties/testcases/t0007/args | 4 + .../util/properties/testcases/t0007/expected | 13 + .../java/util/properties/testcases/t0007/test | 12 + .../java/util/properties/testcases/t0008/args | 5 + .../util/properties/testcases/t0008/expected | 20 + .../java/util/properties/testcases/t0008/test | 17 + .../java/util/properties/testcases/t0009/args | 4 + .../util/properties/testcases/t0009/expected | 23 + .../java/util/properties/testcases/t0009/test | 12 + .../java/util/properties/testcases/t0010/args | 4 + .../util/properties/testcases/t0010/expected | 17 + .../util/properties/testcases/t0010/t.xml | 9 + .../java/util/properties/testcases/t0010/test | 9 + .../java/util/properties/testcases/t0011/args | 4 + .../util/properties/testcases/t0011/expected | 17 + .../util/properties/testcases/t0011/t.xml | 9 + .../java/util/properties/testcases/t0011/test | 10 + .../java/util/properties/testcases/t0012/args | 1 + .../util/properties/testcases/t0012/expected | 5 + .../util/properties/testcases/t0012/t.xml | 7 + .../java/util/properties/testcases/t0012/test | 9 + .../java/util/properties/testcases/t0013/args | 1 + .../util/properties/testcases/t0013/expected | 5 + .../util/properties/testcases/t0013/t.xml | 7 + .../java/util/properties/testcases/t0013/test | 9 + .../util/properties/testcases/t0014/expected | 5 + .../java/util/properties/testcases/t0014/test | 9 + .../java/util/properties/testcases/t0015/args | 2 + .../util/properties/testcases/t0015/expected | 4 + .../java/util/properties/testcases/t0015/test | 7 + .../java/util/properties/testcases/t0016/args | 1 + .../util/properties/testcases/t0016/expected | 5 + .../util/properties/testcases/t0016/t.xml | 7 + .../java/util/properties/testcases/t0016/test | 10 + .../java/util/properties/testcases/t0018/args | 1 + .../util/properties/testcases/t0018/expected | 4 + .../java/util/properties/testcases/t0018/test | 12 + .../java/util/properties/testcases/t0019/args | 0 .../util/properties/testcases/t0019/expected | 4 + .../java/util/properties/testcases/t0019/test | 21 + .../java/util/properties/testcases/t0020/args | 0 .../util/properties/testcases/t0020/expected | 3 + .../java/util/properties/testcases/t0020/test | 9 + .../java/util/properties/testcases/t0021/args | 1 + .../util/properties/testcases/t0021/expected | 8 + .../util/properties/testcases/t0021/t.xml | 8 + .../java/util/properties/testcases/t0021/test | 12 + .../java/util/properties/testcases/t0022/args | 0 .../util/properties/testcases/t0022/expected | 8 + .../util/properties/testcases/t0022/t.xml | 21 + .../java/util/properties/testcases/t0022/test | 7 + .../java/util/properties/testcases/t0023/args | 1 + .../util/properties/testcases/t0023/expected | 6 + .../java/util/properties/testcases/t0023/test | 26 + .../java/util/properties/testcases/t0024/args | 1 + .../util/properties/testcases/t0024/expected | 9 + .../java/util/properties/testcases/t0024/test | 39 + .../java/util/properties/testcases/t0025/args | 1 + .../util/properties/testcases/t0025/expected | 6 + .../java/util/properties/testcases/t0025/test | 37 + .../java/util/properties/testcases/t0026/args | 1 + .../util/properties/testcases/t0026/expected | 11 + .../java/util/properties/testcases/t0026/test | 7 + .../java/util/properties/testcases/t0027/args | 2 + .../util/properties/testcases/t0027/expected | 11 + .../util/properties/testcases/t0027/t.xml | 4 + .../java/util/properties/testcases/t0027/test | 11 + .../java/util/properties/testcases/t0028/args | 0 .../util/properties/testcases/t0028/expected | 6 + .../java/util/properties/testcases/t0028/test | 9 + .../java/util/properties/testcases/t0029/args | 0 .../util/properties/testcases/t0029/expected | 4 + .../java/util/properties/testcases/t0029/test | 19 + .../java/util/properties/testcases/t0030/args | 0 .../util/properties/testcases/t0030/expected | 4 + .../java/util/properties/testcases/t0030/test | 23 + .../java/util/properties/testcases/t0031/args | 0 .../util/properties/testcases/t0031/expected | 4 + .../java/util/properties/testcases/t0031/test | 18 + .../java/util/properties/testcases/t0032/args | 1 + .../util/properties/testcases/t0032/expected | 8 + .../java/util/properties/testcases/t0032/test | 37 + .../java/util/properties/testcases/test.pl | 97 + .../java/util/xml/TestplanCompiler.java | 249 + .../java/util/xml/XmlPropFileHandler.java | 360 + .../java/util/xml/XmlUtils.java | 59 + .../p4-triggers/build/triggerbuild.sh | 276 + .../infrastructure/p4-triggers/install.sh | 4 + .../p4-triggers/p4-triggers.package | 14 + .../p4-triggers/templates/custom.mk.template | 13 + .../someonefixedthebuildyoubroke.txt | 7 + .../templates/theydidnotfixthebuild.txt | 11 + .../templates/youbrokethebuild.txt | 10 + .../templates/youdidnotfixthebuild.txt | 11 + .../youdidnotfixthebuildyoubroke.txt | 11 + .../templates/youfixedthebuild.txt | 8 + .../templates/youfixedthebuildyoubroke.txt | 9 + .../p4-triggers/triggers/cad.trigger.sh | 58 + .../p4-triggers/util/handlechange.sh | 497 + .../release-system/doc/developer.csh | 73 + .../release-system/doc/fulcrumscript.html | 510 + .../release-system/doc/index.html | 38 + .../release-system/doc/plan.html | 69 + .../release-system/doc/proposal.html | 812 ++ .../release-system/doc/releasedoc.html | 820 ++ .../doc/thread/20040326225224_GB13623.html | 38 + .../doc/thread/20040326231021_GC13623.html | 39 + .../doc/thread/40628713_5050907.html | 732 ++ .../doc/thread/40631371_204.html | 805 ++ .../doc/thread/4064B681_6060601.html | 56 + .../doc/thread/4064BA26_9070309.html | 40 + .../doc/thread/4064BD7E_7000004.html | 58 + .../doc/thread/40652849_6020503.html | 95 + .../doc/thread/40652AD3_8060006.html | 46 + .../doc/thread/40652FE2_3070305.html | 44 + .../doc/thread/406845C8_9070905.html | 57 + .../release-system/doc/thread/index.html | 28 + .../release-system/scripts/.beta | 0 .../release-system/scripts/.itools | 62 + .../release-system/scripts/.latest | 0 .../release-system/scripts/.proteusbeta | 1 + .../release-system/scripts/.release | 0 .../release-system/scripts/buildcron.tcsh | 163 + .../release-system/scripts/buildfull.pl | 1090 ++ .../release-system/scripts/chkfmdb.pl | 180 + .../release-system/scripts/chkpref | 53 + .../release-system/scripts/chkrel | 70 + .../scripts/donotbuild_fedora-x86_64.txt | 27 + .../scripts/donotbuild_fedora.txt | 49 + .../scripts/donotbuild_solaris8.txt | 28 + .../release-system/scripts/fulcrum.pl | 1923 ++++ .../release-system/scripts/fulcrum.whatis | 239 + .../release-system/scripts/layout.txt | 3 + .../release-system/scripts/listfmdb.pl | 43 + .../release-system/scripts/package-inst.pl | 365 + .../release-system/scripts/preferred.txt | 320 + .../release-system/scripts/proteusbeta.txt | 3 + .../release-system/scripts/release.txt | 4 + .../release-system/scripts/releasef64.txt | 4 + .../release-system/scripts/releasepdk.txt | 1 + .../release-system/scripts/releases8.txt | 16 + .../release-system/scripts/tb-install.pl | 160 + .../release-system/scripts/tbdev.txt | 4 + .../release-system/scripts/trigger.pl | 256 + .../release-system/scripts/triggerd.pl | 324 + .../release-system/scripts/update2latest | 105 + .../release-system/scripts/updateall.pl | 122 + .../release-system/scripts/updatefmdb.pl | 389 + .../release-system/scripts/updaterelease.pl | 51 + .../infrastructure/sh-lib/file/config.sh | 92 + .../infrastructure/sh-lib/file/conon.sh | 24 + .../infrastructure/sh-lib/file/filecheck.sh | 116 + .../script/generate_script_with_libs.sh | 30 + .../infrastructure/sh-lib/sh-lib.package.inc | 5 + 2842 files changed, 624627 insertions(+) create mode 100644 async-toolkit/jtools/cad/all/all.package create mode 100644 async-toolkit/jtools/cad/all/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/assura.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/cdsp4.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/dfII_split_subtypes.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/calls.dot create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/index.html create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/fulcrum_cds_setup.inc create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/gdsIIWrite.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/javafiles-custom.mk create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/lefdef.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/mk_instance.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/nano.package create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cdl2snp.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/checkpgvia.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cmpdef.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dangling.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/def_rename.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dfIIhier.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/gds2cdl.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importGDS.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importQ.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef2rp.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef_rename.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mk_instance_multi.pl create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt.pl create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt_all.pl create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mklvt.pl create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mksvt.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mosaicify.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstract.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstractCellLog.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/defNets.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/exportDesignLef.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/genTracks.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/initNanoroute.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/listMissingAbstracts.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/plotdensity.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/signoff.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/cdl2cast2 create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/compilemem.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixcdl.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixgds.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixportdirection create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/gen_sram_scan_wrap.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importIP.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importSR.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/Lvbe.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAlwaysError.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssura.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraDrc.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraLvs.pm create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraNvn.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeDrc.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeLvs.pm create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOff.pm create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOffInclude.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/Lvfe.pm create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/vfe create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/ve.package create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2calibre.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2cast.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2et.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/getlibs create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslib create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslibs create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/custom.mk create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/density.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/dfIIflat2tree.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_abstract_views.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_instantiator_views.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_leaf_cells.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_mid_cells.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/updatenetlist.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/Tapeout.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/cdlsize265.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/ensurecelllib create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/gdsIIWrite.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/genIP.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/size265.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/writegds create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/templates/leaf_cell.il.template create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/floorplan/initFloorplan.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/lefdef/lefdefWrite.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/createFlattenView.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/exportDesignDef.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4add.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4addlibs.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4celllog.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4delete.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4edit.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4opened.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4revert.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4smartedit.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4submit.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4sync.sh create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/change_list_template.txt create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/gen_branch_spec.sh create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/assura_tech.lib create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/autoload/bindkeys create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/display.drf create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/usermenu/.menu create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/fakelib.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/lmwait.pl create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/mkcdswd.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/runincdswd.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/subtyping/dfII_split_subtypes.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/findclosestwithlayout.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/importPR.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mk_instance create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mkcdslib create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mktestcase create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/parsecellname create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/verilog2cdl.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/vip.sh create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.fvwm2/Main-8-bit create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.vnc/xstartup create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/getvncserver.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/nograph.sh create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/gen_autoload create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/aspice/aspice.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/area.rul create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/assura.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/drc.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/lvs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus28.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus65.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/fat.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/obs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/patterns.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/shield.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/util.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/GndSheild.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/Obstruction.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/cdc_insts.txt create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/optimus.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/placer.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/routedbuffers.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/router.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/sync_placer.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/templates.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/util.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/cellinfo.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/constraints.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/chain.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/compactsuperstacks.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/componentinfo.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/createsuperstacks.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domain.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domino.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/foldandchain.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/group.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/inlinesuperstacks.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/refold.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack_tools.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/unstack.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/density/density.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/distort/distort.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fig/fig.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/SpareCellFill.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.txt create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/align.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/anchor.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/floorplanTemplating.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/getcellmappings.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/importfloorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/initFloorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/optimizeXY.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/resolveOverlap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefloorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefromlayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/util.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsDataPath.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsNonOverlap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AnalysisLayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/CompactCells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawIO.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawWellPlugs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ExtraBasicSkills.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FL_Overlap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FloorplanCells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/Floorplanner.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumLoad.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumSetup.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GetOverlaps.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GlobalHiliteStack.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6 create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6.alias create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.map.x6 create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Floorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Main.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Verify.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ManageWindows.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MapConnectivity.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MoveToSnap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/PathFinder.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SelectSameMaster.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetDeleteViewLevels.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetSnapping.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ShowName.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/StandardBindKeys.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ChangeInstName.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CountNets.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CrawFish.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO_Globals_x6.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ExtendConnDepth.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FindInstance.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FloorplanArray.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_Floorplanner.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GenerateBindingFile.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GetManhattanDistance.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_HiLiteLabels.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_MoveAndSnap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TrackRouter.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/trZoom.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/gdsII/gdsIIhier.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/genfromsource/genfromsource.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/area.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/bbox.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/corner.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/fig.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/line.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/path.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/point.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/polygon.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/range.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/rect.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/segmenttree.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/checklength.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/deletepins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/length.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/rectonpitch.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/wiring.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/hierarchy.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/inline.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instance.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instantiator.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/fp.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/import.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/instancesfile/instance.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/abstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus28.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus65.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/conductor.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/drawdirectivekeepout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/fat.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/keepout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/obs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/patterns.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/shield.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/util.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/import.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/pr.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/AddBlkCell.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreator.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreatorTwo.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/CtreeGenerator.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/DrawImplant.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/Implant.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/LayoutGridPoly.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/decompact.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/spacestacks.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/fill.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/drawimplant.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/findplugingateinstance.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/lvsnodes.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/open.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.rp create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/guessplacementregions.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/initnp.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/npsearch.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placementregions.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placer.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placer.pl create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placercheck.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placerhack.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.rpl create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearchdone.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.inst create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.sh create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/squish.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/addplugs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/connectwellplugs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/plugs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/wellplugsoff.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/property.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/removeinvalidlayers.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/PreroutePowerVia.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/checkpolygons.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/delextrapolycontact.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/importccar.sh create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/lvsnodes.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/router.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routercheck.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearch.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchdone.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchinit.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routerwidth.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runccar.sh create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runrouter.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/setglcparams.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/snapFatPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/swapvias.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/template.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/drawregionwell.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/regionwell.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/apr_lefdef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/lefdef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/compact.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/mid.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/fillnotches.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/notches.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/ScanPinToAutoPinFile.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/abstractpin.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/autopin.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/canonicalize.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/channels/e1ofn.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/detailed_abstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/expand_pins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/leafpins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/midlevelpins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinlayer.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinplace.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pintemplates.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinutil.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/sync_pins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/vstruts.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/power_grid/power_grid.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/AutoGeneratePowerGrid.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/powergrid.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/proteus/proteus.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/abstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/canonicalize.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/flatten.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/ground.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/layout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/nanoroute.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/prelayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/reset.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/route.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/routepath.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/sync.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/trim.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/tech/spacing.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/transform/transform.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.state.template create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/cellview.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/flatten.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/floorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/routed.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/sync.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/util.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/p4/p4.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/distinst.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/inlineconnections.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/lvsnodes.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/netlisttable.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/swapmasters.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/syncnetlist.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/update_floorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/updatenetlist.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ArrayCells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FLOverlap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanAllSubcells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanTemplate.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/InitFloorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/LoadFloorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/PromoteInplacePins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ReplaceSubcells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ResolveOverlap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/SaveFloorplan.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/CheckAlignment.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/FixAlignment.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/SetAlignment.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGrid.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGridAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CopyBusGuidesToPrelayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CreateGuideInst.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteBusWires.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteOverlapMarkers.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteWires.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawAllPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawWires.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindCopies.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindOverlaps.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/MoveGuidesToBuswires.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RefreshAll.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RoundGuidePaths.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/SetBusPattern.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CCAR.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CheckSubcell.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreateCDL.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreateFloorplan.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreateLib.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreatePrBound.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DeleteAllShapes.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DiffLayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/EstimateWireDistance.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/AttachPinShape.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/CheckSubcellPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkBaliToFiji.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkPrelayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/SnapPowerGrid.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fill.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/FillSpareGate.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetCellArea.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetFigArea.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GoTo.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/DeleteNotHand.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandAll.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandSelected.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/Struts.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Inline.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Instanciators.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReplaceSubcells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReportInstances.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/Clean.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawImplant.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPoly.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawStruts.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/GroupChains.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/MakeAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlaceGates.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlacePlugs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/RouteLeaf.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/SyncToNetlist.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LeafAbstractList.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LockFolds.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/Clean.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeFlatten.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeLayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakePrelayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Options.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/.menu create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4Cell.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4EditAllSubcells.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4add.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4edit.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4revert.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4submit.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/CanonicalizePins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawResetPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawSubPins.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/PreroutePins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Clean.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/CreateMidAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/DrawPlugs.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Keepout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Route.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/ViaExtension.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Fold.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Inline.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Stack.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/StartVLVS.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/Signoff.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/SignoffInclude.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/CheckBusWires.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/InteractiveReport.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportMBUFChannels.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportWirelengths.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/clearHighlights.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/createTagView.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/runVue.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/setVueWindow.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateLeafAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateMidAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePowerGridAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePrBound.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/ListMissingAbstracts.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/CreateTracksDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignLef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportNondefaultRuleDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportVerilog.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CopyBusGuidesToPrelayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreateCellList.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreatePowerGrid.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/DrawPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/CreateLayoutView.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/ImportDef.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/SaveFiles.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/InitNanoroute.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/RunNanoroute.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/NanorouteDoc.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CheckAlignment.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/Clean.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrBound.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrelayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/ResolveOverlap.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteOverlapMarkers.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteWires.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DrawBusWire.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/FindBusOverlaps.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/SetBusPattern.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateLeafAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateMidAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePowerGridAbstract.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePrBound.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/ListMissingAbstracts.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/CreateTracksDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportDesignLef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportNondefaultRuleDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportProteusFloorplanDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreateCellList.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreatePowerGrid.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/DrawPins.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/FlattenView.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrBound.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrelayout.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/DrawWires.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/FlushAndSync.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/GetCellArea.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/.menu create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/AllSync.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateCellList.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateGuideInst.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignLef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportNondefaultRuleDef.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/Flush.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys_hand create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/automation/copyview.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/util/license.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/binarysearch.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/search.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cache/cache.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cellview.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/counter.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/db.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/defaults.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/expression/expression.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/configfile.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/dirtree.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/fileutil.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/libcellview.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/path.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/readfile.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/tempfile.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/lib.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/list.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/partition.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makelayouttag.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makemidlayouttag.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/math/math.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/name.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il create mode 100755 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il.inst create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/pcell/pcell.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/profile.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/prop/prop.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/recurse.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/stack/stack.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/escapestring.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/strutil.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/table/table.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/version.il create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/updatenetlist.package create mode 100644 async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/virtuoso-integration.package create mode 100755 async-toolkit/jtools/cad/java/Makefile create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/CDL/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/Cast/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/CastQuery/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/CastTwo/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/CellHierarchyDump/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/CoSim/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/Csp/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/MathExpression/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/Shape/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/antlr-grammers/StringExpression/antlrrules.mk create mode 100644 async-toolkit/jtools/cad/java/build/apps/dsim/apprules.mk create mode 100644 async-toolkit/jtools/cad/java/build/apps/jauto/apprules.mk create mode 100644 async-toolkit/jtools/cad/java/custom.mk create mode 100755 async-toolkit/jtools/cad/java/scripts/cadencize create mode 100755 async-toolkit/jtools/cad/java/scripts/cdl2aspice create mode 100755 async-toolkit/jtools/cad/java/scripts/csp2java create mode 100755 async-toolkit/jtools/cad/java/scripts/ext2aspice create mode 100644 async-toolkit/jtools/cad/java/scripts/fakecadencize create mode 100644 async-toolkit/jtools/cad/java/scripts/fulcrum-java.sh.template create mode 100644 async-toolkit/jtools/cad/java/scripts/fulcrum-rename.sh.template create mode 100755 async-toolkit/jtools/cad/java/scripts/gen-build-id create mode 100755 async-toolkit/jtools/cad/java/scripts/grabRegisterData.pl create mode 100755 async-toolkit/jtools/cad/java/scripts/iosim create mode 100755 async-toolkit/jtools/cad/java/scripts/jauto create mode 100755 async-toolkit/jtools/cad/java/scripts/jauto_espresso create mode 100644 async-toolkit/jtools/cad/java/scripts/jespresso create mode 100755 async-toolkit/jtools/cad/java/scripts/jflat create mode 100755 async-toolkit/jtools/cad/java/scripts/jlvs create mode 100755 async-toolkit/jtools/cad/java/scripts/make_subdir_makefile create mode 100755 async-toolkit/jtools/cad/java/scripts/mgn create mode 100755 async-toolkit/jtools/cad/java/scripts/mips-dis create mode 100755 async-toolkit/jtools/cad/java/scripts/output-source-files create mode 100755 async-toolkit/jtools/cad/java/scripts/run-all-tests create mode 100755 async-toolkit/jtools/cad/java/scripts/run-one-test create mode 100644 async-toolkit/jtools/cad/java/src/cfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/benchmarks/JavaSyncCost.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastCacheManager.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFileParser.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSemanticException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSyntaxException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ASTWithInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AbstractSplicingEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AlintFaninValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AmbiguousLookupException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AnonymousValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ArrayValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BlockEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BoolValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Cast.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastLexerInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTree.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTreeParserInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CellInterfaceCollectionIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentEntryIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CircularImportException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ClassType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DenseSubscriptSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Dumb.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbLexerInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbParserInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Environment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntry.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntryIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FieldedValueInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FixedBlockEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FloatValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ImportEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InstanceValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/IntValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidBindException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidOperationException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelContainerValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LocalEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LoopEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/MetaParamValueInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NodeValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NullEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/PRSExpressionValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Range.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SelfImportException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SemanticWrapperException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SparseSubscriptSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SplicingEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SubscriptSpecInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Symbol.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SymbolRedeclaredException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TestDenseSubscriptSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TokenWithInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TopLevelEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleGroupValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Type.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/UserDefinedValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Value.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveConstants.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterfaceFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/UnknownDirectiveException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/CastEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DefaultCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveComparator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveConditional.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDefinition.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDifference.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactoryInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveLoop.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveParser.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSyntaxException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/TokenInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAliases.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAssert.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastInfo.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastParsingOption.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastPrs.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubcells.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubtypes.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwo.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoTree.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/DumbTwo.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/Functions.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/PrsCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/package.html create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/CastFileServer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveOverride.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveWalker.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/NetProperty.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/StandardParsingOption.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/fileserver.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/AttributeInheritanceException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/BadCSPPortException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellDelay.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/ChildrenFirstCellInterfaceIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSets.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/HierarchyInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/InstanceTrace.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchEnvironmentException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchSubcellException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/RefinementException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/SubcellCreationException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/cell/TestExclusiveNodeSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractCircuit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Capacitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapacitorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CircuitGraph.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ConjunctivePath.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CullingCircuitGraph.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Diode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DriverNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedRCGraph.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/MosDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Node.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistiveSubnet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Resistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Source.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/SourceInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TestSubnet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Transistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TransistorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNodeInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractBinaryExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractCompositeStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractGuardedStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractLoop.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractRepetitionStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractSelectionStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractUnaryExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AddExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AndExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayAccessExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AssignmentStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BitRangeExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/CSPProgram.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelStructureType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalAndExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalOrExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declaration.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclarationList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declarator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclaratorList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicRepetitionStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicSelectionStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DivideExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/EqualityExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ErrorStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExponentialExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionCallExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionDeclaration.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterEqualExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterThanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommand.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandWithStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IncDecStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/InequalityExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LeftShiftExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessEqualExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessThanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageArrayAccessExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionTerm.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageIdentifierExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageLoopTerm.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageStructureAccessExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTermInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTerms.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopGuard.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MemberAccessExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MultiplyExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NegateExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NodeType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicRepetitionStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicSelectionStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NotExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/OrExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ParallelStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PeekExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PortDirection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ProbeExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Range.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RemainderExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RightShiftExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SendStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SequentialStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SkipStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StatementInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureAccessExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureDeclaration.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SubtractExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/TemporaryIntegerType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Type.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VarStatement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/XorExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/coverage/Monitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/coverage/ParseException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/coverage/ProbeInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2gma/Csp2Gma.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2gma/GmaEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/.empty create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/ArbiterVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Class.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Java.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/JavaEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/NoCSPBlockException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SemanticException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolRedefinedException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolUndefinedException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.html create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArray.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArrayBoundsException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspBoolean.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray1.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray2.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray1.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray2.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspCloneableValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspInteger.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspMetaParamArray1.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNodeArray1.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspRuntimeAbstractDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspSnoopingInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspString.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspStructure.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/FiniteCspInteger.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Fold.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LinkageHelper.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LoggedCspArray.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/NonDeterminismException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Packable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/ShadowCspInteger.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/StackFrame.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/cspruntime.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/Csp2TT.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/PlayingChannelInput.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/RecordingChannelOutput.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/CommonEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/Csp2Verilog.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/SystemVerilogEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/VerilogEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/Csp2Xml.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/XmlTourist.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/Csp.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParsePosition.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParseRange.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/assign.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select_else.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_bar_stmt.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_comma_stmt.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_seq_stmt.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_stmt.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select_else.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_bars.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_comma.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/paren_proc.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/peek.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv_var.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det_else.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd_else.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_true.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_add.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_and.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array_2d.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_div.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_eq.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_geq.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_gt.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_hex.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_leq.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_add.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_and.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_mul.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_or.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_lt.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mod.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mul.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neg.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neq.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_not.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_octal.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_or.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_paren.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_peek.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_probe.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_recv.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shl.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shr.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_sub.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_id.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true_skip.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_expr.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_var.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/seq.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/skip.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/alt.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_bucket.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_gen.csp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/csp2rtl.properties create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/preprocessor.properties create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/resources.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/typechecker.properties create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ArithmeticOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CSPCellInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ConstantEvaluator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/DeclarationProcessor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FilterInitializers.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FunctionPreprocessor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Interval.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/NullResourceBundle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Problem.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ProblemFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RefinementResolver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RemoveScalars.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SimpleProblem.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SymbolTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/UniqueLabel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalysisException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalyzer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorByCategory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorExceptionWithLocation.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/AnonymousInstanceException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/AssertBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockCommon.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/CastDesign.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellNet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellTypeProcessor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ChannelNet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ConnectionInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/CspBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/DirectiveBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/EnvBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/HalfOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/JavaBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/MergeDirective.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/NamedEnvironmentRedeclaredException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ParamTypeInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsDirective.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/SubcellBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/VerilogBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/ArrayMetaParam.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/BooleanMetaParam.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/FloatMetaParam.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/IntegerMetaParam.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamDefinition.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamTypeInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ArrayType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ChannelType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/NodeType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortDefinition.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortTypeInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/StructureType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ArgumentMismatchException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Point.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Polygon.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/PolygonIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Shape.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollectionIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionRedefinedException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionUndefinedException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlockIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteablePoint.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShape.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollectionIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeFunctionTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapesBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/PolygonImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFactoryImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFunctionImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/SkillExporter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteablePointImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeCollectionImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeFunctionTableImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapesBlockImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/Shape.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollectionIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollectionIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/ConcatOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/Constant.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/OperatorCommon.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SkillStringVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/StringExpressionFactoryImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SubExpressionReference.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/VariableReference.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/WriteableStringExpressionCollectionImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpression.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionary.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionaryIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionary.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionaryIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/impl/WriteableStringVariableDictionaryImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AbstractDeviceTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceCell.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/BSim3Model.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Capacitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CapacitorTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CastTestEnvironment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DeviceInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Diode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DiodeTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCharge.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphChargeDerivative.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrentDerivative.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphPortData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/NoModelException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/PortData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Resistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/ResistorTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/SizedModel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Tester.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Transistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/TransistorTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Wire.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLFileFormatException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLParser.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/AspiceCellAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDL.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLAliases.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLDeviceNameFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryAdaptor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInlineFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInterfaceSimplifier.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLNodeNameFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScaleBali.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScalingFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLstat.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CanonicalizeCDL.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CellSetFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ChildrenFirstTemplateIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inline.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inliner.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/InternalNodeFilterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesCDLFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesNullHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/NetlistBlockFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ReadCDLIntoFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RemoveLVSNodesCDLFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RenumberFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/SplittingFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Template.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateSplitterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/CDLWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/BindRulNameInterfaceFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterfaceFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamerFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CachingNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNames2CastNames.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceReverseNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2CadenceNames.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2GDSIINames.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterfaceFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeNames.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2NameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2ReverseNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDSIINames2CastNames.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNames.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/PMCHackNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/RCXHackNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/ReloadableNameInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/Rename.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/TrivialCDLNameInterfaceFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/__init__.py create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/cdlrenamer.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.py create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.sh create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/common/Capacitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/common/DeviceTypes.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/common/HierName.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/common/InvalidHierNameException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/common/TestHierName.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Environment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ExtCell.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/FET.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Node.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ResistanceClassOutOfBoundsException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Terminal.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ArraySpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtFileFormatException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtParser.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SimulatorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceFileFormatException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceParser.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/verilog/grammar/PortDeclaration.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/verilog/grammar/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/file/verilog/grammar/verilog.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/CellListFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/GenerateFloorPlanningData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypeInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfoImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFilePCellTypeInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFileTransistorTypeInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/TransistorTypeInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/geometry/BoundingBox.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Point.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/geometry/SteinnerTree.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Transform.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/CopyingOutputStream.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/EmptyPositionStackException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/FileSearchPath.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/FileUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentPrintWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/LineContinuationStream.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/NullWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/OutputPumper.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/PositionStackReader.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/Printable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPath.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectoryIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/StreamLexer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/StringBuilderWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TestPositionStackReader.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TestStreamLexer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotDoubleException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotEOFException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIdentifierException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIntException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotLiteralException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotQuotedStringException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotSymbolException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotWhitespaceException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/TrivialSearchPathFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintStream.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/AP1ofNDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APChannelDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APDefaultPortDefFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APHorizontalStrutDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceChannelDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceNodeDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlacePortDefFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APLocale.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APNodeDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPitchedNodeDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDefFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPowerGridDef.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/AutoPins.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/CellDirs2Skill.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/CellInterfaceActionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/CellInterfacePortCollector.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/CellProcessor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/CellProcessorException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/CellProcessorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/HierarchicalDirectiveInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/InstanceCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodes.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForExtract.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForHierarchy.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/LayerCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/MapUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinGlobal.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinPlaceException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillDirectiveEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillStringInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/AssuraBindRulTableEmitterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/CachingTableEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/FilterInternalNodesTableEmitterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GDSIILVSNodesHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIDataFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SharedTableEmitterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SkillTableEmitterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SplittingTableEmitterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterFactoryInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/layout/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDeviceIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlist.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlistIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNodeIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/Visitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/CDLEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/ConcatAbstractDeviceIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FactoryEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FoldTransistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NetlistFormatter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NumberedNodeNetlist.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractDeviceIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNetlistIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNodeIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SkillEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/VisitorImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/CDLReaderToNetlist.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Device.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/FET.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Net.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlist.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlistFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SubCircuit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/ChildrenFirstNetlistIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/CombiningNodeIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FETIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FlatteningIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/SubcellIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRule.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRuleSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/prs/UnimplementableProductionRuleException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/sync/Semaphore.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/test/AbstractTestCase.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/test/TestEverything.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/test/TestFailedError.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AbstractDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogTraceInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogWatcher.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/BSim3Model.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Capacitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Circuit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/CurrentSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DefaultCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DevTester.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DigitalDriver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Diode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/ExpVoltageSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/GroundNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Jaspice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceCallbackInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceCircuit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceModule.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceProp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceCircuit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Node.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PWLVoltageSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PulseVoltageSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Resistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SinVoltageSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SizedModel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SourceHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TestCircuit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceElement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFileException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Transistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/VoltageSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cadalyze.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cell.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/DoubleDistribution.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/HtmlPage.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/LayoutInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/LeafStats.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NetGraphAnalyzer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NodeProps.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/cadalyze.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceActionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataTreeMapImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/Cadencize.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeDataInterfaceActionHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeOutputToSkill.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/SubCellFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/Cast2Def.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/cast2def.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/Cast2Skill.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/Cast2Verilog.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/cast2verilog.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/verilog_filelist.pl create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2aspice/CDL2Aspice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/CDL2Cast.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/cdl2cast.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2Skill.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cell/CellConstants.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/.empty create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CSPCoSimInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelDictionary.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelFactoryInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelParameterDict.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelTimingInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelArrayInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelInputArray.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelNames.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelOutputArray.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimHelper.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimParameters.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceConstructionException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceParameters.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/InternalChannelInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/JavaClassParameter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/JavaCoSimDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/JavaCoSimInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/NodeFactoryInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/NodeLinkageInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/AcceptorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimLevelSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/DuplicateInstanceSpecException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ExtraInstanceSpecException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/HierarchyDepthException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpecList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/LevelSpecInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/Mode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeListLevelSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/NoSuchInstanceException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/VisitorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayers.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/GDSIIFile.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayerInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayeredPolygon.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/PolygonUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/BinningQueue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/CutoffChecker.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSim.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimDebug.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimMain.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimSynchronizer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DigitalScheduler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Event.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueueInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ExceptionPrettyPrinter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpEdge.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpGraph.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InputSlewCheck.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InstanceData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoBehaviorFoundException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoSuchCellException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Node.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NodeWatcher.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/OutputSlewCheck.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProcessMeasuredDelay.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProgressMeter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RandomEventQueue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Resetable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Rule.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunSlewChecks.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunStaticTiming.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SchedulerRunner.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SequencedEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewCheck.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewChecker.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewViolation.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/StaticizerSlewCheck.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/WakeAt.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim-readlineonly.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2aspice/Ext2Aspice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2cdl/Ext2Cdl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Edge.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/GA.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/ILG.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Layer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/PlugEntry.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Poly.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/PolyOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortableVector.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortedEdges.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Span.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SpanList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Util.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/WellPlugData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/GenerateIPData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitterFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/PMCNameInterfaceFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/RenamingVerilogFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/TablifyingNameInterfaceFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AbstractPath.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AdditiveTerms.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AutoThreshold.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CDLOutput.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CGTransistorSizingTool.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Cast2Cdl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastStat.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CatPath.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CellHierarchyDump.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CheckChargeTools.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/ConjugateGradientSolver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CountPrs.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DebugOption.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DelayCalculator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Floorplan.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionSimplifier.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionTerm.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GenerateChargeSharingTests.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GeneratePLTSubtypes.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GlobalNet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/IdleStateSolver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jauto.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessage.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessageCenter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoSolver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoUI.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jtimer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/LeafSpec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/MergeHint.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NegativeDelayBudget.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSink.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetlistDistance.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/PartialExtract.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizeStaticizers.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizingPath.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubcellProcessor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubprocessFailedException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeMerge.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeOutput.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeSplit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TechnologyData.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Transistor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TransistorSizingTool.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/cast2cdl.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/countprs.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jauto.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/javafiles-custom.mk create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jtimer.sh create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/AbstractDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/BenchMarkJfast.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/TestDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/JFlat.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/jflat.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Dnf.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LVS.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LVSProblem.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LvsOperators.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetGraph.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetToPrs.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/PrsToNet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Staticizer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/SubtypeInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/jlvs.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/02-09-03.html create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelName.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelNameImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/LogicFileReader.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/PReSto.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/Presto2.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTableImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/WarningAccumulator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Emitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/GreedyComplete.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Node.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/NodeBuilder.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeMunger.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeReadjuster.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AbstractPrsLine.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AliasNodeExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/And2C2Expression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ArbitraryNodeExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/CElementExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Direction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/LineAndSection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NandExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeCanonicalizer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeName.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NorExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Organizer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ParameterizedNodeName.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Power.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsLine.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsPrinter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Section.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/SectionImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ShorthandNodeExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Simplification.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/TwoAnd2C2Expression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/UnparameterizedNodeName.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperatorSink.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/presto.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/CompletionInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Declarations.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DeclarationsImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoCompletion.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoLogic.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Doodad.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/SectionFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Template.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/TestOutput.java create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-one-cell.pl create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-summary.txt create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.cast create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.pl create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/AbstractConverter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterConstants.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GateConverter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GeneratePortMapping.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GenerateWrapper.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphConverter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphGateConverter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetlistConverter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/Prs2Verilog.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/TriConverter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/prs2verilog.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/ArrayAccess.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/BinaryOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/CompilationUnit.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/ConcatOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/ContinuousAssign.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/Delay.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/Expr.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/HierIdent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/Ident.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/LineComment.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/MacroUse.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/Module.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/ModuleInst.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/NamedPort.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/NetDecl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/Parameter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/ParameterDecl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/Primitive.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/SimpleRenamingVerilogFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/TrivialVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/UnaryOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/VerilogEmitter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/VerilogFactoryImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/VerilogFactoryInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/VerilogObject.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/VerilogUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/verilog/VerilogVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/AutoSimulateCell.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/ClientHandlerThread.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/DSimHelper.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/RTEClient.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/RTEServer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/RegressionTestEngine.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/SimResults.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/htmlWriter/FrameMaker.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/htmlWriter/HtmlStandardWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/htmlWriter/WriteCellList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/htmlWriter/WriteSimResults.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/htmlWriter/WriteStatistics.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/htmlWriter/WriteTestList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/htmlWriter/WriteTreeHier.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/man/rte.1 create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/rte create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/rte.package create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/job_netbatch.pm create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/pltReporter create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/rte create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/rteCellListGen create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/rteDbMerge create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/rteLauncher create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/rteLib.pm create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/rteReporter create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/util.pm create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/scripts/verif_util.pm create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/share/examples.html create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/share/help-doc.html create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/share/logo.png create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/share/stylesheet.css create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/rte/share/test-info.html create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/AnalogTrace.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/Attribute.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/AttributeEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/AttributeValue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/BeginTranEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/BooleanAttribute.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/ChannelSigscan.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/DebugOpts.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/EndTranEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/GrowingArray.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/IntAttribute.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LinkEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LogEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggedDouble.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggedInt.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggedLogicArray.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggedLong.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggedString.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggedVar.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggedVarEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LoggingObject.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/LongAttribute.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/NativeHandle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/NodeLogger.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/ObjectHandle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/README.html create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/Sigscan.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/SigscanException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/StringAttribute.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/Transaction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/TransactionFiber.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/TransactionType.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/cppfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/progfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/sigscan.cpp create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/sigscan/sigscan.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/Cast.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/Channel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/ObjectiveTerm.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/Slacker.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/Subcell.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/Type.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/slacker/slacker.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spice2spice/Spice2Spice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/NetStatistics.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/ProgressUpdateCallback.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/SpiceMine.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/test/maxpath.spice create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/test/testsubnet1.spice create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/test/testsubnet2.spice create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/test/testsubnet3.spice create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/test/testsubnet5.spice create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/spicemine/test/vdn.spice create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/svs/SVS.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/CellTiming.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/CellTimingProteusVCSetup.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/Espresso.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/GenerateCast.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/GenerateLib.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/GenerateLogicLibrary.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/GenerateVerilog.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/Karnaugh.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/PathTiming.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/Test.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/TimingBlock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/Vector.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/synthesis.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/synthesis/synthesis.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/AbstractDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/AbstractDeviceThread.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/AbstractSingleThreadedDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/AbstractSyncDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/AccurateWait.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Arbiter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BenchMarkTsim.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BitBucketChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BufferedChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BufferedNodeChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BufferedNodeReadChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BufferedNodeWriteChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BusConnector.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BusDriver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/BusWatcher.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChanSetup.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelBundle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelCreationInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelFullException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelIO.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelInput.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelInputAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelInputBundle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelInputListener.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelInputUnfilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelOutput.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelOutputAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelOutputBundle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelOutputFilter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelOutputListener.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ChannelStatus.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Clock.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ClockDriver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ClockWatcher.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ClockedDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ConvenientDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Data.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/DelayElement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/DelayedSetEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/DeviceLogger.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/EmptyWaitSetException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ExitEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/ForceDriver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/IllegalSlackException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/InaccurateWait.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/MergeConflict.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/MergeDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Message.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/NativeBusDriver.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/NoSuchNodeException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/NodeChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/NodeReadChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/NodeWriteChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/README create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/RailList.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SchedulerRunner.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SharedBus.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SharedBusEvent.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SlacklessNodeChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SlacklessNodeReadChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SlacklessNodeWriteChannel.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SplitDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Startable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/StateMachine.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Statistics.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Statusable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/SynchronousConverter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/TSimDebug.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/TestChannelBundle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/TestChannelOutputBundle.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/TimingBuffer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/UnservicedEventException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Wait.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/WaitFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/Waitable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/WaiterInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/WideNode.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/WideNodeImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/channellib.package create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/examples/BusExample.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/examples/ConverterExample.java_ create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/examples/MixedExample.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/package.html create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/Alternator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/BUFFERED_CHANNEL.cast create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/BenchMarkTsim.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/Buffer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/Copy.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/DataGenerator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/NodeChannelTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/TestDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/TestLoop.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/TokenRelay.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/buffered_channel_timing.txt create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/go create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/histogram.pl create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/loopgraph create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/perf/AsyncBufferDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/perf/AsyncFIFOTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/perf/AsyncSinkDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/perf/AsyncSourceDevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/perf/SyncFIFODevice.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/perf/SyncFIFOTest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/sync/SyncSink.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/sync/SyncSource.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/sync/SyncTest.java create mode 100755 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/test/testloop create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/tsim.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/DeviceHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/DeviceInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/Server.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/SignalNotFoundException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/VerilogConnection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/VerilogInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/VerilogServer.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/VerilogSharedBus.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/VerilogTestClient.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/VerilogUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/VpiInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/tsim/verilog/verilog.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/Distribution.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/FilePacket.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/GrabBag.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/LFSR.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/LFSRPacket.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/OrderedGrabBag.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/Packet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/RandomGrabBag.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/RandomPacket.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/Streamable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/TestBags.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/TestGen.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/tools/verification/gen/WeightedElement.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/AbstractAtomicBooleanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/AbstractBooleanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/AndBooleanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/AndBooleanExpressionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/BooleanExpressionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/BooleanExpressionVisitorInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/BooleanUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/HierNameAtomicBooleanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/OrBooleanExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/OrBooleanExpressionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/bool/TestBooleans.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/classloader/ConfigurableClassLoader.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/ADsimModule.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/CmdCommand.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/CmdLine.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/CmdModule.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/DSimModule.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/EchoModule.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/RssSampler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/Signal.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/Signal.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/Signal.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/cmdline.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdline/submakefile create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/CommandLineArg.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/CommandLineArgFormatException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/CommandLineArgs.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/CommandLineArgsIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/CommandLineArgsUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/InvalidCommandLineArgException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/MissingCommandLineArgException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/CachingCommandLineArgs.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/CommandLineArgDefImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/CommandLineArgWithNoValueDefImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/CommandLineArgsBaseImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/CommandLineArgsDefImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/CommandLineArgsWithConfigFiles.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/ConfigFileListAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/PedanticCommandLineArgs.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/TransformCommandLineArgs.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/UnionCommandLineArgs.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/cmdlineargs/defimpl/defimpl.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Alias.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/AliasedMap.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/AliasedSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Array2DIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/BigIntegerReference.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/BigIntegerReferenceInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/BoundedSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/CollectionUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Counter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/DefaultedMap.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/EnumerationToIteratorAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/FilteringIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/FlatteningIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/FullTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/HashCounter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/IntArrayComparator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Interpolate.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/IterableIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Iterator2StringContainerIteratorAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/LinearInterpolatable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Map2SetAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/MappingIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/MultiMap.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/MultiSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/MutableDouble.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/MutableInt.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Namespace.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/NaturalOrderComparator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/ObjectUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Pair.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Partition.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/PriorityQueue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Queue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/RandomQueue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/ReverseArray.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/SortingIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/SparseTable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/StringContainerIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/StringRepComparator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TestAlias.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TestAliasedMap.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TestAliasedSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TestCollectionUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TestMultiSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TestPriorityQueue.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TriMap.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/TriTree.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/Triplet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/UnmodifiableIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/WeakHashSet.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/container/container.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/Debug.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/GetTime.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/GetTime.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/SimpleProfiler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/VersionInfo.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/cfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/gettime.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/debug/progfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/exception/AssertionFailure.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/exception/ExceptionUtils.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/ext/Exec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/ext/TestExec.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/BinaryAction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/BinaryFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/BinaryPredicate.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/Functional.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/NonNull.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/NullaryAction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/NullaryPredicate.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/NumericPredicate.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/UnaryAction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/UnaryFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/functions/UnaryPredicate.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/graph/Edge.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/graph/Graph.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/graph/GraphUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/graph/ShortestPaths.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/graph/Vertex.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/graph/WeightedVertex.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/htmlWriter/HtmlDocWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/htmlWriter/HtmlWriter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/logging/Configurator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/logging/ConsoleHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/logging/SimpleFormatter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/logging/StderrHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/logging/StdoutHandler.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/logging/logging.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/logging/logging.properties create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/math/BigIntegerUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/math/LinearInterpolation.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/math/Math.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/math/QuadraticInterpolation.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/math/test.in create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/math/test2.in create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/ExpressionCollection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/ExpressionCollectionIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/MathExpression.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/MathExpressionFactory.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/NotAConstantValueException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/Visitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/WriteableExpressionCollection.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/WriteableExpressionCollectionIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/ArccosFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/ArcsinFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/ArctanFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/CeilFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/Constant.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/CosFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/DivideOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/DottyVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/DoubleCommon.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/DoubleOperatorCommon.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/ExpFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/FloorFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/LessThanOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/LogFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/MathExpressionFactoryImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/MinusOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/ModOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/NegationOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/PlusOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/RoundFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/SinFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/SkillVisitor.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/SubExpressionReference.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/SumOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/TanFunction.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/TimesOperator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/VariableReference.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/WriteableExpressionCollectionImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/parser/MathExpression.g create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/parser/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/impl/parser/parser.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/Variable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/VariableDictionary.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/VariableDictionaryIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/VariableUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/WriteableVariable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/WriteableVariableDictionary.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/WriteableVariableDictionaryIterator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/impl/EnvironmentAdapter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/mathexpression/variable/impl/WriteableVariableDictionaryImpl.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Bind.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Completion.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Keymap.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Modify.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_CPFunction.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_CPPFunction.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_CompletionFunction.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_Function.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_Function2.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_KeyboardFunction.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_Keymap.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_Keymap_Entry.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Readline_VFunction.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Redisplay.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Table.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Test.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Undo.c create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/Wrapper.h create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/cfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/progfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/readline.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/readline/submakefile create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/AbstractBinaryOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/AbstractUnaryOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/AbstractVariable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/DependantVariable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/DivOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/ExpressionInterface.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/Function.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/IndependantVariable.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/Literal.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/MinusOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/ModOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/MultOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/NegateOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/PlusOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/PowOp.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/recalc/TestRecalc.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/BitFieldFormatter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/ByteArrayString.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/NaturalStringComparator.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/NumberFormatter.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/PrintfFormat.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/StringUtil.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/UnrepresentableCharException.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/text/text.package.inc create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/tree/Forest.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/tree/Node.java create mode 100644 async-toolkit/jtools/cad/java/src/com/avlsi/util/tree/Tree.java create mode 100644 async-toolkit/jtools/cad/java/src/cppfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/java/src/libfiles-custom.mk create mode 100644 async-toolkit/jtools/cad/lve/build-system/lveMakefile create mode 100644 async-toolkit/jtools/cad/lve/doc/dag.html create mode 100644 async-toolkit/jtools/cad/lve/doc/data_mining.html create mode 100644 async-toolkit/jtools/cad/lve/doc/directives.html create mode 100755 async-toolkit/jtools/cad/lve/doc/dot create mode 100644 async-toolkit/jtools/cad/lve/doc/faq.html create mode 100644 async-toolkit/jtools/cad/lve/doc/hackers.html create mode 100644 async-toolkit/jtools/cad/lve/doc/intro.html create mode 100644 async-toolkit/jtools/cad/lve/doc/logo.png create mode 100644 async-toolkit/jtools/cad/lve/doc/lve.css create mode 100644 async-toolkit/jtools/cad/lve/doc/lve.dot create mode 100644 async-toolkit/jtools/cad/lve/doc/lve.png create mode 100644 async-toolkit/jtools/cad/lve/doc/resources.html create mode 100644 async-toolkit/jtools/cad/lve/doc/table.css create mode 100644 async-toolkit/jtools/cad/lve/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/LveAspice.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/LveDB.pm create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/LveDelay.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/LveStatus.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/LveSummarize.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/LveUtil.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/Pathalyze.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/Pathalyze/Measurement.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/Pathalyze/Parameter.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/Pathalyze/Parser.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/rename.pm create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/rvp/LICENCE.TXT create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/rvp/hier_print.pl create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/rvp/rvp.pm create mode 100644 async-toolkit/jtools/cad/lve/lib/perl/rvp/rvp.pod.html create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/rvp/rvp_test.pl create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/rvp/simple_hier_print.pl create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/rvp/strip_comments.pl create mode 100755 async-toolkit/jtools/cad/lve/lib/perl/rvp/synth_make.pl create mode 100644 async-toolkit/jtools/cad/lve/lve.package create mode 100755 async-toolkit/jtools/cad/lve/script/perl/analyze_coupling create mode 100755 async-toolkit/jtools/cad/lve/script/perl/canonicalizing_spice2aspice create mode 100755 async-toolkit/jtools/cad/lve/script/perl/captally.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/cell_lef.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/char_cadence_lib.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/check_dummy_pin.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/checkdb.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/chkdupdef.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/chkdupname.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/db2table.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/def2vddgnd.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/deletetracefile create mode 100755 async-toolkit/jtools/cad/lve/script/perl/df2d.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/donvn2 create mode 100755 async-toolkit/jtools/cad/lve/script/perl/find_bumps create mode 100755 async-toolkit/jtools/cad/lve/script/perl/find_envs create mode 100755 async-toolkit/jtools/cad/lve/script/perl/find_layout create mode 100755 async-toolkit/jtools/cad/lve/script/perl/fix_alint_raw create mode 100755 async-toolkit/jtools/cad/lve/script/perl/fix_pinswap.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/fixhdrc.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/fixnames.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/flatcdl.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/frc.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/gds2def.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/genlib.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/genliberty.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/getslack.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/hdrc.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/histogram create mode 100755 async-toolkit/jtools/cad/lve/script/perl/importSync.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/importV.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/isgds create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lefWrite.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/local_aspice create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_apl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_em create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_jobs create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_query create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_raw create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_resummarize create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_sram create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_sram_130nm create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_summarize create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_threshresp create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lve_tracking create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lveextractgray.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/lveliblef2p4 create mode 100755 async-toolkit/jtools/cad/lve/script/perl/make_alint_in create mode 100755 async-toolkit/jtools/cad/lve/script/perl/make_aspice_in create mode 100755 async-toolkit/jtools/cad/lve/script/perl/make_asta_in create mode 100755 async-toolkit/jtools/cad/lve/script/perl/make_slint_in create mode 100755 async-toolkit/jtools/cad/lve/script/perl/merge_alint_out create mode 100755 async-toolkit/jtools/cad/lve/script/perl/mkbind.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/mkpinassign.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/mksigs.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/mmonitor create mode 100755 async-toolkit/jtools/cad/lve/script/perl/pathalyze.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/pathalyze_HitChan create mode 100644 async-toolkit/jtools/cad/lve/script/perl/plt_scenarios.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/proteus_characterize create mode 100755 async-toolkit/jtools/cad/lve/script/perl/qsub/qb create mode 100755 async-toolkit/jtools/cad/lve/script/perl/qsub/qbwrapper create mode 100755 async-toolkit/jtools/cad/lve/script/perl/raw2db.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/rc_spice2aspice create mode 100755 async-toolkit/jtools/cad/lve/script/perl/recursive_graybox create mode 100755 async-toolkit/jtools/cad/lve/script/perl/rehierverilog.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/remote/lve_pmc create mode 100755 async-toolkit/jtools/cad/lve/script/perl/remote/pmc_jobcancel.sh create mode 100755 async-toolkit/jtools/cad/lve/script/perl/remote/pmc_jobsubmit.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/rte_summarize.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/run_cmm.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/run_totem.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/runincdswd.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/shmoo create mode 100755 async-toolkit/jtools/cad/lve/script/perl/signoff_check create mode 100755 async-toolkit/jtools/cad/lve/script/perl/snarf create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spefrename.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/extractCDC.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/extract_starRC.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/hlvs.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/hlvsrename.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/hsim.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/parse_hlvs.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/spice2spice.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/spice/spice_reduce.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/splitcast.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/splitfill.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/tapeout create mode 100755 async-toolkit/jtools/cad/lve/script/perl/tcam/tcam_aplot create mode 100755 async-toolkit/jtools/cad/lve/script/perl/tcam/tcam_cap create mode 100755 async-toolkit/jtools/cad/lve/script/perl/tcam/tcam_lib create mode 100755 async-toolkit/jtools/cad/lve/script/perl/tcam/tcam_todo create mode 100755 async-toolkit/jtools/cad/lve/script/perl/tracescan.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/update_delay_and_cap create mode 100755 async-toolkit/jtools/cad/lve/script/perl/vstorm create mode 100755 async-toolkit/jtools/cad/lve/script/perl/vstorm_async create mode 100755 async-toolkit/jtools/cad/lve/script/perl/wirelen.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/wrapspec.pl create mode 100755 async-toolkit/jtools/cad/lve/script/perl/wwc_tcam/rename_aplot create mode 100755 async-toolkit/jtools/cad/lve/script/perl/wwc_tcam/run_all create mode 100755 async-toolkit/jtools/cad/lve/script/perl/wwc_tcam/run_tcam create mode 100755 async-toolkit/jtools/cad/lve/script/perl/wwc_tcam/tcam_lib create mode 100755 async-toolkit/jtools/cad/lve/script/perl/wwc_tcam/write_tcam_init create mode 100644 async-toolkit/jtools/cad/lve/script/php/index.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/alint.php create mode 120000 async-toolkit/jtools/cad/lve/scripts/php/antenna.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/aspice.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/asta.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/bumps.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/cell.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/common.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/commonSC.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/commonnm28.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/delays.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/dag.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/data_mining.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/directives.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/faq.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/hackers.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/index.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/logo.png create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/lve.css create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/lve.png create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/resources.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/table.css create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/updatenetlist/calls.dot create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/doc/updatenetlist/index.html create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/em.php create mode 120000 async-toolkit/jtools/cad/lve/scripts/php/extract.php create mode 120000 async-toolkit/jtools/cad/lve/scripts/php/frc.php create mode 100755 async-toolkit/jtools/cad/lve/scripts/php/getlvedirs.pl create mode 100755 async-toolkit/jtools/cad/lve/scripts/php/getlvedirsSC.pl create mode 120000 async-toolkit/jtools/cad/lve/scripts/php/hdrc.php create mode 120000 async-toolkit/jtools/cad/lve/scripts/php/hlvs.php create mode 120000 async-toolkit/jtools/cad/lve/scripts/php/hsim.php create mode 120000 async-toolkit/jtools/cad/lve/scripts/php/hspice.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/index.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/jlvs.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/leakage.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/lib.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/libdelays.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/lve.css create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/lvedirs.txt create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/newbumps.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/rte.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/rteSummary.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/site.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/siteSC.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/sitenm28.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/slint.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/statistics.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/table.css create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/totem.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/unzip.php create mode 100644 async-toolkit/jtools/cad/lve/scripts/php/xa.php create mode 100644 async-toolkit/jtools/cad/perl/perlmod/Cast/JavaServer.pm create mode 100644 async-toolkit/jtools/cad/perl/perlmod/Cast/NodeAliasing.pm create mode 100755 async-toolkit/jtools/cad/perl/perlmod/Cast/QA/TestNodeAliasing.pl create mode 100644 async-toolkit/jtools/cad/perl/perlmod/Cast/SourceControl.pm create mode 100644 async-toolkit/jtools/cad/perl/perlmod/Util/Numeric.pm create mode 100755 async-toolkit/jtools/cad/scripts/apply_fixes create mode 100755 async-toolkit/jtools/cad/scripts/cad_bin_install create mode 100755 async-toolkit/jtools/cad/scripts/captally create mode 100755 async-toolkit/jtools/cad/scripts/cast_signoff_report create mode 100755 async-toolkit/jtools/cad/scripts/cdl2dot create mode 100644 async-toolkit/jtools/cad/scripts/charge_sharing_postprocess create mode 100755 async-toolkit/jtools/cad/scripts/charge_sharing_report create mode 100755 async-toolkit/jtools/cad/scripts/check_hierarchy.pl create mode 100755 async-toolkit/jtools/cad/scripts/compile_lib.sh create mode 100644 async-toolkit/jtools/cad/scripts/custom.mk create mode 100755 async-toolkit/jtools/cad/scripts/df2instances create mode 100755 async-toolkit/jtools/cad/scripts/doc_utils/serialtree2ps.pl create mode 100755 async-toolkit/jtools/cad/scripts/fix_charge_sharing create mode 100755 async-toolkit/jtools/cad/scripts/graph_netlist create mode 100644 async-toolkit/jtools/cad/scripts/graph_netlist.inc create mode 100755 async-toolkit/jtools/cad/scripts/group_members create mode 100755 async-toolkit/jtools/cad/scripts/html_diff create mode 100755 async-toolkit/jtools/cad/scripts/install_scripts create mode 100755 async-toolkit/jtools/cad/scripts/integrate_views create mode 100644 async-toolkit/jtools/cad/scripts/layout_spice create mode 100755 async-toolkit/jtools/cad/scripts/layout_spice_stuff/call_spice.scr create mode 100755 async-toolkit/jtools/cad/scripts/layout_spice_stuff/change_char2spice.scr create mode 100755 async-toolkit/jtools/cad/scripts/layout_spice_stuff/chrg_shr_post_processing.scr create mode 100755 async-toolkit/jtools/cad/scripts/layout_spice_stuff/hsim_tds.scr create mode 100755 async-toolkit/jtools/cad/scripts/layout_spice_stuff/post_process_tds.scr create mode 100755 async-toolkit/jtools/cad/scripts/ldg/Graph.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/LDGUtils.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Cells.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Dbaccess.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Errorcodes.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Filter.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Flows.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Libraries.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Locks.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Projects.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Session.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Socket.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Sort.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Tests.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Ldgd/Users.pm create mode 100644 async-toolkit/jtools/cad/scripts/ldg/Msg.pm create mode 100755 async-toolkit/jtools/cad/scripts/ldg/basic_client.pl create mode 100644 async-toolkit/jtools/cad/scripts/ldg/clean_db create mode 100755 async-toolkit/jtools/cad/scripts/ldg/find_cell.pl create mode 100755 async-toolkit/jtools/cad/scripts/ldg/get_parents.pl create mode 100755 async-toolkit/jtools/cad/scripts/ldg/ldg_layout_client.pl create mode 100755 async-toolkit/jtools/cad/scripts/ldg/ldg_p4_review.pl create mode 100755 async-toolkit/jtools/cad/scripts/ldg/ldg_verify_client.pl create mode 100755 async-toolkit/jtools/cad/scripts/ldg/ldgd.pl create mode 100755 async-toolkit/jtools/cad/scripts/ldg/sql.pl create mode 100644 async-toolkit/jtools/cad/scripts/lib/CadenceLib.pm create mode 100644 async-toolkit/jtools/cad/scripts/lib/CastLib.pm create mode 100644 async-toolkit/jtools/cad/scripts/lib/CastParser.pm create mode 100644 async-toolkit/jtools/cad/scripts/lib/CastParserLib.pm create mode 100755 async-toolkit/jtools/cad/scripts/license/checklic.pl create mode 100755 async-toolkit/jtools/cad/scripts/lmusage create mode 100755 async-toolkit/jtools/cad/scripts/measure create mode 100755 async-toolkit/jtools/cad/scripts/minmaxv create mode 100755 async-toolkit/jtools/cad/scripts/mk_instance create mode 100755 async-toolkit/jtools/cad/scripts/p2n create mode 100755 async-toolkit/jtools/cad/scripts/p4_html_diff create mode 100755 async-toolkit/jtools/cad/scripts/postlayout create mode 100755 async-toolkit/jtools/cad/scripts/power_grid_sag create mode 100644 async-toolkit/jtools/cad/scripts/progfiles-custom.mk create mode 100755 async-toolkit/jtools/cad/scripts/r4 create mode 100755 async-toolkit/jtools/cad/scripts/rc_spice2aspice create mode 100644 async-toolkit/jtools/cad/scripts/rescuedb.c create mode 100755 async-toolkit/jtools/cad/scripts/rtlwait create mode 100755 async-toolkit/jtools/cad/scripts/spec_stats create mode 100755 async-toolkit/jtools/cad/scripts/spice create mode 100755 async-toolkit/jtools/cad/scripts/spice2spice create mode 100755 async-toolkit/jtools/cad/scripts/spice_batch create mode 100755 async-toolkit/jtools/cad/scripts/spice_new create mode 100755 async-toolkit/jtools/cad/scripts/support/bugmonitor create mode 100755 async-toolkit/jtools/cad/scripts/support/bugproduct create mode 100755 async-toolkit/jtools/cad/scripts/support/bugzillauser create mode 100755 async-toolkit/jtools/cad/scripts/support/caljul create mode 100755 async-toolkit/jtools/cad/scripts/support/cwd create mode 100755 async-toolkit/jtools/cad/scripts/support/date2time create mode 100755 async-toolkit/jtools/cad/scripts/support/date2time.pm create mode 100755 async-toolkit/jtools/cad/scripts/support/drawlef create mode 100755 async-toolkit/jtools/cad/scripts/support/gds2strings create mode 100755 async-toolkit/jtools/cad/scripts/support/genconfig.pl create mode 100755 async-toolkit/jtools/cad/scripts/support/getquo create mode 100755 async-toolkit/jtools/cad/scripts/support/getquoa create mode 100755 async-toolkit/jtools/cad/scripts/support/getquob create mode 100755 async-toolkit/jtools/cad/scripts/support/getquoh create mode 100755 async-toolkit/jtools/cad/scripts/support/getquol create mode 100755 async-toolkit/jtools/cad/scripts/support/getquos create mode 100755 async-toolkit/jtools/cad/scripts/support/getquot create mode 100755 async-toolkit/jtools/cad/scripts/support/gettmp.sh create mode 100755 async-toolkit/jtools/cad/scripts/support/graph create mode 100755 async-toolkit/jtools/cad/scripts/support/hencrypt create mode 100755 async-toolkit/jtools/cad/scripts/support/julian.pl create mode 100755 async-toolkit/jtools/cad/scripts/support/lmgraph create mode 100755 async-toolkit/jtools/cad/scripts/support/longlines create mode 100755 async-toolkit/jtools/cad/scripts/support/maxlen create mode 100755 async-toolkit/jtools/cad/scripts/support/myqs create mode 100755 async-toolkit/jtools/cad/scripts/support/p4monitor create mode 100755 async-toolkit/jtools/cad/scripts/support/p5check create mode 100755 async-toolkit/jtools/cad/scripts/support/qacc create mode 100755 async-toolkit/jtools/cad/scripts/support/qresource create mode 100755 async-toolkit/jtools/cad/scripts/support/qtrace create mode 100755 async-toolkit/jtools/cad/scripts/support/quotacmp create mode 100755 async-toolkit/jtools/cad/scripts/support/quotagraph create mode 100755 async-toolkit/jtools/cad/scripts/support/s2aplt create mode 100755 async-toolkit/jtools/cad/scripts/support/s2iplt create mode 100644 async-toolkit/jtools/cad/scripts/support/support.package create mode 100755 async-toolkit/jtools/cad/scripts/support/tgraph create mode 100755 async-toolkit/jtools/cad/scripts/support/time2date create mode 100755 async-toolkit/jtools/cad/scripts/support/unwrap create mode 100755 async-toolkit/jtools/cad/scripts/support/userinfo create mode 100755 async-toolkit/jtools/cad/scripts/support/wide create mode 100755 async-toolkit/jtools/cad/scripts/synthesis/add_rough_power.pl create mode 100755 async-toolkit/jtools/cad/scripts/synthesis/custom.config create mode 100755 async-toolkit/jtools/cad/scripts/synthesis/sizing.pl create mode 100755 async-toolkit/jtools/cad/scripts/tidier create mode 100644 async-toolkit/jtools/cad/scripts/time_domain_postprocess create mode 100755 async-toolkit/jtools/cad/scripts/trace_deriv create mode 100644 async-toolkit/jtools/cad/ubersize/javafiles-custom.mk create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Perforce.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/DensityFactor.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/FileIO.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/FulcrumIntegration.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/JavaUtil.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/LayoutIntegration.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/LayoutModeling.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/MergeLibrary.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/Merging.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/Misc.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/ModifySubtypes.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/Netlist.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/PerforceIntegration.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/PostLayout.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/Sizing.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/SizingDebug.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/SizingDrop.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/SubtypeSpace.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/TypeOps.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/TypeUtil.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/Unmerging.pm create mode 100644 async-toolkit/jtools/cad/ubersize/lib/perl/Supersize/Util.pm create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/cast2sync.pl create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/cells2html create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/check_cutoff create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/compare_cells create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/compare_sizes create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/compile_cdc.pl create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/floorplan_init create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/generate_sdcinfo.pl create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/mkdefaultlib.pl create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/supersize create mode 100755 async-toolkit/jtools/cad/ubersize/script/perl/ubersize create mode 100644 async-toolkit/jtools/cad/ubersize/ubersize.package create mode 100644 async-toolkit/jtools/infrastructure/build-and-test-scripts/build-and-test.package create mode 100755 async-toolkit/jtools/infrastructure/build-and-test-scripts/buildandtestfromp4.sh create mode 100755 async-toolkit/jtools/infrastructure/build-and-test-scripts/buildfromsource.sh create mode 100755 async-toolkit/jtools/infrastructure/build-and-test-scripts/gdsII/gdsII2xml.pl create mode 100755 async-toolkit/jtools/infrastructure/build-and-test-scripts/runmake.sh create mode 100755 async-toolkit/jtools/infrastructure/build-and-test-scripts/runtestsfromsource.sh create mode 100755 async-toolkit/jtools/infrastructure/build-and-test-scripts/util/p4/clientroot.sh create mode 100755 async-toolkit/jtools/infrastructure/build-and-test-scripts/util/p4/map_depot_to_disk.sh create mode 100644 async-toolkit/jtools/infrastructure/build-system/Makefile create mode 100644 async-toolkit/jtools/infrastructure/build-system/System.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/bin/antlr-2.7.2 create mode 100644 async-toolkit/jtools/infrastructure/build-system/build-system.package create mode 100644 async-toolkit/jtools/infrastructure/build-system/calc_sub_dirs_info.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/calc_sub_target_mk_include_info.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/commands.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/cononicalizepath.zsh create mode 100644 async-toolkit/jtools/infrastructure/build-system/custom.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/defaults.clean.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/defaults.common.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/defaults.dir.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/defaults.mk.gen create mode 100644 async-toolkit/jtools/infrastructure/build-system/defaults.mk.tmpl create mode 100644 async-toolkit/jtools/infrastructure/build-system/defaults.subincludes.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/dir_exit.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/doc/index.html create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/antlrfiles/mkantlrrules.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/castfiles/annotatecond create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/castfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/castfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/castfiles/env.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/castfiles/getcellname create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/castfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/castfiles/slurp_cell_view.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/cdbdep.sh create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/cdbdiff.pl create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/cdbdiff.sh create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/dirout.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/drcdep.sh create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/mysql_status create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cdbfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cppfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cppfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/cppfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/dotfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/dotfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/dotfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/BuildIdentifier.template create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/dirout.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/jarcombine.sh create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/java2package create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/javadep.sh create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/mkTopLevelJava.pl create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/javafiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/libfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/libfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/libfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/packagingfiles/dir.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/packagingfiles/mkpackage.pl create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/packagingfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/progfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/progfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/progfiles/mklinkrule.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/progfiles/mksolinkrule.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/progfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/pyfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/pyfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/pyfiles/once.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/texfiles/dir.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/texfiles/dirout.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/filetypes/texfiles/once.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/filetypes/texfiles/texdep.zsh create mode 100644 async-toolkit/jtools/infrastructure/build-system/functions.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/generatedir.zsh create mode 100644 async-toolkit/jtools/infrastructure/build-system/include-functions/linkprogram.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/include-functions/popscopedvar.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/include-functions/pushscopedvar.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/infrastructure.mk create mode 100755 async-toolkit/jtools/infrastructure/build-system/runindir.bash create mode 100755 async-toolkit/jtools/infrastructure/build-system/safemkdir.zsh create mode 100755 async-toolkit/jtools/infrastructure/build-system/subdir.mk.gen create mode 100644 async-toolkit/jtools/infrastructure/build-system/systems/romulite.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/systemtypes/Linux-i686.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/systemtypes/Linux-x86_64.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/systemtypes/SunOS-sun4u.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/systemtypes/default.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/tools/autodep/autodep-0.2.1-fulcrum.tar.gz create mode 100644 async-toolkit/jtools/infrastructure/build-system/tools/autodep/rules.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/tools/autodep/vars.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/var_reset.mk create mode 100644 async-toolkit/jtools/infrastructure/build-system/vortexfiles.mk create mode 100644 async-toolkit/jtools/infrastructure/java/Makefile create mode 100755 async-toolkit/jtools/infrastructure/java/scripts/compute_class_path create mode 100755 async-toolkit/jtools/infrastructure/java/scripts/make_obfuscated_jar.pl create mode 100755 async-toolkit/jtools/infrastructure/java/scripts/make_subdir_makefile create mode 100755 async-toolkit/jtools/infrastructure/java/scripts/unkeyword.pl create mode 100644 async-toolkit/jtools/infrastructure/java/util/cmdline/ArgProcessingInterface.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/cmdline/CommandLineIterator.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/cmdline/PropCommandLineIterator.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/cmdline/PropertyArg.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/misc/JepMathExpressionParser.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/misc/Utility.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/BadPropertyException.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/ExpansionErrorException.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/MalformedSubstException.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/PropCommandLineParser.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/PropConfigFileParser.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/PropConfigParserException.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/PropReader.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/PropReaderInterface.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/SubstExpr.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/TypeErrorException.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/common.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/options.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0001.args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0001.expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0001.test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0002.expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0002.test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0003.expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0003.test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0003.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0004.args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0004.expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0004.test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0004.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0005/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0005/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0005/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0006/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0006/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0006/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0007/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0007/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0007/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0008/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0008/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0008/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0009/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0009/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0009/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0010/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0010/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0010/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0010/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0011/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0011/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0011/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0011/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0012/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0012/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0012/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0012/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0013/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0013/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0013/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0013/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0014/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0014/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0015/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0015/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0015/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0016/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0016/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0016/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0016/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0018/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0018/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0018/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0019/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0019/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0019/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0020/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0020/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0020/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0021/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0021/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0021/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0021/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0022/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0022/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0022/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0022/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0023/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0023/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0023/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0024/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0024/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0024/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0025/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0025/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0025/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0026/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0026/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0026/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0027/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0027/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0027/t.xml create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0027/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0028/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0028/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0028/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0029/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0029/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0029/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0030/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0030/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0030/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0031/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0031/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0031/test create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0032/args create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0032/expected create mode 100644 async-toolkit/jtools/infrastructure/java/util/properties/testcases/t0032/test create mode 100755 async-toolkit/jtools/infrastructure/java/util/properties/testcases/test.pl create mode 100644 async-toolkit/jtools/infrastructure/java/util/xml/TestplanCompiler.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/xml/XmlPropFileHandler.java create mode 100644 async-toolkit/jtools/infrastructure/java/util/xml/XmlUtils.java create mode 100755 async-toolkit/jtools/infrastructure/p4-triggers/build/triggerbuild.sh create mode 100755 async-toolkit/jtools/infrastructure/p4-triggers/install.sh create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/p4-triggers.package create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/custom.mk.template create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/someonefixedthebuildyoubroke.txt create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/theydidnotfixthebuild.txt create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/youbrokethebuild.txt create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/youdidnotfixthebuild.txt create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/youdidnotfixthebuildyoubroke.txt create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/youfixedthebuild.txt create mode 100644 async-toolkit/jtools/infrastructure/p4-triggers/templates/youfixedthebuildyoubroke.txt create mode 100755 async-toolkit/jtools/infrastructure/p4-triggers/triggers/cad.trigger.sh create mode 100755 async-toolkit/jtools/infrastructure/p4-triggers/util/handlechange.sh create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/developer.csh create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/fulcrumscript.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/index.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/plan.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/proposal.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/releasedoc.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/20040326225224_GB13623.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/20040326231021_GC13623.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/40628713_5050907.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/40631371_204.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/4064B681_6060601.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/4064BA26_9070309.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/4064BD7E_7000004.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/40652849_6020503.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/40652AD3_8060006.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/40652FE2_3070305.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/406845C8_9070905.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/doc/thread/index.html create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/.beta create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/.itools create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/.latest create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/.proteusbeta create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/.release create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/buildcron.tcsh create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/buildfull.pl create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/chkfmdb.pl create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/chkpref create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/chkrel create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/donotbuild_fedora-x86_64.txt create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/donotbuild_fedora.txt create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/donotbuild_solaris8.txt create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/fulcrum.pl create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/fulcrum.whatis create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/layout.txt create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/listfmdb.pl create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/package-inst.pl create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/preferred.txt create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/proteusbeta.txt create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/release.txt create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/releasef64.txt create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/releasepdk.txt create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/releases8.txt create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/tb-install.pl create mode 100644 async-toolkit/jtools/infrastructure/release-system/scripts/tbdev.txt create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/trigger.pl create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/triggerd.pl create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/update2latest create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/updateall.pl create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/updatefmdb.pl create mode 100755 async-toolkit/jtools/infrastructure/release-system/scripts/updaterelease.pl create mode 100755 async-toolkit/jtools/infrastructure/sh-lib/file/config.sh create mode 100755 async-toolkit/jtools/infrastructure/sh-lib/file/conon.sh create mode 100755 async-toolkit/jtools/infrastructure/sh-lib/file/filecheck.sh create mode 100755 async-toolkit/jtools/infrastructure/sh-lib/script/generate_script_with_libs.sh create mode 100644 async-toolkit/jtools/infrastructure/sh-lib/sh-lib.package.inc diff --git a/async-toolkit/jtools/cad/all/all.package b/async-toolkit/jtools/cad/all/all.package new file mode 100644 index 0000000000..82a61d69de --- /dev/null +++ b/async-toolkit/jtools/cad/all/all.package @@ -0,0 +1,37 @@ +1 1 +include ../ubersize/ubersize.package ../ubersize +include ../proteus/proteus.package ../proteus +include ../lad_quake/lad_quake.inc ../lad_quake +include ../lve/lve.package ../lve +include ../java/src/com/avlsi/tools/synthesis/synthesis.package ../java/src/com/avlsi/tools/synthesis +include ../java/src/com/avlsi/tools/slacker/slacker.package ../java/src/com/avlsi/tools/slacker +include ../java/src/com/avlsi/tools/rte/rte.package ../java/src/com/avlsi/tools/rte +include ../java/src/com/avlsi/tools/prs2verilog/prs2verilog.package ../java/src/com/avlsi/tools/prs2verilog +include ../java/src/com/avlsi/tools/presto/presto.package ../java/src/com/avlsi/tools/presto +include ../java/src/com/avlsi/tools/dsim/dsim.package ../java/src/com/avlsi/tools/dsim +include ../java/src/com/avlsi/tools/cast2verilog/cast2verilog.package ../java/src/com/avlsi/tools/cast2verilog +include ../external-tools-integration/cadence/virtuoso/virtuoso-integration.package ../external-tools-integration/cadence/virtuoso +include ../c/gdsii/gdsii.package ../c/gdsii +include ../scripts/support/support.package ../scripts/support +share/java/Jama-1.0.2.jar ../java/jars/Jama-1.0.2.jar 640 p +share/java/antlr-2.7.2.jar ../java/jars/antlr-2.7.2.jar 640 p +share/java/antlrall-2.7.1.jar ../java/jars/antlrall-2.7.1.jar 640 p +share/java/bcel-5.0.jar ../java/jars/bcel-5.0.jar 640 p +share/java/ccl-20.40.jar ../java/jars/ccl-20.40.jar 640 p +share/java/concurrent-1.3.1.jar ../java/jars/concurrent-1.3.1.jar 640 p +share/java/javancss-20.40.jar ../java/jars/javancss-20.40.jar 640 p +share/java/jcsp-net.jar ../java/jars/jcsp-net.jar 640 p +share/java/jcsp-std.jar ../java/jars/jcsp-std.jar 640 p +share/java/jml-release-3.2.jar ../java/jars/jml-release-3.2.jar 640 p +share/java/jmljunitruntime-3.2.jar ../java/jars/jmljunitruntime-3.2.jar 640 p +share/java/jmlruntime-3.2.jar ../java/jars/jmlruntime-3.2.jar 640 p +share/java/junit-3.7.jar ../java/jars/junit-3.7.jar 640 p +share/java/log4j-1.2.5.jar ../java/jars/log4j-1.2.5.jar 640 p +share/java/mjc-for-jml-3.2.jar ../java/jars/mjc-for-jml-3.2.jar 640 p +share/java/concurrent.jar ../java/jars/concurrent.jar 640 p +share/java/jdom.jar ../java/jars/jdom.jar 640 p +share/java/resolver.jar ../java/jars/resolver.jar 640 p +share/java/stringtemplate.jar ../java/jars/stringtemplate.jar 640 p +share/java/tools.jar ../java/jars/tools.jar 640 p +share/java/xercesImpl.jar ../java/jars/xercesImpl.jar 640 p +share/java/xml-apis.jar ../java/jars/xml-apis.jar 640 p diff --git a/async-toolkit/jtools/cad/all/javafiles-custom.mk b/async-toolkit/jtools/cad/all/javafiles-custom.mk new file mode 100644 index 0000000000..e665884a59 --- /dev/null +++ b/async-toolkit/jtools/cad/all/javafiles-custom.mk @@ -0,0 +1,23 @@ +# Copyright 2003 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/javafiles-custom.mk#2 $ +# $DateTime: 2003/03/18 20:53:51 $ +# $Author: chrisb $ + +VIRTUOSO_CURR_TARGET_DIR_TEMP := $(CURR_TARGET_DIR) +VIRTUOSO_CURR_PROJECT_DIR_TEMP := $(CURR_PROJECT_DIR) + +CURR_TARGET_DIR := $(call CONONICALIZE_PATH, $(CURR_TARGET_DIR)/../java/src) +CURR_PROJECT_DIR := $(call CONONICALIZE_PATH, $(CURR_PROJECT_DIR)/../java/src) + +include $(VIRTUOSO_CURR_PROJECT_DIR_TEMP)/../java/src/javafiles-custom.mk + +CURR_TARGET_DIR := $(VIRTUOSO_CURR_TARGET_DIR_TEMP) +CURR_PROJECT_DIR := $(VIRTUOSO_CURR_PROJECT_DIR_TEMP) + +JAVAFILES_CLASSES_SRC_ROOT := $(call CONONICALIZE_PATH, $(CURR_PROJECT_DIR)/../java/src) +JAVAFILES_CLASSES_JAR_ROOT := $(call CONONICALIZE_PATH, $(CURR_PROJECT_DIR)/../java/jars) +JAVAFILES_CLASSES_CACHE_ROOT := $(call CONONICALIZE_PATH, $(CURR_TARGET_DIR)/classcache) +JAVAFILES_JAVADOC_SOURCE_PATH := $(call CONONICALIZE_PATH, $(CURR_PROJECT_DIR)/../java/src) + +JAVAFILES_PARSERS_USED := $(JAVAFILES_PARSERS_USED) \ + $(call CONONICALIZE_PATH, $(CURR_TARGET_DIR)/../java/src/com/avlsi/tools/jauto/CastQueryParser) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/assura.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/assura.package new file mode 100644 index 0000000000..bdc2f3e277 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/assura.package @@ -0,0 +1,14 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +include script/perl/ve/ve.package script/perl/ve ^share->share/script/perl/ve + +share/skill/layout/geometry/rect.il skill/layout/geometry/rect.il 664 p +share/skill/layout/assura/assura.il skill/layout/assura/assura.il 664 p +share/skill/util/list/list.il skill/util/list/list.il 664 p +share/skill/util/lib.il skill/util/lib.il 664 p +share/skill/schematic/updatenetlist.il skill/schematic/updatenetlist.il 664 p +share/skill/util/string/strutil.il skill/util/string/strutil.il 664 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/cdsp4.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/cdsp4.package new file mode 100644 index 0000000000..fddc747d04 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/cdsp4.package @@ -0,0 +1,20 @@ +2 2 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +### perforce integration for cadence /command line usage +# See Documentation + +$arch/bin/cdsp4.sh script/sh/p4/cdsp4.sh 775 p +$arch/bin/cdsp4add.sh script/sh/p4/cdsp4add.sh 775 p +$arch/bin/cdsp4delete.sh script/sh/p4/cdsp4delete.sh 775 p +$arch/bin/cdsp4edit.sh script/sh/p4/cdsp4edit.sh 775 p +$arch/bin/cdsp4sync.sh script/sh/p4/cdsp4sync.sh 775 p +$arch/bin/cdsp4submit.sh script/sh/p4/cdsp4submit.sh 775 p +$arch/bin/cdsp4revert.sh script/sh/p4/cdsp4revert.sh 775 p +$arch/bin/cdsp4celllog.sh script/sh/p4/cdsp4celllog.sh 775 p +$arch/bin/cdsp4addlibs.sh script/sh/p4/cdsp4addlibs.sh 775 p +$arch/bin/cdsp4smartedit.sh script/sh/p4/cdsp4smartedit.sh 775 p +$arch/bin/cdsp4opened.sh script/sh/p4/cdsp4opened.sh 775 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/dfII_split_subtypes.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/dfII_split_subtypes.package new file mode 100644 index 0000000000..068ebf7fbe --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/dfII_split_subtypes.package @@ -0,0 +1,17 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# This package contains scripts for creating splitting subtypes in dfII +# from subtype spec files + +# see this file for documentation of the spec file format +$arch/bin/dfII_split_subtypes.sh script/sh/subtyping/dfII_split_subtypes.sh 775 p + +share/script/sh/sh-lib/file/filecheck.sh ../../../../infrastructure/sh-lib/file/filecheck.sh 775 p +share/script/sh/sh-lib/file/conon.sh ../../../../infrastructure/sh-lib/file/conon.sh 775 p +share/script/sh/sh-lib/script/generate_script_with_libs.sh ../../../../infrastructure/sh-lib/script/generate_script_with_libs.sh 775 p +share/script/sh/util/parsecellname script/sh/util/parsecellname 775 p +share/script/sh/cell-automation/lib_commands/mkcdslib script/sh/cell-automation/lib_commands/mkcdslib 775 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/calls.dot b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/calls.dot new file mode 100644 index 0000000000..069c517caf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/calls.dot @@ -0,0 +1,138 @@ +/* + $Id$ + $DateTime$ + $Author$ + Copyright 2003 Fulcrum Microsystems + All Rights Reserved. + + +*/ + +digraph callGraph { + + ratio=fill; + size="10,7.5"; + rotate=90; + +shellScript[label="updatenetlist shell script"]; +shellScript->UpdateNetlistCompareCellsToSkillNetlistsInToFileUsingPDKInfo; +UpdateNetlistCompareCellsToSkillNetlistsInToFileUsingPDKInfo->UpdateNetlistCompareCellsToSkillNetlists; + UpdateNetlistCompareCellsToSkillNetlists->UpdateNetlistCompareCellViewsToSkillNetlist; + UpdateNetlistCompareCellViewsToSkillNetlist->UpdateNetlistCompareCellViews; + UpdateNetlistCompareCellViews->UpdateNetlistGetSkillNetlistGetInstanceTripplesFunc [label="ConnectivityGetInstanceTripplesFunc"]; + UpdateNetlistGetSkillNetlistGetInstanceTripplesFunc->NetlistTableGetInstanceTripples; + UpdateNetlistCompareCellViews->UpdateNetlistGetSkillNetlistGetTerminalNamesFunc [label="ConnectivityGetTerminalNamesFunc"]; + UpdateNetlistGetSkillNetlistGetTerminalNamesFunc->NetlistTableGetTerminalNames; + UpdateNetlistCompareCellViews->UpdateNetlistCompareCellView; + UpdateNetlistCompareCellView->UpdateNetlistCompareCellInstances; + UpdateNetlistCompareCellInstances->UpdateNetlistGetInstancesToDelete; + UpdateNetlistGetInstancesToDelete->UpdateNetlistGetSkillNetlistInstanceExistsFunc [label="ConnectivityInstanceExistsFunc"]; + UpdateNetlistGetSkillNetlistInstanceExistsFunc->NetlistTableGetInstance; + UpdateNetlistCompareCellInstances->UpdateNetlistGetInstancesToChange; + UpdateNetlistGetInstancesToChange->UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc [label="ConnectivityGetInstanceMasterLibNameFunc" ]; + UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc->NetlistTableGetInstanceInNetlistMasterLibName; + UpdateNetlistGetInstancesToChange->UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc [label="ConnectivityGetInstanceMasterCellNameFunc" ]; + UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc->NetlistTableGetInstanceInNetlistMasterCellName; + UpdateNetlistGetInstancesToChange->UpdateNetlistGetDefaultGetInstanceTransformFunc [label="ConnectivityGetInstanceTransformFunc"]; + UpdateNetlistGetDefaultGetInstanceTransformFunc->UpdateNetlistGetNullGetInstanceTransformFunc [label="FunctionTable[NetlistViewName]"]; + UpdateNetlistGetDefaultGetInstanceTransformFunc->UpdateNetlistGetNullGetInstanceTransformFunc [label="FunctionTable[LayoutViewName]"]; + UpdateNetlistGetDefaultGetInstanceTransformFunc->UpdateNetlistGetDefaultGetFloorplanInstanceTransformFunc [label="FunctionTable[FloorplanViewName]"]; + UpdateNetlistCompareCellInstances->UpdateNetlistGetInstancesToCreate; + UpdateNetlistGetInstancesToCreate->UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc [label="ConnectivityGetInstanceMasterLibNameFunc" ]; + UpdateNetlistGetInstancesToCreate->UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc [label="ConnectivityGetInstanceMasterCellNameFunc" ]; + UpdateNetlistGetInstancesToCreate->UpdateNetlistGetDefaultGetInstanceTransformFunc [label="ConnectivityGetInstanceTransformFunc"]; + UpdateNetlistCompareCellInstances->UpdateNetlistGetInstancesToFix; + UpdateNetlistCompareCellInstances->UpdateNetlistGetInstanceParametersToSet; + UpdateNetlistGetInstanceParametersToSet->UpdateNetlistGetSkillNetlistGetInstanceParameterPairsFunc [ label="ConnectivityGetInstanceParameterPairsFunc" ]; + UpdateNetlistGetSkillNetlistGetInstanceParameterPairsFunc->NetlistTableGetInstanceInNetlistParametersPairs; + UpdateNetlistCompareCellView->UpdateNetlistCompareCellConnectivity; + UpdateNetlistCompareCellConnectivity->UpdateNetlistGetConnectionsToDelete; + UpdateNetlistGetConnectionsToDelete->UpdateNetlistGetSkillNetlistInstanceHasConnectionFunc [ label="ConnectivityInstanceHasConnectionFunc" ]; + UpdateNetlistGetSkillNetlistInstanceHasConnectionFunc->NetlistTableGetNetNameForInstanceInNetlistTerminalName; + UpdateNetlistCompareCellConnectivity->UpdateNetlistGetConnectionsToCreate; + UpdateNetlistGetConnectionsToCreate->UpdateNetlistGetSkillNetlistGetInstanceConnectionsFunc [ label="ConnectivityGetInstanceConnectionsFunc" ]; + UpdateNetlistGetSkillNetlistGetInstanceConnectionsFunc->NetlistTableGetInstanceInNetlistConnectionPairs; + UpdateNetlistCompareCellConnectivity->UpdateNetlistGetTerminalsToDelete; + UpdateNetlistGetTerminalsToDelete->UpdateNetlistGetSkillNetlistTerminalExistsFunc [ label="ConnectivityTerminalExistsFunc" ]; + UpdateNetlistGetSkillNetlistTerminalExistsFunc->NetlistTableTerminalExists; + UpdateNetlistCompareCellConnectivity->UpdateNetlistGetTerminalsToCreate; + UpdateNetlistCompareCellConnectivity->UpdateNetlistGetNetsToDelete; + UpdateNetlistGetNetsToDelete->UpdateNetlistGetSkillNetlistNetExistsFunc [ label="ConnectivityNetExistsFunc" ]; + UpdateNetlistGetSkillNetlistNetExistsFunc->NetlistTableNetExists; + UpdateNetlistCompareCellConnectivity->UpdateNetlistGetNetsToCreate; + UpdateNetlistCompareCellConnectivity->UpdateNetlistGetNetsToChange; + UpdateNetlistGetNetsToChange->UpdateNetListGetSkillGetNetlistNetWireSpacingFunc [ label="ConnectivityGetNetWireSpacingFunc" ]; + UpdateNetListGetSkillGetNetlistNetWireSpacingFunc->CellInfoGetNetWireSpacingInMeters; + UpdateNetlistGetNetsToChange->UpdateNetListGetSkillGetNetlistNetWireWidthFunc [ label="ConnectivityGetNetWireWidthFunc" ]; + UpdateNetListGetSkillGetNetlistNetWireWidthFunc->CellInfoGetNetWireWidthInMeters; + UpdateNetlistCompareCellView->UpdateNetlistCompareCellBoundary; + UpdateNetlistCompareCellBoundary->UpdateNetlistGetSkillNetlistGetCellHeightFunc [ label="ConnectivityGetCellHeightFunc" ]; + UpdateNetlistGetSkillNetlistGetCellHeightFunc->UpdateNetlistGetDefaultGetCellHeightFunc [ label="GetCellHeightFunc" ]; + UpdateNetlistGetDefaultGetCellHeightFunc->UpdateNetlistGetDefaultGetNetlistViewHeightFunc [ label="FunctionTable[NetlistViewName]" ]; + UpdateNetlistGetDefaultGetCellHeightFunc->UpdateNetlistGetDefaultGetLayoutViewHeightFunc [ label="FunctionTable[LayoutViewName]" ]; + UpdateNetlistGetDefaultGetCellHeightFunc->UpdateNetlistGetDefaultGetFloorplanViewHeightFunc [ label="FunctionTable[FloorplanViewName]" ]; + UpdateNetlistCompareCellBoundary->UpdateNetlistGetSkillNetlistEstimateCellWidthFunc [ label="ConnectivityEstimateCellWidthFunc" ]; + UpdateNetlistGetSkillNetlistEstimateCellWidthFunc->UpdateNetlistGetDefaultGetCellWidthFunc [ label="EstimationFunc" ]; + UpdateNetlistGetDefaultGetCellWidthFunc->UpdateNetlistGetDefaultGetNetlistViewWidthFunc [ label="FunctionTable[NetlistViewName]" ]; + UpdateNetlistGetDefaultGetCellWidthFunc->UpdateNetlistGetDefaultGetLayoutViewWidthFunc [ label="FunctionTable[LayoutViewName]" ]; + UpdateNetlistGetDefaultGetCellWidthFunc->UpdateNetlistGetDefaultGetFloorplanViewHeightFunc [ label="FunctionTable[FloorplanViewName]" ]; + UpdateNetlistCompareCellBoundary->UpdateNetlistGetSkillNetlistEstimateCellPositionFunc [ label="ConnectivityGetBoundaryPositionFunc" ]; + UpdateNetlistGetSkillNetlistEstimateCellPositionFunc->UpdateNetlistGetDefaultGetCellPositionFunc [ label="EstimationFunc" ]; + UpdateNetlistGetDefaultGetCellPositionFunc->UpdateNetlistGetDefaultGetNetlistViewPositionFunc [ label="FunctionTable[NetlistViewName]" ]; + UpdateNetlistGetDefaultGetCellPositionFunc->UpdateNetlistGetDefaultGetLayoutViewPositionFunc [ label="FunctionTable[LayoutViewName]" ]; + UpdateNetlistGetDefaultGetCellPositionFunc->UpdateNetlistGetDefaultGetFloorplanViewHeightFunc [ label="FunctionTable[FloorplanViewName]" ]; + UpdateNetlistCompareCellView->UpdateNetlistComparePins; + UpdateNetlistComparePins->UpdateNetlistGetPinChangeFunc [ label="ConnectivityPinChangeFunc" ]; + UpdateNetlistCompareCellViews->UpdateNetlistCompareEmptyCellView; + UpdateNetlistCompareEmptyCellView->UpdateNetlistCompareEmptyCellInstances; + UpdateNetlistCompareEmptyCellInstances->UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc [label="ConnectivityGetInstanceMasterLibNameFunc" ]; + UpdateNetlistCompareEmptyCellInstances->UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc [label="ConnectivityGetInstanceMasterCellNameFunc" ]; + UpdateNetlistCompareEmptyCellInstances->UpdateNetlistGetDefaultGetInstanceTransformFunc [label="ConnectivityGetInstanceTransformFunc"]; + UpdateNetlistCompareEmptyCellInstances->UpdateNetlistGetSkillNetlistGetInstanceParameterPairsFunc [ label="ConnectivityGetInstanceParameterPairsFunc" ]; + UpdateNetlistCompareEmptyCellView->UpdateNetlistCompareEmptyCellConnectivity; + UpdateNetlistCompareEmptyCellConnectivity->UpdateNetlistGetConnectionsToCreate; + UpdateNetlistCompareEmptyCellView->UpdateNetlistCompareEmptyCellBoundary; + UpdateNetlistCompareEmptyCellBoundary->UpdateNetlistGetSkillNetlistGetCellHeightFunc [ label="ConnectivityGetCellHeightFunc" ]; + UpdateNetlistCompareEmptyCellBoundary->UpdateNetlistGetSkillNetlistEstimateCellWidthFunc [ label="ConnectivityEstimateCellWidthFunc" ]; + UpdateNetlistCompareEmptyCellBoundary->UpdateNetlistGetSkillNetlistEstimateCellPositionFunc [ label="ConnectivityGetBoundaryPositionFunc" ]; + UpdateNetlistCompareEmptyCellView->UpdateNetlistComparePins; + +shellScript->UpdateNetlistUpdateCellsFromSkillNetlistsToFileUsingPDKInfo; +UpdateNetlistUpdateCellsFromSkillNetlistsToFileUsingPDKInfo->UpdateNetlistCompareCellsToSkillNetlists; +UpdateNetlistUpdateCellsFromSkillNetlistsToFileUsingPDKInfo->UpdateNetlistGetErrorsFromCompareResults; +UpdateNetlistUpdateCellsFromSkillNetlistsToFileUsingPDKInfo->UpdateNetlistMakeWriteableCellViewTableFromCompareResults; +UpdateNetlistUpdateCellsFromSkillNetlistsToFileUsingPDKInfo->UpdateNetlistUpdateCellsFromCompareResultsToPort; + UpdateNetlistUpdateCellsFromCompareResultsToPort->UpdateNetlistUpdateCellsFromCompareResults; + UpdateNetlistUpdateCellsFromCompareResults->UpdateNetlistUpdateCellViewWithCompareResult; + +UpdateNetlistCompareCellBoundary[pos = "6604.725475,-216.273764"]; + +UpdateNetlistGetSkillNetlistGetInstanceTripplesFunc[shape=box]; +UpdateNetlistGetSkillNetlistGetTerminalNamesFunc[shape=box]; +UpdateNetlistGetSkillNetlistInstanceExistsFunc[shape=box]; +UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc[shape=box]; +UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc[shape=box]; +UpdateNetlistGetDefaultGetInstanceTransformFunc[shape=box]; +UpdateNetlistGetNullGetInstanceTransformFunc[shape=box]; +UpdateNetlistGetDefaultGetFloorplanInstanceTransformFunc[shape=box]; +UpdateNetlistGetSkillNetlistGetInstanceParameterPairsFunc[shape=box]; +UpdateNetlistGetSkillNetlistInstanceHasConnectionFunc[shape=box]; +UpdateNetlistGetSkillNetlistGetInstanceConnectionsFunc[shape=box]; +UpdateNetlistGetSkillNetlistTerminalExistsFunc[shape=box]; +UpdateNetlistGetSkillNetlistNetExistsFunc[shape=box]; +UpdateNetListGetSkillGetNetlistNetWireSpacingFunc[shape=box]; +UpdateNetListGetSkillGetNetlistNetWireWidthFunc[shape=box]; +UpdateNetlistGetSkillNetlistGetCellHeightFunc[shape=box]; +UpdateNetlistGetDefaultGetCellHeightFunc[shape=box]; +UpdateNetlistGetDefaultGetNetlistViewHeightFunc[shape=box]; +UpdateNetlistGetDefaultGetLayoutViewHeightFunc[shape=box]; +UpdateNetlistGetDefaultGetFloorplanViewHeightFunc[shape=box]; +UpdateNetlistGetSkillNetlistEstimateCellWidthFunc[shape=box]; +UpdateNetlistGetDefaultGetCellWidthFunc[shape=box]; +UpdateNetlistGetDefaultGetNetlistViewPositionFunc[shape=box]; +UpdateNetlistGetDefaultGetLayoutViewPositionFunc[shape=box]; +UpdateNetlistGetDefaultGetFloorplanViewHeightFunc[shape=box]; +UpdateNetlistGetSkillNetlistEstimateCellPositionFunc[shape=box]; +UpdateNetlistGetDefaultGetCellPositionFunc[shape=box]; +UpdateNetlistGetPinChangeFunc[shape=box]; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/index.html b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/index.html new file mode 100644 index 0000000000..8166f92ea0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/doc/updatenetlist/index.html @@ -0,0 +1,450 @@ + + + + + + + + Updatenetlist + + + + + +

Update Netlist

+ +

Overview

+ +

Fulcrum Micro-Architecture engineers use a language called + CAST to specify the netlists for the circuits that Fulcrum + creates. Fulcrum uses the Virtuoso layout editor from Cadence + to create the physical design of a circuit. Thus Fulcrum needs + a way to extract a circuit's netlist from CAST and load the + netlist into the Cadence tools. Updatenetlist is the tool which + accomplishes that task.

+ +

Updatenetlist updates the following types of information in + the DFII layout:

+ +
+
Hierarchy
+ +
+

Updatenetlist makes sure that each cell in the DFII + contains the instances specified in the CAST and only the + instances specified in the CAST.

+ +

The function + UpdateNetlistCompareCellInstances in the skill + code figures out how the dfII layout hierarchy differs from + the CAST hierarchy for a cell.

+ +

UpdateNetlistCompareCellInstances does the + following:

+ +
    +
  1. +

    Figures out which instances in the DFII need to be + deleted. Instances of cells from the gate, stack, and + technology libraries are not considered in the layout + view. Instances of cells from the gate and stack + libraries are always deleted in the floorplan view.

    +
  2. + +
  3. +

    Figures out which instances in the DFII need to + instantiate a different master cell.

    +
  4. + +
  5. +

    Figures out which instances need to be created in + the DFII.

    +
  6. + +
  7. +

    Figures out which instances need to have their + P-Cell parameters set.

    +
  8. +
+
+ +
Connectivity
+ +
+

Updatenetlist makes sure that each port of each instance + in each cell is connected to the net specified for that + port in the CAST.

+ +

The function + UpdateNetlistCompareCellConnectivity in the + skill code figures out how the dfII layout connectivity + differs fomr the CAST connectivity for a CELL.

+ +

UpdateNetlistCompareCellConnectivity does + the following:

+ +
    +
  1. +

    Figures out which connections to instances in the + DFII are not in the CAST.

    +
  2. + +
  3. +

    Figures out which connections to instances in the + cast are not in the DFII.

    +
  4. + +
  5. +

    Figures out which terminals in the DFII are not in + the CAST.

    +
  6. + +
  7. +

    Figures out whihc terminals in the CAST are not in + the DFII.

    +
  8. + +
  9. +

    Figures out which nets in the DFII are not in the + CAST.

    +
  10. + +
  11. +

    Figures out which nets in the CAST are not in the + DFII.

    +
  12. + +
  13. +

    Figures out which nets need to have thier wire + spacing or wire width constraints changed.

    +
  14. +
+
+ +
Floorplanning
+ +
+

Updatenetlist estimates the width of leaf cells and + positions instances in the floorplan view in the same + locations as the corresponding instances in the layout + view.

+ +

The function + UpdateNetlistCompareCellBoundary in the skill + code calculates the height and width of leaf cells as + follows:

+ +
    +
  • +

    If the cell view is a floor plan view:

    + +
    +
    then
    + +
    +
      +
    • +

      If there is a cell view for the layout view + and it has a boundary shape:

      + +
      +
      then
      + +
      +

      Use the height and width of the boundary + in the layout.

      +
      + +
      else
      + +
      +
        +
      • +

        Use the value of the height + directive for the height

        +
      • + +
      • +

        Guess the width with the following + equation: ( ( ( + TotalTransistorGateLengthInMeters * + TransistorBaseWidthInMeters ) + + TotalTransistorGateAreaInMetersSquared + ) / CellHeightInMeters ) * + DensityFactorToUse * + DensityScaleFactorToUse * + BoundaryScalingFactor

        + +

        The guessed width is always rounded + off to the nearest multiple of the + WidthIncrement.

        +
      • +
      +
      +
      +
    • +
    +
    + +
    else
    + +
    +

    Don't change an existing boundary and don't draw + a boundary if there is not one.

    +
    +
    +
  • +
+
+
+ +

Usage

+ +

Updatenetlist can either be run directory or through + ubersize.

+ +

Updatenetlist options

+ +
+
--cell=name
+ +
+

This option is required and specifies the fully + qualified name of the top level cell whose DFII netlist is + to be updated.

+
+ +
--subtype=name
+ +
+

This option is required and specifies the sub type of + the cell specified with the --cell option whose DFII + netlist is to be updated

+
+ +
--fulcrum-pdk-root=dir
+ +
+

This option is required and specifies the root directory + of a Fulcrum PDK installation

+
+ +
--dfII-dir=dir
+ +
+

This option is required and specifies the location of + the + dfII directory.

+
+ +
--cast-path=path
+ +
+

This option is required and specifies a path in which to + look for CAST files that define the cell and subtype + specified with the --cell and --subtype options.

+
+ +
--density-factor-default=num
+ +
+

This option is optional and specifies the density factor + to use for cells that do not have a value for the + density-factor directive. The default value for this option + is 15

+
+ +
--bound-scale-factor=num
+ +
+

This option is optional and specifies the boundary + scaling factor to use. All leaf cell bounding boxes will + have thier calculated width scaled by the specified amount. + This option defaults to 1.

+
+ +
--suppress-pins
+ +
+

This option is optional and specified that updatenetlist + is not to create or modify pins in the DFII

+
+ +
--cadence-log=file
+ +
+

This option is optional and specifies a file that + updatenetlist will write the cadence log to. This option + defaults to /dev/null.

+
+ +
--update-views
+ +
+

This option is optional and specifies that updatenetlist + is to modify the DFII's netlist to match the netlist + specified in the CAST. If this option is not specified + nothing will be changed.

+
+ +
--verbose
+ +
+

This option is optional and specified that updatenetlist + should print out extra information about what it is + doing.

+
+ +
--check-log=file
+ +
+

This option is optional and specifies a file that + updatenetlist will write check log to. This option defaults + to /dev/null.

+
+ +
--lock-bound
+ +
+

This option is optional and specifies that updatenetlist + must not change any boundary shape in the DFII.

+
+ +
--force-pins
+ +
+

Ask Clayton

+
+ +
--suppress-netlist-view
+ +
+

This option is optional and specifies that updatenetlist + should not create or compare netlist views to the netlist + extracted from the CAST.

+
+ +
--lock-layout
+ +
+

This option is optional and specifies that updatenetlist + should not modify any layout view for any reason.

+
+ +
--version
+ +
+

This option is optional and specifies that updatenetlist + should print out the build identifier

+
+ +
--debug
+ +
+

This option is optional and specifies that updatenetlist + should run all skill code in the skill debugger.

+
+ +
--java-max-heap-size=
+ +
+

This option is optional and specifies the value of the + -Xmx argument to the java virtual machine. This option + defaults to 1800M.

+
+ +
--temp-dir=dir
+ +
+

This option is optional and specifies a directory that + will contain any temporary files updatenetlist creates. On + exit, updatenetlist deletes any temporary files or + directories it created. This option default to $TEMP. If + $TEMP is empty this option defaults to /scratch.

+
+
+ +

Ubersize options relating to Updatenetlist

+ +
+
cellName
+ +
+

Specified as --cell to updatenetlist.

+
+ +
subType
+ +
+

Specified as --subtype to updatenetlist.

+
+ +
--fulcrum-pdk-root
+ +
+

Specified as --fulcrum-pdk-root to updatenetlist

+
+ +
--dfII-dir
+ +
+

Specified as --dfII-dir to updatenetlist

+
+ +
--cast-dir
+ +
+

Specified as part of --cast-path to updatenetlist

+
+ +
--spec-dir
+ +
+

Specified as part of --cast-path to updatenetlist

+
+ +
--suppress-netlist
+ +
+

Specified as --suppress-netlist to updatenetlist

+
+ +
--lock-bound
+ +
+

Specified as --lock-bound to updatenetlist

+
+ +
--lock-layout
+ +
+

Specified as --lock-layout to updatenetlist

+
+ +
--bound-scale-factor
+ +
+

Specified as --bound-scale-factor to updatenetlist

+
+ +
--mem
+ +
+

Specified as --java-mex-heap-size to updatenetlist

+
+
+ + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/fulcrum_cds_setup.inc b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/fulcrum_cds_setup.inc new file mode 100755 index 0000000000..95581053ce --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/fulcrum_cds_setup.inc @@ -0,0 +1,58 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/nano.package#1 $ +# $DateTime: 2005/11/07 14:51:55 $ +# $Author: aubrey $ + +< +
  • cell renaming
  • +
  • partial extraction
  • +
  • lvs-nodes (deprecated now that Assura LVS seems to work w/o them)
  • + +DOC + +# JAVA +java com.avlsi.layout.gdsII.GenerateGDSIIData +include assura.package . + +# SH wrapper scripts +$arch/bin/generate_gdsII_data.sh ../../../java/src/com/avlsi/layout/gdsII/generate_gdsII_data.sh 775 +$arch/bin/gdsIIWrite.pl script/sh/cell-automation/one_cell_commands/gdsIIWrite.pl 775 p +$arch/bin/writegds script/sh/cell-automation/one_cell_commands/writegds 775 p +$arch/bin/Tapeout.pl script/sh/cell-automation/one_cell_commands/Tapeout.pl 775 p +$arch/bin/cdlsize265.pl script/sh/cell-automation/one_cell_commands/cdlsize265.pl 775 p +$arch/bin/size265.pl script/sh/cell-automation/one_cell_commands/size265.pl 775 p + +# SKILL +install/share/bin/gen_autoload skill/gen_autoload 775 p +share/skill/layout/hierarchy/hierarchy.il skill/layout/hierarchy/hierarchy.il 664 p +share/skill/layout/gdsII/gdsIIhier.il skill/layout/gdsII/gdsIIhier.il 664 p +share/skill/util/list/list.il skill/util/list/list.il 664 p +share/skill/util/table/table.il skill/util/table/table.il 664 p +share/skill/util/expression/expression.il skill/util/expression/expression.il 664 p +share/skill/util/lib.il skill/util/lib.il 664 p +share/skill/schematic/updatenetlist.il skill/schematic/updatenetlist.il 664 p +share/skill/util/string/strutil.il skill/util/string/strutil.il 664 p +share/skill/util/name.il skill/util/name.il 664 p +share/skill/schematic/lvsnodes.il skill/schematic/lvsnodes.il 664 p +share/skill/layout/keepout/abstract.il skill/layout/keepout/abstract.il 664 p +share/skill/layout/keepout/conductor.il skill/layout/keepout/conductor.il 664 p +share/skill/layout/transform/transform.il skill/layout/transform/transform.il 664 p +share/skill/layout/hierarchy/hierarchy.il skill/layout/hierarchy/hierarchy.il 664 p +share/skill/layout/pins/pinutil.il skill/layout/pins/pinutil.il 664 p + +# External +$arch/bin/rdgds ../../../c/gdsii/aaggds/rdgds 775 +$arch/bin/wrgds ../../../c/gdsii/aaggds/wrgds 775 +$arch/bin/aaggds ../../../c/gdsii/aaggds/aaggds 775 + +# for tapeout utility +$arch/bin/gdsxor ../../../c/gdsii/scripts/gdsxor 775 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/javafiles-custom.mk b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/javafiles-custom.mk new file mode 100644 index 0000000000..323c3c1df8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/javafiles-custom.mk @@ -0,0 +1,23 @@ +# Copyright 2003 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +VIRTUOSO_CURR_TARGET_DIR_TEMP := $(CURR_TARGET_DIR) +VIRTUOSO_CURR_PROJECT_DIR_TEMP := $(CURR_PROJECT_DIR) + +CURR_TARGET_DIR := $(call CONONICALIZE_PATH, $(CURR_TARGET_DIR)/../../../java/src) +CURR_PROJECT_DIR := $(call CONONICALIZE_PATH, $(CURR_PROJECT_DIR)/../../../java/src) + +include $(VIRTUOSO_CURR_PROJECT_DIR_TEMP)/../../../java/src/javafiles-custom.mk + +CURR_TARGET_DIR := $(VIRTUOSO_CURR_TARGET_DIR_TEMP) +CURR_PROJECT_DIR := $(VIRTUOSO_CURR_PROJECT_DIR_TEMP) + +JAVAFILES_CLASSES_SRC_ROOT := $(call CONONICALIZE_PATH, $(CURR_PROJECT_DIR)/../../../java/src) +JAVAFILES_CLASSES_JAR_ROOT := $(call CONONICALIZE_PATH, $(CURR_PROJECT_DIR)/../../../java/jars) +JAVAFILES_CLASSES_CACHE_ROOT := $(CURR_TARGET_DIR)/classcache +JAVAFILES_JAVADOC_SOURCE_PATH := $(call CONONICALIZE_PATH,$(CURR_PROJECT_DIR)/../../../java/src) + +JAVAFILES_PARSERS_USED := $(JAVAFILES_PARSERS_USED) \ + $(call CONONICALIZE_PATH, $(CURR_TARGET_DIR)/../../../java/src/com/avlsi/tools/jauto/CastQueryParser) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/lefdef.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/lefdef.package new file mode 100755 index 0000000000..855dea0ab2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/lefdef.package @@ -0,0 +1,27 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +< +
  • LEF file generation
  • +
  • DEF file generation
  • +
  • LEF file renaming
  • +
  • DEF file renaming
  • + +DOC + +# PERL wrapper scripts +$arch/bin/lef_rename.pl script/perl/lef_rename.pl 755 p +$arch/bin/def_rename.pl script/perl/def_rename.pl 755 p + +# SH wrapper scripts +$arch/bin/lefdefWrite.sh script/sh/lefdef/lefdefWrite.sh 755 p + +# SKILL +install/share/bin/gen_autoload skill/gen_autoload 775 p +share/skill/layout/lefdef/lefdef.il skill/layout/lefdef/lefdef.il 664 p +share/skill/layout/lefdef/apr_lefdef.il skill/layout/lefdef/apr_lefdef.il 664 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/mk_instance.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/mk_instance.package new file mode 100644 index 0000000000..28b96c7e8c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/mk_instance.package @@ -0,0 +1,15 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# This package is used for dumping dfII floorplan data to a format readable by jauto. + +include ../../../java/src/com/avlsi/file/cdl/util/rename/cdlrenamer.package ../../../java/src/com/avlsi/file/cdl/util/rename +$arch/bin/mk_instance.sh script/sh/util/mk_instance 775 p +$arch/bin/mkcdslib.sh script/sh/util/mkcdslib 775 p +$arch/bin/mk_instance_multi.pl script/perl/mk_instance_multi.pl 775 p +install/share/bin/gen_autoload skill/gen_autoload 775 p +share/skill/layout/instancesfile/instance.il skill/layout/instancesfile/instance.il 664 p +share/skill/util/name.il skill/util/name.il 664 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/nano.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/nano.package new file mode 100644 index 0000000000..2b31030629 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/nano.package @@ -0,0 +1,45 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +< +
  • Create Abstract
  • +
  • Create Flatten Cellview
  • +
  • Export Design DEF file
  • +
  • Export Design LEF file
  • +
  • Export Routing Directive DEF file
  • +
  • Create Verilog file
  • +
  • Nanoroute Init
  • + +DOC + +# PERL scripts +$arch/bin/createAbstract.pl script/perl/nano/createAbstract.pl 755 p +$arch/bin/createAbstractCellLog.pl script/perl/nano/createAbstractCellLog.pl 755 p +$arch/bin/defNets.pl script/perl/nano/defNets.pl 755 p +$arch/bin/exportDesignLef.pl script/perl/nano/exportDesignLef.pl 755 p +$arch/bin/genTracks.pl script/perl/nano/genTracks.pl 755 p +$arch/bin/initNanoroute.pl script/perl/nano/initNanoroute.pl 755 p +$arch/bin/listMissingAbstracts.pl script/perl/nano/listMissingAbstracts.pl 755 p +#$arch/bin/lef_rename.pl script/perl/lef_rename.pl 755 p +#$arch/bin/def_rename.pl script/perl/def_rename.pl 755 p + +# SH wrapper scripts +$arch/bin/createFlattenView.sh script/sh/nano/createFlattenView.sh 755 p +$arch/bin/exportDesignDef.sh script/sh/nano/exportDesignDef.sh 755 p + +# SKILL +install/share/bin/gen_autoload skill/gen_autoload 775 p +share/skill/nano/flatten.il skill/nano/flatten.il 664 p +share/skill/nano/util.il skill/nano/util.il 664 p +share/skill/nano/cellview.il skill/nano/cellview.il 664 p +share/skill/nano/routed.il skill/nano/routed.il 664 p +share/skill/nano/sync.il skill/nano/sync.il 664 p +share/skill/nano/floorplan.il skill/nano/floorplan.il 664 p +share/skill/layout/lefdef/lefdef.il skill/layout/lefdef/lefdef.il 664 p + +include ../../../java/src/com/avlsi/tools/cast2def/cast2def.package.inc ../../../java/src/com/avlsi/tools/cast2def diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cdl2snp.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cdl2snp.pl new file mode 100755 index 0000000000..0fe1d4e76c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cdl2snp.pl @@ -0,0 +1,229 @@ +#!/usr/intel/bin/perl -w + +# Translate CDL syntax to SNP syntax for LayGen +# Folds transistors +# Copyright 2012 Intel +# Authors: Andrew Lines + +use FileHandle; +use IPC::Open2; +use POSIX; + +# Output record separator +$" = " "; + +# options and defaults +$gridW = 0.042e-6; # rounding grid for width +$maxNmosW = 2*$gridW; # maximum fold width for NMOS +$maxPmosW = 2*$gridW; # maximum fold width for PMOS + +# usage banner +sub usage() { + die "Usage: $0\n" . + " [--gridW gridW] [--maxNmosW nw] [--maxPmosW pw]\n" . + " \n"; +} + +# parse arguments +while (defined $ARGV[0] && $ARGV[0] =~ /^--(.*)/) { + $flag = $1; + if ($flag eq "gridW") { + $gridW = $ARGV[1]; + shift @ARGV; + } elsif ($flag eq "maxNmosW") { + $maxNmosW = $ARGV[1]; + shift @ARGV; + } elsif ($flag eq "maxPmosW") { + $maxPmosW = $ARGV[1]; + shift @ARGV; + } else { + usage(); + } + shift @ARGV; +} +@ARGV == 3 or usage(); +my $top = "$ARGV[0]"; +my $f_in = "$ARGV[1]"; +my $f_out = "$ARGV[2]"; +print "$top\n"; + +# report a fatal error +sub error_msg { + die "$0: $f_in, line $.: $_[0]\n"; +} + +# map nodes +sub map_nodes { + foreach $node (@_) { + if ($node eq "Vdd") { $node = "vcc"; } + elsif ($node eq "GND") { $node = "vss"; } + } +} + +# Do linewise translation of CDL to SNP +open IN, "<$f_in" or die "Can't read $f_in\n"; +$line = ; +$. = 0; +my $cell; +my @out; +my %portnodes; +my %localnodes; +my $num_mos = 0; +while ($line) { + $next_line = ; + while (defined $next_line && $next_line =~ s/^\+/ /) { + chomp $line; + $line .= $next_line; + $next_line = ; + } + my $full = $line; + if ($line =~ s/^\.SUBCKT\s+//i) { + + # Begin Subcircuit Definition + my @parameters = (); + + $line =~ s/(\S+)\s+//; + $cell = $1; + $type = $1; + #push @out, ".SUBCKT $type" if ($cell eq $top); + while ($line =~ s/(\S+)\s*//) { + $arg = $1; + if ($arg =~ /(\S+)=(\S+)/) { + # Parameter and default. + # Default value saved in subc_arg will be used + # if an instance fails to provide all parameters + #push @out, " $1=$2" if ($cell eq $top); + } else { + # Node argument + #push @out, " $arg" if ($cell eq $top); + map_nodes($arg); + $portnodes{$arg}=1 if ($cell eq $top); + } + } + #push @out, "\n" if ($cell eq $top); + + } elsif ($line =~ s/^\.ENDS//i) { + + $cell = ""; + #push @out, ".ENDS\n" if ($cell eq $top); + + } elsif ($line =~ s/^M//i) { + + # MOSFET + my %parameters = (); + my @nodes = (); + + $line =~s/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)// + or error_msg "Missing arguments in mosfet: $full"; + my $name = $1; + my $type = $6; + my $drain = $2; + my $gate = $3; + my $source = $4; + my $bulk = $5; + map_nodes($drain,$source,$gate,$bulk); + if ($cell eq $top) { + $localnodes{$drain}=1; + $localnodes{$source}=1; + $localnodes{$gate}=1; + $localnodes{$bulk}=1; + } + + # create parameter list in aspice order + while ($line =~ s/(\S+)=//) { + my $p = lc($1); + my $v; + if ($line =~ s/'([^']*)'\s+//) { + $v = $1; + } elsif ($line =~ s/(\S+)\s+//) { + $v = $1; + } + $parameters{$p} = $v; + } + + # compute folds + my $w = POSIX::ceil($parameters{"w"}/$gridW); + my $maxW = $maxPmosW; + $maxW = $maxNmosW if ($type =~ /^n/); + $maxW = POSIX::ceil($maxW/$gridW); + my $folds = POSIX::ceil($w/$maxW); + my $small = 0; + my $mod = $w%$maxW; + if ($mod!=0) { $small = $maxW - $mod; } # number of small folds + + # emit + for ($f=0; $f<$folds; $f++) { + my $suffix = ""; + if ($folds>1) { + $suffix = "_${f}"; + $parameters{"w"} = ($maxW-($f<$small)) * $gridW; + } + $w2 = $parameters{"w"}*1e6; + $l2 = $parameters{"l"}*1e6; + $num_mos++ if ($cell eq $top); + push @out, "M${name}${suffix} $drain $gate $source $bulk $type $w2 $l2 \$\$UNI\n" + if ($cell eq $top); + } + + } elsif ($line =~ s/^X//i) { + + # Call to Subcircuit + my %parms = (); + my @parms = (); + my @nodes = (); + $line =~ s/^(\S+)\s*// or error_msg "Call lacks instance name: $full"; + $name = $1; + while ($line =~ s/(\S+)=(\S+)\s*//) { + $parms{$1}=$2; + push @parms, $1; + } + $line =~ s/(\S+)\s*$// or error_msg "Call lacks SUBCKT name: $full"; + $type = $1; + @nodes = split /\s+/, $line; + my $slash = pop @nodes; # FIXME: find better way to remove last "/" + if ($slash ne "/") { # slash is optional before subcircuit name + push @nodes, $slash; + } + push @out, "X$name @nodes $type" if ($cell eq $top); + foreach my $parm (@parms) { + push @out, " $parm=$parms{$parm}" if ($cell eq $top); + } + push @out, "\n" if ($cell eq $top); + + } elsif ($line =~ m/^\*/) { + # comment line, do nothing + } elsif ($line =~ s/^\s*\n//i ) { + # empty line with space, do nothing + } else { + # unknown line, error + error_msg "Unknown line type: $line"; + } + $line = $next_line; +} +close IN; + +# output +open OUT, ">$f_out" or die "Can't write $f_out\n"; +print OUT ".GLOBAL vcc vss\n"; +my @ports; +foreach my $node (keys %portnodes) { + unless ($node eq "vcc" || $node eq "vss") { push @ports, $node; } +} +print OUT "\$\$.MACRO $top @ports\n"; +print OUT "\$ CELL: $top (default L = 0.028)\n"; +print OUT "\$\$.INPUT @ports\n"; +print OUT "\$\$.OUTPUT\n"; +print OUT "\$\$.IOPUT\n"; +my $num_localnodes = 0; +my @nodes; +foreach my $node (keys %localnodes) { + if (!defined $portnodes{$node}) { push @nodes, $node; $num_localnodes++; } +} +print OUT "\$\$.DIC $num_localnodes $num_mos 0\n"; +print OUT "\$\$ @nodes\n"; +print OUT "\$\$.DICEND\n"; +foreach my $line (@out) { + print OUT $line; +} +print OUT "\$\$.EOM\n"; +close OUT; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/checkpgvia.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/checkpgvia.pl new file mode 100755 index 0000000000..380a03478f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/checkpgvia.pl @@ -0,0 +1,432 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/script/perl/plotdensity.pl#2 $ +# $DateTime: 2009/03/31 16:37:03 $ + +use strict; +use Getopt::Long; + +sub min { $_[0] < $_[1] ? $_[0] : $_[1] } +sub max { $_[0] > $_[1] ? $_[0] : $_[1] } + +my $gdsfile=""; +my $printer=""; +my $outfile=""; +my $maxcolors=10; +my $minlayer=1; +my $maxlayer=8; +my $runassura=1; +my $runname="cov"; +my $cellname=""; +my $gridsize=4.8; +my $workingdir="./"; +my $viewname="layout"; +my $verbose=0; +my $mode="x"; +my $dfIIdir=""; +my @rainbow; +my $pdkroot; +my $dohist=0; +my $doplot=1; +my $v78=0; +my $dolayer=undef; + +sub checkoptions { + my $err=0; + if (! ( $mode =~ /^[xpgdn]/) ) { + print STDERR "Illegal output mode '$mode', must be X11, gif, dwg, or ps"; + $err++; + } + $doplot=0 if ($mode =~ /^n/); + if ($mode =~ /^p/i and $printer ne "") { + my $rslt=`lpq -P$printer 2>/dev/null | grep -c ready`; + chomp $rslt; + if (! $rslt) { + print STDERR "Printer $printer does not exist"; + $err++; + } + } + if (! -d "$workingdir" or ! -w "$workingdir" ) { + print STDERR "Working directory '$workingdir' cannot be used"; + $err++; + } + if ( $cellname eq "" and $runassura ) { + print STDERR "Cell name required"; + $err++; + } + if (! $runassura and ! -f "$runname.cov" ) { + print STDERR "$runname.cov is missing"; + $err++; + } + $err; +} + +my @unlink=( + "alc", "bbc", "bcr", "cnv", "dat", "dvc", + "elf", "env", "erc", "erd", "err", "erx", + "glt", "gmp", "gsm", "hdr", "ilc", "lyr", + "map", "msg", "nrc", "sum", "svi", "tmp", + "trn", "xcn", +); + +sub usage { + my $cmd=$0; + $cmd =~ s:.*/::; + print STDERR < : number of bins in histogram + --gds2-file : gds2 file if required + --grid : grid (default 4.8) + --highest # : top layer to analyze (1-8) + --lowest # : bottom layer to analyze (1-8) + --mode (d|g|p|x) : dwg, gif, ps(postscript), X11 + --run-name : run name prefix to use + --verbose : a little debugging info + --view-name : view name for df2 mode + --source : one of df2 or gds2 + --working-dir : where to run from +EU + exit 1; +} + +my %options = ( + "assura!" => \$runassura, + "bins=i" => \$maxcolors, + "dfII-dir=s" => \$dfIIdir, + "gds2-file=s" => \$gdsfile, + "grid=f" => \$gridsize, + "highest-layer=i"=> \$maxlayer, + "lowest-layer=i" => \$minlayer, + "mode=s" => \$mode, + "printer=s" => \$printer, + "P=s" => \$printer, + "run-name=s" => \$runname, + "verbose" => \$verbose, + "view-name=s" => \$viewname, + "working-dir=s" => \$workingdir, + "fulcrum-pdk-root=s" => \$pdkroot, + "noplot" => sub {$doplot=0;}, + "hist" => \$dohist, + "help" => sub { usage; }, + "layer=s" => \$dolayer, + "via78" => \$v78, +); + +sub dorainbow { + my $n=int(($maxcolors+1)/2+0.51); + my $r=0; + my $g=0; + my $b=0; + my $j=0; + for (my $i = 0; $i < ($maxcolors % 2 ? $n : $n-1); $i++) { + $g = $i*255/($n/2); + $b = ($n-1-$i)*255/($n/2); + $rainbow[$j]= + sprintf "#%02x%02x%02x", $r,$g>255 ? 255:$g,$b>255?255:$b; + $j++; + } + for (my $i = 1; $i < $n; $i++) { + $r = $i*255/($n/2); + $g = ($n-$i)*255/($n/2); + $rainbow[$j]= + sprintf "#%02x%02x%02x", $r>255?255:$r,$g>255 ? 255:$g,$b>255?255:$b; + $j++; + } + $rainbow[0]="#000000"; + $rainbow[1]="#ff0000"; +} + +sub assura { + my $gdscellname; + my $dfIIcellname; + $dfIIcellname=`echo "$cellname" | fulcrum rename --type=cell --from=cast --to=cadence`; + chomp $dfIIcellname; + my $lib = $dfIIcellname; + $lib =~ s/\.[^\.]+$//; + $lib =~ s/\.[^\.]+$//; + if ( ! -f "assura_tech.lib") { + open (ATL, ">assura_tech.lib"); + print ATL "DEFINE Assura_tsmc65 \${FULCRUM_PDK_ROOT}/share/Fulcrum/assura"; + close ATL; + } + my $setv78=""; + $setv78="?set (\"V78\")" if $v78; + open (RSF, ">$runname.rsf"); + print RSF <cds.lib"); + print LIB </dev/null"; + } + else { + system "assura assura $runname.rsf 1>/dev/null"; + } +} + +GetOptions ( %options ) or usage; +$ENV{FULCRUM_PDK_ROOT}=$pdkroot + if ! defined $ENV{FULCRUM_PDK_ROOT}; + +$cellname = $ARGV[0] if $cellname eq "" and defined $ARGV[0]; +$gridsize = max ( $gridsize, 0.1); + +$outfile = "$runname" if $outfile eq ""; + +$maxcolors = max ($maxcolors, 2); +$minlayer = max (min ($maxlayer, $minlayer), 1); +$maxlayer = max (min ($maxlayer, 8), 1); + +checkoptions and usage; +dorainbow; +chdir $workingdir; + +if ( ( $runassura and assura ) or ! -f "$runname.cov" ) { + print STDERR "Assura Failed"; + exit 1; +} +if ($runassura) { + foreach my $ext (@unlink) { + unlink "$runname.$ext"; + } +} +my %density=(); +my ($minx,$miny,$maxx,$maxy); +my (%minx, %miny, %maxx, %maxy); +my %layers=(); +open (P, "<$runname.cov"); +my $cell; +my $layer; +my $dx=1e6; +my $dy=1e6; +my $ok=0; +while (

    ) { + chomp; + my @f=split; + if (/^Cell/) { + $cell=$f[3]; + $cell =~ s/_D_/./g; + $cell =~ s/_U_/_/g; + } + if (/^Rule.*geomGetCoverage/) { + $layer = $f[6]; + $layer =~ s/.*geomGetCoverage.//; + $layer =~ s/\s.*//; + $layer =~ s/_den//; + $layers{$layer}=$layer; + $ok=1; + } + elsif (/^Rule/) { + $ok=0; + } + if ($f[1] eq "X" and $ok) { + $density{"$layer"}->{"$f[2]:$f[3]"}=$f[6]; + if (defined ($minx{$layer})) { + $minx{$layer} = min $minx{$layer},$f[2]; + $maxx{$layer} = max $maxx{$layer},$f[4]; + $miny{$layer} = min $miny{$layer},$f[3]; + $maxy{$layer} = max $maxy{$layer},$f[5]; + } + else { + $dx = max(min($f[4]-$f[2],$dx),0); + $dy = max(min($f[5]-$f[3],$dy),0); + $minx{$layer} = $f[2]; + $miny{$layer} = $f[3]; + $maxx{$layer} = $f[4]; + $maxy{$layer} = $f[5]; + } + if (defined ($minx)) { + $minx = min $minx,$f[2]; + $maxx = max $maxx,$f[4]; + $miny = min $miny,$f[3]; + $maxy = max $maxy,$f[5]; + } + else { + $minx = $f[2]; + $miny = $f[3]; + $maxx = $f[4]; + $maxy = $f[5]; + } + } +} +close P; +$dx = sprintf "%.3f", $dx; +$dy = sprintf "%.3f", $dy; +my $fill=0; +my $scale; + +sub color { + my ($color)=@_; + if ($fill ne $color) { + print "f $color"; + $fill = $color; + } +} + +sub rect { + my ($x1,$y1,$x2,$y2,$f)=@_; + color($rainbow[$f]); + printf "r %.5f %.5f %.5f %.5f 1\n", + $x1, $y1, $x2, $y2; +} + +sub line { + my ($x1,$y1,$x2,$y2,$w)=@_; + color (0); + printf "l %.5f %.5f %.5f %.5f $w\n", + $x1, $y1, $x2, $y2; +} + +sub text { + my ($x1,$y1,$f,$t)=@_; + color (0); + printf "t %.5f %.5f $f \"$t\"\n", $x1, $y1, $t; +} + +$scale = min 7/($maxx-$minx), 7/($maxy-$miny); +my $mindensity=undef; +my $maxdensity=undef; +if (defined($dolayer) and !defined($density{$dolayer})) { + print STDERR "Unknown layer $dolayer"; + print STDERR "Available layers : ".join(" ", sort keys %density); + exit 1; +} +foreach my $layer (sort keys %density) { + my %dn=%{$density{$layer}}; + foreach my $key (keys %dn) { + my ($x,$y)=split(/:/,$key); + my $d = $dn{$key}; + if (defined($mindensity)) { + $mindensity=min($mindensity,$d); + $maxdensity=max($maxdensity,$d); + } + else { + $maxdensity=$mindensity=$d; + } + } +} +my $range=$maxdensity-$mindensity; +$range=1 if ($range==0); +my %hist=(); +foreach my $layer (sort keys %density) { + next if (defined($dolayer) and $dolayer ne $layer); + if ($minx{$layer} < $maxx{$layer} and $miny{$layer} < $maxy{$layer}) { + if (! $doplot or ($mode =~ /^n/)) { + open (X, ">/dev/null"); + } + elsif ($mode =~ /^d/i) { + open (X, ">$outfile.$layer.dwg"); + print STDERR "Writing $outfile.$layer.dwg" if $verbose; + } + elsif ($mode =~ /^g/i) { + open (X, "| gifdwg > $outfile.$layer.gif"); + print STDERR "Writing $outfile.$layer.gif" if $verbose; + } + elsif ($mode =~ /^p/i) { + if ($printer ne "") { + open (X, "| dwg -P$printer"); + print STDERR "Printing Layer METAL$layer" if $verbose; + } + else { + open (X, "| dwg -o $outfile.$layer.ps"); + print STDERR "Writing $outfile.$layer.ps" if $verbose; + } + } + else { + open (X, "| xdwg"); + print STDERR "Displaying Layer METAL$layer" if $verbose; + } + select X; + my $total=0; + my @hist=(); + my $n=0; + print "s 0 1"; + print "x 0"; + print "y 0"; + my %dn=%{$density{$layer}}; + foreach my $key (keys %dn) { + my ($x,$y)=split(/:/,$key); + my $d = $dn{$key}; + $hist{$layer}->{$d}++; + if ($d == 0) { + $hist[0]++; + } + elsif ($d < 0.0048) { + $hist[1]++; + $d=1; + } + else { + $d = 2+max(int(($d-$mindensity)/$range*($maxcolors-2)-1e-6), 0); + $hist[$d]++; + } + $total++; + rect (($x-$minx)*$scale, + ($maxy-$y)*$scale, + ($x+$dx-$minx)*$scale, + ($maxy-$y-$dy)*$scale, $d); + } + my $dtx=0.6; + my $caption=8.5; + color (0); + line (($maxx-$minx)*$scale+0.5, $maxy*$scale, -0.5, $maxy*$scale, 2); + line (-$minx*$scale, ($maxy-$miny)*$scale+0.5, -$minx*$scale, -0.5, 2); + text (0, $caption+0.6, 3, "$layer $cell"); + for ($n = 0; $n < $maxcolors; $n++) { + rect $n*$dtx, $caption, $n*$dtx+0.1, $caption+0.1, $n; + if ($n >= 2) { + text (($n-0.33)*$dtx, $caption+0.25, 1, + sprintf ("<=%.1f%s", (($n-1)/$maxcolors*$range+$mindensity)*4/0.004822, + $n == $maxcolors-1 ? " Vias" : "")); + } + elsif($n==0) { + text (($n-0.33)*$dtx, $caption+0.25, 1, "0"); + } + else { + text (($n-0.33)*$dtx, $caption+0.25, 1, "<4"); + } + text (($n)*$dtx, $caption+0.38, 2, + sprintf ("%.1f%%", 100*($hist[$n]/$total))); + } + close X; + } +} +if ($dohist) { + select STDOUT; + foreach my $layer (sort keys %hist) { + next if (defined($dolayer) and $dolayer ne $layer); + print "$layer"; + foreach my $d (sort keys %{$hist{$layer}}) { + printf "%.1f $hist{$layer}->{$d}\n", $d/0.004822*4; + } + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cmpdef.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cmpdef.pl new file mode 100755 index 0000000000..9cc292fcc3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/cmpdef.pl @@ -0,0 +1,695 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id: cmpdef.pl,v 1.3 2008/01/23 16:38:12 aubrey Exp aubrey $ +# $DateTime$ + +use strict; +use Getopt::Long; + +my $all=0; +my $doext=1; +my $verbose=0; +my $progress=1; +my $spardir=""; +my $vialefargcnt=0; +my %fills=(); +my @vialef = ( + "\$spardir/chip/bali/lef/multi_cut_via.lef", + "\$spardir/chip/bali/lef/non_default_rules.lef", + "\$spardir/vendor/artisan/hs/gates/sc-x/lef/tsmc13fsg_hs_8lm.lef", +); + +select STDERR; +$|=1; +select STDOUT; + +sub usage { + my ($msg)=@_; + print STDERR "$msg" if $msg ne ""; + print STDERR < : root of spar tree to find default via lefs + --vialef= : root of spar tree to find default via lefs + +Notes: +This checks only the VIA, SPECIALNETS, FILLS, and NETS sections for now. + +In FILLS it checks only RECT and not POLY. +EU +exit 1; +} + +GetOptions ( + "all" => \$all, + "noext" => sub { $doext = 0; }, + "verbose" => \$verbose, + "spar-dir=s" => \$spardir, + "vialef=s" => sub { + @vialef=() if ($vialefargcnt == 0); + push @vialef, split(/,/,$_[1]); + $vialefargcnt++; + }, +) or usage; + +usage "Too many (or too few) files." if $#ARGV != 1; + +warn "Warning: should specify spar-dir" + if $spardir eq "" and $vialef[0] =~ /\$spardir/; +warn "Warning: spar-dir does not exist $spardir" if ! -d $spardir; +foreach my $lef (@vialef) { + eval "\$lef=\"$lef\""; + warn "Warning: LEF file $lef does not exist" if ! -s $lef; +} + +my ($file0,$file1)=@ARGV; + + +usage "$file0 does not exist." if ! -s $file0; +usage "$file1 does not exist." if ! -s $file1; + +my $nr=0; +my %comp; +my %nets; +my %specialnets; +my %unmatched; +my %sunmatched; +my %vias=(); +my %viadefined=(); +my %netvias=(); +my %netsegments=(); +my @instances=(); + +my %start = ( + "NEW" => 1, + "ROUTED" => 1, + "FIXED" => 1, + "COVER" => 1, + "SHIELD" => 1, +); + +my %skip = ( + "CLOCK" => 1, + "DIST" => 1, + "FIXEDBUMP" => 1, + "GROUND" => 1, + "NETLIST" => 1, + "ORIGINAL" => 2, + "PATTERN" => 2, + "POWER" => 1, + "PROPERTY" => 3, + "SOURCE" => 1, + "TAPER" => 1, + "TIMING" => 1, + "USE" => 2, + "USER" => 1, + "VOLTAGE" => 2, + "WEIGHT" => 2, +); + +local (*P, $_); + +sub readvialef { + my ($file)=@_; + open (X, "<$file"); + while () { + chomp; + s/^[ \t]*//; + if (/^VIA /) { + my @f=split; + $viadefined{$f[1]}=3; + } + } + close X; +} + +sub readvias { + my @f; + while (

    ) { + chomp; + last if (/^END VIAS/); + my $lx=$_; + my $mask = 1 << $nr; + if (/^ *-/) { + while (! ($lx =~ /;/)) { + $_=

    ; + chomp; + s/^ *\+ */ /; + $lx .= $_; + } + } + $lx =~ s/ */ /g; + $lx =~ s/^ *//; + $lx =~ s/ $//; + @f=split(/ /, $lx); + shift @f; + my $name=shift @f; + my $geom = join " ", @f; + $vias{$geom}[$nr]=$name; + $viadefined{$name} |= $mask; + } +} + +sub readcomp { + my @f; + while (

    ) { + chomp; + last if (/^END COMP/); + my $lx=$_; + if (/^ *-/) { + while (! ($lx =~ /;/)) { + $_=

    ; + chomp; + s/^ *\+ */ /; + $lx .= $_; + } + } + $lx =~ s/ */ /g; + $lx =~ s/^ *//; + $lx =~ s/ $//; + @f=split(/ /, $lx); + shift @f; + my $inst=shift @f; + my $place = join " ", @f; + $comp{$place}[$nr]=$inst; + } +} + +sub readpins { + while (

    ) { + chomp; + last if (/^END PIN/); + } +} + +sub readblockages { + while (

    ) { + chomp; + last if (/^END BLOCK/); + } +} + +sub readfills { + my $mask = 1 << $nr; + while (

    ) { + chomp; + s/ */ /g; + s/^ //; + last if (/^END FILL/); + my $layer; + my @data=(); + push @data, $_; + while (! /;/) { + $_=

    ; + chomp; + s/ */ /g; + s/^ //; + push @data, $_; + } + my $lx = join (" ", @data); + $lx =~ s/ */ /g; + $lx =~ s/^ //; + @data = split(/ /,$lx); + shift @data; + my $layer; + while ($data[0] ne "") { + if ($data[0] eq "LAYER") { + shift @data; + $layer = shift @data; + while ($data[0] ne "RECT" and $data[0] ne "POLYGON" and $data[0] ne "") { + shift @data; + } + } + elsif ($data[0] eq "RECT") { + my $type = shift @data; + shift @data; + my $x0 = shift @data; + my $y0 = shift @data; + shift @data; + shift @data; + my $x1 = shift @data; + my $y1 = shift @data; + shift @data; + $fills{"$layer RECT $x0 $y0 $x1 $y1"} |= $mask; + } + elsif ($data[0] eq ";") { + last; + } + else { + print "$data[0]"; + exit 1; + } + } + } +} + +sub readspecialnets { + my @f; + my @data=(); + while (

    ) { + chomp; + last if (/^END SPECIALNE/); + push @data, $_; + if (/^ *-/) { + while (! /;/) { + $_=

    ; + chomp; + s/^ *\+ */ /; + s/ */ /g; + push @data, $_; + } + } + my $lx = join(" ", @data); + @data=(); + $lx =~ s/ */ /g; + $lx =~ s/^ *//; + $lx =~ s/ $//; + @f=split(/ /, $lx); + shift @f; + my $net=shift @f; + my $route = join " ", @f; + $specialnets{$route}[$nr]=$net; + } +} + +sub readnets { + my @f; + while (

    ) { + chomp; + last if (/^END NET/); + my $lx=$_; + if (/^ *-/) { + while (! ($lx =~ /;/)) { + $_=

    ; + chomp; + s/^ *\+ */ /; + $lx .= $_; + } + } + $lx =~ s/ */ /g; + $lx =~ s/^ *//; + $lx =~ s/ $//; + @f=split(/ /, $lx); + shift @f; + foreach my $f (@f) { + $f = "ROUTED" if ($f eq "FIXED"); + } + my $net=shift @f; + my $route = join " ", @f; + $nets{$route}[$nr]=$net; + } +} + +sub readdef { + my ($file) = @_; + if ($file =~ /\.gz/) { + open (P, "gunzip -c $file |"); + } + else { + open (P, "<$file"); + } + printf STDERR "Reading $file..." if $progress; + while (

    ) { + chomp; + s/^ *//; + readvias() if /^VIAS /; + readnets() if /^NETS /; + readspecialnets() if /^SPECIALNETS /; + readcomp() if /^COMPONENTS /; + readfills() if /^FILLS /; + } + close P; + print STDERR "Done" if $progress; +} + +foreach my $lef (@vialef) { + readvialef ($lef); +} + +readdef ($file0); +$nr++; +readdef ($file1); + +# nets comparison +my $mismatchcnt=0; +printf STDERR "Finding mismatches..." if $progress; +foreach my $route (sort keys %nets) { + if (! defined $nets{$route}[1] ) { + $unmatched{$nets{$route}[0]}[0]=$route; + $mismatchcnt++; + } + elsif (! defined $nets{$route}[0] ) { + $unmatched{$nets{$route}[1]}[1]=$route; + $mismatchcnt++; + } + elsif ($all) { + $unmatched{$nets{$route}[0]}[0]=$route; + $unmatched{$nets{$route}[1]}[1]=$route; + } +} +$mismatchcnt /= 2; +print STDERR " found $mismatchcnt mismatches Done" if $progress; + +undef %nets; +$mismatchcnt=0; +#specialnets comparison +printf STDERR "Finding specialnets mismatches..." if $progress; +foreach my $route (sort keys %specialnets) { + if (! defined $specialnets{$route}[1] ) { + $sunmatched{$specialnets{$route}[0]}[0]=$route; + $mismatchcnt++; + } + elsif (! defined $specialnets{$route}[0] ) { + $sunmatched{$specialnets{$route}[1]}[1]=$route; + $mismatchcnt++; + } + elsif ($all) { + $sunmatched{$specialnets{$route}[0]}[0]=$route; + $sunmatched{$specialnets{$route}[1]}[1]=$route; + } +} +undef %specialnets; +$mismatchcnt /= 2; +print STDERR " found $mismatchcnt mismatches Done" if $progress; + + +my $data0=$ARGV[0]; +$data0 =~ s/\.def/.dat/; +my $data1=$ARGV[1]; +$data1 =~ s/\.def/.dat/; +open (P0, ">$data0"); +open (P1, ">$data1"); + +printf STDERR "Finding Fills Mismatches..."; +foreach my $geom (sort keys %fills) { + if ($fills{$geom} & 1) { + print P0 "FILLS $geom"; + } + if ($fills{$geom} & 2) { + print P1 "FILLS $geom"; + } +} +print STDERR "Done"; + +printf STDERR "Finding Via Definition Mismatches..."; +my $cvm=0; +foreach my $geom (sort keys %vias) { + if (! defined ($vias{$geom}[1]) ) { + print P0 "VIA $vias{$geom}[0] $geom"; + } + elsif (! defined ($vias{$geom}[0])) { + print P1 "VIA $vias{$geom}[1] $geom"; + } + elsif ($all) { + print P0 "VIA $vias{$geom}[0] $geom"; + print P1 "VIA $vias{$geom}[1] $geom"; + } +} +print STDERR "Done"; + +printf STDERR "Reporting %s special net data...", $all ? "all" : "mismatched" + if $progress; +$mismatchcnt=0; +foreach my $net (sort keys %sunmatched) { + $mismatchcnt++; + sreport($net); +} +print STDERR " reported $mismatchcnt nets Done" if $progress; + +printf STDERR "Reporting %s net data...", $all ? "all" : "mismatched" if $progress; +$mismatchcnt=0; +foreach my $net (sort keys %unmatched) { + $mismatchcnt++; + report($net); +} +print STDERR " reported $mismatchcnt nets Done" if $progress; + +close P0; +close P1; +sleep 1; + +open (P, "diff '$data0' '$data1' |"); +my %difnets=(); +my %diflay=(); +my %difvia=(); +my %difs=(); +my $cmp=0; +while (

    ) { + chomp; + my @f=split; + my $dir = 0; + my $dir = 1 if $f[0] eq ">"; + if ($f[0] =~ /^[<>]$/) { + $difs{$f[1]}++; + $difnets{$f[2]}[$dir]=1 if $f[1] eq "NETS" or $f[1] eq "SPECIALNET"; + if (($f[1] eq "NETS" or $f[1] eq "SPECIALNET") and ($f[3] =~ /^METAL\d+$/ or $f[3] =~ /^M\d+$/)) { + $diflay{$f[3]}[$dir]=1; + } + elsif ($f[1] eq "FILLS" and ($f[2] =~ /^METAL\d+$/ or $f[2] =~ /^M\d+$/)) { + $diflay{$f[2]}[$dir]=1; + } + elsif ($f[1] eq "SPECIALNET" and ! ($f[3] =~ /^METAL\d+$/ or $f[3] =~ /^M\d+$/)) { + $difvia{$f[3]}[$dir]=1; + } + elsif ($f[1] eq "NETS") { + $difvia{$f[3]}[$dir]=1; + } + $cmp++; + } +} +close P; +my $cd=0; +foreach my $net (sort keys %difs) { + $cd++; +} +print STDERR "Difference Sections ($cd)"; +foreach my $section (sort keys %difs) { + print " $section"; +} +my $cn=0; +foreach my $net (sort keys %difnets) { + $cn++; +} +print STDERR "Difference Nets ($cn)"; +foreach my $net (sort keys %difnets) { + print " $net"; +} +my $cl=0; +foreach my $lay (sort keys %diflay) { + $cl++; +} +print STDERR "Difference Layers ($cl)"; +foreach my $lay (sort keys %diflay) { + print " $lay"; +} +my $cv=0; +foreach my $via (sort keys %difvia) { + $cv++; +} +print STDERR "Difference Vias ($cv)"; +foreach my $via (sort keys %difvia) { + print " $via"; +} +if ($cmp > 0) { + print STDERR "diff '$data0' '$data1' to see details"; +} +exit ($cmp); + +sub generate { + my ($net, $fn) = @_; + my $r0 = $unmatched{$net}[$fn]; + my @r0=split(/ /,$r0); + my $n0=shift @r0; + my $n0; + my $ndr0=""; + my $bgnext=""; + my $endext=""; + my $mask = 1 << $fn; + for ($n0 = 0; $n0 < $#r0 and ! $start{$r0[$n0]}; $n0++) { + my $x = $r0[$n0]; + if ($x eq "NONDEFAULTRULE") { + $ndr0 = $r0[$n0+1]; + $n0 += 2; + $x = $r0[$n0]; + } + push @{$instances[$fn]}, $x if $x ne '(' and $x ne ')'; + } + my $x; + my $y; + my @xy=(); + # make a list of segments and vias + for ($n0++; $n0 < $#r0 and $r0[$n0] ne ';';) { + my $layer = $r0[$n0]; + $bgnext=$endext=""; + if (! $start{$layer} and ! ($layer =~ /^METAL/)) { + $netvias{"$layer $xy[$#xy-1] $xy[$#xy]"} |= $mask; + $layer = $r0[++$n0]; + } + @xy=(); + $layer = $r0[++$n0] if $start{$layer}; + $layer =~ s/METAL//; + my $ndr=$ndr0; + if ($r0[$n0+1] eq "TAPER") { + $ndr=""; + $n0++; + } + while ( $r0[++$n0] eq '(') { + my $x0 = $r0[++$n0]; + my $y0 = $r0[++$n0]; + $y0 = $y if ($y0 eq "*"); + $x0 = $x if ($x0 eq "*"); + push @xy, $x0; + push @xy, $y0; + $x = $x0; + $y = $y0; + $n0++; + if ($r0[$n0] ne ')') { + if ($#xy == 1) { + $bgnext = $r0[$n0] if $doext; + } + else { + $endext = $r0[$n0] if $doext; + } + $n0++; + } + } + if ($#xy > 2) { + for (my $n = 0; $n < $#xy-2; $n+=2) { + if ($n == 0 and $#xy == 3 and $bgnext ne "" and $endext ne "") { + $netsegments{"METAL$layer BGN=$bgnext $xy[$n] $xy[$n+1] $xy[$n+2] $xy[$n+3] END=$endext $ndr"} |= $mask; + } + elsif ($n == 0 and $bgnext ne "") { + $netsegments{"METAL$layer BGN=$bgnext $xy[$n] $xy[$n+1] $xy[$n+2] $xy[$n+3] $ndr"} |= $mask; + } + elsif ($n == $#xy-3 and $endext ne "") { + $netsegments{"METAL$layer $xy[$n] $xy[$n+1] $xy[$n+2] $xy[$n+3] END=$endext $ndr"} |= $mask; + } + else { + $netsegments{"METAL$layer $xy[$n] $xy[$n+1] $xy[$n+2] $xy[$n+3] $ndr"} |= $mask; + } + } + } + while ($skip{$r0[$n0]}) { + $n0 += $skip{$r0[$n0]}; + } + } +} + +sub report { + my ($net) = @_; + %netsegments=(); + %netvias=(); + generate($net,0); + generate($net,1); + print "Mismatch instances $net" if join(" ", @{$instances[0]}) ne join(" ",@{$instances[1]}); + foreach my $via (sort keys %netvias) { + my @f=split(/ /,$via); + print STDERR "Warning: $f[0] not defined" if $viadefined{$f[0]} != 3; + $viadefined{$f[0]} = 3; + print P0 "NET $net $via" if ($netvias{$via} & 1); + print P1 "NET $net $via" if ($netvias{$via} & 2); + } + foreach my $seg (sort keys %netsegments) { + print P0 "NET $net $seg" if ($netsegments{$seg} & 1); + print P1 "NET $net $seg" if ($netsegments{$seg} & 2); + } +} + +my %snetsegments; +my %snetvias; + +sub sgenerate { + my ($net,$fn)=@_; + my $r0 = $sunmatched{$net}[$fn]; + my @r0=split(/ /,$r0); + my $mask = 1 << $fn; + my $x; + my $y; + my @xy=(); + my $n0 = 0; + # skip to ROUTED/NEW/etc + while ($r0[0] ne "" and ! $start{$r0[0]}) { + shift @r0; + } + # make a list of segments and vias + my $total=$#r0; + for ($n0++; $n0 < $#r0 and $r0[$n0] ne ';';) { + while (! ($start{$r0[$n0]}) and $r0[$n0] ne "") { + $n0++; + } + last if $r0[$n0] eq ""; + $n0++ if $start{$r0[$n0]}; + my $layer = $r0[$n0]; + @xy=(); + $layer = $r0[++$n0] if $start{$layer}; + print STDERR "$layer" if ! $layer =~ /^METAL/; + $layer =~ s/METAL//; + my $width = $r0[++$n0]; + $n0++; + if ($r0[$n0] ne "+" and $r0[$n0] ne "(") { + printf STDERR "Expected '+' at $n0 of $net found:\n "; + for(my $n = $n0-10; $n < $n0+5;$n++) { + if ($n == $n0) { + printf STDERR ":$r0[$n]: "; + } + else { + printf STDERR "$r0[$n] "; + } + } + print STDERR ""; + } + while ($r0[$n0] ne "" and $r0[$n0] ne "(") { + $n0++; + } + $n0--; + while ( $r0[++$n0] eq '(') { + my $x0 = $r0[++$n0]; + my $y0 = $r0[++$n0]; + $y0 = $y if ($y0 eq "*"); + $x0 = $x if ($x0 eq "*"); + push @xy, $x0; + push @xy, $y0; + $x = $x0; + $y = $y0; + $n0++; + if ($r0[$n0] ne ')') { + print STDERR "Expected ')' at $n0 in $net"; + } + } + if ($#xy > 2) { + for (my $n = 0; $n < $#xy-2; $n+=2) { +# print STDERR "METAL$layer $width $xy[$n] $xy[$n+1] $xy[$n+2] $xy[$n+3]"; + $snetsegments{"METAL$layer $width $xy[$n] $xy[$n+1] $xy[$n+2] $xy[$n+3]"} |= $mask; + } + } + elsif ($#xy == 1) { +# print STDERR "VIA $r0[$n0]"; + $snetvias{"$r0[$n0] $xy[0] $xy[1]"} |= $mask; + } + while ($skip{$r0[$n0]}) { + $n0 += $skip{$r0[$n0]}; + } + } +} + +sub sreport { + my ($net) = @_; + %snetsegments=(); + %snetvias=(); + sgenerate($net,0); + sgenerate($net,1); + foreach my $via (sort keys %snetvias) { + my @f=split(/ /,$via); + print STDERR "Warning: $f[0] not defined" if $viadefined{$f[0]} != 3; + $viadefined{$f[0]} = 3; + print P0 "SPECIALNET $net $via" if ($snetvias{$via} & 1); + print P1 "SPECIALNET $net $via" if ($snetvias{$via} & 2); + } + foreach my $seg (sort keys %snetsegments) { + print P0 "SPECIALNET $net $seg" if ($snetsegments{$seg} & 1); + print P1 "SPECIALNET $net $seg" if ($snetsegments{$seg} & 2); + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dangling.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dangling.pl new file mode 100755 index 0000000000..248f6f1ba0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dangling.pl @@ -0,0 +1,210 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id: dangling,v 1.5 2006/04/21 04:10:44 aubrey Exp aubrey $ +# $DateTime$ + +use strict; +use IPC::Open2; + +my $subckt=""; +my %definitions=(); + +my %graybox=(); +my %nodecnt=(); +my %node2inst=(); +my %inst2cell=(); + +my $drd; +my $dwr; +my $dpid=0; + +# for graybox list, which uses cast names +sub cast2cadence { + my ($cell)=@_; + if (! $drd ) { + $dpid=open2 ($drd,$dwr, + "fulcrum rename --from=cast --to=cadence --type=cell"); + } + print $dwr "$cell"; + $cell=<$drd>; + chomp $cell; + $cell; +} + +# does not work without this list +open (P, "<$ARGV[1]"); +while (

    ) { + chomp; + s/ //g; + $graybox{$_}=1; +} +close P; +if ($dwr) { + close $dwr or die; + close $drd or die; +} +waitpid $dpid,0 if $dpid; + + +my %global=( + "GND" => 1, + "Vdd" => 1, + "0" => 1, +); + +my %subckts=(); +my %resistors=(); +my %xrefs=(); +my $top; + +sub parsecdl { + my ($file)=@_; + local (*P,$_); + open (P, "<$file"); + my $ln=""; + my $subckt=""; + my @resistors=(); + my @xrefs=(); + while (

    ) { + chomp; + if (/^\+/) { + s/^\+/ /; + $ln .= $_; + next; + } + my $x = $_; + $_=$ln; + $ln = $x; + s/ */ /g; + if (/^\.subckt /i) { + # collect subckt line + my ($s,$n,@f)=split; + $subckt=$n; + $top=$n; + my @pins=(); + @resistors=(); + @xrefs=(); + foreach my $f (@f) { + if ($f =~ /=/) { + last; + } + $f =~ s/:.*//; + push @pins,$f; + } + $subckts{$subckt}=[@pins]; + } + elsif (/^\.ends/i) { + # reset all the temp arrays and save + $resistors{$subckt}=[@resistors]; + $xrefs{$subckt}=[@xrefs]; + $subckt=""; + @resistors=(); + @xrefs=(); + } + elsif (/^r/i) { + # resistors may connect same nets + my @f=split; + $f[1] =~ s/:.*//; + $f[2] =~ s/:.*//; + push @resistors, "$f[0] $f[1] $f[2] $f[3] $f[4]"; + } + elsif (/^c/i) { # ignore capacitors for now + } + elsif (/^x/i) { + # decode contained instances + s/ \/ / /g; + if (/=/) { + s/=.*//; + my $i=rindex($_," "); + $_=substr($_,0,$i) if ($i > 0); + } + my @f=split; + # dump the :'s but in cdl this is silly, really + foreach my $f (0..$#f) { + $f[$f] =~ s/:.*//; + } + # one array element for each subcell + push @xrefs, "@f"; + } + elsif (/^ *[dm]/i) { + } + elsif (/^ *\*/) { + } + elsif (/^$/) { + } + else { + print STDERR "Warning: Unrecognized element $_"; + } + } + # for last subckt if not decoded above + if( @resistors or @xrefs) { + $resistors{$subckt}=[@resistors]; + $xrefs{$subckt}=[@xrefs]; + } +} + +# called recursively to generate names and port lists +sub getnames { + my ($cell,$inst,@pins)=@_; + $inst .= '.' if $inst ne ""; + $inst2cell{$inst}=$cell; + my @resistors=(); + my @xrefs=(); + my @nodes=(); + @nodes=@{$subckts{$cell}} if defined $subckts{$cell}; + my %nodes=(); + my $n = 0; + foreach my $node (@nodes) { + $nodes{$node}=$n; + $n++; + } + @resistors=@{$resistors{$cell}} if defined $resistors{$cell}; + @xrefs=@{$xrefs{$cell}} if defined $xrefs{$cell}; + foreach my $xref (@xrefs) { + my @f=split(/ /,$xref); + my @spins=(); + my $sinst = $f[0]; + $sinst =~ s/^X//; + $sinst = "${inst}$sinst"; + $inst2cell{$sinst}=$f[$#f]; + foreach my $n (1..$#f-1) { + my @inodes; + @inodes=@{$subckts{$f[$#f]}} if defined $subckts{$f[$#f]}; + if (defined $nodes{$f[$n]}) { + push @spins,$pins[$nodes{$f[$n]}]; + $nodecnt{$pins[$nodes{$f[$n]}]}++; + $nodecnt{$pins[$nodes{$f[$n]}]}++; + $node2inst{$pins[$nodes{$f[$n]}]} = "$sinst:$inodes[$n-1]"; + } + else { + push @spins, "${inst}$f[$n]"; + $nodecnt{"${inst}$f[$n]"}++; + $node2inst{"${inst}$f[$n]"} = "$sinst:$inodes[$n-1]"; + } + } + # descend if not a graybox cell + getnames ($f[$#f],$sinst,@spins) if ( ! $graybox{$f[$#f]}); + } + foreach my $resistor (@resistors) { + my @f=split(/ /,$resistor); + my $tr=$f[0]; + if ($f[1] ne $f[2]) { + $nodecnt{"${inst}$f[1]"}++; + $nodecnt{"${inst}$f[2]"}++; + } + } +} + +# read the netlist entirely +parsecdl ($ARGV[0]); +# recursively find all of the names +getnames ($top, "",@{$subckts{$top}}); + +# just report the results +open(P, ">$ARGV[2]"); +print( P "danglingNodeList=nil" ); +foreach my $node (sort keys %nodecnt) { + my ($inst,$pin)=split(/:/,$node2inst{$node}); + print( P "danglingNodeList=cons( list(\"$node\" \"$inst\" \"$pin\" \"$inst2cell{$inst}\") danglingNodeList)") if $nodecnt{$node}==1; +} +close(P); diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/def_rename.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/def_rename.pl new file mode 100755 index 0000000000..d88a5a352a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/def_rename.pl @@ -0,0 +1,147 @@ +#!/usr/intel/bin/perl -w +# Copyright 2004 Fulcrum Microsystems. All rights reserved. +# Authors: Kai He + +use FileHandle; +use IPC::Open2; + +$rename = "rename"; + +sub usage() { + die "Usage: $0 --from=[cast,cadence,gds2] --to=[cast,cadence,gds2] --infile=[infilename] --outfile=[outfilename]\n"; +} + +while (defined $ARGV[0] && $ARGV[0] =~ /^--(.*)/) { + ($flag,$value) = split('=',$1); + if ($flag eq "to") { + $to = $value; + shift @ARGV; + } elsif ($flag eq "from") { + $from = $value; + shift @ARGV; + } elsif ($flag eq "infile") { + $f_in = $value; + shift @ARGV; + } elsif ($flag eq "outfile") { + $f_out = $value; + shift @ARGV; + } else { + shift @ARGV; + } +} + +defined $to or usage(); +defined $from or usage(); +defined $f_out or usage(); +defined $f_in or usage(); + +$pid1=open2(*INST_IN,*INST_OUT,"$rename --type=instance --from=$from --to=$to"); +$pid2=open2(*CELL_IN,*CELL_OUT,"$rename --type=cell --from=$from --to=$to"); +$pid3=open2(*NODE_IN,*NODE_OUT,"$rename --type=node --from=$from --to=$to"); + +sub inst_rename { + print INST_OUT $_[0]."\n"; + my $name=; + chomp($name); + return $name; +} +sub cell_rename { + print CELL_OUT $_[0]."\n"; + my $name=; + chomp($name); + return $name; +} +sub node_rename { + print NODE_OUT $_[0]."\n"; + my $name=; + chomp($name); + return $name; +} + +open( SOURCE, "<$f_in") or die "Can't open '$f_in' for reading.\n"; +open( TARGET, ">$f_out") or die "Can't open '$f_out' for writing.\n"; + +$. = 0; +$components=0; +$nets=0; +$pins=0; +$thisNet=0; + +while($line=){ + if ($line=~/\\/){$line=~s/\\//g;} + if ($line=~/^DESIGN (\S*)/){ + $oldcellname=$1; + $newcellname=cell_rename($oldcellname); + $line=~s/^DESIGN \Q$oldcellname\E/DESIGN \Q$newcellname\E/; + + } elsif ( $line=~/^COMPONENTS /){ + $components=1; + } elsif ( $components && $line=~/^- (\S*) (\S*) /){ + $oldinstname=$1; + $oldcellname=$2; + $newinstname=inst_rename($oldinstname); + $newcellname=cell_rename($oldcellname); + $line=~s/^- \Q$oldinstname\E \Q$oldcellname\E/- \Q$newinstname\E \Q$newcellname\E/; + + } elsif ( $line=~/^END COMPONENTS$/){ + $components=0; + + } elsif ( $line=~/^PINS /){ + $pins=1; + } elsif ( $pins && $line=~/- (\S*) \+ NET (\S*) /){ + $oldpinname=$1; + $oldnetname=$2; + $newpinname=node_rename($oldpinname); + $newnetname=node_rename($oldnetname); + $line=~s/^- \Q$oldpinname\E \+ NET \Q$oldnetname\E/- \Q$newpinname\E \+ NET \Q$newnetname\E/; + } elsif ( $line=~/^END PINS$/){ + $pins=0; + + } elsif ( $line=~/^NETS /){ + $nets=1; + } elsif ( $line=~/^SPECIALNETS /){ + $nets=1; + } elsif ( $nets && $line=~/^- (\S*)/){ + $oldnetname=$1; + $newnetname=node_rename($oldnetname); + $line=~s/^- \Q$oldnetname\E/- \Q$newnetname\E/; + $thisNet=1; + } elsif ( $nets && $thisNet && $line=~/^(\s*)\( (\S*) (\S*) \)/){ + $newline=$1; + chomp($line); + @word=split(' ',$line); + for( $i=0; $i<$#word; $i++){ + if($word[$i]eq"("){ + $i++; $oldinstname=$word[$i]; + $i++; $oldpinname=$word[$i]; + $i++; # get rid of ")" + $newinstname=inst_rename($oldinstname); + $newpinname=node_rename($oldpinname); + $newline.="( $newinstname $newpinname )"; + } + if($i<$#word-1){$newline.=" ";} + } + $line=$newline."\n"; + } elsif ( $nets && $thisNet && $line=~/^\s*\+/){ + $thisNet=0; + } elsif ( $line=~/^END NETS/){ + $nets=0; + } elsif ( $line=~/^END SPECIALNETS/){ + $nets=0; + } + print TARGET $line; +} + +close(SOURCE); +close(TARGET); + +close(CELL_IN); +close(CELL_OUT); +close(INST_IN); +close(INST_OUT); +close(NODE_IN); +close(NODE_OUT); +waitpid( $pid1, 0); +waitpid( $pid2, 0); +waitpid( $pid3, 0); + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dfIIhier.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dfIIhier.pl new file mode 100755 index 0000000000..876bd286b4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/dfIIhier.pl @@ -0,0 +1,177 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id: dfIIhier.pl,v 1.2 2008/10/09 17:18:17 aubrey Exp aubrey $ +# $DateTime$ + +use strict; +use Getopt::Long; +use IPC::Open2; + +my $dfIIdir; +my $cell; +my $lib; +my $pdk=""; +my $lvl=0; +my $pdkdfII; +my %libdirs; +my $maxlvl = 32; +my $find; +my $view="layout"; +my $conversion="cadence"; +my $virtuoso_mode=0; + +my %options = ( + "dfII-dir=s" => \$dfIIdir, + "cell=s" => \$cell, + "lib=s" => \$lib, + "maxlevel=i" => \$maxlvl, + "where=s" => \$find, + "view=s" => \$view, + "fulcrum-pdk-root=s" => \$pdk, + "conversion=s" => \$conversion, + "virtuoso_mode" => \$virtuoso_mode, +); + +my $usage; + +sub usage { + my ($msg) = @_; + print STDERR "$msg" if defined $msg; + print $usage; + exit 1; +} + +my $pid=0; + +sub convert { + my ($in) = @_; + if ($pid) { + print WR $in; + my $out=; + chomp $out; + $in = $out; + } + $in; +} + +sub readcdslib { + my ($file) = @_; + my $root=$file; + $root =~ s/\/[^\/]+$//; + open (P, "<$file"); + while (

    ) { + chomp; + if (/^DEFINE/) { + my ($d,$lib,$dir)=split; + $lib =~ s/#2d/-/g; + $lib =~ s/#2e/./g; + $lib =~ s/#24/\$/g; + print STDERR "$lib" if $lib =~ /#/; + $libdirs{$lib}="$root/$dir"; + } + } +} + +GetOptions ( %options) or usage; + +if ($conversion ne "cadence") { + $pid = open2(\*RD, \*WR, "rename --type=cell --from=cadence --to=$conversion"); +} + +$cell = shift if @ARGV; +if (! defined($lib)) { + $lib = $cell; + $lib =~ s/\.[^\.]+\.[^\.]+$//; +} +$pdkdfII = "$pdk/share/Fulcrum/dfII" if defined($pdk) and -d $pdk; + +readcdslib ("$pdkdfII/cds.lib"); +readcdslib ("$dfIIdir/cds.lib.generated"); + +$usage = < + Options + cell :[$cell] (does not need --cell) + dfII-dir :[$dfIIdir] root of dfII tree + fulcrum-pdk-root :[$pdk] + lib :[$lib] + where :[$find] locate a cell in the hierarchy + virtuoso_mode :[$virtuoso_mode] output looks like virtuoso +EU + +usage ("invalid dfII-dir [$dfIIdir]") if ! -s "$dfIIdir/cds.lib.generated"; +usage ("invalid pdk [$pdk]") if $pdk ne "" and ! -d $pdk; +usage ("cell name required") if ! defined $cell; +$find =~ s/\./\\./g; +$find =~ s/\?/./g; +$find =~ s/\*/.*/g; + +my @stack=(); + +sub printstack { + my ($cell)=@_; + my $lvl=0; + print "=== $cell"; + foreach my $stack (@stack) { + if ($virtuoso_mode) { + printf "%*.*s$stack\n", 3*$lvl,3*$lvl," "; + } + else { + my @f=split(/ /,$stack); + printf "%*.*s$f[1] $f[0] $f[2]\n", 2*$lvl,2*$lvl," "; + } + $lvl++; + } +} + +sub subcells { + my ($lib,$view,$cell)=@_; + return if $lvl > $maxlvl; + push @stack, "$cell $lib $view"; + printstack($cell) if $cell =~ /$find/ and defined($find); + my $dir = $lib; + my $xcell=convert($cell); + if ($virtuoso_mode) { + if ($lvl == 0) { + print " Design Hierarchy"; + print "****************************************************************************************************"; + print "Library : $lib"; + print "Cell : $xcell"; + print "View : $view"; + print "Stop Level : $maxlvl"; + print "****************************************************************************************************"; + print ""; + } + else { + printf "%*.*s$lib $xcell $view\n", 2*$lvl-2,2*$lvl-2," " if ! defined $find; + } + } + else { + printf "%*.*s$xcell $lib $view\n", 3*$lvl,3*$lvl," " if ! defined $find; + } + $dir =~ s/\./\//g; + $dir = "$dfIIdir/$dir"; + my $celldir=$cell; + $celldir =~ s/\./#2e/g; + $celldir =~ s/-/#2d/g; + $dir = $libdirs{$lib}; + print STDERR "$lib undefined" if ! defined $dir; + local (*P,$_); + if ( open (P, "<$dir/$celldir/$view/pc.db")) { + while (

    ) { + chomp; + my ($sublib,$subcell,$subview)=split; + if (defined ($subview)) { + $lvl++; + subcells($sublib,$subview,$subcell); + $lvl--; + } + } + } + else { + warn "Cannot open $dir/$celldir/$view/pc.db" if $view =~ /\./; + } + pop @stack; +} + +subcells($lib,$view,$cell); diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/gds2cdl.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/gds2cdl.pl new file mode 100755 index 0000000000..f62b50a5ba --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/gds2cdl.pl @@ -0,0 +1,167 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +my $gdsfile; +my $cellname=""; +my $rulesFile; +my $techlib; +my $technology; +my $pdkroot; +my $cdlfile; +my $verbose=0; +my $debug=0; + +my %options = ( + "gds-file=s" => \$gdsfile, + "topcell=s" => \$cellname, + "debug" => \$debug, + "rulesFile=s" => \$rulesFile, + "techlib=s" => \$techlib, + "fulcrum-pdk-root=s" => \$pdkroot, + "technology=s" => \$technology, + "cdl-file=s" => \$cdlfile, + "verbose" => \$verbose, +); + +sub usage { + print STDERR $_[0] if defined ($_[0]); + print STDERR "Usage gds2cdl [options]"; + foreach my $opt (sort keys %options) { + $opt =~ s/=.*/ /; + print " --$opt"; + } +exit 1; +} + +GetOptions ( %options ) or usage; + +$verbose=1 if $debug; + +usage "No gds file" if ! $gdsfile or ! -s $gdsfile; +my %sname; +my %strname; +my $rdgds = `which rdgds`; +chomp $rdgds; +$rdgds = "fulcrum rdgds" if ! $rdgds =~ m:/tools/bin/:; +if ( ! $cellname or $cellname eq "") { + print STDERR "Finding top cell name" if $verbose; + open (P, "$rdgds $gdsfile |"); + while (

    ) { + chomp; + s/^ *//; + if (/^STRNAME /) { + my ($x,$name)=split; + $strname{$name}=1; + } + elsif (/^SNAME /) { + my ($x,$name)=split; + $sname{$name}++; + } + } + close P; + my $cnt=0; + foreach my $name (keys %strname) { + if ( ! $sname{$name}) { + $cnt++; + $cellname=$name; + } + } + usage "Too many potential top cells in $gdsfile" if $cnt > 1; + usage "No topcell found in $gdsfile" if $cnt == 0; +} +elsif ($debug) { + open (P, "$rdgds $gdsfile |"); + while (

    ) { + chomp; + s/^ *//; + if (/^STRNAME /) { + my ($x,$name)=split; + $strname{$name}=1; + } + elsif (/^SNAME /) { + my ($x,$name)=split; + $sname{$name}++; + } + } + close P; + usage "Topcell $cellname not found." if ! defined $strname{$cellname}; +} +usage "No topcell found in $gdsfile" if $cellname eq ""; +$pdkroot = $ENV{FULCRUM_PDK_ROOT} if ! $pdkroot or ! -d $pdkroot; +$rulesFile = "$pdkroot/share/Fulcrum/assura/extract.rul" + if ! -f $rulesFile; +usage "No rules file found" if ! -f $rulesFile; +$techlib = "$pdkroot/share/Fulcrum/assura/assura_tech.lib" + if ! -f $techlib; +usage "No techlib file found" if ! -f $techlib; +if ( ! $technology or $technology eq "" ) { + print STDERR "Finding Technology in techfile" if $verbose; + open (P, "<$techlib"); + while (

    ) { + chomp; + my @f=split; + if ($f[0] eq "DEFINE") { + if ($technology eq "") { + $technology = "$f[1]"; + } + else { + usage "Multiple Technologies in techfile, must define on command line"; + } + } + } +} + +my $prefix="/scratch/gds2cdl"; +my $rsftemplate = <${prefix}$$.rsf"); +print P $rsftemplate; +close P; +$cdlfile = "gds2cdl$$.cdl" if $cdlfile eq ""; +my $rv; +print STDERR "Running assura" if $verbose; +my $logfile="/dev/null"; +$logfile="${prefix}$$.log" if $debug; +$rv=system ("${assura}assura ${prefix}$$.rsf > $logfile"); +usage "assura failed" if $rv; +print STDERR "Running vldbToSpice" if $verbose; +$rv=system ("${assura}vldbToSpice ${prefix}$$.ldb > $cdlfile"); +usage "vldbToSpice failed" if $rv; +if ($debug) { + print STDERR "Files located: $prefix$$.*"; +} +else { + print STDERR "Cleaning $prefix" if $verbose; + system "rm -rf ${prefix}$$.*"; + unlink "spiceMap.txt"; +} +print STDERR "$cdlfile written" if $verbose; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importGDS.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importGDS.pl new file mode 100755 index 0000000000..f84073ddb3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importGDS.pl @@ -0,0 +1,681 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use IPC::Open2; +use Getopt::Long; +my $gnd="GND"; +my $vdd="Vdd"; +my $default_prefix=""; +my $debug=0; +my $skip_cds_lib_generated=0; +my $multipletopcells=0; + +my $template = < + --library= + --fulcrum-pdk-root= use if not using default name + --subtype=[$subtype] + --gnd=[$gnd] + --vdd=[$vdd] + --dopipo run pipo automatically + --tech-vias (experimental, dangerous if misused) + --isflat (special if you KNOW the cell is flat) + [--force] + gdsfile +EU +exit 1; +} + +my %options = ( + "force" => \$force, + "verbose" => \$verbose, + "prefix=s" => \$default_prefix, + "library=s" => \$library, + "fulcrum-pdk-root=s" => \$pdkroot, + "dfII-dir=s" => \$dfIIdir, + "bind-file=s" => \$bindfile, + "topcell=s" => \$topcell, + "subtype=i" => \$subtype, + "dopipo" => \$dopipo, + "tech-vias" => \$tech_vias, + "gnd=s" => \$gnd, + "vdd=s" => \$vdd, + "isflat" => \$skip_cds_lib_generated, +); + +GetOptions ( %options ) or usage; + +usage "Need --library" if $library eq ""; + +if ( $default_prefix eq "") { + $default_prefix = $library; +} +if ( !defined ($subtype)) { + $subtype=400; +} +if ( ! -f "cds.lib") { + my $wd=`pwd`; + chomp $wd; + print "mkcdswd --target-dir=$wd --fulcrum-pdk-root=$pdkroot --dfII-dir=$dfIIdir" + if $verbose; + system "mkcdswd --target-dir=$wd --fulcrum-pdk-root=$pdkroot --dfII-dir=$dfIIdir"; +} +if ($library ne "") { + my $cdsname=$library; + $cdsname =~ s/\./#2e/g; + my $exists=`grep -c "^DEFINE $cdsname " cds.lib 2>/dev/null`; + chomp $exists; + if ($exists == 0) { + $exists=`grep -c "^DEFINE $cdsname " $dfIIdir/cds.lib.generated 2>/dev/null`; + } + printf "Library $library %s\n", $exists ? "EXISTS" : "Does Not Exist" if $verbose; + if ($exists == 0) { + open (P, ">>cds.lib"); + print P "UNDEFINE $cdsname"; + print P "DEFINE $cdsname $library"; + close P; + if ($library ne "" and ! ($library =~ /^\./)) { + print "/bin/rm -rf '$library'" if $verbose; + system "/bin/rm -rf '$library'"; + print "mkdir '$library'"; + mkdir "$library"; + # print "/bin/cp -rp template '$library'" if $verbose; + # system "/bin/cp -rp template '$library'"; + } + } +} + +sub gdsread { + my ($file)=@_; + local(*Q); + my $top = ""; + my %ref=(); + my %string=(); + local(*P,$_); + if ( -f "$file.cells" and ! $force) { + print STDERR "READING $file.cells" if $verbose; + open (P, "<$file.cells"); + open (Q, ">/dev/null"); + } + else { + print STDERR "READING $file" if $verbose; + open (P, "rdgds $file |"); + open (Q, ">$file.cells"); + } + my $last=""; + while (

    ) { + chomp; + s/^ *//; + my ($key,$name)=split; + if ($key eq "STRNAME") { + print Q if ! defined $gds{$name}; + $gds{$name}=1; + $cells{$name}=1; + } + if ($key eq "SNAME") { + print Q if ! defined $ref{$name}; + $ref{$name}++; + $cells{$name}=1; + } + if ($key eq "STRING") { + $name =~ s/'//g; + print Q if ! defined $string{$name}; + $string{$name}=1; + } + $last=$_; + } + close P; + close Q; + if (! defined ($topcell)) { + my $top=""; + my $topcnt = 0; + foreach my $key (keys %gds) { + if (! defined ($ref{$key}) ) { + $top=$key; + $topcnt++; + } + } + if ($topcnt > 1) { + print STDERR "Multiple topcells found"; + $multipletopcells=1; + $topcell=""; + } + elsif ($topcnt == 0 or $top eq "") { + print STDERR "No topcell found"; + } + else { + $topcell = $top; + } + } + print STDERR "Warning: NO $gnd pin" if ! defined $string{$gnd}; + print STDERR "Warning: NO $vdd pin" if ! defined $string{$vdd}; +} + +sub readlib { + my ($lib,$path)=@_; + local(*P,$_,*D); + return if ($skip_cds_lib_generated and $lib =~ /cds\.lib\.generated/); + print STDERR "READING $lib" if $verbose; + open (P, "<$lib"); + $path = `dirname $lib` if ( ! defined ($path)); + chomp $path; + while (

    ) { + chomp; + next if (/^#/); + my ($cmd,$libname,$pathname)=split; + if ($cmd eq "SOFTINCLUDE" and -f $libname) { + $libname = "$path/$libname" if ( ! ($libname =~ m:^/:)); + readlib($libname); + } + elsif ($cmd eq "DEFINE" and $lib ne "cds.lib") { # don't use local files + $libname =~ s/#2e/./g; + #next if $libname eq $library; + # the following hack is until there is a command line option + next if $libname =~ /^chip\.tc4\./; + next if $libname =~ /^chip\.alta\./; + next if $libname =~ /^synthesis/; + $pathname = "$path/$pathname" if ( ! ($pathname =~ m:^/:)); + opendir (D, "$pathname"); + my @dirs=sort( readdir (D)); + closedir D; + $|=1; + foreach my $dir (@dirs) { + next if (($dir =~ /^[RS]/) or ! ($dir =~ /#/)); # can only be regfile/sram subcells + if ( -s "$pathname/$dir/layout/layout.oa") { + my $dfIIcell1 = $dir; + $dfIIcell1 =~ s/#2e/./g; + $dfIIcell1 =~ s/#2d/-/g; + $dfIIcell1 =~ s/#24/\$/g; + my $dfIIcell2; + my $cell1; + my $cell2; + my $cell3; + undef $cell1; + undef $cell2; + undef $cell3; + print "A $dfIIcell1" if $debug; + print GDIN "$dfIIcell1"; + $cell1=; + chomp $cell1; + $dfIIcell2=$dfIIcell1; + print "B $cell1" if $debug; + # note: assumes numeric subtype + $dfIIcell2 =~ s/\.\d+$//; + $dfIIcell2 =~ s/.*\.//; + print GDIN "$dfIIcell2"; + $cell2=; + chomp $cell2; + print "B $cell2" if $debug; + my $xref1=$cell1; + my $xref2=$cell2; + my $xref3=$cell1; + # pipo strmout names + $xref1 =~ s/[^A-Za-z0-9_]/_/g; + if ($xref{$xref1}[0] > 0) { + my $subtype1 = $dfIIcell1; + $subtype1 =~ s/.*\.//; + my $subtype0 = $xref{$xref1}[1]; + $subtype0 =~ s/.*\.//; + if ($dfIIcell1 eq $xref{$xref1}[1]) { + $xref{$xref1}[0]--; + } + elsif (($subtype1 =~ /^\d+$/) and ($subtype0 =~ /^\d+$/) and + $subtype1 < $subtype0) { + $xref{$xref1}[2] = $xref{$xref1}[1]; + $xref{$xref1}[1] = $dfIIcell1; + print "ST1a:$xref{$xref1}[1]:$xref{$xref1}[2]" if $debug; + } + elsif (($xref{$xref1}[1] cmp $dfIIcell1) > 0) { + $xref{$xref1}[2] = $xref{$xref1}[1]; + $xref{$xref1}[1] = $dfIIcell1; + print "ST1b:$xref{$xref1}[1]:$xref{$xref1}[2]" if $debug; + } + else { + $xref{$xref1}[2] = $dfIIcell1; + print "ST1c:$xref{$xref1}[1]:$xref{$xref1}[2]" if $debug; + } + } + else { + $xref{$xref1}[1]=$dfIIcell1; + } + $xref{$xref1}[0]++; + $xref2 =~ s/[^A-Za-z0-9_]/_/g; + if ($xref{$xref2}[0] > 0) { + my $subtype1 = $dfIIcell1; + $subtype1 =~ s/.*\.//; + my $subtype0 = $xref{$xref2}[1]; + $subtype0 =~ s/.*\.//; + if ($dfIIcell1 eq $xref{$xref2}[1]) { + $xref{$xref2}[0]--; + } + elsif (($subtype1 =~ /^\d+$/) and ($subtype0 =~ /^\d+$/) and + $subtype1 < $subtype0) { + $xref{$xref2}[2] = $xref{$xref2}[1]; + $xref{$xref2}[1] = $dfIIcell1; + print "ST2a:$xref{$xref2}[1]:$xref{$xref2}[2]" if $debug; + } + elsif (($xref{$xref2}[1] cmp $dfIIcell1) > 0) { + $xref{$xref2}[2] = $xref{$xref2}[1]; + $xref{$xref2}[1] = $dfIIcell1; + print "ST2b:$xref{$xref2}[1]:$xref{$xref2}[2]" if $debug; + } + else { + $xref{$xref2}[2] = $dfIIcell1; + print "ST2c:$xref{$xref2}[1]:$xref{$xref2}[2]" if $debug; + } + } + else { + $xref{$xref2}[1]=$dfIIcell1; + } + $xref{$xref2}[0]++; + + $xref3 =~ s/-L/_L_/g; + $xref3 =~ s/-R/_R_/g; + $xref3 =~ s/\./__/g; + if ($xref{$xref3}[0] > 0) { + my $subtype1 = $dfIIcell1; + $subtype1 =~ s/.*\.//; + my $subtype0 = $xref{$xref3}[1]; + $subtype0 =~ s/.*\.//; + if ($dfIIcell1 eq $xref{$xref3}[1]) { + $xref{$xref2}[0]--; + } + elsif (($subtype1 =~ /^\d+$/) and ($subtype0 =~ /^\d+$/) and + $subtype1 < $subtype0) { + $xref{$xref3}[2] = $xref{$xref3}[1]; + $xref{$xref3}[1] = $dfIIcell1; + print "ST2a:$xref{$xref3}[1]:$xref{$xref3}[2]" if $debug; + } + elsif (($xref{$xref3}[1] cmp $dfIIcell1) > 0) { + $xref{$xref3}[2] = $xref{$xref3}[1]; + $xref{$xref3}[1] = $dfIIcell1; + print "ST2b:$xref{$xref3}[1]:$xref{$xref3}[2]" if $debug; + } + else { + $xref{$xref3}[2] = $dfIIcell1; + print "ST2c:$xref{$xref3}[1]:$xref{$xref3}[2]" if $debug; + } + } + else { + $xref{$xref3}[1]=$dfIIcell1; + } + $xref{$xref3}[0]++; + + # always xref to self + if ($xref{$dfIIcell1}[0] > 0) { + my $subtype1 = $dfIIcell1; + $subtype1 =~ s/.*\.//; + my $subtype0 = $xref{$dfIIcell1}[1]; + $subtype0 =~ s/.*\.//; + if ($dfIIcell1 eq $xref{$dfIIcell1}[1]) { + $xref{$dfIIcell1}[0]--; + } + elsif (($subtype1 =~ /^\d+$/) and ($subtype0 =~ /^\d+$/) and + $subtype1 < $subtype0) { + $xref{$dfIIcell1}[2] = $xref{$dfIIcell1}[1]; + $xref{$dfIIcell1}[1] = $dfIIcell1; + print "ST3a:$xref{$dfIIcell1}[1]:$xref{$dfIIcell1}[2]" if $debug; + } + elsif (($xref{$dfIIcell1}[1] cmp $dfIIcell1) > 0) { + $xref{$dfIIcell1}[2] = $xref{$dfIIcell1}[1]; + $xref{$dfIIcell1}[1] = $dfIIcell1; + print "ST3b:$xref{$dfIIcell1}[1]:$xref{$dfIIcell1}[2]" if $debug; + } + else { + $xref{$dfIIcell1}[2] = $dfIIcell1; + print "ST3c:$xref{$dfIIcell1}[1]:$xref{$dfIIcell1}[2]" if $debug; + } + } + else { + $xref{$dfIIcell1}[1]=$dfIIcell1; + } + $xref{$dfIIcell1}[0]++; + print "XREF 1 $xref1 => $dfIIcell1" if $verbose; + print "XREF 2 $xref2 => $dfIIcell1" if $verbose; + print "XREF 3 $xref3 => $dfIIcell1" if $verbose; + print "XREF 4 $dfIIcell1 => $dfIIcell1" if $verbose; + } + } + } + elsif ($cmd eq "INCLUDE") { + printf "INCLUDE $path $libname\n" if $verbose; + $libname = "$path/$libname" if ( ! ($libname =~ m:^/:)); + readlib($libname); + } + } +} + +my $file; +$file = $ARGV[0] if defined $ARGV[0]; +usage if (! defined ($file)); +if ( ! -s "textFontTable.txt" or $force) { + open (T, ">textFontTable.txt"); + print T "#Cadence Font Stream Font Scale Factor\nstick 0 0.1"; + close T; +} +if ( ! -s "propQ.map" or $force) { + open (T, ">propQ.map"); + print T <) { + chomp; + my @f=split; + if ($#f == 3) { + $bind{$f[3]}=$f[0]; + } + } + } +} +if ((! -s "$bindfile") or $force) { + if (open P,">$bindfile") { + $writebind=1; + select P; + print STDERR "Writing $bindfile" if $verbose; + } + else { + print STDERR "Cannot open bind file for writing, reverting to reading it."; + } +} +my %symbolic=(); +if ($tech_vias) { + # override xrefs with the pdk techlib cells, experimental! + opendir D, "$pdkroot/share/Fulcrum/dfII"; + my @dfiles=grep(/^tsmc/, readdir(D)); + closedir D; + chomp @dfiles; + if ($#dfiles == 0) { + opendir D, "$pdkroot/share/Fulcrum/dfII/$dfiles[0]"; + my @dirs=readdir(D); + closedir D; + foreach my $dir (@dirs) { + if ( -d "$pdkroot/share/Fulcrum/dfII/$dfiles[0]/$dir/symbolic" or + -d "$pdkroot/share/Fulcrum/dfII/$dfiles[0]/$dir/layout") { + $xref{$dir}[0] = 1; + $xref{$dir}[1] = $dir; + $symbolic{$dir} = 1 if -d "$pdkroot/share/Fulcrum/dfII/$dfiles[0]/$dir/symbolic"; + } + } + } + else { + print STDERR "Warning: No techlib found"; + } +} +my $fatal=0; +foreach my $cell (sort keys %cells) { + print STDERR "CELL $cell" if $verbose; + if (! $writebind and ! defined ($bind{$cell})) { + print STDERR "Error: $cell is not in $bindfile"; + $fatal++; + } + if (defined ($xref{$cell})) { + my $xrefcell=$xref{$cell}[1]; + if ($xref{$cell}[0] > 1 and $default_prefix ne "") { + my $x1 = $xref{$cell}[1]; + my $x2 = $xref{$cell}[2]; + $x1 =~ s/\.[^\.]+$//; + $x2 =~ s/\.[^\.]+$//; + if ($x1 ne $x2) { + $xrefcell =~ s/^[^\.]+\./$default_prefix./; + } + } + if ( ! ($xrefcell =~ /\./)) { + } + elsif ($xrefcell =~ /_(VIA[a-zA-Z0-9_]+)$/i) { + $xrefcell = $default_prefix."_".$1; + } + elsif ($xrefcell =~ /via/i) { + $xrefcell =~ s/$library/$default_prefix/; + } + elsif (! ($xrefcell =~ /\./)) { + $xrefcell = "${default_prefix}.$xrefcell"; + } + if ($writebind) { + if (defined($bind{$cell})) { + if( $bind{$cell}=~/(\.[0-9A-Z_of]+\.[0-9]+)$/ ){ + my $thisLib=$bind{$cell}; + $thisLib=~s/$1//g; + print "$thisLib $bind{$cell} layout $cell"; + } else { + print "$library $bind{$cell} layout $cell"; + } + } + else { + if (defined $symbolic{$cell}) { + print "tsmc28 $xrefcell symbolic $cell"; + } + else { + if ($cell =~ /^a28lvt_/){ print "vendor.avago.lvt vendor.avago.lvt.$cell.0 layout $cell";} + elsif ($cell =~ /^a28hvt_/){ print "vendor.avago.hvt vendor.avago.hvt.$cell.0 layout $cell";} + elsif ($cell =~ /^a28_/){ print "vendor.avago.svt vendor.avago.svt.$cell.0 layout $cell";} + elsif ($cell =~ /globals__wires__a28_fillnw4_a1_/){ print "globals $xrefcell layout $cell";} + else { + print STDERR "$xrefcell\n"; + if( $xrefcell=~/(\.[0-9A-Zof_]+\.[0-9]+)$/ ){ + my $thisLib=$xrefcell; + $thisLib=~s/$1//g; + print "$thisLib $xrefcell layout $cell"; + print STDERR "$thisLib $xrefcell layout $cell"; + } else { + print "$library $xrefcell layout $cell"; + print STDERR "$library $xrefcell layout $cell"; + } + } + } + } + } + if ($xref{$cell}[0] != 1) { + print STDERR "Possible Ambiguous reference $cell => $xref{$cell}[1] ($xref{$cell}[0])\n"; + for (my $n = 2; $n < $xref{$cell}[0]; $n++) { + print STDERR "$xref{$cell}[$n]"; + } + } + } + elsif ($default_prefix eq "") { + print "; not found $cell"; + } + elsif ($cell eq $topcell) { + if ($writebind) { + if ($cell =~ /\./) { + print "$library $cell layout $cell"; + } + elsif ($cell =~/__/) { + my $cadence_cell=$cell; + $cadence_cell=~s/_L_/-L/g; + $cadence_cell=~s/_R_/-R/g; + $cadence_cell=~s/__/\./g; + print "$library $cadence_cell layout $cell"; + } + else { + print "$library $default_prefix.$cell.$subtype layout $cell"; + } + } + } + else { + # default subtype of 0 for non top cells +# print "$default_prefix.$cell.0 layout $cell" + my $xrefcell=$cell; + if (substr($xrefcell,0,length($topcell)+1) eq "${topcell}_" and $default_prefix ne "") { + $xrefcell =~ s/^${topcell}_/$default_prefix./; + } + if ($xrefcell =~ /_(VIA[a-zA-Z0-9_]+)$/i) { + $xrefcell = $default_prefix."_".$1; + } + elsif ($xrefcell =~ /via/i) { + $xrefcell =~ s/$library/$default_prefix/; + } + elsif (! ($xrefcell =~ /\./)) { + $xrefcell = "$default_prefix.$xrefcell.$subtype"; + } + print "$library $xrefcell layout $cell" + if $writebind or $verbose; + } +} +select STDOUT; +close P; +if ($fatal) { + print STDERR "Fatal Error in Bind File"; + exit 1; +} +sleep 1; +`sort -u -o '$bindfile' '$bindfile'` if $writebind; +close GDIN; +close GDOUT; +waitpid ($gdpid,0); +if (! $multipletopcells && (! defined ($topcell) or $topcell eq "")) { + $topcell = $file; + $topcell =~ s/\.gds.*//; +} +print "TOPCELL $topcell" if $verbose; +$template =~ s/GDSFILE/$file/; +$template =~ s/TOPCELL/$topcell/g; +$template =~ s/LIBNAME/$library/; +$template =~ s/BINDFILE/$bindfile/; +$template =~ s/TECHLIB/tsmc28/g; +$template =~ s/LAYERMAP/$pdkroot\/share\/Fulcrum\/stream\/strmin.layermap/; +my $logfile=$file; +$logfile =~ s/\.gds\*/.log/g; +$logfile = "strmIn.log" if $logfile eq $file; +$template =~ s/LOGFILE/$logfile/g; +if ($skip_cds_lib_generated) { + $template =~ s/REFLIB//; +} +else { + my $reflib = $bindfile; + $reflib =~ s/\.[^\.]*$//; + $reflib .= ".reflib"; + open (P, ">$reflib"); + print P "globals\n"; + print P "vendor.avago.svt\n"; + print P "vendor.avago.lvt\n"; + print P "vendor.avago.hvt\n"; + print P "lib.synchronous.conversion.probe\n"; + print P "lib.synchronous.conversion.util\n"; + print P "lib.synchronous.conversion.sizing\n"; + print P "lib.synchronous.conversion.s2a\n"; + print P "lib.synchronous.conversion.a2s\n"; + close P; + $template =~ s/REFLIB/$reflib/; +} +my $rsffile = $bindfile; +$rsffile =~ s/\.[^\.]*$//; +$rsffile .= ".template"; +open (P, ">$rsffile"); +print P $template; +close P; +if ( ! defined ($ENV{FULCRUM_PDK_ROOT})) { + $ENV{FULCRUM_PDK_ROOT} = $pdkroot; +} +print "Streaming in..."; +print "$ENV{IC_SCRIPT} strmin -templateFile $rsffile" + if ! $dopipo or $verbose; +system "$ENV{IC_SCRIPT} strmin -templateFile $rsffile 2>\&1 | grep Translation" + if $dopipo; +# create thumbnails +open (P, ">thumbnails.il"); +print P "hiGenerateThumbnails(?lib \"$library\")"; +close P; +print "Making thumbnails..."; +print "$ENV{IC_SCRIPT} layout -nograph -replay thumbnails.il -log thumbnails.log" + if !$dopipo or $verbose; +system "$ENV{IC_SCRIPT} layout -nograph -replay thumbnails.il -log thumbnails.log" + if $dopipo; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importQ.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importQ.pl new file mode 100755 index 0000000000..7f4c818b7a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/importQ.pl @@ -0,0 +1,1379 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +my $description = <; + chomp $new; + $new; +} + +my %isportdefault=("VddA"=>1,"_RESET"=>1); + +my @castlines=(); + +my %openpins=(); +my $library; +my $cdl; +my $portfile; +my $errs=0; +my $castdir; +my $specdir; +my $bindfile=""; +# could not find this one automatically +my @addimport=("lib.synchronous.schannel"); +my %imports=(); +my %ports=(); +my %implied=(); +my %bind=(); +my %bindnet=(); +my %dummynetassign=(); +my $subtype = 0; +my $flat=0; +my %portdirection=(); +my %castfound=(); + +sub fixup { + my @lines=@_; + my %length=(); + for ( my $n = 0; $n <= $#lines; $n++) { + $_=$lines[$n]; + %length=() if (/module/); + if (/^ *node\[(\d+)\] *([^ ;]+)/) { + # node declarations, both ports and local + my $a = $2; + my $l = $1; + $a =~ s/^[-+]//; + $length{$a}=$l; +# print STDERR "FND1 $a\[$l\]"; + } + elsif (/^ *node *([^\[ ;]+)\[(\d+)\.\.(\d+)\]/) { + # more node declarations, both ports and local + my $a = $1; + my $n = $2; + my $x = $3; + $a =~ s/^[-+]//; + $x++; + $length{$a}=$x; +# print STDERR "FND2 $a\[$x\]"; + } + if (m:^ *([^ ]+) *// node ([^\[]+)\[(\d+)\]:) { + # ports of subcells + my @list=(); + my $sig = $1; + my $port=$2; + my $pdx = $3; + my $size = $pdx+1; + my $comma=$sig; + $comma=~s/[^,]//g; + $sig =~ s/,$//; + my $sdx = -1; + if ($sig =~ /([^\[]+)\[(\d+)\]/) { + $sdx = $2; + $sig = $1; + } + my $i=0; + my $ok = 1; + my $sg = $sig; +# print STDERR "FND3 $sig\[$sdx\] $port\[$pdx\]"; + while ($lines[$n+$i] =~ m:^ *([^ ]+) *// node $port\[(\d+)\]:) { + $sig = $1; + $pdx = $2; + $sdx = -1; + $comma=$sig; + $comma=~s/[^,]//g; + $sig =~ s/,$//; + if ($sig =~ /([^\[]+)\[(\d+)\]$/) { + $sdx = $2; + $sig = $1; + } +# print STDERR "FND4 $sig\[$sdx\] $port\[$pdx\]"; + $ok = 0 if ($pdx != $sdx or $sig ne $sg); + $size = $pdx + 1 if ($ok and $size <= $pdx); + push @list, "$sig $sdx $port $pdx"; + $i++; + } + my $match=$ok; + if ($size != $length{$sig}) { + $ok = 0; + } + if ($size == 1) { + if (defined ($length{$sig})) { + if ($length{$sig} != $size) { + print " $sig\[$sdx\]$comma // node[$size] $port"; + } + else { + print " $sig\[0\]$comma // node[$size] $port"; + } + } + else { + print " $sig$comma // node[$size] $port"; + } + } + elsif ($ok) { + print " $sig$comma // node[$size] $port"; + } + elsif ($match) { + my $max=$size-1; + print " $sig\[0..$max\]$comma // node[$size] $port"; + } + else { + my @port=(); + foreach my $l (@list) { + my ($sig,$sdx,$port,$pdx)=split(/ /,$l); + $port[$pdx]=$sig; + $port[$pdx]="$sig\[$sdx\]" if $sdx >= 0; + } + print " \x7b $port[0],"; + my $x=0; + for ($x = 1; $x < $#port; $x++) { + print " $port[$x],"; + } + print " $port[$x]\x7d$comma // node[$size] $port"; + } + $n += $#list; + } + elsif (/^( *)node ([^ \[]+)\[(\d+)\];/) { + my $sp=$1; + my $node=$2; + my $ndx =$3; + my $min = $ndx; + my $max = $ndx; + my $i = 0; + while (/^ *node $node\[(\d+)\];/) { + $ndx = $1; + $min = $ndx if $ndx < $min; + $max = $ndx if $ndx > $max; + $i++; + $_=$lines[$n+$i]; + } + if ($min == 0) { + $max++; + $length{$node}=$max; + print "${sp}node[$max] $node;"; + } + else { + $length{$node}=$max+1; + print "${sp}node $node\[$min..$max\];"; + } + $n += $i-1; + } + else { + print; + } + } +} + +sub fixup1 { + my @lines=@_; + foreach my $n (0..$#lines) { + $a = $lines[$n]; + $lines[$n] =~ s/ *$//; + $lines[$n] =~ s/_L_/\[/g; + $lines[$n] =~ s/_R_/\]/g; + $lines[$n] =~ s/\[\d+\]\[/\[/; + $lines[$n] =~ s/\[(\d+)\]_/${1}_/; + print STDERR "CHANGE $a : $lines[$n]" if $a ne $lines[$n]; + } + my %length=(); + for ( my $n = 0; $n <= $#lines; $n++) { + $_=$lines[$n]; + %length=() if (/module/); + if (/\]_/) { + s/[\[\]]//g; + } + if (/^ *node\[(\d+)\] *([^ ;]+)/) { + my $a = $2; + my $l = $1; + $a =~ s/^[-+]//; + $length{$a}=$l; + } + elsif (/^\ *node *([^\[ ;]+)\[(\d+)\.\.(\d+)\]/) { + my $a = $1; + my $n = $2; + my $x = $3; + $a =~ s/^[-+]//; + $length{$a}=$x+1; + } + if (m:^ *([^ ]+) *// node ([^\[]+)\[(\d+)\]:) { + my @list=(); + my $sig = $1; + my $port=$2; + my $pdx = $3; + my $size = $pdx+1; + my $comma=$sig; + $comma=~s/[^,]//g; + $sig =~ s/,$//; + my $sdx = -1; + if ($sig =~ /([^\[]+)\[(\d+)\]/) { + $sdx = $2; + $sig = $1; + } + my $i=0; + my $ok = 1; + my $sg = $sig; + while ($lines[$n+$i] =~ m:^ *([^ ]+) *// node $port\[(\d+)\]:) { + $sig = $1; + $pdx = $2; + $sdx = -1; + $comma=$sig; + $comma=~s/[^,]//g; + $sig =~ s/,$//; + if ($sig =~ /([^\[]+)\[(\d+)\]$/) { + $sdx = $2; + $sig = $1; + } + $ok = 0 if ($pdx != $sdx or $sig ne $sg); + push @list, "$sig $sdx $port $pdx"; + $i++; + } + my $match=$ok; + if ($size != $length{$sig}) { + $ok = 0; + } + if ($size == 1) { + if (defined ($length{$sig})) { + if ($length{$sig} != $size) { + print " $sig\[$sdx\]$comma // node[$size] $port"; + } + else { + print " $sig\[0\]$comma // node[$size] $port"; + } + } + else { + print " $sig$comma // node[$size] $port"; + } + } + elsif ($ok) { + print " $sig$comma // node[$size] $port"; + } + elsif ($match) { + my $max=$size-1; + print " $sig\[0..$max\]$comma // node[$size] $port"; + } + else { + my @port=(); + foreach my $l (@list) { + my ($sig,$sdx,$port,$pdx)=split(/ /,$l); + $port[$pdx]=$sig; + $port[$pdx]="$sig\[$sdx\]" if $sdx >= 0; + } + print " \x7b $port[0],"; + my $x=0; + for ($x = 1; $x < $#port; $x++) { + print " $port[$x],"; + } + print " $port[$x]\x7d$comma // node[$size] $port"; + } + $n += $#list; + } + elsif (/^( *)node ([^ \[]+)\[(\d+)\];/) { + my $sp=$1; + my $node=$2; + my $ndx =$3; + my $min = $ndx; + my $max = $ndx; + my $i = 0; + while (/^ *node $node\[(\d+)\];/) { + $ndx = $1; + $min = $ndx if $ndx < $min; + $max = $ndx if $ndx > $max; + $i++; + $_=$lines[$n+$i]; + } + if ($min == 0) { + $max++; + $length{$node}=$max; + print "${sp}node[$max] $node;"; + } + else { + $length{$node}=$max+1; + print "${sp}node $node\[$min..$max\];"; + } + $n += $i-1; + } + else { + print; + } + } +} + +sub readportdirection { + my ($file) = @_; + local *X; + open (X, "<$file"); + my $module; + while () { + chomp; + my ($x,$y)=split; + if (/^MODULE/) { + $module=$y; + next; + } + if (defined ($y)) { + if ($x eq "input") { + $x = "-"; + } + elsif ($x eq "output") { + $x = "+"; + } + else { + $x = "+-"; + } + $portdirection{"$module $y"}=$x; + } + } +} +# sort port list +sub sortary { + my $an = $a; + $an =~ s/\[.*//; + my $bn = $b; + $bn =~ s/\[.*//; + my $av = $a; + $av =~ s/.*\[//; + $av =~ s/\]//; + my $bv = $b; + $bv =~ s/.*\[//; + $bv =~ s/\]//; + if ($an eq $bn) { + return $bv - $av; + } + $an cmp $bn; +} + +sub readbindfile { + my ($file)=@_; + local (*P,$_); + if (open (P, "<$file") ) { + while (

    ) { + chomp; + my ($cell, $instance, $pin, $signal) = split; + $bind{"$cell $instance $pin"}=$signal if defined $signal; + } + } +} + +sub createnodesx { + my $name = $_[0]; + my $file = "$name.nodesx"; + return if ( -s "$file" ); + local(*P,*Q,$_); + open (P, "cast_query --task=external_nodes=im:xr --max-heap-size=1G '--cast-path=$castdir:$specdir' '--cell=$name' |"); + open (Q, ">$file"); + $_=

    ; + while (

    ) { + chomp; + print Q; + } + close P; + close Q; +} + +sub usage { + print STDERR "$_[0]" if defined $_[0]; + my $cmd = $0; + $cmd =~ s:.*/::; + print STDERR < $subtype.cast + --cast-dir=

    + --spec-dir= + [--add-import=] + [--cdl=] + [--portfile=] + [--library=] + [--bindfile=] +$description +EU +exit 1; +} + +GetOptions( + "add-import=s" => sub { push @addimport, $_[1];}, + "cast-dir=s" => \$castdir, + "cdl-file=s" => \$cdl, + "port-file=s" => \$portfile, + "library=s" => \$library, + "bindfile=s" => \$bindfile, + "spec-dir=s" => \$specdir, + "subtype=i" => \$subtype, +) or usage; + +usage "cast-dir needed" if ! defined $castdir or ! -d "$castdir"; +usage "spec-dir needed" if ! defined $specdir or ! -d "$specdir"; +usage if ! defined $ARGV[0]; +my $arg=$ARGV[0]; +my $name=$arg; +$name =~ s/\.(\d+)$//; +my $argsubtype=$1; +my $argcell = $name; +my $deflib=( defined ($library) and $library ne ""); +$library = $name if ! $deflib; +$name =~ s/.*\.//; +$library =~ s/\.$name$// if ! $deflib; +$cdl="$name.sp" if ! $cdl; +if ($bindfile ne "" and -r $bindfile ) { + readbindfile($bindfile); +} +usage "Cannot read $cdl or need to define cdl-file" + if ( ! -f "$cdl" or ! -r "$cdl" ); + +foreach my $add (@addimport) { + $imports{"$add.*"}=1; +} + +my %defchans=(); + +sub getdefchanrefs { + local (*P,$_); + open (P, "find '$castdir' -name \\*.cast | xargs grep '^ *defchan ' |"); + while (

    ) { + chomp; + s:$castdir/::; + s/ *defchan/defchan/; + my ($path,$chan)=split; + $path =~ s/:.*//; + $path =~ s:/:.:g; + $path =~ s/\.cast//; + $chan =~ s/\(.*//; + $defchans{$chan}=$path; + } + close P; +} + +getdefchanrefs; + +sub dumcmp { + my $xa=$a; + my $xb=$b; + $xa=$a; # to prevent warnings + $xb=$b; + $xa=~ s/dummy//; + $xb =~ s/dummy//; + $xa-$xb; +} +my %definesubckts=(); +my %external=(); +my %channeldefs=(); + +sub getexternal { + my ($castcell)=@_; + return if defined $external{$castcell}; + local(*Q, *Y, $_); + if ( -r "$castcell.query.external") { + open (Q, "<$castcell.query.external"); + open (Y, ">/dev/null"); + } + else { + open (Q, "cast_query --cast-path='$castdir:$specdir' --task=external_nodes=all --cell='$castcell' --no-header 2>/dev/null |"); + open (Y, ">$castcell.query.external"); + } + while () { + chomp; + print Y; + push @{$external{$castcell}}, $_; + } + close Q; + close Y; +} + +my %ecanonical=(); +my %rcanonical=(); + +sub getports { + my ($cell)=@_; + my $castcell=$cell; + $castcell =~ s/\.[^\.]+$//; + return if (defined ($ports{$cell})); + print STDERR "getports($cell) = $castcell"; + my @ports; + my @implied; + my @external=(); + %ecanonical=(); + %rcanonical=(); + # first priority, find port list from cast + if ($cell =~ /\./) { # cannot be cast file without .'s + if ( -r "$cell.query.ports") { + open (P, "<$cell.query.ports"); + open (X, ">/dev/null"); + } + else { + open (P, "cast_query --cast-path='$castdir:$specdir' --task=external_nodes=im:xr,ports --cell='$castcell' --no-header 2>/dev/null |"); + open (X, ">$cell.query.ports"); + } + my $portlist; + my @castlines=(); + while (

    ) { + chomp; + print X; + print STDERR "getports: query $cell" if $. == 1; + if (/^[01] /) { + my ($implied, $type, $name)=split; + my $dir = ""; + if ($name =~ s/^([-+])//) { + $dir = $1; + } + if ($name =~ s/\[(\d+)\.\.(\d+)\]$//) { + my $lo=$1; + my $hi=$2; + if ($lo eq "0") { + $hi++; + $type = "$type\[$hi\]"; + } + else { + $type = "$type\[$lo..$hi\]"; + } + } + if ( ! ($type =~ /^node/) and ! defined ($channeldefs{"$type"})) { + foreach my $ex (@external) { + my ($en) = split(/ /,$ex); + my $p=$en; + $p =~ s/\..*//; + $p =~ s/\[.*//; + if ($p eq $name) { + my $ch=$en; + $ch =~ s/$name//; + print STDERR "CHD $name $en $ch $cell $type"; + push @{$channeldefs{"$type"}}, $ch; + } + } + } + push @castlines, "define \"XXXX\"() (" if ! @castlines; + if ($implied) { + push @implied, [$type, $name, $dir]; + } + else { + push @castlines, " $type $dir$name"; + push @ports, [$type, $name, $dir]; + } + print STDERR "getports $cell $type $name"; + } + else { # this comes first from cast_query + push @external, $_; + my ($p,$a)=split; + $ecanonical{$p}=$a; + $rcanonical{$a}=$p; + } + } + close P; + close X; + if (@ports) { + $castfound{$cell}=[@castlines]; + $castfound{$castcell}=[@castlines] if $castcell ne $cell; + $ports{$cell}=[@ports]; + $implied{$cell}=[@implied]; + return; + } + else { + print STDERR "getports: cannot cast_query for $cell"; + } + } + if (defined ($definesubckts{$cell})) { + my @pl = split(/ /,${@{$definesubckts{$cell}}}[0]); + shift @pl; + shift @pl; + foreach my $port (sort sortary @pl) { + push @ports, ["node",$port]; + } + $ports{$cell}=[@ports] if @ports; + print STDERR "getports (cdl) $cell : ", join(" ", @pl); + return; + } + my $localcell=$cell; + $localcell =~ s/\.\d+$//; + $localcell =~ s/.*\.//; + if (defined ($definesubckts{$localcell})) { + my @pl = split(/ /,${@{$definesubckts{$localcell}}}[0]); + shift @pl; + shift @pl; + foreach my $port (sort sortary @pl) { + push @ports, ["node",$port]; + } + $ports{$cell}=[@ports] if @ports; + print STDERR "getports (cdl) $cell : ", join(" ", @pl); + return; + } + print STDERR "getports: No defined SUBCKT nor cast for $cell"; +} + +sub readcdl { + my ($file)=@_; + local(*P,$_); + my $ln=""; + my $subckt=""; + + open (P, "<$file") or die "Cannot open $file"; + $ln =

    ; + chomp $ln; + while (

    ) { + chomp; + s/ *$//; + if (/^$/ or /^\*/ or /^\$/ or /^\.include/i ) { + next; + } + if (/^\+/) { + s/^\+/ /; + $ln .= $_; + } + else { + $ln =~ s/ */ /g; + if ($ln =~ /^\.subckt/i) { + my @f=split(/ /,$ln); + $subckt=cad2cast($f[1]); + $f[1] = $subckt; + push @{$definesubckts{$subckt}}, join(" ", @f); + } + elsif ($ln =~ /^\.ends/i) { + push @{$definesubckts{$subckt}},$ln; + $subckt=""; + } + elsif ($subckt ne "") { + if ($ln =~ /^x/i) { + my @f = split(/ /,$ln); + $f[1] = cad2cast($f[1]); + push @{$definesubckts{$subckt}}, join(" ", @f); + } + else { + push @{$definesubckts{$subckt}},$ln; + } + } + $ln = $_; + } + } + push @{$definesubckts{$subckt}},$ln if $ln ne "" and $subckt ne ""; +} + +readcdl "$cdl"; +close WR; +close RD; +waitpid $cpid, 0; + +if (! defined($portfile)) { + $portfile = $cdl; + $portfile =~ s/\.[^\.]*$//; + $portfile = "$portfile.ports"; +} +readportdirection($portfile); +$"=" "; + +my %cast=(); +my %spec=(); +my %cxref=(); +my %sxref=(); +# find all cells in the spec tree +# there are likely duplicates, especially with multiple subtypes +open (P, "find '$specdir' -name \\*.cast |"); +while (

    ) { + chomp; + s:$specdir/::; + s/:/ /; + s:/:.:g; + s/\.cast$//; + my $spec=$_; + my $cast=$_; + $cast =~ s/\.[^\.]+$//; + my $name = $cast; + $name =~ s/.*\.//; + $sxref{$name}=$spec; + $cxref{$name}=$cast; +} +close P; +my $portmap=$cdl; +$portmap =~ s/\.[^\.]+$/.portmap/; +if ( -r $portmap ) { + open (P, "<$portmap"); + open (Q, ">/dev/null"); +} +else { + open (P, "generate_port_mapping --cast-path='$castdir' --cell='$argcell' --verilog-block=rtl |"); + open (Q, ">$portmap"); +} +my %verilog=(); +my %castname=(); +while (

    ) { + chomp; + print Q; + my ($verilog,$cast)=split; + $verilog{$cast}=$verilog; + $castname{$verilog}=$cast; +} +close P; +close Q; +# find the cast file for this cell +my $castfile="$library"; +$castfile =~ s/\./\//g; +$castfile = $castdir."/".$castfile.".cast"; +if ( ! -f $castfile ) { + print STDERR "Cannot find original cast file at $castfile"; + exit 1; +} +# generate list of imports required +print STDERR "Reading $castfile"; +my %needimport=(); +open (P, "<$castfile"); +while (

    ) { + chomp; + s/^ *//; + last if (/^define/); + if (/^import /) { + my @f=split; + my $import=$f[1]; + $import =~ s/;//; + $imports{$import}=1; + } +} +close P; +my %nodes=(); + +sub getnodes { + my ($subckt)=@_; + %nodes=(); + foreach my $line (@{$definesubckts{$subckt}}) { + print STDERR "SUBCKT $subckt"; + if ($line =~ /^X/i and $line =~ /\$PINS/) { + my @f=split(/ /,$line); + shift @f; + my $name=shift @f; + shift @f; # $PINS + print STDERR "XLINE $name : $cast{$name} : $sxref{$name}"; + if ( ! defined ($cast{$name}) and defined ($sxref{$name})) { + $cast{$name} = $sxref{$name}; + } + if ( ! defined ($cast{$name}) and $name =~ /\./) { + $cast{$name} = $name; + } + if ( ! defined ($cast{$name})) { + print STDERR "Cannot find cast name for $name"; + $cast{$name}=$name; + } + getports($cast{$name}); + if (! defined ($spec{$name})) { + if (defined ($cast{$name})) { + $spec{$name}=$cast{$name}; + } + elsif (defined ($sxref{$name})) { + $spec{$name} = $sxref{$name}; + } + else { + $spec{$name} = $name; + } + } + foreach my $call (@f) { + my ($pin,$net)=split(/=/,$call); + if ($subckt eq "EPL" and defined ($castname{"$net"})) { + $net = $castname{"$net"}; + } + else { + $net =~ s/\//_slash_/g; + $net =~ s/\./_dot_/g; + $net =~ s/\[/_L_/g; + $net =~ s/\]/_R_/g; + $nodes{"$net"}="node $net"; + } + } + } + } +} + +# prints a file containing hierarchical cast which has to be parsed after +# to split into the various modules +my $module; +my $lastimport=0; +my %hasimports=(); +my $keep=0; +# get all of the ports for subckts from cast if possible +getports("$argcell.$argsubtype"); +foreach my $top (keys %definesubckts) { + if ($argcell eq "$library.$top") { + getports("$library.$top.$argsubtype"); + } + elsif ($top =~ /\./) { + getports("$top"); + } + else { + getports("$library.$top.0"); + } +} +# print each module one at a time from the cdl file +my %isport=(); +foreach my $top (sort keys %definesubckts) { + %bindnet=(); + %isport=%isportdefault; + getnodes($top); + my $name=""; + my $min = 10000; + my $max = -1; + my $castcell="$library.$top"; + my $st = $subtype; + if ($top =~ /\./) { + $castcell = $top; + $castcell =~ s/\.([^\.]+)$//; + $st = $1; + } + elsif ("$library.$top" eq "$argcell") { + $st = $argsubtype; + } + my $tc = "$castcell.$st"; + foreach my $x (sort keys %castfound) { + print STDERR "CFX $x"; + } + push @castlines, "module $castcell;"; + my $separatefromparent=0; + if ($castcell =~ /lib.synchronous.conversion.v3.SCAN_A2S\(\d+\)/) { + push @castlines, ""; + push @castlines, "import lib.synchronous.conversion.v3.base.*;"; + $separatefromparent=1; + } + push @castlines, ""; + push @castlines, "define \"$st\"() ("; + # make sure the necessary data has been gathered + # for this cell + getports("$tc"); + if (defined ($castfound{$tc})) { + # print cast header from cast information, most accurate + my @plines=@{$castfound{$tc}}; + foreach my $pn (1..$#plines-1) { + push @castlines, "$plines[$pn];"; + } + push @castlines, "$plines[$#plines]"; + my $parent = $tc; + $parent =~ s/\.[^\.]+$//; + if ($separatefromparent) { + push @castlines, " )(node -Vdd, -GND, -_RESET, +debug_ack) <+ cdc_nofloorplan <+ cdc_cell <: NULL \x7b"; + } + else { + push @castlines, " ) <: $parent \x7b"; + } + } + else { + # find ports from cdl, not accurate, but is all we have left. + my @ports = split(/ /,${@{definesubckts{$top}}}[0]); + shift @ports; + shift @ports; + foreach my $port (sort sortary @ports) { + # ports sorted by name and by array index + my $nm = $port; + $nm =~ s/\[.*//; + my $nv = $port; + $nv =~ s/.*\[//; + $nv =~ s/\]//; + $isport{$nm}=1; + if ($name ne $nm and $name ne "") { + my $dir = "+-"; + $dir = $portdirection{"$top $name"} if defined ($portdirection{"$top $name"}); + if ($min == 0 and $max > 0) { + # a full array + $max++; + push @castlines, " node[$max] $dir$name;"; + foreach my $nn (0..$max-1) { + $isport{"$nm\[$nn\]"}; + } + } + elsif ($min <= $max) { + # a partial array + push @castlines, " node $dir$name\[$min..$max\];"; + foreach my $nn ($min..$max) { + $isport{"$nm\[$nn\]"}; + } + } + else { + # just a node + push @castlines, " node $dir$name;"; + } + $name = $nm; + if ($nv =~ /^\d+$/) { + $max = $min = $nv; + } + else { + $max = -1 if defined $nv; + $min = 10000 if defined $nv; + } + } + $max = $nv if (($nv =~ /^\d+$/) and ($nv > $max)); + $min = $nv if ($nv =~ /^\d+$/) and $nv < $min; + $name = $nm; + } + my $dir = "+-"; + $dir = $portdirection{"$top $name"} if defined ($portdirection{"$top $name"}); + if ($min == 0 and $max > 0) { + $max++; + push @castlines, " node[$max] $dir$name"; + } + elsif ($min <= $max) { + push @castlines, " node $dir$name\[$min..$max\]"; + } + else { + push @castlines, " node $dir$name"; + } + push @castlines, " ) <+ synchronous <: PRIMITIVE \x7b"; + } + # from cast ports, determine the names which are ports + foreach my $ip (@{$implied{$tc}}) { + my ($t,$n,$d)=@{$ip}; + $isport{$n}=1; + print STDERR "IMPLIED $n $tc"; + } + foreach my $p (@{$ports{$tc}}) { + my ($t,$port)=@{$p}; + $isport{$port}=1; + if ($t =~ /^node\[(\d+)\]/) { + my $s = $1; + foreach my $i (0..$s-1) { + $castname{"$port\[$i\]"} = "$port\[$i\]"; + $isport{"$port\[$i\]"}=1; + } + } + elsif ( ! ($t =~ /^node/)) { + if (defined ($channeldefs{$t})) { + foreach my $ch (@{$channeldefs{$t}}) { + $castname{"$port.$ch"}="$port.$ch"; + $isport{"$port.$ch"}=1; + } + } + } + } + # find the dummy channels and nodes and assign them to the + # correct instance pin combinations + my $dummystart=100001; + my $dummynet=$dummystart; + %dummynetassign=(); + foreach my $line (@{$definesubckts{$top}}) { + # look at all instances now + if ($line =~ /^x/i) { + my @f=split(/ /,$line); + my $inst=shift @f; + my $name=shift @f; + shift @f; # $PINS + my %alias=(); + my %unalias=(); + # special handling for CDCs from Tahoe + createnodesx($name) + if ($name =~ /_CDC/ and ! -f "$name.nodesx"); + if (open (Q, "<$name.nodesx")) { + while () { + chomp; + my ($ext,$al)=split; + $alias{$ext}=$al; + $unalias{$al}=$ext; + } + close Q; + } + $cast{$name}="$name" if ( ! defined ($cast{$name})); + $inst =~ s/\[/_L_/g; + $inst =~ s/\]/_R_/g; + $inst =~ s/[\/\.]/_slash_/g; + $inst =~ s/^x//i; + my %net=(); + my %matched=(); + # go thru the list of pin=net assignments + foreach my $call (@f) { + my ($pin,$net)=split(/=/,$call); + if ($top eq "EPL" and defined ($castname{"$net"})) { + $net = $castname{"$net"}; + } + elsif ( ! $isport{$net}) { + $net =~ s/\[/_L_/g; + $net =~ s/\]/_R_/g; + $net =~ s/\//_slash_/g; + $net =~ s/\./_dot_/g; + } + if (! defined ($unalias{$pin})) { + $unalias{$pin}=$pin; + $alias{$pin}=$pin; + } + $net{$unalias{$pin}}=$net; + $matched{$unalias{$pin}}=0; + } + my $cn=$cast{$name}; + # names without dots + if (! ($cn =~ /\./)) { + $cn = "$library.$cn.0"; + $cast{$name}=$cn; + } + my @ps=(); + if (defined $ports{$cn}) { + @ps=@{$ports{$cn}}; + } + elsif (defined ($ports{$name})) { + @ps=@{$ports{$name}}; + } + my $net; + foreach my $ps (@ps) { + my ($type,$pn)=@{$ps}; + if (defined($bind{"$name $inst $pn"})) { + $bindnet{"$inst $pn"} = $bind{"$name $inst $pn"}; + } + elsif (defined ($bind{"$name * $pn"}) ) { + $bindnet{"$inst $pn"} = $bind{"$name * $pn"}; + } + if (! defined ($net{$pn})) { + if (defined ($bindnet{"$inst $pn"})) { + $net=$bindnet{"$inst $pn"}; + $nodes{$net} = "$type ".$net; + } + elsif ($pn eq "GND" or $pn eq "Vdd") { + } + else { + if ($type eq "node" and ! ($pn =~ /\[/) ) { + if ($pn ne "QN" and + ! ($pn eq "PO" and $name =~ /^pnl_/) and + ! ($pn eq "DIN" and $name =~ /^pnl_/)) { + $openpins{"dummy$dummynet"}="$pn $type $name $inst"; + print STDERR "DN OP1 $name $inst $pn $type dummy$dummynet"; + } + } + else { + $openpins{"dummy$dummynet"}="$pn $type $name $inst"; + print STDERR "DN OP2 $name $inst $pn $type dummy$dummynet"; + } + $net="dummy".$dummynet; + if ($pn =~ /\[(.*)/) { + $net .= '['.$1; + } + $nodes{"$net"}="$type $net"; + print STDERR "DN OP3 $name $inst $pn $type $net"; + } + print STDERR "DA '$top $inst $pn' = $dummynet"; + $dummynetassign{"$inst $pn"}=$dummynet; + $bindnet{"$inst $pn"}="dummy$dummynet"; + $dummynet++; + } + } + } + } + # add nodes from bind file + foreach my $b (keys %bind) { + my $n = $bind{$b}; + $n =~ s/\..*//; + $n =~ s/\[.*//; + $nodes{$bind{$b}}="node $bind{$b}" + if ($bind{$b} ne "GND" and $bind{$b} ne "Vdd" and ! $isport{$n}); + } + # now the body of the cell + push @castlines, " subcells {"; + # print nodes + foreach my $node (sort keys %nodes) { + my $n = $node; + $n =~ s/\..*//; + $n =~ s/_L_.*// if $n =~ /_R_$/; + $n =~ s/\[.*//; + my $string = $nodes{$node}; + push @castlines, " $string;" + if ($node ne "GND" and $node ne "Vdd" and ! $isport{$n}); + print STDERR "Skipping $string because port in $top" if $isport{$n}; + } + push @castlines, " aclk = debug_ack;" if $separatefromparent; + $dummynet=$dummystart; + my %dumxrf; + # print netlist + foreach my $line (@{$definesubckts{$top}}) { + if ($line =~ /^X/) { + my @f=split(/ /,$line); + my $inst=shift @f; + my $name=shift @f; + shift @f; # $PINS + my %alias=(); + my %unalias=(); + if (open (Q, "<$name.nodesx")) { + while () { + chomp; + my ($ext,$al)=split; + $alias{$ext}=$al; + $unalias{$al}=$ext; + } + close Q; + } + $inst =~ s/\[/_L_/g; + $inst =~ s/\]/_R_/g; + $inst =~ s/[\/\.]/_slash_/g; + $inst =~ s/^x//i; + my $i = $inst; + $i =~ s/_slash_X$//; + $i =~ s/_$//; + if (!($spec{$name} =~ /\./)) { + $spec{$name} = "$library.$spec{$name}.0"; + } + # instance declaration + push @castlines, " $spec{$name} $i("; + my %net=(); + my %matched=(); + foreach my $call (@f) { + my ($pin,$net)=split(/=/,$call); + if ($top eq "EPL" and defined ($castname{"$net"})) { + print STDERR "NET 0 $pin $net $inst"; + $net = $castname{"$net"}; + } + elsif (! $isport{$net}) { + $net =~ s/\[/_L_/g; + $net =~ s/\]/_R_/g; + $net =~ s/\//_slash_/g; + $net =~ s/\./_dot_/g; + } + if (! defined ($unalias{$pin})) { + $unalias{$pin}=$pin; + $alias{$pin}=$pin; + } + $net{$unalias{$pin}}=$net; + print STDERR "NET 1 $pin $unalias{$pin} $net $inst"; + $matched{$unalias{$pin}}=0; + } + my $cn=$cast{$name}; + my @ps=(); + if (defined $ports{$cn}) { + @ps=@{$ports{$cn}}; + } + elsif (defined ($ports{$name})) { + @ps=@{$ports{$name}}; + } + my @dxrf=(); # dummy cross ref + my %reassigned=(); + # special cases + if (! defined ($net{GND}) and defined ($bindnet{"$inst GND"})) { + $net{GND} = $bindnet{"$inst GND"}; + } + if (! defined ($net{GND}) and defined ($bind{"$name $inst GND"})) { + $net{GND} = $bind{"$name $inst GND"}; + } + if (! defined ($net{GND})) { + $net{GND} = "GND"; + } + if (! defined ($net{Vdd}) and defined ($bindnet{"$inst Vdd"})) { + $net{Vdd} = $bindnet{"$inst Vdd"}; + } + if (! defined ($net{Vdd}) and defined ($bind{"$name $inst Vdd"})) { + $net{Vdd} = $bind{"$name $inst Vdd"}; + } + if (! defined ($net{Vdd})) { + $net{Vdd} = "Vdd"; + } + if (! defined ($net{VDD}) and defined ($bindnet{"$inst VDD"})) { + $net{VDD} = $bindnet{"$inst VDD"}; + } + if (! defined ($net{VDD}) and defined ($bind{"$name $inst VDD"})) { + $net{VDD} = $bind{"$name $inst VDD"}; + } + if (! defined ($net{VDD})) { + $net{VDD} = "Vdd"; # note: NOT VDD but Vdd + } + foreach my $n (0..$#ps) { + my $ps=$ps[$n]; + my ($type,$pn)=@{$ps}; + next if (! defined ($type)); + if (! defined ($net{$pn})) { + if (defined ($dummynetassign{"$inst $pn"})) { + $dummynet=$dummynetassign{"$inst $pn"}; + $net{$pn}="dummy$dummynet"; + push @dxrf, [$pn,$net{$pn}]; + print STDERR "DXRF $inst $pn dummmy$dummynet"; + } + else { + print STDERR "$inst $pn not assigned dummy pin!"; + } + } + # override + if (defined($bindnet{"$inst $pn"}) and ($net{$pn} ne $bindnet{"$inst $pn"})) { + $reassigned{$net{$pn}}=1 if $net{$pn} =~ /^dummy/; + $net{$pn}=$bindnet{"$inst $pn"}; + } + my $atype=$type; + $atype =~ s/\[.*//; + $atype =~ s/\(.*//; + my $deftype=$defchans{"$atype"}; + $deftype = $atype if !defined $deftype; + if ("$atype" ne "node" and + ! ("$deftype" =~ /^standard\./) and + ! defined ($imports{"$deftype.*"}) and + ! defined ($imports{"$deftype.$atype"})) { + print STDERR "Need to import $deftype.$atype"; + $errs++; + $needimport{"$deftype.*"}=1 if defined $deftype; + $imports{"$deftype.*"}=1 if defined $deftype; + } + my $string = $net{$pn}; + my $s = " $string"; + $s .= "," if $n < $#ps; + push @castlines, "$s // $type $pn"; + $matched{$pn}=1 if ! ($net{$pn} =~ m/^dummy1/); + } + if ($cast{$name} =~ /\.lvttl\./) { + push @castlines, " )($net{VDD}, $net{GND});"; + $matched{VDD}=1; + $matched{GND}=1; + } + elsif ($cast{$name} =~ /\.lvds\./) { + push @castlines, " )($net{VDD}, $net{GND});"; + $matched{VDD}=1; + $matched{GND}=1; + } + elsif ($cast{$name} =~ /\.cdc\./) { + push @castlines, " )(Vdd, GND, $net{_reset});"; + $matched{_reset}=1; + } + elsif ($cast{$name} =~ /sIPCell/) { + push @castlines, " )(VddX, VddA, GND);"; + $matched{vdd}=1; + $matched{vddA}=1; + $matched{vss}=1; + } + elsif ($cast{$name} =~ /^lib.cam.sync_tcam.TCAM/) { + push @castlines, " )(Vdd, GND, $net{_reset});"; + $matched{VDD}=1; + $matched{VSS}=1; + $matched{_reset}=1; + } + elsif ($cast{$name} =~ /^vendor.artisan.memory/) { + push @castlines, " )(Vdd, GND);"; + $matched{VDD}=1; + $matched{VSS}=1; + } + else { + my @imp=(); + my $mismatch=0; + my $np=0; + foreach my $pn (sort keys %matched) { + $mismatch=1 if (! $matched{$pn}); + } +# if ($mismatch and defined ($implied{$cast{$name}})) + if (defined ($implied{$cast{$name}})) { + foreach my $ip (@{$implied{$cast{$name}}}) { + my ($t,$n,$d)=@{$ip}; + if ($n eq "Vdd" or $n eq "GND") { + $matched{$n}=1; + push @imp, $n; + } + elsif ($n eq "VDD") { + push @imp, "Vdd"; + $matched{$n}=1; + $np=1; + } + elsif ($n eq "vss" or $n eq "VSS") { + push @imp, "GND"; + $matched{$n}=1; + $np=1; + } + elsif (defined ($net{$n})) { + push @imp, $net{$n}; + $matched{$n}=1; + $np=1 if $n ne $net{$n}; + } + else { + push @imp, "_"; + $np = 1; + } + } + } +# while ($imp[$#imp] eq "_") { +# pop @imp; +# } + if (@imp and $np) { + my $s = " )("; + foreach my $n (0..$#imp-1) { + $s .= "$imp[$n], "; + } + push @castlines, $s."$imp[$#imp]);"; + } + else { + push @castlines, " );"; + } + } + # write out the dummy net assignments + foreach my $dxrf (@dxrf) { + my ($pn,$net)=@{$dxrf}; + my $pfx="A $pn"; + my $print = 0; + $pn =~ s/\[.*\]//; + foreach my $px (keys %net) { + my $px1 = $px; + $px1 =~ s/[^A-Za-z0-9_].*//; + my $px2 = $px; + $px2 =~ s/$px1//; + if ($px2 =~ /\[\d+_\d+\]/ ) { # handle two dimensions + $px2 =~ s/\[(\d+)_(\d+)\]/[$1,$2]/; + print STDERR "D $px2\n" if $print; + } + my $px3=$px2; + if ($px3 =~ /\.d\[(\d+)\]$/) { + $px3 =~ s/\.d\[(\d+)\]$/.$1/; + } + print STDERR "A $pn:$px:$px1:$px2:$net{$px}:$net" if $print; + if ($px1 eq $pn and $net{$px} ne $net) { + print STDERR "B $px $pn ${net}$px2" if $print; + print STDERR "C ${net}$px2=$net{$px};" if $print; + if (substr($net{$px}, length($net{$px})-length($px3)) eq $px3 and length($px3)) { + my $opx = substr($net{$px},0,length($net{$px})-length($px3)); + if ( defined ($dumxrf{$net})) { + if ($dumxrf{$net} ne $opx) { + print STDERR "AERR $net $opx $dumxrf{$net}" if $print; + } + } + else { + $dumxrf{$net} = $opx; + } + print STDERR "$pfx $net $px2 $net{$px} $px" if $print; + } + print STDERR "DXR $inst $top ${net}$px2=$net{$px}"; + push @castlines, " ${net}$px2=$net{$px};" if ! $reassigned{$net}; + $openpins{$net}=0; + $matched{$px}=1; + } + } + } + foreach my $pn (sort keys %matched) { + if (! $matched{$pn}) { + my $found = 0; + if (defined ($implied{$cast{$name}})) { + foreach my $ip (@{$implied{$cast{$name}}}) { + my ($t,$n,$d)=@{$ip}; + if ($n eq $pn) { + print STDERR "Unmatched implied pin $name $inst $pn $net{$pn}"; + $found = 1; + } + } + } + else { + print STDERR "no implied data for $cast{$name}"; + } + print STDERR "Unmatched $cast{$name} $inst $pn $net{$pn}" if ! $found; + $errs++; + } + } + } + } + push @castlines, " \x7d"; + push @castlines, "\x7d"; +} +foreach my $name (sort keys %implied) { + print STDERR "IMPLIED $name"; +} +open (OPEN, ">openpins.txt"); +foreach my $key (sort keys %openpins) { + my ($pin,$type,$cell,$inst)=split(/ /,$openpins{$key}); + print STDERR "pin $pin type $type of $cell inst $inst is open" if ($openpins{$key} ne "0"); + print OPEN "pin $pin type $type of $cell inst $inst is open" if ($openpins{$key} ne "0"); +} +close OPEN; +print STDERR "Completed with $errs error(s)" if $errs; +#print join("\n", @castlines); +fixup (@castlines); +exit $errs; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef2rp.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef2rp.pl new file mode 100755 index 0000000000..6cd4c8fedb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef2rp.pl @@ -0,0 +1,118 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +my $width=2.2; + +my @lines=(); +my $mode=0; +my %pincnt=(); +my $indent=""; +my $pin; +my $macro; +my %macro=(); +my @macro=(); +my %ispwr=(); +while (<>) { + chomp; + if (/^\s*MACRO\s+(\S+)/) { + $macro=$1; + push @{$macro{$macro}},$_; + } + elsif (/^END/ and defined $macro) { + push @{$macro{$macro}},$_; + undef $macro; + undef @macro; + @macro=(); + } + elsif (defined ($macro)) { + push @{$macro{$macro}},$_; + } + if (/^\s*PIN\s+(\S+)/) { + $pin=$1; + $pincnt{$macro}++; + } + if (/^\s*USE\s+(ground|power)/i) { + $ispwr{"$macro $pin"}=1; + $pincnt{$macro}--; + } + push @lines, $_; +} +$mode = 0; +foreach my $line (@lines) { + $_=$line; + if ($mode == 0) { + print; + if (/^\s*MACRO\s+(\S+)/) { + $macro=$1; + $mode=1; + domacro($macro); + } + next; + } + elsif (/^END/) { + $mode=0; + } +} + +sub domacro { + my ($macro)=@_; + my @lns=@{$macro{$macro}}; + my $pincnt = $pincnt{$macro}; + my $validpin=1; + my $delta = $width/($pincnt-1); + my $start = $delta; + foreach my $line (@lns) { + $_=$line; + if (/^END/) { + print; + last; + } + if (/^\s*CLASS/) { + print; + next; + } + if (/^\s*SYMMETRY/) { + print; + next; + } + if (/^(\s*)SIZE/ ) { + print "${1}SIZE $width BY 2.2 ;"; + next; + } + if (/^(\s*)ORIGIN/) { + print "${1}ORIGIN 0.0 0.0 ;"; + next; + } + if (/^(\s*)FOREIGN (\S+)/) { + print "${1}FOREIGN $2 0.0 0.0 ;"; + next; + } + if (/^\s*PIN\s+(\S+)/) { + $pin=$1; + $validpin=0; + $validpin=1 if ! $ispwr{"$macro $pin"}; + print if $validpin; + } + elsif (/^(\s*)DIRECTION/) { + $indent=$1; + print if $validpin; + } + elsif (/^\s*PORT/) { + print $_ if $validpin; + } + elsif (/^(\s*)END \Q$pin\Q/) { + my $indent=$1; + if ($validpin) { + print "${indent} LAYER M2 ;"; + printf "${indent} RECT %.2f %.2f %.2f %.2f ;\n", + $start, 2.0-$delta/2, $start+$delta/2, 2.0+$delta; + print "${indent} END"; + $start += $delta; + print; + } + } + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef_rename.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef_rename.pl new file mode 100755 index 0000000000..034169fe22 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/lef_rename.pl @@ -0,0 +1,100 @@ +#!/usr/intel/bin/perl -w +# Copyright 2004 Fulcrum Microsystems. All rights reserved. +# Authors: Kai He + +use FileHandle; +use IPC::Open2; + +$rename = "rename"; + +sub usage() { + die "Usage: $0 --from=[cast,cadence,gds2] --to=[cast,cadence,gds2] --infile=[infilename] --outfile=[outfilename]\n"; +} + +while (defined $ARGV[0] && $ARGV[0] =~ /^--(.*)/) { + ($flag,$value) = split('=',$1); + if ($flag eq "to") { + $to = $value; + shift @ARGV; + } elsif ($flag eq "from") { + $from = $value; + shift @ARGV; + } elsif ($flag eq "infile") { + $f_in = $value; + shift @ARGV; + } elsif ($flag eq "outfile") { + $f_out = $value; + shift @ARGV; + } else { + shift @ARGV; + } +} + +defined $to or usage(); +defined $from or usage(); +defined $f_out or usage(); +defined $f_in or usage(); + +$pid1=open2(*NODE_IN,*NODE_OUT,"$rename --type=node --from=$from --to=$to"); +$pid2=open2(*CELL_IN,*CELL_OUT,"$rename --type=cell --from=$from --to=$to"); + +sub node_rename { + print NODE_OUT $_[0]."\n"; + my $name=; + chomp($name); + return $name; +} +sub cell_rename { + print CELL_OUT $_[0]."\n"; + my $name=; + chomp($name); + return $name; +} + +open( SOURCE, "<$f_in") or die "Can't open '$f_in' for reading.\n"; +open( TARGET, ">$f_out") or die "Can't open '$f_out' for writing.\n"; + +$. = 0; +$pin=0; +$macro=0; + +while($line=){ + if ($line=~/\\/){$line=~s/\\//g;} + if ($line=~/^MACRO (\S+)\s*$/){ + $oldname=$1; + $newname=cell_rename($oldname); + $line=~s/^MACRO \Q$oldname\E/MACRO \Q$newname\E/; + $macro=1; + } elsif ( $line=~/^\s*FOREIGN (\S+)/){ + $oldname=$1; + $newname=cell_rename($oldname); + $line=~s/^(\s*FOREIGN) \Q$oldname\E/$1 \Q$newname\E/; + } elsif ( $line=~/^\s*PIN (\S+)\s*$/){ + $oldname=$1; + $newname=node_rename($oldname); + $line=~s/^(\s*PIN) \Q$oldname\E/$1 \Q$newname\E/; + $pin=1; + } elsif ( $pin && $line=~/^\s*END (\S+)\s*$/){ + $oldname=$1; + $newname=node_rename($oldname); + $line=~s/^(\s*END) \Q$oldname\E/$1 \Q$newname\E/; + $pin=0; + } elsif ( $macro && $line=~/^\s*END (\S+)\s*$/){ + $oldname=$1; + $newname=cell_rename($oldname); + $line=~s/^(\s*END) \Q$oldname\E/$1 \Q$newname\E/; + $macro=0; + } + print TARGET $line; +} + +close(SOURCE); +close(TARGET); + +close(CELL_IN); +close(CELL_OUT); +close(NODE_IN); +close(NODE_OUT); +waitpid( $pid1, 0); +waitpid( $pid2, 0); + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mk_instance_multi.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mk_instance_multi.pl new file mode 100755 index 0000000000..167fc5dae1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mk_instance_multi.pl @@ -0,0 +1,135 @@ +#!/usr/intel/bin/perl -w +use strict; +use Getopt::Long; +use File::Temp qw/tempfile/; +use File::Path qw/mkpath/; +use IPC::Open2; + +my $package_root = $0; +my $exe = $package_root; +$exe =~ s:.*/::; +if (! ($package_root =~ m:^/:)) { + my $pwd = `pwd`; + chomp $pwd; + $package_root = $pwd; + $package_root .= "/$0"; + $package_root =~ s:$exe$::; + $package_root =~ s://:/:g; + chdir $package_root; + $package_root = `pwd`; + chomp $package_root; + chdir $pwd; +} +else { + $package_root =~ s:/bin/$exe::; +} + +my $rename = "rename"; + +my $layoutPlus = 'layout'; +my $outdir = '.'; +my $defView = 'layout'; +my $pdkroot; +my $cadenceLog; + +sub usage { + return < ] + [ --command= (defaults to $layoutPlus) ] + [ --view= (defaults to $defView) ] + [ --outdir= (defaults to $outdir) ] + --fulcrum-pdk-root= +USAGE +} + +my $renamePid; +my ($renameIn, $renameOut); +sub renameCell { + my $cell = shift; + if (!$renamePid) { + $renamePid = open2($renameIn, $renameOut, "$rename --type=cell --from=cast --to=cadence"); + } + print $renameOut "$cell\n"; + my $renamed = <$renameIn>; + chomp($renamed); + return $renamed; +} + +sub getLibrary { + my $cell = shift; + if ($cell =~ /(.+)\.[^.]+\.[^.]+/) { + return $1; + } + return undef; +} + +my $result = GetOptions("command=s" => \$layoutPlus, + "view=s" => \$defView, + "outdir=s" => \$outdir, + "fulcrum-pdk-root=s" => \$pdkroot, + "cadence-log=s" => \$cadenceLog); + +die usage() . "Unable to parse command line arguments" if (!$result); +die usage() . "You must specify --fulcrum-pdk-root=" if(!$pdkroot); +die "$outdir is not a directory" if (-e $outdir && !-d $outdir); +-e $outdir || mkpath($outdir); +die "Output directory $outdir not writeable" unless (-w $outdir); + +my @todo = (); + +while() { + chomp; + my ($cell, $view, $library) = split; + $view = $defView unless defined($view); + $library = getLibrary($cell) unless defined($library); + die "Cannot get library for cell $cell" unless defined($library); + my $renamedCell = renameCell($cell); + die "Cannot rename cell $cell from CAST to Cadence" + unless defined($renamedCell); + push @todo, [ $library, $renamedCell, $view ]; +} + +my ($skillFh, $skillName) = tempfile(UNLINK => 1); + +print $skillFh < 1); + close($logFh); +} + +my $wrapper = $ENV{'CADENCE_WRAPPER_SCRIPT'} || "/usr/local/cadence/bin/ic"; +$wrapper = $ENV{IC_SCRIPT} if defined $ENV{IC_SCRIPT}; +my $command = "$wrapper $layoutPlus -nograph -replay \"$skillName\" -log \"$logName\" /dev/null"; +print "Running $command...\n"; +my $status = system($command); + +if ($status != 0) { + open($logFh, $logName); + while(<$logFh>) { + print STDERR $_; + } +} +close($renameIn) if ($renameIn); +close($renameOut) if ($renameOut); +waitpid $renamePid, 0 if ($renamePid); +exit $status >> 8; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt.pl new file mode 100644 index 0000000000..c305a0d2f2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt.pl @@ -0,0 +1,41 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +foreach my $file (@ARGV) { + open (P, "<$file"); + my $out=$file; + $out =~ s/\.cast//; + $out .= "_hvt.cast"; + open (Q, ">$out"); + while (

    ) { + chomp; + if (/^define\s+"([^"]+)"/) { + my $st=$1; + s/"$st"/"${st}_hvt"/; + } + if (/\s(gate|stack)/) { + s/\(1\)/(3)/; + s/\(1,1\)/(3,3)/; + } + if (/synthesis\.qdi\..*\.(\d)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (/lib\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (/chip\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + print Q; + } +} +close P; +close Q; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt_all.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt_all.pl new file mode 100644 index 0000000000..0675ad78a1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mkhvt_all.pl @@ -0,0 +1,206 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use Getopt::Long; + +open (FILE, "list_3.txt"); +open (FL, "list_4.txt"); + +while (my $se = ) { +chomp; + $se =~ s/\./\//g; + $se =~ s/[\s+]//g; + $k=0; + +open (FIL, "spec/HVT_skipcells.txt"); +while (my $line=) { + $line =~ s/\./\//g; + $line =~ s/[\s+]//g; + if ($se=~/$line/){ + $k=1; + last; + } + +} +close FIL; + + +if ($k!=1) +{ +$se ="spec/".$se; + $se =~ s/\./\//g; + $se =~ s/[\s+]//g; + $se.=".cast"; + + + +open (P, "<$se"); + my $out=$se; + $out =~ s/\.cast//; + $out .= "_hvt.cast"; + open (Q, ">$out"); + while (

    ) { + chomp; + if (/^define\s+"([^"]+)"/) { + my $st=$1; + s/"$st"/"${st}_hvt"/; + } + if (/\s(gate|stack)/) { + s/\(1\)/(3)/; + s/\(1,1\)/(3,3)/; + } + if (/synthesis\.qdi\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (/standard\.reset\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (!(/lib\.util\.spare\..*\.(\d+)\s/)) { + if (/lib\..*\.(\d+)(.?)\s/) { + my $st=$1.$2; + s/\.$st /\.${st}_hvt /; + }} + if (/chip\..*\.(\d+)(.?)\s/) { + my $st=$1.$2; + s/\.$st /\.${st}_hvt /; + } + print Q; + } + +close P; +close Q; + +} +} + +while (my $see = ) { +chomp; + $see =~ s/\./\//g; + $see =~ s/[\s+]//g; + $l=0; + open (FIL, "spec/HVT_skipcells.txt"); + while ($ss = ) { + $ss =~ s/\./\//g; + $ss =~ s/[\s+]//g; + + if ($see=~/$ss/){ + + $l=1; + last; + print "value of l is $l\n"; + } + } +close FIL; +if ($l!=1) +{ +$see ="spec/".$see; + $see =~ s/\./\//g; + $see =~ s/[\s+]//g; + $see.=".cast"; + + + +open (P, "<$see"); + my $out=$see; + $out =~ s/\.cast//; + $out .= "_hvt.cast"; + open (Q, ">$out"); + while (

    ) { + chomp; + if (/^define\s+"([^"]+)"/) { + my $st=$1; + s/"$st"/"${st}_hvt"/; + } + if (/\s(gate|stack)/) { + s/\(1\)/(3)/; + s/\(1,1\)/(3,3)/; + } + if (/synthesis\.qdi\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (/standard\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (!(/lib\.util\.spare\..*\.(\d+)\s/)) { + if (/^\s+(lib\.\S+)\s+([^+-\s]+);/) { + @sw = split( /\s+/,$_); + $found=0; + open (FIL, "spec/HVT_skipcells.txt"); + while ($sss = ) { + chomp $sss; + $sss =~ s/[\s+]//g; + + if ($sw[1]=~/$sss/){ + $found=1; + last; + } + } + close FIL; + if ($found!=1) + { + my $st=$1; + s/\ \Q$st\E /\ ${st}_hvt /; + + } + + } + } + if (/^\s+(chip\.\S+)\s+([^+-\s]+);/) { + @sw = split( /\s+/,$_); + $found=0; + open (FIL, "spec/HVT_skipcells.txt"); + while ($sss = ) { + chomp $sss; + $sss =~ s/[\s+]//g; + + if ($sw[1]=~/$sss/){ + $found=1; + last; + } + } + close FIL; + if ($found!=1) + { + my $st=$1; + s/\ \Q$st\E /\ ${st}_hvt /; + + } + + } + + if (/^\s+(core\.\S+)\s+([^+-\s]+);/) { + @sw = split( /\s+/,$_); + $found=0; + open (FIL, "spec/HVT_skipcells.txt"); + while ($sss = ) { + chomp $sss; + $sss =~ s/[\s+]//g; + + if ($sw[1]=~/$sss/){ + $found=1; + last; + } + } + close FIL; + if ($found!=1) + { + my $st=$1; + s/\ \Q$st\E /\ ${st}_hvt /; + + } + + } + + print Q; + } + +close P; +close Q; + +}} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mklvt.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mklvt.pl new file mode 100644 index 0000000000..db9d4ff559 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mklvt.pl @@ -0,0 +1,41 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +foreach my $file (@ARGV) { + open (P, "<$file"); + my $out=$file; + $out =~ s/\.cast//; + $out .= "_lvt.cast"; + open (Q, ">$out"); + while (

    ) { + chomp; + if (/^define\s+"([^"]+)"/) { + my $st=$1; + s/"$st"/"${st}_lvt"/; + } + if (/\s(gate|stack)/) { + s/\(1\)/(2)/; + s/\(1,1\)/(2,2)/; + } + if (/synthesis\.qdi\..*\.(\d)\s/) { + my $st=$1; + s/\.$st /\.${st}_lvt /; + } + if (/lib\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_lvt /; + } + if (/chip\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_lvt /; + } + print Q; + } +} +close P; +close Q; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mksvt.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mksvt.pl new file mode 100644 index 0000000000..4656e1b6b4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mksvt.pl @@ -0,0 +1,189 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use Getopt::Long; + +open (FILE, "list_3.txt"); +open (FL, "list_4.txt"); + +while (my $se = ) { +chomp; + $se =~ s/\./\//g; + $se =~ s/[\s+]//g; + $k=0; + $m=0; + + $line = "RESET"; + if ($se=~/$line/){ + $k=1; + } + $lin = "MBUF"; + if ($se=~/$lin/){ + $m=1; + } + +if ($k==1) +{ +$se ="spec/".$se; + $se =~ s/\./\//g; + $se =~ s/[\s+]//g; + $se.=".cast"; + + + +open (P, "<$se"); + my $out=$se; + $out =~ s/\.cast//; + $out .= "_hvt.cast"; + open (Q, ">$out"); + while (

    ) { + chomp; + if (/^define\s+"([^"]+)"/) { + my $st=$1; + s/"$st"/"${st}_hvt"/; + } + if (/\s(gate|stack)/) { + s/\(1\)/(3)/; + s/\(1,1\)/(3,3)/; + } + if (/synthesis\.qdi\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (/standard\.reset\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (!(/lib\.util\.spare\..*\.(\d+)\s/)) { + if (/lib\..*\.(\d+)(.?)\s/) { + my $st=$1.$2; + s/\.$st /\.${st}_hvt /; + }} + if (/chip\..*\.(\d+)(.?)\s/) { + my $st=$1.$2; + s/\.$st /\.${st}_hvt /; + } + print Q; + } + +close P; +close Q; + +} +if ($m==1) +{ +$se ="spec/".$se; + $se =~ s/\./\//g; + $se =~ s/[\s+]//g; + $se.=".cast"; + + + +open (P, "<$se"); + my $out=$se; + $out =~ s/\.cast//; + $out .= "_svt.cast"; + open (Q, ">$out"); + while (

    ) { + chomp; + if (/^define\s+"([^"]+)"/) { + my $st=$1; + s/"$st"/"${st}_svt"/; + } + if (/\s(gate|stack)/) { + s/\(2\)/(1)/; + s/\(2,2\)/(1,1)/; + } + if (/synthesis\.qdi\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (/standard\.reset\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (!(/lib\.util\.spare\..*\.(\d+)\s/)) { + if (/lib\..*\.(\d+)(.?)\s/) { + my $st=$1.$2; + s/\.$st /\.${st}_hvt /; + }} + if (/chip\..*\.(\d+)(.?)\s/) { + my $st=$1.$2; + s/\.$st /\.${st}_hvt /; + } + print Q; + } + +close P; +close Q; + +} + +} + +while (my $see = ) { +chomp; + $see =~ s/\./\//g; + $see =~ s/[\s+]//g; + + +$see ="spec/".$see; + $see =~ s/\./\//g; + $see =~ s/[\s+]//g; + $see.=".cast"; + + + +open (P, "<$see"); + my $out=$see; + $out =~ s/\.cast//; + $out .= "_svt.cast"; + open (Q, ">$out"); + while (

    ) { + chomp; + if (/^define\s+"([^"]+)"/) { + my $st=$1; + s/"$st"/"${st}_svt"/; + } + if (/\s(gate|stack)/) { + s/\(2\)/(1)/; + s/\(2,2\)/(1,1)/; + } + if (/standard\.reset\..*\.(\d+)\s/) { + my $st=$1; + s/\.$st /\.${st}_hvt /; + } + if (!(/lib\.util\.spare\..*\.(\d+)\s/)) { + if (/^\s+(lib\.\S+)\s+([^+-\s]+);/) { + @sw = split( /\s+/,$_); + $found=0; + open (FIL, "spec/SVT_skipcells.txt"); + while ($sss = ) { + chomp $sss; + $sss =~ s/[\s+]//g; + + if ($sw[1]=~/$sss/){ + $found=1; + last; + } + } + close FIL; + if ($found!=1) + { + my $st=$sw[1]; + s/\ \Q$st\E /\ ${st}_svt /; + + } + + } + } + + print Q; + } + +close P; +close Q; + +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mosaicify.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mosaicify.pl new file mode 100755 index 0000000000..35e924f626 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/mosaicify.pl @@ -0,0 +1,179 @@ +#!/usr/intel/bin/perl + +### This scripts takes in a file which is dumped with ( dbWriteSkill ) +my $input = $ARGV[0]; +my $output = $ARGV[1]; +### and outputs dbMosiac calls that replace the instances, which are assumed +### to be aon a grid +my %grid = (); +### + +open SKILL, "<$input" or die; +open OUT, ">$output" or die; + +@gridSmall = (4.8,9.6); +@gridBig = (9.6,9.6); + +$grid{"globals.fill.POLY"} = \@gridSmall; +$grid{"globals.fill.M1"} = \@gridSmall; +$grid{"globals.fill.M2"} = \@gridSmall; +$grid{"globals.fill.M3"} = \@gridSmall; +$grid{"globals.fill.M4"} = \@gridSmall; +$grid{"globals.fill.M5"} = \@gridSmall; +$grid{"globals.fill.M6"} = \@gridBig; +$grid{"globals.fill.M7"} = \@gridBig; + +$grid{"globals.fill.VIA12"} = \@gridSmall; +$grid{"globals.fill.VIA23"} = \@gridSmall; +$grid{"globals.fill.VIA34"} = \@gridSmall; +$grid{"globals.fill.VIA45"} = \@gridSmall; +$grid{"globals.fill.VIA56"} = \@gridBig; +$grid{"globals.fill.VIA67"} = \@gridBig; + +@m1 = ("globals.fill.VIA12"); +@m2 = ("globals.fill.VIA12","globals.fill.VIA23"); +@m3 = ("globals.fill.VIA23","globals.fill.VIA34"); +@m4 = ("globals.fill.VIA34","globals.fill.VIA45"); +@m5 = ("globals.fill.VIA45"); +@m6 = ("globals.fill.VIA67"); +@m7 = ("globals.fill.VIA67"); + +$via{"globals.fill.M1"} = \@m1; +$via{"globals.fill.M2"} = \@m2; +$via{"globals.fill.M3"} = \@m3; +$via{"globals.fill.M4"} = \@m4; +$via{"globals.fill.M5"} = \@m5; +$via{"globals.fill.M6"} = \@m6; +$via{"globals.fill.M7"} = \@m7; + +sub rownd{ + my $float = shift; + return int($float + 0.5); +} + +print OUT "CellView = ( geGetWindowCellView )\n"; + +@cells = (); + +while( ) { + my $line = $_; + + if( $line =~ /\"R0\"/ && defined($grid{$cell}) ) { + my ($coords) = split(" ",$_); + ($x,$y) = split(":",$coords); + $I = rownd($x / $gridX); + $J = rownd($y / $gridY); + $M{$cell} = $I if($I > $M{$cell}); + $N{$cell} = $J if($J > $N{$cell}); + $T = $TT{$cell}; + + $T->[$I][$J] = 1; + } + elsif( $line =~ /dbOpenCellViewByType\(\"(.*)\" \"(.*)\" \"(.*)\"\)/ ) { + ($lib,$cell,$view) = ($1,$2,$3); + ($gridX,$gridY) = @{$grid{$cell}}; + + $M{$cell} = 0; + $N{$cell} = 0; + $lib{$cell} = $lib; + $view{$cell} = $view; + my @T = (); + $TT{$cell} = \@T; + + if($gridX) { + push @cells,$cell; + } + + print "$cell, grid = $gridX $gridY\n"; + } +} + +foreach $cell (@cells) { + + my $T = $TT{$cell}; + my ($gridX,$gridY) = @{$grid{$cell}}; + my $M = $M{$cell}; + my $N = $N{$cell}; + my $lib = $lib{$cell}; + my $view = $view{$cell}; + + my @vias = @{$via{$cell}}; + + + foreach $viaCell (@vias) { + print "Removing redundant cells where there is already $viaCell\n"; + my ($viaT) = @{$TT{$viaCell}}; + for($I=0;$I<=$M;$I++) { + for($J=0;$J<=$N;$J++) { + if( $viaT->[$I][$J] == 1 || + $viaT->[$I][$J] == 2 ) { + $T->[$I][$J] = 0; + } + } + } + } + + print "Doing $M x $N raster of $lib $cell $view with $gridX x $gridY grid...\n"; + $I = 0; + $J = 0; + + print OUT "Master = ( dbOpenCellViewByType \"$lib\" \"$cell\" \"$view\" nil \"r\" )\n"; + + while($I<=$M) { + print "$I\n" if(($I%500) == 0); + + while($J<=$N) { + if( ($T->[$I][$J] == 1)) { + $IE = $I; + $JS = $J; + $JE = $J; + + while( $T->[$I][$JE] == 1 && $JE <= $N ) { + $JE++; + } + $JE--; + + while($IE <= $M) { + my $columnGood = 1; + #print "IS = $IS IE = $IE JS = $JS JE = $JE\n"; + for($JM=$JS;$JM<=$JE;$JM++) { + if($T->[$IE][$JM] != 1 ) { + #print "$IE $JM\n"; + $columnGood = 0; + last; + } + } + if($columnGood == 1) { + for($JM=$JS;$JM<=$JE;$JM++) { + $T->[$IE][$JM] = 2; + } + $IE++; + } else { + $IE--; + my $columns = $IE - $I + 1; + my $rows = $JE - $JS + 1; + my $x = $I * $gridX; + my $y = $JS * $gridY; + #print "Got one!\n"; + print OUT "( dbCreateSimpleMosaic CellView Master nil $x\:$y \"R0\" $rows $columns $gridY $gridX )\n"; + + last; + } + } + $J = $JE; + } + $J++; + } + if($J >= $N) { + $J = 0; + $I++; + } + } +} + + + + +close(OUT); +close(SKILL); + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstract.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstract.pl new file mode 100755 index 0000000000..c2925a334a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstract.pl @@ -0,0 +1,938 @@ +#!/usr/bin/perl -w +# +# Generate dfII abstract cellview from routed layout cellview for single cell, +# using Cadence Abstract Generator. P4 submit generated abstract. +# +# trj 11/29/04 +# +###################################################### +# setup +###################################################### +require 'ctime.pl'; +require 'flush.pl'; + +# +# usage +# +$toolName = "createAbstract"; +$toolRev = &ctime(time); +chop($toolRev); +$toolRev = '$Revision$$DateTime$'; +$toolRev =~ s/\$//g; +$toolRev =~ s/DateTime: //; +$logFile = "$toolName.log"; +$extract = "extract"; +$leaf = "leaf"; +$mid = "mid"; +$stdleaf = "stdleaf"; +$power = "power"; +$bbLeaf = "bbleaf"; +$bbSram = "bbsram"; +$absView = "abstract"; +$userAbsView = "abstract_edit"; +$extAbsView = "abstract_ext"; + +$usage = " +Usage: $toolName + [ --cdswd=

    ] : cadence working directory (default=cwd) + --cell=:: : source dfII cell specification + [ --client-spec= ] : p4 client-spec (required unless type=extract) + --dfII-dir= : dfII path + [ --edit-abstract ] : edit and regenerate existing abstract + --fulcrum-pdk-root= : pdk path + [ --log= ] : name of log file (default=$logFile) + [ --metal1pins ] : extract METAL1 and METAL2 pins (default=METAL3) + [ --metal2pins ] : extract METAL2 pins (default=METAL3) + [ --no-submit ] : do not submit abstract (default=submit) + [ --type={$leaf | $mid | $power | $extract | $stdleaf} ] : source cell type (default=$leaf) + + Notes: + 1. --type=$extract implies --no-submit and --metal1pins. All p4 operations omitted. + 2. --type=$stdleaf implies --metal1pins."; + + +# +# define celltypes & map to Abstract Generator bins +# +$extractBinName = "Extract"; +$stdLeafBinName = "StdLeaf"; +$leafBinName = "Leaf"; +$midBinName = "MidLevel"; +$powerBinName = "PowerGrid"; +$bbLeafBinName = "BlackBoxLeaf"; +$bbSramBinName = "BlackBoxSram"; +%cellTypes = ($extract, $extractBinName, + $stdleaf, $stdLeafBinName, + $leaf, $leafBinName, + $mid, $midBinName, + $power, $powerBinName, + $bbLeaf, $bbLeafBinName, + $bbSram, $bbSramBinName); + + +# +# default and initial values +# +$cdswd = ''; +$debug = 0; +$updateMd5sum = 0; +$editAbs = 0; +$submitAbs = 1; +$clientSpec = ""; +$changeList = ""; +$logOpen = 0; +$sumOpen = 0; +$errorCnt = 0; +$warningCnt = 0; +$cellType = $leaf; +$user = $ENV{'USER'}; +$cwd = $ENV{'PWD'}; +$absExist = 0; +$absP4Exist = 0; +$skipP4 = 0; +$m2pins = 0; +$m1pins = 0; + + +# +# define files & commands +# +$abGenOptFile = ".abstract.options"; +$abGenCmdFile = $toolName . "AG.cmd"; +$abGenLogFile = $toolName . "AG.log"; +$abGenCmd = "fulcrum ic abstract"; # Note: flow assumes ic = ic.50.33u3 +$cdsLib = "cds.lib"; + + +# command options file to look for in dfII cell directory +$cmdOptFileName = "abstract.log"; +$evalCmdOpt = 0; +$cmdOptFileFound = 0; +$cmdOpt = ''; +$cmdOptSrcView = ''; +@routedSrcViews = ("layout", "layout_abs"); + + +###################################################### +# parse command line +###################################################### +# +# display usage if no args +# +if ($#ARGV < 0) { + print "$usage\n\n"; + exit; +} + +# +# ignore command options if type=extract +# +for ($i=0; $i<=$#ARGV; $i++) { + if ($ARGV[$i] =~ /--type=$extract/) { + &echoMsg("\nINFO: Ignore command options for extract cell type.\n"); + $evalCmdOpt = 1; + last; + } +} + + +# +# parse args +# +while ($#ARGV>=0) { + + # --help + if ($ARGV[0] eq "--help") { + print "$usage\n\n"; + exit; + } + + # --debug (undocumented arg) + if ($ARGV[0] eq "--debug") { + $debug = 1; + shift(@ARGV); + next; + } + + # --update-md5sum (undocumented arg) + if ($ARGV[0] eq "--update-md5sum") { + $updateMd5sum = 1; + shift(@ARGV); + next; + } + + # + # load additional options once path to file derivable + # + if (!$evalCmdOpt && $srcLib && $srcCell && $dfiiDir) { + $srcLibPath = join('/', ($dfiiDir, split('\.',$srcLib))); + $cellName = &decodeName($srcCell); + $cmdOptFile = join('/', ($srcLibPath, $cellName, $cmdOptFileName)); + $evalCmdOpt = 1; + &echoMsg(" Looking for command option file: $cmdOptFile\n") if $debug; + if (-e $cmdOptFile) { + $cmdOptFileFound = 1; + &echoMsg(" Found command option file: $cmdOptFile\n") if $debug; + open(OPT, "$cmdOptFile") || &errorExit("Unable to open file '$cmdOptFile': $!\n"); + while () { + if (/$toolName options:\s+/) { + $cmdOpt = $'; + $cmdOpt =~ s/\n//g; + &echoMsg(" Command options: $cmdOpt\n") if $debug; + @cmdOptList = split('\s+', $cmdOpt); + foreach $cmd (@cmdOptList) { + push(@ARGV, $cmd); + &echoMsg(" Adding '$cmd' to ARGV\n") if $debug; + } + } + + if (/abstract source view:\s+(\S+)/) { + $cmdOptSrcView = $1; + } + } + close(OPT); + } + next; + } + + # --metal2pins + if ($ARGV[0] eq "--metal2pins") { + $m2pins = 1; + shift(@ARGV); + next; + } + + # --metal1pins + if ($ARGV[0] eq "--metal1pins") { + $m1pins = 1; + shift(@ARGV); + next; + } + + # --cdswd= + if ($ARGV[0] =~ /--cdswd=(\S+)/) { + $cdswd = $1; + shift(@ARGV); + next; + } + + # --cell=:: + if ($ARGV[0] =~ /--cell=(\S+):(\S+):(\S+)/) { + ($srcLib, $srcCell, $srcView) = ($1, $2, $3); + shift(@ARGV); + next; + } + + # --client-spec= + if ($ARGV[0] =~ /--client-spec=(\S+)/) { + $clientSpec = $1; + shift(@ARGV); + next; + } + + # --dfII-dir= + if ($ARGV[0] =~ /--dfII-dir=(\S+)/) { + $dfiiDir = $1; + shift(@ARGV); + next; + } + + # --edit-abstract + if ($ARGV[0] eq "--edit-abstract") { + $editAbs = 1; + shift(@ARGV); + next; + } + + # --fulcrum-pdk-root= + if ($ARGV[0] =~ /--fulcrum-pdk-root=(\S+)/) { + $pdkRoot = $1; + shift(@ARGV); + next; + } + + # --log= + if ($ARGV[0] =~ /--log=(\S+)/) { + $logFile = $1; + shift(@ARGV); + next; + } + + # --no-submit + if ($ARGV[0] eq "--no-submit") { + $submitAbs = 0; + shift(@ARGV); + next; + } + + # --type={leaf | mid | power | extract} + if ($ARGV[0] =~ /--type=(\w+)/) { + $cellType = $1; + shift(@ARGV); + next; + } + + # unknown argument + &errorExit("Unknown or invalid argument '$ARGV[0]'.\n $usage \n"); +} + + +###################################################### +# validate inputs +###################################################### +# +# set implied arguments +# +if ($cellType eq $extract) { + &echoMsg("INFO: Using special extract settings\n") if $debug; + $m1pins = 1; + $submitAbs = 0; + $skipP4 = 1; + $absView = $extAbsView; +} elsif ($cellType eq $stdleaf) { + $m1pins = 1; +} + + +# +# check for required arguments +# +&errorExit("--cell not specified.\n $usage \n") unless $srcLib; +&errorExit("Invalid cell type '$cellType'.\n $usage \n") unless $cellTypes{$cellType}; +&errorExit("--client-spec not specified.\n $usage \n") if !$skipP4 && !$clientSpec; +&errorExit("--dfII-dir not specified.\n $usage \n") unless $dfiiDir; +&errorExit("--fulcrum-pdk-root not specified.\n $usage \n") unless $pdkRoot; + +$m2pins = 1 if $m1pins; # inclusive option + + +# +# validate paths & files +# +if ($cdswd) { + &errorExit("cdswd '$cdswd' not found.\n") unless -e $cdswd; + &errorExit("cdswd '$cdswd' not a directory.\n") unless -d $cdswd; + chdir($cdswd) || &errorExit("Unable to cd to '$cdswd': $!\n"); + $cdsLib = $cdswd . "/" . $cdsLib; +} +&errorExit("cdswd ",$cdswd?$cdswd:$cwd," not a valid Cadence working directory.\n") unless -e $cdsLib; +&errorExit("dfII-dir '$dfiiDir' not found.\n") unless -e $dfiiDir; +&errorExit("dfII-dir '$dfiiDir' not a directory.\n") unless -d $dfiiDir; +&errorExit("fulcrum-pdk-root '$pdkRoot' not found.\n") unless -e $pdkRoot; +&errorExit("fulcrum-pdk-root '$pdkRoot' not a directory.\n") unless -d $pdkRoot; + +$abGenCfgFile = $pdkRoot . "/share/Fulcrum/nano/abstract.options.template"; +##$abGenCfgFile = "/home/user/tomjones/pdk/hw/layout/tsmc13/pdk/Fulcrum/nano/abstract.options.template"; +##&echoMsg("\n"); +##&warningMsg("#### USING LOCAL abstract.options.template FILE\n"); +&errorExit("Abstract Generator options file '$abGenCfgFile' not found.\n") unless -e $abGenCfgFile; + + +# +# log options +# +open(LOG, ">$logFile") || &errorExit("Unable to open log file '$logFile': $!\n"); +$logOpen = 1; +if ($logFile =~ /(\S+)\.log/) { + $sumFile = $1 . ".sum"; +} else { + $sumFile = substr($logFile, 0, length($logFile)-3); + $sumFile .= "sum"; +} +open(SUM, ">$sumFile") || &errorExit("Unable to open summary file '$sumFile': $!\n"); +$sumOpen = 1; + +# +# define command options used +# +$curCmdOpt = ""; +$curCmdOpt .= "--metal1pins " if $m1pins; +$curCmdOpt .= "--metal2pins " if $m2pins; +$curCmdOpt .= "--type=$cellType"; +$curOpt = $curCmdOpt ? $curCmdOpt : "NONE"; +$prevOpt = $cmdOpt ? $cmdOpt : "NONE"; +$prevCmdOptFile = $cmdOptFileFound ? $cmdOptFile : "NONE"; + +&echoMsg("\n$toolName, $toolRev\n"); +&echoMsg(" $toolName started at: ", &ctime(time)); +&echoMsg("\n"); +&echoMsg("Command options:\n"); +&echoMsg(" Options File = $prevCmdOptFile\n"); +&echoMsg(" Previous Options = $prevOpt\n"); +&echoMsg(" Current Options = $curOpt\n"); +&echoMsg("\n"); +if ($cmdOptFileFound) { + &warningMsg("Command options have changed.\n") if $prevOpt ne $curOpt; + &warningMsg("Abstract source view has changed.\n") if $srcView ne $cmdOptSrcView; +} + +&echoMsg("Source library options:\n"); +&echoMsg(" CDS Working Dir = $cdswd\n") if $cdswd; +&echoMsg(" pdkRoot = $pdkRoot\n") if $debug; +&echoMsg(" dfII-dir = $dfiiDir\n"); +&echoMsg(" libName = $srcLib\n"); +&echoMsg(" cellName = $srcCell\n"); +&echoMsg(" viewName = $srcView\n"); +&echoMsg(" cellType = $cellType\n"); +&echoMsg("\n"); +&echoMsg("Destination library options:\n"); +&echoMsg(" viewName = $absView\n"); +&echoMsg("\n"); +&echoMsg("NOTE: Allowing METAL2 signal pins.\n") if $m2pins && $cellType ne $stdleaf; +&echoMsg("NOTE: Allowing METAL1 signal pins.\n") if $m1pins && $cellType ne $stdleaf; +&echoMsg("\n") if $m2pins || $m1pins; +&echoMsg("Perforce options:\n"); +if ($skipP4) { + &echoMsg(" NONE\n"); +} else { + &echoMsg(" Edit existing abstract =", $editAbs?"TRUE":"FALSE", "\n"); + &echoMsg(" Submit generated abstract =", $submitAbs?"TRUE":"FALSE", "\n"); + &echoMsg(" Submission client spec = $clientSpec\n") if $clientSpec; +} +if ($updateMd5sum) { + &echoMsg("\n"); + &echoMsg("NOTE: Updating md5sum only. Abstract will not be generated.\n"); + &echoMsg("\n"); +} + + +# +# verify layout.cdb exists for source cellview +# +&echoMsg(" Verify source cellview exists...\n") if $debug; +$viewName = &decodeName($srcView); +$srcViewCDB = join('/',($srcLibPath, $cellName, $viewName, "layout.cdb")); +&echoMsg(" Source db file = $srcViewCDB\n") if $debug; +&errorExit("Source db file '$srcViewCDB' not found.\n") unless -e $srcViewCDB; +&echoMsg(" Source db file EXISTS.\n") if $debug; + + +# +# check for final layout source cellview +# +$routedSrcView = 0; +$routedSrcViewFound = 0; +foreach $view (@routedSrcViews) { + $routedSrcView = 1 if $view eq $srcView; +} +if (!$routedSrcView) { + foreach $view (@routedSrcViews) { + $viewName = &decodeName($view); + $viewCDB = join('/',($srcLibPath, $cellName, $viewName, "layout.cdb")); + $routedSrcViewFound = 1 if -e $viewCDB; + &errorMsg("Using source view '$srcView' when routed source view '$view' exists.\n") + if -e $viewCDB; + } +} + + +# +# initial p4 actions +# +if (!$skipP4) { + + # + # verify client spec + # + &echoMsg(" Verify client spec exists...\n") if $debug; + $cmd = "p4 clients"; + &echoMsg(" Command: $cmd\n") if $debug; + open(CMD, "$cmd |") || &errorExit("Unable to execute command '$cmd': $!\n"); + $clientFound = 0; + while () { + if (/Client\s+(\S+)\s+/ && $clientSpec eq $1) { + $clientFound = 1; + last; + } + } + close(CMD); + &errorExit("Client-spec '$clientSpec' not found.\n") unless $clientFound; + &echoMsg(" Client EXISTS.\n") if $debug; + + # + # create abstract cell log + # + &echoMsg(" Create abstract cell log...\n") if $debug; + $cmd = "createAbstractCellLog --cell=$srcLib:$srcCell:$srcView --client-spec=$clientSpec --dfII-dir=$dfiiDir --opt-str=\"$toolName options: $curCmdOpt\""; + $cmd .= " --debug" if $debug; + &echoMsg(" Command: $cmd\n") if $debug; + &echoMsg("==================================================\n") if $debug; + open(CMD, "$cmd |") || &errorMsg("Command '$cmd' failed: $!\n"); + @tmp = ; + close(CMD); + &echoMsg(@tmp) if $debug; + &echoMsg("==================================================\n") if $debug; +} +goto DONE if $updateMd5sum; + + +# +# check for existing abstract cellview +# +if (!$skipP4) { + &echoMsg(" Check for existing abstract cellview...\n") if $debug; + $absCDB = join('/',($srcLibPath, $cellName, "abstract/layout.cdb")); + &echoMsg(" Abstract db file = $absCDB\n") if $debug; + $absExist = 1 if -e $absCDB; + &echoMsg(" Abstract does", $absExist?"EXIST":"NOT exist", "\n") if $debug; + $userAbsCDB = join('/',($srcLibPath, $cellName, $userAbsView, "layout.cdb")); + if (-e $userAbsCDB) { + &echoMsg("\n"); + &warningMsg("Found modified abstract cellview '$userAbsView'.\n") ; + } + &errorExit("Abstract already exists. Use --edit-abstract to overwrite.\n") + if $absExist && !$editAbs; + &warningMsg("Missing command options file for existing abstract\n") if $absExist && !$cmdOptFileFound; +} + + +# +# create change list if submit +# +if ($submitAbs) { + # + # create a p4 change specification file + # + $cmd = "date +%C%y%m%d%H%M%S"; + open(CMD, "$cmd |") || &errorExit("Unable to execute command '$cmd': $!\n"); + $timestamp = ; + close(CMD); + + $changeSpecFile = "tmp." . $timestamp; + open(TMP, ">$changeSpecFile") || &errorExit("Unable to create file '$changeSpecFile': $!\n"); + print TMP "Change: new\n\n"; + print TMP "Client: $clientSpec\n\n"; + print TMP "User: $user\n\n"; + print TMP "Status: new\n\n"; + print TMP "Description:\n"; + print TMP "\tGenerate abstract for cell using $toolName.\n"; + close(TMP); + + # + # create change spec + # + &echoMsg(" Create change spec...\n") if $debug; + $cmd = "p4 change -i < $changeSpecFile"; + &echoMsg(" Command: $cmd") if $debug; + open(CMD, "$cmd |") || &errorExit("Unable to execute command '$cmd': $!\n"); + $tmp = ; + close(CMD); + if ($tmp =~ /Change\s+(\d+)\s+created/) { + $changeSpec = $1; + } else { + &errorExit("Unable to create p4 change specification.\n"); + } + &echoMsg(" Abstract change spec num = $changeSpec\n"); + $changeList = "--change-list=$changeSpec"; + system("rm $changeSpecFile"); +} + + +# +# open abstract for edit if it already exists +# +if ($absExist) { + &echoMsg("\nCheck out cell abstract for edit...\n"); + + # + # find depot path to abstract + # + &echoMsg(" Find depot root for cell...\n") if $debug; + $srcCellPath = join('/', ($srcLibPath, $cellName)); + &echoMsg(" SrcCellPath = $srcCellPath\n") if $debug; + $p4SrcCellPath = $srcCellPath; + $p4SrcCellPath =~ s/#/%23/g; + $cmd = "p4 dirs $p4SrcCellPath"; + &echoMsg(" Command: $cmd\n") if $debug; + open(CMD, "$cmd |") || &errorExit("Unable to execute command '$cmd': $!\n"); + $tmp = ; + close(CMD); + if ($tmp && $tmp =~ /^\/\/depot\//) { + $depotRoot = $tmp; + chop($depotRoot); + $depotRoot =~ s/\$/\\\$/g; + &echoMsg(" Depot Root = $depotRoot\n") if $debug; + } else { + &errorMsg("Depot Root not found.\n"); + $skipP4 = 1; + goto AG; + } + + + # + # check if abstract exists in perforce + # + &echoMsg(" Check if abstract exists in perforce...\n") if $debug; + $absPath = $p4SrcCellPath . "/abstract"; + &echoMsg(" absPath = $absPath\n") if $debug; + $cmd = "p4 dirs $absPath"; + &echoMsg(" Command: $cmd\n") if $debug; + open(CMD, "$cmd |") || &errorExit("Unable to execute command '$cmd': $!\n"); + $tmp = ; + close(CMD); + if ($tmp =~ /^\/\/depot\//) { + &echoMsg(" Abstract EXISTS in perforce.\n") if $debug; + $absP4Exist = 1; + } else { + &echoMsg(" Abstract does NOT exist in perforce.\n") if $debug; + } + + + # + # check if it is already open + # + if ($absP4Exist) { + &echoMsg(" Check if abstract already open for edit...\n") if $debug; + $cmd = "p4 opened"; + &echoMsg(" Command: $cmd\n") if $debug; + $depotTarget = $depotRoot . "/abstract/layout.cdb"; + &echoMsg(" Target = $depotTarget\n") if $debug; + open(CMD, "$cmd |") || &errorExit("Unable to execute command '$cmd': $!\n"); + $absOpen = 0; + $oldChangeNum = 0; + while () { + if (/$depotTarget/) { + &echoMsg(" Match = $_") if $debug; + $absOpen = 1; + + # save change number + if (/edit change (\d+)/) { + $oldChangeNum = $1; + &echoMsg(" Old edit change number = $oldChangeNum\n") if $debug; + } + last; + } + } + close(CMD); + &echoMsg(" Abstract", $absOpen?"OPEN":"NOT open", "\n") if $debug; + } + + + # + # reopen or edit + # + if ($absP4Exist) { + if (!$absOpen) { + $cmd = "cdsp4edit"; + $cmd .= " $changeList" if $submitAbs; + $cmd .= " --dfII-dir=$dfiiDir --view-name=abstract $srcCell"; + &echoMsg(" Exists and not open -- check out for edit...\n") if $debug; + &echoMsg(" Command: $cmd\n"); + print "\n"; + open(CMD, "$cmd |") || &errorMsg("Command '$cmd' failed: $!\n"); + @tmp = ; + close(CMD); + &echoMsg(" @tmp"); + } elsif ($submitAbs) { + @list = split('/', $depotTarget); + pop(@list); + $reopenTarget = join('/',(@list, "...")); + &echoMsg(" Reopen using current change spec...\n"); + $cmd = "p4 reopen -c $changeSpec $reopenTarget"; + &echoMsg(" Command: $cmd\n"); + print "\n"; + open(CMD, "$cmd |") || &errorMsg("Command '$cmd' failed: $!\n"); + @tmp = ; + close(CMD); + &echoMsg(" @tmp"); + + # delete old change number + $cmd = "p4 change -d $oldChangeNum > /dev/null"; + &echoMsg(" Delete old change number $oldChangeNum if empty\n") if $debug && $oldChangeNum; + &echoMsg(" Command: $cmd\n") if $debug && $oldChangeNum; + system($cmd) if $oldChangeNum; + } else { + &echoMsg(" Already open"); + } + &echoMsg("\n"); + } +} + + +###################################################### +# create Abstract Generator command file +###################################################### +AG: +open(CMD, ">$abGenCmdFile") || &errorExit("Unable to open command file '$abGenCmdFile': $!\n"); +print CMD "######################################################\n"; +print CMD "#\n"; +print CMD "# Abstract Generator command file \n"; +print CMD "#\n"; +print CMD "# Created by: $toolName, $toolRev\n"; +print CMD "# ", &ctime(time); +print CMD "#\n"; +print CMD "# Command options:\n"; + +if ($cmdOptFileFound) { + print CMD "# Options File = $cmdOptFile\n"; + print CMD "# Command Options = $cmdOpt\n"; + print CMD "# \n"; +} else { + print CMD "# Command Options = NONE\n"; + print CMD "# \n"; +} + +print CMD "# Source library options:\n"; +print CMD "# dfII-dir = $dfiiDir\n"; +print CMD "# libName = $srcLib\n"; +print CMD "# cellName = $srcCell\n"; +print CMD "# viewName = $srcView\n"; +print CMD "# cellType = $cellType\n"; +print CMD "#\n"; +print CMD "# Destination library options:\n"; +print CMD "# viewName = $absView\n"; +print CMD "#\n" if $m2pins || $m1pins; +print CMD "# NOTE: Allowing METAL2 signal pins.\n" if $m2pins; +print CMD "# NOTE: Allowing METAL1 signal pins.\n" if $m1pins; +print CMD "#\n"; +print CMD "######################################################\n"; +print CMD "\n"; +print CMD "# load library\n"; +print CMD "absSetLibrary \"$srcLib\"\n"; +print CMD "\n"; +print CMD "# define source view\n"; +print CMD "absSetOption \"ViewLayout\" \"$srcView\"\n"; +print CMD "\n"; + +if ($cellType eq $extract) { + print CMD "# define destination view\n"; + print CMD "absSetOption \"ViewAbstract\" \"abstract_ext\"\n"; + print CMD "\n"; +} + +print CMD "# reset bins by moving all cells to Block\n"; +print CMD "absSelectBinFrom \"Core\" \"PowerGrid\"\n"; +print CMD "absSelectCells\n"; +print CMD "absMoveSelectedCellsToBin \"Block\"\n"; +print CMD "absDeselectBinFrom \"Core\" \"$cellTypes{$power}\"\n"; +print CMD "\n"; +print CMD "# move target cell to appropriate bin\n"; +print CMD "absSelectBinFrom \"Block\" \"Block\"\n"; +print CMD "absDeselectCells\n"; +print CMD "absSelectCellFrom \"$srcCell\" \"$srcCell\"\n"; +print CMD "absMoveSelectedCellsToBin \"$cellTypes{$cellType}\"\n"; +print CMD "absDeselectBinFrom \"Block\" \"Block\"\n"; +print CMD "absSelectBinFrom \"$cellTypes{$cellType}\" \"$cellTypes{$cellType}\"\n"; +print CMD "absDeselectCells\n"; +print CMD "\n"; + +if ($cellType ne $extract) { + if ($m1pins) { + print CMD "# allow metal2 and metal1 pins\n"; + print CMD "absSetBinOption \"$cellTypes{$cellType}\" \"ExtractPinLayersSig\"", + " \"METAL1 METAL2 METAL3 METAL4 METAL5 METAL6 METAL7\"\n"; + print CMD "absSetBinOption \"$cellTypes{$cellType}\" \"ExtractPinLayersPwr\"", + " \"METAL1 METAL2 METAL3 METAL4 METAL5 METAL6 METAL7\"\n"; + print CMD "\n"; + } elsif ($m2pins) { + print CMD "# allow metal2 pins\n"; + print CMD "absSetBinOption \"$cellTypes{$cellType}\" \"ExtractPinLayersSig\"", + " \"METAL2 METAL3 METAL4 METAL5 METAL6 METAL7\"\n"; + print CMD "absSetBinOption \"$cellTypes{$cellType}\" \"ExtractPinLayersPwr\"", + " \"METAL2 METAL3 METAL4 METAL5 METAL6 METAL7\"\n"; + print CMD "\n"; + } +} + +print CMD "# create abstract and update properties\n"; +print CMD "absSelectCellFrom \"$srcCell\" \"$srcCell\"\n"; +print CMD "absAbstract\n"; +print CMD "absSetCellProp \"$srcCell\" \"symmetry\" \"X Y\"\n"; +print CMD "absSetCellProp \"$srcCell\" \"prCellClass\" \"cover\"\n" if ($cellType eq $power); +print CMD "\n"; +print CMD "# done\n"; +print CMD "absExit\n"; +close(CMD); + + +###################################################### +# Invoke Abstract Generator +###################################################### +# +# copy AG options file to src lib +# +&errorExit("Abstract Generator options template file '$abGenCfgFile' not found\n") + unless -e $abGenCfgFile; +&echoMsg(" Copy $abGenCfgFile to $srcLibPath/$abGenOptFile\n") if $debug; +system("cp $abGenCfgFile $srcLibPath/$abGenOptFile"); +open(OPT, "$srcLibPath/$abGenOptFile") || + &errorExit("Unable to open options file '$srcLibPath/$abGenOptFile': $!\n"); +while () { + if (/(Revision.*)/) { + $abGenCfgRev = $1; + $abGenCfgRev =~ s/\$//g; + $abGenCfgRev =~ s/\;//g; + $abGenCfgRev =~ s/DateTime: //; + last; + } +} +close(OPT); + + +# +# append ViewLayout option to end of AG options file +# (This is done to prevent false errors if view is other than 'layout'. +# It is not clear why this is necessary, but it seems to work.) +# +if ($srcView ne "layout") { + open(OPT, ">>$srcLibPath/$abGenOptFile") || + &errorExit("Unable to open options file '$srcLibPath/$abGenOptFile': $!\n"); + print OPT "absSetOption( \"ViewLayout\" \"$srcView\")\n"; + close(OPT); +} + + +# +# invoke AG +# +&echoMsg("\nInvoking Abstract Generator...\n"); +&echoMsg(" Using Abstract Generator Options, $abGenCfgRev\n"); +$cmd = "$abGenCmd -tcl -nogui -replay $abGenCmdFile -log $abGenLogFile"; +&echoMsg(" Command: $cmd\n\n"); +open(CMD, "$cmd |") || &errorMsg("Command '$cmd' failed: $!\n"); +@tmp = ; +close(CMD); +&echoMsg(@tmp); +&echoMsg("\n"); + + +###################################################### +# check abstract generator log for errors +###################################################### +open(AGLOG, "$abGenLogFile") || &errorExit("Unable to open log file '$abGenLogFile': $!\n"); +$abGenErrors = 0; +$abGenWarnings = 0; +while () { + $abGenErrors++ if /^\s*ERROR\s+/; + $abGenWarnings++ if /^\s*\*WARNING\*\s+/; + + # flag dbCopyCellView WARNING as ERROR + if (/^\s*\*WARNING\*\s+dbCopyCellView:\s*(.*)\s*Copy aborted/) { + $abGenErrors++; + $reason = $1; + if ($lastLine =~ /^\s*\*WARNING\*\s+dbCopyCellView:\s*(.*)/) { + $reason = $1; + } + &echoMsg("\nERROR: Copy aborted -- $reason.\n\n"); + } + $lastLine = $_; +} +close(AGLOG); + +# +# update accumulated errors and warnings +# +$errorCnt += $abGenErrors; +$warningCnt += $abGenWarnings; +$submitAbs = 0 if $abGenErrors; + +# +# log status +# +&echoMsg(" Abstract Generator Status:", $abGenErrors?"FAILURE":"SUCCESS", "\n"); +&echoMsg(" Warnings: $abGenWarnings\n"); +&echoMsg(" Errors: $abGenErrors\n"); +&echoMsg(" Log File: $abGenLogFile\n"); +&echoMsg("\n"); +goto DONE if $abGenErrors; + + +###################################################### +# submit abstract +###################################################### +goto DONE if $skipP4; + +# +# p4 add if new cellview +# +if (!$absExist || !$absP4Exist) { + &echoMsg("Add cell abstract...\n"); + $cmd = "cdsp4add"; + $cmd .= " $changeList" if $submitAbs; + $cmd .= " --dfII-dir=$dfiiDir --view-name=abstract $srcCell"; + &echoMsg(" Command: $cmd\n"); + print "\n"; + open(CMD, "$cmd |") || &errorMsg("Command '$cmd' failed: $!\n"); + @tmp = ; + close(CMD); + &echoMsg(@tmp); + &echoMsg("\n"); +} + + +# +# p4 submit +# +if ($submitAbs) { + &echoMsg("Submit cell abstract...\n"); + $cmd = "cdsp4submit --change-list=$changeSpec"; + &echoMsg(" Command: $cmd\n"); + print "\n"; + open(CMD, "$cmd |") || &errorMsg("Command '$cmd' failed: $!\n"); + @tmp = ; + close(CMD); + &echoMsg(@tmp); + &echoMsg("\n"); +} + + +###################################################### +# Done. +###################################################### +DONE: +&exitSummary; + + +###################################################### +# functions +###################################################### +# echo output to std & log +sub echoMsg { + print "@_"; + print LOG "@_" if $logOpen; +} + +# error exit +sub errorExit { + &echoMsg("\nERROR: @_ \n"); + if( $sumOpen ) { + print SUM "$toolName FAILED.\n"; + print SUM "\nERROR: @_ \n"; + } + exit 1; +} + +# display error msg +sub errorMsg { + &echoMsg("ERROR: @_\n"); + $errorCnt++; +} + +# display warning msg +sub warningMsg { + &echoMsg("WARNING: @_\n"); + $warningCnt++; +} + +# decode dfii name -- change \W to #xx +sub decodeName { + my $name = $_[0]; + if ($name =~ /\W/) { + $name = $` . "#" . sprintf("%x", ord($&)) . &decodeName($'); + } + return($name); +} + +# normal exit print summary file +sub exitSummary { + &echoMsg("$toolName finished at ", &ctime(time)); + &echoMsg(" Warnings: $warningCnt\n"); + &echoMsg(" Errors: $errorCnt\n"); + &echoMsg("\n"); + close(LOG); + print SUM "$toolName finished at ", &ctime(time); + print SUM " Warnings: $warningCnt\n"; + print SUM " Errors: $errorCnt\n"; + close(SUM); + exit; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstractCellLog.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstractCellLog.pl new file mode 100755 index 0000000000..81f70d8fae --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/createAbstractCellLog.pl @@ -0,0 +1,410 @@ +#!/usr/intel/bin/perl -w +# +# Generate abstract.log file with md5sum of source view and optional +# tool parameters. +# +# trj 4/27/06 +# +###################################################### +# setup +###################################################### +use strict; + +require 'ctime.pl'; +require 'flush.pl'; + + +# +# usage +# +my $toolName = "createAbstractCellLog"; +my $toolRev = &ctime(time); +chop($toolRev); +$toolRev = '$Revision: #2 $$DateTime: 2006/03/16 13:44:22 $'; +$toolRev =~ s/\$//g; +$toolRev =~ s/DateTime: //; +my $logFile = "$toolName.log"; +my $cellLogFileName = "abstract.log"; + +my $usage = " +Usage: $toolName + --cell=:: : source dfII cell specification + [ --cell-log= ] : name of abstract cell log file (default=$cellLogFileName) + [ --client-spec= ] : p4 client-spec + --dfII-dir= : dfII path + [ --tool-log= ] : name of tool log file (default=$logFile) + [ --str= ] : optional string to include in log file. Enclose + in quotes if string contains spaces. Use '\\n' to + separate multiple lines."; + + +# +# default and initial values +# +my $debug = 0; +my $clientSpec = ""; +my $optStr = ""; +my $errorCnt = 0; +my $warningCnt = 0; +my $logOpen = 0; +my $skipP4 = 0; +my $user = $ENV{'USER'}; +my $cellLogFileFound = 0; + + +###################################################### +# parse command line +###################################################### +# +# display usage if no args +# +if ($#ARGV < 0) { + print "$usage\n\n"; + exit; +} + +# +# parse args +# +my $srcLib; +my $srcCell; +my $srcView; +my $dfiiDir; +my @optStrList; +my $srcLibPath; +my $cellName; +my $srcCellPath; + +while ($#ARGV>=0) { + + # --help + if ($ARGV[0] eq "--help") { + print "$usage\n\n"; + exit; + } + + # --debug (undocumented arg) + if ($ARGV[0] eq "--debug") { + $debug = 1; + shift(@ARGV); + next; + } + + # --cell=:: + if ($ARGV[0] =~ /--cell=(\S+):(\S+):(\S+)/) { + ($srcLib, $srcCell, $srcView) = ($1, $2, $3); + shift(@ARGV); + next; + } + + # --cell-log= + if ($ARGV[0] =~ /--cell-log=(\S+)/) { + $cellLogFileName = $1; + shift(@ARGV); + next; + } + + # --client-spec= + if ($ARGV[0] =~ /--client-spec=(\S*)/) { + $clientSpec = $1; + shift(@ARGV); + next; + } + + # --dfII-dir= + if ($ARGV[0] =~ /--dfII-dir=(\S+)/) { + $dfiiDir = $1; + shift(@ARGV); + next; + } + + # --tool-log= + if ($ARGV[0] =~ /--tool-log=(\S+)/) { + $logFile = $1; + shift(@ARGV); + next; + } + + # --opt-str= + if ($ARGV[0] =~ /--opt-str=(.*)/) { + $optStr = $1; + @optStrList = split('\\\n', $optStr); + shift(@ARGV); + next; + } + + # unknown argument + &errorExit("Unknown or invalid argument '$ARGV[0]'.\n $usage \n"); +} + + +###################################################### +# validate inputs +###################################################### +# +# check for required arguments +# +if (!$clientSpec) { + warningMsg("No client-spec given, p4 operations will be skipped."); + $skipP4=1; +} +&errorExit("--cell not specified.\n $usage \n") unless $srcLib; +&errorExit("--dfII-dir not specified.\n $usage \n") unless $dfiiDir; + + +# +# validate paths & files +# +&errorExit("dfII-dir '$dfiiDir' not found.\n") unless -e $dfiiDir; +&errorExit("dfII-dir '$dfiiDir' not a directory.\n") unless -d $dfiiDir; +$srcLibPath = join('/', ($dfiiDir, split('\.',$srcLib))); +$cellName = &decodeName($srcCell); +$srcCellPath = join('/', ($srcLibPath, $cellName)); +&errorExit("Source cell path '$srcCellPath' not found.\n") unless -e $srcCellPath; +&errorExit("Source cell path '$srcCellPath' not a directory.\n") unless -d $srcCellPath; + + +# +# log options +# +if (open(LOG, ">$logFile")) { + $logOpen = 1; +} else { + &errorMsg("Unable to open log file '$logFile': $!\n"); +} + +&echoMsg("\n$toolName, $toolRev\n\t", &ctime(time)); +&echoMsg("\n"); +&echoMsg("Command options:\n"); +&echoMsg(" Lib Name = $srcLib\n"); +&echoMsg(" Cell Name = $srcCell\n"); +&echoMsg(" View Name = $srcView\n"); +&echoMsg(" Client Spec = $clientSpec\n"); +&echoMsg(" dfII dir = $dfiiDir\n"); +if ($optStr) { + &echoMsg(" Opt String = $optStrList[0]\n"); + for(my $i=1; $i<=$#optStrList; $i++) { + &echoMsg(" $optStrList[$i]\n"); + } +} +&echoMsg("\n"); + + +# +# find cell log file +# +my $cellLogFile = join('/', ($srcCellPath, $cellLogFileName)); +&echoMsg(" Looking for cell log file: $cellLogFile\n") if $debug; +if (-e $cellLogFile) { + $cellLogFileFound = 1; + if ($debug) { + &echoMsg(" Found cell log file\n"); + open(OPT, "$cellLogFile") || &errorMsg("Unable to open file '$cellLogFile': $!\n"); + while() { + &echoMsg(" $_"); + } + } +} else { + &echoMsg(" Cell log file NOT FOUND\n"); +} + + +# +# verify layout.oa exists for source cellview +# +&echoMsg("\n") if $debug; +&echoMsg(" Verify source cellview exists...\n") if $debug; +my $viewName = &decodeName($srcView); +my $srcViewCDB = join('/',($srcCellPath, $viewName, "layout.oa")); +&echoMsg(" Source cdb file = $srcViewCDB\n") if $debug; +&errorExit("Source cdb file '$srcViewCDB' not found.\n") unless -e $srcViewCDB; +&echoMsg(" Source cdb file EXISTS.\n") if $debug; + + +# +# initial p4 actions +# +if (!$skipP4) { + + # + # verify client spec + # + &echoMsg("\n") if $debug; + &echoMsg(" Verify client spec exists...\n") if $debug; + my $cmd = "p4 clients"; + &echoMsg(" Command: $cmd\n") if $debug; + open(CMD, "$cmd 2>\&1 |") || &errorExit("Unable to execute command '$cmd': $!\n"); + my $clientFound = 0; + while () { + if (/Client\s+(\S+)\s+/ && $clientSpec eq $1) { + $clientFound = 1; + last; + } + } + close(CMD); + &errorExit("Client-spec '$clientSpec' not found.\n") unless $clientFound; + &echoMsg(" Client EXISTS.\n") if $debug; + + + # + # create a p4 change specification file + # + &echoMsg("\n") if $debug; + &echoMsg(" Create cell log p4 change spec...\n"); + $cmd = "date +%C%y%m%d%H%M%S"; + open(CMD, "$cmd 2>\&1 |") || &errorExit("Unable to execute command '$cmd': $!\n"); + my $timestamp = ; + chop($timestamp); + close(CMD); + + my $cmdChangeSpecFile = "tmp." . $timestamp; + open(TMP, ">$cmdChangeSpecFile") || &errorExit("Unable to create file '$cmdChangeSpecFile': $!\n"); + print TMP "Change: new\n\n"; + print TMP "Client: $clientSpec\n\n"; + print TMP "User: $user\n\n"; + print TMP "Status: new\n\n"; + print TMP "Description:\n"; + print TMP "\tSave abstract options and md5sum.\n"; + close(TMP); + &echoMsg(" File $cmdChangeSpecFile created.\n") if $debug; + + + # + # create change spec + # + $ENV{'P4CLIENT'} = $clientSpec; + delete $ENV{'P4CONFIG'}; + $cmd = "p4 change -i < $cmdChangeSpecFile"; + &echoMsg(" Command: $cmd\n") if $debug; + open(CMD, "$cmd 2>\&1 |") || &errorExit("Unable to execute command '$cmd': $!\n"); + my $tmp = ; + close(CMD); + my $cmdChangeSpec; + if ($tmp =~ /Change\s+(\d+)\s+created/) { + $cmdChangeSpec = $1; + } else { + &errorExit("Unable to create p4 change specification.\n"); + } + &echoMsg(" P4 change spec num = $cmdChangeSpec\n"); + my $cmdChangeList = "--change-list=$cmdChangeSpec"; + system("rm $cmdChangeSpecFile"); + + + # + # edit cell logs file if it exists + # + if ($cellLogFileFound) { + &echoMsg("\n") if $debug; + &echoMsg(" P4 edit cell log...\n"); + $cmd = "cdsp4edit $cmdChangeList --dfII-dir=$dfiiDir --file=$cellLogFileName $srcCell"; + &echoMsg(" Command: $cmd\n") if $debug; + open(CMD, "$cmd 2>\&1 |") || &errorMsg("Command '$cmd' failed: $!\n"); + my @tmp = ; + close(CMD); + &echoMsg(@tmp); + } + + + # + # write cell log file + # + &echoMsg("\n") if $debug; + &echoMsg(" Write cell log file\n") if $debug; + open(OPT, ">$cellLogFile") || &errorExit("Unable to open file '$cellLogFile': $!\n"); + for(my $i=0; $i<=$#optStrList; $i++) { + print OPT "$optStrList[$i]\n"; + } + print OPT "abstract source view: $srcView\n"; + close(OPT); + + + # + # generate md5sum checksum + # + &echoMsg(" Add md5sum to cell log file\n") if $debug; + my $md5sumCmd = "cd $srcCellPath ; /usr/bin/md5sum $viewName/layout.oa >> $cellLogFileName"; + print " md5sum Cmd: $md5sumCmd\n" if $debug; + system(" $md5sumCmd"); + + + # + # add cell logs file if it does not exist + # + if (!$cellLogFileFound) { + &echoMsg("\n") if $debug; + &echoMsg(" P4 add cell log...\n"); + $cmd = "cdsp4add $cmdChangeList --dfII-dir=$dfiiDir --file=$cellLogFileName $srcCell"; + &echoMsg(" Command: $cmd\n"); + open(CMD, "$cmd 2>\&1 |") || &errorMsg("Command '$cmd' failed: $!\n"); + my @tmp = ; + close(CMD); + &echoMsg(@tmp); + &echoMsg("\n"); + } + + + # + # submit cell logs file + # + &echoMsg("\n") if $debug; + &echoMsg(" P4 submit cell log file...\n"); + $cmd = "cdsp4submit $cmdChangeList"; + &echoMsg(" Command: $cmd\n") if $debug; + open(CMD, "$cmd 2>\&1 |") || &errorMsg("Command '$cmd' failed: $!\n"); + my @tmp = ; + close(CMD); + &echoMsg(@tmp); + &echoMsg("\n"); + + # if change is empty, delete it + `p4 change -d $cmdChangeSpec 2>/dev/null 1>/dev/null`; +} + + +###################################################### +# Done. +###################################################### +DONE: +&echoMsg("$toolName finished at ", &ctime(time)); +&echoMsg(" Warnings: $warningCnt\n"); +&echoMsg(" Errors: $errorCnt\n"); +&echoMsg("\n"); +close(LOG); +exit; + + +###################################################### +# functions +###################################################### +# echo output to std & log +sub echoMsg { + print "@_"; + print LOG "@_" if $logOpen; +} + +# error exit +sub errorExit { + &echoMsg("\nERROR: @_ \n"); + exit 1; +} + +# display error msg +sub errorMsg { + &echoMsg("ERROR: @_\n"); + $errorCnt++; +} + +# display warning msg +sub warningMsg { + &echoMsg("WARNING: @_\n"); + $warningCnt++; +} + +# decode dfii name -- change \W to #xx +sub decodeName { + my $name = $_[0]; + if ($name =~ /\W/) { + $name = $` . "#" . sprintf("%x", ord($&)) . &decodeName($'); + } + return($name); +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/defNets.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/defNets.pl new file mode 100755 index 0000000000..38ed5eccbd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/defNets.pl @@ -0,0 +1,207 @@ +#!/usr/bin/perl +# +# Process DEF file to remove all sections except NETS. +# +# +# trj 12/14/04 +# +###################################################### +# setup +###################################################### +require 'ctime.pl'; + +# +# usage +# +$toolName = "defNets"; +$toolRev = '$Revision$$DateTime$'; +$toolRev =~ s/\$//g; +$toolRev =~ s/DateTime: //; + +$usage = " +Usage: $toolName + --defin= : DEF file to process. + [ --defout= ] : Output DEF file (default=.$toolName). + [ --force ] : Overwrite output DEF file if it exists. + [ --special-nets ] : Include SPECIAL NETS section if found (default=omit) + [ --ldtrDefRead ] : Modify output DEF file to support skill ldtrDefRead function"; + + +# +# default and initial argument values +# +$defInFile = ""; +$defOutFile = ""; +$force = 0; +$inclSnets = 0; +$netsFound = 0; +$ldtrDefRead = 0; + + +###################################################### +# parse command line +###################################################### +# +# display usage if no args +# +if ($#ARGV < 0) { + print "$usage\n\n"; + exit; +} + +# +# parse args +# +while ($#ARGV>=0) { + + # --help + if ($ARGV[0] eq "--help") { + print "$usage\n\n"; + exit; + } + + # --debug (undocumented arg) + if ($ARGV[0] eq "--debug") { + $debug = 1; + shift(@ARGV); + next; + } + + # --defin= + if ($ARGV[0] =~ /--defin=(\S+)/) { + $defInFile = $1; + shift(@ARGV); + next; + } + + # --defout= + if ($ARGV[0] =~ /--defout=(\S+)/) { + $defOutFile = $1; + shift(@ARGV); + next; + } + + # --force + if ($ARGV[0] eq "--force") { + $force = 1; + shift(@ARGV); + next; + } + + # --special-nets + if ($ARGV[0] eq "--special-nets") { + $inclSnets = 1; + shift(@ARGV); + next; + } + + # --ldtrDefRead + if ($ARGV[0] eq "--ldtrDefRead") { + $ldtrDefRead = 1; + shift(@ARGV); + next; + } + + # unknown argument + &errorExit("Unknown or invalid argument '$ARGV[0]'.\n $usage \n"); +} + + +###################################################### +# validate inputs +###################################################### +# +# check for required arguments +# +&errorExit("Must specify DEF input --defin.\n $usage \n") if !$defInFile; + + +# +# validate paths & files +# +$defOutFile = $defInFile . ".$toolName" unless $defOutFile; +&errorExit("DEF input '$defInFile' not found.\n $usage \n") if !-e $defInFile; +&errorExit("DEF output '$defOutFile' already exists. Use --force to overwrite.\n") + if -e $defOutFile && !$force; + + +###################################################### +# Parse DEF +###################################################### +# +# open DEF files +# +open(DEFIN, "$defInFile") || &errorExit("Unable to open DEF file '$defInFile': $!\n"); +open(DEFOUT, ">$defOutFile") || &errorExit("Unable to open DEF file '$defOutFile': $!\n"); +print DEFOUT "#######################################################\n"; +print DEFOUT "#\n"; +print DEFOUT "# Modified by: $toolName, $toolRev ", &ctime(time); +print DEFOUT "#\n"; +print DEFOUT "# DEF Input File: $defInFile\n"; +print DEFOUT "# SPECIALNETS : "; +print DEFOUT $inclSnets ? "Included (if found)" : "Omit"; +print DEFOUT "\n"; +print DEFOUT "#\n"; +print DEFOUT "# Skill ldtrDefRead support:\n" if $ldtrDefRead; +print DEFOUT "# Change BUSBITCHARS to '<>'\n" if $ldtrDefRead; +print DEFOUT "# Filter '\\' from all names\n" if $ldtrDefRead; +print DEFOUT "#\n" if $ldtrDefRead; +print DEFOUT "#######################################################\n"; + + +# +# copy header +# +while() { + print DEFOUT if /^#|^VERSION|^NAMES|^DIVIDER|^DESIGN|^TECH|^UNITS|^DIEAREA/; + + # change BUSBITCHARS to '<>' if --ldtrDefRead + if (/^BUSBITCHARS/) { + if ($ldtrDefRead) { + print DEFOUT "BUSBITCHARS \"<>\" ;\n"; + } else { + print DEFOUT; + } + } + + + # optionally include SPECIALNETS + if (/^SPECIALNETS/ && $inclSnets) { + print DEFOUT "\n$_"; + while() { + $line = $_; + $line =~ s/\\//g if $ldtrDefRead; + print DEFOUT $line; + last if /^END SPECIALNETS/; + } + } + + # find NETS + if (/^NETS/) { + $netsFound = 1; + print DEFOUT "\n$_"; + while() { + $line = $_; + $line =~ s/\\//g if $ldtrDefRead; + print DEFOUT $line; + last if /^END NETS/; + } + print DEFOUT "\nEND DESIGN\n"; + last; + } +} +close(DEFIN); +close(DEFOUT); + +&errorExit("Unexpected EOF while processing DEF.\n") unless $netsFound; +exit; + + +###################################################### +# functions +###################################################### +# error exit +sub errorExit { + print "\nERROR: @_ \n"; + exit 1; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/exportDesignLef.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/exportDesignLef.pl new file mode 100755 index 0000000000..b7404e5459 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/exportDesignLef.pl @@ -0,0 +1,1225 @@ +#!/usr/intel/bin/perl +# +# Generate LEF file from dfII abstract cellviews for the specific list of cells referenced +# in a flatten cellview. Uses Cadence lefout function. +# +# trj 12/6/04 +# +###################################################### +# setup +###################################################### +require 'ctime.pl'; +use strict; + +my $package_root = $0; +my $exe = $package_root; +$exe =~ s:.*/::; +if (! ($package_root =~ m:^/:)) { + my $pwd = `pwd`; + chomp $pwd; + $package_root = $pwd; + $package_root .= "/$0"; + $package_root =~ s:$exe$::; + $package_root =~ s://:/:g; + chdir $package_root; + $package_root = `pwd`; + chomp $package_root; + chdir $pwd; +} +else { + $package_root =~ s:/bin/$exe::; +} + +# +# usage +# +my $toolName = "exportDesignLef"; +my $cellList = "flatten_cells_list"; +my $logFile = "$toolName.log"; +my $toolRev = '$Revision$$DateTime$'; +my $toolRev =~ s/\$//g; +my $toolRev =~ s/DateTime: //; +my $userAbsView = "abstract_edit"; + +my $usage = " +Usage: $toolName + [ --cdswd= ] : cadence working directory (default=cwd) + [ --cell-list= ] : cells in design to export (default=$cellList) + [ --client-spec= ] : p4 client-spec, required for --create-abstract + [ --create-abstract ] : invoke createAbstract for missing abstracts + [ --dfII-dir= ] : dfII path, required if not --fix-lef-only + --design= : name of design + [ --fix-lef-only ] : process existing LEF; don't create LEF or abstracts + --fulcrum-pdk-root= : pdk path + [ --keep-temp-lef ] : do not delete the intermediate LEF file + [ --lefin= ] : input to --fix-lef-only (default=_tmp.lef) + [ --lefout= ] : output LEF file (default=.lef) + [ --log= ] : name of log file (default=$logFile) + [ --write-lef ] : overwrite existing output LEF file + [ --power-grid-cell= ] : powergrid cell (default=.wires._POWER_GRID_TIEOFF) + [ --include-USE ] : insert USE statements on power nets + + Note: User modified abstract cellviews '$userAbsView' will be used whenever found."; + + +# +# default and initial argument values +# +my $cdswd = ''; +my $clientSpec = ""; +my $createAbstract = 0; +my $dfiiDir = ""; +my $designName = ""; +my $fixLefOnly = 0; +my $pdkRoot = ""; +my $keepTempLef = 0; +my $lefInFile = ""; +my $lefOutFile = ""; +my $writeLef = 0; +my $powerGridCellName = ""; +my $includeUSE = 0; +my $debug = 0; + + +# +# more inits +# +my $powerGridCellFound = 0; +my $logOpen = 0; +my $sumOpen = 0; +my $errorCnt = 0; +my $warningCnt = 0; +my $createAbsCnt = 0; +my $userAbsCnt = 0; +my $cellListCnt = 0; +my $macroCnt = 0; +my $cellListErrors = 0; +my $createAbsErrors = 0; +my $invalidAbsCnt = 0; +my $unvalidatedAbsCnt = 0; +my $lefoutOverwrite = "t"; +my $leaf = "leaf"; +my $mid = "mid"; +my $power = "power"; +my $foundForeign = 0; +my $foundOrigin = 0; +my $foundSize = 0; +my $obsRectCnt = 0; +my $units = 1000; + + +# +# post processing variables +# +my $vdd = 'Vdd'; +my $gnd = 'GND'; +my $pinShape = "ABUTMENT"; +my $indentSpace = ' '; +my $metal1PinCnt = 0; +my $metal2PinCnt = 0; +my %pinUse = ( $vdd, 'POWER', + $gnd, 'GROUND' ); +my %pinsFound = ( $vdd, 0, + $gnd, 0 ); +my %pinsOmit = ( $vdd, 0, + $gnd, 0 ); +my %pinsFixedUse = ( $vdd, 0, + $gnd, 0 ); +my %pinsFixedShape = ( $vdd, 0, + $gnd, 0 ); +my @layerNames = ( 'METAL1', 'METAL2', 'METAL3', 'METAL4' ,'METAL5', 'METAL6', 'METAL7' ); + + +# +# define commands +# +my $lefoutCmdFile = $toolName . "Out.cmd"; +my $lefoutLogFile = $toolName . "Out.log"; +my $lefoutCmd = "virtuoso -replay $lefoutCmdFile -nograph -log $lefoutLogFile"; +my $createAbstractCmd = "createAbstract"; + +# command options file to look for in dfII cell directory +my $cmdOptFileName = "abstract.log"; +my $cmdOptFileFound = 0; +my $cmdOptSrcView = ''; +my @routedSrcViews = ("layout", "layout_pg", "floorplan", "flatten"); + + +###################################################### +# parse command line +###################################################### +# +# display usage if no args +# +if ($#ARGV < 0) { + print "$usage\n\n"; + exit; +} + + +# +# parse args +# +while ($#ARGV>=0) { + + # --help + if ($ARGV[0] eq "--help") { + print "$usage\n\n"; + exit; + } + + # --debug (undocumented arg) + if ($ARGV[0] eq "--debug") { + $debug = 1; + shift(@ARGV); + next; + } + + # --cdswd= + if ($ARGV[0] =~ /--cdswd=(\S+)/) { + $cdswd = $1; + shift(@ARGV); + next; + } + + # --cell-list= + if ($ARGV[0] =~ /--cell-list=(\S+)/) { + $cellList = $1; + shift(@ARGV); + next; + } + + # --client-spec= + if ($ARGV[0] =~ /--client-spec=(\S+)/) { + $clientSpec = $1; + shift(@ARGV); + next; + } + + # --create-abstract + if ($ARGV[0] eq "--create-abstract") { + $createAbstract = 1; + shift(@ARGV); + next; + } + + # --dfII-dir= + if ($ARGV[0] =~ /--dfII-dir=(\S+)/) { + $dfiiDir = $1; + shift(@ARGV); + next; + } + + # --design= + if ($ARGV[0] =~ /--design=(\S+)/) { + $designName = $1; + shift(@ARGV); + next; + } + + # --fix-lef-only + if ($ARGV[0] eq "--fix-lef-only") { + $fixLefOnly = 1; + shift(@ARGV); + next; + } + + # --fulcrum-pdk-root= + if ($ARGV[0] =~ /--fulcrum-pdk-root=(\S+)/) { + $pdkRoot = $1; + shift(@ARGV); + next; + } + + # --keep-temp-lef + if ($ARGV[0] eq "--keep-temp-lef") { + $keepTempLef = 1; + shift(@ARGV); + next; + } + + # --lefin= + if ($ARGV[0] =~ /--lefin=(\S+)/) { + $lefInFile = $1; + shift(@ARGV); + next; + } + + # --lefout= + if ($ARGV[0] =~ /--lefout=(\S+)/) { + $lefOutFile = $1; + shift(@ARGV); + next; + } + + # --log= + if ($ARGV[0] =~ /--log=(\S+)/) { + $logFile = $1; + shift(@ARGV); + next; + } + + # --write-lef + if ($ARGV[0] eq "--write-lef") { + $writeLef = 1; + shift(@ARGV); + next; + } + + # --power-grid-cell= + if ($ARGV[0] =~ /--power-grid-cell=(\S+)/) { + $powerGridCellName = $1; + shift(@ARGV); + next; + } + + # --include-USE + if ($ARGV[0] eq "--include-USE") { + $includeUSE = 1; + shift(@ARGV); + next; + } + # unknown argument + &errorExit("Unknown or invalid argument '$ARGV[0]'.\n $usage \n"); +} + +###################################################### +# validate inputs +###################################################### +# +# check mutually exclusive arguments +# +&errorExit("Do not specify --create-abstract and --fix-lef-only.\n $usage \n") + if $createAbstract && $fixLefOnly; +&errorExit("Do not specify --lef-in and without --fix-lef-only.\n $usage \n") + if $lefInFile && !$fixLefOnly; + + +# +# check for required arguments +# +&errorExit("--design not specified.\n $usage \n") unless $designName; +&errorExit("--dfII-dir not specified.\n $usage \n") if !$fixLefOnly && !$dfiiDir; +&errorExit("--client-spec not specified. Required for --create-abstract.\n $usage \n") + if $createAbstract && !$clientSpec; +&errorExit("--fulcrum-pdk-root not specified.\n $usage \n") unless $pdkRoot; + + +# +# generate timestamp for use in tmp filenames +# +my $cmd = "date +%C%y%m%d%H%M%S"; +open(CMD, "$cmd |") || &errorExit("Unable to execute command '$cmd': $!\n"); +my $timestamp = ; +chop($timestamp); +close(CMD); +my $lefoutListFile = "tmp.lefoutlist." . $timestamp; +$lefInFile = "tmp.lef." . $timestamp unless $lefInFile; + + +# +# define names dependent upon +# +$lefOutFile = $designName . ".lef" unless $lefOutFile; + +my @tmp = split('\.', $designName); +my $subType = pop(@tmp); +my $type = pop(@tmp) . "_" . $subType; +my $libName = join('.', @tmp); +$powerGridCellName = $libName . ".wires." . $type . "_POWER_GRID_TIEOFF" unless $powerGridCellName; + +# +# validate paths & files +# +my $cdsLib = "cds.lib"; +if ($cdswd) { + &errorExit("cdswd '$cdswd' not found.\n") unless -e $cdswd; + &errorExit("cdswd '$cdswd' not a directory.\n") unless -d $cdswd; + chdir($cdswd) || &errorExit("Unable to cd to '$cdswd': $!\n"); + $cdsLib = $cdswd . "/" . $cdsLib; +} +&errorExit("cdswd ".$cdswd." not a valid Cadence working directory.\n") unless -e $cdsLib; +&errorExit("cell-list '$cellList' not found.\n") unless -e $cellList; +&errorExit("dfII-dir '$dfiiDir' not found.\n") if !$fixLefOnly && ! -e $dfiiDir; +&errorExit("dfII-dir '$dfiiDir' not a directory.\n") if !$fixLefOnly && ! -d $dfiiDir; +&errorExit("fulcrum-pdk-root '$pdkRoot' not found.\n") unless -e $pdkRoot; +&errorExit("fulcrum-pdk-root '$pdkRoot' not a directory.\n") unless -d $pdkRoot; +&errorExit("Package root '$package_root' not found.\n") unless -e $package_root; +&errorExit("lefin '$lefInFile' not found.\n") if $lefInFile && $fixLefOnly && !-e $lefInFile; +&errorExit("lefout '$lefOutFile' already exists. Use --write-lef to overwrite.\n $usage \n") + if -e $lefOutFile && !$writeLef; +$keepTempLef = 1 if $debug; + +my %cdslibs=(); +my $fcdslib; +if (open ($fcdslib, "<$cdsLib")) { + while (<$fcdslib>) { + chomp; + next if /^\s*#/; + if (/INCLUDE (\S+)/) { + my $include=$1; + $include =~ s/\$\{FULCRUM_PDK_ROOT\}/$pdkRoot/; + my $dir=$include; + $dir =~ s/\/[^\/]+$//; + my $finc; + open ($finc, "<$include"); + while (<$finc>) { + chomp; + if (/^DEFINE (\S+) (\S+)/) { + my $lib=$1; + my $d="$dir/$2"; + $lib =~ s/#2e/./g; + $lib =~ s/#2d/-/g; + $cdslibs{$lib}=$d; + } + } + close $finc; + } + if (/^DEFINE (\S+) (\S+)/) { + my $lib=$1; + my $d=$2; + $lib =~ s/#2e/./g; + $lib =~ s/#2d/-/g; + $cdslibs{$lib}=$d; + } + } + close $fcdslib; +} +else { + &errorMsg(" Cannot open $cdsLib\n"); +} + + +# +# define names dependent upon package_root +# +my $skillRoot = "$package_root/share/skill"; +my $skillAutoLoad = "$skillRoot/autoload.il"; +my $pdkInfoIL = "$pdkRoot/share/Fulcrum/pdkinfo.il"; + + +# +# log options +# +open(LOG, ">$logFile") || &errorExit("Unable to open log file '$logFile': $!\n"); +$logOpen = 1; +my $sumFile = substr($logFile, 0, length($logFile)-3); +$sumFile .= "sum"; +open(SUM, ">$sumFile") || &errorExit("Unable to open summary file '$sumFile': $!\n"); +$sumOpen = 1; +&echoMsg("\n$toolName, $toolRev\n"); +&echoMsg(" $toolName started at ", &ctime(time)); +&echoMsg("\n"); +if ($package_root =~ /tomjones/) { + &echoMsg("\n"); + &warningMsg("### USING PKGROOT=$package_root ###\n"); + &echoMsg("\n"); +} +&echoMsg("Mode options:\n"); +&echoMsg(" Create abstracts =", $createAbstract?"TRUE":"FALSE", "\n"); +&echoMsg(" Fix LEF only =", $fixLefOnly?"TRUE":"FALSE", "\n"); +&echoMsg(" Keep Temp LEF =", $keepTempLef?"TRUE":"FALSE", "\n"); +&echoMsg("\n"); +&echoMsg("Source design data:\n"); +&echoMsg(" CDS Working Dir = $cdswd\n") if $cdswd; +&echoMsg(" dfII Dir = $dfiiDir\n") if $dfiiDir; +&echoMsg(" Design Name = $designName\n"); +&echoMsg(" Cell List File = $cellList\n"); +&echoMsg(" Client Spec = $clientSpec\n") if $clientSpec; +&echoMsg(" Power Grid Cell = $powerGridCellName\n") unless $powerGridCellName eq "none"; +&echoMsg(" LEF Input File = $lefInFile\n") if $fixLefOnly || $keepTempLef; +&echoMsg(" LEF Output File = $lefOutFile\n"); +&echoMsg("\n"); + +goto PROCESSLEF if ($fixLefOnly); + + +########################################################################## +# parse cell list, check for missing abstracts and validate timestamps +########################################################################## +# +# parse cell list +# +my @missingAbs=(); +my @invalidAbs=(); +my @unvalidatedAbs=(); +&echoMsg("Evaluating cell list and validating abstracts...\n"); +open(LIST, ">$lefoutListFile") || &errorExit("Unable to open temp file '$lefoutListFile': $!\n"); +open(CELLS, "$cellList") || &errorExit("Unable to open cell-list '$cellList': $!\n"); +while () { + next if /^\s*$/ || /^#/; + if (/\s*(\S+)\s+(\S+)\s+(\S+)/) { + my ($srcLib, $srcCell, $cellView) = ($1, $2, "abstract"); + my $cellName = &decodeName($srcCell); + $cellListCnt++; + + # verify cell exists + &echoMsg(" Validating cell $srcCell \n") if $debug; + my $srcCellPath = join('/', ($cdslibs{$srcLib}, $cellName)); + if (!-e $srcCellPath) { + &errorMsg("Cell '$srcLib:$srcCell' in cell-list not found in dfII-dir"); + $cellListErrors++; + next; + } + + # verify abstract exists + &echoMsg(" Looking for abstract cellview(s)\n") if $debug; + my $cellViewCDB = join('/', ($cdslibs{$srcLib}, $cellName, $cellView, "layout.oa")); + my $cellViewFound = -e $cellViewCDB ? 1 : 0; + &echoMsg(" Found $cellView cellview\n") if $debug && $cellViewFound; + #$cellViewAge = -M $cellViewCDB if $cellViewFound; + #&echoMsg(" $cellView age=$cellViewAge days\n") if $debug && $cellViewFound; + + my $userViewCDB = join('/', ($cdslibs{$srcLib}, $cellName, $userAbsView, "layout.oa")); + my $userViewFound = -e $userViewCDB ? 1 : 0; + &echoMsg(" Found $userAbsView cellview\n") if $debug && $userViewFound; + #$userViewAge = -M $userViewCDB if $userViewFound; + #&echoMsg(" $userAbsView age=$userViewAge days\n") if $debug && $userViewFound; + + # check for user modified abstract + if ($userViewFound) { + $cellView = $userAbsView; + #$absViewAge = $userViewAge; + $userAbsCnt++; + &echoMsg("INFO: Using modified cellview $srcCell $cellView\n"); + + # check if generate file exists and if newer + #if ($cellViewFound) { + #if ($cellViewAge < $userViewAge) { + # &errorMsg("Generated abstract cellview is more recent than $cellView cellview.\n"); + #} + #} + #} else { + # $absViewAge = $cellViewAge; + } + + # check for missing abstract + if (!$cellViewFound && !$userViewFound) { + push(@missingAbs, "$srcLib $srcCell $cellView"); + &echoMsg(" NO ABSTRACT FOUND!\n") if $debug; + next; + } + + # validate abstract is current + my $cmdOptFile = join('/', ($srcCellPath, $cmdOptFileName)); + &echoMsg(" Looking for command option file: $cmdOptFile\n") if $debug; + &echoMsg(" Looking for command option file\n") if $debug; + + if (-e $cmdOptFile) { + $cmdOptFileFound = 1; + &echoMsg(" Found command option file: $cmdOptFile\n") if $debug; + &echoMsg(" Found command option file\n") if $debug; + open(OPT, "$cmdOptFile") || &errorMsg("Unable to open file '$cmdOptFile': $!\n"); + my $absSrcView="layout"; + while () { + if (/abstract source view:\s+(\S+)/) { + $absSrcView = $1; + } + } + close(OPT); + + &echoMsg(" Looking for abstract source view '$absSrcView'\n") if $debug; + my $absSrcViewCDB = join('/', ($srcCellPath, $absSrcView, "layout.oa")); + if (-e $absSrcViewCDB) { + &echoMsg(" Found abstract source view \n") if $debug; + + # + # types of md5sum results + # layout/layout.oa: OK -- validated + # layout/layout.oa: FAILED -- md5sum mismatch + # layout/layout.oa: FAILED open or read -- source missing + # md5sum: abstract.log: no properly formatted MD5 checksum lines found -- md5sum missing + # + &echoMsg(" Checking md5sum for source view\n") if $debug; + my $md5sumResults = `cd $srcCellPath ; md5sum -c $cmdOptFileName 2>&1`; + chomp $md5sumResults; + &echoMsg(" Results: '$md5sumResults'\n") if $debug; + if ($md5sumResults =~ /: OK/) { + &echoMsg(" Validation PASS\n") if $debug; + } elsif ($md5sumResults =~ /: FAILED/) { + &echoMsg(" Validation FAIL\n") if $debug; + push(@invalidAbs, "$srcCell $absSrcView $cellView"); + } elsif ($md5sumResults =~ /: no properly formatted MD5 checksum lines found/) { + &echoMsg(" Unable to validate\n") if $debug; + push(@unvalidatedAbs, "$srcCell $absSrcView $cellView"); + } else { + &errorMsg(" Validation failure for $srcCell $absSrcView $cellView\n"); + push(@unvalidatedAbs, "$srcCell $absSrcView $cellView"); + } + + + #&echoMsg(" Comparing dates: source '$absSrcView' vs abstract '$cellView'\n") if $debug; + #$absSrcViewAge = -M $absSrcViewCDB; + #&echoMsg(" $absSrcView age=$absSrcViewAge days\n") if $debug; + #if ($absSrcViewAge < $absViewAge) { + #push(@invalidAbs, "$srcCell $absSrcView $cellView"); + #&errorMsg("Abstract source view '$absSrcView' is more recent than '$cellView' cellview for cell $srcCell.\n"); + #} + } + + # look for routed source views + &echoMsg(" Looking for other routed source views\n") if $debug; + my $routedSrcView = 0; + my $routedSrcViewFound = 0; + foreach my $view (@routedSrcViews) { + $routedSrcView = 1 if $view eq $absSrcView; + &echoMsg(" Found $view\n") if $debug && $view eq $absSrcView; + } + if (!$routedSrcView) { + foreach my $view (@routedSrcViews) { + my $viewName = &decodeName($view); + my $viewCDB = join('/',($srcCellPath, $viewName, "layout.oa")); + &errorMsg("Using source view '$absSrcView' when routed source view '$view' exists for cell $srcCell.\n") + if -e $viewCDB; + } + } + } else { + print "Ignoring command options file $cmdOptFile\n"; +# &errorMsg("Abstract not validated due to missing command options file $cmdOptFile\n"); + } + print LIST "$srcLib $srcCell $cellView\n"; + + } else { + &warningMsg("Unable to parse line of cell-list: \n $_\n"); + } +} +close(CELLS); +close(LIST); + + +# +# display list of invalid abstracts +# +if ($#invalidAbs >= 0) { + $invalidAbsCnt = $#invalidAbs+1; + &echoMsg("\n ERROR: $invalidAbsCnt abstract(s) FAILED validation -- source view has changed since abstract generated:\n\n"); + $errorCnt += $invalidAbsCnt; + + # format list: "$srcCell $absSrcView $cellView" + my $maxCellLen = 0; + my $maxSrcLen = 0; + my $maxAbsLen = 0; + for (my $i=0; $i<=$#invalidAbs; $i++) { + my @cell = split(' ', $invalidAbs[$i]); + $maxCellLen = &max($maxCellLen, length($cell[0])); + $maxSrcLen = &max($maxSrcLen, length($cell[1])); + $maxAbsLen = &max($maxAbsLen, length($cell[2])); + } + + # Source Abstract + # Cell View View + # + my ($f1, $f2, $f3) = ($maxCellLen, $maxSrcLen, $maxAbsLen); + my $fmt = " %-*s %-*s %-*s\n"; + &echoMsg(sprintf($fmt, $f1, " ", $f2, "Source", $f3, "Abstract")); + &echoMsg(sprintf($fmt, $f1, "Cell ", $f2, " View ", $f3, " View ")); + &echoMsg(sprintf($fmt, $f1, "----------", $f2, "------", $f3, "--------")); + + for (my $i=0; $i<=$#invalidAbs; $i++) { + my @list = split(' ', $invalidAbs[$i]); + &echoMsg(sprintf($fmt, $f1, $list[0], $f2, $list[1], $f3, $list[2])); + } +} + + +# +# display list of unvalidated abstracts +# +if ($#unvalidatedAbs >= 0) { + $unvalidatedAbsCnt = $#unvalidatedAbs+1; + &echoMsg(" ERROR: $unvalidatedAbsCnt abstract(s) are unvalidated -- unable to determine if abstract is valid\n\n"); + $errorCnt += $unvalidatedAbsCnt; + + # format list: "$srcCell $absSrcView $cellView" + my $maxCellLen = 0; + my $maxSrcLen = 0; + my $maxAbsLen = 0; + for (my $i=0; $i<=$#unvalidatedAbs; $i++) { + my @cell = split(' ', $unvalidatedAbs[$i]); + $maxCellLen = &max($maxCellLen, length($cell[0])); + $maxSrcLen = &max($maxSrcLen, length($cell[1])); + $maxAbsLen = &max($maxAbsLen, length($cell[2])); + } + + # Source Abstract + # Cell View View + # + my ($f1, $f2, $f3) = ($maxCellLen, $maxSrcLen, $maxAbsLen); + my $fmt = " %-*s %-*s %-*s\n"; + &echoMsg(sprintf($fmt, $f1, " ", $f2, "Source", $f3, "Abstract")); + &echoMsg(sprintf($fmt, $f1, "Cell ", $f2, " View ", $f3, " View ")); + &echoMsg(sprintf($fmt, $f1, "----------", $f2, "------", $f3, "--------")); + + for (my $i=0; $i<=$#unvalidatedAbs; $i++) { + my @list = split(' ', $unvalidatedAbs[$i]); + &echoMsg(sprintf($fmt, $f1, $list[0], $f2, $list[1], $f3, $list[2])); + } +} +&echoMsg("\n") if $invalidAbsCnt || $unvalidatedAbsCnt; +&echoMsg(" Finished validating abstracts\n"); + + +# +# display list of missing abstracts +# +if ($#missingAbs >= 0) { + &warningMsg("\nThe following cells are missing abstract cellviews:\n"); + + # format list + my $maxLibLen = 0; + my $maxCellLen = 0; + for (my $i=0; $i<=$#missingAbs; $i++) { + my @cell = split(' ', $missingAbs[$i]); + $maxLibLen = &max($maxLibLen, length($cell[0])); + $maxCellLen = &max($maxCellLen, length($cell[1])); + } + + # Abstract Layout Default + # Lib Cell View View CellType + my ($f1, $f2, $f3, $f4) = ($maxLibLen, $maxCellLen, 6, 5); + my $fmt = " %-*s %-*s %-*s %-*s %-*s\n"; + &echoMsg(sprintf($fmt, $f1, "LibName", $f2, "CellName", $f3, "Source", $f4, "Type")); + &echoMsg(sprintf($fmt, $f1, "-------", $f2, "--------", $f3, "------", $f4, "----")); + + for (my $i=0; $i<=$#missingAbs; $i++) { + my @list = split(' ', $missingAbs[$i]); + if ($list[1] eq $powerGridCellName || $list[1] =~ /POWER.*GRID/) { + $type = $power; + } elsif ($list[0] =~ /^core/) { + $type = $mid; + } else { + $type = $leaf; + } + push(@list, "layout", $type); + $missingAbs[$i] = join(" ", @list); + &echoMsg(sprintf($fmt, $f1, $list[0], $f2, $list[1], $f3, $list[3], $f4, $list[4])); + } + + if (!$createAbstract) { + &echoMsg("\nINFO: Use --create-abstract or invoke createAbstract tool to generate missing abstracts.\n"); + &echoMsg(" --create-abstract will use Source and Type as source cellview and abstract cell type.\n"); + goto DONE; + } + &echoMsg("\n"); +} + + +###################################################### +# invoke createAbstract for missing abstracts +###################################################### +if ($#missingAbs >= 0) { + &echoMsg("\nInvoking createAbstract on missing cells...\n"); + for (my $i=0; $i<=$#missingAbs; $i++) { + + # invoke createAbstract + my @list = split(' ', $missingAbs[$i]); + my $cell = "$list[0]:$list[1]:$list[3]"; + my $absLogFile = "createAbstract.$list[1].log"; + $cmd = "$createAbstractCmd --cell=$cell --client-spec=$clientSpec --dfII-dir=$dfiiDir --log=$absLogFile --type=$list[4]"; + &echoMsg(" Command: $cmd\n"); + system($cmd); + + # check log file for errors + open(ABSLOG, "$absLogFile") || &errorExit("Unable to open log file '$absLogFile': $!\n"); + my $status = ""; + while() { + if (/Abstract Generator Status: (\w+)/) { + $status = $1; + last; + } + } + &echoMsg("\n"); + if ($status eq "FAILURE") { + &errorMsg("createAbstract FAILED for cell '$cell'\n"); + $createAbsErrors++; + } elsif ($status eq "SUCCESS") { + &echoMsg("createAbstract SUCCEEDED for cell '$cell'\n"); + } else { + &errorMsg("Unable to determine createAbstract status for cell '$cell'\n") unless $status; + $createAbsErrors++; + } + close(ABSLOG); + #&echoMsg("\n"); + } +} +if ($cellListErrors || $createAbsErrors) { + &echoMsg("INFO: Aborting due to earlier errors.\n") ; + goto DONE; +} + + +####################################################### +# create lefout command file +####################################################### +open(CMD, ">$lefoutCmdFile") || &errorExit("Unable to open command file '$lefoutCmdFile': $!\n"); +print CMD "\;------------------------------------------------------------\n"; +print CMD "\;\n"; +print CMD "\; LEFOUT command file \n"; +print CMD "\;\n"; +print CMD "\; Created by: $toolName, $toolRev ", &ctime(time); +print CMD "\;\n"; +print CMD "\; Source design data:\n"; +print CMD "\; CDS Working Dir = $cdswd\n" if $cdswd; +print CMD "\; dfII Dir = $dfiiDir\n" if $dfiiDir; +print CMD "\; Design Name = $designName\n"; +print CMD "\; Cell List File = $cellList\n"; +print CMD "\; Client Spec = $clientSpec\n" if $clientSpec; +print CMD "\; Power Grid Cell = $powerGridCellName\n" unless $powerGridCellName eq "none"; +print CMD "\; LEF Input File = $lefInFile\n" if $fixLefOnly || $keepTempLef; +print CMD "\; LEF Output File = $lefOutFile\n"; +print CMD "\;\n"; +print CMD "\;------------------------------------------------------------\n"; +print CMD "\n"; +print CMD "load( \"$skillAutoLoad\" )\n"; +print CMD "load( \"$pdkInfoIL\" )\n"; +print CMD "\n"; +print CMD "\; omit technology info\n"; +print CMD "\;gec3SkipLefTECH = t\n"; +print CMD "gec3CurrentLEFVersion=\"5.5\"\n"; +print CMD "\n"; +print CMD "copyViewToAbstractTmp(\"$lefoutListFile\" \"$powerGridCellName\")\n"; +print CMD "returnCode = nil \n"; +print CMD "returnCode = ldtrLefWriteOA( \"$lefInFile\" \n"; +print CMD " \"abstract_tmp\"\n"; +print CMD " \"\"\n"; +print CMD " \"$lefoutListFile.tmp\"\n"; +print CMD " \"abstract_tmp\" \"\" t \"5.4\" nil )\n"; +print CMD "\n"; +print CMD "deleteAbstractTmp(\"$lefoutListFile\")\n" if !$debug; +print CMD "if( returnCode \"SUCCESS\" \"FAILURE\" )\n"; +print CMD "exit\n"; +close(CMD); + + +##################################################### +# invoke lefout +###################################################### +&echoMsg("\n"); +&echoMsg("Invoking lefout...\n"); +$cmd = $lefoutCmd; +&echoMsg(" Command: $cmd\n"); +system($cmd); + + +###################################################### +# check lefout log for errors +###################################################### +## +## NOTE: lefdef.exe has invalid return status so it is not +## possible to check log file or function return code to +## determine success or failure. Instead verify existence +## of temp lef file. +## +if (-e $lefInFile) { + &echoMsg(" lefout completed successfully.\n"); +} else { + &errorMsg(" lefout FAILED.\n"); + goto DONE; +} + + +###################################################### +# process lef for nanoroute +###################################################### +PROCESSLEF: +&echoMsg("\nProcessing lef for Nanoroute...\n") if $debug; +# +# print LEF header +# +open(LEFIN, "$lefInFile") || &errorExit("Unable to open temp LEF file '$lefInFile': $!\n"); +open(LEFOUT, ">$lefOutFile") || &errorExit("Unable to open LEF file '$lefOutFile': $!\n"); +print LEFOUT "############################################################\n"; +print LEFOUT "#\n"; +print LEFOUT "# Created by: $toolName, $toolRev" , &ctime(time); +print LEFOUT "#\n"; +print LEFOUT "# Source design data:\n"; +print LEFOUT "# CDS Working Dir = $cdswd \n" if $cdswd; +print LEFOUT "# dfII Dir = $dfiiDir\n" if $dfiiDir; +print LEFOUT "# Design Name = $designName\n"; +print LEFOUT "# Cell List File = $cellList\n"; +print LEFOUT "# Client Spec = $clientSpec\n" if $clientSpec; +print LEFOUT "# Power Grid Cell = $powerGridCellName\n" unless $powerGridCellName eq "none"; +print LEFOUT "# LEF Input File = $lefInFile\n" if $fixLefOnly || $keepTempLef; +print LEFOUT "# LEF Output File = $lefOutFile\n"; +print LEFOUT "#\n"; +print LEFOUT "############################################################\n"; +print LEFOUT "\nVERSION 5.5 \;\n"; +print LEFOUT "\nNAMESCASESENSITIVE ON \;\n"; +print LEFOUT "\nDIVIDERCHAR \"|\" \;\n"; +print LEFOUT "BUSBITCHARS \"<>\" \;\n\n"; + + +my $line=""; +my $macroName; +my %layer=(); +my $macroX; +my $macroX1; +my $macroX2; +my $pinName; +my $pinNameEsc; +my $layerName; +my @layers=(); +my $pinUseStmt=""; +my $pinCnt=0; +my $pinOmitCnt=0; +my $missingAbsCnt=0; +my $missingMacroCnt=0; +my $pinFixedUseCnt=0; +my $pinFixedShapeCnt=0; +my $mfgGrid=0.005; +my $start=0; + +# +# process macros +# +while () { + + # detect grid + if (/MANUFACTURINGGRID\s+(\S+)\s*;/) { + $mfgGrid=$1; + } + + # macro header + if (/MACRO\s+(.+)\s*/) { + print LEFOUT; + $start = 1; + $macroName = $1; + $macroCnt++; + $foundForeign = 0; + $foundOrigin = 0; + $foundSize = 0; + $powerGridCellFound = 1 if $macroName eq $powerGridCellName; + &echoMsg(" Found Macro $macroName\n") if $debug; + # add CLASS and SYMMETRY + my $class = ($macroName eq $powerGridCellName) ? 'COVER' : 'BLOCK'; + print LEFOUT " CLASS $class ;\n"; + print LEFOUT " SYMMETRY X Y R90 ;\n"; + next; + } + + # skip header fields + next if (!$start); + + # ignore original CLASS + if (/CLASS (.*)/) { + next; + } + + # ignore original SYMMETRY + if (/SYMMETRY (.*)/) { + next; + } + + ###################################################################### + # NOTE: Perl comparison can fail with floating point numbers due to + # roundoff. Scale geometries by UNITS and use integer comparisons. + ###################################################################### + + # find foreign + if (/FOREIGN\s+(\S+)\s+(-*\d+\.*\d*)/) { + my $foreignMacro=$1; + $macroX1 = int($2 * $units); + $foundForeign = 1; + &echoMsg(" Found FOREIGN X=$macroX1\n") if $debug; + &errorMsg("FOREIGN $foreignMacro does not match MACRO $macroName") + if $macroName ne $foreignMacro; + print LEFOUT; + next; + } + + # find origin + if (/ORIGIN\s+(-*\d+\.\d+)/) { + $macroX = int($1 * $units); + $foundOrigin = 1; + &echoMsg(" Found ORIGIN X=$macroX\n") if $debug; + print LEFOUT; + next; + } + + # find size + if (/SIZE\s+(\d+\.\d+)/) { + $macroX2 = int($1 * $units); + $foundSize = 1; + &echoMsg(" Found SIZE X=$macroX2\n") if $debug; + $macroX2 += $macroX1 if $foundForeign; + print LEFOUT; + next; + } + + # make symmetry universal + if (/^(\s*)SYMMETRY\s+/) { + print LEFOUT "${1}SYMMETRY X Y R90 ;\n"; + next; + } + + # find pins + if (/PIN\s+(\S*)/) { + + # check for origin and size + if (!$foundForeign || !$foundSize) { + &warningMsg("FOREIGN and/or SIZE not found for macro $macroName\n"); + $foundForeign = 1; + $foundSize = 1; + $macroX1 = 0; + $macroX2 = 0; + } + + # process pin + $pinName = $1; + $pinNameEsc = &escapeName($pinName); + &echoMsg(" Found pin $pinName\n") if $debug; + my $pin = $_; + do { + $line = ; + my $ok=1; + if ($line =~ /POLYGON.*;/) { + my $t=$line; + $t =~ s/\s+/ /g; + $t =~ s/^\s//; + $t =~ s/\s$//; + my @ln=split(/ /, $t); + my $npt = ($#ln-1)/2; + if ($ln[$#ln-1] eq $ln[2] and $ln[$#ln-2] eq $ln[1]) { + $npt--; # handle end point == first point + } + if ($ok and $npt < 4) { # need 4 points to make a rectangle + print STDERR "Warning: removed a $npt point polygon ($t)\n"; + $warningCnt++; + $ok=0; + } + if ($ok) { + for my $coord (1..$#ln-1) { + if ( int(abs($ln[$coord])/$mfgGrid*100+0.5)%100 != 0) { + $ok=0; + last; + } + } + if (! $ok) { + print STDERR "Warning: off grid coordinates found and removed ($t)\n"; + $warningCnt++; + } + } + } + $pin .= $line if $ok; + } until ($pin =~ /END\s+\S+/); + + # process power pin + if ($pinNameEsc eq $vdd || $pinNameEsc eq $gnd) { + $pinsFound{$pinName}++; + + # verify USE + if ($pin =~ /USE\s+(\w+)\s+;/) { + $pinUseStmt = $1; + $pinUseStmt =~ tr/a-z/A-Z/; + if ($pinUseStmt ne $pinUse{$pinName}) { + &errorMsg("Inconsistent USE '$1' found for pin ($macroName:$pinName)"); + $pin =~ s/$&/USE $pinUse{$pinName} \;/; + $pinsFixedUse{$pinName}++; + } + } else { + if ($includeUSE) { + #&errorMsg("USE statement not found for pin ($macroName:$pinName)"); + &echoMsg(" Add 'USE $pinUse{$pinName}'\n") if $debug; + $pin =~ s/PORT/USE $pinUse{$pinName} \;\n$indentSpace PORT/; + $pinsFixedUse{$pinName}++; + } + } + + # verify SHAPE + if ($pin =~ /SHAPE\s+(\w+)\s+;/) { + if ($1 ne $pinShape) { + &errorMsg("Inconsistent SHAPE '$1' found for pin ($macroName:$pinName)"); + $pin =~ s/$&/SHAPE $pinShape/; + $pinsFixedShape{$pinName}++; + } + } else { + #&errorMsg("SHAPE statement not found for pin ($macroName:$pinName)"); + &echoMsg(" Add 'SHAPE $pinShape'\n") if $debug; + $pin =~ s/PORT/SHAPE $pinShape \;\n$indentSpace PORT/; + $pinsFixedShape{$pinName}++; + } + } + + # warn if pin contains METAL1 or METAL2 + &warningMsg("Pin ($macroName:$pinName) uses LAYER METAL1.") if $pin =~ /METAL1/; + $metal1PinCnt++ if $pin =~ /METAL1/; + &warningMsg("Pin ($macroName:$pinName) uses LAYER METAL2.") if $pin =~ /METAL2/; + $metal2PinCnt++ if $pin =~ /METAL2/; + + print LEFOUT $pin; + next; + } + + # find obs + if (/^\s+OBS\s*$/) { + print LEFOUT; + &echoMsg(" Found OBS section\n") if $debug; + my @lines=(); + my %obsl=(); + $layerName=""; + my $end = " END"; + while($line=) { + if ($line =~ /\s+END\s*$/) { + $end = $line; + chomp $end; + last; + } + if ($line =~ /\s+LAYER\s+(\w+)/) { + $layerName = $1; + push @{$obsl{$layerName}}, $line; + my $pl=$line; + chomp $pl; + &echoMsg("$pl:$layerName:\n") if $debug; + } + elsif ($layerName ne "") { + push @{$obsl{$layerName}}, $line; + } + } + foreach my $ln (sort keys %obsl) { + my @f=@{$obsl{$ln}}; + chomp @f; + next if $#f <= 0; # strip empty section(s) + print LEFOUT join("\n", @f)."\n"; + } + print LEFOUT "$end\n";; + next; + } + + # otherwise + print LEFOUT; +} +close(LEFIN); +close(LEFOUT); +&errorMsg("power-grid-cell $powerGridCellName not found while processing LEF.") + unless $powerGridCellFound or $powerGridCellName eq "none"; + + +###################################################### +# Summary +###################################################### +DONE: +system("rm $lefInFile") if !$keepTempLef && !$fixLefOnly && -e $lefInFile; +system("rm $lefoutListFile") if !$debug && -e $lefoutListFile; + +$pinCnt = $pinsFound{$vdd} + $pinsFound{$gnd}; +$pinOmitCnt = $pinsOmit{$vdd} + $pinsOmit{$gnd}; +$pinFixedUseCnt = $pinsFixedUse{$vdd} + $pinsFixedUse{$gnd}; +$pinFixedShapeCnt = $pinsFixedShape{$vdd} + $pinsFixedShape{$gnd}; +$missingAbsCnt = $#missingAbs + 1; +$cellListCnt = $macroCnt if $fixLefOnly; +$missingMacroCnt = $cellListCnt - $macroCnt; +&errorMsg("$missingMacroCnt cells not exported to LEF") + if $missingMacroCnt && !($cellListErrors || $createAbsErrors); + +&echoMsg("\n"); +&echoMsg("Summary:\n"); +&echoMsg(" Cell Abstracts:\n"); +&echoMsg(" Cells in cell-list = $cellListCnt \n"); +&echoMsg(" Invalid Abstracts = $invalidAbsCnt\n"); +&echoMsg(" Missing Abstracts = $missingAbsCnt\n"); +&echoMsg(" Errors in cell-list = $cellListErrors\n"); +&echoMsg(" Abstracts Generated = $createAbsCnt\n"); +&echoMsg(" User Modified Abstracts = $userAbsCnt\n"); +&echoMsg("\n"); +&echoMsg(" LEF Generation:\n"); +&echoMsg(" Cells Exported = $macroCnt\n"); +if ($debug) { + &echoMsg(" Power Pins Found = $pinCnt ($pinsFound{$vdd}/$pinsFound{$gnd})\n"); + &echoMsg(" Omitted = $pinOmitCnt ($pinsOmit{$vdd}/$pinsOmit{$gnd})\n"); + &echoMsg(" Fixed USE = $pinFixedUseCnt ($pinsFixedUse{$vdd}/$pinsFixedUse{$gnd})\n"); + &echoMsg(" Fixed SHAPE = $pinFixedShapeCnt ($pinsFixedShape{$vdd}/$pinsFixedShape{$gnd})\n"); +} +&echoMsg(" Pins Using METAL1 = $metal1PinCnt\n") if $metal1PinCnt; +&echoMsg(" Pins Using METAL2 = $metal2PinCnt\n") if $metal2PinCnt; +&echoMsg(" Shapes Added to OBS = $obsRectCnt\n"); +&echoMsg("\n"); +&echoMsg(" WARNINGS: $warningCnt\n"); +&echoMsg(" ERRORS: $errorCnt\n"); +&echoMsg("Done\t", &ctime(time)); +close(LOG); + +print SUM "Summary:\n"; +print SUM " Cell Abstracts:\n"; +print SUM " Cells in cell-list = $cellListCnt \n"; +print SUM " Invalid Abstracts = $invalidAbsCnt\n"; +print SUM " Missing Abstracts = $missingAbsCnt\n"; +print SUM " Errors in cell-list = $cellListErrors\n"; +print SUM " Abstracts Generated = $createAbsCnt\n"; +print SUM " User Modified Abstracts = $userAbsCnt\n"; +print SUM "\n"; +print SUM " LEF Generation:\n"; +print SUM " Cells Exported = $macroCnt\n"; +if ($debug) { + print SUM " Power Pins Found = $pinCnt ($pinsFound{$vdd}/$pinsFound{$gnd})\n"; + print SUM " Omitted = $pinOmitCnt ($pinsOmit{$vdd}/$pinsOmit{$gnd})\n"; + print SUM " Fixed USE = $pinFixedUseCnt ($pinsFixedUse{$vdd}/$pinsFixedUse{$gnd})\n"; + print SUM " Fixed SHAPE = $pinFixedShapeCnt ($pinsFixedShape{$vdd}/$pinsFixedShape{$gnd})\n"; +} +print SUM " Pins Using METAL1 = $metal1PinCnt\n" if $metal1PinCnt; +print SUM " Pins Using METAL2 = $metal2PinCnt\n" if $metal2PinCnt; +print SUM " Shapes Added to OBS = $obsRectCnt\n"; +print SUM "\n"; +print SUM " WARNINGS: $warningCnt\n"; +print SUM " ERRORS: $errorCnt\n"; +close(SUM); +exit; + + +###################################################### +# functions +###################################################### +# echo output to std & log +sub echoMsg { + print "@_"; + print LOG "@_" if $logOpen; +} + +# error exit +sub errorExit { + &echoMsg("\nERROR: @_ \n"); + if( $sumOpen ) { + print SUM "$toolName FAILED.\n"; + print SUM "\nERROR: @_ \n"; + } + exit 1; +} + +# display error msg +sub errorMsg { + &echoMsg("ERROR: @_\n"); + $errorCnt++; +} + +# display warning msg +sub warningMsg { + &echoMsg("WARNING: @_\n"); + $warningCnt++; +} + +# decode dfii name -- change \W to #xx +sub decodeName { + my $name = $_[0]; + if ($name =~ /\W/) { + $name = $` . "#" . sprintf("%x", ord($&)) . &decodeName($'); + } + return($name); +} + +# escape name +sub escapeName { + my $name = $_[0]; + my $origName = $name; + $name =~ s/\[/\\\[/g; + $name =~ s/\]/\\\]/g; + $name =~ s/\(/\\\(/g; + $name =~ s/\)/\\\)/g; + $name =~ s/\{/\\\{/g; + $name =~ s/\}/\\\}/g; + print " Mapping $origName to $name\n" if $debug; + return($name); +} + +# max +sub max { + return($_[0]>$_[1]?$_[0]:$_[1]); +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/genTracks.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/genTracks.pl new file mode 100755 index 0000000000..a2b5132365 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/genTracks.pl @@ -0,0 +1,406 @@ +#!/usr/bin/perl +# +# Generate DEF TRACKS information for nanoroute for a specified design. +# +###################################################### +# setup +###################################################### +require 'ctime.pl'; +use POSIX; + +# set defaults for TSMC 28nm +$units = 1000; # 1000 microns per DBU +$metal = "M"; +$trackPitch = 0.13; +$routingPitch = 0.13; +$powerGridPitch = 1.56; +$gcellPitch = 4*$powerGridPitch; +$ArtisanPitch = 0.1; # track pitch +$RowPitch = 1.56; # row pitch +@powerGridLayers = (3,5,7); + +# +# usage +# +$usage = " +Usage: genTracks + { --refdef= | : Get units, diearea and design from . + --design= : Specify design name + --diearea=::: : Specify diearea coordinates in microns. + [--units= ] } : Specify units for 1 micron (default=$units). + [ --track-pitch= ] : Track pitch in microns (default=$trackPitch). + [ --ArtisanTracks ] : Use ${ArtisanPitch}um tracks for M1 and M2. + [ --ArtisanRows ] : Add row definitions. Implies --ArtisanTracks. + [ --rotate ] : Change orientation of preferred directions + { --outfile= | : Output DEF filename (default='tracks.def'). + --stdout } : Output to stdout instead of def file."; + +# +# default and initial argument values +# +$refDef = 0; +$defInFile = ""; +$userDieArea = 0; +@dieAreaCoord = (0,0,0,0); +$userDesign = 0; +$designName = ""; +$defOutFile = "tracks.def"; +$outDef = 1; +$outStd = 0; +$userUnits = 0; +$debug = 0; +$ArtisanTracks = 0; +$ArtisanRows = 0; +$rotate = 0; + +###################################################### +# parse command line +###################################################### +# +# display usage if no args +# +if ($#ARGV < 0) { + print "$usage\n\n"; + exit; +} + +# +# parse args +# +while ($#ARGV>=0) { + + # --help + if ($ARGV[0] eq "--help") { + print "$usage\n\n"; + exit; + } + + if ($ARGV[0] eq "--tsmc130") { + TSMC130; + shift(@ARGV); + } + + if ($ARGV[0] eq "--tsmc65") { + TSMC65; + shift(@ARGV); + } + + # --debug (undocumented arg) + if ($ARGV[0] eq "--debug") { + $debug = 1; + shift(@ARGV); + next; + } + + # --refdef + if ($ARGV[0] =~ /--refdef=(\S+)/) { + $defInFile = $1; + $refDef = 1; + shift(@ARGV); + next; + } + + # --diearea=::: + if ($ARGV[0] =~ /--diearea=(.*):(.*):(.*):(.*)/) { + @dieAreaCoord = ($1, $2, $3, $4); + + $userDieArea = 1; + shift(@ARGV); + next; + } + + # --design= + if ($ARGV[0] =~ /--design=(\S+)/) { + $designName = $1; + $userDesign = 1; + shift(@ARGV); + next; + } + + # --ArtisanTracks + if ($ARGV[0] eq "--ArtisanTracks") { + $ArtisanTracks = 1; + shift(@ARGV); + next; + } + + # --ArtisanRows + if ($ARGV[0] eq "--ArtisanRows") { + $ArtisanRows = 1; + $ArtisanTracks = 1; + shift(@ARGV); + next; + } + + # --rotate + if ($ARGV[0] eq "--rotate") { + $rotate = 1; + shift(@ARGV); + next; + } + + # --outfile= + if ($ARGV[0] =~ /--outfile=(\S+)/) { + $defOutFile = $1; + $outFile = 1; + shift(@ARGV); + next; + } + + # --stdout + if ($ARGV[0] eq "--stdout") { + $outStd = 1; + $outDef = 0; + shift(@ARGV); + next; + } + + # --units= + if ($ARGV[0] =~ /--units=(\d+)/) { + $units = $1; + $userUnits = 1; + shift(@ARGV); + next; + } + + # --track-pitch= + if ($ARGV[0] =~ /--track-pitch=(\d*\.\d+)/) { + $trackPitch = $1; + shift(@ARGV); + next; + } + + # unknown argument + &errorExit("Unknown or invalid argument '$ARGV[0]'.\n $usage \n"); +} + +# scale user diearea +if ($userDieArea) { + @dieAreaCoord = ($dieAreaCoord[0]*$units,$dieAreaCoord[1]*$units, + $dieAreaCoord[2]*$units,$dieAreaCoord[3]*$units); +} + +###################################################### +# validate inputs +###################################################### +# +# check for required arguments +# +&errorExit("Must specify --diearea or --refdef.\n $usage \n") if !$userDieArea && !$refDef; +&errorExit("Do not specify --outfile with --stdout.\n $usage \n") if $outFile && $outStd; + +if ($refDef) { + &errorExit("Do not specify --design, --diearea or --units with --refdef.\n $usage \n") + if $userDieArea || $userDesign || $userUnits; +} elsif (!$outStd) { + &errorExit("Must specify --design and --diearea when not using --refdef.\n $usage \n") + if !$userDieArea || !$userDesign; +} + + +# +# validate paths & files +# +&errorExit("refdef '$defInFile' not found.\n") if !-e $defInFile && $refDef; + +###################################################### +# get design name, units and coords from def +###################################################### +if ($refDef) { + + # get design name + open(DEFIN, "$defInFile") || &errorExit("Unable to open file $defIn: $!"); + while () { + if (/DESIGN\s+(\S+)/) { + $designName = $1; + last; + } + } + &errorExit("Unable to find DESIGN statement in $defIn.") if !$designName; + + # get units + while () { + if (/UNITS DISTANCE MICRONS (\d+)/) { + $designUnits = $1; + unless ($outStd) { + print "WARNING: Modifying UNITS $units to match design UNITS $designUnits.\n" + if $units != $designUnits; + } + $units = $designUnits; + last; + } + } + &errorExit("Unable to find UNITS statement in $defIn.") if !$designUnits; + + # get diearea + while () { + if (/DIEAREA\s+\(\s+(-*\d+)\s+(-*\d+)\s+\)\s+\(\s+(-*\d+)\s+(-*\d+)\s+\)/) { + @dieAreaCoord = ($1, $2, $3, $4); + last; + } + } + &errorExit("Unable to find DIEAREA statement in $defIn.") if !@dieAreaCoord; + close(DEFIN); +} + + +###################################################### +# generate tracks +###################################################### +# +# open output destination +# +if ($outDef) { + open(DEFOUT, ">$defOutFile") || &errorExit("Unable to open file $defOut: $!"); +} else { + open(DEFOUT, ">&STDOUT") || &errorExit("Unable to open STDOUT: $!"); +} + + +# +# print def header +# +if ($outDef) { + print DEFOUT "#************************************************************\n"; + print DEFOUT "#\n"; + print DEFOUT "# created by genTracks.pl ", &ctime(time); + print DEFOUT "#\n"; + print DEFOUT "# Reference DEF = $defInFile\n" if $refDef; + print DEFOUT "# User specified DIEAREA\n" if $userDieArea; + print DEFOUT "# User specified DESIGN\n" if $userDesign; + print DEFOUT "# User specified UNITS\n" if $userUnits; + print DEFOUT "#\n"; + print DEFOUT "#************************************************************\n"; + print DEFOUT "VERSION 5.5 \;\n"; + print DEFOUT "\n"; + print DEFOUT "NAMESCASESENSITIVE ON \;\n"; + print DEFOUT "DIVIDERCHAR \"|\" \;\n"; + print DEFOUT "BUSBITCHARS \"<>\" \;\n"; + print DEFOUT "\n"; + print DEFOUT "DESIGN $designName \;\n"; + print DEFOUT "\n"; + print DEFOUT "UNITS DISTANCE MICRONS $units \;\n"; +} +print DEFOUT "\n"; +print DEFOUT "DIEAREA ( $dieAreaCoord[0] $dieAreaCoord[1] ) ( $dieAreaCoord[2] $dieAreaCoord[3] ) \;\n"; +print DEFOUT "\n"; + +# scale by units +$trackPitch *= $units; +$powerGridPitch *= $units; +$routingPitch *= $units; +$ArtisanPitch *= $units; +$RowPitch *= $units; + +# +# define rows +# + +if ($ArtisanRows==1) { + $firstX = ceilCoord($dieAreaCoord[0],0,$ArtisanPitch); + $firstY = ceilCoord($dieAreaCoord[1],0,$RowPitch); + $lastX = floorCoord($dieAreaCoord[2],0,$ArtisanPitch); + $lastY = floorCoord($dieAreaCoord[3],0,$RowPitch); + $stepsX = POSIX::ceil(($lastX-$firstX)/$ArtisanPitch); + $stepsY = POSIX::ceil(($lastY-$firstY)/$RowPitch); + + for (my $i=0; $i<$stepsY; $i++) { + my $orient = "FS"; $orient = "N" if ($i%2==0); + my $y = $firstY + $RowPitch*$i; + print DEFOUT "ROW CORE_ROW_${i} cnx4site $firstX $y $orient DO $stepsX BY 1 STEP $ArtisanPitch 0 ;\n"; + } + print DEFOUT "\n"; +} + +# +# print base tracks +# +$trackStep = $trackPitch; +for ($layer = 1; $layer < 8; $layer++) { + for ($dir=0; $dir<2; $dir++) { + if ($ArtisanTracks && ($layer<=2)) { + my $off = 0; + if ($dir==0) { $off=-$ArtisanPitch/2; } + $first = (&ceilCoord($dieAreaCoord[$dir], $off, $ArtisanPitch)); + $last = (&floorCoord($dieAreaCoord[2+$dir], $off, $ArtisanPitch)); + $steps = 1+POSIX::ceil(($last-$first) / $ArtisanPitch); + print DEFOUT "TRACKS $direction[$dir] $first DO $steps STEP $ArtisanPitch LAYER ${metal}${layer} \;\n"; + + } else { + $first = (&ceilCoord($dieAreaCoord[$dir], -$routingPitch/2, $trackPitch)); + $last = (&floorCoord($dieAreaCoord[2+$dir], -$routingPitch/2, $trackPitch)); + $steps = 1+POSIX::ceil(($last-$first) / $trackStep); + print DEFOUT "TRACKS $direction[$dir] $first DO $steps STEP $trackStep LAYER ${metal}${layer} \;\n"; + } + } +} +print DEFOUT "\n"; + +# +# print power grid tracks for vias to power stripes +# +print DEFOUT "# power grid tracks for horizontal power stripes\n"; +foreach $layer (@powerGridLayers) { + $dir = (($layer-$rotate)%2) ? 1 : 0; + $first = (&ceilCoord($dieAreaCoord[$dir], 0, $powerGridPitch)); + $last = (&floorCoord($dieAreaCoord[2+$dir], 0, $powerGridPitch)); + $steps = 1+POSIX::ceil(($last-$first) / $powerGridPitch); + print DEFOUT "TRACKS $direction[$dir] $first DO $steps STEP $powerGridPitch LAYER ${metal}${layer} \;\n"; +} +print DEFOUT "\n"; + +# +# print gcells +# +$gcellStep = $gcellPitch * $units; +$firstX = ceilCoord($dieAreaCoord[0],0,$gcellStep); +$lastX = floorCoord($dieAreaCoord[2],0,$gcellStep); +$firstY = ceilCoord($dieAreaCoord[1],0,$gcellStep); +$lastY = floorCoord($dieAreaCoord[3],0,$gcellStep); +$stepsX = 1+POSIX::ceil(($lastX-$firstX)/$gcellStep); +$stepsY = 1+POSIX::ceil(($lastY-$firstY)/$gcellStep); + +# grid inside die area +print DEFOUT "GCELLGRID X $firstX DO $stepsX STEP $gcellStep \;\n"; +print DEFOUT "GCELLGRID Y $firstY DO $stepsY STEP $gcellStep \;\n"; + +# grid on the die boundary as well +print DEFOUT "GCELLGRID X $dieAreaCoord[0] DO 1 STEP $gcellStep \;\n"; +print DEFOUT "GCELLGRID X $dieAreaCoord[2] DO 1 STEP $gcellStep \;\n"; +print DEFOUT "GCELLGRID Y $dieAreaCoord[1] DO 1 STEP $gcellStep \;\n"; +print DEFOUT "GCELLGRID Y $dieAreaCoord[3] DO 1 STEP $gcellStep \;\n"; + +# finish and close file +print DEFOUT "\n"; +print DEFOUT "END DESIGN\n" if $outDef; +close(DEFOUT); +print "Wrote $defOutFile\n" if $outDef; +exit; + + +###################################################### +# functions +###################################################### +# error exit +sub errorExit { + print "\nERROR: @_ \n"; + exit 1; +} + +# display error msg +sub errorMsg { + print "ERROR: @_\n"; + $errorCnt++; +} + +# calculate first coordinate rounded down to pitch and offset +sub ceilCoord { + my ($baseCoord, $offset, $pitch) = @_; + return($offset + $pitch * POSIX::ceil(($baseCoord-$offset)/$pitch)); +} + +# calculate last coordinate rounded up to pitch and offset +sub floorCoord { + my ($baseCoord, $offset, $pitch) = @_; + return($offset + $pitch * POSIX::floor(($baseCoord-$offset)/$pitch)); +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/initNanoroute.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/initNanoroute.pl new file mode 100755 index 0000000000..b2587043d3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/initNanoroute.pl @@ -0,0 +1,702 @@ +#!/usr/bin/perl -w +# +# Generate Nanoroute command file to perform the first pass detailed route for +# the specified design. Nanoroute is then invoke using this command file. +# +# trj 12/14/04 +# +###################################################### +# setup +###################################################### +require 'ctime.pl'; + +# +# usage +# +$toolName = "initNanoroute"; +$toolRev = '$Revision$$DateTime$'; +$toolRev =~ s/\$//g; +$toolRev =~ s/DateTime: //; +$logFile = "$toolName.log"; +$cmdFile = "$toolName.tcl"; +$botLayer = 3; +$topLayer = 5; +$maxOptPassDefault = 20; +$maxOptPass = $maxOptPassDefault; +$trackPitchDef = 0.24; +$trackPitchMin = 0.06; +$no_exit = 0; + +$usage = " +Usage: $toolName + + Nanoroute Input Files: + --design= : name of design + [ --verilog= ] : design Verilog file (default=.v) + [ --lef= ] : design LEF file (default=.lef) + [ --def= ] : design DEF file (default=.def) + [ --nd-def= ] : nondefault routing directives DEF + [ --tracks-def= ] : routing track DEF + [ --addl-def= ] : additional DEF files, 1 file per switch in desired order + [ --priority-nets= ] : list of nets for priority routing, design saved after route. + list syntax: 'selectNet ', one net per line. + [ --out-cmd= ] : Nanoroute command file (default=$cmdFile) + + Nanoroute Output Files: + [ --out-priority-db= ] : db with priority routes (default=_priority) + [ --out-routed-db= ] : db with all nets routed (default=_routed) + [ --out-vias-db= ] : db with multi-cut vias (default=_routed_via) + + Nanoroute Configuration: + [ --autoStop-false ] : true causes routing to abort if number of violations are + too high (default), false will force routing to continue. + [ --skip-multi-cut-vias ] : skip routing pass to add multi-cut vias (default is do not + skip), design is saved before and after pass. + [ --bottom-layer= ] : bottom routing layer (default=$botLayer) + [ --top-layer= ] : top routing layer (default=$topLayer) + [ --max-pass= ] : maximum optimization routing passes (default=$maxOptPass) + [ --bundled ] : include bundled channel DEF and TCL + [ --no-exit] : leave interactive session after finishing + $toolName Tool Control: + [ --force ] : overwrite output files if they exist + --fulcrum-pdk-root= : pdk path + [ --log= ] : name of $toolName log file (default=$logFile) + + Other: + [ --track-pitch= ] : (OBSOLETE) routing track pitch in microns (default=$trackPitchDef)"; + + +# +# default and initial argument values +# +$defFile = ""; +$design = ""; +$force = 0; +$pdkRoot = ""; +$lefFile = ""; +$ndDefFile = ""; +$tracksDefFile = ""; +$verilogFile = ""; +$debug = 0; +$errorCnt = 0; +$warningCnt = 0; +$logOpen = 0; +$sumOpen = 0; +@addlDefFiles = (); +$priorityNetsFile = ""; +$autoStop = 1; +$skipMultiCutVias = 0; +$priorityDB = ""; +$routedDB = ""; +$viaDB = ""; +$bundled = 0; + + + +###################################################### +# parse command line +###################################################### +# +# display usage if no args +# +if ($#ARGV < 0) { + print "$usage\n\n"; + exit; +} + +# +# parse args +# +while ($#ARGV>=0) { + + # --help + if ($ARGV[0] eq "--help") { + print "$usage\n\n"; + exit; + } + + # --debug (undocumented arg) + if ($ARGV[0] eq "--debug") { + $debug = 1; + shift(@ARGV); + next; + } + + # + # Nanoroute Input Files + # + # --design= + if ($ARGV[0] =~ /--design=(\S+)/) { + $design = $1; + shift(@ARGV); + next; + } + + # --verilog= + if ($ARGV[0] =~ /--verilog=(\S+)/) { + $verilogFile = $1; + shift(@ARGV); + next; + } + + # --lef= + if ($ARGV[0] =~ /--lef=(\S+)/) { + $lefFile = $1; + shift(@ARGV); + next; + } + + # --def= + if ($ARGV[0] =~ /--def=(\S+)/) { + $defFile = $1; + shift(@ARGV); + next; + } + + # --nd-def= + if ($ARGV[0] =~ /--nd-def=(\S+)/) { + $ndDefFile = $1; + shift(@ARGV); + next; + } + + # --tracks-def= + if ($ARGV[0] =~ /--tracks-def=(\S+)/) { + $tracksDefFile = $1; + shift(@ARGV); + next; + } + + # --addl-def= + if ($ARGV[0] =~ /--addl-def=(\S+)/) { + push(@addlDefFiles, $1); + shift(@ARGV); + next; + } + + # --out-cmd= + if ($ARGV[0] =~ /--out-cmd=(\S+)/) { + $cmdFile = $1; + shift(@ARGV); + next; + } + + # --priority-nets= + if ($ARGV[0] =~ /--priority-nets=(\S+)/) { + $priorityNetsFile = $1; + shift(@ARGV); + next; + } + + # + # Nanoroute Output Files + # + # --out-priority-db= + if ($ARGV[0] =~ /--out-priority-db=(\S+)/) { + $priorityDB = $1; + shift(@ARGV); + next; + } + + # --out-routed-db= + if ($ARGV[0] =~ /--out-routed-db=(\S+)/) { + $routedDB = $1; + shift(@ARGV); + next; + } + + # --out-vias-db= + if ($ARGV[0] =~ /--out-vias-db=(\S+)/) { + $viaDB = $1; + shift(@ARGV); + next; + } + + # + # Nanoroute Configuration + # + # --bottom-layer= + if ($ARGV[0] =~ /--bottom-layer=(\d+)/) { + $botLayer = $1; + shift(@ARGV); + next; + } + + # --top-layer= + if ($ARGV[0] =~ /--top-layer=(\d+)/) { + $topLayer = $1; + shift(@ARGV); + next; + } + + # --max-pass= + if ($ARGV[0] =~ /--max-pass=(\d+)/) { + $maxOptPass = $1; + shift(@ARGV); + next; + } + + # --autoStop-false + if ($ARGV[0] =~ /--autoStop-false/) { + $autoStop = 0; + shift(@ARGV); + next; + } + + # --skip-multi-cut-vias + if ($ARGV[0] =~ /--skip-multi-cut-vias/) { + $skipMultiCutVias = 1; + shift(@ARGV); + next; + } + + # --bundled + if ($ARGV[0] =~ /--bundled/) { + $bundled = 1; + shift(@ARGV); + next; + } + + # --no-exit + if ($ARGV[0] =~ /--no-exit/) { + $no_exit = 1; + shift (@ARGV); + next; + } + + # + # initNanoroute Tool Control + # + # --force + if ($ARGV[0] =~ /--force/) { + $force = 1; + shift(@ARGV); + next; + } + + # --fulcrum-pdk-root= + if ($ARGV[0] =~ /--fulcrum-pdk-root=(\S+)/) { + $pdkRoot = $1; + shift(@ARGV); + next; + } + + # --log= + if ($ARGV[0] =~ /--log=(\S+)/) { + $logFile = $1; + shift(@ARGV); + next; + } + + # + # Other + # + # --track-pitch= + if ($ARGV[0] =~ /--track-pitch=(\d*\.\d+)/) { + #$trackPitch = $1; + &echoMsg("\n--track-pitch no longer used.\n"); + shift(@ARGV); + next; + } + + # unknown argument + &errorExit("Unknown or invalid argument '$ARGV[0]'.\n $usage \n"); +} + + +###################################################### +# validate inputs +###################################################### +# +# check for required arguments +# +&errorExit("--design not specified. \n $usage \n") unless $design; +&errorExit("--fulcrum-pdk-root not specified. \n $usage \n") unless $pdkRoot; + + +# +# define parameters dependent on inputs +# +$verilogFile = "$design.v" unless $verilogFile; +$lefFile = "$design.lef" unless $lefFile; +$defFile = "$design.def" unless $defFile; + +if ($priorityNetsFile) { + $priorityDB = $design . "_priority" unless $priorityDB; + $priorityDefFile = $priorityDB . ".def"; + $priorityNanoDB = $priorityDB . ".enc"; +} + +$routedDB = $design . "_routed" unless $routedDB; +$routedDefFile = $routedDB . ".def"; +$routedNanoDB = $routedDB . ".enc"; + +if (!$skipMultiCutVias) { + $viaDB = $design . "_routed_via" unless $viaDB; + $viaDefFile = $viaDB . ".def"; + $viaNanoDB = $viaDB . ".enc"; +} +$trackPitchFile = "tracks_" . $trackPitch*1000 . ".def" if $trackPitch; + + +# +# validate files and paths +# +&errorExit("--fulcrum-pdk-root dir '$pdkRoot' not found.\n") unless -e $pdkRoot; +&errorExit("--fulcrum-pdk-root '$pdkRoot' not directory.\n") unless -d $pdkRoot; +$techLefFile = $pdkRoot . "/share/Fulcrum/nano/tech.lef"; +&errorExit("Technology LEF file '$techLefFile' not found.\n") unless -e $techLefFile; +$initTclFile = $pdkRoot . "/share/Fulcrum/nano/nano.init.tcl"; +&errorExit("Nanoroute init file '$initTclFile' not found.\n") unless -e $initTclFile; + +# validate existing outputs +if ($priorityNetsFile) { + &errorExit("Priority nets DEF file '$priorityDefFile' already exists. Use --force to overwrite.\n") + if -e $priorityDefFile && !$force; + $priorityNanoDBDir = $priorityNanoDB . ".dat"; + &errorExit("Nanoroute priority nets DB '$priorityNanoDB' already exists. Use --force to overwrite.\n") + if -e $priorityNanoDBDir && !$force; +} + +&errorExit("Routed nets DEF file '$routedDefFile' already exists. Use --force to overwrite.\n") + if -e $routedDefFile && !$force; +$routedNanoDBDir = $routedNanoDB . ".dat"; +&errorExit("Nanoroute routed nets DB '$routedNanoDB' already exists. Use --force to overwrite.\n") + if -e $routedNanoDBDir && !$force; + +if (!$skipMultiCutVias) { + &errorExit("Multi-cut via nets DEF file '$viaDefFile' already exists. Use --force to overwrite.\n") + if -e $viaDefFile && !$force; + $viaNanoDBDir = $viaNanoDB . ".dat"; + &errorExit("Nanoroute priority nets DB '$viaNanoDB' already exists. Use --force to overwrite.\n") + if -e $viaNanoDBDir && !$force; +} + +&errorExit("--track-pitch $trackPitch must be multiple of $trackPitchMin micron\n") + if $trackPitch && (($trackPitch*1000)%($trackPitchMin*1000)); + + +###################################################### +# Log Options +###################################################### +open(LOG, ">$logFile") || &errorExit("Unable to open log file '$logFile': $!\n"); +$logOpen = 1; +$sumFile = substr($logFile, 0, length($logFile)-3); +$sumFile .= "sum"; +open(SUM, ">$sumFile") || &errorExit("Unable to open summary file '$sumFile': $!\n"); +$sumOpen = 1; + +&echoMsg("\n$toolName, $toolRev \n"); +&echoMsg("\n"); +&echoMsg("Nanoroute Input Files:\n"); +&echoMsg(" Design Name = $design\n"); +&echoMsg(" Design Verilog = $verilogFile\n"); +&echoMsg(" Design LEF = $lefFile\n"); +&echoMsg(" Design DEF = $defFile\n"); +&echoMsg(" Nondefault DEF = $ndDefFile\n") if $ndDefFile; +for($i=0; $i<=$#addlDefFiles; $i++) { + &echoMsg(" Additional DEF = $addlDefFiles[$i]\n"); +} +&echoMsg(" Tracks DEF = $tracksDefFile\n") if $tracksDefFile; +&echoMsg(" Track Pitch DEF = $trackPitchFile\n") if $trackPitchFile; +&echoMsg(" Priority Nets = $priorityNetsFile\n") if $priorityNetsFile; +&echoMsg(" Command File = $cmdFile\n"); +&echoMsg("\n"); + +# validate input files +&errorMsg("--verilog file '$verilogFile' not found.") unless -e $verilogFile; +&errorMsg("--lef file '$lefFile' not found.") unless -e $lefFile; +&errorMsg("--def file '$defFile' not found.") unless -e $defFile; +&errorMsg("--nd-def file '$ndDefFile' not found.") if $ndDefFile && !-e $ndDefFile; +for($i=0; $i<=$#addlDefFiles; $i++) { + &errorMsg("--addl-def file '$addlDefFiles[$i]' not found.") unless -e $addlDefFiles[$i] +} +&errorMsg("--tracks-def file '$tracksDefFile' not found.") if $tracksDefFile && !-e $tracksDefFile; +&errorMsg("--priority-nets file '$priorityNetsFile' not found.") if $priorityNetsFile && !-e $priorityNetsFile; + +&echoMsg("\n") if $errorCnt; + +&echoMsg("Nanoroute Output Files:\n"); +&echoMsg(" Priority Nets DB = $priorityDB\n") if $priorityNetsFile; +&echoMsg(" Routed Nets DB = $routedDB\n"); +&echoMsg(" Multi-Cut Vias DB = $viaDB\n") unless $skipMultiCutVias; +&echoMsg("\n"); + +&echoMsg("Nanoroute Options:\n"); +&echoMsg(" Route Auto Stop = "); +$autoStop?&echoMsg("true"):&echoMsg("false"); +&echoMsg("\n"); +&echoMsg(" Route Priority Nets = "); +$priorityNetsFile?&echoMsg("true"):&echoMsg("false"); +&echoMsg("\n"); +&echoMsg(" Skip Multi-Cut Vias = "); +$skipMultiCutVias?&echoMsg("true"):&echoMsg("false"); +&echoMsg("\n"); +&echoMsg(" Bottom Routing Layer = $botLayer\n"); +&echoMsg(" Top Routing Layer = $topLayer\n"); +&echoMsg(" Use Bundled Channels = $bundled\n"); +&echoMsg(" Max Passes = $maxOptPass"); +&echoMsg(" (default)") if $maxOptPass == $maxOptPassDefault; +&echoMsg("\n"); + + + +&echoMsg(" Track Pitch = $trackPitch\n") if $trackPitch; +&echoMsg("\n"); + + +###################################################### +# Create track pitch file +###################################################### +if ($trackPitch) { + &echoMsg("Generating routing tracks def file...\n"); + $cmd = "genTracks --refdef=$defFile --outfile=$trackPitchFile"; + $cmd .= " --track-pitch=$trackPitch --force"; + &echoMsg(" Command: $cmd\n ") if $debug; + open(CMD, "$cmd |") || &errorMsg("Command '$cmd' failed: $!\n"); + @tmp = ; + close(CMD); + &echoMsg(" ", @tmp); + &echoMsg("\n"); +} + + +###################################################### +# Create command file +###################################################### +open(CMD, ">$cmdFile") || &errorExit("Unable to open command file '$cmdFile': $!\n"); + +# +# log options +# +print CMD "########################################################################################\n"; +print CMD "#\n"; +print CMD "# Created by $toolName, $toolRev \t", &ctime(time); +print CMD "#\n"; +print CMD "# Nanoroute Input Files:\n"; +print CMD "# Design Name = $design\n"; +print CMD "# Design Verilog = $verilogFile\n"; +print CMD "# Design LEF = $lefFile\n"; +print CMD "# Design DEF = $defFile\n"; +print CMD "# Nondefault DEF = $ndDefFile\n" if $ndDefFile; +for($i=0; $i<=$#addlDefFiles; $i++) { + print CMD "# Additional DEF = $addlDefFiles[$i]\n"; +} +print CMD "# Tracks DEF = $tracksDefFile\n" if $tracksDefFile; +print CMD "# Track Pitch DEF = $trackPitchFile\n" if $trackPitchFile; +print CMD "# Priority Nets = $priorityNetsFile\n" if $priorityNetsFile; +print CMD "# Command File = $cmdFile\n"; +print CMD "#\n"; +print CMD "# Nanoroute Output Files:\n"; +print CMD "# Priority Nets DB = $priorityDB\n" if $priorityNetsFile; +print CMD "# Routed Nets DB = $routedDB\n"; +print CMD "# Multi-Cut Vias DB = $viaDB\n" unless $skipMultiCutVias; +print CMD "#\n"; +print CMD "# Nanoroute Options:\n"; +print CMD "# Route Auto Stop = "; +$autoStop?print CMD "true":print CMD "false"; +print CMD "\n"; +print CMD "# Route Priority Nets = "; +$priorityNetsFile?print CMD "true":print CMD "false"; +print CMD "\n"; +print CMD "# Skip Multi-Cut Vias = "; +$skipMultiCutVias?print CMD "true":print CMD "false"; +print CMD "\n"; +print CMD "# Bottom Routing Layer = $botLayer\n"; +print CMD "# Top Routing Layer = $topLayer\n"; +print CMD "# Max Passes = $maxOptPass"; +print CMD " (default)" if $maxOptPass == $maxOptPassDefault; +print CMD "\n"; +print CMD "# Track Pitch = $trackPitch\n" if $trackPitch; +print CMD "#\n"; +print CMD "########################################################################################\n"; +print CMD "#\n"; +print CMD "# Command line usage: \n"; +print CMD "# fulcrum encounter -init [-64] [-SOCE|-socel] [-nowin]\n"; +print CMD "# -init Load and run cmdFile (this script). Script must exit when using qsub.\n"; +print CMD "# -64 64-bit executable. Implied on 64-bit machines. Required for >4GB memory.\n"; +print CMD "# -SOCE Use full SOC Encounter license (Default).\n"; +print CMD "# -socel Use limited SOC Encounter DBS license.\n"; +print CMD "# -nowin No graphics window, ie command line mode. Required for qsub.\n"; +print CMD "#\n"; +print CMD "\n"; + + +# +# include init file +# +open(INIT, "$initTclFile") || &errorExit("Unable to open Nanoroute init file '$initTclFile': $!\n"); +while () { + print CMD $_; +} +close(INIT); + + +# +# setup design options +# +print CMD "\n"; +print CMD "#\n"; +print CMD "# user defined mode settings\n"; +print CMD "#\n"; +print CMD "setNanoRouteMode -quiet -routeTopRoutingLayer $topLayer\n"; +print CMD "setNanoRouteMode -quiet -routeBottomRoutingLayer $botLayer\n"; +print CMD "setNanoRouteMode -quiet -drouteEndIteration "; +if ($maxOptPass == $maxOptPassDefault) { + print CMD "default\n"; +} else { + print CMD "$maxOptPass\n"; +} +print CMD "setNanoRouteMode -quiet -drouteAutoStop "; +$autoStop?print CMD "true":print CMD "false"; +print CMD "\n"; +print CMD "#########################################################################################\n"; +print CMD "# To force Nanoroute to continue as specified by the drouteEndIteration \n"; +print CMD "# variable despite the number of violations, set drouteAutoStop to false\n"; +print CMD "#########################################################################################\n"; +print CMD "\n"; + +# +# load design files +# +print CMD "#\n"; +print CMD "# load design\n"; +print CMD "#\n"; +print CMD "set rda_Input(ui_netlist) \"$verilogFile\"\n"; +print CMD "set rda_Input(ui_netlisttype) {Verilog}\n"; +print CMD "set rda_Input(ui_topcell) {\\$design}\n"; +print CMD "set rda_Input(ui_leffile) \"$techLefFile $lefFile\"\n"; +print CMD "commitConfig\n"; +print CMD "\n"; + +print CMD "if {[file exists \"$design.GNDShieldTieOff.tcl\" ] == 1} {\n"; +print CMD " source $design.GNDShieldTieOff.tcl\n"; +print CMD " AddTieOffCell\n"; +print CMD "}\n"; +print CMD "\n"; + +print CMD "defIn $defFile\n"; +print CMD "defIn $ndDefFile\n" if $ndDefFile; +for($i=0; $i<=$#addlDefFiles; $i++) { + print CMD "defIn $addlDefFiles[$i]\n"; +} +print CMD "defIn $tracksDefFile\n" if $tracksDefFile; +print CMD "defIn $trackPitchFile\n" if $trackPitch; +print CMD "\n"; + +# +# optionally route priority nets +# +if ($priorityNetsFile) { + print CMD "#\n"; + print CMD "# route priority nets\n"; + print CMD "#\n"; + print CMD "########################################################################################\n"; + print CMD "# Priority nets list file syntax: selectNet \n"; + print CMD "# List one net per line. Wild cards are acceptable.\n"; + print CMD "########################################################################################\n"; + print CMD "source $priorityNetsFile\n"; + print CMD "setNanoRouteMode -quiet -routeSelectedNetOnly true\n"; + print CMD "globalDetailRoute\n"; + print CMD "saveDesign $priorityNanoDB\n"; + print CMD "defOut -floorplan -netlist -routing $priorityDefFile\n"; + print CMD "\n"; +} + +# +# route all unrouted nets (remainder in case of priority routing) +# + +print CMD "# insert skiproutes here. syntax - setAttribute -net ts\\[* -skip_routing true \n"; +print CMD "#\n"; + +print CMD "#\n"; +print CMD "# route all nets\n"; +print CMD "#\n"; +if ($bundled) { + print CMD "defIn ${design}_bundled.def\n"; + print CMD "source ${design}_bundled.tcl\n"; +} else { + print CMD "setNanoRouteMode -quiet -routeSelectedNetOnly false\n"; +} +print CMD "routeDesign\n"; +print CMD "saveDesign $routedNanoDB\n"; +print CMD "defOut -floorplan -netlist -routing \\\n $routedDefFile\n"; + +# +# add multi-cut vias +# +if (!$skipMultiCutVias) { + print CMD "\n"; + print CMD "#\n"; + print CMD "# add multi-cut vias\n"; + print CMD "#\n"; + + print CMD "if {[file exists \"$design.SetSkipRouting.tcl\" ] == 1} {\n"; + print CMD " source $design.SetSkipRouting.tcl\n"; + print CMD " ProteusUserSetSkipRouting\n"; + print CMD "}\n"; + print CMD "\n"; + + print CMD "setNanoRouteMode -quiet \\\n"; + print CMD " -droutePostRouteSwapVia multiCut \\\n"; + print CMD " -drouteUseMultiCutViaEffort medium\n"; + print CMD "routeDesign -viaOpt\n"; + + print CMD "saveDesign $viaNanoDB\n"; + print CMD "defOut -floorplan -netlist -routing \\\n $viaDefFile\n"; +} + +print CMD "\n"; +if ($no_exit==0) { + print CMD "exit\n"; +} +close(CMD); + +###################################################### +# Done. +###################################################### +DONE: +&echoMsg("$toolName Done\n"); +&echoMsg(" Warnings: $warningCnt\n"); +&echoMsg(" Errors: $errorCnt\n"); +&echoMsg("\n"); +close(LOG); +print SUM "$toolName Done\n"; +print SUM " Warnings: $warningCnt\n"; +print SUM " Errors: $errorCnt\n"; +close(SUM); +exit; + + +###################################################### +# functions +###################################################### +# echo output to std & log +sub echoMsg { + print "@_"; + print LOG "@_" if $logOpen; +} + +# error exit +sub errorExit { + &echoMsg("\nERROR: @_ \n"); + if( $sumOpen ) { + print SUM "$toolName FAILED.\n"; + print SUM "\nERROR: @_ \n"; + } + exit 1; +} + +# display error msg +sub errorMsg { + &echoMsg("ERROR: @_\n"); + $errorCnt++; +} + +# display warning msg +sub warningMsg { + &echoMsg("WARNING: @_\n"); + $warningCnt++; +} + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/listMissingAbstracts.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/listMissingAbstracts.pl new file mode 100755 index 0000000000..c03d5d6d35 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/nano/listMissingAbstracts.pl @@ -0,0 +1,426 @@ +#!/usr/bin/perl +# +# Verify presence of dfII abstract cellviews for the specific list of cells. +# Sort list into leaf, mid and power cells. +# +# trj 5/10/06 +# +###################################################### +# setup +###################################################### +require 'ctime.pl'; + + +# +# usage +# +$toolName = "listMissingAbstracts"; +$cellListFile = "flatten_cells_list"; +$logFile = $toolName . ".log"; +$toolRev = '$Revision: #3 $$DateTime: 2006/04/26 11:33:34 $'; +$toolRev =~ s/\$//g; +$toolRev =~ s/DateTime: //; +$maxHeapSize = "1800M"; + +$usage = " +Usage: $toolName + --cast-path= : path to cast and spec directories + [ --cell-list= ] : cells in design to verify (default=$cellListFile) + --design= : name of design + --dfII-dir= : dfII path + [ --log= ] : name of log file (default=$logFile) + [ --max-heap-size= ] : java max-heap-size to use for cast_query (default=$maxHeapSize) + [ --regen-leaf-list ] : regenerate leaf cell list using cast_query"; + + +# +# default and initial argument values +# +$castPath = ""; +$design = ""; +$dfiiDir = ""; +$regenLeafList = 0; +$debug = 0; + + +# +# more inits +# +$logOpen = 0; +$sumOpen = 0; +$errorCnt = 0; +$warningCnt = 0; +$cellListCnt = 0; +$cellListErrors = 0; +$leafCnt = 0; +$missingAbsCnt = 0; +$missingLeafCnt = 0; +$missingMidCnt = 0; +$missingOtherCnt = 0; +$missingCellsList = "missingAbstracts"; +$missingLeafFile = $missingCellsList . ".leaf"; +$missingMidFile = $missingCellsList . ".mid"; +$missingOtherFile = $missingCellsList . ".other"; +$leafCellListFile = $toolName . ".leaf"; +$userAbsView = "abstract_edit"; +$castQueryLog = "cast_query.log"; + + +###################################################### +# parse command line +###################################################### +# +# display usage if no args +# +if ($#ARGV < 0) { + print "$usage\n\n"; + exit; +} + + +# +# parse args +# +while ($#ARGV>=0) { + + # --help + if ($ARGV[0] eq "--help") { + print "$usage\n\n"; + exit; + } + + # --debug (undocumented arg) + if ($ARGV[0] eq "--debug") { + $debug = 1; + shift(@ARGV); + next; + } + + # --cast-path= + if ($ARGV[0] =~ /--cast-path=(\S+)/) { + $castPath = $1; + shift(@ARGV); + next; + } + + # --cell-list= + if ($ARGV[0] =~ /--cell-list=(\S+)/) { + $cellListFile = $1; + shift(@ARGV); + next; + } + + # --design= + if ($ARGV[0] =~ /--design=(\S+)/) { + $design = $1; + shift(@ARGV); + next; + } + + # --dfII-dir= + if ($ARGV[0] =~ /--dfII-dir=(\S+)/) { + $dfiiDir = $1; + shift(@ARGV); + next; + } + + # --log= + if ($ARGV[0] =~ /--log=(\S+)/) { + $logFile = $1; + shift(@ARGV); + next; + } + + # --max-heap-size= + if ($ARGV[0] =~ /--max-heap-size=(\S+)/) { + $maxHeapSize = $1; + shift(@ARGV); + next; + } + + # --regen-leaf-list + if ($ARGV[0] =~ /--regen-leaf-list/) { + $regenLeafList = 1; + shift(@ARGV); + next; + } + + # unknown argument + &errorExit("Unknown or invalid argument '$ARGV[0]'.\n $usage \n"); +} + + +###################################################### +# validate inputs +###################################################### +# +# check for required arguments +# +&errorExit("--cast-path not specified.\n $usage \n") unless $castPath; +&errorExit("--design not specified.\n $usage \n") unless $design; +&errorExit("--dfII-dir not specified.\n $usage \n") unless $dfiiDir; + + +# +# validate paths & files +# +#&errorExit("cast-path '$castPath' not found.\n") unless -e $castPath; +#&errorExit("cast-path '$castPath' not a directory.\n") unless -d $castPath; +&errorExit("cell-list '$cellListFile' not found.\n") unless -e $cellListFile; +&errorExit("dfII-dir '$dfiiDir' not found.\n") unless -e $dfiiDir; +&errorExit("dfII-dir '$dfiiDir' not a directory.\n") unless -d $dfiiDir; + + +# +# log options +# +open(LOG, ">$logFile") || &errorExit("Unable to open log file '$logFile': $!\n"); +$logOpen = 1; +$sumFile = substr($logFile, 0, length($logFile)-3); +$sumFile .= "sum"; +open(SUM, ">$sumFile") || &errorExit("Unable to open summary file '$sumFile': $!\n"); +$sumOpen = 1; +&echoMsg("\n$toolName, $toolRev\n"); +&echoMsg(" $toolName started at ", &ctime(time)); +&echoMsg("\n"); +&echoMsg(" Cast Path = $castPath\n"); +&echoMsg(" dfII Dir = $dfiiDir\n"); +&echoMsg(" Cell List File = $cellListFile\n"); +&echoMsg(" Design = $design\n"); +&echoMsg("\n"); + + +########################################################################## +# create and parse leaf cell list +########################################################################## +# +# create leaf cell list +# +if ($regenLeafList || !-e $leafCellListFile) { + &echoMsg("Generate leaf cell list...\n"); + system("rm -f $leafCellListFile") if -e $leafCellListFile; + $castQueryCmd = "cast_query --cadence-name --cast-path=$castPath --cell=$design --task=subcells --filter=leaf --translate=cadence --output=$leafCellListFile --max-heap-size=$maxHeapSize &> $castQueryLog"; + &echoMsg(" Command: $castQueryCmd\n"); + system($castQueryCmd); + &errorExit("Unable to create leaf cell list. See $castQueryLog.\n") unless -e $leafCellListFile; +} + + +# +# parse leaf cell list +# +&echoMsg("Parse leaf cell list...\n"); +open(LEAF, $leafCellListFile) || &errorExit("Unable to open leaf cell list '$leafCelllist': $!\n"); +while () { + if (/(\S+)/) { + $leafCnt++; + $leafCellList{&decodeName($1)} = 1; + } +} +&echoMsg(" Found $leafCnt leaf cells.\n"); +close(LEAF); + + +########################################################################## +# parse cell list +########################################################################## +&echoMsg("Parse cell list...\n"); +open(CELL, $cellListFile) || &errorExit("Unable to open leaf cell list '$cellListFile': $!\n"); +while () { + next if /^\s*$/ || /^#/; + if (/\s*(\S+)\s+(\S+)/) { + ($lib, $cell) = ($1, $2); + $cellListCnt++; + $cellList{&decodeName($cell)} = $lib; + } else { + $cellListErrors++; + &warningMsg("Unable to process cell list line '$_'\n"); + } +} +&echoMsg(" Found $cellListCnt cells in cell list.\n"); +close(CELL); + + +########################################################################## +# check for missing abstracts +########################################################################## +&echoMsg("Check for missing abstracts...\n"); +foreach $cell (sort(keys %cellList)) { + &echoMsg(" Check cell $cell...\n") if $debug; + + # verify cell path exists + $cellPath = join('/', ($dfiiDir, split('\.',$cellList{$cell}), $cell)); + &echoMsg(" Path=$cellPath\n") if $debug; + if (!-e $cellPath) { + &errorMsg("Cell '$cell' in cell-list not found in dfII-dir"); + $cellListErrors++; + next; + } + + # verify abstract or abstract_edit exists + $abstractCDB = $cellPath . "/abstract/layout.cdb"; + $abstractEditCDB = $cellPath . "/abstract_edit/layout.cdb"; + next if -e $abstractCDB || -e $abstractEditCDB; + + # not found -- sort into missing cell class + $missingAbsCnt++; + &echoMsg(" Abstract not found for &encodeName($cell)\n") if $debug; + if ($cell =~ /#2ewires#2e/) { + $missingOtherList[$missingOtherCnt] = &encodeName($cell); + $missingOtherCnt++; + } elsif ($leafCellList{$cell}) { + $missingLeafList[$missingLeafCnt] = &encodeName($cell); + $missingLeafCnt++; + } else { + $missingMidList[$missingMidCnt] = &encodeName($cell); + $missingMidCnt++; + } +} + + +###################################################### +# Show results and write out list files +###################################################### +&echoMsg(" Discovered $missingAbsCnt missing abstracts.\n"); +&echoMsg("\n"); + +# delete old missing files +system("rm -f $missingLeafFile") if -e $missingLeafFile; +system("rm -f $missingMidFile") if -e $missingMidFile; +system("rm -f $missingOtherFile") if -e $missingOtherFile; + +# leaf cells +if ($missingLeafCnt) { + &echoMsg("The following $missingLeafCnt leaf cells are missing abstracts:\n"); + open(OUT, ">$missingLeafFile") || &errorExit("Unable to open list file '$missingLeafFile': $!\n"); + for($i=0; $i<$missingLeafCnt; $i++) { + print OUT "$missingLeafList[$i]\n"; + &echoMsg(" $missingLeafList[$i]\n"); + } + close(OUT); + &echoMsg("\n"); +} + +# mid cells +if ($missingMidCnt) { + &echoMsg("The following $missingMidCnt mid-level cells are missing abstracts:\n"); + open(OUT, ">$missingMidFile") || &errorExit("Unable to open list file '$missingMidFile': $!\n"); + for($i=0; $i<$missingMidCnt; $i++) { + print OUT "$missingMidList[$i]\n"; + &echoMsg(" $missingMidList[$i]\n"); + } + close(OUT); + &echoMsg("\n"); +} + +# other cells +if ($missingOtherCnt) { + &echoMsg("The following $missingOtherCnt other cells are missing abstracts:\n"); + open(OUT, ">$missingOtherFile") || &errorExit("Unable to open list file '$missingOtherFile': $!\n"); + for($i=0; $i<$missingOtherCnt; $i++) { + print OUT "$missingOtherList[$i]\n"; + &echoMsg(" $missingOtherList[$i]\n"); + } + close(OUT); + &echoMsg("\n"); +} + + +###################################################### +# Summary +###################################################### + +&echoMsg("\n"); +&echoMsg("Summary:\n"); +&echoMsg(" Cells in cell-list = $cellListCnt \n"); +&echoMsg(" Cells not checked = $cellListErrors\n"); +&echoMsg(" Total missing abstracts = $missingAbsCnt\n"); +&echoMsg(" Leaf cell abstracts = $missingLeafCnt\n"); +&echoMsg(" Mid-level cell abstracts = $missingMidCnt\n"); +&echoMsg(" Other abstracts = $missingOtherCnt\n"); +&echoMsg("\n"); +&echoMsg(" WARNINGS: $warningCnt\n"); +&echoMsg(" ERRORS: $errorCnt\n"); +&echoMsg("Done\t", &ctime(time)); + +print SUM "Summary:\n"; +print SUM " Cells in cell-list = $cellListCnt \n"; +print SUM " Cells not checked = $cellListErrors\n"; +print SUM " Total missing abstracts = $missingAbsCnt\n"; +print SUM " Leaf cell abstracts = $missingLeafCnt\n"; +print SUM " Mid-level cell abstracts = $missingMidCnt\n"; +print SUM " Other abstracts = $missingOtherCnt\n"; +print SUM "\n"; +print SUM " WARNINGS: $warningCnt\n"; +print SUM " ERRORS: $errorCnt\n"; +exit; + + +###################################################### +# functions +###################################################### +# echo output to std & log +sub echoMsg { + print "@_"; + print LOG "@_" if $logOpen; +} + +# error exit +sub errorExit { + &echoMsg("\nERROR: @_ \n"); + if( $sumOpen ) { + print SUM "$toolName FAILED.\n"; + print SUM "\nERROR: @_ \n"; + } + exit 1; +} + +# display error msg +sub errorMsg { + &echoMsg("ERROR: @_\n"); + $errorCnt++; +} + +# display warning msg +sub warningMsg { + &echoMsg("WARNING: @_\n"); + $warningCnt++; +} + +# decode dfii name -- change \W to #xx +sub decodeName { + my $name = $_[0]; + if ($name =~ /\W/) { + $name = $` . "#" . sprintf("%x", ord($&)) . &decodeName($'); + } + return($name); +} + +# encode dfii name +# +# not generic -- only translates #2e,#2d +sub encodeName { + my $name = $_[0]; + $name =~ s/#2e/./g; + $name =~ s/#2d/-/g; + return($name); +} + +# escape name +sub escapeName { + my $name = $_[0]; + my $origName = $name; + $name =~ s/\[/\\\[/g; + $name =~ s/\]/\\\]/g; + $name =~ s/\(/\\\(/g; + $name =~ s/\)/\\\)/g; + $name =~ s/\{/\\\{/g; + $name =~ s/\}/\\\}/g; + print " Mapping $origName to $name\n" if $debug2; + return($name); +} + +# max +sub max { + return($_[0]>$_[1]?$_[0]:$_[1]); +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/plotdensity.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/plotdensity.pl new file mode 100755 index 0000000000..a471e51443 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/plotdensity.pl @@ -0,0 +1,436 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +sub min { $_[0] < $_[1] ? $_[0] : $_[1] } +sub max { $_[0] > $_[1] ? $_[0] : $_[1] } + +my $gdsfile=""; +my $printer=""; +my $outfile=""; +my $maxcolors=10; +my $minlayer=1; +my $maxlayer=8; +my $runassura=1; +my $runname="cov"; +my $cellname=""; +my $gridsize=4.8; +my $workingdir="./"; +my $viewname="layout"; +my $verbose=0; +my $mode="x"; +my $layouttype="df2"; +my $dfIIdir=""; +my @rainbow; +my $pdkroot; + +sub checkoptions { + my $err=0; + if (! ( $mode =~ /^[xpgd]/) ) { + print STDERR "Illegal output mode '$mode', must be X11, gif, dwg, or ps"; + $err++; + } + if ($mode =~ /^p/i and $printer ne "") { + my $rslt=`lpq -P$printer 2>/dev/null | grep -c ready`; + chomp $rslt; + if (! $rslt) { + print STDERR "Printer $printer does not exist"; + $err++; + } + } + if ($layouttype ne "df2" and ! -r "$gdsfile" and $runassura ) { + print STDERR "gds2 mode requires gds file"; + $err++; + } + if (! -d "$workingdir" or ! -w "$workingdir" ) { + print STDERR "Working directory '$workingdir' cannot be used"; + $err++; + } + if ( $cellname eq "" and $runassura ) { + print STDERR "Cell name required"; + $err++; + } + if (! $runassura and ! -f "$runname.cov" ) { + print STDERR "$runname.cov is missing"; + $err++; + } + $err; +} + +my @unlink=( + "alc", "ilc", "bbc", "bcr", "cnv", + "dat", "dvc", "elf", "env", "erd", + "err", "erx", "glt", "gmp", "gsm", + "hdr", "lyr", "map", "msg", "nrc", + "sum", "svi", "tmp", "trn", "xcn", +); + +sub usage { + my $cmd=$0; + $cmd =~ s:.*/::; + print STDERR < : number of bins in histogram + --gds2-file : gds2 file if required + --grid : grid (default 4.8) + --highest # : top layer to analyze (1-8) + --lowest # : bottom layer to analyze (1-8) + --mode (d|g|p|x) : dwg, gif, ps(postscript), X11 + --run-name : run name prefix to use + --verbose : a little debugging info + --view-name : view name for df2 mode + --source : one of df2 or gds2 + --working-dir : where to run from +EU + exit 1; +} + +my %options = ( + "assura!" => \$runassura, + "bins=i" => \$maxcolors, + "dfII-dir=s" => \$dfIIdir, + "gds2-file=s" => \$gdsfile, + "grid=f" => \$gridsize, + "highest-layer=i"=> \$maxlayer, + "lowest-layer=i" => \$minlayer, + "mode=s" => \$mode, + "printer=s" => \$printer, + "P=s" => \$printer, + "run-name=s" => \$runname, + "verbose" => \$verbose, + "view-name=s" => \$viewname, + "source=s" => \$layouttype, + "working-dir=s" => \$workingdir, + "fulcrum-pdk-root=s" => \$pdkroot, + "help" => sub { usage; }, +); + +sub dorainbow { + my $n=int(($maxcolors+1)/2+0.51); + my $r=0; + my $g=0; + my $b=0; + my $j=0; + for (my $i = 0; $i < ($maxcolors % 2 ? $n : $n-1); $i++) { + $g = $i*255/($n/2); + $b = ($n-1-$i)*255/($n/2); + $rainbow[$j]= + sprintf "#%02x%02x%02x", $r,$g>255 ? 255:$g,$b>255?255:$b; + $j++; + } + for (my $i = 1; $i < $n; $i++) { + $r = $i*255/($n/2); + $g = ($n-1-$i)*255/($n/2); + $rainbow[$j]= + sprintf "#%02x%02x%02x", $r>255?255:$r,$g>255 ? 255:$g,$b>255?255:$b; + $j++; + } +} + +sub assura { + my $gdscellname; + my $dfIIcellname; + if ($layouttype eq "df2" ) { + $dfIIcellname=`echo "$cellname" | rename --type=cell --from=cast --to=cadence`; + chomp $dfIIcellname; + } + else { + $gdscellname=`echo "$cellname" | rename --type=cell --from=cast --to=gds2`; + chomp $gdscellname; + } + open (RSF, ">$runname.rsf"); + print RSF <$runname.rul"); + print RUL < 0.05 windowSize = gridSize stepSize = gridSize ))" i i ) apply( stringToFunction(ks) nil) println(ks) ) + i++) + for(i layerNumberLowest layerNumberHighest + list(ks=sprintf(nil + "(m%dcov=geomGetCoverage( md%d keep > 0.05 squareSize = gridSize ))" i i ) apply( stringToFunction(ks) nil) println(ks) ) + i++) +) +RUL + close RUL; + if ( ! -f "cds.lib" and $layouttype eq "df2" ) { + if ( -d "$dfIIdir" ) { + open (LIB, ">cds.lib"); + print LIB </dev/null"; + } + else { + system "assura assura $runname.rsf 1>/dev/null"; + } +} + +GetOptions ( %options ) or usage; +$ENV{FULCRUM_PDK_ROOT}=$pdkroot + if ! defined $ENV{FULCRUM_PDK_ROOT}; + +$cellname = $ARGV[0] if $cellname eq "" and defined $ARGV[0]; +$gridsize = max ( $gridsize, 0.1); + +$runname .= $layouttype; + +$outfile = "$runname"."$layouttype" if $outfile eq ""; + +$maxcolors = max ($maxcolors, 2); +$minlayer = max (min ($maxlayer, $minlayer), 1); +$maxlayer = max (min ($maxlayer, 8), 1); + +checkoptions and usage; +dorainbow; +chdir $workingdir; + +if ( ( $runassura and assura ) or ! -f "$runname.cov" ) { + print STDERR "Assura Failed"; + exit 1; +} +if ($runassura) { + foreach my $ext (@unlink) { + unlink "$runname.$ext"; + } +} +my %density=(); +my ($minx,$miny,$maxx,$maxy); +my (@minx, @miny, @maxx, @maxy); +my %layers=(); +open (P, "<$runname.cov"); +my $rule=0; +my $cell; +my $layer; +my $dx=1e6; +my $dy=1e6; +while (

    ) { + chomp; + my @f=split; + if (/^Cell/) { + $cell=$f[3]; + $cell =~ s/_D_/./g; + $cell =~ s/_U_/_/g; + } + if (/^Rule/) { + $rule = $f[2]; + $layer = $f[4]; + $layer =~ s/geomGetCoverage.//; + $layer =~ s/[a-z]//g; + $layers{$layer}=$layer; + } + if ($f[1] eq "X") { + $density{"$layer"}->{"$f[2]:$f[3]"}=$f[6]; + if (defined ($minx[$layer])) { + $minx[$layer] = min $minx[$layer],$f[2]; + $maxx[$layer] = max $maxx[$layer],$f[4]; + $miny[$layer] = min $miny[$layer],$f[3]; + $maxy[$layer] = max $maxy[$layer],$f[5]; + } + else { + $dx = max(min($f[4]-$f[2],$dx),0); + $dy = max(min($f[5]-$f[3],$dy),0); + $minx[$layer] = $f[2]; + $miny[$layer] = $f[3]; + $maxx[$layer] = $f[4]; + $maxy[$layer] = $f[5]; + } + if (defined ($minx)) { + $minx = min $minx,$f[2]; + $maxx = max $maxx,$f[4]; + $miny = min $miny,$f[3]; + $maxy = max $maxy,$f[5]; + } + else { + $minx = $f[2]; + $miny = $f[3]; + $maxx = $f[4]; + $maxy = $f[5]; + } + } +} +close P; +$dx = sprintf "%.3f", $dx; +$dy = sprintf "%.3f", $dy; +my $fill=0; +my $scale; + +sub color { + my ($color)=@_; + if ($fill ne $color) { + print "f $color"; + $fill = $color; + } +} + +sub rect { + my ($x1,$y1,$x2,$y2,$f)=@_; + color($rainbow[$f]); + printf "r %.5f %.5f %.5f %.5f 1\n", + $x1, $y1, $x2, $y2; +} + +sub line { + my ($x1,$y1,$x2,$y2,$w)=@_; + color (0); + printf "l %.5f %.5f %.5f %.5f $w\n", + $x1, $y1, $x2, $y2; +} + +sub text { + my ($x1,$y1,$f,$t)=@_; + color (0); + printf "t %.5f %.5f $f \"$t\"\n", $x1, $y1, $t; +} + +my $layer=0; +$scale = min 7/($maxx-$minx), 7/($maxy-$miny); +foreach my $layer (sort keys %density) { + if ($minx[$layer] < $maxx[$layer] and $miny[$layer] < $maxy[$layer]) { + if ($mode =~ /^d/i) { + open (X, ">$outfile.$layer.dwg"); + print STDERR "Writing $outfile.$layer.dwg" if $verbose; + } + elsif ($mode =~ /^g/i) { + open (X, "| gifdwg > $outfile.$layer.gif"); + print STDERR "Writing $outfile.$layer.gif" if $verbose; + } + elsif ($mode =~ /^p/i) { + if ($printer ne "") { + open (X, "| dwg -P$printer"); + print STDERR "Printing Layer METAL$layer" if $verbose; + } + else { + open (X, "| dwg -o $outfile.$layer.ps"); + print STDERR "Writing $outfile.$layer.ps" if $verbose; + } + } + else { + open (X, "| xdwg"); + print STDERR "Displaying Layer METAL$layer" if $verbose; + } + select X; + my $total=0; + my @hist=(); + my $n=0; + print "s 0 1"; + print "x 0"; + print "y 0"; + my %dn=%{$density{$layer}}; + foreach my $key (keys %dn) { + my ($x,$y)=split(/:/,$key); + my $d = $dn{$key}; + $d = max(int($d*$maxcolors-1e-6), 0); + $hist[$d]++; + $total++; + rect (($x-$minx)*$scale, + ($maxy-$y)*$scale, + ($x+$dx-$minx)*$scale, + ($maxy-$y-$dy)*$scale, $d); + } + my $dtx=0.6; + my $caption=8.5; + color (0); + line (($maxx-$minx)*$scale+0.5, $maxy*$scale, -0.5, $maxy*$scale, 2); + line (-$minx*$scale, ($maxy-$miny)*$scale+0.5, -$minx*$scale, -0.5, 2); + text (0, $caption+0.6, 3, "METAL$layer $cell"); + for ($n = 0; $n < $maxcolors; $n++) { + rect $n*$dtx, $caption, $n*$dtx+0.1, $caption+0.1, $n; + text (($n-0.33)*$dtx, $caption+0.25, 1, + sprintf ("%.2f-%.2f", $n/$maxcolors, ($n+1)/$maxcolors)); + text (($n)*$dtx, $caption+0.40, 2, + sprintf ("%.0f%%", 100*($hist[$n]/$total))); + } + close X; + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/signoff.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/signoff.pl new file mode 100755 index 0000000000..2321ea1c64 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/signoff.pl @@ -0,0 +1,54 @@ +#!/usr/intel/bin/perl -w + +#processas a signoff file so that it matches gds2 and cadence names + +use FileHandle; +use IPC::Open2; + +sub usage { + print "Usage: $0 \n"; + exit 2; +} + +$signOffFile = $ARGV[0]; +defined $signOffFile or usage(); + +$rename = "rename"; + +my @cells = (); +open(IN,"<$signOffFile") or die "Can't read $signOffFile"; +while( ) { + if( /^\s*\(\s*cell\s*\"([^^]*)\"\s*\)/ ) { + my ($cell) = split(" ",$1); + push @cells,$cell; + } +} + +my %rename = (); +open2(*Reader,*Writer,"$rename --from=cadence --to=gds2 --type=cell"); +foreach my $cell (@cells) { + print Writer "$cell\n"; + my $new = ; + chomp $new; + $rename{$cell} = $new; +} + +open(IN,"<$signOffFile") or die "Can't read $signOffFile"; +while( ) { + my $line = $_; + if( /^\s*\(\s*cell\s*\"(.*)\"\s*\)/ ) { + my ($old,$view,$lib) = split(" ",$1); + if(defined $view) { $view = " $view"; } else { $view = ""; } + if(defined $lib) { $lib = " $lib"; } else { $lib = ""; } + if(defined $old && defined $rename{$old} ) { + my $new = $rename{$old}; + print " ( cell \"^$old.*$view$lib\")\n"; + print " ( cell \"^$new.*\")\n"; + } else { + print $line; + } + } + else { + print $line; + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/cdl2cast2 b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/cdl2cast2 new file mode 100755 index 0000000000..8b668958f2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/cdl2cast2 @@ -0,0 +1,1025 @@ +#!/usr/bin/perl -l +# AAG +# $Id: cdl2cast2,v 1.1 2013/05/09 23:08:48 aagrey Exp aagrey $ +# $DateTime$ + +# intended for large single cells with hierarchy. + +use strict; +use Getopt::Long; + +my $library; +my $sub_type=0; +my $refinement_parent=""; +my $gnd_node="VSS"; +my $vdd_node="VDD"; +my @implied=(); +my %implied=(); +my $verbose=0; +my $scale=1; +my $sep="."; +my %graybox_list=(); +my $max_heap_size="2G"; +my $libfile=""; # for determining port direction +my %direction=(); +my $output_dir=undef; +my %dirlookup=("input" => "-", "output" => "+", "inout" => "-+", "" => "-+"); +my %resistors=( + "rm1" => 1, + "rm10w" => 1, + "rm1w" => 1, + "rm2w" => 1, + "rm3w" => 1, + "rm4w" => 1, + "rm5w" => 1, + "rm6w" => 1, + "rm7w" => 1, + "rm8w" => 1, + "rm9w" => 1, + "rmap" => 1, + "rnmg" => 1, + "rnmg_m" => 1, + "rnodl" => 1, + "rnodl_m" => 1, + "rnods" => 1, + "rnods_m" => 1, + "rnodwo" => 1, + "rnodwo_m" => 1, + "rnpolywo" => 1, + "rnwod" => 1, + "rnwod_m" => 1, + "rnwsti" => 1, + "rnwsti_m" => 1, + "rpmg" => 1, + "rpmg_m" => 1, + "rpodl" => 1, + "rpodl_m" => 1, + "rpods" => 1, + "rpods_m" => 1, + "rpodwo" => 1, + "rpodwo_m" => 1, + "rppolywo" => 1, + "rupolym" => 1, + "rupolym_m" => 1, + "rupolym_rf" => 1, +); + +my $cdl; + +my $topcell; + +my %devicetranslation = ( + "N" => "nmos", + "NCH" => "nmos", + "NCHPD_SR" => "nmospd_sr", + "NCHPG_SR" => "nmospg_sr", + "NCH_HVT" => "nmos_hvt", + "NCH_SRAM" => "nmos_sram", + "P" => "pmos", + "PCH" => "pmos", + "PCHPU_SR" => "pmospu_sr", + "PCH_HVT" => "pmos_hvt", + "PCH_SRAM" => "pmos_sram", + "nch" => "nmos", + "nch_15_mac" => "nmos_15_mac", + "nch_15od18_mac" => "nmos_15od18_mac", + "nch_18" => "nmos_18", + "nch_18_mac" => "nmos_18_mac", + "nch_18ud12_mac" => "nmos_18ud12_mac", + "nch_18ud15_mac" => "nmos_18ud15_mac", + "nch_25_mac" => "nmos_25_mac", + "nch_25od33_mac" => "nmos_25od33_mac", + "nch_25ud18_mac" => "nmos_25ud18_mac", + "nch_33_mac" => "nmos_33_mac", + "nch_chvt_mac" => "nmos_chvt_mac", + "nch_dnw" => "nmos_dnw", + "nch_edc_mac" => "nmos_edc_mac", + "nch_hg_mac" => "nmos_hg_mac", + "nch_hguhvt_mac" => "nmos_hguhvt_mac", + "nch_hia15_mac" => "nmos_hia15_mac", + "nch_hia18_mac" => "nmos_hia18_mac", + "nch_hia25_mac" => "nmos_hia25_mac", + "nch_hia_mac" => "nmos_hia_mac", + "nch_hlqrpsr" => "nmos_hlqrpsr", + "nch_hlrpsr" => "nmos_hlrpsr", + "nch_hlsvtrpsr" => "nmos_hlsvtrpsr", + "nch_hvt" => "nmos_hvt", + "nch_hvt_mac" => "nmos_hvt_mac", + "nch_hvtrpsr" => "nmos_hvtrpsr", + "nch_io_lvt_mac" => "nmos_io_lvt_mac", + "nch_llrpsr" => "nmos_llrpsr", + "nch_lvt" => "nmos_lvt", + "nch_lvt18ud12_mac" => "nmos_lvt18ud12_mac", + "nch_lvt_mac" => "nmos_lvt_mac", + "nch_lvtrpsr" => "nmos_lvtrpsr", + "nch_mac" => "nmos_mac", + "nch_mlvt_mac" => "nmos_mlvt_mac", + "nch_na15_mac" => "nmos_na15_mac", + "nch_na18" => "nmos_na18", + "nch_na18_mac" => "nmos_na18_mac", + "nch_na18ud15_mac" => "nmos_na18ud15_mac", + "nch_na25_mac" => "nmos_na25_mac", + "nch_na25od33_mac" => "nmos_na25od33_mac", + "nch_na25ud18_mac" => "nmos_na25ud18_mac", + "nch_na33_mac" => "nmos_na33_mac", + "nch_na_mac" => "nmos_na_mac", + "nch_qrpsr" => "nmos_qrpsr", + "nch_rom" => "nmos_rom", + "nch_rpsr" => "nmos_rpsr", + "nch_svt_sp_mac" => "nmos_svt_sp_mac", + "nch_svtrpsr" => "nmos_svtrpsr", + "nch_uhvt_mac" => "nmos_uhvt_mac", + "nch_ulvt_mac" => "nmos_ulvt_mac", + "nch_zvt_mac" => "nmos_zvt_mac", + "nchpd_dpsr" => "nmospd_dpsr", + "nchpd_hldpsr" => "nmospd_hldpsr", + "nchpd_hlsr" => "nmospd_hlsr", + "nchpd_hvtsr" => "nmospd_hvtsr", + "nchpd_lldpsr" => "nmospd_lldpsr", + "nchpd_llsr" => "nmospd_llsr", + "nchpd_sr" => "nmospd_sr", + "nchpg_dpsr" => "nmospg_dpsr", + "nchpg_hldpsr" => "nmospg_hldpsr", + "nchpg_hlsr" => "nmospg_hlsr", + "nchpg_hvtsr" => "nmospg_hvtsr", + "nchpg_lldpsr" => "nmospg_lldpsr", + "nchpg_llsr" => "nmospg_llsr", + "nchpg_sr" => "nmospg_sr", + "nchrpd_sr" => "nmosrpd_sr", + "pch" => "pmos", + "pch_15_mac" => "pmos_15_mac", + "pch_15od18_mac" => "pmos_15od18_mac", + "pch_18" => "pmos_18", + "pch_18_mac" => "pmos_18_mac", + "pch_18ud12_mac" => "pmos_18ud12_mac", + "pch_18ud15_mac" => "pmos_18ud15_mac", + "pch_25_mac" => "pmos_25_mac", + "pch_25od33_mac" => "pmos_25od33_mac", + "pch_25ud18_mac" => "pmos_25ud18_mac", + "pch_33_mac" => "pmos_33_mac", + "pch_alvt_mac" => "pmos_alvt_mac", + "pch_hg_mac" => "pmos_hg_mac", + "pch_hguhvt_mac" => "pmos_hguhvt_mac", + "pch_hvt" => "pmos_hvt", + "pch_hvt_mac" => "pmos_hvt_mac", + "pch_lvt" => "pmos_lvt", + "pch_lvt_mac" => "pmos_lvt_mac", + "pch_mac" => "pmos_mac", + "pch_mlvt_mac" => "pmos_mlvt_mac", + "pch_svt_sp_mac" => "pmos_svt_sp_mac", + "pch_uhvt_mac" => "pmos_uhvt_mac", + "pch_ulvt_mac" => "pmos_ulvt_mac", + "pchpu_2psr" => "pmospu_2psr", + "pchpu_dpsr" => "pmospu_dpsr", + "pchpu_hldpsr" => "pmospu_hldpsr", + "pchpu_hlsr" => "pmospu_hlsr", + "pchpu_hvtsr" => "pmospu_hvtsr", + "pchpu_lldpsr" => "pmospu_lldpsr", + "pchpu_llsr" => "pmospu_llsr", + "pchpu_sr" => "pmospu_sr", +); + +sub usage { + my ($msg) = @_; + print STDERR "$msg" if defined $msg; + print < + options + lib : the cast library name + sub-type : the desired subtype for this cell + refinement-parent : the cast refinement parent + gnd-node : the cdl GND node + vdd-node : the cdl Vdd node + implied : extra implied node(s) + max-heap-size : normal java max-heap-size + cell : the name of the top cell + libfile : file with cell lib port directions defined + output-dir : place for the cast/spec files + verbose : +EU +exit 1; +} + +sub getdirection { + my ($cell,$pin) = @_; + my %dir=(); + %dir=%{$direction{$cell}} if defined $direction{$cell}; + if (! defined ($dir{$pin})) { + my $x = $pin; + $x =~ s/\[.*//; + $dir{$pin} = $dir{$x} if defined $dir{$x}; + $dir{$pin} = "-" if ! defined($dir{$pin}) and $pin =~ /VDD/i; + $dir{$pin} = "-" if ! defined($dir{$pin}) and $pin =~ /GND$/i; + $dir{$pin} = "-+" if ! defined $dir{$pin}; + } + $dir{$pin}; +} + +sub parselibfile { + my ($file) = @_; + open (P, "<$file"); + print STDERR "Parsing $file" if $verbose; + my $cell; + my $pin; + my $bus; + my $bus_type; + my %bit_width; + my %bit_from; + my %bit_to; + my $direction; + while (

    ) { + chomp; + if (/^\s*cell\s*\(\s*(.*)\s*\)/) { + $cell=$1; + $cell =~ s/\s//g; + $cell =~ s/"//g; + $cell =~ s/'//g; + } + if (/^\s*type\s*\(\s*(\S+)\s*\)/) { + $bus_type = $1; + while (

    ) { + chomp; + if (/^\s*(\S+)\s*:\s*(\S+)\s*;/) { + if ($1 eq "bit_width") { + $bit_width{$bus_type}=$2; + } + if ($1 eq "bit_from") { + $bit_from{$bus_type}=$2; + } + if ($1 eq "bit_to") { + $bit_to{$bus_type}=$2; + } + } + if (/^\s*\x7d/) { + last; + } + } + } + if (/^\s*pin\s*\(\s*(.*)\s*\)/) { + $pin = $1; + undef $bus; + } + if (/^\s*bus\s*\(\s*(.*)\s*\)/) { + $bus = $1; + undef $pin; + } + if (/^\s*bus_type\s*:\s*(\S+)\s*;/) { + $bus_type = $1; + print STDERR "BUS TYPE $bus_type not defined" if ! defined $bit_width{$bus_type}; + } + if (/^\s*direction\s*:\s*(.*)\s*;/) { + $direction=$1; + $direction =~ s/\s//g; + $direction = $dirlookup{$direction}; + if (defined ($pin)) { + $direction{$cell}->{$pin}=$direction; + if ($pin =~ /\[/) { + my $base=$pin; + $base =~ s/\[.*//; + $direction{$cell}->{$base}=$direction; + } + } + elsif (defined ($bus)) { + my $to = $bit_to{$bus_type}; + my $from = $bit_from{$bus_type}; + my $width = $bit_width{$bus_type}; + if (defined ($to) and defined ($from) and abs($from-$to)+1 != $width) { + print STDERR "Bus definition may be inconsistent for $bus_type"; + } + if ($to < $from) { + my $x = $from; + $from = $to; + $to = $x; + } + $direction{$cell}->{"$bus"}=$direction; + for (my $n = $from; $n <= $to; $n++) { + $direction{$cell}->{"$bus\[$n\]"}=$direction; + } + } + } + } +} + +GetOptions ( + "lib=s" => \$library, + "libfile=s" => \$libfile, + "sub-type=s" => \$sub_type, + "refinement-parent=s" => \$refinement_parent, + "gnd-node=s" => \$gnd_node, + "vdd-node=s" => \$vdd_node, + "verbose" => \$verbose, + "implied=s" => sub { + push @implied, split(/,/,$_[1]); + foreach my $i (@implied) { + $implied{$i}=1; + } + }, + "max-heap-size=s" => \$max_heap_size, + "cell=s" => \$topcell, + "output-dir=s" => \$output_dir, +) or usage "GetOptions"; + +$implied{$gnd_node}=1; +$implied{$vdd_node}=1; +if ($libfile ne "" and -f $libfile) { + parselibfile($libfile); +} +print STDERR "Warning: $libfile not found" if (! -f $libfile and $libfile ne ""); + +usage "Library or topcell or sub_type" + if ($library eq "") or ($sub_type eq ""); +$cdl = $ARGV[0] if defined $ARGV[0]; +usage if ! -s $cdl; + +my $path=$library; +$path =~ s/\./\//g; +my $cpath = $path; +$cpath =~ s/\/[^\/]+$//; +my $lname=$path; +$lname =~ s/.*\///; +$output_dir=$topcell if ! defined $output_dir; +my $castpath="$output_dir/cast/$cpath"; +my $specpath="$output_dir/spec/$path"; +my $vcell="xCBLK4_mem28_sr1p11_16384x30_pgr_16lm_rrc"; #for debugging + +`mkdir -p "$castpath"` if ! -d "$castpath"; +`mkdir -p "$specpath"` if ! -d "$specpath"; + +open (P, "<$cdl") or die "Cannot open $cdl"; +my %subckts=(); +my %subcktsinfo=(); +my %lines=(); +my $ln=""; +my $subckt=""; +my @lines=(); +my %types=(); +my %gnd=(); +my %vdd=(); +my %order=(); +my %place=(); +my %warnings=(); +my %sdefs=(); +my %subtypes=(); +my %hasnox=(); +my $xcnt=0; +my $hasparams=0; +my %called=(); +my @pins=(); +my @subckts=(); +my @subcktcalls=(); +my @lines=(); +my %localcalled=(); +# read in the cdl +while (

    ) { + chomp; + next if (/^\*/); + s/ \$.*//; + if (/^\+/) { + s/^\+/ /; + $ln .= $_; + next; + } + my $lx = $_; + $_ = $ln; + $ln = $lx; + s/\s+/ /g; + next if /^\*/; + s/ \$.*//; + next if /^$/; + if (/^\.subckt/i) { + my @f=split; + shift @f; + $subckt = shift @f; + $gnd{$subckt}=$vdd{$subckt}=-1; + @lines=(); + @pins=(); + @subckts=(); + @subcktcalls=(); + %localcalled=(); + my %params=(); + my $type="subcells"; + foreach my $n (0..$#f) { + if ($f[$n] eq "$gnd_node" or $f[$n] eq "GND" or $f[$n] =~ /^vss$/i) { + $gnd{$subckt} = $n; + $f[$n] = "GND"; + } + if ($f[$n] eq "$vdd_node" or $f[$n] =~ /^vdd$/i) { + $vdd{$subckt} = $n; + $f[$n] = "Vdd"; + } + print STDERR "ORDER $subckt $n $f[$n]" if $verbose and $subckt eq $vcell; + if ($f[$n] =~ /=/) { + my ($param,$val)=split(/=/,$f[$n]); + $val =~ s/'//g; + $val =~ s/(\d)u/${1}*1e-6/; + $val =~ s/(\d)n/${1}*1e-9/; + $val =~ s/(\d)p/${1}*1e-12/; + $val =~ s/(\d)f/${1}*1e-15/; + $params{$param}=$val; + } + else { + push @pins,$f[$n]; + print STDERR "ORDER $subckt:$n $f[$n]" if $verbose; + $order{"$subckt:$n"}=$f[$n]; + } + } + printf STDERR "SUBCKT $subckt $topcell\n" if $verbose; + $subckts{$subckt}=[@f]; + $_=".SUBCKT ".join(" ", @f); + push @lines, $_; + $xcnt=0; + $hasparams=1 if /=/; + $subcktsinfo{$subckt}->{lines}=[@lines]; + $subcktsinfo{$subckt}->{pins}=[@pins]; + $subcktsinfo{$subckt}->{subckts}=[@subcktcalls]; + $subcktsinfo{$subckt}->{params}={%params}; + next; + } + if (/^\.ends/i) { + push @lines, $_; + $lines{$subckt}=[@lines]; + $hasnox{$subckt}=$xcnt > 0 ? 0 : 1; + $subcktsinfo{$subckt}->{pins}=[@pins]; + $subcktsinfo{$subckt}->{lines}=[@lines]; + $subcktsinfo{$subckt}->{subckts}=[@subcktcalls]; + $subcktsinfo{$subckt}->{called}={%localcalled}; + $subckt = ""; + next; + } + if ($subckt ne "") { + my @f=split; + if (/^x/i and !$resistors{$f[3]}) { + $xcnt++; + my $call=$f[$#f]; + my $n=$#f; + for ($n=$#f; $f[$n] =~ /=/ and $n > 0; $n--) { } + $call=$f[$n]; + $called{$call}=1; + $localcalled{$call}=1; + $types{$subckt}="subcells" if ! defined $types{$subckt}; + if (! $warnings{$subckt} and defined($types{$subckt}) and $types{$subckt} ne "subcells") { + $warnings{$subckt}=1; + print STDERR "Mixed type in subckt $subckt line $." if $verbose; + } + } + elsif (/^[a-z]/i) { + if (! $warnings{$subckt} and defined($types{$subckt}) and $types{$subckt} ne "netlist") { + print STDERR "Mixed type in subckt $subckt line $." if $verbose; + $warnings{$subckt}=1; + } + $types{$subckt}="netlist"; + } + foreach my $f (@f) { + $f = "Vdd" if $f eq $vdd_node or $f =~ /^vdd$/i; + $f = "GND" if $f eq $gnd_node or $f =~ /^gnd$/i or $f =~ /^vss$/i; + } + push @lines, join(" ", @f); + push @subcktcalls, join(" ", @f) if /^x/i; + } +} +if ($ln =~ /^\.ends/i) { + push @lines, $ln; + $lines{$subckt}=[@lines]; + $hasnox{$subckt}=$xcnt > 0 ? 0 : 1; + $subcktsinfo{$subckt}->{pins}=[@pins]; + $subcktsinfo{$subckt}->{lines}=[@lines]; + $subcktsinfo{$subckt}->{subckts}=[@subcktcalls]; + $subcktsinfo{$subckt}->{called}={%localcalled}; +} +close P; +my $lvl=0; +my %subtypedefs=(); +my %celldone=(); +sub expandvalue { + my ($value, $ln) = @_; + $value =~ s/'//g; + printf STDERR "1 $ln $value => " if $verbose; + $value=~ s/([0-9\.])u/$1*1e-6/g; + $value=~ s/([0-9\.])n/$1*1e-9/g; + $value=~ s/([0-9\.])p/$1*1e-12/g; + $value=~ s/([0-9\.])f/$1*1e-15/g; + printf STDERR ("$value => ") if $verbose; + eval("\$value = $value"); + printf STDERR ("$value\n") if $verbose; + $value; +} + +my $checksubckt=""; +sub setvalue { + my ($ln, $value,%param1,%param2)=@_; + %param2=() if (!%param2); + %param1=() if (!%param1); + my $invalue=$value; + my $pp; + printf STDERR "setvalue $checksubckt $ln ".join(",",(sort keys %param1))." $value => " if $verbose; + foreach my $param (sort {$b cmp $a} keys %param1) { + $pp = $param1{$param}; + $pp = expandvalue ($pp, __LINE__); + $value =~ s:\b$param\b:$pp:g; + printf STDERR "$value => " if $verbose; + } + foreach my $param (sort {$b cmp $a} keys %param2) { + $pp = $param2{$param}; + $pp = expandvalue ($pp, __LINE__); + $value =~ s:\b$param\b:$pp:g; + printf STDERR "$value => " if $verbose; + } + $value=expandvalue ($value, __LINE__); + print STDERR "$value" if $verbose; + $value; +} + +sub gensubtypes { + my ($subckt,$subt,$defs)=@_; + return 1 if (defined $celldone{$subckt}->{$subt}); + $celldone{$subckt}->{$subt}=1; + if (! $subcktsinfo{$subckt}->{pins}) { + print STDERR "Warning: No pins for $subckt\n"; + return 0; + } + my @pins = @{$subcktsinfo{$subckt}->{pins}}; + my @lines = @{$subcktsinfo{$subckt}->{lines}}; + # get the subckt default params + my %params = %{$subcktsinfo{$subckt}->{params}}; + foreach my $p (sort keys %params) { + printf STDERR ":$p=$params{$p}" if $verbose; + } + printf STDERR " " if $verbose; + my $multiplier=1; + if (defined $defs) { + my @l=split(/ */,$defs); + for( my $n=$#l; $n >= 0 and $l[$n] =~ /=/; $n--) { + my ($p,$v)=split(/=/,$l[$n],2); + $params{$p}=$v; + } + } + foreach my $p (sort keys %params) { + printf STDERR ";$p=$params{$p}" if $verbose; + } + printf STDERR "\n" if $verbose; + $verbose=0; + foreach my $ln (@lines) { + $_=$ln; + next if /^\*/; + if (/^\./) { + if (/^\.subckt/i) { + my @f=split; + shift @f; + unshift @f, "$subckt.$subt"; + unshift @f, ".SUBCKT"; + my @p=(); + for (my $n=0; ($f[$n] !~ /=/) and $n <= $#f; $n++) { + push @p, $f[$n]; + } + $ln=join(" ", @p); + } + push @{$subtypedefs{$subckt}->{$subt}}, $ln; + next; + } + $checksubckt=$subckt; + if (/^[md]/i) { + my @f=split(/ /); + my $n=$#f; + for ($n=$#f; $f[$n] =~ /=/; $n--) { + my ($l,$v)=split(/=/, $f[$n]); + $v=setvalue(__LINE__,$v,%params); + $f[$n]="$l=$v"; + } + push @{$subtypedefs{$subckt}->{$subt}}, join (" ", @f); + } + elsif (/^x/i) { + my @f=split(/ /); + my $n=$#f; + my @p=(); + for ($n=$#f; $f[$n] =~ /=/; $n--) { + my ($l,$v)=split(/=/, $f[$n]); + $v=setvalue(__LINE__,$v,%params); + push @p, "$l=$v"; + } + my $st=$f[$n]; + if ($st =~ /^r/) { + print STDERR "Warning: Unexpected RESISTOR $_"; + next; + } + my @stdef; + foreach my $x (0..$n-1) { + push @stdef, $f[$x]; + } + my $key=""; + if (@p) { + $key=join(" ", sort @p); + } + if (! defined ($sdefs{$st})) { + $sdefs{$st}->{$key}=0; + $subtypes{$st}=0; + } + elsif (! defined ($sdefs{$st}->{$key})) { + $sdefs{$st}->{$key}=++$subtypes{$st}; + } + push @stdef, "$st.$sdefs{$st}->{$key}"; + push @{$subtypedefs{$subckt}->{$subt}}, join(" ", @stdef); + gensubtypes($st, $sdefs{$st}->{$key}, join(" ",@p)); + } + else { + print STDERR "Warning: Unknown $_"; + } + } +} +gensubtypes( $topcell, 0); +my $totalsubtypes=0; +foreach my $s (sort keys %subtypedefs) { + foreach my $st (sort keys %{$subtypedefs{$s}}) { + $totalsubtypes++; + } +} +my $new=1; +if (! $new) { + foreach my $subckt (sort keys %subckts) { + my @f=@{$subckts{$subckt}}; + my $bus=""; + my @p=(); + my $min=0; + my $max=0; + foreach my $f (sort @f) { + if ($f =~ /(.*)\[(\d+)]$/) { + my $b=$1; + my $c=$2; + if ($b ne $bus and $bus ne "") { + push @p, "$bus\[$min..$max\]"; + $min = $max = $c; + } + $bus = $b; + $max = $c if $c > $max; + $min = $c if $c < $min; + } + else { + if ($bus ne "") { + push @p, "$bus\[$min..$max\]"; + $min = $max = 0; + } + push @p, $f; + $bus=""; + } + } + if ($bus ne "") { + push @p, "$bus\[$min..$max\]"; + $min = $max = 0; + $bus = ""; + } + $subckts{$subckt}=[@p]; + my $seq=0; + foreach my $p (@p) { + if ($p =~ /(.*)\[(\d+)..(\d+)\]/) { + my $name=$1; + my $min=$2; + my $max=$3; + for (my $n = $min; $n <= $max; $n++) { + $place{"$subckt:$name\[$n\]"} = $seq++; + } + } + else { + $place{"$subckt:$p"} = $seq++; + } + } + } +} + +my $dollar='$'; +my $copyright= <$castpath/$lname.cast") or die "$!"; +select P; +print "$copyright"; +print "module $library;"; +my $impliedlist="-".join(", -", sort keys %implied); +foreach my $node (sort keys %implied) { + next if $node eq $gnd_node or $node eq $vdd_node; + $impliedlist .= "-$node, "; +} +$impliedlist =~ s/\s+$//; +$impliedlist = "" if $impliedlist eq "-"; +print <= 0) { + push @ports, "$lastdir$lastname\[$a..$b\]"; + } + else { + push @ports, "$lastdir$lastname"; + } + } + if ($name ne $lastname) { + $a = $b = $ndx; + $lastname=$name; + $lastdir=$dir; + } + else { + $a=$a < $ndx ? $a : $ndx; + $b=$b > $ndx ? $b : $ndx; + } + } + elsif($lastname ne "" and $a >= 0) { + push @ports, "$lastdir$lastname\[$a..$b\]"; + $a=$b=-1; + } + elsif ($lastname ne "") { + push @ports, "$lastdir$lastname"; + } + $lastname=$name; + $lastdir=$dir; + } + if($lastname ne "" and $a >= 0) { + push @ports, "$lastdir$lastname\[$a..$b\]"; + } + else { + push @ports, "$lastdir$lastname"; + } +# } { +# else { +# my $n = 0; +# foreach my $p (@{$subckts{$subckt}}) { +# next if $implied{$p}; +# next if $p =~ /=/; +# my $dir=getdirection($subckt,$p); +# push @ports, "$dir$p"; +# } +# } + print join(", ", @ports); + print " ) <: $refinement_parent {\n}"; + } +} +select STDOUT; +close P; + +# now the spec files +sub namefix { + my ($s)=@_; + $s =~ s/\]/_R_/g; + $s =~ s/\[/_L_/g; + $s; +} + +sub netlist { + my @lines=@_; + local $_; + print " netlist \x7b"; + foreach my $line (@lines) { + $_=$line; + if (/^x/i) { + my @f=split; + if ($f[3] =~ /^r/ and $f[4] =~ /=/) { + $f[3] = "standard.resistor.$f[3]"; + $line=join(" ", @f); + } + print " $line"; + } + elsif (/^[a-z]/i) { + print " $line"; + } + } + print " \x7d"; + +} + +sub subcells { + my @lines=@_; + local $_; + print " subcells \x7b"; + # collect nodes + my %ports=(); + my %nodes=(); + my @calls=(); + my $subcell=""; + my %subcellports=(); + foreach my $line (@lines) { + $_=$line; + my @f=split; + if (/^\.subckt/i) { + for (my $n = 2; $n <= $#f; $n++) { + $ports{$f[$n]}=1 if $f[$n] !~ /=/; + } + } + elsif (/^[a-z]/i) { + my $l=$#f; + for ($l = $#f; $f[$l] =~ /=/; $l--) {}; + $subcell=$f[$l]; + $subcell =~ s/\.\d+$//; + my %subcell=(); + my $x=1; + foreach my $p (@{$subckts{$subcell}}) { + last if $p =~ /=/; + $subcell{$x}=$p; + $x++; + } + my @c=(); + my %impliedmatch=(); + my $impliedmismatch=0; + for (my $n=1; $n < $l; $n++) { + $nodes{$f[$n]}=1 if ! $ports{$f[$n]} and ! $implied{$f[$n]}; + push @c, $f[$n] if ! $implied{$subcell{$n}}; + if ($implied{$subcell{$n}}) { + $impliedmatch{$subcell{$n}}=$f[$n]; + if ($subcell{$n} ne $f[$n]) { + print STDERR "Implied Mismatch in $subckt $subcell $f[$n] vs. $subcell{$n}" if $verbose; + $impliedmismatch=1; + } + } + } + if ($impliedmismatch) { + my @i; + foreach my $i (sort keys %impliedmatch) { + push @i, $impliedmatch{$i}; + } + push @calls, "$library.$f[$l] $f[0](".join(",", @c).")(".join(",", @i).");"; + } + else { + push @calls, "$library.$f[$l] $f[0](".join(",", @c).");"; + } + } + } + foreach my $node (sort keys %nodes) { + print " node $node;"; + } + foreach my $line (@calls) { + print " $line"; + } + print " \x7d"; +} + +sub splitnetlist { + my @lines=@_; + my @netlist=(); + my %netlistnodes=(); + my %subcellsnodes=(); + my @subcells=(); + local $_; + my $netlistline=""; + my $netlistname=""; + my $netlistsubtype=0; + foreach my $line (@lines) { + $_=$line; + if (/^\./) { + my @f=split; + if ($f[0] =~ /^\.subckt$/i) { + $f[1] =~ s/\.(\d+)$/_netlist.$1/; + $netlistsubtype=$1; + $netlistline=join(" ", @f); + $netlistname=$f[1]; + $netlistname =~ s/\.\d+$//; + } + push @netlist, join(" ", @f); + if ($line =~ /^\.ends/) { + push @subcells, "xnetlist ".join(" ", sort keys %netlistnodes)." $netlistname.$netlistsubtype"; + } + push @subcells, $line; + } + if (/^x/i) { + my @f=split; + if ($f[3] =~ /^r/ and $f[4] =~ /=/) { + $f[3] = "standard.resistor.$f[3]"; + $line=join(" ", @f); + $netlistnodes{$f[1]}=1 if ! $implied{$f[1]}; + $netlistnodes{$f[2]}=1 if ! $implied{$f[2]}; + push @netlist, $line; + } + else { + push @subcells, $line; + } + } + elsif (/^[a-z]/i) { + if (/^m/i) { + my @f=split; + for (my $n = 1; $n <= 4; $n++) { + $netlistnodes{$f[$n]}=1 if ! $implied{$f[$n]}; + } + } + else { + my @f=split; + for (my $n = 1; $n <= 2; $n++) { + $netlistnodes{$f[$n]}=1 if ! $implied{$f[$n]}; + } + } + push @netlist, $line; + } + } + subcells(@subcells); + printf "\x7d"; + close P; + mkdir "$specpath/$netlistname"; + open (P, ">$specpath/$netlistname/$netlistsubtype.cast") or die "$!"; + select P; + print "$copyright"; + print "module $library.$netlistname;\n"; + printf "define \"$netlistsubtype\"()"; + # put nodes here + my @f=sort keys %netlistnodes; + my @pins=(); + my $f; + while ( (($f = shift @f) !~ /=/) and defined($f)) { + push @pins, $f; + } + if ($#pins >= 0) { + printf "( node -+".join(", -+", @pins)." )"; + } + else { + printf "()"; + } + print " <: $library.$refinement_parent \x7b"; + netlist(@netlist); +} + +foreach my $subckt (sort keys %subtypedefs) { + foreach my $subtype (sort keys %{$subtypedefs{$subckt}}) { + mkdir "$specpath/$subckt"; + open (P, ">$specpath/$subckt/$subtype.cast") or die "$!"; + select P; + print "$copyright"; + print "module $library.$subckt;\n"; + if ($subckt eq $topcell) { + print "define \"$subtype\"() <: $library.$subckt \x7b"; + } + else { + my @ports=(); + my $n = 0; + print "define \"$subtype\"()("; + foreach my $p (@{$subckts{$subckt}}) { + next if $implied{$p}; + next if $p =~ /=/; + my $dir=getdirection($subckt,$p); + push @ports, namefix("$dir$p"); + } + if (@ports) { + print "node ".join(", ", @ports); + } + print " ) <: $library.$refinement_parent \x7b"; + } + my @lines=@{$subtypedefs{$subckt}->{$subtype}}; + my $hasx=0; + my $hasnx=0; + foreach my $line (@lines) { + $line = namefix($line) if ($subckt ne $topcell); + $_=$line; + if (/^x/i) { + my @f=split; + if (($f[3] =~ /^r/) and ($f[4] =~ /=/)) { + $hasnx++; + } + else { + $hasx++; + } + } + elsif (/^[a-z]/i) { + $hasnx++; + } + } + if (! $hasx and $hasnx ) { # pure netlist or empty + netlist(@lines); + } + elsif (! $hasnx) { # subcells + subcells(@lines); + } + else { + print STDERR "Impure netlist for $subckt.$subtype" if $verbose; + splitnetlist(@lines); + } + printf "\x7d"; + close P; + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/compilemem.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/compilemem.pl new file mode 100755 index 0000000000..9754581c7e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/compilemem.pl @@ -0,0 +1,789 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +# TODO: +# fix libs according to bug 11911 +# something wrong with p4 stuff in here +# better handling of no p4 client + +use strict; +use Getopt::Long; +use IPC::Open2; + +my %ARGS = ( + "acroread" => "acroread", + "asvm" => "on", + "atf" => "off", + "back_biasing" => "off", + "bits" => 32, + "bmux" => "off", + "bus_notation" => "on", + "check_instname" => "off", + "corners" => "", + "cust_comment" => "", + "diodes" => "on", + "dnw" => "off", + "dpccm" => "on", + "drive" => 4, + "ema" => "on", + "frequency" => 700, + "horiz" => "met3", + "left_bus_delim" => "[", + "mux" => 1, + "name_case" => "upper", + "pin_space" => "0.0", + "pipeline" => "off", + "power_gating" => "off", + "power_type" => "rings", + "prefix" => "", + "pwr_gnd_rename" => "", + "rcols" => 1, + "redundancy" => "off", + "retention" => "on", + "right_bus_delim" => "]", + "ring_width_core" => "1.2", + "ring_width_periphery" => "1.2", + "rrows" => 0, + "ser" => "none", + "synopsys.libname" => "", + "top_layer" => "", + "vclef-fp.inst2ring" => "blockages", + "vclef-fp.site_def" => "off", + "vert" => "met4", + "words" => 512, + "wp_size" => 8, + "write_mask" => "off", + "write_thru" => "on", +); +my $verbose=0; + +my $norun=0; +my $type=""; +my %allnames; +my $user=`whoami`; +chomp $user; +my $change; +my $library="vendor.artisan.memory.sram"; +my $libpath="vendor/artisan/memory/sram"; +my $inspecfile; +my $instname; + +my %compilerpath=( + "RD" => "rf_2p_adv", + "RS" => "rf_sp_adv", + "SD" => "sram_dp_adv", + "SS" => "sram_sp_adv", +); + +my %in = ( + "SS" => "SRAM", + "SD" => "SRAM", + "RS" => "REGFILE", + "RD" => "REGFILE", +); + + +my $compilerroot= "/mnt/fulcrum/local/vendors/artisan/tsmc65/aci"; +my $castpath; +my $specpath; +my $sparpath; +my $dfIIpath; +my $client; +my $clientpath=""; +my $interactive=0; +my $pdkroot=""; + +# NOTE: First in array is default option! + +my %coptions=( +# "acroread" => ["acroread"], # ?? + "asvm" => ["on","off"], # address setup violation modeling + "atf" => ["off","on"], # Advanced Test Features (WBT and RDT) + "back_biasing" => ["off"], # VPW and VNW pins added to control back bias + "bits" => ["SS,SD=2..72","RS=8..144","RD=2..144"], # depends on mux width *** + "bmux" => ["off","on"], # bist access mux + "bus_notation" => ["on","off"], # use correct bus notation + "check_instname" => ["off","on"], # needs to be off + "corners" => ["RS,RD,SS,SD=ss_0p9v_125c,ff_1p1v_125c,ff_1p1v_0c,tt_1p0v_25c"], + "cust_comment" => [""], + "dpccm" => ["on","off"], # dual port only for modeling for clock colisions + "diodes" => ["on","off"], # almost certainly needs to be on + "drive" => ["SS,SD=6","RS,RD=4"], + "ema" => ["on","off"], + "frequency" => ["500..700"], # only used for power + "horiz" => ["SS,SD=met2;met3;met4","RS,RD=met2;met3"], +# "inside_ring_type" => ["VDD","GND"], # default?? + "left_bus_delim" => ["["], # obvious + "mux" => ["SS=8;16;32","SD=4;8;16","RS,RD=1;2;4"], # from compiler error report *** + "name_case" => ["upper"], # just use upper case + "pin_space" => ["0.0"], # between pins of core and inner power ring + "pipeline" => ["off","on"], + "power_gating" => ["off","on"], # core and periphery are separated + "power_type" => ["rings","ArtiGrid"], # use rings + "prefix" => [""], + "pwr_gnd_rename" => ["VDDPE:VDDPE,VDDCE:VDDCE,VSSE:GND"], + "rcols" => ["SS=0;2;16","SD=0;2","RS,RD=1"], + "redundancy" => ["off","on"], + "retention" => ["on","off"], # on for power gating + "right_bus_delim" => ["]"], # obvious + "ring_width_core" => ["1.2"], # >= 1/2 width of power grid + "ring_width_periphery" => ["1.2"], # >= 1/2 width of power grid + "rrows" => [0,2,4], +# "se_immunity" => ["off","on"], # add deep nwell for better alpha immunity + "ser" => ["none","1bd1bd","2bd1bc"], # store error codes write_mask off + "synopsys.libname" => ["*"], # should be changed, IMHO + "top_layer" => ["SS,RD=m5-m9","SD=m5-9","RS=met5-9"], + "vclef-fp.inst2ring" => ["blockages","pin"], # power is blockage or pin + "vclef-fp.site_def" => ["off","on"], # does lef have a site definition? + "vert" => ["SS,SD=met2;met3;met4","RS,RD=met2;met3"], +# "wae" => ["RD,RS=off;on"], # register file only? + "words" => ["SS=512..16384","SD=256..4096","RS=8..512","RD=8..256"], # 512-16384, divisble by 2*mux *** + "wp_size" => ["1..36"], + "write_mask" => ["off","on"], + "write_thru" => ["SS,SD,RS=off;on","RD=off"], +); + +sub fixlib { + my ($file,$cell) = @_; + local *P; + local $_; + if (open (P, "<$file")) { + my @lines = (); + while (

    ) { + chomp; + push @lines, $_; + } + close P; + open (P, ">$file"); + for (my $n = 0; $n <= $#lines; $n++) { + $_=$lines[$n]; + if (/UNDEFINED/) { + if (/voltage_map/) { + if (/,\s*0\s*\)/) { + $lines[$n] =~ s/UNDEFINED/GND/; + } + else { + $lines[$n] =~ s/UNDEFINED/VDDCE/; + } + } + if (/related_power_pin/ or /related_pg_pin/) { + $lines[$n] =~ s/UNDEFINED/VDDCE/; + } + if (/related_ground_pin/) { + $lines[$n] =~ s/UNDEFINED/GND/; + } + } + while ($lines[$n] =~ /pg_pin\(/) { + my $i = 0; + my $undefined = "VDDCE"; + while (! ($lines[$n+$i] =~ /\x7d/)) { + $i++; + $undefined = "GND" if $lines[$n+$i] =~ /pg_type.*ground/; + } + for (my $j = 0; $j <= $i; $j++) { + $lines[$n+$j] =~ s/UNDEFINED/$undefined/; + } + $n += $i+1; + } +# print P $lines[$n]; + } + print P join("\n", @lines); + close P; + } +} + +sub setoptionsfromspecfile { + my ($file) = @_; + local *P, $_; + if (open (P, "<$file")) { + while (

    ) { + chomp; + next if /^#/; + my ($arg,$value)=split(/=/,$_); + if (defined ($ARGS{$arg})) { + eval("\$ARGS{$arg}=\"$value\""); + } + else { + eval("\$$arg=\"$value\""); + } + } + } + $type = substr($instname, 0, 1); + my $x = $instname; + $x =~ s/_R90//; + $type .= substr($x,length($x)-2, 1); +} + +sub check_options { + my $err=0; + foreach my $key (sort keys %coptions) { + if (defined ($ARGS{$key})) { + my $ok=0; + my @ok=@{$coptions{$key}}; + if ($ok[0] eq "*") { + $ok = 1; + } + else { + foreach my $v (@ok) { + if ($v eq $ARGS{$key}) { $ok=1;} + elsif ($v =~ /^(\d+)\.\.(\d+)$/) { + $ok = 1 if $ARGS{$key} >= $1 and $ARGS{$key} <= $2; + } + elsif ($v =~ /=/) { + my ($ty,$val)=split(/=/,$v); + my @ty = split(/,/,$ty); + foreach my $t (@ty) { + if ($t eq $type) { + if ($val =~ /^(\d+)\.\.(\d+)$/) { + $ok = 1 if $ARGS{$key} >= $1 and $ARGS{$key} <= $2; + } + elsif ($val =~ /;/) { + my @v=split(/;/,$val); + foreach my $vx (@v) { + $ok=1 if ($ARGS{$key} eq $vx); + } + } + elsif ($ARGS{$key} ne $val and $val ne "*") { + print STDERR "Warning: $key ($ARGS{$key}) changed to $val" + if $verbose and $ARGS{$key} ne ""; + $ARGS{$key} = $val; + $ok=1; + } + else { + $ok=1; + } + } + } + } + } + } + if ($ok == 0 and $ok[0] ne "*") { + if ($#ok == 0 and ! ($ok[0] =~ /^\d+\.\.\d+$/)) { + print STDERR "Warning: $key ($ARGS{$key}) changed to '$ok[0]'" + if $verbose and $ARGS{$key} ne ""; + $ARGS{$key}=$ok[0]; + } + else { + print STDERR "Error: $key ($ARGS{$key}) is not one of '".join("','", @ok)."'"; + $err++; + } + } + } + } + if ($ARGS{words} % ($ARGS{mux}*2) != 0 ) { + print STDERR "Words must be divisible by 2*mux (2 * $ARGS{mux})"; + $err++; + } + if ($type eq "RS" and $ARGS{mux} == 1 and ($ARGS{wp_size} % 4 != 0)) { + print STDERR "wp_size must be divisible by 4 for mux = 1 for Single Port Register File"; + $err++; + } + elsif ($type eq "RS" and $ARGS{mux} == 2 and ($ARGS{wp_size} % 2 != 0)) { + print STDERR "wp_size must be divisible by 2 for mux = 2 for Single Port Register File"; + $err++; + } + if ($ARGS{wp_size} < 1 or $ARGS{wp_size} > 36 or $ARGS{wp_size} > $ARGS{bits}-1) { + print STDERR "wp_size out of range ( 1 < wp_size < min(36,bits-1) )"; + $err++; + } + if ($err) { + print STDERR "Failed with $err errors"; + exit 1; + } +} + +my %options = ( + "bits=i" => \$ARGS{bits}, + "change=i" => \$change, + "drive=i" => \$ARGS{drive}, + "frequency=i" => \$ARGS{frequency}, + "mux=i" => \$ARGS{mux}, + "rcols=i" => \$ARGS{rcols}, + "rrows=i" => \$ARGS{rrows}, + "words=i" => \$ARGS{words}, + "wp_size=i" => \$ARGS{wp_size}, + "write_mask=s" => \$ARGS{write_mask}, + "write_thru=s" => \$ARGS{write_thru}, + "type=s" => \$type, + "ser=s" => \$ARGS{ser}, + "compiler-root=s" => \$compilerroot, +# "vert=s" => \$ARGS{vert}, +# "horiz=s" => \$ARGS{horiz}, + "norun" => \$norun, + "verbose" => \$verbose, + "client=s" => \$client, + "interactive" => \$interactive, + "fulcrum-pdk-root=s" => \$pdkroot, + "spec=s" => \$inspecfile, +); + +my %optdes = ( + "compiler-root" => "[$compilerroot]", + "norun" => " show command, do not run all of the long running tools", + "type" => " one of SS,SD,RS,RD", + "change" => " preset p4 change number", + "client" => " p4 client name", + "interactive" => " run gui with preset defaults", +); + +sub usage { + my ($msg)=@_; + print STDERR "$msg" if defined $msg; + my $ml=0; + foreach my $opt (sort keys %options) { + my ($o,$v)=split(/=/,$opt); + $ml = length($o) if $ml < length($o); + } + $ml += 2; + print STDERR "Usage: compilemem [options]"; + print STDERR " Options:"; + foreach my $opt (sort keys %options) { + my ($o,$v)=split(/=/,$opt); + if ($v eq "i") { + $v = "integer"; + } + elsif ($v eq "s") { + $v = "string"; + } + else { + $v = "flag"; + } + if (defined ($optdes{$o})) { + $v .= " $optdes{$o}"; + } + elsif (defined ($coptions{$o})) { + $v .= " (".join(",", @{$coptions{$o}}).")"; + } + $v =~ s/ */ /g; + printf STDERR " %-*.*s : %s\n", $ml,$ml, "--$o", $v; + } + exit 1; +} + +GetOptions ( %options ) or usage(); + +if (defined($inspecfile) and -f "$inspecfile") { + setoptionsfromspecfile($inspecfile); +} + +$type =~ tr/a-z/A-Z/; +usage ("Unknown type $type") if ! defined $in{$type}; + +$instname="$in{$type}$ARGS{words}_$ARGS{bits}_M$ARGS{mux}_".substr($type,1,1)."P" if $instname eq ""; +if ($type =~ /^R/) { + $ARGS{horiz}="met2" if ($ARGS{horiz} eq "met4"); + $ARGS{vert}="met2" if ($ARGS{vert} eq "met4"); +} +if (defined $client) { # check client exists + my $ok=0; + open (P, "p4 -u system clients |"); + while (

    ) { + chomp; + my @f=split; + if ($f[1] eq $client) { + $ok=1; + last; + } + } + close P; + if (!$ok) { + undef $client; + warn ("Client $client does not exist."); + } +} +if ($verbose) { + if (defined ($client)) { + print STDERR "Client $client ok"; + } + else { + print STDERR "Client not specified"; + } +} +if (defined $client) { + if (! defined ($change) or ! ($change =~ /^\d+$/)) { + my $pid = open2 (\*RD, \*WR, "p4 -c $client -u $user change -i"); + usage ("Cannot create p4 change number") if !$pid; + my $changespec=<; + chomp $change; + if ($change =~ /Change (\d+) created/) { + $change = $1; + print STDERR "Created change number $change"; + } + else { + kill $pid; + waitpid $pid, 0; + print STDERR $changespec; + usage ("Change number not created: $change"); + } + kill $pid; + waitpid $pid, 0; + } + open (P, "p4 -c $client client -o |"); + while (

    ) { + chomp; + if (/^Root:/) { + my @f=split; + $clientpath=$f[1]; + } + if (m://depot/hw/cast: and ! defined $castpath) { + s/^[ \t]*//; + my @f = split; + $f[1] =~ s://$client/:$clientpath/:; + $castpath=$f[1]; + $castpath =~ s:/cast/.*:/cast:; + } + if (m://depot/hw/layout/tsmc\d\d/dfII: and ! defined $dfIIpath) { + s/^[ \t]*//; + my @f = split; + $f[1] =~ s://$client/:$clientpath/:; + $dfIIpath=$f[1]; + $dfIIpath =~ s:/dfII/.*:/dfII:; + } + if (m://depot/hw/layout/tsmc\d\d/spar: and ! defined $sparpath) { + s/^[ \t]*//; + my @f = split; + $f[1] =~ s://$client/:$clientpath/:; + $sparpath=$f[1]; + $sparpath =~ s:/spar/.*:/spar:; + } + if (m://depot/hw/layout/tsmc\d\d/spec: and ! defined $specpath) { + s/^[ \t]*//; + my @f = split; + $f[1] =~ s://$client/:$clientpath/:; + $specpath=$f[1]; + $specpath =~ s:/spec/.*:/spec:; + } + } + my $ok=1; + if (! defined $castpath) { + print STDERR "Cannot find cast path in $client"; + $ok=0; + } + if (! defined $dfIIpath) { + print STDERR "Cannot find dfII path in $client"; + $ok=0; + } + if (! defined $specpath) { + print STDERR "Cannot find spec path in $client"; + $ok=0; + } + if (! defined $sparpath) { + print STDERR "Cannot find spar path in $client"; + $ok=0; + } + usage() if ! $ok; + if ($verbose) { + print STDERR "castpath: $castpath"; + print STDERR "specpath: $specpath"; + print STDERR "dfIIpath: $dfIIpath"; + print STDERR "sparpath: $sparpath"; + } +} + +usage "Type must be specified." if length($type) != 2; +$type =~ tr/a-z/A-Z/; +$type = substr($type,0,2); +#open (P, ") { +# chomp; +# s/=(.*)//; +# my $val=$1; +# $val =~ s/ *#.*//; +# my $name=$_; +# $allnames{$name}=$val; +# if ($val =~ /\x7b/) { +# $val =~ s/\x7b(.*)\x7d/$1/; +# my @f=split(/,/,$val); +# if ($f[0] ne "??") { +# $allnames{$name}=$val; +# } +# } +# if (defined($ARGS{$name})) { +# $allnames{$name}=$ARGS{$name}; +# } +#} +#close P; +if (! defined ($compilerpath{$type})) { + usage "Illegal type $type"; +} +if ($type =~ /^S/) { + $ARGS{"synopsys.libname"} = "vendor.artisan.memory.sram.$instname.1"; +} +else { + $ARGS{"synopsys.libname"} = "vendor.artisan.memory.regfile.$instname.1"; +} +check_options(); + +# write the spec files +open (S, ">$instname.spec") or die "Cannot write spec file."; +print S "#user spec file from Fulcrum compilemem"; +my $dt=localtime(time); +print S "#$dt"; +print S "instname=$instname"; + +$ARGS{check_instname}="off"; +foreach my $name (sort keys %coptions) { + next if $name eq "instname"; + if ($type =~ /S$/ and $name eq "dpccm") { next;} + if ($type ne "SD" and $name eq "dnw") { next;} + if (defined ($ARGS{$name})) { + print S "$name=$ARGS{$name}"; + } + elsif (defined ($coptions{$name})) { + my $t = "-$name '${@{$coptions{$name}}}[0]'"; + print S "$name=${@{$coptions{$name}}}[0]"; + print STDERR "Using internal $t"; + } + else { + print STDERR "Using default -$name=$allnames{$name}"; + print S "$name=$allnames{$name}"; + } +} +close S; + +if ($interactive) { + print STDERR "Running interactive, be sure to save the spec file! (Utilities->Write Spec)"; + system ("$compilerroot/$compilerpath{$type}/bin/$compilerpath{$type} -spec '$instname.spec'"); + open (S, "<$instname.spec"); + while () { + chomp; + next if (/^#/); + my ($name,$value)=split(/=/,$_); + $ARGS{$name}=$value if $name ne "pwr_gnd_rename"; + } + close S; + rename "$instname.spec", "$instname.spec.orig"; + my $newinstname="$in{$type}$ARGS{words}_$ARGS{bits}_M$ARGS{mux}_".substr($type,1,1)."P"; + if ($newinstname ne $instname) { + print STDERR "Warning: Changing instname to $newinstname"; + $instname=$newinstname; + } + print STDERR "Done.."; +} + + +#must re-write pwr_gnd_rename not preserved. +open (S, ">$instname.spec") or die "Cannot write spec file."; +print S "#user spec file from Fulcrum compilemem"; +my $dt=localtime(time); +print S "#$dt"; +print S "instname=$instname"; + +$ARGS{check_instname}="off"; +foreach my $name (sort keys %coptions) { + next if $name eq "instname"; + if ($type =~ /S$/ and $name eq "dpccm") { next;} + if ($type ne "SD" and $name eq "dnw") { next;} + if (defined ($ARGS{$name})) { + print S "$name=$ARGS{$name}"; + } + elsif (defined ($coptions{$name})) { + my $t = "-$name '${@{$coptions{$name}}}[0]'"; + print S "$name=${@{$coptions{$name}}}[0]"; + print STDERR "Using internal $t"; + } + else { + print STDERR "Using default -$name=$allnames{$name}"; + print S "$name=$allnames{$name}"; + } +} +close S; + +open (S, ">${instname}_R90.spec") or die "Cannot write spec file."; +print S "#user spec file from Fulcrum compilemem"; +my $dt=localtime(time); +print S "#$dt"; +print S "instname=${instname}_R90"; + +if ($type =~ /^S/) { + $ARGS{"synopsys.libname"} = "vendor.artisan.memory.sram.${instname}_R90.1"; +} +else { + $ARGS{"synopsys.libname"} = "vendor.artisan.memory.regfile.${instname}_R90.1"; +} +$ARGS{check_instname}="off"; +foreach my $name (sort keys %coptions) { + next if $name eq "instname"; + if ($type =~ /S$/ and $name eq "dpccm") { next;} + if ($type ne "SD" and $name eq "dnw") { next;} + if (defined ($ARGS{$name})) { + if ($name eq "horiz") { + print S "vert=$ARGS{$name}"; + } + elsif ($name eq "vert") { + print S "horiz=$ARGS{$name}"; + } + else { + print S "$name=$ARGS{$name}"; + } + } + elsif (defined ($coptions{$name})) { + if ($name eq "horiz") { + print S "vert=${@{$coptions{$name}}}[0]"; + } + elsif ($name eq "vert") { + print S "horiz=${@{$coptions{$name}}}[0]"; + } + else { + print S "$name=${@{$coptions{$name}}}[0]"; + } + print STDERR "Using internal $name=${@{$coptions{$name}}}[0]"; + } + else { + if ($name eq "horiz") { + print S "vert=$allnames{$name}"; + } + elsif ($name eq "vert") { + print S "horiz=$allnames{$name}"; + } + else { + print S "$name=$allnames{$name}"; + } + print STDERR "Using default -$name=$allnames{$name}"; + } +} +close S; + +my $cmd="$compilerroot/$compilerpath{$type}/bin/$compilerpath{$type} all -spec '$instname.spec'"; +print $cmd if $verbose; +my $err=0; +if (! $norun) { + open(C, "$cmd 2>\&1 |"); + while () { + chomp; + $err++ if /Error/; + print if /Error/ or $verbose; + } + close C; +} +die("Run failed") if $err; +$cmd="$compilerroot/$compilerpath{$type}/bin/$compilerpath{$type} all -spec '${instname}_R90.spec'"; +print $cmd if $verbose; +my $err=0; +if (! $norun) { + open(C, "$cmd 2>\&1 |"); + while () { + chomp; + $err++ if /Error/; + print if /Error/ or $verbose; + } + close C; +} +die("Run failed") if $err; +my $changecount=0; +my $sparlibpath=$libpath; +$sparlibpath =~ s:/[^/]+$::; +if ($instname =~ /^REG/) { + $library =~ s/sram/regfile/; + $libpath =~ s/sram/regfile/; +} +foreach my $sfx ("", "_R90") { + my $targetdir="$sparpath/$sparlibpath/${instname}$sfx"; + `mkdir -p "$targetdir"`; + foreach my $filetype (".dat", ".cdl", ".gds2", ".ps", ".spec", ".v", ".vclef", "_ff_1p1v_125c_syn.lib", "_ff_1p1v_0c_syn.lib", "_ss_0p9v_125c_syn.lib", "_tt_1p0v_25c_syn.lib") { + my $sourcefile="$instname$sfx$filetype"; + my $targetfile="$targetdir/$instname$sfx$filetype"; + my $p4target=$targetfile; + $p4target =~ s/#/%2e/g; + if ( -s "$sourcefile") { + if ($sourcefile =~ /\.lib/) { + fixlib ($sourcefile,"${instname}$sfx"); + } + if ($sourcefile =~ /\.vclef$/) { + my $fl; + my @lines; + if (open ($fl, "<$sourcefile")) { + while (<$fl>) { + chomp; + next if /NAMESCASESENSITIVE/; + if (/FOREIGN/) { + my $ln=$_; + $ln =~ s/^\s+//; + my @f=split; + next if ($#f < 3); + } + push @lines, $_ + } + close $fl; + open ($fl, ">$sourcefile"); + print $fl join("\n", @lines); + close $fl; + } + } + my $edit=0; + if (defined ($client) and -f "$targetfile" and ! -w "$targetfile") { + print STDERR "p4 -c $client edit -c $change \"$p4target\""; + `p4 -c $client edit -c $change "$p4target"`; + unlink $targetfile; + } + `/bin/cp -p "$sourcefile" "$targetfile"`; + print STDERR "p4 -c $client add -c $change \"$p4target\""; + `p4 -c $client add -c $change "$p4target"` if defined($client); + $changecount++; + } + else { + print STDERR "$sourcefile does not exist"; + } + } +} +if (! $changecount and defined($client) and $change =~ /^\d+$/) { + print STDERR "Deleting p4 change $change" if $verbose; + `p4 -c $client -u $user change -d $change`; +} +#elsif ( $norun and $change =~ /^\d+$/ and defined $client) { +# `p4 -c $client -u $user revert -c $change //depot/...`; +# `p4 -c $client -u $user change -d $change`; +# +#} +#print STDERR "Files changed:"; +#`p4 -c $client -u $user change -o $change | grep //depot 1>\&2`; +#print STDERR "Run the following commands:"; +#print STDERR "p4 -c $client -u $user submit -c $change"; +my $verbosearg=""; +$verbosearg = "--verbose" if $verbose; +my $refineparent="SRAM"; +foreach my $sfx ("", "_R90") { +print STDERR "importSR $verbosearg --refinement-parent $refineparent --fulcrum-pdk-root '$pdkroot' --change '$change' --client '$client' --dfII-dir '$dfIIpath' --implied VDDPE --gnd-node GND --vdd-node VDDCE --sub-type 1 --lib '$library' --castpath '$castpath' --specpath '$specpath' --merge '$sparpath/$sparlibpath/${instname}$sfx/${instname}$sfx.cdl' '$sparpath/$sparlibpath/${instname}$sfx/${instname}$sfx.gds2'" if $verbose; +`importSR $verbosearg --refinement-parent $refineparent --fulcrum-pdk-root '$pdkroot' --change '$change' --client '$client' --dfII-dir '$dfIIpath' --implied VDDPE --gnd-node GND --vdd-node VDDCE --sub-type 1 --lib '$library' --castpath '$castpath' --specpath '$specpath' --merge '$sparpath/$sparlibpath/${instname}$sfx/${instname}$sfx.cdl' '$sparpath/$sparlibpath/${instname}$sfx/${instname}$sfx.gds2'` if ! $norun; +} +# add the generation of .db files +foreach my $sfx ("", "_R90") { + my $targetdir="$sparpath/$sparlibpath/${instname}$sfx"; + `mkdir -p "$targetdir"`; + foreach my $filetype ("_ff_1p1v_125c_syn.lib", "_ff_1p1v_0c_syn.lib", "_ss_0p9v_125c_syn.lib", "_tt_1p0v_25c_syn.lib") { + my $sourcefile="$instname$sfx$filetype"; + my $targetfile="$targetdir/$instname$sfx$filetype"; + my $dbsourcefile = $sourcefile; + $dbsourcefile =~ s/\.lib$/.db/; + $targetfile =~ s/\.lib$/.db/; + `compile_lib "$sourcefile" "$dbsourcefile"`; + if ( -s $dbsourcefile ) { + my $edit=0; + if (defined ($client) and -f "$targetfile" and ! -w "$targetfile") { + print STDERR "p4 -c $client edit -c $change \"$targetfile\""; + `p4 -c $client edit -c $change "$targetfile"`; + unlink $targetfile; + $edit=1; + } + `/bin/cp -p "$dbsourcefile" "$targetfile"`; + print STDERR "p4 -c $client add -c $change \"$targetfile\"" if ! $edit; + `p4 -c $client add -c $change "$targetfile"` if defined($client) and ! $edit; + $changecount++; + } + else { + print STDERR "$sourcefile does not exist"; + } + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixcdl.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixcdl.pl new file mode 100755 index 0000000000..0a4a61c8ed --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixcdl.pl @@ -0,0 +1,351 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id: fixcdl.pl,v 1.1 2012/10/26 16:34:44 aagrey Exp $ +# $DateTime$ + +my $resistors=<) { + chomp; +# s/\[//g; +# s/\]//g; +# s/\//_/g; + s/{$n}=$map{$f}; + $n++; + } + } + elsif (/^m/i) { + my @f = split; + for (my $n = 0; $n <= 4 ; $n++) { +### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + $f[$n] =~ s/\./_/g; + } +# $f[5] =~ s/ch/mos/; + for (my $n = 6; $n <= $#f; $n++) { + if ($f[$n] =~ /^[lw]=/i) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + } + elsif (/^[rcd]/i) { +# tr/A-Z/a-z/; + my @f = split; + for (my $n = 0; $n <= 2 ; $n++) { +### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + $f[$n] =~ s/\./_/g; + } + for (my $n = 3; $n <= $#f; $n++) { + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + } + elsif (/^x/i) { + my @f = split; + for (my $n = 0; $n < $#f ; $n++) { +### $f[$n] =~ tr/a-z/A-Z/; + if ($n == 3 and $f[$n] =~ /^R/ and $f[$n+1] =~ /=/) { +### $f[$n] =~ tr/A-Z/a-z/; + $resistors{$f[$n]}=1; + } + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + if ($f[$n] =~ /=/) { +### $f[$n] =~ tr/A-Z/a-z/; + $f[$n] = evaluate($f[$n]); + } + else { + $f[$n] =~ s/\./_/g; + } + } + my $n = $#f; + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); +### $f[$n] =~ tr/A-Z/a-z/; + } + } +} +close P; +open (Q, ">$outfile"); +select Q; +open (P, "<$ARGV[0]"); +$ln=""; +while (

    ) { + chomp; +# s/\[//g; +# s/\]//g; +# s/\//_/g; + s//]/g; + s/\s+/ /g; + s/\s$//; + if (/^\+/) { + s/^\+/ /; + $ln .= $_; + next; + } + my $lx=$_; + $_=$ln; + $ln=$lx; + next if /^\*/; + s/\s+/ /g; + s/ \$.*//; + if (/^\.subckt/i or /^\.ends/i) { + if (! $resistorsdone ) { + foreach my $r (sort keys %resistors) { + print ".SUBCKT $r PLUS MINUS w=w l=l\n.ENDS $r\n"; + } + $resistorsdone=1; + } + my @f = split; + for (my $n = 0; $n <= $#f; $n++) { +### $f[$n] =~ tr/a-z/A-Z/ if $n != 1; + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + } + my $pre=shift @f; + my $subckt = shift @f; + my @ports=@f; + my @suffix=(); + while ($ports[$#ports] =~ /=/) { + push @suffix, pop @ports; + } + my $ports=join(" ", @ports); + my $sortedports=join(" ", ((sort sortNatural @ports),@suffix)); + if ($pre =~ /subckt/i) { + print "$pre $subckt $sortedports"; + } else { + print join(" ", ($pre, $subckt, @f)) + } + } + elsif (/^m/i) { + my @f = split; + for (my $n = 0; $n <= 4 ; $n++) { +### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + $f[$n] =~ s/\./_/g; + } +# $f[5] =~ s/ch/mos/; + for (my $n = 6; $n <= $#f; $n++) { + if ($f[$n] =~ /^[lw]=/i) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + print join(" ", @f); + } + elsif (/^[rcd]/i) { +# tr/A-Z/a-z/; + my @f = split; + for (my $n = 0; $n <= 2 ; $n++) { +### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + $f[$n] =~ s/\./_/g; + } + for (my $n = 3; $n <= $#f; $n++) { + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + print join(" ", @f); + } + elsif (/^x/i) { + my @f = split; + my $subcell=undef; + for (my $n = 0; $n < $#f ; $n++) { +### $f[$n] =~ tr/a-z/A-Z/; + if ($n == 3 and $f[$n] =~ /^R/ and $f[$n+1] =~ /=/) { + $f[$n] =~ tr/A-Z/a-z/; + } + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); +### $f[$n] =~ tr/A-Z/a-z/; + } + else { + $f[$n] =~ s/\./_/g; + } + } + my $n = $#f; + while ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); +### $f[$n] =~ tr/A-Z/a-z/; + $n--; + } + $subcell=$f[$n]; + if (defined $portmap{$subcell}) { + my $inst=shift @f; + my @x=(); + my @x=@f; + my $n=0; + foreach my $f (@f) { + last if $f eq "$subcell"; + $x[$portmap{$subcell}->{$n}] = $f; + $n++; + } + @f=($inst, @x); + } + else { + print STDERR "Portmap for $subcell not defined." if $subcell !~ /^rm/; + } + print join(" ", @f); + } + else { + print; + } +} +$_=$ln; +s/\s+/ /g; +if (/^\.ends/i) { + print; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixgds.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixgds.pl new file mode 100755 index 0000000000..971187b1d0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixgds.pl @@ -0,0 +1,74 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +# purpose: to modify gds to Fulcrum/Intel standards + +use strict; +my %valid=(); +my $validcnt=0; +open (P, ") { + chomp; + $valid{$_}=1; + $validcnt++; +} +close P; +my $gdsfile=shift; +open (P, "rdgds '$gdsfile' |"); +my $outfile=shift; +$outfile = "$gdsfile.mod" if ! defined $outfile; +open (Q, "| wrgds > '$outfile'"); +select Q; +my @text=(); +my $validstring=1; +my $validlayer=1; +my %definedpins=(); +my $string; +while (

    ) { + chomp; + s/'VDD'/'Vdd'/g; + s/'VSS'/'GND'/g; + if (/^BGNSTR/ or /^STRNAME/) { + foreach my $key (keys %definedpins) { + $definedpins{$key}=0; + } + } + if (/^TEXT$/) { + @text=($_); + $validstring=$validlayer=0; + next; + } + if (@text) { + if (/^MAG /) { + $_="MAG 0.1"; + } + push @text, $_; + if (/^STRING/) { + my @f=split(/ /,$_,2); + $string=$f[1]; + $string =~ s/'//g; + $validstring=1 if $valid{$string} or !$validcnt; + $validstring=0 if $definedpins{$string} == 1; # no duplicates + $validstring=1; + } + if (/^LAYER (\d+)$/) { + my $l = $1; + $validlayer = 1 + if (($l >= 31 and $l <= 40) or ($l >= 131 and $l <= 140) or $l == 63); + } + if (/ENDEL/) { + if (($validlayer and $validstring) or ($string eq "GND")) { + print join("\n", @text); + $definedpins{$string}=1 if ($string ne "Vdd"); + } + @text=(); + } + next; + } + if (/^ENDEL/) { + @text=(); + } + print; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixportdirection b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixportdirection new file mode 100755 index 0000000000..d305a6c44f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/fixportdirection @@ -0,0 +1,259 @@ +#!/usr/bin/perl -l +# AAG +# $Id: cdl2mycast,v 1.8 2013/04/01 16:41:42 aagrey Exp $ +# $DateTime$ + +use strict; +use Getopt::Long; + +my $library; +my $sub_type=0; +my $refinement_parent=""; +my $gnd_node="VSS"; +my $vdd_node="VDD"; +my @implied=(); +my %implied=(); +my $verbose=0; +my $max_heap_size="2G"; +my $libfile=""; # for determining port direction +my %direction=(); +my %dirlookup=("input" => "-", "output" => "+", "inout" => "-+", "" => "-+"); +my $searchdir=undef; +my %resistors=( + "rm1" => 1, + "rnpolywo" => 1, + "rppolywo" => 1, + "rm10w" => 1, + "rm1w" => 1, + "rm2w" => 1, + "rm3w" => 1, + "rm4w" => 1, + "rm5w" => 1, + "rm6w" => 1, + "rm7w" => 1, + "rm8w" => 1, + "rm9w" => 1, + "rupolym" => 1, +); + +my $cdl; + +my $topcell; + +my %devicetranslation = ( + "N" => "nmos", + "NCH" => "nmos", + "NCHPD_SR" => "nmospd_sr", + "NCHPG_SR" => "nmospg_sr", + "NCH_HVT" => "nmos_hvt", + "NCH_SRAM" => "nmos_sram", + "P" => "pmos", + "PCH" => "pmos", + "PCHPU_SR" => "pmospu_sr", + "PCH_HVT" => "pmos_hvt", + "PCH_SRAM" => "pmos_sram", + "nch" => "nmos", + "nch_18" => "nmos_18", + "nch_dnw" => "nmos_dnw", + "nch_hvt" => "nmos_hvt", + "nch_lvt" => "nmos_lvt", + "nch_na18" => "nmos_na18", + "pch" => "pmos", + "pch_18" => "pmos_18", + "pch_hvt" => "pmos_hvt", + "pch_lvt" => "pmos_lvt", +); + +sub usage { + my ($msg) = @_; + print STDERR "$msg" if defined $msg; + print < + options + lib : the cast library name + sub-type : the desired subtype for this cell + refinement-parent : the cast refinement parent + gnd-node : the cdl GND node + vdd-node : the cdl Vdd node + implied : extra implied node(s) + max-heap-size : normal java max-heap-size + cell : the name of the top cell + libfile : file with cell lib port directions defined + verbose : +EU +exit 1; +} + +sub getdirection { + my ($cell,$pin) = @_; + my %dir=(); + %dir=%{$direction{$cell}} if defined $direction{$cell}; + if (! defined ($dir{$pin})) { + my $x = $pin; + $x =~ s/\[.*//; + $dir{$pin} = $dir{$x} if defined $dir{$x}; + $dir{$pin} = "-" if ! defined($dir{$pin}) and $pin =~ /VDD/i; + $dir{$pin} = "-" if ! defined($dir{$pin}) and $pin =~ /GND$/i; + $dir{$pin} = "-+" if ! defined $dir{$pin}; +# print STDERR "$pin $dir{$pin}" if $dir{$pin} eq "-+"; + } + $dir{$pin}; +} + +sub parselibfile { + my ($file) = @_; + open (P, "<$file"); + print STDERR "Parsing $file" if $verbose; + my $cell; + my $pin; + my $bus; + my $bus_type; + my %bit_width; + my %bit_from; + my %bit_to; + my $direction; + while (

    ) { + chomp; + if (/^\s*cell\s*\(\s*(.*)\s*\)/) { + $cell=$1; + $cell =~ s/\s//g; + $cell =~ s/"//g; + $cell =~ s/'//g; + } + if (/^\s*type\s*\(\s*(.*)\s*\)/) { + $bus_type = $1; + while (

    ) { + chomp; + if (/^\s*([^\s]+)\s*:\s*([^\s]+)\s*;/) { + if ($1 eq "bit_width") { + $bit_width{$bus_type}=$2; + } + if ($1 eq "bit_from") { + $bit_from{$bus_type}=$2; + } + if ($1 eq "bit_to") { + $bit_to{$bus_type}=$2; + } + } + if (/^\s*\x7d/) { + last; + } + } + } + if (/^\s*pin\s*\(\s*(.*)\s*\)/) { + $pin = $1; + $pin =~ tr/a-z/A-Z/; + $direction{$cell}->{$pin}="undefined"; + $direction="undefined"; + undef $bus; + } + if (/^\s*bus\s*\(\s*(.*)\s*\)/) { + $bus = $1; + undef $pin; + } + if (/^\s*bus_type\s*:\s*(.*)\s*;/) { + $bus_type = $1; + print STDERR "BUS TYPE $bus_type not defined" if ! defined $bit_width{$bus_type}; + } + if (/^\s*direction\s*:\s*(.*)\s*;/) { + $direction=$1; + $direction =~ s/\s//g; + $direction = $dirlookup{$direction}; + if (defined ($pin)) { + $direction{$cell}->{$pin}=$direction; + if ($pin =~ /\[/) { + my $base=$pin; + $base =~ s/\[.*//; + $direction{$cell}->{$base}=$direction; + } + } + elsif (defined ($bus)) { + my $to = $bit_to{$bus_type}; + my $from = $bit_from{$bus_type}; + my $width = $bit_width{$bus_type}; + if (defined ($to) and defined ($from) and abs($from-$to)+1 != $width) { + print STDERR "Bus definition may be inconsistent for $bus_type"; + } + if ($to < $from) { + my $x = $from; + $from = $to; + $to = $x; + } + $direction{$cell}->{"$bus"}=$direction; + for (my $n = $from; $n <= $to; $n++) { + $direction{$cell}->{"$bus\[$n\]"}=$direction; + } + } + } + } +} + +GetOptions ( + "lib=s" => \$library, + "libfile=s" => \$libfile, + "search-dir=s" => \$searchdir, + "sub-type=s" => \$sub_type, + "refinement-parent=s" => \$refinement_parent, + "gnd-node=s" => \$gnd_node, + "vdd-node=s" => \$vdd_node, + "verbose" => \$verbose, + "implied=s" => sub { + push @implied, split(/,/,$_[1]); + foreach my $i (@implied) { + $implied{$i}=1; + } + }, + "max-heap-size=s" => \$max_heap_size, + "cell=s" => \$topcell, +) or usage "GetOptions"; + +$implied{$gnd_node}=1; +$implied{$vdd_node}=1; +if ($libfile ne "" and -f $libfile) { + parselibfile($libfile); +} +print STDERR "Warning: $libfile not found" if (! -f $libfile and $libfile ne ""); + +if ( -d "$searchdir") { + @ARGV=`find $searchdir -name '*.cast'`; + chomp @ARGV; +} +foreach my $file (@ARGV) { + open (P, "<$file"); + my $module; + my @lines=(); + while (

    ) { + chomp; + if (/^module\s+(\S+)\s*;/) { + $module=$1; + push @lines, $_; + } + elsif (/^define\s+"(\S+)"\(\)\((.*)\)(.*)/) { + my $cell=$1; + my $nodes=$2; + my $rest=$3; + my $lookupcell=$cell; + if ($cell eq "0") { + $lookupcell=$module; + $lookupcell =~ s/.*\.//; + } + if (defined ($direction{$lookupcell})) { + my %dir=%{$direction{$lookupcell}}; + my @nodes=(); + foreach my $pin (sort keys %dir) { + $dir{$pin}="-" if $dir{$pin} eq ""; + push @nodes, "$dir{$pin}$pin" if $dir{$pin} ne "undefined"; + } + $nodes="node ".join(", ", @nodes); + } + push @lines, "define \"$cell\"()($nodes)$rest"; + } + else { + push @lines, $_; + } + } + close P; + open (P, ">$file"); + print P join("\n", @lines); + close P; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/gen_sram_scan_wrap.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/gen_sram_scan_wrap.pl new file mode 100755 index 0000000000..9b9b7854ba --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/gen_sram_scan_wrap.pl @@ -0,0 +1,212 @@ +#!/usr/intel/bin/perl -w + +use strict; +use Getopt::Long; + +my $out_dir = "."; + +my $modulename="module"; +my $bitsname="BITS"; +my $addr_depthname="MEM_HEIGHT"; +my $addr_widthname="MEM_WIDTH"; + +sub usage { +print STDERR "Usage: gen_sram_scan_wrap.pl [--out-dir=(dir)] mem1.v mem2.v ...\n"; +exit 1; +} + +GetOptions ( "out-dir=s" => \$out_dir) or usage; + +while (@ARGV) { + print "Creating wrapper for $ARGV[0].\n"; + eval { + my $param = parse_artisan_sram_verilog($ARGV[0]); + write_wrapper($ARGV[0], $out_dir, $param); + }; + if ($@) { + foreach my $f ($@) { + print STDERR $f; + } + print STDERR "Error processing $ARGV[0]. Skipping.\n"; + } + shift; +} + + +sub parse_artisan_sram_verilog { + my $file = shift; + + my $param = {}; + + open (SRAM_IN, $file) || die "Couldn't read $file.\n"; + while () { + if (/^module\s+([^\s]+)/) { + $param->{$modulename} = $1; + } + if (/^\s*parameter\s+([^\s=]+)\s*=\s*([^;]+);/) { + $param->{$1} = $2; + } + } + close SRAM_IN; + if (!exists $param->{$modulename}) { + die "No module declaration in $file.\n"; + } + if (!exists $param->{$bitsname}) { + die "No BITS parameter in $file.\n"; + } + # not really used + if (!exists $param->{$addr_depthname}) { + # 130nm vs 65nm compilers + if (exists $param->{word_depth}) { + $param->{$addr_depthname} = $param->{word_depth}; + } + else { + die "No word_depth parameter in $file.\n"; + } + } + if (!exists $param->{$addr_widthname}) { + # 130nm vs 65nm compilers + if (exists $param->{addr_width}) { + $param->{$addr_widthname} = $param->{addr_width}; + } + else { + die "No addr_width parameter in $file.\n"; + } + } + return $param; +} + +# TODO: Handler dual-ported case +sub write_wrapper { + my $file = shift; + my $wrap_dir = shift; + my $param = shift; + + my $wrap_file = ""; + if ($file =~ /([^\/]+)\.v$/) { + $wrap_file = $wrap_dir . "/SR_" . $1 . ".v"; + } + else { + die "Badly formatted filename $file.\n"; + } + + my $data_range = sprintf("[%d:0]", $param->{$bitsname}-1); + my $addr_range = sprintf("[%d:0]", $param->{$addr_widthname}-1); + my $now = localtime(); + + open (SRAM_OUT, ">$wrap_file") || die "Couldn't write to $wrap_file.\n"; + print SRAM_OUT <{$modulename}. + * Adds scan shadow flops on all inputs & outputs. + * Adds repair address implemented with sideband flip-flops. + * Autogenerated by gen_sram_scan_wrap.pl on $now + */ +module SR_$param->{$modulename} ( +eof + if ($param->{$modulename} =~ /_SP$/ or $param->{$modulename} =~ /_SP_R90$/) { + print SRAM_OUT <{$addr_widthname}, $param->{$bitsname}) wrap( + .CLK(CLK), + .SCAN_EN(SCAN_EN), .SCAN_MODE(SCAN_MODE), + .SCAN_IN(SCAN_IN), .SCAN_OUT(SCAN_OUT), + .INPUT_CEN(CEN), .INPUT_WEN(WEN), + .INPUT_A(A), .INPUT_D(D), + .REPAIR_CFG(REPAIR_CFG), + .TO_SRAM_CEN(sram_cen), .TO_SRAM_WEN(sram_wen), + .TO_SRAM_A(sram_a), .TO_SRAM_D(sram_d), + .FROM_SRAM_Q(sram_q), + .OUTPUT_Q(Q) + ); + + $param->{$modulename} core( + .Q(sram_q), .CLK(CLK), .CEN(sram_cen), .WEN(sram_wen), + .A(sram_a), .D(sram_d) + ); +endmodule +eof + } + elsif ($param->{$modulename} =~ /_DP$/ or $param->{$modulename} =~ /_DP_R90$/) { + print SRAM_OUT <{$addr_widthname}, $param->{$bitsname}) wrap( + .CLK(CLKA), + .SCAN_EN(SCAN_EN), .SCAN_MODE(SCAN_MODE), + .SCAN_IN(SCAN_IN), .SCAN_OUT(SCAN_OUT), + .INPUT_CENA(CENA), .INPUT_WENA(WENA), + .INPUT_AA(AA), .INPUT_DA(DA), + .INPUT_CENB(CENB), .INPUT_WENB(WENB), + .INPUT_AB(AB), .INPUT_DB(DB), + .REPAIR_CFG(REPAIR_CFG), + .TO_SRAM_CENA(sram_cena), .TO_SRAM_WENA(sram_wena), + .TO_SRAM_AA(sram_aa), .TO_SRAM_DA(sram_da), + .TO_SRAM_CENB(sram_cenb), .TO_SRAM_WENB(sram_wenb), + .TO_SRAM_AB(sram_ab), .TO_SRAM_DB(sram_db), + .FROM_SRAM_QA(sram_qa), + .FROM_SRAM_QB(sram_qb), + .OUTPUT_QA(QA), + .OUTPUT_QB(QB) + ); + + $param->{$modulename} core( + .QA(sram_qa), .CLKA(CLKA), .CENA(sram_cena), .WENA(sram_wena), + .AA(sram_aa), .DA(sram_da), + .QB(sram_qb), .CLKB(CLKB), .CENB(sram_cenb), .WENB(sram_wenb), + .AB(sram_ab), .DB(sram_db) + ); +endmodule +eof + } + else { + die "Unknown memory type $param->{$modulename}.\n"; + } + close SRAM_OUT; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importIP.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importIP.pl new file mode 100755 index 0000000000..832dad41eb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importIP.pl @@ -0,0 +1,680 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +my $cdl=undef; +my $verbose=0; +my $vdd="VDD"; +my $gnd="VSS"; +my $pdk=undef; + +my $refinement_parent=undef; +my $lib_name=undef; +my $sub_type=0; +my $bind_rul_in="/dev/null"; +my $output_dir=undef; +my $all_cells=0; +my $lib_file=undef; +my $topcell=""; +my $cdl2cast=0; +my %options=(); +my $cast_path=undef; + +sub usage { + my ($msg)=@_; + print STDERR "Usage: importPR [options]"; + foreach my $opt (sort keys %options) { + my $r=$options{$opt}; + my $ref=ref($options{$opt}); + if ($opt =~ /=/) { + my $o=$opt; + $o =~ s/=.*//; + if ($ref eq "SCALAR") { + print STDERR " --$o=[".$$r."]"; + } + else { + print STDERR " --$o=$o"; + } + } + else { + if ($ref eq "SCALAR") { + print STDERR " --$opt [$$r]"; + } + else { + print STDERR " --$opt [$opt]"; + } + } + } + print STDERR "$msg" if defined $msg; + exit 1; +} + +sub mergecast { + my @files=@_; + my $fh; + my @header=(); + my %cells=(); + my $header=0; + my $cell=""; + foreach my $file (@files) { + if (open($fh, "<$file")) { + while (<$fh>) { + chomp; + if (/^define "(\S+)"/) { + $cell=$1; + @{$cells{$cell}}=(); + $header=1; + } + elsif (/^define (\S+)\(/) { + $cell=$1; + @{$cells{$cell}}=(); + $header=1; + } + push @{$cells{$cell}}, $_ if $cell ne ""; + push @header, $_ if $header==0; + if (/^\x7d/) { + push @{$cells{$cell}}, "" if $cell ne ""; + $cell=""; + } + } + } + else { + print STDERR "Cannot open $file"; + } + } + my @out=@header; + my $cnt=0; + foreach my $cell (sort keys %cells) { + push @out, @{$cells{$cell}}; + $cnt++; + } + @out; +} + +sub evalit { + my ($value)=@_; + $value =~ s/'//g; + $value =~ s/(\d)u/$1*1e-6/ig; + $value =~ s/(\d)n/$1*1e-9/ig; + $value =~ s/(\d)p/$1*1e-12/ig; + $value =~ s/(\d)f/$1*1e-15/ig; + $value =~ s/[\(\)]//g; + print STDERR $value if $value =~ /\*/ and $value =~ /[a-df-z]/; + eval "\$value=$value"; + print STDERR $value if $value =~ /\*/ and $value =~ /[a-df-z]/; + $value; +} + +sub evaluate { + my ($value)=@_; + return $value; + my ($n,$v)=split(/=/, $value); + if (defined ($v)) { + return "$n=".evalit($v); + } + return evalit($n); +} + +# purpose : to modify Avago netlist to agree with Fulcrum/Intel conventions +sub sortNatural { + return $a cmp $b if $a !~ /\d/ and $b !~ /\d/; + my $sa=$a; + $sa =~ s/(\d+)/_/; + my $na=$1; + $na = -1 if ! defined $na; + my $sb=$b; + $sb =~ s/(\d+)/_/; + my $nb=$1; + $nb = -1 if ! defined $nb; + return $sa cmp $sb if $sa ne $sb; + $na - $nb; +} + +my %direction=(); +my %isbus=(); +my %dirlookup=("input" => "-", "output" => "+", "inout" => "-+", "" => "-+", "internal" => "i"); + +sub getdirection { + my ($cell,$pin) = @_; + my %dir=(); + %dir=%{$direction{$cell}} if defined $direction{$cell}; + if (! defined ($dir{$pin})) { + my $x = $pin; + $x =~ s/\[.*//; + $dir{$pin} = $dir{$x} if defined $dir{$x}; + $dir{$pin} = "-" if ! defined($dir{$pin}) and $pin =~ /VDD/i; + $dir{$pin} = "-" if ! defined($dir{$pin}) and $pin =~ /GND$/i; + $dir{$pin} = "-+" if ! defined $dir{$pin}; + } + $dir{$pin}; +} + +sub parselibfile { + my ($file) = @_; + open (P, "<$file"); + print STDERR "Parsing $file" if $verbose; + my $cell; + my $pin; + my $bus; + my $bus_type; + my %bit_width; + my %bit_from; + my %bit_to; + my $direction; + while (

    ) { + chomp; + if (/^\s*cell\s*\(\s*(.*)\s*\)/) { + $cell=$1; + $cell =~ s/\s//g; + $cell =~ s/"//g; + $cell =~ s/'//g; + } + if (/^\s*type\s*\(\s*(\S+)\s*\)/) { + $bus_type = $1; + while (

    ) { + chomp; + if (/^\s*(\S+)\s*:\s*(\S+)\s*;/) { + if ($1 eq "bit_width") { + $bit_width{$bus_type}=$2; + } + if ($1 eq "bit_from") { + $bit_from{$bus_type}=$2; + } + if ($1 eq "bit_to") { + $bit_to{$bus_type}=$2; + } + } + if (/^\s*\x7d/) { + last; + } + } + } + if (/^\s*pin\s*\(\s*(.*)\s*\)/) { + $pin = $1; +# $pin =~ tr/a-z/A-Z/; + $direction{$cell}->{$pin}="undefined"; + $direction="undefined"; + undef $bus; + } + if (/^\s*bus\s*\(\s*(.*)\s*\)/) { + $bus = $1; + $isbus{$cell}->{$bus}=1; + undef $pin; + } + if (/^\s*bus_type\s*:\s*(\S+)\s*;/) { + $bus_type = $1; + print STDERR "BUS TYPE :$bus_type: not defined" if ! defined $bit_width{$bus_type}; + } + if (/^\s*direction\s*:\s*(.*)\s*;/) { + $direction=$1; + $direction =~ s/\s//g; + $direction = $dirlookup{$direction}; + if (defined ($pin)) { + $direction{$cell}->{$pin}=$direction; + if ($pin =~ /\[/) { + my $base=$pin; + $base =~ s/\[.*//; + $direction{$cell}->{$base}=$direction; + } + } + elsif (defined ($bus) and defined($bit_width{$bus_type})) { + my $to = $bit_to{$bus_type}; + my $from = $bit_from{$bus_type}; + my $width = $bit_width{$bus_type}; + if (defined ($to) and defined ($from) and abs($from-$to)+1 != $width) { + print STDERR "Bus definition may be inconsistent for $bus_type"; + } + if ($to < $from) { + my $x = $from; + $from = $to; + $to = $x; + } + $direction{$cell}->{"$bus"}=$direction; + for (my $n = $from; $n <= $to; $n++) { + $direction{$cell}->{"$bus\[$n\]"}=$direction; + } + } + } + } +} + +sub fixcastfile { + my ($file)=@_; + open (P, "<$file"); + my $module; + my @lines=(); + while (

    ) { + chomp; + if (/^module\s+(\S+)\s*;/) { + $module=$1; + push @lines, $_; + } + elsif (/^define\s+"(\S+)"\(\)\((.*)\)(.*)/) { + my $cell=$1; + my $nodes=$2; + my $rest=$3; + my $lookupcell=$cell; + if ($cell eq "0") { + $lookupcell=$module; + $lookupcell =~ s/.*\.//; + } + if (defined ($direction{$lookupcell})) { + my %dir=%{$direction{$lookupcell}}; + my @nodes=(); + my $lastbus=""; + my $a=-1; + my $b=-1; + foreach my $pin (sort sortNatural keys %dir) { + next if $dir{$pin} eq "i"; + my $node=$pin; + my $bus=""; + next if $isbus{$lookupcell}->{$pin}; + if ( $pin =~ /(\S+)\[(\d+)\]$/) { + $bus=$1; + my $n=$2; + if ($bus ne $lastbus) { + if ($lastbus ne "") { + push @nodes, "$dir{$pin}$lastbus\[$a..$b\]"; + } + $lastbus=$bus; + $a=$b=$n; + next; + } + else { + $a = $a > $n ? $n : $a; + $b = $b < $n ? $n : $b; + } + next; + } + elsif ($lastbus ne "") { + push @nodes, "$dir{$pin}$lastbus\[$a..$b\]"; + $lastbus=""; + } + $dir{$pin}="-" if $dir{$pin} eq ""; + push @nodes, "$dir{$pin}$pin" if $dir{$pin} ne "undefined"; + } + $nodes="node ".join(", ", @nodes); + } + push @lines, "define \"$cell\"()($nodes)$rest"; + } + else { + s/_L_/[/g; + s/_R_/]/g; + push @lines, $_; + } + } + close P; + open (P, ">out.cast"); + open (P, ">$file"); + print P join("\n", @lines); + close P; +} + +sub fixcdl { + my ($infile,$outfile)=@_; + $outfile = "$infile.mod" if ! defined $outfile; + my %portmap=(); + open (P, "<$infile"); + my $ln=""; + my @lines=(); + my %resistors=(); + my $resistorsdone=0; + my %called=(); + while (

    ) { + chomp; + s/\//_/g; + if (/^\+/) { + s/^\+/ /; + $ln .= $_; + next; + } + my $lx=$_; + $_=$ln; + $ln=$lx; + s/\s+/ /g; + push @lines, $_; + if (/^\.subckt/i) { + my @f = split; + for (my $n = 0; $n <= $#f; $n++) { + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + } + my $pre=shift @f; + while ($f[$#f] =~ /=/) { + pop @f; + } + my $subckt = shift @f; + my $ports=join(" ", @f); + my $sortedports=join(" ", sort sortNatural @f); + my $n=0; + my %map=(); + $called{$subckt} += 0; + foreach my $f (sort sortNatural @f) { + $map{$f}=$n++; + } + $n=0; + foreach my $f (@f) { + $portmap{$subckt}->{$n}=$map{$f}; + $n++; + } + } + elsif (/^m/i) { + my @f = split; + for (my $n = 0; $n <= 4 ; $n++) { + ### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + $f[$n] =~ s/\./_/g; + } + # $f[5] =~ s/ch/mos/; + for (my $n = 6; $n <= $#f; $n++) { + if ($f[$n] =~ /^[lw]=/i) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + } + elsif (/^[rcd]/i) { + # tr/A-Z/a-z/; + my @f = split; + for (my $n = 0; $n <= 2 ; $n++) { + ### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] =~ /^VDD$/i or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i or $f[$n] =~ /^VSS$/i; + $f[$n] =~ s/\./_/g; + } + for (my $n = 3; $n <= $#f; $n++) { + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + } + elsif (/^x/i) { + my @f = split; + my $ckt=$f[$#f]; + for (my $n = 0; $n <= $#f ; $n++) { + ### $f[$n] =~ tr/a-z/A-Z/; + if ($n == 3 and $f[$n] =~ /^R/ and $f[$n+1] =~ /=/) { + ### $f[$n] =~ tr/A-Z/a-z/; + $resistors{$f[$n]}=1; + } + $f[$n] = "Vdd" if $f[$n] eq "VDD" or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i; + if ($f[$n] =~ /=/) { + ### $f[$n] =~ tr/A-Z/a-z/; + $f[$n] = evaluate($f[$n]); + } + else { + $f[$n] =~ s/\./_/g; + $ckt=$f[$n]; + } + } + $called{$ckt}++; + my $n = $#f; + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); + ### $f[$n] =~ tr/A-Z/a-z/; + } + } + } + $ln =~ s/\s+/ /; + push @lines, $ln; + close P; + open (Q, ">$outfile"); + foreach my $line (@lines) { + $_=$line; + s/\//_/g; + s/\s+/ /g; + s/\s$//; + if (/^\.subckt/i or /^\.ends/i) { +# if (! $resistorsdone ) { +# foreach my $r (sort keys %resistors) { +# print Q ".SUBCKT $r PLUS MINUS w=w l=l\n.ENDS $r\n"; +# } +# $resistorsdone=1; +# } + my @f = split; + for (my $n = 0; $n <= $#f; $n++) { + ### $f[$n] =~ tr/a-z/A-Z/ if $n != 1; + $f[$n] = "Vdd" if $f[$n] eq "VDD" or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i; + } + my $pre=shift @f; + my $subckt = shift @f; + my $ports=join(" ", @f); + my $sortedports=join(" ", sort sortNatural @f); + if ($pre =~ /subckt/i) { + print Q "$pre $subckt $sortedports"; + } else { + print Q join(" ", ($pre, $subckt, @f)) + } + } + elsif (/^m/i) { + my @f = split; + for (my $n = 0; $n <= 4 ; $n++) { + ### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] eq "VDD" or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i; + $f[$n] =~ s/\./_/g; + } + # $f[5] =~ s/ch/mos/; + for (my $n = 6; $n <= $#f; $n++) { + if ($f[$n] =~ /^[lw]=/i) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + print Q join(" ", @f); + } + elsif (/^[rcd]/i) { + # tr/A-Z/a-z/; + my @f = split; + for (my $n = 0; $n <= 2 ; $n++) { + ### $f[$n] =~ tr/a-z/A-Z/; + $f[$n] = "Vdd" if $f[$n] eq "VDD" or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i; + $f[$n] =~ s/\./_/g; + } + for (my $n = 3; $n <= $#f; $n++) { + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); + } + elsif ($f[$n] =~ /^m/i) { + $f[$n] = ""; + } + } + print Q join(" ", @f); + } + elsif (/^x/i) { + my @f = split; + my $subcell=undef; + for (my $n = 0; $n < $#f ; $n++) { + ### $f[$n] =~ tr/a-z/A-Z/; + if ($n == 3 and $f[$n] =~ /^R/ and $f[$n+1] =~ /=/) { + $f[$n] =~ tr/A-Z/a-z/; + } + $f[$n] = "Vdd" if $f[$n] eq "VDD" or $f[$n] =~ /\.VDD$/i; + $f[$n] = "GND" if $f[$n] =~ /\.GND$/i; + if ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); + ### $f[$n] =~ tr/A-Z/a-z/; + } + else { + $f[$n] =~ s/\./_/g; + } + } + my $n = $#f; + while ($f[$n] =~ /=/) { + $f[$n] = evaluate($f[$n]); + ### $f[$n] =~ tr/A-Z/a-z/; + $n--; + } + $subcell=$f[$n]; + if (defined $portmap{$subcell}) { + my $inst=shift @f; + my @x=(); + my @x=@f; + my $n=0; + foreach my $f (@f) { + last if $f eq "$subcell"; + $x[$portmap{$subcell}->{$n}] = $f; + $n++; + } + @f=($inst, @x); + } + else { + print STDERR "Portmap for $subcell not defined." if $subcell !~ /^rm/; + } + print Q join(" ", @f); + } + else { + print Q; + } + } + my $top=undef; + foreach my $cell (keys %called) { + if ($called{$cell}==0) { + if (defined ($top)) { + print STDERR "Too many top cells $cell $top\n"; + } + else { + $top=$cell; + } + } + } + $top; +} + +%options=( + "refinement-parent=s" => \$refinement_parent, + "lib-name=s" => \$lib_name, + "sub-type=s" => \$sub_type, + "output-dir=s" => \$output_dir, + "all-cells" => \$all_cells, + "vdd-node=s" => \$vdd, + "gnd-node=s" => \$gnd, + "cdl=s" => \$cdl, + "fulcrum-pdk-root=s" => \$pdk, + "lib-file=s" => \$lib_file, + "cell=s" => \$topcell, + "cdl2cast" => \$cdl2cast, + "cast-path=s" => \$cast_path, +); + +GetOptions ( + %options +) or usage; + +usage "Bad lib-name" if ! defined $lib_name or $lib_name !~ /\./; +usage "No output-dir specified" if ! defined $output_dir; +usage "No refinement-parent" if ! defined $refinement_parent; +`mkdir -p "$output_dir"`; +usage "Could not create output-dir" if ! -d $output_dir; +usage "CDL not specified" if ! defined $cdl or ! -s $cdl; +my $spec_dir="$output_dir/spec"; +my $cast_dir="$output_dir/cast"; +my $name_table="$output_dir/skill"; +`mkdir -p $output_dir`; +`mkdir -p $spec_dir`; +`mkdir -p $output_dir`; +my $mod="$cdl.modw"; +$mod =~ s:.*/::; +my $rv=system("fixcdl",$cdl, $mod); +die "Bad return for fixcdl" if $rv != 0; +parselibfile($lib_file); +my $libdir=$lib_name; +$libdir=~ s:\.:/:g; +my @cmd=(); +if ($cdl2cast) { # used for stdcells so you get PRS + push @cmd, "cdl2cast"; + push @cmd, "--max-heap-size=2G"; + push @cmd, "--cdl-file=$mod"; + push @cmd, "--output-spec=$spec_dir"; + push @cmd, "--output-cast=$cast_dir"; + push @cmd, "--name-table-dir=$name_table"; + push @cmd, "--vdd-node=$vdd"; + push @cmd, "--gnd-node=$gnd"; + push @cmd, "--refinement-parent=$refinement_parent"; + push @cmd, "--lib-name=$lib_name"; + push @cmd, "--sub-type=$sub_type"; + push @cmd, "--meters-per-input-unit=1"; + push @cmd, "--layout-to-cdl-bind-rul=/dev/null"; + push @cmd, "--output-cdl-to-layout-bind-rul=$output_dir/cdl2layoutbind.rul"; + push @cmd, "--output-cast-cells=$output_dir/allcells.txt"; + push @cmd, "--bind-rul-header=$pdk/share/Fulcrum/assura/bind.rul"; + push @cmd, "--all-cells" if $all_cells; + push @cmd, "--bind-rul-in=bind.rul.combined"; + my $rv=system(@cmd); + die "cdl2cast fails with return code $rv" if $rv != 0; +} +else { + push @cmd, "cdl2cast2"; + push @cmd, "--lib=vendor.avago.mem"; + push @cmd, "--sub-type=0"; + push @cmd, "--gnd-node=GND"; + push @cmd, "--vdd-node=Vdd"; + push @cmd, "--cell=$topcell"; + push @cmd, "--libfile=$lib_file"; + push @cmd, "--refinement-parent=$refinement_parent"; + push @cmd, "--output-dir=$output_dir"; + push @cmd, "$mod"; + my $rv=system(@cmd); + print STDERR "cdl2cast2 returns $rv" if $rv != 0; + exit $rv if $rv != 0; + # use jflat to check the cast syntax + @cmd=("jflat"); + push @cmd, "--cast-path=$output_dir/cast:$output_dir/spec:$cast_path"; + push @cmd, "--cell=$lib_name.$topcell.$sub_type"; + push @cmd, "--tool=check,cdl"; + push @cmd, "--output-dir=$output_dir"; + $rv=system(@cmd); + print STDERR "jflat returns $rv" if $rv != 0; + exit $rv if $rv != 0; + my ($cast_dir,$spec_dir)=split(/:/,$cast_path); + my @spec=`find $output_dir/spec/$libdir -name '*.cast'`; + chomp @spec; + my $writeerr=0; + foreach my $spec (@spec) { + $spec =~ s:$output_dir/spec:$spec_dir:; + if ( ! -w $spec and -e $spec ) { + print STDERR "Cannot write to $spec"; + $writeerr++; + } + } + system("rsync", "-a", "$output_dir/spec/$libdir/", "$spec_dir/$libdir") if ! $writeerr; + my @merged=mergecast( "$output_dir/cast/$libdir.cast", "$cast_dir/$libdir.cast"); + if ( ( -w "$cast_dir/$libdir.cast" or ! -f "$cast_dir/$libdir.cast") and open (P, ">$cast_dir/$libdir.cast")) { + print P join("\n", @merged); + close P; + } + else { + print STDERR "Cannot write to $cast_dir/$libdir.cast"; + } + exit 0; +} + +fixcastfile("$output_dir/cast/$libdir.cast"); +open (P, "<$output_dir/allcells.txt"); # generated by cdl2cast +while (

    ) { + chomp; + next if /CBLK/; + my $topcell=$_; + my @jflat=(); + push @jflat, "jflat"; + push @jflat, "--tool=cdl"; + push @jflat, "--cell=$topcell"; + push @jflat, "--output-dir=$output_dir"; + push @jflat, "--cast-path=/p/work/aagrey/rrc/cast:$cast_dir:$spec_dir"; + my $rv=system(@jflat); +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importSR.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importSR.pl new file mode 100755 index 0000000000..1dc0ab71f8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/util/importSR.pl @@ -0,0 +1,700 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +my $tmpwd; +my $verbose=0; +my $debug=0; + +#hack for 65nm +my %rho = ( + "rm1" => 0.160, + "rm2" => 0.140, + "rm3" => 0.140, + "rm4" => 0.140, + "rm5" => 0.140, + "rm6" => 0.140, + "rm7" => 0.140, + "rm8" => 0.022, + "rppolywo" => 690, +); + +END { +print STDERR "Cleaning up" if $verbose; +`/bin/rm -rf $tmpwd` if defined $tmpwd and ! $debug +} + +my $library; +my $sub_type=1; +my $refinement_parent=""; +my $gnd_node="VSS"; +my $vdd_node="VDD"; +my @implied=(); +my %implied=(); +my $max_heap_size="2G"; +my $topcell; +my $cdl; +my $gds; +my $pdkroot; +my $dfIIdir; +my $force=0; +my $merge=0; +my $casthome=""; +my $castpath=""; +my $specpath=""; +my $client; +my $change; + +my %devicetranslation = ( + "N" => "nmos", + "NCH" => "nmos", + "NCHPD_SR" => "nmospd_sr", + "NCHPG_SR" => "nmospg_sr", + "NCH_HVT" => "nmos_hvt", + "NCH_SRAM" => "nmos_sram", + "P" => "pmos", + "PCH" => "pmos", + "PCHPU_SR" => "pmospu_sr", + "PCH_HVT" => "pmos_hvt", + "PCH_SRAM" => "pmos_sram", + "NDIO" => "ndio", + "PDIO" => "pdio", + "n" => "nmos", + "nch" => "nmos", + "nchpd_sr" => "nmospd_sr", + "nchpg_sr" => "nmospg_sr", + "nch_hvt" => "nmos_hvt", + "nch_sram" => "nmos_sram", + "p" => "pmos", + "pch" => "pmos", + "pchpu_sr" => "pmospu_sr", + "pch_hvt" => "pmos_hvt", + "pch_sram" => "pmos_sram", + "ndio" => "ndio", + "pdio" => "pdio", +); + +sub usage { + my ($msg) = @_; + print STDERR "$msg" if defined $msg; + print < + options + cell : the name of the top cell + dfII-dir : dfII cadence root + force : force overwrite of data + fulcrum-pdk-root : the pdk root + gnd-node : the cdl GND node + implied : extra implied node(s) + lib : the cast library name + max-heap-size : normal java max-heap-size + merge : merge with existing directory + refinement-parent : the cast refinement parent + sub-type : the desired subtype for this cell + vdd-node : the cdl Vdd node + verbose : show progress + debug : debug mode, does not remove tmp directories +EU +exit 1; +} + +GetOptions ( + "lib=s" => \$library, + "sub-type=s" => \$sub_type, + "refinement-parent=s" => \$refinement_parent, + "gnd-node=s" => \$gnd_node, + "vdd-node=s" => \$vdd_node, + "implied=s" => sub { + push @implied, split(/,/,$_[1]); + foreach my $i (@implied) { + $implied{$i}=1; + } + }, + "max-heap-size=s" => \$max_heap_size, + "cell=s" => \$topcell, + "fulcrum-pdk-root=s" => \$pdkroot, + "dfII-dir=s" => \$dfIIdir, + "verbose" => \$verbose, + "debug" => \$debug, + "force" => \$force, + "merge" => \$merge, + "castpath=s" => \$castpath, + "specpath=s" => \$specpath, + "change=i" => \$change, + "client=s" => \$client, +) or usage; + +$verbose = 1 if $debug; +$cdl = shift if defined $ARGV[0]; +$gds = shift if defined $ARGV[0]; +usage("Specify CDL file") if ! -s $cdl; +usage("Specify GDS file") if ! -s $gds; + +if (! defined $topcell) { + $topcell = `awk '/SUBCKT/ { name=\$2 } END { print name }' '$cdl'`; + chomp $topcell; + if ($topcell =~ /^REG/) { + $library = "vendor.artisan.memory.regfile" if ! defined $library; + $refinement_parent="REGFILE" if ! defined $refinement_parent; + } + elsif ($topcell =~ /^SRAM/) { + $library = "vendor.artisan.memory.sram" if ! defined $library; + $refinement_parent="SRAM" if ! defined $refinement_parent; + } +} + +my $path=$library; +$path =~ s/\./\//g; +my $cpath = $path; +$cpath =~ s/\/[^\/]+$//; +my $lname=$path; +$lname =~ s/.*\///; +$casthome=$topcell if $casthome eq ""; +if ($castpath eq "") { + $castpath="$casthome/cast/$cpath"; +} +else { + $castpath="$castpath/$cpath"; +} +if ($specpath eq "") { + $specpath="$casthome/spec/$path"; +} +else { + $specpath="$specpath/$path"; +} +if ((-d "$castpath" or -d "$specpath") and ! $force and ! $merge) { + usage "$castpath or $specpath exists, use --force to overwrite.\n". + "or --merge to Merge"; +} +if ( ! $merge ) { + `/bin/rm -rf "$castpath" "$specpath"`; +} + +# create the cast and spec files +`mkdir -p "$castpath"` if ! -d "$castpath"; +`mkdir -p "$specpath"` if ! -d "$specpath"; + +print STDERR "Creating Cast and Spec files" if $verbose; +open (P, "<$cdl") or die "Cannot open $cdl"; +my %subckts=(); +my %lines=(); +my $ln=""; +my $subckt=""; +my @lines=(); +my %types=(); +my %gnd=(); +my %vdd=(); +my %order=(); +my %place=(); +while (

    ) { + chomp; + next if (/^\*/); + s/ \$.*//; + if (/^\+/) { + s/^\+/ /; + $ln .= $_; + next; + } + my $lx = $_; + $_ = $ln; + $ln = $lx; + s/ */ /g; + if (/^.global/i) { + s/ \$.*//; + my @f=split; + shift @f; + foreach my $f (@f) { + $implied{$f}=1 if $f ne $gnd_node and $f ne $vdd_node; + } + } + if (/^\.subckt/i) { + my @f=split; + shift @f; + $subckt = shift @f; + $gnd{$subckt}=$vdd{$subckt}=-1; + foreach my $n (0..$#f) { + $gnd{$subckt} = $n if $f[$n] eq "gnd_node"; + $vdd{$subckt} = $n if $f[$n] eq "vdd_node"; + $order{"$subckt:$n"}=$f[$n]; + } + $subckts{$subckt}=[@f]; + @lines=(); + push @lines, $_; + next; + } + if (/^\.ends/i) { + push @lines, $_; + $lines{$subckt}=[@lines]; + $subckt = ""; + next; + } + if ($subckt ne "") { + # look for subckt resistors + if(/^x/i and /w=/i and /l=/i) { + s/^x/R/i; + my @f=split; + my $w=0; + my $l=0; + my $m=1; + my $type=$f[3]; + $type =~ tr/A-Z/a-z/; + my $r=0; + foreach my $f (@f) { + if ($f =~ /w=(.*)/i) { + $w = $1; + $w =~ tr/A-Z/a-z/; + $w =~ s/u$/e-6/; + } + if ($f =~ /l=(.*)/i) { + $l = $1; + $l =~ tr/A-Z/a-z/; + $l =~ s/u$/e-6/; + } + if ($f =~ /m=(.*)/i) { + $m = $1; + $m =~ tr/A-Z/a-z/; + $m =~ s/u$/e-6/; + } + } + if ($l > 0 and $w > 0 and $m > 0) { + $r = sprintf "%g", $l/$w/$m*$rho{$type}; + $_="$f[0] $f[1] $f[2] $r \$MODEL=$f[3] $f[4] $f[5] $f[6]"; + } + } + if (/^x/i) { + if (defined($types{$subckt}) and $types{$subckt} ne "subtypes") { + print STDERR "Warning: Mixed type in subckt $subckt"; + } + $types{$subckt}="subtypes"; + } + elsif (/^[a-z]/i) { + if (defined($types{$subckt}) and $types{$subckt} ne "netlist") { + print STDERR "Warning: Mixed type in subckt $subckt"; + } + $types{$subckt}="netlist"; + } + push @lines, $_; + } +} +if ($ln =~ /^\.ends/i) { + push @lines, $ln; + $lines{$subckt}=[@lines]; +} +close P; +foreach my $subckt (sort keys %subckts) { + my @f=@{$subckts{$subckt}}; + my $bus=""; + my @p=(); + my $min=0; + my $max=0; + foreach my $f (sort @f) { + next if $f eq $gnd_node or $f eq $vdd_node or defined $implied{$f}; + if ($f =~ /(.*)\[(\d+)]$/) { + my $b=$1; + my $c=$2; + if ($b ne $bus and $bus ne "") { + push @p, "$bus\[$min..$max\]"; + $min = $max = $c; + } + $bus = $b; + $max = $c if $c > $max; + $min = $c if $c < $min; + } + else { + if ($bus ne "") { + push @p, "$bus\[$min..$max\]"; + $min = $max = 0; + } + push @p, $f; + $bus=""; + } + } + if ($bus ne "") { + push @p, "$bus\[$min..$max\]"; + $min = $max = 0; + $bus = ""; + } + $subckts{$subckt}=[@p]; + my $seq=0; + foreach my $p (@p) { + if ($p =~ /(.*)\[(\d+)..(\d+)\]/) { + my $name=$1; + my $min=$2; + my $max=$3; + for (my $n = $min; $n <= $max; $n++) { + $place{"$subckt:$name\[$n\]"} = $seq++; + } + } + else { + $place{"$subckt:$p"} = $seq++; + } + } +} + +my $copyright= <) { + chomp; + if (/^define/ and ! /<: NULL/) { + my @f=split; + $type=$f[1]; + $type =~ s/\(.*//; + $type =~ s/"//g; + @lines=($_); + next; + } + if (@lines and /^\x7d/) { + push @lines, $_; + $existing{$type}=[@lines]; + @lines=(); + } + push @lines, $_ if (@lines); + } + close P; +} + +sub dop4 { + my ($file) = @_; + if (! -f "$file") { + `touch "$file"`; + } + if (defined ($change) and defined ($client) and -f "$file") { + my $cmd; + if ( -w "$file") { + $cmd = "p4 -c $client add -c $change '$file'"; + } + else { + $cmd = "p4 -c $client edit -c $change '$file'"; + } + print STDERR "$cmd"; + `$cmd`; + `chmod +w "$file"`; + $cmd = "p4 -c $client add -c $change '$file'"; + print STDERR "$cmd"; + `$cmd`; + } +} + +dop4("$castpath/$lname.cast"); +open (P, ">$castpath/$lname.cast") or die "$!"; +select P; +print "$copyright"; +print "module $library;"; +my $impliedlist=" "; +foreach my $node (sort keys %implied) { + $impliedlist .= "-$node, "; +} +$impliedlist =~ s/ $//; +$impliedlist = "" if $impliedlist eq " "; +print <$specpath/$subckt/$sub_type.cast" or die "$!"; + select P; + print $copyright; + print "module $library.$subckt;"; + printf "define \"$sub_type\"()( node"; + my $n = 0; + foreach my $p (@{$subckts{$subckt}}) { + printf "," if $n; + printf " -+$p"; + $n++; + } + if ($subckt eq $topcell) { + print " ) <: $library.$subckt {"; + } + else { + print " ) <: $library.$refinement_parent {"; + } + if ($types{$subckt} eq "netlist") { + print " netlist {"; + foreach my $line (@{$lines{$subckt}}) { + next if ($line =~ /^\.subckt/i) or ($line =~ /^\.ends/i); + if ($line =~ /^m/i) { + foreach my $nm (keys %devicetranslation) { + $line =~ s/ $nm / $devicetranslation{$nm} /; + } + my @f=split(/ /, $line); + for ($n = 0; $n < 5; $n++) { + $f[$n] =~ s/([A-Za-z0-9])-([A-Za-z0-9])/${1}_M_${2}/g; + } + for ($n = 5; $n <= $#f; $n++ ) { + $f[$n] =~ tr/A-Z/a-z/; + } + $line = join (" ", @f); + } + elsif ($line =~ /^d/i) { + foreach my $nm (keys %devicetranslation) { + $line =~ s/ $nm / $devicetranslation{$nm} /; + } + $line =~ s/area=//i; + my @f=split(/ /,$line); + for ($n = 0; $n < 3; $n++) { + $f[$n] =~ s/([A-Za-z0-9])-([A-Za-z0-9])/${1}_M_${2}/g; + } + $f[4] =~ tr/A-Z/a-z/; + $f[5] =~ tr/A-Z/a-z/; + $line="$f[0] $f[1] $f[2] $f[3] area=$f[4] $f[5]"; + } + elsif ($line =~ /^x/i) { + $line =~ s/([A-Za-z0-9])-([A-Za-z0-9])/${1}_M_${2}/g; + my @f=split(/ /, $line); + $f[$#f] = "$library.$f[$#f].$sub_type"; + $line = "@f"; + } + print " $line"; + } + } + else { + print " subcells {"; + # collect nodes + my %nodes=(); + my @nodes=(); + my %pins=(); + foreach my $p (@{$subckts{$subckt}}) { + $pins{$p}=1; + } + foreach my $line (@{$lines{$subckt}}) { + next if ($line =~ /^\.subckt/i) or ($line =~ /^\.ends/i); + my @f=split(/ /, $line); + for ( my $n = 1; $n < $#f; $n++) { + $nodes{$f[$n]}=1; + } + } + { + my $bus=""; + my $min=0; + my $max=0; + foreach my $f (sort keys %nodes) { + if ($f =~ /(.*)\[(\d+)]$/) { + my $b=$1; + my $c=$2; + if ($b ne $bus and $bus ne "") { + push @nodes, "$bus\[$min..$max\]"; + $min = $max = $c; + } + $bus = $b; + $max = $c if $c > $max; + $min = $c if $c < $min; + } + else { + if ($bus ne "") { + push @nodes, "$bus\[$min..$max\]"; + $min = $max = 0; + } + push @nodes, $f; + $bus=""; + } + } + if ($bus ne "") { + push @nodes, "$bus\[$min..$max\]"; + } + } + foreach my $node (@nodes) { + print " node $node;" + if (! defined $pins{$node}) and + ($node ne "$vdd_node") and ($node ne "$gnd_node") and ! defined ($implied{$node});; + } + foreach my $line (@{$lines{$subckt}}) { + next if ($line =~ /^\.subckt/i) or ($line =~ /^\.ends/i); + if ($line =~ /^x/i) { + my @f=split(/ /, $line); + my $ref=$f[$#f]; + $f[$#f] = "$library.$f[$#f].$sub_type"; + $line = "$f[$#f] $f[0]("; + shift @f; + pop @f; + my @p=(); + foreach my $n (0..$#f) { + my $p = $order{"$ref:$n"}; + if (! defined ($p)) { + print STDERR "Warning: Undefined order $ref:$n $f[$n] $p" + } + else { + if ($p ne "$gnd_node" and $p ne "$vdd_node" and ! $implied{$p}) { + my $seq = $place{"$ref:$p"}; + print STDERR "Warning: Undefined place $ref:$p" + if ! defined $seq; + $p[$seq]=$f[$n]; + } + } + } + $line .= join (", ", @p); + $line .= ");"; + } + print " $line"; + } + } + print " }"; + print "}\n"; + select STDOUT; + close P; +} + +# create the dfII files + +open (P, ">$topcell.bind"); +print P "$library.$topcell.$sub_type layout $topcell"; +close P; + +my $user=`whoami`; +chomp $user; +mkdir "/scratch/$user/"; +$tmpwd = `mktemp -d /scratch/$user/isr.XXXXXX`; +chomp $tmpwd; +`mkcdswd --target-dir="$tmpwd" --dfII-dir="$dfIIdir" --fulcrum-pdk-root="$pdkroot"`; + +my $pwd=`pwd`; +chomp $pwd; +open (C, ">>$tmpwd/cds.lib"); +my $cdslib=$library; +$cdslib =~ s/\./#2e/g; +print C "UNDEFINE $cdslib"; +print C "DEFINE $cdslib $pwd/$library"; +close C; +`/bin/rm -rf "$pwd/$library"`; +`mkdir -p "$pwd/$library"`; + + +my $rsf =" +streamInKeys = list(nil + 'runDir \"$tmpwd\" + 'inFile \"$gds\" + 'primaryCell \"$topcell\" + 'libName \"$library\" + 'techfileName \"$pdkroot/share/Fulcrum/stream/strmin.tech\" + 'scale 0.001000 + 'units \"micron\" + 'errFile \"$pwd/${topcell}_pipo.log\" + 'refLib nil + 'hierDepth 32 + 'maxVertices 1024 + 'checkPolygon nil + 'snapToGrid nil + 'arrayToSimMosaic t + 'caseSensitivity \"preserve\" + 'textCaseSensitivity \"preserve\" + 'zeroPathToLine \"lines\" + 'convertNode \"ignore\" + 'keepPcell nil + 'replaceBusBitChar nil + 'skipUndefinedLPP nil + 'ignoreBox nil + 'mergeUndefPurposToDrawing nil + 'reportPrecision nil + 'keepStreamCells nil + 'attachTechfileOfLib \"\" + 'runQuiet nil + 'noWriteExistCell nil + 'NOUnmappingLayerWarning nil + 'comprehensiveLog t + 'ignorePcellEvalFail nil + 'appendDB nil + 'genListHier nil + 'skipDbLocking nil + 'skipPcDbGen nil + 'cellMapTable \"$pwd/$topcell.bind\" + 'layerTable \"\" + 'textFontTable \"\" + 'restorePin 0 + 'propMapTable \"\" + 'propSeparator \",\" + 'userSkillFile \"\" + 'rodDir \"\" + 'refLibOrder \"\" +) +"; + +print STDERR "Streaming in $gds" if $verbose; +open (P, ">$topcell.rsf"); +print P $rsf; +close P; +chdir $tmpwd; +`pipo strmin "$pwd/$topcell.rsf"`; +open (T, "<$pdkroot/share/Fulcrum/dfII/cds.lib") or warn "Cannot open cds.lib"; +$_=; +my ($d,$techlib,$x)=split; +close T; +if ($techlib =~ /tsmc/) { + print STDERR "Attaching $techlib to local $library" if $verbose; + open (T, ">attach.il"); + print T "techBindTechFile(ddGetObj(\"$library\") \"$techlib\")"; + close T; + unlink "$pwd/$library/techfile.cds"; + `layout -nograph -replay attach.il`; +} +chdir $pwd; + +# check in the files +my $cmd="mkdir -p '$dfIIdir/$path'"; +`$cmd` if ! -d "$dfIIdir/$path"; +$cmd = "p4 -c $client edit -c $change '$dfIIdir/$path/...'"; +print STDERR "$cmd"; +`$cmd`; +$cmd = "/bin/cp -rp '$pwd/$library/'* '$dfIIdir/$path'"; +print STDERR "$cmd"; +`$cmd`; +$cmd = "find '$dfIIdir/$path/' -type f | xargs p4 -c $client add -c $change -f"; +print STDERR "$cmd"; +`$cmd`; +$cmd = "p4 -c $client revert -a -c $change '$dfIIdir/$path/...'"; +print STDERR "$cmd"; +`$cmd`; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/Lvbe.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/Lvbe.pm new file mode 100755 index 0000000000..4059fff68f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/Lvbe.pm @@ -0,0 +1,278 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# Verification back-end library +# +# The verification back-end library consists of routines shared among +# back-ends. Routine names and descriptions: +# +# Name Description +# +# get_tempdir Make a temporary directory which will be +# cleaned up +# when the program exits. Takes no arguments. +# get_workingdir Get the name of the working directory for this +# run. Takes no arguments. +# nvpairs_to_skill Get a skill expression which will encode the +# name-value pairs as setq's. 'Lv' is prepended +# to all names. + +package Lvbe; + +# +# Load front-end library +# + +use Lvfe; + +# +# Add a temporary file or directory to the deletion list +# + +sub add_file_to_deletion_list { + ($file) = @_; + + # + # Check that the file is in the 'tmp' directory + # + + $file =~ /\/tmp\/Lvbe/ or die "Invalid temporary file"; + + # + # Add the file to the deletion list + # + + push @deletion_list, $file; +} + + +# +# Make a new temporary directory, and return its full path +# + +# Uses package-local variable 'count' + +sub get_tempdir { + + # + # Set counter if necessary + # + + defined $count or $count = 0; + + # + # Find a count yielding an unused temporary filename + # + + $file = "/tmp/Lvbe.$$.$count"; + + while (-e $file) { + $count++; + $count != 0 or Lvfe::error ("No available temporary files"); + $file = "/tmp/Lvbe.$$.$count"; + } + + # + # Make a temporary directory with this filename + # + + `mkdir $file`; + + # + # Add the new temporary directory to the deletion list + # + + add_file_to_deletion_list ($file); + + # + # Return the new temporary directory name + # + + return $file; +} + +# +# Get the full path for a technology library +# + +sub get_techlibpath { + my ($library) = @_; + + # + # Use the value of CdsLib as a default value of TechLib + # + + if (!Lvfe::is_defined (Lvfe::get_nvpair ("TechLib"))) { + my $cdslib = Lvfe::get_nvpair ("CdsLib"); + Lvfe::add_nvpair ("TechLib", $cdslib, "set", "Default"); + } + + Lvfe::assert_defined ("TechLib"); + + my $techlib = Lvfe::get_nvpair ("TechLib"); + my @techlib_contents=`cat $techlib`; + my %libmap; + + foreach $line (@techlib_contents) { + $line =~ s/^DEFINE\s+// or next; + $line =~ /^(\S+)\s+(\S+)\/*$/ or next; + $libmap{$1} = $2; + } + + $path = $libmap{$library}; + + Lvfe::error "Can't find library $library" if !defined $path; + + return $path; +} + +# +# Get the full path for a library +# + +sub get_libpath { + my ($library) = @_; + + Lvfe::assert_defined ("CdsLib"); + + my $cdslib = Lvfe::get_nvpair ("CdsLib"); + my @cdslib_contents = `cat $cdslib`; + my %libmap; + + foreach $line (@cdslib_contents) { + $line =~ s/^DEFINE\s+// or next; + $line =~ /^(\S+)\s+(\S+)\/*$/ or next; + $libmap{$1} = $2; + } + + $path = $libmap{$library}; + + Lvfe::error "Can't find library $library" if !defined $path; + + return $path; +} + +# +# Get the working directory for this run +# + +sub get_workingdir { + + # + # Check 'WorkingDir' nvpair for directory definition + # + + my $wd = Lvfe::get_nvpair ("WorkingDir"); + + # + # Set up a default working directory if necessary + # + + if (!Lvfe::is_defined ($wd)) { + $wd = get_tempdir (); + Lvfe::header "SET UP DEFAULT WORKING DIRECTORY"; + Lvfe::add_nvpair ("WorkingDir", $wd, "set", "Default"); + } + + # + # Flag an error if a non-directory file conflicts + # + + !-e $wd or -d $wd or Lvfe::error "WorkingDir $wd name conflict"; + + # + # Make working directory if necessary + # + + -e $wd or `mkdir -p $wd`; + -e $wd or Lvfe::error "Cannot make WorkingDir $wd"; + + # + # Remove any trailing '/' from the directory name + # + + $wd =~ s/\/$//; + + # + # Flag an error if /tmp is used (XXX: stage one only). + # + + Lvfe::error "Cannot use files in /tmp for WorkingDir in stage one." + if $wd =~ "^/tmp"; + + return $wd; +} + +# +# Get the RC extraction for a layout cell +# + +sub get_extractfile { + + # + # Check 'ExtractFile' nvpair for file definition + # + + my $ef = Lvfe::get_nvpair ("ExtractFile"); + + # + # Arrange for extraction to occur if necessary + # + + if (!Lvfe::is_defined ($ef)) { + use LvbeAssura; + $wd = get_workingdir(); + LvbeAssura::extract(); + $ef = "$wd\/extract"; + Lvfe::add_nvpair ("ExtractFile", $ef, "set", "Extracted"); + } + + # + # Ensure that extract file exists + # + + -e $ef or Lvfe::error "Cannot find extract file $ef"; + + return $ef; +} + +# +# Return a skill expression which encodes name-value pairs +# + +# N.B. The 'value' of the nvpair is always a list, so it is usually appropriate +# to use expressions such as '(car LvFoo)' rather than just 'LvFoo'. + +sub nvpairs_to_skill { + + $expression = ""; + + @keys = Lvfe::get_names (); + + for $key (@keys) { + $expression .= "(setq Lv$key (list"; + @values = get_nvpairs ($key); + for $value (@values) { + $expression .= " \"$value\""; + } + $expression .= "))\n"; + } +} + +# +# Package finalization -- delete temporary files and directories +# + +END { + foreach $deletion_item (@deletion_list) { + `rm -rf $deletion_item`; + } +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAlwaysError.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAlwaysError.pm new file mode 100755 index 0000000000..e2d2b5d826 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAlwaysError.pm @@ -0,0 +1,24 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# Verification back-end LvbeAlwaysError +# +# This back-end always flags an error. No nvpairs are used by this back-end. +# Insert the following lines in a Perl file to invoke this back-end: +# +# use LvbeAlwaysError; +# LvbeAlwaysError::verify(); + +package LvbeAlwaysError; + +sub verify { + Lvfe::error ("This back-end always returns an error"); +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssura.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssura.pm new file mode 100755 index 0000000000..0407e5c56f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssura.pm @@ -0,0 +1,527 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# Verification back-end LvbeAssura +# and Assura Extraction Utility routine +# +# This back-end provides Assura verification and extraction. The following +# nvpairs are used by this back-end: +# +# Name Description +# +# AssuraSet Assura avParameters 'set' entries +# AssuraType Type of assura verification: Lvs or Drc +# AssuraRsfInclude Run-specific-file include file +# CastObject Cast object for top-level cell +# CdsLib Cadence library configuration file +# LayoutCell Top-level layout cell name to be checked +# LayoutLibrary Cadence library containing layout +# LayoutView Cadence layout view name for top-level cell +# GDS2File GDS2 layout +# OpenOK The string "true" if open connections are OK. +# RuleFile Extraction rule file +# BindingFile Binding rule file +# CompareFile Compare rule file +# RunName Run name +# SchematicFile CDL schematic file +# Technology Name of the Technology. +# TechLib Technology library configuration file + +# WorkingDir Working Directory +# +# AssuraRsfInclude, CastObject, RunName, and WorkingDir are optional. TechLib +# defaults to the value of CdsLib if it is not specified. OpenOK defaults to +# "false" if it is not specified, and only has an effect if AssuraType is +# "LVS". SchematicFile is not used when AssuraType is Drc. CdsLib, +# LayoutCell, LayoutLibrary, LayoutView, RuleFile, SchematicFile, and +# Technology may be defined implicitly by CastObject. AssuraType is +# not used for Assura extraction (XXX: but SchematicFile may be required). +# +# Insert the following lines in a Perl file to invoke verification: +# +# use LvbeAssura; +# LvbeAssura::verify(); +# +# Insert the following lines in a Perl file to invoke extraction: +# +# use LvbeAssura; +# LvbeAssura::extract(); +# +# Package variables +# +# $PackageName Package name (used internally +# $wd Working directory +# $rn Run name + +package LvbeAssura; + +# +# Package variables +# + +$PackageName = "Assura"; +$wd = ""; +$rn = ""; + +# +# Set up Assura run +# + +sub setup { + # + # Add defaults for optionally defined values + # + + Lvfe::header ("BACK-END DEFAULT NAME-VALUE PAIRS"); + + Lvfe::add_nvpair ("RunName", "ThisRun", "set", $PackageName); + Lvfe::add_nvpair ("AssuraRsfInclude", "", "set", $PackageName); + Lvfe::add_nvpair ("OpenOK", "false", "set", $PackageName); + + # + # Ensure required name-value pairs are defined + # + @LayoutFiles = Lvfe::get_nvpairs ("LayoutFile"); + $GDS2File = Lvfe::get_nvpair ("GDS2File"); + $OutFile = Lvfe::get_nvpair ("OutFile"); + + if( !Lvfe::is_defined(@LayoutFiles) ) { + Lvfe::assert_defined ("LayoutCell"); + if( !Lvfe::is_defined($GDS2File) ) { + Lvfe::assert_defined ("CdsLib"); + Lvfe::assert_defined ("LayoutLibrary"); + Lvfe::assert_defined ("LayoutView"); + Lvfe::assert_defined ("RunName"); + Lvfe::add_nvpair ("TechLib", + Lvfe::get_nvpair("CdsLib"), + "set", + $PackageName); + Lvfe::assert_defined ("TechLib"); + } + } + + # + # Set working directory package-local variable + # + + $wd = Lvbe::get_workingdir (); + + # + # Set run name package-local variable + # + + $rn = Lvfe::get_nvpair ("RunName"); + + # + # Start Assura RSF (run-specific file) with an optional inclusion + # + + $include = Lvfe::get_nvpair ("AssuraRsfInclude"); + if(Lvfe::is_defined($include) && -e $include && !-d $include ) { + `cat $include > $wd/$rn\.rsf`; + } + else { + `echo "" > $wd/$rn\.rsf`; + } + } + +sub verify { + # + # Set up Assura back-end + # + + setup(); + + Lvfe::assert_defined ("AssuraType"); + my $type = Lvfe::get_nvpair ("AssuraType"); + if( !( $type eq "Drc" || + $type eq "Lvs" || + $type eq "Nvn" ) ) { + Lvfe::error ("Unknown AssuraType (should be Lvs or Drc)"); + } + + # + # Add run-specific details to rsf file. + # + open RSF, ">>$wd/$rn\.rsf" or die "ERROR: can't append to $wd/$rn\.rsf\n"; + + print RSF "avParameters(\n"; + #input + if(Lvfe::is_defined($GDS2File) ) { #GDS2 + print RSF " ?inputLayout (\"GDS2\" \"" + . Lvfe::get_nvpair("GDS2File") + . "\" )\n"; + print RSF " ?cellName \"" . Lvfe::get_nvpair ("LayoutCell") . "\"\n"; + } elsif(!Lvfe::is_defined(@LayoutFiles)) { #layout + print RSF " ?inputLayout (\"df2\" \"" + . Lvfe::get_nvpair("LayoutLibrary") + . "\" )\n"; + print RSF " ?cellName \"" . Lvfe::get_nvpair ("LayoutCell") . "\"\n"; + print RSF " ?viewName \"" . Lvfe::get_nvpair ("LayoutView") . "\"\n"; + print RSF " ?cdslib \"" . Lvfe::get_nvpair ("CdsLib") . "\"\n"; + print RSF " ?techLib \"" . Lvfe::get_nvpair ("TechLib") . "\"\n"; + $technology = Lvfe::get_nvpair ("Technology"); + if (Lvfe::is_defined ($technology)) { + print RSF " ?technology \"" . "$technology" . "\"\n"; + } + } + if( $type eq "Drc" || + $type eq "Lvs" ) { + Lvfe::assert_file ("RuleFile"); + print RSF " ?rulesFile \"" . Lvfe::get_nvpair ("RuleFile") . "\"\n"; + } + if ($type eq "Drc") { + print RSF " ?saveByRule nil \n"; + } + else { + print RSF " ?saveByRule nil \n"; # used to be t. see bug 11104 + } + # causes Assura to ignore text not at top level, needed for Nevada Sizing + if( ( $type eq "Drc" ) and ( Lvfe::get_nvpair("RuleFile") =~ m:bias.rul$: ) ) { + print RSF " ?textPriOnly t \n"; + } + print RSF " ?runName \"" . Lvfe::get_nvpair ("RunName") . "\"\n"; + print RSF " ?workingDirectory \"" . Lvbe::get_workingdir() . "\"\n"; + + @sets = Lvfe::get_nvpairs("AssuraSet"); + if (@sets != 0) { + @fsets = map(Lvfe::enquote,@sets); + print RSF " ?set (@fsets )\n"; + } + print RSF " ?avrpt t\n"; + print RSF ")\n"; + + + my @layFilters=Lvfe::get_nvpairs("LayFilters"); + my @schFilters=Lvfe::get_nvpairs("SchFilters"); + $area = Lvfe::get_nvpair ("Area"); + if (Lvfe::is_defined ($area) && !($area eq "all") ) { + @area = split(",",$area); + print RSF "verifyArea( @area )\n"; + } + + my $compare = Lvfe::get_nvpair ("CompareFile" ); + if( ( $type eq "Lvs" || + $type eq "Nvn" ) && + defined $compare ) { + if ( Lvfe::is_defined($compare) ) { + Lvfe::assert_file ("CompareFile"); + open COMPARE, "$compare" or die "$0 Can't open $compare"; + while( ) { + print RSF $_; + } + } +# print RSF "joinableNet( )\n"; # would allow multi labels + print RSF "avCompareRules( \n"; + + print RSF "layout(\n"; + if (Lvfe::is_defined("IgnoreBulk") and + Lvfe::get_nvpair("IgnoreBulk") eq "1") { + print RSF " deleteCellPin(MOS \"B\")\n"; + } + if(Lvfe::is_defined(@LayoutFiles)) { + foreach my $arg (@LayoutFiles) { + my ($file,$type) = split(":",$arg); + $type = " cdl" if(!defined $type); + print RSF " netlist( $type \"$file\" )\n"; + } + } + print RSF ")\n"; + print RSF "schematic(\n"; + if (Lvfe::is_defined("IgnoreBulk") and + Lvfe::get_nvpair("IgnoreBulk") eq "1") { + print RSF " deleteCellPin(MOS \"B\")\n"; + } + foreach my $arg (Lvfe::get_nvpairs("SchematicFile")) { + my ($file,$type) = split(":",$arg); + $type = "cdl" if(!defined $type); + print RSF "netlist( $type \"$file\" )\n"; + } + foreach my $opt (@schFilters) { + my @f = split (/,/, $opt); + print RSF "filterOptions( "; + foreach my $f (@f) { + print RSF "\"$f\" "; + } + print RSF ")\n"; + } + print RSF ")\n"; + if (Lvfe::is_defined(@layFilters)) { + print RSF "layout(\n"; + foreach my $opt (@layFilters) { + my @f = split (/,/, $opt); + print RSF "filterOptions( "; + foreach my $f (@f) { + print RSF "\"$f\" "; + } + print RSF ")\n"; + } + print RSF ")\n"; + } +# print RSF "layout(\n filterOptions( \"I\" )\n)\n"; + $bindingFile = Lvfe::get_nvpair ("BindingFile"); + if (Lvfe::is_defined ($bindingFile)) { + print RSF "bindingFile(\"" . "$bindingFile" . "\")"; + } + print RSF " )\n"; + if (Lvfe::get_nvpair ("OpenOK") eq "true") { + print RSF "joinableNet( )\n"; + } + } + + #exclude signoff cells from cell flattening + if( $type eq "Drc" && ! $OutFile ) { + writeSignoffInclude(\*RSF); + } + + if ($type eq "Lvs") { + print RSF "avLVS()"; + } elsif ($type eq "Drc") { + print RSF "avDX()"; + } + + close RSF; + + # + # Record input to Assura + # + + Lvfe::file_with_header ("ASSURA RUN-SPECIFIC FILE", "rsf", + "$wd/$rn\.rsf"); + + # + # Run Assura + # + + my $cmd; + if ($type eq "Nvn") { + $cmd = "nvn"; + } else { + $cmd = "assura"; + } + my $assura = $ENV{ASSURA_SCRIPT} || "/p/rrc/tools/bin/assura_oa"; + my $restart = ""; + $restart = "-restart" if(Lvfe::get_nvpair("Restart")); + system("$assura $cmd $restart $wd/$rn\.rsf 2>$wd/$rn\.log > $wd/$rn\.log"); + + # + # Record output of Assura + # + Lvfe::file_with_header ("Run Log", "log", "$wd/$rn\.log"); + + # + # Record summary results + # + + if ($type eq "Lvs" || + $type eq "Nvn" ) { + # + # Ensure that cell matching detail file exists + # + + -e "$wd/$rn.cls" or Lvfe::error ("Could not find $wd/$rn\.cls"); + + # + # Search cell matching detail file for text indicating success + # + + $results = `cat $wd/$rn.cls`; + if ($results =~ /Schematic and Layout Match/) { + Lvfe::pass(); + } else { + Lvfe::fail(); + } + } elsif($type eq "Drc") { + # + # Ensure that DRC error coordinate file exists + # + + -e "$wd/$rn\.err" or Lvfe::error("Could not find $wd/$rn\.err"); + + # + # Check for DRC error coordinate entries + # + + $results = `cat $wd/$rn\.err`; + if ($results =~ /[a-z]/) { + Lvfe::fail(); + } else { + Lvfe::pass(); + } + } +} + + +sub writeSignoffInclude { + my ($RSF) = @_; + my @signoffs = Lvfe::get_nvpairs("SignOff"); + + return if(scalar @signoffs == 0 ); + + print $RSF "avParameters(\n"; + my %signOffCells = (); + foreach my $signoff (@signoffs) { + open SIGNOFF, "<$signoff" or die "Can't open $signoff for read"; + my $rule; + while( ) { + if( /^\s*\(\s*cell\s*\"(.*)\"\s*\)/ ) { + $signOffCells{$1} = 1; + } + } + close SIGNOFF; + print $RSF " ?exceptionFile \"$signoff\"\n"; + } + + if(scalar keys %signOffCells == 0 ) { + print $RSF ")\n"; + return; + } + + print $RSF " ?expandUniqueCells nil\n"; + print $RSF " ?expandCellToTop ( excludeCell( "; + foreach $signOffCell (keys %signOffCells) { + $signOffCell =~ s/\^/\?/g; + print $RSF "\"$signOffCell\" "; + } + print $RSF ") )\n"; + print $RSF " ?expandCellToParent ( excludeCell( "; + foreach $signOffCell (keys %signOffCells) { + $signOffCell =~ s/\^/\?/g; + print $RSF "\"$signOffCell\" "; + } + print $RSF ") ) )\n"; + + print $RSF "procedure( avFlattenCell( cellName width height numShapes numInsts )\n"; + print $RSF "prog( ()\n"; + foreach $flattenCellRegEx (Lvfe::get_nvpairs("FlattenCellRegEx")) { + print $RSF "when( rexMatchp( \"$flattenCellRegEx\" cellName ) return(t) )\n"; + } + foreach $signOffCell (keys %signOffCells) { + print $RSF "when( rexMatchp( \"$signOffCell\" cellName ) return() )\n"; + } + + printf $RSF "when( (width <= 1.0 && height <= 1.0 && numInsts == 0 ) t )\n"; + printf $RSF ") )\n"; +} + + +# +# Perform Assura extraction +# + +sub extract { + # + # Set up Assura back-end + # + + setup(); + + # + # Ensure that RuleFile exists + # + + Lvfe::assert_file ("RuleFile"); + + # + # Add run-specific details to rsf file. + # + + open RSF, ">>$wd/$rn\.rsf"; + + print RSF "avParameters(\n"; + print RSF " ?inputLayout (\"df2\" \"" + . Lvfe::get_nvpair("LayoutLibrary") + . "\" )\n"; + print RSF " ?cellName \"" . Lvfe::get_nvpair ("LayoutCell") . "\"\n"; + print RSF " ?viewName \"" . Lvfe::get_nvpair ("LayoutView") . "\"\n"; + print RSF " ?cdslib \"" . Lvfe::get_nvpair ("CdsLib") . "\"\n"; + print RSF " ?rulesFile \"" . Lvfe::get_nvpair ("RuleFile") . "\"\n"; + print RSF " ?runName \"" . Lvfe::get_nvpair ("RunName") . "\"\n"; + print RSF " ?workingDirectory \"" . Lvbe::get_workingdir() . "\"\n"; + + @sets = Lvfe::get_nvpairs("AssuraSet"); + if (@sets != 0) { + @fsets = map(Lvfe::enquote,@sets); + print RSF " ?set (@fsets )\n"; + } + + print RSF " ?avrpt t\n"; + + print RSF " ?techLib \"" . Lvfe::get_nvpair ("TechLib") . "\"\n"; + print RSF ")\n"; + + print RSF "rcxParameters(\n"; + print RSF " ?runName \"" . Lvfe::get_nvpair ("RunName") . "\"\n"; + print RSF " ?outputFormat \"spice\"\n"; + print RSF " ?output \"" . Lvbe::get_workingdir() . "/extract\"\n"; + + print RSF ")\n"; + + # + # Add extraction-specific details to rsf file. + # + + print RSF "avCompareRules( schematic( "; + foreach my $arg (Lvfe::get_nvpairs("SchematicFile")) { + my ($file,$type) = split(":",$arg); + $type = "cdl" if(!defined $type); + print RSF "netlist( $type \"$file\")\n"; + } + print RSF " ))\n"; + if (Lvfe::get_nvpair ("OpenOK") eq "true") { + print RSF "joinableNet( )\n"; + } + print RSF "avLVS()\n"; + print RSF "avRCX()\n"; + + close RSF; + + # + # Record input to Assura + # + + Lvfe::file_with_header ("ASSURA RUN-SPECIFIC FILE", "rsf", + "$wd/$rn\.rsf"); + + # + # Run Assura + # + + `assura $wd/$rn\.rsf 2>$wd/$rn\.log > $wd/$rn\.log`; + + # + # Record output of Assura + # + + Lvfe::file_with_header ("Run Log", "log", "$wd/$rn\.log"); + Lvfe::file_with_header ("Labels and text information", "erc", + "$wd/$rn\.erc"); + Lvfe::file_with_header("DRC error coordinates", "err", "$wd/$rn\.err"); + + Lvfe::file_with_header("Cell Match Status", "csm", + "$wd/$rn\.csm"); + Lvfe::file_with_header("LVS mismatches", "cls", "$wd/$rn\.cls"); + + # + # Ensure that cell matching detail file exists + # + + -e "$wd/$rn.cls" or Lvfe::error ("Could not find $wd/$rn\.cls"); + + # + # Search cell matching detail file for text indicating success + # + + $results = `cat $wd/$rn.cls`; + if (!($results =~ /Schematic and Layout Match/)) { + Lvfe::fail("Could not extract parasitics"); + } +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraDrc.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraDrc.pm new file mode 100755 index 0000000000..05bb890d26 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraDrc.pm @@ -0,0 +1,56 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# Verification back-end LvbeAssuraDrc +# +# This back-end performs Assura DRC verification by calling the Assura +# back-end with AssuraType=Drc. +# +# Insert the following lines in a Perl file to invoke this back-end: +# +# use LvbeAssuraDrc; +# LvbeAssuraDrc::verify(); + +package LvbeAssuraDrc; + +use Lvbe; +use LvbeAssura; + +# +# Package name (used internally) +# + +$PackageName = "AssuraDrc"; + +# +# Perform DRC verification +# + +sub verify { + # + # Print header for assignment to Assura variables + # + + Lvfe::header ("SET ASSURA VERIFICATION TYPE"); + + # + # Set AssuraType variable for DRC + # + + Lvfe::add_nvpair ("AssuraType", "Drc", "set", $PackageName); + + # + # Run Assura Verification Back-end + # + + LvbeAssura::verify(); + +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraLvs.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraLvs.pm new file mode 100755 index 0000000000..4454020b85 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraLvs.pm @@ -0,0 +1,56 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# Verification back-end LvbeAssuraLvs +# +# This back-end performs Assura LVS verification by calling the Assura +# back-end with AssuraType=Lvs. +# +# Insert the following lines in a Perl file to invoke this back-end: +# +# use LvbeAssuraLvs; +# LvbeAssuraLvs::verify(); + +package LvbeAssuraLvs; + +use Lvbe; +use LvbeAssura; + +# +# Package name (used internally) +# + +$PackageName = "AssuraLvs"; + +# +# Perform LVS verification +# + +sub verify { + # + # Print header for assignment to Assura variables + # + + Lvfe::header ("SET ASSURA VERIFICATION TYPE"); + + # + # Set AssuraType variable for LVS + # + + Lvfe::add_nvpair ("AssuraType", "Lvs", "set", $PackageName); + + # + # Run Assura Verification Back-end + # + + LvbeAssura::verify(); + +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraNvn.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraNvn.pm new file mode 100644 index 0000000000..0037f93df7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeAssuraNvn.pm @@ -0,0 +1,56 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/script/perl/ve/back-end/LvbeAssuraNvn.pm#2 $ +# $DateTime: 2002/04/16 16:04:07 $ +# $Author: chrisb $ + +# Verification back-end LvbeAssuraNvn +# +# This back-end performs Assura LVS verification by calling the Assura +# back-end with AssuraType=Nvn. +# +# Insert the following lines in a Perl file to invoke this back-end: +# +# use LvbeAssuraNvn; +# LvbeAssuraNvn::verify(); + +package LvbeAssuraNvn; + +use Lvbe; +use LvbeAssura; + +# +# Package name (used internally) +# + +$PackageName = "AssuraNvn"; + +# +# Perform LVS verification +# + +sub verify { + # + # Print header for assignment to Assura variables + # + + Lvfe::header ("SET ASSURA VERIFICATION TYPE"); + + # + # Set AssuraType variable for LVS + # + + Lvfe::add_nvpair ("AssuraType", "Nvn", "set", $PackageName); + + # + # Run Assura Verification Back-end + # + + LvbeAssura::verify(); + +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeDrc.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeDrc.pm new file mode 100755 index 0000000000..b9203d7545 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeDrc.pm @@ -0,0 +1,53 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# XXX: this back-end is not used for stage one. + +# Verification back-end LvbeDrc +# +# This back-end performs DRC verification. The nvpair used by this back-end +# is LVS tool independent. The following nvpair is used: +# +# Name Description +# +# CastObject Cast object for the top-level cell. +# +# Insert the following lines in a Perl file to invoke this back-end: +# +# use LvbeDrc; +# LvbeDrc::verify(); + +package LvbeDrc; + +use LvbeAssuraDrc; + +# +# Perform DRC verification +# + +sub verify { + + # XXX: Flag an error for stage one use. + + Lvfe::error("Use back-end AssuraDrc instead of Drc for stage one."); + + # + # Ensure that required name-value pairs are defined. + # + + Lvfe::assert_defined ("CastObject"); + + # + # Run Assura DRC verification + # + + LvbeAssuraDrc::verify(); +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeLvs.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeLvs.pm new file mode 100755 index 0000000000..e9958c831c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeLvs.pm @@ -0,0 +1,54 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# XXX: this back-end is not used for stage one. + +# Verification back-end LvbeLvs +# +# This back-end performs LVS verification. The nvpair used by this back-end +# is LVS tool independent. The following nvpair is used: +# +# Name Description +# +# CastObject Cast object for top-level cell +# OpenOK The string "true" if open connections are OK. +# +# Insert the following lines in a Perl file to invoke this back-end: +# +# use LvbeLvs; +# LvbeLvs::verify(); + +package LvbeLvs; + +use LvbeAssuraLvs; + +# +# Perform LVS verification +# + +sub verify { + + # XXX: Flag an error for stage one use. + + Lvfe::error("Use back-end AssuraLvs instead of Lvs for stage one."); + + # + # Ensure that required name-value pairs are defined. + # + + Lvfe::assert_defined ("CastObject"); + + # + # Run Assura LVS verification + # + + LvbeAssuraLvs::verify(); +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOff.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOff.pm new file mode 100644 index 0000000000..4fa521031e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOff.pm @@ -0,0 +1,214 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/script/perl/ve/back-end/LvbeSignOff.pm#2 $ +# $DateTime: 2002/04/16 16:04:07 $ +# $Author: chrisb $ + +# XXX: this back-end is not used for stage one. + +# Verification back-end LvbeSignOff +# +# This back-end filters a DRC .err file through a list of signoff files. +# An error is filtered if there is a signoff for the rule,cell such that the +# bounding box of the signoff is contained in the bounding box of the .err violation. +# The following nvpair is used: +# +# Name Description +# +# SignOff SignOff file +# ErrFile .err file +# OutFile .realerr file +# +# Insert the following lines in a Perl file to invoke this back-end: +# +# use LvbeSignOff; +# LvbeSignOff::verify(); + +use Lvfe; +package LvbeSignOff; + +# +# Perform SignOff verification +# + +sub verify { + &Lvfe::assert_defined("ErrFile"); + &Lvfe::assert_defined("OutFile"); + + my $errFile = Lvfe::get_nvpair("ErrFile"); + my $outFile = Lvfe::get_nvpair("OutFile"); + my @signoffFiles = Lvfe::get_nvpairs("SignOff"); + my $signed = parseSignOffs(@signoffFiles); + &filterErrFile($signed,$errFile,$outFile); +} + + +sub filterErrFile { + my ($signed,$errFile,$outFile) = @_; + my @signedSets = (); + my $rule; + my $cell; + my $shapes = 0; + my $errors = 0; + my $pass = 1; + + + open OUT, ">$outFile" or die "Can't open $outFile for write"; + open ERR, "<$errFile" or die "Can't open $errFile for read"; + + while ( ) { + my $line = $_; + if( /^Rule[^:]*:\s*(.*)/ ) { + $rule = $1; + } elsif( /^Cell Name : (.*)/ ) { + ($cell) = split(" ",$1); + $shapes = 0; + @signedSets = (); + while( my ($cellRegEx,$signedSet) = each(%{$signed->{$rule}})) { + if($cell =~ /$cellRegEx/ ) { + push @signedSets,$signedSet; + } + } + } elsif( /^Shape/ ) { + $shapes = 1; + } elsif( /^\s+[0-9]+\s+.\s+([0-9-\.]+)\s+([0-9-\.]+)\s+([0-9-\.]+)\s+([0-9-\.]+)/) { + if( $shapes==1 ) { + $errors = 1; + my @pt1 = ($1,$2); + my @pt2 = ($3,$4); + my @pts = (\@pt1,\@pt2); + my $box = pointsToBBox(\@pts); + my $printLine = 1; + foreach my $signedSet (@signedSets) { + if(&isABoxInBox($signedSet,$box)) { + $printLine = 0; + last; + } + } + if ($printLine) { + $pass = 0; + print OUT "$rule: $cell: @{$box}\n"; + } + } + } + } + if($pass) { + if($errors) { + print OUT "SIGNOFF\n"; + } + else { + print OUT "PASS\n"; + } + } + else { + print OUT "FAIL\n"; + } +} + +sub parseSignOffs { + my @signoffFiles = @_; + my %signed = (); + my @cells = (); + + foreach my $signfile (@signoffFiles) { + open SIGN, "<$signfile" or die "Can't open $signfile for read"; + my $rule; + while( ) { + if( /^\s*\(\s*cell\s*\"(.*)\"\s*\)/ ) { + my ($thisCell) = split(" ",$1); + push @cells, $thisCell; + } elsif( /^\s*\(\s*rule\s*\"(.*)\"\s*\)/ ) { + $rule = $1; + } elsif( /^\s*\(\s*contour\s*(.*)\s*\)/ ) { + my @points = map { &parsePoint($_) } split(" ",$1); + my $box = &pointsToBBox(\@points); + foreach $cell (@cells) { + push @{$signed{$rule}{$cell}}, $box; + } + @cells = (); + } + } + } + + foreach my $rule (keys %signed) { + foreach my $cell (keys %{$signed{$rule}}) { + @{$signed{$rule}{$cell}} = sort { &boxCmp($a,$b) } @{$signed{$rule}{$cell}}; + } + } + return \%signed; +} + +sub isABoxInBox { + my ($boxes,$boundBox) = @_; + my $low = &binary_search($boxes,$boundBox,\&boxCmp); + for(my $k=$low; $k < @$boxes; $k++ ) { + $box = $boxes->[$k]; + return 1 if( &boxInBox($box,$boundBox) ); + return 0 if( $box->[0] > $boundBox->[0]); + } + return 0; +} + +sub binary_search { + my ($array, $word, $cmp) = @_; + my ($low, $high) = ( 0, @$array - 1 ); + my $try; + while ( $low <= $high ) { # While the window is open + $try = int( ($low+$high)/2 ); # Try the middle element + $low = $try+1, next if &$cmp($array->[$try],$word) < 0; # Raise bottom + $high = $try-1, next if &$cmp($array->[$try],$word) > 0; # Lower top + return $try; + } + return $try; +} + +sub boxCmp { + ($a,$b) = @_; + for(my $k=0; $k<@$a; $k++) { + $cmp = ($a->[$k] <=> $b->[$k]); + return $cmp if ($cmp!=0); + } + return 0; +} + +sub boxInBox { + my($box1,$box2) = @_; + my $ret = 0; + if( $box1->[0] >= $box2->[0] && + $box1->[1] >= $box2->[1] && + $box1->[2] <= $box2->[2] && + $box1->[3] <= $box2->[3] ) { + $ret = 1; + } + return $ret +} + + +sub pointsToBBox { + my ($points) = @_; + my ($left,$right) = &minmax( map { $_->[0]; } @{$points} ); + my ($bottom,$top) = &minmax( map { $_->[1]; } @{$points} ); + my @ret = ($left,$bottom,$right,$top); + return \@ret; +} + +sub parsePoint { + my ($str) = @_; + my @pt = split(":",$str); + return \@pt; +} + +sub minmax { + my $min = pop(@_); + my $max = $min; + foreach $val (@_) { + if($val < $min) { $min = $val;} + if($val > $max) { $max = $val;} + } + return ($min,$max); +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOffInclude.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOffInclude.pm new file mode 100644 index 0000000000..dfc5117279 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/back-end/LvbeSignOffInclude.pm @@ -0,0 +1,38 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/script/perl/ve/back-end/LvbeAssuraDrc.pm#2 $ +# $DateTime: 2002/04/16 16:04:07 $ +# $Author: chrisb $ + +package LvbeSignOffInclude; + +use Lvbe; +use LvbeAssura; + +# +# Package name (used internally) +# + +$PackageName = "AssuraSignOffInclude"; + +sub verify { + # + # Run Assura Verification Back-end + # + + $wd = Lvbe::get_workingdir (); + $rn = Lvfe::get_nvpair ("RunName"); + + # + # Start Assura RSF (run-specific file) with an optional inclusion + # + + open RSF,">$wd/$rn\.rsf" or die "Can't write to $wd/$rn\.rsf"; + LvbeAssura::writeSignoffInclude(\*RSF); + close(RSF); +} + +# +# Perl 'require' requires that a module return a true value. +# + +1; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/Lvfe.pm b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/Lvfe.pm new file mode 100755 index 0000000000..5e4c057dbd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/Lvfe.pm @@ -0,0 +1,395 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# Verification front-end library +# +# The verification front-end library contains routines used by the executable +# 'vfe' and the various back-ends to communicate with the user and with each +# other. Shared routine names and descriptions: +# +# Name Description +# +# doc Print static informational message +# info Print informational message +# doc_header Print header for static information +# header Print informational header +# file Print a file +# file_with_header Print a file with an informational header +# error Exit with an error +# pass Pass a test +# fail Fail a test +# get_names Get an array of all names +# get_nvpairs Get an array of values associated with a name +# get_nvpair Get the first value associated with a name +# is_defined True if a value is defined +# assert_defined Ensure that a name has an associated definition +# assert_file Ensure that name represents a readable file +# add_nvpair Add a (name, value) pair (set or append) +# add_nvpair_string Add a (name, value) pair from a string +# stage_one_hacks A function to perform stage-one hacks +# +# More complete descriptions and subroutine parameters may be found with the +# corresponding subroutine definitions below. + +package Lvfe; + +# +# Separator for messages printed to standard output +# + +$Separator = "*" x 70; + +# +# Print arbitrary message with a given line prefix +# + +sub message { + my ($prefix, @message) = @_; + + # + # Handle the case for an empty message + # + + if (@message == 0) { + print "$prefix:\n"; + return; + } + + # + # Handle the case for a non-empty message + # + + foreach $message_element (@message) { + @calculated_lines = split /\n/, $message_element; + foreach $calculated_line (@calculated_lines) { + print "$prefix: $calculated_line\n"; + } + } +} + +# +# Print static informational message +# + +sub enquote { + $arg = $_; + return qq("$arg"); +} + +sub doc { + message ("Doc", @_); +} + +# +# Print informational message +# + +sub info { + message ("Info", @_); +} + +# +# Print header for static information +# + +sub doc_header { + doc $Separator; + doc @_; + doc $Separator; +} + +# +# Print informational header +# + +sub header { + info $Separator; + info @_; + info $Separator; +} + +# +# Print a file with a given line prefix and file name. Prefix will be +# prepended with a colon. +# + +sub file { + my ($prefix, $filename) = @_; + -r $filename or error ("Cannot read $filename"); + @file_contents = `cat $filename`; + message (":$prefix", @file_contents); +} + +# +# Print a file with given line prefix and file name. Prefix will be prepended +# with a colon. Also, print an informational header. +# + +sub file_with_header { + my ($header, $prefix, $filename) = @_; + header ("INCLUDED FILE: $header", + "FILENAME: $filename", "LINE PREFIX: $prefix"); + file ($prefix, $filename); +} + +# +# Exit with an error +# + +sub error { + message ("ERROR", @_); + exit 1; +} + +# +# Pass a test +# + +sub pass { + message ("PASS", @_); + exit 0; +} + +# +# Fail a test +# + +sub fail { + message ("FAIL", @_); + exit 2; +} + +# +# Get an array of all values corresponding to a name +# + +sub get_nvpairs { + my ($name) = @_; + + return () unless $value = $nvpair_value{$name}; + + return split /\|/, $value; +} + +# +# Get first value corresponding to a name +# + +sub get_nvpair { + my ($name) = @_; + @values = get_nvpairs ($name); + if (@values == 0) { + return ""; + } else { + return $values[0]; + } +} + +# +# Check whether a value is defined +# + +sub is_defined { + my ($value) = @_; + return 0 if (!defined $value || $value eq ""); + return 1; +} + +# +# Assert that a value is defined for a given name +# + +sub assert_defined { + my ($name) = @_; + error "'$name' is not defined!" if !is_defined (get_nvpair($name)); +} + +# +# Assert that a name represents a readable file (and not a directory) +# + +sub assert_files { + foreach $value (get_nvpairs($name)) { + error "'$name' is not defined" if !is_defined ($value); + check_file($value); + } +} + +sub assert_file { + my ($name) = @_; + my ($value) = get_nvpair ($name); + error "'$name' is not defined" if !is_defined ($value); + check_file($value); +} + +sub check_file { + my ($value) = @_; + error "File '$value' for '$name' doesn't exist" if !-e $value; + error "File '$value' for '$name' is a directory" if -d $value; + error "File '$value' for '$name' is not readable" if !-r $value; +} + +# +# Subroutine to print a (name, value) assignment event +# + +# TYPE is "set", "append", or "ignore". SOURCE indicates the source of the +# assignment. + +sub print_nvpair { + ($name, $value, $type, $source) = @_; + + if (defined $value && $value ne "") { + $printable_value = $value; + } else { + $printable_value = "''"; + } + + Lvfe::message ("Pair", "($source, $type, $name, $printable_value)"); +} + +# +# Subroutine to clear a (name, value) pair. +# + +# NAME indicates the name for the pair to be cleared. After clearing, no +# values will be associated with NAME. SOURCE describes the unit that is +# performing the clearing. + +sub clear_nvpair { + ($name, $source) = @_; + + undef $nvpair_set{$name}; + undef $nvpair_value{$name}; + + Lvfe::message ("Delp", "($name, $source)"); +} + +# +# Subroutine to add a (name, value) pair. +# + +# TYPE is "set" or "append", indicating whether additional pairs with the +# same name should be ignored or appended. NAME and VALUE form the (name, +# value) pair. Global variables used include Lvfe::nvpair_value, which stores +# the (name, value) pairs as a hash, and nvpair_set, which specifies whether +# additional pairs with the same name should be appended or ignored. + +sub add_nvpair { + ($name, $value, $type, $source) = @_; + + if ($nvpair_set{$name}) { + print_nvpair ($name, $value, "ignored", $source); + return; + } + + if (defined $Lvfe::nvpair_value{$name} && defined $value) { + $Lvfe::nvpair_value{$name} .= "|" . $value; + } elsif (defined $value) { + $Lvfe::nvpair_value{$name} = $value; + } + + if ($type eq "set") { + $nvpair_set{$name} = 1; + } elsif ($type ne "append") { + Lvfe::error "add_nvpair: invalid type $type."; + } + + print_nvpair ($name, $value, $type, $source); +} + +# +# Subroutine to add a (name, value) pair as specified by a string. +# + +# STRING should be "=", to specify that additional values for the +# same name should be ignored, or ".=", to specify that additional +# values for the same name should be appended. + +sub add_nvpair_string { + ($string, $source) = @_; + + if ($string =~ /([^=]+)\.=(.*)/) { + add_nvpair ($1, $2, "append", $source); + } elsif ($string =~ /([^=]+)=(.*)/) { + add_nvpair ($1, $2, "set", $source); + } else { + Lvfe::error "$source: Invalid pair $string"; + } +} + +# +# Subroutine to get all names +# + +sub get_names { + return keys %nvpair_value; +} + +# +# Subroutine to perform stage-one hacks +# + +# Define CastFile and CastCell from LayoutCell. + +sub stage_one_hacks { + + my $sig = "StageOneHacks"; + + doc ("To perform stage-one hacks, define StageOne=true and LayoutCell"); + + my $stage_one = get_nvpair ("StageOne"); + my $layout_cell = get_nvpair ("LayoutCell"); + my $cast_path = get_nvpair ("CastPath"); + my $cast_cell = get_nvpair ("CastCell"); + my $cast_file = get_nvpair ("CastFile"); + + if (is_defined ($stage_one) && is_defined ($layout_cell)) { + + info ("Performing stage-one hacks"); + + if (!is_defined ($cast_cell)) { + $cast_cell = $layout_cell; + $cast_cell =~ s/(.*)-//; + my $module = $1; + $cast_cell =~ s/##2d/\(/g; + $cast_cell =~ s/##2e/\)/g; + add_nvpair ("CastCell", $cast_cell, "set", $sig); + } + if (!is_defined ($cast_file)) { + + # + # Run Mike T's find_cell script + # + + chomp ($cast_file = + `find_cell $cast_cell 2> /dev/null`); + + # + # If more than one is found, then add a module + # specifier. (Note that this is _really_ a hack.) + # + + if ($cast_file =~ /\n/) { + chomp ($cast_file = + `find_cell $module\/$cast_cell 2> /dev/null`); + } + + if (!($cast_file =~ /\S/)) { + error ("Stage-one hack was unable to find the", + "value of CastFile through divination.", + "Specify CastFile manually."); + } + + # + # Keep only final module/file.cast text + # + + $cast_file =~ s/.*\/([^\/]+)\/([^\/]+)/$1\/$2/; + + add_nvpair ("CastFile", $cast_file, "set", $sig); + } + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/vfe b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/vfe new file mode 100755 index 0000000000..dce7a4f195 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/front-end/vfe @@ -0,0 +1,312 @@ +#!/usr/intel/bin/perl -w + +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# +# Verification Front End +# +# Usage: vfe ['NAME=VALUE' | 'NAME.=VALUE']* +# +# 'NAME.=VALUE', assignment in append mode, indicates that values of lower +# precedence for the same name (e.g. appearing later on the command line or as +# a built-in default) should be appended to this value to construct a list, +# whereas 'NAME=VALUE', assignment in set mode, indicates that values of lower +# precedence for the same name should be ignored. +# +# (name, value) pairs are read from the command line, environment variables, +# configuration files, cast, and built-in defaults. Precedence is as follows +# (first item has highest precedence): +# +# 1. Command line +# 2. Environment variables +# 3. Configuration files +# 4. Cast +# 5. Built-in defaults +# +# The verification front end performs the following series of steps: +# +# 1. Build data structures from built-in defaults and the command line. +# +# 2. Search the (name, value) pairs specified on the command line for the +# name 'VerificationEnv', which specifies the environment variable(s) used for +# configuration. If VerificationEnv is not specified on the command line, the +# default environment variable used is 'VFE_ENVIRONMENT', unless this +# environment variable is not defined, in which case no environment variable is +# used. It is possible to specify that no environment variable be used by +# setting VerificationEnv to the empty string. Each environment variable +# should contain a set of strings "NAME=VALUE" and "NAME.=VALUE" separated by +# the '+' character. +# +# 3. Search the (name, value) pairs specified on the command line and in +# environment variables for the name 'VerificationRc', which specifies the +# configuration file(s) used. If VerificationRc is not specified on the +# command line or in environment variables, the default configuration file +# used is the file .vferc in the directory specified by the environment +# variable 'HOME', unless the environment variable 'HOME' is not defined, or +# the file .vferc does not exist, in which case no configuration file is +# used. It is possible to specify that no configuration file be used by +# setting VerificationRc to the empty string. Each file should contain +# a set of strings "NAME=VALUE" and "NAME.=VALUE" separated by the newline +# character. Lines beginning with a '#' character are ignored. +# +# 4. Search the (name, value) pairs specified on the command line, in +# environment variables, and in the configuration file, for the names +# CastPath and CastExecutable, which specify the path to the Cast hierarchy +# and the filename of the executable which processes Cast. If no such (name, +# value) pairs are found, or if the specified hierarchy or executable is not +# found, an error is reported, and the program exits. If a value is specified +# with 'append', or if more than one value is specified for either name, an +# error is reported, and the program exits, since only one value can be used +# for each name. (Perhaps multiple values should be allowed, esp. for +# CastPath.) +# +# 5. Gather remaining (name, value) pairs according to precedence. Values +# specified in cast cause defaults to be ignored. (Effectively, only the +# 'NAME=VALUE' style assignments are allowed in cast, not the 'NAME.=VALUE'. +# Perhaps this should be changed to allow for 'NAME.=VALUE' as well.) +# +# 6. Select verification tool back-end based on the value of +# 'VerificationType'. (The default is AlwaysError, which always returns an +# error status.) +# +# 7. Load corresponding verification module. +# +# 8. Run corresponding verification routine, and collect results as a +# ternary (PASS, FAIL, ERROR) as well as a verbose log report. +# +# 9. Return ternary (PASS, FAIL, ERROR), the verbose log report from the +# module, and a report on the configuration used, including the sources of +# configuration variables. + +# +# Load front-end library +# + +use File::Basename; +use File::Spec; + +BEGIN { + my $self = File::Spec->rel2abs($0); + while ( -l $self ) { $self = readlink($self); } + push @INC, dirname($self) . "/../front-end"; + push @INC, dirname($self) . "/../back-end"; +} + +use Lvfe; + +# +# Load back-end library +# + +use Lvbe; + +# +# Display documentation +# + +Lvfe::doc_header "COMMAND LINE USAGE INFORMATION"; + +Lvfe::doc "Usage: $0 [= | .=]*"; +Lvfe::doc ""; +Lvfe::doc "'=' implies 'set' semantics, in which further assignments"; +Lvfe::doc "are ignored. '.=' implies 'append' semantics, in which"; +Lvfe::doc "further assignments are appended to create a list of values."; + +Lvfe::doc_header "ENVIRONMENT VARIABLE USAGE INFORMATION"; + +Lvfe::doc "Each environment variable specified should contain a string of"; +Lvfe::doc "pairs = or .=, for 'set' or 'append'"; +Lvfe::doc "semantics, respectively. The pairs should be separated by the"; +Lvfe::doc "'+' character. Environment variables are specified by values"; +Lvfe::doc "associated with the name 'VerificationEnv'."; + +Lvfe::doc_header "CONFIGURATION FILE USAGE INFORMATION"; + +Lvfe::doc "Each configuration file specified should contain a set of pairs"; +Lvfe::doc "= or .=, for 'set' or 'append'"; +Lvfe::doc "semantics, respectively. The pairs should be separated by the"; +Lvfe::doc "newline character. Configuration files are specified by values"; +Lvfe::doc "associated with the name 'VerificationRc'."; + +Lvfe::doc_header "PRECEDENCE"; + +Lvfe::doc "Precedence is as follows (highest to lowest):"; +Lvfe::doc "\t1. Command Line"; +Lvfe::doc "\t2. Environment Variables"; +Lvfe::doc "\t3. Configuration Files"; +Lvfe::doc "\t4. Cast"; +Lvfe::doc "\t5. Built-in Defaults"; + +Lvfe::doc_header "DOCUMENTATION"; + +Lvfe::doc "See source for further documentation"; + +# +# Emit header about checking built-in defaults +# + +Lvfe::header "CHECK BUILT-IN DEFAULTS"; + +# +# Set static values to be used as defaults +# + +%nvpair_defaults = ( + VerificationType => "AlwaysError" +); + +# +# Check for the existence of the default environment variable VFE_ENVIRONMENT +# + +# Set a default for (name, value) pair VerificationEnv if VFE_ENVIRONMENT +# is defined. + +if (defined $ENV{"VFE_ENVIRONMENT"}) { + $nvpair_defaults{"VerificationEnv"} = "VFE_ENVIRONMENT"; + Lvfe::info "Default environment variable VFE_ENVIRONMENT defined"; +} else { + Lvfe::info "Default environment variable VFE_ENVIRONMENT not defined"; +} + +# +# Check for the existence of the default configuration file $HOME/.vferc +# + +# Set a default for (name, value) pair VerificationRc if $HOME/.vferc +# exists. + +if (defined $ENV{"HOME"} && -e "$ENV{\"HOME\"}/.vferc") { + $nvpair_defaults{"VerificationRc"} = "$ENV{\"HOME\"}/.vferc"; + Lvfe::info "Default configuration file $ENV{\"HOME\"}/.vferc exists"; +} elsif (defined $ENV{"HOME"}) { + Lvfe::info "Default configuration file " + . "$ENV{\"HOME\"}/.vferc does not exist"; +} else { + Lvfe::info "No default configuration file, since \$HOME is undefined."; +} + +# +# Emit header about collecting name-value pairs +# + +Lvfe::header "COLLECT NAME-VALUE PAIRS ('' denotes an undefined value)"; + +# +# Collect name-value pairs from the command line +# + +foreach $nvpair (@ARGV) { + Lvfe::add_nvpair_string ($nvpair, "Command line"); +} + +# +# Add a default value for VerificationEnv to any command-line values +# + +# If the default environment variable is not defined, VerificationEnv will +# be set to a value which is considered to be undefined by the pair-processing +# routines in the front-end library. + +Lvfe::add_nvpair ("VerificationEnv", $nvpair_defaults{"VerificationEnv"}, "set", + "Default"); + +# +# Read (name, value) pairs from the environment variables specified +# + +@VConfEnvs = Lvfe::get_nvpairs ("VerificationEnv"); +foreach $VConfEnv (@VConfEnvs) { + next if $VConfEnv eq ""; + if (!defined $ENV{$VConfEnv}) { + Lvfe::error "Environment variable $VConfEnv is not defined"; + } + @VConfPairs = split /\+/, $ENV{$VConfEnv}; + + foreach $VConfPair (@VConfPairs) { + Lvfe::add_nvpair_string ($VConfPair, + "Environment Var. '$VConfEnv'"); + } +} + +# +# Add default value for VerificationRc +# + +# If the default configuration file does not exist, VerificationRc will +# be set to a value which is considered to be undefined by the pair-processing +# routines in the front-end library. + +Lvfe::add_nvpair ("VerificationRc", $nvpair_defaults{"VerificationRc"}, "set", + "Default"); + +# +# Read (name, value) pairs from the configuration files specified +# + +@VConfFiles = Lvfe::get_nvpairs ("VerificationRc"); +foreach $VConfFile (@VConfFiles) { + next if $VConfFile eq ""; + -e $VConfFile + or Lvfe::error "Configuration file $VConfFile does not exist"; + @VConfPairs = split /\n/, `cat $VConfFile`; + + foreach $VConfPair (@VConfPairs) { + next if $VConfPair =~ /^#/; + next if $VConfPair =~ /^\s*$/; + Lvfe::add_nvpair_string ($VConfPair, "File '$VConfFile'"); + } +} + +# +# Add default values for CastPath and CastExecutable +# + +Lvfe::add_nvpair ("CastPath", $nvpair_defaults{"CastPath"}, "set", "Default"); +Lvfe::add_nvpair ("CastExecutable", $nvpair_defaults{"CastExecutable"}, "set", + "Default"); + +# +# XXX: Read (name, value) pairs from cast configuration +# + +# +# Add default value for VerificationType +# + +Lvfe::add_nvpair ("VerificationType", $nvpair_defaults{"VerificationType"}, + "set", + "Default"); + +# +# Run stage-one hacks (XXX: stage one only) +# + +Lvfe::stage_one_hacks(); + +# +# Find the appropriate back end +# + + +$VBE_noprefix = Lvfe::get_nvpair ("VerificationType"); +$VBE = "Lvbe" . $VBE_noprefix; + + + Lvfe::header "RUN BACK-END"; + Lvfe::info "Using perl module mechanism to load back-end '${VBE_noprefix}' ..."; +eval { require "${VBE}.pm"; }; + Lvfe::error "Could not load back-end '${VBE_noprefix}'.\n$@" if $@; + Lvfe::info "Back-end loaded ..."; + +# +# Run back-end verification routine +# + Lvfe::info "Running verification ..."; +eval { &{"${VBE}::verify"} (); }; + Lvfe::info "Done."; + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/ve.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/ve.package new file mode 100644 index 0000000000..233cbecb1f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/ve/ve.package @@ -0,0 +1,21 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +< \$top, + "external=s" => \$externalfile, + "debug" => \$debug, + "portmap=s" => \$portmap, + "output=s" => \$outputfile, + "verbose" => \$verbose, + "progress" => \$progress, + "flat" => \$flat, +); + +sub usage { + print STDERR "@_" if @_; + print STDERR < [options] + --external= : read file to define external cells with arrays + --debug : generate lots of debug data + --verbose : generate less debug data + --portmap : renames ports, but should not use here + --output= : output instead of stdout. (may not work right.) + --flat : make a flat spice file +EU + exit 1; +} + +select STDERR; +$|=1; +select STDOUT; +$|=1; +GetOptions ( %opts ) or usage; +usage if ! defined $ARGV[0]; +$verbose=1 if $debug; +$progress=1 if $verbose; +usage("No top module defined") if $top eq "" and $flat; +if ($outputfile eq "") { + if ($top ne "") { + $outputfile = $top; + } + else { + $outputfile = $ARGV[0]; + $outputfile =~ s/\.v[^\.]*$//; + } + $outputfile .= ".sp"; +} +if ($outputfile ne "-" and $outputfile ne "") { + if (open (OUT, ">$outputfile")) { + select OUT; + $|=1; + } + else { + print STDERR "Cannot open $outputfile"; + } +} +my $iofile = $outputfile; +$iofile =~ s/\.[^\.]*$//; +$iofile .= ".ports"; +open(IO, ">$iofile"); + +my %ver=(); +my %cast=(); + +sub readportmap { + my ($file) = @_; + local (*P,$_); + return if ! -r "$file"; + open (P, "<$file") or warn "Cannot open $file: $!"; + print STDERR "Reading $file" if $progress; + while (

    ) { + chomp; + my ($ver,$cast)=split; + $ver{$cast}=$ver; + $cast{$ver}=$cast; + } +} + + +$debugfile = "vs2calibre.dbg" if $debug; +open (DBG, ">$debugfile"); + +readportmap ($portmap); + +# not in the verilog, but necessary +my %specialcases = ( + "QCSMS1_DS_13T" => ["VDD10=vdd","VSS10=GND"], + "QCSMS1_MUX_13T" => ["VDD10=vddA","VSS10=GND"], +); + +my $wraplimit = 4096; +#$wraplimit = 8192; # no wrap + +sub wrap { + my ($str) = @_; + my $orig=$str; + if ($wraplimit > 2000) { + print "$str"; + return; + } + my $b = 0; + while (length ($str) > $wraplimit) { + my $e = rindex($str," ",$wraplimit); + $e = index($str," ") if ($e < 0); + $e = length($str) if ($e < 0); + my $s1 = substr($str, 0, $e); + printf "+ " if $b; + print $s1; + if (length($str) < $e+1) { + $str=""; + } + else { + $str = substr($str,$e+1); + } + $b = 2; + } + if (length($str) > 0) { + printf "+ " if $b; + print $str; + } +} +my %pins=(); +my %type=(); +my %ports=(); +my %portmap=(); +my %hasarray=(); +my @ports=(); +my %porttypes=(); +my %wiretypes=(); +my %wires=(); +my %localnodes=(); +my %module=(); +my %modules=(); # just those in the file + +# whole files goes into memory for ease of handling 'c' comments +sub readfile { + my ($file) = @_; + printf STDERR "Reading $file..." if $progress; + local(*P, $_, $/); + undef $/; + open (P, "<$file") or die "Cannot open $file $!"; + my $text =

    ; + close P; + $text =~ s/;/;\n/g; + $text =~ s/\t/ /g; + $text =~ s/ */ /g; + $text =~ s/^ *//; + $text =~ s/\n */\n/g; + $text =~ s/\\//g; + # initial lines with comments + while ($text =~ m:^//:) { + $text =~ s:^//[^\n]*\n::; + } + $text =~ s/^ *//; + # other 'rest of line' comments + while (index ($text, "//") > 0) { + $text =~ s: *//[^\n]*\n:\n:g; + $text =~ s/\n\n/\n/g; + } + # remove blank lines + while ($text =~ /\n\n/) { + $text =~ s/\n\n/\n/g; + } + # remove 'c' type comments + my $i1; + my $i2; + my $t; + while (($i1 = index($text, "/*")) >= 0) { + $i2 = index(substr($text,$i1),"*/"); + $t = substr($text,0,$i1).substr($text,$i1+$i2+2); + $text=$t; + } + print STDERR "Done" if $progress; + # make into an array of lines + split(/\n/,$text); +} + +sub parse { + my ($file, $external) = @_; + my @lines = readfile ($file); + printf STDERR "Parsing $file..." if $progress; + my $lnr = 0; + local ($_); + my $module = ""; + %localnodes=(); + my @ln = (); + my %plookup=(); + my @plookup=(); + my @wlookup=(); + my @wires=(); + my $hasarray=0; + while ($lnr <= $#lines) { + $_=$lines[$lnr++]; + # skip blank lines + next if (/^[ \t]*$/); + # module definition until terminating ; + if (/^module/) { + my @f = split; + $module = $f[1]; + print IO "MODULE $module"; + $modules{$module}=1; + print DBG "Module $f[1]"; + my $ln = $_; + while (! ($ln =~ /;/) and $lnr <= $#lines) { + $_ = $lines[$lnr++]; + $ln .= " $_"; + } + $ln =~ s/^[^\(]*\(//; + $ln =~ s/,/ /g; + $ln =~ s/ */ /g; + $ln =~ s/^ //; + $ln =~ s/ $//; + $ln =~ s/ *;.*//; + $ln =~ s/\)[^\)]*$//; + undef @ports; + @ports = split(/ /,$ln); + $ports{$module}=[@ports]; + $hasarray=0; + foreach my $n (0..$#ports) { + $portmap{$module}->{port}{$ports[$n]}=$n; + print DBG "HA1 $module $ports[$n]"; + $hasarray = 1 if ($ports[$n] =~ /\[/); + } + $hasarray{$module}=$hasarray; + undef %plookup; + %plookup=(); + foreach my $n (0..$#ports) { + $plookup{$ports[$n]}=$n; + } + undef @ln; + @wires=(); + @wlookup=(); + @ln=(); + } + # port declarations + elsif (/^output/ or /^input/ or /^inout/) { + my $ln = $_; + while (! (/;/) and $lnr <= $#lines) { + $_ = $lines[$lnr++]; + $ln .= $_; + } + $_ = $ln; + s/ */ /g; + my ($io,$aref,$rest) = split (/ /,$_,3); + if (! defined ($rest)) { + $rest = $aref; + $aref = ""; + } + elsif (! ($aref =~ /\[/ ) or ! ($aref =~ /:/)) { + $rest = "$aref $rest"; + $aref = ""; + } + $rest =~ s/\t/ /g; + $rest =~ s/ *;.*//; + $rest =~ s/,/ /g; + $rest =~ s/ */ /g; + $rest =~ s/ $//; + $hasarray{$module}=1 if $aref =~ /\[/; + foreach my $port (split (/ /,$rest)) { + print IO "$io $port"; + if (defined $plookup{$port}) { + $plookup[$plookup{$port}] = $aref; + } + else { + print STDERR "Undefined ref :$port: at $." if $port ne ""; + } + } + } + # finish up module + elsif (/^endmodule/) { + print DBG "ENDMODULE $module $lnr"; + foreach my $n (0..$#ports) { + print STDERR "Undefined type for $module $ports[$n] in $file" + if ! defined $plookup[$n]; + } + $porttypes{$module} = [@plookup]; + $wiretypes{$module} = [@wlookup]; + $wires{$module} = [@wires]; + foreach my $n (0..$#wires) { + $portmap{$module}->{wire}{$wires[$n]}=$n; + } + $localnodes{$module} = [@ln]; + $external{$module}=1 if $external; + @ln = (); + @plookup = (); + $module=""; + } + # local declarations, not necessarily all local nodes! + elsif (/^wire/) { + my $ln = $_; + while (! (/;/) and $lnr <= $#lines) { + $_ = $lines[$lnr++]; + $ln .= " $_"; + $_ = $ln; + } + s/,/ /g; + s/ */ /g; + s/ *; *$//; + my @l = split; + shift @l; + push @ln, @l; + s/ */ /g; + my ($io,$aref,$rest) = split (/ /,$_,3); + if (! defined ($rest)) { + $rest = $aref; + $aref = ""; + } + elsif (! ($aref =~ /\[/ ) ) { + $rest = "$aref $rest"; + $aref = ""; + } + $rest =~ s/\t/ /g; + $rest =~ s/ *;.*//; + $rest =~ s/,/ /g; + $rest =~ s/ */ /g; + $rest =~ s/ $//; + foreach my $port (split (/ /,$rest)) { + push @wires, $port; + push @wlookup, $aref; + } + } + # assigns + elsif (/^assign/) { + } + # assumes the rest is a list of instances, no logic + else { + my $ln = $_; + while (! (/;/) and $lnr <= $#lines) { + $_ = $lines[$lnr++]; + $ln .= $_; + } + $_ = $ln; + s/ */ /g; + s/^ //; + s/ $//; + next if length($_) == 0; + my ($type,$inst,$list)=split(/ /,$_,3); + if ($inst =~ /\(/) { + s/([^ ])\(/ (/; + my $l=$1; + ($type,$inst,$list)=split(/ /,$_,3); + $inst = $inst.$l; + } + $_ = $list; + print DBG "L1 $type $inst $_"; + s/^ *\( *//; + s/ *\) *; *$//; + s/ *\)/)/g; + s/\( */(/g; + print DBG "L2 $type $inst $_"; + my $x = $_; + my @p=(); + my $orig=$_; + while (length($_)) { + my $pin = $_; + $pin =~ s/\(.*//; + $pin =~ s/^\.//; + print DBG "L3 $inst $pin : $_"; + print DBG "$pin : $_"; + $_ = substr($_,length($pin)+1); + $pin =~ s/ //g; + if (substr($_,0,1) ne "(") { + print STDERR "Warning: $type $inst $x =>"; + print STDERR "Syntax pin $pin $_ $ln"; + exit 1; + } + my $l = 1; + my $net = ""; + $_ = substr($_,1); + while ($l >= 1 or (substr($_,0,1) ne ")" and length($_))) { + if ($l == 1 and substr($_,0,1) eq ")") { + $net = ""; + if (length($_) == 1) { + $_=""; + } + else { + $_=substr($_,1); + } + last; + } + $net .= substr ($_,0,1); + $_ = substr($_,1); + $l++ if (substr($_,0,1) eq "("); + $l-- if (substr($_,0,1) eq ")"); + } + while (substr($_,0,1) ne "," and length($_)) { + $_ = substr($_,1); + } + if (length($_)>0) { + $_ = substr($_,1); + } + else { + $_ = ""; + } + while (substr ($_,0,1) eq " ") { + $_ = substr($_,1); + } + $net =~ s/, */, /g; + $net =~ s/ *$//; + print DBG "L4 $inst:$pin:$net"; + if (length ($net) ) { + push @p,"$pin=$net"; + print DBG "P $module:$inst $#p $pin=$net"; + } + } + print DBG "PX2 $module:$inst $#p $type : ",join(";",@p); + $pins{"$module:$inst"} = [@p]; + $type{"$module:$inst"} = $type; + } + } + print STDERR "Done" if $progress; +} + +# get externals to define ports of sIPCell, for example +# cells without definitions are assumed single ports +parse ("$externalfile", 1) if -r $externalfile; +foreach my $file (@ARGV) { + parse ($file, 0); +} +# find which cells are 'leaf' cells and make module lookup +my %leaf = (); +foreach my $k (sort keys %type) { + my ($module,$inst)=split(/:/,$k); + push @{$module{$module}},$inst; + if ($external{$type{$k}} or ! defined ($ports{$type{$k}})) { + $leaf{$k}=1; + $leaf{$type{$k}}=1; + } +} +printf STDERR "Expanding...\n" if $progress; +# now expand all of the ports to make it easier later +foreach my $k (keys %pins) { + my ($module,$inst)=split(/:/,$k); + my $type = $type{$k}; + printf DBG "Expanding $module $inst $type\n"; + my $t0 = [gettimeofday] if $profile; + my @iv=(); + my @wh=(); + my @p=(); + my $ivlast=0; + foreach my $pd (@{$pins{$k}}) { + my ($port,$signal)=split(/=/,$pd); + print DBG "EX1 $inst $port $signal"; + my $t1=time; +# print DBG " $module $inst $pd $type"; + if ((! defined ($hasarray{$type}) or ! $hasarray{$type})) { + print DBG "EX2 $inst $pd"; + if ($profile) { + my $iv = tv_interval($t0,[gettimeofday])*1.e6 - $ivlast; + printf DBG "PET %.0f noexpand $pd\n", $iv - $ivlast; + $ivlast = $iv; + } + push @p, $pd; + } + else { + print DBG "EX3 $inst $port"; + my @port = expandport($type, $port); + if ($profile) { + my $iv = tv_interval($t0,[gettimeofday])*1.e6 - $ivlast; + printf DBG "PET %.0f expandport1 $pd\n", $iv - $ivlast; + $ivlast = $iv; + } + my @s1 = arrayify ($signal); + if ($profile) { + my $iv = tv_interval($t0,[gettimeofday])*1.e6 - $ivlast; + printf DBG "PET %.0f arrayify $pd\n", $iv - $ivlast; + $ivlast = $iv; + } + my @signal=(); + foreach my $s1 (@s1) { + my $ta = [gettimeofday] if $profile; + my @x = expandport($module,$s1); + printf DBG "PE2 %.0f $s1 $module\n", + tv_interval($ta,[gettimeofday])*1.e6 if $profile; + $x[0] = $s1 if ($#x == -1); + push @signal, @x; + } + if ($profile) { + my $iv = tv_interval($t0,[gettimeofday])*1.e6 - $ivlast; + printf DBG "PET %.0f expandport2 $pd\n", $iv - $ivlast; + $ivlast = $iv; + } + if ($#signal != $#port) { + print STDERR "Error: $#signal $#s1 $#port $module $inst $type $pd"; + print STDERR " @signal"; + print STDERR " @port"; + exit 1; + } + foreach my $n (0..$#port) { + print DBG "EX4 $inst $port[$n]=$signal[$n]"; + push @p, "$port[$n]=$signal[$n]"; + } + } + if ($profile) { + my $iv = tv_interval($t0,[gettimeofday])*1.e6 - $ivlast; + printf DBG "PET %.0f pushport $pd\n", $iv - $ivlast; + $ivlast = $iv; + } + my $t2=time-$t1; + print DBG "EPT $t2 $inst $pd"; + } + if ($profile) { + my $iv = tv_interval($t0,[gettimeofday])*1.e6 - $ivlast; + printf DBG "PET %.0f end1\n", $iv - $ivlast; + $ivlast = $iv; + } + # replace old list with new list + $pins{$k}=[sort @p]; + if ($profile) { + my $iv = tv_interval($t0,[gettimeofday])*1.e6 - $ivlast; + printf DBG "PET %.0f end2\n", $iv - $ivlast; + $ivlast = $iv; + } +} +my @expandedports=(); + +print STDERR "Done expanding" if $progress; + +my @stack=(); + +sub writespfile { + $|=1; + @stack=(); + print STDERR "Writing! $top" if $progress; + @expandedports = expandports ($top); + foreach my $n (0..$#expandedports) { + if (defined ($cast{$expandedports[$n]})) { + $expandedports[$n] = $cast{$expandedports[$n]}; + } + } + wrap ".SUBCKT $top @expandedports"; + my @stack = (); + printinst ($top, "", ()); + print ".ENDS\n"; + 0; +} + +if ($flat) { + writespfile(); +} +else { + foreach my $module (sort keys %modules) { + $top = $module; + writespfile() if ! $external{$top}; + } +} +print STDERR "Done!" if $progress; +0; + +# function expands an array into it's components +sub expandf { + my ($name,$s,$e) = @_; + my $t1 = time; + my @epl; + my $t0 = [gettimeofday]; + if (defined ($s) and $e =~ /^\d+$/) { + if ($s >= $e) { + for (my $p = $s; $p >= $e; $p--) { + push @epl, "$name\[$p]"; + } + } + else { + for (my $p = $s; $p <= $e; $p++) { + push @epl, "$name\[$p]"; + } + } + printf DBG "EF1 $name $s $e $#epl %.0f\n", 1e6*tv_interval( $t0, [gettimeofday]); + } + else { + $epl[0] = $name; + printf DBG "EF0 $name - - $#epl %.0f\n", 1e6*tv_interval( $t0, [gettimeofday]); + } + my $t2 = time - $t1; + $s = "" if ! defined $s; + $e = "" if ! defined $e; + print DBG "EXFT $t2 $name:$s:$e"; + @epl; +} + +# expand a port into it's comps by name e.g. abC[16:0] -> abC[16],abC[15]... +sub expand { + my ($name)=@_; + $name =~ s/\[(\d+):(\d+)\]//; + my @epl = expandf($name,$1,$2); + @epl; +} + +# take list with {..} and make into a node list +sub arrayify { + my ($s) = @_; + my @arr=(); + if ($s =~ /^{/) { # } + my @s; + $s =~ s/{ *//; + $s =~ s/}$//; + $s =~ s/, / /g; + $s =~ s/ */ /g; + $s =~ s/^ //; + $s =~ s/ $//; + @s = split (/ /,$s); + foreach my $s (@s) { + push @arr, expand($s); + } + } + else { + $arr[0] = $s; + } + @arr; +} + +# expands a specific port. Requires the module to get the order and range +# correctly extracted +sub expandport { + my ($top,$name) = @_; + my $t1=[gettimeofday]; + my @epl = (); + print DBG "DY $top $name"; + if (! defined ($ports{$top})) { + print DBG "DX No ports for $top"; + push @epl,$name; + printf DBG "EP1 $top $name %.0f\n", tv_interval( $t1, [gettimeofday])*1e6; + return @epl; + } + if ($name =~ /\[\d+\]$/) { + push @epl, $name; + printf DBG "EP2 $top $name %.0f\n", tv_interval( $t1, [gettimeofday])*1e6; + return @epl; + } + if ($name =~ /\[(\d+):(\d+)\]$/) { + @epl=expand($name); + printf DBG "EP3 $top $name %.0f\n", tv_interval( $t1, [gettimeofday])*1e6; + return @epl; + } + printf DBG "DY2 $#ports $top %.0f\n", tv_interval( $t1, [gettimeofday])*1e6; + my $n = 4; + if (defined $portmap{$top}->{port}{$name}) { + my $n = $portmap{$top}->{port}{$name}; + my $porttype = ${@{$porttypes{$top}}}[$n]; + if ($porttype =~ /\[/) { + $porttype =~ m.\[(\d+):(\d+)\].; + push @epl, expandf ($name,$1,$2); + } + else { + push @epl, "$name"; + } + } + printf DBG "DY3 $#ports $top %.0f\n", tv_interval( $t1, [gettimeofday])*1e6; + if (! @epl) { + if (defined $portmap{$top}->{wire}{$name}) { + my $n = $portmap{$top}->{wire}{$name}; + my $porttype=${@{$wiretypes{$top}}}[$n]; + if ($porttype =~ /\[/) { + $porttype =~ m.\[(\d+):(\d+)\].; + push @epl, expandf ($name,$1,$2); + } + else { + push @epl, "$name"; + } + } + } + printf DBG "DY4 $#ports $top %.0f\n", tv_interval( $t1, [gettimeofday])*1e6; + push @epl, $name if ! @epl; + print DBG "DY5 $top $#epl $name @epl"; + printf DBG "EP$n $top $name %.0f ($#ports $#epl) @epl\n", tv_interval( $t1, [gettimeofday])*1e6; + @epl; +} + +# list of all ports expanded into wires for a module +sub expandports { + my ($top) = @_; + print DBG "DYS:$top:"; + my $t1 = time; + my @epl = (); + my @ports = (); + my @porttypes = (); + if ( defined $ports{$top} and defined $porttypes{$top}) { + @ports = @{$ports{$top}}; + @porttypes = @{$porttypes{$top}}; + } + else { + print DBG "DYSE : no ports for $top"; + print STDERR "Error: No ports for $top in expandports"; + } + foreach my $n (0..$#ports) { + if ($porttypes[$n] =~ /\[/) { + $porttypes[$n] =~ m.\[(\d+):(\d+)\].; + push @epl, expandf ($ports[$n],$1,$2); + } + else { + push @epl, "$ports[$n]"; + } + } + my $t2=time-$t1; + print DBG "DYT $t2 $top"; + @epl; +} + +# globals for printinst +my $count=0; +my $isleaf=0; + +sub printinst { + my ($top,$cinst,@connections)=@_; + push @stack,$top; + print DBG "PI $top,$cinst,@connections"; + my %map = (); + my @list = expandports ($top); + my %list=(); + # make a hash of the port names + foreach my $list (@list) { + $list{$list}=1; + } + # map the upper level signal names to the internal port names + foreach my $n (0..$#connections) { + print DBG "C $top:$cinst $connections[$n]"; + my ($p,$s) = split(/=/,$connections[$n]); + $map{$p} = $s; + if (defined ($list{$p})) { + # this may not handle full arrays correctly + my @p = expandport($top,$p); + my @s = arrayify ($s); + foreach my $n (0..$#p) { + $map{$p[$n]} = $s[$n]; + print DBG "MP1x $cinst $top $p[$n] $s[$n]"; + } + print DBG "MP1 $cinst $top $p $map{$p} $#p $#s"; + } + else { # bad thing here, should always be ok except for power + $"="->"; + print STDERR "No port $p in $top $cinst @stack" + unless $p eq "Vdd" or $p eq "GND"; + $"=" "; + } + } + # test for all ports mapped, assign like local nodes if not + # it is an error for this if the cell is not the top cell + foreach my $port (@list) { + print DBG "PRT $top $port"; + if (! defined ($map{$port})) { + print DBG "No portmap for $port in $cinst $top" if $cinst ne ""; +# $map{$port} = $port; + } + } + # now do explicit local nodes (wires) + @list=(); + @list = @{$localnodes{$top}} if defined $localnodes{$top}; + my $ninst = $cinst; + $ninst .= '/' if $cinst ne ""; + foreach my $l (@list) { + $map{$l} = "$ninst$l"; + print DBG "ML $cinst $top $l $map{$l}"; + } + # record all pre-mappings in debug file + foreach my $node (sort keys %map) { + print DBG "M $cinst $top $node $map{$node}"; + } + my $k; + if (defined ($module{$top})) { + foreach my $inst (sort @{$module{$top}}) { + # key for hashes below + $k = "$top:$inst"; + my @p = @{$pins{$k}}; + my @mappins=(); + foreach my $n (0..$#p) { + print DBG "MX1 $k $p[$n]"; + my ($p,$s) = split(/=/,$p[$n]); + my @exp = expandport($type{$k},$p); + my @p = arrayify ($s); + print DBG "PY $type{$k} $k [$p $s] $#exp $#p" if $#exp != $#p; + if ($s =~ /^{/) { # } + if ($#exp == $#p) { + foreach my $n (0..$#p) { + $map{$p[$n]} = "$ninst$p[$n]" + if ! defined $map{$p[$n]}; + push @mappins, "$exp[$n]=$map{$p[$n]}"; + print DBG "MX2 $cinst $top $exp[$n] $map{$p[$n]} $p[$n]"; + } + } + elsif ($#p == 0) { + foreach my $n (0..$#exp) { + my $name = $exp[$n]; + $name =~ s/.*\[/[/; + $name = $p[0].$name; + $map{$name} = "$ninst$name" + if ! defined $map{$name}; + push @mappins, "$exp[$n]=$map{$name}"; + print DBG "MX3 $cinst $top $exp[$n] $map{$name} $name"; + } + } + else { + print DBG "Err Port count mismatch $#exp $#p"; + } + } + else { + $map{$s} = "$ninst$s" + if ! defined $map{$s}; + push @mappins, "$p=$map{$s}"; + print DBG "MX4 $cinst $top $s $map{$s} $p"; + } + } + my @s=(sort @mappins); + if ($leaf{$k} or ! $flat) { + print DBG "PX1 X$ninst$inst $type{$k} \$PINS @s\n @p"; + # fix the port list for printing only + my @ss=(); + foreach my $n (0..$#s) { + if ($s[$n] =~ /1'[bh]([01])/) { + my $sex = $1; + my ($name,$x) = split(/=/,$s[$n]); + $s[$n] = "$name=Vdd" if $sex; + $s[$n] = "$name=GND" if ! $sex; + } + if ($s[$n] =~ /^VDD=/ and $s[$n] =~ /=GND/) { + $s[$n] =~ s/=GND/=Vdd/; + } + elsif ($s[$n] =~/^V[DG][DG]/ and $s[$n] =~ /=GND/) { + my ($name,$x) = split(/=/,$s[$n]); + $s[$n] = "$name=$name"; + } + push @ss, $s[$n] + if $s[$n] ne "Vdd=Vdd" and $s[$n] ne "GND=GND" and + ! ($s[$n] =~ /^Rref=/) and ! ($s[$n] =~ /^Vtt=/); + } + push @ss,@{$specialcases{$type{$k}}} if defined $specialcases{$type{$k}}; + if (! $isleaf) { + foreach my $n (0..$#ss) { + my ($p,$s)=split(/=/,$ss[$n]); + if ($s =~ /^1'[bh]([01])$/) { + my $sex = $1; + $ss[$n] = "$p=Vdd" if $sex; + $ss[$n] = "$p=GND" if ! $sex; + } + elsif (defined ($cast{$s})) { + $s = $cast{$s}; + $ss[$n]="$p=$s"; + } + if ($p eq "VDD" and $s =~ /^1/) { + $ss[$n]="$p=Vdd"; + } + elsif ($p =~/^V[DG][DG]/ and $s =~ /^1/) { + $ss[$n] = "$p=$p"; + } + } + } + wrap "X$ninst$inst $type{$k} \$PINS @ss"; + $count++; + } + else { + $isleaf++; + printinst($type{$k},"$ninst$inst",@s); + $isleaf--; + } + } + } + else { + print STDERR "Skipping $top as undefined"; + } + print DBG "PIX $top"; + pop @stack; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2cast.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2cast.pl new file mode 100755 index 0000000000..f770552ed8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2cast.pl @@ -0,0 +1,3110 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +# not a true verilog parser. Makes assumptions about commas +# not being inside of a commented name. Makes assumptions about +# certain names with square brackets as well as 'curly' brackets. +# does not handle structures more complex than arrays. + +use strict; + +use Getopt::Long; +use IPC::Open2; +use IPC::Open3; +use IO::Select; + +my $apid = open2(\*ARD, \*AWR, "rename --type=all 2>/dev/null"); + +# command line args +my $refineparent="PRIMITIVE"; +my $progress=0; +my @addimport=("lib.synchronous.schannel"); +# maybe not +@addimport=(); +my $bindfile=""; +my $castdir=""; +my $castpath=""; +my $specdir=""; +my $library=""; +my $subtype; +my $subtypedefined=0; +my $verilog_block="rtl"; +my $propagate=1; +my $cast_and_spec=0; +my $wrap=0; # used to wrap the top level for canonicalization issues. +my $argwrap=0; +my $cdc_mode=0; +my $debug=0; +# mainly for non-verilog power ports +my @extra_ports=(); +my @extra_implied=(); + +my $externalfile=""; +my $outputfile=""; +my $verbose=0; +my $quiet=0; +my $argparent; +my $p4client; +my $p4=0; +my $max_heap_size="512M"; +my $extra_refine=""; +my $portbase=""; + +# binding file related +my %bind=(); # result of reading vsbind file +my %bindinstlist=(); # these three track bind signals +my %bindnetlist=(); +my %bindcelllist=(); + +# results from parse: +my %portdirection=(); # key = "module port", value = =|-|+- +my %portmap=(); # key = module, subkey is the port name, value in port order index (n) +my %moduleports=(); # key = module, value is array of [aref,portname] +my %wiretypes=(); # key = module, value is array of [aref,wirename] (not including ports) +my %inst=(); # key = module, value is array of instance names +my %assign=(); # key = module, value is array of assign statements (e.g. a=b) + # note itype is "module:inst" +my %signal=(); # key is itype, subkey is pin name, value is net connected to pin +my %pins=(); # key is itype, key is array of [pin=net] (same info as above, but ordered) +my %type=(); # key is itype, value is cell type of instance + + # from generate_port_mapping of top module +my %verilog=(); # verilog name of top module cast port +my %castname=(); # cast name of top module verilog port + +# from getports +my %castfound=(); # key=cell, array of cast lines representing the ports +my %ports=(); # key=cell, array of [ctype,name,dir] +my %implied=(); # key=cell, array of [ctype,name,dir] +my @aliasedports=(); # only for top cell, all aliases of each port +my %cpdirection=(); # key = cell, subkey=port, value=direction (-|+) +my %ecanonical=(); # key = cell, subkey=port, value=canonical port name +my %eicount=(); # number of inputs on canonical port +my %rcanonical=(); # reverse canonical lookup +my %revlookup=(); # convert .d[#] to .# +my %realchannel=(); # finds the root part of name of channel +my %realport=(); # list of ports actually connected to something, key=cell +my %channeldefs=(); # sub nodes of channels derived from cast_query, merge of all cell types + # for subcells from generate_port_mapping +my %v2c=(); # key is cell, subkey is verilog name, value is cast name +my %c2v=(); # key is cell, subkey is cast name, value is verilog name + +my @module=(); +my %nodes=(); +my $portlist=1; +my $instlist=0; +my %specialnodes=(); +my $top = ""; +my $porttopcell=""; +my $debugfile = "/dev/null"; +my $warning=0; +my $warnings=0; +my $flat=0; +my %external=(); # list of external cells with array ports +my $profile=0; +my $errors=0; + +my $mname="xxx"; + +sub ignore_cell { + my ($cell)=@_; + if(($cell =~ /_TieDown$/) + or ($cell =~ /GNDShieldTieOff$/) or ($cell =~ /POWER_GRID_TIEOFF/)) { + return 1; + } + 0; +} + +my $cast_server_pid=0; +my $SEL; + +sub start_cast_server { + my $cmd="cast_file_server --max-heap-size=$max_heap_size --cast-path=$castpath"; + $cast_server_pid=open3(*CCIn, *CCOut, *CCErr, $cmd); + die "Cannot start cast server" if ! $cast_server_pid; + $SEL = new IO::Select; + $SEL->add(*CCOut); + $SEL->add(*CCErr); + print STDERR "Start cast server $cmd" if $verbose; +} + +sub call_cast_server { + my $cmd = shift; + my $showerrs=shift; + $showerrs=1 if ! defined $showerrs; + start_cast_server if $cast_server_pid==0; + my $done=0; + my @ready; + my $out_data; + my $err_line=""; + my $return_code=0; + my $err_data; + my $n=0; + print STDERR "CastServer: $cmd" if $debug; + print CCIn "- - com.avlsi.tools.$cmd"; + my $return=""; + while (!$done and (@ready = $SEL->can_read())) { + foreach my $fh (@ready) { + if ($fh eq *CCOut) { + if (!sysread CCOut, $out_data, 4096) { + print STDERR "Warning: Java cast server closed stdout.\n"; + $warnings++; + $return_code = -2; + } + $return .= $out_data; + } + elsif ($fh eq *CCErr) { + if (!sysread CCErr, $err_data, 80) { + print STDERR "Warning: Java cast server closed stderr.\n"; + $warnings++; + $return_code = -2; + $done = 1; + } + my @lines = split /\n/, $err_data; + my $leftover = pop @lines if ($err_data !~ /\n$/); + my $starts_with_newline = ($err_data =~ /^\n/); + while (@lines or $err_line ne "" and $err_data eq "\n") { + $err_line .= shift @lines unless ($starts_with_newline); + if ($err_line !~ /^CastFileServer:/) { + if ($showerrs and ! ($err_line =~ /^\s*$/)) { + print STDERR $cmd if $verbose; + print STDERR "Errline: $err_line"; + $errors++; + } + } + elsif ($err_line eq "CastFileServer: EXCEPTION") { + $return_code = -2; + if ($showerrs) { + print STDERR "Error running $cmd"; + $errors++; + } + } + elsif ($err_line =~ /^CastFileServer: EXIT (.*)$/) { + kill 9, $cast_server_pid; + waitpid $cast_server_pid, 0; + $cast_server_pid=0; + $return_code = -2 if ($1 != 0); + } + elsif ($err_line eq "CastFileServer: READY") { + $done = 1; + } + $err_line = ""; $err_data = ""; + $starts_with_newline = 0; + } + $err_line .= $leftover if ($leftover); + } + } + } + $return_code = -2 if (!$done); + # Drain stdout (not usually necessary) + while ($SEL->can_read(0)) { + last if (!sysread CCOut, $out_data, 4096); + $return .= $out_data; + } + $return; +} + +sub query_ports { + my ($cell,$queryfile)=@_; + start_cast_server if $cast_server_pid==0; + my $cmd="jauto.CastQuery --no-header --task=external_nodes=di:im:xr,ports --cell=$cell"; + my $query=call_cast_server($cmd); + if ($query ne "") { + print STDERR "Writing $queryfile" if $debug; + my $fqo; + open ($fqo, ">$queryfile"); + printf $fqo "%s", $query; + close $fqo; + } +} + +sub query_real_ports { + my ($cell,$queryfile)=@_; + start_cast_server if $cast_server_pid==0; + my $cmd="jauto.CastQuery --no-header --task=external_nodes=im:xr:re --cell=$cell"; + my $query=call_cast_server($cmd); + if ($query ne "") { + print STDERR "Writing $queryfile" if $debug; + my $fqo; + open ($fqo, ">$queryfile"); + printf $fqo "%s", $query; + close $fqo; + } + else { # if no real ports at all, just fake it + $cmd="jauto.CastQuery --no-header --task=external_nodes=im:xr --cell=$cell"; + $query=call_cast_server($cmd); + if ($query ne "") { + print STDERR "Writing $queryfile" if $debug; + my $fqo; + open ($fqo, ">$queryfile"); + printf $fqo "%s", $query; + close $fqo; + } + } +} + +sub query_portmap { + my ($cell,$queryfile,$verilogblock)=@_; + start_cast_server if $cast_server_pid==0; + $verilogblock = "rtl" if ! defined $verilogblock; + my $cmd="prs2verilog.GeneratePortMapping --verilog-block=$verilogblock --cast-path=$castpath --cell=$cell"; + # ignore errors on generating port map + my $query=call_cast_server($cmd, 0); + if ($query ne "") { + print STDERR "Writing $queryfile" if $debug; + my $fqo; + open ($fqo, ">$queryfile"); + printf $fqo "%s", $query; + close $fqo; + } +} + +# convert 'b definitions to a list of Vdd and GND nodes +sub btolist { + my ($signal)=@_; + if ($signal =~ /'b/) { + $signal =~ s/'b/ /; + my ($cnt,$vals)=split(/ /,$signal); + $signal=""; + my $v = substr($vals,0,1); + $signal .= $v eq "1" ? "Vdd" : "GND"; + foreach my $i (1..length($vals)-1) { + my $v = substr($vals,$i,1); + $signal .= ", "; + $signal .= $v eq "1" ? "Vdd" : "GND"; + } + } + $signal; +} + +# read vsbind file which allows changing the port +# names, instance connections to override verilog +# mostly used for ports where some things just are +# not in the verilog +sub readbindfile { + my ($file)=@_; + local (*P,$_); + if (open (P, "<$file") ) { + print STDERR "Reading $file..." if $progress; + while (

    ) { + chomp; + next if /^#/; + next if /^\s*$/; + my ($cell, $instance, $pin, $signal) = split; + $bind{"$cell $instance $pin"}=$signal if defined $signal; + $bindinstlist{$instance}=0 if $instance ne "*"; + $bindcelllist{$cell}=0; + $bindnetlist{$signal}=0; + } + } + else { + print STDERR "Warning: bind file $file not readable"; + $warnings++; + } +} + +# traslate signal due to vsbind information collected above +sub getbindsignal { + my ($cell,$inst,$port,$signal)=@_; + if (defined $bind{"$cell $inst $port"}) { + $signal = $bind{"$cell $inst $port"}; + $bindinstlist{$inst}=1; + $bindcelllist{$cell}=1; + $bindnetlist{$signal}=1; + } + elsif (defined $bind{"$cell * $port"}) { + $signal = $bind{"$cell * $port"}; + $bindcelllist{$cell}=1; + $bindnetlist{$signal}=1; + } + $signal; +} + +# cadence cell name to cast name translation (using rename) +sub cellcad2cast { + return $_[0] if ($_[0] =~ /\(/) or ($_[0] =~ /\$/) or ($_[0] eq ""); + print AWR "cell cadence cast $_[0]"; + my $new=; + chomp $new; + if ($new =~ /\s/ or $new eq "") { + $new = $_[0]; + close ARD; + close AWR; + kill $apid; + waitpid $apid, 0; + $apid = open2(\*ARD, \*AWR, "rename --type=all 2>/dev/null"); + } + $new; +} + +# cadence instance name to cast name translation (using rename) +sub instcad2cast { + return $_[0] if ($_[0] =~ /\(/) or ($_[0] =~ /\$/) or ($_[0] eq ""); + print AWR "instance cadence cast $_[0]"; + my $new=; + chomp $new; + if ($new =~ /\s/ or $new eq "") { + $new = $_[0]; + close ARD; + close AWR; + kill $apid; + waitpid $apid, 0; + $apid = open2(\*ARD, \*AWR, "rename --type=all 2>/dev/null"); + } + $new; +} + +# cast instance name to cadence name translation (using rename) +sub instcast2cad { + print AWR "instance cast cadence $_[0]"; + my $new=; + chomp $new; + if ($new =~ /\s/ or $new eq "") { + $new = $_[0]; + close ARD; + close AWR; + kill $apid; + waitpid $apid, 0; + $apid = open2(\*ARD, \*AWR, "rename --type=all 2>/dev/null"); + } + $new; +} + +# cadence node name to cast name translation (using rename) +sub nodecad2cast { + return $_[0] if ($_[0] =~ /[\(\$']/) or ($_[0] eq ""); + print AWR "node cadence cast $_[0]"; + my $new=; + chomp $new; + if ($new =~ /\s/ or $new eq "") { + $new = $_[0]; + close ARD; + close AWR; + kill $apid; + waitpid $apid, 0; + $apid = open2(\*ARD, \*AWR, "rename --type=all 2>/dev/null"); + } + $new; +} + +# cast node name to cadence name translation (using rename) +sub nodecast2cad { + return $_[0] if ($_[0] =~ /\(/) or ($_[0] =~ /\$/) or ($_[0] eq ""); + my $old=$_[0]; + print AWR "node cast cadence $_[0]"; + my $new=; + chomp $new; + if ($new =~ /\s/ or $new eq "") { + $new = $_[0]; + close ARD; + close AWR; + kill $apid; + waitpid $apid, 0; + $apid = open2(\*ARD, \*AWR, "rename --type=all 2>/dev/null"); + } + $new; +} + +sub special { # really double index arrays + my ($name)=@_; + $name =~ s/\[/_l_/g; + $name =~ s/\]/_r_/g; + $name; +} + +# make names cast compatible +my %instxref=(); +my %instlookup=(); + +sub fix_inst { + my ($inst)=@_; + return $instlookup{$inst} if defined $instlookup{$inst}; + my $base = "\\[(\\d+)\\]"; + my $expr = "$base"; + # look for arrays at end of instance name + my $prefix=$inst; + my @new=(); + if ($cast_and_spec) { # for proteus async, keep array syntax + my $n=0; + while ($inst =~ /$expr$/) { + $expr .= $base; + $n++; + } + $expr = substr($expr,0,$n*length($base)); + $inst =~ /(.*)$expr$/; + $prefix=$1; + # array all the integer indicies + for (my $x = 2; $x <= $n+1; $x++) { + eval "push \@new, \$$x;"; + } + } + # the prefix needs gdsii nameing + $prefix =~ s/\[/_L_/g; + $prefix =~ s/\]/_R_/g; + $prefix =~ s/\./_D_/g; + $prefix =~ s/\$/_/g; + $prefix =~ s/,/_c_/g; + # add on cast-like multi-dim array + if (@new) { + $prefix.= "[".join(",", @new)."]"; + } + # check for duplicates + $prefix =~ s/\//_slash_/g; + if (defined ($instxref{$prefix}) and $instxref{$prefix} ne $inst) { + print STDERR "Warning: apparent inadvertent duplicate instance name $prefix"; + $warnings++; + } + $instxref{$prefix} = $inst; + $instlookup{$inst} = $prefix; + $prefix; +} + +my %nodexref=(); +my %nodecheck=(); +my $localmodule=""; + +sub setnodexref { + my ($in,$out)=@_; + if ($out ne $in and defined($nodecheck{$out}) and $nodecheck{$out} ne $in) { + print STDERR "Warning: change in node renaming $out $nodecheck{$out} => $in"; + } + $nodecheck{$out}=$in if $out ne $in; + $nodexref{$in}=$out; +} + +sub fix_node { + my ($signal1, $ln)=@_; + my $insignal=$signal1; + my $doprint = 0; +# $doprint = 1 if $signal1 =~ /\[/; + return $nodexref{$signal1} if defined $nodexref{$signal1}; + $signal1 =~ s/\//_slash_/g; + printf STDERR "$signal1 $ln" if $doprint; + if (defined($ecanonical{$localmodule}->{$signal1})) { + if (defined ($rcanonical{$localmodule}->{$signal1})) { + setnodexref($signal1,$rcanonical{$localmodule}->{$signal1}); + } + else { + setnodexref($signal1,$signal1); + } + print STDERR " 1 $nodexref{$signal1}" if $doprint; + return $nodexref{$signal1}; + } + my $try=$signal1; + $try =~ s/\]\[/,/g; + if (defined($ecanonical{$localmodule}->{$try})) { + if (defined ($rcanonical{$localmodule}->{$try})) { + setnodexref($try,$rcanonical{$localmodule}->{$try}); + } + else { + setnodexref($try,$try); + } + print STDERR " 2 $nodexref{$try}" if $doprint; + return $nodexref{$try}; + } + my $in=$signal1; + $signal1 =~ s/\$/_/g; + $signal1 =~ s/\./_D_/g; + $signal1 =~ s/\[/_l_/g; + $signal1 =~ s/\]/_r_/g; + $signal1 =~ s/,/_c_/g; + if ($signal1 =~ /^\\/) { + my ($sl,$sr)=split("_blank_", $signal1); + $sr = "" if ! defined $sr; + $sl =~ s/\\//; + $sl=~ s/\[/_l_/g; + $sl=~ s/\]/_r_/g; + $sl=~ s/\./_D_/g; + setnodexref($in,$sl.$sr); + print STDERR " 3 $nodexref{$in}" if $doprint; + return $sl.$sr; + } + if ($signal1 =~ /\]_blank_\[/) { + my ($sl,$sr)=split("_blank_", $signal1); + $sr = "" if ! defined $sr; + $sl =~ s/\\//; + $sl=~ s/\[/_l_/g; + $sl=~ s/\]/_r_/g; + $signal1 = $sl.$sr; + } + elsif ($signal1 =~ /_r__blank__l_/) { + my ($sl,$sr)=split("_blank_", $signal1); + $sr = "" if ! defined $sr; + $sl =~ s/\\//; + $sl=~ s/\[/_l_/g; + $sl=~ s/\]/_r_/g; + $sr=~ s/_l_/[/g; + $sr=~ s/_r_/]/g; + $signal1 = $sl.$sr; + } + elsif ($signal1 =~ m:\[\d+\]\[\d+\]:) { + $signal1 =~ s/\[/_l_/g; + $signal1 =~ s/\]/_r_/g; + } + if ($signal1 =~ / /) { + $signal1 =~ s/ //; + } + if ($signal1 =~ /\]\[/) { + $signal1 =~ s/\[/_l_/; + $signal1 =~ s/\]/_r_/; + } + $signal1 =~ s/\[([^\d][^\]]*)\]/_l_${1}_r_/; + if ($signal1 =~ /\]\[/) { + $signal1 =~ s/_r_\[/_c_/; + $signal1 =~ s/\]\[/_r_\[/; + } + $signal1 = $specialnodes{$signal1} if (defined $specialnodes{$signal1}); + $signal1 = $castname{$signal1} if defined $castname{$signal1}; + setnodexref($in,$signal1); + print STDERR " 4 $signal1" if $doprint; + $signal1; +} + +# depends too much on globals here +sub domodule { + my ($cast)=@_; + my @mlines=(); + my $portlist=1; + if (@module) { + if ($debug) { + printf STDERR "Module $module[0]"; + foreach my $nd (sort keys %nodes) { + print STDERR " Node $nd $nodes{$nd}"; + } + } + my $mod=$module[0]; + chomp $mod; + foreach my $ln (@module) { + my $ok = 1; + $portlist=0 if $ln =~ //dev/null"; + foreach my $ln (@lines) { + if ($ln =~ /^define/) { + my @f=split(/"/,$ln); + $st = $f[1]; + last; + } + } + my $exists=0; + my $writable=0; + my $outfile="$libpath/$st.cast"; + $exists = 1 if -f $outfile; + $writable = 1 if -w $outfile; + my $p4edit = ($p4 and $exists and ! $writable); + system "p4 -c $p4client edit '$outfile'" + if $p4edit; + my $fc; + if (open ($fc, ">$outfile") ) { + print STDERR "Writing $outfile" if $progress; + cast_header($fc); + print $fc join("\n", @lines); + close $fc; + system "p4 -c $p4client revert -a '$outfile'" + if $p4edit; + system "p4 -c $p4client add '$outfile'" + if $p4 and ! $exists; + } + else { + print STDERR "Failed to write '$outfile'"; + exit 1; + } +} + +# for profiling, does not work on compute servers +# if profile = 1 +#use Time::HiRes qw( gettimeofday tv_interval); +# if profile = 0 + +sub gettimeofday {} +sub tv_interval {0;} + +my %opts = ( + "add-import=s" => sub { push @addimport, $_[1];}, + "bindfile=s" => \$bindfile, + "cast-and-spec" => \$cast_and_spec, + "cast-dir=s" => \$castdir, + "cast-path=s" => \$castpath, + "cdc-mode" => \$cdc_mode, + "client=s" => \$p4client, + "debug" => \$debug, + "external=s" => \$externalfile, + "extra-implied=s" => sub { + my @f=split(/,/,$_[1]); + foreach my $f (@f) { + my ($type,$dn)=split(/:/,$f,2); + if ( ! defined ($dn) ) { + $dn = $type; + $type = "node"; + } + $dn =~ s/^([-+]*)//; + my $dir=$1; + push @extra_implied, [$type,$dn,$dir]; + }}, + "extra-ports=s" => sub { + my @f=split(/,/,$_[1]); + foreach my $f (@f) { + my ($type,$dn)=split(/:/,$f,2); + if ( ! defined ($dn) ) { + $dn = $type; + $type = "node"; + } + $dn =~ s/^([-+]*)//; + my $dir=$1; + push @extra_ports, [$type,$dn,$dir]; + }}, + "extra-refine=s" => \$extra_refine, + "library=s" => \$library, + "max-heap-size=s" => \$max_heap_size, + "output=s" => \$outputfile, + "p4" => \$p4, + "parent=s" => \$argparent, + "port-base=s" => \$portbase, + "progress" => \$progress, + "propagate" => \$propagate, + "quiet" => \$quiet, + "refineparent=s" => \$refineparent, + "spec-dir=s" => \$specdir, + "subtype=s" => sub { $subtype = $_[1]; $subtypedefined=1; }, + "verbose" => \$verbose, + "verilog-block=s" => \$verilog_block, + "wrap=i" => sub { $wrap = $argwrap = $_[1];}, +); + +sub usage { + print STDERR "@_" if @_; + print STDERR < + --cast-dir=

    : cast directory + --library= : required library name + --spec-dir= : cast spec directory + [--cast-path= : if not cast-dir:spec-dir + [--add-import=] : to be added to each module + [--bindfile=] : external binding file + [--client=<>] : to invoke p4 + [--debug] : generate lots of debug data + [--external=] : read file to define external cells with arrays + [--max-heap-size=<> : set max heap size for sub-tasks + [--output=] : output instead of stdout. (may not work right.) + [--p4] : to allow p4 + [--parent=<>] : refinement parent of top cell + [--progress] : show progress + [--propagate] : actually populate the spec dir + [--quiet] : no info at all + [--refineparent=<>] : refinement parent of subcells + [--subtype=#] : default 1000 + [--verbose] : generate less debug data + [--verilog-bloc=<>] : if not rtl + [--warning] : generate warning messges + [--wrap=#] : number of times to wrap the cast for canon names + [--extra-refine=<>] : extra refinement parent to be added + [--port-base=<>] : base cell for port names if not parent + [--cdc-mode] : used to create a cast of an routed cdc +EU + exit 1; +} + +select STDERR; +$|=1; +select STDOUT; +$|=1; +GetOptions ( %opts ) or usage; +$portbase = $argparent if $portbase eq "" and defined $argparent; +$subtype = 1000 if ! defined $subtype; +usage if ! defined $ARGV[1]; +usage "Must define a library ($library)" if (! ($library =~ /\./)) or $library eq ""; +`mkdir -p "$castdir"` if $castdir ne "" and ! -d $castdir; +usage "Must define a cast-dir ($castdir)" if $castdir eq "" or ! -d $castdir; +`mkdir -p "$specdir"` if $specdir ne "" and ! -d $specdir; +usage "Must define a spec-dir ($specdir)" if $specdir eq "" or ! -d $specdir; +$verbose=1 if $debug; +$warning=1 if $verbose; +$progress=1 if $verbose; +$verbose = $debug = $warning = $progress = 0 if $quiet; +my $verilog=$ARGV[0]; +my $md5sum=`md5sum '$verilog'`; +chomp $md5sum; +$md5sum =~ s/\s.*//; +my $fulcrum_id=`head '$verilog' | awk '/FULCRUM ID/ {print \$4}'`; +chomp $fulcrum_id; +$fulcrum_id = 0 if ! $fulcrum_id =~ /^\d+$/; +my $proteus_tag="$md5sum $fulcrum_id"; +my $extranodes=$verilog; +$extranodes =~ s/\.v$/.extranodes/; +my $directives_file=$verilog; +$directives_file =~ s/\.[^\.]+$/.directives/; +my $arg=$ARGV[1]; +my $argcell=$arg; +$argcell =~ s/\.(\d+)$//; +my $argsubtype=$1; +if ($outputfile eq "") { + $outputfile = $ARGV[0]; + $outputfile =~ s/\.v[^\.]*$//; + $outputfile .= ".cast"; +} +if ($bindfile eq "") { + $bindfile = $arg; + $bindfile .= ".vsbind"; +} +readbindfile ($bindfile) if ($bindfile ne "" and -s $bindfile); + +sub typerename { + my ($type)=@_; + if ($type eq "") { + $type = "node"; + } + elsif ($type =~ m=\[(\d+):(\d+)\]=) { + my $b=$2; + my $e=$1; + if ($b == 0) { + $e++; + $type = "node\[$e\]"; + } + else { + $type = "[$b..$e]"; + } + } + $type; +} + +$debugfile = "vs2cast.dbg" if $debug; +open (DBG, ">$debugfile"); + +# not in the verilog, but necessary +my %specialcases = ( + "QCSMS1_DS_13T" => ["VDD10=vdd","VSS10=GND"], + "QCSMS1_MUX_13T" => ["VDD10=vddA","VSS10=GND"], +); + +my %portnodes=(); +my %hasarray=(); +my @moduleports=(); +my @ports=(); +my %porttypes=(); +my %wires=(); +my %localnodes=(); +my %module=(); +my %modules=(); # just those in the file + +# whole files goes into memory for ease of handling 'c' comments +sub readfile { + my ($file) = @_; + local(*P, $_, $/); + undef $/; + if (open (P, "<$file")) { + printf STDERR "Reading $file..." if $progress; + } + else { + die "Cannot open $file $!"; + } + my $text =

    ; + close P; + $text =~ s/;/;\n/g; + $text =~ s/\t/ /g; + $text =~ s/ */ /g; + $text =~ s/^ *//; + $text =~ s/\n */\n/g; + $text =~ s/\] \[/]_blank_[/g; + # initial lines with comments + while ($text =~ m:^//:) { + $text =~ s:^//[^\n]*\n::; + } + $text =~ s/^ *//; + # other 'rest of line' comments + while (index ($text, "//") > 0) { + $text =~ s: *//[^\n]*\n:\n:g; + $text =~ s/\n\n/\n/g; + } + # remove blank lines + while ($text =~ /\n\n/) { + $text =~ s/\n\n/\n/g; + } + # remove 'c' type comments + my $i1; + my $i2; + my $t; + while (($i1 = index($text, "/*")) >= 0) { + $i2 = index(substr($text,$i1),"*/"); + $t = substr($text,0,$i1).substr($text,$i1+$i2+2); + $text=$t; + } + print STDERR "Done" if $progress; + # added for slash separators +# $text =~ s:/:_slash_:g; + # make into an array of lines + split(/\n/,$text); +} + +sub vsplit { + my ($string)=@_; + my @array=(); + my $token=""; + my $esc=0; + $string =~ s/\/\/.*//; + $string =~ s/^\s+//; + for (my $i = 0; $i < length($string); $i++) { + my $s = substr($string,$i,1); + if ($s =~ /\s/) { + $esc=0; + if (length($token)) { + push @array, $token; + $token=""; + } + } + elsif (($s =~ /[,\)\({}=]/) and ! $esc) { + $esc=0; + if (length($token)) { + push @array, $token; + $token=""; + } + push @array, "$s"; + } + elsif ($s eq "\\") { + $esc=1; + } + elsif ($s eq ";") { + if (length($token)) { + push @array, $token; + $token=""; + } + push @array, ";"; + last; + } + else { + $token .= $s; + } + } + @array; +} + +sub parse { + my ($file, $external) = @_; + my @lines = readfile ($file); + printf STDERR "Parsing $file..." if $progress; + my $lnr = 0; + local ($_); + my $module = ""; + %localnodes=(); + my %plookup=(); + my @plookup=(); + my @wlookup=(); + my @wires=(); + my @inst=(); + my $hasarray=0; + my @mp=(); + my @assign=(); + while ($lnr <= $#lines) { + $_=$lines[$lnr++]; + # skip blank lines + s/^\s+//; + next if (/^$/); + # module definition until terminating ; + if (/^module/) { + @assign=(); + my $ln = $_; + while (! ($ln =~ /;/) and $lnr <= $#lines) { + $ln .= " $lines[$lnr++]"; + } + my @mp = vsplit($ln); + shift @mp; + $module = cellcad2cast(shift @mp); + $modules{$module}=1; + $hasarray=0; + @moduleports=(); + my $lp = shift @mp; + print STDERR "Error: expected '(' got '$lp'" if $lp ne '('; + foreach my $n (0..$#mp) { + if ($mp[$n] eq ')' and $mp[$n+1] eq ';') { + last; + } + elsif ($mp[$n] eq ';' or $mp[$n] eq ')') { + print STDERR "Error: Unexpected '$mp[$n]'"; + } + elsif ($mp[$n] ne ',') { + $moduleports[$n] = ["node", $mp[$n]]; + $portmap{$module}->{$mp[$n]}=$n; + print DBG "HA1 $module $mp[$n]" if $debug; + $hasarray = 1 if ($mp[$n] =~ /\[/); + } + } + $hasarray{$module}=$hasarray; + undef %plookup; + %plookup=(); + foreach my $n (0..$#mp) { + $plookup{$mp[$n]}=$n; + } + @wires=(); + @wlookup=(); + } + # port declarations + elsif (/^output/ or /^input/ or /^inout/) { + my $ln = $_; + my $ln = $_; + while (! ($ln =~ /;/) and $lnr <= $#lines) { + $ln .= " $lines[$lnr++]"; + } + my @tokens=vsplit($ln); + my $io = shift @tokens; + my $aref = shift @tokens; + my $end=pop @tokens; + print STDERR "Parse Error: '$end' should be ';'" if $end ne ';'; + if ($aref eq "wire") { + $aref = shift @tokens; + } + if ($aref =~ /^\[\d+:\d+\]$/ ) { + $hasarray{$module}=1; + } + else { + unshift @tokens, $aref; + $aref = ""; + } + if ($io eq "input") { + $io = "-"; + } + elsif ($io eq "output") { + $io = "+"; + } + else { + $io = "+-"; + } + foreach my $port (@tokens) { + if (! ($port =~ /^[,;]/)) { + $portdirection{"$module $port"}=$io; + if (defined $plookup{$port}) { + $moduleports[$plookup{$port}]=[$aref,$port]; + $plookup[$plookup{$port}] = $aref; + } + else { + print STDERR "Warning: Undefined ref :$port: at $." if $port ne ""; + $warnings++; + } + } + } + } + # local declarations, not necessarily all local nodes! + elsif (/^wire/ or /^trireg/) { + my $ln = $_; + while (! ($ln =~ /;/) and $lnr <= $#lines) { + $ln .= " $lines[$lnr++]"; + } + my @tokens=vsplit($ln); + my $io = shift @tokens; + my $aref = shift @tokens; + my $end=pop @tokens; + print STDERR "Parse Error: '$end' should be ';'" if $end ne ';'; + if (! ($aref =~ /^\[\d+:\d+\]$/ ) ) { + unshift @tokens, $aref; + $aref = ""; + } + foreach my $wire (@tokens) { + if (! ($wire =~ /^[,;]/)) { + push @wlookup, [$aref,$wire] if ! defined $plookup{$wire}; + } + } + } + # finish up module + elsif (/^endmodule/) { + print DBG "ENDMODULE $module $lnr" if $debug; + $moduleports{$module}=[@moduleports]; + @moduleports=(); + $wiretypes{$module} = [@wlookup]; + @wlookup=(); + $external{$module}=1 if $external; + $inst{$module}=[@inst]; + @inst=(); + @plookup = (); + if (@assign) { + $assign{$module}=[@assign]; + } + $module=""; + } + # assigns + elsif (/^assign /) { + my @a=vsplit($_); + shift @a; + my $a = ""; + my $n=0; + while ($n <= $#a and $a[$n] ne "=") { + $a .= $a[$n]; + $n++; + } + my $b=""; + $n++; + while ($n <= $#a and $a[$n] ne ";") { + $b .= $a[$n]; + $n++; + } + $b = "GND" if $b eq "1'b0"; + $b = "Vdd" if $b eq "1'b1"; + push @assign, "$a=$b" if $a ne "obs"; + } + # old assigns + elsif (/^xyassign /) { + my $l=$_; + $l =~ s/ *;//; + $l =~ s/[ ]+/ /g; + $l =~ s/^assign *//; + my ($a, $b)=split(/=/,$l); + $b =~ s/ //g; + $b = "GND" if $b eq "1'b0"; + $b = "Vdd" if $b eq "1'b1"; + my ($x,$y)=split(/ /,$a); + $x = fix_node($x, __LINE__); + if (defined ($y) and $y ne "") { + $a = "$x$y"; + } + else { + $a = $x; + } + $a =~ s/ //g; + ($x,$y)=split(/ /,$b); + $x = fix_node($x, __LINE__); + if (defined ($y) and $y ne "") { + $b = "$x$y"; + } + else { + $b = $x; + } + $b =~ s/ //g; + push @assign, "$a=$b" if $a ne "obs"; + } + # assumes the rest is a list of instances, no logic + else { + my $ln = $_; + while (! ($ln =~ /;/) and $lnr <= $#lines) { + $ln .= " $lines[$lnr++]"; + } + $_ = $ln; + next if $ln eq ""; + my @ins = vsplit($ln); + my $type = shift @ins; + my $inst = shift @ins; + my $itype = "$module:$inst"; + my $x = shift @ins; + print STDERR "Error: Expected '(' got '$x' at line $lnr ($ln)" if $x ne '('; + my @p=(); + for (my $n = 0; $n < $#ins; $n++) { + my $pin = $ins[$n]; + print STDERR "Error: invalid pin form $pin" if ! $pin =~ /^\./; + $pin =~ s/^\.//; + my $net = ""; + my $i; + for ($i = $n+2; $i <= $#ins and $ins[$i] ne ')'; $i++) { + $net .= " $ins[$i]"; + } + $net =~ s/^\s//; + my $p=nodecad2cast($pin); + if ($net ne "") { + # maybe someday + #my $n=nodecad2cast($net); + $signal{$itype}->{$p}=$net; + push @p, "$p=$net"; + } + $n = $i + 1; + } + $pins{$itype} = [@p]; + $type{$itype} = cellcad2cast($type); + push @inst, $itype; + } + } + print STDERR "Done" if $progress; +} + +$castpath="$castdir:$specdir" if $castpath eq ""; +my $topcell=$verilog; +$topcell =~ s/\.[^\.]+$//; +#$refineparent = "chip.bali.port.epl.EPL_CELL" if $topcell =~ /EPL/; # HACK +# get externals to define ports of sIPCell, for example +# cells without definitions are assumed single ports +parse ("$externalfile", 1) if -r $externalfile; +parse ($verilog, 0); +my $mapfile=$arg; +$mapfile .= ".vs2cast.portmap"; +if ( -r $mapfile and -s $mapfile ) { + open (P, "<$mapfile"); + print STDERR "Reading $mapfile" if $progress; +} +else { + my $cell=$argcell; + print STDERR "Generating $mapfile from cast" if $progress; + query_portmap ($cell,$mapfile,$verilog_block); + open (P, "<$mapfile"); +} +while (

    ) { + chomp; + my ($verilog,$cast)=split; + $verilog{$cast}=$verilog; + $castname{$verilog}=$cast; + my %cmaps=(); + my %vmaps=(); + # probably should be more careful with this: + if ($cast =~ /(.*)\[(\d+)\]$/) { + my $castname=$1; + my $castndx=$2; + if ($verilog =~ /(.*)\[(\d+)\]$/) { + my $vname=$1; + my $vndx=$2; + if ($vndx == $castndx) { + $verilog{$castname}=$vname; + $castname{$vname}=$castname; + if (defined ($cmaps{$vname}) and $cmaps{$vname} ne $castname) { + print STDERR "Warning: Inconsistent v->c array mapping $vname : $castname vs. $cmaps{$vname}"; + } + elsif (! defined $cmaps{$vname}) { + $cmaps{$vname}=$castname; + } + if (defined ($vmaps{$castname}) and $vmaps{$castname} ne $vname) { + print STDERR "Warning: Inconsistent c->v array mapping $castname : $vname vs. $vmaps{$castname}"; + } + elsif (! defined ($vmaps{$castname})) { + $vmaps{$castname}=$vname; + } + } + } + } +} +close P; +if ( ! -r $mapfile or ! -s "$mapfile") { + # ok generate a portmap from the verilog itself, no valid cast + my $cell; + $cell = $argcell if defined ($modules{$argcell}); + $cell = $arg if defined ($modules{$arg}); + if (defined ($cell)) { + print STDERR "Generating $mapfile from verilog" if $progress; + open (Q, ">$mapfile"); + my %map=%{$portmap{$cell}}; + foreach my $p (sort keys %map) { + print Q "$p $p"; + $verilog{$p}=$p; + $castname{$p}=$p; + } + close Q; + } +} +if ( ! -r $mapfile or ! -s "$mapfile") { + # this time it is a lost cause + die "Error: $mapfile contains no data but is required"; +} + +my %sxref=(); +my %castexists=(); +# find all cells in the spec tree +# there are likely duplicates, especially with multiple subtypes +mkdir "cache"; +my $cellxreffile="cache/cellxref.dat"; +my @castdirs=split(/:/, $castpath); +if ( -s "$cellxreffile") { + open (P, "<$cellxreffile"); + printf STDERR "Reading $cellxreffile..." if $progress; + while (

    ) { + chomp; + my ($name,$cn)=split; + $sxref{$name}=$cn; + my $x=$cn; + my $cds=$x; + $cds =~ s:\.([^\.]+)$::; + $cds =~ s/\./\//g; + $x =~ s/\.[^\.]+$//; + my $cd = $x; + $cd =~ s:\.([^\.]+)$::; + my $tail=$1; + $cd =~ s/\./\//g; + foreach my $dir (@castdirs) { + if ( -f "$dir/$cds.cast" or -f "$dir/$cd.cast") { + $castexists{$x}=1; + $castexists{$cn}=1; + last; + } + } + } + close P; + print STDERR "Done" if $progress; +} +else { + printf STDERR "Writing $cellxreffile..." if $progress; + open (P, "find '$specdir' -name \\*.cast |"); + while (

    ) { + chomp; + s:$specdir/::; + s/:/ /; + s:/:.:g; + s/\.cast$//; + my $spec=$_; + my $cast=$_; + $cast =~ s/\.([^\.]+)$//; + my $st = $1; + my $st1 = -1; + my $name = $cast; + $name =~ s/.*\.//; + next if ! ($st =~ /^\d+$/); + if (defined ($sxref{$name})) { + $st1 = $sxref{$name}; + $st1 =~ s/.*\.//; + } + $sxref{$name}=$spec if $st < $st1 or $st1 == -1; + } + close P; + open (P, ">$cellxreffile") || die "Cannot write to $cellxreffile: $!"; + foreach my $name (sort keys %sxref) { + print P "$name $sxref{$name}"; + my $cn = $sxref{$name}; + my $x=$cn; + my $cds=$x; + $cds =~ s:\.([^\.]+)$::; + $cds =~ s/\./\//g; + $x =~ s/\.[^\.]+$//; + my $cd = $x; + $cd =~ s:\.([^\.]+)$::; + my $tail=$1; + $cd =~ s/\./\//g; + foreach my $dir (@castdirs) { + if ( -f "$dir/$cds.cast" or -f "$dir/$cd.cast") { + $castexists{$x}=1; + $castexists{$cn}=1; + last; + } + } + } + close P; + print STDERR "Done" if $progress; +} + +sub castexists { + my $cell=shift; + return $castexists{$cell} if defined $castexists{$cell}; + my $cc = $cell; + $cc =~ s/\.\d[^\.]*$//; + if (defined $castexists{$cc}) { + $castexists{$cell} = $castexists{$cc}; + return $castexists{$cc}; + } + my $rv=call_cast_server("jflat.JFlat --cast-path=$castpath --tool=check --cell=$cc", 0); + $rv = ($rv =~ /Checked/) ? 1 : 0; + $castexists{$cc} = $castexists{$cell} = $rv; + return 0 if $rv == 0; + if ($cc ne $cell) { + $rv=call_cast_server("jflat.JFlat --tool=check --cell=$cell"); + $rv = ($rv =~ /Checked/) ? 1 : 0; + $castexists{$cell} = $castexists{$cc} = $rv; + } + $castexists{$cc}; +} + +sub getports { + my ($cell)=@_; + my $castcell=$cell; + $castcell =~ s/\.\d[^\.]*$//; + if ($castcell =~ /\.$subtype$/) { + $castcell =~ s/\.$subtype$//; + } + return 1 if ignore_cell($cell); + return 1 if (defined ($ports{$cell})); + if (defined ($ports{$castcell})) { + $ports{$cell}=$ports{$castcell}; + $implied{$cell}=$implied{$castcell}; + return 1; + } + print STDERR "getports($cell)=$castcell" if $debug; + my @ports=(); + my @portnodes=(); + my @implied; + my @external=(); + my @castlines=(); + my %aliasedports=(); + # first priority, find port list from cast + my $queryfile="cache/$castcell.query.ports"; + my $requeryfile="cache/$castcell.query.realports"; + my $mapqueryfile="cache/$castcell.portmap"; + if ($cell =~ /\./) { # cannot be cast file without .'s +# if (castexists($castcell) or ($castcell =~ /\./)) { } + if (castexists($castcell)) { + query_ports($castcell,$queryfile); + query_real_ports($castcell,$requeryfile); + query_portmap($castcell,$mapqueryfile); + if ( ! -s $queryfile) { + print STDERR "Error: creating/opening $queryfile"; + $errors++; + } + open (P, "<$queryfile"); + while (

    ) { + chomp; + print STDERR "getports: query $cell" if $. == 1 and $debug; + if (/^[01] /) { + my ($implied, $type, $name)=split; + my $dir = ""; + my $ctype=$type; + if ($name =~ s/^([-+]*)//) { + $dir = $1; + if (length($dir) > 1) { + $dir=""; + } + } + my $cname=$name; + if ($name =~ s/\[(\d+)\.\.(\d+)\]$//) { + my $lo=$1; + my $hi=$2; + $ctype = "$type\[$lo..$hi\]"; + } + elsif ($name =~ s/\[(\d+)\.\.(\d+),(\d+)\.\.(\d+)\]$//) { + my $lo1=$1; + my $hi1=$2; + my $lo2=$3; + my $hi2=$4; + $ctype = "$type\[$lo1..$hi1,$lo2..$hi2\]"; + } + if ( ! ($type =~ /^node/) and ! defined ($channeldefs{"$ctype"})) { + foreach my $ex (@external) { + my ($en) = split(/ /,$ex); + my $p=$en; + $p =~ s/\..*//; + $p =~ s/\[.*//; + if ($p eq $name) { + my $ch=$en; + $ch =~ s/$name//; + print STDERR "CHD $name $en $ch $cell $ctype" if $debug; + push @{$channeldefs{"$ctype"}}, $ch; + } + } + } + push @castlines, "define \"XXXX\"() (" if ! @castlines; + if ($implied) { + push @implied, [$ctype, $name, $dir]; + } + else { + if (($type =~ /([^\]]+)\[(\d+)\.\.(\d+)\]$/) and 0) { + my $ltt=$1; + my $lxx=$type; + $lxx =~ s/$ltt//; + push @castlines, " $ltt $dir$name$lxx"; + } + else { + push @castlines, " $type $dir$cname"; + } + push @ports, [$ctype, $name, $dir]; + } + } + else { # this comes first from cast_query + s/^([-+]*)//; + my $d=$1; + $d="" if length($d) > 1; + push @external, $_; + my ($p,$a)=split; + my $isenable = $a =~ /\.e$/ ? 1 : 0; + $cpdirection{$cell}->{$p}=$d; +# $cpdirection{$cell}->{$a}=$d; + $cpdirection{$castcell}->{$p}=$d; +# $cpdirection{$castcell}->{$a}=$d; + $ecanonical{$cell}->{$p}=$a; + $ecanonical{$castcell}->{$p}=$a if $castcell ne $cell; + $ecanonical{$cell}->{$a}=$a; + $ecanonical{$castcell}->{$a}=$a if $castcell ne $cell; + $eicount{$castcell}->{$a} += ($d eq '-' ? 1 : 0); + $eicount{$cell}->{$a} += ($d eq '-' ? 1 : 0); + if ($cell eq $porttopcell) { + if (defined($aliasedports{$a}) ) { + $aliasedports{$a} .= " $p"; + } + else { + $aliasedports{$a} = $p; + } + } +# commented out stuff in the next approx 50 lines may be needed +# later for better handling of canonical port channels. +# if ($p eq $a) { +# $realchannel{$castcell}->{$a}=$p; +# $realchannel{$cell}->{$a}=$p; +# $ecanonical{$castcell}->{$a}=$a; +# $ecanonical{$cell}->{$a}=$a; +# } + # convert .d[#] to .# + $revlookup{$castcell}->{$a}=$p; + $revlookup{$cell}->{$a}=$p; + if ($a =~ /\.\d+$/) { + $p =~ s/\.d\[(\d+)\]$/.$1/; + } + $rcanonical{$castcell}->{$a}=$p; + $rcanonical{$cell}->{$a}=$p; +# $realchannel{$castcell}->{$a}=$p; +# $realchannel{$cell}->{$a}=$p; + my $done=$isenable; + while (! $done and $p ne "" and $a ne "") { + my $ps=""; + if ($p =~ s/\.([^\.]+)$//) { + $ps = $1; + } + my $as=""; + if ($a =~ s/\.([^\.]+)$//) { + $as = $1; + } + if ($as eq $ps and $as ne "") { + $realchannel{$castcell}->{$a}=$p; + $realchannel{$cell}->{$a}=$p; + $realchannel{$castcell}->{$p}=$p; + $realchannel{$cell}->{$p}=$p; +# $ecanonical{$castcell}->{$a}=$a; +# $ecanonical{$cell}->{$a}=$a; +# $ecanonical{$castcell}->{$p}=$a; +# $ecanonical{$cell}->{$p}=$a; + } + else { + $done=1; + } + } + # arrays +# $p =~ s/(\[.*\])$//; +# my $ps=$1; +# $a =~ s/(\[.*\])$//; +# my $cs=$1; +# if ($cs eq $ps and $cs ne "") { +# $ecanonical{$castcell}->{$a}=$a; +# $ecanonical{$cell}->{$a}=$a; +# $ecanonical{$castcell}->{$p}=$a; +# $ecanonical{$cell}->{$p}=$a; +# $realchannel{$castcell}->{$a}=$p; +# $realchannel{$cell}->{$a}=$p; +# $realchannel{$castcell}->{$p}=$p; +# $realchannel{$cell}->{$p}=$p; +# } + } + } + close P; + open (P, "<$requeryfile"); + while (

    ) { + chomp; + print STDERR "getports: query $cell" if $. == 1 and $debug; + if (! /^[01] /) { + my ($p,$a)=split; + $realport{$cell}->{$a}=1; + $realport{$castcell}->{$a}=1; + $realport{$cell}->{$p}=1; + $realport{$castcell}->{$p}=1; + } + } + close P; + open (P, "<$mapqueryfile"); + while (

    ) { + chomp; + my ($v,$c)=split; + $v2c{$cell}->{$v}=$c; + $v2c{$castcell}->{$v}=$c; + $c2v{$cell}->{$c}=$v; + $c2v{$castcell}->{$c}=$v; + # convert verilog names of subcell to cast names of subcell + if (defined $ecanonical{$cell}->{$c}) { + $ecanonical{$cell}->{$v}=$ecanonical{$cell}->{$c}; + $ecanonical{$castcell}->{$v}=$ecanonical{$cell}->{$c} if $castcell ne $cell; + } + else { + print STDERR "Error: no defined canonical cast port $c from $mapqueryfile"; + } + } + close P; + } + else { + print STDERR "Info: No cast cell $castcell, no query done" + if $verbose; + close P; + } + if (@ports || @implied) { + $castfound{$cell}=[@castlines]; + $castfound{$castcell}=[@castlines] if $castcell ne $cell; + $ports{$cell}=[@ports]; + $ports{$castcell}=[@ports] if $castcell ne $cell; + $implied{$cell}=[@implied]; + $implied{$castcell}=[@implied]; + if ($cell eq $porttopcell) { + foreach my $port (sort keys %aliasedports) { + push @aliasedports, $aliasedports{$port} + if $aliasedports{$port} =~ / /; + } + } + print STDERR "getports (query) $cell" if $debug; + return 1; + } + } + my $shortname = $castcell; + $shortname =~ s/.*\.//; + # keep the port order from the verilog + if (defined ($moduleports{$shortname})) { + $ports{$cell}=$moduleports{$shortname}; + $ports{$castcell}=$ports{$cell} if $castcell ne $cell; + print STDERR "getports (short) $cell" if $debug; + return 1; + } + if (defined ($moduleports{$castcell})) { + $ports{$cell}=$moduleports{$castcell}; + $ports{$castcell}=$ports{$cell} if $castcell ne $cell; + print STDERR "getports (castcell) $cell" if $debug; + return 1; + } + if (defined ($moduleports{$cell})) { + $ports{$cell}=$moduleports{$cell}; + $ports{$castcell}=$ports{$cell} if $castcell ne $cell; + print STDERR "getports (cell) $cell" if $debug; + return 1; + } + print STDERR "Error: getports: No defined SUBCKT nor cast for $castcell"; + $errors++; + 0; +} + +my @speclines=(); +my @castlines=(); + +foreach my $top (sort keys %modules) { + # do not do external modules + next if $external{$top}; + my %isport=(); + my %iswire=(); + my $castcell="$library.$top"; + my $st = $subtype; + if ($top =~ /\./) { + $castcell = $top; + $castcell =~ s/\.([^\.]+)$//; + $st = $1; + $st = $subtype if $subtypedefined and $cdc_mode; + } + elsif ("$library.$top" eq "$argcell") { + $st = $argsubtype; + } + my $tc = "$castcell.$st"; + # dump the existing cdc modules + next if !$cdc_mode and $tc =~ /^lib\.synchronous\.conversion\.v3\./; + if ($cdc_mode) { + my @castcell=split(/\./, $castcell); + $castcell="$library.$castcell[$#castcell]"; + } + push @speclines, "module $castcell;\n"; + push @castlines, "module $library;\n"; + foreach my $im (@addimport) { + push @speclines, "import $im;"; + push @castlines, "import $im;"; + } + push @speclines, "" if @addimport; + push @castlines, "" if @addimport; + my $ltc=$tc; + $tc =~ /.*\.([^\.]+)\.([^\.]+)$/; + if (defined ($2) and $2 eq $st) { + $ltc = $1; + } + $castcell =~ /\.([^\.]+)$/; + my $cname=$1; + my $istop=0; + if ($wrap <= 0 or ($ltc ne $arg and $tc ne $arg)) { + push @speclines, "define \"$st\"() ("; + push @castlines, "define \"$cname\"() ("; + $istop=1; + } + else { + push @speclines, "define \"a\"() ("; + push @castlines, "define \"${cname}_a\"() ("; + } + my $ptc=$tc; + $ptc = $argparent if defined $argparent; + $ptc = $portbase if $portbase ne ""; + $porttopcell=$ptc; + getports($ptc); + $localmodule=$ptc; + foreach my $mp (@{$ports{$ptc}},@{$implied{$ptc}}) { + next if ! defined $mp; + my ($t,$p)=@{$mp}; + if (defined($channeldefs{$t})) { + foreach my $ch (@{$channeldefs{$t}}) { + my $cha=$ch; + $cha =~ s/\.d\[(\d+)\]$/.$1/; + if (defined $verilog{$p.$cha}) { + my $v=$verilog{$p.$cha}; + $v =~ s/\[.*//; + $v =~ s/\..*//; + print STDERR "ISP 1 $v" if $debug; + $isport{$v}=1; + print STDERR "ISP 2 $verilog{$p.$cha}" if $debug; + $isport{$verilog{$p.$cha}}=1; + } + elsif (defined ($verilog{$p.$ch})) { + my $v=$verilog{$p.$ch}; + $v =~ s/\[.*//; + $v =~ s/\..*//; + print STDERR "ISP 2 $v" if $debug; + $isport{$v}=1; + print STDERR "ISP 4 $verilog{$p.$ch}" if $debug; + $isport{$verilog{$p.$ch}}=1; + } + } + } + elsif (defined ($verilog{$p})) { + my $v=$verilog{$p}; + $v =~ s/\[.*//; + $v =~ s/\..*//; + print STDERR "ISP 5 $v" if $debug; + $isport{$v}=1; + print STDERR "ISP 6 $p" if $debug; + $isport{$verilog{$p}}=1; + } + print STDERR "ISP 7 $p" if $debug; + $isport{$p}=1; + } + if ($tc =~ /^$library/) { + foreach my $mp (@extra_ports) { + my ($t,$n,$d)=@{$mp}; + push @{$ports{$tc}}, $mp; + print STDERR "ISP 8 $n" if $debug; + $isport{$n}=1; + } + foreach my $mp (@extra_implied) { + my ($t,$n,$d)=@{$mp}; + push @{$implied{$tc}}, $mp; + print STDERR "ISP 9 $n" if $debug; + $isport{$n}=1; + } + if (! $isport{Vdd}) { + $isport{Vdd}=1; + push @{$implied{$tc}}, ["node", "Vdd", "-"]; + } + if (! $isport{GND}) { + $isport{GND}=1; + push @{$implied{$tc}}, ["node", "GND", "-"]; + } + } + undef %specialnodes; + %specialnodes=(); + if (defined ($castfound{$ptc})) { + # print cast header from cast information, most accurate + my @plines=@{$castfound{$ptc}}; + foreach my $pn (1..$#plines-1) { + push @speclines, "$plines[$pn];"; + push @castlines, "$plines[$pn];"; + } + push @speclines, "$plines[$#plines]"; + push @castlines, "$plines[$#plines]"; + my $parent; + if (defined ($argparent)) { + $parent = $argparent; + } + else { + $parent = $tc; + $parent =~ s/\.[^\.]+$//; + } + if ($istop) { + if ($cast_and_spec) { + push @speclines, " ) <+ routed <: $castcell \x7b"; + } + elsif ($cdc_mode) { + push @speclines, " ) <+ routed <: $refineparent \x7b"; + } + else { + push @speclines, " ) <+ routed <: $parent \x7b"; + } + } + else { + if ($cast_and_spec) { + push @speclines, " ) <+ unrouted <: ${castcell}_a \x7b"; + } + elsif ($cdc_mode) { + push @speclines, " ) <+ unrouted <: $refineparent \x7b"; + } + else { + push @speclines, " ) <+ unrouted <: $parent \x7b"; + } + } + if ($istop and $extra_refine ne "") { + push @castlines, " ) <+ ".join(" <+ ", split(/,/,$extra_refine))." <: $parent \x7b"; + } + else { + push @castlines, " ) <: $parent \x7b"; + } + } + else { + # find ports from cdl, not accurate, but is all we have left. + foreach my $mp (@{$ports{$ptc}}) { + next if ! defined $mp; + my ($type,$port,$d)=@{$mp}; + my $dir = "+-"; + $dir = $d if defined $d; + $dir = $portdirection{"$top $port"} + if defined ($portdirection{"$top $port"}); + # ports sorted by name and by array index + my $nm = $port; + $nm =~ s/\[.*//; + my $nv = $port; + $nv =~ s/.*\[//; + $nv =~ s/\]//; + $type = typerename($type); + my $port1=fix_node($port, __LINE__); + if ($type =~ /node\[/ and $port1 =~ /\[/) { + $specialnodes{$port1} = special($port1); + $port1=$specialnodes{$port1}; + } + if ($type =~ /^\[/) { + push @speclines, " node $dir$port1$type;"; + push @castlines, " node $dir$port1$type;"; + } + else { + push @speclines, " $type $dir$port1;"; + push @castlines, " $type $dir$port1;"; + } + } + $speclines[$#speclines] =~ s/;$//; + $castlines[$#castlines] =~ s/;$//; + push @speclines, " ) <+ synchronous <+ unrouted <: $refineparent \x7b"; + push @castlines, " ) <+ synchronous <: $refineparent \x7b"; + } + # subcells block + if ($cast_and_spec) { + push @speclines, " subtypes \x7b"; + push @castlines, " [~SlackerSkipProteusSubcells -> subcells \x7b"; + } + else { + push @speclines, " subcells \x7b"; + push @castlines, " subcells \x7b"; + } + if ( -s "$extranodes" and $tc eq $arg) { + open (XT, "<$extranodes"); + print STDERR "Reading $extranodes" if $progress; + while () { + chomp; + push @castlines, $_; + push @speclines, $_ if ! $cast_and_spec; + } + close XT; + } + my @temp; + my %localaliasedports=(); + foreach my $aliases (@aliasedports) { + my (@f)=split(/ /, $aliases); + my $canon=shift @f; + $localaliasedports{$canon}=1; + foreach my $name (@f) { + $localaliasedports{$name}=1; + push @temp, " $name=$canon;"; + } + } + if ($cast_and_spec) { + push @castlines, @temp; + } + else { + push @speclines, @temp; + } + undef @temp; + # node declarations + foreach my $wd (@{$wiretypes{$top}}) { + my ($type,$name)=@{$wd}; + $iswire{$name}=1 if ! $isport{$name}; + $type = typerename($type); + $name=fix_node($name, __LINE__); + if ($type =~ /node\[/ and $name =~ /\[/) { + $specialnodes{$name} = special($name); + $name=$specialnodes{$name}; + } + if ($type =~ /^\[/) { + push @castlines, " node $name$type;"; + push @speclines, " node $name$type;" if ! $cast_and_spec; + } + else { + push @castlines, " $type $name;"; + push @speclines, " $type $name;" if ! $cast_and_spec; + } + } + if (defined $assign{$top}) { + # the first part of this is to fix a situation + # which should not occur in a final netlist + my %declare=(); + my %arr=(); + foreach my $assign (sort @{$assign{$top}}) { + my ($var,$val)=split(/=/,$assign); + $var = fix_node($var, __LINE__); + $val = fix_node($val, __LINE__); + my $svar = $var; + $svar =~ s/\[.*//; + my $pvar=$var; + $pvar =~ s/_l.*//; + if (! $iswire{$svar} and ! $iswire{$var} and ! $isport{$var} and ! $isport{$svar} and ! $isport{$pvar}) { + $declare{$var}=1; + } + $svar = ""; + my $osvar=""; + foreach $var (sort keys %declare) { + next if (defined($ecanonical{$localmodule}->{$var})); + $svar = $var; + $svar =~ s/\[(\d+)\]$//; + my $ndx = $1; + if ($svar ne $var) { + if (defined ($arr{$svar})) { + $arr{$svar} = $ndx+1 if $arr{$svar} < $ndx+1; + } + else { + $arr{$svar} = $ndx+1; + } + } + } + } + foreach my $arr (sort keys %arr) { + push @castlines, " node[$arr{$arr}] $arr;"; + push @speclines, " node[$arr{$arr}] $arr;" if ! $cast_and_spec; + } + foreach my $declare (sort keys %declare) { + push @castlines, " node $declare;" + if (! $declare =~ /\[\d+\]$/); + push @speclines, " node $declare;" + if (! $declare =~ /\[\d+\]$/) and ! $cast_and_spec; + } + # this is the normal part + foreach my $assign (sort @{$assign{$top}}) { + my ($a,$b)=split(/=/, $assign); + $a = fix_node($a, __LINE__); + $b = fix_node($b, __LINE__); + my $psignal=$a; + $psignal =~ s/_l_.*//; + $psignal =~ s/\..*//; + if ($isport{$psignal}) { + print STDERR "FSP 1 $psignal" if $debug; + my $signal2=$a; + $signal2 =~ s/_l_/[/g; + $signal2 =~ s/_r_/]/g; + $signal2 =~ s/\]\[/,/g; + # trap false port detection + $signal2 =~ /\]([^\]]+)$/; + $a = $signal2 if ! defined($1) or $1 eq ""; + $a=$castname{$a} if defined $castname{$a}; + } + else { + print STDERR "NSP 1 $psignal" if $debug; + } + $psignal=$b; + $psignal =~ s/_l_.*//; + $psignal =~ s/\..*//; + if ($isport{$psignal}) { + print STDERR "FSP 2 $psignal" if $debug; + my $signal2=$b; + $signal2 =~ s/_l_/[/g; + $signal2 =~ s/_r_/]/g; + $signal2 =~ s/\]\[/,/g; + # trap false port detection + $signal2 =~ /\]([^\]]+)$/; + $b = $signal2 if ! defined($1) or $1 eq ""; + $b=$castname{$b} if defined $castname{$b}; + } + else { + print STDERR "NSP 2 $psignal" if $debug; + } + $assign = "$a=$b"; + push @castlines, " $assign;"; + push @speclines, " $assign;" if ! $cast_and_spec; + } + } + # instance calls + my $dummycnt=100001; + my $dummystart=$dummycnt; + my %dummytypes=(); + foreach my $itype (@{$inst{$top}}) { + my ($mod,$vinst)=split(/:/,$itype); + $dummystart=$dummycnt; + my $inst = fix_inst($vinst); + my $type = $type{$itype}; + next if ignore_cell($type); + if (! ($type =~ /\./)) { + if (defined ($sxref{$type})) { + $type = $sxref{$type}; + } + else { + $type = "$library.$type.$subtype"; + } + } + getports($type); + my %lsignal=(); + if (defined $v2c{$type}) { + foreach my $key (keys %{$signal{$itype}}) { + if (defined $v2c{$type}->{$key}) { + $lsignal{$itype}->{$v2c{$type}->{$key}}=$signal{$itype}->{$key}; + print STDERR "Defined port $key in $type $v2c{$type}->{$key}" if $debug; + } + else { + # maybe it is a verilog array + my $n=0; + for ($n = 0; defined $v2c{$type}->{"$key\[$n\]"}; $n++) { + $lsignal{$itype}->{$v2c{$type}->{"$key\[$n\]"}} = "$signal{$itype}->{$key}\[$n\]"; + print STDERR "Defined port $key\[$n\] in $type ".$v2c{$type}->{"$key\[$n\]"} if $debug; + } + if ($n == 0) { print STDERR "Undefined port $key in $type";} + } + } + %{$signal{$itype}}=%{$lsignal{$itype}}; + } + if ( ! defined $ports{$type} ) { + print STDERR "Error: Cannot find port list for $type"; + $errors++; + } + my @portlines=(); + my $basetype = $type; + $basetype =~ s/\.\d[^\.]*$//; + if ($cast_and_spec) { + push @portlines, " $basetype $inst("; + push @speclines, " $basetype :>"; + push @speclines, " $type $inst;"; + } + else { + push @portlines, " $type $inst("; + } + # for debugging only + my $test=0; + my %dassign=(); + my %net=map { split /=/ } @{$pins{$itype}}; + my %aliasesadded=(); + foreach my $pl (@{$ports{$type}}) { + my ($ty,$pt2,$d)=@{$pl}; + $pt2 =~ s/^[-+]//; + $ty = typerename($ty); + my $found=0; + my $auxfound=0; + my $pt = $pt2; + if ($ty eq "node") { # could still be problems for channels + if (defined ($ecanonical{$basetype}->{$pt2})) { + $pt = $ecanonical{$basetype}->{$pt2}; + } + else { + print STDERR "Warning: no canonical name for $pt2 in $basetype"; + $warnings++; + } + } + my $s = getbindsignal($type, $inst, $pt2, ""); + if ($s ne "") { + $found=1; + $auxfound=1; + $net{$pt}=$s; + push @portlines, " $net{$pt}, // $ty $pt"; + } + if (! $found) { + # order is important here, so use the array + foreach my $p (@{$pins{$itype}}) { + my ($port,$signal)=split(/=/,$p); + my $pa = $port; + $pa =~ s/\[.*//; + $pa =~ s/\..*$//; + $net{$port}=$signal; + $auxfound = 1 if $port eq $pt or $pa eq $pt or $port eq $pt2 or $pa eq $pt2; + next if $port ne $pt and $port ne $pt2; + my $port1=fix_node($port, __LINE__); + $found=1; + print STDERR "CPT 1 $signal $isport{$signal}" if $debug; + if ($iswire{$signal}) { + $signal=fix_node($signal, __LINE__); + } + elsif (! ($signal =~ /\x7b/) and $tc eq $arg and defined ($castname{$signal})) { + if (($signal ne $castname{$signal}) and + (($isport{$signal} and $isport{$castname{$signal}}) or (! $isport{$signal} and ! $isport{$castname{$signal}}))) { + $signal = $castname{$signal}; + print STDERR "CPT 1a $signal $isport{$signal}" if $debug; + } + } + $signal =~ s/^1'b1$/Vdd/g; + $signal =~ s/^1'b0$/GND/g; + if ($signal =~ /'b/) { + if ($signal =~ /\x7b/) { + my $sig=$signal; + $sig =~ s/[ ,\x7b\x7d]+/ /g; + $sig =~ s/^ //; + $sig =~ s/ $//; + $signal="\x7b"; + my @s=split(/ /, $sig); + $signal .= btolist($s[0]); + foreach my $n (1..$#s) { + $signal .= ", "; + $signal .= btolist($s[$n]); + } + $signal .= " \x7d"; + } + else { + $signal = "\x7b".btolist($signal)."\x7d"; + } + } + # reverse order of arrays + if ($signal =~ /\x7b/) { + $signal =~ s/[ ,\x7b\x7d]+/ /g; + $signal =~ s/^ //; + $signal =~ s/ $//; + my @signal=(); + my @s=split(/ /,$signal); + foreach my $s (@s) { + if ( $s =~ /(.*)\[(\d+):(\d+)\]$/) { + my $name=$1; + my $e=$2; + my $b=$3; + if ($b <= $e ) { + for (my $n = $e; $n >= $b; $n--) { + push @signal, "$name\[$n\]"; + } + } + else { + for (my $n = $e; $n <= $b; $n++) { + push @signal, "$name\[$n\]"; + } + } + } + else { + push @signal,$s; + } + } + foreach my $s (@signal) { + print STDERR "CPT 2 $s $isport{$s}" if $debug; + if ($iswire{$s}) { + $s = fix_node($s, __LINE__); + } + elsif (! ($s =~ /\x7b/) and $tc eq $arg and defined ($castname{$s})) { + if (($s ne $castname{$s}) and + (($isport{$s} and $isport{$castname{$s}}) or (! $isport{$s} and ! $isport{$castname{$s}}))) { + $s = $castname{$s}; + print STDERR "CPT 2a $s $isport{$s}" if $debug; + } + $s = $castname{$s}; + } + } + my $fxsig; + if ($#signal > 0) { + $fxsig = fix_node($signal[$#signal], __LINE__); + push @portlines, " \x7b $fxsig, "; + for (my $i = $#signal-1; $i > 0; $i--) { + $fxsig = fix_node($signal[$i], __LINE__); + push @portlines, " $fxsig,"; + } + $fxsig = fix_node($signal[0], __LINE__); + push @portlines, " $fxsig \x7d, // $ty $port1"; + } + else { + $fxsig = fix_node($signal[0], __LINE__); + push @portlines, " \x7b $fxsig \x7d, // $ty $port1"; + } + } + else { + my $signal1=fix_node($signal, __LINE__); + my $psignal=$signal1; + $psignal =~ s/_l_.*//; + $psignal =~ s/\..*//; + print STDERR "CPT 3 $psignal $isport{$psignal}" if $debug; + if ($isport{$psignal}) { + my $signal2=$signal1; + $signal2 =~ s/_l_/[/g; + $signal2 =~ s/_r_/]/g; + $signal2 =~ s/\]\[/,/g; + # trap false port detection + $signal2 =~ /\]([^\]]+)$/; + $signal1 = $signal2 if ! defined($1) or $1 eq ""; + $signal1=$castname{$signal1} if defined $castname{$signal1}; + } + if ($signal1 =~ /(.*)\[(\d+):(\d+)\]$/) { + my $name=$1; + my $start=$3; + my $end=$2; + my @arr=(); + for (my $n = $start; $n <= $end; $n++) { + push @arr, "$name\[$n\]"; + } + push @portlines, " \x7b"; + push @portlines, " ".join(",\n ", @arr); + push @portlines, " \x7d, // $port1"; + } + else { + push @portlines, " $signal1, // $port1"; + } + } + last; + } + } + if (! $found) { + if ($pt eq "VDD10") { + push @portlines, " Vdd, // $ty $pt"; + } + elsif ($pt eq "VSS10") { + push @portlines, " GND, // $ty $pt"; + } + else { + my $pt1=fix_node($pt2, __LINE__); + my $tysuffix=""; + my $typrefix=$ty; + if ($typrefix =~ s/\[(\d+)\.\.(\d+)\]$//) { + $tysuffix="[$1..$2]"; + } + elsif ($typrefix =~ s/\[(\d+)\.\.(\d+),(\d+)\.\.(\d+)\]$//) { + $tysuffix="[$1..$2,$3..$4]"; + } + my $portchannelcount=0; + my $portchannelconnect=0; + my $portchannel=""; + my $print = 0; + if (defined($channeldefs{$ty})) { + my $match=0; + my $chcnt=0; + my @chlines=(); + my $sigroot=""; + foreach my $ch (@{$channeldefs{$ty}}) { + $chcnt++; + my $lm=0; + $portchannelcount++; + my $portmatch=0; + my $lastsignal; + my $cha = $ch; + $cha =~ s/\.d$/.0/; + $cha =~ s/\.d\[(\d+)\]$/.$1/; + my $ctype=$type; + $ctype=~s/\.[^\.]+$//; + my $ec=$ecanonical{$ctype}->{"$pt2$ch"}; + $ec = "" if ! defined $ec; + my $eca=$ecanonical{$ctype}->{"$pt2$cha"}; + $eca = "" if ! defined $eca; + my $signal=undef; + my $port=undef; + if (defined($signal{$itype}->{$pt2.$ch})) { + $port=$pt2.$ch; + } + elsif (defined($signal{$itype}->{$pt2.$cha})) { + $port=$pt2.$cha; + } + elsif (defined($signal{$itype}->{$ec})) { + $port=$ec; + } + elsif (defined($signal{$itype}->{$eca})) { + $port=$eca; + } + if (defined($port)) { + $signal = $signal{$itype}->{$port}; + $signal = "Vdd" if $signal eq "1'b1"; + $signal = "GND" if $signal eq "1'b0"; + print STDERR "CPT 4 $signal $isport{$signal}" if $debug; + if ($iswire{$signal}) { + $signal = fix_node($signal, __LINE__); + } + elsif (! ($signal =~ /\x7b/) and ! $isport{$signal} and $tc eq $arg) { + $signal=$castname{$signal} if defined $castname{$signal}; + $signal=$castname{"$signal\[0\]"} if defined $castname{"$signal\[0\]"}; + } + $lastsignal=$signal; + $sigroot="" if (! defined ($sigroot)); + my $chroot=$signal; + $chroot =~ s/\.[^\.]+$//; + $chroot =~ s/\]\[/,/g; + if ($sigroot eq "") { + $sigroot = substr($signal,0,length($signal)-length($ch)); + } + if (substr($signal,0,length($signal)-length($ch)) eq $sigroot) { + $match++; + } + if (($portchannel eq "" or $portchannel eq $chroot)) { + $portchannelconnect++; + $portchannel = $chroot if $portchannel eq ""; + $portmatch=1; + } + $signal=fix_node($signal, __LINE__); + $signal = $castname{$signal} if defined $castname{$signal}; + push @chlines, " dummy$dummycnt$ch=$signal;"; + $lm=1; + } + my $ps=$lastsignal; + $ps =~ s/\.[^\.]+$//; + if (! $lm) { + if ($ps eq $portchannel) { + if ($lastsignal eq "") { + my $sig="dummy$dummycnt$ch"; + push @chlines, "// unconnected $sig"; + push @chlines, " $sig=GND;" if ! defined $aliasesadded{$sig}; + $aliasesadded{$sig}=1; + } + else { + push @chlines, "// unconnected $lastsignal $portchannel"; + push @chlines, " $lastsignal=GND;" if ! defined $aliasesadded{$lastsignal}; + $aliasesadded{$lastsignal}=1; + } + } + elsif ((! defined($realport{$ctype}->{"$pt2$ch"}) and $eicount{$ctype}->{$ec} == 0) or $cpdirection{$ctype}->{"$pt2$ch"} eq "-") { + push @chlines, "// unconnected node $pt2$ch of $basetype"; + # only for inputs, bidi and outputs ignored, bug 14646 + push @chlines, " dummy$dummycnt$ch=GND;"; + } + elsif ( $cpdirection{$ctype}->{"$pt2$ch"} ne "-") { + push @chlines, "// unconnected node $pt2$ch of $basetype"; + } + else { + push @chlines, "// unconnected node $pt2$ch of $basetype"; + print STDERR "Error: unconnected $pt2$ch of $basetype"; + $errors++; + } + } + } + print STDERR "CDEF $ty $match=$chcnt $sigroot ".join(',',@{$channeldefs{$ty}}) if $debug; + if ($portchannelcount != $portchannelconnect or 1) { + push @castlines, " $typrefix dummy$dummycnt$tysuffix;"; + push @speclines, " $typrefix dummy$dummycnt$tysuffix;" if ! $cast_and_spec; + push @castlines, @chlines; + push @speclines, @chlines if ! $cast_and_spec; + push @portlines, " dummy$dummycnt, // $ty $pt1"; + $auxfound=1; + } + else { + push @portlines, " $portchannel, // $ty $pt1"; + $dummycnt--; + } + } + elsif ( $ty =~ /^node\[(\d+)(?:\.\.(\d+))?\]$/ ) { + # todo try to match up node arrays to ports + push @portlines, " dummy$dummycnt, // $ty $pt1"; + push @castlines, " $typrefix dummy$dummycnt$tysuffix;"; + push @speclines, " $typrefix dummy$dummycnt$tysuffix;" if ! $cast_and_spec; + $auxfound=1; + my ($al, $ah) = ($1, $2); + if (!defined($ah)) { + $ah = $al - 1; + $al = 0; + } + for (my $n = $al; $n <= $ah; $n++) { + my $ch = "\[$n\]"; + foreach my $p (@{$pins{$itype}}) { + my ($port,$signal)=split(/=/,$p); + $signal = "Vdd" if $signal eq "1'b1"; + $signal = "GND" if $signal eq "1'b0"; + print STDERR "CPT 5 $signal $isport{$signal}" if $debug; + if ($iswire{$signal}) { + $signal=fix_node($signal, __LINE__); + } + elsif (! ($signal =~ /\x7b/) and ! $isport{$signal} and $tc eq $arg) { + $signal=$castname{$signal} if defined $castname{$signal}; + $signal=$castname{"$signal\[0\]"} if defined $castname{"$signal\[0\]"}; + } + if ($port eq "$pt2$ch") { + my $fxname=fix_node($signal, __LINE__); + $fxname =~ s/\$/_/g; + $fxname = $castname{$fxname} if defined $castname{$fxname}; + push @castlines, " dummy$dummycnt$ch=$fxname;"; + push @speclines, " dummy$dummycnt$ch=$fxname;" if ! $cast_and_spec; + last; + } + } + } + } + elsif (! ($ty =~ /^node$/)) { + # todo try to match up nodes to ports, but may already be done! + push @portlines, " dummy$dummycnt, // $ty $pt1"; + push @castlines, " $typrefix dummy$dummycnt$tysuffix;"; + push @speclines, " $typrefix dummy$dummycnt$tysuffix;" if ! $cast_and_spec; + print STDERR "NDEF1 $ty $itype $inst" if $debug; + $auxfound=1; + } + else { + push @portlines, " dummy$dummycnt, // $ty $pt1"; + push @castlines, " $typrefix dummy$dummycnt$tysuffix;"; + push @speclines, " $typrefix dummy$dummycnt$tysuffix;" if ! $cast_and_spec; + print STDERR "NDEF2 $ty $itype $inst" if $debug; + $auxfound=1; + } + $dummycnt++; + } + } + print STDERR "Warning: port $pt2 may not be connected in $type:$itype" + if $warning and ! $auxfound; + $warnings++ if ! $auxfound; + } + $portlines[$#portlines] =~ s/,\s/ /; + # need implied ports + if (defined ($implied{$type})) { + my @imp=(); + my $allmatch=1; + foreach my $ip (@{$implied{$type}}) { + my ($it, $in1, $id)=@{$ip}; + $it = typerename($it); + $in1 = "aclk" if ($in1 eq "debug_ack"); #HACK + # implied ports may be explictily connected + my $in = $in1; + if ($it eq "node") { + if (defined ($ecanonical{$basetype}->{$in1})) { + $in = $ecanonical{$basetype}->{$in1}; + } + else { + print STDERR "Warning: no canonical name for $in1 in $basetype"; + $warnings++; + } + } + my $s = getbindsignal($type, $inst, $in1, ""); + my $bound=0; + if ($s ne "") { + $net{$in}=$s; + $bound=1; + } + print STDERR "CPT 6 $in $isport{$in}" if $debug; + if (defined $net{$in}) { + if ($bound) { + push @imp, $net{$in}; + } + else { + my $signal1=$net{$in}; + if ($signal1 =~ /(.*)\[(\d+)\]\.(.*)/) { + $signal1 = "${1}_l_${2}_r__D_${3}"; + } + elsif ($signal1 =~ /(.*)\[(\d+)\](.*)/) { + $signal1 = "${1}_l_${2}_r_${3}"; + } + $signal1 = $castname{$signal1} + if (defined ($castname{$signal1})); + push @imp, fix_node($signal1, __LINE__); + } + $allmatch=0; + } + # implied ports are connected by name + elsif ($isport{$in} or $iswire{$in}) { + $in = $castname{$in} + if (defined ($castname{$in})); + push @imp, fix_node($in, __LINE__); + } + # verilog does not have power pins + elsif ($in eq "Vdd" or $in eq "GND") { + push @imp, $in; + } + # special case power names + elsif ($in eq "VDD") { + push @imp, "Vdd"; + $allmatch=0; + } + elsif ($in eq "vss" or $in eq "VSS") { + push @imp, "GND"; + $allmatch=0; + } + # everything else + else { + $allmatch=0; + push @castlines, " $it dummy$dummycnt;"; + push @speclines, " $it dummy$dummycnt;" if ! $cast_and_spec; + push @imp, "dummy$dummycnt /* $in */"; + $dummycnt++; + } + } + if ($allmatch) { + push @portlines, " );"; + } + else { + push @portlines, " )(".join(", ",@imp).");"; + } + } + else { + push @portlines, " );"; + } + if ($cast_and_spec) { + push @castlines,@portlines; + } + else { + push @speclines,@portlines; + } + @portlines=(); + } + # end subcells/subtypes + my @subcells_directives_data=(); + my @cell_directives_data=(); + my $fh; + if (open ($fh, "<$directives_file")) { + print STDERR "Reading $directives_file" if $verbose; + while (<$fh>) { + chomp; + s/\\//g; + if (/^\s*(extra_delay|slew_signoff|skew_signoff)\(\s*(.*)\)\s*=\s*(.*)\s*;$/ ) { + my $directive=$1; + my $node = $2; + my $delay = $3; + $node =~ s/\\//g; + $node =~ s/\s//g; + if ($node =~ /\//) { + $node =~ m/(.*)\/(.*)/; + my $tail=$2; + my $inst=$1; + # the directive instances are not proper verilog instances + $inst =~ s/,/][/g; + $inst = fix_inst($inst); + $node = $inst.".".$tail; + my $inode=nodecad2cast($node); + $node = $inode if $inode ne ""; + } + else { + $node=fix_node($node, __LINE__); + my $inode=nodecad2cast($node); + $node = $inode if $inode ne ""; + } + push @subcells_directives_data, "$directive($node)=$delay;"; + } + elsif (/^\s*delaybias\s*\(\s*(\S+)\s*\)\s*=\s*(\S+)\s*;/) { + my $inst = fix_inst($1); + my $value= $2; + push @subcells_directives_data, "delaybias($inst)=$value;" + if $value != 1; + } + elsif (/^\s*slacker_leaf\s*=\s*(\S+)\s*;/) { + push @cell_directives_data, "slacker_leaf=$1;" + if $istop; + } + elsif (/^\s*(slacker_time|slacker_alignment|slacker_ignore)\s*\(\s*(\S+)\s*\)\s*=\s*(\S+)\s*;/) { + my $dir=$1; + my $channel=$2; + my $value=$3; + $channel =~ s/\]\[/,/g; + $channel = $realchannel{$localmodule}->{$channel} if defined $realchannel{$localmodule}->{$channel}; + push @cell_directives_data, "$dir($channel)=$value;" + if $istop; + } + } + close $fh; + } + if (@subcells_directives_data) { + if ($cast_and_spec) { + push @castlines, " directives \x7b"; + foreach my $line (@subcells_directives_data) { + push @castlines, " $line"; + } + push @castlines, " \x7d"; + } + else { + push @speclines, " directives \x7b"; + foreach my $line (@subcells_directives_data) { + push @speclines, " $line"; + } + push @speclines, " \x7d"; + } + } + push @speclines, " \x7d"; + if ($cast_and_spec) { + push @castlines, " \x7d]"; + } + else { + push @castlines, " \x7d"; + } + # end module + push @cell_directives_data, "proteus_tag = $proteus_tag;"; + if (@cell_directives_data) { + if ($cast_and_spec) { + push @castlines, " directives \x7b"; + foreach my $line (@cell_directives_data) { + push @castlines, " $line"; + } + push @castlines, " \x7d"; + if ($wrap == 0) { + push @speclines, " directives \x7b"; + push @speclines, " fixed_size = true;"; + push @speclines, " \x7d"; + } + } + else { + push @speclines, " directives \x7b"; + push @speclines, " fixed_size = true;"; + foreach my $line (@cell_directives_data) { + push @speclines, " $line"; + } + push @speclines, " \x7d"; + } + } + push @speclines, "\x7d"; + push @castlines, "\x7d"; +} +## wrappers for canonicalization issues +my $char = 97; +for(; $wrap > 0; $wrap--) { + # do not do external modules + my $top = $arg; + $char++; + my %isport=(); + my %iswire=(); + my $castcell="$library.$top"; + my $st = $subtype; + if ($top =~ /\./) { + $castcell = $top; + $castcell =~ s/\.([^\.]+)$//; + $st = $1; + } + elsif ("$library.$top" eq "$argcell") { + $st = $argsubtype; + } + my $tc = "$castcell.$st"; + # dump the existing cdc modules + push @speclines, "module $castcell;\n"; + push @castlines, "module $library;\n"; + foreach my $im (@addimport) { + push @speclines, "import $im;"; + push @castlines, "import $im;"; + } + push @speclines, "" if @addimport; + push @castlines, "" if @addimport; + $castcell =~ /\.([^\.]+)$/; + my $cname = $1; + my $istop=0; + if ($wrap == 1) { + push @speclines, "define \"$st\"() ("; + push @castlines, "define \"$cname\"() ("; + $istop=1; + } + else { + push @speclines, sprintf "define \"%c\"() (", $char; + push @castlines, sprintf "define \"${cname}_%c\"() (", $char; + } + my $ptc=$tc; + $ptc = $argparent if defined $argparent; + $ptc = $portbase if $portbase ne ""; + getports($ptc); + foreach my $mp (@{$ports{$ptc}}) { + my ($t,$p,$d)=@{$mp}; + print STDERR "ISP 9 $p" if $debug; + $isport{$p}=1; + } + foreach my $mp (@{$implied{$ptc}}) { + my ($t,$p,$d)=@{$mp}; + print STDERR "ISP 10 $p" if $debug; + $isport{$p}=1; + } + if ($tc =~ /^$library/) { + if (! $isport{Vdd}) { + $isport{Vdd}=1; + $isport{GND}=1; + push @{$implied{$tc}}, ["node", "Vdd", "-"]; + push @{$implied{$tc}}, ["node", "GND", "-"]; + } + } + if (defined ($castfound{$ptc})) { + print STDERR "Cast Found for $ptc" if $verbose; + # print cast header from cast information, most accurate + my @plines=@{$castfound{$ptc}}; + foreach my $pn (1..$#plines-1) { + push @speclines, "$plines[$pn];"; + push @castlines, "$plines[$pn];"; + } + push @speclines, "$plines[$#plines]"; + push @castlines, "$plines[$#plines]"; + my $parent; + if ( defined ($argparent) ) { + $parent = $argparent; + } + else { + $parent = $tc; + $parent =~ s/\.[^\.]+$//; + } + if ($wrap == 1) { + if ($cast_and_spec) { + push @speclines, " ) <+ routed <: $castcell \x7b"; + } + else { + push @speclines, " ) <+ routed <: $parent \x7b"; + } + } + else { + if ($cast_and_spec) { + push @speclines, sprintf " ) <+ unrouted <: ${castcell}_%c \x7b", $char; + } + else { + push @speclines, " ) <+ unrouted <: $parent \x7b"; + } + } + if ($istop and $extra_refine ne "") { + push @castlines, " ) <+ ".join(" <+ ", split(/,/,$extra_refine))." <: $parent \x7b"; + } + else { + push @castlines, " ) <: $parent \x7b"; + } + } + else { + # find ports from cdl, not accurate, but is all we have left. + foreach my $mp (@{$ports{$tc}}) { + my ($type,$port,$d)=@{$mp}; + my $dir = "+-"; + $dir = $d if defined $d; + $dir = $portdirection{"$top $port"} + if defined ($portdirection{"$top $port"}); + # ports sorted by name and by array index + my $nm = $port; + $nm =~ s/\[.*//; + my $nv = $port; + $nv =~ s/.*\[//; + $nv =~ s/\]//; + $type = typerename($type); + my $port1=fix_node($port, __LINE__); + if ($type =~ /node\[/ and $port1 =~ /\[/) { + $specialnodes{$port1} = special($port1); + $port1=$specialnodes{$port1}; + } + if ($type =~ /^\[/) { + push @speclines, " node $dir$port1$type;"; + push @castlines, " node $dir$port1$type;"; + } + else { + push @speclines, " $type $dir$port1;"; + push @castlines, " $type $dir$port1;"; + } + } + $speclines[$#speclines] =~ s/;$//; + $castlines[$#castlines] =~ s/;$//; + push @speclines, " ) <+ synchronous <+ unrouted <: $refineparent \x7b"; + push @castlines, " ) <+ synchronous <: $refineparent \x7b"; + } + # subcells block + if ($cast_and_spec) { + push @speclines, " subtypes \x7b"; + } + else { + push @speclines, " subcells \x7b"; + } + push @castlines, " subcells \x7b"; + if ($cast_and_spec) { + push @castlines, sprintf " ${castcell}_%c z(", $char-1; + push @speclines, sprintf " ${castcell}_%c :> \n". + " ${castcell}.%c z;", $char-1, $char-1; + } + else { + push @speclines, sprintf " $castcell.%c z(", $char-1; + } + my @plines=(); + @plines=@{$castfound{$ptc}} if defined ($castfound{$ptc}); + if (@plines) { + my $ln; + foreach my $pn (1..$#plines-1) { + $ln = $plines[$pn]; + $ln =~ s/^ *//; + $ln =~ s/^[a-z].* //; + $ln =~ s/[-+]//; + $ln =~ s/\[[^\]]+\]//; + push @speclines, " $ln," + if ! $cast_and_spec; + push @castlines, " $ln,"; + } + $ln = $plines[$#plines]; + $ln =~ s/^ *//; + $ln =~ s/^[a-z].* //; + $ln =~ s/[-+]//; + $ln =~ s/\[[^\]]+\]//; + push @speclines, " $ln" + if ! $cast_and_spec; + push @castlines, " $ln"; + } + else { + # find ports from cdl, not accurate, but is all we have left. + my @pl=(); + foreach my $mp (@{$ports{$tc}}) { + my ($type,$port,$d)=@{$mp}; + my $dir = "+-"; + $dir = $d if defined $d; + $dir = $portdirection{"$top $port"} + if defined ($portdirection{"$top $port"}); + # ports sorted by name and by array index + my $nm = $port; + $nm =~ s/\[.*//; + my $nv = $port; + $nv =~ s/.*\[//; + $nv =~ s/\]//; + $type = typerename($type); + my $port1=fix_node($port, __LINE__); + if ($type =~ /node\[/ and $port1 =~ /\[/) { + $specialnodes{$port1} = special($port1); + $port1=$specialnodes{$port1}; + } + push @pl, $port1; + } + push @speclines, " ".join(",\n ",@pl); + push @castlines, " ".join(",\n ",@pl); + } + push @speclines, " );" if ! $cast_and_spec; + push @castlines, " );"; + # end subcells + my @subcells_directives_data=(); + my @cell_directives_data=(); + my $fh; + if (open ($fh, "<$directives_file")) { + print STDERR "Reading $directives_file" if $verbose; + while (<$fh>) { + chomp; + s/\\//g; + if (/^\s*(extra_delay|slew_signoff|skew_signoff)\(\s*(.*)\)\s*=\s*(.*)\s*;$/ ) { + my $directive=$1; + my $node = $2; + my $delay = $3; + $node =~ s/\\//g; + $node =~ s/\s//g; + if ($node =~ /\//) { + $node =~ m/(.*)\/(.*)/; + my $tail=$2; + my $inst=$1; + # the directive instances are not proper verilog instances + $inst =~ s/,/][/g; + $inst = fix_inst($inst); + $node = $inst.".".$tail; + my $inode=nodecad2cast($node); + $node = $inode if $inode ne ""; + } + else { + $node=fix_node($node, __LINE__); + my $inode=nodecad2cast($node); + $node = $inode if $inode ne ""; + } + push @subcells_directives_data, "$directive($node)=$delay;"; + } + elsif (/^\s*delaybias\s*\(\s*(\S+)\s*\)\s*=\s*(\S+)\s*;/) { + my $inst = fix_inst($1); + my $value= $2; + push @subcells_directives_data, "delaybias($inst)=$value;" + if $value != 1; + } + elsif (/^\s*slacker_leaf\s*=\s*(\S+)\s*;/) { + push @cell_directives_data, "slacker_leaf=$1;" + if $istop; + } + elsif (/^\s*(slacker_time|slacker_alignment|slacker_ignore)\s*\(\s*(\S+)\s*\)\s*=\s*(\S+)\s*;/) { + my $dir=$1; + my $channel=$2; + my $value=$3; + $channel =~ s/\]\[/,/g; + $channel = $realchannel{$localmodule}->{$channel} if defined $realchannel{$localmodule}->{$channel}; + push @cell_directives_data, "$dir($channel)=$value;" + if $istop; + } + } + close $fh; + } + if (@subcells_directives_data) { + if ($cast_and_spec) { + push @castlines, " directives \x7b"; + foreach my $line (@subcells_directives_data) { + push @castlines, " $line"; + } + push @castlines, " \x7d"; + } + else { + push @speclines, " directives \x7b"; + foreach my $line (@subcells_directives_data) { + push @speclines, " $line"; + } + push @speclines, " \x7d"; + } + } + push @speclines, " \x7d"; + push @castlines, " \x7d"; + # end module + if (@cell_directives_data) { + if ($cast_and_spec) { + if (@cell_directives_data) { + push @castlines, " directives \x7b"; + foreach my $line (@cell_directives_data) { + push @castlines, " $line"; + } + push @castlines, " \x7d"; + if ($wrap == 1) { + push @speclines, " directives \x7b"; + push @speclines, " fixed_size = true;"; + push @speclines, " \x7d"; + } + } + else { + push @speclines, " directives \x7b"; + push @speclines, " fixed_size = true;"; + foreach my $line (@cell_directives_data) { + push @speclines, " $line"; + } + push @speclines, " \x7d"; + } + } + } + push @speclines, "\x7d"; + push @castlines, "\x7d"; +} +## end wrappers +if ($debug) { + my $fd; + open ($fd, ">castlines.cast"); + print $fd join("\n", @castlines); + close $fd; + open ($fd, ">speclines.cast"); + print $fd join("\n", @castlines); + close $fd; +} + +## create cast file +if ($cast_and_spec) { + if ($castlines[0] =~ /^module\s+(.*)\s*;/) { + my $dir=$1; + $dir =~ s/\./\//g; + $dir =~ s/\/([^\/]+)$//; + $dir = "$castdir/$dir"; + my $file = $1.".cast"; + system("mkdir","-p",$dir) if ! -d $dir; + my $fh; + if (open ($fh, ">$dir/$file")) { + print STDERR "Writing $dir/$file" if $verbose; + cast_header ($fh); + print $fh "$castlines[0]\n"; + my $abstractlibrary=$argparent; + $abstractlibrary =~ s/\.[^\.]+$//; + if ($abstractlibrary eq $library) { + my $fx; + $outputfile =~ /\.([^\.]+)\.cast$/; + my $cell=$1; + my $cmd= "image2cast"; + $cmd .= " --cell='$cell'"; + $cmd .= " --base='ABSTRACT_$cell'"; + $cmd .= " '${cell}.qdi_image.v'"; + print STDERR $cmd if $verbose; + open $fx, "$cmd |"; + while (<$fx>) { + chomp; + print $fh $_; + } + close $fx; + print $fh ""; + } + for (my $n = 1; $n <= $#castlines; $n++) { + print $fh $castlines[$n] if ! ($castlines[$n] =~ /^module/); + } + close $fh; + } + else { + print STDERR "Error: failed to create $dir/$file"; + $errors++; + } + } + else { + print STDERR "Error: internal error: poorly formed castlines"; + $errors++; + } +} +foreach my $line (@speclines) { +# $line =~ s/_r__l_/_c_/g; + $_=$line; + if (/^module/) { + domodule(0); + $mname = $_; + chomp $mname; + $mname =~ s/;$//; + $mname =~ s/.* //; + } + $_=$line; + $portlist = 0 if /$xcell.instxref"); +mkdir "cast2skill"; +open ($fxril, ">cast2skill/$xcell.instmap.il"); +print STDERR "Writing cast2skill/$xcell.instmap.il" if $verbose; +print STDERR "Writing $xcell.instxref" if $verbose; +my $ic=0; +my $ci=100000; +foreach my $inst (sort keys %instlookup) { + if ($ci > 4000) { + if ($ic > 0) { + print $fxril " Table ) )\n"; + } + $ic++; + print $fxril "(defun PinInstXrefTable$ic ( )"; + print $fxril " (let ("; + print $fxril " ( Table ( makeTable `pd nil ) ) )"; + $ci=0; + } + my $ixref=instcast2cad($prefix.$instlookup{$inst}); + print $fxr "$inst $prefix$instlookup{$inst}"; + print $fxril " ( setarray Table \"$inst\" \"$ixref\" )"; + $ci++; +} +close $fxr; +print $fxril " Table ) )\n"; +print $fxril "(defun PinInstXrefTable ( )"; +print $fxril " (let ( Key map"; +print $fxril " ( Table ( makeTable `pd nil ) ) )"; +for (my $n = 1; $n <= $ic; $n++) { + print $fxril " map = PinInstXrefTable$n( )"; + print $fxril " foreach( Key map"; + print $fxril " ( setarray Table Key arrayref( map Key ) ) )"; +} +print $fxril " Table ) )"; +close $fxril; +open ($fxr, ">$xcell.nodexref"); +open ($fxril, ">cast2skill/$xcell.nodemap.il"); +print STDERR "Writing $xcell.nodexref" if $verbose; +print STDERR "Writing cast2skill/$xcell.nodemap.il" if $verbose; +my $ic=0; +my $ci=100000; +foreach my $node (sort keys %nodexref) { + if ($ci > 4000) { + if ($ic > 0) { + print $fxril " Table ) )\n"; + } + $ic++; + print $fxril "(defun PinNodeXrefTable$ic ( )"; + print $fxril " (let ("; + print $fxril " ( Table ( makeTable `pd nil ) ) )"; + $ci=0; + } + # cannot translate these names to cadence names because they have '$' in them! + my $n1=$node; + my $n2=$nodexref{$node}; + print $fxr "$node $nodexref{$node}"; + print $fxril " ( setarray Table \"$n1\" \"$n2\" )"; + $ci++; +} +close $fxr; +print $fxril " Table ) )\n"; +print $fxril "(defun PinNodeXrefTable ( )"; +print $fxril " (let ( Key map"; +print $fxril " ( Table ( makeTable `pd nil ) ) )"; +for (my $n = 1; $n <= $ic; $n++) { + print $fxril " map = PinNodeXrefTable$n( )"; + print $fxril " foreach( Key map"; + print $fxril " ( setarray Table Key arrayref( map Key ) ) )"; +} +print $fxril " Table ) )"; +close $fxril; + +open ($fxr, ">$porttopcell.rcanon"); +open ($fxril, ">cast2skill/$porttopcell.rcanon.il"); +print STDERR "Writing $porttopcell.rcanon" if $verbose; +print STDERR "Writing cast2skill/$porttopcell.rcanon.il" if $verbose; +my $ic=0; +my $ci=100000; +my %x=(); +my $ptc=$porttopcell; +$ptc =~ s/\.\d[^\.]*$//; +%x=%{$revlookup{$porttopcell}} if defined $revlookup{$ptc}; +foreach my $node (sort keys %x) { + if ($ci > 4000) { + if ($ic > 0) { + print $fxril " Table ) )\n"; + } + $ic++; + print $fxril "(defun PinRevCanonicalTable$ic ( )"; + print $fxril " (let ("; + print $fxril " ( Table ( makeTable `pd nil ) ) )"; + $ci=0; + } + my $n1=nodecast2cad($node); + my $n2=nodecast2cad($x{$node}); + print $fxr "$node $x{$node}"; + print $fxril " ( setarray Table \"$n1\" \"$n2\" )"; + $ci++; +} +close $fxr; +print $fxril " Table ) )\n"; +print $fxril "(defun PinRevCanonicalTable ( )"; +print $fxril " (let ( Key map"; +print $fxril " ( Table ( makeTable `pd nil ) ) )"; +for (my $n = 1; $n <= $ic; $n++) { + print $fxril " map = PinRevCanonicalTable$n( )"; + print $fxril " foreach( Key map"; + print $fxril " ( setarray Table Key arrayref( map Key ) ) )"; +} +print $fxril " Table ) )"; +close $fxril; + +END { + if ($cast_server_pid) { + close CCin; + close CCOut; + close CCErr; + kill 9, $cast_server_pid; +# waitpid $cast_server_pid, 0; + } + if ($apid) { + kill 9, $apid; +# waitpid $apid, 0; + } + print STDERR "Warning count: $warnings" if $warnings; + print STDERR "Error count: $errors" if $errors; + exit $errors; +} +exit $errors; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2et.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2et.pl new file mode 100755 index 0000000000..74b9a4eba1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/perl/vs2et.pl @@ -0,0 +1,232 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +my %options; +my $verilog; +my $topcell; + +GetOptions ( %options ) or die; +$topcell = shift; +$verilog = shift; + +if ($verilog =~ /gz$/) { + open (P, "gunzip -c '$verilog' |"); +} +else { + open (P, "<$verilog"); +} +$/ = "\n"; +my @assign=(); +my @lines=(); +my @statements=(); +my $state=0; +while (

    ) { + chomp; + push @lines, $_; + if (/^module.*$topcell/) { + $state = 1; + } + if ($state == 1 and /^endmodule/) { + last; + } +} +close P; +my $statement=""; +my $module=0; +foreach my $line (@lines) { + if ($line =~ /^module.*$topcell/) { + $module = 1; + } + if ($line =~ /^endmodule/) { + $module=0; + } + if ($module) { + $statement .= $line; + if ($statement =~ /;\s*$/) { + $statement =~ s/\s+/ /g; + $statement =~ s/;\s*$//; + $statement =~ s/^ //; + push @statements, $statement; + $statement=""; + } + } + else { + $statement=""; + } +} +my %needassign = ( + "SCAN_OUT" => ["output [7:0]","SO%d"], + "SCAN_MODE" => ["input","+TI"], + "SCAN_IN" => ["input [7:0]","SI%d"], + "SCAN_IDL" => ["input [7:0]","-TI"], + "SCAN_EN" => ["input","+SE"], + "MODULE_RESET_N" => ["input","+SC"], + "CORE_RESET_N" => ["input","+SC"], + "CLK" => ["input","-ES"], + "CDC_RESET_N" => ["input","+SC"], +); +my $statement=$statements[0]; +$statement =~ s/\(/ ( /g; +$statement =~ s/\)/ ) /g; +$statement =~ s/,\s*/ /g; +my @f=split(/ /,$statement); +shift @f; # module +shift @f; # topcell +shift @f; # lparen +pop @f; # rparen +my %ports=(); +foreach my $port (@f) { + $ports{$port}=1; +} +my %trace=(); +foreach my $statement (@statements) { + $_ = $statement; + if (/av_/ and (/buf/ or /delay/)) { + s/\(/ ( /g; + s/\)/ ) /g; + s/\s+/ /g; + my $out; + my $in; + my @f=split; + foreach my $n (0..$#f) { + if ($f[$n] eq ".Q") { + $out = $f[$n+2]; + } + elsif ($f[$n] eq ".A") { + $in = $f[$n+2]; + } + } + $in =~ s/\s//g; + $out =~ s/\s//g; + $trace{$in}=$out; + } + if (/lib.dft.converter.SYNC_CONVERTER_ARRAY_8.1000/) { + s/\n/ /g; + s/\s+/ /g; + s/^[^\(]*\(//; + my @ports = split(/,/); + my @pl=(); + my $line = ""; + for( my $n=0; $n <= $#ports; $n++) { + my $assign=$ports[$n]; + $assign =~ s/^\s*//; + $line = $assign; + while (! ($line =~ /\)/)) { + $n++; + $line .= ", $ports[$n]"; + } + push @pl, $line; + } + foreach my $pl (@pl) { + my ($port,$wire)=split(/\(/,$pl); + $port =~ s/^\.//; + $port =~ s/\s+$//; + $wire =~ s/\)+\s*$//g; + s/ */ /g; + push @assign, " assign $port = $wire;" if ! ($port =~ /\\/) and defined($needassign{$port}); + } + } +} +my @newports=(); +foreach my $port (sort keys %needassign) { + push @newports, $port if (! $ports{$port}); +} +my $doassign=1; +$module=0; +for( my $n = 0; $n <= $#lines; $n++) { + while ($lines[$n] =~ /^\s*$/) { + $n++; + } + $_ = $lines[$n]; + if (/^module.*lib.synchronous/) { + while (! ($lines[$n] =~ /^endmodule/)) { + $n++; + } + next; + } + if (/^module.*$topcell/) { + $module=1; + } + if ($module == 1 and /;/) { + s/\);\s*$//; + $_ .= ", ".join(" , ", @newports)." );"; + $module=2; + print; + foreach my $port (@newports) { + print " $needassign{$port}[0] $port;"; + } + next; + } + if (/lib.dft.converter.SYNC_CONVERTER_ARRAY_8.1000/) { + while ( ! ($lines[$n] =~ /;/)) { + print "// $lines[$n]"; + $n++; + } + print "// $lines[$n]"; + next; + } + if ($doassign and $module == 2 and /\(/) { + print join ("\n", @assign); + print ""; + $doassign=0; + } + print; +} +# find valid scan +my @in; +my @out; +foreach my $as (@assign) { + if ($as =~ /SCAN_IN/) { + $as =~ s/,/ /g; + $as =~ s/\s+/ /g; + $as =~ s/\x7d;//; + @in = split(/ /,$as); + while (@in and $in[0] ne "\x7b") { + shift @in; + } + shift @in; + } + if ($as =~ /SCAN_OUT/) { + $as =~ s/,/ /g; + $as =~ s/\s+/ /g; + $as =~ s/\x7d;//; + @out = split(/ /,$as); + while (@out and $out[0] ne "\x7b") { + shift @out; + } + shift @out; + } +} +sub trace { + my $in = $_[0]; + $in =~ s/\s//g; + while (defined ($trace{$in})) { + $in = $trace{$in}; + } + $in; +} + +my @valid; +foreach my $n (0..$#in) { + my $out = trace($in[$n]); + $valid[7-$n]=1 if $out ne $out[$n]; + $valid[7-$n]=0 if $out eq $out[$n]; +} +open (P, ">x.pinassign"); +select P; +foreach my $port (sort keys %needassign) { + if ($needassign{$port}[0] =~ /:/) { + foreach my $n (0..7) { + printf "assign pin=$port\[%d\]\ttest_function= $needassign{$port}[1];\n", + $n, $n if $valid[$n]; + } + } + else { + print "assign pin=$port\ttest_function= $needassign{$port}[1]"; + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/getlibs b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/getlibs new file mode 100755 index 0000000000..221a05615c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/getlibs @@ -0,0 +1,30 @@ +#!/bin/sh +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + + +cell_list_file= + + +command_args= +for arg in $@ ; do + case "$arg" in + --cell-list=* ) + cell_list_file=`echo $arg | sed -e "s/--cell-list=//"` + ;; + esac +done + + +if [ -n "$cell_list_file" ] ; then + + if [ -f "$cell_list_file" ] ; then + cat $cell_list_file | sed -e "s/\.[^\.]\+\$//" -e "s/\.[^\.]\+\$//" | sort | uniq + else + echo "\"$cell_list_file\" is not a file." + fi +else + echo "Usage: $0 --cell-list=file" +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslib b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslib new file mode 100755 index 0000000000..a777995dc2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslib @@ -0,0 +1,157 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +function usage() { + echo "$0 --cds-wd=dir --generated-libraries-root=dir" + echo " --blank-cds-library=dir --lib=libname" + echo " --cadence-shell-library=dir" +} + +sedcmd=`which sed` +grepcmd=`which grep` +gawkcmd=`which gawk` +findcmd=`which find` + +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$grepcmd" "Unable to find grep in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Unable to find gawk in \"$PATH\"" 2 +check_executable_file "$findcmd" "Unable to find find in \"$PATH\"" 2 + +cds_wd= +generated_libs_root= +blank_cds_library= +lib= +cds_sh_lib= + +for arg in $@ ; do + + case "$arg" in + --cds-wd=* ) + cds_wd=`echo $arg | $sedcmd -e "s/--cds-wd=//"` + ;; + --generated-libraries-root=* ) + generated_libs_root=`echo $arg | $sedcmd -e "s/--generated-libraries-root=//"` + ;; + --blank-cds-library=* ) + blank_cds_library=`echo $arg | $sedcmd -e "s/--blank-cds-library=//"` + ;; + --lib=* ) + lib=`echo $arg | $sedcmd -e "s/--lib=//"` + ;; + --cadence-shell-library=* ) + cds_sh_lib=`echo $arg | $sedcmd -e "s/--cadence-shell-library=//"` + ;; + esac +done + + +check_for_empty_arg "$cds_wd" "You must specify the cadence working directory." 2 +check_for_empty_arg "$generated_libs_root" "A generated libraries root directory was not specified." 2 +check_for_empty_arg "$blank_cds_library" "A directory containing a blank cadence library was not specified." 2 +check_for_empty_arg "$lib" "\"$cell\"'s library was not specified." 2 +check_for_empty_arg "$cds_sh_lib" "You must specify the location of the cadence shell script library." 2 + +check_writeable_dir "$cds_wd" "Cadence Working Directory: \"$cds_wd\" is not a readable, writeable directory." 2 +conon_path "$cds_wd" +cds_wd="$ret" + +check_writeable_dir "$generated_libs_root" \ + "Generated Libraries Root Directory: \"$generated_libs_root\" is not a readable, writeable directory." 2 +conon_path "$generated_libs_root" +generated_libs_root="$ret" + +check_readable_dir "$blank_cds_library" \ + "Blank Cadence Library: \"$blank_cds_library\" is not a readable directory." 2 +conon_path "$blank_cds_library" +blank_cds_library="$ret" + +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +conon_path "$cds_sh_lib" +cds_sh_lib="$ret" + +cds_sh_lib_files=`$findcmd "$cds_sh_lib" \! -type d` +for file in $cds_sh_lib_files ; do + source "$file" +done + +get_escaped_library_name_for_library "$lib" +escaped_lib_name="$ret" + +cds_lib_generated="$generated_libs_root/cds.lib.generated" + +lib_exists_already= +if [ -f "$cds_lib_generated" ] ; then + existing_cds_lib_libs=`$grepcmd -ve "--" $cds_lib_generated | $grepcmd -e "^DEFINE" | $gawkcmd -- "{ print \\\$2 }"` + for existing_lib in $existing_cds_lib_libs ; do + if [[ "$escaped_lib_name" == "$existing_lib" ]] ; then + lib_exists_already=1 + fi + done +fi + +cds_lib="$cds_wd/cds.lib" + +if [ -f "$cds_lib" ] ; then + existing_cds_lib_libs=`$grepcmd -ve "--" $cds_lib | $grepcmd -e "^DEFINE" | $gawkcmd -- "{ print \\\$2 }"` + for existing_lib in $existing_cds_lib_libs ; do + if [[ "$escaped_lib_name" == "$existing_lib" ]] ; then + lib_exists_already=1 + fi + done +fi + +if [ -z "$lib_exists_already" ] ; then + get_library_dir_for_libraray "$lib" "$generated_libs_root" + newlibdir="$ret" + + escaped_generated_libs_root=`echo "$generated_libs_root" | $sedcmd -e "s/\//\\\\\\\\\\//g"` + + relative_new_lib_dir=`echo "$newlibdir" | $sedcmd -e "s/$escaped_generated_libs_root\///g"` + + cds_lib_entry="DEFINE $escaped_lib_name $relative_new_lib_dir" + + if [ ! -d "$newlibdir" ] ; then + libparentdir=`dirname $newlibdir` + if [ ! -d "$libparentdir" ]; then + mkdir -p "$libparentdir" + fi + cp -a "$blank_cds_library" "$newlibdir" + $findcmd "$newlibdir" -print0 | xargs -0 chmod u+w + else + dirs_in_blank=`(cd "$blank_cds_library" ; $findcmd . -type d)` + files_in_blank=`(cd "$blank_cds_library" ; $findcmd . -type f)` + for dir in $dirs_in_blank ; do + dir=`echo "$dir" | $sedcmd -e "s:^./:$newlibdir/:"` + if [ ! -d "$dir" ]; then + mkdir -p "$dir" + chmod u+w "$dir" + fi + done + for file in $files_in_blank ; do + nfile=`echo "$file" | $sedcmd -e "s:^./:$newlibdir/:"` + file=`echo "$file" | $sedcmd -e "s:^./:$blank_cds_library/:"` + if [ ! -f "$nfile" ]; then + cp -p "$file" "$nfile" + chmod u+w "$nfile" + fi + done + fi + + echo "$cds_lib_entry" >>$cds_lib_generated + +fi + +cds_lib_generated_base=`basename $cds_lib_generated` + +cds_lib_tmp=`mktemp /tmp/ensurecelllib.XXXXXX` +if [ -f "$cds_lib" ] ; then + cat $cds_lib | \ + $grepcmd -ve "^SOFTINCLUDE[[:space:]]\+.*$cds_lib_generated_base" >$cds_lib_tmp +fi +echo "SOFTINCLUDE $cds_lib_generated" >>$cds_lib_tmp +cp $cds_lib_tmp $cds_lib +rm $cds_lib_tmp diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslibs b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslibs new file mode 100755 index 0000000000..8a5db1fbad --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/lib_commands/mkcdslibs @@ -0,0 +1,126 @@ +#!/bin/sh +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +sedcmd=`which sed` +findcmd=`which find` + +# commented out as of today +#check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +#check_executable_file "$findcmd" "Unable to find find in \"$PATH\"" 2 +if [ ! -x "$sedcmd" ]; then + echo "Unable to find sed in \"$PATH\"" + exit 2 +fi +if [ ! -x "$findcmd" ]; then + echo "Unable to find find in \"$PATH\"" + exit 2 +fi + +function usage() { + echo "$0 --cell-list=cell_list_file --target-cds-root=root_dir_to_contain_generated_libs --cds-wd=cds_wd --blank-lib=template_lib" +} +cell_list_file= +target_cds_root= +cds_wd= +blank_lib= + +command_args= +for arg in $@ ; do + case "$arg" in + --cell-list=* ) + cell_list_file=`echo $arg | sed -e "s/--cell-list=//"` + ;; + --target-cds-root=* ) + target_cds_root=`echo $arg | sed -e "s/--target-cds-root=//"` + ;; + --cds-wd=* ) + cds_wd=`echo $arg | sed -e "s/--cds-wd=//"` + ;; + --blank-lib=* ) + blank_lib=`echo $arg | sed -e "s/--blank-lib=//"` + ;; + esac +done + + +if [[ -n "$cell_list_file" && -n "$target_cds_root" && -n "$cds_wd" && -n "$blank_lib" ]] ; then + if [ -f "$cell_list_file" ] ; then + + if [[ -d "$target_cds_root" && -w "$target_cds_root" ]] ; then + pushd "$target_cds_root" >/dev/null + target_cds_root=`pwd` + popd >/dev/null + + if [[ -d "$cds_wd" && -r "$cds_wd" ]] ; then + pushd "$cds_wd" >/dev/null + cds_wd=`pwd` + popd >/dev/null + + if [[ -d "$blank_lib" && -r "$blank_lib" ]] ; then + pushd "$blank_lib" >/dev/null + blank_lib=`pwd` + popd >/dev/null + + libnames=`cat $cell_list_file | sed -e "s/\.[^\.]\+\$//" -e "s/\.[^\.]\+\$//" | sort | uniq` + + cds_lib_generated="$target_cds_root/cds.lib.generated" + + if [ -f "$cds_lib_generated" ] ; then + rm "$cds_lib_generated" + fi + + for lib in $libnames ; do + parentlib=`echo $lib | sed -e "s/\.[^\.]\+\$//"` + if [ -n "$parentlib" ] ; then + libparentdir=`echo $parentlib | sed -e "s/\./\\//g"` + if [ ! -d "$target_cds_root/$libparentdir" ] ; then + mkdir -p "$target_cds_root/$libparentdir" + fi + newlibdir=$target_cds_root/$libparentdir/$lib + if [ ! -d "$newlibdir" ] ; then + cp -a "$blank_lib" "$newlibdir" + else + dirs_in_blank=`(cd "$blank_lib" ; $findcmd . -type d)` + files_in_blank=`(cd "$blank_lib" ; $findcmd . -type f)` + for dir in $dirs_in_blank ; do + dir=`echo "$dir" | $sedcmd -e "s:^./:$newlibdir/:"` + if [ ! -d "$dir" ]; then + mkdir -p "$dir" + chmod u+w "$dir" + fi + done + for file in $files_in_blank ; do + nfile=`echo "$file" | $sedcmd -e "s:^./:$newlibdir/:"` + file=`echo "$file" | $sedcmd -e "s:^./:$blank_lib/:"` + if [ ! -f "$nfile" ]; then + cp -p "$file" "$nfile" + chmod u+w "$nfile" + fi + done + fi + escaped_lib_name=`echo $lib | sed -e "s/\./#2e/g"` + echo "DEFINE $escaped_lib_name $newlibdir" >>$cds_lib_generated + else + echo "\"$lib\" is not a valid library name." + fi + done + + else + echo "\"$blank_lib\" is not a readable library directory." + fi + else + echo "\"$cds_wd\" is not a readable directory." + fi + else + echo "\"$target_cds_root\" is not a writeable directory." + fi + else + echo "\"$cell_list_file\" is not a file." + fi +else + usage + exit 2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/custom.mk b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/custom.mk new file mode 100644 index 0000000000..4132fca367 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/custom.mk @@ -0,0 +1,10 @@ +# Copyright 2003 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +CURR_RESULT_FILES := $(CURR_RESULT_FILES) $(CURR_TARGET_DIR)/updatenetlist.sh + + +$(CURR_TARGET_DIR)/updatenetlist.sh: $(CURR_PROJECT_DIR)/updatenetlist.sh + cat $< | $(GNUSED) -e "s/\\\$$buildid\\\$$/$(FULCRUM_BUILD_ID)/" >$@ diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/density.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/density.sh new file mode 100755 index 0000000000..2728e83f51 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/density.sh @@ -0,0 +1,207 @@ +#!/bin/bash +<. +DOC + +input= +output= +cds_wd= +cds_wd_template=$CDS_WD_TEMPLATE +debug= + + +function exit_func() { + if [[ $debug != t ]] ; then + [ -d "$cds_wd" ] && rm -rf "$cds_wd" + [ -f "$input" ] && rm -f "$input" + [ -f "$output" ] && rm -f "$output" + fi +} + +trap exit_func EXIT + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} + +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" + +# +##### Parse arguments ##### +# + +function usage() { + cat< ... +USAGE +} + +sedcmd=`which sed` +bashcmd=`which bash` +grepcmd=`which grep` + +check_executable_file "$grepcmd" "Unable to find grep in \"$PATH\"" 2 +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$bashcmd" "Unable to find bash in \"$PATH\"" 2 + +cell_list= +view= +fulcrum_pdk_root= +working_dir= +dfII_dir= +cds_wd= +transistor_base_width=0.0 +debug=nil + +for arg in $@ ; do + case "$arg" in + --fulcrum-pdk-root=* ) + fulcrum_pdk_root=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --view=* ) + view=`echo $arg | $sedcmd -e "s/--view=//"` + ;; + --lib=* ) + lib=`echo $arg | $sedcmd -e "s/--lib=//"` + ;; + --transistor-base-width=* ) + transistor_base_width=`echo $arg | $sedcmd -e "s/--transistor-base-width=//"` + ;; + --dfII-dir=* ) + dfII_dir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --working-dir=* ) + working_dir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; + --debug ) + debug=t + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + cell_list="$cell_list $arg" + ;; + esac +done + +check_for_empty_arg "$package_root" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$view" \ + "The view name must be specified." 2 +check_for_empty_arg "$transistor_base_width" \ + "The transistor base width (in meters) must be specified." 2 +check_for_empty_arg "$fulcrum_pdk_root" \ + "The fulcrum pdk root mist be specified." 2 + +check_readable_dir "$fulcrum_pdk_root" \ + "Fulcrum PDK: \"$fulcrum_pdk_root\" is not a readable directory." 2 +conon_path "$fulcrum_pdk_root" +fulcrum_pdk_root="$ret" + + +check_for_empty_arg "$working_dir" \ + "An NFS working dir must be speciified." 2 +check_for_empty_arg "$dfII_dir" \ + "A dfII dir must be speciified." 2 + +check_readable_dir "$working_dir" \ + "NFS working dir: \"$working_dir\" is not a readable directory." 2 +conon_path "$working_dir" +working_dir="$ret" + +check_readable_dir "$dfII_dir" \ + "dfII dir: \"$dfII_dir\" is not a readable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +cds_wd=$(mktemp -d "$working_dir/cds_wd.XXXXXX") + +mkcdswd="$arch_bin_dir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +$mkcdswd "--dfII-dir=$dfII_dir" \ + "--fulcrum-pdk-root=$fulcrum_pdk_root" \ + "--cast-path=foo" \ + "--target-dir=$cds_wd" \ + "--force" \ + "--user-template=$cds_wd_template" +cd "$cds_wd" + +cells="" +for cell in $cell_list ; do + cells="$cells \"$cell\"" +done + +input="$cds_wd/input" +output="$cds_wd/output" + +cat<< EOF > "$input" +(load "$package_root/share/skill/autoload.il") +(load "$fulcrum_pdk_root/share/Fulcrum/pdkinfo.il") +(when $debug + ilToolBox() + ilDebugToolBox() + ilDebugToolBoxForm->autoStacktrace->value = "16" + hiCloseWindow(ilDebugToolBoxWindow) ) + +(let ( + ( Output ( outfile "$output" ) ) ) + ( foreach CellName ( list $cells ) + (let ( + ( LibName + (cond ( + ( not ( equal "" "$lib" ) ) + "$lib" ) + ( + ( car + ( NameParseCellName + CellName ) ) ) ) ) ) + (let ( + ( DDObj ( ddGetObj + LibName + CellName + "$view" ) ) ) + (cond ( + ( and + DDObj + ( ddIsObjReadable DDObj ) ) + ( fprintf + Output + "%s\n" + ( DensityFactorVerboseUsingPDKInfo + ( dbOpenCellViewByType + LibName + CellName + "$view" + nil + "r" ) + $transistor_base_width ) ) ) + ( + ( fprintf Output "%s %s %s doesn't exist...did you use cadence names? Try rename --from=cast --to=cadence --type=cell\n" + LibName + CellName + "$view" ) ) ) ) ) ) + ( close Output ) ) +(exit) +EOF + +cdsLog="$cds_wd/CDS.log" + +$cmd layout -nograph -replay "$input" -log "$cdsLog" /dev/null + +[[ $? == 0 ]] || cat "$cdsLog" +cat "$output" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/dfIIflat2tree.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/dfIIflat2tree.sh new file mode 100755 index 0000000000..2674a8c814 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/dfIIflat2tree.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" + +function usage() { + echo Usage: `basename $0` + echo " --src-dfII-lib-dir=dir" + echo " --dest-dfII-dir=dir" + echo " --fulcrum-pdk-root=dir" + echo " [--force]" + echo " [--dest-view=autorouted]" + echo " [--src-view=routed]" +} + +function exit_func() { + if [ -d "$cmd_tmp_dir" ] ; then + rm -rf "$cmd_tmp_dir" + fi +} + +trap exit_func EXIT + +sedcmd=`which sed` +bashcmd=`which bash` +grepcmd=`which grep` + +check_executable_file "$grepcmd" "Unable to find grep in \"$PATH\"" 2 +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$bashcmd" "Unable to find bash in \"$PATH\"" 2 + +source "$package_root/share/script/sh/util/parsecellname" + +src_dfII_lib_dir= +dest_dfII_dir= +force= +dest_view="autorouted" +src_view="routed" +fulcrumPDKRoot= + +for arg in $@ ; do + + case "$arg" in + --force ) + force=1 + ;; + --dest-dfII-dir=* ) + dest_dfII_dir=`echo $arg | $sedcmd -e "s/--dest-dfII-dir=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrumPDKRoot=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --src-dfII-lib-dir=* ) + src_dfII_lib_dir=`echo $arg | $sedcmd -e "s/--src-dfII-lib-dir=//"` + ;; + --dest-view=* ) + dest_view=`echo $arg | $sedcmd -e "s/--dest-view=//"` + ;; + --src-view=* ) + src_view=`echo $arg | $sedcmd -e "s/--src-view=//"` + ;; + --* ) + echo "Unknown option \"$arg\"." + usage + exit 2 + ;; + esac +done + +check_for_empty_arg "$package_root" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$dest_dfII_dir" \ + "You must specify the destination dfII dir" 2 +check_for_empty_arg "$src_dfII_lib_dir" \ + "You must specify the dfII lib dir from the run" 2 +check_for_empty_arg "$fulcrumPDKRoot" \ + "You must specify the location of the fulcrum PDK package installation." 2 + +check_readable_dir "$fulcrumPDKRoot" \ + "Fulcrum PDK: \"$fulcrumPDKRoot\" is not a readable directory." 1 +conon_path "$fulcrumPDKRoot" +fulcrumPDKRoot="$ret" + +check_readable_dir "$src_dfII_lib_dir" \ + "src dfII lib: \"$src_dfII_lib_dir\" is not a readable directory." 2 +conon_path "$src_dfII_lib_dir" +src_dfII_lib_dir="$ret" + +check_writeable_dir "$dest_dfII_dir" \ + "dest dfII dir: \"$dest_dfII_dir\" is not a readable, writeable, directory." 1 +conon_path "$dest_dfII_dir" +dest_dfII_dir="$ret" + +blank_lib="$fulcrumPDKRoot/share/Fulcrum/blank-library" + +dfII_cell_dirs=`find $src_dfII_lib_dir -maxdepth 1 -mindepth 1 -type d -printf "%P\n"` + +for dfII_cell_dir in $dfII_cell_dirs ; do + cadence_reverse_escape_string $dfII_cell_dir + cell=$ret + used= + + get_cadence_cell_view_dir $cell "$dest_view" $dest_dfII_dir + dest_dfII_cell_dir="$ret" + get_library_dir $cell $dest_dfII_dir + dest_dfII_lib_dir="$ret" + if [[ ! ( -d $dest_dfII_lib_dir ) ]] ; then + cp -a $blank_lib $dest_dfII_lib_dir + elif [[ ! ( -e $dest_dfII_lib_dir/cdsinfo.tag ) ]] ; then + cp -a "$blank_lib/"*"" $dest_dfII_lib_dir + fi + + src_dfII_cell_dir="$src_dfII_lib_dir/$dfII_cell_dir/$src_view" + if [ -d "$src_dfII_cell_dir" ] ; then + mkdir -p $dest_dfII_cell_dir + used=1 + if [ -n "$force" ] ; then + cp -rf "$src_dfII_cell_dir/"*"" "$dest_dfII_cell_dir" + else + cp -r "$src_dfII_cell_dir/"*"" "$dest_dfII_cell_dir" + fi + fi + + if [ -n "$used" ] ; then + echo $cell + fi +done + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_abstract_views.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_abstract_views.sh new file mode 100755 index 0000000000..e5e940f083 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_abstract_views.sh @@ -0,0 +1,328 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +< Description +Generates 'abstract' views in your dfII directory. +Abstract views are intended to be used for routing purposes, as they greatly simplify the problem to the router, while keeping all relevant information. These abstract views: +

      +
    • Have pins and boundary. +
    • Have no subcells. +
    • Have merged keepout ('boundary' purpose) instead of the original shapes on non-terminal nets. +
    • Have detail around pins on terminal nets, which is on the 'drawing' purpose. The --limit-pins option will limit the detail to a radius of one powergrid around the pins. +
    • Have no vias, unles the --draw-vias option is used. +
    • Have no powergrid, unless the --keep-power-grid option is used. Use the --keepout-power-grid to convert the power grid into keepout instead of metal. +
    + +

    Implementation

    +

    See and the assura rules from PDK.

    + +

    Usage Notes / Debugging

    +* Cadence logs are at [output-dir]/[cell]/CDS.log. +* ASSURA runs are found in [output-dir]/ASSURA.XXXXX +DOC + + +function exit_func() { +true +} + +trap exit_func EXIT + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/file/config.sh" + +cds_wd_template="$package_root/share/script/sh/setup/cds_wd_default_template" + +# +##### Parse arguments ##### +# + +arch=x86_64 + +function usage() { +cat< (cadence names)... +USAGE + +} + +layout=`mywhich layout` || exit 2 +sedcmd=`mywhich sed` || exit 2 +grepcmd=`mywhich grep` || exit 2 +findcmd=`mywhich find` || exit 2 + +cell_list= +fulcrum_pdk_root= +working_dir= +dfII_dir= +debug=nil +libCellsToIgnore="" +ErasePowerGrid=t +KeepoutPowerGrid=nil +Internal=nil +Subcells=nil +Simplify=nil +P4=nil +DrawVias=nil +LimitPins=nil +NoPCells=t +verbose= + + +Host=$(hostname) + +for arg in $@ ; do +case "$arg" in +--fulcrum-pdk-root=* ) + fulcrum_pdk_root=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; +--dfII-dir=* ) + dfII_dir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; +--arch=* ) + arch=`echo "$arg" | $sedcmd -e "s/--arch=//"` + ;; +--working-dir=* ) + working_dir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; +--lib-cells-to-ignore=* ) + libCellsToIgnore=`echo "$arg" | $sedcmd -e "s/--lib-cells-to-ignore=//"` + ;; +--debug ) + debug=t + ;; +--verbose ) + verbose=t + ;; +--p4 ) + P4=t + ;; +--draw-vias ) + DrawVias=t + ;; +--limit-pins ) + LimitPins=t + ;; +--subcells ) + Subcells=t + ;; +--keep-pcells ) + NoPCells=nil + ;; +--simplify ) + Simplify=t + ;; +--keep-power-grid ) + ErasePowerGrid=nil + ;; +--keepout-power-grid ) + KeepoutPowerGrid=t + ;; +--* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; +* ) + cell_list="$cell_list $arg" +;; +esac +done + +check_for_empty_arg "$package_root" \ +"The packageroot variable must contain the location of the package installation." \ 2 +check_for_empty_arg "$fulcrum_pdk_root" \ + "The fulcrum pdk root mist be specified." 2 +check_for_empty_arg "$working_dir" \ + "An NFS working dir must be specified." 2 +check_for_empty_arg "$dfII_dir" \ + "A dfII dir must be specified." 2 + +check_readable_dir "$fulcrum_pdk_root" \ + "Fulcrum PDK: \"$fulcrum_pdk_root\" is not a readable directory." 2 +conon_path "$fulcrum_pdk_root" +fulcrum_pdk_root="$ret" + +check_readable_dir "$working_dir" \ + "NFS working dir: \"$working_dir\" is not a readable directory." 2 +conon_path "$working_dir" +working_dir="$ret" + +check_readable_dir "$dfII_dir" \ + "dfII dir: \"$dfII_dir\" is not a readable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +blank_lib="$fulcrum_pdk_root/share/Fulcrum/blank-library" +mkdir -p "$working_dir" +cds_wd="$working_dir" + +mkcdswd "--dfII-dir=$dfII_dir" \ + "--fulcrum-pdk-root=$fulcrum_pdk_root" \ + "--cast-path=$cast_path" \ + "--target-dir=$cds_wd" \ + --force + +k=1 +n=$(echo $cell_list | wc | awk '{print $2}' ) + +input="$working_dir/rp" +errFile="$working_dir/err" + +rm -f "$errFile" +cat< "$input" +(load "$package_root/share/skill/autoload.il") +(load "$fulcrum_pdk_root/share/Fulcrum/pdkinfo.il") +EOF + +for cell in $cell_list ; do + cell_dir="$working_dir/$cell" + mkdir -p "$cell_dir" + + echo "$cell ($k of $n)" + k=$(($k + 1)) + +cat<> "$input" + +(when $debug ( ilDebugToolBox ) ) +(let ( + ( WorkingDir "$working_dir" ) + ( LibCellsToIgnore + ( append + ( ListGroup 2 ( parseString "$libCellsToIgnore" ",/" ) ) + ( append + WiringCellLibCellPairRegExs + ( append + TechLibCellPairRegExs + ( append + GateLibCellPairRegExs + StackLibCellPairRegExs ) ) ) ) ) + ( OutPort ( outfile "$errFile" "a" ) ) + ( CellView + ( dbOpenCellViewByType + ( car ( NameParseCellName "$cell" ) ) + "$cell" + "layout" + "maskLayout" + "r" ) ) ) + (let ( + ( CellsToAbstract + (cond ( + $Subcells + ( ListUniqNoTableElements + ( car ( NameFilterInstances + CellView->instances + LibCellsToIgnore ) ) ~> master + ) ) + ( + ( list CellView ) ) ) ) ) + + (when $P4 + ( CDSP4EditLibCellViewTripples + "$Host" + "$P4USER" + "$P4PASSWD" + "$P4CLIENT" + "$P4CONFIG" + "default" + ( mapcar + (lambda ( CellView ) + ( list + CellView->libName + CellView->cellName + "abstract" ) ) + CellsToAbstract ) + 16 + ( sprintf nil "%s/p4.log" WorkingDir ) + WorkingDir ) ) + + + ( foreach + CellView + CellsToAbstract + ( println CellView->cellName ) + (let ( + ( DDCell + ( ddGetObj + CellView->libName + CellView->cellName + "abstract" ) ) ) + (cond ( + ( or ( null DDCell ) + ( ddIsObjWritable DDCell ) ) + (let ( + ( Abstract + ( AbstractCellUsingPDKInfo + CellView + WorkingDir + ?ErasePowerGrid + ;don't erase powergrid in powergrid + (unless ( rexMatchp "globals" CellView->libName ) + $ErasePowerGrid ) + ?Simplify $Simplify + ?DrawVias $DrawVias + ?KeepoutPowerGrid $KeepoutPowerGrid + ?LimitPins $LimitPins + ?NoPCells $NoPCells + + ) ) ) + ( leMergeShapes Abstract->shapes ) + ( dbSave Abstract ) + ( dbPurge Abstract ) + ) ) + ( + ( fprintf OutPort "Couldn't write to %L %L %L\n" + CellView->libName + CellView->cellName + "abstract" ) ) ) ) ) + + ( close OutPort ) +) ) +SKILL +done + +if [[ "$debug" == "nil" ]]; then + echo "(exit)" >> "$input" +fi + +rm -f "$working_dir/CDS.log" +cmd="/p/rrc/tools/bin/ic /p/rrc/tools/bin/assura layout -replay $input -log $working_dir/CDS.log" +if [[ "$debug" == "nil" ]]; then + cmd="$cmd -nograph" +fi + +function my_exec() { + qrsh -V -now n -cwd -nostdin -noshell -l a=$arch -l mem=1500M $@ /dev/null +} + +cd "$cds_wd" && my_exec $cmd & pid=$! +if [ -n "$verbose" ] ; then + tail -F --pid=$pid "$working_dir/CDS.log" +else + wait $pid +fi + +cat "$errFile" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_instantiator_views.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_instantiator_views.sh new file mode 100755 index 0000000000..ee3c91cbd3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_instantiator_views.sh @@ -0,0 +1,347 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +<. +
      +
    1. Uses to search up through the hierarchy to find shapes that are on top of the cell somehwere in the hierarchy. +
    2. Uses to do simple layer processing. +
    3. the assura rules from PDK +
    + +

    Usage Notes / Debugging

    +* output-dir becomes a cadence working directory. +* Cadence logs are at [output-dir]/CDS.log. +* ASSURA runs are found in [output-dir]/[cell]/ASSURA.XXXXXX +* The generated views are in your dfII-dir. +DOC + + + +function exit_func() { +true +} + +trap exit_func EXIT + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/file/config.sh" + +cds_wd_template="$package_root/share/script/sh/setup/cds_wd_default_template" + +# +##### Parse arguments ##### +# + +arch=x86_64 + +function usage() { +cat< (cadence names)..." +USAGE +} + +layout=`mywhich layout` || exit 2 +sedcmd=`mywhich sed` || exit 2 +grepcmd=`mywhich grep` || exit 2 +findcmd=`mywhich find` || exit 2 + + +cell_list= +fulcrum_pdk_root= +working_dir= +dfII_dir= +lib=dfII +debug=nil +client_spec= +assuraOnly=nil +useExistingInstantiatorViews=nil +libCellsToIgnore="" +p4=1 +maxDepth=1024 +bottomLayer=2 +topLayer=7 + +for arg in $@ ; do +case "$arg" in +--fulcrum-pdk-root=* ) + fulcrum_pdk_root=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; +--dfII-dir=* ) + dfII_dir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; +--arch=* ) + arch=`echo "$arg" | $sedcmd -e "s/--arch=//"` + ;; +--working-dir=* ) + working_dir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; +--lib-cells-to-ignore=* ) + libCellsToIgnore=`echo "$arg" | $sedcmd -e "s/--lib-cells-to-ignore=//"` + ;; +--debug ) + debug=t + ;; +--assura-only ) + assuraOnly=t + ;; +--bottom-layer=* ) + bottomLayer=`echo "$arg" | $sedcmd -e "s/--bottomLayer=//"` + ;; +--top-layer=* ) + topLayer=`echo "$arg" | $sedcmd -e "s/--topLayer=//"` + ;; +--use-existing-instantiator-views ) + useExistingInstantiatorViews=t + ;; +--max-depth=* ) + maxDepth=`echo "$arg" | $sedcmd -e "s/--max-depth=//"` + ;; +--* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; +* ) + cell_list="$cell_list $arg" +;; +esac +done + +check_for_empty_arg "$package_root" \ +"The packageroot variable must contain the location of the package installation." \ 2 +check_for_empty_arg "$fulcrum_pdk_root" \ + "The fulcrum pdk root mist be specified." 2 +check_for_empty_arg "$working_dir" \ + "An NFS working dir must be specified." 2 +check_for_empty_arg "$dfII_dir" \ + "A dfII dir must be specified." 2 + +check_readable_dir "$fulcrum_pdk_root" \ + "Fulcrum PDK: \"$fulcrum_pdk_root\" is not a readable directory." 2 +conon_path "$fulcrum_pdk_root" +fulcrum_pdk_root="$ret" + +check_readable_dir "$working_dir" \ + "NFS working dir: \"$working_dir\" is not a readable directory." 2 +conon_path "$working_dir" +working_dir="$ret" + +check_readable_dir "$dfII_dir" \ + "dfII dir: \"$dfII_dir\" is not a readable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +blank_lib="$fulcrum_pdk_root/share/Fulcrum/blank-library" +mkdir -p "$working_dir" +cds_wd="$working_dir" + +mkcdswd "--dfII-dir=$dfII_dir" \ + "--fulcrum-pdk-root=$fulcrum_pdk_root" \ + "--cast-path=$cast_path" \ + "--target-dir=$cds_wd" --force + +keepout_rules="$fulcrum_pdk_root/share/Fulcrum/cell_automation/keepout.rules" + +k=1 +n=$(echo $cell_list | wc | awk '{print $2}' ) + +input="$working_dir/rp" +errFile="$working_dir/err" + +rm -f "$errFile" +cat< "$input" +(load "$package_root/share/skill/autoload.il") +(load "$fulcrum_pdk_root/share/Fulcrum/pdkinfo.il") +InstantiatorsTable = +( HierarchyMakeCellsInstantiatorsTable + "floorplan" + "layout" + ( ListGroup 2 ( parseString "$libCellsToIgnore" ",/" ) ) + ) +EOF + +for cell in $cell_list ; do + cell_dir="$working_dir/$cell" + mkdir -p "$cell_dir" + + echo "$cell ($k of $n)" + k=$(($k + 1)) + +cat<> "$input" + +(when $debug ( ilDebugToolBox ) ) +(let ( + ( LibCellsToIgnore + ( append GateLibCellPairRegExs + StackLibCellPairRegExs ) ) + ( OutPort ( outfile "$errFile" "a" ) ) + ( PinNetNamesToIgnoreLPP + ( list GNDNetName VddNetName ) ) + ( LayoutView + ( dbOpenCellViewByType + ( car ( NameParseCellName "$cell" ) ) + "$cell" + "layout" + "maskLayout" + (if (let ( + ( LayoutDDObj + ( ddGetObj + ( car ( NameParseCellName "$cell" ) ) + "$cell" + "layout" ) ) ) + ( and + LayoutDDObj + ( getq LayoutDDObj files ) + ( forall + FileDDObj + ( getq LayoutDDObj files ) + ( ddIsObjWritable FileDDObj ) ) ) ) + "a" "r" ) + ) ) + ( InstantiatorView + ( dbOpenCellViewByType + ( car ( NameParseCellName "$cell" ) ) + "$cell" + "instantiator" + "maskLayout" + (if $assuraOnly "a" "w" ) + ) ) + ( EmptyCellView + ( dbOpenCellViewByType + ( car ( NameParseCellName "$cell" ) ) + "$cell" + "instantiator_tmp" + "maskLayout" + "w" ) ) + ) + (let ( + ( LPPs + ( ListAppend + (if ( and + ( leqp $bottomLayer 2 ) + ( geqp $topLayer 2 ) ) + ( list Metal2LPP ) ) + (if ( and + ( leqp $bottomLayer 3 ) + ( geqp $topLayer 3 ) ) + ( list Metal3LPP ) ) + (if ( and + ( leqp $bottomLayer 4 ) + ( geqp $topLayer 4 ) ) + ( list Metal4LPP ) ) + (if ( and + ( leqp $bottomLayer 5 ) + ( geqp $topLayer 5 ) ) + ( list Metal5LPP ) ) + (if ( and + ( leqp $bottomLayer 6 ) + ( geqp $topLayer 6 ) ) + ( list Metal6LPP ) ) + (if ( and + ( leqp $bottomLayer 7 ) + ( geqp $topLayer 7 ) ) + ( list Metal7LPP ) ) + (if ( and + ( leqp $bottomLayer 8 ) + ( geqp $topLayer 8 ) ) + ( list Metal8LPP ) ) ) ) ) + + (unless $assuraOnly + ( InstantiatorsCreateInstantiatorsView + LayoutView + InstantiatorView + EmptyCellView + InstantiatorsTable + "layout" + "floorplan" + "dummy" + BoundaryLPP + LPPs + PinNetNamesToIgnoreLPP + $useExistingInstantiatorViews + OutPort + LibCellsToIgnore + $maxDepth + ) + ) + + ;move target to temp view + ( dbCopyCellView + InstantiatorView + ( getq EmptyCellView libName ) + ( getq EmptyCellView cellName ) + ( getq EmptyCellView viewName ) + nil nil t ) + + ;make final target + (when t + ( KeepOutCreateRoutingView + EmptyCellView + ( getq InstantiatorView libName ) + ( getq InstantiatorView cellName ) + ( getq InstantiatorView viewName ) + "$keepout_rules" + "$cell_dir" + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ) ) + LPPs ) + PinNetNamesToIgnoreLPP + ) + ) + + ( close OutPort ) + ( dbSave EmptyCellView ) + ( dbPurge EmptyCellView ) + ( dbSave InstantiatorView ) + ( dbPurge InstantiatorView ) + ( dbPurge LayoutView ) +) ) +SKILL +done + +if [[ "$debug" == "nil" ]]; then + echo "(exit)" >> "$input" +fi + +cmd="/p/rrc/tools/bin/ic /p/rrc/tools/bin/assura layout -replay $input -log $working_dir/CDS.log" +if [[ "$debug" == "nil" ]]; then + cmd="$cmd -nograph" +fi + +function my_exec() { + qrsh -V -now n -cwd -nostdin -noshell -l a=$arch -l mem=1500M $@ /dev/null +} + +cd "$cds_wd" && my_exec $cmd +cat "$errFile" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_leaf_cells.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_leaf_cells.sh new file mode 100755 index 0000000000..5ce6ca86ef --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_leaf_cells.sh @@ -0,0 +1,527 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +< Summary +

    Generates leaf cells using virtuoso,ccar,vcp and SKILL code, starting with CAST.

    +The cells:
    +
      +
    • Are the minimal width the placer/router could obtain. +
    • Are fixed height, based on the bitpitch/height directives. +
    • Have components placed in alternating (n-p)-(p-n) columns. +
    • LVS clean +
    • Have well plugs(but not guarnteed to be enough) +
    • Are not always DRC clean after routing, but an attempt is made to clean the results using assura layer processor functionality. +
    • Are best suited for medium sized leaf cells(not to say it only works on medium sized cells). Big cells (>8 columns,) tend to confuse it, and small cells are often better left up to layout engineers. +
    • Have contact shared gates/stacks. +
    + +

    The tool is intended to work for all available technologies. It gets all the information for the technology in various places in the . In particular, the SKILL global variable definitions defining names of things, and important numbers are in the pdkinfo.il files. See and .

    + +

    Description

    + +

    I break up the description into two parts. The Script Description is for everything the script does, up until running a SKILL replay file. The SKILL description describes the meat of the tool, which takes place in the skill.

    + +

    Script Description

    +This script: +
      +
    1. Creates a usable cadence working directory with . +
    2. For each cell in the cell list, creates a cell directory [output-root]/ +
    3. For each cell, calls com.avlsi.tools.jauto.Cast2Cdl to create [output-root]//cell.cdl +
    4. For each cell, calls com.avlsi.tools.cast2skill.Cast2Skill to create : +
        +
      1. [output-root]/[cell]/ilnets/*.netlist.il needed to generated components with / +
      2. [output-root]/[cell]/autopins/[cell].pins.il files to draw pins. +
      3. [output-root]/[cell]/directives/[cell].directives.il for directives used in routing/pins. +
      +
    5. Creates a replay file leaf.il from leaf_cell.il.template +
    6. Runs layout -replay leaf.il +
    + +

    SKILL Description

    + +

    We break up the execution into 3 steps, instantiation of the netlist, .

    + +

    +
      +
    1. Instantiate the gates and stacks in the 'genfromsource' view. +
    + +

    + +
      +
    1. Tweak parameters Fold and chain the chains. +
    2. Fold and chain the chains into superstacks based on heuristics. +
    3. Fold and chain the gates into superstacks based on heuristsics. +
    4. Choose n/p widths. +
    5. Draw pins prior to placement. +
    6. Place the superstacks. +
    7. Vertically and horizontally optimize stacks in each column. That is, squeeze the folding as much as possible while still fitting in the column. Tricky. There's an option --nocompactsuperstacks to turn this off as it sometimes makes things worse. Usually it helps quite a bit to leave it on. +
    8. Vertically spread out gates/stacks placement to improve routability. +
    9. Draw well plugs (substrate contacts) in each column. +
    10. Now that we know what's in all of the columns(they've been compacted and well plugs have been placed), squish(abut) the columns together horizontally. +
    11. Draw well/implant in each column. +
    12. Redraw the boundary and pins. +
    13. Check the resulting placement for valididty using a simple drc check. If passes, create a 'preroute_XXX' and 'placed_XXX' view. +
    14. Do a binary search on the n/p widths based on the success of the drccheck. Go back to 1 unless we've searched all possible column n/p widths. +
    + +

    +
      +
    1. Space the chains out from the center to allow for more poly routing bandwidth. +
    2. Space apart the columns (add routing width) for more vertical m2 routing bandwidth. +
    3. Route the cell. +
    4. Check LVS +
    5. Attempt to fix DRC errors from router. +
    6. Do a binary search on the routing widths of each column, based on the success of the lvs check. Go back to 1 unless we've searched all possible router widths between 0 and 16*wirepitch for each column. +
    + + +

    References

    +
      +
    • See for how we fix DRC errors from the router. +
    • See for heuristics used in supestacking. +
    • See / for how we do placement. +
    • See / for how we do routing. +
    • See and cast2skill to see how we generate pins. +
    • See for how we do Vertical m2 and Horizontal m3 GND/Vdd struts and contacts. +
    • See to see how we generate plugs/substrate contacts. +
    + +

    Output/Debugging

    +For debugging, note the location of these various files:
    + +
    +
    cadence log. Dump of a bunch of SKILL debugging information. + grep for Error if something horrible happened. +
    [output-root]/[cell]/CDS.log + +
    Generated layout. Consists of various types of views.
    + The _XXX corresponds to the iteration number.
    + In the order they are created, these are:
    +
    +
    scratch +
    The view that glc last touched. + +
    genfromsource +
    Unplaced components. + +
    preroutescratch_XXX +
    Placed components with no implant/nwell layers/power routing. + +
    placedscratch_XXX +
    Placed components with implant/nwell layers/power routing. + +
    preroute_XXX +
    A preroutescratch_XXX view that passes a rudimentary prerouting drc check. Used by the routing stage. + +
    placed_XXX +
    A placedscratch_XXX view that passes a rudimentary prerouting drc check. A good starting point for semi-automated layout if routing doesn't give good results. + +
    placed +
    The smallest placed view. + +
    preroute +
    The smallest preroute view. + +
    routedscratch_XXX +
    A view routed with ccar. + +
    routed_XXX +
    A view routed with ccar that passes LVS! + +
    routed +
    The smallest routed_XXX view. +
    +
    [output-root]/dfII/[cell]/
    + +
    Routing (icc/ccar working dir) +
    [output-root]/CCAR.XXXXXX
    + +
    Placement (icc/sbtool.exe working dir) +
    [output-root]/PLACER.XXXXXX + +
    All assura runs (temporary working dir) +
    [output-root]/ASSURA.XXXXXX + +
    well plugs (temporary dfII library) +
    [output-root]/PLUGS... + +
    assura drc (completed) +
    [output-root]/[cell]/assura_drc/[view] + +
    assura lvs (completed) +
    [output-root]/[cell]/assura_lvs/[view] + +
    + +DOC + +function usage() { + cat< "$cds_wd/cds.lib" + echo "UNDEFINE gate" >> "$cds_wd/cds.lib" + echo "UNDEFINE stack" >> "$cds_wd/cds.lib" + cat "$cds_wd/cds.lib_bak" >> "$cds_wd/cds.lib" + fi +fi + +target_layout_script="$output_root_dir/main.sh" +echo 'source /usr/local/grid/default/common/settings.sh' > $target_layout_script + +k=0 +n=$(wc $cell_list_file | awk '{print $2}' ) + +for cell in $cells; do + k=$(($k + 1)) + echo "Doing $cell ( $k of $n )" + + #make dirs + cell_dir="$output_root_dir/$cell" + cell_wd="$cell_dir/cds_wd" + mkdir -p "$cell_wd" + + #make files + input="$cell_dir/leaf.il" + cadence_log="$cell_dir/CDS.log" + cell_script="$cell_dir/layout.sh" + cdl_file="$cell_dir/cell.cdl" + + cp -f "$cds_wd/cds.config" "$cell_wd/cds.config" + cp -f "$cds_wd/.cdsinit" "$cell_wd/.cdsinit" + cp -f "$cds_wd/cds.lib" "$cell_wd/cds.lib" + cp -f "$cds_wd/display.drf" "$cell_wd/display.drf" + + run_num=$[ $[ $k - 1 ] % $numruns ] + this_run_script="$output_root_dir/glc"_"$run_num.sh" + + #starting a new run script + if [[ $[ $[ $k - 1 ] / $numruns ] == 0 ]] ; then + echo "QRSH_FLAGS='-l mem=$mem -l a=$os -l centos=4 -N glc_$run_num' QB_RUN_NAME='glc_$run_num' QB_DIAG_FILE="$output_root_dir/glc_$run_num.diag" $qb $this_run_script &" >>$target_layout_script + echo "#!/bin/bash" > $this_run_script + chmod 755 $this_run_script + fi + + echo "source \"$cell_script\"" >>$this_run_script + + cast2skill="$bin_dir/cast2skill" + cast2cdl="$bin_dir/cast2cdl" + + check_executable_file "$cast2skill" \ + "cast2skill: \"$cast2skill_src\" is not an executable file." 2 + check_executable_file "$cast2cdl" \ + "cast2cdl: \"$cast2cdl_src\" is not an executable file." 2 + + ### prepare cell output dir + if [[ ! -d "$cell_dir" ]] ; then + mkdir -p $cell_dir + fi + + ### the library to use is the dfII unilib if given, else the parsed lib name + + if [ -n "$dfII_lib_name" ] ; then + lib=$dfII_lib_name + else + get_lib_name "$cell" + lib="$ret" + fi + + if [[ ( -z "$noprepare" ) || ! ( -e "$cdl_file" ) ]] ; then + echo "Cast2Cdl..." + $cast2cdl --cell="$cell" --cast-path=$cast_path \ + --output=$cdl_file --cadence-name --process-dependent-name + echo "Cast2Skill..." + $cast2skill --cell="$cell" --cast-path=$cast_path \ + --output-dir=$cell_dir \ + --root-only --cadence-name + fi + + if [[ ( -e $cdl_file ) ]] ; then + config_fill_template_from_env "$templates_dir/leaf_cell.il.template" \ + > $input + else + echo "Skipping $cell" + fi + +if [[ "$graphics" == "t" ]] ; then + nograph= +else + nograph=-nograph +fi + +cat<$cell_script +cd "$cell_wd" && layoutPlus $nograph -replay $input -log $cell_dir/CDS.log run.err +EOF + +done + +echo 'wait' >> $target_layout_script +source $target_layout_script + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_mid_cells.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_mid_cells.sh new file mode 100755 index 0000000000..4b46a3a759 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/gen_mid_cells.sh @@ -0,0 +1,212 @@ +#!/bin/bash + +function my_exec() { + qrsh -V -now n -cwd -nostdin -noshell -l mem=500 -p -20 $@ /dev/null & +} + +function exit_func() { + true +} + +trap exit_func EXIT + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/file/config.sh" + +cds_wd_template="$package_root/share/script/sh/setup/cds_wd_default_template" + + +# +##### Parse arguments ##### +# + +function usage() { + + echo "Usage: $0" + echo " --fulcrum-pdk-root=dir" + echo " --working-dir=dir" + echo " --dfII-dir=dir" + echo " --cast-path=cast_path" + echo " [--graphics]" + echo " ..." +} + +layout=`mywhich layout` || exit 2 +sedcmd=`mywhich sed` || exit 2 +grepcmd=`mywhich grep` || exit 2 +findcmd=`mywhich find` || exit 2 +awkcmd=`mywhich awk` || exit 2 + +cell_list= +fulcrum_pdk_root= +working_dir= +dfII_dir= +lib=dfII +noprepare= +graphics=nil + +for arg in $@ ; do + case "$arg" in + --fulcrum-pdk-root=* ) + fulcrum_pdk_root=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --dfII-dir=* ) + dfII_dir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --working-dir=* ) + working_dir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; + --cast-path=* ) + cast_path=`echo "$arg" | $sedcmd -e "s/--cast-path=//"` + ;; + --noprepare ) + noprepare=1 + ;; + --graphics ) + graphics=t + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + cell_list="$cell_list $arg" + ;; + esac +done + +check_for_empty_arg "$package_root" \ + "The packageroot variable must contain the location of the package installation." \ 2 +check_for_empty_arg "$fulcrum_pdk_root" \ + "The fulcrum pdk root mist be specified." 2 +check_for_empty_arg "$working_dir" \ + "An NFS working dir must be speciified." 2 +check_for_empty_arg "$dfII_dir" \ + "A dfII dir must be speciified." 2 +check_for_empty_arg "$cast_path" \ + "A cast path must be speciified." 2 + +check_readable_dir "$fulcrum_pdk_root" \ + "Fulcrum PDK: \"$fulcrum_pdk_root\" is not a readable directory." 2 +conon_path "$fulcrum_pdk_root" +fulcrum_pdk_root="$ret" + +check_readable_dir "$working_dir" \ + "NFS working dir: \"$working_dir\" is not a readable directory." 2 +conon_path "$working_dir" +working_dir="$ret" + +check_readable_dir "$dfII_dir" \ + "dfII dir: \"$dfII_dir\" is not a readable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +blank_lib="$fulcrum_pdk_root/share/Fulcrum/blank-library" +mkdir -p "$working_dir" +cds_wd="$working_dir" + +mkcdswd="$arch_bin_dir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +$mkcdswd "--dfII-dir=$dfII_dir" \ + "--fulcrum-pdk-root=$fulcrum_pdk_root" \ + "--cast-path=$cast_path" \ + "--target-dir=$cds_wd" \ + +newlibdir="$working_dir/dfII" +if [ ! -d "$newlibdir" ] ; then + cp -a "$blank_lib" "$newlibdir" + $findcmd "$newlibdir" -print0 | xargs -0 chmod u+w +fi +if [ -z "$(grep "DEFINE dfII $newlibdir" "$cds_wd/cds.lib" )" ] ; then + echo "DEFINE dfII $newlibdir" >> "$cds_wd/cds.lib" +fi + +cast2skill="$arch_bin_dir/cast2skill" +cast2cdl="$arch_bin_dir/cast2cdl" +check_executable_file "$cast2skill" \ + "cast2skill: \"$cast2skill\" is not a readable, executable file." 2 +check_executable_file "$cast2cdl" \ + "cast2cdl: \"$cast2cdl\" is not a readable, executable file." 2 + +pdk_config="$fulcrum_pdk_root/share/Fulcrum/pdk.config" +config_get_all_values source pdk_config + +k=1 +n=$(echo $cell_list | wc | $awkcmd '{print $2}' ) + +for cell in $cell_list ; do + + cell_dir="$working_dir/$cell" + mkdir -p "$cell_dir" + input="$cell_dir/mid.rp" + + echo "$cell ($k of $n)" + cdl_file="$cell_dir/cell.cdl" + if [[ ! ( -s "$cdl_file" ) || ( -z "$noprepare" ) ]] ; then + echo "Cast2Cdl..." + $cast2cdl --cell="$cell" \ + --cast-path="$cast_path" \ + --output="$cdl_file" \ + --cadence-name + fi + + k=$(($k + 1)) + + directives_dir="$cell_dir/ildirectives" + directives_file="$directives_dir/$cell.directives.il" + if [[ ! ( -s "$directives_file" ) || ( -z "$noprepare" ) ]] ; then + echo "Cast2Skill..." + $cast2skill --cell="$cell" \ + --cast-path="$cast_path" \ + --output-dir="$cell_dir" \ + --root-only \ + --cadence-name + fi + +cat< "$input" +(load "$package_root/share/skill/autoload.il") +(load "$fulcrum_pdk_root/share/Fulcrum/pdkinfo.il") +(let ( + ( CellName "$cell" ) + ( TargetLibName "$lib" ) + ( FulcrumPDKRoot "$fulcrum_pdk_root" ) + ( SchematicFile "$cdl_file" ) + ( WorkingDir "$cell_dir" ) + ( LPPsToUse ( list Metal2LPP Metal3LPP ) ) + ( LPPsToSearch ( list Metal4LPP Metal5LPP ) ) + ) + + ( MidLevelAutoUsingPDKInfo + CellName + TargetLibName + FulcrumPDKRoot + SchematicFile + WorkingDir + LPPsToUse + LPPsToSearch + ?Graphics $graphics ) ) +(exit) +EOF + +cmd="layout -replay $input -log $cell_dir/CDS.log" +if [[ "$graphics" == "nil" ]]; then + cmd="$cmd -nograph" +fi + +cp -f "$cds_wd/cds.lib" "$cell_dir/cds.lib" +cp -f "$cds_wd/display.drf" "$cell_dir/display.drf" + +cd "$cell_dir" && my_exec $cmd + + +done + +wait diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/updatenetlist.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/updatenetlist.sh new file mode 100755 index 0000000000..ca2a0555ea --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/multi_cell_commands/updatenetlist.sh @@ -0,0 +1,566 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" +build_id="$buildid$" + +#To debug updatenetlist problems in skill comment out the if blocks +#for skill_netlist_dir, directives_skill_dir, +#and main_il. You will also need to insert the "exit" command immediately +#before the command that runs ssh to run commands on the sun. + +function exit_func() { + if [ -n "$local_working_dir" ] ; then + rm -rf "$local_working_dir" + fi +} + +trap exit_func EXIT + +function usage() { + echo "Usage: $0 " + echo " --cell=cell | --cell-list=" + echo " --subtype=num" + echo " --fulcrum-pdk-root=dir" + echo " --dfII-dir=dir" + echo " --cast-path=castpath" + echo " [ --density-factor-default=15 ]" + echo " [ --bound-scale-factor=1 ]" + echo " [ --suppress-pins ]" + echo " [ --cadence-log=/dev/null ]" + echo " [ --update-views ]" + echo " [ --change-list=num ]" + echo " [ --check-log=/dev/null ]" + echo " [ --lock-bound ]" + echo " [ --use-layout-height ]" + echo " [ --force-pins ]" + echo " [ --suppress-netlist-view ]" + echo " [ --lock-layout ]" + echo " [ --version ]" + echo " [ --debug ]" + echo " [ --disable-license-queuing ]" + echo " [ --cast2skill-options=options ]" +} + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +layout=`mywhich layout` || exit 2 +sedcmd=`mywhich sed` || exit 2 +gawkcmd=`mywhich gawk` || exit 2 +grepcmd=`mywhich grep` || exit 2 +bashcmd=`mywhich bash` || exit 2 +findcmd=`mywhich find` || exit 2 +sortcmd=`mywhich sort` || exit 2 +uniqcmd=`mywhich uniq` || exit 2 + +# parsecellname demands that sedcmd be defined first +source "$package_root/share/script/sh/util/parsecellname" + +check_readable_dir "$arch_bin_dir" \ + "Package arch bin: \"$arch_bin_dir\" is not a readable directory." 2 + +cast2skill="$arch_bin_dir/cast2skill" +check_executable_file "$cast2skill" \ + "cast2skill: \"$cast2skill\" is not an executable file." 2 + + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 + +cds_sh_lib_files=`$findcmd "$cds_sh_lib" \! -type d` +for file in $cds_sh_lib_files ; do + source "$file" +done + + +mkcdswd="$arch_bin_dir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +netlist_view_name="netlist" +layout_view_name="layout" +floorplan_view_name="floorplan" + +root_cell= +root_cell_subtype= +fulcrum_pdk_root= +dfII_dir= +cast_path= +density_factor_default=15 +bound_scale_factor=1 +cadence_log=/dev/null +client_spec= +update_views= +verbose= +change_list_num= +check_log=/dev/null +no_netlist_views= +lock_bound=nil +suppress_pins=nil +suppress_wiring_directives=nil +force_pins=nil +use_layout_height=nil +lock_layout=nil +profile_out= +debug= +javaMaxHeapSize="1800M" +tempDir="$TMPDIR" +cellList= +cast2skill_opt= +license_wait='WAIT' + +for arg in "$@" ; do + + case "$arg" in + --cell=* ) + root_cell=`echo "$arg" | $sedcmd -e "s/--cell=//"` + ;; + --cell-list=* ) + cellList=`echo "$arg" | $sedcmd -e "s/--cell-list=//"` + ;; + --subtype=* ) + root_cell_subtype=`echo "$arg" | $sedcmd -e "s/--subtype=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrum_pdk_root=`echo "$arg" | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --dfII-dir=* ) + dfII_dir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --cast-path=* ) + cast_path=`echo "$arg" | $sedcmd -e "s/--cast-path=//"` + ;; + --density-factor-default=* ) + density_factory_default=`echo "$arg" | $sedcmd -e "s/--density-factor-default=//"` + ;; + --bound-scale-factor=* ) + bound_scale_factor=`echo "$arg" | $sedcmd -e "s/--bound-scale-factor=//"` + ;; + --cadence-log=* ) + cadence_log=`echo "$arg" | $sedcmd -e "s/--cadence-log=//"` + ;; + --update-views ) + update_views=1 + ;; + --verbose ) + verbose=1 + ;; + --check-log=* ) + check_log=`echo "$arg" | $sedcmd -e "s/--check-log=//"` + ;; + --cds-wd=* ) + echo "--cds-wd option is no longer needed. \"$arg\" ignored." + ;; + --suppress-netlist-view ) + no_netlist_views=t + ;; + --lock-bound ) + lock_bound=t + ;; + --force-pins ) + force_pins=t + ;; + --lock-layout ) + lock_layout=t + ;; + --profile-out=* ) + profile_out=`echo "$arg" | $sedcmd -e "s/--profile-out=//"` + ;; + --use-layout-height ) + use_layout_height=t + ;; + --suppress-pins ) + suppress_pins=t + ;; + --suppress-wiring-directives ) + suppress_wiring_directives=t + ;; + --version ) + echo "$build_id" + ;; + --debug ) + debug=1 + ;; + --java-max-heap-size=* ) + javaMaxHeapSize=`echo "$arg" | $sedcmd -e "s/--java-max-heap-size=//"` + ;; + --temp-dir=* ) + tempDir=`echo "$arg" | $sedcmd -e "s/--temp-dir=//"` + ;; + --cast2skill-options=* ) + cast2skill_opt=`echo "$arg" | $sedcmd -e "s/--cast2skill-options=//"` + ;; + --disable-license-queuing ) + license_wait='NOWAIT' + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + +check_for_empty_arg "$package_root" \ + "The packageroot variable must contain the location of the package installation." 2 + +if [[ ( -z "$cellList" ) && \ + (( -z $root_cell ) || ( -z "$root_cell_subtype" )) ]] ; then + usage + echo "A cell list or cell name/subtype must be specified" + exit 2 +fi + + +check_for_empty_arg "$fulcrum_pdk_root" \ + "You must specify the location of the fulcrum pdk you want to use." 2 +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$cast_path" \ + "You must specify a cast path" 2 +check_for_empty_arg "$density_factor_default" \ + "You must specify a default value for the density factor directive." 2 +check_for_empty_arg "$bound_scale_factor" \ + "You must specify a boundary scaling factor" 2 +check_for_empty_arg "$cadence_log" \ + "You must specify a cadence log file." 2 +check_for_empty_arg "$check_log" \ + "You must specify a file into which the check log is written." 2 + +check_for_empty_arg "$javaMaxHeapSize" \ + "You must specify a maximum java heap size." 2 + +if [ -z "$tempDir" ] ; then + tempDir="/scratch" +fi + +local_working_dir=`mktemp -d "$tempDir/updatenetlist.XXXXXX"` || exit 1 + +check_readable_dir "$package_root" \ + "Package Installation: \"$package_root\" is not a readable directory." 2 + +check_readable_dir "$fulcrum_pdk_root" \ + "Fulcrum PDK: \"$fulcrum_pdk_root\" is not a readable directory." 2 +conon_path "$fulcrum_pdk_root" +fulcrum_pdk_root="$ret" + +check_writeable_dir "$dfII_dir" \ + "Generated Libraries Root: \"$dfII_dir\" is not a writeable, readable directory." 1 +conon_path "$dfII_dir" +dfII_dir="$ret" + +if [ "$cadence_log" != "/dev/null" ] ; then + check_writeable_file "$cadence_log" \ + "Cadence Log File: \"$cadence_log\" is not a writeable file." 1 + conon_path "$cadence_log" + cadence_log="$ret" +fi + +if [ "$check_log" != "/dev/null" ] ; then + check_writeable_file "$check_log" \ + "Check Log: \"$check_log\" is not a writeable file." 1 + conon_path "$check_log" + check_log="$ret" +fi + + + + +lib_commands_dir="$package_root/share/script/sh/cell-automation/lib_commands" +skill_root="$package_root/share/skill" +setup_dir="$package_root/share/script/sh/setup" +change_list_template="$package_root/share/data/change_list_template.txt" + + +check_readable_dir "$lib_commands_dir" \ + "commands directory: \"$lib_commands_dir\" is not a directory." 2 +check_readable_dir "$skill_root" \ + "Skill Root Directory: \"$skill_root\" is not a readable directory." 2 +check_readable_file "$change_list_template" \ + "change_list_template: \"$change_list_template\" is not a readable file." 2 + + +pdkinfo_il="$fulcrum_pdk_root/share/Fulcrum/pdkinfo.il" +check_readable_file "$pdkinfo_il" \ + "pdkinfo.il: \"$pdkinfo_il\' is not a readable file." 2 + +skill_auto_load="$skill_root/autoload.il" +check_readable_file "$skill_auto_load" \ + "Skill Autoload: \"$skill_auto_load\" is not a readable file." 2 + +mkcdslib_source="$lib_commands_dir/mkcdslib" +check_readable_file "$mkcdslib_source" \ + "mkcdslib: \"$mkcdslib_source\" is not a readable file." 2 + +blank_cds_library="$fulcrum_pdk_root/share/Fulcrum/blank-library" +check_readable_dir "$blank_cds_library" \ + "Blank Cadence Library: \"$blank_cds_library\" is not a readable directory." 2 + + + + +cast2skill_output=`mktemp -d "$local_working_dir/updatenetlist.XXXXXX"` + + +cast2skill_params="--cast-version=2 \ + --cast-path=$cast_path \ + --output-dir=$cast2skill_output \ + --max-heap-size=$javaMaxHeapSize \ + --fulcrum-pdk-root=$fulcrum_pdk_root" + +if [ -n "$cast2skill_opt" ] ; then + cast2skill_params="$cast2skill_params $cast2skill_opt" +fi + +#do one cell or a cell list +if [ -n "$cellList" ] ; then + cast2skill_params="$cast2skill_params --cells=$cellList" +else + cast2skill_params="$cast2skill_params --cell=$root_cell.$root_cell_subtype" +fi + +if [ "$suppress_pins" == "t" ] ; then + cast2skill_params="$cast2skill_params --suppress-pins" +fi + +if [ "$suppress_wiring_directives" == "t" ] ; then + cast2skill_params="$cast2skill_params --suppress-wiring-directives" +fi + +cast2SkillCmd="$cast2skill $cast2skill_params" + +if [ -n "$verbose" ] ; then + echo "Running cast2skill to generate skill netlist, directives, pins, etc. for \"$root_cell.$root_cell_subtype\"." + echo "$cast2SkillCmd" +fi + +if [ -n "$profile_out" ] ; then + (echo "cast2verilog started at " `date`; \ + $cast2skill $cast2skill_params &>$cast2skill_output/cast2skill.out; \ + echo "cast2verilog ended at " `date`; \ + times) &> "$profile_out" +else + $cast2skill $cast2skill_params &>$cast2skill_output/cast2skill.out +fi + +cast2SkillOutput="$?" + +if [[ "$cast2SkillOutput" != "0" ]] ; then + echo "Unable to generate skill from CAST." + cat "$cast2skill_output/cast2skill.out" + exit 1 +fi + +cmd_tmp_dir=`mktemp -d "$local_working_dir/updatenetlist.XXXXXX"` + +generate_command_script "$cmd_tmp_dir" "$mkcdslib_source" "$sh_lib_dir" "$bashcmd" +mkcdslib="$ret" +check_executable_file "$mkcdslib" \ + "mkcdslib: \"$mkcdslib\" is not readable, executable file." 2 + +skill_netlist_dir="$cast2skill_output/ilnets" + +cell_list_file="$cast2skill_output/cellnames.txt" + +lib_list_file="$cast2skill_output/libnames.txt" + +directives_skill_dir="$cast2skill_output/ildirectives" + +autopins_skill_dir="$cast2skill_output/autopins" + +cells=`cat "$cell_list_file"` +libraries=`cat "$lib_list_file"` + +cdsWD=`mktemp -d "$local_working_dir/updatenetlist.XXXXXX"` + +mkcdswdCmd="$mkcdswd \"--dfII-dir=$dfII_dir\"" +mkcdswdCmd="$mkcdswdCmd \"--fulcrum-pdk-root=$fulcrum_pdk_root\"" +mkcdswdCmd="$mkcdswdCmd \"--target-dir=$cdsWD\"" +mkcdswdCmd="$mkcdswdCmd \"--force\"" +mkcdswdCmd="$mkcdswdCmd \"--cast-path=$cast_path\"" + +if [ -n "$verbose" ] ; then + echo "Generated cdsWD in \"$cdsWD\"." + echo "$mkcdswdCmd" +fi + +eval "$mkcdswdCmd" + + +for lib in $libraries ; do + if [ -n "$verbose" ] ; then + echo "Ensuring that library \"$lib\" exists." + fi + # bug 14632 + if [ ! -d "$fulcrum_pdk_root/share/Fulcrum/dfII/$lib" ]; then + $mkcdslib "--cds-wd=$cdsWD" \ + "--generated-libraries-root=$dfII_dir" \ + "--blank-cds-library=$blank_cds_library" \ + "--lib=$lib --cadence-shell-library=$cds_sh_lib" + fi +done + +if [ -n "$verbose" ] ; then + echo "Generating main skill program." +fi + + +mainIL=`mktemp "$local_working_dir/updatenetlist.XXXXXX"` +mainILProf="$mainIL.profile" + +if [ -n "$debug" ] ; then + echo "( ilDebugToolBox )" >>$mainIL +fi +echo "( load \"$skill_auto_load\" )" >>$mainIL +echo "( load \"$pdkinfo_il\" )" >>$mainIL +echo "( UIInit )" >>$mainIL + +update_netlist_check_result=`mktemp "$local_working_dir/updatenetlist.XXXXXX"` + + +cell_list_file=`mktemp "$local_working_dir/updatenetlist.XXXXXX"` + +for cell in $cells ; do + + get_lib_name $cell + cell_lib="$ret" + + if [ -n "$cell_lib" ] ; then + echo "$cell_lib $cell" >>$cell_list_file + else + echo "\"$cell\" is not a valid cell name." + fi + +done + +if [ -n "$profile_out" ] ; then + echo "(profile 'time)" >> $mainIL +fi + +if [[ "$update_views" != 1 ]] ; then + echo "( UpdateNetlistCompareCellsToSkillNetlistsInToFileUsingPDKInfo" >>$mainIL + echo " ( LibCellViewReadLibCellPairsFromFile" >>$mainIL + echo " \"$cell_list_file\" )" >>$mainIL + if [[ "$no_netlist_views" == t ]] ; then + echo " nil" >>$mainIL + else + echo " \"$netlist_view_name\"" >>$mainIL + fi + echo " \"$layout_view_name\"" >>$mainIL + echo " \"$floorplan_view_name\"" >>$mainIL + echo " \"$skill_netlist_dir\"" >>$mainIL + echo " \"$directives_skill_dir\"" >>$mainIL + echo " \"$autopins_skill_dir\"" >>$mainIL + echo " $density_factor_default" >>$mainIL + echo " $bound_scale_factor" >>$mainIL + echo " \"$update_netlist_check_result\"" >>$mainIL + echo " $lock_bound" >>$mainIL + echo " $suppress_pins" >>$mainIL + echo " $force_pins" >>$mainIL + echo " $use_layout_height" >>$mainIL + echo " $lock_layout" >>$mainIL + echo " )" >>$mainIL +else + echo '(if ( LicenseGetLicense "Virtuoso_Layout_Suite_GXL" (getLicVersion) 0 ?LicenseType "'$license_wait'" )' >>$mainIL + echo "( UpdateNetlistUpdateCellsFromSkillNetlistsToFileUsingPDKInfo" >>$mainIL + echo " ( LibCellViewReadLibCellPairsFromFile" >>$mainIL + echo " \"$cell_list_file\" )" >>$mainIL + if [[ "$no_netlist_views" == t ]] ; then + echo " nil" >>$mainIL + else + echo " \"$netlist_view_name\"" >>$mainIL + fi + echo " \"$layout_view_name\"" >>$mainIL + echo " \"$floorplan_view_name\"" >>$mainIL + echo " \"$skill_netlist_dir\"" >>$mainIL + echo " \"$directives_skill_dir\"" >>$mainIL + echo " \"$autopins_skill_dir\"" >>$mainIL + echo " $density_factor_default" >>$mainIL + echo " $bound_scale_factor" >>$mainIL + echo " \"$update_netlist_check_result\"" >>$mainIL + echo " $lock_bound" >>$mainIL + echo " $suppress_pins" >>$mainIL + echo " $force_pins" >>$mainIL + echo " $use_layout_height" >>$mainIL + echo " $lock_layout" >>$mainIL + echo " ) )" >>$mainIL +fi + +if [ -n "$profile_out" ] ; then + echo "(profileSummary ?children t ?file \"$mainILProf\")" >> $mainIL +fi + +if [ -z "$debug" ] ; then + echo "( exit )" >>$mainIL +fi + +if [ -n "$verbose" ] ; then + echo "Generating shell code to run cadence." +fi +cadenceScript=`mktemp "$local_working_dir/updatenetlist.XXXXXX"` +cadenceLogTemp=`mktemp "$local_working_dir/updatenetlist.XXXXXX"` +cadenceErr=`mktemp "$local_working_dir/gdsIIWrite.XXXXXX"` + +if [ -n "$verbose" ] ; then + echo "Running cadence" +fi + +graphics= +if [ -z "$debug" ] ; then + graphics="-nograph" +fi + +cat <"$cadenceScript" +#!/bin/bash +cd "$cdsWD" +CDS_AUTO_64BIT=$CDS_AUTO_64BIT $layout \ +-replay "$mainIL" -log "$cadenceLogTemp" $graphics \ + /dev/null 2>"$cadenceErr" +EOF + +chmod +x "$cadenceScript" +if [ -n "$profile_out" ] ; then + (echo "updatenlist started at " `date`; \ + "$cadenceScript"; \ + status=$?; \ + echo "updatenlist ended at " `date`; \ + times; \ + exit $status) >> "$profile_out" 2>&1 +else + "$cadenceScript" +fi + +ret=$? + +cat "$cadenceLogTemp" > "$cadence_log" +cat "$update_netlist_check_result" > "$check_log" + +if [ -n "$profile_out" ] ; then + cat "$mainILProf" >> "$profile_out" +fi + +#check for error in cadence +#FIXME: this is unreliable because a cell name could contain "ERROR" +([[ $ret != 0 ]] || grep -i Error "$cadence_log") && tail -10 "$cadence_log" && exit 2 + + +error_in_update=`cat "$update_netlist_check_result" | $grepcmd -e "^ERROR:"` + +if [ -n "$error_in_update" ] ; then + cat $update_netlist_check_result | $grepcmd -e "\(^ERROR:\)\|\(^+\)" | $sedcmd -e "s/+//" + exit 1 +fi + + +if [[ "$update_views" != 1 ]] ; then + cat $update_netlist_check_result | $grepcmd -v "\(^NET:\)\|\(^IGNORE:\)" + +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/Tapeout.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/Tapeout.pl new file mode 100755 index 0000000000..493af89b1c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/Tapeout.pl @@ -0,0 +1,808 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use IPC::Open2; +use Getopt::Long; +use IPC::Open2; +my $user=$ENV{USER}; +$user="nobody" if ($user eq ""); + +my $libName; +my $dfIIdir; +my $castpath; +my $cell; +my $output=""; +my $outgds=""; +my $bindfile="/dev/null"; +my $use_tag=0; +my $pdkroot; +my $rootcellname=""; +my $debug=0; +my $flattenpcells=1; +my $bit64=0; +my $maxheapsize = "4G"; +my $jreargs = "-server"; +my $qsubextras=""; +my $workingDir=`pwd`; +chomp $workingDir; +my $viewName="layout"; +my $layers=""; +my $layertable=""; +my $cellmaptable=""; +my $verbose=0; +my %env=(); +my $reducedgds; +my $prevgds; +my $assura_technology; +my $tasks; +my $maxnamelen=127; +my $checkonly=0; +my $grayboxlist=""; +my $blackboxhlvs=0; +my $hdrc_threads=4; +my $hlvs_threads=4; +my $hdrc_bin=""; +my $hdrc_select_window=""; +my %jid=(); +my %setmaxheap=(); +my $tapeoutid=$$; +my $summary=0; +my $fullchip=""; + +my %tasks = ( + "fullgds" => 0, + "subgds" => 0, + "fullcdl" => 0, + "fullerc" => 0, + "gdsxor1" => 0, + "gdsxor2" => 0, + "fullhdrc" => 0, + "fullhlvs" => 0, + "fullant" => 0, + "fullbump" => 0, +); + +my %maxheapsize=(); +foreach my $task (sort keys %tasks) { + $maxheapsize{$task}=$maxheapsize; +} + +# Env list for qsub (see also qb for original code +foreach my $e (keys %ENV) { + if (! ($e =~ /^SSH_/) or ( $e =~ /^LD_/) or ( $e =~ /^TERM/ ) ) { + $env{$e} = 1; + } +} + +my $env_vars=join(",", keys %env ); + +sub qrsh { + my ($task, $cmd, $holdid,$flags)=@_; + my $pwd=`pwd`; + chomp $pwd; + print STDERR "$cmd" if $verbose; + unlink "$task.out"; + unlink "$task.err"; + my $taskscript=`mktemp qb.$task.XXXXXX`; + chomp $taskscript; + my $fs; + open ($fs, ">$taskscript"); + print $fs "#!/bin/bash"; + print $fs "cd $pwd"; + print $fs "export CDS_AUTO_64BIT=ALL"; + print $fs "$cmd"; + close $fs; + chmod 0700, $taskscript; + my @holdid=(); + if (defined ($holdid) and $holdid ne "") { + foreach my $tk (split(/,/, $holdid)) { + if ($tasks{$tk} > 1 and defined ($jid{$tk})) { + push @holdid, $jid{$tk}; + } + } + $holdid=join ",", @holdid; + if (defined ($holdid) and length($holdid)) { + $holdid="-hold_jid=$holdid"; + } + else { + $holdid=""; + } + } + else { + $holdid=""; + } + $ENV{QB_DIAG_FILE}="/dev/null"; + $ENV{QB_LOCAL}=0; + $ENV{QB_RUN_NAME}="$task$tapeoutid"; + $ENV{QRSH_FLAGS}="$holdid -cwd -l mem=$maxheapsize{$task} $qsubextras -v '$env_vars' $flags"; + if (my $pid = fork()) { + my $trys=0; + my $jid=0; + while (1) { + $trys++; + if ($trys > 15) { + print STDERR "Could not find submitted jid for task $task"; + last; + } + open ($fs, "nbstatus jobs --fields 'Jobid,Task,StartTime,User' --format csv \"Task='$task$tapeoutid'\" |"); + my $header=<$fs>; + chomp $header; + my @header=split(/,/, $header); + my %ndx=(); + foreach my $n (0..$#header) { + $ndx{$header[$n]}=$n; + } + while (<$fs>) { + chomp; + my @data=split(/,/, $_); + if (($data[$ndx{User}] eq $user) and ($data[$ndx{Task}] eq "$task$tapeoutid")) { + $jid=$data[$ndx{Jobid}] if $data[$ndx{Jobid}] > $jid; + } + } + sleep 1; + last if $jid > 0; + } + $jid{$task}=$jid; + return $jid; + } + else { + system("qb ./$taskscript 1> $task.out 2> $task.err"); + exit 0; + } +} + +sub expandlayers { + my %mask; + my %lpp; + open (MO, "<$pdkroot/share/Fulcrum/stream/maskops.txt") or die "Warning: Cannot open $pdkroot/share/Fulcrum/stream/maskops.txt"; + my $df2=0; + my $gds=0; + while () { + chomp; + s/\t/ /g; + s/ */ /g; + s/^ //; + s/ $//; + next if /^$/; + s/[\(\)]/ /g; + s/ */ /g; + my @f=split; + my $mask=shift @f; + foreach my $f (@f) { + if ($f =~ /;/) { + my ($l,$p)=split(/;/,$f); + $mask{$mask} .= "$l;$p "; + $lpp{"$l;$p"} .= "$mask "; + } + } + } + close MO; + + my %layers=(); + foreach my $layer (split(/,/, $layers)) { + if ($layer =~ /^m/) { + $layer =~ s/^m//; + foreach my $lpp (split(/ /,$mask{$layer})) { + my ($l,$p) = split(/;/, $lpp); + $layers{"$l;$p"}=1; + } + } + else { + $layers{$layer}=1; + } + } + $layers = join(",", sort keys %layers); +} + +sub fullgds { + my $task="fullgds"; + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my $ut= $use_tag ? " --use-tag" : ""; + my $cmd="gdsIIWrite --64 --fulcrum-pdk-root '$pdkroot' --view-name '$viewName' --dfII-dir '$dfIIdir' --cast-path '$castpath' --working-dir '$workingDir' --output-root-cell-name '$rootcellname' --tapeout --flatten-pcells --suppress-pins --max-heap-size '$maxheapsize{$task}' --jre-args '$jreargs' --cell '$cell' --output-bind-file '$rootcellname.bind' --pipo-log=strmOutFull.log --max-name-length=$maxnamelen$ut"; + $cmd .= " --debug" if $debug; + $cmd .= " --output '$outgds'" if $outgds ne ""; + unlink $outgds if $outgds ne ""; + qrsh($task,$cmd,"",""); +} + +sub subgds { + my $task="subgds"; + if (! defined($reducedgds) or $layers eq "*" or $layers eq "") { + print STDERR "Skipping $task because of layers='$layers'" if $verbose; + return 0; + } + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my $ut= $use_tag ? " --use-tag" : ""; + my $cmd="gdsIIWrite --fulcrum-pdk-root '$pdkroot' --view-name '$viewName' --dfII-dir '$dfIIdir' --cast-path '$castpath' --working-dir '$workingDir' --output '$reducedgds' --output-root-cell-name '$rootcellname' --tapeout --flatten-pcells --suppress-pins --max-heap-size '$maxheapsize{$task}' --jre-args '$jreargs' --cell '$cell' --layers '$layers' --max-name-length=$maxnamelen$ut --pipo-log=strmOutSub.log"; + $cmd .= " --debug" if $debug; + unlink $reducedgds; + qrsh ($task,$cmd,"",""); +} + +sub fullcdl { + my $task="fullcdl"; + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } +# my $cmd = "mmonitor \&\n"; + my $cmd = "cast2cdl --fulcrum-pdk-root='$pdkroot' --process-dependent-name --max-heap-size='$maxheapsize{$task}' --cast-path='$castpath' --cell='$cell' --output='$rootcellname.cdl'\n"; +# $cmd .= "pkill -HUP -s 0 mmonitor\npkill -s 0 mmonitor"; + return qrsh($task,$cmd,"",""); +} + +sub gdsxor1 { + # xor of the full gds with the reduced gds expects no errors in the reduced layers + my $task="gdsxor1"; + if (! $tasks{$task} or ! defined ($reducedgds)) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + # notes on qsub + # for holdid use --trigger with nbjob run + # see qb + my $cmd="gdsxor --large --layerlist='$layers' '$outgds' '$reducedgds'"; + qrsh($task,$cmd,"fullgds,subgds","-l drc=1"); +} + +sub gdsxor2 { + # xor of the new full gds with the old full gds if any + my $task="gdsxor2"; + if ( ! defined $prevgds ) { + print STDERR "Skipping $task because prevgds not defined." if $verbose; + return 0; + } + if ( ! -s $prevgds ) { + print STDERR "Skipping $task because $prevgds does not exist." if $verbose; + return 0; + } + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my $cmd="gdsxor --large '$outgds' '$prevgds'"; + qrsh($task,$cmd,"fullgds","-l drc=1"); +} + + +sub fullant { + my $task="fullant"; + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my $rules="$pdkroot/share/Fulcrum/icv/antenna.rul"; + my $cmd = "/bin/rm -rf hant; mkdir hant; cd hant; $ENV{ICV_SCRIPT} icv -c '$rootcellname' -i '../$outgds' '$rules'"; + qrsh($task,$cmd,"fullgds","-l hdrc=1,cc=$hdrc_threads"); +} + +sub fullhdrc { + my $task="fullhdrc"; + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my $rules="$pdkroot/share/Fulcrum/icv/drc.rul"; + # the following has NOT been tried with ICV + if (defined ($hdrc_select_window) and $hdrc_select_window ne "") { + my $fr; + my $fro; + open ($fr, "<$rules") or die "Cannot open '$rules'"; + $hdrc_bin=0; + while ( -f "hdrc-$hdrc_bin.rul" ) { $hdrc_bin++;} + my $newrules="hdrc-$hdrc_bin.rul"; + open ($fro, ">$newrules") or die "Cannot open '$newrules'"; + while (<$fr>) { + chomp; + if (/MAXIMUM_CELLNAME_LENGTH/) { + print $fro $hdrc_select_window; + } + print $fro $_; + } + close $fro; + close $fr; + $rules="../$newrules"; + } + my $cmd = "/bin/rm -rf hdrc$hdrc_bin; mkdir hdrc$hdrc_bin; cd hdrc$hdrc_bin; $ENV{ICV_SCRIPT} icv $fullchip -c '$rootcellname' -i '$outgds' '$rules'"; + qrsh($task,$cmd,"fullgds","-l hdrc=1,cc=$hdrc_threads"); +} + +# FIXME +sub fullbump { + my $task="fullbump"; + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my $cmd = "/bin/rm -rf hbump; mkdir hbump; cd hbump; $ENV{HERC_SCRIPT} hercules -threads $hdrc_threads -b '$rootcellname' -i '$outgds' '$pdkroot/share/Fulcrum/hdrc/hbump.rul'"; + qrsh($task,$cmd,"fullgds","-l hdrc=1,cc=$hdrc_threads"); +} + +sub fullhlvs { + my $task="fullhlvs"; + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my $pwd=`pwd`; + chomp $pwd; + my $cdlname=`echo '$cell' | rename --type=cell --from=cast --to=cadence`; + my $grayarg=""; + if (-s $grayboxlist) { + $grayarg="--gray-cell-list='$grayboxlist'"; + } + my $hlvsmode=""; + if ( -s $grayboxlist ) { + if ( $blackboxhlvs ) { + $hlvsmode="--hlvs-mode=blackbox"; + } + else { + $hlvsmode="--hlvs-mode=graybox"; + } + } + chomp $cdlname; + my $cmd = "/bin/rm -rf hlvs; mkdir hlvs; cd hlvs; hlvs --threads=$hlvs_threads $grayarg $hlvsmode --gds2-file '$outgds' --working-dir='$pwd/hlvs' -64bit=1 --cdl-file '../$rootcellname.cdl' --cdl-cell-name '$cdlname' --priority=0 --mem '$maxheapsize{$task}' --fulcrum-pdk-root '$pdkroot' --plug-wells=0 --merge-paths=0 --tapeout '$rootcellname'"; + qrsh($task,$cmd,"fullgds,fullcdl","-l herc=1,cc=$hlvs_threads"); +} + +# FIXME +sub fullerc { + my $task="fullerc"; + if (! $tasks{$task}) { + print STDERR "Skipping $task because it was not specified." if $verbose; + return 0; + } + my %hold; + $hold{$tasks{fullgds}}=1 if $tasks{fullgds} > 1; + $hold{$tasks{fullcdl}}=1 if $tasks{fullcdl} > 1; + my $holdid=join ",", keys %hold; + my $pwd=`pwd`; + chomp $pwd; + $holdid = "-hold_jid '$holdid'" if length($holdid); + my $cdlname=`echo '$cell' | rename --type=cell --from=cast --to=cadence`; + my $grayarg=""; + if (-s $grayboxlist) { + $grayarg="--gray-cell-list='$grayboxlist'"; + } + my $hlvsmode=""; + if ( -s $grayboxlist ) { + if ( $blackboxhlvs ) { + $hlvsmode="--hlvs-mode=blackbox"; + } + else { + $hlvsmode="--hlvs-mode=graybox"; + } + } + chomp $cdlname; + my $cmd = "hlvs --threads=$hlvs_threads $grayarg $hlvsmode --erc --gds2-file '$outgds' --working-dir='$pwd/herc' -64bit=1 --cdl-file '../$rootcellname.cdl' --cdl-cell-name '$cdlname' --priority=0 --mem '$maxheapsize{$task}' --fulcrum-pdk-root '$pdkroot' --plug-wells=0 --merge-paths=0 --tapeout '$rootcellname'"; + unlink "$task.out"; + unlink "$task.err"; + print STDERR "fullerc"; + my $pid=open2 (\*RD, \*WR, "qsub $holdid -N $task -l a=lx24-amd64,mem=$maxheapsize{$task},herc=1,cc=$hlvs_threads $qsubextras -cwd -o $task.out -e $task.err -v '$env_vars'"); + print WR "#!/bin/bash"; + print WR "/bin/rm -rf herc"; + print WR "mkdir herc"; + print WR "cd herc"; + print WR "$cmd"; + close WR; + my $result = ; + chomp $result; + if ($result =~ /Your job (\d+)/) { + $jid{$task}=$1; + } + close RD; + waitpid($pid,0); + print STDERR $result if $verbose; + my @f=split(/ /,$result); + $f[2]; +} + +my %options = ( + "64" => \$bit64, + "bind-rul=s" => \$bindfile, + "cast-path=s" => \$castpath, + "cell=s" => \$cell, + "use-tag" => \$use_tag, + "check-only" => \$checkonly, + "debug" => \$debug, + "dfII-dir=s" => \$dfIIdir, + "flatten-pcells" => \$flattenpcells, + "fulcrum-pdk-root=s" => \$pdkroot, + "graybox-list=s" => \$grayboxlist, + "hdrc-threads=i" => \$hdrc_threads, + "hlvs-threads=i" => \$hlvs_threads, + "hdrc-select-window=s" => sub { + my ($x1,$y1,$x2,$y2)=split(/,/, $_[1]); + if (defined ($y2) and $y2 > $y1 and $x2 > $x1) { + $hdrc_select_window = "SELECT_WINDOW = [$x1,$y1, $x2,$y2]"; + } + else { + print STDERR "Error: select_window is --hdrc-select_window=x1,y1,x2,y2"; + exit 1; + } + }, + "hlvs-blackbox" => \$blackboxhlvs, + "jre-args=s" => sub { $jreargs .= " $_[1]"; }, + "layers=s" => \$layers, + "max-heap-size=s" => sub { $maxheapsize=$_[1]; + foreach my $task (keys %tasks) { + $maxheapsize{$task}=$maxheapsize if ! $setmaxheap{$task}; + } + }, + "max-name-length=i" => \$maxnamelen, + "output-root-cell-name=s" => \$rootcellname, + "output=s" => \$output, + "previous-gds=s" => \$prevgds, + "qsub-extras=s" => \$qsubextras, + "task=s" => \$tasks, + "verbose" => \$verbose, + "view-name=s" => \$viewName, + "working-dir=s" => \$workingDir, + "full-chip" => sub { $fullchip="-D FULL_CHIP=1"; } +); + +foreach my $task (sort keys %tasks) { + eval "\$options{\"max-heap-size-$task=s\"}=sub { \$maxheapsize{$task}=\$_[1]; \$setmaxheap{$task}=1;}"; +} + +my %help = ( + "64" => "[$bit64] run in 64 bit mode (mostly irrelevant)", + "bind-rul" => "[$bindfile] binding file, if specified", + "cast-path" => "[$castpath] normal cast path", + "cell" => "[$cell] cell cast name", + "check-only" => "[$checkonly] Just check results", + "debug" => "[$debug] progress info plus keep temporary files", + "dfII-dir" => "[$dfIIdir] normal dfII-dir", + "flatten-pcells" => "[$flattenpcells] stream out pcell flattening", + "fulcrum-pdk-root" => "[$pdkroot] fulcrum pdk root path", + "full-chip" => "do full chip DRC rules", + "graybox-list" => "[$grayboxlist] list of cells for black/graybox (cast names)", + "hdrc-threads" => "[$hdrc_threads] threads to use for hdrc", + "hlvs-threads" => "[$hlvs_threads] threads to use for hlvs and erc", + "hdrc-select-window" => "[$hdrc_select_window] restrict area for fullhdrc only", + "hlvs-blackbox" => "[$blackboxhlvs] blackbox (0=graybox if list provided)", + "jre-args" => "[$jreargs] for java sub-tasks", + "layers" => "[$layers] comma separated list of:\n". + " ### (all purposes for this layer)\n". + " ###;### (just this layer,purpose)\n". + " m### (all lpp for this mask)\n". + " * (all lpp's required for tapeout)\n". + " blank/missing (all lpp in tech file)", + "max-heap-size" => "[$maxheapsize] for java sub-tasks and for qsub memory", + "max-heap-size-{task}" => "for java sub-tasks and for qsub memory for specific task", + "max-name-length" => "[$maxnamelen] longest allowed gds name", + "output" => "[$output] output gds file name", + "output-root-cell-name" => "[$rootcellname] rename of top cell from default", + "previous-gds" => "[$prevgds] The gds file from the last tapeout", + "qsub-extras" => "[$qsubextras] longest allowed gds name", + "task" => "[$tasks] list of tasks", + "use-tag" => "[$use_tag] gdsIIWrite generates tag cell", + "verbose" => "[$verbose] more progress info", + "view-name" => "[$viewName] the dfII view name", + "working-dir" => "[$workingDir] usually the current directory", +); + +sub usage { + my ($msg)=@_; + my $name=$0; + $name =~ s:.*/::; + print STDERR $msg if defined $msg; + printf STDERR < 1, "cell" => 1, "fulcrum-pdk-root" => 1, "dfII-dir" => 1 ); + foreach my $option (sort keys %options) { + my $opt = $option; + $opt =~ s/=.*//; + if ( ! defined ($mandatory{$opt})) { + if ($opt eq "max-heap-size") { + print " --$opt $help{$opt}"; + print " --max-heap-size-=mem overrides above"; + } + elsif ( defined ($help{$opt})) { + print " --$opt $help{$opt}"; + } + elsif ($opt !~ /max-heap-size/) { + print " --$opt UNDEFINED HELP"; + } + } + } + exit 1; +} + +my $err=0; +GetOptions ( %options ) or usage; +`mkdir -p "$workingDir"`; +usage("invalid working-dir [$workingDir]") if ! -d $workingDir; +chdir $workingDir; +$output="$rootcellname.gds" if (! defined ($output) or $output eq ""); +$outgds=$output; +my $pwd=`pwd`; +chomp $pwd; +$outgds = "$pwd/$output" if ($output !~ /\//) and $output ne ""; +usage("output-root-cell-name not defined") if $rootcellname eq ""; +usage("view-name not specified") if $viewName eq ""; +usage("cell name not specified") if $cell eq ""; +usage("invalid dfII-dir [$dfIIdir]") if ! -f "$dfIIdir/cds.lib.generated"; +usage("invalid pdk root [$pdkroot]") if ! -d $pdkroot; +my $err=0; +foreach my $dir (split(/:/,$castpath)) { + if ( ! -d $dir ) { + $err++; + } +} +usage("Invalid cast-path [$castpath]") if $err; + +expandlayers if $layers =~ /m/; + +my $taskerr=0; + +$summary = 1 if $tasks =~ /summary/; +if (! defined($tasks) or $tasks eq "") { + foreach my $key (keys %tasks) { + $tasks{$key}=1; + } +} +elsif (! ($tasks =~ /summary/)) { + foreach my $key (split(/,/, $tasks)) { + if (defined ($tasks{$key})) { + $tasks{$key} = 1; + } + else { + print STDERR "Illegal task $key"; + $taskerr++; + } + } +} + +usage "Task error" if ($taskerr); +usage "dfII-dir improperly specified" if ! -d "$dfIIdir" or ! -s "$dfIIdir/cds.lib.generated"; + +if (! -s "cds.lib" ) { + my $pwd=`pwd`; + chomp $pwd; + system "mkcdswd --target-dir='$pwd' --dfII-dir='$dfIIdir' --fulcrum-pdk-root='$pdkroot'"; +} + +if ( ! -s "cds.lib" or ! -s "assura_tech.lib") { + print STDERR "Fatal: files cds.lib and assura_tech.lib not found."; + exit 1; +} + +$assura_technology = `awk '/^DEFINE Assura_/ {print \$2}' assura_tech.lib`; +chomp $assura_technology; + +sub checkfullgds { + if ( ! -s "$output") { + print STDERR "Error: fullgds failed to generate a file"; + return 1; + } + else { + print STDERR "Fullgds Run without Errors"; + } + 0; +} + +sub checksubgds { + if ( defined $reducedgds ) { + if ( ! -s "$reducedgds" ) { + print STDERR "Error: subgds had no output $reducedgds"; + return 1; + } + } + 0 +} + +sub checkfullcdl { + if ( ! -s "$rootcellname.cdl") { + print STDERR "Error: fullcdl failed to generate a file"; + return 1; + } + print STDERR "Fullcdl Run without Errors"; + 0; +} + +sub checkfullerc { + if (! -f "herc/$rootcellname.LVS_ERRORS") { + print STDERR "Error: fullerc did not run"; + return 1; + } + my $hercerr1=1; + if (open (P, ") { + chomp; + last if /ERROR DETAILS/; + $hercerr1=1 if /violations/ and ! /ERR_DUP_PLCMT/; + } + } + print STDERR "Herc ERC Run without Errors" if ! $hercerr1; + print STDERR "Herc ERC Run with Errors" if $hercerr1; + if (! -f "herc/$rootcellname.LAYOUT_ERRORS") { + print STDERR "Error: fullerc did not finish"; + return 1; + } + print STDERR "ERC Run without Errors" if ! $hercerr1; + $hercerr1; +} + +sub checkfullhdrc { + if (! -f "hdrc$hdrc_bin/$rootcellname.LAYOUT_ERRORS") { + print STDERR "Error: hdrc did not run"; + return 1; + } + my $hdrcerr=`grep -c ' violation.*found' 'hdrc$hdrc_bin/$rootcellname.LAYOUT_ERRORS'`; + chomp $hdrcerr; + print STDERR "Error: Hercules drc errors in hdrc$hdrc_bin/$rootcellname.LAYOUT_ERRORS" if ($hdrcerr); + print STDERR "HDRC Run without Errors" if ! $hdrcerr; + $hdrcerr; +} + +sub checkfullant { + if (! -f "hant/$rootcellname.LAYOUT_ERRORS") { + print STDERR "Error: hant did not run"; + return 1; + } + my $hanterr=`grep -c ' violation.*found' 'hant/$rootcellname.LAYOUT_ERRORS'`; + chomp $hanterr; + print STDERR "Error: Hercules antenna drc errors in hant/$rootcellname.LAYOUT_ERRORS" if ($hanterr); + print STDERR "Herc Antenna Run without Errors" if ! $hanterr; + $hanterr; +} + +sub checkfullbump { + if (! -f "hbump/$rootcellname.LAYOUT_ERRORS") { + print STDERR "Error: fullbump did not run"; + return 1; + } + my $hdrcerr=`grep -c ' violation.*found' 'hbump/$rootcellname.LAYOUT_ERRORS'`; + chomp $hdrcerr; + print STDERR "Error: Hercules drc errors in hbump/$rootcellname.LAYOUT_ERRORS" if ($hdrcerr); + print STDERR "HBUMP Run without Errors" if ! $hdrcerr; + $hdrcerr; +} + +sub checkgdsxor1 { + if ( ! -s "gdsxor1.out") { + print STDERR "Error: gdsxor1 did not run"; + return 1; + } + my $match=`grep -c 'No shape was written to the output file' gdsxor1.out`; + chomp $match; + if ($match != 1) { + print STDERR "Error: Mismatches in gdsxor1 ($match)"; + return 1; + } + print STDERR "XOR1 Run without Errors"; + 0; +} + +sub checkgdsxor2 { + if ( ! -s "gdsxor2.out") { + print STDERR "Error: gdsxor2 did not run"; + return 1; + } + my $match=`grep -c 'No shape was written to the output file' gdsxor2.out`; + chomp $match; + if ($match == 1) { + print STDERR "Error: gdsxor2 shows no differences, quite odd"; + return 1; + } + my @egreplist=(); + foreach my $lpp (split(/,/, $layers)) { + my ($l,$p) = split(/;/, $lpp); + push @egreplist, "Layer\\( $l $p \\)"; + } + my $egreplist=join("|", @egreplist); + my $invalid = `egrep -cv '$egreplist' gdsxor2.out`; + print STDERR "grep -cv '$egreplist' gdsxor2.out" if $verbose; + chomp $invalid; + if ($invalid > 0) { + system "egrep -v '$egreplist' gdsxor2.out"; + return $invalid; + } + print STDERR "XOR2 Run without Errors"; + 0; +} + +sub checkfullhlvs { + if (! -f "hlvs/$rootcellname.LVS_ERRORS") { + print STDERR "Error: fullhlvs did not run"; + return 1; + } + my $hlvserr=1; + open (P, ") { + chomp; + $hlvserr=0 + if(/TOP BLOCK COMPARE RESULT.*: PASS/i); + } + print STDERR "Herc LVS Run without Errors" if ! $hlvserr; + print STDERR "Herc LVS Run with Errors" if $hlvserr; + $hlvserr; +} + +sub summarize { + my @holdid=(); + foreach my $task (keys %tasks) { + if ($tasks{$task} > 1) { + if (defined ($jid{$task})) { + push @holdid, $jid{$task}; + } + } + } + my $holdid="-hold_jid=".join ",", @holdid; + if (@holdid) { + open (S, ">waitscript"); + print S "#!/bin/bash"; + print S "exit 0"; + close S; + chmod 0700, "waitscript"; + sleep 1; + $ENV{QB_DIAG_FILE}="/dev/null"; + $ENV{QB_LOCAL}=0; + $ENV{QB_RUN_NAME}="wait$tapeoutid"; + $ENV{QRSH_FLAGS}="$holdid"; + system("qb ./waitscript 1>/dev/null 2>/dev/null"); + } + my $err=0; + $err += checkfullgds if $tasks{fullgds} or $summary; + $err += checksubgds if $tasks{subgds} or $summary; + $err += checkfullcdl if $tasks{fullcdl} or $summary; + $err += checkfullhdrc if $tasks{fullhdrc} or $summary; + $err += checkfullant if $tasks{fullant} or $summary; + $err += checkfullbump if $tasks{fullbump} or $summary; + $err += checkgdsxor1 if $tasks{gdsxor1} or $summary; + $err += checkgdsxor2 if $tasks{gdsxor2} or $summary; + $err += checkfullhlvs if $tasks{fullhlvs} or $summary; + $err += checkfullerc if $tasks{fullerc} or $summary; + $err; +} + +if (defined ($layers) and $layers ne "" and $layers ne "*") { + $reducedgds = $output; + $reducedgds =~ s/\.g[^\.]*$//; + $reducedgds .= "_${layers}_only.gds"; + $reducedgds =~ s/,//g; + $reducedgds =~ s/;//g; +} + +# run the tasks +if (! $checkonly) { + $tasks{fullgds} = fullgds; + $tasks{subgds} = subgds; + $tasks{fullcdl} = fullcdl; + $tasks{gdsxor1} = gdsxor1; + $tasks{gdsxor2} = gdsxor2; + $tasks{fullbump} = fullbump; + $tasks{fullhlvs} = fullhlvs; + $tasks{fullerc} = fullerc; + $tasks{fullant} = fullant; + $tasks{fullhdrc} = fullhdrc; +} + +my $err=summarize; +print STDERR "--------------------"; +if ($err) { + print STDERR "Tapeout finished with errors"; + exit $err; +} +print STDERR "Tapeout finished with NO errors"; +if (! $debug ) { + `/bin/rm -f qb.* waitscript xStrmOut_cellMap.txt strmOut*.log`; +} +exit 0; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/cdlsize265.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/cdlsize265.pl new file mode 100755 index 0000000000..8235dc3dcd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/cdlsize265.pl @@ -0,0 +1,87 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +my $verbose=0; +my $debug = 0; +# default layer mapping + +my %options = ( + "verbose" => \$verbose, + "debug" => \$debug, +); +my $prefix="outfile$$"; + +GetOptions ( %options ) or usage(); + +my $in = $ARGV[0]; +my $tmpout=$in; +if ($tmpout =~ /\//) { + $tmpout =~ s:/([^/]+$):/tmp$1:; +} +else { + $tmpout = "tmp$tmpout"; +} +usage() if ! defined $in; + + +sub usage { + my ($msg)=@_; + print STDERR "$msg" if defined $msg; + print STDERR <) { + chomp; + my @f=split; + foreach my $n (0..$#f) { + $f[$n]="nmospd_sr" if ($f[$n] eq "nmos_sram"); + $f[$n]="pmospu_sr" if ($f[$n] eq "pmos_sram"); + if ($f[$n] =~ /=/) { + if ($f[$n] =~ /^(\+)?(\S+)=(\S+)$/) { + my $pl=$1; + my $p=$2; + my $v=$3; + if ($v =~ /u$/) { + $v =~ s/u$//; + $v *= 1e-6; + } + if ($v != 0) { + if ($p =~ /^[np]w/i or $p =~ /^w$/i) { + $v *= 0.6; + $v += 0.03e-6 if $v < 1.2e-7; + $v = sprintf "%.8e", $v; + $v =~ s/0+e/e/; + $v =~ s/\.e/e/; + $f[$n] = "$pl$p=$v"; + } + if ($p =~ /^[np]l/i or $p =~ /^l$/i) { + $v = $v * 0.6; + $v = sprintf "%.8e", $v - 0.018e-6; + $v =~ s/0+e/e/; + $v =~ s/\.e/e/; + $f[$n] = "$pl$p=$v"; + } + } + } + } + } + push @lines, join(" ", @f); +} + +close P; +system "/bin/mv '$in' '$in.130'"; +open (P, ">$in"); +print P join("\n", @lines); +close P; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/ensurecelllib b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/ensurecelllib new file mode 100755 index 0000000000..2d7f95c3df --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/ensurecelllib @@ -0,0 +1,125 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +function usage() { + echo "$0 --cds-wd=dir --generated-libraries-root=dir --blank-cds-library=dir --cell=cellname --lib=libname --short-name=cellshortname --lib-dir=librarydir --cell-dir=celldir --cell-number=num --number-of-cells=numcells --percent-complete=percentcomplete" +} + + +sedcmd=`which sed` +grepcmd=`which grep` +gawkcmd=`which gawk` +findcmd=`which find` +bashcmd=`which bash` + +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$grepcmd" "Unable to find grep in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Unable to find gawk in \"$PATH\"" 2 +check_executable_file "$findcmd" "Unable to find find in \"$PATH\"" 2 +check_executable_file "$bashcmd" "Unable to find bash in \"$PATH\"" 2 + +cds_wd= +generated_libs_root= +blank_cds_library= +lib_commands_dir= +sh_lib_dir= + +lib= + +cell_num= +cell_count= +percent_complete= + +for arg in $@ ; do + + case "$arg" in + --cds-wd=* ) + cds_wd=`echo $arg | $sedcmd -e "s/--cds-wd=//"` + ;; + --generated-libraries-root=* ) + generated_libs_root=`echo $arg | $sedcmd -e "s/--generated-libraries-root=//"` + ;; + --blank-cds-library=* ) + blank_cds_library=`echo $arg | $sedcmd -e "s/--blank-cds-library=//"` + ;; + --library-commands-dir=* ) + lib_commands_dir=`echo $arg | $sedcmd -e "s/--library-commands-dir=//"` + ;; + --shell-library=* ) + sh_lib_dir=`echo $arg | $sedcmd -e "s/--shell-library=//"` + ;; + --lib=* ) + lib=`echo $arg | $sedcmd -e "s/--lib=//"` + ;; + --number-of-cells=* ) + cell_count=`echo $arg | $sedcmd -e "s/--number-of-cells=//"` + ;; + --percent-complete=* ) + percent_complete=`echo $arg | $sedcmd -e "s/--percent-complete=//"` + ;; + esac +done + +check_for_empty_arg "$cds_wd" "You must specify the cadence working directory." 2 +check_for_empty_arg "$generated_libs_root" "A generated libraries root directory was not specified." 2 +check_for_empty_arg "$blank_cds_library" "A directory containing a blank cadence library was not specified." 2 +check_for_empty_arg "$lib_commands_dir" "You must specify the library commands directory." 2 + +check_for_empty_arg "$sh_lib_dir" \ + "The directory containing the shell script library was not specified." 2 + +check_for_empty_arg "$lib" "\"$cell\"'s library was not specified." 2 + + +check_writeable_dir "$cds_wd" "Cadence Working Directory: \"$cds_wd\" is not a readable, writeable directory." 2 +conon_path "$cds_wd" +cds_wd="$ret" + +check_writeable_dir "$generated_libs_root" \ + "Generated Libraries Root Directory: \"$generated_libs_root\" is not a readable, writeable directory." 2 +conon_path "$generated_libs_root" +generated_libs_root="$ret" + +check_readable_dir "$blank_cds_library" \ + "Blank Cadence Library: \"$blank_cds_library\" is not a readable directory." 2 +conon_path "$blank_cds_library" +blank_cds_library="$ret" + + +check_readable_dir "$sh_lib_dir" "Shell Library: \"$sh_lib_dir\" is not a readable directory." 2 +conon_path "$sh_lib_dir" +sh_lib_dir="$ret" + +check_readable_dir "$lib_commands_dir" \ + "Library Commands Directory: \"$lib_commands_dir\" is not a readable directory." 2 +conon_path "$lib_commands_dir" +lib_commands_dir="$ret" + +mkcdslib_src="$lib_commands_dir/mkcdslib" +check_readable_file "$mkcdslib_src" \ + "mkcdslib: \"$mkcdslib_src\" is not a readable file." 2 + + +cmd_tmp_dir=`mktemp -d /tmp/ensurecelllib.XXXXXX` + +generate_command_script "$cmd_tmp_dir" "$mkcdslib_src" "$sh_lib_dir" "$bashcmd" +mkcdslib="$ret" + +if [[ -n "$cell_num" && -n "$cell_count" ]] ; then + echo "Doing $cell ( $cell_num of $cell_count )" +fi + +$mkcdslib --cds-wd=$cds_wd \ + --generated-libraries-root=$generated_libs_root \ + --blank-cds-library=$blank_cds_library \ + --lib=$lib + +rm -rf $cmd_tmp_dir + +if [ -n "$percent_complete" ] ; then + echo "$percent_complete% complete." +fi + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/gdsIIWrite.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/gdsIIWrite.pl new file mode 100755 index 0000000000..273dbee83a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/gdsIIWrite.pl @@ -0,0 +1,1204 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use IPC::Open2; +use Getopt::Long; +my $user=$ENV{USER}; +$user="nobody" if ($user eq ""); + +sub setfilemode { + my ($file)= @_; + if (defined ($ENV{LVE_FILEMODE}) and -f "$file" ) { + chmod $ENV{LVE_FILEMODE}, "$file"; + if (defined($ENV{LVE_SGID}) and $ENV{LVE_SGID} == 1) { + `chgrp $ENV{LVE_GID} "$file" &>/dev/null`; + } + } +} + +sub setdirmode { + my ($dir) = @_; + if (defined ($ENV{LVE_DIRMODE}) and -d "$dir") { + chmod $ENV{LVE_DIRMODE}, "$dir"; + if (defined($ENV{LVE_SGID}) and $ENV{LVE_SGID} == 1) { + `chgrp $ENV{LVE_GID} "$dir" &>/dev/null`; + } + } +} + +sub conon_path { + my ($patharg)=@_; + my $pwd=`pwd`; + chomp $pwd; + my $path=$patharg; + my $tail=""; + if ( ! -d $path ) { + $path =~ s:(/[^\/]+)$::; + $tail = $1; + } + if (! -d $path ) { + print STDERR "Warning: Cannot cononicalize $patharg" if $tail ne ""; + return $patharg; + } + chdir $path; + $path=`pwd`; + chomp $path; + chdir $pwd; + $path =~ s:^/mnt/fulcrum/home/:/home/:; + $path .= $tail; + $path; +} + +my $err=0; +my $ipid=0; +my $cpid=0; +my $n2pid=0; +my $c2pid=0; +my $i2pid=0; + +my $verbose=0; +my $maxnamelen=0; + +local(*IRD,*IWR); +sub iconvert { + my $in = $_[0]; + local($_); + $in =~ s:/:.:g; + $in =~ s:\\::g; + # hack because renamer does not recognize '$', use '_' to be consistent with vs2cast + $in =~ s/\$/_/g; + if ($ipid <= 0) { + $ipid=open2 (\*IRD,\*IWR, "rename --from=cadence --to=gds2 --type=instance"); + } + print IWR "$in"; + $_=$in; + $_=; + chomp $_; + if ($_ eq "") { + $_=$in; + $err++; + } + $_; +} + +local(*CRD,*CWR); +sub cconvert { + my $in = $_[0]; + # hack because renamer does not recognize '$', use '_' to be consistent with vs2cast + $in =~ s/\$/_/g; + local($_); + if ($cpid <= 0) { + $cpid=open2 (\*CRD,\*CWR, "rename --from=cast --to=cadence --type=cell"); + } + print CWR "$in"; + $_="$in"; + $_=; + chomp $_; + if ($_ eq "") { + $_=$in; + $err++; + } + $_; +} + +local(*C2RD,*C2WR); +sub c2convert { + my $in = $_[0]; + # hack because renamer does not recognize '$', use '_' to be consistent with vs2cast + $in =~ s/\$/_/g; + local($_); + if ($c2pid <= 0) { + $c2pid=open2 (\*C2RD,\*C2WR, "rename --from=gds2 --to=cast --type=cell"); + } + print C2WR "$in"; + $_="$in"; + $_=; + chomp $_; + if ($_ eq "") { + $_=$in; + $err++; + } + $_; +} + +local(*I2RD,*I2WR); +sub i2convert { + my $in = $_[0]; + # hack because renamer does not recognize '$', use '_' to be consistent with vs2cast + $in =~ s/\$/_/g; + local($_); + if ($i2pid <= 0) { + $i2pid=open2 (\*I2RD,\*I2WR, "rename --from=gds2 --to=cast --type=instance"); + } + print I2WR "$in"; + $_="$in"; + $_=; + chomp $_; + if ($_ eq "") { + $_=$in; + $err++; + } + $_; +} + +local(*N2RD,*N2WR); +sub n2convert { + my $in = $_[0]; + # hack because renamer does not recognize '$', use '_' to be consistent with vs2cast + $in =~ s/\$/_/g; + local($_); + if ($n2pid <= 0) { + $n2pid=open2 (\*N2RD,\*N2WR, "rename --from=gds2 --to=cast --type=node"); + } + print N2WR "$in"; + $_="$in"; + $_=; + chomp $_; + if ($_ eq "") { + $_=$in; + $err++; + } + $_; +} + +sub get_lib_name { + my $in = $_[0]; + $in =~ s/\.[^\.]+$//; + $in =~ s/\.[^\.]+$//; + $in; +} + +my $template=< \$srcViewName, + "cell=s" => \$cell, + "dfII-dir=s" => \$dfIIdir, + "fulcrum-pdk-root=s" => \$pdkroot, + "cast-path=s" => \$castpath, + "working-dir=s" => \$workingDir, + "output=s" => \$output, + "bind-rul=s" => \$bindfile, + "output-bind-file=s" => \$outbind, + "output-root-cell-name=s" => \$rootcellname, + "cadence-log=s" => \$cadencelog, + "assura-log=s" => \$assuralog, + "pipo-log=s" => \$pipolog, + "verbose" => \$verbose, + "debug" => \$debug, + "flatten-pcells" => \$flattenpcells, + "flatten-vias" => \$flattenvias, + "scale=f" => \$scale, + "64" => \$bit64, + "suppress-pins" => \$suppresspins, + "max-heap-size=s" => \$maxheapsize, + "jre-args=s" => \$jreargs, + "jre=s" => \$jre, + "65mode:i" => \$sixtyfivemode, + "tapeout" => \$tapeout, + "layers=s" => \$layers, + "max-name-length=i" => \$maxnamelen, + "noproperties" => \$noproperties, + "use-tag" => \$use_tag, + "tag-orientation=s" => \$tag_orientation, + "verilog" => \$verilog, + "skip-libs=s" => sub { push @skip_libs,split(/,/,$_[1]);}, +); + +my %help = ( + "layers" => "comma separated list of:\n". + " ### (all purposes for this layer)\n". + " ###;### (just this layer,purpose)\n". + " m### (all lpp for this mask)\n". + " * (all lpp's required for tapeout)\n". + " blank/missing (all lpp in tech file)", + "view-name" => "the dfII view name", + "cell" => "cell cast name", + "dfII-dir" => "normal dfII-dir", + "fulcrum-pdk-root" => "fulcrum pdk root path", + "cast-path" => "normal cast path", + "working-dir" => "usually the current directory", + "output" => "output gds file name", + "bind-rul" => "binding file, if specified", + "output-root-cell-name" => "rename of top cell from default", + "cadence-log" => "for layout.exe log file", + "assura-log" => "for assura logging (65mode only)", + "pipo-log" => "stream out log file", + "verbose" => "more progress info", + "debug" => "progress info plus keep temporary files", + "flatten-pcells" => "stream out pcell flattening", + "flatten-vias" => "stream out with via flattening", + "scale=f" => "scale results (not sure this works)", + "64" => "run in 64 bit mode", + "suppress-pins" => "pipo suppress pins mode", + "max-heap-size" => "for java sub-tasks", + "jre-args" => "for java sub-tasks", + "jre" => "for java sub-tasks", + "65mode" => "used when translating cells, not for normal use", + "tapeout" => "fast mode for tapeout", + "noproperties" => "for smaller files, do not write properties", + "skip-libs" => "comma separated list of libs to skip or 'all' to just to the top lib", +); + +sub usage { +my $name=$0; +$name =~ s:.*/::; +printf <) { + chomp; + s/\t/ /g; + s/ *;.*//; + s/^ *//; + s/ */ /g; + s/^ //; + if (/^streamLayers\(/) { + $ld=1; + next; + } + if (/^\)/) { + $ld=0; + next; + } + if ($ld) { + s/[\(\)"]/ /g; + s/ */ /g; + s/^ //; + s/ $//; + my ($name,$purpose,$nr,$dt,$tr)=split; + next if $tr ne "t"; + next if $nr == 0; + $strm{"$name $purpose"}="$nr;$dt"; + $strm{"$nr;$dt"} .= "$name $purpose "; + } + } + close TF; + open (MO, "<$pdkroot/share/Fulcrum/stream/maskops.txt") or die "Warning: Cannot open $pdkroot/share/Fulcrum/stream/maskops.txt"; + my $df2=0; + my $gds=0; + while () { + chomp; + s/\t/ /g; + s/ */ /g; + s/^ //; + s/ $//; + next if /^$/; + s/[\(\)]/ /g; + s/ */ /g; + my @f=split; + my $mask=shift @f; + foreach my $f (@f) { + if ($f =~ /;/) { + my ($l,$p)=split(/;/,$f); + $mask{$mask} .= "$l;$p "; + $lpp{"$l;$p"} .= "$mask "; + } + } + } + close MO; + my $star=0; + if ($layers eq "*" or $layers eq "**") { + $star=1; + $star=2 if $layers eq "**"; + $layers = "1"; + # required IP layer for full tapeout + $mask{1024} = "63;63"; + $lpp{"63;63"} = "1024"; + for(my $n = 1; $n <= 255; $n++) { + $layers .= ",$n"; + } + } + my %done; + my %masksaffected; + $layertable = "$gdsIIDataDir/layertable"; + $opened = 1; + open (LT, ">$layertable") or $opened = 0; + foreach my $lpp (split(/,/,$layers)) { + my ($layer,$purpose)=split(/;/,$lpp); + my $count=0; + if ($layer =~ /^\d+$/ and ($purpose eq "" or $purpose =~ /^\d+$/)) { + if ($purpose eq "") { + for (my $p = 0; $p <= 255; $p++) { + my $lpp = "$layer;$p"; + next if ! $strm{$lpp}; # if not in tech file + next if ! $lpp{$lpp} and $star != 2; # if not in mask ops + $strm{$lpp} =~ s/ $//; + my @an=split(/ /,$strm{$lpp}); + foreach my $mask (split(/ /,$lpp{$lpp})) { + $masksaffected{$mask}=1; + } + for (my $n = 0; $n < $#an; $n += 2) { + my $string = "$an[$n] $an[$n+1] $layer $p"; + print LT "$string" if ! $done{$string}; + $done{$string}=1; + $count++; + } + } + } + else { + my $lpp="$layer;$purpose"; + if (! $strm{$lpp}) { + warn "$lpp is not in tech file"; + } + if (! $lpp{$lpp} and $star != 2) { + warn "$lpp is not in mask ops"; + } + if ($strm{$lpp} and ($lpp{$lpp} or $star == 2)) { + $strm{$lpp} =~ s/ $//; + my @an=split(/ /,$strm{$lpp}); + foreach my $mask (split(/ /,$lpp{$lpp})) { + $masksaffected{$mask}=1; + } + for (my $n = 0; $n < $#an; $n += 2) { + my $string = "$an[$n] $an[$n+1] $layer $purpose"; + print LT "$string" if ! $done{$string}; + $done{$string}=1; + $count++; + } + } + } + if ($count==0) { + my $lpp = "$layer;$purpose"; + $lpp .= "*" if $purpose eq ""; + print STDERR "Warning: lpp $lpp does not exist" + if ! $star; + } + } + elsif ($layer =~ /^m/i) { + $layer =~ s/^m//; +# $masksaffected{$layer} = 1 if defined $lpp{$layer}; + foreach my $lpp (split(/ /,$mask{$layer})) { + my ($l,$p) = split(/;/, $lpp); + $strm{$lpp} =~ s/ $//; + my @an = split(/ /, $strm{$lpp}); + foreach my $mask (split(/ /, $lpp{$lpp})) { + $masksaffected{$mask}=1; + } + for (my $n = 0; $n < $#an; $n += 2) { + my $string = "$an[$n] $an[$n+1] $l $p"; + print LT "$string" if ! $done{$string}; + $done{$string}=1; + $count++; + } + } + } + else { + print STDERR "$lpp is malformed or undefined in layer list"; + $err++; + } + } + close LT; + $layertable="" if ! $opened; + if ($err) { + unlink $layertable; + exit 1; + } + if (! $star) { + print "MASKS AFFECTED:" if %masksaffected; + foreach my $mask (sort keys %masksaffected) { + print "MASK $mask"; + } + } +} +$verbose = 1 if $debug; +print STDERR "$0 @args" if $verbose; +if ($verbose) { + foreach my $opt (sort keys %options) { + my $xx=$opt; + $xx =~ s/=.*//; + my $value="undef"; + my $value = ${$options{$opt}} + if defined $options{$opt}; + print " --$xx=[$value]" if $value ne ""; + } +} +$err+=check_empty_arg "$cell", "The cell that you want to stream out must be specified."; +$err+=check_empty_arg "$dfIIdir", "You must specify the location of directory containing all the dfII data."; +$err+=check_readable_dir "$dfIIdir", "dfII dir" if $dfIIdir ne ""; +$err+=check_readable_file "$dfIIdir/cds.lib.generated", "dfII cds.lib.generated" + if $dfIIdir ne ""; +$err+=check_empty_arg "$pdkroot", "You must specify the location of the fulcrum pdk you want to use."; +$err+=check_readable_dir "$pdkroot", "fulcrum pdk root" if $pdkroot ne ""; +$err+=check_empty_arg "$castpath", "You must specify a cast-path"; +foreach my $path (split (/:/,$castpath)) { + $err+=check_readable_dir "$path", "Cast Directory"; +} +#$err+=check_empty_arg "$workingDir", "You must specify a working-dir"; +$err+=check_readable_dir "$workingDir", "Working Directory"; +#$err+=check_empty_arg "$bindfile", "You must specify an output bind.rul filename."; +$err+=check_empty_arg "$cadencelog", "You must specify a cadence log file."; +$err+=check_empty_arg "$assuralog", "You must specify a assura log file."; +$err+=check_empty_arg "$srcViewName", "You must specify the view of,\"$cell\" that you want to stream to GDSII."; +my $assurarule = "$pdkroot/share/Fulcrum/assura/bind.rul"; +#$err+=check_readable_file "$assurarule", "Cannot find Assura bind.rul file in PDK" +# if $pdkroot ne ""; +my $propmap = "$pdkroot/share/Fulcrum/stream/prop.map"; +$err+=check_readable_file "$propmap", "Cannot find prop.map file in PDK" + if $pdkroot ne ""; +usage if $err; + +$libName = get_lib_name $cell; +$dfIIdir=conon_path $dfIIdir; +$bindfile=conon_path $bindfile if $bindfile ne "/dev/null"; +$output=conon_path $output if defined $output and $output ne ""; +$cadencelog=conon_path $cadencelog if $cadencelog ne "/dev/null"; +$assuralog=conon_path $assuralog if $assuralog ne "/dev/null"; +$pipolog=conon_path $pipolog if defined $pipolog; + +my %list=(); +my %cbinding=(); +my %gbinding=(); +my %nbinding=(); +my %ibinding=(); + +sub checkTagCell { + my ($cadcellname,$srcViewName,$viewName) = @_; + my $celldir=$cadcellname; + $celldir =~ s/-/#2d/g; + $celldir =~ s/\./#2e/g; + $celldir = "$libName/$celldir"; + $celldir =~ s/\./\//g; + $celldir = "$dfIIdir/$celldir"; + my @src=stat("$celldir/$srcViewName/layout.oa"); + my @tag=stat("$celldir/$viewName/layout.oa"); + return (! @tag) or $tag[9] < $src[9] or $tag[7]==0; +} + +sub gethier { + my($cell, $library)=@_; + my $path=$cell; + return if $library eq "symbolic"; + return if (defined ($list{$cell})); + $path =~ s/\.\d+$//; + $path =~ s/\.[^\.]+$//; + $path =~ s:\.:/:g; + $path = "$dfIIdir/$path"; + my $dir=$cell; + $dir =~ s/\(/-L/g; + $dir =~ s/\)/-R/g; + $list{$cell}=1; + $dir =~ s/\./#2e/g; + $dir =~ s/-/#2d/g; + $path = "$path/$dir/$srcViewName/pc.db"; + local(*P,$_); + if (open (P, "<$path")) { + while (

    ) { + chomp; + my ($lib,$name,$lib)=split; + if (defined ($name)) { + gethier ($name,$lib); + } + } + } +} + +my $generateGDSIIDataOptions=""; +$generateGDSIIDataOptions .= " --cadence-name" if ( $cadenceName ); +my $bit64arg = ""; +$bit64arg = " --64" if $bit64; +$generateGDSIIDataOptions .= $bit64arg; + +my $gdsIIDataOutput = `mktemp "$workingDir/gdsIIWriteDataOut.XXXXXX"`; +chomp $gdsIIDataOutput; +setfilemode $gdsIIDataOutput; + +my $generateGDSIIData="generate_gdsII_data"; +$generateGDSIIData .= " \"--bind-all-nodes\""; +$generateGDSIIData .= " \"--max-heap-size=$maxheapsize\""; +$generateGDSIIData .= " \"--jre-args=$jreargs\""; +$generateGDSIIData .= " \"--jre=$jre\"" if $jre ne "" and -d $jre; +$generateGDSIIData .= " \"--cast-path=$castpath\""; +$generateGDSIIData .= " \"--cell=$cell\""; +$generateGDSIIData .= " \"--bind-rul=$assurarule\"" + if ( -s "$assurarule" ); +$generateGDSIIData .= " \"--output-dir=$gdsIIDataDir\""; +$generateGDSIIData .= " \"--output-root-cell-name=$rootcellname\""; +$generateGDSIIData .= " $generateGDSIIDataOptions \&> \"$gdsIIDataOutput\""; + +if (! $tapeout ) { +print "$generateGDSIIData" if $verbose; +`$generateGDSIIData`; +if ($? != 0) { + $err = 1; + print STDERR "\"$generateGDSIIData\" exited with status: $?\n"; + exit $err; +} + +opendir (DD, "$gdsIIDataDir"); +foreach my $il (grep(/\.il$/, readdir(DD))) { + unlink "$gdsIIDataDir/$il"; +} +closedir DD; + +`/bin/cp '$gdsIIDataDir/bind.rul' '$bindfile'` if $bindfile ne "/dev/null"; +`/bin/cp '$gdsIIDataDir/bind.rul' 'bind.rul'`; +print STDERR "$gdsIIDataDir/bind.rul"; +open (D, "<$gdsIIDataDir/bind.rul"); +my $cl=""; +while () { + chomp; + my ($type,$dfii,$gds)=split; + if (/^C/) { + my $pipo=$dfii; + print STDERR; + $pipo =~ s/[^a-zA-Z0-9_]/_/g; + my $st=$gds; + my $fst="undef"; + if ($verilog and $gds ne $rootcellname) { + my $x=c2convert($gds); + $fst=$x; + $x =~ s/\(/_L_/g; + $x =~ s/\)/_R_/g; + $x =~ s/\./__/g; + $x =~ s/[^A-Za-z0-9_]/_/g; + $gds=$x; + } + $cbinding{$pipo}=$gds; + $gbinding{$dfii}=$pipo; + print STDERR "BINDC $st => $fst => $gds"; +# print STDERR "BINDG $dfii => $pipo" if /SRAMFIFO32/; + $cl=$gds; + } + elsif (/^N/) { + if ($verilog) { + my $x = n2convert($gds); + $x =~ s/\(/_L_/g; + $x =~ s/\)/_R_/g; + $x =~ s/\./__/g; + $x =~ s/[^A-Za-z0-9_]/_/g; + $gds=$x; + } + $nbinding{"$cl $dfii"} = $gds; + } + if (/^I/) { + if ($verilog) { + my $x=i2convert($gds); + $x =~ s/\(/_L_/g; + $x =~ s/\)/_R_/g; + $x =~ s/\./__/g; + $x =~ s/[^A-Za-z0-9_]/_/g; + $gds=$x; + } + $ibinding{"$cl $dfii"} = $gds; + } +} +close D; +} +my $myrsf=$template; +# make sure we have the property maps correct +my %propmap; +if (! $noproperties) { + open (P, "<$propmap"); + while (

    ) { + chomp; + if (/^\d/) { + my ($nr,$type,$name)=split; + $propmap{$type}[0]=$nr if (defined ($name)); + $propmap{$type}[1]=$name if (defined ($name)); + } + } + close P; +} +$pipolog = "$cdsWD/strmOut.log" if ($debug or ! defined $pipolog); +my $mkcdswd="mkcdswd \"--dfII-dir=$dfIIdir\" \"--fulcrum-pdk-root=$pdkroot\" \"--cast-path=$castpath\" \"--target-dir=$cdsWD\" \"--force\""; +if ( $verbose ) { + print "Making cadence working directory."; + print "$mkcdswd"; +} +system "$mkcdswd"; + +if ($use_tag) { + my $ft; + my $pc=`echo '$cell' | rename --type=cell --from=cast --to=cadence`; + chomp $pc; + my @lib=split(/\./, $pc); + pop @lib; + pop @lib; + my $lib = join("/", @lib); + my $path=$pc; + $path =~ s/\./#2e/g; + $path =~ s/-/#2d/g; + $path = "$dfIIdir/$lib/$path/custom_tag/layout.oa"; + if ( -s "$path" and -f "$path") { + $viewName="custom_tag"; + } + else { + open ($ft, ">$cdsWD/mktag.il"); + print $ft < 0) { + my $subcellnr=1; + open (X, "dfIIhier --dfII-dir='$dfIIdir' --fulcrum-pdk-root='$pdkroot' --view='$srcViewName' '$pc' |") or warn "Cannot run dfIIhier"; + while () { + chomp; + s/^\s+//; + my ($cn,$ln,$vn)=split; + if (length($cn) > $maxnamelen and ! defined ($cellmap{"$cn $vn"})) { + $cellmap{"$cn $vn"}=sprintf("SUBCELL%04d", $subcellnr++); + } + } + close X; + } + my $pc=`echo '$cell' | rename --type=cell --from=cast --to=cadence`; + chomp $pc; + print "VIEWS $viewName $srcViewName"; + $cellmap{"$pc $viewName"}=$rootcellname; + $cellmaptable = "$gdsIIDataDir/cellmaptable"; + open (P, ">$cellmaptable"); + foreach my $cn (sort keys %cellmap) { + my @lib=split(/\./, $cn); + pop @lib; + pop @lib; + my $lib=join(".", @lib); + print P "$lib $cn $cellmap{$cn}"; + } + close P; +} +$output = "$workingDir/$cell.gdsII" if ( ! $output ); +my $tmpgds; +if (! $tapeout) { + if (! $debug and defined ($ENV{TMP}) and $ENV{TMP} =~ /scratch/) { + $tmpgds = `mktemp "$ENV{TMP}/gdsIIWritegds.XXXXXX"`; + } + else { + $tmpgds = `mktemp "/scratch/$user/gdsIIWritegds.XXXXXX"`; + } + chomp $tmpgds; + setfilemode $tmpgds; +} +else { + $tmpgds = $output; +} +if ($flattenpcells) { + $myrsf =~ s/COMMENTPCELLS//; +} +else { + $myrsf =~ s/COMMENTPCELLS/#/; +} +if ($flattenvias) { + $myrsf =~ s/COMMENTVIAS//; +} +else { + $myrsf =~ s/COMMENTVIAS/#/; +} +my $dfcell=cconvert($cell); +close CWR; +close CRD; +waitpid $cpid,0; +my $pwd=`pwd`; +chomp $pwd; + +if (@skip_libs) { + my $fr; + my $all=0; + $refLibList="$pwd/refLibList$$.txt"; + open ($fr, ">$refLibList"); + foreach my $lib (@skip_libs) { + $all=1 if $lib eq "all"; + } + if ($all) { + print $fr "XST_CDS_LIB"; +# open ($fl, "<$dfIIdir/cds.lib.generated"); +# while (<$fl>) { +# chomp; +# my ($d, $lib, $dir)=split; +# $lib =~ s/#2e/./g; +# print $fr $lib; +# } +# close $fl; + print $fr "gate"; + print $fr "stack"; + print $fr "tsmc28"; + } + else { + print $fr join("\n", @skip_libs); + } + close $fr; +} +$dfcell =~ s/\(/-L/g; +$dfcell =~ s/\)/-R/g; +$myrsf =~ s:REFLIBLIST:$refLibList:g; +$myrsf =~ s:RUNDIR:$workingDir:g; +$myrsf =~ s/CELLNAME/$dfcell/g; +$myrsf =~ s/VIEWNAME/$viewName/g; +if ($tapeout or $noproperties) { +$myrsf =~ s/PROPMAP//g; +} +else { +$myrsf =~ s/PROPMAP/$propmap/g; +} +$myrsf =~ s/LIBNAME/$libName/g; +$myrsf =~ s:GDSIINAME:$tmpgds:g; +$myrsf =~ s/LOGFILE/$pipolog/g; +$myrsf =~ s:LAYERTABLE:$layertable:g; +$myrsf =~ s:CELLMAPTABLE:$cellmaptable:g; +my $rsffile; +if (! $debug and defined ($ENV{TMP}) and $ENV{TMP} =~ /scratch/) { + $rsffile=`mktemp "$ENV{TMP}/template.XXXXXX"`; +} +else { + $rsffile=`mktemp "/scratch/$user/template.XXXXXX"`; +} +chomp $rsffile; +setfilemode $rsffile; +open (P, ">>$rsffile") or die "Opening $rsffile : $!"; +print P "$myrsf\n"; +close P; +my $pipoout=">/dev/null"; +$pipoout = "" if $verbose; +$bit64arg = " -64" if $bit64; +my $ldassumekernel=""; +my $unamer = `uname -r`; +chomp $unamer; +$unamer =~ s/.*FC/FC/; +$unamer = substr($unamer,0,3); +$ldassumekernel = "LD_ASSUME_KERNEL=2.4.1" + if ($unamer eq "FC2" and ! $bit64 and ! defined ($ENV{CDS_AUTO_64BIT})); +my $cmd = "cd '$cdsWD'; strmout $bit64arg -templateFile '$rsffile'"; +print "$cmd" if $verbose; +open (X, "$cmd |"); +while () { + chomp; + if (/There were.*error/) { + my @f=split; + $err += $f[3]; + print if ($err) and ! $verbose; + } + if (/^ERROR/) { + $err++; + print if ! $verbose; + } + print if $verbose; +} +close X; +unlink $refLibList; +if ($err) { + print STDERR "Errors encountered in strmout, re-run in debug mode with pipo-log defined to see details."; + exit $err; +} + +# this is supposed to deal with the mangled names which +# pipo generates for pcells. It does not work right now +# but neither does the standard gdsIIWrite. +my %variant=(); +my $gate; +open (P, "<$workingDir/xStrmOut_cellMap.txt"); +while (

    ) { + chomp; +# if (/\slayout\s/ or /\ssymbolic\s/) { +# if (/SRAMFIFO32/) { + s/\s+/ /g; + s/^\s//; + my ($lib,$gate,$view,$cell)=split; +# $cell =~ s/\)//; +# $cell =~ s/[^a-zA-Z0-9_\$]/_/g; + $variant{$cell}=$gbinding{$gate}; +# print STDERR "VARIANT $cell => $variant{$cell} $gate : $_"; +# } +} +close P; +# translate the gds +if (! $tapeout) { +open (P, "rdgds '$tmpgds' |"); +open (Q, "| wrgds > '$output'"); +my $strname=""; +my $base=""; +my $prop=""; +while (

    ) { + chomp; + s/^ *//; + if (/^STRNAME/ or /^SNAME/) { + # translate structure names + my ($s,$snpipo)=split; + my $sn = $snpipo; + $sn = $cbinding{$snpipo} if (defined ($cbinding{$sn})); + print Q "$s $sn"; + $strname = $sn if (/^STRNAME/); + $base = $strname; + $base = $variant{$base} if defined $variant{$base}; +# print STDERR "BASE $strname => $base\n" if $strname =~ /SRAMFIFO32/; + next; + } + elsif (/^TEXT/) { + # dump text which does not agree with the port map of the structure + my $el=""; + my $ok=1; + my $iplayer=0; + $el = "$_\n"; + while (

    ) { + chomp; + s/^ *//; + if (/LAYER 63/) { + $iplayer=1; + } + if (/^STRING/) { + my $sn = $_; + $sn =~ s/^STRING //; + $sn =~ s/'//g; + my $xx=$nbinding{"$base $sn"}; +# print STDERR "BIND $base $sn $xx" if $base =~ /SRAMFIFO32/ and $sn eq 'Vdd'; + $ok &= defined ($nbinding{"$base $sn"}); + $sn = $nbinding{"$base $sn"} + if defined ($nbinding{"$base $sn"}) and ! ($base =~ /^(gate|stack)/); + $_ = "STRING '$sn'"; + } + $el .= "$_\n"; + last if /^ENDEL/; + } + chomp $el; +# $ok = 1 if $base =~ /SRAMFIFO32/; + print Q $el if ($ok or $iplayer); + next; + } + elsif (defined ($propmap{pin}) and /^PROPATTR $propmap{pin}[0]/ and $suppresspins) { + # remove pins properties + next; + } + elsif (defined ($propmap{pin}) and /^PROPATTR $propmap{pin}[0]$/) { + # setup to include appropriate properties + $prop = $_; + next; + } + elsif (defined ($propmap{pin}) and /^PROPVALUE $propmap{pin}[1]=/) { + next if $suppresspins; + # check pin property for validity + my ($s,$sn)=split; + $sn =~ s/'//g; + $sn =~ s/.*=//; + if (defined ($nbinding{"$base $sn"})) { + $sn = $nbinding{"$base $sn"}; + print Q "$prop\n$s termName=$sn"; + } + next; + } + elsif (defined ($propmap{inst}) and /^PROPATTR $propmap{inst}[0]$/) { + $prop = $_; + next; + } + elsif (defined ($propmap{inst}) and /^PROPVALUE $propmap{inst}[1]=/) { + my ($s,$sn)=split; + # convert instance property names + $sn =~ s/'//g; + $sn =~ s/.*=//; + $sn =~ s/^\|//g; + # should this be converted?? + $sn = iconvert($sn); + print Q "$prop\n$s instName=$sn"; +# print Q "$s instName=$sn"; + next; + } + if (/^LIBNAME/) { + $_ = "LIBNAME GDSIIWRITE0.DB"; + } + print Q; +} +close IWR; +close IRD; +waitpid $ipid,0; +close P; +close Q; +} +if ($sixtyfivemode) { + system "/bin/mv '$output' '$output.130'"; + # avoid problems with ',' in path + my $workdir=$output; + $workdir =~ s:/([^/]+)$::; + my $outfile=$1; + my $rv=system "( cd '$workdir'; size265 '$outfile.130' '$outfile')"; + print STDERR "Error: size265 $output.130 $output $rv" if $rv; +} +print STDERR "One or more errors encountered" if ($err); + +END { + if (defined ($outbind)) { + # create binding file + if ( -s "$assurarule") { + system "/bin/cp '$pdkroot/share/Fulcrum/assura/bind.rul' '$outbind'"; + } + else { + system "/bin/touch '$outbind'"; + } + system "chmod +w '$rootcellname.bind'"; + open (O, ">>$outbind"); + if (-f "$workingDir/cellName.map") { + open (P, "<$workingDir/cellName.map"); + while (

    ) { + chomp; + next if /^#/; + my ($out,$v,$in)=split; + print O "C $out $in"; + } + } + if (-f "$cellmaptable") { + open (P, "<$cellmaptable"); + while (

    ) { + chomp; + next if /^#/; + my ($out,$v,$in)=split; + print O "C $out $in"; + } + } +# my $pc=`echo '$cell' | rename --type=cell --from=cast --to=cadence`; +# chomp $pc; +# print O "C $pc $rootcellname"; + close P; + close O; + } + if ($cleanup) { + if ($err) { + unlink "$output"; + } + unlink "$tmpgds" if ! $tapeout; + unlink "$gdsIIDataOutput"; + `/bin/rm -rf "$gdsIIDataDir"`; + unlink "$rsffile"; + unlink "$workingDir/pipo_xout_info"; + unlink "$workingDir/cellName.map"; + `/bin/rm -rf "$cdsWD"`; + } + exit $err; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/genIP.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/genIP.sh new file mode 100755 index 0000000000..fadbe0ba87 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/genIP.sh @@ -0,0 +1,748 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + + +< +genIP is a script to generate a bzip2 compressed +tar file of all the things we need to send to a +customer that is buying one of our circuits. + +From a high level genIP does the following: +1. Parse and validate command line arguments +2. Call jauto to get strength report. +3. Call GenerateIPData java program to generate CDL, + verilog models, skill name tables for gdsII writing, + and rename the contents of the strength report to use + the names in the CDL, verilog, and GDSII. +4. Generate a shell script to run PIPO to stream DFII data to GDSII. +5. Generate a skill program that uses the skill name tables to + munge all the layout and the pipo script to stream the munged + layout to GDSII. +6. Put all the required files in the output tar archive + +DOC + +arch_bin_dir=${0%\/*} +packageRoot=${arch_bin_dir%\/*} +shLibDir="$packageRoot/share/script/sh/sh-lib" + + +if [ -z "$CADENCE_WRAPPER_SCRIPT" ] ; then + CADENCE_WRAPPER_SCRIPT="fulcrum --pdk=nv90 ic icc assura " +fi + +function exit_func() { + #echo "Deleting temporary files"; + #delete_nfs_temp_files + #delete_local_temp_files + /bin/true +} + +function delete_nfs_temp_files() { + if [ -n "$ipDataDir" ] ; then + rm -rf "$ipDataDir" + fi + if [ -n "$pipoConf0" ] ; then + rm -f "$pipoConf0" + fi + if [ -n "$pipoConf1" ] ; then + rm -f "$pipoConf1" + fi + if [ -n "$pipoWD" ] ; then + rm -rf "$pipoWD" + fi + if [ -n "$pipoLog" ] ; then + rm -f "$pipoLog" + fi + if [ -n "$gdsIIOutput" ] ; then + rm -f "$gdsIIOutput" + fi + if [ -n "$pipoScript" ] ; then + rm -f "$pipoScript" + fi + if [ -n "$cdsWD" ] ; then + rm -rf "$cdsWD" + fi + if [ -n "$mainIL" ] ; then + rm -f "$mainIL" + fi + if [ -n "$tempLibDir" ] ; then + rm -rf "$tempLibDir" + fi + +} + +function delete_local_temp_files() { + if [ -n "$jautoToilet" ] ; then + rm -rf "$jautoToilet" + fi + if [ -n "$inputBindRul" ] ; then + rm -f "$inputBindRul" + fi + if [ -n "$genIPDataOutput" ]; then + rm -f "$genIPDataOutput" + fi + if [ -n "$verilogTree" ] ; then + rm -rf "$verilogTree" + fi + if [ -n "$tarDir" ] ; then + rm -rf "$tarDir" + fi +} + +#prs2verilog uses macros to instantiate +#logic gates. This function generates +#the definitions of those macros. Each +#macro is defined to use its corresponding +#built-in verilog operator. +function make_verilog_macro_definitions() { + + srcVerilogFile="$1" + outputVerilogFile="$2" + blackBoxCellName="$3" + + echo "" >$outputVerilogFile + + andGateTypes=`$grepcmd -e "^\\\`AND[1-9][0-9]*" "$srcVerilogFile" | \ + $sedcmd -e "s/^\\\`[a-zA-Z]\+//g" | \ + $sortcmd -n | \ + $uniqcmd` + for typeNum in $andGateTypes ; do + echo "\`define AND$typeNum and" >>$outputVerilogFile + done + + nandGateTypes=`$grepcmd -e "^\\\`NAND[1-9][0-9]*" "$srcVerilogFile" | \ + $sedcmd -e "s/^\\\`[a-zA-Z]\+//g" | \ + $sortcmd -n | \ + $uniqcmd` + for typeNum in $nandGateTypes ; do + echo "\`define NAND$typeNum nand" >>$outputVerilogFile + done + + orGateTypes=`$grepcmd -e "^\\\`OR[1-9][0-9]*" "$srcVerilogFile" | \ + $sedcmd -e "s/^\\\`[a-zA-Z]\+//g" | \ + $sortcmd -n | \ + $uniqcmd` + for typeNum in $orGateTypes ; do + echo "\`define OR$typeNum or" >>$outputVerilogFile + done + + norGateTypes=`$grepcmd -e "^\\\`NOR[1-9][0-9]*" "$srcVerilogFile" | \ + $sedcmd -e "s/^\\\`[a-zA-Z]\+//g" | \ + $sortcmd -n | \ + $uniqcmd` + for typeNum in $norGateTypes ; do + echo "\`define NOR$typeNum nor" >>$outputVerilogFile + done + + echo "\`define INV not" >>$outputVerilogFile + echo "\`define BLACKBOX $blackBoxCellName" >>$outputVerilogFile + +} + +#Delete tempfiles on exit. +trap exit_func EXIT + +localWorkingDir="$TEMP" + +archBinDir="$packageRoot/bin" + +rename="$archBinDir/rename" +source "$shLibDir/file/filecheck.sh" +source "$shLibDir/file/conon.sh" +source "$shLibDir/file/config.sh" +source "$shLibDir/script/generate_script_with_libs.sh" + +function usage() { + echo "Usage: $0 " + echo " --cell=cell" + echo " --fulcrum-pdk-root=dir" + echo " --temp-dir=dir" + echo " --dfII-dir=dir" + echo " --cast-path=path" + echo " --version=str" + echo " [--verilog-test-benches-dir=file ]" + echo " [ --output=cell.tar.bz2 ]" + echo " [ --custom-bind-rul=file ]" + echo " [ --cadence-log=file]" + echo " [ --view=layout ]" + echo " [ --doc-dir=dir ]" + echo " [ --verbose ]" + echo " [ --debug-java ]" +} + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +bashcmd=`which bash` +findcmd=`which find` +tarcmd=`which tar` +sortcmd=`which sort` +uniqcmd=`which uniq` + +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Unable to find gawk in \"$PATH\"" 2 +check_executable_file "$grepcmd" "Unable to fine grep in \"$PATH\"" 2 +check_executable_file "$bashcmd" "Unable to find bash in \"$PATH\"" 2 +check_executable_file "$findcmd" "Unable to find find in \"$PATH\"" 2 +check_executable_file "$tarcmd" "Unable to find tar in \"$PATH\"" 2 +check_executable_file "$sortcmd" "Unable to find sort in \"$PATH\"" 2 +check_executable_file "$uniqcmd" "Unable to find uniq in \"$PATH\"" 2 + + +check_readable_dir "$archBinDir" \ + "Package arch bin: \"$archBinDir\" is not a readable directory." 2 + +cdsSHLib="$packageRoot/share/script/sh/util" +check_readable_dir "$cdsSHLib" \ + "Cadence Shell Script Library: \"$cdsSHLib\" is not a readable directory." 2 + +cdsSHLibFiles=`$findcmd "$cdsSHLib" \! -type d` +for file in $cdsSHLibFiles ; do + source "$file" +done + +cadenceRootCell= +rootCell= +fulcrumPDKRoot= +localWorkingDir= +castPath= +versionStr= +verilogBlackBox= +verilogTestBenchesDir= +outputFile= +customBindRul= +cadenceLog=/dev/null +view="layout" +docDir= +pipoRun= +verbose= +debugJava= +javaMaxHeapSize="1800M" + + +for arg in $@ ; do + + case "$arg" in + --cell=* ) + rootCell=`echo $arg | $sedcmd -e "s/--cell=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrumPDKRoot=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --temp-dir=* ) + localWorkingDir=`echo $arg | $sedcmd -e "s/--temp-dir=//"` + ;; + --dfII-dir=* ) + dfIIDir=`echo $arg | $sedcmd -e "s/--dfII-dir=//"` + ;; + --cast-path=* ) + castPath=`echo $arg | $sedcmd -e "s/--cast-path=//"` + ;; + --version=* ) + versionStr=`echo $arg | $sedcmd -e "s/--version=//"` + ;; + --verilog-test-benches-dir=* ) + verilogTestBenchesDir=`echo $arg | $sedcmd -e "s/--verilog-test-benches-dir=//"` + ;; + --output=* ) + outputFile=`echo $arg | $sedcmd -e "s/--output=//"` + ;; + --custom-bind-rul=* ) + customBindRul=`echo $arg | $sedcmd -e "s/--custom-bind-rul=//"` + ;; + --cadence-log=* ) + cadenceLog=`echo $arg | $sedcmd -e "s/--cadence-log=//"` + ;; + --view=* ) + view=`echo $arg | $sedcmd -e "s/--view=//"` + ;; + --doc-dir=* ) + docDir=`echo $arg | $sedcmd -e "s/--doc-dir=//"` + ;; + --pipo-run=*) + pipoRun=`echo $arg | $sedcmd -e "s/--pipo-run=//"` + ;; + --verbose ) + verbose=1 + ;; + --debug-java ) + debugJava=1 + ;; + --java-max-heap-size=* ) + javaMaxHeapSize=`echo "$arg" | $sedcmd -e "s/--java-max-heap-size=//"` + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + +cadenceRootCell=$(echo "$rootCell" | $rename --type=cell --from=cast --to=cadence) +if [ -z "$localWorkingDir" ] ; then + localWorkingDir="/scratch/" +fi + +check_for_empty_arg "$packageRoot" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$rootCell" \ + "The cell that you want to stream out must be specified." 2 +check_for_empty_arg "$fulcrumPDKRoot" \ + "You must specify the location of the fulcrum pdk you want to use." 2 +check_for_empty_arg "$localWorkingDir" \ + "You must specify an NFS working directory for temporary files generated by this script." 2 +check_for_empty_arg "$dfIIDir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$castPath" \ + "You must specify a cast path" 2 +check_for_empty_arg "$versionStr" \ + "You must specify a version string." 2 +check_for_empty_arg "$cadenceLog" \ + "You must specify a cadence log file." 2 +check_for_empty_arg "$view" \ + "You must specify the view of \"$rootCell\" that you want to stream to GDSII." 2 + +check_for_empty_arg "$javaMaxHeapSize" \ + "You must specify a maximum java heap size." 2 + +check_readable_dir "$packageRoot" \ + "Package Installation: \"$packageRoot\" is not a readable directory." 2 + +check_readable_dir "$fulcrumPDKRoot" \ + "Fulcrum PDK: \"$fulcrumPDKRoot\" is not a readable directory." 2 +conon_path "$fulcrumPDKRoot" +fulcrumPDKRoot="$ret" + +check_writeable_dir "$localWorkingDir" \ + "working directory: \"$localWorkingDir\" is not a readable, writeable directory." 1 +conon_path "$localWorkingDir" +localWorkingDir="$ret" + +check_readable_dir "$dfIIDir" \ + "dfII directory: \"$dfIIDir\" is not a readable, writeable directory." 1 +conon_path "$localWorkingDir" +localWorkingDir="$ret" + +conon_path "$verilogTestBenchesDir" +verilogTestBenchesDir="$ret" + +if [ -n "$customBindRul" ] ; then + check_readable_file "$customBindRul" \ + "Custom Bind.rul: \"$customBindRul\" is not a readable file." 1 + conon_path "$customBindRul" + customBindRul="$ret" +else + customBindRul="/dev/null" +fi + + +if [ -z "$outputFile" ] ; then + outputFile=`pwd` + outputFile="$outputFile/$rootCell.tar.bz2" +fi + +check_writeable_file "$outputFile" \ + "Output File: \"$outputFile\" can not be written to." 1 +conon_path "$outputFile" +outputFile="$ret" + +if [ "$cadenceLog" != "/dev/null" ] ; then + check_writeable_file "$cadenceLog" \ + "Cadence Log File: \"$cadenceLog\" is not a writeable file." 1 + conon_path "$cadenceLog" + cadenceLog="$ret" +fi + +if [ -n "$docDir" ] ; then + check_readable_dir "$docDir" \ + "Documentation Directory: \'$docDir\" is not a readable directory." 1 + conon_path "$docDir" + docDir="$ret" +fi + +if [ -n "$pipoRun" ] ; then + check_writeable_file "$pipoRun" "PIPO Run: \"$pipoRun\" is not a writeable file." 1 + conon_path "$pipoRun" + pipoRun="$ret" +fi + +templatesDir="$packageRoot/share/script/sh/cell-automation/templates" +check_readable_dir "$templatesDir" \ + "Templates Directory: \"$templatesDir\" is not a readable directory." 2 + +skillRoot="$packageRoot/share/skill" +check_readable_dir "$skillRoot" \ + "Skill Root Directory: \"$skillRoot\" is not a readable directory." 2 + +generateIPData="$archBinDir/generate_ip_data" +check_executable_file "$generateIPData" \ + "generateIPData: \"$generateIPData\" is not an executable file." 2 + +jauto="$archBinDir/jauto" +check_executable_file "$jauto" \ + "jauto: \"$jauto\" is not an executable file." 2 + +mkcdswd="$archBinDir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +techBindRul="$fulcrumPDKRoot/share/Fulcrum/assura/bind.rul" +check_readable_file "$techBindRul" \ + "Assura LVS name bindings: \"$techBindRul\" is not a readable file." 2 + +presizeConfig="$fulcrumPDKRoot/share/Fulcrum/jauto/presize.config" +check_readable_file "$presizeConfig" \ + "Jauto Config: \"$presizeConfig\" is not a readable file." 2 + +processConfig="$fulcrumPDKRoot/share/Fulcrum/jauto/process.config" +check_readable_file "$processConfig" \ + "Process Config: \"$processConfig\" is not a readable file." 2 + +verilogGLMConfig="$fulcrumPDKRoot/share/Fulcrum/prs2verilog/glm.config" +check_readable_file "$verilogGLMConfig" \ + "Verilog GLM Config file: \"$verilogGLMConfig\" is not a readable file." 2 + +verilogELMConfig="$fulcrumPDKRoot/share/Fulcrum/prs2verilog/elm.config" +check_readable_file "$verilogELMConfig" \ + "Verilog ELM Config file: \"$verilogELMConfig\" is not a readable file." 2 + +skillAutoLoad="$skillRoot/autoload.il" +check_readable_file "$skillAutoLoad" \ + "Skill Autoload: \"$skillAutoLoad\" is not a readable file." 2 + +propMapFile="$fulcrumPDKRoot/share/Fulcrum/stream/prop.map" +check_readable_file "$propMapFile" \ + "Stream Out Property Map: \"$propMapFile\" is not a readable file." 2 + +streamOutPipoConfigTemplate="$fulcrumPDKRoot/share/Fulcrum/stream/pipo.streamout.tmpl" +check_readable_file "$streamOutPipoConfigTemplate" \ + "Stream Out Config: \"$streamOutPipoConfigTemplate is not a readable file." 2 + +pdkInfoIL="$fulcrumPDKRoot/share/Fulcrum/pdkinfo.il" +check_readable_file "$pdkInfoIL" \ + "pdkinfo.il: \"$pdkInfoIL\' is not a readable file." 2 + +techLib="$fulcrumPDKRoot/share/Fulcrum/pdk.config" + +#config_get_value "$fulcrumPDKRoot/share/Fulcrum/pdk.config" tech_lib +#techLib="$ret" +#techLibDir="$fulcrumPDKRoot/share/Fulcrum/$techLib" +#check_readable_dir "$techLibDir" +# \ +# "Technology file : \"$techLibDir\" is not a readable dir." + # 2 + + + + +get_lib_name "$rootCell" +libName="$ret" +check_for_empty_arg "$libName" "Unable to get library name for \"$rootCell\"." 2 + +get_cell_name_from_cell_name_with_subtype "$rootCell" +rootCellWithoutSubType="$ret" +check_for_empty_arg "$rootCellWithoutSubType" "Unable to remove subtype from cell name \"$rootCell\"." 2 + +get_subtype_from_cell_name_with_subtype "$rootCell" +rootCellSubType="$ret" +check_for_empty_arg "$rootCellSubType" "Unable to get subtype from cell name \"$rootCell\"." 2 + +if [ -n "$verbose" ] ; then + echo "\"$rootCell\" is in library \"$libName\"" + echo "\"$rootCell\" is subtype \"$rootCellSubType\" of \"$rootCellWithoutSubType\"." +fi + +if [ -n "$verbose" ] ; then + echo "Making bind.rul from \"$techBindRul\" and \"$customBindRul\"" +fi +inputBindRul=`mktemp $localWorkingDir/genIP.XXXXXX` + +#See if the specified customBindRul file tells us what to call the top level cell +#in the output. +outputRootCellName=`cat $customBindRul | \ + $grepcmd -F "$rootCell" | \ + $gawkcmd -- "{ print \\$3 }"` +cat "$techBindRul" >$inputBindRul +if [ -z "$outputRootCellName" ] ; then + #The customBindRul file didn't tell us what to call the top level cell + #in the output so we will just call it "TOP" in the output. + outputRootCellName="TOP" + echo "" >>$inputBindRul + echo "" >>$inputBindRul + echo "C $cadenceRootCell TOP" >>$inputBindRul + echo "" >>$inputBindRul + echo "" >>$inputBindRul +fi +cat "$customBindRul" >>$inputBindRul + + +#Run jauto to get the strength report. + +jautoToilet=`mktemp -d $localWorkingDir/genIP.XXXXXX` + +echo $presizeConfig; +echo $processConfig; +jautoCmd="$jauto \"--config=$presizeConfig\"" +jautoCmd="$jautoCmd \"--config=$processConfig\"" +jautoCmd="$jautoCmd \"--castInRoot=$castPath\"" +jautoCmd="$jautoCmd \"--cellName=$rootCellWithoutSubType\"" +jautoCmd="$jautoCmd \"--subtype=$rootCellSubType\"" +jautoCmd="$jautoCmd \"--outRoot=$jautoToilet\"" +jautoCmd="$jautoCmd \"--cdlRoot=$jautoToilet\"" +jautoCmd="$jautoCmd \"--subtypePath=$jautoToilet\"" +jautoCmd="$jautoCmd \"--max-heap-size=$javaMaxHeapSize\"" +jautoCmd="$jautoCmd \"--lancelotTemp=$jautoToilet/lancelot\"" +jautoCmd="$jautoCmd &>$jautoToilet/presize.output.txt" + +if [ -n "$verbose" ] ; then + echo "Generating strength report using jauto." + echo "$jautoCmd" +fi +eval "$jautoCmd" + +strengthReportFile="$jautoToilet/hier_strength.debug" + +if [[ ( ! ( -r "$strengthReportFile" && -s "$strengthReportFile" ) ) ]] ; then + echo "WARNING: Unable to generate strength report." + cat "$jautoToilet/presize.output.txt" +fi + + +ipDataDir=`mktemp -d $localWorkingDir/genIP.XXXXXX` + +genIPDataOutput=`mktemp $localWorkingDir/genIP.XXXXXX` + +# set options to generate verilog for only gatelevel and emulation model +glModelName="$outputRootCellName"; +emulationModelName="$outputRootCellName-emulation"; +prs2VerilogArg="$glModelName:--config=$verilogGLMConfig"; +prs2VerilogArg="$prs2VerilogArg:$emulationModelName:--config=$verilogELMConfig"; + +echo "prs2verilog: $prs2verilogArg" + +#call generatIPData to get CDL, verilog, renamed strength report, +#and skill name tables. +generateIPDataCmd="$generateIPData \"--max-heap-size=$javaMaxHeapSize\"" +generateIPDataCmd="$generateIPDataCmd \"--cast-path=$castPath\"" +generateIPDataCmd="$generateIPDataCmd \"--cell=$rootCell\"" +generateIPDataCmd="$generateIPDataCmd \"--gdsII-name-interface=pmc\"" +generateIPDataCmd="$generateIPDataCmd \"--bind-rul=$inputBindRul\"" +generateIPDataCmd="$generateIPDataCmd \"--prs2verilog=$prs2VerilogArg\"" +generateIPDataCmd="$generateIPDataCmd \"--output-dir=$ipDataDir\"" +generateIPDataCmd="$generateIPDataCmd \"--strength-report=$strengthReportFile\"" +if [ -n "$debugJava" ] ; then + generateIPDataCmd="$generateIPDataCmd --run-debugger" +fi +generateIPDataCmd="$generateIPDataCmd &>$genIPDataOutput" + +if [ -n "$verbose" ] ; then + echo "Top level cell in GDSII file will be called \"$outputRootCellName\"." + echo "Generating verilog, CDL, and name mapping files." + echo "$generateIPDataCmd" +fi + +eval "$generateIPDataCmd" + +generatedBindRul="$ipDataDir/bind.rul" +generatedCDLFile="$ipDataDir/gdsII.cdl" +generatedILFiles="$ipDataDir/ilnames" +generatedStrengthReport="$ipDataDir/$rootCell.strength.report.txt" +generatedglModel="$ipDataDir/$glModelName" +generatedemulationModel="$ipDataDir/$emulationModelName" + +if [[ ( ! ( -r "$generatedBindRul" && -s "$generatedBindRul" ) ) || + ( ! ( -r "$generatedCDLFile" && -s "$generatedCDLFile" ) ) || + ( ! ( -r "$generatedStrengthReport" && -s "$generatedStrengthReport" ) ) ]] ; then + echo "WARNING: Unable to generate verilog, CDL, and name mapping files." + cat $genIPDataOutput + exit 1 +fi + +# Collect all the verilog models and put them in the verilog tree that +# we will use in the output. + + +pipoConf0=`mktemp $localWorkingDir/genIP.XXXXXX` +pipoConf1=`mktemp $localWorkingDir/genIP.XXXXXX` + +pipoWD=`mktemp -d $localWorkingDir/genIP.XXXXXX` + +pipoLog=`mktemp $localWorkingDir/genIP.XXXXXX` + +gdsIIOutput=`mktemp $localWorkingDir/genIP.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Generating config file for PIPO." +fi + +#Generate the pipo config file. +$sedcmd -e "s=\\\$workingdir\\\$=$pipoWD=g" \ + -e "s=\\\$outputfile\\\$=$gdsIIOutput=g" \ + -e "s=\\\$propmap\\\$=$propMapFile=g" \ + -e "s=\\\$logfile\\\$=$pipoLog=g" \ + -e "s=\\\$flatten_pcells\\\$=t=g" \ + $streamOutPipoConfigTemplate \ + >$pipoConf0 + +pipoScript=`mktemp $localWorkingDir/genIP.XXXXXX` +pipoOutput="$pipoWD/pipo.out" + +cdsWD=`mktemp -d $localWorkingDir/genIP.XXXXXX` + +#Make a cadence working directory in which to copy and munge the +#layout for export. +makeCdsWDCmd="$mkcdswd \"--dfII-dir=$dfIIDir\"" +makeCdsWDCmd="$makeCdsWDCmd \"--fulcrum-pdk-root=$fulcrumPDKRoot\"" +makeCdsWDCmd="$makeCdsWDCmd \"--target-dir=$cdsWD\"" +makeCdsWDCmd="$makeCdsWDCmd \"--force\"" +makeCdsWDCmd="$makeCdsWDCmd \"--temp\"" + +if [ -n "$verbose" ] ; then + echo "$makeCdsWDCmd" +fi + +eval "$makeCdsWDCmd" + +#Generate a shell script that the skill code can execute to stream +#out the munged layout. Things are done this way because +#only the skill code knows things like user units per database unit and +#the user unit. +if [ -n "$verbose" ] ; then + echo "Generating script to run PIPO." +fi +echo "#!/bin/bash" >$pipoScript +echo "pushd $cdsWD >/dev/null" >>$pipoScript +echo "$sedcmd \\" >>$pipoScript +echo " -e \"s=\\\\\\\$lib\\\\\\\$=\$1=g\" \\" >>$pipoScript +echo " -e \"s=\\\\\\\$cell\\\\\\\$=\$2=g\" \\" >>$pipoScript +echo " -e \"s=\\\\\\\$view\\\\\\\$=\$3=g\" \\" >>$pipoScript +echo " -e \"s=\\\\\\\$uuperdbu\\\\\\\$=\$4=g\" \\" >>$pipoScript +echo " -e \"s=\\\\\\\$userunit\\\\\\\$=\$5=g\" \\" >>$pipoScript +echo " $pipoConf0 \\" >>$pipoScript +echo " >$pipoConf1" >>$pipoScript +echo "$CADENCE_WRAPPER_SCRIPT pipo strmout $pipoConf1 >$pipoOutput" >>$pipoScript +if [ -n "$pipoRun" ] ; then + echo "cp \"$pipoConf0\" \"$pipoWD/pipo.conf.0.txt\"" >>$pipoScript + echo "cp \"$pipoConf1\" \"$pipoWD/pipo.conf.1.txt\"" >>$pipoScript + echo "cp \"$pipoScript\" \"$pipoWD/pipo.run.script\"" >>$pipoScript + echo "tar -cjf \"$pipoRun\" -C \"$pipoWD\" ." >>$pipoScript +fi +echo "popd >/dev/null" >>$pipoScript + +chmod 755 "$pipoScript" + +mainIL=`mktemp $localWorkingDir/genIP.XXXXXX` + +tempLibDir=`mktemp -d $localWorkingDir/genIP.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Generating skill program." +fi + + +#Generate the skill program that will copy, munge, and stream +#out the layout for export. +echo "( load \"$skillAutoLoad\" )" >$mainIL +echo "( load \"$pdkInfoIL\" )" >>$mainIL +echo "( GDSIIHierCopyAndMungeAndStreamCellTrippleForExportWithPDKInfo" >>$mainIL +echo " \"$generatedILFiles\"" >>$mainIL +echo " \"GDSIIWrite\"" >>$mainIL +echo " \"$tempLibDir\"" >>$mainIL +echo " \"$libName\"" >>$mainIL +echo " \"$cadenceRootCell\"" >>$mainIL +echo " \"$view\"" >>$mainIL +echo " \"$outputRootCellName\"" >>$mainIL +echo " \"$pipoScript\" )" >>$mainIL +echo "( exit )" >>$mainIL + +#Generate the command the will run the generated skill program in cadence. +cadenceCmd="$CADENCE_WRAPPER_SCRIPT layout " +cadenceCmd="$cadenceCmd -replay \"$mainIL\"" +cadenceCmd="$cadenceCmd -log \"$cadenceLog\"" +cadenceCmd="$cadenceCmd -nograph" +cadenceCmd="$cadenceCmd &>/dev/null /dev/null +eval "$cadenceCmd" +popd >/dev/null + +#See if we made a GDSII file. +if [[ -f "$gdsIIOutput" && -s "$gdsIIOutput" ]] ; then + echo "GDSII output successfully created"; +else + echo "WARNING: Unable to generate GDSII." +fi + +tarDir=`mktemp -d $localWorkingDir/genIP.XXXXXX` + +tarContentsDir="$tarDir/$outputRootCellName-$versionStr" +mkdir -p "$tarContentsDir" +mkdir -p "$tarContentsDir/design/" +mkdir -p "$tarContentsDir/testbench/" +mkdir -p "$tarContentsDir/design/gdsII" +mkdir -p "$tarContentsDir/design/emulation" +mkdir -p "$tarContentsDir/design/glm" +mkdir -p "$tarContentsDir/design/netlist" + + +if [ -n "$verilogTestBenchesDir" ] ; then + cpTBFileCmd="cp -r \"$verilogTestBenchesDir\" \"$tarContentsDir/testbench\"" + if [ -n "$verbose" ] ; then + echo "$cpTBFileCmd" + fi + #eval "$cpTBFileCmd" +fi + +cpGDSIICmd="cp -r \"$gdsIIOutput\" \"$tarContentsDir/design/gdsII/$outputRootCellName.gdsII\"" +if [ -n "$verbose" ] ; then + echo "$cpGDSIICmd" +fi + eval "$cpGDSIICmd" + + cpVerilogTreeCmd="cp -Rv \"$generatedglModel/\"* \"$tarContentsDir/design/glm/\"" + if [ -n "$verbose" ] ; then + echo "$cpVerilogTreeCmd" + fi + eval "$cpVerilogTreeCmd" + + cpVerilogTreeCmd="cp -Rv \"$generatedemulationModel/\"* \"$tarContentsDir/design/emulation/\"" + if [ -n "$verbose" ] ; then + echo "$cpVerilogTreeCmd" + fi + eval "$cpVerilogTreeCmd" + + #cpTechCmd="cp -rf \"$techLibDir\" \"$tarContentsDir/design/gdsII\"" + #if [ -n "$verbose" ] ; then + # echo "$cpTechCmd" + #fi + #eval "$cpTechCmd" + + cpCDLCmd="cp -r \"$generatedCDLFile\" \"$tarContentsDir/design/netlist/$outputRootCellName.cdl\"" + if [ -n "$verbose" ] ; then + echo "$cpCDLCmd" + fi + eval "$cpCDLCmd" + + cpStrengthReportCmd="cp -r \"$generatedStrengthReport\" \"$tarContentsDir/design/netlist/$outputRootCellName.strength.report.txt\"" + if [ -n "$verbose" ] ; then + echo "$cpStrengthReportCmd" + fi + eval "$cpStrengthReportCmd" + + tarOutputCmd="$tarcmd -cjf \"$outputFile\" -C \"$tarDir\" \".\"" + if [ -n "$verbose" ] ; then + echo "$tarOutputCmd" + fi + eval "$tarOutputCmd" + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/size265.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/size265.pl new file mode 100755 index 0000000000..185941fb9e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/size265.pl @@ -0,0 +1,309 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; + +my $verbose=0; +my $debug = 0; +my $topcell=""; +# default layer mapping + +my %options = ( + "verbose" => \$verbose, + "debug" => \$debug, + "topcell=s" => \$topcell, +); +my $prefix="outfile$$"; + +GetOptions ( %options ) or usage(); + +my $in = $ARGV[0]; +my $out= $ARGV[1]; +my $tmpout=$out; +if ($tmpout =~ /\//) { +$tmpout =~ s:/([^/]+$):/tmp$1:; +} +else { +$tmpout = "tmp$tmpout"; +} +usage() if ! defined $out; + + +sub usage { + my ($msg)=@_; + print STDERR "$msg" if defined $msg; + print STDERR < : top cell name if ambiguous + --verbose : what is happening + --debug : keep temp files +EU + exit 1; +} + +my %layers=(); +my %names=(); +my %text=(); +my %size=(); +my $rul = < $bl; + return -1 if $al < $bl; + return 1 if $at > $bt; + return -1 if $at < $bt; + 0; +} + +open (P, "rdgds '$in' |"); +open (Q, "| wrgds > '$tmpout'"); +my $layer=0; +my $type=0; +my %strname; +my %sname; +my $text=0; +while (

    ) { + chomp; + s/^ *//; + if (/^-?\d+,-?\d+$/) { + s/ //g; + my ($x,$y)=split(/,/,$_); + $x /= 5; + $y /= 5; + my $xp = sprintf "%.0f", $x; + my $yp = sprintf "%.0f", $y; + $x = 3*$xp; + $y = 3*$yp; + $_="$x,$y"; + # checks for 5nm grid. + print STDERR "Not int x $x line $." if $x != int($x); + print STDERR "Not int y $y line $." if $y != int($y); + } + elsif (/,/) { + print STDERR "Bad coordinate $_ or string"; + } + if (/^BOUNDARY/ or /^PATH/) { + $layer = -1; + $text=0; + $type = 0; + } + if (/^DATATYPE/) { + my ($x,$y)=split; + $type=$y; + $text=0; + } + if (/^LAYER/) { + my ($x,$y)=split; + $layer=$y; + } + if (/^TEXT$/) { + $text=1; + } + if (/^TEXTTYPE/) { + my ($x,$y)=split; + $type=$y; + $text=1; + } + if (/^ENDEL/) { + if ($layer > 0 and $type >= 0) { + if (! defined ($layers{"$layer $type"})) { + print STDERR "Warning: $layer;$type not predefined"; + $layers{"$layer $type"} = "$layer $type"; + } + if ($text) { + $text{"$layer $type"} = $layers{"$layer $type"}; + } + } + $layer = $type = -1; + $text=0; + } + if (/^STRNAME/) { + my ($x,$y)=split; + $strname{$y}=1; + } + if (/^SNAME/) { + my ($x, $y)=split; + $sname{$y}++; + } + print Q; +} +close P; +close Q; +my $cnt=0; +if ($topcell ne "") { + usage "Topcell $topcell not in GDS file" if ! defined($strname{$topcell}); +} +else { + foreach my $sn (keys %strname) { + if (! $sname{$sn}) { + $topcell = $sn; + $cnt++; + } + } + print STDERR "Ambiguous topcell, using $topcell" if $cnt > 1; +} +usage "No topcell found in $in" if $cnt==0; +$rsf =~ s/TOPCELL/$topcell/; +open P, ">sizing$$.rul"; +select P; +print "$rul"; +select STDOUT; +close P; +my $dir="."; +open P, ">sizing$$.rsf"; +select P; +print "$rsf"; +select STDOUT; +close P; + +my $cmd="assura.31.6u1 assura 'sizing$$.rsf' > 'sizing$$.log'"; +print $cmd if $verbose; +system "$cmd"; +if ($debug) { + system "sleep 1; rm '$prefix'.*"; +} +else { + system "rm 'sizing$$.'* '$prefix.'* '$tmpout'"; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/writegds b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/writegds new file mode 100755 index 0000000000..5ce0a0bf64 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/one_cell_commands/writegds @@ -0,0 +1,236 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use strict; +use Getopt::Long; +my $user=`whoami`; +chomp $user; +my $cast_path; +my $spec_dir; +my $spar_dir; +my $cast_dir; +my $dfII_dir; +my $spar_dir = "/p/work/aagrey/rrc/spar"; +my $pdk_root; +my $max_heap_size="8192M"; +my $cell; +my $verbose=0; +my $debug=0; +my $dotop=1; +my $top_dir=undef; +my $synchronous=0; + +GetOptions ( + "cast-path=s" => \$cast_path, + "spec-dir=s" => \$spec_dir, + "cast-dir=s" => \$cast_dir, + "dfii-dir=s" => \$dfII_dir, + "fulcrum-pdk-root=s" => \$pdk_root, + "max-heap-size=s" => \$max_heap_size, + "synchronous" => \$synchronous, + "verbose" => \$verbose, + "debug" => \$debug, + "notop" => sub {$dotop=0;}, +); + +$verbose=1 if $debug; +$top_dir=$spar_dir if ! defined $top_dir and -d $spar_dir; + +sub mysystem { + my @cmd=@_; + chomp @cmd; + print STDERR join " ", @cmd; + system(@cmd); +} + +$cell=shift if defined $ARGV[0]; +$cell =~ s/_L_/\(/g; +$cell =~ s/_R_/\)/g; +$cell =~ s/__/./g if $cell =~ /__/; + +usage() if ! defined $cell; + +open (STDERR, ">/dev/null") if ! $debug; + +writegds ($cell, $dotop); + +sub usage { + print STDERR < $gdstime); + print "$cn is out of date for $cell" if $outofdate; + last if $outofdate; + } + if (! $outofdate) { + print "Skipping $cell" if $verbose; + return 0; + } + } + my $start=time; + print "Generating $cell" if $verbose; + mysystem "mkdir", "-p", "$working_dir"; + + mkdir "/scratch/$user"; + my $gdswd=`mktemp -d "/scratch/$user/writegds.XXXXXX"`; + chomp $gdswd; + my @cmd=( +# "qbwrapper", +# "-l", "mem=8G", + "gdsIIWrite", + "--64", + "--max-heap-size=$max_heap_size", + "--jre-args=-server", + "--working-dir=$gdswd", + "--fulcrum-pdk-root=$pdk_root", + "--cast-path=$cast_path", + "--view=layout", + "--dfII-dir=$dfII_dir", + "--cadence-log=$working_dir/gdsIIWrite.log", + "--assura-log=$working_dir/partial.log", + "--output=$gdswd/cell.gds2.tmp", + "--bind-rul=/nfs/site/disks/wdisk.50/aagrey/rrcwd/lve/lib/sram/8T/fifo/SRAMFIFO32(24)/3000/layout/cell.bindrul.tmp", + "--cell=$cell", + "--noproperties", + "--output-root-cell-name=$gdsIIcell", + "--65mode=0", + "--flatten-vias", + "--flatten-pcells"); + push @cmd, "--use-tag" if $topcell; + push @cmd, "--tapeout" if $cell =~ /\.wires\./ or $cell =~ /^global/; + push @cmd, "--verilog" if $synchronous; + + my $cmd="'".join("' '", @cmd)."'"; + mysystem($cmd); + + print "TOPCELLS of $gdsIIcell ".join(" ", @topcells); + my $outnames=$outgds; + $outnames =~ s/\.gd[^\.]*$/.names/; + if (@topcells || $topcell) { + my @gdstopcells=@topcells; + print STDERR ("aaggds '$gdswd/cell.gds2.tmp'"); + if ($debug) { + open (P, "| aaggds '$gdswd/cell.gds2.tmp' 2>\&1"); + } + else { + open (P, "| aaggds '$gdswd/cell.gds2.tmp' 2>/dev/null 1>/dev/null"); + } + print STDERR "t"; + print P "t"; + foreach my $g (@gdstopcells) { + $g=`echo '$g' | rename --type=cell --from=cast --to=gds2`; + chomp $g; + print STDERR "rm $g"; + print P "rm $g"; + } + if ($topcell) { + print P "t $xlatcell"; + print P "wh $working_dir/t.gds"; + print P "t $gdsIIcell"; + print P "rm $xlatcell"; + } + print P "wh $working_dir/x.gds"; + print P "q"; + close P; + if ($topcell) { + unlink "$working_dir/cell.names"; + mysystem("rdgds '$working_dir/t.gds' | sed -e 's/$xlatcell/$gdsIIcell/' | awk '{print \$0} /STRNAME/ {st[\$2]=1} /SNAME/ {sn[\$2]=1} END {for (s in sn) { print \"SNAME\",s >> \"$working_dir/cell.names\" } for (s in st ) { print \"STRNAME\",s >> \"$working_dir/cell.names\"}}' | wrgds > '$working_dir/cell.gds2'"); + unlink "$working_dir/t.gds"; + unlink "$outnames"; + mysystem("rdgds '$working_dir/x.gds' | sed -e 's/$gdsIIcell/${gdsIIcell}_top/' -e 's/$xlatcell/$gdsIIcell/' | awk '{print \$0} /STRNAME/ {st[\$2]=1} /SNAME/ {sn[\$2]=1} END {for (s in sn) { print \"SNAME\",s >> \"$outnames\" } for (s in st ) { print \"STRNAME\",s >> \"$outnames\"}}' | wrgds > '$outgds'"); + unlink "$working_dir/x.gds"; + } + else { + rename "$working_dir/x.gds", "$outgds"; + mysystem ("rdgds '$outgds' | egrep 'SNAME|STRNAME' | sort -u > '$outnames'"); + } + } + else { + if ($topcell) { + mysystem ("cp", "-p", "$gdswd/cell.gds2.tmp", "$outgds"); + mysystem ("rdgds '$outgds' | egrep 'SNAME|STRNAME' | sort -u > '$outnames'"); + } + else { + print STDERR ("aaggds '$gdswd/cell.gds2.tmp'"); + if ($debug) { + open (P, "| aaggds '$gdswd/cell.gds2.tmp' 2>\&1"); + } + else { + open (P, "| aaggds '$gdswd/cell.gds2.tmp' 2>/dev/null 1>/dev/null"); + } + print P "wf $working_dir/g.gds"; + print P "q"; + close P; + rename "$working_dir/g.gds", "$outgds"; + mysystem ("rdgds '$outgds' | egrep 'SNAME|STRNAME' | sort -u > '$outnames'"); + } + } + system ("/bin/rm -rf $gdswd"); + my $elapse=sprintf("%.1f", ((time-$start)/60)); + print "Elapsed for $cell ${elapse}M" if $verbose; +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/templates/leaf_cell.il.template b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/templates/leaf_cell.il.template new file mode 100755 index 0000000000..3702b71d5f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/cell-automation/templates/leaf_cell.il.template @@ -0,0 +1,228 @@ +when( $debug$ +ilToolBox() +ilDebugToolBox() +ilDebugToolBoxForm->autoStacktrace->value = "16" +hiCloseWindow(ilDebugToolBoxWindow) ) + +( UseGraphics= $graphics$ ) +( OptionRoute= $route$ ) +( OptionPlace= $place$ ) +( OptionCompactSuperstacks= $compactsuperstacks$ ) +( OptionKeepPlacerViewHistory= $keepplacerviews$ ) +( OptionKeepRouterViewHistory= $keeprouterviews$ ) +( OptionSemiAutomatedMode= t ) +( PlugsInRoutingStage= $plugs_in_routing_search$ ) +( OptionDetailedRouterSearch= t ) +( OptionBackwardsRouterSearch= t ) + + + +( CellDir= "$cell_dir$" ) +( LibName= "$lib$" ) +( CellName= "$cell$" ) +( PackageRoot= "$package_root$" ) +( ScriptRoot= sprintf( nil "%s/share/script" PackageRoot ) ) +( SkillLibRoot= sprintf( nil "%s/share/skill" PackageRoot ) ) + + + +( GateLibrary= "$gate_lib$" ) +( StackLibrary= "$stack_lib$" ) + +( PinsDirectory= "$cell_dir$/autopins" ) +( SkillNetlistDir= "$cell_dir$/ilnets" ) +( SkillDirectivesDir= "$cell_dir$/ildirectives" ) +( LogFileName= "$logfile$" ) + + +;load autoload and pdkinfo +( PDKRoot= "$fulcrum_pdk_root$" ) +load( sprintf( nil "%s/share/Fulcrum/pdkinfo.il" PDKRoot ) ) +load( sprintf( nil "%s/autoload.il" SkillLibRoot ) ) + +( RouterDir= ( sprintf nil "%s/router" CellDir ) ) +createDir( RouterDir ) + +;routing +( RouterRuleFile= sprintf( nil "%s/share/Fulcrum/cell_automation/router/runleaf.rul" PDKRoot ) ) +( RouterMinDoFile= sprintf( nil "%s/share/Fulcrum/cell_automation/router/runleaf_min.do" PDKRoot ) ) +( RouterDoFile= sprintf( nil "%s/share/Fulcrum/cell_automation/router/runleaf.do" PDKRoot ) ) +( RouterTemplateTclFile= sprintf( nil "%s/share/Fulcrum/cell_automation/router/leaf_vsr.tcl" PDKRoot ) ) +( RouterExcludeNetFile= sprintf( nil "%s/share/Fulcrum/cell_automation/router/leaf.excludenet" PDKRoot ) ) + +( RouterConductorDepth= 0 ) +( RouterKeepOutDepth= 32 ) + + +( PlacerRuleFile= sprintf( nil "%s/share/Fulcrum/cell_automation/placer.rules" PDKRoot ) ) + +( WorkingDir= "$cds_wd$" ) + +;auto pin template +glcFindPinTemplate( CellName + ?PinGlobalWirePitch 0.24 + ?PinGlobalWireWidth 0.12 + ?PinGlobalWireSpacing 0.12 + ?PowerGridTrackOffset -1 + ?AutoPinFileName sprintf(nil "%s/%s.pins.il" PinsDirectory CellName) + ?templateViewName "layout" + ) + +;assura stuff +( SchematicFile= "$cdl_file$" ) + +( PlacerCheckDRCRuleFile= sprintf( nil "%s/share/Fulcrum/cell_automation/placer_check_drc_assura.txt" PDKRoot ) ) +( PlacerCheckDRCAssuraSets= list( "LATCH_UP" ) ) +( LVSRuleFile= sprintf( nil "%s/share/Fulcrum/assura/extract.rul" PDKRoot ) ) +( LVSBindFile= sprintf( nil "%s/share/Fulcrum/assura/bind.rul" PDKRoot ) ) +( LVSCompareFile= sprintf( nil "%s/share/Fulcrum/assura/compare.rul" PDKRoot ) ) +( LVSIncludeFile= sprintf( nil "%s/share/Fulcrum/assura/LVSinclude.rsf" PDKRoot ) ) +( PlugDRCRuleFile= sprintf( nil "%s/share/Fulcrum/plugs/plugs.assura.rules" PDKRoot ) ) +( NotchDRCRuleFile= sprintf( nil "%s/share/Fulcrum/notch/fill_notches.assura.rules" PDKRoot ) ) +( KeepOutDRCRuleFile= sprintf( nil "%s/share/Fulcrum/cell_automation/keepout.rules" PDKRoot ) ) +( AssuraPlacerCheckDRCDir= sprintf( nil "%s/assura_drc" CellDir ) ) +createDir( AssuraPlacerCheckDRCDir ) + +( AssuraLVSDir= sprintf( nil "%s/assura_lvs" CellDir ) ) +createDir( AssuraLVSDir ) + +( NetListTable= NetlistTableGetSkillNetlistTableForCellName( + CellName SkillNetlistDir ) ) +( DirectiveTable= CellInfoGetTableForCellName( + CellName SkillDirectivesDir ) ) + + +;do some dealings with the tables +( YPitch= UserUnitsPerMeter * CellInfoGetHeightInMeters( DirectiveTable DirectiveUnitsPerMeter ) ) +( StatisticsTable= arrayref( NetListTable "s" ) ) + +( TotalTransistorArea= UserUnitsPerMeter * UserUnitsPerMeter * +arrayref( StatisticsTable "a" ) ) +( TargetCellArea= TotalTransistorArea* +cond( (CellInfoLookup( DirectiveTable "density_factor" ) ) +( 20.0 ) +) ) +FinalBoundaryPosition= cond( + (CellInfoLookup( DirectiveTable "boundary_position" ) ) + (list( 0 0 )) +) + +( LeftBuffer= -car( BoundaryPosition )*UserUnitsPerMeter ) +( RightBuffer= -car( BoundaryPosition )*UserUnitsPerMeter ) + + +;fudged +( TargetCellWidth= 3.0*quotient( TargetCellArea YPitch) ) + +;all the various view names used +( ScratchViewName= "scratch" ) + +;placement phase +( NetListViewName= "netlist" ) +( GenFromSourceViewName= "genfromsource" ) +( PlacedOnlyViewName= "placedonly" ) +( PlacedViewName= "placed" ) +( PlacedScratchViewName= "placedscratch" ) +( PreRouteViewName= "preroute" ) +( PreRouteScratchViewName= "preroutescratch" ) + +;routing phase +( RoutedScratchViewName= "routedscratch" ) +( RoutedViewName= "routed" ) +( PreKeepOutRoutedViewName= "prekeepoutrouted" ) +( PreKeepOutRoutedScratchViewName= "prekeepoutroutedscratch" ) +( KeepOutRoutedViewName= "keepoutrouted" ) +( RoutingViewName= "routing" ) +( AbstractViewName= "abstract" ) + +BestPlacedViewName= nil +BestPreRouteViewName= nil +BestRoutedViewName= nil +BestPlacedViewArea= 1e9 +BestRoutedViewArea= 1e9 +PreRouteViewNames= nil +BestPreKeepOutRoutedViewName= nil + +;cdf, placer info +TransistorLayoutViewName= "layout" +NRegionComponentClassName= "NSTACK" +PRegionComponentClassName= "PSTACK" +GateRegionComponentClassName= "GATE" + + +InitialRoutingSearchPassed= nil +RoutingGood= nil +PlacementGood= nil + +;binary search tables +ColumnSearchTable= makeTable( `ColumnSearchTable ) +NWidthSearchTable= makeTable( `NWidthSearchTable ) +PWidthSearchTable= makeTable( `PWidthSearchTable ) +RouterGapWidthInitialSearchTable= nil +RouterGapWidthSearchTableList= nil +InitialRoutingSearchDone= nil + +;chain/superstack +NComponentLibCellPairRegExs= NSuperStackLibCellPairRegExs +PComponentLibCellPairRegExs= PSuperStackLibCellPairRegExs +MaxMergeHeight= YPitch - 2.0* UserUnitsPerMeter * LeafCellMinVerticalSpacingToBoundary +MaxNonPowerMergeHeight= min( 0.5* YPitch 3.0+ YPitch * 0.2 ) +MaxPowerMergeHeight= min( 0.5* YPitch 3.0+ YPitch * 0.1 ) +PreferEvenFolds= t + + +;binary search values +NMinimumTrialMaximumTriple= nil +PMinimumTrialMaximumTriple= nil +InitialColumnCount= nil +NWidthData= nil +PWidthData= nil +NWidth= nil +PWidth= nil +ColumnCount= nil +InitialColumnInfo= nil +GateRegionHeight= nil +GateTransistorSpacing= 0 +ColumnSpacing= 0 + +;step number +CurrentStepNumber= 0 + +;Licenses +VirtuosoXLVersion= 5.0 +VirtuosoVersion= 5.0 +LicensesToLeave= 0 + +;instantiator +DFIIDir= "$dfII_dir$" +InstantiatorView= dbOpenCellViewByType( car( ( NameParseCellName "$cell$" ) ) +"$cell$" "instantiator" nil "r" ) + +;insantiate netlist +errset( GenFromSourceView = GenFromSourceMain( + LibName CellName GenFromSourceViewName SkillNetlistDir SkillDirectivesDir) t) +CurrentSearchTable= (if OptionPlace ColumnSearchTable ) + +CurrentStepNumber = 0 + +;place +PlacedView= nrOpenCellViewReadable( LibName CellName PlacedViewName ) +(when OptionPlace && !PlacedView + PlacerSearchStatus = nil + errset( while((PlacerSearchStatus != t && CurrentStepNumber<100 ) + PlacerSearchStatus = PlacerSearch() + if((CurrentStepNumber==99) printf("Error: Placing over 100 iteration. Giving up!\n")) +) t) ) + +CurrentStepNumber = 0 + +;route +RoutedView= nrOpenCellViewReadable( LibName CellName RoutedViewName ) +(when OptionRoute && !RoutedView + RouterSearchStatus = nil + errset( while((RouterSearchStatus != t && CurrentStepNumber<1000) + RouterSearchStatus = RouterSearch() + if((CurrentStepNumber==999) printf("Error: Routing over 1000 iteration. Giving up!\n")) +) t) ) + +(exit) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/floorplan/initFloorplan.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/floorplan/initFloorplan.sh new file mode 100755 index 0000000000..632185456a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/floorplan/initFloorplan.sh @@ -0,0 +1,263 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/initFloorplan.sh#4 $ +# $DateTime: 2006/08/31 09:01:40 $ +# $Author: aubrey $ + +arch_bin_dir=${0%\/*} +packageRoot=${arch_bin_dir%\/*} +shLibDir="$packageRoot/share/script/sh/sh-lib" + +archBinDir="$packageRoot/bin" + +umask 000 +source "$shLibDir/file/filecheck.sh" +source "$shLibDir/file/conon.sh" +source "$shLibDir/script/generate_script_with_libs.sh" + +function usage() { + echo "Usage: $0 " + echo " --cell=cellName" + echo " --lib=libName" + echo " --dfII-dir=dir" + echo " --fulcrum-pdk-root=dir" + echo " --cast-path=path" + echo " --working-dir=dir" + echo " [ --cadence-log=initFloorplan.log]" + echo " [ --view=layout ]" + echo " [ --verbose ]" + echo " [ --max-heap-size=1800 ]" + echo " [ --64 ]" +} + +layout=`mywhich layoutPlus` || myexit "$layout" 2 +sedcmd=`mywhich sed` || myexit "$sedcmd" 2 +gawkcmd=`mywhich gawk` || myexit "$gawkcmd" 2 +grepcmd=`mywhich grep` || myexit "$grepcmd" 2 +bashcmd=`mywhich bash` || myexit "$bashcmd" 2 +findcmd=`mywhich find` || myexit "$findcmd" 2 + +check_readable_dir "$archBinDir" \ + "Package arch bin: \"$archBinDir\" is not a readable directory." 2 + +cdsShLib="$packageRoot/share/script/sh/util" +check_readable_dir "$cdsShLib" \ + "Cadence Shell Script Library: \"$cdsShLib\" is not a readable directory." 2 + +cdsShLibFiles=`$findcmd "$cdsShLib" \! -type d` +for file in $cdsShLibFiles ; do + source "$file" +done + +cadenceName= +cell= +lib= +dfIIDir= +fulcrumPDKRoot= +castPath= +workingDir= +defOutput="cell.def" +bindRulOutput=/dev/null +outputRootCellName= +cadenceLog="initFloorplan.log" +view="floorplan" +verbose= +debug= +scale= +maxHeapSize=1800 +preservePins=1 +bit64= +if [ -n "$CDS_AUTO_64BIT" -a "$CDS_AUTO_64BIT" = "ALL" ]; then + bit64=1 +fi + +for arg in $@ ; do + + case "$arg" in + --cell=* ) + cell=`echo "$arg" | $sedcmd -e "s/--cell=//"` + ;; + --lib=* ) + lib=`echo "$arg" | $sedcmd -e "s/--lib=//"` + ;; + --dfII-dir=* ) + dfIIDir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrumPDKRoot=`echo "$arg" | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --cast-path=* ) + castPath=`echo "$arg" | $sedcmd -e "s/--cast-path=//"` + ;; + --working-dir=* ) + workingDir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; + --cadence-log=* ) + cadenceLog=`echo "$arg" | $sedcmd -e "s/--cadence-log=//"` + ;; + --view=* ) + view=`echo "$arg" | $sedcmd -e "s/--view=//"` + ;; + --max-heap-size=* ) + maxHeapSize=`echo "$arg" | $sedcmd -e "s/--max-heap-size=//"` + ;; + --verbose ) + verbose=1 + ;; + --debug ) + debug=1 + ;; + --64 ) + bit64=1 + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + +if [ -n "$debug" ] ; then + verbose=1 +fi + +check_for_empty_arg "$packageRoot" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$cell" \ + "The cell that you want to process must be specified." 2 +check_for_empty_arg "$dfIIDir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$fulcrumPDKRoot" \ + "You must specify the location of the fulcrum pdk you want to use." 2 +check_for_empty_arg "$castPath" \ + "You must specify a cast-path" 2 +check_for_empty_arg "$workingDir" \ + "You must specify a working-dir" 2 +check_for_empty_arg "$cadenceLog" \ + "You must specify a cadence log file." 2 +check_for_empty_arg "$view" \ + "You must specify the view of \"$cell\" that you want to process." 2 + +if [[ ( ! ( -w "$workingDir" && -d "$workingDir" ) ) ]] ; then + echo "Can't write and delete in $workingDir." + exit 2 +fi + +check_readable_dir "$packageRoot" \ + "Package Installation: \"$packageRoot\" is not a readable directory." 2 + +check_readable_dir "$dfIIDir" \ + "dfII directory: \"$dfIIDir\" is not a readable, writeable directory." 1 +conon_path "$dfIIDir" +dfIIDir="$ret" + +check_readable_dir "$fulcrumPDKRoot" \ + "Fulcrum PDK: \"$fulcrumPDKRoot\" is not a readable directory." 2 +conon_path "$fulcrumPDKRoot" +fulcrumPDKRoot="$ret" + +check_writeable_file "$defOutput" \ + "Def Output File: \"$defOutput\" can not be written to." 1 +conon_path "$defOutput" +defOutput="$ret" + +if [ "$cadenceLog" != "/dev/null" ] ; then + check_writeable_file "$cadenceLog" \ + "Cadence Log File: \"$cadenceLog\" is not a writeable file." 1 + conon_path "$cadenceLog" + cadenceLog="$ret" +fi + +skillRoot="$packageRoot/share/skill" +check_readable_dir "$skillRoot" \ + "Skill Root Directory: \"$skillRoot\" is not a readable directory." 2 + +mkcdswd="$archBinDir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +skillAutoLoad="$skillRoot/autoload.il" +check_readable_file "$skillAutoLoad" \ + "Skill Autoload: \"$skillAutoLoad\" is not a readable file." 2 + +pdkInfoIL="$fulcrumPDKRoot/share/Fulcrum/pdkinfo.il" +check_readable_file "$pdkInfoIL" \ + "pdkinfo.il: \"$pdkInfoIL\' is not a readable file." 2 + + +cdsWD=`mktemp -d $workingDir/initFloorplan.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Making cadence working directory." + echo "$mkcdswd \"--dfII-dir=$dfIIDir\" \"--fulcrum-pdk-root=$fulcrumPDKRoot\" \"--cast-path=$castPath\" \"--target-dir=$cdsWD\" \"--force\" " +fi + +templateCdsWd= +if [ -n "$CDS_WD_TEMPLATE" ] ; then + templateCdsWd="--user-template=$CDS_WD_TEMPLATE" +fi + +$mkcdswd "--dfII-dir=$dfIIDir" \ + "--fulcrum-pdk-root=$fulcrumPDKRoot" \ + "--cast-path=$castPath" \ + "--target-dir=$cdsWD" \ + "--force" "$templateCdsWd" + +mainIL=`mktemp $workingDir/initFloorplan.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Generating skill program." + verbose="t" +else + verbose="nil" + +fi + +cat <$mainIL +(unless ( equal "" "$debug" ) ( ilDebugToolBox )) +( load "$skillAutoLoad" ) +( load "$pdkInfoIL" ) +flInitFloorplan( "$lib" "$cell" "$view" + ?Verbose t + ?RegenerateFromCast nil + ?MaxHeapSize $maxHeapSize + ) +Status = 0 +(when ( equal "" "$debug" ) ( exit Status ) ) +SKILL + +cadenceLogTemp=`mktemp "$workingDir/cadenceLogTemp.XXXXXX"` +cadenceScript=`mktemp "$workingDir/cadenceScript.XXXXXX"` +cadenceErr=`mktemp "$workingDir/cadenceErr.XXXXXX"` + +if [ -n "$bit64" ] ; then +CDS_AUTO_64BIT=ALL +else +CDS_AUTO_64BIT=NONE +fi + +graphics= +if [ -z "$debug" ] ; then + graphics="-nograph" +fi + +cat <"$cadenceScript" +#!/bin/bash +cd "$cdsWD" +CDS_AUTO_64BIT=$CDS_AUTO_64BIT $layout \ +-replay "$mainIL" -log "$cadenceLogTemp" $graphics \ + /dev/null 2>"$cadenceErr" +EOF + +chmod +x "$cadenceScript" + +"$cadenceScript" + +if [ $? != 0 ] ; then + cat "$cadenceErr" 1>&2 + echo "ERROR: layoutPlus returned with non-zero exit status" 1>&2 +fi + +cp "$cadenceLogTemp" "$cadenceLog" + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/lefdef/lefdefWrite.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/lefdef/lefdefWrite.sh new file mode 100755 index 0000000000..46d6761bc0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/lefdef/lefdefWrite.sh @@ -0,0 +1,269 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +arch_bin_dir=${0%\/*} +packageRoot=${arch_bin_dir%\/*} +shLibDir="$packageRoot/share/script/sh/sh-lib" + +archBinDir="$packageRoot/bin" + +umask 000 +source "$shLibDir/file/filecheck.sh" +source "$shLibDir/file/conon.sh" +source "$shLibDir/script/generate_script_with_libs.sh" + +function usage() { + echo "Usage: $0 " + echo " --cell=cell" + echo " --dfII-dir=dir" + echo " --fulcrum-pdk-root=dir" + echo " --cast-path=path" + echo " --working-dir=dir" + echo " [ --lef-output=cell.lef ]" + echo " [ --def-output=cell.def ]" + echo " [ --cadence-log=file]" + echo " [ --view=layout ]" + echo " [ --verbose ]" + echo " [ --64 ]" +} + +layout=`mywhich layoutPlus` || exit 2 +sedcmd=`mywhich sed` || exit 2 +gawkcmd=`mywhich gawk` || exit 2 +grepcmd=`mywhich grep` || exit 2 +bashcmd=`mywhich bash` || exit 2 +findcmd=`mywhich find` || exit 2 + +check_readable_dir "$archBinDir" \ + "Package arch bin: \"$archBinDir\" is not a readable directory." 2 + +cdsShLib="$packageRoot/share/script/sh/util" +check_readable_dir "$cdsShLib" \ + "Cadence Shell Script Library: \"$cdsShLib\" is not a readable directory." 2 + +cdsShLibFiles=`$findcmd "$cdsShLib" \! -type d` +for file in $cdsShLibFiles ; do + source "$file" +done + +cadenceName= +rootCell= +dfIIDir= +fulcrumPDKRoot= +castPath= +workingDir= +lefOutput="cell.lef" +defOutput="cell.def" +bindRulOutput=/dev/null +outputRootCellName= +cadenceLog=/dev/null +view="layout" +verbose= +debug= +scale= +preservePins=1 +bit64= +if [ -n "$CDS_AUTO_64BIT" -a "$CDS_AUTO_64BIT" = "ALL" ]; then + bit64=1 +fi + +for arg in $@ ; do + + case "$arg" in + --cell=* ) + rootCell=`echo "$arg" | $sedcmd -e "s/--cell=//"` + ;; + --dfII-dir=* ) + dfIIDir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrumPDKRoot=`echo "$arg" | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --cast-path=* ) + castPath=`echo "$arg" | $sedcmd -e "s/--cast-path=//"` + ;; + --working-dir=* ) + workingDir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; + --lef-output=* ) + lefOutput=`echo "$arg" | $sedcmd -e "s/--lef-output=//" -e "s=(=\\\\\\(=g" -e "s=)=\\\\\\)=g"` + ;; + --def-output=* ) + defOutput=`echo "$arg" | $sedcmd -e "s/--def-output=//" -e "s=(=\\\\\\(=g" -e "s=)=\\\\\\)=g"` + ;; + --cadence-log=* ) + cadenceLog=`echo "$arg" | $sedcmd -e "s/--cadence-log=//"` + ;; + --view=* ) + view=`echo "$arg" | $sedcmd -e "s/--view=//"` + ;; + --verbose ) + verbose=1 + ;; + --debug ) + debug=1 + ;; + --64 ) + bit64=1 + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + +if [ -n "$debug" ] ; then + verbose=1 +fi + +check_for_empty_arg "$packageRoot" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$rootCell" \ + "The cell that you want to lef & def out must be specified." 2 +check_for_empty_arg "$dfIIDir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$fulcrumPDKRoot" \ + "You must specify the location of the fulcrum pdk you want to use." 2 +check_for_empty_arg "$castPath" \ + "You must specify a cast-path" 2 +check_for_empty_arg "$workingDir" \ + "You must specify a working-dir" 2 +check_for_empty_arg "$cadenceLog" \ + "You must specify a cadence log file." 2 +check_for_empty_arg "$view" \ + "You must specify the view of \"$rootCell\" that you want to lef & def out." 2 + +get_lib_name "$rootCell" +libName="$ret" +check_for_empty_arg "$libName" "Unable to get library name for \"$rootCell\"." 2 + +if [[ ( ! ( -w "$workingDir" && -d "$workingDir" ) ) ]] ; then + echo "Can't write and delete in $workingDir." + exit 2 +fi + +check_readable_dir "$packageRoot" \ + "Package Installation: \"$packageRoot\" is not a readable directory." 2 + +check_readable_dir "$dfIIDir" \ + "dfII directory: \"$dfIIDir\" is not a readable, writeable directory." 1 +conon_path "$dfIIDir" +dfIIDir="$ret" + +check_readable_dir "$fulcrumPDKRoot" \ + "Fulcrum PDK: \"$fulcrumPDKRoot\" is not a readable directory." 2 +conon_path "$fulcrumPDKRoot" +fulcrumPDKRoot="$ret" + +skillRoot="$packageRoot/share/skill" +check_readable_dir "$skillRoot" \ + "Skill Root Directory: \"$skillRoot\" is not a readable directory." 2 + +mkcdswd="$archBinDir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +skillAutoLoad="$skillRoot/autoload.il" +check_readable_file "$skillAutoLoad" \ + "Skill Autoload: \"$skillAutoLoad\" is not a readable file." 2 + +pdkInfoIL="$fulcrumPDKRoot/share/Fulcrum/pdkinfo.il" +check_readable_file "$pdkInfoIL" \ + "pdkinfo.il: \"$pdkInfoIL\' is not a readable file." 2 + +techonly_lef="$fulcrumPDKRoot/share/Fulcrum/lefdef/tech_only.lef" +check_readable_file "$techonly_lef" \ + "techonly.lef: \"$techonly_lef\' is not a readable file." 2 + + +cdsWD=`mktemp -d $workingDir/lefdef.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Making cadence working directory." + echo "$mkcdswd \"--dfII-dir=$dfIIDir\" \"--fulcrum-pdk-root=$fulcrumPDKRoot\" \"--cast-path=$castPath\" \"--target-dir=$cdsWD\" \"--force\" \"--temp\"" +fi + +templateCdsWd= +if [ -n "$CDS_WD_TEMPLATE" ] ; then + templateCdsWd="--user-template=$CDS_WD_TEMPLATE" +fi + +$mkcdswd "--dfII-dir=$dfIIDir" \ + "--fulcrum-pdk-root=$fulcrumPDKRoot" \ + "--cast-path=$castPath" \ + "--target-dir=$cdsWD" \ + "--force" "--temp" "$templateCdsWd" + +mainIL=`mktemp $workingDir/lefdef.XXXXXX` + +tempLibDir=`mktemp -d $workingDir/lefdef.XXXXXX` +lefTempFile=`mktemp "$workingDir/lef.XXXXXX"` +defTempFile=`mktemp "$workingDir/def.XXXXXX"` + +if [ -n "$verbose" ] ; then + echo "Generating skill program." + verbose="t" +else + verbose="nil" + +fi + +cat <$mainIL +(unless ( equal "" "$debug" ) ( ilDebugToolBox )) +( load "$skillAutoLoad" ) +( load "$pdkInfoIL" ) +lefStatus=lefLefOut( "$libName" + "$rootCell" + "$view" + "$lefTempFile" + ?Verbose $verbose) +defStatus=defDefOut( "$libName" + "$rootCell" + "$view" + "$defTempFile" + ?Verbose $verbose) +Status = (cond ( !lefStatus 1 ) ( !defStatus 2 ) ( 0 ) ) +(when ( equal "" "$debug" ) ( exit Status ) ) +SKILL + +cadenceLogTemp=`mktemp "$workingDir/cadenceLogTemp.XXXXXX"` +cadenceScript=`mktemp "$workingDir/cadenceScript.XXXXXX"` +cadenceErr=`mktemp "$workingDir/cadenceErr.XXXXXX"` + +if [ -n "$bit64" ] ; then +CDS_AUTO_64BIT=ALL +else +CDS_AUTO_64BIT=NONE +fi + +graphics= +if [ -z "$debug" ] ; then + graphics="-nograph" +fi + +cat <"$cadenceScript" +#!/bin/bash +cd "$cdsWD" +CDS_AUTO_64BIT=$CDS_AUTO_64BIT $layout \ +-replay "$mainIL" -log "$cadenceLogTemp" $graphics \ + /dev/null 2>"$cadenceErr" +cat $techonly_lef $lefTempFile > $lefOutput +mv $defTempFile $defOutput +EOF + +chmod +x "$cadenceScript" + +"$cadenceScript" + +if [ $? != 0 ] ; then + cat "$cadenceErr" 1>&2 + echo "ERROR: layoutPlus returned with non-zero exit status" 1>&2 +fi + +cp "$cadenceLogTemp" "$cadenceLog" + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/createFlattenView.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/createFlattenView.sh new file mode 100755 index 0000000000..b092ddd0be --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/createFlattenView.sh @@ -0,0 +1,275 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +arch_bin_dir=${0%\/*} +packageRoot=${arch_bin_dir%\/*} +shLibDir="$packageRoot/share/script/sh/sh-lib" + +archBinDir="$packageRoot/bin" + +umask 000 +source "$shLibDir/file/filecheck.sh" +source "$shLibDir/file/conon.sh" +source "$shLibDir/script/generate_script_with_libs.sh" + +function usage() { + echo "Usage: $0 " + echo " --cell=cellName" + echo " --lib=libName" + echo " --dfII-dir=dir" + echo " --fulcrum-pdk-root=dir" + echo " --cast-path=path" + echo " --working-dir=dir" + echo " [ --view=layout]" + echo " [ --flatten-view=flatten ]" + echo " [ --power-grid-cellname=powerGridTieOff ]" + echo " [ --flatten-cells-list=flatten_cells_list ]" + echo " [ --cadence-log=createFlattenView.log]" + echo " [ --verbose ]" + echo " [ --64 ]" +} + +layout=`mywhich layoutPlus` || exit 2 +sedcmd=`mywhich sed` || exit 2 +gawkcmd=`mywhich gawk` || exit 2 +grepcmd=`mywhich grep` || exit 2 +bashcmd=`mywhich bash` || exit 2 +findcmd=`mywhich find` || exit 2 + +check_readable_dir "$archBinDir" \ + "Package arch bin: \"$archBinDir\" is not a readable directory." 2 + +cdsShLib="$packageRoot/share/script/sh/util" +check_readable_dir "$cdsShLib" \ + "Cadence Shell Script Library: \"$cdsShLib\" is not a readable directory." 2 + +cdsShLibFiles=`$findcmd "$cdsShLib" \! -type d` +for file in $cdsShLibFiles ; do + source "$file" +done + +powerGridCellName="powerGridTieOff" +flattenCellsList="flatten_cells_list" +cadenceName= +cell= +lib= +dfIIDir= +fulcrumPDKRoot= +castPath= +workingDir= +bindRulOutput=/dev/null +outputRootCellName= +cadenceLog="createFlattenView.log" +view="layout" +flattenView="flatten" +verbose= +debug= +scale= +preservePins=1 +bit64= +if [ -n "$CDS_AUTO_64BIT" -a "$CDS_AUTO_64BIT" = "ALL" ]; then + bit64=1 +fi + +for arg in $@ ; do + + case "$arg" in + --cell=* ) + cell=`echo "$arg" | $sedcmd -e "s/--cell=//"` + ;; + --lib=* ) + lib=`echo "$arg" | $sedcmd -e "s/--lib=//"` + ;; + --dfII-dir=* ) + dfIIDir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrumPDKRoot=`echo "$arg" | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --cast-path=* ) + castPath=`echo "$arg" | $sedcmd -e "s/--cast-path=//"` + ;; + --working-dir=* ) + workingDir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; + --cadence-log=* ) + cadenceLog=`echo "$arg" | $sedcmd -e "s/--cadence-log=//"` + ;; + --view=* ) + view=`echo "$arg" | $sedcmd -e "s/--view=//"` + ;; + --power-grid-cellname=* ) + powerGridCellName=`echo "$arg" | $sedcmd -e "s/--power-grid-cellname=//"` + ;; + --flatten-cells-list=* ) + flattenCellsList=`echo "$arg" | $sedcmd -e "s/--flatten-cells-list=//"` + ;; + --flatten-view=* ) + flattenView=`echo "$arg" | $sedcmd -e "s/--flatten-view=//"` + ;; + --verbose ) + verbose=1 + ;; + --debug ) + debug=1 + ;; + --64 ) + bit64=1 + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + +if [ -n "$debug" ] ; then + verbose=1 +fi + +check_for_empty_arg "$packageRoot" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$cell" \ + "The cell that you want to flatten must be specified." 2 +check_for_empty_arg "$lib" \ + "The library that you want to flatten must be specified." 2 +check_for_empty_arg "$dfIIDir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$fulcrumPDKRoot" \ + "You must specify the location of the fulcrum pdk you want to use." 2 +check_for_empty_arg "$castPath" \ + "You must specify a cast-path" 2 +check_for_empty_arg "$workingDir" \ + "You must specify a working-dir" 2 +check_for_empty_arg "$cadenceLog" \ + "You must specify a cadence log file." 2 +check_for_empty_arg "$view" \ + "You must specify the view of \"$cell\" that you want to flatten out." 2 + +get_lib_name "$rootCell" +libName="$ret" +check_for_empty_arg "$libName" "Unable to get library name for \"$rootCell\"." 2 + +if [[ ( ! ( -w "$workingDir" && -d "$workingDir" ) ) ]] ; then + echo "Can't write and delete in $workingDir." + exit 2 +fi + +check_readable_dir "$packageRoot" \ + "Package Installation: \"$packageRoot\" is not a readable directory." 2 + +check_readable_dir "$dfIIDir" \ + "dfII directory: \"$dfIIDir\" is not a readable, writeable directory." 1 +conon_path "$dfIIDir" +dfIIDir="$ret" + +check_readable_dir "$fulcrumPDKRoot" \ + "Fulcrum PDK: \"$fulcrumPDKRoot\" is not a readable directory." 2 +conon_path "$fulcrumPDKRoot" +fulcrumPDKRoot="$ret" + +if [ "$cadenceLog" != "/dev/null" ] ; then + check_writeable_file "$cadenceLog" \ + "Cadence Log File: \"$cadenceLog\" is not a writeable file." 1 + conon_path "$cadenceLog" + cadenceLog="$ret" +fi + +skillRoot="$packageRoot/share/skill" +check_readable_dir "$skillRoot" \ + "Skill Root Directory: \"$skillRoot\" is not a readable directory." 2 + +mkcdswd="$archBinDir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +skillAutoLoad="$skillRoot/autoload.il" +check_readable_file "$skillAutoLoad" \ + "Skill Autoload: \"$skillAutoLoad\" is not a readable file." 2 + +pdkInfoIL="$fulcrumPDKRoot/share/Fulcrum/pdkinfo.il" +check_readable_file "$pdkInfoIL" \ + "pdkinfo.il: \"$pdkInfoIL\' is not a readable file." 2 + + +cdsWD=`mktemp -d $workingDir/flat.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Making cadence working directory." + echo "$mkcdswd \"--dfII-dir=$dfIIDir\" \"--fulcrum-pdk-root=$fulcrumPDKRoot\" \"--cast-path=$castPath\" \"--target-dir=$cdsWD\" \"--force\" \"--temp\"" +fi + +templateCdsWd= +if [ -n "$CDS_WD_TEMPLATE" ] ; then + templateCdsWd="--user-template=$CDS_WD_TEMPLATE" +fi + +$mkcdswd "--dfII-dir=$dfIIDir" \ + "--fulcrum-pdk-root=$fulcrumPDKRoot" \ + "--cast-path=$castPath" \ + "--target-dir=$cdsWD" \ + "--force" "--temp" "$templateCdsWd" + +mainIL=`mktemp $workingDir/flat.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Generating skill program." + verbose="t" +else + verbose="nil" + +fi + +cat <$mainIL +(unless ( equal "" "$debug" ) ( ilDebugToolBox )) +( load "$skillAutoLoad" ) +( load "$pdkInfoIL" ) +CellView= dbOpenCellViewByType( "$lib" "$cell" "$view" ) +flattenView=nrFlattenView( CellView "$flattenView" "$powerGridCellName" "$flattenCellsList" + ?Verbose $verbose + ?OverWrite t + ?DeleteWires t + ?DeleteVias t + ) +Status = if( flattenView 1 0 ) +(when ( equal "" "$debug" ) ( exit Status ) ) +SKILL + +cadenceLogTemp=`mktemp "$workingDir/cadenceLogTemp.XXXXXX"` +cadenceScript=`mktemp "$workingDir/cadenceScript.XXXXXX"` +cadenceErr=`mktemp "$workingDir/cadenceErr.XXXXXX"` + +if [ -n "$bit64" ] ; then +CDS_AUTO_64BIT=ALL +else +CDS_AUTO_64BIT=NONE +fi + +graphics= +if [ -z "$debug" ] ; then + graphics="-nograph" +fi + +cat <"$cadenceScript" +#!/bin/bash +cd "$cdsWD" +CDS_AUTO_64BIT=$CDS_AUTO_64BIT $layout \ +-replay "$mainIL" -log "$cadenceLogTemp" $graphics \ + /dev/null 2>"$cadenceErr" +EOF + +chmod +x "$cadenceScript" + +"$cadenceScript" + +if [ $? != 0 ] ; then + cat "$cadenceErr" 1>&2 + echo "ERROR: layoutPlus returned with non-zero exit status" 1>&2 +fi + +cp "$cadenceLogTemp" "$cadenceLog" + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/exportDesignDef.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/exportDesignDef.sh new file mode 100755 index 0000000000..9a5fbf761c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/nano/exportDesignDef.sh @@ -0,0 +1,282 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +arch_bin_dir=${0%\/*} +packageRoot=${arch_bin_dir%\/*} +shLibDir="$packageRoot/share/script/sh/sh-lib" + +archBinDir="$packageRoot/bin" + +umask 000 +source "$shLibDir/file/filecheck.sh" +source "$shLibDir/file/conon.sh" +source "$shLibDir/script/generate_script_with_libs.sh" + +function usage() { + echo "Usage: $0 " + echo " --cell=cellName" + echo " --lib=libName" + echo " --dfII-dir=dir" + echo " --fulcrum-pdk-root=dir" + echo " --cast-path=path" + echo " --working-dir=dir" + echo " [ --def-output=cell.def ]" + echo " [ --cadence-log=exportDesignDef.log]" + echo " [ --view=layout ]" + echo " [ --verbose ]" + echo " [ --64 ]" +} + +layout=`mywhich layoutPlus` || exit 2 +sedcmd=`mywhich sed` || exit 2 +gawkcmd=`mywhich gawk` || exit 2 +grepcmd=`mywhich grep` || exit 2 +bashcmd=`mywhich bash` || exit 2 +findcmd=`mywhich find` || exit 2 + +check_readable_dir "$archBinDir" \ + "Package arch bin: \"$archBinDir\" is not a readable directory." 2 + +cdsShLib="$packageRoot/share/script/sh/util" +check_readable_dir "$cdsShLib" \ + "Cadence Shell Script Library: \"$cdsShLib\" is not a readable directory." 2 + +cdsShLibFiles=`$findcmd "$cdsShLib" \! -type d` +for file in $cdsShLibFiles ; do + source "$file" +done + +cadenceName= +cell= +lib= +dfIIDir= +fulcrumPDKRoot= +castPath= +workingDir= +defOutput="cell.def" +bindRulOutput=/dev/null +outputRootCellName= +cadenceLog=exportDesignDef.log +view="layout" +verbose= +debug= +scale= +preservePins=1 +bit64= +OutputNets="nil" +AllSpecialNets="nil" +PowerPins="nil" + +if [ -n "$CDS_AUTO_64BIT" -a "$CDS_AUTO_64BIT" = "ALL" ]; then + bit64=1 +fi + +for arg in $@ ; do + + case "$arg" in + --cell=* ) + cell=`echo "$arg" | $sedcmd -e "s/--cell=//"` + ;; + --lib=* ) + lib=`echo "$arg" | $sedcmd -e "s/--lib=//"` + ;; + --dfII-dir=* ) + dfIIDir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrumPDKRoot=`echo "$arg" | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --cast-path=* ) + castPath=`echo "$arg" | $sedcmd -e "s/--cast-path=//"` + ;; + --working-dir=* ) + workingDir=`echo "$arg" | $sedcmd -e "s/--working-dir=//"` + ;; + --def-output=* ) + defOutput=`echo "$arg" | $sedcmd -e "s/--def-output=//"` + ;; + --cadence-log=* ) + cadenceLog=`echo "$arg" | $sedcmd -e "s/--cadence-log=//"` + ;; + --view=* ) + view=`echo "$arg" | $sedcmd -e "s/--view=//"` + ;; + --verbose ) + verbose=1 + ;; + --OutputNets ) + OutputNets="t" + ;; + --AllSpecialNets ) + AllSpecialNets="t" + ;; + --PowerPins ) + PowerPins="t" + ;; + --debug ) + debug=1 + ;; + --64 ) + bit64=1 + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + +if [ -n "$debug" ] ; then + verbose=1 +fi + +check_for_empty_arg "$packageRoot" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$cell" \ + "The cell that you want to lef & def out must be specified." 2 +check_for_empty_arg "$dfIIDir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$fulcrumPDKRoot" \ + "You must specify the location of the fulcrum pdk you want to use." 2 +check_for_empty_arg "$castPath" \ + "You must specify a cast-path" 2 +check_for_empty_arg "$workingDir" \ + "You must specify a working-dir" 2 +check_for_empty_arg "$cadenceLog" \ + "You must specify a cadence log file." 2 +check_for_empty_arg "$view" \ + "You must specify the view of \"$cell\" that you want to def out." 2 + +if [[ ( ! ( -w "$workingDir" && -d "$workingDir" ) ) ]] ; then + echo "Can't write and delete in $workingDir." + exit 2 +fi + +check_readable_dir "$packageRoot" \ + "Package Installation: \"$packageRoot\" is not a readable directory." 2 + +check_readable_dir "$dfIIDir" \ + "dfII directory: \"$dfIIDir\" is not a readable, writeable directory." 1 +conon_path "$dfIIDir" +dfIIDir="$ret" + +check_readable_dir "$fulcrumPDKRoot" \ + "Fulcrum PDK: \"$fulcrumPDKRoot\" is not a readable directory." 2 +conon_path "$fulcrumPDKRoot" +fulcrumPDKRoot="$ret" + +check_writeable_file "$defOutput" \ + "Def Output File: \"$defOutput\" can not be written to." 1 +conon_path "$defOutput" +defOutput="$ret" + +if [ "$cadenceLog" != "/dev/null" ] ; then + check_writeable_file "$cadenceLog" \ + "Cadence Log File: \"$cadenceLog\" is not a writeable file." 1 + conon_path "$cadenceLog" + cadenceLog="$ret" +fi + +skillRoot="$packageRoot/share/skill" +check_readable_dir "$skillRoot" \ + "Skill Root Directory: \"$skillRoot\" is not a readable directory." 2 + +mkcdswd="$archBinDir/mkcdswd" +check_executable_file "$mkcdswd" \ + "mkcdswd: \"$mkcdswd\" is not an executable file." 2 + +skillAutoLoad="$skillRoot/autoload.il" +check_readable_file "$skillAutoLoad" \ + "Skill Autoload: \"$skillAutoLoad\" is not a readable file." 2 + +pdkInfoIL="$fulcrumPDKRoot/share/Fulcrum/pdkinfo.il" +check_readable_file "$pdkInfoIL" \ + "pdkinfo.il: \"$pdkInfoIL\' is not a readable file." 2 + + +cdsWD=`mktemp -d $workingDir/lefdef.XXXXXX` + +if [ -n "$verbose" ] ; then + echo "Making cadence working directory." + echo "$mkcdswd \"--dfII-dir=$dfIIDir\" \"--fulcrum-pdk-root=$fulcrumPDKRoot\" \"--cast-path=$castPath\" \"--target-dir=$cdsWD\" \"--force\" \"--temp\"" +fi + +templateCdsWd= +if [ -n "$CDS_WD_TEMPLATE" ] ; then + templateCdsWd="--user-template=$CDS_WD_TEMPLATE" +fi + +$mkcdswd "--dfII-dir=$dfIIDir" \ + "--fulcrum-pdk-root=$fulcrumPDKRoot" \ + "--cast-path=$castPath" \ + "--target-dir=$cdsWD" \ + "--force" "--temp" "$templateCdsWd" + +mainIL=`mktemp $workingDir/lefdef.XXXXXX` + +tempLibDir=`mktemp -d $workingDir/lefdef.XXXXXX` +lefTempFile=`mktemp "$workingDir/lef.XXXXXX"` + +if [ -n "$verbose" ] ; then + echo "Generating skill program." + verbose="t" +else + verbose="nil" + +fi + +cat <$mainIL +(unless ( equal "" "$debug" ) ( ilDebugToolBox )) +( load "$skillAutoLoad" ) +( load "$pdkInfoIL" ) +defStatus=defDefOut( "$lib" + "$cell" + "$view" + "$defOutput" + ?Verbose $verbose + ?OutputNets $OutputNets + ?AllSpecialNets $AllSpecialNets + ?PowerPins $PowerPins +) +Status = (cond ( !defStatus 1 ) ( 0 ) ) +(when ( equal "" "$debug" ) ( exit Status ) ) +SKILL + +cadenceLogTemp=`mktemp "$workingDir/cadenceLogTemp.XXXXXX"` +cadenceScript=`mktemp "$workingDir/cadenceScript.XXXXXX"` +cadenceErr=`mktemp "$workingDir/cadenceErr.XXXXXX"` + +if [ -n "$bit64" ] ; then +CDS_AUTO_64BIT=ALL +else +CDS_AUTO_64BIT=NONE +fi + +graphics= +if [ -z "$debug" ] ; then + graphics="-nograph" +fi + +cat <"$cadenceScript" +#!/bin/bash +cd "$cdsWD" +CDS_AUTO_64BIT=$CDS_AUTO_64BIT $layout \ +-replay "$mainIL" -log "$cadenceLogTemp" $graphics \ + /dev/null 2>"$cadenceErr" +EOF + +chmod +x "$cadenceScript" + +"$cadenceScript" + +if [ $? != 0 ] ; then + cat "$cadenceErr" 1>&2 + echo "ERROR: layoutPlus returned with non-zero exit status" 1>&2 +fi + +cp "$cadenceLogTemp" "$cadenceLog" + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4.sh new file mode 100755 index 0000000000..f0eb5a362d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4.sh @@ -0,0 +1,266 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " --view-name=view_name" + echo " --cmd=command string" + echo " [ --client-spec=client_spec_name ]" + echo " [ --change-list=num ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " cell1 [ cell2 [ ... ] ]" + exit 2 + +} + +verbose= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +check_executable_file "$sedcmd" "Can't find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +dfII_dir= +view_name= +client_spec= +change_list= +no_sync= +cell_list= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +argname= + + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=${arg/--dfII-dir=} + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=${arg/--view-name=} + ;; + --cmd ) + argname="cmd" + ;; + --cmd=* ) + cmd=${arg/--cmd=} + ;; + --file ) + argname="file_name" + ;; + --file=* ) + file_name=${arg/--file=} + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=${arg/--client-spec=} + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=${arg/--change-list=} + ;; + --no-sync ) + no_sync=1 + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=${arg/--perforce-user=} + argname= + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=${arg/--perforce-password=} + argname= + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=${arg/--perforce-server=} + argname= + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=${arg/--perforce-port=} + argname= + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg"; + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 + +if [ -z "$file_name" ] ; then + check_for_empty_arg "$view_name" \ + "You must specify the view name or file that you want to edit for each cell." 2 +fi +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" +cd $dfII_dir; +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + + p4_sub_command="$p4_command $cmd" + + cadence_escape_string "$view_name" + escaped_view="$ret" + message "escaped_view $escaped_view" + + if [ -n "$change_list" ] ; then + p4_edit_command="$p4_edit_command -c $change_list" + fi + + for cell in $cell_list ; do + + message "cell $cell" + get_escaped_cell_dir "$cell" "$dfII_dir" + celltargetdir="$ret" + message "celltargetdir $celltargetdir" + + if [ -n "$celltargetdir" ] ; then + path_to_edit="$celltargetdir" + + if [ -n "$view_name" ] ; then + path_to_edit="$path_to_edit/$escaped_view" + fi + + if [ -n "$file_name" ] ; then + path_to_edit="$path_to_edit/$file_name" + fi + message "path_to_edit $path_to_edit" + + if [[ -r "$path_to_edit" && -w "$path_to_edit" && -d "$path_to_edit" ]] ; then + path_to_edit="$path_to_edit/..." + else + if [[ ! ( -r "$path_to_edit" && -f "$path_to_edit" ) ]] ; then + echo "\"$path_to_edit\" is not a file or directory." 1>&2 + path_to_edit= + fi + fi + + if [ -n "$path_to_edit" ] ; then + escaped_path_to_edit=`echo "$path_to_edit" | sed -e 's/#/%23/g'` + curr_p4_sub_command="$p4_sub_command $escaped_path_to_edit" + message "$cur_p4_sub_command" + + $curr_p4_sub_command + fi + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + done +else + echo "The client specification \"$client_spec\" does not exist." 1>&2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4add.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4add.sh new file mode 100755 index 0000000000..c98a313191 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4add.sh @@ -0,0 +1,430 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " ( --file=filename |" + echo " --view-name=view_name" + echo " [ --file=filename ] )" + echo " [ --file-type=ktext ]" + echo " [ --client-spec=client_spec_name ]" + echo " [ --change-list=num ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " [ --verbose ]" + echo " cell1 [ cell2 [ ... ] ]" + exit 2 + +} + +verbose= + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +sortcmd=`which sort` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 +check_executable_file "$sortcmd" "Can't find sort in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + +dfII_dir= +view_name= +file_name= +file_type="ktext" +client_spec= +change_list=default +cell_list= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +argname= +oa=1 + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=${arg/--dfII-dir=} + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=${arg/--view-name=} + ;; + --file ) + argname="file_name" + ;; + --file=* ) + file_name=${arg/--file=} + ;; + --file-type ) + argname="file_type" + ;; + --file-type=* ) + file_type=${arg/--file-type=} + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=${arg/--client-spec=} + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=${arg/--change-list=} + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=${arg/--perforce-user=} + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=${arg/--perforce-password=} + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=${arg/--perforce-server=} + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=${arg/--perforce-port=} + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg" + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 +if [ -z "$file_name" ] ; then + check_for_empty_arg "$view_name" \ + "You must specify the view name or file that you want to add for each cell." 2 +else + check_for_empty_arg "$file_type" \ + "You must specify a file type if you are adding a file." 2 +fi +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +# cd into dfII dir so AltRoots work +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + + cadence_escape_string "$view_name" + escaped_view="$ret" + message "escaped_view $escaped_view" + + p4_add_command="$p4_command add -f" + p4_fstat_command="$p4_command fstat" + p4_reopen_command="$p4_command reopen" + if [ -n "$change_list" -a "$change_list" != "default" ] ; then + p4_add_command="$p4_add_command -c $change_list" + p4_reopen_command="$p4_reopen_command -c $change_list" + fi + + for cell in $cell_list ; do + message "cell $cell" + if [ -n "$view_name" ] ; then + message "view_name $view_name" + if [ -z "$file_name" ] ; then + get_cadence_cell_view_binary_files "$cell" "$view_name" "$dfII_dir" + cell_view_bin_files="$ret" + message "cell_view_bin_files $cell_view_bin_files" + + get_cadence_cell_view_text_files "$cell" "$view_name" "$dfII_dir" + cell_view_text_files="$ret" + message "cell_view_text_files $cell_view_text_files" + + if [[ -n "$cell_view_bin_files" && -n "cell_view_text_files" ]] ; then + is_invalid_cadence_cell_view "$cell" "$view_name" "$dfII_dir" + invalid_cell_view="$ret" + message "invalid_cell_view $invalid_cell_view" + if [[ "$invalid_cell_view" == "0" ]] ; then + + for bin_file in $cell_view_bin_files ; do + if [[ ! ( -f "$bin_file" && + -r "$bin_file" && + -w "$bin_file" ) ]] ; then + touch $bin_file + fi + escaped_bin_file=`echo "$bin_file" | sed -e 's/#/%23/g'` + $p4_add_command -t "binary+l" -f "$bin_file" + done + for text_file in $cell_view_text_files ; do + if [[ ! ( -f "$text_file" && + -r "$text_file" && + -w "$text_file" ) ]] ; then + touch $text_file + fi + escaped_text_file=`echo "$text_file" | sed -e 's/#/%23/g'` + $p4_add_command -t "text+l" "$text_file" + done + + else + echo "\"$view_name\" of \"$cell\" does not seem to be a valid cell view." 1>&2 + cell_view_files="$cell_view_bin_files $cell_view_text_files" + for file in $cell_view_files ; do + if [[ ! ( -r "$file" && + -f "$file" ) ]] ; then + echo "\"$file\" is not a readable file." 1>&2 + fi + done + fi + else + echo "Unable to get list of files for \"$view_name\" of \"$cell\"." 1>&2 + fi + else + get_cadence_cell_view_dir "$cell" "$view_name" "$dfII_dir" + cellViewDir="$ret" + message "cellViewDir $cellViewDir" + + if [ -n "$cellViewDir" ] ; then + cellViewFile="$cellViewDir/$file_name" + message "cellViewFile $cellViewFile" + + if [[ -r "$cellViewFile" && -f "$cellViewFile" ]] ; then + $p4_add_command -t "$file_type" "$cellViewFile" + else + echo "ERROR: \"$cellViewFile\" is not a file." 1>&2 + fi + else + echo "ERROR: Unable to get directory for \"$cell\" \"$view_name\"." 1>&2 + fi + fi + else + get_escaped_cell_dir "$cell" "$dfII_dir" + cellDir="$ret" + message "cellDir $cellDir" + + if [ -n "$cellDir" ] ; then + cellFile="$cellDir/$file_name" + message "cellFile $cellFile" + escaped_cellFile=`echo "$cellFile" | sed -e 's/#/%23/g'` + + if [[ -r "$cellFile" && -f "$cellFile" ]] ; then + $p4_add_command -t "$file_type" "$cellFile" + else + echo "ERROR: \"$cellFile\" is not a file." 1>&2 + fi + else + echo "ERROR: Unable to get directory for \"$cell\"." 1>&2 + fi + fi + get_lib_name "$cell" + lib_list="$ret $lib_list" + message "lib for $cell is $ret" + done + + lib_list=`echo "$lib_list" | $sortcmd -u` + message "lib_list $lib_list" + + for lib in $lib_list ; do + message "lib $lib" + get_library_dir_for_libraray "$lib" "$dfII_dir" + lib_dir="$ret" + message "lib_dir $lib_dir" + + lib_prop_xx="$lib_dir/prop.xx" + lib_cdsinfo="$lib_dir/cdsinfo.tag" + lib_oalib="$lib_dir/.oalib" + lib_techlib="$lib_dir/tech.db" + lib_datadm="$lib_dir/data.dm" + + # prop.xx must not exist in OA + if [[ ( "$oa" == "1" || + ( -f "$lib_prop_xx" && + -r "$lib_prop_xx" ) ) && + -f "$lib_cdsinfo" && + -r "$lib_cdsinfo" && + -s "$lib_cdsinfo" && + ( "$oa" == "0" || + ( -f "$lib_oalib" && + -r "$lib_oalib" && + -s "$lib_oalib" ) + ) + ]] ; then + if [ "$oa" == "1" ]; then + lib_bin_files= + if [ -f $lib_techlib ]; then lib_bin_files="$lib_techlib"; fi + if [ -f $lib_datadm ]; then lib_bin_files="$lib_bin_files $lib_datadm"; fi + lib_text_files="$lib_cdsinfo $lib_oalib" + else + lib_bin_files="$lib_prop_xx" + lib_text_files="$lib_cdsinfo" + fi + + for bin_file in $lib_bin_files ; do + message "bin_file $bin_file" + escaped_bin_file=`echo "$bin_file" | sed -e 's/#/%23/g'` + message "escaped_bin_file $escaped_bin_file" + depot_path=`$p4_fstat_command "$escaped_bin_file" 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + message "depot_path $depot_path" + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command "$escaped_bin_file" | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + message "curr_action $curr_action" + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command $escaped_bin_file | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + message "curr_change_list $curr_change_list" + if [[ "$change_list" != "$curr_change_list" ]] ; then + message "\"$bin_file\" is open in change list \"$curr_change_list\"." + message "\"$bin_file\" will now be opened in change list \"$change_list\"." + $p4_reopen_command -t "binary+l" "$escaped_bin_file" + else + message "\"$bin_file\" is already open in change list \"$change_list\", skipping..." + fi + else + message "\"$bin_file\" is already checked into perforce, skipping..." + fi + else + if [[ ! ( -f "$bin_file" && + -r "$bin_file" && + -w "$bin_file" ) ]] ; then + touch "$bin_file" + fi + message "\"$bin_file\" has never been added to perforce, adding now." + $p4_add_command -t "binary+l" "$bin_file" + fi + done + + for text_file in $lib_text_files ; do + message "text_file $text_file" + escaped_text_file=`echo "$text_file" | sed -e 's/#/%23/g'` + message "escaped_text_file $escaped_text_file" + depot_path=`$p4_fstat_command "$escaped_text_file" 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command "$escaped_text_file" | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + message "curr_action $curr_action" + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command $escaped_text_file | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + message "curr_change_list $curr_change_list" + if [[ "$change_list" != "$curr_change_list" ]] ; then + message "\"$text_file\" is open in change list \"$curr_change_list\"." + message "\"$text_file\" will now be opened in change list \"$change_list\"." + $p4_reopen_command -t "text+l" "$escaped_text_file" + else + message "\"$text_file\" is already open in change list \"$change_list\", skipping..." + fi + else + message "\"$text_file\" is already checked into perforce, skipping..." + fi + else + if [[ ! ( -f "$text_file" && + -r "$text_file" && + -w "$text_file" ) ]] ; then + touch "$text_file" + fi + message "\"$text_file\" has never been added to perforce, adding now." + $p4_add_command -t "text+l" "$text_file" + fi + done + else + echo "ERROR: \"$lib\" in \"$lib_dir\" is not a valid library." 1>&2 + fi + done + +else + echo "The client specification \"$client_spec\" does not exist." 1>&2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4addlibs.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4addlibs.sh new file mode 100755 index 0000000000..3e13aebe66 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4addlibs.sh @@ -0,0 +1,285 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " [ --client-spec=client_spec_name ]" + echo " [ --change-list=num ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " [ --fast ]" + echo " [ --no-recurse ]" + +} + +verbose= +fast= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +findcmd=`which find` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 +check_executable_file "$findcmd" "Can't find find in \"$PATH\"." 2 + +dfII_dir= +view_name= +client_spec= +change_list= +cell_list= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +argname= +no_recurse= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --fast ) + fast=t + ;; + --verbose ) + verbose=t + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=${arg/--dfII-dir=} + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=${arg/--client-spec=} + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=${arg/--change-list=} + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=${arg/--perforce-user=} + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=${arg/--perforce-password=} + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=${arg/--perforce-server=} + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=${arg/--perforce-port=} + ;; + --no-recurse ) + no_recurse="-maxdepth 1" + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg" + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + + p4_add_command="$p4_command add -f" + p4_edit_command="$p4_command edit" + p4_fstat_command="$p4_command fstat" + p4_reopen_command="$p4_command reopen" + if [ -n "$change_list" ] ; then + p4_add_command="$p4_add_command -c $change_list" + p4_edit_command="$p4_edit_command -c $change_list" + p4_reopen_command="$p4_reopen_command -c $change_list" + else + p4_reopen_command="$p4_reopen_command -c default" + change_list="default" + fi + + message "Searching for all cdsinfo.tag files under \"$dfII_dir\"." + if [ -n "$fast" -a -z "$no_recurse" ]; then + all_cds_info_files=`$findcmd $dfII_dir -follow \\( \\( -name '*#*' -o -name '[RS]*' \\) -prune \\) -o -type f -name "cdsinfo.tag" -print` + else + all_cds_info_files=`$findcmd "$dfII_dir" $no_recurse -type f -name "cdsinfo.tag"` + fi + + for cds_info in $all_cds_info_files ; do + cds_info_dir=`dirname $cds_info` + + lib_prop_xx="$cds_info_dir/prop.xx" + lib_oalib="$cds_info_dir/.oalib" + lib_techdb="$cds_info_dir/tech.db" + lib_datadm="$cds_info_dir/data.dm" + + message "\"$cds_info_dir\" smells like a library." + + if [ "$oa" == "1" ]; then + lib_bin_files= + if [ -f $lib_techdb ]; then lib_bin_files="$lib_techdb"; fi + if [ -f $lib_datadm ]; then lib_bin_files="$lib_bin_files $lib_datadm"; fi + lib_text_files="$cds_info $lib_oalib" + else + lib_bin_files="$lib_prop_xx" + lib_text_files="$cds_info" + fi + + for bin_file in $lib_bin_files ; do + message "bin_file $bin_file" + escaped_bin_file=`echo "$bin_file" | sed -e 's/#/%23/g'` + depot_path=`$p4_fstat_command $escaped_bin_file 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command $escaped_bin_file | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command $escaped_bin_file | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + if [[ "$change_list" != "$curr_change_list" ]] ; then + message "\"$bin_file\" is open in change list \"$curr_change_list\"." + message "\"$bin_file\" will now be opened in change list \"$change_list\"." + $p4_reopen_command -t "binary+l" "$escaped_bin_file" + else + message "\"$bin_file\" is already open in change list \"$change_list\", skipping..." + fi + else + message "\"$bin_file\" is already checked into perforce, skipping..." + fi + else + if [[ ! ( -f "$bin_file" && + -r "$bin_file" && + -w "$bin_file" ) ]] ; then + touch "$bin_file" + fi + message "\"$bin_file\" has never been added to perforce, adding now." + $p4_add_command -t "binary+l" "$bin_file" + fi + done + + for text_file in $lib_text_files ; do + message "text_file $text_file" + escaped_text_file=`echo "$text_file" | sed -e 's/#/%23/g'` + depot_path=`$p4_fstat_command $escaped_text_file 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command $escaped_text_file | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command $escaped_text_file | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + if [[ "$change_list" != "$curr_change_list" ]] ; then + message "\"$text_file\" is open in change list \"$curr_change_list\"." + message "\"$text_file\" will now be opened in change list \"$change_list\"." + $p4_reopen_command -t "text+l" "$escaped_text_file" + else + message "\"$text_file\" is already open in change list \"$change_list\", skipping..." + fi + else + message "\"$text_file\" is already checked into perforce, skipping..." + fi + else + if [[ ! ( -f "$text_file" && + -r "$text_file" && + -w "$text_file" ) ]] ; then + touch "$text_file" + fi + message "\"$text_file\" has never been added to perforce, adding now." + $p4_add_command -t "text+l" "$text_file" + fi + done + done + +else + echo "The client specification \"$client_spec\" does not exist." +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4celllog.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4celllog.sh new file mode 100755 index 0000000000..4fab4232db --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4celllog.sh @@ -0,0 +1,176 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " [ --client-spec=client_spec_name ]" + echo " --dfII-dir=dir --view-name=view_name" + echo " cell1 [ cell2 [ ... ] ]" + +} + +verbose= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +egrepcmd=`which egrep` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$egrepcmd" "Can't find grep in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + +client_spec= +dfII_dir= +cell_list= +view_name= +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=${arg/--client-spec=} + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=${arg/--dfII-dir=} + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=${arg/--view-name=} + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg" + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 + +check_for_empty_arg "$view_name" \ + "You must specify the view name of the cells you want to see the log for." 2 + + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_cmd="$p4_executable" + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_executable client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_executable clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + cadence_escape_string "$view_name" + escaped_view="$ret" + message "escaped_view $escaped_view" + + p4_command="$p4_executable -c $client_spec" + + p4_log_command="$p4_command filelog" + + for cell in $cell_list ; do + message "cell $cell" + bad_cell_name=`echo $cell | grep -e "#"` + if [ -z "$bad_cell_name" ] ; then + + get_escaped_cell_dir "$cell" "$dfII_dir" + celltargetdir="$ret" + message "celltargetdir $celltargetdir" + + if [ -n "$celltargetdir" ] ; then + if [ "$oa" == "1" ]; then + curr_file_to_log="$celltargetdir/$escaped_view/layout.oa" + else + curr_file_to_log="$celltargetdir/$escaped_view/layout.cdb" + fi + + curr_file_to_log=`echo "$curr_file_to_log" | sed -e 's/#/%23/g'` + curr_p4_log_command="$p4_log_command $curr_file_to_log" + + $curr_p4_log_command | \ + $egrepcmd '...[[:space:]]+(change)|(desc)' | \ + $sedcmd -e 's/.*#[0-9]* change /change /' \ + -e 's/...[[:space:]]+desc[0-9]*/descripion:/' + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + done + +else + echo "The client specification \"$client_spec\" does not exist." 1>&2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4delete.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4delete.sh new file mode 100755 index 0000000000..1173d8f64d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4delete.sh @@ -0,0 +1,234 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " [ --client-spec=client_spec_name ]" + echo " [ --view-name=view_name ]" + echo " [ --change-list=num ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " cell1 [ cell2 [ ... ] ]" + +} + +verbose= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +client_spec= +dfII_dir= +cell_list= +view_name= +change_list= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=${arg/--client-spec=} + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=${arg/--dfII-dir=} + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=${arg/--view-name=} + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=${arg/--change-list=} + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=${arg/--perforce-user=} + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=${arg/--perforce-password=} + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=${arg/--perforce-server=} + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=${arg/--perforce-port=} + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg" + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +# cd into dfII dir so AltRoots work +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + + p4_delete_command="$p4_command delete" + + if [ -n "$change_list" ] ; then + p4_delete_command="$p4_delete_command -c $change_list" + fi + + + cadence_escape_string "$view_name" + escaped_view="$ret" + message "escaped_view $escaped_view" + + for cell in $cell_list ; do + message "cell $cell" + + bad_cell_name=`echo $cell | $grepcmd -e "#"` + if [ -z "$bad_cell_name" ] ; then + + get_escaped_cell_dir "$cell" "$dfII_dir" + celltargetdir="$ret" + message "celltargetdir $celltargetdir" + if [ -n "$celltargetdir" ] ; then + + curr_dir_to_delete="$celltargetdir" + + if [ -n "$view_name" ] ; then + curr_dir_to_delete="$curr_dir_to_delete/$escaped_view" + fi + + curr_dir_to_delete=`echo "$curr_dir_to_delete" | sed -e 's/#/%23/g'` + + curr_p4_delete_command="$p4_delete_command $curr_dir_to_delete/..." + + $curr_p4_delete_command + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + done + +else + echo "The client specification \"$client_spec\" does not exist." 1>&2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4edit.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4edit.sh new file mode 100755 index 0000000000..2f39ceac6b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4edit.sh @@ -0,0 +1,272 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " ( --file=filename |" + echo " --view-name=view_name" + echo " [ --file=filename ] )" + echo " [ --client-spec=client_spec_name ]" + echo " [ --change-list=num ]" + echo " [ --no-sync ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " cell1 [ cell2 [ ... ] ]" + +} + +verbose= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +dfII_dir= +view_name= +file_name= +client_spec= +change_list= +cell_list= +no_sync= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=${arg/--dfII-dir=} + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=${arg/--view-name=} + ;; + --file ) + argname="file_name" + ;; + --file=* ) + file_name=${arg/--file=} + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=${arg/--client-spec=} + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=${arg/--change-list=} + ;; + --no-sync ) + no_sync=1 + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=${arg/--perforce-user=} + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=${arg/--perforce-password=} + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=${arg/--perforce-server=} + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=${arg/--perforce-port=} + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg" + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 + + +if [ -z "$file_name" ] ; then + check_for_empty_arg "$view_name" \ + "You must specify the view name or file that you want to edit for each cell." 2 +fi +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + + + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +# cd into dfII dir so AltRoots work +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + + p4_sync_command="$p4_command sync" + p4_edit_command="$p4_command edit" + p4_lock_command="$p4_command lock" + + cadence_escape_string "$view_name" + escaped_view="$ret" + message "escaped_view $escaped_view" + + if [ -n "$change_list" ] ; then + p4_edit_command="$p4_edit_command -c $change_list" + fi + + for cell in $cell_list ; do + + message "cell $cell" + get_escaped_cell_dir "$cell" "$dfII_dir" + celltargetdir="$ret" + message "celltargetdir $celltargetdir" + + if [ -n "$celltargetdir" ] ; then + path_to_edit="$celltargetdir" + + if [ -n "$view_name" ] ; then + path_to_edit="$path_to_edit/$escaped_view" + fi + + if [ -n "$file_name" ] ; then + path_to_edit="$path_to_edit/$file_name" + fi + message "path_to_edit $path_to_edit" + + if [[ -r "$path_to_edit" && -w "$path_to_edit" && -d "$path_to_edit" ]] ; then + path_to_edit="$path_to_edit/..." + else + if [[ ! ( -r "$path_to_edit" && -f "$path_to_edit" ) ]] ; then + echo "ERROR: \"$path_to_edit\" is not a file or directory." + path_to_edit= + fi + fi + + path_to_edit=`echo "$path_to_edit" | sed -e 's/#/%23/g'` + + if [ -n "$path_to_edit" ] ; then + curr_p4_sync_command="$p4_sync_command $path_to_edit" + + curr_p4_edit_command="$p4_edit_command $path_to_edit" + + curr_p4_lock_command="$p4_lock_command $path_to_edit" + + if [[ "$no_sync" != "1" ]] ; then + $curr_p4_sync_command &>/dev/null + fi + + $curr_p4_edit_command + fi + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + done +else + echo "The client specification \"$client_spec\" does not exist." 1>&2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4opened.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4opened.sh new file mode 100755 index 0000000000..782603c4f4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4opened.sh @@ -0,0 +1,207 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED + +function usage() { + echo "Usage: $0 " + echo " [ --user=all ]" + echo " [ --client-spec=client_spec_name ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + exit 2 + +} + +verbose= + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +sortcmd=`which sort` +uniqcmd=`which uniq` +perlcmd="/usr/intel/bin/perl" +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 +check_executable_file "$sortcmd" "Can't find sort in \"$PATH\"." 2 +check_executable_file "$uniqcmd" "Can't find uniq in \"$PATH\"." 2 +check_executable_file "$p4_executable" "Can't find p4 in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +user="all" +client_spec= +p4_user= +p4_passwd= +p4_server_host="ssl:p4proxy07.devtools.intel.com" +p4_server_port="2510" +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --user ) + argname="user" + ;; + --user=* ) + user=${arg/--user=} + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=${arg/--client-spec=} + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=${arg/--perforce-user=} + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=${arg/--perforce-password=} + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=${arg/--perforce-server=} + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=${arg/--perforce-port=} + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg" + else + usage + exit 2 + fi + argname= + ;; + esac +done + +check_for_empty_arg "$user" \ + "You must specify a user name with which to filter." 2 +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4Command="$p4_cmd -c $client_spec" + + p4OpenedCommand="$p4Command opened -a" + + userPattern=".*" + if [[ "$user" != "all" ]] ; then + userPattern="$user" + fi + + export userPattern + export client_spec + + $p4OpenedCommand | + $perlcmd -l -e ' + $user=$ENV{userPattern}; + $client_spec=$ENV{client_spec}; + while(<>) { + chomp; + next if ! ((/layout.cdb#/) or (/layout.oa#/)); + @f=split; + $file=$f[0]; + $file =~ s/#\d+$//; + $action=$f[2]; + $change=$f[3]; + $client=$f[$#f]; + $client=$f[$#f-1] if ($client =~ /(locked|exclusive)/); + $client =~ s/@/ /g; + next if ! ( $client =~ / $client_spec$/); + next if ( (! ($client =~ /^$user /)) and $user ne ".*" ); + $file =~ s://depot/.*/dfII/::; + @d=split(/\//,$file); + $branch=$d[1]; + $view=$d[$#d-1]; + $cell=$d[$#d-2]; + $cell =~ s/%232e/./g; + $cell =~ s/%232d/-/g; + $cell =~ s/%2324/\$/g; + print "$branch $cell $view $action $change $client"; + }' + +else + echo "The client specification \"$client_spec\" does not exist." +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4revert.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4revert.sh new file mode 100755 index 0000000000..89d5345cb4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4revert.sh @@ -0,0 +1,249 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATE 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " [ --client-spec=client_spec_name ]" + echo " [ --view-name=view_name ]" + echo " [ --file-name=file_name ]" + echo " [ --change-list=num ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " cell1 [ cell2 [ ... ] ]" + +} + +verbose= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +client_spec= +dfII_dir= +cell_list= +view_name= +file_name= +change_list= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +verbose= +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=`echo $arg | $sedcmd -e "s/--client-spec=//"` + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=`echo $arg | $sedcmd -e "s/--dfII-dir=//"` + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=`echo $arg | $sedcmd -e "s/--view-name=//"` + ;; + --file ) + argname="file_name" + ;; + --file=* ) + file_name=${arg/--file=} + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=`echo $arg | $sedcmd -e "s/--change-list=//"` + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=`echo $arg | $sedcmd -e "s/--perforce-user=//"` + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=`echo $arg | $sedcmd -e "s/--perforce-password=//"` + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=`echo $arg | $sedcmd -e "s/--perforce-server=//"` + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=`echo $arg | $sedcmd -e "s/--perforce-port=//"` + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg" + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 +if [ -z "$file_name" ] ; then + check_for_empty_arg "$view_name" \ + "You must specify the view name or file that you want to edit for each cell." 2 +fi +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +# cd into dfII dir so AltRoots work +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + + p4_revert_command="$p4_command revert" + + if [ -n "$change_list" ] ; then + p4_revert_command="$p4_revert_command -c $change_list" + fi + + + cadence_escape_string "$view_name" + escaped_view="$ret" + message "escaped_view $escaped_view" + + for cell in $cell_list ; do + bad_cell_name=`echo $cell | $grepcmd -e "#"` + message "bad_cell_name $bad_cell_name" + if [ -z "$bad_cell_name" ] ; then + + get_escaped_cell_dir "$cell" "$dfII_dir" + celltargetdir="$ret" + message "celltargetdir $celltargetdir" + if [ -n "$celltargetdir" ] ; then + + curr_dir_to_revert="$celltargetdir" + + if [ -n "$view_name" ] ; then + curr_dir_to_revert="$curr_dir_to_revert/$escaped_view" + fi + if [ -n "$file_name" ] ; then + path_to_revert="$path_to_revert/$file_name" + fi + + message "curr_dir_to_revert $curr_dir_to_revert" + escaped_dir_to_revert=`echo "$curr_dir_to_revert" | sed -e 's/#/%23/g'` + + curr_p4_revert_command="$p4_revert_command $escaped_dir_to_revert/..." + + $curr_p4_revert_command + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + else + echo "\"$cell\" is not a valid cell name." 1>&2 + fi + done + +else + echo "The client specification \"$client_spec\" does not exist." 1>&2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4smartedit.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4smartedit.sh new file mode 100755 index 0000000000..0b724c5762 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4smartedit.sh @@ -0,0 +1,417 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " --view-name=view_name" + echo " [ --client-spec=client_spec_name ]" + echo " [ --change-list=num ]" + echo " [ --perforce-user=user_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " cell1 [ cell2 [ ... ] ]" + +} + +verbose= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +p4_executable=`which p4` +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +sortcmd=`which sort` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 +check_executable_file "$sortcmd" "Can't find sort in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +dfII_dir= +view_name= +client_spec= +change_list= +no_sync= +cell_list= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=`echo $arg | $sedcmd -e "s/--dfII-dir=//"` + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=`echo $arg | $sedcmd -e "s/--view-name=//"` + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=`echo $arg | $sedcmd -e "s/--client-spec=//"` + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=`echo $arg | $sedcmd -e "s/--change-list=//"` + ;; + --no-sync ) + no_sync=1 + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=`echo $arg | $sedcmd -e "s/--perforce-user=//"` + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=`echo $arg | $sedcmd -e "s/--perforce-password=//"` + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=`echo $arg | $sedcmd -e "s/--perforce-server=//"` + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=`echo $arg | $sedcmd -e "s/--perforce-port=//"` + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg"; + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$view_name" \ + "You must specify the view name that you want to add for each cell." 2 +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +# cd into dfII dir so AltRoots work +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + message "p4_command $p4_command" + + cadence_escape_string "$view_name" + escaped_view="$ret" + message "escaped_view $escaped_view" + + p4_add_command="$p4_command add -f" + p4_edit_command="$p4_command edit" + p4_fstat_command="$p4_command fstat" + p4_reopen_command="$p4_command reopen" + p4_sync_command="$p4_command sync" + if [ -n "$change_list" ] ; then + p4_add_command="$p4_add_command -c $change_list" + p4_edit_command="$p4_edit_command -c $change_list" + p4_reopen_command="$p4_reopen_command -c $change_list" + else + p4_reopen_command="$p4_reopen_command -c default" + change_list="default" + fi + + message "cell_list $cell_list" + for cell in $cell_list ; do + get_cadence_cell_view_binary_files "$cell" "$view_name" "$dfII_dir" + cell_view_bin_files="$ret" + message "cell_view_bin_files $cell_view_bin_files" + + get_cadence_cell_view_text_files "$cell" "$view_name" "$dfII_dir" + cell_view_text_files="$ret" + message "cell_view_text_files $cell_view_text_files" + if [[ -n "$cell_view_bin_files" && -n "cell_view_text_files" ]] ; then + is_invalid_cadence_cell_view "$cell" "$view_name" "$dfII_dir" + invalid_cell_view="$ret" + message "invalid_cell_view $ret" + if [[ "$invalid_cell_view" == "0" ]] ; then + + for bin_file in $cell_view_bin_files ; do + escaped_bin_file=`echo "$bin_file" | sed -e 's/#/%23/g'` + message "bin_file $bin_file" + message "escaped_bin_file $escaped_bin_file" + depot_path=`$p4_fstat_command "$escaped_bin_file" 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + message "depot_path $depot_path" + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command "$escaped_bin_file" | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + message "curr_action $curr_action"; + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command "$escaped_bin_file" | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + message "curr_change_list $curr_change_list" + if [[ "$change_list" != "$curr_change_list" ]] ; then + $p4_reopen_command -t "binary+l" "$escaped_bin_file" + fi + else + if [[ -z "$no_sync" || ( ! -e "$bin_file" ) ]] ; then + $p4_sync_command -f "$escaped_bin_file" + fi + $p4_edit_command -t "binary+l" "$escaped_bin_file" + fi + else + if [[ ! ( -f "$bin_file" && + -r "$bin_file" && + -w "$bin_file" ) ]] ; then + touch "$bin_file" + fi + $p4_add_command -t "binary+l" "$bin_file" + fi + done + + for text_file in $cell_view_text_files ; do + message "text_file $text_file" + escaped_text_file=`echo "$text_file" | sed -e 's/#/%23/g'` + depot_path=`$p4_fstat_command "$escaped_text_file" 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + message "depot_path $depot_path" + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command "$escaped_text_file" | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + message "curr_action $curr_action" + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command "$escaped_text_file" | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + message "curr_change_list $curr_change_list" + if [[ "$change_list" != "$curr_change_list" ]] ; then + $p4_reopen_command -t "text+l" "$escaped_text_file" + fi + else + if [[ -z "$no_sync" || ( ! -e "$text_file" ) ]] ; then + $p4_sync_command -f "$escaped_text_file" + fi + $p4_edit_command -t "text+l" "$escaped_text_file" + fi + else + if [[ ! ( -f "$text_file" && + -r "$text_file" && + -w "$text_file" ) ]] ; then + touch "$text_file" + fi + $p4_add_command -t "text+l" "$text_file" + fi + done + + else + echo "\"$view_name\" of \"$cell\" does not seem to be a valid cell view." 1>&2 + cell_view_files="$cell_view_bin_files $cell_view_text_files" + for file in $cell_view_files ; do + if [[ ! ( -r "$file" && + -f "$file" ) ]] ; then + echo "\"$file\" is not a readable file." 1>&2 + fi + done + fi + else + echo "Unable to get list of files for \"$view_name\" of \"$cell\"." 1>&2 + fi + get_lib_name "$cell" + message "lib for $cell is $ret" + lib_list="$ret $lib_list" + message "lib_list $lib_list" + done + + lib_list=`echo "$lib_list" | $sortcmd -u` + + for lib in $lib_list ; do + get_library_dir_for_libraray "$lib" "$dfII_dir" + lib_dir="$ret" + message "lib_dir for $lib is $lib_dir" + + lib_prop_xx="$lib_dir/prop.xx" + lib_cdsinfo="$lib_dir/cdsinfo.tag" + lib_oalib="$lib_dir/.oalib" + lib_techdb="$lib_dir/tech.db" + lib_datadm="$lib_dir/data.dm" + + if [[ ( "$oa" == "1" || + ( -f "$lib_prop_xx" && + -r "$lib_prop_xx" ) ) && + -f "$lib_cdsinfo" && + -r "$lib_cdsinfo" && + -s "$lib_cdsinfo" && + ( "$oa" == "0" || + ( -f "$lib_oalib" && + -r "$lib_oalib" && + -s "$lib_oalib" ) + ) + ]] ; then + + if [ "$oa" == "1" ]; then + lib_bin_files= + lib_text_files="$lib_cdsinfo $lib_oalib" + if [ -f $lib_techdb ]; then lib_bin_files="$lib_techdb"; fi + if [ -f $lib_datadm ]; then lib_bin_files="$lib_bin_files $lib_datadm"; fi + else + lib_bin_files="$lib_prop_xx" + lib_text_files="$lib_cdsinfo" + fi + + for bin_file in $lib_bin_files ; do + message "bin_file $bin_file" + escaped_bin_file=`echo "$bin_file" | sed -e 's/#/%23/g'` + message "escaped_bin_file $escaped_bin_file" + depot_path=`$p4_fstat_command "$escaped_bin_file" 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command "$escaped_bin_file" | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command "$escaped_bin_file" | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + if [[ "$change_list" != "$curr_change_list" ]] ; then + message "\"$bin_file\" is open in change list \"$curr_change_list\"." + message "\"$bin_file\" will now be opened in change list \"$change_list\"." + $p4_reopen_command -t "binary+l" "$escaped_bin_file" + else + message "\"$bin_file\" is already open in change list \"$change_list\", skipping..." + fi + else + message "\"$bin_file\" is already checked into perforce, skipping..." + fi + else + if [[ ! ( -f "$bin_file" && + -r "$bin_file" && + -w "$bin_file" ) ]] ; then + touch "$bin_file" + fi + message "\"$bin_file\" has never been added to perforce, adding now." + $p4_add_command -t "binary+l" "$bin_file" + fi + done + + for text_file in $lib_text_files ; do + message "text_file $text_file" + escaped_text_file=`echo "$text_file" | sed -e 's/#/%23/g'` + message "escaped_text_file $escaped_text_file" + depot_path=`$p4_fstat_command "$escaped_text_file" 2>/dev/null | $grepcmd -e "^\.\.\. depotFile" | $gawkcmd -- " { print \\$3 } "` + message "depot_path $depot_path" + if [ -n "$depot_path" ] ; then + curr_action=`$p4_fstat_command "$escaped_text_file" | $grepcmd -e "^\.\.\. action" | $gawkcmd -- " { print \\$3 } "` + message "curr_action $curr_action" + if [ -n "$curr_action" ] ; then + curr_change_list=`$p4_fstat_command "$text_file" | $grepcmd -e "^\.\.\. change" | $gawkcmd -- " { print \\$3 } "` + message "curr_change_list $curr_change_list" + if [[ "$change_list" != "$curr_change_list" ]] ; then + message "\"$text_file\" is open in change list \"$curr_change_list\"." + message "\"$text_file\" will now be opened in change list \"$change_list\"." + $p4_reopen_command -t "text+l" "$escaped_text_file" + else + message "\"$text_file\" is already open in change list \"$change_list\", skipping..." + fi + else + message "\"$text_file\" is already checked into perforce, skipping..." + fi + else + if [[ ! ( -f "$text_file" && + -r "$text_file" && + -w "$text_file" ) ]] ; then + touch "$text_file" + fi + message "\"$text_file\" has never been added to perforce, adding now." + $p4_add_command -t "text+l" "$text_file" + fi + done + else + echo "ERROR: \"$lib\" in \"$lib_dir\" is not a valid library." + fi + done + +else + echo "The client specification \"$client_spec\" does not exist." +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4submit.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4submit.sh new file mode 100755 index 0000000000..5fd0829ebd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4submit.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED + +export LD_LIBRARY_PATH= +function usage() { + echo "Usage: $0 " + echo " [ --client-spec=client_spec_name ]" + echo " [ --change-list=num ]" + exit 2 + +} + + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +arch_bin_dir="$package_root/bin" + +p4_executable=`which p4` + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 + + +client_spec= +change_list= +verbose= +p4_passwd= +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --verbose ) + verbose=t + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=`echo $arg | $sedcmd -e "s/--client-spec=//"` + ;; + --change-list ) + argname="change_list" + ;; + --change-list=* ) + change_list=`echo $arg | $sedcmd -e "s/--change-list=//"` + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=`echo $arg | $sedcmd -e "s/--perforce-password=//"` + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg"; + else + usage + fi + argname= + esac +done + +p4_command="$p4_executable" + +if [ -n "$p4_passwd" ]; then + p4_command="$p4_command -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_command client -o | grep -e "^Client:" | sed -e "s/Client:[[:space:]]\+//"` +fi + +client_spec_exists=`$p4_command clients | \ + $grepcmd -e "^Client[[:space:]]\+$client_spec[[:space:]]*"` +if [ -z "$client_spec_exists" ] ; then +client_spec_exists=`$p4_cmd_with_passwd clients | \ + $grepcmd -e "^\.\.\.[[:space:]]\+client[[:space:]]\+$client_spec[[:space:]]*\$"` +fi + +if [ -n "$client_spec_exists" ] ; then + + + p4_command="$p4_command -c $client_spec" + p4_submit_command="$p4_command submit" + + if [ -n "$change_list" ] ; then + p4_submit_command="$p4_submit_command -c $change_list" + fi + + $p4_submit_command + +else + echo "The client specification \"$client_spec\" does not exist." +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4sync.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4sync.sh new file mode 100755 index 0000000000..353ded19ec --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/cdsp4sync.sh @@ -0,0 +1,306 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +# UPDATED 2 + +function usage() { + echo "Usage: $0 " + echo " --dfII-dir=dir" + echo " --force" + echo " [ --client-spec=client_spec_name ]" + echo " [ --perforce-password=xxx ]" + echo " [ --perforce-port=xxx ]" + echo " [ --perforce-server=xxx ]" + echo " [ --perforce-user=user_name ]" + echo " [ --rev=rev-spec]" + echo " [ --view-name=view_name ]" + echo " [ --verbose ]" + echo " [ --fast ]" + echo " [ --nosync ]" + echo " [ cell1 [ cell2 [ ... ] ] ]" + exit 2 +} + +verbose= +fast= +oa=1 + +function message() { + if [ -n "$verbose" ]; then + echo "$@" + fi +} + + +temp_cds_lib_generated= + +function exit_func() { + if [ -e "$temp_cds_lib_generated" ]; then + /bin/rm -f "$temp_cds_lib_generated"; + fi +} + +trap exit_func EXIT; + +# assumes run under fulcrum script +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +p4_executable=`which p4` +sh_lib_dir="$package_root/share/script/sh/sh-lib" +if [ ! -r "$sh_lib_dir" -o ! -d "$sh_lib_dir" ]; then + echo "Script Library: \"$sh_lib_dir\" is not a readable directory." + exit 2 +fi + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +check_executable_file "$p4_executable" "p4: \"$p4_executable\" is not an exectable file." 2 + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +findcmd=`which find` + +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 +check_executable_file "$findcmd" "Can't find find in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d` + +for file in $cds_sh_lib_files ; do + source "$file" +done + +client_spec= +rev= +dfII_dir= +cell_list= +view_name= +change_list= +p4_user= +p4_passwd= +p4_server_host=ssl:p4proxy07.devtools.intel.com +p4_server_port=2510 +sync_force= +nosync= +argname= + +for arg in $@ ; do + + case "$arg" in + --* ) + argname= + ;; + esac + case "$arg" in + --nosync ) + nosync=1 + ;; + --fast ) + fast=1 + ;; + --verbose ) + verbose=t + ;; + --force ) + sync_force="-f" + ;; + --client-spec ) + argname="client_spec" + ;; + --client-spec=* ) + client_spec=`echo $arg | $sedcmd -e "s/--client-spec=//"` + ;; + --dfII-dir ) + argname="dfII_dir" + ;; + --dfII-dir=* ) + dfII_dir=`echo $arg | $sedcmd -e "s/--dfII-dir=//"` + ;; + --view-name ) + argname="view_name" + ;; + --view-name=* ) + view_name=`echo $arg | $sedcmd -e "s/--view-name=//"` + ;; + --rev ) + argname="rev" + ;; + --rev=* ) + rev=`echo $arg | $sedcmd -e "s/--rev=//"` + ;; + --perforce-user ) + argname="p4_user" + ;; + --perforce-user=* ) + p4_user=`echo $arg | $sedcmd -e "s/--perforce-user=//"` + ;; + --perforce-password ) + argname="p4_passwd" + ;; + --perforce-password=* ) + p4_passwd=`echo $arg | $sedcmd -e "s/--perforce-password=//"` + ;; + --perforce-server ) + argname="p4_server_host" + ;; + --perforce-server=* ) + p4_server_host=`echo $arg | $sedcmd -e "s/--perforce-server=//"` + ;; + --perforce-port ) + argname="p4_server_port" + ;; + --perforce-port=* ) + p4_server_port=`echo $arg | $sedcmd -e "s/--perforce-port=//"` + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + if [ -n "$argname" ]; then + eval "$argname=$arg"; + else + cell_list="$cell_list $arg" + fi + argname= + ;; + esac +done + +check_for_empty_arg "$dfII_dir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$p4_server_host" \ + "You must specify a perforce server." 2 +check_for_empty_arg "$p4_server_port" \ + "You must specify a perforce server port." 2 + + +mkdir -p "$dfII_dir" # because you may not have done p4 sync yet! +check_writeable_dir "$dfII_dir" \ + "dfII directory: \"$dfII_dir\" is not a readable, writeable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +# cd into dfII dir so AltRoots work +cd "$dfII_dir" +if [ -e "OA" ]; then oa=1; fi + +p4_executable="$p4_executable -p $p4_server_host:$p4_server_port"; +p4_cmd="$p4_executable" + +if [ -n "$p4_user" ] ; then + p4_cmd="$p4_cmd -u $p4_user" +fi + +if [ -n "$p4_passwd" ] ; then + p4_cmd="$p4_cmd -P $p4_passwd" +fi + +if [ -z "$client_spec" ] ; then + client_spec=`$p4_cmd client -o |\ + $gawkcmd '/^Client:/ {print $2}'` +fi +message "client_spec $client_spec" + +qu='"' +dl='$' +client_spec_exists=`$p4_cmd clients | \ + $gawkcmd "${dl}2 == \"${client_spec}\" {print ${dl}2}"` +message "client_spec_exists $client_spec_exists" + +if [ -n "$client_spec_exists" ] ; then + + p4_command="$p4_cmd -c $client_spec" + + p4_sync_command="$p4_command sync $sync_force" + + if [ -n "$cell_list" ] ; then + + cadence_escape_string "$view_name" + escaped_view="$ret" + + for rawcell in $cell_list ; do + bad_cell_name=`echo $rawcell | $grepcmd -e "#"` + if [ -z "$bad_cell_name" ] ; then + + atstr=`echo $rawcell | $grepcmd -e "@" | $sedcmd -e "s/^.\+@//"` + cell=`echo $rawcell | $sedcmd -e "s/@.*\$//"` + + get_escaped_cell_dir "$cell" "$dfII_dir" + celltargetdir="$ret" + + if [ -n "$celltargetdir" ] ; then + + curr_dir_to_sync="$celltargetdir" + + if [ -n "$view_name" ] ; then + curr_dir_to_sync="$curr_dir_to_sync/$escaped_view" + fi + + curr_dir_to_sync=`echo "$curr_dir_to_sync" | sed -e 's/#/%23/g'` + curr_p4_sync_command="$p4_sync_command $curr_dir_to_sync/..." + if [ -n "$verbose" ]; then + echo "$curr_p4_sync_command" 1>&2 + fi + + if [ -n "$atstr" ] ; then + curr_p4_sync_command="${curr_p4_sync_command}@${atstr}" + fi + + $curr_p4_sync_command + else + echo "\"$cell\" is not a valid cell name." + fi + else + echo "\"$rawcell\" is not a valid cell name." + fi + done + elif [ -z "$nosync" ]; then + $p4_sync_command //..."$rev" + fi + + if [ -n "$fast" ]; then + # this can save a LOT of time, but has to be maintained if someone changes lib names to have uppercase first letter + all_cds_info_files=`$findcmd $dfII_dir -follow \\( -name '*#*' -o -name '[A-Z]*' -o -name layout -o -name floorplan -o -name abstract -o -name custom_tag -o -name b8\*_mem\* \\) -type d -prune -o \\( -type f -name cdsinfo.tag -print \\)` + else + all_cds_info_files=`$findcmd $dfII_dir -follow -type f -name "cdsinfo.tag"` + fi + + lib_dirs= + + for cds_info in $all_cds_info_files ; do + cds_info_dir=`dirname $cds_info` + lib_dirs="$lib_dirs $cds_info_dir" + done + + cds_lib_generated="$dfII_dir/cds.lib.generated" + + temp_cds_lib_generated=`mktemp "$dfII_dir/cds.lib.generated.XXXXXX"` + rm -f "$temp_cds_lib_generated" + + escapedDFIIDir=`echo "$dfII_dir" | $sedcmd -e "s/\//\\\\\\\\\\//g"` + for libdir in $lib_dirs ; do + get_lib_name_for_dir "$libdir" "$dfII_dir" + libname="$ret" + if [ -n "$libname" ] ; then + cadence_escape_string "$libname" + escaped_lib_name="$ret" + relativeLibDir=`echo "$libdir" | $sedcmd -e "s/$escapedDFIIDir\///g"` + echo "DEFINE $escaped_lib_name $relativeLibDir" >>$temp_cds_lib_generated + fi + done + /bin/mv -f "$temp_cds_lib_generated" "$cds_lib_generated" + +else + echo "The client specification \"$client_spec\" does not exist." +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/change_list_template.txt b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/change_list_template.txt new file mode 100644 index 0000000000..6d0068e925 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/change_list_template.txt @@ -0,0 +1,26 @@ +# A Perforce Change Specification. +# +# Change: The change number. 'new' on a new changelist. Read-only. +# Date: The date this specification was last modified. Read-only. +# Client: The client on which the changelist was created. Read-only. +# User: The user who created the changelist. Read-only. +# Status: Either 'pending' or 'submitted'. Read-only. +# Description: Comments about the changelist. Required. +# Jobs: What opened jobs are to be closed by this changelist. +# You may delete jobs from this list. (New changelists only.) +# Files: What opened files from the default changelist are to be added +# to this changelist. You may delete files from this list. +# (New changelists only.) + +Change: new + +Client: $clientspec$ + +User: $user$ + +Status: new + +Description: + $description$ + +Files: diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/gen_branch_spec.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/gen_branch_spec.sh new file mode 100755 index 0000000000..657bb7f7e8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/p4/gen_branch_spec.sh @@ -0,0 +1,156 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + + +function exit_func() { + if [ -n "$libnamesfile" ] ; then + rm -f "$libnamesfile" + fi + /bin/true +} + +trap exit_func EXIT + +function usage() { + echo "Usage: $0 " + echo " [ --depot-dfII-dir=dir ]" + echo " [ --depot-spec-dir=dir ]" + echo " --src-branch=branchname" + echo " --dest-branch=branchname" + echo " [ --cell-list=file ]" + echo " [ cell [ cell [ cell ... ] ] ]" +} + + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +sortcmd=`which sort` +uniqcmd=`which uniq` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Can't find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Can't find grep in \"$PATH\"." 2 +check_executable_file "$sortcmd" "Can't find sort in \"$PATH\"." 2 +check_executable_file "$uniqcmd" "Can't find uniq in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`find "$cds_sh_lib" \! -type d ` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +depot_dfII_dir= +depot_spec_dir= +src_branch= +dest_branch= +cell_list_file= +suppress_spec= +suppress_dfII= +cells_list= + + +for arg in $@ ; do + + case "$arg" in + --depot-dfII-dir=* ) + depot_dfII_dir=`echo $arg | $sedcmd -e "s/--depot-dfII-dir=//"` + ;; + --depot-spec-dir=* ) + depot_spec_dir=`echo $arg | $sedcmd -e "s/--depot-spec-dir=//"` + ;; + --src-branch=* ) + src_branch=`echo $arg | $sedcmd -e "s/--src-branch=//"` + ;; + --dest-branch=* ) + dest_branch=`echo $arg | $sedcmd -e "s/--dest-branch=//"` + ;; + --cell-list=* ) + cell_list_file=`echo $arg | $sedcmd -e "s/--cell-list=//"` + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + * ) + cell_list="$cell_list $arg" + ;; + esac +done + + +check_for_empty_arg "$src_branch" \ + "You must specify the name of the source branch." 2 + +check_for_empty_arg "$dest_branch" \ + "You must specify the name of the destination branch." 2 + +if [ -n "$cell_list_file" ] ; then + check_readable_file "$cell_list_file" \ + "cell list file: \"$cell_list_file\" is not a readable file." 2 + cells_in_file=`cat $cell_list_file | $sedcmd -e "s/[[:space:]]*#.*//" | $grepcmd -e "[^[:space:]]"` + cell_list="$cell_list $cells_in_file" +fi + + + +libnamesfile=`mktemp /tmp/gen_branch_spec.XXXXXX` + +for cell in $cell_list ; do + + get_lib_name "$cell" + libname="$ret" + + echo "$libname" >>$libnamesfile + + if [ -n "$depot_dfII_dir" ] ; then + get_dfII_depot_path_for_cell_name "$depot_dfII_dir" "$src_branch" "$cell" + srcDepotPath="$ret" + + get_dfII_depot_path_for_cell_name "$depot_dfII_dir" "$dest_branch" "$cell" + destDepotPath="$ret" + + echo "$srcDepotPath/... $destDepotPath/..." + fi + + if [ -n "$depot_spec_dir" ] ; then + get_spec_depot_path_for_cell_name "$depot_spec_dir" "$src_branch" "$cell" + srcDepotPath="$ret" + + get_spec_depot_path_for_cell_name "$depot_spec_dir" "$dest_branch" "$cell" + destDepotPath="$ret" + + echo "$srcDepotPath $destDepotPath" + fi + +done + +if [ -n "$depot_dfII_dir" ] ; then + uniqlibs=`cat $libnamesfile | $sortcmd | $uniqcmd` + for lib in $uniqlibs ; do + get_depot_path_for_lib_name "$depot_dfII_dir" "$src_branch" "$lib" + srcLibDepotPath="$ret" + + get_depot_path_for_lib_name "$depot_dfII_dir" "$dest_branch" "$lib" + destLibDepotPath="$ret" + + echo "$srcLibDepotPath/prop.xx" "$destLibDepotPath/prop.xx" + echo "$srcLibDepotPath/cdsinfo.tag" "$destLibDepotPath/cdsinfo.tag" + done +fi + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd.package new file mode 100644 index 0000000000..a6ea41cd07 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd.package @@ -0,0 +1,11 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +### the cds_wd package used to cadence working directories that point +### to the correct layout and setup environemnt for users/tools +$arch/bin/mkcdswd.sh mkcdswd.sh 775 p +share/cds_wd_default_template/usermenu/.menu cds_wd_default_template/usermenu/.menu 664 p +share/cds_wd_default_template/autoload/bindkeys cds_wd_default_template/autoload/bindkeys 664 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/assura_tech.lib b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/assura_tech.lib new file mode 100644 index 0000000000..04fab30858 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/assura_tech.lib @@ -0,0 +1 @@ +define TSMC013_TC3 /home/group/cadadmin/technology/TSMC13_micron/assura/TSMC013_TC3 diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/autoload/bindkeys b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/autoload/bindkeys new file mode 100644 index 0000000000..e69de29bb2 diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/display.drf b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/display.drf new file mode 100644 index 0000000000..f1341c23fc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/display.drf @@ -0,0 +1,2106 @@ +drDefineDisplay( +;( DisplayName ) + ( display ) + ( colorplot ) +) +drDefineColor( +;( DisplayName ColorsName Red Green Blue ) + ( display white 255 255 255 ) + ( display yellow 255 255 0 ) + ( display silver 217 230 255 ) + ( display cream 255 255 204 ) + ( display pink 255 191 242 ) + ( display magenta 255 0 255 ) + ( display lime 0 255 0 ) + ( display tan 255 230 191 ) + ( display cyan 0 255 255 ) + ( display cadetBlue 57 191 255 ) + ( display orange 255 128 0 ) + ( display red 255 0 0 ) + ( display purple 153 0 230 ) + ( display green 0 204 102 ) + ( display brown 191 64 38 ) + ( display blue 0 0 255 ) + ( display slate 140 140 166 ) + ( display gold 217 204 0 ) + ( display maroon 230 31 13 ) + ( display violet 94 0 230 ) + ( display forest 38 140 107 ) + ( display chocolate 128 38 38 ) + ( display navy 51 51 153 ) + ( display black 0 0 0 ) + ( display gray 204 204 217 ) + ( display winColor1 166 166 166 ) + ( display winColor2 115 115 115 ) + ( display winColor3 189 204 204 ) + ( display winColor4 204 204 204 ) + ( display winColor5 199 199 199 ) + ( display blinkRed 255 0 0 t ) + ( display blinkYellow 255 255 0 t ) + ( display blinkWhite 255 255 255 t ) + ( display winBack 224 224 224 ) + ( display winFore 128 0 0 ) + ( display winText 51 51 51 ) + ( display lightpink 255 196 209 ) + ( display joy1 0 204 242 ) + ( display volorange 255 164 0 ) + ( display whiteB 255 255 255 t ) + ( display silverB 217 230 255 t ) + ( display pinkB 255 191 242 t ) + ( display yellowB 255 255 0 t ) + ( display orangeB 255 128 0 t ) + ( display redB 255 0 0 t ) + ( display purpleB 153 0 230 t ) + ( display greenB 0 204 102 t ) + ( display brownB 191 64 38 t ) + ( display blueB 0 0 255 t ) + ( display goldB 217 204 0 t ) + ( display winColor5B 199 199 199 t ) +) +drDefineStipple( +;( DisplayName StippleName Bitmap ) + ( display dots ( ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display dots1 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) ) ) + ( display hLine ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) ) ) + ( display vLine ( ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) ) ) + ( display cross ( ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) ) ) + ( display grid ( ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) ) ) + ( display slash ( ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) ) ) + ( display backSlash ( ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) ) ) + ( display hZigZag ( ( 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) ) ) + ( display vZigZag ( ( 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 ) + ( 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 ) + ( 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 ) + ( 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 ) ) ) + ( display hCurb ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display vCurb ( ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) ) ) + ( display brick ( ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) ) ) + ( display dagger ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) ) ) + ( display triangle ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display x ( ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) ) ) + ( display hLine2 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) ) ) + ( display miniHatch ( ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display halfslash ( ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) ) ) + ( display rvZigZag ( ( 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ) + ( 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 ) + ( 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 ) + ( 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ) + ( 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 ) + ( 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 ) + ( 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 ) ) ) + ( display dot1 ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display dot2 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display dot3 ( ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display dot4 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display dot5 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display checker ( ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ) ) ) + ( display viap ( ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) ) ) + ( display metal1S ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 ) ) ) + ( display metal2S ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) ) ) + ( display gnd2S ( ( 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) ) ) + ( display vcc2S ( ( 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) ) ) + ( display vcc1S ( ( 1 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 ) + ( 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 ) + ( 0 0 1 0 0 1 1 0 0 0 1 0 0 1 1 0 ) + ( 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 ) + ( 1 0 0 0 1 0 0 1 1 0 0 0 1 0 0 1 ) + ( 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 ) + ( 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 ) + ( 1 0 0 1 1 0 0 0 1 0 0 1 1 0 0 0 ) + ( 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 ) + ( 0 0 1 0 0 1 1 0 0 0 1 0 0 1 1 0 ) + ( 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 ) + ( 1 0 0 0 1 0 0 1 1 0 0 0 1 0 0 1 ) + ( 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 ) + ( 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 ) ) ) + ( display poly2p ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 ) + ( 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 ) + ( 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display contp ( ( 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 ) + ( 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 ) + ( 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 ) + ( 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 ) + ( 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display pplusp ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display wellp ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display checker1 ( ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) ) ) + ( display checker2 ( ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) + ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) + ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) + ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) + ( 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ) ) ) + ( display invCross ( ( 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) ) ) + ( display wellBp ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display cwellBp ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display capID ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display resID ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 0 1 0 0 1 1 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display diodeID ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 ) + ( 0 0 0 1 1 1 1 0 0 0 1 1 1 1 0 0 ) + ( 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display stipple0 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display stipple1 ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) ) ) + ( display stipple2 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display stipple3 ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) ) ) + ( display medslash ( ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) ) ) + ( display dotsa ( ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( display medbackSlash ( ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) ) ) + ( display dots2 ( ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) +) +drDefineLineStyle( +;( DisplayName LineStyle Size Pattern ) + ( display solid 1 (1 1 1 ) ) + ( display dashed 1 (1 1 1 1 0 0 ) ) + ( display dots 1 (1 0 0 ) ) + ( display dashDot 1 (1 1 1 0 0 1 0 0 ) ) + ( display shortDash 1 (1 1 0 0 ) ) + ( display doubleDash 1 (1 1 1 1 0 0 1 1 0 0 ) ) + ( display hidden 1 (1 0 0 0 ) ) + ( display thickLine 3 (1 1 1 ) ) + ( display thickLine2 2 (1 1 1 ) ) + ( display mLine 2 (1 1 1 ) ) + ( display thickDash 3 (1 1 1 1 0 0 ) ) +) +drDefinePacket( +;( DisplayName PacketName Stipple LineStyle Fill Outline [FillStyle]) + ( display yellowdaggerthickLine2 dagger thickLine2 yellow yellow outlineStipple) + ( display via5 invCross solid yellow yellow outlineStipple) + ( display via3Net blank solid tan tan outline ) + ( display border blank solid tan tan outline ) + ( display winColor5dashed_LB blank dashed winColor5B winColor5B outline ) + ( display graythickLine_L blank thickLine gray gray outline ) + ( display mpol blank solid magenta magenta outline ) + ( display n3v blank thickLine2 gray gray outline ) + ( display via4Net blank solid blue blue outline ) + ( display metal1Bnd blank solid blue blue outline ) + ( display y8 blank solid blue blue outline ) + ( display background solid solid black black solid ) + ( display yellow blank solid yellow yellow outline ) + ( display greendashed_LB blank dashed greenB greenB outline ) + ( display silverdashed_L blank dashed silver silver outline ) + ( display forestXthickLine2 contp thickLine2 magenta magenta outlineStipple) + ( display creamcross_S halfslash solid forest forest outlineStipple) + ( display via4 invCross solid blue blue outlineStipple) + ( display sdi blank solid white white outline ) + ( display y9 blank solid silver silver outline ) + ( display metal3Net blank solid cyan cyan outline ) + ( display magentathickLine2_L blank thickLine2 magenta magenta outline ) + ( display dnwell blank solid tan tan outline ) + ( display metal2Bnd blank solid magenta magenta outline ) + ( display pin solid solid red red solid ) + ( display via7 invCross solid purple silver outlineStipple) + ( display hardFence blank solid red red outline ) + ( display yellowdot4_S metal1S solid green green outlineStipple) + ( display goldstipple3_S stipple3 solid gold gold outlineStipple) + ( display p2v blank solid magenta magenta outline ) + ( display whitecrossdashed cross dashed white white outlineStipple) + ( display slatedot4_S dot4 solid blue blue outlineStipple) + ( display pactive invCross solid orange orange outlineStipple) + ( display designFlow3 solid solid winColor1 winColor1 solid ) + ( display via6 invCross solid lime yellow outlineStipple) + ( display Unrouted1 blank dashed brown brown outline ) + ( display RowLbl blank solid cyan cyan outline ) + ( display edgeLayerPin blank solid yellow yellow outline ) + ( display instance blank solid red red outline ) + ( display whitedot4_S metal1S solid maroon maroon outlineStipple) + ( display blue blank solid blue blue outline ) + ( display nselect pplusp solid green green outlineStipple) + ( display snap blank solid yellow yellow outline ) + ( display pinAnt blank solid red red outline ) + ( display pinkdashed_L blank dashed pink pink outline ) + ( display codep blank solid magenta magenta outline ) + ( display designFlow2 blank solid black black outline ) + ( display forestdot4_S dot4 solid magenta magenta outlineStipple) + ( display cc solid solid black chocolate solid ) + ( display Unrouted2 blank dashed red red outline ) + ( display hilite blank solid white white outline ) + ( display whitedashed_L blank dashed white white outline ) + ( display redthickLine_L blank thickLine red red outline ) + ( display blueX_S X solid blue blue X ) + ( display metal7Slo blank solid blue blue outline ) + ( display metal3Dum blank solid cyan cyan outline ) + ( display designFlow1 solid solid black black solid ) + ( display grid1 blank solid white white outline ) + ( display goldXthickLine2 contp solid green green outlineStipple) + ( display Unrouted3 blank dashed pink pink outline ) + ( display greensolid_S solid solid green green solid ) + ( display cream blank solid cream cream outline ) + ( display metal7Pin X solid gold gold X ) + ( display bjtdummy triangle solid green green outlineStipple) + ( display viaNet blank solid purple black outline ) + ( display select blank solid tan tan outline ) + ( display reddot3_S dot3 solid orange orange outlineStipple) + ( display mw blank shortDash cream cream outline ) + ( display via5Net blank solid yellow yellow outline ) + ( display reddashed_LB blank dashed redB redB outline ) + ( display via3 invCross solid tan tan outlineStipple) + ( display Unrouted4 blank dashed orange orange outline ) + ( display wireLbl solid solid cadetBlue cadetBlue solid ) + ( display bluesolid_S solid solid blue blue solid ) + ( display via6Bnd blank solid yellow yellow outline ) + ( display goldx_S x mLine slate black solid ) + ( display metal5Dum blank solid cadetBlue cadetBlue outline ) + ( display whiteX_SB X solid white whiteB X ) + ( display red blank solid gray winColor1 outline ) + ( display via2 invCross solid cadetBlue cadetBlue outlineStipple) + ( display designFlow7 solid solid forest forest solid ) + ( display align blank solid tan tan outline ) + ( display magentashortDash_L blank shortDash magenta magenta outline ) + ( display golddashed_LB blank dashed goldB goldB outline ) + ( display psub2 X solid white white X ) + ( display Unrouted5 blank dashed green green outline ) + ( display unset blank solid forest forest outline ) + ( display metal8 miniHatch solid gold gold outlineStipple) + ( display designFlow6 solid solid maroon maroon solid ) + ( display esd2dummy dot5 solid orange orange outlineStipple) + ( display tactive dagger thickLine winColor2 winColor1 outlineStipple) + ( display Unrouted6 blank dashed blue blue outline ) + ( display metal6Dum blank solid gold gold outline ) + ( display grayshortDash_L blank shortDash gray gray outline ) + ( display metal7Bnd blank solid gold gold outline ) + ( display resist blank solid cyan cyan outline ) + ( display magenta miniHatch solid yellow yellow outline ) + ( display hotwl X solid orange orange X ) + ( display ref blank hidden red red outline ) + ( display designFlow5 solid solid chocolate chocolate solid ) + ( display Unrouted7 blank dashed purple purple outline ) + ( display CannotoccupyBnd blank solid red red outline ) + ( display greenthickLine2_L blank thickLine2 green green outline ) + ( display vardummy blank dashed navy navy outline ) + ( display metalLab blank solid white white outline ) + ( display nactive invCross solid green green outlineStipple) + ( display limeXthickLine2 contp thickLine2 chocolate chocolate outlineStipple) + ( display designFlow4 solid solid yellow yellow solid ) + ( display softFence blank solid yellow yellow outline ) + ( display winColor5dashed_L blank dashed winColor5 winColor5 outline ) + ( display purpledot2_S dot2 solid purple purple outlineStipple) + ( display orangesolid_S solid solid orange orange solid ) + ( display forestx_S x solid forest forest outlineStipple) + ( display pldummy blank solid pink pink outline ) + ( display greendot3_S dot3 solid green green outlineStipple) + ( display yellowX_S checker1 solid forest cadetBlue outlineStipple) + ( display changedLayerTl1 blank solid yellow yellow outline ) + ( display graythickLine2_L blank thickLine2 gray gray outline ) + ( display prBoundaryLbl blank solid purple purple outline ) + ( display greendashed_L blank dashed green green outline ) + ( display metal3Bnd blank solid cyan cyan outline ) + ( display redsolid_S solid solid red red solid ) + ( display viaBnd blank solid purple black outline ) + ( display active invCross solid green green outlineStipple) + ( display blueXthickLine X thickLine blue blue X ) + ( display via7Bnd blank solid yellow yellow outline ) + ( display changedLayerTl0 blank solid red red outline ) + ( display spike blank solid purple purple outline ) + ( display limestipple0_S stipple0 solid lime lime outlineStipple) + ( display metal3 halfslash solid cyan cyan outlineStipple) + ( display text blank solid white white outline ) + ( display whitex_S x solid white white outlineStipple) + ( display vcdummy dagger dashed pink pink outlineStipple) + ( display hri dot2 solid magenta magenta outlineStipple) + ( display Row blank solid cyan cyan outline ) + ( display purplevLine_S vLine solid purple purple solid ) + ( display pwell slash solid orange orange outlineStipple) + ( display bluedashed_L blank dashed blue blue outline ) + ( display greenX_S X solid green green X ) + ( display esd1dummy dot2 solid white white outlineStipple) + ( display boundary blank dashed red red outline ) + ( display metal2 dots solid magenta magenta outlineStipple) + ( display cyandot4_S backSlash solid cadetBlue cadetBlue outlineStipple) + ( display pad X doubleDash yellow yellow X ) + ( display metal4Net blank solid cream cream outline ) + ( display wire solid solid cadetBlue cadetBlue solid ) + ( display creamthickLine2_L dots1 thickLine2 forest forest stipple ) + ( display metal1 backSlash solid blue blue outlineStipple) + ( display Cannotoccupy X solid red red X ) + ( display GroupLbl blank solid green green outline ) + ( display pinkdaggerdashed dagger dashed pink pink outlineStipple) + ( display psub blank thickLine2 blue blue outline ) + ( display p1r dagger thickLine2 yellow yellow outlineStipple) + ( display axis blank solid white white outline ) + ( display flash blank solid lime lime outline ) + ( display green blank solid green green outline ) + ( display greendot4_S metal1S solid magenta magenta outlineStipple) + ( display wlsp blank solid lime lime outline ) + ( display metal8Slo blank solid blue blue outline ) + ( display edgeLayer blank solid winColor5 winColor5 outline ) + ( display gold blank solid gold gold outline ) + ( display metal1Slo blank solid blue blue outline ) + ( display purpledashed_L blank dashed purple purple outline ) + ( display metal8Pin X solid gold gold X ) + ( display winColor3XthickLine2 contp thickLine2 maroon maroon outlineStipple) + ( display codec blank solid orange orange outline ) + ( display n2v blank shortDash gray gray outline ) + ( display metal7 miniHatch solid green lime outlineStipple) + ( display annotate2 blank solid lime lime outline ) + ( display tansolid_S solid solid tan tan solid ) + ( display via6Net blank solid yellow yellow outline ) + ( display metal1Pin X solid blue blue X ) + ( display whitetriangle_S grid solid violet chocolate solid ) + ( display tanvLine_S vLine mLine green black solid ) + ( display reddashed_L blank dashed red red outline ) + ( display orangedots_S dots solid lime lime outlineStipple) + ( display cdummy dagger dashed pink pink outlineStipple) + ( display tanshortDash_L blank shortDash tan tan outline ) + ( display silversolid_S solid solid silver silver solid ) + ( display golddashed_L blank dashed gold gold outline ) + ( display ntn blank shortDash gray gray outline ) + ( display via invCross solid magenta navy outlineStipple) + ( display p1w dot3 solid green green outlineStipple) + ( display rpo blank solid forest forest outline ) + ( display metal6 halfslash solid gold gold outlineStipple) + ( display annotate3 blank solid cyan cyan outline ) + ( display metal7Dum blank solid gold gold outline ) + ( display deviceAnt blank solid yellow yellow outline ) + ( display winColor2winColor1daggerthickLine dagger solid winColor2 winColor1 outline ) + ( display silverdashed_LB blank dashed silverB silverB outline ) + ( display metal5 metal2S solid cadetBlue cadetBlue outlineStipple) + ( display creamstipple0_S stipple0 solid cream cream outlineStipple) + ( display Unrouted blank dashed winColor5 winColor5 outline ) + ( display stretch blank solid yellow yellow outline ) + ( display limehLine_S hLine solid lime lime outlineStipple) + ( display bluecrossthickLine checker1 solid red red outlineStipple) + ( display metal4 dot4 solid cream cream outlineStipple) + ( display via2Bnd blank solid cadetBlue cadetBlue outline ) + ( display annotate1 blank solid pink pink outline ) + ( display winColor4brickdashDot brick dashDot winColor4 winColor4 outlineStipple) + ( display cyan blank solid cyan cyan outline ) + ( display whiteX_S X solid white white X ) + ( display purplesolid_S solid solid purple purple solid ) + ( display browndashed_L blank dashed brown brown outline ) + ( display Group dots solid green green outlineStipple) + ( display deviceLbl blank solid green green outline ) + ( display magentadots_S dots solid magenta magenta outlineStipple) + ( display annotate6 blank solid silver silver outline ) + ( display Canplace blank solid cyan cyan outline ) + ( display pinksolid_S solid solid pink pink solid ) + ( display redbackSlash_S backSlash solid maroon maroon outlineStipple) + ( display graydot1thickLine dot1 thickLine gray gray outlineStipple) + ( display dpdummy blank solid navy navy outline ) + ( display annotate7 blank solid red red outline ) + ( display yellowsolid_S solid solid yellow yellow solid ) + ( display esd3dummy dot5 solid green green outlineStipple) + ( display metal2Slo blank solid blue blue outline ) + ( display yellowhLine_S invCross solid magenta forest outlineStipple) + ( display redhidden_L stipple0 solid slate slate outlineStipple) + ( display navysolid_S solid solid navy navy solid ) + ( display p3v blank thickLine gray gray outline ) + ( display orange blank solid orange orange outline ) + ( display gray miniHatch solid green green stipple ) + ( display via7Net blank solid yellow yellow outline ) + ( display metal2Pin X solid magenta magenta X ) + ( display annotate4 blank solid yellow yellow outline ) + ( display device1 solid solid green green solid ) + ( display winColor2winColor1crossthickLine cross thickLine winColor2 winColor1 outlineStipple) + ( display tanthickLine2_L blank thickLine2 tan tan outline ) + ( display orangeX_S X solid orange orange X ) + ( display markerWarn X solid blinkYellow blinkYellow X ) + ( display text2 solid solid white white solid ) + ( display rwdummy dagger dashed white white outlineStipple) + ( display designFlow solid solid winColor5 winColor5 solid ) + ( display hilite1 blank solid magenta magenta outline ) + ( display device blank solid green green outline ) + ( display prBoundary blank solid purple purple outline ) + ( display tanXthickLine2 contp thickLine2 navy navy outlineStipple) + ( display metal5Net blank solid cadetBlue cadetBlue outline ) + ( display annotate5 blank solid white white outline ) + ( display redthickLine2_L blank thickLine2 red red outline ) + ( display magentasolid_S solid solid magenta magenta solid ) + ( display metal4Bnd blank solid cream cream outline ) + ( display metal4Slo blank solid blue blue outline ) + ( display text1 blank dashed white white outline ) + ( display ctm4 dot3 solid purple purple outlineStipple) + ( display silver blank solid silver silver outline ) + ( display metal4Pin X solid cream cream X ) + ( display markerErr X solid blinkWhite blinkWhite X ) + ( display slateXthickLine2 contp thickLine2 blue blue outlineStipple) + ( display limedot4_S halfslash solid chocolate chocolate outlineStipple) + ( display lime blank solid lime lime outline ) + ( display unknown blank solid yellow yellow outline ) + ( display magentathickLine_L blank thickLine magenta magenta outline ) + ( display ctm3 dot2 solid purple purple outlineStipple) + ( display metal8Dum blank solid gold gold outline ) + ( display annotate blank solid orange orange outline ) + ( display tanstipple3_S halfslash solid navy violet outlineStipple) + ( display pink blank solid pink pink outline ) + ( display metal6Net blank solid gold gold outline ) + ( display hilite3 blank solid cyan cyan outline ) + ( display winColor3dot3_S dot3 solid maroon maroon outlineStipple) + ( display rpdummy brick dashDot winColor4 winColor4 outlineStipple) + ( display via3Bnd blank solid tan tan outline ) + ( display pinLbl blank solid red red outline ) + ( display device2 blank dashed green green outline ) + ( display grid blank solid slate slate outline ) + ( display yellowshortDash_L blank shortDash yellow yellow outline ) + ( display purple blank solid purple purple outline ) + ( display greendots_S dots solid green green outlineStipple) + ( display excl triangle solid green green outlineStipple) + ( display metal8Net blank solid gold gold outline ) + ( display via4Bnd blank solid blue blue outline ) + ( display yellowX_SB X solid yellow yellowB X ) + ( display ctm2 dot1 solid purple purple outlineStipple) + ( display metal1Net blank solid blue blue outline ) + ( display redXthickLine X thickLine red red X ) + ( display c1 stipple0 solid cream cream outlineStipple) + ( display ccBnd blank solid black black outline ) + ( display hilite2 blank solid tan tan outline ) + ( display annotate8 blank solid tan tan outline ) + ( display magentaX_S X solid magenta magenta X ) + ( display hvnw blank thickLine2 red red outline ) + ( display c2 stipple0 solid lime lime outlineStipple) + ( display hilite5 blank solid lime lime outline ) + ( display goldstipple0_S dots solid green green outlineStipple) + ( display metal3Slo blank solid blue blue outline ) + ( display annotate9 blank solid green green outline ) + ( display orangedashed_L blank dashed orange orange outline ) + ( display metal2Net blank solid magenta magenta outline ) + ( display fulcrum_color05 metal1S solid forest forest outlineStipple) + ( display forest blank solid forest forest outline ) + ( display cyansolid_S solid solid cyan cyan solid ) + ( display cyanX_S X solid cyan cyan X ) + ( display metal3Pin X solid cyan cyan X ) + ( display hilite4 blank solid orange orange outline ) + ( display y0 blank solid yellow yellow outline ) + ( display greencross_S solid solid winColor2 navy solid ) + ( display supply blank solid lime lime outline ) + ( display whitesolid_S solid solid white white solid ) + ( display graysolid_S solid solid gray gray solid ) + ( display fulcrum_color04 metal1S solid chocolate chocolate outlineStipple) + ( display winColor5_B blank solid winColor5B winColor5B outline ) + ( display hilite7 blank solid cream cream outline ) + ( display y1 blank solid red red outline ) + ( display pinkdashed_LB blank dashed pinkB pinkB outline ) + ( display limesolid_S solid solid lime lime solid ) + ( display bluethickLine2_L blank thickLine2 blue blue outline ) + ( display metal5Slo blank solid blue blue outline ) + ( display metal1Dum blank solid blue blue outline ) + ( display defaultPacket blank solid white yellow outline ) + ( display fuse dots solid magenta magenta outlineStipple) + ( display poly checker1 solid red red outlineStipple) + ( display creamXthickLine2 contp solid forest forest outlineStipple) + ( display metal5Pin X solid cadetBlue cadetBlue X ) + ( display via2Net blank solid cadetBlue cadetBlue outline ) + ( display Unrouted8 blank dashed gold gold outline ) + ( display hilite6 blank solid orange orange outline ) + ( display y2 blank solid green green outline ) + ( display purpletriangle_S triangle solid purple purple outlineStipple) + ( display pinkbrick_SN brick _NA_ pink pink stipple ) + ( display greentriangle_S triangle solid green green outlineStipple) + ( display hvpw blank thickLine2 orange orange outline ) + ( display fulcrum_color06 miniHatch solid orange orange stipple ) + ( display metal2Dum blank solid magenta magenta outline ) + ( display nwell slash solid green green outlineStipple) + ( display Unrouted9 backSlash dashed white white outline ) + ( display hilite9 blank solid pink pink outline ) + ( display bluedashed_LB blank dashed blueB blueB outline ) + ( display via5Bnd blank solid yellow yellow outline ) + ( display y3 blank solid magenta magenta outline ) + ( display prBoundaryBnd blank solid cyan cyan outline ) + ( display browndashed_LB blank dashed brownB brownB outline ) + ( display metal8Bnd blank solid gold gold outline ) + ( display fulcrum_color01 metal1S solid cadetBlue cadetBlue outlineStipple) + ( display tan blank solid tan tan outline ) + ( display purpledashed_LB blank dashed purpleB purpleB outline ) + ( display magentadot2_S dot2 solid magenta magenta outlineStipple) + ( display creamslash_S slash mLine navy black solid ) + ( display hilite8 blank solid magenta magenta outline ) + ( display y4 blank solid cyan cyan outline ) + ( display white blank solid white white outline ) + ( display pselect pplusp solid orange orange outlineStipple) + ( display joy1brickdashDot brick dashDot joy1 joy1 outlineStipple) + ( display blacksolid_S solid solid black black solid ) + ( display ccNet blank solid brown brown outline ) + ( display polyPin X solid red red X ) + ( display designFlow9 solid solid white white solid ) + ( display cyanXthickLine2 contp thickLine2 cadetBlue cadetBlue outlineStipple) + ( display metal4Dum blank solid cream cream outline ) + ( display orangedashed_LB blank dashed orangeB orangeB outline ) + ( display creamshortDash_L dots shortDash orange orange stipple ) + ( display metal5Bnd blank solid cadetBlue cadetBlue outline ) + ( display y5 blank solid purple purple outline ) + ( display wlpo blank solid red red outline ) + ( display hiz blank solid orange orange outline ) + ( display drive blank solid blue blue outline ) + ( display wireFlt blank dashed red red outline ) + ( display instanceLbl blank solid gold gold outline ) + ( display fulcrum_color03 metal1S solid navy navy outlineStipple) + ( display navy blank solid navy navy outline ) + ( display designFlow8 solid solid winColor1 winColor1 solid ) + ( display whitedaggerdashed dagger dashed white white outlineStipple) + ( display limeX_S X solid lime lime X ) + ( display flgt blank solid orange orange outline ) + ( display y6 blank solid orange orange outline ) + ( display rmdummy brick dashDot joy1 joy1 outlineStipple) + ( display metal7Net blank solid gold gold outline ) + ( display fulcrum_color02 metal1S solid blue blue outlineStipple) + ( display metal6Bnd blank solid gold gold outline ) + ( display metal6Slo blank solid blue blue outline ) + ( display y7 blank solid gold gold outline ) + ( display limedot3_S dot3 solid lime lime outlineStipple) + ( display metal6Pin X solid gold gold X ) +) +drDefineColor( +;( DisplayName ColorsName Red Green Blue ) + ( colorplot white 255 255 255 ) + ( colorplot yellow 255 255 0 ) + ( colorplot silver 217 230 255 ) + ( colorplot cream 255 255 204 ) + ( colorplot pink 255 191 242 ) + ( colorplot magenta 255 0 255 ) + ( colorplot lime 0 255 0 ) + ( colorplot tan 255 230 191 ) + ( colorplot cyan 0 255 255 ) + ( colorplot cadetBlue 57 191 255 ) + ( colorplot orange 255 128 0 ) + ( colorplot red 255 0 0 ) + ( colorplot purple 153 0 230 ) + ( colorplot green 0 204 102 ) + ( colorplot brown 191 64 38 ) + ( colorplot blue 0 0 255 ) + ( colorplot slate 140 140 166 ) + ( colorplot gold 217 204 0 ) + ( colorplot maroon 230 31 13 ) + ( colorplot violet 94 0 230 ) + ( colorplot forest 38 140 107 ) + ( colorplot chocolate 128 38 38 ) + ( colorplot navy 51 51 153 ) + ( colorplot black 0 0 0 ) + ( colorplot gray 204 204 217 ) + ( colorplot winColor1 166 166 166 ) + ( colorplot winColor2 115 115 115 ) + ( colorplot winColor3 189 204 204 ) + ( colorplot winColor4 204 204 204 ) + ( colorplot winColor5 199 199 199 ) + ( colorplot blinkRed 255 0 0 t ) + ( colorplot blinkYellow 255 255 0 t ) + ( colorplot blinkWhite 255 255 255 t ) + ( colorplot whiteB 255 255 255 t ) + ( colorplot silverB 217 230 255 t ) + ( colorplot pinkB 255 191 242 t ) + ( colorplot yellowB 255 255 0 t ) + ( colorplot orangeB 255 128 0 t ) + ( colorplot redB 255 0 0 t ) + ( colorplot purpleB 153 0 230 t ) + ( colorplot greenB 0 204 102 t ) + ( colorplot brownB 191 64 38 t ) + ( colorplot blueB 0 0 255 t ) + ( colorplot goldB 217 204 0 t ) + ( colorplot winBack 224 224 224 ) + ( colorplot winFore 128 0 0 ) + ( colorplot winText 51 51 51 ) + ( colorplot winColor5B 199 199 199 t ) + ( colorplot joy1 0 204 242 ) +) +drDefineStipple( +;( DisplayName StippleName Bitmap ) + ( colorplot dots ( ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot dots1 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) ) ) + ( colorplot hLine ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) ) ) + ( colorplot vLine ( ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) ) ) + ( colorplot cross ( ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) ) ) + ( colorplot grid ( ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) ) ) + ( colorplot slash ( ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) ) ) + ( colorplot backSlash ( ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) ) ) + ( colorplot hZigZag ( ( 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) ) ) + ( colorplot vZigZag ( ( 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 ) + ( 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 ) + ( 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 ) + ( 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 ) + ( 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 ) + ( 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 ) + ( 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 ) + ( 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 ) ) ) + ( colorplot hCurb ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 ) + ( 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot vCurb ( ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 ) ) ) + ( colorplot brick ( ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) ) ) + ( colorplot dagger ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) ) ) + ( colorplot triangle ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot x ( ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) ) ) + ( colorplot dot1 ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot dot2 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot dot3 ( ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot dot4 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot stipple0 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot stipple1 ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) ) ) + ( colorplot stipple2 ( ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot stipple3 ( ( 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ) ) ) + ( colorplot medslash ( ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) ) ) + ( colorplot dotsa ( ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) + ( colorplot medbackSlash ( ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) + ( 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 ) + ( 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 ) + ( 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 ) + ( 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ) + ( 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 ) + ( 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 ) ) ) + ( colorplot dots2 ( ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) + ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) ) ) +) +drDefineLineStyle( +;( DisplayName LineStyle Size Pattern ) + ( colorplot solid 1 (1 1 1 ) ) + ( colorplot dashed 1 (1 1 1 1 0 0 ) ) + ( colorplot dots 1 (1 0 0 ) ) + ( colorplot dashDot 1 (1 1 1 0 0 1 0 0 ) ) + ( colorplot shortDash 1 (1 1 0 0 ) ) + ( colorplot doubleDash 1 (1 1 1 1 0 0 1 1 0 0 ) ) + ( colorplot hidden 1 (1 0 0 0 ) ) + ( colorplot thickLine 3 (1 1 1 ) ) + ( colorplot thickLine2 2 (1 1 1 ) ) + ( colorplot thickDash 3 (1 1 1 1 0 0 ) ) +) +drDefinePacket( +;( DisplayName PacketName Stipple LineStyle Fill Outline [FillStyle]) + ( colorplot yellowdaggerthickLine2 dagger thickLine2 yellow yellow outlineStipple) + ( colorplot border blank solid tan tan outline ) + ( colorplot y8 blank solid blue blue outline ) + ( colorplot winColor5dashed_LB blank dashed winColor5B winColor5B outline ) + ( colorplot graythickLine_L blank thickLine gray gray outline ) + ( colorplot background solid solid black black solid ) + ( colorplot yellow blank solid yellow yellow outline ) + ( colorplot greendashed_LB blank dashed greenB greenB outline ) + ( colorplot silverdashed_L blank dashed silver silver outline ) + ( colorplot forestXthickLine2 X thickLine2 forest forest X ) + ( colorplot creamcross_S cross solid cream cream outlineStipple) + ( colorplot y9 blank solid silver silver outline ) + ( colorplot pin solid solid red red solid ) + ( colorplot magentathickLine2_L blank thickLine2 magenta magenta outline ) + ( colorplot hardFence blank solid red red outline ) + ( colorplot yellowdot4_S dot4 solid yellow yellow outlineStipple) + ( colorplot goldstipple3_S stipple3 solid gold gold outlineStipple) + ( colorplot whitecrossdashed cross dashed white white outlineStipple) + ( colorplot slatedot4_S dot4 solid slate slate outlineStipple) + ( colorplot designFlow3 solid solid winColor1 winColor1 solid ) + ( colorplot instance blank solid red red outline ) + ( colorplot edgeLayerPin blank solid yellow yellow outline ) + ( colorplot Unrouted1 blank dashed brown brown outline ) + ( colorplot RowLbl blank solid cyan cyan outline ) + ( colorplot whitedot4_S dot4 solid white white outlineStipple) + ( colorplot snap blank solid yellow yellow outline ) + ( colorplot pinAnt blank solid red red outline ) + ( colorplot blue blank solid blue blue outline ) + ( colorplot pinkdashed_L blank dashed pink pink outline ) + ( colorplot designFlow2 blank solid black black outline ) + ( colorplot hilite blank solid white white outline ) + ( colorplot forestdot4_S dot4 solid forest forest outlineStipple) + ( colorplot Unrouted2 blank dashed red red outline ) + ( colorplot whitedashed_L blank dashed white white outline ) + ( colorplot redthickLine_L blank thickLine red red outline ) + ( colorplot grid1 blank solid white white outline ) + ( colorplot designFlow1 solid solid black black solid ) + ( colorplot blueX_S X solid blue blue X ) + ( colorplot goldXthickLine2 X thickLine2 gold gold X ) + ( colorplot Unrouted3 blank dashed pink pink outline ) + ( colorplot greensolid_S solid solid green green solid ) + ( colorplot cream blank solid cream cream outline ) + ( colorplot select blank solid tan tan outline ) + ( colorplot reddot3_S dot3 solid red red outlineStipple) + ( colorplot wireLbl solid solid cadetBlue cadetBlue solid ) + ( colorplot reddashed_LB blank dashed redB redB outline ) + ( colorplot Unrouted4 blank dashed orange orange outline ) + ( colorplot bluesolid_S solid solid blue blue solid ) + ( colorplot goldx_S x solid gold gold outlineStipple) + ( colorplot whiteX_SB X solid white whiteB X ) + ( colorplot red blank solid red red outline ) + ( colorplot designFlow7 solid solid forest forest solid ) + ( colorplot align blank solid tan tan outline ) + ( colorplot unset blank solid forest forest outline ) + ( colorplot magentashortDash_L blank shortDash magenta magenta outline ) + ( colorplot golddashed_LB blank dashed goldB goldB outline ) + ( colorplot Unrouted5 blank dashed green green outline ) + ( colorplot designFlow6 solid solid maroon maroon solid ) + ( colorplot Unrouted6 blank dashed blue blue outline ) + ( colorplot resist blank solid cyan cyan outline ) + ( colorplot grayshortDash_L blank shortDash gray gray outline ) + ( colorplot magenta blank solid magenta magenta outline ) + ( colorplot designFlow5 solid solid chocolate chocolate solid ) + ( colorplot Unrouted7 blank dashed purple purple outline ) + ( colorplot CannotoccupyBnd blank solid red red outline ) + ( colorplot greenthickLine2_L blank thickLine2 green green outline ) + ( colorplot softFence blank solid yellow yellow outline ) + ( colorplot limeXthickLine2 X thickLine2 lime lime X ) + ( colorplot designFlow4 solid solid yellow yellow solid ) + ( colorplot winColor5dashed_L blank dashed winColor5 winColor5 outline ) + ( colorplot purpledot2_S dot2 solid purple purple outlineStipple) + ( colorplot orangesolid_S solid solid orange orange solid ) + ( colorplot forestx_S x solid forest forest outlineStipple) + ( colorplot greendot3_S dot3 solid green green outlineStipple) + ( colorplot yellowX_S X solid yellow yellow X ) + ( colorplot changedLayerTl1 blank solid yellow yellow outline ) + ( colorplot prBoundaryLbl blank solid purple purple outline ) + ( colorplot graythickLine2_L blank thickLine2 gray gray outline ) + ( colorplot greendashed_L blank dashed green green outline ) + ( colorplot redsolid_S solid solid red red solid ) + ( colorplot spike blank solid purple purple outline ) + ( colorplot changedLayerTl0 blank solid red red outline ) + ( colorplot blueXthickLine X thickLine blue blue X ) + ( colorplot limestipple0_S stipple0 solid lime lime outlineStipple) + ( colorplot text blank solid white white outline ) + ( colorplot whitex_S x solid white white outlineStipple) + ( colorplot Row blank solid cyan cyan outline ) + ( colorplot purplevLine_S vLine solid purple purple outlineStipple) + ( colorplot bluedashed_L blank dashed blue blue outline ) + ( colorplot greenX_S X solid green green X ) + ( colorplot wire solid solid cadetBlue cadetBlue solid ) + ( colorplot cyandot4_S dot4 solid cyan cyan outlineStipple) + ( colorplot creamthickLine2_L blank thickLine2 cream cream outline ) + ( colorplot GroupLbl blank solid green green outline ) + ( colorplot Cannotoccupy X solid red red X ) + ( colorplot pinkdaggerdashed dagger dashed pink pink outlineStipple) + ( colorplot axis blank solid white white outline ) + ( colorplot green blank solid green green outline ) + ( colorplot greendot4_S dot4 solid green green outlineStipple) + ( colorplot edgeLayer blank solid winColor5 winColor5 outline ) + ( colorplot gold blank solid gold gold outline ) + ( colorplot purpledashed_L blank dashed purple purple outline ) + ( colorplot winColor3XthickLine2 X thickLine2 winColor3 winColor3 X ) + ( colorplot annotate2 blank solid lime lime outline ) + ( colorplot tansolid_S solid solid tan tan solid ) + ( colorplot whitetriangle_S triangle solid white white outlineStipple) + ( colorplot tanvLine_S vLine solid tan tan outlineStipple) + ( colorplot reddashed_L blank dashed red red outline ) + ( colorplot orangedots_S dots solid orange orange outlineStipple) + ( colorplot tanshortDash_L blank shortDash tan tan outline ) + ( colorplot silversolid_S solid solid silver silver solid ) + ( colorplot golddashed_L blank dashed gold gold outline ) + ( colorplot annotate3 blank solid cyan cyan outline ) + ( colorplot deviceAnt blank solid yellow yellow outline ) + ( colorplot winColor2winColor1daggerthickLine dagger thickLine winColor2 winColor1 outlineStipple) + ( colorplot silverdashed_LB blank dashed silverB silverB outline ) + ( colorplot stretch blank solid yellow yellow outline ) + ( colorplot creamstipple0_S stipple0 solid cream cream outlineStipple) + ( colorplot Unrouted blank dashed winColor5 winColor5 outline ) + ( colorplot limehLine_S hLine solid lime lime outlineStipple) + ( colorplot bluecrossthickLine cross thickLine blue blue outlineStipple) + ( colorplot annotate1 blank solid pink pink outline ) + ( colorplot winColor4brickdashDot brick dashDot winColor4 winColor4 outlineStipple) + ( colorplot cyan blank solid cyan cyan outline ) + ( colorplot whiteX_S X solid white white X ) + ( colorplot purplesolid_S solid solid purple purple solid ) + ( colorplot deviceLbl blank solid green green outline ) + ( colorplot browndashed_L blank dashed brown brown outline ) + ( colorplot Group dots solid green green outlineStipple) + ( colorplot magentadots_S dots solid magenta magenta outlineStipple) + ( colorplot annotate6 blank solid silver silver outline ) + ( colorplot Canplace blank solid cyan cyan outline ) + ( colorplot pinksolid_S solid solid pink pink solid ) + ( colorplot redbackSlash_S backSlash solid red red outlineStipple) + ( colorplot graydot1thickLine dot1 thickLine gray gray outlineStipple) + ( colorplot annotate7 blank solid red red outline ) + ( colorplot yellowsolid_S solid solid yellow yellow solid ) + ( colorplot yellowhLine_S hLine solid yellow yellow outlineStipple) + ( colorplot redhidden_L blank hidden red red outline ) + ( colorplot navysolid_S solid solid navy navy solid ) + ( colorplot orange blank solid orange orange outline ) + ( colorplot gray blank solid gray gray outline ) + ( colorplot device1 solid solid green green solid ) + ( colorplot annotate4 blank solid yellow yellow outline ) + ( colorplot winColor2winColor1crossthickLine cross thickLine winColor2 winColor1 outlineStipple) + ( colorplot tanthickLine2_L blank thickLine2 tan tan outline ) + ( colorplot text2 solid solid white white solid ) + ( colorplot orangeX_S X solid orange orange X ) + ( colorplot markerWarn X solid blinkYellow blinkYellow X ) + ( colorplot prBoundary blank solid purple purple outline ) + ( colorplot hilite1 blank solid magenta magenta outline ) + ( colorplot device blank solid green green outline ) + ( colorplot designFlow solid solid winColor5 winColor5 solid ) + ( colorplot tanXthickLine2 X thickLine2 tan tan X ) + ( colorplot annotate5 blank solid white white outline ) + ( colorplot text1 blank dashed white white outline ) + ( colorplot redthickLine2_L blank thickLine2 red red outline ) + ( colorplot magentasolid_S solid solid magenta magenta solid ) + ( colorplot silver blank solid silver silver outline ) + ( colorplot markerErr X solid blinkWhite blinkWhite X ) + ( colorplot unknown blank solid yellow yellow outline ) + ( colorplot slateXthickLine2 X thickLine2 slate slate X ) + ( colorplot limedot4_S dot4 solid lime lime outlineStipple) + ( colorplot lime blank solid lime lime outline ) + ( colorplot magentathickLine_L blank thickLine magenta magenta outline ) + ( colorplot annotate blank solid orange orange outline ) + ( colorplot tanstipple3_S stipple3 solid tan tan outlineStipple) + ( colorplot pink blank solid pink pink outline ) + ( colorplot hilite3 blank solid cyan cyan outline ) + ( colorplot winColor3dot3_S dot3 solid winColor3 winColor3 outlineStipple) + ( colorplot pinLbl blank solid red red outline ) + ( colorplot grid blank solid slate slate outline ) + ( colorplot device2 blank dashed green green outline ) + ( colorplot yellowshortDash_L blank shortDash yellow yellow outline ) + ( colorplot purple blank solid purple purple outline ) + ( colorplot greendots_S dots solid green green outlineStipple) + ( colorplot yellowX_SB X solid yellow yellowB X ) + ( colorplot redXthickLine X thickLine red red X ) + ( colorplot hilite2 blank solid tan tan outline ) + ( colorplot annotate8 blank solid tan tan outline ) + ( colorplot magentaX_S X solid magenta magenta X ) + ( colorplot hilite5 blank solid lime lime outline ) + ( colorplot goldstipple0_S stipple0 solid gold gold outlineStipple) + ( colorplot annotate9 blank solid green green outline ) + ( colorplot orangedashed_L blank dashed orange orange outline ) + ( colorplot fulcrum_color05 dot4 solid white white outlineStipple) + ( colorplot forest blank solid forest forest outline ) + ( colorplot cyansolid_S solid solid cyan cyan solid ) + ( colorplot cyanX_S X solid cyan cyan X ) + ( colorplot y0 blank solid yellow yellow outline ) + ( colorplot hilite4 blank solid orange orange outline ) + ( colorplot supply blank solid lime lime outline ) + ( colorplot greencross_S cross solid green green outlineStipple) + ( colorplot whitesolid_S solid solid white white solid ) + ( colorplot graysolid_S solid solid gray gray solid ) + ( colorplot fulcrum_color04 dot4 solid white white outlineStipple) + ( colorplot y1 blank solid red red outline ) + ( colorplot winColor5_B blank solid winColor5B winColor5B outline ) + ( colorplot hilite7 blank solid cream cream outline ) + ( colorplot pinkdashed_LB blank dashed pinkB pinkB outline ) + ( colorplot limesolid_S solid solid lime lime solid ) + ( colorplot defaultPacket blank solid white yellow outline ) + ( colorplot bluethickLine2_L blank thickLine2 blue blue outline ) + ( colorplot creamXthickLine2 X thickLine2 cream cream X ) + ( colorplot Unrouted8 blank dashed gold gold outline ) + ( colorplot y2 blank solid green green outline ) + ( colorplot hilite6 blank solid orange orange outline ) + ( colorplot purpletriangle_S triangle solid purple purple outlineStipple) + ( colorplot pinkbrick_SN brick _NA_ pink pink stipple ) + ( colorplot greentriangle_S triangle solid green green outlineStipple) + ( colorplot fulcrum_color06 blank solid magenta magenta outline ) + ( colorplot hilite9 blank solid pink pink outline ) + ( colorplot Unrouted9 blank dashed silver silver outline ) + ( colorplot y3 blank solid magenta magenta outline ) + ( colorplot prBoundaryBnd blank solid cyan cyan outline ) + ( colorplot bluedashed_LB blank dashed blueB blueB outline ) + ( colorplot browndashed_LB blank dashed brownB brownB outline ) + ( colorplot fulcrum_color01 dot4 solid cyan cyan outlineStipple) + ( colorplot tan blank solid tan tan outline ) + ( colorplot purpledashed_LB blank dashed purpleB purpleB outline ) + ( colorplot y4 blank solid cyan cyan outline ) + ( colorplot magentadot2_S dot2 solid magenta magenta outlineStipple) + ( colorplot hilite8 blank solid magenta magenta outline ) + ( colorplot creamslash_S slash solid cream cream outlineStipple) + ( colorplot white blank solid white white outline ) + ( colorplot joy1brickdashDot brick dashDot joy1 joy1 outlineStipple) + ( colorplot designFlow9 solid solid white white solid ) + ( colorplot blacksolid_S solid solid black black solid ) + ( colorplot cyanXthickLine2 X thickLine2 cyan cyan X ) + ( colorplot y5 blank solid purple purple outline ) + ( colorplot orangedashed_LB blank dashed orangeB orangeB outline ) + ( colorplot creamshortDash_L blank shortDash cream cream outline ) + ( colorplot wireFlt blank dashed red red outline ) + ( colorplot instanceLbl blank solid gold gold outline ) + ( colorplot hiz blank solid orange orange outline ) + ( colorplot drive blank solid blue blue outline ) + ( colorplot fulcrum_color03 dot4 solid white white outlineStipple) + ( colorplot navy blank solid navy navy outline ) + ( colorplot designFlow8 solid solid winColor1 winColor1 solid ) + ( colorplot y6 blank solid orange orange outline ) + ( colorplot whitedaggerdashed dagger dashed white white outlineStipple) + ( colorplot limeX_S X solid lime lime X ) + ( colorplot fulcrum_color02 dot4 solid cyan cyan outlineStipple) + ( colorplot y7 blank solid gold gold outline ) + ( colorplot limedot3_S dot3 solid lime lime outlineStipple) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/usermenu/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/usermenu/.menu new file mode 100644 index 0000000000..732b22cbf9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/cds_wd_default_template/usermenu/.menu @@ -0,0 +1 @@ +( list "UserMenu" "UIUserMenu" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/fakelib.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/fakelib.sh new file mode 100755 index 0000000000..add523c878 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/fakelib.sh @@ -0,0 +1,19 @@ +dfII_dir=$1 +fake_dfII_dir=$2 +view=$3 +blank_cell=$4 + +mkdir -p "$fake_dfII_dir" +for file in $(find "$dfII_dir" -maxdepth 1 -type f ) ; do + cp "$file" "$fake_dfII_dir"&>/dev/null +done + +for dir in $(find "$dfII_dir" -type d -name $view -printf "%P\n" ) ; do + [[ -n "$(find "$fake_dfII_dir/$dir" -type f -not -perm -200)" ]] || \ + ( mkdir -p $(dirname "$fake_dfII_dir/$dir" ) && \ + cp -a "$blank_cell" "$fake_dfII_dir/$dir" ) +done + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/lmwait.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/lmwait.pl new file mode 100755 index 0000000000..26cedb390f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/lmwait.pl @@ -0,0 +1,111 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +# Note and Warning: this can still fail due to asynchonous issues since +# there is no locking mechanism to prevent a license being grabbed after +# this program checks the license. + +use strict; +use Getopt::Long; +my $licenses; +my @licenses; +my %licenses; +if ( !defined ($ENV{LM_LICENSE_FILE})) { + $ENV{LM_LICENSE_FILE} = + "/usr/local/flexlm/licenses/license.80e5b6d8.dat". + ":/usr/local/flexlm/licenses/license.0048546B71E0.dat"; +} + +sub usage { + print @_; + print < + --wait : do not ask to wait + --licenses : [required] list of licenses to check + command line : the command to execute when license available +U +exit 1; +} + +sub checklicense { + local (*P); + local ($_); + if ($#licenses == 0) { + open (P, "/usr/local/cadence/bin/ic lmstat -f $licenses[0] |"); + } + else { + open (P, "/usr/local/cadence/bin/ic lmstat -a |"); + } + my $nok=0; + while (

    ) { + chomp; + if (/^Users of /) { + s/:/ /g; + my @f=split; + if ($licenses{$f[2]}) { + $licenses{$f[2]} = 2; + if ($f[5] <= $f[10]) { + $nok = 1; + } + } + } + } + close P; + foreach my $l (keys %licenses) { + if ($licenses{$l} == 1) { + $nok = 2; + print STDERR "License $l not found, possible spelling error."; + } + } + if ($nok == 2) { + die; + } + $nok; +} + +my $noask = 0; +GetOptions ( + "licenses=s" => \$licenses, + "wait" => \$noask, +) or usage 1; + +if (defined ($licenses) ) { + @licenses = split(/[ ,]/, $licenses); +} + +usage $licenses if $#licenses < 0; +foreach my $l (@licenses) { + $licenses{$l}=1; +} + +my $istty = (defined ($ENV{TERM})); +my $user=""; + +$|=1; +my $ex = shift (@ARGV); +if ( ! defined ($ex)) { + usage 3; +} +unshift (@ARGV, $ex); +my $nok = checklicense; +if ($istty and $nok and ! $noask) { + printf "License(s) in use, do you want to wait? "; + my $ans=<>; + if ($ans =~ /^n/i) { + exit 1; + } +} +my $cnt=0; +while ($nok) { + sleep 1; + $nok = checklicense; + if (! $cnt) { + print "Waiting for a license"; + } + $cnt++; +} +$"=" "; +print "running: @ARGV"; +exec @ARGV; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/mkcdswd.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/mkcdswd.sh new file mode 100755 index 0000000000..23e8500112 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/mkcdswd.sh @@ -0,0 +1,292 @@ +#!/bin/bash + +< +Sets up a cadence working directory for tools/users. Files created include: +

    + +
    .cdsinit +
    This is automatically loaded at initialization time by cadence. This is where we: + +
      +
    • Load the autoload.il so we can use all the SKILL +
    • Initialize the menus in the usermenu directory inside your cds working directory +
    • Initialize the Fulcrum menu from the ui package +
    • Read in the cds.config variables for use in ui tools. +
    + +
    cds.lib +
    Binds cadence libraries to the filesystem. mkcdswd just references the cds.lib.generated from . + +
    cds.config +
    Contains bash environment variable syntax key value pairs, specific to the user interface tools, including CAST_PATH,UI_DIRECTORY,TEMP.
    + +
    assura_tech.lib +
    In the same syntax as the cds.lib, references the assura directory in the PDK installation. + +
    + +

    Bindkeys are made available from several sources:

    + + + +DOC + +PATH="/usr/intel/bin:$PATH" + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +function usage() { + cat<"$cds_wd_target/cds.lib" +# Auto-generated - please edit cds.lib.user instead +SOFTINCLUDE $dfII_dir/cds.lib.generated +SOFTINCLUDE \${FULCRUM_PDK_ROOT}/share/Fulcrum/dfII/cds.lib +SOFTINCLUDE cds.lib.user +# Use following line instead to use fake gates/stacks +# SOFTINCLUDE \${FULCRUM_PDK_ROOT}/share/Fulcrum/dfII/cds.lib.fake +EOF +fi +[ -n "$interactive" ] && \ +[ -z "$force" ] && \ +[ -e "$cds_wd_target/cds.lib.old" ] && \ + ! ( diff "$cds_wd_target/cds.lib" "$cds_wd_target/cds.lib.old" ) && \ + echo Original "$cds_wd_target/cds.lib" saved to "$cds_wd_target/cds.lib.old" ... please merge manually + +# .cdsinit +[ -n "$interactive" ] && [ -e "$cds_wd_target/.cdsinit" ] && cp "$cds_wd_target/.cdsinit" "$cds_wd_target/.cdsinit.old" +if [[ !( -e "$cds_wd_target/.cdsinit" ) || \ + ( -n "$interactive" ) || \ + ( -n "$force" ) ]] ; then +rm -f "$cds_wd_target/.cdsinit" +if [ -n "$interactive" ] ; then +cat <"$cds_wd_target/.cdsinit" +; Automatically generated +; Please edit ".cdsinit.user" instead +; They will be automatically loaded +VirtuosoHome = ( getShellEnvVar "VIRTUOSO_HOME" ) +(if VirtuosoHome + ( load ( strcat VirtuosoHome "/share/skill/autoload.il" ) ) + (error "VIRTUOSO_HOME environment variable must be set to the virtuoso-integration package root!") +) +( UIInit ) +SKILL +else +# for non interactive use, do a one off w/ explicit paths +# so we don't have to mess with environment variables +cat <"$cds_wd_target/.cdsinit" +( load "$package_root/share/skill/autoload.il" ) +( load "$fulcrum_pdk_root/share/Fulcrum/pdkinfo.il" ) +SKILL +fi +fi +[ -n "$interactive" ] && \ +[ -z "$force" ] && \ +[ -e "$cds_wd_target/.cdsinit.old" ] && \ + ! ( diff "$cds_wd_target/.cdsinit" "$cds_wd_target/.cdsinit.old" ) && \ + echo Original "$cds_wd_target/.cdsinit" saved to "$cds_wd_target/.cdsinit.old" ... please merge manually + +# .cdsinit.user +if [[ ! ( -e "$cds_wd_target/.cdsinit.user" ) ]] ; then +rm -f "$cds_wd_target/.cdsinit.user" +cat <"$cds_wd_target/.cdsinit.user" +; This file is automatically loaded at startup +; If you want to make a change, put it in here, NOT in .cdsinit +; You can use ( UILoadDir Dir [regular expression] ) +; to load all files in a Directory that match regular expression +( load ( prependInstallPath "samples/local/leBindKeys.il" ) ) +( load ( prependInstallPath "samples/local/lxBindKeys.il" ) ) +SKILL +fi + + +# assura_tech.lib +if [[ ! ( -e "$cds_wd_target/assura_tech.lib" ) || ( -n "$force" ) ]] ; then +rm -f "$cds_wd_target/assura_tech.lib" +cat <"$cds_wd_target/assura_tech.lib" +DEFINE Assura_$technology \${FULCRUM_PDK_ROOT}/share/Fulcrum/assura +EOF +for dir in frc GNDVddShortCheck keepoutCheck fillCheck drc_m2345678 m2-8 offgrid wellnotch powerCheck dummyCheck; do +if [ -d "$fulcrum_pdk_root/share/Fulcrum/drc/$dir" ]; then +echo "DEFINE $dir \${FULCRUM_PDK_ROOT}/share/Fulcrum/drc/$dir" >> "$cds_wd_target/assura_tech.lib" +fi +done +fi + +# cds.config +if [[ ( -n "$interactive" ) && \ + ( ( -n "$force" ) || ! ( -e "$cds_wd_target/cds.config" ) ) ]] ; then +# cds.config +rm -f "$cds_wd_target/cds.config" +cat <"$cds_wd_target/cds.config" +# colon seperated path of menu root directories +UI_DIRECTORY= +# DFII_DIR - dfII directory +DFII_DIR=$dfII_dir +# CAST_PATH - standard colon seperated cast-path +CAST_PATH=$cast_path +# temporary directory used by tools +TEMP=$cds_wd_target/temp +CDL_DIR=$cds_wd_target/cdl +EOF +if [ -n "$p4_client" ] ; then +cat <>"$cds_wd_target/cds.config" +#P4 CLIENT +P4CLIENT=$p4_client +EOC +fi +fi + +# copy their cds_wd template usermenu/autoload +if [ -n "$force" ] ; then + [ -d "$cds_wd_target/usermenu" ] && chmod -R +w "$cds_wd_target/usermenu" + cmd="cp -rf" +else + cmd="cp -ru" +fi + +if [ -d "$user_template_cds_wd" ]; then +[ -r "$user_template_cds_wd/display.drf" ] && /bin/rm -f "$cds_wd_target/display.drf"; +$cmd "$user_template_cds_wd"/* "$cds_wd_target" +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/runincdswd.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/runincdswd.sh new file mode 100755 index 0000000000..1acfb8a169 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/setup/runincdswd.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +function usage() { + echo "usage: $0" + echo " --dfII-dir=dir" + echo " --fulcrum-pdk-root=dir" +} + +function exit_func() { + if [ -d "$tmp_dir" ] ; then + rm -rf "$tmp_dir" + fi +} + +trap exit_func EXIT + +sedcmd=`which sed` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 + +gotcmd= + +dfII_dir= +fulcrum_pdk_root= + +for arg in $@ ; do + case "$arg" in + --dfII-dir=* ) + if [ -z "$gotcmd" ] ; then + dfII_dir=`echo $arg | $sedcmd -e "s/--dfII-dir=//"` + shift + fi + ;; + --fulcrum-pdk-root=* ) + if [ -z "$gotcmd" ] ; then + fulcrum_pdk_root=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + shift + fi + ;; + * ) + gotcmd=1 + ;; + esac +done + +check_for_empty_arg "$package_root" \ + "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$dfII_dir" \ + "The cadence dfII directory was not specified." 2 +check_for_empty_arg "$fulcrum_pdk_root" \ + +check_readable_dir "$fulcrum_pdk_root" \ + "Fulcrum PDK: \"$fulcrum_pdk_root\" is not a readable directory." 2 +conon_path "$fulcrum_pdk_root" +fulcrum_pdk_root="$ret" + +check_readable_dir "$dfII_dir" \ + "DFII dir: \"$dfII_dir\" is not a readable directory." 2 +conon_path "$dfII_dir" +dfII_dir="$ret" + +mkcdswd="$arch_bin_dir/mkcdswd" +check_executable_file "$mkcdswd" "Unable to find mkcdswd in $arch_bin_dir" 2 + +if [ -d "$TEMP" ] ; then + temp="$TEMP" +elif [ -d "$TMP" ] ; then + temp="$TMP" +else + temp="/tmp" +fi + +tmp_dir=$(mktemp -d "$temp/cdswd.XXXXXX") +$mkcdswd --target-dir="$tmp_dir" --dfII-dir="$dfII_dir" --fulcrum-pdk-root="$fulcrum_pdk_root" --force --temp +cd "$tmp_dir" +$@ diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/subtyping/dfII_split_subtypes.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/subtyping/dfII_split_subtypes.sh new file mode 100755 index 0000000000..4118a7bb0c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/subtyping/dfII_split_subtypes.sh @@ -0,0 +1,317 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# Implements a dfII subtype spec, by copying cellviews around with the +# filesystem +# The spec format is just lines of the following format +# SPLIT: fqcn fromsubtype tosubtype+ +# COPY: fromfqcn tofqcn + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +local_working_dir="/tmp" + +function exit_func() { + if [ -n "$cmd_tmp_dir" ] ; then + rm -rf "$cmd_tmp_dir" + fi + if [ -n "$lib_list_file" ] ; then + rm -f "$lib_list_file" + fi + if [ -n "$src_dest_file" ] ; then + rm -f "$src_dest_file" + fi +} + +trap exit_func EXIT + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +function usage() { + echo "Usage: $0 " + echo " --split-spec=file" + echo " --src-dfII-dir=dir" + echo " --dest-dfII-dir=dir" + echo " --fulcrum-pdk-root=dir" + echo " [ --pedantic ]" + echo " [ --verbose ]" + echo " [ --force ]" + echo " [ --views=netlist,floorplan ]" +} + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +sortcmd=`which sort` +uniqcmd=`which uniq` +findcmd=`which find` +bashcmd=`which bash` + +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"." 2 +check_executable_file "$gawkcmd" "Unable to find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Unable to fine grep in \"$PATH\"." 2 +check_executable_file "$sortcmd" "Unable to find sort in \"$PATH\"." 2 +check_executable_file "$uniqcmd" "Unable to find uniq in \"$PATH\"." 2 +check_executable_file "$findcmd" "Unable to find find in \"$PATH\"." 2 +check_executable_file "$bashcmd" "Unable to find bash in \"$PATH\"." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +cds_sh_lib_files=`$findcmd "$cds_sh_lib" \! -type d ` + +for file in $cds_sh_lib_files ; do + source "$file" +done + + +spilt_spec= +src_dfII_dir= +dest_dfII_dir= +pedantic= +verbose= +force= +views=netlist,floorplan +fulcrumPDKRoot= + +for arg in $@ ; do + case "$arg" in + --split-spec=* ) + split_spec=`echo $arg | $sedcmd -e "s/--split-spec=//"` + ;; + --src-dfII-dir=* ) + src_dfII_dir=`echo $arg | $sedcmd -e "s/--src-dfII-dir=//"` + ;; + --dest-dfII-dir=* ) + dest_dfII_dir=`echo $arg | $sedcmd -e "s/--dest-dfII-dir=//"` + ;; + --pedantic ) + pedantic="1" + ;; + --verbose ) + verbose="1" + ;; + --force ) + force="1" + ;; + --views=* ) + views=`echo $arg | $sedcmd -e "s/--views=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrumPDKRoot=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + + +check_for_empty_arg "$split_spec" \ + "You must specify the split specification file." 2 +check_for_empty_arg "$src_dfII_dir" \ + "You must specify the location of directory containing all the existing dfII data." 2 +check_for_empty_arg "$dest_dfII_dir" \ + "You must specify the location of directory containing all the new dfII data." 2 +check_for_empty_arg "$views" \ + "You must specify the views you want copied" 2 +check_for_empty_arg "$fulcrumPDKRoot" \ + "You must specify the location of the fulcrum PDK package installation." 2 + + +check_readable_file "$split_spec" \ + "Split Specification File: \"$split_spec\" is not a readable file." 1 +conon_path "$split_spec" +split_spec="$ret" + + +check_readable_dir "$src_dfII_dir" \ + "Source DFII directory: \"$src_dfII_dir\" is not a readable directory." 1 +conon_path "$src_dfII_dir" +src_dfII_dir="$ret" + +check_readable_dir "$fulcrumPDKRoot" \ + "Fulcrum PDK: \"$fulcrumPDKRoot\" is not a readable directory." 1 +conon_path "$fulcrumPDKRoot" +fulcrumPDKRoot="$ret" + + +if [[ ! ( -d "$dest_dfII_dir" ) ]] ; then + mkdir -p "$dest_dfII_dir" +fi + +check_writeable_dir "$dest_dfII_dir" \ + "Destination DFII directory: \"$dest_dfII_dir\" did not exist and could not be created." 1 +conon_path "$dest_dfII_dir" +dest_dfII_dir="$ret" + + +lib_commands_dir="$package_root/share/script/sh/cell-automation/lib_commands" +templates_dir="$package_root/share/script/sh/cell-automation/templates" + +check_readable_dir "$lib_commands_dir" \ + "commands directory: \"$lib_commands_dir\" is not a directory." 2 + +mkcdslib_source="$lib_commands_dir/mkcdslib" +check_readable_file "$mkcdslib_source" \ + "mkcdslib: \"$mkcdslib_source\" is not a readable file." 2 + +blank_cds_library="$fulcrumPDKRoot/share/Fulcrum/blank-library" +check_readable_dir "$blank_cds_library" \ + "Blank Cadence Library: \"$blank_cds_library\" is not a readable directory." 2 + + +cmd_tmp_dir=`mktemp -d $local_working_dir/dfII_split_subtypes.XXXXXX` +generate_command_script "$cmd_tmp_dir" "$mkcdslib_source" "$sh_lib_dir" "$bashcmd" +mkcdslib="$ret" + +check_executable_file "$mkcdslib" \ + "mkcdslib: \"$mkcdslib\" is not readable, executable file." 2 + + + +src_dest_file=`mktemp $local_working_dir/dfII_split_subtypes.XXXXXX` + +lib_list_file=`mktemp $local_working_dir/dfII_split_subtypes.XXXXXX` + +parsed_views=`echo "$views" | $sedcmd -e "s/,/ /g"` + +( cat $split_spec | \ + $grepcmd -e "^SPLIT" | \ + $gawkcmd -- '{ N=4; while($N != "" ) { print $2 "." $3 "#" $2 "." $N ; N++ } }' & \ + cat $split_spec | \ + $grepcmd -e "^COPY" | \ + $gawkcmd -- '{ N=3; while($N != "" ) { print $2 "#" $N ; N++ } }' ) | \ + $sortcmd | $uniqcmd > $src_dest_file + + +function get_dir_info { + src_cell_subtype=$1 + dest_cell_subtypes="$2" + + for view in $parsed_views ; do + get_cadence_cell_view_dir "$src_cell_subtype" "$view" "$src_dfII_dir" + src_cell_view_dir="$ret" + + if [[ ! ( -r "$src_cell_view_dir" && -d "$src_cell_view_dir" ) ]] ; then + if [ -n "$pedantic" ] ; then + curr_error_str="\"$src_cell_view_dir\" is not a readable directory." + if [ -n "$error_str" ] ; then + error_str="$error_str\n$curr_error_str" + else + error_str="$curr_error_str" + fi + fi + else + for dest_cell_subtype in $dest_cell_subtypes ; do + get_cadence_cell_view_dir "$dest_cell_subtype" "$view" "$dest_dfII_dir" + dest_cell_view_dir="$ret" + + get_lib_name "$dest_cell_subtype" + dest_lib_name="$ret" + echo "$dest_lib_name" >>$lib_list_file + + if [[ -a "$dest_cell_view_dir" ]] ; then + if [[ "$src_cell_view_dir" != "$dest_cell_view_dir" ]] ; then + if [ -n "$force" ] ; then + dirs_to_delete="$dirs_to_delete $dest_cell_view_dir" + else + curr_error_str="\"$dest_cell_view_dir\" exists use --force to overwrite." + if [ -n "$error_str" ] ; then + error_str="$error_str\n$curr_error_str" + else + error_str="$curr_error_str" + fi + fi + fi + else + dest_cell_view_dir_parent=`dirname $dest_cell_view_dir` + if [[ ( ! -d "$dest_cell_view_dir_parent" ) ]] ; then + dirs_to_create="$dirs_to_create $dest_cell_view_dir_parent" + fi + fi + done + fi + done +} + +function copy_cell { + src_cell_subtype=$1 + dest_cell_subtypes="$2" + for view in $parsed_views ; do + get_cadence_cell_view_dir "$src_cell_subtype" "$view" "$src_dfII_dir" + src_cell_view_dir="$ret" + if [[ -r "$src_cell_view_dir" && -d "$src_cell_view_dir" ]] ; then + for dest_cell_subtype in $dest_cell_subtypes ; do + get_cadence_cell_view_dir "$dest_cell_subtype" "$view" "$dest_dfII_dir" + dest_cell_view_dir="$ret" + + if [[ "$src_cell_view_dir" != "$dest_cell_view_dir" ]] ; then + if [ -n "$verbose" ] ; then + echo "Copy \"$src_cell_view_dir\" to \"$dest_cell_view_dir\"." + fi + cp -a "$src_cell_view_dir" "$dest_cell_view_dir" + $findcmd $dest_cell_view_dir | xargs chmod u+w + fi + done + fi + done +} + +for src_dest in $(<$src_dest_file) ; do + get_dir_info $(echo $src_dest | $sedcmd -e "y/#/ /" ) +done + +if [ -z "$error_str" ] ; then + lib_list=`cat $lib_list_file | $sortcmd | $uniqcmd` + for lib in $lib_list ; do + if [ -n "$verbose" ] ; then + echo "Ensuring that library \"$lib\" exists." + fi + $mkcdslib "--cds-wd=$dest_dfII_dir" \ + "--generated-libraries-root=$dest_dfII_dir" \ + "--lib=$lib" \ + "--blank-cds-library=$blank_cds_library" \ + "--cadence-shell-library=$cds_sh_lib" + done +fi + +dirs_to_create=$(echo $dirs_to_create | $sortcmd | $uniqcmd ) +dirs_to_delete=$(echo $dirs_to_delete | $sortcmd | $uniqcmd ) + +if [ -z "$error_str" ] ; then + if [ -n "$dirs_to_delete" ] ; then + for dir_to_delete in $dirs_to_delete ; do + if [ -n "$verbose" ] ; then + echo "Delete \"$dir_to_delete\"." + fi + rm -r "$dir_to_delete" + done + fi + + if [ -n "$dirs_to_create" ] ; then + for dir_to_create in $dirs_to_create ; do + if [ -n "$verbose" ] ; then + echo "Create \"$dir_to_create\"." + fi + mkdir -p "$dir_to_create" + done + fi + + if [ -z "$error_str" ] ; then + for src_dest in $(<$src_dest_file) ; do + copy_cell $(echo $src_dest | $sedcmd -e "y/#/ /" ) + done + else + echo -e "$error_str" + fi +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/findclosestwithlayout.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/findclosestwithlayout.sh new file mode 100755 index 0000000000..180e205156 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/findclosestwithlayout.sh @@ -0,0 +1,177 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" +build_id="$buildid$" + + + + +function exit_func() { + if [ -n "$subtypesListFile" ] ; then + rm -f "$subtypesListFile" + fi + if [ -n "$netlistDistanceOutputFile" ] ; then + rm -f "$netlistDistanceOutputFile" + fi + + +} + +trap exit_func EXIT + + + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + + + +function usage() { + echo "Usage: $0 " + echo " --cell=cell" + echo " --dfII-dir=dir" + echo " --cast-path=castpath" + echo " [ --verbose ]" + echo " [ --debug ]" +} + +sedcmd=`which sed` +gawkcmd=`which gawk` +grepcmd=`which grep` +bashcmd=`which bash` +findcmd=`which find` +sortcmd=`which sort` +uniqcmd=`which uniq` + +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"." 2 +check_executable_file "$gawkcmd" "Unable to find gawk in \"$PATH\"." 2 +check_executable_file "$grepcmd" "Unable to fine grep in \"$PATH\"." 2 +check_executable_file "$bashcmd" "Unable to find bash in \"$PATH\"." 2 +check_executable_file "$findcmd" "Unable to find find in \"$PATH\"." 2 +check_executable_file "$sortcmd" "Unable to find sort in \"$PATH\"." 2 +check_executable_file "$uniqcmd" "Unable to find uniq in \"$PATH\"." 2 + +check_readable_dir "$arch_bin_dir" \ + "Package arch bin: \"$arch_bin_dir\" is not a readable directory." 2 + +cds_sh_lib="$package_root/share/script/sh/util" +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 + +cds_sh_lib_files=`$findcmd "$cds_sh_lib" \! -type d` +for file in $cds_sh_lib_files ; do + source "$file" +done + +netlistDistance="$arch_bin_dir/netlistDistance" +check_executable_file "$netlistDistance" "\"$netlistDistance\" is not an executable file." 2 + +layoutViewName="layout" + + +cell= +dfIIDir= +castPath= +verbose= +debug= + + + +for arg in $@ ; do + + case "$arg" in + --cell=* ) + cell=`echo "$arg" | $sedcmd -e "s/--cell=//"` + ;; + --dfII-dir=* ) + dfIIDir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --cast-path=* ) + castPath=`echo "$arg" | $sedcmd -e "s/--cast-path=//"` + ;; + --verbose ) + verbose=1 + ;; + --debug ) + verbose=1 + debug=1 + ;; + --* ) + echo "Unknown argument: \"$arg\"." + usage + exit 2 + ;; + esac +done + +check_for_empty_arg "$cell" \ + "You must specify a cell name." 2 +check_for_empty_arg "$dfIIDir" \ + "You must specify the location of directory containing all the dfII data." 2 +check_for_empty_arg "$castPath" \ + "You must specify a cast path" 2 + +check_readable_dir "$dfIIDir" \ + "DFII Directory: \"$dfIIDir\" is not a readable directory." 1 +conon_path "$dfIIDir" +dfIIDir="$ret" + + +get_cell_name_from_cell_name_with_subtype "$cell" +cellBaseName="$ret" +if [ -n "$verbose" ] ; then + echo "Cell Base Name: \"$cellBaseName\"." +fi + +get_library_dir "$cell" "$dfIIDir" +libDir="$ret" +if [ -n "$verbose" ] ; then + echo "Library Directort: \"$libDir\"." +fi + +cadence_escape_string "$cellBaseName" +escapedCellBaseName="$ret" + +cadence_escape_string "$cell" +escapedCellName="$ret" + +otherSubTypeDirs=`$findcmd "$libDir" -mindepth 1 -maxdepth 1 -type d -name "$escapedCellBaseName#2e*" -not -name "$escapedCellName"` + +otherSubTypesWithLayout= + +for otherSubTypeDir in $otherSubTypeDirs ; do + if [[ -d "$otherSubTypeDir/$layoutViewName" && -r "$otherSubTypeDir/$layoutViewName" ]] ; then + escapedSubTypeName=`basename "$otherSubTypeDir"` + cadence_reverse_escape_string "$escapedSubTypeName" + subTypeName="$ret" + otherSubTypesWithLayout="$otherSubTypesWithLayout $subTypeName" + if [ -n "$verbose" ] ; then + echo "Found $subTypeName with layout." + fi + fi +done + +subtypesListFile=`mktemp /tmp/findclosestwithlayout.XXXXXX` + +for otherSubTypeWithLayout in $otherSubTypesWithLayout ; do + echo "$otherSubTypeWithLayout" >>$subtypesListFile +done + +netlistDistanceOutputFile=`mktemp /tmp/findclosestwithlayout.XXXXXX` + +netlistDistanceCmd="$netlistDistance \"--cast-path=$castPath\" \"--library-cells-file=$subtypesListFile\" \"--cell=$cell\" >$netlistDistanceOutputFile" + +if [ -n "$verbose" ] ; then + echo "$netlistDistanceCmd" +fi + +eval "$netlistDistanceCmd" + +cat "$netlistDistanceOutputFile" | gawk -- "{ print \$2 FS \$3 FS \$1}" | sort -n diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/importPR.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/importPR.sh new file mode 100755 index 0000000000..e83e8452f6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/importPR.sh @@ -0,0 +1,819 @@ +#!/bin/bash +# $Id$ +# $DateTime$ +# $Author$ + +< +
  • cast - tar of the digital cast +
  • spec - tar of the spec cast +
  • dfII - tar of the generated dfII - layout and floorplan + + +Most importantly, we need to get the .cxl name mapping file from the cdl vs. gdsII. This is then passed to cdl2cast, which uses it to make SKILL name tables (used by ) consistent with the cdl and the the bind rul. + +

    This script uses

    +
    +
    com.avlsi.tools.cdl2cast.Cdl2Cast +
    +
    +
    SKILL that implements the name mappings that cdl2cast creates. +
    com.avlsi.tools.cdl2cast.Cast2Cdl +
    To create cdl for optional final lvs checks. +
    +
    To create floorplans. +
    +
    For running lvs/nvn. +
    +DOC + +arch_bin_dir=${0%\/*} +packageRoot=${arch_bin_dir%\/*} + +function exit_func() { + if [ -n "$debug" -o -n "$verbose" ] ; then + exit + fi + if [ -d "$tempDir" ] ; then + rm -rf "$tempDir" + fi +} + +trap exit_func EXIT + +function usage() { + cat </dev/null +dfIIDir=$tempDir/dfII +mkdir -p $dfIIDir 2>/dev/null +if [ -n "$verbose" ]; then + echo DFII $dfIIDir +fi + +makeStreamInWDCmd="$mkcdswd \"--target-dir=$streamInWD\"" +makeStreamInWDCmd="$makeStreamInWDCmd \"--dfII-dir=$dfIIDir\"" +makeStreamInWDCmd="$makeStreamInWDCmd \"--fulcrum-pdk-root=$pdkRoot\"" +makeStreamInWDCmd="$makeStreamInWDCmd \"--force\"" +makeStreamInWDCmd="$makeStreamInWDCmd \"--temp\"" + +if [ -n "$verbose" ] ; then + echo "$makeStreamInWDCmd" +fi + +eval "$makeStreamInWDCmd" +makeStreamInWDRet=$? + +if [[ "$makeStreamInWDRet" != "0" ]] ; then + echo "mkcdswd FAILED" 1>&2 + exit "$makeStreamInWDRet" +fi + +# we just create an empty directory +mkdir -p "$streamInWD/STREAMIN" + +echo "DEFINE STREAMIN $streamInWD/STREAMIN" >>$streamInWD/cds.lib +mkdir -p $streamInWD/$defaultOutputLibName +cdslibname=`echo $defaultOutputLibName | sed -e 's/\./#2e/g'`; +echo "DEFINE $cdslibname $streamInWD/$defaultOutputLibName" >> $streamInWD/cds.lib + +strminConfig=$tempDir/strmin.cfg +strminWD=$tempDir/streamInWD +mkdir -p $strminWD 2>/dev/null + +echo "stick 0 0.1" > $strminWD/textFontTable.txt + +if [[ $all_cells == 1 ]] ; then + $sedcmd \ + -e "s=STRMINLAYERMAP=$streamInLayerMap =" \ + -e "s=LIBRARY=STREAMIN=" \ + -e "s=STRMINTECH==" \ + -e "s=STRMINATTACH=tsmc28=" \ + -e "s=STRMINLOG=StrmIn.log=" \ + -e "s=STRMINGDS=$gdsIIFile=" \ + -e "s=STRMINTECHOUT=/dev/null=" \ + -e "s=STRMINTOPCELL==" \ + -e "s=STRMINVIEW=layout=" \ + -e 's=textFontTable.*""=textFontTable\t"textFontTable.txt"=' \ + $streamInTemplate|grep -v topCell >$strminConfig +else + $sedcmd \ + -e "s=STRMINLAYERMAP=$streamInLayerMap =" \ + -e "s=LIBRARY=$defaultOutputLibName=" \ + -e "s=STRMINTECH==" \ + -e "s=STRMINLOG=/dev/null=" \ + -e "s=STRMINGDS=$gdsIIFile=" \ + -e "s=STRMINTECHOUT=/dev/null=" \ + -e "s=STRMINTOPCELL=$cell=" \ + -e "s=STRMINVIEW=layout=" \ + -e 's=textFontTable.*""=textFontTable\t"textFontTable.txt"=' \ + $streamInTemplate >$strminConfig +fi + +strminOutput=$tempDir/strmin.out + +strminCmd="strmin" +strminCmd="$strminCmd -templateFile \"$strminConfig\"" +strminCmd="$strminCmd &>$strminOutput" + +if [ -n "$verbose" ] ; then + echo "$strminCmd" +fi + +pushd "$streamInWD" >/dev/null +eval "$strminCmd" +strminRet=$? +popd >/dev/null + +if [[ "$strminRet" != "0" ]] ; then + echo "strmin FAILED!!!" 1>&2 + cat $strminOutput 1>&2 + exit "$strminRet" +fi + + + +############ Run post-stream in SKILL ############## + +postStreamInRPFile= +postStreamInLog= +if [ -n "$postStreamInIL" ] ; then + postStreamInRPFile=$tempDir/streamIn.rpt + postStreamInLog=$tempDir/streamIn.log + if [ -n "$debug" ] ; then + echo "( ilDebugToolBox )" >>$postStreamInRPFile + fi + echo "( load \"$skillAutoLoad\" )" >>$postStreamInRPFile + echo "( load \"$pdkInfoIL\" )" >>$postStreamInRPFile + echo "( load \"$postStreamInIL\" )" >>$postStreamInRPFile + echo "( ImportPRPostStreamIn \"STREAMIN\" \"$cell\" \"layout\" )" >>$postStreamInRPFile + if [ -z "$debug" ] ; then + echo "( exit )" >>$postStreamInRPFile + fi + + postStreamInCmd="layout" + postStreamInCmd="$postStreamInCmd -replay \"$postStreamInRPFile\"" + postStreamInCmd="$postStreamInCmd -log \"$postStreamInLog\"" + if [ -z "$debug" ] ; then + postStreamInCmd="$postStreamInCmd -nograph" + fi + postStreamInCmd="$postStreamInCmd /dev/null" + if [ -n "$verbose" ] ; then + echo "$postStreamInCmd" + fi + pushd "$streamInWD" >/dev/null + echo "$postStreamInCmd" 1>&2 + eval "$postStreamInCmd" + popd >/dev/null +fi + +############ Run cdl2cast ############## + +layoutToCDLBindRul=/dev/null +cdlToLayoutBindRul=$tempDir/cdl2layoutbind.rul +if [ ! -s "$cdlToLayoutBindRul" ]; then + touch "$cdlToLayoutBindRul" + for cell in `awk '/^\.subckt/i {print $2}' $cdlFiles`; do + echo "C $cell $library.$cell.$subType" >> "$cdlToLayoutBindRul" + done +fi + +specTreeDir=$tempDir/specTreeDir +mkdir -p $specTreeDir 2>/dev/null +castTreeDir=$tempDir/castTreeDir +mkdir -p $castTreeDir 2>/dev/null +skillDir=$tempDir/skill +mkdir -p $skillDir 2>/dev/null +finalCastCellList=$tempDir/finalCastCellList.txt + +cdl2castCmd="$cdl2cast --max-heap-size=$maxHeapSize" +cdl2castCmd="$cdl2castCmd \"--cdl-file=$convertedCDLFile\"" +cdl2castCmd="$cdl2castCmd \"--output-spec=$specTreeDir\"" +cdl2castCmd="$cdl2castCmd \"--output-cast=$castTreeDir\"" +cdl2castCmd="$cdl2castCmd \"--name-table-dir=$skillDir\"" +cdl2castCmd="$cdl2castCmd \"--vdd-node=$vddNode\"" +cdl2castCmd="$cdl2castCmd \"--gnd-node=$gndNode\"" +cdl2castCmd="$cdl2castCmd \"--refinement-parent=$refinementParent\"" +if [ -n "$defaultOutputLibName" ] ; then + cdl2castCmd="$cdl2castCmd \"--lib-name=$defaultOutputLibName\"" +fi +if [ -n "$subType" ] ; then + cdl2castCmd="$cdl2castCmd \"--sub-type=$subType\"" +fi +cdl2castCmd="$cdl2castCmd \"--meters-per-input-unit=$metersPerInputUnit\"" +cdl2castCmd="$cdl2castCmd \"--layout-to-cdl-bind-rul=$layoutToCDLBindRul\"" +cdl2castCmd="$cdl2castCmd \"--output-cdl-to-layout-bind-rul=$cdlToLayoutBindRul\"" +cdl2castCmd="$cdl2castCmd \"--output-cast-cells=$finalCastCellList\"" +cdl2castCmd="$cdl2castCmd \"--bind-rul-header=$lvsBindingRules\"" +cdl2castCmd="$cdl2castCmd \"--bind-rul-in=$bindRul\"" + + +if [ -n "$verbose" ] ; then + echo "$cdl2castCmd" +fi +eval "$cdl2castCmd" +cdl2castRet=$? + +if [[ "$cdl2castRet" != "0" ]] ; then + echo "cdl2cast FAILED" 1>&2 + exit "$cdl2castRet" +fi + +for file in `find "$tempDir" -name '*.cast'` ; do + sed -e 's/, GND, Vdd//' "$file" > "$tempDir/tcast" + mv "$tempDir/tcast" "$file" +done + +############ Munge the dfII names to what cdl2cast says ############## + +if [ 1 ]; then + pushd "$streamInWD/STREAMIN" 2>/dev/null + for dir in *; do + if [ -d $dir ]; then + mv "$dir" "${cdslibname}#2e${dir}#2e$subType"; + fi + done + libdir=`echo "$defaultOutputLibName" | sed -e 's:\.:/:g'` + libdir="$dfIIDir/$libdir/$defaultOutputLibName" + mkdir -p "$libdir" 2>/dev/null + mv "$streamInWD/STREAMIN/"/* "$libdir" + popd 2>/dev/null +else +importRPFile=$tempDir/importRPFile + +if [ -n "$debug" ] ; then + echo "( ilDebugToolBox )" >>$importRPFile +fi +echo "( load \"$skillAutoLoad\" )" >>$importRPFile +echo "( load \"$pdkInfoIL\" )" >>$importRPFile + +echo "( GDSIIHierCopyAndMungeLibraryForImportUsingPDKInfo" >>$importRPFile +echo " \"$skillDir\"" >>$importRPFile +echo " \"$dfIIDir\"" >>$importRPFile +echo " \"STREAMIN\"" >>$importRPFile +echo " ( ListApplyFuncToListAndAccumulateResults" >>$importRPFile +echo " ( getq ( ddGetObj \"STREAMIN\" ) cells )" >>$importRPFile +echo " (lambda" >>$importRPFile +echo " ( CellDDObj )" >>$importRPFile +echo " ( list" >>$importRPFile +echo " ( getq CellDDObj name )" >>$importRPFile +echo " ( sprintf" >>$importRPFile +echo " nil" >>$importRPFile +echo " \"$defaultOutputLibName.%s.$subType\"" >>$importRPFile +echo " ( getq CellDDObj name ) ) ) )" >>$importRPFile +echo " nil ) )" >>$importRPFile + +if [ -n "$postImportIL" ] ; then + echo "( load \"$postImportIL\" )" >>$importRPFile + echo "( ImportPRPostImport " >>$importRPFile + echo " \"$skillDir\"" >>$importRPFile + echo " \"$dfIIDir\"" >>$importRPFile + echo " \"STREAMIN\"" >>$importRPFile + echo " \"$cell\" " >>$importRPFile + echo " \"layout\" )" >>$importRPFile +fi + +importLog=$tempDir/import.log + +importCmd="layout" +importCmd="$importCmd -replay \"$importRPFile\"" +importCmd="$importCmd -log \"$importLog\"" +if [ -z "$debug" ] ; then + importCmd="$importCmd -nograph" +fi +importCmd="$importCmd /dev/null" + +if [ -n "$verbose" ] ; then + echo "$importCmd" +fi + +pushd "$streamInWD" >/dev/null +eval "$importCmd" +popd >/dev/null +fi + + +############ Get final names ############## + +finalCastCell=$(head -1 $finalCastCellList) +finalLayoutCell=$(grep "^C $cell .*" "$cdlToLayoutBindRul" | $awkcmd '{print $3}') +get_lib_name "$finalLayoutCell" +finalLayoutLib="$ret" + + +doUpdateNetlist= +if [ $doUpdateNetlist ]; then +############ Create floorplan views with updatenetlist ############# + +updatenetlistCadenceLog=$tempDir/CDS.log +updatenetlistCmd="$updatenetlist --java-max-heap-size=$maxHeapSize" +updatenetlistCmd="$updatenetlistCmd \"--dfII-dir=$dfIIDir\"" +updatenetlistCmd="$updatenetlistCmd \"--cast-path=$castTreeDir:$specTreeDir:$standardCastDir\"" +if [[ $all_cells == 1 ]] ; then + #tell updatenetlist to do each cell + updatenetlistCmd="$updatenetlistCmd \"--cell-list=$finalCastCellList\"" +else + updatenetlistCmd="$updatenetlistCmd \"--cell=$defaultOutputLibName.$cell\"" +fi +updatenetlistCmd="$updatenetlistCmd \"--subtype=$subType\"" +updatenetlistCmd="$updatenetlistCmd \"--suppress-pins\"" +updatenetlistCmd="$updatenetlistCmd \"--suppress-netlist-view\"" +updatenetlistCmd="$updatenetlistCmd \"--lock-layout\"" +updatenetlistCmd="$updatenetlistCmd \"--update-views\"" +updatenetlistCmd="$updatenetlistCmd \"--fulcrum-pdk-root=$pdkRoot\"" +updatenetlistCmd="$updatenetlistCmd \"--cadence-log=$updatenetlistCadenceLog\"" +if [ -n $verbose ]; then +updatenetlistCmd="$updatenetlistCmd \"--verbose\"" +fi + +if [ -n "$verbose" ] ; then + echo "$updatenetlistCmd" +fi + +eval "$updatenetlistCmd" +status=$? + +if [[ "$status" != "0" ]] ; then + echo "updatenetlist FAILED" 1>&2 + exit "$status" +fi + +fi + +if [[ (( -n "$assuraVerilogCheckRunTarFile" ) || \ + ( -n "$assuraCheckRunTarFile" )) && + ( $all_cells == 1 ) ]] ; then + + finalCDLFile=$tempDir/cell.cdl_final + + cast2cdlCmd="$cast2cdl --max-heap-size=$maxHeapSize" +# cast2cdlCmd="$cast2cdlCmd \"--cdl-file=$finalCDLFile\"" + cast2cdlCmd="$cast2cdlCmd \"--cdl-file=av28m_hvt_lvs.sp.mod\"" + cast2cdlCmd="$cast2cdlCmd \"--cell=$finalCastCell\"" + cast2cdlCmd="$cast2cdlCmd \"--cast-path=$castTreeDir:$standardCastDir:$specTreeDir\"" + cast2cdlCmd="$cast2cdlCmd \"--output=$finalCDLFile\"" + + if [ -n "$verbose" ] ; then + echo "$cast2cdlCmd" + fi + + eval "$cast2cdlCmd" + status=$? + + if [[ "$status" != "0" ]] ; then + echo "cast2cdl failed" + exit "$status" + fi + + # Optionally LVS the final cdl against the original verilog + if [ -n "$assuraVerilogCheckRunTarFile" ] ; then + lvsRunDir=$tempDir/lvsRunDir + mkdir -p $lvsRunDir 2>/dev/null + lvsOutput=$tempDir/lvs.out + + lvsCmd="$vfeCmd" + lvsCmd="$lvsCmd \"VerificationType=AssuraNvn\"" + lvsCmd="$lvsCmd \"AssuraRsfInclude=$lvsRSFInclude\"" + lvsCmd="$lvsCmd \"CompareFile=$lvsCompareRules\"" + lvsCmd="$lvsCmd \"BindingFile=$cdlToLayoutBindRul\"" + lvsCmd="$lvsCmd \"RunName=lvs\"" + lvsCmd="$lvsCmd \"LayoutFile.=$finalCDLFile:cdl\"" + for verilogFile in $verilogFiles ; do + lvsCmd="$lvsCmd \"SchematicFile.=$verilogFile:verilog\"" + done + for cdlFile in $cdlFiles ; do + lvsCmd="$lvsCmd \"SchematicFile.=$cdlFile:cdl\"" + done + lvsCmd="$lvsCmd \"WorkingDir=$lvsRunDir\"" + lvsCmd="$lvsCmd &>$lvsOutput" + + if [ -n "$verbose" ] ; then + echo "$lvsCmd" + fi + + eval "$lvsCmd" + lvsRet=$? + + if [[ "$lvsRet" != "0" ]] ; then + echo "ve FAILED" 1>&2 + cat "$lvsOutput" + exit "$lvsRet" + fi + + lvsPass=`$grepcmd -e "^PASS:" $lvsOutput` + + if [[ "$lvsPass" != "PASS:" ]] ; then + echo "verilog-layout lvs FAILED" 1>&2 + exit 1 + fi + + $tarcmd -cjf "$assuraVerilogCheckRunTarFile" -C "$lvsRunDir" . + fi + + # Optionally LVS the final layout against the final cdl + if [ -n "$assuraCheckRunTarFile" ] ; then + + lvsRunDir=$tempDir/lvsRunDir2 + mkdir -p $lvsRunDir 2>/dev/null + lvsOutput=$tempDir/lvsOutput.out + + lvsCmd="$vfeCmd" + lvsCmd="$lvsCmd \"VerificationType=AssuraLvs\"" + lvsCmd="$lvsCmd \"AssuraRsfInclude=$lvsRSFInclude\"" + lvsCmd="$lvsCmd \"CdsLib=$streamInWD/cds.lib\"" + lvsCmd="$lvsCmd \"LayoutCell=$finalLayoutCell\"" + lvsCmd="$lvsCmd \"LayoutLibrary=$finalLayoutLib\"" + lvsCmd="$lvsCmd \"LayoutView=layout\"" + lvsCmd="$lvsCmd \"RuleFile=$lvsExtractRules\"" + lvsCmd="$lvsCmd \"CompareFile=$lvsCompareRules\"" + lvsCmd="$lvsCmd \"BindingFile=$lvsBindingRules\"" + lvsCmd="$lvsCmd \"RunName=lvs\"" + lvsCmd="$lvsCmd \"SchematicFile=$finalCDLFile:cdl\"" + lvsCmd="$lvsCmd \"WorkingDir=$lvsRunDir\"" + lvsCmd="$lvsCmd &>$lvsOutput" + + if [ -n "$verbose" ] ; then + echo "$lvsCmd" + fi + + eval "$lvsCmd" + lvsRet=$? + + if [[ "$lvsRet" != "0" ]] ; then + echo "ve FAILED" 1>&2 + cat "$lvsOutput" + exit "$lvsRet" + fi + + lvsPass=`$grepcmd -e "^PASS:" $lvsOutput` + + if [[ "$lvsPass" != "PASS:" ]] ; then + echo "verilog-layout lvs FAILED" 1>&2 + exit 1 + fi + + $tarcmd -cjf "$assuraCheckRunTarFile" -C "$lvsRunDir" . + fi +fi + +fixPortCmd="fixportdirection --libfile=$libFile --search-dir=$tempDir" +if [ -n "$verbose" ] ; then + echo "$fixPortCmd" +fi +eval "$fixPortCmd" + +castTarCmd="$tarcmd -cjf \"$castFile\"" +castTarCmd="$castTarCmd -C \"$castTreeDir\" ." + +if [ -n "$verbose" ] ; then + echo "$castTarCmd" +fi + +eval "$castTarCmd" + +specTarCmd="$tarcmd -cjf \"$specFile\"" +specTarCmd="$specTarCmd -C \"$specTreeDir\" ." + +if [ -n "$verbose" ] ; then + echo "$specTarCmd" +fi + +eval "$specTarCmd" + +echo DFII $dfIIDir +dfIITarCmd="$tarcmd -cjf \"$dfIIFile\"" +dfIITarCmd="$dfIITarCmd -C \"$dfIIDir\" ." + +if [ -n "$verbose" ] ; then + echo "$dfIITarCmd" +fi + +eval "$dfIITarCmd" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mk_instance b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mk_instance new file mode 100755 index 0000000000..8651254ff1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mk_instance @@ -0,0 +1,116 @@ +#!/bin/bash + +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +input= +log=$(mktemp "$PWD/mkinstances_log.XXXXXX") +function exit_func() { + [ -f "$input" ] && rm -f "$input" +} + +trap exit_func EXIT + + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" +source "$sh_lib_dir/file/filecheck.sh" + +if [ -z "$CADENCE_WRAPPER_SCRIPT" ] ; then + CADENCE_WRAPPER_SCRIPT="/usr/local/cadence/bin/ic" +fi +# override from FULCRUM script if appropriate +if [ -n "$IC_SCRIPT" ] ; then + CADENCE_WRAPPER_SCRIPT=$IC_SCRIPT +fi + +function usage() { + cat << USAGE +Usage: $0 + [--lib= (defaults to lib in cell name)] + --cell= + [ --view= (defaults to $view) ] + [ --outdir= (defaults to $outdir) ] + --fulcrum-pdk-root= +USAGE +} + +sedcmd=`which sed` +mkdircmd=`which mkdir` +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$mkdircmd" "Unable to find mkdir in \"$PATH\"" 2 + +view="layout" +outdir="." +lib= +logremove=1 + +for arg in "$@"; do + case "$arg" in + --cadence-log=*) + rm "$log" + log=`echo "$arg" | "$sedcmd" -e "s/--cadence-log=//"` + logremove=0 + ;; + --lib=*) + library=`echo "$arg" | "$sedcmd" -e "s/--lib=//"` + ;; + --cell=*) + cell=`echo "$arg" | "$sedcmd" -e "s/--cell=//"` + ;; + --view=*) + view=`echo "$arg" | "$sedcmd" -e "s/--view=//"` + ;; + --outdir=*) + outdir=`echo "$arg" | "$sedcmd" -e "s/--outdir=//"` + ;; + --fulcrum-pdk-root=*) + pdkroot=`echo "$arg" | "$sedcmd" -e "s/--fulcrum-pdk-root=//"` + ;; + *) + ;; + esac +done + +if [ -z "$library" ] ; then + source "$package_root/share/script/sh/util/parsecellname" + get_lib_name "$cell" + library="$ret" +fi + +check_for_empty_arg "$package_root" "The packageroot variable must contain the location of the package installation." 2 +check_for_empty_arg "$library" "You must specify the Cadence library of the cell." 2 +check_for_empty_arg "$cell" "You must specify the name of the cell." 2 +check_for_empty_arg "$pdkroot" "You must specify the location of the Fulcrum PDK you want to use." 2 +check_readable_dir "$pdkroot" "PDK: \"$pdkroot\" is not a readable directory." 2 + + +[ -d $outdir ] || $mkdircmd -p $outdir + +check_writeable_dir "$outdir" "Output directory: \"$outdir\" is not writeable." 1 + +if cadence_cell=`echo "$cell" | "$arch_bin_dir/rename" --type=cell --from=cast --to=cadence`; then + cell="$cadence_cell" +else + echo "Cannot get convert CAST cell name $cell to Cadence name" + exit 2 +fi + +input=$(mktemp "$PWD/mkinstances.XXXXXX") +cat<< EOF > "$input" +(load "$package_root/share/skill/autoload.il") +(load "$pdkroot/share/Fulcrum/pdkinfo.il") +(WriteInstancesFile "$outdir" (dbOpenCellViewByType "$library" "$cell" "$view") ?LibCellPairRegExsToExclude \`(,@WiringCellLibCellPairRegExs ,@GateLibCellPairRegExs ,@ChainLibCellPairRegExs ,@SuperStackLibCellPairRegExs (,( strcat "^" TechLibName "$" ) ".*" ) ) ) +(exit) +EOF + +DISPLAY= $CADENCE_WRAPPER_SCRIPT layout -nograph -replay "$input" -log "$log" /dev/null +ret=$? +[ $ret == 0 ] || cat "$log" 1>&2 +if [ -f "$log" -a $logremove == 1 ]; then + rm "$log" +fi +exit $ret diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mkcdslib b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mkcdslib new file mode 100755 index 0000000000..dd85c82c9e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mkcdslib @@ -0,0 +1,179 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/script/sh/cell-automation/lib_commands/mkcdslib#7 $ +# $DateTime: 2005/01/13 19:31:07 $ +# $Author: abe $ + +PATH="/usr/intel/bin:$PATH" + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" +source "$sh_lib_dir/script/generate_script_with_libs.sh" + +function usage() { + echo Usage: `basename $0` --cds-wd=dir --generated-libraries-root=dir + echo " --blank-cds-library=dir --lib=libname" + echo " --cadence-shell-library=dir" + echo " --dfII-fir=dir" +} + +sedcmd=`which sed` +grepcmd=`which grep` +gawkcmd=`which gawk` +findcmd=`which find` + +source "$package_root/share/script/sh/util/parsecellname" + +check_executable_file "$sedcmd" "Unable to find sed in \"$PATH\"" 2 +check_executable_file "$grepcmd" "Unable to find grep in \"$PATH\"" 2 +check_executable_file "$gawkcmd" "Unable to find gawk in \"$PATH\"" 2 +check_executable_file "$findcmd" "Unable to find find in \"$PATH\"" 2 + +cds_wd= +generated_libs_root= +blank_cds_library= +lib= +cds_sh_lib= + +for arg in $@ ; do + + case "$arg" in + --cds-wd=* ) + cds_wd=`echo $arg | $sedcmd -e "s/--cds-wd=//"` + ;; + --generated-libraries-root=* ) + generated_libs_root=`echo $arg | $sedcmd -e "s/--generated-libraries-root=//"` + ;; + --blank-cds-library=* ) + blank_cds_library=`echo $arg | $sedcmd -e "s/--blank-cds-library=//"` + ;; + --lib=* ) + lib=`echo $arg | $sedcmd -e "s/--lib=//"` + ;; + --cadence-shell-library=* ) + cds_sh_lib=`echo $arg | $sedcmd -e "s/--cadence-shell-library=//"` + ;; + --dfII-dir=* ) + dfII_dir=`echo $arg | $sedcmd -e "s/--dfII-dir=//"` + ;; + esac +done + + +check_for_empty_arg "$cds_wd" "You must specify the cadence working directory." 2 +check_for_empty_arg "$generated_libs_root" "A generated libraries root directory was not specified." 2 +check_for_empty_arg "$blank_cds_library" "A directory containing a blank cadence library was not specified." 2 +check_for_empty_arg "$lib" "\"$cell\"'s library was not specified." 2 +check_for_empty_arg "$cds_sh_lib" "You must specify the location of the cadence shell script library." 2 + +check_writeable_dir "$cds_wd" "Cadence Working Directory: \"$cds_wd\" is not a readable, writeable directory." 2 +conon_path "$cds_wd" +cds_wd="$ret" + +check_writeable_dir "$generated_libs_root" \ + "Generated Libraries Root Directory: \"$generated_libs_root\" is not a readable, writeable directory." 2 +conon_path "$generated_libs_root" +generated_libs_root="$ret" + +check_readable_dir "$blank_cds_library" \ + "Blank Cadence Library: \"$blank_cds_library\" is not a readable directory." 2 +conon_path "$blank_cds_library" +blank_cds_library="$ret" + +check_readable_dir "$cds_sh_lib" \ + "Cadence Shell Script Library: \"$cds_sh_lib\" is not a readable directory." 2 +conon_path "$cds_sh_lib" +cds_sh_lib="$ret" + +cds_sh_lib_files=`$findcmd "$cds_sh_lib" \! -type d` +for file in $cds_sh_lib_files ; do + source "$file" +done + +get_escaped_library_name_for_library "$lib" +escaped_lib_name="$ret" + +cds_lib_generated="$generated_libs_root/cds.lib.generated" + +lib_exists_already= +if [ -f "$cds_lib_generated" ] ; then + existing_cds_lib_libs=`$grepcmd -ve "--" $cds_lib_generated | $grepcmd -e "^DEFINE" | $gawkcmd -- "{ print \\\$2 }"` + for existing_lib in $existing_cds_lib_libs ; do + if [[ "$escaped_lib_name" == "$existing_lib" ]] ; then + lib_exists_already=1 + fi + done +fi + +cds_lib="$cds_wd/cds.lib" + +if [ -f "$cds_lib" ] ; then + existing_cds_lib_libs=`$grepcmd -ve "--" $cds_lib | $grepcmd -e "^DEFINE" | $gawkcmd -- "{ print \\\$2 }"` + for existing_lib in $existing_cds_lib_libs ; do + if [[ "$escaped_lib_name" == "$existing_lib" ]] ; then + lib_exists_already=1 + fi + done +fi + +if [ -z "$lib_exists_already" ] ; then + get_library_dir_for_libraray "$lib" "$generated_libs_root" + newlibdir="$ret" + + escaped_generated_libs_root=`echo "$generated_libs_root" | $sedcmd -e "s/\//\\\\\\\\\\//g"` + + relative_new_lib_dir=`echo "$newlibdir" | $sedcmd -e "s/$escaped_generated_libs_root\///g"` + + cds_lib_entry="DEFINE $escaped_lib_name $relative_new_lib_dir" + + if [ ! -d "$newlibdir" ] ; then + libparentdir=`dirname $newlibdir` + if [ ! -d "$libparentdir" ]; then + mkdir -p "$libparentdir" + fi + cp -a "$blank_cds_library" "$newlibdir" + $findcmd "$newlibdir" -print0 | xargs -0 chmod u+w + else + dirs_in_blank=`(cd "$blank_cds_library" ; $findcmd . -type d)` + files_in_blank=`(cd "$blank_cds_library" ; $findcmd . -type f)` + for dir in $dirs_in_blank ; do + dir=`echo "$dir" | $sedcmd -e "s:^./:$newlibdir/:"` + if [ ! -d "$dir" ]; then + mkdir -p "$dir" + chmod u+w "$dir" + fi + done + for file in $files_in_blank ; do + nfile=`echo "$file" | $sedcmd -e "s:^./:$newlibdir/:"` + file=`echo "$file" | $sedcmd -e "s:^./:$blank_cds_library/:"` + if [ ! -f "$nfile" ]; then + cp -p "$file" "$nfile" + chmod u+w "$nfile" + fi + done + fi + + echo "$cds_lib_entry" >>$cds_lib_generated + +fi + +cds_lib_generated_base=`basename $cds_lib_generated` + +cds_lib_tmp=`mktemp /tmp/ensurecelllib.XXXXXX` +if [ -n "$dfII_dir" ] ; then + dfII_cds_generated="$dfII_dir/cds.lib.generated" + echo "SOFTINCLUDE $dfII_cds_generated" > $cds_lib_tmp + echo "UNDEFINE gate" >> $cds_lib_tmp + echo "UNDEFINE stack" >> $cds_lib_tmp +fi +if [ -f "$cds_lib" ] ; then + cat $cds_lib | \ + $grepcmd -ve "^SOFTINCLUDE[[:space:]]\+.*$cds_lib_generated_base" >>$cds_lib_tmp +fi +echo "SOFTINCLUDE $cds_lib_generated" >>$cds_lib_tmp +cp $cds_lib_tmp $cds_lib +rm $cds_lib_tmp diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mktestcase b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mktestcase new file mode 100755 index 0000000000..5621032574 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/mktestcase @@ -0,0 +1,493 @@ +#!/usr/intel/bin/perl -l +# AAG +# $Id$ +# $DateTime$ + +use Getopt::Long; + +$verbose=0; # generates a lot of output to STDERR +$fulcrum_pdk_root=""; # default pdk root is nowhere +$ui_directory=""; # default ui_directory is nowhere +$autoload_directory=""; # default autoload_directory is nowhere +$config=""; # default config is nowhere +$temp=""; # default temp is nowhere +$home=$ENV{HOME}; # home is where your home directory is +$home =~ s:^/mnt/fulcrum/home:/home:; # get rid of /mnt/fulcrum from path +$target = ""; # default place to put results +$changedconfig=1; # checks to see if config file values were changed +$pwd=$ENV{PWD}; +$pwd =~ s:^/mnt/fulcrum/home:/home:; + +GetOptions( + "v|verbose" => \$verbose, + "fulcrum_pdk_root=s" => \$fulcrum_pdk_root, + "ui_directory=s" => \$ui_directory, + "autoload_directory=s" => \$autoload_directory, + "config=s" => \$config, + "temp=s" => \$temp, + "target=s" => \$target, + "h|help" => \$help, +); + +if ($help) { + print STDERR < : the pdk root to use (will get from cds.config too) + --ui_directory= : the ui directory (gets package root from this) + and gets this from cds.config as well. + --autoload_directory= : normally gets from cds.config + --config= : this is the cds config file from cds.config + --temp= : the temp file also from cds.config + --target= : the target directory of the test case + --help : this help + +Files: + cds.confg : reads PDK and PKG from this + strace.out : reads the list of files needed from this + testcase.config : reads mktestcase configuration from this +EF + exit 1; +} + +# createpath +# this creates a set of directories along the specified path +# it is needed to make sure that a place exists to place a file +# later + +sub createpath { + my ($path)=@_; + my @dirs=split(/\//,$path); + if ( ! -d $path && $verbose) { + print STDERR "Creating $path"; + } + $path=""; + for (my $n = 0; $n <= $#dirs; $n++) { + if ($dirs[$n] eq "") { next;} + $path .= "/$dirs[$n]"; + if (index ($path,$target) == 0 && ! -d $path ) { + mkdir $path || die "Cannot create $path"; + } + } +} + +# simple query returns true for a yes or y response +# and false for a no or n. Typing q quits and it +# allows for defaults. +sub query { + my ($string, $default)=@_; + my $ans = 'x'; + $default =~ tr/A-Z/a-z/; + while (! ($ans =~ /^[yn]/)) { + printf STDERR "$string [y|n|q] "; + $ans=<>; + chomp $ans; + $ans =~ tr/A-Z/a-z/; + if ($ans =~ /^q/) { + exit (1); + } + if ($ans eq "" && defined ($default)) { + $ans = $default; + } + } + ($ans =~ /^y/); +} + +# sometimes a directory contains /../ in it's path. +# this replaces /../ with the next level up directory. +sub fixdotdot { + my ($file)=@_; + while ($file =~ /\/\.\.\//) { + my @dirs=split(/\//,$file); + $file="/"; + for (my $n = 0; $n < $#dirs; $n++) { + if ($n == 0 && $dirs[0] eq "") { next;} + if ($dirs[$n] eq "..") { + $file =~ s/$dirs[$n-1]\/$//; + next; + } + $file .= "$dirs[$n]/"; + } + $file .= $dirs[$#dirs]; + } + $file; +} + +# read the testcase config file. Helps in rerunning the script +# there are only two keywords at present: +# TARGETHOME which is $target above, and +# TARGET which has two args, the source and the target +# user can override while running +if (open (P, ") { + chomp; + s/ */ /; + s/[ \t]+$//; + @f=split; + for ($i=$pndx=$ndx=0; $ndx >= 0; ) { + $pndx++; + $ndx = index (substr($_,$pndx),"'"); + if ($ndx >= 0) { + $i++; + } + $pndx += $ndx; + } + if ($i % 2) { + die "Syntax error in testcase.config, unbalanced \"'\""; + } + if (substr($f[1],0,1) eq "'") { + @g = split (/'/, $_); + $f[1] = $g[1]; + if ($g[2] =~ /[ \t]+/ && defined ($g[3])) { + # we have a second set of "'" + $f[2] = $g[3]; + } + } + elsif (substr($f[2],0,1) eq "'") { + @g=split(/'/,$_); + $f[2] = $g[1]; + } + if (/^TARGETHOME /) { + $target=$f[1]; + } + elsif (/^TARGET /) { + $target{$f[1]}=$f[2]; + } + elsif (/^EXCLUDE /) { + push (@exclude, $f[1]); + } + } + $changedconfig=0; + foreach $src (keys %target) { + if ( ! ($target{$src} =~ /^\//) ) { + $target{$src} = "$target/$target{$src}"; + $target{$src} =~ s/\/\//\//g; + } + } +} +# check the above and correct interactively if not found +if ($target eq "") { + $ok = 0; + while (!$ok) { + printf STDERR "Target: "; + $target = <>; + chomp $target; + if ( ! ( $target =~ /^\//)) { + $target = "$home/$target"; + } + if (index ($target,$pwd) == 0) { + printf STDERR "Do not put target under current directory!"; + } + else { + $ok = 1; + } + } +} +# if there is a cds.config file, we get the pdk, +# temp, autoload and ui directories here. We ignore +# the P4 entries +# also, do not override the command line options! +open (P, ") { + chomp; + @f=split(/=/, $_); + @g=split(/:/, $f[1]); + if (/^P4/) { next;} + if ($f[0] eq "FULCRUM_PDK_ROOT" && $fulcrum_pdk_root eq "") { + $fulcrum_pdk_root=$g[0]; + $configdirs{$g[0]}=1; + } + elsif ($f[0] eq "config" && $config eq "") { + $config=$g[0]; + } + elsif ($f[0] eq "TEMP" && $temp eq "") { + $temp=$g[0]; + $configdirs{$g[0]}=1; + } + for ($n = 0; $n <= $#g; $n++) { + if ( -d $g[$n] || -f $g[$n]) { + $config{$f[0]}[$n]=$g[$n]; + if ($f[0] eq "UI_DIRECTORY" && ! ($g[$n] =~ /\/user\//) && $ui_directory eq "" ) { + $ui_directory=$g[$n]; + $configdirs{$g[0]}=1; + } + if ($f[0] eq "AUTOLOAD_DIRECTORY" && ! ($g[$n] =~ /\/user\//) && $autoload_directory eq "") { + $autoload_directory=$g[$n]; + $configdirs{$g[0]}=1; + } + } + else { + print STDERR "cds.config: File/Direcctory not found f[0]=$g[$n]"; + } + } +} +if (! -d $fulcrum_pdk_root ) { + die "fulcrum_pdk_root is not a directory: $fulcrum_pdk_root"; +} +$configdirs{$fulcrum_pdk_root}=1; +if (! -d $ui_directory ) { + die "ui_directory is not a directory: $ui_directory"; +} +$configdirs{$ui_directory}=1; +if (! -d $autoload_directory ) { + die "autoload_directory is not a directory: $autoload_directory"; +} +$configdirs{$autoload_directory}=1; +if (! -d $temp ) { + die "temp is not a directory: $temp"; +} +$configdirs{$temp}=1; +if (! -f $config ) { + die "config is not a file: $config"; +} +# Now we open the strace.out file which contains the +# files opened during the run. +open (P, ") { + chomp; + if (/open\("/) { # only the lines with open(" in them are appropriate + @f=split(/"/,$_); # look at the string between the quotes + $_=$f[1]; # use the default string to simplify the lookup + $file=$_; + # First, the file/directory must exist! + # second, it should not be a system file like .so files, files in /etc/ + # files in /var files in /usr files in /proc files in /tmp and /dev + if ((-f $_ || -d $_ ) && ! ( /\.so\./ || /\.so"/ || /^\/etc\// || /^\/var\// || /^\/dev\// || /^\/usr\// || /^\/proc\// || /^\/tmp\//)) { + $file =~ s:^/mnt/fulcrum/home:/home:; + $file = fixdotdot($file); + $_ = $file; + if ($file =~ /^\./) { + $file =~ s/^\.//; + $file = "$pwd/$file"; + } + $dir=$file; + if ( -f $file) { + $dir =~ s/\/[^\/]*$/\//; + $dir =~ s/\/+/\//g; + } + #ignore cadence install + if (! ($file =~ /^\/home\/local\/common\//)) { + if (-d $dir) { + if ($dir =~ /^\./) { + print STDERR "$dir : $file"; + } + $dirs{$dir}=1; + } + $files{$file}=1; + } + } + } +} +# now start the writing +if ( -d $target ) { + if (query ("Remove $target?") ) { + system ("chmod -R +w $target"); + system ("rm -rf $target"); + ( -r $target ) && die "did not remove $target"; + mkdir ($target) || die "Cannot create $target"; + } +} +else { + mkdir ($target) || die "Cannot create $target"; +} +$found = 0; +foreach $tgt (keys %target) { + if (index ($tgt, $fulcrum_pdk_root) == 0 && $tgt ne $fulcrum_pdk_root) { + print STDERR "Warning: Userdefined target matches PDK root"; + print STDERR " $tgt"; + print STDERR " $fulcrum_pdk_root"; + $found = 1; + } + if ($tgt eq $fulcrum_pdk_root) { + $found = 1; + } +} +if (! $found ) { + printf STDERR "$fulcrum_pdk_root where? "; + $ans = <>; + chomp $ans; + if (index ($ans, $target)) { + $ans = "$target/$ans"; + $ans =~ s/\/\//\//g; + } + $target{$fulcrum_pdk_root}="$ans"; + $changedconfig=1; +} +$package_home=$ui_directory; +$package_home =~ s/\/share\/skill.*//; +foreach $tgt (keys %target) { + if (index ($tgt, $package_home) == 0 && $tgt ne $package_home) { + print STDERR "Warning: Userdefined target matches PDK root"; + print STDERR " $tgt"; + print STDERR " $package_home"; + $found = 1; + } + if ($tgt eq $package_home) { + $found = 1; + } +} +if (! $found ) { + printf STDERR "$package_home where? "; + $ans = <>; + chomp $ans; + if (index ($ans, $target)) { + $ans = "$target/$ans"; + $ans =~ s/\/\//\//g; + } + $target{$package_home}="$ans"; + $changedconfig=1; +} +# create all of the directoies found in the files +# to be transferred +$lastdir = "xx"; +foreach $dir (sort keys %dirs) { + $dx=$dir.'/'; + $dx =~ s/\/\//\//g; + @dir=split(/\//,$dx); + $found=0; + foreach $tgt (keys %target) { + if (index ($dx,$tgt) == 0) { + $found = 1; + last; + } + } + if (! $found && index ($dx,$lastdir) != 0) { + $redo=1; + if (defined ($target{$dx})) { + my $xx = substr($target{$dx},length($target)+1); + $redo=query("Replace $xx for $dx?"); + } + if ($redo) { + printf STDERR "$dx $dirlist{$dx} where? "; + $ans=<>; + chomp $ans; + $ans = "$target/$ans"; + if (!(-d $ans && -w $ans && $ans ne $dx) ) { + if (query ("Create $ans?")) { + createpath($ans); + } + } + $changedconfig=1; + $target{$dx}=$ans; + } + else { + $ans = $target{$dx}; + createpath($ans); + } + $lastdir = $dx; + } +} +# create a sed command to fixup any text files with +# hard coded paths +$sedcmd = "-e 's:^/mnt/fulcrum/home:/home:g'"; +foreach $dx (reverse sort keys %target) { + $t=$target{$dx}; + $t =~ s/\/$//; + $sedcmp .= " -e 's:$dx:$t:g'"; +} +# all paths are created, start file transfer +foreach $file (sort keys %files) { + $copied=0; + if (-f $file || -d $file) { + foreach $dx (keys %target) { + # the source of target key matches first part of file string + if (index ($file,$dx) == 0) { + $excluded = 0; + # make sure this path is not in the EXCLUDED list + foreach $f (@exclude) { + if (index($file, $f) >= 0) { + $excluded = 1; + last; + } + } + if ($excluded) { + next; + } + # create the target path name + $tgt = $target{$dx}.'/'.substr($file,length($dx)); + $tgt =~ s/\/\//\//g; + # create the target directory path + $tgtdir=$tgt; + if ( ! -d $tgtdir ) { + $tgtdir =~ s/\/[^\/]*$//; + } + # make sure the path to the directory exists by creating it + createpath($tgtdir); + # assume the filetype is dir + $filetype = "dir"; + if ( ! -d $tgt ) { + # non directories (aka files) + open (P, "/usr/bin/file -b $file |"); + $filetype=

    ; + chomp $filetype; + close P; + # best way to overwrite is to remove it + system ("rm -f '$tgt'"); + } + if ($filetype =~ / text/ ) { + # text files get their internal paths changed + if ($verbose) { + print STDERR "sed -e 's:/mnt/fulcrum/home:/home:g' '$file' | sed $sedcmp > '$tgt'"; + } + $rv=system ("sed -e 's:/mnt/fulcrum/home:/home:g' '$file' | sed $sedcmp > '$tgt'"); + if ( -x $file ) { + system ("chmod +x '$tgt'"); + } + $copied = 1; + } + elsif (-f $file ) { + # non text files get copied + if ($verbose) { + print STDERR "cp -p '$file' '$tgt'"; + } + $rv=system ("cp -p '$file' '$tgt'"); + $copied = 1; + } + elsif ($file ne $home) { + # directories get copied in full, I know this seems silly, + # but I had problems when not doing this. + $file =~ s/$/\//; + $tgt =~ s/$/\//; + $file =~ s/\/\//\//g; + $tgt =~ s/\/\//\//g; + if ($verbose) { + print STDERR "cp -rf $file $tgt"; + } + system ("rm -rf '$tgt'"); + $rv=system ("cp -rf '$file' '$tgt'"); + $copied = 1; + } + if ($rv) { + print STDERR "Error:$rv on $tgt"; + $copied = 0; + } + last; + } + } + if (! copied) { + print STDERR "Error: Not copied $file"; + } + } +} +# update the config file, if necessary +if ($changedconfig && query ("Write Config File?")) { + $target =~ s/\/$//; + open (P, ">testcase.config"); + select P; + print "TARGETHOME '$target'"; + foreach $dx (sort keys %target) { + if (index ($target{$dx},$target) == 0) { + $t = substr($target{$dx},length($target)+1); + } + else { + $t = $target{$dx}; + } + print "TARGET '$dx' '$t'"; + } + foreach $dx (@exclude) { + print "EXCLUDE '$dx'"; + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/parsecellname b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/parsecellname new file mode 100644 index 0000000000..5e6d56c192 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/parsecellname @@ -0,0 +1,504 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +if [[ -x "$sedcmd" && -r "$sedcmd" ]] ; then + +function get_lib_name() { + local cellName="$1" + local libName=`echo "$cellName" | $sedcmd -e 's/\.[^\.]*$//' -e 's/\.[^\.]*$//'` + ret="$libName" +} + +function get_cell_name_from_cell_name_with_subtype() { + local cellNameWithSubType="$1" + local cellName=`echo "$cellNameWithSubType" | $sedcmd -e 's/\.[^\.]*$//'` + ret="$cellName" +} + +function get_subtype_from_cell_name_with_subtype() { + local cellNameWithSubType="$1" + local subType=`echo "$cellNameWithSubType" | $sedcmd -e "s/.*\.//"` + ret="$subType" +} + +function strip_lib_name() { + local cellName="$1" + + get_cell_name_from_cell_name_with_subtype "$cellName" + local subtype_stripped="$ret" + + + local shortName=`echo "$subtype_stripped" | $sedcmd -e "s/.*\.//"` + + get_subtype_from_cell_name_with_subtype "$cellName" + local subtype="$ret" + + ret="$shortName.$subtype" + +} + + +function get_short_name() { + local cellName="$1" + local shortName=`echo "$cellName" | $sedcmd -e "s/.*\.//"` + ret="$shortName" +} + +function get_library_dir_for_libraray() { + local libName="$1" + local rootDir="$2" + + local libDir=`echo $libName | $sedcmd -e "s/\./\\//g"` + ret="$rootDir/$libDir" + +} + +function get_library_dir() { + local cellName="$1" + local rootDir="$2" + + if [[ -n "$cellName" && -n "$rootDir" ]] ; then + local libName + local libDir + get_lib_name "$cellName" + libName="$ret" + + get_library_dir_for_libraray "$libName" "$rootDir" + libDir="$ret" + + ret="$libDir" + + else + ret="" + fi + +} + +function get_cell_dir() { + local cellName="$1" + local rootDir="$2" + if [[ -n "$cellName" && -n "$rootDir" ]] ; then + local libDir + get_library_dir "$cellName" "$rootDir" + libDir="$ret" + ret="$libDir/$cellName" + else + ret="" + fi +} + +function cadence_escape_string() { + local theStr="$1" + + ret=`echo "$theStr" | $sedcmd -e "s/\./#2e/g" -e "s/-/#2d/g" -e 's/\\$/#24/g'` +} + +function cadence_reverse_escape_string() { + local theStr="$1" + + ret=`echo "$theStr" | $sedcmd -e "s/#2e/./g" -e "s/#2d/-/g"` +} + +function get_escaped_cell_dir() { + local cellName="$1" + local rootDir="$2" + if [[ -n "$cellName" && -n "$rootDir" ]] ; then + local libDir + get_library_dir "$cellName" "$rootDir" + libDir="$ret" + + local escapedCellName + cadence_escape_string "$cellName" + escapedCellName="$ret" + + ret="$libDir/$escapedCellName" + else + ret="" + fi +} + +function get_cadence_cell_view_dir() { + local cellName="$1" + local viewName="$2" + local rootDir="$3" + + if [[ -n "$cellName" && -n "$viewName" && -n "$rootDir" ]] ; then + local cellDir + get_escaped_cell_dir "$cellName" "$rootDir" + cellDir="$ret" + + if [ -n "$cellDir" ] ; then + local escapedViewName + cadence_escape_string "$viewName" + escapedViewName="$ret" + + ret="$cellDir/$escapedViewName" + else + ret="" + fi + else + ret="" + fi + +} + + +#Tells you if we know a cell view is invalid. +#Inverting the result of this function tells you +#if a cell COULD be valid, NOT that it is valid. +function is_invalid_cadence_cell_view() { + local cellName="$1" + local viewName="$2" + local rootDir="$3" + + if [[ -n "$cellName" && -n "$viewName" && -n "$rootDir" ]] ; then + local cellViewDir + get_cadence_cell_view_dir "$cellName" "$viewName" "$rootDir" + local cellViewDir="$ret" + + if [ -n "$cellViewDir" ] ; then + is_invalid_cadence_cell_view_dir "$cellViewDir" + else + ret="1" + fi + else + ret="1" + fi +} + +function is_invalid_cadence_cell_view_dir() { + local cellViewDir="$1" + local master_tag="$cellViewDir/master.tag" + local cdb_file= + if [[ -f "$master_tag" && + -r "$master_tag" ]] ; then + cdb_file=`tail -1 "$master_tag"` + cdb_file="$cellViewDir/$cdb_file" + fi + + if [ -n "$cdb_file" ] ; then + if [[ -f "$cdb_file" && + -r "$cdb_file" && + -f "$master_tag" && + -r "$master_tag" ]] ; then + ret="0" + else + ret="1" + fi + else + ret="1" + fi +} + +function get_cadence_cell_view_binary_files() { + + local cellName="$1" + local viewName="$2" + local rootDir="$3" + + if [[ -n "$cellName" && -n "$viewName" && -n "$rootDir" ]] ; then + local cellViewDir + get_cadence_cell_view_dir "$cellName" "$viewName" "$rootDir" + cellViewDir="$ret" + + echo "$cellViewDir"; + if [ -n "$cellViewDir" ] ; then + + local master_tag="$cellViewDir/master.tag" + local prop_xx="$cellViewDir/prop.xx" + local thumbnail="$cellViewDir/thumbnail_128x128.png" + local cdb_file= + if [[ -f "$master_tag" && + -r "$master_tag" ]] ; then + cdb_file=`tail -1 "$master_tag"` + cdb_file="$cellViewDir/$cdb_file" + fi + + # do not really need prop.xx if it is not there + if [ ! -f "$prop_xx" ]; then prop_xx=""; fi + if [ ! -f "$thumbnail" ]; then thumbnail=""; fi + if [ -n "$cdb_file" ] ; then + ret="$cdb_file $prop_xx $thumbnail" + else + ret="$prop_xx" + fi + else + ret="" + fi + else + ret="" + fi + +} + +function get_cadence_cell_view_text_files() { + + local cellName="$1" + local viewName="$2" + local rootDir="$3" + + if [[ -n "$cellName" && -n "$viewName" && -n "$rootDir" ]] ; then + local cellViewDir + get_cadence_cell_view_dir "$cellName" "$viewName" "$rootDir" + cellViewDir="$ret" + + if [ -n "$cellViewDir" ] ; then + local master_tag="$cellViewDir/master.tag" + local cdb_file= + ret="$master_tag" + + else + ret="" + fi + else + ret="" + fi + +} + +function is_cell_view_writeable() { + + local cellName="$1" + local viewName="$2" + local rootDir="$3" + + if [[ -n "$cellName" && -n "$viewName" && -n "$rootDir" ]] ; then + local cellViewDir + get_cadence_cell_view_dir "$cellName" "$viewName" "$rootDir" + cellViewDir="$ret" + + if [ -n "$cellViewDir" ] ; then + + local master_tag="$cellViewDir/master.tag" + local cdb_file= + if [[ -f "$master_tag" && + -r "$master_tag" ]] ; then + cdb_file=`tail -1 "$master_tag"` + cdb_file="$cellViewDir/$cdb_file" + fi + + if [ -n "$cdb_file" ] ; then + if [[ -f "$master_tag" && + -w "$master_tag" && + -r "$master_tag" && + -f "$cdb_file" && + -w "$cdb_file" && + -r "$cdb_file" ]] ; then + ret="1" + else + ret="0" + fi + else + ret="0" + fi + else + ret="0" + fi + else + ret="0" + fi + +} + +function get_lib_name_for_dir() { + local dirName="$1" + local rootDir="$2" + + local escapedRootDir=`echo "$rootDir" | $sedcmd -e "s/\//\\\\\\\\\\//g"` + + local relativeLibDir=`echo "$dirName" | $sedcmd -e "s/$escapedRootDir//g"` + + local libName=`echo "$relativeLibDir" | $sedcmd -e "s/\//./g" -e "s/^\.//" -e "s/\.\$//"` + + ret="$libName" + +} + +function get_escaped_library_name_for_library() { + local libName="$1" + + local escapedLibName + cadence_escape_string "$libName" + escapedLibName="$ret" + + ret="$escapedLibName" + +} + +function get_first_component_of_name() { + + local name="$1" + + ret=`echo $name | $sedcmd -e "s/^\([^\.]\+\)\..\+/\1/"` + +} + +function strip_first_component_of_name() { + local name="$1" + ret=`echo $name | $sedcmd -e "s/^\([^\.]\+\)\.\(.\+\)/\2/"` +} + +function get_second_component_of_name() { + local name="$1" + + strip_first_component_of_name "$name" + + local second_and_beyond="$ret" + + get_first_component_of_name "$second_and_beyond" + + local second_component="$ret" + + ret="$second_component" + +} + +function strip_first_two_components_of_name() { + + local name="$1" + strip_first_component_of_name "$name" + local firstStripped="$ret" + strip_first_component_of_name "$firstStripped" + local firstTwoStripped="$ret" + ret="$firstTwoStripped" +} + +function get_third_component_of_name() { + local name="$1" + + strip_first_two_components_of_name "$name" + + local third_and_beyond="$ret" + + get_first_component_of_name "$third_and_beyond" + + local third_component="$ret" + + ret="$third_component" + +} + +function strip_first_three_components_of_name() { + local name="$1" + strip_first_two_components_of_name "$name" + local firstTwoStripped="$ret" + strip_first_component_of_name "$firstTwoStripped" + local firstThreeStripped="$ret" + ret="$firstThreeStripped" +} + +function get_depot_path_for_lib_name() { + + local dfIIRoot="$1" + local branchName="$2" + local libName="$3" + + + get_first_component_of_name "$libName" + firstComponent="$ret" + + local preBranch="$dfIIRoot" + local postBranch="" + + if [[ "$firstComponent" == "chip" || "$firstComponent" == "core" ]] ; then + get_second_component_of_name "$libName" + local secondComponent="$ret" + preBranch="$preBranch/$firstComponent/$secondComponent" + + strip_first_two_components_of_name "$libName" + local postBranchComponents="$ret" + postBranch=`echo $postBranchComponents | $sedcmd -e "s/\./\\//g"` + else + if [[ "$firstComponent" == "vendor" ]] ; then + get_second_component_of_name "$libName" + local secondComponent="$ret" + + get_third_component_of_name "$libName" + local thirdComponent="$ret" + preBranch="$preBranch/$firstComponent/$secondComponent/$thirdComponent" + + strip_first_three_components_of_name "$libName" + local postBranchComponents="$ret" + postBranch=`echo $postBranchComponents | $sedcmd -e "s/\./\\//g"` + else + + preBranch="$preBranch/$firstComponent" + + strip_first_component_of_name "$libName" + local postBranchComponents="$ret" + postBranch=`echo $postBranchComponents | $sedcmd -e "s/\./\\//g"` + fi + fi + + ret="$preBranch/$branchName/$postBranch" + +} + +function get_dfII_depot_path_for_cell_name() { + local dfIIRoot="$1" + local branchName="$2" + local cellName="$3" + + get_lib_name "$cellName" + local libName="$ret" + + get_depot_path_for_lib_name "$dfIIRoot" "$branchName" "$libName" + local libDepotPath="$ret" + + cadence_escape_string "$cellName" + escapedCellName="$ret" + + ret="$libDepotPath/${cellName}Q$" + +} + +function get_spec_depot_path_for_cell_name() { + + + local dfIIRoot="$1" + local branchName="$2" + local cellName="$3" + + get_lib_name "$cellName" + local libName="$ret" + + get_depot_path_for_lib_name "$dfIIRoot" "$branchName" "$libName" + local libDepotPath="$ret" + + cadence_escape_string "$cellName" + escapedCellName="$ret" + + strip_lib_name "$cellName" + libStripped="$ret" + + get_first_component_of_name "$libStripped" + rootCellName="$ret" + + get_second_component_of_name "$libStripped" + subType="$ret" + + ret="$libDepotPath/$rootCellName/$subType.cast" + +} + +function get_cadence_cell_name_for_dfII_file() { + local file="$1" + local viewDir=`dirname $file` + local cellDir=`dirname $viewDir` + local cell=`basename $cellDir` + + cadence_reverse_escape_string $cell +} + +function get_cadence_view_name_for_dfII_file() { + local file="$1" + local viewDir=`dirname $file` + ret=`basename $viewDir` +} + +else + echo "You must define the sedcmd variable before sourcing the parsecellname file." +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/verilog2cdl.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/verilog2cdl.sh new file mode 100755 index 0000000000..98d482d0b5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/verilog2cdl.sh @@ -0,0 +1,225 @@ +#!/bin/bash +# $Id$ +# $DateTime$ +# $Author$ + +<Converts a verilog file into a cdl file, using netReader/vldb2spice assura tools. Used by for converting verilog from vendors into cdl, which will eventually turn into CAST using com.avlsi.tools.cdl2cast.Cdl2Cast.

    +DOC + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +debug= + +function exit_func() { + if [ -z "$debug" ]; then + if [ -n "$netReaderCmds" ] ; then + rm -f "$netReaderCmds" + fi + if [ -n "$vldbFile" ] ; then + rm -f "$vldbFile" + fi + if [ -n "$vldbToSpiceDir" ] ; then + rm -rf "$vldbToSpiceDir" + fi + if [ -n "$spiceFile" ] ; then + rm -f "$spiceFile" + fi + fi +} + +trap exit_func EXIT + +function usage() { + echo "Usage: $0 " + echo " --cell=cell" + echo " --output-cdl=file" + echo " [ --verilog=file [ --verilog=file [ ... ] ] ]" + echo " [ --cdl=file [ --cdl=file [ ... ] ] ]" + echo " [ --net-reader-log=/dev/null ]" + echo " [ --vldb-to-spice-log=/dev/null ]" + echo " [ --verbose ]" +} + +shLibDir="$package_root/share/script/sh/sh-lib" +source "$shLibDir/file/filecheck.sh" +source "$shLibDir/file/conon.sh" + +vldbToSpice=`mywhich vldbToSpice` || exit 2 +netReader=`mywhich netReader` || exit 2 +sedcmd=`mywhich sed` || exit 2 + +verilogFiles= +cdlFiles= +outputCDLFile= +cell= +netReaderLog="/dev/null" +vldbToSpiceLog="/dev/null" +verbose= +# One should not use /tmp for temp files /tmp is for the operating +# system's /tmp. All temp files created by this script +# go in $tempDir which can be set by the --temp-dir option. +tempDir="/scratch" + +for arg in "$@"; do + case "$arg" in + --verilog=*) + thisVerilogFile=`echo "$arg" | $sedcmd -e "s/--verilog=//"` + verilogFiles="$verilogFiles $thisVerilogFile" + ;; + --cdl=*) + thisCDLFile=`echo "$arg" | $sedcmd -e "s/--cdl=//"` + cdlFiles="$cdlFiles $thisCDLFile" + ;; + --output-cdl=*) + outputCDLFile=`echo "$arg" | $sedcmd -e "s/--output-cdl=//"` + ;; + --cell=*) + cell=`echo "$arg" | $sedcmd -e "s/--cell=//"` + ;; + --net-reader-log=*) + netReaderLog=`echo "$arg" | $sedcmd -e "s/--net-reader-log=//"` + ;; + --vldb-to-spice-log=*) + vldbToSpiceLog=`echo "$arg" | $sedcmd -e "s/--vldb-to-spice-log=//"` + ;; + --verbose) + verbose=1 + debug=1 + ;; + --temp-dir=*) + tempDir=`echo "$arg" | $sedcmd -e "s/--temp-dir=//"` + ;; + *) + echo "Unknown argument: \"$arg\"" + ;; + esac +done + +check_for_empty_arg "$outputCDLFile" "You must specify an output file name." 2 + +check_for_empty_arg "$netReaderLog" "You must specify a log file for netReader." 2 +check_for_empty_arg "$vldbToSpiceLog" "You must specify a log file for vldbToSpice" 2 +check_for_empty_arg "$tempDir" "You must specify a directory to contain temporary files." 2 + +check_writeable_file "$outputCDLFile" "Output CDL: \"$outputCDLFile\" is not a writable file." 1 +conon_path "$outputCDLFile" +outputCDLFile="$ret" + +if [[ "$netReaderLog" != "/dev/null" ]] ; then + check_writeable_file "$netReaderLog" "netReader Log: \"$netReaderLog\" is not a writable file." 1 + conon_path "$netReaderLog" + netReaderLog="$ret" +fi +if [[ "$vldbToSpiceLog" != "/dev/null" ]] ; then + check_writeable_file "$vldbToSpiceLog" "vldbToSpice Log: \"$vldbToSpiceLog\" is not a writable file." 1 + conon_path "$vldbToSpiceLog" + vldbToSpiceLog="$ret" +fi + +check_writeable_dir "$tempDir" "\"$tempDir\" is not a writable directory." 1 +conon_path "$tempDir" +tempDir="$ret" + +netReaderCmds=`mktemp $tempDir/verilog2cdl.XXXXXX` + +for file in $cdlFiles ; do + check_readable_file "$file" "\"$file\" is not a readable file." 1 + conon_path "$file" + file="$ret" + if [ -n "$verbose" ] ; then + echo "cdl $file" + fi + echo "cdl $file" >>$netReaderCmds +done + +for file in $verilogFiles ; do + check_readable_file "$file" "\"$file\" is not a readable file." 1 + conon_path "$file" + file="$ret" + if [ -n "$verbose" ] ; then + echo "verilog $file" + fi + echo "verilog $file" >>$netReaderCmds +done + +if [ -n "$verbose" ] ; then + echo "topCell $cell" +fi +if [ -n "$cell" ] ; then + echo "topCell $cell" >>$netReaderCmds +fi + +vldbFile=`mktemp $tempDir/verilog2cdl.XXXXXX` +if [ -n "$verbose" ] ; then + echo "file $vldbFile" +fi +echo "file $vldbFile" >>$netReaderCmds + +if [ -n "$verbose" ] ; then + echo "exit" +fi +echo "exit" >>$netReaderCmds + +netReaderCmd="cat $netReaderCmds | $netReader &>$netReaderLog" + +if [ -n "$verbose" ] ; then + echo "$netReaderCmd" +fi + +eval "$netReaderCmd" +netReaderRet=$? + +if [[ "$netReaderRet" != "0" ]] ; then + echo "netReader FAILED" >/proc/self/fd/2 + exit $netReaderRet +fi + +vldbToSpiceDir=`mktemp -d $tempDir/verilog2cdl.XXXXXX` + +spiceFile=`mktemp $tempDir/verilog2cdl.XXXXXX` + +vldbToSpiceCmd="pushd \"$vldbToSpiceDir\" >/dev/null ; " +vldbToSpiceCmd="$vldbToSpiceCmd $CADENCE_WRAPPER_SCRIPT $vldbToSpice \"$vldbFile\" \"$spiceFile\" &>$vldbToSpiceLog ;" +vldbToSpiceCmd="$vldbToSpiceCmd popd >/dev/null" + +if [ -n "$verbose" ] ; then + echo "$vldbToSpiceCmd" +fi + +eval "$vldbToSpiceCmd" +vldbToSpiceRet=$? + +if [[ "$vldbToSpiceRet" != "0" ]] ; then + echo "vldbToSpice FAILED" 1>2 + exit "$vldbToSpiceRet" +fi + +#HACK HACK +#1. Prepend all instances with an extra x, because vldbToSPice uses the first character +# of instance names that begin with X as the instation operator X in the CDL format. +# Ex: If there is an instance name X8_foo vldbToSpice will emit: +# . +# . +# . +# X8_foo ... +# . +# . +# . +# Rather than xX8_foo or XX8_foo. Instance names that don't begin with X such +# as Blah are emited as xBlah. +#2. Fulcrum uses '.' as the hierarchy seperator, verilog generally uses +# '/', so replace all '/'es with '.'. vldbToSpice emits all '/'es as "\/" so +# replace all instances of "\/" with '.' +#3 Get rid of all '\'es that precede an identifer. +#4 Get rid of all '\'es that precede an instance name +spiceToCDLCmd="$sedcmd -e \"s/^X/xX/\"" +spiceToCDLCmd="$spiceToCDLCmd -e \"s,\\\\\/,.,g\"" +spiceToCDLCmd="$spiceToCDLCmd -e \"s/[[:space:]]\+\\\\\/ /g\"" +spiceToCDLCmd="$spiceToCDLCmd -e \"s/^[xX]\\\\\/x/\"" +spiceToCDLCmd="$spiceToCDLCmd \"$spiceFile\" >$outputCDLFile" + +if [ -n "$verbose" ] ; then + echo "$spiceToCDLCmd" +fi +eval "$spiceToCDLCmd" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/vip.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/vip.sh new file mode 100755 index 0000000000..f4de40abf1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/util/vip.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# $1 technology +# $2 dfII/CAST project + +# examples: +# CASTPATH= glc tsmc13 x8 ~/cell_lists/eco1 --debug (pv1) +# CASTPATH= SPECPATH=/scratch/net2/nevada/ccar_support.v2 glc nv90 nv ~/cell_lists/nv90 --debug (nevada) + +technology="$1" +project="$2" +shift 2 + +output_dir="$HOME/working/glc-$technology-$project" +mkdir -p "$output_dir" + +${HWDIR:=$HOME/hw} +${DFIIDIR:=$HWDIR/layout/$technology/dfII/$project} + +CASTPATH=$CASTPATH:$hw_dir/cast/$project:$hw_dir/cast/main:$SPECPATH:$hw_dir/layout/$technology/spec/$project:$hw_dir/layout/$technology/spec/main:$hw_dir/layout/$technology/spec + +gen_leaf_cells \ +--fulcrum-pdk-root=$FULCRUM_PDK_ROOT \ +--dfII-dir=$DFIIDIR \ +--cast-path=$CASTPATH \ +--cell-list=$cell_list \ +--output-root=$output_dir \ +$@ diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.fvwm2/Main-8-bit b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.fvwm2/Main-8-bit new file mode 100644 index 0000000000..48ff22f0ca --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.fvwm2/Main-8-bit @@ -0,0 +1,643 @@ +# Trying to compile an old .fvwrc to the new fvwm-2.0 Format +########################################################################### +# set up the colors +# +# OK some people like bright clear colors on their window decorations. +# These people, I guess would mostly be from nice sunny/good weather places +# line California. +# +# StdForeColor Black +# StdBackColor LightSkyBlue +# HiForeColor yellow +# HiBackColor PeachPuff1 + +# Me, I'm from Upstate New York, and live in New Hampshire, so I prefer +# these dark muddy colors... + +# this is used for non-selected windows, menus, and the panner +#!StdForeColor #c03050 (new command=Style "*" Color f/b) +Style "*" ForeColor #ffffff +#!StdBackColor #001010 (new command=Style "*" Color f/b) +Style "*" BackColor #ff0000 + +# this is used for the selected window +#!HiBackColor MidnightBlue (new command=HilightColor) +#!HiForeColor MintCream (new command=HilightColor) + +#Set the foreground and background color for selected windows +HilightColor Black White + +#PagerBackColor #202050 +#PagerForeColor orchid +#! PagerBackColor #000092 [deleted] +#! PagerForeColor Red [deleted] + + +# Menu colors +#!MenuForeColor #109090 (new command=MenuStyle) +#!MenuBackColor MidnightBlue (new command=MenuStyle) +#!MenuStippleColor RoyalBlue (new command=MenuStyle) + +############################################################################ +# Now the fonts - one for menus, another for window titles, another for icons +#Font -adobe-helvetica-medium-r-*-*-14-*-*-*-*-*-*-* +#!Font -bitstream-charter-black-r-*-*-*-*-*-*-*-110-*-* (new command=MenuStyle) +#WindowFont -adobe-helvetica-bold-r-*-*-12-*-*-*-*-*-*-* +WindowFont 6x13 +#IconFont -adobe-helvetica-medium-r-*-*-11-*-*-*-*-*-*-* +IconFont fixed + +########################################################################### +# Set up the major operating modes +# +######################## FOCUS STUFF ############################## +# Set windows to auto-raise after 750 milliseconds if you like it. +# Autoraise can sometimes obscure pop-up windows. Performance is now +# similar to olvwm's auto-raise feature. +#AutoRaise 750 + +# Normally, we'll be in focus-follows mouse mode, but uncomment this +# for mwm-style click-to-focus +#ClickToFocus + +######################## ICON STUFF ############################## +# Auto Place Icons is a nice feature.... +# This creates two icon boxes, one on the left side, then one on the +# bottom. Leaves room in the upper left for my clock and xbiff, +# room on the bottom for the Pager. +Style "*" IconBox -150 90 -5 -140 +Style "*" IconBox 5 -140 -140 -5 +#IconBox -70 1 -1 -140 + +# If you uncomment this, and make sure that the WindowList is bound to +# something, it works pretty much like an icon manager. +#SuppressIcons + +# StubbornIcons makes icons de-iconify into their original position on the +# desktop, instead of on the current page. +#StubbornIcons + +# With AutoPlacement, icons will normally place themselves underneath active +# windows. This option changes that. +#StubbornIconPlacement + +# If you want ALL you icons to follow you around the desktop (Sticky), try +# this +#StickyIcons + +######################## MWM EMULATION ####################### +# +# My feeling is that everyone should use MWMDecorHints and MWMFunctionHints, +# since some applications depend on having the window manager respect them + +# MWMFunction hints parses the function information in the MOTIF_WM_HINTS +# property, and prohibits use of these functions on the window. Appropriate +# portions of the window decorations are removed. +Style "*" MWMFunctions + +# MWM is kinda picky about what can be done to transients, and it was keeping +# me from iconifying some windows that I like to iconify, so here's an +# over-ride that will allow me to do the operation, even tough the menu +# item is shaded out. +Style "*" HintOverride + +# MWMDecor hints parses the decoration information in the MOTIF_WM_HINTS +# property, and removes these decoratons from the window. This does not affect +# the functions that can be performed via the menus. +Style "*" MWMDecor + +# These are affect minor aspects for the look-and-feel. +# Sub-menus placement mwm-style? +# MWMMenus +# mwm-style border reliefs (less deep than default fvwm) ? +# MWMBorders +# Maximize button does mwm-inversion thingy +# MWMButtons +######################## MISCELLANEOUS STUFF ####################### +# If you don't like the default 150 msec click delay for the complex functions +# change this and uncomment it. +#ClickTime 150 + +# OpaqueMove has a number (N) attached to it (default 5). +# if the window occupies less than N% of the screen, +# then opaque move is used. 0 <= N <= 100 +OpaqueMoveSize 100 + +# flip by whole pages on the edge of the screen. +EdgeScroll 0 0 + +# A modest delay before flipping pages seems to be nice... +# I thresh in a 50 pixel Move-resistance too, just so people +# can try it out. +EdgeResistance 0 0 + +# I like to use a large virtual screen and move from page to page with the +# pager. +#EdgeResistance 10000 0 + + +######################## WINDOW PLACEMENT ####################### +# RandomPlacement prevents user interaction while placing windows: +Style "*" RandomPlacement + +# SmartPlacement makes new windows pop-up in blank regions of screen +# if possible, or falls back to random or interactive placement. +Style "*" SmartPlacement + +# With SmartPlacement, windows will normally place themselves over icons. +# Uncomment this to change that. +#StubbornPlacement + +# NoPPosition instructs fvwm to ignore the PPosition field in window +# geometry hints. Emacs annoyingly sets PPosition to (0,0)! +Style "*" NoPPosition + + +######################## DECORATIONS ####################### +# If you want decorated transient windows, uncomment this: +#DecorateTransients + +########################################################################### +# Set up the virtual desktop and pager + +#set the desk top size in units of physical screen size +DeskTopSize 3x3 + +# and the reduction scale used for the panner/pager +#!DeskTopScale 36 (new command=*FvwmPagerDeskTopScale ) +*FvwmPagerDeskTopScale 36 + +# Use the Fvwm Pager +#! Pager 0 0 [deleted] + +########################################################################## +# Module path and paths to the icons +# +# ModulePath is a colon-separated list, just like regular unix PATH +ModulePath /usr/lib/X11/fvwm2/:/home/chrisb/bin/i386/fvwmmodules/ +ImagePath /usr/include/X11/pixmaps/:/usr/include/X11/bitmaps/ + +############################################################################ +# Set the decoration styles and window options +# Order is important!!!! +# If compatible styles are set for a single window in multiple Style +# commands, then the styles are ORed together. If conflicting styles +# are set, the last one specified is used. + +# These commands should command before any menus or functions are defined, +# and before the internal pager is started. + +# change the default width. +Style "*" BorderWidth 5, HandleWidth 5, Icon unknown1.xpm + +Style "Fvwm*" NoTitle, WindowListSkip,BorderWidth 0 +Style "FvwmPager" Sticky,StaysOnTop, BorderWidth 0, NoHandles +Style "FvwmBanner" StaysOnTop +Style "FvwmButtons" NoTitle, NoHandles, Sticky, WindowListSkip,BorderWidth 0 +Style "*lock" NoTitle, WindowListSkip, BorderWidth 0, Sticky, NoHandles +Style "xbiff" NoTitle, WindowListSkip, BorderWidth 0, Sticky, NoHandles +Style "xload" NoTitle, WindowListSkip, BorderWidth 0, NoHandles +Style "xlogo" NoTitle, WindowListSkip, BorderWidth 0, Sticky, NoHandles +Style "xlogout" NoTitle, WindowListSkip, BorderWidth 0, Sticky, NoHandles +Style "dumplogs" NoTitle, WindowListSkip, BorderWidth 0, NoHandles +#Style "Maker" StartsOnDesk 1 +#Style "matlab" StartsOnDesk 3 +#Style "signal" StartsOnDesk 3 +Style "rxvt" Icon term.xpm +Style "xterm" Icon xterm.xpm +Style "color_xterm" Icon xterm.xpm +Style "Appointment" Icon datebook.xpm +Style "xcalc" Icon xcalc.xpm +Style "xmh" Icon mail1.xpm, StartsOnDesk 2 +Style "xman" Icon xman.xpm +Style "xvgr" Icon graphs.xpm +Style "matlab" Icon math4.xpm +Style "xmag" Icon mag_glass.xpm +Style "xgraph" Icon graphs.xpm +Style "FvwmButtons" Icon toolbox.xpm +Style "syslog" NoTitle,BorderWidth 0 +Style "xload" NoTitle,BorderWidth 0 + +############################################################################# + +# Stuff to do at start-up + +AddToFunc "InitFunction" "I" Exec xsetroot -solid MidnightBlue ++ "I" Module FvwmPager 0 0 + +AddToFunc "RestartFunction" "I" Exec xsetroot -solid "#011111" +# Module "I" GoodStuff ++ "I" Module FvwmPager 0 0 ++ "I" Exec xsetroot -solid MidnightBlue + + +############################################################################ +# Now define some handy complex functions + +# This one moves and then raises the window if you drag the mouse, +# only raises the window if you click, or does a RaiseLower if you double +# click +AddToFunc "Move-or-Raise" "M" Move ++ "M" Raise ++ "C" Raise ++ "D" RaiseLower + +# This one maximizes vertically if you click (leaving room for the GoodStuff bar at the +# bottom, or does a full maximization if you double click, or a true full vertical +# maximization if you just hold the mouse button down. +AddToFunc "maximize_func" "M" Maximize 0 100 ++ "C" Maximize 0 80 ++ "D" Maximize 100 100 + + +# This one moves and then lowers the window if you drag the mouse, +# only lowers the window if you click, or does a RaiseLower if you double +# click +AddToFunc "Move-or-Lower" "M" Move ++ "M" Lower ++ "C" Lower ++ "D" RaiseLower + +# This one moves or (de)iconifies: +AddToFunc "Move-or-Iconify" "M" Move ++ "D" Iconify + +# This one resizes and then raises the window if you drag the mouse, +# only raises the window if you click, or does a RaiseLower if you double +# click +AddToFunc "Resize-or-Raise" "M" Resize ++ "M" Raise ++ "C" Raise ++ "D" RaiseLower + + +# This is provided as a hint only. +# Move to a known page on the desktop, then start an application in a +# known location. Could also switch to a known desktop, I guess +#Function "abs_coord" +# GoToPage "Immediate" 1,1 +# Exec "Immediate" exec xcalc -geometry +100+100& +#EndFunction + + +############################################################################## +#now define the menus - defer bindings until later + +AddToMenu Shells "Shells" Title ++ "Color Xterm" Exec exec xterm -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff"& ++ "Large Color Xterm" Exec exec xterm -sb -sl 500 -j -ls -fn 10x20 -cr "#20e020" -bg "black" -fg "#ffffff"& + +AddToMenu Hosts "Other Hosts" Title ++ "ADD" Popup ADDMenu ++ "Cco" Exec exec xterm -title "cco" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh -l cab00001 cco.caltech.edu & ++ "Ugcs" Popup UGCSMenu + +AddToMenu ADDMenu "ADD" Title ++ "dime" Exec exec xterm -title "dime" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh dime ++ "odin" Exec exec xterm -title "odin" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh odin ++ "alex" Exec exec xterm -title "alex" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh alex + +AddToMenu UGCSMenu "UGCS" Title ++ "Intel" Popup UGCSIntel + +AddToMenu UGCSIntel "Intels" Title ++ "Bolivar" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh bolivar.ugcs.caltech.edu & ++ "Riyal" Exec exec /usr/ug/bin/xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh riyal.ugcs.caltech.edu & ++ "Dinar" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh dinar.ugcs.caltech.edu & ++ "Krone" Exec exec /usr/ug/bin/xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh krone.ugcs.caltech.edu & ++ "Mark" Exec exec /usr/ug/bin/xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh mark.ugcs.caltech.edu & ++ "Lira" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh lira.ugcs.caltech.edu & ++ "Euro" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh euro.ugcs.caltech.edu & ++ "Lek" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh lek.ugcs.caltech.edu & ++ "Baht" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh baht.ugcs.caltech.edu & ++ "Zloty" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh zloty.ugcs.caltech.edu & ++ "Ngwee" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh ngwee.ugcs.caltech.edu & ++ "Drachma" Exec exec color_xterm -title "UGCS" -g 100x30 -sb -sl 500 -j -ls -bg "black" -cr "#20e020" -fg "#ffffff" -e ssh drachma.ugcs.caltech.edu & + +AddToMenu AnimateRootWindow "Root" Title +AddToMenu AnimateRootWindow "Root" Title ++ "Blot" Exec exec xlock -inroot -nolock -nice 0 -mode blot & ++ "Bounce" Exec exec xlock -inroot -nolock -nice 0 -mode bounce & ++ "Forest" Exec exec xlock -inroot -nolock -nice 0 -mode forest & ++ "Galaxy" Exec exec xlock -inroot -nolock -nice 0 -mode galaxy & ++ "Grav" Exec exec xlock -inroot -nolock -nice 0 -mode grav & ++ "Helix" Exec exec xlock -inroot -nolock -nice 0 -mode helix & ++ "Hop" Exec exec xlock -inroot -nolock -nice 0 -mode hop & ++ "Hyper" Exec exec xlock -inroot -nolock -nice 0 -mode hyper & ++ "Kaleid" Exec exec xlock -inroot -nolock -nice 0 -mode kaleid & ++ "Lasers" Exec exec xlock -inroot -nolock -nice 0 -mode laser & ++ "Maze" Exec exec xlock -inroot -nolock -nice 0 -mode maze & ++ "Pyro" Exec exec xlock -inroot -nolock -nice 0 -mode pyro & ++ "Qix" Exec exec xlock -inroot -nolock -nice 0 -mode qix & ++ "Random" Exec exec xlock -inroot -nolock -nice 0 -mode random & ++ "Rock" Exec exec xlock -inroot -nolock -nice 0 -mode rock & ++ "Rotor" Exec exec xlock -inroot -nolock -nice 0 -mode rotor & ++ "Sphere" Exec exec xlock -inroot -nolock -nice 0 -mode sphere & ++ "Spirals" Exec exec xlock -inroot -nolock -nice 0 -mode spiral & ++ "Spline" Exec exec xlock -inroot -nolock -nice 0 -mode spline & ++ "Swarm" Exec exec xlock -inroot -nolock -nice 0 -mode swarm & ++ "Swirls" Exec exec xlock -inroot -nolock -nice 0 -mode swirl & ++ "Wator" Exec exec xlock -inroot -nolock -nice 0 -mode wator & ++ "Worm" Exec exec xlock -inroot -nolock -nice 0 -mode worm & ++ "World" Exec exec xlock -inroot -nolock -nice 0 -mode world & + +AddToMenu Screenlock "Lock Screen" Title ++ "Blot" Exec exec xlock -nice 0 -mode blot & ++ "Bounce" Exec exec xlock -nice 0 -mode bounce & ++ "Forest" Exec exec xlock -nice 0 -mode forest & ++ "Galaxy" Exec exec xlock -nice 0 -mode galaxy & ++ "Grav" Exec exec xlock -nice 0 -mode grav & ++ "Helix" Exec exec xlock -nice 0 -mode helix & ++ "Hop" Exec exec xlock -nice 0 -mode hop & ++ "Hyper" Exec exec xlock -nice 0 -mode hyper & ++ "Kaleid" Exec exec xlock -nice 0 -mode kaleid & ++ "Lasers" Exec exec xlock -nice 0 -mode laser & ++ "Maze" Exec exec xlock -nice 0 -mode maze & ++ "Pyro" Exec exec xlock -nice 0 -mode pyro & ++ "Qix" Exec exec xlock -nice 0 -mode qix & ++ "Random" Exec exec xlock -nice 0 -mode random & ++ "Rock" Exec exec xlock -nice 0 -mode rock & ++ "Rotor" Exec exec xlock -nice 0 -mode rotor & ++ "Sphere" Exec exec xlock -nice 0 -mode sphere & ++ "Spirals" Exec exec xlock -nice 0 -mode spiral & ++ "Spline" Exec exec xlock -nice 0 -mode spline & ++ "Swarm" Exec exec xlock -nice 0 -mode swarm & ++ "Swirls" Exec exec xlock -nice 0 -mode swirl & ++ "Wator" Exec exec xlock -nice 0 -mode wator & ++ "Worm" Exec exec xlock -nice 0 -mode worm & ++ "World" Exec exec xlock -nice 0 -mode world & + +AddToMenu Games "Games" Title +# Exec "Xcolormap" exec xcolormap & ++ "Xeyes" Exec exec xeyes & ++ "Xtetris" Exec exec xtetris & + +AddToMenu Applications "Applications" Title ++ "mozilla" Exec exec mozilla & ++ "Ghostview" Exec exec ghostview & ++ "GNU Emacs" Exec exec emacs & ++ "Xedit" Exec exec xedit & ++ "Xfig" Exec exec xfig & ++ "Xgrab" Exec exec xgrab & ++ "Xpaint" Exec exec xpaint & ++ "Xxgdb" Exec exec xxgdb & + +# This menu is invoked as a sub-menu - it allows you to quit, +# restart, or switch to another WM. +AddToMenu Quit-Verify "Really Quit Fvwm?" Title ++ "Yes, Really Quit" Quit ++ "Restart fvwm2" Restart fvwm2 ++ "" Nop ++ "No, Don't Quit" Nop + +# Provides a list of modules to fire off +AddToMenu Module-Popup "Modules" Title ++ "FvwmButtons" Module FvwmButtons ++ "Clean-Up" Module FvwmClean ++ "Identify" Module FvwmIdent ++ "SaveDesktop" Module FvwmSave ++ "Debug" Module FvwmDebug ++ "Pager" Module FvwmPager 0 0 ++ "FvwmWinList" Module FvwmWinList + +# This menu will fire up some very common utilities +AddToMenu Utilities "Utilities" Title ++ "Top" Exec exec xterm -fg white -bg MidnightBlue -fn 7x14 -title Top -n Top -e top & ++ "Calculator" Exec exec xcalc & ++ "Xman" Exec exec xman & ++ "Xmag" Exec exec xmag & ++ "" Nop ++ "Applications" Popup Applications ++ "" Nop ++ "Shells" Popup Shells ++ "" Nop ++ "Other Hosts" Popup Hosts ++ "" Nop ++ "Games" Popup Games ++ "" Nop ++ "Animate root" Popup AnimateRootWindow ++ "" Nop ++ "Lock Screen" Popup Screenlock ++ "" Nop ++ "Modules" Popup Module-Popup ++ "" Nop ++ "Exit Fvwm" Popup Quit-Verify ++ "" Nop ++ "Refresh Screen" Refresh + +# This defines the most common window operations +AddToMenu WindowOps "Window Ops" Title ++ "Move" Function Move-or-Raise ++ "Resize" Function Resize-or-Raise ++ "Raise" Raise ++ "Lower" Lower ++ "(De)Iconify" Iconify ++ "(Un)Stick" Stick ++ "(Un)Maximize" Function maximize_func ++ "" Nop ++ "Destroy" Destroy ++ "Delete" Delete ++ "" Nop ++ "Refresh Screen" Refresh + +# A trimmed down version of "Window Ops", good for binding to decorations +AddToMenu WindowOps2 "Move" Function Move-or-Raise ++ "Resize" Function Resize-or-Raise ++ "Raise" Raise ++ "Lower" Lower ++ "Iconify" Iconify ++ "(Un)Stick" Stick ++ "" Nop ++ "Destroy" Destroy ++ "Delete" Delete ++ "" Nop ++ "ScrollBar" Module FvwmScroll 2 2 + +############################################################################# +# One more complex function - couldn't be defined earlier because it used +# pop-up menus +# +# This creates a motif-ish sticky menu for the title-bar window-ops +# pop-up +# Menu acts like normal twm menu if you just hold the button down, +# but if you click instead, the menu stays up, motif style +AddToFunc "window_ops_func" "C" PopUp Window Ops2 ++ "M" PopUp Window Ops2 +# Motif would add +# Delete "DoubleClick" + + +############################################################################## +# This defines the mouse bindings + +# First, for the mouse in the root window +# Button 1 gives the Utilities menu +# Button 2 gives the Window Ops menu +# Button 3 gives the WindowList (like TwmWindows) +# I use the AnyModifier (A) option for the modifier field, so you can hold down +# any shift-control-whatever combination you want! + +# Button Context Modifi Function +Mouse 1 R A Menu Utilities Nop +Mouse 2 R A Menu WindowOps Nop +Mouse 3 R A WindowList +#Mouse 3 R A Module "winlist" FvwmWinList transient + + + +# Now the title bar buttons +# Any button in the left title-bar button gives the window ops menu +# Any button in the right title-bar button Iconifies the window +# Any button in the rightmost title-bar button maximizes +# Note the use of "Mouse 0" for AnyButton. + +# Button Context Modifi Function +Mouse 0 1 A Function "window_ops_func" +Mouse 0 2 A Function "maximize_func" +Mouse 0 4 A Iconify + +# Now the rest of the frame +# Here I invoke my complex functions for Move-or-lower, Move-or-raise, +# and Resize-or-Raise. +# Button 1 in the corner pieces, with any modifiers, gives resize or raise +Mouse 1 F A Function "Resize-or-Raise" +# Button 1 in the title, sides, or icon, w/ any modifiers, gives move or raise +Mouse 1 TS A Function "Move-or-Raise" + +# Button 1 in an icons gives move for a drag, de-iconify for a double-click, +# nothing for a single click +# Button 2 in an icon, w/ any modifiers, gives de-iconify + +Mouse 1 I A Function "Move-or-Iconify" +Mouse 2 I A Iconify + +# Button 2 in the corners, sides, or title-bar gives the window ops menu +Mouse 2 FST A Function "window_ops_func" +# Button 3 anywhere in the decoration (except the title-bar buttons) +# does a raise-lower +Mouse 3 TSIF A RaiseLower + +# Button 3 in the window, with the Modifier-1 key (usually alt or diamond) +# gives Raise-Lower. Used to use control here, but that interferes with xterm +Mouse 3 W M RaiseLower + +############################################################################ +# Now some keyboard shortcuts. + +# Arrow Keys +# press arrow + control anywhere, and scroll by 1 page +#Key Left A C Scroll -100 0 +#Key Right A C Scroll +100 +0 +#Key Up A C Scroll +0 -100 +#Key Down A C Scroll +0 +100 + +# press arrow + meta key, and scroll by 1/10 of a page +#Key Left A M Scroll -10 +0 +#Key Right A M Scroll +10 +0 +#Key Up A M Scroll +0 -10 +#Key Down A M Scroll +0 +10 + +# press shift arrow + control anywhere, and move the pointer by 1% of a page +#Key Left A SC CursorMove -1 0 +#Key Right A SC CursorMove +1 +0 +#Key Up A SC CursorMove +0 -1 +#Key Down A SC CursorMove +0 +1 + +# press shift arrow + meta key, and move the pointer by 1/10 of a page +#Key Left A SM CursorMove -10 +0 +#Key Right A SM CursorMove +10 +0 +#Key Up A SM CursorMove +0 -10 +#Key Down A SM CursorMove +0 +10 + +# Keyboard accelerators +Key F1 A M Popup "Utilities" +Key F1 A M Popup "Utilities" +Key F2 A M Popup "Window Ops" +Key F3 A M Module "WindowList" FvwmWinList +Key F4 A M Iconify +Key F5 A M Move +Key F6 A M Resize +Key F7 A M CirculateUp +Key F8 A M CirculateDown + +#Page Up/Dapge Down keys are used to scroll by one desktop page +# in any context, press page up/down + control +# in root context, just pressing page up/down is OK +# +# I prefer the non-wrapping scroll. These are for example purposes only +#Key Next A C Scroll 100000 0 +#Key Next R N Scroll 100000 0 +#Key Prior A C Scroll -100000 0 +#Key Prior R N Scroll -100000 0 + + +############################################################################ +############################################################################ +#Definitions used by the modules + +###################### GoodStuff button-bar ################################ +# Colors +*FvwmButtonsFore Black +*FvwmButtonsBack #908090 + +# Font +*FvwmButtonsFont -adobe-helvetica-bold-r-*-*-10-*-*-*-*-*-*-* +# Geometry - really likes to pick its own size, but giving a position is OK +*FvwmButtonsGeometry -1-90 + +# Layout: specify rows or columns, not both +*FvwmButtonsColumns 1 + +# Define the buttons to use..... +*FvwmButtons Kill rbomb.xpm Destroy + +# xterm or rxvts on remote machines can be done like this +# Output re-direction is csh style, not sh style +# You will want to substitute your own hosts here! + + + +######################### No Clutter ######################################## +# I only wrote NoClutter as a simple test case, but maybe some big sites like +# universities really have usage problems (too many open windows).... +# Time delays are in seconds. +*FvwmNoClutter 3600 Iconify 1 +*FvwmNoClutter 86400 Delete +*FvwmNoCLutter 172800 Destroy + +########################## Window-Identifier ############################### +# Just choose colors and a fonts +*FvwmIdentBack MidnightBlue +*FvwmIdentFore Yellow +*FvwmIdentFont -adobe-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* + +########################### Pager ######################################### +*FvwmPagerBack #000092 +*FvwmPagerFore red +*FvwmPagerFont -adobe-helvetica-bold-r-*-*-10-*-*-*-*-*-*-* +*FvwmPagerHilight #cab3ca +*FvwmPagerGeometry -1-1 +#*FvwmPagerLabel 0 Misc +#*FvwmPagerLabel 1 FrameMaker +#*FvwmPagerLabel 2 Mail +#*FvwmPagerLabel 3 Matlab +*FvwmPagerSmallFont 5x8 + + +##########################FvwmWinList################################## +*FvwmWinListBack #908090 +*FvwmWinListFore Black +*FvwmWinListFont -adobe-helvetica-bold-r-*-*-10-*-*-*-*-*-*-* +*FvwmWinListAction Click1 Iconify -1,Focus +*FvwmWinListAction Click2 Iconify +*FvwmWinListAction Click3 Module "FvwmIdent" FvwmIdent +*FvwmWinListUseSkipList +*FvwmWinListGeometry +0-1 +#!Warning: Keyword "" not handled yet + + +#Set the foreground, background and stipple color and font for menus +MenuStyle Black White Red -bitstream-charter-black-r-*-*-*-*-*-*-*-110-*-* fvwm +# overide default RandomPlacement and SmartPlacement Styles +#Style "*" ActivePlacement, DumbPlacement +Style "*" SmartPlacement diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.vnc/xstartup b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.vnc/xstartup new file mode 100644 index 0000000000..31afa24df2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/.vnc/xstartup @@ -0,0 +1,4 @@ +#!/bin/bash +xsetroot -solid grey +xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & +fvwm2 -f "$HOME/.fvwm2/Main-8-bit" & diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/getvncserver.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/getvncserver.sh new file mode 100755 index 0000000000..431bb972a5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/getvncserver.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +function exit_func() { + if [ -f "$pidfile" ] ; then + rm $pidfile + fi +} + +trap exit_func EXIT + +vncserver=`which Xvnc` + +pidfile=`mktemp /tmp/vnc.XXXXXX` + +if [ -x $vncserver ]; then + ret= + displaynum=1 + while [[ ( -z "$ret" ) && ( $displaynum -lt 100 ) ]] ; do + $vncserver :$displaynum -depth 8 -cc 3 -fp "unix/:7100" -geometry 1024x768 &>/dev/null & echo $! > $pidfile + usleep 1000 + pid=`cat $pidfile` + ret=`ps --pid $pid | grep $pid` + if [ -z "$ret" ] ; then + displaynum=$[$displaynum+1] + fi + done + + if [ -z "$ret" ] ; then + echo "Couldn't get a VNC display" + exit 1 + else + display="$HOSTNAME:$displaynum" + echo "`cat $pidfile` $display" + fi +else + echo "$vncserver is not an executable file" + exit 2 +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/nograph.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/nograph.sh new file mode 100755 index 0000000000..78357c56ca --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/script/sh/vnc/nograph.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# +# Runs $@ from a vncserver +# Usefual if $@ needs an X server, but you don't want to deal with physical +# terminals +# + + +function exit_func() { + if [[ ( -n "$pid" ) && ( `ps --pid $pid | grep $pid`) ]] ; then + echo "Killing VNC display $display" + kill -9 $pid + fi +} + +trap exit_func EXIT + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +fvwmrc="$package_root/share/script/sh/vnc/.fvwm2/Main-8-bit" +getvncserver="$package_root/share/script/sh/vnc/getvncserver.sh" + +ret=`$getvncserver` + +if [ $? -ne 0 ] ; then + echo "Couldn't get VNC server" + exit 1 +else + pid=`echo $ret | awk '{print $1}'` + display=`echo $ret | awk '{print $2}'` + echo "Running on VNC display $display" + echo "Xvnc pid=$pid" + DISPLAY=$display xsetroot -solid grey + DISPLAY=$display fvwm2 -f $fvwmrc & + DISPLAY=$display xhost + >/dev/null + DISPLAY=$display "$@" +fi diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/gen_autoload b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/gen_autoload new file mode 100755 index 0000000000..ddbdf7a9b5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/gen_autoload @@ -0,0 +1,143 @@ +#!/usr/intel/bin/perl +use strict; + +use File::Spec; + +use Cwd; + +use FileHandle; + +sub dofile { + local $_; + my $file = shift; + my $fh; + open($fh, "cpp -P -traditional $file |"); + my @out = (); + while (<$fh>) { + s/^([^;]*).*$/$1/; #remove ';' comments + s/^\s*$//; #remove whitespace lines + s/(\w+)\(/\(\1/g; # replace "foo(" with "(foo" + + while (/.*(defun|defstruct|procedure|defmacro)[\([:space:]]+([^[:space:]\)\(]+)/g) { + if ($1 eq "defun" or $1 eq "procedure" or $1 eq "defmacro") { + push @out, $2; + } elsif ($1 eq "defstruct") { + push @out, "make_$2"; + push @out, "copy_$2"; + } + } + } + close($fh); + return @out; +} + +sub real_canon { + my ( $path ) = @_; + + my $absPath; + + if ( File::Spec->file_name_is_absolute( $path ) ) { + $absPath = File::Spec->canonpath($path); + } + else { + $absPath = File::Spec->canonpath(File::Spec->rel2abs( $path ) ); + } + + my ( $volume, $dir, $file ) = File::Spec->splitpath( $absPath ); + + + + my $dirPath; + + $dirPath = File::Spec->catpath( $volume, $dir ); + + if ( -d $dirPath ) { + + chomp( my $realDirName = `cd $dirPath ; pwd`); + + my $canonPath = File::Spec->catpath( $volume, $realDirName, $file ); + + return $canonPath; + } + else { + return $absPath; + } + +} + +sub dodir { + my ( $outputFile, $dir, $dup ) = @_; + my $dh; + $dir = real_canon( $dir ); + + opendir($dh, $dir); + my @entries=sort(readdir($dh)); + closedir($dh); + + foreach my $entry (@entries) { + my $full = File::Spec->canonpath($dir . "/" . $entry); + if (( -f $full or -l $full ) and $entry =~ /\.ils?$/) { + my @out; + @out = dofile($full); + if ($#out != -1) { + + my $func; + foreach $func (@out) { + push @{${$dup}{$func}}, $full; + print $outputFile "( putpropq `$func \"$full\" autoload )\n"; + } + + } + } elsif (-d $full and $entry !~ /^\./ and $entry !~ /^CVS$/) { + dodir($outputFile, $full, $dup); + } + } +} + +if ( $#ARGV != 7 ) { + print STDERR "#ARGV=\"$#ARGV\"\n"; + print STDERR "$0 packageRoot installShareBin installShareData" . + " installArchBin installArchData packageInst archBin archData\n"; + exit 1; +} +else { + my $packageRoot=$ARGV[0]; + my $installShareBin=$ARGV[1]; + my $installShareData=$ARGV[2]; + my $installArchBin=$ARGV[3]; + my $installArchData=$ARGV[4]; + my $packageInst=$ARGV[5]; + my $archBin=$ARGV[6]; + my $archData=$ARGV[7]; + + my $skillRoot="$packageRoot/share/skill"; + + if ( ( -d $skillRoot ) && + ( -w $skillRoot ) && + ( -r $skillRoot ) ) { + my $warning = 0; # Whether to print out warnings for multiple definitions + + my $autoloadFileName = "$skillRoot/autoload.il"; + + my $autoloadFile = new FileHandle; + $autoloadFile->open( ">$autoloadFileName" ) or die "Can't open $autoloadFileName for writing."; + + my %dup = (); + &dodir($autoloadFile, $skillRoot, \%dup); + $autoloadFile->close(); + if ($warning) { + my $key; + foreach $key (keys %dup) { + if ($#{ $dup{$key} } > 0) { + print STDERR "$key defined in @{ $dup{$key}} \n"; + } + } + } + } + else { + print STDERR "Unable to find skill code at \"" . $skillRoot . "\" after package extraction.\n"; + exit 1; + } +} +0; + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/aspice/aspice.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/aspice/aspice.il new file mode 100644 index 0000000000..5ad77a1d9d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/aspice/aspice.il @@ -0,0 +1,427 @@ +; Select an instance by its name +(defun SelectInstByName (name) + (let (CV inst) + CV = (geGetEditCellView) + inst = (dbFindAnyInstByName CV name) + (cond (inst (geSelectObject inst))) + inst + ) + ) + +; Selects a bunch of instaces given names in file +(defun SelectInstancesFromFile (filename @key (CV (geGetEditCellView)) (CAST nil)) + (let (TEMP newfilename file line inst n) + + ; rename instances + (when CAST + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + newfilename = (sprintf nil "%s/%s.insts" TEMP CV->cellName) + (shell (sprintf nil "rename --from=cast --to=cadence --type=instance < %s > %s" + filename newfilename)) + filename = newfilename + ) + + ; select instances + (printf "Reading %s\n" filename) + n=0 + file = (infile filename) + (while (and file (gets line file)) + line = (substring line 1 strlen(line)-1) + (unless (SelectInstByName line) + (printf "Missing instance %s\n" line) + n=n+1 + ) + ) + (close file) + (when n (printf "%d missing instances\n" n)) + t + ) + ) + +; Prints an aspice.asp file to simulate only selected cells and nets they touch +(defun AspiceSelected (fileName @key (CV (geGetEditCellView)) (tau 50) (power nil) (toGDS2 nil)) + (let (maplist typeMap instMap nodeMap instGds2Map nodeGds2Map + selected insts nodes n node instances + rename aspFile nodeName typeName instName) + + ; translate names + (when toGDS2 + maplist = (TranslateNames "gds2" ?CV CV) + instGds2Map = (cadr maplist) + nodeGds2Map = (caddr maplist) + ) + maplist = (TranslateNames "cast" ?CV CV) + typeMap = (car maplist) + instMap = (cadr maplist) + nodeMap = (caddr maplist) + + ; start asp file + aspFile = (outfile fileName) + (fprintf aspFile ".scale_after_delay = 0.5; /* 100 delay equals %dps */\n" tau) + + ; find critical nets + selected = (setof x (geGetSelSet) x->type=="trueInst" && x->libName!=TechLibName) + insts = (makeTable "instances" nil) + nodes = (makeTable "nodes" nil) + (unless power + nodes[(dbFindNetByName CV GNDNetName)] = t + nodes[(dbFindNetByName CV VddNetName)] = t + ) + n=0 + (foreach inst selected + insts[inst] = t + (foreach term inst->instTerms + node = term->net + (unless nodes[node] + nodes[node]=t + nodeName = (if toGDS2 && node->pins==nil + nodeGds2Map[node->name] + nodeMap[node->name]) + (fprintf aspFile ".critical \"%s\";\n" nodeName) + n++ + ) + ) + ) + (printf "found %d critical nets...\n" n) + + ; find skipped instances + n=0 + instances = (setof x CV->instances x->type=="trueInst" && x->libName!=TechLibName) + (foreach inst instances + (unless (or insts[inst] (strncmp inst->cellName "synthesis.shared." 17)==0) + typeName = typeMap[inst->cellName] + instName = (if toGDS2 instGds2Map[inst->name] instMap[inst->name]) + (fprintf aspFile ".modify skip \"%s\" \"%s\";\n" typeName instName) + (fprintf aspFile ".modify env \"%s.*\" \"%s\";\n" typeName instName) + n++ + ) + ) + (printf "found %d non-critical instances\n" n) + (close aspFile) + ) + t + ) + +; draw M7 power stripes so --extractPower=1 is useful +(defun DrawPowerStripes (@key (CV (geGetEditCellView))) + (let (x0 y0 x1 y1) + x0 = (car (car CV->bBox)) + y0 = (cadr (car CV->bBox)) + x1 = (car (cadr CV->bBox)) + y1 = (cadr (cadr CV->bBox)) + x0 = PowerGridPitch*(floor x0/PowerGridPitch) + x1 = PowerGridPitch*(ceiling x1/PowerGridPitch) + y0 = (floor y0/PowerGridPitch) + y1 = (ceiling y1/PowerGridPitch) + (for y y0 y1 + (DrawChannel BusMetal67 node_6W (if (mod y 2)==0 "GND" "Vdd") + (list x0:PowerGridPitch*y x1:PowerGridPitch*y) ?isPin t) + ) + ) + t + ) + +; translate all type, inst, node names in a CellView, return 3 maps +(defun TranslateNames (to @key (CV (geGetEditCellView))) + (let (typeMap instMap nodeMap + nodeFileName typeFileName instFileName typeFile instFile nodeFile + TEMP rename) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + nodeFileName = (sprintf nil "%s/%s.nodes" TEMP CV->cellName) + typeFileName = (sprintf nil "%s/%s.types" TEMP CV->cellName) + instFileName = (sprintf nil "%s/%s.insts" TEMP CV->cellName) + typeFile = (outfile typeFileName) + instFile = (outfile instFileName) + nodeFile = (outfile nodeFileName) + + ; find all types, instances, nodes in this cell + typeMap = (makeTable "types" nil) + instMap = (makeTable "instances" nil) + nodeMap = (makeTable "nodes" nil) + (foreach inst (setof x CV->instances x->type=="trueInst" && x->libName!=TechLibName) + typeMap[inst->cellName]=t + instMap[inst->name]=t + ) + (foreach net CV->nets + nodeMap[net->name]=t + ) + (foreach name (setof a typeMap t) + (fprintf typeFile "%s\n" name) + ) + (foreach name (setof a instMap t) + (fprintf instFile "%s\n" name) + ) + (foreach name (setof a nodeMap t) + (fprintf nodeFile "%s\n" name) + ) + (close typeFile) + (close instFile) + (close nodeFile) + + ; rename nodes, types, instances + rename = (sprintf nil "rename --from=cadence --to=%s" to) + (shell (sprintf nil "%s --type=cell < %s > %s.renamed" + rename typeFileName typeFileName)) + (shell (sprintf nil "%s --type=instance < %s > %s.renamed" + rename instFileName instFileName)) + (shell (sprintf nil "%s --type=node < %s > %s.renamed" + rename nodeFileName nodeFileName)) + + ; read back mapped names + typeFile = (infile (sprintf nil "%s.renamed" typeFileName)) + instFile = (infile (sprintf nil "%s.renamed" instFileName)) + nodeFile = (infile (sprintf nil "%s.renamed" nodeFileName)) + (foreach name (setof a typeMap t) + (gets line typeFile) + line = (StringUtilChompNewline line) + typeMap[name] = line + ) + (foreach name (setof a instMap t) + (gets line instFile) + line = (StringUtilChompNewline line) + instMap[name] = line + ) + (foreach name (setof a nodeMap t) + (gets line nodeFile) + line = (StringUtilChompNewline line) + nodeMap[name] = line + ) + (close typeFile) + (close instFile) + (close nodeFile) + (list typeMap instMap nodeMap) + ) + ) + +; find subcells that connect to a selected wire +(defun WriteConnectedSubcells (netname filename @key (CV (geGetEditCellView))) + (let (net file found n) + net = (dbFindNetByName CV netname) + file = (outfile filename) + found = (makeTable "instances" nil) + n=0 + (foreach term net->allInstTerms + (when term->inst->libName!=TechLibName && !found[term->inst] + found[term->inst]=t + (fprintf file "%s\n" term->inst->name) + n++ + ) + ) + (close file) + n + ) + ) + +; move shapes and subcell pins to a different net +(defun RenameSelectedNet (to @key (CV (geGetEditCellView))) + (let (net connected n) + net = (MakeNet CV to) + (SelectConnectedWiring) + n=0 + + ; rename wires and contacts + (foreach obj (geGetSelSet) + (cond (obj->objType=="path" || + obj->objType=="rect" || + obj->objType=="polygon" + (when obj->net!=net + obj->net=nil + obj->net=net + n++) + ) + (obj->libName==TechLibName + term = (car obj->instTerms) + term->net=nil + term->net=net + n++) + ) + ) + + ; rename subcell pins + connected = (ConnectedSubcellPins CV (geGetSelSet)) + (foreach a connected + inst = (car a) + pin = (cadr a) + (foreach term (setof x inst->instTerms x->name==pin->net->name) + term->net=nil + term->net=net + n++ + ) + ) + n + ) + ) + +; Translate instance names to GDS2 +(defun TranslateInstanceNames (@key (CV (geGetEditCellView))) + (let (x instGds2Map) + x = (TranslateNames "gds2" ?CV CV) + instGds2Map = (cadr x) + (foreach inst (setof a CV->instances + (and a->libName!=TechLibName (length a->instTerms)>2)) + inst->name = instGds2Map[inst->name] + ) + ) + t + ) + +; Write CAST file from DFII. +(defun WriteCastSubcells (filename @key (CV (geGetEditCellView))) + (let (file x typeCastMap instCastMap nodeCastMap + pinCastMap pinCastMaps portMap castName terms + nodeName typeName portName portNameNew start) + (rexCompile "\\(\\]\\[\\)") ; use to translate subcell port names + + x = (TranslateNames "cast" ?CV CV) + typeCastMap = (car x) + instCastMap = (cadr x) + nodeCastMap = (caddr x) + + x = (TranslateNames "gds2" ?CV CV) + typeGds2Map = (car x) + instGds2Map = (cadr x) + nodeGds2Map = (caddr x) + + file = (outfile filename) + (fprintf file " subcells {\n") + + ; subcells + pinCastMaps = (makeTable "pinCastMaps" nil) + (foreach inst (setof a CV->instances + (and a->libName!=TechLibName (length a->instTerms)>2)) + typeName = typeCastMap[inst->cellName] + (fprintf file " %s %s()();\n" typeName inst->name) + pinCastMap = pinCastMaps[inst->master] + (unless pinCastMap + pinCastMap = (GetCastPinNameMap typeName) + pinCastMaps[inst->master]=pinCastMap + ) + ) + + ; nodes + (foreach net CV->nets + terms = (list) + + ; find pins + (when net->pins + castName = nodeCastMap[net->name] + terms = (cons castName terms) + ) + + ; find subcell terminals + (foreach term net->instTerms + inst = term->inst + pinCastMap = pinCastMaps[inst->master] + (when pinCastMap + portName = (rexReplace term->name "," -1) ; TODO: better + portNameNew = pinCastMap[portName] + (when portNameNew portName = portNameNew) + terms = (cons (sprintf nil "%s.%s" inst->name portName) terms) + ) + ) + + ; print connections + start = t + (when (length terms)>1 + (foreach name terms + (fprintf file (if start " " "\n =")) + start=nil + (fprintf file "%s" name) + ) + (fprintf file ";\n") + ) + ) + (fprintf file " }\n") + (close file) + ) + t + ) + +; utility to figure out the proper CAST name for pins +(defun GetCastPinNameMap (typeName) + (let (TEMP CAST_PATH cmd file line fields pinMap) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + CAST_PATH = (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + cmd = (sprintf nil "cast_query --cast-path=\"%s\" --max-heap-size=%dM --cell=\"%s\" --task=external_nodes=xr:im > \"%s/%s.pins\"" + CAST_PATH (nrGetMaxHeapSize) typeName TEMP typeName) + (shell cmd) + file = (infile (sprintf nil "%s/%s.pins" TEMP typeName)) + pinMap = (makeTable "pins" nil) + (gets line file) + (while (gets line file) + line = (StringUtilChompNewline line) + fields =(parseString line " ") + pinMap[(cadr fields)]=(car fields) + ) + (close file) + pinMap + ) + ) + +; clean TEMP directory +(defun CleanTempDir (@key (temp (ConfigFileGetValue TheCDSConfigTable "TEMP"))) + (shell (sprintf nil "rm -rf %s/*" temp)) + t + ) + +; Canonicalize pin names, always preferring port names +(defun NewCanonicalizePins () + (setShellEnvVar "NEW_CANONICALNESS_ALGORITHM=true") + (CleanTempDir) ; avoid incompatible cached files + (CanonicalizePins) + (CleanTempDir) ; avoid incompatible cached files + (setShellEnvVar "NEW_CANONICALNESS_ALGORITHM=false") + t + ) + +; delete connectivity information from shapes, contacts, and optionally subcells +(defun DeleteConnectivity (@key (CV (geGetEditCellView)) (subcells nil)) + (foreach shape CV->shapes shape->net=nil) + (foreach inst CV->instances + (when (or subcells inst->libName==TechLibName) + (foreach term inst->instTerms term->net=nil) + ) + ) + t + ) + +; Unconnect Vdd and GND pins for now +(defun DisconnectPowerPins (@key (CV (geGetEditCellView))) + (let (Vdd GND) + Vdd = (dbFindNetByName CV "Vdd") + GND = (dbFindNetByName CV "GND") + (dbDeleteObject Vdd) + (dbDeleteObject GND) + t + ) + ) + +; save a list of inst terms +(defun GetInstanceTerms (netname @key (CV (geGetEditCellView))) + (let (net l) + l = (list) + net = (dbFindNetByName CV netname) + (foreach term net->allInstTerms + (when term->inst->libName!=TechLibName + l = (cons (list term->inst->name term->name) l) + ) + ) + l + ) + ) + +; reconnect given a list of inst terms +(defun ConnectInstanceTerms (netname termList @key (CV (geGetEditCellView))) + (let (net inst term n) + net = (dbFindNetByName CV netname) + n=0 + (foreach pair termList + inst = (dbFindAnyInstByName CV (car pair)) + term = (car (setof x inst->instTerms x->name==(cadr pair))) + term->net=nil + term->net=net + n++ + ) + n + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/area.rul b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/area.rul new file mode 100644 index 0000000000..9fa5583237 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/area.rul @@ -0,0 +1,64 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +drcExtractRules( +layerDefs( "df2" + + ;leaf cell boundaries + prBound_leaf = layer( "prBoundary" type("drawing")) + + ;top level boundary + prBound_bound = layer( "prBoundary" type("boundary")) + + ;sub cell boundaries + prBound_sub = layer( "prBoundary" type("label")) + + prBound_text = textToPin( "prBound" ) + +) ; layerDefs complete + +geomConnect( + via( prBound_leaf prBound_bound prBound_sub ) + label( prBound_text prBound_bound ) +) + + +size = 19.2 +leaf = geomOr( prBound_leaf ) +merge = geomSize( geomSize( prBound_leaf size ) -size ) +mid_bound = geomOr( prBound_bound ) +subcell = geomOr( prBound_sub ) + + +geomStamp( leaf prBound_leaf ) +geomStamp( merge prBound_leaf ) +geomStamp( subcell prBound_sub ) +geomStamp( mid_bound prBound_bound ) + +; leaf +extractDevice( "leaf" leaf leaf("X") flagMalformed ) +leaf_area = measureParameter( area ( leaf ) 1.0 ) +nameParameter( leaf_area "area" ) + +; bloat/shrunk leaf cells +extractDevice( "merge" merge merge("X") flagMalformed ) +merge_area = measureParameter( area ( merge ) 1.0 ) +nameParameter( merge_area "area" ) + +;top level boundary +extractDevice( "mid_bound" mid_bound mid_bound("X") flagMalformed ) +mid_bound_area = measureParameter( area ( mid_bound ) 1.0 ) +nameParameter( mid_bound_area "area" ) + +;merged mid level boundaries +extractDevice( "subcell" subcell subcell("X") flagMalformed ) +subcell_area = measureParameter( area ( subcell ) 1.0 ) +nameParameter( subcell_area "area" ) + + + + + +) ; drcExtractRules Complete diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/assura.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/assura.il new file mode 100644 index 0000000000..b3e8509abc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/assura.il @@ -0,0 +1,880 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun AssuraGetAreas ( CellView + LPP + LeafCellPredicate ) + "Calculates +
    +
    LeafArea
    The area of the union of all leaf cell bounding boxes
    +
    MergeArea
    The area of the bloat/shrunk leaf cell bounding boxes.
    +
    MidBoundArea
    The area of the top level prBoundary.
    +
    SubCellArea
    The area of the union of all subcell bounding boxes
    +
    + Uses with area.rul. + " + + (let ( + ( TechFileDBObj ( techGetTechFile CellView ) ) ) + (let ( + ( TempDirForThisRun + ( makeTempFileName + ( sprintf + nil + "%sASSURA.XXXXXX" + ( ddGetStartup "" ) + ) ) ) + ) + + ( createDir TempDirForThisRun ) + + (let ( + ( TempLibrary + ( LibCreateTempLibrary + TechFileDBObj + "lib" + TempDirForThisRun + ) ) + ( Rects + ( MidLevelGetRects + CellView + LPP + LeafCellPredicate ) ) + ( BoundShape + ( PinUtilFindPRBoundShape + LPP + CellView ) ) + ( RunAssuraScript + ( sprintf + nil + "%s/share/script/perl/ve/front-end/vfe" + ( PackageGetPackageRoot ) ) ) + ( CdsLibFile ( ddGetStartup "cds.lib" ) ) + ) + (let ( + ( TempCellView + ( dbOpenCellViewByType + TempLibrary + ( getq CellView cellName ) + "area_calc" + "maskLayout" + "w" ) ) ) + + ;leaf cells + ( foreach Rect Rects + ( dbCreateRect TempCellView ( list "prBoundary" "drawing" ) + Rect ) ) + ;subcells + ( foreach Rect ( getq CellView instances )~>bBox + ( dbCreateRect TempCellView ( list "prBoundary" "label" ) + Rect ) ) + ;boundary + (when BoundShape ( dbCopyFig BoundShape TempCellView )->lpp = + ( list "prBoundary" "boundary" ) + ) + + ( dbSave TempCellView ) + + (let ( + ( AssuraRuleFile ( sprintf nil "%s/share/skill/layout/assura/area.rul" ( PackageGetPackageRoot ) ) ) + ( AssuraRunCmd ( sprintf nil "%s/assura.cmd" TempDirForThisRun ) ) + ( AssuraRunLog ( sprintf nil "%s/assura.log" TempDirForThisRun ) ) + ( Netlist ( sprintf nil "%s/netlist" TempDirForThisRun ) ) + ( AreaLog ( sprintf nil "%s/area" TempDirForThisRun ) ) + ) + (let ( + ( AssuraRunCmdOut + ( outfile AssuraRunCmd ) ) ) + + ( fprintf AssuraRunCmdOut "#!/bin/bash\n" ) + ( fprintf + AssuraRunCmdOut + "%s VerificationType=AssuraLvs \"RunName=%s\" \"CdsLib=%s\" \"Layout\ +Cell=%s\" \"LayoutLibrary=%s\" \"LayoutView=%s\" \"RuleFile=%s\" \"WorkingDir=%s\"" + RunAssuraScript + ( getq TempCellView cellName ) + CdsLibFile + ( getq TempCellView cellName ) + ( getq TempCellView libName ) + ( getq TempCellView viewName ) + AssuraRuleFile + TempDirForThisRun + ) + + ( close AssuraRunCmdOut ) + ( shell ( sprintf nil "chmod u+x %s" AssuraRunCmd ) ) + ( system ( sprintf + nil + "%s&>%s" + AssuraRunCmd + AssuraRunLog ) ) + + (let ( + ( LeafArea 0.0 ) + ( MidBoundArea 0.0 ) + ( MergeArea 0.0 ) + ( SubCellArea 0.0 ) + ( Area 0.0 ) + ( Cmd + ( sprintf + nil + "vldbToSpice %s/%s.ldb %s; cat %s" + TempDirForThisRun + ( getq TempCellView cellName ) + Netlist + Netlist + ) ) + ( ReadLine t ) + ) + (let ( + ( CID + ( ipcBeginProcess Cmd ) ) ) + (ipcWaitForProcess CID) + (unless ( ipcIsAliveProcess CID ) + (error "assura failed" ) ) + ( rexCompile ".* \\(.*\\) area=\\(.*\\)" ) + (while ReadLine + ReadLine = ( StringUtilReadLine CID 10 ) + (when ReadLine + ( rexExecute ReadLine ) + ( println ( rexSubstitute "\\1" ) ) + (cond ( + ( equal ( rexSubstitute "\\1" ) "leaf" ) + LeafArea = LeafArea + + ( atof ( rexSubstitute "\\2" ) ) ) + ( + ( equal ( rexSubstitute "\\1" ) "mid_bound" ) + MidBoundArea = MidBoundArea + + ( atof ( rexSubstitute "\\2" ) ) ) + ( + ( equal ( rexSubstitute "\\1" ) "subcell" ) + SubCellArea = SubCellArea + + ( atof ( rexSubstitute "\\2" ) ) ) + ( + ( equal ( rexSubstitute "\\1" ) "merge" ) + MergeArea = MergeArea + + ( atof ( rexSubstitute "\\2" ) ) ) ) ) ) +; ( shell ( sprintf nil "rm -rf %s" TempDirForThisRun ) ) + + ( list LeafArea MergeArea MidBoundArea SubCellArea ) + ) ) ) ) ) ) ) ) ) + + + + +(defun AssuraCopyShapesFromCellView ( SourceCellView + TargetCellView + ShapePredicate ) + "Copies all shapes in SourceCellView that satisfy ShapePredicate to TargetCellView" + ( foreach Shape ( getq SourceCellView shapes ) + (if ( or ( null ShapePredicate ) + ( apply ShapePredicate ( list Shape ) ) ) + ( dbCopyFig Shape TargetCellView ) ) ) ) + + + +(defun AssuraWriteOutFileRSF ( RSFFile + LibName + WorkingDir + TechFile + Mode + AssuraLayerMappings ) + "Writes an .rsf include file, which instructs assura to write an output database in WorkingDir using the TechFile filename, with assura-dfII layer mappings defined as in AssuraLayerMappings(see for a description of AssuraLayerMappings)." + (let ( + ( OutPort ( outfile RSFFile ) ) ) + + ( fprintf + OutPort + "avParameters( ?outputErrorLib modifyExistingLibrary ?flagMalformed nil ?ignoreMissingOutLayer t )\n" ) + ( fprintf + OutPort + "outFile(\"DF2\" \"%s\" \"%s\" \"%s\" %s %s )\n" + LibName + WorkingDir + TechFile + Mode + ( AssuraMakeOutLayersStringFromLayerMappings + AssuraLayerMappings ) ) + + ( close OutPort ) + ) ) + + +(defun AssuraMakeOutLayersStringFromLayerMappings ( AssuraLayerMappings ) + "Given a list of pairs ((assuraLayer LPP) ...), creates an outLayer string for use in an .rsf file. This string tells assura how to map between internal layers and dfII/gdsII layers in the outfile database." + (let ( + ( Result "" ) ) + ( foreach + AssuraLayerMapping + AssuraLayerMappings + (let ( + ( AssuraLayerName ( car AssuraLayerMapping ) ) + ( TargetLPP ( cadr AssuraLayerMapping ) ) ) + (let ( + ( TargetLayerName ( car TargetLPP ) ) + ( TargetLayerPurpose ( cadr TargetLPP ) ) ) + ( setq Result ( sprintf + nil + "outLayer( %s \"%s\" type( \"%s\" ) ) %s" + AssuraLayerName + TargetLayerName + TargetLayerPurpose + Result ) ) ) ) ) + Result ) ) + + +(defun AssuraPrepareCellForProcessing ( CellView TempLibName CellMappings ) + "Copies over all subcells of Cellview to temporary library called TempLibName according to CellMappings: a list of pairs (((srclibname srccellname srcviewname)->destcellname)...), and updates the instances in CellView accordingly.
    This is so assura can reference these cells in the output database using outfile. See for the reverse process." + (let ( + ( CellViewCopy ( dbCopyCellView + CellView + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) + nil + nil + t ) ) ) + ( dbSave CellViewCopy ) + ) + + + ( foreach + CellMapping + CellMappings + (let ( + ( SrcCellTripple ( car CellMapping ) ) + ( TargetCellName ( cadr CellMapping ) ) ) + (let ( + ( SrcLibName ( car SrcCellTripple ) ) + ( SrcCellName ( cadr SrcCellTripple ) ) + ( SrcViewName ( caddr SrcCellTripple ) ) ) + (let ( + ( SrcCellViewDDObj ( ddGetObj SrcLibName SrcCellName SrcViewName ) ) ) + (if ( and SrcCellViewDDObj ( getq SrcCellViewDDObj files ) ) + (let ( + ( CurrSrcCellView ( dbOpenCellViewByType + SrcLibName + SrcCellName + SrcViewName + nil + "r" ) ) ) + (let ( + ( CellViewCopy + ( dbCopyCellView + CurrSrcCellView + TempLibName + TargetCellName + "layout" + nil + nil + t ) ) ) + (if CellViewCopy + (let () + ( dbSave CellViewCopy ) + ( dbClose CellViewCopy ) + ) + ( printf + "Could not copy %L %L %L to %L %L %L.\n" + SrcLibName + SrcCellName + SrcViewName + TempLibName + TargetCellName + "layout" ) ) ) ) + ( printf "%L %L %L does not exist.\n" SrcLibName SrcCellName SrcViewName ) ) ) ) ) ) + nil ) + + +(defun AssuraFixGeneratedInstances ( CellView + TempLibName + CellMappings ) + "Changes instantiations in CellView according to the inverse of CellMappings. This will reverse . Apply this to the cellview that assura writes with the outfile function." + (let ( + ( MappingsTable ( makeTable "foo" nil ) ) ) + ( foreach + CellMapping + CellMappings + (let ( + ( SrcCellTripple ( car CellMapping ) ) + ( TargetCellName ( cadr CellMapping ) ) ) + (let ( + ( SrcLibName ( car SrcCellTripple ) ) + ( SrcCellName ( cadr SrcCellTripple ) ) + ( SrcViewName ( caddr SrcCellTripple ) ) ) + (let ( + ( SrcCellViewDDObj ( ddGetObj SrcLibName SrcCellName SrcViewName ) ) ) + (when ( and SrcCellViewDDObj ( getq SrcCellViewDDObj files ) ) + (let ( + ( SrcCellView ( dbOpenCellViewByType + SrcLibName + SrcCellName + SrcViewName + nil + "r" ) ) ) + ( setarray + MappingsTable + ( list TempLibName TargetCellName "layout" ) + SrcCellView ) ) ) ) ) ) ) + ( foreach + Instance + ( getq CellView instances ) + (let ( + ( NewMaster ( arrayref + MappingsTable + ( list + ( getq Instance libName ) + ( getq Instance cellName ) + "layout" ) ) ) ) + (when NewMaster + ( dbSetq Instance NewMaster master ) ) ) ) ) ) + +(defun AssuraRunDRC ( CellView + AssuraRuleFile + AssuraSets + ScratchDirectory ;path must be < 255 characters + OutputDirectory + ) + "Run's assura DRC with the AssuraRuleFile on CellView. Uses the vfe. Returns t if DRC passes, and nil otherwise." + (let ( + ( RunAssuraScript + ( sprintf + nil + "%s/share/script/perl/ve/front-end/vfe" + ( PackageGetPackageRoot ) ) ) + ( CdsLibFile ( ddGetStartup "cds.lib" ) ) + ( TempDirForThisRun + ( makeTempFileName + ( sprintf + nil + "%s/DRC.XXXXXX" + ScratchDirectory ) ) ) ) + ( createDir TempDirForThisRun ) + (let ( + ( AssuraRunCmd ( sprintf nil "%s/assura.cmd" TempDirForThisRun ) ) + ( AssuraRunLog ( sprintf nil "%s/assura.log" TempDirForThisRun ) ) + ) + (let ( + ( AssuraRunCmdOut + ( outfile AssuraRunCmd ) ) ) + + ( fprintf AssuraRunCmdOut "#!/bin/bash\n" ) + ( fprintf + AssuraRunCmdOut + "%s VerificationType=AssuraDrc \"RunName=%s\" \"CdsLib=%s\" \"LayoutCell=%s\" \"LayoutLibrary=%s\" \"LayoutView=%s\" \"RuleFile=%s\" \"WorkingDir=%s\" %s" + RunAssuraScript + ( getq CellView cellName ) + CdsLibFile + ( getq CellView cellName ) + ( getq CellView libName ) + ( getq CellView viewName ) + AssuraRuleFile + TempDirForThisRun + ( StringUtilPrefix + "AssuraSet.=" + AssuraSets ) ) + + ( close AssuraRunCmdOut ) + ( shell ( sprintf nil "chmod u+x %s" AssuraRunCmd ) ) + + (let ( + ( AssuraRunPID + ( ipcBatchProcess + AssuraRunCmd + "" + AssuraRunLog ) ) ) + ( ipcWait AssuraRunPID ) + (let ( + ( AssuraRunExitStatus + ( ipcGetExitStatus AssuraRunPID ) ) ) + ;clean up + ( shell ( sprintf + nil + "mkdir -p %s; cp -rf %s/* %s; rm -rf %s" + OutputDirectory + TempDirForThisRun + OutputDirectory + TempDirForThisRun ) ) + ( equal AssuraRunExitStatus 0 ) + ) ) ) ) ) ) + +(defun AssuraRunLVS ( CellView + ExtractRuleFile + AssuraSets + BindFile + CompareFile + IncludeFile + SchematicFile + ScratchDirectory ;path must be < 255 characters + OutputDirectory ) + "Run's assura LVS with the ExtractRuleFile/CompareFile/BindFile/LVS Include File on CellView vs CDL SchematicFile. Uses the vfe. Returns t if LVS passes, and nil otherwise." + (let ( + ( RunAssuraScript + ( sprintf + nil + "%s/share/script/perl/ve/front-end/vfe" + ( PackageGetPackageRoot ) ) ) + ( CdsLibFile ( ddGetStartup "cds.lib" ) ) + ( TempDirForThisRun ( makeTempFileName + ( sprintf + nil + "%s/LVS.XXXXXX" + ScratchDirectory ) ) ) ) + ( createDir TempDirForThisRun ) + (let ( + ( AssuraRunCmd ( sprintf nil "%s/assura.cmd" TempDirForThisRun ) ) + ( AssuraRunLog ( sprintf nil "%s/assura.log" TempDirForThisRun ) ) + ) + (let ( + ( AssuraRunCmdOut + ( outfile AssuraRunCmd ) ) ) + + ( fprintf AssuraRunCmdOut "#!/bin/bash\n" ) + ( fprintf + AssuraRunCmdOut + "%s VerificationType=AssuraLvs \"RunName=%s\" \"CdsLib=%s\" \"LayoutCell=%s\" \"LayoutLibrary=%s\" \"LayoutView=%s\" \"RuleFile=%s\" \"CompareFile=%s\" \"AssuraRsfInclude=%s\" \"WorkingDir=%s\" \"BindingFile=%s\" \"SchematicFile=%s\" %s" + RunAssuraScript + ( getq CellView cellName ) + CdsLibFile + ( getq CellView cellName ) + ( getq CellView libName ) + ( getq CellView viewName ) + ExtractRuleFile + CompareFile + IncludeFile + TempDirForThisRun + BindFile + SchematicFile + ( StringUtilPrefix + "AssuraSet.=" + AssuraSets ) + ) + + ( close AssuraRunCmdOut ) + ( shell ( sprintf nil "chmod u+x %s" AssuraRunCmd ) ) + (let ( + ( AssuraRunPID + ( ipcBatchProcess + AssuraRunCmd + "" + AssuraRunLog ) ) ) + ( ipcWait AssuraRunPID ) + (let ( + ( AssuraRunExitStatus + ( ipcGetExitStatus AssuraRunPID ) ) ) + ;clean up + ( shell ( sprintf + nil + "mkdir -p %s; cp -rf %s/* %s; rm -rf %s" + OutputDirectory + TempDirForThisRun + OutputDirectory + TempDirForThisRun ) ) + ( equal AssuraRunExitStatus 0 ) ) ) ) ) ) ) + + +(defun AssuraRunAssuraLayerProcessor ( SrcCellView + TargetLibraryName + TargetCellName + TargetViewName + AssuraRuleFile + ScratchDirectory ;path must be < 255 characters + AssuraLayerMappings + CellMappings + @key + ( AssuraSets nil ) + ( LeaveMess nil ) + ( Area nil ) + ( NoPCells nil ) + ( Promote nil ) + ( CustomFill nil ) + ( AssuraRunLog "/dev/null" ) + ( allbloat nil ) + ) +" +
      +
    1. copies all instances to a temporary library. See .
    2. +
    3. dumps the binary tech file to an ascii tech file for assura to use
    4. +
    5. optionally defines a cds.lib with gates and stacks replaced with gates-fake and stacks-fake libraries
    6. +
    7. defines an included .rsf file with given assura layer-dfII LPP mappings
    8. +
    9. vfe with area.rul
    10. +
    11. Do some postprocessing on mosaics/instances. See dependencies.
    12. +
    +" +(let ( + ( RunAssuraScript + ( sprintf + nil + "%s/share/script/perl/ve/front-end/vfe" + ( PackageGetPackageRoot ) ) ) + ( CdsLibFile ( ddGetStartup "cds.lib" ) ) + ( TechFileDBObj ( techGetTechFile SrcCellView ) ) + ( TempDirForThisRun + ( makeTempFileName + ( sprintf + nil + "%s/ASSURA.XXXXXX" + ScratchDirectory ) ) ) + ) + ( createDir TempDirForThisRun ) + + (let ( + ;munge the input and put all cells to be added in here + ( TempInputLibName + ( LibCreateTempLibrary + TechFileDBObj + ( sprintf nil "ASSURA_%s" ( getq SrcCellView cellName ) ) + TempDirForThisRun ) ) + ;munge the output to reference the original cells + ( TempOutputLibName + ( LibCreateTempLibrary + TechFileDBObj + ( sprintf nil "ASSURA_%s" ( getq SrcCellView cellName ) ) + TempDirForThisRun + ) ) + ( RSFIncludeFile + ( sprintf nil "%s/outfile.rsf" TempDirForThisRun ) ) + ( AsciiDumpOfTechFile + ( sprintf nil "%s/techfile.txt" TempDirForThisRun ) ) + ( OutputLibPath nil ) + ( AssuraRunCmd ( sprintf nil "%s/assura.cmd" TempDirForThisRun ) ) + ) + + ( setq OutputLibPath + ( PathDirName + ( car ( ddGetObj TempOutputLibName )->files~>readPath) ) ) + + ( tcDumpTechFile TechFileDBObj AsciiDumpOfTechFile ( list "layerDefinitions" "layerRules" "physicalRules" "lxRules") ) + + (when NoPCells + (let ( + ( NoPCellCdsLibFile + ( makeTempFileName + ( sprintf nil "%s/cds.lib.XXXXXX" TempDirForThisRun ) ) ) ) + (let ( + ( NoPCellCdsLibPort + ( outfile NoPCellCdsLibFile ) ) + ( GateFakeDir + ( PathDirName + ( car ( ddGetObj "gate-fake" )->lib->files )->readPath ) ) + ( StackFakeDir + ( PathDirName + ( car ( ddGetObj "stack-fake" )->lib->files )->readPath ) ) + ) + ( fprintf NoPCellCdsLibPort + "SOFTINCLUDE %s\n" + CdsLibFile ) + ( fprintf NoPCellCdsLibPort + "UNDEFINE gate\n" ) + ( fprintf NoPCellCdsLibPort + "UNDEFINE stack\n" ) + ( fprintf NoPCellCdsLibPort + "UNDEFINE gate#2dfake\n" ) + ( fprintf NoPCellCdsLibPort + "UNDEFINE stack#2dfake\n" ) + ( fprintf NoPCellCdsLibPort + "DEFINE gate %s\n" GateFakeDir ) + ( fprintf NoPCellCdsLibPort + "DEFINE stack %s\n" StackFakeDir ) + ( close NoPCellCdsLibPort ) + + ( setq CdsLibFile NoPCellCdsLibFile ) + ) ) ) + + ( AssuraWriteOutFileRSF + RSFIncludeFile + TempOutputLibName + TempDirForThisRun + AsciiDumpOfTechFile + (if ( or CellMappings Promote ) + "" + "flat" ) + AssuraLayerMappings ) + + + ( AssuraPrepareCellForProcessing + SrcCellView TempInputLibName CellMappings ) + + + (let ( tmpCellView ) + if( allbloat then + ; what is this? Why is this hard coded as "abstract"? + tmpCellView=nrOpenCellViewWritable( TempInputLibName ( getq SrcCellView cellName ) "abstract" ) + if( tmpCellView then + printf( "Deleting all instances of %s %s %s\n" tmpCellView~>libName tmpCellView~>cellName tmpCellView~>viewName) + foreach( inst tmpCellView->instances + if( ! inst~>isShape then + ;printf("Deleting %s %s\n" inst~>baseName inst~>cellName ) ; too much spam + if(inst~>objType!="mosaicInst" + dbDeleteObject( inst ) + ;dbDeleteObject( inst~>mosaic ) ; probably should not be deleting mosaics + ) + ) + ) + dbSave( tmpCellView ) + dbClose( tmpCellView ) + else + printf("Warning: Cannot open temporary cell for modification\n") + ) + ) + ) + + ( printf "Starting assura\n" ) + + (let ( + ( AssuraRunCmdOut + ( outfile AssuraRunCmd "w" ) ) + ) + + ( fprintf AssuraRunCmdOut "#!/bin/bash\n" ) + ( fprintf + AssuraRunCmdOut + "%s VerificationType=AssuraDrc \"RunName=%s\" \"CdsLib=%s\" \"LayoutCell=%s\" \"LayoutLibrary=%s\" \"LayoutView=%s\" \"RuleFile=%s\" OutFile=1 \"AssuraRsfInclude=%s\" \"WorkingDir=%s\" \"Area=%s\" %s" + RunAssuraScript + ( getq SrcCellView cellName ) + CdsLibFile + ( getq SrcCellView cellName ) + TempInputLibName + ( getq SrcCellView viewName ) + AssuraRuleFile + RSFIncludeFile + TempDirForThisRun + (if Area + ( sprintf nil "%f:%f,%f:%f" + ( caar Area ) + ( cadar Area ) + ( caadr Area ) + ( cadadr Area ) ) + "all" ) + ( StringUtilPrefix + "AssuraSet.=" + AssuraSets ) ) + + ( close AssuraRunCmdOut ) + ( shell + ( sprintf nil "chmod u+x %s" AssuraRunCmd ) ) + ;ipcBeginProcess was dying mysteriously, so i use 'system' now + ( system ( sprintf + nil + "%s&>%s" + AssuraRunCmd + AssuraRunLog ) ) + + ; make sure the library manager doesn't bitch at you + ( ddUpdateLibList ) + ( ddCreateLib TempOutputLibName + OutputLibPath ) + + ( printf "Done with assura\n" ) + + (let ( + ( ResultCellDDObj + ( ddGetObj + TempOutputLibName + ( getq SrcCellView cellName ) + ) ) ) + (if ResultCellDDObj + (let ( + ( ResultCellViewDDObj + ( car ( getq ResultCellDDObj views ) ) ) ) + (if ( and + ResultCellViewDDObj + ( getq ResultCellViewDDObj files ) ) + (let ( + ( ResultCellView ( dbOpenCellViewByType + TempOutputLibName + ( getq SrcCellView cellName ) + ( getq ResultCellViewDDObj name ) + nil + "a" ) ) ) + (let ( + ( TargetCellView ( dbCopyCellView + ResultCellView + TargetLibraryName + TargetCellName + TargetViewName + nil + nil + t ) ) ) + + (if TargetCellView + (let () + ( ddUpdateLibList ) + ( AssuraFixGeneratedInstances + TargetCellView + TempOutputLibName + CellMappings ) + + (when CustomFill + ( AssuraFixCustomFill + TargetCellView + AssuraLayerMappings + CellMappings + TargetLibraryName ) ) + + ( dbSave TargetCellView ) + + ( dbPurge TargetCellView ) + ( dbPurge ResultCellView ) + (unless LeaveMess + (when ( ddGetObj TempInputLibName ) + ( ddDeleteObj + ( ddGetObj TempInputLibName ) ) ) + (when ( ddGetObj TempOutputLibName ) + ( ddDeleteObj + ( ddGetObj TempOutputLibName ) ) ) + ( shell ( sprintf nil "rm -rf %s" TempDirForThisRun ) ) ) + nil ) + ( sprintf + nil + "Unable to copy result from %L to %L. %s" + ( list + TempOutputLibName + ( getq SrcCellView cellName ) + ( getq ResultCellViewDDObj name ) ) + ( list TargetLibraryName TargetCellName TargetViewName ) + TempDirForThisRun ) ) ) ) + ( sprintf + nil + "Result cell %L has no views. %s" + ( list TempOutputLibName ( getq SrcCellView cellName ) ) + TempDirForThisRun ) ) ) + ( sprintf + nil + "Result cell %L does not exist. %s" + ( list TempOutputLibName ( getq SrcCellView cellName ) ) + TempDirForThisRun ) ) ) + ) ) ) ) + + +(defun AssuraFixCustomFill ( CellView + AssuraLayerMappings + CellMappings + LibName ) + "This function implements post-processing on custom fill cells(i.e. cells with shapes/instances created with assura's generateRectangle/generateCustomFill). Currently, it just replaces generateRectangle shapes with instances. See " + ;just create the mappings from LPP->libcellview and use our friendly + ;neighborhood helper function + (let ( + ( Done ( makeTable `foo nil ) ) + ( LayerToLPP ( makeTable `foo nil ) ) + ( Mappings ( makeTable `foo nil ) ) ) + + ( foreach Mapping AssuraLayerMappings + ( setarray LayerToLPP ( car Mapping ) ( cadr Mapping ) ) ) + + ( foreach Mapping CellMappings + ( setarray Done ( cadr ( car Mapping ) ) t ) + ( setarray Mappings + ( arrayref LayerToLPP ( cadr Mapping ) ) + ( car Mapping ) ) ) + + ( AssuraFixCustomFillImpl + CellView + Mappings + Done + LibName ) ) ) + +(defun AssuraFixCustomFillImpl ( CellView + Mappings + Done + LibName + ) + "Recursive helper for " + (cond ( + ( arrayref Done CellView->cellName ) + ) + ( + t + ( printf "Doing %s\n" CellView->cellName ) + ( setq + CellView + (cond ( + ( equal LibName CellView->libName ) + CellView ) + ( + ( dbCopyCellView + CellView + LibName + CellView->cellName + CellView->viewName + nil nil t ) ) ) ) + + ( dbReopen CellView "a" ) + + ;check for crappiness + ( foreach Mosaic CellView->mosaics + ( foreach Orient Mosaic->tileArray + (when ( not ( equal Orient "R0" ) ) + (error ( sprintf nil "orient %L in %L %L\n" + Orient + CellView->cellName + Mosaic->xy ) ) ) ) ) + ;recurse + ( foreach + Instance + ( append + CellView->instances + ( ListNonDestructiveMapCan + (lambda ( Mosaic ) + Mosaic->instanceList ) + CellView->mosaics ) ) + (when ( and Instance->orient + ( not ( equal Instance->orient "R0" ) ) ) + ( printf ( sprintf nil "orient %L %L in %L\n" + Instance->orient + CellView->cellName + Instance->xy + ) ) ) + (when Instance->master + ( dbSetq + Instance + ( AssuraFixCustomFillImpl + Instance->master + Mappings + Done + LibName ) + master ) ) + ) + + ;do some work + ( AssuraCustomFillConvertShapes CellView Mappings ) + ( dbSave CellView ) + ( setarray Done CellView->cellName CellView ) + + CellView ) ) ) + +(defun AssuraCustomFillConvertShapes ( CellView Mappings ) + "converts shapes into instances according to Mappings:((LPP->libcellview)...)." + ( foreach + LPP + CellView->lpps + (let ( + ( LibCellView + ( arrayref Mappings ( list LPP->layerName LPP->purpose ) ) ) ) + (when LibCellView + (let ( + ( Master + ( dbOpenCellViewByType + ( car LibCellView ) + ( cadr LibCellView ) + ( caddr LibCellView ) + nil + "r" ) ) ) + (cond ( + Master + ( foreach + Shape + LPP->shapes + ( dbCreateInst + CellView + Master + nil + ( car Shape->bBox ) + "R0" ) + ( dbDeleteObject Shape ) + ) ) + ( + ( printf + "Couldn't load %L for %L\n" + LibCellView ( list LPP->layerName LPP->purpose ) ) ) ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/drc.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/drc.il new file mode 100644 index 0000000000..2d71972f91 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/drc.il @@ -0,0 +1,90 @@ +; Batch and user friendly wrapper to run DRC. By default runs full +; DRC rule deck. Or change the ?rules open to "m2-8", "frc", +; "proteus_frc", "fillCheck", "keepoutCheck", "powerCheck", +; "wellnotch" to run smaller decks. + +; Run DRC +(defun AssuraDRC + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (rules nil) ; string to pick rule deck, or nil for all default rules + (dir "drc") ; run directory + (doDensity nil) ; do density checks + ) + (let (TEMP PDKRoot AssuraRuleFile AssuraSets status) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + PDKRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + AssuraRuleFile = (if rules (sprintf nil "%s/share/Fulcrum/drc/%s.rul" PDKRoot rules) + (sprintf nil "%s/share/Fulcrum/assura/drc.rul" PDKRoot)) + (when !(isFile AssuraRuleFile) (error "Can't read %s\n" AssuraRuleFile)) + AssuraSets = nil + (unless doDensity AssuraSets = (cons "SKIP_DENSITY" AssuraSets)) + (dbSave CV) + status = (AssuraRunDRC CV AssuraRuleFile AssuraSets TEMP dir) + (printf "DRC: %s\n" (if status "PASS" "FAIL")) + status + ) + ) + +; Shortcut for FRC +(defun AssuraFRC + (@key (CV (geGetEditCellView))) + (AssuraDRC ?CV CV ?rules "frc" ?dir "frc") + ) + +; Run DRC on a scratch cell that overlays an abstract view +(defun AssuraCheckAbstract + (@key (CV (geGetEditCellView)) ; specify CellView + (views (list "abstract_edit" "abstract")) ; overlay views, use first one found + (rules "abstractCheck") ; string to pick rule deck + (dir "drc") ; run directory + ) + (let (scratchCV overlayCV status) + + ; copy CV to scratch_overlay view + (when CV->viewName=="scratch_overlay" (error "Can't run from scratch_overlay view\n")) + scratchCV = (dbCopyCellView CV CV->libName CV->cellName "scratch_overlay" nil nil t) + (unless scratchCV (error "Can't write scratch %s %s\n" CV->cellName CV->viewName)) + + ; copy shapes from abstract view + (foreach view views + (unless overlayCV + overlayCV = (nrOpenCellViewReadable CV->libName CV->cellName view) + ) + ) + (unless overlayCV (error "Can't read %s %s overlay view\n" CV->libName CV->cellName)) + (foreach shape overlayCV->shapes + (dbCopyFig shape scratchCV (list 0:0 "R0")) + ) + + ; add power grid if it exists + (AddPowerGridInstance ?CV scratchCV) + + ; run Assura + status = (AssuraDRC ?CV scratchCV ?rules rules ?dir dir) + + ; delete scratch view if it PASS'es + (when status + (ddDeleteObj (ddGetObj scratchCV->libName scratchCV->cellName scratchCV->viewName)) + ) + + ; return status + status + ) + ) + +; Check abstracts of all routed subcells +(defun AssuraCheckAbstracts + (@key (CV (geGetEditCellView)) ; specify CellView + (views (list "abstract_edit" "abstract")) ; overlay views, use first one found + (rules "abstractCheck") ; string to pick rule deck + (dir "drc") ; run directory + ) + (let (s (status t)) + (foreach subCV (ListLefSubcells ?CV CV) + (printf "Checking %s... " subCV->cellName) + s = (AssuraCheckAbstract ?CV subCV ?views views ?rules rules ?dir dir) + status = (and status s) + ) + status + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/lvs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/lvs.il new file mode 100644 index 0000000000..390a462c94 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/assura/lvs.il @@ -0,0 +1,54 @@ +; Batch and user friendly wrappers to create CDL and run LVS. + +; Run LVS +(defun AssuraLVS + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (RegenerateCDL nil) ; force regeneration of CDL + ) + (let (TEMP PDKRoot SchematicFile status + LVSRuleFile LVSBindFile LVSCompareFile LVSIncludeFile) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + PDKRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + LVSRuleFile = (sprintf nil "%s/share/Fulcrum/assura/extract.rul" PDKRoot) + LVSBindFile = (sprintf nil "%s/share/Fulcrum/assura/bind.rul" PDKRoot) + LVSCompareFile = (sprintf nil "%s/share/Fulcrum/assura/compare.rul" PDKRoot) + LVSIncludeFile = (sprintf nil "%s/share/Fulcrum/assura/LVSinclude.rsf" PDKRoot) + SchematicFile = (CreateCDL ?CV CV ?RegenerateCDL RegenerateCDL) + (dbSave CV) + status = (AssuraRunLVS CV + LVSRuleFile + (list "EXPAND") + LVSBindFile + LVSCompareFile + LVSIncludeFile + SchematicFile + TEMP + "lvs") + (printf "LVS: %s\n" (if status "PASS" "FAIL")) + status + ) + ) + +; Generate CDL +(defun CreateCDL + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (RegenerateCDL t) ; force regeneration of CDL + (maxheap (nrGetMaxHeapSize)) ; max-heap-size + ) + (let (TEMP CAST_PATH CDLFile CMD status) + CAST_PATH = (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + CDLFile = (sprintf nil "cdl/%s.cdl" CV->cellName) + (when (or !(isFile CDLFile) RegenerateCDL) + CMD = (sprintf nil + "%s/cast2cdl --cast-path=%s --cell=%s --cadence-name --output=%s --max-heap-size=%dM --name-map=%s/share/Fulcrum/lve/transistor.map --process-dependent-name --64" + (PackageGetBinRoot) + CAST_PATH + CV->cellName + CDLFile maxheap + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT")) + status = (shell CMD) + (when !status (error "Unable to generate %s\n" CDLFile)) + ) + CDLFile + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus.il new file mode 100644 index 0000000000..4a56641d63 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus.il @@ -0,0 +1,1933 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; global defaults +defchan_modtime = 0 ; store latest modtime of dfII/defchan.il +defchan_patterns = nil ; global list of patterns for DrawTracks +Startloadwires = 0 +wires_modtime = makeTable("wires" 0) + +(defvar ShieldNet list("GND" "VDD" "AVDD" "AGND")) + +(defun BusDefaults () + busContacts = t ; draw the contacts + busKeepout = nil ; draw keepout instead of metal + busTopMetal = nil ; use top metal in both directions + busContactNum = 1 ; unique number for contact instance names + busGuideInstName = "buswires" ; global default guideInstName + busPatterns = nil ; list of additional name->pattern pairs + busUseDefaultPatterns = t ; draw the standard patterns from the PDK + bundled_channels = nil ; for bundled channel routing in fat.il + bundled_bottom_layer = 3 ; bottom layer for bundled channel routing + bundled_top_layer = 7 ; top layer for bundled channel routing + delete_redundant_pins = nil ; DeleteRedundantPins or just warn about them + t + ) +(BusDefaults) + +; return reference to guide instance given instance name +; if inst already defined, use that +(defun GetGuideInst (inst name @key (CV (geGetEditCellView))) + (cond (inst!=nil inst) + (name!=nil + (dbFindAnyInstByName CV name)) + (busGuideInstName!=nil + (dbFindAnyInstByName CV busGuideInstName)) + ) + ) + +; simple heuristic to check for guide instances or views +(defun IsGuideInst (inst) + (let (part) + part = (car (last (parseString inst->cellName "_"))) + (or part=="buswires" inst->name=="buswires" + part=="autobuswires" inst->name=="autobuswires") + ) + ) + +(defun EditGuideInstInPlace () + (let (cell) + cell=(GetGuideInst nil busGuideInstName) + (geDeselectAllFig) + (geSelectObject cell) + (leHiEditInPlace) +)) + +(defun EditAutoGuideInstInPlace () + (let (cell) + cell=(GetGuideInst nil "autobuswires") + (geDeselectAllFig) + (geSelectObject cell) + (leHiEditInPlace) +)) + +; create a template guide instance +(defun MakeGuideInst (guidename instname @key (CV (geGetEditCellView))) + (let (instview moveguides) + + (if (HasGuides CV) then + moveguides = (hiDisplayAppDBox + ?name 'GuideOverwriteDbox + ?dboxBanner "Warning" + ?dboxText "This view has bus guides. Move them into buswires cell?" + ?dialogType hicQuestionDialog + ?buttonLayout 'YesNo + ?defaultButton 1 + ) + ) + (if !(dbFindAnyInstByName CV instname) then + instview = (nrOpenCellViewWritable CV~>libName guidename "layout" ?mode "a" ) + (when !instview + (printf "Cellview %s is not writeable. Instantiating existing cell.\n" guidename) + ) + inst = (dbCreateInstByMasterName CV CV~>libName guidename "layout" instname (list 0 0) "R0") + (AnchorInstance inst) + busGuideInstName = instname + (when instview && moveguides + (CopyGuides CV instview) + (DeleteGuideShapes CV) + ) + (when instview && !instview->shapes + (dbCreateRect instview (list "prBoundary" "boundary") (list 0:0 TrackPitch:TrackPitch)) ) + else + (printf "Instance name %s is already used." instname) + ) + ) +) + +; copy paths or inst to prelayout view +(defun CopyBusGuidesToPrelayout (@key (CV (geGetEditCellView))) + (let (prelayout overwrite) + prelayout = (nrOpenCellViewWritable CV->libName CV->cellName "prelayout" ?mode "a" ) + (if !prelayout then + (printf "Couldn't edit prelayout view.") + else + (if (HasGuides prelayout) then + overwrite = (hiDisplayAppDBox + ?name 'GuideOverwriteDbox + ?dboxBanner "Warning" + ?dboxText "Prelayout view already has bus guides. Replace them?" + ?dialogType hicQuestionDialog + ?buttonLayout 'YesNo + ?defaultButton 1 + ) + (when overwrite + (DeleteGuides prelayout) + (CopyGuides CV prelayout) + ) + else + (CopyGuides CV prelayout) + ) + ) + ) +) + +(defun MoveGuidesToBuswiresCell (@key (CV (geGetEditCellView))) + (let (wirescell wirescv) + wirescell=(GetGuideInst nil busGuideInstName) + (if wirescell then + wirescv=(dbOpenCellViewByType + wirescell->libName wirescell->cellName wirescell->viewName "maskLayout" "a") + (CopyGuideShapes CV wirescv) + (DeleteGuideShapes CV) + else + (hiDisplayAppDBox + ?name 'NoBuswiresCellDbox + ?dboxBanner "Error" + ?dboxText "No buswires instance found." + ?dialogType hicQuestionDialog + ?buttonLayout 'Close + ?defaultButton 1 + ) + ) + ) +) + + +; create wires.il +(defun MakeWiresSkill (CellView instname defchans) + (let (filename file skilltemplate defchantemplate) + + skilltemplate = (sprintf nil "\n ; template wires skill for %s\n" CellView->cellName) + skilltemplate = (strcat skilltemplate "\n ; Add custom channel definitions here\n") + skilltemplate = (strcat skilltemplate "\n(defun DrawAll ()\n") + skilltemplate = (strcat skilltemplate "busGuideInstName = \"") + skilltemplate = (strcat skilltemplate instname) + skilltemplate = (strcat skilltemplate "\"\n") + skilltemplate = (strcat skilltemplate "\n ; Add DefChans to be drawn here\n") + skilltemplate = (strcat skilltemplate " ; syntax- (DrawChannels nil YourNewChannel nil \"YourNewChannel\")\n") + skilltemplate = (strcat skilltemplate "\n(DrawTracks)\n") + skilltemplate = (strcat skilltemplate ";(DrawDefaultTracks)\n") + skilltemplate = (strcat skilltemplate "(DrawObstructions)\n") + skilltemplate = (strcat skilltemplate ")\n") + + defchantemplate = "(ReloadDefChans)\n" + + filename = strcat( "/" + buildString( reverse( cddr( reverse( parseString( CellView~>fileName "/")))) "/") + "/wires.il") + (if (isFile filename) then + (printf "File wires.il already exists. Won't overwrite.") + else + file = (outfile filename) + + (if !file then + (printf "File %s is not writeable." filename) + else + (when defchans + (fprintf file "%s" defchantemplate) + ) + (fprintf file "%s" skilltemplate) + (close file) + )) + ) +) + +; check for updates to defchan.il and reload if necessary +(defun ReloadDefChans () + (let (DFII_dir defchanfile ) + DFII_dir = ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + defchanfile = (sprintf nil "%s/defchan.il" DFII_dir) + modtime = (fileTimeModified defchanfile) + (when modtime > defchan_modtime + (printf "reloading defchan.il ... ") + defchan_patterns = nil + (load defchanfile) + (printf "defchan.il reloaded.\n") + ) + defchan_modtime = modtime + ) +) + +; redraw everything +(defun RefreshAllBuswires () + (geDeselectAllFig) + (DeleteBusWires) + (DrawWires) + (DeleteUnusedNets) +) + +; redraw all pins in conjunction with inplace pins +(defun RedrawAllPins () + (DeletePinsExcludeType "Power") + (DeletePinsByPurpose "pin") + (DeletePinsByType "Inplace") + (RefreshPinDatabase) + (RefreshAllBuswires) + (CanonicalizePins) + (DrawMidLevelPins) +) + +; Update layout_pg/layout view after editing bus wires without +; touching other wires. +(defun UpdateBusLayout (@key (CV (geGetEditCellView))) + (unless CV->viewName=="layout_pg" + (error "UpdateBusLayout should be run from layout_pg view\n")) + (RedrawAllPins) + (DeleteKeepout) + (CanonicalizeNets) + (DeleteRedundantPins ?warnOnly !delete_redundant_pins) + (MakeLayout) + ) + +(defun SetBusProp (obj) + (when obj + (dbReplaceProp obj "BusScriptObject" "boolean" t) + ) +) + +(defun IsBusObject (obj) + (let (isbus) + isbus = nil + (when obj + (when (dbGetPropByName obj "BusScriptObject")->value=="TRUE" + isbus=t + ) + ) + isbus + ) +) + + +; draw an individual segment of a path +(defun DrawSegment (name layer width xy0 xy1 beginExt endExt isPin + @key (guideInst nil) (CV (geGetEditCellView))) + (let (nxy0 nxy1 x0 y0 x1 y1 fig rect net label pin) + nxy0 = (busTransformPoint xy0 guideInst) + nxy1 = (busTransformPoint xy1 guideInst) + x0 = (car nxy0) + y0 = (cadr nxy0) + x1 = (car nxy1) + y1 = (cadr nxy1) + fig = (dbCreatePath CV layer (list nxy0 nxy1) width "varExtendExtend") + (SetBusProp fig) + net = (MakeNet CV name) + fig->beginExt = (if beginExt width/2 0) + fig->endExt = (if endExt width/2 0) + (if net!=nil fig->net = net) + (cond (isPin + (cond (y0==y1 + rect = (dbCreateRect CV layer list(x0:y0-width/2 x1:y1+width/2)) ; pins should be rectangles + ) + (x0==x1 + rect = (dbCreateRect CV layer list(x0-width/2:y0 x1+width/2:y1)) ; pins should be rectangles + ) + (t (error "invalid coordinates for pins %f:%f %f:%f" x0 y0 x1 y1) + ) + ) + (dbDeleteObject fig) ; delete the path + pin = (dbCreatePin net rect) ; create a pin + (SetBusProp rect) + (dbReplaceProp rect "PinType" "string" "BusScript") + pin->accessDir = (list "left" "right" "top" "bottom") + pin->term->direction = "inputOutput" + (LabelPin CV rect) + ) + ) + ) + t + ) + + +; draw a via (use Nanoroute compatible vias) +(defun DrawVia (name viaList xy width cuts @key (doubleVias t) (verticalVias nil) (positiveVias nil) + (guideInst nil) (stacked nil) (corrected nil) (CV (geGetEditCellView))) + (let (inst net type extensions params contactOrientation layer1 layer2) + +; when(verticalVias==t println("YES")) + + ;convert to a list if not a list + (if !listp(viaList) viaList = list(viaList)) + (foreach via viaList + (cond (guideInst!=nil contactOrientation = guideInst->orient) + (guideInst==nil contactOrientation = "R0")) + (cond ((and busContacts (via!=nil)) + (if cuts=="" then + type = via + (if !doubleVias then + nil + else + type = (strcat via "_R_H") + ) + else type = (strcat via cuts) + ) + extensions = (BusDefaultViaExtensions via + ?cuts cuts ?doubleVias doubleVias ?stacked stacked) + params = (if extensions + (list (list "layer1XEnclosure" "float" (car extensions)) + (list "layer1YEnclosure" "float" (cadr extensions)) + (list "layer2XEnclosure" "float" (caddr extensions)) + (list "layer2YEnclosure" "float" (cadddr extensions)) + ) + nil + ) + + inst = (dbCreateVia CV + (techFindViaDefByName TechLib type) + (busTransformPoint xy guideInst) + contactOrientation + ) + when( corrected + layer2 = evalstring(car(parseString(nth(0 parseString(type "_")) "M"))) + layer1 = evalstring(car(parseString(nth(1 parseString(type "_")) "M"))) + if( evenp(layer1) + then + inst~>layer1Enc = 0.04:0.01 + inst~>layer2Enc = 0.04:0.01 + else + inst~>layer1Enc = 0.04:0.01 + inst~>layer2Enc = 0.04:0.01 + ) + ) + (SetBusProp inst) + net = (MakeNet CV name) + (cond (net!=nil (dbAddFigToNet inst net))) + ) + ) + ) ;foreach + ) + t + ) + +; Draw a multisegment path on two perpendicular layers with vias. +; (DrawWire metal67 "a" 0.36 (list 0:0 9.6:0 9.6:9.6 19.2:9.6)) +(defun DrawWire (layers name width points + @key (isPin nil) (startVias nil) (endVias nil) (doubleVias t) (verticalVias nil) (positiveVias nil) + (guideInst nil) (flipX nil) (flipY nil) (pattern evalstring("e1of4")) + (CV (geGetEditCellView))) + (let (horz_layer vert_layer via viadir last first lastIndex index cuts layer hv dir templast (types (ClassifyPoints points)) (dirs (ClassifyDirs points)) corrected correctOP) + corrected = nil + horz_layer = (car layers) + vert_layer = (cadr layers) + via = (caddr layers) + viadir = (cadddr layers) + points = (CanonicalizePoints points) + last = (car points) + first = t + lastIndex = (length points)-2 + index = 0 + when(!verticalVias + cuts = (if (almostEqual (car (cadr points)) (car last)) "_R_V" "_R_H")) + when(verticalVias + cuts = (if verticalVias "_R_V" "_R_H")) + + (if startVias (DrawVia name via last width cuts ?doubleVias doubleVias ?verticalVias verticalVias ?positiveVias positiveVias ?guideInst guideInst ?stacked t ?CV CV)) + (foreach point (cdr points) + hv = nth(index types) + dir = nth(index dirs) + layer = (if (almostEqual (car point) (car last)) vert_layer horz_layer) + (DrawSegment name layer width last point + (index!=0) (index!=lastIndex) isPin ?guideInst guideInst ?CV CV) + when(!verticalVias + cuts = (if (and doubleVias viadir) (strcat "_R_" viadir) "")) + when(verticalVias + cuts = (if verticalVias "_R_V" "_R_H")) + templast = last + when( doubleVias && !verticalVias + correctOP = DoubleViaCorrection(templast hv dir pattern flipX flipY) + last = nth(0 correctOP) + corrected = nth(1 correctOP) + ) + when( doubleVias && verticalVias + correctOP = VerticalViaCorrection(templast hv dir pattern flipX flipY positiveVias) + last = nth(0 correctOP) + corrected = nth(1 correctOP) + ) + (if (not first) (DrawVia name via last width cuts + ?doubleVias doubleVias ?guideInst guideInst ?verticalVias verticalVias ?positiveVias positiveVias + ?stacked nil ?corrected corrected ?CV CV)) + corrected = nil + first = nil + when(!verticalVias + cuts = (if (almostEqual (car point) (car last)) "_R_V" "_R_H")) + when(verticalVias + cuts = (if verticalVias "_R_V" "_R_H")) + last = point + index = index+1 + ) + (if endVias (DrawVia name via last width cuts ?doubleVias doubleVias ?verticalVias verticalVias ?positiveVias positiveVias + ?guideInst guideInst ?stacked t ?CV CV)) + ) + t + ) + +; return list of which directions segments point connect to +(defun ClassifyPoints (points) + (let (a b types) + a = (car points) + b = (cadr points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "EV"))) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "EH")))) + (for i 1 (length points)-2 + a = (nth i-1 points) + b = (nth i points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "VH"))) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "HV")))) + ) + a = (nth (length points)-2 points) + b = (nth (length points)-1 points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "VE"))) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "HE"))) + ) + types + ) + ) + +; add suffix to a prefix (unless the prefix is empty, in which case result is too) +(defun AddSuffix (prefix suffix) + (cond (member(suffix ShieldNet) ||prefix==nil suffix) + (prefix!="" (sprintf nil "%s%s" prefix suffix)) + (prefix=="" "") + ) + ) + +; Draw a channel bundle of wires. +; (DrawChannel metal67 e1of4 "a" (list 0:0 9.6:0 9.6:9.6 19.2:9.6 19.2:19.2 38.4:19.2)) +(defun DrawChannel (layers pattern prefix points + @key (flipX nil) (flipY nil) (isPin nil) + (startVias nil) (endVias nil) (doubleVias t) (verticalVias nil) (positiveVias nil) + (altLayerPatternList nil) + (guideInstName nil) (guideInst nil) (shieldM2 t) (drawShield t) + (CV (geGetEditCellView))) + (let (newpoints node width offset index x y hv + offsetX offsetY nextOffset curOffset lastLayer curLayer tmpx tmpy + curPattern nextLayer nextPattern stVias eVias segNum layer_override lastx lasty shieldDrawn + (types (ClassifyPoints points))) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + shieldDrawn = nil + + ; go through all nodes in channel + (foreach node_offset pattern + node = (car node_offset) + width = (cadr node_offset) + offset = (caddr node_offset) + layer_override = (cadddr node_offset) + newpoints = nil + index = 0 + segNum = 0 ; for multiple segment due to changing layers + lastLayer = curLayer + (foreach point points + x = (car point) + y = (cadr point) + hv = (nth index types) + (if altLayerPatternList then + ;altLayerPatternList either a list of patterns for each segments or a single one + ;if a single one it will be used for the second segment to the end + ;a nil entry in the altLayerPatternList will use the original layer and pattern + nextOffset = offset + curOffset = offset + curLayer = layers + (if length(altLayerPatternList) > 1 + then + ;current pattern + (if index >= 2 && nth(1 nth(index-2 altLayerPatternList)) + then + curLayerPattern = nth(index-2 altLayerPatternList) + curLayer = nth(0 curLayerPattern ) + curPattern = nth(1 curLayerPattern ) + (foreach cur_node_offset curPattern + (if node == (car cur_node_offset) then + curOffset = (caddr cur_node_offset) + ) + ) + ) + ;next pattern + (if index >= 1 && nth(1 nth(index-1 altLayerPatternList)) + then + nextLayer = nth(0 nth(index-1 altLayerPatternList)) + nextPattern = nth(1 nth(index-1 altLayerPatternList)) + (foreach next_node_offset nextPattern + (if node == (car next_node_offset) then + nextOffset = (caddr next_node_offset) + ) + ) + ) + else + ;single alternate pattern + altLayerPattern = nth(0 altLayerPatternList) + altLayer = nth(0 altLayerPattern) + altPattern = nth(1 altLayerPattern) + (foreach alt_node_offset altPattern + (if node == (car alt_node_offset) then + altOffset = (caddr alt_node_offset) + ) + ) + (if index <= 1 + then curLayer = layers nextLayer = (if (index == 0) layers altLayer) curOffset = offset nextOffset = altOffset + else curLayer = altLayer nextLayer = altLayer curOffset = altOffset nextOffset = altOffset + ) + ) + (if hv == "EH" || hv == "HV" then + offsetX = nextOffset + offsetY = curOffset + else + (if hv == "VE" || hv == "HE" then + offsetX = curOffset + offsetY = curOffset + else + offsetX = curOffset + offsetY = nextOffset + ) + ) + ;layer info is in the startVias to draw multiple vias + stVias = (segNum == 0 && startVias == t) + (if (caddr curLayer) != (caddr lastLayer) && length(newpoints) >= 1 then + ;switch layers if via list is different + tmpx = x + (if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0.0) + tmpy = y + (if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0.0) + newpoints = (append newpoints (list (list ((lastx+tmpx)/2.0) ((lasty+tmpy)/2.0)))) + (DrawWire lastLayer (AddSuffix prefix node) + width newpoints + ?isPin isPin ?startVias stVias ?endVias nil ?verticalVias verticalVias ?positiveVias positiveVias + ?doubleVias doubleVias ?guideInst guideInst ?flipX flipX ?flipY flipY ?pattern pattern ?CV CV) + newpoints = (list (list ((lastx+tmpx)/2.0) ((lasty+tmpy)/2.0))) + ) + lastLayer = curLayer + lastx= x+(if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0) + lasty = y+(if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0) + (if segNum == 0 && startVias && startVias!=t then + ;layer info is in the startVias to draw multiple vias + DrawVia((AddSuffix prefix node) startVias lastx:lasty + width (if (and hv!="HE" hv!="EH") "_R_V" "_R_H") ?doubleVias doubleVias ?verticalVias verticalVias ?positiveVias positiveVias ?CV CV) + stVias = nil + ) + eVias = endVias + (if segNum == length(points)-1 && endVias && endVias!=t then + ;layer info is in the endVias to draw multiple vias + DrawVia((AddSuffix prefix node) endVias lastx:lasty + width (if (and hv!="HE" hv!="EH") "_R_V" "_R_H") ?doubleVias doubleVias ?verticalVias verticalVias ?positiveVias positiveVias ?CV CV) + eVias = nil + ) + segNum++ + else + ; no alternate pattern + offsetX = offset + offsetY = offset + stVias = startVias + eVias = endVias + curLayer = layers + ) + + x = x+(if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0) + y = y+(if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0) + newpoints = (append newpoints (list (list x y))) + index = index+1 + ) + ; draw wire for this node + (DrawWire (if layer_override layer_override curLayer) + (AddSuffix prefix node) width newpoints + ?isPin isPin ?startVias stVias ?endVias eVias ?verticalVias verticalVias ?positiveVias positiveVias + ?doubleVias doubleVias ?guideInst guideInst ?flipX flipX ?flipY flipY ?pattern pattern ?CV CV) + + when( drawShield DrawBusShield(newpoints (if layer_override layer_override curLayer) prefix ?shieldM2 shieldM2) ) + + ) + + ) + t + ) + +; Draw an array of channels. Must give array_pitch for each segment +; (including "before and "after" segments), or give a single atom for +; all segments except before and after segments, which will be 0. +; +;(DrawChannelArray metal67 e1of4 "a" 0:3 (list 0 19.2 4.8 4.8 4.8 0) +; (list 0.5:2 9.6:0 9.6:9.6 38.4:9.6 38.4:19.2)) +(defun DrawChannelArray (layers pattern prefix indices array_pitch points + @key (flipX nil) (flipY nil) (isPin nil) + (startVias nil) (endVias nil) (doubleVias t) (verticalVias nil) (positiveVias nil) + (guideInstName nil) (guideInst nil) + (only_evens nil) (only_odds nil) (drawShield t) + (CV (geGetEditCellView))) + (let (x y o hv xoff yoff newpoints index index_list + (types (ClassifyPoints points)) + (NP (length points))) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + + ; check usage + (cond ((and (not (atom array_pitch)) (length array_pitch)!=NP+1) + (printf "ERROR: in array_pitch for %s.\nMust be either a single number or a list of N+1 pitches for an N point path.\n" prefix) + nil + )) + + ; create list of indices + index_list=(list 0) + (for i (car indices) (cadr indices) + (when (mod i 2)==0 && only_evens + index_list=(append1 index_list i) + ) + (when (mod i 2)!=0 && only_odds + index_list=(append1 index_list i) + ) + (when !only_evens && !only_odds + index_list=(append1 index_list i) + ) + ) + ; go through all channels in array + (foreach i (cdr index_list) + newpoints = nil + index = 0 + (foreach point points + x = (car point) + y = (cadr point) + o = i-(car indices) + hv = (nth index types) + xoff = (cond (hv=="VE" (GetOffset NP index array_pitch)) + (hv=="EV" (GetOffset NP index+1 array_pitch)) + (hv=="VH" (GetOffset NP index array_pitch)) + (hv=="HV" (GetOffset NP index+1 array_pitch)) + (hv=="EH" (GetOffset NP index array_pitch)) + (hv=="HE" (GetOffset NP index+1 array_pitch))) + x = x+o*xoff*(if flipX -1 1) + yoff = (cond (hv=="VE" (GetOffset NP index+1 array_pitch)) + (hv=="EV" (GetOffset NP index array_pitch)) + (hv=="VH" (GetOffset NP index+1 array_pitch)) + (hv=="HV" (GetOffset NP index array_pitch)) + (hv=="EH" (GetOffset NP index+1 array_pitch)) + (hv=="HE" (GetOffset NP index array_pitch))) + y = y+o*yoff*(if flipY -1 1) + newpoints = (append newpoints (list (list x y))) + index = index+1 + ) + + ; draw channel + (DrawChannel layers pattern (AddSuffix prefix (sprintf nil "[%d]" i)) newpoints + ?flipX flipX ?flipY flipY ?verticalVias verticalVias ?positiveVias positiveVias + ?isPin isPin ?startVias startVias ?endVias endVias ?doubleVias doubleVias + ?guideInst guideInst ?drawShield drawShield ?CV CV) + ) + ) + t + ) + +; get the nth array_pitch, or return 0/array_pitch if its an atom +(defun GetOffset (num_points index array_pitch) + (if (atom array_pitch) then + (if (or index==0 index==num_points) then 0 + else array_pitch) + else (nth index array_pitch) + ) + ) + +; select by BusPattern +(defun SelectPattern (name @key (CV (geGetEditCellView))) + (let (prop found) + found = 0 + (foreach obj CV->shapes + prop = (GetProp obj "BusPattern" nil) + (cond ((and obj->objType=="path" prop==name) + (geSelectObject obj) + found = found+1 + ) + ) + ) + found + ) + ) + +; select by BusPrefix +(defun SelectPrefix (name @key (CV (geGetEditCellView))) + (let (prop found) + found = 0 + (foreach obj CV->shapes + prop = (GetProp obj "BusPrefix" nil) + (cond ((and obj->objType=="path" prop==name) + (geSelectObject obj) + found = found+1 + ) + ) + ) + found + ) + ) + +; get list of waypoints and layers from (optionally) named shapes +(defun GetPaths (name @key (guideInstName nil) (CV (geGetEditCellView))) + (let (paths shapes pattern pre isPin startVias endVias flipX flipY pitch double shield rotate vertical positive props) + paths = nil + shapes = (geGetSelSet) + (cond (guideInstName!=nil CV = (GetGuideInst nil guideInstName)->master)) + (cond (shapes==nil shapes = CV->shapes)) + (foreach obj shapes + pattern = (GetProp obj "BusPattern" nil) + pre = (GetProp obj "BusPrefix" "") + isPin = (GetProp obj "BusPin" nil) + startVias = (GetProp obj "BusStartVias" nil) + endVias = (GetProp obj "BusEndVias" nil) + flipX = (GetProp obj "BusFlipX" nil) + flipY = (GetProp obj "BusFlipY" nil) + pitch = (GetProp obj "BusArrayPitch" TrackPitch) + double = (GetProp obj "BusDoubleVias" nil) + shield = (GetProp obj "DrawBusShields" nil) + rotate = (GetProp obj "RotateMetalOrientation" nil) + vertical = (GetProp obj "BusVerticalVias" nil) + positive = (GetProp obj "PositiveViaShift" nil) + props = (list pattern obj->lpp pre isPin startVias endVias flipX flipY pitch double shield rotate vertical positive) + (cond ((and obj->objType=="path" pattern!=nil (or name==nil pattern==name)) + paths = (cons (list props obj->points) paths)) + ) + ) + paths + ) + ) + +; create bus properties if necessary +(defun CreateBusProps (@key (paths nil)) + (let (pattern prefix pin flipX flipY startVias endVias doubleVias drawShield rotateMetals verticalVias positiveVias ) + paths = (if paths==nil (geGetSelSet) paths) + (foreach obj paths + (cond (obj->objType=="path" + pattern = (GetProp obj "BusPattern" "") + prefix = (GetProp obj "BusPrefix" "") + pin = (GetProp obj "BusPin" nil) + flipX = (GetProp obj "BusFlipX" nil) + flipY = (GetProp obj "BusFlipY" nil) + startVias = (GetProp obj "BusStartVias" nil) + endVias = (GetProp obj "BusEndVias" nil) + pitch = (GetProp obj "BusArrayPitch" TrackPitch) + doubleVias = (GetProp obj "BusDoubleVias" t) + drawShield = (GetProp obj "DrawBusShields" t) + rotateMetals = (GetProp obj "RotateMetalOrientation" nil) + verticalVias = (GetProp obj "BusVerticalVias" nil) + positiveVias = (GetProp obj "PositiveViaShift" nil) + ; delete properties + (dbDeletePropByName obj "BusPattern") + (dbDeletePropByName obj "BusPrefix") + (dbDeletePropByName obj "BusPin") + (dbDeletePropByName obj "BusFlipX") + (dbDeletePropByName obj "BusFlipY") + (dbDeletePropByName obj "BusStartVias") + (dbDeletePropByName obj "BusEndVias") + (dbDeletePropByName obj "BusArrayPitch") + (dbDeletePropByName obj "BusDoubleVias") + (dbDeletePropByName obj "DrawBusShields") + (dbDeletePropByName obj "RotateMetalOrientation") + (dbDeletePropByName obj "BusVerticalVias") + (dbDeletePropByName obj "PositiveViaShift") + + ; set new properties + (dbReplaceProp obj "BusPattern" "string" pattern) + (dbReplaceProp obj "BusPrefix" "string" prefix) + (dbReplaceProp obj "BusPin" "boolean" pin) + (dbReplaceProp obj "BusFlipX" "boolean" flipX) + (dbReplaceProp obj "BusFlipY" "boolean" flipY) + (dbReplaceProp obj "BusStartVias" "boolean" startVias) + (dbReplaceProp obj "BusEndVias" "boolean" endVias) + (dbReplaceProp obj "BusArrayPitch" "list" pitch) + (dbReplaceProp obj "BusDoubleVias" "boolean" doubleVias) + (dbReplaceProp obj "DrawBusShields" "boolean" drawShield) + (dbReplaceProp obj "RotateMetalOrientation" "boolean" rotateMetals) + (dbReplaceProp obj "BusVerticalVias" "boolean" verticalVias) + (dbReplaceProp obj "PositiveViaShift" "boolean" positiveVias) + )) + ) + ) + t + ) + +; set the BusPattern property, create other properties if necessary +(defun SetPattern (pattern @key (paths nil)) + (let (pat) + paths = (if paths==nil (geGetSelSet) paths) + (foreach obj paths + (cond (obj->objType=="path" + pat = (if pattern pattern (GetProp obj "BusPattern" "e1of4")) + (CreateBusProps ?paths (list obj)) + (dbReplaceProp obj "BusPattern" "string" pat) + ) + ((or obj->objType=="rect" obj->objType=="polygon") + (CreateObsProps ?shapes (list obj)) + ) + ) + ) + t + ) + ) + +; eliminate degenerate segments from points +(defun CanonicalizePoints (points) + (let (newpoints last next point (len (length points))) + newpoints = (append newpoints (list (nth 0 points))) ; first point + (for i 1 len-2 + last = (nth i-1 points) + point = (nth i points) + next = (nth i+1 points) + (cond ((and (not (almostEqual (car last) (car next))) + (not (almostEqual (cadr last) (cadr next)))) + newpoints = (append newpoints (list point)))) + ) + newpoints = (append newpoints (list (nth len-1 points))) ; last point + ) + ) + +; move way points +(defun OffsetPoints (points dx dy) + (let (newpoints p) + (for i 0 (length points)-1 + p = (nth i points) + p = (list (car p)+dx (cadr p)+dy) + newpoints = (append newpoints (list p)) + ) + newpoints + ) + ) + +; offset some of the points +(defun OffsetSomePoints (points from to dx dy) + (let (newpoints apply p) + (for i 0 (length points)-1 + apply = (and i>=from i<=to) + p = (nth i points) + p = (list (car p)+dx*(if apply!=nil 1 0) (cadr p)+dy*(if apply!=nil 1 0)) + newpoints = (append newpoints (list p)) + ) + newpoints + ) + ) + +; move paths +(defun OffsetPaths (paths dx dy) + (let (newpaths props points) + (foreach path paths + props = (car path) + points = (cadr path) + newpaths = (cons (list props (OffsetPoints points dx dy)) newpaths)) + newpaths + ) + ) + +; move only some points of paths +(defun OffsetSomePointsOfPaths (paths from to dx dy) + (let (newpaths props points) + (foreach path paths + props = (car path) + points = (cadr path) + newpaths = (cons (list props (OffsetSomePoints points from to dx dy)) newpaths)) + newpaths + ) + ) + +; translate path layer to metal layers, or use specified layers +(defun ChooseLayers (layers pathlayer @key (rotateMetals nil)) + (cond (layers!=nil layers) + ((and layers==nil busKeepout==nil busTopMetal==nil) + (cond ((pathlayer==BusPath12) if(rotateMetals then BusMetal21 else BusMetal12)) + ((pathlayer==BusPath23) if(rotateMetals then BusMetal32 else BusMetal23)) + ((pathlayer==BusPath34) if(rotateMetals then BusMetal43 else BusMetal34)) + ((pathlayer==BusPath45) if(rotateMetals then BusMetal54 else BusMetal45)) + ((pathlayer==BusPath56) if(rotateMetals then BusMetal65 else BusMetal56)) + ((pathlayer==BusPath67) if(rotateMetals then BusMetal76 else BusMetal67)) + ((pathlayer==BusPath78) if(rotateMetals then BusMetal87 else BusMetal78)) + ((pathlayer==BusPath89) if(rotateMetals then BusMetal98 else BusMetal89)) + ((pathlayer==BusPath910) if(rotateMetals then BusMetal109 else BusMetal910)) + (t (printf "ERROR: unrecognized bus lpp (%s %s)\n" + (car pathlayer) (cadr pathlayer)) nil) + )) + ((and layers==nil busKeepout==nil busTopMetal==t) + (cond ((pathlayer==BusPath12) BusMetal2) + ((pathlayer==BusPath23) BusMetal3) + ((pathlayer==BusPath34) BusMetal4) + ((pathlayer==BusPath45) BusMetal5) + ((pathlayer==BusPath56) BusMetal6) + ((pathlayer==BusPath67) BusMetal7) + ((pathlayer==BusPath78) BusMetal8) + ((pathlayer==BusPath89) BusMetal9) + ((pathlayer==BusPath910) BusMetal10) + (t (printf "ERROR: unrecognized bus lpp (%s %s)\n" + (car pathlayer) (cadr pathlayer)) nil) + )) + ((and layers==nil busKeepout==t) + (cond ((layer==BusPath12) if(rotateMetals then BusKeepout21 else BusKeepout12)) + ((layer==BusPath23) if(rotateMetals then BusKeepout32 else BusKeepout23)) + ((layer==BusPath34) if(rotateMetals then BusKeepout43 else BusKeepout34)) + ((layer==BusPath45) if(rotateMetals then BusKeepout54 else BusKeepout45)) + ((layer==BusPath56) if(rotateMetals then BusKeepout65 else BusKeepout56)) + ((layer==BusPath67) if(rotateMetals then BusKeepout76 else BusKeepout67)) + (t (printf "ERROR: unrecognized bus lpp (%s %s)\n" + (car layer) (cadr layer)) nil) + )) + ) + ) + +; pick which bus prefix to use +(defun ChoosePrefix (prefix path_prefix) + (cond + ((and path_prefix!=nil path_prefix!="") path_prefix) + ((and prefix!=nil prefix!="") prefix) + ("") + ) + ) + +; draw multiple channels +(defun DrawChannels (layers pattern prefix paths + @key (guideInstName nil) (guideInst nil) (CV (geGetEditCellView))) + (let (props points layer isPin startVias endVias doubleVias flipX flipY busShield rotateMetals verticalVias positiveVias + patlist prelist pre buspat) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + + ; process guide paths + (cond ((or paths==nil (atom paths)) + paths = (GetPaths paths ?CV (if guideInst->master guideInst->master CV)))) + (foreach path paths + props = (car path) + points = (cadr path) + patlist = (parseString (nth 0 props) " ") + layer = (nth 1 props) + prelist = (parseString (nth 2 props) " ") + isPin = (nth 3 props) + startVias = (nth 4 props) + endVias = (nth 5 props) + flipX = (nth 6 props) + flipY = (nth 7 props) + doubleVias = (nth 9 props) + busShield = (nth 10 props) + rotateMetals = (nth 11 props) + verticalVias = (nth 12 props) + positiveVias = (nth 13 props) + + ; iterate over BusPattern/BusPrefix lists + (foreach pat patlist + pre = (ChoosePrefix prefix (car prelist)) + prelist = (cdr prelist) + buspat = (if pattern==nil (MapBusPattern pat) pattern) + (when (and buspat pre) + (DrawChannel (ChooseLayers layers layer ?rotateMetals rotateMetals) + buspat pre points + ?flipX flipX ?flipY flipY ?isPin isPin + ?startVias startVias ?endVias endVias + ?doubleVias doubleVias ?verticalVias verticalVias ?positiveVias positiveVias + ?guideInst guideInst ?drawShield busShield ?CV CV) + ) + ) + ) + ) + t + ) + +; draw multiple channel arrays +(defun DrawChannelArrays (layers pattern prefix indices array_pitch paths + @key (guideInstName nil) (guideInst nil) + (only_evens nil) (only_odds nil) + (CV (geGetEditCellView))) + (let (props points layer isPin startVias endVias doubleVias flipX flipY + pitch busShield rotateMetals verticalVias positiveVias + patlist prelist pre buspat lo hi lohi options evens odds) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + + ; look for array bus patterns + (rexCompile "^\\(.*\\)\\[\\([0-9]+\\)[\\.]*\\([0-9]*\\)\\]$") + + ; process all guide paths + (cond ((or paths==nil (atom paths)) + paths = (GetPaths paths ?CV (if guideInst->master guideInst->master CV)))) + (foreach path paths + props = (car path) + points = (cadr path) + patlist = (parseString (nth 0 props) " ") + layer = (nth 1 props) + prelist = (parseString (nth 2 props) " ") + isPin = (nth 3 props) + startVias = (nth 4 props) + endVias = (nth 5 props) + flipX = (nth 6 props) + flipY = (nth 7 props) + pitch = (if array_pitch==nil (nth 8 props) array_pitch) + doubleVias = (nth 9 props) + busShield = (nth 10 props) + rotateMetals = (nth 11 props) + verticalVias = (nth 12 props) + positiveVias = (nth 13 props) + + ; iterate over BusPattern/BusPrefix lists + (for n 0 (length patlist)-1 + pat = (nth n patlist) + pre = (if prelist (nth (mod n (length prelist)) prelist) nil) + pre = (ChoosePrefix prefix pre) + + ; default options + evens = only_evens + odds = only_odds + lohi = indices + + ; process pattern options (pattern:opt1:opt2:...) + (unless pattern + options = (parseString pat ":") + pat = (car options) + options = (cdr options) + (while options + (cond ((car options)=="even" evens=t) + ((car options)=="odd" odds=t) + ) + options = (cdr options) + ) + ) + + ; pick pattern and array range automatically + (when (and pattern==nil lohi==nil (rexExecute pat)) + pat = (rexSubstitute "\\1") + lo = (rexSubstitute "\\2") + hi = (rexSubstitute "\\3") + (cond (hi=="" hi=(atoi lo)-1 lo=0) + (t hi=(atoi hi) lo=(atoi lo)) + ) + lohi = (list lo hi) + ) + buspat = (if pattern==nil (MapBusPattern pat) pattern) + + ; draw + (when (and buspat pre lohi) + (DrawChannelArray (ChooseLayers layers layer ?rotateMetals rotateMetals) + buspat pre lohi pitch points + ?flipX flipX ?flipY flipY ?isPin isPin + ?startVias startVias ?endVias endVias + ?doubleVias doubleVias ?verticalVias verticalVias ?positiveVias positiveVias + ?guideInst guideInst + ?only_evens evens ?only_odds odds ?drawShield busShield) + ) + ) + ) + ) + t + ) + +; highlight overlaps of paths on the same metal layer +(defun FindBusOverlaps (@key (CV (geGetEditCellView))) + (let (any_overlap bbox xy0 xy1 x0 y0 x1 y1 overlaps writable) + any_overlap=nil + if( CV then + writeable=nil; + if(CV~>mode == "r" then + writeable=nil + else + writable=t + ) + any_overlap = nil + if(writable (geDeleteAllMarker CV)) + (foreach shape CV->shapes + (cond (((isWiringPath shape) && ( writable || ! any_overlap ) ) + bbox = shape->bBox + xy0 = (car bbox) + xy1 = (cadr bbox) + x0 = (car xy0) + y0 = (cadr xy0) + x1 = (car xy1) + y1 = (cadr xy1) + bbox = (list x0+0.005:y0+0.005 x1-0.005:y1-0.005) + overlaps = (dbGetOverlaps CV bbox shape->lpp 0) + (foreach obj overlaps + (cond ((and (isWiringPath obj) obj!=shape) + any_overlap = t + if(writable (geCreateMarker obj "warning" "bus" "overlap" "")))) + ) + ) + ) + ) + ) + any_overlap + ) + ) + +; Create a channel of sub-channels. Examples: +; chan = (DefChan (list (list prefix channel offset) ...)) +; datatail = (DefChan (let (chan channels) +; (for i 0 15 +; chan = (list (sprintf nil ".D[%d]" i) smr_e1of4 TrackPitch*i) +; channels = (cons chan channels)) +; chan = (list ".T" smr_e1of2 TrackPitch*16) +; channels = (cons chan channels) +; channels)) +(defun DefChan (channels) + (let (newchan newrail prefix pattern offset newname) + (foreach chan channels + prefix = (car chan) + pattern = (cadr chan) + offset = (caddr chan) + layer_override = (cadddr chan) + (foreach rail pattern + newname = (if (car rail)=="GND" "GND" + (sprintf nil "%s%s" prefix (car rail))) + newrail = (list newname (cadr rail) + (caddr rail)+offset layer_override) + newchan = (append newchan (list newrail)) + ) + ) + newchan + ) +) + +; Round the offsets in a channel definition (suitable for DefChan) to multiple +; of pitch, and return a new channel definition (suitable for DefChan) +(defun AlignDefChan (pitch channels) + (mapcar + (lambda (chan) + (list (car chan) + (cadr chan) + (truncate (caddr chan)/pitch)*pitch ; or MathRoundToNearest? + (cadddr chan))) + channels)) + +; Expand array elements into a defchan +(defun DefChanArray (pattern indices array_pitch) + (let (chan channels) + channels = nil + (for i (car indices) (cadr indices) + chan = (list (sprintf nil "[%d]" i) pattern i*array_pitch) + channels = (cons chan channels) + ) + (DefChan channels) + ) + ) + +(defun BuildDefChanList ( oldlist name array type offset increment @key (use_dots t) ) + (let (namelist newlist i dot) + (if use_dots then dot = "." else dot = "") + (if array <= 1 then + namelist = (list (sprintf nil "%s%s" dot name) ) + else + namelist = (list (sprintf nil "%s%s[0]" dot name) ) + (for i 1 array-1 + namelist = (append1 namelist (sprintf nil "%s%s[%d]" dot name i) ) + ) + ) + i=0 + (foreach newname namelist + (if !newlist then + (if !oldlist then + newlist = (list (list newname type offset) ) + else + newlist = (append1 oldlist (list newname type offset) ) + ) + else + i=i+1 + newlist = (append1 newlist (list newname type offset+i*increment) ) + ) + ) + newlist + )) + +; load wires.il for currently edited cellview +(defun LoadWires (@key (CV (geGetEditCellView))) + (BusDefaults) + (let (fl port Outfl outfl h txt var1 var2 text CN Cellname lngth Initial k i j finalpath initialpath FinalPath modtime variable1 variable2 Variable2 Match Initialize_wires l FileFound) + i=0 + l=0 + Match=0 + Cellname=(NameGetCellPathFromCellName CV->cellName) + piece=parseString( Cellname "/" ) + lngth=length(piece) + println(Cellname) + Initial=nth(1 piece) + finalpath="" + for(j 6 lngth-1 + FileFound=0 + Initialize_wires=0 + for(i 0 j + initialpath=nth(i piece) + finalpath=strcat(finalpath "/" initialpath) + i=i+1) + FinalPath=strcat(finalpath "/" "wires.il") + modtime = (fileTimeModified FinalPath) + when(modtime!=nil + when((Startloadwires==0) + load(FinalPath) + printf("Loading %s \n" FinalPath) + wires_modtime[Startloadwires]=list(FinalPath modtime) + Startloadwires=Startloadwires+1 + ) + when((Startloadwires!=0) + for(l 0 length(wires_modtime)-1 + variable1=car(wires_modtime[l]) + variable2=cadr(wires_modtime[l]) + when((variable1!=FinalPath) + FileFound=1 + ) + when((variable1==FinalPath)&&(modtime>variable2) + load(FinalPath) + printf("Loading %s \n" FinalPath) + wires_modtime[l]=list(FinalPath modtime) + Initialize_wires=1 + ) + when((variable1==FinalPath)&&(modtime<=variable2) + Initialize_wires=1 + ) + l=l+1 + ) + + when( FileFound == 1 && Initialize_wires == 0 + load(FinalPath) + printf("Loading %s \n" FinalPath) + wires_modtime[Startloadwires]=list(FinalPath modtime) + Startloadwires=Startloadwires+1 + ) + )) + l=0 + j=j+1 + finalpath="" + i=0 + ) + + ;always load the primary cell's file + FinalPath=(sprintf nil "%s/wires.il" + (NameGetCellPathFromCellName CV->cellName)) + (when (isFile FinalPath) + (load FinalPath) + ) + ) + ) + +; load a file given a relative path from the cell directory (i.e. "../wires.il") +(defun LoadRelative (path @key (CV (geGetEditCellView))) + (let (dir file) + dir = (NameGetCellPathFromCellName CV->cellName) + file = (sprintf nil "%s/%s" dir path) + (load file) + ) + ) + +; load then draw wires.il for currently edited cellview +(defun DrawWires (@key (CV (geGetEditCellView))) + (defun DrawAll () + (printf "Default DrawAll: DrawTracks with paths in current cellview.\n") + busPatterns = (append busPatterns defchan_patterns) + (DrawTracks) + (DrawObstructions) + t + ) + (cond ((IsGuideInst CV) + (printf "Can't draw wires inside the guide instance\n")) + (t + (LoadWires) + (DrawAll) + (when (dbFindAnyInstByName CV "autobuswires") + (DrawChannels nil nil nil nil ?guideInstName "autobuswires") + ) + ) + ) + ) + +; fix up pin names by using labels attached to them +(defun FixPinNames (@key (CV (geGetEditCellView))) + (let () + (foreach shape CV->shapes + (cond ((and shape->objType=="label" shape->parent!=nil) + (dbCreatePin (MakeNet CV shape->theLabel) shape->parent) + ) + ) + ) + ) + t + ) + +; flatten any subcecells with .wires. in its cell name, then delete guide layers +(defun FlattenWiringSubcells (@key (CV (geGetEditCellView))) + (let (progress) + leSetAllLayerVisible(t) + + ; flatten wiring subcells + (rexCompile "\\.wires\\.") + progress = t + (while progress + progress = nil + (foreach inst CV->instances + (cond ((and inst->objType=="inst" (rexExecute inst->cellName)) + (dbFlattenInst inst 1 nil t t) + progress = t + ) + ) + ) + ) + + ; delete guide paths + (foreach shape CV->shapes + (cond ((and shape->objType=="path" + (or shape->lpp==BusPath23 + shape->lpp==BusPath34 + shape->lpp==BusPath45 + shape->lpp==BusPath56 + shape->lpp==BusPath67)) + (dbDeleteObject shape) + ) + ) + ) + + ; slot paths + (SlotPaths) + + ; fix pins + (FixPinNames) + ) + t + ) + +; chop all shapes with given chop bbox on specified layer +(defun ChopPaths (CV bbox layerName @key (onlyGND nil)) + (let (shapes x0 y0 x1 y1 chop) + shapes = (dbGetOverlaps CV bbox (list layerName "drawing") 0) + (foreach shape shapes + (cond ((and (isMetalDrawing shape->layerName shape->purpose) + shape->layerName==layerName + shape->objType=="path" + (or !onlyGND shape->net->name=="GND") + (IsBusObject shape)) + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + chop = (list x0:y0 x1:y0 x1:y1 x0:y1) + (leChopShape shape chop t t) + ) + ) + ) + ) + t + ) + +; chop all paths using "slot" rectangles in specified subcell +(defun SlotPathsSubcell (CV inst) + (let (transform bbox) + transform = (geGetInstTransform inst) + (foreach shape inst->master->shapes + (cond ((and shape->objType=="rect" + (isMetalSlot shape->layerName shape->purpose)) + bbox = (geTransformUserBBox shape->bBox transform) + (ChopPaths CV bbox shape->layerName) + ) + ) + ) + ) + t + ) + +; chop all paths using rectangles with "slot" purpose in all subcells +(defun SlotPaths (@key (CV (geGetEditCellView))) + (let (bbox) + + ; process subcell slot layers + (foreach inst CV->instances + (cond (inst->libName!=TechLibName (SlotPathsSubcell CV inst))) + ) + + ; process then delete top level slot layers + (foreach shape CV->shapes + (cond ((and shape->objType=="rect" + (isMetalSlot shape->layerName shape->purpose)) + bbox = shape->bBox + (ChopPaths CV bbox shape->layerName) + (dbDeleteObject shape) + ) + ) + ) + ) + t + ) + +; Alternate version of SlotPaths meant to be added to DrawAll. Looks +; for "buscut" purpose in buswires instance, and only chops GND +; shielding wires. Can include in DrawAll of wires.il +(defun SlotGND (@key (guideInst nil) (guideInstName nil) (CV (geGetEditCellView))) + guideInst = (GetGuideInst guideInst guideInstName) + (foreach shape guideInst->master->shapes + (when (isMetalSlot shape->layerName shape->purpose) + (ChopPaths CV shape->bBox shape->layerName ?onlyGND t) + ) + ) + t + ) + +; mark a list of wiring shapes with marker paint +(defun MarkWires (shapes) + (foreach shape shapes + (cond ((isWiringPath shape) + (geCreateMarker shape "warning" "bus" "length" ""))) + ) + t + ) + +; create BusMark property and set to t +(defun SetBusMark (CV) + (foreach shape CV->shapes + (cond ((isWiringPath shape) + (dbReplaceProp shape "BusMark" "boolean" t)))) + (rexCompile ".*VIA[1-8][1-8].*") + (foreach inst CV->instances + (cond ((or (rexExecute inst->cellName) (isWiringContact inst)) + (dbReplaceProp inst "BusMark" "boolean" t)))) + t + ) + +; create BusMark property and set to t for a list of objects +(defun SetBusMarkForObjects (objects) + (foreach obj objects (dbReplaceProp obj "BusMark" "boolean" t)) + t + ) + +; delete BusMark property +(defun ClearBusMark (CV) + (foreach shape CV->shapes + (cond ((isWiringPath shape) + (dbDeletePropByName shape "BusMark")))) + (foreach inst CV->instances + (cond ((isWiringContact inst) + (dbDeletePropByName inst "BusMark")))) + t + ) + +; find subcell pins connected to set of wires +(defun ConnectedSubcellPins (CV objects) + (let (connected overlaps inst pin layerName bbox) + (foreach obj objects + (cond (obj->objType=="path" + overlaps = (dbGetOverlaps CV obj->bBox (list obj->layerName "net") 1:1) + overlaps = (append overlaps (dbGetOverlaps CV obj->bBox (list obj->layerName "drawing") 1:1)) + overlaps = (append overlaps (dbGetOverlaps CV obj->bBox (list obj->layerName "pin") 1:1)) + (foreach overlap overlaps + (cond ((atom overlap)==nil + inst = (car overlap) + pin = (cadr overlap) + (cond ((and pin->pin !(isWiringContact inst)) + connected = (append connected (list (list inst pin))) + ) + ) + ) + ) + ) + ) + ((isWiringContact obj) + (foreach lpp obj->master->lpps + layerName = lpp->layerName + bbox = (list obj->xy obj->xy) + overlaps = (dbGetOverlaps CV bbox (list layerName "net") 1:1) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "drawing") 1:1)) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "pin") 1:1)) + (foreach overlap overlaps + (cond ((atom overlap)==nil + inst = (car overlap) + pin = (cadr overlap) + (cond ((and pin->pin !(isWiringContact inst)) + connected = (append connected (list (list inst pin))) + ) + ) + ) + ) + ) + ) + ) + ) + ) + connected + ) + ) + +; returns all wiring connected to a subcell pin +(defun ConnectedWiringFromSubcellPin (CV inst pin) + (let (connected overlaps transform bbox) + transform = (geGetInstTransform inst) + bbox = (geTransformUserBBox pin->bBox transform) + overlaps = (dbGetOverlaps CV bbox) + (foreach overlap overlaps + (cond ((areOverlappingObjectsConnected pin overlap) + connected = (append connected (ConnectedWiring CV overlap))) + ) + ) + connected + ) + ) + +; exchange L fpr R pins +(defun SwapLeftRightPins (inst pin) + (let (name term) + name = pin->net->name + (cond ((substring name 1 1)=="L" + name = (strcat "R" (substring name 2)) + term = (dbFindTermByName inst->master name) + pin = (car term->pins) + pin->fig) + (t nil) + ) + ) + ) + +; name instances of buffers encountered start at initial inst and pin +(defun NameBuffersRecursive (CV inst pin prefix index) + (let (wires inst_pins newinst newpin nextpin newname oldinst) + (cond ((inst==nil) wires = (ConnectedWiring CV pin)) + ((inst!=nil) wires = (ConnectedWiringFromSubcellPin CV inst pin)) + ) + (MarkWires wires) + inst_pins = (ConnectedSubcellPins CV wires) + (foreach inst_pin inst_pins + newinst = (car inst_pin) + newpin = (cadr inst_pin) + nextpin = (SwapLeftRightPins newinst newpin) + (cond ((and newinst->viewName=="wiring" newinst!=inst nextpin!=nil) + ; give this instance its proper name + (printf "%s -> %s[%d]\n" newinst->name prefix index) + newname = (sprintf nil "%s[%d]" prefix index) + oldinst = (dbFindAnyInstByName CV newname) + (cond (oldinst!=nil + oldinst->name = (sprintf nil "old_%s" oldinst->name) + ) + ) + newinst->name = newname + ; search for more buffers + (NameBuffersRecursive CV newinst nextpin prefix index+1)) + ) + ) + ) + t + ) + +; name instances of buffers encountered starting after initial instName and pinName +; must call SetBusMark before processing a non-conflicting set of these +(defun NameBuffers (instName pinName prefix @key (CV (geGetEditCellView))) + (let (inst term pin) + (cond ((instName!=nil) ; start with a subcell pin + inst = (dbFindAnyInstByName CV instName) + (cond ((or inst!=nil instName==nil) + term = (dbFindTermByName inst->master pinName) + pin = (car term->pins)->fig + (cond (pin!=nil + (NameBuffersRecursive CV inst pin prefix 0)) + (t + (printf "ERROR: can't find pin %s in instance %s\n" pinName instName)) + ) + ) + (t + (printf "ERROR: can't find instance %s\n" instName) + ) + ) + ) + ((instName==nil) ; start with top level pin + term = (dbFindTermByName CV pinName) + pin = (car term->pins)->fig + (cond (pin!=nil + (NameBuffersRecursive CV nil pin prefix 0)) + (t + (printf "ERROR: can't find pin %s\n" pinName)) + ) + ) + ) + ) + t + ) + +; infer SPEC subtypes from dfII, also list unique wiring-view cell types +(defun ScanSubtypes (@key (CV (geGetEditCellView))) + (let (file temp type subtypes types last) + + ; find wiring subcells + (foreach inst CV->instances + (cond (inst->viewName=="wiring" + temp = (parseString inst->cellName ".") + type = nil + (for i 0 (length temp)-2 + type = (append type (list (nth i temp))) + ) + type = (buildString type ".") + types = (cons inst->cellName types) + temp = (sprintf nil " %s :>\n %s %s;" + type inst->cellName inst->name) + subtypes = (cons temp subtypes) + ) + ) + ) + + ; sort and write subtypes + subtypes = (sort subtypes nil) + file = (outfile (sprintf nil "%s.subtypes" CV->cellName "w")) + (foreach subtype subtypes (fprintf file "%s\n" subtype)) + (close file) + + ; sort and write types + types = (sort types nil) + file = (outfile (sprintf nil "%s.types" CV->cellName "w")) + last = nil + (foreach type types + (cond (type!=last (fprintf file "%s\n" type))) + last = type + ) + (close file) + ) + t + ) + +; quickly scan pins to a userpins.il file +(defun ScanPins (@key (CV (geGetEditCellView))) + (let (file bbox x0 y0 x1 y1 name str pins) + (foreach obj CV->shapes + (cond (obj->pin + bbox = obj->bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + name = obj->net->name + str = (sprintf nil "(PinPlace \"%s\" (list %g:%g %g:%g) ?LPP (list \"%s\" \"%s\"))" + name x0 y0 x1 y1 obj->layerName obj->purpose) + pins = (cons str pins) + ) + ) + ) + + ; sort and write userpins.il + file = (outfile (sprintf nil "%s/userpins.il" + (NameGetCellPathFromCellName CV->cellName) "w")) + pins = (sort pins nil) + (foreach str pins (fprintf file "%s\n" str)) + (close file) + ) + t + ) + +; report what _RESET pins in wiring subcells are connected to +(defun ScanReset (@key (CV (geGetEditCellView))) + (let (file term pin wiring str resets name sub) + (rexCompile "^standard\\.reset\\.BUF_RESET\\.") + (SetBusMark CV) + (foreach inst CV->instances + (cond (inst->viewName=="wiring" + term = (dbFindTermByName inst->master "_RESET") + (cond (term + name = "_RESET" + + ; find wiring connected to this instances _RESET pin + pin = (car term->pins)->fig + wiring = (ConnectedWiringFromSubcellPin CV inst pin) + (SetBusMarkForObjects wiring) + + ; look for outputs of BUF_RESET's + inst_pins = (ConnectedSubcellPins CV wiring) + (foreach inst_pin inst_pins + sub = (car inst_pin) + pin = (cadr inst_pin) + (cond ((and (rexExecute sub->master->cellName) + pin->net->name=="_RES") + name = (sprintf nil "%s._RES" sub->name) + ) + ) + ) + + ; look for top level pins + (foreach obj wiring (cond (obj->pin name = obj->net->name))) + str = (sprintf nil "%s._RESET = %s" inst->name name) + + ; append to list of resets found + resets = (cons str resets) + ) + ) + ) + ) + ) + (ClearBusMark CV) + + ; sort and write userpins.il + file = (outfile (sprintf nil "%s.resets" CV->cellName "w")) + resets = (sort resets nil) + (foreach str resets (fprintf file "%s\n" str)) + (close file) + ) + t + ) + +; check a single object for a power short +(defun CheckObjectPowerShort (obj grid distance) + (let (x0 y0 x1 y1 gx0 gy0 gx1 gy1 bbox) + bbox = obj->bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + gx0 = grid * (round x0/grid) + gy0 = grid * (round y0/grid) + gx1 = grid * (round x1/grid) + gy1 = grid * (round y1/grid) + (cond ((or (and (isWiringPath obj) + (or obj->layerName==(car Metal2LPP) + obj->layerName==(car Metal4LPP) + obj->layerName==(car Metal6LPP)) + (or ((abs x0-gx0)layerName==(car Metal3LPP) + obj->layerName==(car Metal5LPP) + obj->layerName==(car Metal7LPP)) + (or ((abs y0-gy0)shapes + shorts = shorts+(CheckObjectPowerShort shape grid distance)) + (foreach inst CV->instances + shorts = shorts+(CheckObjectPowerShort inst grid distance)) + shorts + ) + ) + +; open a list of CellViews named in a file +(defun OpenCellViewsFromFile (filename viewName mode) + (let (cells file cellName libName temp CellView) + file = (infile filename) + (cond (file==nil (printf "ERROR: can't read file %s" filename)) + (t + (while (gets line file) + cellName = (StringUtilChompNewline line) + temp = (parseString cellName ".") + libName = nil + (for i 0 (length temp)-3 + libName = (append libName (list (nth i temp))) + ) + libName = (buildString libName ".") + CellView = (dbOpenCellViewByType libName cellName viewName nil mode) + (cond (CellView==nil + (printf "ERROR: can't open %s %s %s in mode %s\n" + libName cellName viewName mode)) + (t cells = (cons CellView cells)) + ) + ) + (close file) + ) + ) + cells + ) + ) + + + +; this is a bit hackish, but the idea is that you can instantiate a cell +; inside the buswires cell that contains a collection of paths from a previous +; subcell. the instance name of the subcell serves as a hierarchical prefix +; to be attached to the names. +; this seemed the best way to reuse a collection of subcell pins which are +; not all on the same layer or contain a mixture of flippings, neither of which +; can be done in a DefChan. +(defun ProcessBuswiresSubcell () + (let (wirescell wirescv subcell prefix newpath pathname newname flipx flipy) + wirescell=(GetGuideInst nil busGuideInstName) + wirescv=(nrOpenCellViewWritable wirescell->libName wirescell->cellName wirescell->viewName ?mode "a") + subcells=wirescv->instances + + ;clear any previously promoted paths + (foreach shape wirescv->shapes + (when (IsBusSubcellPath shape) + (dbDeleteObject shape) + ) + ) + + (foreach subcell subcells + prefix=subcell->name + (foreach shape subcell->master->shapes + (when shape->objType=="path" && (cadr shape->lpp)=="bus" + newpath=(dbCopyFig shape wirescv subcell->transform) + (SetBusSubcellProp newpath) + pathname=(GetProp newpath "BusPrefix" nil) + newname=(strcat prefix "." pathname) + (dbReplaceProp newpath "BusPrefix" "string" newname) + + (when subcell->orient=="MX" || subcell->orient=="R180" + flipy=(GetProp newpath "BusFlipY" nil) + (if flipy then + (dbReplaceProp newpath "BusFlipY" "boolean" nil) + else + (dbReplaceProp newpath "BusFlipY" "boolean" t) + ) + ) + (when subcell->orient=="MY" || subcell->orient=="R180" + flipx=(GetProp newpath "BusFlipX" nil) + (if flipx then + (dbReplaceProp newpath "BusFlipX" "boolean" nil) + else + (dbReplaceProp newpath "BusFlipX" "boolean" t) + ) + ) + + ) + ) + ) + ) +) + + +(defun SetBusSubcellProp (obj) + (when obj + (dbReplaceProp obj "BusSubcellPath" "boolean" t) + ) +) + +(defun IsBusSubcellPath (obj) + (let (isbus) + isbus = nil + (when obj + isbus=(dbGetPropByName obj "BusSubcellPath") + ) + isbus + ) +) + +(defun DoubleViaCorrection (point hv dir pattern flipX flipY) + let( (newpoint corrected up Flip) + corrected = nil + Flip = (flipX || flipY) && !(flipX && flipY) +; if( nth(2 car(pattern)) != 0 +; then + corrected = t + if( hv == "HV" + then + if( (dir == "P" && Flip) || (dir == "N" && !Flip) + then + newpoint = car(point)-(TrackPitch/24):cadr(point) + else + newpoint = car(point)+(TrackPitch/24):cadr(point) + ) + else + if( (dir == "P" && Flip) || (dir == "N" && !Flip) + then + newpoint = car(point)+(TrackPitch/24):cadr(point) + else + newpoint = car(point)-(TrackPitch/24):cadr(point) + ) + ) +; else +; newpoint = point +; ) + + list(newpoint corrected) + ) +) + +(defun VerticalViaCorrection (point hv dir pattern flipX flipY positiveVias) + let( (newpoint corrected up Flip) + corrected = nil + Flip = (flipX || flipY) && !(flipX && flipY) + corrected = nil + when(positiveVias==nil + newpoint = car(point):cadr(point)-(TrackPitch/24)) + when(positiveVias==t + newpoint = car(point):cadr(point)+(TrackPitch/24)) + list(newpoint corrected) + )) + +(defun ClassifyDirs (points) + let( ((types (ClassifyPoints points)) Idx dirs currPt comparePt) + + for( Idx 0 length(points)-1 + + when( nth(Idx types) == "VE" || nth(Idx types) == "HE" || nth(Idx types) == "EV" || nth(Idx types) == "EH" + dirs = cons(nil dirs) + ) + + when( nth(Idx types) == "HV" + currPt = nth(Idx points) + comparePt = nth(Idx+1 points) + if( cadr(currPt) < cadr(comparePt) + then + dirs = cons("P" dirs) + else + dirs = cons("N" dirs) + ) + ) + + when( nth(Idx types) == "VH" + currPt = nth(Idx points) + comparePt = nth(Idx-1 points) + if( cadr(currPt) > cadr(comparePt) + then + dirs = cons("P" dirs) + else + dirs = cons("N" dirs) + ) + ) + ) + + reverse(dirs) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus28.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus28.il new file mode 100644 index 0000000000..cc2ffa4162 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus28.il @@ -0,0 +1,151 @@ +(defun busnew () + (let (view shapes) + view = (geGetEditCellView) + fl = infile("/home/user/vjain/alpine/bus.list") + ;gets(k fl) + while(gets(k fl) != nil + text1 = parseString(k "\n") + txt=car(text1) + ;point1=car(evalstring(car(text1))) + (when (txt!="OBS") + point1=car(evalstring(car(text1))) + ;text = parseString(k "\n") + ;point=evalstring(car(text)) + gets(k fl) + text = parseString(k "\n") + point=evalstring(car(text)) + ;text1 = parseString(k "\n") + ;point1=car(evalstring(car(text1))) + x=dbCreatePath(view (list point1 "bus") point 0.06) + ;(dbReplaceProp x "BusPattern" "boolean" t) + gets(k fl) + ;s=car((wcv()->shapes)) + ;(dbReplaceProp s "BusPattern" "boolean" t) + gets(k fl) + text2 = parseString(k " \n") + point2=car(text2) + ;(dbReplaceProp x "BusPattern" "string" point2) + gets(k fl) + text3 = parseString(k " \n") + point3=car(text3) + (dbReplaceProp x "BusPattern" "string" point2) + (when (k==" \n") + (dbReplaceProp x "BusPrefix" "string" " ")) + (when (k!=" \n") + (dbReplaceProp x "BusPrefix" "string" point3)) + gets(k fl) + text4 = parseString(k " \n") + point4=car(text4) + (dbReplaceProp x "BusPin" "boolean" point4) + gets(k fl) + text5 = parseString(k " \n") + point5=car(text5) + (dbReplaceProp x "BusFlipX" "boolean" point5) + gets(k fl) + text6 = parseString(k " \n") + point6=car(text6) + (dbReplaceProp x "BusFlipY" "boolean" point6) + gets(k fl) + text7 = parseString(k " \n") + point7=car(text7) + (dbReplaceProp x "BusStartVias" "boolean" point7) + gets(k fl) + text8 = parseString(k " \n") + point8=car(text8) + (dbReplaceProp x "BusEndVias" "boolean" point8) + gets(k fl) + text9 = parseString(k " \n") + point9=evalstring(car(text9)) + (dbReplaceProp x "BusArrayPitch" "float" point9) + gets(k fl) + text10 = parseString(k " \n") + point10=car(text10) + (dbReplaceProp x "BusDoubleVias" "boolean" point10) + gets(k fl) + gets(k fl) + ) + (when (txt=="OBS") + gets(k fl) + text11 = parseString(k "\n") + point11=evalstring(car(text11)) + (when (k!="list()\n") + x=dbCreatePolygon(view (list "OBS" "bus") point11) + gets(k fl) + gets(k fl) + text1 = parseString(k " \n") + point1=car(text1) + (dbReplaceProp x "M2" "boolean" point1) + gets(k fl) + text2 = parseString(k " \n") + point2=car(text2) + (dbReplaceProp x "M3" "boolean" point2) + gets(k fl) + text3 = parseString(k " \n") + point3=car(text3) + (dbReplaceProp x "M4" "boolean" point3) + gets(k fl) + text4 = parseString(k " \n") + point4=car(text4) + (dbReplaceProp x "M5" "boolean" point4) + gets(k fl) + text5 = parseString(k " \n") + point5=car(text5) + (dbReplaceProp x "M6" "boolean" point5) + gets(k fl) + text6 = parseString(k " \n") + point6=car(text6) + (dbReplaceProp x "M7" "boolean" point6) + gets(k fl) + text7 = parseString(k " \n") + point7=car(text7) + (dbReplaceProp x "M1" "boolean" point7) + gets(k fl) + gets(k fl) + gets(k fl) + gets(k fl) + + ) + (when (k=="list()\n") + gets(k fl) + text12 = parseString(k "\n") + point12=evalstring(car(text12)) + x=dbCreateRect(view (list "OBS" "bus") point12) + gets(k fl) + text1 = parseString(k " \n") + point1=car(text1) + (dbReplaceProp x "M2" "boolean" point1) + gets(k fl) + text2 = parseString(k " \n") + point2=car(text2) + (dbReplaceProp x "M3" "boolean" point2) + gets(k fl) + text3 = parseString(k " \n") + point3=car(text3) + (dbReplaceProp x "M4" "boolean" point3) + gets(k fl) + text4 = parseString(k " \n") + point4=car(text4) + (dbReplaceProp x "M5" "boolean" point4) + gets(k fl) + text5 = parseString(k " \n") + point5=car(text5) + (dbReplaceProp x "M6" "boolean" point5) + gets(k fl) + text6 = parseString(k " \n") + point6=car(text6) + (dbReplaceProp x "M7" "boolean" point6) + gets(k fl) + text7 = parseString(k " \n") + point7=car(text7) + (dbReplaceProp x "M1" "boolean" point7) + gets(k fl) + gets(k fl) + gets(k fl) + gets(k fl) + + ) + ) +))) +;) +;close(out) +;)) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus65.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus65.il new file mode 100644 index 0000000000..6ea27a00cb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus65.il @@ -0,0 +1,114 @@ +;out = outfile("/home/user/vjain/alpine/bus.list") + +(defun busold () + (let (view shapes) + view = (geGetEditCellView) + out = outfile("/home/user/vjain/alpine/bus.list") + (foreach shape view->shapes + (when (shape->layerName!="OBS") + (when (shape->purpose=="bus") + ;out = outfile("/home/user/vjain/alpine/bus.list") + Pattern=(dbGetPropByName shape "BusPattern")->value + Prefix=(dbGetPropByName shape "BusPrefix")->value + Pin=(dbGetPropByName shape "BusPin")->value + FlipX=(dbGetPropByName shape "BusFlipX")->value + FlipY=(dbGetPropByName shape "BusFlipY")->value + StartVias=(dbGetPropByName shape "BusStartVias")->value + EndVias=(dbGetPropByName shape "BusEndVias")->value + ArrayPitch=((dbGetPropByName shape "BusArrayPitch")->value)/1.846 + DoubleVias=(dbGetPropByName shape "BusDoubleVias")->value + Layer=(shape->layerName) + boundingBox=(shape->bBox) + cord=(shape->points) + Width=(shape->width)/2 + bends=(shape->nPoints) + fprintf(out "%s\n" Layer) + fprintf(out "list(") + (foreach point shape->points + point1=((car point)/1.846) + point2=((cadr point)/1.846) + fprintf(out "%.2f:%.2f " point1 point2) + ) + fprintf(out ")\n") + ;fprintf(out "%s\n" Layer) + fprintf(out "bBox ") + (foreach box shape->bBox + box1=((car box)/1.846) + box2=((cadr box)/1.846) + fprintf(out "%.2f %.2f " box1 box2) + ) + fprintf(out "\n") + fprintf(out "%s \n" Pattern) + fprintf(out "%s \n" Prefix) + fprintf(out "%s \n" Pin) + fprintf(out "%s \n" FlipX) + fprintf(out "%s \n" FlipY) + fprintf(out "%s \n" StartVias) + fprintf(out "%s \n" EndVias) + fprintf(out "%.2f \n" ArrayPitch) + fprintf(out "%s \n" DoubleVias) + fprintf(out "%.2f \n" Width) + fprintf(out "%d \n" bends) + print(Pattern) + print(Prefix) + print(Pin) + print(FlipX) + print(FlipY) + print(StartVias) + print(EndVias) + print(ArrayPitch) + print(DoubleVias) + print(Layer) + print(boundingBox) + print(cord) + print(Width) + print(bends) + )) + (when (shape->layerName=="OBS") + MTWO=(dbGetPropByName shape "M2")->value + MTHREE=(dbGetPropByName shape "M3")->value + MFOUR=(dbGetPropByName shape "M4")->value + MFIVE=(dbGetPropByName shape "M5")->value + MSIX=(dbGetPropByName shape "M6")->value + MSEVEN=(dbGetPropByName shape "M7")->value + MONE=(dbGetPropByName shape "M1")->value + Layer=(shape->layerName) + fprintf(out "%s\n" Layer) + fprintf(out "list(") + (foreach point shape->points + point1=((car point)/1.846) + point2=((cadr point)/1.846) + fprintf(out "%.2f:%.2f " point1 point2) + ) + fprintf(out ")\n") + ;Layer=(shape->layerName) + ;fprintf(out "%s \n" Layer) + fprintf(out "list(") + (foreach box shape->bBox + box1=((car box)/1.846) + box2=((cadr box)/1.846) + fprintf(out "%.2f:%.2f " box1 box2) + ) + fprintf(out ")\n") + ;Layer=(shape->layerName) + ;fprintf(out "%s \n" Layer) + fprintf(out "%s \n" MTWO) + fprintf(out "%s \n" MTHREE) + fprintf(out "%s \n" MFOUR) + fprintf(out "%s \n" MFIVE) + fprintf(out "%s \n" MSIX) + fprintf(out "%s \n" MSEVEN) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + + + + ) + +) +) + close(out) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/fat.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/fat.il new file mode 100644 index 0000000000..6d0de2b34e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/fat.il @@ -0,0 +1,980 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus.il#5 $ +; $DateTime: 2006/12/09 12:58:15 $ +; $Author: lines $ +; +; User must set bundled_channels in wires.il. The syntax is a list of +; lists. The inner list starts with the BusPattern name followed by 1 +; or more BusPrefix's. For example: +; +; bundled_channels = (list (list "e1of4" "x" "y") (list "e1of2" "z")) +; +; The [lo..hi] will be expanded. + +; Export, Route, Import using CCAR with bundled channels +(defun BundledRoute + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (bottomMetal nil) ; bottom metal layer to use, or nil to use wires.il + (topMetal nil) ; top metal layer to use, or nil to use wires.il + (routeWires t) ; route regular wires in parallel with bundled channels + (SaveQuit nil) ; automatically save and quit CCAR + (Background nil) ; run in foreground or background + (viaType "c") ; via type ("c"/"min") + (subcellView "abstract_edit abstract") ; alternate views of subcells + (importView "layout_pg") ; view name to import wiring back to + (type "fat") ; routing rul/do file to use from PDK ("fat"/"fat_onepass") + (retry t) ; automatic retry + ) + (let (TEMP FulcrumPDKRoot RouterPDK DoFile RouterDoFile BundledDoFile SaveQuitStr + LCV rules options session status win flattenCV cmd) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + + ; make flatten view automatically + (when (or CV->viewName=="floorplan" CV->viewName=="prelayout") + CV = (MakeFlatten ?CV CV)) + flattenCV = CV + + ; get config settings + SaveQuit = (or SaveQuit Background) + FulcrumPDKRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + RouterPDK = (sprintf nil "%s/share/Fulcrum/cell_automation/router" FulcrumPDKRoot) + DoFile = (sprintf nil "%s/%s.do" RouterPDK type) + SaveQuitStr = (sprintf nil "-do %s/savequit.do" RouterPDK) + + ; load wires.il and set options + (LoadWires) + (unless bundled_channels (error "No bundled_channels defined in wires.il\n")) + (unless bottomMetal bottomMetal = bundled_bottom_layer) + (unless topMetal topMetal = bundled_top_layer) + + ; prepare bundled view + CV = (CreateBundledView CV routeWires subcellView ?bottomMetal bottomMetal) + + ; write do files + (when routeWires + RouterDoFile = (WriteRouterDoFile CV ?viaType viaType + ?bottomMetal bottomMetal ?topMetal topMetal)) + BundledDoFile = (WriteBundledDoFile CV ?bottomMetal bottomMetal ?topMetal topMetal + ?routeWires routeWires) + + ; options + LCV = (list CV->libName CV->cellName CV->viewName) + rules = (sprintf nil "%s/%s.rul" RouterPDK type) + options = (sprintf nil "-guidir %s -noclean -virtuoso -do %s %s -do %s %s" + TEMP BundledDoFile + (if routeWires (sprintf nil "-do %s" RouterDoFile) "") + DoFile + (if SaveQuit SaveQuitStr "")) + session = (sprintf nil "%s/%s.ses" TEMP CV->cellName) + (shell (sprintf nil "rm -f %s" session)) + + ; export + status = (iccExportCellview + ?layoutLCV LCV + ?background nil + ?exportDirectory TEMP + ?rulesFile rules + ?conductorDepth 32 + ?keepoutDepth 32 + ?pinConnection "strong" + ?optionList (list "fullConnectivity" "interLayer") + ?startICC nil) + (unless status (error "Unable to export to VCAR\n")) + + ; route + cmd = (sprintf nil "vcar %s/%s.dsn %s %s" TEMP CV->cellName options + (if Background "-nog &" "")) + (printf "%s\n" cmd) + status = nil + (while !status + status = (shell cmd) + (unless status || retry (error "VCAR failed. Inspect *.did file.\n")) + (unless status + (printf "Unable to run VCAR, retrying...\n") + (sleep 30) + ) + ) + + ; import from VCAR + (cond (Background (printf "Running in background, finish with BundledRouteImport\n")) + (t CV = (BundledRouteImport ?CV flattenCV ?importView importView)) + ) + CV + ) + ) + +; Import from VCAR and post-process +(defun BundledRouteImport + (@key (CV (geGetEditCellView)) + (importView "layout_pg") + ) + (let (TEMP session status win) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + session = (sprintf nil "%s/%s.ses" TEMP CV->cellName) + + ; import from CCAR + status = (iccImportCellview + ?layoutLCV (list CV->libName CV->cellName "bundled") + ?iccFile session + ?background nil) + (unless status (error "Unable to import from VCAR\n")) + + ; post-process the routes + CV = (FinishBundledImport CV ?importView importView) + + ; change to importView + win = (hiGetCurrentWindow) + (unless win (error "Can't change to view %s\n" importView)) + (geOpen ?window win + ?lib CV->libName + ?cell CV->cellName + ?view CV->viewName + ?viewType "maskLayout" + ?mode "a") + + ; draw new bundled bus wires only + (DrawTracks ?guideInstName "autobuswires") + + ; canonicalize net names + (CanonicalizeNets ?CV CV) + + ; execute custom function + (FinishRouterImport) + + ; save importView + (dbSave CV) + + ; create layout view + (MakeLayout ?CV CV) + CV + ) + ) + +; write FQCN_bundled.do for CCAR +(defun WriteBundledDoFile (CV @key (bottomMetal 2) (topMetal 7) (routeWires nil)) + (let (name TEMP file nets) + + ; find all matching e rails + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + + ; write CCAR do file + name = (sprintf nil "%s/%s_bundled.do" TEMP CV->cellName) + file = (outfile name "w") + (unless routeWires (fprintf file "define (class RESET_3W3S)\n")) ; make sure it exists + (fprintf file "# Bundled channel rules\n") + (fprintf file "define (class BUNDLED_CHANNEL\n") + (foreach net (BundledNets CV) (fprintf file " %s\n" net->name)) + (fprintf file ")\n") + (fprintf file "rule class BUNDLED_CHANNEL (width 2.28)\n") + (fprintf file "rule class BUNDLED_CHANNEL (clearance 0.12)\n") + (fprintf file "rule class BUNDLED_CHANNEL (pin_width_taper off)\n") + (fprintf file "rule class BUNDLED_CHANNEL (limit_way 0)\n") + (fprintf file "circuit class BUNDLED_CHANNEL (length 1.1 -1 (type ratio))\n") + (fprintf file "circuit class BUNDLED_CHANNEL (length 900 -1 (type actual))\n") + (fprintf file "circuit class BUNDLED_CHANNEL (use_via") + (for layer bottomMetal topMetal + (when layer>=3 (fprintf file " M%d_M%d_FAT" layer layer-1))) + (fprintf file ")\n") + (close file) + name + ) + ) + +; Prepare Bundled View for Export +(defun CreateBundledView (CV routeWires subcellView @key (bottomMetal 2)) + (let (bundled_nets GND Vdd) + + ; copy to bundled view + CV = (dbCopyCellView CV CV->libName CV->cellName "bundled" nil nil t) + + ; DrawBundledPins + (DrawBundledPins CV) + + ; change subcells to subcellView + (when subcellView!="" + (foreach inst CV->instances + (when inst->libName!=TechLibName + (ChangeView inst (parseString subcellView " ")) + ) + ) + ) + + ; flatten subcells and vias for CCAR + (FlattenAbstractSubcells CV) + + ; delete labels + (DeleteLabels ?CV CV) + + ; unconnect individual rails of bundled channels + (DisconnectBundledPins CV) + + ; delete non-bundled nets + (when routeWires==nil (DeleteNonBundledNets CV)) + + ; delete power supply nets + GND = (dbFindNetByName CV "GND") + (when GND (dbDeleteObject GND)) + Vdd = (dbFindNetByName CV "Vdd") + (when Vdd (dbDeleteObject Vdd)) + + ; convert unconnected shapes to keepout + (ConvertUnconnectedShapesToKeepout CV) + + ; convert preroutes to polygons instead of paths + (ConvertPreroutedPaths CV) + + ; draw M2 keepout stripes + (when bottomMetal<=2 (DrawMetal2KeepoutStripes CV)) + + ; return bundled CellView + (dbSave CV) + CV + ) + ) + +; Post-processing after import from CCAR +(defun FinishBundledImport (CV @key (importView "layout_pg")) + (let (srcCV dstCV pgCV buswires libName cellName viewName + components baseName win newobj) + libName = CV->libName + cellName = CV->cellName + viewName = CV->viewName + win = (hiGetCurrentWindow) + + ; create name of buswires cell + components = (parseString cellName ".") + baseName = (cadr (reverse components)) + buswires = (strcat libName ".wires." baseName "_autobuswires") + + ; find relevant views + dstCV = (dbOpenCellViewByType libName buswires "layout" "maskLayout" "w") + srcCV = (dbOpenCellViewByType libName cellName "bundled") + (cond (importView!=CV->viewName + pgCV = (dbCopyCellView CV libName cellName importView nil nil t)) + (t pgCV=CV) + ) + (if (and dstCV srcCV pgCV)==nil (error "Unable to open import views\n")) + + ; draw guide paths to autobuswires cell + win = (geOpen ?window win ?lib dstCV->libName + ?cell dstCV->cellName ?view dstCV->viewName + ?viewType "maskLayout" ?mode "a" ) + (DrawBundledChannels srcCV) + (dbSave srcCV) + (dbSave dstCV) + + ; import remaining wires to layout_pg view + win = (geOpen ?window win ?lib libName + ?cell cellName ?view "layout_pg" + ?viewType "maskLayout" ?mode "a") + + ; delete prerouted contacts + (DeleteDuplicateContacts srcCV) + + ; copy new wires and vias back to layout_pg + (CopyPathsAndContactsWithConnectivity srcCV pgCV) + + ; add autobuswires instance + (dbCreateInst pgCV dstCV "autobuswires" 0:0 "R0") + + ; save and return layout_pg + (dbSave pgCV) + pgCV + ) + ) + +; delete prerouted contacts in bundled view +(defun DeleteDuplicateContacts (CV) + (let (net) + (foreach contact CV->instances + (when (and contact->libName==TechLibName contact->terminals) + net = (car contact->terminals)->net + (when (and net (dbGetPropByName net "BusPrefixes")) + (dbDeleteObject contact) + ) + ) + ) + ) + t + ) + +; shortcut to add autobuswires to current CV +(defun AddAutoBusWires (@key (CV (geGetEditCellView))) + (AddBusWires ?CV CV ?name "autobuswires") + ) + +; enumerate bundled nets +(defun BundledNets (CV) + (setof net CV->nets (dbGetPropByName net "BusPrefixes")!=nil) + ) + +; flatten abstract subcells +(defun FlattenAbstractSubcells (CV) + (foreach inst CV->instances + (cond (inst->libName==TechLibName nil) + (t + (dbFlattenInst inst 1 nil t t) + ) + ) + ) + t + ) + +; disconnect shapes that overlap bundled pins +(defun DisconnectBundledPins (CV) + (let (overlaps) + (foreach net (BundledNets CV) + (foreach pin net->pins + (when (GetProp pin->fig "PinType" nil)=="BundledPin" + overlaps = (FindMetalOverlaps CV pin->fig->bBox pin->fig->layerName) + (foreach obj overlaps + (when (GetProp obj "PinType" nil)!="BundledPin" + (dbReplaceProp obj->net "BundledNet" "boolean" t) + obj->lpp = (list (car obj->lpp) "boundary") + (when obj->pin (dbDeleteObject obj->pin)) + ) + ) + overlaps = (FindContactOverlaps CV pin->fig->bBox pin->fig->layerName) + (foreach obj overlaps + (foreach term obj->terminals term->net=nil) + ) + ) + ) + ) + ) + t + ) + +; delete nets that aren't bundled +(defun DeleteNonBundledNets (CV) + (foreach net CV->nets + (when (dbGetPropByName net "BusPrefixes")==nil + (dbDeleteObject net)) + ) + t + ) + +; turn unconnected shapes into keepout +(defun ConvertUnconnectedShapesToKeepout (CV) + (let (layer purpose) + (foreach shape CV->shapes + layer = (car shape->lpp) + purpose = (cadr shape->lpp) + (when (and shape->net==nil (isMetal layer) + (or purpose=="drawing" purpose=="net" + purpose=="vdd" purpose=="gnd")) + shape->lpp = (list (car shape->lpp) "boundary") ) + ) + ) + t + ) + +; paint a grid of M2 keepout to force fat wires to be on grid +(defun DrawMetal2KeepoutStripes (CV) + (let (bBox x0 x1 y0 y1 i0 i1 j0 j1 scratchlpp1 scratchlpp2) + ; draw stripes + scratchlpp1=NRegionLPP + scratchlpp2=PRegionLPP + bBox = CV->bBox + x0 = (car (car bBox)) + x1 = (car (cadr bBox)) + y0 = (cadr (car bBox)) + y1 = (cadr (cadr bBox)) + i0 = (round (x0+0.24)/2.88) + i1 = (round (x1-0.24)/2.88) + j0 = (round (y0+0.24)/2.88) + j1 = (round (y1-0.24)/2.88) + (for i i0 i1 (dbCreateRect CV scratchlpp1 (list 2.88*i-0.18:y0 2.88*i+0.18:y1))) + + ; trim M2 stripes keepout around M2 pins + (foreach purpose (list "net" "drawing" "pin") + (leLayerSize CV (list "M2" purpose) DefaultWiringSpacing scratchlpp2) + ) + (leLayerAndNot CV scratchlpp1 scratchlpp2 Metal2byLPP) + (foreach shape CV->shapes + (when shape->lpp==scratchlpp2 (dbDeleteObject shape)) + (when shape->lpp==scratchlpp1 (dbDeleteObject shape)) + ) + ) + t + ) + +; Convert prerouted paths to polygons to distinguish them from routed wires +(defun ConvertPreroutedPaths (CV) + (foreach path CV->shapes + (when path->objType=="path" (dbConvertPathToPolygon path)) + ) + t + ) + +; search for nets of overlapping bundled pin +(defun FindOverlappingBundledShape (CV bbox lpp) + (let (overlaps overlap) + overlap = nil + overlaps = (dbGetOverlaps CV bbox lpp 0) + (foreach shape overlaps + (when (GetProp shape "PinType" nil)=="BundledPin" + overlap = shape + ) + ) + overlap + ) + ) + +; draw bundled pin +(defun DrawBundledPin (net bbox lpp pattern flip) + (let (horz x0 y0 x1 y1 x y flipX flipY rect oshape onet p prefixes patterns small) + x = (car (car bbox)) + y = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + x0 = (min x x1) + x1 = (max x x1) + y0 = (min y y1) + y1 = (max y y1) + flipX = nil + flipY = nil + small = nil + x = (x0+x1)/2 + y = (y0+y1)/2 + horz = (IsLayerHorizontal (car lpp)) + (cond (horz + y0 = (round y0/2.88-0.5)*2.88 + 0.18 + y1 = (round y1/2.88+0.5)*2.88 - 0.18 + flipY = y-y0>y1-y != flip + (when (round (x0-0.3)/2.88+0.5)>=(round (x1+0.3)/2.88-0.5) small=t) + ) + (t + x0 = (round x0/2.88-0.5)*2.88 + 0.18 + x1 = (round x1/2.88+0.5)*2.88 - 0.18 + flipX = x-x0>x1-x != flip + (when (round (y0-0.3)/2.88+0.5)>=(round (y1+0.3)/2.88-0.5) small=t) + ) + ) + (when small (printf "WARNING: pin %s at %g:%g on %s is small or poorly aligned.\n" + net->name x y (car lpp))) + bbox = (list x0:y0 x1:y1) + oshape = (FindOverlappingBundledShape CV bbox lpp) + (cond (oshape + ; combine with overlapping bundled pin + onet = oshape->net + oshape->bBox = (BBoxCombine oshape->bBox bbox) + p = (dbGetPropByName onet "BusPrefixes") + (cond ((member net->name p->value)==nil + (printf "Appending %s to same path as %s\n" net->name (car p->value)) + prefixes = (cons net->name p->value) + p = (dbGetPropByName onet "BusPatterns") + patterns = (cons pattern p->value) + (dbReplaceProp onet "BusPrefixes" "list" prefixes) + (dbReplaceProp onet "BusPatterns" "list" patterns) + ) + ) + ) + (t + ; create new bundled pin + rect = (dbCreateRect CV lpp bbox) + (dbReplaceProp rect "PinType" "string" "BundledPin") + (cond (horz (dbReplaceProp rect "FlipY" "boolean" flipY)) + (t (dbReplaceProp rect "FlipX" "boolean" flipX)) + ) + (dbCreatePin net rect) + (cond (horz rect->pin->accessDir = (list "left" "right")) + (t rect->pin->accessDir = (list "top" "bottom")) + ) + (cond ((dbGetPropByName net "BusPrefixes")==nil + bundled_nets = (cons net bundled_nets))) + (dbReplaceProp net "BusPrefixes" "list" (list net->name)) + (dbReplaceProp net "BusPatterns" "list" (list pattern)) + ) + ) + ) + t + ) + +; Expand bundled_channels for debugging +(defun MatchBundledChannelsCore (CV) + (let (names canonMap canonName patlist pattern i buspattern name net result net_tbl + railflip) + ; first pass to find net names + (foreach entry bundled_channels + patlist = (car entry) + patlist = (if (atom patlist) (list patlist) patlist) + i=0 + (foreach chan (ExpandArrayRanges (cdr entry)) + pattern = (nth (mod i (length patlist)) patlist) + i=i+1 + buspattern = (MapBusPattern pattern) + (unless buspattern (error "BusPattern %s unsupported\n" pattern)) + railflip = (BusPatternReference buspattern) + name = (sprintf nil "%s%s" chan (car railflip)) + names = (cons name names) + ) + ) + ; query cast to get canonical name mapping + canonMap = (CanonicalizeNetNames names ?CV CV) + net_tbl = (makeTable "net added" nil) + ; second pass + (foreach entry bundled_channels + patlist = (car entry) + patlist = (if (atom patlist) (list patlist) patlist) + i=0 + (foreach chan (ExpandArrayRanges (cdr entry)) + pattern = (nth (mod i (length patlist)) patlist) + i=i+1 + buspattern = (MapBusPattern pattern) + (unless buspattern (error "BusPattern %s unsupported\n" pattern)) + railflip = (BusPatternReference buspattern) + name = (sprintf nil "%s%s" chan (car railflip)) + canonName = (arrayref canonMap name) + (unless canonName (error "%s is not a local node\n" name)) + net = (dbFindNetByName CV canonName) + (unless net (error "Can't find rail %s\n" canonName)) + e = (list pattern chan buspattern net (cadr railflip)) + (unless net_tbl[net] ; uniquify list + net_tbl[net] = t + result = (append result (list e)) + ) + ) + ) + result + ) + ) + +; Pick a reference rail to detect flipX/flipY. Returns the suffix and +; a boolean for if it should be in the top half of a track. +(defun BusPatternReference (pattern) + (let (suffix flip) + (foreach rail (reverse pattern) + (when (caddr rail)!=0 && (car rail)!="GND" + suffix=(car rail) flip=(caddr rail)>0) + ) + (unless suffix suffix=(car (car pattern))) + (list suffix flip) + ) + ) + +; for user feedback +(defun MatchBundledChannels (@key (CV (geGetEditCellView))) + (LoadWires) + (foreach entry (MatchBundledChannelsCore CV) + (printf "Pattern=%s Channel=%s\n" (car entry) (cadr entry)) + ) + t + ) + +; convert to bundled pins +(defun DrawBundledPins (CV) + (let (pattern chan buspattern net cnet transform ubox) + (foreach entry (MatchBundledChannelsCore CV) + + ; extract channel information + pattern = (car entry) + chan = (cadr entry) + buspattern = (caddr entry) + net = (cadddr entry) + flip = (nth 4 entry) + (printf "Pattern=%s Channel=%s\n" pattern chan) + + ; create net for channel + cnet = (MakeNet CV chan) + + ; paint fat pins over top-level bundled pins + (foreach pin net->pins + (DrawBundledPin cnet pin->fig->bBox pin->fig->lpp pattern flip)) + + ; paint fat pins over subcell bundled pins + (foreach instTerm net->instTerms + inst = instTerm->inst + (cond (inst->libName!=TechLibName + transform = (geGetInstTransform inst) + (foreach pin instTerm->term->pins + ubox = (geTransformUserBBox + pin->fig->bBox transform) + (DrawBundledPin cnet ubox + pin->fig->lpp pattern flip) + ) + ) + ) + ) + + ; paint fat pins over prerouted nets + (foreach fig net->figs + (DrawBundledPin cnet fig->bBox fig->lpp pattern flip) + ) + ) + t + ) + ) + +; draw all declared bundled channels +(defun DrawBundledChannels (CV) + (foreach net (BundledNets CV) (DrawBundledChannel CV net)) + t + ) + +; draw just one bundled channel by channel name +(defun DrawBundledChannel (CV net) + (let (selected delpaths paths contacts overlaps + layers points xy x y flipX flipY pattern prefix) + + ; channel properties + (printf "Guide Channel=%s\n" net->name) + + ; overlapping patterns and prefixes + prefix = (buildString (dbGetPropByName net "BusPrefixes")->value " ") + pattern = (buildString (dbGetPropByName net "BusPatterns")->value " ") + + ; find paths and contacts for bundled channels + paths = (setof obj CV->shapes + (and obj->objType=="path" + obj->net==net) + ) + contacts = (setof obj CV->instances + (and obj->objType=="inst" + obj->libName==TechLibName + (BBoxGetWidth obj->bBox)>PowerGridPitch/2 + (BBoxGetHeight obj->bBox)>PowerGridPitch/2 + (or obj->cellName=="M7_M6_FAT" + obj->cellName=="M6_M5_FAT" + obj->cellName=="M5_M4_FAT" + obj->cellName=="M4_M3_FAT" + obj->cellName=="M3_M2_FAT" + ; NOTE: CCAR doesn't use FAT vias reliably! + obj->cellName=="M7_M6c" + obj->cellName=="M6_M5c" + obj->cellName=="M5_M4c" + obj->cellName=="M4_M3c" + obj->cellName=="M3_M2c" + obj->cellName=="M7_M6min" + obj->cellName=="M6_M5min" + obj->cellName=="M5_M4min" + obj->cellName=="M4_M3min" + obj->cellName=="M3_M2min") + (car obj->instTerms)->net==net ) + ) + + ; figure out if paths or contacts are flipY or flipX + (foreach path paths (MarkPath CV path)) + (foreach cont contacts (MarkContact CV cont)) + + ; draw paths + (foreach path paths + layers = (PickBundledLayers path) + points = (GetPathPoints path) + (cond (layers!=nil + flipX = (GetProp path "FlipX" nil) + flipY = (GetProp path "FlipY" nil) + (DrawGuidePath layers pattern prefix points flipX flipY) + ) + ) + ) + + ; draw contacts + (foreach cont contacts (DrawGuideContact cont pattern prefix)) + + ; delete source wires + (foreach path paths (dbDeleteObject path)) + (foreach contact contacts (dbDeleteObject contact)) + ) + t + ) + +; draw a guide path with bus properties +(defun DrawGuidePath (layer pattern prefix points flipX flipY + @key (CV (geGetEditCellView))) + (let (path) + obj = (dbCreatePath CV (list layer "bus") points 0.12 "squareFlush") + (dbReplaceProp obj "BusPattern" "string" pattern) + (dbReplaceProp obj "BusPrefix" "string" prefix) + (dbReplaceProp obj "BusPin" "boolean" nil) + (dbReplaceProp obj "BusFlipX" "boolean" flipX) + (dbReplaceProp obj "BusFlipY" "boolean" flipY) + (dbReplaceProp obj "BusStartVias" "boolean" nil) + (dbReplaceProp obj "BusEndVias" "boolean" nil) + (dbReplaceProp obj "BusArrayPitch" "float" 2.88) + (dbReplaceProp obj "BusDoubleVias" "boolean" (RecommendDoubleVias pattern)) + ) + t + ) + +; draw an optimized guide path for a contact +(defun DrawGuideContact (cont pattern chan) + (let (layers xy x y points flipX flipY metalW metalE metalN metalS dx dy) + layers = (PickBundledLayers cont) + (cond (layers!=nil + xy = cont->xy + x = (car xy) + y = (cadr xy) + metalW = (GetProp cont "MetalW" nil) + metalE = (GetProp cont "MetalE" nil) + metalN = (GetProp cont "MetalN" nil) + metalS = (GetProp cont "MetalS" nil) + flipX = (GetProp cont "FlipX" nil) + flipY = (GetProp cont "FlipY" nil) + (cond ((and metalW!=metalE metalN!=metalS) ; turn via + dx = (if metalW -1.14 1.14) + dy = (if metalS -1.14 1.14) + points = (list x+dx:y x:y x:y+dy) + (DrawGuidePath layers pattern chan points flipX flipY) + ) + (t ; stacked via or > 2 spoke + points = (list x-1.14:y x:y x:y-1.14) + (DrawGuidePath layers pattern chan points flipX flipY) + points = (list x+1.14:y x:y x:y+1.14) + (DrawGuidePath layers pattern chan points flipX flipY) + ) + ) + ) + ) + ) + t + ) + +; pick a suitable bus layer for a particular path or contact +(defun PickBundledLayers (obj) + (cond (obj->objType=="path" obj->layerName) + (obj->objType=="inst" + (cond ((setof lpp obj->master->lpps lpp->layerName=="VIA2")!=nil "M3") + ((setof lpp obj->master->lpps lpp->layerName=="VIA3")!=nil "M4") + ((setof lpp obj->master->lpps lpp->layerName=="VIA4")!=nil "M5") + ((setof lpp obj->master->lpps lpp->layerName=="VIA5")!=nil "M6") + ((setof lpp obj->master->lpps lpp->layerName=="VIA6")!=nil "M7") + (t nil) + ) + ) + ) + ) + +; copy flip properties from one object to another +(defun CopyFlipProperties (from to) + (let (flipX flipY) + flipX = (dbGetPropByName from "FlipX") + flipY = (dbGetPropByName from "FlipY") + (if flipX (dbReplaceProp to "FlipX" "boolean" flipX->value)) + (if flipY (dbReplaceProp to "FlipY" "boolean" flipY->value)) + ) + t + ) + +; mark if a path needs to be flipped +(defun MarkPath (CV path) + (let (overlaps flipX flipY pinType) + + ; find overlapping fat pins + overlaps = (FindMetalOverlaps CV path->bBox path->layerName) + + ; copy their FlipX/FlipY properties + (foreach overlap overlaps + (cond ((atom overlap) + (CopyFlipProperties overlap path) + ) + ) + ) + ) + t + ) + +; mark a contact if it needs to be flipped, and which way metal overlaps connect +(defun MarkContact (CV cont) + (let (overlaps x0 y0 x1 y1 ox0 oy0 ox1 oy1 mW mE mS mN) + (foreach lp cont->master->lpps + overlaps = (FindMetalOverlaps CV cont->bBox lp->layerName) + x0 = (car (car cont->bBox)) + y0 = (cadr (car cont->bBox)) + x1 = (car (cadr cont->bBox)) + y1 = (cadr (cadr cont->bBox)) + (foreach path overlaps + (cond ((atom path) + ox0 = (car (car path->bBox)) + oy0 = (cadr (car path->bBox)) + ox1 = (car (cadr path->bBox)) + oy1 = (cadr (cadr path->bBox)) + (CopyFlipProperties path cont) + mW = ox0x1+1.14 + mS = oy0y1+1.14 + (cond (mW + (dbReplaceProp cont "MetalW" "boolean" t) + (TrimPath path cont->xy -1.14:0) + )) + (cond (mE + (dbReplaceProp cont "MetalE" "boolean" t) + (TrimPath path cont->xy 1.14:0) + )) + (cond (mS + (dbReplaceProp cont "MetalS" "boolean" t) + (TrimPath path cont->xy 0:-1.14) + )) + (cond (mN + (dbReplaceProp cont "MetalN" "boolean" t) + (TrimPath path cont->xy 0:1.14) + )) + ) + ) + ) + ) + ) + t + ) + +; find overlaps on "drawing" "pin" or "net" purposes +(defun FindMetalOverlaps (CV bbox layerName) + (let (overlaps) + overlaps = (dbGetOverlaps CV bbox (list layerName "drawing")) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "net"))) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "pin"))) + ) + ) + +; find overlaps of contacts +(defun FindContactOverlaps (CV bbox layerName) + (let (overlaps contacts) + overlaps = (dbGetOverlaps CV bbox (list layerName "drawing") 1) + (foreach overlap overlaps + (when (and (atom overlap)==nil (car overlap)->objType=="inst") + contacts = (cons (car overlap) contacts) + ) + ) + contacts + ) + ) + +; detect direction of a metal layer +(defun IsLayerHorizontal (layerName) + (or layerName=="M3" layerName=="M5" layerName=="M7") + ) + +; simplify degenerate paths, assuming only first and last points are valid +(defun GetPathPoints (path) + (let (points) + points = (list (car path->points) (nth (length path->points)-1 path->points)) + (unless (or (car (car points))==(car (cadr points)) + (cadr (car points))==(cadr (cadr points))) + (printf "WARNING: Jogged bundled path on net %s\n" (if path->net path->net->name "")) + points = (list (car path->points) (cadr path->points)) + ) + points + ) + ) + +; trim the ends of a path if it connects to a contact +(defun TrimPath (path xy dxy) + (let (newpoints) + (cond (path->objType=="path" + newpoints = nil + (foreach point path->points + (cond ((and (car point)==(car xy) (cadr point)==(cadr xy)) + point = (car point)+(car dxy):(cadr point)+(cadr dxy) + ) + ) + newpoints = (append newpoints (list point)) + ) + path->points = newpoints + ) + ) + ) + t + ) + +; expand [i..j] in a list of BusPrefix names +(defun ExpandArrayRanges (names) + (let (expanded a b c left lo hi right prefix n) + expanded=nil + (rexCompile "^\\(.*\\)\\[\\([0-9]+\\)\\.\\.\\([0-9]+\\)\\]\\(.*\\)$") + (foreach name names + (cond ((rexExecute name) + left = (rexSubstitute "\\1") + lo = (atoi (rexSubstitute "\\2")) + hi = (atoi (rexSubstitute "\\3")) + right = (rexSubstitute "\\4") + (foreach prefix (ExpandArrayRanges (list left)) + (foreach suffix (ExpandArrayRanges (list right)) + (for i lo hi + n = (sprintf nil "%s[%d]%s" prefix i suffix) + expanded = (append expanded (list n)) + ) + ) + ) + ) + (t (cdr a)==nil expanded = (append expanded (list name))) + ) + ) + expanded + ) + ) + + + +(defun FindMBUFChannels (LegalMBUFs @key (CV (geGetEditCellView))) + (let (nets iterms filename file goodnets) + nets=CV->nets + (foreach net nets + iterms=net->instTerms + (when (length iterms)==2 + (when (IsInList (car iterms)->inst->master->cellName LegalMBUFs) && + (IsInList (cadr iterms)->inst->master->cellName LegalMBUFs) + goodnets=(cons net goodnets) + ) + ) + ) + goodnets + ) +) + +(defun ReportMBUFChannels (filename @key (filter_buswires nil)) + (let (file nets newname bufs) + file=(outfile filename) + + (fprintf file "e1of4s = (list \"e1of4\" ") + bufs=(list "lib.buffer.half.RBUF_1of4.1000" + "lib.buffer.half.MBUF_1of4.1000" + "lib.buffer.half.SBUF_1of4.1000" + ) + nets=(FindMBUFChannels bufs) + (foreach net nets + (when !filter_buswires || (filter_buswires && !(DoesBusWireExist net)) + newname=(reverse (parseString net->name ".")) + (when (car newname)=="e" + (fprintf file "\"%s\" " (buildString (reverse (cdr newname)) ".")) + ) + ) + ) + (fprintf file ")\n\n") + + (fprintf file "e1of3s = (list \"e1of3\" ") + bufs=(list "lib.buffer.half.RBUF_1of3.1000" + "lib.buffer.half.MBUF_1of3.1000" + "lib.buffer.half.SBUF_1of3.1000" + ) + nets=(FindMBUFChannels bufs) + (foreach net nets + (when !filter_buswires || (filter_buswires && !(DoesBusWireExist net)) + newname=(reverse (parseString net->name ".")) + (when (car newname)=="e" + (fprintf file "\"%s\" " (buildString (reverse (cdr newname)) ".")) + ) + ) + ) + (fprintf file ")\n\n") + + (fprintf file "e1of2s = (list \"e1of2\" ") + bufs=(list "lib.buffer.half.RBUF_1of2.1000" + "lib.buffer.half.MBUF_1of2.1000" + "lib.buffer.half.SBUF_1of2.1000" + ) + nets=(FindMBUFChannels bufs) + (foreach net nets + (when !filter_buswires || (filter_buswires && !(DoesBusWireExist net)) + newname=(reverse (parseString net->name ".")) + (when (car newname)=="e" + (fprintf file "\"%s\" " (buildString (reverse (cdr newname)) ".")) + ) + ) + ) + (fprintf file ")\n\n") + + + (close file) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/obs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/obs.il new file mode 100644 index 0000000000..96a153935a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/obs.il @@ -0,0 +1,142 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/obs.il#1 $ +; $DateTime: 2009/08/07 15:34:02 $ +; $Author: stevemc $ + + +(defun isBusObs (obj) + (when (car obj->lpp)==(car BusObs) && (cadr obj->lpp)==(cadr BusObs) t) +) + +(defun CreateObsProps (@key (shapes nil)) + (let (obs_m1 obs_m2 obs_m3 obs_m4 obs_m5 obs_m6 obs_m7 blk_pr) + shapes = (if shapes==nil (geGetSelSet) shapes) + (foreach obj shapes + (cond ((isBusObs obj) + blk_pr = (GetProp obj "ChopPRB" nil) + obs_m1 = (GetProp obj "M1" nil) + obs_m2 = (GetProp obj "M2" nil) + obs_m3 = (GetProp obj "M3" nil) + obs_m4 = (GetProp obj "M4" nil) + obs_m5 = (GetProp obj "M5" nil) + obs_m6 = (GetProp obj "M6" nil) + obs_m7 = (GetProp obj "M7" nil) + + ; delete properties + (dbDeletePropByName obj "ChopPRB") + (dbDeletePropByName obj "M1") + (dbDeletePropByName obj "M2") + (dbDeletePropByName obj "M3") + (dbDeletePropByName obj "M4") + (dbDeletePropByName obj "M5") + (dbDeletePropByName obj "M6") + (dbDeletePropByName obj "M7") + + ; set new properties + (dbReplaceProp obj "ChopPRB" "boolean" blk_pr) + (dbReplaceProp obj "M1" "boolean" obs_m1) + (dbReplaceProp obj "M2" "boolean" obs_m2) + (dbReplaceProp obj "M3" "boolean" obs_m3) + (dbReplaceProp obj "M4" "boolean" obs_m4) + (dbReplaceProp obj "M5" "boolean" obs_m5) + (dbReplaceProp obj "M6" "boolean" obs_m6) + (dbReplaceProp obj "M7" "boolean" obs_m7) + )) + ) + ) + t + ) + + +(defun DrawObsLayers (view obj @key (CV (geGetEditCellView))) + (let (points obs_m1 obs_m2 obs_m3 obs_m4 obs_m5 obs_m6 obs_m7 blk_pr) + ; get props + blk_pr = (GetProp obj "ChopPRB" nil) + obs_m1 = (GetProp obj "M1" nil) + obs_m2 = (GetProp obj "M2" nil) + obs_m3 = (GetProp obj "M3" nil) + obs_m4 = (GetProp obj "M4" nil) + obs_m5 = (GetProp obj "M5" nil) + obs_m6 = (GetProp obj "M6" nil) + obs_m7 = (GetProp obj "M7" nil) + ; get points + (when obj->objType=="rect" + points = obj->bBox + (when blk_pr (SetBusProp (dbCreateRect CV (list "prBoundary" "block") points)) ) + (when obs_m1 (SetBusProp (dbCreateRect CV Metal1byLPP points)) ) + (when obs_m2 (SetBusProp (dbCreateRect CV Metal2byLPP points)) ) + (when obs_m3 (SetBusProp (dbCreateRect CV Metal3byLPP points)) ) + (when obs_m4 (SetBusProp (dbCreateRect CV Metal4byLPP points)) ) + (when obs_m5 (SetBusProp (dbCreateRect CV Metal5byLPP points)) ) + (when obs_m6 (SetBusProp (dbCreateRect CV Metal6byLPP points)) ) + (when obs_m7 (SetBusProp (dbCreateRect CV Metal7byLPP points)) ) + ) + (when obj->objType=="polygon" + points = obj->points + (when blk_pr (SetBusProp (dbCreatePolygon CV (list "prBoundary" "block") points)) ) + (when obs_m1 (SetBusProp (dbCreatePolygon CV Metal1byLPP points)) ) + (when obs_m2 (SetBusProp (dbCreatePolygon CV Metal2byLPP points)) ) + (when obs_m3 (SetBusProp (dbCreatePolygon CV Metal3byLPP points)) ) + (when obs_m4 (SetBusProp (dbCreatePolygon CV Metal4byLPP points)) ) + (when obs_m5 (SetBusProp (dbCreatePolygon CV Metal5byLPP points)) ) + (when obs_m6 (SetBusProp (dbCreatePolygon CV Metal6byLPP points)) ) + (when obs_m7 (SetBusProp (dbCreatePolygon CV Metal7byLPP points)) ) + ) + ) +) + +; draw obstructions (NOTE: upto is obsolete) +(defun DrawObstructions (@key (upto 128) (guideInstName nil) (guideInst nil) + (CV (geGetEditCellView))) + (let (view obstype top pitch pattern flip track + busKeepout busPatterns busUseDefaultPatterns) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName) + view = guideInst->master + (when !view view = CV) + + ; draw OBS shapes + (foreach shape view->shapes + (when (isBusObs shape) (DrawObsLayers view shape) ) + ) + + ; draw bus paths with BusPattern "obstruction" + busKeepout = t + busUseDefaultPatterns = nil + busPatterns = (list (list "obstruction" node_TW)) + (DrawChannels nil nil nil nil ?guideInst guideInst) + (DrawChannelArrays nil nil nil nil nil nil ?guideInst guideInst) + + ; draw obstructM* + (for i 2 7 + obstype=(sprintf nil "obstructM%d" i) + (foreach shape view->shapes + pattern=(GetProp shape "BusPattern" nil) + (when shape->objType=="path" && pattern==obstype + pitch=(GetProp shape "BusArrayPitch" nil) + (if (mod i 2)==0 then + flip=(GetProp shape "BusFlipX" nil) + track=(caar shape->points)-TrackPitch/2 + (if !flip then + top=(caadr CV->bBox)-track + else + top=track-(caar CV->bBox) + ) + else + flip=(GetProp shape "BusFlipY" nil) + track=(cadar shape->points)-TrackPitch/2 + (if !flip then + top=(cadadr CV->bBox)-track + else + top=track-(cadar CV->bBox) + ) + ) + ) + ) + (when top && pitch + (DrawChannelArrays nil node_TW "" 0:(floor top/pitch) nil obstype ) + ) + ) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/patterns.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/patterns.il new file mode 100644 index 0000000000..0ca8ba1184 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/patterns.il @@ -0,0 +1,135 @@ +; Map from BusPattern string name to pattern structure. All native +; patterns of the PDK should be included here. Wide and sparse array +; patterns are parsed separately and can apply to all of these base +; patterns. Try to put common patterns near the top for performance +; reasons. Also supports user-defined busPatterns, a list of lists. +; The inner list contains the name and the pattern. This busPatterns +; should be set in wires.il +(defun MapBusPattern (name @key (defaults busUseDefaultPatterns) (patterns busPatterns)) + (let (pattern) + (when defaults pattern = (MapBusPatternPDK name)) + (unless pattern pattern = (cadr (car (setof p patterns name==(car p))))) + pattern + ) + ) + +; Should a pattern use double vias? +(defun RecommendDoubleVias (name) + (cond (name=="e1of1" t) + (name=="e1of2" t) + (name=="e1of3" t) + (name=="e1of4" t) + (name=="1of1" t) + (name=="1of2" t) + (name=="1of3" t) + (name=="1of4" t) + (name=="e1of1d" t) + (name=="e1of2d" t) + (name=="e1of3d" t) + (name=="e1of4d" t) + (name=="ChanDft2" t) + (t nil) + ) + ) + +; draw bus wires using guide paths (NOTE: upto is obsolete) +(defun DrawTracks (@key (upto 64) (guideInst nil) (guideInstName nil)) + (DrawChannels nil nil nil nil + ?guideInst guideInst ?guideInstName guideInstName) + (DrawChannelArrays nil nil nil nil nil nil + ?guideInst guideInst ?guideInstName guideInstName) + t + ) + +; obsolete +(defun DrawExtraTracks (@key (upto 64) (guideInstName nil) (guideInst nil)) + (printf "WARNING: DrawExtraTracks is obsolete -- DrawTracks is sufficient.\n") + nil + ) + +; obsolete +(defun DrawPartialArrays (@key (guideInstName nil)) + (printf "WARNING: DrawPartialArrays is obsolete -- DrawTracks is sufficient.\n") + nil + ) + +; draw double_default_e1of2/double_default_e1of4 arrays +(defun DrawDefaultTracks (@key (upto 64) (guideInstName nil) (guideInst nil) (pack_e1of2 nil)) + (let (chan str) + (for hi 1 upto + chan=(CreateDoubleDefaulte1of4 hi) + str=(sprintf nil "double_default_e1of4[%d]" hi) + (DrawChannels nil chan nil str ?guideInst guideInst ?guideInstName guideInstName) + ) + (for hi 1 upto + chan=(CreateDoubleDefaulte1of3 hi) + str=(sprintf nil "double_default_e1of3[%d]" hi) + (DrawChannels nil chan nil str ?guideInst guideInst ?guideInstName guideInstName) + ) + (for hi 1 upto + chan=(CreateDoubleDefaulte1of2 hi ?pack pack_e1of2) + str=(sprintf nil "double_default_e1of2[%d]" hi) + (DrawChannels nil chan nil str ?guideInst guideInst ?guideInstName guideInstName) + ) + ) + t + ) + +(defun CreateDoubleDefaulte1of4 (array) + (let (channel defchan str) + channel=(list "") + (for i 0 array-1 + str=(sprintf nil "[%d]" i) + (if (mod i 2)==0 then + channel=(BuildDefChanList channel str 1 + inlv_e1of4_A i/2*TrackPitch nil ?use_dots nil) + else + channel=(BuildDefChanList channel str 1 + inlv_e1of4_B i/2*TrackPitch nil ?use_dots nil) + ) + ) + defchan=(DefChan (cdr channel)) + ) + ) + +(defun CreateDoubleDefaulte1of3 (array) + (let (channel defchan str) + channel=(list "") + (for i 0 array-1 + str=(sprintf nil "[%d]" i) + (if (mod i 2)==0 then + channel=(BuildDefChanList channel str 1 + inlv_e1of3_A i/2*TrackPitch nil ?use_dots nil) + else + channel=(BuildDefChanList channel str 1 + inlv_e1of3_B i/2*TrackPitch nil ?use_dots nil) + ) + ) + defchan=(DefChan (cdr channel)) + ) + ) + +(defun CreateDoubleDefaulte1of2 (array @key (pack nil)) + (let (channel defchan str typeA typeB) + (if pack then + typeA=inlv_e1of2_A + typeB=inlv_e1of2_B + else + typeA=inlv_e1of2_A2 + typeB=inlv_e1of2_B2 + ) + + channel=(list "") + (for i 0 array-1 + str=(sprintf nil "[%d]" i) + (if (mod i 2)==0 then + channel=(BuildDefChanList channel str 1 + typeA i/2*TrackPitch nil ?use_dots nil) + else + channel=(BuildDefChanList channel str 1 + typeB i/2*TrackPitch nil ?use_dots nil) + ) + ) + defchan=(DefChan (cdr channel)) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/shield.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/shield.il new file mode 100644 index 0000000000..096e086bdb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/shield.il @@ -0,0 +1,486 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/shield.il#1 $ +; $DateTime: 2012/07/27 17:24:08 $ +; $Author: pankala $ + +(defun DrawBusShield ( points layers prefix @key (CellVue (UIGetCellView)) (shieldM2 t)) + let( ( Idx NPoints HLayer VLayer + CurrPoint NextPoint CurrLayer Segments + ShieldDir ShieldPoint ShieldPointX ShieldPointY ShieldLength ShieldInst ShieldInstName + CurrXQuad CurrYQuad (types (ClassifyPoints points)) + ) + + HLayer = car(nth(0 layers)) + VLayer = car(nth(1 layers)) + NPoints = length(points) + + for( Idx 0 NPoints-2 + + CurrPoint = nth(Idx points) + + CurrXQuad = car(ShieldFindQuad(CurrPoint)) + CurrYQuad = cadr(ShieldFindQuad(CurrPoint)) + + when( Idx == 0 + NextPoint = nth(Idx+1 points) + + if( almostEqual(car(CurrPoint) car(NextPoint)) + then + CurrLayer = VLayer + if( NPoints > 2 + then + Segments = round((abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( cadr(NextPoint) > cadr(CurrPoint) + then + ShieldDir = "V_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = round((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + else + ShieldDir = "V_MX" + if( CurrYQuad > 0 + then + ShieldPointY = round((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + else + CurrLayer = HLayer + if( NPoints > 2 + then + Segments = round((abs(car(NextPoint)*1000 - car(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(car(NextPoint)*1000 - car(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( car(NextPoint) > car(CurrPoint) + then + ShieldDir = "H_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = round((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + else + ShieldDir = "H_MY" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = round((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + ) + ) + ShieldPoint = list(ShieldPointX ShieldPointY) + when( !OverlapShield(CellVue ShieldPoint CurrLayer ShieldDir Segments) + DrawShieldShapes(CellVue Segments ShieldPoint ShieldDir CurrLayer ?shieldM2 shieldM2) + ) + ) + + when( Idx > 0 && Idx < NPoints-2 + NextPoint = nth(Idx+1 points) + + if( almostEqual(car(CurrPoint) car(NextPoint)) + then + CurrLayer = VLayer + Segments = round(abs(cadr(NextPoint) - cadr(CurrPoint))/TrackPitch) - 1 + if( cadr(NextPoint) > cadr(CurrPoint) + then + ShieldDir = "V_R0" + if( CurrYQuad > 0 + then + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + else + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + else + ShieldDir = "V_MX" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + else + CurrLayer = HLayer + Segments = round(abs(car(NextPoint) - car(CurrPoint))/TrackPitch) - 1 + if( car(NextPoint) > car(CurrPoint) + then + ShieldDir = "H_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + else + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + else + ShieldDir = "H_MY" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + ) + ShieldPoint = list(ShieldPointX ShieldPointY) + when( !OverlapShield(CellVue ShieldPoint CurrLayer ShieldDir Segments) + DrawShieldShapes(CellVue Segments ShieldPoint ShieldDir CurrLayer ?shieldM2 shieldM2) + ) + ) + + when( Idx == NPoints-2 && Idx != 0 + NextPoint = nth(Idx+1 points) + + if( almostEqual(car(CurrPoint) car(NextPoint)) + then + CurrLayer = VLayer + if( NPoints > 2 + then + Segments = round((abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( cadr(NextPoint) > cadr(CurrPoint) + then + ShieldDir = "V_R0" + if( CurrYQuad > 0 + then + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1)*TrackPitch + else + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + else + ShieldDir = "V_MX" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) - 1)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + else + CurrLayer = HLayer + if( NPoints > 2 + then + Segments = round((abs(car(NextPoint)*1000 - car(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(car(NextPoint)*1000 - car(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( car(NextPoint) > car(CurrPoint) + then + ShieldDir = "H_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1)*TrackPitch + else + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + else + ShieldDir = "H_MY" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) - 1)*TrackPitch + ) + ) + ) + ShieldPoint = list(ShieldPointX ShieldPointY) + when( !OverlapShield(CellVue ShieldPoint CurrLayer ShieldDir Segments) + DrawShieldShapes(CellVue Segments ShieldPoint ShieldDir CurrLayer ?shieldM2 shieldM2) + ) + ) + + + ) + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun OverlapShield (CellVue ShieldPoint CurrLayer ShieldDir Segments) + let( ( ShieldbBoxFirst ShieldbBoxLast ShieldPresent ShieldShape SegInc ) + if( cadr(parseString(ShieldDir "_")) == "R0" + then + SegInc = 1 + else + SegInc = -1 + ) + when( car(parseString(ShieldDir "_")) == "H" + ShieldbBoxFirst = list(car(ShieldPoint)+(0.78*SegInc):cadr(ShieldPoint)+0.045 car(ShieldPoint)+(0.80*SegInc):cadr(ShieldPoint)+0.095) + ShieldbBoxLast = list(car(ShieldPoint)+(0.78*(Segments-1)*SegInc):cadr(ShieldPoint)+0.045 car(ShieldPoint)+(0.80*(Segments-1)*SegInc):cadr(ShieldPoint)+0.095) + ) + when( car(parseString(ShieldDir "_")) == "V" + ShieldbBoxFirst = list(car(ShieldPoint)+0.045:cadr(ShieldPoint)+(0.78*SegInc) car(ShieldPoint)+0.095:cadr(ShieldPoint)+(0.80*SegInc)) + ShieldbBoxLast = list(car(ShieldPoint)+0.045:cadr(ShieldPoint)+(0.78*(Segments-1)*SegInc) car(ShieldPoint)+0.095:cadr(ShieldPoint)+(0.80*(Segments-1)*SegInc)) + ) + if( setof(ShieldShape dbGetOverlaps(CellVue ShieldbBoxFirst) ShieldShape~>BusScriptObject&&car(ShieldShape~>lpp)==CurrLayer) && setof(ShieldShape dbGetOverlaps(CellVue ShieldbBoxLast) ShieldShape~>BusScriptObject&&car(ShieldShape~>lpp)==CurrLayer) + then + ShieldPresent = t + else + ShieldPresent = nil + ) + ShieldPresent + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun DrawShieldShapes (CellVue Segments ShieldPoint ShieldDir CurrLayer @key (shieldM2 t)) + let( ( Idx ShieldbBox1 ShieldbBox2 ShieldObj1 ShieldObj2 SegInc ShieldbBox1M2 ShieldbBox2M2 ShieldViolationM2 ShieldViolation1M2 ShieldViolation2M2 + RBlockObj1 RBlockObj2 VBlockObj1 VBlockObj2 M2Block1 M2Block2 viaid ShieldVia1 ShieldVia2 + ) + + if( cadr(parseString(ShieldDir "_")) == "R0" + then + SegInc = 1 + else + SegInc = -1 + ) + + for( Idx 0 Segments-1 + when( car(parseString(ShieldDir "_")) == "H" + ShieldbBox1 = list(car(ShieldPoint)+TrackPitch*Idx*SegInc:cadr(ShieldPoint)+0.045 car(ShieldPoint)+(TrackPitch*Idx+1.355)*SegInc:cadr(ShieldPoint)+0.095) + ShieldbBox2 = list(car(ShieldPoint)+TrackPitch*Idx*SegInc:cadr(ShieldPoint)+1.465 car(ShieldPoint)+(TrackPitch*Idx+1.355)*SegInc:cadr(ShieldPoint)+1.515) + when( SegInc == -1 + ShieldbBox1 = list(caar(ShieldbBox1)-0.205:cadar(ShieldbBox1) caadr(ShieldbBox1)-0.205:cadadr(ShieldbBox1)) + ShieldbBox2 = list(caar(ShieldbBox2)-0.205:cadar(ShieldbBox2) caadr(ShieldbBox2)-0.205:cadadr(ShieldbBox2)) + ) + ShieldObj1 = dbCreateRect(CellVue CurrLayer ShieldbBox1) + ShieldObj2 = dbCreateRect(CellVue CurrLayer ShieldbBox2) + RBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox1)) + RBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox2)) + SetBusProp(ShieldObj1) + SetBusProp(ShieldObj2) + SetBusProp(RBlockObj1) + SetBusProp(RBlockObj2) + ) + + if( SegInc == 1 + then + ShieldbBox1M2 = list(car(ShieldPoint)-0.105:cadr(ShieldPoint)+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+0.105:cadr(ShieldPoint)+(TrackPitch*Idx+1.365)*SegInc) + ShieldbBox2M2 = list(car(ShieldPoint)+1.455:cadr(ShieldPoint)+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+1.665:cadr(ShieldPoint)+(TrackPitch*Idx+1.365)*SegInc) + else + ShieldbBox1M2 = list(car(ShieldPoint)-0.105:cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+0.105:cadr(ShieldPoint)-1.56+(TrackPitch*Idx+1.365)*SegInc) + ShieldbBox2M2 = list(car(ShieldPoint)+1.455:cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+1.665:cadr(ShieldPoint)-1.56+(TrackPitch*Idx+1.365)*SegInc) + ) +; when( CurrLayer == "M2" +; ShieldObj1 = dbCreateRect(CellVue "PO" ShieldbBox1M2) +; ShieldObj2 = dbCreateRect(CellVue "PO" ShieldbBox2M2) +; SetBusProp(ShieldObj1) +; SetBusProp(ShieldObj2) +; +; ) + ShieldViolationM2 = nil + if( CurrLayer == "M2" && dbGetOverlaps(CellVue ShieldbBox1M2 "M2" 32) == nil + then + ShieldViolationM2 = nil + ShieldViolation1M2 = nil + else + ShieldViolationM2 = t + ShieldViolation1M2 = t + ) + + if( CurrLayer == "M2" && dbGetOverlaps(CellVue ShieldbBox2M2 "M2" 32) == nil + then + ShieldViolationM2 = nil + ShieldViolation2M2 = nil + else + ShieldViolationM2 = t + ShieldViolation1M2 = t + ) + + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolationM2) + ShieldbBox1 = list(car(ShieldPoint)+0.045:cadr(ShieldPoint)+TrackPitch*Idx*SegInc car(ShieldPoint)+0.095:cadr(ShieldPoint)+(TrackPitch*Idx+1.365)*SegInc) + ShieldbBox2 = list(car(ShieldPoint)+1.465:cadr(ShieldPoint)+TrackPitch*Idx*SegInc car(ShieldPoint)+1.515:cadr(ShieldPoint)+(TrackPitch*Idx+1.365)*SegInc) + when( SegInc == -1 + ShieldbBox1 = list(caar(ShieldbBox1):cadar(ShieldbBox1)-0.195 caadr(ShieldbBox1):cadadr(ShieldbBox1)-0.195) + ShieldbBox2 = list(caar(ShieldbBox2):cadar(ShieldbBox2)-0.195 caadr(ShieldbBox2):cadadr(ShieldbBox2)-0.195) + ) + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation1M2) + ShieldObj1 = dbCreateRect(CellVue CurrLayer ShieldbBox1) + SetBusProp(ShieldObj1) + RBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox1)) + SetBusProp(RBlockObj1) + ) + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation2M2) + ShieldObj2 = dbCreateRect(CellVue CurrLayer ShieldbBox2) + SetBusProp(ShieldObj2) + RBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox2)) + SetBusProp(RBlockObj2) + ) + when( CurrLayer == "M2" && shieldM2 + ShieldbBox1 = list(car(ShieldPoint)-0.105:cadr(ShieldPoint)+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+0.105:cadr(ShieldPoint)+(TrackPitch*Idx+0.105)*SegInc) + ShieldbBox2 = list(car(ShieldPoint)+1.455:cadr(ShieldPoint)+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+1.665:cadr(ShieldPoint)+(TrackPitch*Idx+0.105)*SegInc) + when( SegInc == -1 + ShieldbBox1 = list(car(ShieldPoint)-0.105:cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+0.105:cadr(ShieldPoint)-1.56+(TrackPitch*Idx+0.105)*SegInc) + ShieldbBox2 = list(car(ShieldPoint)+1.455:cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+1.665:cadr(ShieldPoint)-1.56+(TrackPitch*Idx+0.105)*SegInc) + ) + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation1M2) + M2Block1 = dbCreateRect(CellVue CurrLayer ShieldbBox1) + RBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox1)) + SetBusProp(RBlockObj1) + SetBusProp(M2Block1) + ) + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation2M2) + M2Block2 = dbCreateRect(CellVue CurrLayer ShieldbBox2) + RBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox2)) + SetBusProp(RBlockObj2) + SetBusProp(M2Block2) + ) + viaid = techFindViaDefByName(techGetTechFile(CellVue) "M3_M2_R_H") + if( SegInc == 1 + then + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation1M2) + ShieldVia1 = dbCreateVia(CellVue viaid list(car(ShieldPoint) cadr(ShieldPoint)+(TrackPitch*Idx+0.065)*SegInc) "R0") + ) + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation2M2) + ShieldVia2 = dbCreateVia(CellVue viaid list(car(ShieldPoint)+TrackPitch cadr(ShieldPoint)+(TrackPitch*Idx+0.065)*SegInc) "R0") + ) + else + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation1M2) + ShieldVia1 = dbCreateVia(CellVue viaid list(car(ShieldPoint) cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.065)*SegInc) "R0") + ) + when( ( car(parseString(ShieldDir "_")) == "V" && CurrLayer != "M2" ) || (CurrLayer == "M2" && !ShieldViolation2M2) + ShieldVia2 = dbCreateVia(CellVue viaid list(car(ShieldPoint)+TrackPitch cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.065)*SegInc) "R0") + ) + ) + SetBusProp(ShieldVia1) + SetBusProp(ShieldVia2) + ) + + ) ;when + + + + ) ;for + + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun BBoxToPoints (bBox) + list(car(bBox) caadr(bBox):cadar(bBox) cadr(bBox) caar(bBox):cadadr(bBox)) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun ShieldSetProps (ShieldInst CurrLayer ShieldLength) + let( (ShieldLayer layer) + + ShieldInst~>SegLength = ShieldLength + + for( layer 2 7 + sprintf(ShieldLayer "M%d" layer) + if( ShieldLayer == CurrLayer + then + dbReplaceProp(ShieldInst ShieldLayer "boolean" "TRUE") + println(ShieldLayer) + else + dbReplaceProp(ShieldInst ShieldLayer "boolean" "FALSE") + ) + ) + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun ShieldFindQuad (point) + let( (XQuad YQuad) + + if( car(CurrPoint) >= 0 + then + XQuad = 1 + else + XQuad = -1 + ) + + if( cadr(CurrPoint) >= 0 + then + YQuad = 1 + else + YQuad = -1 + ) + + list(XQuad YQuad) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/util.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/util.il new file mode 100644 index 0000000000..9256b763e7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/util.il @@ -0,0 +1,679 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/util.il#1 $ +; $DateTime: 2009/08/13 08:18:26 $ +; $Author: stevemc $ + + +; check if two coordinates are equal to rounding precision +(defun almostEqual (x0 x1) + (abs x1-x0)<0.001 + ) + +; make a net unless name is empty +(defun MakeNet (view name) + (cond (name!="" (dbMakeNet view name)) + (name=="" nil) + ) + ) + +; attach a label to a pin +(defun LabelPin (view fig @key (bBox nil)) + (let (x0 y0 x1 y1 x y rotation height) + (unless bBox bBox = fig->bBox) + x0 = (car (car bBox)) + y0 = (cadr (car bBox)) + x1 = (car (cadr bBox)) + y1 = (cadr (cadr bBox)) + x = (x0+x1)/2 + y = (y0+y1)/2 + x = MfgGrid * (round x/MfgGrid) + y = MfgGrid * (round y/MfgGrid) + (cond (x1-x0>y1-y0 rotation = "R0" height = y1-y0) + (t rotation = "R90" height = x1-x0) + ) + height = MfgGrid * (round height/MfgGrid/3) ; adjust height + label = (dbCreateLabel view fig->layerName x:y fig->net->name + "centerCenter" rotation "stick" height) ; draw the label + label->parent = fig ; label moves with figure + ) + t + ) + +; relabel all pins +(defun LabelPins (@key (CV (geGetEditCellView))) + (let (term pin) + (foreach term CV->terminals + (foreach pin term->pins + (when pin->fig && pin->fig->objType=="rect" (LabelPin CV pin->fig)) + ) + ) + ) + t + ) + +; transform xy coordinates using transform +(defun busTransformPoint (xy guideInst) + (cond (guideInst==nil xy) + (guideInst!=nil (geTransformUserPoint xy guideInst->transform)) + ) + ) + +; choose next available contact name -- faster than using nil name! +(defun NextContactName (view) + (let (name duplicate) + duplicate = t + (while duplicate + name = (sprintf nil "IC%d" busContactNum) + duplicate = (dbFindAnyInstByName view name) + busContactNum = (if duplicate busContactNum*2 busContactNum+1) + ) + name + ) + ) + +; get a property or default value +(defun GetProp (obj prop default) + p = (dbGetPropByName obj prop) + (cond ((and p!=nil p->valueType=="boolean") p->value=="TRUE") + (p p->value) + (t default) + ) + ) + +; select wires/contacts/subcells by net name +(defun SelectNet + (name + @key (CV (geGetEditCellView)) + (net nil) + (pins t) + (wires t) + (contacts t) + (subcells nil) + ) + (let (found) + found = 0 + (unless net net = (dbFindNetByName CV name)) + (when pins + (foreach pin net->pins + (geSelectObject pin->fig) + found = found+1 + ) + ) + (when wires + (foreach fig net->figs + (geSelectObject fig) + found = found+1 + ) + ) + (foreach term net->instTerms + (when (or (and contacts term->inst->libName==TechLibName) + (and subcells term->inst->libName!=TechLibName)) + (geSelectObject term->inst) + found = found+1 + ) + ) + found + ) + ) + +; select wires/contacts/subcells by net name with regular expression matching +(defun SelectNetRegExp + (regexp + @key (CV (geGetEditCellView)) + (pins t) + (wires t) + (contacts t) + (subcells nil)) + (let (found) + found = 0 + (rexCompile regexp) + (foreach net (setof net CV->nets (rexExecute net->name)) + found = found + + (SelectNet nil ?net net ?CV CV + ?pins pins ?wires wires ?contacts contacts ?subcells subcells) + ) + found + ) + ) + +; test for wiring shapes +(defun isWiringPath (obj) + (let ((iswire nil)) + (when (or obj->objType=="path" obj->objType=="polygon" obj->objType=="rect") && ((isMetalDrawing obj->layerName obj->purpose) || (isMetalPin obj->layerName obj->purpose)) + iswire=t + ) + (when obj->objType=="pin" + (when (isMetalDrawing obj->fig->layerName obj->fig->purpose) || (isMetalPin obj->fig->layerName obj->fig->purpose) + iswire=t + ) + ) + iswire + ) +) + +; test for wiring contacts +(defun isWiringContact (obj) + (or (and obj->objType=="inst" obj->libName==TechLibName) + obj->objType=="stdVia") + ) + +; delete contacts only +(defun DeleteContacts (@key (CV (geGetEditCellView))) + busContactNum = 0 + (let () + (foreach obj CV->instances + (cond ((isWiringContact obj) (dbDeleteObject obj)) + ) + ) + (foreach obj CV->vias + (cond ((isWiringContact obj) (dbDeleteObject obj)) + ) + ) + ) + t + ) + +; delete metal paths and contacts +(defun DeleteWires (@key (CV (geGetEditCellView))) + (let () + (foreach obj CV->shapes + (cond ((isWiringPath obj) (dbDeleteObject obj)) + ) + ) + ) + (DeleteContacts) + t + ) + +; delete metal blockages +(defun DeleteBlockages (@key (CV (geGetEditCellView))) + (let () + (foreach obj CV~>blockages + (dbDeleteObject obj) + ) + ) + t + ) + +; delete both +(defun DeleteWiresAndKeepout () + (DeleteWires) + (DeleteKeepout) + (DeleteBlockages) + t + ) + +; delete shapes and vias that have BusScriptObject property +(defun DeleteBusWires (@key (CV (geGetEditCellView))) + (let (shapes vias blockages) + shapes = (setof obj CV->shapes (IsBusObject obj)) + vias = (GetBusScriptVias CV) + blockages = (setof obj CV->blockages (IsBusObject obj)) + (foreach shape shapes (dbDeleteObject shape)) + (foreach via vias (dbDeleteObject via)) + (foreach blockage blockages (dbDeleteObject blockage)) + ) + t + ) + +;check for scripted wire +(defun DoesBusWireExist (net @key (CV (geGetEditCellView))) + (let (exist) + exist=nil + (foreach shape CV->shapes + (when shape->net==net && (IsBusObject shape) + exist=t + ) + ) + exist + ) +) + +; utility to turn drawing shapes into keepout +(defun ConvertWiresToKeepout (@key (CV (geGetEditCellView))) + (let () + (foreach obj CV->shapes + (cond ((isMetalDrawing obj->layerName obj->purpose) + obj->purpose="boundary" + ) + ) + ) + ) + t + ) + +; delete the warning markers +(defun DeleteMarkers (@key (CV (geGetEditCellView))) + (geDeleteAllMarker CV) + ) + +; delete unused nets +(defun DeleteUnusedNets (@key (CV (geGetEditCellView))) + (let (cnt) + cnt = 0 + (foreach net CV->nets + (when (and net->instTermCount==0 net->pins==nil net->figs==nil) + (dbDeleteObject net) + cnt=cnt+1 + ) + ) + cnt + ) + ) + +; check if the cell has bus guides +(defun HasGuides (view) + (let ((guides nil)) + (foreach inst view->instances + (when (IsGuideInst inst) + guides = t + ) + ) + (foreach shape view->shapes + (when (cadr shape->lpp)=="bus" + guides = t + ) + ) + guides + ) +) + +; delete bus guides +(defun DeleteGuides (view) + (foreach inst view->instances + (when (IsGuideInst inst) + (dbDeleteObject inst) + ) + ) + (foreach shape view->shapes + (when (cadr shape->lpp)=="bus" + (dbDeleteObject shape) + ) + ) +) + +(defun DeleteGuideShapes (view) + (foreach shape view->shapes + (when (cadr shape->lpp)=="bus" + (dbDeleteObject shape) + ) + ) +) + +; copy bus guides +(defun CopyGuides (srcview dstview) + (foreach inst srcview->instances + (when (IsGuideInst inst) + (dbCreateInstByMasterName dstview inst->libName + inst->cellName inst->viewName inst->name (list 0 0) "R0") + ) + ) + (foreach shape srcview->shapes + (when (cadr shape->lpp)=="bus" + (dbCopyFig shape dstview) + ) + ) + (dbSave dstview) +) + +(defun CopyGuideShapes (srcview dstview) + (foreach shape srcview->shapes + (when (cadr shape->lpp)=="bus" + (dbCopyFig shape dstview) + ) + ) + (dbSave dstview) +) + + +(defun RoundGuidesToGrid ( @key (paths nil) (grid TrackPitch/2) (CV (geGetEditCellView))) + (let (haspaths newpoints) + + (if !paths then + haspaths = nil + (foreach shape CV->shapes + (when shape->objType=="path" && (cadr shape->lpp)=="bus" + haspaths = t + paths = (cons shape paths) + ) + ) + else + haspaths = t + ) + + (if haspaths then + (foreach path paths + newpoints = (PathRoundPointsToGrid path->points ?grid grid) + path->points = newpoints + ) + else + (hiDisplayAppDBox + ?name 'RoundPathsDialogBox + ?dboxText "No bus guidepaths found." + ?dboxBanner "No Guides" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'Close + ) + ) + + ) +) + +(defun GetBusScriptVias (cv) +; (setof inst cv->instances (and inst->libName==TechLibName (IsBusObject inst))) + (setof inst cv->vias (IsBusObject inst)) + ) + +(defun AreViasDuplicate (via1 via2) + (and via1->libName==via2->libName + via1->cellName==via2->cellName + via1->xy==via2->xy + via1->orient==via2->orient) + ) + +(defun DeleteDuplicateBusScriptVias (@key (CV (geGetEditCellView))) + (let (busvias) + busvias = (GetBusScriptVias CV) + (foreach inst CV->instances + (when inst->libName==TechLibName + (foreach via busvias + (when (AreViasDuplicate via inst) && !(IsInList inst busvias) + (dbDeleteObject inst) + ) + ) + ) + ) + ) +) + + +(defun FindDuplicateBuswires (@key (check_points t) (CV (geGetEditCellView))) + (let (wirescell wirescv paths duplicates already_done points_match) + wirescell=(GetGuideInst nil busGuideInstName) + (if wirescell then + wirescv=(nrOpenCellViewWritable wirescell->libName wirescell->cellName wirescell->viewName ?mode "a") + else + wirescv=CV + ) + + (foreach shape wirescv->shapes + (when shape->objType=="path" && (cadr shape->lpp)=="bus" + paths=(cons shape paths) + ) + ) + (foreach path1 paths + already_done=(cons path1 already_done) + (foreach path2 paths + points_match=!check_points + (when check_points && path1->points==path2->points + points_match=t + ) + + (when !(IsInList path2 already_done) && + points_match && + path1->lpp==path2->lpp && + (GetProp path1 "BusPrefix" nil)==(GetProp path2 "BusPrefix" nil) && + (GetProp path1 "BusPattern" nil)==(GetProp path2 "BusPattern" nil) && + (GetProp path1 "BusPin" nil)==(GetProp path2 "BusPin" nil) + duplicates=(cons path2 duplicates) + ) + ) + ) + duplicates + ) +) + +; helper function to determine the length of all paths in a floorplan +(defun ReportPathLengths (@key (filename "alta_path_lengths.txt") + (pathProp (list "Channel" "myProp")) + (CV (geGetEditCellView))) + (let (shape fp channelName length points p0 p1 x0 y0 x1 y1 propName + shapeCount width refCoord refPoint oddList oddPoint) + + ; open the output file + fp = (outfile filename) + + shapeCount = 0 + (if fp != nil + then + ; look for all paths in the current view + (foreach shape CV->shapes + ; process only shapes with type "path" + shapeCount = shapeCount + 1 + (printf "%d: objType = %s - lpp = %s\n" shapeCount shape->objType (cadr shape->lpp)) + (when shape->objType=="path" + + ; look for any of the valid properties + channelName = nil + properties = pathProp + (while (and channelName == nil properties != nil) + propName = (car properties) + properties = (cdr properties) + channelName = (GetProp shape propName nil) + ) ; end (while ... ) + + (if channelName != nil + then + ; now determine the length + length = 0 + aligned = t + oddList = nil + points = shape->points + (for i 0 (length points)-2 + p0 = (nth i points) + p1 = (nth i+1 points) + x0 = (car p0) + y0 = (cadr p0) + x1 = (car p1) + y1 = (cadr p1) + length = length+(abs x1-x0)+(abs y1-y0) + width = shape->width + ; determine the direction + (if x1 == x0 + then + ; we're moving vertically + ; we'll determine the aligment + ; of the left edge of the path + refCoord = x0+width/2.0 + (if y1 > y0 then dir=1 else dir=-1) + refPoint = (list refCoord y0+dir*width/2.0) + else + ; we're moving vertically + ; we'll determine the aligment + ; of the top edge of the path + refCoord = y0+width/2.0 + (if x1 > x0 then dir=1 else dir=-1) + refPoint = (list x0+dir*width/2.0 refCoord) + ) + + ; is the reference coordinate aligned? + (when (IsAligned refCoord (2*TrackPitch)) != t + (if aligned == t + then + oddList = (list (list i refPoint)) + aligned = nil + else + oddList = (append oddList (list (list i refPoint))) + ) + ) + ) ; end for + + ; output the result to file + (fprintf fp "Path=%-54s Length=%8.2f Layer=\"%2s,%8s\" - " + channelName + length + (car shape->lpp) + (cadr shape->lpp) + ) + (if aligned == t + then (fprintf fp "Path ALIGNED\n") + else + (fprintf fp "Path NOT ALIGNED: ") + (foreach oddPoint oddList + (fprintf fp " (%4.2f:%4.2f)" + (nth 0 (cadr oddPoint)) + (nth 1 (cadr oddPoint)) + ) ; end (fprintf ... ) + ) ; end (foreach ... ) + (fprintf fp "\n") + ) ; end (if aligned ... ) + else + (printf "Property not found!\n") + (printf "Layer = %s, %s\n" (car shape->lpp) (cadr shape->lpp)) + (geCreateMarker shape "error" "bus" "length" "") + ) ; end (if channelName ... ) + + ) ; end when + + ) ; end foreach + + ; close the output file + (close fp) + else + (printf "Couldn't open file %s" filename) + ) ; end if + + ) ; end let +) + +; select bus paths with optional filters +(defun SelectBusPaths + (@key (CV (geGetEditCellView)) + (prefix "") ; require BusPrefix to start with prefix + (pattern "") ; require BusPattern to start with pattern + (doPins t) ; allow BusPin=t + (doWires t) ; allow BusPin=nil + (rexPrefix nil) ; optional regular expression for prefix + (rexPattern nil)) ; optional regular expression for pattern + (let (pre pat pin (n 0)) + (foreach path CV->shapes + (when (and path->objType=="path" (cadr path->lpp)=="bus") + pre = (GetProp path "BusPrefix" "") + pat = (GetProp path "BusPattern" "") + pin = (GetProp path "BusPin" nil) + (when (and (if pin doPins doWires) + (strncmp prefix pre (strlen prefix))==0 + (strncmp pattern pat (strlen pattern))==0 + (or !rexPrefix (rexMatchp rexPrefix pre)) + (or !rexPattern (rexMatchp rexPattern pat))) + (geSelectObject path) + n = n+1 + ) + ) + ) + n + ) + ) + +; select inplace pins only +(defun SelectInplacePins + (@key (CV (geGetEditCellView)) + (minLength 0) ; only select pins longer than this + ) + (let (n) + n = 0 + (foreach shape CV->shapes + (when (and (GetProp shape "PinType" nil)=="InPlace" + (or (BBoxGetWidth shape->bBox)>minLength + (BBoxGetHeight shape->bBox)>minLength)) + (geSelectObject shape) + n = n+1 + ) + ) + n + ) + ) + +; replace prefix of BusPrefix of bus paths +(defun ReplaceBusPrefix + (from ; original prefix + to ; replacement prefix + @key (CV (geGetEditCellView))) ; optional cell view + (let (paths prefix (n 0)) + paths = (geGetSelSet) + (unless paths paths=CV->shapes) + paths = (setof shape paths shape->objType=="path") (foreach path paths + prefix = (GetProp path "BusPrefix" nil) + (when (strncmp prefix from (strlen from))==0 + prefix = (substring prefix (strlen from)+1) + prefix = (if prefix (strcat to prefix) to) + (dbReplaceProp path "BusPrefix" "string" prefix) + n=n+1 + ) + ) + n + ) + ) + +; Trim pins that overlap with bbox to stay inside bbox, converting the +; original shape into wires with connectivity. Use to repair layout +; affected by BUG 18821. +(defun TrimPins (bbox @key (CV (geGetEditCellView))) + (let (n shapes bbox_in rect) + n=0 + shapes = (geGetSelSet) + (unless shapes shapes=CV->shapes) + (foreach shape shapes + (when (and shape->pin shape->objType=="rect") + bbox_in = (BBoxAnd bbox shape->bBox) + (when bbox_in + rect = (dbCreateRect CV shape->lpp shape->bBox) + rect->net = shape->net + shape->bBox = bbox_in + (foreach label shape->children + (when label->objType=="label" + label->xy = (BBoxGetCenter bbox_in) + ) + ) + n=n+1 + ) + ) + ) + n + ) + ) + +; Offset a single point by specified amounts for each bBox it overlaps. +(defun StretchPointWithinBoxes + (boxstretch xy @key (CV (geGetEditCellView))) + (let (bbox dxy nxy) + nxy = xy + (foreach bs boxstretch + bbox = (car bs) + dxy = (cadr bs) + (when (BBoxAnd (list xy xy) bbox) + nxy = (car nxy)+(car dxy):(cadr nxy)+(cadr dxy) + ) + ) + nxy + ) + ) + +; Applies offset to all points within each bbox. Bbox overlaps are +; tested before offsets are applied. Takes a list of bbox, offset +; pairs (list (list bbox offet) ...). +(defun StretchShapesWithinBoxes + (boxstretch @key (CV (geGetEditCellView))) + (let (points) + (foreach inst CV->instances + inst->xy = (StretchPointWithinBoxes boxstretch inst->xy) + ) + (foreach shape CV->shapes + (cond (shape->objType=="rect" + shape->bBox = (list (StretchPointWithinBoxes boxstretch (car shape->bBox)) + (StretchPointWithinBoxes boxstretch (cadr shape->bBox))) + ) + (t + points = nil + (foreach xy shape->points + points = (append points + (list (StretchPointWithinBoxes boxstretch xy))) + ) + shape->points = points + ) + ) + ) + ) + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/GndSheild.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/GndSheild.il new file mode 100644 index 0000000000..54e8244a56 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/GndSheild.il @@ -0,0 +1,98 @@ +(defvar Scratch1LPP ( list "y1" "drawing" ) ) +(defvar Scratch3LPP ( list "y6" "drawing" ) ) +(defvar Scratch4LPP ( list "y7" "drawing" ) ) +(defvar Scratch5LPP ( list "y8" "drawing" ) ) +(defvar Scratch6LPP ( list "y9" "drawing" ) ) + +(defun DrawGndSheild () + (let (CellView INST bfr obstr overlapy5) + CellView=geGetEditCellView() + bfr=0 + obstr=0 + overlapy5=nil + ;locating instances like MBUFS and RESET cells + foreach(INST CellView->instances + (let (xy1 xy2 bx1 by1 bx2 by2 Instname pieces piecess LibName cbls) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + Instname=INST->cellName + pieces=parseString( Instname "." ) + LibName=nth( 0 pieces ) + when((LibName=="standard") || (LibName=="lib") + dbCreateRect(CellView Scratch5LPP list( bx1:by1 bx2:by2) ) + )) + ) + foreach(shape CellView-> shapes + when( (cadr(shape->lpp)== "bus") && (shape~>BufferHops!= nil) + CreateCableBoundary(?CableShape shape))) + foreach(shape CellView-> shapes + when((shape~>lpp==Scratch5LPP)||(car(shape~>lpp)=="OBS") + when(shape~>lpp==Scratch5LPP + leLayerXor(CellView list("y8" "drawing") list("prBoundary" "drawing") list("y6" "drawing")) + bfr=1) + when(car(shape~>lpp)=="OBS" + leLayerXor(CellView list("OBS" "bus") list("prBoundary" "drawing") list("y7" "drawing")) + obstr=1) + )) + when((obstr==1)&&(bfr==1) + leLayerAnd(CellView list("y7" "drawing") list("y6" "drawing") list("y9" "drawing"))) + when((obstr==1)&&(bfr==0) + leLayerAnd(CellView list("y7" "drawing") list("prBoundary" "drawing") list("y9" "drawing"))) + when((obstr==0)&&(bfr==1) + leLayerAnd(CellView list("y6" "drawing") list("prBoundary" "drawing") list("y9" "drawing"))) + foreach(shape CellView-> shapes + (let (xy1 xy2 bx1 by1 bx2 by2) + when(shape~>lpp==Scratch6LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapy5=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) list("y5" "drawing") 1) + when(overlapy5==nil + dbCreateRect(CellView Scratch1LPP list(bx1:by1 bx2:by2))) + ;leLayerAnd(CellView list("y9" "drawing") list("prBoundary" "drawing") list("y1" "drawing"))) + when(overlapy5!=nil + leLayerXor(CellView list("y9" "drawing") list("y5" "drawing") list("y1" "drawing")) + overlapy5==nil) + ) + )) + foreach(shape CellView-> shapes + when(shape~>lpp==Scratch1LPP + (let (xy1 xy2 bx1 by1 bx2 by2 diffx diffy numx numy inst gridCV overlapM4 overlapM5) + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapM4=nil + overlapM5=nil + overlapM4=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) list("M4" "drawing") 1) + overlapM5=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) list("M5" "drawing") 1) + when((overlapM4!=nil)&&(overlapM5==nil) + ;println("Vertical") + diffx=bx2-bx1 + diffy=by2-by1 + numx=round(diffx/3.12) + numy=round(diffy/3.12) + gridCV = (nrOpenCellViewReadable "globals" "globals.wires.HORIZONTAL_STRUTS_M357" "layout") + dbCreateSimpleMosaic( CellView gridCV nil bx1:by1 "R0" numy numx 3.12 3.12) + ) + when((overlapM4==nil)&&(overlapM5!=nil) + ;println("Horizontal") + diffx=bx2-bx1 + diffy=by2-by1 + numx=round(diffx/3.12) + numy=round(diffy/3.12) + gridCV = (nrOpenCellViewReadable "globals" "globals.wires.VERTICAL_STRUTS_M246" "layout") + dbCreateSimpleMosaic( CellView gridCV nil bx1:by1 "R0" numy numx 3.12 3.12) + ) + when((overlapM4!=nil)&&(overlapM5!=nil) + println("WEIRD")) + when((overlapM4==nil)&&(overlapM5==nil) + println("STILL WEIRD")) + ) + )) +)) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/Obstruction.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/Obstruction.il new file mode 100644 index 0000000000..9952326ac7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/Obstruction.il @@ -0,0 +1,85 @@ +(defun Obstruction ( LibName CellName ViewName ) + let( ( SHAPE) + CellView=nrOpenCellViewReadable( LibName CellName ViewName) + foreach(SHAPE CellView->shapes + (let (shp channelwidth channelhops sbufornt rbufornt channelbuf channelname channellayer cellname cn piecechannelname1 piecechannelname2 piecechannelname3 channame lowercase1 lowercase2 ncv mcv) + when(SHAPE~>purpose=="boundary" + dbCreatePath(CellView list("y2" "drawing") SHAPE~>points SHAPE~>width "varExtendExtend") + channelwidth=SHAPE~>ChannelWidth + channelhops=SHAPE~>ChannelHops + sbufornt=SHAPE~>sbuf_orient + rbufornt=SHAPE~>rbuf_orient + channelbuf=SHAPE~>ChannelBuf + channelname=SHAPE~>ChannelName + channellayer=SHAPE~>layerName + piecechannelname1=parseString( channelname "[") + when(length(piecechannelname1)>=2 + piecechannelname2=parseString( nth(1 piecechannelname1) "]") + lowercase1=lowerCase(nth(0 piecechannelname1)) + channame=strcat(lowercase1 "_" car(piecechannelname2))) + when(length(piecechannelname1)<2 + channame=lowerCase(channelname)) + cellname=sprintf( nil "chip.rrc.util.cable.%s_CABLE_MBUFS-L%d_%d-R.%s" channelbuf channelhops channelwidth channame) + println(cellname) + dbDeleteObject(SHAPE) + leLayerAnd(CellView list("y2" "drawing") list("M1" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M2" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M3" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M4" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M5" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M6" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M7" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M8" "boundary") list("OBS" "bus")) + leLayerAnd(CellView list("y2" "drawing") list("M9" "boundary") list("OBS" "bus")) + ncv = nrOpenCellViewWritable( "chip.rrc.util.cable" cellname "cable") + when(ncv!=nil + ddDeleteObj(ddGetObj("chip.rrc.util.cable" cellname "cable")) + ncv=nil) + foreach(shp CellView~>shapes + (let (obj) + when(shp~>lpp==list("OBS" "bus") + when(ncv==nil + mcv = nrOpenCellViewWritable( "chip.rrc.util.cable" cellname "cable") + + dbCopyShape(shp mcv) + dbDeleteObject(shp) + dbSave(mcv) + dbPurge(mcv) + )) + when(shp~>lpp==list("y2" "drawing") + obj=dbCreatePath(CellView list(channellayer "boundary") shp~>points shp~>width "varExtendExtend") + (dbReplaceProp obj "ChannelName" "string" channelname) + (dbReplaceProp obj "ChannelBuf" "string" channelbuf) + (dbReplaceProp obj "rbuf_orient" "string" rbufornt) + (dbReplaceProp obj "sbuf_orient" "string" sbufornt) + (dbReplaceProp obj "ChannelHops" "list" channelhops) + (dbReplaceProp obj "ChannelWidth" "list" channelwidth) + dbDeleteObject(shp)))) + + ) + )) + )) +(defun DrawCableOBS () + (let (fl k text lcv kcv libname cellname viewname piece n path) + lcv=nrOpenCellViewWritable( "chip.rrc.util.cable" "chip.rrc.util.cable.ALL_PATHS.1000" "scratch") + when(lcv!=nil + ddDeleteObj(ddGetObj("chip.rrc.util.cable" "chip.rrc.util.cable.ALL_PATHS.1000" "scratch")) + lcv=nil) + when(lcv==nil + kcv = nrOpenCellViewWritable( "chip.rrc.util.cable" "chip.rrc.util.cable.ALL_PATHS.1000" "scratch") + fl = infile("path.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + piece=parseString(car(text) ".") + libname=nth( 0 piece ) + cellname=car(text) + for( n 1 length(piece)-3 + libname = strcat( libname "." nth( n piece ))) + kcv = nrOpenCellViewWritable( "chip.rrc.util.cable" "chip.rrc.util.cable.ALL_PATHS.1000" "scratch") + path=dbCreateInstByMasterName(kcv libname cellname "floorplan" "path" 0.0:0 "R0") + dbFlattenInst(path 1) + dbSave(kcv) + dbPurge(kcv)) + Obstruction( "chip.rrc.util.cable" "chip.rrc.util.cable.ALL_PATHS.1000" "scratch" ) + ) +)) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/cdc_insts.txt b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/cdc_insts.txt new file mode 100644 index 0000000000..6beed6fc05 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/cdc_insts.txt @@ -0,0 +1,76 @@ +# ChannelName TxCell TxInst TxCDC RxCell RxInst RxCDC +HEADER_SUB[0] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[0]_u_a2s_subsegs +HEADER_SUB[1] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[1]_u_a2s_subsegs +HEADER_SUB[2] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[2]_u_a2s_subsegs +HEADER_SUB[3] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[3]_u_a2s_subsegs +HEADER_SUB[4] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[4]_u_a2s_subsegs +HEADER_SUB[5] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[5]_u_a2s_subsegs +HEADER_SUB[6] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[6]_u_a2s_subsegs +HEADER_SUB[7] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[7]_u_a2s_subsegs +HEADER_SUB[8] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[8]_u_a2s_subsegs +HEADER_SUB[9] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[9]_u_a2s_subsegs +HEADER_SUB[10] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[10]_u_a2s_subsegs +HEADER_SUB[11] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[11]_u_a2s_subsegs +HEADER_SUB[12] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[12]_u_a2s_subsegs +HEADER_SUB[13] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[13]_u_a2s_subsegs +HEADER_SUB[14] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[14]_u_a2s_subsegs +HEADER_SUB[15] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__fc__PARSING__1000 parsing gen_a2s_subsegs[15]_u_a2s_subsegs + +INGRESS_SUB[0] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][0] u_cdc_in +INGRESS_SUB[1] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][1] u_cdc_in +INGRESS_SUB[2] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][2] u_cdc_in +INGRESS_SUB[3] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][3] u_cdc_in +INGRESS_SUB[4] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][4] u_cdc_in +INGRESS_SUB[5] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][5] u_cdc_in +INGRESS_SUB[6] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][6] u_cdc_in +INGRESS_SUB[7] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][7] u_cdc_in +INGRESS_SUB[8] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][0] u_cdc_in +INGRESS_SUB[9] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][1] u_cdc_in +INGRESS_SUB[10] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][2] u_cdc_in +INGRESS_SUB[11] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][3] u_cdc_in +INGRESS_SUB[12] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][4] u_cdc_in +INGRESS_SUB[13] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][5] u_cdc_in +INGRESS_SUB[14] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][6] u_cdc_in +INGRESS_SUB[15] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][7] u_cdc_in +INGRESS_SUB[16] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][0] u_cdc_in +INGRESS_SUB[17] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][1] u_cdc_in +INGRESS_SUB[18] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][2] u_cdc_in +INGRESS_SUB[19] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][3] u_cdc_in +INGRESS_SUB[20] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][4] u_cdc_in +INGRESS_SUB[21] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][5] u_cdc_in +INGRESS_SUB[22] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][6] u_cdc_in +INGRESS_SUB[23] chip.rrc.fabric.ingress.INGRESS.1000 ingress nil chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][7] u_cdc_in + +ARRAY_SUB[0] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][0] u_cdc_out chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_array_sub[0]_u_a2s_hs_v_66_array_sub +ARRAY_SUB[1] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][1] u_cdc_out chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_array_sub[1]_u_a2s_hs_v_66_array_sub +ARRAY_SUB[2] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][2] u_cdc_out chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_array_sub[2]_u_a2s_hs_v_66_array_sub +ARRAY_SUB[3] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][3] u_cdc_out chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_array_sub[3]_u_a2s_hs_v_66_array_sub +ARRAY_SUB[4] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][4] u_cdc_out chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_array_sub[4]_u_a2s_hs_v_66_array_sub +ARRAY_SUB[5] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][5] u_cdc_out chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_array_sub[5]_u_a2s_hs_v_66_array_sub +ARRAY_SUB[6] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][6] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[7] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[0][7] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[8] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][0] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[9] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][1] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[10] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][2] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[11] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][3] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[12] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][4] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[13] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][5] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[14] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][6] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[15] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[1][7] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[16] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][0] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[17] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][1] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[18] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][2] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[19] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][3] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[20] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][4] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[21] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][5] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[22] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][6] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil +ARRAY_SUB[23] chip__rrc__fabric__array__ARRAY_SUBSEG__1000 subseg[2][7] u_cdc_out chip.rrc.fabric.egress.EGRESS.1000 egress nil + +EGRESS_SUB[0] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[0]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil +EGRESS_SUB[1] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[1]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil +EGRESS_SUB[2] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[2]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil +EGRESS_SUB[3] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[3]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil +EGRESS_SUB[4] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[4]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil +EGRESS_SUB[5] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[5]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil +EGRESS_SUB[6] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[6]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil +EGRESS_SUB[7] chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000 modify gen_egress_sub[7]_u_s2a_hs_h_76_egress_sub chip.rrc.fabric.egress.EGRESS.1000 egress nil diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/optimus.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/optimus.il new file mode 100644 index 0000000000..f2ff165570 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/optimus.il @@ -0,0 +1,25 @@ +; Copyright Intel Corporation. All rights reserved. +; $Author: pankala1 $ + +(defun TransformOptimus (ObjList) + let( ( Ovp InstHier TransList FinObj I Trnf ) + + Ovp = ObjList + InstHier = nil + TransList = nil + + while( listp(Ovp) + InstHier = cons(car(Ovp) InstHier) + Ovp = cadr(Ovp) + ) + + FinObj = Ovp + TransList = list(FinObj~>bBox) + + for( I 0 length(InstHier)-1 + Trnf = dbTransformBBox(car(TransList) nth(I InstHier)~>transform) + TransList = cons(Trnf TransList) + ) + list(FinObj car(TransList)) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/placer.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/placer.il new file mode 100644 index 0000000000..d547728203 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/placer.il @@ -0,0 +1,416 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/placer.il#1 $ +; $DateTime: 2012/07/27 17:24:08 $ +; $Author: pankala $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( PlaceCableBuffers ( @key (CableShape car(geGetSelectedSet())) (CV (UIGetCellView)) ) + let( ( + Hops CableWidth + BufIdx HopIdx + I J + StartDist EndDist HopDist + StartLoc + CurrLoc CurrIdx CurrSeg CurrDir + LocatorOP + EvInst EvInstName + OdInst ODInstName + CableLength SearchSeed + TemplateArray BufArray + StartDistX MInst BlkShape + ) + + foreach( MInst CV~>instances + MInst~>Orient = "R0" + MInst~>xy = 0:0 + ) + + foreach( BlkShape CV~>shapes + when( car(BlkShape~>lpp) == "y5" + dbDeleteObject(BlkShape) + ) + ) + + CBLCreateBufBlockage(?CableShape CableShape) + EndDist = CableShape~>OutputDistance_um + + Hops = CableShape~>BufferHops + when( stringp(Hops) + Hops = evalstring(CableShape~>BufferHops) + ) + + StartDist = CableShape~>InputDistance_um + when( stringp(StartDist) + StartDist = evalstring(CableShape~>InputDistance_um) + ) + + EndDist = CableShape~>OutputDistance_um + when( stringp(EndDist) + EndDist = evalstring(CableShape~>OutputDistance_um) + ) + + CableWidth = CableShape~>CableWidth + when( stringp(CableWidth) + CableWidth = evalstring(CableShape~>CableWidth) + ) + + println(CableWidth) + + StartDistX = round(StartDist/1.56)*1.56 + + SearchSeed = 0 + CableLength = CAComputeCableLength(CableShape) + HopDist = round(300.8/3.12)*3.12 ; 250.8 ; round(((CableLength - (StartDist + EndDist))/(Hops-1))/3.12) * 3.12 + BufIdx = 0 + StartLoc = nth(0 CableShape~>points) + BufArray = CBLCreateBufArray() + + for( HopIdx 0 Hops-1 + + ; println(HopIdx) + I = 0 + + while( I <= length(BufArray) - 1 ; evalstring(CableShape~>CableWidth) - 1 + + BufIdx = BufArray[I] + ; println(BufIdx) + + when( BufIdx <= CableWidth ; evalstring(CableShape~>CableWidth) + sprintf(EvInstName "mbuf[%d][%d]" HopIdx BufIdx) + sprintf(OdInstName "mbuf[%d][%d]" HopIdx BufIdx+1) + + EvInst = dbFindAnyInstByName(CV EvInstName) + OdInst = dbFindAnyInstByName(CV OdInstName) + + LocatorOP = CBLLocateBuffer(CableShape StartLoc StartDistX+(SearchSeed*I*3.12)+(HopIdx*HopDist)) + CurrLoc = nth(0 LocatorOP) + CurrIdx = nth(1 LocatorOP) + CurrSeg = nth(2 LocatorOP) + CurrDir = nth(3 LocatorOP) + + case( CurrSeg + ( "H" + if( CurrDir == "P" + then + EvInst~>orient = "R0" + OdInst~>orient = "R0" + EvInst~>xy = CurrLoc + OdInst~>xy = list(car(CurrLoc)+3.12 cadr(CurrLoc)) + EvInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + OdInst~>CablePt = list(car(CurrLoc)+3.12 cadr(CurrLoc)+0.78) + EvInst~>CableIdx = CurrIdx + OdInst~>CableIdx = CurrIdx + dbSet(EvInst "H" "Segment") + dbSet(OdInst "H" "Segment") + else + EvInst~>orient = "MY" + OdInst~>orient = "MY" + EvInst~>xy = CurrLoc + OdInst~>xy = list(car(CurrLoc)-3.12 cadr(CurrLoc)) + EvInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + OdInst~>CablePt = list(car(CurrLoc)-3.12 cadr(CurrLoc)+0.78) + EvInst~>CableIdx = CurrIdx + OdInst~>CableIdx = CurrIdx + dbSet(EvInst "H" "Segment") + dbSet(OdInst "H" "Segment") + ) + ) + ( "V" + if( CurrDir == "P" + then + EvInst~>orient = "R0" + OdInst~>orient = "R0" + EvInst~>xy = CurrLoc + OdInst~>xy = list(car(CurrLoc)+3.12 cadr(CurrLoc)) + EvInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + OdInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + EvInst~>CableIdx = CurrIdx + OdInst~>CableIdx = CurrIdx + dbSet(EvInst "V" "Segment") + dbSet(OdInst "V" "Segment") + else + EvInst~>orient = "MX" + OdInst~>orient = "MX" + EvInst~>xy = CurrLoc + OdInst~>xy = list(car(CurrLoc)+3.12 cadr(CurrLoc)) + EvInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + OdInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + EvInst~>CableIdx = CurrIdx + OdInst~>CableIdx = CurrIdx + dbSet(EvInst "V" "Segment") + dbSet(OdInst "V" "Segment") + ) + ) + ) + ) + I = I + 2 + ) + ) + + PlaceResetBufs(?CableShape CableShape) + + + ) + t +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLLocateBuffer (CableShape Loc Dist @key (CV (UIGetCellView)) (SearchMultiple 1) (BufType "DENSE")) + let( ( + Overlaps + LocatorOP BufOP + BufLocFound BufShape + CurrLoc CurrSeg CurrDir TrCurrLoc + FinalLoc FinalSeg FinalDir FinalIdx + ) + + BufLocFound = nil + + while( BufLocFound == nil + + LocatorOP = CBLLocateAtDist(CableShape Loc Dist ?CV CV) + + CurrLoc = car(LocatorOP) + CurrSeg = CBLCurrSegment(CableShape cadr(LocatorOP)) + CurrDir = CBLCurrDir(CableShape cadr(LocatorOP)) + + BufOP = CBLCreateBufShape(CurrLoc CurrSeg CurrDir ?BufType BufType ?CV CV) + BufShape = nth(0 BufOP) + + Overlaps = dbGetTrueOverlaps(CV BufShape~>bBox) + + if( CBLOveralapExists(Overlaps "placer") + then + dbDeleteObject(BufShape) + Dist = Dist + SearchMultiple*1.56 + else + BufLocFound = t + FinalIdx = cadr(LocatorOP) + FinalLoc = nth(3 BufOP) + FinalSeg = nth(1 BufOP) + FinalDir = nth(2 BufOP) + dbDeleteObject(BufShape) + ) + ) + + list(FinalLoc FinalIdx FinalSeg FinalDir) + + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLCreateBufShape (CurrLoc CurrSeg CurrDir @key (CV (UIGetCellView)) (BufType "DENSE")) + let( ( + BufShape + CurrLocX CurrLocY + TrCurrLoc + ) +case( BufType + + ( "DENSE" || "NYB" + case( CurrSeg + + ( "H" + if( CurrDir == "P" + then + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/3.12)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY+0.78 CurrLocX+5.46:CurrLocY+5.46)) + else + CurrLocX = (truncate(car(CurrLoc)/3.12)+1)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/3.12)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX-0.78:CurrLocY+0.78 CurrLocX-5.46:CurrLocY+5.46)) + ) + ) + ( "V" + if( CurrDir == "P" + then + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/3.12)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY+0.78 CurrLocX+5.46:CurrLocY+5.46)) + else + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = (truncate(cadr(CurrLoc)/3.12)+1)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY-0.78 CurrLocX+5.46:CurrLocY-5.46)) + ) + ) + ) + ) + + ( "TS" + case( CurrSeg + + ( "H" + if( CurrDir == "P" + then + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/1.56)*1.56 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY+0.78 CurrLocX+5.46:CurrLocY+7.02)) + else + CurrLocX = (truncate(car(CurrLoc)/3.12)+1)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/1.56)*1.56 + BufShape = dbCreateRect(CV "y4" list(CurrLocX-0.78:CurrLocY+0.78 CurrLocX-5.46:CurrLocY+7.02)) + ) + ) + ( "V" + if( CurrDir == "P" + then + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/1.56)*1.56 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY+0.78 CurrLocX+5.46:CurrLocY+7.02)) + else + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = (truncate(cadr(CurrLoc)/1.56)+1)*1.56 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY-0.78 CurrLocX+5.46:CurrLocY-7.02)) + ) + ) + ) + ) + + ( "RESET" + case( CurrSeg + + ( "H" + if( CurrDir == "P" + then + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/3.12)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY+0.78 CurrLocX+2.34:CurrLocY+2.34)) + else + CurrLocX = (truncate(car(CurrLoc)/3.12)+1)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/3.12)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX-0.78:CurrLocY+0.78 CurrLocX-2.34:CurrLocY+2.34)) + ) + ) + + ( "V" + if( CurrDir == "P" + then + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = truncate(cadr(CurrLoc)/3.12)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY+0.78 CurrLocX+2.34:CurrLocY+2.34)) + else + CurrLocX = truncate(car(CurrLoc)/3.12)*3.12 + CurrLocY = (truncate(cadr(CurrLoc)/3.12)+1)*3.12 + BufShape = dbCreateRect(CV "y4" list(CurrLocX+0.78:CurrLocY-0.78 CurrLocX+2.34:CurrLocY-2.34)) + ) + ) + + ) + ) + ) + + TrCurrLoc = list(CurrLocX CurrLocY) + + list(BufShape CurrSeg CurrDir TrCurrLoc) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; to be called only once all the MBUFs are placed on the cable guide. + +(defun PlaceResetBufs ( @key (CableShape car(geGetSelectedSet())) (CV (UIGetCellView)) ) + let( ( Hops HopIdx BufInst BufInstName + StartDist StartLoc StartDistX HopDist LocatorOP + ResetBufInst ResetBufInstName ResetRampInst ResetRampInstName + CurrLoc CurrIdx CurrSeg CurrDir + ) + + Hops = CableShape~>BufferHops + when( stringp(Hops) + Hops = evalstring(CableShape~>BufferHops) + ) + StartDist = CableShape~>InputDistance_um + when( stringp(StartDist) + StartDist = evalstring(CableShape~>InputDistance_um) + ) + + StartDistX = round(StartDist/1.56)*1.56 + HopDist = round(300.8/3.12)*3.12 + StartLoc = nth(0 CableShape~>points) + + for( HopIdx 0 Hops-1 + sprintf(BufInstName "mbuf[%d][0]", HopIdx) + sprintf(ResetBufInstName "bufReset[%d]", HopIdx) + sprintf(ResetRampInstName "rampReset[%d]", HopIdx) + + BufInst = dbFindAnyInstByName(CV BufInstName) + ResetBufInst = dbFindAnyInstByName(CV ResetBufInstName) + ResetRampInst = dbFindAnyInstByName(CV ResetRampInstName) + + LocatorOP = CBLLocateBuffer(CableShape StartLoc StartDistX+(HopIdx*HopDist) ?SearchMultiple -1 ?BufType "RESET") + CurrLoc = nth(0 LocatorOP) + CurrIdx = nth(1 LocatorOP) + CurrSeg = nth(2 LocatorOP) + CurrDir = nth(3 LocatorOP) + + case( CurrSeg + ( "H" + if( CurrDir == "P" + then + ResetBufInst~>orient = "R0" + ResetRampInst~>orient = "R0" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc) cadr(CurrLoc)+3.12) + ResetBufInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetRampInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "H" "Segment") + dbSet(ResetRampInst "H" "Segment") + else + ResetBufInst~>orient = "MY" + ResetRampInst~>orient = "MY" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc) cadr(CurrLoc)+3.12) + ResetBufInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetRampInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "H" "Segment") + dbSet(ResetRampInst "H" "Segment") + ) + ) + ( "V" + if( CurrDir == "P" + then + ResetBufInst~>orient = "R0" + ResetRampInst~>orient = "R0" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc)+3.12 cadr(CurrLoc)) + ResetBufInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetRampInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "V" "Segment") + dbSet(ResetRampInst "V" "Segment") + else + ResetBufInst~>orient = "MX" + ResetRampInst~>orient = "MX" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc)+3.12 cadr(CurrLoc)) + ResetBufInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetRampInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "V" "Segment") + dbSet(ResetRampInst "V" "Segment") + ) + ) + ) + + ) + + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;(defun AnalyzeCable ( @key (CableShape car(geGetSelectedSet())) ) +; let( ( ) +; +; +; +; +; ) +;) +; diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/routedbuffers.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/routedbuffers.il new file mode 100644 index 0000000000..601f0f9be9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/routedbuffers.il @@ -0,0 +1,364 @@ +(defun BuffersUpTo (x) + (let (TempStr) + for(n 0 (59 - x) + println(x) + sprintf(TempStr "%d" x) + DeleteMyObject(TempStr) + x = x + 1 + ) + ) + t +) + + +(defun DeleteMyObject (x) + (let (ObjL0 ObjL1 ObjLe ObjL2 ObjL3 + ObjR0 ObjR1 ObjRe ObjR2 ObjR3 + InstName view shapes) + + + ObjL0=strcat("L[" x "].0") + ObjL1=strcat("L[" x "].1") + ObjLe=strcat("L[" x "].e") + ObjL2=strcat("L[" x "].2") + ObjL3=strcat("L[" x "].3") + + ObjR0=strcat("R[" x "].0") + ObjR1=strcat("R[" x "].1") + ObjRe=strcat("R[" x "].e") + ObjR2=strcat("R[" x "].2") + ObjR3=strcat("R[" x "].3") + + InstName=strcat("mbuf[0][" x "]") + + view=(geGetEditCellView) + + (foreach shape view~>shapes + + (when shape~>net~>name==ObjL0 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjL1 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjLe + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjL2 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjL3 + (dbDeleteObject shape) + ) + + + (when shape~>net~>name==ObjR0 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjR1 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjRe + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjR2 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjR3 + (dbDeleteObject shape) + ) + ) + + (foreach via view~>vias + + (when via~>net~>name==ObjL0 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjL1 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjLe + (dbDeleteObject via) + ) + (when via~>net~>name==ObjL2 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjL3 + (dbDeleteObject via) + ) + + + (when via~>net~>name==ObjR0 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjR1 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjRe + (dbDeleteObject via) + ) + (when via~>net~>name==ObjR2 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjR3 + (dbDeleteObject via) + ) + ) + + (foreach instance view~>instances + + (when instance~>name==InstName + (dbDeleteObject instance) + ) + ) + ) + t +) + +(defun BuffersUpTo (x) + (let (TempStr) + for(n 0 (59 - x) + println(x) + sprintf(TempStr "%d" n) + DeleteMyObject(TempStr) + n = n + 1 + ) + + w = 60 - x + println(w) + for(m 0 (x - 1) + y = w - 60 + x + println(y) + sprintf(TempStr1 "%d" w) + sprintf(TempStr2 "%d" y) + SetObjProp(TempStr1 TempStr2) + w = w + 1 + ) + ) + t +) + + +(defun DeleteMyObject (z) + (let (ObjL0 ObjL1 ObjLe ObjL2 ObjL3 + ObjR0 ObjR1 ObjRe ObjR2 ObjR3 + InstName view shapes) + + + ObjL0=strcat("L[" z "].0") + ObjL1=strcat("L[" z "].1") + ObjLe=strcat("L[" z "].e") + ObjL2=strcat("L[" z "].2") + ObjL3=strcat("L[" z "].3") + + ObjR0=strcat("R[" z "].0") + ObjR1=strcat("R[" z "].1") + ObjRe=strcat("R[" z "].e") + ObjR2=strcat("R[" z "].2") + ObjR3=strcat("R[" z "].3") + + InstName=strcat("mbuf[0][" z "]") + + view=(geGetEditCellView) + + (foreach shape view~>shapes + + (when shape~>net~>name==ObjL0 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjL1 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjLe + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjL2 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjL3 + (dbDeleteObject shape) + ) + + + (when shape~>net~>name==ObjR0 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjR1 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjRe + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjR2 + (dbDeleteObject shape) + ) + (when shape~>net~>name==ObjR3 + (dbDeleteObject shape) + ) + ) + + (foreach via view~>vias + + (when via~>net~>name==ObjL0 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjL1 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjLe + (dbDeleteObject via) + ) + (when via~>net~>name==ObjL2 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjL3 + (dbDeleteObject via) + ) + + + (when via~>net~>name==ObjR0 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjR1 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjRe + (dbDeleteObject via) + ) + (when via~>net~>name==ObjR2 + (dbDeleteObject via) + ) + (when via~>net~>name==ObjR3 + (dbDeleteObject via) + ) + ) + + (foreach instance view~>instances + + (when instance~>name==InstName + (dbDeleteObject instance) + ) + ) + ) + t +) + + +(defun SetObjProp (w y) + (let (ObjL0 ObjL1 ObjLe ObjL2 ObjL3 + ObjR0 ObjR1 ObjRe ObjR2 ObjR3 + InstName view shapes) + + + + ObjL0=strcat("L[" w "].0") + ObjL1=strcat("L[" w "].1") + ObjLe=strcat("L[" w "].e") + ObjL2=strcat("L[" w "].2") + ObjL3=strcat("L[" w "].3") + + ObjL0r=strcat("L[" y "].0") + ObjL1r=strcat("L[" y "].1") + ObjLer=strcat("L[" y "].e") + ObjL2r=strcat("L[" y "].2") + ObjL3r=strcat("L[" y "].3") + + ObjR0=strcat("R[" w "].0") + ObjR1=strcat("R[" w "].1") + ObjRe=strcat("R[" w "].e") + ObjR2=strcat("R[" w "].2") + ObjR3=strcat("R[" w "].3") + + ObjR0r=strcat("R[" y "].0") + ObjR1r=strcat("R[" y "].1") + ObjRer=strcat("R[" y "].e") + ObjR2r=strcat("R[" y "].2") + ObjR3r=strcat("R[" y "].3") + + InstName=strcat("mbuf[0][" w "]") + + InstNamer=strcat("mbuf[0][" y "]") + + view=(geGetEditCellView) + + (foreach shape view~>shapes + + (when shape~>net~>name==ObjL0 + (dbSet shape ObjL0r "name") + ) + (when shape~>net~>name==ObjL1 + (dbSet shape ObjL1r "name") + ) + (when shape~>net~>name==ObjLe + (dbSet shape ObjLer "name") + ) + (when shape~>net~>name==ObjL2 + (dbSet shape ObjL2r "name") + ) + (when shape~>net~>name==ObjL3 + (dbSet shape ObjL3r "name") + ) + + + (when shape~>net~>name==ObjR0 + (dbSet shape ObjR0r "name") + ) + (when shape~>net~>name==ObjR1 + (dbSet shape ObjR1r "name") + ) + (when shape~>net~>name==ObjRe + (dbSet shape ObjRer "name") + ) + (when shape~>net~>name==ObjR2 + (dbSet shape ObjR2r "name") + ) + (when shape~>net~>name==ObjR3 + (dbSet shape ObjR3r "name") + ) + ) + + (foreach via view~>vias + + (when via~>net~>name==ObjL0 + (dbSet via ObjL0r "name") + ) + (when via~>net~>name==ObjL1 + (dbSet via ObjL1r "name") + ) + (when via~>net~>name==ObjLe + (dbSet via ObjLer "name") + ) + (when via~>net~>name==ObjL2 + (dbSet via ObjL2r "name") + ) + (when via~>net~>name==ObjL3 + (dbSet via ObjL3r "name") + ) + + + (when via~>net~>name==ObjR0 + (dbSet via ObjR0r "name") + ) + (when via~>net~>name==ObjR1 + (dbSet via ObjR1r "name") + ) + (when via~>net~>name==ObjRe + (dbSet via ObjRer "name") + ) + (when via~>net~>name==ObjR2 + (dbSet via ObjR2r "name") + ) + (when via~>net~>name==ObjR3 + (dbSet via ObjR3r "name") + ) + ) + + (foreach instance view~>instances + + (when instance~>name==InstName + (dbSet instance InstNamer "name") + ) + ) + ) + t +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/router.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/router.il new file mode 100644 index 0000000000..6a1cc6d815 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/router.il @@ -0,0 +1,759 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/router.il#1 $ +; $DateTime: 2012/07/27 17:24:08 $ +; $Author: pankala $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( DrawCablePins (CableShape CellVue Template) + let( ( + IpProbeXP IpProbeXN IpProbeYP IpProbeYN CableWidth + OpProbeXP OpProbeXN OpProbeYP OpProbeYN + IpRouteList OpRouteList + Idx TempArray + ) + + TempArray = CBLCreateTempArray(Template) + StartPt = nth(0 CableShape~>points) + EndPt = nth(CableShape~>nPoints-1 CableShape~>points) + + + CableWidth = CableShape~>CableWidth + when( stringp(CableWidth) + CableWidth = evalstring(CableShape~>CableWidth) + ) + + IpRouteList = list(StartPt car(CBLLocateAtDist(CableShape StartPt 0.39))) + + OpRouteList = list(EndPt car(CBLLocateAtDist(CableShape EndPt -0.39))) + + for( Idx 0 CableWidth - 1 + DrawChannel(nil DefChan(list(TempArray[Idx])) "L" IpRouteList ?isPin t) + DrawChannel(nil DefChan(list(TempArray[Idx])) "R" OpRouteList ?isPin t) + ) + + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( RouteCableBuffers (@optional (CableShape car(geGetSelectedSet())) (CellVue (UIGetCellView))) + let( ( BufIdx HopIdx + Hops Bufs BufArray CableWidth + temp + ) + + (DeleteBusWires) + DrawCablePins(CableShape CellVue "Template_A") + BufArray = CBLCreateBufArray() + + CableWidth = CableShape~>CableWidth + when( stringp(CableWidth) + CableWidth = evalstring(CableShape~>CableWidth) + ) + Hops = CableShape~>BufferHops + when( stringp(Hops) + Hops = evalstring(CableShape~>BufferHops) + ) + + if( evenp(CableWidth) + then + Bufs = truncate(CableWidth)/2 - 1 + else + Bufs = truncate(CableWidth)/2 - 1 + ) + + for( BufIdx 0 Bufs + TrBufIdx = BufArray[2*BufIdx] + when( BufIdx <= CableWidth + CBLPlaceWiringInst(CableShape 0 2*BufIdx "Template_A") + temp = CBLRouteBufferInput(CableShape 0 2*BufIdx "Template_A" "Input") + ) + ) + + for( HopIdx 1 Hops-1 + for( BufIdx 0 Bufs + TrBufIdx = BufArray[2*BufIdx] + when( BufIdx <= CableWidth + CBLPlaceWiringInst(CableShape HopIdx 2*BufIdx "Template_A") + temp = CBLRouteBufferInput(CableShape HopIdx 2*BufIdx "Template_A" "Buffer") + ) + ) + ) + + for( BufIdx 0 Bufs + TrBufIdx = BufArray[2*BufIdx] + when( BufIdx <= CableWidth + temp = CBLRouteBufferInput(CableShape Hops 2*BufIdx "Template_A" "Output") + ) + ) + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLFindCableSegPoints (CableShape StartPt EndPt) + let( ( + StartIdx + EndIdx + SegPoints + ) + + StartIdx = cadr(CBLFindPtIdxs(CableShape StartPt)) + EndIdx = cadr(CBLFindPtIdxs(CableShape EndPt)) + + SegPoints = list(EndPt) + I = EndIdx + + when( EndIdx - StartIdx > 0 + while( I > StartIdx + SegPoints = cons(nth(I-1 CableShape~>points) SegPoints) + I = I - 1 + ) + ) + + SegPoints = cons(StartPt SegPoints) + + SegPoints + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLRoundPts (RouteList) + let( ( + TrRouteList AdjustedXY + ) + + TrRouteList = nil + + for( I 0 length(RouteList)-1 + +; println(I) + AdjustedXY = nil + + when( I == 0 + if( cadr(nth(I RouteList)) == cadr(nth(I+1 RouteList)) + then + when( (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78 != cadr(nth(I RouteList)) + TrRouteList = append(TrRouteList list(list(car(nth(I RouteList)) (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78))) + AdjustedXY = t + ) + else + when( (truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 != car(nth(I RouteList)) + TrRouteList = append(TrRouteList list(list((truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 cadr(nth(I RouteList))))) + AdjustedXY = t + ) + ) + when( AdjustedXY == nil + TrRouteList = append(TrRouteList list(nth(I RouteList))) + ) + ) + + when( I == length(RouteList)-1 + if( cadr(nth(I RouteList)) == cadr(nth(I-1 RouteList)) + then + when( (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78 != cadr(nth(I RouteList)) + TrRouteList = append(TrRouteList list(list(car(nth(I RouteList)) (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78))) + ) + else + when( (truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 != car(nth(I RouteList)) + TrRouteList = append(TrRouteList list(list((truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 cadr(nth(I RouteList))))) + ) + ) + when( AdjustedXY == nil + TrRouteList = append(TrRouteList list(nth(I RouteList))) + ) + ) + + when( I > 0 && I < length(RouteList)-1 + when( (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78 != cadr(nth(I RouteList)) && (truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 != car(nth(I RouteList)) + TrRouteList = append(TrRouteList list(list((truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78))) + AdjustedXY = t + ) + when( (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78 != cadr(nth(I RouteList)) && AdjustedXY == nil + TrRouteList = append(TrRouteList list(list(car(nth(I RouteList)) (truncate(cadr(nth(I RouteList))/3.12)*3.12)+0.78))) + AdjustedXY = t + ) + when( (truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 != car(nth(I RouteList)) && AdjustedXY == nil + TrRouteList = append(TrRouteList list(list((truncate(car(nth(I RouteList))/3.12)*3.12)+0.78 cadr(nth(I RouteList))))) + AdjustedXY = t + ) + when( AdjustedXY == nil + TrRouteList = append(TrRouteList list(nth(I RouteList))) + ) + ) + + ) + TrRouteList + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLRouteBufferInput (CableShape HopIdx BufIdx TempType RouteType @key (CellVue (UIGetCellView))) + let( ( TempArray + OpEvInst OpEvInstName + OpOdInst OpOdInstName + IpEvInst IpEvInstName + IpOdInst IpOdInstName + StartPt StartSeg TrStartPt + EndPt EndSeg TrEndPt + RouteList TrRouteList + IpSegOp OpSegOp + EvNetName OdNetName + ) + + TempArray = CBLCreateTempArray(TempType) + + sprintf(OpEvInstName "mbuf[%d][%d]" HopIdx BufIdx) + sprintf(OpOdInstName "mbuf[%d][%d]" HopIdx BufIdx+1) + sprintf(IpEvInstName "mbuf[%d][%d]" HopIdx-1 BufIdx) + sprintf(IpOdInstName "mbuf[%d][%d]" HopIdx-1 BufIdx+1) + + OpEvInst = dbFindAnyInstByName(CellVue OpEvInstName) + OpOdInst = dbFindAnyInstByName(CellVue OpOdInstName) + IpEvInst = dbFindAnyInstByName(CellVue IpEvInstName) + IpOdInst = dbFindAnyInstByName(CellVue IpOdInstName) + + when( IpEvInst != nil || OpEvInst != nil + + IpSegOp = CBLFindInstCableSeg(CableShape IpEvInst) + OpSegOp = CBLFindInstCableSeg(CableShape OpEvInst) + + + StartPt = cadr(IpSegOp) + EndPt = cadr(OpSegOp) + + StartSeg = car(IpSegOp) + EndSeg = car(OpSegOp) + + case( StartSeg + + ( "H" + if( IpEvInst~>orient == "R0" + then + TrStartPt = list(car(StartPt)+6.24 cadr(StartPt)) + else + TrStartPt = list(car(StartPt)-6.24 cadr(StartPt)) + ) + ) + + ( "V" + if( IpEvInst~>orient == "R0" + then + TrStartPt = list(car(StartPt) cadr(StartPt)+6.24) + else + TrStartPt = list(car(StartPt) cadr(StartPt)-6.24) + ) + ) + + ) + + case( RouteType + + ( "Buffer" + RouteList = CBLFindCableSegPoints(CableShape TrStartPt EndPt) + ) + + ( "Input" + RouteList = CBLFindCableSegPoints(CableShape nth(0 CableShape~>points) EndPt) + ) + + ( "Output" + RouteList = CBLFindCableSegPoints(CableShape TrStartPt nth(length(CableShape~>points)-1 CableShape~>points)) + ) + + ) + + ; RouteList = CBLFindCableSegPoints(CableShape TrStartPt EndPt) + + + ; TrRouteList = CBLRoundPts(RouteList) + + sprintf(EvNetName "wrA[%d]" HopIdx-1) + DrawChannel(nil DefChan(list(TempArray[BufIdx])) EvNetName RouteList) + + ) + + when( OpOdInst != nil || IpOdInst != nil + sprintf(OdNetName "wrA[%d]" HopIdx-1) + DrawChannel(nil DefChan(list(TempArray[BufIdx+1])) OdNetName RouteList) + ) + + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLPlaceWiringInst (CableShape HopIdx BufIdx TempType @key (CellVue (UIGetCellView))) + let( ( TempArray + Pts PtFound + I Metals + EvInst EvInstName + OdInst OdInstName + WrInst WrInstName WrCellName + CurrIdx CurrSeg + ) + + declare(Pts[4]) + I = 0 + TempArray = CBLCreateTempArray(TempType) + + WrCellName = "globals.cable.wires.M" + + sprintf(EvInstName "mbuf[%d][%d]" HopIdx BufIdx) + sprintf(OdInstName "mbuf[%d][%d]" HopIdx BufIdx+1) + + sprintf(WrInstName "wr[%d][%d]" HopIdx BufIdx) + + EvInst = dbFindAnyInstByName(CellVue EvInstName) + OdInst = dbFindAnyInstByName(CellVue OdInstName) + + when( EvInst != nil + CurrSeg = car(CBLFindInstCableSeg(CableShape EvInst)) + + + println(CurrSeg) + + Metals = parseString(nth(2 nth(3 TempArray[BufIdx])) "M") + WrCellName = strcat(WrCellName cadr(Metals) car(Metals) CurrSeg "_0") + println(WrInstName) + + WrInst = dbCreateInstByMasterName(CellVue "globals.cable" WrCellName "layout" WrInstName EvInst~>xy EvInst~>orient) + + WrInst~>Pitch = nth(2 TempArray[BufIdx]) + when( OdInst == nil + WrInst~>Odd_Channel = "FALSE" + ) + ) + WrInst + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLFindInstCableSeg (CableShape EvInst @key (CellVue (UIGetCellView))) + let( ( + Probe_Bot_0 Probe_Bot_1 + Probe_Top_0 Probe_Top_1 + Ovp_Bot_0 Ovp_Bot_1 + Ovp_Top_0 Ovp_Top_1 + CurrSeg CurrLoc + ) + + CurrSeg = nil + + when( EvInst != nil + case( EvInst~>orient + + ( "R0" + Probe_Bot_0 = list(car(EvInst~>xy)+0.39:cadr(EvInst~>xy)+0.39 car(EvInst~>xy)+2.73:cadr(EvInst~>xy)+1.17) + Probe_Bot_1 = list(car(EvInst~>xy)+0.39:cadr(EvInst~>xy)+1.95 car(EvInst~>xy)+2.73:cadr(EvInst~>xy)+2.73) + + Probe_Top_0 = list(car(EvInst~>xy)+0.39:cadr(EvInst~>xy)+3.51 car(EvInst~>xy)+1.17:cadr(EvInst~>xy)+5.85) + Probe_Top_1 = list(car(EvInst~>xy)+1.95:cadr(EvInst~>xy)+3.51 car(EvInst~>xy)+2.73:cadr(EvInst~>xy)+5.85) + ) + + ( "MY" + Probe_Bot_0 = list(car(EvInst~>xy)-0.39:cadr(EvInst~>xy)+0.39 car(EvInst~>xy)-2.73:cadr(EvInst~>xy)+1.17) + Probe_Bot_1 = list(car(EvInst~>xy)-0.39:cadr(EvInst~>xy)+1.95 car(EvInst~>xy)-2.73:cadr(EvInst~>xy)+2.73) + + Probe_Top_0 = list(car(EvInst~>xy)-0.39:cadr(EvInst~>xy)+3.51 car(EvInst~>xy)-1.17:cadr(EvInst~>xy)+5.85) + Probe_Top_1 = list(car(EvInst~>xy)-1.95:cadr(EvInst~>xy)+3.51 car(EvInst~>xy)-2.73:cadr(EvInst~>xy)+5.85) + + CurrSeg = "H" + ) + + ( "MX" + Probe_Bot_0 = list(car(EvInst~>xy)+0.39:cadr(EvInst~>xy)-0.39 car(EvInst~>xy)+2.73:cadr(EvInst~>xy)-1.17) + Probe_Bot_1 = list(car(EvInst~>xy)+0.39:cadr(EvInst~>xy)-1.95 car(EvInst~>xy)+2.73:cadr(EvInst~>xy)-2.73) + + Probe_Top_0 = list(car(EvInst~>xy)+0.39:cadr(EvInst~>xy)-3.51 car(EvInst~>xy)+1.17:cadr(EvInst~>xy)-5.85) + Probe_Top_1 = list(car(EvInst~>xy)+1.95:cadr(EvInst~>xy)-3.51 car(EvInst~>xy)+2.73:cadr(EvInst~>xy)-5.85) + + CurrSeg = "V" + ) + + ) + + Ovp_Bot_0 = CBLOveralapExists(dbGetTrueOverlaps(CellVue Probe_Bot_0) "router") + Ovp_Bot_1 = CBLOveralapExists(dbGetTrueOverlaps(CellVue Probe_Bot_1) "router") + Ovp_Top_0 = CBLOveralapExists(dbGetTrueOverlaps(CellVue Probe_Top_0) "router") + Ovp_Top_1 = CBLOveralapExists(dbGetTrueOverlaps(CellVue Probe_Top_1) "router") + + when( EvInst~>orient == "R0" + if( (Ovp_Bot_0 == t || Ovp_Bot_1 == t) && (Ovp_Top_0 == t || Ovp_Top_1 == t) + then + CurrSeg = "V" + else + CurrSeg = "H" + ) + ) + + case( CurrSeg + + ( "H" + if( Ovp_Bot_0 == t + then + CurrLoc = list(car(EvInst~>xy) cadr(EvInst~>xy)+0.78) + else + CurrLoc = list(car(EvInst~>xy) cadr(EvInst~>xy)+2.34) + ) + ) + + ( "V" + if( Ovp_Top_0 == t + then + CurrLoc = list(car(EvInst~>xy)+0.78 cadr(EvInst~>xy)) + else + CurrLoc = list(car(EvInst~>xy)+2.34 cadr(EvInst~>xy)) + ) + ) + ) + ) + list(CurrSeg CurrLoc) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun RouteBufReset (@optional (CableShape car(geGetSelectedSet())) (CellVue (UIGetCellView))) + let( ( BufResetPts BufToRampPts Hops + CurrInstName NextInstName CurrInst RampInstName RampInst NextInst ResNetName + StartPt EndPt + ) + + Hops = evalstring(CableShape~>BufferHops) + + for( HopIdx 0 Hops-1 + when( HopIdx == 0 + sprintf(NextInstName "bufReset[%d]", HopIdx) + + NextInst = dbFindAnyInstByName(CellVue NextInstName) + + StartPt = nth(0 CableShape~>points) + EndPt = car(FindResetPts(NextInst)) + + BufResetPts = TransformCablePoints(CableShape StartPt EndPt 1 NextInst~>CableIdx 1.56 0) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal34))) "L_RESET" BufResetPts) + ) + when( HopIdx != Hops-1 + sprintf(CurrInstName "bufReset[%d]", HopIdx) + sprintf(NextInstName "bufReset[%d]", HopIdx+1) + + CurrInst = dbFindAnyInstByName(CellVue CurrInstName) + NextInst = dbFindAnyInstByName(CellVue NextInstName) + + StartPt = cadr(FindResetPts(CurrInst)) + EndPt = car(FindResetPts(NextInst)) + + BufResetPts = TransformCablePoints(CableShape StartPt EndPt CurrInst~>CableIdx NextInst~>CableIdx 1.56 0) + sprintf(ResNetName "w_BufReset[%d]", HopIdx+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal34))) ResNetName BufResetPts) + ConnectBufToRamp(CurrInst HopIdx) + ) + when( HopIdx == Hops-1 + sprintf(CurrInstName "bufReset[%d]", HopIdx) + + CurrInst = dbFindAnyInstByName(CellVue CurrInstName) + + StartPt = cadr(FindResetPts(CurrInst)) + EndPt = nth(CableShape~>nPoints-1 CableShape~>points) + + BufResetPts = TransformCablePoints(CableShape StartPt EndPt CurrInst~>CableIdx CableShape~>nPoints-1 1.56 0) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal34))) "R_RESET" BufResetPts) + ConnectBufToRamp(CurrInst HopIdx) + ) + ) + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ConnectBufToRamp ( BufResInst Hop ) + let( ( StartPt EndPt ResNetName ) + + case( BufResInst~>Segment + ( "H" + if( BufResInst~>orient == "R0" + then + StartPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)+2.34) + EndPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)+3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufResInst~>xy)-2.34 cadr(BufResInst~>xy)+2.34) + EndPt = list(car(BufResInst~>xy)-2.34 cadr(BufResInst~>xy)+3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ( "V" + if( BufResInst~>orient == "R0" + then + StartPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)+0.78) + EndPt = list(car(BufResInst~>xy)+3.90 cadr(BufResInst~>xy)+0.78) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)-0.78) + EndPt = list(car(BufResInst~>xy)+3.90 cadr(BufResInst~>xy)-0.78) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ) + + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun RouteRampReset (@optional (CableShape car(geGetSelectedSet())) (CellVue (UIGetCellView))) + let( ( RampResetPts Hops Bufs BufIdx RampInstName RampInst + FirstInstName LastInstName FirstInst LastInst ResNetName + StartPt EndPt HopIdx FirstIdx LastIdx EvInstName EvInst + ) + + Hops = CableShape~>BufferHops + when( stringp(Hops) + Hops = evalstring(CableShape~>BufferHops) + ) + + Bufs = CableShape~>CableWidth + when( stringp(Bufs) + Bufs = evalstring(CableShape~>CableWidth) + ) + + BufArray = CBLCreateBufArray() + + if( Bufs <= CableBufferSplitIdx + then + FirstIdx = 0 + LastIdx = truncate((Bufs-1)/2)*2 + else + FirstIdx = CableBufferSplitIdx + LastIdx = truncate((CableBufferSplitIdx - 1)/2)*2 + ) + + println(LastIdx) + + for( HopIdx 0 Hops-1 + + sprintf(FirstInstName "mbuf[%d][%d]", HopIdx,FirstIdx) + sprintf(LastInstName "mbuf[%d][%d]", HopIdx,LastIdx) + FirstInst = dbFindAnyInstByName(CellVue FirstInstName) + LastInst = dbFindAnyInstByName(CellVue LastInstName) + sprintf(RampInstName "rampReset[%d]", HopIdx) + RampInst = dbFindAnyInstByName(CellVue RampInstName) + + + StartPt = cadr(FindResetPts(FirstInst)) + EndPt = car(FindResetPts(LastInst)) + + RampResetPts = TransformCablePoints(CableShape StartPt EndPt FirstInst~>CableIdx LastInst~>CableIdx -0.325 4.68) + sprintf(ResNetName "w_rampReset[%d]", HopIdx+1) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName RampResetPts) + + ConnectRampToMbuf(RampInst HopIdx) + + for( BufIdx 0 Bufs-1 + when( evenp(BufIdx) + sprintf(EvInstName "mbuf[%d][%d]", HopIdx,BufIdx) + EvInst = dbFindAnyInstByName(CellVue EvInstName) + ConnectEvenOddResets(EvInst HopIdx) + ) + ) + ) + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ConnectEvenOddResets ( BufInst Hop ) + let( ( StartPt EndPt ResNetName ) + + case( BufInst~>Segment + ( "H" + if( BufInst~>orient == "R0" + then + StartPt = list(car(BufInst~>xy)+2.34 cadr(BufInst~>xy)+5.46) + EndPt = list(car(BufInst~>xy)+3.90 cadr(BufInst~>xy)+5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufInst~>xy)-2.34 cadr(BufInst~>xy)+5.46) + EndPt = list(car(BufInst~>xy)-3.90 cadr(BufInst~>xy)+5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ( "V" + if( BufInst~>orient == "R0" + then + StartPt = list(car(BufInst~>xy)+2.34 cadr(BufInst~>xy)+5.46) + EndPt = list(car(BufInst~>xy)+3.90 cadr(BufInst~>xy)+5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufInst~>xy)+2.34 cadr(BufInst~>xy)-5.46) + EndPt = list(car(BufInst~>xy)+3.90 cadr(BufInst~>xy)-5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ) + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ConnectRampToMbuf ( RampResInst Hop ) + let( ( StartPt EndPt ResNetName ) + + case( RampResInst~>Segment + ( "H" + if( RampResInst~>orient == "R0" + then + StartPt = list(car(RampResInst~>xy)+2.34 cadr(RampResInst~>xy)+2.34) + EndPt = list(car(RampResInst~>xy)+3.90 cadr(RampResInst~>xy)+2.34) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(RampResInst~>xy)-2.34 cadr(RampResInst~>xy)+2.34) + EndPt = list(car(RampResInst~>xy)-3.90 cadr(RampResInst~>xy)+2.34) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ( "V" + if( RampResInst~>orient == "R0" + then + StartPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)+2.34) + EndPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)+3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)-2.34) + EndPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)-3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ) + + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun FindResetPts ( Inst ) + let( ( StartPt EndPt ) + + case( car(parseString(Inst~>name "[")) + + ( "bufReset" + case( Inst~>Segment + ( "H" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt)+0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)+2.34 cadr(Inst~>CablePt)) + else + StartPt = list(car(Inst~>CablePt)-0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)-2.34 cadr(Inst~>CablePt)) + ) + ) + ( "V" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+2.34) + else + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-2.34) + ) + ) + ) + ) + + ( "rampReset" + case( Inst~>Segment + ( "H" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt)+0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)+2.34 cadr(Inst~>CablePt)) + else + StartPt = list(car(Inst~>CablePt)-0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)-2.34 cadr(Inst~>CablePt)) + ) + ) + ( "V" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+2.34) + else + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-2.34) + ) + ) + ) + ) + + ( "mbuf" + case( Inst~>Segment + ( "H" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt)+0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)+2.34 cadr(Inst~>CablePt)) + else + StartPt = list(car(Inst~>CablePt)-0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)-2.34 cadr(Inst~>CablePt)) + ) + ) + ( "V" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+5.46) + else + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-5.46) + ) + ) + ) + ) + + ) + +list(StartPt EndPt) + ) +) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun TransformCablePoints (CableShape StartPt EndPt StartIdx EndIdx HOffset VOffset) + let( ( OutPts NOutPts CablePt I ) + + NOutPts = EndIdx - StartIdx + 2 + + for( I 0 NOutPts-1 + println(I) + when( I == 0 + if( CBLCurrSegment(CableShape StartIdx) == "H" + then + OutPts = list(list(car(StartPt) cadr(StartPt)+VOffset)) + else + OutPts = list(list(car(StartPt)+HOffset cadr(StartPt))) + ) + ) + + when( I != 0 && I != NOutPts-1 + CablePt = nth((StartIdx + I - 1) CableShape~>points) + OutPts = append(OutPts list(list(car(CablePt)+HOffset cadr(CablePt)+VOffset))) + ) + + when( I == NOutPts-1 + if( CBLCurrSegment(CableShape EndIdx) == "H" + then + OutPts = append(OutPts list(list(car(EndPt) cadr(EndPt)+VOffset))) + else + OutPts = append(OutPts list(list(car(EndPt)+HOffset cadr(EndPt)))) + ) + ) + + ) + + OutPts + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/sync_placer.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/sync_placer.il new file mode 100644 index 0000000000..f76e5a28fd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/sync_placer.il @@ -0,0 +1,800 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun PlaceSyncCableBuffers ( @key (CableShape car(geGetSelectedSet())) (CV (UIGetCellView)) (ResetDist t) ) + let( ( + Hops CableWidth + BufIdx HopIdx + I J + StartDist EndDist HopDist HopDistX BufType + StartLoc + CurrLoc CurrIdx CurrSeg CurrDir + LocatorOP + EvInst EvInstName + OdInst ODInstName + Inst InstName + CableLength SearchSeed SearchDist SearchLoc SearchBuf SearchBufName + TemplateArray BufArray + StartDistX MInst BlkShape + ) + +; Move all the Instances to origin initially. + foreach( MInst CV~>instances MInst~>Orient = "R0" MInst~>xy = 0:0 ) +; Delete old buffer blockage shapes. + foreach( BlkShape CV~>shapes when( car(BlkShape~>lpp) == "y5" dbDeleteObject(BlkShape)) ) + + CBLCreateBufBlockage(?CableShape CableShape ?CV CV) + + Hops = CableShape~>ChannelHops + CableWidth = CableShape~>ChannelWidth + StartDist = CableShape~>InputDistance_um + EndDist = CableShape~>OutputDistance_um + HopDist = CableShape~>HopDistance_um + BufType = CableShape~>ChannelBuf + StartDistX = round(StartDist/1.56)*1.56 + HopDistX = round(HopDist/3.12)*3.12 + SearchSeed = 0 + BufIdx = 0 + CableLength = CAComputeCableLength(CableShape) + StartLoc = nth(0 CableShape~>points) + BufArray = CBLCreateBufArray(?Size CableWidth) + + for( HopIdx 0 Hops-1 + + I = 0 + if( HopIdx == 0 + then + SearchDist = StartDistX+(SearchSeed*I*3.12)+(HopIdx*HopDist) + SearchLoc = StartLoc + else + t +; SearchBufName = sprintf(nil "mbuf[%d][%d]" HopIdx-1 BufArray[0]) +; SearchBuf = dbFindAnyInstByName(CV SearchBufName) +; SearchLoc = SearchBuf~>CablePt +; SearchDist = HopDist + ) + + println(SearchDist) + println(SearchLoc) + + while( I <= length(BufArray) - 1 + + if( HopIdx == 0 + then + BufIdx = BufArray[I] + SearchMultiple = 1 + else + BufIdx = BufArray[length(BufArray)-I-1] + println(BufIdx) + SearchBufName = sprintf(nil "mbuf[%d][%d]" HopIdx-1 BufArray[length(BufArray)-1]) + SearchBuf = dbFindAnyInstByName(CV SearchBufName) + SearchLoc = SearchBuf~>CablePt + SearchDist = HopDist + SearchMultiple = -1 + ) + + when( BufIdx <= CableWidth + InstName = sprintf(nil "mbuf[%d][%d]" HopIdx BufIdx) + Inst = dbFindAnyInstByName(CV InstName) + LocatorOP = CBLLocateBuffer(CableShape SearchLoc SearchDist ?SearchMultiple SearchMultiple ?BufType BufType ?CV CV) + CurrLoc = nth(0 LocatorOP) + CurrIdx = nth(1 LocatorOP) + CurrSeg = nth(2 LocatorOP) + CurrDir = nth(3 LocatorOP) + + case( CurrSeg + ( "H" + if( CurrDir == "P" + then + Inst~>orient = "MXR90" + Inst~>xy = CurrLoc + Inst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + Inst~>CableIdx = CurrIdx + dbSet(Inst "H" "Segment") + else + Inst~>orient = "R90" + Inst~>xy = CurrLoc + Inst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + Inst~>CableIdx = CurrIdx + dbSet(Inst "H" "Segment") + ) + ) + ( "V" + if( CurrDir == "P" + then + Inst~>orient = "MXR90" + Inst~>xy = CurrLoc + Inst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + Inst~>CableIdx = CurrIdx + dbSet(Inst "V" "Segment") + else + Inst~>orient = "R270" + Inst~>xy = CurrLoc + Inst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + Inst~>CableIdx = CurrIdx + dbSet(Inst "V" "Segment") + ) + ) + ) + ) + I = I + 1 ; 2 + ) + ) + +; when( ResetDist +; PlaceSyncResetBufs(?CableShape CableShape ?CV CV) +; ) + + ) + t +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun RouteSyncCableBuffers (@optional (CableShape car(geGetSelectedSet())) (CV (UIGetCellView))) + let( ( BufIdx HopIdx + Hops Bufs BufArray + temp + ) + + (DeleteBusWires) + DrawCablePins(CableShape CV "Template_A_R90") + BufArray = CBLCreateBufArray() + + if( evenp(evalstring(CableShape~>CableWidth)) + then + Bufs = truncate(evalstring(CableShape~>CableWidth))/2 - 1 + else + Bufs = truncate(evalstring(CableShape~>CableWidth))/2 - 1 + ) + + Hops = CableShape~>BufferHops + when( type(Hops) == "string" + Hops = evalstring(CableShape~>BufferHops) + ) + + for( BufIdx 0 Bufs + TrBufIdx = BufArray[2*BufIdx] + when( BufIdx <= evalstring(CableShape~>CableWidth) + CBLPlaceSyncWiringInst(CableShape 0 2*BufIdx "Template_A") + temp = CBLRouteSyncBufferInput(CableShape 0 2*BufIdx "Template_A_R90" "Input") + ) + ) + + for( HopIdx 1 Hops-1 + for( BufIdx 0 Bufs + TrBufIdx = BufArray[2*BufIdx] + when( BufIdx <= evalstring(CableShape~>CableWidth) + CBLPlaceSyncWiringInst(CableShape HopIdx 2*BufIdx "Template_A") + temp = CBLRouteSyncBufferInput(CableShape HopIdx 2*BufIdx "Template_A_R90" "Buffer") + ) + ) + ) + + for( BufIdx 0 Bufs + TrBufIdx = BufArray[2*BufIdx] + when( BufIdx <= evalstring(CableShape~>CableWidth) + temp = CBLRouteSyncBufferInput(CableShape Hops 2*BufIdx "Template_A_R90" "Output") + ) + ) + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( DrawSyncCablePins (@optional (CableShape car(geGetSelectedSet())) (CV (UIGetCellView))) + let( ( + IpProbeXP IpProbeXN IpProbeYP IpProbeYN + OpProbeXP OpProbeXN OpProbeYP OpProbeYN + IpRouteList OpRouteList + Idx TempArray + ) + + TempArray = CBLCreateTempArray("Template_A_R90") + StartPt = nth(0 CableShape~>points) + EndPt = nth(CableShape~>nPoints-1 CableShape~>points) + + IpRouteList = list(StartPt car(CBLLocateAtDist(CableShape StartPt 0.39))) + + OpRouteList = list(EndPt car(CBLLocateAtDist(CableShape EndPt -0.39))) + + for( Idx 0 evalstring(CableShape~>CableWidth) - 1 + DrawChannel(nil DefChan(list(TempArray[Idx])) "L" IpRouteList ?isPin t) + DrawChannel(nil DefChan(list(TempArray[Idx])) "R" OpRouteList ?isPin t) + ) + + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CBLRouteSyncBufferInput (CableShape HopIdx BufIdx TempType RouteType @key (CV (UIGetCellView))) + let( ( TempArray + OpEvInst OpEvInstName + OpOdInst OpOdInstName + IpEvInst IpEvInstName + IpOdInst IpOdInstName + StartPt StartSeg TrStartPt + EndPt EndSeg TrEndPt + RouteList TrRouteList + IpSegOp OpSegOp + EvNetName OdNetName + ) + + TempArray = CBLCreateTempArray(TempType) + + sprintf(OpEvInstName "mbuf[%d][%d]" HopIdx BufIdx) + sprintf(OpOdInstName "mbuf[%d][%d]" HopIdx BufIdx+1) + sprintf(IpEvInstName "mbuf[%d][%d]" HopIdx-1 BufIdx) + sprintf(IpOdInstName "mbuf[%d][%d]" HopIdx-1 BufIdx+1) + + OpEvInst = dbFindAnyInstByName(CV OpEvInstName) + OpOdInst = dbFindAnyInstByName(CV OpOdInstName) + IpEvInst = dbFindAnyInstByName(CV IpEvInstName) + IpOdInst = dbFindAnyInstByName(CV IpOdInstName) + + when( IpEvInst != nil || OpEvInst != nil + + StartPt = IpEvInst~>CablePt + EndPt = OpEvInst~>CablePt + + StartSeg = IpEvInst~>Segment + EndSeg = OpEvInst~>Segment + + case( StartSeg + + ( "H" + if( IpEvInst~>orient == "MXR90" + then + TrStartPt = list(car(StartPt)+6.24 cadr(StartPt)) + else + TrStartPt = list(car(StartPt)-6.24 cadr(StartPt)) + ) + ) + + ( "V" + if( IpEvInst~>orient == "MXR90" + then + TrStartPt = list(car(StartPt) cadr(StartPt)+6.24) + else + TrStartPt = list(car(StartPt) cadr(StartPt)-6.24) + ) + ) + + ) + + case( RouteType + + ( "Buffer" + RouteList = CBLFindCableSegPoints(CableShape TrStartPt EndPt) + ) + + ( "Input" + RouteList = CBLFindCableSegPoints(CableShape nth(0 CableShape~>points) EndPt) + ) + + ( "Output" + RouteList = CBLFindCableSegPoints(CableShape TrStartPt nth(length(CableShape~>points)-1 CableShape~>points)) + ) + + ) + + sprintf(EvNetName "wrA[%d]" HopIdx-1) + DrawChannel(nil DefChan(list(TempArray[BufIdx])) EvNetName RouteList) + + ) + + when( OpOdInst != nil || IpOdInst != nil + sprintf(OdNetName "wrA[%d]" HopIdx-1) + DrawChannel(nil DefChan(list(TempArray[BufIdx+1])) OdNetName RouteList) + ) + + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CBLPlaceSyncWiringInst (CableShape HopIdx BufIdx TempType @key (CV (UIGetCellView))) + let( ( TempArray + Pts PtFound + I Metals + EvInst EvInstName + OdInst OdInstName + WrInst WrInstName WrCellName + CurrIdx CurrSeg + ) + + declare(Pts[4]) + I = 0 + TempArray = CBLCreateTempArray(TempType) + + WrCellName = "globals.cable.wires.M" + + sprintf(EvInstName "mbuf[%d][%d]" HopIdx BufIdx) + sprintf(OdInstName "mbuf[%d][%d]" HopIdx BufIdx+1) + + sprintf(WrInstName "wr[%d][%d]" HopIdx BufIdx) + + EvInst = dbFindAnyInstByName(CV EvInstName) + OdInst = dbFindAnyInstByName(CV OdInstName) + + when( EvInst != nil + + if( EvInst~>Segment == "H" + then + CurrSeg = "V" + else + CurrSeg = "H" + ) + + Metals = parseString(nth(2 nth(3 TempArray[BufIdx])) "M") + WrCellName = strcat(WrCellName cadr(Metals) car(Metals) CurrSeg "_0") + WrInst = dbCreateInstByMasterName(CV "globals.cable" WrCellName "layout" WrInstName EvInst~>xy EvInst~>orient) + WrInst~>Pitch = nth(2 TempArray[BufIdx]) + when( OdInst == nil + WrInst~>Odd_Channel = "FALSE" + ) + ) + WrInst + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; to be called only once all the MBUFs are placed on the cable guide. + +(defun PlaceSyncResetBufs ( @key (CableShape car(geGetSelectedSet())) (CV (UIGetCellView)) ) + let( ( Hops HopIdx BufInst BufInstName BufArray + StartDist StartLoc StartDistX HopDist LocatorOP Multiple + ResetBufInst ResetBufInstName ResetRampInst ResetRampInstName + CurrLoc CurrIdx CurrSeg CurrDir + ) + Hops = CableShape~>BufferHops + when( type(Hops) == "string" + Hops = evalstring(CableShape~>BufferHops) + ) + + StartDist = CableShape~>InputDistance_um + when( stringp(StartDist) + StartDist = evalstring(CableShape~>InputDistance_um) + ) + + StartDistX = round(StartDist/1.56)*1.56 + HopDist = round(300/3.12)*3.12 + StartLoc = nth(0 CableShape~>points) + BufArray = CBLCreateBufArray() + + for( HopIdx 0 Hops-1 + sprintf(BufInstName "mbuf[%d][%d]", HopIdx, BufArray[0]) + sprintf(ResetBufInstName "bufReset[%d]", HopIdx) + sprintf(ResetRampInstName "rampReset[%d]", HopIdx) + + if( HopIdx < Hops-1 + then + Multiple = 1 + else + Multiple = -1 + ) + + println("helo") + println(BufInstName) + println(ResetBufInstName) + + BufInst = dbFindAnyInstByName(CV BufInstName) + ResetBufInst = dbFindAnyInstByName(CV ResetBufInstName) + ResetRampInst = dbFindAnyInstByName(CV ResetRampInstName) + + LocatorOP = CBLLocateBuffer(CableShape BufInst~>CablePt 0 ?SearchMultiple Multiple ?BufType "RESET" ?CV CV) + CurrLoc = nth(0 LocatorOP) + CurrIdx = nth(1 LocatorOP) + CurrSeg = nth(2 LocatorOP) + CurrDir = nth(3 LocatorOP) + + case( CurrSeg + ( "H" + if( CurrDir == "P" + then + ResetBufInst~>orient = "MXR90" + ResetRampInst~>orient = "MXR90" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc) cadr(CurrLoc)+3.12) + ResetBufInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetRampInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "H" "Segment") + dbSet(ResetRampInst "H" "Segment") + else + ResetBufInst~>orient = "R90" + ResetRampInst~>orient = "R90" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc) cadr(CurrLoc)+3.12) + ResetBufInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetRampInst~>CablePt = list(car(CurrLoc) cadr(CurrLoc)+0.78) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "H" "Segment") + dbSet(ResetRampInst "H" "Segment") + ) + ) + ( "V" + if( CurrDir == "P" + then + ResetBufInst~>orient = "MXR90" + ResetRampInst~>orient = "MXR90" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc)+3.12 cadr(CurrLoc)) + ResetBufInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetRampInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "V" "Segment") + dbSet(ResetRampInst "V" "Segment") + else + ResetBufInst~>orient = "R270" + ResetRampInst~>orient = "R270" + ResetBufInst~>xy = CurrLoc + ResetRampInst~>xy = list(car(CurrLoc)+3.12 cadr(CurrLoc)) + ResetBufInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetRampInst~>CablePt = list(car(CurrLoc)+0.78 cadr(CurrLoc)) + ResetBufInst~>CableIdx = CurrIdx + ResetRampInst~>CableIdx = CurrIdx + dbSet(ResetBufInst "V" "Segment") + dbSet(ResetRampInst "V" "Segment") + ) + ) + ) + + ) + + t + ) +) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun RouteSyncBufReset (@optional (CableShape car(geGetSelectedSet())) (CV (UIGetCellView))) + let( ( BufResetPts BufToRampPts Hops + CurrInstName NextInstName CurrInst RampInstName RampInst NextInst ResNetName + StartPt EndPt + ) + + Hops = CableShape~>BufferHops + when( type(Hops) == "string" + Hops = evalstring(CableShape~>BufferHops) + ) + for( HopIdx 0 Hops-1 + when( HopIdx == 0 + sprintf(NextInstName "bufReset[%d]", HopIdx) + + NextInst = dbFindAnyInstByName(CV NextInstName) + + StartPt = nth(0 CableShape~>points) + EndPt = car(FindSyncResetPts(NextInst)) + + BufResetPts = TransformSyncCablePoints(CableShape StartPt EndPt 1 NextInst~>CableIdx 0 1.56) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal43))) "L_RESET" BufResetPts) + ) + when( HopIdx != Hops-1 + sprintf(CurrInstName "bufReset[%d]", HopIdx) + sprintf(NextInstName "bufReset[%d]", HopIdx+1) + + CurrInst = dbFindAnyInstByName(CV CurrInstName) + NextInst = dbFindAnyInstByName(CV NextInstName) + + StartPt = cadr(FindSyncResetPts(CurrInst)) + EndPt = car(FindSyncResetPts(NextInst)) + + BufResetPts = TransformSyncCablePoints(CableShape StartPt EndPt CurrInst~>CableIdx NextInst~>CableIdx 0 1.56) + sprintf(ResNetName "w_BufReset[%d]", HopIdx+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal43))) ResNetName BufResetPts) + ConnectSyncBufToRamp(CurrInst HopIdx) + ) + when( HopIdx == Hops-1 + sprintf(CurrInstName "bufReset[%d]", HopIdx) + + CurrInst = dbFindAnyInstByName(CV CurrInstName) + + StartPt = cadr(FindSyncResetPts(CurrInst)) + EndPt = nth(CableShape~>nPoints-1 CableShape~>points) + + BufResetPts = TransformSyncCablePoints(CableShape StartPt EndPt CurrInst~>CableIdx CableShape~>nPoints-1 0 1.56) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal43))) "R_RESET" BufResetPts) + ConnectSyncBufToRamp(CurrInst HopIdx) + ) + ) + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ConnectSyncBufToRamp ( BufResInst Hop ) + let( ( StartPt EndPt ResNetName ) + + case( BufResInst~>Segment + ( "H" + if( BufResInst~>orient == "R0" + then + StartPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)+2.34) + EndPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)+3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal32))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufResInst~>xy)-2.34 cadr(BufResInst~>xy)+2.34) + EndPt = list(car(BufResInst~>xy)-2.34 cadr(BufResInst~>xy)+3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal32))) ResNetName list(StartPt EndPt)) + ) + ) + ( "V" + if( BufResInst~>orient == "R0" + then + StartPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)+0.78) + EndPt = list(car(BufResInst~>xy)+3.90 cadr(BufResInst~>xy)+0.78) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal32))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufResInst~>xy)+2.34 cadr(BufResInst~>xy)-0.78) + EndPt = list(car(BufResInst~>xy)+3.90 cadr(BufResInst~>xy)-0.78) + sprintf(ResNetName "w_BufReset[%d]", Hop+1) + DrawChannel(nil DefChan(list(list( "" node_4W 0*TrackPitch BusMetal32))) ResNetName list(StartPt EndPt)) + ) + ) + ) + + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun RouteSyncRampReset (@optional (CableShape car(geGetSelectedSet())) (CV (UIGetCellView))) + let( ( RampResetPts Hops Bufs BufIdx RampInstName RampInst + FirstInstName LastInstName FirstInst LastInst ResNetName + StartPt EndPt HopIdx FirstIdx LastIdx EvInstName EvInst + ) + Hops = CableShape~>BufferHops + when( type(Hops) == "string" + Hops = evalstring(CableShape~>BufferHops) + ) + Bufs = evalstring(CableShape~>CableWidth) + BufArray = CBLCreateBufArray() + + if( Bufs <= CableBufferSplitIdx + then + FirstIdx = 0 + LastIdx = truncate((Bufs-1)/2)*2 + else + FirstIdx = CableBufferSplitIdx + LastIdx = truncate((CableBufferSplitIdx - 1)/2)*2 + ) + + println(LastIdx) + + for( HopIdx 0 Hops-1 + + sprintf(FirstInstName "mbuf[%d][%d]", HopIdx,FirstIdx) + sprintf(LastInstName "mbuf[%d][%d]", HopIdx,LastIdx) + FirstInst = dbFindAnyInstByName(CV FirstInstName) + LastInst = dbFindAnyInstByName(CV LastInstName) + sprintf(RampInstName "rampReset[%d]", HopIdx) + RampInst = dbFindAnyInstByName(CV RampInstName) + + + StartPt = cadr(FindResetPts(FirstInst)) + EndPt = car(FindResetPts(LastInst)) + + RampResetPts = TransformCablePoints(CableShape StartPt EndPt FirstInst~>CableIdx LastInst~>CableIdx -0.325 4.68) + sprintf(ResNetName "w_rampReset[%d]", HopIdx+1) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName RampResetPts) + + ConnectRampToMbuf(RampInst HopIdx) + + for( BufIdx 0 Bufs-1 + when( evenp(BufIdx) + sprintf(EvInstName "mbuf[%d][%d]", HopIdx,BufIdx) + EvInst = dbFindAnyInstByName(CV EvInstName) + ConnectEvenOddResets(EvInst HopIdx) + ) + ) + ) + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ConnectSyncEvenOddResets ( BufInst Hop ) + let( ( StartPt EndPt ResNetName ) + + case( BufInst~>Segment + ( "H" + if( BufInst~>orient == "R0" + then + StartPt = list(car(BufInst~>xy)+2.34 cadr(BufInst~>xy)+5.46) + EndPt = list(car(BufInst~>xy)+3.90 cadr(BufInst~>xy)+5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufInst~>xy)-2.34 cadr(BufInst~>xy)+5.46) + EndPt = list(car(BufInst~>xy)-3.90 cadr(BufInst~>xy)+5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ( "V" + if( BufInst~>orient == "R0" + then + StartPt = list(car(BufInst~>xy)+2.34 cadr(BufInst~>xy)+5.46) + EndPt = list(car(BufInst~>xy)+3.90 cadr(BufInst~>xy)+5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(BufInst~>xy)+2.34 cadr(BufInst~>xy)-5.46) + EndPt = list(car(BufInst~>xy)+3.90 cadr(BufInst~>xy)-5.46) + sprintf(ResNetName "w_rampReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ) + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ConnectSyncRampToMbuf ( RampResInst Hop ) + let( ( StartPt EndPt ResNetName ) + + case( RampResInst~>Segment + ( "H" + if( RampResInst~>orient == "R0" + then + StartPt = list(car(RampResInst~>xy)+2.34 cadr(RampResInst~>xy)+2.34) + EndPt = list(car(RampResInst~>xy)+3.90 cadr(RampResInst~>xy)+2.34) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(RampResInst~>xy)-2.34 cadr(RampResInst~>xy)+2.34) + EndPt = list(car(RampResInst~>xy)-3.90 cadr(RampResInst~>xy)+2.34) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ( "V" + if( RampResInst~>orient == "R0" + then + StartPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)+2.34) + EndPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)+3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + else + StartPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)-2.34) + EndPt = list(car(RampResInst~>xy)+0.455 cadr(RampResInst~>xy)-3.90) + sprintf(ResNetName "w_BufReset[%d]", Hop) + DrawChannel(nil DefChan(list(list( "" node_2W 0*TrackPitch BusMetal23))) ResNetName list(StartPt EndPt)) + ) + ) + ) + + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun FindSyncResetPts ( Inst ) + let( ( StartPt EndPt ) + + case( car(parseString(Inst~>name "[")) + + ( "bufReset" + case( Inst~>Segment + ( "H" + case( Inst~>orient + ( "MXR90" + StartPt = list(car(Inst~>CablePt)+0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)+2.34 cadr(Inst~>CablePt)) + ) + ( "R90" + StartPt = list(car(Inst~>CablePt)-0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)-2.34 cadr(Inst~>CablePt)) + ) + ) + ) + ( "V" + case( Inst~>orient + ( "MXR90" + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+2.34) + ) + ( "R270" + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-2.34) + ) + ) + ) + ) + ) + + ( "rampReset" + case( Inst~>Segment + ( "H" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt)+0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)+2.34 cadr(Inst~>CablePt)) + else + StartPt = list(car(Inst~>CablePt)-0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)-2.34 cadr(Inst~>CablePt)) + ) + ) + ( "V" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+2.34) + else + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-2.34) + ) + ) + ) + ) + + ( "mbuf" + case( Inst~>Segment + ( "H" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt)+0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)+2.34 cadr(Inst~>CablePt)) + else + StartPt = list(car(Inst~>CablePt)-0.78 cadr(Inst~>CablePt)) + EndPt = list(car(Inst~>CablePt)-2.34 cadr(Inst~>CablePt)) + ) + ) + ( "V" + if( Inst~>orient == "R0" + then + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)+5.46) + else + StartPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-0.78) + EndPt = list(car(Inst~>CablePt) cadr(Inst~>CablePt)-5.46) + ) + ) + ) + ) + + ) + +list(StartPt EndPt) + ) +) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun TransformSyncCablePoints (CableShape StartPt EndPt StartIdx EndIdx HOffset VOffset) + let( ( OutPts NOutPts CablePt I ) + + NOutPts = EndIdx - StartIdx + 2 + + for( I 0 NOutPts-1 + println(I) + when( I == 0 + if( CBLCurrSegment(CableShape StartIdx) == "H" + then + OutPts = list(list(car(StartPt) cadr(StartPt)+VOffset)) + else + OutPts = list(list(car(StartPt)+HOffset cadr(StartPt))) + ) + ) + + when( I != 0 && I != NOutPts-1 + CablePt = nth((StartIdx + I - 1) CableShape~>points) + OutPts = append(OutPts list(list(car(CablePt)+HOffset cadr(CablePt)+VOffset))) + ) + + when( I == NOutPts-1 + if( CBLCurrSegment(CableShape EndIdx) == "H" + then + OutPts = append(OutPts list(list(car(EndPt) cadr(EndPt)+VOffset))) + else + OutPts = append(OutPts list(list(car(EndPt)+HOffset cadr(EndPt)))) + ) + ) + + ) + + OutPts + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/templates.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/templates.il new file mode 100644 index 0000000000..c328ab730c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/templates.il @@ -0,0 +1,539 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/templates.il#1 $ +; $DateTime: 2012/07/27 17:24:08 $ +; $Author: pankala $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defvar CableBufferSplitIdx 12) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLCreateTempArray (Template) + let( ( + TempArray + ) + + declare(TempArray[61]) + + case( Template + + ( "Template_DENSE" + TempArray[0] = list( "[0]" inlv_e1of4_A 0*TrackPitch BusMetal45) + TempArray[1] = list( "[1]" inlv_e1of4_B 0*TrackPitch BusMetal45) + TempArray[2] = list( "[2]" inlv_e1of4_A 3*TrackPitch BusMetal45) + TempArray[3] = list( "[3]" inlv_e1of4_B 3*TrackPitch BusMetal45) + + TempArray[4] = list( "[4]" inlv_e1of4_A 0*TrackPitch BusMetal67) + TempArray[5] = list( "[5]" inlv_e1of4_B 0*TrackPitch BusMetal67) + TempArray[6] = list( "[6]" inlv_e1of4_A 1*TrackPitch BusMetal67) + TempArray[7] = list( "[7]" inlv_e1of4_B 1*TrackPitch BusMetal67) + TempArray[8] = list( "[8]" inlv_e1of4_A 2*TrackPitch BusMetal67) + TempArray[9] = list( "[9]" inlv_e1of4_B 2*TrackPitch BusMetal67) + TempArray[10] = list( "[10]" inlv_e1of4_A 3*TrackPitch BusMetal67) + TempArray[11] = list( "[11]" inlv_e1of4_B 3*TrackPitch BusMetal67) + + TempArray[12] = list( "[12]" inlv_e1of4_A 4*TrackPitch BusMetal23) + TempArray[13] = list( "[13]" inlv_e1of4_B 4*TrackPitch BusMetal23) + TempArray[14] = list( "[14]" inlv_e1of4_A 4*TrackPitch BusMetal45) + TempArray[15] = list( "[15]" inlv_e1of4_B 4*TrackPitch BusMetal45) + TempArray[16] = list( "[16]" inlv_e1of4_A 4*TrackPitch BusMetal67) + TempArray[17] = list( "[17]" inlv_e1of4_B 4*TrackPitch BusMetal67) + + TempArray[18] = list( "[18]" inlv_e1of4_A 5*TrackPitch BusMetal23) + TempArray[19] = list( "[19]" inlv_e1of4_B 5*TrackPitch BusMetal23) + TempArray[20] = list( "[20]" inlv_e1of4_A 5*TrackPitch BusMetal45) + TempArray[21] = list( "[21]" inlv_e1of4_B 5*TrackPitch BusMetal45) + TempArray[22] = list( "[22]" inlv_e1of4_A 5*TrackPitch BusMetal67) + TempArray[23] = list( "[23]" inlv_e1of4_B 5*TrackPitch BusMetal67) + + TempArray[24] = list( "[24]" inlv_e1of4_A 6*TrackPitch BusMetal23) + TempArray[25] = list( "[25]" inlv_e1of4_B 6*TrackPitch BusMetal23) + TempArray[26] = list( "[26]" inlv_e1of4_A 6*TrackPitch BusMetal45) + TempArray[27] = list( "[27]" inlv_e1of4_B 6*TrackPitch BusMetal45) + TempArray[28] = list( "[28]" inlv_e1of4_A 6*TrackPitch BusMetal67) + TempArray[29] = list( "[29]" inlv_e1of4_B 6*TrackPitch BusMetal67) + + TempArray[30] = list( "[30]" inlv_e1of4_A 7*TrackPitch BusMetal23) + TempArray[31] = list( "[31]" inlv_e1of4_B 7*TrackPitch BusMetal23) + TempArray[32] = list( "[32]" inlv_e1of4_A 7*TrackPitch BusMetal45) + TempArray[33] = list( "[33]" inlv_e1of4_B 7*TrackPitch BusMetal45) + TempArray[34] = list( "[34]" inlv_e1of4_A 7*TrackPitch BusMetal67) + TempArray[35] = list( "[35]" inlv_e1of4_B 7*TrackPitch BusMetal67) + + TempArray[36] = list( "[36]" inlv_e1of4_A 8*TrackPitch BusMetal23) + TempArray[37] = list( "[37]" inlv_e1of4_B 8*TrackPitch BusMetal23) + TempArray[38] = list( "[38]" inlv_e1of4_A 8*TrackPitch BusMetal45) + TempArray[39] = list( "[39]" inlv_e1of4_B 8*TrackPitch BusMetal45) + TempArray[40] = list( "[40]" inlv_e1of4_A 8*TrackPitch BusMetal67) + TempArray[41] = list( "[41]" inlv_e1of4_B 8*TrackPitch BusMetal67) + + TempArray[42] = list( "[42]" inlv_e1of4_A 9*TrackPitch BusMetal23) + TempArray[43] = list( "[43]" inlv_e1of4_B 9*TrackPitch BusMetal23) + TempArray[44] = list( "[44]" inlv_e1of4_A 9*TrackPitch BusMetal45) + TempArray[45] = list( "[45]" inlv_e1of4_B 9*TrackPitch BusMetal45) + TempArray[46] = list( "[46]" inlv_e1of4_A 9*TrackPitch BusMetal67) + TempArray[47] = list( "[47]" inlv_e1of4_B 9*TrackPitch BusMetal67) + + TempArray[48] = list( "[48]" inlv_e1of4_A 10*TrackPitch BusMetal23) + TempArray[49] = list( "[49]" inlv_e1of4_B 10*TrackPitch BusMetal23) + TempArray[50] = list( "[50]" inlv_e1of4_A 10*TrackPitch BusMetal45) + TempArray[51] = list( "[51]" inlv_e1of4_B 10*TrackPitch BusMetal45) + TempArray[52] = list( "[52]" inlv_e1of4_A 10*TrackPitch BusMetal67) + TempArray[53] = list( "[53]" inlv_e1of4_B 10*TrackPitch BusMetal67) + + TempArray[54] = list( "[54]" inlv_e1of4_A 11*TrackPitch BusMetal23) + TempArray[55] = list( "[55]" inlv_e1of4_B 11*TrackPitch BusMetal23) + TempArray[56] = list( "[56]" inlv_e1of4_A 11*TrackPitch BusMetal45) + TempArray[57] = list( "[57]" inlv_e1of4_B 11*TrackPitch BusMetal45) + TempArray[58] = list( "[58]" inlv_e1of4_A 11*TrackPitch BusMetal67) + TempArray[59] = list( "[59]" inlv_e1of4_B 11*TrackPitch BusMetal67) + ) + + ( "Template_DENSE_R90" + TempArray[0] = list( "[0]" inlv_e1of4_A 0*TrackPitch BusMetal54) + TempArray[1] = list( "[1]" inlv_e1of4_B 0*TrackPitch BusMetal54) + TempArray[2] = list( "[2]" inlv_e1of4_A 3*TrackPitch BusMetal54) + TempArray[3] = list( "[3]" inlv_e1of4_B 3*TrackPitch BusMetal54) + + TempArray[4] = list( "[4]" inlv_e1of4_A 0*TrackPitch BusMetal76) + TempArray[5] = list( "[5]" inlv_e1of4_B 0*TrackPitch BusMetal76) + TempArray[6] = list( "[6]" inlv_e1of4_A 1*TrackPitch BusMetal76) + TempArray[7] = list( "[7]" inlv_e1of4_B 1*TrackPitch BusMetal76) + TempArray[8] = list( "[8]" inlv_e1of4_A 2*TrackPitch BusMetal76) + TempArray[9] = list( "[9]" inlv_e1of4_B 2*TrackPitch BusMetal76) + TempArray[10] = list( "[10]" inlv_e1of4_A 3*TrackPitch BusMetal76) + TempArray[11] = list( "[11]" inlv_e1of4_B 3*TrackPitch BusMetal76) + + TempArray[12] = list( "[12]" inlv_e1of4_A 4*TrackPitch BusMetal32) + TempArray[13] = list( "[13]" inlv_e1of4_B 4*TrackPitch BusMetal32) + TempArray[14] = list( "[14]" inlv_e1of4_A 4*TrackPitch BusMetal54) + TempArray[15] = list( "[15]" inlv_e1of4_B 4*TrackPitch BusMetal54) + TempArray[16] = list( "[16]" inlv_e1of4_A 4*TrackPitch BusMetal76) + TempArray[17] = list( "[17]" inlv_e1of4_B 4*TrackPitch BusMetal76) + + TempArray[18] = list( "[18]" inlv_e1of4_A 5*TrackPitch BusMetal32) + TempArray[19] = list( "[19]" inlv_e1of4_B 5*TrackPitch BusMetal32) + TempArray[20] = list( "[20]" inlv_e1of4_A 5*TrackPitch BusMetal54) + TempArray[21] = list( "[21]" inlv_e1of4_B 5*TrackPitch BusMetal54) + TempArray[22] = list( "[22]" inlv_e1of4_A 5*TrackPitch BusMetal76) + TempArray[23] = list( "[23]" inlv_e1of4_B 5*TrackPitch BusMetal76) + + TempArray[24] = list( "[24]" inlv_e1of4_A 6*TrackPitch BusMetal32) + TempArray[25] = list( "[25]" inlv_e1of4_B 6*TrackPitch BusMetal32) + TempArray[26] = list( "[26]" inlv_e1of4_A 6*TrackPitch BusMetal54) + TempArray[27] = list( "[27]" inlv_e1of4_B 6*TrackPitch BusMetal54) + TempArray[28] = list( "[28]" inlv_e1of4_A 6*TrackPitch BusMetal76) + TempArray[29] = list( "[29]" inlv_e1of4_B 6*TrackPitch BusMetal76) + + TempArray[30] = list( "[30]" inlv_e1of4_A 7*TrackPitch BusMetal32) + TempArray[31] = list( "[31]" inlv_e1of4_B 7*TrackPitch BusMetal32) + TempArray[32] = list( "[32]" inlv_e1of4_A 7*TrackPitch BusMetal54) + TempArray[33] = list( "[33]" inlv_e1of4_B 7*TrackPitch BusMetal54) + TempArray[34] = list( "[34]" inlv_e1of4_A 7*TrackPitch BusMetal76) + TempArray[35] = list( "[35]" inlv_e1of4_B 7*TrackPitch BusMetal76) + + TempArray[36] = list( "[36]" inlv_e1of4_A 8*TrackPitch BusMetal32) + TempArray[37] = list( "[37]" inlv_e1of4_B 8*TrackPitch BusMetal32) + TempArray[38] = list( "[38]" inlv_e1of4_A 8*TrackPitch BusMetal54) + TempArray[39] = list( "[39]" inlv_e1of4_B 8*TrackPitch BusMetal54) + TempArray[40] = list( "[40]" inlv_e1of4_A 8*TrackPitch BusMetal76) + TempArray[41] = list( "[41]" inlv_e1of4_B 8*TrackPitch BusMetal76) + + TempArray[42] = list( "[42]" inlv_e1of4_A 9*TrackPitch BusMetal32) + TempArray[43] = list( "[43]" inlv_e1of4_B 9*TrackPitch BusMetal32) + TempArray[44] = list( "[44]" inlv_e1of4_A 9*TrackPitch BusMetal54) + TempArray[45] = list( "[45]" inlv_e1of4_B 9*TrackPitch BusMetal54) + TempArray[46] = list( "[46]" inlv_e1of4_A 9*TrackPitch BusMetal76) + TempArray[47] = list( "[47]" inlv_e1of4_B 9*TrackPitch BusMetal76) + + TempArray[48] = list( "[48]" inlv_e1of4_A 10*TrackPitch BusMetal32) + TempArray[49] = list( "[49]" inlv_e1of4_B 10*TrackPitch BusMetal32) + TempArray[50] = list( "[50]" inlv_e1of4_A 10*TrackPitch BusMetal54) + TempArray[51] = list( "[51]" inlv_e1of4_B 10*TrackPitch BusMetal54) + TempArray[52] = list( "[52]" inlv_e1of4_A 10*TrackPitch BusMetal76) + TempArray[53] = list( "[53]" inlv_e1of4_B 10*TrackPitch BusMetal76) + + TempArray[54] = list( "[54]" inlv_e1of4_A 11*TrackPitch BusMetal32) + TempArray[55] = list( "[55]" inlv_e1of4_B 11*TrackPitch BusMetal32) + TempArray[56] = list( "[56]" inlv_e1of4_A 11*TrackPitch BusMetal54) + TempArray[57] = list( "[57]" inlv_e1of4_B 11*TrackPitch BusMetal54) + TempArray[58] = list( "[58]" inlv_e1of4_A 11*TrackPitch BusMetal76) + TempArray[59] = list( "[59]" inlv_e1of4_B 11*TrackPitch BusMetal76) + ) + + ( "Template_TS" + TempArray[0] = list( "[0]" ts_e1of4 0*TrackPitch BusMetal45 ) + TempArray[1] = list( "[1]" ts_e1of4 1*TrackPitch BusMetal45 ) + TempArray[2] = list( "[2]" ts_e1of4 3*TrackPitch BusMetal45 ) + + TempArray[3] = list( "[3]" ts_e1of4 0*TrackPitch BusMetal67 ) + TempArray[4] = list( "[4]" ts_e1of4 1*TrackPitch BusMetal67 ) + TempArray[5] = list( "[5]" ts_e1of4 2*TrackPitch BusMetal67 ) + TempArray[6] = list( "[6]" ts_e1of4 3*TrackPitch BusMetal67 ) + + TempArray[7] = list( "[7]" ts_e1of4 4*TrackPitch BusMetal45 ) + TempArray[8] = list( "[8]" ts_e1of4 4*TrackPitch BusMetal67 ) + + TempArray[9] = list( "[9]" ts_e1of4 5*TrackPitch BusMetal23 ) + TempArray[10] = list( "[10]" ts_e1of4 5*TrackPitch BusMetal45 ) + TempArray[11] = list( "[11]" ts_e1of4 5*TrackPitch BusMetal67 ) + + TempArray[12] = list( "[12]" ts_e1of4 6*TrackPitch BusMetal23 ) + TempArray[13] = list( "[13]" ts_e1of4 6*TrackPitch BusMetal45 ) + TempArray[14] = list( "[14]" ts_e1of4 6*TrackPitch BusMetal67 ) + + TempArray[15] = list( "[15]" ts_e1of4 7*TrackPitch BusMetal23 ) + TempArray[16] = list( "[16]" ts_e1of4 7*TrackPitch BusMetal45 ) + TempArray[17] = list( "[17]" ts_e1of4 7*TrackPitch BusMetal67 ) + + TempArray[18] = list( "[18]" ts_e1of4 8*TrackPitch BusMetal23 ) + TempArray[19] = list( "[19]" ts_e1of4 8*TrackPitch BusMetal45 ) + TempArray[20] = list( "[20]" ts_e1of4 8*TrackPitch BusMetal67 ) + + TempArray[21] = list( "[21]" ts_e1of4 9*TrackPitch BusMetal23 ) + TempArray[22] = list( "[22]" ts_e1of4 9*TrackPitch BusMetal45 ) + TempArray[23] = list( "[23]" ts_e1of4 9*TrackPitch BusMetal67 ) + + TempArray[24] = list( "[24]" ts_e1of4 10*TrackPitch BusMetal23 ) + TempArray[25] = list( "[25]" ts_e1of4 10*TrackPitch BusMetal45 ) + TempArray[26] = list( "[26]" ts_e1of4 10*TrackPitch BusMetal67 ) + + TempArray[27] = list( "[27]" ts_e1of4 11*TrackPitch BusMetal23 ) + TempArray[28] = list( "[28]" ts_e1of4 11*TrackPitch BusMetal45 ) + TempArray[29] = list( "[29]" ts_e1of4 11*TrackPitch BusMetal67 ) + ) + + ( "Template_TS_R90" + TempArray[0] = list( "[0]" ts_e1of4 0*TrackPitch BusMetal54 ) + TempArray[1] = list( "[1]" ts_e1of4 1*TrackPitch BusMetal54 ) + TempArray[2] = list( "[2]" ts_e1of4 3*TrackPitch BusMetal54 ) + + TempArray[3] = list( "[3]" ts_e1of4 0*TrackPitch BusMetal76 ) + TempArray[4] = list( "[4]" ts_e1of4 1*TrackPitch BusMetal76 ) + TempArray[5] = list( "[5]" ts_e1of4 2*TrackPitch BusMetal76 ) + TempArray[6] = list( "[6]" ts_e1of4 3*TrackPitch BusMetal76 ) + + TempArray[7] = list( "[7]" ts_e1of4 4*TrackPitch BusMetal54 ) + TempArray[8] = list( "[8]" ts_e1of4 4*TrackPitch BusMetal76 ) + + TempArray[9] = list( "[9]" ts_e1of4 5*TrackPitch BusMetal32 ) + TempArray[10] = list( "[10]" ts_e1of4 5*TrackPitch BusMetal54 ) + TempArray[11] = list( "[11]" ts_e1of4 5*TrackPitch BusMetal76 ) + + TempArray[12] = list( "[12]" ts_e1of4 6*TrackPitch BusMetal32 ) + TempArray[13] = list( "[13]" ts_e1of4 6*TrackPitch BusMetal54 ) + TempArray[14] = list( "[14]" ts_e1of4 6*TrackPitch BusMetal76 ) + + TempArray[15] = list( "[15]" ts_e1of4 7*TrackPitch BusMetal32 ) + TempArray[16] = list( "[16]" ts_e1of4 7*TrackPitch BusMetal54 ) + TempArray[17] = list( "[17]" ts_e1of4 7*TrackPitch BusMetal76 ) + + TempArray[18] = list( "[18]" ts_e1of4 8*TrackPitch BusMetal32 ) + TempArray[19] = list( "[19]" ts_e1of4 8*TrackPitch BusMetal54 ) + TempArray[20] = list( "[20]" ts_e1of4 8*TrackPitch BusMetal76 ) + + TempArray[21] = list( "[21]" ts_e1of4 9*TrackPitch BusMetal32 ) + TempArray[22] = list( "[22]" ts_e1of4 9*TrackPitch BusMetal54 ) + TempArray[23] = list( "[23]" ts_e1of4 9*TrackPitch BusMetal76 ) + + TempArray[24] = list( "[24]" ts_e1of4 10*TrackPitch BusMetal32 ) + TempArray[25] = list( "[25]" ts_e1of4 10*TrackPitch BusMetal54 ) + TempArray[26] = list( "[26]" ts_e1of4 10*TrackPitch BusMetal76 ) + + TempArray[27] = list( "[27]" ts_e1of4 11*TrackPitch BusMetal32 ) + TempArray[28] = list( "[28]" ts_e1of4 11*TrackPitch BusMetal54 ) + TempArray[29] = list( "[29]" ts_e1of4 11*TrackPitch BusMetal76 ) + ) + + ( "Template_NYB" + TempArray[0] = list( "[0]" nyb_e1of4 0*TrackPitch BusMetal45 ) + TempArray[1] = list( "[1]" nyb_e1of4 1*TrackPitch BusMetal45 ) + + TempArray[2] = list( "[2]" nyb_e1of4 0*TrackPitch BusMetal67 ) + TempArray[3] = list( "[3]" nyb_e1of4 1*TrackPitch BusMetal67 ) + TempArray[4] = list( "[4]" nyb_e1of4 2*TrackPitch BusMetal67 ) + TempArray[5] = list( "[5]" nyb_e1of4 3*TrackPitch BusMetal67 ) + + TempArray[6] = list( "[6]" nyb_e1of4 4*TrackPitch BusMetal23 ) + TempArray[7] = list( "[7]" nyb_e1of4 4*TrackPitch BusMetal45 ) + TempArray[8] = list( "[8]" nyb_e1of4 4*TrackPitch BusMetal67 ) + + TempArray[9] = list( "[9]" nyb_e1of4 5*TrackPitch BusMetal23 ) + TempArray[10] = list( "[10]" nyb_e1of4 5*TrackPitch BusMetal45 ) + TempArray[11] = list( "[11]" nyb_e1of4 5*TrackPitch BusMetal67 ) + + TempArray[12] = list( "[12]" nyb_e1of4 6*TrackPitch BusMetal23 ) + TempArray[13] = list( "[13]" nyb_e1of4 6*TrackPitch BusMetal45 ) + TempArray[14] = list( "[14]" nyb_e1of4 6*TrackPitch BusMetal67 ) + + TempArray[15] = list( "[15]" nyb_e1of4 7*TrackPitch BusMetal23 ) + TempArray[16] = list( "[16]" nyb_e1of4 7*TrackPitch BusMetal45 ) + TempArray[17] = list( "[17]" nyb_e1of4 7*TrackPitch BusMetal67 ) + + TempArray[18] = list( "[18]" nyb_e1of4 8*TrackPitch BusMetal23 ) + TempArray[19] = list( "[19]" nyb_e1of4 8*TrackPitch BusMetal45 ) + TempArray[20] = list( "[20]" nyb_e1of4 8*TrackPitch BusMetal67 ) + + TempArray[21] = list( "[21]" nyb_e1of4 9*TrackPitch BusMetal23 ) + TempArray[22] = list( "[22]" nyb_e1of4 9*TrackPitch BusMetal45 ) + TempArray[23] = list( "[23]" nyb_e1of4 9*TrackPitch BusMetal67 ) + + TempArray[24] = list( "[24]" nyb_e1of4 10*TrackPitch BusMetal23 ) + TempArray[25] = list( "[25]" nyb_e1of4 10*TrackPitch BusMetal45 ) + TempArray[26] = list( "[26]" nyb_e1of4 10*TrackPitch BusMetal67 ) + + TempArray[27] = list( "[27]" nyb_e1of4 11*TrackPitch BusMetal23 ) + TempArray[28] = list( "[28]" nyb_e1of4 11*TrackPitch BusMetal45 ) + TempArray[29] = list( "[29]" nyb_e1of4 11*TrackPitch BusMetal67 ) + ) + + ( "Template_NYB_R90" + TempArray[0] = list( "[0]" nyb_e1of4 0*TrackPitch BusMetal54 ) + TempArray[1] = list( "[1]" nyb_e1of4 1*TrackPitch BusMetal54 ) + + TempArray[2] = list( "[2]" nyb_e1of4 0*TrackPitch BusMetal76 ) + TempArray[3] = list( "[3]" nyb_e1of4 1*TrackPitch BusMetal76 ) + TempArray[4] = list( "[4]" nyb_e1of4 2*TrackPitch BusMetal76 ) + TempArray[5] = list( "[5]" nyb_e1of4 3*TrackPitch BusMetal76 ) + + TempArray[6] = list( "[6]" nyb_e1of4 4*TrackPitch BusMetal32 ) + TempArray[7] = list( "[7]" nyb_e1of4 4*TrackPitch BusMetal54 ) + TempArray[8] = list( "[8]" nyb_e1of4 4*TrackPitch BusMetal76 ) + + TempArray[9] = list( "[9]" nyb_e1of4 5*TrackPitch BusMetal32 ) + TempArray[10] = list( "[10]" nyb_e1of4 5*TrackPitch BusMetal54 ) + TempArray[11] = list( "[11]" nyb_e1of4 5*TrackPitch BusMetal76 ) + + TempArray[12] = list( "[12]" nyb_e1of4 6*TrackPitch BusMetal32 ) + TempArray[13] = list( "[13]" nyb_e1of4 6*TrackPitch BusMetal54 ) + TempArray[14] = list( "[14]" nyb_e1of4 6*TrackPitch BusMetal76 ) + + TempArray[15] = list( "[15]" nyb_e1of4 7*TrackPitch BusMetal32 ) + TempArray[16] = list( "[16]" nyb_e1of4 7*TrackPitch BusMetal54 ) + TempArray[17] = list( "[17]" nyb_e1of4 7*TrackPitch BusMetal76 ) + + TempArray[18] = list( "[18]" nyb_e1of4 8*TrackPitch BusMetal32 ) + TempArray[19] = list( "[19]" nyb_e1of4 8*TrackPitch BusMetal54 ) + TempArray[20] = list( "[20]" nyb_e1of4 8*TrackPitch BusMetal76 ) + + TempArray[21] = list( "[21]" nyb_e1of4 9*TrackPitch BusMetal32 ) + TempArray[22] = list( "[22]" nyb_e1of4 9*TrackPitch BusMetal54 ) + TempArray[23] = list( "[23]" nyb_e1of4 9*TrackPitch BusMetal76 ) + + TempArray[24] = list( "[24]" nyb_e1of4 10*TrackPitch BusMetal32 ) + TempArray[25] = list( "[25]" nyb_e1of4 10*TrackPitch BusMetal54 ) + TempArray[26] = list( "[26]" nyb_e1of4 10*TrackPitch BusMetal76 ) + + TempArray[27] = list( "[27]" nyb_e1of4 11*TrackPitch BusMetal32 ) + TempArray[28] = list( "[28]" nyb_e1of4 11*TrackPitch BusMetal54 ) + TempArray[29] = list( "[29]" nyb_e1of4 11*TrackPitch BusMetal76 ) + ) + + + ( "Template_NODES" + TempArray[0] = list( "[0]" node_1W -DefaultWiringPitch*4.5 BusMetal76) + TempArray[1] = list( "[1]" node_1W -DefaultWiringPitch*3.5 BusMetal76) + TempArray[2] = list( "[2]" node_1W -DefaultWiringPitch*2.5 BusMetal76) + TempArray[3] = list( "[3]" node_1W -DefaultWiringPitch*1.5 BusMetal76) + TempArray[4] = list( "[4]" node_1W -DefaultWiringPitch*0.5 BusMetal76) + TempArray[5] = list( "[5]" node_1W DefaultWiringPitch*0.5 BusMetal76) + TempArray[6] = list( "[6]" node_1W DefaultWiringPitch*1.5 BusMetal76) + TempArray[7] = list( "[7]" node_1W DefaultWiringPitch*2.5 BusMetal76) + TempArray[8] = list( "[8]" node_1W DefaultWiringPitch*3.5 BusMetal76) + TempArray[9] = list( "[9]" node_1W DefaultWiringPitch*4.5 BusMetal76) + TempArray[10] = list( "[10]" node_1W -DefaultWiringPitch*7.5 BusMetal32) + TempArray[11] = list( "[11]" node_1W -DefaultWiringPitch*8.5 BusMetal32) + TempArray[12] = list( "[12]" node_1W -DefaultWiringPitch*9.5 BusMetal32) + TempArray[13] = list( "[13]" node_1W -DefaultWiringPitch*10.5 BusMetal32) + TempArray[14] = list( "[14]" node_1W -DefaultWiringPitch*11.5 BusMetal32) + TempArray[15] = list( "[15]" node_1W DefaultWiringPitch*12.5 BusMetal32) + TempArray[16] = list( "[16]" node_1W DefaultWiringPitch*13.5 BusMetal32) + TempArray[17] = list( "[17]" node_1W DefaultWiringPitch*14.5 BusMetal32) + TempArray[18] = list( "[18]" node_1W DefaultWiringPitch*15.5 BusMetal32) + TempArray[19] = list( "[19]" node_1W DefaultWiringPitch*16.5 BusMetal32) + TempArray[20] = list( "[20]" node_1W DefaultWiringPitch*7.5 BusMetal54) + TempArray[21] = list( "[21]" node_1W DefaultWiringPitch*8.5 BusMetal54) + TempArray[22] = list( "[22]" node_1W DefaultWiringPitch*9.5 BusMetal54) + TempArray[23] = list( "[23]" node_1W DefaultWiringPitch*10.5 BusMetal54) + TempArray[24] = list( "[24]" node_1W DefaultWiringPitch*11.5 BusMetal54) + TempArray[25] = list( "[25]" node_1W DefaultWiringPitch*12.5 BusMetal54) + TempArray[26] = list( "[26]" node_1W DefaultWiringPitch*13.5 BusMetal54) + TempArray[27] = list( "[27]" node_1W DefaultWiringPitch*14.5 BusMetal54) + TempArray[28] = list( "[28]" node_1W DefaultWiringPitch*15.5 BusMetal54) + TempArray[29] = list( "[29]" node_1W DefaultWiringPitch*16.5 BusMetal54) + TempArray[30] = list( "[30]" node_1W DefaultWiringPitch*7.5 BusMetal76) + TempArray[31] = list( "[31]" node_1W DefaultWiringPitch*8.5 BusMetal76) + TempArray[32] = list( "[32]" node_1W DefaultWiringPitch*9.5 BusMetal76) + TempArray[33] = list( "[33]" node_1W DefaultWiringPitch*10.5 BusMetal76) + TempArray[34] = list( "[34]" node_1W DefaultWiringPitch*11.5 BusMetal76) + TempArray[35] = list( "[35]" node_1W DefaultWiringPitch*12.5 BusMetal76) + TempArray[36] = list( "[36]" node_1W DefaultWiringPitch*13.5 BusMetal76) + TempArray[37] = list( "[37]" node_1W DefaultWiringPitch*14.5 BusMetal76) + TempArray[38] = list( "[38]" node_1W DefaultWiringPitch*15.5 BusMetal76) + TempArray[39] = list( "[39]" node_1W DefaultWiringPitch*16.5 BusMetal76) + TempArray[40] = list( "[40]" node_1W DefaultWiringPitch*19.5 BusMetal32) + TempArray[41] = list( "[41]" node_1W DefaultWiringPitch*20.5 BusMetal32) + TempArray[42] = list( "[42]" node_1W DefaultWiringPitch*21.5 BusMetal32) + TempArray[43] = list( "[43]" node_1W DefaultWiringPitch*22.5 BusMetal32) + TempArray[44] = list( "[44]" node_1W DefaultWiringPitch*23.5 BusMetal32) + TempArray[45] = list( "[45]" node_1W DefaultWiringPitch*24.5 BusMetal32) + TempArray[46] = list( "[46]" node_1W DefaultWiringPitch*25.5 BusMetal32) + TempArray[47] = list( "[47]" node_1W DefaultWiringPitch*26.5 BusMetal32) + TempArray[48] = list( "[48]" node_1W DefaultWiringPitch*27.5 BusMetal32) + TempArray[49] = list( "[49]" node_1W DefaultWiringPitch*28.5 BusMetal32) + TempArray[50] = list( "[50]" node_1W DefaultWiringPitch*19.5 BusMetal54) + TempArray[51] = list( "[51]" node_1W DefaultWiringPitch*20.5 BusMetal54) + TempArray[52] = list( "[52]" node_1W DefaultWiringPitch*21.5 BusMetal54) + TempArray[53] = list( "[53]" node_1W DefaultWiringPitch*22.5 BusMetal54) + TempArray[54] = list( "[54]" node_1W DefaultWiringPitch*23.5 BusMetal54) + TempArray[55] = list( "[55]" node_1W DefaultWiringPitch*24.5 BusMetal54) + TempArray[56] = list( "[56]" node_1W DefaultWiringPitch*25.5 BusMetal54) + TempArray[57] = list( "[57]" node_1W DefaultWiringPitch*26.5 BusMetal54) + TempArray[58] = list( "[58]" node_1W DefaultWiringPitch*27.5 BusMetal54) + TempArray[59] = list( "[59]" node_1W DefaultWiringPitch*28.5 BusMetal54) + TempArray[60] = list( "[60]" node_1W DefaultWiringPitch*19.5 BusMetal76) + TempArray[61] = list( "[61]" node_1W DefaultWiringPitch*20.5 BusMetal76) + TempArray[62] = list( "[62]" node_1W DefaultWiringPitch*21.5 BusMetal76) + TempArray[63] = list( "[63]" node_1W DefaultWiringPitch*22.5 BusMetal76) + TempArray[64] = list( "[64]" node_1W DefaultWiringPitch*23.5 BusMetal76) + TempArray[65] = list( "[65]" node_1W DefaultWiringPitch*24.5 BusMetal76) + TempArray[66] = list( "[66]" node_1W DefaultWiringPitch*25.5 BusMetal76) + TempArray[67] = list( "[67]" node_1W DefaultWiringPitch*26.5 BusMetal76) + TempArray[68] = list( "[68]" node_1W DefaultWiringPitch*27.5 BusMetal76) + TempArray[69] = list( "[69]" node_1W DefaultWiringPitch*28.5 BusMetal76) + TempArray[70] = list( "[70]" node_1W DefaultWiringPitch*31.5 BusMetal32) + TempArray[71] = list( "[71]" node_1W DefaultWiringPitch*32.5 BusMetal32) + TempArray[72] = list( "[72]" node_1W DefaultWiringPitch*33.5 BusMetal32) + TempArray[73] = list( "[73]" node_1W DefaultWiringPitch*34.5 BusMetal32) + TempArray[74] = list( "[74]" node_1W DefaultWiringPitch*35.5 BusMetal32) + TempArray[75] = list( "[75]" node_1W DefaultWiringPitch*36.5 BusMetal32) + TempArray[76] = list( "[76]" node_1W DefaultWiringPitch*37.5 BusMetal32) + TempArray[77] = list( "[77]" node_1W DefaultWiringPitch*38.5 BusMetal32) + TempArray[78] = list( "[78]" node_1W DefaultWiringPitch*39.5 BusMetal32) + TempArray[79] = list( "[79]" node_1W DefaultWiringPitch*40.5 BusMetal32) + TempArray[80] = list( "[80]" node_1W DefaultWiringPitch*31.5 BusMetal54) + TempArray[81] = list( "[81]" node_1W DefaultWiringPitch*32.5 BusMetal54) + TempArray[82] = list( "[82]" node_1W DefaultWiringPitch*33.5 BusMetal54) + TempArray[83] = list( "[83]" node_1W DefaultWiringPitch*34.5 BusMetal54) + TempArray[84] = list( "[84]" node_1W DefaultWiringPitch*35.5 BusMetal54) + TempArray[85] = list( "[85]" node_1W DefaultWiringPitch*36.5 BusMetal54) + TempArray[86] = list( "[86]" node_1W DefaultWiringPitch*37.5 BusMetal54) + TempArray[87] = list( "[87]" node_1W DefaultWiringPitch*38.5 BusMetal54) + TempArray[88] = list( "[88]" node_1W DefaultWiringPitch*39.5 BusMetal54) + TempArray[89] = list( "[89]" node_1W DefaultWiringPitch*40.5 BusMetal54) + TempArray[90] = list( "[90]" node_1W DefaultWiringPitch*31.5 BusMetal76) + TempArray[91] = list( "[91]" node_1W DefaultWiringPitch*32.5 BusMetal76) + TempArray[92] = list( "[92]" node_1W DefaultWiringPitch*33.5 BusMetal76) + TempArray[93] = list( "[93]" node_1W DefaultWiringPitch*34.5 BusMetal76) + TempArray[94] = list( "[94]" node_1W DefaultWiringPitch*35.5 BusMetal76) + TempArray[95] = list( "[95]" node_1W DefaultWiringPitch*36.5 BusMetal76) + TempArray[96] = list( "[96]" node_1W DefaultWiringPitch*37.5 BusMetal76) + TempArray[97] = list( "[97]" node_1W DefaultWiringPitch*38.5 BusMetal76) + TempArray[98] = list( "[98]" node_1W DefaultWiringPitch*39.5 BusMetal76) + TempArray[99] = list( "[99]" node_1W DefaultWiringPitch*40.5 BusMetal76) + TempArray[100] = list( "[100]" node_1W DefaultWiringPitch*43.5 BusMetal32) + TempArray[101] = list( "[101]" node_1W DefaultWiringPitch*44.5 BusMetal32) + TempArray[102] = list( "[102]" node_1W DefaultWiringPitch*45.5 BusMetal32) + TempArray[103] = list( "[103]" node_1W DefaultWiringPitch*46.5 BusMetal32) + TempArray[104] = list( "[104]" node_1W DefaultWiringPitch*47.5 BusMetal32) + TempArray[105] = list( "[105]" node_1W DefaultWiringPitch*48.5 BusMetal32) + TempArray[106] = list( "[106]" node_1W DefaultWiringPitch*49.5 BusMetal32) + TempArray[107] = list( "[107]" node_1W DefaultWiringPitch*50.5 BusMetal32) + TempArray[108] = list( "[108]" node_1W DefaultWiringPitch*51.5 BusMetal32) + TempArray[109] = list( "[109]" node_1W DefaultWiringPitch*52.5 BusMetal32) + TempArray[110] = list( "[110]" node_1W DefaultWiringPitch*43.5 BusMetal54) + TempArray[111] = list( "[111]" node_1W DefaultWiringPitch*44.5 BusMetal54) + TempArray[112] = list( "[112]" node_1W DefaultWiringPitch*45.5 BusMetal54) + TempArray[113] = list( "[113]" node_1W DefaultWiringPitch*46.5 BusMetal54) + TempArray[114] = list( "[114]" node_1W DefaultWiringPitch*47.5 BusMetal54) + TempArray[115] = list( "[115]" node_1W DefaultWiringPitch*48.8 BusMetal54) + TempArray[116] = list( "[116]" node_1W DefaultWiringPitch*49.5 BusMetal54) + TempArray[117] = list( "[117]" node_1W DefaultWiringPitch*50.5 BusMetal54) + TempArray[118] = list( "[118]" node_1W DefaultWiringPitch*51.5 BusMetal54) + TempArray[119] = list( "[119]" node_1W DefaultWiringPitch*52.5 BusMetal54) + TempArray[120] = list( "[120]" node_1W DefaultWiringPitch*43.5 BusMetal76) + TempArray[121] = list( "[121]" node_1W DefaultWiringPitch*44.5 BusMetal76) + TempArray[122] = list( "[122]" node_1W DefaultWiringPitch*45.5 BusMetal76) + TempArray[123] = list( "[123]" node_1W DefaultWiringPitch*46.5 BusMetal76) + TempArray[124] = list( "[124]" node_1W DefaultWiringPitch*47.5 BusMetal76) + TempArray[125] = list( "[125]" node_1W DefaultWiringPitch*48.5 BusMetal76) + TempArray[126] = list( "[126]" node_1W DefaultWiringPitch*49.5 BusMetal76) + TempArray[127] = list( "[127]" node_1W DefaultWiringPitch*50.5 BusMetal76) + TempArray[128] = list( "[128]" node_1W DefaultWiringPitch*51.5 BusMetal76) + TempArray[129] = list( "[129]" node_1W DefaultWiringPitch*52.5 BusMetal76) + TempArray[130] = list( "[130]" node_1W DefaultWiringPitch*55.5 BusMetal32) + TempArray[131] = list( "[131]" node_1W DefaultWiringPitch*56.5 BusMetal32) + TempArray[132] = list( "[132]" node_1W DefaultWiringPitch*57.5 BusMetal32) + TempArray[133] = list( "[133]" node_1W DefaultWiringPitch*58.5 BusMetal32) + TempArray[134] = list( "[134]" node_1W DefaultWiringPitch*59.5 BusMetal32) + TempArray[135] = list( "[135]" node_1W DefaultWiringPitch*60.5 BusMetal32) + TempArray[136] = list( "[136]" node_1W DefaultWiringPitch*61.5 BusMetal32) + TempArray[137] = list( "[137]" node_1W DefaultWiringPitch*62.5 BusMetal32) + TempArray[138] = list( "[138]" node_1W DefaultWiringPitch*63.5 BusMetal32) + TempArray[139] = list( "[139]" node_1W DefaultWiringPitch*64.5 BusMetal32) + TempArray[140] = list( "[140]" node_1W DefaultWiringPitch*55.5 BusMetal54) + TempArray[141] = list( "[141]" node_1W DefaultWiringPitch*56.5 BusMetal54) + TempArray[142] = list( "[142]" node_1W DefaultWiringPitch*57.5 BusMetal54) + TempArray[143] = list( "[143]" node_1W DefaultWiringPitch*58.5 BusMetal54) + TempArray[144] = list( "[144]" node_1W DefaultWiringPitch*59.5 BusMetal54) + TempArray[145] = list( "[145]" node_1W DefaultWiringPitch*60.5 BusMetal54) + TempArray[146] = list( "[146]" node_1W DefaultWiringPitch*61.5 BusMetal54) + TempArray[147] = list( "[147]" node_1W DefaultWiringPitch*62.5 BusMetal54) + TempArray[148] = list( "[148]" node_1W DefaultWiringPitch*63.5 BusMetal54) + TempArray[149] = list( "[149]" node_1W DefaultWiringPitch*64.5 BusMetal54) + TempArray[150] = list( "[150]" node_1W DefaultWiringPitch*55.5 BusMetal76) + TempArray[151] = list( "[151]" node_1W DefaultWiringPitch*56.5 BusMetal76) + TempArray[152] = list( "[152]" node_1W DefaultWiringPitch*57.5 BusMetal76) + TempArray[153] = list( "[153]" node_1W DefaultWiringPitch*58.5 BusMetal76) + TempArray[154] = list( "[154]" node_1W DefaultWiringPitch*59.5 BusMetal76) + TempArray[155] = list( "[155]" node_1W DefaultWiringPitch*60.5 BusMetal76) + TempArray[156] = list( "[156]" node_1W DefaultWiringPitch*61.5 BusMetal76) + TempArray[157] = list( "[157]" node_1W DefaultWiringPitch*62.5 BusMetal76) + TempArray[158] = list( "[158]" node_1W DefaultWiringPitch*63.5 BusMetal76) + TempArray[159] = list( "[159]" node_1W DefaultWiringPitch*64.4 BusMetal76) + ) + ) + TempArray + + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLCreateBufArray ( @key (Size 60)) + let( ( BufArray ) + + declare(BufArray[Size]) + + for( I 0 Size-1 + + when( Size <= CableBufferSplitIdx BufArray[I] = I ) + + when( Size > CableBufferSplitIdx + when( I <= (Size-1 - CableBufferSplitIdx) BufArray[I] = CableBufferSplitIdx + I ) + when( I > (Size-1 - CableBufferSplitIdx) BufArray[I] = I - (Size - CableBufferSplitIdx) ) + ) + ) + + BufArray + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;defun( CBLCreateBufArray () +; let( ( BufArray ) +; +; declare(BufArray[60]) +; +; for( I 0 59 +; +; when( I <= 35 +; BufArray[I] = 24 + I +; ) +; +; when( I > 35 +; BufArray[I] = I - 36 +; ) +; +; ) +; +; BufArray +; ) +;) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/util.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/util.il new file mode 100644 index 0000000000..04fcc6fbbe --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/util.il @@ -0,0 +1,1156 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/layout/cable/util.il#1 $ +; $DateTime: 2012/07/27 17:24:08 $ +; $Author: pankala $ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;; Generic function for overlaps. Use the Toggle for different checks + +defun( CBLOveralapExists (Overlaps Toggle) + let( ( lay Overlap OverlapFound ) + + Overlap = nil + OverlapFound = nil + + foreach( lay Overlaps + + case( Toggle + + ( "placer" + ; add other blockage layers in the condition + when( (car(lay~>lpp) == "y5" || car(lay~>lpp) == "OBS") && !OverlapFound + Overlap = t + OverlapFound = t + ) + when( lay~>isAnyInst && !OverlapFound + if( lay~>libName == "lib.buffer.smr" || lay~>libName == "lib.buffer.nyb" || lay~>libName == "lib.buffer.ts" + then + Overlap = t + OverlapFound = t + else + Overlap = nil + ) + ) + ) + + ( "router" + ; add other blockage layers in the condition + when( cadr(lay~>lpp) == "bus" + Overlap = t + ) + ) + + ) + ) + + Overlap + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLCurrDir (CableShape CurrIdx) + let( (Direction + Seg + ) + + Seg = CBLCurrSegment(CableShape CurrIdx) + + if( Seg == "H" + then + if( car(nth(CurrIdx CableShape~>points)) > car(nth(CurrIdx-1 CableShape~>points)) + then + Direction = "P" + else + Direction = "N" + ) + else + if( cadr(nth(CurrIdx CableShape~>points)) > cadr(nth(CurrIdx-1 CableShape~>points)) + then + Direction = "P" + else + Direction = "N" + ) + ) + + Direction + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( CBLCurrSegment (CableShape CurrIdx) + let( ( Segment ) + +; if( CurrIdx < CableShape~>nPoints-1 +; then + if( car(nth(CurrIdx CableShape~>points)) == car(nth(CurrIdx-1 CableShape~>points)) + then + Segment = "V" + else + Segment = "H" + ) +; else +; Segment = nil +; ) + Segment + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( CBLSetCableProp (Shape Prp) + + dbReplaceProp(Shape Prp "boolean" "TRUE") + +t +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLFindPtIdxs ( CableShape Point @key (CV (UIGetCellView)) ) + let( ( LwIdx UpIdx FoundIdx + I N SegLen + StartPt EndPt StartX StartY EndX EndY PtX PtY + ) + + N = CableShape~>nPoints + LwIdx = nil + UpIdx = nil + FoundIdx = nil + + when( cadr(Point) != nil + PtX = round(car(Point)*1000) + PtY = round(cadr(Point)*1000) + + for( I 0 N-2 + + StartPt = nth(I CableShape~>points) + StartX = round(car(StartPt)*1000) + StartY = round(cadr(StartPt)*1000) + + EndPt = nth(I+1 CableShape~>points) + EndX = round(car(EndPt)*1000) + EndY = round(cadr(EndPt)*1000) + + if( StartY == EndY ; && !FoundIdx + then + SegLen = abs(EndX - StartX) + when( (PtY == StartY) && ( (abs(PtX - StartX) + abs(PtX - EndX)) == SegLen ) + LwIdx = I + UpIdx = I+1 + FoundIdx = t + ) + else + SegLen = abs(EndY - StartY) + when( (PtX == StartX) && ( (abs(PtY - StartY) + abs(PtY - EndY)) == SegLen ) + LwIdx = I + UpIdx = I+1 + FoundIdx = t + ) + ) + ) + ) + + list(LwIdx UpIdx) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( CBLLocateAtDist ( CableShape StartLoc Distance @key (CV (UIGetCellView)) ) + let( ( + XYCoOrd + FinalIdx + LwIdx UpIdx + CurrIdx CurrDist CurrLoc + CablePoints + LocFound + shp + ) + + CablePoints = CableShape~>points + UpIdx = cadr(CBLFindPtIdxs(CableShape StartLoc)) + CurrIdx = UpIdx + CurrDist = Distance + CurrLoc = StartLoc + + while( !LocFound && (CurrIdx != length(CablePoints)) + if( car(CurrLoc) == car(nth(CurrIdx CablePoints)) + then + if( CurrDist <= abs(difference(cadr(CurrLoc) cadr(nth(CurrIdx CablePoints)))) + then + if( negativep(difference(cadr(CurrLoc) cadr(nth(CurrIdx CablePoints)))) + then + XYCoOrd = list(car(CurrLoc) cadr(CurrLoc)+CurrDist) + FinalIdx = CurrIdx + LocFound = t + else + XYCoOrd = list(car(CurrLoc) difference(cadr(CurrLoc) CurrDist)) + FinalIdx = CurrIdx + LocFound = t + ) + else + CurrDist = CurrDist - abs(difference(cadr(CurrLoc) cadr(nth(CurrIdx CablePoints)))) + CurrLoc = nth(CurrIdx CablePoints) + CurrIdx = CurrIdx + 1 + ) + else + if( CurrDist <= abs(difference(car(CurrLoc) car(nth(CurrIdx CablePoints)))) + then + if( negativep(difference(car(CurrLoc) car(nth(CurrIdx CablePoints)))) + then + XYCoOrd = list(car(CurrLoc)+CurrDist cadr(CurrLoc)) + FinalIdx = CurrIdx + LocFound = t + else + XYCoOrd = list(difference(car(CurrLoc) CurrDist) cadr(CurrLoc)) + FinalIdx = CurrIdx + LocFound = t + ) + else + CurrDist = CurrDist - abs(difference(car(CurrLoc) car(nth(CurrIdx CablePoints)))) + CurrLoc = nth(CurrIdx CablePoints) + CurrIdx = CurrIdx + 1 + ) + + ) + + + ) + + ; shp = dbCreateRect(CV "M5" list(XYCoOrd list(car(XYCoOrd)+1.56 cadr(XYCoOrd)+1.56))) + + list(XYCoOrd FinalIdx) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( CBLCreateBufBlockage ( @key (CableShape car(geGetSelectedSet())) (CV (UIGetCellView)) (BlockLPP list("y5" "drawing"))) + + let( ( + CablePoints + PathWidth + XCord YCord + I N + BufBlock BlockList + ) + + PathWidth = CBLGetPathWidth(?CableShape CableShape) + CablePoints = CableShape~>points + N = CableShape~>nPoints + + BlockList = nil + + when( N > 2 + for( I 1 N-2 + + XCord = truncate(car(nth(I CableShape~>points))/3.12)*3.12 + YCord = truncate(cadr(nth(I CableShape~>points))/3.12)*3.12 + + BufBlock = dbCreateRect(CV BlockLPP list(list(XCord YCord) list((XCord + PathWidth*3.12) (YCord + PathWidth*3.12))) ) + CBLSetCableProp(BufBlock "BufBlock") + BlockList = cons(BufBlock BlockList) + ) + ) + + +BlockList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CBLGetPathWidth ( @key (CableShape car(geGetSelectedSet())) ) + let( ( + DataWidth + PathWidth + WidthFound channelBuf + ) + DataWidth = 1 + when( stringp(CableShape~>ChannelWidth) DataWidth = evalstring(CableShape~>ChannelWidth)) + when( numberp(CableShape~>ChannelWidth) DataWidth = CableShape~>ChannelWidth) + DataWidth = DataWidth - 1 + channelBuf + + +; WidthFound = nil + PathWidth = 2 + +; if( DataWidth > 12 +; then +; while( PathWidth > 1 && WidthFound != t +; +; if( DataWidth <= (PathWidth-1)*12 && DataWidth >= (PathWidth-2)*12 +; then +; WidthFound = t +; else +; PathWidth = PathWidth - 1 +; ) +; +; ) +; else +; PathWidth = 2 +; ) + + when( DataWidth > 0 && DataWidth < 12 + PathWidth = 2 + ) + when( DataWidth >= 12 && DataWidth < 24 + PathWidth = 3 + ) + when( DataWidth >= 24 && DataWidth < 36 + PathWidth = 4 + ) + when( DataWidth >= 36 && DataWidth < 48 + PathWidth = 5 + ) + when( DataWidth >= 48 && DataWidth < 60 + PathWidth = 6 + ) + + when( channelBuf == "TS" + when( DataWidth > 0 && DataWidth < 12 + PathWidth = 2 + ) + when( DataWidth >= 12 && DataWidth < 24 + PathWidth = 3 + ) + when( DataWidth >= 24 && DataWidth < 36 + PathWidth = 4 + ) + when( DataWidth >= 36 && DataWidth < 48 + PathWidth = 5 + ) + when( DataWidth >= 48 && DataWidth < 60 + PathWidth = 6 + ) + ) + PathWidth + + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CAComputeCableLength ( CableShape @key (CV (UIGetCellView)) ) + let( ( + CableLength + I N + StartPt EndPt + ) + N = CableShape~>nPoints + CableLength = 0 + for( I 0 N-2 + + StartPt = nth(I CableShape~>points) + EndPt = nth(I+1 CableShape~>points) + + when( cadr(StartPt) == cadr(EndPt) + CableLength = CableLength + abs(difference(car(StartPt) car(EndPt))) + ) + + when( car(StartPt) == car(EndPt) + CableLength = CableLength + abs(difference(cadr(StartPt) cadr(EndPt))) + ) + ) + CableLength + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun SetCablePattern (template @key (paths nil)) + (let (pat) + paths = (if paths==nil (geGetSelSet) paths) + (foreach obj paths + (cond (obj->objType=="path" + pat = (if template template (GetProp obj "ChannelTemplate" "Template_A")) + (CreateCableProps ?paths (list obj)) + (dbReplaceProp obj "ChannelTemplate" "string" pat) + ) + ) + ) + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CreateCableProps (@key (paths nil)) + (let ( + template width prop_mbuf prop_template + mbuf hops prop_hops prop_hopdist + sbuf start prop_width + rbuf end hopdist + ) + paths = (if paths==nil (geGetSelSet) paths) + props = (FindCableProps) + when( nth(0 props) prop_mbuf = nth(0 props) ) + when( nth(1 props) prop_hops = nth(1 props) ) + when( nth(2 props) prop_width = nth(2 props) ) + when( nth(3 props) prop_template = nth(3 props) ) + when( nth(4 props) prop_hopdist = nth(4 props) ) + (foreach obj paths + (cond (obj->objType=="path" + ; copy properties + template = (GetProp obj "ChannelTemplate" prop_template ) + mbuf = (GetProp obj "ChannelBuf" prop_mbuf ) + sbuf = (GetProp obj "ChannelSbufOrient" "H" ) + rbuf = (GetProp obj "ChannelRbufOrient" "H" ) + hops = (GetProp obj "ChannelHops" prop_hops ) + width = (GetProp obj "ChannelWidth" prop_width ) + start = (GetProp obj "InputDistance_um" 0.0 ) + end = (GetProp obj "OutputDistance_um" 0.0 ) + hopdist = (GetProp obj "HopDistance_um" prop_hopdist ) + + ; delete properties + (dbDeletePropByName obj "ChannelTemplate" ) + (dbDeletePropByName obj "ChannelBuf" ) + (dbDeletePropByName obj "ChannelSbufOrient" ) + (dbDeletePropByName obj "ChannelRbufOrient" ) + (dbDeletePropByName obj "ChannelHops" ) + (dbDeletePropByName obj "ChannelWidth" ) + (dbDeletePropByName obj "InputDistance_um" ) + (dbDeletePropByName obj "OutputDistance_um" ) + (dbDeletePropByName obj "HopDistance_um" ) + + ; set new properties + (dbReplaceProp obj "ChannelTemplate" "string" template ) + (dbReplaceProp obj "ChannelBuf" "string" mbuf ) + (dbReplaceProp obj "ChannelSbufOrient" "string" sbuf ) + (dbReplaceProp obj "ChannelRbufOrient" "string" rbuf ) + (dbReplaceProp obj "ChannelHops" "fixnum" hops ) + (dbReplaceProp obj "ChannelWidth" "fixnum" width ) + (dbReplaceProp obj "InputDistance_um" "flonum" start ) + (dbReplaceProp obj "OutputDistance_um" "flonum" end ) + (dbReplaceProp obj "HopDistance_um" "flonum" hopdist ) + + )) + ) + ) + t +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun FindCableProps (@key (CV (UIGetCellView)) ) + (let ( props + parts1 parts2 parts3 + bufType bufHops bufWidth buftemplate hopDist + ) + + if( CV~>libName == "chip.rrc.util.cable" + then + parts1 = parseString(CV~>cellName "." ) + parts2 = parseString(nth(4 parts1) "-" ) + parts3 = parseString(nth(1 parts2) "_L" ) + bufHops = readstring(nth(0 parts3) ) + bufWidth = readstring(nth(1 parts3) ) + case( nth(0 parts2) + ( "CABLE_MBUFS" || "CABLE" bufType = "DENSE" buftemplate = "Template_BUF_R90" hopDist = 290.0 ) + ( "NYB_CABLE_MBUFS" || "NYB_CABLE" bufType = "NYB" buftemplate = "Template_NYBBUF_R90" hopDist = 290.0 ) + ( "TS_CABLE_MBUFS" || "TS_CABLE" bufType = "TS" buftemplate = "Template_TSBUF_R90" hopDist = 230.0 ) + ) + props = list(bufType bufHops bufWidth buftemplate hopDist ) + else + props = nil + ) +props + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CreateCableBoundary (@key (CableShape car(geGetSelectedSet())) (CV (UIGetCellView)) (CreatePRObject nil)) + (let ( I CurrDir CurrSeg PathWidth NotStart NotEnd + PRList PRShape MergePRShape + ) + + PRList = CBLCreateBufBlockage(?CableShape CableShape ?BlockLPP list("prBoundary" "drawing")) + PathWidth = CBLGetPathWidth(?CableShape CableShape) + + for( I 1 CableShape~>nPoints-1 + CurrSeg = CBLCurrSegment(CableShape I) + CurrDir = CBLCurrDir(CableShape I) + NotStart = 1 + NotEnd = 1 + when( I == 1 NotStart = 0 ) + when( I == CableShape~>nPoints-1 NotEnd = 0 ) + PRShape = CreateCableSegmentBoundary(CV PathWidth nth(I-1 CableShape~>points) nth(I CableShape~>points) CurrSeg CurrDir NotStart NotEnd) + PRList = cons(PRShape PRList) + ) + + MergePRShape = car(leMergeShapes(remove(nil PRList))) + + when( CreatePRObject + if( MergePRShape~>points + then + dbCreatePRBoundary(CV MergePRShape~>points) + else + dbCreatePRBoundary(CV BBoxToPoints(MergePRShape~>bBox)) + ) + ) + +MergePRShape + + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CreateCableSegmentBoundary (CV PathWidth StartPt EndPt Segment Dir NotStart NotEnd) + (let ( StartXCord StartYCord EndXCord EndYCord + MetalbBox PRbBox M4Block M2Block M6Block M3Block M5Block M7Block PRShape + ) + + StartXCord = truncate((car(StartPt)*1000)/(PowerGridPitch*2000))*PowerGridPitch*2 + StartYCord = truncate((cadr(StartPt)*1000)/(PowerGridPitch*2000))*PowerGridPitch*2 + EndXCord = truncate((car(EndPt)*1000)/(PowerGridPitch*2000))*PowerGridPitch*2 + EndYCord = truncate((cadr(EndPt)*1000)/(PowerGridPitch*2000))*PowerGridPitch*2 + + when( Segment == "V" + if( Dir == "P" + then + when(NotEnd == 0 EndYCord = cadr(EndPt)) + when(NotStart == 0 StartYCord = cadr(StartPt)) + MetalbBox = list(StartXCord+PowerGridPitch/4:StartYCord+PowerGridPitch/4 EndXCord-PowerGridPitch/4+PathWidth*PowerGridPitch*2:EndYCord-PowerGridPitch/4+(PathWidth*PowerGridPitch*2)*NotEnd) + PRbBox = list(StartXCord:StartYCord+(PathWidth*PowerGridPitch*2)*NotStart EndXCord+PathWidth*PowerGridPitch*2:EndYCord) +; M2Block = dbCreateRect(CV list("M2" "boundary") MetalbBox) +; SetBusProp(M2Block) +; M4Block = dbCreateRect(CV list("M4" "boundary") MetalbBox) +; SetBusProp(M4Block) + M6Block = dbCreateRect(CV list("M6" "boundary") MetalbBox) + SetBusProp(M6Block) + PRShape = dbCreateRect(CV list("prBoundary" "drawing") PRbBox) + SetBusProp(PRShape) + else + when(NotEnd == 0 EndYCord = cadr(EndPt)) + when(NotStart == 0 StartYCord = cadr(StartPt)) + MetalbBox = list(StartXCord+PowerGridPitch/4:StartYCord-PowerGridPitch/4+(PathWidth*PowerGridPitch*2)*NotStart EndXCord-PowerGridPitch/4+PathWidth*PowerGridPitch*2:EndYCord+PowerGridPitch/4) + PRbBox = list(StartXCord:StartYCord EndXCord+PathWidth*PowerGridPitch*2:EndYCord+(PathWidth*PowerGridPitch*2)*NotEnd) +; M2Block = dbCreateRect(CV list("M2" "boundary") MetalbBox) +; SetBusProp(M2Block) +; M4Block = dbCreateRect(CV list("M4" "boundary") MetalbBox) +; SetBusProp(M4Block) + M6Block = dbCreateRect(CV list("M6" "boundary") MetalbBox) + SetBusProp(M6Block) + PRShape = dbCreateRect(CV list("prBoundary" "drawing") PRbBox) + SetBusProp(PRShape) + ) + ) + when( Segment == "H" + if( Dir == "P" + then + when(NotEnd == 0 EndXCord = car(EndPt)) + when(NotStart == 0 StartXCord = car(StartPt)) + MetalbBox = list(StartXCord+PowerGridPitch/4:StartYCord+PowerGridPitch/4 EndXCord-PowerGridPitch/4+(PathWidth*PowerGridPitch*2)*NotEnd:EndYCord-PowerGridPitch/4+PathWidth*PowerGridPitch*2) + PRbBox = list(StartXCord+(PathWidth*PowerGridPitch*2)*NotStart:StartYCord EndXCord:EndYCord+PathWidth*PowerGridPitch*2) +; M3Block = dbCreateRect(CV list("M3" "boundary") MetalbBox) +; SetBusProp(M3Block) +; M5Block = dbCreateRect(CV list("M5" "boundary") MetalbBox) +; SetBusProp(M5Block) + M7Block = dbCreateRect(CV list("M7" "boundary") MetalbBox) + SetBusProp(M7Block) + PRShape = dbCreateRect(CV list("prBoundary" "drawing") PRbBox) + M3Block = dbCreateRect(CV list("M3" "boundary") MetalbBox) + SetBusProp(M3Block) + M5Block = dbCreateRect(CV list("M5" "boundary") MetalbBox) + SetBusProp(M5Block) SetBusProp(PRShape) + else + when(NotEnd == 0 EndXCord = car(EndPt)) + when(NotStart == 0 StartXCord = car(StartPt)) + MetalbBox = list(StartXCord-PowerGridPitch/4+(PathWidth*PowerGridPitch*2)*NotStart:StartYCord+PowerGridPitch/4 EndXCord+PowerGridPitch/4:EndYCord-PowerGridPitch/4+PathWidth*PowerGridPitch*2) + PRbBox = list(StartXCord:StartYCord EndXCord+(PathWidth*PowerGridPitch*2)*NotEnd:EndYCord+PathWidth*PowerGridPitch*2) +; M3Block = dbCreateRect(CV list("M3" "boundary") MetalbBox) +; SetBusProp(M3Block) +; M5Block = dbCreateRect(CV list("M5" "boundary") MetalbBox) +; SetBusProp(M5Block) + M7Block = dbCreateRect(CV list("M7" "boundary") MetalbBox) + SetBusProp(M7Block) + PRShape = dbCreateRect(CV list("prBoundary" "drawing") PRbBox) + SetBusProp(PRShape) + ) + ) + + PRShape + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CreateCableBufObstruction (@key (CV (UIGetCellView))) + (let ( BufInst OBTemp OBShapes ) + + OBShapes = nil + + foreach( BufInst wcv()~>instances + when( BufInst~>libName == "lib.buffer.smr" + OBTemp = dbCreateRect(CV list("M8" "boundary") list(PGRound(caar(BufInst~>bBox)):PGRound(cadar(BufInst~>bBox)) PGRound(caadr(BufInst~>bBox)):PGRound(cadadr(BufInst~>bBox)))) + dbSet(OBTemp BufInst~>Segment "Segment") + when( OBTemp OBShapes = cons(OBTemp OBShapes) ) + ) + ) + leMergeShapes(OBShapes) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun PGRound ( CoOrd @key (Factor 1) ) + round(round(CoOrd*1000)/(PowerGridPitch*Factor*1000))*PowerGridPitch*Factor +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun PGTruncate ( CoOrd @key (Factor 1) ) + truncate(round(CoOrd*1000)/(PowerGridPitch*Factor*1000))*PowerGridPitch*Factor +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CreateSyncCablePowerPins ( CV layer @key (instprefix "mbuf") ) + let( ( inst instname xy x1 y1 figg figv netg netv label pinop ) + + label = t + + instname = strcat(instprefix, "[0][0]") + + inst = dbFindAnyInstByName(CV instname) + + pinop = CablePowerPinFigs(CV inst) + + + ; GND pin + if( dbFindNetByName( CV GNDNetName ) + then + netg = dbFindNetByName( CV GNDNetName ) + else + netg = dbMakeNet( CV GNDNetName ) + ) + + figg = car(pinop) + dbReplaceProp( figg "PinType" "string" "PowerGrid" ) + dbReplaceProp( figg "PinType" "string" "Power") + dbCreatePin( netg figg ) + when( label MidPinsCreateLabel(CV figg) ) + + + ; Vdd pin + if( dbFindNetByName( CV VddNetName) + then + netv = dbFindNetByName( CV VddNetName ) + else + netv = dbMakeNet( CV VddNetName) + ) + + figv = cadr(pinop) + dbReplaceProp( figv "PinType" "string" "PowerGrid" ) + dbReplaceProp( figv "PinType" "string" "Power") + dbCreatePin( netv figv ) + when( label MidPinsCreateLabel(CV figv) ) + +t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CablePowerPinFigs ( CellView inst ) + let( ( xy x1 y1 figg figv ) + + xy = inst~>xy + x1 = car( xy ) + y1 = cadr( xy ) + + case( inst~>orient + ( "MXR90" + figg = dbCreateRect( CellView list(layer "gnd") + list(x1+3.03:y1+1.535 x1+3.08:y1+1.585) ) + figv = dbCreateRect( CellView list(layer "vdd") + list(x1+1.6:y1+1.535 x1+1.65:y1+1.585) ) + ) + ( "R90" + figg = dbCreateRect( CellView list(layer "gnd") + list(x1-3.03:y1+1.535 x1-3.08:y1+1.585) ) + figv = dbCreateRect( CellView list(layer "vdd") + list(x1-1.6:y1+1.535 x1-1.65:y1+1.585) ) + ) + ( "R270" + figg = dbCreateRect( CellView list(layer "gnd") + list(x1+3.03:y1-1.535 x1+3.08:y1-1.585) ) + figv = dbCreateRect( CellView list(layer "vdd") + list(x1+1.6:y1-1.535 x1+1.65:y1-1.585) ) + ) + ) + + list(figg figv) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun FindCableLength ( @key (CableShape car(geGetSelectedSet())) ) + let( ( sum I cpt npt ) + + sum = 0 + + for( I 0 CableShape~>nPoints-2 + cpt = nth(I CableShape~>points) + npt = nth(I+1 CableShape~>points) + sum = sum + abs(car(cpt)-car(npt)) + abs(cadr(cpt)-cadr(npt)) + + ) +sum + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CreateCableCell ( libName @key (CableShape car(geGetSelectedSet())) ) + (let ( Hops W cellName cellfound subtype cv newcv ) + + cellfound = nil + subtype = 1000 + Hops = CableShape~>BufferHops ; evalstring(CableShape~>BufferHops) + W = CableShape~>ChannelWidth + + while( !cellfound + + sprintf(cellName "%s.CABLE-L%d_%d-R.%d" libName Hops W subtype) + + cv = nrOpenCellViewReadableByName(cellName "cable") + if( cv + then + dbClose(cv) + subtype = subtype + 1 + else + newcv = nrOpenCellViewWritableByName(cellName "cable") + dbCopyShape(CableShape newcv) + dbSave(newcv) + dbClose(newcv) + + cellfound = t + ) + ) + +list(cellName subtype) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun CreateCableSpec ( libName Hops W subtype ) + let( ( source cell module define shoutdir skoutdir root root1 + libparts inf shinfl skinfl skoutfl outf strparts ) + + root = "/nfs/site/disks/wdisk.83/pankala1/rrc_1/spec" + root1 = "/nfs/site/disks/wdisk.83/pankala1/rrc_1/spec" + source = strcat(root1 "/experiment/cable/CABLE\\(3,10\\)/1000.cast") + + libparts = parseString(libName ".") + shoutdir = root + skoutdir = root + for( I 0 length(libparts)-1 + shoutdir = strcat(shoutdir "/" nth(I libparts)) + skoutdir = strcat(skoutdir "/" nth(I libparts)) + ) + + ;evalstring(Hops) + + when( stringp(Hops) + println("helo") + Hops = evalstring(Hops) + ) + when( stringp(W) + W = evalstring(W) + ) + + sprintf(shoutdir "%s/CABLE\\(%d,%d\\)" shoutdir Hops W) + sprintf(skoutdir "%s/CABLE(%d,%d)" skoutdir Hops W) + + + sh(strcat("mkdir -p " shoutdir)) + sprintf(shinfl "%s/%d.cast" shoutdir subtype) + sprintf(skinfl "%s/%d.cast" skoutdir subtype) + sprintf(shoutfl "%s/%d_temp.cast" shoutdir subtype) + sprintf(skoutfl "%s/%d_temp.cast" skoutdir subtype) + + + inf = infile(skinfl) + + when( !inf + println("jaffa") + sh(strcat("cp " source " " shinfl)) + sh(strcat("chmod +w " shinfl)) + inf = infile(skinfl) + ) + + outf = outfile(skoutfl) + + sprintf(cell "%s.CABLE(%d,%d)" libName Hops W) + module = strcat("module " cell ";\n") + sprintf(define "define \"%d\"() <+ standard.process.standard_layout_cell <: %s { \n" subtype cell) + + while( gets(str inf) + strparts=parseString(str) + when( car(strparts) == "module" + str = module + ) + when( car(strparts) == "define" + str = define + ) + fprintf(outf "%s" str) + ) + close(inf) + close(outf) + + sh(strcat("mv " shoutfl " " shinfl)) + + println(module) + println(define) + println(skoutdir) + println(skinfl) + + + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun ReplaceCableShapes ( @key (CV (UIGetCellView)) (CableShapes (geGetSelectedSet)) ) + let( ( cbl cellop instname I ) + I = 0 + foreach( cbl CableShapes + cellop = CreateCableCell("experiment.cable.ring" ?CableShape cbl) + sprintf(instname "cable[%d]" I) + dbCreateInstByMasterName(CV "experiment.cable.ring" car(cellop) "cable" instname list(0 0) "R0") + CreateCableSpec("experiment.cable.ring" cbl~>BufferHops cbl~>ChannelWidth cadr(cellop)) + I = I+1 + ) +t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun InverseTransform ( Transform ) + (let ( newTrans ) + + origin = nth(0 Transform) + rotate = nth(1 Transform) + + case( rotate + ( "R0" + newOrigin = list(car(origin)*-1.0 cadr(origin)*-1.0) + newRotate = "R0" + ) + ( "R90" + newOrigin = list(car(origin)*-1.0 cadr(origin)) + newRotate = "R270" + ) + ( "R180" + newOrigin = list(car(origin) cadr(origin)) + newRotate = "R180" + ) + ( "R270" + newOrigin = list(car(origin) cadr(origin)*-1.0) + newRotate = "R90" + ) + ( "MX" + newOrigin = list(car(origin)*-1.0 cadr(origin)) + newRotate = "MX" + ) + ( "MXR90" + newOrigin = list(car(origin)*-1.0 cadr(origin)*-1.0) + newRotate = "MXR90" + ) + ( "MY" + newOrigin = list(car(origin) cadr(origin)*-1.0) + newRotate = "MY" + ) + ( "MYR90" + newOrigin = list(car(origin) cadr(origin)) + newRotate = "MYR90" + ) + ( t + newOrigin = origin + newRotate = rotate + ) + ) + + list(newOrigin newRotate nth(2 Transform)) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun DrawHierTopLevelShape ( objPath @key (CV (UIGetCellView)) (layer nil) ) + (let ( tempPath TopTransform botObj botInst topBBox topPts topObj objLayer ) + when( listp(objPath) + tempPath = objPath + TopTransform = dbGetHierPathTransform(objPath) + + while( listp(cadr(tempPath)) + tempPath = cadr(tempPath) + ) + botInst = car(tempPath) + botObj = cadr(tempPath) + if( layer + then + objLayer = layer + else + objLayer = botObj~>lpp + ) + + case( botObj~>objType + ( "rect" + topBBox = dbTransformBBox(botObj~>bBox TopTransform) + topObj = dbCreateRect(CV objLayer topBBox) + dbCopyProp(botObj topObj) + ) + ( "polygon" + topPts = TransformPoints(botObj~>points TopTransform) + topObj = dbCreatePolygon(CV objLayer topPts) + dbCopyProp(botObj topObj) + ) + ( "path" + topPts = TransformPoints(botObj~>points TopTransform) + topObj = dbCreatePath(CV objLayer topPts botObj~>width botObj~>pathStyle) + dbCopyProp(botObj topObj) + ) + ) + list(topObj botInst) + ) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun PushHierTopLevelShape ( objPath topObj botCV @key (CV (UIGetCellView)) ) + (let (tempPath currInst topGuide botObj botInst) + when( listp(objPath) + + tempPath = objPath + + case( topObj~>objType + ( "rect" topGuide = topObj~>bBox ) + ( "polygon" || "path" topGuide = topObj~>points ) + ) + + while( listp(cadr(tempPath)) + currInst = car(tempPath) + topGuide = TransformPoints(topGuide InverseTransform(currInst~>transform)) + tempPath = cadr(tempPath) + ) + + botInst = car(tempPath) + topGuide = TransformPoints(topGuide InverseTransform(botInst~>transform)) + + case( topObj~>objType + ( "rect" + botObj = dbCreateRect(botCV topObj~>lpp topGuide) + dbCopyProp(topObj botObj) + ) + ( "polygon" + botObj = dbCreatePolygon(botCV topObj~>lpp topGuide) + dbCopyProp(topObj botObj) + ) + ( "path" + botObj = dbCreatePath(botCV topObj~>lpp topGuide topObj~>width topObj~>pathStyle) + dbCopyProp(topObj botObj) + ) + ) + botObj + ) + ) +) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun TransformPoints (points Transform) + (let ( I newlist ) + + for( I 0 length(points)-1 + newlist = append(newlist list(dbTransformPoint(nth(I points) Transform))) + ) +newlist + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun FindAllCableShapes ( @key (CV (UIGetCellView)) ) + let( ( rawCables shp currShp currInst opFile opFileName aO autoObs + cableInsts cableShapes cableOrigins currOP ) + + rawCables = dbGetTrueOverlaps(CV CV~>bBox list("M8" "bus") 32) + sprintf(opFileName "%s.cablecells" CV~>cellName) + opFile = outfile(opFileName) + + foreach( autoObs setof( aO CV~>shapes aO~>AutoCableShape=="TRUE" ) dbDeleteObject(autoObs) ) + + foreach( shp rawCables + if( listp(shp) + then + currOP = DrawHierTopLevelShape(shp ?CV CV ?layer list("y9" "drawing")) + currShp = car(currOP) + currShp~>AutoCableShape = "TRUE" + currInst = cadr(currOP) + if( currShp~>ChannelWidth + then + cableInsts = cons(currInst cableInsts) + cableShapes = cons(currShp cableShapes) + cableOrigins = cons(shp cableOrigins) + else + dbDeleteObject(currShp) + ) + else + when( shp~>ChannelWidth + cableInsts = cons(CV cableInsts) + cableShapes = cons(shp cableShapes) + cableOrigins = cons(shp cableOrigins) + ) + ) + ) + + foreach( inst cableInsts fprintf(opFile "%s\n" inst~>cellName) ) + close(opFile) + +list(cableShapes cableOrigins cableInsts) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun GenerateCableOverlaps ( @key (CableShapes (geGetSelectedSet)) ) + (let ( cbl currPr allPr pr tempPr obs allObs ) + + foreach( cbl CableShapes + currPr = CreateCableBoundary(?CableShape cbl) + allPr = cons(currPr allPr) + ) + + foreach( pr allPr + tempPr = remove(pr allPr) + obs = dbLayerAnd(wcv() list("OBS" "bus") list(pr) tempPr) + allObs = append(allObs obs) + ) + + leMergeShapes(allObs) + allPr + + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun RefreshCableBlockages ( cableShapeInstList @key (CV (UIGetCellView)) ) + (let ( I cableShapes cableInsts cableOrigins + remPr currShp currInst allPr obs obj autoObs aO currCV ) + + cableOrigins = nth(1 cableShapeInstList) + cableShapes = nth(0 cableShapeInstList) + cableInsts = nth(2 cableShapeInstList) + + foreach( autoObs setof( aO CV~>shapes aO~>AutoBufBlock=="TRUE" ) dbDeleteObject(autoObs) ) + + for( I 0 length(cableShapes)-1 + println(I) + allPr = append(allPr list(CreateCableBoundary(?CableShape nth(I cableShapes)))) + ) + + for( I 0 length(cableShapes)-1 + currShp = nth(I cableShapes) + currInst = nth(I cableInsts) + currOrigin = nth(I cableOrigins) + currPr = nth(I allPr) + when( listp(currOrigin) + obs = dbLayerAnd(CV list("OBS" "bus") list(currPr) remove(currPr allPr)) + currCV = nrOpenCellViewWritableByName(currInst~>cellName "cable") + if( currCV + then + foreach( autoObs setof( aO currCV~>shapes aO~>AutoBufBlock=="TRUE" ) dbDeleteObject(autoObs) ) + foreach( obj obs obj~>AutoBufBlock = "TRUE" PushHierTopLevelShape(currOrigin obj currCV) ) + foreach( obj obs dbDeleteObject(obj) ) + dbSave(currCV) + dbClose(currCV) + else + printf("Unable to open %s. Pls. run the auto check-out function !\n" currInst~>cellName) + ) + ) + ) + + (DeleteBusWires) + allPr + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun P4AllCableSubcells ( @key (CV (UIGetCellView)) (CMD "ADD") (CustomFile nil) (CustomView "cable") ) + (let ( ipFileName ipFile cellName currCV ) + + (if ( and + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) "" ) + ( or + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) "" ) + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) "" ) ) ) + (error "Must specify P4CONFIG or P4USER and P4CLIENT in envirnoment or cds.config" ) ) + + if( CustomFile + then + ipFileName = CustomFile + else + sprintf(ipFileName "%s.cablecells" CV~>cellName) + ) + +; when( (CMD == "EDIT" || CMD == "ADD") && !CustomFile ; !ipFile +; FindAllCableShapes(?CV CV) +; ) + + ipFile = infile(ipFileName) + + while( gets(cellName ipFile) + cellName = car(parseString(cellName "\n")) + println(cellName) + currCV = nrOpenCellViewReadableByName(cellName CustomView) + case( CMD + ( "ADD" + ( CDSP4Add + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + currCV + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ) + ( "EDIT" + ( CDSP4Edit + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + currCV + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ) + ( "REVERT" + ( CDSP4Revert + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + currCV + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ) + ) + dbClose(currCV) + ) + close(ipFile) + t + ) +) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun mergeshp () + let( (shp s ) + shp = setof(s wcv()~>shapes car(s~>lpp)=="M1") + leMergeShapes(shp) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun AutoCreateCable ( Cell @key (Orient "SYNC") ) + (let ( ipFile ipFileName cellName cbl shp cellname currCV ) + + sprintf(ipFileName "%s.cablecells" Cell) + ipFile = infile(ipFileName) + + while( gets(cellname ipFile) + cellname = car(parseString(cellname "\n")) + currCV = nrOpenCellViewWritableByName(cellname "cable") + println(currCV~>cellName) + + cbl = car(setof(shp currCV~>shapes shp~>BufferHops)) + + nrSyncToNetlist(currCV) + PlaceSyncCableBuffers(?CableShape cbl ?CV currCV) + + dbSave(currCV) + dbClose(currCV) + ) + +close(ipFile) +t + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/cellinfo.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/cellinfo.il new file mode 100644 index 0000000000..4877baddaf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/cellinfo.il @@ -0,0 +1,151 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun CellInfoGetDirectivesSkillFileForCellName ( CellName DirectivesSkillDir ) + ( sprintf nil "%s/%s.directives.il" DirectivesSkillDir CellName ) ) + + +(defun CellInfoGetTableForCellName ( CellName DirectivesSkillDir ) + (let ( + ( DirectivesSkillFileName ( CellInfoGetDirectivesSkillFileForCellName + CellName + DirectivesSkillDir ) ) ) + ( CellInfoGetTableForFileName + DirectivesSkillFileName ) ) ) + +(defun CellInfoGetTableForFileName ( DirectivesSkillFileName ) + (if ( isReadable + DirectivesSkillFileName ) + (let () + (defvar DirectiveTable nil ) + ( load DirectivesSkillFileName ) + (if DirectiveTable + DirectiveTable + ( sprintf + nil + "Could not load %L even though it is readable." + DirectivesSkillFileName ) ) ) + ( sprintf + nil + "%L is not a readable file." + DirectivesSkillFileName ) ) ) + + +(defun CellInfoGetDF2Path ( LibName CellName ) + (let ( + ( CellDirObj ( ddGetObj LibName CellName ) ) + ) + ( cond ( + ( null CellDirObj ) + ( printf "CellName/LibName not valid\n" ) + nil + ) + ( + ( ddGetObjWritePath CellDirObj) + ) + ) + ) +) + + +(defun CellInfoGetSubTable ( Table SubTableKey ) + ( arrayref Table SubTableKey ) ) + +(defun CellInfoLookup ( Table Key ) + ( arrayref Table Key ) +) + +(defun CellInfoLookupInBlock ( Table Block Key ) + (let ( + ( BlockTable + ( arrayref Table Block ) ) ) + (when ( tablep BlockTable ) + ( CellInfoLookup BlockTable Key ) ) ) ) + +(defun CellInfoLookupParametrizedInBlock ( Table Block Key Type Parameter ) + (let ( + ( BlockTable + ( arrayref Table Block ) ) ) + (when ( tablep BlockTable ) + ( CellInfoLookupParametrized BlockTable Key Type Parameter ) ) ) ) + +(defun CellInfoLookupTable ( Table Key Type ) + ( arrayref Table ( sprintf nil "%s(%s)" Key Type ) ) ) + +(defun CellInfoLookupParametrized ( Table Key Type Parameter ) + (let ( + ( SubTable ( CellInfoLookupTable Table Key Type ) ) ) + (when ( tablep SubTable ) + ( arrayref SubTable Parameter ) ) ) ) + +(defun CellInfoGetHeightInMeters ( Table DirectiveUnitsPerMeter ) + ( quotient + ( times ( float ( CellInfoLookup Table "bitpitch" ) ) + ( float ( CellInfoLookup Table "height" ) ) ) + DirectiveUnitsPerMeter ) ) + +(defun CellInfoGetPinLayer ( Table ) + ( CellInfoLookup Table "pinlayer" ) +) + +(defun CellInfoGetNetWireWidthInMeters ( Table NetName DirectiveUnitsPerMeter ) + (let ( + ( Ret + (cond ( + ( CellInfoLookupParametrizedInBlock Table "subcell" "wirewidth" "node" NetName ) ) + ( + ( CellInfoLookupInBlock Table "subcell" "wirewidth" ) ) + ( + ( CellInfoLookupParametrized Table "wirewidth" "node" NetName ) ) + ( + ( CellInfoLookup Table "wirewidth" ) + ) ) ) ) + (when Ret + ( quotient + Ret + DirectiveUnitsPerMeter ) ) ) ) + +(defun CellInfoGetNetWireSpacingInMeters ( Table NetName DirectiveUnitsPerMeter ) + (let ( + ( Ret + (cond ( + ( CellInfoLookupParametrizedInBlock Table "subcell" "wirespace" "node" NetName ) ) + ( + ( CellInfoLookupInBlock Table "subcell" "wirespace" ) ) + ( + ( CellInfoLookupParametrized Table "wirespace" "node" NetName ) ) + ( + ( CellInfoLookup Table "wirespace" ) ) ) ) ) + (when Ret + ( quotient + Ret + DirectiveUnitsPerMeter ) ) ) ) + +(defun CellInfoGetLayerWirePitchInMeters ( Table Layer DirectiveUnitsPerMeter ) + ( quotient + ( CellInfoLookupParametrized Table "layer_wirepitch" "layer" Layer ) + DirectiveUnitsPerMeter ) ) + +(defun CellInfoGetLayerWireSpacingInMeters ( Table Layer DirectiveUnitsPerMeter ) + ( quotient + ( CellInfoLookupParametrized Table "layer_wirespacing" "layer" Layer ) + DirectiveUnitsPerMeter ) ) + +;FIXME +(defun CellInfoGetLayerPowerGridWireWidthInMeters ( Table Layer DirectiveUnitsPerMeter ) + ( quotient + (cond ( + ( CellInfoLookupParametrized Table "layer_powergrid_wirewidth" "layer" Layer ) ) + ( + 0.72e-6 ) ) + DirectiveUnitsPerMeter ) ) + +(defun CellInfoGetLayerWireWidthInMeters ( Table Layer DirectiveUnitsPerMeter ) + ( quotient + ( CellInfoLookupParametrized Table "layer_wirewidth" "layer" Layer ) + DirectiveUnitsPerMeter ) ) + +(defun CellInfoGetLayerKeepOutPattern ( Table MetalLPP ) + ( CellInfoLookupParametrized Table "layer_keepout_pattern" "layer" MetalLPP ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/constraints.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/constraints.il new file mode 100644 index 0000000000..4a19b44ab0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/cell/constraints.il @@ -0,0 +1,307 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun ConstraintsReplaceNetWireWidth ( Net + WireWidth + ) + ( dbReplaceProp + Net + "wirewidth" + "float" + WireWidth ) ) + +(defun ConstraintsReplaceNetWireSpacing ( Net + WireSpacing + ) + ( dbReplaceProp + Net + "wirespacing" + "float" + WireSpacing ) ) + +(defun ConstraintsReplaceNetWirePriority ( Net + WirePriority + ) + ( dbReplaceProp + Net + "priority" + "float" + WirePriority ) ) + +(defun ConstraintsReplaceGlobalWireSpacing ( CellView + WireSpacing ) + ( dbReplaceProp + CellView + "wirespacing" + "float" + WireSpacing ) ) + +(defun ConstraintsReplaceGlobalWireSpacing ( CellView + WireSpacing ) + ( dbReplaceProp + CellView + "wirespacing" + "float" + WireSpacing ) ) + +(defun ConstraintsGetNetWireWidth ( Net + ) + ( PropGetPropValueForPropName + ( getq Net prop ) + "wirewidth" ) ) + +(defun ConstraintsGetNetWireSpacing ( Net + ) + ( PropGetPropValueForPropName + ( getq Net prop ) + "wirespacing" ) ) + +(defun ConstraintsGetNetWirePriority ( Net + ) + ( PropGetPropValueForPropName + ( getq Net prop ) + "priority" ) ) + +(defun ConstraintsGetGlobalWireSpacing ( CellView ) + ( PropGetPropValueForPropName + ( getq CellView prop ) + "wirewidth" ) ) + +(defun ConstraintsGetGlobalWireSpacing ( CellView ) + ( PropGetPropValueForPropName + ( getq CellView prop ) + "wirespacing" ) ) + +(defun ConstraintsGetICCNetName ( NetName ) + (cond ( + ( rexMatchp ".*-.*" NetName ) + ( sprintf nil "'%s'" NetName ) ) + ( + NetName ) ) ) + + +(defun ConstraintsPrint ( CellView ) + ( mapcar + (lambda ( Net ) + (when ( or + ( ConstraintsGetNetWireWidth + Net ) + ( ConstraintsGetNetWireSpacing + Net ) + ( ConstraintsGetNetWirePriority + Net ) ) + ( printf "Net %s\t width: %g\t spacing: %g\t priority: %d\n" + Net->name + (cond ( + ( ConstraintsGetNetWireWidth + Net ) ) + ( 0.0 ) ) + (cond ( + ( ConstraintsGetNetWireSpacing + Net ) ) + ( 0.0 ) ) + (cond ( + ( ConstraintsGetNetWirePriority + Net ) ) + ( 0 ) ) + ) ) ) + CellView->nets + ) + t ) + +(defun ConstraintsGetNetNames ( CellView + NetNamesToAvoid ) + ( mapcar + `ConstraintsGetICCNetName + ( ListDifference + CellView->nets~>name + NetNamesToAvoid + `equal + nil + ) + ) ) + +(defun ConstraintsWriteAllNetsClass_ICC ( CellView + NetNamesToAvoid + Port) + ( fprintf + Port + "define (class allnetclass " ) + + ( foreach NetName + ( ConstraintsGetNetNames + CellView + NetNamesToAvoid ) + ( fprintf + Port + ( strcat NetName " " ) ) ) + ( fprintf + Port + ")\n" ) +) + +(defun ConstraintsWriteInternalNetsClass_ICC ( CellView + NetNamesToAvoid + Port) + let( ( internalNetNames ) + internalNetNames=setof( name ConstraintsGetNetNames( CellView NetNamesToAvoid ) rexMatchp( InternalNetRegEx name )) + if( internalNetNames then + fprintf( Port "define (class internalnetclass " ) + foreach( NetName internalNetNames + fprintf( Port strcat( NetName " " ) ) ) + fprintf( Port ")\n" ) + foreach( NetName internalNetNames + fprintf( Port "circuit net %s ( priority 255 )\n" NetName) ) + ) + ) +) + + +(defun ConstraintsGetICCNetClassName ( NetName ) + ( ConstraintsGetICCNetName + ( sprintf nil "netclass_%s" + NetName ) ) ) + +(defun ConstraintsWriteNetClass_ICC ( Net + Port ) + ( fprintf + Port + "define (class %s %s)\n" + ( ConstraintsGetICCNetClassName + ( getq Net name ) ) + ( ConstraintsGetICCNetName ( getq Net name ) ) ) ) + + +(defun ConstraintsWriteGlobalWireSpacing_ICC ( CellView + ICCUnitsPerMeter + Port ) + ( fprintf + Port + "rule class_class allnetclass allnetclass (clearance %f)\n" + ( times ICCUnitsPerMeter + ( ConstraintsGetGlobalWireSpacing + CellView ) ) ) ) + +(defun ConstraintsWriteGlobalWireWidth_ICC ( CellView + ICCUnitsPerMeter + Port ) + ( fprintf + Port + "rule class_class allnetclass allnetclass (width %f)\n" + ( times ICCUnitsPerMeter + ( ConstraintsGetGlobalWireWidth + CellView ) ) ) ) + +(defun ConstraintsWriteWireSpacing_ICC ( Net + ICCUnitsPerMeter + Port ) + ( fprintf + Port + "rule class_class %s allnetclass (clearance %f)\n" + ( ConstraintsGetICCNetClassName + ( getq Net name ) ) + ( times ICCUnitsPerMeter + ( ConstraintsGetNetWireSpacing + Net ) ) + ) ) + + +(defun ConstraintsWriteWireWidth_ICC ( Net + ICCUnitsPerMeter + Port ) + ( fprintf + Port + "rule net %s (width %f)\n" + ( ConstraintsGetICCNetName ( getq Net name ) ) + ( times ICCUnitsPerMeter + ( ConstraintsGetNetWireWidth + Net ) ) + ) ) + +(defun ConstraintsDumpICCToFile ( CellView + FileName + ICCUnitsPerMeter + NetNamesToAvoid ) + (if ( not ( isWritable ( PathDirName FileName ) ) ) + ( printf + "Error: Can't dump constraints to non-writable file %s" + FileName ) + (let ( + ( Port ( outfile FileName ) ) ) + ( ConstraintsDumpICC + CellView + Port + ICCUnitsPerMeter + NetNamesToAvoid ) + ( close Port ) ) ) ) + + +(defun ConstraintsDumpICC ( CellView + Port + ICCUnitsPerMeter + NetNamesToAvoid ) + ( ConstraintsWriteAllNetsClass_ICC + CellView + NetNamesToAvoid + Port ) + ( ConstraintsWriteInternalNetsClass_ICC + CellView + NetNamesToAvoid + Port ) + ( foreach Net ( getq CellView nets ) + (when ( ConstraintsGetNetWireSpacing + Net ) + ( ConstraintsWriteNetClass_ICC + Net + Port ) + ( ConstraintsWriteWireSpacing_ICC + Net + ICCUnitsPerMeter + Port ) + ) + (when ( ConstraintsGetNetWireWidth + Net ) + ( ConstraintsWriteWireWidth_ICC + Net + ICCUnitsPerMeter + Port ) ) ) + ) + + +(defun ConstraintsDumpLayers_ICC ( LPPs + ViaNames + Port ) + ( fprintf Port "select net *\n" ) + ( fprintf Port "circuit selected (use_layer %s)\n" + ( StringUtilConvertStringListToSpaceSeperatedString + ( mapcar + `car + LPPs ) ) ) + ( fprintf Port "circuit selected (use_via %s)\n" + ( StringUtilConvertStringListToSpaceSeperatedString + ViaNames ) ) + ( fprintf Port "unselect net *\n" ) + ) + + +(defun ConstraintsConvertLPPListToViaNameList ( LPPs + ViaLibraryName + ViaNameFormat + ) + ( setof + ViaName + ( maplist + (lambda ( Rest ) + (let ( + ( ThisLayer ( car ( car Rest ) ) ) + ( ThatLayer ( car ( cadr Rest ) ) ) ) + (when ( and ThisLayer ThatLayer ) + ( AutoPinGetViaMasterName + ViaLibraryName + ViaNameFormat + ThisLayer + ThatLayer ) ) ) ) + LPPs ) + ViaName ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/chain.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/chain.il new file mode 100644 index 0000000000..54e985cfea --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/chain.il @@ -0,0 +1,227 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun ChainCalculateFolds ( ChainInfo + ColumnWidth + UserUnitsPerMeter + PreferEvenFolds ) + "Calculate the number of folds for a ChainInfo." + (unless ( fboundp `PDKFoldChain ) + (error "The PDK pdkinfo.il must define (PDKFoldChain + ColumnWidth + OverrideFolds + Folds + MaxFolds)")) + (let ( + ( Folds + ( length + ( PDKFoldChain + ( ComponentInfoGetStrengthFromChainInfo ChainInfo ) + ColumnWidth + nil + 0 + 16 + ) ) ) ) + (if ( and PreferEvenFolds + ( greaterp Folds 1) + ( equal ( mod Folds 2 ) 1 ) ) + ( plus Folds 1 ) + Folds ) ) ) + + +(defun ChainCreateFoldedChainsFromChainInfos ( CellView + ChainInfos + Location ) + "Instantiates a list of ChainInfos in a row starting at given Location." + (let ( + ( X ( car Location ) ) ) + ( mapcar + (lambda ( ChainInfo ) + ( ComponentInfoCreateComponentFromComponentInfo + CellView + ChainInfo + ( list + ( setq X ( plus X ( ComponentInfoGetWidth ChainInfo ) ) ) + ( cadr Location ) ) ) ) + ChainInfos ) ) ) + + +(defun ChainFoldChainInfoToChainInfos ( CellView ChainInfo ColumnWidth UserUnitsPerMeter RoundToNearest PreferEvenFolds ) + (let ( + ( ChainFolds ( ChainCalculateFolds ChainInfo ColumnWidth UserUnitsPerMeter PreferEvenFolds ) ) ) + ( ChainFoldChainInfoToChainInfosOverrideFolds + CellView + ChainInfo + ChainFolds + RoundToNearest ) ) ) + + +(defun ChainFoldChainInfoToChainInfosOverrideFolds ( CellView ChainInfo ChainFolds RoundToNearest ) + "Constructs folded ChainInfos from a ChainInfo according to PDKFoldChain." + (unless ( fboundp `PDKFoldChain ) + (error "The PDK pdkinfo.il must define (PDKFoldChain + ColumnWidth + OverrideFolds + Folds + MaxFolds)")) + + (let ( + ( OldConnTable ( ComponentInfoGetConnTable ChainInfo ) ) + ( ChainName ( ComponentInfoGetName ChainInfo ) ) + ( ChainParameters ( ComponentInfoGetParameterList ChainInfo ) ) + ( Parity ( ComponentInfoGetParity ChainInfo ) ) + ( WidthParameterName ( ComponentInfoGetWidthParameterNameFromChainInfo ChainInfo ) ) + ( ChainStrength ( ComponentInfoGetStrengthFromChainInfo ChainInfo ) ) + ( ChainHeight ( ComponentInfoGetHeight ChainInfo ) ) + ( ChainWidth ( ComponentInfoGetWidth ChainInfo ) ) + ( Position ( ComponentInfoGetPosition ChainInfo ) ) + ( BBox ( ComponentInfoGetBBox ChainInfo ) ) + ( HParity ( ComponentInfoGetHParity ChainInfo ) ) + ( BottomCSInfo ( ComponentInfoGetBottomCSInfo ChainInfo ) ) + ( TopCSInfo ( ComponentInfoGetTopCSInfo ChainInfo ) ) + ) + (let ( + ( I 0 ) + ( ChainInfoList nil ) + ( FoldedChainStrengths + ( PDKFoldChain + ChainStrength + 1e9 + t + ChainFolds + ChainFolds + ) ) ) + ( foreach + FoldedChainStrength + FoldedChainStrengths + (let ( + ( OldBottomSymbol ( DominoGetBottomSymbol ChainInfo ) ) + ( OldTopSymbol ( DominoGetTopSymbol ChainInfo ) ) + ( OldSourceNetName ( arrayref OldConnTable "S" ) ) + ( OldDrainNetName ( arrayref OldConnTable "D" ) ) ) + (let ( + ( NewConnTable ( TableCopy OldConnTable ) ) + ( NewSourceNetName + OldSourceNetName ) + ( NewDrainNetName + OldDrainNetName ) + ( NewBottomSymbol + OldBottomSymbol ) + ( NewTopSymbol + OldTopSymbol ) + ) + + + ( setarray NewConnTable "S" NewSourceNetName ) + ( setarray NewConnTable "D" NewDrainNetName ) + (let ( + ( NewChainInfo + ( ComponentInfoCreateComponentInfo + ( ComponentInfoGetLibCellView ChainInfo ) + (cond ( + ( rexMatchp ".*\\.[0-9]+" ChainName ) + (if ( equal ChainFolds 0 ) ChainName + ( sprintf nil "%s%d" ChainName I ) + ) ) + ( + t + ( sprintf nil "%s.%d" ChainName I ) ) ) + ChainParameters + (if Parity + NewTopSymbol + NewBottomSymbol ) + (if Parity + NewBottomSymbol + NewTopSymbol ) + NewConnTable + ChainHeight + ChainWidth + Position + BBox + HParity + BottomCSInfo + TopCSInfo + ) ) ) + + ( ComponentInfoSetStrengthForChainInfo + NewChainInfo + FoldedChainStrength ) + + ( setq ChainInfoList + ( tconc ChainInfoList NewChainInfo + ) ) + ( setq I ( plus I 1 ) ) + + ) ) ) ) + ( car ChainInfoList ) ) ) ) + + + +(defun ChainFoldToChainInfos ( CellView Chain ColumnWidth UserUnitsPerMeter RoundToNearest PreferEvenFolds ) + "Converts a chain instance into a ChainInfos that isn't part of the database" + ( ChainFoldChainInfoToChainInfos + CellView + ( ComponentInfoCreateComponentInfoFromComponent Chain ) + ColumnWidth + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) ) + +(defun ChainFoldToChainInfosOverrideFolds ( CellView Chain ChainFolds RoundToNearest ) + ( ChainFoldChainInfoToChainInfosOverrideFolds + CellView + ( ComponentInfoCreateComponentInfoFromComponent Chain ) + ChainFolds + RoundToNearest ) ) + +(defun ChainFoldChains ( CellView + Chains + ColumnWidth + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) + ( mapcar + (lambda ( Chain ) + ( ChainCreateFoldedChainsFromChainInfos + CellView + ( ChainFoldToChainInfos CellView Chain ColumnWidth UserUnitsPerMeter RoundToNearest PreferEvenFolds ) + ( getq Chain xy ) ) + ( dbDeleteObject Chain ) ) + Chains ) ) + +(defun ChainFoldChainsOverrideFolds ( CellView + Chains + ChainFolds + RoundToNearest ) + ( mapcar + (lambda ( Chain ) + ( ChainCreateFoldedChainsFromChainInfos + CellView + ( ChainFoldToChainInfosOverrideFolds CellView Chain ChainFolds RoundToNearest ) + ( getq Chain xy ) + ) + ( dbDeleteObject Chain ) ) + Chains ) ) + + +(defun ChainFoldAllChains ( CellView + ChainLibCellPairRegExs + ColumnWidth + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) + + (let ( + ( Chains ( cadr ( NameFilterInstances + ( getq CellView instances ) + ChainLibCellPairRegExs ) ) ) ) + ( ChainFoldChains + CellView + Chains + ColumnWidth + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/compactsuperstacks.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/compactsuperstacks.il new file mode 100644 index 0000000000..791c3e5aa9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/compactsuperstacks.il @@ -0,0 +1,380 @@ +;; Copyright 2003 Fulcrum Microsystems. All rights reserved. +;; $Id$ +;; $DateTime$ +;; $Author$ + +; Function: CompactSuperstacks +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Compact the superstacks +; +; +; + +(defun CompactSuperstacks ( CellView ) + + (let ( + ( RoundToNearest ManufacturingGrid ) + ( InstanceMap + ( NameMakeInstanceMapFromCellView + CellView + FoldableCellLibCellPairRegExs ) ) + ( AllStacks + ( cadr + ( NameFilterInstances + ( getq CellView instances ) + SuperStackLibCellPairRegExs ) ) ) ) + ( foreach + Column + ( PlacementRegionsGetCellRegionDataColumnList + CellRegionData ) + (let ( + ( NPRegionParity ( PlacementRegionGetNPRegionParity Column ) ) + ( ColumnBBox ( PlacementRegionGetColumnBBox Column ) ) ) + ;sort the stacks in this column by y location + (let ( + ( Stacks + ( sort + ( setof Stack AllStacks + ( and ( getq Stack bBox ) + ( RangeIsNumberInRangeClose + ( car ( getq Stack xy ) ) + ( RectGetXRange ColumnBBox ) + 1e-9 ) ) ) + (lambda ( X Y ) + ( lessp ( cadar ( getq X bBox ) ) + ( cadar ( getq Y bBox ) ) ) ) ) ) ) + + ;remove this column's stacks from the list of stacks + ( setq AllStacks ( ListDifference + AllStacks + Stacks + `equal + nil ) ) + ;Break up the stacks according to the type + ;i.e. split up NMOS PMOS GATE superstacks + ;split if the run length exceeds 5, to aid in spacing + ;things out + (let ( + ( StackClumps + ( ListSplitOnPredicate + Stacks + (lambda ( C1 C2 ) + (let ( + ( Split + ( and + ( exists + C + ( list C1 C2 ) + ( equal + ( getq C cellName ) + GateSuperStackCellName ) ) + ( exists + C + ( list C1 C2 ) + ( not ( equal + ( getq C cellName ) + GateSuperStackCellName ) ) ) ) ) ) + Split ) ) ) ) ) + ;Inline the stacks into components + (let ( + ( Clumps + ( mapcar + (lambda ( StackClump ) + ( ListNonDestructiveMapCan + (lambda ( Stack ) + ( InlineSuperStack + CellView + CellView + InstanceMap + InstanceMap + Stack + "netlist" + nil + FoldableCellLibCellPairRegExs ) ) + StackClump + ) ) + StackClumps ) ) ) + ;This is all the components in the column + (let ( + ( Components + ( ListNonDestructiveMapCan + (lambda ( Clump ) Clump ) + Clumps ) ) ) + ;Derive width data of all the components in this column only + (let ( + ( NWidthData + ( NPSearchGetWidthData + ( cadr ( NameFilterInstances + Components + GateLibCellPairRegExs ) ) + ( cadr ( NameFilterInstances + Components + NChainLibCellPairRegExs ) ) + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ( times UserUnitsPerMeter TransistorMinimumContactableWidth ) + ( times UserUnitsPerMeter TransistorDiffusionToBBoxDistance ) + MaximumComponentWidthRatio + ( times UserUnitsPerMeter NRegionOffsetFromColumnCenter ) + ( times UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectiveTable + Metal3LPP + DirectiveUnitsPerMeter ) ) + MaximumNColumnWidth + UserUnitsPerMeter + t + PreferEvenFolds + ( times UserUnitsPerMeter ExtraGateWidth ) + ?MaxTransistorFolds 1 + ) ) + ( PWidthData + ( NPSearchGetWidthData + ( cadr ( NameFilterInstances + Components + GateLibCellPairRegExs ) ) + ( cadr ( NameFilterInstances + Components + PChainLibCellPairRegExs ) ) + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ( times UserUnitsPerMeter TransistorMinimumContactableWidth ) + ( times UserUnitsPerMeter TransistorDiffusionToBBoxDistance ) + MaximumComponentWidthRatio + ( times UserUnitsPerMeter PRegionOffsetFromColumnCenter ) + ( times UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectiveTable + Metal3LPP + DirectiveUnitsPerMeter ) ) + MaximumPColumnWidth + UserUnitsPerMeter + nil + PreferEvenFolds + ( times UserUnitsPerMeter ExtraGateWidth ) + ?MaxTransistorFolds 1 + ) ) ) + ;binary search over the possible columns widths so as to maximally compact the resultant superstacks + (let ( + ( MinimumNIndex + ( BinarySearchFindSmallest + 0 + ( difference + ( length + ( NPSearchGetWidthVectorFromWidthData + NWidthData ) ) 1 ) + (lambda ( Trial ) + ( geqp + ( NPSearchGetWidthFromIndex + NWidthData + Trial ) + ( NPSearchGetMinFitWidthFromWidthData + NWidthData ) ) ) + nil ) ) + ( MinimumPIndex + ( BinarySearchFindSmallest + 0 + ( difference + ( length + ( NPSearchGetWidthVectorFromWidthData + PWidthData ) ) 1 ) + (lambda ( Trial ) + ( geqp + ( NPSearchGetWidthFromIndex + PWidthData + Trial ) + ( NPSearchGetMinFitWidthFromWidthData + PWidthData ) ) ) + nil ) ) + ( MaximumNIndex + ( BinarySearchFindGreatest + 0 + ( difference + ( length + ( NPSearchGetWidthVectorFromWidthData + NWidthData ) ) 1 ) + (lambda ( Trial ) + ( leqp + ( NPSearchGetWidthFromIndex + NWidthData + Trial ) + NWidth ) ) + nil ) ) + ( MaximumPIndex + ( BinarySearchFindGreatest + 0 + ( difference + ( length + ( NPSearchGetWidthVectorFromWidthData + PWidthData ) ) 1 ) + (lambda ( Trial ) + ( leqp + ( NPSearchGetWidthFromIndex + PWidthData + Trial ) + PWidth ) ) + nil ) ) ) + ( setq MinimumNIndex ( min MinimumNIndex + MaximumNIndex ) ) + ( setq MinimumPIndex ( min MinimumPIndex + MaximumPIndex ) ) + (let ( + ( TrialPair + ( NPSearchGetSmallestFittingTrialPairForColumn + CellView + ( setof Clump Clumps + ( equal ( getq ( car Clump ) libName ) + GateLibraryName ) ) + ( setof Clump Clumps + ( equal ( getq ( car Clump ) libName ) + StackLibraryName ) ) + NChainLibCellPairRegExs + PChainLibCellPairRegExs + NWidthData + PWidthData + MinimumNIndex + MinimumPIndex + MaximumNIndex + MaximumPIndex + ( times UserUnitsPerMeter + NRegionOffsetFromColumnCenter ) + ( times UserUnitsPerMeter + PRegionOffsetFromColumnCenter ) + NColumnWidthParamName + PColumnWidthParamName + ( difference + ( RectGetHeight ColumnBBox ) + 1.15 ) + SuperStackLibraryName + GateSuperStackCellName + NSuperStackCellName + PSuperStackCellName + SuperStackViewName + UserUnitsPerMeter + RoundToNearest + ( list MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight ) + GNDNetName + VddNetName + PreferEvenFolds + nil ) ) ) + (let ( + ( NColumnWidth + ( NPSearchGetWidthFromIndex + NWidthData + ( car TrialPair ) ) ) + ( PColumnWidth + ( NPSearchGetWidthFromIndex + PWidthData + ( cadr TrialPair ) ) ) ) + + ;re-instantiate the superstack groups + ( FigStackClumps + ( mapcar + `SuperStackCompactStackGroup + ;fold the components first + ( mapcar + (lambda ( Clump ) + (cond ( + ;gate folding + ( equal ( getq ( car Clump ) libName ) + GateLibraryName ) + ( NPSearchFoldGates + Clump + NColumnWidthParamName + PColumnWidthParamName + NColumnWidth + PColumnWidth + UserUnitsPerMeter ) + ( SuperStackCreateStackGroupsFromClumpUsingPDKInfo + CellView + Clump ) ) + ( + ;chains + (let ( + ( NChains ( cadr ( NameFilterInstances + Clump + NChainLibCellPairRegExs ) ) ) + ( PChains ( cadr ( NameFilterInstances + Clump + PChainLibCellPairRegExs ) ) ) ) + + ( list + ( NPSearchRefoldAndChainChains + CellView + NChains + SuperStackLibraryName + NSuperStackCellName + SuperStackViewName + NChainPrefix + NColumnWidth + ( times + UserUnitsPerMeter + NRegionOffsetFromColumnCenter ) + UserUnitsPerMeter + RoundToNearest + ( list MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight ) + GNDNetName + VddNetName + PreferEvenFolds + ?Align + (cond ( + NPRegionParity + "ll" ) + ( + "lr" ) ) + ) + ( NPSearchRefoldAndChainChains + CellView + PChains + SuperStackLibraryName + PSuperStackCellName + SuperStackViewName + PChainPrefix + PColumnWidth + ( times + UserUnitsPerMeter + PRegionOffsetFromColumnCenter ) + UserUnitsPerMeter + RoundToNearest + ( list MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight ) + GNDNetName + VddNetName + PreferEvenFolds + ?Align + (cond ( + NPRegionParity + "lr" ) + ( + "ll" ) ) + ) ) ) ) ) ) + Clumps ) ) + ( RectGetBottom ColumnBBox ) + ) + ) ) ) ) ) ) ) ) ) ) + + ;space out the superstacks + (when t + ( DeCompactVerticalKeepOrderFromCellRegionData + CellView + CellRegionData + `DeCompactVerticalKeepOrderDefault + ( list + ( times UserUnitsPerMeter ManufacturingGrid ) + t ) ) + ) + + ;( dbSave CellView ) + ) +CellView +) + + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/componentinfo.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/componentinfo.il new file mode 100644 index 0000000000..80279c19ab --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/componentinfo.il @@ -0,0 +1,366 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +/*DOC + +A ComponentInfo is a duplication of the instance database object, with some extras for dealing with components like contact sharing proeprties and special parameters like strength. The advantage over using instances is that we don't have to worry about dirtying any databases, and it is more efficient.
    + +This module has get,set functions, functions for converting between instances and ComponentInfos, and functions for dealing with connectivity/parameters.
    + +Meaning of some properties:
    +
    +
    TopCSInfo
    A hierProp that contains the contact sharing properties of of the top part of the component. +
    BottomCSInfo
    A hierProp that contains the contact sharing properties of of the bottom part of the component. +
    Parity
    The orientation about the x axis of the component. nil for R0; t for MX +
    HParity
    The orientation about the y axis of the component. nil for R0; t for MY +
    Location
    Location of the component. +
    BBox
    Bounding box of the component. +
    Height
    Height of bounding box. +
    Widdh
    Widdh of bounding box. +
    Multiplicity
    The number of transistors to implement a component. +
    Strength
    The strength of the transistors in a component, corresponding to a transistor width parameter. Gates have an n and a p strength with a parameter name like NW2,PW4, etc, where the number represents the multiplicity. Stacks have either an n strength or a p strength with the same naming convention. + +
    +*/ + + +(defun ComponentInfoCreateConnTable ( Component ) + "Create a connection table for an instance. Maps component's terminal name to external net name." + (let ( + ( ConnTable ( makeTable `bla nil ) ) ) + ( foreach InstTerm ( getq Component conns ) + (let ( + ( Term ( getq ( getq InstTerm term ) name ) ) + ( Net ( getq ( getq InstTerm net ) name ) ) ) + (when ( and Term Net ) + ( setarray ConnTable Term Net ) ) ) ) + ConnTable ) ) + +(defun ComponentInfoCreateComponentInfoFromComponent ( Component ) + "Creates a ComponentInfo from an instance of a component." + (let ( + ( LibCellView + ( list ( getq Component libName ) + ( getq Component cellName ) + ( getq Component viewName ) ) ) + ( ParameterList ( copy ( PCellGetParameterList Component ) ) ) + ( ConnTable ( ComponentInfoCreateConnTable Component ) ) ) + (let ( + ( BottomCSInfo + ( PropGetPropValueForPropName + ( getq ( getq Component master ) prop ) + "csBottom" ) ) + ( TopCSInfo + ( PropGetPropValueForPropName + ( getq ( getq Component master ) prop ) + "csTop" ) ) ) + (let ( + ( BottomTerminalNames + ( list + ( PropGetPropValueForPropName + BottomCSInfo + "NTerminal" ) + ( PropGetPropValueForPropName + BottomCSInfo + "PTerminal" ) ) ) + ( TopTerminalNames + ( list + ( PropGetPropValueForPropName + TopCSInfo + "NTerminal" ) + ( PropGetPropValueForPropName + TopCSInfo + "PTerminal" ) ) ) ) + (let ( + ( Ret + ( ComponentInfoCreateComponentInfo + LibCellView + ( getq Component name ) + ParameterList + ( mapcar + (lambda ( TerminalName ) + ( arrayref ConnTable TerminalName ) ) + BottomTerminalNames ) + ( mapcar + (lambda ( TerminalName ) + ( arrayref ConnTable TerminalName ) ) + TopTerminalNames ) + ConnTable + ( RectGetHeight ( getq Component bBox ) ) + ( RectGetWidth ( getq Component bBox ) ) + ( getq Component xy ) + ( getq Component bBox ) + (if ( or + ( equal ( getq Component orient ) "R0" ) + ( equal ( getq Component orient ) "MX" ) ) + nil t ) + ( PropGetPropValueForPropName + ( getq ( getq Component master ) prop ) + "csBottom" ) + ( PropGetPropValueForPropName + ( getq ( getq Component master ) prop ) + "csTop" ) ) ) ) + + ( DominoSetParity Ret (if ( or + ( equal ( getq Component orient ) "R0" ) + ( equal ( getq Component orient ) "MY" ) ) + nil t ) ) + + Ret + + ) ) ) ) ) + +(defun ComponentInfoCreateComponentInfo ( LibCellView + Name + Params + BottomNetNames + TopNetNames + Conns + Height + Width + Position + BBox + HParity + BottomCSInfo + TopCSInfo + ) + "Constructs a ComponentInfo" + (let ( + ( ComponentInfo ( makeTable `chaininfo ) ) ) + ( setarray ComponentInfo `libcellview LibCellView ) + ( setarray ComponentInfo `params Params ) + ( setarray ComponentInfo `conns Conns ) + ( setarray ComponentInfo `height Height ) + ( setarray ComponentInfo `width Width ) + ( setarray ComponentInfo `position Position ) + ( setarray ComponentInfo `bBox BBox ) + ( setarray ComponentInfo `hparity HParity ) + ( setarray ComponentInfo `bottom_csinfo BottomCSInfo ) + ( setarray ComponentInfo `top_csinfo TopCSInfo ) + + ( DominoInit + ComponentInfo + Name + BottomNetNames + TopNetNames ) + ComponentInfo ) ) + +(defun ComponentInfoCopy ( ComponentInfo ) + ( TableCopy ComponentInfo ) ) + +(defun ComponentInfoGetLibCellView ( ComponentInfo ) + ( arrayref ComponentInfo `libcellview ) ) + +(defun ComponentInfoGetName ( ComponentInfo ) + ( arrayref ComponentInfo `name ) ) + +(defun ComponentInfoGetParameterList ( ComponentInfo ) + ( arrayref ComponentInfo `params ) ) + +(defun ComponentInfoGetParity ( ComponentInfo ) + ( arrayref ComponentInfo `parity ) ) + +(defun ComponentInfoGetConnTable ( ComponentInfo ) + ( arrayref ComponentInfo `conns ) ) + +(defun ComponentInfoGetHeight ( ComponentInfo ) + ( arrayref ComponentInfo `height ) ) + +(defun ComponentInfoGetWidth ( ComponentInfo ) + ( arrayref ComponentInfo `width ) ) + +(defun ComponentInfoGetPosition ( ComponentInfo ) + ( arrayref ComponentInfo `position ) ) + +(defun ComponentInfoGetBBox ( ComponentInfo ) + ( arrayref ComponentInfo `bBox ) ) + +(defun ComponentInfoGetHParity ( ComponentInfo ) + ( arrayref ComponentInfo `hparity ) ) + +(defun ComponentInfoGetBottomCSInfo ( ComponentInfo ) + (if ( ComponentInfoGetParity ComponentInfo ) + ( arrayref ComponentInfo `top_csinfo ) + ( arrayref ComponentInfo `bottom_csinfo ) ) ) + +(defun ComponentInfoGetTopCSInfo ( ComponentInfo ) + (if ( ComponentInfoGetParity ComponentInfo ) + ( arrayref ComponentInfo `bottom_csinfo ) + ( arrayref ComponentInfo `top_csinfo ) ) ) + + +(defun ComponentInfoGetNStrength ( ComponentInfo ) + ( nth 2 + ( ComponentInfoGetNWidthParameter + ComponentInfo ) ) ) + +(defun ComponentInfoGetPStrength ( ComponentInfo ) + ( nth 2 + ( ComponentInfoGetPWidthParameter + ComponentInfo ) ) ) + +(defun ComponentInfoGetNStrengthFromComponent ( Component ) + ( nth 2 + ( ComponentInfoGetNWidthParameterFromParameterList + ( PCellGetParameterList Component ) ) ) ) + +(defun ComponentInfoGetPStrengthFromComponent ( Component ) + ( nth 2 + ( ComponentInfoGetPWidthParameterFromParameterList + ( PCellGetParameterList Component ) ) ) ) + +(defun ComponentInfoGetNMultiplicityFromComponent ( Component ) + (let ( + ( ParamName + ( car + ( ComponentInfoGetNWidthParameterFromParameterList + ( PCellGetParameterList Component ) ) ) ) ) + (cond ( + ParamName + ( rexMatchp "NW\\([0-9]*\\)" ParamName ) + ( atoi ( rexSubstitute "\\1" ) ) ) + ( + 0 ) ) ) ) + +(defun ComponentInfoGetPMultiplicityFromComponent ( Component ) + (let ( + ( ParamName + ( car + ( ComponentInfoGetPWidthParameterFromParameterList + ( PCellGetParameterList Component ) ) ) ) ) + (cond ( + ParamName + ( rexMatchp "PW\\([0-9]*\\)" ParamName ) + ( atoi ( rexSubstitute "\\1" ) ) ) + ( + 0 ) ) ) ) + +(defun ComponentInfoGetNLengthFromComponent ( Component ) + ( nth 2 + ( ComponentInfoGetNLengthParameterFromParameterList + ( PCellGetParameterList Component ) ) ) ) + +(defun ComponentInfoGetPLengthFromComponent ( Component ) + ( nth 2 + ( ComponentInfoGetPLengthParameterFromParameterList + ( PCellGetParameterList Component ) ) ) ) + + +(defun ComponentInfoGetNLengthParameterFromParameterList ( ParameterList ) + ( rexCompile "NL\\([0-9]*\\)" ) + ( car ( exists Parameter + ParameterList + ( rexExecute ( car Parameter ) ) ) ) ) + +(defun ComponentInfoGetPLengthParameterFromParameterList ( ParameterList ) + ( rexCompile "PL\\([0-9]*\\)" ) + ( car ( exists Parameter + ParameterList + ( rexExecute ( car Parameter ) ) ) ) ) + +(defun ComponentInfoGetNWidthParameterFromParameterList ( ParameterList ) + ( rexCompile "NW\\([0-9]*\\)" ) + ( car ( exists Parameter + ParameterList + ( rexExecute ( car Parameter ) ) ) ) ) + +(defun ComponentInfoGetPWidthParameterFromParameterList ( ParameterList ) + ( rexCompile "PW\\([0-9]*\\)" ) + ( car ( exists Parameter + ParameterList + ( rexExecute ( car Parameter ) ) ) ) ) + +(defun ComponentInfoGetNWidthParameter ( ComponentInfo ) + ( ComponentInfoGetNWidthParameterFromParameterList + ( ComponentInfoGetParameterList ComponentInfo ) ) ) + +(defun ComponentInfoGetPWidthParameter ( ComponentInfo ) + ( ComponentInfoGetPWidthParameterFromParameterList + ( ComponentInfoGetParameterList ComponentInfo ) ) ) + +(defun ComponentInfoGetNWidthParameterName ( ComponentInfo ) + ( car ( ComponentInfoGetNWidthParameter ComponentInfo ) ) ) + +(defun ComponentInfoGetPWidthParameterName ( ComponentInfo ) + ( car ( ComponentInfoGetPWidthParameter ComponentInfo ) ) ) + +(defun ComponentInfoGetWidthParameterNameFromChainInfo ( ChainInfo ) + (cond ( + ( stringp ( ComponentInfoGetNWidthParameterName ChainInfo ) ) + ( ComponentInfoGetNWidthParameterName ChainInfo ) ) + ( + ( stringp ( ComponentInfoGetPWidthParameterName ChainInfo ) ) + ( ComponentInfoGetPWidthParameterName ChainInfo ) ) ) ) + +(defun ComponentInfoGetStrengthFromChainInfo ( ChainInfo ) + (let ( + ( N ( ComponentInfoGetNStrength ChainInfo ) ) + ( P ( ComponentInfoGetPStrength ChainInfo ) ) ) + (cond ( ( numberp N ) N ) ( ( numberp P ) P ) ) ) ) + +(defun ComponentInfoSetHeight ( ComponentInfo Height ) + ( setarray ComponentInfo `height Height ) ) + +(defun ComponentInfoSetWidth ( ComponentInfo Width ) + ( setarray ComponentInfo `width Width ) ) + +(defun ComponentInfoSetParity ( ComponentInfo Parity ) + ( setarray ComponentInfo `parity Parity ) ) + +(defun ComponentInfoSetPosition ( ComponentInfo Position ) + ( setarray ComponentInfo `position ) ) + +(defun ComponentInfoSetStrengthForChainInfo ( ChainInfo NewChainStrength ) + (let ( + ( ChainParameters ( ComponentInfoGetParameterList ChainInfo ) ) + ( ChainStrength ( ComponentInfoGetStrengthFromChainInfo ChainInfo ) ) + ( WidthParameterName ( ComponentInfoGetWidthParameterNameFromChainInfo ChainInfo ) ) ) + ( setarray ChainInfo `params + ( subst ( list WidthParameterName + "float" + NewChainStrength ) + ( list WidthParameterName + "float" + ChainStrength ) + ChainParameters ) ) ) ) + +(defun ComponentInfoCreateComponentFromComponentInfo ( CellView + ComponentInfo + Location ) + "Converts a ComponentInfo into an instance at a given Location in given CellView" + (let ( + ( LibCellView ( ComponentInfoGetLibCellView ComponentInfo ) ) ) + (let ( + ( Instance + ( dbCreateParamInstByMasterName + CellView + ( car LibCellView ) + ( cadr LibCellView ) + ( caddr LibCellView ) + ( ComponentInfoGetName ComponentInfo ) + Location + (if ( ComponentInfoGetParity ComponentInfo ) "MX" "R0" ) + 1 + ( append + ( ComponentInfoGetParameterList ComponentInfo ) + ( append + (if ( ComponentInfoGetNWidthParameterName ComponentInfo ) + ( list + ( list ( ComponentInfoGetNWidthParameterName ComponentInfo ) + "float" + ( ComponentInfoGetNStrength ComponentInfo ) ) ) ) + (if ( ComponentInfoGetPWidthParameterName ComponentInfo ) + ( list + ( list ( ComponentInfoGetPWidthParameterName ComponentInfo ) + "float" + ( ComponentInfoGetPStrength ComponentInfo ) ) ) ) ) ) ) ) ) + ( mapcar + (lambda ( Conn ) + ( dbCreateConnByName + ( dbMakeNet CellView ( cadr Conn ) ) + Instance + ( car Conn ) ) ) + ( tableToList ( ComponentInfoGetConnTable ComponentInfo ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/createsuperstacks.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/createsuperstacks.il new file mode 100644 index 0000000000..771dbc9293 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/createsuperstacks.il @@ -0,0 +1,58 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: CreateSuperStacks +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Create Super Stacks +; +; +; + +defun( CreateSuperStacks ( CellView ) + + ;stack the clumps + ( mapcar + (lambda ( Clump ) + ( SuperStackCreateStackGroupsFromClumpUsingPDKInfo + CellView + Clump ) ) + ;inline the sub-clumps + ( ListNonDestructiveMapCan + (lambda ( X ) + X ) + ;break the clumps into sub-clumps + ( mapcar + (lambda ( Clump ) + ( ListSplitOnPredicate + ( sort Clump (lambda ( C1 C2 ) ( lessp ( RectGetBottom ( getq C1 bBox ) ) + ( RectGetBottom ( getq C2 bBox ) ) ) ) ) + (lambda ( C1 C2 ) + ( and + ( exists C ( list C1 C2 ) + ( equal ( getq C libName ) GateLibraryName ) ) + ( exists C ( list C1 C2 ) + ( not ( equal ( getq C libName ) GateLibraryName ) ) ) ) ) ) ) + ;clumps of components + ( mapcar + `cadr + ( tableToList + ( FigGetClumpTable + ( cadr + ( NameFilterInstances + ( getq CellView instances ) + ( append + GateLibCellPairRegExs + ( append + NChainLibCellPairRegExs + PChainLibCellPairRegExs ) ) ) ) ) ) ) ) ) ) + + + ( dbSave CellView ) + CellView +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domain.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domain.il new file mode 100644 index 0000000000..4761fe09b6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domain.il @@ -0,0 +1,212 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +Creates a DomainTable whose values are the domains of a cell. +This is used in +A domain is a set of componentinfos connected through a non-power net +*/ + +(defun SuperStackGetDomainTable ( ComponentInfos + NetTable + PowerSymbol ) + + (let ( + ;maps net name to domain + ( DomainTable ( makeTable `domain nil ) ) + ;maps chain name to chain info + ( ComponentInfoTable ( makeTable `chaininfos nil ) ) ) + ( foreach ComponentInfo ComponentInfos + ( setarray ComponentInfoTable ( ComponentInfoGetName ComponentInfo ) ComponentInfo ) ) + + ( SuperStackTraverseNetGraph + ComponentInfoTable + DomainTable + NetTable + nil + nil + PowerSymbol + PowerSymbol ) + DomainTable ) ) + +(defun SuperStackGetDomains ( ComponentInfos + NetTable + PowerSymbol ) + + (let ( + ( DomainTable ( SuperStackGetDomainTable + ComponentInfos + NetTable + PowerSymbol ) ) ) + + ; ( printf "Domains\n" ) + ; ( foreach Table ( mapcar `cadr ( tableToList DomainTable ) ) + ; ( printf "...\n" ) + ; ( DominoPrintDominoList ( mapcar `cadr ( tableToList Table ) ) ) ) + ; ( shudder ) + (let ( + ( Domains ( mapcar + (lambda ( Table ) + ( mapcar `cadr ( tableToList Table ) ) ) + ( mapcar `cadr ( tableToList DomainTable ) ) ) ) + ( DomainList nil ) ) + ( foreach Domain Domains + (if ( not ( exists OtherDomain DomainList + ( exists ComponentInfo Domain + ( exists OtherComponentInfo OtherDomain + ( equal ComponentInfo OtherComponentInfo ) ) ) ) ) + ( setq DomainList ( cons Domain DomainList ) ) ) ) + (let ( + ( LeftOver ( ListDifference + ComponentInfos + ( ListNonDestructiveMapCan + (lambda ( x ) x ) + DomainList ) + (lambda ( x y ) ( equal x y ) ) + nil ) ) ) + (if LeftOver + ( cons LeftOver DomainList ) + DomainList ) ) ) ) ) + + +(defun SuperStackGetComponentInfosOnNetName ( ComponentInfoTable NetTable NetName ) + ( mapcar + `car + ( SuperStackGetComponentInfoSidePairsOnNetName ComponentInfoTable NetTable NetName ) ) ) + +(defun SuperStackGetComponentNameSidePairsOnNetName ( ComponentInfoTable NetTable Symbol NetName ) +; ( println NetName ) + (let ( + ( AttachedInstanceNames + ( ListRemoveDuplicatesFromStringList + ( ListNonDestructiveMapCan + (lambda ( Names ) Names ) + ( mapcar `cadr ( tableToList ( arrayref NetTable NetName ) ) ) ) ) ) ) + ( ListApplyFuncToListAndAccumulateNonNilResults + AttachedInstanceNames + (lambda ( ComponentInfoName ) + (let ( + ( ComponentInfo ( arrayref ComponentInfoTable ComponentInfoName ) ) ) + (when ComponentInfo + (cond ( + ( SuperStackSymbolMatch + ( DominoGetTopSymbol ComponentInfo ) + Symbol ) + ( list ComponentInfoName t ) ) + ( + ( SuperStackSymbolMatch + ( DominoGetBottomSymbol ComponentInfo ) + Symbol ) + ( list ComponentInfoName nil ) ) ) ) ) ) + nil ) ) ) + +(defun SuperStackGetComponentInfosOnSymbol ( ComponentInfoTable NetTable Symbol ) + (when ( or ( car Symbol ) ( cadr Symbol ) ) + (let ( + ( ComponentNameSidePairsOnLeftNet + (if ( car Symbol ) + ( SuperStackGetComponentNameSidePairsOnNetName + ComponentInfoTable + NetTable + Symbol + ( car Symbol ) ) ) ) + ( ComponentNameSidePairsOnRightNet + (if ( cadr Symbol ) + ( SuperStackGetComponentNameSidePairsOnNetName + ComponentInfoTable + NetTable + Symbol + ( cadr Symbol ) ) ) ) ) + ( mapcar + (lambda ( ComponentNameSidePair ) + ( arrayref ComponentInfoTable ( car ComponentNameSidePair ) ) ) + (cond ( + ( null ( car Symbol ) ) + ComponentNameSidePairsOnRightNet ) + ( + ( null ( cadr Symbol ) ) + ComponentNameSidePairsOnLeftNet ) + ( + t + ( ListUnionNoTableElements + ComponentNameSidePairsOnLeftNet + ComponentNameSidePairsOnRightNet ) ) ) ) ) ) ) + + +(defun SuperStackDomainGetOtherSymbol ( ComponentInfo + Symbol ) + (if ( car ( DominoGetTopSymbol ComponentInfo ) ) + (if ( equal ( car ( DominoGetTopSymbol ComponentInfo ) ) ( car Symbol ) ) + ( DominoGetBottomSymbol ComponentInfo ) + ( DominoGetTopSymbol ComponentInfo ) ) + (if ( equal ( cadr ( DominoGetTopSymbol ComponentInfo ) ) ( cadr Symbol ) ) + ( DominoGetBottomSymbol ComponentInfo ) + ( DominoGetTopSymbol ComponentInfo ) ) ) ) + + +(defun SuperStackTraverseNetGraph ( ComponentInfoTable DomainTable NetTable DomainSymbolTable DomainKey Symbol PowerSymbol ) + (let ( + ( ComponentInfosOnSymbol + ( SuperStackGetComponentInfosOnSymbol ComponentInfoTable NetTable Symbol ) ) ) + ( foreach ComponentInfo ComponentInfosOnSymbol + (let ( + ( OtherSymbol + ( SuperStackDomainGetOtherSymbol + ComponentInfo + Symbol ) ) ) + (let ( + ( DomainComponentTable + (if ( arrayref DomainTable DomainKey ) + ( arrayref DomainTable DomainKey ) + ( makeTable `foo nil ) ) ) + ( DomainSymbolTable + (if DomainSymbolTable DomainSymbolTable ( makeTable `foo nil ) ) ) + ( DomainKey + (if DomainKey DomainKey OtherSymbol ) ) ) + + ( setarray DomainTable DomainKey DomainComponentTable ) + ( setarray DomainComponentTable + ( ComponentInfoGetName ComponentInfo ) + ComponentInfo ) + ( setarray DomainSymbolTable + Symbol + Symbol ) + (let ( + ( AlreadyWalked + ( arrayref DomainSymbolTable OtherSymbol ) ) ) + ( setarray DomainSymbolTable + OtherSymbol + OtherSymbol ) + (when ( and ( not AlreadyWalked ) + ( not ( SuperStackSymbolMatch PowerSymbol OtherSymbol ) ) ) + ( SuperStackTraverseNetGraph + ComponentInfoTable + DomainTable + NetTable + DomainSymbolTable + DomainKey + OtherSymbol + PowerSymbol ) ) ) ) ) ) ) ) + +/* +dt = +( SuperStackGetDomains;Table + ( mapcar `ComponentInfoCreateComponentInfoFromComponent + (wcv)->instances ) + ( SuperStackCreateNetTable + (wcv) + ( mapcar `ComponentInfoCreateComponentInfoFromComponent + (wcv)->instances ) + nil ) + ( list "GND" "Vdd" ) ) + +( println + ( mapcar + (lambda ( L ) + ( mapcar + `ComponentInfoGetName + L ) ) + dt ) ) +*/ diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domino.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domino.il new file mode 100644 index 0000000000..182528883c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/domino.il @@ -0,0 +1,472 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +/*DOC +Dominos are used as the abstract type of components in a superstack, which become Domino Stacks. See . + +Data structures:
    +
    +
    Domino +
    An ordered pair (a,b) of symbols. Also thought of as an edge in a graph with nodes symbols. + +
    DominoStack +
    An ordered list of (domino parity) pairs. Also thoughtof as a graph. + +
    Parity +
    nil for unflipped (a,b). t for flipped (b,a). + +
    Top/Bottom Domino +The first/last domino in a DominoStack. + +
    Top/Bottom Symbol +
    The first/last symbol of the first/last domino in a DominoStack. + +
    Ring +
    A DominoStack such that the bottom symbol is the same as the top symbol. Also a cyclic graph. + +
    NodeIndex +
    The index of a node in a DominoStack. nil for the bottom symbol, t for the top symbol. An integer 1..(number of dominos) for internal symbol nodes. + +
    +*/ + +(defun DominoCreateDomino ( Name + BottomSymbol + TopSymbol + ) + (let ( + ( Domino + ( makeTable `foo nil ) ) ) + ( DominoInit + Domino + Name + BottomSymbol + TopSymbol ) ) ) + +(defun DominoInit ( Domino + Name + BottomSymbol + TopSymbol + ) + ( setarray Domino `name Name ) + ( setarray Domino "1" BottomSymbol ) + ( setarray Domino "2" TopSymbol ) + ( setarray Domino `parity nil ) ) + + + +(defun DominoGetName ( Domino ) + ( arrayref Domino `name ) ) + +(defun DominoGetParity ( Domino ) + ( arrayref Domino `parity ) ) + +(defun DominoSetParity ( Domino Value ) + ( setarray Domino `parity Value ) ) + +(defun DominoGetBottomSymbol ( Domino ) + (if ( DominoGetParity Domino ) + ( arrayref Domino "2" ) + ( arrayref Domino "1" ) ) ) + +(defun DominoGetTopSymbol ( Domino ) + (if ( DominoGetParity Domino ) + ( arrayref Domino "1" ) + ( arrayref Domino "2" ) ) ) + + +;domino stacks +(defun DominoStackCreateDominoStack ( DominoList ) + (let ( + ( DominoStack ( makeTable `foo nil ) ) ) + ( DominoStackInit + DominoStack + DominoList) ) ) + +(defun DominoStackInit ( DominoStack + DominoList + ) + ( setarray DominoStack `list DominoList ) + ( setarray DominoStack `top ( car ( last DominoList ) ) ) + ( setarray DominoStack `bottom ( car DominoList ) ) +) + +(defun DominoStackGetBottomDomino ( DominoStack ) + ( arrayref DominoStack `bottom ) ) + +(defun DominoStackGetTopDomino ( DominoStack ) + ( arrayref DominoStack `top ) ) + +(defun DominoStackGetDominoList ( DominoStack ) + ( arrayref DominoStack `list ) ) + +(defun DominoStackGetKey ( DominoStack ) + ( DominoGetName + ( DominoStackGetBottomDomino DominoStack ) ) ) + +(defun DominoStackGetBottomSymbol ( DominoStack ) + ( DominoGetBottomSymbol ( arrayref DominoStack `bottom ) ) ) + +(defun DominoStackGetTopSymbol ( DominoStack ) + ( DominoGetTopSymbol ( arrayref DominoStack `top ) ) ) + +(defun DominoStackGetBottomSymbolOfTopDomino ( DominoStack ) + ( DominoGetBottomSymbol ( arrayref DominoStack `top ) ) ) + +(defun DominoStackGetTopSymbolOfBottomDomino ( DominoStack ) + ( DominoGetTopSymbol ( arrayref DominoStack `bottom ) ) ) + + + +(defun DominoStackGetDominoFromDominoStackAndNodeIndex ( DominoStackAndNodeIndex ) + ( car ( DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex DominoStackAndNodeIndex ) ) ) + + (defun DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex ( DominoStackAndNodeIndex ) + (cond ( + ( equal ( cadr DominoStackAndNodeIndex ) t ) + ( list ( DominoStackGetTopDomino ( car DominoStackAndNodeIndex ) ) t ) ) + ( + ( equal ( cadr DominoStackAndNodeIndex ) nil ) + ( list ( DominoStackGetBottomDomino ( car DominoStackAndNodeIndex ) ) nil ) ) + ( + ( numberp ( cadr DominoStackAndNodeIndex ) ) + ( list ( nth ( cadr DominoStackAndNodeIndex ) ( DominoStackGetDominoList ( car DominoStackAndNodeIndex ) ) ) t ) ) ) ) + +(defun DominoStackGetSymbolFromDominoStackAndNodeIndex ( DominoStackAndNodeIndex ) + (cond ( + ( equal ( cadr DominoStackAndNodeIndex ) t ) + ( DominoStackGetTopSymbol ( car DominoStackAndNodeIndex ) ) ) + ( + ( equal ( cadr DominoStackAndNodeIndex ) nil ) + ( DominoStackGetBottomSymbol ( car DominoStackAndNodeIndex ) ) ) + ( + ( numberp ( cadr DominoStackAndNodeIndex ) ) + ( DominoGetBottomSymbol ( nth ( cadr DominoStackAndNodeIndex ) + ( DominoStackGetDominoList ( car DominoStackAndNodeIndex ) ) ) ) ) ) ) + + +(defun DominoStackPrintDomino ( Domino ) + ( printf " %L\n" ( list ( DominoGetName Domino ) + ( DominoGetBottomSymbol Domino ) + ( DominoGetTopSymbol Domino ) + ( DominoGetParity Domino ) + ;( tableToList Domino ) + ) ) + ) + +(defun DominoPrintDominoList ( DominoList ) + ( mapcar + (lambda ( Domino ) + ( DominoStackPrintDomino Domino ) ) + DominoList ) ) + +(defun DominoStackPrintDominoStack ( DominoStack ) + ( printf "domino stack: %s\n" ( DominoStackGetKey DominoStack ) ) + ( DominoPrintDominoList ( DominoStackGetDominoList DominoStack ) ) ) + +(defun DominoStackPrintDominoStackSet ( DominoStackSet ) + ( printf "domino stack set ( size %d) \n" ( length DominoStackSet ) ) + ( mapcar + (lambda ( DominoStack ) + ( DominoStackPrintDominoStack DominoStack ) ) + ( mapcar `cadr ( tableToList DominoStackSet ) ) ) ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; real functionality +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun DominoReverseDominoList ( DominoList ) + ( foreach Domino DominoList + ( setarray Domino `parity + ( null ( arrayref Domino `parity ) ) ) ) + ( reverse DominoList ) ) + +;first one on bottom, 2 flip bits +(defun DominoStack ( DominoStack1 DominoStack2 NodeIndex1 NodeIndex2 DominoStackConstructor ) + (let ( + ;reverse the first if we're rotating ( we want this side on top ) + ;or if the bottom side matches + ( Reverse1 ( or ( numberp NodeIndex1 ) ( null NodeIndex1 ) ) ) + ;opposite of above + ( Reverse2 ( and ( not ( numberp NodeIndex2 ) ) NodeIndex2 ) ) + ( RotatedDominoList1 + ( ListRotate ( DominoStackGetDominoList DominoStack1 ) NodeIndex1 ) ) + ( RotatedSplitDominoLists2 ( ListSplit ( DominoStackGetDominoList DominoStack2 ) NodeIndex2 ) ) ) + ;( print ( list + ; RotatedDominoList1 + ; RotatedSplitDominoLists2 ) ) + (let ( + ;if they're both reversed leave the first alone, reverse the 2nd and swap the two splits + ;if first is reversed then reverse it, leave 2nd alone + ;if second is reversed, leave first alone + ;if neither reversed, leave thm alone + ( OrientedDominoList1 + (if Reverse1 + ( DominoReverseDominoList RotatedDominoList1 ) + RotatedDominoList1 ) ) + ( OrientedSplitDominoLists2 + (if Reverse2 + (if ( null ( car RotatedSplitDominoLists2 ) ) + ( list ( DominoReverseDominoList ( car RotatedSplitDominoLists2 ) ) + ( DominoReverseDominoList ( cadr RotatedSplitDominoLists2 ) ) ) + ( list ( DominoReverseDominoList ( cadr RotatedSplitDominoLists2 ) ) + ( DominoReverseDominoList ( car RotatedSplitDominoLists2 ) ) ) ) + RotatedSplitDominoLists2 ) ) ) + ( apply + DominoStackConstructor + ( list ( append + ( car OrientedSplitDominoLists2 ) + ( append + OrientedDominoList1 + ( cadr OrientedSplitDominoLists2 ) ) ) + ( list DominoStack1 + DominoStack2 ) + ) ) ) ) ) + +;( greaterp ( DominoCalculateHeight S ) + +(defun DominoStackRemove ( DominoStack DominoStackSet ) + ( remove ( DominoStackGetKey DominoStack ) DominoStackSet ) ) + +(defun DominoStackAdd ( DominoStack DominoStackSet ) + ( setarray DominoStackSet ( DominoStackGetKey DominoStack ) DominoStack ) ) + +(defun DominoStackMerge ( DominoStackSet + DominoStackAndNodeIndex1 + DominoStackAndNodeIndex2 + DominoStackConstructor ) + ( DominoStackRemove ( car DominoStackAndNodeIndex1 ) DominoStackSet ) + ( DominoStackRemove ( car DominoStackAndNodeIndex2 ) DominoStackSet ) + (let ( + ( MergedDomino ( DominoStack + ( car DominoStackAndNodeIndex1 ) + ( car DominoStackAndNodeIndex2 ) + ( cadr DominoStackAndNodeIndex1 ) + ( cadr DominoStackAndNodeIndex2 ) + DominoStackConstructor ) ) ) + ( DominoStackAdd MergedDomino DominoStackSet ) ) + t +) + +(defun DominoStackGetFirstAcceptableDominoStackAndNodeIndex ( DominoStackSet MergeTestFunc SymbolMatchFunc ) + "Returns the first pair of (superstack,side) pairs that match according to SymbolMatchFunc. A node is t/nil for top/bottom or an integer representing the index into internal nodes." + (let ( + ( FirstDominoStackAndNodeIndex nil ) + ( SecondDominoStackAndNodeIndex nil ) + ( DominoStackList ( mapcar `cadr ( tableToList DominoStackSet ) ) ) ) + + ;find first stack + ( exists + DominoStack + DominoStackList + ;that is a ring + ( and + ( apply + SymbolMatchFunc + ( list ( DominoStackGetTopSymbol DominoStack ) + ( DominoStackGetBottomSymbol DominoStack ) ) ) + ;and has a point in the ring + ( exists + NodeIndex + ( CounterFillList + 0 + ( difference + ( length + ( DominoStackGetDominoList + DominoStack ) ) 1 ) + 1 ) + (let ( + ( DominoStackAndNodeIndex + ( list DominoStack NodeIndex ) ) ) + ;such that there is another stack + ( and + ( exists + OtherDominoStack + DominoStackList + ;with a side(t nil) or point internal + ( exists + OtherNodeIndex + ( cons + t + ( CounterFillList + 0 + ( difference + ( length + ( DominoStackGetDominoList + OtherDominoStack ) ) 1 ) + 1 ) ) + + (let ( + ( OtherDominoStackAndNodeIndex + ( list OtherDominoStack OtherNodeIndex ) ) ) + ;such that the 2 stacks match at those points + ( and + ( not + ( equal + ( car DominoStackAndNodeIndex ) + ( car OtherDominoStackAndNodeIndex ) ) ) + ( apply + MergeTestFunc + ( list DominoStackAndNodeIndex + OtherDominoStackAndNodeIndex ) ) + ( setq SecondDominoStackAndNodeIndex + OtherDominoStackAndNodeIndex ) ) ) ) ) + ( setq FirstDominoStackAndNodeIndex + DominoStackAndNodeIndex ) ) ) ) ) ) + + ;if no ring matches, try the same with non-rings + (if ( not ( and FirstDominoStackAndNodeIndex SecondDominoStackAndNodeIndex ) ) + ( exists + DominoStack + DominoStackList + ( exists NodeIndex ( list t nil ) + (let ( + ( DominoStackAndNodeIndex ( list DominoStack NodeIndex ) ) ) + ( and + ( exists + OtherDominoStack + DominoStackList + ( exists + OtherNodeIndex + ( list t nil ) + (let ( + ( OtherDominoStackAndNodeIndex + ( list OtherDominoStack OtherNodeIndex ) ) ) + ( and + ( not + ( equal + ( car DominoStackAndNodeIndex ) + ( car OtherDominoStackAndNodeIndex ) ) ) + ( apply + MergeTestFunc + ( list DominoStackAndNodeIndex + OtherDominoStackAndNodeIndex ) ) + ( setq SecondDominoStackAndNodeIndex + OtherDominoStackAndNodeIndex ) ) ) ) ) + ( setq FirstDominoStackAndNodeIndex + DominoStackAndNodeIndex ) ) ) ) ) ) + ;return the 2 stack/side paris that match + ( list + FirstDominoStackAndNodeIndex + SecondDominoStackAndNodeIndex ) ) ) + +(defun DominoStackMergeFirstAcceptablePair ( DominoStackSet + MergeTestFunc + DominoStackConstructor + SymbolMatchFunc + ) + (let ( + ( MergePair + ( DominoStackGetFirstAcceptableDominoStackAndNodeIndex + DominoStackSet + MergeTestFunc + SymbolMatchFunc + ) ) ) + (when ( and ( car MergePair ) ( cadr MergePair ) ) + ( DominoStackMerge + DominoStackSet + ( car MergePair ) + ( cadr MergePair ) + DominoStackConstructor + ) ) ) ) + +(defun DominoStackMergeDominoStackSet ( DominoStackSet + MergeTestFuncInfoList + DominoStackConstructor + SymbolMatchFunc + BVerbose ) + + ( foreach MergeTestFuncInfo MergeTestFuncInfoList + (while + ( DominoStackMergeFirstAcceptablePair + DominoStackSet + (lambda ( DominoStackAndNodeIndex1 DominoStackAndNodeIndex2 ) + ( apply ( car MergeTestFuncInfo ) + ( append + ( list DominoStackAndNodeIndex1 DominoStackAndNodeIndex2 ) + ( cadr MergeTestFuncInfo ) ) ) ) + DominoStackConstructor + SymbolMatchFunc ) + + (when BVerbose + ( printf + "Verbose:\n" + ( DominoStackPrintDominoStackSet + DominoStackSet ) + ) ) ) ) ) + + +(defun DominoStackCutRings ( DominoStackSet + PreferredCutSymbols + IsSymbolExternalToDominoStackFunc + SymbolMatchFunc + DominoStackConstructor ) + ( foreach Key DominoStackSet + (let ( + ( DominoStack ( arrayref DominoStackSet Key ) ) ) + (let ( + ( NewDominoStack + ( DominoStackCutRing + DominoStack + PreferredCutSymbols + IsSymbolExternalToDominoStackFunc + SymbolMatchFunc + DominoStackConstructor ) ) ) + + ( DominoStackRemove DominoStack DominoStackSet ) + ( DominoStackAdd NewDominoStack DominoStackSet ) +) ) ) ) + +(defun DominoStackCutRing ( DominoStack + PreferredCutSymbols + IsSymbolExternalToDominoStackFunc + SymbolMatchFunc + DominoStackConstructor ) + "Re-orders a dominostack so that PreferredCutSymbols(power nets) or nets external to the stack appear on the top/botttom" + (if ( apply SymbolMatchFunc ( list ( DominoStackGetTopSymbol DominoStack ) + ( DominoStackGetBottomSymbol DominoStack ) ) ) + (let ( + ( DominoStackList ( DominoStackGetDominoList DominoStack ) ) ) + (let ( + ( CutPoint nil ) + ( CutSymbol nil ) ) + ( for CurrPoint 0 ( difference ( length DominoStackList ) 1 ) + (let ( + ( DominoStackAndNodeIndex ( list DominoStack CurrPoint ) ) ) + (let ( + ( CurrSymbol + ( DominoStackGetSymbolFromDominoStackAndNodeIndex DominoStackAndNodeIndex ) ) ) + (cond ( + ( and ( not + ( exists PreferredCutSymbol PreferredCutSymbols + ( apply SymbolMatchFunc + ( list CutSymbol PreferredCutSymbol ) ) ) ) + ( or + ( exists PreferredCutSymbol PreferredCutSymbols + ( apply SymbolMatchFunc + ( list CurrSymbol PreferredCutSymbol ) ) ) + ( apply + IsSymbolExternalToDominoStackFunc + ( list CurrSymbol + DominoStack + ) ) ) ) + ( setq CutSymbol CurrSymbol ) + ( setq CutPoint CurrPoint ) ) ) ) ) ) + (if CutPoint + (let ( + ( NewDominoStackList ( ListRotate DominoStackList CutPoint ) ) ) + (let ( + ( NewDominoStack ( apply + DominoStackConstructor + ( list NewDominoStackList + ( list DominoStack ) ) + ) ) ) + NewDominoStack ) ) + DominoStack ) ) ) + DominoStack ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/foldandchain.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/foldandchain.il new file mode 100644 index 0000000000..245b1ab185 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/foldandchain.il @@ -0,0 +1,82 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: FoldAndChain +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Change the folding of the Gates to adjust the width of them +; +; +; + +defun( FoldAndChain ( CellView ) + + ;fold + ( ChainFoldAllChains CellView + NChainLibCellPairRegExs + ( difference NWidth ( times UserUnitsPerMeter NRegionOffsetFromColumnCenter ) ) + UserUnitsPerMeter + ManufacturingGrid + PreferEvenFolds ) + ( ChainFoldAllChains CellView + PChainLibCellPairRegExs + ( difference PWidth ( times UserUnitsPerMeter PRegionOffsetFromColumnCenter ) ) + UserUnitsPerMeter + + ManufacturingGrid + PreferEvenFolds ) + + ;chain chains + ( SuperStackCreateFromCellView + CellView + SuperStackLibraryName + NSuperStackCellName + SuperStackViewName + NChainPrefix + `SuperStackGetDefaultMergeFuncInfoLists_Chain + ( list MaxNonPowerMergeHeight MaxPowerMergeHeight MaxMergeHeight ) + GNDNetName + VddNetName + NChainLibCellPairRegExs + t + nil ) + + ( SuperStackCreateFromCellView + CellView + SuperStackLibraryName + PSuperStackCellName + SuperStackViewName + PChainPrefix + `SuperStackGetDefaultMergeFuncInfoLists_Chain + ( list MaxNonPowerMergeHeight MaxPowerMergeHeight MaxMergeHeight ) + GNDNetName + VddNetName + PChainLibCellPairRegExs + t + nil ) + + ;stack gates + ( SuperStackCreateFromCellView + CellView + SuperStackLibraryName + GateSuperStackCellName + SuperStackViewName + GateChainPrefix + `SuperStackGetDefaultMergeFuncInfoLists_Gate + ( list MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight + GNDNetName + VddNetName) + GNDNetName + VddNetName + GateLibCellPairRegExs + nil + nil ) + + ( dbSave CellView ) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/group.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/group.il new file mode 100644 index 0000000000..a62eb7414f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/group.il @@ -0,0 +1,416 @@ +/** + * INTEL TOP SECRET + * Copyright 2002-2012 Intel Corporation. All Rights Reserved. + * $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/group.il#0 $ + */ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +/*DOC +This module contains functions for the grouping the NMOS & PMOS chains based on the dynamic "numbered" nets. + + + +*/ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( GroupStackGetChains () + let( ( CellView + Inst ChainName + ChainList + ) + + CellView = wcv() + + foreach( Inst CellView~>instances + ChainName = nth(0 parseString(nth(1 parseString(Inst~>cellName ".")) "_")) + when( ChainName == "NMOS" || ChainName == "PMOS" + ChainList = cons(Inst ChainList) + ) + ) + ChainList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( GroupStackGetNumNets (SelectedList) + + let( ( Inst IdxOP + NumList + DNet + SNet + I + DNetPresent + SNetPresent + ) + + NumList = nil + DNetPresent = nil + SNetPresent = nil + + foreach(Inst SelectedList + IdxOP = FindSDIdxs(Inst) + SNet = nth(car(IdxOP) Inst~>conns~>net~>name) + DNet = nth(cadr(IdxOP) Inst~>conns~>net~>name) + when( DNet + when( rexMatchp("^[0-9]" DNet) && rexMatchp("[0-9]$" DNet) + for( I 0 length(NumList) + when( nth(I NumList) == DNet + DNetPresent = t + ) + ) + + when( !DNetPresent + NumList = cons(DNet NumList) + DNetPresent = nil + ) + ) + ) + + when( SNet + when( rexMatchp("^[0-9]" SNet) && rexMatchp("[0-9]$" SNet) + for( I 0 length(NumList) + when( nth(I NumList) == SNet + SNetPresent = t + ) + ) + + when( !SNetPresent + NumList = cons(SNet NumList) + SNetPresent = nil + ) + ) + ) + + DNetPresent = nil + SNetPresent = nil + + ) + + NumList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( FindSDIdxs (Inst) + let( (SIdx DIdx I) + + for( I 0 length(Inst~>conns)-1 + when( nth(I Inst~>conns~>name) == "S" + SIdx = I + ) + when( nth(I Inst~>conns~>name) == "D" + DIdx = I + ) + ) + list(SIdx DIdx) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +procedure( GroupStackGetNumInst(SelectedList NumNet) + let( ( SNet + DNet IdxOP + NInst + TempList + ) + + TempList = '() + foreach( NInst SelectedList + IdxOP = FindSDIdxs(NInst) + SNet = nth(car(IdxOP) NInst~>conns~>net~>name) + DNet = nth(cadr(IdxOP) NInst~>conns~>net~>name) + + when( DNet == NumNet + TempList = cons(NInst TempList) + ) + + when( SNet == NumNet + TempList = cons(NInst TempList) + ) + + remove(NInst SelectedList) + ) + +TempList + ) ;let +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( GroupChains ( @key (SelectedList nil) (CellVue (UIGetCellView)) ) + let( ( NumNetsList SuperList ; SelectedList + NumNet NumNetInsts + NumNetsSortList + I J K + Len + JIdx + NewNet + NetAdded + ) + + if( geGetSelectedSet(CellVue) != nil && SelectedList == nil + then + SelectedList = RemoveGates(geGetSelectedSet(CellVue)) + else + SelectedList = GroupStackGetChains() + ) + + DisColorSuperList(SelectedList) + + NumNetsList = GroupStackGetNumNets(SelectedList) + NumNetsSortList = GroupStackSortNumNets(NumNetsList) + + printf("Num Nets ") + println(NumNetsSortList) + + SuperList = GroupCreateSuperList(SelectedList NumNetsSortList) + + println(SuperList~>name) + + ColorSuperList(SuperList) +; ArrangeColoredInsts(SelectedList) + printf("Total Colors: ") + println(length(SuperList)-1) + + + length(SuperList)-1 + + );let +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( GroupCreateSuperList (SelectedList NumNetsSortList) + let( ( NumNetsList SuperList + NumNet NumNetInsts + I J K + Len + JIdx + NewNet + NetAdded + ) + + for( K 0 length(NumNetsSortList) + + NumNet = nth(K NumNetsSortList) + JIdx = nil + + NumNetInsts = GroupStackGetNumInst(SelectedList NumNet) + + Len = length(SuperList) + NewNet = t + NetAdded = nil + + for( I 0 Len + + when( !NetAdded + when( Len == 0 + SuperList = list(NumNetInsts) + ) + + when( Len > 0 + + for( J 0 Len + when( SuperListNetPresent(nth(J SuperList) NumNet) + JIdx = J + ) + ) + + if( JIdx + then + SuperList = AddSuperListInst(SuperList NumNetInsts JIdx) + NetAdded = t + else + SuperList = AddSuperListNew(SuperList NumNetInsts) + NetAdded = t + ) + ) + ) + ) + ) + + SuperList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( GroupSortSuperList (SuperList) + let( ( ModSuperList ) + + ModSuperList + + for( I 0 length(SuperList)-1 + CurrGroup = nth(I SuperList) + + + ) + + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +procedure( GroupStackCompareGates( X Y ) + let( ( term ) + lessp(1 strcmp(car(setof(term X~>terminals term~>name=="G[0]"))~>net~>name car(setof(term Y~>terminals term~>name=="G[0]"))~>net~>name)) + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +procedure( IsNetNumNet( NetName ) + rexMatchp("^[0-9]" NetName) && rexMatchp("[0-9]$" NetName) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( gtemp (instlist) + let( ( I outlist instc ) + + for( I 1 6 + outlist = cons(length(setof(instc instlist length(instc~>terminals)==I+3)) outlist) + + ) + + for( I 0 length(instlist)-1 + instc = nth(I instlist) + when( I == 0 + SNet = car(setof(term instc~>terminals term~>name=="S"))~>net~>name + DNet = car(setof(term instc~>terminals term~>name=="D"))~>net~>name + + ) + + ) + +outlist + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +defun( SuperListNetPresent (List Net) + let( (ListNets) + ListNets = GroupStackGetNumNets(List) + nequal(member(Net ListNets) nil) + );let +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( AddSuperListInst (List Insts Idx) + let( ( + I + ChopList ChopListTop + NewList OutList + ) + NewList = append(nth(Idx List) Insts) + OutList = subst(NewList nth(Idx List) List) + OutList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( AddSuperListNew (List Insts) + let( ( NewList OutList ) + NewList = list(Insts) + OutList = append(List NewList) + OutList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +procedure( GroupStackCompareNumNets( X Y ) + lessp(evalstring(X) evalstring(Y)) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +procedure( GroupStackSortNumNets( SelectedList ) + sort(SelectedList 'GroupStackCompareNumNets) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( ColorSuperList (SuperList) + let( ( + I + J + CurrList + XGrid + YGrid + PrevY + ) + + XGrid = -PowerGridPitch + + for( I 0 length(SuperList) + CurrList = nth(I SuperList) + YGrid = 0 + PrevY = 0 + when( CurrList + for( J 0 length(CurrList) + when( PrevY != 0 + YGrid = PrevY + 0.04 + ) + when( nth(J CurrList) && (nth(J CurrList)~>StackColor != "FALSE"); && nth(J CurrList)~>StackColor != nil + dbReplaceProp(nth(J CurrList) "StackColor" "int" I) + dbSet(nth(J CurrList) "R0" "orient") + dbSet(nth(J CurrList) "TRUE" "MovedFig") + dbSet(nth(J CurrList) list(XGrid YGrid) "xy") + PrevY = cadadr(nth(J CurrList)~>bBox) + ) + ) + ) + XGrid = XGrid - PowerGridPitch + ) + ) +t +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( DisColorSuperList (SelectedList) + let( ( Inst ) + + foreach( Inst SelectedList + dbDeletePropByName(Inst "StackColor") + dbSet(Inst "FALSE" "MovedFig") + ) + + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( ArrangeColoredInsts (SelectedList) + let( ( + Inst + XCoordOffset + NewLoc + XGrid + ) + + XGrid = -1.52 + foreach( Inst SelectedList + + when( Inst~>StackColor + XCoordOffset = (Inst~>StackColor + 1) * XGrid + NewLoc = list(XCoordOffset cadr(Inst~>xy)) + dbSet(Inst NewLoc "xy") + ) + ) + + + );let +t +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +defun( RemoveGates (InstList) + let( ( modList Inst ) + + modList = InstList + + foreach( Inst InstList + when( Inst~>libName == "gate" + modList = remove(Inst modList) + ) + ) + modList + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/inlinesuperstacks.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/inlinesuperstacks.il new file mode 100644 index 0000000000..1d7e04a7fb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/inlinesuperstacks.il @@ -0,0 +1,46 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: InlineSuperstacks +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Flatten one level of Hirachy of stack component to make all +; instance gates +; +; + +defun( InlineSuperstacks ( CellView InlineMultipleGateStacks ) + + (let ( + ( SuperStacks + ( cadr ( NameFilterInstances + ( getq CellView instances ) + SuperStackLibCellPairRegExs ) ) ) ) + + ( InlineInstances + CellView + CellView + ( setof SuperStack SuperStacks + ( or ( not ( equal ( getq SuperStack cellName ) + GateSuperStackCellName ) ) + InlineMultipleGateStacks + ( equal + ( length + ( SuperStackGetComponentNameListFromSuperStackName + ( getq SuperStack name ) ) ) + 1 ) ) ) + "netlist" + nil + FoldableCellLibCellPairRegExs + SuperStackLibCellPairRegExs + ?Verbose nil ) + + ( dbSave CellView ) + ) +CellView +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/refold.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/refold.il new file mode 100644 index 0000000000..bab58d79f0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/refold.il @@ -0,0 +1,407 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun RefoldFilterComponentInfos ( ComponentInfos LibCellPairRegExs ) + ( NameFilterObjects + ComponentInfos + LibCellPairRegExs + (lambda ( ComponentInfo ) + ( nth 0 ( ComponentInfoGetLibCellView ) ) ) + (lambda ( ComponentInfo ) + ( nth 1 ( ComponentInfoGetLibCellView ) ) ) ) ) + +(defun RefoldCreateSameFoldChainInfoTable ( ChainInfos ) + (let ( + ( SameFoldChainInfoTable ( makeTable `foo nil ) ) ) + ( foreach ChainInfo ChainInfos + (let ( + ( CanonicalName + ( NameCanonicalizeFoldableInstanceName + ( ComponentInfoGetName ChainInfo ) ) ) ) + ( setarray SameFoldChainInfoTable CanonicalName + ( cons ChainInfo ( arrayref SameFoldChainInfoTable CanonicalName ) ) ) ) ) + SameFoldChainInfoTable ) ) + + +(defun RefoldCombineFolds ( ChainInfos ) + ( PDKCombineFolds + ( mapcar + `ComponentInfoGetStrengthFromChainInfo + ChainInfos ) ) ) + +(defun RefoldCreateOriginalChainInfoFromSameFoldChainInfos ( SameFoldChainInfos + UserUnitsPerMeter ) + + (let ( + ;get chain with name=bla.x with lowest x + ( FirstChainInfo + ( car SameFoldChainInfos ) ) ) + (let ( + ( CanonicalName + ( NameCanonicalizeFoldableInstanceName + ( ComponentInfoGetName FirstChainInfo ) ) ) ) + (let ( + ( NewStrength + ( RefoldCombineFolds + SameFoldChainInfos ) ) + ( NewChainInfo ( ComponentInfoCopy FirstChainInfo ) ) ) + + ( setarray NewChainInfo `name CanonicalName ) + + ( ComponentInfoSetStrengthForChainInfo + NewChainInfo + NewStrength ) + + ( ComponentInfoSetWidth + NewChainInfo + ( plus + NewStrength + ( difference + ( ComponentInfoGetWidth FirstChainInfo ) + ( times UserUnitsPerMeter + ( ComponentInfoGetStrengthFromChainInfo FirstChainInfo ) ) ) ) ) + + NewChainInfo ) ) ) ) + + +;1) get all chain infos and other instances +;2) get map from canonical name -> list of chain infos +;3) create original chain infos from existing chain infos of same fold +;4) create a map from canonical name -> original chain info +;5) get all original chain infos +;6) get original chain infos of given chains +;7) get original chain infos to refold: +; - AllInDomain: get all chain infos that aare in domains of given chains +; - Otherwise : use 6) +;8) return folds of all the original chain infos to refold + +(defun RefoldGetAllOriginalChainInfosForGivenChains ( CellView + GivenChains + ChainLibCellPairRegExs + UserUnitsPerMeter + AllInDomain + GNDNetName + VddNetName ) + (let ( + ( FilterResult ( NameFilterInstances + ( getq CellView instances ) + ChainLibCellPairRegExs ) ) ) + (let ( + ( OtherInstances ( car FilterResult ) ) + ( AllChainInfos + ( mapcar + (lambda ( Chain ) + ( ComponentInfoCreateComponentInfoFromComponent + Chain ) ) + ( cadr FilterResult ) ) ) ) + (let ( + ( SameFoldChainInfoTable + ( RefoldCreateSameFoldChainInfoTable + AllChainInfos ) ) ) + + (let ( + ( OriginalChainInfoTable ( makeTable `original nil ) ) + ( OriginalChainInfoToFoldsTable ( makeTable `fold nil ) ) ) + ( foreach SameFoldChainInfoList ( mapcar `cadr ( tableToList SameFoldChainInfoTable ) ) + (let ( + ( OriginalChainInfo + ( RefoldCreateOriginalChainInfoFromSameFoldChainInfos + SameFoldChainInfoList + UserUnitsPerMeter + ) ) ) + ( setarray OriginalChainInfoTable + ( ComponentInfoGetName OriginalChainInfo ) + OriginalChainInfo ) + ( setarray OriginalChainInfoToFoldsTable + ( ComponentInfoGetName OriginalChainInfo ) + SameFoldChainInfoList ) ) ) + (let ( + ( AllOriginalChainInfos + ( mapcar `cadr ( tableToList OriginalChainInfoTable ) ) ) + ( OriginalChainInfosOfGivenChains + ( mapcar + ( lambda ( Chain ) + ( arrayref OriginalChainInfoTable ( NameCanonicalizeFoldableInstanceName + ( getq Chain name ) ) ) ) + GivenChains ) ) ) + (let ( + ( OriginalChainInfosToRefold + (if AllInDomain + ( RefoldGetAllChainInfosInDomainsOfGivenChainInfos + CellView + AllOriginalChainInfos + OriginalChainInfosOfGivenChains + OtherInstances + GNDNetName + VddNetName ) + OriginalChainInfosOfGivenChains ) ) ) + OriginalChainInfosToRefold + + ) ) ) ) ) ) ) + + +(defun RefoldRefoldChainInfosOfSameFold ( CellView + NewChainInfos + InstanceMap ) + (when NewChainInfos + (let ( + ( CanonicalName ( NameCanonicalizeFoldableInstanceName + ( ComponentInfoGetName ( car NewChainInfos ) ) ) ) ) + (let ( + ( ChainTable ( makeTable `chain nil ) ) + ( ChainsOfFold + ( NameGetInstancesForCanonicalName + InstanceMap + CanonicalName ) ) ) + (let ( + ( Location ( getq ( car ChainsOfFold ) xy ) ) + ( Orient ( getq ( car ChainsOfFold ) orient ) ) + ( Offset ( RectGetWidth ( getq ( car ChainsOfFold ) bBox ) ) ) + ) + ( foreach Chain ChainsOfFold + ( setarray ChainTable Chain Chain ) ) + ( foreach ChainInfo NewChainInfos + (let ( + ( Chain ( dbFindAnyInstByName + CellView + ( ComponentInfoGetName ChainInfo ) ) ) ) + (if Chain + (let () + ( dbReplaceProp + Chain + ( ComponentInfoGetWidthParameterNameFromChainInfo + ChainInfo ) + "float" + ( ComponentInfoGetStrengthFromChainInfo + ChainInfo ) ) + ( remove Chain ChainTable ) ) + (let ( + ( NewChain + ( ComponentInfoCreateComponentFromComponentInfo + CellView + ChainInfo + ( setq Location + ( list + ( plus ( car Location ) Offset ) + ( cadr Location ) ) ) ) ) ) + ( dbSetq NewChain Orient orient ) ) ) ) ) + ( foreach Chain ( mapcar `cadr ( tableToList ChainTable ) ) + ( dbDeleteObject Chain ) ) ) ) ) ) ) + + +(defun RefoldGetAllChainInfosInDomainsOfGivenChainInfos ( CellView + AllChainInfos + GivenChainInfos + OtherInstances + GNDNetName + VddNetName ) + + (let ( + ( NetTable ( SuperStackCreateNetTable + CellView + AllChainInfos + OtherInstances ) ) ) + (let ( + ( Domains + ( SuperStackGetDomains + AllChainInfos + NetTable + ( list GNDNetName + VddNetName ) ) ) ) + (let ( + ( DomainsOfGivenChains + ( setof Domain Domains + ( exists ChainInfo1 Domain + ( exists ChainInfo2 GivenChainInfos + ( equal ChainInfo1 ChainInfo2 ) ) ) ) ) ) + ( ListNonDestructiveMapCan + (lambda ( Domain ) Domain ) + DomainsOfGivenChains ) ) ) ) ) + + +(defun RefoldGetDefaultFoldFunc ( CellView + ColumnWidth + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) + + ( ExpressionReplaceSymbolsWithValues + `(lambda ( ChainInfo ) + ( println + ( list + CellView + ChainInfo + ColumnWidth + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) ) + + ( ChainFoldChainInfoToChainInfos + CellView + ChainInfo + ColumnWidth + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) + ) + ( list `CellView + `ColumnWidth + `UserUnitsPerMeter + `RoundToNearest + `PreferEvenFolds ) ) ) + + +(defun RefoldGetOverrideFoldsFoldFunc ( CellView + Folds + RoundToNearest ) + + ( ExpressionReplaceSymbolsWithValues + `(lambda ( ChainInfo ) + ( ChainFoldChainInfoToChainInfosOverrideFolds + CellView + ChainInfo + Folds + RoundToNearest ) ) + ( list `CellView + `RoundToNearest + `Folds + ) ) ) + + +(defun RefoldRefoldChains ( CellView + GivenChains + ChainLibCellPairRegExs + UserUnitsPerMeter + AllInDomain + FoldFunc + GNDNetName + VddNetName + ) + (let ( + ( InstanceMap ( NameMakeInstanceMapFromCellView + CellView + ChainLibCellPairRegExs ) ) ) + (let ( + ( OriginalChainInfos + ( RefoldGetAllOriginalChainInfosForGivenChains + CellView + GivenChains + ChainLibCellPairRegExs + UserUnitsPerMeter + AllInDomain + GNDNetName + VddNetName ) ) ) + ( foreach OriginalChainInfo OriginalChainInfos + (let ( + ( NewFoldedChainInfos + ( apply + FoldFunc + ( list OriginalChainInfo ) ) ) ) + ( RefoldRefoldChainInfosOfSameFold + CellView + NewFoldedChainInfos + InstanceMap + ) ) ) ) ) ) + +(defun RefoldReStackChains ( CellView + GivenChains + SuperStackLibName + SuperStackCellName + SuperStackViewName + ChainPrefix + NonPowerMergeFuncInfoList + PowerMergeFuncInfoList + GNDNetName + VddNetName + ChainLibCellPairRegExs + AllInDomain + BCutRings + BVerbose + PreserveOrder ) + (let ( + ( FilterResult ( NameFilterInstances + ( getq CellView instances ) + ChainLibCellPairRegExs ) ) ) + (let ( + ( OtherInstances ( car FilterResult ) ) + ( AllChainInfos + ( mapcar + (lambda ( Chain ) + ( ComponentInfoCreateComponentInfoFromComponent + Chain ) ) + ( cadr FilterResult ) + ) ) ) + ( println ( mapcar + (lambda ( ChainInfo ) + ( ComponentInfoGetName ChainInfo ) ) + AllChainInfos ) ) + (let ( + ( ChainInfosOfGivenChains + ( TableGetCorrespondingList + AllChainInfos + GivenChains + (lambda ( ChainInfo ) + ( ComponentInfoGetName ChainInfo ) ) + (lambda ( Chain ) + ( getq Chain name ) + ) ) ) ) + ( println ChainInfosOfGivenChains ) + ( println GivenChains~>name ) + (let ( + ( ChainInfosToStack + (if AllInDomain + ( RefoldGetAllChainInfosInDomainsOfGivenChainInfos + CellView + AllChainInfos + ChainInfosOfGivenChains + OtherInstances + GNDNetName + VddNetName ) + ChainInfosOfGivenChains ) ) ) + ( println ChainInfosToStack ) + (let ( + ( ChainsToStack + ( mapcar + (lambda ( ChainInfo ) + ( dbFindAnyInstByName CellView ( ComponentInfoGetName ChainInfo ) ) ) + ChainInfosToStack ) ) ) + + (if PreserveOrder + ( SuperStackCreateFromComponentInfos_PreserveOrder + CellView + (mapcar (lambda ( Chain ) + ( ComponentInfoCreateComponentInfoFromComponent + Chain ) ) + ChainsToStack ) + SuperStackLibName + SuperStackCellName + SuperStackViewName + ChainPrefix + BVerbose ) + + ( SuperStackCreateFromComponentInfos + CellView + (mapcar (lambda ( Chain ) + ( ComponentInfoCreateComponentInfoFromComponent + Chain ) ) + ChainsToStack ) + ( append OtherInstances + ( ListDifference ( cadr FilterResult ) ChainsToStack (lambda ( x y ) ( equal x y ) ) nil ) ) + SuperStackLibName + SuperStackCellName + SuperStackViewName + ChainPrefix + NonPowerMergeFuncInfoList + PowerMergeFuncInfoList + GNDNetName + VddNetName + BCutRings + BVerbose ) ) + + + + ( foreach Chain ChainsToStack + ( dbDeleteObject Chain ) ) ) ) ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack.il new file mode 100644 index 0000000000..c735cb74d7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack.il @@ -0,0 +1,609 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +This module has the basic ocde for constructing superstacks from s respresenting gates/stacks.
    + +Some data structures:
    +
    +
    SuperStackSet +
    Represents a set of superstacks. Maps name of first componentinfo in each superstack to a SuperStackInfo. + +
    SuperStackInfo +
    A table with entries for: a list of component infos, the min width, and the max width of those components. We keep the widths around so when we're checking heuristics in we don't have to traverse the componentinfolist. This contains all the information we need to create an acutal superstack instance. + +
    Ring +
    If the top of a superstack connects to the bottom, we call it a ring. This means the top/bottom of the superstack is arbitrary. Cutting a ring means choosing some component in the superstack to be at the bottom. + +
    NodeIndex +
    t=top of superstack, nil=bottom of superstack, integer=index of locations in superstack. + +
    SuperStackInfoAndNodeIndex +
    (superstackinfo nodeindex). Corresponds to some location in a superstack that could potentially be connected to a location in another superstack. This is what we deal with when determining which superstacks can merge together. Non rings can only merge at their top or bottom, because merging an internal location with another superstack would break the superstack. For rings, we can choose internal locations (integers) as well, becuase the top or bottom is arbitrary to begin with/ + +
    MergeTestFuncInfoList +
    List of heuristics which take two SuperStackInfoAndNodeIndex's and returns non-nil iff the 2 superstacks can merge together. + +
    NonPowerMergeTestFuncInfoList +
    List of heuristics to use before allowing mingling of domains. + +
    PowerMergeTestFuncInfoList +
    List of heuristics to use after domains are mingled. + +
    Domain +
    See +
    + + +This is how superstacks are generated:
    +
      +
    1. Create componentinfos from some set of gate/stack components. + +
    2. Determine the connected domains of components, and promote componentinfos to singleton superstacks. We will merge superstacks into bigger superstacks. + +
    3. For each domain, greedily attempt to merge the superstacks in the domain together according to NonPowerMergeTestFuncInfoList heuristics. That is, we just keep picking pairs of SuperStackInfoAndNodeIndex from different superstacks, and then ask the MergeTestFuncInfo heuristics if it's OK for them to merge together. The simplest heuristic is that the nets must match. Others say that the widths of the components must be close together, or the stack can't be too tall, or the components must share a non-power net,etc. + +
    4. Cut the superstack rings so that power nets or nets external to the ring are on the top/bottom. If we didn't do this then there + +
    5. Greedily attempt to merge the stacks in different domains together according to PowerMergeTestFuncInfoList heuristics. + +
    6. Cut the superstack rings so that power nets or nets external to the ring are on the top/bottom. + +
    + +*/ + +;super stack info creation and access +(defun SuperStackCreateSuperStackInfoFromComponentInfo ( ComponentInfo ) + (let ( + ( Width ( ComponentInfoGetWidth ComponentInfo ) ) + ( Height ( ComponentInfoGetHeight ComponentInfo ) ) ) + ( SuperStackCreateSuperStackInfo ( list ComponentInfo ) Width Width Height ) ) ) + +(defun SuperStackCreateSuperStackInfoFromComponentInfoList ( ComponentInfoList + SourceSuperStack + GetOverlapFunc + ) + (let ( + ( MinWidth 1e9 ) + ( MaxWidth 0 ) + ( Height + (when GetOverlapFunc + ( SuperStackCalculateHeightFromComponentInfos + ComponentInfoList + GetOverlapFunc ) ) ) + ) + ( foreach ComponentInfo ComponentInfoList + (let ( + ( Width ( ComponentInfoGetWidth ComponentInfo ) ) ) + (if ( lessp Width MinWidth ) + ( setq MinWidth Width ) ) + (if ( greaterp Width MaxWidth ) + ( setq MaxWidth Width ) ) ) ) + ( SuperStackCreateSuperStackInfo + ComponentInfoList + MinWidth + MaxWidth + Height + ) ) ) + +(defun SuperStackCreateName ( SuperStackInfo ) + (let ( + ( Name "" ) + ( ComponentInfoList ( SuperStackGetComponentInfoList + SuperStackInfo ) ) ) + ( foreach ComponentInfo ComponentInfoList + ( setq Name ( sprintf nil "%s:%s" Name ( ComponentInfoGetName + ComponentInfo ) ) ) ) + Name ) ) + +;for inlining +(defun SuperStackGetComponentNameListFromSuperStackName ( SuperStackName ) + ( parseString SuperStackName ":" ) ) + +(defun SuperStackGetComponentIndexFromComponentName ( ComponentName ) + ( rexMatchp "[0-9]+" ComponentName ) + ( atoi ( rexSubstitute "\\0" ) ) ) +;; + +(defun SuperStackCreateSuperStackInfo ( ComponentInfoList MinWidth MaxWidth Height ) + (let ( + ( SuperStackInfoTable ( makeTable `superstackinfo nil ) ) ) + ( setarray SuperStackInfoTable `minwidth MinWidth ) + ( setarray SuperStackInfoTable `maxwidth MaxWidth ) + ( setarray SuperStackInfoTable `height Height ) + ( DominoStackInit + SuperStackInfoTable + ComponentInfoList ) + SuperStackInfoTable + ) ) + +(defun SuperStackGetComponentInfoList ( SuperStackInfo ) + ( arrayref SuperStackInfo `list ) ) + +(defun SuperStackGetBottomComponentInfo ( SuperStackInfo ) + ( arrayref SuperStackInfo `bottom ) ) + +(defun SuperStackGetTopComponentInfo ( SuperStackInfo ) + ( arrayref SuperStackInfo `top ) ) + +(defun SuperStackGetMinWidth ( SuperStackInfo ) + ( arrayref SuperStackInfo `minwidth ) ) + +(defun SuperStackGetMaxWidth ( SuperStackInfo ) + ( arrayref SuperStackInfo `maxwidth ) ) + +(defun SuperStackGetHeight ( SuperStackInfo ) + ( arrayref SuperStackInfo `height ) ) + +(defun SuperStackGetSuperStackKey ( SuperStackInfo ) + ( ComponentInfoGetName + ( SuperStackGetBottomComponentInfo SuperStackInfo ) ) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Creation of PCell Parameters +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;SuperStackParameter = ( list ComponentParameterInfo... ) +;ComponentParameterInfo = ( list Parity ComponentParameterList ) +;ComponentParameterList = the pcell parameter list for the chain + +(defun SuperStackCreateSuperStackParameterFromSuperStackInfo ( SuperStackInfo ) + (let ( + ( LastComponentInfo nil ) ) + + ( mapcar + (lambda ( ComponentInfo ) + (let ( + ( Parameter + ( list + ( ComponentInfoGetLibCellView + ComponentInfo ) + ( ComponentInfoGetParity + ComponentInfo ) + ( ComponentInfoGetParameterList + ComponentInfo ) + (when ( and LastComponentInfo + ( SuperStackSymbolMatch + ( DominoGetBottomSymbol ComponentInfo ) + ( DominoGetTopSymbol LastComponentInfo ) ) ) + t ) ) ) ) + ( setq LastComponentInfo ComponentInfo ) + Parameter + ) ) + ( SuperStackGetComponentInfoList SuperStackInfo ) ) ) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Connecting the superstack instance terminals +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun SuperStackConnect ( CellView SuperStack SuperStackInfo ComponentPrefix ) + (let ( + ( CurrNum 0 ) ) + ( foreach ComponentInfo ( SuperStackGetComponentInfoList SuperStackInfo ) + ( mapcar + (lambda ( Conn ) + (let ( + ( TermName ( sprintf nil "%s%d.%s" ComponentPrefix CurrNum ( car Conn ) ) ) + ( NetName ( cadr Conn ) ) ) + (if ( dbFindTermByName ( getq SuperStack master ) TermName ) + ( dbCreateConnByName + ( dbMakeNet CellView NetName ) + SuperStack + TermName ) ) ) ) + ( tableToList ( ComponentInfoGetConnTable ComponentInfo ) ) ) + ( setq CurrNum ( plus CurrNum 1 ) ) ) ) ) + + +(defun SuperStackIsSymbolExternalToSuperStackInfo ( Symbol + SuperStackInfo + NetTable ) + ( and + ( SuperStackIsNetExternalToSuperStackInfo ( car Symbol ) + SuperStackInfo + NetTable ) + ( SuperStackIsNetExternalToSuperStackInfo ( cadr Symbol ) + SuperStackInfo + NetTable ) ) ) + +(defun SuperStackIsNetExternalToSuperStackInfo ( NetName + SuperStackInfo + NetTable ) + (if NetName + (let ( + ( TermTable ( arrayref NetTable NetName ) ) ) + ;are tere any connected instances ( through instTerms ) that aren't in the stack + ( or ( arrayref TermTable "EXTERNAL" ) + ( exists Key TermTable + ( exists InstanceName ( arrayref TermTable Key ) + ( not ( exists ComponentInfo ( SuperStackGetComponentInfoList SuperStackInfo ) + ( equal + ( ComponentInfoGetName ComponentInfo ) + InstanceName ) ) ) ) ) ) ) ) ) + + +;; +;; Calculate actual height +;; + +(defun SuperStackCalculateHeightFromComponentInfoList ( ComponentInfoList + GetOverlapFunc ) + + (let ( + ( Height 0.0 ) + ( LastComponentInfo nil ) ) + ( foreach ComponentInfo ComponentInfoList + (let ( + ( Overlap + (if ( and LastComponentInfo + ( not + ( or + ( equal + ( PropGetPropValueFromPropertyList + ( ComponentInfoGetParameterList ComponentInfo ) + "well_plugs" ) + "TRUE" ) + ( equal + ( PropGetPropValueFromPropertyList + ( ComponentInfoGetParameterList LastComponentInfo ) + "well_plugs" ) + "TRUE" ) ) ) ) + ( apply + GetOverlapFunc + ( list ( ComponentInfoGetBottomCSInfo + ComponentInfo ) + ( ComponentInfoGetTopCSInfo + LastComponentInfo ) + ( SuperStackSymbolMatch + ( DominoGetBottomSymbol + ComponentInfo ) + ( DominoGetTopSymbol + LastComponentInfo ) ) ) ) + 0.0 ) ) ) + + /* + ( printf "component height: %L overlap: %L\n" + ( ComponentInfoGetHeight ComponentInfo ) + Overlap ) + */ + ( setq Height + ( plus Height + ( difference ( ComponentInfoGetHeight ComponentInfo ) + Overlap ) ) ) + + + ( setq LastComponentInfo ComponentInfo ) + ) ) + Height ) ) + +(defun SuperStackCalculateHeight ( SuperStackInfo + GetOverlapFunc ) + + ( SuperStackCalculateHeightFromComponentInfoList + ( SuperStackGetComponentInfoList SuperStackInfo ) + GetOverlapFunc ) ) + +(defun SuperStackGetDefaultConstructor ( GetOverlapFunc ) + (lambda ( ComponentInfoList + SourceSuperStackInfos ) + (let ( + ( MinWidth (if SourceSuperStackInfos + ( ListFindMinimum + SourceSuperStackInfos + (lambda ( SuperStackInfo ) + ( SuperStackGetMinWidth SuperStackInfo ) ) ) + ( ListFindMinimum + ComponentInfoList + (lambda ( ComponentInfo ) + ( ComponentInfoGetWidth + ComponentInfo ) ) ) + ) ) + ( MaxWidth (if SourceSuperStackInfos + ( ListFindMaximum + SourceSuperStackInfos + (lambda ( SuperStackInfo ) + ( SuperStackGetMaxWidth SuperStackInfo ) ) ) + ( ListFindMaximum + ComponentInfoList + (lambda ( ComponentInfo ) + ( ComponentInfoGetWidth + ComponentInfo ) ) ) ) ) + ( Height + ( SuperStackCalculateHeightFromComponentInfoList + ComponentInfoList + GetOverlapFunc ) ) + ) + ( SuperStackCreateSuperStackInfo + ComponentInfoList + MinWidth + MaxWidth + Height + ) ) ) ) + +(defun SuperStackFlattenSubSuperStackSets ( SuperStackSets ) + "trivially merges a list of superstack sets into a single superstack set" + (let ( + ( NewSuperStackSet ( makeTable `superstack nil ) ) ) + ( foreach SuperStackSet SuperStackSets + ( foreach Entry ( tableToList SuperStackSet ) + ( setarray NewSuperStackSet ( car Entry ) ( cadr Entry ) ) ) ) + NewSuperStackSet ) ) + + +(defun SuperStackCreateFromSuperStackSet ( CellView + SuperStackSet + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentPrefix ;prefix for instance/terminal names + BVerbose + @key + ( Align "ll" ) + ) + "Creates superstack instances" + (let ( + ( ListOfSuperStackInfoSuperStackParameterPairs + ( SuperStackCreateListOfSuperStackInfoSuperStackParameterPairsFromSuperStackSet + SuperStackSet ) ) ) + ( mapcar + (lambda ( SuperStackInfoSuperStackParameterPair ) + (let ( + ( SuperStackParameter ( cadr SuperStackInfoSuperStackParameterPair ) ) + ( SuperStackInfo ( car SuperStackInfoSuperStackParameterPair ) ) ) + (let ( + ( AlignPoint + (cond ( + ( equal Align "ll" ) + ( list + ( ListFindMinimum + ( SuperStackGetComponentInfoList + SuperStackInfo ) + (lambda ( ComponentInfo ) + ( RectGetLeft ( ComponentInfoGetBBox ComponentInfo ) ) ) ) + ( ListFindMinimum + ( SuperStackGetComponentInfoList + SuperStackInfo ) + (lambda ( ComponentInfo ) + ( RectGetBottom ( ComponentInfoGetBBox ComponentInfo ) ) ) ) ) ) + ( + ( equal Align "lr" ) + ( list + ( ListFindMaximum + ( SuperStackGetComponentInfoList + SuperStackInfo ) + (lambda ( ComponentInfo ) + ( RectGetRight ( ComponentInfoGetBBox ComponentInfo ) ) ) ) + ( ListFindMinimum + ( SuperStackGetComponentInfoList + SuperStackInfo ) + (lambda ( ComponentInfo ) + ( RectGetBottom ( ComponentInfoGetBBox ComponentInfo ) ) ) ) ) ) ) ) + ( Orient + (if ( ComponentInfoGetHParity + ( DominoStackGetBottomDomino SuperStackInfo ) ) + "MY" "R0" ) ) + ) + (let ( + ( SuperStack + ( dbCreateParamInstByMasterName + CellView + SuperStackLibName + SuperStackCellName + SuperStackViewName + nil + AlignPoint + "R0" + 1 + ( list + ( list "ParameterInfoList" "ILList" SuperStackParameter ) ) ) ) ) + ;set name + ( dbReplaceProp + SuperStack + "name" + "string" + ( SuperStackCreateName SuperStackInfo ) + ) + + ;connect terminals + ( SuperStackConnect + CellView + SuperStack + SuperStackInfo + ComponentPrefix ) + + ( FigMove + SuperStack + AlignPoint + ?Orient Orient + ?Align Align + ) + + SuperStack + ) ) ) ) + ListOfSuperStackInfoSuperStackParameterPairs ) ) ) + +(defun SuperStackSortValueFunc ( SuperStackInfo ) + ( cadr + ( ComponentInfoGetPosition + ( SuperStackGetBottomComponentInfo + SuperStackInfo ) ) ) ) + +(defun SuperStackCreateListOfSuperStackInfoSuperStackParameterPairsFromSuperStackSet ( SuperStackSet ) + ( mapcar + (lambda ( SuperStackInfo ) + ( list + SuperStackInfo + ( SuperStackCreateSuperStackParameterFromSuperStackInfo + SuperStackInfo + ) ) ) + ( sort + ( mapcar `cadr ( tableToList SuperStackSet ) ) + (lambda ( X Y ) + ( lessp + ( SuperStackSortValueFunc X ) + ( SuperStackSortValueFunc Y ) + ) ) ) ) ) + + +;maps net names to terminal tables +;terminal tables map terminal type to list of instance names +(defun SuperStackCreateNetTable ( CellView ComponentInfos OtherInstances ) + (let ( + ( NetTable ( makeTable `net nil ) ) ) + ( SuperStackAddComponentInfosToNetTable NetTable ComponentInfos ) + ( SuperStackAddInstancesToNetTable NetTable OtherInstances ) + ( SuperStackAddExternalToNetTable NetTable CellView ) + NetTable ) ) + +(defun SuperStackCreateNetTableEntry ( NetTable NetName TermName InstanceName ) + (let ( + ( TermTable + (cond ( + ( arrayref NetTable NetName ) ) + ( + ( makeTable `term nil ) ) ) ) ) + ( setarray NetTable NetName TermTable ) + ( setarray TermTable TermName ( cons InstanceName + ( arrayref TermTable TermName ) ) ) ) ) + +(defun SuperStackAddExternalToNetTable ( NetTable CellView ) + ( foreach Net ( getq CellView nets ) + (if ( getq Net term ) + ( SuperStackCreateNetTableEntry NetTable ( getq Net name ) "EXTERNAL" nil ) ) ) ) + +(defun SuperStackAddComponentInfosToNetTable ( NetTable ComponentInfos ) + ( foreach ComponentInfo ComponentInfos + ( mapcar + (lambda ( Conn ) + ( SuperStackCreateNetTableEntry NetTable + ( cadr Conn ) + ( car Conn ) + ( ComponentInfoGetName ComponentInfo ) ) ) + + ( tableToList ( ComponentInfoGetConnTable ComponentInfo ) ) ) ) ) + +(defun SuperStackAddInstancesToNetTable ( NetTable Gates ) + ( foreach Gate Gates + ( foreach InstTerm ( getq Gate conns ) + ( SuperStackCreateNetTableEntry NetTable + ( getq ( getq InstTerm net ) name ) + ( getq InstTerm name ) + ( getq Gate name ) ) ) ) ) + + +(defun SuperStackSymbolMatch ( SuperStackSymbol1 SuperStackSymbol2 ) + ( and + ( or + ( equal ( car SuperStackSymbol1 ) ( car SuperStackSymbol2 ) ) + ( null ( car SuperStackSymbol1 ) ) + ( null ( car SuperStackSymbol2 ) ) ) + + ( or + ( equal ( cadr SuperStackSymbol1 ) ( cadr SuperStackSymbol2 ) ) + ( null ( cadr SuperStackSymbol1 ) ) + ( null ( cadr SuperStackSymbol2 ) ) ) +) ) + +(defun SuperStackCreateSingletonSuperStackSetsFromComponentInfos ( ComponentInfos + NetTable + GNDNetName + VddNetName + ) + "Seed a list of superstacksets with a componentinfo from each domain" + (let ( + ( Domains ( SuperStackGetDomains + ComponentInfos + NetTable + ( list GNDNetName + VddNetName ) ) ) ) + ( mapcar + (lambda ( Domain ) + (let ( + ( SuperStackSet ( makeTable `superstack nil ) ) ) + ( foreach ComponentInfo Domain + (let ( + ( SuperStackInfo + ( SuperStackCreateSuperStackInfoFromComponentInfo ComponentInfo ) ) ) + ( setarray SuperStackSet ( SuperStackGetSuperStackKey SuperStackInfo ) SuperStackInfo ) ) ) + SuperStackSet ) ) + Domains ) ) ) + + + +(defun SuperStackCreateSuperStackSetFromComponentInfos + ( NetTable + ComponentInfos + NonPowerMergeTestFuncInfoList + PowerMergeTestFuncInfoList + SuperStackSymbolMatchFunc + GetOverlapFunc + GNDNetName + VddNetName + BCutRings + BVerbose ) + + (let ( + ( SuperStackIsSymbolExternalToSuperStackFunc + (lambda ( Symbol SuperStackInfo ) + ( SuperStackIsSymbolExternalToSuperStackInfo + Symbol + SuperStackInfo + NetTable ) ) ) + ( DominoStackConstructor + ( SuperStackGetDefaultConstructor GetOverlapFunc ) ) + ;seed initial superstack for each domain + ( DomainSuperStackSets + ( SuperStackCreateSingletonSuperStackSetsFromComponentInfos + ComponentInfos + NetTable + GNDNetName + VddNetName + ) ) ) + + ( foreach + SuperStackSet + DomainSuperStackSets + ;merge together stacks using + ;the heuristics in NonPowerMergeTestFuncInfoList + ;superstacks stay within their domain at this point + ( DominoStackMergeDominoStackSet + SuperStackSet + NonPowerMergeTestFuncInfoList + DominoStackConstructor + SuperStackSymbolMatchFunc + BVerbose ) + (when BCutRings + ( DominoStackCutRings + SuperStackSet + ( list ( list + GNDNetName + VddNetName ) ) + SuperStackIsSymbolExternalToSuperStackFunc + SuperStackSymbolMatchFunc + DominoStackConstructor + ) ) + ) + + ;merge the domains together using the more conservative + ; heuristics in PowerMergeTestFuncInfoList + (let ( + ( DomainSuperStackSet + ( SuperStackFlattenSubSuperStackSets + DomainSuperStackSets ) ) ) + ( DominoStackMergeDominoStackSet + DomainSuperStackSet + PowerMergeTestFuncInfoList + DominoStackConstructor + SuperStackSymbolMatchFunc + BVerbose ) + (when BCutRings + ( DominoStackCutRings + DomainSuperStackSet + ( list ( list + GNDNetName + VddNetName ) ) + SuperStackIsSymbolExternalToSuperStackFunc + SuperStackSymbolMatchFunc + DominoStackConstructor ) ) + DomainSuperStackSet ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack_tools.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack_tools.il new file mode 100644 index 0000000000..9ab1d49c2f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/superstack_tools.il @@ -0,0 +1,882 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun SuperStackCalculateTotalHeightTotalAreaPairOfStackedComponentInfos + ( CellView + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentInfos + OtherInstances + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs + GNDNetName + VddNetName + BCutRings + BVerbose ) + (let ( + ( SuperStackSet + ( SuperStackCreateSuperStackSetFromComponentInfos_Default + CellView + ComponentInfos + OtherInstances + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs + GNDNetName + VddNetName + BCutRings + BVerbose ) ) ) + ( SuperStackCalculateTotalHeightTotalAreaPairOfSuperStackSet + SuperStackSet + ) ) ) + + +(defun SuperStackCalculateTotalHeightTotalAreaPairOfSuperStackSet + ( SuperStackSet ) + (let ( + ( GetOverlapFunc `SuperStackGetOverlap ) + ( TotalHeight 0.0 ) + ( TotalArea 0.0 ) ) + ( foreach + Key + SuperStackSet + (let ( + ( SuperStackInfo ( arrayref SuperStackSet Key ) ) ) + (let ( + ( Height ( SuperStackCalculateHeight + SuperStackInfo + GetOverlapFunc ) ) + ( Width ( SuperStackGetMaxWidth SuperStackInfo ) ) ) + + ( setq TotalHeight ( plus TotalHeight Height ) ) + ( setq TotalArea ( plus TotalArea ( times Height Width ) ) ) + ;( printf "height: %L width: %L\n" Height Width ) + ) ) ) + ( list TotalHeight TotalArea ) ) ) + + +(defun SuperStackCreateFromCellView ( CellView + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentPrefix + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs + GNDNetName + VddNetName + ComponentLibCellPairRegExs + BCutRings + BVerbose ) + (let ( + ( FilterResult + ( NameFilterInstances + ( getq CellView instances ) + ComponentLibCellPairRegExs ) ) ) + (let ( + ( Components + ( cadr FilterResult ) ) + ( Others + ( car FilterResult ) ) ) + (let ( + ( ComponentInfos + ( mapcar + (lambda ( Component ) + ( ComponentInfoCreateComponentInfoFromComponent Component ) ) + Components ) ) ) + + ( SuperStackCreateFromComponentInfos + CellView + ComponentInfos + Others + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentPrefix + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs + GNDNetName + VddNetName + BCutRings + BVerbose ) + + ( foreach Component Components + ( dbDeleteObject Component ) ) + + ) ) ) ) + + + +(defun SuperStackCreateSuperStackSetFromComponentInfos_Default + ( CellView + ComponentInfos + OtherInstances + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs + GNDNetName + VddNetName + BCutRings + BVerbose ) + (let ( + ( GetOverlapFunc `SuperStackGetOverlap ) + ( MergeFuncInfoLists + ( apply + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs ) ) ) + (let ( + ( NetTable + ( SuperStackCreateNetTable + CellView + ComponentInfos + OtherInstances ) ) ) + ( SuperStackCreateSuperStackSetFromComponentInfos + NetTable + ComponentInfos + ( car MergeFuncInfoLists ) + ( cadr MergeFuncInfoLists ) + `SuperStackSymbolMatch + GetOverlapFunc + GNDNetName + VddNetName + BCutRings + BVerbose ) ) ) ) + +(defun SuperStackCreateFromComponentInfos ( CellView + ComponentInfos + OtherInstances + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentPrefix + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs + GNDNetName + VddNetName + BCutRings + BVerbose ) + ( SuperStackCreateFromSuperStackSet + CellView + ( SuperStackCreateSuperStackSetFromComponentInfos_Default + CellView + ComponentInfos + OtherInstances + MergeFuncInfoListsFunc + MergeFuncInfoListsFuncArgs + GNDNetName + VddNetName + BCutRings + BVerbose ) + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentPrefix + BVerbose ) ) + +(defun SuperStackCreateStackGroupsFromClumpUsingPDKInfo + ( CellView + Clump ) + (let ( + ( N + ( cadr + ( NameFilterInstances + Clump + NChainLibCellPairRegExs ) ) ) + ( P + ( cadr + ( NameFilterInstances + Clump + PChainLibCellPairRegExs ) ) ) + ( G + ( cadr + ( NameFilterInstances + Clump + GateLibCellPairRegExs ) ) ) ) + ( mapcar + (lambda ( Group ) + ( SuperStackCreateFromGroupUsingPDKInfo + CellView + Group ) ) + ( list N P G ) ) ) ) + + +(defun SuperStackCompactStackGroup ( StackGroups ) + (let ( + ( Y ( ListFindMinimum + ( ListNonDestructiveMapCan + (lambda ( StackGroup ) + StackGroup ) + StackGroups ) + (lambda ( Stack ) + ( RectGetBottom ( getq Stack bBox ) ) ) ) ) + ( H ( ListFindMaximum + StackGroups + (lambda ( StackGroup ) + ( ListFindSum + StackGroup + (lambda ( Stack ) + ( RectGetHeight ( getq Stack bBox ) ) ) ) ) ) ) + ) + (when ( exists StackGroup StackGroups StackGroup ) + ( ListNonDestructiveMapCan + (lambda ( StackGroup ) + (when StackGroup + ( DeCompactVerticalKeepOrderDefault + StackGroup + ( list Y ( plus Y H ) ) + .05 + t ) ) + StackGroup + ) + StackGroups ) ) ) ) + + +(defun SuperStackFlipComponentInfos ( ComponentInfos ) + "Tries to greedily optimize the order of a stack according to this simple rule: flip the current component if the last one doesn't match the current, and if the current matches the next when flipped." + (let ( + ( Prev nil ) + ( Curr nil ) + ( Next nil ) + ) + + (while ( or ComponentInfos Curr ) + ( setq Prev Curr ) + ( setq Curr Next ) + ( setq Next ( car ComponentInfos ) ) + ;when + (when ( and + Curr + ( or + ( and + ;curr doesn't match previous + ( or ( null Prev ) + ( not ( SuperStackSymbolMatch + ( DominoGetTopSymbol Prev ) + ( DominoGetBottomSymbol Curr ) ) ) + ( not ( SuperStackIsSharable + ( ComponentInfoGetTopCSInfo Prev ) + ( ComponentInfoGetBottomCSInfo Curr ) ) ) + ) + ;but it matches next if flipped! + ( and Next + ( SuperStackSymbolMatch + ( DominoGetBottomSymbol Curr ) + ( DominoGetBottomSymbol Next ) ) + ( SuperStackIsSharable + ( ComponentInfoGetBottomCSInfo Curr ) + ( ComponentInfoGetBottomCSInfo Next ) ) + ) ) + ;or + ( and + ;curr doesn't match next + ( or ( null Next ) + ( not ( SuperStackSymbolMatch + ( DominoGetTopSymbol Curr ) + ( DominoGetBottomSymbol Next ) ) ) + ( not ( SuperStackIsSharable + ( ComponentInfoGetTopCSInfo Curr ) + ( ComponentInfoGetBottomCSInfo Next ) ) ) + ) + ;but it matches prev if flipped! + ( and Prev + ( SuperStackSymbolMatch + ( DominoGetTopSymbol Curr ) + ( DominoGetTopSymbol Prev ) ) + ( SuperStackIsSharable + ( ComponentInfoGetTopCSInfo Curr ) + ( ComponentInfoGetTopCSInfo Prev ) ) ) + ) ) ) + ;then flip curr! + ( ComponentInfoSetParity + Curr + ( null ( ComponentInfoGetParity Curr ) ) ) ) + ( setq ComponentInfos ( cdr ComponentInfos ) ) + ) ) ) + +(defun SuperStackCreateFromGroupUsingPDKInfo ( CellView + Group ) + (let ( + ( Info + (cond ( + ( cadr + ( NameFilterInstances + Group + NChainLibCellPairRegExs ) ) + ( list NSuperStackCellName NChainPrefix ) ) + ( + ( cadr + ( NameFilterInstances + Group + PChainLibCellPairRegExs ) ) + ( list PSuperStackCellName PChainPrefix ) ) + ( + ( cadr + ( NameFilterInstances + Group + GateLibCellPairRegExs ) ) + ( list GateSuperStackCellName GateChainPrefix ) ) ) ) + ( ComponentInfos + ( mapcar + (lambda ( Chain ) + ( ComponentInfoCreateComponentInfoFromComponent + Chain ) ) + Group ) ) + ) + + (let ( + ( Ret + ( SuperStackCreateFromComponentInfos_PreserveOrder + CellView + ComponentInfos + SuperStackLibraryName + ( car Info ) + SuperStackViewName + ( cadr Info ) + nil + ?Flip nil ) ) ) + ( foreach Component Group ( dbDeleteObject Component ) ) + Ret + ) ) ) + + +(defun SuperStackCreateSuperStackSetFromComponentInfos_PreserveOrder + ( ComponentInfos + @key + ( Flip t ) + ) + ( SuperStackCreateSuperStackSetFromComponentInfoClumps_PreserveOrder + ( list ComponentInfos ) + ?Flip Flip ) + ) +(defun SuperStackCreateSuperStackSetFromComponentInfoClumps_PreserveOrder + ( Clumps + @key + ( Flip t ) ) + (let ( + ( SuperStackSet ( makeTable `foo nil ) ) ) + (let ( + ( SuperStackInfos + ( mapcar + (lambda ( Clump ) + (let ( + ( SortedComponentInfos + ( sort ( copy Clump ) + (lambda ( C1 C2 ) + ( lessp ( RectGetBottom ( ComponentInfoGetBBox C1 ) ) + ( RectGetBottom ( ComponentInfoGetBBox C2 ) ) + ) ) ) ) ) + (when Flip + ( SuperStackFlipComponentInfos + SortedComponentInfos ) ) + ( SuperStackCreateSuperStackInfoFromComponentInfoList + SortedComponentInfos + nil + nil + ) ) ) + Clumps ) ) ) + + ( foreach SuperStackInfo SuperStackInfos + (when ( DominoStackGetDominoList SuperStackInfo ) + ( DominoStackAdd + SuperStackInfo + SuperStackSet ) ) ) + SuperStackSet + ) ) ) + +(defun SuperStackStackSuperStackSet ( SuperStackSet ) + "merges superstacks in a superstack set into a single superstack, which is just the original superstacks ordered by their original y location" + (let ( + ( NewSuperStackSet ( makeTable `foo nil ) ) ) + (let ( + ( SortedComponentInfos + ( mapcan + (lambda ( SuperStackInfo ) + ( copy ( SuperStackGetComponentInfoList + SuperStackInfo ) ) ) + ;sorted superstackinfos + ( sort ( mapcar `cadr ( tableToList SuperStackSet ) ) + (lambda ( CIL1 CIL2 ) + ( lessp + ( RectGetBottom + ( ComponentInfoGetBBox ( DominoStackGetBottomDomino CIL1 ) ) ) + ( RectGetBottom + ( ComponentInfoGetBBox ( DominoStackGetBottomDomino CIL2 ) ) ) ) ) ) ) ) ) + (when SortedComponentInfos + ( SuperStackFlipComponentInfos + SortedComponentInfos ) + ( DominoStackAdd + ( SuperStackCreateSuperStackInfoFromComponentInfoList + SortedComponentInfos + nil + nil + ) + NewSuperStackSet ) ) + NewSuperStackSet + ) ) ) + +(defun SuperStackCreateFromComponentInfos_PreserveOrder ( CellView + ComponentInfos + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentPrefix + BVerbose + @key + ( Flip t ) + ) + ( SuperStackCreateFromSuperStackSet + CellView + ( SuperStackCreateSuperStackSetFromComponentInfos_PreserveOrder + ComponentInfos + ?Flip Flip ) + SuperStackLibName + SuperStackCellName + SuperStackViewName + ComponentPrefix + BVerbose + ) ) + + +(defun SuperStackRefoldAndChainChainsToSuperStackSet ( CellView + Chains + ColumnWidth + RegionOffsetFromColumnCenter + UserUnitsPerMeter + RoundToNearest + MergeParams + GNDNetName + VddNetName + PreferEvenFolds + ) + "Fold chains and put them in a single stack so that they fit in ColumnWidth" + (let ( + ( ChainInfos + ( ListNonDestructiveMapCan + (lambda ( Chain ) + ( ChainFoldToChainInfos + CellView + Chain + ( difference + ColumnWidth + RegionOffsetFromColumnCenter ) + UserUnitsPerMeter + RoundToNearest + PreferEvenFolds ) ) + Chains + ) ) ) + ;if no folding, leave it be + (cond ( + ( equal ( length ChainInfos ) + ( length Chains ) ) + t ;don't fold for now + ( SuperStackCreateSuperStackSetFromComponentInfos_PreserveOrder + ( mapcar + (lambda ( Chain ) + ( ComponentInfoCreateComponentInfoFromComponent Chain ) ) + Chains ) ) ) + ( + t + (let ( + ( Others + ( ListDifference + ( getq CellView instances ) + Chains + `equal + nil + ) ) ) + ;put the superstacks together + ( SuperStackStackSuperStackSet + ( SuperStackCreateSuperStackSetFromComponentInfos_Default + CellView + ChainInfos + Others + `SuperStackGetDefaultMergeFuncInfoLists_Chain + MergeParams + GNDNetName + VddNetName + t + nil ) ) ) ) ) ) ) + + +(defun SuperStackGetDefaultMergeFuncInfoLists_Chain ( MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight ) + (unless ( fboundp `SuperStackIsSharable ) + (error "Must define SuperStackIsSharable function in PDK!" ) ) + + (unless ( fboundp `SuperStackGetOverlap ) + (error "Must define SuperStackGetOverlap function in PDK!" ) ) + (let ( + ( IsSharableFunc + `SuperStackIsSharable ) + ( GetOverlapFunc + `SuperStackGetOverlap ) ) + (let ( + ( MergeTest_Match + ( list `SuperStackMergeTest_Match + ( list IsSharableFunc ) ) ) + ( MergeTest_MaxHeight + ( list `SuperStackMergeTest_Height + ( list MaxMergeHeight GetOverlapFunc ) ) ) + ( NonPowerMergeTest_Height + ( list `SuperStackMergeTest_Height + ( list MaxNonPowerMergeHeight GetOverlapFunc ) ) ) + ( PowerMergeTest_Height + ( list `SuperStackMergeTest_Height + ( list MaxPowerMergeHeight GetOverlapFunc ) ) ) ) + (let ( + ( NonPowerMergeTestFuncInfoList + ( list + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + ( list `SuperStackMergeTest_FoldsOfSameStack nil ) + MergeTest_MaxHeight + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + ( list `SuperStackMergeTest_SameEnds nil ) + MergeTest_MaxHeight + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + ( list `SuperStackMergeTest_ShareNet ( list "[0-9]+-H" ) ) + MergeTest_MaxHeight + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_MaxHeight + MergeTest_Match + ( list `SuperStackMergeTest_AnyShareNet ( list "[0-9]+-H" ) ) + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + NonPowerMergeTest_Height + MergeTest_Match + ( list `SuperStackMergeTest_Width ( list 1.0 ) ) + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + NonPowerMergeTest_Height + MergeTest_Match + ( list `SuperStackMergeTest_Width ( list 1.5 ) ) + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + ( list `SuperStackMergeTest_Height + ( list ( times 0.5 ( plus MaxMergeHeight + MaxNonPowerMergeHeight ) ) + GetOverlapFunc ) ) + ( list `SuperStackMergeTest_AnyShareNet ( list "[0-9]+-H" ) ) + ) ) ) + ) ) + ( PowerMergeTestFuncInfoList + ( list + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + ( list `SuperStackMergeTest_Width ( list 1.0 ) ) + PowerMergeTest_Height + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + ( list `SuperStackMergeTest_Width ( list 1.5 ) ) + PowerMergeTest_Height + ) ) ) ) ) + ) + ( list + NonPowerMergeTestFuncInfoList + PowerMergeTestFuncInfoList + ) ) ) ) ) + + +(defun SuperStackGetDefaultMergeFuncInfoLists_Gate ( MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight + GNDNetName + VddNetName ) + (unless ( fboundp `SuperStackIsSharable ) + (error "Must define SuperStackIsSharable function in PDK!" ) ) + + (unless ( fboundp `SuperStackGetOverlap ) + (error "Must define SuperStackGetOverlap function in PDK!" ) ) + (let ( + ( IsSharableFunc + `SuperStackIsSharable ) + ( GetOverlapFunc + `SuperStackGetOverlap ) ) + (let ( + ( MergeTest_ShareNonPower + ( list `SuperStackMergeTest_ShareNonPower + ( list ( list GNDNetName + VddNetName ) ) ) ) + ( MergeTest_AnyShareNonPower + ( list `SuperStackMergeTest_AnyShareNonPower + ( list ( list GNDNetName + VddNetName ) ) ) ) + ( MergeTest_Match + ( list `SuperStackMergeTest_Match + ( list IsSharableFunc ) ) ) + ( NonPowerMergeTest_Height + ( list `SuperStackMergeTest_Height + ( list MaxNonPowerMergeHeight GetOverlapFunc ) ) ) + ( PowerMergeTest_Height + ( list `SuperStackMergeTest_Height + ( list MaxPowerMergeHeight GetOverlapFunc ) ) ) ) + (let ( + ( NonPowerMergeTestFuncInfoList + nil ) + ( PowerMergeTestFuncInfoList + ( list + ( list `SuperStackAndFuncs + ( list + ( list + ( list `SuperStackMergeTest_2Sided nil ) + MergeTest_Match + MergeTest_ShareNonPower + PowerMergeTest_Height + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + ( list `SuperStackMergeTest_Width ( list 1.0 ) ) + MergeTest_ShareNonPower + PowerMergeTest_Height + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + MergeTest_ShareNonPower + PowerMergeTest_Height + ) ) ) + ( list `SuperStackAndFuncs + ( list + ( list + MergeTest_Match + MergeTest_AnyShareNonPower + PowerMergeTest_Height + ) ) ) ) ) + ) + ( list + NonPowerMergeTestFuncInfoList + PowerMergeTestFuncInfoList + ) ) ) ) ) + +;;;;;;;;;;;;;;;;;;;;;; +;; MergeTestFuncs +;;;;;;;;;;;;;;;;;;;;;; + +(defun SuperStackAndFuncs ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 FuncInfoList ) + ( ListAndFuncs + ( mapcar + (lambda ( FuncInfo ) + ( list ( car FuncInfo ) + ( append ( list SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 ) + ( cadr FuncInfo ) ) ) ) + FuncInfoList ) ) ) + +(defun SuperStackMergeTest_Height ( SuperStackInfoAndNodeIndex1 + SuperStackInfoAndNodeIndex2 + MaxHeight + GetOverlapFunc + ) + ( leqp ( plus ( SuperStackGetHeight + ( car SuperStackInfoAndNodeIndex1 ) ) + ( SuperStackGetHeight + ( car SuperStackInfoAndNodeIndex2 ) ) + ) + MaxHeight ) ) + + + +; ------------------------ Heuristics -------------- + +(defun SuperStackMergeTest_Match ( SuperStackInfoAndNodeIndex1 + SuperStackInfoAndNodeIndex2 + SuperStackIsSharableFunc ) + ( and + ( SuperStackSymbolMatch + ( DominoStackGetSymbolFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex1 ) + ( DominoStackGetSymbolFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex2 ) ) + (let ( + ( ComponentInfoAndNodeIndex1 + ( DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex1 ) ) + ( ComponentInfoAndNodeIndex2 + ( DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex2 ) ) ) + (let ( + ( CSProps1 (if ( cadr ComponentInfoAndNodeIndex1 ) + ( ComponentInfoGetTopCSInfo + ( car ComponentInfoAndNodeIndex1 ) ) + ( ComponentInfoGetBottomCSInfo + ( car ComponentInfoAndNodeIndex1 ) ) ) ) + ( CSProps2 (if ( cadr ComponentInfoAndNodeIndex2 ) + ( ComponentInfoGetTopCSInfo + ( car ComponentInfoAndNodeIndex2 ) ) + ( ComponentInfoGetBottomCSInfo + ( car ComponentInfoAndNodeIndex2 ) ) ) ) ) + + ( apply SuperStackIsSharableFunc + ( list CSProps1 CSProps2 ) ) ) ) ) ) + + + +(defun SuperStackMergeTest_ShareNet ( SuperStackInfoAndNodeIndex1 + SuperStackInfoAndNodeIndex2 + NetRegEx ) + (let ( + ( ComponentInfoAndNodeIndex1 + ( DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex1 ) ) + ( ComponentInfoAndNodeIndex2 + ( DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex2 ) ) + ) + ( rexCompile NetRegEx ) + (let ( + ( ConnTable1 + ( ComponentInfoGetConnTable ( car ComponentInfoAndNodeIndex1 ) ) ) + ( ConnTable2 + ( ComponentInfoGetConnTable ( car ComponentInfoAndNodeIndex2 ) ) ) ) + ( exists Term1 ConnTable1 + ( exists Term2 ConnTable2 + ( and ( equal ( arrayref ConnTable1 Term1 ) ( arrayref ConnTable2 Term2 ) ) + ( rexExecute ( arrayref ConnTable1 Term1 ) ) ) ) ) ) ) ) + +(defun SuperStackMergeTest_AnyShareNet ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 NetRexEx ) + ( exists + ComponentInfo1 + ( SuperStackGetComponentInfoList + ( car SuperStackInfoAndNodeIndex1 ) ) + ( exists + ComponentInfo2 + ( SuperStackGetComponentInfoList + ( car SuperStackInfoAndNodeIndex2 ) ) + (let ( + ( ConnTable1 ( ComponentInfoGetConnTable ComponentInfo1 ) ) + ( ConnTable2 ( ComponentInfoGetConnTable ComponentInfo2 ) ) ) + ( exists Term1 ConnTable1 + ( exists Term2 ConnTable2 + ( and ( equal ( arrayref ConnTable1 Term1 ) ( arrayref ConnTable2 Term2 ) ) + ( rexExecute ( arrayref ConnTable1 Term1 ) ) ) ) ) ) ) ) ) + + +(defun SuperStackMergeTest_ShareNonPower ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 PowerNetNames ) + (let ( + ( ComponentInfoAndNodeIndex1 + ( DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex1 ) ) + ( ComponentInfoAndNodeIndex2 + ( DominoStackGetDominoAndNodeIndexFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex2 ) ) ) + (let ( + ( ConnTable1 ( ComponentInfoGetConnTable ( car ComponentInfoAndNodeIndex1 ) ) ) + ( ConnTable2 ( ComponentInfoGetConnTable ( car ComponentInfoAndNodeIndex2 ) ) ) ) + ( exists Term1 ConnTable1 + ( exists Term2 ConnTable2 + ( and ( equal ( arrayref ConnTable1 Term1 ) + ( arrayref ConnTable2 Term2 ) ) + ( not ( exists PowerNetName PowerNetNames + ( equal ( arrayref ConnTable1 Term1 ) PowerNetName ) ) ) ) ) ) ) ) ) + + +(defun SuperStackMergeTest_AnyShareNonPower ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 PowerNetNames ) + "Tests if any non-power net is shared between 2 superstacks." + ( exists + ComponentInfo1 + ( SuperStackGetComponentInfoList + ( car SuperStackInfoAndNodeIndex1 ) ) + ( exists + ComponentInfo2 + ( SuperStackGetComponentInfoList + ( car SuperStackInfoAndNodeIndex2 ) ) + (let ( + ( ConnTable1 ( ComponentInfoGetConnTable ComponentInfo1 ) ) + ( ConnTable2 ( ComponentInfoGetConnTable ComponentInfo2 ) ) ) + ( exists Term1 ConnTable1 + ( exists Term2 ConnTable2 + ( and ( equal + ( arrayref ConnTable1 Term1 ) + ( arrayref ConnTable2 Term2 ) ) + ( not ( exists + PowerNetName + PowerNetNames + ( equal + ( arrayref ConnTable1 Term1 ) + PowerNetName ) ) ) ) ) ) ) ) ) ) + +(defun SuperStackMergeTest_2Sided ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 ) + "Tests to see if one of 2 superstacks is not a ring." + ( or + ( and + ( or + ( car ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex1 ) ) ) + ( cadr ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex1 ) ) ) ) + ( or + ( car ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex1 ) ) ) + ( cadr ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex1 ) ) ) ) ) + ( and + ( or + ( car ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) + ( cadr ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) ) + ( or + ( car ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) + ( cadr ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) ) ) ) ) + +(defun SuperStackMergeTest_FoldsOfSameStack ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 ) + "Tests if components of 2 superstacks have same canonical name, and are thus from the same chain." + (let ( + ( Name1 ( NameCanonicalizeFoldableInstanceName + ( ComponentInfoGetName + ( DominoStackGetDominoFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex1 ) ) ) ) + ( Name2 ( NameCanonicalizeFoldableInstanceName + ( ComponentInfoGetName + ( DominoStackGetDominoFromDominoStackAndNodeIndex + SuperStackInfoAndNodeIndex2 ) ) ) ) ) + ( equal Name1 Name2 ) ) ) + +(defun SuperStackMergeTest_SameEnds ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 ) + "Tests if both sides match on 2 superstacks" + ( or + ( and ( SuperStackSymbolMatch + ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex1 ) ) + ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) + ( SuperStackSymbolMatch + ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex1 ) ) + ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) ) + + ( and ( SuperStackSymbolMatch + ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex1 ) ) + ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) + ( SuperStackSymbolMatch + ( DominoStackGetTopSymbol ( car SuperStackInfoAndNodeIndex1 ) ) + ( DominoStackGetBottomSymbol ( car SuperStackInfoAndNodeIndex2 ) ) ) ) ) ) + +(defun SuperStackMergeTest_Width ( SuperStackInfoAndNodeIndex1 SuperStackInfoAndNodeIndex2 WidthRatioThreshold ) + "Tests if 2 superstacks widths are within a threshold ratio" + (let ( + ( MinWidth ( min ( SuperStackGetMinWidth ( car SuperStackInfoAndNodeIndex1 ) ) + ( SuperStackGetMinWidth ( car SuperStackInfoAndNodeIndex2 ) ) ) ) + ( MaxWidth ( max ( SuperStackGetMaxWidth ( car SuperStackInfoAndNodeIndex1 ) ) + ( SuperStackGetMaxWidth ( car SuperStackInfoAndNodeIndex2 ) ) ) ) ) + ( leqp ( quotient MaxWidth MinWidth ) WidthRatioThreshold ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/unstack.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/unstack.il new file mode 100644 index 0000000000..e780040712 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/unstack.il @@ -0,0 +1,495 @@ +/** + * INTEL TOP SECRET + * Copyright 2002-2012 Intel Corporation. All Rights Reserved. + * $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/chain/unstack.il#2 $ + */ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +/*DOC +This module contains functions for the post processing of the SUPERSTACK, aimed at making the output chain of stacks/gates DRC correct. + +The following issues are encountered with the current (TSMC65) SUPERSTACK when used in TSMC28nm tecnology + +1) + When two gates' contacts are shared, the smaller gate's diffusion contacts are turned off. + So the smaller gate's poly input contacts are needed to be spaced away from the diffusion, to avoid the DRCs. + +2) + The fabrication rules need the OD to be either of T, L or U shapes. + Thus the SUPERSTACK generated needs to go through post-processing step to detect the shared OD shapes and "UNSTACK" them to allowable shapes + +3) + This can be a pre-processing step for the SUPERSTACK to cluster and arrage the domino logic or the gates, based on a set priority. + +*/ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;Define Constants +(defvar SharedOverlap 0.18) +(defvar UnSharedOverlap 0.05) + +;;;;;;;;;;;;;;; +; Compares the physical Y locations of two Instances +procedure( UnStackCompareLLY( InstX InstY ) + + lessp(cadar(InstX~>bBox) cadar(InstY~>bBox)) + +) + +;;;;;;;;;;;;;;; +; Sorts the list in incrementing order of physical Y location +procedure( UnStackSortYOrder( SelectedList ) + + sort(SelectedList 'UnStackCompareLLY) + +) + +;;;;;;;;;;;;;;; +; +procedure( UnStackInstSharedOnTop( Inst TopInst ) + let( ( InstOverlap ) + + InstOverlap = round((cadadr(Inst~>bBox)-cadar(TopInst~>bBox))*100)/100.00 + + equal(InstOverlap SharedOverlap) + ) +) + +;;;;;;;;;;;;;;; +; +procedure( UnStackInstSharedOnBottom( Inst BottomInst ) + let( ( InstOverlap ) + + InstOverlap = round((cadadr(BottomInst~>bBox)-cadar(Inst~>bBox))*100)/100.00 + equal(InstOverlap SharedOverlap) + ) +) + +;;;;;;;;;;;;;;; +; +procedure( UnStackGetNColumnWidth( Inst ) + + let( ( NWidth + GateName + ) + + NWidth = nil + + when( car(parseString(Inst~>cellName ".")) == "gate" + GateName = nth(1 parseString(Inst~>cellName ".")) + ) + + when( car(parseString(Inst~>cellName ".")) == "stack" + GateName = strcat("NW" nth(2 parseString(nth(1 parseString(Inst~>cellName ".")) "_"))) + ) + + case( GateName + + ( "INV" || "NOR2" || "NOR3" || "NW1" + when( dbGet(Inst "NW1") + NWidth = dbGet(Inst "NW1") / UnStackGetFolds(Inst) + ) + ) + + ( "NAND2" || "C2" || "C2_STAT" || "NW2" + when( dbGet(Inst "NW2") + NWidth = dbGet(Inst "NW2") / UnStackGetFolds(Inst) + ) + ) + + ( "NAND3" || "NW3" + when( dbGet(Inst "NW3") + NWidth = dbGet(Inst "NW3") / UnStackGetFolds(Inst) + ) + ) + + ( "NAND4" || "NW4" + when( dbGet(Inst "NW4") + NWidth = dbGet(Inst "NW4") / UnStackGetFolds(Inst) + ) + ) + + ( "NAND5" || "NW5" + when( dbGet(Inst "NW5") + NWidth = dbGet(Inst "NW5") / UnStackGetFolds(Inst) + ) + ) + + ( "NW6" + when( dbGet(Inst "NW6") + NWidth = dbGet(Inst "NW6") / UnStackGetFolds(Inst) + ) + ) + ) + ) +) + +;;;;;;;;;;;;;;; +; +procedure( UnStackGetPColumnWidth( Inst ) + + let( ( PWidth + GateName + ) + + PWidth = nil + + when( car(parseString(Inst~>cellName ".")) == "gate" + GateName = nth(1 parseString(Inst~>cellName ".")) + ) + + when( car(parseString(Inst~>cellName ".")) == "stack" + GateName = strcat("PW" nth(2 parseString(nth(1 parseString(Inst~>cellName ".")) "_"))) + ) + + case( GateName + + ( "INV" || "NAND2" || "NAND3" || "NAND4" || "NAND5" || "PW1" + when( dbGet(Inst "PW1") + PWidth = dbGet(Inst "PW1") / UnStackGetFolds(Inst) + ) + ) + + ( "NOR2" || "C2" || "C2_STAT" || "PW2" + when( dbGet(Inst "PW2") + PWidth = dbGet(Inst "PW2") / UnStackGetFolds(Inst) + ) + ) + + ( "NOR3" || "PW3" + when( dbGet(Inst "PW3") + PWidth = dbGet(Inst "PW3") / UnStackGetFolds(Inst) + ) + ) + + ( "PW4" + when( dbGet(Inst "PW4") + PWidth = dbGet(Inst "PW4") / UnStackGetFolds(Inst) + ) + ) + ) + ) +) + +;;;;;;;;;;;;;;; +; +procedure( UnStackGetFolds( Inst ) + + let( ( Folds + GateName + GateNum + ) + + GateName = nth(1 parseString(Inst~>cellName ".")) + + case( GateName + + ( "INV" + Folds = round((((cadadr(Inst~>bBox) - cadar(Inst~>bBox)) - 0.31) / 0.13) + 1) + ) + ( "C2_STAT" + Folds = 2 + ) + ( t + GateNum = evalstring(substring(GateName strlen(GateName) 1)) + Folds = round(((((cadadr(Inst~>bBox) - cadar(Inst~>bBox)) - 0.31) / 0.13) + 1) / GateNum) + ) + ) + Folds + ) +) + +;;;;;;;;;;;;;;; +; +defun( UnStackAdjustPolyContacts ( SelectedList ) + +;defun( UnStackAdjustPolyContacts () + + let( ( I + PrevInst + CurrInst + NextInst + SortedList + TempSelectedList GateName + NPolyAdjustTop + PPolyAdjustTop + NPolyAdjustBottom + PPolyAdjustBottom + ) + + TempSelectedList = SelectedList +; SelectedList = geGetSelectedSet() + SortedList = UnStackSortYOrder(TempSelectedList) + + UnStackReadListNames() + + for( I 0 length(SortedList) + + NPolyAdjustTop = 0.05 + PPolyAdjustTop = 0.05 + NPolyAdjustBottom = 0.05 + PPolyAdjustBottom = 0.05 + + when( nth(I SortedList) != nil + CurrInst = nth(I SortedList) + + GateName = nth(1 parseString(CurrInst~>cellName ".")) + + when( I == 0 + NextInst = nth(1 SortedList) + when( UnStackInstSharedOnTop(CurrInst NextInst) && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(NextInst))) + PPolyAdjustTop = PPolyAdjustTop + when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) (UnStackGetPColumnWidth(NextInst) - UnStackGetPColumnWidth(CurrInst))* 1e6) ; + dbGet(CurrInst "poly_contact_offset") + println(PPolyAdjustTop) + ) + when( UnStackInstSharedOnTop(CurrInst NextInst) && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(NextInst))) + NPolyAdjustTop = NPolyAdjustTop + when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) (UnStackGetNColumnWidth(NextInst) - UnStackGetNColumnWidth(CurrInst))* 1e6) ; + dbGet(CurrInst "poly_contact_offset") + println(NPolyAdjustTop) + ) + dbSet(CurrInst NPolyAdjustTop "n_contact_offset") + dbSet(CurrInst PPolyAdjustTop "p_contact_offset") + ) + + when( I == (length(SortedList) - 1) + PrevInst = nth(I-1 SortedList) + when( UnStackInstSharedOnBottom(CurrInst PrevInst) && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(PrevInst))) + PPolyAdjustBottom = PPolyAdjustBottom + when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) (UnStackGetPColumnWidth(PrevInst) - UnStackGetPColumnWidth(CurrInst)) * 1e6) ; + dbGet(CurrInst "poly_contact_offset") + ) + when( UnStackInstSharedOnBottom(CurrInst PrevInst) && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(PrevInst))) + NPolyAdjustBottom = NPolyAdjustBottom + when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) (UnStackGetNColumnWidth(PrevInst) - UnStackGetNColumnWidth(CurrInst)) * 1e6) ; + dbGet(CurrInst "poly_contact_offset") + ) + dbSet(CurrInst NPolyAdjustBottom "n_contact_offset") + dbSet(CurrInst PPolyAdjustBottom "p_contact_offset") + ) + + when( I > 0 && I < (length(SortedList) - 1) + PrevInst = nth(I-1 SortedList) + NextInst = nth(I+1 SortedList) + when( UnStackInstSharedOnTop(CurrInst NextInst) && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(NextInst))) + NPolyAdjustTop = NPolyAdjustTop + when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) (UnStackGetNColumnWidth(NextInst) - UnStackGetNColumnWidth(CurrInst)) * 1e6) ; + dbGet(CurrInst "poly_contact_offset") + ) + when( UnStackInstSharedOnTop(CurrInst NextInst) && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(NextInst))) + PPolyAdjustTop = PPolyAdjustTop + when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) (UnStackGetPColumnWidth(NextInst) - UnStackGetPColumnWidth(CurrInst)) * 1e6) ; + dbGet(CurrInst "poly_contact_offset") + ) + when( UnStackInstSharedOnBottom(CurrInst PrevInst) && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(PrevInst))) + NPolyAdjustBottom = NPolyAdjustBottom + when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) (UnStackGetNColumnWidth(PrevInst) - UnStackGetNColumnWidth(CurrInst)) * 1e6) ; + dbGet(CurrInst "poly_contact_offset") + ) + when( UnStackInstSharedOnBottom(CurrInst PrevInst) && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(PrevInst))) + PPolyAdjustBottom = PPolyAdjustBottom + when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) (UnStackGetPColumnWidth(PrevInst) - UnStackGetPColumnWidth(CurrInst)) * 1e6) ; + dbGet(CurrInst "poly_contact_offset") + ) + if( NPolyAdjustTop >= NPolyAdjustBottom + then + dbSet(CurrInst NPolyAdjustTop "n_contact_offset") + else + dbSet(CurrInst NPolyAdjustBottom "n_contact_offset") + ) + if( PPolyAdjustTop >= PPolyAdjustBottom + then + dbSet(CurrInst PPolyAdjustTop "p_contact_offset") + else + dbSet(CurrInst PPolyAdjustBottom "p_contact_offset") + ) + ) + ) + ) + ) +) + +;;;;;;;;;;;;;;; +; +defun( UnStackAdjustDiffusion (SelectList) + let( ( I + PrevInst + CurrInst + NextInst + SortedList + TempSelectedList + + NIsLTForm PIsLTForm NIsTForm PIsTForm NIsLUForm PIsLUForm NIsUForm PIsUForm + NIsStepForm PIsStepForm + ) + + TempSelectedList = SelectList + SortedList = UnStackSortYOrder(TempSelectedList) + + NIsLTForm = nil + PIsLTForm = nil + NIsTForm = nil + PIsTForm = nil + NIsLUForm = nil + PIsLUForm = nil + NIsUForm = nil + PIsUForm = nil + + for( I 0 length(SortedList) + + when( nth(I SortedList) != nil + CurrInst = nth(I SortedList) + + when( I == 0 + NextInst = nth(1 SortedList) + when( UnStackInstSharedOnTop(CurrInst NextInst) + NIsLTForm = when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(NextInst))) + NIsLUForm = when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(NextInst) UnStackGetNColumnWidth(CurrInst))) + PIsLTForm = when(UnStackGetPColumnWidth(NextInst)&&UnStackGetPColumnWidth(CurrInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(NextInst))) + PIsLUForm = when(UnStackGetPColumnWidth(NextInst)&&UnStackGetPColumnWidth(CurrInst) lessp(UnStackGetPColumnWidth(NextInst) UnStackGetPColumnWidth(CurrInst))) + ) + ) + + when( I > 0 && I < (length(SortedList) - 1) + + println(I) + + NextInst = nth(I+1 SortedList) + + if( NIsLTForm || NIsLUForm || PIsLTForm || PIsLUForm + then + if( NIsStepForm || PIsStepForm + then + when( UnStackInstSharedOnTop(CurrInst NextInst) + ; when( (UnStackGetPColumnWidth(CurrInst) != UnStackGetPColumnWidth(NextInst)) || (UnStackGetNColumnWidth(CurrInst) != UnStackGetNColumnWidth(NextInst)) + UnStackUnShareInstance(I+1 SortedList) + println("hello") + NIsStepForm = nil + PIsStepForm = nil + NIsTForm = nil + NIsUForm = nil + PIsTForm = nil + PIsUForm = nil + NIsLTForm = nil + NIsLUForm = nil + PIsLTForm = nil + PIsLUForm = nil + ; ) + ) + + else + when( UnStackInstSharedOnTop(CurrInst NextInst) + NIsStepForm = (NIsLTForm && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(NextInst)))) || (NIsLUForm && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(NextInst) UnStackGetNColumnWidth(CurrInst)))) + PIsStepForm = (PIsLTForm && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(NextInst)))) || (PIsLUForm && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(NextInst) UnStackGetPColumnWidth(CurrInst)))) + ) + ) + if( NIsTForm || NIsUForm || PIsTForm || PIsUForm + then + when( UnStackInstSharedOnTop(CurrInst NextInst) + when( (UnStackGetPColumnWidth(CurrInst) != UnStackGetPColumnWidth(NextInst)) || (UnStackGetNColumnWidth(CurrInst) != UnStackGetNColumnWidth(NextInst)) + UnStackUnShareInstance(I+1 SortedList) + NIsStepForm = nil + PIsStepForm = nil + NIsTForm = nil + NIsUForm = nil + NIsLTForm = nil + NIsLUForm = nil + PIsTForm = nil + PIsUForm = nil + PIsLTForm = nil + PIsLUForm = nil + ) + ) + + else + when( UnStackInstSharedOnTop(CurrInst NextInst) + NIsTForm = NIsLTForm && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(NextInst) UnStackGetNColumnWidth(CurrInst))) + NIsUForm = NIsLUForm && when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(NextInst))) + PIsTForm = PIsLTForm && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(NextInst) UnStackGetPColumnWidth(CurrInst))) + PIsUForm = PIsLUForm && when(UnStackGetPColumnWidth(CurrInst)&&UnStackGetPColumnWidth(NextInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(NextInst))) + ) + ) + else + when( UnStackInstSharedOnTop(CurrInst NextInst) + NIsLTForm = when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(CurrInst) UnStackGetNColumnWidth(NextInst))) + NIsLUForm = when(UnStackGetNColumnWidth(CurrInst)&&UnStackGetNColumnWidth(NextInst) lessp(UnStackGetNColumnWidth(NextInst) UnStackGetNColumnWidth(CurrInst))) + PIsLTForm = when(UnStackGetPColumnWidth(NextInst)&&UnStackGetPColumnWidth(CurrInst) lessp(UnStackGetPColumnWidth(CurrInst) UnStackGetPColumnWidth(NextInst))) + PIsLUForm = when(UnStackGetPColumnWidth(NextInst)&&UnStackGetPColumnWidth(CurrInst) lessp(UnStackGetPColumnWidth(NextInst) UnStackGetPColumnWidth(CurrInst))) + ) + ) + ) + + ) + );for + );let +t +);func + + +;;;;;;;;;;;;;;; +; +defun( UnStackUnShareInstance (Index SortedList) + + let( ( I + CurrInst + PrevInst + NewYLoc + ) + + for( I Index length(SortedList)-1 + CurrInst = nth(I SortedList) +; println(CurrInst~>name) +; println(CurrInst~>orient) + when( I==Index + PrevInst = nth(I-1 SortedList) + UnStackTurnContON(CurrInst CurrInst~>orient "BOTTOM") + UnStackTurnContON(PrevInst PrevInst~>orient "TOP") + ) + NewYLoc = list(car(CurrInst~>xy) cadr(CurrInst~>xy)+(SharedOverlap - UnSharedOverlap)) + dbSet(CurrInst NewYLoc "xy") + ) + + t + ) +) +;;;;;;;;;;;;;;; +; +defun( UnStackTurnContON (Inst Orient Loc) + + case( Orient + + ( "R0" || "MY" + when( Loc == "TOP" + dbSet(Inst "FALSE" "share_top_Pcontacts") + dbSet(Inst "FALSE" "share_top_Ncontacts") + ) + when( Loc == "BOTTOM" + dbSet(Inst "FALSE" "share_bottom_Pcontacts") + dbSet(Inst "FALSE" "share_bottom_Ncontacts") + ) + ) + + ( "R180" || "MX" + when( Loc == "TOP" + dbSet(Inst "FALSE" "share_bottom_Pcontacts") + dbSet(Inst "FALSE" "share_bottom_Ncontacts") + ) + when( Loc == "BOTTOM" + dbSet(Inst "FALSE" "share_top_Pcontacts") + dbSet(Inst "FALSE" "share_top_Ncontacts") + ) + ) + ) +) +;;;;;;;;;;;;;;; +; +; defun( UnStackReadListNames ( SelectedList ) + +defun( UnStackReadListNames () + + let( ( I + SelectedList + SortedList + ) + + SelectedList = geGetSelectedSet() + + SortedList = UnStackSortYOrder(SelectedList) + + for( I 0 length(SortedList) + when( nth(I SortedList) != nil + println((nth(I SortedList)~>name)) + println(UnStackGetFolds(nth(I SortedList))) + println(UnStackGetNColumnWidth(nth(I SortedList))) + println(UnStackGetPColumnWidth(nth(I SortedList))) + ) + ) + + ) ;let +t +) ;defun diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/density/density.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/density/density.il new file mode 100644 index 0000000000..3caacb2a4b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/density/density.il @@ -0,0 +1,543 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +

    Description

    +Determines area usage for mid level cells based on prBoundary layer.
    + +

    References

    +Used by . +Uses for mid level cell layer operations. + +

    Output format

    +
    +
    leaf cells +
     [cellname] density: %g area: %g transistor_width: %g count(count,cdl_transistors,layout_transistors) gate: %d %d %d chain: %d %d %d flat: %d %d %d.
    +Where: +
    +
    density +
    (total transistor gate area/prBoundary area) +
    area +
    total transistor gate area +
    transistor width +
    The total of all transistor gate widths +
    count +
    transistor counts. cdl_transistors is the number of transistors from the schematic that were implemented. layout_transistors is the total number of transistors drawn by gates/stacks. The counts are then broken up by whether they were found in gates, chains, or flat nmos/pmos. +
    +
    mid-level cells +
    [cellname] cover '%s leaf: %g merge: %g bound: %g subcell: %g box: %g'.
    +
    +
    leaf +
    The leaf cell bounding box area. +
    merge +
    The area of the bloated-merged-shrunk leaf cell boundaries. Bloating is by one bitpitch. +
    bound +
    The area of the top level bounding box. +
    subcell +
    The area of the subcell bounding boxes. +
    box +
    The area of the top level bounding box. +
    +
    +*/ + +(defun DensityCalculateTotalTransistorCount ( CellView + GateLibCellPairRegExs + ChainLibCellPairRegExs + TransistorLibCellPairRegExs ) + "(cdl gate transistor count, actual gate transistor count) \ + (cdl chain transistor count, actual chain transistor count) \ + (cdl flat transistor count, actual flat transistor count)" + (let ( + ( GateFilter ( NameFilterInstances + ( getq CellView instances ) + GateLibCellPairRegExs ) ) ) + (let ( + ( Gates ( cadr GateFilter ) ) + ( TransistorFilter + ( NameFilterInstances + ( car GateFilter ) + TransistorLibCellPairRegExs ) ) ) + (let ( + ( Chains + ( cadr + ( NameFilterInstances + ( car TransistorFilter ) + ChainLibCellPairRegExs ) ) ) + ( Transistors ( cadr TransistorFilter ) ) ) + (let ( + ( InstanceMap + ( NameMakeInstanceMapFromInstances + Chains + ChainLibCellPairRegExs ) ) ) + ( list + ( list + ( length Gates ) + ( ListFindSum + Gates + (lambda ( Gate ) + ( DensityGetUnfoldedComponentCount + Gate + TransistorLibCellPairRegExs ) ) ) + ( ListFindSum + Gates + (lambda ( Gate ) + ( DensityGetTotalComponentCount + Gate + TransistorLibCellPairRegExs ) ) ) ) + ( list + ( length + ( NameGetCanonicalInstanceNames + InstanceMap ) ) + ( ListFindSum + ( NameGetCanonicalInstanceNames + InstanceMap ) + (lambda ( CanonicalName ) + ( DensityGetUnfoldedComponentCount + ( car ( NameGetInstancesForCanonicalName + InstanceMap + CanonicalName ) ) + TransistorLibCellPairRegExs ) ) ) + ( ListFindSum + Chains + (lambda ( Chain ) + ( DensityGetTotalComponentCount + Chain + TransistorLibCellPairRegExs ) ) ) ) + ( list ( length Transistors ) 0 ( length Transistors ) ) ) ) ) ) ) ) + + + +(defun DensityCalculateTotalTransistorWidth + ( CellView + ComponentLibCellPairRegExs + TransistorLibCellPairRegExs + DefaultTransistorLength + BaseTransistorWidth + UserUnitsPerMeter + PolyLPP + DiffLPP + ) + + (let ( + ( ComponentFilter ( NameFilterInstances + ( getq CellView instances ) + ComponentLibCellPairRegExs ) ) ) + (let ( + ( Components ( cadr ComponentFilter ) ) + ( TransistorFilter ( NameFilterInstances + ( car ComponentFilter ) + TransistorLibCellPairRegExs ) ) ) + (let ( + ( Transistors ( cadr TransistorFilter ) ) ) + (let ( + ( PolyShapes ( setof Shape ( getq CellView shapes ) + ( equal ( getq Shape lpp ) PolyLPP ) ) ) + ( DiffShapes ( setof Shape ( getq CellView shapes ) + ( equal ( getq Shape lpp ) DiffLPP ) ) ) ) + (let ( + ( Easy + ( plus + ( ListFindSum + Components + (lambda ( Component ) + ( DensityGetTotalComponentWidth + Component + DefaultTransistorLength + BaseTransistorWidth + TransistorLibCellPairRegExs + ) ) + ) + ( ListFindSum + Transistors + (lambda ( Transistor ) + ( DensityGetTotalTransistorWidth + Transistor + BaseTransistorWidth + UserUnitsPerMeter ) ) ) ) ) + ( Hard + ( DensityGetTotalDiffPolyArea + DiffShapes + PolyShapes + BaseTransistorWidth ) ) ) + (when ( geqp Hard 0.0 ) + ( plus Easy Hard ) ) ) ) ) ) ) ) + +(defun DensityCalculateTotalTransistorArea + ( CellView + ComponentLibCellPairRegExs + TransistorLibCellPairRegExs + DefaultTransistorLength + BaseTransistorWidth + UserUnitsPerMeter + PolyLPP + DiffLPP + ) + + (let ( + ( ComponentFilter ( NameFilterInstances + ( getq CellView instances ) + ComponentLibCellPairRegExs ) ) ) + (let ( + ( Components ( cadr ComponentFilter ) ) + ( TransistorFilter ( NameFilterInstances + ( car ComponentFilter ) + TransistorLibCellPairRegExs ) ) ) + (let ( + ( Transistors ( cadr TransistorFilter ) ) ) + (let ( + ( PolyShapes ( setof Shape ( getq CellView shapes ) + ( equal ( getq Shape lpp ) PolyLPP ) ) ) + ( DiffShapes ( setof Shape ( getq CellView shapes ) + ( equal ( getq Shape lpp ) DiffLPP ) ) ) ) + (let ( + ( Easy + ( plus + ( ListFindSum + Components + (lambda ( Component ) + ( DensityGetTotalComponentArea + Component + DefaultTransistorLength + BaseTransistorWidth + TransistorLibCellPairRegExs + ) ) + ) + ( ListFindSum + Transistors + (lambda ( Transistor ) + ( DensityGetTotalTransistorArea + Transistor + BaseTransistorWidth + UserUnitsPerMeter ) ) ) ) ) + ( Hard + ( DensityGetTotalDiffPolyArea + DiffShapes + PolyShapes + BaseTransistorWidth ) ) ) + (when ( geqp Hard 0.0 ) + ( plus Easy Hard ) ) ) ) ) ) ) ) + + + +(defun DensityGetUnfoldedComponentCount ( Component + TransistorLibCellPairRegExs ) + (let ( + ( N + ( PropGetPropValueForPropName ( getq ( getq Component master ) prop ) "ncount" ) ) + ( P + ( PropGetPropValueForPropName ( getq ( getq Component master ) prop ) "pcount" ) ) ) + (if ( and N P ) ( plus N P ) -1e9 ) ) ) + + +(defun DensityGetTotalComponentCount ( Component TransistorLibCellPairRegExs ) + ( length + ( cadr + ( NameFilterInstances + ( getq ( getq Component master ) instances ) + TransistorLibCellPairRegExs ) ) ) ) + +(defun DensityGetTotalComponentArea ( Component + DefaultTransistorLength + BaseTransistorWidth + TransistorLibCellPairRegExs ) + ( ListFindSum + ( cadr + ( NameFilterInstances + ( getq ( getq Component master ) instances ) + TransistorLibCellPairRegExs ) ) + (lambda ( Transistor ) + ( DensityGetTotalTransistorArea + Transistor + BaseTransistorWidth + UserUnitsPerMeter ) ) ) ) + +(defun DensityGetTotalComponentWidth ( Component + DefaultTransistorLength + BaseTransistorWidth + TransistorLibCellPairRegExs ) + ( ListFindSum + ( cadr + ( NameFilterInstances + ( getq ( getq Component master ) instances ) + TransistorLibCellPairRegExs ) ) + (lambda ( Transistor ) + ( DensityGetTotalTransistorWidth + Transistor + BaseTransistorWidth + UserUnitsPerMeter ) ) ) ) + + +(defun DensityGetTotalTransistorArea ( Transistor + BaseTransistorWidth + UserUnitsPerMeter ) + ( times + ( DensityGetTotalTransistorWidth + Transistor + BaseTransistorWidth + UserUnitsPerMeter ) + ( DensityGetTotalTransistorLength + Transistor + UserUnitsPerMeter ) ) ) + +(defun DensityGetTotalTransistorLength ( Transistor + UserUnitsPerMeter ) + (let ( + ( Length + ( StringUtilParseLengthString + ( PCellGetParameterValue Transistor "l" ) ) ) ) + (cond ( + ( greaterp Length 1e-3 ) + ( quotient Length UserUnitsPerMeter ) ) + ( + Length ) ) ) ) + +(defun DensityGetTotalTransistorWidth ( Transistor + BaseTransistorWidth + UserUnitsPerMeter ) + (let ( + ( Width + ( StringUtilParseLengthString + ( PCellGetParameterValue Transistor "w" ) ) ) ) + ( plus + (cond ( + ( greaterp Width 1e-3 ) + ( quotient Width UserUnitsPerMeter ) ) + ( + Width ) ) + BaseTransistorWidth ) ) ) + + +(defun DensityGetTotalDiffPolyArea ( DiffShapes PolyShapes BaseTransistorWidth ) + (let ( + ( Ret 0.0 ) + ( TotalArea 0.0 ) ) + ( foreach DiffShape DiffShapes + (let ( + ( PolyShape ( car ( exists PolyShape PolyShapes + ( RectDoRectsOverlap + ( getq DiffShape bBox ) + ( getq PolyShape bBox ) ) ) ) ) ) + (when PolyShape + ( println ( list DiffShape PolyShape ) ) + ( setq TotalArea ( plus TotalArea -1e9 + /*( DensityGetTotalDiffPolyAreaOne + DiffShape + PolyShape + BaseTransistorWidth )*/ + ) ) ) ) ) + TotalArea + ) ) + +(defun DensityGetTotalDiffPolyAreaOne ( DiffShape + PolyShape + BaseTransistorWidth ) + (cond ( + ( RangeIsRangeInRangeProperClose + ( RectGetXRange ( getq DiffShape bBox ) ) + ( RectGetXRange ( getq PolyShape bBox ) ) ) + ( times + ;width + ( plus BaseTransistorWidth + ( RectGetHeight + ( getq DiffShape bBox ) ) ) + ;length + (cond ( + ( equal ( getq PolyShape objType ) "rect" ) + ( RectGetHeight ( getq PolyShape bBox ) ) ) + ( + ( equal ( getq PolyShape objType ) "path" ) + ( getq PolyShape width ) ) + ( + ( equal ( getq PolyShape objType ) "polygon" ) + ( PolygonGetShortestEdge + ( getq PolyShape points ) ) ) ) ) ) + ( + ( RangeIsRangeInRangeProperClose + ( RectGetYRange ( getq DiffShape bBox ) ) + ( RectGetYRange ( getq PolyShape bBox ) ) ) + ( times + ( plus BaseTransistorWidth + ( RectGetHeight + ( getq DiffShape bBox ) ) ) + (cond ( + ( equal ( getq PolyShape objType ) "rect" ) + ( RectGetWidth ( getq PolyShape bBox ) ) ) + ( + ( equal ( getq PolyShape objType ) "path" ) + ( getq PolyShape width ) ) + ( + ( equal ( getq PolyShape objType ) "polygon" ) + ( PolygonGetShortestEdge + ( getq PolyShape points ) ) ) ) ) ) + ( + 0.0 ) ) ) + +(defun DensityFactor ( CellView + ComponentLibCellPairRegExs + TransistorLibCellPairRegExs + UserUnitsPerMeter + DefaultTransistorLength + BaseTransistorWidth + BoundaryLPP + PolyLPP + DiffLPP ) + (let ( + ( TransistorArea + ( DensityCalculateTotalTransistorArea + CellView + ComponentLibCellPairRegExs + TransistorLibCellPairRegExs + DefaultTransistorLength + BaseTransistorWidth + UserUnitsPerMeter + PolyLPP + DiffLPP ) ) ) + (cond ( + ( not ( numberp TransistorArea ) ) + nil ) + ( + ( leqp TransistorArea 0.0 ) + t ) + ( + t + ( quotient + ( RectGetArea + ( PinUtilFindPRBoundBBox + BoundaryLPP + CellView ) ) + ( times + UserUnitsPerMeter + UserUnitsPerMeter + TransistorArea ) ) ) ) ) ) + +(defun DensityCoverGetCoverOld ( CellView + LPP + LeafCellPredicate ) + ( list + ( RectGetAreaOfUnion + ( MidLevelGetRects + CellView + LPP + LeafCellPredicate + ) ) + ( RectGetArea ( getq CellView bBox ) ) + ( RectGetArea ( getq CellView bBox ) ) + ) ) + +(defun DensityCoverGetCover ( CellView + LPP + LeafCellPredicate ) + ( AssuraGetAreas + CellView + LPP + LeafCellPredicate + ) ) + +(defun DensityFactorVerboseUsingPDKInfo ( CellView + BaseTransistorWidth ) + + (let ( + ( Area ( RectGetArea + ( getq CellView bBox ) ) ) ) + (cond ( + ( cadr ( NameFilterInstances + ( getq CellView instances ) + ( append + ( append + GateLibCellPairRegExs + ChainLibCellPairRegExs ) + TransistorLibCellPairs ) ) ) + (let ( + ( Density + ( DensityFactor + CellView + ( append + GateLibCellPairRegExs + ChainLibCellPairRegExs ) + TransistorLibCellPairs + UserUnitsPerMeter + DefaultTransistorLength + BaseTransistorWidth + BoundaryLPP + PolyLPP + DiffLPP ) ) + ( TWidth + ( times + UserUnitsPerMeter + ( DensityCalculateTotalTransistorWidth + CellView + ( append + GateLibCellPairRegExs + ChainLibCellPairRegExs ) + TransistorLibCellPairs + DefaultTransistorLength + BaseTransistorWidth + UserUnitsPerMeter + + PolyLPP + DiffLPP ) ) ) + ( Count + ( DensityCalculateTotalTransistorCount + CellView + GateLibCellPairRegExs + ChainLibCellPairRegExs + TransistorLibCellPairs ) ) + ) + (cond ( + ( numberp Density ) + ( sprintf + nil + "%s density: %L area: %L transistor_width: %L count(count,cdl_transistors,layout_transistors) gate: %d %L %d chain: %d %d %d flat: %d %d %d" + ( getq CellView cellName ) + Density + Area + TWidth + ( round ( car ( car Count ) ) ) + (cond ( ( geqp ( cadr ( car Count ) ) 0 ) + ( cadr ( car Count ) ) 0 ) + ( "?" ) ) + ( round ( caddr ( car Count ) ) ) + ( round ( car ( cadr Count ) ) ) + ( round ( cadr ( cadr Count ) ) ) + ( round ( caddr ( cadr Count ) ) ) + ( round ( car ( caddr Count ) ) ) + ( round ( cadr ( caddr Count ) ) ) + ( round ( caddr ( caddr Count ) ) ) + + ) ) + ( + ( equal Density nil ) + ( sprintf nil "%s has flattened transistors...not supported" + ( getq CellView cellName ) ) + ) + ( + t + ( sprintf nil "%s has no transistors" + ( getq CellView cellName ) ) + ) ) ) ) + ( + t + (let ( + ( Cover + ( DensityCoverGetCover + CellView + BoundaryLPP + (lambda ( CellView ) + ( null + ( car ( NameFilterInstances + ( getq CellView instances ) + LeafCellInstanceLibCellPairRegExs ) ) ) ) + + ) ) ) + ( sprintf nil "%s cover leaf: %L merge: %L bound: %L subcell: %L box: %L" + ( getq CellView cellName ) + ( car Cover ) + ( cadr Cover ) + ( caddr Cover ) + ( cadddr Cover ) + Area + ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/distort/distort.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/distort/distort.il new file mode 100644 index 0000000000..701e5526a1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/distort/distort.il @@ -0,0 +1,1471 @@ +; $Id$ + +(defun DistortLayer (@key (CV nil) (layer "M7") (shift t) (debug nil)) + (let (y tract dy_M7 twoCutContacts shapes contacts points tmp_y m6layer vOrient hOrient M7Contacts) + CV = (if CV CV (geGetEditCellView)) + m6layer="M6" + shapes = (setof shape CV->shapes (car shape->lpp)==layer) + contacts = (setof contact CV->instances + (and contact->libName=="tsmc65" + (setof x contact->master->lpps x->layerName==layer)) + ) + + (when debug printf("Distort Metal\n")) + (foreach shape shapes + (cond ((or shape->objType=="path" shape->objType=="polygon") + shape->points = (DistortPoints shape->points) + ) + (shape->objType=="rect" + ; the top and bottom needs to move the same distance to align with path and avoid edge errors + tmp_y= (topEdge(shape->bBox) + bottomEdge(shape->bBox))/2 + dy= cadr( DistortPoint( 0:tmp_y )) - tmp_y + shape->bBox = list( leftEdge(shape->bBox):bottomEdge(shape->bBox)+dy rightEdge(shape->bBox):topEdge(shape->bBox)+dy) + ) + ) + ) + + ; Find All Via with 0.14 spacing of a vertical M7 path + (when debug printf("Find MinX %d\n" length(shapes))) + minXContacts=nil + foreach( shape shapes + if( shape->objType=="path" then + points=listToVector( shape->points ) + for( i 0 length(points)-2 + if(car(points[i])==car(points[i+1]) then + instancesWithinRange= dbProduceOverlapInst( CV + list(car(points[i])-0.14:min( cadr(points[i]) cadr(points[i+1]))-0.095 + car(points[i])+0.14:max( cadr(points[i]) cadr(points[i+1]))+0.095) + ) + instancesOverlappingPath= dbProduceOverlapInst( CV + list(car(points[i])-0.01:min( cadr(points[i]) cadr(points[i+1]))-0.01 + car(points[i])+0.01:max( cadr(points[i]) cadr(points[i+1]))+0.01) + ) + + instances=setof( inst instancesWithinRange member( inst contacts ) && !member( inst instancesOverlappingPath)) + minXContacts=append(minXContacts instances) + ) + ) + ) + ) + (when debug printf("Find MinX %d\n" length(minXContacts))) + plusYContacts=nil + minusYContacts=nil + contactOverlapShapes=nil + if(shift then + ; does a number of things: + ; 1) makes a list of contacts with m6 pointing up and down (plus and minus respectively) this part + ; is used only for double cut vias later + ; 2) adds to each contact the width of the m6 path, the offset in X if any (to see if the contact + ; is aligned to the m6 path, the length of the path overlap at the end point in case that overlap + ; is being used to fix drc (a frequent occurance). + ; I make no attempt to remove the data from the contact but it is only added to M7_M6 contacts anyway. + ; note that, like minXContacts above, plusYContacts and minusYContacts are global variables + shapes = (setof shape CV->shapes (car shape->lpp)==m6layer && shape~>objType=="path") + vOrient=list("R0" "R180" "MX" "MY") + hOrient=list("R90" "R270" "MXR90" "MYR90") + ; two cut contacts which are actually oriented vertically + twoCutContacts=(setof contact contacts + (contact~>cellName=="M7_M6_2CUT_H" && member(contact~>orient hOrient)) || + (contact~>cellName=="M7_M6_2CUT_V") && member(contact~>orient vOrient)) + + M7Contacts=list("M7_M6_R0" "M7_M6_H" "M7_M6_V" "M7_M6_R90" + "M7_M6_STACK" "M7_M6_STACK_R90" "M7_M6_2CUT_H" "M7_M6_2CUT_V" + "M7_M6min" "M7_M6c" ) + when( debug printf("Find XY %d %d %d\n" length(shapes) length(twoCutContacts) length(contacts))) + foreach( shape shapes + points=listToVector( shape->points ) + for( i 0 length(points)-2 + ; vertical segments only + if(car(points[i])==car(points[i+1]) then + ext1=shape~>width/2 + ext2=shape~>width/2 + if(i==0 && shape~>pathStyle=="varExtendExtend" ext1=shape~>beginExt) + if(i==length(points)-2 && shape~>pathStyle=="varExtendExtend" ext2=shape~>endExt) + if(cadr(points[i]) - cadr(points[i+1]) > 0.18 then + ; one end + instancesOverlappingPoint=dbProduceOverlapInst( CV + list(car(points[i])-0.01:cadr(points[i])-0.01 + car(points[i])+0.01:cadr(points[i])+0.01)) + minusYContacts=append(minusYContacts setof( inst instancesOverlappingPoint member( inst~>cellName M7Contacts ))) + if(shape~>width > 0.0 then + foreach( s setof( i instancesOverlappingPoint member( i~>cellName M7Contacts ) ) s~>pathWidth=shape~>width s~>XOffset=car(s~>xy)-car(points[i]) s~>YOverlap=cadr(points[i])+ext1-cadr(s~>xy)) + ) + ; other end + instancesOverlappingPoint=dbProduceOverlapInst( CV + list(car(points[i+1])-0.01:cadr(points[i+1])-0.01 + car(points[i+1])+0.01:cadr(points[i+1])+0.01)) + plusYContacts=append(plusYContacts setof( inst instancesOverlappingPoint member( inst~>cellName M7Contacts ))) + if(shape~>width > 0.0 then + foreach( s setof( i instancesOverlappingPoint member( i~>cellName M7Contacts ) ) s~>pathWidth=shape~>width s~>XOffset=car(s~>xy)-car(points[i]) s~>YOverlap=cadr(s~>xy)-cadr(points[i+1])-ext2) + ) + ) + if(cadr(points[i]) - cadr(points[i+1]) < -0.18 then + ; one end + instancesOverlappingPoint=dbProduceOverlapInst( CV + list(car(points[i])-0.01:cadr(points[i])-0.01 + car(points[i])+0.01:cadr(points[i])+0.01)) + plusYContacts=append(plusYContacts setof( inst instancesOverlappingPoint member( inst~>cellName M7Contacts ))) + if(shape~>width > 0.0 then + foreach( s setof( i instancesOverlappingPoint member( i~>cellName M7Contacts ) ) s~>pathWidth=shape~>width s~>XOffset=car(s~>xy)-car(points[i]) s~>YOverlap=cadr(s~>xy)-cadr(points[i])-ext1) + ) + ; other end + instancesOverlappingPoint=dbProduceOverlapInst( CV + list(car(points[i+1])-0.01:cadr(points[i+1])-0.01 + car(points[i+1])+0.01:cadr(points[i+1])+0.01)) + minusYContacts=append(minusYContacts setof( inst instancesOverlappingPoint member( inst~>cellName M7Contacts ))) + if(shape~>width > 0.0 then + foreach( s setof( i instancesOverlappingPoint member( i~>cellName M7Contacts ) ) s~>pathWidth=shape~>width s~>XOffset=car(s~>xy)-car(points[i]) s~>YOverlap=cadr(points[i+1])+ext2-cadr(s~>xy)) + ) + ) + ) + ) + ) + (when debug printf("Minus Contacts %d, Plus Contacts %d\n" length(minusYContacts) length(plusYContacts))) + ) + + (when debug printf("DistortContacts\n")) + (foreach contact contacts (DistortContact contact ?shift shift)) + when( debug printf("Done DistortLayer\n")) + t + ) +) + +; distort Y-coordinates of a list a points +(defun DistortPoints (points) + (when points + (cons (DistortPoint (car points)) (DistortPoints (cdr points))) + ) + ) + +; distort Y-coordinate of one point +(defun DistortPoint (point) + (let (x y track dy) + x = round((car point)*1000.0)/1000.0 + y = round((cadr point)*1000.0)/1000.0 + ; the rounding is not always consistently offset from the PG for 1/2 track offsets + track = (mod (round (y-0.12)/0.24+0.000001) 12) + track = (mod (track+12) 12) + dy = (nth track (list 0.02 0.02 0.015 0.01 0.005 0 + 0 -0.005 -0.01 -0.015 -0.02 -0.02)) + x:y+dy + ) + ) + + +(defun GetDefaultExtensions (contact) + prog((value) +; used to be only for R0, removed that restriction +; if( contact~>orient !="R0" then return(nil)) + cond( +; there seems to be no way to get this with skill, so this comes from reading the +; data interactively +; layer1XDefOverride layer1YDefOverride layer2XDefOverride layer2YDefOverride +; layer1XEnclosure layer1YEnclosure layer2XEnclosure layer2YEnclosure +; layer1Direction layer2Direction isOneCut + (contact->cellName=="M7_M6_R0" + value=list(0.07 0.07 0.07 0.07 0.01 0.05 0.05 0.01 "lrtb" "lrtb" t)) + (contact->cellName=="M7_M6_H" + value=list(0.07 0.07 0.07 0.07 0.05 0.01 0.05 0.01 "lrtb" "lrtb" t)) + (contact->cellName=="M7_M6_V" + value=list(0.07 0.07 0.07 0.07 0.01 0.05 0.01 0.05 "lrtb" "lrtb" t)) + (contact~>cellName=="M7_M6_R90" + value=list(0.07 0.07 0.07 0.07 0.05 0.01 0.01 0.05 "lrtb" "lrtb" t)) + (contact->cellName=="M7_M6_STACK" + value=list(0.07 0.07 0.07 0.07 0.01 0.17 0.05 0.01 "lrtb" "lrtb" t)) + (contact->cellName=="M7_M6_STACK_R90" + value=list(0.07 0.07 0.07 0.07 0.17 0.01 0.01 0.05 "lrtb" "lrtb" t)) + (contact->cellName=="M7_M6_2CUT_H" + value=list(0.07 0.07 0.07 0.07 0.04 0.01 0.04 0.01 "lrtb" "lrtb" nil)) + (contact->cellName=="M7_M6_2CUT_V" + value=list(0.07 0.07 0.07 0.07 0.01 0.04 0.01 0.04 "lrtb" "lrtb" nil)) + (contact->cellName=="M7_M6min" + value=list(0.005 0.005 0.005 0.005 0.005 0.005 0.005 0.005 "lrtb" "lrtb" t)) + (contact->cellName=="M7_M6c" + value=list(0.01 0.04 0.04 0.01 0.01 0.04 0.04 0.01 "lrtb" "lrtb" t)) + (t + return(nil)) + ) + return(listToVector(value)) + ) +) + +; distort extensions of single cuts +; not yet used, it is intended to handle rotations better +(defun DistortExtensionsSingle ( + layer1YTopEnclosure layer1YBottomEnclosure layer1XLeftEnclosure layer1XRightEnclosure + layer2YTopEnclosure layer2YBottomEnclosure layer2XLeftEnclosure layer2XRightEnclosure used_dy) + (let () + if(layer1XLeftEnclosure < 0.01 layer1XLeftEnclosure=0.01) + if(layer1XRightEnclosure < 0.01 layer1XRightEnclosure=0.01) + ; move top of M6 + layer1YTopEnclosure=layer1YTopEnclosure-used_dy + if(layer1YTopEnclosure < 0.0 layer1YTopEnclosure=0.0) + if(layer1YTopEnclosure < 0.04 && ( layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YTopEnclosure=0.04) + ; move bottom of M6 + layer1YBottomEnclosure=layer1YBottomEnclosure+used_dy + if(layer1YBottomEnclosure < 0.0 layer1YBottomEnclosure=0.0) + if(layer1YBottomEnclosure < 0.04 && ( layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YBottomEnclosure=0.04) + ) + list(layer1YTopEnclosure layer1YBottomEnclosure layer1XLeftEnclosure layer1XRightEnclosure + layer2YTopEnclosure layer2YBottomEnclosure layer2XLeftEnclosure layer2XRightEnclosure used_dy) +) + +; distort and move contact +(defun DistortContact (contact @key (shift t) ) + (prog (x y track dy used_dy dy_contact dy_M7 + layer1XDefOverride layer1YDefOverride layer2XDefOverride layer2YDefOverride + layer1XEnclosure layer1YEnclosure layer2XEnclosure layer2YEnclosure + layer1Direction layer2Direction isOneCut + layer1YTopEnclosure layer1YBottomEnclosure layer1XLeftEnclosure layer1XRightEnclosure + layer2YTopEnclosure layer2YBottomEnclosure layer2XLeftEnclosure layer2XRightEnclosure + defaultExtension extensionList + shiftDistance actualDistance + ) + layer1XDefOverride=nil + layer1YDefOverride=nil + layer2XDefOverride=nil + layer2YDefOverride=nil + layer1XEnclosure=nil + layer1YEnclosure=nil + layer2XEnclosure=nil + layer2YEnclosure=nil + layer1Direction=nil + layer2Direction=nil + isOneCut=nil + x = round((car contact~>xy)*1000.0)/1000.0 + y = round((cadr contact~>xy)*1000.0)/1000.0 + track = (mod (round (y-0.12)/0.24) 12) + track = (mod (track+12) 12) + ; be absolutely sure this matches where it is defined elsewhere too! + dy_contact = (nth track (list 0.01 0.01 0.005 0 0 0 0 0 0 -0.005 -0.01 -0.01)) + dy_M7 = (nth track (list 0.02 0.02 0.015 0.01 0.005 0 0 -0.005 -0.01 -0.015 -0.02 -0.02)) + + if(contact~>OriginalY==nil then + contact~>OriginalY=cadr(contact~>xy)+dy_M7 + ) + + if( dy_M7 == 0.0 then return(nil) ) + used_dy=dy_contact + + defaultExtension=GetDefaultExtensions(contact) + + if( contact->cellName=="M7_M6min" + used_dy=dy_M7 + used_dy=dy_contact + ) + + ; gather the actual contact extensions + if(defaultExtension != nil then + layer1XDefOverride = dbGetPropByName(contact "layer1XDefOverride")~>value || defaultExtension[0] + layer1YDefOverride = dbGetPropByName(contact "layer1YDefOverride")~>value || defaultExtension[1] + layer2XDefOverride = dbGetPropByName(contact "layer2XDefOverride")~>value || defaultExtension[2] + layer2YDefOverride = dbGetPropByName(contact "layer2YDefOverride")~>value || defaultExtension[3] + layer1XEnclosure = dbGetPropByName(contact "layer1XEnclosure")~>value || defaultExtension[4] + layer1YEnclosure = dbGetPropByName(contact "layer1YEnclosure")~>value || defaultExtension[5] + layer2XEnclosure = dbGetPropByName(contact "layer2XEnclosure")~>value || defaultExtension[6] + layer2YEnclosure = dbGetPropByName(contact "layer2YEnclosure")~>value || defaultExtension[7] + layer1Direction = dbGetPropByName(contact "layer1Direction")~>value || defaultExtension[8] + ; need to recognize old strings + if( layer1Direction == "yx" layer1Direction = "lrtb") + if( layer1Direction == "y" layer1Direction = "tb") + if( layer1Direction == "x" layer1Direction = "lr") + layer2Direction = dbGetPropByName(contact "layer2Direction")~>value || defaultExtension[9] + ; need to recognize old strings + if( layer2Direction == "yx" layer2Direction = defaultExtension[9]) + if( layer2Direction == "y" layer2Direction = "tb") + if( layer2Direction == "x" layer2Direction = "lr") + ; these are the variables actually used! + isOneCut=defaultExtension[10] + layer1YTopEnclosure = if( rexMatchp("t" layer1Direction) layer1YEnclosure layer1YDefOverride ) + layer1YBottomEnclosure = if( rexMatchp("b" layer1Direction) layer1YEnclosure layer1YDefOverride ) + layer1XLeftEnclosure = if( rexMatchp("l" layer1Direction) layer1XEnclosure layer1XDefOverride ) + layer1XRightEnclosure = if( rexMatchp("r" layer1Direction) layer1XEnclosure layer1XDefOverride ) + layer2YTopEnclosure = if( rexMatchp("t" layer2Direction) layer2YEnclosure layer2YDefOverride ) + layer2YBottomEnclosure = if( rexMatchp("b" layer2Direction) layer2YEnclosure layer2YDefOverride ) + layer2XLeftEnclosure = if( rexMatchp("l" layer2Direction) layer2XEnclosure layer2XDefOverride ) + layer2XRightEnclosure = if( rexMatchp("r" layer2Direction) layer2XEnclosure layer2XDefOverride ) + ) + + if( defaultExtension==nil then + let( (left right bottom top top6 top7 bottom6 bottom6 shapeM6 shapeM7) + ; non-parameterized vias, currently. only R0 supported + ; for these we cannot manipulate the internal extensions, so metal has + ; to be added instead + if( contact~>orient == "R0" && ( used_dy != 0 || dy_M7 != 0 ) then + ; if it moves: + ; the via is moved and so is the overlap. To guarantee + ; that the old edge remains coincident with the old metal, + ; have to create new little rectangles. + ; assumes only one M7 and one M6 shape + shapeM6=car(setof( shape contact~>master~>shapes shape~>lpp == Metal6LPP)) + if(shapeM6 then + left=car(contact~>xy)+car(car(shapeM6~>bBox)) + right=car(contact~>xy)+car(cadr(shapeM6~>bBox)) + bottom=cadr(contact~>xy)+cadr(car(shapeM6~>bBox)) + top=cadr(contact~>xy)+cadr(cadr(shapeM6~>bBox)) + if( used_dy > 0 then + ; via moved up, fill bottom side for M6 + bottom6=bottom; + top6=bottom+used_dy + else + ; via moved down, fill top side for M6 + bottom6=top + top6=top+used_dy + ) + if( bottom6 != top6 + dbCreateRect(contact~>cellView Metal6LPP list(list(left bottom6) list(right top6))) + ) + ) + shapeM7=car(setof( shape contact~>master~>shapes shape~>lpp == Metal7LPP)) + if(shapeM7 then + left=car(contact~>xy)+car(car(shapeM7~>bBox)) + right=car(contact~>xy)+car(cadr(shapeM7~>bBox)) + bottom=cadr(contact~>xy)+cadr(car(shapeM7~>bBox)) + top=cadr(contact~>xy)+cadr(cadr(shapeM7~>bBox)) + if( dy_M7 > 0 then + ; fill top side for M7 + bottom7=top+used_dy + top7=top+dy_M7 + else + ; fill bottom side for M7 + top7=bottom+used_dy + bottom7=bottom+dy_M7 + ) + ; rectangle fill + if( bottom7 != top7 + dbCreateRect(contact~>cellView Metal7LPP list(list(left bottom7) list(right top7))) + ) + ) + ; move the contact + contact->xy = x:y+used_dy + ) + ; change this if/when non R0 supported + if(contact~>orient != "R0" printf("Non parameterized contact %s, orientation %s, not yet supported, ignored\n" + contact~>cellName contact~>orient)) + ) + return(nil) + ) + if( isOneCut then + ; single cut, assume vertical M6 horiz M7, move full M7 change, expand M6, do not touch M7 + ; I know this is controversial, but it works more often then the original idea of using the smaller shift, + ; at least in my experience doing hundreds of cells + used_dy=dy_M7 + (cond + ( contact~>orient == "R0" + ; R0, this is model for all rotations + ; T + ; L R + ; B + ;px=nil + ;if(x==-2.16 && y==-55.2 then printf("%s dy=%f x=%f y=%f o=%L l=%f r=%f t=%f b=%f\n" contact~>cellName + ; used_dy car(contact~>xy) cadr(contact~>xy) contact~>orient + ; layer1XLeftEnclosure, layer1XRightEnclosure + ; layer1YTopEnclosure layer1YBottomEnclosure) px=t) + minext1=nil + minext2=nil + touchext1=nil + if(layer1XLeftEnclosure==0.005 && layer1YTopEnclosure==0.005 && + layer1XRightEnclosure==0.005 && layer1YBottomEnclosure==0.005 then +; if(dy_M7 > 0.006 used_dy=0.005 used_dy=0) +; if(dy_M7 < -0.006 used_dy=-0.005 used_dy=0) + if(contact~>pathWidth != nil then + ; if pathWidth defined, the there is a m6 path under the contact + ;if(px printf("%.3f %.3f %.3f %.0f\n" contact~>pathWidth contact~>XOffset contact~>YOverlap contact~>Type)) + if(contact~>XOffset == 0.0 then + ; if the offset is 0, then the contact is horizontally aligned to the path + ; then we make the Left/Right overlap match the path width, minimizes DRCs at the ends + layer1XLeftEnclosure=(contact~>pathWidth-0.1)/2 + layer1XRightEnclosure=(contact~>pathWidth-0.1)/2 + ; if the overlap seems to fix DRC, the adjust contact to match original overlap + ; top side + if(contact~>YOverlap-0.05 >= 0.04 + layer1YTopEnclosure=contact~>YOverlap-0.05 + layer1YTopEnclosure=0.04 + ) + ; bottom side + if(contact~>YOverlap+0.05 <= -0.04 + layer1YBottomEnclosure=-contact~>YOverlap-0.05 + layer1YBottomEnclosure=0.04 + ) + touchext1=t + ;if(px printf("layer1YTopEnclosure=%.3f layer1YBottomEnclosure=%.3f\n" layer1YTopEnclosure layer1YBottomEnclosure)) + ) + else + ; found that single contacts frequently need to meet minimum area if they do not + ; overlap a path, this guarantees min area + layer1XLeftEnclosure=0.01 + layer1XRightEnclosure=0.01 + layer1YTopEnclosure=0.07 + layer1YBottomEnclosure=0.07 + ) + minext1=t + ) + if(! minext1 then + ; never let the overlap left/right be less than 0.01 if it is not a min overlap contact + if(layer1XLeftEnclosure < 0.01 layer1XLeftEnclosure=0.01) + if(layer1XRightEnclosure < 0.01 layer1XRightEnclosure=0.01) + ) + ; move top of M6, if not already set above + if( ! touchext1 layer1YTopEnclosure=layer1YTopEnclosure-used_dy) + ; avoid negatives + if(layer1YTopEnclosure < 0.0 then layer1YTopEnclosure=0.0) + if(! minext1 && layer1YTopEnclosure < 0.04 && ( layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YTopEnclosure=0.04) + ; move bottom of M6, if not already set above + if(! touchext1 layer1YBottomEnclosure=layer1YBottomEnclosure+used_dy) + ; avoid negatives + if(layer1YBottomEnclosure < 0.0 layer1YBottomEnclosure=0.0) + if(! minext1 && layer1YBottomEnclosure < 0.04 && ( layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YBottomEnclosure=0.04) + ; move the thing + contact~>xy = x:y+used_dy + ; set extensions + dbReplaceProp( contact "layer1YDefOverride" "float" layer1YTopEnclosure) ; top + dbReplaceProp( contact "layer1YEnclosure" "float" layer1YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer1XDefOverride" "float" layer1XLeftEnclosure) ; left + dbReplaceProp( contact "layer1XEnclosure" "float" layer1XRightEnclosure) ; right + dbReplaceProp( contact "layer1Direction" "string" "br") + ; obviously this never happens here, but it here for a place holder + if(used_dy != dy_M7 then + dbReplaceProp( contact "layer2YDefOverride" "float" layer2YTopEnclosure) ; top + dbReplaceProp( contact "layer2YEnclosure" "float" layer2YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer2XDefOverride" "float" layer2XLeftEnclosure) ; left + dbReplaceProp( contact "layer2XEnclosure" "float" layer2XRightEnclosure) ; right + dbReplaceProp( contact "layer2Direction" "string" "br") + ) + + return( t ) + ) + ( contact~>orient == "R270" + ; R270: rotates CW 90deg (single cuts) + ; L + ; B T + ; R + ; + minext1=nil + minext2=nil + touchext1=nil + if(layer1YBottomEnclosure==0.005 && layer1XLeftEnclosure==0.005 && + layer1YTopEnclosure==0.005 && layer1XRightEnclosure==0.005 then +; if(dy_M7 > 0.006 used_dy=0.005 used_dy=0) +; if(dy_M7 < -0.006 used_dy=-0.005 used_dy=0) + if(contact~>pathWidth != nil then + if(contact~>XOffset == 0.0 then + layer1YBottomEnclosure=(contact~>pathWidth-0.1)/2 + layer1YTopEnclosure=(contact~>pathWidth-0.1)/2 + if(contact~>YOverlap-0.05 >= 0.04 + layer1XLeftEnclosure=contact~>YOverlap-0.05 + layer1XLeftEnclosure=0.04 + ) + if(contact~>YOverlap+0.05 <= -0.04 + layer1XRightEnclosure=-contact~>YOverlap-0.05 + layer1XRightEnclosure=0.04 + ) + touchext1=t + ) + else + layer1YBottomEnclosure=0.01 + layer1YTopEnclosure=0.01 + layer1XLeftEnclosure=0.07 + layer1XRightEnclosure=0.07 + ) + minext1=t + ) +; if(layer2YBottomEnclosure==0.005 && layer2XLeftEnclosure==0.005 && +; layer2YTopEnclosure==0.005 && layer2XRightEnclosure==0.005 then +; layer2YBottomEnclosure=0.07 +; layer2YTopEnclosure=0.07 +; layer2XLeftEnclosure=0.01 +; layer2XRightEnclosure=0.01 +; minext2=t +; ) + if(! minext1 then + if(layer1YBottomEnclosure < 0.01 layer1YBottomEnclosure=0.01) + if(layer1YTopEnclosure < 0.01 layer1YTopEnclosure=0.01) + ) + ; move top of M6 + if( ! touchext1 layer1XLeftEnclosure=layer1XLeftEnclosure-used_dy) + if(layer1XLeftEnclosure < 0.0 then layer1XLeftEnclosure=0.0) +; if((member( contact plusYContacts) || member( contact minusYContacts)) && ! minext1 && layer1XLeftEnclosure < 0.04 && ( layer1YBottomEnclosure < 0.03 || layer1YTopEnclosure < 0.03) layer1XLeftEnclosure=0.04) + if(! minext1 && layer1XLeftEnclosure < 0.04 && ( layer1YBottomEnclosure < 0.03 || layer1YTopEnclosure < 0.03) layer1XLeftEnclosure=0.04) + ; move bottom of M6 + if(! touchext1 layer1XRightEnclosure=layer1XRightEnclosure+used_dy) + if(layer1XRightEnclosure < 0.0 layer1XRightEnclosure=0.0) +; if((member( contact plusYContacts) || member( contact minusYContacts)) && ! minext1 && layer1XRightEnclosure < 0.04 && ( layer1YBottomEnclosure < 0.03 || layer1YTopEnclosure < 0.03) layer1XRightEnclosure=0.04) + if(! minext1 && layer1XRightEnclosure < 0.04 && ( layer1YBottomEnclosure < 0.03 || layer1YTopEnclosure < 0.03) layer1XRightEnclosure=0.04) + ; update the contact: note, only origin and M6 + contact~>xy = x:y+used_dy + dbReplaceProp( contact "layer1YDefOverride" "float" layer1YTopEnclosure) ; top + dbReplaceProp( contact "layer1YEnclosure" "float" layer1YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer1XDefOverride" "float" layer1XLeftEnclosure) ; left + dbReplaceProp( contact "layer1XEnclosure" "float" layer1XRightEnclosure) ; right + dbReplaceProp( contact "layer1Direction" "string" "br") +; if(x==912.42 && y==-124.44 printf("%s dy=%f x=%f y=%f o=%L l=%f r=%f t=%f b=%f\n" contact~>cellName +; used_dy car(contact~>xy) cadr(contact~>xy) contact~>orient +; layer1XLeftEnclosure, layer1XRightEnclosure +; layer1YTopEnclosure layer1YBottomEnclosure)) + + return( t ) + ) + ( contact~>orient == "R90" + ; R90: rotates CCW 90deg (single cuts) + ; R + ; T B + ; L + minext1=nil + minext2=nil + touchext1=nil + if(layer1YTopEnclosure==0.005 && layer1XRightEnclosure==0.005 && + layer1YBottomEnclosure==0.005 && layer1XLeftEnclosure==0.005 then +; if(dy_M7 > 0.006 used_dy=0.005 used_dy=0) +; if(dy_M7 < -0.006 used_dy=-0.005 used_dy=0) + if(contact~>pathWidth != nil then + ; if pathWidth defined, the there is a m6 path under the contact + ;if(px printf("%.3f %.3f %.3f %.0f\n" contact~>pathWidth contact~>XOffset contact~>YOverlap contact~>Type)) + if(contact~>XOffset == 0.0 then + ; if the offset is 0, then the contact is horizontally aligned to the path + ; then we make the Left/Right overlap match the path width, minimizes DRCs at the ends + layer1YTopEnclosure=(contact~>pathWidth-0.1)/2 + layer1YBottomEnclosure=(contact~>pathWidth-0.1)/2 + ; if the overlap seems to fix DRC, the adjust contact to match original overlap + ; top side + if(contact~>YOverlap-0.05 >= 0.04 + layer1XRightEnclosure=contact~>YOverlap-0.05 + layer1XRightEnclosure=0.04 + ) + ; bottom side + if(contact~>YOverlap+0.05 <= -0.04 + layer1XLeftEnclosure=-contact~>YOverlap-0.05 + layer1XLeftEnclosure=0.04 + ) + touchext1=t + ;if(px printf("layer1XRightEnclosure=%.3f layer1XLeftEnclosure=%.3f\n" layer1XRightEnclosure layer1XLeftEnclosure)) + ) + else + ; found that single contacts frequently need to meet minimum area if they do not + ; overlap a path, this guarantees min area + layer1YTopEnclosure=0.01 + layer1YBottomEnclosure=0.01 + layer1XRightEnclosure=0.07 + layer1XLeftEnclosure=0.07 + ) + minext1=t + ) + if(! minext1 then + ; never let the overlap left/right be less than 0.01 if it is not a min overlap contact + if(layer1YTopEnclosure < 0.01 layer1YTopEnclosure=0.01) + if(layer1YBottomEnclosure < 0.01 layer1YBottomEnclosure=0.01) + ) + ; move top of M6, if not already set above + if( ! touchext1 layer1XRightEnclosure=layer1XRightEnclosure-used_dy) + ; avoid negatives + if(layer1XRightEnclosure < 0.0 then layer1XRightEnclosure=0.0) + if(! minext1 && layer1XRightEnclosure < 0.04 && ( layer1YTopEnclosure < 0.03 || layer1YBottomEnclosure < 0.03) layer1XRightEnclosure=0.04) + ; move bottom of M6, if not already set above + if(! touchext1 layer1XLeftEnclosure=layer1XLeftEnclosure+used_dy) + ; avoid negatives + if(layer1XLeftEnclosure < 0.0 layer1XLeftEnclosure=0.0) + if(! minext1 && layer1XLeftEnclosure < 0.04 && ( layer1YTopEnclosure < 0.03 || layer1YBottomEnclosure < 0.03) layer1XLeftEnclosure=0.04) + ; update the contact: note, only origin and M6 + contact~>xy = x:y+used_dy + dbReplaceProp( contact "layer1YDefOverride" "float" layer1YTopEnclosure) ; top + dbReplaceProp( contact "layer1YEnclosure" "float" layer1YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer1XDefOverride" "float" layer1XLeftEnclosure) ; left + dbReplaceProp( contact "layer1XEnclosure" "float" layer1XRightEnclosure) ; right + dbReplaceProp( contact "layer1Direction" "string" "br") + + return( t ) + ) + ( contact~>orient == "MX" + ; MX + ; B + ; L R + ; T + minext1=nil + minext2=nil + touchext1=nil + if(layer1XLeftEnclosure==0.005 && layer1YBottomEnclosure==0.005 && + layer1XRightEnclosure==0.005 && layer1YTopEnclosure==0.005 then +; if(dy_M7 > 0.006 used_dy=0.005 used_dy=0) +; if(dy_M7 < -0.006 used_dy=-0.005 used_dy=0) + if(contact~>pathWidth != nil then + ; if pathWidth defined, the there is a m6 path under the contact + ;if(px printf("%.3f %.3f %.3f %.0f\n" contact~>pathWidth contact~>XOffset contact~>YOverlap contact~>Type)) + if(contact~>XOffset == 0.0 then + ; if the offset is 0, then the contact is horizontally aligned to the path + ; then we make the Left/Right overlap match the path width, minimizes DRCs at the ends + layer1XLeftEnclosure=(contact~>pathWidth-0.1)/2 + layer1XRightEnclosure=(contact~>pathWidth-0.1)/2 + ; if the overlap seems to fix DRC, the adjust contact to match original overlap + ; top side + if(contact~>YOverlap-0.05 >= 0.04 + layer1YBottomEnclosure=contact~>YOverlap-0.05 + layer1YBottomEnclosure=0.04 + ) + ; bottom side + if(contact~>YOverlap+0.05 <= -0.04 + layer1YTopEnclosure=-contact~>YOverlap-0.05 + layer1YTopEnclosure=0.04 + ) + touchext1=t + ;if(px printf("layer1YBottomEnclosure=%.3f layer1YTopEnclosure=%.3f\n" layer1YBottomEnclosure layer1YTopEnclosure)) + ) + else + ; found that single contacts frequently need to meet minimum area if they do not + ; overlap a path, this guarantees min area + layer1XLeftEnclosure=0.01 + layer1XRightEnclosure=0.01 + layer1YBottomEnclosure=0.07 + layer1YTopEnclosure=0.07 + ) + minext1=t + ) + if(! minext1 then + ; never let the overlap left/right be less than 0.01 if it is not a min overlap contact + if(layer1XLeftEnclosure < 0.01 layer1XLeftEnclosure=0.01) + if(layer1XRightEnclosure < 0.01 layer1XRightEnclosure=0.01) + ) + ; move top of M6, if not already set above + if( ! touchext1 layer1YBottomEnclosure=layer1YBottomEnclosure-used_dy) + ; avoid negatives + if(layer1YBottomEnclosure < 0.0 then layer1YBottomEnclosure=0.0) + if(! minext1 && layer1YBottomEnclosure < 0.04 && ( layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YBottomEnclosure=0.04) + ; move bottom of M6, if not already set above + if(! touchext1 layer1YTopEnclosure=layer1YTopEnclosure+used_dy) + ; avoid negatives + if(layer1YTopEnclosure < 0.0 layer1YTopEnclosure=0.0) + if(! minext1 && layer1YTopEnclosure < 0.04 && ( layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YTopEnclosure=0.04) + ; + contact~>xy = x:y+used_dy + dbReplaceProp( contact "layer1YDefOverride" "float" layer1YTopEnclosure) ; top + dbReplaceProp( contact "layer1YEnclosure" "float" layer1YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer1XDefOverride" "float" layer1XLeftEnclosure) ; left + dbReplaceProp( contact "layer1XEnclosure" "float" layer1XRightEnclosure) ; right + dbReplaceProp( contact "layer1Direction" "string" "br") + + return( t ) + ) + ( contact~>orient == "MY" + ; MY + ; T + ; R L + ; B + minext1=nil + minext2=nil + touchext1=nil + if(layer1XRightEnclosure==0.005 && layer1YTopEnclosure==0.005 && + layer1XLeftEnclosure==0.005 && layer1YBottomEnclosure==0.005 then +; if(dy_M7 > 0.006 used_dy=0.005 used_dy=0) +; if(dy_M7 < -0.006 used_dy=-0.005 used_dy=0) + if(contact~>pathWidth != nil then + ; if pathWidth defined, the there is a m6 path under the contact + ;if(px printf("%.3f %.3f %.3f %.0f\n" contact~>pathWidth contact~>XOffset contact~>YOverlap contact~>Type)) + if(contact~>XOffset == 0.0 then + ; if the offset is 0, then the contact is horizontally aligned to the path + ; then we make the Left/Right overlap match the path width, minimizes DRCs at the ends + layer1XRightEnclosure=(contact~>pathWidth-0.1)/2 + layer1XLeftEnclosure=(contact~>pathWidth-0.1)/2 + ; if the overlap seems to fix DRC, the adjust contact to match original overlap + ; top side + if(contact~>YOverlap-0.05 >= 0.04 + layer1YTopEnclosure=contact~>YOverlap-0.05 + layer1YTopEnclosure=0.04 + ) + ; bottom side + if(contact~>YOverlap+0.05 <= -0.04 + layer1YBottomEnclosure=-contact~>YOverlap-0.05 + layer1YBottomEnclosure=0.04 + ) + touchext1=t + ;if(px printf("layer1YTopEnclosure=%.3f layer1YBottomEnclosure=%.3f\n" layer1YTopEnclosure layer1YBottomEnclosure)) + ) + else + ; found that single contacts frequently need to meet minimum area if they do not + ; overlap a path, this guarantees min area + layer1XRightEnclosure=0.01 + layer1XLeftEnclosure=0.01 + layer1YTopEnclosure=0.07 + layer1YBottomEnclosure=0.07 + ) + minext1=t + ) + if(! minext1 then + ; never let the overlap left/right be less than 0.01 if it is not a min overlap contact + if(layer1XRightEnclosure < 0.01 layer1XRightEnclosure=0.01) + if(layer1XLeftEnclosure < 0.01 layer1XLeftEnclosure=0.01) + ) + ; move top of M6, if not already set above + if( ! touchext1 layer1YTopEnclosure=layer1YTopEnclosure-used_dy) + ; avoid negatives + if(layer1YTopEnclosure < 0.0 then layer1YTopEnclosure=0.0) + if(! minext1 && layer1YTopEnclosure < 0.04 && ( layer1XRightEnclosure < 0.03 || layer1XLeftEnclosure < 0.03) layer1YTopEnclosure=0.04) + ; move bottom of M6, if not already set above + if(! touchext1 layer1YBottomEnclosure=layer1YBottomEnclosure+used_dy) + ; avoid negatives + if(layer1YBottomEnclosure < 0.0 layer1YBottomEnclosure=0.0) + if(! minext1 && layer1YBottomEnclosure < 0.04 && ( layer1XRightEnclosure < 0.03 || layer1XLeftEnclosure < 0.03) layer1YBottomEnclosure=0.04) + + ; update the contact: note, only origin and M6 + contact~>xy = x:y+used_dy + dbReplaceProp( contact "layer1YDefOverride" "float" layer1YTopEnclosure) ; top + dbReplaceProp( contact "layer1YEnclosure" "float" layer1YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer1XDefOverride" "float" layer1XLeftEnclosure) ; left + dbReplaceProp( contact "layer1XEnclosure" "float" layer1XRightEnclosure) ; right + dbReplaceProp( contact "layer1Direction" "string" "br") + + return( t ) + ) + ( contact~>orient == "R180" + ; R180, this is model for all rotations + ; B + ; R L + ; T + minext1=nil + minext2=nil + touchext1=nil + if(layer1XRightEnclosure==0.005 && layer1YBottomEnclosure==0.005 && + layer1XLeftEnclosure==0.005 && layer1YTopEnclosure==0.005 then +; if(dy_M7 > 0.006 used_dy=0.005 used_dy=0) +; if(dy_M7 < -0.006 used_dy=-0.005 used_dy=0) + if(contact~>pathWidth != nil then + ; if pathWidth defined, the there is a m6 path under the contact + if(contact~>XOffset == 0.0 then + ; if the offset is 0, then the contact is horizontally aligned to the path + ; then we make the Right/Left overlap match the path width, minimizes DRCs at the ends + layer1XRightEnclosure=(contact~>pathWidth-0.1)/2 + layer1XLeftEnclosure=(contact~>pathWidth-0.1)/2 + ; if the overlap seems to fix DRC, the adjust contact to match original overlap + ; top side + if(contact~>YOverlap-0.05 >= 0.04 + layer1YBottomEnclosure=contact~>YOverlap-0.05 + layer1YBottomEnclosure=0.04 + ) + ; Bottom side + if(contact~>YOverlap+0.05 <= -0.04 + layer1YTopEnclosure=-contact~>YOverlap-0.05 + layer1YTopEnclosure=0.04 + ) + touchext1=t + ) + else + ; found that single contacts frequently need to meet minimum area if they do not + ; overlap a path, this guarantees min area + layer1XRightEnclosure=0.01 + layer1XLeftEnclosure=0.01 + layer1YBottomEnclosure=0.07 + layer1YTopEnclosure=0.07 + ) + minext1=t + ) + if(! minext1 then + ; never let the overlap left/Right be less than 0.01 if it is not a min overlap contact + if(layer1XRightEnclosure < 0.01 layer1XRightEnclosure=0.01) + if(layer1XLeftEnclosure < 0.01 layer1XLeftEnclosure=0.01) + ) + ; move top of M6, if not already set above + if( ! touchext1 layer1YBottomEnclosure=layer1YBottomEnclosure-used_dy) + ; avoid negatives + if(layer1YBottomEnclosure < 0.0 then layer1YBottomEnclosure=0.0) + if(! minext1 && layer1YBottomEnclosure < 0.04 && ( layer1XRightEnclosure < 0.03 || layer1XLeftEnclosure < 0.03) layer1YBottomEnclosure=0.04) + ; move Bottom of M6, if not already set above + if(! touchext1 layer1YTopEnclosure=layer1YTopEnclosure+used_dy) + ; avoid negatives + if(layer1YTopEnclosure < 0.0 layer1YTopEnclosure=0.0) + if(! minext1 && layer1YTopEnclosure < 0.04 && ( layer1XRightEnclosure < 0.03 || layer1XLeftEnclosure < 0.03) layer1YTopEnclosure=0.04) + ; move the thing + contact~>xy = x:y+used_dy + ; set extensions + dbReplaceProp( contact "layer1YDefOverride" "float" layer1YTopEnclosure) ; top + dbReplaceProp( contact "layer1YEnclosure" "float" layer1YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer1XDefOverride" "float" layer1XLeftEnclosure) ; left + dbReplaceProp( contact "layer1XEnclosure" "float" layer1XRightEnclosure) ; right + dbReplaceProp( contact "layer1Direction" "string" "br") + ; obviously this never happens here, but it here for a place holder + if(used_dy != dy_M7 then + dbReplaceProp( contact "layer2YDefOverride" "float" layer2YTopEnclosure) ; top + dbReplaceProp( contact "layer2YEnclosure" "float" layer2YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer2XDefOverride" "float" layer2XLeftEnclosure) ; left + dbReplaceProp( contact "layer2XEnclosure" "float" layer2XRightEnclosure) ; right + dbReplaceProp( contact "layer2Direction" "string" "br") + ) + + return( t ) + ) + (t printf("Warning: Unsupported orientation %s in contact %s at %.3f:%.3f\n" contact~>orient contact~>cellName x y)) + ) + ) + + ; M7_M6_2CUT_V is the only via that is capable to create spacing drc spacing error. + ; I would suggest do assura run and replace bad ones with single cut. + if( contact~>cellName=="M7_M6_2CUT_V" then + if( layer1YTopEnclosure<0.04 then layer1YTopEnclosure=0.04) + if( layer1YBottomEnclosure<0.04 then layer1YBottomEnclosure=0.04) + if( layer2YTopEnclosure<0.04 then layer2YTopEnclosure=0.04) + if( layer2YBottomEnclosure<0.04 then layer2YBottomEnclosure=0.04) + ) + if( contact~>cellName=="M7_M6_2CUT_H" then + if( layer1XLeftEnclosure<0.04 then layer1XLeftEnclosure=0.04) + if( layer1XRightEnclosure<0.04 then layer1XRightEnclosure=0.04) + if( layer2XLeftEnclosure<0.04 then layer2XLeftEnclosure=0.04) + if( layer2XRightEnclosure<0.04 then layer2XRightEnclosure=0.04) + ) + + if( member( contact minXContacts ) then + (cond + (contact~>orient == "R0" || contact~>orient == "R180" + if(layer2XLeftEnclosure>0.04 layer2XLeftEnclosure=0.04) + if(layer2XRightEnclosure>0.04 layer2XRightEnclosure=0.04)) + (contact~>orient == "R90" || contact~>orient == "R270" + if(layer2YTopEnclosure>0.04 layer2YTopEnclosure=0.04) + if(layer2YBottomEnclosure>0.04 layer2YBottomEnclosure=0.04)) + ) + ) + +; has not been tried all that much, and was not 100% successful: +; do not allow a 'shift' if the contact is within 0.525 microns of a power grid +; shiftDistance=525 +; actualDistance=(mod (mod (round ( y+used_dy )*1000) 2880)+2880 2880) +; if(actualDistance <= shiftDistance && actualDistance > shiftDistance-220 used_dy=used_dy-0.01) +; if(2880-actualDistance <= shiftDistance && 2880-actualDistance > shiftDistance-220 used_dy=used_dy+0.01) + ; the following are ALL two cut contacts + (cond + (contact~>orient == "R270" + ; left is top, top is right, right is bottom, bottom is left (double vias) + + layer2XLeftEnclosure = layer2XLeftEnclosure - used_dy + dy_M7 + if(layer2XLeftEnclosure < 0.04 && layer2YBottomEnclosure < 0.03 layer2XLeftEnclosure=0.04) + if(layer2XLeftEnclosure < 0.0 layer2XLeftEnclosure=0.0) + layer2XRightEnclosure = layer2XRightEnclosure + used_dy - dy_M7 + if(layer2XRightEnclosure < 0.04 && layer2YBottomEnclosure < 0.03 layer2XRightEnclosure=0.04) + if(layer2XRightEnclosure < 0.0 layer2XRightEnclosure=0.0) + + if( contact~>cellName=="M7_M6_2CUT_H" then + if( layer2XLeftEnclosure>0.04 then + used_dy=used_dy+layer2XLeftEnclosure-0.04 + layer2XLeftEnclosure=0.04 + ) + if( layer2XRightEnclosure>0.04 then + used_dy=used_dy-layer2XRightEnclosure+0.04 + layer2XRightEnclosure=0.04 + ) + ) + ; left is top side + layer1XLeftEnclosure = layer1XLeftEnclosure-used_dy + if(layer1XLeftEnclosure < 0.0 layer1XLeftEnclosure=0.0) + if(layer1XLeftEnclosure < 0.04 && (layer1YBottomEnclosure < 0.03 || layer1YTopEnclosure < 0.03) layer1XLeftEnclosure=0.04) + ; right is bottom side + layer1XRightEnclosure = layer1XRightEnclosure+used_dy + if(layer1XRightEnclosure < 0.0 layer1XRightEnclosure=0.0) + if(layer1XRightEnclosure < 0.04 && (layer1YBottomEnclosure < 0.03 || layer1YTopEnclosure < 0.03) layer1XRightEnclosure=0.04) + + ; do not put too much extension if there is M6 already there (was needed to fix AREA) + if(member( contact plusYContacts) || member( contact minusYContacts) then + if(layer1XRightEnclosure > 0.04 layer1XRightEnclosure=0.04) + if(layer1XLeftEnclosure > 0.04 layer1XLeftEnclosure=0.04) + ) + ; if there seems to be room on M6, tweek the contact + (cond + (member( contact plusYContacts) && contact~>cellName=="M7_M6_2CUT_H" && track > 2 used_dy=used_dy+0.005) + (member( contact minusYContacts) && contact~>cellName=="M7_M6_2CUT_H" && track < 9 used_dy=used_dy-0.005) +; (member( contact plusYContacts) && contact~>cellName=="M7_M6_2CUT_H" && track > 2 printf("Plus %L %.3f %d\n" contact~>xy used_dy track) used_dy=used_dy+0.005) +; (member( contact minusYContacts) && contact~>cellName=="M7_M6_2CUT_H" && track < 9 printf("Minus %L %.3f %d\n" contact~>xy used_dy track) used_dy=used_dy-0.005) +; (contact~>cellName=="M7_M6_2CUT_H" printf("No change %L %.3f %d\n" contact~>xy used_dy track)) + ) + ) + (contact~>orient == "R0" + layer2YTopEnclosure = layer2YTopEnclosure - used_dy + dy_M7 + if(layer2YTopEnclosure < 0.04 && layer2XLeftEnclosure < 0.03 layer2YTopEnclosure=0.04) + if(layer2YTopEnclosure < 0.0 layer2YTopEnclosure=0.0) + layer2YBottomEnclosure = layer2YBottomEnclosure + used_dy - dy_M7 + if(layer2YBottomEnclosure < 0.04 && layer2XLeftEnclosure < 0.03 layer2YBottomEnclosure=0.04) + if(layer2YBottomEnclosure < 0.0 layer2YBottomEnclosure=0.0) + + if( contact~>cellName=="M7_M6_2CUT_V" then + if( layer2YTopEnclosure>0.04 then + used_dy=used_dy+layer2YTopEnclosure-0.04 + layer2YTopEnclosure=0.04 + ) + if( layer2YBottomEnclosure>0.04 then + used_dy=used_dy-layer2YBottomEnclosure+0.04 + layer2YBottomEnclosure=0.04 + ) + ) + ; Top side + layer1YTopEnclosure = layer1YTopEnclosure-used_dy + if(layer1YTopEnclosure < 0.0 layer1YTopEnclosure=0.0) + if(layer1YTopEnclosure < 0.04 && (layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YTopEnclosure=0.04) + ; Bottom side + layer1YBottomEnclosure = layer1YBottomEnclosure+used_dy + if(layer1YBottomEnclosure < 0.0 layer1YBottomEnclosure=0.0) + if(layer1YBottomEnclosure < 0.04 && (layer1XLeftEnclosure < 0.03 || layer1XRightEnclosure < 0.03) layer1YBottomEnclosure=0.04) + + ; do not put too much extension if there is M6 already there (was needed to fix AREA) + if(member( contact plusYContacts) || member( contact minusYContacts) then + if(layer1YBottomEnclosure > 0.04 layer1YBottomEnclosure=0.04) + if(layer1YTopEnclosure > 0.04 layer1YTopEnclosure=0.04) + ) + ; if there seems to be room on M6, tweek the contact + (cond + (member( contact plusYContacts) && contact~>cellName=="M7_M6_2CUT_V" && track > 2 used_dy=used_dy+0.005) + (member( contact minusYContacts) && contact~>cellName=="M7_M6_2CUT_V" && track < 9 used_dy=used_dy-0.005) +; (member( contact plusYContacts) && contact~>cellName=="M7_M6_2CUT_H" && track > 2 printf("Plus %L %.3f %d\n" contact~>xy used_dy track) used_dy=used_dy+0.005) +; (member( contact minusYContacts) && contact~>cellName=="M7_M6_2CUT_H" && track < 9 printf("Minus %L %.3f %d\n" contact~>xy used_dy track) used_dy=used_dy-0.005) +; (contact~>cellName=="M7_M6_2CUT_H" printf("No change %L %.3f %d\n" contact~>xy used_dy track)) + ) +; if(x == 9.84 && y == 399.78 printf("1 %s dy=%L x=%L y=%f o=%L l=%L r=%L t=%L b=%L\n" contact~>cellName +; used_dy car(contact~>xy) cadr(contact~>xy) contact~>orient +; layer1YTopEnclosure layer1YBottomEnclosure +; layer1XRightEnclosure layer1XLeftEnclosure)) + ) + (t printf("Warning: Unsupported orientation %s in contact %s at %.3f:%.3f\n" contact~>orient contact~>cellName x y)) + ) + +; if(x == 1105.08 && y == -437.28 printf("3 %s dy=%f x=%f y=%f o=%L l=%f r=%f t=%f b=%f\n" contact~>cellName +; used_dy car(contact~>xy) cadr(contact~>xy) contact~>orient +; layer2XLeftEnclosure, layer2XRightEnclosure +; layer2YTopEnclosure layer2YBottomEnclosure)) + contact~>xy = x:y+used_dy + dbReplaceProp( contact "layer1YDefOverride" "float" layer1YTopEnclosure) ; top + dbReplaceProp( contact "layer1YEnclosure" "float" layer1YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer1XDefOverride" "float" layer1XLeftEnclosure) ; left + dbReplaceProp( contact "layer1XEnclosure" "float" layer1XRightEnclosure) ; right + dbReplaceProp( contact "layer1Direction" "string" "br") +; + dbReplaceProp( contact "layer2YDefOverride" "float" layer2YTopEnclosure) ; top + dbReplaceProp( contact "layer2YEnclosure" "float" layer2YBottomEnclosure) ; bottom + dbReplaceProp( contact "layer2XDefOverride" "float" layer2XLeftEnclosure) ; left + dbReplaceProp( contact "layer2XEnclosure" "float" layer2XRightEnclosure) ; right + dbReplaceProp( contact "layer2Direction" "string" "br") + + return( t ) + ) +) + +; create distorted views from layout +; if the layout_pg exists, distort it, replace its subcells, +; then copy to distort view and delete the grid. +; if only layout exists, just distort that and replace its subells. +; viewname is the output view name and/or output_pg prefix +; layer is the layer to be shifted. For Alta it is ALWAYS M7 +; verbose is not all that effective, but it echos the cell being processed +; shift should always be true now. It shifts the double contacts if M6 says it is ok by 0.005 +; layout_only is really for debugging, will distort layout view even if layout_pg exists it will not distort it +(defun DistortCell (cellname @key + (viewname "distort") + (layer "M7") + (verbose nil) + (shift t) + (layout_only nil) + (clean nil) + (debug nil)) + (let (layoutcv layout_pgcv distortcv distort_pgcv) + if(debug verbose=t) + if(verbose printf("%s\n" cellname)) + layoutcv = (nrOpenCellViewReadableByName cellname "layout") + layout_pgcv=nil + if(layout_only == nil layout_pgcv = (nrOpenCellViewReadableByName cellname "layout_pg")) + distortcv = (nrOpenCellViewWritableByName cellname viewname) + distort_pgcv = nil + (when !layout_pgcv && verbose + (printf "No layout_pg view found. Using layout view.\n") + ) + (when !layoutcv + (error "No layout view found.\n") + ) + (if !distortcv then +; (error (sprintf nil "%s %s view not writable.\n" cellname viewname)) + (printf "%s %s view not writable.\n" cellname viewname) + else + (if layout_pgcv != nil then + distort_pgcv = (nrOpenCellViewWritableByName cellname (strcat viewname "_pg")) + (if distort_pgcv == nil then +; (error (sprintf nil "%s %s_pg view not writable.\n" cellname viewname)) + (printf "%s %s_pg view not writable.\n" cellname viewname) + else + (dbSave layout_pgcv distort_pgcv) + (DistortLayer ?CV distort_pgcv ?layer layer ?shift shift ?debug debug) + (ReplaceSubcells distort_pgcv "layout" viewname ?verbose nil) + (ReplaceSubcells distort_pgcv "layout_pg" (strcat viewname "_pg") ?verbose nil) + (DistortAddM78PowerGrid distort_pgcv viewname) + when( clean DistortClean(distort_pgcv ?verbose verbose )) + (dbSave distort_pgcv) + (dbSave distort_pgcv distortcv) + (DeletePowerGridInstance distortcv) + (dbSave distortcv) + ) + ) + + (when layoutcv && !layout_pgcv + distortcv = (nrOpenCellViewWritableByName cellname viewname) + (when !distortcv + (error (sprintf nil "%s view not writable.\n" viewname)) + ) + (dbSave layoutcv distortcv) + (DistortLayer ?CV distortcv ?layer layer ?shift shift ?debug debug) + (ReplaceSubcells distortcv "layout" viewname ?verbose nil) + (ReplaceSubcells distortcv "layout_pg" (strcat viewname "_pg") ?verbose nil ) + (DistortAddM78PowerGrid distortcv viewname) + when( clean DistortClean(distortcv ?verbose verbose )) + (dbSave distortcv) + ) + if(layoutcv dbPurge(layoutcv)) + if(layout_pgcv dbPurge(layout_pgcv)) + if(distortcv dbPurge(distortcv)) + if(distort_pgcv dbPurge(distort_pgcv)) + ) + t + ) +) + +; just grab the cell name from current window +(defun DistortCV () + (DistortCell (geGetWindowCellView)->cellName) +) + +; this is to fix a distort_pg view/distort view with m8grid instantiated +(defun DistortPGFix ( cellname @key (verbose t) (viewname "distort_pg") ) + (let (m8grid cv inst dpcv dcv) + (if verbose printf("%s\n" cellname)) + cv = (nrOpenCellViewReadableByName cellname "layout_pg") + m8grid = "globals.wires.POWER_GRID_M78" + if(cv then + dpcv = (nrOpenCellViewWritableByName cellname strcat( viewname "_pg") ) + (foreach inst dpcv->instances + (when inst->objType=="inst" && inst~>cellName == m8grid + (dbDeleteObject inst) + ) + (when inst->objType=="mosaicInst" && inst~>master~>cellName == m8grid + (dbDeleteObject inst~>mosaic) + ) + ) + dcv = (nrOpenCellViewWritableByName cellname viewname ) + (DistortAddM78PowerGrid dpcv viewname ) + dbSave(dpcv) + dbSave(dpcv dcv) + (DeletePowerGridInstance dcv) + (dbSave dcv) + (dbPurge dpcv) + (dbPurge dcv) + else + printf("Cannot open %s %s\n" cellname "layout_pg") + ) + t + ) +) + +; there are two potential cases as I see it. one is the normal flow where +; we have a POWER_GRID_TIEOFF cell. in this case, we will copy that cellview +; to a distorted view of its own and instantiate M78 wherever there is grid +; reaching up to m7. +; there are also layout(pg) views that were done by hand and merely instantiate +; mosaics of power grid tiles. in this case, we will directly instantiate matching +; mosaics of m78 in the layout(pg) view on top of the old grids. +(defun DistortAddM78PowerGrid (cv distortviewname) + (let (gridcv distortgridcv has_pg pginst m7grids m8grid xy orient num rows columns uX uY cellname) + m7grids = (list "globals.wires.POWER_GRID_M34567" + "globals.wires.POWER_GRID_M4567" + "globals.wires.POWER_GRID_M567" + "globals.wires.POWER_GRID_M67" + "globals.wires.POWER_GRID_M34567_FULL" + ) + m8grid = "globals.wires.POWER_GRID_M78" + + ;find the power grid cell + has_pg=nil + (foreach inst cv->instances + (when (IsPowerGridCell inst) + pginst = inst + has_pg=t + gridcv = (nrOpenCellViewReadableByName inst->cellName "layout") + distortgridcv = (nrOpenCellViewWritableByName inst->cellName distortviewname) + (when !distortgridcv + (error (sprintf nil "Can't open distort cell %s for write.\n" inst->cellName)) + ) + (if !gridcv then + (printf "Can't open cell %s layout for read, instance view %s\n" inst->cellName inst~>viewName) + has_pg=nil; +; dbDeleteObject(pginst) + else + (dbSave gridcv distortgridcv) + ) + ) + ) + + ;add m78 to the distort view of the power grid cell and instantiate it + (when has_pg + num=0 + ; delete M78 grid, no mosaics in PG? + (foreach inst setof( i distortgridcv->instances i~>cellName==m8grid) + (dbDeleteObject inst) + ) + ; put M78 grid back + (foreach inst distortgridcv->instances + (when inst->objType=="inst" + cellname = inst->cellName + ) + (when inst->objType=="mosaicInst" + cellname = inst->master->cellName + ) + (when (IsInList cellname m7grids) + (when inst->objType=="inst" + (dbCreateInstByMasterName distortgridcv "globals" m8grid + "layout" (sprintf nil "grid_%d" num) inst~>xy inst~>orient) + num=num+1 + ) + (when inst->objType=="mosaicInst" + (dbCreateSimpleMosaicByMasterName distortgridcv "globals" m8grid + "layout" (sprintf nil "grid_%d" num) inst~>mosaic~>xy + "R0" inst~>mosaic~>rows inst~>mosaic~>columns inst~>mosaic~>uY inst~>mosaic~>uX) + num=num+1 + ) + ) + ) + (dbSave distortgridcv) + (dbClose distortgridcv) + ;replace the old layout view with distort + (dbCreateInstByMasterName cv pginst->libName pginst->cellName + distortviewname (sprintf nil "distort_%s" pginst->name) pginst->xy pginst->orient) + (dbDeleteObject pginst) + ) + + ;if no grid cell, assume that mosaics are instantiated at the toplevel + (when !has_pg + num=0 + (foreach inst setof( i cv->instances i~>cellName==m8grid) + (if inst->objType=="mosaicInst" then + (dbDeleteObject inst~>mosaic) + else + (dbDeleteObject inst) + ) + ) + (foreach inst cv->instances + (when inst->objType=="inst" + cellname = inst->cellName + ) + (when inst->objType=="mosaicInst" + cellname = inst->master->cellName + ) + + (when (IsInList cellname m7grids) + (when inst->objType=="inst" + (dbCreateInstByMasterName cv "globals" m8grid + "layout" (sprintf nil "grid_%d" num) inst~>xy inst~>orient) + num=num+1 + ) + (when inst->objType=="mosaicInst" + (dbCreateSimpleMosaicByMasterName cv "globals" m8grid + "layout" (sprintf nil "grid_%d" num) inst~>mosaic~>xy + "R0" inst~>mosaic~>rows inst~>mosaic~>columns inst~>mosaic~>uY inst~>mosaic~>uX) + num=num+1 + ) + ) + ) + ) + ) +) + +; this function is a minimal set of stuff from RouteClean +(defun DistortClean ( CellView @key (verbose nil) ) + (let ( + ( DirectiveTable + ( CellInfoGetTableForCellName + "null" + ( sprintf + nil + "%s/share/Fulcrum" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ) ) + + ( Area + (when nil + ( enterBox ?prompts ( list "Select area to clean" ) ) ) ) + ) + + when(verbose printf("DistortClean\n")) + (cond ( + ( PinUtilFindPRBoundShape BoundaryLPP CellView ) + (let ( + ( MetalLPPs + ( append + ( list Metal6LPP ) + ( list Metal7LPP ) ) ) ) + + + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ( NotchesFillNotchesOnCellView CellView + + ( append + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "area" 0 ) + MetalLPP ) ) + MetalLPPs ) + ( append + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "notch" 0 ) MetalLPP ) ) + MetalLPPs ) + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "extension" 0 ) MetalLPP ) ) + MetalLPPs ) ) ) + + ( append + ( mapcar + (lambda ( MetalLPP ) + ( car MetalLPP ) ) + MetalLPPs ) + ( append + ( setof + Set + ;( list "AREA" "NOTCH" "EXTENSION" ) + ( list "AREA" ) + ( stringp Set ) ) + ( append + (if nil ; UIRouteClean_Form->UIRouteClean_Form_OnGrid->value + ( list + "M6_AREA_KEEPIN" + "M7_AREA_KEEPIN" ) ) + (if ( equal + ( VersionGetMajorVersion ) + "4" ) + ( list "VERSION_4X" ) ) ) ) ) + + ( sprintf + nil + "%s/share/Fulcrum/notch/fill_notches.assura.rules.all" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ?Area Area + ?NoPCells nil + ) + ; Why are we deleting Dummy? + ;( foreach LPP + ; ( mapcar + ; (lambda ( LPP ) + ; ( list ( car LPP ) "dummy" ) ) + ; MetalLPPs ) + ; ( foreach Shape ( PinUtilGetAllShapesOnLPP CellView LPP ) + ; ( dbDeleteObject Shape ) ) ) + ) ) + ( + ( printf "No prBoundary shape!!!\n" ) ) + + ) ) ) + +(defun Distort2CutCell ( cellname viewname @key (verbose nil)) + (let (cv) + cv = (nrOpenCellViewWritableByName cellname viewname) + if(cv then + Distort2Cut( cv ?verbose verbose) + dbSave(cv) + else + printf("Error: Cannot open %s %s for write\n" cellname viewname) + ) + ) +) + +; do both at once... Most of the time it seems best to do M6 first +(defun Distort2Cut ( CellView @key (verbose nil)) + DistortMXClean( CellView ?verbose verbose ?layer "M7" ?start t) + DistortMXClean( CellView ?verbose verbose ?layer "M6" ?start nil) + ; third pass to pick up remaining un-fixable contacts + DistortMXClean( CellView ?verbose verbose ?layer "M7" ?start nil) +) + +(defun DistortMXClean ( CellView @key + (verbose nil) + (layer "M7") ; we do actually run this on M6 AND M7 + (start t)) + (let ( x y twocut height ovelaps ucnt dcnt ccnt fix mincontact) + twocut=(setof contact CellView~>instances + (contact~>cellName=="M7_M6_2CUT_H" && member(contact~>orient list("R90" "R270" "MXR90" "MYR90"))) || + (contact~>cellName=="M7_M6_2CUT_V" && member(contact~>orient list("R0" "R180" "MX" "MY")))) + ucnt=0 + dcnt=0 + ccnt=0 + mincontact=nil + foreach( cut twocut + if(start==t then + cut~>Up="F" + cut~>Dn="F" + ) + x=car(cut~>xy) + y=cadr(cut~>xy) + height=0.38/2 ; two cut height, ignore ACTUAL height... mostly ok due to other changes + ; selected layer, drawing purpose, top only + ; check that it is NOT connected above because connected above does not need to move down + ; use 0.03 instead of 0.01 because sometimes another cut lies slighly offset just below + overlaps=dbGetOverlaps(CellView list( list( x-0.03 y+height+0.03) list(x+0.03 y+height-0.03)) list(layer "drawing")) + fix=nil + if( overlaps == nil then + if(layer == "M7" then + ; check pg only for M7 because it is horizontal + (let (grid delta) + ; find nearest power grid and see if it is close enough to create a violation + grid = round(y/2.88)*2.88 + delta=abs(grid-y)-0.2-0.19-0.1 ; 0.2=1/2 PG, 0.19=1/2 contact 0.1=spacing + if(delta < 0 && y-grid < 0 then + ucnt=ucnt+1 + fix=t + if(delta > -0.021 then + when( verbose printf("DG %.3f %.3f %s\n" x y cut~>cellName)) + y=y+delta + cut~>xy=list(x y) + cut~>Dn="T" + ) + ) + ) + ) + ; if we moved due to pg, no point in looking for other things + if(! fix then + ; x +- 0.06 to look for shapes not quite aligned + overlaps=dbGetTrueOverlaps(CellView list( list( x-0.06 y+height+0.095) list(x+0.06 y+height+0.095)) list(layer "drawing") 1 ) + foreach( ov overlaps + when( verbose printf("D1 %.3f %.3f %s %L %L %L\n" x y cut~>cellName ov~>objType ov~>bBox ov~>lpp)) + if(! fix ucnt=ucnt+1); count only once + fix=t + ) + if(fix then + y=y-0.005 + cut~>xy=list(x y) + cut~>Dn="T" + ) + ; do it twice + if(fix then + fix=nil + overlaps=dbGetTrueOverlaps(CellView list( list( x-0.06 y+height+0.095) list(x+0.06 y+height+0.095)) list(layer "drawing") 1 ) + foreach( ov overlaps + when(verbose printf("D2 %.3f %.3f %s %L %L %L\n" x y cut~>cellName ov~>objType ov~>bBox ov~>lpp)) + fix=t + ) + if(fix then + y=y-0.005 + cut~>xy=list(x y) + ) + ) + ; do it third time, sometimes have to move 0.015 + if(fix then + fix=nil + overlaps=dbGetTrueOverlaps(CellView list( list( x-0.06 y+height+0.095) list(x+0.06 y+height+0.095)) list(layer "drawing") 1 ) + foreach( ov overlaps + when(verbose printf("D3 %.3f %.3f %s %L %L %L\n" x y cut~>cellName ov~>objType ov~>bBox ov~>lpp)) + fix=t + ) + if(fix then + y=y-0.005 + cut~>xy=list(x y) + ) + ) + ) + ) + ; now do the same in the other direction + overlaps=dbGetOverlaps(CellView list( list( x-0.03 y-height-0.03) list(x+0.03 y-height+0.03)) list(layer "drawing")) + fix=nil + if( overlaps == nil then + if(layer == "M7" then + ; check pg only for M7 because it is horizontal + (let (grid delta) + ; find nearest power grid and see if it is close enough to create a violation + grid = round(y/2.88)*2.88 + delta=abs(grid-y)-0.2-0.19-0.1 ; 0.2=1/2 PG, 0.19=1/2 contact 0.1=spacing + if(delta < 0 && y-grid > 0 then + when( verbose printf("UG %.3f %.3f %s\n" x y cut~>cellName)) + dcnt=dcnt+1 + fix=t + if(delta > -0.021 then + y=y-delta + cut~>xy=list(x y) + cut~>Up="T" + ) + ) + ) + ) + if( ! fix then + overlaps=dbGetTrueOverlaps(CellView list( list( x-0.06 y-height-0.095) list(x+0.06 y-height-0.095)) list(layer "drawing") 1 ) + foreach( ov overlaps + when(verbose printf("U1 %.3f %.3f %s %L %L %L\n" x y cut~>cellName ov~>objType ov~>bBox ov~>lpp)) + if(! fix dcnt=dcnt+1) + fix=t + ) + if(fix then + y=y+0.005 + cut~>xy=list(x y) + cut~>Up="T" + ) + ; do it twice + ; but there ought to be a way to use the first set of overlap's coordinates to tell how much to shift, the problem + ; is that sometimes it is an instance (like another contact) and sometimes it is a shape + if( fix then + fix=nil + overlaps=dbGetTrueOverlaps(CellView list( list( x-0.06 y-height-0.095) list(x+0.06 y-height-0.095)) list(layer "drawing") 1 ) + foreach( ov overlaps + when( verbose printf("U2 %.3f %.3f %s %L %L %L\n" x y cut~>cellName ov~>objType ov~>bBox ov~>lpp)) + fix=t + ) + if(fix then + y=y+0.005 + cut~>xy=list(x y) + ) + ) + ; do it third time + if( fix then + fix=nil + overlaps=dbGetTrueOverlaps(CellView list( list( x-0.06 y-height-0.095) list(x+0.06 y-height-0.095)) list(layer "drawing") 1 ) + foreach( ov overlaps + when( verbose printf("U3 %.3f %.3f %s %L %L %L\n" x y cut~>cellName ov~>objType ov~>bBox ov~>lpp)) + fix=t + ) + if(fix then + y=y+0.005 + cut~>xy=list(x y) + ) + ) + ) + ) + ; if we had to move both ways, this is un-fixable as a 2cut + if(cut~>Up=="T" && cut~>Dn=="T" then + if(mincontact == nil mincontact=dbOpenCellViewByType( TechLibName "M7_M6min" "layout" "maskLayout" "r")) + cut~>master=mincontact + ; change extensions and align with m7 + if(cut~>OriginalY != nil cut~>xy=(list x cut~>OriginalY)) + cut~>orient="R0" ; the extensions below assume R0 + dbReplaceProp( cut "layer1YDefOverride" "float" 0.05) ; top + dbReplaceProp( cut "layer1YEnclosure" "float" 0.05) ; bottom + dbReplaceProp( cut "layer1XDefOverride" "float" 0.01) ; left + dbReplaceProp( cut "layer1XEnclosure" "float" 0.01) ; right + dbReplaceProp( cut "layer1Direction" "string" "br") + dbReplaceProp( cut "layer2YDefOverride" "float" 0.01) ; top + dbReplaceProp( cut "layer2YEnclosure" "float" 0.01) ; bottom + dbReplaceProp( cut "layer2XDefOverride" "float" 0.04) ; left + dbReplaceProp( cut "layer2XEnclosure" "float" 0.04) ; right + dbReplaceProp( cut "layer2Direction" "string" "br") + printf("Change Two Cut to One Cut %.3f %.3f %s\n" x y cut~>cellName) + ccnt=ccnt+1 + ) + ) + when(verbose printf("Count %s UP %d DN %d\n" layer dcnt ucnt)) + when(ccnt > 0 printf("Info: %d Contacts changed to single cut\n" ccnt)) + ) +) + + + + +(defun MakeDistort + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + ) + (let (layoutCV tiehilo) + (when CV->viewName=="distort_pg" + layoutCV = (dbCopyCellView CV CV->libName CV->cellName "distort" nil nil t) + (when !layoutCV (error "Unable to write layout view\n")) + tiehilo = (dbFindAnyInstByName layoutCV "distort_tiehilo") + (when tiehilo (dbDeleteObject tiehilo)) + tiehilo = (dbFindMosaicByName layoutCV "distort_tiehilo") + (when tiehilo (dbDeleteObject tiehilo)) + (dbSave layoutCV) + ) + layoutCV + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fig/fig.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fig/fig.il new file mode 100644 index 0000000000..1d62b91501 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fig/fig.il @@ -0,0 +1,130 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +;aligns reference point of Fig to Point +(defun FigMove ( Fig + Point + @key + ( Orient nil ) + ( Align "ll" ) + ) + ;first orient + (when Orient + ( dbSetq Fig Orient orient ) ) + + ( dbMoveFig + Fig + nil + ( list + ( PointDifference + Point + (cond ( + ( equal Align "ll" ) + ( car ( getq Fig bBox ) ) ) + ( + ( equal Align "lr" ) + ( list ( RectGetRight ( getq Fig bBox ) ) + ( RectGetBottom ( getq Fig bBox ) ) ) ) ) ) + "R0" ) ) ) + +(defun FigStackClumps ( Clumps Y ) + ( foreach Clump Clumps + (when Clump + (let ( + ( Bottom + ( ListFindMinimum + Clump + (lambda ( Fig ) + ( RectGetBottom ( getq Fig bBox ) ) ) ) ) ) + ( foreach Fig Clump + ( dbMoveFig + Fig + nil + ( list ( list 0 ( difference Y Bottom ) ) + "R0" ) ) ) + ( setq + Y + ( ListFindMaximum + Clump + (lambda ( Fig ) + ( RectGetTop ( getq Fig bBox ) ) ) ) ) + ) ) ) ) + + +(defun FigStack ( Stack Y ) + ( foreach Fig Stack + ( FigMove + Fig + ( list + ( RectGetLeft ( getq Fig bBox ) ) + Y ) ) + ( setq Y + ( RectGetTop ( getq Fig bBox ) ) ) ) ) + +(defun FigStackHorizontal ( Stack X ) + ( foreach Fig Stack + ( FigMove + Fig + ( list + X + ( RectGetBottom ( getq Fig bBox ) ) ) ) + ( setq X + ( RectGetRight ( getq Fig bBox ) ) ) + ) ) + +;Move all figs together so that left-most point is at X +(defun FigStackHorizontalMaintainSep ( Stack X ) + (let ( + ( Offset ( difference + X + ( RectGetLeft ( getq ( car Stack ) bBox ) ) + ) ) ) + ( foreach Fig Stack + ( dbMoveFig + Fig + nil + ( list Offset:0 "R0" ) ) ) ) ) + + + +(defun FigGetClumpTable ( Instances + @key + ( ClumpPredicate + `RectDoRectsOverlapOpenRects ) + ( Clumpify + (lambda ( C ) ( getq C bBox ) ) ) + ( ClumpUnion + `RectGetBoundRect ) + ( InstanceTable + ( makeTable `bar nil ) ) + ) + ( foreach Instance Instances + (let ( + ( Clump + ( apply Clumpify ( list Instance ) ) ) ) + (let ( + ( Union Clump ) + ( IntersectingClumps + ( setof OtherClump InstanceTable + ( apply ClumpPredicate ( list Clump OtherClump ) ) ) ) ) + (let ( + ( Instances + ( ListNonDestructiveMapCan + (lambda ( IntersectingClump ) + (let ( + ( Instances ( arrayref + InstanceTable + IntersectingClump ) ) ) + ( remove IntersectingClump InstanceTable ) + ( setq Union ( apply + ClumpUnion + ( list IntersectingClump + Union ) ) ) + Instances ) ) + IntersectingClumps ) ) ) + ( setarray InstanceTable Union + ( cons Instance Instances ) ) ) ) ) ) + InstanceTable ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/SpareCellFill.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/SpareCellFill.il new file mode 100644 index 0000000000..a1e5c39e95 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/SpareCellFill.il @@ -0,0 +1,239 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( AutoSpareCell ( CellView fillCellName + @key + (fillViewName "layout") + (PowerGridSize 5.76) + (PowerGridOffset 0.24) + (FillWithSpareCell t) + (FillWithDcapCell nil) + (FillWithM2M7 t) + (SpareCellLibName "lib.util.spare") + (LargeSpareCellName "lib.util.spare.LARGE_SPARE_GATES.500") + (SmallSpareCellName "lib.util.spare.SMALL_SPARE_GATES.500") + (LargeSpaceCellGridX 3) + (LargeSpaceCellGridY 4) + (FillCellLibName "globals") + (DcapFillCellName "globals.fill.DCAP") + (ODPOM1FillCellName "globals.fill.ODPOM1") + (ODM1FillCellName "globals.fill.ODM1") + (ODPOFillCellName "globals.fill.ODPO") + (ODSMALLFillCellName "globals.fill.OD_SMALL") + (M2FillCellName "globals.fill.M2") + (M3FillCellName "globals.fill.M3") + (M4FillCellName "globals.fill.M4") + (M5FillCellName "globals.fill.M5") + (M6FillCellName "globals.fill.M6") + (M7FillCellName "globals.fill.M7") + (M23FillCellName "globals.fill.M23") + (M34FillCellName "globals.fill.M34") + (M45FillCellName "globals.fill.M45") + (M56FillCellName "globals.fill.M56") + (M67FillCellName "globals.fill.M67") + (LeaveMess nil) + ) + prog(( fillTempView fillGridView x1 x2 x1s x2s y1 y2 y1s y2s x y i j ci + AssuraLayerMappings AssuraRuleFile AssuraSets libName) + ; create table of fill cell mappings to generated layers + ReplaceCellNameTable=makeTable("a" "") + ReplaceCellNameTable[car(NImplantLPP)]=SmallSpareCellName + ReplaceCellNameTable[car(PImplantLPP)]=LargeSpareCellName + ReplaceCellNameTable[car(PolyLPP)]=DcapFillCellName + ReplaceCellNameTable[car(NWellLPP)]=ODSMALLFillCellName + ReplaceCellNameTable[car(DiffLPP)]=ODPOFillCellName + ReplaceCellNameTable[car(Metal1LPP)]=ODM1FillCellName + ReplaceCellNameTable[car(Metal2LPP)]=M2FillCellName + ReplaceCellNameTable[car(Metal3LPP)]=M3FillCellName + ReplaceCellNameTable[car(Metal4LPP)]=M4FillCellName + ReplaceCellNameTable[car(Metal5LPP)]=M5FillCellName + ReplaceCellNameTable[car(Metal6LPP)]=M6FillCellName + ReplaceCellNameTable[car(Metal7LPP)]=M7FillCellName + ReplaceCellNameTable[car(Via23LPP)]=M23FillCellName + ReplaceCellNameTable[car(Via34LPP)]=M34FillCellName + ReplaceCellNameTable[car(Via45LPP)]=M45FillCellName + ReplaceCellNameTable[car(Via56LPP)]=M56FillCellName + ReplaceCellNameTable[car(Via67LPP)]=M67FillCellName + ci=setof( in CellView~>instances in~>cellName == fillCellName) + if(ci + foreach( i ci + dbDeleteObject( i ) + printf("Warning: %s exists in %s, removing\n" fillCellName CellView~>cellName) + ) + ) +; fillGridView=ddGetObj( CellView~>libName fillCellName "layout" ) +; if( fillGridView != nil then +; ddDeleteObj(fillGridView) +; printf("Warning: Deleted cell %s\n" fillCellName) +; ) + ; check for p4Bound + if( setof( lpp CellView~>lpps lpp~>layerName=="prBoundary" ) == nil then + printf("Error: There is no prBoundary layer defined in cellview %s. \n" CellView~>cellName) + return(nil) + ) + ; delete existing temp cell if it exists + fillTempView=ddGetObj( CellView~>libName CellView~>cellName "autoFillGrid_temp") + if( fillTempView != nil ddDeleteObj(fillTempView) ) + ; create new temp cell + fillTempView=dbOpenCellViewByType( CellView~>libName CellView~>cellName "autoFillGrid_temp" "maskLayout" "w" ) + if( fillTempView == nil then + printf("Error: Can not open cellview %s (autoFillGrid_temp) for write. \n" CellView~>cellName) + return(nil) + ) + ; create new the fill cell + fillGridView=nrOpenCellViewWritable(CellView~>libName fillCellName fillViewName) + if( fillGridView == nil then + printf("Error: Can not open cellview %s (%s) for write. \n" fillCellName fillViewName) + return(nil) + ) + ; get the small fill cell + smallGridCellView=nrOpenCellViewReadable(SpareCellLibName SmallSpareCellName "layout") + if( smallGridCellView == nil then + printf("Error: Can not open cellview %s for read. \n" SmallSpaceCellName) + return(nil) + ) + ; get the large fill cell + largeGridCellView=nrOpenCellViewReadable(SpareCellLibName LargeSpareCellName "layout") + if( largeGridCellView == nil then + printf("Error: Can not open cellview %s for read. \n" LargeSpaceCellName) + return(nil) + ) + + ; instantiate the cell to be filled in the temp view + dbCreateInst( fillTempView CellView "I0" list(0 0) "R0" ) + ; ??? shouldn' this be dbSave( fillTempView ) ??? + dbSave( CellView ) + ; Draw 5.76 x 5.76 rectangle grid + x1=leftEdge( fillTempView~>bBox ) + x2=rightEdge( fillTempView~>bBox ) + y1=bottomEdge( fillTempView~>bBox ) + y2=topEdge( fillTempView~>bBox ) + x1s=floor(x1/(PowerGridSize/2)) + x1=floor(x1/PowerGridSize) + y1s=floor((y1+PowerGridOffset)/(PowerGridSize/2)) + y1=floor((y1+PowerGridOffset)/PowerGridSize) + x2s=floor(x2/(PowerGridSize/2)) + x2=floor(x2/PowerGridSize) + y2s=floor((y2+PowerGridOffset-0.005)/(PowerGridSize/2)) + y2=floor((y2+PowerGridOffset-0.005)/PowerGridSize) + ; create a pg size grid + for( i x1 x2 + x=i*PowerGridSize + for( j y1 y2 + y=j*PowerGridSize-PowerGridOffset + ; rectangles are slightly small so they are maintained as rectangles thru the Assura processing! + ; the only thing important is the lower left corner + dbCreateRect(fillTempView list("y0" "drawing") list(x:y x+PowerGridSize-0.005:y+PowerGridSize-0.005)) + ) + ) + ; create a large cell size grid + for( i floor(x1/LargeSpaceCellGridX) floor(x2/LargeSpaceCellGridX) + x=i*PowerGridSize*LargeSpaceCellGridX + for( j floor(y1/LargeSpaceCellGridY) floor(y2/LargeSpaceCellGridY) + y=j*PowerGridSize*LargeSpaceCellGridY-PowerGridOffset + ; rectangles are slightly small so they are maintained as rectangles thru the Assura processing! + dbCreateRect(fillTempView list("y1" "drawing") list(x:y x+PowerGridSize*LargeSpaceCellGridX-0.005:y+PowerGridSize*LargeSpaceCellGridY-0.005)) + ) + ) + ; create a 1/2 pg size grid for OD_SMALL + for( i x1s x2s + x=i*PowerGridSize/2 + for( j y1s y2s + y=j*PowerGridSize/2-PowerGridOffset + ; rectangles are slightly small so they are maintained as rectangles thru the Assura processing! + ; the only thing important is the lower left corner + ; y2 is a block layer, do not use y2 + dbCreateRect(fillTempView list("y3" "drawing") list(x:y x+PowerGridSize/2-0.005:y+PowerGridSize/2-0.005)) + ) + ) + dbSave( fillTempView ) + printf("Creating %s layout\n" fillCellName ) + ; run layer processing + AssuraLayerMappings = (list (list "smallFill" NImplantLPP) + (list "largeFill" PImplantLPP) + (list "dcapFill" PolyLPP) + (list "odsmallFill" NWellLPP) + (list "odFill" DiffLPP) + (list "m1Fill" Metal1LPP) + (list "m2Fill" Metal2LPP) + (list "m3Fill" Metal3LPP) + (list "m4Fill" Metal4LPP) + (list "m5Fill" Metal5LPP) + (list "m6Fill" Metal6LPP) + (list "m7Fill" Metal7LPP) + (list "via23Fill" Via23LPP) + (list "via34Fill" Via34LPP) + (list "via45Fill" Via45LPP) + (list "via56Fill" Via56LPP) + (list "via67Fill" Via67LPP) + ) + AssuraSets = append( + append( + if( FillWithSpareCell list("SPAREGATE") nil ) + if( FillWithDcapCell list("DCAP") nil ) + ) + if( FillWithM2M7 list("M2M7") nil ) + ) + AssuraRuleFile = sprintf( nil "%s/share/Fulcrum/filler/%s" + ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT") + "generateFill.rul") + AssuraRunLog = sprintf( nil "%s/%s.fill_grid.log" + ConfigFileGetValue( TheCDSConfigTable "TEMP") + CellView~>cellName ) + ErrorStr = AssuraRunAssuraLayerProcessor( + fillTempView CellView~>libName fillCellName fillViewName + AssuraRuleFile + ConfigFileGetValue( TheCDSConfigTable "TEMP") + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess LeaveMess + ?AssuraSets AssuraSets + ) + ddDeleteObj(ddGetObj(fillTempView~>libName fillTempView~>cellName fillTempView~>viewName)) + fillGridView=nrOpenCellViewWritable(CellView~>libName fillCellName fillViewName) + + count=0 + foreach( lpp fillGridView~>lpps + if(ReplaceCellNameTable[lpp~>layerName]!="" then + if( lpp~>layerName==car(NImplantLPP) || lpp~>layerName==car(PImplantLPP) then + libName=SpareCellLibName + else + libName=FillCellLibName + ) + fillMosaicView=nrOpenCellViewReadable( libName ReplaceCellNameTable[lpp~>layerName] "layout" ) + if( fillMosaicView == nil then printf("(%s) (%s)\n" libName lpp~>layerName)) + x1=0 + foreach( shape lpp~>shapes + if( shape~>objType == "rect" || (shape~>objType == "polygon" && shape~>nPoints==5) then + x2=leftEdge(shape~>bBox) + ; small cells, do not offset + if(ReplaceCellNameTable[lpp~>layerName] == "globals.fill.OD_SMALL" + y2=bottomEdge(shape~>bBox) + y2=bottomEdge(shape~>bBox)+PowerGridOffset + ) + ; suggested alternative, to be tested + ; if( abs(x2-floor(x2/PowerGridSize+0.0001)*PowerGridSize)<0.001 && abs(y2-floor(y2/PowerGridSize+0.0001)*PowerGridSize)<0.001 then + ; I think the following condition is always true!, see above + if( abs(x2-(x2/PowerGridSize)*PowerGridSize)<0.001 && abs(y2-(y2/PowerGridSize)*PowerGridSize)<0.001 then + dbCreateInst(fillGridView fillMosaicView sprintf( nil "F%d" count ) list(x2 y2) "R0" ) + count=count+1 + x1=x1+1 + ) + else + printf("Warning: no rectangle %s shape found: %L\n" shape~>layerName shape~>points) + ) + dbDeleteObject(shape) + ) + printf("%s count: %d \n" ReplaceCellNameTable[lpp~>layerName] x1) + ) + ) + printf("Done: %s (%s) created. \n" fillCellName fillViewName) + dbSave(fillGridView) + return(fillGridView) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.il new file mode 100644 index 0000000000..6638a79984 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.il @@ -0,0 +1,476 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +
    +****************
    +Fill Overview
    +****************
    +
    +There are 3 types of fill. 
    +All of them place fill only in areas marked with ( "y9" "drawing" ), which we call the 
    +fill boundary.
    +
    +In the order they are typically run.
    +* Fill grid (assura rules )
    +  This is placed everywhere where there is non-power-grid metal.
    +  Powergrid is on M3-M7.  M3-M5 have a 4.8x9.6 pitch.  M6-M8 have a 9.6x9.6 pitch.
    +  Powergrid is signaled by the existence of yN layers 
    +  (e.g ("y3" "drawing" ) means that there is M3 powergrid here.  
    +  Care must be taken not to draw these layers anywhere but the STANDARD powergrid!
    +  There was a case where a M7_wide powergrid cell had y7 drawing where it shouldn't
    +  and this caused shorts.
    +  
    +  The cells are placed per metal layer.
    +  (e.g. globals.fill.M3 is the fill for metal 3)
    +  We also place via cells between layers, that avoids non-power grid metal on 
    +  the 2 layers it connects.  
    +  (e.g. globals.fill.VIA34 has vias that connects the M3 to M4 powergrid.
    +  The via cells also have redundant metal in them so we dont have any floating vias.
    +
    +  Each fill cell is the same size as its metal's powergrid pitch.
    +  (e.g. globals.fill.M3 is 4.8x9.6)
    +
    +  
    +  The cells are placed with assura using generateRectangle() which just tiles them all in
    +  the fill boundary, and then gets rid of rectangles that are within 1.2u of non-powergrid
    +  shapes.  Assura returns with a bunch of rectangles which are postprocessed into fillergrid cells.
    +  
    +  There is another post-processing stage called mosaicification, which converts these instances
    +  into mosaics.  To run this, Do the following:
    +  * From layout: ( dbWriteSkill cellview "file1" "w" "5.0" )
    +  * Run fulcrum mosaicify file1 file2
    +  * From layout, open an empty cellview where you want the mosaics, nad ( load "file2" )
    +    If you have multiple cellviews and you want to merge all their mosaics, just cat
    +    together the results of dbWriteSkill. 
    +
    +* Fill cells (assura rules )
    +  This is placed 0.6u away from existing metal.  It just uses the standard assura
    +  generateFill().  The fill is non-optimal but is space-efficient because it consists
    +  of mosaics. 
    +
    +
    +* Fill shapes (assura rules )
    +  This is placed 0.6u away from existing metal.  It is more optimal than filler cells
    +  but it consists of flat shapes.  Care is taken to avoid spacing <=0.4, area<=1.44, 
    +  width<=0.6, and vertices>4.  Particularly useful for place and route cells.
    +  
    +
    +****************
    +How to run fill
    +****************
    +
    +Currently, the interface is through the CIW in cadence.  For chip level stuff you'll 
    +probably want to start cadence with
    +CDS_AUTO_64BIT=ALL /usr/local/cadence/scripts/cadence.latest.run layout
    +
    +
    +Just run ( Fill cellview ?Type type ?Layers layers )
    +
    +cellview is a cellview dbId
    +type is one of ("grid" "cells" "shapes")
    +layers is t or nil and it means the following for the different types
    +
    +grid/nil   : od through m2
    +grid/t     : via23 through m7, dont export gates/stacks
    +
    +cells/nil  : od through m1
    +cells/t    : m2 through m7, don't export gates/stacks
    +
    +shapes/t   : m2 though m3, don't export gates/stacks
    +shapes/nil : m4 through m7, don't export gates/stacks
    +
    +First the CIW will tell you the name of the library to look for the result...
    +something like FILL_grid0
    +The library will be in your cds.config TEMP directory, and the assura logs
    +will be in some AssuraRuXXXXX directory inside your TEMP directory.
    +
    +
    +Then it will probably complain about some libraries or something(don't worry),
    +and then it will say:
    +
    +"running assura"
    +
    +Then it will run for a while (3-4 hours or so for the chip, depending on the type of run)
    +and come back with:
    +
    +"done with assura"
    +
    +And you're good to go.
    +
    +*/ + +(defun FillerGridAlignInstances ( CellView + FillerGridLibCellExpressionPairs + FillerGridAlignmentInUserUnits ) + (let ( + ( FilterRet ( NameFilterInstances + ( getq CellView instances ) + FillerGridLibCellExpressionPairs ) ) ) + (let ( + ( FillerGridInstances ( cadr FilterRet ) ) ) + ( foreach + Instance + FillerGridInstances + ( InstanceAlignInstance Instance FillerGridAlignmentInUserUnits ) ) ) ) ) + +(defun FillerGridMakeFillerGrid ( SrcCellView + TargetLibName + PDKPackageRoot + TempDir + FillerGridLib + FillerGridPolyCellName + FillerGridM1CellName + FillerGridM2CellName + FillerGridM3CellName + FillerGridM4CellName + FillerGridM5CellName + FillerGridM6CellName + FillerGridM7CellName + FillerGridContCellName + FillerGridVia12CellName + FillerGridVia23CellName + FillerGridVia34CellName + FillerGridVia45CellName + FillerGridVia56CellName + FillerGridVia67CellName + FillerGridViewName + FillerGridAlignmentInUserUnits + FillerGridLPP + @key + ( LeaveMess nil ) + ( M2M7 nil ) + ( ODM2 nil ) + ) + (let ( + ( RuleFile + ( sprintf + nil "%s/share/Fulcrum/filler/fillergrid.rul" PDKPackageRoot ) ) + ( ErrorStr nil ) ) + + ( setq + ErrorStr + ( AssuraRunAssuraLayerProcessor + SrcCellView + TargetLibName + ( getq SrcCellView cellName ) + ( getq SrcCellView viewName ) + RuleFile + TempDir + ( append + (when ODM2 + ( list + ( list "polyFill" PolyLPP ) + ( list "m1Fill" Metal1LPP ) + ( list "contFill" ContactLPP ) + ( list "m2Fill" Metal2LPP ) + ( list "via12Fill" Via12LPP ) + ) ) + (when M2M7 + ( list + ( list "m3Fill" Metal3LPP ) + ( list "m4Fill" Metal4LPP ) + ( list "m5Fill" Metal5LPP ) + ( list "m6Fill" Metal6LPP ) + ( list "m7Fill" Metal7LPP ) + ( list "via23Fill" Via23LPP ) + ( list "via34Fill" Via34LPP ) + ( list "via45Fill" Via45LPP ) + ( list "via56Fill" Via56LPP ) + ( list "via67Fill" Via67LPP ) + ) ) ) + + ( append + (when ODM2 + ( list + ( list + ( list FillerGridLib FillerGridPolyCellName FillerGridViewName ) + "polyFill" ) + ( list + ( list FillerGridLib FillerGridM1CellName FillerGridViewName ) + "m1Fill" ) + ( list + ( list FillerGridLib FillerGridM2CellName FillerGridViewName ) + "m2Fill" ) + ( list + ( list FillerGridLib FillerGridContCellName FillerGridViewName ) + "contFill" ) + ( list + ( list FillerGridLib FillerGridVia12CellName FillerGridViewName ) + "via12Fill" ) ) ) + (when M2M7 + ( list + ( list + ( list FillerGridLib FillerGridM3CellName FillerGridViewName ) + "m3Fill" ) + ( list + ( list FillerGridLib FillerGridM4CellName FillerGridViewName ) + "m4Fill" ) + ( list + ( list FillerGridLib FillerGridM5CellName FillerGridViewName ) + "m5Fill" ) + ( list + ( list FillerGridLib FillerGridM6CellName FillerGridViewName ) + "m6Fill" ) + ( list + ( list FillerGridLib FillerGridM7CellName FillerGridViewName ) + "m7Fill" ) + + ( list + ( list FillerGridLib FillerGridVia23CellName FillerGridViewName ) + "via23Fill" ) + ( list + ( list FillerGridLib FillerGridVia34CellName FillerGridViewName ) + "via34Fill" ) + ( list + ( list FillerGridLib FillerGridVia45CellName FillerGridViewName ) + "via45Fill" ) + ( list + ( list FillerGridLib FillerGridVia56CellName FillerGridViewName ) + "via56Fill" ) + ( list + ( list FillerGridLib FillerGridVia67CellName FillerGridViewName ) + "via67Fill" ) + ) ) ) + ?AssuraSets ( append (when ODM2 ( list "ODM2" ) ) ( when M2M7 ( list "M2M7" ) ) ) + ?CustomFill t + ?NoPCells ( not ODM2 ) + ?LeaveMess LeaveMess + ?AssuraRunLog "assura.log" + ) ) + ( println ErrorStr ) ) ) + + + +(defun FillerMakeFillerCells ( SrcCellView + TargetLibName + PDKPackageRoot + TempDir + FillerGridLib + FillerGridODPolyBigCellName + FillerGridODPolySmallCellName + FillerLPP + @key + ( LeaveMess nil ) + ( M2M7 nil ) + ( ODM1 nil ) ) + (let ( + ( RuleFile + ( sprintf + nil + "%s/share/Fulcrum/filler/fillercells.rul" + PDKPackageRoot ) ) + ( ErrorStr nil ) ) + + ( setq + ErrorStr + ( AssuraRunAssuraLayerProcessor + SrcCellView + TargetLibName + ( getq SrcCellView cellName ) + ( getq SrcCellView viewName ) + RuleFile + TempDir + ( append + (when ODM1 + ( list + ( list "odFillBig" DiffLPP ) + ( list "odFillSmall" DiffLPP ) + ( list "m1Fill" Metal1LPP ) ) ) + (when M2M7 + ( list + ( list "m2Fill" Metal2LPP ) + ( list "m3Fill" Metal3LPP ) + ( list "m4Fill" Metal4LPP ) + ( list "m5Fill" Metal5LPP ) + ( list "m6Fill" Metal6LPP ) + ( list "m7Fill" Metal7LPP ) + ) ) ) + + (when ODM1 + ( list + ( list + ( list FillerGridLib FillerGridODPolyBigCellName FillerGridViewName ) + "odFillBig" ) + ( list + ( list FillerGridLib FillerGridODPolySmallCellName FillerGridViewName ) + "odFillSmall" ) + + ( list + ( list FillerGridLib "globals.fill.M1BOX" FillerGridViewName ) + "m1Fill_FILL" ) + ( list + ( list FillerGridLib "globals.fill.M2BOX" FillerGridViewName ) + "m2Fill_FILL" ) + ( list + ( list FillerGridLib "globals.fill.M3BOX" FillerGridViewName ) + "m3Fill_FILL" ) + ( list + ( list FillerGridLib "globals.fill.M4BOX" FillerGridViewName ) + "m4Fill_FILL" ) + ( list + ( list FillerGridLib "globals.fill.M5BOX" FillerGridViewName ) + "m5Fill_FILL" ) + ( list + ( list FillerGridLib "globals.fill.M6BOX" FillerGridViewName ) + "m6Fill_FILL" ) + ( list + ( list FillerGridLib "globals.fill.M7BOX" FillerGridViewName ) + "m7Fill_FILL" ) + + ) ) + + ?AssuraSets ( append (when ODM1 ( list "ODM1" ) ) ( when M2M7 ( list "M2M7" ) ) ) + ?Promote t + ?NoPCells ( not ODM1 ) + ?LeaveMess LeaveMess + ) ) + (cond ( + ErrorStr + ( println ErrorStr ) ) ) ) ) + + +(defun FillerMakeFillerShapes ( SrcCellView + TargetLibName + PDKPackageRoot + TempDir + @key + ( LeaveMess nil ) + ( M2M3 nil ) + ( M4M7 nil ) ) + (let ( + ( RuleFile + ( sprintf + nil + "%s/share/Fulcrum/filler/fillershapes.rul" + PDKPackageRoot ) ) + ( ErrorStr nil ) ) + + ( setq + ErrorStr + ( AssuraRunAssuraLayerProcessor + SrcCellView + TargetLibName + ( getq SrcCellView cellName ) + ( getq SrcCellView viewName ) + RuleFile + TempDir + ( list + ( list "m2Fill" ( list ( car Metal2LPP ) "dummy" ) ) + ( list "m3Fill" ( list ( car Metal3LPP ) "dummy" ) ) + ( list "m4Fill" ( list ( car Metal4LPP ) "dummy" ) ) + ( list "m5Fill" ( list ( car Metal5LPP ) "dummy" ) ) + ( list "m6Fill" ( list ( car Metal6LPP ) "dummy" ) ) + ( list "m7Fill" ( list ( car Metal7LPP ) "dummy" ) ) + ) + nil + ?AssuraSets ( append (when M2M3 ( list "M2M3" ) ) ( when M4M7 ( list "M4M7" ) ) ) + ?NoPCells t + ?LeaveMess LeaveMess + ) ) + (cond ( + ErrorStr + ( println ErrorStr ) ) ) ) ) + +; creates a cell in library +; Fill_XXXXXX + +(defun Fill ( CellView + @key + ( Type "grid" ) + ( Layers nil ) + ( LeaveMess nil ) + ) + (let ( + ( FillerGridLib "globals" ) + ( FillerGridViewName "layout" ) + ( TempDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ( PDKPackageRoot ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + + ( FillerGridPolyCellName "globals.fill.DCAP" ) + ( FillerGridM1CellName "globals.fill.M1" ) + ( FillerGridM2CellName "globals.fill.M2" ) + ( FillerGridM3CellName "globals.fill.M3" ) + ( FillerGridM4CellName "globals.fill.M4" ) + ( FillerGridM5CellName "globals.fill.M5" ) + ( FillerGridM6CellName "globals.fill.M6" ) + ( FillerGridM7CellName "globals.fill.M7" ) + + ( FillerGridContCellName "globals.fill.DCAP" ) + ( FillerGridVia12CellName "globals.fill.M12" ) + ( FillerGridVia23CellName "globals.fill.M23" ) + ( FillerGridVia34CellName "globals.fill.M34" ) + ( FillerGridVia45CellName "globals.fill.M45" ) + ( FillerGridVia56CellName "globals.fill.M56" ) + ( FillerGridVia67CellName "globals.fill.M67" ) + + ( FillerGridAlignmentInUserUnits 9.6 ) + ( FillerLPP ( list "y0" "drawing" ) ) + + ( FillerGridODPolyBigCellName "globals.fill.ODPOLY_big" ) + ( FillerGridODPolySmallCellName "globals.fill.ODPOLY_small" ) ) + + (let ( + ( TargetLibName + ( LibCreateTempLibraryFromCellView + CellView + ( strcat "FILL_" Type ) + TempDir ) ) ) + + (cond ( + ( equal Type "grid" ) + ( FillerGridMakeFillerGrid + CellView + TargetLibName + PDKPackageRoot + TempDir + FillerGridLib + FillerGridPolyCellName + FillerGridM1CellName + FillerGridM2CellName + FillerGridM3CellName + FillerGridM4CellName + FillerGridM5CellName + FillerGridM6CellName + FillerGridM7CellName + FillerGridContCellName + FillerGridVia12CellName + FillerGridVia23CellName + FillerGridVia34CellName + FillerGridVia45CellName + FillerGridVia56CellName + FillerGridVia67CellName + FillerGridViewName + FillerGridAlignmentInUserUnits + FillerLPP + ?LeaveMess LeaveMess + ?M2M7 Layers + ?ODM2 ( not Layers ) ) + ) + ( + ( equal Type "cells" ) + ( FillerMakeFillerCells + CellView + TargetLibName + PDKPackageRoot + TempDir + FillerGridLib + FillerGridODPolyBigCellName + FillerGridODPolySmallCellName + FillerLPP + ?LeaveMess LeaveMess + ?M2M7 Layers + ?ODM1 ( not Layers ) ) ) + ( + ( equal Type "shapes" ) + ( FillerMakeFillerShapes + CellView + TargetLibName + PDKPackageRoot + TempDir + ?LeaveMess LeaveMess + ?M2M3 Layers + ?M4M7 ( not Layers ) ) ) + ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.txt b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.txt new file mode 100644 index 0000000000..3da0005242 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/filler/filler.txt @@ -0,0 +1,118 @@ +**************** +Fill Overview +**************** + +See and //. + +There are 3 types of fill. +All of them place fill only in areas marked with ( "y9" "drawing" ), which we call the +fill boundary. + +In the order they are typically run. +* Fill grid + This is placed everywhere where there is non-power-grid metal. + Powergrid is on M3-M7. M3-M5 have a 4.8x9.6 pitch. M6-M8 have a 9.6x9.6 pitch. + Powergrid is signaled by the existence of yN layers + (e.g ("y3" "drawing" ) means that there is M3 powergrid here. + Care must be taken not to draw these layers anywhere but the STANDARD powergrid! + There was a case where a M7_wide powergrid cell had y7 drawing where it shouldn't + and this caused shorts. + + The cells are placed per metal layer. + (e.g. globals.fill.M3 is the fill for metal 3) + We also place via cells between layers, that avoids non-power grid metal on + the 2 layers it connects. + (e.g. globals.fill.VIA34 has vias that connects the M3 to M4 powergrid. + The via cells also have redundant metal in them so we dont have any floating vias. + + Each fill cell is the same size as its metal's powergrid pitch. + (e.g. globals.fill.M3 is 4.8x9.6) + + + The cells are placed with assura using generateRectangle() which just tiles them all in + the fill boundary, and then gets rid of rectangles that are within 1.2u of non-powergrid + shapes. Assura returns with a bunch of rectangles which are postprocessed into fillergrid cells. + + There is another post-processing stage called mosaicification, which converts these instances + into mosaics. To run this, Do the following: + * From layout: ( dbWriteSkill cellview "file1" "w" "5.0" ) + * Run fulcrum mosaicify file1 file2 + * From layout, open an empty cellview where you want the mosaics, nad ( load "file2" ) + If you have multiple cellviews and you want to merge all their mosaics, just cat + together the results of dbWriteSkill. + +* Fill cells + This is placed 0.6u away from existing metal. It just uses the standard assura + generateFill(). The fill is non-optimal but is space-efficient because it consists + of mosaics. + + +* Fill shapes + This is placed 0.6u away from existing metal. It is more optimal than filler cells + but it consists of flat shapes. Care is taken to avoid spacing <=0.4, area<=1.44, + width<=0.6, and vertices>4. Particularly useful for place and route cells. + + + +**************** +How to run fill +**************** + +Currently, the interface is through the CIW in cadence. For chip level stuff you'll +probably want to start cadence with +CDS_AUTO_64BIT=ALL /usr/local/cadence/scripts/cadence.latest.run layout + + +Just run ( Fill cellview ?Type type ?Layers layers ) + +cellview is a cellview dbId +type is one of ("grid" "cells" "shapes") +layers is t or nil and it means the following for the different types + +grid/nil : od through m2 +grid/t : via23 through m7, dont export gates/stacks + +cells/nil : od through m1 +cells/t : m2 through m7, don't export gates/stacks + +shapes/t : m2 though m3, don't export gates/stacks +shapes/nil : m4 through m7, don't export gates/stacks + +First the CIW will tell you the name of the library to look for the result... +something like FILL_grid0 +The library will be in your cds.config TEMP directory, and the assura logs +will be in some AssuraRuXXXXX directory inside your TEMP directory. + + +Then it will probably complain about some libraries or something(don't worry), +and then it will say: + +"running assura" + +Then it will run for a while (3-4 hours or so for the chip, depending on the type of run) +and come back with: + +"done with assura" + +And you're good to go. + + + +************************ +Current risk assessment +************************ + +* I have LVS'd the chip with fillergrid and it passed. + +* The filler cells are low risk, and we checked that they didn't short any metal shapes. + I checked to see if GND/Vdd were shorted with these cells added using GNDVddShortCheck.rul + (in the pdk/drc directory), and they did not. I only went down to M2, though. + +* The filler shapes are relatively high risk still. They were shorting nets in a truly + mysterious way. I made some changes and ran the fill again and indeed removed problems of + that type, but I've learned to make no guarantees. + I checked to see if GND/Vdd were shorted with m2m3 shapes + (these were the layers that the short was on) using GNDVddShortCheck.rul, and they did not. + I only went down to M2, though. + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/align.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/align.il new file mode 100644 index 0000000000..536d46e8ac --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/align.il @@ -0,0 +1,474 @@ + + +(defun SetXAlignmentProp ( cv val ) + (dbReplaceProp cv "XAlignGrid" "float" val) +) + +(defun GetXAlignmentProp ( cv ) + (let (align) + align = (dbGetPropByName cv "XAlignGrid")->value + ) +) + +(defun SetYAlignmentProp ( cv val ) + (dbReplaceProp cv "YAlignGrid" "float" val) +) + +(defun GetYAlignmentProp ( cv ) + (let (align) + align = (dbGetPropByName cv "YAlignGrid")->value + ) +) + + +(defun SetAlignmentUI () + (let (cv valx valy xalign maxalign yalign use_subcell str + layout prelayout floorplan layout_exists prelayout_exists floorplan_exists noedit edit) + cv = (geGetWindowCellView) + valx = UISetAlignment_Form->UISetAlignment_Form_XAlign->value + valy = UISetAlignment_Form->UISetAlignment_Form_YAlign->value + xalign = valx + yalign = valy + ; I'm intentionally not doing anything smart with yalign because we shouldn't ever + ; be doing funky alignments in that axis + + (if cv->viewName=="layout_pg" then + hiDisplayAppDBox( + ?name 'SetAlignmentErrorDialogBox + ?dboxText "Don't do this in a layout_pg view." + ?dboxBanner "Wrong view" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'Close + ) + else + + + ; check for additonal views to be updated + floorplan_exists = (dbOpenCellViewByType cv->libName cv->cellName "floorplan" nil "r") + prelayout_exists = (dbOpenCellViewByType cv->libName cv->cellName "prelayout" nil "r") + layout_exists = (dbOpenCellViewByType cv->libName cv->cellName "layout" nil "r") + + noedit = nil + (when floorplan_exists + floorplan = (nrOpenCellViewWritable cv->libName cv->cellName "floorplan") + (when !floorplan + noedit = t + (printf "Couldn't open floorplan view for edit.\n") + floorplan = (nrOpenCellViewReadable cv->libName cv->cellName "floorplan") + ) + ) + (when prelayout_exists + prelayout = (nrOpenCellViewWritable cv->libName cv->cellName "prelayout") + (when !prelayout + noedit = t + (printf "Couldn't open prelayout view for edit.\n") + prelayout = (nrOpenCellViewReadable cv->libName cv->cellName "prelayout") + ) + ) + (when layout_exists + layout = (nrOpenCellViewWritable cv->libName cv->cellName "layout") + (when !layout + noedit = t + (printf "Couldn't open layout view for edit.\n") + layout = (nrOpenCellViewReadable cv->libName cv->cellName "layout") + ) + ) + (when noedit + edit = (hiDisplayAppDBox + ?name 'AlignEditDbox + ?dboxBanner "Warning" + ?dboxText "One or more views could not be edited. P4 Edit and modify them?" + ?dialogType hicQuestionDialog + ?buttonLayout 'YesNo + ?defaultButton 1 + ) + ) + (when edit + (when floorplan_exists + floorplan = (CDSP4CellView floorplan "edit")) + (when prelayout_exists + prelayout = (CDSP4CellView prelayout "edit")) + (when layout_exists + layout = (CDSP4CellView layout "edit")) + ) + + ;check for larger grid in subcells + (SetXAlignmentProp cv 0) + maxalign = (GetMaxSubcellXAlignment cv) + (when valxinstances + (when !(IsInList inst->cellName uniqueNames) && inst->libName!=TechLibName + uniqueNames = (cons inst->cellName uniqueNames ) + uniqueInstances = (cons inst uniqueInstances ) + ) + ) + (foreach inst uniqueInstances + cellv = (nrOpenCellViewReadable inst->libName inst->cellName inst->viewName) + (when cellv + align = (max align (GetMaxSubcellXAlignment cellv)) + ) + ) + align + ) +) + + +(defun SetCellAlignment (cv @key (xalign MfgGrid) (yalign GridPitch) ) + (let (maxalign current_xalign) + (if (nrIsCellViewWritable cv) then + (SetYAlignmentProp cv yalign) + current_xalign = (GetXAlignmentProp cv) + (when !current_xalign + current_xalign = MfgGrid + ) + maxalign = (max xalign (GetMaxSubcellXAlignment cv) current_xalign) + (SetXAlignmentProp cv maxalign) + (dbSave cv) + else + (printf "Couldn't open cell %s for edit.\n" cv->cellName) + ) + ) +) + + +(defun CheckRoutedAlignment (cv @key (dialog nil)) + (let (uniqueInstances uniqueNames cellv routed (location nil) (locations nil) + (misalignment nil) (inst_misaligned nil) (sub_misaligned nil) instances) + uniqueInstances = nil + uniqueNames = nil + instances = (setof inst cv->instances inst->libName!=TechLibName) ; exclude vias + (foreach inst instances + inst_misaligned = !(IsInstAligned inst) + misalignment = misalignment || inst_misaligned + (when inst_misaligned (printf " in cell %s\n" cv->cellName)) + (when inst->libName!=TechLibName && inst->orient + (when !(IsInList inst->orient LegalRotations) + misalignment = t + (printf "Instance %s in cell %s has illegal orientation.\n" inst->name cv->cellName) + ) + ) + + location = (list inst->xy inst->cellName inst->orient) + (when (IsInList location locations) + misalignment = t + (printf "Duplicate instance placement of cell %s \n in cell %s at (%.3f %.3f)\n" + inst->cellName inst->cellView->cellName (car inst->xy) (cadr inst->xy)) + ) + locations = (cons location locations) + + (when !(IsInList inst->cellName uniqueNames) && inst->libName!=TechLibName && !(IsWiringCell inst) + uniqueNames = (cons inst->cellName uniqueNames ) + uniqueInstances = (cons inst uniqueInstances ) + ) + ) + (foreach inst uniqueInstances + routed = (nrIsRoutedCell inst->libName inst->cellName inst->viewName) + (when !routed && !(IsGlobalsCell inst) + cellv = (nrOpenCellViewReadable inst->libName inst->cellName inst->viewName) + sub_misaligned = (CheckRoutedAlignment cellv) + ) + misalignment = misalignment || sub_misaligned + ) + + (when dialog + (if misalignment then + str = (sprintf nil "One or more cells are misaligned. Check CIW.") + else + str = (sprintf nil "All cells are correctly aligned.") + ) + (hiDisplayAppDBox + ?name 'checkAlignmentDialogBox + ?dboxText str + ?dboxBanner "Alignment Status" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'Close + ) + ) + misalignment + ) +) + +(defun fixXAlignment ( @key (cv nil)) + (let (xalign instcv inst misaligned inst_moved) + (when !cv + cv = (geGetWindowCellView) + ) + move=0.0 + inst_moved=0 + instances=sort( cv~>instances + lambda((cell1 cell2) leftEdge(cell1~>bBox)bBox))) + foreach( inst instances + new_move=AlignInstX( cv inst move ) + if( new_move>0.0 then inst_moved=inst_moved+1 ) + if( new_move > move then + printf("Instance \"%s\" (%s) is moved by %.3f to snap to X alignment.\n" inst~>name inst~>cellName new_move) + move=new_move + ) + ) + if( move == 0.0 then + printf( "No instance moved. \n" ) + else + printf( "\nTotal %d instances moved.\n" inst_moved ) + ) + ) +) + + +(defun CheckFlatAlignment ( @key (cv nil) (dialog nil)) + (let (xalign instcv instx misaligned) + (when !cv + cv = (geGetWindowCellView) + ) + + misaligned = nil + (foreach inst cv->instances + (when !(IsInstAligned inst) + misaligned = (cons inst misaligned) + ) + ) + (if misaligned then + str = (sprintf nil "One or more cells are misaligned. Check CIW.") + else + str = (sprintf nil "All cells are correctly aligned.") + ) + (if dialog then + (hiDisplayAppDBox + ?name 'checkAlignmentDialogBox + ?dboxText str + ?dboxBanner "Alignment Status" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'Close + ) + else + (printf "%s\n" str) + ) + ) +) + +(defun IsInstAligned (inst) + (let (instcv xalign yalign instx insty aligned) + aligned = t + (unless inst->libName==TechLibName + instcv = (nrOpenCellViewReadable inst->libName inst->cellName inst->viewName) + xalign = (GetXAlignmentProp instcv) + (when !xalign + xalign = MfgGrid + ) + yalign = (GetYAlignmentProp instcv) + (when !yalign + yalign = GridPitch + ) + instx = (car inst->xy) || (car inst->mosaic->xy) + insty = (cadr inst->xy) || (cadr inst->mosaic->xy) + (when !(IsAligned instx xalign) + aligned = nil + (printf "Instance \"%s\" of type %s is misaligned in X\n" inst->name inst->cellName ) + ) + (when !(IsAligned insty yalign) + aligned = nil + (printf "Instance \"%s\" of type %s is misaligned in Y\n" inst->name inst->cellName ) + ) + ) + aligned + ) +) + +(defun AlignInstX (cv inst moveX) + (let (instcv xalign instx instx_new ) + instcv = (nrOpenCellViewReadable inst->libName inst->cellName inst->viewName) + xalign = (GetXAlignmentProp instcv) + (when !xalign + xalign = MfgGrid + ) + instx = round( 1000* ((car inst->xy) || (car inst->mosaic->xy)))/1000.0 + instx_new = ceiling( round( 1000 * (instx + moveX))/1000.0 / xalign) *xalign + moveX = round( 1000* (instx_new - instx))/1000.0 + if( moveX > 0.0 then dbMoveFig( inst cv list(moveX:0 "R0" 1.0))) + moveX + ) +) + +(defun IsAligned (x align) + (let (aligned) + (if (modulo (floor (round 1000*x)) (floor (round 1000*align)))==0 then + aligned = t + else + aligned = nil + ) + ) +) + +(defun CopyAlignmentProps (cv1 cv2) + (if (GetXAlignmentProp cv1) then + (SetXAlignmentProp cv2 (GetXAlignmentProp cv1)) + else + (SetXAlignmentProp cv2 MfgGrid) + ) + (if (GetYAlignmentProp cv1) then + (SetYAlignmentProp cv2 (GetYAlignmentProp cv1)) + else + (SetYAlignmentProp cv2 MfgGrid) + ) +) + +(defun CreateInstWithAlignmentProps (cv master name point orient) + (let (newinst cellv xalign yalign) + newinst = (dbCreateInst cv master name point orient) + cellv = (nrOpenCellViewReadable newinst->libName newinst->cellName newinst->viewName) + xalign = (GetXAlignmentProp cellv) + yalign = (GetYAlignmentProp cellv) + (when !xalign + xalign = MfgGrid) + (when !yalign + yalign = GridPitch) + (SetXAlignmentProp newinst xalign) + (SetYAlignmentProp newinst yalign) + ) +) + +(defun GetMaxXAlignmentOfSet (set) + (let (maxalign cellv align) + maxalign = MfgGrid + (foreach inst set + cellv = (nrOpenCellViewReadable inst->libName inst->cellName inst->viewName) + align = (GetXAlignmentProp cellv) + (when !align + align = MfgGrid + ) + maxalign = (max maxalign align) + ) + maxalign + ) +) + +(defun GetMaxYAlignmentOfSet (set) + (let (maxalign cellv align) + maxalign = MfgGrid + (foreach inst set + cellv = (nrOpenCellViewReadable inst->libName inst->cellName inst->viewName) + align = (GetYAlignmentProp cellv) + (when !align + align = MfgGrid + ) + maxalign = (max maxalign align) + ) + maxalign + ) +) + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; functions interfacing to the virtuoso alignment dialog + +(defun AlignSelectedH () + (let (tempdir filename file) + tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + filename = (sprintf nil "%s/align.replay" tempdir) + file = (outfile filename) + + (fprintf file "leHiAlign()\n") + (fprintf file "leAlignSelSetForm->sortObjOption->value = \"Instance Name\"\n") + (fprintf file "leAlignSelSetForm->direction->value = \"Horizontal\"\n") + (fprintf file "leAlignSelSetForm->alignSepOption->value = \"Component Space\"\n") + (fprintf file "leAlignSelSetForm->alignObjOption->value = \"Component Origin\"\n") + (fprintf file "leAlignSelSetForm->alignSepLabel->value = \"Spacings\"\n") + (fprintf file "leAlignSelSetForm->alignSeparation->value = \"0\"\n") + (fprintf file "hiFormDone(leAlignSelSetForm)\n") + (fprintf file "_leAlignSSNewRefCB\n") + + (close file) + + (hiReplayFile filename) + ) +) + +(defun AlignSelectedV () + (let (tempdir filename file) + tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + filename = (sprintf nil "%s/align.replay" tempdir) + file = (outfile filename) + + (fprintf file "leHiAlign()\n") + (fprintf file "leAlignSelSetForm->sortObjOption->value = \"Instance Name\"\n") + (fprintf file "leAlignSelSetForm->direction->value = \"Vertical\"\n") + (fprintf file "leAlignSelSetForm->alignSepOption->value = \"Component Space\"\n") + (fprintf file "leAlignSelSetForm->alignObjOption->value = \"Component Origin\"\n") + (fprintf file "leAlignSelSetForm->alignSepLabel->value = \"Spacings\"\n") + (fprintf file "leAlignSelSetForm->alignSeparation->value = \"0\"\n") + (fprintf file "hiFormDone(leAlignSelSetForm)\n") + (fprintf file "_leAlignSSNewRefCB\n") + + (close file) + + (hiReplayFile filename) + ) +) + + +(defun OpenAlignForm () + (let (tempdir filename file) + tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + filename = (sprintf nil "%s/align.replay" tempdir) + file = (outfile filename) + + (fprintf file "leHiAlign()\n") + (fprintf file "leAlignSelSetForm->sortObjOption->value = \"Instance Name\"\n") + (fprintf file "leAlignSelSetForm->direction->value = \"Horizontal\"\n") + (fprintf file "leAlignSelSetForm->alignSepOption->value = \"Component Space\"\n") + (fprintf file "leAlignSelSetForm->alignObjOption->value = \"Component Origin\"\n") + (fprintf file "leAlignSelSetForm->alignSepLabel->value = \"Spacings\"\n") + (fprintf file "leAlignSelSetForm->alignSeparation->value = \"0\"\n") + + (close file) + + (hiReplayFile filename) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/anchor.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/anchor.il new file mode 100644 index 0000000000..571f3ee24d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/anchor.il @@ -0,0 +1,115 @@ +(defun AnchorInstance (inst) + (when inst + (unless inst->libName==TechLibName + (dbReplaceProp inst "Anchored" "boolean" t) + ) + ) +) + +(defun UnAnchorInstance (inst) + (when inst + (unless inst->libName==TechLibName + (dbReplaceProp inst "Anchored" "boolean" nil) + ) + ) +) + +(defun IsInstanceAnchored (inst) + (let (anchored) + anchored = nil + (when inst + (if (dbGetPropByName inst "Anchored")->value=="TRUE" then + anchored=t + else + anchored=nil + ) + ) + anchored + ) +) + +(defun ToggleInstanceAnchor (inst) + (if (IsInstanceAnchored inst) then + (UnAnchorInstance inst) + else + (AnchorInstance inst) + ) +) + +(defun AnchorSelectedInstances () + (let (set) + set=(geGetSelectedSet) + (foreach item set + (when item->objType=="inst" + (AnchorInstance item) + ) + ) + ) +) + +(defun UnAnchorSelectedInstances () + (let (set) + set=(geGetSelectedSet) + (foreach item set + (when item->objType=="inst" + (UnAnchorInstance item) + ) + ) + ) +) + + + +;additional properties to protect from deletion + +(defun ProtectInstance (inst) + (when inst + (unless inst->libName==TechLibName + (dbReplaceProp inst "Protected" "boolean" t) + ) + ) +) + +(defun UnProtectInstance (inst) + (when inst + (unless inst->libName==TechLibName + (dbReplaceProp inst "Protected" "boolean" nil) + ) + ) +) + +(defun IsInstanceProtected (inst) + (let (protected) + protected = nil + (when inst + (if (dbGetPropByName inst "Protected")->value=="TRUE" then + protected=t + else + protected=nil + ) + ) + protected + ) +) + +(defun ProtectSelectedInstances () + (let (set) + set=(geGetSelectedSet) + (foreach item set + (when item->objType=="inst" + (ProtectInstance item) + ) + ) + ) +) + +(defun UnProtectSelectedInstances () + (let (set) + set=(geGetSelectedSet) + (foreach item set + (when item->objType=="inst" + (UnProtectInstance item) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/floorplanTemplating.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/floorplanTemplating.il new file mode 100644 index 0000000000..65fcf097bf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/floorplanTemplating.il @@ -0,0 +1,139 @@ +; Copyright 2008 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( flFloorplanCopy ( dstCellView srcCellName + @key + (srcLibName "") + (srcViewName "") + (Recursive nil) + ) + prog((srcCellView dstInst srcInst unfoundInstances processedCells x subDstCellView subSrcCellView xalign yalign) + if(srcLibName == "" then srcLibName=car( NameParseCellName( srcCellName ))) + if(srcViewName == "" then srcViewName="floorplan") + srcCellView=nrOpenCellViewReadable( srcLibName srcCellName srcViewName) + if( srcCellView == nil then + printf("Error: %s(%s) %s view not found. \n" srcCellName srcLibName srcViewName) + return(0) + ) + if( dstCellView==srcCellView then return(t)) + unfoundInstances=nil + processedCells=nil + x=0 + foreach( dstInst dstCellView~>instances + srcInst=dbFindAnyInstByName( srcCellView dstInst~>name ) + if( srcInst then + dstInst~>xy=srcInst~>xy + dstInst~>orient=srcInst~>orient + if( car(dstInst~>xy)>x then x= car(dstInst~>xy)) + if( !member( srcInst~>cellName processedCells) then + processedCells=cons( srcInst~>cellName processedCells) + if( dstInst~>master~>instances then + if( Recursive then + subDstCellView=nrOpenCellViewWritable( dstInst~>libName dstInst~>cellName dstInst~>viewName) + if( subDstCellView then + flFloorplanCopy( subDstCellView srcInst~>cellName + ?srcLibName srcInst~>libName + ?srcViewName srcInst~>viewName + ?Recursive Recursive) + + else + printf("Error: Can not open %s(%s) %s for write. \n" dstInst~>libName dstInst~>cellName dstInst~>viewName) + ) + ) + ) + ) + else + unfoundInstances=cons( dstInst unfoundInstances ) + ) + ) + xalign=(dbGetPropByName srcCellView "XAlignGrid")->value + yalign=(dbGetPropByName srcCellView "YAlignGrid")->value + if( xalign then (dbReplaceProp dstCellView "XAlignGrid" "float" xalign)) + if( yalign then (dbReplaceProp dstCellView "YAlignGrid" "float" yalign)) + return(t) + ) +) + +defun( ssFloorplanTemplating ( srcLibName srcCellName srcViewName + dstLibName dstCellName dstViewname ) +; this is flFloorplanTemplateing interface for super size package + let((dstCellView) + dstCellView=nrOpenCellViewWritable( dstLibName dstCellName dstViewname ) + if( dstCellView == nil then + printf("Error: cellview %s(%s) %s not writable.\n" dstCellName dstLibName dstViewname) + else + flFloorplanTemplating( dstCellView srcCellName + ?srcLibName srcLibName + ?srcViewName srcViewName ) + ) + ) +) + + +defun( flFloorplanTemplating ( dstCellView srcCellName + @key + (srcLibName "") + (srcViewName "") + (ResolveOverlap t) + (SnapXGrid 0.0) + (SnapXInst nil) + (Recursive nil) + (DeletePins nil) + (SkipCellList nil) + ) + prog((TEMP projectName SkipCellList xtotal returnCode) + returnCode=flFloorplanCopy( dstCellView srcCellName + ?srcLibName srcLibName + ?srcViewName srcViewName + ?Recursive Recursive + ) + if( returnCode==0 then return(0)) + if( DeletePins then + foreach( shape dstCellView~>shapes + if( shape~>layerName!="prBoundary" then + dbDeleteObject( shape ) + ) + ) + ) + if( ResolveOverlap==nil then return(t)) + TEMP=ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + createDir( sprintf( nil "%s/glpsol/" TEMP)) + projectName=dstCellView~>cellName + xtotal=flResolveOverlap( dstCellView + ?SkipCellList SkipCellList + ?LPMacroFileName sprintf( nil "%s/glpsol/%s.lpt" TEMP projectName) + ?LPOutputFileName sprintf( nil "%s/glpsol/%s.out" TEMP projectName) + ?LPLogFileName sprintf( nil "%s/glpsol/%s.log" TEMP projectName) + ?LPmemoFileName sprintf( nil "%s/glpsol/%s.memo" TEMP projectName) + ?SaveFileName sprintf( nil "%s/glpsol/%s.autosave" TEMP projectName) + ?BlockLayer list("LOGO" "drawing") + ?SaveCellView t + ?AbutCellKeepOrder t + ?SingleHierarchy nil + ?SnapXGrid SnapXGrid + ) + if( xtotal!=0 then + flResolveOverlap( dstCellView + ?SkipCellList SkipCellList + ?LPMacroFileName sprintf( nil "%s/glpsol/%s.lpt" TEMP projectName) + ?LPOutputFileName sprintf( nil "%s/glpsol/%s.out" TEMP projectName) + ?LPLogFileName sprintf( nil "%s/glpsol/%s.log" TEMP projectName) + ?LPmemoFileName sprintf( nil "%s/glpsol/%s.memo" TEMP projectName) + ?SaveFileName sprintf( nil "%s/glpsol/%s.autosave" TEMP projectName) + ?BlockLayer list("LOGO" "drawing") + ?SaveCellView t + ?AbutCellKeepOrder t + ?SingleHierarchy nil + ?xtotal xtotal + ?Mode 1 + ?SnapXGrid SnapXGrid + ) + ) + if( SnapXInst then + fixXAlignment( ?cv dstCellView ) + ) + return(t) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/getcellmappings.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/getcellmappings.il new file mode 100644 index 0000000000..a5cdf61ca3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/getcellmappings.il @@ -0,0 +1,96 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun GetCellNameMappingsGetBiDirectionalCellNameMappings ( NewRootCellView + BottomUpListOfNewRootCellDescendants + OldRootCellView + TargetOldToNewTable + TargetNewToOldTable + GetOldCellViewFunc + GetOldCellViewFuncParams ) + (let ( + ( TopDownListOfNewCells ( reverse BottomUpListOfNewRootCellDescendants ) ) ) + ( setarray + TargetNewToOldTable + ( getq NewRootCellView cellName ) + OldRootCellView ) + ( setarray + TargetOldToNewTable + ( getq OldRootCellView cellName ) + NewRootCellView ) + ( foreach + Cell + TopDownListOfNewCells + (let ( + ( OldCellView ( arrayref + TargetNewToOldTable + ( getq Cell cellName ) ) ) ) + (when OldCellView + (let ( + ( OldInstances ( getq OldCellView instances ) ) ) + ( foreach + Instance + ( getq Cell instances ) + (unless ( arrayref TargetNewToOldTable ( getq Instance cellName ) ) + (let ( + ( OldInstance ( ListFindElement + OldInstances + (lambda + ( OldInstance Instance ) + (let ( + ( MungedOldInstanceName ( MungeInstanceName + ( getq OldInstance name ) ) ) ) + + ( equal + MungedOldInstanceName + ( getq Instance name ) ) ) ) + ( list Instance ) ) ) ) + (when OldInstance + (let ( + ( OldMasterCellView ( apply + GetOldCellViewFunc + ( cons + ( getq OldInstance libName ) + ( cons + ( getq OldInstance cellName ) + ( cons + ( getq OldInstance viewName ) + ( cons + ( getq Instance cellName ) + GetOldCellViewFuncParams ) ) ) ) ) ) ) + (when OldMasterCellView + ( setarray + TargetOldToNewTable + ( getq OldInstance cellName ) + ( getq Instance master ) ) + ( setarray + TargetNewToOldTable + ( getq Instance cellName ) + OldMasterCellView ) ) ) ) ) ) ) ) ) ) ) ) + t ) + +(defun GetCellNameMappings ( NewRootCellView LibsToIgnore OldRootCellView TargetTable ) + ( GetCellNameMappingsGetBiDirectionalCellNameMappings + NewRootCellView + ( HierarchyGetCellDescendants + RootConnectivityCellView + LibsToIgnore + (lambda ( CellView ) + nil ) + nil ) + OldRootCellView + ( makeTable "foo" nil ) + TargetTable + (lambda + ( OldLibName OldCellName OldViewName NewCellName ) + (when ( ddGetObj OldLibNAme OldCellName OldViewName ) + ( printf "%L=%L\n" NewCellName OldCellName ) + ( dbOpenCellViewByType + OldLibName + OldCellName + OldViewName + nil + "r" ) ) ) + nil ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/importfloorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/importfloorplan.il new file mode 100644 index 0000000000..55b07ae84f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/import/importfloorplan.il @@ -0,0 +1,495 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun ImportFloorPlanTablifyInstances ( Instances TargetTable ) + ( foreach + Instance + Instances + ( setarray + TargetTable + ( MungeInstanceName ( getq Instance name ) ) + Instance ) ) ) +(defun ImportFloorPlanTablifyNets ( CellView TargetTable ) + ( foreach + Net + ( getq CellView nets ) + ( setarray TargetTable + ( getq Net name ) + Net ) ) ) +(defun ImportFloorPlanTablifyTerminals ( CellView TargetTable ) + ( foreach + Term + ( getq CellView terminals ) + ( setarray TargetTable + ( getq Term name ) + Term ) ) ) + +(defun ImportFloorPlanTablifyInstanceTerms ( Instance TargetTable ) + ( foreach + InstTerm + ( getq Instance conns ) + ( setarray TargetTable + ( getq ( getq InstTerm term ) name ) + InstTerm + ) ) ) + +(defun ImportFloorPlanUpdateCellInstances ( ConnectivityCell + ConnectivityInstancesTable + ConnectivityCellInstances + NewCell + NewCellInstancesTable + NewCellInstances + NewBoundaryLPP + DefCellWidth + DefCellHeight + OldCell + ScalingFactor ) + ( dbComputeBBox NewCell ) + (let ( + ( OldInstances (when OldCell ( getq OldCell instances ) ) ) + ( OldInstancesTable ( makeTable "baz" nil ) ) + ( ErrorStr nil ) + ( NewCellBBox ( getq NewCell bBox ) ) ) + ( ImportFloorPlanTablifyInstances OldInstances OldInstancesTable ) + (let ( + ( InstancesToDelete ( setof + NewInstance + NewCellInstances + ( null + ( arrayref ConnectivityInstancesTable ( getq NewInstance name ) ) ) ) ) + ( InstancesToCreate ( setof + ConnectivityInstance + ConnectivityCellInstances + ( null + ( arrayref NewCellInstancesTable ( getq ConnectivityInstance name ) ) ) ) ) + ( CurrX ( RectGetRight NewCellBBox ) ) ) + ( foreach + InstanceToDelete + InstancesToDelete + (let () + ( setarray NewCellInstanceTable ( getq InstanceToDelete name ) nil ) + ( dbDeleteObject + InstanceToDelete ) ) ) + + ( foreach + InstanceToCreate + InstancesToCreate + (unless ErrorStr + (let ( + ( NewMasterCell ( dbOpenCellViewByType + ( getq ( getq InstanceToCreate master ) lib ) + ( getq InstanceToCreate cellName ) + ( getq NewCell viewName ) nil "r" ) ) + ( OldInstance ( arrayref OldInstancesTable ( getq InstanceToCreate name ) ) ) ) + (if NewMasterCell + (if OldInstance + (let ( + ( ScaledXPos ( times ( car ( getq OldInstance xy ) ) ScalingFactor ) ) + ( ScaledYPos ( times ( car ( cdr ( getq OldInstance xy ) ) ) ScalingFactor ) ) ) + (let ( + ( NewInstance ( dbCreateInst + NewCell + NewMasterCell + ( getq InstanceToCreate name ) + ( list ScaledXPos ScaledYPos ) + ( getq OldInstance orient ) ) ) ) + ( setarray NewCellInstancesTable ( getq InstanceToCreate name ) NewInstance ) ) ) + (let ( + ( NewInstance ( dbCreateInst + NewCell + NewMasterCell + ( getq InstanceToCreate name ) + ( list 0 0 ) + "R0" ) ) ) + ( setarray NewCellInstancesTable ( getq InstanceToCreate name ) NewInstance ) + ( dbMoveFig + NewInstance + nil + ( list + ( list + ( difference + CurrX + ( RectGetLeft + ( getq NewInstance bBox ) ) ) + 0 ) + "R0" ) ) + ( setq CurrX ( plus CurrX ( RectGetWidth ( getq NewInstance bBox ) ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + ( strcat + "Unable to find \"%s\" \"%s\" \"%s\"" + " to create instance \"%s\" in \"%s\" \"%s\" \"%s\"." + ) + ( getq InstanceToCreate libName ) + ( getq InstanceToCreate cellName ) + ( getq NewCell viewName ) + ( getq InstanceToCreate name ) + ( getq NewCell libName ) + ( getq NewCell cellName ) + ( getq NewCell viewName ) ) ) ) ) ) ) ) + (when ( and + ( null ErrorStr ) + ( null ( getq NewCell instances ) ) + ( null ( getq NewCell shapes ) ) ) + (if OldCell + (let ( + ( OldCellBBox ( getq OldCell bBox ) ) ) + ( dbCreateRect + NewCell + NewBoundaryLPP + ( list + ( list + ( times ScalingFactor ( RectGetLeft OldCellBBox ) ) + ( times ScalingFactor ( RectGetBottom OldCellBBox ) ) ) + ( list + ( times ScalingFactor ( RectGetRight OldCellBBox ) ) + ( times ScalingFactor ( RectGetTop OldCellBBox ) ) ) ) ) ) + ( dbCreateRect + NewCell + NewBoundaryLPP + ( list + ( list 0 0 ) + ( list DefCellWidth DefCellHeight ) ) ) ) + ) + ErrorStr ) ) + + + + +(defun ImportFloorPlanCompareConnections ( InstTerm1 InstTerm2 ) + ( and + InstTerm1 + InstTerm2 + ( equal + ( getq ( getq InstTerm1 net ) name ) + ( getq ( getq InstTerm2 net ) name ) ) + ( equal + ( getq ( getq InstTerm1 term ) name ) + ( getq ( getq InstTerm2 term ) name ) ) ) ) + + +(defun ImportFloorPlanUpdateConnectivity ( ConnectivityCell + ConnectivityCellInstances + NewCell + NewCellInstancesTable ) + (let ( + ( ErrorStr nil ) ) + ( foreach + ConnectivityInstance + ConnectivityCellInstances + (unless ErrorStr + (let ( + ( NewInstance ( arrayref NewCellInstancesTable ( getq ConnectivityInstance name ) ) ) ) + (if ( not ( null NewInstance ) ) + (let ( + ( ConnectivityInstanceConnectionsTable ( makeTable "bar" nil ) ) + ( NewInstanceConnectionsTable ( makeTable "foo" nil ) ) ) + ( ImportFloorPlanTablifyInstanceTerms + ConnectivityInstance + ConnectivityInstanceConnectionsTable ) + ( ImportFloorPlanTablifyInstanceTerms + NewInstance + NewInstanceConnectionsTable ) + (let ( + ( ConnectionsToDelete ( setof + NewInstanceConnection + ( getq NewInstance conns ) + ( not + ( ImportFloorPlanCompareConnections + NewInstanceConnection + ( arrayref + ConnectivityInstanceConnectionsTable + ( getq + ( getq NewInstanceConnection term ) + name ) ) ) ) ) ) + + ( ConnectionsToCreate ( setof + ConnectivityInstanceConnection + ( getq ConnectivityInstance conns ) + ( not + ( ImportFloorPlanCompareConnections + ConnectivityInstanceConnection + ( arrayref + NewInstanceConnectionsTable + ( getq + ( getq ConnectivityInstanceConnection term ) + name ) ) ) ) ) ) ) + + ( foreach + ConnectionToDelete + ConnectionsToDelete + ( dbDeleteObject ConnectionToDelete ) ) + + ( foreach + ConnectionToCreate + ConnectionsToCreate + ( dbCreateConnByName + ( dbMakeNet NewCell ( getq ( getq ConnectionToCreate net ) name ) ) + NewInstance + ( getq ( getq ConnectionToCreate term ) name ) + ) ) ) ) + (let () + ( setq ErrorStr ( sprintf + nil + "Unable to find instance \"%s\" in \"%s\" \"%s\" \"%s" + ( getq ConnectivityInstance name ) + ( getq NewCell libName ) + ( getq NewCell cellName ) + ( getq NewCell viewName ) + ) ) + ( printf "\n%L\n" NewInstance ) + ( foreach + Key + NewCellInstancesTable + ( printf "%L %L\n" Key ( arrayref NewCellInstancesTable Key ) ) ) + ) ) ) ) ) + + (unless ErrorStr + (let ( + ( ConnectivityNetsTable ( makeTable "foo" nil ) ) + ( NewNetsTable ( makeTable "bar" nil ) ) + ) + ( ImportFloorPlanTablifyNets ConnectivityCell ConnectivityNetsTable ) + ( ImportFloorPlanTablifyNets NewCell NewNetsTable ) + + (let ( + ( NetsToDelete ( setof + NewNet + ( getq NewCell nets ) + ( null + ( arrayref ConnectivityNetsTable ( getq NewNet name ) ) ) ) ) + ( NetsToCreate ( setof + ConnectivityNet + ( getq ConnectivityCell nets ) + ( null + ( arrayref NewNetsTable ( getq ConnectivityNet name ) ) ) ) ) ) + ( foreach + NetToDelete + NetsToDelete + ( dbDeleteObject NetToDelete ) + ) + ( foreach + NetToCreate + NetsToCreate + ( dbCreateNet NewCell ( getq NetToCreate name ) ) ) ) ) ) + (unless ErrorStr + (let ( + ( ConnectivityTerminalsTable ( makeTable "bar" nil ) ) + ( NewTerminalsTable ( makeTable "foo" nil ) ) ) + ( ImportFloorPlanTablifyTerminals + ConnectivityCell + ConnectivityTerminalsTable ) + ( ImportFloorPlanTablifyTerminals + NewCell + NewTerminalsTable ) + + (let ( + ( TerminalsToDelete ( setof + NewTerminal + ( getq NewCell terminals ) + ( null + ( arrayref + ConnectivityTerminalsTable + ( getq NewTerminal name ) ) ) ) ) + ( TerminalsToCreate ( setof + ConnectivityTerminal + ( getq ConnectivityCell terminals ) + ( null + ( arrayref + NewTerminalsTable + ( getq ConnectivityTerminal name ) ) ) ) ) + ) + ( foreach + TerminalToDelete + TerminalsToDelete + ( dbDeleteObject TerminalToDelete ) ) + + ( foreach + TerminalToCreate + TerminalsToCreate + ( dbCreateTerm + ( dbMakeNet NewCell ( getq ( getq TerminalToCreate net ) name ) ) + ( getq TerminalToCreate name ) + ( getq TerminalToCreate direction ) ) ) ) ) ) + ErrorStr + ) ) + +(defun ImportFloorPlanUpdateCell ( ConnectivityCell + LibsToIgnore + CellsToIgnore + NewCell + NewBoundaryLPP + DefCellWidth + DefCellHeight + OldCell + ScalingFactor ) + (let ( + ( ErrorStr nil ) + ( NewCellInstances ( UpdateNetlistFilterInstances + NewCell + LibsToIgnore + CellsToIgnore ) ) + ( NewCellInstanceTable ( makeTable "foo" nil ) ) + ( ConnectivityInstances ( UpdateNetlistFilterInstances + ConnectivityCell + LibsToIgnore + CellsToIgnore ) ) + ( ConnectivityInstancesTable ( makeTable "bar" nil ) ) ) + + ( ImportFloorPlanTablifyInstances NewCellInstances NewCellInstanceTable ) + ( ImportFloorPlanTablifyInstances ConnectivityInstances ConnectivityInstancesTable ) + (let ( + ( ShouldDoCell ( or + ( equal ( getq NewCell mode ) "a" ) + ( equal ( getq NewCell mode ) "w" ) + ( dbReopen NewCell "a" ) ) ) ) + (if ShouldDoCell + (let () + (unless ErrorStr + ( setq + ErrorStr + ( ImportFloorPlanUpdateCellInstances + ConnectivityCell + ConnectivityInstancesTable + ConnectivityInstances + NewCell + NewCellInstanceTable + NewCellInstances + NewBoundaryLPP + DefCellWidth + DefCellHeight + OldCell + ScalingFactor ) ) ) + (unless ErrorStr + ( setq + ErrorStr + ( ImportFloorPlanUpdateConnectivity + ConnectivityCell + ConnectivityInstances + NewCell + NewCellInstanceTable ) ) ) + (unless ErrorStr + ( dbComputeBBox NewCell ) + ( dbSave NewCell ) + ( dbPurge NewCell ) ) ) + ( printf + "Could not open %s %s %s for writing, skipping.\n" + ( getq NewCell libName ) + ( getq NewCell cellName ) + ( getq NewCell viewName ) ) ) ) + ErrorStr ) ) + +(defun ImportFloorPlan ( RootConnectivityCellView + LibsToIgnore + CellsToIgnore + ResultViewName + ResultBoundaryLPP + DefCellWidth + DefCellHeight + CellMappingTable + ScalingFactor ) + (let ( + ( BottomUpListOfCells ( HierarchyGetAllCellsInTree + RootConnectivityCellView + LibsToIgnore ) ) + ( ErrorStr nil ) ) + ( foreach + ConnectivityCell + BottomUpListOfCells + (unless ErrorStr + (let ( + ( OldCell ( arrayref CellMappingTable ( getq ConnectivityCell cellName ) ) ) + ( NewCellDDObj ( ddGetObj + ( getq ConnectivityCell libName ) + ( getq ConnectivityCell cellName ) + ResultViewName + "pc.db" + nil + "r" ) ) ) + (if ( or ( null NewCellDDObj ) ( ddIsObjReadable NewCellDDObj ) ) + (when ( or ( null NewCellDDObj ) ( ddIsObjWritable NewCellDDObj ) ) + (let ( + ( NewCell ( dbOpenCellViewByType + ( getq ConnectivityCell lib ) + ( getq ConnectivityCell cellName ) + ResultViewName + "maskLayout" + (if NewCellDDObj + "a" + "w" ) ) ) ) + ( setq ErrorStr + ( ImportFloorPlanUpdateCell + ConnectivityCell + LibsToIgnore + CellsToIgnore + NewCell + ResultBoundaryLPP + DefCellWidth + DefCellHeight + OldCell + ScalingFactor ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "\"%s\" \"%s\" \"%s\" exists but is not readable." + ( getq ConnectivityCell lib ) + ( getq ConnectivityCell cellName ) + ResultViewName ) ) ) ) ) ) + ErrorStr ) ) + + +(defun ImportFloorPlanWrapper ( RootConnectivityLibName + RootConnectivityCellName + RootConnectivityViewName + LibsToIgnore + CellsToIgnore + ResultViewName + ResultBoundaryLPP + DefCellWidth + DefCellHeight + RootReferenceLibName + RootReferenceCellName + RootReferenceViewName + ScalingFactor ) + (let ( + ( RootConnectivityCellView ( dbOpenCellViewByType + RootConnectivityLibName + RootConnectivityCellName + RootConnectivityViewName + nil + "r" ) ) + ( RootReferenceCellView (when ( and + RootReferenceLibName + RootReferenceCellName + RootReferenceViewName + ) + ( dbOpenCellViewByType + RootReferenceLibName + RootReferenceCellName + RootReferenceViewName + nil + "r" ) ) ) + ( MappingTable ( makeTable "foo" nil ) ) ) + ( GetCellNameMappings + RootConnectivityCellView + LibsToIgnore + RootReferenceCellView + MappingTable ) + ( ImportFloorPlan + RootConnectivityCellView + LibsToIgnore + CellsToIgnore + ResultViewName + ResultBoundaryLPP + DefCellWidth + DefCellHeight + MappingTable + ScalingFactor ) ) ) + + +;( ImportFloorPlanWrapper "chip.tc3.alu" "chip.tc3.alu.ALU.0" "netlist" ( list "tsmc13lg" "gate" ) ( list ) "foo-floorplan" ( list "prBoundary" "drawing" ) 38.4 38.4 nil nil nil 1 ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/initFloorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/initFloorplan.il new file mode 100644 index 0000000000..e264ba78bd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/initFloorplan.il @@ -0,0 +1,202 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( flInitFloorplan ( libName cellName viewName + @key + ( Verbose nil ) + ( RegenerateFromCast nil ) + ( ScriptFileName "" ) + ( SnapXGrid 0.01 ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ( InstOrderList nil ) + ( TaskOption "" ) + ( x_offset 0.0 ) + ( y_offset 0.0 ) + ( SubcellsToCreate nil ) + ( DoNotMoveExistingInstances t ) + ( RunSyncToNetlist t ) + ) + prog( ( TargetDFIIPath NetlistDir DirectivesDir Command DirectiveTable InstOrderFile CellView p_in + width height x1 y1 x y prBoundBox thisInst inst line instances instName lineList instMaster scriptFilterCmd + unit command commandList ) + TargetDFIIPath = ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + NetlistDir = sprintf( nil "%s/ilnets" TargetDFIIPath) + DirectivesDir = sprintf( nil "%s/ildirectives" TargetDFIIPath ) + InstOrderFile = sprintf( nil "%s/%s.instOrder" TargetDFIIPath cellName) + CellView=nrOpenCellViewWritable( libName cellName viewName ) + scriptFilterCmd="" + unit=PowerGridPitch*4 + if( ScriptFileName != "" then + if( isFile(ScriptFileName) then + scriptFilterCmd=sprintf(nil "| %s %s" ScriptFileName cellName) + else + printf("Warning: Script File %s does not exist, skipped script filtering.\n" ScriptFileName) + ) + ) + if( CellView == nil then + printf("Error: Failed to open cellview %s (%s) for write.\n" cellName viewName) + return(0) + ) + if( InstOrderList == nil then + nrLoadRoutedDirective( CellView + ?Verbose Verbose + ?RegenerateFromCast RegenerateFromCast + ?MaxHeapSize MaxHeapSize + ) + + if( RunSyncToNetlist then + SyncNetlistGenFromSkillNetlistUsingPDKInfo( + CellView + NetlistDir + DirectivesDir + ?DoNotMoveExistingInstances DoNotMoveExistingInstances + ) + dbSave( CellView ) + ) + ) + return(CellView) + ) +) + +defun( flInitFloorplanWithInstOrderList ( libName cellName viewName + @key + ( Verbose nil ) + ( RegenerateFromCast nil ) + ( ScriptFileName "" ) + ( SnapXGrid 0.01 ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ( InstOrderList nil ) + ( TaskOption "" ) + ( x_offset 0.0 ) + ( y_offset 0.0 ) + ( SubcellsToCreate nil ) + ( DoNotMoveExistingInstances t ) + ( RunSyncToNetlist nil ) + ) + prog( ( TargetDFIIPath NetlistDir DirectivesDir Command DirectiveTable InstOrderFile CellView p_in + width height x1 y1 x y prBoundBox thisInst inst line instances instName lineList instMaster scriptFilterCmd + unit command commandList selectedSubcells thisObj) + TargetDFIIPath = ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + NetlistDir = sprintf( nil "%s/ilnets" TargetDFIIPath) + DirectivesDir = sprintf( nil "%s/ildirectives" TargetDFIIPath ) + InstOrderFile = sprintf( nil "%s/%s.instOrder" TargetDFIIPath cellName) + CellView=nrOpenCellViewWritable( libName cellName viewName ) + selectedSubcells=nil + foreach( thisObj geGetSelectedSet() + if( thisObj~>objType=="inst" then selectedSubcells=cons( thisObj~>name selectedSubcells )) + ) + printf( "Processing selected subcells: %L\n" selectedSubcells ) + scriptFilterCmd="" + unit=PowerGridPitch*4 + if( ScriptFileName != "" then + if( isFile(ScriptFileName) then + scriptFilterCmd=sprintf(nil "| %s %s" ScriptFileName cellName) + else + printf("Warning: Script File %s does not exist, skipped script filtering.\n" ScriptFileName) + ) + ) + if( CellView == nil then + printf("Error: Failed to open cellview %s (%s) for write.\n" cellName viewName) + return(0) + ) + if( InstOrderList == nil then + nrLoadRoutedDirective( CellView + ?Verbose Verbose + ?RegenerateFromCast RegenerateFromCast + ?MaxHeapSize MaxHeapSize + ) + Command = sprintf( nil + "%s/cast_query --cast-path=%s --cell=%s --task=initial_floorplan%s --no-header --no-recurse --translate=cadence --cadence-name --max-heap-size=%dM --64 %s > %s" + PackageGetBinRoot( ) + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + CellView~>cellName + TaskOption + MaxHeapSize + scriptFilterCmd + InstOrderFile + ) + printf( "%s\n" Command ) + shell( Command ) + p_in=infile(InstOrderFile) + InstOrderList=nil + while( gets( line p_in) + line=car(parseString( line "\n")) + InstOrderList=append( InstOrderList list( line )) + ) + close(p_in) + ) + x=x_offset +; println(InstOrderList) + printf("Processing %s creating subcells: " CellView~>cellName ) + println(SubcellsToCreate) + foreach( line InstOrderList + y=y_offset + nextX=x + lineList=parseString( line " " ) + while(lineList!= nil + instName=car(lineList) + lineList=cdr(lineList) + if( instName!=nil && !rexMatchp("^<.*>$" instName) then + if( DoNotMoveExistingInstances == nil || member( instName SubcellsToCreate ) || member( instName selectedSubcells ) then + thisInst=car( setof( inst CellView~>instances inst~>name==instName )) + if( thisInst == nil then + printf("Error: instance %s does not exist in layout.\n" instName ) + else + instMaster=nrOpenCellViewReadable( thisInst~>libName thisInst~>cellName thisInst~>viewName) + prBound=setof( lpp instMaster~>lpps lpp~>layerName=="prBoundary" ) + if((prBound !=nil) then + prBoundBox=nil + foreach( thisLayer prBound + foreach( shape thisLayer~>shapes + if((shape~>objType!="label" && prBoundBox==nil) then + prBoundBox=shape~>bBox + ) + ) + ) + if((prBoundBox==nil || thisInst~>xy==nil) then + prBoundBox=instMaster~>bBox + printf("Warning: %s (%s) does not have rectangle prBoundary. Use bBox instead.\n" + thisInst~>name thisInst~>cellName) + ) + else + prBoundBox=instMaster~>bBox + printf("Warning: %s (%s) does not have prBoundary layer. Use bBox instead.\n" + thisInst~>name thisInst~>cellName) + ) + printf("%f %f %L " x y prBoundBox) + x1=x-leftEdge(prBoundBox) + y1=y-bottomEdge(prBoundBox) + width=rightEdge(prBoundBox)-leftEdge(prBoundBox) + height=topEdge(prBoundBox)-bottomEdge(prBoundBox) + width=ceiling(width/SnapXGrid)*SnapXGrid + thisInst~>xy=list( x1 y1 ) + printf("%L\n" list( x1 y1 )) +; dbMoveFig( thisInst CellView list(x1-car(thisInst~>xy):y1-cadr(thisInst~>xy) "R0")) + y=y+height + nextX=max( x+width nextX ) + ) + ) + else + if(rexMatchp("^<.*>$" instName) then + command=substring(instName 2 strlen(instName)-2) + commandList=parseString( command "=" ) + case( car(commandList) + ("unit" sscanf(cadr(commandList) "%f" x1) unit=x1 ) + ("xSpace" sscanf(cadr(commandList) "%f" x1) x=x+x1*unit nextX=max(x nextX)) + ("ySpace" sscanf(cadr(commandList) "%f" y1) y=y+y1*unit ) + ("x" sscanf(cadr(commandList) "%f" x1) x=x1*unit nextX=max(x nextX)) + ("y" sscanf(cadr(commandList) "%f" y1) y=y1*unit+y_offset ) + (t printf("Unrecognized Command \"%s\".\n" command)) + ) + ) + ) + ) + x=nextX + ) + return( CellView ) + + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/optimizeXY.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/optimizeXY.il new file mode 100644 index 0000000000..de6374ba4f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/optimizeXY.il @@ -0,0 +1,99 @@ +; Functions to move selected cells to minimize the vertical and/or +; horizontal wirespan to their fanin or fanout. Designed to help +; placement of complex structures like +; lib.6T.ecc.HAMMING_PARITY_TREE's or CTREE's. +; +; Author: Andrew Lines + +; Make X coordinate of selected cells half-way between minimum and +; maximum X coordinate of fanins and fanouts. Snap to Xsnap grid. +(defun OptimizeX (Xsnap) + (for i 0 20 (OptimizeXY t nil Xsnap 1.0) nil) +) + +; Make Y coordinate of selected cells half-way between minimum and +; maximum Y coordinate of fanins and fanouts. Snap to Ysnap grid. +(defun OptimizeY (Ysnap) + (for i 1 20 (OptimizeXY nil t 1.0 Ysnap) nil) +) + +; Core function (does only one iteration) +(defun OptimizeXY (doX doY Xsnap Ysnap) + (let (moved minX maxX minY maxY x0 y0 x1 y1 ox oy cx cy nx ny x y) + moved = nil + (foreach obj (geGetSelSet) + (cond (obj->objType=="inst" + minX= 10000 minY= 10000 + maxX=-10000 maxY=-10000 + (foreach conn obj->conns + net = conn->net + (cond ((and net->name!="GND" net->name!="Vdd" net->name!="_RESET") + bbox = (NetBoundingBox net obj) + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) +; (printf " %s %f %f %f %f\n" net->name x0*1.0 y0*1.0 x1*1.0 y1*1.0) + minX = (min minX x0) + maxX = (max maxX x1) + minY = (min minY y0) + maxY = (max maxY y1) + ) + ) + ) + ; adjust origin of this instance + ox = (car obj->xy) + oy = (cadr obj->xy) + cx = ((car (car obj->bBox)) + (car (cadr obj->bBox)))/2 + cy = ((cadr (car obj->bBox)) + (cadr (cadr obj->bBox)))/2 + nx = (minX+maxX)/2 + ny = (minY+maxY)/2 + x = ox+nx-cx + y = oy+ny-cy + x = (round x/Xsnap)*Xsnap + y = (round y/Ysnap)*Ysnap + x = (if doX x ox) + y = (if doY y oy) + moved = (or (car obj->xy)!=x (cadr obj->xy)!=y) + obj->xy = (list x y) + ) + ) + ) + moved + ) + ) + +; Return the bounding box of pins and instTerms of a net excluding the +; terminals of excludeInst. +(defun NetBoundingBox (net excludeInst) + (let (bbox x0 y0 x1 y1 minX minY maxX maxY) + minX= 10000 minY= 10000 + maxX=-10000 maxY=-10000 + (foreach pin net->pins + bbox = pin~>fig~>bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + minX = (min minX x0) + maxX = (max maxX x1) + minY = (min minY y0) + maxY = (max maxY y1) + ) + (foreach term net->instTerms + (cond (term~>inst!=excludeInst + bbox = term~>inst~>bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + minX = (min minX x0) + maxX = (max maxX x1) + minY = (min minY y0) + maxY = (max maxY y1) + ) + ) + ) + (list minX:minY maxX:maxY) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/resolveOverlap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/resolveOverlap.il new file mode 100644 index 0000000000..cb55c6abdf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/resolveOverlap.il @@ -0,0 +1,858 @@ +; Copyright 2005 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( flAddOrient ( orient1 instance ) + case( sprintf( nil "%s|%s" orient1 instance~>orient ) + ("R0|R0" "R0") + ("MY|MY" "R0") + ("R0|MY" "MY") + ("MY|R0" "MY") + ( t printf("Warning: illegal orient(%s)(%s) found!\n" instance~>cellName instance~>orient) "R0") + ) +) + +defun( flAddxy ( XY1 XY2 orient2 ) + let(( X3string Y3string x3 y3) + case( orient2 + ("R0" X3string=sprintf( nil "%s +%s" caar(XY1) caar(XY2)) + Y3string=sprintf( nil "%s +%s" cadar(XY1) cadar(XY2)) + x3=caadr(XY1)+caadr(XY2) + y3=cadadr(XY1)+cadadr(XY2) + ) + ("MY" X3string=sprintf( nil "%s -%s" caar(XY1) caar(XY2)) + Y3string=sprintf( nil "%s +%s" cadar(XY1) cadar(XY2)) + x3=caadr(XY1)-caadr(XY2) + y3=cadadr(XY1)+cadadr(XY2) + ) + ( t printf("Warning: illegal orient(%s) found!\n" orient2) + X3string=sprintf( nil "%s +%s" caar(XY1) caar(XY2)) + Y3string=sprintf( nil "%s +%s" cadar(XY1) cadar(XY2)) + x3=caadr(XY1)+caadr(XY2) + y3=cadadr(XY1)+cadadr(XY2) + ) + ) + rexCompile("--") + X3string=rexReplace(X3string "+" 0) + Y3string=rexReplace(Y3string "+" 0) + rexCompile("[+]-") + X3string=rexReplace(X3string "-" 0) + Y3string=rexReplace(Y3string "-" 0) + rexCompile("^top [+]") + X3string=rexReplace(X3string "" 0) + Y3string=rexReplace(Y3string "" 0) + rexCompile("^top ") + X3string=rexReplace(X3string "" 0) + Y3string=rexReplace(Y3string "" 0) + list( list(X3string Y3string) list(x3 y3)) + ) +) + +defun( flGetLeafCellInfo ( inst parentCellName parentxy parentOrient) + let( (bBox transform xy orient instCellView width height XYlist variableName prBound shape yy) + width=-1 height=-1 orient=inst~>orient + instCellView=inst~>master + variableName=sprintf(nil "%s|%s" parentCellName inst~>name) + XYlist=list( list(variableName variableName) inst~>xy) + prBound=car(setof( lpp instCellView~>lpps lpp~>layerName=="prBoundary" && lpp~>purpose=="drawing")) + if( prBound && prBound~>nShapes != 0 then + if( prBound~>nShapes == 1 then + shape=car(prBound~>shapes) + if(shape~>objType=="rect" then + bBox=shape~>bBox + else + printf("Warning: Non rectagular prBound in %s(%s), use cellview bBox instead of prBound layer.\n" inst~>name inst~>cellName) bBox=shape~>bBox + ) + else + printf("Warning: More than one prBound layer found in %s(%s)(%d), use first one.\n" inst~>name inst~>cellName prBound~>nShapes) + shape=car(prBound~>shapes) + bBox=shape~>bBox + ) + else + printf("Warning: No prBound layer found in %s(%s), use cellview bBox instead.\n" inst~>name inst~>cellName) + bBox=instCellView~>bBox + ) + + width=caadr(instCellView~>bBox)-caar(instCellView~>bBox) + height=cadadr(instCellView~>bBox)-cadar(instCellView~>bBox) + yy=cadr(inst~>xy)+cadar(instCellView~>bBox) + + list( sprintf(nil "%s|%s" parentCellName inst~>name) inst~>cellName parentxy bBox parentOrient ) + ) +) + +defun( flGetMidCellInfo (instance parentCellName parentxy parentOrient hierachyName + @key + ( SkipCellList nil ) + ) + let( ( orient instances XYlist variableName fullInstName inst instances LibCellsToIgnore + instCellView instName) + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + variableName=sprintf(nil "%s|%s" parentCellName instance~>name) + instCellView=instance~>master + instances= car( NameFilterInstances( instCellView~>instances LibCellsToIgnore )) +; instances=setof( inst instances !member(inst~>cellName SkipCellList)) + orient=flAddOrient( parentOrient instance) + XYlist=flAddxy( parentxy list( list(variableName variableName) instance~>xy) parentOrient) + instName=sprintf( nil "%s|%s" parentCellName instance~>name ) + xValueTable[instName]=car(instance~>xy) + xLeftEdgeTable[instName]=caar(instance~>bBox) + fullInstName=sprintf( nil "%s|%s" hierachyName instance~>name ) + if( instances !=nil && !member(instance~>cellName SkipCellList) && instance~>viewName != "layout" then + foreach( inst instances + flGetMidCellInfo( inst instance~>cellName XYlist orient + sprintf( nil "%s|%s" hierachyName instance~>name ) ?SkipCellList SkipCellList) + ) + midCellList=cons( + list( instName + instance~>cellName XYlist + instance~>orient fullInstName) + midCellList ) + instList=cons( list( "mid" fullInstName instance~>cellName XYlist orient ) instList ) + else + leafCellList=cons( append( flGetLeafCellInfo( instance parentCellName XYlist orient ) list(fullInstName)) leafCellList ) + instList=cons( list( "leaf" fullInstName instance~>cellName XYlist orient ) instList ) + ) + ) +) + +defun( flFillMidCellInfo ( cellView paraTable + @key + ( SaveCellView nil ) + ( SkipCellList nil ) + ) + let( ( LibCellsToIgnore instances inst x cv instanceMasters transfrom errorCount) + errorCount=0 + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ))) + instances= car( NameFilterInstances( cellView~>instances LibCellsToIgnore )) + if( instances !=nil then + printf("Processing %s...\n" cellView~>cellName) + cv=nrOpenCellViewWritable(cellView~>libName cellView~>cellName cellView~>viewName) + if(cv==nil then + printf("Error: Unable to open %s %s(%s) for write.\n" cellView~>libName cellView~>cellName cellView~>viewName) + errorCount=errorCount+1 + else + foreach( inst instances + x=paraTable[sprintf( nil "%s|%s" cellView~>cellName inst~>name )]-car(inst~>xy) + transform=list(list(x 0) "R0" 1.0) + dbMoveFig( inst cellView transform) + ) + if( SaveCellView then dbSave( cellView )) + ) + ) + instanceMasters=nil + instances=setof( inst instances !member(inst~>cellName SkipCellList) && inst~>viewName != "layout" ) + foreach( cv instances~>master + if(!member(cv~>cellName instanceMasters~>cellName) then + instanceMasters=cons( cv instanceMasters ) + errorCount=errorCount+flFillMidCellInfo(cv paraTable ?SaveCellView SaveCellView ?SkipCellList SkipCellList) + ) + ) + errorCount + ) +) + +defun( flFillTopCellInfo ( cellView paraTable + @key + ( SaveCellView nil ) + ( SkipCellList nil ) + ( BlockLayer list("LOGO" "drawing")) + ) + let( ( LibCellsToIgnore cv errorCount blockLayer lpp shape instName cellName x1 y1 x2 y2 width height) + errorCount=0 + cv=nrOpenCellViewWritable(cellView~>libName cellView~>cellName cellView~>viewName) + if(cv==nil then + printf("Error: Unable to open %s %s(%s) for write.\n" cellView~>libName cellView~>cellName cellView~>viewName) + errorCount=errorCount+1 + else + blockLayer=car( setof(lpp cv~>lpps lpp~>layerName==car(BlockLayer) && lpp~>purpose==cadr(BlockLayer))) + foreach( shape blockLayer~>shapes dbDeleteObject(shape)) + if( blockCellList then + foreach( cell blockCellList + instName=car(cell) + cellName=cadr(cell) + x1=caddr(cell) + y1=cadddr(cell) + x2=cadddr(cdr(cell)) + y2=cadddr(cddr(cell)) + width=cadr(x2)-cadr(x1) + height=cadr(y2)-cadr(y1) + x1=floor(xValueTable[instName]*1000.0+0.5)/1000.0 + y1=cadr(y1) + dbCreateRect( cv BlockLayer list( x1:y1 x1+width:y1+height)) + ) + if( SaveCellView then dbSave(cv)) + ) + errorCount=errorCount+flFillMidCellInfo(cv paraTable ?SaveCellView SaveCellView ?SkipCellList SkipCellList) + ) + errorCount + ) +) +defun( flGetTopCellInfo ( cellView + @key + ( SkipCellList nil ) + ( RegenerateFromCast nil ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ( BlockLayer list("LOGO" "drawing") ) + ) + let( ( orient instances routedDirectiveList LibCellsToIgnore inst + blockCount shape cellName instName fullInstName bBox + x1x2 y1 y2) + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + blockLayer=car( setof(lpp cellView~>lpps lpp~>layerName==car(BlockLayer) && lpp~>purpose==cadr(BlockLayer))) + blockCount=1 + if( blockLayer~>shapes then + printf("Found %d blockage shapes in top cell.\n" blockLayer~>nShapes) + foreach( shape blockLayer~>shapes + cellName=sprintf(nil "dummyblock%d" blockCount) + instName=sprintf(nil "%s|%s" cellview~>cellName cellName) + fullInstName=sprintf( nil "top|%s" cellName) + blockCount=blockCount+1 + bBox=shape~>bBox + x1=list( instName caar(bBox)) + x2=list( sprintf( nil "%s +%f" instName caadr(bBox)-caar(bBox)) caadr(bBox)) + y1=list( instName cadar(bBox)) + y2=list( sprintf( nil "%s +%f" instName cadadr(bBox)-cadar(bBox)) cadadr(bBox)) + blockCellList=cons( list( instName cellName x1 y1 x2 y2 fullInstName ) blockCellList ) + xValueTable[instName]=cadr(x1) + xLeftEdgeTable[instName]=cadr(x1) + ) + ) + instances= car( NameFilterInstances( cellView~>instances LibCellsToIgnore )) +; routedDirectiveList=nrCastQuery( cellView ?RegenerateFromCast RegenerateFromCast ?MaxHeapSize MaxHeapSize) + foreach( inst instances + flGetMidCellInfo( inst cellView~>cellName list(list("top" "top") list(0 0)) "R0" "top" + ?SkipCellList SkipCellList + ) + ) + ) +) + +defun( flParseConstraint ( string variableTable replaceValueTable + @key + ( SnapXGrid 0.0 ) + ) + let( (name sections paraTable para section op i j foundAlpha vName vPara para finalString vValue) + paraTable=makeTable("myTable" 0.0) + op="" + section=listToVector(parseString(string " ")) + for(i 0 length(section)-1 + foundAlpha=0 + j=-1 + if(section[i]==">=" || section[i]=="<=" || section[i]=="=" then + op=section[i] + else + while( foundAlpha==0 && j0 then finalString=sprintf(nil "%s +%f%s" finalString paraTable[vName] vName)) + if(paraTable[vName]<0 then finalString=sprintf(nil "%s %f%s" finalString paraTable[vName] vName)) + ) + ) + ;snap paraTable["constant"] to SnapXGrid + if( SnapXGrid>0.0 then + if( op == ">=" then + paraTable["constant"]=floor(paraTable["constant"]/SnapXGrid)*SnapXGrid + ) + if( op == "<=" then + paraTable["constant"]=ceiling(paraTable["constant"]/SnapXGrid)*SnapXGrid + ) + ) + if(finalString != "" then + finalString=sprintf(nil "%s %s %f" finalString op -paraTable["constant"]) + else + ; when parameters of all vName is zero + if( abs(paraTable["constant"])>1e-5 then + if( op == ">=" && paraTable["constant"]<0.0 then + printf( "Warning 0>=+1: %s\n" string )) + if( op == "<=" && paraTable["constant"]>0.0 then + printf( "Warning 0<=-1: %s\n" string )) + ) + finalString=nil + ) + finalString + ) +) + +defun( flGetArrayName ( string ) + let((temp value) + temp=parseString(string "[") + value=car(temp) + temp=cdr(temp) + if( temp then + while( cdr(temp) + value=sprintf(nil "%s[%s" value car(temp)) + temp=cdr(temp) + ) + if( rexMatchp("|" car(temp)) then value=nil) + else value=nil + ) + if(value && substring(value strlen(value) 1)=="]" then value=flGetArrayName(value)) + value + ) +) + +defun( flSaveCoordinates ( cellview filename + @key + ( SkipCellList nil ) + ( BlockLayer list("LOGO" "drawing") ) + ) + let((instances errorCount p cellInfo x1 y1 x2 y2 xy1 xy2 minX1 minX2 minY1 minY2) + instances=cellview~>instances + midCellList=nil + leafCellList=nil + blockCellList=nil + instList=nil + errorCount=0 + xValueTable=makeTable("myTbale" 0) + xLeftEdgeTable=makeTable("myTbale" 0) + cellInfo=list( cellview~>libName cellview~>cellName cellview~>viewName ) + printf("Exporting Coordinates ...\n") + flGetTopCellInfo( cellview ?SkipCellList SkipCellList ?BlockLayer BlockLayer) + + p=outfile(filename) + if(p then + fprintf(p "cellInfo= `%L\n" cellInfo) + fprintf(p "SkipCellList= `%L\n" SkipCellList) + fprintf(p "blockCellList= `%L\n" blockCellList) + fprintf(p "BlockLayer= `%L\n" BlockLayer) + valueList=tableToList(xValueTable) + fprintf(p "valueList= nil\n") + foreach( cell valueList + fprintf(p "valueList=cons( `%L valueList )\n" cell) + ) + fprintf(p "leafCellList= nil\n") + foreach( cell leafCellList + fprintf(p "leafCellList=cons( `%L leafCellList )\n" cell) + ) + fprintf(p "midCellList= nil\n") + foreach( cell midCellList + fprintf(p "midCellList=cons( `%L midCellList )\n" cell) + ) + fprintf(p "instList= nil\n") + foreach( cell instList + fprintf(p "instList=cons( `%L instList )\n" cell) + ) + close(p) + printf("Success saved coordinates to file %s.\n" filename) + else + printf("Fail to open file %s for write.\n" filename) + ) + ) +) + +defun( flLoadCoordinates ( cellview filename + @key + ( SkipCellList nil ) + ( SaveCellView nil ) + ( BlockLayer list("LOGO" "drawing") ) + ) + let((instances errorCount p cellInfo x1 y1 x2 y2 xy1 xy2 minX1 minX2 minY1 minY2) + instances=cellview~>instances + midCellList=nil + leafCellList=nil + blockCellList=nil + instList=nil + cellInfo=nil + errorCount=0 + load(filename) + xValueTable=makeTable("myTable" 0.0) + foreach( para valueList xValueTable[car(para)]=cadr(para)) + if( car(cellInfo)==cellview~>libName && cadr(cellInfo)==cellview~>cellName && caddr(cellInfo)==cellview~>viewName then + printf("Importing Coordinates ...\n") + errorCount=flFillTopCellInfo(cellview xValueTable ?SaveCellView SaveCellView ?BlockLayer BlockLayer ?SkipCellList SkipCellList) + if( errorCount==0 then + printf("All cells has been updated.\n") + else + printf("Total %d errors found in importing coordinates. \n" errorCount) + ) + else + printf("The cellInfo of cellview and file %s does not match:\n" filename) + printf(" Cellview: %s %s (%s)\n" cellview~>libName cellview~>cellName cellview~>viewName) + printf(" File : %s %s (%s)\n" car(cellInfo) cadr(cellInfo) caddr(cellInfo)) + ) + ) +) + +defun( flResolveOverlap ( cellview + @key + ( SkipCellList nil ) + ( FreezeCellList nil ) + ( LPMacroFileName "glpsol.lpt") + ( LPOutputFileName "glpsol.out") + ( LPLogFileName "glpsol.log") + ( LPmemoFileName "glpsol.memo") + ( BlockLayer list("LOGO" "drawing")) + ( SaveCellView nil ) + ( SaveFileName "temp.sav" ) + ( AbutCellKeepOrder t ) + ( SingleHierarchy nil ) + ( xtotal 0 ) + ( Mode 0 ) + ( SnapXGrid 0.0 ) + ) + let((instances errorCount cell x1 y1 x2 y2 xy1 xy2 minX1 minX2 minY1 minY2 cv_minX topName xMinBound SaveFileName1 p p1) + instances=cellview~>instances + midCellList=nil + leafCellList=nil + blockCellList=nil + instList=nil + errorCount=0 + cv_minX=caar(cellview~>bBox) + xVariableTable=makeTable("myTable" 0) + xValueTable=makeTable("myTable" 0.0) + xValueTableOld=makeTable("myTable" 0.0) + xValueTableNew=makeTable("myTable" 0.0) + xVariableTable["xtotal"]="xtotal" + xLeftEdgeTable=makeTable("myTbale" 0) + + if( xtotal!=0 then + SaveFileName1=SaveFileName + load(SaveFileName) + foreach( para valueList xValueTableOld[car(para)]=cadr(para)) + SaveFileName=sprintf(nil "%s.%d" SaveFileName Mode) + ) + + if( SingleHierarchy then SkipCellList=append( cellview~>instances~>cellName SkipCellList )) + flSaveCoordinates( cellview SaveFileName ?SkipCellList SkipCellList ?BlockLayer BlockLayer ) + if( xtotal!=0 then + load(SaveFileName) + foreach( para valueList xValueTableNew[car(para)]=cadr(para)) + flLoadCoordinates( cellview SaveFileName1 ?SkipCellList SkipCellList ?BlockLayer BlockLayer ) + ) + + PinUtilDeletePinsByType( cellview "InPlace" ) + + printf("Building Constraints ...\n") + + p=outfile(LPMacroFileName "w") + if( p==nil then printf("Can not open %s for write.\n" LPMacroFileName)) + p1=outfile(LPmemoFileName "w") + if( p1==nil then printf("Can not open %s for write.\n" LPmemoFileName)) + fprintf(p "\\ Variable Map\n") + + unique=nil + i=1 + foreach( cell blockCellList + xVariableTable[car(cell)]=sprintf(nil "xb%04d" i) + i=i+1 + ) + foreach( cell leafCellList + if( !member( car(cell) unique) then + unique=cons( car(cell) unique) + xVariableTable[car(cell)]=sprintf(nil "xl%04d" i) + i=i+1 + ) + ) + foreach( cell midCellList + if( !member( car(cell) unique) then + unique=cons( car(cell) unique) + xVariableTable[car(cell)]=sprintf(nil "xm%04d" i) + i=i+1 + ) + ) + + ; process mid array contraints + xMid=listToVector(midCellList) + for(i 0 length(xMid)-2 + instName1=car(xMid[i]) + cellName1=cadr(xMid[i]) + posXY1=caddr(xMid[i]) + orient1=cadddr(xMid[i]) + fullInstName1=caddr(cddr(xMid[i])) + fullInstArrayName1=flGetArrayName(fullInstName1) + minX1=list(caar(posXY1) caadr(posXY1)) + minY1=list(cadar(posXY1) cadadr(posXY1)) + if( fullInstArrayName1 then + for(j i+1 length(xMid)-1 + instName2=car(xMid[j]) + cellName2=cadr(xMid[j]) + posXY2=caddr(xMid[j]) + orient2=cadddr(xMid[j]) + fullInstName2=caddr(cddr(xMid[j])) + fullInstArrayName2=flGetArrayName(fullInstName2) + minX2=list(caar(posXY2) caadr(posXY2)) + minY2=list(cadar(posXY2) cadadr(posXY2)) + ; type 1: if two mid cells have same array name and same x coordinate, then combining two x varaibles into one + if( fullInstArrayName1 && fullInstArrayName2 && fullInstArrayName1==fullInstArrayName2 && + cellName1==cellName2 && abs(cadr(minX1)-cadr(minX2))<0.001 then + variableName1=xVariableTable[instName1] + variableName2=xVariableTable[instName2] + foreach( vName xVariableTable + if(xVariableTable[vName]==variableName2 then xVariableTable[vName]=variableName1) + ) + ) ; type 1 + ) + ) + ) + + xLeaf=nil + foreach( cell leafCellList + instName=car(cell) + cellName=cadr(cell) + XYpos=caddr(cell) + bBox=cadddr(cell) + originPos=cadr(XYpos) + orient=caddr(cddr(cell)) + fullInstName=caddr(cdddr(cell)) + xy1=car(bBox) + xy2=cadr(bBox) + xy1=list(list(sprintf(nil "%f" car(xy1)) sprintf(nil "%f" cadr(xy1))) xy1) + xy2=list(list(sprintf(nil "%f" car(xy2)) sprintf(nil "%f" cadr(xy2))) xy2) + xy1=flAddxy( XYpos xy1 orient) + xy2=flAddxy( XYpos xy2 orient) + if(caadr(xy1)>caadr(xy2) then + x1=list( caar(xy2) caadr(xy2)) + x2=list( caar(xy1) caadr(xy1)) + else + x1=list( caar(xy1) caadr(xy1)) + x2=list( caar(xy2) caadr(xy2)) + ) + if(cadadr(xy1)>cadadr(xy2) then + y1=list( cadar(xy2) cadadr(xy2)) + y2=list( cadar(xy1) cadadr(xy1)) + else + y1=list( cadar(xy1) cadadr(xy1)) + y2=list( cadar(xy2) cadadr(xy2)) + ) + xLeaf=cons( list( instName cellName x1 y1 x2 y2 fullInstName) xLeaf) + ) + + xLeaf=listToVector(append(blockCellList xLeaf)) + ; process leaf array contraints + for(i 0 length(xLeaf)-2 + instName1=car(xLeaf[i]) + cellName1=cadr(xLeaf[i]) + minX1=caddr(xLeaf[i]) + minY1=cadddr(xLeaf[i]) + maxX1=caddr(cddr(xLeaf[i])) + maxY1=caddr(cdddr(xLeaf[i])) + fullInstName1=cadddr(cdddr(xLeaf[i])) + fullInstArrayName1=flGetArrayName(fullInstName1) + if( fullInstArrayName1 then + for(j i+1 length(xLeaf)-1 + instName2=car(xLeaf[j]) + cellName2=cadr(xLeaf[j]) + minX2=caddr(xLeaf[j]) + minY2=cadddr(xLeaf[j]) + maxX2=caddr(cddr(xLeaf[j])) + maxY2=caddr(cdddr(xLeaf[j])) + fullInstName2=cadddr(cdddr(xLeaf[j])) + fullInstArrayName2=flGetArrayName(fullInstName2) + + ; type2: if two leaf cells have same array name and same x coordinate, then combining two x varaibles into one + if( fullInstArrayName1 && fullInstArrayName2 && fullInstArrayName1==fullInstArrayName2 && + cellName1==cellName2 && abs(cadr(minX1)-cadr(minX2))<0.001 then + variableName1=xVariableTable[instName1] + variableName2=xVariableTable[instName2] + foreach( vName xVariableTable + if(xVariableTable[vName]==variableName2 then xVariableTable[vName]=variableName1) + ) + ) ; type 2 + + ) + ) + ) + + ; type 3.a: the leftmost subcell in each mid cell will not move + ; all those subcell x position variable will become constant + xMinBound= cv_minX + xMinValueTable=makeTable("myTable" list(1e9 "")) + foreach( instName xValueTable + topName=car(parseString(instName "|")) + if( !member(topName list("top" "xtotal")) then + if(xLeftEdgeTable[instName]= xValueTableOld[cell] + fprintf(p "+%f%s " paraTable[xVariableTable[cell]] xVariableTable[cell]) + fprintf(p "-%f%s " paraTable[xVariableTable[cell]] xVariableTable[cell]) + ) + ) + else + foreach( cell uniqueVNames fprintf(p "+%f%s " paraTable[cell] cell)) + ) + fprintf(p "\n") + ) + + fprintf(p "\nSubject To\n") + constraintList="" + constraintCount=1 + + if( xtotal !=0 && Mode==1 then + foreach( cell uniqueNames + if(xValueTableNew[cell]>= xValueTableOld[cell] then + constraint=sprintf(nil "%s >= %f" cell xValueTableOld[cell]) + else + constraint=sprintf(nil "%s <= %f" cell xValueTableOld[cell]) + ) + fprintf(p1 "\\ Constraint%d: %s\n" constraintCount constraint) + constraintString=flParseConstraint(constraint xVariableTable xReplaceValueTable ?SnapXGrid SnapXGrid) + if( constraintString then + fprintf(p " Constraint%d: %s\n" constraintCount constraintString) + else + fprintf(p "\\ Constraint%d: \n" constraintCount) + ) + constraintCount=constraintCount+1 + ) + fprintf(p1 "\n") + fprintf(p "\n") + ) + for(i 0 length(xLeaf)-1 + instName1=car(xLeaf[i]) + cellName1=cadr(xLeaf[i]) + minX1=caddr(xLeaf[i]) + minY1=cadddr(xLeaf[i]) + maxX1=caddr(cddr(xLeaf[i])) + maxY1=caddr(cdddr(xLeaf[i])) + fullInstName1=cadddr(cdddr(xLeaf[i])) + constraint=sprintf(nil "%s >= %f" car(minX1) cv_minX) + fprintf(p1 "\\ Constraint%d: %s\n" constraintCount constraint) + constraintString=flParseConstraint(constraint xVariableTable xReplaceValueTable ?SnapXGrid SnapXGrid) + if( constraintString then + fprintf(p " Constraint%d: %s\n" constraintCount constraintString) + else + fprintf(p "\\ Constraint%d: \n" constraintCount) + ) + constraintCount=constraintCount+1 + constraint=sprintf(nil "%s -xtotal <= 0.0" car(maxX1)) + fprintf(p1 "\\ Constraint%d: %s\n" constraintCount constraint) + constraintString=flParseConstraint(constraint xVariableTable xReplaceValueTable ?SnapXGrid SnapXGrid) + if( constraintString then + fprintf(p " Constraint%d: %s\n" constraintCount constraintString) + else + fprintf(p "\\ Constraint%d: \n" constraintCount) + ) + constraintCount=constraintCount+1 + ) + fprintf(p1 "\n") + fprintf(p "\n") + + for(i 0 length(xLeaf)-2 + instName1=car(xLeaf[i]) + cellName1=cadr(xLeaf[i]) + minX1=caddr(xLeaf[i]) + minY1=cadddr(xLeaf[i]) + maxX1=caddr(cddr(xLeaf[i])) + maxY1=caddr(cdddr(xLeaf[i])) + fullInstName1=cadddr(cdddr(xLeaf[i])) + fullInstArrayName1=flGetArrayName(fullInstName1) + for(j i+1 length(xLeaf)-1 + instName2=car(xLeaf[j]) + cellName2=cadr(xLeaf[j]) + minX2=caddr(xLeaf[j]) + minY2=cadddr(xLeaf[j]) + maxX2=caddr(cddr(xLeaf[j])) + maxY2=caddr(cdddr(xLeaf[j])) + fullInstName2=cadddr(cdddr(xLeaf[j])) + fullInstArrayName2=flGetArrayName(fullInstName2) + + ; process leaf x contraints + + ; type 4: if two leaf cell has overlap Y, add an x constraint + if(cadr(maxY1)>cadr(minY2)+0.001 && cadr(maxY2)>cadr(minY1)+0.001 then + cond( + (cadr(minX1) < cadr(minX2) constraint= sprintf(nil "%s <= %s" car(maxX1) car(minX2))) + (cadr(minX1) > cadr(minX2) constraint= sprintf(nil "%s >= %s" car(minX1) car(maxX2))) + (t + printf("Warning: %s %s overlap and have same x cordinate!\n" fullInstName1 fullInstName2 ) + cond( + (cadr(maxX1) < cadr(maxX2) constraint= sprintf(nil "%s <= %s" car(maxX1) car(minX2))) + (cadr(maxX1) > cadr(maxX2) constraint= sprintf(nil "%s >= %s" car(minX1) car(maxX2))) + (t + if( strcmp( fullInstArrayName1 fullInstArrayName2 )>0 then + constraint= sprintf(nil "%s <= %s" car(maxX1) car(minX2)) + else + constraint= sprintf(nil "%s >= %s" car(minX1) car(maxX2)) + ) + ) + ) + ) + ) + fprintf(p1 "\\ Constraint%d(type4): %s\n" constraintCount constraint) + constraintString=flParseConstraint(constraint xVariableTable xReplaceValueTable ?SnapXGrid SnapXGrid) + if( constraintString then + fprintf(p " Constraint%d: %s\n" constraintCount constraintString) + else + fprintf(p "\\ Constraint%d: \n" constraintCount) + ) + constraintCount=constraintCount+1 + ) ; type 4 + + ; type 5: if two leaf cell has Y abut and different x, add an x constraint + if( AbutCellKeepOrder && + (fullInstArrayName1==nil || fullInstArrayName2==nil || fullInstArrayName1!=fullInstArrayName2) && + (abs(cadr(maxY1)-cadr(minY2))<0.001 || abs(cadr(maxY2)-cadr(minY1))<0.001) && + (cadr(maxX1)>cadr(minX2)+0.001 && cadr(maxX2)>cadr(minX1)+0.001) + then +; fprintf(p1 "minX2: %f minX1: %f\n" cadr(minX2) cadr(minX1)) + if(abs(cadr(minX2)-cadr(minX1))<0.001 then + constraint= sprintf(nil "%s = %s" car(minX1) car(minX2)) + ) + if(cadr(minX2)>cadr(minX1)+0.001 then + constraint= sprintf(nil "%s <= %s" car(minX1) car(minX2)) + ) + if(cadr(minX1)>cadr(minX2)+0.001 then + constraint= sprintf(nil "%s >= %s" car(minX1) car(minX2)) + ) + fprintf(p1 "\\ Constraint%d(type5): %s\n" constraintCount constraint) + constraintString=flParseConstraint(constraint xVariableTable xReplaceValueTable ?SnapXGrid SnapXGrid) + if( constraintString then + fprintf(p " Constraint%d: %s\n" constraintCount constraintString) + else + fprintf(p "\\ Constraint%d: \n" constraintCount) + ) + constraintCount=constraintCount+1 + ) ; type 5 + + ) + ) + + if( xtotal != 0 then + constraint= sprintf(nil "xtotal <= %f" xtotal+1e-4) + fprintf(p1 "\\ Constraint%d: %s\n" constraintCount constraint) + fprintf(p " Constraint%d: %s" constraintCount flParseConstraint(constraint xVariableTable xReplaceValueTable ?SnapXGrid SnapXGrid)) + ) + + fprintf(p1 "\n") + fprintf(p "\n") + + fprintf(p "\nBounds\n") + foreach( vName uniqueVNames + fprintf(p " %s >= %f \n" vName xMinBound) + ) + + fprintf(p "End") + + close(p1) + close(p) + + if( errorCount==0 then + cmd=sprintf( nil "glpsol --lpt --min -o %s %s > %s" LPOutputFileName LPMacroFileName LPLogFileName) + printf("Running %s\n" cmd) + system(cmd) + + paraTable=makeTable("myTable" 0.0) + foreach( vName xReplaceValueTable + paraTable[vName]=xReplaceValueTable[vName] + ) + p=infile(LPOutputFileName) + if( p then + gets(s p) + while( !rexMatchp( "Status:" s) gets(s p)) + if( rexMatchp("OPTIMAL" s) then optimal=t else optimal=nil ) + while( !rexMatchp( "No. Column name St Activity Lower bound Upper bound Marginal" s) + gets(s p) + ) + gets(s p) + gets(s p) + while(s + if( rexMatchp("^[ \n]*$" s) then s=nil + else + sscanf( s "%d %s %s %f" no vName st vPara ) + paraTable[vName]=vPara + gets(s p) + ) + ) + close(p) + + xValueTable=makeTable("myTable" 0.0) + foreach( vName xVariableTable + xValueTable[vName]=paraTable[xVariableTable[vName]] + ) + if(!optimal then + printf("No Solution Found ...\n") + else + printf("Importing Coordinates ...\n") + errorCount=flFillTopCellInfo(cellview xValueTable ?SaveCellView SaveCellView ?BlockLayer BlockLayer ?SkipCellList SkipCellList) + if( errorCount==0 then + printf("All cells has been updated.\n") + else + printf("Total %d errors found in importing coordinates. \n" errorCount) + ) + ) + else + printf("Error in running glpsol, please check %s\n" LPLogFileName) + ) + else + printf("Total %d errors found in generating contraints.\n" errorCount) + ) + + xValueTable["xtotal"] + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefloorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefloorplan.il new file mode 100644 index 0000000000..af758267ff --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefloorplan.il @@ -0,0 +1,430 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun UpdateFloorplanTablifyInstances ( Instances TargetTable ) + ( foreach + Instance + Instances + ( setarray + TargetTable + ( NameCanonicalizeNonFoldableInstanceName ( getq Instance name ) ) + Instance ) ) ) + +(defun UpdateFloorplanComparePRBounds ( FloorplanCellView CellView PRBoundLPP ) + (let ( + ( FloorplanBoundShape ( car + ( setof + Shape + ( getq FloorplanCellView shapes ) + ( and + ( equal ( car ( getq Shape lpp ) ) ( car PRBoundLPP ) ) + ( equal ( cadr ( getq Shape lpp ) ) ( cadr PRBoundLPP ) ) ) ) ) ) + ( LayoutBoundShape ( car + ( setof + Shape + ( getq CellView shapes ) + ( and + ( equal ( car ( getq Shape lpp ) ) ( car PRBoundLPP ) ) + ( equal ( cadr ( getq Shape lpp ) ) ( cadr PRBoundLPP ) ) ) ) ) ) ) + ( dbComputeBBox CellView ) + (when FloorplanBoundShape + (let ( + ( FloorplanBBox ( getq FloorplanBoundShape bBox ) ) + ( LayoutBBox (if LayoutBoundShape + ( getq LayoutBoundShape bBox ) + ( getq CellView bBox ) ) ) ) + (unless ( and + ( equal ( RectGetLeft FloorplanBBox ) ( RectGetLeft LayoutBBox ) ) + ( equal ( RectGetRight FloorplanBBox ) ( RectGetRight LayoutBBox ) ) + ( equal ( RectGetBottom FloorplanBBox ) ( RectGetBottom LayoutBBox ) ) + ( equal ( RectGetTop FloorplanBBox ) ( RectGetTop LayoutBBox ) ) ) + ( list + LayoutBBox + FloorplanBBox ) ) ) ) ) ) + + +(defun UpdateFloorplanCompareInstances ( FloorplanInstance Instance ) + (let ( + ( FloorplanLibName ( getq FloorplanInstance libName ) ) + ( LibName ( getq Instance libName ) ) + ( FloorplanCellName ( getq FloorplanInstance cellName ) ) + ( CellName ( getq Instance cellName ) ) + ( FloorplanPosition ( getq FloorplanInstance xy ) ) + ( Position ( getq Instance xy ) ) + ( FloorplanOrientation ( getq FloorplanInstance orient ) ) + ( Orientation ( getq Instance orient ) ) ) + (let ( + ( CompareResult + ( list + (unless ( and + ( equal FloorplanLibName LibName ) + ( equal FloorplanCellName CellName ) ) + ( list + ( list + LibName + CellName ) + ( list + FloorplanLibName + FloorplanCellName ) ) ) + (unless ( and + ( equal ( car FloorplanPosition ) ( car Position ) ) + ( equal ( cadr FloorplanPosition ) ( cadr Position ) ) ) + ( list + Position + FloorplanPosition ) ) + (unless ( equal FloorplanOrientation Orientation ) + ( list + Orientation + FloorplanOrientation ) ) ) ) ) + (unless ( forall Entry CompareResult ( null Entry ) ) + ( cons + ( list Instance FloorplanInstance ) + CompareResult ) ) ) ) ) + +(defun UpdateFloorplanGetInstancesFromInstanceCompareResult ( InstanceCompareResult ) + ( car InstanceCompareResult ) ) + +(defun UpdateFloorplanGetMasterCellLibCellPairsFromInstanceCompareResult ( InstanceCompareResult ) + ( nth 1 InstanceCompareResult ) ) + +(defun UpdateFloorplanGetPositionsFromInstanceCompareResult ( InstanceCompareResult ) + ( nth 2 InstanceCompareResult ) ) + +(defun UpdateFloorplanGetOrientationsFromInstanceCompareResult ( InstanceCompareResult ) + ( nth 3 InstanceCompareResult ) ) + +(defun UpdateFloorplanMakeCompareResult ( CellView + FloorplanCellView + ExtraLayoutInstances + MissingLayoutInstances + InstancesCompareResult + BoundaryCompareResult ) + ( list + CellView + FloorplanCellView + ( getq CellView cellName ) + ExtraLayoutInstances + MissingLayoutInstances + InstancesCompareResults + BoundaryCompareResult ) ) + +(defun UpdateFloorplanGetCellViewFromCompareResult ( CompareResult ) + ( car CompareResult ) ) + +(defun UpdateFloorplanGetFloorplanCellViewFromCompareResult ( CompareResult ) + ( nth 1 CompareResult ) ) + +(defun UpdateFloorplanGetCellNameFromCompareResult ( CompareResult ) + ( nth 2 CompareResult ) ) + +(defun UpdateFloorplanGetExtaLayoutInstancesFromCompareResult ( CompareResult ) + ( nth 3 CompareResult ) ) + +(defun UpdateFloorplanGetMissingLayoutInstancesFromCompareResult ( CompareResult ) + ( nth 4 CompareResult ) ) + +(defun UpdateFloorplanGetInstancesCompareResultsFromCompareResult ( CompareResult ) + ( nth 5 CompareResult ) ) + +(defun UpdateFloorplanGetBoundaryCompareResultFromCompareResult ( CompareResult ) + ( nth 6 CompareResult ) ) + +(defun UpdateFloorplanCompareCellViewToFloorplanView ( FloorplanCellView + CellView + LibCellExpressionPairsToIgnore + PRBoundLPP ) + (let ( + ( FloorplanInstances ( getq + FloorplanCellView + instances ) ) + ( Instances ( car + ( NameFilterInstances + ( getq CellView instances ) + LibCellExpressionPairsToIgnore ) ) ) + ( FloorplanInstanceTable ( makeTable "instanceTable" nil ) ) + ( InstanceTable ( makeTable "instanceTable" nil ) ) ) + ( UpdateFloorplanTablifyInstances FloorplanInstances FloorplanInstanceTable ) + ( UpdateFloorplanTablifyInstances Instances InstanceTable ) + (let ( + ( ExtraLayoutInstances ( setof + Instance + Instances + ( null + ( arrayref + FloorplanInstanceTable + ( NameCanonicalizeNonFoldableInstanceName + ( getq Instance name ) ) ) ) ) ) + ( MissingLayoutInstances ( setof + FloorplanInstance + FloorplanInstances + ( null + ( arrayref + InstanceTable + ( NameCanonicalizeNonFoldableInstanceName + ( getq FloorplanInstance name ) ) ) ) ) ) + ( FloorplanInstancesToCheck ( setof + FloorplanInstance + FloorplanInstances + ( arrayref + InstanceTable + ( NameCanonicalizeNonFoldableInstanceName + ( getq FloorplanInstance name ) ) ) ) ) ) + (let ( + ( BoundaryCompareResult ( UpdateFloorplanComparePRBounds + FloorplanCellView + CellView + PRBoundLPP ) ) + ( InstancesCompareResults ( ListApplyFuncToListAndAccumulateNonNilResults + FloorplanInstancesToCheck + (lambda ( FloorplanInstanceToCheck InstanceTable ) + (let ( + ( Instance ( arrayref + InstanceTable + ( NameCanonicalizeNonFoldableInstanceName + ( getq FloorplanInstanceToCheck name ) ) ) ) ) + ( UpdateFloorplanCompareInstances + FloorplanInstanceToCheck + Instance ) ) ) + ( list InstanceTable ) ) ) ) + (when ( or InstancesCompareResults ExtraLayoutInstances MissingLayoutInstances BoundaryCompareResult ) + ( UpdateFloorplanMakeCompareResult + CellView + FloorplanCellView + ExtraLayoutInstances + MissingLayoutInstances + InstancesCompareResults + BoundaryCompareResult ) ) ) ) ) ) + + +(defun UpdateFloorplanHierCompareCellViewsToFloorplanViews ( RootCellViews + LibCellExpressionPairsToIgnore + FloorplanViewName + PRBoundLPP ) + (let ( + ( CellViewsInTree ( HierarchyGetCellDescendantsOfCells + RootCellViews + LibCellExpressionPairsToIgnore + (lambda ( CellView ) nil ) + nil ) ) ) + ( ListApplyFuncToListAndAccumulateNonNilResults + CellViewsInTree + (lambda + ( CellView LibCellExpressionPairsToIgnore FloorplanViewName ) + (let ( + ( LibName ( getq CellView libName ) ) + ( CellName ( getq CellView cellName ) ) ) + (let ( + ( FloorplanCellViewDDObj ( ddGetObj LibName CellName FloorplanViewName ) ) ) + (if FloorplanCellViewDDObj + (let ( + ( FloorplanCellView ( dbOpenCellViewByType + LibName + CellName + FloorplanViewName + nil + "r" ) ) ) + ( UpdateFloorplanCompareCellViewToFloorplanView + FloorplanCellView + CellView + LibCellExpressionPairsToIgnore + PRBoundLPP ) ) + ( list CellView nil ( getq CellView cellName ) nil nil nil nil ) ) ) ) ) + ( list LibCellExpressionPairsToIgnore FloorplanViewName ) ) ) ) + +(defun UpdateFloorplanPrintDifferences ( OutputPort CompareResults ) + ( foreach + CompareResult + CompareResults + (let ( + ( CellName ( UpdateFloorplanGetCellNameFromCompareResult CompareResult ) ) + ( FloorplanCellView ( UpdateFloorplanGetFloorplanCellViewFromCompareResult CompareResult ) ) + ( ExtraInstances ( UpdateFloorplanGetExtaLayoutInstancesFromCompareResult CompareResult ) ) + ( MissingInstances ( UpdateFloorplanGetMissingLayoutInstancesFromCompareResult CompareResult ) ) + ( InstancesCompareResults ( UpdateFloorplanGetInstancesCompareResultsFromCompareResult + CompareResult ) ) + ( BoundaryCompareResult ( UpdateFloorplanGetBoundaryCompareResultFromCompareResult + CompareResult ) ) ) + (if FloorplanCellView + (let () + ( foreach + ExtraInstance + ExtraInstances + ( fprintf OutputPort "%L EXTRA %L\n" CellName ( getq ExtraInstance name ) ) ) + ( foreach + MissingInstance + MissingInstances + ( fprintf OutputPort "%L MISSING %L\n" CellName ( getq MissingInstance name ) ) ) + + ( foreach + InstanceCompareResult + InstancesCompareResults + (let ( + ( Instances ( UpdateFloorplanGetInstancesFromInstanceCompareResult + InstanceCompareResult ) ) + ( MasterCellLibCellPairs ( UpdateFloorplanGetMasterCellLibCellPairsFromInstanceCompareResult + InstanceCompareResult ) ) + ( Positions ( UpdateFloorplanGetPositionsFromInstanceCompareResult + InstanceCompareResult ) ) + ( Orientations ( UpdateFloorplanGetOrientationsFromInstanceCompareResult + InstanceCompareResult ) ) ) + (when MasterCellLibCellPairs + ( fprintf + OutputPort + "%L MASTER %L %L %L\n" + CellName + ( getq ( car Instances ) name ) + ( cadr MasterCellLibCellPairs ) + ( car MasterCellLibCellPairs ) ) ) + (when Positions + ( fprintf + OutputPort + "%L POS %L %L %L\n" + CellName + ( getq ( car Instances ) name ) + ( cadr Positions ) + ( car Positions ) ) ) + (when Orientations + ( fprintf + OutputPort + "%L ORIENT %L %L %L\n" + CellName + ( getq ( car Instances ) name ) + ( cadr Orientations ) + ( car Orientations ) ) ) ) ) + (when BoundaryCompareResult + ( fprintf OutputPort "%L BOUND %L %L\n" CellName ( cadr BoundaryCompareResult ) ( car BoundaryCompareResult ) ) ) ) + ( fprintf OutputPort "#%L did not have a floorplan view.\n" CellName ) ) ) ) + nil ) + +(defun UpdateFloorplanDoUpdate ( CompareResults PRBoundLPP ) + (let ( + ( Errors nil ) ) + ( foreach + CompareResult + CompareResults + (let ( + ( CellName ( UpdateFloorplanGetCellNameFromCompareResult CompareResult ) ) + ( FloorplanCellView ( UpdateFloorplanGetFloorplanCellViewFromCompareResult CompareResult ) ) + ( ExtraInstances ( UpdateFloorplanGetExtaLayoutInstancesFromCompareResult CompareResult ) ) + ( MissingInstances ( UpdateFloorplanGetMissingLayoutInstancesFromCompareResult CompareResult ) ) + ( InstancesCompareResults ( UpdateFloorplanGetInstancesCompareResultsFromCompareResult + CompareResult ) ) + ( BoundaryCompareResult ( UpdateFloorplanGetBoundaryCompareResultFromCompareResult + CompareResult ) ) ) + (if FloorplanCellView + (let ( + ( FloorplanCellViewDDObj ( ddGetObj + ( getq FloorplanCellView libName ) + ( getq FloorplanCellView cellName ) + ( getq FloorplanCellView viewName ) ) ) ) + (when ( not ( equal ( getq FloorplanCellView viewName ) "floorplan" ) ) + ( error "floorplan view was not named \"floorplan\"" ) ) + (if ( and + FloorplanCellViewDDObj + ( car ( getq FloorplanCellViewDDObj files ) ) + ( forall + File + ( getq FloorplanCellViewDDObj files ) + ( ddIsObjWritable File ) ) ) + (let () + ( dbReopen FloorplanCellView "a" ) + ( foreach + InstanceCompareResult + InstancesCompareResults + (let ( + ( Instances ( UpdateFloorplanGetInstancesFromInstanceCompareResult + InstanceCompareResult ) ) + ( MasterCellLibCellPairs ( UpdateFloorplanGetMasterCellLibCellPairsFromInstanceCompareResult + InstanceCompareResult ) ) + ( Positions ( UpdateFloorplanGetPositionsFromInstanceCompareResult + InstanceCompareResult ) ) + ( Orientations ( UpdateFloorplanGetOrientationsFromInstanceCompareResult + InstanceCompareResult ) ) ) + (let ( + ( FloorplanInstance ( cadr Instances ) ) ) + (unless ( equal ( getq FloorplanInstance viewName ) "floorplan" ) + ( error "Not instance of floorplan view." ) ) + (when MasterCellLibCellPairs + (let ( + ( LayoutLibCellPair ( car MasterCellLibCellPairs ) ) ) + (let ( + ( NewMasterCellViewDDObj ( ddGetObj + ( car LayoutLibCellPair ) + ( cadr LayoutLibCellPair ) + ( getq FloorplanInstance viewName ) ) ) ) + (if ( and + NewMasterCellViewDDObj + ( getq NewMasterCellViewDDObj files ) ) + (let ( + ( NewMasterCellView ( dbOpenCellViewByType + ( car LayoutLibCellPair ) + ( cadr LayoutLibCellPair ) + ( getq FloorplanInstance viewName ) + nil + "r" ) ) ) + (if NewMasterCellView + ( dbSetq FloorplanInstance NewMasterCellView master ) + ( setq + Errors + ( cons + ( sprintf + nil + "Unable to open %L %L %L for instance %L in %L %L %L" + ( car LayoutLibCellPair ) + ( cadr LayoutLibCellPair ) + ( getq FloorplanInstance viewName ) + ( getq FloorplanInstance name ) + ( getq FloorplanCellView libName ) + ( getq FloorplanCellView cellName ) + ( getq FloorplanCellView viewName ) ) + Errors ) ) ) ) + ( setq + Errors + ( cons + ( sprintf + nil + "%L %L %L for instance %L in %L %L %L does not exist." + ( car LayoutLibCellPair ) + ( cadr LayoutLibCellPair ) + ( getq FloorplanInstance viewName ) + ( getq FloorplanInstance name ) + ( getq FloorplanCellView libName ) + ( getq FloorplanCellView cellName ) + ( getq FloorplanCellView viewName ) ) + Errors ) ) ) ) ) ) + (when Positions + ( dbSetq FloorplanInstance ( car Positions ) xy ) ) + (when Orientations + ( dbSetq FloorplanInstance ( car Orientations ) orient ) ) ) ) ) + (when BoundaryCompareResult + ( foreach + Shape + ( getq FloorplanCellView shapes ) + (when ( and + ( equal ( car ( getq Shape lpp ) ) ( car PRBoundLPP ) ) + ( equal ( cadr ( getq Shape lpp ) ) ( cadr PRBoundLPP ) ) ) + ( dbDeleteObject Shape ) ) ) + ( dbCreateRect + FloorplanCellView + PRBoundLPP + ( car BoundaryCompareResult ) ) ) + ( dbSave FloorplanCellView ) ) + ( setq + Errors + ( cons + ( sprintf + nil + "Unable to open %L %L %L for append." + ( getq FloorplanCellView libName ) + ( getq FloorplanCellView cellName ) + ( getq FloorplanCellView viewName ) ) + Errors ) ) ) ) + ( setq + Errors + ( cons + ( sprintf nil "%L did not have a floorplan view." CellName ) + Errors ) ) ) ) ) + Errors ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefromlayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefromlayout.il new file mode 100644 index 0000000000..4af7494705 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/updatefromlayout.il @@ -0,0 +1,93 @@ +(defun GetPrbound (cv) + (let (prb prb2) + (foreach shape cv->shapes + (when (car shape->lpp)=="prBoundary" && (cadr shape->lpp)=="drawing" + prb=shape + ) + ) + (when cv->prBoundary + prb=cv->prBoundary + ) + prb + ) +) + +; return points of prBoundary as if it were a polygon +(defun GetPrboundPoints (cv) + (let (prb x0 y0 x1 y1) + prb = (car (setof s cv->shapes (car s->lpp)=="prBoundary" && (cadr s->lpp)=="drawing")) + (unless prb prb=cv->prBoundary) + (cond (prb->objType=="rect" + x0 = (car (car prb->bBox)) + y0 = (cadr (car prb->bBox)) + x1 = (car (cadr prb->bBox)) + y1 = (cadr (cadr prb->bBox)) + (list x0:y0 x1:y0 x1:y1 x0:y1) + ) + (t + prb->points + ) + ) + ) + ) + +(defun ConvertPrboundToObject + (@key (CV (geGetEditCellView))) ; specify CellView or nil to use edit view + (let (prb) + prb=(GetPrbound CV) + (if prb->objType=="PRBoundary" then + (printf "already a boundary object.\n") + else + (when prb->objType=="rect" + (dbCreatePRBoundary CV (RectGetPolygonPoints prb->bBox)) + (dbDeleteObject prb) + ) + (when prb->objType=="polygon" + (dbCreatePRBoundary CV prb->points) + (dbDeleteObject prb) + ) + ) + ) +) + + +(defun UpdateLeafFloorplanList (leaflist) + (let (cells floorplan layout prbf prbl count) + + count=0 + cells=(OpenCellViewsFromFile leaflist "floorplan" "r") + (foreach cell cells + floorplan=nil layout=nil prbf=nil prbl=nil + layout=(nrOpenCellViewReadable cell->libName cell->cellName + "layout") + (when layout + prbl=(GetPrbound layout) + ) + floorplan=(nrOpenCellViewReadable cell->libName cell->cellName + "floorplan") + (when floorplan + prbf=(GetPrbound cell) + (when prbl && prbf + (if prbf->bBox!=prbl->bBox then + (CDSP4Edit + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cell + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + (printf "Updating floorplan of %s.\n" cell->cellName) + prbf->bBox=prbl->bBox + count=count+1 + (dbSave floorplan) + else + (printf "Prbounds match for %s.\n" cell->cellName) + ) + ) + ) + ) + (printf "Updated %d floorplan views.\n" count) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/util.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/util.il new file mode 100644 index 0000000000..526fe3eb4d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/floorplanning/util.il @@ -0,0 +1,90 @@ +; move a single instance +(defun MoveInstance ( x y @key (inst nil)) + (when !inst + inst=(car (geGetSelectedSet)) + ) + (if (IsInstanceAnchored inst) then + (printf "Not moving anchored instance %s.\n" inst->name) + else + inst->xy = x:y + ) +) + +; move selected items +(defun MoveSelected ( xOffset yOffset) + (foreach x (geGetSelSet) + (cond ((IsInstanceAnchored x) + (printf "Not moving anchored instance %s.\n" x->name) + ) + (!x->parent + (dbMoveFig x nil (list xOffset:yOffset "R0")) + ) + ) + ) + t + ) + +; basic move of selected stuff, while filtering anchors +(defun MoveWithAnchor () + (let (selected) + selected=(geGetSelectedSet) + (foreach item selected + (when item->objType=="inst" && (IsInstanceAnchored item) + (printf "Deselecting anchored instance %s.\n" item->name) + (geDeselectFig item) + ) + ) + (leHiMove) + ) +) + +; basic stretch of selected stuff, while filtering anchors +(defun StretchWithAnchor () + (let (selected) + selected=(geGetSelectedSet) + (foreach item selected + (when item->objType=="inst" && (IsInstanceAnchored item) + (printf "Deselecting anchored instance %s.\n" item->name) + (geDeselectFig item) + ) + ) + (leHiStretch) + ) +) + +; click and drag of selected stuff, while filtering anchors +; this is the most common way of inadvertently moving things +(defun SelBoxOrStretchWithAnchor () + (let (selected) + selected=(geGetSelectedSet) + (foreach item selected + (when item->objType=="inst" && (IsInstanceAnchored item) + (printf "Deselecting anchored instance %s.\n" item->name) + (geDeselectFig item) + ) + ) + (leSelBoxOrStretch) + ) +) + +; basic delete of selected stuff, while filtering protected +(defun DeleteWithProtect () + (let (selected) + selected=(geGetSelectedSet) + (foreach item selected + (when item->objType=="inst" && (IsInstanceProtected item) + (printf "Deselecting protected instance %s.\n" item->name) + (geDeselectFig item) + ) + (when item->objType!="inst" + dbDeleteObject(item) + ) + (when item->objType=="inst" && !(IsInstanceProtected item) + dbDeleteObject(item) + ) + + ) +; (leHiDelete) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCells.il new file mode 100644 index 0000000000..4ca4195615 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCells.il @@ -0,0 +1,55 @@ +; This Fuction is used to align all the selected cells on to the power grids +procedure( AlignCells( xGrid yGrid xOffset yOffset ) + + SelectedCellList = geGetSelSet( ) + + foreach( SelectedCell SelectedCellList + + if( SelectedCell->objType == "inst" + + then + + xCord = car( SelectedCell -> xy ) + yCord = car( cdr( SelectedCell -> xy )) + + ; Move to negative x direction + xDiff1 = (( xCord / xGrid ) - floor( xCord / xGrid )) * xGrid + + ; Move to negative y direction + yDiff1 = (( yCord / yGrid ) - floor( yCord / yGrid )) * yGrid + + ; Move to positive x direction + xDiff2 = (( xCord / xGrid ) - floor( ( xCord / xGrid ) + 1 )) * xGrid + + ; Move to positive y direction + yDiff2 = (( yCord / yGrid ) - floor( ( yCord / yGrid ) + 1 )) * yGrid + + ; Find the closest + if( abs( xDiff1 ) > abs( xDiff2 ) + then + xDiff = xDiff2 + else + xDiff = xDiff1 + ) + if( yDiff1 > abs( yDiff2 ) + then + yDiff = yDiff2 + else + yDiff = yDiff1 + ) + + dbMoveFig( SelectedCell, nil, list(-xDiff:-yDiff "R0")) + dbMoveFig( SelectedCell, nil, list(xOffset:yOffset "R0")) + + else + + geDeselectObject( SelectedCell ) + ) ;if + + ) ;foreach + + +) ;procedure + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsDataPath.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsDataPath.il new file mode 100644 index 0000000000..35922e81db --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsDataPath.il @@ -0,0 +1,149 @@ +; This Fuction is used to align all the selected cells on to form a vertical datapath +; It only works if the selected cells are of the same master +; It will retain the rotation properties of the cells +procedure( AlignCellsV( x y h stickX ) + + ; local Varibales + let( ( l_d_SelectedCell + xOffset x_Selected + yOffset y_Selected + returnValue) + + l_d_SelectedCell = geGetSelectedSet( ) + + returnValue = t + + ;Verifying the validity of the input + ;Check to make sure that the user has selected at least 1 cell (inst) + if( length( l_d_SelectedCell ) > 0 && car( l_d_SelectedCell )->objType == "inst" + then + d_masterCell = car( l_d_SelectedCell )->master + + ;Check to make sure that they are the same master + foreach( d_SelectedCell l_d_SelectedCell + + if( d_SelectedCell->master != d_masterCell + + then + returnValue = nil + println( "AlignCellsV ---> Error!!! Instances selected belong to different cell types" ) + ) ;end if + + ) ;end for + + else + + returnValue = nil + println( "AlignCellsV ---> Error!!! You must select at least ONE instance" ) + + ) ;end if + + + ;Do the Vertical DataPath Alignment + if( returnValue == t + then + l_d_SelectedCell = dbSortDBList( l_d_SelectedCell ) + + printf( "AlignCellsV ---> New ordering from dbSortDBList\n") + printf( "AlignCellsV ---> ") + + foreach( d_SelectedCell l_d_SelectedCell + + printf( "%s " d_SelectedCell->name) + + x_Selected = car( car( d_SelectedCell->bBox ) ) + y_Selected = car( cdr( car( d_SelectedCell->bBox ) ) ) + + + if( stickX + then + xOffset = 0 + else + xOffset = x - x_Selected + ); end if + + yOffset = y - y_Selected + + dbMoveFig( d_SelectedCell, nil, list(xOffset:yOffset "R0")) + + if( h == 0 + then + y = car( cdr( car( cdr( d_SelectedCell->bBox ) ) ) ) + else + y = y + h + ); end if + + ) ;end for + + printf( "\n") + + ) ;end if + + ; Return Value + returnValue + + ); end let + +); end procedure + + +; This Fuction is an advanced GUI Version of AlignCellsV + +; Create Form Entries +trAlignCellsVbitPitch = hiCreateStringField( + ?name 'trAlignCellsVbitPitch + ?prompt "Enter Desired Bit Pitch" + ?defValue "19.2" + ?editable t +) + +trAlignCellsVnumBits = hiCreateRadioField( + ?name 'trAlignCellsVnumBits + ?choices '( "1" "2" "3" "4" "6" "8" "16") + ?prompt "Number of Bits for each Cell" + ?defValue "1" +) + +trAlignCellsVstickXY = hiCreateToggleField( + ?name 'trAlignCellsVstickXY + ?choices list( list( `stickX "x" ) ) + ?prompt "Stick Coordinates for" + ?defValue list( t ) +) + + +trAlignCellsVForm = hiCreateAppForm( + ?name 'trAlignCellsVForm + ?fields '( trAlignCellsVbitPitch trAlignCellsVnumBits trAlignCellsVstickXY ) + ?callback "trAlignCellsVCallBack( hiGetCurrentForm() )" +) + +; This is the callback function +procedure( trAlignCellsVCallBack( theForm ) + + let( ( x + y + bitPitch + numBits + ArrayHeight + stickX ) + + bitPitch = evalstring( theForm->trAlignCellsVbitPitch->value ) + numBits = evalstring( theForm->trAlignCellsVnumBits->value ) + ArrayHeight = bitPitch * numBits + stickX = trAlignCellsVForm->trAlignCellsVstickXY->stickX->value + + ArrayHeight = bitPitch * numBits + x = 0 + y = 0 + + println( ArrayHeight ) + + AlignCellsV( x y ArrayHeight stickX ) + + ); end let +); end procedure + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsNonOverlap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsNonOverlap.il new file mode 100644 index 0000000000..bc776c84c8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AlignCellsNonOverlap.il @@ -0,0 +1,70 @@ +; This Fuction is used to align all the selected cells on to the power grids +; It is only applicable for instances (cells), if other types (eg. rectangle) are +; selected, they will be filtered out by the skill code and automatically unselected + +procedure( AlignCellsNonOverlap( xGrid yGrid xOffset yOffset ) + + SelectedCellList = geGetSelSet( ) + + foreach( SelectedCell SelectedCellList + + if( SelectedCell->objType == "inst" + + then + + xCord = car( SelectedCell -> xy ) + yCord = car( cdr( SelectedCell -> xy )) + + ; Move to negative x direction + xDiff1 = (( xCord / xGrid ) - floor( xCord / xGrid )) * xGrid + + ; Move to negative y direction + yDiff1 = (( yCord / yGrid ) - floor( yCord / yGrid )) * yGrid + + ; Move to positive x direction + xDiff2 = (( xCord / xGrid ) - floor( ( xCord / xGrid ) + 1 )) * xGrid + + ; Move to positive y direction + yDiff2 = (( yCord / yGrid ) - floor( ( yCord / yGrid ) + 1 )) * yGrid + + ; Find the closest + if( abs( xDiff1 ) > abs( xDiff2 ) + then + xDiff = xDiff2 + else + xDiff = xDiff1 + ) + if( yDiff1 > abs( yDiff2 ) + then + yDiff = yDiff2 + else + yDiff = yDiff1 + ) + + dbMoveFig( SelectedCell, nil, list(-xDiff:-yDiff "R0")) + dbMoveFig( SelectedCell, nil, list(xOffset:yOffset "R0")) + + MoveCount = 1 + + while( length( dbGetOverlaps( geGetWindowCellView( ) SelectedCell->bBox nil ) ) > 1 + + yMove = MoveCount * yGrid * ( -1 ** MoveCount ) + + dbMoveFig( SelectedCell, nil, list(0:yMove "R0")) + + MoveCount++ + + ) + + else + + geDeselectObject( SelectedCell ) + ) ;if + + ) ;foreach + + +) ;procedure + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AnalysisLayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AnalysisLayout.il new file mode 100644 index 0000000000..9cec2911c0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/AnalysisLayout.il @@ -0,0 +1,333 @@ +; Analysis Layout +; +; Optional Parameters +; 1. WorkOnAll - "Work on All Cells" VS "Work on Selected Cells" +; 2. DebugOn - Print Debugging Messages +; 3. DatapathHeight +; 4. DatapathThreshold +; 5. ScanLine - Get Cells by performing Scan Lines from Left to Right (to reserve ordering) +; +; Global Variables + +TR_Floorplanner_Counter_Data = 0 +TR_Floorplanner_Counter_Ctrl = 0 +TR_Floorplanner_DatapathHeight = 0 + + +procedure( AnalysisLayout( @key + ( WorkOnAll t ) + ( DebugOn nil ) + ( DatapathHeight 0 ) + ( DatapathThreshold 0.4 ) + ( ScanLine nil ) + ) + + let( ( + SelectedCellDone + l_d_Selected l_d_Selected_temp + l_CellGroup + l_PredefinedPattern + FormNewPattern + D0StartIndex + Counter_Data Counter_Ctrl + CellGroup_New CellGroup_Old + Order_Old Order_New + ScanLine_bBox_original ScanLine_bBox_current + newPattern + ) + + SelectedCellDone = nil + FormNewPattern = nil + l_PredefinedPattern = nil + l_CellGroup = nil + Counter_Data = 0 + Counter_Ctrl = 0 + ScanLine_l_Cells = nil + + if( !WorkOnAll && !ScanLine + then + l_d_Selected = geGetSelectedSet() + ) + + if( WorkOnAll && !ScanLine + then + geSelectAllFig() + l_d_Selected = geGetSelectedSet() + ) + + ; Filter out non-instances + ; ========================= + l_d_Selected = setof( x l_d_Selected x->objType=="inst" ) + + + if( ScanLine + then + l_d_Selected_temp = geGetSelectedSet() + + ScanLine_bBox_original = geGetWindowCellView()->bBox + + DebugOn && printf( "AnalysisLayout --> Running ScanLines\n") + + for( i floor( caar( ScanLine_bBox_original )) floor( caadr( ScanLine_bBox_original )) + + ScanLine_bBox_current = list( + car( ScanLine_bBox_original ) + list( i+1 cadadr( ScanLine_bBox_original )) + ) + + geSingleSelectBox( geGetCellViewWindow( geGetWindowCellView()) t ScanLine_bBox_current ) + + l_d_Selected = geGetSelectedSet() + + if( !WorkOnAll + then + foreach( d_Selected l_d_Selected + if( member( d_Selected l_d_Selected_temp ) == nil + then + l_d_Selected = remove( d_Selected l_d_Selected ) + geDeselectFig( d_Selected ) + ) + + ) + + ); end if + + ScanLine_l_Cells = nconc( ScanLine_l_Cells setof( x l_d_Selected !member(x ScanLine_l_Cells))) + ) + l_d_Selected = ScanLine_l_Cells + ) + + foreach( d_Selected l_d_Selected + + SelectedCellDone = nil + + ; First match the pre-defined patterns + for( i 0 length( l_PredefinedPattern )-1 + + rexCompile( nth( i l_PredefinedPattern )) + if( rexExecute( d_Selected->name ) + then + if( DebugOn + then + printf( "AnalysisLayout --> Pattern %n: %s matches %s\n" + i + 1 + nth( i l_PredefinedPattern ) + d_Selected->name ) + ) + + SelectedCellDone = t + evalstring( sprintf( nil "CellGroup_%n = + list( car(CellGroup_%n) + cadr(CellGroup_%n) + caddr(CellGroup_%n) + cadddr(CellGroup_%n) + reverse( cons( + d_Selected + reverse( car( cddddr( CellGroup_%n))))))" + i + 1 + i + 1 + i + 1 + i + 1 + i + 1 + i + 1 + )) + + ) + + ); end for + + + ; Deal with 3-D Array + rexCompile( ConvertWildCardString( "*[*]*[*]*[*]*" )) + if( rexExecute( d_Selected->name ) && !SelectedCellDone + then + DebugOn && printf( "AnalysisLayout --> 3-D Array Found %s\n" d_Selected->name ) + SelectedCellDone = t + FormNewPattern = t + NewPatternDimension = 3 + NewPatternType = "Data" + NewPatternOrientation = "NA" + NewPatternHeight = cadadr( d_Selected->bBox ) - cadar( d_Selected->bBox ) + ) + + ; Deal with 2-D Array + rexCompile( ConvertWildCardString( "*[*]*[*]*" )) + if( rexExecute( d_Selected->name ) && !SelectedCellDone + then + DebugOn && printf( "AnalysisLayout --> 2-D Array Found %s\n" d_Selected->name ) + SelectedCellDone = t + FormNewPattern = t + NewPatternDimension = 2 + NewPatternType = "Data" + NewPatternOrientation = "HV" + NewPatternHeight = cadadr( d_Selected->bBox ) - cadar( d_Selected->bBox ) + ) + + ; Deal with 1-D Array + rexCompile( ConvertWildCardString( "*[*]*" )) + if( rexExecute( d_Selected->name ) && !SelectedCellDone + then + DebugOn && printf( "AnalysisLayout --> 1-D Array Found %s\n" d_Selected->name ) + SelectedCellDone = t + FormNewPattern = t + NewPatternDimension = 1 + NewPatternType = "Data" + NewPatternOrientation = "V" + NewPatternHeight = cadadr( d_Selected->bBox ) - cadar( d_Selected->bBox ) + ) + + ; Deal with the remaining cells + if( !SelectedCellDone + then + DebugOn && printf( "AnalysisLayout --> Single Cell Found %s\n" d_Selected->name ) + SelectedCellDone = t + FormNewPattern = t + NewPatternDimension = 0 + NewPatternType = "Ctrl" + NewPatternOrientation = "NA" + NewPatternHeight = cadadr( d_Selected->bBox ) - cadar( d_Selected->bBox ) + ) + + ; Compiling New Pattern for matching + if( FormNewPattern + then + ; Creat a New Pattern + rexCompile( ConvertWildCardString( "[+]" ?FullString nil )) + + newPattern = rexReplace( d_Selected->name + "\\\\[[0-9\\\\-]*\\\\]" + 0 ) + + newPattern = list( strcat( newPattern "$" ) ) + + l_PredefinedPattern = append( l_PredefinedPattern newPattern ) + + + +; l_PredefinedPattern = reverse( cons( rexReplace( d_Selected->name +; "\\\\[[0-9\\\\-]*\\\\]" +; 0 ) +; reverse( l_PredefinedPattern ) +; )) + + + + evalstring( sprintf( nil "CellGroup_%n = list( list( %n \"%s\" nil ) + list( \"%s\" -1 ) + %n \"%s\" list( d_Selected ))" + length( l_PredefinedPattern ) + NewPatternDimension + NewPatternOrientation + NewPatternType + NewPatternHeight + rexReplace( d_Selected->name "[+]" 0 ) + )) + + FormNewPattern = nil + ) + + ); end foreach + + + + ; ====================================================================================== + ; Concat all the CellGroup_n + ; ====================================================================================== + l_CellGroup = nil + + for( i 0 length( l_PredefinedPattern )-1 + evalstring( sprintf( nil "l_CellGroup = xcons( l_CellGroup CellGroup_%n )" i+1 )) + ) ;end for + l_CellGroup = reverse( l_CellGroup ) + + + ; ====================================================================================== + ; Post Processing + ; ====================================================================================== + + ; Calculate the Datapath Height + if( DatapathHeight <= 0 + + then + + TR_Floorplanner_DatapathHeight = 0 + + for( i 0 length(l_CellGroup)-1 + + TR_Floorplanner_DatapathHeight = max(TR_Floorplanner_DatapathHeight caddr(nth(i l_CellGroup))*length(car(cddddr(nth(i l_CellGroup))))) + + ); end foreach + + else + TR_Floorplanner_DatapathHeight = DatapathHeight + + + ); end if + + DebugOn && printf( "AnalysisLayout --> TR_Floorplanner_DatapathHeight = %n\n" TR_Floorplanner_DatapathHeight ) + DebugOn && printf( "AnalysisLayout --> DatapathThreshold = %n\n" DatapathThreshold ) + + ; Changing Cells Types "Data" <-> "Ctrl" if necessary + for( i 0 length(l_CellGroup)-1 + + Height = caddr(nth(i l_CellGroup))*length(car(cddddr(nth(i l_CellGroup)))) + + ; Changing from "Ctrl" to "Data" + if( Height > ( TR_Floorplanner_DatapathHeight*DatapathThreshold ) + then + + CellGroup_Old = nth(i l_CellGroup ) + CellGroup_New = subst( "Data" "Ctrl" nth(i l_CellGroup)) + l_CellGroup = subst( CellGroup_New CellGroup_Old l_CellGroup ) + ) + + ; Changing from "Data" to "Ctrl" + if( Height < ( TR_Floorplanner_DatapathHeight*DatapathThreshold ) + then + + CellGroup_Old = nth(i l_CellGroup ) + CellGroup_New = subst( "Ctrl" "Data" nth(i l_CellGroup)) + l_CellGroup = subst( CellGroup_New CellGroup_Old l_CellGroup ) + ) + + ) + + ; Add Ordering + for( i 0 length(l_CellGroup)-1 + + case( caadr( nth(i l_CellGroup )) + + ( "Data" + Counter_Data = Counter_Data + 1 + Counter_Current = Counter_Data + ) + + ( "Ctrl" + Counter_Ctrl = Counter_Ctrl + 1 + Counter_Current = Counter_Ctrl + ) + + ); end case + + CellGroup_Old = nth( i l_CellGroup ) + Order_Old = cadr( CellGroup_Old ) + Order_New = list( caadr( CellGroup_Old ) Counter_Current ) + + CellGroup_New = subst( Order_New Order_Old nth(i l_CellGroup)) + l_CellGroup = subst( CellGroup_New CellGroup_Old l_CellGroup ) + + ) + + + TR_Floorplanner_Counter_Data = Counter_Data + TR_Floorplanner_Counter_Ctrl = Counter_Ctrl + + l_CellGroup + + + );end let + +); end procedure + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/CompactCells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/CompactCells.il new file mode 100644 index 0000000000..f3e4335968 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/CompactCells.il @@ -0,0 +1,900 @@ +; This procedure compact/expand the layout horizontally ONLY +; +; Useful Skill Function +; ===================== +; dbProduceOverlapInst( geGetWindowCellView( ) car( geGetSelectedSet( ))->bBox ) +; setof( x ScanLine_l_Cells_next !member(x ScanLine_l_Cells_current)) +; +; Notice +; ====== +; The procedure will fail to operate correctly if +; (1) there are instances within another instances + + +; Setting Global Snapping + +envSetVal("layout" "xSnapSpacing" `float 0.01) +envSetVal("layout" "ySnapSpacing" `float 0.01) + + +procedure( CompactCells( @key + ( WorkOnAll nil ) + ( DebugOn t ) + ( StepByStep nil ) + ( AlignToGrid list( 0.5:9.6 5:9.6 )) + ) + + let( ( returnValue + ScanLine_l_Cells_current + ScanLine_l_OverlappedCells + OffSet + SkipLoop + IsFinish + l_ValidCells + StepByStepDialogBox + NeighborList NeighborID NeighborOffSet + tempCell Counter + IsMidLevelCell overwrite_xy CellUnderTest + ) + + ScanLine_l_Cells_current = nil + IsFinish = nil + + DebugOn && printf( "CompactCells --> Start Procedure\n") + + ScanLine_l_Cells_current = GetOrderedCellList( ?WorkOnAll WorkOnAll + ?AlignToGrid AlignToGrid + ) + + + ; Forming the Valid Cell List + l_ValidCells = foreach( mapcar d_Cell ScanLine_l_Cells_current + + car( d_Cell ) + + ); end foreach + + geDeselectAllFig( ) + + + foreach( ScanLine_Cell ScanLine_l_Cells_current + + + println( 888 ) + + ScanLine_Cell = car( ScanLine_Cell ) + + ; ================================= + ; Deals with Compaction to the Left + ; ================================= + + NeighborList = dbGetNeighbor( geGetWindowCellView() + list( caar(ScanLine_Cell->bBox):cadar(ScanLine_Cell->bBox)+0.001 + caadr(ScanLine_Cell->bBox):cadadr(ScanLine_Cell->bBox)-0.001) + "left" + ) + + DebugOn && printf( "CompactCells --> ========================================================================== \n" ) + + if( NeighborList && car( NeighborList ) != 0 + then + NeighborID = cadr( NeighborList ) + NeighborOffSet = car( NeighborList ) + + DebugOn && printf( "CompactCells --> Perform Compaction: \"%s\" has \"%s\" on the left with an OffSet = %num\n" + ScanLine_Cell->name + NeighborID->name + NeighborOffSet + ) + +; MoveExactAbuttedGroup( ScanLine_Cell -NeighborOffSet 0 ScanLine_l_Cells_current ) + + dbMoveFig( ScanLine_Cell nil list(-NeighborOffSet:0 "R0")) + + ); end if + + + + + + + + if( StepByStep + then + StepByStepDialogBox = hiDisplayAppDBox( + ?name 'StepByStepDialogBox + ?dboxText "Press to Continue" + ?dialogType hicMessageDialog + ?dialogStyle 'systemModal + ?buttonLayout 'OKCancel + ) + ) + + + + + + + + + + + + + ; ================================= + ; Post-Compaction Alignment + ; ================================= + + ; Test to see if it is one of the tempCell + if( ScanLine_Cell->viewName == "layout.compactor" + then + CellUnderTest = car( leSearchHierarchy( ScanLine_Cell->master + ScanLine_Cell->master->bBox + 0 + "inst" + nil + )) + overwrite_xy = list( car( ScanLine_Cell->xy) + car( CellUnderTest->xy ) + cadr( ScanLine_Cell->xy) + cadr( CellUnderTest->xy )) + else + CellUnderTest = ScanLine_Cell + overwrite_xy = ScanLine_Cell->xy + ) + + + if( AlignToGrid + then + IsMidLevelCell = setof( x + leSearchHierarchy( CellUnderTest->master + CellUnderTest->master->bBox + 0 + "inst" + nil + ) + ( x->libName != "tsmc13lg" && x->libName != "gate" && x->libName != "stack" ) + ) + + + + + ; Filter out SLACK + if( IsMidLevelCell + then + rexCompile( "lib.buffer.slack" ) + IsMidLevelCell = !rexExecute( CellUnderTest->cellName ) + ) + + + ; Filter out TOKEN + if( IsMidLevelCell + then + rexCompile( "lib.buffer.token" ) + IsMidLevelCell = !rexExecute( CellUnderTest->cellName ) + ) + + ; Filter out CTREE + if( IsMidLevelCell + then + rexCompile( "lib.util.ctree" ) + IsMidLevelCell = !rexExecute( CellUnderTest->cellName ) + ) + + + if( IsMidLevelCell + then + DebugOn && printf( "CompactCells --> Post-Compaction Alignment: \"%s\" is a mid-level cell\n" CellUnderTest->name ) +; MoveAndSnap( "ARAV" +; ?overwrite_fig ScanLine_Cell +; ?overwrite_xSnap caadr( AlignToGrid ) +; ?overwrite_ySnap cadadr( AlignToGrid ) +; ?overwrite_xy overwrite_xy +; ) + + else + DebugOn && printf( "CompactCells --> Post-Compaction Alignment: \"%s\" is a leaf cell\n" CellUnderTest->name ) +; MoveAndSnap( "ARAV" +; ?overwrite_fig ScanLine_Cell +; ?overwrite_xSnap caar( AlignToGrid ) +; ?overwrite_ySnap cadar( AlignToGrid ) +; ?overwrite_xy overwrite_xy +; ) + + ) + + ) + + + +; Hang up here + + + + + if( StepByStep + then + StepByStepDialogBox = hiDisplayAppDBox( + ?name 'StepByStepDialogBox + ?dboxText "Press to Continue" + ?dialogType hicMessageDialog + ?dialogStyle 'systemModal + ?buttonLayout 'OKCancel + ) + ) + + + + + + + + + + ; ================================= + ; Deals with Expansion to the Right + ; ================================= + +; ScanLine_l_OverlappedCells = dbProduceOverlapInst( geGetWindowCellView( ) ScanLine_Cell->bBox 1:1 ) + ScanLine_l_OverlappedCells = dbProduceOverlapInst( geGetWindowCellView( ) ScanLine_Cell->bBox ) + +; println( ScanLine_l_OverlappedCells ) + + + + ScanLine_l_OverlappedCells = setof( x ScanLine_l_OverlappedCells member(x l_ValidCells)) + + SkipLoop = nil + + foreach( ScanLine_OverlappedCell ScanLine_l_OverlappedCells + + if( SkipLoop && !member( ScanLine_OverlappedCell l_ValidCells ) + then + OffSet = 0 + else + OffSet = GetOffSet( ScanLine_Cell + ScanLine_OverlappedCell + ) + ) + + + if( OffSet != 0 + then + + if( StepByStep + then + StepByStepDialogBox = hiDisplayAppDBox( + ?name 'StepByStepDialogBox + ?dboxText "Press to Continue" + ?dialogType hicMessageDialog + ?dialogStyle 'systemModal + ?buttonLayout 'OKCancel + ) + ) + + if( OffSet > 0 + then + + ; MoveExactAbuttedGroup( ScanLine_OverlappedCell OffSet 0 ScanLine_l_Cells_current ) + + + dbMoveFig( ScanLine_OverlappedCell nil list(OffSet:0 "R0")) + + DebugOn && printf( "\n" ) + + DebugOn && printf( "CompactCells --> \"%s\" overlapped with \"%s\" ==> \"%s\" is moved right by %n\n" + ScanLine_OverlappedCell->name + ScanLine_Cell->name + ScanLine_OverlappedCell->name + OffSet) + else + ; EXCEPTION + printf( "CompactCells --> ERROR!!! OffSet (%n) must be non-negative\n" OffSet) + + ); end if + ) + + ); end foreach + + ); end foreach + + + + ; Get Inverse of l_ValidCells + geSelectAllFig( ) + l_ValidCells = setof( x geGetSelectedSet( ) !member( x l_ValidCells )) + geDeselectAllFig( ) + + + ; Flatten All the tempCells + geSelectAllFig( ) + foreach( tempCell setof( x geGetSelectedSet( ) x->viewName=="layout.compactor") + dbFlattenInst( tempCell 1 ) + ) + + ; Delete All tempCells in your library + Counter = 0 + tempCell = t + while( tempCell + + + tempCell = ddGetObj( geGetWindowCellView()->libName + sprintf( nil "tempCell%n" Counter ) + "layout.compactor" + ) + + tempCell && ddDeleteLocal( tempCell ) + + Counter = Counter + 1 + + ) + + + ; Select back all the ValidCells + geSelectAllFig( ) + l_ValidCells = setof( x geGetSelectedSet( ) !member( x l_ValidCells )) + geDeselectAllFig( ) + + + foreach( ValidCells l_ValidCells + + geSelectFig( ValidCells ) + + ); end foreach + + dbComputeBBox( geGetWindowCellView()) + + + ); end let + +); end procedure + + +; ============================================================================================================= +; This is a simple procedure that you have to run if you want it see if the overlap is due to +; exact bBox abutment or real overlap +; +; This procedure is NOT meant to use alone. It is serving as a PIPE to the result provided by +; "dbProduceOverlapInst" or similar function +; +; Three Types of returnValue +; (1) >0 - Two objects are overlapped, object on the right will got moved by an offset=returnValue +; (2) 0 - Two objects are only abutting, should not do anything +; (3) <0 - One Object is within the other one, the smaller object will be moved by an offeset=abs(returnValue) +; + +procedure( GetOffSet( d_CellA d_CellB + @key ( DebugOn nil )) + + let(( bBox_A bBox_B + returnValue ) + + bBox_A = d_CellA->bBox + bBox_B = d_CellB->bBox + + + ;========================== + ;||| Case (2)(3a)(3b) ||| + ;========================== + if( caar( bBox_A ) == caadr( bBox_B ) || + caar( bBox_B ) == caadr( bBox_A ) || + cadar( bBox_A ) == cadadr( bBox_B ) || + cadar( bBox_B ) == cadadr( bBox_A ) || + d_CellA == d_CellB + + then + returnValue = 0 + ; DebugOn && printf( "GetOffSet --> \"%s\" and \"%s\" are abutting\n" d_CellA->name d_CellB->name ) + + else + + ;=========================== + ;||| Case (1)(3a)(3b) ||| + ;=========================== + returnValue = caadr( bBox_A ) - caar( bBox_B ) + DebugOn && printf( "GetOffSet --> Case (1) \"%s\" and \"%s\" are overlapping\n" d_CellA->name d_CellB-> name ) + + + ); end if Case 2 + + returnValue + + + ); end let + +); end procedure + + + + +procedure( GetOrderedCellList( @key ( WorkOnAll t ) + ( AlignToGrid list( 0.5:9.6 5:9.6 )) + ( DebugOn t ) + ( FilterBigCells t ) + ( GroupCells t ) + ) + let(( + l_d_Cell + bBox_A + bBox_B + SkipLoop + Counter l_AddedCell l_GroupCell + returnValue + ) + + d_OverlappedCell = nil + + if( WorkOnAll + then + geSelectAllFig( ) + ); end if + + ; Only get objType == "inst" + l_d_Cell = setof( x geGetSelectedSet( ) x->objType=="inst" ) + + + ; Align All Objects + geSelectAllFig( ) + SuperMoveAndSnap( "A" ?AlignToGrid AlignToGrid ?DebugOn nil ) + geDeselectAllFig( ) + + ; GroupCells + Counter = 0 + l_AddedCell = nil + + if( GroupCells + then + foreach( d_Cell l_d_Cell + + ; l_GroupCell = setof( x l_d_Cell ( caar(d_Cell->bBox)==caar(x->bBox) && caadr(d_Cell->bBox)==caadr(x->bBox) )) + + if( d_Cell->name + then + geDeselectAllFig( ) + SelectAbuttedGroup( d_Cell ) + l_GroupCell = geGetSelectedSet( ) + geDeselectAllFig( ) + + if( length(l_GroupCell) > 1 + then + l_AddedCell = cons( leMakeCell( l_GroupCell + geGetWindowCellView()->libName + sprintf( nil "tempCell%n" Counter) + "layout.compactor" t + ) + l_AddedCell + ) + + Counter = Counter + 1 + + l_d_Cell = setof( x l_d_Cell !member( x l_GroupCell )) + ) + ) + + ); end foreach + + geSelectAllFig( ) + l_AddedCell = setof( x geGetSelectedSet( ) member( x->master l_AddedCell)) + + l_d_Cell = append( l_d_Cell l_AddedCell ) + + ) + + + ; Apply x-coordinate of the left edge of the bBox for sorting db -> list( x db ) + l_d_Cell = foreach( mapcar d_Cell l_d_Cell + + list( caar( d_Cell->bBox ) d_Cell ) + + ); end foreach + + + + ; Sort by car + l_d_Cell = sortcar( l_d_Cell `lessp) + + + ; Rearrange from list( x db ) to list( db x ) + l_d_Cell = foreach( mapcar d_Cell l_d_Cell + + list( cadr( d_Cell ) car( d_Cell )) + + ); end foreach + + if( FilterBigCells + then + foreach( d_Cell l_d_Cell + + bBox_A = car(d_Cell)->bBox + + SkipLoop = nil + + foreach( CELL dbProduceOverlapInst( geGetWindowCellView( ) bBox_A 0:0 ) + + if( !SkipLoop + then + bBox_B = CELL->bBox + + if( ( caar( bBox_A ) <= caar( bBox_B ) && + caadr( bBox_A ) >= caadr( bBox_B ) && + cadar( bBox_A ) <= cadar( bBox_B ) && + cadadr( bBox_A ) >= cadadr( bBox_B ) && + car(d_Cell) != CELL + ) + + then + DebugOn && printf( "GetOrderedCellList --> \"%s\" is filtered since it completely contains \"%s\" \n" + car(d_Cell)->name + CELL->name ) + + l_d_Cell = remove( d_Cell l_d_Cell ) + + geDeselectAllFig( ) + geSelectFig( car( d_Cell ) ) + + Old_x = car( car( d_Cell )->xy) + Old_y = cadr( car( d_Cell )->xy) + +; if( AlignToGrid +; then +; ; Align to Grid +; SuperMoveAndSnap( "A" ?AlignToGrid AlignToGrid ?DebugOn nil ) +; SuperMoveAndSnap( "L" ?AlignToGrid AlignToGrid ?DebugOn nil ) +; SuperMoveAndSnap( "R" ?AlignToGrid AlignToGrid ?DebugOn nil ) +; SuperMoveAndSnap( "U" ?AlignToGrid AlignToGrid ?DebugOn nil ) +; SuperMoveAndSnap( "D" ?AlignToGrid AlignToGrid ?DebugOn nil ) +; ) + + geDeselectAllFig( ) + + SkipLoop = t + ) + ) + + ); end foreach + + + ); end foreach + ); end if + + + + if( DebugOn + then + printf( "GetOrderedCellList --> ") + foreach( d_Cell l_d_Cell + printf( "%s " car(d_Cell)->name ) + ); end foreach + printf( "\n") + + ); end if + + l_d_Cell + + ); end let + +); end procedure + + + +procedure( SelectAbuttedGroup( d_CellA + @key ( ProcessTop t ) + ( ProcessBottom t ) + ( LinkedVertical t ) + ( DebugOn nil ) + ) + + let(( returnValue + l_d_Cell_Overlapped + bBox_A bBox_B + ) + + returnValue = nil + + geSelectFig( d_CellA ) + + bBox_A = d_CellA->bBox + + l_d_Cell_Overlapped = dbProduceOverlapInst( geGetWindowCellView( ) bBox_A ) + + DebugOn && printf( "%s " d_CellA->name ) + + foreach( d_CellB l_d_Cell_Overlapped + + bBox_B = d_CellB->bBox + + if( cadar( bBox_B ) == cadadr( bBox_A ) && + caar( bBox_A ) == caar( bBox_B ) && + caadr( bBox_B ) == caadr( bBox_A ) && + d_CellA != d_CellB && ProcessTop + + then + returnValue = t + CellTop = SelectAbuttedGroup( d_CellB ?ProcessTop t ?ProcessBottom nil ) + + else + + if( cadar( bBox_A ) == cadadr( bBox_B ) && + caar( bBox_A ) == caar( bBox_B ) && + caadr( bBox_B ) == caadr( bBox_A ) && + d_CellA != d_CellB && ProcessBottom + + then + returnValue = t + CellBottom = SelectAbuttedGroup( d_CellB ?ProcessTop nil ?ProcessBottom t ) + ); end if + + ); end if + + ); end foreach + + returnValue + + ); end let + +); end procedure + +;SelectAbuttedGroup( car( geGetSelectedSet( ))) + + + + + + + +; Global Variable +CellMap = nil + +procedure( GenerateCellMap( @key + ( CellUnderTest geGetWindowCellView( ) ) + ( CurrentLevel 0 ) + ( Depth 32 ) + ( DebugOn nil ) + ) + + let(( returnValue + l_d_Cell + ) + + returnValue = t + l_d_Cell = nil + + + ; ========================== + ; Generate List for this level + ; ========================== + foreach( d_Cell CellUnderTest->instances + if( !member( d_Cell->master l_d_Cell ) + then + l_d_Cell = cons( d_Cell->master l_d_Cell ) + ) + ) + + + ; ==================================== + ; Continue ONLY if l_d_Cell is not nil + ; ==================================== + if( l_d_Cell + + then + + ; Append to Global List + CellMap = cons( list( CurrentLevel CellUnderTest l_d_Cell ) CellMap ) + + + ; For Debugging Purpose ONLY + if( DebugOn + then + printf( "GenerateCellMap --> %2n : %s ==> " CurrentLevel CellUnderTest->cellName ) + foreach( d_Cell l_d_Cell + printf( "\"%s\" " d_Cell->cellName ) + ) + printf( "\n" ) + ); end if + + ; Resursive Calls + foreach( d_Cell l_d_Cell + + if( CurrentLevel + 1 <= Depth + then + GenerateCellMap( ?CellUnderTest d_Cell + ?CurrentLevel CurrentLevel+1 + ?Depth Depth + ) + ) + + ); end foreach + + + + ); end if + + returnValue + + ); end let + +); end procedure + + + +procedure( GenerateCellTree( @key + ( CellUnderTest geGetWindowCellView( ) ) + ( Depth 32 ) + ( DebugOn nil ) + ( WithDuplicate nil ) + ) + + let(( cellTree + currentLevel + l_d_CellatAllLevels + ) + + cellTree = nil + currentLevel = Depth + l_d_CellatAllLevels = nil + + + ; Globals + CellMap = nil + + GenerateCellMap( ?CellUnderTest CellUnderTest + ?Depth Depth + ) + + + declare( l_d_CellatLevel[Depth+1] ) + + for( i 0 Depth + l_d_CellatLevel[i] = nil + ) + + foreach( l_d_Cell CellMap + + if( caddr( l_d_Cell ) + then + foreach( d_Cell caddr( l_d_Cell ) + + if( !member( d_Cell l_d_CellatLevel[car(l_d_Cell)] ) + then + l_d_CellatLevel[car(l_d_Cell)] = cons( d_Cell l_d_CellatLevel[car(l_d_Cell)] ) + ) + + if( !member( d_Cell l_d_CellatAllLevels ) + then + l_d_CellatAllLevels = cons( d_Cell l_d_CellatAllLevels ) + ) + + ); end foreach + ); end if + + ); end foreach + + + ; Get rid of duplicates on every levels + if( !WithDuplicate + then + while( currentLevel >= 0 + + l_d_CellatLevel[currentLevel] = setof( x l_d_CellatLevel[currentLevel] member( x l_d_CellatAllLevels )) + l_d_CellatAllLevels = setof( x l_d_CellatAllLevels !member( x l_d_CellatLevel[currentLevel] )) + currentLevel = currentLevel - 1 + + ); end while + ); end if + + + for( i 0 Depth + cellTree = append( cellTree list( list( i l_d_CellatLevel[i]))) + ) + + cellTree + + ); end let + + +); end procedure + + + + +; ============================================================================ +; Hierarchical Version of CompactCells +; ============================================================================ +; Depth = -1: work on current cell only (CellUnderTest) +; Depth = 0: work on all children cell at current level (CellUnderTest + Level 0 Cells) +; +; If Depth >=0 ==> WorkOnAll Parameter has NO effect + +procedure( CompactCellsResursive( @key + ( Depth 32 ) + ( WorkOnAll nil ) + ( AlignToGrid list( 0.5:9.6 5:9.6 )) + + ( AutoSave nil ) + ( CellUnderTest geGetWindowCellView( ) ) + ( DebugOn nil ) + ( StepByStep nil ) + ) + + let(( returnValue + CellTree + currentLevel + ) + + libName = CellUnderTest->libName + cellName = CellUnderTest->cellName + viewName = CellUnderTest->viewName + + ; Local + returnValue = t + currentLevel = Depth + + if( Depth >= 0 + then + CellTree = GenerateCellTree( ?CellUnderTest CellUnderTest + ?Depth Depth + ?WithDuplicate nil + ) + WorkOnAll = t + ) + + while( currentLevel >= 0 + + foreach( d_Cell cadr( assoc( currentLevel CellTree )) + + DebugOn && printf( "CompactCellsResursive --> CompactCells on \"%s\" \n" d_Cell->cellName ) + + geOpen( ?window geGetCellViewWindow( geGetWindowCellView( ) ) + ?lib d_Cell->libName + ?cell d_Cell->cellName + ?view d_Cell->viewName + ?viewType "maskLayout" + ?mode "a" + ) + + CompactCells( ?WorkOnAll WorkOnAll + ?AlignToGrid AlignToGrid + ) + + dbComputeBBox( geGetWindowCellView()) + + geRefresh( ) + + AutoSave && geSave( ) + + ); end foreach + + currentLevel = currentLevel - 1 + + ); end while + + ; Work On CellUnderTest + + DebugOn && printf( "CompactCellsResursive --> CompactCells on \"%s\" \n" cellName ) + + + if( Depth >= 0 + then + geOpen( ?window geGetCellViewWindow( geGetWindowCellView( ) ) + ?lib libName + ?cell cellName + ?view viewName + ?viewType "maskLayout" + ?mode "a" + ) + ) + + + CompactCells( ?WorkOnAll WorkOnAll + ?AlignToGrid AlignToGrid + ) + + geRefresh( ) + AutoSave && geSave( ) + + returnValue + + ); end let + +); end procedure + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawIO.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawIO.il new file mode 100644 index 0000000000..10623c08d9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawIO.il @@ -0,0 +1,1669 @@ +; This Fuction is used to initialize the entire IO Pad Frame +; This first function does nothing but just create and display the form +procedure( TR_DrawIO( ) + + let( ( TR_DrawIO_SignalListFile + TR_DrawIO_ChipHeight + TR_DrawIO_ChipWidth + TR_DrawIO_IOVDD + TR_DrawIO_IOVSS + TR_DrawIO_CoreVDD + TR_DrawIO_CoreVSS + TR_DrawIO_theForm + ) + + ; Create Fields for the Form + TR_DrawIO_SignalListFile = hiCreateStringField( + ?name 'TR_DrawIO_SignalListFile + ?prompt "Signal List File" + ?defValue "tc3_pinout.txt" + ?editable t ) + + TR_DrawIO_ChipHeight = hiCreateStringField( + ?name 'TR_DrawIO_ChipHeight + ?prompt "Chip Height (in millimeter)" + ?defValue "5" + ?editable t ) + + TR_DrawIO_ChipWidth = hiCreateStringField( + ?name 'TR_DrawIO_ChipWidth + ?prompt "Chip Width (in millimeter)" + ?defValue "5" + ?editable t ) + + TR_DrawIO_MinDriverSpacing = hiCreateStringField( + ?name 'TR_DrawIO_MinDriverSpacing + ?prompt "MinDriverSpacing (in micron)" + ?defValue "60" + ?editable t ) + + + ; This is the Format + ; IOGenericType = list( libName cellName viewName prOrigin prWidth prHeight list( PinName x:y )) + + + TR_DrawIO_IOVDD = hiCreateStringField( + ?name 'TR_DrawIO_IOVDD + ?prompt "IO Pad VDD Info " + ?defValue "IOVDD = list( \"fb_tpz013g2_110c\" \"PVDD2DGZ\" \"layout\" 0:0 35 246 \"VD33\" )" + ?editable nil ) + + TR_DrawIO_IOVSS = hiCreateStringField( + ?name 'TR_DrawIO_IOVSS + ?prompt "IO Pad VSS Info " + ?defValue "IOVSS = list( \"fb_tpz013g2_110c\" \"PVSS2DGZ\" \"layout\" 0:0 35 246 \"VSSPST\" )" + ?editable nil ) + + TR_DrawIO_CoreVDD = hiCreateStringField( + ?name 'TR_DrawIO_CoreVDD + ?prompt "Core VDD Info " + ?defValue "CoreVDD = list( \"fb_tpz013g2_110c\" \"PVDD1DGZ\" \"layout\" 0:0 35 246 \"Vdd\" list( \"VDD\" 17.6:245.9 ) )" + ?editable nil ) + + TR_DrawIO_CoreVSS = hiCreateStringField( + ?name 'TR_DrawIO_CoreVSS + ?prompt "Core VSS Info " + ?defValue "CoreVSS = list( \"fb_tpz013g2_110c\" \"PVSS1DGZ\" \"layout\" 0:0 35 246 \"GND\" list( \"VSS\" 17.6:245.9 ) )" + ?editable nil ) + + TR_DrawIO_DigitalSignalInputType1 = hiCreateStringField( + ?name 'TR_DrawIO_DigitalSignalInputType1 + ?prompt "Digital Signal Input Type1 " + ?defValue "DSI1 = list( \"fb_tpz013g2_110c\" \"PDIDGZ\" \"layout\" 0:0 35 246 list( \"C\" 8.2:245.9 ) list( \"PAD\" 17.2:-5.6 ) )" + ?editable nil ) + + TR_DrawIO_DigitalSignalOutputType1 = hiCreateStringField( + ?name 'TR_DrawIO_DigitalSignalOutputType1 + ?prompt "Digital Signal Output Type1 " + ?defValue "DSO1 = list( \"fb_tpz013g2_110c\" \"PDO02CDG\" \"layout\" 0:0 35 246 list( \"I\" 4.6:245.9 ) list( \"PAD\" 17.2:-5.6 ) )" + ?editable nil ) + + TR_DrawIO_AnalogSignalType1 = hiCreateStringField( + ?name 'TR_DrawIO_AnalogSignalType1 + ?prompt "Analog Signal Type1 " + ?defValue "list( \"chip.tc3.padframe\" \"PRT08DGZ\" \"layout\" 0:0 35 246 list( \"I\" 4.6:245.9 ) list( \"PAD\" 17.2:-5.6 ) list( \"OEN\" 18.6:245.9 )" + ?editable nil ) + + TR_DrawIO_Topology = hiCreateStringField( + ?name 'TR_DrawIO_Topology + ?prompt "Enter Desired Topology" + ?defValue "list( \"S\" \"P\" )" + ?editable t ) + + TR_DrawIO_TopologyAdvancedSpacing = hiCreateRadioField( + ?name 'TR_DrawIO_TopologyAdvancedSpacing + ?choices list( "None" "Max Feeder" "Max Power" ) + ?defValue "None" + ?prompt "Advanced Spacing?" + ?callback list( "TR_DrawIO_TopologyAdvancedSpacing_CB( hiGetCurrentForm() ) " + "TR_DrawIO_TopologyAdvancedSpacing_CB( hiGetCurrentForm() ) " + "TR_DrawIO_TopologyAdvancedSpacing_CB( hiGetCurrentForm() ) " ) + ) + + TR_DrawIO_CreatePadList = hiCreateToggleField( + ?name 'TR_DrawIO_CreatePadList + ?choices list( list( `IOVDD "IOVDD" ) list( `IOVSS "IOVSS" ) list( `CoreVDD "CoreVDD" ) list( `CoreVSS "CoreVSS" ) ) + ?numSelect 4 + ?defValue list( t t t t ) + ?prompt "Create Power Pad List" + ) + + TR_DrawIO_GenCDL = hiCreateToggleField( + ?name 'TR_DrawIO_GenCDL + ?choices list( list( `GenCDL nil ) ) + ?numSelect 1 + ?defValue list( nil ) + ?prompt "Generate CDL File?" + ?callback list( "TR_DrawIO_GenCDL_CB( hiGetCurrentForm() ) ") + ) + + TR_DrawIO_GenCAST = hiCreateToggleField( + ?name 'TR_DrawIO_GenCAST + ?choices list( list( `GenCAST nil ) ) + ?numSelect 1 + ?defValue list( nil ) + ?prompt "Generate CAST File?" + ?callback list( "TR_DrawIO_GenCAST_CB( hiGetCurrentForm() ) ") + ) + + ; Create the Form + TR_DrawIO_theForm = hiCreateAppForm( + ?name 'TR_DrawIO_theForm + ?fields '( TR_DrawIO_SignalListFile + TR_DrawIO_ChipHeight + TR_DrawIO_ChipWidth + TR_DrawIO_MinDriverSpacing + TR_DrawIO_IOVDD + TR_DrawIO_IOVSS + TR_DrawIO_CoreVDD + TR_DrawIO_CoreVSS + TR_DrawIO_DigitalSignalInputType1 + TR_DrawIO_DigitalSignalOutputType1 + TR_DrawIO_AnalogSignalType1 + TR_DrawIO_Topology + TR_DrawIO_TopologyAdvancedSpacing + TR_DrawIO_CreatePadList + TR_DrawIO_GenCDL + TR_DrawIO_GenCAST + ) + ?initialSize t + ?callback "TR_DrawIO_processDataCB( hiGetCurrentForm() )" + ) + + ; Display the Form + hiDisplayForm( TR_DrawIO_theForm ) + + ); end let + +); end procedure + + +; This second function is the actual one that process the data +procedure( TR_DrawIO_processDataCB( theForm ) + + let( ( SignalListFile + ChipHeight + ChipWidth + IOVDD + IOVSS + CoreVDD + CoreVSS + DSI1 + DSO1 + AS1 + inPort + H + x + y + CoreVDDNetID CoreVDDNetName CoreVDDPin + CoreVSSNetID CoreVSSNetName CoreVSSPin ) + + SignalListFile = theForm->TR_DrawIO_SignalListFile->value + ChipHeight_um = evalstring( theForm->TR_DrawIO_ChipHeight->value ) * 1000 + ChipWidth_um = evalstring( theForm->TR_DrawIO_ChipWidth->value ) * 1000 + MinDriverSpacing = evalstring( theForm->TR_DrawIO_MinDriverSpacing->value ) + evalstring( theForm->TR_DrawIO_IOVDD->value ) + evalstring( theForm->TR_DrawIO_IOVSS->value ) + evalstring( theForm->TR_DrawIO_CoreVDD->value ) + evalstring( theForm->TR_DrawIO_CoreVSS->value ) + evalstring( theForm->TR_DrawIO_DigitalSignalInputType1->value ) + evalstring( theForm->TR_DrawIO_DigitalSignalOutputType1->value ) + AS1 = evalstring( theForm->TR_DrawIO_AnalogSignalType1->value ) + + ; Power Pad Ordering and Counter + PowerPadList = nil + + if( theForm->TR_DrawIO_CreatePadList->CoreVSS->value + then + PowerPadList = cons( "CoreVSS" PowerPadList ) + ) + if( theForm->TR_DrawIO_CreatePadList->CoreVDD->value + then + PowerPadList = cons( "CoreVDD" PowerPadList ) + ) + if( theForm->TR_DrawIO_CreatePadList->IOVDD->value + then + PowerPadList = cons( "IOVDD" PowerPadList ) + ) + if( theForm->TR_DrawIO_CreatePadList->IOVSS->value + then + PowerPadList = cons( "IOVSS" PowerPadList ) + ) + + ; PowerPadList = list( "IOVDD" "IOVSS" "CoreVDD" "CoreVSS" ) + + + if( theForm->TR_DrawIO_Topology->enabled == t + then + l_IO_Topology = evalstring( theForm->TR_DrawIO_Topology->value ) + else + l_IO_Topology = list( "S" "P" ) + ) + + case( theForm->TR_DrawIO_TopologyAdvancedSpacing->value + ("Max Feeder" + MaxFeeder = t + MaxPower = nil + ) + ("Max Power" + MaxFeeder = t + MaxPower = t + ) + ("None" + MaxFeeder = nil + MaxPower = nil + ) + ( t + MaxFeeder = nil + MaxPower = nil + ) + + ); end case + + + GenCDL = theForm->TR_DrawIO_GenCDL->GenCDL->value + GenCDL && ( CDLFileName = theForm->TR_DrawIO_CDLFileName->value ) + GenCAST = theForm->TR_DrawIO_GenCAST->GenCAST->value + GenCAST && ( CASTFileName = theForm->TR_DrawIO_CASTFileName->value ) + + ; Need to be put in the Form later + + BONDIZ40 = list( "fb_tpz013g2_110c" "PADIZ40" "layout" 17:0 35 88.8 ) + CORPAD = list( "fb_tpz013g2_110c" "PCORNERDGZ" "layout" 0:0 246 246 89.2 89.2 ) + + F0_005 = list( "fb_tpz013g2_110c" "PFEED0_005Z" "layout" 0:0 0.005 246 ) + F0_01 = list( "fb_tpz013g2_110c" "PFEED0_01Z" "layout" 0:0 0.01 246 ) + F0_1 = list( "fb_tpz013g2_110c" "PFEED0_1Z" "layout" 0:0 0.1 246 ) + F1 = list( "fb_tpz013g2_110c" "PFEED1Z" "layout" 0:0 1 246 ) + F5 = list( "fb_tpz013g2_110c" "PFEED5Z" "layout" 0:0 5 246 ) + F10 = list( "fb_tpz013g2_110c" "PFEED10Z" "layout" 0:0 10 246 ) + F20 = list( "fb_tpz013g2_110c" "PFEED20Z" "layout" 0:0 20 246 ) + F60 = list( "testspace2" "PFEED60Z" "layout" 0:0 60 246 ) + + ;================================================================================= + ; COUNTERS + ;================================================================================= + FeederCellCounter = 0 + TotalNumberOfSignals = 0 + PowerPadCounter = 0 + IOVDDCounter = 0 + IOVSSCounter = 0 + CoreVDDCounter = 0 + CoreVSSCounter = 0 + SignalPadCounter = 0 + TempCounter = 0 + + ;================================================================================= + + + H = "TR_DrawIO_processDataCB --> " + x = 0 + y = 0 + drawFirstCorner = t + currentOri = "R0" + nextOri = "R0" + + ; This defines the values for parameters related to the pads for the Core Power + CoreVDDNetName = car( cdddr( cdddr( CoreVDD ))) + CoreVSSNetName = car( cdddr( cdddr( CoreVSS ))) + CoreVDDNetID = nil + CoreVSSNetID = nil + CoreVDDPin = cadr( cdddr( cdddr( CoreVDD ))) + CoreVSSPin = cadr( cdddr( cdddr( CoreVSS ))) + + ; This defines the values for parameters related to the pads for the IO Power + IOVDDNetName = car( cdddr( cdddr( IOVDD ))) + IOVSSNetName = car( cdddr( cdddr( IOVSS ))) + + ; This defines the values for parameters related to the pads for DSO1 + DSO1_IPin = car( cdddr( cdddr( DSO1 ))) + DSO1_PADPin = cadr( cdddr( cdddr( DSO1 ))) + + ; This defines the values for parameters related to the pads for DSI1 + DSI1_CPin = car( cdddr( cdddr( DSI1 ))) + DSI1_PADPin = cadr( cdddr( cdddr( DSI1 ))) + + ; This defines the values for parameters related to the pads for AS1 + AS1_CPin = car( cdddr( cdddr( AS1 ))) + AS1_PADPin = cadr( cdddr( cdddr( AS1 ))) + AS1_OENPin = caddr( cdddr( cdddr( AS1 ))) + + ; This is used to check if it is the end of file + EndOfFile = nil + + ; These parameters are used to deal with corner pads + CORPAD_extraOffsetX = cadddr( cdddr( CORPAD )) + CORPAD_extraOffsetY = cadddr( cdddr( cdr( CORPAD ))) + CORPAD_prWidth = cadddr( cdr( CORPAD )) + CORPAD_prHeight = cadddr( cddr( CORPAD )) + + ; We need to offset these parameters 'coz there is a certain part of the CORPAD which is out of + ; the bounding box but yet count towards the height and width + currentWidth = CORPAD_extraOffsetX + currentHeight = CORPAD_extraOffsetY + + + ; This is the tolerance for the error when dealing with floating point math + Delta = 0.0000000001 + + StopDrawing = nil + + ; ================================================================================================= + ; CDL OUTPUT + ; ================================================================================================= + ; Print out the SUBCKT and port part of the CDL file + if( GenCDL + then + ; File I/O Port Definitions + inPort = infile( SignalListFile ) + outPort = outfile( CDLFileName ) + + fprintf( outPort ".SUBCKT PADFRAME\n" ) + fprintf( outPort " + %-20s\n" CoreVDDNetName ) + fprintf( outPort " + %-20s\n" CoreVSSNetName ) + + when( inPort + + while( fscanf( inPort "%s " signalName ) + if( signalName != "IOVDD" && + signalName != "IOVSS" && + signalName != "CoreVDD" && + signalName != "CoreVSS" + then + fscanf( inPort "%s\n" ioActualType) + ; CDL Output + fprintf( outPort " + %-20s\n" signalName ) + ) + + ); end while + + close( inPort ) + + +; when( inPort +; while( fscanf( inPort "%s %s\n" signalName ioActualType ) +; +; +; ; CDL Output +; fprintf( outPort " + %-20s\n" signalName ) +; +; ); end while +; +; close( inPort ) + + ); end when + + close( outPort ) + + ); end if + + ; ================================================================================================= + ; CAST OUTPUT + ; ================================================================================================= + ; Print out the header part of the cast file + + if( GenCAST + then + ; File I/O Port Definitions + outPort = outfile( CASTFileName ) + + fprintf( outPort "define PADFRAME()\n" ) + fprintf( outPort " ( \n" ) + fprintf( outPort " // Wake up and Fill out the port list yourself!!! \n" ) + fprintf( outPort " // I have no CAST knowledge to fill out this for you!!! \n" ) + fprintf( outPort " ) \n" ) + fprintf( outPort "{ \n" ) + + close( outPort ) + + ); end if + + + ; ================================================================================================= + ; FEEDER INSERTION + ; ================================================================================================= + ; This routine is used to insert sufficient feeder pads to satisfy the minimum driver spacing + ; set by the user (MinDriverSpacing) + + l_IO_Topology_new = list( ) + foreach( IO_Topology l_IO_Topology + + l_IO_Topology_new = reverse( cons( IO_Topology reverse( l_IO_Topology_new ))) + + if( IO_Topology == "S" || IO_Topology == "P" + then + l_IO_Topology_new = reverse( cons( evalstring( "list( \"F\" MinDriverSpacing )" ) reverse( l_IO_Topology_new ))) + ); end if + + ); end foreach + l_IO_Topology = l_IO_Topology_new + l_IO_Topology_save = l_IO_Topology_new + + + ; ================================================================================================= + ; ADVANCED SPACING TOPOLOGY -- MAX POWER PADS + ; ================================================================================================= + inPort = infile( SignalListFile ) + TotalLengthAvaliable = 2 * ( ChipHeight_um - ( CORPAD_extraOffsetY + CORPAD_extraOffsetX + (2 * CORPAD_prWidth ))) + + 2 * ( ChipWidth_um - ( CORPAD_extraOffsetY + CORPAD_extraOffsetX + (2 * CORPAD_prWidth ))) - + 4 * MinDriverSpacing + + if( MaxPower + then + when( inPort + + while( fscanf( inPort "%s " signalName ) + if( signalName != "IOVDD" && + signalName != "IOVSS" && + signalName != "CoreVDD" && + signalName != "CoreVSS" + then + fscanf( inPort "%s\n" ioActualType) + TotalLengthAvaliable = TotalLengthAvaliable - cadr( cdddr( evalstring( ioActualType ))) - MinDriverSpacing + TotalNumberOfSignals = TotalNumberOfSignals + 1 + ) + + ); end while + + close( inPort ) + + ) ;end when + + TotalNumberOfPower = TotalLengthAvaliable / ( 35 + MinDriverSpacing ) + TargetRatio = TotalNumberOfPower / TotalNumberOfSignals + + ); end if + + ; ================================================================================================= + ; File I/O Port Definitions + inPort = infile( SignalListFile ) + GenCDL && ( outPortCDL = outfile( CDLFileName "a" ) ) + GenCAST && ( outPortCAST = outfile( CASTFileName "a" ) ) + + when( inPort + while( !EndOfFile + + ; Decoding the Topology + foreach( currentSymbolType l_IO_Topology + + ; See if it is an advanced Topology Setting + if( listp( currentSymbolType ) + then + Parameter = cadr( currentSymbolType ) + currentSymbolType = car( currentSymbolType ) + ); end if + + ; Clear Variables to start + l_currentCellType = list( ) + l_t_instName = list( ) + addedWidth = 0 + + + + case( currentSymbolType + ( "S" + + if( fscanf( inPort "%s " signalName ) + then + case( signalName + ( "IOVDD" + + IOVDDCounter = IOVDDCounter + 1 + TempCounter = IOVDDCounter + currentPowerPadNumberString = strcat( "_" sprintf( nil "%d" TempCounter )) + currentPowerPad = "IOVDD" + + PowerPadCounter = PowerPadCounter + 1 + l_currentCellType = list( "BONDIZ40" currentPowerPad ) + l_t_instName = list( strcat( strcat( "bondP_" currentPowerPad ) currentPowerPadNumberString ) + strcat( strcat( "padP_" currentPowerPad ) currentPowerPadNumberString )) + addedWidth = cadr( cdddr( evalstring( currentPowerPad ))) + + ) + + ( "IOVSS" + + IOVSSCounter = IOVSSCounter + 1 + TempCounter = IOVSSCounter + currentPowerPadNumberString = strcat( "_" sprintf( nil "%d" TempCounter )) + currentPowerPad = "IOVSS" + + PowerPadCounter = PowerPadCounter + 1 + l_currentCellType = list( "BONDIZ40" currentPowerPad ) + l_t_instName = list( strcat( strcat( "bondP_" currentPowerPad ) currentPowerPadNumberString ) + strcat( strcat( "padP_" currentPowerPad ) currentPowerPadNumberString )) + addedWidth = cadr( cdddr( evalstring( currentPowerPad ))) + + ) + + ( "CoreVDD" + + CoreVDDCounter = CoreVDDCounter + 1 + TempCounter = CoreVDDCounter + currentPowerPadNumberString = strcat( "_" sprintf( nil "%d" TempCounter )) + currentPowerPad = "CoreVDD" + + PowerPadCounter = PowerPadCounter + 1 + l_currentCellType = list( "BONDIZ40" currentPowerPad ) + l_t_instName = list( strcat( strcat( "bondP_" currentPowerPad ) currentPowerPadNumberString ) + strcat( strcat( "padP_" currentPowerPad ) currentPowerPadNumberString )) + addedWidth = cadr( cdddr( evalstring( currentPowerPad ))) + + ) + + ( "CoreVSS" + + CoreVSSCounter = CoreVSSCounter + 1 + TempCounter = CoreVSSCounter + currentPowerPadNumberString = strcat( "_" sprintf( nil "%d" TempCounter )) + currentPowerPad = "CoreVSS" + + PowerPadCounter = PowerPadCounter + 1 + l_currentCellType = list( "BONDIZ40" currentPowerPad ) + l_t_instName = list( strcat( strcat( "bondP_" currentPowerPad ) currentPowerPadNumberString ) + strcat( strcat( "padP_" currentPowerPad ) currentPowerPadNumberString )) + addedWidth = cadr( cdddr( evalstring( currentPowerPad ))) + + ) + + ( t + fscanf( inPort "%s\n" ioActualType ) + EndOfFile = nil + FillFeeder = nil + l_currentCellType = list( "BONDIZ40" ioActualType ) + l_t_instName = list( strcat( "bondS_" signalName ) + strcat( "padS_" signalName )) + addedWidth = cadr( cdddr( evalstring( ioActualType ))) + + SignalPadCounter = SignalPadCounter + 1 + ) + ); end case + + else + EndOfFile = t + FillFeeder = t + ); end if + + ) + + ( "P" + if( !EndOfFile + then + currentPowerPad = car( PowerPadList ) + PowerPadList = remove( currentPowerPad PowerPadList ) + PowerPadList = reverse( cons( currentPowerPad reverse( PowerPadList ))) + + case( currentPowerPad + ( "IOVDD" + + IOVDDCounter = IOVDDCounter + 1 + TempCounter = IOVDDCounter + ) + ( "IOVSS" + + printf( "IOVSSCounter = %n\n" IOVSSCounter ) + IOVSSCounter = IOVSSCounter + 1 + TempCounter = IOVSSCounter + ) + ( "CoreVDD" + + CoreVDDCounter = CoreVDDCounter + 1 + TempCounter = CoreVDDCounter + ) + ( "CoreVSS" + + CoreVSSCounter = CoreVSSCounter + 1 + TempCounter = CoreVSSCounter + ) + ) + + currentPowerPadNumberString = strcat( "_" sprintf( nil "%d" TempCounter )) + + PowerPadCounter = PowerPadCounter + 1 + l_currentCellType = list( "BONDIZ40" currentPowerPad ) + l_t_instName = list( strcat( strcat( "bondP_" currentPowerPad ) currentPowerPadNumberString ) + strcat( strcat( "padP_" currentPowerPad ) currentPowerPadNumberString )) + addedWidth = cadr( cdddr( evalstring( currentPowerPad ))) + + ); end if + ) + + ( "F" + if( !EndOfFile + then + l_currentCellType = list() + l_t_instName = list() + addedWidth = Parameter + neededFeederLength = Parameter + + ; ==================================================================================== + ; Put in the corresponding Feeder Cells + ; We have Feeder Cells in dimensions of 0.005, 0.01, 0.1, 1, 5, 10, 20 microns + dividerNameList = list( "F20" "F10" "F5" "F1" "F0_1" "F0_01" "F0_005" ) + + foreach( dividerName dividerNameList + + divider = cadr( cdddr( evalstring( dividerName ))) + numAdded = floor( neededFeederLength / divider ) + + neededFeederLength = neededFeederLength - ( numAdded * divider ) + for( i 1 numAdded + + FeederCellCounterString = sprintf( nil "%n" FeederCellCounter ) + l_currentCellType = cons( dividerName l_currentCellType ) + t_instName = strcat( "padFeeder_" FeederCellCounterString ) + FeederCellCounter = FeederCellCounter + 1 + l_t_instName = cons( t_instName l_t_instName ) + + ); end for + + ); end foreach + ; ==================================================================================== + ); end if + ) + + ); end case + + + ; See if the pads need to turn the corner + ; See if a Corner Pad is necessary + if( ( currentOri == "R0" && ( currentWidth + CORPAD_extraOffsetX + CORPAD_prWidth + addedWidth ) > ChipWidth_um ) || + ( currentOri == "R90" && ( currentHeight + CORPAD_extraOffsetX + CORPAD_prWidth + addedWidth ) > ChipHeight_um ) || + ( currentOri == "R180" && ( currentWidth + CORPAD_extraOffsetX + CORPAD_prWidth + addedWidth ) > ChipWidth_um ) || + ( currentOri == "R270" && EndOfFile == t && FillFeeder == t ) + + then + + case( currentOri + ( "R0" + nextOri = "R90" + ChipSideLength_um = ChipWidth_um + currentSideLength = currentWidth + ) + ( "R90" + nextOri = "R180" + ChipSideLength_um = ChipHeight_um + currentSideLength = currentHeight + ) + ( "R180" + nextOri = "R270" + ChipSideLength_um = ChipWidth_um + currentSideLength = currentWidth + ) + ( "R270" + nextOri = "R0" + ChipSideLength_um = ChipHeight_um + currentSideLength = currentHeight + ) + ); end case + + + if( !EndOfFile + then + + neededFeederLength = MinDriverSpacing + + ; ==================================================================================== + ; Put in the corresponding Feeder Cells + ; We have Feeder Cells in dimensions of 0.005, 0.01, 0.1, 1, 5, 10, 20 microns + dividerNameList = list( "F20" "F10" "F5" "F1" "F0_1" "F0_01" "F0_005" ) + + foreach( dividerName dividerNameList + + divider = cadr( cdddr( evalstring( dividerName ))) + numAdded = floor( neededFeederLength / divider ) + + neededFeederLength = neededFeederLength - ( numAdded * divider ) + for( i 1 numAdded + + FeederCellCounterString = sprintf( nil "%n" FeederCellCounter ) + l_currentCellType = cons( dividerName l_currentCellType ) + t_instName = strcat( "padFeeder_" FeederCellCounterString ) + FeederCellCounter = FeederCellCounter + 1 + l_t_instName = cons( t_instName l_t_instName ) + + ); end for + + ); end foreach + ; ==================================================================================== + + ; Then add a Feeder pad to the first of the list +; l_currentCellType = cons( "F60" l_currentCellType ) +; l_t_instName = cons( strcat( "padF_" nextOri ) l_t_instName ) + + ; First add a corner pad to the first of the list before the just-added feeder pad + l_currentCellType = cons( "CORPAD" l_currentCellType ) + l_t_instName = cons( strcat( "CORPAD_" nextOri ) l_t_instName ) + ); end if + + neededFeederLength = max( ( ChipSideLength_um - ( currentSideLength + CORPAD_extraOffsetX + CORPAD_prWidth )) 0 ) + + ; ==================================================================================== + ; Put in the corresponding Feeder Cells + ; We have Feeder Cells in dimensions of 0.005, 0.01, 0.1, 1, 5, 10, 20 microns + dividerNameList = list( "F20" "F10" "F5" "F1" "F0_1" "F0_01" "F0_005" ) + + foreach( dividerName dividerNameList + + divider = cadr( cdddr( evalstring( dividerName ))) + numAdded = floor( neededFeederLength / divider ) + + neededFeederLength = neededFeederLength - ( numAdded * divider ) + for( i 1 numAdded + + FeederCellCounterString = sprintf( nil "%n" FeederCellCounter ) + l_currentCellType = cons( dividerName l_currentCellType ) + t_instName = strcat( "padFeeder_" FeederCellCounterString ) + FeederCellCounter = FeederCellCounter + 1 + l_t_instName = cons( t_instName l_t_instName ) + + ); end for + + ); end foreach + ; ==================================================================================== + + StopDrawing = nil + + + + ) ;end if + + ; Special Case for first Pad + if( drawFirstCorner + then + + + neededFeederLength = MinDriverSpacing + + ; ==================================================================================== + ; Put in the corresponding Feeder Cells + ; We have Feeder Cells in dimensions of 0.005, 0.01, 0.1, 1, 5, 10, 20 microns + dividerNameList = list( "F20" "F10" "F5" "F1" "F0_1" "F0_01" "F0_005" ) + + foreach( dividerName dividerNameList + + divider = cadr( cdddr( evalstring( dividerName ))) + numAdded = floor( neededFeederLength / divider ) + + neededFeederLength = neededFeederLength - ( numAdded * divider ) + for( i 1 numAdded + + FeederCellCounterString = sprintf( nil "%n" FeederCellCounter ) + l_currentCellType = cons( dividerName l_currentCellType ) + t_instName = strcat( "padFeeder_" FeederCellCounterString ) + FeederCellCounter = FeederCellCounter + 1 + l_t_instName = cons( t_instName l_t_instName ) + + ); end for + + ); end foreach + ; ==================================================================================== + + + ; Then add a Feeder pad to the first of the list + ;l_currentCellType = cons( "F60" l_currentCellType ) + ;l_t_instName = cons( strcat( "padF_" nextOri ) l_t_instName ) + + ; First add a corner pad to the first of the list before the just-added feeder pad + l_currentCellType = cons( "CORPAD" l_currentCellType ) + l_t_instName = cons( strcat( "CORPAD_" nextOri ) l_t_instName ) + + drawFirstCorner = nil + ); end if + + + ; See if you have way too many pads than the space you have on the chip + if( ( currentOri == "R270" && (( currentHeight + CORPAD_extraOffsetX + CORPAD_prWidth + addedWidth ) - ChipHeight_um ) > Delta ) + || StopDrawing + then + if( fscanf( inPort "%s %s\n" signalName ioActualType ) + then + printf( "%sERROR!!! Too many pads!!! Not enough space\n" H ) + printf( "%sERROR!!! Try to change topology or Change Size of Chip\n" H ) + ) + l_currentCellType = list() + + StopDrawing = t + + ); end if + + + + ; This is the actual loop that do the drawing and instantiations + foreach( currentCellType l_currentCellType + + ; Get the prBound info for the cell + prWidth = car( cdr( cdr( cdr( cdr( evalstring( currentCellType )))))) + prHeight = car( cdr( cdr( cdr( cdr( cdr( evalstring( currentCellType ))))))) + prX = car( car( cdr( cdr( cdr( evalstring( currentCellType )))))) + prY = cadr( car( cdr( cdr( cdr( evalstring( currentCellType )))))) + + ; See if it is the second corner pad or up (ignore the first one) + if( currentCellType == "CORPAD" && currentOri != nextOri + then + case( currentOri + ( "R0" + x = x + CORPAD_prHeight + currentWidth = CORPAD_extraOffsetX + ) + + ( "R90" + y = y + CORPAD_prWidth + currentHeight = CORPAD_extraOffsetY + ) + + ( "R180" + x = x - CORPAD_prHeight + currentWidth = CORPAD_extraOffsetX + ) + + ) ;end case + currentOri = nextOri + + ; x = x + CORPAD_prHeight + );end if + + + ; If it is a bond pad, it should be on the outer side + if( currentCellType == "BONDIZ40" + then + case( currentOri + ( "R0" + l_origin = list( x-prX y-prHeight-prY ) + ) + ( "R90" + l_origin = list( x-prY+prHeight y-prX ) + ) + ( "R180" + l_origin = list( x+prX y+prHeight+prY ) + ) + ( "R270" + l_origin = list( x+prY-prHeight y+prX ) + ) + + ); end case + else + l_origin = list( x-prX y-prY ) + ); end if + + d_cellView = geGetWindowCellView( ) + t_libName = car( evalstring( currentCellType )) + t_cellName = cadr( evalstring( currentCellType )) + t_viewName = caddr( evalstring( currentCellType )) + t_instName = car( l_t_instName ) + l_t_instName = remove( t_instName l_t_instName ) + t_orient = currentOri + + printf( "%sPad \"%s\" created using type ( %s %s %s ) \n" + H + t_instName + t_libName + t_cellName + t_viewName ) + + ; Put in Signal Pad + d_inst = dbCreateInstByMasterName( + d_cellView + t_libName + t_cellName + t_viewName + t_instName + l_origin + t_orient + ) + + ;================================================================================================= + ; CDL OUTPUT + ;================================================================================================= + ; Output CDL for IOVDD and IOVSS only + + if( ( currentCellType == "IOVDD" || currentCellType == "IOVSS" ) && GenCDL + then + fprintf( outPortCDL + "X%-20s %-10s %-10s %-10s %-10s %-20s\n" + t_instName + CoreVDDNetName + CoreVSSNetName + IOVDDNetName + IOVSSNetName + t_cellName ) + + ); end if + ;================================================================================================= + + + ; Add Connectivity and pins Info to the Driver Cells + case( currentCellType + + ( "CoreVDD" + VDDpinOffset = cadr( CoreVDDPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_VDD = list( ( car( l_origin ) + car( VDDpinOffset )) + ( cadr( l_origin ) + cadr( VDDpinOffset ))) + ) + ( "R90" + l_origin_VDD = list( ( car( l_origin ) - cadr( VDDpinOffset )) + ( cadr( l_origin ) + car( VDDpinOffset ))) + ) + ( "R180" + l_origin_VDD = list( ( car( l_origin ) - car( VDDpinOffset )) + ( cadr( l_origin ) - cadr( VDDpinOffset ))) + ) + ( "R270" + l_origin_VDD = list( ( car( l_origin ) + cadr( VDDpinOffset )) + ( cadr( l_origin ) - car( VDDpinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" +; strcat( "pinVDD_" signalName ) + strcat( "pinVDD_" currentPowerPadNumberString ) + l_origin_VDD + "R0" + ) + + CoreVDDNetID || ( CoreVDDNetID = dbCreateNet( geGetWindowCellView() CoreVDDNetName )) + + ; Create Connectivity + dbCreatePin( CoreVDDNetID d_pin ) + dbCreateConnByName( CoreVDDNetID d_inst car( CoreVDDPin )) + + ;=================================================================================== + ; CDL OUTPUT + ;=================================================================================== + if( GenCDL + then + fprintf( outPortCDL + "X%-20s %-10s %-10s %-10s %-10s %-20s\n" + t_instName + CoreVDDNetName + CoreVSSNetName + IOVDDNetName + IOVSSNetName + t_cellName ) + ); end if + ;=================================================================================== + + ) + + ( "CoreVSS" + VSSpinOffset = cadr( CoreVSSPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_VSS = list( ( car( l_origin ) + car( VSSpinOffset )) + ( cadr( l_origin ) + cadr( VSSpinOffset ))) + ) + ( "R90" + l_origin_VSS = list( ( car( l_origin ) - cadr( VSSpinOffset )) + ( cadr( l_origin ) + car( VSSpinOffset ))) + ) + ( "R180" + l_origin_VSS = list( ( car( l_origin ) - car( VSSpinOffset )) + ( cadr( l_origin ) - cadr( VSSpinOffset ))) + ) + ( "R270" + l_origin_VSS = list( ( car( l_origin ) + cadr( VSSpinOffset )) + ( cadr( l_origin ) - car( VSSpinOffset ))) + ) + + ); end case + + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" +; strcat( "pinVSS_" signalName ) + strcat( "pinVSS_" currentPowerPadNumberString ) + l_origin_VSS + "R0" + ) + + CoreVSSNetID || ( CoreVSSNetID = dbCreateNet( geGetWindowCellView() CoreVSSNetName )) + + ; Create Connectivity + dbCreatePin( CoreVSSNetID d_pin ) + dbCreateConnByName( CoreVSSNetID d_inst car(CoreVSSPin) ) + + ;=================================================================================== + ; CDL OUTPUT + ;=================================================================================== + if( GenCDL + then + fprintf( outPortCDL + "X%-20s %-10s %-10s %-10s %-10s %-20s\n" + t_instName + CoreVDDNetName + CoreVSSNetName + IOVDDNetName + IOVSSNetName + t_cellName ) + ); end if + ;=================================================================================== + ) + + ( "DSO1" + DSO1_IPinOffset = cadr( DSO1_IPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_DSO1_IPin = list( ( car( l_origin ) + car( DSO1_IPinOffset )) + ( cadr( l_origin ) + cadr( DSO1_IPinOffset ))) + ) + ( "R90" + l_origin_DSO1_IPin = list( ( car( l_origin ) - cadr( DSO1_IPinOffset )) + ( cadr( l_origin ) + car( DSO1_IPinOffset ))) + ) + ( "R180" + l_origin_DSO1_IPin = list( ( car( l_origin ) - car( DSO1_IPinOffset )) + ( cadr( l_origin ) - cadr( DSO1_IPinOffset ))) + ) + ( "R270" + l_origin_DSO1_IPin = list( ( car( l_origin ) + cadr( DSO1_IPinOffset )) + ( cadr( l_origin ) - car( DSO1_IPinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" + strcat( "pinDSO1_" signalName ) + l_origin_DSO1_IPin + "R0" + ) + + DSO1NetID = dbCreateNet( geGetWindowCellView() signalName ) + + ; Create Connectivity + dbCreatePin( DSO1NetID d_pin ) + dbCreateConnByName( DSO1NetID d_inst car( DSO1_IPin ) ) + + + + DSO1_PADPinOffset = cadr( DSO1_PADPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_DSO1_PADPin = list( ( car( l_origin ) + car( DSO1_PADPinOffset )) + ( cadr( l_origin ) + cadr( DSO1_PADPinOffset ))) + ) + ( "R90" + l_origin_DSO1_PADPin = list( ( car( l_origin ) - cadr( DSO1_PADPinOffset )) + ( cadr( l_origin ) + car( DSO1_PADPinOffset ))) + ) + ( "R180" + l_origin_DSO1_PADPin = list( ( car( l_origin ) - car( DSO1_PADPinOffset )) + ( cadr( l_origin ) - cadr( DSO1_PADPinOffset ))) + ) + ( "R270" + l_origin_DSO1_PADPin = list( ( car( l_origin ) + cadr( DSO1_PADPinOffset )) + ( cadr( l_origin ) - car( DSO1_PADPinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" + strcat( "pad_" signalName ) + l_origin_DSO1_PADPin + "R0" + ) + + DSO1NetID = dbCreateNet( geGetWindowCellView() strcat( "pad_" signalName )) + + ; Create Connectivity + dbCreatePin( DSO1NetID d_pin ) + dbCreateConnByName( DSO1NetID d_inst car( DSO1_PADPin ) ) + + ;=================================================================================== + ; CDL OUTPUT + ;=================================================================================== + if( GenCDL + then + fprintf( outPortCDL + "X%-20s %-10s %-10s %-10s %-10s %-20s %-20s %-20s\n" + t_instName + CoreVDDNetName + CoreVSSNetName + IOVDDNetName + IOVSSNetName + strcat( "pad_" signalName ) + signalName + t_cellName ) + ); end if + + ;=================================================================================== + ; CAST OUTPUT + ;=================================================================================== + if( GenCAST + then + fprintf( outPortCAST + "%-10s %15s( %-15s, %-15s );\n" + t_cellName + t_instName + strcat( "pad_" signalName ) + signalName ) + ); end if + ;=================================================================================== + + ); end type DSO1 + + ( "DSI1" + DSI1_CPinOffset = cadr( DSI1_CPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_DSI1_CPin = list( ( car( l_origin ) + car( DSI1_CPinOffset )) + ( cadr( l_origin ) + cadr( DSI1_CPinOffset ))) + ) + ( "R90" + l_origin_DSI1_CPin = list( ( car( l_origin ) - cadr( DSI1_CPinOffset )) + ( cadr( l_origin ) + car( DSI1_CPinOffset ))) + ) + ( "R180" + l_origin_DSI1_CPin = list( ( car( l_origin ) - car( DSI1_CPinOffset )) + ( cadr( l_origin ) - cadr( DSI1_CPinOffset ))) + ) + ( "R270" + l_origin_DSI1_CPin = list( ( car( l_origin ) + cadr( DSI1_CPinOffset )) + ( cadr( l_origin ) - car( DSI1_CPinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" + strcat( "pinDSI1_" signalName ) + l_origin_DSI1_CPin + "R0" + ) + + DSI1NetID = dbCreateNet( geGetWindowCellView() signalName ) + + ; Create Connectivity + dbCreatePin( DSI1NetID d_pin ) + dbCreateConnByName( DSI1NetID d_inst car( DSI1_CPin ) ) + + + + DSI1_PADPinOffset = cadr( DSI1_PADPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_DSI1_PADPin = list( ( car( l_origin ) + car( DSI1_PADPinOffset )) + ( cadr( l_origin ) + cadr( DSI1_PADPinOffset ))) + ) + ( "R90" + l_origin_DSI1_PADPin = list( ( car( l_origin ) - cadr( DSI1_PADPinOffset )) + ( cadr( l_origin ) + car( DSI1_PADPinOffset ))) + ) + ( "R180" + l_origin_DSI1_PADPin = list( ( car( l_origin ) - car( DSI1_PADPinOffset )) + ( cadr( l_origin ) - cadr( DSI1_PADPinOffset ))) + ) + ( "R270" + l_origin_DSI1_PADPin = list( ( car( l_origin ) + cadr( DSI1_PADPinOffset )) + ( cadr( l_origin ) - car( DSI1_PADPinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" + strcat( "pad_" signalName ) + l_origin_DSI1_PADPin + "R0" + ) + + DSI1NetID = dbCreateNet( geGetWindowCellView() strcat( "pad_" signalName )) + + ; Create Connectivity + dbCreatePin( DSI1NetID d_pin ) + dbCreateConnByName( DSI1NetID d_inst car( DSI1_PADPin ) ) + + ;=================================================================================== + ; CDL OUTPUT + ;=================================================================================== + if( GenCDL + then + fprintf( outPortCDL + "X%-20s %-10s %-10s %-10s %-10s %-20s %-20s %-20s\n" + t_instName + CoreVDDNetName + CoreVSSNetName + IOVDDNetName + IOVSSNetName + signalName + strcat( "pad_" signalName ) + t_cellName ) + ); end if + + ;=================================================================================== + ; CAST OUTPUT + ;=================================================================================== + if( GenCAST + then + fprintf( outPortCAST + "%-10s %15s( %-15s, %-15s );\n" + t_cellName + t_instName + signalName + strcat( "pad_" signalName )) + ); end if + ;=================================================================================== + ); end type DSI1 + + + + + + + + + + + + + + + + + ( "AS1" + AS1_CPinOffset = cadr( AS1_CPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_AS1_CPin = list( ( car( l_origin ) + car( AS1_CPinOffset )) + ( cadr( l_origin ) + cadr( AS1_CPinOffset ))) + ) + ( "R90" + l_origin_AS1_CPin = list( ( car( l_origin ) - cadr( AS1_CPinOffset )) + ( cadr( l_origin ) + car( AS1_CPinOffset ))) + ) + ( "R180" + l_origin_AS1_CPin = list( ( car( l_origin ) - car( AS1_CPinOffset )) + ( cadr( l_origin ) - cadr( AS1_CPinOffset ))) + ) + ( "R270" + l_origin_AS1_CPin = list( ( car( l_origin ) + cadr( AS1_CPinOffset )) + ( cadr( l_origin ) - car( AS1_CPinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" + strcat( "pinAS1_" signalName ) + l_origin_AS1_CPin + "R0" + ) + + AS1NetID = dbCreateNet( geGetWindowCellView() signalName ) + + ; Create Connectivity + dbCreatePin( AS1NetID d_pin ) + dbCreateConnByName( AS1NetID d_inst car( AS1_CPin ) ) + + + + AS1_PADPinOffset = cadr( AS1_PADPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_AS1_PADPin = list( ( car( l_origin ) + car( AS1_PADPinOffset )) + ( cadr( l_origin ) + cadr( AS1_PADPinOffset ))) + ) + ( "R90" + l_origin_AS1_PADPin = list( ( car( l_origin ) - cadr( AS1_PADPinOffset )) + ( cadr( l_origin ) + car( AS1_PADPinOffset ))) + ) + ( "R180" + l_origin_AS1_PADPin = list( ( car( l_origin ) - car( AS1_PADPinOffset )) + ( cadr( l_origin ) - cadr( AS1_PADPinOffset ))) + ) + ( "R270" + l_origin_AS1_PADPin = list( ( car( l_origin ) + cadr( AS1_PADPinOffset )) + ( cadr( l_origin ) - car( AS1_PADPinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" + strcat( "pad_" signalName ) + l_origin_AS1_PADPin + "R0" + ) + + AS1NetID = dbCreateNet( geGetWindowCellView() strcat( "pad_" signalName )) + + ; Create Connectivity + dbCreatePin( AS1NetID d_pin ) + dbCreateConnByName( AS1NetID d_inst car( AS1_PADPin ) ) + + + + + + AS1_OENPinOffset = cadr( AS1_OENPin ) + + ; Moving the origin + case( currentOri + ( "R0" + l_origin_AS1_OENPin = list( ( car( l_origin ) + car( AS1_OENPinOffset )) + ( cadr( l_origin ) + cadr( AS1_OENPinOffset ))) + ) + ( "R90" + l_origin_AS1_OENPin = list( ( car( l_origin ) - cadr( AS1_OENPinOffset )) + ( cadr( l_origin ) + car( AS1_OENPinOffset ))) + ) + ( "R180" + l_origin_AS1_OENPin = list( ( car( l_origin ) - car( AS1_OENPinOffset )) + ( cadr( l_origin ) - cadr( AS1_OENPinOffset ))) + ) + ( "R270" + l_origin_AS1_OENPin = list( ( car( l_origin ) + cadr( AS1_OENPinOffset )) + ( cadr( l_origin ) - car( AS1_OENPinOffset ))) + ) + + ); end case + + ; Draw the actual Pin + d_pin = dbCreateInstByMasterName( + geGetWindowCellView() + "tsmc13lg" + "m3_T" + "symbolic" + strcat( "oen_" signalName ) + l_origin_AS1_OENPin + "R0" + ) + + AS1NetID = dbCreateNet( geGetWindowCellView() strcat( "oen_" signalName )) + + ; Create Connectivity + dbCreatePin( AS1NetID d_pin ) + dbCreateConnByName( AS1NetID d_inst car( AS1_OENPin ) ) + + ;=================================================================================== + ; CDL OUTPUT + ;=================================================================================== + if( GenCDL + then + fprintf( outPortCDL + "X%-15s %-7s %-7s %-7s %-7s %-15s %-15s %-15s %-15s\n" + t_instName + CoreVDDNetName + CoreVSSNetName + IOVDDNetName + IOVSSNetName + strcat( "pad_" signalName ) + signalName + strcat( "oen_" signalName ) + t_cellName ) + ); end if + + ;=================================================================================== + ; CAST OUTPUT + ;=================================================================================== + if( GenCAST + then + fprintf( outPortCAST + "%-10s %15s( %-15s, %-15s, %-15s );\n" + t_cellName + t_instName + strcat( "pad_" signalName ) + signalName + strcat( "oen_" signalName )) + ); end if + ;=================================================================================== + ); end type AS1 + + ); end case + + ;================================================================================================= + + ; Increment the pointer only if it is not doing a bonding pad + if( currentCellType != "BONDIZ40" + then + case( currentOri + ( "R0" + currentWidth = currentWidth + prWidth + x = x + prWidth + ) + ( "R90" + currentHeight = currentHeight + prWidth + y = y + prWidth + ) + ( "R180" + currentWidth = currentWidth + prWidth + x = x - prWidth + ) + ( "R270" + currentHeight = currentHeight + prWidth + y = y - prWidth + ) + ); end case + ); end if + + ) ;end foreach + + + if( MaxPower && !EndOfFile + then + + PowerPadCounterTemp = PowerPadCounter + 1 + SignalPadCounterTemp = SignalPadCounter + 1 + CurrentRatio = PowerPadCounterTemp / SignalPadCounterTemp + + + + l_IO_Topology = l_IO_Topology_save + ExitWhile = nil + + printf( "Target Ratio is %f\n" TargetRatio ) + + while( ( TargetRatio - CurrentRatio ) > 0 && !ExitWhile + + PowerPadCounterTemp = PowerPadCounterTemp + 1 + CurrentRatio = float( PowerPadCounterTemp ) / float( SignalPadCounterTemp ) + printf( "Current Ratio is %3n / %-3n = %f\n" PowerPadCounterTemp SignalPadCounterTemp CurrentRatio ) + + if( ( TargetRatio - CurrentRatio ) > 0 + then + + l_IO_Topology = reverse( cons( "P" reverse( l_IO_Topology ))) + l_IO_Topology = reverse( cons( evalstring( "list( \"F\" MinDriverSpacing )") reverse( l_IO_Topology ))) + printf( "Added 1 Power Pad \n") + + + else + ExitWhile = t + ) + + );end while + println( l_IO_Topology ) + + + ); end if + + + + FillFeeder = nil + + ); end foreach + + ); end while + + close( inPort ) + if( GenCDL + then + close( outPortCDL ) + ) + + if( GenCAST + then + close( outPortCAST ) + ) + + ); end when + + ;=================================================================================== + ; CDL OUTPUT + ;=================================================================================== + ; Print out .ENDS part of the CDL file + if( GenCDL + then + outPortCDL = outfile( CDLFileName "a" ) + fprintf( outPortCDL ".ENDS PADFRAME\n" ) + close( outPortCDL ) + + ); end if + + ;=================================================================================== + ; CAST OUTPUT + ;=================================================================================== + if( GenCAST + then + outPortCAST = outfile( CASTFileName "a" ) + fprintf( outPortCAST "}\n" ) + close( outPortCAST ) + ); end if + ;=================================================================================== + + ); end let + +); end procedure + + + + +; ============================================================================================= +; TR_DrawIO_GenCDL_CB +; ============================================================================================= +; This is a small CallBack Function used to get the filename for the desired cdl output file + +procedure( TR_DrawIO_GenCDL_CB( theForm ) + + let( ( GenCDL + TR_DrawIO_CDLFileName + ReturnValue ) + + GenCDL = theForm->TR_DrawIO_GenCDL->GenCDL->value + ReturnValue = t + + if( GenCDL + then + TR_DrawIO_CDLFileName = hiCreateStringField( + ?name 'TR_DrawIO_CDLFileName + ?prompt "Enter CDL Filename" + ?defValue "./PADFRAME.cdl" + ?editable t ) + + hiAddField( theForm TR_DrawIO_CDLFileName ) + else + hiDeleteField( theForm `TR_DrawIO_CDLFileName ) + + ); end if + + ReturnValue + + ); end let + +); end procedure + +; ============================================================================================= +; TR_DrawIO_GenCAST_CB +; ============================================================================================= +; This is a small CallBack Function used to get the filename for the desired cast output file + +procedure( TR_DrawIO_GenCAST_CB( theForm ) + + let( ( GenCAST + TR_DrawIO_CASTFileName + ReturnValue ) + + GenCAST = theForm->TR_DrawIO_GenCAST->GenCAST->value + ReturnValue = t + + if( GenCAST + then + TR_DrawIO_CASTFileName = hiCreateStringField( + ?name 'TR_DrawIO_CASTFileName + ?prompt "Enter CAST Filename" + ?defValue "./PADFRAME.cast" + ?editable t ) + + hiAddField( theForm TR_DrawIO_CASTFileName ) + else + hiDeleteField( theForm `TR_DrawIO_CASTFileName ) + + ); end if + + ReturnValue + + ); end let + +); end procedure + +; ============================================================================================= +; TR_DrawIO_TopologyAdvancedSpacing_CB_MaxPower +; ============================================================================================= +; This is a small CallBack Function used to enable/disable the topology field + +procedure( TR_DrawIO_TopologyAdvancedSpacing_CB( theForm ) + + let( ( + ReturnValue ) + + ReturnValue = t + + case( theForm->TR_DrawIO_TopologyAdvancedSpacing->value + + ("None" + + theForm->TR_DrawIO_Topology->enabled = t + + ) + ("Max Feeder" + + theForm->TR_DrawIO_Topology->enabled = nil + + ) + ("Max Power" + + theForm->TR_DrawIO_Topology->enabled = nil + + ) + + ); end case + + ReturnValue + + ); end let + +); end procedure + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawWellPlugs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawWellPlugs.il new file mode 100644 index 0000000000..91005d32f7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/DrawWellPlugs.il @@ -0,0 +1,280 @@ +; This Fuction is used to auto draw well plugs +; Assume that there is only one layer of each NIMP, PIMP and/or NWELL +; Multiple overlaps of the same layer may crash the script +; For NWELL Plug, it will always draw a plug if there is a NWELL, but will +; only cut the PIMP if there is any (vice verse for PWELL) + +procedure( DrawWellPlugs( ) + + ; local Varibales + let( ( + d_CurrentWindow + d_cellView + d_PIMP + d_NIMP + d_inst + l_Path + CurrentXY + t_libName + t_cellName + ix1 ix2 iy1 iy2 + px1 px2 py1 py2 + ) + + d_cellView = geGetWindowCellView( ) + d_CurrentWindow = geGetCellViewWindow( geGetWindowCellView()) + t_libName = "tsmc13lg" + + ; Get the cursor coordinates + CurrentXY = hiGetPoint( d_CurrentWindow ) + + d_PIMP = gePointQuery( d_CurrentWindow CurrentXY "DrawWellPlugs_checkPIMP" ) + d_NIMP = gePointQuery( d_CurrentWindow CurrentXY "DrawWellPlugs_checkNIMP" ) + + if( gePointQuery( d_CurrentWindow CurrentXY "DrawWellPlugs_checkNWELL" ) && !d_NIMP + then + printf( "DrawWellPlugs --> Draw NWELL Plug \n" ) + + t_cellName = "M1_NACTIVE" + t_viewName = "symbolic" + t_instName = nil + t_orient = "R0" + l_origin = CurrentXY + NetName = "Vdd" + + d_inst = dbCreateInstByMasterName( d_cellView + t_libName + t_cellName + t_viewName + t_instName + l_origin + t_orient + ) + + + + NetID = dbMakeNet( d_cellView NetName ) + + + ; Create Connectivity + dbCreatePin( NetID d_inst ) + + ix1 = caar( d_inst->bBox ) + ix2 = caadr( d_inst->bBox ) + iy1 = cadar( d_inst->bBox ) + iy2 = cadadr( d_inst->bBox ) + + + if( d_PIMP + then + case( d_PIMP->objType + + ( "rect" + + px1 = caar( d_PIMP->bBox ) + px2 = caadr( d_PIMP->bBox ) + py1 = cadar( d_PIMP->bBox ) + py2 = cadadr( d_PIMP->bBox ) + + l_Path = list( px1:py1 + px1:iy2 + ix2:iy2 + ix2:iy1 + ix1:iy1 + ix1:iy2 + px1:iy2 + px1:py2 + px2:py2 + px2:py1 + px1:py1 + ) + ) + + ( "polygon" + + px1 = caar( d_PIMP->points ) + px2 = caadr( d_PIMP->points ) + py1 = cadar( d_PIMP->points ) + py2 = cadadr( d_PIMP->points ) + + l_Path = list( px1:py1 + px1:iy2 + ix2:iy2 + ix2:iy1 + ix1:iy1 + ix1:iy2 + px1:iy2 + px1:py2 + px2:py2 + px2:py1 + px1:py1 + ) + + l_path = nconc( l_Path cdr( d_PIMP->points ) ) + + ) + + );end case + + dbDeleteObject( d_PIMP ) + + d_PIMP = dbCreatePolygon( d_cellView list( "PIMP" "drawing" ) l_Path ) + + );end if + + + else + + + if( !gePointQuery( d_CurrentWindow CurrentXY "DrawWellPlugs_checkNWELL" ) && !d_PIMP + + then + + printf( "DrawWellPlugs --> Draw PWELL Plug\n" ) + + t_cellName = "M1_PACTIVE" + t_viewName = "symbolic" + t_instName = nil + t_orient = "R0" + l_origin = CurrentXY + NetName = "GND" + + d_inst = dbCreateInstByMasterName( d_cellView + t_libName + t_cellName + t_viewName + t_instName + l_origin + t_orient + ) + + + NetID = dbMakeNet( d_cellView NetName ) + + ; Create Connectivity + dbCreatePin( NetID d_inst ) + + if( d_NIMP + then + case( d_NIMP->objType + + ( "rect" + + l_Path = list( car( d_NIMP->bBox ) + caar( d_inst->bBox ):cadar( d_NIMP->bBox ) + caar( d_inst->bBox ):cadadr( d_inst->bBox ) + cadr( d_inst->bBox ) + caadr( d_inst->bBox ):cadar( d_inst->bBox ) + car( d_inst->bBox ) + caar( d_inst->bBox ):cadar( d_NIMP->bBox ) + caadr( d_NIMP->bBox ):cadar( d_NIMP->bBox ) + cadr( d_NIMP->bBox ) + caar( d_NIMP->bBox ):cadadr( d_NIMP->bBox ) + ) + + ) + + ( "polygon" + + l_Path = list( car( d_NIMP->points ) + caar( d_inst->bBox ):cadar( d_NIMP->points ) + caar( d_inst->bBox ):cadadr( d_inst->bBox ) + cadr( d_inst->bBox ) + caadr( d_inst->bBox ):cadar( d_inst->bBox ) + car( d_inst->bBox ) + caar( d_inst->bBox ):cadar( d_NIMP->points ) + ) + l_path = nconc( l_Path cdr( d_NIMP->points ) ) + + ) + + + );end case + + dbDeleteObject( d_NIMP ) + + d_NIMP = dbCreatePolygon( d_cellView list( "NIMP" "drawing" ) l_Path ) + );end if + + + else + + printf( "Error!!! You layout sucks!!! \n") + + + ); end if + + + + ); end if + + ); end let + +); end procedure + + +procedure( DrawWellPlugs_checkNIMP( fig ) + + fig->layerName == "NIMP" + +); end procedure + +procedure( DrawWellPlugs_checkPIMP( fig ) + + fig->layerName == "PIMP" + +); end procedure + +procedure( DrawWellPlugs_checkNWELL( fig ) + + fig->layerName == "NWELL" + +); end procedure + +procedure( DropWellPlug( + @key + ( libName "tsmc13lg" ) + ( cellName "M1_NWELL" ) + ( viewName "symbolic") + ( netName "Vdd" ) + ( XY nil ) + ) + + let(( CurrentXY + CurrentCellView + instName + origin + orient + ) + + CurrentCellView = geGetWindowCellView() + + if( XY + then + CurrentXY = XY + else + ; Get the cursor coordinates + CurrentXY = hiGetPoint( geGetCellViewWindow( CurrentCellView )) + );end if + + instName = nil + origin = CurrentXY + orient = "R0" + + d_inst = dbCreateInstByMasterName( CurrentCellView + libName + cellName + viewName + instName + origin + orient + ) + + NetID = dbMakeNet( CurrentCellView netName ) + + ; Create Connectivity + dbCreatePin( NetID d_inst ) + ;dbCreateConnByName( NetID d_inst "pdd" ) + + ); end let +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ExtraBasicSkills.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ExtraBasicSkills.il new file mode 100644 index 0000000000..c0a50f20a8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ExtraBasicSkills.il @@ -0,0 +1,540 @@ +; This Fuction is resize the windowsimilar to "dbGetOverlaps" +; except it will filter out completely abutted (aligned) cells +procedure( dbGetOverlapsNoAbutted( d_cellView ) + + OverlappedCellList = dbGetOverlaps( d_cellView->cellView d_cellView->bBox nil) + OverlappedCellListNoAbutted = '() + + x_low_org = car( car( d_cellView->bBox ) ) + y_low_org = car( cdr( car( d_cellView->bBox ) ) ) + x_high_org = car( car( cdr( d_cellView->bBox ) ) ) + y_high_org = car( cdr( car( cdr( d_cellView->bBox ) ) ) ) + + foreach( OverlappedCell OverlappedCellList + + ; Get Coordinations + x_low = car( car( OverlappedCell->bBox ) ) + y_low = car( cdr( car( OverlappedCell->bBox ) ) ) + x_high = car( car( cdr( OverlappedCell->bBox ) ) ) + y_high = car( cdr( car( cdr( OverlappedCell->bBox ) ) ) ) + + ; Set Filter to True by default + FilterResult = "Filter" + + + ;Check for itself + if( OverlappedCell == d_cellView + + then + FilterResult = "NoFilter" + ) ;end if + + + ;Check for Abutment + if( ( x_low == x_high_org ) || + ( x_high == x_low_org ) || + ( y_low == y_high_org ) || + ( y_high == y_low_org ) + + then + FilterResult = "NoFilter" + ) ;end if + + + ; Appending to the new List + if( FilterResult == "Filter" + + then + + OverlappedCellListNoAbutted = cons( OverlappedCell OverlappedCellListNoAbutted ) + ) + + + ) ;foreach + + ; Return Value + OverlappedCellListNoAbutted + +) ;procedure + + + + +; This Fuction is an enhanced version of the dbGetNeighbor in the sense that +; it will ignore any abutted or non-instance type neighbors +procedure( dbGetNeighborInstanceNoAbutted( d_cellView direction ) + + cellNeighborList = dbGetNeighborList( d_cellView->cellView d_cellView->bBox direction ) + + ; x and y coordinates for the selected object + x_low_org = car( car( d_cellView->bBox ) ) + y_low_org = car( cdr( car( d_cellView->bBox ) ) ) + x_high_org = car( car( cdr( d_cellView->bBox ) ) ) + y_high_org = car( cdr( car( cdr( d_cellView->bBox ) ) ) ) + + ; Initialize Variables + x_min = abs( car( car( geGetWindowCellView()->bBox)) - car( car( cdr( geGetWindowCellView()->bBox ) ) ) ) + y_min = abs( car( cdr( car( geGetWindowCellView()->bBox))) - car( cdr( car( cdr( geGetWindowCellView()->bBox ) ) ) ) ) + d_closestNeighbor = nil + + foreach( cellNeighbor cellNeighborList + + d_cellNeighbor = car( cdr( cellNeighbor)) + + if( !listp( d_cellNeighbor ) && ( d_cellNeighbor->objType == "inst") + + then + ; Get Coordinations + x_low = car( car( d_cellNeighbor->bBox ) ) + y_low = car( cdr( car( d_cellNeighbor->bBox ) ) ) + x_high = car( car( cdr( d_cellNeighbor->bBox ) ) ) + y_high = car( cdr( car( cdr( d_cellNeighbor->bBox ) ) ) ) + + if( ( direction == "L" && + y_low != y_high_org && + y_high != y_low_org ) + then + x_diff = abs( x_low_org - x_high ) + + if( x_diff < x_min + then + d_closestNeighbor = d_cellNeighbor + x_min = x_diff + ) ;end if + + ) + + if( ( direction == "R" && + y_low != y_high_org && + y_high != y_low_org ) + then + x_diff = abs( x_high_org - x_low ) + + if( x_diff < x_min + then + d_closestNeighbor = d_cellNeighbor + x_min = x_diff + ) ;end if + + ) + + if( ( direction == "T" && + x_low != x_high_org && + x_high != x_low_org ) + then + y_diff = abs( y_high_org - y_low ) + + if( y_diff < y_min + then + d_closestNeighbor = d_cellNeighbor + y_min = y_diff + ) ;end if + + ) + + if( ( direction == "B" && + x_low != x_high_org && + x_high != x_low_org ) + then + y_diff = abs( y_low_org - y_high ) + + if( y_diff < y_min + then + d_closestNeighbor = d_cellNeighbor + y_min = y_diff + ) ;end if + + ) + + + ) ;end if + + ) ;end foreach + + ; Return Value + d_closestNeighbor + +) ;procedure + + + +; This Fuction is used to sort a list of d_objects w.r.t. their instance names +; It does NOT do an error check on the input list (i.e. it always assume that the input is a list of dbObjects +procedure( dbSortDBList( l_d_cellView ) + + let( ( genericPattern + l_d_cellViewSorted) + + l_d_cellViewSorted = nil + +; genericPattern = "\\[N\\]$" + genericPattern = "\\[N\\][\\.]*[a-zA-Z0-9]*$" + + while( l_d_cellView != nil + + for( i 0 1024 + iString = sprintf( nil "%d" i) + + rexCompile( "N" ) + actualPattern = rexReplace( genericPattern iString 0 ) + + rexCompile( actualPattern ) + + foreach( d_cellView l_d_cellView + + if( rexExecute( d_cellView->name ) + + then + + printf( "dbSortDBList --> Instance %s matches pattern %s \n" d_cellView->name actualPattern ) + l_d_cellView = remove( d_cellView l_d_cellView ) + l_d_cellViewSorted = cons( d_cellView l_d_cellViewSorted ) + + ); end if + + ); end foreach + + ); end for + + ; In case the instance names do not match any of the pre-defined hashed table + ; Just append the rest of the string to the front (= back after reverse) + l_d_cellViewSorted = nconc( l_d_cellView l_d_cellViewSorted ) + l_d_cellView = nil + + ); end while + + reverse( l_d_cellViewSorted ) + + ); end let + +); end procedure + + +; ============================================================================================= +; This Fuction is used to flip an instance upside down +; It works on multiple # of instances +; This procedure assumes that the selected instances do not have any rotation "R90" "R180" etc +; ============================================================================================= +procedure( dbFlipInstanceUD( ) + let( ( + y_low + y_high + y_origin + bBox + cellHeight + yOffset + returnValue) + + returnValue = t + + l_d_cellView = geGetSelectedSet( ) + + foreach( d_cellView l_d_cellView + + bBox = d_cellView->bBox + y_low = car( cdr( car( bBox))) + y_high = car( cdr( car( cdr( bBox)))) + y_origin = car( cdr( d_cellView->xy ) ) + cellHeight = y_high - y_low + yOffset = cellHeight - 2 * (y_origin - y_low) + + + case( d_cellView->orient + + ( "MX" + d_cellView->orient = "R0" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( "R0" + d_cellView->orient = "MX" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( "R90" + d_cellView->orient = "MYR90" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( "MYR90" + d_cellView->orient = "R90" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( "R180" + d_cellView->orient = "MY" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( "MY" + d_cellView->orient = "R180" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( "R270" + d_cellView->orient = "MXR90" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( "MXR90" + d_cellView->orient = "R270" + dbMoveFig( d_cellView, nil, list(0:yOffset "R0")) + ) + + ( t + returnValue = nil + ) + + ); end case + + ); end foreach + + returnValue + + ); end let + +); end procedure + +procedure( dbFlipInstanceLR( ) + let( ( + x_low + x_high + x_origin + bBox + cellWidth + xOffset + returnValue) + + returnValue = t + + l_d_cellView = geGetSelectedSet( ) + + foreach( d_cellView l_d_cellView + + bBox = d_cellView->bBox + x_low = car( car( bBox)) + x_high = car( car( cdr( bBox))) + x_origin = car( d_cellView->xy ) + cellWidth = x_high - x_low + xOffset = cellWidth - 2 * (x_origin - x_low) + + case( d_cellView->orient + + ( "MY" + d_cellView->orient = "R0" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( "R0" + d_cellView->orient = "MY" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( "MYR90" + d_cellView->orient = "R270" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( "R270" + d_cellView->orient = "MYR90" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( "MX" + d_cellView->orient = "R180" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( "R180" + d_cellView->orient = "MX" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( "MXR90" + d_cellView->orient = "R90" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( "R90" + d_cellView->orient = "MXR90" + dbMoveFig( d_cellView, nil, list(xOffset:0 "R0")) + ) + + ( t + returnValue = nil + ) + + ); end case + + ); end foreach + + returnValue + + ); end let + +); end procedure + + +; This function is a wrap around of the dbFlipInstance +; it will flip it in unit of a group +procedure( DB_FlipGroup( direction ) + + let( ( l_d_cellView + libName + cellName + viewName + d_tempCell + returnValue + ) + + l_d_cellView = geGetSelectedSet( ) + libName = geGetWindowCellView()->libName + cellName = "tempCell" + viewName = "layout" + returnValue = t + + leMakeCell( l_d_cellView libName cellName viewName t ) + + geSelectAllFig( geGetWindowCellView()) + l_d_cellView = geGetSelectedSet( ) + + foreach( d_cellView l_d_cellView + if( d_cellView->cellName != cellName + then + geDeselectFig( d_cellView ) + else + d_tempCell = d_cellView + );end if + ); end foreach + + if( direction == "UD" + then + dbFlipInstanceUD( ) + else + dbFlipInstanceLR( ) + );end if + + dbFlattenInst( d_tempCell 1 ) + + ddDeleteLocal( ddGetObj( libName cellName viewName ) ) + + returnValue + + ); end let + +); end procedure + + +; ============================================================= +; Simple Move Procedure Similar to MAGIC Move Command +; ============================================================= +procedure( Move( direction value @key ( DebugOn nil )) + + let(( returnValue + l_d_Selected + ) + + returnValue = t + l_d_Selected = geGetSelectedSet( ) + + foreach( d_Selected l_d_Selected + case( direction + ( "l" + dbMoveFig( d_Selected nil list( -value:0 "0" )) + ) + ( "r" + dbMoveFig( d_Selected nil list( value:0 "0" )) + ) + ( "u" + dbMoveFig( d_Selected nil list( 0:value "0" )) + ) + ( "d" + dbMoveFig( d_Selected nil list( 0:-value "0" )) + ) + ); end case + ); end foreach + + + ); end let + +); end procedure + +procedure( ML( value ) + + Move( "l" value ) + +); end procedure + +procedure( MR( value ) + + Move( "r" value ) + +); end procedure + +procedure( MU( value ) + + Move( "u" value ) + +); end procedure + +procedure( MD( value ) + + Move( "d" value ) + +); end procedure + + +; ============================================================= +; Simple Move Procedure Similar to MAGIC Copy Command +; ============================================================= +procedure( Copy( direction value @key ( DebugOn nil )) + + let(( returnValue + l_d_Selected + d_Selected + ) + + returnValue = t + l_d_Selected = geGetSelectedSet( ) + + case( direction + ( "l" + geCopySelSet(geGetCellViewWindow(geGetWindowCellView()) list(0 0) list(-value 0)) + ) + ( "r" + geCopySelSet(geGetCellViewWindow(geGetWindowCellView()) list(0 0) list(value 0)) + ) + ( "u" + geCopySelSet(geGetCellViewWindow(geGetWindowCellView()) list(0 0) list(0 value)) + ) + ( "d" + geCopySelSet(geGetCellViewWindow(geGetWindowCellView()) list(0 0) list(0 -value)) + ) + ); end case + + returnValue + + ); end let + +); end procedure + +procedure( CL( value ) + + Copy( "l" value ) + +) +procedure( CR( value ) + + Copy( "r" value ) + +) +procedure( CU( value ) + + Copy( "u" value ) + +) +procedure( CD( value ) + + Copy( "d" value ) + +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FL_Overlap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FL_Overlap.il new file mode 100644 index 0000000000..88e057a4ae --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FL_Overlap.il @@ -0,0 +1,53 @@ +; Copyright 2006 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus.il#4 $ +; $DateTime: 2006/09/08 20:01:38 $ +; $Author: lines $ + +; Flatten prBoundary shapes to overlap view, then select any overlaps +(defun FL_Overlap (@key (CV (geGetEditCellView))) + (let (ovCV window instances pts + pr_list count BB x0 y0 x1 y1 overlap_list) + + ; create overlap CV + window = (geOpen ?lib CV->libName ?cell CV->cellName + ?view "overlap" ?viewType "maskLayout" ?mode "w") + ovCV = (geGetWindowCellView window) + + ; load the full hierarchy + (dbOpenHier CV 32) + + ; create shapes from PRBoundary boundary objects + instPaths=(dbBoundaryQuery CV CV->bBox) + (foreach item instPaths + pts=TransformGetBBoxFromPath(item) + (dbCreateRect ovCV BoundaryLPP pts) + ) + + ; make a list of prBoundaries shapes + pr_list = (setof scell ovCV->shapes scell->lpp=BoundaryLPP ) + + ; for each prBoundary, look for overlaps + count = 0 + (geDeselectAllFig ovCV) + (foreach obj1 pr_list + + ; shrink BBox slightly + BB = obj1->bBox + x0 = (car (car BB)) + 0.01 + y0 = (cadr (car BB)) + 0.01 + x1 = (car (cadr BB)) - 0.01 + y1 = (cadr (cadr BB)) - 0.01 + BB = (list x0:y0 x1:y1) + + ; find any overlapping prBoundary + overlap_list = (dbGetOverlaps ovCV BB (list "prBoundary")) + + ; select overlapping shapes + (cond ((length overlap_list)>1 + (foreach obj2 overlap_list (geSelectFig obj2)))) + ) + + ; return number of overlaps + (length (geGetSelSet)) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FloorplanCells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FloorplanCells.il new file mode 100644 index 0000000000..17ef587c0b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FloorplanCells.il @@ -0,0 +1,273 @@ +; Work on Selected Cells Only +; Return Value = x:y relative to the input x:y + +procedure( FloorplanCells( x y + @key + ( Dimension 0 ) + ( Type "Data" ) + ( Orientation "NA" ) + ( HashList nil ) + ( DebugOn nil ) + ( BitPitch 0 ) + ( DatapathHeight 0 ) + ( NumBitsPerCell 0 ) + ) + + ; local Varibales + let( ( l_d_SelectedCell + xOffset x_Selected x_Multiplier x_Shifter xHashList + yOffset y_Selected y_Multiplier y_Shifter yHashlist yCellHeight yMaxBitNum + width height + num_column + num_row + max_Index + max_Height + returnValue) + + num_column = 1 + num_row = 1 + l_d_SelectedCell = geGetSelectedSet( ) + + x_Multiplier = 1 + x_Shifter = 0 + + ; Make sure that all indices increases in positive x and positive y direction + ; =========================================================================== + xHashList = car( HashList ) + yHashList = cadr( HashList ) + if( Type == "Ctrl" + then + case( car( yHashList ) + ( nil + yHashList = list( -1 ) + ) + ( -1 + yHashList = nil + ) + ); end case + ); end if + + + + + x_Shifter2 = 0 + y_Shifter2 = 0 + + DebugOn && printf( "FloorplanCells --> Strating Procedure xHashList=%L yHashList=%L \n" xHashList yHashList) + + + ; Deals with Horizontal Hashing + if( xHashList != nil + then + case( car( xHashList ) + ( -1 + DebugOn && printf( "FloorplanCells --> Inverting x-arrays for %s\n" car( l_d_SelectedCell )->name ) + x_Multiplier = -1 + x_Shifter = 1 + x_Shifter2 = 1 + ) + ); end case + ); end if + + ; Deals with Vertical Hashing + if( yHashList != nil + then + case( car( yHashList ) + ( -1 + DebugOn && printf( "FloorplanCells --> Inverting y-arrays for %s\n" car( l_d_SelectedCell )->name ) + case( Type + ("Data" + y_Multiplier = -1 + y_Shifter = 1 + y_Shifter2 = 1 + ) + ("Ctrl" + y_Multiplier = 1 + y_Shifter = 0 + y_Shifter2 = -1 + ) + ) + ) + ); end case + else + case( Type + + ( "Data" + y_Multiplier = 1 + y_Shifter = 0 + ) + + ( "Ctrl" + y_Multiplier = -1 + y_Shifter = 1 + ) + + ) + ) + + ; ======================================================================================================================================= + ; SMART Floorplanning + ; Setting the CellHeight + ; ======================================================================================================================================= + yMaxBitNum = cadr( GetMaxIndex( l_d_SelectedCell ?Orientation Orientation )) + 1 + + if( BitPitch > 0 && Type == "Data" && yMaxBitNum > 1 && NumBitsPerCell == 0 + then + NumBitsPerCell = round( float( DatapathHeight ) / ( yMaxBitNum * BitPitch ) ) + ) + + if( BitPitch > 0 && Type == "Data" + then + yCellHeight = max( BitPitch BitPitch*NumBitsPerCell cadadr( car( l_d_SelectedCell )->bBox ) - cadar( car( l_d_SelectedCell )->bBox )) + else + yCellHeight = cadadr( car( l_d_SelectedCell )->bBox ) - cadar( car( l_d_SelectedCell )->bBox ) + ) + + foreach( d_SelectedCell l_d_SelectedCell + + x_Selected = caar( d_SelectedCell->bBox ) + y_Selected = cadar( d_SelectedCell->bBox ) + + xOffset = x - x_Selected + yOffset = y - y_Selected + + xOffset = xOffset + ( car( GetIndex( d_SelectedCell->name ?Orientation Orientation ) ) + x_Shifter ) * x_Multiplier * + ( caadr( d_SelectedCell->bBox ) - caar( d_SelectedCell->bBox )) + + yOffset = yOffset + ( cadr( GetIndex( d_SelectedCell->name ?Orientation Orientation ) ) + y_Shifter ) * y_Multiplier * yCellHeight + + num_column = max( num_column car( GetIndex( d_SelectedCell->name ?Orientation Orientation ))+1 ) + num_row = max( num_row cadr( GetIndex( d_SelectedCell->name ?Orientation Orientation ))+1 ) + + dbMoveFig( d_SelectedCell, nil, list(xOffset:yOffset "R0")) + + ); end foreach + + width = ( caadr( car( l_d_SelectedCell )->bBox ) - caar( car( l_d_SelectedCell )->bBox ) ) * num_column + height = yCellHeight * num_row + + + foreach( d_SelectedCell l_d_SelectedCell + dbMoveFig( d_SelectedCell, nil, list(width*x_Shifter2:height*y_Shifter2 "R0")) + ) + + ; Return Value + width + + ); end let + + +); end procedure + + +;========================================================================================================= +; This procedure get the index list of a particular string in the form of list( x y z ) +; where x = horizontal index +; y = vertical index +; z = UNUSED +;========================================================================================================= +procedure( GetIndex( String @key (Orientation "NA" )) + + let( ( l_Substring + l_returnIndex ) + + l_Substring = parseString( String "[]" ) + l_returnIndex = nil + + + foreach( Substring l_Substring + + rexCompile( "[0-9\\-]" ) + if( rexExecute( Substring ) + then + + rexCompile( "[a-zA-Z]" ) + if( !rexExecute( Substring ) + then + l_returnIndex = reverse( cons( evalstring( Substring ) reverse( l_returnIndex ))) + ); end if + + ); end if + + ); end foreach + + ; Post-processing + ; Supports 3-D i.e list( a b c ) + case( length( l_returnIndex ) + + (0 + l_returnIndex = list( 0 0 0 ) + ) + + (1 + case( Orientation + ( "V" + l_returnIndex = list( 0 car(l_returnIndex) 0 ) + ) + ( "H" + l_returnIndex = list( car(l_returnIndex) 0 0 ) + ) + ( t + l_returnIndex = list( 0 car(l_returnIndex) 0 ) + ) + ) + ) + + (2 + case( Orientation + ( "HV" + l_returnIndex = list( car(l_returnIndex) cadr(l_returnIndex) 0 ) + ) + ( "VH" + l_returnIndex = list( cadr(l_returnIndex) car(l_returnIndex) 0 ) + ) + ( t + l_returnIndex = list( car(l_returnIndex) cadr(l_returnIndex) 0 ) + ) + ) + ) + + ); end case + + l_returnIndex + + ); end let + +); end procedure + + +;========================================================================================================= +; This procedure get the total number of horizontal and vertical cells in the given cell list +; Return Value is in the form of list( x y z ) +; where x = number of horizontal cells +; y = number of vertical cells +; z = UNUSED +;========================================================================================================= +procedure( GetMaxIndex( l_d_Cell @key (Orientation "NA" ) ( DebugOn nil )) + + let(( l_returnValue + l_tempValue + ) + + l_returnValue = list( 0 0 0 ) + + DebugOn && printf( "=============================================================\n" ) + foreach( d_Cell l_d_Cell + + l_tempValue = GetIndex( d_Cell->name ?Orientation Orientation ) + DebugOn && printf( "GetMaxIndex --> Processing \"%s\" => list%L \n" d_Cell->name l_tempValue ) + + l_returnValue = list( max( car( l_returnValue ) car( l_tempValue )) + max( cadr( l_returnValue ) cadr( l_tempValue )) + 0 + ) + ); end foreach + + DebugOn && printf( "GetMaxIndex --> l_returnValue = list%L \n" l_returnValue ) + DebugOn && printf( "=============================================================\n" ) + + l_returnValue + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/Floorplanner.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/Floorplanner.il new file mode 100644 index 0000000000..caffdcd0b3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/Floorplanner.il @@ -0,0 +1,178 @@ +; This Fuction is used to create a resonable floorplan for a given initial layout +; It will retain the rotation properties of the cells +; Assumption +; All Bit-slice cells are in the form "AAA[NNN][NNN]" or "AAA[NNN]" +; All non-bit-slice cells can be named anything but not containing "[" or "]" + +procedure( Floorplan( ) + + ; local Varibales + let( ( l_d_SelectedCell + l_d_NonArrayCell + x_org x xOffset + y_org y yOffset + matchPattern + returnValue + maxDataPathHeight + NonArrayCellHeight + bitHeight) + + l_d_SelectedCell = geGetSelectedSet( ) + l_d_NonArrayCell = nil + returnValue = t + x_org = 0 + y_org = 0 + x = x_org + y = y_org + maxDataPathHeight = 0 + NonArrayCellHeight = 0 + bitHeight = 19.2 + + geDeselectAllFig( geGetWindowCellView() ) + + ; Filter out Non-bit-slice Cells +; rexCompile( "\\[[0-9]+\\]$" ) + rexCompile( "\\[[0-9]+\\][\\.]*[a-zA-Z0-9]*$" ) + foreach( d_SelectedCell l_d_SelectedCell + + if( rexExecute( d_SelectedCell->name ) == nil + then + l_d_SelectedCell = remove( d_SelectedCell l_d_SelectedCell ) + l_d_NonArrayCell = cons( d_SelectedCell l_d_NonArrayCell ) + ); end if + + + ); end foreach + + + while( l_d_SelectedCell != nil + + geDeselectAllFig( geGetWindowCellView() ) + + + matchPattern = car( l_d_SelectedCell )->name + rexCompile( "\\[" ) + matchPattern = rexReplace( matchPattern "\\\\\\[" 0 ) + rexCompile( "\\]" ) + matchPattern = rexReplace( matchPattern "\\\\\\]" 0 ) +; rexCompile( "\\[[0-9]+\\\\\\]$" ) + rexCompile( "\\[[0-9]+\\\\\\][\\.]*[a-zA-Z0-9]*$" ) +; matchPattern = rexReplace( matchPattern "[[0-9]+\\\\\\]$" 0 ) + matchPattern = rexReplace( matchPattern "[[0-9]+\\\\\\][\\.]*[a-zA-Z0-9]*$" 0 ) + + rexCompile( matchPattern ) + + xOffset = abs( car( car( car( l_d_SelectedCell )->bBox)) - car( car( cdr( car( l_d_SelectedCell )->bBox)))) + + printf( "Floorplan --> Start forming DataPath for Pattern %s \n" matchPattern ) + printf( "Floorplan --> " ) + + ; Re-initialize Variable + numArrayCell = 0 + + foreach( d_SelectedCell l_d_SelectedCell + + if( rexExecute( d_SelectedCell->name ) + then + geSelectFig( d_SelectedCell ) + l_d_SelectedCell = remove( d_SelectedCell l_d_SelectedCell ) + numArrayCell = numArrayCell + 1 + heightArrayCell = abs( car( cdr( car( d_SelectedCell->bBox ))) - car( cdr( car( cdr( d_SelectedCell->bBox ))))) + printf( "%s " d_SelectedCell->name) + + ); end if + + ); end foreach + + maxDataPathHeight = max( maxDataPathHeight numArrayCell*heightArrayCell ) + + printf( "\n" ) + printf( "Floorplan --> End forming DataPath for Pattern %s \n" matchPattern ) + + AlignCellsV( x y 0 nil ) + + x = x + xOffset + + ); end while + + ; Report maxDataPathHeight + printf( "Floorplan --> maxDataPathHeight = %n \n" maxDataPathHeight ) + printf( "Floorplan --> Height of 8 bits = %n \n" bitHeight*8 ) + printf( "Floorplan --> Any non-array cells with height > min( %n %n ) will be treated as part of Datapath \n" maxDataPathHeight*0.45 bitHeight*8 ) + + + + + ; Doing non-array cells that's part of DataPath + + geDeselectAllFig( geGetWindowCellView() ) + + foreach( d_NonArrayCell l_d_NonArrayCell + + NonArrayCellHeight = abs( car( cdr( car( d_NonArrayCell->bBox ))) - car( cdr( car( cdr( d_NonArrayCell->bBox ))))) + if( NonArrayCellHeight > min( maxDataPathHeight*0.45 bitHeight*8 ) + + then + printf( "Floorplan --> Non-array Cell \"%s\" with a height of %n is being added into the Datapath \n" d_NonArrayCell->name NonArrayCellHeight ) + geSelectFig( d_NonArrayCell ) + l_d_NonArrayCell = remove( d_NonArrayCell l_d_NonArrayCell ) + AlignCellsV( x y 0 nil ) + xOffset = abs( car( car( d_NonArrayCell->bBox )) - car( car( cdr( d_NonArrayCell->bBox )))) + x = x + xOffset + geDeselectAllFig( geGetWindowCellView() ) + + ) ;end if + + ); end foreach + + + + ; Doing non-array cells that's NOT part of DataPath + ; Reset Variables + geDeselectAllFig( geGetWindowCellView() ) + x = x_org + y = y_org + + foreach( d_NonArrayCell l_d_NonArrayCell + printf( "Floorplan --> Non-array Cell \"%s\" is being added into Control \n" d_NonArrayCell->name ) + yOffset = abs( car( cdr( car( d_NonArrayCell->bBox ))) - car( cdr( car( cdr( d_NonArrayCell->bBox ))))) + y = y_org - yOffset + + geSelectFig( d_NonArrayCell ) + AlignCellsV( x y 0 nil ) + geDeselectAllFig( geGetWindowCellView() ) + + xOffset = abs( car( car( d_NonArrayCell->bBox )) - car( car( cdr( d_NonArrayCell->bBox )))) + x = x + xOffset + + ); end foreach + + + ; Return Value + returnValue + + ) ; end let + +); end procedure + +; ============================================================ +; Useful Pattern Matching Code +; ============================================================ +;A = "BUF[9]" + +;rexCompile( "\\[" ) +;A = rexReplace( A "\\\\\\[" 0 ) +;rexCompile( "\\]" ) +;A = rexReplace( A "\\\\\\]" 0 ) + + +;rexCompile( "\\[[0-9]+\\\\\\]$" ) +;matchPattern = rexReplace( A "[[0-9]+\\\\\\]$" 0 ) + +; ============================================================ + + + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumLoad.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumLoad.il new file mode 100644 index 0000000000..7ede5b668b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumLoad.il @@ -0,0 +1,29 @@ +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/DrawWellPlugs.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/AlignCells.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/AlignCellsNonOverlap.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/GetOverlaps.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/SetDeleteViewLevels.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/ManageWindows.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/MoveToSnap.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/SelectSameMaster.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/AlignCellsDataPath.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/Floorplanner.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_FloorplanArray.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/ShowName.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/trZoom.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/ExtraBasicSkills.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_MoveAndSnap.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_MoveAndSnap.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_HiLiteLabels.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_FindInstance.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_Floorplanner.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/AnalysisLayout.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/FloorplanCells.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/CompactCells.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/M_Floorplan.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/M_Verify.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/M_Main.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/PathFinder.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/GlobalHiliteStack.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_CrawFish.il")) +load( sprintf( nil "%s/share/skill/layout/fulcrum_setup/%s" VirtuosoHome "/TR_ChangeInstName.il")) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumSetup.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumSetup.il new file mode 100644 index 0000000000..3e6b6aa04e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/FulcrumSetup.il @@ -0,0 +1,130 @@ +; In-house Skill Files +; ==================== +defun( FulcrumSetup () + +printf("Loading FulcrumSetup bindkeys...\n") +hiSetBindKey( "Layout" "h" "SetSnap_x4_8_y9_6_Key_h( )" ) +hiSetBindKey( "Layout" "h" "AlignCells( PowerGridPitch 2*PowerGridPitch 0 0 )" ) + +hiSetBindKey( "Layout" "j" "SetSnap_x0_48_y9_6_Key_j( )" ) +hiSetBindKey( "Layout" "j" "AlignCells( 0.24 2*PowerGridPitch 0 0 )" ) + +hiSetBindKey( "Layout" "o" "GetOverlaps( )" ) + +hiSetBindKey( "Layout" "1" "SetViewLevels( 0 1 )" ) +hiSetBindKey( "Layout" "2" "SetViewLevels( 0 2 )" ) +hiSetBindKey( "Layout" "3" "SetViewLevels( 0 3 )" ) +hiSetBindKey( "Layout" "4" "SetViewLevels( 0 4 )" ) +hiSetBindKey( "Layout" "5" "SetViewLevels( 0 5 )" ) +hiSetBindKey( "Layout" "6" "SetViewLevels( 0 6 )" ) +hiSetBindKey( "Layout" "7" "SetViewLevels( 0 7 )" ) +hiSetBindKey( "Layout" "8" "SetViewLevels( 0 8 )" ) +hiSetBindKey( "Layout" "9" "SetViewLevels( 0 32 )" ) + +hiSetBindKey( "Layout" "1" "SetViewLevels( 1 1 )" ) +hiSetBindKey( "Layout" "2" "SetViewLevels( 2 2 )" ) +hiSetBindKey( "Layout" "3" "SetViewLevels( 3 3 )" ) +hiSetBindKey( "Layout" "4" "SetViewLevels( 4 4 )" ) +hiSetBindKey( "Layout" "5" "SetViewLevels( 5 5 )" ) +hiSetBindKey( "Layout" "6" "SetViewLevels( 6 6 )" ) +hiSetBindKey( "Layout" "7" "SetViewLevels( 7 7 )" ) +hiSetBindKey( "Layout" "8" "SetViewLevels( 8 8 )" ) + +hiSetBindKey( "Layout" "1" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "2" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "3" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "4" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "5" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "6" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "7" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "8" "DeleteViewLevels()" ) + +hiSetBindKey( "Layout" "w" "ResizeWindow( \"half\" )" ) +hiSetBindKey( "Layout" "i" "IconifyWindow( )" ) +hiSetBindKey( "Layout" "i" "DeiconifyWindow( )" ) + +hiSetBindKey( "Layout" "Left" "MoveToSnap( \"L\" )" ) +hiSetBindKey( "Layout" "Right" "MoveToSnap( \"R\" )" ) +hiSetBindKey( "Layout" "Up" "MoveToSnap( \"T\" )" ) +hiSetBindKey( "Layout" "Down" "MoveToSnap( \"B\" )" ) + +hiSetBindKey( "Layout" "Left" "MoveToSnapAlignV( \"L\" )" ) +hiSetBindKey( "Layout" "Right" "MoveToSnapAlignV( \"R\" )" ) +hiSetBindKey( "Layout" "Up" "MoveToSnapAlignV( \"T\" )" ) +hiSetBindKey( "Layout" "Down" "MoveToSnapAlignV( \"B\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Left" "MoveToSnapAlignV( \"L\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Right" "MoveToSnapAlignV( \"R\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Up" "MoveToSnapAlignV( \"T\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Down" "MoveToSnapAlignV( \"B\" )" ) + +hiSetBindKey( "Layout" "s" "SelectSameMaster( )" ) + +;hiSetBindKey( "Layout" "v" "AlignCellsV( 0 0 0 nil )" ) +hiSetBindKey( "Layout" "v" "hiDisplayForm( trAlignCellsVForm )" ) + +hiSetBindKey( "Layout" "Ctrl Shift p" "Floorplan( )" ) + +hiSetBindKey( "Layout" "Alt Ctrl p" "TR_FloorplanArray( )" ) +hiSetBindKey( "Layout" "Alt p" "ArrayCells( )" ) + +hiSetBindKey( "Layout" "n" "ShowNameInstance( )" ) +hiSetBindKey( "Layout" "n" "ShowNameMaster( )" ) + +hiSetBindKey( "Layout" "F6" "hiDisplayForm( A )" ) + +hiSetBindKey( "Layout" "u" "dbFlipInstanceUD( )" ) +;hiSetBindKey( "Layout" "l" "dbFlipInstanceLR( )" ) + +hiSetBindKey( "Layout" "u" "DB_FlipGroup( \"UD\" )" ) +hiSetBindKey( "Layout" "l" "DB_FlipGroup( \"LR\" )" ) + +; SetSnapping +; =========== + + +; MoveAndSnap +; =========== +(hiSetBindKey "Layout" "AltLeft" "(MoveAndSnap \"L\" )" ) +(hiSetBindKey "Layout" "AltRight" "(MoveAndSnap \"R\" )" ) +(hiSetBindKey "Layout" "AltUp" "(MoveAndSnap \"U\" )" ) +(hiSetBindKey "Layout" "AltDown" "(MoveAndSnap \"D\" )" ) +(hiSetBindKey "Layout" "Altz" "(MoveAndSnap \"L\" )" ) +(hiSetBindKey "Layout" "Altc" "(MoveAndSnap \"R\" )" ) +(hiSetBindKey "Layout" "Alts" "(MoveAndSnap \"U\" )" ) +(hiSetBindKey "Layout" "Altx" "(MoveAndSnap \"D\" )" ) +(hiSetBindKey "Layout" "F5" "TR_MoveAndSnap( )" ) + +; vi-style cell movement bindings +(hiSetBindKey "Layout" "Ctrlh" "(MoveAndSnap \"L\" )" ) +(hiSetBindKey "Layout" "Ctrll" "(MoveAndSnap \"R\" )" ) +(hiSetBindKey "Layout" "Ctrlk" "(MoveAndSnap \"U\" )" ) +(hiSetBindKey "Layout" "Ctrlj" "(MoveAndSnap \"D\" )" ) + + +hiSetBindKey( "Layout" "Shiftl" "AddHiLiteLabels( )" ) +;hiSetBindKey( "Layout" "Ctrl l" "ZoomToHiLiteLabels( )" ) +hiSetBindKey( "Layout" "Ctrl Shift l" "TR_AddHiLiteLabels( )" ) + +hiSetBindKey( "Layout" "F4" "TR_FindInstance( )" ) + +hiSetBindKey( "Layout" "Ctrl p" "TR_Floorplanner( )" ) + + +; CrawFish Module +; =============== + +hiSetBindKey( "Layout" "Ctrl q" "TR_AssuraLVS( )" ) + +; olap +; =============== +hiSetBindKey( "Layout" "Ctrl Shifto" "FL_Overlap( )" ) + + +; Enhancement +; =========== +hiSetBindKey( "Layout" "Alt q" "TR_ChangeInstNameProcGUI( )" ) + +) + + +FulcrumSetup() diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GetOverlaps.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GetOverlaps.il new file mode 100644 index 0000000000..4fcd107aea --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GetOverlaps.il @@ -0,0 +1,45 @@ +; This Skill Code will select cells ("inst") whish is overlapping with the seleceted cells +; The code will automatically filter out unrelated object type (eg. "shape" "rect") and +; will not consider them in the process +; +; Example +; ------- +; Consider a layout with only instances A, B, C and one rectangle D +; Suppose: A overlaps with B, C overlaps with the rectangle D, both groups (AB and CD) +; do not intersect +; +; (1) If A,B,C,D are selected to run this skill code +; ==> only A and B will result in selection (since the code pays no attention to "rectangles" +; +; (2) If only rectangle D is selected +; ==> nothing will be in the selection (for the same reason in (1)) +; +; (3) If only instance A is selected +; ==> Instance B will be in the selection (not A as it is treated as the source) + +procedure( GetOverlaps( ) + + SelectedCellList = geGetSelSet( ) + + geDeselectAllFig( geGetWindowCellView( ) ) + + foreach( SelectedCell SelectedCellList + + if( SelectedCell->objType == "inst" + + then + overlap_list = dbGetOverlaps( geGetWindowCellView( ) SelectedCell->bBox nil ) + + foreach( overlap_object overlap_list + + if( !( overlap_object == SelectedCell ) + then + geSelectFig( overlap_object ) + ) ;if + + ) ;foreach + ) ; if + + ) ;foreach + +) ;procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GlobalHiliteStack.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GlobalHiliteStack.il new file mode 100644 index 0000000000..3515d2f3a8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/GlobalHiliteStack.il @@ -0,0 +1,67 @@ +; Global Variable +; +; 1. Global_HitliteStack + +GlobalHiliteStack = nil + +; ============================================================================================ +; This procedure is used to create a hilite rectange griup and do nothing +; ============================================================================================ + +procedure( GlobalHiliteStack_Pop( ) + + if( geGetCurrentHilightSet( geGetWindowCellView()) + then + GlobalHiliteStack = cons( geGetCurrentHilightSet( geGetWindowCellView()) GlobalHiliteStack) + ) + gePopHilightStack( geGetWindowCellView( )) +) + + +; ============================================================================================ +; This procedure is used to create a hilite rectange griup and do nothing +; ============================================================================================ + +procedure( GlobalHiliteStack_Push( ) + + if( car( GlobalHiliteStack ) + then + gePushHilightStack( car( GlobalHiliteStack ) ) + ) + GlobalHiliteStack = cdr( GlobalHiliteStack ) +) + +; ============================================================================================ +; This procedure is used to delete a hilite group +; ============================================================================================ + +procedure( GlobalHiliteStack_Delete( ) + + gePopHilightStack( geGetWindowCellView( )) + +) + +; ============================================================================================ +; This procedure is used to clear the entire stack +; ============================================================================================ + +procedure( GlobalHiliteStack_Clear( ) + + let(( isFinish ) + + ; Local Variables + ; =============== + isFinish = nil + + while( !isFinish + gePopHilightStack( geGetWindowCellView( )) + if( !geGetCurrentHilightSet( geGetWindowCellView( )) + then + isFinish = t + ); end if + ); end while + + ); end let + +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6 b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6 new file mode 100644 index 0000000000..b346c5ac00 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6 @@ -0,0 +1,1303 @@ +; ==================================================== +; DIE SIZE 12.2 x 11.85 (W x H) +; ==================================================== + + + +; ==================================================== +; SOUTH SIDE +; ==================================================== + +; SPI4(5) TX LVDS +; ---------------------------------------------------- + + +LVDS D D1 nil +LVDS D D1 nil +LVDS D D5_0u nil + + +; clkout2 +; ======= +LVDS S OUT_GO list( "PLL5_CLKOUT2" "GND" "PLL5_CLKOUT2.OE" "pad_gd25_5tx" "padn_PLL5_CLKOUT2" "padp_PLL5_CLKOUT2" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) + +LVDS S OUT_VC list( "TX5_TDCLK" "GND" "TX5_TDCLK.OE" "pad_Vdd" "padn_TX5_TDCLK" "padp_TX5_TDCLK" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GC list( "TX5_TCTL" "GND" "TX5_TCTL.OE" "pad_GND" "padn_TX5_TCTL" "padp_TX5_TCTL" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VOP list( "TX5_TDAT[0]" "GND" "TX5_TDAT[0].OE" "pad_vd25op_5tx" "padn_TX5_TDAT[0]" "padp_TX5_TDAT[0]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GO list( "TX5_TDAT[1]" "GND" "TX5_TDAT[1].OE" "pad_gd25_5tx" "padn_TX5_TDAT[1]" "padp_TX5_TDAT[1]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VC list( "TX5_TDAT[2]" "GND" "TX5_TDAT[2].OE" "pad_Vdd" "padn_TX5_TDAT[2]" "padp_TX5_TDAT[2]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GC list( "TX5_TDAT[3]" "GND" "TX5_TDAT[3].OE" "pad_GND" "padn_TX5_TDAT[3]" "padp_TX5_TDAT[3]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VREF list( "TX5_TDAT[4]" "GND" "TX5_TDAT[4].OE" "pad_vref_5tx" "padn_TX5_TDAT[4]" "padp_TX5_TDAT[4]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VOP list( "TX5_TDAT[5]" "GND" "TX5_TDAT[5].OE" "pad_vd25op_5tx" "padn_TX5_TDAT[5]" "padp_TX5_TDAT[5]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GO list( "TX5_TDAT[6]" "GND" "TX5_TDAT[6].OE" "pad_gd25_5tx" "padn_TX5_TDAT[6]" "padp_TX5_TDAT[6]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VC list( "TX5_TDAT[7]" "GND" "TX5_TDAT[7].OE" "pad_Vdd" "padn_TX5_TDAT[7]" "padp_TX5_TDAT[7]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GC list( "TX5_TDAT[8]" "GND" "TX5_TDAT[8].OE" "pad_GND" "padn_TX5_TDAT[8]" "padp_TX5_TDAT[8]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VOP list( "TX5_TDAT[9]" "GND" "TX5_TDAT[9].OE" "pad_vd25op_5tx" "padn_TX5_TDAT[9]" "padp_TX5_TDAT[9]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GO list( "TX5_TDAT[10]" "GND" "TX5_TDAT[10].OE" "pad_gd25_5tx" "padn_TX5_TDAT[10]" "padp_TX5_TDAT[10]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VC list( "TX5_TDAT[11]" "GND" "TX5_TDAT[11].OE" "pad_Vdd" "padn_TX5_TDAT[11]" "padp_TX5_TDAT[11]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GC list( "TX5_TDAT[12]" "GND" "TX5_TDAT[12].OE" "pad_GND" "padn_TX5_TDAT[12]" "padp_TX5_TDAT[12]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VOP list( "TX5_TDAT[13]" "GND" "TX5_TDAT[13].OE" "pad_vd25op_5tx" "padn_TX5_TDAT[13]" "padp_TX5_TDAT[13]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_GO list( "TX5_TDAT[14]" "GND" "TX5_TDAT[14].OE" "pad_gd25_5tx" "padn_TX5_TDAT[14]" "padp_TX5_TDAT[14]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) +LVDS S OUT_VC list( "TX5_TDAT[15]" "GND" "TX5_TDAT[15].OE" "pad_Vdd" "padn_TX5_TDAT[15]" "padp_TX5_TDAT[15]" "SGND" "DISABLE_STRAP5_n" "Vdd" "vd25o_5tx" "vd25p_5tx" "VGG" "vref_5tx" "gd25_5tx" ) + +LVDS D D20_0u nil +LVTTL D D1 nil +LVTTL D D1 nil + + +; Power Grid Observation Pair (SPI-4 IP Edge) +; =========================================== +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S AIO list( "GND" "pad_OBS_SPI4_IP_VDD" "Vdd" "PAD_OBS_SPI4_IP_VDD_RIN" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S AIO list( "GND" "pad_OBS_SPI4_IP_GND" "GND" "PAD_OBS_SPI4_IP_GND_RIN" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil + + + + +; Power Grid Observation Pair (SPI-4 Async Edge) +; =========================================== +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S AIO list( "GND" "pad_OBS_SPI4_ASYNC_VDD" "Vdd" "PAD_OBS_SPI4_ASYNC_VDD_RIN" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S AIO list( "GND" "pad_OBS_SPI4_ASYNC_GND" "GND" "PAD_OBS_SPI4_ASYNC_GND_RIN" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + + +LVTTL D D1 nil +LVTTL D D1 nil + + +; MISC DOMAIN -- TAP + TEST/SCAN + SERIAL TREE +; ---------------------------------------------------- +; 9x LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; 9x LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + + +; TAP +; === +; 5x Signals +; 1x LVTTL PRH VOO list( "GND" "pad_vd33o_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; 1x LVTTL PRH VP list( "GND" "pad_vd33p_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; 1x LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; --------------------------------------------------------------------------------------------------------------------- +; 8x TOTAL + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INnn8 list( "TCK" "GND" "pad_TCK" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpu2 list( "TDI" "GND" "pad_TDI" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpu2 list( "TMS" "GND" "pad_TMS" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpu2 list( "TRST_N" "GND" "pad_TRST_N" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "TDO.DI" "TDO" "GND" "oe_TDO" "pad_TDO" "SGND" "tn_TDO" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + + +; TEST/SCAN +; ========= +; 12x Signals +; 1x LVTTL PRH VOO list( "GND" "pad_vd33o_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; 3x LVTTL PRH VP list( "GND" "pad_vd33p_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; 4x LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; --------------------------------------------------------------------------------------------------------------------- +; 20x TOTAL + +LVTTL S INpd8 list( "CHIP_RESET_N" "GND" "pad_CHIP_RESET_N" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpu2 list( "SCAN_IN0" "GND" "pad_SCAN_IN0" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpu2 list( "SCAN_IN1" "GND" "pad_SCAN_IN1" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpu2 list( "SCAN_IN2" "GND" "pad_SCAN_IN2" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpu2 list( "SCAN_IN3" "GND" "pad_SCAN_IN3" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "SCAN_OUT0.DI" "SCAN_OUT0" "GND" "oe_SCAN_OUT0" "pad_SCAN_OUT0" "SGND" "tn_SCAN_OUT0" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "SCAN_OUT1.DI" "SCAN_OUT1" "GND" "oe_SCAN_OUT1" "pad_SCAN_OUT1" "SGND" "tn_SCAN_OUT1" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "SCAN_OUT2.DI" "SCAN_OUT2" "GND" "oe_SCAN_OUT2" "pad_SCAN_OUT2" "SGND" "tn_SCAN_OUT2" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "SCAN_OUT3.DI" "SCAN_OUT3" "GND" "oe_SCAN_OUT3" "pad_SCAN_OUT3" "SGND" "tn_SCAN_OUT3" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpd2 list( "SCAN_ENABLE" "GND" "pad_SCAN_ENABLE" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpd2 list( "TEST_MODE" "GND" "pad_TEST_MODE" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL D D1 nil +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +; SELF OSC TEST +; 5x Signals (Outputs) +; +; SOSC_TEST_IO[0..4] +; SOSC_TEST_PAD[0..4] +; --------------------------------------------------------------------------------------------------------------------- + + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT2nn2 list( "SOSC_TEST_IO[0].DI" "SOSC_TEST_IO[0]" "GND" "oe_SOSC_TEST_IO[0]" "pad_SOSC_TEST_PAD[0]" "SGND" "tn_SOSC_TEST_IO[0]" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT2nn2 list( "SOSC_TEST_IO[1].DI" "SOSC_TEST_IO[1]" "GND" "oe_SOSC_TEST_IO[1]" "pad_SOSC_TEST_PAD[1]" "SGND" "tn_SOSC_TEST_IO[1]" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT2nn2 list( "SOSC_TEST_IO[2].DI" "SOSC_TEST_IO[2]" "GND" "oe_SOSC_TEST_IO[2]" "pad_SOSC_TEST_PAD[2]" "SGND" "tn_SOSC_TEST_IO[2]" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT2nn2 list( "SOSC_TEST_IO[3].DI" "SOSC_TEST_IO[3]" "GND" "oe_SOSC_TEST_IO[3]" "pad_SOSC_TEST_PAD[3]" "SGND" "tn_SOSC_TEST_IO[3]" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT2nn2 list( "SOSC_TEST_IO[4].DI" "SOSC_TEST_IO[4]" "GND" "oe_SOSC_TEST_IO[4]" "pad_SOSC_TEST_PAD[4]" "SGND" "tn_SOSC_TEST_IO[4]" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL D D1 nil +LVTTL D D1 nil + + + +; Power Grid Observation Pair (ASOC Edge) +; =========================================== +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S AIO list( "GND" "pad_OBS_ASOC_VDD" "Vdd" "PAD_OBS_ASOC_VDD_RIN" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S AIO list( "GND" "pad_OBS_ASOC_GND" "GND" "PAD_OBS_ASOC_GND_RIN" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + + +LVTTL D D1 nil +LVTTL D D1 nil + +; SERIAL TREE +; 9x Signals +; 1x LVTTL PRH VOO list( "GND" "pad_vd33o_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; 3x LVTTL PRH VP list( "GND" "pad_vd33p_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; 3x LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; --------------------------------------------------------------------------------------------------------------------- +; 16x TOTAL + +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +; LVTTL S INpd2 list( "ASIIO_MODE" "GND" "pad_ASIIO_MODE" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpd2 list( "ASII0" "GND" "pad_ASII0" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpd2 list( "ASII1" "GND" "pad_ASII1" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INpd2 list( "ASII2" "GND" "pad_ASII2" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "ASII_E.DI" "ASII_E" "GND" "oe_ASII_E" "pad_ASII_E" "SGND" "tn_ASII_E" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRL GO list( "GND" "pad_gd33_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL S INOUT4nn2 list( "ASIO0.DI" "ASIO0" "GND" "oe_ASIO0" "pad_ASIO0" "SGND" "tn_ASIO0" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "ASIO1.DI" "ASIO1" "GND" "oe_ASIO1" "pad_ASIO1" "SGND" "tn_ASIO1" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL S INOUT4nn2 list( "ASIO2.DI" "ASIO2" "GND" "oe_ASIO2" "pad_ASIO2" "SGND" "tn_ASIO2" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL D D1 nil + +LVTTL S INpd2 list( "ASIO_E" "GND" "pad_ASIO_E" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Misc" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + + +LVTTL D D17_0u nil + +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Misc" "vd33p_Misc" "VGG" "gd33_Misc" ) + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL D D1 nil + + +LVDS D D20_0u nil + +; SPI4(0) TX LVDS +; ---------------------------------------------------- + +LVDS S OUT_VC list( "TX0_TDAT[15]" "GND" "TX0_TDAT[15].OE" "pad_Vdd" "padn_TX0_TDAT[15]" "padp_TX0_TDAT[15]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GO list( "TX0_TDAT[14]" "GND" "TX0_TDAT[14].OE" "pad_gd25_0tx" "padn_TX0_TDAT[14]" "padp_TX0_TDAT[14]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VOP list( "TX0_TDAT[13]" "GND" "TX0_TDAT[13].OE" "pad_vd25op_0tx" "padn_TX0_TDAT[13]" "padp_TX0_TDAT[13]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GC list( "TX0_TDAT[12]" "GND" "TX0_TDAT[12].OE" "pad_GND" "padn_TX0_TDAT[12]" "padp_TX0_TDAT[12]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VC list( "TX0_TDAT[11]" "GND" "TX0_TDAT[11].OE" "pad_Vdd" "padn_TX0_TDAT[11]" "padp_TX0_TDAT[11]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GO list( "TX0_TDAT[10]" "GND" "TX0_TDAT[10].OE" "pad_gd25_0tx" "padn_TX0_TDAT[10]" "padp_TX0_TDAT[10]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VOP list( "TX0_TDAT[9]" "GND" "TX0_TDAT[9].OE" "pad_vd25op_0tx" "padn_TX0_TDAT[9]" "padp_TX0_TDAT[9]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GC list( "TX0_TDAT[8]" "GND" "TX0_TDAT[8].OE" "pad_GND" "padn_TX0_TDAT[8]" "padp_TX0_TDAT[8]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VC list( "TX0_TDAT[7]" "GND" "TX0_TDAT[7].OE" "pad_Vdd" "padn_TX0_TDAT[7]" "padp_TX0_TDAT[7]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GO list( "TX0_TDAT[6]" "GND" "TX0_TDAT[6].OE" "pad_gd25_0tx" "padn_TX0_TDAT[6]" "padp_TX0_TDAT[6]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VOP list( "TX0_TDAT[5]" "GND" "TX0_TDAT[5].OE" "pad_vd25op_0tx" "padn_TX0_TDAT[5]" "padp_TX0_TDAT[5]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VREF list( "TX0_TDAT[4]" "GND" "TX0_TDAT[4].OE" "pad_vref_0tx" "padn_TX0_TDAT[4]" "padp_TX0_TDAT[4]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GC list( "TX0_TDAT[3]" "GND" "TX0_TDAT[3].OE" "pad_GND" "padn_TX0_TDAT[3]" "padp_TX0_TDAT[3]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VC list( "TX0_TDAT[2]" "GND" "TX0_TDAT[2].OE" "pad_Vdd" "padn_TX0_TDAT[2]" "padp_TX0_TDAT[2]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GO list( "TX0_TDAT[1]" "GND" "TX0_TDAT[1].OE" "pad_gd25_0tx" "padn_TX0_TDAT[1]" "padp_TX0_TDAT[1]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VOP list( "TX0_TDAT[0]" "GND" "TX0_TDAT[0].OE" "pad_vd25op_0tx" "padn_TX0_TDAT[0]" "padp_TX0_TDAT[0]" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_GC list( "TX0_TDCLK" "GND" "TX0_TDCLK.OE" "pad_GND" "padn_TX0_TDCLK" "padp_TX0_TDCLK" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) +LVDS S OUT_VC list( "TX0_TCTL" "GND" "TX0_TCTL.OE" "pad_Vdd" "padn_TX0_TCTL" "padp_TX0_TCTL" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) + + +; clkout2 +; ======= +LVDS S OUT_GO list( "PLL0_CLKOUT2" "GND" "PLL0_CLKOUT2.OE" "pad_gd25_0tx" "padn_PLL0_CLKOUT2" "padp_PLL0_CLKOUT2" "SGND" "DISABLE_STRAP0_n" "Vdd" "vd25o_0tx" "vd25p_0tx" "VGG" "vref_0tx" "gd25_0tx" ) + + +LVDS D D1 nil +LVDS D D1 nil + + + + + + + + + +; ==================================================== +; EAST SIDE +; ==================================================== + +LVTTL D D10_0u nil + + +; SPI4(0) TX LVTTL +; ---------------------------------------------------- + +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) + +LVTTL S INpd2_2 list( "DISABLE_STRAP0" "GND" "pad_DISABLE_STRAP0" "Vdd" "DISABLE_STRAP0_n" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) +LVTTL S INnn2 list( "TX0_TSTAT[1]" "GND" "pad_TX0_TSTAT[1]" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_0tx" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) +LVTTL S INnn2 list( "TX0_TSTAT[0]" "GND" "pad_TX0_TSTAT[0]" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) +LVTTL S INnn2 list( "TX0_TSCLK" "GND" "pad_TX0_TSCLK" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) +LVTTL PRL GO list( "GND" "pad_gd33_0tx" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_0tx" "vd33p_0tx" "VGG" "gd33_0tx" ) + +LVDS D D1 nil + + + + + +; SPI4(0) PLL +; ---------------------------------------------------- + + +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +LVTTL S INOUT4nn2 list( "PLL0_LOCK.DIN" "PLL0_LOCK" "GND" "oe_PLL0_LOCK" "pad_PLL0_LOCK" "SGND" "tn_PLL0_LOCK" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +LVTTL S INnn2 list( "PLL0_BYPASS_VCO" "GND" "pad_PLL0_BYPASS_VCO" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +LVTTL PRH VOP_2 list( "GND" "pad_vaa_0" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +LVTTL PRH VOP list( "GND" "pad_vaa_0" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +LVTTL S INnn2 list( "PLL0_REFCLK" "GND" "pad_PLL0_REFCLK" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +LVTTL S INpd2 list( "PLL0_BYPASS_EN" "GND" "pad_PLL0_BYPASS_EN" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +LVTTL PRL GO_2 list( "GND" "pad_ag_0" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) +;LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_0" "vaa_0" "VGG" "ag_0" ) + +LVDS D D1 nil + + +; SPI4(0) RX LVTTL +; ---------------------------------------------------- + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) +LVTTL PRL GO list( "GND" "pad_gd33_0rx" "SGND" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) +LVTTL S INOUT8nn2 list( "RX0_RSTAT[1].DIN" "RX0_RSTAT[1]" "GND" "oe_RX0_RSTAT[1]" "pad_RX0_RSTAT[1]" "SGND" "tn_RX0_RSTAT[1]" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) +LVTTL S INOUT8nn2 list( "RX0_RSTAT[0].DIN" "RX0_RSTAT[0]" "GND" "oe_RX0_RSTAT[0]" "pad_RX0_RSTAT[0]" "SGND" "tn_RX0_RSTAT[0]" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_0rx" "SGND" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) +LVTTL S INOUT8nn2 list( "RX0_RSCLK.DIN" "RX0_RSCLK" "GND" "oe_RX0_RSCLK" "pad_RX0_RSCLK" "SGND" "tn_RX0_RSCLK" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_0rx" "vd33p_0rx" "VGG" "gd33_0rx" ) + + + +; SPI4(0) RX LVDS +; ---------------------------------------------------- + +LVDS S IN list( "RX0_RDAT[15]" "GND" "padn_RX0_RDAT[15]" "padp_RX0_RDAT[15]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[14]" "GND" "padn_RX0_RDAT[14]" "padp_RX0_RDAT[14]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_0rx" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[13]" "GND" "padn_RX0_RDAT[13]" "padp_RX0_RDAT[13]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[12]" "GND" "padn_RX0_RDAT[12]" "padp_RX0_RDAT[12]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[11]" "GND" "padn_RX0_RDAT[11]" "padp_RX0_RDAT[11]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[10]" "GND" "padn_RX0_RDAT[10]" "padp_RX0_RDAT[10]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_0rx" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[9]" "GND" "padn_RX0_RDAT[9]" "padp_RX0_RDAT[9]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[8]" "GND" "padn_RX0_RDAT[8]" "padp_RX0_RDAT[8]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDCLK" "GND" "padn_RX0_RDCLK" "padp_RX0_RDCLK" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RCTL" "GND" "padn_RX0_RCTL" "padp_RX0_RCTL" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_0rx" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[7]" "GND" "padn_RX0_RDAT[7]" "padp_RX0_RDAT[7]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[6]" "GND" "padn_RX0_RDAT[6]" "padp_RX0_RDAT[6]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[5]" "GND" "padn_RX0_RDAT[5]" "padp_RX0_RDAT[5]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[4]" "GND" "padn_RX0_RDAT[4]" "padp_RX0_RDAT[4]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_0rx" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[3]" "GND" "padn_RX0_RDAT[3]" "padp_RX0_RDAT[3]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[2]" "GND" "padn_RX0_RDAT[2]" "padp_RX0_RDAT[2]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[1]" "GND" "padn_RX0_RDAT[1]" "padp_RX0_RDAT[1]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS S IN list( "RX0_RDAT[0]" "GND" "padn_RX0_RDAT[0]" "padp_RX0_RDAT[0]" "DISABLE_STRAP0" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_0rx" "vd25p_0rx" "VGG" "vref_0rx" "gd25_0rx" ) + +LVTTL D D9_6u nil + + +; SPI4(1) RX LVTTL +; ---------------------------------------------------- + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_1rx" "vd33p_1rx" "VGG" "gd33_1rx" ) +LVTTL S INOUT8nn2 list( "RX1_RSCLK.DIN" "RX1_RSCLK" "GND" "oe_RX1_RSCLK" "pad_RX1_RSCLK" "SGND" "tn_RX1_RSCLK" "Vdd" "vd33o_1rx" "vd33p_1rx" "VGG" "gd33_1rx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_1rx" "SGND" "Vdd" "vd33o_1rx" "vd33p_1rx" "VGG" "gd33_1rx" ) +LVTTL S INOUT8nn2 list( "RX1_RSTAT[0].DIN" "RX1_RSTAT[0]" "GND" "oe_RX1_RSTAT[0]" "pad_RX1_RSTAT[0]" "SGND" "tn_RX1_RSTAT[0]" "Vdd" "vd33o_1rx" "vd33p_1rx" "VGG" "gd33_1rx" ) +LVTTL S INOUT8nn2 list( "RX1_RSTAT[1].DIN" "RX1_RSTAT[1]" "GND" "oe_RX1_RSTAT[1]" "pad_RX1_RSTAT[1]" "SGND" "tn_RX1_RSTAT[1]" "Vdd" "vd33o_1rx" "vd33p_1rx" "VGG" "gd33_1rx" ) +LVTTL PRL GO list( "GND" "pad_gd33_1rx" "SGND" "Vdd" "vd33o_1rx" "vd33p_1rx" "VGG" "gd33_1rx" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_1rx" "vd33p_1rx" "VGG" "gd33_1rx" ) + +; SPI4(1) RX LVDS +; ---------------------------------------------------- +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[0]" "GND" "padn_RX1_RDAT[0]" "padp_RX1_RDAT[0]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[1]" "GND" "padn_RX1_RDAT[1]" "padp_RX1_RDAT[1]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[2]" "GND" "padn_RX1_RDAT[2]" "padp_RX1_RDAT[2]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[3]" "GND" "padn_RX1_RDAT[3]" "padp_RX1_RDAT[3]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_1rx" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[4]" "GND" "padn_RX1_RDAT[4]" "padp_RX1_RDAT[4]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[5]" "GND" "padn_RX1_RDAT[5]" "padp_RX1_RDAT[5]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[6]" "GND" "padn_RX1_RDAT[6]" "padp_RX1_RDAT[6]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[7]" "GND" "padn_RX1_RDAT[7]" "padp_RX1_RDAT[7]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_1rx" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RCTL" "GND" "padn_RX1_RCTL" "padp_RX1_RCTL" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDCLK" "GND" "padn_RX1_RDCLK" "padp_RX1_RDCLK" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[8]" "GND" "padn_RX1_RDAT[8]" "padp_RX1_RDAT[8]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[9]" "GND" "padn_RX1_RDAT[9]" "padp_RX1_RDAT[9]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_1rx" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[10]" "GND" "padn_RX1_RDAT[10]" "padp_RX1_RDAT[10]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[11]" "GND" "padn_RX1_RDAT[11]" "padp_RX1_RDAT[11]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[12]" "GND" "padn_RX1_RDAT[12]" "padp_RX1_RDAT[12]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[13]" "GND" "padn_RX1_RDAT[13]" "padp_RX1_RDAT[13]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_1rx" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[14]" "GND" "padn_RX1_RDAT[14]" "padp_RX1_RDAT[14]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) +LVDS S IN list( "RX1_RDAT[15]" "GND" "padn_RX1_RDAT[15]" "padp_RX1_RDAT[15]" "DISABLE_STRAP1" "SGND" "Vdd" "vd25o_1rx" "vd25p_1rx" "VGG" "vref_1rx" "gd25_1rx" ) + + +; SPI4(1) PLL +; ---------------------------------------------------- +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) + +LVTTL PRL GO_2 list( "GND" "pad_ag_1" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL S INpd2 list( "PLL1_BYPASS_EN" "GND" "pad_PLL1_BYPASS_EN" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL S INnn2 list( "PLL1_REFCLK" "GND" "pad_PLL1_REFCLK" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL PRH VOP list( "GND" "pad_vaa_1" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL PRH VOP_2 list( "GND" "pad_vaa_1" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL S INnn2 list( "PLL1_BYPASS_VCO" "GND" "pad_PLL1_BYPASS_VCO" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL S INOUT4nn2 list( "PLL1_LOCK.DIN" "PLL1_LOCK" "GND" "oe_PLL1_LOCK" "pad_PLL1_LOCK" "SGND" "tn_PLL1_LOCK" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +LVTTL D D1 nil +LVTTL D D1 nil + +; Changed by Samson +; ================= +; Swap out 35um x 4 = 140um +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_1" "vaa_1" "VGG" "ag_1" ) + +; Swap in 20um + 120um = 140um +; ============================ +LVDS D D20_0u nil + + + +; clkout2 +; ======= +LVDS S OUT_GO list( "PLL1_CLKOUT2" "GND" "PLL1_CLKOUT2.OE" "pad_gd25_1tx" "padn_PLL1_CLKOUT2" "padp_PLL1_CLKOUT2" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) + + + +; SPI4(1) TX LVDS +; ---------------------------------------------------- +LVDS S OUT_VC list( "TX1_TCTL" "GND" "TX1_TCTL.OE" "pad_Vdd" "padn_TX1_TCTL" "padp_TX1_TCTL" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GC list( "TX1_TDCLK" "GND" "TX1_TDCLK.OE" "pad_GND" "padn_TX1_TDCLK" "padp_TX1_TDCLK" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VOP list( "TX1_TDAT[0]" "GND" "TX1_TDAT[0].OE" "pad_vd25op_1tx" "padn_TX1_TDAT[0]" "padp_TX1_TDAT[0]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GO list( "TX1_TDAT[1]" "GND" "TX1_TDAT[1].OE" "pad_gd25_1tx" "padn_TX1_TDAT[1]" "padp_TX1_TDAT[1]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VC list( "TX1_TDAT[2]" "GND" "TX1_TDAT[2].OE" "pad_Vdd" "padn_TX1_TDAT[2]" "padp_TX1_TDAT[2]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GC list( "TX1_TDAT[3]" "GND" "TX1_TDAT[3].OE" "pad_GND" "padn_TX1_TDAT[3]" "padp_TX1_TDAT[3]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VREF list( "TX1_TDAT[4]" "GND" "TX1_TDAT[4].OE" "pad_vref_1tx" "padn_TX1_TDAT[4]" "padp_TX1_TDAT[4]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VOP list( "TX1_TDAT[5]" "GND" "TX1_TDAT[5].OE" "pad_vd25op_1tx" "padn_TX1_TDAT[5]" "padp_TX1_TDAT[5]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GO list( "TX1_TDAT[6]" "GND" "TX1_TDAT[6].OE" "pad_gd25_1tx" "padn_TX1_TDAT[6]" "padp_TX1_TDAT[6]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VC list( "TX1_TDAT[7]" "GND" "TX1_TDAT[7].OE" "pad_Vdd" "padn_TX1_TDAT[7]" "padp_TX1_TDAT[7]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GC list( "TX1_TDAT[8]" "GND" "TX1_TDAT[8].OE" "pad_GND" "padn_TX1_TDAT[8]" "padp_TX1_TDAT[8]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VOP list( "TX1_TDAT[9]" "GND" "TX1_TDAT[9].OE" "pad_vd25op_1tx" "padn_TX1_TDAT[9]" "padp_TX1_TDAT[9]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GO list( "TX1_TDAT[10]" "GND" "TX1_TDAT[10].OE" "pad_gd25_1tx" "padn_TX1_TDAT[10]" "padp_TX1_TDAT[10]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VC list( "TX1_TDAT[11]" "GND" "TX1_TDAT[11].OE" "pad_Vdd" "padn_TX1_TDAT[11]" "padp_TX1_TDAT[11]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GC list( "TX1_TDAT[12]" "GND" "TX1_TDAT[12].OE" "pad_GND" "padn_TX1_TDAT[12]" "padp_TX1_TDAT[12]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VOP list( "TX1_TDAT[13]" "GND" "TX1_TDAT[13].OE" "pad_vd25op_1tx" "padn_TX1_TDAT[13]" "padp_TX1_TDAT[13]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_GO list( "TX1_TDAT[14]" "GND" "TX1_TDAT[14].OE" "pad_gd25_1tx" "padn_TX1_TDAT[14]" "padp_TX1_TDAT[14]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) +LVDS S OUT_VC list( "TX1_TDAT[15]" "GND" "TX1_TDAT[15].OE" "pad_Vdd" "padn_TX1_TDAT[15]" "padp_TX1_TDAT[15]" "SGND" "DISABLE_STRAP1_n" "Vdd" "vd25o_1tx" "vd25p_1tx" "VGG" "vref_1tx" "gd25_1tx" ) + + +; SPI4(1) TX LVTTL +; ---------------------------------------------------- +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) +LVTTL S INnn2 list( "TX1_TSCLK" "GND" "pad_TX1_TSCLK" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) +LVTTL S INnn2 list( "TX1_TSTAT[0]" "GND" "pad_TX1_TSTAT[0]" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_1tx" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) +LVTTL S INnn2 list( "TX1_TSTAT[1]" "GND" "pad_TX1_TSTAT[1]" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) +LVTTL S INpd2_2 list( "DISABLE_STRAP1" "GND" "pad_DISABLE_STRAP1" "Vdd" "DISABLE_STRAP1_n" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) +LVTTL PRL GO list( "GND" "pad_gd33_1tx" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_1tx" "vd33p_1tx" "VGG" "gd33_1tx" ) + + + + +LVTTL D D9_6u nil +LVTTL D D9_6u nil + + + + + +; SPI4(2) RX LVDS +; ---------------------------------------------------- + +LVDS S IN list( "RX2_RDAT[0]" "GND" "padn_RX2_RDAT[0]" "padp_RX2_RDAT[0]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[1]" "GND" "padn_RX2_RDAT[1]" "padp_RX2_RDAT[1]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[2]" "GND" "padn_RX2_RDAT[2]" "padp_RX2_RDAT[2]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[3]" "GND" "padn_RX2_RDAT[3]" "padp_RX2_RDAT[3]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_2rx" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[4]" "GND" "padn_RX2_RDAT[4]" "padp_RX2_RDAT[4]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[5]" "GND" "padn_RX2_RDAT[5]" "padp_RX2_RDAT[5]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[6]" "GND" "padn_RX2_RDAT[6]" "padp_RX2_RDAT[6]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[7]" "GND" "padn_RX2_RDAT[7]" "padp_RX2_RDAT[7]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_2rx" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RCTL" "GND" "padn_RX2_RCTL" "padp_RX2_RCTL" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDCLK" "GND" "padn_RX2_RDCLK" "padp_RX2_RDCLK" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[8]" "GND" "padn_RX2_RDAT[8]" "padp_RX2_RDAT[8]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[9]" "GND" "padn_RX2_RDAT[9]" "padp_RX2_RDAT[9]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_2rx" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[10]" "GND" "padn_RX2_RDAT[10]" "padp_RX2_RDAT[10]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[11]" "GND" "padn_RX2_RDAT[11]" "padp_RX2_RDAT[11]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[12]" "GND" "padn_RX2_RDAT[12]" "padp_RX2_RDAT[12]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[13]" "GND" "padn_RX2_RDAT[13]" "padp_RX2_RDAT[13]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_2rx" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[14]" "GND" "padn_RX2_RDAT[14]" "padp_RX2_RDAT[14]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) +LVDS S IN list( "RX2_RDAT[15]" "GND" "padn_RX2_RDAT[15]" "padp_RX2_RDAT[15]" "DISABLE_STRAP2" "SGND" "Vdd" "vd25o_2rx" "vd25p_2rx" "VGG" "vref_2rx" "gd25_2rx" ) + + + +; SPI4(2) RX LVTTL +; ---------------------------------------------------- +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) + +LVTTL S INOUT8nn2 list( "RX2_RSTAT[1].DIN" "RX2_RSTAT[1]" "GND" "oe_RX2_RSTAT[1]" "pad_RX2_RSTAT[1]" "SGND" "tn_RX2_RSTAT[1]" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) +LVTTL S INOUT8nn2 list( "RX2_RSTAT[0].DIN" "RX2_RSTAT[0]" "GND" "oe_RX2_RSTAT[0]" "pad_RX2_RSTAT[0]" "SGND" "tn_RX2_RSTAT[0]" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_2rx" "SGND" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) +LVTTL S INOUT8nn2 list( "RX2_RSCLK.DIN" "RX2_RSCLK" "GND" "oe_RX2_RSCLK" "pad_RX2_RSCLK" "SGND" "tn_RX2_RSCLK" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) +LVTTL PRL GO list( "GND" "pad_gd33_2rx" "SGND" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_2rx" "vd33p_2rx" "VGG" "gd33_2rx" ) + +LVDS D D1 nil + + + +; SPI4(2) PLL +; ---------------------------------------------------- + +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) + +LVTTL S INOUT4nn2 list( "PLL2_LOCK.DIN" "PLL2_LOCK" "GND" "oe_PLL2_LOCK" "pad_PLL2_LOCK" "SGND" "tn_PLL2_LOCK" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) +LVTTL S INnn2 list( "PLL2_BYPASS_VCO" "GND" "pad_PLL2_BYPASS_VCO" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) +LVTTL PRH VOP_2 list( "GND" "pad_vaa_2" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) +LVTTL PRH VOP list( "GND" "pad_vaa_2" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) +LVTTL S INnn2 list( "PLL2_REFCLK" "GND" "pad_PLL2_REFCLK" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) +LVTTL S INpd2 list( "PLL2_BYPASS_EN" "GND" "pad_PLL2_BYPASS_EN" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) +LVTTL PRL GO_2 list( "GND" "pad_ag_2" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) +;LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_2" "vaa_2" "VGG" "ag_2" ) + +LVDS D D1 nil + + + +; SPI4(2) TX LVTTL +; ---------------------------------------------------- + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL PRL GO list( "GND" "pad_gd33_2tx" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL S INpd2_2 list( "DISABLE_STRAP2" "GND" "pad_DISABLE_STRAP2" "Vdd" "DISABLE_STRAP2_n" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL S INnn2 list( "TX2_TSTAT[1]" "GND" "pad_TX2_TSTAT[1]" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_2tx" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL S INnn2 list( "TX2_TSTAT[0]" "GND" "pad_TX2_TSTAT[0]" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL S INnn2 list( "TX2_TSCLK" "GND" "pad_TX2_TSCLK" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_2tx" "vd33p_2tx" "VGG" "gd33_2tx" ) + + +LVTTL D D1 nil +LVTTL D D1 nil + + +; ==================================================== +; NORTH SIDE +; ==================================================== + +; SPI4(2) TX LVDS +; ---------------------------------------------------- + +LVDS D D1 nil +LVDS D D1 nil +LVDS D D13_0u nil + + +; clkout2 +; ======= +LVDS S OUT_GO list( "PLL2_CLKOUT2" "GND" "PLL2_CLKOUT2.OE" "pad_gd25_2tx" "padn_PLL2_CLKOUT2" "padp_PLL2_CLKOUT2" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) + + +LVDS S OUT_VC list( "TX2_TDCLK" "GND" "TX2_TDCLK.OE" "pad_Vdd" "padn_TX2_TDCLK" "padp_TX2_TDCLK" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GC list( "TX2_TCTL" "GND" "TX2_TCTL.OE" "pad_GND" "padn_TX2_TCTL" "padp_TX2_TCTL" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VOP list( "TX2_TDAT[0]" "GND" "TX2_TDAT[0].OE" "pad_vd25op_2tx" "padn_TX2_TDAT[0]" "padp_TX2_TDAT[0]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GO list( "TX2_TDAT[1]" "GND" "TX2_TDAT[1].OE" "pad_gd25_2tx" "padn_TX2_TDAT[1]" "padp_TX2_TDAT[1]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VC list( "TX2_TDAT[2]" "GND" "TX2_TDAT[2].OE" "pad_Vdd" "padn_TX2_TDAT[2]" "padp_TX2_TDAT[2]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GC list( "TX2_TDAT[3]" "GND" "TX2_TDAT[3].OE" "pad_GND" "padn_TX2_TDAT[3]" "padp_TX2_TDAT[3]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VREF list( "TX2_TDAT[4]" "GND" "TX2_TDAT[4].OE" "pad_vref_2tx" "padn_TX2_TDAT[4]" "padp_TX2_TDAT[4]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VOP list( "TX2_TDAT[5]" "GND" "TX2_TDAT[5].OE" "pad_vd25op_2tx" "padn_TX2_TDAT[5]" "padp_TX2_TDAT[5]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GO list( "TX2_TDAT[6]" "GND" "TX2_TDAT[6].OE" "pad_gd25_2tx" "padn_TX2_TDAT[6]" "padp_TX2_TDAT[6]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VC list( "TX2_TDAT[7]" "GND" "TX2_TDAT[7].OE" "pad_Vdd" "padn_TX2_TDAT[7]" "padp_TX2_TDAT[7]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GC list( "TX2_TDAT[8]" "GND" "TX2_TDAT[8].OE" "pad_GND" "padn_TX2_TDAT[8]" "padp_TX2_TDAT[8]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VOP list( "TX2_TDAT[9]" "GND" "TX2_TDAT[9].OE" "pad_vd25op_2tx" "padn_TX2_TDAT[9]" "padp_TX2_TDAT[9]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GO list( "TX2_TDAT[10]" "GND" "TX2_TDAT[10].OE" "pad_gd25_2tx" "padn_TX2_TDAT[10]" "padp_TX2_TDAT[10]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VC list( "TX2_TDAT[11]" "GND" "TX2_TDAT[11].OE" "pad_Vdd" "padn_TX2_TDAT[11]" "padp_TX2_TDAT[11]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GC list( "TX2_TDAT[12]" "GND" "TX2_TDAT[12].OE" "pad_GND" "padn_TX2_TDAT[12]" "padp_TX2_TDAT[12]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VOP list( "TX2_TDAT[13]" "GND" "TX2_TDAT[13].OE" "pad_vd25op_2tx" "padn_TX2_TDAT[13]" "padp_TX2_TDAT[13]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_GO list( "TX2_TDAT[14]" "GND" "TX2_TDAT[14].OE" "pad_gd25_2tx" "padn_TX2_TDAT[14]" "padp_TX2_TDAT[14]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) +LVDS S OUT_VC list( "TX2_TDAT[15]" "GND" "TX2_TDAT[15].OE" "pad_Vdd" "padn_TX2_TDAT[15]" "padp_TX2_TDAT[15]" "SGND" "DISABLE_STRAP2_n" "Vdd" "vd25o_2tx" "vd25p_2tx" "VGG" "vref_2tx" "gd25_2tx" ) + +LVDS D D20_0u nil + + +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D0_6u nil +LVTTL D D1 nil +LVTTL D D1 nil + + +; X8BUS Interface +; ---------------------------------------------------- +;11x LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +;5x LVTTL PRH VOO list( "GND" "pad_vd33o_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +;7x LVTTL PRH VP list( "GND" "pad_vd33p_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "CLK_X8BUSIF" "GND" "pad_CLK_X8BUSIF" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INpu2 list( "BUSIF_RESET_N" "GND" "pad_BUSIF_RESET_N" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[1]" "GND" "pad_ADDR[1]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[2]" "GND" "pad_ADDR[2]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[3]" "GND" "pad_ADDR[3]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[4]" "GND" "pad_ADDR[4]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[5]" "GND" "pad_ADDR[5]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[6]" "GND" "pad_ADDR[6]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[7]" "GND" "pad_ADDR[7]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[8]" "GND" "pad_ADDR[8]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[9]" "GND" "pad_ADDR[9]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[10]" "GND" "pad_ADDR[10]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[11]" "GND" "pad_ADDR[11]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[12]" "GND" "pad_ADDR[12]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[13]" "GND" "pad_ADDR[13]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[14]" "GND" "pad_ADDR[14]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[15]" "GND" "pad_ADDR[15]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[16]" "GND" "pad_ADDR[16]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "ADDR[17]" "GND" "pad_ADDR[17]" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) + +LVTTL S INOUT4nn2 list( "DATA_IN[0]" "DATA_OUT[0]" "GND" "DATA_OE[0]" "pad_DATA[0]" "SGND" "tn_DATA[0]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[1]" "DATA_OUT[1]" "GND" "DATA_OE[1]" "pad_DATA[1]" "SGND" "tn_DATA[1]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[2]" "DATA_OUT[2]" "GND" "DATA_OE[2]" "pad_DATA[2]" "SGND" "tn_DATA[2]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[3]" "DATA_OUT[3]" "GND" "DATA_OE[3]" "pad_DATA[3]" "SGND" "tn_DATA[3]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[4]" "DATA_OUT[4]" "GND" "DATA_OE[4]" "pad_DATA[4]" "SGND" "tn_DATA[4]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[5]" "DATA_OUT[5]" "GND" "DATA_OE[5]" "pad_DATA[5]" "SGND" "tn_DATA[5]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[6]" "DATA_OUT[6]" "GND" "DATA_OE[6]" "pad_DATA[6]" "SGND" "tn_DATA[6]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[7]" "DATA_OUT[7]" "GND" "DATA_OE[7]" "pad_DATA[7]" "SGND" "tn_DATA[7]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[8]" "DATA_OUT[8]" "GND" "DATA_OE[8]" "pad_DATA[8]" "SGND" "tn_DATA[8]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[9]" "DATA_OUT[9]" "GND" "DATA_OE[9]" "pad_DATA[9]" "SGND" "tn_DATA[9]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[10]" "DATA_OUT[10]" "GND" "DATA_OE[10]" "pad_DATA[10]" "SGND" "tn_DATA[10]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[11]" "DATA_OUT[11]" "GND" "DATA_OE[11]" "pad_DATA[11]" "SGND" "tn_DATA[11]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[12]" "DATA_OUT[12]" "GND" "DATA_OE[12]" "pad_DATA[12]" "SGND" "tn_DATA[12]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[13]" "DATA_OUT[13]" "GND" "DATA_OE[13]" "pad_DATA[13]" "SGND" "tn_DATA[13]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[14]" "DATA_OUT[14]" "GND" "DATA_OE[14]" "pad_DATA[14]" "SGND" "tn_DATA[14]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DATA_IN[15]" "DATA_OUT[15]" "GND" "DATA_OE[15]" "pad_DATA[15]" "SGND" "tn_DATA[15]" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) + +LVTTL S INnn2 list( "RW_N_INV" "GND" "pad_RW_N_INV" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "RW_N" "GND" "pad_RW_N" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "AS_N" "GND" "pad_AS_N" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "DS_N" "GND" "pad_DS_N" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "CS_N" "GND" "pad_CS_N" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRL GO list( "GND" "pad_gd33_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "DTACK_N.DIN" "DTACK_N" "GND" "DTACK_OE" "pad_DTACK_N" "SGND" "tn_DTACK_N" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "DTACK_INV" "GND" "pad_DTACK_INV" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_Bus" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "IGNORE_DS_N" "GND" "pad_IGNORE_DS_N" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INnn2 list( "SYNC_MODE" "GND" "pad_SYNC_MODE" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL S INOUT4nn2 list( "INTR_N.DIN" "GND" "GND" "oe_INTR_N" "pad_INTR_N" "SGND" "tn_INTR_N" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) + + +LVTTL D D1 nil +LVTTL D D16_4u nil + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_Bus" "vd33p_Bus" "VGG" "gd33_Bus" ) +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL D D1 nil + + + +LVDS D D20_0u nil + +; SPI4(3) TX LVDS +; ---------------------------------------------------- + +LVDS S OUT_VC list( "TX3_TDAT[15]" "GND" "TX3_TDAT[15].OE" "pad_Vdd" "padn_TX3_TDAT[15]" "padp_TX3_TDAT[15]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GO list( "TX3_TDAT[14]" "GND" "TX3_TDAT[14].OE" "pad_gd25_3tx" "padn_TX3_TDAT[14]" "padp_TX3_TDAT[14]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VOP list( "TX3_TDAT[13]" "GND" "TX3_TDAT[13].OE" "pad_vd25op_3tx" "padn_TX3_TDAT[13]" "padp_TX3_TDAT[13]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GC list( "TX3_TDAT[12]" "GND" "TX3_TDAT[12].OE" "pad_GND" "padn_TX3_TDAT[12]" "padp_TX3_TDAT[12]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VC list( "TX3_TDAT[11]" "GND" "TX3_TDAT[11].OE" "pad_Vdd" "padn_TX3_TDAT[11]" "padp_TX3_TDAT[11]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GO list( "TX3_TDAT[10]" "GND" "TX3_TDAT[10].OE" "pad_gd25_3tx" "padn_TX3_TDAT[10]" "padp_TX3_TDAT[10]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VOP list( "TX3_TDAT[9]" "GND" "TX3_TDAT[9].OE" "pad_vd25op_3tx" "padn_TX3_TDAT[9]" "padp_TX3_TDAT[9]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GC list( "TX3_TDAT[8]" "GND" "TX3_TDAT[8].OE" "pad_GND" "padn_TX3_TDAT[8]" "padp_TX3_TDAT[8]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VC list( "TX3_TDAT[7]" "GND" "TX3_TDAT[7].OE" "pad_Vdd" "padn_TX3_TDAT[7]" "padp_TX3_TDAT[7]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GO list( "TX3_TDAT[6]" "GND" "TX3_TDAT[6].OE" "pad_gd25_3tx" "padn_TX3_TDAT[6]" "padp_TX3_TDAT[6]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VOP list( "TX3_TDAT[5]" "GND" "TX3_TDAT[5].OE" "pad_vd25op_3tx" "padn_TX3_TDAT[5]" "padp_TX3_TDAT[5]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VREF list( "TX3_TDAT[4]" "GND" "TX3_TDAT[4].OE" "pad_vref_3tx" "padn_TX3_TDAT[4]" "padp_TX3_TDAT[4]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GC list( "TX3_TDAT[3]" "GND" "TX3_TDAT[3].OE" "pad_GND" "padn_TX3_TDAT[3]" "padp_TX3_TDAT[3]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VC list( "TX3_TDAT[2]" "GND" "TX3_TDAT[2].OE" "pad_Vdd" "padn_TX3_TDAT[2]" "padp_TX3_TDAT[2]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GO list( "TX3_TDAT[1]" "GND" "TX3_TDAT[1].OE" "pad_gd25_3tx" "padn_TX3_TDAT[1]" "padp_TX3_TDAT[1]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VOP list( "TX3_TDAT[0]" "GND" "TX3_TDAT[0].OE" "pad_vd25op_3tx" "padn_TX3_TDAT[0]" "padp_TX3_TDAT[0]" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_GC list( "TX3_TDCLK" "GND" "TX3_TDCLK.OE" "pad_GND" "padn_TX3_TDCLK" "padp_TX3_TDCLK" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) +LVDS S OUT_VC list( "TX3_TCTL" "GND" "TX3_TCTL.OE" "pad_Vdd" "padn_TX3_TCTL" "padp_TX3_TCTL" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) + + +; clkout2 +; ======= +LVDS S OUT_GO list( "PLL3_CLKOUT2" "GND" "PLL3_CLKOUT2.OE" "pad_gd25_3tx" "padn_PLL3_CLKOUT2" "padp_PLL3_CLKOUT2" "SGND" "DISABLE_STRAP3_n" "Vdd" "vd25o_3tx" "vd25p_3tx" "VGG" "vref_3tx" "gd25_3tx" ) + + +LVDS D D1 nil +LVDS D D1 nil + + + + +; ==================================================== +; WEST SIDE +; ==================================================== + +LVTTL D D12_0u nil +LVTTL D D9_6u nil +LVTTL D D9_6u nil + + +; SPI4(3) TX LVTTL +; ---------------------------------------------------- + +LVTTL D D1 nil +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) + +LVTTL S INpd2_2 list( "DISABLE_STRAP3" "GND" "pad_DISABLE_STRAP3" "Vdd" "DISABLE_STRAP3_n" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) +LVTTL S INnn2 list( "TX3_TSTAT[1]" "GND" "pad_TX3_TSTAT[1]" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_3tx" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) +LVTTL S INnn2 list( "TX3_TSTAT[0]" "GND" "pad_TX3_TSTAT[0]" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) +LVTTL S INnn2 list( "TX3_TSCLK" "GND" "pad_TX3_TSCLK" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) +LVTTL PRL GO list( "GND" "pad_gd33_3tx" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_3tx" "vd33p_3tx" "VGG" "gd33_3tx" ) + +LVDS D D1 nil + + + + + +; SPI4(3) PLL +; ---------------------------------------------------- + + +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +LVTTL S INOUT4nn2 list( "PLL3_LOCK.DIN" "PLL3_LOCK" "GND" "oe_PLL3_LOCK" "pad_PLL3_LOCK" "SGND" "tn_PLL3_LOCK" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +LVTTL S INnn2 list( "PLL3_BYPASS_VCO" "GND" "pad_PLL3_BYPASS_VCO" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +LVTTL PRH VOP_2 list( "GND" "pad_vaa_3" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +LVTTL PRH VOP list( "GND" "pad_vaa_3" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +LVTTL S INnn2 list( "PLL3_REFCLK" "GND" "pad_PLL3_REFCLK" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +LVTTL S INpd2 list( "PLL3_BYPASS_EN" "GND" "pad_PLL3_BYPASS_EN" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +LVTTL PRL GO_2 list( "GND" "pad_ag_3" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) +;LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_3" "vaa_3" "VGG" "ag_3" ) + +LVDS D D1 nil + + +; SPI4(3) RX LVTTL +; ---------------------------------------------------- + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) +LVTTL PRL GO list( "GND" "pad_gd33_3rx" "SGND" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) +LVTTL S INOUT8nn2 list( "RX3_RSTAT[1].DIN" "RX3_RSTAT[1]" "GND" "oe_RX3_RSTAT[1]" "pad_RX3_RSTAT[1]" "SGND" "tn_RX3_RSTAT[1]" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) +LVTTL S INOUT8nn2 list( "RX3_RSTAT[0].DIN" "RX3_RSTAT[0]" "GND" "oe_RX3_RSTAT[0]" "pad_RX3_RSTAT[0]" "SGND" "tn_RX3_RSTAT[0]" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_3rx" "SGND" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) +LVTTL S INOUT8nn2 list( "RX3_RSCLK.DIN" "RX3_RSCLK" "GND" "oe_RX3_RSCLK" "pad_RX3_RSCLK" "SGND" "tn_RX3_RSCLK" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_3rx" "vd33p_3rx" "VGG" "gd33_3rx" ) + + + +; SPI4(3) RX LVDS +; ---------------------------------------------------- + +LVDS S IN list( "RX3_RDAT[15]" "GND" "padn_RX3_RDAT[15]" "padp_RX3_RDAT[15]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[14]" "GND" "padn_RX3_RDAT[14]" "padp_RX3_RDAT[14]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_3rx" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[13]" "GND" "padn_RX3_RDAT[13]" "padp_RX3_RDAT[13]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[12]" "GND" "padn_RX3_RDAT[12]" "padp_RX3_RDAT[12]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[11]" "GND" "padn_RX3_RDAT[11]" "padp_RX3_RDAT[11]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[10]" "GND" "padn_RX3_RDAT[10]" "padp_RX3_RDAT[10]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_3rx" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[9]" "GND" "padn_RX3_RDAT[9]" "padp_RX3_RDAT[9]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[8]" "GND" "padn_RX3_RDAT[8]" "padp_RX3_RDAT[8]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDCLK" "GND" "padn_RX3_RDCLK" "padp_RX3_RDCLK" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RCTL" "GND" "padn_RX3_RCTL" "padp_RX3_RCTL" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_3rx" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[7]" "GND" "padn_RX3_RDAT[7]" "padp_RX3_RDAT[7]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[6]" "GND" "padn_RX3_RDAT[6]" "padp_RX3_RDAT[6]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[5]" "GND" "padn_RX3_RDAT[5]" "padp_RX3_RDAT[5]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[4]" "GND" "padn_RX3_RDAT[4]" "padp_RX3_RDAT[4]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_3rx" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[3]" "GND" "padn_RX3_RDAT[3]" "padp_RX3_RDAT[3]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[2]" "GND" "padn_RX3_RDAT[2]" "padp_RX3_RDAT[2]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[1]" "GND" "padn_RX3_RDAT[1]" "padp_RX3_RDAT[1]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS S IN list( "RX3_RDAT[0]" "GND" "padn_RX3_RDAT[0]" "padp_RX3_RDAT[0]" "DISABLE_STRAP3" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_3rx" "vd25p_3rx" "VGG" "vref_3rx" "gd25_3rx" ) + +LVTTL D D9_6u nil +LVTTL D D9_6u nil + + + +; SPI4(4) TX LVTTL +; ---------------------------------------------------- + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) +LVTTL PRL GO list( "GND" "pad_gd33_4tx" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) +LVTTL S INpd2_2 list( "DISABLE_STRAP4" "GND" "pad_DISABLE_STRAP4" "Vdd" "DISABLE_STRAP4_n" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) +LVTTL S INnn2 list( "TX4_TSTAT[1]" "GND" "pad_TX4_TSTAT[1]" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_4tx" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) +LVTTL S INnn2 list( "TX4_TSTAT[0]" "GND" "pad_TX4_TSTAT[0]" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) +LVTTL S INnn2 list( "TX4_TSCLK" "GND" "pad_TX4_TSCLK" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_4tx" "vd33p_4tx" "VGG" "gd33_4tx" ) + + +; SPI4(4) TX LVDS +; ---------------------------------------------------- + +LVDS S OUT_VC list( "TX4_TDAT[15]" "GND" "TX4_TDAT[15].OE" "pad_Vdd" "padn_TX4_TDAT[15]" "padp_TX4_TDAT[15]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GO list( "TX4_TDAT[14]" "GND" "TX4_TDAT[14].OE" "pad_gd25_4tx" "padn_TX4_TDAT[14]" "padp_TX4_TDAT[14]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VOP list( "TX4_TDAT[13]" "GND" "TX4_TDAT[13].OE" "pad_vd25op_4tx" "padn_TX4_TDAT[13]" "padp_TX4_TDAT[13]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GC list( "TX4_TDAT[12]" "GND" "TX4_TDAT[12].OE" "pad_GND" "padn_TX4_TDAT[12]" "padp_TX4_TDAT[12]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VC list( "TX4_TDAT[11]" "GND" "TX4_TDAT[11].OE" "pad_Vdd" "padn_TX4_TDAT[11]" "padp_TX4_TDAT[11]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GO list( "TX4_TDAT[10]" "GND" "TX4_TDAT[10].OE" "pad_gd25_4tx" "padn_TX4_TDAT[10]" "padp_TX4_TDAT[10]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VOP list( "TX4_TDAT[9]" "GND" "TX4_TDAT[9].OE" "pad_vd25op_4tx" "padn_TX4_TDAT[9]" "padp_TX4_TDAT[9]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GC list( "TX4_TDAT[8]" "GND" "TX4_TDAT[8].OE" "pad_GND" "padn_TX4_TDAT[8]" "padp_TX4_TDAT[8]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VC list( "TX4_TDAT[7]" "GND" "TX4_TDAT[7].OE" "pad_Vdd" "padn_TX4_TDAT[7]" "padp_TX4_TDAT[7]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GO list( "TX4_TDAT[6]" "GND" "TX4_TDAT[6].OE" "pad_gd25_4tx" "padn_TX4_TDAT[6]" "padp_TX4_TDAT[6]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VOP list( "TX4_TDAT[5]" "GND" "TX4_TDAT[5].OE" "pad_vd25op_4tx" "padn_TX4_TDAT[5]" "padp_TX4_TDAT[5]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VREF list( "TX4_TDAT[4]" "GND" "TX4_TDAT[4].OE" "pad_vref_4tx" "padn_TX4_TDAT[4]" "padp_TX4_TDAT[4]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GC list( "TX4_TDAT[3]" "GND" "TX4_TDAT[3].OE" "pad_GND" "padn_TX4_TDAT[3]" "padp_TX4_TDAT[3]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VC list( "TX4_TDAT[2]" "GND" "TX4_TDAT[2].OE" "pad_Vdd" "padn_TX4_TDAT[2]" "padp_TX4_TDAT[2]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GO list( "TX4_TDAT[1]" "GND" "TX4_TDAT[1].OE" "pad_gd25_4tx" "padn_TX4_TDAT[1]" "padp_TX4_TDAT[1]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VOP list( "TX4_TDAT[0]" "GND" "TX4_TDAT[0].OE" "pad_vd25op_4tx" "padn_TX4_TDAT[0]" "padp_TX4_TDAT[0]" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_GC list( "TX4_TDCLK" "GND" "TX4_TDCLK.OE" "pad_GND" "padn_TX4_TDCLK" "padp_TX4_TDCLK" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS S OUT_VC list( "TX4_TCTL" "GND" "TX4_TCTL.OE" "pad_Vdd" "padn_TX4_TCTL" "padp_TX4_TCTL" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) + + +; clkout2 +; ======= +LVDS S OUT_GO list( "PLL4_CLKOUT2" "GND" "PLL4_CLKOUT2.OE" "pad_gd25_4tx" "padn_PLL4_CLKOUT2" "padp_PLL4_CLKOUT2" "SGND" "DISABLE_STRAP4_n" "Vdd" "vd25o_4tx" "vd25p_4tx" "VGG" "vref_4tx" "gd25_4tx" ) +LVDS D D20_0u nil + + +; SPI4(4) PLL +; ---------------------------------------------------- + +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL D D1 nil +LVTTL D D1 nil +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) + +LVTTL S INOUT4nn2 list( "PLL4_LOCK.DIN" "PLL4_LOCK" "GND" "oe_PLL4_LOCK" "pad_PLL4_LOCK" "SGND" "tn_PLL4_LOCK" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL S INnn2 list( "PLL4_BYPASS_VCO" "GND" "pad_PLL4_BYPASS_VCO" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL PRH VOP_2 list( "GND" "pad_vaa_4" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL PRH VOP list( "GND" "pad_vaa_4" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL S INnn2 list( "PLL4_REFCLK" "GND" "pad_PLL4_REFCLK" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL S INpd2 list( "PLL4_BYPASS_EN" "GND" "pad_PLL4_BYPASS_EN" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL PRL GO_2 list( "GND" "pad_ag_4" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_4" "vaa_4" "VGG" "ag_4" ) + + +; SPI4(4) RX LVDS +; ---------------------------------------------------- + +LVDS S IN list( "RX4_RDAT[15]" "GND" "padn_RX4_RDAT[15]" "padp_RX4_RDAT[15]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[14]" "GND" "padn_RX4_RDAT[14]" "padp_RX4_RDAT[14]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_4rx" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[13]" "GND" "padn_RX4_RDAT[13]" "padp_RX4_RDAT[13]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[12]" "GND" "padn_RX4_RDAT[12]" "padp_RX4_RDAT[12]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[11]" "GND" "padn_RX4_RDAT[11]" "padp_RX4_RDAT[11]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[10]" "GND" "padn_RX4_RDAT[10]" "padp_RX4_RDAT[10]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_4rx" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[9]" "GND" "padn_RX4_RDAT[9]" "padp_RX4_RDAT[9]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[8]" "GND" "padn_RX4_RDAT[8]" "padp_RX4_RDAT[8]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDCLK" "GND" "padn_RX4_RDCLK" "padp_RX4_RDCLK" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RCTL" "GND" "padn_RX4_RCTL" "padp_RX4_RCTL" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_4rx" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[7]" "GND" "padn_RX4_RDAT[7]" "padp_RX4_RDAT[7]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[6]" "GND" "padn_RX4_RDAT[6]" "padp_RX4_RDAT[6]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[5]" "GND" "padn_RX4_RDAT[5]" "padp_RX4_RDAT[5]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[4]" "GND" "padn_RX4_RDAT[4]" "padp_RX4_RDAT[4]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_4rx" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[3]" "GND" "padn_RX4_RDAT[3]" "padp_RX4_RDAT[3]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[2]" "GND" "padn_RX4_RDAT[2]" "padp_RX4_RDAT[2]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[1]" "GND" "padn_RX4_RDAT[1]" "padp_RX4_RDAT[1]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS S IN list( "RX4_RDAT[0]" "GND" "padn_RX4_RDAT[0]" "padp_RX4_RDAT[0]" "DISABLE_STRAP4" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_4rx" "vd25p_4rx" "VGG" "vref_4rx" "gd25_4rx" ) + + +; SPI4(4) RX LVTTL +; ---------------------------------------------------- + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_4rx" "vd33p_4rx" "VGG" "gd33_4rx" ) +LVTTL PRL GO list( "GND" "pad_gd33_4rx" "SGND" "Vdd" "vd33o_4rx" "vd33p_4rx" "VGG" "gd33_4rx" ) +LVTTL S INOUT8nn2 list( "RX4_RSTAT[1].DIN" "RX4_RSTAT[1]" "GND" "oe_RX4_RSTAT[1]" "pad_RX4_RSTAT[1]" "SGND" "tn_RX4_RSTAT[1]" "Vdd" "vd33o_4rx" "vd33p_4rx" "VGG" "gd33_4rx" ) +LVTTL S INOUT8nn2 list( "RX4_RSTAT[0].DIN" "RX4_RSTAT[0]" "GND" "oe_RX4_RSTAT[0]" "pad_RX4_RSTAT[0]" "SGND" "tn_RX4_RSTAT[0]" "Vdd" "vd33o_4rx" "vd33p_4rx" "VGG" "gd33_4rx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_4rx" "SGND" "Vdd" "vd33o_4rx" "vd33p_4rx" "VGG" "gd33_4rx" ) +LVTTL S INOUT8nn2 list( "RX4_RSCLK.DIN" "RX4_RSCLK" "GND" "oe_RX4_RSCLK" "pad_RX4_RSCLK" "SGND" "tn_RX4_RSCLK" "Vdd" "vd33o_4rx" "vd33p_4rx" "VGG" "gd33_4rx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_4rx" "vd33p_4rx" "VGG" "gd33_4rx" ) + + + + + +;LVTTL D D9_6u nil +LVTTL D D9_6u nil + + + +; SPI4(5) RX LVDS +; ---------------------------------------------------- + +LVDS S IN list( "RX5_RDAT[0]" "GND" "padn_RX5_RDAT[0]" "padp_RX5_RDAT[0]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[1]" "GND" "padn_RX5_RDAT[1]" "padp_RX5_RDAT[1]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[2]" "GND" "padn_RX5_RDAT[2]" "padp_RX5_RDAT[2]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[3]" "GND" "padn_RX5_RDAT[3]" "padp_RX5_RDAT[3]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_5rx" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[4]" "GND" "padn_RX5_RDAT[4]" "padp_RX5_RDAT[4]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[5]" "GND" "padn_RX5_RDAT[5]" "padp_RX5_RDAT[5]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[6]" "GND" "padn_RX5_RDAT[6]" "padp_RX5_RDAT[6]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[7]" "GND" "padn_RX5_RDAT[7]" "padp_RX5_RDAT[7]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_5rx" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RCTL" "GND" "padn_RX5_RCTL" "padp_RX5_RCTL" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDCLK" "GND" "padn_RX5_RDCLK" "padp_RX5_RDCLK" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[8]" "GND" "padn_RX5_RDAT[8]" "padp_RX5_RDAT[8]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[9]" "GND" "padn_RX5_RDAT[9]" "padp_RX5_RDAT[9]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_5rx" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[10]" "GND" "padn_RX5_RDAT[10]" "padp_RX5_RDAT[10]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[11]" "GND" "padn_RX5_RDAT[11]" "padp_RX5_RDAT[11]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[12]" "GND" "padn_RX5_RDAT[12]" "padp_RX5_RDAT[12]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[13]" "GND" "padn_RX5_RDAT[13]" "padp_RX5_RDAT[13]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS PRH VOP list( "GND" "pad_vd25op_5rx" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[14]" "GND" "padn_RX5_RDAT[14]" "padp_RX5_RDAT[14]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) +LVDS S IN list( "RX5_RDAT[15]" "GND" "padn_RX5_RDAT[15]" "padp_RX5_RDAT[15]" "DISABLE_STRAP5" "SGND" "Vdd" "vd25o_5rx" "vd25p_5rx" "VGG" "vref_5rx" "gd25_5rx" ) + + + +; SPI4(5) RX LVTTL +; ---------------------------------------------------- +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) + +LVTTL S INOUT8nn2 list( "RX5_RSTAT[1].DIN" "RX5_RSTAT[1]" "GND" "oe_RX5_RSTAT[1]" "pad_RX5_RSTAT[1]" "SGND" "tn_RX5_RSTAT[1]" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) +LVTTL S INOUT8nn2 list( "RX5_RSTAT[0].DIN" "RX5_RSTAT[0]" "GND" "oe_RX5_RSTAT[0]" "pad_RX5_RSTAT[0]" "SGND" "tn_RX5_RSTAT[0]" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_5rx" "SGND" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) +LVTTL S INOUT8nn2 list( "RX5_RSCLK.DIN" "RX5_RSCLK" "GND" "oe_RX5_RSCLK" "pad_RX5_RSCLK" "SGND" "tn_RX5_RSCLK" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) +LVTTL PRL GO list( "GND" "pad_gd33_5rx" "SGND" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_5rx" "vd33p_5rx" "VGG" "gd33_5rx" ) + +LVDS D D1 nil + + + +; SPI4(5) PLL +; ---------------------------------------------------- + +;LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) + +LVTTL S INOUT4nn2 list( "PLL5_LOCK.DIN" "PLL5_LOCK" "GND" "oe_PLL5_LOCK" "pad_PLL5_LOCK" "SGND" "tn_PLL5_LOCK" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) +LVTTL S INnn2 list( "PLL5_BYPASS_VCO" "GND" "pad_PLL5_BYPASS_VCO" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) +LVTTL PRH VOP_2 list( "GND" "pad_vaa_5" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) +LVTTL PRH VOP list( "GND" "pad_vaa_5" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) +LVTTL S INnn2 list( "PLL5_REFCLK" "GND" "pad_PLL5_REFCLK" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) +LVTTL S INpd2 list( "PLL5_BYPASS_EN" "GND" "pad_PLL5_BYPASS_EN" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) +LVTTL PRL GO_2 list( "GND" "pad_ag_5" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) +;LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vaao_5" "vaa_5" "VGG" "ag_5" ) + +LVDS D D1 nil + + + +; SPI4(5) TX LVTTL +; ---------------------------------------------------- + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) + +LVTTL PCL GCS list( "GND" "pad_GND" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL PRL GO list( "GND" "pad_gd33_5tx" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL S INpd2_2 list( "DISABLE_STRAP5" "GND" "pad_DISABLE_STRAP5" "Vdd" "DISABLE_STRAP5_n" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL S INnn2 list( "TX5_TSTAT[1]" "GND" "pad_TX5_TSTAT[1]" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL PRH VOP list( "GND" "pad_vd33op_5tx" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL S INnn2 list( "TX5_TSTAT[0]" "GND" "pad_TX5_TSTAT[0]" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL S INnn2 list( "TX5_TSCLK" "GND" "pad_TX5_TSCLK" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) + +LVTTL PCH VC list( "GND" "pad_Vdd" "SGND" "Vdd" "vd33o_5tx" "vd33p_5tx" "VGG" "gd33_5tx" ) +LVDS D D1 nil + +;LVTTL D D9_6u nil diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6.alias b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6.alias new file mode 100644 index 0000000000..8f787ade9f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.input.x6.alias @@ -0,0 +1,861 @@ +; Syntax +; ====== +; +; (1) Comments +; +; ;[String] +; +; Any line starts with a semi-colon (";") is considered +; to be a comment and will be discarded by the compiler +; +; +; (2) Normal Operations +; +; Arg1[S1 Arg2][S2 Arg3 S3 Arg3 S4 Arg4] +; +; (a) Command Mode +; -- supports only ONE argument +; +; BREAK -> Stop the compiler from reading any line +; below the breakpoint +; +; DEBUG_ON -> Turn on message debugging +; +; DEBUG_OFF -> Turn off message debugging +; +; (b) Alias Mode +; -- supports two or five arguments +; Sn = any white space including tabs +; Arg1 = Original Name +; Arg2 = Desired Aliased Name +; Arg3 = Loop Construct (will replace any string with "$Arg3" in Arg2) +; Arg4 = Loop Start Value +; Arg5 = Loop End Value +; +; + +; DISABLE STRAP +; ============== +pad_DISABLE_STRAP0 pad_DISABLE_STRAP[1] PWR_DN_STRAP_1 +pad_DISABLE_STRAP1 pad_DISABLE_STRAP[3] PWR_DN_STRAP_3 +pad_DISABLE_STRAP2 pad_DISABLE_STRAP[5] PWR_DN_STRAP_5 +pad_DISABLE_STRAP3 pad_DISABLE_STRAP[4] PWR_DN_STRAP_4 +pad_DISABLE_STRAP4 pad_DISABLE_STRAP[2] PWR_DN_STRAP_2 +pad_DISABLE_STRAP5 pad_DISABLE_STRAP[0] PWR_DN_STRAP_0 + + +; PLL 0-5 IO +; ================== +PLL0_BYPASS_EN PLL_IO[1].BYPASS_EN +PLL0_BYPASS_VCO PLL_IO[1].BYPASS_VCO +PLL0_LOCK PLL_IO[1].LOCK +PLL0_REFCLK PLL_IO[1].REFCLK +DISABLE_STRAP0_n PLL_IO[1].DISABLE_STRAP_N +ag_0 PLL_IO[1].AG +vaa_0 PLL_IO[1].VAA + +PLL1_BYPASS_EN PLL_IO[3].BYPASS_EN +PLL1_BYPASS_VCO PLL_IO[3].BYPASS_VCO +PLL1_LOCK PLL_IO[3].LOCK +PLL1_REFCLK PLL_IO[3].REFCLK +DISABLE_STRAP1_n PLL_IO[3].DISABLE_STRAP_N +ag_1 PLL_IO[3].AG +vaa_1 PLL_IO[3].VAA + +PLL2_BYPASS_EN PLL_IO[5].BYPASS_EN +PLL2_BYPASS_VCO PLL_IO[5].BYPASS_VCO +PLL2_LOCK PLL_IO[5].LOCK +PLL2_REFCLK PLL_IO[5].REFCLK +DISABLE_STRAP2_n PLL_IO[5].DISABLE_STRAP_N +ag_2 PLL_IO[5].AG +vaa_2 PLL_IO[5].VAA + +PLL3_BYPASS_EN PLL_IO[4].BYPASS_EN +PLL3_BYPASS_VCO PLL_IO[4].BYPASS_VCO +PLL3_LOCK PLL_IO[4].LOCK +PLL3_REFCLK PLL_IO[4].REFCLK +DISABLE_STRAP3_n PLL_IO[4].DISABLE_STRAP_N +ag_3 PLL_IO[4].AG +vaa_3 PLL_IO[4].VAA + +PLL4_BYPASS_EN PLL_IO[2].BYPASS_EN +PLL4_BYPASS_VCO PLL_IO[2].BYPASS_VCO +PLL4_LOCK PLL_IO[2].LOCK +PLL4_REFCLK PLL_IO[2].REFCLK +DISABLE_STRAP4_n PLL_IO[2].DISABLE_STRAP_N +ag_4 PLL_IO[2].AG +vaa_4 PLL_IO[2].VAA + +PLL5_BYPASS_EN PLL_IO[0].BYPASS_EN +PLL5_BYPASS_VCO PLL_IO[0].BYPASS_VCO +PLL5_LOCK PLL_IO[0].LOCK +PLL5_REFCLK PLL_IO[0].REFCLK +DISABLE_STRAP5_n PLL_IO[0].DISABLE_STRAP_N +ag_5 PLL_IO[0].AG +vaa_5 PLL_IO[0].VAA + +; PLL 0-5 PAD +; ================== + +pad_PLL0_BYPASS_EN PLL_PAD[1].BYPASS_EN BYPASS_EN_1 +pad_PLL0_BYPASS_VCO PLL_PAD[1].BYPASS_VCO BYPASS_VCO_1 +pad_PLL0_LOCK PLL_PAD[1].LOCK PLL_LOCK_1 +pad_PLL0_REFCLK PLL_PAD[1].REFCLK PLL_REFCLK_1 +pad_ag_0 PLL_PAD[1].AG VSSA_PLL +pad_vaa_0 PLL_PAD[1].VAA VDDA33_PLL + +pad_PLL1_BYPASS_EN PLL_PAD[3].BYPASS_EN BYPASS_EN_3 +pad_PLL1_BYPASS_VCO PLL_PAD[3].BYPASS_VCO BYPASS_VCO_3 +pad_PLL1_LOCK PLL_PAD[3].LOCK PLL_LOCK_3 +pad_PLL1_REFCLK PLL_PAD[3].REFCLK PLL_REFCLK_3 +pad_ag_1 PLL_PAD[3].AG VSSA_PLL +pad_vaa_1 PLL_PAD[3].VAA VDDA33_PLL + +pad_PLL2_BYPASS_EN PLL_PAD[5].BYPASS_EN BYPASS_EN_5 +pad_PLL2_BYPASS_VCO PLL_PAD[5].BYPASS_VCO BYPASS_VCO_5 +pad_PLL2_LOCK PLL_PAD[5].LOCK PLL_LOCK_5 +pad_PLL2_REFCLK PLL_PAD[5].REFCLK PLL_REFCLK_5 +pad_ag_2 PLL_PAD[5].AG VSSA_PLL +pad_vaa_2 PLL_PAD[5].VAA VDDA33_PLL + +pad_PLL3_BYPASS_EN PLL_PAD[4].BYPASS_EN BYPASS_EN_4 +pad_PLL3_BYPASS_VCO PLL_PAD[4].BYPASS_VCO BYPASS_VCO_4 +pad_PLL3_LOCK PLL_PAD[4].LOCK PLL_LOCK_4 +pad_PLL3_REFCLK PLL_PAD[4].REFCLK PLL_REFCLK_4 +pad_ag_3 PLL_PAD[4].AG VSSA_PLL +pad_vaa_3 PLL_PAD[4].VAA VDDA33_PLL + +pad_PLL4_BYPASS_EN PLL_PAD[2].BYPASS_EN BYPASS_EN_2 +pad_PLL4_BYPASS_VCO PLL_PAD[2].BYPASS_VCO BYPASS_VCO_2 +pad_PLL4_LOCK PLL_PAD[2].LOCK PLL_LOCK_2 +pad_PLL4_REFCLK PLL_PAD[2].REFCLK PLL_REFCLK_2 +pad_ag_4 PLL_PAD[2].AG VSSA_PLL +pad_vaa_4 PLL_PAD[2].VAA VDDA33_PLL + +pad_PLL5_BYPASS_EN PLL_PAD[0].BYPASS_EN BYPASS_EN_0 +pad_PLL5_BYPASS_VCO PLL_PAD[0].BYPASS_VCO BYPASS_VCO_0 +pad_PLL5_LOCK PLL_PAD[0].LOCK PLL_LOCK_0 +pad_PLL5_REFCLK PLL_PAD[0].REFCLK PLL_REFCLK_0 +pad_ag_5 PLL_PAD[0].AG VSSA_PLL +pad_vaa_5 PLL_PAD[0].VAA VDDA33_PLL + + +; Extra PLL LVDS PADs +; =================== +padn_PLL0_CLKOUT2 PLL_PAD[1].padn_PLL0_CLKOUT2 CLKOUT2N_1 +padn_PLL1_CLKOUT2 PLL_PAD[3].padn_PLL0_CLKOUT2 CLKOUT2N_3 +padn_PLL2_CLKOUT2 PLL_PAD[5].padn_PLL0_CLKOUT2 CLKOUT2N_5 +padn_PLL3_CLKOUT2 PLL_PAD[4].padn_PLL0_CLKOUT2 CLKOUT2N_4 +padn_PLL4_CLKOUT2 PLL_PAD[2].padn_PLL0_CLKOUT2 CLKOUT2N_2 +padn_PLL5_CLKOUT2 PLL_PAD[0].padn_PLL0_CLKOUT2 CLKOUT2N_0 + +padp_PLL0_CLKOUT2 PLL_PAD[1].padp_PLL0_CLKOUT2 CLKOUT2P_1 +padp_PLL1_CLKOUT2 PLL_PAD[3].padp_PLL0_CLKOUT2 CLKOUT2P_3 +padp_PLL2_CLKOUT2 PLL_PAD[5].padp_PLL0_CLKOUT2 CLKOUT2P_5 +padp_PLL3_CLKOUT2 PLL_PAD[4].padp_PLL0_CLKOUT2 CLKOUT2P_4 +padp_PLL4_CLKOUT2 PLL_PAD[2].padp_PLL0_CLKOUT2 CLKOUT2P_2 +padp_PLL5_CLKOUT2 PLL_PAD[0].padp_PLL0_CLKOUT2 CLKOUT2P_0 + +PLL0_CLKOUT2 PLL_IO[1].CLKOUT2 +PLL1_CLKOUT2 PLL_IO[3].CLKOUT2 +PLL2_CLKOUT2 PLL_IO[5].CLKOUT2 +PLL3_CLKOUT2 PLL_IO[4].CLKOUT2 +PLL4_CLKOUT2 PLL_IO[2].CLKOUT2 +PLL5_CLKOUT2 PLL_IO[0].CLKOUT2 + + +; TX IO Side +; ================== + +TX0_TDAT[$i] TXSPI4_IO[1].xo_tdat[$i] i 0 15 +TX0_TSTAT[$i] TXSPI4_IO[1].xi_tstat[$i] i 0 1 +TX0_TDCLK TXSPI4_IO[1].xo_tdclk +TX0_TCTL TXSPI4_IO[1].xo_tctl +TX0_TSCLK TXSPI4_IO[1].xi_tsclk + +TX1_TDAT[$i] TXSPI4_IO[3].xo_tdat[$i] i 0 15 +TX1_TSTAT[$i] TXSPI4_IO[3].xi_tstat[$i] i 0 1 +TX1_TDCLK TXSPI4_IO[3].xo_tdclk +TX1_TCTL TXSPI4_IO[3].xo_tctl +TX1_TSCLK TXSPI4_IO[3].xi_tsclk + +TX2_TDAT[$i] TXSPI4_IO[5].xo_tdat[$i] i 0 15 +TX2_TSTAT[$i] TXSPI4_IO[5].xi_tstat[$i] i 0 1 +TX2_TDCLK TXSPI4_IO[5].xo_tdclk +TX2_TCTL TXSPI4_IO[5].xo_tctl +TX2_TSCLK TXSPI4_IO[5].xi_tsclk + +TX3_TDAT[$i] TXSPI4_IO[4].xo_tdat[$i] i 0 15 +TX3_TSTAT[$i] TXSPI4_IO[4].xi_tstat[$i] i 0 1 +TX3_TDCLK TXSPI4_IO[4].xo_tdclk +TX3_TCTL TXSPI4_IO[4].xo_tctl +TX3_TSCLK TXSPI4_IO[4].xi_tsclk + +TX4_TDAT[$i] TXSPI4_IO[2].xo_tdat[$i] i 0 15 +TX4_TSTAT[$i] TXSPI4_IO[2].xi_tstat[$i] i 0 1 +TX4_TDCLK TXSPI4_IO[2].xo_tdclk +TX4_TCTL TXSPI4_IO[2].xo_tctl +TX4_TSCLK TXSPI4_IO[2].xi_tsclk + +TX5_TDAT[$i] TXSPI4_IO[0].xo_tdat[$i] i 0 15 +TX5_TSTAT[$i] TXSPI4_IO[0].xi_tstat[$i] i 0 1 +TX5_TDCLK TXSPI4_IO[0].xo_tdclk +TX5_TCTL TXSPI4_IO[0].xo_tctl +TX5_TSCLK TXSPI4_IO[0].xi_tsclk + +; TX PAD Side +; ================== + +padn_TX0_TDAT[$i] TXSPI4_PAD[1].padn_TX_TDAT[$i] i 0 15 TDATN_1[$i] +padp_TX0_TDAT[$i] TXSPI4_PAD[1].padp_TX_TDAT[$i] i 0 15 TDATP_1[$i] +pad_TX0_TSTAT[$i] TXSPI4_PAD[1].pad_TX_TSTAT[$i] i 0 1 TSTAT_1[$i] +padn_TX0_TDCLK TXSPI4_PAD[1].padn_TX_TDCLK TDCLKN_1 +padp_TX0_TDCLK TXSPI4_PAD[1].padp_TX_TDCLK TDCLKP_1 +padn_TX0_TCTL TXSPI4_PAD[1].padn_TX_TCTL TCTLN_1 +padp_TX0_TCTL TXSPI4_PAD[1].padp_TX_TCTL TCTLP_1 +pad_TX0_TSCLK TXSPI4_PAD[1].pad_TX_TSCLK TSCLK_1 + +pad_vd25op_0tx TXSPI4_PAD[1].LVDS_VDDO VDD25 +pad_gd25_0tx TXSPI4_PAD[1].LVDS_VSSO VSS +pad_vref_0tx TXSPI4_PAD[1].LVDS_VREF VREF_1 +pad_vd33op_0tx TXSPI4_PAD[1].LVTTL_VDDP VDD33 +pad_gd33_0tx TXSPI4_PAD[1].LVTTL_VSSO VSS + + +padn_TX1_TDAT[$i] TXSPI4_PAD[3].padn_TX_TDAT[$i] i 0 15 TDATN_3[$i] +padp_TX1_TDAT[$i] TXSPI4_PAD[3].padp_TX_TDAT[$i] i 0 15 TDATP_3[$i] +pad_TX1_TSTAT[$i] TXSPI4_PAD[3].pad_TX_TSTAT[$i] i 0 1 TSTAT_3[$i] +padn_TX1_TDCLK TXSPI4_PAD[3].padn_TX_TDCLK TDCLKN_3 +padp_TX1_TDCLK TXSPI4_PAD[3].padp_TX_TDCLK TDCLKP_3 +padn_TX1_TCTL TXSPI4_PAD[3].padn_TX_TCTL TCTLN_3 +padp_TX1_TCTL TXSPI4_PAD[3].padp_TX_TCTL TCTLP_3 +pad_TX1_TSCLK TXSPI4_PAD[3].pad_TX_TSCLK TSCLK_3 + +pad_vd25op_1tx TXSPI4_PAD[3].LVDS_VDDO VDD25 +pad_gd25_1tx TXSPI4_PAD[3].LVDS_VSSO VSS +pad_vref_1tx TXSPI4_PAD[3].LVDS_VREF VREF_3 +pad_vd33op_1tx TXSPI4_PAD[3].LVTTL_VDDP VDD33 +pad_gd33_1tx TXSPI4_PAD[3].LVTTL_VSSO VSS + + + +padn_TX2_TDAT[$i] TXSPI4_PAD[5].padn_TX_TDAT[$i] i 0 15 TDATN_5[$i] +padp_TX2_TDAT[$i] TXSPI4_PAD[5].padp_TX_TDAT[$i] i 0 15 TDATP_5[$i] +pad_TX2_TSTAT[$i] TXSPI4_PAD[5].pad_TX_TSTAT[$i] i 0 1 TSTAT_5[$i] +padn_TX2_TDCLK TXSPI4_PAD[5].padn_TX_TDCLK TDCLKN_5 +padp_TX2_TDCLK TXSPI4_PAD[5].padp_TX_TDCLK TDCLKP_5 +padn_TX2_TCTL TXSPI4_PAD[5].padn_TX_TCTL TCTLN_5 +padp_TX2_TCTL TXSPI4_PAD[5].padp_TX_TCTL TCTLP_5 +pad_TX2_TSCLK TXSPI4_PAD[5].pad_TX_TSCLK TSCLK_5 + +pad_vd25op_2tx TXSPI4_PAD[5].LVDS_VDDO VDD25 +pad_gd25_2tx TXSPI4_PAD[5].LVDS_VSSO VSS +pad_vref_2tx TXSPI4_PAD[5].LVDS_VREF VREF_5 +pad_vd33op_2tx TXSPI4_PAD[5].LVTTL_VDDP VDD33 +pad_gd33_2tx TXSPI4_PAD[5].LVTTL_VSSO VSS + + +padn_TX3_TDAT[$i] TXSPI4_PAD[4].padn_TX_TDAT[$i] i 0 15 TDATN_4[$i] +padp_TX3_TDAT[$i] TXSPI4_PAD[4].padp_TX_TDAT[$i] i 0 15 TDATP_4[$i] +pad_TX3_TSTAT[$i] TXSPI4_PAD[4].pad_TX_TSTAT[$i] i 0 1 TSTAT_4[$i] +padn_TX3_TDCLK TXSPI4_PAD[4].padn_TX_TDCLK TDCLKN_4 +padp_TX3_TDCLK TXSPI4_PAD[4].padp_TX_TDCLK TDCLKP_4 +padn_TX3_TCTL TXSPI4_PAD[4].padn_TX_TCTL TCTLN_4 +padp_TX3_TCTL TXSPI4_PAD[4].padp_TX_TCTL TCTLP_4 +pad_TX3_TSCLK TXSPI4_PAD[4].pad_TX_TSCLK TSCLK_4 + +pad_vd25op_3tx TXSPI4_PAD[4].LVDS_VDDO VDD25 +pad_gd25_3tx TXSPI4_PAD[4].LVDS_VSSO VSS +pad_vref_3tx TXSPI4_PAD[4].LVDS_VREF VREF_4 +pad_vd33op_3tx TXSPI4_PAD[4].LVTTL_VDDP VDD33 +pad_gd33_3tx TXSPI4_PAD[4].LVTTL_VSSO VSS + + + +padn_TX4_TDAT[$i] TXSPI4_PAD[2].padn_TX_TDAT[$i] i 0 15 TDATN_2[$i] +padp_TX4_TDAT[$i] TXSPI4_PAD[2].padp_TX_TDAT[$i] i 0 15 TDATP_2[$i] +pad_TX4_TSTAT[$i] TXSPI4_PAD[2].pad_TX_TSTAT[$i] i 0 1 TSTAT_2[$i] +padn_TX4_TDCLK TXSPI4_PAD[2].padn_TX_TDCLK TDCLKN_2 +padp_TX4_TDCLK TXSPI4_PAD[2].padp_TX_TDCLK TDCLKP_2 +padn_TX4_TCTL TXSPI4_PAD[2].padn_TX_TCTL TCTLN_2 +padp_TX4_TCTL TXSPI4_PAD[2].padp_TX_TCTL TCTLP_2 +pad_TX4_TSCLK TXSPI4_PAD[2].pad_TX_TSCLK TSCLK_2 + +pad_vd25op_4tx TXSPI4_PAD[2].LVDS_VDDO VDD25 +pad_gd25_4tx TXSPI4_PAD[2].LVDS_VSSO VSS +pad_vref_4tx TXSPI4_PAD[2].LVDS_VREF VREF_2 +pad_vd33op_4tx TXSPI4_PAD[2].LVTTL_VDDP VDD33 +pad_gd33_4tx TXSPI4_PAD[2].LVTTL_VSSO VSS + + + +padn_TX5_TDAT[$i] TXSPI4_PAD[0].padn_TX_TDAT[$i] i 0 15 TDATN_0[$i] +padp_TX5_TDAT[$i] TXSPI4_PAD[0].padp_TX_TDAT[$i] i 0 15 TDATP_0[$i] +pad_TX5_TSTAT[$i] TXSPI4_PAD[0].pad_TX_TSTAT[$i] i 0 1 TSTAT_0[$i] +padn_TX5_TDCLK TXSPI4_PAD[0].padn_TX_TDCLK TDCLKN_0 +padp_TX5_TDCLK TXSPI4_PAD[0].padp_TX_TDCLK TDCLKP_0 +padn_TX5_TCTL TXSPI4_PAD[0].padn_TX_TCTL TCTLN_0 +padp_TX5_TCTL TXSPI4_PAD[0].padp_TX_TCTL TCTLP_0 +pad_TX5_TSCLK TXSPI4_PAD[0].pad_TX_TSCLK TSCLK_0 + +pad_vd25op_5tx TXSPI4_PAD[0].LVDS_VDDO VDD25 +pad_gd25_5tx TXSPI4_PAD[0].LVDS_VSSO VSS +pad_vref_5tx TXSPI4_PAD[0].LVDS_VREF VREF_0 +pad_vd33op_5tx TXSPI4_PAD[0].LVTTL_VDDP VDD33 +pad_gd33_5tx TXSPI4_PAD[0].LVTTL_VSSO VSS + + + +; RX IO Side +; ================== + +RX0_RDAT[$i] RXSPI4_IO[1].xi_rdat[$i] i 0 15 +RX0_RSTAT[$i] RXSPI4_IO[1].xo_rstat[$i] i 0 1 +RX0_RDCLK RXSPI4_IO[1].xi_rdclk +RX0_RCTL RXSPI4_IO[1].xi_rctl +RX0_RSCLK RXSPI4_IO[1].xo_rsclk + +RX1_RDAT[$i] RXSPI4_IO[3].xi_rdat[$i] i 0 15 +RX1_RSTAT[$i] RXSPI4_IO[3].xo_rstat[$i] i 0 1 +RX1_RDCLK RXSPI4_IO[3].xi_rdclk +RX1_RCTL RXSPI4_IO[3].xi_rctl +RX1_RSCLK RXSPI4_IO[3].xo_rsclk + +RX2_RDAT[$i] RXSPI4_IO[5].xi_rdat[$i] i 0 15 +RX2_RSTAT[$i] RXSPI4_IO[5].xo_rstat[$i] i 0 1 +RX2_RDCLK RXSPI4_IO[5].xi_rdclk +RX2_RCTL RXSPI4_IO[5].xi_rctl +RX2_RSCLK RXSPI4_IO[5].xo_rsclk + +RX3_RDAT[$i] RXSPI4_IO[4].xi_rdat[$i] i 0 15 +RX3_RSTAT[$i] RXSPI4_IO[4].xo_rstat[$i] i 0 1 +RX3_RDCLK RXSPI4_IO[4].xi_rdclk +RX3_RCTL RXSPI4_IO[4].xi_rctl +RX3_RSCLK RXSPI4_IO[4].xo_rsclk + +RX4_RDAT[$i] RXSPI4_IO[2].xi_rdat[$i] i 0 15 +RX4_RSTAT[$i] RXSPI4_IO[2].xo_rstat[$i] i 0 1 +RX4_RDCLK RXSPI4_IO[2].xi_rdclk +RX4_RCTL RXSPI4_IO[2].xi_rctl +RX4_RSCLK RXSPI4_IO[2].xo_rsclk + +RX5_RDAT[$i] RXSPI4_IO[0].xi_rdat[$i] i 0 15 +RX5_RSTAT[$i] RXSPI4_IO[0].xo_rstat[$i] i 0 1 +RX5_RDCLK RXSPI4_IO[0].xi_rdclk +RX5_RCTL RXSPI4_IO[0].xi_rctl +RX5_RSCLK RXSPI4_IO[0].xo_rsclk + +; RX PAD Side +; ================== + +padn_RX0_RDAT[$i] RXSPI4_PAD[1].padn_RX_RDAT[$i] i 0 15 RDATN_1[$i] +padp_RX0_RDAT[$i] RXSPI4_PAD[1].padp_RX_RDAT[$i] i 0 15 RDATP_1[$i] +pad_RX0_RSTAT[$i] RXSPI4_PAD[1].pad_RX_RSTAT[$i] i 0 1 RSTAT_1[$i] +padn_RX0_RDCLK RXSPI4_PAD[1].padn_RX_RDCLK RDCLKN_1 +padp_RX0_RDCLK RXSPI4_PAD[1].padp_RX_RDCLK RDCLKP_1 +padn_RX0_RCTL RXSPI4_PAD[1].padn_RX_RCTL RCTLN_1 +padp_RX0_RCTL RXSPI4_PAD[1].padp_RX_RCTL RCTLP_1 +pad_RX0_RSCLK RXSPI4_PAD[1].pad_RX_RSCLK RSCLK_1 + +pad_vd25op_0rx RXSPI4_PAD[1].LVDS_VDDP VDD25 +pad_gd25_0rx RXSPI4_PAD[1].LVDS_VSSO VSS +pad_vd33op_0rx RXSPI4_PAD[1].LVTTL_VDDO VDD33 +pad_gd33_0rx RXSPI4_PAD[1].LVTTL_VSSO VSS + + +padn_RX1_RDAT[$i] RXSPI4_PAD[3].padn_RX_RDAT[$i] i 0 15 RDATN_3[$i] +padp_RX1_RDAT[$i] RXSPI4_PAD[3].padp_RX_RDAT[$i] i 0 15 RDATP_3[$i] +pad_RX1_RSTAT[$i] RXSPI4_PAD[3].pad_RX_RSTAT[$i] i 0 1 RSTAT_3[$i] +padn_RX1_RDCLK RXSPI4_PAD[3].padn_RX_RDCLK RDCLKN_3 +padp_RX1_RDCLK RXSPI4_PAD[3].padp_RX_RDCLK RDCLKP_3 +padn_RX1_RCTL RXSPI4_PAD[3].padn_RX_RCTL RCTLN_3 +padp_RX1_RCTL RXSPI4_PAD[3].padp_RX_RCTL RCTLP_3 +pad_RX1_RSCLK RXSPI4_PAD[3].pad_RX_RSCLK RSCLK_3 + +pad_vd25op_1rx RXSPI4_PAD[3].LVDS_VDDP VDD25 +pad_gd25_1rx RXSPI4_PAD[3].LVDS_VSSO VSS +pad_vd33op_1rx RXSPI4_PAD[3].LVTTL_VDDO VDD33 +pad_gd33_1rx RXSPI4_PAD[3].LVTTL_VSSO VSS + + +padn_RX2_RDAT[$i] RXSPI4_PAD[5].padn_RX_RDAT[$i] i 0 15 RDATN_5[$i] +padp_RX2_RDAT[$i] RXSPI4_PAD[5].padp_RX_RDAT[$i] i 0 15 RDATP_5[$i] +pad_RX2_RSTAT[$i] RXSPI4_PAD[5].pad_RX_RSTAT[$i] i 0 1 RSTAT_5[$i] +padn_RX2_RDCLK RXSPI4_PAD[5].padn_RX_RDCLK RDCLKN_5 +padp_RX2_RDCLK RXSPI4_PAD[5].padp_RX_RDCLK RDCLKP_5 +padn_RX2_RCTL RXSPI4_PAD[5].padn_RX_RCTL RCTLN_5 +padp_RX2_RCTL RXSPI4_PAD[5].padp_RX_RCTL RCTLP_5 +pad_RX2_RSCLK RXSPI4_PAD[5].pad_RX_RSCLK RSCLK_5 + +pad_vd25op_2rx RXSPI4_PAD[5].LVDS_VDDP VDD25 +pad_gd25_2rx RXSPI4_PAD[5].LVDS_VSSO VSS +pad_vd33op_2rx RXSPI4_PAD[5].LVTTL_VDDO VDD33 +pad_gd33_2rx RXSPI4_PAD[5].LVTTL_VSSO VSS + + +padn_RX3_RDAT[$i] RXSPI4_PAD[4].padn_RX_RDAT[$i] i 0 15 RDATN_4[$i] +padp_RX3_RDAT[$i] RXSPI4_PAD[4].padp_RX_RDAT[$i] i 0 15 RDATP_4[$i] +pad_RX3_RSTAT[$i] RXSPI4_PAD[4].pad_RX_RSTAT[$i] i 0 1 RSTAT_4[$i] +padn_RX3_RDCLK RXSPI4_PAD[4].padn_RX_RDCLK RDCLKN_4 +padp_RX3_RDCLK RXSPI4_PAD[4].padp_RX_RDCLK RDCLKP_4 +padn_RX3_RCTL RXSPI4_PAD[4].padn_RX_RCTL RCTLN_4 +padp_RX3_RCTL RXSPI4_PAD[4].padp_RX_RCTL RCTLP_4 +pad_RX3_RSCLK RXSPI4_PAD[4].pad_RX_RSCLK RSCLK_4 + +pad_vd25op_3rx RXSPI4_PAD[4].LVDS_VDDP VDD25 +pad_gd25_3rx RXSPI4_PAD[4].LVDS_VSSO VSS +pad_vd33op_3rx RXSPI4_PAD[4].LVTTL_VDDO VDD33 +pad_gd33_3rx RXSPI4_PAD[4].LVTTL_VSSO VSS + + +padn_RX4_RDAT[$i] RXSPI4_PAD[2].padn_RX_RDAT[$i] i 0 15 RDATN_2[$i] +padp_RX4_RDAT[$i] RXSPI4_PAD[2].padp_RX_RDAT[$i] i 0 15 RDATP_2[$i] +pad_RX4_RSTAT[$i] RXSPI4_PAD[2].pad_RX_RSTAT[$i] i 0 1 RSTAT_2[$i] +padn_RX4_RDCLK RXSPI4_PAD[2].padn_RX_RDCLK RDCLKN_2 +padp_RX4_RDCLK RXSPI4_PAD[2].padp_RX_RDCLK RDCLKP_2 +padn_RX4_RCTL RXSPI4_PAD[2].padn_RX_RCTL RCTLN_2 +padp_RX4_RCTL RXSPI4_PAD[2].padp_RX_RCTL RCTLP_2 +pad_RX4_RSCLK RXSPI4_PAD[2].pad_RX_RSCLK RSCLK_2 + +pad_vd25op_4rx RXSPI4_PAD[2].LVDS_VDDP VDD25 +pad_gd25_4rx RXSPI4_PAD[2].LVDS_VSSO VSS +pad_vd33op_4rx RXSPI4_PAD[2].LVTTL_VDDO VDD33 +pad_gd33_4rx RXSPI4_PAD[2].LVTTL_VSSO VSS + + +padn_RX5_RDAT[$i] RXSPI4_PAD[0].padn_RX_RDAT[$i] i 0 15 RDATN_0[$i] +padp_RX5_RDAT[$i] RXSPI4_PAD[0].padp_RX_RDAT[$i] i 0 15 RDATP_0[$i] +pad_RX5_RSTAT[$i] RXSPI4_PAD[0].pad_RX_RSTAT[$i] i 0 1 RSTAT_0[$i] +padn_RX5_RDCLK RXSPI4_PAD[0].padn_RX_RDCLK RDCLKN_0 +padp_RX5_RDCLK RXSPI4_PAD[0].padp_RX_RDCLK RDCLKP_0 +padn_RX5_RCTL RXSPI4_PAD[0].padn_RX_RCTL RCTLN_0 +padp_RX5_RCTL RXSPI4_PAD[0].padp_RX_RCTL RCTLP_0 +pad_RX5_RSCLK RXSPI4_PAD[0].pad_RX_RSCLK RSCLK_0 + +pad_vd25op_5rx RXSPI4_PAD[0].LVDS_VDDP VDD25 +pad_gd25_5rx RXSPI4_PAD[0].LVDS_VSSO VSS +pad_vd33op_5rx RXSPI4_PAD[0].LVTTL_VDDO VDD33 +pad_gd33_5rx RXSPI4_PAD[0].LVTTL_VSSO VSS + + +; EBIF IO Side +; ============= + +ADDR[$i] BUSIF_IO.ADDR[$i] i 1 17 +DATA_IN[$i] BUSIF_IO.DATA_IN[$i] i 0 15 +CLK_X8BUSIF BUSIF_IO.CLK_X8BUSIF +BUSIF_RESET_N BUSIF_IO.BUSIF_RESET_N +RW_N BUSIF_IO.RW_N +AS_N BUSIF_IO.AS_N +DS_N BUSIF_IO.DS_N +CS_N BUSIF_IO.CS_N +DTACK_INV BUSIF_IO.DTACK_INV +RW_N_INV BUSIF_IO.RW_N_INV +IGNORE_DS_N BUSIF_IO.IGNORE_DS_N +SYNC_MODE BUSIF_IO.SYNC_MODE +DATA_OUT[$i] BUSIF_IO.DATA_OUT[$i] i 0 15 +DATA_OE[$i] BUSIF_IO.DATA_OE[$i] i 0 15 +DTACK_N BUSIF_IO.DTACK_N +DTACK_OE BUSIF_IO.DTACK_OE +INTR_N BUSIF_IO.INTR_N +oe_INTR_N BUSIF_IO.INTR_OE + + +; EBIF PAD Side +; ============= + +pad_ADDR[$i] BUSIF_PAD.ADDR[$i] i 1 17 ADDR[$i] +pad_DATA[$i] BUSIF_PAD.DATA[$i] i 0 15 DATA[$i] +pad_CLK_X8BUSIF BUSIF_PAD.CLK_X8BUSIF BUSIF_CLK +pad_BUSIF_RESET_N BUSIF_PAD.BUSIF_RESET_N BUSIF_RESET_N +pad_RW_N BUSIF_PAD.RW_N RW_N +pad_AS_N BUSIF_PAD.AS_N AS_N +pad_DS_N BUSIF_PAD.DS_N DS_N +pad_CS_N BUSIF_PAD.CS_N CS_N +pad_DTACK_INV BUSIF_PAD.DTACK_INV DTACK_INV +pad_RW_N_INV BUSIF_PAD.RW_N_INV RW_N_INV +pad_IGNORE_DS_N BUSIF_PAD.IGNORE_DS_N IGNORE_DS_N +pad_SYNC_MODE BUSIF_PAD.SYNC_MODE SYNC_MODE +pad_DTACK_N BUSIF_PAD.DTACK_N DTACK_N +pad_INTR_N BUSIF_PAD.INTR_N INTR_N + +pad_vd33op_Bus BUSIF_PAD.LVTTL_VDDO VDD33 +pad_gd33_Bus BUSIF_PAD.LVTTL_VSSO VSS + + +; TAP IO Side +; =========== + +TCK JTAG_IO.TCK +TDI JTAG_IO.TDI +TMS JTAG_IO.TMS +TRST_N JTAG_IO.TRST_N +oe_TDO JTAG_IO.TDO_OE +TDO JTAG_IO.TDO + +; TAP PAD Side +; =========== + +pad_TCK JTAG_PAD.TCK TCK +pad_TDI JTAG_PAD.TDI TDI +pad_TMS JTAG_PAD.TMS TMS +pad_TRST_N JTAG_PAD.TRST_N TRST_N +pad_TDO JTAG_PAD.TDO TDO + +pad_vd33op_Misc JTAG_PAD.LVTTL_VDDO VDD33 +pad_gd33_Misc JTAG_PAD.LVTTL_VSSO VSS + +; Test +; ==== + +SCAN_IN0 SCANTX_IN_IO +SCAN_OUT0 SCANTX_OUT_IO + +pad_SCAN_IN0 SCANTX_IN_PAD SCAN_IN_0 +pad_SCAN_OUT0 SCANTX_OUT_PAD SCAN_OUT_0 + +SCAN_IN1 SCANRX_IN_IO.SCAN1 +SCAN_IN2 SCANRX_IN_IO.SCAN2 +SCAN_IN3 SCANRX_IN_IO.SCAN3 + +pad_SCAN_IN1 SCANRX_IN_PAD.SCAN1 SCAN_IN_1 +pad_SCAN_IN2 SCANRX_IN_PAD.SCAN2 SCAN_IN_2 +pad_SCAN_IN3 SCANRX_IN_PAD.SCAN3 SCAN_IN_3 + +SCAN_OUT1 SCANRX_OUT_IO.SCAN1 +SCAN_OUT2 SCANRX_OUT_IO.SCAN2 +SCAN_OUT3 SCANRX_OUT_IO.SCAN3 + +pad_SCAN_OUT1 SCANRX_OUT_PAD.SCAN1 SCAN_OUT_1 +pad_SCAN_OUT2 SCANRX_OUT_PAD.SCAN2 SCAN_OUT_2 +pad_SCAN_OUT3 SCANRX_OUT_PAD.SCAN3 SCAN_OUT_3 + +pad_SCAN_ENABLE pad_SCAN_ENABLE SCAN_ENABLE +pad_TEST_MODE pad_TEST_MODE TEST_MODE +pad_CHIP_RESET_N pad_CHIP_RESET_N CHIP_RESET_N + +ASII0 EXTSERIAL_IO.ASII.0 +ASII1 EXTSERIAL_IO.ASII.1 +ASII2 EXTSERIAL_IO.ASII.2 +ASII_E EXTSERIAL_IO.ASII.e +ASIO0 EXTSERIAL_IO.ASIO.0 +ASIO1 EXTSERIAL_IO.ASIO.1 +ASIO2 EXTSERIAL_IO.ASIO.2 +ASIO_E EXTSERIAL_IO.ASIO.e + +pad_ASII0 EXTSERIAL_PAD.ASII.0 ASII_0 +pad_ASII1 EXTSERIAL_PAD.ASII.1 ASII_1 +pad_ASII2 EXTSERIAL_PAD.ASII.2 ASII_2 +pad_ASII_E EXTSERIAL_PAD.ASII.e ASII_E +pad_ASIO0 EXTSERIAL_PAD.ASIO.0 ASIO_0 +pad_ASIO1 EXTSERIAL_PAD.ASIO.1 ASIO_1 +pad_ASIO2 EXTSERIAL_PAD.ASIO.2 ASIO_2 +pad_ASIO_E EXTSERIAL_PAD.ASIO.e ASIO_E + +Vdd CORE_VDD +GND CORE_GND + +pad_Vdd pad_CORE_VDD VDD +pad_GND pad_CORE_GND VSS + + +pad_OBS_SPI4_IP_VDD PAD_OBS_SPI4_IP_VDD +pad_OBS_SPI4_IP_GND PAD_OBS_SPI4_IP_GND +pad_OBS_SPI4_ASYNC_VDD PAD_OBS_SPI4_ASYNC_VDD +pad_OBS_SPI4_ASYNC_GND PAD_OBS_SPI4_ASYNC_GND +pad_OBS_ASOC_VDD PAD_OBS_ASOC_VDD +pad_OBS_ASOC_GND PAD_OBS_ASOC_GND + +pad_SOSC_TEST_PAD[0] SOSC_TEST_PAD[0] +pad_SOSC_TEST_PAD[1] SOSC_TEST_PAD[1] +pad_SOSC_TEST_PAD[2] SOSC_TEST_PAD[2] +pad_SOSC_TEST_PAD[3] SOSC_TEST_PAD[3] +pad_SOSC_TEST_PAD[4] SOSC_TEST_PAD[4] + + +; Floating Node Name Aliasing +; =========================== + +ASII_E.DI FLOAT_ASII_E_DI +ASIO0.DI FLOAT_ASIO0_DI +ASIO1.DI FLOAT_ASIO1_DI +ASIO2.DI FLOAT_ASIO2_DI +DTACK_N.DIN FLOAT_DTACK_N_DIN +INTR_N.DIN FLOAT_INTR_N_DIN +PLL0_LOCK.DIN FLOAT_PLL0_LOCK_DIN +PLL1_LOCK.DIN FLOAT_PLL1_LOCK_DIN +PLL2_LOCK.DIN FLOAT_PLL2_LOCK_DIN +PLL3_LOCK.DIN FLOAT_PLL3_LOCK_DIN +PLL4_LOCK.DIN FLOAT_PLL4_LOCK_DIN +PLL5_LOCK.DIN FLOAT_PLL5_LOCK_DIN +RX0_RSCLK.DIN FLOAT_RX0_RSCLK_DIN +RX0_RSTAT[0].DIN FLOAT_RX0_RSTAT0_DIN +RX0_RSTAT[1].DIN FLOAT_RX0_RSTAT1_DIN +RX1_RSCLK.DIN FLOAT_RX1_RSCLK_DIN +RX1_RSTAT[0].DIN FLOAT_RX1_RSTAT0_DIN +RX1_RSTAT[1].DIN FLOAT_RX1_RSTAT1_DIN +RX2_RSCLK.DIN FLOAT_RX2_RSCLK_DIN +RX2_RSTAT[0].DIN FLOAT_RX2_RSTAT0_DIN +RX2_RSTAT[1].DIN FLOAT_RX2_RSTAT1_DIN +RX3_RSCLK.DIN FLOAT_RX3_RSCLK_DIN +RX3_RSTAT[0].DIN FLOAT_RX3_RSTAT0_DIN +RX3_RSTAT[1].DIN FLOAT_RX3_RSTAT1_DIN +RX4_RSCLK.DIN FLOAT_RX4_RSCLK_DIN +RX4_RSTAT[0].DIN FLOAT_RX4_RSTAT0_DIN +RX4_RSTAT[1].DIN FLOAT_RX4_RSTAT1_DIN +RX5_RSCLK.DIN FLOAT_RX5_RSCLK_DIN +RX5_RSTAT[0].DIN FLOAT_RX5_RSTAT0_DIN +RX5_RSTAT[1].DIN FLOAT_RX5_RSTAT1_DIN +SCAN_OUT0.DI FLOAT_SCAN_OUT0_DI +SCAN_OUT1.DI FLOAT_SCAN_OUT1_DI +SCAN_OUT2.DI FLOAT_SCAN_OUT2_DI +SCAN_OUT3.DI FLOAT_SCAN_OUT3_DI +SOSC_TEST_IO[0].DI FLOAT_SOSC_TEST_IO0_DI +SOSC_TEST_IO[1].DI FLOAT_SOSC_TEST_IO1_DI +SOSC_TEST_IO[2].DI FLOAT_SOSC_TEST_IO2_DI +SOSC_TEST_IO[3].DI FLOAT_SOSC_TEST_IO3_DI +SOSC_TEST_IO[4].DI FLOAT_SOSC_TEST_IO4_DI +TDO.DI FLOAT_TDO_DI +PAD_OBS_SPI4_IP_VDD_RIN FLOAT_OBS_SPI4_IP_VDD_RIN +PAD_OBS_SPI4_IP_GND_RIN FLOAT_OBS_SPI4_IP_GND_RIN +PAD_OBS_SPI4_ASYNC_VDD_RIN FLOAT_OBS_SPI4_ASYNC_VDD_RIN +PAD_OBS_SPI4_ASYNC_GND_RIN FLOAT_OBS_SPI4_ASYNC_GND_RIN +PAD_OBS_ASOC_VDD_RIN FLOAT_OBS_ASOC_VDD_RIN +PAD_OBS_ASOC_GND_RIN FLOAT_OBS_ASOC_GND_RIN + + +; Internal Power Ring +; ==================== +gd25_0rx INT_gd25_1rx +gd25_0tx INT_gd25_1tx +gd25_1rx INT_gd25_3rx +gd25_1tx INT_gd25_3tx +gd25_2rx INT_gd25_5rx +gd25_2tx INT_gd25_5tx +gd25_3rx INT_gd25_4rx +gd25_3tx INT_gd25_4tx +gd25_4rx INT_gd25_2rx +gd25_4tx INT_gd25_2tx +gd25_5rx INT_gd25_0rx +gd25_5tx INT_gd25_0tx + +gd33_0rx INT_gd33_1rx +gd33_0tx INT_gd33_1tx +gd33_1rx INT_gd33_3rx +gd33_1tx INT_gd33_3tx +gd33_2rx INT_gd33_5rx +gd33_2tx INT_gd33_5tx +gd33_3rx INT_gd33_4rx +gd33_3tx INT_gd33_4tx +gd33_4rx INT_gd33_2rx +gd33_4tx INT_gd33_2tx +gd33_5rx INT_gd33_0rx +gd33_5tx INT_gd33_0tx + +gd33_Bus INT_gd33_Bus +gd33_Misc INT_gd33_Misc + +vaao_0 INT_vaao_1 +vaao_1 INT_vaao_3 +vaao_2 INT_vaao_5 +vaao_3 INT_vaao_4 +vaao_4 INT_vaao_2 +vaao_5 INT_vaao_0 + +vd25o_0rx INT_vd25o_1rx +vd25o_0tx INT_vd25o_1tx +vd25o_1rx INT_vd25o_3rx +vd25o_1tx INT_vd25o_3tx +vd25o_2rx INT_vd25o_5rx +vd25o_2tx INT_vd25o_5tx +vd25o_3rx INT_vd25o_4rx +vd25o_3tx INT_vd25o_4tx +vd25o_4rx INT_vd25o_2rx +vd25o_4tx INT_vd25o_2tx +vd25o_5rx INT_vd25o_0rx +vd25o_5tx INT_vd25o_0tx + +vd25p_0rx INT_vd25p_1rx +vd25p_0tx INT_vd25p_1tx +vd25p_1rx INT_vd25p_3rx +vd25p_1tx INT_vd25p_3tx +vd25p_2rx INT_vd25p_5rx +vd25p_2tx INT_vd25p_5tx +vd25p_3rx INT_vd25p_4rx +vd25p_3tx INT_vd25p_4tx +vd25p_4rx INT_vd25p_2rx +vd25p_4tx INT_vd25p_2tx +vd25p_5rx INT_vd25p_0rx +vd25p_5tx INT_vd25p_0tx + +vd33o_0rx INT_vd33o_1rx +vd33o_0tx INT_vd33o_1tx +vd33o_1rx INT_vd33o_3rx +vd33o_1tx INT_vd33o_3tx +vd33o_2rx INT_vd33o_5rx +vd33o_2tx INT_vd33o_5tx +vd33o_3rx INT_vd33o_4rx +vd33o_3tx INT_vd33o_4tx +vd33o_4rx INT_vd33o_2rx +vd33o_4tx INT_vd33o_2tx +vd33o_5rx INT_vd33o_0rx +vd33o_5tx INT_vd33o_0tx +vd33o_Bus INT_vd33o_Bus +vd33o_Misc INT_vd33o_Misc + +vd33p_0rx INT_vd33p_1rx +vd33p_0tx INT_vd33p_1tx +vd33p_1rx INT_vd33p_3rx +vd33p_1tx INT_vd33p_3tx +vd33p_2rx INT_vd33p_5rx +vd33p_2tx INT_vd33p_5tx +vd33p_3rx INT_vd33p_4rx +vd33p_3tx INT_vd33p_4tx +vd33p_4rx INT_vd33p_2rx +vd33p_4tx INT_vd33p_2tx +vd33p_5rx INT_vd33p_0rx +vd33p_5tx INT_vd33p_0tx +vd33p_Bus INT_vd33p_Bus +vd33p_Misc INT_vd33p_Misc + +vref_0rx INT_vref_1rx +vref_0tx INT_vref_1tx +vref_1rx INT_vref_3rx +vref_1tx INT_vref_3tx +vref_2rx INT_vref_5rx +vref_2tx INT_vref_5tx +vref_3rx INT_vref_4rx +vref_3tx INT_vref_4tx +vref_4rx INT_vref_2rx +vref_4tx INT_vref_2tx +vref_5rx INT_vref_0rx +vref_5tx INT_vref_0tx + +SGND INT_SGND +VGG INT_VGG + + +; Deals with Connectivitiy +; ======================== + +tn_SOSC_TEST_IO[0] CORE_VDD +tn_SOSC_TEST_IO[1] CORE_VDD +tn_SOSC_TEST_IO[2] CORE_VDD +tn_SOSC_TEST_IO[3] CORE_VDD +tn_SOSC_TEST_IO[4] CORE_VDD + +oe_SOSC_TEST_IO[0] CORE_VDD +oe_SOSC_TEST_IO[1] CORE_VDD +oe_SOSC_TEST_IO[2] CORE_VDD +oe_SOSC_TEST_IO[3] CORE_VDD +oe_SOSC_TEST_IO[4] CORE_VDD + +tn_ASII_E CORE_VDD +tn_ASIO0 CORE_VDD +tn_ASIO1 CORE_VDD +tn_ASIO2 CORE_VDD +tn_SCAN_OUT0 CORE_VDD +tn_SCAN_OUT1 CORE_VDD +tn_SCAN_OUT2 CORE_VDD +tn_SCAN_OUT3 CORE_VDD + +tn_TDO CORE_VDD + +tn_PLL0_LOCK CORE_VDD +tn_PLL1_LOCK CORE_VDD +tn_PLL2_LOCK CORE_VDD +tn_PLL3_LOCK CORE_VDD +tn_PLL4_LOCK CORE_VDD +tn_PLL5_LOCK CORE_VDD + +oe_ASII_E CORE_VDD +oe_ASIO0 CORE_VDD +oe_ASIO1 CORE_VDD +oe_ASIO2 CORE_VDD +oe_SCAN_OUT0 TEST_MODE +oe_SCAN_OUT1 TEST_MODE +oe_SCAN_OUT2 TEST_MODE +oe_SCAN_OUT3 TEST_MODE + +oe_PLL0_LOCK PLL_IO[1].DISABLE_STRAP_N +oe_PLL1_LOCK PLL_IO[3].DISABLE_STRAP_N +oe_PLL2_LOCK PLL_IO[5].DISABLE_STRAP_N +oe_PLL3_LOCK PLL_IO[4].DISABLE_STRAP_N +oe_PLL4_LOCK PLL_IO[2].DISABLE_STRAP_N +oe_PLL5_LOCK PLL_IO[0].DISABLE_STRAP_N + +tn_RX0_RSCLK PLL_IO[1].DISABLE_STRAP_N +tn_RX0_RSTAT[0] PLL_IO[1].DISABLE_STRAP_N +tn_RX0_RSTAT[1] PLL_IO[1].DISABLE_STRAP_N +tn_RX1_RSCLK PLL_IO[3].DISABLE_STRAP_N +tn_RX1_RSTAT[0] PLL_IO[3].DISABLE_STRAP_N +tn_RX1_RSTAT[1] PLL_IO[3].DISABLE_STRAP_N +tn_RX2_RSCLK PLL_IO[5].DISABLE_STRAP_N +tn_RX2_RSTAT[0] PLL_IO[5].DISABLE_STRAP_N +tn_RX2_RSTAT[1] PLL_IO[5].DISABLE_STRAP_N +tn_RX3_RSCLK PLL_IO[4].DISABLE_STRAP_N +tn_RX3_RSTAT[0] PLL_IO[4].DISABLE_STRAP_N +tn_RX3_RSTAT[1] PLL_IO[4].DISABLE_STRAP_N +tn_RX4_RSCLK PLL_IO[2].DISABLE_STRAP_N +tn_RX4_RSTAT[0] PLL_IO[2].DISABLE_STRAP_N +tn_RX4_RSTAT[1] PLL_IO[2].DISABLE_STRAP_N +tn_RX5_RSCLK PLL_IO[0].DISABLE_STRAP_N +tn_RX5_RSTAT[0] PLL_IO[0].DISABLE_STRAP_N +tn_RX5_RSTAT[1] PLL_IO[0].DISABLE_STRAP_N + +tn_DATA[$i] BS_MODE3_N[6] i 0 15 +tn_DTACK_N BS_MODE3_N[6] +tn_INTR_N BS_MODE3_N[6] + +TX0_TDAT[$i].OE BS_MODE3_N[1] i 0 15 +TX0_TDCLK.OE BS_MODE3_N[1] +TX0_TCTL.OE BS_MODE3_N[1] +oe_RX0_RSCLK BS_MODE3_N[1] +oe_RX0_RSTAT[0] BS_MODE3_N[1] +oe_RX0_RSTAT[1] BS_MODE3_N[1] + +TX1_TDAT[$i].OE BS_MODE3_N[3] i 0 15 +TX1_TDCLK.OE BS_MODE3_N[3] +TX1_TCTL.OE BS_MODE3_N[3] +oe_RX1_RSCLK BS_MODE3_N[3] +oe_RX1_RSTAT[0] BS_MODE3_N[3] +oe_RX1_RSTAT[1] BS_MODE3_N[3] + +TX2_TDAT[$i].OE BS_MODE3_N[5] i 0 15 +TX2_TDCLK.OE BS_MODE3_N[5] +TX2_TCTL.OE BS_MODE3_N[5] +oe_RX2_RSCLK BS_MODE3_N[5] +oe_RX2_RSTAT[0] BS_MODE3_N[5] +oe_RX2_RSTAT[1] BS_MODE3_N[5] + +TX3_TDAT[$i].OE BS_MODE3_N[4] i 0 15 +TX3_TDCLK.OE BS_MODE3_N[4] +TX3_TCTL.OE BS_MODE3_N[4] +oe_RX3_RSCLK BS_MODE3_N[4] +oe_RX3_RSTAT[0] BS_MODE3_N[4] +oe_RX3_RSTAT[1] BS_MODE3_N[4] + +TX4_TDAT[$i].OE BS_MODE3_N[2] i 0 15 +TX4_TDCLK.OE BS_MODE3_N[2] +TX4_TCTL.OE BS_MODE3_N[2] +oe_RX4_RSCLK BS_MODE3_N[2] +oe_RX4_RSTAT[0] BS_MODE3_N[2] +oe_RX4_RSTAT[1] BS_MODE3_N[2] + +TX5_TDAT[$i].OE BS_MODE3_N[0] i 0 15 +TX5_TDCLK.OE BS_MODE3_N[0] +TX5_TCTL.OE BS_MODE3_N[0] +oe_RX5_RSCLK BS_MODE3_N[0] +oe_RX5_RSTAT[0] BS_MODE3_N[0] +oe_RX5_RSTAT[1] BS_MODE3_N[0] + +PLL0_CLKOUT2.OE BS_MODE3_N[1] +PLL1_CLKOUT2.OE BS_MODE3_N[3] +PLL2_CLKOUT2.OE BS_MODE3_N[5] +PLL3_CLKOUT2.OE BS_MODE3_N[4] +PLL4_CLKOUT2.OE BS_MODE3_N[2] +PLL5_CLKOUT2.OE BS_MODE3_N[0] + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.map.x6 b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.map.x6 new file mode 100644 index 0000000000..0dcb043441 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/IO.map.x6 @@ -0,0 +1,88 @@ +; PLL IPs 0 to 5 +; ================== +c SPI4_$i i 0 5 +LOCK PLL_IO[$i].LOCK +BYPASS_VCO PLL_IO[$i].BYPASS_VCO +BYPASS_EN PLL_IO[$i].BYPASS_EN +REFCLK PLL_IO[$i].REFCLK +CLKOUT2 PLL_IO[$i].CLKOUT2 +vaa PLL_IO[$i].VAA +ag PLL_IO[$i].AG + +; RX IPs 0 to 5 +; ================== +c SPI4_$i i 0 5 +xi_rctl RXSPI4_IO[$i].xi_rctl +xi_rdclk RXSPI4_IO[$i].xi_rdclk +xi_rdat[$j] RXSPI4_IO[$i].xi_rdat[$j] j 0 15 +xo_rsclk RXSPI4_IO[$i].xo_rsclk +xo_rstat[$j] RXSPI4_IO[$i].xo_rstat[$j] j 0 1 + +; TX IPs 0 to 5 +; ================== +c SPI4_$i i 0 5 +n_xo_tctl TXSPI4_IO[$i].xo_tctl +n_xo_tdclk TXSPI4_IO[$i].xo_tdclk +n_xo_tdat_L_$j_R_ TXSPI4_IO[$i].xo_tdat[$j] j 0 15 +n_xi_tsclk TXSPI4_IO[$i].xi_tsclk +n_xi_tstat_L_$j_R_ TXSPI4_IO[$i].xi_tstat[$j] j 0 1 + +; EBI EXTERNAL BUS INTERFACE +; ========================== +c busif_sync +n_ADDR_L_$j_R_ BUSIF_IO.ADDR[$j] j 1 17 +n_DATA_IN_L_$j_R_ BUSIF_IO.DATA_IN[$j] j 0 15 +n_DATA_OUT_L_$j_R_ BUSIF_IO.DATA_OUT[$j] j 0 15 +n_DATA_OE_L_$j_R_ BUSIF_IO.DATA_OE[$j] j 0 15 +n_CLK_X8BUSIF BUSIF_IO.CLK_X8BUSIF +n_RW_N BUSIF_IO.RW_N +n_AS_N BUSIF_IO.AS_N +n_DS_N BUSIF_IO.DS_N +n_CS_N BUSIF_IO.CS_N +n_DTACK_INV BUSIF_IO.DTACK_INV +n_RW_N_INV BUSIF_IO.RW_N_INV +n_IGNORE_DS_N BUSIF_IO.IGNORE_DS_N +n_SYNC_MODE BUSIF_IO.SYNC_MODE +n_DTACK_N BUSIF_IO.DTACK_N +n_DTACK_OE BUSIF_IO.DTACK_OE +n_INTR_OE BUSIF_IO.INTR_OE + +; PADFRAME +; ======== +c PADFRAME i 0 5 +PLL_IO[$i].BYPASS_EN PLL_IO[$i].BYPASS_EN +PLL_IO[$i].BYPASS_VCO PLL_IO[$i].BYPASS_VCO +PLL_IO[$i].LOCK PLL_IO[$i].LOCK +PLL_IO[$i].REFCLK PLL_IO[$i].REFCLK +PLL_IO[$i].VAA PLL_IO[$i].VAA +PLL_IO[$i].AG PLL_IO[$i].AG +PLL_IO[$i].CLKOUT2 PLL_IO[$i].CLKOUT2 + +RXSPI4_IO[$i].xi_rctl RXSPI4_IO[$i].xi_rctl +RXSPI4_IO[$i].xi_rdat[$j] RXSPI4_IO[$i].xi_rdat[$j] j 0 15 +RXSPI4_IO[$i].xi_rdclk RXSPI4_IO[$i].xi_rdclk +RXSPI4_IO[$i].xo_rsclk RXSPI4_IO[$i].xo_rsclk +RXSPI4_IO[$i].xo_rstat[$j] RXSPI4_IO[$i].xo_rstat[$j] j 0 1 + +TXSPI4_IO[$i].xo_tctl TXSPI4_IO[$i].xo_tctl +TXSPI4_IO[$i].xo_tdclk TXSPI4_IO[$i].xo_tdclk +TXSPI4_IO[$i].xo_tdat[$j] TXSPI4_IO[$i].xo_tdat[$j] j 0 15 +TXSPI4_IO[$i].xi_tsclk TXSPI4_IO[$i].xi_tsclk +TXSPI4_IO[$i].xi_tstat[$j] TXSPI4_IO[$i].xi_tstat[$j] j 0 1 + +BUSIF_IO.ADDR[$j] BUSIF_IO.ADDR[$j] j 1 17 +BUSIF_IO.DATA_IN[$j] BUSIF_IO.DATA_IN[$j] j 0 15 +BUSIF_IO.DATA_OUT[$j] BUSIF_IO.DATA_OUT[$j] j 0 15 +BUSIF_IO.DATA_OE[$j] BUSIF_IO.DATA_OE[$j] j 0 15 +BUSIF_IO.CLK_X8BUSIF BUSIF_IO.CLK_X8BUSIF +BUSIF_IO.RW_N BUSIF_IO.RW_N +BUSIF_IO.AS_N BUSIF_IO.AS_N +BUSIF_IO.DS_N BUSIF_IO.DS_N +BUSIF_IO.CS_N BUSIF_IO.CS_N +BUSIF_IO.DTACK_INV BUSIF_IO.DTACK_INV +BUSIF_IO.RW_N_INV BUSIF_IO.RW_N_INV +BUSIF_IO.IGNORE_DS_N BUSIF_IO.IGNORE_DS_N +BUSIF_IO.SYNC_MODE BUSIF_IO.SYNC_MODE +BUSIF_IO.DTACK_N BUSIF_IO.DTACK_N +BUSIF_IO.DTACK_OE BUSIF_IO.DTACK_OE +BUSIF_IO.INTR_OE BUSIF_IO.INTR_OE diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Floorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Floorplan.il new file mode 100644 index 0000000000..843fbcd555 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Floorplan.il @@ -0,0 +1,31 @@ +; boundp( `M_Floorplan ) && hiFixedMenuDown( M_Floorplan ) + +M_TR_Floorplanner = hiCreateMenuItem( + ?name `M_TR_Floorplanner + ?itemText "Spider 3.0.5" + ?callback "TR_Floorplanner( )" + ?disable nil + ) + +M_TR_FindInstance = hiCreateMenuItem( + ?name `M_TR_FindInstance + ?itemText "Find" + ?callback "TR_FindInstance( )" + ?disable nil + ) + +M_TR_FloorplanArray = hiCreateMenuItem( + ?name `M_TR_FloorplanArray + ?itemText "Array" + ?callback "TR_FloorplanArray( )" + ?disable nil + ) + +M_Floorplan = hiCreateHorizontalFixedMenu( 'M_Floorplan + list( M_TR_Floorplanner + M_TR_FindInstance + M_TR_FloorplanArray) + 1 + 3 ) + +; hiDisplayFixedMenu( M_Floorplan "top" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Main.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Main.il new file mode 100644 index 0000000000..f88c0ba548 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Main.il @@ -0,0 +1,64 @@ +boundp( `M_Main ) && hiFixedMenuDown( M_Main ) + +;M_Main = hiCreateHorizontalFixedMenu( +; 'M_Main +; list( M_TR_NormalLVS +; M_TR_FullVirtualLVS +; M_TR_PartialVirtualLVS +; M_TR_InteractiveVirtualLVS +; M_TR_Floorplanner +; M_TR_FindInstance +; M_TR_FloorplanArray ) +; 2 +; 4 ) + +M_TR_CrawFish = hiCreateMenuItem( + ?name `M_TR_CrawFish + ?itemText "CrawFish" + ?callback "hiDisplayFixedMenu( M_CrawFish \"top\" )" + ?disable nil + ) + +M_TR_CrawFishVLVS = hiCreateMenuItem( + ?name `M_TR_CrawFishVLVS + ?itemText "CFish-VLVS" + ?callback "TR_AssuraLVS( )" + ?disable nil + ) + +M_TR_CrawFishPathFinder = hiCreateMenuItem( + ?name `M_TR_CrawFishPathFinder + ?itemText "CFish-PathFinder" + ?callback "TR_PathFinder( )" + ?disable nil + ) + +M_TR_Spider = hiCreateMenuItem( + ?name `M_TR_Spider + ?itemText "Spider" + ?callback "TR_Floorplanner" + ?disable nil + ) + +M_Main = hiCreateHorizontalFixedMenu( + 'M_Main + list( + M_TR_CrawFish + M_TR_Spider + M_TR_FloorplanArray + M_TR_FindInstance + ) + 5 + 1 ) + +M_CrawFish = hiCreateHorizontalFixedMenu( + 'M_CrawFish + list( + M_TR_CrawFishVLVS + M_TR_CrawFishPathFinder + ) + 3 + 1 ) + + +hiDisplayFixedMenu( M_Main "top" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Verify.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Verify.il new file mode 100644 index 0000000000..c14bddd21b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/M_Verify.il @@ -0,0 +1,49 @@ +; boundp( `M_Verify ) && hiFixedMenuDown( M_Verify ) + +M_TR_NormalLVS = hiCreateMenuItem( + ?name `M_TR_NormalLVS + ?itemText "Normal LVS" + ?callback "AssuraLVS( ?runVirtual nil + ?runBlackBox nil + ?runPartialVirtual nil)" + ?disable nil + ) + +M_TR_FullVirtualLVS = hiCreateMenuItem( + ?name `M_TR_FullVirtualLVS + ?itemText "Full Virtual LVS" + ?callback "AssuraLVS( ?runVirtual t + ?runBlackBox nil + ?runPartialVirtual nil)" + ?disable nil + ) + +M_TR_PartialVirtualLVS = hiCreateMenuItem( + ?name `M_TR_PartialVirtualLVS + ?itemText "Partial Virtual LVS" + ?callback "AssuraLVS( ?runVirtual t + ?runBlackBox nil + ?runPartialVirtual t)" + ?disable nil + ) + +M_TR_InteractiveVirtualLVS = hiCreateMenuItem( + ?name `M_TR_InteractiveVirtualLVS + ?itemText "Interactive VLVS + Setup" + ?callback "TR_AssuraLVS( )" + ?disable nil + ) + + +M_Verify = hiCreateHorizontalFixedMenu( + 'M_Verify + list( M_TR_NormalLVS + M_TR_FullVirtualLVS + M_TR_PartialVirtualLVS + M_TR_InteractiveVirtualLVS + M_TR_Floorplanner + M_TR_FindInstance) + 2 + 4 ) + +; hiDisplayFixedMenu( M_Verify "top" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ManageWindows.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ManageWindows.il new file mode 100644 index 0000000000..cb303e50c6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ManageWindows.il @@ -0,0 +1,35 @@ +; This Fuction is resize the window +procedure( ResizeWindow( style ) + + if( style == "max" + then + XYmin = 0:0 + XYmax = hiGetMaxScreenCoords() + ) + + if( style == "half" + then + XYmin = ( floor( car( hiGetMaxScreenCoords()) * 0.25 ):floor( car( cdr( hiGetMaxScreenCoords( ))) * 0.25 )) + XYmax = ( floor( car( hiGetMaxScreenCoords()) * 0.75 ):floor( car( cdr( hiGetMaxScreenCoords( ))) * 0.75 )) + + println( XYmin ) + println( XYmax ) + ) + + hiResizeWindow( geGetCellViewWindow( geGetWindowCellView( ) ) list(XYmin XYmax)) + +) ;procedure + + +procedure( IconifyWindow( ) + + hiIconifyWindow( geGetCellViewWindow( geGetWindowCellView( ) ) ) + +) ;procedure + + +procedure( DeiconifyWindow( ) + + hiDeiconifyWindow( geGetCellViewWindow( geGetWindowCellView( ) ) ) + +) ;procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MapConnectivity.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MapConnectivity.il new file mode 100644 index 0000000000..ee0ee6c521 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MapConnectivity.il @@ -0,0 +1,91 @@ +procedure( MapConnectivity( @key + ( Filename "/home/user/samson/myskill/IO.map.x6" ) + ( WarningOn t ) + ) + let(( inPort Arg1 Arg2 l_Arg nextLine + NetParent + NetChild + NetID + CurrentCell + l_d_Cell Cell + ) + + inPort = infile( Filename ) + CurrentCell = nil + + geSelectAllFig( ) + l_d_Cell = geGetSelectedSet( ) + geDeselectAllFig( ) + + + when( inPort + + while( inPort && gets( IOEntry inPort ) + + ; Filter out for Comment Line + rexCompile( "^;" ) + + if( parseString( IOEntry ) && !rexExecute( IOEntry ) + then + IOEntryList = parseString( IOEntry ) + + Arg0 = nth( 0 IOEntryList ) + Arg1 = nth( 1 IOEntryList ) + Arg2 = nth( 2 IOEntryList ) + Arg3 = nth( 3 IOEntryList ) + Arg4 = nth( 4 IOEntryList ) + + if( Arg2 + then + LoopConstruct = Arg2 + LoopStart = evalstring( Arg3 ) + LoopEnd = evalstring( Arg4 ) + else + LoopConstruct = "$$" + LoopStart = -1 + LoopEnd = -1 + ); end if + + + if( Arg0 == "c" + then + TargetCell = Arg1 + LoopConstructCell = LoopConstruct + LoopStartCell = LoopStart + LoopEndCell = LoopEnd + else + + for( i LoopStartCell LoopEndCell + + rexCompile( sprintf( nil "\\$%s" LoopConstructCell )) + CurrentCell = rexReplace( TargetCell sprintf( nil "%n" i ) 0 ) + + foreach( Cell l_d_Cell + if( Cell->name == CurrentCell + then + for( j LoopStart LoopEnd + rexCompile( sprintf( nil "\\$%s" LoopConstructCell )) + NetParent = rexReplace( Arg0 sprintf( nil "%n" i ) 0 ) + NetChild = rexReplace( Arg1 sprintf( nil "%n" i ) 0 ) + + rexCompile( sprintf( nil "\\$%s" LoopConstruct )) + NetParent = rexReplace( NetParent sprintf( nil "%n" j ) 0 ) + NetChild = rexReplace( NetChild sprintf( nil "%n" j ) 0 ) + NetID = dbMakeNet( geGetWindowCellView() NetChild ) + dbCreateConnByName( NetID Cell NetParent ) + ); end for + ); end if + ); end foreach + ); end for + ); end if + );end if + + + ); end while + );end when + + close( inPort ) + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MoveToSnap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MoveToSnap.il new file mode 100644 index 0000000000..01424db7a4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/MoveToSnap.il @@ -0,0 +1,169 @@ +; This Fuction snaps the selected objext to the closest neighbor instance only + + +procedure( MoveToSnap( direction ) + let( (SelectedCellList x_low_org y_low_org x_high_org y_high_org + x_low y_low x_high y_high d_closestNeighbor) + + ; sort selected cells so that they move in order of closest first + SelectedCellList = sort( geGetSelSet( ) + lambda((cell1 cell2) + case( direction + ("L" leftEdge(cell1~>bBox)bBox)) + ("R" rightEdge(cell1~>bBox)>rightEdge(cell2~>bBox)) + ("T" topEdge(cell1~>bBox)>topEdge(cell2~>bBox)) + ("B" bottomEdge(cell1~>bBox)bBox)) + ) + ) + ) + + foreach( SelectedCell SelectedCellList + (if (IsInstanceAnchored SelectedCell) then + (printf "Not moving anchored instance %s.\n" SelectedCell->name) + else ;do the rest + + x_low_org = car( car( SelectedCell->bBox ) ) + y_low_org = car( cdr( car( SelectedCell->bBox ) ) ) + x_high_org = car( car( cdr( SelectedCell->bBox ) ) ) + y_high_org = car( cdr( car( cdr( SelectedCell->bBox ) ) ) ) + d_closestNeighbor=nil + + if( SelectedCell->objType == "inst" then + ;d_closestNeighbor = dbGetNeighborInstanceNoAbutted( SelectedCell direction ) + ;d_closestNeighbor= car(cadr( dbGetNeighbor( wcv() + ; list(x_low_org+0.005:y_low_org+0.005 + ; x_high_org-0.005:y_high_org-0.005) + ; direction nil 32 ))) + + d_closestNeighbor = (FindClosestNeighborInstance (wcv) direction SelectedCell) + ) ;end if + + if( d_closestNeighbor != nil then + x_low = car( car( d_closestNeighbor->bBox ) ) + y_low = car( cdr( car( d_closestNeighbor->bBox ) ) ) + x_high = car( car( cdr( d_closestNeighbor->bBox ) ) ) + y_high = car( cdr( car( cdr( d_closestNeighbor->bBox ) ) ) ) + + if( direction == "L" then + xOffset = x_high - x_low_org + yOffset = 0 + ) + if( direction == "R" then + xOffset = x_low - x_high_org + yOffset = 0 + ) + if( direction == "T" then + xOffset = 0 + yOffset = y_low - y_high_org + ) + if( direction == "B" then + xOffset = 0 + yOffset = y_high - y_low_org + ) + dbMoveFig( SelectedCell wcv() list(xOffset:yOffset "R0")) + ) ;end if + ) + ) ;foreach + d_closestNeighbor + ) +) ;procedure + + +; Re-implement dbGetNeighbor that works for instances. Silly Cadence! +(defun FindClosestNeighborInstance (CV direction inst) + (let (bbox d_closestNeighbor x x0 y0 x1 y1 search_bbox overlaps distance + distance_L distance_R distance_T distance_B best_inst best_distance) + bbox = inst->bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + (cond (direction=="L" x1=x0 x0=(car (car CV->bBox))) + (direction=="R" x0=x1 x1=(car (cadr CV->bBox))) + (direction=="B" y1=y0 y0=(cadr (car CV->bBox))) + (direction=="T" y0=y1 y1=(cadr (cadr CV->bBox))) + ) + search_bbox = (list x0+MfgGrid:y0+MfgGrid x1-MfgGrid:y1-MfgGrid) + overlaps = (dbGetOverlaps CV search_bbox) + best_distance = nil + best_inst = nil + (foreach b (setof a overlaps a->objType=="inst" && a!=inst) + distance_L = x1 - (car (cadr b->bBox)) + distance_R = (car (car b->bBox)) - x0 + distance_B = y1 - (cadr (cadr b->bBox)) + distance_T = (cadr (car b->bBox)) - y0 + (cond (direction=="L" distance=distance_L) + (direction=="R" distance=distance_R) + (direction=="B" distance=distance_B) + (direction=="T" distance=distance_T) + ) + (when distance>=0 && (!best_distance || distancebBox ) ) + y_low_org = car( cdr( car( d_SelectedCell->bBox ) ) ) + x_high_org = car( car( cdr( d_SelectedCell->bBox ) ) ) + y_high_org = car( cdr( car( cdr( d_SelectedCell->bBox ) ) ) ) + + x_low = car( car( d_closestNeighbor->bBox ) ) + y_low = car( cdr( car( d_closestNeighbor->bBox ) ) ) + x_high = car( car( cdr( d_closestNeighbor->bBox ) ) ) + y_high = car( cdr( car( cdr( d_closestNeighbor->bBox ) ) ) ) + + if( d_closestNeighbor != nil && + d_closestNeighbor->master == d_SelectedCell->master + + then + if( direction == "L" || direction == "R" + + then + xOffset = x_low - x_low_org + yOffset = y_low - y_high_org + + ) ; end if + + if( direction == "T" || direction == "B" + + then + xOffset = x_low - x_low_org + yOffset = y_low - y_low_org + dbMoveFig( d_closestNeighbor, nil, list(0:-yOffset "R0")) + + ) ; end if + + dbMoveFig( d_SelectedCell, nil, list(xOffset:yOffset "R0")) + + ) ;end if + + else + println( "Error! You have selected more than ONE cell") + + ) ;end if + + ; Return Value + d_closestNeighbor + +) ;procedure + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/PathFinder.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/PathFinder.il new file mode 100644 index 0000000000..bc65771547 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/PathFinder.il @@ -0,0 +1,724 @@ +; Global Variables +; ================ +PathFinder_GlobalRectList = nil + + + +procedure( PathFinder( @key + ( layer "METAL2") + ( purpose "drawing" ) + ( direction "vertical") + ( width 0.24 ) + ( spacing 0.24 ) + ( viaSpacing 0.215 ) + ( searchDepth 32 ) + ( resolution 0 ) + ( onPowerGrid nil ) + ( bBox geGetWindowCellView( )->bBox ) + ( numTracks 0 ) + ( inverse nil ) + ( exceptionList nil ) + ( DebugOn t ) + ) + + let(( x_low x_high x_start x_end xDirectionFactor + y_low y_high y_start y_end yDirectionFactor + bBox_current + isFinish + AnyOverlaps AnyOverlapsTmp + returnValue + layoutResolution + DeltaError + Counter + Track_bBox + l_ContactCells + ) + + ; Local Variables + ; =============== + DeltaError = 0.001 + isFinish = nil + returnValue = nil + layoutResolution = 0.01 + Counter = 0 + Track_bBox = nil + l_ContactCells = list( "M8_M7" "M7_M6" "M6_M5" "M5_M4" "M4_M3" "M3_M2" "M2_M1" + "M8_M7_min" "M7_M6_min" "M6_M5_min" "M5_M4_min" "M4_M3_min" "M3_M2_min" "M2_M1_min" + ) + + + case( direction + ( "vertical" + if( !inverse + then + xDirectionFactor = 1 + yDirectionFactor = 0 + else + xDirectionFactor = -1 + yDirectionFactor = 0 + ) + ) + ( "horizontal" + if( !inverse + then + xDirectionFactor = 0 + yDirectionFactor = 1 + else + xDirectionFactor = 0 + yDirectionFactor = -1 + ) + + ) + ( t + xDirectionFactor = 0 + yDirectionFactor = 0 + isFinish = t + printf( "PathFinder --> FATAL ERROR!!! is NOT an acceptable input\n" direction ) + ) + ); end case + + ;============================================================================================ + + x_start = round( float( caar( bBox )) / layoutResolution ) * layoutResolution + x_end = round( float( caadr( bBox )) / layoutResolution ) * layoutResolution + + y_start = round( float( cadar( bBox )) / layoutResolution ) * layoutResolution + y_end = round( float( cadadr( bBox )) / layoutResolution ) * layoutResolution + + ;============================================================================================ + + if( !inverse + then + x_low = x_start + DeltaError + y_low = y_start + DeltaError + + x_high = xDirectionFactor * ( x_start + width + spacing * 2 ) + yDirectionFactor * x_end - DeltaError + y_high = yDirectionFactor * ( y_start + width + spacing * 2 ) + xDirectionFactor * y_end - DeltaError + else + x_low = -xDirectionFactor * ( x_start + DeltaError ) - yDirectionFactor * ( x_end - width - spacing * 2 ) - DeltaError + y_low = -yDirectionFactor * ( y_start + DeltaError ) - xDirectionFactor * ( y_end - width - spacing * 2 ) - DeltaError + + x_low = ( -yDirectionFactor * ( x_start + DeltaError ) ) - ( xDirectionFactor * ( x_end - width - spacing * 2 ) - DeltaError ) + y_low = ( -xDirectionFactor * ( y_start + DeltaError ) ) - ( yDirectionFactor * ( y_end - width - spacing * 2 ) - DeltaError ) + + x_high = x_end - DeltaError + y_high = y_end - DeltaError + ) + + bBox_current = list( x_low:y_low x_high:y_high ) + + + + ; Check Extreme Cases + if( !inverse && ( x_high > x_end || y_high > y_end ) + then + isFinish = t + ) + + if( inverse && ( x_low < x_start || y_low < y_start ) + then + isFinish = t + ) + + + + + + + + + + + + ; Auto-resolution setup + if( resolution == 0 + then + resolution = ( abs( xDirectionFactor ) * abs( x_end - x_start ) + abs( yDirectionFactor ) * abs( y_end - y_start ) )/ 500 + + resolution = round( float( resolution ) / layoutResolution ) * layoutResolution + + if( resolution == 0 + then + resolution = 0.01 + ) + + resolution = min( width + spacing * 2 resolution ) + + DebugOn && printf( "PathFinder --> Resolution is automatically set to %num\n" resolution ) + else + DebugOn && printf( "PathFinder --> Resolution is set to input value %num\n" resolution ) + ) + + CreateRectangleHilite( layer purpose geGetWindowCellView( ) ) + + while( !isFinish + + if( onPowerGrid + then + case( layer + ( "METAL3" + if( direction == "horizontal" && ( floor( y_low /4.8 ) - floor( y_high / 4.8 )) !=0 + then + if( !inverse + then + y_low = ( ceiling( y_low /4.8 ) * 4.8 ) + 0.36 + DeltaError + else + y_low = ( ceiling( y_low /4.8 ) * 4.8 ) - 0.36 - width - 2 * spacing + DeltaError + ); end if + + y_high = y_low + width + 2 * spacing - 2 * DeltaError + bBox_current = list( x_low:y_low x_high:y_high ) + + ); end if + ) + + ( "METAL5" + if( direction == "horizontal" && ( floor( y_low /4.8 ) - floor( y_high / 4.8 )) !=0 + then + if( !inverse + then + y_low = ( ceiling( y_low /4.8 ) * 4.8 ) + 0.36 + DeltaError + else + y_low = ( ceiling( y_low /4.8 ) * 4.8 ) - 0.36 - width - 2 * spacing + DeltaError + ); end if + + y_high = y_low + width + 2 * spacing - 2 * DeltaError + bBox_current = list( x_low:y_low x_high:y_high ) + + ); end if + ) + + ( "METAL7" + if( direction == "horizontal" && ( floor( y_low /4.8 ) - floor( y_high / 4.8 )) !=0 + then + if( !inverse + then + y_low = ( ceiling( y_low /4.8 ) * 4.8 ) + 0.60 + DeltaError + else + y_low = ( ceiling( y_low /4.8 ) * 4.8 ) - 0.60 - width - 2 * spacing + DeltaError + ); end if + + y_high = y_low + width + 2 * spacing - 2 * DeltaError + bBox_current = list( x_low:y_low x_high:y_high ) + + ); end if + ) + + ( "METAL4" + if( direction == "vertical" && ( floor( x_low /2.4 ) - floor( x_high / 2.4 )) !=0 + then + if( !inverse + then + x_low = ( ceiling( x_low /2.4 ) * 2.4 ) + 0.12 + DeltaError + else + x_low = ( ceiling( x_low /2.4 ) * 2.4 ) - 0.12 - width - 2 * spacing + DeltaError + ); end if + + x_high = x_low + width + 2 * spacing - 2 * DeltaError + bBox_current = list( x_low:y_low x_high:y_high ) + + ); end if + ) + + ( "METAL6" + if( direction == "vertical" && ( floor( x_low /4.8 ) - floor( x_high / 4.8 )) !=0 + then + if( !inverse + then + x_low = ( ceiling( x_low /4.8 ) * 4.8 ) + 0.36 + DeltaError + else + x_low = ( ceiling( x_low /4.8 ) * 4.8 ) - 0.36 - width - 2 * spacing + DeltaError + ); end if + + x_high = x_low + width + 2 * spacing - 2 * DeltaError + bBox_current = list( x_low:y_low x_high:y_high ) + + ); end if + ) + + ); end case + ); end if + + geRefresh( ); + + ; Get the Overlapping objects in a TREE List Structure + ; ==================================================== + AnyOverlaps = dbGetTrueOverlaps( geGetWindowCellView( ) bBox_current list( layer nil ) searchDepth ) + + + + ; This essentially flatten the return list structure + ; ================================================== + for( i 0 32 + AnyOverlapsTmp = nil + + foreach( Cell AnyOverlaps + + if( listp( Cell ) + then + if( !member( car( Cell )->cellName l_ContactCells ) + then + AnyOverlapsTmp = append( AnyOverlapsTmp cdr( Cell )) + else + AnyOverlapsTmp = append( AnyOverlapsTmp list(car( Cell ))) + ); end if + + else + AnyOverlapsTmp = append( AnyOverlapsTmp list( Cell )) + ) + + ); end foreach + + if( AnyOverlaps == AnyOverlapsTmp + then + i = 33 + else + AnyOverlaps = AnyOverlapsTmp + ) + + ); end for + + + ; Check for overlapping objects (filter out ONLY labels) + ; ====================================================== + AnyOverlaps = setof( x AnyOverlaps ( x->objType!="textDisplay" && x->objType!="label" && !member( x exceptionList ))) + + + + ; In case there are overlaps but are caused just by contact cells + ; =============================================================== + if( AnyOverlaps && setof( x AnyOverlaps !member( x->cellName l_ContactCells)) == nil && spacing!=viaSpacing + then + case( direction + ( "vertical" + bBox_temp = list( + list( + caar( bBox_current ) + spacing - viaSpacing + cadar( bBox_current ) + ) + list( + caadr( bBox_current ) - spacing + viaSpacing + cadadr( bBox_current ) + ) + ) + ) + ( "horizontal" + bBox_temp = list( + list( + caar( bBox_current ) + cadar( bBox_current ) + spacing - viaSpacing + ) + list( + caadr( bBox_current ) + cadadr( bBox_current ) - spacing + viaSpacing + ) + ) + ) + ); end case + + AnyOverlaps = dbGetTrueOverlaps( geGetWindowCellView( ) bBox_temp list( layer nil ) searchDepth ) + + ; This essentially flatten the return list structure + ; ================================================== + for( i 0 32 + AnyOverlapsTmp = nil + + foreach( Cell AnyOverlaps + + if( listp( Cell ) + then + if( !member( car( Cell )->cellName l_ContactCells ) + then + AnyOverlapsTmp = append( AnyOverlapsTmp cdr( Cell )) + else + AnyOverlapsTmp = append( AnyOverlapsTmp list(car( Cell ))) + ); end if + + else + AnyOverlapsTmp = append( AnyOverlapsTmp list( Cell )) + ) + + ); end foreach + + if( AnyOverlaps == AnyOverlapsTmp + then + i = 33 + else + AnyOverlaps = AnyOverlapsTmp + ) + + ); end for + + + ; Check for overlapping objects (filter out ONLY labels) + ; ====================================================== + AnyOverlaps = setof( x AnyOverlaps ( x->objType!="textDisplay" && x->objType!="label" && !member( x exceptionList ))) + + + ); end if + + + + + + + + DebugOn && !AnyOverlaps && printf( "PathFinder --> %3n (%s, %s) path found at %L\n" + Counter + 1 + layer + purpose + bBox_current ) + + if( !AnyOverlaps + then + + Counter = Counter + 1 + + if( Counter == numTracks + then + isFinish = t + ); end if + + Track_bBox = list( list( round( ( x_low + abs( xDirectionFactor ) * spacing - DeltaError ) / layoutResolution ) * layoutResolution + round( ( y_low + abs( yDirectionFactor ) * spacing - DeltaError ) / layoutResolution ) * layoutResolution + ) + list( round( ( x_high - abs( xDirectionFactor ) * spacing + DeltaError ) / layoutResolution ) * layoutResolution + round( ( y_high - abs( yDirectionFactor ) * spacing + DeltaError ) / layoutResolution ) * layoutResolution + ) + ) + + DrawRectangleHilite( layer + purpose + Track_bBox + geGetWindowCellView( ) + ) + + x_low = x_low + xDirectionFactor * ( width + spacing ) + x_high = x_high + xDirectionFactor * ( width + spacing ) + y_low = y_low + yDirectionFactor * ( width + spacing ) + y_high = y_high + yDirectionFactor * ( width + spacing ) + + returnValue = cons( Track_bBox returnValue ) + else + x_low = x_low + xDirectionFactor * resolution + x_high = x_high + xDirectionFactor * resolution + y_low = y_low + yDirectionFactor * resolution + y_high = y_high + yDirectionFactor * resolution + + ) + + bBox_current = list( x_low:y_low x_high:y_high ) + + if( !inverse && ( x_high > x_end || y_high > y_end ) + then + isFinish = t + ) + + if( inverse && ( x_low < x_start || y_low < y_start ) + then + isFinish = t + ) + + ); end while + + DebugOn && printf( "PathFinder --> %L\n" reverse( returnValue )) + PathFinder_GlobalRectList = reverse( returnValue ) + + ); end let + +); end procedure + + +; ============================================================================================ +; This procedure is used to create a hilite rectange group and do nothing +; ============================================================================================ + +procedure( CreateRectangleHilite( layer purpose d_CellView ) + + gePushHilightStack( geCreateHilightSet( d_CellView list( layer purpose ) t )) + geGetCurrentHilightSet( geGetWindowCellView())->enable = t +) + + + +; ============================================================================================ +; This procedure is used to draw a hilite rectange using the specified lpp +; ============================================================================================ + +procedure( DrawRectangleHilite( layer purpose l_bBox d_CellView ) + + let(( ArrowPoints + returnValue + ) + + returnValue = t + + if( abs( caadr( l_bBox ) - caar( l_bBox )) > abs( cadadr( l_bBox ) - cadar( l_bBox )) + then + ArrowPoints = list( caar( l_bBox ) - 3 :( cadadr( l_bBox ) - cadar( l_bBox ) )/2 + cadar( l_bBox ) + caar( l_bBox ):( cadadr( l_bBox ) - cadar( l_bBox ) )/2 + cadar( l_bBox ) + caar( l_bBox ) - 0.3: cadadr( l_bBox ) + caar( l_bBox ) - 0.3: cadar( l_bBox ) + caar( l_bBox ):( cadadr( l_bBox ) - cadar( l_bBox ) )/2 + cadar( l_bBox ) + ) + else + ArrowPoints = list( ( caadr( l_bBox ) - caar( l_bBox ) )/2 + caar( l_bBox ):cadar( l_bBox ) - 3 + ( caadr( l_bBox ) - caar( l_bBox ) )/2 + caar( l_bBox ):cadar( l_bBox ) + caadr( l_bBox ):cadar( l_bBox ) - 0.3 + caar( l_bBox ):cadar( l_bBox ) - 0.3 + ( caadr( l_bBox ) - caar( l_bBox ) )/2 + caar( l_bBox ):cadar( l_bBox ) + ) + ) + + + geAddHilightLine( geGetCurrentHilightSet( geGetWindowCellView()) ArrowPoints ) + geAddHilightRectangle( geGetCurrentHilightSet( geGetWindowCellView()) l_bBox ) + returnValue + + ); end let + +); end procedure + + + +; ============================================================================================ +; This is the GUI (User interface) +; ============================================================================================ +procedure( TR_PathFinder( ) + + let(( TR_PathFinder_layerField + TR_PathFinder_purposeField + TR_PathFinder_directionField + TR_PathFinder_widthField + TR_PathFinder_spacingField + TR_PathFinder_searchDepthField + TR_PathFinder_resolutionField + TR_PathFinder_onPowerGridField + TR_PathFinder_currentbBoxField + TR_PathFinder_grabbBoxField + TR_PathFinder_theForm + ) + + TR_PathFinder_layerField = hiCreateCyclicField( + ?name `TR_PathFinder_layerField + ?choices list( "METAL1" "METAL2" "METAL3" "METAL4" "METAL5" "METAL6" ) + ?prompt "Layer" + ?defValue "METAL1" + ?callback "TR_PathFinder_layerField_CB( hiGetCurrentForm() )" + ) + + TR_PathFinder_purposeField = hiCreateCyclicField( + ?name `TR_PathFinder_purposeField + ?choices list( "drawing" ) + ?prompt "Purpose" + ?defValue "drawing" + ?enabled nil + ) + + TR_PathFinder_directionField = hiCreateCyclicField( + ?name `TR_PathFinder_directionField + ?choices list( "horizontal" "vertical" ) + ?prompt "Direction" + ?defValue "horizontal" + ) + + TR_PathFinder_widthField = hiCreateFloatField( + ?name `TR_PathFinder_widthField + ?prompt "Width (um)" + ?defValue 0.24 + ) + + TR_PathFinder_numTracksField = hiCreateIntField( + ?name `TR_PathFinder_numTracksField + ?prompt "NumTracks" + ?defValue 0 + ) + + TR_PathFinder_spacingField = hiCreateFloatField( + ?name `TR_PathFinder_spacingField + ?prompt "Wire Spacing" + ?defValue 0.24 + ) + + TR_PathFinder_viaSpacingField = hiCreateFloatField( + ?name `TR_PathFinder_viaSpacingField + ?prompt "Via Spacing" + ?defValue 0.215 + ) + + + TR_PathFinder_searchDepthField = hiCreateIntField( + ?name `TR_PathFinder_searchDepthField + ?prompt "Search Dep" + ?defValue 32 + ?enabled nil + ?callback "TR_PathFinder_searchDepthField_CB( hiGetCurrentForm() )" + ) + + TR_PathFinder_resolutionField = hiCreateFloatField( + ?name `TR_PathFinder_resolutionField + ?prompt "Res (um)" + ?defValue nil + ?enabled t + ) + + TR_PathFinder_onPowerGridField = hiCreateToggleField( + ?name `TR_PathFinder_onPowerGridField + ?choices list( list( `onPowerGrid "Flush-to-Grid" )) + ?defValue list( nil ) + ?enabled t + ) + + TR_PathFinder_currentbBoxField = hiCreateListField( + ?name `TR_PathFinder_currentbBoxField + ?prompt "Area" + ?defValue geGetWindowCellView()->bBox + ?enabled t + ?callback "TR_PathFinder_currentbBoxField_CB( hiGetCurrentForm() )" + ) + + TR_PathFinder_grabbBoxField = hiCreateButton( + ?name `TR_PathFinder_grabbBoxField + ?buttonText "Custom Window" + ?enabled t + ?callback "TR_PathFinder_grabbBoxField_CB( hiGetCurrentForm() )" + ) + + TR_PathFinder_theForm = hiCreateAppForm( + ?name `TR_PathFinder_theForm + ?initialSize list( 1000 1500 ) + ?fields list( list( TR_PathFinder_layerField 0:0 200:30 80 ) + list( TR_PathFinder_purposeField 200:0 200:30 80 ) + list( TR_PathFinder_directionField 400:0 200:30 80 ) + + list( TR_PathFinder_widthField 0:30 170:30 80 ) + list( TR_PathFinder_numTracksField 200:30 170:30 80 ) + + list( TR_PathFinder_spacingField 0:60 170:30 80 ) + list( TR_PathFinder_viaSpacingField 200:60 170:30 80 ) + + list( TR_PathFinder_searchDepthField 0:90 170:30 80 ) + list( TR_PathFinder_resolutionField 200:90 170:30 80 ) + list( TR_PathFinder_onPowerGridField 400:90 170:30 80 ) + + list( TR_PathFinder_currentbBoxField 0:120 370:30 80 ) + list( TR_PathFinder_grabbBoxField 400:120 170:30 0 ) + + ) + ?callback "PathFinder( ?layer TR_PathFinder_layerField->value + ?purpose TR_PathFinder_purposeField->value + ?direction TR_PathFinder_directionField->value + ?width TR_PathFinder_widthField->value + ?spacing TR_PathFinder_spacingField->value + ?searchDepth TR_PathFinder_searchDepthField->value + ?resolution TR_PathFinder_resolutionField->value + ?onPowerGrid TR_PathFinder_onPowerGridField->onPowerGrid->value + ?bBox TR_PathFinder_currentbBoxField->value + ?numTracks TR_PathFinder_numTracksField->value + )" + ?buttonLayout list( `ApplyCancelDef + list( `CrawFishVersionHistory "TR_CrawFish_VersionHistoryField_CB( )") + list( `ClearHiLites "GlobalHiliteStack_Clear( )" ) + list( `DreamsComeTrue "PathFinder_ProcDreamsComeTrue( + ?layer TR_PathFinder_layerField->value + ?purpose TR_PathFinder_purposeField->value + )" ) + ) + ) + + hiDisplayForm( TR_PathFinder_theForm ) + + ); end let + +); end procedure + + +procedure( TR_PathFinder_layerField_CB( theForm ) + + if( member( theForm->TR_PathFinder_layerField->value list( "METAL1" "METAL3" "METAL5" "METAL7" )) + then + theForm->TR_PathFinder_directionField->value = "horizontal" + else + theForm->TR_PathFinder_directionField->value = "vertical" + ) + +); end procedure + + +procedure( TR_PathFinder_searchDepthField_CB( theForm ) + + if( theForm->TR_PathFinder_searchDepthField->value > 32 || + theForm->TR_PathFinder_searchDepthField->value < 0 + then + theForm->TR_PathFinder_searchDepthField->value = theForm->TR_PathFinder_searchDepthField->lastValue + ) + +); end procedure + +procedure( TR_PathFinder_currentbBoxField_CB( theForm ) + + if( !listp( TR_PathFinder_currentbBoxField->value ) + then + + theForm->TR_PathFinder_currentbBoxField->value = theForm->TR_PathFinder_currentbBoxField->lastValue + + hiDeleteField( theForm + `TR_PathFinder_currentbBoxField + ) + + hiAddField( theForm + list( TR_PathFinder_currentbBoxField 0:120 370:30 80 ) + ) + ) + +); end procedure + +procedure( TR_PathFinder_grabbBoxField_CB( theForm ) + + let(( bBox + ) + theForm->TR_PathFinder_currentbBoxField->value = enterBox( ) + + hiDeleteField( theForm + `TR_PathFinder_currentbBoxField + ) + + hiAddField( theForm + list( TR_PathFinder_currentbBoxField 0:120 370:30 80 ) + ) + ); end let + +); end procedure + + +; ==================================================================== +; This procedure will turn the hilite rectangles into real rectangles +; ==================================================================== +procedure( PathFinder_ProcDreamsComeTrue( @key + ( layer "METAL1" ) + ( purpose "drawing" ) + ) + + let(( RectPair + RectPairList + ) + + ; Local Variable + ; =============== + RectPairList = PathFinder_GlobalRectList + RectPair = nil + + GlobalHiliteStack_Clear( ) + + foreach( RectPair RectPairList + + dbCreateRect( geGetWindowCellView( ) + list( layer purpose ) + RectPair + ) + + ); end foreach + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SelectSameMaster.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SelectSameMaster.il new file mode 100644 index 0000000000..0aec9cea66 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SelectSameMaster.il @@ -0,0 +1,36 @@ +; This Fuction is used to select all the instances in the layout that +; have the same master as the selected cell(s) +procedure( SelectSameMaster( ) + + SelectedCellList = geGetSelectedSet( ) + + geSelectAllFig( ) + + PassedCellList = geGetSelectedSet( ) + + foreach( SelectedCell SelectedCellList + + if( SelectedCell->objType == "inst" + + then + foreach( PassedCell PassedCellList + + if( PassedCell->master != SelectedCell->master + then + geDeselectObject( PassedCell ) + ) ;end if + + ) ;end foreach + + else + + geDeselectObject( SelectedCell ) + ) ;if + + ) ;foreach + + PassedCellList + +) ;procedure + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetDeleteViewLevels.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetDeleteViewLevels.il new file mode 100644 index 0000000000..9340509c64 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetDeleteViewLevels.il @@ -0,0 +1,38 @@ +; This Fuction is used to set the view levels of selected instances +procedure( SetViewLevels( fromLevel toLevel ) + + SelectedCellList = geGetSelSet( ) + SelectedCellList = setof( x SelectedCellList member( x->objType list( "inst" "mosaic" ))) + + foreach( SelectedCell SelectedCellList + + geSetInstViewLevel( + geGetCellViewWindow( geGetWindowCellView( ) ) + SelectedCell + fromLevel + toLevel + ) + + ) ;foreach + + +) ;procedure + + +procedure( DeleteViewLevels( ) + + SelectedCellList = geGetSelSet( ) + SelectedCellList = setof( x SelectedCellList member( x->objType list( "inst" "mosaic" ))) + + foreach( SelectedCell SelectedCellList + + geDeleteInstViewLevel( + geGetCellViewWindow( geGetWindowCellView( ) ) + SelectedCell + ) + + ) ;foreach + + +) ;procedure + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetSnapping.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetSnapping.il new file mode 100644 index 0000000000..1c4b2a7830 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/SetSnapping.il @@ -0,0 +1,74 @@ +procedure( SetSnapping( @key + ( xSnap 0.01 ) + ( ySnap 0.01 ) + ( DebugOn nil ) + ) + + let(( outPort + outFilename + outFilenameHash + tempdir + ) + + ; Local Variables + ; =============== + tempdir = ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + outFilename = sprintf( nil "%s/SetSnapping.replayFile" tempdir ) + outPort = outfile( outFilename ) + + ; Dealing with Special Characters in the Filename + ; =============================================== + rexCompile( "\\." ) + outFilenameHash = rexReplace( outFilename "\\\\." 0 ) + rexCompile( "\\/" ) + outFilenameHash = rexReplace( outFilenameHash "\\\\/" 0 ) + + ; Delete Previous File + ; ==================== + sh( sprintf( nil "rm -rf $s" outFilenameHash )) + + ; Create Replay File + ; ================== + fprintf( outPort "leHiEditDisplayOptions()\n" ) + fprintf( outPort "leDisplayOptionsForm->xSnap->value = %n\n" xSnap ) + fprintf( outPort "leDisplayOptionsForm->ySnap->value = %n\n" ySnap ) + fprintf( outPort "hiFormDone(leDisplayOptionsForm)\n" ) + + close( outPort ) + + ; Execute the Replay File + ; ======================= + hiReplayFile( outFilename ) + + ; Delete Replay File + ; ==================== + sh( sprintf( nil "rm -rf $s" outFilenameHash )) + + ); end let + +); end procedure + + + + +procedure( InitCycleSnap() + CycleSnap = 0 +) +InitCycleSnap() + +procedure( CycleSnapGrids() + when( mod(CycleSnap 4)==0 + SetSnapping( ?xSnap MfgGrid ?ySnap MfgGrid ) + ) + when( mod(CycleSnap 4)==1 + SetSnapping( ?xSnap DefaultWiringPitch/2 ?ySnap DefaultWiringPitch/2 ) + ) + when( mod(CycleSnap 4)==2 + SetSnapping( ?xSnap TrackPitch/2 ?ySnap TrackPitch/2 ) + ) + when( mod(CycleSnap 4)==3 + SetSnapping( ?xSnap GridPitch ?ySnap GridPitch ) + ) + CycleSnap = CycleSnap+1 +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ShowName.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ShowName.il new file mode 100644 index 0000000000..730c605294 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/ShowName.il @@ -0,0 +1,50 @@ +procedure( ShowNameInstance( ) + + sh( "rm -f temp.bk" ) + sh( "echo \"leHiEditDisplayOptions()\" > temp.bk" ) + sh( "echo \"leDisplayOptionsForm->instName->value = \\\"instance\\\"\" >> temp.bk" ) + sh( "echo \"hiFormDone(leDisplayOptionsForm)\" >> temp.bk" ) + hiReplayFile( "temp.bk" ) + +); end procedure + +procedure( ShowNameMaster( ) + + sh( "rm -f temp.bk" ) + sh( "echo \"leHiEditDisplayOptions()\" > temp.bk" ) + sh( "echo \"leDisplayOptionsForm->instName->value = \\\"master\\\"\" >> temp.bk" ) + sh( "echo \"hiFormDone(leDisplayOptionsForm)\" >> temp.bk" ) + hiReplayFile( "temp.bk" ) + +); end procedure + + + +(defun InitNameToggle () + ShowNameToggle=0 +) +(InitNameToggle) + + +(defun ToggleNameDisplay () + (let (tempdir filename file) + tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + filename = (sprintf nil "%s/showname.replay" tempdir) + file = (outfile filename) + + ShowNameToggle=ShowNameToggle+1 + + (fprintf file "leHiEditDisplayOptions()\n") + (if (mod ShowNameToggle 2)==0 then + (fprintf file "leDisplayOptionsForm->instName->value = \"instance\"\n") + else + (fprintf file "leDisplayOptionsForm->instName->value = \"master\"\n") + ) + (fprintf file "hiFormDone(leDisplayOptionsForm)\n") + + (close file) + + (hiReplayFile filename) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/StandardBindKeys.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/StandardBindKeys.il new file mode 100644 index 0000000000..0864019e3e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/StandardBindKeys.il @@ -0,0 +1,15 @@ +; Cadence Standard +; ================ + +load( prependInstallPath( "/samples/local/leBindKeys.il")) +load( prependInstallPath( "/samples/local/lxBindKeys.il")) +load( prependInstallPath( "/samples/local/schBindKeys.il")) + +load( prependInstallPath( "/etc/sted/stroke.il" )) +load( prependInstallPath( "/etc/sted/defstrokes.il" )) +hiLoadStrokeFile( prependInstallPath( "/etc/sted/def.strokes" ) "Layout") + +; In-house Skill Files +; ==================== +;load "/home/group/cadadmin/technology/archive/TSMC13_micron/cadence_setup/FulcrumSetup.il" + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ChangeInstName.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ChangeInstName.il new file mode 100644 index 0000000000..9f915eec5f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ChangeInstName.il @@ -0,0 +1,67 @@ +procedure( TR_ChangeInstNameProcMainWild( @key + ( l_d_Cell geGetSelectedSet()) + ( newInstName "DumbDumb" ) + ( patternList list( "\\[0\\]\\[1\\]" "\\[0\\]\\[2\\]" )) + ) + let(( d_Cell + sourcePattern sourceName + targetPattern targetName + ) + + d_Cell = nil + sourcePattern = nth( 0 patternList ) + targetPattern = nth( 1 patternList ) + + foreach( d_Cell l_d_Cell + + sourceName = d_Cell->name + + rexCompile( sourcePattern ) + targetName = rexReplace( sourceName targetPattern 0 ) + + d_Cell->name = targetName + + ); end foreach + + ); end let + +); end procedure + +procedure( TR_ChangeInstNameProcMain( @key + ( d_Cell car(geGetSelectedSet())) + ( newInstName "DumbDumb" ) + ) + d_Cell->name = newInstName + +); end procedure + + +procedure( TR_ChangeInstNameProcGUI( ) + + let( ( TR_ChangeInstNameProcGUI + TR_ChangeInstNameProcGUI_newInstNameField + ) + + TR_ChangeInstNameProcGUI_newInstNameField = hiCreateStringField( + ?name 'TR_ChangeInstNameProcGUI_newInstNameField + ?prompt "Enter New Instance Name" + ?defValue car( geGetSelectedSet())->name + ?editable t ) + + TR_ChangeInstNameProcGUI_Form = hiCreateAppForm( + ?name 'TR_ChangeInstNameProcGUI_Form + ?initialSize list( 300 500 ) + ?fields list( + list( TR_ChangeInstNameProcGUI_newInstNameField 0:0 300:30 200 ) + ) + ?callback "TR_ChangeInstNameProcMain( + ?d_Cell car( geGetSelectedSet()) + ?newInstName TR_ChangeInstNameProcGUI_newInstNameField->value + )" + ) + + hiDisplayForm( TR_ChangeInstNameProcGUI_Form ) + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CountNets.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CountNets.il new file mode 100644 index 0000000000..10deffd112 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CountNets.il @@ -0,0 +1,171 @@ +; ========================================================================= +; This procedure is used to count the number of paths with connectivities +; in a layout +; ========================================================================= + +; Global Variables +; ================= +TR_CountNets_GlobalCounter = 0 +TR_CountNets_GlobalPinFile = "./TR_CountNets_GlobalPinFile.txt" + +procedure( TR_CountNets( @key + ( d_CellView nil ) + ( DebugOn t ) + ) + + let(( l_Obj Obj + l_NetName + d_Cell + outPort + ) + + ; Local Variables + ; =============== + l_NetName = nil + d_Cell = geGetWindowCellView( ) + outPort = outfile( TR_CountNets_GlobalPinFile "a" ) + + geSelectAllFig( ) + l_Obj = geGetSelectedSet( ) + geDeselectAllFig( ) + + l_Obj = setof( x l_Obj x->objType=="path" ) + + foreach( Obj l_Obj + + if( Obj->net->name && !member( Obj->net->name l_NetName ) + then + l_NetName = cons( Obj->net->name l_NetName ) + fprintf( outPort "%s\n" Obj->net->name ) + ); end if + + ); end foreach + + close( outPort ) + + ; Return Value + ; ============ + DebugOn && printf( "TR_CountNets -> ====================================================\n" ) + DebugOn && printf( "TR_CountNets -> %s %s %s\n" d_Cell->libName d_Cell->cellName d_Cell->viewName ) + DebugOn && printf( "TR_CountNets -> There are %n unique paths with connectivities\n" length( l_NetName )) + DebugOn && printf( "TR_CountNets -> ====================================================\n" ) + + length( l_NetName ) + + ); end let + +); end procedure + + +; ======================================================================================= +; This is a wrap-around procedure use to parse the entire layout from the top down +; The skil code is setup to recognize only wiring cells with cellName "xxxwiresxxx" +; ======================================================================================= + +procedure( TR_CountNets_ProcDigHierarchy( @key + ( DebugOn t ) + ) + + let(( l_WiringCell WiringCell + ) + + ; Refresh Current Window + ; ====================== + geRefresh( ) + + geSelectAllFig( ) + l_WiringCell = setof( x geGetSelectedSet() + !member( x->libName list( "tsmc13lg" "stack" "gate" )) && x->objType == "inst" ) + geDeselectAllFig( ) + + rexCompile( "wires" ) + l_WiringCell = setof( x l_WiringCell rexExecute( x->cellName )) + + + ; ======================================================================================================= + ; Since the skill code will automatically swap in and swap out the wiring cells in the current window + ; therefore, the "l_WiringCell" should contain the actual dd object instead of the purgeable db objects + ; ======================================================================================================= + l_WiringCell = foreach( mapcar WiringCell l_WiringCell + + ddGetObj( WiringCell->libName WiringCell->cellName WiringCell->viewName ) + + ); end foreach + + + ; Get the Number of Paths with Connectivities on this level + ; ========================================================= + TR_CountNets_GlobalCounter = TR_CountNets( ) + TR_CountNets_GlobalCounter + + foreach( WiringCell l_WiringCell + + DebugOn && printf( "TR_CountNets_ProcDigHierarchy --> Processing ( \"%s\" \"%s\" \"%s\" ) \n" + WiringCell->lib->name + WiringCell->cell->name + WiringCell->name + ) + + geOpen( ?window geGetCellViewWindow( geGetWindowCellView( ) ) + ?lib WiringCell->lib->name + ?cell WiringCell->cell->name + ?view WiringCell->name + ?viewType "maskLayout" + ?mode "r" ) + + TR_CountNets_ProcDigHierarchy( ) + + ); end foreach + + ); end let + +); end procedure + + +; ======================================================================================== +; Main Procedure +; ======================================================================================== + +procedure( TR_CountNets_ProcMain( @key + ( DebugOn t ) + ) + let(( Original_cellName + Original_libName + Original_viewName + ) + + ; Erase Global Pin File + ; ===================== + sh( sprintf( nil "rm -rf %s" TR_CountNets_GlobalPinFile )) + + + ; Initialize Counter + ; ================== + Original_cellName = geGetWindowCellView( )->cellName + Original_libName = geGetWindowCellView( )->libName + Original_viewName = geGetWindowCellView( )->viewName + + ; Global Variables + ; ================= + TR_CountNets_GlobalCounter = 0 + + ; Call the Main Routine + ; ===================== + TR_CountNets_ProcDigHierarchy( ?DebugOn t ) + + printf( "TR_CountNets_ProcMain -> ======================================================================\n" ) + printf( "TR_CountNets_ProcMain -> %s %s %s\n" Original_cellName Original_libName Original_viewName ) + printf( "TR_CountNets_ProcMain -> There are %n unique paths with connectivities for ALL hierarchies \n" TR_CountNets_GlobalCounter ) + printf( "TR_CountNets_ProcMain -> ======================================================================\n" ) + + geOpen( ?window geGetCellViewWindow( geGetWindowCellView( ) ) + ?lib Original_libName + ?cell Original_cellName + ?view Original_viewName + ?viewType "maskLayout" + ?mode "r" ) + + ); end let + + TR_CountNets_GlobalCounter + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CrawFish.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CrawFish.il new file mode 100644 index 0000000000..b138e697d2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_CrawFish.il @@ -0,0 +1,97 @@ +; ==================================================================================================== +; TR_CrawFish_VersionLogField CallBack Function +; ==================================================================================================== +procedure( TR_CrawFish_VersionHistoryField_CB( ) + + let(( TR_CrawFish_VersionHistoryTextField + TR_CrawFish_VersionHistoryTextForm + HistoryText + ) + + HistoryText = + "\n CrawFish 1.1.1 + \n -- Released Oct-15-2003 7:30am + \n -- Added Support for Assura 3.0 and Assura 2.0 + \n -- -- VLVS View Name Support + \n User can now choose what the VLVS View Name + \n he wants it to be (Default = \"layout.VLVS\" + \n -- Misc Fixes and Cleanup + \n -- -- The Virtual Pin Dialog Box now use + \n \"Load File\" and \"Save File\" buttons + \n to eliminate any confusion + \n -- -- The \"NetList Path\" and \"BlackBoxFileName\" + \n options are now disable + \n + \n CrawFish 1.1.0 + \n -- Released Aug-25-2003 12:30pm + \n -- Added Support for Assura 3.0 + \n -- -- \"lvs..state\" File is used + \n to automatically lanuch LVS + \n -- -- VLVS will cause unbound pins on Layout side ONLY + \n since Assura 3.0 flags excess pins as unbounded + \n all virtual pins created by VLVS will be unbounded + \n + \n CrawFish 1.0.4 + \n -- Released Apr-22-2003 04:30pm + \n -- Added \"DramsComeTrue\" switch to PathFinder Module + \n -- Now, you can turn the hiLite into real rectangles!! + \n + \n CrawFish 1.0.3 + \n -- Released Feb-06-2003 11:10am + \n -- Fixed Bug + \n -- Now, Partial Virtual Joined Net should + \n also work on Top-level pins + \n + \n CrawFish 1.0.2 + \n -- Released Jan-27-2003 3:50pm + \n -- Fixed VLVS Module (TR_AssuraLVS.il) + \n -- \"DrawPinsLabels\" is now capable of auto set everything + \n in the LSW window to visible and selectable + \n to bring up pins + \n -- Once script is done, it will automatically + \n restore the original LSW + \n + \n CrawFish 1.0.1 + \n -- Released Jan-27-2003 + \n -- Fixed VLVS Module + \n -- Added support for \"path\" and \"polygon\" + \n -- Program now draw a 0.02 by 0.02 um square + \n pins on top of these object types + \n + \n CrawFish 1.0 + \n -- Released Jan-23-2003 (First Release) + \n -- Added \"viaSpacing\" Option to PathFinder Module + \n -- Added Version History Support + \n -- Added \"ClearHiLites\" Button + \n + \n + \n CrawFish Family (Module List) + \n ============================= + \n Hand Routing and Advanced Verification Tool + \n 1. PathFinder + \n 2. NetLabeller (done but not released) + \n 3. VLVS (Virtual-Blackbox)" + + + TR_CrawFish_VersionHistoryTextField = hiCreateMLTextField( + ?name `TR_CrawFish_VersionHistoryTextField + ?defValue HistoryText + ?editable nil + ?enabled t + ) + + TR_CrawFish_VersionHistoryTextForm = hiCreateAppForm( + ?name 'TR_CrawFish_VersionHistoryTextForm + ?initialSize list( 500 500 ) + ?fields list( + list( TR_CrawFish_VersionHistoryTextField 0:0 500:400 100 ) + ) + ) + + hiDisplayForm( TR_CrawFish_VersionHistoryTextForm ) + + t + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO.il new file mode 100644 index 0000000000..0b4206e86d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO.il @@ -0,0 +1,2397 @@ +; ====================================================== +; This is a procedure used to compile global variables +; ====================================================== +; Project Files (with Global Setup ) +; 1. "TR_DrawIO_Globals_demo.il" +; 2. "TR_DrawIO_Globals_x8.il" + +procedure( DrawIO_ProcCompileGlobals( @key + ( Project "x8" ) + ( DriverPitch 40.0 ) + ( DebugOn t ) + ) + + evalstring( sprintf( nil "DrawIO_ProcCompileGlobals_%s( ?DriverPitch %n )" Project DriverPitch )) + + DebugOn && printf( "=================================================================================\n") + DebugOn && printf( "DrawIO_ProcCompileGlobals --> Compiled Global Variables for Project \"%s\" \n" Project ) + DebugOn && printf( "=================================================================================\n") + +); end procedure + + + +; ======================================================================== +; This procedure is used to read input from file only +; ======================================================================== +procedure( DrawIO_ProcReadInput( @key + ( DebugOn t ) + ( DeepTrace nil ) + ) + + let(( + inPort + IOEntry IOEntryList + IOGroup + IOType + IOName + IOSignalList + + ) + + ; Global Variables + DrawIO_GlobalRawIOList = nil + + ; Local Variables + inPort = infile( DrawIO_GlobalRawIOFile ) + + DebugOn && printf( "DrawIO_ProcReadInput --> Start reading file %s \n" DrawIO_GlobalRawIOFile ) + + when( inPort + + while( gets( IOEntry inPort ) + + ; Filter out for Comment Line + rexCompile( "^;" ) + + if( parseString( IOEntry ) && !rexExecute( IOEntry ) + then + IOEntryList = parseString( IOEntry "\t" ) + + IOGroup= nth( 0 IOEntryList ) + IOType = nth( 1 IOEntryList ) + IOName = nth( 2 IOEntryList ) + IOSignalList = evalstring( nth( 3 IOEntryList )) + + DeepTrace && printf( "DrawIO_ProcReadInput --> Read --> %s %s %s %L \n" IOGroup IOType IOName IOSignalList ) + + DrawIO_GlobalRawIOList = cons( list( IOGroup IOType IOName IOSignalList ) DrawIO_GlobalRawIOList ) + ); end if + + ); end while + + ); end when + + DebugOn && printf( "DrawIO_ProcReadInput --> Finished reading file %s \n" DrawIO_GlobalRawIOFile ) + DebugOn && printf( "DrawIO_ProcReadInput --> ----------------------------------------------------------\n") + DebugOn && printf( "DrawIO_ProcReadInput --> RAW DATA\n" ) + DebugOn && printf( "DrawIO_ProcReadInput --> ----------------------------------------------------------\n") + DebugOn && printf( "DrawIO_ProcReadInput --> Number of Signal Drivers = %n \n" length( setof( x DrawIO_GlobalRawIOList cadr(x)=="S"))) + DebugOn && printf( "DrawIO_ProcReadInput --> Number of IO VDD Drivers = %n \n" length( setof( x DrawIO_GlobalRawIOList cadr(x)=="PRH"))) + DebugOn && printf( "DrawIO_ProcReadInput --> Number of IO GND Drivers = %n \n" length( setof( x DrawIO_GlobalRawIOList cadr(x)=="PRL"))) + DebugOn && printf( "DrawIO_ProcReadInput --> Number of Core VDD Drivers = %n \n" length( setof( x DrawIO_GlobalRawIOList cadr(x)=="PCH"))) + DebugOn && printf( "DrawIO_ProcReadInput --> Number of Core GND Drivers = %n \n" length( setof( x DrawIO_GlobalRawIOList cadr(x)=="PCL"))) + DebugOn && printf( "DrawIO_ProcReadInput --> Number of Dummy Drivers = %n \n" length( setof( x DrawIO_GlobalRawIOList cadr(x)=="D"))) + DebugOn && printf( "DrawIO_ProcReadInput --> ----------------------------------------------------------\n") + + DrawIO_GlobalRawIOList = reverse( DrawIO_GlobalRawIOList ) + + ); end let + +); end procedure + + + + +; ======================================================================== +; This procedure is completely optional. +; ======================================================================== +procedure( DrawIO_ProcPerformAliasing( @key + ( Filename "/home/user/samson/myskill/IO.input.x6.alias" ) + ( DebugOn nil ) + ) + let(( inPort + IOEntry IOEntryList + + MasterName MasterNameList + TargetName TargetNameList + TargetPackageName + + MappingList + + LoopConstruct + LoopStart + LoopEnd + + i j k + + RawIO + ) + + ; Global Variables + ; ================ + DrawIO_GlobalRawIOList + DrawIO_GlobalRawIOList_Alias = nil + DrawIO_GlobalAliasList = nil + + ; Local Variables + ; =============== + inPort = infile( DrawIO_GlobalAliasFile ) + + when( inPort + + while( inPort && gets( IOEntry inPort ) + + ; Filter out for Comment Line + rexCompile( "^;" ) + + if( parseString( IOEntry ) && !rexExecute( IOEntry ) + then + IOEntryList = parseString( IOEntry ) + + case( length( IOEntryList ) + + ; Command Mode + ; ============ + ( 1 + case( nth( 0 IOEntryList ) + ( "BREAK" + DebugOn && printf( "DrawIO_ProcPerformAliasing --> User Break Operation!!!\n" ) + inPort = nil + ) + ( "DEBUG_ON" + DebugOn = t + ) + ( "DEBUG_OFF" + DebugOn = nil + ) + ); end case + + ) + + ; Normal Mode (Two Arguments) + ; =========================== + ( 2 + MasterName = nth( 0 IOEntryList ) + TargetName = nth( 1 IOEntryList ) + TargetPackageName = TargetName + + DebugOn && printf( "DrawIO_ProcPerformAliasing --> %25s ==> %-25s ( %s )\n" + MasterName + TargetName + TargetPackageName + ) + + DrawIO_GlobalAliasList = append( DrawIO_GlobalAliasList list( list( MasterName TargetName TargetPackageName ))) + ) + + ; Normal Mode (Three Arguments) + ; =========================== + ( 3 + MasterName = nth( 0 IOEntryList ) + TargetName = nth( 1 IOEntryList ) + TargetPackageName = nth( 2 IOEntryList ) + + DebugOn && printf( "DrawIO_ProcPerformAliasing --> %25s ==> %-25s ( %s )\n" + MasterName + TargetName + TargetPackageName + ) + + DrawIO_GlobalAliasList = append( DrawIO_GlobalAliasList list( list( MasterName TargetName TargetPackageName ))) + ) + + ; Normal Mode (Five Arguments with Loop) + ; ====================================== + ( 5 + LoopConstruct = nth( 2 IOEntryList ) + LoopStart = evalstring( nth( 3 IOEntryList )) + LoopEnd = evalstring( nth( 4 IOEntryList )) + + for( i LoopStart LoopEnd + + rexCompile( sprintf( nil "\\$%s" LoopConstruct )) + + MasterName = rexReplace( nth( 0 IOEntryList ) sprintf( nil "%n" i ) 0 ) + TargetName = rexReplace( nth( 1 IOEntryList ) sprintf( nil "%n" i ) 0 ) + TargetPackageName = TargetName + + DebugOn && printf( "DrawIO_ProcPerformAliasing --> %25s ==> %-25s ( %s )\n" + MasterName + TargetName + TargetPackageName + ) + + DrawIO_GlobalAliasList = append( DrawIO_GlobalAliasList list( list( MasterName TargetName TargetPackageName ))) + + ); end for + + ) + + ; Normal Mode (Five Arguments with Loop with Aliased Package Name) + ; ================================================================ + ( 6 + LoopConstruct = nth( 2 IOEntryList ) + LoopStart = evalstring( nth( 3 IOEntryList )) + LoopEnd = evalstring( nth( 4 IOEntryList )) + + for( i LoopStart LoopEnd + + rexCompile( sprintf( nil "\\$%s" LoopConstruct )) + + MasterName = rexReplace( nth( 0 IOEntryList ) sprintf( nil "%n" i ) 0 ) + TargetName = rexReplace( nth( 1 IOEntryList ) sprintf( nil "%n" i ) 0 ) + TargetPackageName = rexReplace( nth( 5 IOEntryList ) sprintf( nil "%n" i ) 0 ) + + DebugOn && printf( "DrawIO_ProcPerformAliasing --> %25s ==> %-25s ( %s )\n" + MasterName + TargetName + TargetPackageName + ) + + DrawIO_GlobalAliasList = append( DrawIO_GlobalAliasList list( list( MasterName TargetName TargetPackageName ))) + + ); end for + + ) + + ); end case + + ); end if + + ); end while + + ); end when + + + foreach( RawIO DrawIO_GlobalRawIOList + + MasterNameList = nth( 3 RawIO ) + TargetNameList = nil + + foreach( MasterName MasterNameList + + MappingList = setof( x DrawIO_GlobalAliasList car(x)==MasterName ); + + case( length( MappingList ) + + ; No Alias Defined + ; ================ + ( 0 +; TargetNameList = append( TargetNameList list( MasterName )) + TargetNameList = append( TargetNameList list( list( MasterName MasterName MasterName ))) + ) + + ; One Alias Mapping Found (1-to-1 Map) + ; ==================================== + ( 1 +; TargetNameList = append( TargetNameList cdr( nth( 0 MappingList ))) + TargetNameList = append( TargetNameList list( append( list( MasterName ) cdr( nth( 0 MappingList ))))) + ) + + ; Error Found (1-to-many Map) + ; ==================================== + ( t + printf( "ERROR !!! You are trying to map \"%L\"\n" MappingList ) + printf( "ERROR !!! You can NOT have more than one Alias Names for One Master Name!!! \n" ) + ) + + ); end case + + ); end foreach + + DrawIO_GlobalRawIOList_Alias = append( DrawIO_GlobalRawIOList_Alias + list( list( nth( 0 RawIO ) + nth( 1 RawIO ) + nth( 2 RawIO ) + TargetNameList + )) + ) + + );end foreach + + DrawIO_GlobalRawIOList = DrawIO_GlobalRawIOList_Alias + + ); end let + +); end procedure + + + + + + + + +; ======================================================================== +; This procedure is used to run analysis of the read-in input +; +; Supported Modes +; --------------- +; 1. Normal +; 2. FixCount <== Fill gaps with feeders +; 3. FixPitch <== Fill gaps with power drivers (PRH PRL PCH PCL) +; ======================================================================== +procedure( DrawIO_ProcAnalysisInput( @key + ( Mode "FixCount" ) + ( DebugOn t ) + ) + + let(( MaxNumPadsHorizontal MaxNumPadsVertical MaxNumPadsChip + EffectiveWidth EffectiveHeight + BondPadChipCounter BondPadSideCounter + CurrentOrient + RequiredFeederWidth + RawIO + FixCountAddedFeederList + NumBondPadPerDriver + ExtraWidth + DrawIO_LocalRawIOList + RawIO_Save + ) + + case( Mode + ( "FixCount" + FixCountAddedFeederList = DrawIO_ProcCalculateNewDriverPitch( ) + ) + ); end case + + ; Local Variables + ; =============== + EffectiveWidth = DrawIO_GlobalChipWidth - 2 * DrawIO_GlobalChipOffset + EffectiveHeight = DrawIO_GlobalChipHeight - 2 * DrawIO_GlobalChipOffset + + MaxNumPadsHorizontal = EffectiveWidth / DrawIO_GlobalDriverPitch - 2.0 + MaxNumPadsVertical = EffectiveHeight / DrawIO_GlobalDriverPitch - 2.0 + MaxNumPadsChip = ( floor( MaxNumPadsHorizontal ) + floor( MaxNumPadsVertical )) * 2 + + BondPadChipCounter = 1 + BondPadSideCounter = 1 + CurrentOrient = "horizontal" + RequiredFeederWidth = 0 + + ExtraWidth = 0.0 + DrawIO_LocalRawIOList = DrawIO_GlobalRawIOList + + RawIO_Save = nil + + ; Global Variables + ; ================= + DrawIO_GlobalFullIOList = nil + + + ; Debugging Message + ; ================= + DebugOn && printf( "DrawIO_ProcAnalysisInput --> ----------------------------------------------------------\n") + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Default Driver Pitch = %n \n" DrawIO_GlobalDriverPitch ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Max Number of Bond Pads = %n \n" MaxNumPadsChip ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> ----------------------------------------------------------\n") + DebugOn && DrawIO_PrintStat( ) + + + while( DrawIO_LocalRawIOList != nil + + + RawIO = car( DrawIO_LocalRawIOList ) + DrawIO_LocalRawIOList = cdr( DrawIO_LocalRawIOList ) + + ; Auto Corner Pad Insertion + ; ================================================= + if( BondPadSideCounter == 1 && ExtraWidth == 0 + then + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList list( caar( setof( x DrawIO_GlobalCornerPadList caar( x )==car( RawIO ))))) + ); end if + + + ; Post Corner Pad Auto Feeder Insertion for Horizontal Direction + ; ============================================================== + if( ( CurrentOrient == "horizontal" && BondPadSideCounter == 1 && ExtraWidth == 0) + then + + RequiredFeederWidth = ( MaxNumPadsHorizontal - floor( MaxNumPadsHorizontal ) + 2 ) * DrawIO_GlobalDriverPitch / 2 + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Serving %L\n" RawIO ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Added Extra Feeder %num after Pad Number %n\n" RequiredFeederWidth BondPadChipCounter ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> =====================================================\n") + + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList DrawIO_ProcInsertFeeder( car( RawIO ) RequiredFeederWidth )) + + else + + ; Post Corner Pad Auto Feeder Insertion for Vertical Direction + ; ============================================================ + if( ( CurrentOrient == "vertical" && BondPadSideCounter == 1 && ExtraWidth == 0) + then + + RequiredFeederWidth = ( MaxNumPadsVertical - floor( MaxNumPadsVertical ) + 2 ) * DrawIO_GlobalDriverPitch / 2 + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Serving %L\n" RawIO ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Added Extra Feeder %num after Pad Number %n\n" RequiredFeederWidth BondPadChipCounter ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> =====================================================\n") + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList DrawIO_ProcInsertFeeder( car( RawIO ) RequiredFeederWidth )) + + else + RequiredFeederWidth = 0 + + ); end if + ); end if + + + ; Insert Ring Breaker to break the IO Ring + ; ======================================== + if( car( RawIO ) != car( RawIO_Save ) && RawIO_Save != nil + then + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList list( list( "RingBreaker" "F" "RB3" ))) + ExtraWidth = ExtraWidth + 3 + printf( "DrawIO_ProcAnalysisInput --> Insert Ring Breaker after Pad Number %n : ExtraWidth = %3.3f\n" BondPadChipCounter ExtraWidth ) + ); end if + + RawIO_Save = RawIO + + + ; Process the actual RawIO + ; =============================== + + case( cadr( RawIO ) + + ( "S" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalSignalDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + RequiredFeederWidth = NumBondPadPerDriver * DrawIO_GlobalDriverPitch - + car( nth( 2 car( setof( x DrawIO_GlobalSignalDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO )))))) + + ExtraWidth = ExtraWidth - min( RequiredFeederWidth 0.0 ) + RequiredFeederWidth = max( RequiredFeederWidth 0.0 ) + + ) + + ( "PRH" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerRingHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + + RequiredFeederWidth = NumBondPadPerDriver * DrawIO_GlobalDriverPitch - + car( nth( 2 car( setof( x DrawIO_GlobalPowerRingHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO )))))) + + ExtraWidth = ExtraWidth - min( RequiredFeederWidth 0.0 ) + RequiredFeederWidth = max( RequiredFeederWidth 0.0 ) + ) + + ( "PRL" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerRingLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + + RequiredFeederWidth = NumBondPadPerDriver * DrawIO_GlobalDriverPitch - + car( nth( 2 car( setof( x DrawIO_GlobalPowerRingLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO )))))) + + ExtraWidth = ExtraWidth - min( RequiredFeederWidth 0.0 ) + RequiredFeederWidth = max( RequiredFeederWidth 0.0 ) + ) + + ( "PCH" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerCoreHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + + RequiredFeederWidth = NumBondPadPerDriver * DrawIO_GlobalDriverPitch - + car( nth( 2 car( setof( x DrawIO_GlobalPowerCoreHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO )))))) + + ExtraWidth = ExtraWidth - min( RequiredFeederWidth 0.0 ) + RequiredFeederWidth = max( RequiredFeederWidth 0.0 ) + ) + + ( "PCL" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerCoreLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + + RequiredFeederWidth = NumBondPadPerDriver * DrawIO_GlobalDriverPitch - + car( nth( 2 car( setof( x DrawIO_GlobalPowerCoreLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO )))))) + + ExtraWidth = ExtraWidth - min( RequiredFeederWidth 0.0 ) + RequiredFeederWidth = max( RequiredFeederWidth 0.0 ) + ) + + ( "D" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalDummyDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + ; RequiredFeederWidth = NumBondPadPerDriver * DrawIO_GlobalDriverPitch + ; ExtraWidth = ExtraWidth - min( RequiredFeederWidth 0.0 ) + ; RequiredFeederWidth = max( RequiredFeederWidth 0.0 ) + + RequiredFeederWidth = NumBondPadPerDriver * DrawIO_GlobalDriverPitch - + car( nth( 2 car( setof( x DrawIO_GlobalDummyDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO )))))) + ExtraWidth = ExtraWidth - min( RequiredFeederWidth 0.0 ) + + RequiredFeederWidth = max( RequiredFeederWidth 0.0 ) + + car( nth( 2 car( setof( x DrawIO_GlobalDummyDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO )))))) + +; if( RequiredFeederWidth > 100 +; then +; println( ExtraWidth ) +; ) + + ) + + ); end case + + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList DrawIO_ProcInsertFeeder( car( RawIO ) RequiredFeederWidth / 2 )) + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList list( RawIO )) + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList DrawIO_ProcInsertFeeder( car( RawIO ) RequiredFeederWidth / 2 )) + + + + ; Print Error Message for Unsupported Modes + ; ========================================= + if( ExtraWidth != 0 && Mode == "FixCount" + then + printf( "DrawIO_ProcAnalysisInput --> ERROR!!! \n" ) + printf( "DrawIO_ProcAnalysisInput --> DriverWidth > DriverPitch * NumPads \n") + printf( "DrawIO_ProcAnalysisInput --> -- Unspported for \"FixCount\" \n") + printf( "DrawIO_ProcAnalysisInput --> -- Pls switch to \"Normal\" Mode \n") + ); end if + + + ; Deal with the "ExtraWidth" Buffer for oversized drivers + ; ======================================================== + if( floor( ExtraWidth ) >= DrawIO_GlobalDriverPitch + then + BondPadSideCounter = BondPadSideCounter + 1 + ExtraWidth = ExtraWidth - DrawIO_GlobalDriverPitch + ); end if + + if( ( BondPadSideCounter == floor( MaxNumPadsHorizontal ) - 1 || BondPadSideCounter == floor( MaxNumPadsVertical ) - 1 ) && ExtraWidth != 0 + then + DebugOn && printf( "DrawIO_ProcAnalysisInput --> ExtraWidth = %3.3f : Added %n um feeders!\n" + ExtraWidth + DrawIO_GlobalDriverPitch - ExtraWidth ) + RequiredFeederWidth = DrawIO_GlobalDriverPitch - ExtraWidth + BondPadSideCounter = BondPadSideCounter + 1 + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList DrawIO_ProcInsertFeeder( car( RawIO ) RequiredFeederWidth )) + ExtraWidth = 0.0 + ); end if + + + + ; Pre Corner Pad Auto Feeder Insertion for Horizontal Direction + ; =============================================================== + if( ( CurrentOrient == "horizontal" && BondPadSideCounter == floor( MaxNumPadsHorizontal )) + then + + RequiredFeederWidth = ( MaxNumPadsHorizontal - floor( MaxNumPadsHorizontal ) + 2 ) * DrawIO_GlobalDriverPitch / 2 + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Serving %L\n" RawIO ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Added Extra Feeder %num before Pad Number %n\n" RequiredFeederWidth BondPadChipCounter ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> =====================================================\n") + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList DrawIO_ProcInsertFeeder( car( RawIO ) RequiredFeederWidth )) + + else + + ; Pre Corner Pad Auto Feeder Insertion for Vertical Direction + ; =============================================================== + if( ( CurrentOrient == "vertical" && BondPadSideCounter == floor( MaxNumPadsVertical )) + then + + RequiredFeederWidth = ( MaxNumPadsVertical - floor( MaxNumPadsVertical ) + 2 ) * DrawIO_GlobalDriverPitch / 2 + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Serving %L\n" RawIO ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> Added Extra Feeder %num before Pad Number %n\n" RequiredFeederWidth BondPadChipCounter ) + DebugOn && printf( "DrawIO_ProcAnalysisInput --> =====================================================\n") + DrawIO_GlobalFullIOList = append( DrawIO_GlobalFullIOList DrawIO_ProcInsertFeeder( car( RawIO ) RequiredFeederWidth )) + + else + RequiredFeederWidth = 0 + + ); end if + ); end if + + + ; Continue to seal the IO ring with dummy pads if all signal pads are gone + ; ======================================================================== + if( DrawIO_LocalRawIOList == nil && + !( CurrentOrient == "vertical" + && BondPadSideCounter == floor( MaxNumPadsVertical ) + && BondPadChipCounter > ( floor( MaxNumPadsVertical ) + floor( MaxNumPadsHorizontal ))) + + then + + ; Seal the ring with 1-Driverpitch-Wide Dummy Driver + ; ================================================== + DrawIO_LocalRawIOList = append( DrawIO_LocalRawIOList + list( append( caar( setof( x DrawIO_GlobalDummyDriverList ( caar( x )==car( RawIO ) && nth( 4 x )==1))) + list( nil ) + ) + ) + ) + + ); end if + + + ; Increment Both Pad Counters for Horizontal Direction + ; ====================================================== + if( CurrentOrient == "horizontal" && BondPadSideCounter == floor( MaxNumPadsHorizontal ) + then + CurrentOrient = "vertical" + BondPadSideCounter = 1 + else + + + ; Increment Both Pad Counters for Vertical Direction + ; ====================================================== + if( CurrentOrient == "vertical" && BondPadSideCounter == floor( MaxNumPadsVertical ) + then + CurrentOrient = "horizontal" + BondPadSideCounter = 1 + + else + BondPadSideCounter = BondPadSideCounter + NumBondPadPerDriver + + ); end if + ); end if + + BondPadChipCounter = BondPadChipCounter + NumBondPadPerDriver + + ); end foreach + + + ; Print Error Message if there are more pads than space + ; ===================================================== + if( MaxNumPadsChip < BondPadChipCounter - 1 + then + printf( "DrawIO_ProcAnalysisInput --> ERROR!!! \n" ) + printf( "DrawIO_ProcAnalysisInput --> Too many pads!!! \n" ) + printf( "DrawIO_ProcAnalysisInput --> -- Max Number of Pads Allowed = %n \n" MaxNumPadsChip ) + printf( "DrawIO_ProcAnalysisInput --> -- Current Number of Pads Instantiated = %n \n" BondPadChipCounter - 1 ) + ); end if + + + t + + ); end let + +); end procedure + + + + + +; ======================================================================== +; This procedure is used to insert feeders +; ======================================================================== +procedure( DrawIO_ProcInsertFeeder( IOGroup + RequiredFeederWidth + @key ( DebugOn nil ) + ) + + let(( AvaliableFeederWidthList + CurrentFeederWidth + AvaliableFeederList + CurrentFeeder + NumFeederNeeded + returnValue + DeltaError + ) + + ; Local Variables + ; ================== + + AvaliableFeederList = setof( x DrawIO_GlobalFeederList caar( x )==IOGroup ) + + AvaliableFeederWidthList = foreach( mapcar CurrentFeeder AvaliableFeederList + + car( nth( 2 CurrentFeeder )) + + ); end foreach + + AvaliableFeederWidthList = sort( AvaliableFeederWidthList `greaterp ) + + NumFeederNeeded = 0 + + returnValue = nil + + DeltaError = 0.00001 + + ; Debugging Messages + ; ================== + + DebugOn && printf( "DrawIO_ProcInsertFeeder --> IOGroup = \"%s\" AvaliableFeederWidthList = %L\n" IOGroup AvaliableFeederWidthList ) + + + foreach( CurrentFeederWidth AvaliableFeederWidthList + + RequiredFeederWidth = float( round( RequiredFeederWidth / DeltaError ) * DeltaError) + + NumFeederNeeded = floor( RequiredFeederWidth / float( CurrentFeederWidth ) ) + + RequiredFeederWidth = RequiredFeederWidth - NumFeederNeeded * CurrentFeederWidth + + CurrentFeeder = car( setof( x AvaliableFeederList ( caar( x )==IOGroup && car( nth( 2 x ))==CurrentFeederWidth ))) + + DebugOn && printf( "DrawIO_ProcInsertFeeder --> Add %n Feeder \"%s\"\n" NumFeederNeeded caddar(CurrentFeeder)) + + for( i 0 NumFeederNeeded-1 + + returnValue = cons( car(CurrentFeeder) returnValue ) + + ); end for + + ); end foreach + + DebugOn && printf( "DrawIO_ProcInsertFeeder --> Procedure Done!!! \n" ) + + returnValue + + ); end let + +); end procedure + + + + +; ======================================================================== +; This procedure is used to calculate new driver pitch +; ======================================================================== +procedure( DrawIO_ProcCalculateNewDriverPitch( @key + ( DebugOn t ) + ) + + let(( MaxNumPadsHorizontal MaxNumPadsVertical MaxNumPadsChip + EffectiveWidth EffectiveHeight + Resolution + NumFeederAdded + CurrentNumPadsChip NumBondPadPerDriver + RawIO + ) + + ; Local Variables + Resolution = 0.001 + CurrentNumPadsChip = 0 + + EffectiveWidth = DrawIO_GlobalChipWidth - 2 * DrawIO_GlobalChipOffset + EffectiveHeight = DrawIO_GlobalChipHeight - 2 * DrawIO_GlobalChipOffset + + ; Get a first estimate on the new "DrawIO_GlobalDriverPitch" + ; This estimate is ALWAYS bigger than the actual value ("ceiling") + ; =================================================================== + DrawIO_GlobalDriverPitch = ( 2 * ( EffectiveWidth + EffectiveHeight )) / ( length( DrawIO_GlobalRawIOList ) + 8.0 ) + DrawIO_GlobalDriverPitch = ceiling( DrawIO_GlobalDriverPitch / Resolution ) * Resolution + + MaxNumPadsHorizontal = EffectiveWidth / DrawIO_GlobalDriverPitch - 2.0 + MaxNumPadsVertical = EffectiveHeight / DrawIO_GlobalDriverPitch - 2.0 + MaxNumPadsChip = ( floor( MaxNumPadsHorizontal ) + floor( MaxNumPadsVertical )) * 2 + + + ; Debugging Massages + ; =================== + DebugOn && printf( "========================================================================================================\n" ) + DebugOn && printf( "DrawIO_ProcCalculateNewDriverPitch --> First Estimate \"DrawIO_GlobalDriverPitch\" = %n um\n" DrawIO_GlobalDriverPitch ) + + foreach( RawIO DrawIO_GlobalRawIOList + + case( cadr( RawIO ) + + ( "S" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalSignalDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + ) + + ( "PRH" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerRingHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + ) + + ( "PRL" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerRingLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + ) + + ( "PCH" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerCoreHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + ) + + ( "PCL" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerCoreLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + ) + + ( "D" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalDummyDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + ) + + ); end case + + ; Calculate the total number of pads the chip has currently + ; ========================================================= + CurrentNumPadsChip = CurrentNumPadsChip + NumBondPadPerDriver + + ); end foreach + + + ; Increase Feeder width by "Resolution" um at a time + ; Once feeder width increases, recalcuate the "MaxNumPadsChip" the chip can now hold + ; continue the process only if "MaxNumPadsChip" + ; =================================================================================================== + while( MaxNumPadsChip < CurrentNumPadsChip + + MaxNumPadsHorizontal = EffectiveWidth / DrawIO_GlobalDriverPitch - 2.0 + MaxNumPadsVertical = EffectiveHeight / DrawIO_GlobalDriverPitch - 2.0 + MaxNumPadsChip = ( floor( MaxNumPadsHorizontal ) + floor( MaxNumPadsVertical )) * 2 + + DrawIO_GlobalDriverPitch = DrawIO_GlobalDriverPitch - Resolution + + ); end while + + + + ; Debugging Messages + ; =================== + DebugOn && printf( "DrawIO_ProcCalculateNewDriverPitch --> Final \"DrawIO_GlobalDriverPitch\" = %n um\n" DrawIO_GlobalDriverPitch ) + DebugOn && printf( "========================================================================================================\n" ) + + + ; NumFeederAdded = number of 1-driverpitch-wide dummy drivers needed to be added + ; ============================================================================== + NumFeederAdded = MaxNumPadsChip - CurrentNumPadsChip + + for( i 1 NumFeederAdded + + DrawIO_GlobalRawIOList = append( DrawIO_GlobalRawIOList + list( caar( + setof( x + DrawIO_GlobalDummyDriverList + ( caar( x )==car( nth( length( DrawIO_GlobalRawIOList )-1 DrawIO_GlobalRawIOList )) && nth( 4 x )==1)))) + ) + + + + + ); end for + + t + + ); end let + +); end procedure + + + +; ======================================================================== +; This procedure is used to print stat from DrawIO_GlobalRawIOList +; ======================================================================== +procedure( DrawIO_PrintStat( @key + ( DebugOn t ) + ) + + let(( RawIO + NumBondPadPerDriver + + CounterDriverSignalSinglePad + CounterDriverSignalDoublePad + CounterDriverSignalTriplePad + CounterDriverPRHSinglePad + CounterDriverPRHDoublePad + CounterDriverPRLSinglePad + CounterDriverPCHSinglePad + CounterDriverPCLSinglePad + CounterDriverDummySinglePad + CounterDriver + CounterBondPad + ) + + + ; Local Variables + ; =============== + CounterDriverSignalSinglePad = 0 + CounterDriverSignalDoublePad = 0 + CounterDriverSignalTriplePad = 0 + CounterDriverPRHSinglePad = 0 + CounterDriverPRHDoublePad = 0 + CounterDriverPRLSinglePad = 0 + CounterDriverPCHSinglePad = 0 + CounterDriverPCLSinglePad = 0 + CounterDriverDummySinglePad = 0 + CounterDriver = 0 + CounterBondPad = 0 + + + foreach( RawIO DrawIO_GlobalRawIOList + + case( cadr( RawIO ) + + ( "S" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalSignalDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + case( NumBondPadPerDriver + ( 1 + CounterDriverSignalSinglePad = CounterDriverSignalSinglePad + 1 + ) + ( 2 + CounterDriverSignalDoublePad = CounterDriverSignalDoublePad + 1 + ) + ( 3 + CounterDriverSignalTriplePad = CounterDriverSignalTriplePad + 1 + ) + ); end case + + ) + + ( "PRH" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerRingHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + case( NumBondPadPerDriver + ( 1 + CounterDriverPRHSinglePad = CounterDriverPRHSinglePad + 1 + ) + ( 2 + CounterDriverPRHDoublePad = CounterDriverPRHDoublePad + 1 + ) + ); end case + ) + + ( "PRL" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerRingLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + case( NumBondPadPerDriver + ( 1 + CounterDriverPRLSinglePad = CounterDriverPRLSinglePad + 1 + ) + ); end case + ) + + ( "PCH" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerCoreHighDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + case( NumBondPadPerDriver + ( 1 + CounterDriverPCHSinglePad = CounterDriverPCHSinglePad + 1 + ) + ); end case + ) + + ( "PCL" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalPowerCoreLowDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + case( NumBondPadPerDriver + ( 1 + CounterDriverPCLSinglePad = CounterDriverPCLSinglePad + 1 + ) + ); end case + ) + + ( "D" + NumBondPadPerDriver = nth( 4 car( setof( x DrawIO_GlobalDummyDriverList ( caar( x )==car( RawIO ) && caddar( x )==caddr( RawIO ))))) + case( NumBondPadPerDriver + ( 1 + CounterDriverDummySinglePad = CounterDriverDummySinglePad + 1 + ) + ); end case + ) + + (t + DebugOn && printf( "DrawIO_PrintStat --> UnSupported Input %s!!! \n" cadr( RawIO )) + ) + + ); end case + + CounterDriver = CounterDriver + 1 + CounterBondPad = CounterBondPad + NumBondPadPerDriver + + ); end foreach + + + printf( "DrawIO_PrintStat --> | NumDriver | NumBondPad |\n") + printf( "DrawIO_PrintStat --> --------------------------------------------------------------\n") + printf( "DrawIO_PrintStat --> Signal Drivers (Single-Paded)| %3n | %3n |\n" + CounterDriverSignalSinglePad + CounterDriverSignalSinglePad + ) + printf( "DrawIO_PrintStat --> Signal Drivers (Double-Paded)| %3n | %3n |\n" + CounterDriverSignalDoublePad + CounterDriverSignalDoublePad * 2 + ) + printf( "DrawIO_PrintStat --> Signal Drivers (Triple-Paded)| %3n | %3n |\n" + CounterDriverSignalTriplePad + CounterDriverSignalTriplePad * 3 + ) + printf( "DrawIO_PrintStat --> IOVDD Drivers (Single-Paded) | %3n | %3n |\n" + CounterDriverPRHSinglePad + CounterDriverPRHSinglePad + ) + printf( "DrawIO_PrintStat --> IOVDD Drivers (Double-Paded) | %3n | %3n |\n" + CounterDriverPRHDoublePad + CounterDriverPRHDoublePad * 2 + ) + printf( "DrawIO_PrintStat --> IOVSS Drivers (Single-Paded) | %3n | %3n |\n" + CounterDriverPRLSinglePad + CounterDriverPRLSinglePad + ) + printf( "DrawIO_PrintStat --> CoreVDD Drivers(Single-Paded)| %3n | %3n |\n" + CounterDriverPCHSinglePad + CounterDriverPCHSinglePad + ) + printf( "DrawIO_PrintStat --> CoreVSS Drivers(Single-Paded)| %3n | %3n |\n" + CounterDriverPCLSinglePad + CounterDriverPCLSinglePad + ) + printf( "DrawIO_PrintStat --> Dummy Drivers (Single-Paded) | %3n | %3n |\n" + CounterDriverDummySinglePad + CounterDriverDummySinglePad + ) + printf( "DrawIO_PrintStat --> --------------------------------------------------------------\n") + printf( "DrawIO_PrintStat --> Total | %3n | %3n |\n" + CounterDriver + CounterBondPad + ) + printf( "DrawIO_PrintStat --> --------------------------------------------------------------\n") + + + ); end let + + t + +); end procedure + + + + + + + + + + + + + +; ======================================================================== +; This procedure is used to draw the actial padframe +; ======================================================================== +procedure( DrawIO_ProcDrawIO( @key ( DebugOn nil ) + ) + + let(( CurrentDriverX CurrentDriverY + CounterAllDriver + CounterBondPad + CounterSignalDriver + CounterPowerRingHighDriver + CounterPowerRingLowDriver + CounterPowerCoreHighDriver + CounterPowerCoreLowDriver + CounterFeeder + CounterCornerPad + + FullIO ActualIO + BondPad BondPad_origin BondPadOld BondPad_instName + TEXT_origin TEXT_orient TEXT_just TEXT_size TEXT_gap + PackageIO_origin + d_cellView + t_libName + t_cellName + t_viewName + t_instName + l_origin + t_orient + + NumBondPadPerDriver + NextBondPadOffset + + NetID + NetParent + NetChild + + Filename_Package + Filename_CDL + Filename_CDL_tmp + Filename_Cast + Filename_Cast_tmp + Filename_Spec + Filename_Spec_tmp + Filename_Binding_Rule + + outPort_Package + outPort_CDL + outPort_CDL_tmp + outPort_Cast + outPort_Cast_tmp + outPort_Spec + outPort_Spec_tmp + outPort_Binding_Rule + + l_IOPort IOPort + l_IOType IOType + ExceptList + + PadNameList + PadName + + CastCellName_S + CastCellName_L + + ) + + ; Local Variables + ; ==================== + CurrentDriverX = 0 + CurrentDriverY = 0 + + CounterAllDriver = 0 + CounterBondPad = 0 + CounterSignalDriver = 0 + CounterPowerRingHighDriver = 0 + CounterPowerRingLowDriver = 0 + CounterPowerCoreHighDriver = 0 + CounterPowerCoreLowDriver = 0 + CounterFeeder = 0 + CounterCornerPad = 0 + + + BondPad_origin = list( 0.0 0.0 ) + PackageIO_origin = list( 0.0 0.0 ) + + TEXT_size = 35 + TEXT_gap = 100 + + t_orient = "R0" + + Filename_Package = "./PADFRAME.package" + Filename_CDL = "./PADFRAME.cdl" + Filename_CDL_tmp = "./PADFRAME.cdl.tmp" + Filename_Cast = "./PADFRAME.cast" + Filename_Cast_tmp = "./PADFRAME.cast.tmp" + Filename_Spec = "./PADFRAME.spec" + Filename_Spec_tmp = "./PADFRAME.spec.tmp" + Filename_Binding_Rule = "./PADFRAME.bind.rul" + + outPort_Package = outfile( Filename_Package ) + outPort_CDL = outfile( Filename_CDL ) + outPort_CDL_tmp = outfile( Filename_CDL_tmp ) + outPort_Cast = outfile( Filename_Cast ) + outPort_Cast_tmp = outfile( Filename_Cast_tmp ) + outPort_Spec = outfile( Filename_Spec ) + outPort_Spec_tmp = outfile( Filename_Spec_tmp ) + outPort_Binding_Rule = outfile( Filename_Binding_Rule ) + + l_IOPort = nil + l_IOType = nil + + ExceptList = nil + + PadNameList = nil + PadName = nil + + CastCellName_S = nil + CastCellName_L = nil + + + + ; Global Variables + ; ==================== + ; DrawIO_GlobalFullIOList + + + ; Actual Processing + ; ====================== + + foreach( FullIO DrawIO_GlobalFullIOList + + ; Table Lookup for the Actual IO Cell + ; =================================== + case( cadr( FullIO ) + + ( "S" + ActualIO = car( setof( x DrawIO_GlobalSignalDriverList ( caar( x )==car( FullIO ) && caddar( x )==caddr( FullIO )))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterSignalDriver = CounterSignalDriver + 1 + CounterAllDriver = CounterAllDriver + 1 +; t_instName = sprintf( nil "S%n" CounterSignalDriver ) +; t_instName = sprintf( nil "S%n" CounterBondPad + 1 ) + t_instName = sprintf( nil "zzzS%n" CounterBondPad + 1 ) + ) + + ( "PRH" + ActualIO = car( setof( x DrawIO_GlobalPowerRingHighDriverList ( caar( x )==car( FullIO ) && caddar( x )==caddr( FullIO )))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterPowerRingHighDriver = CounterPowerRingHighDriver + 1 + CounterAllDriver = CounterAllDriver + 1 +; t_instName = sprintf( nil "PRH%n" CounterPowerRingHighDriver ) +; t_instName = sprintf( nil "S%n" CounterBondPad + 1 ) + t_instName = sprintf( nil "zzzS%n" CounterBondPad + 1 ) + ) + + ( "PRL" + ActualIO = car( setof( x DrawIO_GlobalPowerRingLowDriverList ( caar( x )==car( FullIO ) && caddar( x )==caddr( FullIO )))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterPowerRingLowDriver = CounterPowerRingLowDriver + 1 + CounterAllDriver = CounterAllDriver + 1 +; t_instName = sprintf( nil "PRL%n" CounterPowerRingLowDriver ) +; t_instName = sprintf( nil "S%n" CounterBondPad + 1 ) + t_instName = sprintf( nil "zzzS%n" CounterBondPad + 1 ) + ) + + ( "PCH" + ActualIO = car( setof( x DrawIO_GlobalPowerCoreHighDriverList ( caar( x )==car( FullIO ) && caddar( x )==caddr( FullIO )))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterPowerCoreHighDriver = CounterPowerCoreHighDriver + 1 + CounterAllDriver = CounterAllDriver + 1 +; t_instName = sprintf( nil "PCH%n" CounterPowerCoreHighDriver ) +; t_instName = sprintf( nil "S%n" CounterBondPad + 1 ) + t_instName = sprintf( nil "zzzS%n" CounterBondPad + 1 ) + ) + + ( "PCL" + ActualIO = car( setof( x DrawIO_GlobalPowerCoreLowDriverList ( caar( x )==car( FullIO ) && caddar( x )==caddr( FullIO )))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterPowerCoreLowDriver = CounterPowerCoreLowDriver + 1 + CounterAllDriver = CounterAllDriver + 1 +; t_instName = sprintf( nil "PCL%n" CounterPowerCoreLowDriver ) +; t_instName = sprintf( nil "S%n" CounterBondPad + 1 ) + t_instName = sprintf( nil "zzzS%n" CounterBondPad + 1 ) + ) + + ( "C" + ActualIO = car( setof( x DrawIO_GlobalCornerPadList ( caar( x )==car( FullIO ) && caddar( x )==caddr( FullIO )))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterCornerPad = CounterCornerPad + 1 + t_instName = sprintf( nil "C%n" CounterCornerPad ) + ) + + ( "F" + ActualIO = car( setof( x DrawIO_GlobalFeederList ( caar( x )==car( FullIO ) && caddar( x )==caddr( FullIO )))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterFeeder = CounterFeeder + 1 + t_instName = sprintf( nil "F%n" CounterFeeder ) + ) + + ( "D" + + ActualIO = car( setof( x DrawIO_GlobalDummyDriverList + ( caar( x )==car( FullIO ) && + cadar( x )==cadr( FullIO ) && + caddar( x )==caddr( FullIO ) + ))) + NumBondPadPerDriver = nth( 4 ActualIO ) + CounterAllDriver = CounterAllDriver + 1 + ) + + ); end case + + d_cellView = geGetWindowCellView( ) + t_libName = car( nth( 1 ActualIO )) + t_cellName = cadr( nth( 1 ActualIO )) + t_viewName = caddr( nth( 1 ActualIO )) + + + + ; Table Lookup for the appropiate Bonding Cell + ; ============================================== + if( member( cadr( FullIO ) list( "S" "PRH" "PRL" "PCH" "PCL" )) + then + BondPad = nth( mod( CounterBondPad 2 ) + setof( x DrawIO_GlobalBondPadList ( caar( x )==car( FullIO ) )) + ) + else + BondPad = nil + ); end if + + + + ; Rotate 90 degree counter-clockwise if not the first corner pad + ; ================================================================== + if( cadr( FullIO ) == "C" && CounterBondPad != 0 + then + case( t_orient + + ( "R0" + t_orient = "R90" + CurrentDriverX = CurrentDriverX + cadr( nth( 2 ActualIO )) + ) + + ( "R90" + t_orient = "R180" + CurrentDriverY = CurrentDriverY + cadr( nth( 2 ActualIO )) + ) + + ( "R180" + t_orient = "R270" + CurrentDriverX = CurrentDriverX - cadr( nth( 2 ActualIO )) + ) + + + ( "R270" + t_orient = "R0" + ) + + ); end case + + ); end if + + + ; Calculate the origin of the current IO + ; ================================================================= + ; Increment the x/y coordinates for the next IO + ; ================================================================= + + if( member( cadr( FullIO ) list( "S" "PRH" "PRL" "PCH" "PCL" "F" "C" )) + then + + case( t_orient + + ( "R0" + l_origin = list( CurrentDriverX - car( nth( 3 ActualIO )) + CurrentDriverY - cadr( nth( 3 ActualIO )) + ) + + TEXT_origin = list( CurrentDriverX CurrentDriverY - TEXT_gap ) + TEXT_orient = "R90" + TEXT_just = "upperLeft" + + if( BondPad + then + BondPad_origin = list( CurrentDriverX - car( nth( 3 BondPad )) + car( nth( 5 ActualIO )) + CurrentDriverY - cadr( nth( 3 BondPad )) + ) + ); end if + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) + 17.5 cadr( BondPad_origin ) + 104.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) + 17.5 cadr( BondPad_origin ) + 27.5 ) + ); end if + + CurrentDriverX = CurrentDriverX + car( nth( 2 ActualIO )) + ) + + ( "R90" + l_origin = list( CurrentDriverX + cadr( nth( 3 ActualIO )) + CurrentDriverY - car( nth( 3 ActualIO )) + ) + + TEXT_origin = list( CurrentDriverX + TEXT_gap CurrentDriverY + 20 ) + TEXT_orient = "R180" + TEXT_just = "lowerLeft" + + if( BondPad + then + BondPad_origin = list( CurrentDriverX + cadr( nth( 3 BondPad )) + CurrentDriverY - car( nth( 3 BondPad )) + car( nth( 5 ActualIO )) + ) + ); end if + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) - 104.5 cadr( BondPad_origin ) + 17.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) - 27.5 cadr( BondPad_origin ) + 17.5 ) + ); end if + + CurrentDriverY = CurrentDriverY + car( nth( 2 ActualIO )) + ) + + ( "R180" + l_origin = list( CurrentDriverX + car( nth( 3 ActualIO )) + CurrentDriverY + cadr( nth( 3 ActualIO )) + ) + + TEXT_origin = list( CurrentDriverX - 20 CurrentDriverY + TEXT_gap ) + TEXT_orient = "R270" + TEXT_just = "lowerLeft" + + if( BondPad + then + BondPad_origin = list( CurrentDriverX + car( nth( 3 BondPad )) - car( nth( 5 ActualIO )) + CurrentDriverY + cadr( nth( 3 BondPad )) + ) + ); end if + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) - 17.5 cadr( BondPad_origin ) - 104.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) - 17.5 cadr( BondPad_origin ) - 27.5 ) + ); end if + + + CurrentDriverX = CurrentDriverX - car( nth( 2 ActualIO )) + ) + + ( "R270" + l_origin = list( CurrentDriverX - cadr( nth( 3 ActualIO )) + CurrentDriverY + car( nth( 3 ActualIO )) + ) + + TEXT_origin = list( CurrentDriverX - TEXT_gap CurrentDriverY ) + TEXT_orient = "R0" + TEXT_just = "upperLeft" + + if( BondPad + then + BondPad_origin = list( CurrentDriverX - cadr( nth( 3 BondPad )) + CurrentDriverY + car( nth( 3 BondPad )) - car( nth( 5 ActualIO )) + ) + ); end if + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) + 104.5 cadr( BondPad_origin ) - 17.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) + 27.5 cadr( BondPad_origin ) - 17.5 ) + ); end if + + CurrentDriverY = CurrentDriverY - car( nth( 2 ActualIO )) + ) + + ); end case + + );end if + + ; Perform Actual Instantantion (Driver/Feeder) + ; ============================================ + if( member( cadr( FullIO ) list( "S" "PRH" "PRL" "PCH" "PCL" "F" "C" )) + then + d_inst = dbCreateInstByMasterName( + d_cellView + t_libName + t_cellName + t_viewName + t_instName + l_origin + t_orient + ) + ); end if + + + + ; Add the IOType into the List if it's not already there + ; -- used mainly for Cast Generation + ; ====================================================== + if( member( cadr( FullIO ) list( "S" "PRH" "PRL" "PCH" "PCL" )) + then + IOType = cadr( cadr( ActualIO )) + rexCompile( "\\.0" ) + IOType = rexReplace( IOType "" 0 ) + rexCompile( "\\.1" ) + IOType = rexReplace( IOType "" 0 ) + + if( !member( IOType l_IOType ) + then + DebugOn && printf( "DrawIO_ProcDrawIO --> Found New Cadence Cellname \"%s\"\n" IOType ) + l_IOType = cons( IOType l_IOType ) + ); end if + ); end if + + + ; Create Connectivities (Fill up the "Propagate Net" Box) + ; ========================================================== + for( i 0 length( nth( 3 FullIO ))-1 + + NetChild = cadr( nth( i nth( 3 FullIO ))) + +; NetChild = nth( i nth( 3 FullIO )) + + + NetParent = nth( i nth( 6 ActualIO )) + + ; In case the NetElement is just a simple string + ; Position Mapping + ; =============================================== + if( stringp( NetChild ) && stringp( NetParent ) + then + NetID = dbMakeNet( geGetWindowCellView() NetChild ) + dbCreateConnByName( NetID d_inst NetParent ) + if( !member( NetChild l_IOPort ) + then + l_IOPort = cons( NetChild l_IOPort ) + fprintf( outPort_Binding_Rule "changeLabel( \"%s\" \"%s.%s\" ) \n" + NetChild + t_instName + NetParent + ) + ); end if + ); end if +;Samson + + ); end for + + ; Draw inplace pins and labels for this driver + ; ============================================== + + DrawIO_ProcDrawInPlacePinsAndLabels( d_inst ) + + + ; Instantantion of Bond Pad if necessary + ; ======================================= + for( i 1 NumBondPadPerDriver + + CounterBondPad = CounterBondPad + 1 + + ; Make sure that a Bond Pad is needed for this driver + ; =================================================== + if( member( cadr( FullIO ) list( "S" "PRH" "PRL" "PCH" "PCL" )) + then + BondPad_instName = sprintf( nil "B%n" CounterBondPad ) + t_libName = car( nth( 1 BondPad )) + t_cellName = cadr( nth( 1 BondPad )) + t_viewName = caddr( nth( 1 BondPad )) + + d_inst = dbCreateInstByMasterName( + d_cellView + t_libName + t_cellName + t_viewName + BondPad_instName + BondPad_origin + t_orient + ) + + dbCreateLabel( d_cellView + list( "TEXT" "drawing" ) + TEXT_origin + sprintf( nil "%n" CounterBondPad ) + TEXT_just + TEXT_orient + "roman" + TEXT_size + ) + + + + ; Dealing with the next BondPad for the current Driver + ; Currently, only LVDS Drivers will have TWO BondPads + ; ====================================================================== + + BondPadOld = BondPad + PackageIO_originOld = PackageIO_origin + + BondPad = nth( mod( CounterBondPad 2 ) + setof( x DrawIO_GlobalBondPadList ( caar( x )==car( FullIO ) )) + ) + + + if( nth( i nth( 5 ActualIO )) == nil + then + NextBondPadOffset = 0 + else + NextBondPadOffset = nth( i nth( 5 ActualIO )) + ); end if + + case( t_orient + + ( "R0" + BondPad_origin = list( car( BondPad_origin ) + NextBondPadOffset - car( nth( 3 BondPad )) + car( nth( 3 BondPadOld )) + cadr( BondPad_origin ) - cadr( nth( 3 BondPad )) + cadr( nth( 3 BondPadOld )) + ) + TEXT_origin = list( car( TEXT_origin ) + NextBondPadOffset cadr( TEXT_origin )) + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) + 17.5 cadr( BondPad_origin ) + 104.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) + 17.5 cadr( BondPad_origin ) + 27.5 ) + ); end if + + ) + + ( "R90" + BondPad_origin = list( car( BondPad_origin ) + cadr( nth( 3 BondPad )) - cadr( nth( 3 BondPadOld )) + cadr( BondPad_origin ) + NextBondPadOffset - car( nth( 3 BondPad )) + car( nth( 3 BondPadOld )) + ) + TEXT_origin = list( car( TEXT_origin ) cadr( TEXT_origin ) + NextBondPadOffset ) + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) - 104.5 cadr( BondPad_origin ) + 17.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) - 27.5 cadr( BondPad_origin ) + 17.5 ) + ); end if + + ) + + ( "R180" + BondPad_origin = list( car( BondPad_origin ) - NextBondPadOffset + car( nth( 3 BondPad )) - car( nth( 3 BondPadOld )) + cadr( BondPad_origin ) + cadr( nth( 3 BondPad )) - cadr( nth( 3 BondPadOld )) + ) + TEXT_origin = list( car( TEXT_origin ) - NextBondPadOffset cadr( TEXT_origin )) + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) - 17.5 cadr( BondPad_origin ) - 104.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) - 17.5 cadr( BondPad_origin ) - 27.5 ) + ); end if + + ) + + ( "R270" + BondPad_origin = list( car( BondPad_origin ) - cadr( nth( 3 BondPad )) + cadr( nth( 3 BondPadOld )) + cadr( BondPad_origin ) - NextBondPadOffset + car( nth( 3 BondPad )) - car( nth( 3 BondPadOld )) + ) + TEXT_origin = list( car( TEXT_origin ) cadr( TEXT_origin ) - NextBondPadOffset ) + + if( caddar( BondPad ) == "BI" + then + PackageIO_origin = list( car( BondPad_origin ) + 104.5 cadr( BondPad_origin ) - 17.5 ) + else + PackageIO_origin = list( car( BondPad_origin ) + 27.5 cadr( BondPad_origin ) - 17.5 ) + ); end if + + ) + + ); end case + + ); end if + + + + ; ================================ + ; Output Packaging File + ; ================================ + GroupName = car( car( ActualIO )) + GroupType = caddr( car( ActualIO )) + + ; Hash the Symbol Name to get the original cellname + ; ================================================= + + case( GroupName + + ( "LVDS" + case( GroupType + + ( "IN" + GroupType = "pnl_sp_se_in" + ) + + ( "OUT_VC" + GroupType = "pnl_lvds85_out_vc" + ) + + ( "OUT_VO" + GroupType = "pnl_lvds85_out_vo" + ) + + ( "OUT_VOP" + GroupType = "pnl_lvds85_out_vop" + ) + + ( "OUT_GC" + GroupType = "pnl_lvds85_out_gc" + ) + + ( "OUT_GO" + GroupType = "pnl_lvds85_out_go" + ) + + ( "OUT_VREF" + GroupType = "pnl_lvds85_out_vref" + ) + + ( "VREF" + GroupType = "pnl_vref_lvds" + ) + + ( "VP" + GroupType = "pnl_vp_lvds" + ) + + ( "VO" + GroupType = "pnl_vo_lvds" + ) + + ( "VOP" + GroupType = "pnl_vop_lvds" + ) + + ( "GO" + GroupType = "pnl_go_lvds" + ) + + ( "VC" + GroupType = "pnl_vc_lvds" + ) + + ( "GCS" + GroupType = "pnl_gcs_lvds" + ) + + ( "D1" + GroupType = "Dummy(noBondPad)" + ) + + ); end case + + ) + + ( "LVTTL" + + case( GroupType + + ( "INnn2" + GroupType = "pnl_it2nn2" + ) + + ( "INpd2" + GroupType = "pnl_it2pd2" + ) + + ( "INpd2_2" + GroupType = "pnl_it2pd2(withPI)" + ) + + ( "INpu2" + GroupType = "pnl_it2pu2" + ) + + ( "INnn8" + GroupType = "pnl_it2nn8" + ) + + ( "INpd8" + GroupType = "pnl_it2pd8" + ) + + ( "INOUT2nn2" + GroupType = "pnl_tf02it0nn2" + ) + + ( "INOUT4nn2" + GroupType = "pnl_tf04it0nn2" + ) + + ( "INOUT8nn2" + GroupType = "pnl_tf08it0nn2" + ) + + ( "AIO" + GroupType = "pnl_aio" + ) + + ( "VP" + GroupType = "pnl_vp" + ) + + ( "VOO" + GroupType = "pnl_voo" + ) + + ( "VOP" + GroupType = "pnl_vop" + ) + + ( "VOP_2" + GroupType = "pnl_vop" + ) + + ( "VP_2" + GroupType = "pnl_vp" + ) + + ( "GO" + GroupType = "pnl_go" + ) + + ( "GO_2" + GroupType = "pnl_go" + ) + + ( "VC" + GroupType = "pnl_vc" + ) + + ( "GCS" + GroupType = "pnl_gcs" + ) + + ( "D1" + GroupType = "Dummy(noBondPad)" + ) + + ); end case + + + ) + + ); end case + + + + + + +; println( GroupName ) +; println( GroupType ) +; println( ActualIO ) +; println( NumBondPadPerDriver ) + + case( NumBondPadPerDriver + + ( 1 + rexCompile( "^pad_" ) + PadNameList = setof( x nth( 3 FullIO ) rexExecute( car( x ))) + PadName = cadr( car( PadNameList )) + PadPackageName = caddr( car( PadNameList )) + + ; Error Checking + ; ============== + if( length( PadNameList ) != 1 && cadr( FullIO ) != "D" + then + printf( "ERROR!!! Number of Bondpad must be 1 for single-paded drivers\n" ) + printf( "ERROR!!! Trying to search a padname prefixed \"pad_\" in the List %L \n" nth( 3 FullIO )) + printf( "ERROR!!! Search failed and return %L \n" PadNameList ) + printf( "========================================================================= \n" ) + ); end if + + ) + + ( 2 + rexCompile( nth( i-1 list( "^padp_" "^padn_" ))) + PadNameList = setof( x nth( 3 FullIO ) rexExecute( car( x ))) + PadName = cadr( car( PadNameList )) + PadPackageName = caddr( car( PadNameList )) + + ) + + ( 3 + rexCompile( nth( i-1 list( "^padp_" "^pad_" "^padn_" ))) + PadNameList = setof( x nth( 3 FullIO ) rexExecute( car( x ))) + PadName = cadr( car( PadNameList )) + PadPackageName = caddr( car( PadNameList )) + + ) + + ); end case + + + ; Deals with Dummy Pads "D" + ; ========================= + if( PadNameList == nil + then + PadName = "No_Pad_Name" + PadPackageName = "No_Package_Name" + else + + ; Deals with Printout for Inner/Outer Bondpads + ; ============================================ + if( caddar( BondPadOld ) == "BI" + then + BondPadDirection = "Inner" + else + BondPadDirection = "Outer" + );end if + ); end if + + +; println( PadNameList ) +; println( PadName ) +; println( "++++++++++++++++++++++" ) + + + if( PadName != "No_Pad_Name" + then + fprintf( outPort_Package "%-4n\t%3s\t%5s\t%22s\t%-35s\t%-35s\t%-8.3n\t%-8.3n\t%-8s\n" + CounterBondPad + t_orient + GroupName + GroupType + PadName + PadPackageName + car( PackageIO_originOld ) + cadr( PackageIO_originOld ) + BondPadDirection + ) + else + fprintf( outPort_Package "%-4n\t%3s\t%5s\t%22s\t%-35s\t%-35s\t%-11s\t%-11s\t%-8s\n" + CounterBondPad + t_orient + GroupName + GroupType + PadName + PadPackageName + "XXXXXX" + "YYYYYY" + "Dummy" + ) + ); end if + + geRefresh( ) + + + ); end for End Drawing Bondpad + + + +;Samson3 + ; Output CDL File + ; ================================ + if( member( cadr( FullIO ) list( "S" "PRH" "PRL" "PCH" "PCL" )) + then + fprintf( outPort_CDL_tmp "X%s\t" t_instName ) + + for( i 0 length( nth( 3 FullIO ))-1 + +; NetChild = nth( i nth( 3 FullIO )) + NetChild = cadr( nth( i nth( 3 FullIO ))) + ; NetParent = nth( i nth( 6 ActualIO )) + + ; In case the NetElement is just a simple string + ; Position Mapping + ; =============================================== + if( stringp( NetChild ) + then + fprintf( outPort_CDL_tmp "%s\t" NetChild ) + ); end if + + ); end for + + fprintf( outPort_CDL_tmp "%s\n" cadr( nth( 1 ActualIO ))) + ); end if + + ; Output Cast File and Spec File + ; ================================ + if( member( cadr( FullIO ) list( "S" "PRH" "PRL" "PCH" "PCL" )) + then + + CastCellName_L = cadr( nth( 1 ActualIO )) + CastCellName_M = cadr( nth( 1 ActualIO )) + CastCellName_S = cadr( nth( 1 ActualIO )) + + rexCompile( strcat( car( nth( 1 ActualIO )) "." )) + CastCellName_S = rexReplace( CastCellName_S "" 0 ) + rexCompile( "\\.0" ) + CastCellName_S = rexReplace( CastCellName_S "" 0 ) + rexCompile( "\\.1" ) + CastCellName_S = rexReplace( CastCellName_S "" 0 ) + + fprintf( outPort_Cast_tmp "%s %s(" CastCellName_S t_instName ) + + for( i 0 length( nth( 3 FullIO ))-1 + +;Samson4 + ; NetChild = nth( i nth( 3 FullIO )) + NetChild = cadr( nth( i nth( 3 FullIO ))) + ; NetParent = nth( i nth( 6 ActualIO )) + + ; In case the NetElement is just a simple string + ; Position Mapping + ; =============================================== + if( stringp( NetChild ) + then + fprintf( outPort_Cast_tmp "%s" NetChild ) + i!=length( nth( 3 FullIO ))-1 && fprintf( outPort_Cast_tmp "," ) + ); end if + + + ); end for + + fprintf( outPort_Cast_tmp ");\n" ) + + + ; Output Spec File + ; ================ + + rexCompile( "\\.0" ) + CastCellName_M = rexReplace( CastCellName_M "" 0 ) + rexCompile( "\\.1" ) + CastCellName_M = rexReplace( CastCellName_M "" 0 ) + + fprintf( outPort_Spec_tmp "\t%s :> \n" CastCellName_M ) + fprintf( outPort_Spec_tmp "\t\t%s %s; \n" CastCellName_L t_instName ) + + ); end if + + ); end foreach + + fprintf( outPort_CDL_tmp ".ENDS PADFRAME \n" ) + close( outPort_Package ) + close( outPort_CDL_tmp ) + close( outPort_Cast_tmp ) + close( outPort_Spec_tmp ) + close( outPort_Binding_Rule ) + + + ; Create the Final CDL File + ; ============================== + l_IOPort = sort( l_IOPort `alphalessp ) + + fprintf( outPort_CDL ".SUBCKT PADFRAME \n" ) + + foreach( IOPort l_IOPort + fprintf( outPort_CDL "+ %s\n" IOPort ) + ); end foreach + + close( outPort_CDL ) + + sh( sprintf( nil "cat %s >> %s" Filename_CDL_tmp Filename_CDL )) + + + ; Create the Final Cast File + ; ============================== + l_IOPort = sort( l_IOPort `alphalessp ) + l_IOType = sort( l_IOType `alphalessp ) + + fprintf( outPort_Cast "/* Automatically generated. Modify at your own risk. */\n") + fprintf( outPort_Cast "/* \n" ) + fprintf( outPort_Cast " Created by Octopus (Fulcrum Padframe Compiler) \n" ) + fprintf( outPort_Cast "*/ \n" ) + + fprintf( outPort_Cast "module chip.x6.padframe;\n\n" ) + + foreach( IOType l_IOType + fprintf( outPort_Cast "import %s;\n" IOType ) + ); end foreach + + fprintf( outPort_Cast "define PADFRAME ()\n" ) + fprintf( outPort_Cast "(\n" ) + + foreach( IOPort l_IOPort + if( IOPort != nth( length( l_IOPort )-1 l_IOPort ) + then + fprintf( outPort_Cast "node %s;\n" IOPort ) + else + fprintf( outPort_Cast "node %s\n" IOPort ) + ); end if + ); end foreach + + fprintf( outPort_Cast ") <: NULL \n" ) + + close( outPort_Cast ) + + sh( sprintf( nil "echo \"{\" >> %s" Filename_Cast )) + sh( sprintf( nil "echo \"subcells {\" >> %s" Filename_Cast )) + sh( sprintf( nil "cat %s >> %s" Filename_Cast_tmp Filename_Cast )) + sh( sprintf( nil "echo \"}\" >> %s" Filename_Cast )) + sh( sprintf( nil "echo \"}\" >> %s" Filename_Cast )) + + + + ; Create the Final Spec File + ; ============================== + l_IOPort = sort( l_IOPort `alphalessp ) + + fprintf( outPort_Spec "/* Automatically generated. Modify at your own risk. */\n") + fprintf( outPort_Spec "/* \n" ) + fprintf( outPort_Spec " Created by Octopus (Fulcrum Padframe Compiler) \n" ) + fprintf( outPort_Spec "*/ \n" ) + + fprintf( outPort_Spec "module chip.x6.padframe.PADFRAME;\n" ) + fprintf( outPort_Spec "define \"0\"()(\n" ) + + foreach( IOPort l_IOPort + if( IOPort != nth( length( l_IOPort )-1 l_IOPort ) + then + fprintf( outPort_Spec "\tnode %s;\n" IOPort ) + else + fprintf( outPort_Spec "\tnode %s\n" IOPort ) + ); end if + ); end foreach + + close( outPort_Spec ) + + sh( sprintf( nil "echo \") <: chip.x6.padframe.PADFRAME {\" >> %s" Filename_Spec )) + sh( sprintf( nil "echo \" subtypes {\" >> %s" Filename_Spec )) + sh( sprintf( nil "cat %s >> %s" Filename_Spec_tmp Filename_Spec )) + sh( sprintf( nil "echo \" }\" >> %s" Filename_Spec )) + sh( sprintf( nil "echo \"} \" >> %s" Filename_Spec )) + + + t + + ); end let + +); end procedure + + + + +; ======================================================================== +; This procedure is used to draw inplace pins +; ======================================================================== +procedure( DrawIO_ProcDrawInPlacePinsAndLabels( Cell @key + ( Pin list( "drawing" t )) + ( Label list( "drawing" t )) + ( ExceptList nil ) + ( DebugOn nil ) + ) + +let( ( x_inst y_inst + xlow_instTerm ylow_instTerm + xhigh_instTerm yhigh_instTerm + xlow_instTerm_new ylow_instTerm_new + xhigh_instTerm_new yhigh_instTerm_new + d_Pin DrawPin PinLayer PinPurpose + d_Label DrawLabel LabelLayer LabelPurpose + d_Net l_Net + bBox_instTerm xy_instTerm + ) + + DrawPin = cadr( Pin ) + DrawLabel = cadr( Label ) + PinPurpose = car( Pin ) + LabelPurpose = car( Label ) + + if( Cell->objType == "inst" && Cell->viewName != "symbolic" + then + + DebugOn && printf( "DrawIO_ProcDrawInPlacePinsAndLabels --> Start cell \"%s\" \"%s\" \n" Cell->cellName Cell->name ) + + x_inst = car( Cell->xy ) + y_inst = cadr( Cell->xy ) + + ; Go thru each instTerms (IO pins) + foreach( d_instTerm Cell->instTerms + + DebugOn && printf( "DrawIO_ProcDrawInPlacePinsAndLabels --> --> Start instTerms = %s -> %s \n" d_instTerm->name d_instTerm->net->name ) + + foreach( d_instTermPin d_instTerm->term->pins + + ; Filter out Symbolic Pins + ; ======================== + if( d_instTermPin->fig->objType != "inst" + then + + xlow_instTerm = caar( d_instTermPin->fig->bBox ) + ylow_instTerm = cadar( d_instTermPin->fig->bBox ) + xhigh_instTerm = caadr( d_instTermPin->fig->bBox ) + yhigh_instTerm = cadadr( d_instTermPin->fig->bBox ) + + if( member( d_instTermPin->fig->objType list( "polygon" "path" )) + then + xlow_instTerm = car( car( d_instTermPin->fig->points ) ) - 0.01 + ylow_instTerm = cadr( car( d_instTermPin->fig->points ) ) - 0.01 + xhigh_instTerm = car( car( d_instTermPin->fig->points ) ) + 0.01 + yhigh_instTerm = cadr( car( d_instTermPin->fig->points ) ) + 0.01 + ); end if + + case( Cell->orient + + ( "R0" + xlow_instTerm = x_inst + xlow_instTerm + ylow_instTerm = y_inst + ylow_instTerm + xhigh_instTerm = x_inst + xhigh_instTerm + yhigh_instTerm = y_inst + yhigh_instTerm + ) + + ( "R90" + xlow_instTerm_new = x_inst - ylow_instTerm + ylow_instTerm_new = y_inst + xlow_instTerm + xhigh_instTerm_new = x_inst - yhigh_instTerm + yhigh_instTerm_new = y_inst + xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + ( "R180" + xlow_instTerm = x_inst - xlow_instTerm + ylow_instTerm = y_inst - ylow_instTerm + xhigh_instTerm = x_inst - xhigh_instTerm + yhigh_instTerm = y_inst - yhigh_instTerm + + ) + + ( "R270" + xlow_instTerm_new = x_inst + ylow_instTerm + ylow_instTerm_new = y_inst - xlow_instTerm + xhigh_instTerm_new = x_inst + yhigh_instTerm + yhigh_instTerm_new = y_inst - xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + ( "MY" + xlow_instTerm = x_inst - xlow_instTerm + ylow_instTerm = y_inst + ylow_instTerm + xhigh_instTerm = x_inst - xhigh_instTerm + yhigh_instTerm = y_inst + yhigh_instTerm + ) + + ( "MYR90" + xlow_instTerm_new = x_inst - ylow_instTerm + ylow_instTerm_new = y_inst - xlow_instTerm + xhigh_instTerm_new = x_inst - yhigh_instTerm + yhigh_instTerm_new = y_inst - xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + + ( "MX" + xlow_instTerm = x_inst + xlow_instTerm + ylow_instTerm = y_inst - ylow_instTerm + xhigh_instTerm = x_inst + xhigh_instTerm + yhigh_instTerm = y_inst - yhigh_instTerm + ) + + ( "MXR90" + xlow_instTerm_new = x_inst + ylow_instTerm + ylow_instTerm_new = y_inst + xlow_instTerm + xhigh_instTerm_new = x_inst + yhigh_instTerm + yhigh_instTerm_new = y_inst + xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + ( t + xlow_instTerm = x_inst + xlow_instTerm + ylow_instTerm = y_inst + ylow_instTerm + xhigh_instTerm = x_inst + xhigh_instTerm + yhigh_instTerm = y_inst + yhigh_instTerm + ) + + ); end case + + + bBox_instTerm = list( + xlow_instTerm:ylow_instTerm + xhigh_instTerm:yhigh_instTerm + ) + xy_instTerm = list( + ( xlow_instTerm+xhigh_instTerm )/2 + ( ylow_instTerm+yhigh_instTerm )/2 + ) + if( DrawPin && !member( d_instTerm->net->name ExceptList ) + then + PinLayer = d_instTermPin->fig->layerName + + ; First, draw the pin + d_Pin = dbCreateRect( geGetWindowCellView( ) list( PinLayer PinPurpose ) bBox_instTerm ) + + ; Second, Fill up Connectivity + d_Net = dbMakeNet( geGetWindowCellView() d_instTerm->net->name ) + dbCreatePin( d_Net d_Pin ) + ); end if + + + if( DrawLabel && !member( d_instTerm->net->name ExceptList ) + then + LabelLayer = d_instTermPin->fig->layerName + + d_Label = dbCreateLabel( + geGetWindowCellView( ) + list( LabelLayer LabelPurpose ) + xy_instTerm + sprintf( nil "%s" d_instTerm->net->name ) + "centerCenter" + "R0" + "stick" + 0.2 + ) + );end if + + ); end if filter out inst type pins + + );foreach d_instTermPin + + ); foreach instTerm + + DebugOn && printf( "DrawIO_ProcDrawInPlacePinsAndLabels --> Finish Cell \"%s\" \"%s\" \n" Cell->cellName Cell->name ) + + ); end if + + xy_instTerm + +); end let + +);end procedure + + + + +; ======================================================================== +; This procedure is the MAIN GUI +; ======================================================================== +procedure( DrawIO_ProcWrapper( @key ( DebugOn nil ) + ) + + let(( TR_DrawIO_ModeField + TR_DrawIO_DriverPitchField + TR_DrawIO_CompileGlobalsField + TR_DrawIO_ReadInputField + TR_DrawIO_PerformAliasingField + TR_DrawIO_AnalysisInputField + TR_DrawIO_DrawIOField + TR_DrawIO_theForm + ) + + + TR_DrawIO_ProjectField = hiCreateStringField( + ?name `TR_DrawIO_ProjectField + ?prompt "Current Project" + ?defValue "x6" + ?enabled t + ) + + TR_DrawIO_ModeField = hiCreateRadioField( + ?name `TR_DrawIO_ModeField + ?choices list( "Normal" "FixCount" ) + ?prompt "Mode" + ?defValue "Normal" + ?enabled t + ?callback list( "TR_DrawIO_theForm->TR_DrawIO_DriverPitchField->enabled = t" "TR_DrawIO_theForm->TR_DrawIO_DriverPitchField->enabled = nil" ) + ) + + TR_DrawIO_DriverPitchField = hiCreateFloatField( + ?name `TR_DrawIO_DriverPitchField + ?defValue 35.0 + ?enabled t + ?callback "TR_DrawIO_DriverPitchField_CB( hiGetCurrentForm() ?DebugOn t )" + ) + + TR_DrawIO_CompileGlobalsField = hiCreateButton( + ?name `TR_DrawIO_CompileGlobalsField + ?buttonText "Compile Global Variables" + ?enabled t + ?callback "DrawIO_ProcCompileGlobals( ?Project TR_DrawIO_theForm->TR_DrawIO_ProjectField->value + ?DriverPitch TR_DrawIO_theForm->TR_DrawIO_DriverPitchField->value + )" + ) + + TR_DrawIO_ReadInputField = hiCreateButton( + ?name `TR_DrawIO_ReadInputField + ?buttonText "Read Input" + ?enabled t + ?callback "DrawIO_ProcReadInput( )" + ) + + TR_DrawIO_PerformAliasingField = hiCreateButton( + ?name `TR_DrawIO_PerformAliasingField + ?buttonText "Perform Name Aliasing" + ?enabled t + ?callback "DrawIO_ProcPerformAliasing( )" + ) + + TR_DrawIO_AnalysisInputField = hiCreateButton( + ?name `TR_DrawIO_AnalysisInputField + ?buttonText "Analysis Input" + ?enabled t + ?callback "DrawIO_ProcAnalysisInput( ?Mode TR_DrawIO_ModeField->value )" + ) + + TR_DrawIO_DrawIOField = hiCreateButton( + ?name `TR_DrawIO_DrawIOField + ?buttonText "Instantiate Padframe" + ?enabled t + ?callback "DrawIO_ProcDrawIO( )" + ) + + TR_DrawIO_theForm = hiCreateAppForm( + ?name `TR_DrawIO_theForm + ?initialSize list( 300 500 ) + ?fields list( + list( TR_DrawIO_ProjectField 0:0 300:30 200) + + list( TR_DrawIO_ModeField 0:30 200:30 50 ) + list( TR_DrawIO_DriverPitchField 200:30 100:30 0 ) + + list( TR_DrawIO_CompileGlobalsField 0:60 300:30 0 ) + list( TR_DrawIO_ReadInputField 0:90 300:30 0 ) + list( TR_DrawIO_PerformAliasingField 0:120 300:30 0 ) + list( TR_DrawIO_AnalysisInputField 0:150 300:30 0 ) + list( TR_DrawIO_DrawIOField 0:180 300:30 0 ) + ) + ?callback "" + ) + + + hiDisplayForm( TR_DrawIO_theForm ) + + ); end let + + +); end procedure + + + + +; ================================================ +; Callback Function for TR_DrawIO_DriverPitchField +; ================================================ +procedure( TR_DrawIO_DriverPitchField_CB( theForm @key ( DebugOn t )) + + DrawIO_GlobalDriverPitch = float( theForm->TR_DrawIO_DriverPitchField->value ) + DebugOn && printf( "TR_DrawIO_DriverPitchField_CB --> DrawIO_GlobalDriverPitch = %n\n" DrawIO_GlobalDriverPitch ) + +); end procedure + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO_Globals_x6.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO_Globals_x6.il new file mode 100644 index 0000000000..89b7028e29 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawIO_Globals_x6.il @@ -0,0 +1,175 @@ +; =================================================================== +; This is a procedure used to compile global variables for "x6" Space +; =================================================================== +procedure( DrawIO_ProcCompileGlobals_x6( @key + ( DriverPitch 35.0 ) + ) + + let(( + LVTTL_libName LVTTL_cellHeight + LVDS_libName LVDS_cellHeight + ) + + ; Local Variables + ; =============== + LVTTL_libName = "vendor.nurlogic.io.lvttl" + LVTTL_cellHeight = 458.40 + LVDS_libName = "vendor.nurlogic.io.lvds" + LVDS_cellHeight = 458.40 + + + ; Globals + ; ======= + ; DrawIO_GlobalConfigFile + + DrawIO_GlobalChipWidth = 12200.0 + DrawIO_GlobalChipHeight = 11850.0 + DrawIO_GlobalChipOffset = 458.40 + + if( DriverPitch + then + DrawIO_GlobalDriverPitch = DriverPitch + else + DrawIO_GlobalDriverPitch = 40.0 + ); end if + + + DrawIO_GlobalFeederList = + list( + list( list( "LVDS" "F" "F01" ) list( LVDS_libName "vendor.nurlogic.io.lvds.filler_01g.0" "layout" ) list( 0.1 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "F" "F1" ) list( LVDS_libName "vendor.nurlogic.io.lvds.filler_1g.0" "layout" ) list( 1 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "F" "F2" ) list( LVDS_libName "vendor.nurlogic.io.lvds.filler_2g.0" "layout" ) list( 2 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "F" "F4" ) list( LVDS_libName "vendor.nurlogic.io.lvds.filler_4g.0" "layout" ) list( 4 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "F" "F8" ) list( LVDS_libName "vendor.nurlogic.io.lvds.filler_8g.0" "layout" ) list( 8 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + + list( list( "LVTTL" "F" "F01" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_01g.0" "layout" ) list( 0.1 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "F" "F1" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_1g.0" "layout" ) list( 1 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "F" "F2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_2g.0" "layout" ) list( 2 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "F" "F4" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_4g.0" "layout" ) list( 4 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "F" "F8" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_8g.0" "layout" ) list( 8 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "F" "F16" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_16g.0" "layout" ) list( 16 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "F" "F32" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_32g.0" "layout" ) list( 32 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "F" "F64" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.filler_64g.0" "layout" ) list( 64 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + + list( list( "RingBreaker" "F" "RB3" ) list( LVDS_libName "vendor.nurlogic.io.lvds.filler_brk_3g.0" "layout" ) list( 3 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + + ) + + + DrawIO_GlobalCornerPadList = + list( + list( list( "LVDS" "C" "CORNERPAD" ) list( LVDS_libName "vendor.nurlogic.io.lvds.iocrnr.0" "layout" ) list( LVDS_cellHeight LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "C" "CORNERPAD" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.iocrnr.0" "layout" ) list( LVTTL_cellHeight LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + ) + + DrawIO_GlobalSignalDriverList = + list( + list( list( "LVDS" "S" "IN" ) list( LVDS_libName "vendor.nurlogic.io.lvds.sp_se_in.0" "layout" ) list( 70 LVDS_cellHeight ) list( 0 0 ) 2 list( 0 35 ) list( "DI" "GND" "PADN" "PADP" "PD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "S" "OUT_VC" ) list( LVDS_libName "vendor.nurlogic.io.lvds.85_out_vc.0" "layout" ) list( 120 LVDS_cellHeight ) list( 0 0 ) 3 list( 2.5 40 40 ) list( "DO" "GND" "OE" "PAD" "PADN" "PADP" "SGND" "TN" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "S" "OUT_VO" ) list( LVDS_libName "vendor.nurlogic.io.lvds.85_out_vo.0" "layout" ) list( 120 LVDS_cellHeight ) list( 0 0 ) 3 list( 2.5 40 40 ) list( "DO" "GND" "OE" "PAD" "PADN" "PADP" "SGND" "TN" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "S" "OUT_VOP" ) list( LVDS_libName "vendor.nurlogic.io.lvds.85_out_vop.0" "layout" ) list( 120 LVDS_cellHeight ) list( 0 0 ) 3 list( 2.5 40 40 ) list( "DO" "GND" "OE" "PAD" "PADN" "PADP" "SGND" "TN" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "S" "OUT_GC" ) list( LVDS_libName "vendor.nurlogic.io.lvds.85_out_gcs.0" "layout" ) list( 120 LVDS_cellHeight ) list( 0 0 ) 3 list( 2.5 40 40 ) list( "DO" "GND" "OE" "PAD" "PADN" "PADP" "SGND" "TN" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "S" "OUT_GO" ) list( LVDS_libName "vendor.nurlogic.io.lvds.85_out_go.0" "layout" ) list( 120 LVDS_cellHeight ) list( 0 0 ) 3 list( 2.5 40 40 ) list( "DO" "GND" "OE" "PAD" "PADN" "PADP" "SGND" "TN" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "S" "OUT_VREF" ) list( LVDS_libName "vendor.nurlogic.io.lvds.85_out_vref.0" "layout" ) list( 120 LVDS_cellHeight ) list( 0 0 ) 3 list( 2.5 40 40 ) list( "DO" "GND" "OE" "PAD" "PADN" "PADP" "SGND" "TN" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "S" "VREF" ) list( LVDS_libName "vendor.nurlogic.io.lvds.vref.0" "layout" ) list( 35 LVDS_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "GND" "PAD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + + list( list( "LVTTL" "S" "INnn2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.it2nn2.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INpd2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.it2pd2.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INpd2_2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.it2pd2_2.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_GND" "n_PAD" "n_PI" "n_PO" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INpu2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.it2pu2.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INnn8" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.it2nn8.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INpd8" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.it2pd8.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INOUT2nn2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.tf02it0nn2.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_DO" "n_GND" "n_OE" "n_PAD" "n_SGND" "n_TN" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INOUT4nn2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.tf04it0nn2.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_DO" "n_GND" "n_OE" "n_PAD" "n_SGND" "n_TN" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "INOUT8nn2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.tf08it0nn2.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_DIN" "n_DO" "n_GND" "n_OE" "n_PAD" "n_SGND" "n_TN" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "S" "AIO" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.aio.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_PADX" "n_RIN" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + ) + + DrawIO_GlobalPowerRingHighDriverList = + list( + list( list( "LVDS" "PRH" "VP" ) list( LVDS_libName "vendor.nurlogic.io.lvds.vp_lvds.0" "layout" ) list( 35 LVDS_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "GND" "PAD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "PRH" "VO" ) list( LVDS_libName "vendor.nurlogic.io.lvds.vo_lvds.0" "layout" ) list( 35 LVDS_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "GND" "PAD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVDS" "PRH" "VOP" ) list( LVDS_libName "vendor.nurlogic.io.lvds.vop_lvds.0" "layout" ) list( 35 LVDS_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "GND" "PAD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + + list( list( "LVTTL" "PRH" "VP" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.vp.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "PRH" "VOO" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.voo.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "PRH" "VOP" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.vop.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + + list( list( "LVTTL" "PRH" "VOP_2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.vop.1" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "PRH" "VP_2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.vp.1" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + + ) + + + DrawIO_GlobalPowerRingLowDriverList = + list( + list( list( "LVDS" "PRL" "GO" ) list( LVDS_libName "vendor.nurlogic.io.lvds.go_lvds.0" "layout" ) list( 35 LVDS_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "GND" "PAD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVTTL" "PRL" "GO" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.go.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + list( list( "LVTTL" "PRL" "GO_2" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.go.1" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + ) + + DrawIO_GlobalPowerCoreHighDriverList = + list( + list( list( "LVDS" "PCH" "VC" ) list( LVDS_libName "vendor.nurlogic.io.lvds.vc_lvds.0" "layout" ) list( 35 LVDS_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "GND" "PAD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVTTL" "PCH" "VC" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.vc.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + ) + + DrawIO_GlobalPowerCoreLowDriverList = + list( + list( list( "LVDS" "PRL" "GCS" ) list( LVDS_libName "vendor.nurlogic.io.lvds.gcs_lvds.0" "layout" ) list( 35 LVDS_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "GND" "PAD" "SGND" "VDD" "VDDO" "VDDP" "VGG" "VREF" "VSSO" )) + list( list( "LVTTL" "PCL" "GCS" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.gcs.0" "layout" ) list( 35 LVTTL_cellHeight ) list( 0 0 ) 1 list( 0 ) list( "n_GND" "n_PAD" "n_SGND" "n_VDD" "n_VDDO" "n_VDDP" "n_VGG" "n_VSSO" )) + ) + + + ; Use LVTTL Bond Pads for LVDS Drivers + ; ==================================== + DrawIO_GlobalBondPadList = + list( + list( list( "LVDS" "B" "BI" ) list( LVDS_libName "vendor.nurlogic.io.lvds.stgin_50x50.0" "layout" ) list( 35.0 LVDS_cellHeight ) list( 0.0 0.0 ) 0 nil nil ) + list( list( "LVDS" "B" "BO" ) list( LVDS_libName "vendor.nurlogic.io.lvds.stgout_50x50.0" "layout" ) list( 35.0 LVDS_cellHeight ) list( 0.0 0.0 ) 0 nil nil ) + list( list( "LVTTL" "B" "BI" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.CUpadTSMC_stgin_50x50.0" "layout" ) list( 35.0 LVTTL_cellHeight ) list( 0.0 0.0 ) 0 nil nil ) + list( list( "LVTTL" "B" "BO" ) list( LVTTL_libName "vendor.nurlogic.io.lvttl.CUpadTSMC_stgout_50x50.0" "layout" ) list( 35.0 LVTTL_cellHeight ) list( 0.0 0.0 ) 0 nil nil ) + ) + + DrawIO_GlobalDummyDriverList = + list( + list( list( "LVDS" "D" "D1" ) nil list( 35.0 LVDS_cellHeight ) list( 0 0 ) 1 nil nil ) + list( list( "LVDS" "D" "D3_4u" ) nil list( 3.4 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "D" "D5_0u" ) nil list( 5.0 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "D" "D13_0u" ) nil list( 13.0 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "D" "D20_0u" ) nil list( 20.0 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVDS" "D" "D28_8u" ) nil list( 28.8 LVDS_cellHeight ) list( 0 0 ) 0 nil nil ) + + + list( list( "LVTTL" "D" "D1" ) nil list( 35.0 LVTTL_cellHeight ) list( 0 0 ) 1 nil nil ) + list( list( "LVTTL" "D" "D0_6u" ) nil list( 0.6 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D2_0u" ) nil list( 2.0 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D8_0u" ) nil list( 8.0 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D9_6u" ) nil list( 9.6 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D12_0u" ) nil list( 12.0 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D10_0u" ) nil list( 10.0 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D16_4u" ) nil list( 16.4 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D17_0u" ) nil list( 17.0 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D26_0u" ) nil list( 26.0 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + list( list( "LVTTL" "D" "D26_6u" ) nil list( 26.6 LVTTL_cellHeight ) list( 0 0 ) 0 nil nil ) + ) + +; DrawIO_GlobalRawIOFile = "/home/user/samson/myskill/IO.input.x6.OutputTest" + DrawIO_GlobalRawIOFile = "/home/user/samson/myskill/IO.input.x6" + DrawIO_GlobalRawIOList = nil + DrawIO_GlobalRawIOList_Alias = nil + + DrawIO_GlobalAliasFile = "/home/user/samson/myskill/IO.input.x6.alias" + DrawIO_GlobalAliasList = nil + + DrawIO_GlobalFullIOList = nil + + ); end let + + t + +); end procedure + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawPins.il new file mode 100644 index 0000000000..8df476403b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_DrawPins.il @@ -0,0 +1,1199 @@ +; ============================================================================================================== +; Descriptions +; -------------------------------------------------------------------------------------------------------------- +; BitTemplate = nil | ChanTemplate = nil ==> "SAMPLE_CHANNEL" | +; BitTemplate = list( 0 15 1 ) | ChanTemplate = nil ==> "SAMPLE_CHANNEL[0..15]" | +; BitTemplate = nil | ChanTemplate = list( "0" "e" ) ==> "SAMPLE_CHANNEL.0" / "SAMPLE_CHANNEL.e" | +; BitTemplate = list( 0 15 1 ) | ChanTemplate = list( "0" "e" ) ==> "SAMPLE_CHANNEL[0..15].0/e" | +; -------------------------------------------------------------------------------------------------------------- +; +; ============================================================================================================== + +procedure( TR_DrawPins( @key + ( DebugOn t ) + ( LabelPurpose "drawing" ) + ( PinLpp list( "METAL5" "drawing" )) + ( PinOrigin list( 0 0 )) + ( PinTemplate list( + list( 0:0 0.36:0.36 ) + list( 0:0.72 0.36:1.08 ) + list( 0:1.44 0.36:1.80 ) + list( 0:2.16 0.36:2.52 ) + list( 0:2.88 0.36:3.24 ) + )) + ( BitPitch list( 0 19.2 )) + ( BitTemplate list( 0 15 1 )) + ( ChanName "SAMPLE_CHANNEL" ) + ( ChanTemplate list( "0" "1" "e" "2" "3" )) + ) + + let(( d_Pin + d_Net + currentPinTemplate + currentBitTemplate + currentbBox + currentX + currentY + currentChanName + tempChanName + bitCurrent bitEnd bitInc bitCurrent + LabelLpp + ) + + ; XY Coordinates + ; ============== + currentX = car( PinOrigin ) + currentY = cadr( PinOrigin ) + + LabelLpp = list( car( PinLpp ) LabelPurpose ) + + ; Set Up the Current Name + ; ======================= + if( BitTemplate + then + ChanName = sprintf( nil "%s[$$i]" ChanName ) + bitCurrent = car( BitTemplate ) + bitEnd = cadr( BitTemplate ) + bitInc = caddr( BitTemplate ) + else + bitCurrent = 0 + bitEnd = 0 + bitInc = 1 + ) + + if( ChanTemplate + then + ChanName = sprintf( nil "%s.$$k" ChanName ) + else + ChanTemplate = list( "nil" ) + ) + + + ; Processing Each Bit + ; =================== + while( bitCurrent <= bitEnd + + rexCompile( "\\$\\$i" ) + + tempChanName = ChanName + + tempChanName = rexReplace( tempChanName sprintf( nil "%n" bitCurrent) 0 ) + + for( k 0 length( ChanTemplate )-1 + + currentChan = nth( k ChanTemplate ) + rexCompile( "\\$\\$k" ) + currentChanName = tempChanName + currentChanName = rexReplace( currentChanName currentChan 0 ) + println( currentChanName ) + + + currentPinTemplate = nth( mod( k length( PinTemplate )) PinTemplate ) + + + currentbBox = list( list( currentX + caar( currentPinTemplate ) + currentY + cadar( currentPinTemplate ) + ) + list( currentX + caadr( currentPinTemplate ) + currentY + cadadr( currentPinTemplate ) + ) + ) + + ; First, draw the pin + ; =================== + d_Pin = dbCreateRect( geGetWindowCellView( ) + PinLpp + currentbBox + ) + + ; Second, Fill up Connectivity + ; ============================ + d_Net = dbMakeNet( geGetWindowCellView() currentChanName ) + dbCreatePin( d_Net d_Pin ) + + + ; Third, Put Labels + ; ================== + dbCreateLabel( geGetWindowCellView( ) + LabelLpp + list( currentX + caar( currentPinTemplate ) + ( caadr( currentPinTemplate ) - caar( currentPinTemplate )) / 2 + currentY + cadar( currentPinTemplate ) + ( cadadr( currentPinTemplate ) - cadar( currentPinTemplate )) / 2 + ) + currentChanName + "centerLeft" + "R0" + "stick" + 0.2 ) + + ); end for + + bitCurrent = bitCurrent + bitInc + currentX = currentX + car( BitPitch ) + currentY = currentY + cadr( BitPitch ) + + ); end while + + ; returnValue + ; =========== + currentX:currentY + + ); end let + +); end procedure + + +; From CAST +; ========== +; defchan TxFifoManagerChannels ()( +; // channels used by TX_OUT +; TxFifoManagerOutPort +TX_OUT; +; +; // status IO +; e1of4 -STATUS; // 2-bit, FIFO status channel, core -> glue +; e1of2 -NEW_CALENDAR; // 1-bit, start of new calendar, core -> glue +; +; // core states +; e1of2 -CORE_ERROR; // 1-bit, device fatal error, core -> glue +; e1of2 -GOOD_SYNC[0..1]; // 1-bit, is in good sync, core -> glue +; // Two signals are needed. Might come at +; // different times. +; e1of2 -TRAINING_ACTIVE; // 1-bit, is sending training pattern +; e1of2 -DIP2_ERROR; // 1-bit, status bad parity detected +; e1of2 -STALL; // 1-bit, stalled; data flow control +; +; // reset output +; e1of2 +nRST // hard reset command +; ){} +; +; defchan TxFifoManagerOutPort()( +; e1of4[4] +PORT_ADDR; // port ID channel +; e1of4[32] +DATA; // data channel +; e1of2[3] +LAST_BYTE; // number of valid bytes +; e1of4 +EOPS; // end-of-packet status channel +; e1of2 +SOP; // start-of-packet channel +; e1of2 +FBP // force-bad-parity channel +; ){} +; +; defchan TxFifoManagerNodes ()( +; +; // link layer configure +; node[8] +i_calendar_m; // calendar multiplicity +; node[8] +i_calendar_len; // calendar length +; node[1] +i_tsclk_edge; // status clock edge +; node[4] +i_max_bad_parity; // max number of bad parities to declare +; node[4] +i_min_good_parity;// min number of good parities to declare sync +; node[8] +i_alpha; // training sequence multiplicity +; node[32] +i_data_max_t; // DATA_MAX_T [?] +; node[8] +i_stall_wm_low; // FIFO watermark low +; node[8] +i_stall_wm_high // FIFO watermark high +; ){} + +procedure( DrawPins_TOP_TX( ) + + let(( e1of4onM5 + e1of2onM5 + X Y XY + ) + + X = 216 + Y = 76.8 + XY = X:Y + + e1of4onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:1.44 0.36:1.80 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.00 0.36:3.36 ) + list( 0:3.72 0.36:4.08 ) + ) + + e1of2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.72 0.36:4.08 ) + ) + + ONEof2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:3.72 0.36:4.08 ) + ) + + EonM5 = list( + list( 0:2.16 0.36:2.64 ) + ) + + e1of1onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + ) + + node4onM7 = list( + list( 0:1.00 0.36:1.40 ) + list( 0:1.80 0.36:2.20 ) + list( 0:2.60 0.36:3.00 ) + list( 0:3.40 0.36:3.80 ) + ) + + + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of1onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_s2aerr" + ?ChanTemplate list( "0" "e") + ) + +; // status IO +; e1of4 -STATUS; // 2-bit, FIFO status channel, core -> glue + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of4onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.STATUS" + ?ChanTemplate list( "0" "1" "e" "2" "3" ) + ) + +; e1of2 -NEW_CALENDAR; // 1-bit, start of new calendar, core -> glue + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.NEW_CALENDAR" + ?ChanTemplate list( "0" "e" "1" ) + ) +; +; // core states +; e1of2 -CORE_ERROR; // 1-bit, device fatal error, core -> glue + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.CORE_ERROR" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -GOOD_SYNC[0..1]; // 1-bit, is in good sync, core -> glue +; // Two signals are needed. Might come at +; // different times. + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 1 1 ) + ?ChanName "tx_channels.GOOD_SYNC" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -TRAINING_ACTIVE; // 1-bit, is sending training pattern + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.TRAINING_ACTIVE" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -DIP2_ERROR; // 1-bit, status bad parity detected + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.DIP2_ERROR" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -STALL; // 1-bit, stalled; data flow control + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.STALL" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; // reset output +; e1of2 +nRST // hard reset command + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.nRST" + ?ChanTemplate list( "0" "e" "1" ) + ) + +;checkpoint +; e1of2[3] +LAST_BYTE; // number of valid bytes + + TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate ONEof2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 2 1 ) + ?ChanName "tx_channels.TX_OUT.LAST_BYTE" + ?ChanTemplate list( "0" "1" ) + ) + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate EonM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "txsigconv._lastbyte01.le" + ?ChanTemplate nil + ) + + XY = car(XY):cadr(XY)+9.6 + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate EonM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "txsigconv._lastbyte2.le" + ?ChanTemplate nil + ) + +; e1of2 +SOP; // start-of-packet channel + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate ONEof2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.TX_OUT.SOP" + ?ChanTemplate list( "0" "1" ) + ) + +; e1of2 +FBP // force-bad-parity channel + + TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate ONEof2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_channels.TX_OUT.FBP" + ?ChanTemplate list( "0" "1" ) + ) + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate EonM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "txsigconv._sop_force_bad.le" + ?ChanTemplate nil + ) + + +; e1of4 +EOPS; ==> chantxdata[1] // end-of-packet status channel + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin list( X+0 Y+192 ) + ?PinTemplate e1of4onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "txsigconv.chantxdata[1]" + ?ChanTemplate list( "0" "1" "e" "2" "3" ) + ) + +; e1of4[32] +DATA; ==> chantxdata[4..35] // data channel +; e1of4[4] +PORT_ADDR; ==> chantxdata[36..39] // port ID channel + + TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of4onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 4 39 1 ) + ?ChanName "txsigconv.chantxdata" + ?ChanTemplate list( "0" "1" "e" "2" "3" ) + ) + + + X = 216 + Y = 76.8 + XY = X:Y + + +; All "tx_nodes" changed to "tx_core" +; node[8] +i_calendar_m; // calendar multiplicity + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 7 1 ) + ?ChanName "tx_core.i_calendar_m" + ?ChanTemplate nil + ) + +; node[8] +i_calendar_len; // calendar length + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 7 1 ) + ?ChanName "tx_core.i_calendar_len" + ?ChanTemplate nil + ) + +; node[1] +i_tsclk_edge; // status clock edge + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "tx_core.i_tsclk_edge" + ?ChanTemplate nil + ) + +; node[4] +i_max_bad_parity; // max number of bad parities to declare + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 3 1 ) + ?ChanName "tx_core.i_max_bad_parity" + ?ChanTemplate nil + ) + +; node[4] +i_min_good_parity;// min number of good parities to declare sync + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 3 1 ) + ?ChanName "tx_core.i_max_good_parity" + ?ChanTemplate nil + ) + +; node[8] +i_alpha; // training sequence multiplicity + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 7 1 ) + ?ChanName "tx_core.i_alpha" + ?ChanTemplate nil + ) + +; node[32] +i_data_max_t; // DATA_MAX_T [?] + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 4.8 ) + ?BitTemplate list( 0 31 1 ) + ?ChanName "tx_core.i_data_max_t" + ?ChanTemplate nil + ) + +; node[8] +i_stall_wm_low; // FIFO watermark low + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 7 1 ) + ?ChanName "tx_core.i_stall_wm_low" + ?ChanTemplate nil + ) + +; node[8] +i_stall_wm_high // FIFO watermark high + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) + ?PinOrigin XY + ?PinTemplate node4onM7 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 7 1 ) + ?ChanName "tx_core.i_stall_wm_high" + ?ChanTemplate nil + ) + + ); end let + +); end procedure + + + + + + + + + +; =============================================================================================================== + +procedure( DrawPins_TOP_RX( ) + + let(( e1of4onM5 + e1of2onM5 + X Y XY + ) + + X = 259.2 + Y = 76.8 + XY = X:Y + + e1of4onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:1.44 0.36:1.80 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.00 0.36:3.36 ) + list( 0:3.72 0.36:4.08 ) + ) + + e1of3onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:1.44 0.36:1.80 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.00 0.36:3.36 ) + ) + + e1of2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.72 0.36:4.08 ) + ) + + ONEof2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:3.72 0.36:4.08 ) + ) + + EonM5 = list( + list( 0:2.16 0.36:2.64 ) + ) + + e1of1onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + ) + + node4onM7 = list( + list( 0:1.00 0.36:1.40 ) + list( 0:1.80 0.36:2.20 ) + list( 0:2.60 0.36:3.00 ) + list( 0:3.40 0.36:3.80 ) + ) + + + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of1onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 3 1 ) + ?ChanName "rx_s2aerr" + ?ChanTemplate list( "0" "e") + ) + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of1onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "rx_watchdog_intr" + ?ChanTemplate list( "0" "e" ) + ) + + +; defchan RxFifoManagerChannels ()( +; +; e1of2 -WATCHDOG; // watchdog (pseudo-clock ticks) +; e1of2 -DATA_VALID; // data inputs +; e1of4[4] -ADDRESS; +; e1of4[32] -DATA; +; e1of2[3] -MOD; +; e1of4 -EOPS; +; e1of2 -SOP; +; e1of2 -BAD_PARITY; +; e1of2 -SOP_ADDR_BAD_PARITY; +; +; e1of2 -ALT_DATA_VALID; +; e1of4[4] -ALT_ADDRESS; // alternative data inputs +; e1of4[16] -ALT_DATA; +; e1of4 -ALT_MOD; +; e1of4 -ALT_EOPS; +; e1of2 -ALT_SOP; +; e1of2 -ALT_BAD_PARITY; +; e1of2 -ALT_SOP_ADDR_BAD_PARITY; +; +; e1of2 -CALENDAR_RD; // configure calendar +; e1of4[4] -CALENDAR_RDADDR; +; e1of4[2] +CALENDAR_RDDATA; +; e1of3 +STATUS; // status outputs +; e1of4[2] +STATUS_ADDRESS; +; e1of2 -ERROR; // core monitor +; e1of2 -GOOD_SYNC; +; e1of2 -TRAINING_ACTIVE; +; // e1of4[16] -CAPTURE_DATA_TRAIN; +; e1of2[5] +SELECT_DATA_TRAIN; +; e1of2 +nRST // reset output +; ){} + + +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.WATCHDOG" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.DATA_VALID" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_channels.ADDRESS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 31 1 ) ?ChanName "rx_channels.DATA" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 2 1 ) ?ChanName "rx_channels.MOD" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.EOPS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.SOP" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.SOP_ADDR_BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_DATA_VALID" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_channels.ALT_ADDRESS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 15 1 ) ?ChanName "rx_channels.ALT_DATA" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_MOD" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_EOPS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_SOP" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_SOP_ADDR_BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.CALENDAR_RD" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_channels.CALENDAR_RDADDR" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 1 1 ) ?ChanName "rx_channels.CALENDAR_RDDATA" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of3onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.STATUS" ?ChanTemplate list( "0" "1" "e" "2" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 1 1 ) ?ChanName "rx_channels.STATUS_ADDRESS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ERROR" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.GOOD_SYNC" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.TRAINING_ACTIVE" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 4 1 ) ?ChanName "rx_channels.SELECT_DATA_TRAIN" ?ChanTemplate list( "0" "e" "1" )) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.nRST" ?ChanTemplate list( "0" "e" "1" )) + + + + + X = 259.2 + Y = 76.8 + XY = X:Y + + +; defchan RxFifoManagerNodes ()( +; +; node[8] +CALENDAR_LEN; +; node[8] +CALENDAR_M; +; node[1] +RSCLK_EDGE; +; node[4] +MIN_GOOD_PARITY; // misc configure outputs +; node[4] +MAX_BAD_PARITY; +; node[4] +AVERAGE; + +; node[1] +ENABLE_MANUAL_DESKEW; +; node[1] +ENABLE_STATIC_DESKEW; +; node[1] +ENABLE_REALTIME_TUNING; +; node[85] +MANUAL_DESKEW +; ){} +; + + +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "rx_core.i_calendar_len" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "rx_core.i_calendar_m" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_core.i_rsclk_edge" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_core.i_min_good_parity" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_core.i_max_bad_parity" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_core.i_average" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_core.i_enable_manual_deskew" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_core.i_enable_static_deskew" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_core.i_enable_realtime_tuning" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 84 1 ) ?ChanName "rx_core.i_manual_deskew" ?ChanTemplate nil ) +if( cadr(XY)>=576 then XY=297.6:cadr(XY)) + + ); end let + +); end procedure + + + +; =============================================================================================================== +; =============================================================================================================== +; =============================================================================================================== +; =============================================================================================================== + +procedure( DrawPins_TX_FM( ) + + let(( e1of4onM5 + e1of2onM5 + X Y XY + ) + + X = 1012.8 - 28.8 - 4.8 + Y = 1056 + XY = X:Y + + e1of4onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:1.44 0.36:1.80 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.00 0.36:3.36 ) + list( 0:3.72 0.36:4.08 ) + ) + + e1of2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.72 0.36:4.08 ) + ) + + ONEof2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:3.72 0.36:4.08 ) + ) + + EonM5 = list( + list( 0:2.16 0.36:2.64 ) + ) + + e1of1onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + ) + + node4onM7 = list( + list( 0:1.00 0.36:1.40 ) + list( 0:1.80 0.36:2.20 ) + list( 0:2.60 0.36:3.00 ) + list( 0:3.40 0.36:3.80 ) + ) + + + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of1onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "S2AERR" + ?ChanTemplate list( "0" "e") + ) + +; // status IO +; e1of4 -STATUS; // 2-bit, FIFO status channel, core -> glue + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of4onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.STATUS" + ?ChanTemplate list( "0" "1" "e" "2" "3" ) + ) + +; e1of2 -NEW_CALENDAR; // 1-bit, start of new calendar, core -> glue + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.NEW_CALENDAR" + ?ChanTemplate list( "0" "e" "1" ) + ) +; +; // core states +; e1of2 -CORE_ERROR; // 1-bit, device fatal error, core -> glue + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.CORE_ERROR" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -GOOD_SYNC[0..1]; // 1-bit, is in good sync, core -> glue +; // Two signals are needed. Might come at +; // different times. + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 1 1 ) + ?ChanName "CHAN.GOOD_SYNC" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -TRAINING_ACTIVE; // 1-bit, is sending training pattern + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.TRAINING_ACTIVE" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -DIP2_ERROR; // 1-bit, status bad parity detected + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.DIP2_ERROR" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 -STALL; // 1-bit, stalled; data flow control + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.STALL" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; // reset output +; e1of2 +nRST // hard reset command + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.nRST" + ?ChanTemplate list( "0" "e" "1" ) + ) + +;checkpoint +; e1of2[3] +LAST_BYTE; // number of valid bytes + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 2 1 ) + ?ChanName "CHAN.TX_OUT.LAST_BYTE" + ?ChanTemplate list( "0" "e" "1" ) + ) + +; e1of2 +SOP; // start-of-packet channel + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate ONEof2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.TX_OUT.SOP" + ?ChanTemplate list( "0" "1" ) + ) + +; e1of2 +FBP // force-bad-parity channel + + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of2onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.TX_OUT.FBP" + ?ChanTemplate list( "0" "e" "1" ) + ) + + +; e1of4 +EOPS; ==> chantxdata[1] // end-of-packet status channel + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin list( X+0 Y+192 ) + ?PinTemplate e1of4onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "CHAN.TX_OUT.EOPS" + ?ChanTemplate list( "0" "1" "e" "2" "3" ) + ) + +; e1of4[32] +DATA; ==> chantxdata[4..35] // data channel +; e1of4[4] +PORT_ADDR; ==> chantxdata[36..39] // port ID channel + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of4onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 31 1 ) + ?ChanName "CHAN.TX_OUT.DATA" + ?ChanTemplate list( "0" "1" "e" "2" "3" ) + ) + + TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of4onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 3 1 ) + ?ChanName "CHAN.TX_OUT.PORT_ADDR" + ?ChanTemplate list( "0" "1" "e" "2" "3" ) + ) + + + +; All "tx_nodes" changed to "tx_core" +; node[8] +i_calendar_m; // calendar multiplicity +; ========================================================== + + X = 1012.8 - 28.8 - 4.8 + Y = 1056 + XY= X:Y + + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "NODE.i_calendar_m" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "NODE.i_calendar_len" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "NODE.i_tsclk_edge" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "NODE.i_max_bad_parity" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "NODE.i_max_good_parity" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "NODE.i_alpha" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 4.8 ) ?BitTemplate list( 0 31 1 ) ?ChanName "NODE.i_data_max_t" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "NODE.i_stall_wm_low" ?ChanTemplate nil ) + XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "NODE.i_stall_wm_high" ?ChanTemplate nil ) + + ); end let + +); end procedure + +; =============================================================================================================== +; =============================================================================================================== +; =============================================================================================================== +; =============================================================================================================== + +; =============================================================================================================== + +procedure( DrawPins_RX_FM( ) + + let(( e1of4onM5 + e1of2onM5 + X Y XY + ) + + X = 259.2 + 1440 + Y = 76.8 + 316.8 + XY = X:Y + + e1of4onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:1.44 0.36:1.80 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.00 0.36:3.36 ) + list( 0:3.72 0.36:4.08 ) + ) + + e1of3onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:1.44 0.36:1.80 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.00 0.36:3.36 ) + ) + + e1of2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + list( 0:3.72 0.36:4.08 ) + ) + + ONEof2onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:3.72 0.36:4.08 ) + ) + + EonM5 = list( + list( 0:2.16 0.36:2.64 ) + ) + + e1of1onM5 = list( + list( 0:0.72 0.36:1.08 ) + list( 0:2.16 0.36:2.64 ) + ) + + node4onM7 = list( + list( 0:1.00 0.36:1.40 ) + list( 0:1.80 0.36:2.20 ) + list( 0:2.60 0.36:3.00 ) + list( 0:3.40 0.36:3.80 ) + ) + + + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of1onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate list( 0 3 1 ) + ?ChanName "rx_s2aerr" + ?ChanTemplate list( "0" "e") + ) + + XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) + ?PinOrigin XY + ?PinTemplate e1of1onM5 + ?BitPitch list( 0 9.6 ) + ?BitTemplate nil + ?ChanName "rx_watchdog_intr" + ?ChanTemplate list( "0" "e" ) + ) + + +; defchan RxFifoManagerChannels ()( +; +; e1of2 -WATCHDOG; // watchdog (pseudo-clock ticks) +; e1of2 -DATA_VALID; // data inputs +; e1of4[4] -ADDRESS; +; e1of4[32] -DATA; +; e1of2[3] -MOD; +; e1of4 -EOPS; +; e1of2 -SOP; +; e1of2 -BAD_PARITY; +; e1of2 -SOP_ADDR_BAD_PARITY; +; +; e1of2 -ALT_DATA_VALID; +; e1of4[4] -ALT_ADDRESS; // alternative data inputs +; e1of4[16] -ALT_DATA; +; e1of4 -ALT_MOD; +; e1of4 -ALT_EOPS; +; e1of2 -ALT_SOP; +; e1of2 -ALT_BAD_PARITY; +; e1of2 -ALT_SOP_ADDR_BAD_PARITY; +; +; e1of2 -CALENDAR_RD; // configure calendar +; e1of4[4] -CALENDAR_RDADDR; +; e1of4[2] +CALENDAR_RDDATA; +; e1of3 +STATUS; // status outputs +; e1of4[2] +STATUS_ADDRESS; +; e1of2 -ERROR; // core monitor +; e1of2 -GOOD_SYNC; +; e1of2 -TRAINING_ACTIVE; +; // e1of4[16] -CAPTURE_DATA_TRAIN; +; e1of2[5] +SELECT_DATA_TRAIN; +; e1of2 +nRST // reset output +; ){} + + +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.WATCHDOG" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.DATA_VALID" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_channels.ADDRESS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 31 1 ) ?ChanName "rx_channels.DATA" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 2 1 ) ?ChanName "rx_channels.MOD" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.EOPS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.SOP" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.SOP_ADDR_BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_DATA_VALID" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_channels.ALT_ADDRESS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 15 1 ) ?ChanName "rx_channels.ALT_DATA" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_MOD" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_EOPS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_SOP" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ALT_SOP_ADDR_BAD_PARITY" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.CALENDAR_RD" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_channels.CALENDAR_RDADDR" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 1 1 ) ?ChanName "rx_channels.CALENDAR_RDDATA" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of3onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.STATUS" ?ChanTemplate list( "0" "1" "e" "2" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of4onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 1 1 ) ?ChanName "rx_channels.STATUS_ADDRESS" ?ChanTemplate list( "0" "1" "e" "2" "3" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.ERROR" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.GOOD_SYNC" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.TRAINING_ACTIVE" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 4 1 ) ?ChanName "rx_channels.SELECT_DATA_TRAIN" ?ChanTemplate list( "0" "e" "1" )) +XY=TR_DrawPins( ?PinLpp list( "METAL5" "pin" ) ?PinOrigin XY ?PinTemplate e1of2onM5 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_channels.nRST" ?ChanTemplate list( "0" "e" "1" )) + + + + + X = 259.2 + 1440 + Y = 76.8 + 316.8 + XY = X:Y + + +; defchan RxFifoManagerNodes ()( +; +; node[8] +CALENDAR_LEN; +; node[8] +CALENDAR_M; +; node[1] +RSCLK_EDGE; +; node[4] +MIN_GOOD_PARITY; // misc configure outputs +; node[4] +MAX_BAD_PARITY; +; node[4] +AVERAGE; + +; node[1] +ENABLE_MANUAL_DESKEW; +; node[1] +ENABLE_STATIC_DESKEW; +; node[1] +ENABLE_REALTIME_TUNING; +; node[85] +MANUAL_DESKEW +; ){} +; + + +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "rx_nodes.i_calendar_len" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 7 1 ) ?ChanName "rx_nodes.i_calendar_m" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_nodes.i_rsclk_edge" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_nodes.i_min_good_parity" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_nodes.i_max_bad_parity" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 3 1 ) ?ChanName "rx_nodes.i_average" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_nodes.i_enable_manual_deskew" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_nodes.i_enable_static_deskew" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate nil ?ChanName "rx_nodes.i_enable_realtime_tuning" ?ChanTemplate nil ) +XY=TR_DrawPins( ?PinLpp list( "METAL7" "pin" ) ?PinOrigin XY ?PinTemplate node4onM7 ?BitPitch list( 0 9.6 ) ?BitTemplate list( 0 84 1 ) ?ChanName "rx_nodes.i_manual_deskew" ?ChanTemplate nil ) + + ); end let + +); end procedure + + + +; =============================================================================================================== +; =============================================================================================================== +; =============================================================================================================== +; =============================================================================================================== diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ExtendConnDepth.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ExtendConnDepth.il new file mode 100644 index 0000000000..affb043ecb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_ExtendConnDepth.il @@ -0,0 +1,186 @@ + + + +procedure( TR_ExtendConnDepth_ProcMain( @key + ( WorkOnAll nil ) + ( ConnDepth 2 ) + ) + + let(( l_Cell Cell + ) + + if( WorkOnAll + then + geSelectAllFig( ) + ); end if + + l_Cell = setof( x geGetSelectedSet( ) x->net->name && !member( x->net->name list( "Vdd" "GND" ))) + + geDeselectAllFig( ) + + foreach( Cell l_Cell +; println( Cell->net->name) + geSelectFig( Cell ) + TR_ExtendConnDepth_ProcProcessOnePin( ?d_Pin Cell ?ConnDepth ConnDepth ) + ); end foreach + + t + + ); end let + +); end procedure + + + + +procedure( TR_ExtendConnDepth_ProcProcessOnePin( @key + ( d_Pin car(geGetSelectedSet())) + ( ConnDepth 2 ) + ) + + let(( l_Overlapped Overlapped + ) + + l_Overlapped = dbGetTrueOverlaps( geGetWindowCellView( ) + d_Pin->bBox + car( d_Pin->lpp ) + ConnDepth + ) + + foreach( Overlapped l_Overlapped + + TR_ExtendConnDepth_ProcDrawShape( Overlapped car( d_Pin->lpp ) 0:0 1 1 d_Pin->net->name ) + + ); end foreach + +; println( l_Overlapped ) + + t + + ); end let + +); end procedure + +procedure( TR_ExtendConnDepth_ProcDrawShape( d_object + layer + xyOffset + xMultiplier + yMultiplier + pinName + @key ( DebugOn nil ) + ) + + let(( l_Overlapped Overlapped Parent + XL XH YL YH + currentbBox currentPath + xOffset yOffset + d_Pin d_Net + l_point point + PinLayer PinPurpose + ) + + xOffset = car( xyOffset ) + yOffset = cadr( xyOffset ) + + ; If the input object is a shape + ; ============================== + if( car( d_object->lpp ) == layer && member( d_object->objType list( "path" "rect" )) + then + XL = xMultiplier*caar( d_object->bBox ) + xOffset + XH = xMultiplier*caadr( d_object->bBox ) + xOffset + YL = yMultiplier*cadar( d_object->bBox ) + yOffset + YH = yMultiplier*cadadr( d_object->bBox ) + yOffset + + currentbBox = list( XL:YL XH:YH ) + + DebugOn && printf( "TR_ExtendConnDepth_ProcDrawShape --> %L \n" currentbBox ) + + + PinLayer = layer + PinPurpose = "drawing" + + ; First, draw the pin + case( d_object->objType + ( "rect" + d_Pin = dbCreateRect( geGetWindowCellView( ) list( PinLayer PinPurpose ) currentbBox ) + ) + ( "path" + + l_point = d_object->points + currentPath = nil + + foreach( point l_point + currentPath = cons( list( xMultiplier*car(point) + xOffset + yMultiplier*cadr(point) + yOffset ) + currentPath ) + ); end foreach + + d_Pin = dbCreatePath( geGetWindowCellView( ) list( PinLayer PinPurpose ) currentPath d_object->width) + ) + ); end case + + ; Second, Fill up Connectivity + d_Net = dbMakeNet( geGetWindowCellView() pinName ) + dbCreatePin( d_Net d_Pin ) + + ); end if + + + ; If the input object is a list ==> need to further tranverse the tree + ; ==================================================================== + if( listp( d_object ) && !member( car( d_object )->objType list( "mosaic" "mosaicInst" )) + then + + l_Overlapped = cdr( d_object ) + Parent = car( d_object ) + + xOffset = xMultiplier*car( Parent->xy ) + xOffset + yOffset = yMultiplier*cadr( Parent->xy ) + yOffset + + case( Parent->orient + + ( "MY" + xMultiplier = -xMultiplier + yMultiplier = yMultiplier + + ); end MY + + ( "MX" + xMultiplier = xMultiplier + yMultiplier = -yMultiplier + + ); end MX + + ( "R0" + xMultiplier = xMultiplier + yMultiplier = yMultiplier + ) + + ( t + DebugOn && + printf( "TR_ExtendConnDepth_ProcDrawShape --> Orientation \"%s\" NOT Supported\n" + Parent->orient + ) + ) + + ); end case + + foreach( Overlapped l_Overlapped + TR_ExtendConnDepth_ProcDrawShape( Overlapped layer xOffset:yOffset xMultiplier yMultiplier pinName ) + ); end foreach + + + ); end if + + t + + ); end let + +); end procedure + + + + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FindInstance.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FindInstance.il new file mode 100644 index 0000000000..2ddab9a8bd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FindInstance.il @@ -0,0 +1,227 @@ +; This will report all +; 1. cellName +; 2. instName +; 3. viewName +; on all selected instance ONLY +; CheckName( ?viewName `( nil "crap" ) ?cellName `( nil "lib.buffer.half.MBUF_1of2.0_L1")) +; +; WildCard Usage "*" matches 1+ occurance of any character if "*" appears as the first character +; else matches 0+ occurance +; +; WildCard Usage "+" matches 0+ occurance of any number and the "-" charater +; +; Support Special Character List = "[" "]" "-" "." "," + + +procedure( FindInstance( @key + ( cellName list( t nil ) ) + ( viewName list( t nil ) ) + ( instName list( t nil ) ) + ( WorkOnAll t ) + ) + + let( ( returnValue + CellMatch + Counter + l_d_Selected) + + returnValue = t + CellMatch = t + Counter = 0 + + if( WorkOnAll + then + geSelectAllFig() + ) + + l_d_Selected = geGetSelectedSet() + + geDeselectAllFig() + + foreach( d_Selected l_d_Selected + + if( d_Selected->objType == "inst" + then + CellMatch = t + ; Compile Patterns for cellName + if( !car( cellName ) && CellMatch + then + rexCompile( ConvertWildCardString( cadr( cellName ) ) ) + CellMatch = rexExecute( d_Selected->cellName ) + ); end if + + ; Compile Patterns for cellName + if( !car( viewName ) && CellMatch + then + rexCompile( ConvertWildCardString( cadr( viewName ) ) ) + CellMatch = rexExecute( d_Selected->viewName ) + ); end if + + ; Compile Patterns for instName + if( !car( instName ) && CellMatch + then + rexCompile( ConvertWildCardString( cadr( instName ) ) ) + CellMatch = rexExecute( d_Selected->name ) + ); end if + + + if( CellMatch + then + Counter = Counter + 1 + printf( "FindInstance --> %3n %-45s %-15s %-15s\n" + Counter + d_Selected->cellName + d_Selected->viewName + d_Selected->name + ) + geSelectFig( d_Selected ) + ) + ) + + ); end foreach + + if( Counter == 0 + then + printf( "FindInstance --> No Match Cells\n" ) + else + printf( "FindInstance --> Number Matched = %n\n" Counter ) + ) + + returnValue + + ); end let + +); end procedure + + +; WildCard String Converter +procedure( ConvertWildCardString( InputString @key ( FullString t ) ) + + let( ( OutputString ) + + if( FullString + then + InputString = strcat( "^" InputString ) + InputString = strcat( InputString "$" ) + ) + + rexCompile( "\\." ) + InputString = rexReplace( InputString "\\\\." 0 ) + + rexCompile( "\\[" ) + InputString = rexReplace( InputString "\\\\[" 0 ) + + rexCompile( "\\]" ) + InputString = rexReplace( InputString "\\\\]" 0 ) + + rexCompile( "\\-" ) + InputString = rexReplace( InputString "\\\\-" 0 ) + + rexCompile( "\\," ) + InputString = rexReplace( InputString "\\\\," 0 ) + + rexCompile( "\\*" ) + InputString = rexReplace( InputString ".*" 0 ) + + rexCompile( "\\+" ) + InputString = rexReplace( InputString "[0-9\\\\-]*" 0 ) + + rexCompile( "^\\^\\.\\*" ) + InputString = rexReplace( InputString "^.+" 0 ) + + OutputString = InputString + + ); end let + +); end procedure + + +; This is the GUI Portion +procedure( TR_FindInstance( ) + + let( ( TR_FindInstance + TR_FindInstance_cellName + TR_FindInstance_ySnap ) + + TR_FindInstance_cellName = hiCreateStringField( + ?name 'TR_FindInstance_cellName + ?prompt "Enter cellName (t = search all)" + ?defValue "t" + ?editable t ) + + TR_FindInstance_viewName = hiCreateStringField( + ?name 'TR_FindInstance_viewName + ?prompt "Enter viewName (t = search all)" + ?defValue "t" + ?editable t ) + + TR_FindInstance_instName = hiCreateStringField( + ?name 'TR_FindInstance_instName + ?prompt "Enter instName (t = search all)" + ?defValue "t" + ?editable t ) + + + TR_FindInstance_WorkOnAll = hiCreateRadioField( + ?name 'TR_FindInstance_WorkOnAll + ?choices list( "Selected Objects Only" "All Objects" ) + ?prompt "Work on" + ?defValue "All Objects" + ) + + TR_FindInstance_Form = hiCreateAppForm( + ?name 'TR_FindInstance_Form + ?fields '( TR_FindInstance_cellName + TR_FindInstance_viewName + TR_FindInstance_instName + TR_FindInstance_WorkOnAll ) + ?callback "TR_FindInstance_CB( hiGetCurrentForm() )" + ) + + + hiDisplayForm( TR_FindInstance_Form ) + + ); end let + +); end procedure + + +procedure( TR_FindInstance_CB( theForm ) + + if( theForm->TR_FindInstance_cellName->value == "t" + then + FindInstance_cellName = list( t t ) + else + FindInstance_cellName = list( nil theForm->TR_FindInstance_cellName->value ) + ) + + if( theForm->TR_FindInstance_viewName->value == "t" + then + FindInstance_viewName = list( t t ) + else + FindInstance_viewName = list( nil theForm->TR_FindInstance_viewName->value ) + ) + + if( theForm->TR_FindInstance_instName->value == "t" + then + FindInstance_instName = list( t t ) + else + FindInstance_instName = list( nil theForm->TR_FindInstance_instName->value ) + ) + + if( theForm->TR_FindInstance_WorkOnAll->value == "All Objects" + then + FindInstance_WorkOnAll = t + else + FindInstance_WorkOnAll = nil + ) + + FindInstance( ?cellName FindInstance_cellName + ?viewName FindInstance_viewName + ?instName FindInstance_instName + ?WorkOnAll FindInstance_WorkOnAll + ) + +); end procedure + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FloorplanArray.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FloorplanArray.il new file mode 100644 index 0000000000..819b698f8c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_FloorplanArray.il @@ -0,0 +1,241 @@ +; custom skill functions + +; return list of array indices from an instance name +(defun GetIndices ( name ) + ind = (list) + (foreach substring (parseString name "[]") + (if (sscanf substring "%d" i) == 1 then ind = (append1 ind i)) + ) + ind + ) + +; Aligns an array of cells using transformation: +; (x,y) = Sum_i {(dx_i, dy_i) * index_i} +; normal example (ArrayCells (list 4.8:0 0:9.6)) +; transposed example (ArrayCells (list 0:9.6 4.8:0)) +; +; ArrayCells( list( 15:0 0:38.4 ) ?WildCardString "slk_ex[+].mb[+]") +; +(defun ArrayCells ( matrix @key ( WildCardString nil ) + ( Inline t ) + ) + + ; Local Variables + let(( minX x xx + minY y yy + ) + + if( WildCardString && WildCardString != "ENTER WILDCARD STRING" && WildCardString != "" + then + geDeselectAllFig( ) + FindInstance( ?instName list( nil WildCardString )) + ) + + SelectedCellList = geGetSelSet( ) + + ; Initiate minX and minY to the right hand corner of the bBox + minX = caadr( geGetWindowCellView( )->bBox ) + minY = cadadr( geGetWindowCellView( )->bBox ) + + (foreach SelectedCell SelectedCellList + (if SelectedCell->objType == "inst" then + + ; parse indices from instance name + name = SelectedCell -> name + indices = (GetIndices name) + + ; get current coordinates + x = (car SelectedCell -> xy ) + y = (cadr SelectedCell -> xy ) + + ; compute offset + xDiff = -x + yDiff = -y + (foreach xy matrix + dx = (car xy) + dy = (cadr xy) + index = (car indices) + indices = (cdr indices) + (cond ((and index!=nil (atom dx) (atom dy)) + xDiff = xDiff + dx * index + yDiff = yDiff + dy * index + ) + ((and index!=nil (nth index xy)!=nil) + xDiff = xDiff + (car (nth index xy)) + yDiff = yDiff + (cadr (nth index xy)) + ) + ) + ) + + + ; move instance + dbMoveFig( SelectedCell, nil, (list xDiff:yDiff "R0")) + + ; get current coordinates + x = (car SelectedCell -> xy ) + y = (cadr SelectedCell -> xy ) + + ; Update minX and minY + if( ( y <= minY && x < minX ) || ( x <= minX && y < minY ) + then + minX = x + minY = y + xx = xDiff + yy = yDiff + ) + + else + ; ignore non instances + geDeselectObject( SelectedCell ) + ) + ) + + ; Move based on minX and minY + if( Inline + then + foreach( SelectedCell SelectedCellList + + dbMoveFig( SelectedCell, nil, (list -xx:-yy "R0")) + ) + ) + + ); end let + t +) + +; Wraparound GUI +procedure( TR_FloorplanArray( ) + + let( ( TR_FloorplanArray + TR_FloorplanArray_xOffset + TR_FloorplanArray_yOffset ) + + TR_FloorplanArray_Matrix = hiCreateStringField( + ?name 'TR_FloorplanArray_Matrix + ?prompt "Matrix List" + ?defValue "0:2.88*8" + ?editable t ) + + TR_FloorplanArray_InlineField = hiCreateToggleField( + ?name 'TR_FloorplanArray_InlineField + ?prompt "Inline" + ?choices list( list( `Inline "Yes" ) ) + ?defValue list( t ) + ) + + TR_FloorplanArray_WorkOnSelectedField = hiCreateToggleField( + ?name 'TR_FloorplanArray_WorkOnSelectedField + ?prompt "Manual Select" + ?choices list( list( `WorkOnSelected "Yes" ) ) + ?defValue list( t ) + ?callback list( "TR_FloorplanArray_WorkOnSelectedField_CB( hiGetCurrentForm() )" ) + ) + + TR_FloorplanArray_WildCardStringField = hiCreateStringField( + ?name 'TR_FloorplanArray_WildCardStringField + ?defValue "ENTER WILDCARD STRING" + ?editable nil + ) + + TR_FloorplanArray_Form = hiCreateAppForm( + ?name 'TR_FloorplanArray_Form + ?fields list( + list( TR_FloorplanArray_InlineField 0:0 150:30 100 ) + list( TR_FloorplanArray_Matrix 200:0 200:30 100 ) + list( TR_FloorplanArray_WorkOnSelectedField 0:30 150:30 100 ) + list( TR_FloorplanArray_WildCardStringField 200:30 200:30 0 ) + ) + ?callback "ArrayCells( evalstring( sprintf( nil \"list(%s)\" TR_FloorplanArray_Form->TR_FloorplanArray_Matrix->value )) + ?WildCardString TR_FloorplanArray_WildCardStringField->value + ?Inline TR_FloorplanArray_InlineField->Inline->value + )" + ) + + hiDisplayForm( TR_FloorplanArray_Form ) + + ); end let + +); end procedure + +; =========================================================================== +; TR_FloorplanArray_WorkOnSelectedField_CB( hiGetCurrentForm() ) +; =========================================================================== +procedure( TR_FloorplanArray_WorkOnSelectedField_CB( theForm ) + + if( !theForm->TR_FloorplanArray_WorkOnSelectedField->WorkOnSelected->value + then + theForm->TR_FloorplanArray_WildCardStringField->editable = t + theForm->TR_FloorplanArray_WildCardStringField->value = "" + else + theForm->TR_FloorplanArray_WildCardStringField->editable = nil + theForm->TR_FloorplanArray_WildCardStringField->value = theForm->TR_FloorplanArray_WildCardStringField->defValue + ) + + +); end procedure + + + + + + + +; handy binds +hiSetBindKey( "Layout" "KP_4" "(MoveSelected -0.01 0)") +hiSetBindKey( "Layout" "KP_6" "(MoveSelected 0.01 0)") +hiSetBindKey( "Layout" "KP_2" "(MoveSelected 0 -0.01)") +hiSetBindKey( "Layout" "KP_8" "(MoveSelected 0 0.01)") + +hiSetBindKey( "Layout" "KP_4" "(MoveSelected -0.48 0)") +hiSetBindKey( "Layout" "KP_6" "(MoveSelected 0.48 0)") +hiSetBindKey( "Layout" "KP_2" "(MoveSelected 0 -0.48)") +hiSetBindKey( "Layout" "KP_8" "(MoveSelected 0 0.48)") + +; Align pcells on minimum grid +(defun AlignPCells () + + SelectedCellList = geGetSelSet( ) + + (foreach SelectedCell SelectedCellList + + (if SelectedCell->objType == "inst" then + + xGrid = 0.01 + yGrid = 0.01 + + xCord = (car SelectedCell -> xy ) + yCord = (cadr SelectedCell -> xy ) + + ; Move to negative x direction + xDiff1 = (( xCord / xGrid ) - floor( xCord / xGrid )) * xGrid + + ; Move to negative y direction + yDiff1 = (( yCord / yGrid ) - floor( yCord / yGrid )) * yGrid + + ; Move to positive x direction + xDiff2 = (( xCord / xGrid ) - floor( ( xCord / xGrid ) + 1 )) * xGrid + + ; Move to positive y direction + yDiff2 = (( yCord / yGrid ) - floor( ( yCord / yGrid ) + 1 )) * yGrid + + ; Find the closest + (if ((abs xDiff1) > (abs xDiff2)) + then + xDiff = xDiff2 + else + xDiff = xDiff1 + ) + (if ((abs yDiff1) > (abs yDiff2)) + then + yDiff = yDiff2 + else + yDiff = yDiff1 + ) + + dbMoveFig( SelectedCell, nil, list(-xDiff:-yDiff "R0")) + ) + ) + ) + +; bind it +hiSetBindKey( "Layout" "KP_Enter" "(AlignPCells)") diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_Floorplanner.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_Floorplanner.il new file mode 100644 index 0000000000..5f51789442 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_Floorplanner.il @@ -0,0 +1,1156 @@ +; Global Variable Used: +; 1. TR_Floorplanner_CellGroup_%n (use to display result after analysis) +; 2. TR_Floorplanner_CellGroup_x TR_Floorplanner_CellGroup_y (Form Coordinates) + +TR_Floorplanner_CellGroup_x = 0 +TR_Floorplanner_CellGroup_y = 0 +TR_Floorplanner_DatapathThreshold = 0.4 +TR_Floorplanner_Counter_Data = 0 +TR_Floorplanner_Counter_Ctrl = 0 +TR_Floorplanner_DatapathHeight = 0 +TR_Floorplanner_BitPitch = 0 +TR_Floorplanner_NumBits = 0 +TR_Floorplanner_WorkOnAll = t +TR_Floorplanner_ScanLine = nil + +; Set Reference Point for the form to (x,y)=(0,0) from the left top corner +hiSetFormPosition( 0:0 ) + +; ==================================================================================================== +; Main Function Dialog +; ==================================================================================================== +procedure( TR_Floorplanner( ) + + let( ( + TR_Floorplanner_LeafResolutionX TR_Floorplanner_LeafResolutionY + TR_Floorplanner_MidResolutionX TR_Floorplanner_MidResolutionY + TR_Floorplanner_AutoSaveField + TR_Floorplanner_StartCompaction + TR_Floorplanner_WorkOnAllField + TR_Floorplanner_ScanLineField + TR_Floorplanner_DatapathThresholdField + TR_Floorplanner_StartAnalysis + TR_Floorplanner_Separator1 + ) + + TR_Floorplanner_CellGroup_x = 0 + TR_Floorplanner_CellGroup_y = 0 + + TR_Floorplanner_LeafResolutionX = hiCreateFloatField( + ?name 'TR_Floorplanner_LeafResolutionX + ?prompt "Leaf Cell xSnap(um)" + ?defValue 0.24 + ) + + TR_Floorplanner_LeafResolutionY = hiCreateFloatField( + ?name 'TR_Floorplanner_LeafResolutionY + ?prompt "Leaf Cell ySnap(um)" + ?defValue 2*PowerGridPitch + ?enabled t + ) + + TR_Floorplanner_MidResolutionX = hiCreateFloatField( + ?name 'TR_Floorplanner_MidResolutionX + ?prompt "Mid Cell xSnap(um)" + ?defValue PowerGridPitch + ) + + TR_Floorplanner_MidResolutionY = hiCreateFloatField( + ?name 'TR_Floorplanner_MidResolutionY + ?prompt "Mid Cell ySnap(um)" + ?defValue 2*PowerGridPitch + ?enabled t + ) + + TR_Floorplanner_AutoSaveField = hiCreateToggleField( + ?name 'TR_Floorplanner_AutoSaveField + ?choices list( list( `AutoSave "AutoSave" )) + ?prompt "" + ?defValue list( nil ) + ?enabled t + ) + + + TR_Floorplanner_CompactionDepthField = hiCreateScaleField( + ?name `TR_Floorplanner_CompactionDepthField + ?prompt "Compaction Depth (\"-1\" = Current Cell Only)" + ?isContinuous t + ?range list( -1 32 ) + ?defValue -1 + ?enabled t + ) + + TR_Floorplanner_StartCompactionField = hiCreateButton( + ?name 'TR_Floorplanner_StartCompactionField + ?buttonText "Compaction" + ?callback "TR_Floorplanner_StartCompactionField_CB( hiGetCurrentForm() )" + ) + + TR_Floorplanner_WorkOnAllField = hiCreateRadioField( + ?name 'TR_Floorplanner_WorkOnAllField + ?choices list( "Selected Objects Only" "All Objects" ) + ?prompt "Work on" + ?defValue "All Objects" + ?callback list( "TR_Floorplanner_WorkOnAllField_CB( hiGetCurrentForm() )" ) + ) + + TR_Floorplanner_ScanLineField = hiCreateRadioField( + ?name 'TR_Floorplanner_ScanLineField + ?choices list( "Yes" "No" ) + ?prompt "Use Scan Line" + ?defValue "No" + ?callback list( "TR_Floorplanner_ScanLineField_CB( hiGetCurrentForm() )" ) + ) + + TR_Floorplanner_DatapathHeightField = hiCreateFloatField( + ?name 'TR_Floorplanner_DatapathHeightField + ?prompt "Datapath Height (um)" + ?defValue float( TR_Floorplanner_DatapathHeight ) + ?callback "TR_Floorplanner_DatapathHeightField_CB( hiGetCurrentForm() )" + ) + + TR_Floorplanner_BitPitchField = hiCreateFloatField( + ?name 'TR_Floorplanner_BitPitchField + ?prompt " Bit Pitch (um)" + ?defValue float( TR_Floorplanner_BitPitch ) + ?callback "TR_Floorplanner_BitPitchField_CB( hiGetCurrentForm() )" + ) + + TR_Floorplanner_NumBitsField = hiCreateIntField( + ?name 'TR_Floorplanner_NumBitsField + ?prompt " Number of Bits" + ?defValue TR_Floorplanner_NumBits + ?callback "TR_Floorplanner_NumBitsField_CB( hiGetCurrentForm() )" + ) + + TR_Floorplanner_DatapathThresholdField = hiCreateScaleField( + ?name `TR_Floorplanner_DatapathThresholdField + ?prompt "Datapath Threshold (%)" + ?callback "TR_Floorplanner_DatapathThresholdField_CB( hiGetCurrentForm() )" + ?isContinuous t + ?range list( 20 80 ) + ?defValue 40 + ?enabled t + ) + + TR_Floorplanner_StartAnalysis = hiCreateButton( + ?name 'TR_Floorplanner_StartAnalysis + ?buttonText "Analysis" + ?callback "TR_Floorplanner_StartAnalysis_CB( hiGetCurrentForm() )" + ) + + TR_Floorplanner_Separator1 = hiCreateSeparatorField( + ?name `TR_Floorplanner_Separator1 + ) + + TR_Floorplanner_Separator2 = hiCreateSeparatorField( + ?name `TR_Floorplanner_Separator2 + ) + + TR_Floorplanner_Form = hiCreateAppForm( + ?name 'TR_Floorplanner_Form + ?initialSize list( 1000 1500 ) + ?fields list( + list( TR_Floorplanner_LeafResolutionX 0:0 180:40 130 ) + list( TR_Floorplanner_LeafResolutionY 200:0 180:40 130 ) + + list( TR_Floorplanner_MidResolutionX 0:40 180:40 130 ) + list( TR_Floorplanner_MidResolutionY 200:40 180:40 130 ) + + list( TR_Floorplanner_AutoSaveField 500:0 100:40 00 ) + + list( TR_Floorplanner_CompactionDepthField 0:75 400:40 300 ) + list( TR_Floorplanner_StartCompactionField 420:88 180:30 180 ) + + + list( TR_Floorplanner_WorkOnAllField 0:120 400:40 100 ) + list( TR_Floorplanner_ScanLineField 400:120 200:40 100 ) + + list( TR_Floorplanner_DatapathHeightField 0:160 200:40 140 ) + list( TR_Floorplanner_BitPitchField 200:160 200:40 140 ) + list( TR_Floorplanner_NumBitsField 400:160 200:40 140 ) + + list( TR_Floorplanner_DatapathThresholdField 0:200 600:50 300 ) + + list( TR_Floorplanner_StartAnalysis 0:250 600:30 600 )) + +; ?buttonLayout list( `OKCancel list( `Spider\ 3\.0\.2 "TR_Floorplanner_VersionHistoryField_CB( )" ) ) +; ?buttonDisabled list( `OK `Help `Spider\ 3\.0\.2 ) + ?buttonLayout list( `OKCancel list( `SpiderVersionHistory "TR_Floorplanner_VersionHistoryField_CB( )" ) ) + ?buttonDisabled list( `OK `Help ) + ?callback "TR_Floorplanner_CB( hiGetCurrentForm() )" + ) + + TR_Floorplanner_CellGroup_y = TR_Floorplanner_CellGroup_y + 280 + + hiDisplayForm( TR_Floorplanner_Form ) + + ); end let + +); end procedure + + +; ==================================================================================================== +; TR_Floorplanner_VersionLogField CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_VersionHistoryField_CB( ) + + let(( TR_Floorplanner_VersionHistoryTextField + TR_Floorplanner_VersionHistoryTextForm + HistoryText + ) + + HistoryText = + "\n Spider 3.0.5 + \n -- Released May-29-2003 + \n -- Spider will now automatically filter out + \n non-instance cells + \n + \n Spider 3.0.4 + \n -- Released Jan-21-2003 + \n -- Added options to auto-align cells + \n after floorplanning + \n + \n Spider 3.0.3 + \n -- Released Jan-21-2003 + \n -- Fixed Small bug in AnalysisLayout.il + \n so that it will not match \"S1\" with \"S12\" + \n -- Cells are auto-aligned after Floorplanning + \n + \n Spider 3.0.2 + \n -- Released Jan-20-2003 + \n -- All arrays increase indicies + \n going upward (+y) or right (+x) + \n -- Added Version History Support" + + + TR_Floorplanner_VersionHistoryTextField = hiCreateMLTextField( + ?name `TR_Floorplanner_VersionHistoryTextField + ?defValue HistoryText + ?editable nil + ?enabled t + ) + + TR_Floorplanner_VersionHistoryTextForm = hiCreateAppForm( + ?name 'TR_Floorplanner_VersionHistoryTextForm + ?initialSize list( 500 500 ) + ?fields list( + list( TR_Floorplanner_VersionHistoryTextField 0:0 500:400 100 ) + ) + ) + + hiDisplayForm( TR_Floorplanner_VersionHistoryTextForm ) + + t + + ); end let + +); end procedure + + + +; ==================================================================================================== +; TR_Floorplanner_DatapathThreshold CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_DatapathThresholdField_CB( theForm ) + + TR_Floorplanner_DatapathThreshold = float( theForm->TR_Floorplanner_DatapathThresholdField->value ) / 100 + +); end procedure + + + + + +; ==================================================================================================== +; TR_Floorplanner_StartCompaction CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_StartCompactionField_CB( theForm ) + + if( theForm->TR_Floorplanner_CompactionDepthField->value >= 0 + then + theForm->TR_Floorplanner_WorkOnAllField->value = "All Objects" + TR_Floorplanner_WorkOnAll = t + ) + + CompactCellsResursive( ?Depth theForm->TR_Floorplanner_CompactionDepthField->value + ?WorkOnAll TR_Floorplanner_WorkOnAll + ?AlignToGrid list( theForm->TR_Floorplanner_LeafResolutionX->value:theForm->TR_Floorplanner_LeafResolutionY->value + theForm->TR_Floorplanner_MidResolutionX->value:theForm->TR_Floorplanner_MidResolutionY->value ) + ?AutoSave theForm->TR_Floorplanner_AutoSaveField->AutoSave->value + ) + +); end procedure + + + +; ==================================================================================================== +; TR_Floorplanner_WorkOnAll CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_WorkOnAllField_CB( theForm ) + + if( theForm->TR_Floorplanner_WorkOnAllField->value == "All Objects" + then + TR_Floorplanner_WorkOnAll = t + else + TR_Floorplanner_WorkOnAll = nil + ) + + +); end procedure + +; ==================================================================================================== +; TR_Floorplanner_ScanLine CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_ScanLineField_CB( theForm ) + + if( theForm->TR_Floorplanner_ScanLineField->value == "Yes" + then + TR_Floorplanner_ScanLine = t + else + TR_Floorplanner_ScanLine = nil + ) + + +); end procedure + +; ==================================================================================================== +; TR_Floorplanner_DatapathHeight CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_DatapathHeightField_CB( theForm ) + + TR_Floorplanner_DatapathHeight = theForm->TR_Floorplanner_DatapathHeightField->value + +); end procedure + + +; ==================================================================================================== +; TR_Floorplanner_BitPitch CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_BitPitchField_CB( theForm ) + + TR_Floorplanner_BitPitch = theForm->TR_Floorplanner_BitPitchField->value + TR_Floorplanner_DatapathHeight = TR_Floorplanner_BitPitch * TR_Floorplanner_NumBits + theForm->TR_Floorplanner_DatapathHeightField->value = TR_Floorplanner_DatapathHeight + +); end procedure + + +; ==================================================================================================== +; TR_Floorplanner_NumBits CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_NumBitsField_CB( theForm ) + + TR_Floorplanner_NumBits = theForm->TR_Floorplanner_NumBitsField->value + TR_Floorplanner_DatapathHeight = TR_Floorplanner_BitPitch * TR_Floorplanner_NumBits + theForm->TR_Floorplanner_DatapathHeightField->value = TR_Floorplanner_DatapathHeight + +); end procedure + + +; ==================================================================================================== +; TR_Floorplanner_StartAnalysis CallBack Function +; ==================================================================================================== +procedure( TR_Floorplanner_StartAnalysis_CB( theForm ) + + let( ( + ;l_CellGroup + l_TR_Floorplanner_CellGroup + CleanPreviousRun + Height_CellGroup + ) + + CleanPreviousRun = t + Height_CellGroup = 35 + + ; ==================================================================================================== + ; Deleting Previous Fields + ; ==================================================================================================== + l_TR_Floorplanner_CellGroup = nil + Counter = 1 + while( ( CleanPreviousRun && boundp( `l_CellGroup ) ) + + if( evalstring( sprintf( nil "boundp( `TR_Floorplanner_CellGroup_%n )" Counter)) && + evalstring( sprintf( nil "TR_Floorplanner_CellGroup_%n->usedIn" Counter)) + then + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_CellGroup_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_TypeField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_OrderField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_OrientationField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_OrderHashingField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + TR_Floorplanner_CellGroup_y = TR_Floorplanner_CellGroup_y - Height_CellGroup + ) + + if( Counter == length( l_CellGroup) + then + + CleanPreviousRun = nil + + ); end if + Counter = Counter + 1 + + + ); end while + + hiDeleteFields( theForm l_TR_Floorplanner_CellGroup ) + + l_CellGroup = AnalysisLayout( ?WorkOnAll TR_Floorplanner_WorkOnAll + ?DatapathThreshold TR_Floorplanner_DatapathThreshold + ?ScanLine TR_Floorplanner_ScanLine + ?DatapathHeight TR_Floorplanner_DatapathHeight + ) + + theForm->TR_Floorplanner_DatapathHeightField->value = TR_Floorplanner_DatapathHeight + + + ; ==================================================================================================== + ; Create Display Options Field + ; ==================================================================================================== + ; draw only if the variable exists OR it's not already on the GUI + + if( !boundp( `TR_Floorplanner_DisplayOptions ) || !TR_Floorplanner_DisplayOptions->usedIn + then + + TR_Floorplanner_DisplayOptions = hiCreateToggleField( + ?name 'TR_Floorplanner_DisplayOptions + ?choices list( list( `All "All" ) + list( `None "None") + list( `D3 "3-D" ) + list( `D2 "2-D" ) + list( `D1 "1-D" ) + list( `D0 "0-D" ) + list( `Data "Data") + list( `Ctrl "Ctrl")) + ?prompt "Display Options" + ?callback list( "TR_Floorplanner_DisplayOptions_CB_All( hiGetCurrentForm() )" + "TR_Floorplanner_DisplayOptions_CB_None( hiGetCurrentForm() )" + "TR_Floorplanner_DisplayOptions_CB_Else( hiGetCurrentForm() )" + "TR_Floorplanner_DisplayOptions_CB_Else( hiGetCurrentForm() )" + "TR_Floorplanner_DisplayOptions_CB_Else( hiGetCurrentForm() )" + "TR_Floorplanner_DisplayOptions_CB_Else( hiGetCurrentForm() )" + "TR_Floorplanner_DisplayOptions_CB_Else( hiGetCurrentForm() )" + "TR_Floorplanner_DisplayOptions_CB_Else( hiGetCurrentForm() )" + ) + ?defValue list( nil t nil nil nil nil nil nil ) + ) + + + TR_Floorplanner_DisplayApply = hiCreateButton( + ?name 'TR_Floorplanner_DisplayApply + ?buttonText "Refresh Display" + ?callback "TR_Floorplanner_DisplayApply_CB( hiGetCurrentForm() )" + ) + + TR_Floorplanner_StartFloorplan = hiCreateButton( + ?name 'TR_Floorplanner_StartFloorplan + ?buttonText "Floorplan without Auto-alignment" + ?callback "TR_Floorplanner_StartFloorplan_CB( hiGetCurrentForm() ?AutoAlign nil )" + ) + + TR_Floorplanner_StartFloorplanWithAlign = hiCreateButton( + ?name 'TR_Floorplanner_StartFloorplanWithAlign + ?buttonText "Floorplan with Auto-alignment" + ?callback "TR_Floorplanner_StartFloorplan_CB( hiGetCurrentForm() ?AutoAlign t )" + ) + + + hiAddFields( theForm list( list( TR_Floorplanner_DisplayOptions + TR_Floorplanner_CellGroup_x:TR_Floorplanner_CellGroup_y + 500:30 + 120 ) + list( TR_Floorplanner_DisplayApply + 500:TR_Floorplanner_CellGroup_y + 100:30 + 0 ) + list( TR_Floorplanner_StartFloorplan + TR_Floorplanner_CellGroup_x:TR_Floorplanner_CellGroup_y+30 + 300:30 + 0 ) + list( TR_Floorplanner_StartFloorplanWithAlign + TR_Floorplanner_CellGroup_x+300:TR_Floorplanner_CellGroup_y+30 + 300:30 + 0 ) + )) + + + TR_Floorplanner_CellGroup_y = TR_Floorplanner_CellGroup_y + 60 + ) + + + + ); end let + +); end procedure + + + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayOptions_CB_All( theForm ) + + if( theForm->TR_Floorplanner_DisplayOptions->All->value + then + theForm->TR_Floorplanner_DisplayOptions->D3->value = t + theForm->TR_Floorplanner_DisplayOptions->D2->value = t + theForm->TR_Floorplanner_DisplayOptions->D1->value = t + theForm->TR_Floorplanner_DisplayOptions->D0->value = t + theForm->TR_Floorplanner_DisplayOptions->Data->value = t + theForm->TR_Floorplanner_DisplayOptions->Ctrl->value = t + theForm->TR_Floorplanner_DisplayOptions->None->value = nil + ) + +); end procedure + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayOptions_CB_None( theForm ) + + if( theForm->TR_Floorplanner_DisplayOptions->None->value + then + theForm->TR_Floorplanner_DisplayOptions->D3->value = nil + theForm->TR_Floorplanner_DisplayOptions->D2->value = nil + theForm->TR_Floorplanner_DisplayOptions->D1->value = nil + theForm->TR_Floorplanner_DisplayOptions->D0->value = nil + theForm->TR_Floorplanner_DisplayOptions->Data->value = nil + theForm->TR_Floorplanner_DisplayOptions->Ctrl->value = nil + theForm->TR_Floorplanner_DisplayOptions->All->value = nil + ) + +); end procedure + + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayOptions_CB_Else( theForm ) + + + if( ( theForm->TR_Floorplanner_DisplayOptions->D3->value && + theForm->TR_Floorplanner_DisplayOptions->D2->value && + theForm->TR_Floorplanner_DisplayOptions->D1->value && + theForm->TR_Floorplanner_DisplayOptions->D0->value ) || + ( theForm->TR_Floorplanner_DisplayOptions->Data->value && + theForm->TR_Floorplanner_DisplayOptions->Ctrl->value ) + + + then + + theForm->TR_Floorplanner_DisplayOptions->All->value = t + theForm->TR_Floorplanner_DisplayOptions->None->value = nil + else + theForm->TR_Floorplanner_DisplayOptions->All->value = nil + ) + + if( ( theForm->TR_Floorplanner_DisplayOptions->D3->value || + theForm->TR_Floorplanner_DisplayOptions->D2->value || + theForm->TR_Floorplanner_DisplayOptions->D1->value || + theForm->TR_Floorplanner_DisplayOptions->D0->value || + theForm->TR_Floorplanner_DisplayOptions->Data->value || + theForm->TR_Floorplanner_DisplayOptions->Ctrl->value ) + + then + + theForm->TR_Floorplanner_DisplayOptions->None->value = nil + else + theForm->TR_Floorplanner_DisplayOptions->None->value = t + theForm->TR_Floorplanner_DisplayOptions->All->value = nil + ) + +); end procedure + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayApply_CB( theForm ) + + let( ( + ;l_CellGroup + l_TR_Floorplanner_CellGroup + CleanPreviousRun + Height_CellGroup + ) + + CleanPreviousRun = t + Height_CellGroup = 35 + + + ; ==================================================================================================== + ; Deleting Previous Fields + ; ==================================================================================================== + l_TR_Floorplanner_CellGroup = nil + Counter = 1 + while( CleanPreviousRun + + if( evalstring( sprintf( nil "boundp( `TR_Floorplanner_CellGroup_%n )" Counter)) && + evalstring( sprintf( nil "TR_Floorplanner_CellGroup_%n->usedIn" Counter)) + then + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_CellGroup_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_TypeField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_OrderField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_OrientationField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( `TR_Floorplanner_DisplayApply_CB_OrderHashingField_%n l_TR_Floorplanner_CellGroup )" Counter )) + + TR_Floorplanner_CellGroup_y = TR_Floorplanner_CellGroup_y - Height_CellGroup + ) + + if( Counter == length( l_CellGroup) + then + + CleanPreviousRun = nil + + ); end if + Counter = Counter + 1 + + + ); end while + + hiDeleteFields( theForm l_TR_Floorplanner_CellGroup ) + + + ; ==================================================================================================== + ; Add Current Fields + ; ==================================================================================================== + l_TR_Floorplanner_CellGroup = nil + for( i 0 length( l_CellGroup )-1 + + if( ( caar( nth( i l_CellGroup )) == 3 && theForm->TR_Floorplanner_DisplayOptions->D3->value ) || + ( caar( nth( i l_CellGroup )) == 2 && theForm->TR_Floorplanner_DisplayOptions->D2->value ) || + ( caar( nth( i l_CellGroup )) == 1 && theForm->TR_Floorplanner_DisplayOptions->D1->value ) || + ( caar( nth( i l_CellGroup )) == 0 && theForm->TR_Floorplanner_DisplayOptions->D0->value ) || + ( caadr( nth( i l_CellGroup )) == "Data" && theForm->TR_Floorplanner_DisplayOptions->Data->value ) || + ( caadr( nth( i l_CellGroup )) == "Ctrl" && theForm->TR_Floorplanner_DisplayOptions->Ctrl->value ) + + then + + + ; ============================================================================================= + ; Cell Group Field + evalstring( sprintf( nil "TR_Floorplanner_CellGroup_%n = + hiCreateStringField( + ?name 'TR_Floorplanner_CellGroup_%n + ?prompt \"%n\" + ?defValue cadddr( nth( %n l_CellGroup )) + ?editable nil)" + i+1 + i+1 + i+1 + i) + ) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( + list( TR_Floorplanner_CellGroup_%n + TR_Floorplanner_CellGroup_x:TR_Floorplanner_CellGroup_y + 150:Height_CellGroup + 30 ) + l_TR_Floorplanner_CellGroup )" i+1 )) + + + ; ============================================================================================= + ; CellType Field + evalstring( sprintf( nil "TR_Floorplanner_DisplayApply_CB_TypeField_%n = + hiCreateRadioField( + ?name 'TR_Floorplanner_DisplayApply_CB_TypeField_%n + ?choices list( \"Data\" \"Ctrl\" ) + ?defValue caadr( nth( %n l_CellGroup )) + ?callback list( \"TR_Floorplanner_DisplayApply_CB_TypeField_CB( hiGetCurrentForm() %n )\" ))" + i+1 + i+1 + i + i) + ) + + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( + list( TR_Floorplanner_DisplayApply_CB_TypeField_%n + 150:TR_Floorplanner_CellGroup_y + 120:Height_CellGroup + 0 ) + l_TR_Floorplanner_CellGroup )" i+1 )) + + + + ; ============================================================================================= + ; CellOrdering Field + + evalstring( sprintf( nil "TR_Floorplanner_DisplayApply_CB_OrderField_%n = + hiCreateScaleField( + ?name 'TR_Floorplanner_DisplayApply_CB_OrderField_%n + ?isContinuous t + ?range list( 1 evalstring( strcat( \"TR_Floorplanner_Counter_\" caadr( nth( %n l_CellGroup ))))) + ?defValue cadadr( nth( %n l_CellGroup )) + ?callback \"TR_Floorplanner_DisplayApply_CB_OrderField_CB( hiGetCurrentForm() %n )\" )" + i+1 + i+1 + i + i + i) + ) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( + list( TR_Floorplanner_DisplayApply_CB_OrderField_%n + 270:TR_Floorplanner_CellGroup_y + 130:Height_CellGroup + 0 ) + l_TR_Floorplanner_CellGroup )" i+1 )) + + + ; ============================================================================================= + ; CellOrientation Field + + case( evalstring( sprintf( nil "caar( nth( %n l_CellGroup ))" i)) + + ( 0 + FieldChoices = list( "NA" ) + FieldEnabled = nil + ) + + ( 1 + FieldChoices = list( "V" "H" ) + FieldEnabled = t + ) + + ( 2 + FieldChoices = list( "HV" "VH" ) + FieldEnabled = t + ) + ) + + + + evalstring( sprintf( nil "TR_Floorplanner_DisplayApply_CB_OrientationField_%n = + hiCreateRadioField( + ?name 'TR_Floorplanner_DisplayApply_CB_OrientationField_%n + ?choices FieldChoices + ?defValue cadar( nth( %n l_CellGroup )) + ?callback list( \"TR_Floorplanner_DisplayApply_CB_OrientationField_CB( hiGetCurrentForm() %n )\" ) + ?enabled FieldEnabled )" + i+1 + i+1 + i + i) + ) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( + list( TR_Floorplanner_DisplayApply_CB_OrientationField_%n + 400:TR_Floorplanner_CellGroup_y + 100:Height_CellGroup + 0 ) + l_TR_Floorplanner_CellGroup )" i+1 )) + + + ; ============================================================================================= + ; Order Hashing Field + + evalstring( sprintf( nil "TR_Floorplanner_DisplayApply_CB_OrderHashingField_%n = + hiCreateListField( + ?name 'TR_Floorplanner_DisplayApply_CB_OrderHashingField_%n + ?callback \"TR_Floorplanner_DisplayApply_CB_OrderHashingField_CB( hiGetCurrentForm() %n )\" + ?defValue caddar( nth( %n l_CellGroup )) + ?editable t)" + i+1 + i+1 + i + i) + ) + + evalstring( sprintf( nil + "l_TR_Floorplanner_CellGroup = cons( + list( TR_Floorplanner_DisplayApply_CB_OrderHashingField_%n + 500:TR_Floorplanner_CellGroup_y + 100:Height_CellGroup + 0 ) + l_TR_Floorplanner_CellGroup )" i+1 )) + + + TR_Floorplanner_CellGroup_y = TR_Floorplanner_CellGroup_y + Height_CellGroup + + ); end if + + ); end foreach + + + hiAddFields( theForm l_TR_Floorplanner_CellGroup ) + + ; ==================================================================================================== + + ); end let + +) + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayApply_CB_TypeField_CB( theForm index ) + + let( ( CellGroup_Old + CellGroup_New + Type_Old + Type_New + ) + + Type_Old = caadr( nth( index l_CellGroup ) ) + Order_Old = cadadr( nth( index l_CellGroup ) ) + + evalstring( sprintf( nil "Type_New = theForm->TR_Floorplanner_DisplayApply_CB_TypeField_%n->value" index+1 )) + + case( Type_Old + + ( "Data" + for( i Order_Old TR_Floorplanner_Counter_Data + evalstring( sprintf( nil "theForm->TR_Floorplanner_DisplayApply_CB_OrderField_%n->value = i" index+1 )) + ) + + TR_Floorplanner_Counter_Data = TR_Floorplanner_Counter_Data - 1 + TR_Floorplanner_Counter_Ctrl = TR_Floorplanner_Counter_Ctrl + 1 + CellGroup_New = subst( list( "Ctrl" TR_Floorplanner_Counter_Ctrl ) list( Type_Old TR_Floorplanner_Counter_Data+1 ) nth(index l_CellGroup)) + + CellGroup_Old = nth( index l_CellGroup ) + ) + + ( "Ctrl" + for( i Order_Old TR_Floorplanner_Counter_Ctrl + evalstring( sprintf( nil "theForm->TR_Floorplanner_DisplayApply_CB_OrderField_%n->value = i" index+1 )) + ) + + TR_Floorplanner_Counter_Data = TR_Floorplanner_Counter_Data + 1 + TR_Floorplanner_Counter_Ctrl = TR_Floorplanner_Counter_Ctrl - 1 + CellGroup_New = subst( list( "Data" TR_Floorplanner_Counter_Data ) list( Type_Old TR_Floorplanner_Counter_Ctrl+1 ) nth(index l_CellGroup)) + CellGroup_Old = nth( index l_CellGroup ) + ) + + ); end case + + l_CellGroup = subst( CellGroup_New CellGroup_Old l_CellGroup ) + + ; Refresh the display + TR_Floorplanner_DisplayApply_CB( theForm ) + + ; Return Value + l_CellGroup + + ); end let + +) + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayApply_CB_OrderField_CB( theForm index ) + + let( ( CellGroup_Old + CellGroup_New + Order_Old + Order_New + + CellGroup_Old2 + CellGroup_New2 + Order_Old2 + Order_New2 + + ) + + CellGroup_Old = nth( index l_CellGroup ) + Order_Old = cadr( CellGroup_Old ) + + evalstring( sprintf( nil "Order_New = list( caadr( CellGroup_Old ) theForm->TR_Floorplanner_DisplayApply_CB_OrderField_%n->value)" index+1 )) + CellGroup_New = subst( Order_New Order_Old nth(index l_CellGroup)) + + l_CellGroup = subst( CellGroup_New CellGroup_Old l_CellGroup ) + + + for( i 0 length(l_CellGroup)-1 + + if( cadr( nth( i l_CellGroup )) == Order_New && i != index + + then + + + CellGroup_Old2 = nth( i l_CellGroup ) + Order_Old2 = cadr( CellGroup_Old2 ) + + Order_New2 = Order_Old + CellGroup_New2 = subst( Order_New2 Order_Old2 nth(i l_CellGroup)) + + l_CellGroup = subst( CellGroup_New2 CellGroup_Old2 l_CellGroup ) + + ) + + ) + + ; Can't do a Refresh on the display + ; since this is a recursive callback + + ); end let + +) + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayApply_CB_OrientationField_CB( theForm index ) + + let( ( CellGroup_Old + CellGroup_New + Orientation_Old + Orientation_New + ) + + CellGroup_Old = nth( index l_CellGroup ) + Orientation_Old = car( CellGroup_Old ) + + evalstring( sprintf( nil "Orientation_New = list( caar( CellGroup_Old ) + theForm->TR_Floorplanner_DisplayApply_CB_OrientationField_%n->value + caddar( CellGroup_Old ))" index+1 )) + CellGroup_New = subst( Orientation_New Orientation_Old nth(index l_CellGroup)) + + l_CellGroup = subst( CellGroup_New CellGroup_Old l_CellGroup ) + + ); end let + +);end procedure + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_DisplayApply_CB_OrderHashingField_CB( theForm index ) + + let( ( CellGroup_Old + CellGroup_New + OrderHashing_Old + OrderHashing_New + ) + + CellGroup_Old = nth( index l_CellGroup ) + OrderHashing_Old = car( CellGroup_Old ) + + evalstring( sprintf( nil "OrderHashing_New = list( caar( CellGroup_Old ) + cadar( CellGroup_Old ) + theForm->TR_Floorplanner_DisplayApply_CB_OrderHashingField_%n->value)" index+1 )) + CellGroup_New = subst( OrderHashing_New OrderHashing_Old nth(index l_CellGroup)) + + l_CellGroup = subst( CellGroup_New CellGroup_Old l_CellGroup ) + + ); end let + +);end procedure + + +; ==================================================================================================== +; Callback Function +; ==================================================================================================== +procedure( TR_Floorplanner_StartFloorplan_CB( theForm @key (DebugOn nil ) (AutoAlign nil)) + + let( ( Data_x Data_y Data_Width + Ctrl_x Ctrl_y Ctrl_Width + BitPitch + ) + + Data_x = 0 + Data_y = 0 + + Ctrl_x = 0 + Ctrl_y = 0 + + geDeselectAllFig() + + l_CellGroup = TR_Floorplanner_Sort_l_CellGroup( l_CellGroup ) + + foreach( CellGroup l_CellGroup + + DebugOn && printf( "TR_Floorplanner_StartFloorplan_CB --> Start Selecting Cells for CellGroup %s \n" cadddr( CellGroup )) + + foreach( Cell car( cddddr( CellGroup )) + + geSelectFig( Cell ) + + ); end foreach + + DebugOn && printf( "TR_Floorplanner_StartFloorplan_CB --> Forking to Procedure \"FloorplanCells\"\n") + + case( caadr( CellGroup ) + + ( "Data" + + if( TR_Floorplanner_NumBits == 0 + then + BitPitch = 0 + else + BitPitch = TR_Floorplanner_BitPitch + ) + + Data_Width = FloorplanCells( Data_x Data_y + ?Dimension caar( CellGroup ) + ?Type caadr( CellGroup ) + ?Orientation cadar( CellGroup ) + ?HashList eval( caddar( CellGroup )) + ?BitPitch BitPitch + ?DatapathHeight TR_Floorplanner_DatapathHeight + ?NumBitsPerCell 0 + ) + Data_x = Data_x + Data_Width + ) + + ( "Ctrl" + Ctrl_Width = FloorplanCells( Ctrl_x Ctrl_y + ?Dimension caar( CellGroup ) + ?Type caadr( CellGroup ) + ?Orientation cadar( CellGroup ) + ?HashList eval( caddar( CellGroup )) + ?BitPitch 0 + ?DatapathHeight 0 + ?NumBitsPerCell 0 + ) + Ctrl_x = Ctrl_x + Ctrl_Width + ) + + + ); end case + + geDeselectAllFig() + + );end foreach + + ; Refresh the display + TR_Floorplanner_DisplayApply_CB( theForm ) + + + ; Align everything to the corresponding power grid + if( AutoAlign + then + CompactCellsResursive( ?Depth -1 + ?WorkOnAll TR_Floorplanner_WorkOnAll + ?AlignToGrid list( theForm->TR_Floorplanner_LeafResolutionX->value:theForm->TR_Floorplanner_LeafResolutionY->value + theForm->TR_Floorplanner_MidResolutionX->value:theForm->TR_Floorplanner_MidResolutionY->value ) + ?AutoSave nil + ) + ); end if + + );end let + +); end procedure + + +; ==================================================================================================== +; Sorting Function +; ==================================================================================================== +procedure( TR_Floorplanner_Sort_l_CellGroup( l_CellGroup_Input ) + + let( ( l_CellGroup_returnValue + l_CellGroup_Data + l_CellGroup_Ctrl ) + + l_CellGroup_returnValue = nil + l_CellGroup_Data = nil + l_CellGroup_Ctrl = nil + + + foreach( CellGroup_Input l_CellGroup_Input + + if( caadr( CellGroup_Input ) == "Data" + then + l_CellGroup_Data = cons( list( cadadr( CellGroup_Input ) CellGroup_Input ) l_CellGroup_Data) + else + l_CellGroup_Ctrl = cons( list( cadadr( CellGroup_Input ) CellGroup_Input ) l_CellGroup_Ctrl) + + ) + + ); end foreach + + + l_CellGroup_Data = sortcar( l_CellGroup_Data `greaterp ) + l_CellGroup_Ctrl = sortcar( l_CellGroup_Ctrl `greaterp ) + + foreach( CellGroup_Ctrl l_CellGroup_Ctrl + + l_CellGroup_returnValue = cons( cadr( CellGroup_Ctrl ) l_CellGroup_returnValue ) + + ) + + foreach( CellGroup_Data l_CellGroup_Data + + l_CellGroup_returnValue = cons( cadr( CellGroup_Data ) l_CellGroup_returnValue ) + + ) + + l_CellGroup_returnValue + + ); end let + +); end procedure + + +; ==================================================================================================== +; Sorting Function ------------CURRENTLY FORBIDDEN----------------- +; ==================================================================================================== +procedure( TR_Floorplanner_Sort_l_Cell( l_Cell_Input l_Hash @key (Dimension 0 ) ( Orientation "NA" )) + + + let( ( l_Cell_returnValue + l_Cell_Temp ) + + l_Cell_returnValue = nil + l_Cell_Temp = nil + + + case( l_Hash + ( nil + ; Do Nothing + ) + + ( t + ) + + + ); end case + + + + ); end let + +); end procedure + + +;============================================================================== +; DUMMY CALLBACK FUNCTION +;============================================================================== +procedure( TR_Floorplanner_CB( theForm ) + + let(( returnValue ) + + printf( "TR_Floorplanner_CB --> Thankx for using Spider 2.0\n" ) + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GenerateBindingFile.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GenerateBindingFile.il new file mode 100644 index 0000000000..270d473d55 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GenerateBindingFile.il @@ -0,0 +1,91 @@ +; ====================================================================================================== +; This procedure is used to produce ("merge") the original binding file with the cellName.map file +; (obtained from the Cadence PIPO process) +; ====================================================================================================== + +procedure( TR_GenerateBindingFile( @key + ( InputCellMapFile "/home/user/samson/cds_wd/x8/cellName.map" ) + ( InputBindingFile "/home/user/samson/myassura/tsmc_pdk_v1.4/patched/bind.rul" ) + ( OutputBindingFile "/home/user/samson/cds_wd/x8/bind.rul" ) + ( DebugOn t ) + ) + let(( Line LineList + currentBindedCellList + inPort + outPort + skipLoop + ) + + outPort = outfile( OutputBindingFile ) + + ; Processing the Original Binding File + ; ======================================================== + currentBindedCellList = nil + inPort = infile( InputBindingFile ) + println( inPort ) + when( inPort + while( gets( Line inPort ) + + fprintf( outPort "%s" Line ) + + rexCompile( "^c" ) + if( rexExecute( Line ) + then + LineList = parseString( Line ) + currentBindedCellList = cons( nth( 1 LineList ) currentBindedCellList ) + ); end if + ); end while + ); end when + close( inPort ) + + + ; Processing the cellName.map file + ; ======================================================== + inPort = infile( InputCellMapFile ) + skipLoop = nil + + fprintf( outPort "; ====================================================\n" ) + fprintf( outPort "; The following Lines are inserted automatically\n" ) + fprintf( outPort "; by the Cadence Skill Script \n" ) + fprintf( outPort "; ====================================================\n" ) + + when( inPort + + while( gets( Line inPort ) + + skipLoop = nil + + ; Filter out cells from "gate" and "stack" + ; ======================================== + rexCompile( "^gate" ) + if( rexExecute( Line ) then skipLoop = t ) + + rexCompile( "^stack" ) + if( rexExecute( Line ) then skipLoop = t ) + + ; Filter out Comment Line + ; ======================= + rexCompile( "^\\#" ) + if( rexExecute( Line ) then skipLoop = t ) + + LineList = parseString( Line ) + + if( !skipLoop && !member( nth( 0 LineList ) currentBindedCellList ) + then + fprintf( outPort + "c %s %s\n" + nth( 0 LineList ) + nth( 2 LineList ) + ) + ); end if + + ); end while + + ); end when + + close( inPort ) + close( outPort ) + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GetManhattanDistance.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GetManhattanDistance.il new file mode 100644 index 0000000000..1d26920746 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_GetManhattanDistance.il @@ -0,0 +1,98 @@ +procedure( TR_GetManhattanDistance_ProcMain( @key + ( DebugOn t ) + ( WorkOnAll t ) + ( Filename "./TR_GetManhattanDistance.output.txt" ) + ( DumpFile t ) + ) + let(( outPort + l_Cell Cell + l_Pin Pin + l_MatchPin + l_return + P1 P1x P1y + P2 P2x P2y + distance + ) + + ; Perform on All Objects + ; ====================== + WorkOnAll && geSelectAllFig( ) + + ; Local Variables + ; =============== + l_Cell = geGetSelectedSet( ) + l_Cell = setof( x l_Cell x->objType == "inst" ) + l_return = nil + outPort = outfile( Filename ) + + ; Bring Up Inplace Pins + ; ===================== + foreach( Cell l_Cell + + DrawIO_ProcDrawInPlacePinsAndLabels( Cell ) + + ); end foreach + + ; Get Only Objects with Connectivity + ; ================================== + geSelectAllFig( ) + l_Pin = geGetSelectedSet( ) + l_Pin = setof( x l_Pin x->net->name ) + + ; Sort the List + ; ============= + l_Pin = foreach( mapcar Pin l_Pin + list( Pin->net->name Pin ) + ) + l_Pin = sortcar( l_Pin `alphalessp ) + l_Pin = foreach( mapcar Pin l_Pin + cadr( Pin ) + ) + + + ; Actual Processing + ; ================= + while( l_Pin + + l_MatchPin = setof( x l_Pin x->net->name == car( l_Pin )->net->name) + l_Pin = setof( x l_Pin !member( x l_MatchPin )) + l_return = append( l_return list( l_MatchPin )) + + if( DumpFile + + then + + case( length( l_MatchPin ) + + ( 2 + P1 = car( nth( 0 l_MatchPin )->bBox ) + P2 = car( nth( 1 l_MatchPin )->bBox ) + + P1x = car( P1 ) + P1y = cadr( P1 ) + + P2x = car( P2 ) + P2y = cadr( P2 ) + +; distance = round( sqrt( (P2y-P1y)*(P2y-P1y) + (P2x-P1x)*(P2x-P1x) )) + distance = round( abs(P2y-P1y) + abs(P2x-P1x)) + fprintf( outPort "%-35s %-4n\n" car( l_MatchPin )->net->name distance ) + + ) + + ); end case + + ); end if + + ); end while + + close( outPort ) + + ; Return Value + ; ============ + l_return + + ); end let + +); end procedure + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_HiLiteLabels.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_HiLiteLabels.il new file mode 100644 index 0000000000..3184d94424 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_HiLiteLabels.il @@ -0,0 +1,336 @@ +; This Script is use to add temp labels for all +; 1. rect +; 2. polygon +; 3. path +; +; Characteristics +; 1. The corresponding layer must be selected in order for the script to put labels on +; 2. Script only operates on the current screen view, does not always put labels on the +; entire layout (this actually minimize a lot of compute time) +; 3. All Labels are volatile => no write permission is required to draw labels +; Labels are drawn on hilite set +; +; Global Variable +; 1. AddHiLiteLabels_DB +; 2. AddHiLiteLabels_FontSize +; 3. AddHiLiteLabels_NetName + +AddHiLiteLabels_NetName = "ALL" +AddHiLiteLabels_FontSize = 0.02 +AddHiLiteLabels_DB = nil + +;( SuppressList list( nil list( "GND" "Vdd" ))) + + +procedure( AddHiLiteLabels( @key + ( DebugOn nil ) + ( SuppressList nil ) + ( SelectFig nil ) + ) + "This Script is use to add temp labels for all" + + let( ( l_d_Selected + returnValue + FontSize + NetName + SuppressedSourceList + SuppressedTargetList + ) + + returnValue = t + + AddHiLiteLabels_DB = nil + FontSize = AddHiLiteLabels_FontSize + NetName = AddHiLiteLabels_NetName +; SuppressedSourceList = car( SuppressList ) + SuppressedSourceList = list( "GND" "Vdd" "pdd") + SuppressedTargetList = cadr( SuppressList ) + + DebugOn && printf( "==================================================================================\n" ) + DebugOn && printf( "AddHiLiteLabels --> SuppressedSourceList = %L\n" SuppressedSourceList ) + DebugOn && printf( "AddHiLiteLabels --> SuppressedTargetList = %L\n" SuppressedTargetList ) + DebugOn && printf( "==================================================================================\n" ) + + ; Check to see if there is a hilite Set for this cellview + if( !geGetCurrentHilightSet( geGetWindowCellView()) + then + gePushHilightStack( geCreateHilightSet( geGetWindowCellView() list( "hilite" "drawing8" ) t )) + geGetCurrentHilightSet( geGetWindowCellView())->enable = t + + geDeselectAllFig() + +; geSingleSelectBox( +; geAddSelectBox( +; geGetCellViewWindow( geGetWindowCellView()) +; t +; geGetWindowBox( geGetCellViewWindow( geGetWindowCellView()) )) +; +; geSelectArea( geGetCellViewWindow( geGetWindowCellView()) +; geGetWindowBox( geGetCellViewWindow( geGetWindowCellView()) )) + + + l_d_Selected = dbGetOverlaps( geGetWindowCellView() + geGetWindowBox( geGetCellViewWindow( geGetWindowCellView()) )) + + +; l_d_Selected = geGetSelectedSet() +; geDeselectAllFig() + + foreach( d_Selected l_d_Selected + + SelectFig && geSelectFig( d_Selected ) + + case( d_Selected->objType + + ( "rect" + if( ( ( d_Selected->net->name && NetName == "ALL" ) + || d_Selected->net->name == NetName + ) + && !member( d_Selected->net->name SuppressedTargetList ) + then + geAddHilightLabel( + geGetCurrentHilightSet( geGetWindowCellView()) + car( d_Selected->bBox ) + d_Selected->net->name + "centerCenter" + "R0" + "stick" + FontSize + t + ) + + AddHiLiteLabels_DB = cons( car( d_Selected->bBox ) AddHiLiteLabels_DB ) + ); end if + ) + + ( "path" + if( ( ( d_Selected->net->name && NetName == "ALL" ) + || d_Selected->net->name == NetName + ) + && !member( d_Selected->net->name SuppressedTargetList ) + + then + geAddHilightLabel( + geGetCurrentHilightSet( geGetWindowCellView()) + car( d_Selected->points ) + d_Selected->net->name + "centerCenter" + "R0" + "stick" + FontSize + t + ) + AddHiLiteLabels_DB = cons( car( d_Selected->points ) AddHiLiteLabels_DB ) + ); end if + ) + + ( "inst" + + DebugOn && printf( "==================================================================================\n" ) + DebugOn && printf( "AddHiLiteLabels --> Processing Cell instName=\"%s\" cellName=\"%s\"\n" + d_Selected->name + d_Selected->cellName + ) + + x_inst = car( d_Selected->xy ) + y_inst = cadr( d_Selected->xy ) + + ; Go thru each instTerms (IO pins) + foreach( d_instTerm d_Selected->instTerms + + + DebugOn && printf( "AddHiLiteLabels --> --> Processing %12s -> %-12s\t" + sprintf( nil "\"%s\"" d_instTerm->name ) + sprintf( nil "\"%s\"" d_instTerm->net->name ) + ) + + x_instTerm = caar( car( d_instTerm->term->pins )->fig->bBox ) + y_instTerm = cadar( car( d_instTerm->term->pins )->fig->bBox ) + + ; This is necessary since some gate PCELL has layout change but + ; the terminal remains in the propagate net box + if( x_instTerm && y_instTerm + then + + case( d_Selected->orient + + ( "MY" + xy_instTerm = list( ( x_inst - x_instTerm ) + ( y_inst + y_instTerm )) + ) + + ( "MX" + xy_instTerm = list( ( x_inst + x_instTerm ) + ( y_inst - y_instTerm )) + ) + + ( "R90" + xy_instTerm = list( ( x_inst - y_instTerm ) + ( y_inst + x_instTerm )) + ) + + ( "R180" + xy_instTerm = list( ( x_inst - x_instTerm ) + ( y_inst - y_instTerm )) + ) + + ( t + xy_instTerm = list( ( x_inst + x_instTerm ) + ( y_inst + y_instTerm )) + ) + + + ); end case + + else + DebugOn && printf( + "\nAddHiLiteLabels --> --> --> Warning! No Physical Shape Found for this Terminal!!! Skip!!!\n") + + ); end xyTerm + + if( ( NetName == "ALL" || d_instTerm->net->name == NetName ) + && !member( d_instTerm->net->name SuppressedTargetList ) + && !member( d_instTerm->name SuppressedSourceList ) + && d_instTerm->net->name != nil + + then + geAddHilightLabel( + geGetCurrentHilightSet( geGetWindowCellView()) + xy_instTerm + sprintf( nil "%s->%s" + d_instTerm->name + d_instTerm->net->name + ) + "centerCenter" + "R0" + "stick" + FontSize + t + ) + + AddHiLiteLabels_DB = cons( xy_instTerm AddHiLiteLabels_DB ) + + ;printf( "Drawn!!!\n" ) + + ;else + ;printf( "Supressed!!!\n" ) + + + + );end if + + + ); end foreach + + ); end "inst" subcase + + + ); end case + ); end foreach + + else + + gePopHilightStack( geGetWindowCellView()) + + );end if + + if( AddHiLiteLabels_DB == nil + then + gePopHilightStack( geGetWindowCellView()) + + );end if + + returnValue + + ); end let + + +); end procedure + + +procedure( ZoomToHiLiteLabels( ) + + let( ( temp_xy + temp_bBox + temp_scale + returnValue + ) + + returnValue = t + + ; Check to see if there is a hilite Set for this cellview + if( !geGetCurrentHilightSet( geGetWindowCellView()) + then + printf( "ZoomToHiLiteLabels( )--> ERROR!!! You do NOT have any hilite labels at all!!!\n" ) + + else + + temp_xy = car( AddHiLiteLabels_DB ) + temp_scale = AddHiLiteLabels_FontSize * 5 + + + temp_bBox = list( + list( car( temp_xy )-temp_scale cadr( temp_xy )-temp_scale) + list( car( temp_xy )+temp_scale cadr( temp_xy )+temp_scale) + ) + + hiZoomIn( geGetCellViewWindow( geGetWindowCellView()) temp_bBox ) + + AddHiLiteLabels_DB = remove( temp_xy AddHiLiteLabels_DB ) + AddHiLiteLabels_DB = reverse( AddHiLiteLabels_DB ) + AddHiLiteLabels_DB = cons( temp_xy AddHiLiteLabels_DB ) + AddHiLiteLabels_DB = reverse( AddHiLiteLabels_DB ) + + );end if + + returnValue + + );end let + +); end procedure + + +; Simple GUI + +procedure( TR_AddHiLiteLabels( ) + + let( ( TR_AddHiLiteLabels + TR_AddHiLiteLabels_ + TR_AddHiLiteLabels_ySnap ) + + TR_AddHiLiteLabels_NetName = hiCreateStringField( + ?name 'TR_AddHiLiteLabels_NetName + ?prompt "Enter NetName" + ?defValue sprintf( nil "%s" AddHiLiteLabels_NetName ) + ?editable t ) + + TR_AddHiLiteLabels_FontSize = hiCreateStringField( + ?name 'TR_AddHiLiteLabels_FontSize + ?prompt "Enter FontSize" + ?defValue sprintf( nil "%n" AddHiLiteLabels_FontSize ) + ?editable t ) + + TR_AddHiLiteLabels_Form = hiCreateAppForm( + ?name 'TR_AddHiLiteLabels_Form + ?fields '( TR_AddHiLiteLabels_NetName TR_AddHiLiteLabels_FontSize ) + ?callback "TR_AddHiLiteLabels_CB( hiGetCurrentForm() )" + ) + + hiDisplayForm( TR_AddHiLiteLabels_Form ) + + ); end let + +); end procedure + + +procedure( TR_AddHiLiteLabels_CB( theForm ) + + AddHiLiteLabels_NetName = theForm->TR_AddHiLiteLabels_NetName->value + AddHiLiteLabels_FontSize = evalstring( theForm->TR_AddHiLiteLabels_FontSize->value ) + +); end procedure + + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_MoveAndSnap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_MoveAndSnap.il new file mode 100644 index 0000000000..a2eb8881fc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TR_MoveAndSnap.il @@ -0,0 +1,504 @@ +; global variables for alignment +MoveAndSnap_xSnap=PowerGridPitch +MoveAndSnap_ySnap=PowerGridPitch*2 + +MoveAndSnapGate_xSnap=GatePitch/2 +MoveAndSnapGate_ySnap=GatePitch + +; Check to See if the selected objects is out of window +procedure( TR_MoveAndSnap_ProcCheckWindow( @key + ( DebugOn t ) + ) + + let(( currentWindow currentWindowBox + currentSelectedSet currentSelected currentSelectedBox + numViolations + XL XH YL YH + XL0 XH0 YL0 YH0 + XL1 XH1 YL1 YH1 + lockedDirection + ) + + ; Local Variables + ; =============== + currentWindow = geGetCellViewWindow( geGetWindowCellView()) + currentSelectedSet = geGetSelectedSet( ) + numViolations = 1 + lockedDirection = nil + + XL = caar( car( currentSelectedSet )->bBox ) + YL = cadar( car( currentSelectedSet )->bBox ) + XH = caadr( car( currentSelectedSet )->bBox ) + YH = cadadr( car( currentSelectedSet )->bBox ) + + foreach( currentSelected currentSelectedSet + + XL1 = caar( currentSelected->bBox ) + YL1 = cadar( currentSelected->bBox ) + XH1 = caadr( currentSelected->bBox ) + YH1 = cadadr( currentSelected->bBox ) + + if( XL1 < XL + then + XL = XL1 + ); end if + + if( XH1 > XH + then + XH = XH1 + ); end if + + if( YL1 < YL + then + YL = YL1 + ); end if + + if( YH1 > YH + then + YH = YH1 + ); end if + ) + + currentSelectedBox = list( XL:YL XH:YH ) + + + + while( numViolations == 1 + + numViolations = 0 + + currentWindowBox = geGetWindowBox( currentWindow ) + + XL0 = caar( currentWindowBox ) + YL0 = cadar( currentWindowBox ) + XH0 = caadr( currentWindowBox ) + YH0 = cadadr( currentWindowBox ) + + ; If the selected object is out of bound on the top + if( YH > YH0 + then + numViolations = numViolations + 1 + if( lockedDirection != nil && lockedDirection != "n" + then + numViolations = numViolations + 1 + ); end if + lockedDirection = "n" + );end if + + ; If the selected object is out of bound on the bottom + if( YL < YL0 + then + numViolations = numViolations + 1 + if( lockedDirection != nil && lockedDirection != "s" + then + numViolations = numViolations + 1 + ); end if + lockedDirection = "s" + );end if + + ; If the selected object is out of bound on the left + if( XL < XL0 + then + numViolations = numViolations + 1 + if( lockedDirection != nil && lockedDirection != "w" + then + numViolations = numViolations + 1 + ); end if + lockedDirection = "w" + );end if + + ; If the selected object is out of bound on the right + if( XH > XH0 + then + numViolations = numViolations + 1 + if( lockedDirection != nil && lockedDirection != "e" + then + numViolations = numViolations + 1 + ); end if + lockedDirection = "e" + );end if + + + + ; Scroll ONLY if there is one Violation + ; ===================================== + if( numViolations == 1 + then + geScroll( currentWindow lockedDirection nil ) + DebugOn && printf( "TR_MoveAndSnap_ProcCheckWindow --> Scroll %s: currentWindowBox = %L objBox = %L\n" + lockedDirection + currentWindowBox + currentSelectedBox ) + ); end if + + + ); end while + + ); end let + +); end procedure + + + +; move one cell +(defun MoveAndSnap_MoveFig ( fig dx dy ) + (dbMoveFig fig nil (list (list dx dy) "R0")) + ) + +; move selected cells by specified offset +(defun MoveAndSnap_MoveSelected ( dx dy ) + (foreach fig (geGetSelSet) (MoveAndSnap_MoveFig fig dx dy)) + ) + +; move selected cells to closest alignment grid in each direction +(defun MoveAndSnap (dir @key (overwrite_xSnap nil) (overwrite_ySnap nil) (overwrite_fig nil) (overwrite_xy nil)) + (let (x xSnap y ySnap l_Selected) + + (if overwrite_fig then + l_Selected = ( list overwrite_fig) + else + l_Selected = (geGetSelectedSet) + ) + (if !overwrite_xSnap then + xSnap = (max MoveAndSnap_xSnap (GetMaxXAlignmentOfSet l_Selected)) + else + xSnap = overwrite_xSnap + ) + + (if !overwrite_ySnap then + ySnap = (max MoveAndSnap_ySnap (GetMaxYAlignmentOfSet l_Selected)) + else + ySnap = overwrite_ySnap + ) + + (foreach fig l_Selected + (if (IsInstanceAnchored fig) then + (printf "Not moving anchored instance %s.\n" fig->name) + else ;do the rest + + (if fig->objType == "inst" || fig->objType == "mosaic" then + (if overwrite_xy then + xOffSet = car( overwrite_xy ) - (car fig -> xy ) + yOffSet = cadr( overwrite_xy ) - (car (cdr fig -> xy )) + else + xOffSet = 0 + yOffSet = 0 + ) + + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (cond + ((equal dir "L") (MoveAndSnap_MoveFig fig (floor (x-0.005)/xSnap)*xSnap-x 0 )) + ((equal dir "R") (MoveAndSnap_MoveFig fig (ceiling (x+0.005)/xSnap)*xSnap-x 0 )) + ((equal dir "U") (MoveAndSnap_MoveFig fig 0 (ceiling (y+0.005)/ySnap)*ySnap-y )) + ((equal dir "D") (MoveAndSnap_MoveFig fig 0 (floor (y-0.005)/ySnap)*ySnap-y )) + + ((equal dir "A") + (if (abs (floor x/xSnap)*xSnap-x ) <= (abs (ceiling x/xSnap)*xSnap-x) then + (MoveAndSnap_MoveFig fig (floor x/xSnap)*xSnap-x 0 ) + else + (MoveAndSnap_MoveFig fig (ceiling x/xSnap)*xSnap-x 0 ) + ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (if (abs (ceiling y/ySnap)*ySnap-y ) <= (abs (floor y/ySnap)*ySnap-y ) then + (MoveAndSnap_MoveFig fig 0 (ceiling y/ySnap)*ySnap-y ) + else + (MoveAndSnap_MoveFig fig 0 (floor y/ySnap)*ySnap-y ) + ) + ) + + ((equal dir "AV") + (if (abs (ceiling y/ySnap)*ySnap-y ) <= (abs (floor y/ySnap)*ySnap-y ) then + (MoveAndSnap_MoveFig fig 0 (ceiling y/ySnap)*ySnap-y ) + else + (MoveAndSnap_MoveFig fig 0 (floor y/ySnap)*ySnap-y ) + ) + ) + + ((equal dir "AH") + (if (abs (floor x/xSnap)*xSnap-x ) <= abs( (ceiling x/xSnap)*xSnap-x) then + (MoveAndSnap_MoveFig fig (floor x/xSnap)*xSnap-x 0 ) + else + (MoveAndSnap_MoveFig fig (ceiling x/xSnap)*xSnap-x 0 ) + ) + ) + + ((equal dir "ARAV") + (MoveAndSnap_MoveFig fig (ceiling x/xSnap)*xSnap-x 0 ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + (if (abs (ceiling y/ySnap)*ySnap-y ) <= (abs (floor y/ySnap)*ySnap-y ) then + (MoveAndSnap_MoveFig fig 0 (ceiling y/ySnap)*ySnap-y ) + else + (MoveAndSnap_MoveFig fig 0 (floor y/ySnap)*ySnap-y ) + ) + ) + + ((equal dir "RUD") + (MoveAndSnap_MoveFig fig (ceiling (x+0.005)/xSnap)*xSnap-x 0 ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (MoveAndSnap_MoveFig fig 0 (ceiling (y+0.005)/ySnap)*ySnap-y ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (MoveAndSnap_MoveFig fig 0 (floor (y-0.005)/ySnap)*ySnap-y ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + ) + ) + ) + ) + ) + + ;removing this procedure call for Bug 13562 + ;TR_MoveAndSnap_ProcCheckWindow( ) + ); end let +) + +;Move Selected Gates/Stacks to the nearest poly pitch +(defun MoveAndSnapGate (dir @key (overwrite_xSnap nil) (overwrite_ySnap nil) (overwrite_fig nil) (overwrite_xy nil)) + (let (x xSnap y ySnap l_Selected) + + (if overwrite_fig then + l_Selected = ( list overwrite_fig) + else + l_Selected = (geGetSelectedSet) + ) + (if !overwrite_xSnap then + xSnap = (max MoveAndSnapGate_xSnap (GetMaxXAlignmentOfSet l_Selected)) + else + xSnap = overwrite_xSnap + ) + + (if !overwrite_ySnap then + ySnap = (max MoveAndSnapGate_ySnap (GetMaxYAlignmentOfSet l_Selected)) + else + ySnap = overwrite_ySnap + ) + + (foreach fig l_Selected + (if (IsInstanceAnchored fig) then + (printf "Not moving anchored instance %s.\n" fig->name) + else ;do the rest + + (if fig->objType == "inst" || fig->objType == "mosaic" then + (if overwrite_xy then + xOffSet = car( overwrite_xy ) - (car fig -> xy ) + yOffSet = cadr( overwrite_xy ) - (car (cdr fig -> xy )) + else + xOffSet = 0 + yOffSet = 0 + ) + + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (cond + ((equal dir "L") (MoveAndSnap_MoveFig fig (floor (x-0.005)/xSnap)*xSnap-x 0 )) + ((equal dir "R") (MoveAndSnap_MoveFig fig (ceiling (x+0.005)/xSnap)*xSnap-x 0 )) + ((equal dir "U") (MoveAndSnap_MoveFig fig 0 (ceiling (y+0.005)/ySnap)*ySnap-y )) + ((equal dir "D") (MoveAndSnap_MoveFig fig 0 (floor (y-0.005)/ySnap)*ySnap-y )) + + ((equal dir "A") + (if (abs (floor x/xSnap)*xSnap-x ) <= (abs (ceiling x/xSnap)*xSnap-x) then + (MoveAndSnap_MoveFig fig (floor x/xSnap)*xSnap-x 0 ) + else + (MoveAndSnap_MoveFig fig (ceiling x/xSnap)*xSnap-x 0 ) + ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (if (abs (ceiling y/ySnap)*ySnap-y ) <= (abs (floor y/ySnap)*ySnap-y ) then + (MoveAndSnap_MoveFig fig 0 (ceiling y/ySnap)*ySnap-y ) + else + (MoveAndSnap_MoveFig fig 0 (floor y/ySnap)*ySnap-y ) + ) + ) + + ((equal dir "AV") + (if (abs (ceiling y/ySnap)*ySnap-y ) <= (abs (floor y/ySnap)*ySnap-y ) then + (MoveAndSnap_MoveFig fig 0 (ceiling y/ySnap)*ySnap-y ) + else + (MoveAndSnap_MoveFig fig 0 (floor y/ySnap)*ySnap-y ) + ) + ) + + ((equal dir "AH") + (if (abs (floor x/xSnap)*xSnap-x ) <= abs( (ceiling x/xSnap)*xSnap-x) then + (MoveAndSnap_MoveFig fig (floor x/xSnap)*xSnap-x 0 ) + else + (MoveAndSnap_MoveFig fig (ceiling x/xSnap)*xSnap-x 0 ) + ) + ) + + ((equal dir "ARAV") + (MoveAndSnap_MoveFig fig (ceiling x/xSnap)*xSnap-x 0 ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + (if (abs (ceiling y/ySnap)*ySnap-y ) <= (abs (floor y/ySnap)*ySnap-y ) then + (MoveAndSnap_MoveFig fig 0 (ceiling y/ySnap)*ySnap-y ) + else + (MoveAndSnap_MoveFig fig 0 (floor y/ySnap)*ySnap-y ) + ) + ) + + ((equal dir "RUD") + (MoveAndSnap_MoveFig fig (ceiling (x+0.005)/xSnap)*xSnap-x 0 ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (MoveAndSnap_MoveFig fig 0 (ceiling (y+0.005)/ySnap)*ySnap-y ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + + (MoveAndSnap_MoveFig fig 0 (floor (y-0.005)/ySnap)*ySnap-y ) + x = (car fig -> xy ) + xOffSet + y = (car (cdr fig -> xy )) + yOffSet + ) + ) + ) + ) + ) + + ;removing this procedure call for Bug 13562 + ;TR_MoveAndSnap_ProcCheckWindow( ) + ); end let +) + + +procedure( InitLockMoveAndSnap() + ToggleSnapLock=0 +) +InitLockMoveAndSnap() + +procedure( LockMoveAndSnap() + if( mod(ToggleSnapLock 2)==0 then + hiSetBindKey( "Layout" "Left" "MoveAndSnap(\"L\")") + hiSetBindKey( "Layout" "Right" "MoveAndSnap(\"R\")") + hiSetBindKey( "Layout" "Up" "MoveAndSnap(\"U\")") + hiSetBindKey( "Layout" "Down" "MoveAndSnap(\"D\")") + else + hiSetBindKey( "Layout" "Left" "geScroll(nil \"w\" nil)") + hiSetBindKey( "Layout" "Right" "geScroll(nil \"e\" nil)") + hiSetBindKey( "Layout" "Up" "geScroll(nil \"n\" nil)") + hiSetBindKey( "Layout" "Down" "geScroll(nil \"s\" nil)") + ) + ToggleSnapLock = ToggleSnapLock+1 +) + + + +procedure( TR_MoveAndSnap( ) + + let( ( TR_MoveAndSnap + TR_MoveAndSnap_xSnap + TR_MoveAndSnap_ySnap ) + + TR_MoveAndSnap_xSnap = hiCreateStringField( + ?name 'TR_MoveAndSnap_xSnap + ?prompt "Enter xSnap Value" + ?defValue sprintf( nil "%n" MoveAndSnap_xSnap ) + ?editable t ) + + TR_MoveAndSnap_ySnap = hiCreateStringField( + ?name 'TR_MoveAndSnap_ySnap + ?prompt "Enter ySnap Value" + ?defValue sprintf( nil "%n" MoveAndSnap_ySnap ) + ?editable t ) + + TR_MoveAndSnap_Form = hiCreateAppForm( + ?name 'TR_MoveAndSnap_Form + ?fields '( TR_MoveAndSnap_xSnap TR_MoveAndSnap_ySnap ) + ?callback "TR_MoveAndSnap_CB( hiGetCurrentForm() )" + ) + + hiDisplayForm( TR_MoveAndSnap_Form ) + + ); end let + +); end procedure + + +procedure( TR_MoveAndSnap_CB( theForm ) + + MoveAndSnap_xSnap = evalstring( theForm->TR_MoveAndSnap_xSnap->value ) + MoveAndSnap_ySnap = evalstring( theForm->TR_MoveAndSnap_ySnap->value ) + +); end procedure + + +procedure( SuperMoveAndSnap( direction @key + ( AlignToGrid list( 0.48:MoveAndSnap_ySnap MoveAndSnap_xSnap:MoveAndSnap_ySnap )) + ( DebugOn t ) + ) + + let(( l_d_Cell + IsMidLevelCell + ) + + l_d_Cell = setof( x geGetSelectedSet() x->objType=="inst" ) + + foreach( CellUnderTest l_d_Cell + + IsMidLevelCell = setof( x + leSearchHierarchy( CellUnderTest->master + CellUnderTest->master->bBox + 0 + "inst" + nil + ) + ( x->libName != "tsmc13lg" && x->libName != "gate" && x->libName != "stack" ) + ) + + ; Filter out SLACK + if( IsMidLevelCell + then + rexCompile( "lib.buffer.slack" ) + IsMidLevelCell = !rexExecute( CellUnderTest->cellName ) + ) + + + ; Filter out TOKEN + if( IsMidLevelCell + then + rexCompile( "lib.buffer.token" ) + IsMidLevelCell = !rexExecute( CellUnderTest->cellName ) + ) + + ; Filter out CTREE + if( IsMidLevelCell + then + rexCompile( "lib.util.ctree" ) + IsMidLevelCell = !rexExecute( CellUnderTest->cellName ) + ) + + + if( IsMidLevelCell + then + DebugOn && printf( "SuperMoveAndSnap --> \"%s\" is a mid-level cell\n" CellUnderTest->name ) + MoveAndSnap( direction + ?overwrite_fig CellUnderTest + ?overwrite_xSnap caadr( AlignToGrid ) + ?overwrite_ySnap cadadr( AlignToGrid ) + ) + else + DebugOn && printf( "SuperMoveAndSnap --> \"%s\" is a leaf cell\n" CellUnderTest->name ) + MoveAndSnap( direction + ?overwrite_fig CellUnderTest + ?overwrite_xSnap caar( AlignToGrid ) + ?overwrite_ySnap cadar( AlignToGrid ) + ) + ) + + ); end foreach + + + ); end let + +); end procedure + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TrackRouter.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TrackRouter.il new file mode 100644 index 0000000000..4f157aa912 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/TrackRouter.il @@ -0,0 +1,882 @@ +;Globals +TR_TrackRouter_p1 = nil +TR_TrackRouter_p2 = nil +TR_TrackRouter_exceptionList = nil + +procedure( ManhattanRouter( @key + ( point1_db nil ) + ( point2_db nil ) + ( direction nil ) + + ( layer nil ) + ( purpose nil ) + + ( width 0.24 ) + ( viaSpacing 0.215 ) + ( spacing 0.24 ) + ( allowedLayers list( "METAL1" "METAL2" "METAL3" )) + + ( DebugOn t ) + ( StepByStep nil ) + ) + let(( OverlappedCells + ) + + +; OverlappedCells = dbGetTrueOverlaps( geGetWindowCellView( ) point1_db->bBox list( point1_db->layer nil ) 32 ) + + TR_TrackRouter_exceptionList = list( point1_db point2_db ) + + TrackRouter( ?point1_db point1_db + ?point2_db point2_db + ?direction direction + ?layer layer + ?purpose purpose + ?width width + ?spacing spacing + ?viaSpacing viaSpacing + ?allowedLayers allowedLayers + ?DebugOn DebugOn + ?StepByStep StepByStep + ) + + ); end let + + + GlobalHiliteStack_Clear( ) + + +); end procedure + + + + +procedure( TrackRouter( @key + ( point1_db nil ) + ( point2_db nil ) + ( direction nil ) + + ( layer nil ) + ( purpose nil ) + + ( width 0.24 ) + ( spacing 0.24 ) + ( viaSpacing 0.215 ) + ( allowedLayers list( "METAL1" "METAL2" "METAL3" )) + + ( DebugOn t ) + ( StepByStep nil ) + + ) + + let(( bBox + Track1 Layer1 Purpose1 bBox1 bBox1o + Track2 Layer2 Purpose2 bBox2 bBox2o + InverseOn + + direction0 point1_db0 point2_db0 point3_db + t1 t2 + Layer0 + + direction13 p13_1 p13_2 layer13 + direction32 p32_1 p32_2 layer32 + + ; These are for the contact cut + Contact_cellName + Contact_instName + Contact_counter + Contact_db + ) + + + + + ; Localize Input + ; ==================== + direction0 = direction + point1_db0 = point1_db + point2_db0 = point2_db + Layer0 = layer + Purpose0 = purpose + + + ; Initializations + ; ===================== + Contact_counter = 0 + + Layer1 = point1_db0->layerName + Layer2 = point2_db0->layerName + + Purpose1 = point1_db0->purpose + Purpose2 = point2_db0->purpose + + bBox1o = point1_db0->bBox + bBox2o = point2_db0->bBox + + if( !Purpose0 + then + Purpose0 = Purpose1 + Purpose0 = "drawing" + ); end if + + + + ; Globals Variables + ; ================== + ; TR_TrackRouter_exceptionList + ; + if( !member( point1_db TR_TrackRouter_exceptionList ) + then + TR_TrackRouter_exceptionList = cons( point1_db TR_TrackRouter_exceptionList ) + ); end if + + if( !member( point2_db TR_TrackRouter_exceptionList ) + then + TR_TrackRouter_exceptionList = cons( point2_db TR_TrackRouter_exceptionList ) + ); end if + + + + if( !Layer0 + then + Layer0 = Layer1 + ); end if + + if( direction0 == "nil" + then + direction0 = nil + ); end if + + + + + + if( StepByStep + then + StepByStepDialogBox = hiDisplayAppDBox( + ?name 'StepByStepDialogBox + ?dboxText "Press to Continue" + ?dialogType hicMessageDialog + ?dialogStyle 'systemModal + ?buttonLayout 'OKCancel + ) + ) + + + + +; t1 = dbCreateRect( geGetWindowCellView() list( "VIA23" "boundary" ) point1_db0->bBox ) +; t2 = dbCreateRect( geGetWindowCellView() list( "VIA23" "boundary" ) point2_db0->bBox ) + + isFinish = nil + + Offset = 0 + + + + surprise = width + + + + while( !isFinish + + + ; First Pass + ; ========== + + if( cadar( bBox1o ) < cadar( bBox2o ) || cadadr( bBox1o ) < cadadr( bBox2o ) + then + if( direction0 == "horizontal" || ( direction0 == nil && member( Layer0 list( "METAL3" "METAL5" "METAL7" ))) + then + ; Case 1a + bBox1 = list( list( max( caadr( bBox1o ) - width caar( bBox1o )) - surprise + min( cadar( bBox1o ) - spacing cadadr( bBox1o ) - spacing - width ) + ) + list( min( caar( bBox2o ) + width caadr( bBox2o )) - Offset + surprise + cadar( bBox2o ) + spacing + width + ) + ) + InverseOn = t + direction0 = "horizontal" + DebugOn && printf( "TrackRouter --> Pass1 --> Case 1a \"%s\" p1 is lower than p2 %L \n" direction0 bBox1 ) + else + ;Case 1b + bBox1 = list( list( min( caar( bBox1o ) - spacing caadr( bBox1o ) - spacing - width ) + max( cadadr( bBox1o ) - width cadar( bBox1o )) - surprise + ) + list( caar( bBox2o ) + spacing + width + min( cadar( bBox2o ) + width cadadr( bBox2o )) - Offset + surprise + ) + ) + + InverseOn = t + direction0 = "vertical" + DebugOn && printf( "TrackRouter --> Pass1 --> Case 1b \"%s\" p1 is lower than p2 %L \n" direction0 bBox1 ) + + ); end case 1a 1b + + else + + if( direction0 == "horizontal" || ( direction0 == nil && member( Layer0 list( "METAL3" "METAL5" "METAL7" ))) + then + ; Case 2a + bBox1 = list( list( max( caadr( bBox1o ) - width caar( bBox1o )) - surprise + cadadr( bBox2o ) - spacing - width + ) + list( min( caar( bBox2o ) + width caadr( bBox2o )) - Offset + surprise + max( cadadr( bBox1o ) + spacing cadar( bBox1o ) + spacing + width ) + ) + ) + InverseOn = nil + direction0 = "horizontal" + DebugOn && printf( "TrackRouter --> Pass1 --> Case 2a \"%s\" p1 is higher than p2 %L \n" direction0 bBox1 ) + else + ; Case 2b + bBox1 = list( list( min( caar( bBox1o ) - spacing caadr( bBox1o ) - spacing - width ) + max( cadadr( bBox2o ) - width cadar( bBox2o )) - surprise + ) + list( caar( bBox2o ) + spacing + width + min( cadar( bBox1o ) + width cadadr( bBox1o )) - Offset + surprise + ) + ) + InverseOn = t + direction0 = "vertical" + DebugOn && printf( "TrackRouter --> Pass1 --> Case 2b \"%s\" p1 is higher than p2 %L \n" direction0 bBox1 ) + + ); end if case 2a 2b + + ); end if all Cases + + + Track1 = car( PathFinder( ?layer Layer0 + ?purpose Purpose0 + ?direction direction0 + ?width width + ?spacing spacing + ?viaSpacing viaSpacing + ?searchDepth 32 + ?resolution 0.01 + ?onPowerGrid nil + ?bBox bBox1 + ?numTracks 1 + ?inverse InverseOn + ?exceptionList TR_TrackRouter_exceptionList + ?DebugOn nil + )) + + surprise = width + + ; Second Pass + if( Track1 == nil + then + DebugOn && printf( "TrackRouter --> Pass1 Failed --> Go for Pass 2 \n\n") + + if( cadar( bBox1o ) < cadar( bBox2o ) || cadadr( bBox1o ) < cadadr( bBox2o ) + then + if( direction0 == "horizontal" || ( direction0 == nil && member( Layer0 list( "METAL3" "METAL5" "METAL7" ))) + then + ; Case 1a + bBox1 = list( list( max( caadr( bBox1o ) - width caar( bBox1o )) - surprise + cadar( bBox2o ) - spacing + ) + list( min( caar( bBox2o ) + width caadr( bBox2o )) - Offset + surprise + max( cadadr( bBox2o ) + spacing cadar( bBox2o ) + spacing + width ) + ) + ) + InverseOn = nil + direction0 = "horizontal" + DebugOn && printf( "TrackRouter --> Pass2 --> Case 1a \"%s\" p1 is lower than p2 %L \n" direction0 bBox1) + else + ;Case 1b + bBox1 = list( list( caar( bBox2o ) - spacing + max( cadadr( bBox1o ) - width cadar( bBox1o )) - surprise + ) + list( max( caadr( bBox2o ) + spacing caar( bBox2o ) + spacing + width ) + min( cadar( bBox2o ) + width cadadr( bBox2o )) - Offset + surprise + ) + ) + + InverseOn = nil + direction0 = "vertical" + DebugOn && printf( "TrackRouter --> Pass2 --> Case 1b \"%s\" p1 is lower than p2 %L \n" direction0 bBox1) + + ); end case 1a 1b + + else + + if( direction0 == "horizontal" || ( direction0 == nil && member( Layer0 list( "METAL3" "METAL5" "METAL7" ))) + then + ; Case 2a + bBox1 = list( list( max( caadr( bBox1o ) - width caar( bBox1o )) - surprise + min( cadar( bBox2o ) - spacing cadadr( bBox2o ) - spacing - width ) + ) + list( min( caar( bBox2o ) + width caadr( bBox2o )) - Offset + surprise + cadadr( bBox2o ) + spacing + ) + ) + + InverseOn = t + direction0 = "horizontal" + DebugOn && printf( "TrackRouter --> Pass2 --> Case 2a \"%s\" p1 is higher than p2 %L \n" direction0 bBox1) + + else + ; Case 2b + bBox1 = list( list( caar( bBox2o ) - spacing + max( cadadr( bBox2o ) - width cadar( bBox2o )) - surprise + ) + list( max( caadr( bBox2o ) + spacing caar( bBox2o ) + spacing + width ) + min( cadar( bBox1o ) + width cadadr( bBox1o )) - Offset + surprise + ) + ) + InverseOn = nil + direction0 = "vertical" + DebugOn && printf( "TrackRouter --> Pass2 --> Case 2b \"%s\" p1 is higher than p2 %L \n" direction0 bBox1) + + ); end if case 2a 2b + + ); end if all Cases + + Track1 = car( PathFinder( ?layer Layer0 + ?purpose Purpose0 + ?direction direction0 + ?width width + ?spacing spacing + ?viaSpacing viaSpacing + ?searchDepth 32 + ?resolution 0.01 + ?onPowerGrid nil + ?bBox bBox1 + ?numTracks 1 + ?inverse InverseOn + ?exceptionList TR_TrackRouter_exceptionList + ?DebugOn nil + )) + + + if( Track1 == nil + then + DebugOn && printf( "TrackRouter --> Pass2 Failed \n\n") + else + DebugOn && printf( "TrackRouter --> Pass2 Passed \n\n") + ); end if + + else + + DebugOn && printf( "TrackRouter --> Pass1 Passed \n\n") + + ); end if Second Pass + + + +; if( Track1 || Offset >= 6 + if( Track1 + then + isFinish = t + else + Offset = Offset + width + ) + + + ); end while isFinish + + + + DebugOn && printf( "TrackRouter --> ------------------------------------------------------\n" ) + + + + ; Shrink Track1 by width to prevent abuttment problem + ; =================================================== + if( Track1 + then + case( direction0 + ( "horizontal" + Track1 = list( + list( + caar( Track1 ) + width + cadar( Track1 ) + ) + list( + caadr( Track1 ) - width + cadadr( Track1 ) + ) + ) + + ); end horizontal + + ( "vertical" + Track1 = list( + list( + caar( Track1 ) + cadar( Track1 ) + width + ) + list( + caadr( Track1 ) + cadadr( Track1 ) - width + ) + ) + + ); end vertical + + ); end case + + ); end if + + + + + + + + + + point3_db = dbCreateRect( geGetWindowCellView() list( Layer0 Purpose0 ) Track1 ) + + + + direction13 = nil + + ;======================= + ; point1_db0 Covered + ;======================= +; if( !member( point1_db0 dbGetOverlaps( geGetWindowCellView( ) Track1 list( Layer0 nil ) 32 )) + if( !member( point1_db0 dbGetOverlaps( geGetWindowCellView( ) Track1 t 32 )) + then + if( direction0 == "horizontal" + then + direction13 = "vertical" + else + direction13 = "horizontal" + ) + + case( Layer0 + + ( "METAL2" + layer13 = "METAL3" + ) + + ( "METAL3" + layer13 = "METAL2" + ) + + ); end case + + + + DebugOn && printf( "TrackRouter --> --> branch p1 p3 direction = \"%s\" \n" direction13 ) + + TrackRouter( ?point1_db point1_db0 + ?point2_db point3_db + ?direction direction13 + ?layer layer13 + ?allowedLayers allowedLayers + ) + else + case( direction0 + ( "vertical" + point1_db0->bBox = list( + car( point1_db0->bBox ) + list( caar( Track1 ) + width cadadr( point1_db0->bBox )) + ) + + if( cadar( bBox1o ) < cadar( bBox2o ) || cadadr( bBox1o ) < cadadr( bBox2o ) + then + Contact_origin = list( + caar( Track1 ) + width/2 + cadar( Track1 ) + width/2 + ) + else + Contact_origin = list( + caadr( Track1 ) - width/2 + cadadr( Track1 ) - width/2 + ) + ) + + + ) + + ( "horizontal" + + Contact_origin = list( + caar( Track1 ) + width/2 + cadar( Track1 ) + width/2 + ) + + if( cadar( bBox1o ) < cadar( bBox2o ) || cadadr( bBox1o ) < cadadr( bBox2o ) + then + point1_db0->bBox = list( + car( point1_db0->bBox ) + list( caadr( point1_db0->bBox ) + min( cadar( Track1 ) + width cadadr( point1_db0->bBox )) + ) + ) + else + point1_db0->bBox = list( + list( caar( point1_db0->bBox ) + max( cadadr( Track1 ) - width cadar( point1_db0->bBox )) + ) + cadr( point1_db0->bBox ) + ) + ); end if + ) + + ); end case + + ; Auto Contact Cuts + Contact_cellName = nil + case( Layer1 + + ( "METAL2" + case( Layer0 + ( "METAL1" + Contact_cellName = "M2_M1" + ) + ( "METAL3" + Contact_cellName = "M3_M2" + ) + ); end case + ); end "METAL2" case + + ( "METAL3" + case( Layer0 + ( "METAL2" + Contact_cellName = "M3_M2" + ) + ( "METAL4" + Contact_cellName = "M4_M3" + ) + ); end case + ); end "METAL2" case + + ); end case + + + if( Contact_cellName + then +; Contact_origin = list( +; caar( Track1 ) + width/2 +; cadar( Track1 ) + width/2 +; ) + + Contact_db = dbCreateInstByMasterName( + geGetWindowCellView( ) + "tsmc13lg" + Contact_cellName + "symbolic" + nil + Contact_origin + "R0" + ) + + TR_TrackRouter_exceptionList = cons( Contact_db TR_TrackRouter_exceptionList ) + + ) + ); end if + + + direction32 = nil + + + ;======================= + ; point2_db0 Covered + ;======================= +; if( !member( point2_db0 dbGetOverlaps( geGetWindowCellView( ) Track1 list( Layer0 nil ) 32 )) + if( !member( point2_db0 dbGetOverlaps( geGetWindowCellView( ) Track1 t 32 )) + then + if( direction0 == "horizontal" + then + direction32 = "vertical" + else + direction32 = "horizontal" + ) + + case( Layer0 + + ( "METAL2" + layer32 = "METAL3" + ) + + ( "METAL3" + layer32 = "METAL2" + ) + + ); end case + + + DebugOn && printf( "TrackRouter --> --> branch p3 p2 direction = \"%s\" \n" direction32 ) + + TrackRouter( ?point1_db point3_db + ?point2_db point2_db0 + ?direction direction32 + ?layer layer32 + ?allowedLayers allowedLayers + ) + else + case( direction0 + ( "vertical" + point2_db0->bBox = list( + list( caadr( Track1 ) - width cadar( point2_db0->bBox )) + cadr( point2_db0->bBox ) + ) + + if( cadar( bBox1o ) < cadar( bBox2o ) || cadadr( bBox1o ) < cadadr( bBox2o ) + then + Contact_origin = list( + caadr( Track1 ) - width/2 + cadadr( Track1 ) - width/2 + ) + else + Contact_origin = list( + caar( Track1 ) + width/2 + cadar( Track1 ) + width/2 + ) + ) + + ) + ( "horizontal" + if( cadar( bBox1o ) < cadar( bBox2o ) || cadadr( bBox1o ) < cadadr( bBox2o ) + then + point2_db0->bBox = list( + list( caar( point2_db0->bBox ) + max( cadadr( Track1 ) - width cadar( point2_db0->bBox )) + ) + cadr( point2_db0->bBox ) + ) + + Contact_origin = list( + caadr( Track1 ) - width/2 + cadadr( Track1 ) - width/2 + ) + else + point2_db0->bBox = list( + car( point2_db0->bBox ) + list( caadr( point2_db0->bBox ) + min( cadar( Track1 ) + width cadadr( point2_db0->bBox )) + ) + ) + + Contact_origin = list( + caadr( Track1 ) - width/2 + cadadr( Track1 ) - width/2 + ) + ); end if + ) + ); end case + + + tempWidth = caadr( point2_db0->bBox ) - caar( point2_db0->bBox ) + tempHeight= cadadr( point2_db0->bBox ) - cadar( point2_db0->bBox ) + + if( ( abs( tempWidth - width ) < 0.00001 && + abs( tempHeight - width ) < 0.0001 && + nth( 0 reverse(TR_TrackRouter_exceptionList) ) != point2_db0 && + nth( 1 reverse(TR_TrackRouter_exceptionList) ) != point2_db0 + ) + + then + println( "Hit!" ) + +; tempList = setof( x +; exists( x reverse(TR_TrackRouter_exceptionList) x==point2_db0 ) +; !member( x exists( x reverse(TR_TrackRouter_exceptionList) x==point3_db )) +; ) +; printf( "tempList=%L" tempList ) +; +; println( tempList ) +; +; foreach( tempCell tempList +; println( "REMOVE" ) +; dbDeleteObject( tempCell ) +; TR_TrackRouter_exceptionList = remove( tempCell TR_TrackRouter_exceptionList ) +; ); end foreach +; +; +; dbDeleteObject( point2_db0 ) +; TR_TrackRouter_exceptionList = remove( point2_db0 TR_TrackRouter_exceptionList ) + else + + ; Auto Contact Cuts + Contact_cellName = nil + case( Layer2 + + ( "METAL2" + case( Layer0 + ( "METAL1" + Contact_cellName = "M2_M1" + ) + ( "METAL3" + Contact_cellName = "M3_M2" + ) + ); end case + ); end "METAL2" case + + ( "METAL3" + case( Layer0 + ( "METAL2" + Contact_cellName = "M3_M2" + ) + ( "METAL4" + Contact_cellName = "M4_M3" + ) + ); end case + ); end "METAL2" case + + ); end case + + + if( Contact_cellName + then + +; Contact_origin = list( +; caadr( Track1 ) - width/2 +; cadadr( Track1 ) - width/2 +; ) + + Contact_db = dbCreateInstByMasterName( + geGetWindowCellView( ) + "tsmc13lg" + Contact_cellName + "symbolic" + nil + Contact_origin + "R0" + ) + + TR_TrackRouter_exceptionList = cons( Contact_db TR_TrackRouter_exceptionList ) + + ) + + ); end if + ); end if + +; dbDeleteObject( t1 ) +; dbDeleteObject( t2 ) + + ); end let + +); procedure + +;p1 = car( geGetSelectedSet( )) +;p2 = car( geGetSelectedSet( )) +;TrackRouter( ?point1_db p1 ?point2_db p2 ?direction "vertical" ) +;TrackRouter( ?point1_db p1 ?point2_db p2 ) + + +;=================== +; MAIN GUI +;=================== + +procedure( TR_TrackRouter( ) + + let(( TR_TrackRouter_Add_p1 + p1 p2 + ) + + TR_TrackRouter_Add_p1 = hiCreateButton( + ?name `TR_TrackRouter_Add_p1 + ?buttonText "Add Point 1" + ?enabled t + ?callback "TR_TrackRouter_Add_p1_CB( hiGetCurrentForm() )" + ) + + TR_TrackRouter_Add_p2 = hiCreateButton( + ?name `TR_TrackRouter_Add_p2 + ?buttonText "Add Point 2" + ?enabled t + ?callback "TR_TrackRouter_Add_p2_CB( hiGetCurrentForm() )" + ) + + TR_TrackRouter_DirectionField = hiCreateCyclicField( + ?name `TR_TrackRouter_DirectionField + ?choices list( "horizontal" "vertical" "nil" ) + ?prompt "Direction" + ?defValue "nil" + ?callback "" + ) + + TR_TrackRouter_Form = hiCreateAppForm( + ?name 'TR_TrackRouter_Form + ?initialSize list( 600 1000 ) + ?fields list( + list( TR_TrackRouter_Add_p1 0:0 200:30 0 ) + list( TR_TrackRouter_Add_p2 200:0 200:30 0 ) + list( TR_TrackRouter_DirectionField 0:30 200:30 100 ) + ) + ?formTitle "" + ?callback "ManhattanRouter( + ?point1_db TR_TrackRouter_p1 + ?point2_db TR_TrackRouter_p2 + ?direction TR_TrackRouter_DirectionField->value + ?layer nil + ?purpose nil + )" + ) + + hiDisplayForm( TR_TrackRouter_Form ) + + ); end let + +); end procedure + + +;=================== +; Add Point 1 +;=================== + +procedure( TR_TrackRouter_Add_p1_CB( theForm ) + + let(( dummy + w_windowId + g_partial + returnValue + ) + + w_windowId = geGetCellViewWindow( geGetWindowCellView( )) + g_partial = nil + returnValue = nil + + geDeselectAllFig( ) + + if( geAddSelectPoint( w_windowId g_partial ) + then + returnValue = car( geGetSelectedSet( )) + ); end if + + TR_TrackRouter_p1 = returnValue + + returnValue + + ); end let + +); end procedure + +;=================== +; Add Point 2 +;=================== + +procedure( TR_TrackRouter_Add_p2_CB( theForm ) + + let(( dummy + w_windowId + g_partial + returnValue + ) + + w_windowId = geGetCellViewWindow( geGetWindowCellView( )) + g_partial = nil + returnValue = nil + + geDeselectAllFig( ) + + if( geAddSelectPoint( w_windowId g_partial ) + then + returnValue = car( geGetSelectedSet( )) + ); end if + + TR_TrackRouter_p2 = returnValue + + returnValue + + ); end let + +); end procedure diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/trZoom.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/trZoom.il new file mode 100644 index 0000000000..b39b7604f0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/fulcrum_setup/trZoom.il @@ -0,0 +1,183 @@ +trX = hiCreateStringField( + ?name 'trX + ?prompt "Enter x-value" + ?defValue "23.4" + ?editable t ) + +trY = hiCreateStringField( + ?name 'trY + ?prompt "Enter y-value" + ?defValue "12" + ?editable t ) + +trRadius = hiCreateStringField( + ?name 'trRadius + ?prompt "Enter Zoom Radius" + ?defValue "14" + ?editable t ) + +trLabel = hiCreateMLTextField( + ?name `trLabel + ?prompt "Enter Label (Optional)" ) + +trColor = hiCreateRadioField( + ?name 'trColor + ?choices '( "White" "Magenta" "Orange" "Lime" "Pink" ) + ?prompt "Enter desired Color to add" +) + +trErase = hiCreateToggleField( + ?name 'trErase + ?choices list( list( `ER1 "White") + list( `ER2 "Magenta") + list( `ER3 "Orange") + list( `ER4 "Lime") + list( `ER5 "Pink") + list( `ER6 "Erase All")) + ?prompt "Enter desired Color to erase" +) + +procedure( trZoom( theForm ) + + let( ( x x_low x_high + y y_low y_high + Radius + ER + HiliteSet) + + x = evalstring( theForm->trX->value ) + y = evalstring( theForm->trY->value ) + Radius = evalstring( theForm->trRadius->value ) + ER1 = theForm->trErase->ER1->value + ER2 = theForm->trErase->ER2->value + ER3 = theForm->trErase->ER3->value + ER4 = theForm->trErase->ER4->value + ER5 = theForm->trErase->ER5->value + ER6 = theForm->trErase->ER6->value + Label = theForm->trLabel->value + Color = theForm->trColor->value + + ; If User wants to erase all markers + if( ER1 || ER2 || ER3 || ER4 || ER5 || ER6 + then + if( ER1 + then + boundp( `setWhite ) && geIsValidHilightSet( evalstring( "setWhite" )) && geDeleteHilightSet( evalstring( strcat( "set" "White" ) ) ) + printf( "trZoom --> White markers erased!!! \n") + ) ; end if + + if( ER2 + then + boundp( `setMagenta ) && geIsValidHilightSet( evalstring( "setMagenta" )) && geDeleteHilightSet( evalstring( strcat( "set" "Magenta" ) ) ) + printf( "trZoom --> Magenta markers erased!!! \n") + ) ; end if + + if( ER3 + then + boundp( `setOrange ) && geIsValidHilightSet( evalstring( "setOrange" )) && geDeleteHilightSet( evalstring( strcat( "set" "Orange" ) ) ) + printf( "trZoom --> Orange markers erased!!! \n") + ) ; end if + + if( ER4 + then + boundp( `setLime ) && geIsValidHilightSet( evalstring( "setLime" )) && geDeleteHilightSet( evalstring( strcat( "set" "Lime" ) ) ) + printf( "trZoom --> Lime markers erased!!! \n") + ) ; end if + + if( ER5 + then + boundp( `setPink ) && geIsValidHilightSet( evalstring( "setPink" )) && geDeleteHilightSet( evalstring( strcat( "set" "Pink" ) ) ) + printf( "trZoom --> Pink markers erased!!! \n") + ) ; end if + + if( ER6 + then + boundp( `setWhite ) && geIsValidHilightSet( evalstring( "setWhite" )) && geDeleteHilightSet( evalstring( strcat( "set" "White" ) ) ) + boundp( `setMagenta ) && geIsValidHilightSet( evalstring( "setMagenta" )) && geDeleteHilightSet( evalstring( strcat( "set" "Magenta" ) ) ) + boundp( `setOrange ) && geIsValidHilightSet( evalstring( "setOrange" )) && geDeleteHilightSet( evalstring( strcat( "set" "Orange" ) ) ) + boundp( `setLime ) && geIsValidHilightSet( evalstring( "setLime" )) && geDeleteHilightSet( evalstring( strcat( "set" "Lime" ) ) ) + boundp( `setPink ) && geIsValidHilightSet( evalstring( "setPink" )) && geDeleteHilightSet( evalstring( strcat( "set" "Pink" ) ) ) + printf( "trZoom --> All markers erased!!! \n") + ) ; end if + else + + printf( "trZoom --> Zoom to ( %n , %n ) with a radius of %n \n" x y Radius) + + x_low = x - Radius + y_low = y - Radius + x_high = x + Radius + y_high = y + Radius + boundBox = list( x_low:y_low x_high:y_high ) + pathList = list( x:y + x:(y + (y_high-y)/2) + (x + (x_high-x)/2):y + x:y + x_high:y_high ) + + ; Setting the drawType + + case( + Color + + ( "White" + drawType = "drawing" + ) + + ( "Magenta" + drawType = "drawing1" + ) + + ( "Orange" + drawType = "drawing4" + ) + + ( "Lime" + drawType = "drawing5" + ) + + ( "Pink" + drawType = "drawing9" + ) + ); end case + + ; Create a New Hilite Group + if( boundp( concat( "set" Color )) == nil || geIsValidHilightSet( evalstring( strcat( "set" Color ))) == nil + ; if( boundp( concat( "set" Color )) == nil + then + printf( "trZoom --> Hilite Set \"set%s\" created!!! \n" Color ) + evalstring( strcat( "set" Color "= geCreateHilightSet( geGetWindowCellView( ) list(\"hilite\" drawType) nil )" )) + + ); end if + + ; Set the current Hilite Group + setCurrent = evalstring( strcat( "set" Color ) ) + setCurrent->enable = t + + geAddHilightDot( setCurrent x:y 0.48 0.48 ) + geAddHilightCircle( setCurrent x:y Radius ) + geAddHilightLabel( setCurrent list(x y+Radius) Label "upperCenter" "R0" "stick" max( Radius/4 2 ) t ) + + + hiZoomIn( geGetCellViewWindow( geGetWindowCellView( )) boundBox ) + leZoomToPoint(hiGetCurrentWindow(), x:y) + ; leCreatePath( geGetWindowCellView() list("hilite" drawType) pathList 0.01 ) + ); end if + + ) ; end let + +) ; procedure + + ; hiDeleteForm( A ) + +A = hiCreateAppForm( + ?name 'trZoomForm + ?fields '( trX trY trRadius trLabel trColor trErase) + ?callback "trZoom( hiGetCurrentForm() )" +) + + + + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/gdsII/gdsIIhier.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/gdsII/gdsIIhier.il new file mode 100644 index 0000000000..7b663351f3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/gdsII/gdsIIhier.il @@ -0,0 +1,1527 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +
    + This file contains skill code for preparing layout for export to GDSII or for converted layout imported from GDSII to normal layout cells.
    +
    + When Exporting layout, all cell names, node name, and instance names
    + are changed based on mappings stored in skill name tables.  There is
    + one skill name table per cell to be converted.  All the skill name tables
    + are in the same directory.  Each skill name table is named cellname.names.il.
    + Each skill name table file defines three tables:
    +    CadenceNodeToGDSIINodeTable
    +       maps node name in source layout to node name in exported layout.
    +    CadenceCellToGDSIICellTable
    +       maps cell name in source layout to cell name in exported layout.
    +    CadenceInstanceToGDSIIInstanceTable
    +       maps instance name in source layout to instance name in exported layout.
    + During export each cell to be exported is copied to a temporary library.  The cell's
    + name in the temporary library will be it's export name.
    + The copy of the cell will then be opened and all instances will have their masters
    + redefined to be the copy of their master in the temporary library.
    +The copy of the cell will also have all of its labels texts and instance
    + names changed based on what is in the CadenceNodeToGDSIINodeTable and 
    + CadenceInstanceToGDSIIInstanceTable tables.
    + Importing is the reverse of exporting.  skill name table files
    +are used as in export, but the keys in all the tables are names from
    + the gdsII and the values are names to use in the dfII layout.
    +
    +*/ + +(defun GDSIIHierUnRodObjects ( CellView ) + (let ( + ( Shapes ( getq CellView shapes ) ) ) + ( foreach + RodObj + ( rodGetNamedShapes CellView ) + ( rodUnAlign RodObj ) + ( rodUnNameShape RodObj ) ) ) + (let ( + ( Instances ( getq CellView instances ) ) ) + ( foreach + Instance + Instances + (let ( + ( RodObj ( rodGetObj Instance ) ) ) + (when RodObj + ( rodUnAlign RodObj ) + (when ( getq RodObj align ) + ( rodUnNameShape RodObj ) ) ) ) ) ) ) + +(defun GDSIIHierParseCellName ( CellName ) + (let ( + ( Components ( parseString CellName "." ) ) ) + (let ( + ( RComponents ( reverse Components ) ) ) + (let ( + ( RLibNameComponents ( cdr ( cdr RComponents ) ) ) + ( LibName nil ) ) + ( foreach + Component + ( reverse RLibNameComponents ) + (if LibName + ( setq LibName ( sprintf nil "%s.%s" LibName Component ) ) + ( setq LibName Component ) ) ) + ( list LibName CellName ) ) ) ) ) + + +(defun GDSIIHierMakeNameGDSIISafe ( CellName ) + (let ( + ( NumChars ( strlen CellName ) ) + ( CurrIndex 1 ) + ( Result "" ) + ( bracketNumber 0 ) + CurrChar + ConvertedChar + ) + bracketNumber= 0 + (while ( and + Result + ( not ( lessp NumChars CurrIndex ) ) ) + CurrChar=substring( CellName CurrIndex 1 ) + ConvertedChar= (cond + ( + ( or + ( StringUtilIsCharLetter CurrChar ) + ( StringUtilIsCharDigit CurrChar ) ) + CurrChar ) + ( ( equal "$" CurrChar ) "_24_" ) + ( ( equal "." CurrChar ) "_D_" ) + ( ( equal "_" CurrChar ) if( bracketNumber==0 "_U_" "_C_") ) + ( ( equal "-" CurrChar ) + CurrChar=substring( CellName CurrIndex 2 ) + CurrIndex=CurrIndex+1 + if( CurrChar=="-L" then + bracketNumber=bracketNumber+1 + CurrChar=if( bracketNumber==1 "_L_" "_7b_") + else + bracketNumber=bracketNumber-1 + CurrChar=if( bracketNumber==0 "_R_" "_7d_") + ) + CurrChar + ) + ( ( equal "(" CurrChar ) "_L_" ) + ( ( equal ")" CurrChar ) "_R_" ) + ( ( equal "{" CurrChar ) "_7b_" ) + ( ( equal "}" CurrChar ) "_7d_" ) + ( ( equal "," CurrChar ) "_C_" ) + ( t nil ) + ) + (if ConvertedChar + Result= strcat( Result ConvertedChar ) + Result= nil ) + CurrIndex= CurrIndex + 1 + ) + Result ) ) + +(defun GDSIIHierGetTableFileForCellView ( CellView TableDirectory ) + ( GDSIIHierGetTableFileForCellName ( getq CellView cellName ) TableDirectory ) ) + +(defun GDSIIHierGetTableFileForCellName ( CellName TableDirectory ) + ( sprintf nil "%s/%s.names.il" TableDirectory CellName ) ) + +(defun GDSIIHierGetPartialExtractTableFileForCellName ( CellName TableDirectory ) + ( sprintf nil "%s/%s.partial.il" TableDirectory CellName ) ) + +(defun GDSIIHierGetPartialExtractTableFileForCellView ( CellView TableDirectory ) + ( GDSIIHierGetPartialExtractTableFileForCellName ( getq CellView cellName ) TableDirectory ) ) + +(defun GDSIIHierGetLVSNodesTableFileForCellName ( CellName TableDirectory ) + ( sprintf nil "%s/%s.lvsNodes.il" TableDirectory CellName ) ) + +(defun GDSIIHierGetLVSNodesTableFileForCellView ( CellView TableDirectory ) + ( GDSIIHierGetLVSNodesTableFileForCellName ( getq CellView cellName ) TableDirectory ) ) + +(defun GDSIIHierGetGDSIIImportMungedCellView ( CadenceCellName + ViewName ) + (let ( + ( CadenceLibName ( car ( NameParseCellName CadenceCellName ) ) ) ) + (when CadenceLibName + ( dbOpenCellViewByType + CadenceLibName + CadenceCellName + ViewName + nil + "r" ) ) ) ) + +(defun GDSIIHierGetGDSIIExportMungedCellView ( GDSIICellName + ViewName + GDSIIExportLib ) + ( dbOpenCellViewByType + GDSIIExportLib + GDSIICellName + ViewName + nil + "r" ) ) + + + +(defun GDSIIHierMungeCellInstances ( CellViewToMunge + CellTable + InstanceTable + GetMungedCellViewFunc + GetMungedCellViewFuncParams + LibCellExpressionPairsToIgnore ) + (let ( + ( ErrorStr nil ) ) + ( foreach + Instance + ( UpdateNetlistFilterInstances + CellViewToMunge + LibCellExpressionPairsToIgnore ) + (unless ErrorStr + (let ( + ( CurrMasterName ( getq Instance cellName ) ) ) + (let ( + ( MungedMasterNameFromTable ( arrayref + CellTable + CurrMasterName ) ) ) + ;don't munge globals instances + (let ( + ( MungedMasterName + (if ( equal + ( getq Instance libName ) + "globals" ) + CurrMasterName + (if MungedMasterNameFromTable + MungedMasterNameFromTable + ( GDSIIHierMakeNameGDSIISafe + CurrMasterName ) ) ) ) ) + (when ( and + MungedMasterName + ( not ( equal MungedMasterName CurrMasterName ) ) ) + (let ( + ( MungedMasterCellView + ( apply + GetMungedCellViewFunc + ( cons + MungedMasterName + ( cons + ( getq Instance viewName ) + GetMungedCellViewFuncParams ) ) ) ) ) + (if MungedMasterCellView + ( dbSetq Instance MungedMasterCellView master ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to get cell %L for instance %L in cell %L" + MungedMasterName + ( getq Instance name ) + ( getq CellViewToMunge cellName ) ) ) ) ) ) ) ) ) ) ) + + + ( foreach + Instance + ( getq CellViewToMunge instances ) + (unless ErrorStr + (let ( + ( CurrInstanceName ( NameCanonicalizeNonFoldableInstanceName ( getq Instance name ) ) ) ) + (let ( + ( MungedInstanceNameFromTable ( arrayref + InstanceTable + CurrInstanceName ) ) ) + (let ( + ( MungedInstanceName (if MungedInstanceNameFromTable + MungedInstanceNameFromTable + (if ( equal + ( StringUtilGetFirstChar CurrInstanceName ) + "|" ) + ( arrayref + InstanceTable + ( StringUtilGetAllButFirstChar + CurrInstanceName ) ) + ( GDSIIHierMakeNameGDSIISafe + CurrInstanceName ) ) ) ) ) + (unless ( or + ( not MungedInstanceName ) + ( equal MungedInstanceName CurrInstanceName ) ) + ( dbSetq Instance MungedInstanceName name ) ) ) ) ) ) ) + + ErrorStr ) ) + + +(defun GDSIIHierMungeCellLabels ( CellViewToMunge NodeTable ) + (let ( + ( TextDisplaysAndLabels ( setof + Shape + ( getq CellViewToMunge shapes ) + ( or + ( equal ( getq Shape objType ) "label" ) + ( equal ( getq Shape objType ) "textDisplay" ) ) ) ) ) + ( foreach + TextOrLabel + TextDisplaysAndLabels + (if ( equal "label" ( getq TextOrLabel objType ) ) + (let ( + ( LabelObj TextOrLabel ) ) + (let ( + ( NodeName ( getq LabelObj theLabel ) ) ) + (let ( + ( MungedNameFromTable ( arrayref NodeTable NodeName ) ) ) + (if MungedNameFromTable + (unless ( equal NodeName MungedNameFromTable ) + ( dbSetq LabelObj MungedNameFromTable theLabel ) ) + ( dbDeleteObject LabelObj ) ) ) ) ) + (let ( + ( TextObj TextOrLabel ) ) + (let ( + ( AssociateObj ( getq TextObj associate ) ) + ( AssociateField ( stringToSymbol ( getq TextObj text ) ) ) + ( LayerPP ( getq TextObj lpp ) ) + ( Location ( getq TextObj xy ) ) + ( Orientation ( getq TextObj orient ) ) + ( Font ( getq TextObj font ) ) + ( Height ( getq TextObj height ) ) + ( Justification ( getq TextObj justify ) ) ) + (let ( + ( NodeName ( get AssociateObj AssociateField ) ) ) + (let ( + ( MungedNameFromTable ( arrayref NodeTable NodeName ) ) ) + ( dbDeleteObject TextObj ) + (when MungedNameFromTable + (unless ( equal NodeName MungedNameFromTable ) + ( dbCreateLabel + CellViewToMunge + LayerPP + Location + MungedNameFromTable + Justification + Orientation + Font + Height ) ) ) ) ) ) ) ) ) ) + nil ) + +(defun GDSIIHierDeleteInstanceTerms ( CellViewToMunge ) + ( foreach + Instance + ( getq CellViewToMunge instances ) + ( foreach + InstTerm + ( getq Instance conns ) + ( dbDeleteObject InstTerm ) ) ) ) + + +(defun GDSIIHierFindNet ( CellViewToMunge NetName ) + ( car + ( setof + Net + ( getq CellViewToMunge nets ) + ( equal + ( getq Net name ) + NetName ) ) ) ) + +(defun GDSIIHierMungeCellConnectivity ( CellViewToMunge NodeTable ) + ( GDSIIHierDeleteInstanceTerms CellViewToMunge ) + (let ( + ( NetsTable ( makeTable "netstable" nil ) ) ) + (let ( + ( ErrorStr nil ) + ( NetsToDeleteAndRename ( ListApplyFuncToListAndAccumulateResult + ( getq CellViewToMunge nets ) + (lambda + ( Net CurrResult NetsTable NodeTable ) + (let ( + ( NewNetName ( arrayref NodeTable ( getq Net name ) ) ) ) + (if NewNetName + (let () + (if ( equal NewNetName ( getq Net name ) ) + CurrResult + (let ( + ( NewResult + ( list + ( car CurrResult ) + ( cons + ( list Net NewNetName ) + ( cadr CurrResult ) ) ) ) ) + ( setarray NetsTable ( getq Net name ) Net ) + NewResult ) ) ) + ( list + ( cons + Net + ( car CurrResult ) ) + ( cadr CurrResult ) ) ) ) ) + ( list NetsTable NodeTable ) + ( list nil nil ) ) ) ) + + ( foreach + Net + ( car NetsToDeleteAndRename ) + (let ( + ( NetTerm ( getq Net term ) ) ) + (when NetTerm + ( dbDeleteObject NetTerm ) ) + ( dbDeleteObject Net ) ) ) + + ( foreach + NetRename + ( cadr NetsToDeleteAndRename ) + (let ( + ( Net ( car NetRename ) ) + ( NewNetName ( cadr NetRename ) ) ) + (if NewNetName + (let ( + ( ExistingNet ( arrayref NetsTable NewNetName ) ) ) + (if ExistingNet + ( setq + ErrorStr + ( sprintf + nil + "Unable to rename \"%s\" to \"%s\" because net \"%s\" aleady existed.\n" + ( getq Net name ) + NewNetName + NewNetName ) ) + (let ( + ( ExistingTerm ( getq Net term ) ) + ( ExistingPins ( getq Net pins ) ) + ( NewNet ( dbCreateNet CellViewToMunge NewNetName ) ) ) + ( setarray NetsTable NewNetName NewNet ) + (when ExistingTerm + ( dbCreateTerm + NewNet + NewNetName + ( getq ExistingTerm direction ) ) ) + + ( foreach + ExistingPin + ExistingPins + (let ( + ( ExistingShape ( getq ExistingPin fig ) ) ) + ( dbDeleteObject ExistingPin ) + ( dbCreatePin NewNet ExistingShape ) ) ) + (let ( + ( NetTerm ( getq Net term ) ) ) + (when NetTerm + ( dbDeleteObject NetTerm ) ) ) + ( setarray NetsTable ( getq Net name ) nil ) + ( dbDeleteObject Net ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to get new net name for \"%s\".\n" + ( getq Net name ) ) ) ) ) ) + ErrorStr ) ) ) + + + +(defun GDSIIHierMungeCellCopy ( CellViewToMunge + NodeTable + CellTable + InstanceTable + GetMungedCellViewFunc + GetMungedCellViewFuncParams + LibCellExpressionPairsToIgnore ) + (let ( + ( ErrorStr nil ) ) + ( GDSIIHierUnRodObjects CellViewToMunge ) + + (unless ErrorStr + ( printf "Munging Instances for %L\n" ( getq CellViewToMunge cellName ) ) + ( setq ErrorStr ( GDSIIHierMungeCellInstances + CellViewToMunge + CellTable + InstanceTable + GetMungedCellViewFunc + GetMungedCellViewFuncParams + LibCellExpressionPairsToIgnore ) ) ) + (unless ErrorStr + ( printf "Munging labels for %L\n" ( getq CellViewToMunge cellName ) ) + ( setq ErrorStr ( GDSIIHierMungeCellLabels CellViewToMunge NodeTable ) ) ) + (unless ErrorStr + ( printf "Munging Connectivity for %L\n" ( getq CellViewToMunge cellName ) ) + ( setq ErrorStr ( GDSIIHierMungeCellConnectivity CellViewToMunge NodeTable ) ) ) + (when ErrorStr + ( printf "ERROR: %L\n" ErrorStr ) ) + ErrorStr ) ) + + +(defun GDSIIHierGetMungedCellNameForCellName ( TableDirectory + CellName ) + (let ( + ( TableFile ( GDSIIHierGetTableFileForCellName CellName TableDirectory ) ) ) + (when ( isReadable TableFile ) + ( load TableFile ) + ( arrayref CadenceCellToGDSIICellTable CellName ) ) ) ) + +(defun GDSIIHierFixInstancesForPartialExtract ( CellView + SubTypeTable + InstancesToDelete + ) + (let ( + ( ErrorStr nil ) ) + ( foreach + Instance + ( getq CellView instances ) + (when ( and + ( equal ( getq Instance objType ) "inst" ) + ( null ErrorStr ) + ( equal ( getq Instance libName ) ( getq CellView libName ) ) + ( null ( getq ( getq Instance master ) superMaster ) ) + (let ( + ( MasterCellView ( getq Instance master ) ) ) + (let ( + ( IncludeInPartialExtractProp ( dbSearchPropByName + MasterCellView + "includeInPartialExtract" ) ) ) + (if IncludeInPartialExtractProp + ( not ( equal ( getq IncludeInPartialExtractProp value ) "TRUE" ) ) + t ) ) ) ) + + (when ( equal ( getq Instance name ) "t" ) + ( printf "Hello, the instance name is \"t\"!!!!\n" ) ) + (let ( + ( NewMasterCellName ( arrayref SubTypeTable ( getq Instance name ) ) ) ) + (if NewMasterCellName + (let ( + ( NewMasterCellViewDDObj ( ddGetObj + ( getq CellView libName ) + NewMasterCellName + ( getq Instance viewName ) ) ) ) + (when ( equal ( getq Instance name ) "t" ) + ( printf + "%L %L %L %L\n" + ( getq CellView cellName ) + ( getq Instance name ) + ( getq Instance cellName ) + NewMasterCellName ) ) + (if ( and + NewMasterCellViewDDObj + ( getq NewMasterCellViewDDObj files ) ) + (let ( + ( NewMasterCellView ( dbOpenCellViewByType + ( getq CellView libName ) + NewMasterCellName + ( getq Instance viewName ) + nil + "r" ) ) ) + (when ( equal ( getq Instance name ) "t" ) + ( printf + "%L %L %L %L %L %L\n" + ( getq CellView cellName ) + ( getq Instance name ) + ( getq Instance cellName ) + NewMasterCellName + NewMasterCellView + (when NewMasterCellView + ( getq NewMasterCellView cellName ) ) ) ) + (if NewMasterCellView + ( dbSetq Instance NewMasterCellView master ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to open cell view for %L %L for instance %L in %L %L." + NewMasterCellName + ( getq Instance viewName ) + ( getq Instance name ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "cell view for %L %L for instance %L in %L %L does not exist." + NewMasterCellName + ( getq Instance viewName ) + ( getq Instance name ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) + (let () + ( printf "Deleting instance %L\n" ( getq Instance name ) ) + ;don't delete now because wew may have to complete the nets + ;( dbDeleteObject Instance ) + ( setarray InstancesToDelete ( getq Instance name ) t ) + ) ) ) ) ) + ErrorStr + ) ) + +(defun GDSIIHierDoLVSNodes ( CellView + LVSNodesLabelsTable + LVSNodesTable ) + (let ( + ( FinishedLabels ( makeTable "labelTable" nil ) ) + ( LVSNodes ( LVSNodesGetLVSNodes LVSNodesTable ) ) ) + + ( foreach + Instance + ( getq CellView instances ) + (let ( + ( LVSNodesInstance ( LVSNodesGetLVSNodesInstance + LVSNodesTable + ( getq Instance name ) ) ) ) + (when LVSNodesInstance + ( foreach + LVSNodePair + ( LVSNodesGetLVSNodesInstanceConnectionPairs + LVSNodesInstance ) + (let ( + ( LVSNode ( car LVSNodePair ) ) + ( LVSNodeInInstance ( cadr LVSNodePair ) ) ) + (let ( + ( LabelObjInInstance ( arrayref + ( arrayref + LVSNodesLabelsTable + ( getq Instance cellName ) ) + LVSNodeInInstance ) ) ) + (when LabelObjInInstance + (let ( + ( LabelPosInInstance ( getq LabelObjInInstance xy ) ) + ( LabelLayerInInstance ( getq LabelObjInInstance lpp ) ) + ( LabelOrientationInInstance ( getq LabelObjInInstance orient ) ) + ( LabelFontInInstance ( getq LabelObjInInstance font ) ) + ( LabelHeightInInstance ( getq LabelObjInInstance height ) ) + ( LabelJustificationInInstance ( getq LabelObjInInstance justify ) ) ) + ( setarray + FinishedLabels + LVSNode + ( dbCreateLabel + CellView + LabelLayerInInstance + ( dbTransformPoint + LabelPosInInstance + ( getq + Instance + transform ) ) + LVSNode + LabelJustificationInInstance + LabelOrientationInInstance + LabelFontInInstance + LabelHeightInInstance ) + ) ) ) ) ) ) ) ) ) + + ( ListFindElementsInList + ( getq CellView shapes ) + LVSNodes + (lambda + ( Shape LVSNode LabelTable ) + (when ( equal + ( getq Shape objType ) + "label" ) + (when ( equal + ( getq Shape theLabel ) + LVSNode ) + (if ( arrayref + LabelTable + LVSNode ) + t + (let () + ( setarray + LabelTable + LVSNode + Shape ) + t ) ) ) ) ) + ( list FinishedLabels ) ) + + ( setarray + LVSNodesLabelsTable + ( getq CellView cellName ) + FinishedLabels ) ) + nil ) + +;Copies a hierarchy of cells rooted by RootCellView to a temporary directory +;and changes all the cell names, instance names, and label texts as dictacted +;by the contents of the skill name table files in TableDirectory. +(defun GDSIIHierCopyAndMungeCellsForExport ( TableDirectory + GDSIILibraryName + RootCellView + LibCellExpressionPairsToIgnore + GateLibName + StackLibName + AbstractFunc + AbstractArgs + NetNamesToAvoid + DeletedInstanceLPP + ) + (let ( + ( LVSNodesLabelsTable ( makeTable "labelTablesTable" nil ) ) + ; Get bottoms up list of cells to export. + ( CellViewsToCopy ( HierarchyGetAllCellsInTree + RootCellView + LibCellExpressionPairsToIgnore ) ) + ( FilesInTableDirectory ( getDirFiles TableDirectory ) ) + ( TargetLibraryDDObj ( ddGetObj GDSIILibraryName ) ) + ( TopLevelCellView nil ) + ( CellsToCompleteBrokenNets ( makeTable `foo nil ) ) + ( ErrorStr nil ) ) + + (when ( and FilesInTableDirectory TargetLibraryDDObj CellViewsToCopy ) + (unless ErrorStr + ( foreach + CellViewToCopy + CellViewsToCopy + (unless ErrorStr + (let ( + ; Get the skill name table file for the current cell. + ( TableFile ( GDSIIHierGetTableFileForCellView + CellViewToCopy + TableDirectory ) ) + ( CellName ( getq CellViewToCopy cellName ) ) ) + (if ( isReadable TableFile ) + (let () + ( printf "Loading %L\n" TableFile ) + ( load TableFile ) ) + (let () + ( printf "Unable to get name file %L for %L\n" TableFile CellName ) + ( defvar CadenceNodeToGDSIINodeTable ( makeTable "foo" nil ) ) + ( defvar CadenceCellToGDSIICellTable ( makeTable "bar" nil ) ) + ( defvar CadenceInstanceToGDSIIInstanceTable ( makeTable "baz" nil ) ) + ( setarray + CadenceCellToGDSIICellTable + CellName + ( GDSIIHierMakeNameGDSIISafe CellName ) ) ) ) + (let ( + ( GDSIICellName + ( arrayref + CadenceCellToGDSIICellTable + ( getq CellViewToCopy cellName ) ) ) ) + (if GDSIICellName + ;Copy the current cell to its new name in the + ;temporary library. + (let ( + ( CellViewCopy ( dbCopyCellView + CellViewToCopy + GDSIILibraryName + GDSIICellName + ( getq CellViewToCopy viewName ) + nil + nil + t ) ) ) + (if CellViewCopy + (let () + ( dbReplaceProp + CellViewCopy + "includeInPartialExtract" + "boolean" + ( not ( isReadable TableFile ) ) ) + (when ( and + ( equal + ( getq CellViewToCopy libName ) + ( getq RootCellView libName ) ) + ( equal + ( getq CellViewToCopy cellName ) + ( getq RootCellView cellName ) ) + ( equal + ( getq CellViewToCopy viewName ) + ( getq RootCellView viewName ) ) ) + ( setq TopLevelCellView CellViewCopy ) ) + + ;don't munge if it's only got globals or other weird cells + (when ( or + ( null + ( getq CellViewCopy instanceMasters ) ) + ( exists + Master + ( getq CellViewCopy instanceMasters ) + (let () + (unless Master + ( setq + ErrorStr + ( sprintf + nil + "An instance is invalid in %L %L %L (look for flashing white boxes!)" + ( getq CellViewToCopy libName ) + ( getq CellViewToCopy cellName ) + ( getq CellViewToCopy viewName ) ) ) ) + ( and + ( null ErrorStr ) + ;( not ( equal ( getq Master libName ) "globals" ) ) + ( car ( NameParseCellName + ( getq Master cellName ) ) ) ) ) ) ) + + ;Munge the instances to point at cells in the temporary library, + ;rename instance names, and rename node names. + ( setq ErrorStr ( GDSIIHierMungeCellCopy + CellViewCopy + CadenceNodeToGDSIINodeTable + CadenceCellToGDSIICellTable + CadenceInstanceToGDSIIInstanceTable + (lambda + ( GDSIICellName + ViewName + GDSIIExportLib ) + ( GDSIIHierGetGDSIIExportMungedCellView + GDSIICellName + ViewName + GDSIIExportLib ) ) + ( list GDSIILibraryName ) + LibCellExpressionPairsToIgnore ) ) ) + + ;assura3.1.2 renders lvs-nodes unnecessary + (unless ( or t ErrorStr ) + (let ( + ( LVSNodesTableFile + ( GDSIIHierGetLVSNodesTableFileForCellView + CellViewToCopy + TableDirectory ) ) ) + + + (when ( isReadable LVSNodesTableFile ) + ( printf "Loading %L\n" LVSNodesTableFile ) + ( load LVSNodesTableFile ) + ( setq + ErrorStr + ( GDSIIHierDoLVSNodes + CellViewCopy + LVSNodesLabelsTable + GDSIILVSNodesTable ) ) ) ) ) + + (unless ErrorStr + ( dbSave CellViewCopy ) + (let ( + ( PartialExtractTableFile ( GDSIIHierGetPartialExtractTableFileForCellView + CellViewToCopy + TableDirectory ) ) ) + (when ( isReadable PartialExtractTableFile ) + ( printf "Loading %L\n" PartialExtractTableFile ) + ( load PartialExtractTableFile ) + ( foreach + SubTypeName + PartialExtractTable + (let ( + ( SubTypeCellView ( dbCopyCellView + CellViewCopy + GDSIILibraryName + SubTypeName + ( getq CellViewCopy viewName ) + nil + nil + t ) ) + + ( InstancesToDelete ( makeTable `foo nil ) ) + ( SubTypeTable ( arrayref PartialExtractTable SubTypeName ) ) ) + (let ( + ( ErrorStr + ( GDSIIHierFixInstancesForPartialExtract + SubTypeCellView + SubTypeTable + InstancesToDelete + ) ) ) + + ;cell is 'broken' so draw labels on top level + ;and later run assura to complete the nets + (when ( tableToList InstancesToDelete ) + ( setarray + CellsToCompleteBrokenNets + ( getq SubTypeCellView cellName ) + InstancesToDelete ) ) + + (unless ErrorStr + ( dbSave SubTypeCellView ) + (when ( and + ( equal + ( getq CellViewToCopy libName ) + ( getq RootCellView libName ) ) + ( equal + ( getq CellViewToCopy cellName ) + ( getq RootCellView cellName ) ) + ( equal + ( getq CellViewToCopy viewName ) + ( getq RootCellView viewName ) ) ) + ( setq TopLevelCellView SubTypeCellView ) ) ) ) ) ) + + ( defvar PartialExtractTable ( makeTable "partialExtractTable" nil ) ) ) ) ) ) + + ( setq + ErrorStr + ( sprintf + nil + "Could not copy %L %L %L to %L %L %L" + ( getq CellViewToCopy libName ) + ( getq CellViewToCopy cellName ) + ( getq CellViewToCopy viewName ) + GDSIILibraryName + GDSIICellName + ( getq CellViewToCopy viewName ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "Could not get GDSII name for %L %L %L" + ( getq CellViewToCopy libName ) + ( getq CellViewToCopy cellName ) + ( getq CellViewToCopy viewName ) ) ) ) ) ) ) ) ) + + ;complete potentially broken nets by drawing labels for all ports of broken subtypes, + ; and using assura to gather all shapes attached to these labels + (unless ErrorStr + (when ( and t ( tableToList CellsToCompleteBrokenNets ) ) + (let ( + ( CopyOfTopLevelCellView + ( dbCopyCellView + TopLevelCellView + TempLibName + ( getq TopLevelCellView cellName ) + "pre-abstract" ) ) ) + (let ( + ( LabelFuncFactory + ( GDSIIHierGetLabelFuncFactory + CopyOfTopLevelCellView + CellsToCompleteBrokenNets + NetNamesToAvoid + ) ) ) + + ( foreach + SubTypeName + CellsToCompleteBrokenNets + (let ( + ( InstanceNamesToDelete + ( arrayref CellsToCompleteBrokenNets SubTypeName ) ) + ( SubTypeCellView + (cond ( + ( equal + SubTypeName + ( getq TopLevelCellView cellName ) ) + CopyOfTopLevelCellView ) + ( + ( dbOpenCellViewByType + GDSIILibraryName + SubTypeName + ( getq TopLevelCellView viewName ) + nil + "a" ) ) ) ) ) + + ( foreach + InstanceNameToDelete + InstanceNamesToDelete + + ( dbCreateRect + SubTypeCellView + DeletedInstanceLPP + ( getq + ( dbFindAnyInstByName + SubTypeCellView + InstanceNameToDelete ) + bBox ) ) ) + + ( dbSave SubTypeCellView ) + ) ) + + CP = CellsToCompleteBrokenNets + LFF = LabelFuncFactory + + ( ConductorPropogateLabelAndTerminals + CopyOfTopLevelCellView + LabelFuncFactory + 1024 + LibCellExpressionPairsToIgnore + ) + + ( dbSave + CopyOfTopLevelCellView ) + + (when t + (let ( + ( Abstract + ( apply AbstractFunc + ( cons CopyOfTopLevelCellView AbstractArgs ) ) ) ) + ( dbSave + Abstract ) + + ;copy non-pin, non-label shapes and instances(vias) + ( foreach + Fig + ( append + ( setof + Shape + ( getq Abstract shapes ) + ( and + ( not + ( equal ( getq Shape objType ) "label" ) ) + ( not ( getq Shape pin ) ) ) ) + ( getq Abstract instances ) ) + ( dbCopyFig + Fig + TopLevelCellView ) ) ) ) + ) ) ) + + ( dbSave TopLevelCellView ) + ) + (unless ErrorStr + ;delete instances + ( foreach + SubTypeName + CellsToCompleteBrokenNets + (let ( + ( InstanceNamesToDelete + ( arrayref CellsToCompleteBrokenNets SubTypeName ) ) + ( SubTypeCellView + ( dbOpenCellViewByType + GDSIILibraryName + SubTypeName + ( getq TopLevelCellView viewName ) + nil + "a" ) ) ) + + ( foreach + InstanceNameToDelete + InstanceNamesToDelete + + ( dbDeleteObject + ( dbFindAnyInstByName + SubTypeCellView + InstanceNameToDelete ) ) ) + ( dbSave SubTypeCellView ) + ) ) ) + ) + (if ErrorStr + ErrorStr + TopLevelCellView ) ) ) + + +(defun GDSIIHierGetLabelFuncFactory ( TopLevelCellView + CellsToCompleteBrokenNets + NetNamesToAvoid + ) + ( eval + ( ExpressionReplaceSymbolsWithValues + `(lambda ( CellName + InstanceName ) + (let ( + ( InstancesToDelete + ( arrayref + CellsToCompleteBrokenNets + CellName ) ) ) + (let ( + ( CellNetNamesToAvoid `NetNamesToAvoid ) + ( Purpose + (cond ( + ( and + ( tablep InstancesToDelete ) + ( arrayref + InstancesToDelete + InstanceName ) ) + "drawing" ) + ( "net" ) ) ) ) + ( eval + ( ExpressionReplaceSymbolsWithValues + `(lambda ( NetName + Position + LPP ) + ( dbCreateLabel + TopLevelCellView + ( list + ( car ( PinUtilGetValidLayer LPP ) ) + Purpose + ) + Position + ;pruposely have different labels on NetNamesToAvoid + ;so they aren't retrieved by geomGetNet( "XXX*" ) + + (cond ( + ( exists NetNameToAvoid `CellNetNamesToAvoid + ( equal NetNameToAvoid NetName ) ) + ( strcat (cond ( CellName ) ( "ZZZ" ) ) "." NetName ) ) + ( + "XXX" ) ) + "centerCenter" + "R0" + "stick" + 0.1 ) ) + ( list `Purpose `CellName `CellNetNamesToAvoid ) + ) ) ) ) ) + ( list `CellsToCompleteBrokenNets + `TopLevelCellView + `NetNamesToAvoid ) + ) ) ) + + +;Munges and streams out a cell hierarchy rooted by RootCellView. +;Needs StreamOutScript to actually do the streaming. +;The StreamOutScript is given five arguments: +; 1. Library containing cell to stream. +; 2. Cell to stream +; 3. View of cell to stream. +; 4. User units per database unit +; 5. Name of the user unit. + +; See top of this file for top level description of export process. + +(defun GDSIIHierCopyAndMungeAndStreamCellViewForExport ( GDSIIDataDir + TempLibPrefix + TempLibDir + RootCellView + RootCellOutputName + LibCellExpressionPairsToIgnore + GateLibName + StackLibName + AbstractFunc + AbstractArgs + NetNamesToAvoid + DeletedInstanceLPP + StreamOutScript + ) + (let ( + ( TempLibName ( LibCreateTempLibrary + ( techGetTechFile RootCellView ) + TempLibPrefix + TempLibDir ) ) + ( CellName ( getq RootCellView cellName ) ) + ( ViewName ( getq RootCellView viewName ) ) + ( UserUnitsPerDBU ( quotient 1.0 ( getq RootCellView DBUPerUU ) ) ) + ( UserUnits ( getq RootCellView userUnits ) ) ) + (let ( + ; Copy all the cells and change all the names. + ( TopLevelCellViewForExport ( GDSIIHierCopyAndMungeCellsForExport + GDSIIDataDir + TempLibName + RootCellView + LibCellExpressionPairsToIgnore + GateLibName + StackLibName + AbstractFunc + AbstractArgs + NetNamesToAvoid + DeletedInstanceLPP + ) ) ) + (if ( stringp TopLevelCellViewForExport ) + TopLevelCellViewForExport + (let ( + ( StreamOutCmd ( sprintf + nil + "%s \"%s\" \"%s\" \"%s\" %f \"%s\"" + StreamOutScript + TempLibName + RootCellOutputName + ViewName + UserUnitsPerDBU + UserUnits ) ) ) + (unless ( equal + RootCellOutputName + ( getq TopLevelCellViewForExport cellName ) ) + (let ( + ( CopyOfRoot + ( dbCopyCellView + TopLevelCellViewForExport + TempLibName + RootCellOutputName + ViewName + nil + nil + t ) ) ) + ( dbSave CopyOfRoot ) + ( dbPurge CopyOfRoot ) ) ) + + (let ( + ( ExitStatus + ( system StreamOutCmd ) + ) + ) + ;( ddDeleteObj ( ddGetObj TempLibName ) ) + (unless ( equal ExitStatus 0 ) + "ERROR: pipo failed" + ) ) ) ) + ) ) ) + +;Wrapper for GDSIIHierCopyAndMungeAndStreamCellViewForExport that +;takes a CellTripple ( A list containg library name, cell name, and view name ) +;instead of an open cell view object. +(defun GDSIIHierCopyAndMungeAndStreamCellTrippleForExport ( GDSIIDataDir + TempLibPrefix + TempLibDir + RootLibName + RootCellName + RootViewName + RootCellOutputName + LibCellExpressionPairsToIgnore + GateLibName + StackLibName + AbstractFunc + AbstractArgs + NetNamesToAvoid + DeletedInstanceLPP + StreamOutScript ) + (let ( + ( CellViewDDObj ( ddGetObj RootLibName RootCellName RootViewName "pc.db" ) ) ) + (if ( and + CellViewDDObj + ( ddIsObjReadable CellViewDDObj ) ) + (let ( + ( RootCellView ( dbOpenCellViewByType + RootLibName + RootCellName + RootViewName + nil + "r" ) ) ) + + ( GDSIIHierCopyAndMungeAndStreamCellViewForExport + GDSIIDataDir + TempLibPrefix + TempLibDir + RootCellView + (if ( null RootCellOutputName ) + (let ( + ( TableFile ( GDSIIHierGetTableFileForCellView + RootCellView + GDSIIDataDir ) ) ) + ( load TableFile ) + ( arrayref + CadenceCellToGDSIICellTable + ( getq RootCellView cellName ) ) ) + RootCellOutputName ) + LibCellExpressionPairsToIgnore + GateLibName + StackLibName + AbstractFunc + AbstractArgs + NetNamesToAvoid + DeletedInstanceLPP + StreamOutScript ) ) + (let ( + ( ErrorStr + ( sprintf + nil + "ERROR: %L %L %L does not exist." + RootLibName + RootCellName + RootViewName ) ) ) + ErrorStr + ) ) ) ) + + +; Wrapper for GDSIIHierCopyAndMungeAndStreamCellTrippleForExport that passes +; in options from PDK. +(defun GDSIIHierCopyAndMungeAndStreamCellTrippleForExportWithPDKInfo ( GDSIIDataDir + TempLibPrefix + TempLibDir + RootLibName + RootCellName + RootViewName + RootCellOutputName + StreamOutScript + @key + ( AssuraRunLog "/dev/null" ) ) + + + Ret = ( GDSIIHierCopyAndMungeAndStreamCellTrippleForExport + GDSIIDataDir + TempLibPrefix + TempLibDir + RootLibName + RootCellName + RootViewName + RootCellOutputName + ( append + TransistorLibCellPairs + ( append + ContactLibCellExpressionPairs + ( append + GateLibCellPairRegExs + StackLibCellPairRegExs ) ) ) + GateLibraryName + StackLibraryName + `GDSIIHierCreateNetCompletionView + ( list + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/netCompletion.rul" + FulcrumPDKRoot ) + ViaLayerFormat + MetalLayerFormat + MetalLPPs + ViaLPPs + TempLibDir + AssuraRunLog + ) + ( list GNDNetName VddNetName ) + ( list "y0" "drawing" ) + StreamOutScript ) + ( printf "Ret = %L\n" Ret ) + Ret + + ) + + +(defun GDSIIHierCreateNetCompletionView ( CellView + RuleFile + ViaLayerFormat + MetalLayerFormat + MetalLPPs + ViaLPPs + WorkingDir + AssuraRunLog ) + (let ( + ( TempLibName + ( LibCreateTempLibraryFromCellView CellView "ABSTRACT" WorkingDir ) ) + ( AssuraLayerMappings + ( append + ( ListNonDestructiveMapCan + (lambda ( LPP ) + (let ( + ( Num 0 ) ) + ( sscanf ( car LPP ) MetalLayerFormat Num ) + ( list + ( list ( sprintf nil "m%dComplete" Num ) + LPP ) ) ) ) + MetalLPPs ) + ( ListNonDestructiveMapCan + (lambda ( LPP ) + (let ( + ( Num 1 ) + ) + ( sscanf ( car LPP ) ViaLayerFormat Num ) + ( list + ( list ( sprintf nil "via%dComplete" + Num + ) + LPP ) ) ) ) + ViaLPPs ) ) + ) ) + (let ( + ( ErrorStr + ( AssuraRunAssuraLayerProcessor + CellView + TempLibName + CellView->cellName + "netCompletion" + RuleFile + WorkingDir + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ) ) ) + (if ErrorStr + ErrorStr + ( dbOpenCellViewByType + TempLibName + CellView->cellName + "netCompletion" + nil + "a" ) ) ) ) ) + + +(defun GDSIIHierMakeLibrary ( NewLibName DFIIDir TechnologyLibraryName ) + (let ( + ( ExistingLibDDObj ( ddGetObj NewLibName ) ) ) + (if ExistingLibDDObj + ExistingLibDDObj + + (let ( + ( NewLibDir ( NameGetLibDirFromDFIIDirAndLibName + DFIIDir + NewLibName ) ) ) + (if NewLibDir + (if ( isDir NewLibDir ) then + (let ( + ( NewLibDDObj ( ddCreateLib + NewLibName + NewLibDir ) ) ) + (if NewLibDDObj + (let () + ( techBindTechFile NewLibDDObj TechnologyLibraryName ) + NewLibDDObj ) + ( sprintf + nil + "Unable to create library %L in directory %L." + NewLibName + NewLibDir ) ) ) + ( sprintf + nil + "Library %L does not exist, but directory %L does." + NewLibName + NewLibDir ) + + else + (if ( equal + ( FileUtilMakeDir + NewLibDir + t ) + 0 ) + (let ( + ( NewLibDDObj ( ddCreateLib + NewLibName + NewLibDir ) ) ) + (if NewLibDDObj + (let () + ( techBindTechFile NewLibDDObj TechnologyLibraryName ) + NewLibDDObj ) + ( sprintf + nil + "Unable to create library %L in directory %L." + NewLibName + NewLibDir ) ) ) + ( sprintf + nil + "Unable to create directory %L for library %L." + NewLibDir + NewLibName ) ) ) + ( sprintf + nil + "Unable to determine what directory library %L should be in." + NewLibName ) ) ) ) ) ) + + +(defun GDSIIHierCopyAndMungeCellsForImport ( TableDirectory + DFIIDir + LibCellViewTripplesToImport + TechnologyLibraryName + BackStopCellNameMappingsTable ) + (let ( + ( CellViewsToCopy ( HierarchyGetCellDescendantsOfLibCellViewTripples + LibCellViewTripplesToImport + ( list ) + (lambda + ( CellView ) + nil ) + nil ) ) + ( FilesInTableDirectory ( getDirFiles TableDirectory ) ) + ( ErrorStr nil ) ) + (when ( and FilesInTableDirectory CellViewsToCopy ) + (unless ErrorStr + ( foreach + CellViewToCopy + CellViewsToCopy + (unless ErrorStr + (let ( + ( TableFile ( GDSIIHierGetTableFileForCellView + CellViewToCopy + TableDirectory ) ) + ( CellName ( getq CellViewToCopy cellName ) ) ) + (if ( isReadable TableFile ) + (let () + ( printf "Loading %L\n" TableFile ) + ( load TableFile ) ) + (let () + ( printf "Unable to get name file %L for %L\n" TableFile CellName ) + ( defvar CadenceNodeToGDSIINodeTable ( makeTable "foo" nil ) ) + ( defvar CadenceCellToGDSIICellTable ( makeTable "bar" nil ) ) + ( defvar CadenceInstanceToGDSIIInstanceTable ( makeTable "baz" nil ) ) + ( setarray + CadenceCellToGDSIICellTable + CellName + ( arrayref BackStopCellNameMappingsTable CellName ) ) ) ) + (let ( + ( CadenceCellName + ( arrayref + CadenceCellToGDSIICellTable + ( getq CellViewToCopy cellName ) ) ) ) + (if CadenceCellName + (let ( + ( CadenceLibName ( car ( NameParseCellName CadenceCellName ) ) ) ) + (let ( + ( CadenceLibDDObj ( GDSIIHierMakeLibrary + CadenceLibName + DFIIDir + TechnologyLibraryName ) ) ) + (if ( stringp CadenceLibDDObj ) + ( setq ErrorStr CadenceLibDDObj ) + (let ( + ( CellViewCopy ( dbCopyCellView + CellViewToCopy + CadenceLibName + CadenceCellName + ( getq CellViewToCopy viewName ) + nil + nil + t ) ) ) + (if CellViewCopy + (let ( + ( TempCellTable ( makeTable "cellTable" nil ) ) ) + ( foreach + BackstopEntry + ( tableToList BackStopCellNameMappingsTable ) + ( setarray TempCellTable ( car BackstopEntry ) ( cadr BackstopEntry ) ) ) + ( foreach + Entry + ( tableToList CadenceCellToGDSIICellTable ) + ( setarray TempCellTable ( car Entry ) ( cadr Entry ) ) ) + ( setq ErrorStr ( GDSIIHierMungeCellCopy + CellViewCopy + CadenceNodeToGDSIINodeTable + TempCellTable + CadenceInstanceToGDSIIInstanceTable + (lambda + ( CadenceCellName + ViewName ) + ( GDSIIHierGetGDSIIImportMungedCellView + CadenceCellName + ViewName ) ) + nil + ( list ) ) ) + (unless ErrorStr + ( dbSave CellViewCopy ) + ( dbPurge CellViewCopy ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "Could not copy %L %L %L to %L %L %L" + ( getq CellViewToCopy libName ) + ( getq CellViewToCopy cellName ) + ( getq CellViewToCopy viewName ) + CadenceLibraryName + CadenceCellName + ( getq CellViewToCopy viewName ) ) ) ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "Could not get Cadence name for %L %L %L" + ( getq CellViewToCopy libName ) + ( getq CellViewToCopy cellName ) + ( getq CellViewToCopy viewName ) ) ) ) ) ) ) ) ) ) + ErrorStr ) ) + +(defun GDSIIHierCopyAndMungeLibraryForImport ( GDSIIDataDir + DFIIDir + LibName + TechnologyLibraryName + BackStopCellNameMappings ) + (let ( + ( BackStopCellNameMappingsTable + ( makeTable "Cell Name Mappings" nil ) ) + ( LibDDObj ( ddGetObj LibName ) ) ) + ( foreach + Mapping + BackStopCellNameMappings + ( setarray + BackStopCellNameMappingsTable + ( car Mapping ) + ( cadr Mapping ) ) ) + (when LibDDObj + (let ( + ( LibCellViewTripples + ( ListApplyFuncToListAndAccumulateResult + ( getq LibDDObj cells ) + (lambda + ( CellDDObj CurrResult ) + ( ListApplyFuncToListAndAccumulateResult + ( getq CellDDObj views ) + (lambda ( ViewDDObj CurrResult ) + ( cons + ( list + ( getq ( getq ( getq ViewDDObj cell ) lib ) name ) + ( getq ( getq ViewDDObj cell ) name ) + ( getq ViewDDObj name ) ) + CurrResult ) ) + nil + CurrResult ) ) + nil + nil ) ) ) + ( GDSIIHierCopyAndMungeCellsForImport + GDSIIDataDir + DFIIDir + LibCellViewTripples + TechnologyLibraryName + BackStopCellNameMappingsTable ) ) ) ) ) + +(defun GDSIIHierCopyAndMungeLibraryForImportUsingPDKInfo ( GDSIIDataDir + DFIIDir + LibName + BackStopCellNameMappings ) + ( GDSIIHierCopyAndMungeLibraryForImport + GDSIIDataDir + DFIIDir + LibName + TechLibName + BackStopCellNameMappings ) ) + + +; ( GDSIIHierCopyAndMungeCells "~/foo" "GDSIIOut" ( geGetWindowCellView ) ( list "tsmc13lg" "cross_vias" ) ( list ) "gate" ) +;( GDSIIHierCopyAndMungeCells "~/cds/tc3/names" "GDSIIOut" ( geGetWindowCellView ) ( list "tsmc13lg" "cross_vias" ) ( list ) "gate" ) + + +; ( ListRemoveDuplicatesFromStringList ( ListApplyFuncToListAndAccumulateResults ( HierarchyGetAllCellsInTree ( geGetWindowCellView ) ( list ) ) ( lambda ( CellView ) ( getq CellView libName ) ) nil ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/genfromsource/genfromsource.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/genfromsource/genfromsource.il new file mode 100644 index 0000000000..e94c2a7291 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/genfromsource/genfromsource.il @@ -0,0 +1,85 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: GenFromSource +; Parameter: LibName (string) +; CellName (string) +; ViewName (string) +; SkillNetListDir (list) +; SkillDirectivesDir (list) +; Return: GenFromSourceView (CVId) +; +; Takes inputs from SkillNetListDir & SkillDirectivesDir. Create a new +; cell view with LibName CellName ViewName. Create Pcell instances +; according to SkillNetListDir & SkillDirectivesDir in this newly created +; cell view. + +defun( GenFromSourceMain ( LibName CellName ViewName + SkillNetlistDir SkillDirectivesDir) + + GenFromSourceView = dbOpenCellViewByType( + LibName + CellName + ViewName + "maskLayout" + "w" ) + + SyncNetlistGenFromSkillNetlistUsingPDKInfo( + GenFromSourceView + SkillNetlistDir + SkillDirectivesDir + ) + + dbSave( GenFromSourceView ) + GenFromSourceView + ) + +(defun GenFromSource ( ConnectivityCellView + TargetCellView + GateLibCellRegExs + NChainLibCellRegExs + PChainLibCellRegExs + SymbolicViewName + LayoutViewName ) + + + (let ( + ( NChains ( cadr ( NameFilterInstances + ( getq CellView instances ) + NChainLibCellRegExs ) ) ) + ( PChains ( cadr ( NameFilterInstances + ( getq CellView instances ) + PChainLibCellRegExs ) ) ) + ( Gates ( cadr ( NameFilterInstances + ( getq CellView instances ) + GateLibCellRegExs ) ) ) ) + + ( foreach Instance ( append Gates NChains PChains ) + ( GenFromSourceCreateLayoutGateFromSymbolGate + TargetCellView + Instance + LayoutViewName + ) ) ) ) + + +(defun GenFromSourceCreateLayoutGateFromSymbolGate ( TargetCellView + Gate + LayoutViewName ) + (let ( + ( Master ( getq Gate master ) ) ) + ( dbCreateParamInstByMasterName + TargetCellView + ( getq Master libName ) + ( getq Master cellName ) + LayoutViewName + ( getq Gate name ) + ( getq Gate xy ) + ( getq Gate orient ) + 1 + ( PCellGetPropertyList Gate ) ) ) ) + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/area.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/area.il new file mode 100644 index 0000000000..2debeeebdf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/area.il @@ -0,0 +1,283 @@ +defun( GetBboxArea (bbox) + let( (xbl ybl xtr ytr area) + + xbl = caar(bbox) + ybl = cadar(bbox) + xtr = caadr(bbox) + ytr = cadadr(bbox) + area = (xbl-xtr)*(ybl-ytr) + area +)) + + +defun( GetFigArea (fig) + let((minX minY maxX maxY layerName layerPurpose thisArea + boundingBox points xbl ybl xtr ytr x1 x2 y1 y2 prb) + minX = 1.0e10 + minY = 1.0e10 + maxX = -1.0e10 + maxY = -1.0e10 + layerName = car(fig->lpp) + layerPurpose = cadr(fig->lpp) + thisArea = 0.0 + + case( fig~>objType + ( "rect" + boundingBox =fig~>bBox + xbl = caar(boundingBox) + ybl = cadar(boundingBox) + xtr = caadr(boundingBox) + ytr = cadadr(boundingBox) + thisArea = (xbl-xtr)*(ybl-ytr) + if((xblmaxX) then maxX=xtr) + if((ytr>maxY) then maxY=ytr) + if((abs(thisArea) == 0.00) + printf("Warning:found zero area shape! %s (%f %f)\n" layerName xbl ybl)) + ) + ( "polygon" || "PRBoundary" + points = listToVector(fig~>points) + for(k 0 length(points)-1 + if((k < length(points)-1) then k2=k+1 else k2=0) + x1 = car(points[k]) + y1 = cadr(points[k]) + x2 = car(points[k2]) + y2 = cadr(points[k2]) + thisArea = thisArea+ (x1*y2-x2*y1) * 0.5 + if((x1maxX) then maxX=x1) + if((y1>maxY) then maxY=y1)) + thisArea = abs(thisArea) + if((thisArea == 0.00) + printf("Warning:found zero area shape! %s (%f %f)\n" layerName x1 y1)) + ) + ( "path" + points = listToVector(fig~>points) + for(k 0 length(points)-2 + k2=k+1 x1 = car(points[k]) + y1 = cadr(points[k]) + x2 = car(points[k2]) + y2 = cadr(points[k2]) + thisArea = thisArea+ max(abs(x1-x2) abs(y1-y2))*fig~>width + if((x1maxX) then maxX=x2) + if((y2>maxY) then maxY=y2) + if((abs(thisArea) == 0.00) + printf("Warning:found zero area shape! %s (%f %f)\n" layerName x1 y1)) + ) + ) + ( "inst" + prb = fig~>master~>prBoundary + points = listToVector(prb~>points) + for(k 0 length(points)-1 + if((k < length(points)-1) then k2=k+1 else k2=0) + x1 = car(points[k]) + y1 = cadr(points[k]) + x2 = car(points[k2]) + y2 = cadr(points[k2]) + thisArea = thisArea+ (x1*y2-x2*y1) * 0.5 + if((x1maxX) then maxX=x1) + if((y1>maxY) then maxY=y1)) + thisArea = abs(thisArea) + if((thisArea == 0.00) + printf("Warning: No prBoundary object found ! \n")); %s (%f %f)\n" layerName x1 y1)) + ) + ( "clusterBoundary" || "areaBlockage" + points = listToVector(fig~>points) + for(k 0 length(points)-1 + if((k < length(points)-1) then k2=k+1 else k2=0) + x1 = car(points[k]) + y1 = cadr(points[k]) + x2 = car(points[k2]) + y2 = cadr(points[k2]) + thisArea = thisArea+ (x1*y2-x2*y1) * 0.5 + if((x1maxX) then maxX=x1) + if((y1>maxY) then maxY=y1)) + thisArea = abs(thisArea) + if((thisArea == 0.00) + printf("Warning: No prBoundary object found ! \n")); %s (%f %f)\n" layerName x1 y1)) + ) + ( "label" + nil + ) + ( t + printf("Warning: Area of \"%s\" are not calculated.\n" fig~>objType) + nil + ) + ) + thisArea +)) + + +defun( GetSelectedArea () + let(( inst area ) + + foreach( inst geGetSelectedSet() + area = GetFigArea(inst) + if(inst~>isAnyInst + then + (printf "%s -- %3.3fmm^2\n" inst~>cellName area/1000000) + else + (printf "%3.3fmm^2\n" area/1000000) + ) + ) +t + )) + + +defun( GetCellArea (cv) + ;returns the prbound area. if there is more than one, returns the largest. + ;if there is none, returns the bbox + let( (bbox prb found_prb area prbmax prboundary) + + bbox = GetBboxArea(cv->bBox) + + found_prb = nil + prbmax = 0.0 + + prboundary = GetPrbound(cv) + when( prboundary~>objType == "PRBoundary" + found_prb = t + prb = GetFigArea(prboundary) + when( prbmaxshapes + if( car(shape->lpp)=="prBoundary" && cadr(shape->lpp)=="drawing" && shape~>objType != "label" then + when( found_prb printf("Warning: found multiple prbounds in %s\n" cv->cellName) ) + found_prb = t + prb = GetFigArea(shape) + when( prbmaxcellName) + ) + area +)) + + +defun( GetPhantomArea (cv) + let( (area macroarea areas) + + macroarea = 0.0 + foreach( shape cv->shapes + when( car(shape->lpp)=="prBoundary" && cadr(shape->lpp)=="boundary" + macroarea = macroarea+GetFigArea(shape) + ) + ) + areas = list( GetCellArea(cv) macroarea ) + areas +)) + + +defun( PrintCellArea (name areas depth) + printf("%s %3.2f %3.2f\n" name car(areas)/1000000 cadr(areas)/1000000 ) +) + + +defun( ReportAreaRecursive (cv depth @key (file nil)) + let( (instances areas LibCellsToIgnore cell uniqueInstances) + + areas = GetPhantomArea(cv) + + if(!file then + PrintCellArea(cv->cellName areas depth) + else + PrintCellAreaToHtml(cv->cellName areas depth file) + ) + + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + instances = car( NameFilterInstances( cv->instances LibCellsToIgnore )) + uniqueInstances = nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances= cons( inst uniqueInstances ) + ) + ) + foreach( inst uniqueInstances + cell = nrOpenCellViewReadable(inst->libName inst->cellName inst->viewName) + ReportAreaRecursive(cell depth+1 ?file file) + ) +)) + + +defun( ReportPhantomArea () + let( (cv) + cv = geGetWindowCellView() + ReportAreaRecursive(cv 0) + t +)) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; functions to spit out html for Alta +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +defun( ReportAltaArea () + let( (cv file) + + file = (outfile "/nfs/site/disks/wdisk.83/pankala1/area/area.html") + (if !file then + (printf "File %s is not writeable." filename) + else + (fprintf file "%s" AreaHtmlHeader()) + + cv = nrOpenCellViewReadable("chip.rrc" "chip.rrc.RRC.1000" "floorplan") + ReportAreaRecursive(cv 0 ?file file) + + fprintf(file "%s" AreaHtmlFooter()) + close(file) + ) + t +)) + + +defun( PrintCellAreaToHtml (name areas depth file) + let( (cell base) + cell = "" + for( i 0 depth + cell = strcat(cell "      ") + ) + base = cadr( reverse( parseString( name "." ) )) + cell = strcat(cell base) + cell = strcat(cell sprintf(nil "%3.2f" car(areas)/1000000) ) + cell = strcat(cell sprintf(nil "%3.2f\n" cadr(areas)/1000000) ) + fprintf(file "%s" cell) +)) + + +defun( AreaHtmlHeader () + (let (header) + header = sprintf(nil "\n\n") + header = strcat(header "

    This table is generated from the checked-in phantom view of chip.alta.alta.ALTA.1000") + header = strcat(header "

    Please file bugs regarding discrepancies to Steve in Alta Physical Design:Block Area

    ") + header = strcat(header "\n\n") + header = strcat(header "") + header = strcat(header "\n") + header +)) + + +defun( AreaHtmlFooter () + (let (footer) + footer = "\n\n
    CellAreaMacros
    \n" + footer +)) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/bbox.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/bbox.il new file mode 100644 index 0000000000..5c366f50cc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/bbox.il @@ -0,0 +1,160 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun BBoxCanonicalize ( BBox ) + ( list ( list ( min ( caar BBox ) ( caadr BBox ) ) + ( min ( cadar BBox ) ( cadadr BBox ) ) ) + ( list ( max ( caar BBox ) ( caadr BBox ) ) + ( max ( cadar BBox ) ( cadadr BBox ) ) ) ) ) + +(defun BBoxExpandHorizontal ( BBox ExpandWidth ) + ( BBoxExpandHorizontalAsymmetric BBox ExpandWidth ExpandWidth ) ) + +(defun BBoxExpandHorizontalAsymmetric ( BBox StartExpandWidth EndExpandWidth ) + ( BBoxCanonicalize + (cond ( + ( lessp ( caar BBox ) ( caadr BBox ) ) + ( list ( list ( difference ( caar BBox ) StartExpandWidth ) + ( cadar BBox ) + ) + ( list ( plus ( caadr BBox ) EndExpandWidth ) + ( cadadr BBox ) ) ) ) + ( + ( list ( list ( plus ( caar BBox ) StartExpandWidth ) + ( cadar BBox ) + ) + ( list ( difference ( caadr BBox ) EndExpandWidth ) + ( cadadr BBox ) ) ) ) ) ) ) + + +(defun BBoxExpandVertical ( BBox ExpandWidth ) + ( BBoxExpandVerticalAsymmetric BBox ExpandWidth ExpandWidth ) ) + +(defun BBoxExpandVerticalAsymmetric ( BBox StartExpandWidth EndExpandWidth ) + ( BBoxCanonicalize + (cond ( + ( lessp ( cadar BBox ) ( cadadr BBox ) ) + ( list ( list ( caar BBox ) + ( difference ( cadar BBox ) StartExpandWidth ) + ) + ( list ( caadr BBox ) + ( plus ( cadadr BBox ) EndExpandWidth ) ) ) ) + ( + ( list ( list ( caar BBox ) + ( plus ( cadar BBox ) StartExpandWidth ) + ) + ( list ( caadr BBox ) + ( difference ( cadadr BBox ) EndExpandWidth ) ) ) ) ) ) ) + +(defun BBoxGetHeight ( BBox ) + ( difference ( cadadr BBox ) ( cadar BBox ) ) ) + +(defun BBoxGetWidth ( BBox ) + ( difference ( caadr BBox ) ( caar BBox ) ) ) + +(defun BBoxGetCenter ( BBox ) + ( list + ( plus ( caar BBox ) ( times 0.5 ( BBoxGetWidth BBox ) ) ) + ( plus ( cadar BBox ) ( times 0.5 ( BBoxGetHeight BBox ) ) ) ) ) + +;round up to nearest grid spacing +(defun BBoxSnapToHorizontalGrid ( BBox GridSpacing ) + (let ( + ( BoundWidth ( times ( ceiling ( quotient ( BBoxGetWidth BBox ) GridSpacing ) ) + GridSpacing ) ) ) + ( list ( car BBox ) + ( list + ( plus ( caar BBox ) BoundWidth ) + ( cadadr BBox ) ) ) ) ) + +(defun BBoxIsPoint ( BBox ) + ( and ( eqv ( caar BBox ) ( caadr BBox ) ) + ( eqv ( cadar BBox ) ( cadadr BBox ) ) ) ) + + +(defun BBoxClose ( B1 B2 Eps ) + ( and ( lessp ( abs ( difference ( caar B1 ) ( caar B2 ) ) ) Eps ) + ( lessp ( abs ( difference ( caadr B1 ) ( caadr B2 ) ) ) Eps ) + ( lessp ( abs ( difference ( cadar B1 ) ( cadar B2 ) ) ) Eps ) + ( lessp ( abs ( difference ( cadadr B1 ) ( cadadr B2 ) ) ) Eps ) ) ) + + +(defun BBoxGetPolygonEdges ( BBox ) + ( let ( + ( LowerLeft ( car BBox ) ) + ( UpperRight ( cadr BBox ) ) + ) + ( PolygonGetEdges ( list + LowerLeft + ( list ( car UpperRight ) ( cadr LowerLeft ) ) + UpperRight + ( list ( car LowerLeft ) ( cadr UpperRight ) ) + ) + ) + ) +) + + +(defun BBoxSnapOutwardToGrid ( BBox GridSpacing ) + (let (newgrid x1 y1 x2 y2) + x1 = (caar BBox) + y1 = (cadar BBox) + x2 = (caadr BBox) + y2 = (cadadr BBox) + newgrid = (list + (list (floor (round 1000*x1)/(round 1000*GridSpacing))*GridSpacing + (floor (round 1000*y1)/(round 1000*GridSpacing))*GridSpacing ) + (list (ceiling (round 1000*x2)/(round 1000*GridSpacing))*GridSpacing + (ceiling (round 1000*y2)/(round 1000*GridSpacing))*GridSpacing ) + ) + newgrid + ) +) + + +(defun IsBBoxOnGrid ( BBox GridSpacing ) + (let ((ongrid t)) + (when (modulo (round 1000*(caar BBox)) (round 1000*GridSpacing)) != 0 + ongrid = nil + ) + (when (modulo (round 1000*(cadar BBox)) (round 1000*GridSpacing)) != 0 + ongrid = nil + ) + (when (modulo (round 1000*(caadr BBox)) (round 1000*GridSpacing)) != 0 + ongrid = nil + ) + (when (modulo (round 1000*(cadadr BBox)) (round 1000*GridSpacing)) != 0 + ongrid = nil + ) + ongrid + ) +) + +(defun BBoxCombine ( @rest BBoxes ) + (let ( + ( Result nil ) ) + ( foreach BBox BBoxes + (if BBox + (if Result + ( setq + Result + ( list + ( list ( min ( leftEdge Result ) ( leftEdge BBox ) ) + ( min ( bottomEdge Result ) ( bottomEdge BBox ) ) ) + ( list ( max ( rightEdge Result ) ( rightEdge BBox ) ) + ( max ( topEdge Result ) ( topEdge BBox ) ) ) ) ) + ( setq Result BBox ) ) ) ) + Result ) ) + +; Geometric And of two bboxes, or nil if no overlap +(defun BBoxAnd (a b) + (let (x0 y0 x1 y1) + x0 = (max (leftEdge a) (leftEdge b)) + y0 = (max (bottomEdge a) (bottomEdge b)) + x1 = (min (rightEdge a) (rightEdge b)) + y1 = (min (topEdge a) (topEdge b)) + (if x1>=x0 && y1>=y0 (list x0:y0 x1:y1) nil) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/corner.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/corner.il new file mode 100644 index 0000000000..6559ab6220 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/corner.il @@ -0,0 +1,48 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun CornerIsNoEntry ( Corner ) + ( null ( car Corner ) ) +) + +(defun CornerIsNoExit ( Corner ) + ( null ( caddr Corner ) ) +) + +(defun CornerIsStraightLine ( Corner ) + ( or ( and ( eqv ( car ( car Corner ) ) ( car ( cadr Corner ) ) ) + ( eqv ( car ( car Corner ) ) ( car ( caddr Corner ) ) ) + ) + ( and ( eqv ( cadr ( car Corner ) ) ( cadr ( cadr Corner ) ) ) + ( eqv ( cadr ( car Corner ) ) ( cadr ( caddr Corner ) ) ) + ) + ) +) + +(defun CornerGetEntryLine ( Corner ) + ( list ( car Corner ) ( cadr Corner ) ) +) + +(defun CornerGetExitLine ( Corner ) + ( cdr Corner ) +) + +(defun CornerTurnsRelativeLeft ( Corner ) + (if ( LineIsSegmentIncreasing ( CornerGetEntryLine Corner ) ) + (if ( null ( LineIsSegmentIncreasing ( CornerGetExitLine Corner ) ) ) + t ) + (if ( LineIsSegmentIncreasing ( CornerGetExitLine Corner ) ) + t ) ) ) + +(defun CornerGetCornerPoint ( Corner ) + ( cond ( + ( CornerIsNoEntry Corner ) + ( car ( CornerGetExitLine Corner ) ) + ) + ( + ( cadr ( CornerGetEntryLine Corner ) ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/fig.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/fig.il new file mode 100644 index 0000000000..c42975f4fd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/fig.il @@ -0,0 +1,68 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + +(defun FigGetPolygonEdgesForFig ( Fig ) + (let ( + ( ObjType ( getq Fig objType ) ) ) + (cond ( + ( equal ObjType "path" ) + ( PolygonGetEdges ( PathGetPolygonPoints + Fig ) ) ) + ( + ( equal ObjType "polygon" ) + ( PolygonGetEdges ( getq Fig points ) ) ) + ( + ( BBoxGetPolygonEdges ( getq Fig bBox ) ) ) ) ) ) + +(defun FigGetRectInsideFig ( Fig ) + (let ( + ( ObjType ( getq Fig objType ) ) ) + (cond ( + ( equal ObjType "rect" ) + ( getq Fig bBox ) ) + ( + ( equal ObjType "inst" ) + ( getq Fig bBox ) ) + ( + ( equal ObjType "path" ) + ( PolygonGetRectInsidePolygon + ( PathGetPolygonPoints + Fig ) ) ) + ( + ( equal ObjType "donut" ) + ( RectMakeFromCenter ( FigGetValidPoint Fig ) + ( quotient ( difference ( getq Fig outerRadius ) ( getq Fig innerRadius ) ) 2.0 ) + ( quotient ( difference ( getq Fig outerRadius ) ( getq Fig innerRadius ) ) 2.0 ) ) ) + ( + ( equal ObjType "polygon" ) + ( PolygonGetRectInsidePolygon ( getq Fig points ) ) ) + ( + ( getq Fig bBox ) ) ) ) ) + + + +(defun FigGetValidPoint ( Fig ) + (let ( + ( ObjType ( getq Fig objType ) ) ) + (cond ( + ( equal ObjType "rect" ) + ( BBoxGetCenter ( getq Fig bBox ) ) + ) + ( + ( equal ObjType "path" ) + ( cadr ( getq Fig points ) ) + ) + ( + ( equal ObjType "polygon" ) + ( car ( getq Fig points ) ) + ) + ( + ( equal ObjType "donut" ) + ( plus ( getq Fig xy ) ( quotient ( plus ( getq Fig innerRadius ) ( getq Fig outerRadius ) ) 2.0 ) ) + ) + ( + ( BBoxGetCenter ( getq Fig bBox ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/line.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/line.il new file mode 100644 index 0000000000..a18d744636 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/line.il @@ -0,0 +1,311 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun LineIsManhattan ( Line ) + ( or ( LineIsSegmentVertical Line ) + ( LineIsSegmentHorizontal Line ) ) ) + +(defun LineIsSegmentVertical ( SegmentPoints ) + (let ( + ( Point0 ( car SegmentPoints ) ) + ( Point1 ( cadr SegmentPoints ) ) ) + (let ( + ( X0 ( car Point0 ) ) + ( X1 ( car Point1 ) ) ) + ( equal X0 X1 ) ) ) ) + +(defun LineIsSegmentHorizontal ( SegmentPoints ) + (let ( + ( Point0 ( car SegmentPoints ) ) + ( Point1 ( cadr SegmentPoints ) ) ) + (let ( + ( Y0 ( cadr Point0 ) ) + ( Y1 ( cadr Point1 ) ) ) + ( equal Y0 Y1 ) ) ) ) + +(defun LineGetSegmentMaxX ( SegmentPoints ) + (let ( + ( Point0 ( car SegmentPoints ) ) + ( Point1 ( cadr SegmentPoints ) ) ) + (let ( + ( X0 ( car Point0 ) ) + ( X1 ( car Point1 ) ) ) + (when ( and X0 X1 ) + ( max X0 X1 ) ) ) ) ) + +(defun LineGetSegmentMaxY ( SegmentPoints ) + (let ( + ( Point0 ( car SegmentPoints ) ) + ( Point1 ( cadr SegmentPoints ) ) ) + (let ( + ( Y0 ( cadr Point0 ) ) + ( Y1 ( cadr Point1 ) ) ) + (when ( and Y0 Y1 ) + ( max Y0 Y1 ) ) ) ) ) + +(defun LineGetSegmentMinX ( SegmentPoints ) + (let ( + ( Point0 ( car SegmentPoints ) ) + ( Point1 ( cadr SegmentPoints ) ) ) + (let ( + ( X0 ( car Point0 ) ) + ( X1 ( car Point1 ) ) ) + (when ( and X0 X1 ) + ( min X0 X1 ) ) ) ) ) + +(defun LineGetSegmentMinY ( SegmentPoints ) + (let ( + ( Point0 ( car SegmentPoints ) ) + ( Point1 ( cadr SegmentPoints ) ) ) + (let ( + ( Y0 ( cadr Point0 ) ) + ( Y1 ( cadr Point1 ) ) ) + (when ( and Y0 Y1 ) + ( min Y0 Y1 ) ) ) ) ) + + +(defun LineMakeLineDataFromPoints ( Point1 Point2 ) + (let ( + ( X0 ( car Point1 ) ) + ( Y0 ( cadr Point1 ) ) + ( X1 ( car Point2 ) ) + ( Y1 ( cadr Point2 ) ) ) + (if ( equal X0 X1 ) + ( list nil X0 ) + (let ( + ( Slope ( quotient + ( float ( difference Y1 Y0 ) ) + ( float ( difference X1 X0 ) ) ) ) ) + (let ( + ( Intercept ( float ( difference Y0 ( times Slope ( float X0 ) ) ) ) ) ) + ( list Slope Intercept ) ) ) ) ) ) + +(defun LineMakeLineDataFromPointList ( PointList ) + ( LineMakeLineDataFromPoints ( car PointList ) ( cadr PointList ) ) ) + +(defun LineSolveForX ( LineData Y ) + (unless ( equal ( float ( car LineData ) ) ( float 0 ) ) + (if ( car LineData ) + ( quotient + ( float + ( difference Y ( cadr LineData ) ) ) + ( car LineData ) ) + ( cadr LineData ) ) ) ) + +(defun LineSolveForY ( LineData X ) + (when ( car LineData ) + ( plus + ( times + ( float ( car LineData ) ) + ( float X ) ) + ( float ( cadr LineData ) ) ) ) ) + +(defun LineGetClosestPointOnLineToPoint ( Point LineData ) + (let ( + ( PointX ( float ( car Point ) ) ) + ( PointY ( float ( cadr Point ) ) ) + ( Slope ( car LineData ) ) + ( Intercept ( cadr LineData ) ) ) + (if Slope + (let ( + ( Slope ( float Slope ) ) + ( Intercept ( float Intercept ) ) + ) + (let ( + ( RetX ( quotient + ( difference + ( plus + PointX + ( times PointY Slope) ) + ( times Intercept Slope ) ) + ( plus + ( times Slope Slope ) + 1 ) ) ) ) + ( list + RetX + ( plus + ( times RetX Slope ) + Intercept ) ) ) ) + ( list ( cadr LineData ) PointY ) ) ) ) + +(defun LineGetSegmentLength ( LineSegmentPoints ) + (let ( + ( Point0 ( car LineSegmentPoints ) ) + ( Point1 ( cadr LineSegmentPoints ) ) ) + (let ( + ( X0 ( float ( car Point0 ) ) ) + ( Y0 ( float ( cadr Point0 ) ) ) + ( X1 ( float ( car Point1 ) ) ) + ( Y1 ( float ( cadr Point1 ) ) ) ) + (let ( + ( XDiff ( difference X1 X0 ) ) + ( YDiff ( difference Y1 Y0 ) ) ) + ( sqrt + ( plus + ( times XDiff XDiff ) + ( times YDiff YDiff ) ) ) ) ) ) ) + +(defun LinePointIsOnSegment ( Point LineSegmentPoints ) + (let ( + ( Point0 ( car LineSegmentPoints ) ) + ( Point1 ( cadr LineSegmentPoints ) ) ) + (let ( + ( X0 ( float ( car Point0 ) ) ) + ( Y0 ( float ( cadr Point0 ) ) ) + ( X1 ( float ( car Point1 ) ) ) + ( Y1 ( float ( cadr Point1 ) ) ) + ( X2 ( float ( car Point ) ) ) + ( Y2 ( float ( cadr Point ) ) ) ) + (let ( + ( SegmentMaxX ( max X0 X1 ) ) + ( SegmentMinX ( min X0 X1 ) ) + ( SegmentMaxY ( max Y0 Y1 ) ) + ( SegmentMinY ( min Y0 Y1 ) ) ) + ( and + ( leqp X2 SegmentMaxX ) + ( geqp X2 SegmentMinX ) + ( leqp Y2 SegmentMaxY ) + ( geqp Y2 SegmentMinY ) + (if ( equal X0 X1 ) + ( equal X2 X0 ) + ( equal + Y2 + ( LineSolveForY + ( LineMakeLineDataFromPoints Point0 Point1 ) + X2 ) ) ) ) ) ) ) ) + + + +(defun LineGetClosestPointOnSegmentToPoint ( Point LineSegmentPoints ) + (let ( + ( SegmentLine ( LineMakeLineDataFromPoints + ( car LineSegmentPoints ) + ( cadr LineSegmentPoints ) ) ) ) + (let ( + ( ClosePointOnSegmentLine ( LineGetClosestPointOnLineToPoint + Point + SegmentLine ) ) ) + + (if ( LinePointIsOnSegment ClosePointOnSegmentLine LineSegmentPoints ) + ClosePointOnSegmentLine + (let ( + ( Point0 ( car LineSegmentPoints ) ) + ( Point1 ( cadr LineSegmentPoints ) ) ) + (let ( + ( PointPoint0Distance ( LineGetSegmentLength ( list Point0 Point ) ) ) + ( PointPoint1Distance ( LineGetSegmentLength ( list Point1 Point ) ) ) + ) + (if ( lessp PointPoint0Distance PointPoint1Distance ) + Point0 + Point1 ) ) ) ) ) ) ) + + +(defun LineGetXRange ( Line ) + (when Line + ( RangeCanonicalize + ( list ( caar Line ) ( caadr Line ) ) ) ) ) + +(defun LineGetYRange ( Line ) + (when Line + ( RangeCanonicalize + ( list ( cadar Line ) ( cadadr Line ) ) ) ) ) + + +(defun LineIsPoint ( Line ) + ( and ( eq ( caar Line ) ( caadr Line ) ) + ( eq ( cadar Line ) ( cadadr Line ) ) + ) +) + +(defun LineIsNoStart ( Line ) + ( null ( car Line ) ) +) + +(defun LineIsNoEnd ( Line ) + ( null ( cadr Line ) ) +) + +(defun LineIsSegmentIncreasing ( Line ) + ( and ( leqp ( caar Line ) ( caadr Line ) ) ( leqp ( cadar Line ) ( cadadr Line ) ) ) +) + +;returns nil if no intersect +(defun LineGetIntersectX ( LineData1 LineData2 ) + (if ( null ( car LineData1 ) ) + (if ( null ( car LineData2 ) ) + ;both vertical + (if ( equal ( cadr LineData1 ) ( cadr LineData2 ) ) + ( cadr LineData1 ) + nil ) + ;first is vertical + ( cadr LineData1 ) ) + (if ( null ( car LineData2 ) ) + ;second is vertical + ( cadr LineData2 ) + ;neither vertical + (if ( equal ( car LineData1 ) ( car LineData2 ) ) + ;parallel + nil + ;normal + ( quotient ( difference ( cadr LineData2 ) ( cadr LineData1 ) ) + ( difference ( car LineData1 ) ( car LineData2 ) ) ) ) ) ) ) + +(defun LineIntersect ( Line1 Line2 ) + (let ( + ( LineData1 ( LineMakeLineDataFromPointList Line1 ) ) + ( LineData2 ( LineMakeLineDataFromPointList Line2 ) ) ) + ;parallel + (if ( LineParallel Line1 Line2 ) + ( and + ( RangeIntersection ( LineGetXRange Line1 ) + ( LineGetXRange Line2 ) ) + ( RangeIntersection ( LineGetYRange Line1 ) + ( LineGetYRange Line2 ) ) ) + (let ( + ( IntersectX ( LineGetIntersectX LineData1 LineData2 ) ) ) + ;check to see if intersection is in segment + (if IntersectX + (let ( + ( IntersectY + (if ( car LineData1 ) + ( LineSolveForY LineData1 IntersectX ) + ( LineSolveForY LineData2 IntersectX ) ) ) ) + (if IntersectY + ( and ( RangeIsNumberInRangeClose IntersectX ( LineGetXRange Line1 ) 1e-9 ) + ( RangeIsNumberInRangeClose IntersectX ( LineGetXRange Line2 ) 1e-9 ) + ( RangeIsNumberInRangeClose IntersectY ( LineGetYRange Line1 ) 1e-9 ) + ( RangeIsNumberInRangeClose IntersectY ( LineGetYRange Line2 ) 1e-9 ) ) ) ) ) ) ) ) ) + +(defun LineIntersectNoEndPointsAllowed ( Line1 Line2 ) + ( and ( LineIntersect Line1 Line2 ) + ( not ( LineIntersectAtEndPoint Line1 Line2 ) ) ) ) + +(defun LineContainsLine ( BigLine LittleLine ) + ( and + ( LineParallel BigLine LittleLine ) + ( RangeIsRangeInRangeClose ( LineGetXRange LittleLine ) + ( LineGetXRange BigLine 1e-9 ) ) + ( RangeIsRangeInRangeClose ( LineGetYRange LittleLine ) + ( LineGetYRange BigLine 1e-9 ) ) ) ) + +(defun LineParallel ( Line1 Line2 ) + (let ( + ( LineData1 ( LineMakeLineDataFromPointList Line1 ) ) + ( LineData2 ( LineMakeLineDataFromPointList Line2 ) ) ) + ( equal (if ( car LineData1 ) ( abs ( car LineData1 ) ) nil ) + (if ( car LineData2 ) ( abs ( car LineData2 ) ) nil ) ) ) ) + +(defun LineIntersectAtEndPoint ( Line1 Line2 ) + ( or + ( LinePointIsOnSegment ( car Line1 ) Line2 ) + ( LinePointIsOnSegment ( cadr Line1 ) Line2 ) + ( LinePointIsOnSegment ( car Line2 ) Line1 ) + ( LinePointIsOnSegment ( cadr Line2 ) Line1 ) ) ) + +(defun LineOverlap ( Line1 Line2 ) + ( and + ( LineParallel Line1 Line2 ) + ( LineIntersect Line1 Line2 ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/path.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/path.il new file mode 100644 index 0000000000..6f971d7acf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/path.il @@ -0,0 +1,153 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun PathGetPolygonPoints ( Path ) + (let ( + ( Width ( getq Path width ) ) + ( BeginExt ( getq Path beginExt ) ) + ( EndExt ( getq Path endExt ) ) + ( Points ( ListUniq ( getq Path points ) ) ) ) + ( PathGetPolygonPointsImpl + Points + BeginExt + EndExt + Width ) ) ) + + +(defun PathGetPolygonPointsImpl ( Points + BeginExt + EndExt + Width ) + (let ( + ( Width ( times 0.5 Width ) ) + ( RevPoints ( reverse ( copy Points ) ) ) ) + ( append + ( PathGetLeftRightHandPointsForLine + ( list ( car Points ) ( cadr Points ) ) + BeginExt + Width ) + ( append + ( append + ( PathGetRightHandedPoints + Points + Width ) + ( PathGetLeftRightHandPointsForLine + ( list ( car RevPoints ) ( cadr RevPoints ) ) + EndExt + Width ) ) + ( PathGetRightHandedPoints + RevPoints + Width ) ) + ) ) ) + +(defun PathGetRightHandedPoints ( Points + Width ) + ( mapcar + (lambda ( Corner ) + ( PathGetRightHandedPointForCorner + Corner + Width ) ) + ( ListRemoveLastNElements + ( maplist + (lambda ( List ) + ( list ( car List ) ( cadr List ) ( caddr List ) ) ) + Points ) + 2 ) ) ) + +(defun PathGetRightHandedPointForCorner ( Corner + Width ) + (let ( + ( Line ( CornerGetEntryLine Corner ) ) + ( Point ( CornerGetCornerPoint Corner ) ) ) + (cond ( + ( LineIsSegmentHorizontal Line ) + (cond ( + ( LineIsSegmentIncreasing Line ) + (cond ( + ( CornerTurnsRelativeLeft Corner ) + ( PointAdd Point ( list -Width -Width ) ) ) + ( + ( PointAdd Point ( list Width -Width ) ) ) ) ) + ( + t + (cond ( + ( CornerTurnsRelativeLeft Corner ) + ( PointAdd Point ( list Width Width ) ) ) + ( + ( PointAdd Point ( list -Width Width ) ) ) ) ) ) ) + ( + t + (cond ( + ( LineIsSegmentIncreasing Line ) + (cond ( + ( CornerTurnsRelativeLeft Corner ) + ( PointAdd Point ( list Width Width ) ) ) + ( + ( PointAdd Point ( list Width -Width ) ) ) ) ) + ( + t + (cond ( + ( CornerTurnsRelativeLeft Corner ) + ( PointAdd Point ( list -Width -Width ) ) ) + ( + ( PointAdd Point ( list -Width Width ) ) ) ) ) ) ) ) ) ) + + + +(defun PathGetLeftRightHandPointsForLine ( Line + Extension + Width ) + (let ( + ( Point ( car Line ) ) + ( HLOffset ( list Extension -Width ) ) + ( HROffset ( list Extension Width ) ) ) + (cond ( + ( LineIsSegmentHorizontal Line ) + (cond ( + ( LineIsSegmentIncreasing Line ) + ( list + ( PointDifference Point HLOffset ) + ( PointDifference Point HROffset ) ) ) + ( + ( list + ( PointAdd Point HLOffset ) + ( PointAdd Point HROffset ) ) ) ) ) + ( + t + (cond ( + ( LineIsSegmentIncreasing Line ) + ( list + ( PointDifference Point ( reverse HLOffset ) ) + ( PointDifference Point ( reverse HROffset ) ) ) ) + ( + ( list + ( PointAdd Point ( reverse HLOffset ) ) + ( PointAdd Point ( reverse HROffset ) ) ) ) ) ) ) ) ) + + +(defun PathRoundPointsToGrid ( points @key (grid MfgGrid) ) + (let (x y newpoints) + newpoints = nil + (foreach point points + x = (round 1/grid*(car point))*grid + y = (round 1/grid*(cadr point))*grid + newpoints = (cons (list x y) newpoints) + ) + (reverse newpoints) + ) +) + +(defun PathGetDistance ( Path ) + (letseq ( + ( Sum 0 ) + ( Points ( getq Path points ) ) + ( LastPoint ( car Points ) ) + ) + ( foreach + Point + ( cdr Points ) + ( setq Sum ( plus Sum ( PointGetDistance LastPoint Point ) ) ) + ( setq LastPoint Point ) ) + Sum ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/point.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/point.il new file mode 100644 index 0000000000..9391944d76 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/point.il @@ -0,0 +1,30 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun PointDifference ( Point1 Point2 ) + ( list ( difference ( car Point1 ) ( car Point2 ) ) + ( difference ( cadr Point1 ) ( cadr Point2 ) ) ) ) + +(defun PointAdd ( Point1 Point2 ) + ( list ( plus ( car Point1 ) ( car Point2 ) ) + ( plus ( cadr Point1 ) ( cadr Point2 ) ) ) ) + +(defun PointGetDistance ( Point1 Point2 ) + (let ( + ( XDist ( difference ( car Point1 ) ( car Point2 ) ) ) + ( YDist ( difference ( cadr Point1 ) ( cadr Point2 ) ) ) ) + ( sqrt ( plus ( times XDist XDist ) + ( times YDist YDist ) ) ) ) ) + +(defun PointManhattanDistance ( Point1 Point2 ) + (let ( + ( XDist ( difference ( car Point1 ) ( car Point2 ) ) ) + ( YDist ( difference ( cadr Point1 ) ( cadr Point2 ) ) ) ) + ( plus ( abs XDist ) ( abs YDist ) ) ) ) + +(defun PointScale ( Point S ) + ( list + ( times ( car Point ) S ) + ( times ( cadr Point ) S ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/polygon.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/polygon.il new file mode 100644 index 0000000000..7bc98522bf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/polygon.il @@ -0,0 +1,840 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun PolygonComparePointX ( Point0 Point1 ) + ( difference + ( car Point0 ) + ( car Point1 ) ) ) + +(defun PolygonComparePointY ( Point0 Point1 ) + ( difference + ( car ( cdr Point0 ) ) + ( car ( cdr Point1 ) ) ) ) + +(defun PolygonComparePointXY ( Point0 Point1 XMult YMult ) + (let ( + ( XResult ( PolygonComparePointX + Point0 + Point1 ) ) ) + (if ( equal XResult 0 ) + ( times + ( PolygonComparePointY + Point0 + Point1 ) + YMult ) + ( times XResult XMult ) ) ) ) + + +(defun PolygonComparePointYX ( Point0 Point1 YMult XMult ) + (let ( + ( YResult ( PolygonComparePointY + Point0 + Point1 ) ) ) + (if ( equal YResult 0 ) + ( times + ( PolygonComparePointX + Point0 + Point1 ) + XMult ) + ( times YResult YMult ) ) ) ) + +(defun PolygonGetBottomLeftPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointYX + CurrPoint + CurrRet + 1 + 1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + +(defun PolygonGetLeftBottomPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointXY + CurrPoint + CurrRet + 1 + 1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + + + +(defun PolygonGetLeftTopPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointXY + CurrPoint + CurrRet + -1 + -1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + + +(defun PolygonGetTopLeftPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointYX + CurrPoint + CurrRet + -1 + -1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + + +(defun PolygonGetTopRightPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointYX + CurrRet + CurrPoint + -1 + -1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + + +(defun PolygonGetRightTopPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointXY + CurrRet + CurrPoint + -1 + -1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + +(defun PolygonGetRightBottomPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointXY + CurrRet + CurrPoint + -1 + 1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + +(defun PolygonGetBottomRightPoint ( PointList ) + (let ( + ( CurrRet ( car PointList ) ) + ( RemainingPoints ( cdr PointList ) ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) + ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + (when ( lessp ( PolygonComparePointYX + CurrRet + CurrPoint + 1 + -1 ) + 0 ) + ( setq CurrRet CurrPoint ) ) ) ) + CurrRet ) ) + + + + + +(defun PolygonGetEdges ( PolygonPointList ) + (let ( + ( FirstPoint ( car PolygonPointList ) ) + ( PrevPoint ( car PolygonPointList ) ) + ( RemainingPoints ( cdr PolygonPointList ) ) + ( Ret nil ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + ( setq Ret ( tconc Ret ( list PrevPoint CurrPoint ) ) ) + ( setq PrevPoint CurrPoint ) ) ) + (when ( car ( car PolygonPointList ) ) + ( setq Ret ( tconc Ret ( list PrevPoint FirstPoint ) ) ) ) + ( car Ret ) ) ) + + +(defun PolygonEdgeHasY ( Edge YPos ) + (let ( + ( Y0 ( cadr ( car Edge ) ) ) + ( Y1 ( cadr ( cadr Edge ) ) ) ) + Y0=round(Y0/MfgGrid)*MfgGrid + Y1=round(Y1/MfgGrid)*MfgGrid + YPos=round(YPos/MfgGrid)*MfgGrid + ( or + ( and + ( lessp Y0 Y1 ) + ( and + ( not ( greaterp Y0 YPos ) ) + ( not ( greaterp YPos Y1 ) ) ) ) + ( and + ( greaterp Y0 Y1 ) + ( and + ( not ( greaterp YPos Y0 ) ) + ( not ( greaterp Y1 YPos ) ) ) ) ) ) ) + + +(defun PolygonEdgeHasX ( Edge XPos ) + (let ( + ( X0 ( car ( car Edge ) ) ) + ( X1 ( car ( cadr Edge ) ) ) ) + X0=round(X0/MfgGrid)*MfgGrid + X1=round(X1/MfgGrid)*MfgGrid + XPos=round(XPos/MfgGrid)*MfgGrid + ( or + ( and + ( lessp X0 X1 ) + ( and + ( not ( greaterp X0 XPos ) ) + ( not ( greaterp XPos X1 ) ) ) ) + ( and + ( greaterp X0 X1 ) + ( and + ( not ( greaterp XPos X0 ) ) + ( not ( greaterp X1 XPos ) ) ) ) ) ) ) + +(defun PolygonGetEdgesThatHaveY ( PolygonEdges YPos ) + ( ListApplyFuncToListAndAccumulateNonNilResults + PolygonEdges + ( lambda + ( Edge ) + when( PolygonEdgeHasY( Edge YPos) + Edge ) ) + nil ) ) + + +(defun PolygonGetEdgesThatHaveX ( PolygonEdges XPos ) + ( ListApplyFuncToListAndAccumulateNonNilResults + PolygonEdges + ( lambda + ( Edge ) + ( when ( PolygonEdgeHasX Edge XPos) + Edge ) ) + nil ) ) + + +(defun PolygonGetEdgeAverageX ( PolygonEdge ) + ( quotient + ( plus + ( car ( car PolygonEdge ) ) + ( car ( car ( cdr PolygonEdge ) ) ) ) + 2 ) ) + +(defun PolygonGetEdgeAverageY ( PolygonEdge ) + ( quotient + ( plus + ( car ( cdr ( car PolygonEdge ) ) ) + ( car ( cdr ( car ( cdr PolygonEdge ) ) ) ) ) + 2 ) ) + +(defun PolygonGetEdgesAverageX ( Edges ) + (when Edges + (let ( + ( Sum 0 ) ) + ( foreach + Edge + Edges + ( setq + Sum + ( plus + Sum + ( PolygonGetEdgeAverageX + Edge ) ) ) ) + ( quotient + Sum + ( length Edges ) ) ) ) ) + +(defun PolygonGetEdgesAverageY ( Edges ) + (when Edges + (let ( + ( Sum 0 ) ) + ( foreach + Edge + Edges + ( setq + Sum + ( plus + Sum + ( PolygonGetEdgeAverageY + Edge ) ) ) ) + ( quotient + Sum + ( length + Edges ) ) ) ) ) + +(defun PolygonGetCenterXAtY ( PolygonEdges YPos ) + (let ( + ( EdgesAtY ( PolygonGetEdgesThatHaveY + PolygonEdges + YPos ) ) ) + ( PolygonGetEdgesAverageX + EdgesAtY ) ) ) + +(defun PolygonGetCenterYAtX ( PolygonEdges XPos ) + (let ( + ( EdgesAtX ( PolygonGetEdgesThatHaveX + PolygonEdges + XPos ) ) ) + ( PolygonGetEdgesAverageY + EdgesAtX ) ) ) + +(defun PolygonGetClosestEdgeAndIndexOfClosestEdge ( PolygonEdges Point ) + (let ( + ( CurrClosest ( car PolygonEdges ) ) + ( CurrClosestIndex 0 ) + ( CurrIndex 0 ) + ( RemainingEdges ( cdr PolygonEdges ) ) ) + (let ( + ( CurrClosestDist ( LineGetClosestPointOnSegmentToPoint + Point + CurrClosest ) ) ) + (while RemainingEdges + (let ( + ( CurrEdge ( car RemainingEdges ) ) ) + ( setq RemainingEdges ( cdr RemainingEdges ) ) + (let ( + ( CurrDist ( LineGetClosestPointOnSegmentToPoint + Point + CurrEdge ) ) ) + (when ( lessp CurrDist CurrClosestDist ) + ( setq CurrClosest CurrEdge ) + ( setq CurrClosestDist CurrDist ) + ( setq CurrClosestIndex CurrIndex ) ) ) + ( setq CurrIndex ( plus CurrIndex 1 ) ) ) ) ) + ( list CurrClosest CurrClosestIndex ) ) ) + + +(defun PolygonGetClosestEdge ( PolygonEdges Point ) + ( car ( PolygonGetClosestEdgeAndIndexOfClosestEdge PolygonEdges Point ) ) ) + +(defun PolygonGetIndexOfClosestEdge ( PolygonEdges Point ) + ( cadr ( PolygonGetClosestEdgeAndIndexOfClosestEdge PolygonEdges Point ) ) ) + + +(defun PolygonGetRightMostEdge ( PolygonEdges ) + (let ( + ( CurrResultEdge ( car PolygonEdges ) ) + ( CurrResultEdgeMaxX ( LineGetSegmentMaxX ( car PolygonEdges ) ) ) + ( RemainingEdges ( cdr PolygonEdges ) ) ) + (while RemainingEdges + (let ( + ( CurrEdge ( car RemainingEdges ) ) ) + ( setq RemainingEdges ( cdr RemainingEdges ) ) + (let ( + ( CurrEdgeMaxX ( LineGetSegmentMaxX CurrEdge ) ) + ) + (when ( or + ( greaterp CurrEdgeMaxX CurrResultEdgeMaxX ) + ( greaterp + ( LineGetSegmentMinX CurrEdge ) + ( LineGetSegmentMinX CurrResultEdge ) ) ) + ( setq CurrResultEdge CurrEdge ) + ( setq CurrResultEdgeMaxX CurrEdgeMaxX ) ) ) ) ) + CurrResultEdge ) ) + +(defun PolygonGetTopMostEdge ( PolygonEdges ) + (let ( + ( CurrResultEdge ( car PolygonEdges ) ) + ( CurrResultEdgeMaxY ( LineGetSegmentMaxY ( car PolygonEdges ) ) ) + ( RemainingEdges ( cdr PolygonEdges ) ) ) + (while RemainingEdges + (let ( + ( CurrEdge ( car RemainingEdges ) ) ) + ( setq RemainingEdges ( cdr RemainingEdges ) ) + (let ( + ( CurrEdgeMaxY ( LineGetSegmentMaxY CurrEdge ) ) + ) + (when ( or + ( greaterp CurrEdgeMaxY CurrResultEdgeMaxY ) + ( greaterp + ( LineGetSegmentMinY CurrEdge ) + ( LineGetSegmentMinY CurrResultEdge ) ) ) + ( setq CurrResultEdge CurrEdge ) + ( setq CurrResultEdgeMaxY CurrEdgeMaxY ) ) ) ) ) + CurrResultEdge ) ) + +(defun PolygonGetLeftMostEdge ( PolygonEdges ) + (let ( + ( CurrResultEdge ( car PolygonEdges ) ) + ( CurrResultEdgeMinX ( LineGetSegmentMinX ( car PolygonEdges ) ) ) + ( RemainingEdges ( cdr PolygonEdges ) ) ) + (while RemainingEdges + (let ( + ( CurrEdge ( car RemainingEdges ) ) ) + ( setq RemainingEdges ( cdr RemainingEdges ) ) + (let ( + ( CurrEdgeMinX ( LineGetSegmentMinX CurrEdge ) ) + ) + (when ( or + ( lessp CurrEdgeMinX CurrResultEdgeMinX ) + ( lessp + ( LineGetSegmentMaxX CurrEdge ) + ( LineGetSegmentMaxX CurrResultEdge ) ) ) + ( setq CurrResultEdge CurrEdge ) + ( setq CurrResultEdgeMinX CurrEdgeMinX ) ) ) ) ) + CurrResultEdge ) ) + + +(defun PolygonGetHeight ( PolygonEdges ) + (let ( + ( BottomEdge + ( PolygonGetBottomMostEdge PolygonEdges ) ) + ( TopEdge + ( PolygonGetTopMostEdge PolygonEdges ) ) ) + ( difference + ( max ( cadar TopEdge ) + ( cadadr TopEdge ) ) + ( min ( cadar BottomEdge ) + ( cadadr BottomEdge ) ) ) ) ) + +(defun PolygonGetWidth ( PolygonEdges ) + (let ( + ( LeftEdge + ( PolygonGetLeftMostEdge PolygonEdges ) ) + ( RightEdge + ( PolygonGetRightMostEdge PolygonEdges ) ) ) + ( difference + ( max ( caar RightEdge ) + ( caadr RightEdge ) ) + ( min ( caar LeftEdge ) + ( caadr LeftEdge ) ) ) ) ) + + +(defun PolygonGetBottomMostEdge ( PolygonEdges ) + (let ( + ( CurrResultEdge ( car PolygonEdges ) ) + ( CurrResultEdgeMinY ( LineGetSegmentMinY ( car PolygonEdges ) ) ) + ( RemainingEdges ( cdr PolygonEdges ) ) ) + (while RemainingEdges + (let ( + ( CurrEdge ( car RemainingEdges ) ) ) + ( setq RemainingEdges ( cdr RemainingEdges ) ) + (let ( + ( CurrEdgeMinY ( LineGetSegmentMinY CurrEdge ) ) + ) + (when ( or + ( lessp CurrEdgeMinY CurrResultEdgeMinY ) + ( lessp + ( LineGetSegmentMaxY CurrEdge ) + ( LineGetSegmentMaxY CurrResultEdge ) ) ) + ( setq CurrResultEdge CurrEdge ) + ( setq CurrResultEdgeMinY CurrEdgeMinY ) ) ) ) ) + CurrResultEdge ) ) + +(defun PolygonGetRightMostEdgeAtY ( PolygonEdges YPos ) + ( PolygonGetRightMostEdge ( PolygonGetEdgesThatHaveY PolygonEdges YPos ) ) ) + +(defun PolygonGetTopMostEdgeAtX ( PolygonEdges XPos ) + ( PolygonGetTopMostEdge ( PolygonGetEdgesThatHaveX PolygonEdges XPos ) ) ) + +(defun PolygonGetLeftMostEdgeAtY ( PolygonEdges YPos ) + ( PolygonGetLeftMostEdge ( PolygonGetEdgesThatHaveY PolygonEdges YPos ) ) ) + +(defun PolygonGetBottomMostEdgeAtX ( PolygonEdges XPos ) + ( PolygonGetBottomMostEdge ( PolygonGetEdgesThatHaveX PolygonEdges XPos ) ) ) + + +(defun PolygonGetHorizontalLeftAndRightBoundaryFromBottomAndTop ( BottomAndTop + BoundaryPolygonEdges ) + (let ( + ( Bottom ( car BottomAndTop ) ) + ( Top ( cadr BottomAndTop ) ) ) + (let ( + ( BoundaryLeft + ( max + ( LineGetSegmentMaxX + ( PolygonGetLeftMostEdgeAtY BoundaryPolygonEdges Bottom ) ) + ( LineGetSegmentMaxX + ( PolygonGetLeftMostEdgeAtY BoundaryPolygonEdges Top ) ) ) ) + ( BoundaryRight + ( min + ( LineGetSegmentMinX + ( PolygonGetRightMostEdgeAtY BoundaryPolygonEdges Bottom ) ) + ( LineGetSegmentMinX + ( PolygonGetRightMostEdgeAtY BoundaryPolygonEdges Top ) ) ) ) ) + ( list BoundaryLeft BoundaryRight ) ) ) ) + +(defun PolygonGetVerticalTopAndBottomBoundaryFromLeftAndRight ( LeftAndRight + BoundaryPolygonEdges ) + (let ( + ( Left ( car LeftAndRight ) ) + ( Right ( cadr LeftAndRight ) ) ) + (let ( + ( BoundaryBottom + ( max + ( LineGetSegmentMaxY + ( PolygonGetBottomMostEdgeAtX BoundaryPolygonEdges Left ) ) + ( LineGetSegmentMaxY + ( PolygonGetBottomMostEdgeAtX BoundaryPolygonEdges Right ) ) ) ) + ( BoundaryTop + ( min + ( LineGetSegmentMinY + ( PolygonGetTopMostEdgeAtX BoundaryPolygonEdges Left ) ) + ( LineGetSegmentMinY + ( PolygonGetTopMostEdgeAtX BoundaryPolygonEdges Right ) ) ) ) ) + ( list BoundaryBottom BoundaryTop ) ) ) ) + + +(defun PolygonGetPointOnPolygonRightEdgeForY ( PolygonPoints YPos ) + ( list + ( LineSolveForX + ( LineMakeLineDataFromPointList + ( PolygonGetRightMostEdgeAtY + ( PolygonGetEdges + PolygonPoints ) + YPos ) ) + YPos ) + YPos ) ) + +(defun PolygonGetPointOnPolygonLeftEdgeForY ( PolygonPoints YPos ) + ( list + ( LineSolveForX + ( LineMakeLineDataFromPointList + ( PolygonGetLeftMostEdgeAtY + ( PolygonGetEdges + PolygonPoints ) + YPos ) ) + YPos ) + YPos ) ) + + + +(defun PolygonGetCenterOfGravity ( PolygonPoints ) + (when PolygonPoints + (let ( + ( RemainingPoints PolygonPoints ) + ( CurrXSum 0 ) + ( CurrYSum 0 ) + ( Count 0 ) ) + (while RemainingPoints + (let ( + ( CurrPoint ( car RemainingPoints ) ) ) + ( setq RemainingPoints ( cdr RemainingPoints ) ) + ( setq Count ( plus Count 1 ) ) + ( setq CurrXSum ( plus CurrXSum ( car CurrPoint ) ) ) + ( setq CurrYSum ( plus CurrYSum ( cadr CurrPoint ) ) ) ) ) + ( list + ( quotient + CurrXSum + Count ) + ( quotient + CurrYSum + Count ) ) ) ) ) + + +(defun PolygonIsLeftEdge ( Edge PolygonEdges ) + (unless ( LineIsSegmentHorizontal Edge ) + (let ( + ( EdgeY ( PolygonGetEdgeAverageY Edge ) ) + ( EdgeX ( PolygonGetEdgeAverageX Edge ) ) + ) + (let ( + ( CenterAtY ( PolygonGetCenterXAtY + PolygonEdges + EdgeY ) ) ) + ( lessp + EdgeX + CenterAtY ) ) ) ) ) + +(defun PolygonIsRightEdge ( Edge PolygonEdges ) + (unless ( LineIsSegmentHorizontal Edge ) + ( not ( PolygonIsLeftEdge Edge PolygonEdges ) ) ) ) + +(defun PolygonIsBottomEdge ( Edge PolygonEdges ) + (unless ( LineIsSegmentVertical Edge ) + (let ( + ( EdgeY ( PolygonGetEdgeAverageY Edge ) ) + ( EdgeX ( PolygonGetEdgeAverageX Edge ) ) ) + (let ( + ( CenterAtX ( PolygonGetCenterYAtX + PolygonEdges + EdgeX ) ) ) + ( lessp + EdgeY + CenterAtX ) ) ) ) ) + +(defun PolygonIsTopEdge ( Edge PolygonEdges ) + (unless ( LineIsSegmentVertical Edge ) + ( not ( PolygonIsBottomEdge Edge PolygonEdges ) ) ) ) + +(defun PolygonMoveEdgeInX ( PolygonPoints Edge Delta ) + (when PolygonPoints + ( ListApplyFuncToListAndAccumulateResults + PolygonPoints + ( lambda + ( Point Edge Delta ) + (if ( or + ( lessp + ( LineGetSegmentLength + ( list ( car Edge ) Point ) ) + 0.0001 ) + ( lessp + ( LineGetSegmentLength + ( list ( cadr Edge ) Point ) ) + 0.0001 ) ) + ( list + ( plus ( car Point ) Delta ) + ( cadr Point ) ) + Point ) ) + ( list Edge Delta ) ) ) ) + +(defun PolygonMoveEdgeInY ( PolygonPoints Edge Delta ) + (when PolygonPoints + ( ListApplyFuncToListAndAccumulateResults + PolygonPoints + ( lambda + ( Point Edge Delta ) + (if ( or + ( lessp + ( LineGetSegmentLength + ( list ( car Edge ) Point ) ) + 0.0001 ) + ( lessp + ( LineGetSegmentLength + ( list ( cadr Edge ) Point ) ) + 0.0001 ) ) + ( list + ( car Point ) + ( plus ( cadr Point ) Delta ) ) + Point ) ) + ( list Edge Delta ) ) ) ) + +;gets smallest lwoer left block +(defun PolygonGetRectInsidePolygon ( PolygonPoints ) + (let ( + ( BottomLeftPoint ( PolygonGetBottomLeftPoint PolygonPoints ) ) ) + ( list BottomLeftPoint ( PolygonGetNextPointToRightAndUp BottomLeftPoint PolygonPoints ) ) ) ) + + +(defun PolygonGetNextPointToRightAndUp ( Point PolygonPoints ) + (let ( + ( PolygonEdges ( PolygonGetEdges PolygonPoints ) ) ) + ( car ( exists PolygonPoint PolygonPoints + ( and ( greaterp ( car PolygonPoint ) ( car Point ) ) + ( greaterp ( cadr PolygonPoint ) ( cadr Point ) ) + (let ( + ( Rect ( list Point PolygonPoint ) ) ) + (let ( + ( BBoxEdges ( BBoxGetPolygonEdges Rect ) ) ) + ( not ( exists BBoxEdge BBoxEdges + ( exists Edge PolygonEdges + ( and ( LineIntersect Edge BBoxEdge ) + ( RectIsLineSegmentEverInRect Rect Edge nil ) + ) ) ) ) ) ) ) ) ) ) ) + +;corners count +(defun PolygonEdgesAbut ( PolygonEdges1 PolygonEdges2 ) + (if ( exists PolygonEdge1 PolygonEdges1 + ( exists PolygonEdge2 PolygonEdges2 + (let () + ( or + ( LineIntersectAtEndPoint PolygonEdge1 PolygonEdge2 ) + ( LineOverlap PolygonEdge1 PolygonEdge2 ) ) ) ) ) + t ) ) + + +(defun PolygonGetShortestEdge ( PolygonPoints ) + ( ListFindMinimum + ( PolygonGetEdges PolygonPoints ) + (lambda ( Edge ) + ( PointGetDistance + ( car Edge ) + ( cadr Edge ) ) ) ) ) + +(defun PolygonIsAngled ( Points ) + ( not ( forall Line ( PolygonGetEdges ( getq Shape points ) ) + ( LineIsManhattan Line ) ) ) ) + +(defun PathCanonicalizePoints ( Points + @key + ( Snap 0.0 ) + ) + (let ( + ( Points + ( ListUniq + ( mapcar + (lambda ( Point ) + ( mapcar + (lambda ( Coord ) + (cond ( ( equal 0.0 Snap ) Coord ) + ( ( MathRoundToNearest Coord Snap ) ) ) ) + Point ) ) + Points ) ) ) ) + (when ( equal ( car Points ) ( car ( last Points ) ) ) + ( setq Points ( cdr Points ) ) ) + Points + ) ) + +(defun PolygonCanonicalizePoints ( Points + @key + ( Snap 0.0 ) + ) + (let ( + ( Points + ( PathCanonicalizePoints Points ?Snap Snap ) ) ) + + (when ( equal ( car Points ) ( car ( last Points ) ) ) + ( setq Points ( cdr Points ) ) ) + Points + ) ) + +(defun PolygonPerimeter ( PolygonPoints ) + ( ListFindSum + ( PolygonGetEdges PolygonPoints ) + (lambda ( Edge ) + ( PointGetDistance + ( car Edge ) + ( cadr Edge ) ) ) ) ) + + + + +(defun IsPointInPolygon (point points) + (let (inside ptj + (testX (car point)) + (testY (cadr point))) + (setq ptj (car (last points))) + (foreach pti points + (when + (and + (nequal + (greaterp (yCoord pti) testY) + (greaterp (yCoord ptj) testY)) + (lessp + testX + (plus + (quotient + (times + (difference (xCoord ptj) (xCoord pti)) + (difference testY (yCoord pti)) + ) + (difference (yCoord ptj) (yCoord pti)) + ) + (xCoord pti) + ) + ) + ) + (setq inside (null inside)) + ) + (setq ptj pti) + ) + inside + ) + ) + + +procedure(FracturePolygon(p) + let( (bb xll xur xy xx yll yur yy pieces pp pnts) + (if (p~>objType == "polygon") then ; only fracture polygons + (if (p~>nPoints > 3) then ; not a triangle + bb=p~>bBox + ; printf("bBox=%L\n" bb) + xll=xCoord(lowerLeft(bb)) + yll=yCoord(lowerLeft(bb)) + xur=xCoord(upperRight(bb)) + yur=yCoord(upperRight(bb)) + pieces=nil + ; first look for places to cut vertically + pnts=p~>points + (while pnts + xy=car(pnts) + ; printf("xy=%L\n" xy) + pnts=cdr(pnts) + xx=xCoord(xy) + (if (xx > xll && xx < xur) then + ; printf("vchop %L\n" list(xx:yll xx:yur) ) + pieces=leChopShape(p + list(xx:yll xx:yur xll:yur xll:yll) t nil) + pnts=nil + ) + ) + (if (pieces==nil) then + ; didn't find vertical cut, look for horizontal cut + pnts=p~>points + (while pnts + xy=car(pnts) + pnts=cdr(pnts) + yy=yCoord(xy) + (if (yy > yll && yy < yur) then + ; printf("hchop %L\n" list(xll:yy xur:yy) ) + pieces=leChopShape(p + list(xll:yy xur:yy xur:yll xll:yll) t nil) + pnts=nil + ) + ) + ) + (foreach pp pieces + fracture(pp) + ) + ) + ) + ) +) + +procedure( FractureAllPolygons(lib name view) + prog( (c l s) + c=dbOpenCellView(lib name view nil "an") + (foreach s c~>shapes + FracturePolygon(s) + ) + dbSave(c) + dbClose(c) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/range.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/range.il new file mode 100644 index 0000000000..424ca524c1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/range.il @@ -0,0 +1,173 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun RangeMakeRange ( Left Size ) + ( list + Left + ( plus Left Size ) ) ) + +(defun RangeMakeRangeFromRight ( Right Size ) + ( list + ( difference Right Size ) + Right ) ) + +(defun RangeMakeRangeFromCenter ( Center Radius ) + ( list ( difference Center Radius ) + ( plus Center Radius ) ) ) + +(defun RangeGetDistance ( Range1 Range2 ) + (cond ( + ( RangeDoIntersect Range1 Range2 1e-9 ) + 0.0 ) + ( + ( min + ( abs ( difference + ( cadr Range1 ) + ( car Range2 ) ) ) + ( abs ( difference + ( car Range1 ) + ( cadr Range2 ) ) ) ) ) ) ) + +(defun RangeExpandRange ( Range Radius ) + ( list ( difference ( car Range ) Radius ) + ( plus ( cadr Range ) Radius ) ) ) + +(defun RangeCanonicalize ( Range ) + ( list ( min ( car Range ) ( cadr Range ) ) + ( max ( car Range ) ( cadr Range ) ) ) ) + +(defun RangeShareBound ( Range1 Range2 ) + ( or ( equal ( car Range1 ) ( cadr Range2 ) ) + ( equal ( cadr Range1 ) ( car Range2 ) ) ) ) + +(defun RangeAddOffset ( Range Offset ) + ( list ( plus ( car Range ) Offset ) + ( plus ( cadr Range ) Offset ) ) ) + +(defun RangeGetSize ( Range ) + ( difference ( cadr Range ) ( car Range ) ) ) + +(defun RangeGetMidpoint ( Range ) + ( plus ( car Range ) + ( times 0.5 ( RangeGetSize Range ) ) ) ) + +(defun RangeUnion ( Range1 Range2 ) + (cond ( + ( null Range1 ) + Range2 ) + ( + ( null Range2 ) + Range1 ) + ( + t + ( list ( min ( car Range1 ) ( car Range2 ) ) + ( max ( cadr Range1 ) ( cadr Range2 ) ) ) ) ) ) + +(defun RangeUnionMultiple ( Ranges ) + (let ( + ( Union ( car Ranges ) ) + ( TheRanges ( cdr Ranges ) ) + ) + ( foreach Range TheRanges + ( setq Union ( RangeUnion Union Range ) ) ) + Union ) ) + +(defun RangeIntersection ( Range1 Range2 ) + (let ( + ( Ret + ( list ( max ( car Range1 ) ( car Range2 ) ) + ( min ( cadr Range1 ) ( cadr Range2 ) ) ) ) ) + (if ( lessp ( car Ret ) ( cadr Ret ) ) + Ret ) ) ) + +(defun RangeDoIntersect ( Range1 Range2 Eps ) + ( or ( RangeIsNumberInRangeClose ( car Range1 ) Range2 Eps ) + ( RangeIsNumberInRangeClose ( cadr Range1 ) Range2 Eps ) + ( RangeIsNumberInRangeClose ( car Range2 ) Range1 Eps ) ) ) + +(defun RangeGetOverlap ( Range1 Range2 ) + (let ( + ( Int ( RangeIntersection Range1 Range2 ) ) ) + (if Int ( RangeGetSize Int ) 0.0 ) ) ) + +(defun RangeIsNumberInRangeClose ( Value Range Eps ) + ( and ( leqp ( car Range ) ( plus Value Eps ) ) + ( geqp ( plus ( cadr Range ) Eps ) Value ) ) ) + + +(defun RangeIsRangeInRangeClose ( LittleRange BigRange Eps ) + ( and BigRange + ( and ( RangeIsNumberInRangeClose ( car LittleRange ) BigRange Eps ) + ( RangeIsNumberInRangeClose ( cadr LittleRange ) BigRange Eps ) ) ) ) + +(defun RangeIsRangeInRangeProperClose ( LittleRange BigRange Eps ) + ( and ( geqp ( difference ( car LittleRange ) ( car BigRange ) Eps ) ) + ( geqp ( difference ( cadr BigRange ) ( cadr LittleRange ) Eps ) ) ) ) + +(defun RangeIsRangeContainedInUnionOfRangesClose ( Range Ranges Eps ) + ( or + ( leqp ( cadr Range ) ( car Range ) ) + (let ( + ( IntersectingRange + ( car ( exists OtherRange Ranges + ( or + ( and ( leqp ( car OtherRange ) ( car Range ) ) + ( greaterp ( cadr OtherRange ) ( car Range ) ) ) + ( and ( lessp ( car OtherRange ) ( cadr Range ) ) + ( geqp ( cadr OtherRange ) ( cadr Range ) ) ) ) ) ) ) ) + (if IntersectingRange + ( RangeIsRangeContainedInUnionOfRangesClose + (cond ( + ( lessp ( car Range ) ( car IntersectingRange ) ) + ( list ( car Range ) ( car IntersectingRange ) ) ) + ( + ( list ( cadr IntersectingRange ) ( cadr Range ) ) ) ) + Ranges + Eps ) ) ) ) ) + + +(defun RangeGetAllRangesNotCovered ( RangeToCover Ranges ) + ( RangeGetAllRangesNotCoveredInner + RangeToCover + ( sort ( copy Ranges ) + (lambda ( X Y ) ( lessp ( car X ) ( car Y ) ) ) ) ) ) + +(defun RangeGetAllRangesNotCoveredInner ( RangeToCover + SortedRanges ) + (let ( + ( Missed nil ) ) + ( foreach Range SortedRanges + (when ( lessp ( car RangeToCover ) ( car Range ) ) + ( setq Missed ( cons ( list ( car RangeToCover ) + ( car Range ) ) + Missed ) ) ) + ( setq RangeToCover ( list ( max ( car RangeToCover ) + ( cadr Range ) ) + ( cadr RangeToCover ) ) ) ) + (when ( greaterp ( cadr RangeToCover ) ( car RangeToCover ) ) + ( setq Missed ( cons RangeToCover Missed ) ) ) + Missed ) ) + +(defun RangeGetCover ( Ranges ) + (let ( + ( SortedRanges + ( sort ( copy Ranges ) + (lambda ( X Y ) ( lessp ( car X ) ( car Y ) ) ) ) ) ) + (let ( + ( MaxRange + ( list + ( car ( car SortedRanges ) ) + ( cadr ( car ( last SortedRanges ) ) ) + ) ) ) + ( difference + ( RangeGetSize MaxRange ) + ( ListFindSum + ( RangeGetAllRangesNotCoveredInner + MaxRange + SortedRanges ) + (lambda ( Range ) + ( RangeGetSize Range ) ) ) ) ) ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/rect.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/rect.il new file mode 100644 index 0000000000..b36e87ee7d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/rect.il @@ -0,0 +1,791 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + +(defun RectApplyToCoords ( Rect Func ) + ( mapcar + (lambda ( Pt ) + ( mapcar + Func + Pt ) ) + Rect ) ) + +(defun RectGetWidth ( Rect ) + ( difference + ( RectGetRight Rect ) + ( RectGetLeft Rect ) + ) + ) + +(defun RectGetHeight ( Rect ) + ( difference + ( RectGetTop Rect ) + ( RectGetBottom Rect ) + ) + ) + +(defun RectGetLeft ( Rect ) + ( car + ( car + Rect + ) + ) + ) + +(defun RectGetRight ( Rect ) + ( car + ( car + ( cdr + Rect + ) + ) + ) + ) + +(defun RectGetBottom ( Rect ) + ( car + ( cdr + ( car + Rect + ) + ) + ) + ) + +(defun RectGetTop ( Rect ) + ( car + ( cdr + ( car + ( cdr + Rect + ) + ) + ) + ) + ) + +(defun RectGetCenter ( Rect ) + + ( list + ( quotient + ( plus + ( RectGetLeft + Rect + ) + ( RectGetRight + Rect + ) + ) + 2.0 + ) + ( quotient + ( plus + ( RectGetTop + Rect + ) + ( RectGetBottom + Rect + ) + ) + 2.0 + ) + ) + ) + +(defun RectGetPoints ( Rect ) + ( list + ( list + ( RectGetLeft + Rect + ) + ( RectGetBottom + Rect + ) + ) + ( list + ( RectGetLeft + Rect + ) + ( RectGetTop + Rect + ) + ) + ( list + ( RectGetRight + Rect + ) + ( RectGetTop + Rect + ) + ) + ( list + ( RectGetRight + Rect + ) + ( RectGetBottom + Rect + ) + ) + ) + ) + +(defun RectMakeRect ( LeftBound BottomBound Width Height ) + ( list + ( list + LeftBound + BottomBound + ) + ( list + ( plus + LeftBound + Width + ) + ( plus + BottomBound + Height + ) + ) + ) + ) + +(defun RectMakeFromCenter ( CenterPos Width Height ) + (let ( + ( halfwidth ( quotient + Width + 2.0 + ) + ) + ( halfheight ( quotient + Height + 2.0 + ) + ) + ( CenterX ( car CenterPos ) ) + ( CenterY ( car ( cdr CenterPos ) ) ) + ) + (let ( + ( Left ( difference + CenterX + halfwidth + ) + ) + ( Right ( plus + CenterX + halfwidth + ) + ) + ( Bottom ( difference + CenterY + halfheight + ) + ) + ( Top ( plus + CenterY + halfheight + ) + ) + ) + ( list + ( list + Left + Bottom + ) + ( list + Right + Top + ) + ) + ) + ) + ) + + +(defun RectMakeFromLeftBottom ( Left Bottom Width Height ) + ( list + ( list + Left + Bottom + ) + ( list + ( plus + Left + Width + ) + ( plus + Bottom + Height + ) + ) + ) + ) + +(defun RectMakeFromRightTop ( Right Top Width Height ) + ( list + ( list + ( difference + Right + Width + ) + ( difference + Top + Height + ) + ) + ( list + Right + Top + ) + ) + ) + +(defun RectExpandRight ( Rect HowMuch ) + ( list + ( car Rect ) + ( list ( plus ( RectGetRight Rect ) HowMuch ) + ( RectGetTop Rect ) ) ) ) + +(defun RectShrinkInY ( Rect HowMuch ) + ( list + ( list + ( RectGetLeft + Rect + ) + ( plus + ( RectGetBottom + Rect + ) + HowMuch + ) + ) + ( list + ( RectGetRight + Rect + ) + ( difference + ( RectGetTop + Rect + ) + HowMuch + ) + ) + ) + ) + +(defun RectShrinkInX ( Rect HowMuch ) + ( list + ( list + ( plus + ( RectGetLeft + Rect ) + HowMuch ) + ( RectGetBottom + Rect ) ) + ( list + ( difference + ( RectGetRight + Rect ) + HowMuch ) + ( RectGetTop + Rect ) ) ) ) + +(defun RectGetBoundRect ( Rect0 Rect1 ) + ( cond + ( + ( null Rect0 ) + Rect1 + ) + ( + ( null Rect1 ) + Rect0 + ) + ( + t + ( list + ( list + ( min + ( RectGetLeft + Rect0 + ) + ( RectGetLeft + Rect1 + ) + ) + ( min + ( RectGetBottom + Rect0 + ) + ( RectGetBottom + Rect1 + ) + ) + ) + ( list + ( max + ( RectGetRight + Rect0 + ) + ( RectGetRight + Rect1 + ) + ) + ( max + ( RectGetTop + Rect0 + ) + ( RectGetTop + Rect1 + ) + ) + ) + ) + ) + ) + ) + +(defun RectIsRectInRect ( ContainedRect ContainingRect ) + ( RectRectsAreEqual + ( RectGetBoundRect ContainedRect ContainingRect ) + ContainingRect + ) + ) + +(defun RectRectsAreEqual ( Rect0 Rect1 ) + ( and + ( and + ( equal + ( RectGetLeft + Rect0 + ) + ( RectGetLeft + Rect1 + ) + ) + ( equal + ( RectGetBottom + Rect0 + ) + ( RectGetBottom + Rect1 + ) + ) + ) + ( and + ( equal + ( RectGetRight + Rect0 + ) + ( RectGetRight + Rect1 + ) + ) + ( equal + ( RectGetTop + Rect0 + ) + ( RectGetTop + Rect1 + ) + ) + ) + ) + ) + +(defun RectGetDistanceFromRectToSurroundingRect ( InnerRect OuterRect ) + ( ListFindMinimum + ( list + ( difference ( RectGetLeft InnerRect ) + ( RectGetLeft OuterRect ) ) + ( difference ( RectGetRight OuterRect ) + ( RectGetRight InnerRect ) ) + ( difference ( RectGetBottom InnerRect ) + ( RectGetBottom OuterRect ) ) + ( difference ( RectGetTop OuterRect ) + ( RectGetTop InnerRect ) ) ) + nil ) ) + +(defun RectGetDistanceFromRectToRect ( Rect1 Rect2 ) + (let ( + ( YIntersect ( RangeDoIntersect + ( RectGetYRange Rect1 ) + ( RectGetYRange Rect2 ) + 1e-9 ) ) + ( XIntersect ( RangeDoIntersect + ( RectGetXRange Rect1 ) + ( RectGetXRange Rect2 ) + 1e-9 ) ) ) + (if YIntersect + (if XIntersect + 0.0 + ( min + ( abs ( difference ( RectGetLeft Rect2 ) ( RectGetRight Rect1 ) ) ) + ( abs ( difference ( RectGetLeft Rect1 ) ( RectGetRight Rect2 ) ) ) ) ) + (if XIntersect + ( min ( abs ( difference ( RectGetBottom Rect2 ) ( RectGetTop Rect1 ) ) ) + ( abs ( difference ( RectGetBottom Rect1 ) ( RectGetTop Rect2 ) ) ) ) + ( max + ( min + ( abs ( difference ( RectGetBottom Rect2 ) ( RectGetTop Rect1 ) ) ) + ( abs ( difference ( RectGetBottom Rect1 ) ( RectGetTop Rect2 ) ) ) ) + ( min + ( abs ( difference ( RectGetLeft Rect2 ) ( RectGetRight Rect1 ) ) ) + ( abs ( difference ( RectGetLeft Rect1 ) ( RectGetRight Rect2 ) ) ) ) ) + ) ) ) ) + +(defun RectIsRectInRectClose ( ContainedRect ContainingRect Eps ) + ( RectAreRectsClose + ( RectGetBoundRect ContainedRect ContainingRect ) + ContainingRect + Eps ) ) + +(defun RectAreRectsClose ( B1 B2 Eps ) + ( and ( lessp ( abs ( difference ( caar B1 ) ( caar B2 ) ) ) Eps ) + ( lessp ( abs ( difference ( caadr B1 ) ( caadr B2 ) ) ) Eps ) + ( lessp ( abs ( difference ( cadar B1 ) ( cadar B2 ) ) ) Eps ) + ( lessp ( abs ( difference ( cadadr B1 ) ( cadadr B2 ) ) ) Eps ) ) ) + +(defun RectMoveRectInsideRect ( InnerRect OuterRect ) + (let ( + ( InnerLeft ( RectGetLeft InnerRect ) ) + ( InnerRight ( RectGetRight InnerRect ) ) + ( InnerBottom ( RectGetBottom InnerRect ) ) + ( InnerTop ( RectGetTop InnerRect ) ) + ( OuterLeft ( RectGetLeft OuterRect ) ) + ( OuterRight ( RectGetRight OuterRect ) ) + ( OuterBottom ( RectGetBottom OuterRect ) ) + ( OuterTop ( RectGetTop OuterRect ) ) + ) + ( list + ( plus + ( if ( lessp + InnerLeft + OuterLeft + ) + ( difference + OuterLeft + InnerLeft + ) + 0.0 + ) + ( if ( lessp + OuterRight + InnerRight + ) + ( difference + OuterRight + InnerRight + ) + 0.0 + ) + ) + ( plus + ( if ( lessp + InnerBottom + OuterBottom + ) + ( difference + OuterBottom + InnerBottom + ) + 0.0 + ) + ( if ( lessp + OuterTop + InnerTop + ) + ( difference + OuterTop + InnerTop + ) + 0.0 + ) + ) + ) + ) + ) + +(defun RectIsPointInRect ( Rect Point IsClosedRect ) + + (let ( + ( Left ( RectGetLeft Rect ) ) + ( Right ( RectGetRight Rect ) ) + ( Bottom ( RectGetBottom Rect ) ) + ( Top ( RectGetTop Rect ) ) + ( PointX ( car Point ) ) + ( PointY ( car ( cdr Point ) ) ) ) + ( and + ( or + ( lessp Left PointX ) + ( and + IsClosedRect + ( equal Left PointX ) ) ) + ( or + ( greaterp Right PointX ) + ( and + IsClosedRect + ( equal Right PointX ) ) ) + ( or + ( lessp Bottom PointY ) + ( and + IsClosedRect + ( equal Bottom PointY ) ) ) + ( or + ( greaterp Top PointY ) + ( and + IsClosedRect + ( equal Top PointY ) ) ) ) ) ) + +(defun RectGetEdgesForPoint ( Rect Point ) + ( setof Edge ( BBoxGetPolygonEdges Rect ) + ( LinePointIsOnSegment Point Edge ) ) ) + +(defun RectIsLineSegmentEverInRect ( Rect Line IsClosedRect ) + ;if closed, a point must be in closed rect + (if IsClosedRect + ( or ( RectIsPointInRect Rect ( car Line ) t ) + ( RectIsPointInRect Rect ( cadr Line ) t ) ) + ;if open, a point must be in open rect, or + ; line must go through an edge interseting edges for endpoints must be nonempty and disjoint + ; + ( or ( RectIsPointInRect Rect ( car Line ) nil ) + ( RectIsPointInRect Rect ( cadr Line ) nil ) + (if ( exists Edge ( BBoxGetPolygonEdges Rect ) + ( LineIntersectNoEndPointsAllowed Line Edge ) ) + t ) + (let ( + ( Edges1 ( RectGetEdgesForPoint Rect ( car Line ) ) ) + ( Edges2 ( RectGetEdgesForPoint Rect ( cadr Line ) ) ) ) + ( and + Edges1 + Edges2 + ( null ( ListIntersect Edges1 Edges2 ) ) ) ) ) ) ) + + +(defun RectGetOverlapArea ( Rect0 Rect1 ) + ( times + ( RangeGetOverlap + ( RectGetXRange Rect0 ) + ( RectGetXRange Rect1 ) ) + ( RangeGetOverlap + ( RectGetYRange Rect0 ) + ( RectGetYRange Rect1 ) ) ) ) + +(defun RectGetOverlap ( Rect0 Rect1 ) + (if ( RectDoRectsOverlapOpenRects Rect0 Rect1 ) + ( min + ( RangeGetOverlap + ( RectGetXRange Rect0 ) + ( RectGetXRange Rect1 ) ) + ( RangeGetOverlap + ( RectGetYRange Rect0 ) + ( RectGetYRange Rect1 ) ) ) + 0.0 ) ) + +(defun RectDoRectsOverlapOpenRects ( Rect0 Rect1 ) + ( and ( RectDoRectsOverlap Rect0 Rect1 ) + ( not ( RectDoRectsAbutClose Rect0 Rect1 1e-9 ) ) ) ) + +;corner's count +(defun RectDoRectsAbutClose ( Rect0 Rect1 Eps ) + ( or ( leqp ( abs ( difference ( RectGetLeft Rect0 ) ( RectGetRight Rect1 ) ) ) Eps ) + ( leqp ( abs ( difference ( RectGetRight Rect0 ) ( RectGetLeft Rect1 ) ) ) Eps ) + ( leqp ( abs ( difference ( RectGetBottom Rect0 ) ( RectGetTop Rect1 ) ) ) Eps ) + ( leqp ( abs ( difference ( RectGetTop Rect0 ) ( RectGetBottom Rect1 ) ) ) Eps ) ) ) + +(defun RectDoRectsOverlap ( Rect0 Rect1 ) + ( or + ( not + ( forall + Point + ( RectGetPoints + Rect0 ) + ( not + ( RectIsPointInRect + Rect1 + Point + t ) ) ) ) + ( not + ( forall + Point + ( RectGetPoints + Rect1 ) + ( not + ( RectIsPointInRect + Rect0 + Point + t ) ) ) ) ) ) + + +(defun RectIsLeftOnLambdaGrid ( Rect ) + ( equal + ( round + ( RectGetLeft + Rect + ) + ) + ( RectGetLeft + Rect + ) + ) + ) + +(defun RectIsRightOnLambdaGrid ( Rect ) + ( equal + ( round + ( RectGetRight + Rect + ) + ) + ( RectGetRight + Rect + ) + ) + ) + +(defun RectIsBottomOnLambdaGrid ( Rect ) + ( equal + ( round + ( RectGetBottom + Rect + ) + ) + ( RectGetBottom + Rect + ) + ) + ) +(defun RectIsTopOnLambdaGrid ( Rect ) + ( equal + ( round + ( RectGetTop + Rect + ) + ) + ( RectGetTop + Rect + ) + ) + ) + +(defun RectGetArea ( Rect ) + ( times + ( RectGetWidth + Rect + ) + ( RectGetHeight + Rect + ) + ) + ) + +(defun RectCompareRects ( Rect0 Rect1 ) + (if ( equal + ( RectGetBottom + Rect0 + ) + ( RectGetBottom + Rect1 + ) + ) + ( lessp + ( RectGetLeft + Rect0 + ) + ( RectGetLeft + Rect1 + ) + ) + ( lessp + ( RectGetBottom + Rect0 + ) + ( RectGetBottom + Rect1 + ) + ) + ) + ) + + +(defun RectGetXRange ( Rect ) + ( LineGetXRange + Rect ) ) + +(defun RectGetYRange ( Rect ) + ( LineGetYRange + Rect ) ) + +(defun RectMakeFromRanges ( XRange YRange ) + (when ( and XRange YRange ) + ( list ( list ( car XRange ) ( car YRange ) ) + ( list ( cadr XRange ) ( cadr YRange ) ) ) ) ) + +(defun RectGetIntersection ( Rect1 Rect2 ) + ( RectMakeFromRanges + ( RangeIntersection ( RectGetXRange Rect1 ) ( RectGetXRange Rect2 ) ) + ( RangeIntersection ( RectGetYRange Rect1 ) ( RectGetYRange Rect2 ) ) ) ) + + + +(defun RectGetSortedXYRangePairs ( Rects ) + ( sort + ( ListNonDestructiveMapCan + (lambda ( Rect ) + ( list + ( list + ( caar Rect ) + ( RectGetYRange Rect ) + t + ) + ( list + ( caadr Rect ) + ( RectGetYRange Rect ) + nil + ) ) ) + Rects ) + (lambda ( X Y ) ( lessp ( car X ) ( car Y ) ) ) ) ) + +(defun RectGetAreaOfUnion ( Rects ) + (let ( + ( SortedXYRangePairs + ( RectGetSortedXYRangePairs + Rects ) ) ) + (let ( + ( Area 0.0 ) + ( STree ( SegmentTreeCreate + ( ListNonDestructiveMapCan + `cadr + SortedXYRangePairs ) ) ) ) + + (while SortedXYRangePairs + (let ( + ( CurrXYRangePair ( car SortedXYRangePairs ) ) + ( NextXYRangePair ( cadr SortedXYRangePairs ) ) ) + (let ( + ( X ( car CurrXYRangePair ) ) + ( YRange ( cadr CurrXYRangePair ) ) + ( Insert ( caddr CurrXYRangePair ) ) + ( NextX ( car NextXYRangePair ) ) ) + (if Insert + ( SegmentTreeInsert STree YRange ) + ( SegmentTreeDelete STree YRange ) ) + (when NextXYRangePair + ( setq Area ( plus + Area + ( times + ( difference NextX X ) + ( SegmentTreeGetCover STree ) ) ) ) ) + ( setq SortedXYRangePairs ( cdr SortedXYRangePairs ) ) ) ) ) +Area +) ) ) + + +(defun RectGetPolygonPoints ( Rect ) + ( list ( car Rect ) + ( list ( car ( cadr Rect ) ) ( cadr ( car Rect ) ) ) + ( cadr Rect ) + ( list ( car ( car Rect ) ) ( cadr ( cadr Rect ) ) ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/segmenttree.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/segmenttree.il new file mode 100644 index 0000000000..edd1dd937b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/geometry/segmenttree.il @@ -0,0 +1,165 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defstruct SegmentTree segment left right cover segments shared ) + +(defun SegmentTreeCreate ( EndPoints ) + (let ( + ( IntMap ( makeTable `foo nil ) ) + ( RealMap ( makeTable `foo nil ) ) + ( SegmentMap ( makeTable `foo nil ) ) + ( K 0 ) ) + ( foreach EndPoint + ( ListUniq + ( sort ( copy EndPoints ) + (lambda ( X Y ) ( lessp X Y ) ) ) ) + ( setarray RealMap K EndPoint ) + ( setarray IntMap EndPoint K ) + ( setq K ( plus K 1 ) ) ) + ( SegmentTreeInit + 0 + ( difference K 1 ) + ( list IntMap RealMap SegmentMap ) ) + ) ) + +(defun SegmentTreeInit ( Left Right Data ) + (let ( + ( Mid + ( quotient ( plus Left Right ) 2 ) ) ) + ( make_SegmentTree + ?segment ( list Left Right ) + ?left + (when ( greaterp Right + ( plus Left 1 ) ) + ( SegmentTreeInit + Left + Mid + Data ) ) + ?right + (when ( greaterp Right + ( plus Left 1 ) ) + ( SegmentTreeInit + Mid + Right + Data ) ) + ?cover 0.0 + ?segments ( makeTable `foo 0 ) + ?shared Data ) ) ) + +(defun SegmentTreeGetMidPoint ( STree ) + ( quotient + ( plus + ( car STree->segment ) + ( cadr STree->segment ) ) ) ) + +(defun SegmentTreeGetIntMap ( STree ) + ( car STree->shared ) ) + +(defun SegmentTreeGetRealMap ( STree ) + ( cadr STree->shared ) ) + +(defun SegmentTreeGetInternalSegment ( STree Segment ) + (let ( + ( Map ( SegmentTreeGetIntMap STree ) ) ) + ( mapcar + (lambda ( Point ) + ( arrayref Map Point ) ) + Segment + ) ) ) + +(defun SegmentTreeGetSegmentSize ( STree ) + (let ( + ( TreeSegment STree->segment ) + ( Map ( SegmentTreeGetRealMap STree ) ) ) + ( difference + ( arrayref Map ( cadr TreeSegment ) ) + ( arrayref Map ( car TreeSegment ) ) ) ) ) + +(defun SegmentTreeGetCover ( STree ) + STree->cover ) + +(defun SegmentTreeInsert ( STree Segment ) + (let ( + ( IntegerSegment ( SegmentTreeGetInternalSegment + STree + Segment ) ) ) + ( SegmentTreeImpl STree IntegerSegment nil ) ) ) + +(defun SegmentTreeDelete ( STree Segment ) + (let ( + ( IntegerSegment ( SegmentTreeGetInternalSegment + STree + Segment ) ) ) + ( SegmentTreeImpl STree IntegerSegment t ) ) ) + + +(defun SegmentTreeImpl ( STree Segment BDelete ) + (let ( + ( TreeSegment + STree->segment ) ) +; ( println ( list TreeSegment Segment ) ) + (if ( and + ( leqp ( car Segment ) ( car TreeSegment ) ) + ( geqp ( cadr Segment ) ( cadr TreeSegment ) ) ) + (if BDelete + ( SegmentTreeRemoveSegment STree Segment ) + ( SegmentTreeAddSegment STree Segment ) ) + (let ( + ( MidPoint + ( quotient ( plus ( car TreeSegment ) + ( cadr TreeSegment ) ) + 2 ) ) ) + (if ( lessp ( car Segment ) MidPoint ) + ( SegmentTreeImpl + STree->left + Segment + BDelete ) ) + (if ( lessp MidPoint ( cadr Segment ) ) + ( SegmentTreeImpl + STree->right + Segment + BDelete ) ) ) ) + (cond ( + ( not ( SegmentTreeIsSegments STree ) ) + STree->cover = ( plus (cond ( + STree->left + STree->left->cover ) + ( + 0.0 ) ) + (cond ( + STree->right + STree->right->cover ) + ( + 0.0 ) ) ) ) + ( + t + STree->cover = ( SegmentTreeGetSegmentSize + STree ) ) ) ) ) + +;segments: +;this is not a set, but a list +(defun SegmentTreeIsSegments ( STree ) + ( exists + Segment + STree->segments + ( geqp ( arrayref STree->segments Segment ) 1 ) ) ) + +(defun SegmentTreeAddSegment ( STree Segment ) + ( setarray + STree->segments + Segment + ( plus ( arrayref STree->segments Segment ) 1 ) ) ) + +(defun SegmentTreeRemoveSegment ( STree Segment ) + (let ( + ( Count + ( arrayref STree->segments Segment ) ) ) + (cond ( + ( geqp Count 2 ) + ( setarray STree->segments Segment + ( difference Count 1 ) ) ) + ( + t + ( remove Segment STree->segments ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/checklength.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/checklength.il new file mode 100644 index 0000000000..f1bf9bfad7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/checklength.il @@ -0,0 +1,625 @@ +(defun CheckLengthAccumulate ( Fig Table ) + (let ( + ( Type ( getq Fig objType ) ) + ( Key nil ) + ( Incr 0 ) ) + (cond ( + ( equal Type "path" ) + (let () + ( setq Key ( getq Fig lpp ) ) + ( setq Incr ( PathGetDistance Fig ) ) + ) ) + ( + ( equal Type "rect" ) + (let ( + ( BBox ( getq Fig bBox ) ) ) + ( setq Key ( getq Fig lpp ) ) + ( setq Incr ( max ( BBoxGetHeight BBox ) + ( BBoxGetWidth BBox ) ) ) ) ) + ( + ( equal Type "polygon" ) + (let () + ( setq Key ( getq Fig lpp ) ) + ( setq Incr ( quotient ( PolygonPerimeter ( getq Fig points ) ) + 2 ) ) ) ) + ( + ( equal Type "inst" ) + (let () + ( setq Key ( getq Fig master ) ) + ( setq Incr 1 ) ) ) ) + (if Key + ( setarray Table Key ( plus ( arrayref Table Key ) Incr ) ) ) ) ) + +(defun CheckLengthRoutedLocal ( Net Table ) + (let ( + ( Fig nil ) + ( Term ( getq Net term ) ) ) + ( foreach + Fig + ( getq Net figs ) + ( CheckLengthAccumulate Fig Table ) ) + (if Term + ( foreach + Pin + ( getq Term pins ) + (let ( + ( Fig ( getq Pin fig ) ) ) + (if Fig + ( CheckLengthAccumulate Fig Table ) ) ) ) ) + Table ) ) + +(defun CheckLengthPutCache ( Net Value Cache ) + (letseq ( + ( CellView ( getq Net cellView ) ) + ( Key ( list ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) + ( CellCache ( arrayref Cache Key ) ) ) + (unless CellCache + ( setq CellCache ( makeTable "cell cache" nil ) ) + ( setarray Cache Key CellCache ) ) + ( setarray CellCache ( getq Net name ) Value ) ) ) + +(defun CheckLengthLookupCache ( Net Cache ) + (letseq ( + ( CellView ( getq Net cellView ) ) + ( Key ( list ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) + ( CellCache (if Cache ( arrayref Cache Key ) ) ) ) + (if CellCache + ( arrayref CellCache ( getq Net name ) ) ) ) ) + +(defun CheckLengthCombine ( LocalTable RemoteTable ) + (let ( + ( Result ( makeTable "remote" 0 ) ) ) + ( foreach Key LocalTable + (let ( + ( LocalValue ( arrayref LocalTable Key ) ) + ( RemoteValue ( arrayref RemoteTable Key ) ) ) + ( setarray Result Key ( plus LocalValue RemoteValue ) ) ) ) + ( foreach Key RemoteTable + (let ( + ( LocalValue ( arrayref LocalTable Key ) ) + ( RemoteValue ( arrayref RemoteTable Key ) ) ) + (if ( equal LocalValue 0 ) + ( setarray Result Key RemoteValue ) ) ) ) + Result ) ) + +(defun CheckLengthCombineInplace ( CachedTable RemoteTable ) + ( foreach Key CachedTable + (let ( + ( CachedValue ( arrayref CachedTable Key ) ) + ( RemoteValue ( arrayref RemoteTable Key ) ) ) + ( setarray RemoteTable Key ( plus CachedValue RemoteValue ) ) ) ) ) + +(defun CheckLengthRoutedRecursive ( Net LocalTable RemoteTable Cache ) + (letseq ( + ( LibCellExpressionPairsToIgnore LeafCellInstanceLibCellPairRegExs ) + ( InstTerm nil ) + ( Recursive ( eq LocalTable RemoteTable ) ) + ( Cached (if Recursive ( CheckLengthLookupCache Net Cache ) ) ) ) + (if Cached + ( CheckLengthCombineInplace Cached RemoteTable ) + (letseq ( + ( RealRemote ( makeTable "remote" 0 ) ) ) + ( CheckLengthRoutedLocal Net (if Recursive RealRemote LocalTable ) ) + ( foreach + InstTerm + ( CheckLengthFilterInstTerms + ( getq Net instTerms ) + LibCellExpressionPairsToIgnore ) + (letseq ( + ( Term ( getq InstTerm term ) ) + ( Abstract ( CheckLengthGetAbstract Term ) ) + ( InstNet ( getq Term net ) ) ) + (if Abstract + (let ( + ( Key "abstract" ) ) + ( setarray + RealRemote + Key + ( plus ( arrayref RealRemote Key ) Abstract ) ) ) + ( CheckLengthRoutedRecursive + InstNet + RealRemote + RealRemote + Cache ) ) ) ) + (if ( and Cache ( getq Net term ) ) + ( CheckLengthPutCache + Net + (if Recursive + RealRemote + ( CheckLengthCombine LocalTable RealRemote ) ) + Cache ) ) + ( CheckLengthCombineInplace RealRemote RemoteTable ) ) ) + ) ) + +(defun CheckLengthSummarize ( Table ViaCost ) + (let ( + ( Key nil ) + ( Sum 0.0 ) ) + ( foreach Key Table + (let ( + ( Value ( arrayref Table Key ) ) + ( Incr 0 ) ) + (cond ( + ( equal Key "abstract" ) + ( setq Incr Value ) ) + ( + ( listp Key ) + ( setq Incr Value ) ) + ( + t + ( setq Incr ( times ViaCost Value ) ) ) ) + ( setq Sum ( plus Sum Incr ) ) ) ) + Sum ) ) + +(defun CheckLengthRouted ( Net @key ( ViaCost 0.1 ) ( Cache nil ) ) + (let ( + ( LocalTable ( makeTable "local" 0 ) ) + ( RemoteTable ( makeTable "remote" 0 ) ) + ( LocalSum 0.0 ) + ( RemoteSum 0.0 ) ) + ( CheckLengthRoutedRecursive Net LocalTable RemoteTable Cache ) + ( setq LocalSum ( CheckLengthSummarize LocalTable ViaCost ) ) + ( setq RemoteSum ( CheckLengthSummarize RemoteTable ViaCost ) ) + ( list LocalSum RemoteSum ) ) ) + +(defun IdentityTransform () '( ( 0 0 ) "R0" 1.0 ) ) + +; Returns a list of ( Transform Terminal ) pairs for every terminal on a net. +(defun CheckLengthDistanceTerms ( Net Transform ) + (let ( + ( Terms nil ) + ) + ( setq + Terms + ( mapcar + '(lambda + ( InstTerm ) + ( list + ( dbConcatTransform + Transform + ( getq ( getq InstTerm inst ) transform ) ) + ( getq InstTerm term ) ) ) + ( getq Net instTerms ) ) ) + (if ( getq Net term ) + ( cons ( list Transform ( getq Net term ) ) Terms ) + Terms ) ) ) + +(defun CheckLengthPinDistance ( Transform1 Pin1 Transform2 Pin2 ) + (let ( + ( Fig1 ( getq Pin1 fig ) ) + ( Fig2 ( getq Pin2 fig ) ) ) + (if ( and Fig1 Fig2 ) + (let ( + ( Result nil ) + ( BBox1 ( dbTransformBBox ( getq Fig1 bBox ) Transform1 ) ) + ( BBox2 ( dbTransformBBox ( getq Fig2 bBox ) Transform2 ) ) ) + ( foreach + Point1 + ( list ( lowerLeft BBox1 ) + ( upperRight BBox1 ) ) + ( foreach + Point2 + ( list ( lowerLeft BBox2 ) + ( upperRight BBox2 ) ) + ( setq + Result + ( CheckLengthDistanceMin + Result + ( PointManhattanDistance Point1 Point2 ) ) ) ) ) + Result ) ) ) ) + +(defun CheckLengthDistanceMin ( Dist1 Dist2 ) + (cond ( ( null Dist1 ) Dist2 ) + ( ( null Dist2 ) Dist1 ) + ( ( lessp Dist1 Dist2 ) Dist1 ) + ( t Dist2 ) ) ) + +(defun CheckLengthManhattanLocal ( Net ) + (let ( + ( Result nil ) + ( Terms ( CheckLengthDistanceTerms Net ( IdentityTransform ) ) ) ) + (cond ( + ( null Terms ) ) + ( + ( null ( cdr Terms ) ) + (let ( + ( BBox ( getq ( getq Net cellView ) bBox ) ) ) + ( plus ( BBoxGetHeight BBox ) ( BBoxGetWidth BBox ) ) ) ) + ( + ( null ( cddr Terms ) ) + (letseq ( + ( Info1 ( car Terms ) ) + ( Info2 ( cadr Terms ) ) + ( Transform1 ( car Info1 ) ) + ( Term1 ( cadr Info1 ) ) + ( Transform2 ( car Info2 ) ) + ( Term2 ( cadr Info2 ) ) + ) + ( foreach + Pin1 + ( getq Term1 pins ) + ( foreach + Pin2 + ( getq Term2 pins ) + (let ( + ( Distance ( CheckLengthPinDistance + Transform1 + Pin1 + Transform2 + Pin2 ) ) ) + ( setq + Result + ( CheckLengthDistanceMin + Result + Distance ) ) ) ) ) ) ) + ( + t + (let ( + ( BBox nil ) ) + ( foreach + Info + Terms + (let ( + ( Transform ( car Info ) ) + ( Term ( cadr Info ) ) ) + ( foreach + Pin + ( getq Term pins ) + (let ( + ( Fig ( getq Pin fig ) ) ) + (if Fig + ( setq + BBox + ( BBoxCombine + BBox + ( dbTransformBBox + ( getq Fig bBox ) + Transform ) ) ) ) ) ) ) ) + (if BBox + ( setq + Result + ( plus ( BBoxGetHeight BBox ) + ( BBoxGetWidth BBox ) ) ) ) ) ) ) + Result ) ) + +; Returns all instTerms whose associated instance passes the library cell +; filter +(defun CheckLengthFilterInstTerms ( InstTerms LibCellExpressionPairsToIgnore ) + ( car + ( NameFilterObjects + InstTerms + LibCellExpressionPairsToIgnore + (lambda ( InstTerm ) + ( getq ( getq InstTerm inst ) libName ) ) + (lambda ( InstTerm ) + ( getq ( getq InstTerm inst ) cellName ) ) ) ) ) + +; Return the bounding box of all sources and sinks on the given net +(defun CheckLengthJautoBBox ( Net Transform LibCellExpressionPairsToIgnore + Cache ) + (letseq ( + ( CellView ( getq Net cellView ) ) + ( Term ( getq Net term ) ) + ( Result (if Term ( CheckLengthLookupCache Net Cache ) ) ) ) + (unless Result + (let ( + ( InstTerms + ( CheckLengthFilterInstTerms + ( getq Net instTerms ) + LibCellExpressionPairsToIgnore ) ) ) + (if InstTerms + ( foreach InstTerm InstTerms + (let ( + ( InstNet ( getq ( getq InstTerm term ) net ) ) ) + ( setq + Result + ( BBoxCombine + Result + ( CheckLengthJautoBBox + InstNet + ( getq ( getq InstTerm inst ) transform ) + LibCellExpressionPairsToIgnore + Cache ) ) ) ) ) + ( setq Result ( getq CellView bBox ) ) ) + (if Term ( CheckLengthPutCache Net Result Cache ) ) ) ) + ( dbTransformBBox Result Transform ) ) ) + +; Compute the wirelength of a given net as Jauto would +(defun CheckLengthJauto ( Net Cache ) + (letseq ( + ( LibCellExpressionPairsToIgnore + ( append + WiringCellLibCellPairRegExs + LeafCellInstanceLibCellPairRegExs ) ) + ( BBox ( CheckLengthJautoBBox + Net + ( IdentityTransform ) + LibCellExpressionPairsToIgnore + Cache ) ) ) + ( plus ( BBoxGetHeight BBox ) ( BBoxGetWidth BBox ) ) ) ) + +; Return the wirelength for the given terminal stored in the abstract view +(defun CheckLengthGetAbstract ( Term ) + (letseq ( + ( CellView ( getq Term cellView ) ) + ( AbstractView + ( nrOpenCellViewReadable + ( getq CellView libName ) + ( getq CellView cellName ) + "abstract" ) ) ) + (if AbstractView + (let ( + ( AbstractTerm ( dbFindTermByName + AbstractView + ( getq Term name ) ) ) ) + (if AbstractTerm + ( dbGetPropByName AbstractTerm "WireLength" ) ) ) ) ) ) + +(defun CheckLengthReportNet ( Net Port @key ( Cache nil ) + ( JautoCache nil ) ) + (let ( + ( Jauto ( CheckLengthJauto Net JautoCache ) ) + ( Routed ( CheckLengthRouted Net ?Cache Cache ) ) + ( Local ( CheckLengthManhattanLocal Net ) ) + ) + ( fprintf + Port + "%s %6.3f %6.3f %6.3f %L\n" + ( getq Net name ) + Jauto + ( car Routed ) + ( cadr Routed ) + Local ) ) ) + +(defun CheckLengthReportAll ( CellView File + @key ( Cache ( makeTable "cache" nil ) ) + ( JautoCache ( makeTable "jauto" nil ) ) ) + (let ( + ( Port ( outfile File ) ) + ( Success t ) ) + ( fprintf + Port + "# This reports, for each net in the current cell, wirelength as would have been calculated by Jauto, routed wirelength in the current cell, routed wirelength in subcells, and manhattan wirelength in the current cell.\n" + ) + ( foreach + Net + ( getq CellView nets ) + (let ( + ( NetName ( getq Net name ) ) ) + (if ( and ( not ( equal NetName GNDNetName ) ) + ( not ( equal NetName VddNetName ) ) ) + (let ( + ( Err ( errset ( CheckLengthReportNet + Net + Port + ?Cache Cache + ?JautoCache JautoCache ) ) ) ) + (if ( null Err ) + (let () + ( printf "Error: cannot report wirelength for %s (%L)\n" + ( getq Net name ) + errset.errset ) + ( setq Success nil ) ) ) ) ) ) ) + ( close Port ) + Success ) ) + + + +;get a list of netname/length pairs from file +(defun GetNetLengthListFromFile (filename) + (let (file line pair netinfo netlengths) + file=(infile filename) + (if !file then + (printf "ERROR: can't read file %s" filename) + else + (while (gets line file) + (if (not (equal (getchar line 1) '\#)) + (let () + netinfo=(parseString line " ") + pair=(list (car netinfo) (atof (nth 4 netinfo)) ) + netlengths=(cons pair netlengths))) + ) + ) + (close file) + netlengths + ) +) + + +(defun CompareWireLengthsToManhattan (infilename outfilename) + (let (cv netlengths paths wirelength ratio file) + cv=(geGetWindowCellView) + file=(outfile outfilename) + netlengths=(GetNetLengthListFromFile infilename) + (foreach pair netlengths + paths=(GetPathsForNetName (car pair)) + (if paths then + wirelength=(TotalPathLength paths 0) + ratio=wirelength/(cadr pair) + else + wirelength=(cadr pair) + ratio=0.0 + ) + (fprintf file "%s %f %f\n" (car pair) (cadr pair) ratio) + ) + (close file) + ) +) + + +(defun CompareBusWireLengthsToManhattan (infilename outfilename) + (let (cv netlengths paths wirelength ratio file) + cv=(geGetWindowCellView) + file=(outfile outfilename) + netlengths=(GetNetLengthListFromFile infilename) + (foreach pair netlengths + paths=(GetBusScriptPathsForNetName (car pair)) + (if paths && (cadr pair) then + wirelength=(TotalPathLength paths 0) + ratio=wirelength/(plus (cadr pair) 0.01) + else + wirelength=(cadr pair) + ratio=0.0 + ) + (if (cadr pair) then + (fprintf file "%s %f %f\n" (car pair) (cadr pair) ratio) + else + (fprintf file "%s %s %f\n" (car pair) "NA" ratio) + ) + ) + (close file) + ) +) + +; Functions for displaying the wirelength report +(defun CheckLengthAdd (a b) (if (or (null a) (null b)) nil (plus a b))) + +(defun CheckLengthReadFullReport (filename) + (let (file line fields result) + (setq file (infile filename)) + (if file + (while (gets line file) + (if (not (equal (getchar line 1) '\#)) + (let () + (setq fields (parseString line " ")) + (setq result + (cons (list (nth 0 fields) + (CheckLengthAdd (atof (nth 2 fields)) + (atof (nth 3 fields))) + (atof (nth 2 fields)) + (atof (nth 3 fields)) + (atof (nth 1 fields)) + (atof (nth 4 fields))) result))))) + (error "Cannot read file: %s" filename)) + result)) + +(defvar CheckLengthReportState) + +(defun CheckLengthSelectNet (sel func) + (let (name instTerm net fig (cv CheckLengthReportState->cellView)) + (foreach name sel + net = (dbFindNetByName cv name) + (if net + (let () + (foreach fig net->figs + (funcall func fig)) + (foreach instTerm net->instTerms + (if (equal instTerm->inst->libName TechLibName) + (funcall func instTerm->inst)))) + (printf "Warning: cannot find net: %L\n" name))))) + +(defun CheckLengthSelectCB (sel) + (CheckLengthSelectNet sel 'geSelectObject)) + +(defun CheckLengthDeselectCB (sel) + (CheckLengthSelectNet sel 'geDeselectObject)) + +(defun CheckLengthReportCB (field values) + (let ((table (makeTable "SelectedTable" nil)) sel desel net + (prevTable CheckLengthReportState->table) + ) + (foreach value values + (let ((choices checkLengthReportForm->checkLengthReportField->choices)) + net = (car (nth value choices)) + table[net] = t + (if (not prevTable[net]) + sel = (cons net sel)))) + (foreach net prevTable + (if (null table[net]) + desel = (cons net desel))) + CheckLengthReportState->table = table + (if (and desel CheckLengthReportState->deselectCB) + (funcall CheckLengthReportState->deselectCB desel)) + (if (and sel CheckLengthReportState->selectCB) + (funcall CheckLengthReportState->selectCB sel)))) + +(defun CheckLengthSearchCB (fieldName regex sourceOfChange) + (let (net (first (getchar regex 1)) magic hint) + (if (eq first '\/) ; if starts with /, treat as regular expression + (let () + (setq regex (substring regex 2)) + (setq hint "Input regular expression") + (setq magic t)) + (setq hint (if (equal regex "") "Use / to start regular expression" ""))) + + (if (or (null regex) (equal regex "")) + checkLengthReportForm->checkLengthReportField->choices = + CheckLengthReportState->allRows + (let () + (rexMagic magic) + (if (errset (rexCompile regex)) + (let (choices) + (foreach row CheckLengthReportState->allRows + (setq net (car row)) + (if (rexExecute net) + (setq choices (cons row choices)))) + checkLengthReportForm->checkLengthReportField->choices = choices) + (if magic + hint = (car (nth 4 errset.errset))) + ) + (rexMagic t))) + (if hint + checkLengthReportForm->checkLengthRegexField->value = hint) + t)) + +(defun CheckLengthReportWidth (label text) + (max (ceiling (plus (hiGetTextWidth (hiGetFont "label") label) 10)) + (ceiling (hiGetTextWidth (hiGetFont "text") text)))) + +(defun CheckLengthReportForm (wirelengths) + (let (searchField mainField form netWidth fieldWidth allWidth) + CheckLengthReportState = '(nil) + CheckLengthReportState->table = (makeTable "SelectedTable" nil) + CheckLengthReportState->cellView = (geGetEditCellView) + CheckLengthReportState->selectCB = 'CheckLengthSelectCB + CheckLengthReportState->deselectCB = 'CheckLengthDeselectCB + CheckLengthReportState->allRows = wirelengths + (setq searchField + (hiCreateStringField + ?name 'checkLengthSearchField + ?prompt "Filter net: " + ?modifyCallback "CheckLengthSearchCB" + ?editable t)) + (setq regexField + (hiCreateLabel + ?name 'checkLengthRegexField + ?labelText "Use / to start regular expression" + ?enabled t)) + netWidth = 300 + fieldWidth = (max (CheckLengthReportWidth "Total" "88888.888") + (CheckLengthReportWidth "Local" "88888.888") + (CheckLengthReportWidth "Subcells" "88888.888") + (CheckLengthReportWidth "Jauto" "88888.888") + (CheckLengthReportWidth "Manhattan" "88888.888")) + 10 + allWidth = netWidth + fieldWidth * 5 + 24 ; vertical scrollbar 24px wide + (setq mainField + (hiCreateReportField + ?name 'checkLengthReportField + ?headers `(("Net" ,netWidth left string t) + ("Total" ,fieldWidth right float3 t) + ("Local" ,fieldWidth right float3 t) + ("Subcells" ,fieldWidth right float3 t) + ("Jauto" ,fieldWidth right float3 t) + ("Manhattan" ,fieldWidth right float3 t)) + ?choices wirelengths + ?sort '(1 t) + ?callback 'CheckLengthReportCB + ?enableDeselectCB t + )) + (setq form + (hiCreateAppForm + ?name 'checkLengthReportForm + ?formTitle "Wirelength Report" + ?initialSize t + ?buttonLayout 'OKCancel + ?fields + (list + (list searchField 0:0 200:hicLineHeight + (hiGetTextWidth (hiGetFont "label") searchField->prompt)) + (list regexField 250:0 100:hicLineHeight) + (list mainField 0:hicLineHeight allWidth:1000 100)))) + (hiDisplayForm form))) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/deletepins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/deletepins.il new file mode 100644 index 0000000000..9012aefa3e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/deletepins.il @@ -0,0 +1,17 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun DeletePinsDeletePinFromShape ( ShapeObj ) + (let ( + ( PinObj ( getq ShapeObj pin ) ) ) + (when PinObj + (let ( + ( TerminalObj ( getq PinObj term ) ) ) + (let ( + ( TerminalName ( getq TerminalObj name ) ) ) + ( dbDeleteObject PinObj ) + (unless ( getq TerminalObj pins ) + ( dbDeleteObject TerminalObj ) ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/length.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/length.il new file mode 100644 index 0000000000..4535699e4b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/length.il @@ -0,0 +1,252 @@ +; Wire length checking functions. Use net connectivity as a hint, but +; use overlaps to find wiring without connectivity as well. +; Recursively accumulates lengths in subcells. +; +; NOTE: Needs cleanup, refactoring, optimization. There are at least +; 3 other codebases that check for long wires! + +; Report total wirelengths of nets. Optionally provide the net name, +; or a regular expression. Optionally length cutoff, select top-level +; shapes, enable recursion. +(defun ReportNetLengths + (@key (CV (geGetEditCellView)) ; cell view + (minLength 0) ; minimum length to report + (rex nil) ; regular expression to pick nets + (name nil) ; a single net name to evaluate + (select nil) ; select top-level nets for debugging + (recurse t) ; recurse into subcells + ) + (let (nets Vdd GND file lines line cachelength cacheleaf done_polygons) + (cond (rex + (rexCompile rex) + nets = (setof net CV->nets (rexExecute net->name)) + ) + (name + nets = (list (dbFindNetByName CV name)) + ) + (t + nets = CV->nets + ) + ) + GND = (dbFindNetByName CV "GND") + Vdd = (dbFindNetByName CV "Vdd") + (when (length nets)>100 (printf "# Evaluating %d nets\n" (length nets))) + cachelength = (makeTable "cachelength" nil) + cacheleaf = (makeTable "cacheleaf" nil) + done_polygons = 0 + (foreach net (sort nets 'CompareNetNames) + (unless net==Vdd || net==GND + length = (NetLength net ?select select ?recurse recurse) + (when length>minLength + line = (list net->name length) + (printf "%s %g\n" (car line) (cadr line)) + lines = (cons line lines) + ) + ) + ) + file = (outfile (sprintf nil "%s.lengths" CV->cellName)) + lines = (sort lines 'CompareNetLengths) + (foreach line lines (fprintf file "%s %g\n" (car line) (cadr line))) + (close file) + (when done_polygons>0 + (printf "WARNING: found %d polygons, results may be inaccurate!\n" + done_polygons)) + ) + t + ) + +; compare (name length) pairs in decreasing length +(defun CompareNetLengths (a b) + (cadr a) >= (cadr b) + ) + +; compare net names in increasing order +(defun CompareNetNames (a b) + (strcmp a->name b->name)<=0 + ) + +; total length of all path/rect/polygon in a list of shapes +(defun TotalLengthOfObjects (shapes) + (let (length points p0 p1 x0 y0 x1 y1) + length = 0.0 + (foreach shape shapes + (when (isMetalDrawing shape->layerName shape->purpose) + (cond (shape->objType=="path" + ; length of segments + points = shape->points + (for i 0 (length points)-2 + p0 = (nth i points) + p1 = (nth i+1 points) + x0 = (car p0) + y0 = (cadr p0) + x1 = (car p1) + y1 = (cadr p1) + length = length+(abs x1-x0)+(abs y1-y0) + ) + ) + (shape->objType=="rect" + ; maximum width or height + x0 = (leftEdge shape->bBox) + y0 = (bottomEdge shape->bBox) + x1 = (rightEdge shape->bBox) + y1 = (topEdge shape->bBox) + length = length+(max x1-x0 y1-y0) + ) + (shape->objType=="polygon" + ; half the perimeter of a polygon + points = shape->points + (for i 0 (length points)-1 + p0 = (nth i points) + p1 = (nth (mod (i+1) (length points)) points) + x0 = (car p0) + y0 = (cadr p0) + x1 = (car p1) + y1 = (cadr p1) + length = length+((abs x1-x0)+(abs y1-y0))/2 + ) + ) + ) + ) + ) + length + ) + ) + +; return list of wires/contacts by net +(defun GetNetWiring (net @key (pins t) (figs t) (contacts t)) + (let (found) + found = nil + (when pins (foreach pin net->pins + found = (cons pin->fig found) + )) + (when figs (foreach fig net->figs + found = (cons fig found) + )) + (when contacts (foreach term net->instTerms + (when term->inst->libName==TechLibName + found = (cons term->inst found) + ) + )) + found + ) + ) + +; identify connected wiring (using "done" table to mark) +(defun GetConnectedWiring (obj) + (let (connected bboxes lpps transform lpp bbox overlaps o) + done[obj] = t + connected = nil + lpps = nil + bboxes = nil + (cond (obj->objType=="rect" + lpps = (list obj->lpp) + bboxes = (list obj->bBox) + ) + (obj->objType=="path" + (foreach rect (nrConvertPathToRectList obj) + lpps = (cons obj->lpp lpps) + bboxes = (cons rect bboxes) + ) + ) + (obj->objType=="polygon" + ; BUG: should convert polygons into rectangles + done_polygons = done_polygons+1 + ) + (obj->objType=="inst" + transform = (geGetInstTransform obj) + (foreach shape obj->master->shapes + lpps = (cons shape->lpp lpps) + bboxes = (cons (geTransformUserBBox shape->bBox transform) bboxes) + ) + ) + ) + (for i 0 (length lpps)-1 + lpp = (nth i lpps) + bbox = (nth i bboxes) + lpp = (list (car lpp) "drawing") + overlaps = (dbGetTrueOverlaps obj->cellView bbox lpp 1) + (foreach overlap overlaps + o = (if (atom overlap) overlap (car overlap)) + (when !done[o] && o->objType!="label" && + (o->objType!="inst" || o->libName==TechLibName) + connected = (cons o connected) + connected = (append (GetConnectedWiring o) connected) + ) + ) + ) + connected + ) + ) + +; Report total length of a net +(defun NetLength (net @key (select nil) (recurse t)) + (let (CV length explicit connected done leaf inst transform lpp bbox overlaps o) + CV = net->cellView + + ; detect leaf cells (only trust their pin connectivity!) + leaf = cacheleaf[CV] + (unless leaf + leaf = (length (setof x CV->instances x->libName=="gate" || x->libName=="stack")) + cacheleaf[CV] = leaf + ) + + ; get top level explicitly connected shapes + explicit = (GetNetWiring net ?contacts nil ?figs nil) + done = (makeTable "done" nil) + (foreach obj explicit done[obj]=t) + + ; add wires/contacts that overlap subcell pins + (when leaf==0 + (foreach instTerm net->instTerms + inst = instTerm->inst + (when inst->libName!=TechLibName + transform = (geGetInstTransform inst) + (foreach pin instTerm->term->pins + (unless pin->fig->objType=="rect" + (error "non-rectangular pin on %s = %s/%s\n" + net->name inst->name pin->net->name)) + bbox = (geTransformUserBBox pin->fig->bBox transform) + lpp = (list (car pin->fig->lpp) "drawing") + overlaps = (dbGetTrueOverlaps CV bbox lpp 1) + (foreach overlap overlaps + o = (if (atom overlap) overlap (car overlap)) + (when !done[o] && o->objType!="label" && + (o->objType!="inst" || o->libName==TechLibName) + done[o] = t + explicit = (cons o explicit) + ) + ) + ) + ) + ) + ) + connected = explicit + + ; expand connected list to include other overlapping shapes + (foreach obj explicit + connected = (append (GetConnectedWiring obj) connected) + ) + + ; select top level objects + (when select + (foreach obj connected (geSelectObject obj)) + ) + + ; compute top-level wirelength + length = (TotalLengthOfObjects connected) + + ; recursely accumulate connected subcells + (when leaf==0 && recurse + (foreach instTerm net->instTerms + (when instTerm->inst->libName!=TechLibName + length = length + + (if cachelength[instTerm->term->net] cachelength[instTerm->term->net] + cachelength[instTerm->term->net]=(NetLength instTerm->term->net)) + ) + ) + ) + + ; return total length + length + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/rectonpitch.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/rectonpitch.il new file mode 100644 index 0000000000..d15d4f72de --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/rectonpitch.il @@ -0,0 +1,132 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun RectOnPitchFindNearestPitch ( MetalSpacing MetalWidth BoundPosition Position ) + (let ( + ( Pitch ( plus MetalSpacing MetalWidth ) ) + ( HalfSpacing ( quotient MetalSpacing 2.0 ) ) + ( HalfWidth ( quotient MetalWidth 2.0 ) ) ) + ( plus + BoundPosition + ( plus + HalfSpacing + ( plus + HalfWidth + ( times + Pitch + ( round + ( quotient + ( difference + ( difference + ( difference + Position + BoundPosition ) + HalfWidth ) + HalfSpacing ) + Pitch ) ) ) ) ) ) ) ) + +(defun RectOnPitchMakeRectNearestPitchOnHorizontalLayer ( MfgGrid + MetalSpacing + MetalWidth + MinArea + BoundaryPoints + Point ) + (let ( + ( BottomOfBound ( cadr ( PolygonGetBottomLeftPoint BoundaryPoints ) ) ) ) + (let ( + ( CenterY ( RectOnPitchFindNearestPitch + MetalSpacing + MetalWidth + BottomOfBound + ( cadr Point ) ) ) + ( CenterX ( car Point ) ) ) + ( RectMakeFromCenter + ( list + CenterX + CenterY ) + ( times + MfgGrid + ( ceiling + ( quotient + ( quotient + MinArea + MetalWidth ) + MfgGrid ) ) ) + MetalWidth ) ) ) ) + +(defun RectOnPitchMakeRectNearestPitchOnVerticleLayer ( MfgGrid + MetalSpacing + MetalWidth + MinArea + BoundaryPoints + Point ) + (let ( + ( LeftOfBound ( car ( PolygonGetLeftBottomPoint BoundaryPoints ) ) ) ) + (let ( + ( CenterX ( RectOnPitchFindNearestPitch + MetalSpacing + MetalWidth + LeftOfBound + ( car Point ) ) ) + ( CenterY ( cadr Point ) ) ) + ( RectMakeFromCenter + ( list + CenterX + CenterY ) + MetalWidth + ( times + MfgGrid + ( ceiling + ( quotient + ( quotient + MinArea + MetalWidth ) + MfgGrid ) ) ) ) ) ) ) + +; ( RectOnPitchDrawRectOnPitch 0.05 0.24 0.24 0.2 ( list "METAL2" "drawing" ) nil ( list "prBoundary" "drawing" ) ( geGetWindowCellView ) ( hiGetPoint ( hiGetCurrentWindow ) ) ) +(defun RectOnPitchDrawRectOnPitch ( MfgGrid + MetalSpacing + MetalWidth + MinArea + LayerPP + IsHorizontal + BoundaryLPP + CellView + Point ) + (let ( + ( BoundaryShape ( car + ( setof + Shape + ( getq CellView shapes ) + (let ( + ( ShapeLPP ( getq Shape lpp ) ) ) + ( and + ( equal ( car BoundaryLPP ) ( car ShapeLPP ) ) + ( equal ( cadr BoundaryLPP ) ( cadr ShapeLPP ) ) ) ) ) ) ) ) + (let ( + ( BoundaryPoints (if ( equal ( getq BoundaryShape objType ) "rect" ) + ( RectGetPoints ( getq BoundaryShape bBox ) ) + ( getq BoundaryShape points ) ) ) ) + (let ( + ( TheRect (if IsHorizontal + ( RectOnPitchMakeRectNearestPitchOnHorizontalLayer + MfgGrid + MetalSpacing + MetalWidth + MinArea + BoundaryPoints + Point ) + ( RectOnPitchMakeRectNearestPitchOnVerticleLayer + MfgGrid + MetalSpacing + MetalWidth + MinArea + BoundaryPoints + Point ) ) ) ) + ( dbCreateRect + CellView + LayerPP + TheRect ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/wiring.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/wiring.il new file mode 100644 index 0000000000..9a1cff3ed5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hand/wiring.il @@ -0,0 +1,349 @@ +; compare two contacts for electrical connection +(defun ContactsConnected (obj1 obj2) + (let (match) + match = nil + (foreach lpp1 obj1->master->lpps + (foreach lpp2 obj2->master->lpps + (cond (lpp1->layerName==lpp2->layerName match=t)) + ) + ) + match + ) + ) + +; compare a path and a contact for electrical connection +(defun PathAndContactConnected (path inst) + (let (match bbox x y) + match = nil + + ; first check if contact's center overlaps path + bbox = path->bBox + x = (car inst->xy) + y = (cadr inst->xy) + (cond ((and x>=(leftEdge bbox) x<=(rightEdge bbox) + y>=(bottomEdge bbox) y<=(topEdge bbox)) + ; check VIA names + (for N 1 7 + (rexCompile (sprintf nil ".*%s%d%d.*" ViaLayerPrefix N N+1)) + (cond ((and (rexExecute inst->cellName) + (or (path->layerName==(sprintf nil "%s%d" MetalLayerPrefix N)) + (path->layerName==(sprintf nil "%s%d" MetalLayerPrefix N+1)))) + match=t + ) + ) + ) + + ; check symbolic vias + (foreach lpp inst->master->lpps + (cond (lpp->layerName==path->layerName match=t)) + ) + ) + ) + match + ) + ) + +; check if two overlapping objects are electrically connected +(defun areOverlappingObjectsConnected (obj1 obj2) + (cond ((and obj1->objType!="inst" obj2->objType!="inst") + (obj1->layerName==obj2->layerName)) + ((and obj1->objType!="inst" obj2->objType=="inst") + (PathAndContactConnected obj1 obj2)) + ((and obj1->objType=="inst" obj2->objType!="inst") + (PathAndContactConnected obj2 obj1)) + ((and obj1->objType=="inst" obj2->objType=="inst") + (ContactsConnected obj1 obj2)) + ) + ) + +; recursively identify connected wiring, clear BusMark as you go +(defun ConnectedWiring (view obj) + (let (connected overlaps bbox lpps o) + connected = nil + (when (GetProp obj "BusMark" nil) + (dbDeletePropByName obj "BusMark") + connected = (list obj) + bbox = obj->bBox + lpps = (list obj->lpp) + (when obj->objType=="inst" + bbox = (list obj->xy obj->xy) + lpps = nil + (foreach lpp obj->master->lpps + lpps = (cons (list lpp->layerName lpp->purpose) lpps) + ) + ) + (foreach lpp lpps + overlaps = (dbGetOverlaps view bbox lpp 1) + (foreach overlap overlaps + o = (if (atom overlap) overlap (car overlap)) + (when (areOverlappingObjectsConnected obj o) + connected = (append connected (ConnectedWiring view o)) + ) + ) + ) + ) + connected + ) + ) + +; total length of all paths in a list of shapes +(defun TotalPathLength (shapes pinLength) + (let (length points p0 p1 x0 y0 x1 y1) + length = 0 + (foreach shape shapes + (cond (shape->pin length = length + pinLength) + ((isWiringPath shape) + points = shape->points + (for i 0 (length points)-2 + p0 = (nth i points) + p1 = (nth i+1 points) + x0 = (car p0) + y0 = (cadr p0) + x1 = (car p1) + y1 = (cadr p1) + length = length+(abs x1-x0)+(abs y1-y0) + ) + ) + ) + ) + length + ) + ) + +; Select all shapes and contacts connected to selected objects +(defun SelectConnectedWiring () + (let (view wiring) + view = (geGetEditCellView) + (SetBusMark view) + (foreach obj (geGetSelSet) + wiring = (ConnectedWiring view obj) + (foreach fig wiring (geSelectObject fig)) + ) + (ClearBusMark view) + ) + t + ) + +; return list of shapes connected to argument object +(defun GetConnectedWires (wire) + (let (view wiring wires) + view = wire->cellView + (SetBusMark view) + wiring = (ConnectedWiring view wire) + (ClearBusMark view) + (foreach obj wiring + (when (isWiringPath obj) + wires = (cons obj wires) + ) + ) + wires + ) +) + +; return set of shapes connected to each input shape in a list +(defun GetConnectedWireSets (CV objects) + (let (groups connected) + groups = nil + (SetBusMark CV) ; mark all nets only once + (foreach shape objects + connected = (ConnectedWiring CV shape) + (when connected groups = (cons connected groups)) + ) + (ClearBusMark CV) ; clear remaining markings + groups + ) + ) + +; mark all long wires +(defun FindLongWires (length pinLength) + (let (view connected) + view = (geGetEditCellView) + (geDeleteAllMarker view) + (SetBusMark view) + + ; test length of all shapes that still have BusMark property + (foreach shape view->shapes + (cond ((GetProp shape "BusMark" nil) + connected = (ConnectedWiring view shape) + (cond ((TotalPathLength connected pinLength)>length + (MarkWires connected))))) + ) + ) + t + ) + + + + +(defun IsWiringCell (cell) + (let (iswiring) + iswiring = nil + (foreach part (parseString cell->cellName "." ) + (when part=="wires" iswiring=t ) + ) + (when cell->name=="wires" iswiring=t) + iswiring +)) + + +(defun IsGlobalsCell (cell) + (let (isglobals) + (if cell->libName=="globals" then + isglobals=t + else + islgobals=nil + ) + isglobals +)) + + +(defun IsCustomWiringCell (cell) + (let (iscustom) + (if (IsWiringCell cell) && !(IsGlobalsCell cell) + && !(IsGuideInst cell) && !(IsPowerGridCell cell) then + iscustom=t + else + iscustom=nil + ) + iscustom +)) + + +; return paths on a given net, +; also return paths with no connectivity if argument is nil +(defun GetPathsForNet (net) + (let (paths cv) + cv=(geGetEditCellView) + (foreach shape cv->shapes + (when shape->objType=="path" + && shape->net==net + && (cadr shape->lpp)=="drawing" + paths=(cons shape paths) + ) + ) + paths + ) +) + +(defun GetPathsForNetName (netname) + (let (paths cv) + cv=(geGetEditCellView) + (foreach shape cv->shapes + (when shape->objType=="path" + && shape->net->name==netname + && (cadr shape->lpp)=="drawing" + paths=(cons shape paths) + ) + ) + paths + ) +) + +; same as above, but only if they were drawn by bus script +(defun GetBusScriptPathsForNet (net) + (let (paths cv) + cv=(geGetEditCellView) + (foreach shape cv->shapes + (when shape->objType=="path" + && shape->net==net + && (cadr shape->lpp)=="drawing" + && (IsBusObject shape) + paths=(cons shape paths) + ) + ) + paths + ) +) + +(defun GetBusScriptPathsForNetName (netname) + (let (paths cv) + cv=(geGetEditCellView) + (foreach shape cv->shapes + (when shape->objType=="path" + && shape->net->name==netname + && (cadr shape->lpp)=="drawing" + && (IsBusObject shape) + paths=(cons shape paths) + ) + ) + paths + ) +) + + +; collection of functions to assist in doing +; leaf cells by hand +(defun SetHandLayoutProp (obj) + (when obj + (dbReplaceProp obj "HandLayoutObject" "boolean" t) + ) +) + +(defun IsHandLayoutObject (obj) + (let (ishand) + ishand=nil + (when obj + ishand=(dbGetPropByName obj "HandLayoutObject") + ) + ishand + ) +) + +(defun SetHandLayoutSelectedObjects () + (let (cv ss) + cv=(geGetEditCellView) + ss=(geGetSelectedSet cv) + (foreach obj ss + (SetHandLayoutProp obj) + ) + ) +) + +(defun SetHandLayoutAllObjects () + (let (cv set) + cv=(geGetEditCellView) + set=cv->shapes + (foreach obj set + (SetHandLayoutProp obj) + ) + set=cv->instances + (foreach obj set + (SetHandLayoutProp obj) + ) + set=cv->vias + (foreach obj set + (SetHandLayoutProp obj) + ) + ) +) + +(defun DeleteObjectsNotHandLayout () + (let (cv set) + cv=(geGetEditCellView) + set=cv->instances + (foreach obj set + (when !(IsHandLayoutObject obj) + && obj->libName!="gate" + && obj->libName!="stack" + (dbDeleteObject obj) + ) + ) + set=cv->shapes + (foreach obj set + (when !(IsHandLayoutObject obj) + && !obj->pin + && (car obj->lpp)!="prBoundary" + (dbDeleteObject obj) + ) + ) + set=cv->vias + (foreach obj set + (when !(IsHandLayoutObject obj) + && !obj->pin + && (car obj->lpp)!="prBoundary" + (dbDeleteObject obj) + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/hierarchy.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/hierarchy.il new file mode 100644 index 0000000000..4e8fb6ee08 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/hierarchy.il @@ -0,0 +1,805 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun HierarchyGetMaxDepth ( CellView + @key + ( LibCellsToIgnore nil ) + ( DescendIntoInstancePredicate + (lambda ( Instance CurrTransform ) t) ) + ) + (cond ( + ( ListFindMaximum + ( car ( NameFilterInstances + ( getq CellView instances ) + LibCellsToIgnore ) ) + (lambda ( Instance ) + (cond ( + ( null ( getq ( getq Instance master ) instances ) ) + 1 ) + ( + ( plus 1 ( HierarchyGetMaxDepth + ( getq Instance master ) + ?LibCellsToIgnore LibCellsToIgnore + ) ) ) ) ) ) ) + ( + 0 + ) + ) ) + +(defun HierarchyGetCellDescendantsMakeStackFrame ( Cell Instances ) + ( list + Cell + Instances ) ) + +(defun HierarchyGetCellDescendantsPush ( Stack + Cell + Instances ) + ( cons ( list Cell Instances ) Stack ) ) + +(defun HierarchyGetCellDescendantsSmartPush ( Stack + CellTable + Cell + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) + (if ( arrayref CellTable ( HierarchyMakeKeyStringForCellView Cell ) ) + Stack + ( HierarchyGetCellDescendantsPush + Stack + Cell + (let ( + ( FilterResult ( NameFilterInstances + ( getq Cell instances ) + LibCellExpressionPairsToIgnore ) ) ) + ( foreach + Instance + ( cadr FilterResult ) + ( setarray CellTable ( HierarchyMakeKeyStringForInstance Instance ) t ) ) + ( setof + Instance + ( car FilterResult ) + (unless ( or + ( null ( getq Instance master ) ) + ( arrayref + CellTable + ( HierarchyMakeKeyStringForInstance + Instance ) ) ) + (if ( apply + CellIgnoreFunc + ( cons + ( getq Instance master ) + CellIgnoreFuncParams ) ) + ( setarray CellTable ( HierarchyMakeKeyStringForInstance Instance ) t ) + t ) ) ) ) ) ) ) + + +(defun HierarchyGetCellDescendantsGetCurrInstance ( Stack ) + ( car ( car ( cdr ( car Stack ) ) ) ) ) + +(defun HierarchyGetCellDescendantsNextInstance ( Stack ) + ( HierarchyGetCellDescendantsPush + ( cdr + Stack ) + ( car + ( car + Stack ) ) + ( cdr + ( car + ( cdr + ( car + Stack ) ) ) ) ) ) + +(defun HierarchyGetCellDescendantsGetCurrCell ( Stack ) + ( car ( car Stack ) ) ) + +(defun HierarchyMakeKeyStringForCellView ( CellView ) + ( sprintf + nil + "%s,%s,%s" + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) + +(defun HierarchyMakeKeyStringForInstance ( Instance ) + ( HierarchyMakeKeyStringForCellView ( getq Instance master ) ) ) + + +(defun HierarchyInnerGetCellDescendants ( RootCellView + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams + TouchedCells ) + (let ( + ( Result nil ) + ( Stack nil ) + ( RootInstances ( getq RootCellView instances ) ) ) + ( setq Stack ( HierarchyGetCellDescendantsSmartPush + Stack + TouchedCells + RootCellView + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) ) + + (while Stack + (let ( + ( CurrInstance ( HierarchyGetCellDescendantsGetCurrInstance Stack ) ) ) + (if CurrInstance + (let () + ( setq Stack ( HierarchyGetCellDescendantsNextInstance Stack ) ) + ( setq Stack ( HierarchyGetCellDescendantsSmartPush + Stack + TouchedCells + ( getq CurrInstance master ) + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) ) ) + (let ( + ( CurrCell ( HierarchyGetCellDescendantsGetCurrCell Stack ) ) + ) + ( setarray TouchedCells ( HierarchyMakeKeyStringForCellView CurrCell ) t ) + ( setq Result ( tconc Result CurrCell ) ) + ( setq Stack ( cdr Stack ) ) ) ) ) ) + ( car Result ) ) ) + +(defun HierarchyGetCellDescendants ( RootCellView + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) + ( HierarchyInnerGetCellDescendants + RootCellView + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams + ( makeTable "HierarchyGetCellDescendantsTable" nil ) ) ) + +(defun HierarchyGetCellDescendantsOfCells ( ListOfRootCellViews + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) + (let ( + ( TouchedCells ( makeTable "HierarchyGetCellDescendantsTable" nil ) ) + ( Ret nil ) ) + ( foreach + RootCellView + ListOfRootCellViews + ( setq + Ret + ( lconc + Ret + ( HierarchyInnerGetCellDescendants + RootCellView + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams + TouchedCells ) ) ) ) + ( car Ret ) ) ) + +(defun HierarchyGetCellDescendantsOfLibCellViewTripples ( ListOfRootLibCellViewTripples + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) + ( HierarchyGetCellDescendantsOfCells + ( ListApplyFuncToListAndAccumulateNonNilResults + ListOfRootLibCellViewTripples + (lambda ( Tripple ) + (let ( + ( LibName ( car Tripple ) ) + ( CellName ( cadr Tripple ) ) + ( ViewName ( caddr Tripple ) ) ) + (let ( + ( CellViewDDObj ( ddGetObj LibName CellName ViewName ) ) ) + (when ( and + CellViewDDObj + ( getq CellViewDDObj files ) ) + ( dbOpenCellViewByType + LibName + CellName + ViewName + nil + "r" ) ) ) ) ) + nil ) + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) ) + +(defun HierarchyGetAllCellsInTree ( RootCellView + LibCellExpressionPairsToIgnore ) + ( HierarchyGetCellDescendants + RootCellView + LibCellExpressionPairsToIgnore + (lambda + ( CellView ) + nil ) + nil ) ) + +(defun HierarchyGetDescendantLibCellPairs ( RootCellView + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) + ( ListRemoveDuplicates + ( ListApplyFuncToListAndAccumulateResults + ( HierarchyGetCellDescendants + RootCellView + LibCellExpressionPairsToIgnore + CellIgnoreFunc + CellIgnoreFuncParams ) + (lambda ( CellView ) + ( list ( getq CellView libName ) ( getq CellView cellName ) ) ) + nil ) + (lambda ( LibCellPair0 LibCellPair1 ) + ( and + ( equal + ( car LibCellPair0 ) + ( car LibCellPair1 ) ) + ( equal + ( cadr LibCellPair0 ) + ( cadr LibCellPair1 ) ) ) ) + nil ) ) + +(defun HierarchyPrintCells ( RootCellView LibCellExpressionPairsToIgnore ) + (let ( + ( OrderedViews + ( HierarchyGetCellDescendants + RootCellView + LibCellExpressionPairsToIgnore + (lambda + ( CellView ) + nil ) + nil ) ) ) + (let ( + ( ViewNames ( ListApplyFuncToListAndAccumulateResults + OrderedViews + (lambda + ( CellView ) + ( getq CellView cellName ) ) + nil ) ) ) + ( foreach + Name + ViewNames + ( printf "%s\n" Name ) ) ) ) + nil ) + + + +(defun HierarchyGICMakeStackFrame ( CellView InstanceCount ) + (let ( + ( InstanceCountsTable ( HierarchyCountInstancesInCell + CellView ) ) ) + ( list + CellView + InstanceCount + ( ListApplyFuncToListAndAccumulateNonNilResults + ( tableToList InstanceCountsTable ) + (lambda + ( Entry ) + (let ( + ( LibCellViewTripple ( car Entry ) ) + ( InstanceCount ( cadr Entry ) ) ) + (let ( + ( LibName ( car LibCellViewTripple ) ) + ( CellName ( cadr LibCellViewTripple ) ) + ( ViewName ( caddr LibCellViewTripple ) ) ) + (let ( + ( CellViewDDObj ( ddGetObj LibName CellName ViewName ) ) ) + (when ( and + CellViewDDObj + ( getq CellViewDDObj files ) ) + ( list + InstanceCount + ( dbOpenCellViewByType + LibName + CellName + ViewName + nil + "r" ) ) ) ) ) ) ) + nil ) + InstanceCountsTable ) ) ) + +(defun HierarchyGICGetCellViewFromStackFrame ( StackFrame ) + ( car StackFrame ) ) + +(defun HierarchyGICGetInstanceCountFromStackFrame ( StackFrame ) + ( cadr StackFrame ) ) + +(defun HierarchyGICGetCellViewsToRecurseOnFromStackFrame ( StackFrame ) + ( caddr StackFrame ) ) + +(defun HierarchyGICGetInstanceCountsTableFromStrackFrame ( StackFrame ) + ( cadddr StackFrame ) ) + + +(defun HierarchyGICMergeTwoFrames ( TopFrame NextFrame ) + (let ( + ( TopInstanceCountsTable + ( HierarchyGICGetInstanceCountsTableFromStrackFrame + TopFrame ) ) + ( TopInstanceCount + ( HierarchyGICGetInstanceCountFromStackFrame + TopFrame ) ) + ( NextCellView + ( HierarchyGICGetCellViewFromStackFrame + NextFrame ) ) + ( NextInstanceCount + ( HierarchyGICGetInstanceCountFromStackFrame + NextFrame ) ) + ( NextCellViewsToRecurseOn + ( HierarchyGICGetCellViewsToRecurseOnFromStackFrame + NextFrame ) ) + ( NextInstanceCountsTable + ( HierarchyGICGetInstanceCountsTableFromStrackFrame + NextFrame ) ) ) + (let ( + ( MergedInstanceCounts + ( HierarchyGICMergeInstanceCountsTables + NextInstanceCountsTable + TopInstanceCountsTable + TopInstanceCount ) ) ) + ( list + NextCellView + NextInstanceCount + NextCellViewsToRecurseOn + MergedInstanceCounts ) ) ) ) + + + +(defun HierarchyGICMergeInstanceCountsTables ( TargetTable SrcTable Mult ) + ( foreach + SrcEntry + ( tableToList SrcTable ) + (let ( + ( LibCellViewTripple ( car SrcEntry ) ) + ( SrcCount ( times ( cadr SrcEntry ) Mult ) ) ) + (let ( + ( CurrCount ( arrayref TargetTable LibCellViewTripple ) ) ) + ( setarray + TargetTable + LibCellViewTripple + (if CurrCount + ( plus CurrCount SrcCount ) + SrcCount ) ) ) ) ) + TargetTable ) + + ;Merges Stack Frames until the top of the stack has + ;some cells to recurse on. +(defun HierarchyGICMergeStackFrames ( Stack ) + (let ( + ( MyStack Stack ) ) + (while ( and + ( cadr MyStack ) + ( null + ( HierarchyGICGetCellViewsToRecurseOnFromStackFrame + ( car MyStack ) ) ) ) + (let ( + ( TopFrame ( car MyStack ) ) + ( NextFrame ( cadr MyStack ) ) + ( RestOfStack ( cddr MyStack ) ) ) + (let ( + ( NewTopFrame ( HierarchyGICMergeTwoFrames + TopFrame + NextFrame ) ) ) + ( setq MyStack ( cons NewTopFrame RestOfStack ) ) ) ) ) + MyStack ) ) + + ;Returns ( list NextCellView Stack ) +(defun HierarchyGICGetNextCellViewToRecurseOnFromStack ( Stack ) + (let ( + ( MyStack ( HierarchyGICMergeStackFrames + Stack ) ) ) + (let ( + ( TopFrame ( car MyStack ) ) + ( RestOfMyStack ( cdr MyStack ) ) ) + (let ( + ( CurrNextCellView + ( car + ( HierarchyGICGetCellViewsToRecurseOnFromStackFrame + TopFrame ) ) ) ) + (if CurrNextCellView + (let ( + ( TopCellView + ( HierarchyGICGetCellViewFromStackFrame + TopFrame ) ) + ( TopInstanceCount + ( HierarchyGICGetInstanceCountFromStackFrame + TopFrame ) ) + ( TopCellViewsToRecurseOn + ( HierarchyGICGetCellViewsToRecurseOnFromStackFrame + TopFrame ) ) + ( TopInstanceCountsTable + ( HierarchyGICGetInstanceCountsTableFromStrackFrame + TopFrame ) ) ) + ( list + CurrNextCellView + ( cons + ( list + TopCellView + TopInstanceCount + ( cdr TopCellViewsToRecurseOn ) + TopInstanceCountsTable ) + RestOfMyStack ) ) ) + ( list + nil + MyStack ) ) ) ) ) ) + +(defun HierarchyCountInstancesInCell ( CellView ) + (let ( + ( CountTable ( makeTable "InstanceCountsTable" nil ) ) ) + ( foreach + Instance + ( getq CellView instances ) + (let ( + ( MasterLibName ( getq Instance libName ) ) + ( MasterCellName ( getq Instance cellName ) ) + ( MasterViewName ( getq Instance viewName ) ) ) + (let ( + ( CurrCount ( arrayref + CountTable + ( list MasterLibName MasterCellName MasterViewName ) ) ) ) + ( setarray + CountTable + ( list + MasterLibName + MasterCellName + MasterViewName ) + (if CurrCount + ( plus CurrCount 1 ) + 1 ) ) ) ) ) + CountTable ) ) + +(defun HierarchyGetInstanceCounts ( RootCellView ) + (let ( + ( Stack ( list + ( HierarchyGICMakeStackFrame + RootCellView + 1 ) ) ) ) + (while ( or + ( cadr Stack ) + ( HierarchyGICGetCellViewsToRecurseOnFromStackFrame + ( car Stack ) ) ) + (let ( + ( NextCellViewResult ( HierarchyGICGetNextCellViewToRecurseOnFromStack + Stack ) ) ) + (let ( + ( NextCellViewAndCount ( car NextCellViewResult ) ) ) + (if NextCellViewAndCount + (let ( + ( InstanceCount ( car NextCellViewAndCount ) ) + ( NextCellView ( cadr NextCellViewAndCount ) ) ) + ( setq + Stack + ( cons + ( HierarchyGICMakeStackFrame + NextCellView + InstanceCount ) + ( cadr NextCellViewResult ) ) ) ) + ( setq + Stack + ( cadr NextCellViewResult ) ) ) ) ) ) + (let ( + ( ResultTable ( HierarchyGICGetInstanceCountsTableFromStrackFrame + ( car Stack ) ) ) ) + ( setarray + ResultTable + ( list + ( getq RootCellView libName ) + ( getq RootCellView cellName ) + ( getq RootCellView viewName ) ) + 1 ) + ResultTable ) ) ) + + +(defun HierarchyMakeCellsInstantiatorsTable ( HierarchyViewName + ViewName + LibCellRegExsToIgnore + ) + (let ( + ( CellsInstantiatorTable ( makeTable "foo" nil ) ) + ( LibCellPairs + ( car + ( NameFilterObjects + ( ListNonDestructiveMapCan + (lambda ( Lib ) + ( mapcar + (lambda ( Cell ) + ( list Lib->name Cell->name ) + ) + ( getq Lib cells ) ) ) + ( ddGetLibList ) ) + LibCellRegExsToIgnore + `car + `cadr ) ) ) ) + + ( foreach + LibCellPair + LibCellPairs + (let ( + ( LibName ( car LibCellPair ) ) + ( CellName ( cadr LibCellPair ) ) ) + (let ( + ( HierarchyViewDDObj + ( ddGetObj + LibName + CellName + HierarchyViewName ) ) + ( ViewDDObj + ( ddGetObj + LibName + CellName + ViewName ) ) ) + (when ( and + HierarchyViewDDObj + ViewDDObj + ( getq HierarchyViewDDObj files ) + ( getq ViewDDObj files ) + ) + (let ( + ( CellView + ( dbOpenCellViewByType + LibName + CellName + HierarchyViewName + nil + "r" ) ) ) + (when CellView + (let ( + ( Instances ( getq CellView instances ) ) ) + ( foreach + Instance + Instances + (let ( + ( MasterCellName ( getq Instance cellName ) ) ) + (let ( + ( ExistingEntry ( arrayref + CellsInstantiatorTable + MasterCellName ) ) ) + (let ( + ( TableForCell + (if ExistingEntry + ExistingEntry + (let ( + ( NewTableForCell + ( makeTable + "CellInstantiators" + nil ) ) ) + ( setarray + CellsInstantiatorTable + MasterCellName + NewTableForCell ) + NewTableForCell ) ) ) ) + ( setarray + TableForCell + ( getq CellView cellName ) + ( cons + ( getq Instance name ) + ( arrayref TableForCell ( getq CellView cellName ) ) + ) + ) ) ) ) ) ) ) ) ) ) ) ) + + CellsInstantiatorTable ) ) + +(defun HierarchyGetTopLevelCellNames ( CellsInstantiatorsTable FloorplanViewName ) + (let ( + ( Ret nil ) ) + ( foreach + Lib + ( ddGetLibList ) + ( foreach + Cell + ( getq Lib cells ) + (let ( + ( FloorplanViewDDObj ( ddGetObj + ( getq Lib name ) + ( getq Cell name ) + FloorplanViewName ) ) ) + (when ( and + FloorplanViewDDObj + ( getq FloorplanViewDDObj files ) ) + (unless ( arrayref CellsInstantiatorsTable ( getq Cell name ) ) + ( setq Ret ( cons ( getq Cell name ) Ret ) ) ) ) ) ) ) + Ret ) ) + +(defun HierarchyGetInstantiatorsOfCell ( CellsInstantiatorsTable CellName ) + (let ( + ( CellInstantiatorsTable ( arrayref CellsInstantiatorsTable CellName ) ) ) + (when CellInstantiatorsTable + ( ListApplyFuncToListAndAccumulateResults + ( tableToList CellInstantiatorsTable ) + (lambda ( Entry ) + ( car Entry ) ) + nil ) ) ) ) + +(defun HierarchyGetTopLevelCellsThatContainCell ( CellsInstantiatorsTable + CellName + GoAboveThisCellPredicate + ) + ( ListUnionNoTableElements + nil + ( mapcar + `car + ( HierarchyGetInstancePathChoicesThatContainCell + CellsInstantiatorsTable + CellName + GoAboveThisCellPredicate ) ) ) ) + +(defun HierarchyGetInstancePathChoicesThatContainCell ( CellsInstantiatorsTable + CellName + GoAboveThisCellPredicate + ) + (let ( + ( CellNameInstanceNameChoices nil ) + ) + ;initialize queue + (let ( + ( CellNameInstanceNameChoicesQueue + (let ( + ( InstantiatorTable + ( arrayref + CellsInstantiatorsTable + CellName ) ) ) + (if InstantiatorTable + ( lconc + nil + ( mapcar + (lambda ( CellNameInstancesPair ) + ( list ( car CellNameInstancesPair ) + ( cdr CellNameInstancesPair ) ) ) + ( tableToList InstantiatorTable ) + ) ) + nil ) ) ) ) + (while ( car CellNameInstanceNameChoicesQueue ) + + (let ( + ( CurrCellNameInstanceNameChoices + ( car ( car CellNameInstanceNameChoicesQueue ) ) ) ) + ;dequeue + ( setq + CellNameInstanceNameChoicesQueue + ( lconc nil ( cdr ( car CellNameInstanceNameChoicesQueue ) ) ) ) + + (let ( + ( CurrCell + ( car CurrCellNameInstanceNameChoices ) ) + ( CurrInstanceCellNameInstanceNameChoices + ( cadr CurrCellNameInstanceNameChoices ) ) ) + (let ( + ( InstantiatorsOfCurrCell + ( arrayref + CellsInstantiatorsTable + CurrCell ) ) ) + (if ( and InstantiatorsOfCurrCell + ( apply GoAboveThisCellPredicate + ( list CellsInstantiatorsTable + CurrCell ) ) ) + ;enqueue with children added + ( foreach NextCellNameInstanceNameChoices + ( tableToList InstantiatorsOfCurrCell ) + (let ( + ( NextCell + ( car NextCellNameInstanceNameChoices ) ) + ( NextInstances + ( cadr NextCellNameInstanceNameChoices ) ) ) + + ( setq + CellNameInstanceNameChoicesQueue + ( tconc + CellNameInstanceNameChoicesQueue + ( list NextCell + ( cons NextInstances + CurrInstanceCellNameInstanceNameChoices ) ) ) + ) ) ) + ;add to unique, and don't enqueue + ( setq CellNameInstanceNameChoices + ( cons CurrCellNameInstanceNameChoices + CellNameInstanceNameChoices ) ) ) ) ) ) ) + CellNameInstanceNameChoices ) ) ) + +(defun HierarchyExpandPathChoices ( Choices ) + (let ( + ( CurrPaths + ( mapcar + (lambda ( Choice ) ( list Choice ) ) + ( car Choices ) ) ) + ( CurrChoices ( cdr Choices ) ) + ) + (while CurrChoices + (let ( + ( NewPaths nil ) ) + + ( setq NewPaths + ( ListNonDestructiveMapCan + (lambda ( Choice ) + ( mapcar + (lambda ( Path ) + ( append1 Path Choice ) ) + CurrPaths ) ) + ( car CurrChoices ) ) ) + ( setq CurrPaths NewPaths ) + ( setq CurrChoices ( cdr CurrChoices ) ) ) ) + CurrPaths ) ) + +(defun HierarchyPredicateSimplifier ( SimplePredicate + CellInstantiatorsTable + CellName + ViewName ) + ( ExpressionReplaceSymbolsWithValues + `(lambda ( CellInstantiatorsTable + CellName ) + ( apply + SimplePredicate + ( list CellInstantiatorsTable + ( dbOpenCellViewByType + ( car ( NameParseCellName CellName ) ) + CellName + ViewName + nil + "r" ) ) ) ) + ( list `ViewName `SimplePredicate ) + ) ) + + +; change an instance to a preferred view or list of views +(defun ChangeView (inst view @key (verbose t)) + (let (views to_cv) + views = (if (atom view) (list view) view) + (foreach v views + (unless to_cv + to_cv=(nrOpenCellViewReadable inst->libName inst->cellName v) + ) + ) + (cond (to_cv inst->master=to_cv) + (verbose (printf "Can't find subcell view for %s\n" inst->cellName)) + ) + ) + ) + +(defun ReplaceSubcells (cv from_view to_view @key (verbose t)) + (let (to from_master to_master) + (when (nrIsCellViewWritable cv) + (foreach inst cv->instances + (when inst->viewName==from_view && inst->libName!=TechLibName + (ChangeView inst to_view ?verbose verbose) + ) + ) + (dbSave cv) + ) + ) +) + +(defun RecursiveReplaceSubcells (from_view to_view @key (cv nil)) + (let (cellview uniqueInstances cell) + (if cv then + cellview=cv + else + cellview=(geGetEditCellView) + ) + + (when (nrIsCellViewWritable cellview) + cell = (nrOpenCellViewWritable cellview->libName cellview->cellName cellview->viewName) + (ReplaceSubcells cell from_view to_view) + ) + + uniqueInstances=nil + (foreach inst cellview->instances + (when !(member inst->cellName uniqueInstances->cellName) + && inst->libName!=TechLibName + && inst->libName!=GateLibName + && inst->libName!=StackLibName + uniqueInstances= (cons inst uniqueInstances ) + ) + ) + (foreach inst uniqueInstances + cell = (nrOpenCellViewReadable inst->libName inst->cellName inst->viewName) + (when cell + (RecursiveReplaceSubcells from_view to_view ?cv cell) + ) + ) + t + ) +) + +(defun shit (from to) +(RecursiveReplaceSubcells from to) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/inline.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/inline.il new file mode 100644 index 0000000000..75520d6d03 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/inline.il @@ -0,0 +1,363 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +;If we inline an instance a and it has a net b, first +; look for a connection from the CellView to a.b +; This will be the case if a.b is a port net +; If there is no connection (a.b is local in a) +; then create a new net a.b, and make sure it doesn't 'short' +; with an existing net. +(defun InlineMakeNewNet ( OldNet ParentNet CellView Instance ConnMap ) + (cond ( + ( arrayref + ConnMap + OldNet->name + ) ) + ( + (let ( + ( NewNetName + ( sprintf + nil + "%s%s%s" + ( getq Instance name ) + HieracrchyDeliminator + ( getq OldNet name ) ) ) ) + (when ( dbFindNetByName CellView NewNetName ) +; (error ( sprintf nil "Net %s already exists in parent cell" NewNetName ) ) ) + (println ( sprintf nil "Net %s already exists in parent cell" NewNetName ) ) ) + ( setarray + ConnMap + OldNet->name + ( dbMakeNet + CellView + NewNetName + ParentNet ) ) ) ) ) ) + +(defun InlineInstancesSimple ( CellView + Instances ) + ( InlineInstances + CellView + CellView + Instances + "netlist" + nil + nil + nil + ?Verbose nil + ?CopyPins t ) ) + +(defun InlineInstances ( ConnectivityCellView + CellView + Instances + ConnectivityViewName + UpdateConnectivityCellView + FoldableLibCellExpressionPairs + SuperStackLibCellPairRegExs + @key + ( Verbose t ) + ( CopyPins nil ) + ( CopyFigs t ) + ) + (let ( + ( ConnectivityInstanceMap ( NameMakeInstanceMapFromCellView + ConnectivityCellView + FoldableLibCellExpressionPairs ) ) + ( LayoutInstanceMap ( NameMakeInstanceMapFromCellView + CellView + FoldableLibCellExpressionPairs ) ) ) + (let ( + ( FilterRet ( NameFilterInstances + Instances + SuperStackLibCellPairRegExs ) ) ) + (let ( + ( SuperStacks ( cadr FilterRet ) ) + ( Others ( car FilterRet ) ) ) + ( append + ( mapcan + (lambda ( SuperStack ) + ( InlineSuperStack + ConnectivityCellView + CellView + ConnectivityInstanceMap + LayoutInstanceMap + SuperStack + ConnectivityViewName + UpdateConnectivityCellView + FoldableLibCellExpressionPairs + ?Verbose Verbose + ?CopyPins CopyPins + ?CopyFigs CopyFigs + ) ) + SuperStacks ) + ( mapcan + (lambda ( Instance ) + ( InlineInstance + ConnectivityCellView + CellView + ConnectivityInstanceMap + LayoutInstanceMap + Instance + ConnectivityViewName + UpdateConnectivityCellView + FoldableLibCellExpressionPairs + ?Verbose Verbose + ?CopyPins CopyPins + ?CopyFigs CopyFigs + ) ) + Others ) ) ) ) ) ) + + + +(defun InlineSuperStack ( ConnectivityCellView + CellView + ConnectivityInstanceMap + LayoutInstanceMap + SuperStack + ConnectivityViewName + UpdateConnectivityCellView + FoldableLibCellExpressionPairs + @key + ( Verbose nil ) + ( CopyFigs t ) + ( CopyPins nil ) ) + (let ( + ( ChainNameList + ( SuperStackGetComponentNameListFromSuperStackName + ( PropGetPropValueForPropName + ( getq SuperStack prop ) + "name" + ) ) ) ) + (let ( + ( NewFigs ( InlineInstance + ConnectivityCellView + CellView + ConnectivityInstanceMap + LayoutInstanceMap + SuperStack + ConnectivityViewName + UpdateConnectivityCellView + FoldableLibCellExpressionPairs + ?Verbose Verbose + ?CopyFigs CopyFigs + ?CopyPins CopyPins ) ) ) + ;reset chain names to what superstack name implies + ( foreach + Chain + ( setof + Fig + NewFigs + ( equal ( getq Fig objType ) "inst" ) ) + (let ( + ( ChainName + ( car ( last ( parseString ( getq Chain name ) "." ) ) ) ) ) + ( dbSetq + Chain + ( nth + ( SuperStackGetComponentIndexFromComponentName + ChainName ) + ChainNameList ) + name + ) ) ) ) ) ) + +(defun InlineInstance ( + ConnectivityCellView + CellView + ConnectivityInstanceMap + LayoutInstanceMap + Instance + ConnectivityViewName + UpdateConnectivityCellView + FoldableLibCellExpressionPairs + @key + ( Verbose nil ) + ( CopyPins nil ) + ( CopyFigs t ) + ) + ;recreate and reeconnect sub Instances + + (let ( + ( NewFigs nil ) + ( NetTable ( makeTable `bla nil ) ) + ( InstanceLayoutCellView ( getq Instance master ) ) + ( InstanceConnectivityCellView + (if ( ddGetObj ( getq ( getq Instance master ) libName ) + ( getq ( getq Instance master ) cellName ) + ConnectivityViewName ) + ( dbOpenCellViewByType + ( getq ( getq Instance master ) libName ) + ( getq ( getq Instance master ) cellName ) + ConnectivityViewName + nil + "r" ) + ( getq Instance master ) ) ) ) + (let ( + ( ConnMap ( makeTable `conn nil ) ) + ( LayoutInstanceInstanceMap ( NameMakeInstanceMapFromCellView + InstanceLayoutCellView + FoldableLibCellExpressionPairs ) ) + ( ConnectivityInstanceInstanceMap ( NameMakeInstanceMapFromCellView + InstanceConnectivityCellView + FoldableLibCellExpressionPairs ) ) ) + + ( foreach InstTerm ( getq Instance conns ) + ( setarray ConnMap InstTerm->term->net->name InstTerm->net ) ) + + ( foreach + ConnectivityCanonicalInstanceName + ( NameGetCanonicalInstanceNames + ConnectivityInstanceInstanceMap ) + (if Verbose + ( printf "Connectivity Instance: %s\n" + ConnectivityCanonicalInstanceName ) ) + (let ( + ( ConnectivitySubInstance + ( car + ( NameGetInstancesForCanonicalName + ConnectivityInstanceInstanceMap + ConnectivityCanonicalInstanceName ) ) ) + ( LayoutSubInstances + ( NameGetInstancesForCanonicalName + LayoutInstanceInstanceMap + ConnectivityCanonicalInstanceName ) ) ) + (if Verbose + ( printf "Layout Instances: %L\n" LayoutSubInstances~>name ) ) + ( foreach LayoutSubInstance LayoutSubInstances + (if ( equal ( getq LayoutSubInstance objType ) "inst" ) + (let ( + ( NewInstance + ( InlineAddFigure + LayoutSubInstance + CellView + Instance + ConnMap + CopyPins ) ) + ) + ( setq NewFigs ( cons NewInstance NewFigs ) ) + ;get connectivity + ( foreach InstTerm ( getq ConnectivitySubInstance conns ) + (let ( + ( NewNet + ( InlineMakeNewNet + InstTerm->net + nil + CellView + Instance + ConnMap ) ) ) + ;make sure there is in fact a terminal + (cond ( + ( getq InstTerm term ) + (if Verbose + ( printf "make connection %s.%s = %s\n" + NewInstance->name + InstTerm->name + NewNet->name ) ) + ( dbCreateConnByName + NewNet + NewInstance + ( getq InstTerm name ) ) ) + ( + (if Verbose + ( printf "Cant make connection %s.%s = %s\n" + NewInstance->name + InstTerm->name + NewNet->name ) ) ) ) ) ) ) ) ) ) ) + + (if CopyFigs then + ;add shapes + ( foreach Shape ( getq ( getq Instance master ) shapes ) + ( setq NewFigs + ( cons + ( InlineAddFigure Shape CellView Instance ConnMap CopyPins ) + NewFigs ) ) ) + + ;add mosaics + ( foreach Mosaic ( getq ( getq Instance master ) mosaics ) + ( setq NewFigs + ( cons + ( InlineAddFigure Mosaic CellView Instance ConnMap CopyPins ) + NewFigs ) ) ) + ) + (cond ( + ( and UpdateConnectivityCellView + ( not ( equal ConnectivityCellView CellView ) ) ) + (if Verbose + ( printf "Updating Netlist view...\n" ) ) + (let ( + ( ConnectivityCellViewInstance + ( NameGetInstancesForCanonicalName + LayoutInstanceMap + ( NameGetCanonicalInstanceNameForInstance + ConnectivityInstanceMap + ConnectivitySubInstance ) ) ) ) + ( InlineInstance + ConnectivityCellView + ConnectivityCellView + ConnectivityInstanceMap + ConnectivityInstanceMap + ConnectivityCellViewInstance + ConnectivityViewName + UpdateConnectivityCellView + FoldableLibCellExpressionPairs + ?CopyPins CopyPins + ?Verbose Verbose + ?CopyFigs CopyFigs + ) ) ) ) + + (if Instance + ( dbDeleteObject Instance ) ) + + NewFigs ) ) ) + + +(defun InlineMergeNet ( SinkNet SourceNet ) + ( foreach InstTerm ( getq SourceNet allInstTerms ) + ( dbCreateConn SinkNet ( getq InstTerm inst ) ( getq InstTerm term ) ) + ) + ( dbDeleteObject SourceNet ) +) + + +(defun InlineAddFigure ( Figure CellView Instance ConnMap CopyPins ) + (cond ( + ;dont copy if it has a parent - parent will do so + ( and + ( or CopyPins ( not ( getq Figure pin ) ) ) + ( not ( getq Figure parent ) ) ) + (let ( + ( NewFig ( InlineCopyFig Figure CellView Instance ) ) ) + (cond ( + ( getq Figure net ) + (let ( + ( NewNet + ( InlineMakeNewNet + ( getq Figure net ) + nil + CellView + Instance + ConnMap ) ) ) + ( cond ( NewNet + ( dbAddFigToNet NewFig NewNet ) ) ) ) ) ) + NewFig ) ) ) ) + +(defun InlineCopyFig ( Figure CellView Instance ) + (let ( + ( NewFig ( dbCopyFig + Figure + CellView + ( getq Instance transform ) ) ) ) + (cond ( + ;if the figure had a name, give new fig a name + ( getq Figure name ) + ( dbSetq + NewFig + ( sprintf + nil + "%s%s%s" + ( getq Instance name ) + HieracrchyDeliminator + ( getq Figure name ) ) + name ) ) ) + NewFig ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instance.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instance.il new file mode 100644 index 0000000000..9f9ff98f3d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instance.il @@ -0,0 +1,88 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun InstanceAlignInstance ( Instance AlignmentUnitInUserUnits ) + (let ( + ( ObjectToAlign + (if ( equal ( getq Instance objType ) "mosaicInst" ) + ( getq Instance mosaic ) + Instance ) ) ) + (when ObjectToAlign + (let ( + ( CurrPos ( getq ObjectToAlign xy ) ) ) + (let ( + ( CurrX ( car CurrPos ) ) + ( CurrY ( cadr CurrPos ) ) ) + (let ( + ( NewX ( times + ( float AlignmentUnitInUserUnits ) + ( round + ( quotient + CurrX + ( float AlignmentUnitInUserUnits ) ) ) ) ) + ( NewY ( times + ( float AlignmentUnitInUserUnits ) + ( round + ( quotient + CurrY + ( float AlignmentUnitInUserUnits ) ) ) ) ) ) + ( dbSetq ObjectToAlign ( list NewX NewY ) xy ) ) ) ) ) ) ) + + + +(defun ReportInstances () + (let (cv all_cells unique_cells count filename file + lcv fcv layout_area floorplan_area ratio total cmd) + cv=(geGetWindowCellView) + filename=(sprintf nil "%s.instances" cv->cellName) + file=(outfile filename) + + all_cells=cv->instances + (foreach inst all_cells + (when !(IsInList inst->cellName unique_cells) + unique_cells=(cons inst->cellName unique_cells) + ) + ) + + (foreach inst unique_cells + count=0 + (foreach inst2 all_cells + (when inst==inst2->cellName + count=count+1 + ) + ) + lcv=(nrOpenCellViewReadableByName inst "layout") + fcv=(nrOpenCellViewReadableByName inst "floorplan") + layout_area=nil + floorplan_area=nil + (when lcv + layout_area=(GetCellArea lcv) + ) + (when fcv + floorplan_area=(GetCellArea fcv) + ) + (when layout_area && floorplan_area + ratio=layout_area/floorplan_area + total=layout_area*count + (fprintf file "%s\t%d\t%2.2f\t%4.2f\n" inst count ratio total) + (printf "%s\t%d\t%2.2f\t%4.2f\n" inst count ratio total) + ) + (when !layout_area && floorplan_area + total=floorplan_area*count + (fprintf file "%s\t%d\t%s\t%4.2f\n" inst count "NA" total) + (printf "%s\t%d\t%s\t%4.2f\n" inst count "NA" total) + ) + ) + (close file) + cmd=(sprintf nil "sort -k2n,2 %s > %s.count" filename filename) + (shell cmd) + cmd=(sprintf nil "sort -k3n,3 %s > %s.ratio" filename filename) + (shell cmd) + cmd=(sprintf nil "sort -k4n,4 %s > %s.total" filename filename) + (shell cmd) + t + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instantiator.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instantiator.il new file mode 100644 index 0000000000..77e69fa313 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/hierarchy/instantiator.il @@ -0,0 +1,516 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +

    Purpose

    +

    This module is used to create instantiator views, which help in s of low level cells.

    +

    The problem is when high level cells route over lower level cells. In order to redo the lower level cell, we must either reroute the upper level cell or constrain the routing of the lower level cell by taking into account the wiring on top of it.

    + +

    Description

    +

    An instantiator view for cell X will have keepout ('boundary' layer) every where a higher level cell draws shapes over X that don't connect to X, and 'drawing' layer everywhere a higher level cell connects to a shape in X (or a subcell of X).

    +

    They keep the pins from the source cell, and can be instantiated in the cell you want to route provided the conductor-depth>=1. The /Fulcrum/route menu has an option to instantiate the instantiator view.

    + +

    Other References

    +
      +
    • See the for the SKILL that does the layer post processing. +
    • Used only by . +
    +*/ + + + +(defun InstantiatorsCreateInstantiatorsView ( CellView + TargetCellView + EmptyCellView + InstantiatorsTable + ViewName + HierarchyViewName + ConductorPurpose + BoundaryLPP + LPPs + PinNetNamesToIgnoreLPP + UseExistingInstantiatorViews + OutPort + LibCellsToIgnore + MaxDepth + ) + "Looks through the InstantiatorsTable for cells that instantiate CellView, and copies shapes in these cells that overlap the bounding box of instances of CellView. \ + Shapes turn into these layers: \ + subcell shapes and signal pins become 'drawing' purpose (metal)\ + all other shaopes in the cell become 'dummy' purpose (conductor)\ + metal in instantiators become 'boundary' purpose (keepout)" + (let ( + ( BoundaryShape nil ) + ( NoWriteMode t ) + ( PruneCacheTable ( makeTable `foo nil ) ) + ( CellName ( getq CellView cellName ) ) + ) + (let ( + ( ViewNameCellNameInstanceNamePathChoicesList nil ) + ( CellNameInstanceNamePathChoicesList + ( HierarchyGetInstancePathChoicesThatContainCell + InstantiatorsTable + CellName + ( HierarchyPredicateSimplifier + (lambda ( CellInstantiatorsTable + CellView ) + ;go above this cell provided... + ( not + ( and UseExistingInstantiatorViews + ( ddGetObj + ( getq CellView libName ) + ( getq CellView cellName ) + "instantiator" ) ) ) ) + InstantiatorsTable + CellName + ViewName ) + ) ) + ( PrunePredicate + ( InstantiatorDefaultPrunePredicate + PruneCacheTable + LPPs ) ) + ) + + (when ( equal ( getq CellView mode ) "r" ) + ( setq NoWriteMode t ) + ) + + ;copy everything over + ( dbCopyCellView + CellView + ( getq TargetCellView libName ) + ( getq TargetCellView cellName ) + ( getq TargetCellView viewName ) + nil nil t ) + + (unless NoWriteMode + ( printf "Warning: deleting stuff in %s %s %s\n" + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) + ;clear the original + ( dbCopyCellView + EmptyCellView + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) + nil nil t ) + ) + + ;save the original - we'll restore it later + ( dbCopyCellView + TargetCellView + ( getq EmptyCellView libName ) + ( getq EmptyCellView cellName ) + ( getq EmptyCellView viewName ) + nil nil t ) + + ( setq + BoundaryShape + ( PinUtilFindPRBoundShape + BoundaryLPP + TargetCellView ) ) + + + ;we need to keep the boundary shape in the original cell + ; so we know how big it is + (unless NoWriteMode + ( dbCopyFig + BoundaryShape + CellView ) + ) + + ( foreach + Shape + ( getq TargetCellView shapes ) + (cond ( + ( exists LPP LPPs + ( equal + ( car ( getq Shape lpp ) ) + ( car LPP ) ) ) + (when ( and + ( equal + ( cadr ( getq Shape lpp ) ) + "drawing" ) + ;convert non signal-pin shapes to conductor(dummy) purpose + ( or + ( not ( getq Shape pin ) ) + ( exists + NetName + PinNetNamesToIgnoreLPP + ( equal + Shape->pin->net->name + NetName ) ) ) + ) + ( dbSetq + Shape + ( list ( car ( getq Shape lpp ) ) + ConductorPurpose ) + lpp ) ) + + ) + ( + ( equal ( getq Shape lpp ) BoundaryLPP ) ) + ( + t + ( dbDeleteObject Shape ) + ) ) ) + + (unless BoundaryShape + (error "No boundary shape" ) ) + + + ;add instantiator views + ( foreach + CellNameInstanceNamePathChoices + CellNameInstanceNamePathChoicesList + + (let ( + ( CellName + ( car CellNameInstanceNamePathChoices ) ) ) + ( setq + ViewNameCellNameInstanceNamePathChoicesList + ( cons + ( cons ViewName CellNameInstanceNamePathChoices ) + ViewNameCellNameInstanceNamePathChoicesList ) ) + + (when ( and + UseExistingInstantiatorViews + ( ddGetObj + ( car ( NameParseCellName + CellName ) ) + CellName + "instantiator" ) ) + ( setq + ViewNameCellNameInstanceNamePathChoicesList + ( cons + ( cons "instantiator" CellNameInstanceNamePathChoices ) + ViewNameCellNameInstanceNamePathChoicesList ) ) ) ) + ) + + ;get prunings + ( setq + ViewNameCellNameInstanceNamePathChoicesList + ( mapcar + (lambda ( ViewNameCellNameInstanceNamePathChoices ) + ( InstantiatorGetPrunings + ViewNameCellNameInstanceNamePathChoices + HierarchyViewName + PrunePredicate ) ) + ViewNameCellNameInstanceNamePathChoicesList ) ) + + ( println + ViewNameCellNameInstanceNamePathChoicesList ) + + + ;copy the overlaps + ( foreach + ViewNameCellNameInstanceNamePathChoices + ViewNameCellNameInstanceNamePathChoicesList + (let ( + ( ViewNameToSearch + ( car ViewNameCellNameInstanceNamePathChoices ) ) + ( CellName + ( cadr ViewNameCellNameInstanceNamePathChoices ) ) + ( InstanceNamePathChoices + ( caddr ViewNameCellNameInstanceNamePathChoices ) ) ) + (let ( + ( TopLevelLayoutCellView + ( dbOpenCellViewByType + ( car ( NameParseCellName + CellName ) ) + CellName + ViewName + nil + "r" ) ) + ( TopLevelCellViewToSearch + ( dbOpenCellViewByType + ( car ( NameParseCellName + CellName ) ) + CellName + ViewNameToSearch + nil + "r" ) ) + ) + + ( println ( list CellName ViewNameToSearch ) ) + + ( foreach + InstanceNamePath + ( HierarchyExpandPathChoices + InstanceNamePathChoices ) + + ( printf "instances: %L\n" InstanceNamePath ) + + (let ( + ( InstancePath + ( TransformGetInstancePathFromInstanceNamePath + TopLevelCellViewToSearch + InstanceNamePath ) ) + ) + (let ( + ( TargetCellToTopLevelTransform + ( TransformGetTransformFromInstancePath + InstancePath ) ) + ) + (let ( + ( InstanceBBoxAtTopLevel + ( dbTransformBBox + ( getq CellView bBox ) + TargetCellToTopLevelTransform ) ) + ( TopLevelToTargetCellTransform + ( TransformGetInverseTransform + TargetCellToTopLevelTransform ) ) ) + (let ( + ;if layout search for drawing + ;if not layout search for keepout + ( LPPsToSearch + (cond ( + ( equal ViewName ViewNameToSearch ) + LPPs ) + ( + ( mapcar + (lambda ( LPP ) + ( list ( car LPP ) "boundary" ) ) + LPPs ) ) ) ) + ;expand search area + ( RectToSearch + ( RectExpandRight + InstanceBBoxAtTopLevel + 10 + ) ) + ;look until we get to gates,stacks + ( DepthRange + ( list + 0 + ( min + ( max ( length InstanceNamePath ) + MaxDepth ) + ( HierarchyGetMaxDepth + TopLevelCellViewToSearch + ?LibCellsToIgnore LibCellsToIgnore + ?DescendIntoInstancePredicate + (lambda ( Instance CurrTransform ) + (when ( RectDoRectsOverlap + InstanceBBoxAtTopLevel + ( dbTransformBBox + ( getq Instance bBox ) + CurrTransform ) ) t ) ) + ) ) ) ) + ) + (let ( + ( Overlaps + ( ListNonDestructiveMapCan + (lambda ( LPP ) + ( dbProduceOverlap + TopLevelCellViewToSearch + RectToSearch + DepthRange + LPP + ) ) + LPPsToSearch + ) ) ) + + + ( println ( list InstanceBBoxAtTopLevel + TopLevelToTargetCellTransform ) ) + + ( println "Finding overlaps..." ) + ( foreach + Overlap + Overlaps + (let ( + ( FigStack + ( reverse + ( TransformCanonicalizeInstancePath Overlap ) ) ) ) + ;If we couldn't clear out the cell for which we're + ;making the instantiator view, then make sure we don't copy + ;figs that are in that cell + (unless ( and + NoWriteMode + ( exists + Component + FigStack + ( equal + ( getq Component cellName ) + ( getq CellView cellName ) ) ) ) + (let ( + ( FigInSomeCell ( car FigStack ) ) + ) + (when ( and + ( or + ( equal ( getq FigInSomeCell objType ) "rect" ) + ( equal ( getq FigInSomeCell objType ) "polygon" ) + ( equal ( getq FigInSomeCell objType ) "path" ) ) + t ) + (let ( + ( SomeCellToTopLevelTransform + ( TransformGetTransformFromInstanceStack + ( cdr FigStack ) ) ) ) + + (let ( + ( FigInTargetCell + ( dbCopyFig + FigInSomeCell + TargetCellView + ( dbConcatTransform + SomeCellToTopLevelTransform + TopLevelToTargetCellTransform ) ) ) ) + ;change to keepout + ( dbSetq + FigInTargetCell + ( list ( car ( getq FigInTargetCell lpp ) ) + "boundary" ) + lpp ) + ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) + + ;restore the original + (unless NoWriteMode + ( dbCopyCellView + EmptyCellView + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) + nil nil t ) + ) + + ( foreach + Key + PruneCacheTable + (when ( equal ( arrayref PruneCacheTable Key ) 2 ) + ( fprintf + OutPort + "WARNING...seriously: %L was not examined for cell %s because it's names don't m!\n" + Key + ( getq CellView cellName ) + ) ) ) + ) ) ) + + +(defun InstantiatorDefaultPrunePredicate ( PrunePredicateCache + LPPs ) + ( ExpressionReplaceSymbolsWithValues + `(lambda ( ViewNameCellNameInstanceNamePathChoices ) + (let ( + ( ViewName + ( car ViewNameCellNameInstanceNamePathChoices ) ) + ( CellName + ( cadr ViewNameCellNameInstanceNamePathChoices ) ) + ( InstanceNamePathChoices + ( caddr ViewNameCellNameInstanceNamePathChoices ) ) + ( PruneMeCached + ( arrayref + PrunePredicateCache + ViewNameCellNameInstanceNamePathChoices + ) ) ) + (cond ( + ( numberp PruneMeCached ) + ( not ( equal 0 PruneMeCached ) ) + ) + ( + (let ( + ( CellView + ( dbOpenCellViewByType + ( car ( NameParseCellName + CellName ) ) + CellName + ViewName + nil + "r" ) ) ) + (let ( + ( AffectsCell + ( exists + LPP + LPPs + ( PinUtilGetAllShapesOnLPP + CellView + LPP ) ) ) + ( LayoutMatchesHierarchy + ( forall + InstanceNamePath + ( HierarchyExpandPathChoices + InstanceNamePathChoices ) + ( TransformIsValidInstanceNamePath + CellView + InstanceNamePath ) ) ) + ) + (let ( + ( PruneMe (if AffectsCell + (if LayoutMatchesHierarchy 0 1 ) 2 ) ) ) + + ( setarray + PrunePredicateCache + ViewNameCellNameInstanceNamePathChoices + PruneMe ) + + ( println + ( list CellName AffectsCell LayoutMatchesHierarchy ( equal 1 PruneMe ) ) ) + + ( not ( equal 0 PruneMe ) ) + ) ) ) ) ) ) ) + ( list `PrunePredicateCache + ) ) + ) + +(defun InstantiatorGetPrunings ( ViewNameCellNameInstanceNamePathChoices + HierarchyViewName + PrunePredicate ) + (let ( + ( ViewNameToSearch + ( car ViewNameCellNameInstanceNamePathChoices ) ) + ( CellName + ( cadr ViewNameCellNameInstanceNamePathChoices ) ) + ( InstanceNamePathChoices + ( caddr ViewNameCellNameInstanceNamePathChoices ) ) + ) + (let ( + ( TopLevelCellView + ( dbOpenCellViewByType + ( car ( NameParseCellName + CellName ) ) + CellName + ViewNameToSearch + nil + "r" ) ) ) + (cond ( + ( apply PrunePredicate ( list ViewNameCellNameInstanceNamePathChoices ) ) + ( InstantiatorGetPrunings + ( InstantiatorGetSubViewNameCellNameInstanceNamePathChoices + ViewNameCellNameInstanceNamePathChoices + HierarchyViewName + ) + HierarchyViewName + PrunePredicate ) ) + ( + t + ViewNameCellNameInstanceNamePathChoices ) ) ) ) ) + +(defun InstantiatorGetSubViewNameCellNameInstanceNamePathChoices + ( InstanceNamePathChoices + HierarchyViewName ) + (let ( + ( ViewName + ( car ViewNameCellNameInstanceNamePathChoices ) ) + ( CellName + ( cadr ViewNameCellNameInstanceNamePathChoices ) ) + ( InstanceNamePathChoices + ( caddr ViewNameCellNameInstanceNamePathChoices ) ) + ) + (let ( + ( CellView + ( dbOpenCellViewByType + ( car ( NameParseCellName + CellName ) ) + CellName + HierarchyViewName + nil + "r" ) ) ) + (let ( + ( Instance + ( dbFindAnyInstByName + CellView + ( car ( car InstanceNamePathChoices ) ) ) ) ) + ( list ViewName ( getq Instance cellName ) ( cdr InstanceNamePathChoices ) ) + ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/fp.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/fp.il new file mode 100644 index 0000000000..c0d2561dc4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/fp.il @@ -0,0 +1,100 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +;FPable: ( orient, x, y ) -> instance name +;derived from .fp files from Place and Route flow ( Astro ) + +(defun FPRenameInstancesFromFPTable ( Instances + FPTable + RenameFunc ) + + ( rexCompile "^I[0-9]*$" ) + + ( foreach Instance + Instances + (let ( + ( Key + ( list + Instance->orient + ( atof + ( sprintf + nil + "%f" + ( MathRoundToNearest + ( car Instance->xy ) + .001 ) ) ) + ( atof + ( sprintf + nil + "%f" + ( MathRoundToNearest + ( cadr Instance->xy ) + .001 + ) ) ) + ) ) ) + (let ( + ( NewInstanceName + ( arrayref FPTable + Key + ) ) ) + + (when ( stringp NewInstanceName ) + ( dbSetq Instance + ( apply RenameFunc ( list NewInstanceName ) ) + name ) ) + +; ( println ( list Key NewInstanceName ) ) + + + (when ( rexExecute + Instance->name ) + (error + ( sprintf + nil + "Instance %s at %L has a bad name\n" + Instance->name + ( list Instance->xy Instance->orient ) + ) ) ) ) ) ) ) + +(defun FPRenameInstancesDefault ( CellView + FPTable + ) + + + (let ( + ( Instances + ( car + ( NameFilterInstances + ( getq CellView instances ) + ( list + ( list ".*" ".*via.*" ) + ( list ".*" ".*FILL.*" ) + ) ) ) ) ) + + ( FPRenameInstancesFromFPTable + Instances + FPTable + `FPDefaultRename ) ) ) + +(defun FPDefaultRename ( Name ) + (let ( + ( Result "i_" ) + ( FirstChar t ) + ) + ( for I 1 ( strlen Name ) + (let ( + ( CurrChar ( substring Name I 1 ) ) ) + (let ( + ( ConvertedChar (cond + ( ( equal "." CurrChar ) "_D_" ) + ( ( and ( equal "x" CurrChar ) + FirstChar ) + "" ) + ( t CurrChar ) ) ) ) + ( setq FirstChar nil ) + ( setq Result ( strcat Result ConvertedChar ) ) ) ) ) + Result + ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/import.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/import.il new file mode 100644 index 0000000000..c1dd51c65a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/import/import.il @@ -0,0 +1,215 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun ImportMungeCellInstances ( CellToMunge CellViewTable ) + (let ( + ( InstancesToMunge ( getq CellToMunge instances ) ) ) + ( foreach + InstanceToMunge + InstancesToMunge + (let ( + ( CurrentMasterLibName ( getq InstanceToMunge libName ) ) + ( CurrentMasterCellName ( getq InstanceToMunge cellName ) ) + ( CurrentMasterViewName ( getq InstanceToMunge viewName ) ) ) + (let ( + ( NewMasterCellView ( arrayref + CellViewTable + ( list + CurrentMasterLibName + CurrentMasterCellName + CurrentMasterViewName ) ) ) ) + (when NewMasterCellView + ( dbSetq InstanceToMunge NewMasterCellView master ) ) ) ) ) ) ) + + +(defun ImportBuildLibCellViewMappingTableFromCellNameMappingTable ( CellNameTable + SrcLibName + SrcViewName + TargetLibFunc + TargetLibFuncParams + TargetView ) + (let ( + ( Result ( makeTable "LibCellViewTable" nil ) ) ) + ( foreach + CellNameEntry + ( tableToList CellNameTable ) + (let ( + ( OldCellName ( car CellNameEntry ) ) + ( NewCellName ( cadr CellNameEntry ) ) ) + (unless ( equal OldCellName NewCellName ) + (let ( + ( NewLibName ( apply + TargetLibFunc + ( cons + OldCellName + ( cons + NewCellName + TargetLibFuncParams ) ) ) ) ) + (when NewLibName + ( setarray + Result + ( list + SrcLibName + OldCellName + SrcViewName ) + ( list + NewLibName + NewCellName + TargetView ) ) ) ) ) ) ) + Result ) ) + +(defun ImportBuildCellViewTableFromLibCellViewMappingTable ( LibCellViewMappingTable + TechnologyLibraryName + DFIIDir ) + (let ( + ( ErrorStr nil ) + ( Result ( makeTable "CellViewTable" nil ) ) ) + ( foreach + LibCellViewEntry + ( tableToList LibCellViewMappingTable ) + (unless ErrorStr + (let ( + ( OldLibCellViewTripple ( car LibCellViewEntry ) ) + ( NewLibCellViewTripple ( cadr LibCellViewEntry ) ) ) + (let ( + ( OldLibName ( car OldLibCellViewTripple ) ) + ( OldCellName ( cadr OldLibCellViewTripple ) ) + ( OldViewName ( caddr OldLibCellViewTripple ) ) + ( NewLibName ( car NewLibCellViewTripple ) ) + ( NewCellName ( cadr NewLibCellViewTripple ) ) + ( NewViewName ( caddr NewLibCellViewTripple ) ) ) + (let ( + ( OldCellViewDDObj ( ddGetObj OldLibName OldCellName OldViewName ) ) ) + (if ( and + OldCellViewDDObj + ( getq OldCellViewDDObj files ) ) + (let ( + ( OldCellView (let ( + ( MyCellView ( dbOpenCellViewByType + OldLibName + OldCellName + OldViewName + nil + "r" ) ) ) + (unless MyCellView + ( setq + ErrorStr + ( sprintf + nil + "Unable to open %L %L %L." + OldLibName + OldCellName + OldViewName ) ) ) + MyCellView ) ) + ( NewLibDDObj (let ( + ( ExistingLibDDObj ( ddGetObj NewLibName ) ) ) + (if ExistingLibDDObj + ExistingLibDDObj + + (let ( + ( NewLibDir ( NameGetLibDirFromDFIIDirAndCellName + DFIIDir + NewCellName ) ) ) + (if NewLibDir + (if ( isDir NewLibDir ) + ( setq + ErrorStr + ( sprintf + nil + "Library %L does not exist, but directory %L does." + NewLibName + NewLibDir ) ) + (if ( equal + ( FileUtilMakeDir + NewLibDir + t ) + 0 ) + (let ( + ( NewLibDDObj ( ddCreateLib + NewLibName + NewLibDir ) ) ) + (if NewLibDDObj + (let () + ( techBindTechFile NewLibDDObj TechnologyLibraryName ) + NewLibDDObj ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to create library %L in directory %L." + NewLibName + NewLibDir ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to create directory %L for library %L." + NewLibDir + NewLibName ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to determine what directory library %L should be in." + NewLibName ) ) ) ) ) ) ) ) + (unless ErrorStr + (let ( + ( NewCellView ( dbCopyCellView + OldCellView + NewLibName + NewCellName + NewViewName + nil + nil + t ) ) ) + (if NewCellView + ( setarray + Result + ( list OldLibName OldCellName OldViewName ) + NewCellView ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to copy %L %L %L to %L %L %L." + OldLibName + OldCellName + OldViewName + NewLibName + NewCellName + NewViewName ) ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "%L %L %L does not exist." + OldLibName + OldCellName + OldViewName ) ) ) ) ) ) ) ) + (if ErrorStr + ErrorStr + Result ) ) ) + + +(defun ImportMungeCellViewsInCellViewTable ( CellViewTable ) + ( foreach + CellViewTableEntry + ( tableToList + CellViewTable ) + (let ( + ( CellViewToMunge ( cadr CellViewTableEntry ) ) ) + ( ImportMungeCellInstances + CellViewToMunge + CellViewTable ) ) ) + ( foreach + CellViewTableEntry + ( tableToList + CellViewTable ) + (let ( + ( CellViewToSaveAndClose ( cadr CellViewTableEntry ) ) ) + ( dbSave CellViewToSaveAndClose ) + ( dbPurge CellViewToSaveAndClose ) ) ) + nil ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/instancesfile/instance.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/instancesfile/instance.il new file mode 100644 index 0000000000..c2db33441c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/instancesfile/instance.il @@ -0,0 +1,175 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun SerializeStackMachine (l @optional (p poport)) + (cond + ((booleanp l) (if l (fprintf p "true\n") (fprintf p "null\n"))) + ((listp l) (fprintf p "beginlist\n") + (mapc (lambda (x) (SerializeStackMachine x p)) l) + (fprintf p "endlist\n")) + (t (fprintf p "%L\n" l)))) + +(defun MicronToMeter (x) + (quotient x 1000000.0)) + +(defun TransformInstanceName (name) + ; Change foo(1,2,3) -> foo[1,2,3] + (rexCompile "(") + (setq name (rexReplace name "[" 0)) + (rexCompile ")") + (setq name (rexReplace name "]" 0)) + + ; Translating from ][ to , is now done by CadenceReverseNameInterface + name) + +(defun TransformCellName (name) + name) + +(defun ScaleBBox (bbox @optional (fun 'MicronToMeter)) + (let + ((ll (car bbox)) + (ur (cadr bbox))) + (list (mapcar fun ll) (mapcar fun ur)))) + +(defun CenterBBox (bbox) + (let + ((ll (car bbox)) + (ur (cadr bbox))) + (list (quotient (plus (car ll) (car ur)) 2.0) + (quotient (plus (cadr ll) (cadr ur)) 2.0)))) + +(defun TranslatePoint (pt dists) + (list (plus (car pt) (car dists)) + (plus (cadr pt) (cadr dists)))) + +(defun TranslateBBox (bbox dists) + (list (TranslatePoint (car bbox) dists) + (TranslatePoint (cadr bbox) dists))) + +; Print pins +(defun PrintPins (CV) + (let (GND Vdd result) + GND = (dbFindNetByName CV "GND") + Vdd = (dbFindNetByName CV "Vdd") + dists = (mapcar 'minus (CenterBBox CV->bBox)) + (foreach net (setof net CV->nets (and net!=GND net!=Vdd)) + (foreach pin net->pins + (if pin->fig != nil + result=(cons (list net->name (ScaleBBox (TranslateBBox pin->fig->bBox dists))) result) + ) + ) + ) + result)) + +(defun GenerateInstancesSingle + (cv center LibCellPairRegExsToInclude LibCellPairRegExsToExclude + @optional (bboxTransform 'ScaleBBox) + (cellTransform 'TransformCellName) + (instTransform 'TransformInstanceName)) + (let + ((dists (mapcar 'minus (CenterBBox cv->bBox)))) + (mapcar + (lambda (inst) + (list + (funcall cellTransform inst->cellName) + (funcall instTransform inst->name) + (stringToSymbol inst->orient) + (funcall bboxTransform + (if center + (TranslateBBox inst->bBox dists) + inst->bBox)))) + (let + ; Filter out pcell instance masters, and other undesirable cells + ((candidates + (setof x cv->instances + ; Only output real, non-pcell, instances + (and (equal x->objType "inst") + (not x->master->superMaster))))) + (if LibCellPairRegExsToInclude + (setq candidates + (cadr (NameFilterInstances candidates + LibCellPairRegExsToInclude)))) + (if LibCellPairRegExsToExclude + (setq candidates + (car (NameFilterInstances candidates + LibCellPairRegExsToExclude)))) + candidates)))) + +(defun GenerateInstancesHierarchy (cv center + LibCellPairRegExsToInclude + LibCellPairRegExsToExclude + @optional (cache (makeTable "cache" nil)) + (result nil)) + ; Give a concise but informative warning if an instance master cannot be + ; found. This may happen because a cellview was not checked in, or cds.lib + ; is not setup correct, for example. + (let + ((badcells (makeTable "badcells" nil)) key) + (mapcar + (lambda (inst) + (if (not inst->master) + (let + ((lcv (list inst->libName inst->cellName inst->viewName))) + badcells[lcv] = (cons inst->name badcells[lcv])))) + cv->instances) + (if (greaterp (length badcells) 0) + (begin + (printf "In %L, the following cannot be loaded:\n" (list cv->libName cv->cellName cv->viewName)) + ; (lib cell view): (instance instance ...) + (foreach key badcells + (printf "%L: %L\n" key badcells[key]))))) + + ; Recurse to subcells + (mapc + (lambda (master) + (unless cache[master] + (setq result (append result (GenerateInstancesHierarchy master center LibCellPairRegExsToInclude LibCellPairRegExsToExclude cache))) + cache[master]=t)) + (let + ; Filter out pcell instance masters, and null instanceMasters + ((candidates (setof x cv->instanceMasters (and x (not x->superMaster))))) + (if LibCellPairRegExsToInclude + (setq candidates + (cadr (NameFilterInstanceMasters candidates + LibCellPairRegExsToInclude)))) + (if LibCellPairRegExsToExclude + (setq candidates + (car (NameFilterInstanceMasters candidates + LibCellPairRegExsToExclude)))) + candidates)) + + ; Generate instances for this cell + (setq result (cons (list cv (GenerateInstancesSingle cv center LibCellPairRegExsToInclude LibCellPairRegExsToExclude )) result)) + + result) + +(defun WriteInstancesFile (dir cv @key ( center t ) (hierarchical t) (LibCellPairRegExsToInclude nil) (LibCellPairRegExsToExclude nil) ) + (if (isWritable dir) + (mapcar + (lambda (z) + (letseq + ((cv (car z)) + (x (cadr z)) + (fname (strcat dir "/" cv->cellName ".instances")) + (out (outfile fname))) + (if out + (begin + (SerializeStackMachine (ScaleBBox cv->bBox) out) + (setq y (PrintPins cv)) + (if y + (begin + (SerializeStackMachine 'pins out) + (SerializeStackMachine y out))) + (if x + (begin + (SerializeStackMachine 'subcells out) + (SerializeStackMachine x out))) + (drain out) + (close out)) + (error (strcat "Cannot open file: " fname))))) + (if hierarchical + (GenerateInstancesHierarchy cv center LibCellPairRegExsToInclude LibCellPairRegExsToExclude) + ( list ( list cv (GenerateInstancesSingle cv center LibCellPairRegExsToInclude LibCellPairRegExsToExclude) ) ) )) + (error (strcat "Cannot write to directory: " dir)))) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/abstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/abstract.il new file mode 100644 index 0000000000..ff01e044ac --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/abstract.il @@ -0,0 +1,758 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun AbstractCreateAbstractView ( CellView + KeepoutRuleFile + ViaLayerFormat + MetalLayerFormat + MetalLPPs + KeepoutMetalLPPs + ViaLPPs + WorkingDir + FoldableCellLibCellPairRegExs + GNDNetName + VddNetName + ContactLibName + ContactCellNameFormat + ContactViewName + BoundaryLPP + @key + ( Internal nil ) + ( ErasePowerGrid t ) + ( KeepoutPowerGrid t ) + ( DrawKeepout t ) + ( Simplify nil ) + ( DrawVias t ) + ( LimitPins nil ) + ( NoPCells nil ) + ) + (let ( + ( TempLibName + ( LibCreateTempLibraryFromCellView CellView "ABSTRACT" WorkingDir ) ) + ( AssuraLayerMappings + ( cons + ( list "bound" BoundaryLPP ) + ( append + ( ListNonDestructiveMapCan + (lambda ( LPP ) + (let ( + ( Num 0 ) ) + ( sscanf ( car LPP ) MetalLayerFormat Num ) + ( list + ( list ( sprintf nil "m%dKeepout" Num ) + ( list ( car LPP ) + "boundary" ) ) + ( list ( sprintf nil "m%dNeedConnect" Num ) + LPP ) ) ) ) + MetalLPPs ) + ( ListNonDestructiveMapCan + (lambda ( LPP ) + (let ( + ( Num 1 ) + ) + ( sscanf ( car LPP ) ViaLayerFormat Num ) + ( list + ( list ( sprintf nil "via%dNeedConnect" + Num + ) + LPP ) ) ) ) + ViaLPPs ) ) + ) ) ) + (let ( + ( ConductorCellView + ( dbCopyCellView + CellView + TempLibName + CellView->cellName + "conductor" + nil nil t ) ) ) + + ( foreach + Shape + ( getq ConductorCellView shapes ) + (cond ( + ( equal ( getq Shape objType ) "label" ) + (unless ( and + KeepoutPowerGrid + ( or + ( equal Shape->theLabel GNDNetName ) + ( equal Shape->theLabel VddNetName ) ) ) + ( dbSetq Shape ( strcat "XXX" Shape->theLabel ) theLabel ) ) ) ) ) + + ( dbSave ConductorCellView ) + + (let ( + ( ErrorStr + ( AssuraRunAssuraLayerProcessor + ConductorCellView + TempLibName + CellView->cellName + "keepout" + KeepoutRuleFile + WorkingDir + AssuraLayerMappings + nil + ?NoPCells NoPCells + ?AssuraSets + ( append ( setof + Set + ( list (when ErasePowerGrid "ERASE_POWER_GRID" ) + (when DrawKeepout "DRAW_KEEPOUT" ) + (when Simplify "SIMPLIFY" ) + (when DrawVias "DRAW_VIAS" ) + (when LimitPins "LIMIT_PINS" ) + ) + ( stringp Set ) ) + ( mapcar `car KeepoutMetalLPPs ) ) + ) ) ) + (if ErrorStr + ErrorStr + (let ( + ( Keepout + ( dbOpenCellViewByType + TempLibName + CellView->cellName + "keepout" + nil + "r" ) ) + ( Abstract + ( dbCopyCellView + CellView + CellView->libName + CellView->cellName + "abstract" + nil nil t) ) ) + + + ;replace shapes, but keep labels and pins + ( foreach + Fig + ( getq Abstract shapes ) + (unless ( or + ( getq Fig pin ) + ( equal ( getq Fig objType ) "label" ) ) + ( dbDeleteObject Fig ) ) + ) + + ( foreach + Shape + ( getq Keepout shapes ) + ( dbCopyFig + Shape + Abstract + ) ) + + ( foreach + Fig + ( getq Abstract mosaics ) + ( dbDeleteObject Fig ) ) + + ( foreach + Fig + ( getq Abstract instances ) + (unless Internal ( dbDeleteObject Fig ) + ) ) + + ( foreach ly Abstract~>lpps + if((ly~>layerName == "prBoundary" && ly~>purpose == "drawing") then + foreach( shape ly~>shapes shape~>purpose = "boundary" ) + ) + ) + + sprintf( gec3Foreign "%s %f %f" Abstract~>cellName caar(Abstract~>bBox) cadar(Abstract~>bBox) ) + + dbReplacePropList( Abstract list( + list("prCellClass" "string" "block") + list("prCellType" "string" "macro") + list("maskLayoutSubType" "string" "abstract") + list("symmetry" "string" "X Y") +; list("placementClass" "string" "standard") + list("gec3Foreign" "string" gec3Foreign) + ) + ) + + dbSave(Abstract) + println(ViaLPPs) + + ( foreach + LPP + ViaLPPs + (let ( + ( BottomMetalLayer + ( car ( car ( PinUtilGetValidLayers LPP ) ) ) ) + ( N 1 ) ) + ( sscanf BottomMetalLayer MetalLayerFormat Num ) + (let ( + ( ContactCellName + ( sprintf + nil + ContactCellNameFormat + ( plus N 1 ) N ) ) ) + ( foreach + Shape + ( PinUtilGetAllShapesOnLPP + Abstract + LPP ) + + ( dbCreateInstByMasterName + Abstract + ContactLibName + ContactCellName + ContactViewName + nil + ( RectGetCenter + ( getq Shape bBox ) ) + "R0" + ) + ( dbDeleteObject Shape ) + ) ) ) ) + + ( dbPurge Keepout ) + ( dbPurge ConductorCellView ) + + ( ddDeleteObj ( ddGetObj TempLibName ) ) + + Abstract + ) ) ) ) ) ) + +(defun AbstractCellUsingPDKInfo ( CellView + WorkingDir + @key + ( Internal nil ) + ( ErasePowerGrid t ) + ( Simplify nil ) + ( DrawVias t ) + ( KeepoutPowerGrid t ) + ( LimitPins nil ) + ( NoPCells nil ) + ( KeepoutMetalLPPs + ( list + Metal3LPP + Metal4LPP + Metal5LPP + Metal6LPP + Metal7LPP + Metal8LPP ) + ) ) + (let ( + ( Abstract + ( AbstractCreateAbstractView + CellView + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/abstract.rul" + FulcrumPDKRoot ) + ViaLayerFormat + MetalLayerFormat + MetalLPPs + KeepoutMetalLPPs + ViaLPPs + WorkingDir + FoldableCellLibCellPairRegExs + GNDNetName + VddNetName + ContactLibrary + ContactMinCellNameFormat + ContactViewName + BoundaryLPP + ?ErasePowerGrid ErasePowerGrid + ?Internal Internal + ?Simplify Simplify + ?DrawVias DrawVias + ?KeepoutPowerGrid KeepoutPowerGrid + ?LimitPins LimitPins + ?NoPCells NoPCells + ) ) ) + Abstract + ) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MakeSimpleAbstract ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun MakeSimpleAbstract (@key (CV (geGetEditCellView)) + (cutaroundpins nil) + (cutout KeepoutM2to7WireSpacing) + (topMetal nil)) + (let (abstractCV name net fig term + havem2pins havem3pins havem4pins havem5pins havem6pins havem7pins) + + ; load wires.il and set topMetal + (LoadWires) + (unless topMetal topMetal = bundled_top_layer) + + abstractCV=(dbOpenCellViewByType CV->libName CV->cellName "abstract" "maskLayout" "w") + (when !abstractCV + (printf "Couldn't edit abstract view for %s\n" CV->cellName) + (error "Cellview not writable.\n") + ) + (printf "Generating abstract of %s at %s\n" CV->cellName (getCurrentTime)) + (foreach shape abstractCV->shapes + (when shape (dbDeleteObject shape) ) + ) + + ; create prBoundary + prb = (dbCreatePRBoundary abstractCV (GetPrboundPoints CV)) + (dbCreatePolygon abstractCV BoundaryLPP (GetPrboundPoints CV)) + + ; invert keepout + (AbstractInvertKeepout Metal1byLPP CV abstractCV ?cutout cutout) + (when topMetal>1 (AbstractInvertKeepout Metal2byLPP CV abstractCV ?cutout cutout) ) + (when topMetal>2 (AbstractInvertKeepout Metal3byLPP CV abstractCV ?cutout cutout) ) + (when topMetal>3 (AbstractInvertKeepout Metal4byLPP CV abstractCV ?cutout cutout) ) + (when topMetal>4 (AbstractInvertKeepout Metal5byLPP CV abstractCV ?cutout cutout) ) + (when topMetal>5 (AbstractInvertKeepout Metal6byLPP CV abstractCV ?cutout cutout) ) + (when topMetal>6 (AbstractInvertKeepout Metal7byLPP CV abstractCV ?cutout cutout) ) + + ;copy pins to abstract + havem2pins=nil + havem3pins=nil + havem4pins=nil + havem5pins=nil + havem6pins=nil + havem7pins=nil + (foreach shape CV->shapes + (when shape->pin + name=shape->net->name + net=(dbFindNetByName abstractCV name) + (when !net net=(dbCreateNet abstractCV name)) + term=(dbFindTermByName abstractCV name) + (when !term (dbCreateTerm net name "inputOutput")) + fig=(dbCopyFig shape abstractCV) + (dbCreatePin net fig) + (when shape->lpp==Metal2LPP || shape->lpp==Metal2pinLPP + havem2pins=t + ) + (when shape->lpp==Metal3LPP || shape->lpp==Metal3pinLPP + havem3pins=t + ) + (when shape->lpp==Metal4LPP || shape->lpp==Metal4pinLPP + havem4pins=t + ) + (when shape->lpp==Metal5LPP || shape->lpp==Metal5pinLPP + havem5pins=t + ) + (when shape->lpp==Metal6LPP || shape->lpp==Metal6pinLPP + havem6pins=t + ) + (when shape->lpp==Metal7LPP || shape->lpp==Metal7pinLPP + havem7pins=t + ) + ) + ) + (PinUtilOrientLabels abstractCV) + + ;chop keepouts around pins + (when cutaroundpins + (when havem2pins (AbstractCutAroundPins abstractCV Metal2LPP Metal2byLPP + ?otherpinlpp Metal2pinLPP ?cutout cutout)) + (when havem3pins (AbstractCutAroundPins abstractCV Metal3LPP Metal3byLPP + ?otherpinlpp Metal3pinLPP ?cutout cutout)) + (when havem4pins (AbstractCutAroundPins abstractCV Metal4LPP Metal4byLPP + ?otherpinlpp Metal4pinLPP ?cutout cutout)) + (when havem5pins (AbstractCutAroundPins abstractCV Metal5LPP Metal5byLPP + ?otherpinlpp Metal5pinLPP ?cutout cutout)) + (when havem6pins (AbstractCutAroundPins abstractCV Metal6LPP Metal6byLPP + ?otherpinlpp Metal6pinLPP ?cutout cutout)) + (when havem7pins (AbstractCutAroundPins abstractCV Metal7LPP Metal7byLPP + ?otherpinlpp Metal7pinLPP ?cutout cutout)) + ) + + ;create power grid blockages + x2box = (rightEdge prb->bBox) + x1box = (leftEdge prb->bBox) + y2box = (topEdge prb->bBox) + y1box = (bottomEdge prb->bBox) + numx2 = (round x2box/1.56) + numx1 = (round x1box/1.56) + numy2 = (round y2box/1.56) + numy1 = (round y1box/1.56) + (for i numx1 numx2 + (for j numy1 numy2 + (dbCreateRect abstractCV (list "M4" "boundary") (list i*1.56-0.105:j*1.56-0.105 i*1.56+0.105:j*1.56+0.105)) + (dbCreateRect abstractCV (list "M5" "boundary") (list i*1.56-0.105:j*1.56-0.105 i*1.56+0.105:j*1.56+0.105)) + (dbCreateRect abstractCV (list "M6" "boundary") (list i*1.56-0.105:j*1.56-0.105 i*1.56+0.105:j*1.56+0.105)) + (dbCreateRect abstractCV (list "M7" "boundary") (list i*1.56-0.105:j*1.56-0.105 i*1.56+0.105:j*1.56+0.105)) + (dbCreateRect abstractCV (list "M8" "boundary") (list i*1.56-0.25:j*1.56-0.31 i*1.56+0.25:j*1.56+0.31)) + ) + ) + (for k numy1 numy2 + (dbCreateRect abstractCV (list "M3" "boundary") (list numx1*1.56-0.105:k*1.56-0.1 numx2*1.56+0.105:k*1.56+0.1)) + (dbCreateRect abstractCV (list "M8" "boundary") (list numx1*1.56-0.31:k*1.56-0.4 numx2*1.56+0.31:k*1.56+0.4)) + ) + + (CopyKeepoutToBlockage abstractCV ) + (SetLefProperties abstractCV) + (dbSave abstractCV) + abstractCV + ) + ) + +(defun AbstractCutAroundPins (cv pinlpp keepoutlpp + @key (otherpinlpp nil) (cutout KeepoutM2to7WireSpacing)) + (let () + (leLayerSize cv pinlpp cutout Scratch1LPP) + (when otherpinlpp (leLayerSize cv otherpinlpp cutout Scratch1LPP)) + (leLayerAndNot cv keepoutlpp Scratch1LPP Scratch2LPP) + (foreach shape cv->shapes + (cond (shape->lpp==keepoutlpp (dbDeleteObject shape)) + (shape->lpp==Scratch1LPP (dbDeleteObject shape)) + (shape->lpp==Scratch2LPP shape->lpp=keepoutlpp)) + ) + ) + t + ) + +; KEEPOUT = (PRB & !KEEPOUT)-cutout/2 +(defun AbstractInvertKeepout (lpp cv1 cv2 @key (cutout KeepoutM2to7WireSpacing)) + (foreach shape cv1->shapes + (when shape->lpp==lpp (dbCopyFig shape cv2)->lpp=Scratch1LPP) + ) + (leLayerSize cv2 Scratch1LPP cutout Scratch1LPP) + (leLayerSize cv2 BoundaryLPP -cutout/2 Scratch2LPP) + (leLayerAndNot cv2 Scratch2LPP Scratch1LPP lpp) + (foreach shape cv2->shapes + (cond (shape->lpp==Scratch1LPP (dbDeleteObject shape)) + (shape->lpp==Scratch2LPP (dbDeleteObject shape)) + ) + ) + t + ) + +; KEEPOUT = (PRB)-cutout/2 +(defun AbstractInvertCDCKeepout (lpp cv1 cv2 @key (cutout KeepoutM2to7WireSpacing)) +; (foreach shape cv1->shapes +; (when shape->lpp==lpp (dbCopyFig shape cv2)->lpp=Scratch1LPP) +; ) + (leLayerSize cv2 Scratch1LPP cutout Scratch1LPP) + (leLayerSize cv2 BoundaryLPP -cutout/2 Scratch2LPP) + (leLayerAndNot cv2 Scratch2LPP Scratch1LPP lpp) + (foreach shape cv2->shapes + (cond (shape->lpp==Scratch1LPP (dbDeleteObject shape)) + (shape->lpp==Scratch2LPP (dbDeleteObject shape)) + ) + ) + t + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MakeLeafAbstract ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun MakeLeafAbstract (@key (CV (geGetEditCellView)) + (cutout KeepoutM2to7WireSpacing) + (floodfillM3Keepout nil) + (floodfillM2Keepout t) + (floodfillM1Keepout t) + (extendM3Keepout t) + (extendM2Keepout t)) + (let (abstractCV name net fig term pin prb prbSpacing + llPrB urPrB xy0 xy1 x0 y0 x1 y1 + trackshape Vdd GND dd_CV layer purpose) + + ; sanity check + (when CV->viewName=="abstract" + (error "Can't call MakeAbstract on abstract view of %s\n" CV->cellName) + ) + + ; check for prBoundary first + prb = (GetPrbound CV) + (unless prb (error "No prBoundary object in %s\n" CV->cellName)) + + ; create empty abstract view + (printf "Generating abstract of %s at %s\n" CV->cellName (getCurrentTime)) + abstractCV=(dbOpenCellViewByType CV->libName CV->cellName "abstract" "maskLayout" "w") + (when !abstractCV (error "Couldn't edit abstract view for %s\n" CV->cellName)) + + ; flatten pcells and vias to abstract_temp view + CV=(dbCopyCellView CV CV->libName CV->cellName "abstract_temp" nil nil t) + (when !CV (error "Couldn't edit abstract_temp view for %s\n" CV->cellName)) + (foreach inst CV->instances (dbFlattenInst inst 32 t)) + (foreach inst CV->vias (dbFlattenInst inst 32 t)) + (dbSave CV) + + ; create prBoundary + (dbCreatePRBoundary abstractCV (GetPrboundPoints CV)) + (dbCreatePolygon abstractCV BoundaryLPP (GetPrboundPoints CV)) + llPrB=(car prb->bBox) + urPrB=(cadr prb->bBox) + + ; flood fill keepout + (when floodfillM1Keepout (AbstractInvertKeepout Metal1byLPP CV abstractCV ?cutout cutout) ) + (when floodfillM2Keepout (AbstractInvertKeepout Metal2byLPP CV abstractCV ?cutout cutout) ) + (when floodfillM3Keepout (AbstractInvertKeepout Metal3byLPP CV abstractCV ?cutout cutout) ) + + ; extend M3 keepout to left and right sides of cell + prbSpacing = KeepoutM2to7WireSpacing/2 + (when !floodfillM3Keepout && extendM3Keepout + (foreach shape CV->shapes + (when shape->lpp==Metal3LPP && !shape->pin && shape->objType!="label" + xy0=(car shape->bBox) + xy1=(cadr shape->bBox) + y0=(cadr xy0) + y1=(cadr xy1) + x0=(car llPrB)+prbSpacing + x1=(car urPrB)-prbSpacing + trackshape=(list x0:y0 x1:y1) + (dbCreateRect abstractCV Metal3byLPP trackshape) + ) + ) + ) + + ; extend M2 keepout to top and bottom sides of cell + (when !floodfillM2Keepout && extendM2Keepout + (foreach shape CV->shapes + (when shape->lpp==Metal2LPP && !shape->pin && shape->objType!="label" + xy0=(car shape->bBox) + xy1=(cadr shape->bBox) + y0=(cadr xy0) + y1=(cadr xy1) + x0=(car llPrB)+prbSpacing + x1=(car urPrB)-prbSpacing + trackshape=(list x0:y0 x1:y1) + (dbCreateRect abstractCV Metal2byLPP trackshape) + ) + ) + ) + + ; convert Vdd/GND purposes to pins + GND = (dbCreateNet abstractCV GNDNetName) + Vdd = (dbCreateNet abstractCV VddNetName) + (dbCreateTerm GND GND->name "inputOutput") + (dbCreateTerm Vdd Vdd->name "inputOutput") + (foreach shape CV->shapes + (unless shape->pin + (cond (shape->purpose=="gnd" + fig = (dbCopyFig shape abstractCV) + fig->lpp = (list (car fig->lpp) "drawing") + (dbCreatePin GND (dbCopyFig shape abstractCV)) + ) + (shape->purpose=="vdd" + fig = (dbCopyFig shape abstractCV) + fig->lpp = (list (car fig->lpp) "drawing") + (dbCreatePin Vdd (dbCopyFig shape abstractCV)) + ) + ) + ) + ) + + ; copy pins on metal layers + (foreach shape CV->shapes + (when shape->pin && (isMetal (car shape->lpp)) + name=shape->net->name + net=(dbFindNetByName abstractCV name) + (unless net net=(dbCreateNet abstractCV name)) + term=(dbFindTermByName abstractCV name) + (unless term term=(dbCreateTerm net name "inputOutput")) + pin=(car term->pins) + (unless pin pin=(dbCreatePin net nil)) + fig=(dbCopyFig shape abstractCV) + fig->lpp = (list (car fig->lpp) "drawing") + (dbAddFigToPin pin fig) ; strongly connected figures + ) + ) + (DeleteLabels ?CV abstractCV) + (LabelPins ?CV abstractCV) + + ; chop flooded/extended keepout near pins + (AbstractCutAroundPins abstractCV Metal2LPP Metal2byLPP ?cutout cutout) + (AbstractCutAroundPins abstractCV Metal3LPP Metal3byLPP ?cutout cutout) + + ; copy explicit metal shapes to boundary purpose + (foreach shape CV->shapes + layer = (car shape->lpp) + purpose = (cadr shape->lpp) + (when !shape->pin && shape->objType!="label" && (isMetal layer) && + (purpose=="drawing" || purpose=="pin" || purpose=="vdd" || purpose=="gnd") + fig = (dbCopyFig shape abstractCV) + fig->lpp = (list layer "boundary") + ) + ) + + ; chop keepout overlapping pins + (AbstractCutAroundPins abstractCV Metal2LPP Metal2byLPP ?cutout 0) + (AbstractCutAroundPins abstractCV Metal3LPP Metal3byLPP ?cutout 0) + + ; create final boundary shapes and blockage objects + (leMergeShapes abstractCV->shapes) + (CopyKeepoutToBlockage abstractCV) + + ; save and exit + (SetLefProperties abstractCV) + (dbSave abstractCV) + dd_CV = (ddGetObj abstractCV->libName abstractCV->cellName "abstract_temp") + (when dd_CV (ddDeleteObj dd_CV)) + abstractCV + ) + ) + +; turn blockage from layers to objects +(defun CopyKeepoutToBlockage (cv) + (let (points) + (foreach shape cv->shapes + (foreach layer (list Metal1byLPP Metal2byLPP Metal3byLPP Metal4byLPP + Metal5byLPP Metal6byLPP Metal7byLPP Metal8byLPP) + (when shape->lpp==layer + points = (if shape->objType=="rect" (RectGetPolygonPoints shape->bBox) shape->points) + (when points (dbCreateLayerBlockage cv (car layer) "routing" points)) + ) + ) + ) + ) + t + ) + +(defun MakeMidAbstract ( @key (CV (geGetEditCellView)) + (cutaroundpins t) + (cutout KeepoutM2to7WireSpacing) + (topMetal nil)) + (MakeSimpleAbstract ?CV CV ?cutaroundpins cutaroundpins ?cutout cutout + ?topMetal topMetal) + ) + +(defun MakeAbstract ( @key (CV (geGetEditCellView)) + (cutaroundpins t) + (cutout KeepoutM2to7WireSpacing) + (topMetal nil)) + (if (IsLeafCell CV->cellName) + (MakeLeafAbstract ?CV CV ?cutout cutout) + (MakeMidAbstract ?CV CV ?cutaroundpins cutaroundpins ?cutout cutout ?topMetal topMetal) + ) + ) + +; set properties for LEF export +(defun SetLefProperties (CV @key (powergrid nil)) + (let (Vdd GND) + CV->cellType = (if powergrid "cover" "block") ; CLASS [COVER|BLOCK] + (dbSetCellViewSymmetry CV "any") ; SYMMETRY X Y R90 + GND = (dbFindNetByName CV GNDNetName) + Vdd = (dbFindNetByName CV VddNetName) + (when GND GND->sigType = "ground") ; USE GROUND + (when Vdd Vdd->sigType = "supply") ; USE POWER + ) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MakeCDCLeafAbstract ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun MakeCDCLeafAbstract (@key (cv (geGetEditCellView)) + (cutaroundpins t) + (cutout KeepoutM2to7WireSpacing) + (topMetal 3)) + (let (abstractcv name net fig term prb + havem2pins havem3pins llPrB urPrB llshapeM3 urshapeM3 llM3y urM3y + lxPrB rxPrB trackshape) + + abstractcv=(dbOpenCellViewByType cv->libName cv->cellName "abstract" "maskLayout" "w") + (when !abstractcv + (printf "Couldn't edit abstract view for %s\n" cv->cellName) + (error "Cellview not writable.\n") + ) + (printf "Generating abstract of %s at %s\n" cv->cellName (getCurrentTime)) + (foreach shape abstractcv->shapes + (when shape (dbDeleteObject shape) ) + ) + + ; flatten pcells and vias to abstract_temp view + abstract_temp=(dbCopyCellView cv cv->libName cv->cellName "abstract_temp" nil nil t) + (when !abstract_temp (error "Couldn't edit abstract_temp view for %s\n" cv->cellName)) + cv=abstract_temp + (foreach inst cv->instances (dbFlattenInst inst 32 t)) + (foreach inst cv->vias (dbFlattenInst inst 32 t)) + (dbSave cv) + + ; create prBoundary + prb = (GetPrbound cv) + (dbCreatePRBoundary abstractcv (GetPrboundPoints cv)) + (dbCreatePolygon abstractcv BoundaryLPP (GetPrboundPoints cv)) + llPrB=(car prb->bBox) + urPrB=(cadr prb->bBox) + + ; invert keepout + (AbstractInvertCDCKeepout Metal1byLPP cv abstractcv ?cutout cutout) + (when topMetal>1 (AbstractInvertCDCKeepout Metal2byLPP cv abstractcv ?cutout cutout) ) +; (when topMetal>2 (AbstractInvertCDCKeepout Metal3byLPP cv abstractcv ?cutout cutout) ) + + ; extend M3 keepout to left and right sides of cell + (foreach shape cv->shapes + (when shape->lpp== Metal3LPP && !shape->pin && shape->objType!="label" + llshapeM3=(car shape->bBox) + urshapeM3=(cadr shape ->bBox) + llM3y=(cadr llshapeM3) + urM3y=(cadr urshapeM3) + lxPrB=(car llPrB) + rxPrB=(car urPrB) + trackshape=(list lxPrB+0.06 : llM3y rxPrB-0.06 : urM3y) +; trackshape=shape->bBox + (dbCreateRect abstractcv Metal3byLPP trackshape) + ) + ) + + ; explicit copy of m3 pwr stripes + (foreach shape cv->shapes + (when shape->lpp== Metal3LPP + (when IsM3Power(shape)==GNDNetName || IsM3Power(shape)==VddNetName + name=IsM3Power(shape) + net=(dbFindNetByName abstractcv name) + (when !net net=(dbCreateNet abstractcv name)) + term=(dbFindTermByName abstractcv name) + (when !term (dbCreateTerm net name "input")) + fig=(dbCopyFig shape abstractcv) + (dbCreatePin net fig) + ) + ) + ) + + ; copy other pins to abstract + havem2pins=nil + havem3pins=t + (foreach shape cv->shapes + (when shape->pin || (shape->lpp==Metal3pinLPP && shape->objType != "label") + (when shape->net->name!=GNDNetName && shape->net->name!=VddNetName + name=shape->net->name + net=(dbFindNetByName abstractcv name) + (when !net net=(dbCreateNet abstractcv name)) + term=(dbFindTermByName abstractcv name) + (when !term (dbCreateTerm net name "inputOutput")) + fig=(dbCopyFig shape abstractcv) + (dbCreatePin net fig) + ) + (when shape->lpp==Metal2LPP || shape->lpp==Metal2pinLPP + havem2pins=t + ) + (when shape->lpp==Metal3LPP || shape->lpp==Metal3pinLPP + havem3pins=t + ) + ) + ) + (PinUtilOrientLabels abstractcv) + + ; chop keepouts around pins + (when cutaroundpins + (when havem2pins (AbstractCutAroundPins abstractcv Metal2LPP Metal2byLPP + ?otherpinlpp Metal2pinLPP ?cutout cutout)) + (when havem3pins (AbstractCutAroundPins abstractcv Metal3LPP Metal3byLPP + ?otherpinlpp Metal3pinLPP ?cutout cutout)) + ) + +; (CopyKeepoutToBlockage abstractcv) + (SetLefProperties abstractcv) + (dbSave abstractcv) + dd_CV = (ddGetObj abstractcv->libName abstractcv->cellName "abstract_temp") + (when dd_CV (ddDeleteObj dd_CV)) + abstractcv + ) +) + +defun( IsM3Power ( shape ) + prog(( x1 x2 y1 y2 nthRail) + y1=bottomEdge( shape->bBox ) + y2=topEdge( shape->bBox ) + x1=leftEdge( shape->bBox ) + x2=rightEdge( shape->bBox ) + if(x2-x1<0.25 then return(nil)) + nthRail=floor(y2/1.1) + if(y1>nthRail*1.1+0.125 then return(nil) ) +; if(y2pattern pairs + busUseDefaultPatterns = t ; draw the standard patterns from the PDK + bundled_channels = nil ; for bundled channel routing in fat.il + bundled_bottom_layer = 3 ; bottom layer for bundled channel routing + bundled_top_layer = 7 ; top layer for bundled channel routing + delete_redundant_pins = nil ; DeleteRedundantPins or just warn about them + t + ) +(BusDefaults) + +; return reference to guide instance given instance name +; if inst already defined, use that +(defun GetGuideInst (inst name @key (CV (geGetEditCellView))) + (cond (inst!=nil inst) + (name!=nil + (dbFindAnyInstByName CV name)) + (busGuideInstName!=nil + (dbFindAnyInstByName CV busGuideInstName)) + ) + ) + +; simple heuristic to check for guide instances or views +(defun IsGuideInst (inst) + (let (part) + part = (car (last (parseString inst->cellName "_"))) + (or part=="buswires" inst->name=="buswires" + part=="autobuswires" inst->name=="autobuswires") + ) + ) + +(defun EditGuideInstInPlace () + (let (cell) + cell=(GetGuideInst nil busGuideInstName) + (geDeselectAllFig) + (geSelectObject cell) + (leHiEditInPlace) +)) + +(defun EditAutoGuideInstInPlace () + (let (cell) + cell=(GetGuideInst nil "autobuswires") + (geDeselectAllFig) + (geSelectObject cell) + (leHiEditInPlace) +)) + +; create a template guide instance +(defun MakeGuideInst (guidename instname @key (CV (geGetEditCellView))) + (let (instview moveguides) + + (if (HasGuides CV) then + moveguides = (hiDisplayAppDBox + ?name 'GuideOverwriteDbox + ?dboxBanner "Warning" + ?dboxText "This view has bus guides. Move them into buswires cell?" + ?dialogType hicQuestionDialog + ?buttonLayout 'YesNo + ?defaultButton 1 + ) + ) + (if !(dbFindAnyInstByName CV instname) then + instview = (nrOpenCellViewWritable CV~>libName guidename "layout" ?mode "a" ) + (when !instview + (printf "Cellview %s is not writeable. Instantiating existing cell.\n" guidename) + ) + inst = (dbCreateInstByMasterName CV CV~>libName guidename "layout" instname (list 0 0) "R0") + (AnchorInstance inst) + busGuideInstName = instname + (when instview && moveguides + (CopyGuides CV instview) + (DeleteGuideShapes CV) + ) + (when instview && !instview->shapes + (dbCreateRect instview (list "prBoundary" "boundary") (list 0:0 TrackPitch:TrackPitch)) ) + else + (printf "Instance name %s is already used." instname) + ) + ) +) + +; copy paths or inst to prelayout view +(defun CopyBusGuidesToPrelayout (@key (CV (geGetEditCellView))) + (let (prelayout overwrite) + prelayout = (nrOpenCellViewWritable CV->libName CV->cellName "prelayout" ?mode "a" ) + (if !prelayout then + (printf "Couldn't edit prelayout view.") + else + (if (HasGuides prelayout) then + overwrite = (hiDisplayAppDBox + ?name 'GuideOverwriteDbox + ?dboxBanner "Warning" + ?dboxText "Prelayout view already has bus guides. Replace them?" + ?dialogType hicQuestionDialog + ?buttonLayout 'YesNo + ?defaultButton 1 + ) + (when overwrite + (DeleteGuides prelayout) + (CopyGuides CV prelayout) + ) + else + (CopyGuides CV prelayout) + ) + ) + ) +) + +(defun MoveGuidesToBuswiresCell (@key (CV (geGetEditCellView))) + (let (wirescell wirescv) + wirescell=(GetGuideInst nil busGuideInstName) + (if wirescell then + wirescv=(dbOpenCellViewByType + wirescell->libName wirescell->cellName wirescell->viewName "maskLayout" "a") + (CopyGuideShapes CV wirescv) + (DeleteGuideShapes CV) + else + (hiDisplayAppDBox + ?name 'NoBuswiresCellDbox + ?dboxBanner "Error" + ?dboxText "No buswires instance found." + ?dialogType hicQuestionDialog + ?buttonLayout 'Close + ?defaultButton 1 + ) + ) + ) +) + + +; create wires.il +(defun MakeWiresSkill (CellView instname defchans) + (let (filename file skilltemplate defchantemplate) + + skilltemplate = (sprintf nil "\n ; template wires skill for %s\n" CellView->cellName) + skilltemplate = (strcat skilltemplate "\n ; Add custom channel definitions here\n") + skilltemplate = (strcat skilltemplate "\n(defun DrawAll ()\n") + skilltemplate = (strcat skilltemplate "busGuideInstName = \"") + skilltemplate = (strcat skilltemplate instname) + skilltemplate = (strcat skilltemplate "\"\n") + skilltemplate = (strcat skilltemplate "\n ; Add DefChans to be drawn here\n") + skilltemplate = (strcat skilltemplate " ; syntax- (DrawChannels nil YourNewChannel nil \"YourNewChannel\")\n") + skilltemplate = (strcat skilltemplate "\n(DrawTracks)\n") + skilltemplate = (strcat skilltemplate ";(DrawDefaultTracks)\n") + skilltemplate = (strcat skilltemplate "(DrawObstructions)\n") + skilltemplate = (strcat skilltemplate ")\n") + + defchantemplate = "(ReloadDefChans)\n" + + filename = strcat( "/" + buildString( reverse( cddr( reverse( parseString( CellView~>fileName "/")))) "/") + "/wires.il") + (if (isFile filename) then + (printf "File wires.il already exists. Won't overwrite.") + else + file = (outfile filename) + + (if !file then + (printf "File %s is not writeable." filename) + else + (when defchans + (fprintf file "%s" defchantemplate) + ) + (fprintf file "%s" skilltemplate) + (close file) + )) + ) +) + +; check for updates to defchan.il and reload if necessary +(defun ReloadDefChans () + (let (DFII_dir defchanfile ) + DFII_dir = ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + defchanfile = (sprintf nil "%s/defchan.il" DFII_dir) + modtime = (fileTimeModified defchanfile) + (when modtime > defchan_modtime + (printf "reloading defchan.il ... ") + defchan_patterns = nil + (load defchanfile) + (printf "defchan.il reloaded.\n") + ) + defchan_modtime = modtime + ) +) + +; redraw everything +(defun RefreshAllBuswires () + (geDeselectAllFig) + (DeleteBusWires) + (DrawWires) + (DeleteUnusedNets) +) + +; redraw all pins in conjunction with inplace pins +(defun RedrawAllPins () + (DeletePinsExcludeType "Power") + (DeletePinsByPurpose "pin") + (DeletePinsByType "Inplace") + (RefreshPinDatabase) + (RefreshAllBuswires) + (CanonicalizePins) + (DrawMidLevelPins) +) + +; Update layout_pg/layout view after editing bus wires without +; touching other wires. +(defun UpdateBusLayout (@key (CV (geGetEditCellView))) + (unless CV->viewName=="layout_pg" + (error "UpdateBusLayout should be run from layout_pg view\n")) + (RedrawAllPins) + (DeleteKeepout) + (CanonicalizeNets) + (DeleteRedundantPins ?warnOnly !delete_redundant_pins) + (MakeLayout) + ) + +(defun SetBusProp (obj) + (when obj + (dbReplaceProp obj "BusScriptObject" "boolean" t) + ) +) + +(defun IsBusObject (obj) + (let (isbus) + isbus = nil + (when obj + (when (dbGetPropByName obj "BusScriptObject")->value=="TRUE" + isbus=t + ) + ) + isbus + ) +) + + +; draw an individual segment of a path +(defun DrawSegment (name layer width xy0 xy1 beginExt endExt isPin + @key (guideInst nil) (CV (geGetEditCellView))) + (let (nxy0 nxy1 x0 y0 x1 y1 fig rect net label pin) + nxy0 = (busTransformPoint xy0 guideInst) + nxy1 = (busTransformPoint xy1 guideInst) + x0 = (car nxy0) + y0 = (cadr nxy0) + x1 = (car nxy1) + y1 = (cadr nxy1) + fig = (dbCreatePath CV layer (list nxy0 nxy1) width "varExtendExtend") + (SetBusProp fig) + net = (MakeNet CV name) + fig->beginExt = (if beginExt width/2 0) + fig->endExt = (if endExt width/2 0) + (if net!=nil fig->net = net) + (cond (isPin + (cond (y0==y1 + rect = (dbCreateRect CV layer list(x0:y0-width/2 x1:y1+width/2)) ; pins should be rectangles + ) + (x0==x1 + rect = (dbCreateRect CV layer list(x0-width/2:y0 x1+width/2:y1)) ; pins should be rectangles + ) + (t (error "invalid coordinates for pins %f:%f %f:%f" x0 y0 x1 y1) + ) + ) + (dbDeleteObject fig) ; delete the path + pin = (dbCreatePin net rect) ; create a pin + (SetBusProp rect) + (dbReplaceProp rect "PinType" "string" "BusScript") + pin->accessDir = (list "left" "right" "top" "bottom") + pin->term->direction = "inputOutput" + (LabelPin CV rect) + ) + ) + ) + t + ) + + +; draw a via (use Nanoroute compatible vias) +(defun DrawVia (name viaList xy width cuts @key (doubleVias t) + (guideInst nil) (stacked nil) (corrected nil) (CV (geGetEditCellView))) + (let (inst net type extensions params contactOrientation layer1 layer2) + ;convert to a list if not a list + (if !listp(viaList) viaList = list(viaList)) + (foreach via viaList + (cond (guideInst!=nil contactOrientation = guideInst->orient) + (guideInst==nil contactOrientation = "R0")) + (cond ((and busContacts (via!=nil)) + (if cuts=="" then + type = via + (if !doubleVias then + nil + else + type = (strcat via "_R_H") + ) + else type = (strcat via cuts) + ) + extensions = (BusDefaultViaExtensions via + ?cuts cuts ?doubleVias doubleVias ?stacked stacked) + params = (if extensions + (list (list "layer1XEnclosure" "float" (car extensions)) + (list "layer1YEnclosure" "float" (cadr extensions)) + (list "layer2XEnclosure" "float" (caddr extensions)) + (list "layer2YEnclosure" "float" (cadddr extensions)) + ) + nil + ) + inst = (dbCreateVia CV + (techFindViaDefByName TechLib type) + (busTransformPoint xy guideInst) + contactOrientation + ) + when( corrected + layer2 = evalstring(car(parseString(nth(0 parseString(type "_")) "M"))) + layer1 = evalstring(car(parseString(nth(1 parseString(type "_")) "M"))) + if( evenp(layer1) + then + inst~>layer1Enc = 0.04:0.01 + inst~>layer2Enc = 0.04:0.01 + else + inst~>layer1Enc = 0.04:0.01 + inst~>layer2Enc = 0.04:0.01 + ) + ) + (SetBusProp inst) + net = (MakeNet CV name) + (cond (net!=nil (dbAddFigToNet inst net))) + ) + ) + ) ;foreach + ) + t + ) + +; Draw a multisegment path on two perpendicular layers with vias. +; (DrawWire metal67 "a" 0.36 (list 0:0 9.6:0 9.6:9.6 19.2:9.6)) +(defun DrawWire (layers name width points + @key (isPin nil) (startVias nil) (endVias nil) (doubleVias t) + (guideInst nil) (flipX nil) (flipY nil) (pattern evalstring("e1of4")) + (CV (geGetEditCellView))) + (let (horz_layer vert_layer via viadir last first lastIndex index cuts layer hv dir templast (types (ClassifyPoints points)) (dirs (ClassifyDirs points)) corrected correctOP) + corrected = nil + horz_layer = (car layers) + vert_layer = (cadr layers) + via = (caddr layers) + viadir = (cadddr layers) + points = (CanonicalizePoints points) + last = (car points) + first = t + lastIndex = (length points)-2 + index = 0 + cuts = (if (almostEqual (car (cadr points)) (car last)) "_R_V" "_R_H") + (if startVias (DrawVia name via last width cuts ?doubleVias doubleVias + ?guideInst guideInst ?stacked t ?CV CV)) + (foreach point (cdr points) + hv = nth(index types) + dir = nth(index dirs) + layer = (if (almostEqual (car point) (car last)) vert_layer horz_layer) + (DrawSegment name layer width last point + (index!=0) (index!=lastIndex) isPin ?guideInst guideInst ?CV CV) + cuts = (if (and doubleVias viadir) (strcat "_R_" viadir) "") + templast = last + when( doubleVias + correctOP = DoubleViaCorrection(templast hv dir pattern flipX flipY) + last = nth(0 correctOP) + corrected = nth(1 correctOP) + ) + (if (not first) (DrawVia name via last width cuts + ?doubleVias doubleVias ?guideInst guideInst + ?stacked nil ?corrected corrected ?CV CV)) + corrected = nil + first = nil + cuts = (if (almostEqual (car point) (car last)) "_R_V" "_R_H") + last = point + index = index+1 + ) + (if endVias (DrawVia name via last width cuts ?doubleVias doubleVias + ?guideInst guideInst ?stacked t ?CV CV)) + ) + t + ) + +; return list of which directions segments point connect to +(defun ClassifyPoints (points) + (let (a b types) + a = (car points) + b = (cadr points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "EV"))) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "EH")))) + (for i 1 (length points)-2 + a = (nth i-1 points) + b = (nth i points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "VH"))) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "HV")))) + ) + a = (nth (length points)-2 points) + b = (nth (length points)-1 points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "VE"))) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "HE"))) + ) + types + ) + ) + +; add suffix to a prefix (unless the prefix is empty, in which case result is too) +(defun AddSuffix (prefix suffix) + (cond (suffix=="GND"||prefix==nil suffix) + (prefix!="" (sprintf nil "%s%s" prefix suffix)) + (prefix=="" "") + ) + ) + +; Draw a channel bundle of wires. +; (DrawChannel metal67 e1of4 "a" (list 0:0 9.6:0 9.6:9.6 19.2:9.6 19.2:19.2 38.4:19.2)) +(defun DrawChannel (layers pattern prefix points + @key (flipX nil) (flipY nil) (isPin nil) + (startVias nil) (endVias nil) (doubleVias t) + (altLayerPatternList nil) + (guideInstName nil) (guideInst nil) (shieldM2 t) (drawShield t) + (CV (geGetEditCellView))) + (let (newpoints node width offset index x y hv + offsetX offsetY nextOffset curOffset lastLayer curLayer tmpx tmpy + curPattern nextLayer nextPattern stVias eVias segNum layer_override lastx lasty shieldDrawn + (types (ClassifyPoints points))) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + shieldDrawn = nil + + ; go through all nodes in channel + (foreach node_offset pattern + node = (car node_offset) + width = (cadr node_offset) + offset = (caddr node_offset) + layer_override = (cadddr node_offset) + newpoints = nil + index = 0 + segNum = 0 ; for multiple segment due to changing layers + lastLayer = curLayer + (foreach point points + x = (car point) + y = (cadr point) + hv = (nth index types) + (if altLayerPatternList then + ;altLayerPatternList either a list of patterns for each segments or a single one + ;if a single one it will be used for the second segment to the end + ;a nil entry in the altLayerPatternList will use the original layer and pattern + nextOffset = offset + curOffset = offset + curLayer = layers + (if length(altLayerPatternList) > 1 + then + ;current pattern + (if index >= 2 && nth(1 nth(index-2 altLayerPatternList)) + then + curLayerPattern = nth(index-2 altLayerPatternList) + curLayer = nth(0 curLayerPattern ) + curPattern = nth(1 curLayerPattern ) + (foreach cur_node_offset curPattern + (if node == (car cur_node_offset) then + curOffset = (caddr cur_node_offset) + ) + ) + ) + ;next pattern + (if index >= 1 && nth(1 nth(index-1 altLayerPatternList)) + then + nextLayer = nth(0 nth(index-1 altLayerPatternList)) + nextPattern = nth(1 nth(index-1 altLayerPatternList)) + (foreach next_node_offset nextPattern + (if node == (car next_node_offset) then + nextOffset = (caddr next_node_offset) + ) + ) + ) + else + ;single alternate pattern + altLayerPattern = nth(0 altLayerPatternList) + altLayer = nth(0 altLayerPattern) + altPattern = nth(1 altLayerPattern) + (foreach alt_node_offset altPattern + (if node == (car alt_node_offset) then + altOffset = (caddr alt_node_offset) + ) + ) + (if index <= 1 + then curLayer = layers nextLayer = (if (index == 0) layers altLayer) curOffset = offset nextOffset = altOffset + else curLayer = altLayer nextLayer = altLayer curOffset = altOffset nextOffset = altOffset + ) + ) + (if hv == "EH" || hv == "HV" then + offsetX = nextOffset + offsetY = curOffset + else + (if hv == "VE" || hv == "HE" then + offsetX = curOffset + offsetY = curOffset + else + offsetX = curOffset + offsetY = nextOffset + ) + ) + ;layer info is in the startVias to draw multiple vias + stVias = (segNum == 0 && startVias == t) + (if (caddr curLayer) != (caddr lastLayer) && length(newpoints) >= 1 then + ;switch layers if via list is different + tmpx = x + (if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0.0) + tmpy = y + (if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0.0) + newpoints = (append newpoints (list (list ((lastx+tmpx)/2.0) ((lasty+tmpy)/2.0)))) + (DrawWire lastLayer (AddSuffix prefix node) + width newpoints + ?isPin isPin ?startVias stVias ?endVias nil + ?doubleVias doubleVias ?guideInst guideInst ?flipX flipX ?flipY flipY ?pattern pattern ?CV CV) + newpoints = (list (list ((lastx+tmpx)/2.0) ((lasty+tmpy)/2.0))) + ) + lastLayer = curLayer + lastx= x+(if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0) + lasty = y+(if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0) + (if segNum == 0 && startVias && startVias!=t then + ;layer info is in the startVias to draw multiple vias + DrawVia((AddSuffix prefix node) startVias lastx:lasty + width (if (and hv!="HE" hv!="EH") "_R_V" "_R_H") ?doubleVias doubleVias ?CV CV) + stVias = nil + ) + eVias = endVias + (if segNum == length(points)-1 && endVias && endVias!=t then + ;layer info is in the endVias to draw multiple vias + DrawVia((AddSuffix prefix node) endVias lastx:lasty + width (if (and hv!="HE" hv!="EH") "_R_V" "_R_H") ?doubleVias doubleVias ?CV CV) + eVias = nil + ) + segNum++ + else + ; no alternate pattern + offsetX = offset + offsetY = offset + stVias = startVias + eVias = endVias + curLayer = layers + ) + + x = x+(if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0) + y = y+(if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0) + newpoints = (append newpoints (list (list x y))) + index = index+1 + ) + ; draw wire for this node + (DrawWire (if layer_override layer_override curLayer) + (AddSuffix prefix node) width newpoints + ?isPin isPin ?startVias stVias ?endVias eVias + ?doubleVias doubleVias ?guideInst guideInst ?flipX flipX ?flipY flipY ?pattern pattern ?CV CV) + + when( drawShield DrawBusShield(newpoints (if layer_override layer_override curLayer) prefix ?shieldM2 shieldM2) ) + + ) + + ) + t + ) + +; Draw an array of channels. Must give array_pitch for each segment +; (including "before and "after" segments), or give a single atom for +; all segments except before and after segments, which will be 0. +; +;(DrawChannelArray metal67 e1of4 "a" 0:3 (list 0 19.2 4.8 4.8 4.8 0) +; (list 0.5:2 9.6:0 9.6:9.6 38.4:9.6 38.4:19.2)) +(defun DrawChannelArray (layers pattern prefix indices array_pitch points + @key (flipX nil) (flipY nil) (isPin nil) + (startVias nil) (endVias nil) (doubleVias t) + (guideInstName nil) (guideInst nil) + (only_evens nil) (only_odds nil) (drawShield t) + (CV (geGetEditCellView))) + (let (x y o hv xoff yoff newpoints index index_list + (types (ClassifyPoints points)) + (NP (length points))) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + + ; check usage + (cond ((and (not (atom array_pitch)) (length array_pitch)!=NP+1) + (printf "ERROR: in array_pitch for %s.\nMust be either a single number or a list of N+1 pitches for an N point path.\n" prefix) + nil + )) + + ; create list of indices + index_list=(list 0) + (for i (car indices) (cadr indices) + (when (mod i 2)==0 && only_evens + index_list=(append1 index_list i) + ) + (when (mod i 2)!=0 && only_odds + index_list=(append1 index_list i) + ) + (when !only_evens && !only_odds + index_list=(append1 index_list i) + ) + ) + ; go through all channels in array + (foreach i (cdr index_list) + newpoints = nil + index = 0 + (foreach point points + x = (car point) + y = (cadr point) + o = i-(car indices) + hv = (nth index types) + xoff = (cond (hv=="VE" (GetOffset NP index array_pitch)) + (hv=="EV" (GetOffset NP index+1 array_pitch)) + (hv=="VH" (GetOffset NP index array_pitch)) + (hv=="HV" (GetOffset NP index+1 array_pitch)) + (hv=="EH" (GetOffset NP index array_pitch)) + (hv=="HE" (GetOffset NP index+1 array_pitch))) + x = x+o*xoff*(if flipX -1 1) + yoff = (cond (hv=="VE" (GetOffset NP index+1 array_pitch)) + (hv=="EV" (GetOffset NP index array_pitch)) + (hv=="VH" (GetOffset NP index+1 array_pitch)) + (hv=="HV" (GetOffset NP index array_pitch)) + (hv=="EH" (GetOffset NP index+1 array_pitch)) + (hv=="HE" (GetOffset NP index array_pitch))) + y = y+o*yoff*(if flipY -1 1) + newpoints = (append newpoints (list (list x y))) + index = index+1 + ) + + ; draw channel + (DrawChannel layers pattern (AddSuffix prefix (sprintf nil "[%d]" i)) newpoints + ?flipX flipX ?flipY flipY + ?isPin isPin ?startVias startVias ?endVias endVias ?doubleVias doubleVias + ?guideInst guideInst ?drawShield busShield ?CV CV) + ) + ) + t + ) + +; get the nth array_pitch, or return 0/array_pitch if its an atom +(defun GetOffset (num_points index array_pitch) + (if (atom array_pitch) then + (if (or index==0 index==num_points) then 0 + else array_pitch) + else (nth index array_pitch) + ) + ) + +; select by BusPattern +(defun SelectPattern (name @key (CV (geGetEditCellView))) + (let (prop found) + found = 0 + (foreach obj CV->shapes + prop = (GetProp obj "BusPattern" nil) + (cond ((and obj->objType=="path" prop==name) + (geSelectObject obj) + found = found+1 + ) + ) + ) + found + ) + ) + +; select by BusPrefix +(defun SelectPrefix (name @key (CV (geGetEditCellView))) + (let (prop found) + found = 0 + (foreach obj CV->shapes + prop = (GetProp obj "BusPrefix" nil) + (cond ((and obj->objType=="path" prop==name) + (geSelectObject obj) + found = found+1 + ) + ) + ) + found + ) + ) + +; get list of waypoints and layers from (optionally) named shapes +(defun GetPaths (name @key (guideInstName nil) (CV (geGetEditCellView))) + (let (paths shapes pattern pre isPin startVias endVias flipX flipY pitch double shield rotate props) + paths = nil + shapes = (geGetSelSet) + (cond (guideInstName!=nil CV = (GetGuideInst nil guideInstName)->master)) + (cond (shapes==nil shapes = CV->shapes)) + (foreach obj shapes + pattern = (GetProp obj "BusPattern" nil) + pre = (GetProp obj "BusPrefix" "") + isPin = (GetProp obj "BusPin" nil) + startVias = (GetProp obj "BusStartVias" nil) + endVias = (GetProp obj "BusEndVias" nil) + flipX = (GetProp obj "BusFlipX" nil) + flipY = (GetProp obj "BusFlipY" nil) + pitch = (GetProp obj "BusArrayPitch" TrackPitch) + double = (GetProp obj "BusDoubleVias" nil) + shield = (GetProp obj "DrawBusShields" nil) + rotate = (GetProp obj "RotateMetalOrientation" nil) + props = (list pattern obj->lpp pre isPin startVias endVias flipX flipY pitch double shield rotate) + (cond ((and obj->objType=="path" pattern!=nil (or name==nil pattern==name)) + paths = (cons (list props obj->points) paths)) + ) + ) + paths + ) + ) + +; create bus properties if necessary +(defun CreateBusProps (@key (paths nil)) + (let (pattern prefix pin flipX flipY startVias endVias doubleVias drawShield rotateMetals) + paths = (if paths==nil (geGetSelSet) paths) + (foreach obj paths + (cond (obj->objType=="path" + pattern = (GetProp obj "BusPattern" "") + prefix = (GetProp obj "BusPrefix" "") + pin = (GetProp obj "BusPin" nil) + flipX = (GetProp obj "BusFlipX" nil) + flipY = (GetProp obj "BusFlipY" nil) + startVias = (GetProp obj "BusStartVias" nil) + endVias = (GetProp obj "BusEndVias" nil) + pitch = (GetProp obj "BusArrayPitch" TrackPitch) + doubleVias = (GetProp obj "BusDoubleVias" t) + drawShield = (GetProp obj "DrawBusShields" t) + rotateMetals = (GetProp obj "RotateMetalOrientation" nil) + + ; delete properties + (dbDeletePropByName obj "BusPattern") + (dbDeletePropByName obj "BusPrefix") + (dbDeletePropByName obj "BusPin") + (dbDeletePropByName obj "BusFlipX") + (dbDeletePropByName obj "BusFlipY") + (dbDeletePropByName obj "BusStartVias") + (dbDeletePropByName obj "BusEndVias") + (dbDeletePropByName obj "BusArrayPitch") + (dbDeletePropByName obj "BusDoubleVias") + (dbDeletePropByName obj "DrawBusShields") + (dbDeletePropByName obj "RotateMetalOrientation") + + ; set new properties + (dbReplaceProp obj "BusPattern" "string" pattern) + (dbReplaceProp obj "BusPrefix" "string" prefix) + (dbReplaceProp obj "BusPin" "boolean" pin) + (dbReplaceProp obj "BusFlipX" "boolean" flipX) + (dbReplaceProp obj "BusFlipY" "boolean" flipY) + (dbReplaceProp obj "BusStartVias" "boolean" startVias) + (dbReplaceProp obj "BusEndVias" "boolean" endVias) + (dbReplaceProp obj "BusArrayPitch" "list" pitch) + (dbReplaceProp obj "BusDoubleVias" "boolean" doubleVias) + (dbReplaceProp obj "DrawBusShields" "boolean" drawShield) + (dbReplaceProp obj "RotateMetalOrientation" "boolean" rotateMetals) + )) + ) + ) + t + ) + +; set the BusPattern property, create other properties if necessary +(defun SetPattern (pattern @key (paths nil)) + (let (pat) + paths = (if paths==nil (geGetSelSet) paths) + (foreach obj paths + (cond (obj->objType=="path" + pat = (if pattern pattern (GetProp obj "BusPattern" "e1of4")) + (CreateBusProps ?paths (list obj)) + (dbReplaceProp obj "BusPattern" "string" pat) + ) + ((or obj->objType=="rect" obj->objType=="polygon") + (CreateObsProps ?shapes (list obj)) + ) + ) + ) + t + ) + ) + +; eliminate degenerate segments from points +(defun CanonicalizePoints (points) + (let (newpoints last next point (len (length points))) + newpoints = (append newpoints (list (nth 0 points))) ; first point + (for i 1 len-2 + last = (nth i-1 points) + point = (nth i points) + next = (nth i+1 points) + (cond ((and (not (almostEqual (car last) (car next))) + (not (almostEqual (cadr last) (cadr next)))) + newpoints = (append newpoints (list point)))) + ) + newpoints = (append newpoints (list (nth len-1 points))) ; last point + ) + ) + +; move way points +(defun OffsetPoints (points dx dy) + (let (newpoints p) + (for i 0 (length points)-1 + p = (nth i points) + p = (list (car p)+dx (cadr p)+dy) + newpoints = (append newpoints (list p)) + ) + newpoints + ) + ) + +; offset some of the points +(defun OffsetSomePoints (points from to dx dy) + (let (newpoints apply p) + (for i 0 (length points)-1 + apply = (and i>=from i<=to) + p = (nth i points) + p = (list (car p)+dx*(if apply!=nil 1 0) (cadr p)+dy*(if apply!=nil 1 0)) + newpoints = (append newpoints (list p)) + ) + newpoints + ) + ) + +; move paths +(defun OffsetPaths (paths dx dy) + (let (newpaths props points) + (foreach path paths + props = (car path) + points = (cadr path) + newpaths = (cons (list props (OffsetPoints points dx dy)) newpaths)) + newpaths + ) + ) + +; move only some points of paths +(defun OffsetSomePointsOfPaths (paths from to dx dy) + (let (newpaths props points) + (foreach path paths + props = (car path) + points = (cadr path) + newpaths = (cons (list props (OffsetSomePoints points from to dx dy)) newpaths)) + newpaths + ) + ) + +; translate path layer to metal layers, or use specified layers +(defun ChooseLayers (layers pathlayer @key (rotateMetals nil)) + (cond (layers!=nil layers) + ((and layers==nil busKeepout==nil busTopMetal==nil) + (cond ((pathlayer==BusPath12) if(rotateMetals then BusMetal21 else BusMetal12)) + ((pathlayer==BusPath23) if(rotateMetals then BusMetal32 else BusMetal23)) + ((pathlayer==BusPath34) if(rotateMetals then BusMetal43 else BusMetal34)) + ((pathlayer==BusPath45) if(rotateMetals then BusMetal54 else BusMetal45)) + ((pathlayer==BusPath56) if(rotateMetals then BusMetal65 else BusMetal56)) + ((pathlayer==BusPath67) if(rotateMetals then BusMetal76 else BusMetal67)) + (t (printf "ERROR: unrecognized bus lpp (%s %s)\n" + (car pathlayer) (cadr pathlayer)) nil) + )) + ((and layers==nil busKeepout==nil busTopMetal==t) + (cond ((pathlayer==BusPath12) BusMetal2) + ((pathlayer==BusPath23) BusMetal3) + ((pathlayer==BusPath34) BusMetal4) + ((pathlayer==BusPath45) BusMetal5) + ((pathlayer==BusPath56) BusMetal6) + ((pathlayer==BusPath67) BusMetal7) + (t (printf "ERROR: unrecognized bus lpp (%s %s)\n" + (car pathlayer) (cadr pathlayer)) nil) + )) + ((and layers==nil busKeepout==t) + (cond ((layer==BusPath12) if(rotateMetals then BusKeepout21 else BusKeepout12)) + ((layer==BusPath23) if(rotateMetals then BusKeepout32 else BusKeepout23)) + ((layer==BusPath34) if(rotateMetals then BusKeepout43 else BusKeepout34)) + ((layer==BusPath45) if(rotateMetals then BusKeepout54 else BusKeepout45)) + ((layer==BusPath56) if(rotateMetals then BusKeepout65 else BusKeepout56)) + ((layer==BusPath67) if(rotateMetals then BusKeepout76 else BusKeepout67)) + (t (printf "ERROR: unrecognized bus lpp (%s %s)\n" + (car layer) (cadr layer)) nil) + )) + ) + ) + +; pick which bus prefix to use +(defun ChoosePrefix (prefix path_prefix) + (cond + ((and path_prefix!=nil path_prefix!="") path_prefix) + ((and prefix!=nil prefix!="") prefix) + ("") + ) + ) + +; draw multiple channels +(defun DrawChannels (layers pattern prefix paths + @key (guideInstName nil) (guideInst nil) (CV (geGetEditCellView))) + (let (props points layer isPin startVias endVias doubleVias flipX flipY busShield rotateMetals + patlist prelist pre buspat) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + + ; process guide paths + (cond ((or paths==nil (atom paths)) + paths = (GetPaths paths ?CV (if guideInst->master guideInst->master CV)))) + (foreach path paths + props = (car path) + points = (cadr path) + patlist = (parseString (nth 0 props) " ") + layer = (nth 1 props) + prelist = (parseString (nth 2 props) " ") + isPin = (nth 3 props) + startVias = (nth 4 props) + endVias = (nth 5 props) + flipX = (nth 6 props) + flipY = (nth 7 props) + doubleVias = (nth 9 props) + busShield = (nth 10 props) + rotateMetals = (nth 11 props) + + ; iterate over BusPattern/BusPrefix lists + (foreach pat patlist + pre = (ChoosePrefix prefix (car prelist)) + prelist = (cdr prelist) + buspat = (if pattern==nil (MapBusPattern pat) pattern) + (when (and buspat pre) + (DrawChannel (ChooseLayers layers layer ?rotateMetals rotateMetals) + buspat pre points + ?flipX flipX ?flipY flipY ?isPin isPin + ?startVias startVias ?endVias endVias + ?doubleVias doubleVias + ?guideInst guideInst ?drawShield busShield ?CV CV) + ) + ) + ) + ) + t + ) + +; draw multiple channel arrays +(defun DrawChannelArrays (layers pattern prefix indices array_pitch paths + @key (guideInstName nil) (guideInst nil) + (only_evens nil) (only_odds nil) + (CV (geGetEditCellView))) + (let (props points layer isPin startVias endVias doubleVias flipX flipY + pitch busShield rotateMetals + patlist prelist pre buspat lo hi lohi options evens odds) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName ?CV CV) + + ; look for array bus patterns + (rexCompile "^\\(.*\\)\\[\\([0-9]+\\)[\\.]*\\([0-9]*\\)\\]$") + + ; process all guide paths + (cond ((or paths==nil (atom paths)) + paths = (GetPaths paths ?CV (if guideInst->master guideInst->master CV)))) + (foreach path paths + props = (car path) + points = (cadr path) + patlist = (parseString (nth 0 props) " ") + layer = (nth 1 props) + prelist = (parseString (nth 2 props) " ") + isPin = (nth 3 props) + startVias = (nth 4 props) + endVias = (nth 5 props) + flipX = (nth 6 props) + flipY = (nth 7 props) + pitch = (if array_pitch==nil (nth 8 props) array_pitch) + doubleVias = (nth 9 props) + busShield = (nth 10 props) + rotateMetals = (nth 11 props) + + ; iterate over BusPattern/BusPrefix lists + (for n 0 (length patlist)-1 + pat = (nth n patlist) + pre = (if prelist (nth (mod n (length prelist)) prelist) nil) + pre = (ChoosePrefix prefix pre) + + ; default options + evens = only_evens + odds = only_odds + lohi = indices + + ; process pattern options (pattern:opt1:opt2:...) + (unless pattern + options = (parseString pat ":") + pat = (car options) + options = (cdr options) + (while options + (cond ((car options)=="even" evens=t) + ((car options)=="odd" odds=t) + ) + options = (cdr options) + ) + ) + + ; pick pattern and array range automatically + (when (and pattern==nil lohi==nil (rexExecute pat)) + pat = (rexSubstitute "\\1") + lo = (rexSubstitute "\\2") + hi = (rexSubstitute "\\3") + (cond (hi=="" hi=(atoi lo)-1 lo=0) + (t hi=(atoi hi) lo=(atoi lo)) + ) + lohi = (list lo hi) + ) + buspat = (if pattern==nil (MapBusPattern pat) pattern) + + ; draw + (when (and buspat pre lohi) + (DrawChannelArray (ChooseLayers layers layer ?rotateMetals rotateMetals) + buspat pre lohi pitch points + ?flipX flipX ?flipY flipY ?isPin isPin + ?startVias startVias ?endVias endVias + ?doubleVias doubleVias + ?guideInst guideInst + ?only_evens evens ?only_odds odds ?drawShield busShield) + ) + ) + ) + ) + t + ) + +; highlight overlaps of paths on the same metal layer +(defun FindBusOverlaps (@key (CV (geGetEditCellView))) + (let (any_overlap bbox xy0 xy1 x0 y0 x1 y1 overlaps writable) + any_overlap=nil + if( CV then + writeable=nil; + if(CV~>mode == "r" then + writeable=nil + else + writable=t + ) + any_overlap = nil + if(writable (geDeleteAllMarker CV)) + (foreach shape CV->shapes + (cond (((isWiringPath shape) && ( writable || ! any_overlap ) ) + bbox = shape->bBox + xy0 = (car bbox) + xy1 = (cadr bbox) + x0 = (car xy0) + y0 = (cadr xy0) + x1 = (car xy1) + y1 = (cadr xy1) + bbox = (list x0+0.005:y0+0.005 x1-0.005:y1-0.005) + overlaps = (dbGetOverlaps CV bbox shape->lpp 0) + (foreach obj overlaps + (cond ((and (isWiringPath obj) obj!=shape) + any_overlap = t + if(writable (geCreateMarker obj "warning" "bus" "overlap" "")))) + ) + ) + ) + ) + ) + any_overlap + ) + ) + +; Create a channel of sub-channels. Examples: +; chan = (DefChan (list (list prefix channel offset) ...)) +; datatail = (DefChan (let (chan channels) +; (for i 0 15 +; chan = (list (sprintf nil ".D[%d]" i) smr_e1of4 TrackPitch*i) +; channels = (cons chan channels)) +; chan = (list ".T" smr_e1of2 TrackPitch*16) +; channels = (cons chan channels) +; channels)) +(defun DefChan (channels) + (let (newchan newrail prefix pattern offset newname) + (foreach chan channels + prefix = (car chan) + pattern = (cadr chan) + offset = (caddr chan) + layer_override = (cadddr chan) + (foreach rail pattern + newname = (if (car rail)=="GND" "GND" + (sprintf nil "%s%s" prefix (car rail))) + newrail = (list newname (cadr rail) + (caddr rail)+offset layer_override) + newchan = (append newchan (list newrail)) + ) + ) + newchan + ) +) + +; Round the offsets in a channel definition (suitable for DefChan) to multiple +; of pitch, and return a new channel definition (suitable for DefChan) +(defun AlignDefChan (pitch channels) + (mapcar + (lambda (chan) + (list (car chan) + (cadr chan) + (truncate (caddr chan)/pitch)*pitch ; or MathRoundToNearest? + (cadddr chan))) + channels)) + +; Expand array elements into a defchan +(defun DefChanArray (pattern indices array_pitch) + (let (chan channels) + channels = nil + (for i (car indices) (cadr indices) + chan = (list (sprintf nil "[%d]" i) pattern i*array_pitch) + channels = (cons chan channels) + ) + (DefChan channels) + ) + ) + +(defun BuildDefChanList ( oldlist name array type offset increment @key (use_dots t) ) + (let (namelist newlist i dot) + (if use_dots then dot = "." else dot = "") + (if array <= 1 then + namelist = (list (sprintf nil "%s%s" dot name) ) + else + namelist = (list (sprintf nil "%s%s[0]" dot name) ) + (for i 1 array-1 + namelist = (append1 namelist (sprintf nil "%s%s[%d]" dot name i) ) + ) + ) + i=0 + (foreach newname namelist + (if !newlist then + (if !oldlist then + newlist = (list (list newname type offset) ) + else + newlist = (append1 oldlist (list newname type offset) ) + ) + else + i=i+1 + newlist = (append1 newlist (list newname type offset+i*increment) ) + ) + ) + newlist + )) + +; load wires.il for currently edited cellview +(defun LoadWires (@key (CV (geGetEditCellView))) + (BusDefaults) + (let (fl port Outfl outfl h txt var1 var2 text CN Cellname lngth Initial k i j finalpath initialpath FinalPath modtime variable1 variable2 Variable2 Match Initialize_wires l FileFound) + i=0 + l=0 + Match=0 + Cellname=(NameGetCellPathFromCellName CV->cellName) + piece=parseString( Cellname "/" ) + lngth=length(piece) + println(Cellname) + Initial=nth(1 piece) + finalpath="" + for(j 6 lngth-1 + FileFound=0 + Initialize_wires=0 + for(i 0 j + initialpath=nth(i piece) + finalpath=strcat(finalpath "/" initialpath) + i=i+1) + FinalPath=strcat(finalpath "/" "wires.il") + modtime = (fileTimeModified FinalPath) + when(modtime!=nil + when((Startloadwires==0) + load(FinalPath) + printf("Loading %s \n" FinalPath) + wires_modtime[Startloadwires]=list(FinalPath modtime) + Startloadwires=Startloadwires+1 + ) + when((Startloadwires!=0) + for(l 0 length(wires_modtime)-1 + variable1=car(wires_modtime[l]) + variable2=cadr(wires_modtime[l]) + when((variable1!=FinalPath) + FileFound=1 + ) + when((variable1==FinalPath)&&(modtime>variable2) + load(FinalPath) + printf("Loading %s \n" FinalPath) + wires_modtime[l]=list(FinalPath modtime) + Initialize_wires=1 + ) + when((variable1==FinalPath)&&(modtime<=variable2) + Initialize_wires=1 + ) + l=l+1 + ) + + when( FileFound == 1 && Initialize_wires == 0 + load(FinalPath) + printf("Loading %s \n" FinalPath) + wires_modtime[Startloadwires]=list(FinalPath modtime) + Startloadwires=Startloadwires+1 + ) + )) + l=0 + j=j+1 + finalpath="" + i=0 + ) + + ;always load the primary cell's file + FinalPath=(sprintf nil "%s/wires.il" + (NameGetCellPathFromCellName CV->cellName)) + (when (isFile FinalPath) + (load FinalPath) + ) + ) + ) + +; load a file given a relative path from the cell directory (i.e. "../wires.il") +(defun LoadRelative (path @key (CV (geGetEditCellView))) + (let (dir file) + dir = (NameGetCellPathFromCellName CV->cellName) + file = (sprintf nil "%s/%s" dir path) + (load file) + ) + ) + +; load then draw wires.il for currently edited cellview +(defun DrawWires (@key (CV (geGetEditCellView))) + (defun DrawAll () + (printf "Default DrawAll: DrawTracks with paths in current cellview.\n") + busPatterns = (append busPatterns defchan_patterns) + (DrawTracks) + (DrawObstructions) + t + ) + (cond ((IsGuideInst CV) + (printf "Can't draw wires inside the guide instance\n")) + (t + (LoadWires) + (DrawAll) + (when (dbFindAnyInstByName CV "autobuswires") + (DrawChannels nil nil nil nil ?guideInstName "autobuswires") + ) + ) + ) + ) + +; fix up pin names by using labels attached to them +(defun FixPinNames (@key (CV (geGetEditCellView))) + (let () + (foreach shape CV->shapes + (cond ((and shape->objType=="label" shape->parent!=nil) + (dbCreatePin (MakeNet CV shape->theLabel) shape->parent) + ) + ) + ) + ) + t + ) + +; flatten any subcecells with .wires. in its cell name, then delete guide layers +(defun FlattenWiringSubcells (@key (CV (geGetEditCellView))) + (let (progress) + leSetAllLayerVisible(t) + + ; flatten wiring subcells + (rexCompile "\\.wires\\.") + progress = t + (while progress + progress = nil + (foreach inst CV->instances + (cond ((and inst->objType=="inst" (rexExecute inst->cellName)) + (dbFlattenInst inst 1 nil t t) + progress = t + ) + ) + ) + ) + + ; delete guide paths + (foreach shape CV->shapes + (cond ((and shape->objType=="path" + (or shape->lpp==BusPath23 + shape->lpp==BusPath34 + shape->lpp==BusPath45 + shape->lpp==BusPath56 + shape->lpp==BusPath67)) + (dbDeleteObject shape) + ) + ) + ) + + ; slot paths + (SlotPaths) + + ; fix pins + (FixPinNames) + ) + t + ) + +; chop all shapes with given chop bbox on specified layer +(defun ChopPaths (CV bbox layerName @key (onlyGND nil)) + (let (shapes x0 y0 x1 y1 chop) + shapes = (dbGetOverlaps CV bbox (list layerName "drawing") 0) + (foreach shape shapes + (cond ((and (isMetalDrawing shape->layerName shape->purpose) + shape->layerName==layerName + shape->objType=="path" + (or !onlyGND shape->net->name=="GND") + (IsBusObject shape)) + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + chop = (list x0:y0 x1:y0 x1:y1 x0:y1) + (leChopShape shape chop t t) + ) + ) + ) + ) + t + ) + +; chop all paths using "slot" rectangles in specified subcell +(defun SlotPathsSubcell (CV inst) + (let (transform bbox) + transform = (geGetInstTransform inst) + (foreach shape inst->master->shapes + (cond ((and shape->objType=="rect" + (isMetalSlot shape->layerName shape->purpose)) + bbox = (geTransformUserBBox shape->bBox transform) + (ChopPaths CV bbox shape->layerName) + ) + ) + ) + ) + t + ) + +; chop all paths using rectangles with "slot" purpose in all subcells +(defun SlotPaths (@key (CV (geGetEditCellView))) + (let (bbox) + + ; process subcell slot layers + (foreach inst CV->instances + (cond (inst->libName!=TechLibName (SlotPathsSubcell CV inst))) + ) + + ; process then delete top level slot layers + (foreach shape CV->shapes + (cond ((and shape->objType=="rect" + (isMetalSlot shape->layerName shape->purpose)) + bbox = shape->bBox + (ChopPaths CV bbox shape->layerName) + (dbDeleteObject shape) + ) + ) + ) + ) + t + ) + +; Alternate version of SlotPaths meant to be added to DrawAll. Looks +; for "buscut" purpose in buswires instance, and only chops GND +; shielding wires. Can include in DrawAll of wires.il +(defun SlotGND (@key (guideInst nil) (guideInstName nil) (CV (geGetEditCellView))) + guideInst = (GetGuideInst guideInst guideInstName) + (foreach shape guideInst->master->shapes + (when (isMetalSlot shape->layerName shape->purpose) + (ChopPaths CV shape->bBox shape->layerName ?onlyGND t) + ) + ) + t + ) + +; mark a list of wiring shapes with marker paint +(defun MarkWires (shapes) + (foreach shape shapes + (cond ((isWiringPath shape) + (geCreateMarker shape "warning" "bus" "length" ""))) + ) + t + ) + +; create BusMark property and set to t +(defun SetBusMark (CV) + (foreach shape CV->shapes + (cond ((isWiringPath shape) + (dbReplaceProp shape "BusMark" "boolean" t)))) + (rexCompile ".*VIA[1-8][1-8].*") + (foreach inst CV->instances + (cond ((or (rexExecute inst->cellName) (isWiringContact inst)) + (dbReplaceProp inst "BusMark" "boolean" t)))) + t + ) + +; create BusMark property and set to t for a list of objects +(defun SetBusMarkForObjects (objects) + (foreach obj objects (dbReplaceProp obj "BusMark" "boolean" t)) + t + ) + +; delete BusMark property +(defun ClearBusMark (CV) + (foreach shape CV->shapes + (cond ((isWiringPath shape) + (dbDeletePropByName shape "BusMark")))) + (foreach inst CV->instances + (cond ((isWiringContact inst) + (dbDeletePropByName inst "BusMark")))) + t + ) + +; find subcell pins connected to set of wires +(defun ConnectedSubcellPins (CV objects) + (let (connected overlaps inst pin layerName bbox) + (foreach obj objects + (cond (obj->objType=="path" + overlaps = (dbGetOverlaps CV obj->bBox (list obj->layerName "net") 1:1) + overlaps = (append overlaps (dbGetOverlaps CV obj->bBox (list obj->layerName "drawing") 1:1)) + overlaps = (append overlaps (dbGetOverlaps CV obj->bBox (list obj->layerName "pin") 1:1)) + (foreach overlap overlaps + (cond ((atom overlap)==nil + inst = (car overlap) + pin = (cadr overlap) + (cond ((and pin->pin !(isWiringContact inst)) + connected = (append connected (list (list inst pin))) + ) + ) + ) + ) + ) + ) + ((isWiringContact obj) + (foreach lpp obj->master->lpps + layerName = lpp->layerName + bbox = (list obj->xy obj->xy) + overlaps = (dbGetOverlaps CV bbox (list layerName "net") 1:1) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "drawing") 1:1)) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "pin") 1:1)) + (foreach overlap overlaps + (cond ((atom overlap)==nil + inst = (car overlap) + pin = (cadr overlap) + (cond ((and pin->pin !(isWiringContact inst)) + connected = (append connected (list (list inst pin))) + ) + ) + ) + ) + ) + ) + ) + ) + ) + connected + ) + ) + +; returns all wiring connected to a subcell pin +(defun ConnectedWiringFromSubcellPin (CV inst pin) + (let (connected overlaps transform bbox) + transform = (geGetInstTransform inst) + bbox = (geTransformUserBBox pin->bBox transform) + overlaps = (dbGetOverlaps CV bbox) + (foreach overlap overlaps + (cond ((areOverlappingObjectsConnected pin overlap) + connected = (append connected (ConnectedWiring CV overlap))) + ) + ) + connected + ) + ) + +; exchange L fpr R pins +(defun SwapLeftRightPins (inst pin) + (let (name term) + name = pin->net->name + (cond ((substring name 1 1)=="L" + name = (strcat "R" (substring name 2)) + term = (dbFindTermByName inst->master name) + pin = (car term->pins) + pin->fig) + (t nil) + ) + ) + ) + +; name instances of buffers encountered start at initial inst and pin +(defun NameBuffersRecursive (CV inst pin prefix index) + (let (wires inst_pins newinst newpin nextpin newname oldinst) + (cond ((inst==nil) wires = (ConnectedWiring CV pin)) + ((inst!=nil) wires = (ConnectedWiringFromSubcellPin CV inst pin)) + ) + (MarkWires wires) + inst_pins = (ConnectedSubcellPins CV wires) + (foreach inst_pin inst_pins + newinst = (car inst_pin) + newpin = (cadr inst_pin) + nextpin = (SwapLeftRightPins newinst newpin) + (cond ((and newinst->viewName=="wiring" newinst!=inst nextpin!=nil) + ; give this instance its proper name + (printf "%s -> %s[%d]\n" newinst->name prefix index) + newname = (sprintf nil "%s[%d]" prefix index) + oldinst = (dbFindAnyInstByName CV newname) + (cond (oldinst!=nil + oldinst->name = (sprintf nil "old_%s" oldinst->name) + ) + ) + newinst->name = newname + ; search for more buffers + (NameBuffersRecursive CV newinst nextpin prefix index+1)) + ) + ) + ) + t + ) + +; name instances of buffers encountered starting after initial instName and pinName +; must call SetBusMark before processing a non-conflicting set of these +(defun NameBuffers (instName pinName prefix @key (CV (geGetEditCellView))) + (let (inst term pin) + (cond ((instName!=nil) ; start with a subcell pin + inst = (dbFindAnyInstByName CV instName) + (cond ((or inst!=nil instName==nil) + term = (dbFindTermByName inst->master pinName) + pin = (car term->pins)->fig + (cond (pin!=nil + (NameBuffersRecursive CV inst pin prefix 0)) + (t + (printf "ERROR: can't find pin %s in instance %s\n" pinName instName)) + ) + ) + (t + (printf "ERROR: can't find instance %s\n" instName) + ) + ) + ) + ((instName==nil) ; start with top level pin + term = (dbFindTermByName CV pinName) + pin = (car term->pins)->fig + (cond (pin!=nil + (NameBuffersRecursive CV nil pin prefix 0)) + (t + (printf "ERROR: can't find pin %s\n" pinName)) + ) + ) + ) + ) + t + ) + +; infer SPEC subtypes from dfII, also list unique wiring-view cell types +(defun ScanSubtypes (@key (CV (geGetEditCellView))) + (let (file temp type subtypes types last) + + ; find wiring subcells + (foreach inst CV->instances + (cond (inst->viewName=="wiring" + temp = (parseString inst->cellName ".") + type = nil + (for i 0 (length temp)-2 + type = (append type (list (nth i temp))) + ) + type = (buildString type ".") + types = (cons inst->cellName types) + temp = (sprintf nil " %s :>\n %s %s;" + type inst->cellName inst->name) + subtypes = (cons temp subtypes) + ) + ) + ) + + ; sort and write subtypes + subtypes = (sort subtypes nil) + file = (outfile (sprintf nil "%s.subtypes" CV->cellName "w")) + (foreach subtype subtypes (fprintf file "%s\n" subtype)) + (close file) + + ; sort and write types + types = (sort types nil) + file = (outfile (sprintf nil "%s.types" CV->cellName "w")) + last = nil + (foreach type types + (cond (type!=last (fprintf file "%s\n" type))) + last = type + ) + (close file) + ) + t + ) + +; quickly scan pins to a userpins.il file +(defun ScanPins (@key (CV (geGetEditCellView))) + (let (file bbox x0 y0 x1 y1 name str pins) + (foreach obj CV->shapes + (cond (obj->pin + bbox = obj->bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + name = obj->net->name + str = (sprintf nil "(PinPlace \"%s\" (list %g:%g %g:%g) ?LPP (list \"%s\" \"%s\"))" + name x0 y0 x1 y1 obj->layerName obj->purpose) + pins = (cons str pins) + ) + ) + ) + + ; sort and write userpins.il + file = (outfile (sprintf nil "%s/userpins.il" + (NameGetCellPathFromCellName CV->cellName) "w")) + pins = (sort pins nil) + (foreach str pins (fprintf file "%s\n" str)) + (close file) + ) + t + ) + +; report what _RESET pins in wiring subcells are connected to +(defun ScanReset (@key (CV (geGetEditCellView))) + (let (file term pin wiring str resets name sub) + (rexCompile "^standard\\.reset\\.BUF_RESET\\.") + (SetBusMark CV) + (foreach inst CV->instances + (cond (inst->viewName=="wiring" + term = (dbFindTermByName inst->master "_RESET") + (cond (term + name = "_RESET" + + ; find wiring connected to this instances _RESET pin + pin = (car term->pins)->fig + wiring = (ConnectedWiringFromSubcellPin CV inst pin) + (SetBusMarkForObjects wiring) + + ; look for outputs of BUF_RESET's + inst_pins = (ConnectedSubcellPins CV wiring) + (foreach inst_pin inst_pins + sub = (car inst_pin) + pin = (cadr inst_pin) + (cond ((and (rexExecute sub->master->cellName) + pin->net->name=="_RES") + name = (sprintf nil "%s._RES" sub->name) + ) + ) + ) + + ; look for top level pins + (foreach obj wiring (cond (obj->pin name = obj->net->name))) + str = (sprintf nil "%s._RESET = %s" inst->name name) + + ; append to list of resets found + resets = (cons str resets) + ) + ) + ) + ) + ) + (ClearBusMark CV) + + ; sort and write userpins.il + file = (outfile (sprintf nil "%s.resets" CV->cellName "w")) + resets = (sort resets nil) + (foreach str resets (fprintf file "%s\n" str)) + (close file) + ) + t + ) + +; check a single object for a power short +(defun CheckObjectPowerShort (obj grid distance) + (let (x0 y0 x1 y1 gx0 gy0 gx1 gy1 bbox) + bbox = obj->bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + gx0 = grid * (round x0/grid) + gy0 = grid * (round y0/grid) + gx1 = grid * (round x1/grid) + gy1 = grid * (round y1/grid) + (cond ((or (and (isWiringPath obj) + (or obj->layerName==(car Metal2LPP) + obj->layerName==(car Metal4LPP) + obj->layerName==(car Metal6LPP)) + (or ((abs x0-gx0)layerName==(car Metal3LPP) + obj->layerName==(car Metal5LPP) + obj->layerName==(car Metal7LPP)) + (or ((abs y0-gy0)shapes + shorts = shorts+(CheckObjectPowerShort shape grid distance)) + (foreach inst CV->instances + shorts = shorts+(CheckObjectPowerShort inst grid distance)) + shorts + ) + ) + +; open a list of CellViews named in a file +(defun OpenCellViewsFromFile (filename viewName mode) + (let (cells file cellName libName temp CellView) + file = (infile filename) + (cond (file==nil (printf "ERROR: can't read file %s" filename)) + (t + (while (gets line file) + cellName = (StringUtilChompNewline line) + temp = (parseString cellName ".") + libName = nil + (for i 0 (length temp)-3 + libName = (append libName (list (nth i temp))) + ) + libName = (buildString libName ".") + CellView = (dbOpenCellViewByType libName cellName viewName nil mode) + (cond (CellView==nil + (printf "ERROR: can't open %s %s %s in mode %s\n" + libName cellName viewName mode)) + (t cells = (cons CellView cells)) + ) + ) + (close file) + ) + ) + cells + ) + ) + + + +; this is a bit hackish, but the idea is that you can instantiate a cell +; inside the buswires cell that contains a collection of paths from a previous +; subcell. the instance name of the subcell serves as a hierarchical prefix +; to be attached to the names. +; this seemed the best way to reuse a collection of subcell pins which are +; not all on the same layer or contain a mixture of flippings, neither of which +; can be done in a DefChan. +(defun ProcessBuswiresSubcell () + (let (wirescell wirescv subcell prefix newpath pathname newname flipx flipy) + wirescell=(GetGuideInst nil busGuideInstName) + wirescv=(nrOpenCellViewWritable wirescell->libName wirescell->cellName wirescell->viewName ?mode "a") + subcells=wirescv->instances + + ;clear any previously promoted paths + (foreach shape wirescv->shapes + (when (IsBusSubcellPath shape) + (dbDeleteObject shape) + ) + ) + + (foreach subcell subcells + prefix=subcell->name + (foreach shape subcell->master->shapes + (when shape->objType=="path" && (cadr shape->lpp)=="bus" + newpath=(dbCopyFig shape wirescv subcell->transform) + (SetBusSubcellProp newpath) + pathname=(GetProp newpath "BusPrefix" nil) + newname=(strcat prefix "." pathname) + (dbReplaceProp newpath "BusPrefix" "string" newname) + + (when subcell->orient=="MX" || subcell->orient=="R180" + flipy=(GetProp newpath "BusFlipY" nil) + (if flipy then + (dbReplaceProp newpath "BusFlipY" "boolean" nil) + else + (dbReplaceProp newpath "BusFlipY" "boolean" t) + ) + ) + (when subcell->orient=="MY" || subcell->orient=="R180" + flipx=(GetProp newpath "BusFlipX" nil) + (if flipx then + (dbReplaceProp newpath "BusFlipX" "boolean" nil) + else + (dbReplaceProp newpath "BusFlipX" "boolean" t) + ) + ) + + ) + ) + ) + ) +) + + +(defun SetBusSubcellProp (obj) + (when obj + (dbReplaceProp obj "BusSubcellPath" "boolean" t) + ) +) + +(defun IsBusSubcellPath (obj) + (let (isbus) + isbus = nil + (when obj + isbus=(dbGetPropByName obj "BusSubcellPath") + ) + isbus + ) +) + +(defun DoubleViaCorrection (point hv dir pattern flipX flipY) + let( (newpoint corrected up Flip) + corrected = nil + Flip = (flipX || flipY) && !(flipX && flipY) +; if( nth(2 car(pattern)) != 0 +; then + corrected = t + if( hv == "HV" + then + if( (dir == "P" && Flip) || (dir == "N" && !Flip) + then + newpoint = car(point)-(TrackPitch/24):cadr(point) + else + newpoint = car(point)+(TrackPitch/24):cadr(point) + ) + else + if( (dir == "P" && Flip) || (dir == "N" && !Flip) + then + newpoint = car(point)+(TrackPitch/24):cadr(point) + else + newpoint = car(point)-(TrackPitch/24):cadr(point) + ) + ) +; else +; newpoint = point +; ) + + list(newpoint corrected) + ) +) + +(defun ClassifyDirs (points) + let( ((types (ClassifyPoints points)) Idx dirs currPt comparePt) + + for( Idx 0 length(points)-1 + + when( nth(Idx types) == "VE" || nth(Idx types) == "HE" || nth(Idx types) == "EV" || nth(Idx types) == "EH" + dirs = cons(nil dirs) + ) + + when( nth(Idx types) == "HV" + currPt = nth(Idx points) + comparePt = nth(Idx+1 points) + if( cadr(currPt) < cadr(comparePt) + then + dirs = cons("P" dirs) + else + dirs = cons("N" dirs) + ) + ) + + when( nth(Idx types) == "VH" + currPt = nth(Idx points) + comparePt = nth(Idx-1 points) + if( cadr(currPt) > cadr(comparePt) + then + dirs = cons("P" dirs) + else + dirs = cons("N" dirs) + ) + ) + ) + + reverse(dirs) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus28.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus28.il new file mode 100644 index 0000000000..cc2ffa4162 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus28.il @@ -0,0 +1,151 @@ +(defun busnew () + (let (view shapes) + view = (geGetEditCellView) + fl = infile("/home/user/vjain/alpine/bus.list") + ;gets(k fl) + while(gets(k fl) != nil + text1 = parseString(k "\n") + txt=car(text1) + ;point1=car(evalstring(car(text1))) + (when (txt!="OBS") + point1=car(evalstring(car(text1))) + ;text = parseString(k "\n") + ;point=evalstring(car(text)) + gets(k fl) + text = parseString(k "\n") + point=evalstring(car(text)) + ;text1 = parseString(k "\n") + ;point1=car(evalstring(car(text1))) + x=dbCreatePath(view (list point1 "bus") point 0.06) + ;(dbReplaceProp x "BusPattern" "boolean" t) + gets(k fl) + ;s=car((wcv()->shapes)) + ;(dbReplaceProp s "BusPattern" "boolean" t) + gets(k fl) + text2 = parseString(k " \n") + point2=car(text2) + ;(dbReplaceProp x "BusPattern" "string" point2) + gets(k fl) + text3 = parseString(k " \n") + point3=car(text3) + (dbReplaceProp x "BusPattern" "string" point2) + (when (k==" \n") + (dbReplaceProp x "BusPrefix" "string" " ")) + (when (k!=" \n") + (dbReplaceProp x "BusPrefix" "string" point3)) + gets(k fl) + text4 = parseString(k " \n") + point4=car(text4) + (dbReplaceProp x "BusPin" "boolean" point4) + gets(k fl) + text5 = parseString(k " \n") + point5=car(text5) + (dbReplaceProp x "BusFlipX" "boolean" point5) + gets(k fl) + text6 = parseString(k " \n") + point6=car(text6) + (dbReplaceProp x "BusFlipY" "boolean" point6) + gets(k fl) + text7 = parseString(k " \n") + point7=car(text7) + (dbReplaceProp x "BusStartVias" "boolean" point7) + gets(k fl) + text8 = parseString(k " \n") + point8=car(text8) + (dbReplaceProp x "BusEndVias" "boolean" point8) + gets(k fl) + text9 = parseString(k " \n") + point9=evalstring(car(text9)) + (dbReplaceProp x "BusArrayPitch" "float" point9) + gets(k fl) + text10 = parseString(k " \n") + point10=car(text10) + (dbReplaceProp x "BusDoubleVias" "boolean" point10) + gets(k fl) + gets(k fl) + ) + (when (txt=="OBS") + gets(k fl) + text11 = parseString(k "\n") + point11=evalstring(car(text11)) + (when (k!="list()\n") + x=dbCreatePolygon(view (list "OBS" "bus") point11) + gets(k fl) + gets(k fl) + text1 = parseString(k " \n") + point1=car(text1) + (dbReplaceProp x "M2" "boolean" point1) + gets(k fl) + text2 = parseString(k " \n") + point2=car(text2) + (dbReplaceProp x "M3" "boolean" point2) + gets(k fl) + text3 = parseString(k " \n") + point3=car(text3) + (dbReplaceProp x "M4" "boolean" point3) + gets(k fl) + text4 = parseString(k " \n") + point4=car(text4) + (dbReplaceProp x "M5" "boolean" point4) + gets(k fl) + text5 = parseString(k " \n") + point5=car(text5) + (dbReplaceProp x "M6" "boolean" point5) + gets(k fl) + text6 = parseString(k " \n") + point6=car(text6) + (dbReplaceProp x "M7" "boolean" point6) + gets(k fl) + text7 = parseString(k " \n") + point7=car(text7) + (dbReplaceProp x "M1" "boolean" point7) + gets(k fl) + gets(k fl) + gets(k fl) + gets(k fl) + + ) + (when (k=="list()\n") + gets(k fl) + text12 = parseString(k "\n") + point12=evalstring(car(text12)) + x=dbCreateRect(view (list "OBS" "bus") point12) + gets(k fl) + text1 = parseString(k " \n") + point1=car(text1) + (dbReplaceProp x "M2" "boolean" point1) + gets(k fl) + text2 = parseString(k " \n") + point2=car(text2) + (dbReplaceProp x "M3" "boolean" point2) + gets(k fl) + text3 = parseString(k " \n") + point3=car(text3) + (dbReplaceProp x "M4" "boolean" point3) + gets(k fl) + text4 = parseString(k " \n") + point4=car(text4) + (dbReplaceProp x "M5" "boolean" point4) + gets(k fl) + text5 = parseString(k " \n") + point5=car(text5) + (dbReplaceProp x "M6" "boolean" point5) + gets(k fl) + text6 = parseString(k " \n") + point6=car(text6) + (dbReplaceProp x "M7" "boolean" point6) + gets(k fl) + text7 = parseString(k " \n") + point7=car(text7) + (dbReplaceProp x "M1" "boolean" point7) + gets(k fl) + gets(k fl) + gets(k fl) + gets(k fl) + + ) + ) +))) +;) +;close(out) +;)) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus65.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus65.il new file mode 100644 index 0000000000..6ea27a00cb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/bus65.il @@ -0,0 +1,114 @@ +;out = outfile("/home/user/vjain/alpine/bus.list") + +(defun busold () + (let (view shapes) + view = (geGetEditCellView) + out = outfile("/home/user/vjain/alpine/bus.list") + (foreach shape view->shapes + (when (shape->layerName!="OBS") + (when (shape->purpose=="bus") + ;out = outfile("/home/user/vjain/alpine/bus.list") + Pattern=(dbGetPropByName shape "BusPattern")->value + Prefix=(dbGetPropByName shape "BusPrefix")->value + Pin=(dbGetPropByName shape "BusPin")->value + FlipX=(dbGetPropByName shape "BusFlipX")->value + FlipY=(dbGetPropByName shape "BusFlipY")->value + StartVias=(dbGetPropByName shape "BusStartVias")->value + EndVias=(dbGetPropByName shape "BusEndVias")->value + ArrayPitch=((dbGetPropByName shape "BusArrayPitch")->value)/1.846 + DoubleVias=(dbGetPropByName shape "BusDoubleVias")->value + Layer=(shape->layerName) + boundingBox=(shape->bBox) + cord=(shape->points) + Width=(shape->width)/2 + bends=(shape->nPoints) + fprintf(out "%s\n" Layer) + fprintf(out "list(") + (foreach point shape->points + point1=((car point)/1.846) + point2=((cadr point)/1.846) + fprintf(out "%.2f:%.2f " point1 point2) + ) + fprintf(out ")\n") + ;fprintf(out "%s\n" Layer) + fprintf(out "bBox ") + (foreach box shape->bBox + box1=((car box)/1.846) + box2=((cadr box)/1.846) + fprintf(out "%.2f %.2f " box1 box2) + ) + fprintf(out "\n") + fprintf(out "%s \n" Pattern) + fprintf(out "%s \n" Prefix) + fprintf(out "%s \n" Pin) + fprintf(out "%s \n" FlipX) + fprintf(out "%s \n" FlipY) + fprintf(out "%s \n" StartVias) + fprintf(out "%s \n" EndVias) + fprintf(out "%.2f \n" ArrayPitch) + fprintf(out "%s \n" DoubleVias) + fprintf(out "%.2f \n" Width) + fprintf(out "%d \n" bends) + print(Pattern) + print(Prefix) + print(Pin) + print(FlipX) + print(FlipY) + print(StartVias) + print(EndVias) + print(ArrayPitch) + print(DoubleVias) + print(Layer) + print(boundingBox) + print(cord) + print(Width) + print(bends) + )) + (when (shape->layerName=="OBS") + MTWO=(dbGetPropByName shape "M2")->value + MTHREE=(dbGetPropByName shape "M3")->value + MFOUR=(dbGetPropByName shape "M4")->value + MFIVE=(dbGetPropByName shape "M5")->value + MSIX=(dbGetPropByName shape "M6")->value + MSEVEN=(dbGetPropByName shape "M7")->value + MONE=(dbGetPropByName shape "M1")->value + Layer=(shape->layerName) + fprintf(out "%s\n" Layer) + fprintf(out "list(") + (foreach point shape->points + point1=((car point)/1.846) + point2=((cadr point)/1.846) + fprintf(out "%.2f:%.2f " point1 point2) + ) + fprintf(out ")\n") + ;Layer=(shape->layerName) + ;fprintf(out "%s \n" Layer) + fprintf(out "list(") + (foreach box shape->bBox + box1=((car box)/1.846) + box2=((cadr box)/1.846) + fprintf(out "%.2f:%.2f " box1 box2) + ) + fprintf(out ")\n") + ;Layer=(shape->layerName) + ;fprintf(out "%s \n" Layer) + fprintf(out "%s \n" MTWO) + fprintf(out "%s \n" MTHREE) + fprintf(out "%s \n" MFOUR) + fprintf(out "%s \n" MFIVE) + fprintf(out "%s \n" MSIX) + fprintf(out "%s \n" MSEVEN) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + fprintf(out "%s \n" MONE) + + + + ) + +) +) + close(out) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/conductor.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/conductor.il new file mode 100644 index 0000000000..5a165c64b9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/conductor.il @@ -0,0 +1,276 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun ConductorPropogateLabelAndTerminals ( RootCellView + LabelFuncFactory + MaxDepth + LibCellsToIgnore ) + + (let ( + ( TopLabels + ( setof + Shape + ( getq RootCellView shapes ) + ( equal ( getq Shape objType ) "label" ) ) ) ) + + ( ConductorRecursivelyCopyLabels + RootCellView + RootCellView + ( list 0:0 "R0" ) + LabelFuncFactory + ( apply + LabelFuncFactory + ( list nil + nil ) ) + 0 + MaxDepth + LibCellsToIgnore ) + + + ( foreach + Shape + TopLabels + ( dbDeleteObject Shape ) ) + ) ) + +;returns a list of pairs +;terminal name, position +(defun ConductorGetTerminalNamePositionLPPs ( CellView ) + ( ListNonDestructiveMapCan + (lambda ( Terminal ) + ( mapcar + (lambda ( Pin ) + ( list ( getq ( getq Pin net ) name ) + ( list + ( RectGetCenter + ( getq ( getq Pin fig ) bBox ) ) + ( getq ( getq Pin fig ) lpp ) + ) ) ) + ( getq Terminal pins ) ) ) + ( getq CellView terminals ) ) ) + +(defun ConductorGetLabelNamePositionLPPs ( CellView ) + ( mapcar + (lambda ( Label ) + ( list ( getq Label theLabel ) + ( list + ( getq Label xy ) + ( getq Label lpp ) + ) ) ) + ( setof + Shape + ( getq CellView shapes ) + ( equal ( getq Shape objType ) "label" ) + ) ) ) + +(defun ConductorGetTerminalAndLabelNamePositionLPPs ( CellView ) + (let ( + ( PortTable ( makeTable `foo nil ) ) ) + + ( foreach + NamePositionLPP + ( append + ( ConductorGetTerminalNamePositionLPPs CellView ) + ( ConductorGetLabelNamePositionLPPs CellView ) ) + ( setarray PortTable + ( car NamePositionLPP ) + ( cadr NamePositionLPP ) ) ) + + PortTable + ) ) + + +;if a cells has borkificatified nets, we will label it's ports +;This means subcells will never +(defun ConductorRecursivelyCopyLabels ( TopLevelCellView + CellView + Transform + LabelFuncFactory + LabelFunc + Depth + MaxDepth + LibCellsToIgnore + ) + (when ( leqp Depth MaxDepth ) + + ( foreach + NamePositionLPP + ( tableToList + ( ConductorGetTerminalAndLabelNamePositionLPPs + CellView ) ) + (let ( + ( NetName + ( car NamePositionLPP ) ) + ( Position + ( dbTransformPoint + ( car ( cadr NamePositionLPP ) ) + Transform ) + ) + ( LPP + ( cadr ( cadr NamePositionLPP ) ) ) ) + + ( apply + LabelFunc + ( list NetName Position LPP ) ) ) ) + + + ( foreach + Instance + ;ignore mosaics + ( car + ( NameFilterInstances + ( setof + Instance + ( getq CellView instances ) + ( equal ( getq Instance objType ) "inst" ) ) + LibCellsToIgnore ) ) + + ( ConductorRecursivelyCopyLabels + TopLevelCellView + ( getq Instance master ) + ( dbConcatTransform + ( getq Instance transform ) + Transform ) + LabelFuncFactory + ( apply + LabelFuncFactory + ( list ( getq CellView cellName ) + ( getq Instance name ) + ) ) + ( plus 1 Depth ) + MaxDepth + LibCellsToIgnore ) ) + + ) ) + + + + + +(defun ConductorDraw ( CellView + Pin + Instance + Net + Force + ) + (let ( + ( SubCellToTopLevelTransform + ( getq Instance transform ) ) ) + (let ( + ( PinBBoxAtTopLevel + ( dbTransformBBox + ( getq ( getq Pin fig ) bBox ) + SubCellToTopLevelTransform ) ) ) + (let ( + ( LPP ( getq ( getq Pin fig ) lpp ) ) + ( SubCellView + ( getq Instance master ) ) ) + (let ( + ( Overlaps + ( dbGetTrueOverlaps + CellView + PinBBoxAtTopLevel + ( list ( car LPP ) + "drawing" ) + ( list 1 32 ) + ) ) ) + ( foreach + Overlap + Overlaps + (let ( + ( FigStack + ( reverse + ( TransformCanonicalizeInstancePath + Overlap ) ) ) ) + (let ( + ( FigInSomeCell ( car FigStack ) ) ) + + (when ( and + ( not ( listp FigInSomeCell ) ) + ( or + ( equal + FigInSomeCell->objType + "rect" ) + ( equal + FigInSomeCell->objType + "polygon" ) + ( equal + FigInSomeCell->objType + "path" ) ) ) + (let ( + ( SomeCellToTopLevelTransform + ( TransformGetTransformFromInstanceStack + ( cdr FigStack ) ) ) ) + (let ( + ( Fig + ( dbCopyFig + FigInSomeCell + CellView + SomeCellToTopLevelTransform ) ) + ) + (cond ( + ( and + ( not Force ) + ( RectIsRectInRectClose + ( getq Fig bBox ) + PinBBoxAtTopLevel + 1e-6 + ) ) + ( dbDeleteObject Fig ) + nil ) + ( + t + Fig->net = Net + t + ) ) ) ) ) ) ) ) ) ) ) ) ) + + + + +(defun Conductor ( CellView + FoldableCellLibCellPairRegExs + GNDNetName + VddNetName + ) + (let ( + ( LayoutInstanceMap + ( NameMakeInstanceMapFromCellView + CellView + FoldableCellLibCellPairRegExs ) ) ) + ( foreach Net ( getq CellView nets ) + (when ( and + ( or Local ( getq Net pins ) ) + ( not ( equal Net->name GNDNetName ) ) + ( not ( equal Net->name VddNetName ) ) ) + (let ( + ( PinInstancePairs + ( PinUtilGetConnectedPinInstancePairs_2 + CellView + CellView + LayoutInstanceMap + ( getq Net name ) + ) ) + ( Done nil ) + ) + ( foreach + PinInstancePair + PinInstancePairs + (let ( + ( Pin + ( car PinInstancePair ) ) + ( Instance + ( cadr PinInstancePair ) ) + ) + + (when ( ConductorDraw + CellView + Pin + Instance + Net + ( not Done ) + ) + ( setq Done t ) + + ) ) ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/drawdirectivekeepout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/drawdirectivekeepout.il new file mode 100644 index 0000000000..858262cb6f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/drawdirectivekeepout.il @@ -0,0 +1,37 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: DrawDirectiveKeepout +; Parameter: CellView (CVId) +; Return: DRCStatus (boolean) +; +; Draw Keepout + +defun( DrawDirectiveKeepout ( CellView ) + + + ( KeepOutDrawKeepOut + CellView + DirectiveTable + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) + ( list Metal3LPP ) ) + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) + ( list Metal2LPP ) ) + BoundaryLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + ( list GNDNetName VddNetName ) + ( list nil ) ; nil + t + nil + 0 ) + + ( dbSave CellView ) + CellView +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/fat.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/fat.il new file mode 100644 index 0000000000..6d0de2b34e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/fat.il @@ -0,0 +1,980 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/bus.il#5 $ +; $DateTime: 2006/12/09 12:58:15 $ +; $Author: lines $ +; +; User must set bundled_channels in wires.il. The syntax is a list of +; lists. The inner list starts with the BusPattern name followed by 1 +; or more BusPrefix's. For example: +; +; bundled_channels = (list (list "e1of4" "x" "y") (list "e1of2" "z")) +; +; The [lo..hi] will be expanded. + +; Export, Route, Import using CCAR with bundled channels +(defun BundledRoute + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (bottomMetal nil) ; bottom metal layer to use, or nil to use wires.il + (topMetal nil) ; top metal layer to use, or nil to use wires.il + (routeWires t) ; route regular wires in parallel with bundled channels + (SaveQuit nil) ; automatically save and quit CCAR + (Background nil) ; run in foreground or background + (viaType "c") ; via type ("c"/"min") + (subcellView "abstract_edit abstract") ; alternate views of subcells + (importView "layout_pg") ; view name to import wiring back to + (type "fat") ; routing rul/do file to use from PDK ("fat"/"fat_onepass") + (retry t) ; automatic retry + ) + (let (TEMP FulcrumPDKRoot RouterPDK DoFile RouterDoFile BundledDoFile SaveQuitStr + LCV rules options session status win flattenCV cmd) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + + ; make flatten view automatically + (when (or CV->viewName=="floorplan" CV->viewName=="prelayout") + CV = (MakeFlatten ?CV CV)) + flattenCV = CV + + ; get config settings + SaveQuit = (or SaveQuit Background) + FulcrumPDKRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + RouterPDK = (sprintf nil "%s/share/Fulcrum/cell_automation/router" FulcrumPDKRoot) + DoFile = (sprintf nil "%s/%s.do" RouterPDK type) + SaveQuitStr = (sprintf nil "-do %s/savequit.do" RouterPDK) + + ; load wires.il and set options + (LoadWires) + (unless bundled_channels (error "No bundled_channels defined in wires.il\n")) + (unless bottomMetal bottomMetal = bundled_bottom_layer) + (unless topMetal topMetal = bundled_top_layer) + + ; prepare bundled view + CV = (CreateBundledView CV routeWires subcellView ?bottomMetal bottomMetal) + + ; write do files + (when routeWires + RouterDoFile = (WriteRouterDoFile CV ?viaType viaType + ?bottomMetal bottomMetal ?topMetal topMetal)) + BundledDoFile = (WriteBundledDoFile CV ?bottomMetal bottomMetal ?topMetal topMetal + ?routeWires routeWires) + + ; options + LCV = (list CV->libName CV->cellName CV->viewName) + rules = (sprintf nil "%s/%s.rul" RouterPDK type) + options = (sprintf nil "-guidir %s -noclean -virtuoso -do %s %s -do %s %s" + TEMP BundledDoFile + (if routeWires (sprintf nil "-do %s" RouterDoFile) "") + DoFile + (if SaveQuit SaveQuitStr "")) + session = (sprintf nil "%s/%s.ses" TEMP CV->cellName) + (shell (sprintf nil "rm -f %s" session)) + + ; export + status = (iccExportCellview + ?layoutLCV LCV + ?background nil + ?exportDirectory TEMP + ?rulesFile rules + ?conductorDepth 32 + ?keepoutDepth 32 + ?pinConnection "strong" + ?optionList (list "fullConnectivity" "interLayer") + ?startICC nil) + (unless status (error "Unable to export to VCAR\n")) + + ; route + cmd = (sprintf nil "vcar %s/%s.dsn %s %s" TEMP CV->cellName options + (if Background "-nog &" "")) + (printf "%s\n" cmd) + status = nil + (while !status + status = (shell cmd) + (unless status || retry (error "VCAR failed. Inspect *.did file.\n")) + (unless status + (printf "Unable to run VCAR, retrying...\n") + (sleep 30) + ) + ) + + ; import from VCAR + (cond (Background (printf "Running in background, finish with BundledRouteImport\n")) + (t CV = (BundledRouteImport ?CV flattenCV ?importView importView)) + ) + CV + ) + ) + +; Import from VCAR and post-process +(defun BundledRouteImport + (@key (CV (geGetEditCellView)) + (importView "layout_pg") + ) + (let (TEMP session status win) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + session = (sprintf nil "%s/%s.ses" TEMP CV->cellName) + + ; import from CCAR + status = (iccImportCellview + ?layoutLCV (list CV->libName CV->cellName "bundled") + ?iccFile session + ?background nil) + (unless status (error "Unable to import from VCAR\n")) + + ; post-process the routes + CV = (FinishBundledImport CV ?importView importView) + + ; change to importView + win = (hiGetCurrentWindow) + (unless win (error "Can't change to view %s\n" importView)) + (geOpen ?window win + ?lib CV->libName + ?cell CV->cellName + ?view CV->viewName + ?viewType "maskLayout" + ?mode "a") + + ; draw new bundled bus wires only + (DrawTracks ?guideInstName "autobuswires") + + ; canonicalize net names + (CanonicalizeNets ?CV CV) + + ; execute custom function + (FinishRouterImport) + + ; save importView + (dbSave CV) + + ; create layout view + (MakeLayout ?CV CV) + CV + ) + ) + +; write FQCN_bundled.do for CCAR +(defun WriteBundledDoFile (CV @key (bottomMetal 2) (topMetal 7) (routeWires nil)) + (let (name TEMP file nets) + + ; find all matching e rails + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + + ; write CCAR do file + name = (sprintf nil "%s/%s_bundled.do" TEMP CV->cellName) + file = (outfile name "w") + (unless routeWires (fprintf file "define (class RESET_3W3S)\n")) ; make sure it exists + (fprintf file "# Bundled channel rules\n") + (fprintf file "define (class BUNDLED_CHANNEL\n") + (foreach net (BundledNets CV) (fprintf file " %s\n" net->name)) + (fprintf file ")\n") + (fprintf file "rule class BUNDLED_CHANNEL (width 2.28)\n") + (fprintf file "rule class BUNDLED_CHANNEL (clearance 0.12)\n") + (fprintf file "rule class BUNDLED_CHANNEL (pin_width_taper off)\n") + (fprintf file "rule class BUNDLED_CHANNEL (limit_way 0)\n") + (fprintf file "circuit class BUNDLED_CHANNEL (length 1.1 -1 (type ratio))\n") + (fprintf file "circuit class BUNDLED_CHANNEL (length 900 -1 (type actual))\n") + (fprintf file "circuit class BUNDLED_CHANNEL (use_via") + (for layer bottomMetal topMetal + (when layer>=3 (fprintf file " M%d_M%d_FAT" layer layer-1))) + (fprintf file ")\n") + (close file) + name + ) + ) + +; Prepare Bundled View for Export +(defun CreateBundledView (CV routeWires subcellView @key (bottomMetal 2)) + (let (bundled_nets GND Vdd) + + ; copy to bundled view + CV = (dbCopyCellView CV CV->libName CV->cellName "bundled" nil nil t) + + ; DrawBundledPins + (DrawBundledPins CV) + + ; change subcells to subcellView + (when subcellView!="" + (foreach inst CV->instances + (when inst->libName!=TechLibName + (ChangeView inst (parseString subcellView " ")) + ) + ) + ) + + ; flatten subcells and vias for CCAR + (FlattenAbstractSubcells CV) + + ; delete labels + (DeleteLabels ?CV CV) + + ; unconnect individual rails of bundled channels + (DisconnectBundledPins CV) + + ; delete non-bundled nets + (when routeWires==nil (DeleteNonBundledNets CV)) + + ; delete power supply nets + GND = (dbFindNetByName CV "GND") + (when GND (dbDeleteObject GND)) + Vdd = (dbFindNetByName CV "Vdd") + (when Vdd (dbDeleteObject Vdd)) + + ; convert unconnected shapes to keepout + (ConvertUnconnectedShapesToKeepout CV) + + ; convert preroutes to polygons instead of paths + (ConvertPreroutedPaths CV) + + ; draw M2 keepout stripes + (when bottomMetal<=2 (DrawMetal2KeepoutStripes CV)) + + ; return bundled CellView + (dbSave CV) + CV + ) + ) + +; Post-processing after import from CCAR +(defun FinishBundledImport (CV @key (importView "layout_pg")) + (let (srcCV dstCV pgCV buswires libName cellName viewName + components baseName win newobj) + libName = CV->libName + cellName = CV->cellName + viewName = CV->viewName + win = (hiGetCurrentWindow) + + ; create name of buswires cell + components = (parseString cellName ".") + baseName = (cadr (reverse components)) + buswires = (strcat libName ".wires." baseName "_autobuswires") + + ; find relevant views + dstCV = (dbOpenCellViewByType libName buswires "layout" "maskLayout" "w") + srcCV = (dbOpenCellViewByType libName cellName "bundled") + (cond (importView!=CV->viewName + pgCV = (dbCopyCellView CV libName cellName importView nil nil t)) + (t pgCV=CV) + ) + (if (and dstCV srcCV pgCV)==nil (error "Unable to open import views\n")) + + ; draw guide paths to autobuswires cell + win = (geOpen ?window win ?lib dstCV->libName + ?cell dstCV->cellName ?view dstCV->viewName + ?viewType "maskLayout" ?mode "a" ) + (DrawBundledChannels srcCV) + (dbSave srcCV) + (dbSave dstCV) + + ; import remaining wires to layout_pg view + win = (geOpen ?window win ?lib libName + ?cell cellName ?view "layout_pg" + ?viewType "maskLayout" ?mode "a") + + ; delete prerouted contacts + (DeleteDuplicateContacts srcCV) + + ; copy new wires and vias back to layout_pg + (CopyPathsAndContactsWithConnectivity srcCV pgCV) + + ; add autobuswires instance + (dbCreateInst pgCV dstCV "autobuswires" 0:0 "R0") + + ; save and return layout_pg + (dbSave pgCV) + pgCV + ) + ) + +; delete prerouted contacts in bundled view +(defun DeleteDuplicateContacts (CV) + (let (net) + (foreach contact CV->instances + (when (and contact->libName==TechLibName contact->terminals) + net = (car contact->terminals)->net + (when (and net (dbGetPropByName net "BusPrefixes")) + (dbDeleteObject contact) + ) + ) + ) + ) + t + ) + +; shortcut to add autobuswires to current CV +(defun AddAutoBusWires (@key (CV (geGetEditCellView))) + (AddBusWires ?CV CV ?name "autobuswires") + ) + +; enumerate bundled nets +(defun BundledNets (CV) + (setof net CV->nets (dbGetPropByName net "BusPrefixes")!=nil) + ) + +; flatten abstract subcells +(defun FlattenAbstractSubcells (CV) + (foreach inst CV->instances + (cond (inst->libName==TechLibName nil) + (t + (dbFlattenInst inst 1 nil t t) + ) + ) + ) + t + ) + +; disconnect shapes that overlap bundled pins +(defun DisconnectBundledPins (CV) + (let (overlaps) + (foreach net (BundledNets CV) + (foreach pin net->pins + (when (GetProp pin->fig "PinType" nil)=="BundledPin" + overlaps = (FindMetalOverlaps CV pin->fig->bBox pin->fig->layerName) + (foreach obj overlaps + (when (GetProp obj "PinType" nil)!="BundledPin" + (dbReplaceProp obj->net "BundledNet" "boolean" t) + obj->lpp = (list (car obj->lpp) "boundary") + (when obj->pin (dbDeleteObject obj->pin)) + ) + ) + overlaps = (FindContactOverlaps CV pin->fig->bBox pin->fig->layerName) + (foreach obj overlaps + (foreach term obj->terminals term->net=nil) + ) + ) + ) + ) + ) + t + ) + +; delete nets that aren't bundled +(defun DeleteNonBundledNets (CV) + (foreach net CV->nets + (when (dbGetPropByName net "BusPrefixes")==nil + (dbDeleteObject net)) + ) + t + ) + +; turn unconnected shapes into keepout +(defun ConvertUnconnectedShapesToKeepout (CV) + (let (layer purpose) + (foreach shape CV->shapes + layer = (car shape->lpp) + purpose = (cadr shape->lpp) + (when (and shape->net==nil (isMetal layer) + (or purpose=="drawing" purpose=="net" + purpose=="vdd" purpose=="gnd")) + shape->lpp = (list (car shape->lpp) "boundary") ) + ) + ) + t + ) + +; paint a grid of M2 keepout to force fat wires to be on grid +(defun DrawMetal2KeepoutStripes (CV) + (let (bBox x0 x1 y0 y1 i0 i1 j0 j1 scratchlpp1 scratchlpp2) + ; draw stripes + scratchlpp1=NRegionLPP + scratchlpp2=PRegionLPP + bBox = CV->bBox + x0 = (car (car bBox)) + x1 = (car (cadr bBox)) + y0 = (cadr (car bBox)) + y1 = (cadr (cadr bBox)) + i0 = (round (x0+0.24)/2.88) + i1 = (round (x1-0.24)/2.88) + j0 = (round (y0+0.24)/2.88) + j1 = (round (y1-0.24)/2.88) + (for i i0 i1 (dbCreateRect CV scratchlpp1 (list 2.88*i-0.18:y0 2.88*i+0.18:y1))) + + ; trim M2 stripes keepout around M2 pins + (foreach purpose (list "net" "drawing" "pin") + (leLayerSize CV (list "M2" purpose) DefaultWiringSpacing scratchlpp2) + ) + (leLayerAndNot CV scratchlpp1 scratchlpp2 Metal2byLPP) + (foreach shape CV->shapes + (when shape->lpp==scratchlpp2 (dbDeleteObject shape)) + (when shape->lpp==scratchlpp1 (dbDeleteObject shape)) + ) + ) + t + ) + +; Convert prerouted paths to polygons to distinguish them from routed wires +(defun ConvertPreroutedPaths (CV) + (foreach path CV->shapes + (when path->objType=="path" (dbConvertPathToPolygon path)) + ) + t + ) + +; search for nets of overlapping bundled pin +(defun FindOverlappingBundledShape (CV bbox lpp) + (let (overlaps overlap) + overlap = nil + overlaps = (dbGetOverlaps CV bbox lpp 0) + (foreach shape overlaps + (when (GetProp shape "PinType" nil)=="BundledPin" + overlap = shape + ) + ) + overlap + ) + ) + +; draw bundled pin +(defun DrawBundledPin (net bbox lpp pattern flip) + (let (horz x0 y0 x1 y1 x y flipX flipY rect oshape onet p prefixes patterns small) + x = (car (car bbox)) + y = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + x0 = (min x x1) + x1 = (max x x1) + y0 = (min y y1) + y1 = (max y y1) + flipX = nil + flipY = nil + small = nil + x = (x0+x1)/2 + y = (y0+y1)/2 + horz = (IsLayerHorizontal (car lpp)) + (cond (horz + y0 = (round y0/2.88-0.5)*2.88 + 0.18 + y1 = (round y1/2.88+0.5)*2.88 - 0.18 + flipY = y-y0>y1-y != flip + (when (round (x0-0.3)/2.88+0.5)>=(round (x1+0.3)/2.88-0.5) small=t) + ) + (t + x0 = (round x0/2.88-0.5)*2.88 + 0.18 + x1 = (round x1/2.88+0.5)*2.88 - 0.18 + flipX = x-x0>x1-x != flip + (when (round (y0-0.3)/2.88+0.5)>=(round (y1+0.3)/2.88-0.5) small=t) + ) + ) + (when small (printf "WARNING: pin %s at %g:%g on %s is small or poorly aligned.\n" + net->name x y (car lpp))) + bbox = (list x0:y0 x1:y1) + oshape = (FindOverlappingBundledShape CV bbox lpp) + (cond (oshape + ; combine with overlapping bundled pin + onet = oshape->net + oshape->bBox = (BBoxCombine oshape->bBox bbox) + p = (dbGetPropByName onet "BusPrefixes") + (cond ((member net->name p->value)==nil + (printf "Appending %s to same path as %s\n" net->name (car p->value)) + prefixes = (cons net->name p->value) + p = (dbGetPropByName onet "BusPatterns") + patterns = (cons pattern p->value) + (dbReplaceProp onet "BusPrefixes" "list" prefixes) + (dbReplaceProp onet "BusPatterns" "list" patterns) + ) + ) + ) + (t + ; create new bundled pin + rect = (dbCreateRect CV lpp bbox) + (dbReplaceProp rect "PinType" "string" "BundledPin") + (cond (horz (dbReplaceProp rect "FlipY" "boolean" flipY)) + (t (dbReplaceProp rect "FlipX" "boolean" flipX)) + ) + (dbCreatePin net rect) + (cond (horz rect->pin->accessDir = (list "left" "right")) + (t rect->pin->accessDir = (list "top" "bottom")) + ) + (cond ((dbGetPropByName net "BusPrefixes")==nil + bundled_nets = (cons net bundled_nets))) + (dbReplaceProp net "BusPrefixes" "list" (list net->name)) + (dbReplaceProp net "BusPatterns" "list" (list pattern)) + ) + ) + ) + t + ) + +; Expand bundled_channels for debugging +(defun MatchBundledChannelsCore (CV) + (let (names canonMap canonName patlist pattern i buspattern name net result net_tbl + railflip) + ; first pass to find net names + (foreach entry bundled_channels + patlist = (car entry) + patlist = (if (atom patlist) (list patlist) patlist) + i=0 + (foreach chan (ExpandArrayRanges (cdr entry)) + pattern = (nth (mod i (length patlist)) patlist) + i=i+1 + buspattern = (MapBusPattern pattern) + (unless buspattern (error "BusPattern %s unsupported\n" pattern)) + railflip = (BusPatternReference buspattern) + name = (sprintf nil "%s%s" chan (car railflip)) + names = (cons name names) + ) + ) + ; query cast to get canonical name mapping + canonMap = (CanonicalizeNetNames names ?CV CV) + net_tbl = (makeTable "net added" nil) + ; second pass + (foreach entry bundled_channels + patlist = (car entry) + patlist = (if (atom patlist) (list patlist) patlist) + i=0 + (foreach chan (ExpandArrayRanges (cdr entry)) + pattern = (nth (mod i (length patlist)) patlist) + i=i+1 + buspattern = (MapBusPattern pattern) + (unless buspattern (error "BusPattern %s unsupported\n" pattern)) + railflip = (BusPatternReference buspattern) + name = (sprintf nil "%s%s" chan (car railflip)) + canonName = (arrayref canonMap name) + (unless canonName (error "%s is not a local node\n" name)) + net = (dbFindNetByName CV canonName) + (unless net (error "Can't find rail %s\n" canonName)) + e = (list pattern chan buspattern net (cadr railflip)) + (unless net_tbl[net] ; uniquify list + net_tbl[net] = t + result = (append result (list e)) + ) + ) + ) + result + ) + ) + +; Pick a reference rail to detect flipX/flipY. Returns the suffix and +; a boolean for if it should be in the top half of a track. +(defun BusPatternReference (pattern) + (let (suffix flip) + (foreach rail (reverse pattern) + (when (caddr rail)!=0 && (car rail)!="GND" + suffix=(car rail) flip=(caddr rail)>0) + ) + (unless suffix suffix=(car (car pattern))) + (list suffix flip) + ) + ) + +; for user feedback +(defun MatchBundledChannels (@key (CV (geGetEditCellView))) + (LoadWires) + (foreach entry (MatchBundledChannelsCore CV) + (printf "Pattern=%s Channel=%s\n" (car entry) (cadr entry)) + ) + t + ) + +; convert to bundled pins +(defun DrawBundledPins (CV) + (let (pattern chan buspattern net cnet transform ubox) + (foreach entry (MatchBundledChannelsCore CV) + + ; extract channel information + pattern = (car entry) + chan = (cadr entry) + buspattern = (caddr entry) + net = (cadddr entry) + flip = (nth 4 entry) + (printf "Pattern=%s Channel=%s\n" pattern chan) + + ; create net for channel + cnet = (MakeNet CV chan) + + ; paint fat pins over top-level bundled pins + (foreach pin net->pins + (DrawBundledPin cnet pin->fig->bBox pin->fig->lpp pattern flip)) + + ; paint fat pins over subcell bundled pins + (foreach instTerm net->instTerms + inst = instTerm->inst + (cond (inst->libName!=TechLibName + transform = (geGetInstTransform inst) + (foreach pin instTerm->term->pins + ubox = (geTransformUserBBox + pin->fig->bBox transform) + (DrawBundledPin cnet ubox + pin->fig->lpp pattern flip) + ) + ) + ) + ) + + ; paint fat pins over prerouted nets + (foreach fig net->figs + (DrawBundledPin cnet fig->bBox fig->lpp pattern flip) + ) + ) + t + ) + ) + +; draw all declared bundled channels +(defun DrawBundledChannels (CV) + (foreach net (BundledNets CV) (DrawBundledChannel CV net)) + t + ) + +; draw just one bundled channel by channel name +(defun DrawBundledChannel (CV net) + (let (selected delpaths paths contacts overlaps + layers points xy x y flipX flipY pattern prefix) + + ; channel properties + (printf "Guide Channel=%s\n" net->name) + + ; overlapping patterns and prefixes + prefix = (buildString (dbGetPropByName net "BusPrefixes")->value " ") + pattern = (buildString (dbGetPropByName net "BusPatterns")->value " ") + + ; find paths and contacts for bundled channels + paths = (setof obj CV->shapes + (and obj->objType=="path" + obj->net==net) + ) + contacts = (setof obj CV->instances + (and obj->objType=="inst" + obj->libName==TechLibName + (BBoxGetWidth obj->bBox)>PowerGridPitch/2 + (BBoxGetHeight obj->bBox)>PowerGridPitch/2 + (or obj->cellName=="M7_M6_FAT" + obj->cellName=="M6_M5_FAT" + obj->cellName=="M5_M4_FAT" + obj->cellName=="M4_M3_FAT" + obj->cellName=="M3_M2_FAT" + ; NOTE: CCAR doesn't use FAT vias reliably! + obj->cellName=="M7_M6c" + obj->cellName=="M6_M5c" + obj->cellName=="M5_M4c" + obj->cellName=="M4_M3c" + obj->cellName=="M3_M2c" + obj->cellName=="M7_M6min" + obj->cellName=="M6_M5min" + obj->cellName=="M5_M4min" + obj->cellName=="M4_M3min" + obj->cellName=="M3_M2min") + (car obj->instTerms)->net==net ) + ) + + ; figure out if paths or contacts are flipY or flipX + (foreach path paths (MarkPath CV path)) + (foreach cont contacts (MarkContact CV cont)) + + ; draw paths + (foreach path paths + layers = (PickBundledLayers path) + points = (GetPathPoints path) + (cond (layers!=nil + flipX = (GetProp path "FlipX" nil) + flipY = (GetProp path "FlipY" nil) + (DrawGuidePath layers pattern prefix points flipX flipY) + ) + ) + ) + + ; draw contacts + (foreach cont contacts (DrawGuideContact cont pattern prefix)) + + ; delete source wires + (foreach path paths (dbDeleteObject path)) + (foreach contact contacts (dbDeleteObject contact)) + ) + t + ) + +; draw a guide path with bus properties +(defun DrawGuidePath (layer pattern prefix points flipX flipY + @key (CV (geGetEditCellView))) + (let (path) + obj = (dbCreatePath CV (list layer "bus") points 0.12 "squareFlush") + (dbReplaceProp obj "BusPattern" "string" pattern) + (dbReplaceProp obj "BusPrefix" "string" prefix) + (dbReplaceProp obj "BusPin" "boolean" nil) + (dbReplaceProp obj "BusFlipX" "boolean" flipX) + (dbReplaceProp obj "BusFlipY" "boolean" flipY) + (dbReplaceProp obj "BusStartVias" "boolean" nil) + (dbReplaceProp obj "BusEndVias" "boolean" nil) + (dbReplaceProp obj "BusArrayPitch" "float" 2.88) + (dbReplaceProp obj "BusDoubleVias" "boolean" (RecommendDoubleVias pattern)) + ) + t + ) + +; draw an optimized guide path for a contact +(defun DrawGuideContact (cont pattern chan) + (let (layers xy x y points flipX flipY metalW metalE metalN metalS dx dy) + layers = (PickBundledLayers cont) + (cond (layers!=nil + xy = cont->xy + x = (car xy) + y = (cadr xy) + metalW = (GetProp cont "MetalW" nil) + metalE = (GetProp cont "MetalE" nil) + metalN = (GetProp cont "MetalN" nil) + metalS = (GetProp cont "MetalS" nil) + flipX = (GetProp cont "FlipX" nil) + flipY = (GetProp cont "FlipY" nil) + (cond ((and metalW!=metalE metalN!=metalS) ; turn via + dx = (if metalW -1.14 1.14) + dy = (if metalS -1.14 1.14) + points = (list x+dx:y x:y x:y+dy) + (DrawGuidePath layers pattern chan points flipX flipY) + ) + (t ; stacked via or > 2 spoke + points = (list x-1.14:y x:y x:y-1.14) + (DrawGuidePath layers pattern chan points flipX flipY) + points = (list x+1.14:y x:y x:y+1.14) + (DrawGuidePath layers pattern chan points flipX flipY) + ) + ) + ) + ) + ) + t + ) + +; pick a suitable bus layer for a particular path or contact +(defun PickBundledLayers (obj) + (cond (obj->objType=="path" obj->layerName) + (obj->objType=="inst" + (cond ((setof lpp obj->master->lpps lpp->layerName=="VIA2")!=nil "M3") + ((setof lpp obj->master->lpps lpp->layerName=="VIA3")!=nil "M4") + ((setof lpp obj->master->lpps lpp->layerName=="VIA4")!=nil "M5") + ((setof lpp obj->master->lpps lpp->layerName=="VIA5")!=nil "M6") + ((setof lpp obj->master->lpps lpp->layerName=="VIA6")!=nil "M7") + (t nil) + ) + ) + ) + ) + +; copy flip properties from one object to another +(defun CopyFlipProperties (from to) + (let (flipX flipY) + flipX = (dbGetPropByName from "FlipX") + flipY = (dbGetPropByName from "FlipY") + (if flipX (dbReplaceProp to "FlipX" "boolean" flipX->value)) + (if flipY (dbReplaceProp to "FlipY" "boolean" flipY->value)) + ) + t + ) + +; mark if a path needs to be flipped +(defun MarkPath (CV path) + (let (overlaps flipX flipY pinType) + + ; find overlapping fat pins + overlaps = (FindMetalOverlaps CV path->bBox path->layerName) + + ; copy their FlipX/FlipY properties + (foreach overlap overlaps + (cond ((atom overlap) + (CopyFlipProperties overlap path) + ) + ) + ) + ) + t + ) + +; mark a contact if it needs to be flipped, and which way metal overlaps connect +(defun MarkContact (CV cont) + (let (overlaps x0 y0 x1 y1 ox0 oy0 ox1 oy1 mW mE mS mN) + (foreach lp cont->master->lpps + overlaps = (FindMetalOverlaps CV cont->bBox lp->layerName) + x0 = (car (car cont->bBox)) + y0 = (cadr (car cont->bBox)) + x1 = (car (cadr cont->bBox)) + y1 = (cadr (cadr cont->bBox)) + (foreach path overlaps + (cond ((atom path) + ox0 = (car (car path->bBox)) + oy0 = (cadr (car path->bBox)) + ox1 = (car (cadr path->bBox)) + oy1 = (cadr (cadr path->bBox)) + (CopyFlipProperties path cont) + mW = ox0x1+1.14 + mS = oy0y1+1.14 + (cond (mW + (dbReplaceProp cont "MetalW" "boolean" t) + (TrimPath path cont->xy -1.14:0) + )) + (cond (mE + (dbReplaceProp cont "MetalE" "boolean" t) + (TrimPath path cont->xy 1.14:0) + )) + (cond (mS + (dbReplaceProp cont "MetalS" "boolean" t) + (TrimPath path cont->xy 0:-1.14) + )) + (cond (mN + (dbReplaceProp cont "MetalN" "boolean" t) + (TrimPath path cont->xy 0:1.14) + )) + ) + ) + ) + ) + ) + t + ) + +; find overlaps on "drawing" "pin" or "net" purposes +(defun FindMetalOverlaps (CV bbox layerName) + (let (overlaps) + overlaps = (dbGetOverlaps CV bbox (list layerName "drawing")) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "net"))) + overlaps = (append overlaps (dbGetOverlaps CV bbox (list layerName "pin"))) + ) + ) + +; find overlaps of contacts +(defun FindContactOverlaps (CV bbox layerName) + (let (overlaps contacts) + overlaps = (dbGetOverlaps CV bbox (list layerName "drawing") 1) + (foreach overlap overlaps + (when (and (atom overlap)==nil (car overlap)->objType=="inst") + contacts = (cons (car overlap) contacts) + ) + ) + contacts + ) + ) + +; detect direction of a metal layer +(defun IsLayerHorizontal (layerName) + (or layerName=="M3" layerName=="M5" layerName=="M7") + ) + +; simplify degenerate paths, assuming only first and last points are valid +(defun GetPathPoints (path) + (let (points) + points = (list (car path->points) (nth (length path->points)-1 path->points)) + (unless (or (car (car points))==(car (cadr points)) + (cadr (car points))==(cadr (cadr points))) + (printf "WARNING: Jogged bundled path on net %s\n" (if path->net path->net->name "")) + points = (list (car path->points) (cadr path->points)) + ) + points + ) + ) + +; trim the ends of a path if it connects to a contact +(defun TrimPath (path xy dxy) + (let (newpoints) + (cond (path->objType=="path" + newpoints = nil + (foreach point path->points + (cond ((and (car point)==(car xy) (cadr point)==(cadr xy)) + point = (car point)+(car dxy):(cadr point)+(cadr dxy) + ) + ) + newpoints = (append newpoints (list point)) + ) + path->points = newpoints + ) + ) + ) + t + ) + +; expand [i..j] in a list of BusPrefix names +(defun ExpandArrayRanges (names) + (let (expanded a b c left lo hi right prefix n) + expanded=nil + (rexCompile "^\\(.*\\)\\[\\([0-9]+\\)\\.\\.\\([0-9]+\\)\\]\\(.*\\)$") + (foreach name names + (cond ((rexExecute name) + left = (rexSubstitute "\\1") + lo = (atoi (rexSubstitute "\\2")) + hi = (atoi (rexSubstitute "\\3")) + right = (rexSubstitute "\\4") + (foreach prefix (ExpandArrayRanges (list left)) + (foreach suffix (ExpandArrayRanges (list right)) + (for i lo hi + n = (sprintf nil "%s[%d]%s" prefix i suffix) + expanded = (append expanded (list n)) + ) + ) + ) + ) + (t (cdr a)==nil expanded = (append expanded (list name))) + ) + ) + expanded + ) + ) + + + +(defun FindMBUFChannels (LegalMBUFs @key (CV (geGetEditCellView))) + (let (nets iterms filename file goodnets) + nets=CV->nets + (foreach net nets + iterms=net->instTerms + (when (length iterms)==2 + (when (IsInList (car iterms)->inst->master->cellName LegalMBUFs) && + (IsInList (cadr iterms)->inst->master->cellName LegalMBUFs) + goodnets=(cons net goodnets) + ) + ) + ) + goodnets + ) +) + +(defun ReportMBUFChannels (filename @key (filter_buswires nil)) + (let (file nets newname bufs) + file=(outfile filename) + + (fprintf file "e1of4s = (list \"e1of4\" ") + bufs=(list "lib.buffer.half.RBUF_1of4.1000" + "lib.buffer.half.MBUF_1of4.1000" + "lib.buffer.half.SBUF_1of4.1000" + ) + nets=(FindMBUFChannels bufs) + (foreach net nets + (when !filter_buswires || (filter_buswires && !(DoesBusWireExist net)) + newname=(reverse (parseString net->name ".")) + (when (car newname)=="e" + (fprintf file "\"%s\" " (buildString (reverse (cdr newname)) ".")) + ) + ) + ) + (fprintf file ")\n\n") + + (fprintf file "e1of3s = (list \"e1of3\" ") + bufs=(list "lib.buffer.half.RBUF_1of3.1000" + "lib.buffer.half.MBUF_1of3.1000" + "lib.buffer.half.SBUF_1of3.1000" + ) + nets=(FindMBUFChannels bufs) + (foreach net nets + (when !filter_buswires || (filter_buswires && !(DoesBusWireExist net)) + newname=(reverse (parseString net->name ".")) + (when (car newname)=="e" + (fprintf file "\"%s\" " (buildString (reverse (cdr newname)) ".")) + ) + ) + ) + (fprintf file ")\n\n") + + (fprintf file "e1of2s = (list \"e1of2\" ") + bufs=(list "lib.buffer.half.RBUF_1of2.1000" + "lib.buffer.half.MBUF_1of2.1000" + "lib.buffer.half.SBUF_1of2.1000" + ) + nets=(FindMBUFChannels bufs) + (foreach net nets + (when !filter_buswires || (filter_buswires && !(DoesBusWireExist net)) + newname=(reverse (parseString net->name ".")) + (when (car newname)=="e" + (fprintf file "\"%s\" " (buildString (reverse (cdr newname)) ".")) + ) + ) + ) + (fprintf file ")\n\n") + + + (close file) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/keepout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/keepout.il new file mode 100644 index 0000000000..50b93d769d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/keepout.il @@ -0,0 +1,709 @@ +(defun KeepOutCreateAbstractLayerStruct ( LPP + @key + ( Purpose "boundary" ) ) + (let ( + ( Layer ( car LPP ) ) + ( Number nil ) ) + ( sscanf Layer MetalLayerFormat Number ) + ( list Layer + ( list "hilite" ( sprintf nil "drawing%d" Number ) ) + ( list Layer Purpose ) + ( sprintf nil "abstract_keepout%d" Number ) + ( sprintf nil "metal%d_in_window" Number ) + ( sprintf nil "used_conductor%d" Number ) + ( list Layer "dummy" ) + ) ) ) + +(defun KeepOutCreateRoutingLayerStruct ( LPP + @key + ( Purpose "boundary" ) ) + (let ( + ( Layer ( car LPP ) ) + ( Number nil ) ) + ( sscanf Layer MetalLayerFormat Number ) + ( list Layer + ( list "hilite" ( sprintf nil "drawing%d" Number ) ) + ( list Layer Purpose ) + ( sprintf nil "routing_keepout%d" Number ) + ( sprintf nil "metal%d_in_window" Number ) + ( sprintf nil "used_conductor%d" Number ) + ( list Layer "dummy" ) + ) ) ) + +(defun KeepOutCreateDrawingToPinMapping ( PinLayers ) + ( mapcar + (lambda ( PinLayer ) ( list ( list PinLayer "drawing" ) + ( list PinLayer "pin" ) ) ) + PinLayers ) ) + +(defun KeepOutDuplicateShapeOnPins ( CellView OldToNewLPPPairs NetNamesToAvoid ) + ( foreach OldToNewLPPPair OldToNewLPPPairs + (let ( + ( OldPinLPP ( car OldToNewLPPPair ) ) + ( NewPinLPP ( cadr OldToNewLPPPair ) ) ) + ( mapcar + (lambda ( Rect ) + ( dbCreateRect + CellView + NewPinLPP + Rect ) ) + ( PinUtilGetPinRectsForCellView + CellView + (lambda ( NetName ) ( not ( exists NetNameToAvoid NetNamesToAvoid + ( equal NetName NetNameToAvoid ) ) ) ) + (lambda ( LPP ) ( equal ( car LPP ) ( car OldPinLPP ) ) ) ) ) ) ) ) + +(defun KeepOutChangeLayerOnPins ( CellView OldToNewLPPPairs NetNamesToAvoid ) + ( foreach OldToNewLPPPair OldToNewLPPPairs + (let ( + ( OldPinLPP ( car OldToNewLPPPair ) ) + ( NewPinLPP ( cadr OldToNewLPPPair ) ) ) + ( mapcar + (lambda ( PinFig ) + ( dbSetq PinFig NewPinLPP lpp ) ) + ( PinUtilGetPinFigsForCellView + CellView + (lambda ( NetName ) ( not ( exists NetNameToAvoid NetNamesToAvoid + ( equal NetName NetNameToAvoid ) ) ) ) + (lambda ( LPP ) ( equal LPP OldPinLPP ) ) ) ) ) ) ) + + + + + +(defun KeepOutGetPinLayerFromLayerStruct ( LayerStruct ) + ( nth 0 LayerStruct ) ) + +(defun KeepOutGetPitchLPPFromLayerStruct ( LayerStruct ) + ( nth 1 LayerStruct ) ) + +(defun KeepOutGetKeepOutLPPFromLayerStruct ( LayerStruct ) + ( nth 2 LayerStruct ) ) + +(defun KeepOutGetAssuraLayerFromLayerStruct ( LayerStruct ) + ( nth 3 LayerStruct ) ) + +(defun KeepOutGetAssuraWindowMetalLayerFromLayerStruct ( LayerStruct ) + ( nth 4 LayerStruct ) ) + +(defun KeepOutGetConductorAssuraLayerFromLayerStruct ( LayerStruct ) + ( nth 5 LayerStruct ) ) + +(defun KeepOutGetConductorLPPFromLayerStruct ( LayerStruct ) + ( nth 6 LayerStruct ) ) + +(defun KeepOutCreateKeepOutView ( CellView + TargetLibName + TargetCellName + TargetViewName + KeepOutRuleFile + WorkingDir + LayerStructs + PinNetNamesToIgnoreLPP ) + ;copy the Target View to the new view + (let ( + ( TempLibName + ( LibCreateTempLibraryFromCellView CellView "KEEPOUT" WorkingDir ) ) + ( PinLayers + ( mapcar (lambda ( LayerStruct ) + ( KeepOutGetPinLayerFromLayerStruct + LayerStruct ) ) + LayerStructs ) ) + ( AssuraLayerMappings + ( ListNonDestructiveMapCan + (lambda ( LayerStruct ) + ( list + ( list ( KeepOutGetAssuraLayerFromLayerStruct + LayerStruct ) + ( KeepOutGetKeepOutLPPFromLayerStruct + LayerStruct ) ) + ( list ( KeepOutGetAssuraWindowMetalLayerFromLayerStruct + LayerStruct ) + ( list + ( KeepOutGetPinLayerFromLayerStruct LayerStruct ) + "drawing" ) ) + ( list ( KeepOutGetConductorAssuraLayerFromLayerStruct + LayerStruct ) + ( list + ( KeepOutGetPinLayerFromLayerStruct LayerStruct ) + "drawing" ) ) + ) ) + LayerStructs ) ) + ( PreKeepOutCellView ( dbCopyCellView + CellView + TempLibName + TargetCellName + TargetViewName + nil + nil + t ) ) + ) + ;draw pin layer on drawing layer +; ( KeepOutChangeLayerOnPins + ; PreKeepOutCellView + ; ( KeepOutCreateDrawingToPinMapping PinLayers ) + ; PinNetNamesToIgnoreLPP ) + + ( dbSave PreKeepOutCellView ) + + (let ( + ( ErrorStr + ( AssuraRunAssuraLayerProcessor + PreKeepOutCellView + TargetLibName + TargetCellName + TargetViewName + KeepOutRuleFile + WorkingDir + AssuraLayerMappings + nil ) ) ) + (if ErrorStr + ErrorStr + ( dbOpenCellViewByType + TargetLibName + TargetCellName + TargetViewName + nil + "r" ) ) ) ) ) + +(defun KeepOutCreateAbstractView ( CellView + TargetLibName + TargetCellName + TargetViewName + KeepOutRuleFile + WorkingDir + PRBoundaryLPP + LayerStructs + PinNetNamesToIgnoreLPP ) + (let ( + ( TempLibName ( LibCreateTempLibraryFromCellView + CellView "ABSTRACT" WorkingDir ) ) ) + (let ( + ( PinLayers ( mapcar ( lambda ( LayerStruct ) + ( KeepOutGetPinLayerFromLayerStruct + LayerStruct ) ) + LayerStructs ) ) + ( KeepOutViewRet ( KeepOutCreateKeepOutView + CellView + TempLibName + TargetCellName + TargetViewName + KeepOutRuleFile + WorkingDir + LayerStructs + PinNetNamesToIgnoreLPP ) ) ) + ;run assura + (let ( + ( Ret + (cond ( + ( stringp KeepOutViewRet ) + KeepOutViewRet ) + ( + (let ( + ( AbstractCellView ( dbCopyCellView + CellView + TargetLibName + TargetCellName + TargetViewName + nil + nil + t + ) ) ) + ;first delete all shapes + ( foreach Shape ( getq AbstractCellView shapes ) + ( dbDeleteObject Shape ) ) + ; move the pins and boundary to the abstract view + ( AssuraCopyShapesFromCellView + CellView + AbstractCellView + (lambda ( Shape ) + ( or ( equal ( getq Shape lpp ) PRBoundaryLPP ) + ( and ( getq Shape pin ) + ( exists + PinLayer + PinLayers + ( equal + ( car ( getq Shape lpp ) ) + PinLayer ) ) + ) ) ) ) + ;copy the keepout from the assura made view + ( AssuraCopyShapesFromCellView + KeepOutViewRet AbstractCellView nil ) + ;change all instantiations to abstract view if possible + ( SwapInstanceMasterViews + AbstractCellView "abstract" "maskLayout" ) + ;delete non abstract shapes + ( foreach + Instance + ( getq AbstractCellView instances ) + (if ( not ( equal + ( getq Instance viewName ) + "abstract" ) ) + ( dbDeleteObject Instance ) ) ) + ( dbSave AbstractCellView ) + AbstractCellView ) ) ) ) ) + ( ddDeleteObj ( ddGetObj TempLibName ) ) + Ret ) ) ) ) + +(defun KeepOutCreateRoutingView ( CellView + TargetLibName + TargetCellName + TargetViewName + KeepOutRuleFile + WorkingDir + LayerStructs + PinNetNamesToIgnoreLPP ) + + (let ( + ( TempLibName ( LibCreateTempLibraryFromCellView + CellView + "ROUTING" + WorkingDir ) ) ) + (let ( + ( KeepOutViewRet ( KeepOutCreateKeepOutView + CellView + TempLibName + TargetCellName + TargetViewName + KeepOutRuleFile + WorkingDir + LayerStructs + PinNetNamesToIgnoreLPP ) ) ) + ;run assura + (let ( + ( Ret + (cond ( + ( stringp KeepOutViewRet ) + KeepOutViewRet ) + ( + (let ( + ( RoutingCellView ( dbCopyCellView + CellView + TargetLibName + TargetCellName + TargetViewName + nil + nil + t + ) ) ) + + ;first delete existing keepouts shapes + ( foreach + Shape + ( setof + Shape + ( getq RoutingCellView shapes ) + ( exists + LayerStruct + LayerStructs + ( or + ( equal ( getq Shape lpp ) + ( KeepOutGetKeepOutLPPFromLayerStruct + LayerStruct ) ) + ( equal ( getq Shape lpp ) + ( KeepOutGetConductorLPPFromLayerStruct + LayerStruct ) ) ) ) ) + ( dbDeleteObject Shape ) ) + + ;then copy the keepout from the assura made view + ( AssuraCopyShapesFromCellView + KeepOutViewRet + RoutingCellView + nil ) + ( SwapInstanceMasterViews + RoutingCellView + "abstract" + "maskLayout" ) + ( dbSave RoutingCellView ) + RoutingCellView ) ) ) ) ) + + ( ddDeleteObj ( ddGetObj TempLibName ) ) + + Ret ) ) ) ) + +(defun KeepOutDrawKeepOut ( CellView + DirectiveTable + HorizontalLayerStructs + VerticalLayerStructs + BoundaryLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + NetNamesToAvoid + KeepoutPattern ;nil implies use directives + DrawKeepout + DrawPinPitches + PinKeepInWidth + @key + ( Area nil ) ) + + (let ( + ( BoundaryPolygonEdges + ( PinUtilGetBoundaryPolygonEdgesFromCellView + BoundaryLPP + CellView ) ) ) + ( foreach + X + ( append + ( mapcar (lambda ( X ) + ( list X + ( list + `AutoPinCalculateNumVerticalWirePitches + `PinUtilGetVerticalPitchWidthPairForRect + `KeepOutGetVerticalRect ) ) ) + VerticalLayerStructs ) + ( mapcar (lambda ( X ) + ( list X + ( list + `AutoPinCalculateNumHorizontalWirePitches + `PinUtilGetHorizontalPitchWidthPairForRect + `KeepOutGetHorizontalRect ) ) ) + HorizontalLayerStructs ) ) + (let ( + ( LayerStruct ( car X ) ) + ( Funcs ( cadr X ) ) ) + (let ( + ( MetalLPP + ( list + ( KeepOutGetPinLayerFromLayerStruct LayerStruct ) "drawing" ) ) ) + (let ( + ( PinRects + ( PinUtilGetPinRectsForCellView + CellView + (lambda ( NetName ) ( not ( exists NetNameToAvoid NetNamesToAvoid + ( equal NetName NetNameToAvoid ) ) ) ) + + (lambda ( LPP ) + ( equal ( car LPP ) ( KeepOutGetPinLayerFromLayerStruct LayerStruct ) ) ) ) ) + ( KeepoutPattern + (if ( null KeepoutPattern ) + ( KeepOutParseKeepOutDirectiveString + ( CellInfoGetLayerKeepOutPattern + DirectiveTable + MetalLPP + ) ) + KeepoutPattern ) ) + ( PowerGridPattern + ( PowerGridCreatePowerGridPatternFromDirectives + DirectiveTable MetalLPP ) ) + ( WirePitch + ( times UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectiveTable + MetalLPP + DirectiveUnitsPerMeter + ) ) ) + ( PowerGridWireWidth + ( times UserUnitsPerMeter + ( CellInfoGetLayerPowerGridWireWidthInMeters + DirectiveTable + MetalLPP + DirectiveUnitsPerMeter + ) ) ) + ( WireWidth + ( times UserUnitsPerMeter + ( CellInfoGetLayerWireWidthInMeters + DirectiveTable + MetalLPP + DirectiveUnitsPerMeter + ) ) ) + ( WireSpacing + ( times UserUnitsPerMeter + ( CellInfoGetLayerWireSpacingInMeters + DirectiveTable + MetalLPP + DirectiveUnitsPerMeter + ) ) ) + + ) + (let ( + ( PitchOffset + ( KeepoutGetPitchOffset + PowerGridWireWidth + WireSpacing + WirePitch ) ) ) + ( println PitchOffset ) + ( DrawKeepOutForLayer + LayerStruct + BoundaryPolygonEdges + PowerGridPattern + KeepoutPattern + ( nth 0 Funcs ) + ( nth 1 Funcs ) + ( nth 2 Funcs ) + PinRects + WirePitch + WireWidth + PitchOffset + DrawKeepout + DrawPinPitches + PinKeepInWidth ) ) ) ) ) ) ) ) + +(defun KeepoutGetPitchOffset ( PowerGridWireWidth + WireSpacing + WirePitch ) + (let ( + ( HalfPitchOffset ( times 0.5 + ( plus PowerGridWireWidth + WireSpacing ) ) ) ) + ( difference + 0.0 + ( difference + ( times + ( ceiling + ( quotient HalfPitchOffset + WirePitch ) ) + WirePitch ) + HalfPitchOffset ) ) ) ) + +(defun DrawKeepOutForLayer ( LayerStruct + BoundaryPolygonEdges + PowerGridPattern + KeepoutPattern + NumPitchesFunc + GetPinPitchWidthPairFunc + RectFunc + PinRects + WirePitch + WireWidth + PitchOffset + DrawKeepout + DrawPinPitches + PinKeepInWidth + ) + + (let ( + ( NumPitches ( apply NumPitchesFunc + ( list + BoundaryPolygonEdges + WirePitch + PitchOffset + ) ) ) + ) + (let ( + ( FirstPitch 0 ) + ( LastPitch NumPitches ) ) + (let ( + ( KeepOutPitches + ( KeepOutGetKeepOutPitches + KeepoutPattern + PowerGridPattern + FirstPitch + LastPitch ) ) ) + (let ( + ( PinPitchWidthPairs + ( mapcar + (lambda ( Rect ) + ( apply GetPinPitchWidthPairFunc + ( list Rect BoundaryPolygonEdges WirePitch PitchOffset ) ) ) + PinRects ) ) ) + + (when DrawPinPitches + ( mapcar + (lambda ( Rect ) + ( dbCreateRect + CellView + ( KeepOutGetPitchLPPFromLayerStruct LayerStruct ) + Rect ) ) + ( mapcar + (lambda ( PitchWidthPair ) + ( apply RectFunc ( list + PitchWidthPair + WirePitch + WirePitch + PitchOffset + BoundaryPolygonEdges ) ) ) + PinPitchWidthPairs ) ) ) + + (when DrawKeepout + ( mapcar + (lambda ( Rect ) + ( dbCreateRect + CellView + ( KeepOutGetKeepOutLPPFromLayerStruct LayerStruct ) + Rect ) ) + ( mapcar + (lambda ( Pitch ) + ( apply RectFunc ( list ( list Pitch 1 ) + WirePitch + WireWidth + PitchOffset + BoundaryPolygonEdges ) ) ) + ( KeepOutSubtractOutPitchWidthPairsFromPitches + FirstPitch + LastPitch + KeepOutPitches + ( mapcar + (lambda ( PitchWidthPair ) + ( KeepOutChangeWidthOfPitchWidthPair + PitchWidthPair PinKeepInWidth ) ) + PinPitchWidthPairs ) ) ) ) ) ) ) ) ) ) + + + +(defun KeepOutSubtractOutPitchWidthPairsFromPitches ( Min + Max + Pitches + PitchWidthPairs ) + + (let ( + ( Size ( plus ( difference Max Min ) 1 ) ) ) + (let ( + ( KeepOutVector ( makeVector Size t ) ) ) + ( foreach Pitch Pitches + ( setarray KeepOutVector ( difference Pitch Min ) nil ) ) + ( foreach PitchWidthPair PitchWidthPairs + ( for I + ( car PitchWidthPair ) + ( min ( difference Size 1 ) + ( plus ( car PitchWidthPair ) ( difference ( cadr PitchWidthPair ) 1 ) ) ) + ( setarray KeepOutVector ( difference I Min ) t ) ) ) + ( KeepOutGetKeepOutPitches + ( vectorToList KeepOutVector ) + ( list nil ) + Min + Max ) ) ) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Getting the pitch/width pairs +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun KeepOutChangeWidthOfPitchWidthPair ( PitchWidthPair WidthModifier ) + (let ( + ( OriginalPitch ( car PitchWidthPair ) ) + ( OriginalWidth ( cadr PitchWidthPair ) ) ) + (let ( + ( Width (if ( equal WidthModifier 0 ) 0 ( plus OriginalWidth ( difference WidthModifier 1 ) ) ) ) ) + ( list ( max 0 ( difference OriginalPitch ( quotient ( difference Width OriginalWidth ) 2 ) ) ) + Width ) ) ) ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Creating and Drawing the Rectangles +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun KeepOutGetHorizontalRect ( PitchWidthPair + WirePitch + WireWidth + WirePitchOffset + BoundaryPolygonEdges ) + (let ( + ( YRange ( PinUtilGetYRangeForHorizontalPitchWidthPair + PitchWidthPair + WirePitch + WireWidth + WirePitchOffset + BoundaryPolygonEdges ) ) ) + (let ( + ( XRange ( PolygonGetHorizontalLeftAndRightBoundaryFromBottomAndTop + YRange + BoundaryPolygonEdges ) ) ) + ( RectMakeFromRanges + XRange + YRange ) ) ) ) + + +(defun KeepOutGetVerticalRect ( PitchWidthPair + WirePitch + WireWidth + WirePitchOffset + BoundaryPolygonEdges ) + (let ( + ( XRange ( PinUtilGetXRangeForVerticalPitchWidthPair + PitchWidthPair + WirePitch + WireWidth + WirePitchOffset + BoundaryPolygonEdges ) ) ) + (let ( + ( YRange ( PolygonGetVerticalTopAndBottomBoundaryFromLeftAndRight + XRange + BoundaryPolygonEdges ) ) ) + ( RectMakeFromRanges + XRange + YRange ) ) ) ) + + +(defun KeepOutParseKeepOutDirectiveString ( DirectiveString ) + (let ( + ( Len ( strlen DirectiveString ) ) + ( Ret nil ) ) + ( for + CurrIndex + 1 + Len + (let ( + ( CurrChar ( substring DirectiveString CurrIndex 1 ) ) ) + (cond + ( + ( equal CurrChar "0" ) + ( setq Ret ( tconc Ret nil ) ) ) + ( + ( equal CurrChar "1" ) + ( setq Ret ( tconc Ret t ) ) ) ) ) ) + ( car Ret ) ) ) + + + +(defun KeepOutGetKeepOutPitches ( Pattern PowerGridPattern FirstPitch LastPitch ) + (let ( + ( CurrPattern nil ) + ( CurrPowerGridPattern nil ) + ( CurrPitch FirstPitch ) + ( Ret nil ) ) + (while ( lessp CurrPitch LastPitch ) + (let () + (unless CurrPattern + ( setq CurrPattern Pattern ) ) + (unless CurrPowerGridPattern + ( setq CurrPowerGridPattern PowerGridPattern ) ) + + (let ( + ( PowerInCurrPitch ( car CurrPowerGridPattern ) ) ) + (unless PowerInCurrPitch + (let ( + ( KeepoutInPitch ( not ( car CurrPattern ) ) ) ) + (when KeepoutInPitch + ( setq Ret ( tconc Ret CurrPitch ) ) ) + ( setq CurrPattern ( cdr CurrPattern ) ) ) ) + ( setq CurrPitch ( plus CurrPitch 1 ) ) + ( setq CurrPowerGridPattern ( cdr CurrPowerGridPattern ) ) ) ) ) + ( car Ret ) ) ) + + + +; check if the cell has keepouts +(defun HasKeepout (view) + (let ((keepout nil)) + (foreach shape view->shapes + (when (cadr shape->lpp)=="boundary" + keepout = t + ) + ) + keepout + ) +) + +; delete keepout +(defun DeleteKeepout (@key (CV nil)) + (cond (CV==nil CV = (geGetEditCellView))) + (foreach shape CV->shapes + (cond ((isMetalKeepout shape->layerName shape->purpose) + (dbDeleteObject shape)) + ((and shape->layerName=="prBoundary" shape->purpose=="block") + (dbDeleteObject shape) + ) + ) + ) + t + ) + +; delete worthless nanoroute shape +(defun DeletePrboundBy (@key (CV nil)) + (cond (CV==nil CV = (geGetEditCellView))) + (foreach shape CV->shapes + (cond (shape->layerName=="prBoundary" && shape->purpose=="boundary" + (dbDeleteObject shape)) + ) + ) + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/obs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/obs.il new file mode 100644 index 0000000000..96a153935a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/obs.il @@ -0,0 +1,142 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/obs.il#1 $ +; $DateTime: 2009/08/07 15:34:02 $ +; $Author: stevemc $ + + +(defun isBusObs (obj) + (when (car obj->lpp)==(car BusObs) && (cadr obj->lpp)==(cadr BusObs) t) +) + +(defun CreateObsProps (@key (shapes nil)) + (let (obs_m1 obs_m2 obs_m3 obs_m4 obs_m5 obs_m6 obs_m7 blk_pr) + shapes = (if shapes==nil (geGetSelSet) shapes) + (foreach obj shapes + (cond ((isBusObs obj) + blk_pr = (GetProp obj "ChopPRB" nil) + obs_m1 = (GetProp obj "M1" nil) + obs_m2 = (GetProp obj "M2" nil) + obs_m3 = (GetProp obj "M3" nil) + obs_m4 = (GetProp obj "M4" nil) + obs_m5 = (GetProp obj "M5" nil) + obs_m6 = (GetProp obj "M6" nil) + obs_m7 = (GetProp obj "M7" nil) + + ; delete properties + (dbDeletePropByName obj "ChopPRB") + (dbDeletePropByName obj "M1") + (dbDeletePropByName obj "M2") + (dbDeletePropByName obj "M3") + (dbDeletePropByName obj "M4") + (dbDeletePropByName obj "M5") + (dbDeletePropByName obj "M6") + (dbDeletePropByName obj "M7") + + ; set new properties + (dbReplaceProp obj "ChopPRB" "boolean" blk_pr) + (dbReplaceProp obj "M1" "boolean" obs_m1) + (dbReplaceProp obj "M2" "boolean" obs_m2) + (dbReplaceProp obj "M3" "boolean" obs_m3) + (dbReplaceProp obj "M4" "boolean" obs_m4) + (dbReplaceProp obj "M5" "boolean" obs_m5) + (dbReplaceProp obj "M6" "boolean" obs_m6) + (dbReplaceProp obj "M7" "boolean" obs_m7) + )) + ) + ) + t + ) + + +(defun DrawObsLayers (view obj @key (CV (geGetEditCellView))) + (let (points obs_m1 obs_m2 obs_m3 obs_m4 obs_m5 obs_m6 obs_m7 blk_pr) + ; get props + blk_pr = (GetProp obj "ChopPRB" nil) + obs_m1 = (GetProp obj "M1" nil) + obs_m2 = (GetProp obj "M2" nil) + obs_m3 = (GetProp obj "M3" nil) + obs_m4 = (GetProp obj "M4" nil) + obs_m5 = (GetProp obj "M5" nil) + obs_m6 = (GetProp obj "M6" nil) + obs_m7 = (GetProp obj "M7" nil) + ; get points + (when obj->objType=="rect" + points = obj->bBox + (when blk_pr (SetBusProp (dbCreateRect CV (list "prBoundary" "block") points)) ) + (when obs_m1 (SetBusProp (dbCreateRect CV Metal1byLPP points)) ) + (when obs_m2 (SetBusProp (dbCreateRect CV Metal2byLPP points)) ) + (when obs_m3 (SetBusProp (dbCreateRect CV Metal3byLPP points)) ) + (when obs_m4 (SetBusProp (dbCreateRect CV Metal4byLPP points)) ) + (when obs_m5 (SetBusProp (dbCreateRect CV Metal5byLPP points)) ) + (when obs_m6 (SetBusProp (dbCreateRect CV Metal6byLPP points)) ) + (when obs_m7 (SetBusProp (dbCreateRect CV Metal7byLPP points)) ) + ) + (when obj->objType=="polygon" + points = obj->points + (when blk_pr (SetBusProp (dbCreatePolygon CV (list "prBoundary" "block") points)) ) + (when obs_m1 (SetBusProp (dbCreatePolygon CV Metal1byLPP points)) ) + (when obs_m2 (SetBusProp (dbCreatePolygon CV Metal2byLPP points)) ) + (when obs_m3 (SetBusProp (dbCreatePolygon CV Metal3byLPP points)) ) + (when obs_m4 (SetBusProp (dbCreatePolygon CV Metal4byLPP points)) ) + (when obs_m5 (SetBusProp (dbCreatePolygon CV Metal5byLPP points)) ) + (when obs_m6 (SetBusProp (dbCreatePolygon CV Metal6byLPP points)) ) + (when obs_m7 (SetBusProp (dbCreatePolygon CV Metal7byLPP points)) ) + ) + ) +) + +; draw obstructions (NOTE: upto is obsolete) +(defun DrawObstructions (@key (upto 128) (guideInstName nil) (guideInst nil) + (CV (geGetEditCellView))) + (let (view obstype top pitch pattern flip track + busKeepout busPatterns busUseDefaultPatterns) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName) + view = guideInst->master + (when !view view = CV) + + ; draw OBS shapes + (foreach shape view->shapes + (when (isBusObs shape) (DrawObsLayers view shape) ) + ) + + ; draw bus paths with BusPattern "obstruction" + busKeepout = t + busUseDefaultPatterns = nil + busPatterns = (list (list "obstruction" node_TW)) + (DrawChannels nil nil nil nil ?guideInst guideInst) + (DrawChannelArrays nil nil nil nil nil nil ?guideInst guideInst) + + ; draw obstructM* + (for i 2 7 + obstype=(sprintf nil "obstructM%d" i) + (foreach shape view->shapes + pattern=(GetProp shape "BusPattern" nil) + (when shape->objType=="path" && pattern==obstype + pitch=(GetProp shape "BusArrayPitch" nil) + (if (mod i 2)==0 then + flip=(GetProp shape "BusFlipX" nil) + track=(caar shape->points)-TrackPitch/2 + (if !flip then + top=(caadr CV->bBox)-track + else + top=track-(caar CV->bBox) + ) + else + flip=(GetProp shape "BusFlipY" nil) + track=(cadar shape->points)-TrackPitch/2 + (if !flip then + top=(cadadr CV->bBox)-track + else + top=track-(cadar CV->bBox) + ) + ) + ) + ) + (when top && pitch + (DrawChannelArrays nil node_TW "" 0:(floor top/pitch) nil obstype ) + ) + ) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/patterns.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/patterns.il new file mode 100644 index 0000000000..0ca8ba1184 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/patterns.il @@ -0,0 +1,135 @@ +; Map from BusPattern string name to pattern structure. All native +; patterns of the PDK should be included here. Wide and sparse array +; patterns are parsed separately and can apply to all of these base +; patterns. Try to put common patterns near the top for performance +; reasons. Also supports user-defined busPatterns, a list of lists. +; The inner list contains the name and the pattern. This busPatterns +; should be set in wires.il +(defun MapBusPattern (name @key (defaults busUseDefaultPatterns) (patterns busPatterns)) + (let (pattern) + (when defaults pattern = (MapBusPatternPDK name)) + (unless pattern pattern = (cadr (car (setof p patterns name==(car p))))) + pattern + ) + ) + +; Should a pattern use double vias? +(defun RecommendDoubleVias (name) + (cond (name=="e1of1" t) + (name=="e1of2" t) + (name=="e1of3" t) + (name=="e1of4" t) + (name=="1of1" t) + (name=="1of2" t) + (name=="1of3" t) + (name=="1of4" t) + (name=="e1of1d" t) + (name=="e1of2d" t) + (name=="e1of3d" t) + (name=="e1of4d" t) + (name=="ChanDft2" t) + (t nil) + ) + ) + +; draw bus wires using guide paths (NOTE: upto is obsolete) +(defun DrawTracks (@key (upto 64) (guideInst nil) (guideInstName nil)) + (DrawChannels nil nil nil nil + ?guideInst guideInst ?guideInstName guideInstName) + (DrawChannelArrays nil nil nil nil nil nil + ?guideInst guideInst ?guideInstName guideInstName) + t + ) + +; obsolete +(defun DrawExtraTracks (@key (upto 64) (guideInstName nil) (guideInst nil)) + (printf "WARNING: DrawExtraTracks is obsolete -- DrawTracks is sufficient.\n") + nil + ) + +; obsolete +(defun DrawPartialArrays (@key (guideInstName nil)) + (printf "WARNING: DrawPartialArrays is obsolete -- DrawTracks is sufficient.\n") + nil + ) + +; draw double_default_e1of2/double_default_e1of4 arrays +(defun DrawDefaultTracks (@key (upto 64) (guideInstName nil) (guideInst nil) (pack_e1of2 nil)) + (let (chan str) + (for hi 1 upto + chan=(CreateDoubleDefaulte1of4 hi) + str=(sprintf nil "double_default_e1of4[%d]" hi) + (DrawChannels nil chan nil str ?guideInst guideInst ?guideInstName guideInstName) + ) + (for hi 1 upto + chan=(CreateDoubleDefaulte1of3 hi) + str=(sprintf nil "double_default_e1of3[%d]" hi) + (DrawChannels nil chan nil str ?guideInst guideInst ?guideInstName guideInstName) + ) + (for hi 1 upto + chan=(CreateDoubleDefaulte1of2 hi ?pack pack_e1of2) + str=(sprintf nil "double_default_e1of2[%d]" hi) + (DrawChannels nil chan nil str ?guideInst guideInst ?guideInstName guideInstName) + ) + ) + t + ) + +(defun CreateDoubleDefaulte1of4 (array) + (let (channel defchan str) + channel=(list "") + (for i 0 array-1 + str=(sprintf nil "[%d]" i) + (if (mod i 2)==0 then + channel=(BuildDefChanList channel str 1 + inlv_e1of4_A i/2*TrackPitch nil ?use_dots nil) + else + channel=(BuildDefChanList channel str 1 + inlv_e1of4_B i/2*TrackPitch nil ?use_dots nil) + ) + ) + defchan=(DefChan (cdr channel)) + ) + ) + +(defun CreateDoubleDefaulte1of3 (array) + (let (channel defchan str) + channel=(list "") + (for i 0 array-1 + str=(sprintf nil "[%d]" i) + (if (mod i 2)==0 then + channel=(BuildDefChanList channel str 1 + inlv_e1of3_A i/2*TrackPitch nil ?use_dots nil) + else + channel=(BuildDefChanList channel str 1 + inlv_e1of3_B i/2*TrackPitch nil ?use_dots nil) + ) + ) + defchan=(DefChan (cdr channel)) + ) + ) + +(defun CreateDoubleDefaulte1of2 (array @key (pack nil)) + (let (channel defchan str typeA typeB) + (if pack then + typeA=inlv_e1of2_A + typeB=inlv_e1of2_B + else + typeA=inlv_e1of2_A2 + typeB=inlv_e1of2_B2 + ) + + channel=(list "") + (for i 0 array-1 + str=(sprintf nil "[%d]" i) + (if (mod i 2)==0 then + channel=(BuildDefChanList channel str 1 + typeA i/2*TrackPitch nil ?use_dots nil) + else + channel=(BuildDefChanList channel str 1 + typeB i/2*TrackPitch nil ?use_dots nil) + ) + ) + defchan=(DefChan (cdr channel)) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/shield.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/shield.il new file mode 100644 index 0000000000..95ded4a51d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/shield.il @@ -0,0 +1,444 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/shield.il#1 $ +; $DateTime: 2012/07/27 17:24:08 $ +; $Author: pankala $ + +(defun DrawBusShield ( points layers prefix @key (CellVue (UIGetCellView)) (shieldM2 t)) + let( ( Idx NPoints HLayer VLayer + CurrPoint NextPoint CurrLayer Segments + ShieldDir ShieldPoint ShieldPointX ShieldPointY ShieldLength ShieldInst ShieldInstName + CurrXQuad CurrYQuad (types (ClassifyPoints points)) + ) + + HLayer = car(nth(0 layers)) + VLayer = car(nth(1 layers)) + NPoints = length(points) + + for( Idx 0 NPoints-2 + + CurrPoint = nth(Idx points) + + CurrXQuad = car(ShieldFindQuad(CurrPoint)) + CurrYQuad = cadr(ShieldFindQuad(CurrPoint)) + + when( Idx == 0 + NextPoint = nth(Idx+1 points) + + if( almostEqual(car(CurrPoint) car(NextPoint)) + then + CurrLayer = VLayer + if( NPoints > 2 + then + Segments = round((abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( cadr(NextPoint) > cadr(CurrPoint) + then + ShieldDir = "V_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = round((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + else + ShieldDir = "V_MX" + if( CurrYQuad > 0 + then + ShieldPointY = round((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + else + CurrLayer = HLayer + if( NPoints > 2 + then + Segments = round((abs(car(NextPoint)*1000 - car(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(car(NextPoint)*1000 - car(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( car(NextPoint) > car(CurrPoint) + then + ShieldDir = "H_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = round((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + else + ShieldDir = "H_MY" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = round((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + ) + ) + ShieldPoint = list(ShieldPointX ShieldPointY) + when( !OverlapShield(CellVue ShieldPoint CurrLayer ShieldDir Segments) + DrawShieldShapes(CellVue Segments ShieldPoint ShieldDir CurrLayer ?shieldM2 shieldM2) + ) + ) + + when( Idx > 0 && Idx < NPoints-2 + NextPoint = nth(Idx+1 points) + + if( almostEqual(car(CurrPoint) car(NextPoint)) + then + CurrLayer = VLayer + Segments = round(abs(cadr(NextPoint) - cadr(CurrPoint))/TrackPitch) - 1 + if( cadr(NextPoint) > cadr(CurrPoint) + then + ShieldDir = "V_R0" + if( CurrYQuad > 0 + then + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + else + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + else + ShieldDir = "V_MX" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + else + CurrLayer = HLayer + Segments = round(abs(car(NextPoint) - car(CurrPoint))/TrackPitch) - 1 + if( car(NextPoint) > car(CurrPoint) + then + ShieldDir = "H_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + else + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + else + ShieldDir = "H_MY" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + ) + ShieldPoint = list(ShieldPointX ShieldPointY) + when( !OverlapShield(CellVue ShieldPoint CurrLayer ShieldDir Segments) + DrawShieldShapes(CellVue Segments ShieldPoint ShieldDir CurrLayer ?shieldM2 shieldM2) + ) + ) + + when( Idx == NPoints-2 && Idx != 0 + NextPoint = nth(Idx+1 points) + + if( almostEqual(car(CurrPoint) car(NextPoint)) + then + CurrLayer = VLayer + if( NPoints > 2 + then + Segments = round((abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(cadr(NextPoint)*1000 - cadr(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( cadr(NextPoint) > cadr(CurrPoint) + then + ShieldDir = "V_R0" + if( CurrYQuad > 0 + then + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1)*TrackPitch + else + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + else + ShieldDir = "V_MX" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) - 1)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrXQuad)*TrackPitch + ) + ) + else + CurrLayer = HLayer + if( NPoints > 2 + then + Segments = round((abs(car(NextPoint)*1000 - car(CurrPoint)*1000) - 780)/(TrackPitch*1000)) + else + Segments = round(abs(car(NextPoint)*1000 - car(CurrPoint)*1000)/(TrackPitch*1000)) + ) + if( car(NextPoint) > car(CurrPoint) + then + ShieldDir = "H_R0" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) + 1)*TrackPitch + else + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + ) + else + ShieldDir = "H_MY" + if( CurrYQuad > 0 + then + ShieldPointY = truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointY = (truncate((cadr(CurrPoint)*1000)/(TrackPitch*1000)) + 1*CurrYQuad)*TrackPitch + ) + if( CurrXQuad > 0 + then + ShieldPointX = truncate((car(CurrPoint)*1000)/(TrackPitch*1000))*TrackPitch + else + ShieldPointX = (truncate((car(CurrPoint)*1000)/(TrackPitch*1000)) - 1)*TrackPitch + ) + ) + ) + ShieldPoint = list(ShieldPointX ShieldPointY) + when( !OverlapShield(CellVue ShieldPoint CurrLayer ShieldDir Segments) + DrawShieldShapes(CellVue Segments ShieldPoint ShieldDir CurrLayer ?shieldM2 shieldM2) + ) + ) + + + ) + t + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun OverlapShield (CellVue ShieldPoint CurrLayer ShieldDir Segments) + let( ( ShieldbBoxFirst ShieldbBoxLast ShieldPresent ShieldShape SegInc ) + if( cadr(parseString(ShieldDir "_")) == "R0" + then + SegInc = 1 + else + SegInc = -1 + ) + when( car(parseString(ShieldDir "_")) == "H" + ShieldbBoxFirst = list(car(ShieldPoint)+(0.78*SegInc):cadr(ShieldPoint)+0.045 car(ShieldPoint)+(0.80*SegInc):cadr(ShieldPoint)+0.095) + ShieldbBoxLast = list(car(ShieldPoint)+(0.78*(Segments-1)*SegInc):cadr(ShieldPoint)+0.045 car(ShieldPoint)+(0.80*(Segments-1)*SegInc):cadr(ShieldPoint)+0.095) + ) + when( car(parseString(ShieldDir "_")) == "V" + ShieldbBoxFirst = list(car(ShieldPoint)+0.045:cadr(ShieldPoint)+(0.78*SegInc) car(ShieldPoint)+0.095:cadr(ShieldPoint)+(0.80*SegInc)) + ShieldbBoxLast = list(car(ShieldPoint)+0.045:cadr(ShieldPoint)+(0.78*(Segments-1)*SegInc) car(ShieldPoint)+0.095:cadr(ShieldPoint)+(0.80*(Segments-1)*SegInc)) + ) + if( setof(ShieldShape dbGetOverlaps(CellVue ShieldbBoxFirst) ShieldShape~>BusScriptObject&&car(ShieldShape~>lpp)==CurrLayer) && setof(ShieldShape dbGetOverlaps(CellVue ShieldbBoxLast) ShieldShape~>BusScriptObject&&car(ShieldShape~>lpp)==CurrLayer) + then + ShieldPresent = t + else + ShieldPresent = nil + ) + ShieldPresent + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun DrawShieldShapes (CellVue Segments ShieldPoint ShieldDir CurrLayer @key (shieldM2 t)) + let( ( Idx ShieldbBox1 ShieldbBox2 ShieldObj1 ShieldObj2 SegInc + RBlockObj1 RBlockObj2 VBlockObj1 VBlockObj2 M2Block1 M2Block2 viaid ShieldVia1 ShieldVia2 + ) + + if( cadr(parseString(ShieldDir "_")) == "R0" + then + SegInc = 1 + else + SegInc = -1 + ) + + for( Idx 0 Segments-1 + when( car(parseString(ShieldDir "_")) == "H" + ShieldbBox1 = list(car(ShieldPoint)+TrackPitch*Idx*SegInc:cadr(ShieldPoint)+0.045 car(ShieldPoint)+(TrackPitch*Idx+1.355)*SegInc:cadr(ShieldPoint)+0.095) + ShieldbBox2 = list(car(ShieldPoint)+TrackPitch*Idx*SegInc:cadr(ShieldPoint)+1.465 car(ShieldPoint)+(TrackPitch*Idx+1.355)*SegInc:cadr(ShieldPoint)+1.515) + when( SegInc == -1 + ShieldbBox1 = list(caar(ShieldbBox1)-0.205:cadar(ShieldbBox1) caadr(ShieldbBox1)-0.205:cadadr(ShieldbBox1)) + ShieldbBox2 = list(caar(ShieldbBox2)-0.205:cadar(ShieldbBox2) caadr(ShieldbBox2)-0.205:cadadr(ShieldbBox2)) + ) + ShieldObj1 = dbCreateRect(CellVue CurrLayer ShieldbBox1) + ShieldObj2 = dbCreateRect(CellVue CurrLayer ShieldbBox2) + RBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox1)) + RBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox2)) +; VBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "viaRouting" BBoxToPoints(ShieldbBox1)) +; VBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "viaRouting" BBoxToPoints(ShieldbBox2)) + SetBusProp(ShieldObj1) + SetBusProp(ShieldObj2) + SetBusProp(RBlockObj1) + SetBusProp(RBlockObj2) +; SetBusProp(VBlockObj1) +; SetBusProp(VBlockObj2) + ) + when( car(parseString(ShieldDir "_")) == "V" + ShieldbBox1 = list(car(ShieldPoint)+0.045:cadr(ShieldPoint)+TrackPitch*Idx*SegInc car(ShieldPoint)+0.095:cadr(ShieldPoint)+(TrackPitch*Idx+1.365)*SegInc) + ShieldbBox2 = list(car(ShieldPoint)+1.465:cadr(ShieldPoint)+TrackPitch*Idx*SegInc car(ShieldPoint)+1.515:cadr(ShieldPoint)+(TrackPitch*Idx+1.365)*SegInc) + when( SegInc == -1 + ShieldbBox1 = list(caar(ShieldbBox1):cadar(ShieldbBox1)-0.195 caadr(ShieldbBox1):cadadr(ShieldbBox1)-0.195) + ShieldbBox2 = list(caar(ShieldbBox2):cadar(ShieldbBox2)-0.195 caadr(ShieldbBox2):cadadr(ShieldbBox2)-0.195) + ) + ShieldObj1 = dbCreateRect(CellVue CurrLayer ShieldbBox1) + ShieldObj2 = dbCreateRect(CellVue CurrLayer ShieldbBox2) + SetBusProp(ShieldObj1) + SetBusProp(ShieldObj2) + RBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox1)) + RBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox2)) +; VBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "viaRouting" BBoxToPoints(ShieldbBox1)) +; VBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "viaRouting" BBoxToPoints(ShieldbBox2)) + SetBusProp(ShieldObj1) + SetBusProp(ShieldObj2) + SetBusProp(RBlockObj1) + SetBusProp(RBlockObj2) +; SetBusProp(VBlockObj1) +; SetBusProp(VBlockObj2) + + when( CurrLayer == "M2" && shieldM2 + ShieldbBox1 = list(car(ShieldPoint)-0.105:cadr(ShieldPoint)+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+0.105:cadr(ShieldPoint)+(TrackPitch*Idx+0.105)*SegInc) + ShieldbBox2 = list(car(ShieldPoint)+1.455:cadr(ShieldPoint)+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+1.665:cadr(ShieldPoint)+(TrackPitch*Idx+0.105)*SegInc) + when( SegInc == -1 + ShieldbBox1 = list(car(ShieldPoint)-0.105:cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+0.105:cadr(ShieldPoint)-1.56+(TrackPitch*Idx+0.105)*SegInc) + ShieldbBox2 = list(car(ShieldPoint)+1.455:cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.105)*SegInc car(ShieldPoint)+1.665:cadr(ShieldPoint)-1.56+(TrackPitch*Idx+0.105)*SegInc) + ) + M2Block1 = dbCreateRect(CellVue CurrLayer ShieldbBox1) + M2Block2 = dbCreateRect(CellVue CurrLayer ShieldbBox2) + RBlockObj1 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox1)) + RBlockObj2 = dbCreateLayerBlockage(CellVue CurrLayer "routing" BBoxToPoints(ShieldbBox2)) + SetBusProp(RBlockObj1) + SetBusProp(RBlockObj2) + SetBusProp(M2Block1) + SetBusProp(M2Block2) + viaid = techFindViaDefByName(techGetTechFile(CellVue) "M3_M2_R_H") + if( SegInc == 1 + then + ShieldVia1 = dbCreateVia(CellVue viaid list(car(ShieldPoint) cadr(ShieldPoint)+(TrackPitch*Idx+0.065)*SegInc) "R0") + ShieldVia2 = dbCreateVia(CellVue viaid list(car(ShieldPoint)+TrackPitch cadr(ShieldPoint)+(TrackPitch*Idx+0.065)*SegInc) "R0") + else + ShieldVia1 = dbCreateVia(CellVue viaid list(car(ShieldPoint) cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.065)*SegInc) "R0") + ShieldVia2 = dbCreateVia(CellVue viaid list(car(ShieldPoint)+TrackPitch cadr(ShieldPoint)-1.56+(TrackPitch*Idx-0.065)*SegInc) "R0") + ) + SetBusProp(ShieldVia1) + SetBusProp(ShieldVia2) + ) + + ) ;when + + ) ;for + + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun BBoxToPoints (bBox) + list(car(bBox) caadr(bBox):cadar(bBox) cadr(bBox) caar(bBox):cadadr(bBox)) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun ShieldSetProps (ShieldInst CurrLayer ShieldLength) + let( (ShieldLayer layer) + + ShieldInst~>SegLength = ShieldLength + + for( layer 2 7 + sprintf(ShieldLayer "M%d" layer) + if( ShieldLayer == CurrLayer + then + dbReplaceProp(ShieldInst ShieldLayer "boolean" "TRUE") + println(ShieldLayer) + else + dbReplaceProp(ShieldInst ShieldLayer "boolean" "FALSE") + ) + ) + t + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun ShieldFindQuad (point) + let( (XQuad YQuad) + + if( car(CurrPoint) >= 0 + then + XQuad = 1 + else + XQuad = -1 + ) + + if( cadr(CurrPoint) >= 0 + then + YQuad = 1 + else + YQuad = -1 + ) + + list(XQuad YQuad) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/util.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/util.il new file mode 100644 index 0000000000..eae9679146 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/keepout/util.il @@ -0,0 +1,679 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/bus/util.il#1 $ +; $DateTime: 2009/08/13 08:18:26 $ +; $Author: stevemc $ + + +; check if two coordinates are equal to rounding precision +(defun almostEqual (x0 x1) + (abs x1-x0)<0.001 + ) + +; make a net unless name is empty +(defun MakeNet (view name) + (cond (name!="" (dbMakeNet view name)) + (name=="" nil) + ) + ) + +; attach a label to a pin +(defun LabelPin (view fig @key (bBox nil)) + (let (x0 y0 x1 y1 x y rotation height) + (unless bBox bBox = fig->bBox) + x0 = (car (car bBox)) + y0 = (cadr (car bBox)) + x1 = (car (cadr bBox)) + y1 = (cadr (cadr bBox)) + x = (x0+x1)/2 + y = (y0+y1)/2 + x = MfgGrid * (round x/MfgGrid) + y = MfgGrid * (round y/MfgGrid) + (cond (x1-x0>y1-y0 rotation = "R0" height = y1-y0) + (t rotation = "R90" height = x1-x0) + ) + height = MfgGrid * (round height/MfgGrid/3) ; adjust height + label = (dbCreateLabel view fig->layerName x:y fig->net->name + "centerCenter" rotation "stick" height) ; draw the label + label->parent = fig ; label moves with figure + ) + t + ) + +; relabel all pins +(defun LabelPins (@key (CV (geGetEditCellView))) + (let (term pin) + (foreach term CV~>terminals + foreach( pin term~>pins + (cond (pin~>fig (LabelPin CV pin~>fig ) ) ) + ) + ) + ) + t + ) + +; transform xy coordinates using transform +(defun busTransformPoint (xy guideInst) + (cond (guideInst==nil xy) + (guideInst!=nil (geTransformUserPoint xy guideInst->transform)) + ) + ) + +; choose next available contact name -- faster than using nil name! +(defun NextContactName (view) + (let (name duplicate) + duplicate = t + (while duplicate + name = (sprintf nil "IC%d" busContactNum) + duplicate = (dbFindAnyInstByName view name) + busContactNum = (if duplicate busContactNum*2 busContactNum+1) + ) + name + ) + ) + +; get a property or default value +(defun GetProp (obj prop default) + p = (dbGetPropByName obj prop) + (cond ((and p!=nil p->valueType=="boolean") p->value=="TRUE") + (p p->value) + (t default) + ) + ) + +; select wires/contacts/subcells by net name +(defun SelectNet + (name + @key (CV (geGetEditCellView)) + (net nil) + (pins t) + (wires t) + (contacts t) + (subcells nil) + ) + (let (found) + found = 0 + (unless net net = (dbFindNetByName CV name)) + (when pins + (foreach pin net->pins + (geSelectObject pin->fig) + found = found+1 + ) + ) + (when wires + (foreach fig net->figs + (geSelectObject fig) + found = found+1 + ) + ) + (foreach term net->instTerms + (when (or (and contacts term->inst->libName==TechLibName) + (and subcells term->inst->libName!=TechLibName)) + (geSelectObject term->inst) + found = found+1 + ) + ) + found + ) + ) + +; select wires/contacts/subcells by net name with regular expression matching +(defun SelectNetRegExp + (regexp + @key (CV (geGetEditCellView)) + (pins t) + (wires t) + (contacts t) + (subcells nil)) + (let (found) + found = 0 + (rexCompile regexp) + (foreach net (setof net CV->nets (rexExecute net->name)) + found = found + + (SelectNet nil ?net net ?CV CV + ?pins pins ?wires wires ?contacts contacts ?subcells subcells) + ) + found + ) + ) + +; test for wiring shapes +(defun isWiringPath (obj) + (let ((iswire nil)) + (when (or obj->objType=="path" obj->objType=="polygon" obj->objType=="rect") && ((isMetalDrawing obj->layerName obj->purpose) || (isMetalPin obj->layerName obj->purpose)) + iswire=t + ) + (when obj->objType=="pin" + (when (isMetalDrawing obj->fig->layerName obj->fig->purpose) || (isMetalPin obj->fig->layerName obj->fig->purpose) + iswire=t + ) + ) + iswire + ) +) + +; test for wiring contacts +(defun isWiringContact (obj) + (or (and obj->objType=="inst" obj->libName==TechLibName) + obj->objType=="stdVia") + ) + +; delete contacts only +(defun DeleteContacts (@key (CV (geGetEditCellView))) + busContactNum = 0 + (let () + (foreach obj CV->instances + (cond ((isWiringContact obj) (dbDeleteObject obj)) + ) + ) + (foreach obj CV->vias + (cond ((isWiringContact obj) (dbDeleteObject obj)) + ) + ) + ) + t + ) + +; delete metal paths and contacts +(defun DeleteWires (@key (CV (geGetEditCellView))) + (let () + (foreach obj CV->shapes + (cond ((isWiringPath obj) (dbDeleteObject obj)) + ) + ) + ) + (DeleteContacts) + t + ) + +; delete metal blockages +(defun DeleteBlockages (@key (CV (geGetEditCellView))) + (let () + (foreach obj CV~>blockages + (dbDeleteObject obj) + ) + ) + t + ) + +; delete both +(defun DeleteWiresAndKeepout () + (DeleteWires) + (DeleteKeepout) + (DeleteBlockages) + t + ) + +; delete shapes and vias that have BusScriptObject property +(defun DeleteBusWires (@key (CV (geGetEditCellView))) + (let (shapes vias blockages) + shapes = (setof obj CV->shapes (IsBusObject obj)) + vias = (GetBusScriptVias CV) + blockages = (setof obj CV->blockages (IsBusObject obj)) + (foreach shape shapes (dbDeleteObject shape)) + (foreach via vias (dbDeleteObject via)) + (foreach blockage blockages (dbDeleteObject blockage)) + ) + t + ) + +;check for scripted wire +(defun DoesBusWireExist (net @key (CV (geGetEditCellView))) + (let (exist) + exist=nil + (foreach shape CV->shapes + (when shape->net==net && (IsBusObject shape) + exist=t + ) + ) + exist + ) +) + +; utility to turn drawing shapes into keepout +(defun ConvertWiresToKeepout (@key (CV (geGetEditCellView))) + (let () + (foreach obj CV->shapes + (cond ((isMetalDrawing obj->layerName obj->purpose) + obj->purpose="boundary" + ) + ) + ) + ) + t + ) + +; delete the warning markers +(defun DeleteMarkers (@key (CV (geGetEditCEllView))) + (geDeleteAllMarker CV) + ) + +; delete unused nets +(defun DeleteUnusedNets (@key (CV (geGetEditCellView))) + (let (cnt) + cnt = 0 + (foreach net CV->nets + (when (and net->instTermCount==0 net->pins==nil net->figs==nil) + (dbDeleteObject net) + cnt=cnt+1 + ) + ) + cnt + ) + ) + +; check if the cell has bus guides +(defun HasGuides (view) + (let ((guides nil)) + (foreach inst view->instances + (when (IsGuideInst inst) + guides = t + ) + ) + (foreach shape view->shapes + (when (cadr shape->lpp)=="bus" + guides = t + ) + ) + guides + ) +) + +; delete bus guides +(defun DeleteGuides (view) + (foreach inst view->instances + (when (IsGuideInst inst) + (dbDeleteObject inst) + ) + ) + (foreach shape view->shapes + (when (cadr shape->lpp)=="bus" + (dbDeleteObject shape) + ) + ) +) + +(defun DeleteGuideShapes (view) + (foreach shape view->shapes + (when (cadr shape->lpp)=="bus" + (dbDeleteObject shape) + ) + ) +) + +; copy bus guides +(defun CopyGuides (srcview dstview) + (foreach inst srcview->instances + (when (IsGuideInst inst) + (dbCreateInstByMasterName dstview inst->libName + inst->cellName inst->viewName inst->name (list 0 0) "R0") + ) + ) + (foreach shape srcview->shapes + (when (cadr shape->lpp)=="bus" + (dbCopyFig shape dstview) + ) + ) + (dbSave dstview) +) + +(defun CopyGuideShapes (srcview dstview) + (foreach shape srcview->shapes + (when (cadr shape->lpp)=="bus" + (dbCopyFig shape dstview) + ) + ) + (dbSave dstview) +) + + +(defun RoundGuidesToGrid ( @key (paths nil) (grid TrackPitch/2) (CV (geGetEditCellView))) + (let (haspaths newpoints) + + (if !paths then + haspaths = nil + (foreach shape CV->shapes + (when shape->objType=="path" && (cadr shape->lpp)=="bus" + haspaths = t + paths = (cons shape paths) + ) + ) + else + haspaths = t + ) + + (if haspaths then + (foreach path paths + newpoints = (PathRoundPointsToGrid path->points ?grid grid) + path->points = newpoints + ) + else + (hiDisplayAppDBox + ?name 'RoundPathsDialogBox + ?dboxText "No bus guidepaths found." + ?dboxBanner "No Guides" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'Close + ) + ) + + ) +) + +(defun GetBusScriptVias (cv) +; (setof inst cv->instances (and inst->libName==TechLibName (IsBusObject inst))) + (setof inst cv->vias (IsBusObject inst)) + ) + +(defun AreViasDuplicate (via1 via2) + (and via1->libName==via2->libName + via1->cellName==via2->cellName + via1->xy==via2->xy + via1->orient==via2->orient) + ) + +(defun DeleteDuplicateBusScriptVias (@key (CV (geGetEditCellView))) + (let (busvias) + busvias = (GetBusScriptVias CV) + (foreach inst CV->instances + (when inst->libName==TechLibName + (foreach via busvias + (when (AreViasDuplicate via inst) && !(IsInList inst busvias) + (dbDeleteObject inst) + ) + ) + ) + ) + ) +) + + +(defun FindDuplicateBuswires (@key (check_points t) (CV (geGetEditCellView))) + (let (wirescell wirescv paths duplicates already_done points_match) + wirescell=(GetGuideInst nil busGuideInstName) + (if wirescell then + wirescv=(nrOpenCellViewWritable wirescell->libName wirescell->cellName wirescell->viewName ?mode "a") + else + wirescv=CV + ) + + (foreach shape wirescv->shapes + (when shape->objType=="path" && (cadr shape->lpp)=="bus" + paths=(cons shape paths) + ) + ) + (foreach path1 paths + already_done=(cons path1 already_done) + (foreach path2 paths + points_match=!check_points + (when check_points && path1->points==path2->points + points_match=t + ) + + (when !(IsInList path2 already_done) && + points_match && + path1->lpp==path2->lpp && + (GetProp path1 "BusPrefix" nil)==(GetProp path2 "BusPrefix" nil) && + (GetProp path1 "BusPattern" nil)==(GetProp path2 "BusPattern" nil) && + (GetProp path1 "BusPin" nil)==(GetProp path2 "BusPin" nil) + duplicates=(cons path2 duplicates) + ) + ) + ) + duplicates + ) +) + +; helper function to determine the length of all paths in a floorplan +(defun ReportPathLengths (@key (filename "alta_path_lengths.txt") + (pathProp (list "Channel" "myProp")) + (CV (geGetEditCellView))) + (let (shape fp channelName length points p0 p1 x0 y0 x1 y1 propName + shapeCount width refCoord refPoint oddList oddPoint) + + ; open the output file + fp = (outfile filename) + + shapeCount = 0 + (if fp != nil + then + ; look for all paths in the current view + (foreach shape CV->shapes + ; process only shapes with type "path" + shapeCount = shapeCount + 1 + (printf "%d: objType = %s - lpp = %s\n" shapeCount shape->objType (cadr shape->lpp)) + (when shape->objType=="path" + + ; look for any of the valid properties + channelName = nil + properties = pathProp + (while (and channelName == nil properties != nil) + propName = (car properties) + properties = (cdr properties) + channelName = (GetProp shape propName nil) + ) ; end (while ... ) + + (if channelName != nil + then + ; now determine the length + length = 0 + aligned = t + oddList = nil + points = shape->points + (for i 0 (length points)-2 + p0 = (nth i points) + p1 = (nth i+1 points) + x0 = (car p0) + y0 = (cadr p0) + x1 = (car p1) + y1 = (cadr p1) + length = length+(abs x1-x0)+(abs y1-y0) + width = shape->width + ; determine the direction + (if x1 == x0 + then + ; we're moving vertically + ; we'll determine the aligment + ; of the left edge of the path + refCoord = x0+width/2.0 + (if y1 > y0 then dir=1 else dir=-1) + refPoint = (list refCoord y0+dir*width/2.0) + else + ; we're moving vertically + ; we'll determine the aligment + ; of the top edge of the path + refCoord = y0+width/2.0 + (if x1 > x0 then dir=1 else dir=-1) + refPoint = (list x0+dir*width/2.0 refCoord) + ) + + ; is the reference coordinate aligned? + (when (IsAligned refCoord (2*TrackPitch)) != t + (if aligned == t + then + oddList = (list (list i refPoint)) + aligned = nil + else + oddList = (append oddList (list (list i refPoint))) + ) + ) + ) ; end for + + ; output the result to file + (fprintf fp "Path=%-54s Length=%8.2f Layer=\"%2s,%8s\" - " + channelName + length + (car shape->lpp) + (cadr shape->lpp) + ) + (if aligned == t + then (fprintf fp "Path ALIGNED\n") + else + (fprintf fp "Path NOT ALIGNED: ") + (foreach oddPoint oddList + (fprintf fp " (%4.2f:%4.2f)" + (nth 0 (cadr oddPoint)) + (nth 1 (cadr oddPoint)) + ) ; end (fprintf ... ) + ) ; end (foreach ... ) + (fprintf fp "\n") + ) ; end (if aligned ... ) + else + (printf "Property not found!\n") + (printf "Layer = %s, %s\n" (car shape->lpp) (cadr shape->lpp)) + (geCreateMarker shape "error" "bus" "length" "") + ) ; end (if channelName ... ) + + ) ; end when + + ) ; end foreach + + ; close the output file + (close fp) + else + (printf "Couldn't open file %s" filename) + ) ; end if + + ) ; end let +) + +; select bus paths with optional filters +(defun SelectBusPaths + (@key (CV (geGetEditCellView)) + (prefix "") ; require BusPrefix to start with prefix + (pattern "") ; require BusPattern to start with pattern + (doPins t) ; allow BusPin=t + (doWires t) ; allow BusPin=nil + (rexPrefix nil) ; optional regular expression for prefix + (rexPattern nil)) ; optional regular expression for pattern + (let (pre pat pin (n 0)) + (foreach path CV->shapes + (when (and path->objType=="path" (cadr path->lpp)=="bus") + pre = (GetProp path "BusPrefix" "") + pat = (GetProp path "BusPattern" "") + pin = (GetProp path "BusPin" nil) + (when (and (if pin doPins doWires) + (strncmp prefix pre (strlen prefix))==0 + (strncmp pattern pat (strlen pattern))==0 + (or !rexPrefix (rexMatchp rexPrefix pre)) + (or !rexPattern (rexMatchp rexPattern pat))) + (geSelectObject path) + n = n+1 + ) + ) + ) + n + ) + ) + +; select inplace pins only +(defun SelectInplacePins + (@key (CV (geGetEditCellView)) + (minLength 0) ; only select pins longer than this + ) + (let (n) + n = 0 + (foreach shape CV->shapes + (when (and (GetProp shape "PinType" nil)=="InPlace" + (or (BBoxGetWidth shape->bBox)>minLength + (BBoxGetHeight shape->bBox)>minLength)) + (geSelectObject shape) + n = n+1 + ) + ) + n + ) + ) + +; replace prefix of BusPrefix of bus paths +(defun ReplaceBusPrefix + (from ; original prefix + to ; replacement prefix + @key (CV (geGetEditCellView))) ; optional cell view + (let (paths prefix (n 0)) + paths = (geGetSelSet) + (unless paths paths=CV->shapes) + paths = (setof shape paths shape->objType=="path") (foreach path paths + prefix = (GetProp path "BusPrefix" nil) + (when (strncmp prefix from (strlen from))==0 + prefix = (substring prefix (strlen from)+1) + prefix = (if prefix (strcat to prefix) to) + (dbReplaceProp path "BusPrefix" "string" prefix) + n=n+1 + ) + ) + n + ) + ) + +; Trim pins that overlap with bbox to stay inside bbox, converting the +; original shape into wires with connectivity. Use to repair layout +; affected by BUG 18821. +(defun TrimPins (bbox @key (CV (geGetEditCellView))) + (let (n shapes bbox_in rect) + n=0 + shapes = (geGetSelSet) + (unless shapes shapes=CV->shapes) + (foreach shape shapes + (when (and shape->pin shape->objType=="rect") + bbox_in = (BBoxAnd bbox shape->bBox) + (when bbox_in + rect = (dbCreateRect CV shape->lpp shape->bBox) + rect->net = shape->net + shape->bBox = bbox_in + (foreach label shape->children + (when label->objType=="label" + label->xy = (BBoxGetCenter bbox_in) + ) + ) + n=n+1 + ) + ) + ) + n + ) + ) + +; Offset a single point by specified amounts for each bBox it overlaps. +(defun StretchPointWithinBoxes + (boxstretch xy @key (CV (geGetEditCellView))) + (let (bbox dxy nxy) + nxy = xy + (foreach bs boxstretch + bbox = (car bs) + dxy = (cadr bs) + (when (BBoxAnd (list xy xy) bbox) + nxy = (car nxy)+(car dxy):(cadr nxy)+(cadr dxy) + ) + ) + nxy + ) + ) + +; Applies offset to all points within each bbox. Bbox overlaps are +; tested before offsets are applied. Takes a list of bbox, offset +; pairs (list (list bbox offet) ...). +(defun StretchShapesWithinBoxes + (boxstretch @key (CV (geGetEditCellView))) + (let (points) + (foreach inst CV->instances + inst->xy = (StretchPointWithinBoxes boxstretch inst->xy) + ) + (foreach shape CV->shapes + (cond (shape->objType=="rect" + shape->bBox = (list (StretchPointWithinBoxes boxstretch (car shape->bBox)) + (StretchPointWithinBoxes boxstretch (cadr shape->bBox))) + ) + (t + points = nil + (foreach xy shape->points + points = (append points + (list (StretchPointWithinBoxes boxstretch xy))) + ) + shape->points = points + ) + ) + ) + ) + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/import.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/import.il new file mode 100644 index 0000000000..6056b86290 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/import.il @@ -0,0 +1,219 @@ +; Import LayGen *.gen files into Virtuoso cells +; Copyright Intel 2013 +; Andrew Lines + +; Laygen dimensions +MfgGrid = 1e-3 ; round dimensions of lables to this manufacturing grid +LaygenUnits = 1e-4 ; scale LayGen coordinates to Virtuoso +UV_dx = -0.035 ; x bloat of uv1/uv2 implant layers relative to diffusion +UV_dy = 0.021 ; y bloat of uv1/uv2 implant layers relative to diffusion + +; Other settings +LaygenVersion = 2012 ; sets a LaygenVersion cell property +LaygenVssName = "vss" +LaygenVccName = "vcc" + +; Map Laygen layers to Virtuoso LPPs. Each laygen layer generates a +; list of lppxy, which is (layerName purpose [bloatX] [bloatY]). Only +; the first lpp of a list gets connectivity. The rest are used for +; implied layers like transistor implants or complementary metal. +LaygenLayerMap = (makeTable "layerMap" nil) + +LaygenLayerMap["nwell"] = (list (list "nwell" "drawing")) +LaygenLayerMap["wirepoly"] = (list (list "poly" "drawing")) +LaygenLayerMap["diffcon"] = (list (list "tcn" "drawing")) +LaygenLayerMap["polycon"] = (list (list "gcn" "drawing")) +LaygenLayerMap["viacn"] = (list (list "vcn" "drawing")) + +LaygenLayerMap["metal0"] = (list (list "m0" "drawing")) +LaygenLayerMap["via0"] = (list (list "v0" "drawing")) +LaygenLayerMap["metal1"] = (list (list "m1" "drawing")) +LaygenLayerMap["via1"] = (list (list "v1" "drawing")) +LaygenLayerMap["metal2"] = (list (list "m2" "drawing")) + +LaygenLayerMap["n"] = (list (list "ndiff" "drawing")) +LaygenLayerMap["p"] = (list (list "pdiff" "drawing")) +LaygenLayerMap["nuv1"] = (list (list "ndiff" "drawing") + (list "NV1" "drawing" UV_dx UV_dy)) +LaygenLayerMap["puv1"] = (list (list "pdiff" "drawing") + (list "PV1" "drawing" UV_dx UV_dy)) +LaygenLayerMap["nuv2"] = (list (list "ndiff" "drawing") + (list "NV2" "drawing" UV_dx UV_dy)) +LaygenLayerMap["puv2"] = (list (list "pdiff" "drawing") + (list "PV2" "drawing" UV_dx UV_dy)) + +; Laygen pin direction mapping +LaygenPinMap = (makeTable "pinMap" nil) +LaygenPinMap["In"] = "input" +LaygenPinMap["Out"] = "output" + +; which layers can turn into pins (and which should add overlapping pin layer) +LaygenPinLayers = (makeTable "pinLayers" nil) +LaygenPinLayers["nwell"] = t +LaygenPinLayers["metal1"] = t +LaygenPinLayers["metal2"] = t +LaygenPinPurposeExists = (makeTable "pinPurposeExists" nil) +LaygenPinPurposeExists["metal1"] = t +LaygenPinPurposeExists["metal2"] = t + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Top Level Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Import a *.gen file into a Virtuoso cell +(defun LaygenImport (filename libName cellName @key (viewName "layout")) + (let (file fields type pins CV) + file = (infile filename) + pins = (makeTable "pins" nil) + pins[LaygenVssName] = "input" + pins[LaygenVccName] = "input" + CV = (dbOpenCellViewByType libName cellName viewName "maskLayout" "w") + (unless file (error "Can't read %s" filename)) + (while (gets line file) + fields = (parseString line " \n") + type = (car fields) + fields = (cdr fields) + (cond (type=="Bbox" (LaygenBbox CV fields)) + (type=="Track" (LaygenTrack CV fields)) + (type=="Wire" (LaygenWire CV fields pins)) + (type=="Pin" (LaygenPin CV fields pins)) + (type=="Device" + (LaygenDevice CV (append fields (parseString (gets line file) " \n")))) + ) + ) + (close file) + + ; label pwell, set LaygenVersion property, save and return + (LaygenRect CV (list (list "pwellSubIso" "id")) + LaygenVssName pins[LaygenVssName] nil 0 0 GridPolyPitch GridDiffPitch) + (dbReplaceProp CV "LaygenVersion" "int" LaygenVersion) + (dbSave CV) + CV + ) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Utility Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Define PRBoundary of cell +(defun LaygenBbox (CV fields) + (let (xl yl xh yh) + vars = (LaygenParseVars fields) + xl = (LaygenCoord vars["xl"]) + xh = (LaygenCoord vars["xh"]) + yl = (LaygenCoord vars["yl"]) + yh = (LaygenCoord vars["yh"]) + (when (and xl xh yl yh) + (dbCreatePRBoundary CV (list xl:yl xl:yh xh:yh xh:yl xl:yl)) + ) + ) + t + ) + +; Draw a wire or via rectangle on several lpp's, with optional bloating and pin +(defun LaygenWire (CV fields pins) + (let (vars xl yl xh yh lpps net) + vars = (LaygenParseVars fields) + xl = (LaygenCoord vars["xl"]) + xh = (LaygenCoord vars["xh"]) + yl = (LaygenCoord vars["yl"]) + yh = (LaygenCoord vars["yh"]) + lpps = LaygenLayerMap[vars["layer"]] + pin = (if LaygenPinLayers[vars["layer"]] pins[vars["net"]] nil) + (LaygenRect CV lpps vars["net"] pin LaygenPinPurposeExists[vars["layer"]] xl yl xh yh) + ) + t + ) + +; Unused +(defun LaygenTrack (CV fields) + t + ) + +; Identify pins +(defun LaygenPin (CV fields pins) + (let (vars) + vars = (LaygenParseVars fields) + pins[vars["name"]] = LaygenPinMap[vars["dir"]] + ) + ) + +; Draw a transistor +(defun LaygenDevice (CV fields) + (let (vars lpps xl yl xh yh) + vars = (LaygenParseVars fields) + xl = (LaygenCoord vars["xl"]) + xh = (LaygenCoord vars["xh"]) + yl = (LaygenCoord vars["yl"]) + yh = (LaygenCoord vars["yh"]) + lpps = LaygenLayerMap[vars["model"]] + (LaygenRect CV lpps nil nil nil xl yl xh yh) + t + ) + ) + +; Convert a LayGen coordinate to Virtuoso +(defun LaygenCoord (str) + (if str (atoi str) * LaygenUnits nil) + ) + +; Parse a bunch of a=b strings into a table +(defun LaygenParseVars (fields) + (let (table ve) + table = (makeTable "variables" nil) + (foreach f fields + ve = (parseString f "=") + (when (and ve (length ve)==2) table[(car ve)] = (cadr ve)) + ) + table + ) + ) + +; Draw bloat/shrunk rectangles on several layers +(defun LaygenRect (CV lpps net pin pin_purpose xl yl xh yh) + (let (rect pinrect lpp dx dy fill) + fill = net && (strncmp net "!" 1)==0 + (foreach lppxy lpps + lpp = (list (car lppxy) (cadr lppxy)) + dx = (caddr lppxy) + (unless dx dx=0) + dy = (cadddr lppxy) + (unless dy dy=0) + (when fill && (cadr lpp)=="drawing" lpp = (list (car lpp) "fill")) + rect = (dbCreateRect CV lpp (list xl-dx:yl-dy xh+dx:yh+dy)) + (when net && !fill + rect->net = (dbFindNetByName CV net) + (unless rect->net rect->net=(dbCreateNet CV net)) + (when pin + pinrect = (if pin_purpose + (dbCreateRect CV (list (car lpp) "pin") (list xl-dx:yl-dy xh+dx:yh+dy)) + rect) + rect->net = rect->net + (dbCreatePin rect->net pinrect)->term->direction = pin + (LaygenLabelPin CV pinrect) + ) + net = nil ; only first lpp gets net + ) + ) + ) + t + ) + +; attach a label to a pin +(defun LaygenLabelPin (view fig) + (let (x0 y0 x1 y1 x y rotation height) + x0 = (car (car fig->bBox)) + y0 = (cadr (car fig->bBox)) + x1 = (car (cadr fig->bBox)) + y1 = (cadr (cadr fig->bBox)) + x = (x0+x1)/2 + y = (y0+y1)/2 + x = MfgGrid * (round x/MfgGrid) + y = MfgGrid * (round y/MfgGrid) + (cond (x1-x0>y1-y0 rotation = "R0" height = y1-y0) + (t rotation = "R90" height = x1-x0) + ) + height = MfgGrid * (round height/MfgGrid/3) ; adjust height + label = (dbCreateLabel view fig->lpp x:y fig->net->name + "centerCenter" rotation "stick" height) ; draw the label + label->parent = fig ; label moves with figure + ) + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/pr.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/pr.il new file mode 100644 index 0000000000..20a7c41199 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/laygen/pr.il @@ -0,0 +1,117 @@ +; Export, place, route, import leaf cell with Laygen +; Copyright Intel 2013 +; Andrew Lines + +; laygen configuration +LaygenExec = "$LAYGENWARD/bin/sgrlfg" +LaygenRpg = "$LAYGENWARD/collateral/d04/d04_rpg.txt" +LaygenArch = "$LAYGENWARD/collateral/d04/d04.laygen" +LaygenTcl = "$LAYGENWARD/collateral/d04/d04_container.tcl" +(sprintf LaygenCmd (strcat + "%s \\\n" + "-rpg_file %s \\\n" + "-arch_file %s \\\n" + "-tcl_container_file %s \\\n" + "-fabric d04 \\\n" + "-upperlayer m2 \\\n" + "-placement_effort 3 \\\n" + "-quality_effort 2 \\\n" + ) + LaygenExec LaygenRpg LaygenArch LaygenTcl) + +LaygenPlaceCmd = (strcat LaygenCmd + "-route no \\\n" + "-generate_snp yes \\\n" + ) + +; place, route, import +(defun LaygenPR (cdlFile libName cellName + @key (num_place 10) + (shrink 0) (horz_routes 4) (h nil) (w nil) + (doCdl t) (doPlace t) (doRoute t) (doImport t)) + (let (CV dir bbox h2 w2 cmd obj file viewName out) + ; get target bbox from floorplan view + CV = (dbOpenCellViewByType libName cellName "floorplan" "maskLayout" "r") + (unless CV (printf "NOTE: no floorplan view\n" cellName)) + (when CV bbox = CV->prBoundary->bBox) + (when !h && CV h = (cadr (cadr bbox)) - (cadr (car bbox))) + (when !w && CV w w = (car (cadr bbox)) - (car (car bbox))) + (when !h || !w (error "Must provide floorplan view or ?h and ?w options\n")) + h2 = (round h/TrackPitch) + w2 = (round w/GridPolyPitch) + w2 = w2-shrink + (when w2<4 doCDL=nil doPlace=nil doRoute=nil doImport=nil) + w = w2*GridPolyPitch + + ; make working dir + (sprintf dir "temp/laygen/%s/%s%d" cellName (if shrink<0 "n" "") (abs shrink)) + (csh (sprintf nil "mkdir -p %s" dir)) + + ; generate SNP + (when doCdl + (printf "Generate SNP for %s\n" cellName) + (sprintf cmd "cdl2snp %s %s %s/%s.snp" cellName cdlFile dir cellName) + (csh cmd) + ) + + ; place + (when doPlace + ; run LayGen in placement mode + (printf "Place %s height=%d width=%d placements=%d\n" cellName h2 w2 num_place) + (sprintf cmd (strcat + LaygenPlaceCmd + "-netlist %s.snp \\\n" + "-outdir place \\\n" + "-target_height %d \\\n" + "-target_area %d \\\n" + "-placement_max_hor_routes %d \\\n" + "-placement_result_idx %d \\\n" + ">& %s.log") + cellName h2 w2 horz_routes*h2 num_place-1 cellName) + out = (outfile (sprintf nil "%s/%s.csh" dir cellName)) + (fprintf out "#!/bin/csh\n%s\n" cmd) + (close out) + (csh (sprintf nil "chmod +x %s/%s.csh" dir cellName)) + (csh (sprintf nil "(cd %s; %s)" dir cmd)) + ) + + ; sweep over num_place placements + (for n 0 num_place-1 + ; delete old laygen views + (sprintf viewName "laygen_%s%d_%d" (if shrink<0 "n" "") (abs shrink) n) + obj = (ddGetObj libName cellName viewName) + (when obj (ddDeleteObj obj)) + + ; route + (sprintf file "%s/tmp_%d.snp" dir n) + (when doRoute && (fileTimeModified file) + (printf "Route %s placement=%d\n" cellName n) + (sprintf cmd (strcat + LaygenCmd + "-netlist tmp_%d.snp \\\n" + "-outdir %d \\\n" + ">& %s.%d.log") + n n cellName n) + out = (outfile (sprintf nil "%s/%s.%d.csh" dir cellName n)) + (fprintf out "#!/bin/csh\n%s\n" cmd) + (close out) + (csh (sprintf nil "chmod +x %s/%s.%d.csh" dir cellName n)) + (csh (sprintf nil "(cd %s; %s)" dir cmd)) + ) + + ; import + (sprintf file "%s/%d/%s/u0.gen" dir n cellName) + (when doImport && + (fileTimeModified file) + (printf "Import %s placement=%d\n" cellName n) + (LaygenImport file libName cellName ?viewName viewName) + ) + ) + ) + t + ) + +; just delete laygen views +(defun LaygenClean (libName cellName @key (num_place 10)) + (LaygenPR "" libName cellName ?doCdl nil ?doPlace nil ?doRoute nil ?doImport nil) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/AddBlkCell.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/AddBlkCell.il new file mode 100644 index 0000000000..6e8870e183 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/AddBlkCell.il @@ -0,0 +1,91 @@ + +defun( AddBlkCell ( CellView ) + let((ColumnList prBound Params blkCellName) + ColumnList = caar(PlacementRegionsGetCellRegionDataColumnList( CellRegionData )) + prBound=( PlacementRegionsGetCellRegionDataBBox CellRegionData ) + + blkCellNameTable=makeTable(`blkCellName) + blkCellNameTable[2]="globals.wires.start_np_blk" + blkCellNameTable[3]="globals.wires.start_npn_blk" + blkCellNameTable[4]="globals.wires.start_npnp_blk" + blkCellName=blkCellNameTable[length(ColumnList)-1] + Params=list( + list( "height" "int" ceiling((topEdge(prBound)-bottomEdge(prBound))/3.12 )) + list( "width" "int" ceiling((rightEdge(prBound)-leftEdge(prBound)-2.08)/0.26) ) + list( "metal_implant_guide" "boolean" nil ) + list( "PO_GRID" "boolean" nil ) + list( "PO_BLOCKAGE" "boolean" nil ) + list( "M3_BLOCKAGE" "boolean" nil ) + list( "implants" "boolean" nil ) + + + ) + + Column1=car(ColumnList) + ColumnList=cdr(ColumnList) + + Params=cons( list( "firstsetm2move" "int" ceiling((rightEdge(Column1)-0.325)/0.13) ) Params) + + + dbCreateParamInstByMasterName( + CellView + "globals" + blkCellName + "layout" + "start_blk" + list(leftEdge(prBound) bottomEdge(prBound)) + "R0" + 1 + Params + + ) + ) +) + +defun( AddLeafBlockageCell ( CellView ) + let(( prBound Params blkCellName) + prBound=CellView->prBoundary->bBox + blkCellName="globals.wires.leaf_blockage" + Params=list( + list( "height" "int" ceiling((topEdge(prBound)-bottomEdge(prBound))/3.12 )) + list( "width" "int" ceiling((rightEdge(prBound)-leftEdge(prBound)-2.08)/0.26) ) + list( "PO_GRID" "boolean" nil ) + list( "PO_BLOCKAGE" "boolean" t ) + list( "M3_BLOCKAGE" "boolean" t ) + + + ) + + dbCreateParamInstByMasterName( + CellView + "globals" + blkCellName + "layout" + "leaf_blockage" + list(leftEdge(prBound) bottomEdge(prBound)) + "R0" + 1 + Params + + ) + ) +) +defun( DeleteLeafBlockageCell ( CellView ) + let((inst) + inst=dbFindAnyInstByName( CellView "leaf_blockage") + if( inst then dbDeleteObject( inst )) + ) +) + +defun( SnapGatesStacksToPitch ( CellView ) + let((x y inst) + foreach( inst CellView~>instances + if( inst~>libName=="gate" || inst~>libName=="stack" then + y=cadr(inst->xy) + x=car(inst->xy) + y=0.13*floor(y/0.13) + inst->xy=list(x y) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreator.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreator.il new file mode 100644 index 0000000000..d861528406 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreator.il @@ -0,0 +1,5047 @@ +(defun MakeBuffer (CellView ViewName) + (let (text parameter1 parameter2 parameter3 parameter4 cordM2_M1 INST SHAPE Inst_Reset cordpx1 cordpx2 cordnx1 cordnx2 cordnrx1 cordnrx2 cordRRx cordRaRx cordR2Rx cordR2Lx cordLeRx cordResRx cordUResRx cordPLx cordPLx1 cordPLx2 ixy1 ixy2 diffpass centreXY cordPCLx DIFF Lpinx foldss) + fl = infile("Parameter.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + parameter1 = nth(0 text) + parameter2 = nth(1 text) + parameter3 = nth(2 text) + parameter4 = nth(3 text) + + ;setting instance parameters as per the spec file + foreach(INST CellView->instances + (let (N P Nparam Pparam paraN1 paraN2 paraP1 paraP2 paraP3 paraP4 paraP5 paraP6 paraP7 paraP8 paraP9 paraP10) + when( (INST->name==parameter1) && (INST->cellName=="gate.INV.0-L1_1-R") + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + dbReplaceProp(INST "NW1" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( ( (INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.NMOS_CHAIN_5.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")) + paraN1 = strcat( parameter1 "." "N1") + paraN2 = strcat( parameter1 "." "N2") + paraP1 = strcat( parameter1 "." "P1") + paraP2 = strcat( parameter1 "." "P2") + paraP3 = strcat( parameter1 "." "P3") + paraP4 = strcat( parameter1 "." "P4") + paraP5 = strcat( parameter1 "." "P5") + paraP6 = strcat( parameter1 "." "P6") + paraP7 = strcat( parameter1 "." "P7") + paraP8 = strcat( parameter1 "." "P8") + paraP9 = strcat( parameter1 "." "P9") + paraP10 = strcat( parameter1 "." "P10") + when(((INST->name==paraN1) || (INST->name==paraP1) || (INST->name==paraN2) || (INST->name==paraP2) || (INST->name==paraP3) || (INST->name==paraP4) || (INST->name==paraP5) || (INST->name==paraP6) || (INST->name==paraP7) || (INST->name==paraP8) || (INST->name==paraP9) || (INST->name==paraP10)) + N=evalstring(parameter3) + Nparam=N/2000000 + P=evalstring(parameter4) + Pparam=P/2000000 + dbReplaceProp(INST "NW2" "float" Nparam) + dbReplaceProp(INST "NW5" "float" Nparam) + dbReplaceProp(INST "PW2" "float" Pparam) + dbReplaceProp(INST "PW1" "float" Pparam) + )) + ))) + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordPx cordPx1 cordPx2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.N1")) + cordNx=caar(INST~>bBox) + cordNx1=cordNx+0.02 + cordnx1=cordNx1 + cordNx2=cordNx1-0.06 + cordnx2=cordNx2) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.P1")) + cordPx=caadr(INST~>bBox) + Lpinx=caar(INST~>bBox) + cordPx1=cordPx-0.02 + cordpx1=cordPx1 + cordPx2=cordPx1+0.06 + cordpx2=cordPx2) + )) + +;calculating variables for moving wires, vias and instances + + foreach(INST CellView->instances + (let (cordNRx cordNRx1 cordNRx2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.3")||(INST->name=="R.1")) + diff=xy1-bx1 + XY=((cordpx2+0.25+diff):xy2) + dbSet(INST XY "xy") + ixy1=car(INST~>xy) + ixy2=cadr(INST~>xy)) + )) + + foreach(INST CellView~>instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 pnts bbox diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.915)&&(xy1==1.3))||((xy2==5.655)&&(xy1==1.3))||((xy2==1.495)&&(xy1==1.295))||((xy2==1.235)&&(xy1==1.295))) + XY=(cordpx2+0.1:xy2) + dbSet(INST XY "xy")) ;moves M1_poly vias on the right side of C2 gates in 1st coloumn + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((bx1==1.51)&&(bx2==1.72)) + XY=(ixy1-0.195:xy2) + dbSet(INST XY "xy")) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((bx1==1.9)&&(bx2==2.11)) + XY=(ixy1+0.195:xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.2")||(INST->name=="R.0")) + dbReplaceProp(INST "n_contact_offset" "float" (cordnx2+0.025))) + when(((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")||(INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")) && ((INST->name=="RP.3")||(INST->name=="RP.1")||(INST->name=="_r.3.P2")||(INST->name=="_r.1.P1")||(INST->name=="_r.3.P1")||(INST->name=="_r.1.P2")) + XY=((ixy1-0.01):xy2) + dbSet(INST XY "xy")) + when(((INST->cellName=="stack.NMOS_CHAIN_1.0-L1-R")||(INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R")) && ((INST->name=="RN.3")||(INST->name=="RN.1")||(INST->name=="_r.3.N2")||(INST->name=="_r.1.N1")||(INST->name=="_r.3.N1")||(INST->name=="_r.1.N2")) + XY=((ixy1+0.01):xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="R.3") + cordRRx=caadr(INST~>bBox)) + + )) + + foreach(INST CellView->instances + (let (cordNRx cordNRx1 cordNRx2 xy1 xy2 XY bx1 bx2 by1 by2 diff cordplx) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R")&&(INST->name=="_r.3.N1") + cordNRx=caadr(INST~>bBox) + cordNRx1=cordNRx-0.02 + cordnrx1=cordNRx1 + cordNRx2=cordNRx1+0.06 + cordnrx2=cordNRx2) + when((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")&&(INST->name=="_r.3.P1") + cordPLx=caadr(INST~>bBox) + cordplx=caar(INST~>bBox) + cordPLx1=cordplx+0.02 + cordPLx2=cordPLx1-0.06) + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="R.2") + cordR2Lx=caar(INST~>bBox) + cordR2Rx=caadr(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="L.e") + foldss=cadadr(INST~>bBox) + cordLeRx=caadr(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="Reset") + cordResRx=caar(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="_Reset") + cordUResRx=caadr(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R")&&((INST->name=="R.3")||(INST->name=="R.1")) + when((ixy1+0.36)>=(cordRRx-0.255) + dbReplaceProp(INST "n_contact_offset" "float" (ixy1+0.36-cordRRx+0.255))) + when((ixy1+0.36)<(cordRRx-0.255) + dbReplaceProp(INST "n_contact_offset" "float" 0.065))) + + )) + + foreach(INST CellView~>instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 pnts bbox diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.785)&&(xy1==0.115))||((xy2==5.525)&&(xy1==0.115))||((xy2==5.265)&&(xy1==0.11))||((xy2==1.365)&&(xy1==0.115))||((xy2==1.105)&&(xy1==0.115))||((xy2==0.845)&&(xy1==0.11))) + when(cordR2Lx>=cordnx2 + XY=(cordnx2-0.1:xy2)) + when(cordR2LxcellName=="M1_POLYmin")&&(((xy2==5.005)&&(xy1==1.15))||((xy2==4.745)&&(xy1==1.15))||((xy2==0.585)&&(xy1==1.145))||((xy2==0.325)&&(xy1==1.145))) + XY=(cordR2Rx+0.15:xy2) + dbSet(INST XY "xy")) ;moves M1_poly vias on the left side of the C2 gates in 2nd coloumn + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="R.3") + cordRaRx=caadr(INST~>bBox)) + when((INST->cellName=="stack.NPLUG.0")&&(xy1==2.44&&xy2==2.335) + when(cordRaRx>=(cordnrx2+0.03) + XY=((cordRaRx+0.025):xy2)) + when(cordRaRx<(cordnrx2+0.03) + XY=((cordnrx2+0.05):xy2)) + dbSet(INST XY "xy"));moves NPLUG on right side + when((INST->cellName=="stack.NPLUG.0")&&(xy1==0.13&&xy2==3.38) + when(cordR2Lx>=cordnx2 + XY=((cordnx2-0.08):xy2)) + when(cordR2LxcellName=="stack.PPLUG.0")&&(xy1==1.64&&xy2==1.785) + XY=((ixy1-0.17):xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="stack.NMOS_CHAIN_5.0-L1-R")&&((INST->name=="rv.N2")||(INST->name=="rv.N1")) + diff=mag((bx2-bx1)-(cordnrx2-0.04)) + diffpass=diff + XY=(diff:xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="L.e") + when(foldss==3.08 + pnts=(0.44:2.86) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil pnts "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) )) + when(foldss==2.95 + pnts=(0.44:2.86) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil pnts "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((foldss==2.56)||(foldss==2.3))&&((xy1==0.44&&xy2==2.6)||(xy1==0.83&&xy2==2.6)) + dbDeleteObject(INST)) + )) + + foreach(INST CellView~>instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 pnts bbox diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.135)&&(xy1==2.33))||((xy2==4.875)&&(xy1==2.33))||((xy2==5.395)&&(xy1==2.33))||((xy2==0.975)&&(xy1==2.355))||((xy2==0.715)&&(xy1==2.335))||((xy2==0.455)&&(xy1==2.335))) + when(cordRaRx>=(cordnrx2+0.03) + XY=(cordRaRx+0.075:xy2)) + when(cordRaRx<(cordnrx2+0.03) + XY=(cordnrx2+0.1:xy2)) + dbSet(INST XY "xy")) ;moves M1_poly vias on the right side of the C2 gates in 2nd coloumn + + when((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")&&((INST->name=="rv.P1")||(INST->name=="rv.P2")||(INST->name=="rv.P3")||(INST->name=="rv.P4")||(INST->name=="rv.P5")||(INST->name=="rv.P6")||(INST->name=="rv.P7")||(INST->name=="rv.P8")||(INST->name=="rv.P9")||(INST->name=="rv.P10")) + XY=((diffpass-0.02):xy2) + centreXY=diffpass-0.02 + diff=bx2-bx1 + cordPCLx=centreXY-diff + dbSet(INST XY "xy")) + + )) + + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((((bx2==0.545)&&(by2==5.62))||((bx2==0.53)&&(by2==1.2)))&&(SHAPE~>layerName=="M1") + pnts=list(x1:y1 cordnx1:y2 cordnx1:y3 x4:y4 x5:y5 cordnx2:y6 cordnx2:y7 x8:y8) + dbSet(SHAPE pnts "points")) ;to move M1 of C2 van berkel gate connecting internal nets on the left side of _r.2 and _r.0 + when((((bx1==1.9)&&(by1==5.04))||((bx1==1.9)&&(by1==0.62)))&&(SHAPE~>layerName=="M1") + pnts=list(cordnrx2:y1 (ixy1+0.09):y2 (ixy1+0.09):y3 cordnrx1:y4 cordnrx1:y5 (ixy1+0.09):y6 (ixy1+0.09):y7 cordnrx2:y8) + dbSet(SHAPE pnts "points")) ; to move M1 of C2 van berkel gate connecting internal nets on the right side of _r.3 and _r.1 + when((((bx1==2.005)&&(by1==5.045))||((bx1==2.005)&&(by1==0.625))||((bx1==2.005)&&(by1==4.785))||((bx1==2.005)&&(by1==0.365)))&&(SHAPE~>layerName=="OD") + bbox=list((ixy1+0.1):by1 (ixy1+0.17):by2) + dbSet(SHAPE bbox "bBox")) ; to move OD of C2 van berkel gate connecting internal nets on the right side of _r.3 and _r.1 + when((((bx1==2.025)&&(by1==5.05))||((bx1==2.025)&&(by1==0.63))||((bx1==2.025)&&(by1==4.79))||((bx1==2.025)&&(by1==0.37)))&&(SHAPE~>layerName=="CO") + bbox=list((ixy1+0.12):by1 (ixy1+0.16):by2) + dbSet(SHAPE bbox "bBox")) ; to move CO of C2 van berkel gate connecting internal nets on the right side of _r.3 and _r.1 + when((SHAPE~>layerName=="M2") && ((SHAPE~>net~>name=="L.2")||(SHAPE~>net~>name=="L.0")) + when(cordR2Lx>=cordnx2 + pnts=list((cordnx2-0.1):by1 (cordnx2-0.1):by2)) + when(cordR2LxlayerName=="M2") && ((SHAPE~>net~>name=="R.3")||(SHAPE~>net~>name=="L.1"))&&(x1==2.325) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((cordRaRx+0.075):by1 (cordRaRx+0.075):by2)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list((cordnrx2+0.1):by1 (cordnrx2+0.1):by2)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2") && (SHAPE~>net~>name=="L.1")&&(x1==1.425) + pnts=list((ixy1-0.385):by1 (ixy1-0.385):by2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2") && ((SHAPE~>net~>name=="_r.2")||(SHAPE~>net~>name=="_r.0")) + when(cordR2Lx>=cordnx2 + pnts=list((cordnx2+0.04):by1 (cordnx2+0.04):by2)) + when(cordR2LxlayerName=="M2") && ((SHAPE~>net~>name=="_r.3")||(SHAPE~>net~>name=="_r.1")) + pnts=list((cordRaRx-0.06):by1 (cordRaRx-0.06):by2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && ((SHAPE~>net~>name=="L.2")||(SHAPE~>net~>name=="L.0")) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.13):by1 (cordnx2-0.07):by2)) + when(cordR2LxlayerName=="PO")&&(((bx2==0.35)&&(by2==5.8))||((bx2==0.35)&&(by2==5.54))||((bx2==0.89)&&(by2==5.28))||((bx2==0.35)&&(by2==1.38))||((bx2==0.35)&&(by2==1.12))||((bx2==0.89)&&(by2==0.86))) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.1):by1 bx2:by2)) + when(cordR2LxlayerName=="PO")&&(((bx1==1.055)&&(by1==5.9))||((bx1==1.055)&&(by1==5.64))||((bx1==1.055)&&(by1==1.48))||((bx1==1.055)&&(by1==1.22))) + bbox=list(bx1:by1 (cordpx2+0.1):by2) + dbSet(SHAPE bbox "bBox")); moves poly on the right side of c2 gates R.e in 1st coloumn of gates + when((SHAPE~>layerName=="PO")&&(((bx1==1.67)&&(by1==5.12))||((bx1==1.68)&&(by1==4.86))||((bx1==1.63)&&(by1==0.7))||((bx1==1.695)&&(by1==0.44))||((bx1==1.54)&&(by1==0.96))||((bx1==1.54)&&(by1==5.38))) + bbox=list((ixy1-0.26):by1 (cordRaRx+0.075):by2) + dbSet(SHAPE bbox "bBox")); moves poly on the right side of c2 gates R.e and L.1 in 2nd coloumn of gates + when((SHAPE~>layerName=="M1")&& (SHAPE~>net~>name=="R.2") + when(cordR2Lx>=cordnx2 + pnts=list((cordnx2-0.11):y1 (cordnx2-0.11):y2 x3:y3)) + when(cordR2LxlayerName=="M1")&&(SHAPE~>net~>name=="R.0")&&(by2==0.875) + when(cordR2Lx>=cordnx2 + pnts=list((cordnx2-0.11):y1 (cordnx2-0.11):y2 x3:y3)) + when(cordR2LxlayerName=="M1") + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.015):by1 (cordnx2+0.065):by2)) + when(cordR2LxlayerName=="M1") && ((SHAPE~>net~>name=="_r.2")||(SHAPE~>net~>name=="_r.0"))&&(((bx2==0.87)&&(by2==5.75))||((bx1==0.22)&&(by1==1.27))) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2+0.01):by1 bx2:by2)) + when(cordR2LxlayerName=="M1") && (SHAPE~>net~>name=="R.e")&&(((by1==5.625)&&(by2==5.945))||((by1==1.205)&&(by2==1.725))) + bbox=list((cordpx2+0.07):by1 (cordpx2+0.13):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 of R.e on the right side of the 1st coloumn of gates + when((SHAPE~>layerName=="M1") && ((SHAPE~>net~>name=="R.e")||(SHAPE~>net~>name=="L.1")||(SHAPE~>net~>name=="_r.3"))&&(((by1==4.845)&&(by2==5.165))||((by1==0.425)&&(by2==0.745))||((by1==3.62)&&(by2==4.445))) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx+0.045):by1 (cordRaRx+0.105):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2+0.07):by1 (cordnrx2+0.13):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M1 of R.e and L.1 on the right side of the 2nd coloumn of gates + when((SHAPE~>layerName=="M2") && (SHAPE~>net~>name=="Vdd")&&((bx1==1.535)&&(bx2==1.695)) + bbox=list((ixy1-0.275):by1 (ixy1-0.115):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M2") && (SHAPE~>net~>name=="GND")&&((bx1==1.925)&&(bx2==2.085)) + bbox=list((ixy1+0.115):by1 (ixy1+0.275):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M2") &&((bx1==1.78)&&(bx2==1.84)) + pnts=list(ixy1:by1 ixy1:by2) + dbSet(SHAPE pnts "points")) ;moves M2 in the centre of the gates of 2nd coloumn connecting internal nets and rv net + when((SHAPE~>layerName=="M1") &&((bx1==0.84)&&(bx2==1.565)) + pnts=list(x1:y1 (cordLeRx-0.28):y2 (cordLeRx-0.28):y3 (cordPCLx+0.11):y4 (cordPCLx+0.11):y5 (diffpass-0.1):y6) + dbSet(SHAPE pnts "points")) ;moves M1 connecting the Vdd between L.e and rv.P1 + when((SHAPE~>layerName=="M1") &&((bx1==1.33)&&(by1==2.635)) + bbox=list((cordLeRx-0.11):by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting rv input of L.e gate with the rv on M2 of NAND5 + when((SHAPE~>layerName=="M1") &&(((bx1==1.125)&&(by1==4.715))||((bx1==1.115)&&(by1==0.11))) + bbox=list((cordR2Rx+0.12):by1 (cordR2Rx+0.18):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 of L.3 on the left side of C.2 gate in 2nd coloumn + when((SHAPE~>layerName=="M2") &&((bx1==1.125)&&(by1==4.495)) + pnts=list((cordR2Rx+0.15):by1 (cordR2Rx+0.15):by2) + dbSet(SHAPE pnts "points")) ;moves M2 connecting the M1 input of L.3 of C2 gate and M3 pin + when((SHAPE~>layerName=="M2") &&((bx1==1.25)&&(by1==1.715)) + pnts=list((cordR2Rx+0.28):by1 (cordR2Rx+0.28):by2) + dbSet(SHAPE pnts "points")) ;moves M2 connecting R.e between the C.2 gates in the upper half of the leaf cell + when((SHAPE~>layerName=="M1") &&(((bx1==1.78)&&(by1==5.3))||((bx1==1.78)&&(by1==4.78))||((bx1==1.81)&&(by1==0.88))||((bx1==1.81)&&(by1==0.36))) + bbox=list((ixy1-0.03):by1 (ixy1+0.19):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M1")&&((bx1==1.78&&by1==5.785)||(bx1==1.78&&by1==1.365)) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((cordRaRx+0.075):y1 ixy1:y2 ixy1:y3)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list((cordnrx2+0.1):y1 ixy1:y2 ixy1:y3)) + dbSet(SHAPE pnts "points"));moves M1 for R.3 and R.1 connecting to the centre of the inverter + when((SHAPE~>layerName=="M1")&&(bx1==2.29&&by1==5.245) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx+0.035):by1 (cordRaRx+0.115):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2+0.06):by1 (cordRaRx+0.14):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M1")&&(bx1==2.315&&by1==0.995) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx+0.055):by1 (cordRaRx+0.115):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2+0.07):by1 (cordnrx2+0.13):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M1")&&((bx1==2.175&&by1==5.56)||(bx1==2.175&&by1==1.13)) + bbox=list((cordRaRx-0.115):by1 (cordRaRx-0.005):by2) + dbSet(SHAPE bbox "bBox")) ; moves M1 shapes connecting poly inputs on the right side of gates R.3 and R.1with M2 of _r.3 and _r.1 + when((SHAPE~>layerName=="CO")&&(SHAPE~>net~>name=="_r.3") + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx+0.055):by1 (cordRaRx+0.095):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2+0.08):by1 (cordnrx2+0.12):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&(SHAPE~>net~>name=="_r.3") + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((centreXY-0.18):by1 (cordRaRx+0.145):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((centreXY-0.18):by1 (cordnrx2+0.17):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&(SHAPE~>net~>name=="_r.1") + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((centreXY-0.18):by1 (cordRaRx+0.015):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((centreXY-0.18):by1 (cordnrx2+0.04):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&(SHAPE~>net~>name=="_Reset") + when(cordPCLx<=(ixy1-0.36) + bbox=list((centreXY+0.18):by1 (cordPCLx-0.15):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((centreXY+0.18):by1 (ixy1-0.47):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&(SHAPE~>net~>name=="_r.0") + when(cordPCLx<=(ixy1-0.36) + bbox=list((centreXY+0.18):by1 (cordPCLx-0.28):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((centreXY+0.18):by1 (ixy1-0.6):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&(SHAPE~>net~>name=="_r.2") + when(cordPCLx<=(ixy1-0.36) + bbox=list((centreXY+0.18):by1 (cordPCLx-0.41):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((centreXY+0.18):by1 (ixy1-0.73):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&(((bx1==1.145)&&(by1==0.57))||((bx1==1.145)&&(by1==0.31))||((bx1==1.17)&&(by1==4.99))||((bx1==1.17)&&(by1==4.73))) + bbox=list((cordR2Rx+0.15):by1 (ixy1+0.1):by2) + dbSet(SHAPE bbox "bBox")) ;moves poly connecting the L.3 inputs + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.1")&&((by1==3.36)&&(by2==4.175)) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx-0.085):by1 (cordRaRx-0.025):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2-0.06):by1 cordnrx2:by2)) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting poly inputs of NAND5 for _r.1 + when((SHAPE~>layerName=="CO")&&(SHAPE~>net~>name=="_r.1") + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx-0.075):by1 (cordRaRx-0.035):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2-0.05):by1 (cordnrx2-0.01):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="CO")&&(SHAPE~>net~>name=="_Reset") + when(cordPCLx<=(ixy1-0.36) + bbox=list((cordPCLx-0.09):by1 (cordPCLx-0.05):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((ixy1-0.41):by1 (ixy1-0.37):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="CO")&&(SHAPE~>net~>name=="_r.0") + when(cordPCLx<=(ixy1-0.36) + bbox=list((cordPCLx-0.22):by1 (cordPCLx-0.18):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((ixy1-0.54):by1 (ixy1-0.5):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="CO")&&(SHAPE~>net~>name=="_r.2") + when(cordPCLx<=(ixy1-0.36) + bbox=list((cordPCLx-0.35):by1 (cordPCLx-0.31):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((ixy1-0.67):by1 (ixy1-0.63):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.1")&&((bx1==2.14)&&(by1==2.73)) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((cordRaRx-0.025):y1 (cordRaRx-0.085):y2 (cordRaRx-0.085):y3 (cordRaRx-0.055):y4 (cordRaRx-0.055):y5 (cordRaRx-0.025):y6)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list(cordnrx2:y1 (cordnrx2-0.06):y2 (cordnrx2-0.06):y3 (cordRaRx-0.055):y4 (cordRaRx-0.055):y5 cordnrx2:y6)) + dbSet(SHAPE pnts "points")) ;moves M1 connecting M2 and M1 between poly inputs for _r.1 + when((SHAPE~>layerName=="M1")&&(bx1==1.315&&by1==3.155) + when(cordPCLx<=(ixy1-0.36) + bbox=list((cordPCLx-0.1):by1 (cordPCLx-0.04):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((ixy1-0.42):by1 (ixy1-0.36):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting the _Reset of NAND5 gate + when((SHAPE~>layerName=="M1")&&(bx1==1.185&&by1==3.29) + when(cordPCLx<=(ixy1-0.36) + bbox=list((cordPCLx-0.23):by1 (cordPCLx-0.17):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((ixy1-0.55):by1 (ixy1-0.49):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting the _r.0 of NAND5 gate + when((SHAPE~>layerName=="M1")&&(bx1==1.055&&by1==3.515) + when(cordPCLx<=(ixy1-0.36) + bbox=list((cordPCLx-0.36):by1 (cordPCLx-0.3):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list((ixy1-0.68):by1 (ixy1-0.62):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting the _r.2 of NAND5 gate + when((SHAPE~>layerName=="M1")&&(bx1==0.25&&by1==4.24) + when((cordPCLx<=(ixy1-0.36))&&(cordR2Lx>=cordnx2) + bbox=list((cordnx2+0.04):by1 (cordPCLx-0.3):by2)) + when((cordPCLx<=(ixy1-0.36))&&(cordR2Lx(ixy1-0.36))&&(cordR2Lx>=cordnx2) + bbox=list((cordnx2+0.04):by1 (ixy1-0.62):by2)) + when((cordPCLx>(ixy1-0.36))&&(cordR2LxlayerName=="M1")&&(bx1==0.25&&by1==3.29) + when((cordPCLx<=(ixy1-0.36))&&(cordR2Lx>=cordnx2) + bbox=list((cordnx2+0.04):by1 (cordPCLx-0.17):by2)) + when((cordPCLx<=(ixy1-0.36))&&(cordR2Lx(ixy1-0.36))&&(cordR2Lx>=cordnx2) + bbox=list((cordnx2+0.04):by1 (ixy1-0.48):by2)) + when((cordPCLx>(ixy1-0.36))&&(cordR2LxlayerName=="M1")&&(bx1==0.635&&by1==3.155) + when(cordPCLx<=(ixy1-0.36) + bbox=list(bx1:by1 (cordPCLx-0.04):by2)) + when(cordPCLx>(ixy1-0.36) + bbox=list(bx1:by1 (ixy1-0.35):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting the M2 with M1 of _r.0 of NAND5 gate + when((SHAPE~>layerName=="M1")&&((bx1==1.495&&by1==4.13)||(bx1==1.495&&by1==3.87)||(bx1==1.495&&by1==3.61)||(bx1==1.495&&by1==3.35)) + bbox=list((centreXY-0.18):by1 (ixy1-0.115):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting to the M2_M1 Vdd vias of NAND5 gate + when((SHAPE~>layerName=="M1")&&(bx1==2.15&&by1==4.27) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx-0.055):by1 (cordRaRx+0.075):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordRaRx-0.055):by1 (cordnrx2+0.1):by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M1")&&((bx1==1.422&&by1==4.91&&by2==4.97&&bx2==2.225)||(bx1==1.415&&by1==0.49&&by2==0.55&&bx2==2.223)) + bbox=list((ixy1-0.2):by1 (cordRaRx-0.055):by2) + dbSet(SHAPE bbox "bBox")) ;moves the _r.3 and _r.1 M1 wires connecting the output of C2 gate + when((SHAPE~>layerName=="M1")&&((bx1==1.465&&by2==4.06)||(bx1==1.465&&by2==3.54)||(bx1==1.465&&by2==3.28)) + bbox=list((centreXY-0.25):by1 ixy1:by2) + ;pnts=list((ixy1+0.03):y1 (centreXY-0.18):y2 (centreXY-0.18):y3 (ixy1-0.03):y4 (ixy1-0.03):y5 (centreXY-0.18):y6 (centreXY-0.18):y7 (ixy1+0.03):y8) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting rv of NAND5 gate in the centre + when((SHAPE~>layerName=="M1")&&(bx1==1.345&&by2==4.32) + bbox=list((centreXY-0.25):by1 ixy1:by2) + when(cordPCLx<=(ixy1-0.36) + pnts=list((centreXY-0.15):y1 (cordPCLx-0.04):y2 (cordPCLx-0.04):y3 (centreXY-0.15):y4 (centreXY-0.15):y5 (cordPCLx+0.02):y6 (cordPCLx+0.02):y7 (centreXY-0.15):y8)) + when(cordPCLx>(ixy1-0.36) + pnts=list((centreXY-0.15):y1 (ixy1-0.42):y2 (ixy1-0.42):y3 (centreXY-0.15):y4 (centreXY-0.15):y5 (ixy1-0.36):y6 (ixy1-0.36):y7 (centreXY-0.15):y8)) + dbSet(SHAPE pnts "points")) ;moves M1 connecting rv of NAND5 gate on the left side + when((SHAPE~>layerName=="M1")&&(bx1==1.465&&by2==3.8) + bbox=list((centreXY-0.25):by1 (centreXY+0.25):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting rv of the output of the NAND5 gate + when((SHAPE~>layerName=="PP")&&(bx1==2.545&&by1==2.335&&bx2==2.6&&by2==2.86) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx+0.13):by1 (cordRaRx+0.185):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2+0.155):by1 (cordnrx2+0.21):by2)) + dbSet(SHAPE bbox "bBox")) ;moves PP on the right side of NPLUG + when((SHAPE~>layerName=="PP")&&(bx1==0&&by1==3.38&&bx2==0.08&&by2==3.905) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.21):by1 (cordnx2-0.13):by2)) + when(cordR2LxlayerName=="M1")&&(bx1==1.28&&by2==4.885) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((ixy1-0.515):y1 (cordRaRx+0.075):y2 (cordRaRx+0.075):y3)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list((ixy1-0.515):y1 (cordnrx2+0.1):y2 (cordnrx2+0.1):y3)) + dbSet(SHAPE pnts "points")) ;moves M1 connecting R.e on M2 and M1 on the poly inputs of C.2 gate in R.3 region + when((SHAPE~>layerName=="M1")&&(bx1==0.785&&by2==4.45) + bbox=list(bx1:by1 (centreXY-0.15):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting Vdd and with the PMOS rv.P10 + when((SHAPE~>layerName=="M1")&&((bx1==1.265&&by2==1.725)||(bx1==1.27&&by2==6.13)) + bbox=list((cordpx2+0.07):by1 (cordpx2+0.13):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting the M2_M1 vias and the R.e inputs of C.2 gates + when((SHAPE~>layerName=="M1")&&(bx1==2.3&&by1==0.995) + pnts=list((cordRaRx+0.075):by1 (cordRaRx+0.075):by2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2")&&(bx1==1.25&&by1==0.085)&&(SHAPE~>net~>name=="R.e") + pnts=list((ixy1-0.515):by1 (ixy1-0.515):by2) + dbSet(SHAPE pnts "points"));moves M2 R.e connecting all the C2 gates + when((SHAPE~>layerName=="M1")&&((bx1==1.225&&by2==1.725)||(bx1==1.275&&by2==6.13)) + bbox=list((cordpx2+0.1):by1 (ixy1-0.515):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting R.e on M2 with R.e on the inputs of C2 gates + when((SHAPE~>layerName=="M1")&&(bx1==1.13&&by2==0.17) + bbox=list((cordR2Rx+0.15):by1 (ixy1-0.515):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting the R.e on M2 in the bottom portion + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="_RESET") + when(cordR2Lx>=cordnx2 + pnts=list((cordnx2-0.1):by1 (cordnx2-0.1):by2)) + when(cordR2LxlayerName=="M1")&&(SHAPE~>net~>name=="_RESET") + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.1):by1 (cordResRx+0.08):by2)) + when(cordR2LxlayerName=="M1")&&(SHAPE~>net~>name=="Reset") + pnts=list(x1:y1 (cordUResRx-0.08):y2 (cordUResRx-0.08):y3) + dbSet(SHAPE pnts "points")) ;moves M1 connecting the Reset input of _Reset gate + when((SHAPE~>layerName=="M2")&&((bx1==1.395&&by2==5.355)||(bx1==1.395&&by2==0.935)) + bbox=list((ixy1-0.415):by1 (ixy1-0.355):by2) + dbSet(SHAPE bbox "bBox")) ;moves the M2 internal nets connecting C2 gates of 2nd coloumn on the left side + when((SHAPE~>layerName=="PO")&&(bx1==0.99&&bx2==1.07) + bbox=list(cordR2Rx:by1 (cordR2Rx+0.08):by2) + dbSet(SHAPE bbox "bBox")) ;moves cut_poly associated with the R.0 and R.2 gates + when((SHAPE~>layerName=="PO")&&(bx1==1.37&&bx2==1.45) + bbox=list((cordpx2+0.17):by1 (cordpx2+0.25):by2) + dbSet(SHAPE bbox "bBox")) ;moves cut_poly associated with the R.1 and R.3 gates + when((SHAPE~>layerName=="M1")&&((bx1==1.4&&by1==5.3)||(bx1==1.37&&by1==4.78)||(bx1==1.4&&by1==0.88)||(bx1==1.37&&by1==0.36)) + bbox=list((ixy1-0.385):by1 (ixy1-0.09):by2) + dbSet(SHAPE bbox "bBox")) ;moves M1 connecting the M2 which is connecting the internal nets on the PMOS side of the C2 gate in 2nd coloumn + when((SHAPE~>layerName=="OD")&&((bx1==1.52&&by1==5.045)||(bx1==1.52&&by1==4.785)||(bx1==1.52&&by1==0.625)||(bx1==1.52&&by1==0.365)) + bbox=list((ixy1-0.29):by1 (ixy1-0.11):by2) + dbSet(SHAPE bbox "bBox")) ;moves the OD in the C2 gates of 2nd coloumn i.e in case of internal nets + when((SHAPE~>layerName=="CO")&&((bx1==1.54&&by1==5.05)||(bx1==1.54&&by1==4.79)||(bx1==1.54&&by1==0.63)||(bx1==1.54&&by1==0.37)) + bbox=list((ixy1-0.27):by1 (ixy1-0.23):by2) + dbSet(SHAPE bbox "bBox")) ;moves CO used for inernal nets in the C2 gates of 2nd colomn + when((SHAPE~>layerName=="CO")&&((bx1==1.65&&by1==5.05)||(bx1==1.65&&by1==4.79)||(bx1==1.65&&by1==0.63)||(bx1==1.65&&by1==0.37)) + bbox=list((ixy1-0.16):by1 (ixy1-0.12):by2) + dbSet(SHAPE bbox "bBox")) ;moves CO used for inernal nets in the C2 gates of 2nd colomn + when((SHAPE~>layerName=="M1")&&((bx1==1.25&&by1==5.04)||(bx1==1.25&&by1==0.62)) + pnts=list((ixy1-0.09):y1 cordPLx1:y2 cordPLx1:y3 (ixy1-0.09):y4 (ixy1-0.09):y5 cordPLx2:y6 cordPLx2:y7 (ixy1-0.09):y8) + dbSet(SHAPE pnts "points")) ;moves M1 connecting internal nets n left side of C2 gate in 2nd coloumn + when((SHAPE~>layerName=="M1")&&(bx1==2.08&&by1==2.305) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((cordRaRx+0.055):y1 (cordRaRx-0.005):y2 (cordRaRx-0.005):y3 (ixy1+0.195):y4 (ixy1+0.195):y5 (cordRaRx+0.055):y6)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list((cordnrx2+0.08):y1 (cordnrx2+0.02):y2 (cordnrx2+0.02):y3 (ixy1+0.195):y4 (ixy1+0.195):y5 (cordnrx2+0.08):y6)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M3")&&((SHAPE~>net~>name=="R.2")||(SHAPE~>net~>name=="R.0")) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list(bx1:by1 (cordRaRx+0.145):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list(bx1:by1 (cordnrx2+0.17):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M3 pins R.2 and R.0 + when((SHAPE~>layerName=="M3")&&(SHAPE~>net~>name=="R.1") + when(cordRaRx>=(cordnrx2+0.03) + bbox=list(ixy1:by1 (cordRaRx+0.145):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list(ixy1:by1 (cordnrx2+0.17):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M3 pins R.1 + when((SHAPE~>layerName=="M3")&&(SHAPE~>net~>name=="R.e") + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((ixy1-0.515):by1 (cordRaRx+0.145):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((ixy1-0.515):by1 (cordnrx2+0.17):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M3 pins R.e + when((SHAPE~>layerName=="M3")&&(SHAPE~>net~>name=="R.3") + when(cordRaRx>=(cordnrx2+0.03) + bbox=list(ixy1:by1 (cordRaRx+0.145):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list(ixy1:by1 (cordnrx2+0.17):by2)) + dbSet(SHAPE bbox "bBox")) ;moves M3 pins R.3 + when((SHAPE~>layerName=="M3")&&(SHAPE~>net~>name=="L.0") + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.17):by1 Lpinx:by2)) + when(cordR2LxlayerName=="M3")&&(SHAPE~>net~>name=="L.1") + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.17):by1 (ixy1-0.385):by2)) + when(cordR2LxlayerName=="M3")&&(SHAPE~>net~>name=="L.e") + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.17):by1 bx2:by2)) + when(cordR2LxlayerName=="M3")&&(SHAPE~>net~>name=="L.2") + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.17):by1 Lpinx:by2)) + when(cordR2LxlayerName=="M3")&&(SHAPE~>net~>name=="L.3") + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.17):by1 (cordR2Rx+0.15):by2)) + when(cordR2LxlayerName=="M3")&&(SHAPE~>net~>name=="_RESET") + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx>=cordnx2) + bbox=list((cordnx2-0.17):by1 (cordRaRx+0.145):by2)) + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx=cordnx2) + bbox=list((cordnx2-0.17):by1 (cordnrx2+0.17):by2)) + when((cordRaRx<(cordnrx2+0.03))&&(cordR2LxlayerName=="NP")&&(bx1==1.64&&by1==1.785) + bbox=list((ixy1-0.17):by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")); moves NP associated with the PPLUG + when((SHAPE~>layerName=="PO")&&(bx1==2.56&&bx2==2.6) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordRaRx+0.145):by1 (cordRaRx+0.185):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnrx2+0.17):by1 (cordnrx2+0.21):by2)) + dbSet(SHAPE bbox "bBox")) ; moves CUT_POLY on the right of the leaf cell + when((SHAPE~>layerName=="PO")&&(by2==6.24&&bx2==0.04) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.21):by1 (cordnx2-0.17):by2)) + when(cordR2LxlayerName=="PO")&&((bx2==2.6&&by2==0.08&&bx1==0)||(bx2==2.6&&by2==0.21&&bx1==0)||(bx2==2.6&&by2==0.34&&bx1==0)||(bx2==2.6&&by2==0.47&&bx1==0)||(bx2==2.6&&by2==0.6&&bx1==0)||(bx2==2.6&&by2==0.73&&bx1==0)||(bx2==2.6&&by2==0.86&&bx1==0)||(bx2==2.6&&by2==0.99&&bx1==0)||(bx2==2.6&&by2==1.12&&bx1==0)||(bx2==2.6&&by2==1.25&&bx1==0)||(bx2==2.6&&by2==1.38&&bx1==0)||(bx2==2.6&&by2==1.51&&bx1==0)||(bx2==2.6&&by2==1.64&&bx1==0)||(bx2==2.6&&by2==1.77&&bx1==0)||(bx2==2.6&&by2==2.16&&bx1==0)||(bx2==2.6&&by2==2.29&&bx1==0)||(bx2==2.6&&by2==2.68&&bx1==0)||(bx2==2.6&&by2==2.81&&bx1==0)||(bx2==2.6&&by2==2.94&&bx1==0)||(bx2==2.6&&by2==3.07&&bx1==0)||(bx2==2.6&&by2==3.2&&bx1==0)||(bx2==2.6&&by2==3.33&&bx1==0)||(bx2==2.6&&by2==3.72&&bx1==0)||(bx2==2.6&&by2==3.85&&bx1==0)||(bx2==2.6&&by2==3.98&&bx1==0)||(bx2==2.6&&by2==4.11&&bx1==0)||(bx2==2.6&&by2==4.24&&bx1==0)||(bx2==2.6&&by2==4.37&&bx1==0)||(bx2==2.6&&by2==4.5&&bx1==0)||(bx2==2.6&&by2==4.63&&bx1==0)||(bx2==2.6&&by2==4.76&&bx1==0)||(bx2==2.6&&by2==4.89&&bx1==0)||(bx2==2.6&&by2==5.02&&bx1==0)||(bx2==2.6&&by2==5.15&&bx1==0)||(bx2==2.6&&by2==5.28&&bx1==0)||(bx2==2.6&&by2==5.41&&bx1==0)||(bx2==2.6&&by2==5.54&&bx1==0)||(bx2==2.6&&by2==5.67&&bx1==0)||(bx2==2.6&&by2==5.8&&bx1==0)||(bx2==2.6&&by2==5.93&&bx1==0)||(bx2==2.6&&by2==6.06&&bx1==0)||(bx2==2.6&&by2==6.19&&bx1==0)) + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx>=cordnx2) + bbox=list((cordnx2-0.21):by1 (cordRaRx+0.185):by2)) + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx=cordnx2) + bbox=list((cordnx2-0.21):by1 (cordnrx2+0.21):by2)) + when((cordRaRx<(cordnrx2+0.03))&&(cordR2LxlayerName=="M3")&&((bx1==0&&by2==0.095&&bx2==2.6)||(bx1==0&&by2==1.535&&bx2==2.6)||(bx1==0&&by2==1.655&&bx2==2.6)||(bx1==0&&by2==3.095&&bx2==2.6)||(bx1==0&&by2==3.215&&bx2==2.6)||(bx1==0&&by2==4.655&&bx2==2.6)||(bx1==0&&by2==4.775&&bx2==2.6)||(bx1==0&&by2==6.215&&bx2==2.6)) + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx>=cordnx2) + bbox=list((cordnx2-0.21):by1 (cordRaRx+0.185):by2)) + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx=cordnx2) + bbox=list((cordnx2-0.21):by1 (cordnrx2+0.21):by2)) + when((cordRaRx<(cordnrx2+0.03))&&(cordR2LxlayerName=="prBoundary") + dbDeleteObject(SHAPE) + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx>=cordnx2) + pnts=list((cordnx2-0.21):by1 (cordnx2-0.21):by2 (cordRaRx+0.185):by2 (cordRaRx+0.185):by1)) + when((cordRaRx>=(cordnrx2+0.03))&&(cordR2Lx=cordnx2) + pnts=list((cordnx2-0.21):by1 (cordnx2-0.21):by2 (cordnrx2+0.21):by2 (cordnrx2+0.21):by1)) + when((cordRaRx<(cordnrx2+0.03))&&(cordR2LxlayerName=="PO")&&((by2==3.59&&bx2==2.6&&bx1==0.295)||(by2==3.46&&bx2==2.6&&bx1==0.295)) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((cordnx2+0.06):by1 (cordRaRx+0.185):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((cordnx2+0.06):by1 (cordnrx2+0.21):by2)) + dbSet(SHAPE bbox "bBox")) ;moves poly grids w.r.t 1st NPLUG on left side + when((SHAPE~>layerName=="PO")&&((by2==2.55&&bx2==2.095&&bx1==0)||(by2==2.42&&bx1==0&&bx2==2.095)) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.21):by1 (cordRaRx-0.115):by2)) + when(cordR2LxlayerName=="PO")&&((by2==2.03&&bx1==0&&bx2==1.535)||(by2==1.9&&bx1==0&&bx2==1.535)) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.21):by1 (ixy1-0.31):by2)) + when(cordR2LxlayerName=="PO")&&((by2==1.9&&bx1==1.89&&bx2==2.6)||(by2==2.03&&bx1==1.89&&bx2==2.6)) + when(cordRaRx>=(cordnrx2+0.03) + bbox=list((ixy1+0.08):by1 (cordRaRx+0.185):by2)) + when(cordRaRx<(cordnrx2+0.03) + bbox=list((ixy1+0.08):by1 (cordnrx2+0.21):by2)) + dbSet(SHAPE bbox "bBox")) ;moves poly grids w.r.t 2nd PPLUG on right side + when((SHAPE~>layerName=="M1")&&(by2==3.56&&bx2==0.365&&bx1==0.115) + when(cordR2Lx>=cordnx2 + bbox=list((cordnx2-0.08):by1 bx2:by2)) + when(cordR2LxlayerName=="M1")&&(bx1==1.425&&bx2==2.385) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((ixy1-0.385):y1 (cordRaRx+0.075):y2)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list((ixy1-0.385):y1 (cordnrx2+0.1):y2)) + dbSet(SHAPE pnts "points")) ;moves M1 connecting the L.1 M3 pin + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="L.3") + pnts=list((cordR2Rx+0.15):by1 (cordR2Rx+0.15):by2) + dbSet(SHAPE pnts "points")) ;moves M2 connecting the L.3 pin with the input of the C.2 gate + when((SHAPE~>layerName=="NP")&&(bx1==0&&by2==6.24&&bx2==0.635) + when(cordR2Lx>=cordnx2 + pnts=list(x1:y1 (cordnx2-0.21):y2 (cordnx2-0.21):y3 (cordnx2+0.025):y4 (cordnx2+0.025):y5 (cordnx2-0.21):y6 (cordnx2-0.21):y7 x8:y8)) + when(cordR2LxlayerName=="PP")&&(bx1==0.635&&by2==2.99&&bx2==1.81) + pnts=list(ixy1:y1 (ixy1-0.275):y2 (ixy1-0.275):y3 ixy1:y4 ixy1:y5 x6:y6 x7:y7 ixy1:y8) + dbSet(SHAPE pnts "points")) ;moves PP in the lower portion + when((SHAPE~>layerName=="NW")&&(bx1==0.635&&by2==2.99&&bx2==1.81) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ;moves NW in the lower portion + when((SHAPE~>layerName=="PM")&&(bx1==0.635&&by2==2.99&&bx2==1.81) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ;moves PM in the lower portion + when((SHAPE~>layerName=="PP")&&(bx1==0.635&&by2==6.07&&bx2==1.81) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ;moves PP in the Upper portion + when((SHAPE~>layerName=="NW")&&(bx1==0.635&&by2==6.11&&bx2==1.81) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ;moves NW in the Upper portion + when((SHAPE~>layerName=="PM")&&(bx1==0.635&&by2==6.11&&bx2==1.81) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ;moves PM in the Upper portion + when(((SHAPE~>layerName=="PP")||(SHAPE~>layerName=="PM")||(SHAPE~>layerName=="NW"))&&(bx1==0.635&&by2==4.55&&bx2==1.655) + bbox=list(bx1:by1 (centreXY+0.01):by2) + dbSet(SHAPE bbox "bBox")) ;moves PP/NW/PM in the middle portion + when((SHAPE~>layerName=="NP")&&(bx1==1.81&&by2==2.99&&bx2==2.6) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((cordRaRx+0.185):y1 (cordRaRx-0.08):y2 (cordRaRx-0.08):y3 (cordRaRx+0.185):y4 (cordRaRx+0.185):y5 ixy1:y6 ixy1:y7 (cordRaRx+0.185):y8)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list((cordnrx2+0.21):y1 (cordnrx2-0.055):y2 (cordnrx2-0.055):y3 (cordnrx2+0.21):y4 (cordnrx2+0.21):y5 ixy1:y6 ixy1:y7 (cordnrx2+0.21):y8)) + dbSet(SHAPE pnts "points")) ;moves NP on the right side in the lower portion + when((SHAPE~>layerName=="NP")&&(bx1==1.655&&by2==6.24&&bx2==2.6) + when(cordRaRx>=(cordnrx2+0.03) + pnts=list((cordRaRx+0.185):y1 ixy1:y2 ixy1:y3 (centreXY+0.01):y4 (centreXY+0.01):y5 (cordRaRx+0.185):y6)) + when(cordRaRx<(cordnrx2+0.03) + pnts=list((cordnrx2+0.21):y1 ixy1:y2 ixy1:y3 (centreXY+0.01):y4 (centreXY+0.01):y5 (cordnrx2+0.21):y6)) + dbSet(SHAPE pnts "points")) ;moves NP on the right side in the Upper portion + when((SHAPE~>layerName=="NP")&&((bx1==0.635&&by2==0.17&&bx2==1.81)||(bx1==0.635&&by2==6.24&&bx2==1.81)) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")); moves NP in the lower and upper portions of NW + when((SHAPE~>layerName=="M3")&&((xy1==2.165&&xy2==1.885)||(xy1==2.24&&xy2==5.005)||(xy1==1.8&&xy2==4.485)||(xy1==2.045&&xy2==2.925)||(xy1==1.84&&xy2==0.325)) + orgn=(ixy1+0.1:xy2) + dbSet(SHAPE orgn "xy")) ;moves labels of R pins on M3 + + )) + + foreach(VIA CellView->vias + (let (vx1 vy1 bx1 by1 bx2 by2 vx1 vy1 orgn) + bx1=caar(VIA~>bBox) + by1=cadar(VIA~>bBox) + bx2=caadr(VIA~>bBox) + by2=cadadr(VIA~>bBox) + vx1=car(VIA~>origin) + vy1=cadr(VIA~>origin) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")|| (VIA~>viaHeader~>viaDefName=="M3_M2"))&& ((VIA~>net~>name=="L.2")||(VIA~>net~>name=="L.0")) + when(cordR2Lx>=cordnx2 + orgn=(cordnx2-0.1:vy1)) + when(cordR2LxviaHeader~>viaDefName=="M2_M1")|| (VIA~>viaHeader~>viaDefName=="M3_M2"))&& (VIA~>net~>name=="R.3") + when(cordRaRx>=(cordnrx2+0.03) + orgn=(cordRaRx+0.075:vy1)) + when(cordRaRx<(cordnrx2+0.03) + orgn=(cordnrx2+0.1:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")|| (VIA~>viaHeader~>viaDefName=="M3_M2"))&&(VIA~>net~>name=="L.1")&&(vx1==2.325) + when(cordRaRx>=(cordnrx2+0.03) + orgn=(cordRaRx+0.075:vy1)) + when(cordRaRx<(cordnrx2+0.03) + orgn=(cordnrx2+0.1:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")|| (VIA~>viaHeader~>viaDefName=="M3_M2"))&& (VIA~>net~>name=="R.1") + orgn=(ixy1:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.2")||(VIA~>net~>name=="_r.0")) + when(cordR2Lx>=cordnx2 + orgn=(cordnx2+0.04:vy1)) + when(cordR2LxviaHeader~>viaDefName=="M2_M1")&& ((bx1==1.78)&&(bx2==1.84)) + orgn=(ixy1:vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& (vx1==1.155)&&(VIA~>net~>name=="L.3") + orgn=((cordR2Rx+0.15):vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(VIA~>net~>name=="_RESET") + when(cordR2Lx>=cordnx2 + orgn=((cordnx2-0.1):vy1)) + when(cordR2LxviaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==1.425) + orgn=((ixy1-0.385):vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& (vx1==1.28)&&(VIA~>net~>name=="R.e") + orgn=((ixy1-0.515):vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.3")||(VIA~>net~>name=="_r.1")) + orgn=(cordRaRx-0.06:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& (VIA~>net~>name=="rv") + orgn=(ixy1:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M3_M2_R_H")&& (vx1==2.005) + orgn=(ixy1+0.195:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M3_M2_R_H")&& (vx1==1.615) + orgn=(ixy1-0.195:vy1) + dbSet(VIA orgn "origin")) + )) + + +)) + +(defun MakeBuffer1 (CellView ViewName) + (let (text parameter1 parameter2 parameter3 parameter4 cordM2_M1 INST SHAPE VIA cordnx1 cordnx2 cordpx1 cordpx2 Lpinx cordR0y1 cordR0y2 cordR2y2 NWidth PWidth LePWidth ResPWidth rvNWidth rvPWidth n_contt p_contt cordR1y2 cordrvx1 cordrvx2 cordrvx3 cordrvx4 cordrvy2 cordResx2 cordresx1 cordLex1 cordLex2 cordLex3 cordLex4 cordLey2 cordR1x3 cordR2x2 cordR2x1 cordR1x2 cordR1x1 ActualLeftPoly) + fl = infile("Parameter.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + parameter1 = nth(0 text) + parameter2 = nth(1 text) + parameter3 = nth(2 text) + parameter4 = nth(3 text) + ;setting instance parameters as per the spec file + foreach(INST CellView->instances + (let (N P Nparam Pparam paraN1 paraN2 paraP1 paraP2 paraP3 paraP4 paraP5 paraP6 paraP7 paraP8 paraP9 paraP10) + when( (INST->name==parameter1) && (INST->cellName=="gate.INV.0-L1_1-R") + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0") + NWidth=N) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1") + PWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e") + LePWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset") + ResPWidth=P) + dbReplaceProp(INST "NW1" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( (INST->name==parameter1) && (INST->cellName=="gate.NAND5.0-L1_1-R") + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + rvPWidth=P + rvNWidth=N + dbReplaceProp(INST "NW5" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( ( (INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")) + paraN1 = strcat( parameter1 "." "N1") + paraN2 = strcat( parameter1 "." "N2") + paraP1 = strcat( parameter1 "." "P1") + paraP2 = strcat( parameter1 "." "P2") + paraP3 = strcat( parameter1 "." "P3") + paraP4 = strcat( parameter1 "." "P4") + paraP5 = strcat( parameter1 "." "P5") + paraP6 = strcat( parameter1 "." "P6") + paraP7 = strcat( parameter1 "." "P7") + paraP8 = strcat( parameter1 "." "P8") + paraP9 = strcat( parameter1 "." "P9") + paraP10 = strcat( parameter1 "." "P10") + when(((INST->name==paraN1) || (INST->name==paraP1) || (INST->name==paraN2) || (INST->name==paraP2) || (INST->name==paraP3) || (INST->name==paraP4) || (INST->name==paraP5) || (INST->name==paraP6) || (INST->name==paraP7) || (INST->name==paraP8) || (INST->name==paraP9) || (INST->name==paraP10)) + N=evalstring(parameter3) + Nparam=N/2000000 + P=evalstring(parameter4) + Pparam=P/2000000 + dbReplaceProp(INST "NW2" "float" Nparam) + dbReplaceProp(INST "NW5" "float" Nparam) + dbReplaceProp(INST "PW2" "float" Pparam) + dbReplaceProp(INST "PW1" "float" Pparam) + )) + ))) +; Calculates the XY origina and bBox to move instances w.r.t the new spec + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordPx cordPx1 cordPx2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.N1")) + cordNx=caar(INST~>bBox) + cordNx1=cordNx+0.02 + cordnx1=cordNx1 + cordNx2=cordNx1-0.06 + cordnx2=cordNx2) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.P1")) + cordPx=caadr(INST~>bBox) + Lpinx=caar(INST~>bBox) + cordPx1=cordPx-0.02 + cordpx1=cordPx1 + cordPx2=cordPx1+0.06 + cordpx2=cordPx2) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0")) + cordR0y1=cadar(INST~>bBox) + cordR0y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.2")) + cordR2x1=caar(INST~>bBox) + cordR2x2=caadr(INST~>bBox) + cordR2y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1")) + cordR1x1=caar(INST~>bBox) + cordR1x2=caadr(INST~>bBox) + cordR1y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset")) + when(ResPWidth>=0.15 + p_contt=0.05 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordResx2=caadr(INST~>bBox)) + when(ResPWidth<0.15 + p_contt=0.14 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordResx2=caadr(INST~>bBox))) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="_Reset")) + cordresx1=caar(INST~>bBox)) + when(((INST->cellName=="gate.NAND5.0-L1_1-R") && (INST->name=="rv")) + cordrvx1=caar(INST~>bBox) + cordrvx2=caadr(INST~>bBox) + cordrvy2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e")) + cordLex1=caar(INST~>bBox) + cordLex2=caadr(INST~>bBox) + cordLey2=cadadr(INST~>bBox)) + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.0")||(INST->name=="R.2")) + when((cordR0y1==0.69)&&(cordR1x1>(cordnx1-0.27)) + n_contt=(0.975-0.09-(NWidth/2)-(cordnx1-0.43)-0.04) + dbReplaceProp(INST "n_contact_offset" "float" n_contt)) + when((cordR0y1==0.69)&&(cordR1x1<=(cordnx1-0.27)) + n_contt=(0.975-0.09-(NWidth/2)-(cordR1x1-0.16)-0.04) + dbReplaceProp(INST "n_contact_offset" "float" n_contt)) + when((cordR0y1!=0.69)&&(cordR1x1>(cordnx1-0.27)) + n_contt=(0.975-0.09-NWidth-(cordnx1-0.43)-0.04) + dbReplaceProp(INST "n_contact_offset" "float" n_contt)) + when((cordR0y1!=0.69)&&(cordR1x1<=(cordnx1-0.27)) + n_contt=(0.975-0.09-NWidth-(cordR1x1-0.16)-0.04) + dbReplaceProp(INST "n_contact_offset" "float" n_contt))) ;moves Poly_M1 contacts i.e n_contact_offset on the left side of the R.0/R.2 INV gates + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e") + when((cordLey2==4.25)&&((LePWidth/3)>=0.21) + ; p_contt=(cordLex2-0.09-(PWidth/3)-0.975-0.195) + p_contt=0.05 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordLex3=caadr(INST~>bBox) + cordLex4=caar(INST~>bBox)) + when((cordLey2==4.12)&&((LePWidth/2)>=0.21) + p_contt=0.05 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordLex3=caadr(INST~>bBox) + cordLex4=caar(INST~>bBox)) + when((cordLey2==3.99)&&(LePWidth>=0.21) + p_contt=0.05 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordLex3=caadr(INST~>bBox) + cordLex4=caar(INST~>bBox)) + when((cordLey2==4.25)&&((LePWidth/3)<0.21) + p_contt=0.15 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordLex3=caadr(INST~>bBox) + cordLex4=caar(INST~>bBox)) + when((cordLey2==4.12)&&((LePWidth/2)<0.21) + p_contt=0.15 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordLex3=caadr(INST~>bBox) + cordLex4=caar(INST~>bBox)) + when((cordLey2==3.99)&&(LePWidth<0.21) + p_contt=0.15 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordLex3=caadr(INST~>bBox) + cordLex4=caar(INST~>bBox))) ;moves Poly_M1 contacts i.e p_contact_offset on the right side of the L.e INV gate + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.1")||(INST->name=="R.3")) + when((cordR1y2==1.39)&&(cordR2x2<(cordpx1+0.27)) + p_contt=((cordpx1+0.56)-0.975-0.09-0.04-(PWidth/2)) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordR1x3=caadr(INST~>bBox)) + when((cordR1y2==1.39)&&(cordR2x2>=(cordpx1+0.27)) + p_contt=((cordR2x2+0.26)-0.975-0.09-0.04-(PWidth/2)) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordR1x3=caadr(INST~>bBox)) + when((cordR1y2!=1.39)&&(cordR2x2<(cordpx1+0.27)) + p_contt=((cordpx1+0.56)-0.975-0.09-0.04-PWidth) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordR1x3=caadr(INST~>bBox)) + when((cordR1y2!=1.39)&&(cordR2x2>=(cordpx1+0.27)) + p_contt=((cordR2x2+0.26)-0.975-0.09-0.04-PWidth) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordR1x3=caadr(INST~>bBox)));moves Poly_M1 contacts i.e p_contact_offset on the right side of the R.1/R.3 INV gates + when((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R") && (((xy2==5.72)&&(xy1==1.46))||((xy2==4.55)&&(xy1==1.46))||((xy2==1.69)&&(xy1==1.46))||((xy2==0.52)&&(xy1==1.46))) + XY=((cordpx1+0.01):xy2) + dbSet(INST XY "xy")) ; moves PMOs chains on the right side of the C2 gate w.r.t the new spec file + when((INST->cellName=="stack.NMOS_CHAIN_1.0-L1-R") && (((xy2==5.59)&&(xy1==0.62))||((xy2==4.42)&&(xy1==0.62))||((xy2==1.56)&&(xy1==0.62))||((xy2==0.39)&&(xy1==0.62))) + XY=((cordnx1-0.01):xy2) + dbSet(INST XY "xy")) ; moves NMOS chains on the left side of the C2 gate w.r.t the new spec file + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.915)&&(xy1==1.74))||((xy2==5.655)&&(xy1==1.74))||((xy2==4.745)&&(xy1==1.74))||((xy2==4.485)&&(xy1==1.74))||((xy2==1.885)&&(xy1==1.74))||((xy2==1.625)&&(xy1==1.74))||((xy2==0.715)&&(xy1==1.74))||((xy2==0.455)&&(xy1==1.74))) + when((cordR2x2<(cordpx1+0.27)) + XY=(cordpx1+0.29:xy2)) + when((cordR2x2>=(cordpx1+0.27)) + XY=(cordR2x2+0.02:xy2)) + dbSet(INST XY "xy")) ;moves M1_poly vias on the right side of C2 gates + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.785)&&(xy1==0.34))||((xy2==5.525)&&(xy1==0.34))||((xy2==4.615)&&(xy1==0.34))||((xy2==4.355)&&(xy1==0.34))||((xy2==1.755)&&(xy1==0.34))||((xy2==1.495)&&(xy1==0.34))||((xy2==0.585)&&(xy1==0.34))||((xy2==0.325)&&(xy1==0.34))) + when((cordR1x1>(cordnx1-0.27)) + XY=(cordnx1-0.29:xy2)) + when((cordR1x1<=(cordnx1-0.27)) + XY=(cordR1x1-0.02:xy2)) + dbSet(INST XY "xy")) ;moves M1_poly vias on the left side of C2 gates + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.785)&&(xy1==1.88))||((xy2==4.615)&&(xy1==1.88))||((xy2==1.755)&&(xy1==1.88))||((xy2==0.585)&&(xy1==1.88))) + when((cordR2x2<(cordpx1+0.27)) + XY=(cordpx1+0.43:xy2)) + when((cordR2x2>=(cordpx1+0.27)) + XY=(cordR2x2+0.16:xy2)) + dbSet(INST XY "xy")) ;moves M1_poly vias on the right side of the PMOS chain of C2 gates + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.655)&&(xy1==0.2))||((xy2==4.485)&&(xy1==0.2))||((xy2==1.625)&&(xy1==0.2))||((xy2==0.455)&&(xy1==0.2))) + when((cordR1x1>(cordnx1-0.27)) + XY=(cordnx1-0.43:xy2)) + when((cordR1x1<=(cordnx1-0.27)) + XY=(cordR1x1-0.16:xy2)) + ActualLeftPoly=car(XY) + dbSet(INST XY "xy")) ;moves M1_poly vias on the left sideof the NMOS chain of C2 gates + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="R.2") + when(cordR2y2==5.29 + pnts=(1.17:5.2) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil pnts "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) )) + when(cordR2y2==5.29 + pnts=(0.78:5.2) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil pnts "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ))) + + when((INST->cellName=="gate.INV.0-L1_1-R")&&(INST->name=="R.1") + when(cordR1y2==1.39 + pnts=(0.78:1.3) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil pnts "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) )) + when(cordR1y2==1.39 + pnts=(1.17:1.3) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil pnts "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ))) + + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="gate.NAND5.0-L1_1-R") && (INST->name=="rv") + when((cordrvy2==3.86)&&((rvPWidth/2)<=cordLex3)&&((rvPWidth/2)>=0.21) + p_contt=(cordLex3-0.975-0.09-(rvPWidth/2)-0.1) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox)) + when((cordrvy2==3.21)&&(rvPWidth<=cordLex3)&&(rvPWidth>=0.21) + p_contt=(cordLex3-0.975-0.09-rvPWidth-0.1) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox)) + when((cordrvy2==3.86)&&((rvPWidth/2)>cordLex3)&&((rvPWidth/2)>=0.21) + p_contt=0.06 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox)) + when((cordrvy2==3.21)&&(rvPWidth>cordLex3)&&(rvPWidth>=0.21) + p_contt=0.06 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox)) + when((cordrvy2==3.86)&&((rvPWidth/2)<0.21)&&((rvPWidth/2)<=cordLex3) + p_contt=(cordLex3-0.975-0.09-(rvPWidth/2)-0.1) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox)) + when((cordrvy2==3.86)&&((rvPWidth/2)<0.21)&&((rvPWidth/2)>cordLex3) + p_contt=0.15 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox)) + when((cordrvy2==3.21)&&(rvPWidth<0.21)&&(rvPWidth<=cordLex3) + p_contt=(cordLex3-0.975-0.09-rvPWidth-0.1) + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox)) + when((cordrvy2==3.21)&&(rvPWidth<0.21)&&(rvPWidth>cordLex3) + p_contt=0.15 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordrvx3=caadr(INST~>bBox) + cordrvx4=caar(INST~>bBox))) ; moves Poly_M1 contacts i.e p_contact_offset on the right side of the L.e NAND5 gate + + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.PPLUG.0")&&(xy1==1.925&&xy2==2.355) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3)) + XY=((cordrvx3-0.115):xy2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3)) + XY=((cordLex3-0.115):xy2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3)) + XY=((cordR1x3-0.115):xy2)) + dbSet(INST XY "xy")) ; moves PPLUG + when((INST->cellName=="stack.NPLUG.0")&&(xy1==0.155&&xy2==2.38) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + XY=((cordrvx4+0.115):xy2)) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + XY=((cordR1x1-0.115):xy2)) + when(((cordLex4(cordnx1-0.27)) + XY=((cordLex4+0.115):xy2)) + when(((cordLex4(cordnx1-0.27)) + XY=((cordnx1-0.385):xy2)) + when((((cordnx1-0.5)shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="PO")&&(((bx1==0.91)&&(by1==5.9))||((bx1==0.935)&&(by1==5.64))||((bx1==0.93)&&(by1==4.73))||((bx1==0.93)&&(by1==4.47))||((bx1==0.91)&&(by1==1.87))||((bx1==0.92)&&(by1==1.61))||((bx1==0.895)&&(by1==0.7))||((bx1==0.875)&&(by1==0.44))) + when((cordR2x2<(cordpx1+0.27)) + bbox=list(bx1:by1 (cordpx1+0.29):by2)) + when((cordR2x2>=(cordpx1+0.27)) + bbox=list(bx1:by1 (cordR2x2+0.02):by2)) + dbSet(SHAPE bbox "bBox")); moves poly on the right side of c2 gates i.e connecting R.e net + when((SHAPE~>layerName=="PO")&&(((bx1==0.975)&&(by1==5.77))||((bx1==0.975)&&(by1==4.6))||((bx1==0.975)&&(by1==1.74))||((bx1==0.975)&&(by1==0.57))) + when((cordR2x2<(cordpx1+0.27)) + bbox=list(bx1:by1 (cordpx1+0.43):by2)) + when((cordR2x2>=(cordpx1+0.27)) + bbox=list(bx1:by1 (cordR2x2+0.16):by2)) + dbSet(SHAPE bbox "bBox")); moves poly on the right side of PMOS gate of c2 gates + when((SHAPE~>layerName=="PO")&&(((bx1==0.325)&&(by1==5.77))||((bx1==0.325)&&(by1==5.51))||((bx1==0.325)&&(by1==4.6))||((bx1==0.325)&&(by1==4.34))||((bx1==0.325)&&(by1==1.74))||((bx1==0.325)&&(by1==1.48))||((bx1==0.325)&&(by1==0.57))||((bx1==0.325)&&(by1==0.31))) + when((cordR1x1>(cordnx1-0.27)) + bbox=list((cordnx1-0.29):by1 bx2:by2)) + when((cordR1x1<=(cordnx1-0.27)) + bbox=list((cordR1x1-0.02):by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")); moves poly on the left side of c2 gates i.e connecting L.3/L.2/L.1/L.0 net + when((SHAPE~>layerName=="PO")&&(((bx1==0.225)&&(by1==5.64))||((bx1==0.215)&&(by1==4.47))||((bx1==0.22)&&(by1==1.61))||((bx1==0.22)&&(by1==0.44))) + when((cordR1x1>(cordnx1-0.27)) + bbox=list((cordnx1-0.43):by1 bx2:by2)) + when((cordR1x1<=(cordnx1-0.27)) + bbox=list((cordR1x1-0.16):by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")); moves poly on the left side of NMOS gate of c2 gates + when((SHAPE~>layerName=="PO")&&(((by1==5.71)&&(by2==5.86))||((by1==4.54)&&(by2==4.69))||((by1==1.68)&&(by2==1.83))||((by1==0.51)&&(by2==0.66))) + bbox=list((cordpx1-0.025):by1 (cordpx1+0.055):by2) + dbSet(SHAPE bbox "bBox")); moves Cut_Poly on the right side of c2 gates + when((SHAPE~>layerName=="PO")&&(((by1==5.58)&&(by2==5.73))||((by1==4.41)&&(by2==4.56))||((by1==1.55)&&(by2==1.7))||((by1==0.38)&&(by2==0.53))) + bbox=list((cordnx1+0.025):by1 (cordnx1-0.055):by2) + dbSet(SHAPE bbox "bBox")); moves Cut_Poly on the left side of c2 gates + when((SHAPE~>layerName=="M1")&&(((bx1==1.065)&&(by1==5.82))||((bx1==1.065)&&(by1==5.56))||((bx1==1.065)&&(by1==4.65))||((bx1==1.065)&&(by1==4.39))||((bx1==1.065)&&(by1==1.79))||((bx1==1.065)&&(by1==1.53))||((bx1==1.065)&&(by1==0.62))||((bx1==1.065)&&(by1==0.36))) + bbox=list(bx1:by1 (cordpx1+0.15):by2) + dbSet(SHAPE bbox "bBox")); moves horizontal M1 connecting the PMOS chains on the right side of C2 gates + when((SHAPE~>layerName=="M1")&&(((bx1==1.54)&&(by1==5.56))||((bx1==1.54)&&(by1==4.39))||((bx1==1.54)&&(by1==1.53))||((bx1==1.54)&&(by1==0.36))) + bbox=list((cordpx1+0.09):by1 (cordpx1+0.15):by2) + dbSet(SHAPE bbox "bBox")); moves vertical M1 connecting the PMOS chains on the right side of C2 gates + when((SHAPE~>layerName=="M1")&&(((bx1==0.48)&&(by1==5.82))||((bx1==0.48)&&(by1==5.56))||((bx1==0.48)&&(by1==4.65))||((bx1==0.48)&&(by1==4.39))||((bx1==0.48)&&(by1==1.79))||((bx1==0.48)&&(by1==1.53))||((bx1==0.48)&&(by1==0.62))||((bx1==0.48)&&(by1==0.36))) + bbox=list((cordnx1-0.15):by1 bx2:by2) + dbSet(SHAPE bbox "bBox")); moves horizontal M1 connecting the NMOS chains on the left side of C2 gates + when((SHAPE~>layerName=="M1")&&(((bx1==0.48)&&(by1==5.69))||((bx1==0.48)&&(by1==4.52))||((bx1==0.48)&&(by1==1.66))||((bx1==0.48)&&(by1==0.49))) + bbox=list((cordnx1-0.15):by1 (cordnx1-0.09):by2) + dbSet(SHAPE bbox "bBox")); moves vertical M1 connecting the NMOS chains on the left side of C2 gates + when((SHAPE~>layerName=="M1")&&(((by1==5.625)&&(by2==5.945))||((by1==4.455)&&(by2==4.775))||((by1==1.595)&&(by2==1.915))||((by1==0.425)&&(by2==0.745))) + when((cordR2x2<(cordpx1+0.27)) + bbox=list((cordpx1+0.25):by1 (cordpx1+0.33):by2)) + when((cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR2x2-0.02):by1 (cordR2x2+0.06):by2)) + dbSet(SHAPE bbox "bBox")); moves vertical M1 connecting the R.e input on the right side of C2 gates i.e connecting the 2 poly_M1 vias + when((SHAPE~>layerName=="M1")&&(((by1==5.495)&&(by2==5.815))||((by1==4.325)&&(by2==4.645))||((by1==1.465)&&(by2==1.785))||((by1==0.295)&&(by2==0.615))) + when((cordR1x1>(cordnx1-0.27)) + bbox=list((cordnx1-0.25):by1 (cordnx1-0.33):by2)) + when((cordR1x1<=(cordnx1-0.27)) + bbox=list((cordR1x1-0.06):by1 (cordR1x1+0.02):by2)) + dbSet(SHAPE bbox "bBox")); moves vertical M1 connecting the L.0/L.1/L.2/L.3 input on the left side of C2 gates i.e connecting the 2 poly_M1 vias + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="R.3") + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 (cordpx1+0.24):y3 (cordpx1+0.24):y4 (cordpx1+0.43):y5 (cordpx1+0.43):y6)) + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 (cordpx1+0.24):y3 (cordpx1+0.24):y4 (cordpx1+0.43):y5 (cordpx1+0.43):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 (cordR2x2+0.015):y3 (cordR2x2+0.015):y4 (cordR2x2+0.16):y5 (cordR2x2+0.16):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 (cordR2x2+0.015):y3 (cordR2x2+0.015):y4 (cordR2x2+0.16):y5 (cordR2x2+0.16):y6)) + dbSet(SHAPE pnts "points")); moves vertical M1 connecting the R.3 input on M1 going through the R.3 INV + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="R.2") + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordpx1+0.43):y1 (cordpx1+0.43):y2 (cordnx1-0.24):y3 (cordnx1-0.24):y4 (cordnx1-0.43):y5 (cordnx1-0.43):y6)) + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordpx1+0.43):y1 (cordpx1+0.43):y2 (cordR1x1-0.015):y3 (cordR1x1-0.015):y4 (cordR1x1-0.16):y5 (cordR1x1-0.16):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordR2x2+0.16):y1 (cordR2x2+0.16):y2 (cordnx1-0.24):y3 (cordnx1-0.24):y4 (cordnx1-0.43):y5 (cordnx1-0.43):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR2x2+0.16):y1 (cordR2x2+0.16):y2 (cordR1x1-0.015):y3 (cordR1x1-0.015):y4 (cordR1x1-0.16):y5 (cordR1x1-0.16):y6)) + dbSet(SHAPE pnts "points")); moves vertical M1 connecting the R.2 input on M1 going through the R.2 INV + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="R.1") + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 (cordpx1+0.24):y3 (cordpx1+0.24):y4 (cordpx1+0.43):y5 (cordpx1+0.43):y6)) + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 (cordpx1+0.24):y3 (cordpx1+0.24):y4 (cordpx1+0.43):y5 (cordpx1+0.43):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 (cordR2x2+0.015):y3 (cordR2x2+0.015):y4 (cordR2x2+0.16):y5 (cordR2x2+0.16):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 (cordR2x2+0.015):y3 (cordR2x2+0.015):y4 (cordR2x2+0.16):y5 (cordR2x2+0.16):y6)) + dbSet(SHAPE pnts "points")); moves vertical M1 connecting the R.1 input on M1 going through the R.1 INV + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="R.0") + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 (cordnx1-0.24):y3 (cordnx1-0.24):y4 (cordpx1+0.43):y5 (cordpx1+0.43):y6)) + when((cordR2x2<(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 (cordR1x1-0.015):y3 (cordR1x1-0.015):y4 (cordpx1+0.43):y5 (cordpx1+0.43):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 (cordnx1-0.24):y3 (cordnx1-0.24):y4 (cordR2x2+0.16):y5 (cordR2x2+0.16):y6)) + when((cordR2x2>=(cordpx1+0.27))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 (cordR1x1-0.015):y3 (cordR1x1-0.015):y4 (cordR2x2+0.16):y5 (cordR2x2+0.16):y6)) + dbSet(SHAPE pnts "points")); moves vertical M1 connecting the R.0 input on M1 going through the R.0 INV + when((SHAPE~>layerName=="M1")&&((SHAPE~>net~>name=="_r.3")||(SHAPE~>net~>name=="_r.1"))&&(((bx1==1.39)&&(by1==5.365))||((bx1==1.395)&&(by1==0.11))) + when((cordR2x2<(cordpx1+0.27)) + pnts=list((Lpinx+0.35):y1 (cordpx1+0.56):y2 (cordpx1+0.56):y3 )) + when((cordR2x2>=(cordpx1+0.27)) + pnts=list((Lpinx+0.35):y1 (cordR2x2+0.285):y2 (cordR2x2+0.285):y3 )) + dbSet(SHAPE pnts "points")); moves M1 connecting the _r.3/_r.1 with poly_M1 vias of the R.3 INV + when((SHAPE~>layerName=="M1")&&(bx1==0.125)&&(by1==2.185) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + pnts=list(x1:y1 (cordrvx4+0.115):y2 (cordrvx4+0.115):y3 )) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list(x1:y1 (cordR1x1-0.115):y2 (cordR1x1-0.115):y3 )) + when(((cordLex4(cordnx1-0.27)) + pnts=list(x1:y1 (cordLex4+0.115):y2 (cordLex4+0.115):y3 )) + when(((cordLex4(cordnx1-0.27)) + pnts=list(x1:y1 (cordnx1-0.385):y2 (cordnx1-0.385):y3 )) + when((((cordnx1-0.5)layerName=="M1")&&(bx1==1.485)&&(by1==1.995) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3)) + pnts=list((cordpx1+0.16):y1 (cordrvx3-0.115):y2 (cordrvx3-0.115):y3)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3)) + pnts=list((cordpx1+0.16):y1 (cordLex3-0.115):y2 (cordLex3-0.115):y3)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3)) + pnts=list((cordpx1+0.16):y1 (cordR1x3-0.115):y2 (cordR1x3-0.115):y3)) + dbSet(SHAPE pnts "points")) ;moves M1 connecting the PPLUG to Vdd + when((SHAPE~>layerName=="M1")&&(by2==2.055)&&(by1==1.92) + pnts=list(x1:y1 (cordpx1+0.16):y2 (cordpx1+0.16):y3) + dbSet(SHAPE pnts "points")) ;moves M1 connecting the PPLUG to Vdd + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="_r.3")||(SHAPE~>net~>name=="_r.1"))&&(((bx1==1.36)&&(by1==5.72))||((bx1==1.365)&&(by1==0.13))) + pnts=list((Lpinx+0.38):y1 (Lpinx+0.38):y2 ) + dbSet(SHAPE pnts "points")); moves M2 connecting the _r.3/_r.1 with poly_M1 vias of the R.3 INV + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="_r.3")&&(bx1==1.98)&&(by1==4.28) + when((cordR2x2<(cordpx1+0.27)) + pnts=list((cordpx1+0.56):y1 (cordpx1+0.56):y2 )) + when((cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR2x2+0.285):y1 (cordR2x2+0.285):y2 )) + dbSet(SHAPE pnts "points")); moves M2 connecting the _r.3 with poly_M1 vias of the NAND5 gate + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="_r.1")&&(bx1==1.98)&&(by1==0.13) + when((cordR2x2<(cordpx1+0.27))&&((cordR2x2+0.285)>=(cordrvx3-0.24)) + pnts=list((cordpx1+0.56):y1 (cordpx1+0.56):y2 )) + when((cordR2x2<(cordpx1+0.27))&&((cordR2x2+0.285)<(cordrvx3-0.24)) + pnts=list((cordpx1+0.56):(y1+0.65) (cordpx1+0.56):(y2+0.65))) + when((cordR2x2>=(cordpx1+0.27))&&((cordR2x2+0.285)>=(cordrvx3-0.24)) + pnts=list((cordR2x2+0.285):y1 (cordR2x2+0.285):y2 )) + when((cordR2x2>=(cordpx1+0.27))&&((cordR2x2+0.285)<(cordrvx3-0.24)) + pnts=list((cordR2x2+0.285):(y1+0.65) (cordR2x2+0.285):(y2+0.65))) + dbSet(SHAPE pnts "points")); moves M2 connecting the _r.1 with poly_M1 vias of the NAND5 gate + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="R.2")||(SHAPE~>net~>name=="R.1")||(SHAPE~>net~>name=="R.0"))&&(((bx1==1.85)&&(by1==4.48))||((bx1==1.85)&&(by1==1.34))||((bx1==1.85)&&(by1==0.32))) + when((cordR2x2<(cordpx1+0.27)) + pnts=list((cordpx1+0.43):y1 (cordpx1+0.43):y2 )) + when((cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR2x2+0.155):y1 (cordR2x2+0.155):y2 )) + dbSet(SHAPE pnts "points")); moves M2 connecting the R.2/R.1/R.0 with the respective M3 pins + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="R.e")&&(bx1==1.72)&&(by1==0.425) + when((cordR2x2<(cordpx1+0.27)) + pnts=list((cordpx1+0.3):y1 (cordpx1+0.3):y2 )) + when((cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR2x2+0.025):y1 (cordR2x2+0.025):y2 )) + dbSet(SHAPE pnts "points")); moves M2 connecting the R.e with the respective M3 pins + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="R.3")&&(bx1==1.6)&&(by2==5.38) + when((cordR2x2<(cordpx1+0.27)) + pnts=list((cordpx1+0.17):y1 (cordpx1+0.17):y2 )) + when((cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR2x2-0.105):y1 (cordR2x2-0.105):y2 )) + dbSet(SHAPE pnts "points")); moves M2 connecting the R.3/_r.1 with the respective M3 pins + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="_RESET")&&(bx1==1.415)&&(by1==2.145) + when((cordR2x2<(cordpx1+0.27)) + pnts=list((cordpx1+0.04):y1 (cordpx1+0.04):y2 )) + when((cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR2x2-0.235):y1 (cordR2x2-0.235):y2 )) + dbSet(SHAPE pnts "points")); moves M2 connecting the _RESET with the respective M3 pins + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="L.3")||(SHAPE~>net~>name=="L.2")||(SHAPE~>net~>name=="L.1")||(SHAPE~>net~>name=="L.0"))&&(((bx1==0.3)&&(by1==4.95))||((bx1==0.3)&&(by1==4.325))||((bx1==0.3)&&(by1==1.465))||((bx1==0.3)&&(by1==0.27))) + when((cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.29):y1 (cordnx1-0.29):y2 )) + when((cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.02):y1 (cordR1x1-0.02):y2 )) + dbSet(SHAPE pnts "points")); moves M2 connecting the L.3/L.2/L.1/L.0 with the respective M3 pins + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="_r.2")&&(bx1==0.15)&&(by1==3.545) + when((cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 )) + when((cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 )) + dbSet(SHAPE pnts "points")); moves M2 connecting the _r.2 connecting the Poly_M1 inputs of the INV gate and the NAND5 gate + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="_r.0")&&(bx1==0.43)&&(by1==0.145) + pnts=list((cordnx1-0.16):y1 (cordnx1-0.16):y2 ) + dbSet(SHAPE pnts "points")); moves M2 connecting the _r.0 connecting the Poly_M1 inputs of the INV gate and the NAND5 gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="rv")&&(bx1==1.025)&&(by1==3.61) + when((cordLey2==4.25)&&((LePWidth/3)>=0.21) + pnts=list(x1:y1 (0.975+0.09+(LePWidth/3)+0.085):y2 (0.975+0.09+(LePWidth/3)+0.085):y3 )) + when((cordLey2==4.12)&&((LePWidth/2)>=0.21) + pnts=list(x1:y1 (0.975+0.09+(LePWidth/2)+0.085):y2 (0.975+0.09+(LePWidth/2)+0.085):y3 )) + when((cordLey2==3.99)&&(LePWidth>=0.21) + pnts=list(x1:y1 (0.975+0.09+LePWidth+0.085):y2 (0.975+0.09+LePWidth+0.085):y3 )) + when((cordLey2==4.25)&&((LePWidth/3)<0.21) + pnts=list(x1:y1 (0.975+0.09+(LePWidth/3)+0.185):y2 (0.975+0.09+(LePWidth/3)+0.185):y3 )) + when((cordLey2==4.12)&&((LePWidth/2)<0.21) + pnts=list(x1:y1 (0.975+0.09+(LePWidth/2)+0.185):y2 (0.975+0.09+(LePWidth/2)+0.185):y3 )) + when((cordLey2==3.99)&&(LePWidth<0.21) + pnts=list(x1:y1 (0.975+0.09+LePWidth+0.185):y2 (0.975+0.09+LePWidth+0.185):y3 )) + dbSet(SHAPE pnts "points")); moves M1 connecting the rv connecting the Poly_M1 inputs of the L.e INV gate + when((SHAPE~>layerName=="M1")&&(bx1==0.15)&&(by1==5.01) + when((cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 )) + when((cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.16):y1 (cordR1x1-0.16):y2 )) + dbSet(SHAPE pnts "points")); moves M1 connecting the _r.2 connecting the Poly_M1 inputs of the INV gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.2")&&(bx1==0.155)&&(by1==5.965) + when((cordR1x1>(cordnx1-0.27)) + pnts=list(x1:y1 x2:y2 (cordnx1-0.43):y3 )) + when((cordR1x1<=(cordnx1-0.27)) + pnts=list(x1:y1 x2:y2 (cordR1x1-0.16):y3 )) + dbSet(SHAPE pnts "points")); moves M1 connecting the _r.2 connecting the M2 + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.0")&&(bx1==0.485)&&(by1==0.11) + pnts=list(x1:y1 x2:y2 (cordnx1-0.16):y3 ) + dbSet(SHAPE pnts "points")); moves M1 connecting the _r.0 connecting the M2 + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.0")&&(bx1==0.2)&&(by1==0.945) + when((cordR1x1>(cordnx1-0.27)) + pnts=list((cordnx1-0.43):y1 (cordnx1-0.43):y2 (cordnx1-0.16):y3 )) + when((cordR1x1<=(cordnx1-0.27)) + pnts=list((cordR1x1-0.145):y1 (cordR1x1-0.145):y2 (cordnx1-0.16):y3 )) + dbSet(SHAPE pnts "points")); moves M1 connecting the _r.0 connecting the poly_M1 input of the INV gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.0")&&(bx1==0.415)&&(by1==2.635) + bbox=list((cordrvx1+0.16):by1 (cordnx1-0.16):by2 ) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the _r.0 connecting from the M2 to the Poly_M1 vias of the NAND5 gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.2")&&(bx1==0.125)&&(by1==3.545) + when((cordR1x1>(cordnx1-0.27)) + bbox=list((cordrvx1+0.03):by1 (cordnx1-0.43):by2 )) + when((cordR1x1<=(cordnx1-0.27)) + bbox=list((cordrvx1+0.03):by1 (cordR1x1-0.16):by2 )) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the _r.0 connecting from the M2 to the Poly_M1 vias of the NAND5 gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_RESET")&&(bx1==1.48)&&(by1==2.115) + when((cordR2x2<(cordpx1+0.27)) + bbox=list((cordResx2-0.07):by1 (cordpx1+0.04):by2 )) + when((cordR2x2>=(cordpx1+0.27)) + bbox=list((cordResx2-0.07):by1 (cordR2x2-0.235):by2 )) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the _RESET connecting from the M2 to the Poly_M1 vias of the INV gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="Reset")&&(bx1==0.55)&&(by1==2.05) + pnts=list(x1:y1 (cordresx1+0.07):y2 (cordresx1+0.07):y3 ) + dbSet(SHAPE pnts "points")); moves M1 connecting the _RESET connecting from the M2 to the Poly_M1 vias of the INV gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_Reset")&&(bx1==0.975)&&(by1==2.31) + pnts=list(x1:y1 (cordrvx3-0.33):y2 (cordrvx3-0.33):y3 ) + dbSet(SHAPE pnts "points")); moves M1 connecting the _Reset connecting from the M2 to the Poly_M1 vias of the NAND5 gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.1")&&(by1==2.765)&&(bx1==1.48) + when((cordR2x2<(cordpx1+0.27))&&((cordR2x2+0.285)>=(cordrvx3-0.24)) + bbox=list((cordrvx3-0.2):by1 (cordpx1+0.56):by2)) + when((cordR2x2<(cordpx1+0.27))&&((cordR2x2+0.285)<(cordrvx3-0.24)) + bbox=list((cordrvx3-0.2):(by1+0.65) (cordpx1+0.56):(by2+0.65))) + when((cordR2x2>=(cordpx1+0.27))&&((cordR2x2+0.285)>=(cordrvx3-0.24)) + bbox=list((cordrvx3-0.2):by1 (cordR2x2+0.285):by2)) + when((cordR2x2>=(cordpx1+0.27))&&((cordR2x2+0.285)<(cordrvx3-0.24)) + bbox=list((cordrvx3-0.2):(by1+0.65) (cordR2x2+0.285):(by2+0.65))) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the M2_M1 via of _r.1 connecting to the Poly_M1 via of NAND5 gate + when((SHAPE~>layerName=="M3")&&((SHAPE~>net~>name=="L.3")||(SHAPE~>net~>name=="L.2")||(SHAPE~>net~>name=="L.1")||(SHAPE~>net~>name=="L.0")||(SHAPE~>net~>name=="L.e")) + when((ActualLeftPoly<=cordrvx4)&&(ActualLeftPoly<=cordLex4) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + bbox=list(cordrvx4:by1 bx2:by2)) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + bbox=list(cordR1x1-0.23:by1 bx2:by2)) + when(((cordLex4(cordnx1-0.27)) + bbox=list(cordLex4:by1 bx2:by2)) + when(((cordLex4(cordnx1-0.27)) + bbox=list((cordnx1-0.5):by1 bx2:by2)) + when((((cordnx1-0.5)cordrvx4)||(ActualLeftPoly>cordLex4) + when((cordrvx4<=cordLex4) + bbox=list((cordrvx4-0.04):by1 bx2:by2)) + when((cordLex4layerName=="M3")&&((SHAPE~>net~>name=="R.3")||(SHAPE~>net~>name=="R.2")||(SHAPE~>net~>name=="R.1")||(SHAPE~>net~>name=="R.0")||(SHAPE~>net~>name=="R.e")) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3)) + bbox=list(bx1:by1 cordrvx3:by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3)) + bbox=list(bx1:by1 cordLex3:by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3)) + bbox=list(bx1:by1 cordR1x3:by2)) + dbSet(SHAPE bbox "bBox")) ;moves M3 pins R.3/R.2/R.1/R.0 + when((SHAPE~>layerName=="M3")&&(SHAPE~>net~>name=="_RESET") + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5))) + bbox=list(cordrvx4:by1 cordrvx3:by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5))) + bbox=list(cordrvx4:by1 cordLex3:by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5))) + bbox=list(cordrvx4:by1 cordR1x3:by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)layerName=="M1")&&(SHAPE~>net~>name=="_r.3")&&(bx1==1.645)&&(by1==3.675) + when(((cordpx1+0.5)>cordLex3)&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordrvx3-0.07):y1 (cordpx1+0.56):y2 (cordpx1+0.56):y3 (cordpx1+0.53):y4)) + when(((cordpx1+0.5)>cordLex3)&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordrvx3-0.07):y1 (cordR2x2+0.285):y2 (cordR2x2+0.285):y3 (cordR2x2+0.255):y4)) + when(((cordpx1+0.5)=(cordpx1+0.27)) + pnts=list((cordrvx3-0.07):y1 (cordrvx3-0.07):y2 (cordrvx3-0.07):y3 (cordR2x2+0.255):y4)) + dbSet(SHAPE pnts "points")); moves M1 connecting the _Reset connecting from the M2 to the Poly_M1 vias of the NAND5 gate + when((SHAPE~>layerName=="prBoundary") + dbDeleteObject(SHAPE) + when((ActualLeftPoly<=cordrvx4)&&(ActualLeftPoly<=cordLex4) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordnx1-0.54):by1 (cordnx1-0.54):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordnx1-0.54):by1 (cordnx1-0.54):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + pnts=list((cordR1x1-0.04):by1 (cordR1x1-0.04):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordnx1-0.54):by1 (cordnx1-0.54):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordnx1-0.54):by1 (cordnx1-0.54):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordR1x2+0.04):by2 (cordR1x2+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + pnts=list((cordnx1-0.54):by1 (cordnx1-0.54):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + pnts=list((cordR1x1-0.27):by1 (cordR1x1-0.27):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + pnts=list((cordnx1-0.54):by1 (cordnx1-0.54):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1))) + when((ActualLeftPoly>cordrvx4)||(ActualLeftPoly>cordLex4) + when((cordrvx4<=cordLex4)&&(cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordrvx3+0.04):by2 (cordrvx3+0.04):by1)) + when((cordrvx4<=cordLex4)&&(cordLex3>cordrvx3)&&(cordLex3>=cordR1x3) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordLex3+0.04):by2 (cordLex3+0.04):by1)) + when((cordrvx4<=cordLex4)&&(cordR1x3>cordrvx3)&&(cordR1x3>cordLex3) + pnts=list((cordrvx4-0.04):by1 (cordrvx4-0.04):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when((cordLex4cordrvx3)&&(cordLex3>=cordR1x3) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1)) + when((cordLex4cordrvx3)&&(cordR1x3>cordLex3) + pnts=list((cordLex4-0.04):by1 (cordLex4-0.04):by2 (cordR1x3+0.04):by2 (cordR1x3+0.04):by1))) + dbCreatePRBoundary(CellView pnts)); moves prBoundary + when((SHAPE~>layerName=="M3")&&((bx1==0&&by2==0.095&&bx2==2.08)||(bx1==0&&by2==1.535&&bx2==2.08)||(bx1==0&&by2==1.655&&bx2==2.08)||(bx1==0&&by2==3.095&&bx2==2.08)||(bx1==0&&by2==3.215&&bx2==2.08)||(bx1==0&&by2==4.655&&bx2==2.08)||(bx1==0&&by2==4.775&&bx2==2.08)||(bx1==0&&by2==6.215&&bx2==2.08)) + when((ActualLeftPoly<=cordrvx4)&&(ActualLeftPoly<=cordLex4) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordrvx3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordLex3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordR1x2+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordR1x3+0.04):by2))) + when((ActualLeftPoly>cordrvx4)||(ActualLeftPoly>cordLex4) + when((cordrvx4<=cordLex4)&&(cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3) + bbox=list((cordrvx4-0.04):by1 (cordrvx3+0.04):by2)) + when((cordrvx4<=cordLex4)&&(cordLex3>cordrvx3)&&(cordLex3>=cordR1x3) + bbox=list((cordrvx4-0.04):by1 (cordLex3+0.04):by2)) + when((cordrvx4<=cordLex4)&&(cordR1x3>cordrvx3)&&(cordR1x3>cordLex3) + bbox=list((cordrvx4-0.04):by1 (cordR1x3+0.04):by2)) + when((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when((cordLex4cordrvx3)&&(cordLex3>=cordR1x3) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when((cordLex4cordrvx3)&&(cordR1x3>cordLex3) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2))) + LeftLeaf=caar(bbox) + RightLeaf=caadr(bbox)-LeftLeaf + dbSet(SHAPE bbox "bBox")); stretches M3 GND/VDD power grids + when((SHAPE~>layerName=="NP")&&((bx1==0&&by2==0.17&&bx2==2.08)||(bx1==0&&by2==6.24&&bx2==2.08)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordrvx3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordLex3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordR1x2+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordR1x3+0.04):by2)) + dbSet(SHAPE bbox "bBox")); stretches NP layer on the top and bottom of the leaf cell + when((SHAPE~>layerName=="PO")&&(bx1==2.04&&by2==6.24&&bx2==2.08) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3)) + bbox=list(cordrvx3:by1 (cordrvx3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3)) + bbox=list(cordLex3:by1 (cordLex3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3)) + bbox=list(cordR1x3:by1 (cordR1x3+0.04):by2)) + dbSet(SHAPE bbox "bBox")); moves Cut_poly on the right side of the leaf cell + when((SHAPE~>layerName=="PO")&&(bx1==0&&by2==6.24&&bx2==0.04) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5))&&(cordR1x1>(cordnx1-0.27))) + bbox=list((cordrvx4-0.04):by1 cordrvx4:by2)) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5))&&(cordR1x1<=(cordnx1-0.27))) + bbox=list((cordR1x1-0.23):by1 (cordR1x1-0.27):by2)) + when(((cordLex4(cordnx1-0.27))) + bbox=list((cordLex4-0.04):by1 cordLex4:by2)) + when(((cordLex4(cordnx1-0.27))) + bbox=list((cordnx1-0.54):by1 (cordnx1-0.5):by2)) + when((((cordnx1-0.5)layerName=="PO")&&((bx2==2.08&&by2==0.08&&bx1==0)||(bx2==2.08&&by2==0.21&&bx1==0)||(bx2==2.08&&by2==0.34&&bx1==0)||(bx2==2.08&&by2==0.47&&bx1==0)||(bx2==2.08&&by2==0.6&&bx1==0)||(bx2==2.08&&by2==0.73&&bx1==0)||(bx2==2.08&&by2==0.86&&bx1==0)||(bx2==2.08&&by2==0.99&&bx1==0)||(bx2==2.08&&by2==1.12&&bx1==0)||(bx2==2.08&&by2==1.25&&bx1==0)||(bx2==2.08&&by2==1.38&&bx1==0)||(bx2==2.08&&by2==1.51&&bx1==0)||(bx2==2.08&&by2==1.64&&bx1==0)||(bx2==2.08&&by2==1.77&&bx1==0)||(bx2==2.08&&by2==1.9&&bx1==0)||(bx2==2.08&&by2==2.03&&bx1==0)||(bx2==2.08&&by2==2.42&&bx1==0)||(bx2==2.08&&by2==2.55&&bx1==0)||(bx2==2.08&&by2==2.68&&bx1==0)||(bx2==2.08&&by2==2.81&&bx1==0)||(bx2==2.08&&by2==2.94&&bx1==0)||(bx2==2.08&&by2==3.07&&bx1==0)||(bx2==2.08&&by2==3.2&&bx1==0)||(bx2==2.08&&by2==3.33&&bx1==0)||(bx2==2.08&&by2==3.46&&bx1==0)||(bx2==2.08&&by2==3.59&&bx1==0)||(bx2==2.08&&by2==3.72&&bx1==0)||(bx2==2.08&&by2==3.85&&bx1==0)||(bx2==2.08&&by2==3.98&&bx1==0)||(bx2==2.08&&by2==4.11&&bx1==0)||(bx2==2.08&&by2==4.24&&bx1==0)||(bx2==2.08&&by2==4.37&&bx1==0)||(bx2==2.08&&by2==4.5&&bx1==0)||(bx2==2.08&&by2==4.63&&bx1==0)||(bx2==2.08&&by2==4.76&&bx1==0)||(bx2==2.08&&by2==4.89&&bx1==0)||(bx2==2.08&&by2==5.02&&bx1==0)||(bx2==2.08&&by2==5.15&&bx1==0)||(bx2==2.08&&by2==5.28&&bx1==0)||(bx2==2.08&&by2==5.41&&bx1==0)||(bx2==2.08&&by2==5.54&&bx1==0)||(bx2==2.08&&by2==5.67&&bx1==0)||(bx2==2.08&&by2==5.8&&bx1==0)||(bx2==2.08&&by2==5.93&&bx1==0)||(bx2==2.08&&by2==6.06&&bx1==0)||(bx2==2.08&&by2==6.19&&bx1==0)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordrvx3+0.04):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordrvx3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordLex3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordLex3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordrvx4-0.04):by1 (cordR1x2+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordLex4-0.04):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2<(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)=(cordpx1+0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27))&&(cordR2x2>=(cordpx1+0.27)) + bbox=list((cordnx1-0.54):by1 (cordR1x3+0.04):by2)) + dbSet(SHAPE bbox "bBox")) ; stretches the dummy poly grids to the pr bound + when((SHAPE~>layerName=="PO")&&((bx2==1.82&&by2==2.16&&bx1==0.425)||(bx2==1.82&&by2==2.29&&bx1==0.425)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + bbox=list((cordrvx4+0.22):by1 (cordrvx3-0.22):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + bbox=list((cordR1x1-0.01):by1 (cordrvx3-0.22):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4(cordnx1-0.27)) + bbox=list((cordLex4+0.22):by1 (cordrvx3-0.22):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&((cordLex4=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27)) + bbox=list((cordnx1-0.28):by1 (cordrvx3-0.22):by2)) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + bbox=list((cordrvx4+0.22):by1 (cordLex3-0.22):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + bbox=list((cordR1x1-0.01):by1 (cordLex3-0.22):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4(cordnx1-0.27)) + bbox=list((cordLex4+0.22):by1 (cordLex3-0.22):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&((cordLex4cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)(cordnx1-0.27)) + bbox=list((cordnx1-0.28):by1 (cordLex3-0.22):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3))&&(((cordnx1-0.5)cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + bbox=list((cordrvx4+0.22):by1 (cordR1x3-0.22):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + bbox=list((cordR1x1-0.01):by1 (cordR1x3-0.22):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4(cordnx1-0.27)) + bbox=list((cordLex4+0.22):by1 (cordR1x3-0.22):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&((cordLex4cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)(cordnx1-0.27)) + bbox=list((cordnx1-0.28):by1 (cordR1x3-0.22):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3))&&(((cordnx1-0.5)layerName=="PP")&&(bx1==0&&by2==2.38&&bx2==0.05) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + bbox=list((cordrvx4-0.04):by1 (cordrvx4+0.01):by2)) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + bbox=list((cordR1x1-0.27):by1 (cordR1x1-0.22):by2)) + when(((cordLex4(cordnx1-0.27)) + bbox=list((cordLex4-0.04):by1 (cordLex4+0.01):by2)) + when(((cordLex4(cordnx1-0.27)) + bbox=list((cordnx1-0.54):by1 (cordnx1-0.49):by2)) + when((((cordnx1-0.5)layerName=="NP")&&(bx1==1.99&&by2==2.355&&bx2==2.08) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3)) + bbox=list((cordrvx3-0.05):by1 (cordrvx3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3)) + bbox=list((cordLex3-0.05):by1 (cordLex3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3)) + bbox=list((cordR1x3-0.05):by1 (cordR1x3+0.04):by2)) + dbSet(SHAPE bbox "bBox")); moves NP on the right side of the PPLUG + when((SHAPE~>layerName=="NP")&&(by1==0.17&&by2==6.07) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1>(cordnx1-0.27)) + pnts=list(x1:y1 (cordrvx4-0.04):y2 (cordrvx4-0.04):y3 (cordrvx4+0.22):y4 (cordrvx4+0.22):y5 (cordrvx4-0.04):y6 (cordrvx4-0.04):y7 x8:y8)) + when(((cordrvx4<=cordLex4)&&(cordrvx4<=(cordnx1-0.5)))&&(cordR1x1<=(cordnx1-0.27)) + pnts=list(x1:y1 (cordR1x1-0.27):y2 (cordR1x1-0.27):y3 (cordR1x1-0.01):y4 (cordR1x1-0.01):y5 (cordR1x1-0.27):y6 (cordR1x1-0.27):y7 x8:y8)) + when(((cordLex4(cordnx1-0.27)) + pnts=list(x1:y1 (cordLex4-0.04):y2 (cordLex4-0.04):y3 (cordLex4+0.22):y4 (cordLex4+0.22):y5 (cordLex4-0.04):y6 (cordLex4-0.04):y7 x8:y8)) + when(((cordLex4(cordnx1-0.27)) + pnts=list(x1:y1 (cordnx1-0.54):y2 (cordnx1-0.54):y3 (cordnx1-0.28):y4 (cordnx1-0.28):y5 (cordnx1-0.54):y6 (cordnx1-0.54):y7 x8:y8)) + when((((cordnx1-0.5)layerName=="PP")&&(by1==0.17&&by2==6.07) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3)) + pnts=list((cordrvx3+0.04):y1 (cordrvx3-0.22):y2 (cordrvx3-0.22):y3 (cordrvx3+0.04):y4 (cordrvx3+0.04):y5 x6:y6 x7:y7 (cordrvx3+0.04):y8)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3)) + pnts=list((cordLex3+0.04):y1 (cordLex3-0.22):y2 (cordLex3-0.22):y3 (cordLex3+0.04):y4 (cordLex3+0.04):y5 x6:y6 x7:y7 (cordLex3+0.04):y8)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3)) + pnts=list((cordR1x3+0.04):y1 (cordR1x3-0.22):y2 (cordR1x3-0.22):y3 (cordR1x3+0.04):y4 (cordR1x3+0.04):y5 x6:y6 x7:y7 (cordR1x3+0.04):y8)) + dbSet(SHAPE pnts "points")) ;moves PP + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="PM"))&&(by1==0.13&&by2==6.11) + when(((cordrvx3>=cordLex3)&&(cordrvx3>=cordR1x3)) + bbox=list(bx1:by1 (cordrvx3+0.04):by2)) + when(((cordLex3>cordrvx3)&&(cordLex3>=cordR1x3)) + bbox=list(bx1:by1 (cordLex3+0.04):by2)) + when(((cordR1x3>cordrvx3)&&(cordR1x3>cordLex3)) + bbox=list(bx1:by1 (cordR1x3+0.04):by2)) + dbSet(SHAPE bbox "bBox")) ; stretches NW + )) + + foreach(VIA CellView->vias + (let (vx1 vy1 bx1 by1 bx2 by2 vx1 vy1 orgn) + bx1=caar(VIA~>bBox) + by1=cadar(VIA~>bBox) + bx2=caadr(VIA~>bBox) + by2=cadadr(VIA~>bBox) + vx1=car(VIA~>origin) + vy1=cadr(VIA~>origin) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.3")||(VIA~>net~>name=="_r.1"))&&((vx1==1.39)||(vx1==1.395)) + orgn=(Lpinx+0.38:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& (VIA~>net~>name=="_r.3")&&(vx1==2.01) + when((cordR2x2<(cordpx1+0.27)) + orgn=(cordpx1+0.56:vy1)) + when((cordR2x2>=(cordpx1+0.27)) + orgn=(cordR2x2+0.285:vy1)) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(VIA~>net~>name=="_r.1")&&(vx1==2.01) + when((cordR2x2<(cordpx1+0.27))&&((cordR2x2+0.285)>=(cordrvx3-0.24)) + orgn=(cordpx1+0.56:vy1)) + when((cordR2x2<(cordpx1+0.27))&&((cordR2x2+0.285)<(cordrvx3-0.24)) + orgn=(cordpx1+0.56:(vy1+0.65))) + when((cordR2x2>=(cordpx1+0.27))&&((cordR2x2+0.285)>=(cordrvx3-0.24)) + orgn=(cordR2x2+0.285:vy1)) + when((cordR2x2>=(cordpx1+0.27))&&((cordR2x2+0.285)<(cordrvx3-0.24)) + orgn=(cordR2x2+0.285:(vy1+0.65))) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& (VIA~>net~>name=="_r.2")&&(vx1==0.18) + when((cordR1x1>(cordnx1-0.27)) + orgn=(cordnx1-0.43:vy1)) + when((cordR1x1<=(cordnx1-0.27)) + orgn=(cordR1x1-0.16:vy1)) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& (VIA~>net~>name=="_r.0")&&(vx1==0.46) + orgn=(cordnx1-0.16:vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& ((VIA~>net~>name=="R.2")||(VIA~>net~>name=="R.1")||(VIA~>net~>name=="R.0"))&&(vx1==1.88) + when((cordR2x2<(cordpx1+0.27)) + orgn=(cordpx1+0.43:vy1)) + when((cordR2x2>=(cordpx1+0.27)) + orgn=(cordR2x2+0.155:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& (VIA~>net~>name=="R.e")&&(vx1==1.75) + when((cordR2x2<(cordpx1+0.27)) + orgn=(cordpx1+0.3:vy1)) + when((cordR2x2>=(cordpx1+0.27)) + orgn=(cordR2x2+0.025:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& (VIA~>net~>name=="R.3")&&(vx1==1.63) + when((cordR2x2<(cordpx1+0.27)) + orgn=(cordpx1+0.17:vy1)) + when((cordR2x2>=(cordpx1+0.27)) + orgn=(cordR2x2-0.105:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& (VIA~>net~>name=="_RESET")&&(vx1==1.445) + when((cordR2x2<(cordpx1+0.27)) + orgn=(cordpx1+0.04:vy1)) + when((cordR2x2>=(cordpx1+0.27)) + orgn=(cordR2x2-0.235:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& ((VIA~>net~>name=="L.3")||(VIA~>net~>name=="L.2")||(VIA~>net~>name=="L.1")||(VIA~>net~>name=="L.0"))&&(vx1==0.33) + when((cordR1x1>(cordnx1-0.27)) + orgn=(cordnx1-0.29:vy1)) + when((cordR1x1<=(cordnx1-0.27)) + orgn=(cordR1x1-0.02:vy1)) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& (VIA~>net~>name=="L.e")&&(vy1==4.16)&&(cordLey2!=4.25) + dbDeleteObject(VIA)) + )) + +)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*****************************************************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*****************************************************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*****************************************************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*****************************************************;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun MakeBuffer2 (CellView ViewName) + (let ( fil text k i parameter1 parameter2 parameter3 parameter4 cordM2_M1 INST SHAPE cordnx1 cordnx2 cordleftr3Px cordrightr3Px cordleftR3Px cordnr3x1 cordnr3x2 cordpx1 cordpx2 NWidth PWidth LePWidth ResPWidth cordnx1 cordnx2 cordpx1 cordpx2 cordR0y2 cordR0y1 cordR2x1 cordR2x2 cordR2x3 cordR2x4 cordR2y2 cordR1x1 cordR1x2 cordR1x3 cordR1x4 cordR1y1 cordR1y2 p_contt cordResx2 cordresx1 cordLex1 cordLex2 cordLey2 NR1Width Nr3Width Nr2Width NR3Width PR3Width Pr3Width ixy1 ixy2 a b Actualr2x ActualL2x Actualr1x ActualR3x cordrvNPx1 cordrvNPx2 cordrvPPx1 cordrvPPx2 cordr3NPx2 cordr3NPx1 cordr3PPx2 cordr3PPx1 cordR3NPx2 rightpoly leftNPLUG rightNPLUG) + k = 0 + i = 0 + fil = infile("Parameter.txt") + while( gets(k fil) != nil + text = parseString( k " \n") + parameter1 = nth(0 text) + parameter2 = nth(1 text) + parameter3 = nth(2 text) + parameter4 = nth(3 text) + ;setting instance parameters as per the spec file + foreach(INST CellView->instances + (let (N P Nparam Pparam paraN1 paraN2 paraP1 paraP2 paraP3 paraP4 paraP5 paraP6 paraP7 paraP8 paraP9 paraP10) + when( (INST->name==parameter1) && (INST->cellName=="gate.INV.0-L1_1-R") + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0") + NWidth=N) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1") + NR1Width=N + PWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.3") + NR3Width=N + PR3Width=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e") + LePWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset") + ResPWidth=P) + dbReplaceProp(INST "NW1" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( ( (INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.NMOS_CHAIN_5.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")) + paraN1 = strcat( parameter1 "." "N1") + paraN2 = strcat( parameter1 "." "N2") + paraP1 = strcat( parameter1 "." "P1") + paraP2 = strcat( parameter1 "." "P2") + paraP3 = strcat( parameter1 "." "P3") + paraP4 = strcat( parameter1 "." "P4") + paraP5 = strcat( parameter1 "." "P5") + paraP6 = strcat( parameter1 "." "P6") + paraP7 = strcat( parameter1 "." "P7") + paraP8 = strcat( parameter1 "." "P8") + paraP9 = strcat( parameter1 "." "P9") + paraP10 = strcat( parameter1 "." "P10") + when(((INST->name==paraN1) || (INST->name==paraP1) || (INST->name==paraN2) || (INST->name==paraP2) || (INST->name==paraP3) || (INST->name==paraP4) || (INST->name==paraP5) || (INST->name==paraP6) || (INST->name==paraP7) || (INST->name==paraP8) || (INST->name==paraP9) || (INST->name==paraP10)) + N=evalstring(parameter3) + Nparam=N/2000000 + P=evalstring(parameter4) + Pparam=P/2000000 + dbReplaceProp(INST "NW2" "float" Nparam) + dbReplaceProp(INST "NW5" "float" Nparam) + dbReplaceProp(INST "PW2" "float" Pparam) + dbReplaceProp(INST "PW1" "float" Pparam) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.3.N1")) + Nr3Width=N) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.N1")) + Nr2Width=N) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.3.P1")) + Pr3Width=P) + when(((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R") && (INST->name=="rv.P10")) + PrvWidth=P) + )) + ))) +; Calculates the XY origina and bBox to move instances w.r.t the new spec + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordPx cordPx1 cordPx2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.N1")) + cordNx=caar(INST~>bBox) + cordNx1=cordNx+0.02 + cordnx1=cordNx1 + cordNx2=cordNx1-0.06 + cordnx2=cordNx2) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.3.N1")) + cordNx=caadr(INST~>bBox) + cordNx1=cordNx-0.02 + cordnr3x1=cordNx1 + cordNx2=cordNx1+0.06 + cordnr3x2=cordNx2) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.3.P1")) + cordleftr3Px=caar(INST~>bBox) + cordrightr3Px=caadr(INST~>bBox)) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.P1")) + cordPx=caadr(INST~>bBox) + Lpinx=caar(INST~>bBox) + cordPx1=cordPx-0.02 + cordpx1=cordPx1 + cordPx2=cordPx1+0.06 + cordpx2=cordPx2) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0")) + cordR0y1=cadar(INST~>bBox) + cordR0y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.2")) + cordR2x1=caar(INST~>bBox) + cordR2x2=caadr(INST~>bBox) + cordR2y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1")) + cordR1x1=caar(INST~>bBox) + cordR1x2=caadr(INST~>bBox) + cordR1y1=cadar(INST~>bBox) + cordR1y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.3")) + cordR3y2=cadadr(INST~>bBox) + cordleftR3Px=caar(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset")) + when(ResPWidth>=0.15 + p_contt=0.05 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordResx2=caadr(INST~>bBox)) + when(ResPWidth<0.15 + p_contt=0.14 + dbReplaceProp(INST "p_contact_offset" "float" p_contt) + cordResx2=caadr(INST~>bBox))) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="_Reset")) + cordresx1=caar(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e")) + cordLex1=caar(INST~>bBox) + cordLex2=caadr(INST~>bBox) + cordLey2=cadadr(INST~>bBox)) + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff a1 b1) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + a=float(round((cordleftr3Px-cordR2x2-0.08-0.08+0.000000)*100))/100 + b=float(round((cordleftR3Px-(cordpx1+0.02+0.08+0.08))*100))/100 + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.3")||(INST->name=="R.1"))&&(a>=b) + XY=((xy1-b):xy2) + dbSet(INST XY "xy") + cordR3NPx2=caadr(INST~>bBox) + ixy1=car(INST~>xy) + ixy2=cadr(INST~>xy)) + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.3")||(INST->name=="R.1"))&&(abBox) + ixy1=car(INST~>xy) + ixy2=cadr(INST~>xy)) + when(((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")||(INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")) && ((INST->name=="RP.3")||(INST->name=="RP.1")||(INST->name=="_r.3.P2")||(INST->name=="_r.1.P1")||(INST->name=="_r.3.P1")||(INST->name=="_r.1.P2"))&&(a>=b) + XY=((xy1-b):xy2) + dbSet(INST XY "xy") + cordr3PPx1=caar(INST~>bBox) + cordr3PPx2=caadr(INST~>bBox)) + when(((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")||(INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")) && ((INST->name=="RP.3")||(INST->name=="RP.1")||(INST->name=="_r.3.P2")||(INST->name=="_r.1.P1")||(INST->name=="_r.3.P1")||(INST->name=="_r.1.P2"))&&(abBox) + cordr3PPx2=caadr(INST~>bBox)) + when(((INST->cellName=="stack.NMOS_CHAIN_1.0-L1-R")||(INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R")) && ((INST->name=="RN.3")||(INST->name=="RN.1")||(INST->name=="_r.3.N2")||(INST->name=="_r.1.N1")||(INST->name=="_r.3.N1")||(INST->name=="_r.1.N2"))&&(a>=b) + XY=((xy1-b):xy2) + dbSet(INST XY "xy") + cordr3NPx1=caar(INST~>bBox) + cordr3NPx2=caadr(INST~>bBox)) + when(((INST->cellName=="stack.NMOS_CHAIN_1.0-L1-R")||(INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R")) && ((INST->name=="RN.3")||(INST->name=="RN.1")||(INST->name=="_r.3.N2")||(INST->name=="_r.1.N1")||(INST->name=="_r.3.N1")||(INST->name=="_r.1.N2"))&&(abBox) + cordr3NPx2=caadr(INST~>bBox)) + when((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")&&((INST->name=="rv.P1")||(INST->name=="rv.P2")||(INST->name=="rv.P3")||(INST->name=="rv.P4")||(INST->name=="rv.P5")||(INST->name=="rv.P6")||(INST->name=="rv.P7")||(INST->name=="rv.P8")||(INST->name=="rv.P9")||(INST->name=="rv.P10"))&&(a>=b) + XY=((xy1-b):xy2) + dbSet(INST XY "xy") + cordrvPPx1=caar(INST~>bBox) + cordrvPPx2=caadr(INST~>bBox)) + when((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R")&&((INST->name=="rv.P1")||(INST->name=="rv.P2")||(INST->name=="rv.P3")||(INST->name=="rv.P4")||(INST->name=="rv.P5")||(INST->name=="rv.P6")||(INST->name=="rv.P7")||(INST->name=="rv.P8")||(INST->name=="rv.P9")||(INST->name=="rv.P10"))&&(abBox) + cordrvPPx2=caadr(INST~>bBox)) + when((INST->cellName=="stack.NMOS_CHAIN_5.0-L1-R")&&((INST->name=="rv.N2")||(INST->name=="rv.N1"))&&(a>=b) + XY=((xy1-b):xy2) + dbSet(INST XY "xy") + cordrvNPx1=caar(INST~>bBox) + cordrvNPx2=caadr(INST~>bBox)) + when((INST->cellName=="stack.NMOS_CHAIN_5.0-L1-R")&&((INST->name=="rv.N2")||(INST->name=="rv.N1"))&&(abBox) + cordrvNPx2=caadr(INST~>bBox)) + when((INST->cellName=="stack.PPLUG.0") + when(cordR2x2>1.705 + XY=((cordR2x2+0.16):xy2)) + when(cordR2x2<1.705 + XY=(1.9:xy2)) + dbSet(INST XY "xy")) + + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&(xy1==3.125) + XY=(ixy1-0.195:xy2) + dbSet(INST XY "xy")) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&(xy1==3.515) + XY=(ixy1+0.195:xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.2")||(INST->name=="R.0")) + when((cordR2y2==5.16)&&((NWidth/8)<=0.21) + n_contt=(0.47-0.11-0.09-(NWidth/8)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==5.03)&&((NWidth/7)<=0.21) + n_contt=(0.47-0.11-0.09-(NWidth/7)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.9)&&((NWidth/6)<=0.21) + n_contt=(0.47-0.11-0.09-(NWidth/6)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.77)&&((NWidth/5)<=0.21) + n_contt=(0.47-0.11-0.09-(NWidth/5)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.64)&&((NWidth/4)<=0.21) + n_contt=(0.47-0.11-0.09-(NWidth/4)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.51)&&((NWidth/3)<=0.21) + n_contt=(0.47-0.11-0.09-(NWidth/3)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.38)&&((NWidth/2)<=0.21) + n_contt=(0.47-0.11-0.09-(NWidth/2)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.25)&&(NWidth<=0.21) + n_contt=(0.47-0.11-0.09-NWidth) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==5.16)&&((NWidth/8)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==5.03)&&((NWidth/7)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.9)&&((NWidth/6)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.77)&&((NWidth/5)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.64)&&((NWidth/4)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.51)&&((NWidth/3)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.38)&&((NWidth/2)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox)) + when((cordR2y2==4.25)&&(NWidth>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR2x3=caadr(INST~>bBox) + cordR2x4=caar(INST~>bBox))) + + when((INST->cellName=="gate.INV.0-L1_1-R") && ((INST->name=="R.3")||(INST->name=="R.1")) + when((cordR1y1==1.08)&&((NR1Width/8)<=0.21) + n_contt=(0.47-0.11-0.09-(NR1Width/8)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.21)&&((NR1Width/7)<=0.21) + n_contt=(0.47-0.11-0.09-(NR1Width/7)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.34)&&((NR1Width/6)<=0.21) + n_contt=(0.47-0.11-0.09-(NR1Width/6)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.47)&&((NR1Width/5)<=0.21) + n_contt=(0.47-0.11-0.09-(NR1Width/5)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.6)&&((NR1Width/4)<=0.21) + n_contt=(0.47-0.11-0.09-(NR1Width/4)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.73)&&((NR1Width/3)<=0.21) + n_contt=(0.47-0.11-0.09-(NR1Width/3)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.86)&&((NR1Width/2)<=0.21) + n_contt=(0.47-0.11-0.09-(NR1Width/2)) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.99)&&(NR1Width<=0.21) + n_contt=(0.47-0.11-0.09-NR1Width) + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.08)&&((NR1Width/8)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.21)&&((NR1Width/7)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.34)&&((NR1Width/6)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.47)&&((NR1Width/5)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.6)&&((NR1Width/4)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.73)&&((NR1Width/3)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.86)&&((NR1Width/2)>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox)) + when((cordR1y1==1.99)&&(NR1Width>0.21) + n_contt=0.05 + dbReplaceProp(INST "n_contact_offset" "float" n_contt) + cordR1x3=caadr(INST~>bBox) + cordR1x4=caar(INST~>bBox))) + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.785)&&(xy1==0.11))||((xy2==5.525)&&(xy1==0.11))||((xy2==2.015)&&(xy1==0.11))||((xy2==1.755)&&(xy1==0.11))||((xy2==1.495)&&(xy1==0.11))) + when(((cordnx1+0.06)0.21) + XY=(cordnx1-0.03:xy2)) + when(((cordnx1+0.06)=cordR2x4) + XY=(cordR2x4-0.03:xy2)) + dbSet(INST XY "xy")) ;moves M1_poly vias on the left side of C2 gates in 1st coloumn + when((INST~>cellName=="M1_POLYmin")&&(((xy2==4.745)&&(xy1==4.28))||((xy2==4.485)&&(xy1==4.28))||((xy2==4.225)&&(xy1==4.28))||((xy2==0.715)&&(xy1==4.28))||((xy2==0.455)&&(xy1==4.28))) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + XY=(cordr3NPx2+0.01:xy2) + rightpoly=car(INST~>xy)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + XY=(3.86:xy2) + rightpoly=car(INST~>xy)) + when(((cordr3NPx2-0.06)<=cordR1x3) + XY=(cordR1x3+0.03:xy2) + rightpoly=car(INST~>xy)) + dbSet(INST XY "xy")) ;moves M1_poly vias on the right side of C2 gates in 2nd coloumn + when((INST~>cellName=="M1_POLYmin")&&(((xy2==5.915)&&(xy1==2.28))||((xy2==5.655)&&(xy1==2.28))||((xy2==2.145)&&(xy1==2.28))||((xy2==1.885)&&(xy1==2.28))) + XY=(cordpx1+0.03:xy2) + dbSet(INST XY "xy")) ;moves M1_poly vias on the right side of C2 gates in 1st coloumn + when((INST~>cellName=="M1_POLYmin")&&(xy2==5.265)&&(xy1==1.78) + when(cordR2x2>1.705 + XY=(cordR2x2+0.01:xy2)) + when(cordR2x2<1.705 + XY=(1.725:xy2)) + dbSet(INST XY "xy")) ;moves M1_poly vias on the right side of PMOS chains of C2 gates in 1st coloumn + when((INST~>cellName=="M1_POLYmin")&&(((xy2==4.355)&&(xy1==1.97))||((xy2==4.095)&&(xy1==1.97))||((xy2==0.975)&&(xy1==1.97))||((xy2==0.585)&&(xy1==1.97))||((xy2==0.325)&&(xy1==1.97))) + XY=(cordR2x3+0.15:xy2) + dbSet(INST XY "xy")) ;moves M1_poly vias on the left side of PMOS chains of C2 gates in 1st coloumn + when((INST->cellName=="stack.NPLUG.0")&&(xy1==0.13) + when(((cordnx1+0.06)0.21) + XY=((cordnx1-0.01):xy2)) + when(((cordnx1+0.06)=cordR2x4) + XY=((cordR2x4-0.01):xy2)) + leftNPLUG=car(XY)-0.13 + dbSet(INST XY "xy")) ; moves the NPLUG on the left side in the 1st coloumn + + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.NPLUG.0")&&(xy1==4.29) + when(cordrvNPx2+0.23>=rightpoly+0.07 + XY=((cordrvNPx2+0.14):xy2)) + when(cordrvNPx2+0.23shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="_r.2")||(SHAPE~>net~>name=="_r.0"))&&(((bx1==0.21)&&(by1==4.065))||((bx1==0.21)&&(by1==0.295))) + when(((cordR2x4+0.07)<=0.545) + pnts=list((cordR2x4+0.07):y1 (cordR2x4+0.07):y2 )) + when(((cordR2x4+0.07)>0.545) + pnts=list(0.545:y1 0.545:y2 )) + dbSet(SHAPE pnts "points") + Actualr2x=caar(SHAPE~>bBox)) ;Moves M2 wire connecting _r.2/_r.0 to the input of the R.2/R.0 INV + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="L.2")||(SHAPE~>net~>name=="L.0"))&&(((bx1==0.08)&&(by1==4.45))||((bx1==0.08)&&(by1==0.285))) + when(((cordnx1+0.06)0.21)&&((cordR2x4+0.07)>(cordnx1-0.01)) + pnts=list((cordnx1-0.03):y1 (cordnx1-0.03):y2 )) + when(((cordnx1+0.06)0.21)&&((cordR2x4+0.07)<=(cordnx1-0.01)) + pnts=list(0.415:y1 0.415:y2 )) + when(((cordnx1+0.06)=cordR2x4)&&((cordR2x4+0.07)<=0.545) + pnts=list((cordR2x4-0.03):y1 (cordR2x4-0.03):y2 )) + when(((cordnx1+0.06)>=cordR2x4)&&((cordR2x4+0.07)>0.545) + pnts=list(0.415:y1 0.415:y2 )) + dbSet(SHAPE pnts "points") + ActualL2x=caar(SHAPE~>bBox)) ;Moves M2 wire connecting L.2/L.0 to the respective M3 pins + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="R.e")||(SHAPE~>net~>name=="L.1"))&&(((bx1==4.25)&&(by1==0.46))||((bx1==4.25)&&(by1==2.925))) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width>0.21) + pnts=list((cordnr3x1+0.03):y1 (cordnr3x1+0.03):y2)) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width<0.21) + pnts=list(3.86:y1 3.86:y2)) + when(((cordnr3x1-0.06)<=cordR1x3) + pnts=list((cordnR1x3+0.03):y1 (cordnR1x3+0.03):y2)) + dbSet(SHAPE pnts "points")) ;Moves M2 wire connecting _r.2/_r.0 to the input of the R.2/R.0 INV + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.2")&&((bx1==0.375)&&(by1==3.75)) + pnts=list((cordrvPPx1-0.26):y1 (cordR2x4+0.07):y2 (cordR2x4+0.07):y3) + dbSet(SHAPE pnts "points")) ;Moves M1 wire connecting _r.2 with the input of the NAND5 gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="R.0")&&((bx1==0.08)&&(by1==0.1)) + when(((cordnx1+0.06)0.21) + pnts=list((cordnx1-0.03):y1 (cordnx1-0.03):y2 x3:y3)) + when(((cordnx1+0.06)=cordR2x4) + pnts=list((cordR2x4-0.03):y1 (cordR2x4-0.03):y2 x3:y3)) + dbSet(SHAPE pnts "points")) ;Moves M1 wire connecting R.0 with the input of the NAND5 gate + when((SHAPE~>layerName=="M1")&&((SHAPE~>net~>name=="_r.2")||(SHAPE~>net~>name=="_r.0"))&&(((bx1==0.21)&&(by1==4.975))||((bx1==0.21)&&(by1==4.715))||((bx1==0.21)&&(by1==4.455))||((bx1==0.21)&&(by1==4.195))||((bx1==0.21)&&(by1==1.205))||((bx1==0.21)&&(by1==0.945))||((bx1==0.21)&&(by1==0.945))||((bx1==0.21)&&(by1==0.685))||((bx1==0.21)&&(by1==0.425))) + when(((cordR2x4+0.07)<=0.545) + bbox=list((cordR2x4+0.07):by1 (cordR2x4+0.04):by2 )) + when(((cordR2x4+0.07)>0.545) + bbox=list(0.545:by1 (cordR2x4+0.04):by2 )) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the _r.2 connecting from the M2 to the Poly_M1 vias of the R.2/R.0 INV gate + when((SHAPE~>layerName=="M1")&&((SHAPE~>net~>name=="L.2")||(SHAPE~>net~>name=="L.0"))&&(((by1==5.465)&&(by2==5.845))||((by1==1.695)&&(by2==2.075))) + when(((cordnx1+0.06)0.21) + bbox=list((cordnx1-0.06):by1 cordnx1:by2 )) + when(((cordnx1+0.06)=cordR2x4) + bbox=list((cordR2x4-0.06):by1 cordR2x4:by2 )) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the _r.2 connecting from the M2 to the Poly_M1 vias of the R.2/R.0 INV gate + when((SHAPE~>layerName=="M1")&&(((by1==5.595)&&(by2==5.975))||((by1==1.805)&&(by2==2.225))) + bbox=list(cordpx1:by1 (cordpx1+0.06):by2 ) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the _r.2 connecting from the M2 to the Poly_M1 vias of the R.2/R.0 INV gate + when((SHAPE~>layerName=="PO")&&(((by1==5.45)&&(by2==5.99))||((by1==1.68)&&(by2==2.22))||((by1==1.42)&&(by2==1.57))||((by1==5.19)&&(by2==5.34))||((by1==4.67)&&(by2==4.82))) + bbox=list((cordpx1+0.1):by1 (cordpx1+0.18):by2 ) + dbSet(SHAPE bbox "bBox")); moves Cut_Poly after the C2 gates in the 1st coloumn + when((SHAPE~>layerName=="PO")&&(((by1==4.02)&&(by2==4.56))||((by1==0.25)&&(by2==0.79))||((by1==1.16)&&(by2==1.31))||((by1==0.9)&&(by2==1.05))) + bbox=list(cordR2x3:by1 (cordR2x3+0.08):by2 ) + dbSet(SHAPE bbox "bBox")); moves Cut_Poly after the C2 gates in the 1st coloumn + when((SHAPE~>layerName=="PO")&&(((by1==2.72)&&(by2==3.65))||((by1==2.46)&&(by2==2.61))) + bbox=list(cordLex2:by1 (cordLex2+0.08):by2 ) + dbSet(SHAPE bbox "bBox")); moves Cut_Poly after the L.e/Reset gates in the 1st coloumn + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="Reset")&&(by1==2.375)&&(bx1==0.53) + pnts=list(x1:y1 (cordresx1+0.08):y2 (cordresx1+0.08):y3) + dbSet(SHAPE pnts "points")); moves M1 connecting the Reset to the Poly_M1 vias of the _Reset INV gate + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="_RESET") + pnts=list((cordResx2-0.08):y1 (cordResx2-0.08):y2) + dbSet(SHAPE pnts "points")); moves M2 connecting the _RESET to the Poly_M1 vias of the Reset INV gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_RESET") + bbox=list(cordResx2-0.11:by1 cordResx2-0.015:by2) + dbSet(SHAPE bbox "bBox")); moves M1 connecting the Reset to the Poly_M1 vias of the _Reset INV gate + when((SHAPE~>layerName=="M1")&&(by1==4.91)&&(bx1==1.59) + when(cordR2x2>1.705 + pnts=list(1.06:y1 (cordR2x2+0.01):y2 (cordR2x2+0.01):y3)) + when(cordR2x2<1.705 + pnts=list(1.06:y1 1.725:y2 1.725:y3)) + dbSet(SHAPE pnts "points")); moves M1 connecting the R.2 ouput of the INV gate to the internal connection of the C2 gates i.e nmos/pmos chains + when((SHAPE~>layerName=="PO")&&(by1==5.25)&&(bx1==0.79) + when(cordR2x2>1.705 + bbox=list(bx1:by1 (cordR2x2+0.01):by2)) + when(cordR2x2<1.705 + bbox=list(bx1:by1 1.725:by2)) + dbSet(SHAPE bbox "bBox")); Moves the Poly connecting the M1_Poly vias of the nmos.pmos chains of C2 gates in the 1st coloumn + when((SHAPE~>layerName=="PO")&&(((bx1==1.97)&&(by1==4.34))||((bx1==1.97)&&(by1==0.96))||((bx1==1.97)&&(by1==4.08))||((bx1==1.97)&&(by1==0.57))||((bx1==1.97)&&(by1==0.31))) + bbox=list(cordR2x3+0.15:by1 ixy1+0.2:by2 ) + dbSet(SHAPE bbox "bBox")); moves Poly connecting the Poly_M1 vias connecting the L.3/R.e inputs in the 2nd coloumn + when((SHAPE~>layerName=="NP")&&(by1==4.695)&&(bx1==2.165) + when(cordR2x2>1.705 + bbox=list((cordR2x2+0.16):by1 (cordR2x2+0.33):by2)) + when(cordR2x2<1.705 + bbox=list(1.875:by1 2.045:by2)) + dbSet(SHAPE bbox "bBox")); moves NP layer over the PPLUG according to the PPLUG + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="rv")&&(bx1==1.625)&&(by1==2.79) + pnts=list((cordLex2-0.055):y1 (cordLex2-0.055):y2) + dbSet(SHAPE pnts "points")); moves M2 connecting the rv input of the L.e INV gate with the internal connections of the NAND5 gate. + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="Vdd")&&(bx1==3.045)&&(by1==0.19) + bbox=list((ixy1-0.275):by1 (ixy1-0.115):by2) + dbSet(SHAPE bbox "bBox")); moves M2 Vdd power strip in the 2nd coloumn + when((SHAPE~>layerName=="M2")&&(bx1==3.435)&&(by1==0.07) + bbox=list((ixy1+0.115):by1 (ixy1+0.275):by2) + dbSet(SHAPE bbox "bBox")); moves M2 GND power strip in the 2nd coloumn + when((SHAPE~>layerName=="M2")&&(((bx1==3.29)&&(by1==4.95))||((bx1==3.29)&&(by1==4.135))||((bx1==3.29)&&(by1==2.54))||((bx1==3.29)&&(by1==1.275))||((bx1==3.29)&&(by1==0.335))) + pnts=list(ixy1:y1 ixy1:y2) + dbSet(SHAPE pnts "points")); moves M2 connecting different nets in the centre of the 2nd coloumn i.e in betweeen Vdd and GND + when((SHAPE~>layerName=="CO")&&((bx1==4&&by1==2.775)||(bx1==4&&by1==3.425)) + bbox=list((cordrvNPx2+0.01):by1 (cordrvNPx2+0.05):by2) + dbSet(SHAPE bbox "bBox")) ; moves the CO's connecting the _r.1 inputs of the NAND5 gate + when((SHAPE~>layerName=="PO")&&((bx1==3.13&&by1==3.43)||(bx1==3.13&&by1==2.78)) + bbox=list((ixy1-0.05):by1 (cordrvNPx2+0.1):by2) + dbSet(SHAPE bbox "bBox")) ; moves the PO connecting the _r.1 inputs of the NAND5 gate + when((SHAPE~>layerName=="M1")&&by1==2.71&&by2==3.525 + bbox=list(cordrvNPx2:by1 (cordrvNPx2+0.06):by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the _r.1 inputs of the NAND5 gate + when((SHAPE~>layerName=="CO")&&((bx1==4.13&&by1==3.035)||(bx1==4.13&&by1==3.685)) + bbox=list((cordrvNPx2+0.14):by1 (cordrvNPx2+0.18):by2) + dbSet(SHAPE bbox "bBox")) ; moves the CO's connecting the _r.3 inputs of the NAND5 gate + when((SHAPE~>layerName=="PO")&&((bx1==3.13&&by1==3.04)||(bx1==3.13&&by1==3.69)) + bbox=list((ixy1-0.05):by1 (cordrvNPx2+0.23):by2) + dbSet(SHAPE bbox "bBox")) ; moves the PO's connecting the _r.3 inputs of the NAND5 gate + when((SHAPE~>layerName=="M1")&&bx1==4.085&&by1==3.705 + pnts=list((cordrvNPx2+0.16):y1 (cordrvNPx2+0.16):y2 Actualr1x:y3) + dbSet(SHAPE pnts "points")) ; Moves M1 connecting the _r.3 input of NAND5 with the M2 wire + when((SHAPE~>layerName=="M1")&&by1==2.97&&by2==3.795 + bbox=list((cordrvNPx2+0.13):by1 (cordrvNPx2+0.19):by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1's connecting the _r.3 inputs of the NAND5 gate + when((SHAPE~>layerName=="CO")&&((bx1==2.91&&by1==2.515)||(bx1==2.91&&by1==3.165)) + bbox=list((cordrvPPx1-0.01):by1 (cordrvPPx1-0.05):by2) + dbSet(SHAPE bbox "bBox")) ; moves the CO's connecting the _Reset inputs of the NAND5 gate + when((SHAPE~>layerName=="PO")&&((bx1==2.85&&by1==2.52)||(bx1==2.85&&by1==3.17)) + bbox=list((ixy1+0.05):by1 (cordrvPPx1-0.1):by2) + dbSet(SHAPE bbox "bBox")) ; moves the PO's connecting the _Reset inputs of the NAND5 gate + when((SHAPE~>layerName=="M1")&&by1==2.475&&by2==3.275 + bbox=list(cordrvPPx1:by1 (cordrvPPx1-0.06):by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the _Reset inputs of the NAND5 gate + when((SHAPE~>layerName=="CO")&&((bx1==2.78&&by1==2.645)||(bx1==2.78&&by1==3.295)) + bbox=list((cordrvPPx1-0.14):by1 (cordrvPPx1-0.18):by2) + dbSet(SHAPE bbox "bBox")) ; moves the CO's connecting the _r.0 inputs of the NAND5 gate + when((SHAPE~>layerName=="PO")&&((bx1==2.72&&by1==2.65)||(bx1==2.72&&by1==3.3)) + bbox=list((ixy1+0.05):by1 (cordrvPPx1-0.23):by2) + dbSet(SHAPE bbox "bBox")) ; moves the PO's connecting the _r.0 inputs of the NAND5 gate + when((SHAPE~>layerName=="M1")&&bx1==2.77&&by1==2.64 + bbox=list((cordrvPPx1-0.13):by1 (cordrvPPx1-0.19):by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the _r.0 inputs of the NAND5 gate + when((SHAPE~>layerName=="CO")&&((bx1==2.65&&by1==3.555)||(bx1==2.65&&by1==2.905)) + bbox=list((cordrvPPx1-0.27):by1 (cordrvPPx1-0.31):by2) + dbSet(SHAPE bbox "bBox")) ; moves the CO's connecting the _r.2 inputs of the NAND5 gate + when((SHAPE~>layerName=="PO")&&((bx1==2.59&&by1==2.91)||(bx1==2.59&&by1==3.56)) + bbox=list((ixy1+0.05):by1 (cordrvPPx1-0.36):by2) + dbSet(SHAPE bbox "bBox")) ; moves the PO's connecting the _r.2 inputs of the NAND5 gate + when((SHAPE~>layerName=="M1")&&by1==2.865&&by2==3.81 + bbox=list((cordrvPPx1-0.26):by1 (cordrvPPx1-0.32):by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the _r.2 inputs of the NAND5 gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="rv")&&bx1==2.9&&by1==3.35 + pnts=list((ixy1-0.09):y1 (cordrvPPx1-0.06):y2 (cordrvPPx1-0.06):y3 (ixy1-0.09):y4 (ixy1-0.09):y5 cordrvPPx1:y6 cordrvPPx1:y7 (ixy1-0.09):y8) + dbSet(SHAPE pnts "points")) ; moves the M1 connecting the rv inputs internally of the NAND5 gate + when((SHAPE~>layerName=="M1")&&((bx1==3.19&&by1==2.57)||(bx1==3.19&&by1==2.83)||(bx1==3.19&&by1==3.35)) + bbox=list(ixy1:by1 (ixy1-0.15):by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting internally the rv inputs of the NAND5 gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_Reset")&&bx1==1.075&&by1==2.31 + pnts=list(x1:y1 (ixy1-0.53):y2 (ixy1-0.53):y3 (cordrvPPx1-0.06):y4) + dbSet(SHAPE pnts "points")) ; moves the M1 _Reset connecting to the _Reset INV gate + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.0")&&bx1==1.705&&by1==2.55 + pnts=list(x1:y1 (ixy1-0.65):y2 (ixy1-0.65):y3 (cordrvPPx1-0.19):y4) + dbSet(SHAPE pnts "points")) ; moves the M1 _r.0 connecting to the _r.0 output of the respective C2 gate + when((SHAPE~>layerName=="M2")&&(SHAPE~>net~>name=="L.3")&&bx1==1.94&&by1==4.065 + pnts=list(cordR2x3+0.15:y1 cordR2x3+0.15:y2) + dbSet(SHAPE pnts "points")) ; moves the M2 of L.3 connecting to the M3 pin of L.3 + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="L.3")&&by1==4.065&&by2==4.385 + bbox=list(cordR2x3+0.12:by1 cordR2x3+0.18:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 of L.3 connecting to the M3 pin of L.3 + when((SHAPE~>layerName=="M2")&&bx1==2.07&&by1==0.085 + when((cordR2x3+0.28>=cordLex2-0.055) + pnts=list(cordR2x3+0.28:y1 cordR2x3+0.28:y2)) + when((cordR2x3+0.28layerName=="M1")&&((bx1==2.09&&by1==5.855)||(bx1==2.09&&by1==1.53)) + when((cordR2x3+0.28>=cordLex2-0.055) + pnts=list(cordR2x3+0.28:y1 cordpx1+0.03:y2 cordpx1+0.03:y3)) + when((cordR2x3+0.28layerName=="M1")&&bx1==1.94&&by1==0.1 + when((cordR2x3+0.28>=cordLex2-0.055) + pnts=list(cordR2x3+0.28:y1 cordR2x3+0.15:y2 cordR2x3+0.15:y3)) + when((cordR2x3+0.28layerName=="M1")&&by1==0.295&&by2==0.615 + bbox=list(cordR2x3+0.12:by1 cordR2x3+0.18:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 of R.e connecting to the M3 pin of R.e + when((SHAPE~>layerName=="M1")&&bx1==1.95&&by1==0.945 + pnts=list(ixy1:y1 cordR2x3+0.15:y2 cordR2x3+0.15:y3) + dbSet(SHAPE pnts "points")) ; moves the M1 of R.e connecting to the M3 pin of R.e + when((SHAPE~>layerName=="M1")&&bx1==2.16&&by1==5.045 + when(cordR2x2>1.705 + pnts=list(ixy1-0.09:y1 cordR2x2+0.16:y2 cordR2x2+0.16:y3)) + when(cordR2x2<1.705 + pnts=list(ixy1-0.09:y1 1.9:y2 1.9:y3)) + dbSet(SHAPE pnts "points")) ; moves the M1 connecting the PPLUG to the Vdd + when((SHAPE~>layerName=="M2")&&bx1==2.905&&by1==1.88 + pnts=list(ixy1-0.385:y1 ixy1-0.385:y2) + dbSet(SHAPE pnts "points")) ; moves the M2 connecting to the M3 pin of L.1 + when((SHAPE~>layerName=="M2")&&((by1==4.12&&bx1==2.905)||(by1==0.35&&bx1==2.905)) + bbox=list(ixy1-0.415:by1 ixy1-0.355:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M2 connecting to the internal nets on the left side of the C2 gates to the PMOS/NMOs chains + when((SHAPE~>layerName=="M2")&&((by1==4.38&&bx1==2.785)||(by1==0.61&&bx1==2.785)) + bbox=list(ixy1-0.475:by1 ixy1-0.535:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M2 connecting to the internal nets on the left side of the C2 gates to the PMOS/NMOs chains + when((SHAPE~>layerName=="M2")&&((by1==4.38&&bx1==3.675)||(by1==0.61&&bx1==3.675)) + bbox=list(ixy1+0.355:by1 ixy1+0.415:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M2 connecting to the internal nets on the right side of the C2 gates to the PMOS/NMOs chains + when((SHAPE~>layerName=="M1")&&bx1==3.06&&by1==3.09 + bbox=list(ixy1-0.15:by1 ixy1+0.15:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the rv input in the centre of the NAND5 gate + when((SHAPE~>layerName=="M1")&&((bx1==2.23&&by1==0.36)||(bx1==2.19&&by1==0.62)||(bx1==2.23&&by1==4.13)||(bx1==2.19&&by1==4.39)) + bbox=list(ixy1-0.09:by1 cordr3PPx1+0.09:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 over the CO's on the C2 gates in the 2nd coloumn on the left side i.e PMOS + when((SHAPE~>layerName=="M1")&&((bx1==3.29&&by1==0.36)||(bx1==3.29&&by1==4.13)) + bbox=list(ixy1-0.03:by1 cordr3NPx2-0.09:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 over the CO's on the C2 gates in the 2nd coloumn on the right side i.e NMOS in the lower half + when((SHAPE~>layerName=="M1")&&((bx1==3.41&&by1==0.62)||(bx1==3.41&&by1==4.39)) + bbox=list(ixy1+0.09:by1 cordr3NPx2-0.09:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 over the CO's on the C2 gates in the 2nd coloumn on the right side i.e NMOS in the upper half + when((SHAPE~>layerName=="M1")&&((bx1==1.15&&by1==5.82)||(bx1==1.15&&by1==5.56)||(bx1==1.15&&by1==2.05)||(bx1==1.15&&by1==1.79)) + bbox=list(bx1:by1 cordpx1-0.07:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 over the CO's on the C2 gates in the 1st coloumn on the right side i.e PMOS + when((SHAPE~>layerName=="M1")&&((bx1==1.15&&by1==5.82)||(bx1==1.15&&by1==5.56)||(bx1==1.15&&by1==2.05)||(bx1==1.15&&by1==1.79)) + i = 1.18 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:(by1+0.01) i+0.04:(by2-0.01))) + when((i+0.15)>(cordpx1-0.07) + k=20 + i = 1.18) + when((i+0.15)<=(cordpx1-0.07) + k = k+1 + i = i + 0.11))) ; draws CO for the internal nets of the C2 gates on the right side of the C2 gates in the 1st coloumn i.e on the PMOS side + when((SHAPE~>layerName=="M1")&&((bx1==0.33&&by1==5.82)||(bx1==0.335&&by1==2.05)) + i = 0.94 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:(by1+0.01) i-0.04:(by2-0.01))) + when((i-0.15)<(cordnx1+0.07) + k=20 + i = 0.94) + when((i-0.15)>=(cordnx1+0.07) + k = k+1 + i = i - 0.11))) ; draws CO for the internal nets of the C2 gates on the left side of the C2 gates in the 1st coloumn i.e on the NMOS side + when((SHAPE~>layerName=="M1")&&((bx1==0.32&&by1==5.56)||(bx1==0.32&&by1==1.79)) + i = 0.94 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:(by1+0.01) i-0.04:(by2-0.01))) + when((i-0.15)<(cordnx1+0.07) + k=20 + i = 0.94) + when((i-0.15)>=(cordnx1+0.07) + k = k+1 + i = i - 0.11))) ; draws CO for the internal nets of the C2 gates on the left side of the C2 gates in the 1st coloumn i.e on the NMOS side + when((SHAPE~>layerName=="M1")&&((bx1==2.23&&by1==0.36)||(bx1==2.19&&by1==0.62)||(bx1==2.23&&by1==4.13)||(bx1==2.19&&by1==4.39)) + i = ixy1-0.12 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:(by1+0.01) i-0.04:(by2-0.01))) + when((i-0.15)<(cordr3PPx1+0.09) + k=20 + i = ixy1-0.12) + when((i-0.15)>=(cordr3PPx1+0.09) + k = k+1 + i = i - 0.11))); draws CO for the internal nets of the C2 gates on the left side of the C2 gates in the 2nd coloumn i.e on the PMOS side + when((SHAPE~>layerName=="M1")&&((bx1==3.29&&by1==0.36)||(bx1==3.29&&by1==4.13)) + i = ixy1+0.12 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:(by1+0.01) i+0.04:(by2-0.01))) + when((i+0.15)>(cordr3NPx2-0.09) + k=20 + i = ixy1+0.12) + when((i+0.15)<=(cordr3NPx2-0.09) + k = k+1 + i = i + 0.11))); draws CO for the internal nets of the C2 gates on the right side of the C2 gates in the 2nd coloumn i.e on the NMOS side + when((SHAPE~>layerName=="M1")&&((bx1==3.41&&by1==0.62)||(bx1==3.41&&by1==4.39)) + i = ixy1+0.12 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:(by1+0.01) i+0.04:(by2-0.01))) + when((i+0.15)>(cordr3NPx2-0.09) + k=20 + i = ixy1+0.12) + when((i+0.15)<=(cordr3NPx2-0.09) + k = k+1 + i = i + 0.11))); draws CO for the internal nets of the C2 gates on the right side of the C2 gates in the 2nd coloumn i.e on the NMOS side + + when((SHAPE~>layerName=="M1")&&((bx1==0.33&&by1==5.82)||(bx1==0.335&&by1==2.05)) + bbox=list(cordnx1+0.07:by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 over the CO's on the C2 gates in the 1st coloumn on the left side i.e NMOS + when((SHAPE~>layerName=="M1")&&((bx1==0.32&&by1==5.56)||(bx1==0.32&&by1==1.79)) + bbox=list(cordnx1+0.07:by1 0.97:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 over the CO's on the C2 gates in the 1st coloumn on the left side i.e NMOS + when((SHAPE~>layerName=="M1")&&((bx1==3.29&&by1==4.65)||(bx1==3.29&&by1==0.88)) + bbox=list(ixy1-0.03:by1 ixy1+0.19:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the internal nets with the PMOS/NMOS chains of the C2 gate + + when((SHAPE~>layerName=="M1")&&(bx1==2.935&&by1==0.88)||(bx1==2.935&&by1==4.65) + bbox=list(ixy1-0.09:by1 ixy1-0.415:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the M2 which is connecting the internal net of R.3 C2 stat on left side + when((SHAPE~>layerName=="M1")&&(bx1==2.76&&by1==4.78)||(bx1==2.76&&by1==1.01) + bbox=list(ixy1-0.09:by1 ixy1-0.535:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 connecting the M2 which is connecting the internal net of R.3 C2 stat on left side + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="R.3")&&bx1==3.29&&by1==4.66 + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + pnts=list(cordr3NPx2+0.01:y1 cordr3NPx2+0.01:y2 ixy1:y3 ixy1:y4)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + pnts=list(3.86:y1 3.86:y2 ixy1:y3 ixy1:y4)) + when(((cordr3NPx2-0.06)<=cordR1x3) + pnts=list(cordR1x3+0.03:y1 cordR1x3+0.03:y2 ixy1:y3 ixy1:y4)) + dbSet(SHAPE pnts "points") + ActualR3x=caadr(SHAPE~>bBox)) ; moves the M1 connecting the R.3 input from the middle of the R.3 gate to the input of the internal chains of C2 gate + when((SHAPE~>layerName=="M1")&&(bx1==3.41&&by1==1.01)||(bx1==3.41&&by1==4.78) + bbox=list(ixy1+0.09:by1 ixy1+0.415:by2) + dbSet(SHAPE bbox "bBox")) ; moves M1 connecting the M2 which is connecting the internal net on the right side of the C2 gate + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="_r.3")||(SHAPE~>net~>name=="_r.1"))&&((by1==3.77&&bx1==4.11)||(by1==0.485&&bx1==4.11)) + when(((cordR3NPx2-0.1)>=(ixy1+0.415)) + pnts=list(cordR3NPx2-0.07:y1 cordR3NPx2-0.07:y2)) + when(((cordR3NPx2-0.1)<(ixy1+0.415)) + pnts=list(ixy1+0.505:y1 ixy1+0.505:y2)) + dbSet(SHAPE pnts "points") + Actualr1x=caar(SHAPE~>bBox)) ;Moves the M2 connecting the _r.3 and _r.1 with the NAND5 gate on the right side of the 2nd coloumn + when((SHAPE~>layerName=="M1")&&((bx1==3.985&&by1==1.335)||(bx1==3.985&&by1==1.595)||(bx1==3.985&&by1==1.855)||(bx1==3.985&&by1==2.115)||(bx1==3.99&&by1==5.105)||(bx1==3.99&&by1==5.365)||(bx1==3.99&&by1==5.625)||(bx1==3.99&&by1==5.885)) + when(((cordR3NPx2-0.1)>=(ixy1+0.415)) + bbox=list(cordR3NPx2-0.11:by1 cordR3NPx2-0.03:by2)) + when(((cordR3NPx2-0.1)<(ixy1+0.415)) + bbox=list(cordR3NPx2-0.11:by1 ixy1+0.505:by2)) + dbSet(SHAPE bbox "bBox")) ;Moves the M1 connecting M2 wires of the _r.3 and _r.1 with the Poly_M1 vias of the R.3/R.1 INV gates + when((SHAPE~>layerName=="M1")&&(SHAPE~>net~>name=="_r.1")&&(bx2==4.14&&by1==2.71) + when(((cordR3NPx2-0.1)>=(ixy1+0.415)) + bbox=list(cordR3NPx2-0.11:by1 cordrvNPx2+0.06:by2)) + when(((cordR3NPx2-0.1)<(ixy1+0.415)) + bbox=list(ixy1+0.505:by1 cordrvNPx2+0.06:by2)) + dbSet(SHAPE bbox "bBox")) ;Moves the M1 connecting the _r.1 input of the NAND5 gate with the M2 wire + when((SHAPE~>layerName=="M2")&&((SHAPE~>net~>name=="L.1")||(SHAPE~>net~>name=="R.e"))&&((by1==2.925&&bx1==4.25)||(by1==0.46&&bx1==4.25)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + pnts=list(cordr3NPx2+0.01:y1 cordr3NPx2+0.01:y2)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + pnts=list(3.86:y1 3.86:y2)) + when(((cordr3NPx2-0.06)<=cordR1x3) + pnts=list(cordR1x3+0.03:y1 cordR1x3+0.03:y2)) + dbSet(SHAPE pnts "points")) ; Moves the M2 connecting to the L.1/R.e inputs on the right side of the C2 gates in the 2nd coloum + when((SHAPE~>layerName=="M1")&&(bx1==2.93&&by1==2.31) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + pnts=list(ixy1-0.385:y1 cordr3NPx2+0.04:y2)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + pnts=list(ixy1-0.385:y1 3.89:y2)) + when(((cordr3NPx2-0.06)<=cordR1x3) + pnts=list(ixy1-0.385:y1 cordR1x3+0.06:y2)) + dbSet(SHAPE pnts "points")) ; Moves M1 connecting the two M2's further connecting the L.1 net in the 2nd coloumn of the gates + when((SHAPE~>layerName=="M1")&&(bx1==1.64&&by1==3.87) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + pnts=list(cordLex2-0.055:y1 ixy1:y2)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + pnts=list(cordLex2-0.055:y1 ixy1:y2)) + when(((cordr3NPx2-0.06)<=cordR1x3) + pnts=list(cordLex2-0.055:y1 ixy1:y2)) + dbSet(SHAPE pnts "points")) ; Moves M1 connecting the two M2's further connecting the rv net in the centre of the gates in the two coloumns + when((SHAPE~>layerName=="M1")&&(by1==0.425&&by2==0.745)||(by1==4.17&&by2==4.545) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + bbox=list(cordr3NPx2-0.02:by1 cordr3NPx2+0.04:by2)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + bbox=list(3.83:by1 3.89:by2)) + when(((cordr3NPx2-0.06)<=cordR1x3) + bbox=list(cordR1x3:by1 cordR1x3+0.06:by2)) + dbSet(SHAPE bbox "bBox")) ; Moves the M1 connecting the L.1/R.e inputs on the right side of the C2 gates in between the 2 Poly_M1 vias + when((SHAPE~>layerName=="M1")&&(bx1==0.1&&by1==3.22) + pnts=list(0.97:y1 leftNPLUG+0.1:y2) + dbSet(SHAPE pnts "points")) ; Moves the M1 connecting the NPLUG to the GND on the left side of the gate in the 1st coloumn + when((SHAPE~>layerName=="M1")&&(bx1==3.715&&by1==2.44) + pnts=list(ixy1+0.09:y1 rightNPLUG-0.13:y2 rightNPLUG-0.13:y3) + dbSet(SHAPE pnts "points")) ; Moves the M1 connecting the NPLUG to the GND on the right side of the gate in the 2nd coloumn + when((SHAPE~>layerName=="M1")&&((bx1==3.12&&by1==0.49)||(bx1==3.12&&by1==4.26)) + when(((cordR3NPx2-0.1)>=(ixy1+0.415)) + bbox=list(ixy1-0.2:by1 cordR3NPx2-0.07:by2)) + when(((cordR3NPx2-0.1)<(ixy1+0.415)) + bbox=list(ixy1-0.2:by1 ixy1+0.505:by2)) + dbSet(SHAPE bbox "bBox")) ; Moves the M1 connecting to the output _r.1 of the C2 gates in the lower portion of the 2nd coloumn + when((SHAPE~>layerName=="PO")&&((bx1==3.06&&by1==0.7)||(bx1==3.06&&by1==0.44)||(bx1==3.06&&by1==4.21)||(bx1==3.06&&by1==4.47)||(bx1==3.06&&by1==4.73)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + bbox=list(ixy1-0.2:by1 cordr3NPx2+0.01:by2)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + bbox=list(ixy1-0.2:by1 3.86:by2)) + when(((cordr3NPx2-0.06)<=cordR1x3) + bbox=list(ixy1-0.2:by1 cordR1x3+0.03:by2)) + dbSet(SHAPE bbox "bBox")) ; Moves the poly in the C2 gates connecting to the Poly_M1 vias on the right side of the C2 gates in the 2nd coloumn + when((SHAPE~>layerName=="PO")&&(bx1==4.38&&bx2==4.42) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + bbox=list(cordrvNPx2+0.23:by1 cordrvNPx2+0.27:by2)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + bbox=list(rightpoly+0.07:by1 rightpoly+0.11:by2)) + dbSet(SHAPE bbox "bBox")) ; moves CUT_POLY on the right of the leaf cell + when((SHAPE~>layerName=="PO")&&(by2==6.24&&bx2==0.04) + when(((cordnx1+0.06)0.21) + bbox=list((cordnx1-0.1):by1 (cordnx1-0.14):by2)) + when(((cordnx1+0.06)=cordR2x4) + bbox=list((cordR2x4-0.1):by1 (cordR2x4-0.14):by2)) + dbSet(SHAPE bbox "bBox")) ; moves CUT_POLY on the left of the leaf cell + when((SHAPE~>layerName=="PP")&&(by1==3.12&&by2==3.645) + when(((cordnx1+0.06)0.21) + bbox=list((cordnx1-0.14):by1 (cordnx1-0.06):by2)) + when(((cordnx1+0.06)=cordR2x4) + bbox=list((cordR2x4-0.14):by1 (cordR2x4-0.06):by2)) + dbSet(SHAPE bbox "bBox")) ; moves the PP on the left side of the NPLUG in the 1st coloumn + when((SHAPE~>layerName=="PP")&&(by1==2.34&&by2==2.865) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + bbox=list(cordrvNPx2+0.19:by1 cordrvNPx2+0.27:by2)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + bbox=list(rightpoly+0.03:by1 rightpoly+0.11:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the PP on the right side of the NPLUG in the 2nd coloumn + when((SHAPE~>layerName=="NP")&&(bx2==1.06&&by2==6.24) + when(((cordnx1+0.06)0.21) + pnts=list(x1:y1 (cordnx1-0.14):y2 (cordnx1-0.14):y3 (cordnx1+0.095):y4 (cordnx1+0.095):y5 (cordnx1-0.14):y6 (cordnx1-0.14):y7 x8:y8)) + when(((cordnx1+0.06)=cordR2x4) + pnts=list(x1:y1 (cordR2x4-0.14):y2 (cordR2x4-0.14):y3 (cordR2x4+0.095):y4 (cordR2x4+0.095):y5 (cordR2x4-0.14):y6 (cordR2x4-0.14):y7 x8:y8)) + dbSet(SHAPE pnts "points")) ; moves the NP on the left side of the NPLUG in the 1st coloumn + when((SHAPE~>layerName=="NP")&&(bx1==3.32&&by2==2.34) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + bbox=list(ixy1:by1 cordrvNPx2+0.27:by2)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + bbox=list(ixy1:by1 rightpoly+0.11:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the NP on the right side of the NPLUG in the lower half of the 2nd coloumn + when((SHAPE~>layerName=="NP")&&(bx1==3.32&&by2==6.24) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + pnts=list(cordrvNPx2+0.035:y1 cordrvNPx2+0.035:y2 cordrvNPx2+0.27:y3 cordrvNPx2+0.27:y4 ixy1:y5 ixy1:y6)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + pnts=list(rightpoly-0.125:y1 rightpoly-0.125:y2 rightpoly+0.11:y3 rightpoly+0.11:y4 ixy1:y5 ixy1:y6)) + dbSet(SHAPE pnts "points")) ; moves the NP on the right side of the NPLUG in the upper half of the 2nd coloumn + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="PM"))&&((by1==3.86&&by2==6.11)||(by1==2.34&&by2==3.86)||(by1==0.13&&by2==2.34)) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW in the centre of the leaf cell w.r.t gates + when((SHAPE~>layerName=="PP")&&((by1==0.17&&by2==2.34)||(by1==2.34&&by2==4.695)) + bbox=list(bx1:by1 ixy1:by2) + dbSet(SHAPE bbox "bBox")) ; moves the PP in the centre of the leaf cell w.r.t gates + when((SHAPE~>layerName=="PP")&&(bx1==1.06&&by1==4.695) + when(cordR2x2>1.705 + pnts=list(ixy1:y1 x2:y2 x3:y3 cordR2x2+0.055:y4 cordR2x2+0.055:y5 cordR2x2+0.33:y6 cordR2x2+0.33:y7 ixy1:y8)) + when(cordR2x2<=1.705 + pnts=list(ixy1:y1 x2:y2 x3:y3 1.795:y4 1.795:y5 2.045:y6 2.045:y7 ixy1:y8)) + dbSet(SHAPE pnts "points")) ; moves the PP in the centre of the leaf cell w.r.t gates around the PPLUG region + when((SHAPE~>layerName=="prBoundary") + dbDeleteObject(SHAPE) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + pnts=list((cordnx1-0.14):by1 (cordnx1-0.14):by2 cordrvNPx2+0.27:by2 cordrvNPx2+0.27:by1)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + pnts=list(0.6:by1 0.6:by2 cordrvNPx2+0.27:by2 cordrvNPx2+0.27:by1)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + pnts=list((cordR2x4-0.14):by1 (cordR2x4-0.14):by2 cordrvNPx2+0.27:by2 cordrvNPx2+0.27:by1)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + pnts=list((cordnx1-0.14):by1 (cordnx1-0.14):by2 rightpoly+0.11:by2 rightpoly+0.11:by1)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + pnts=list((cordR2x4-0.14):by1 (cordR2x4-0.14):by2 rightpoly+0.11:by2 rightpoly+0.11:by1)) + dbCreatePRBoundary(CellView pnts)) ;mover the prBoundary w.r.t the new parameters + when((SHAPE~>layerName=="M3")&&((by1==0.025&&by2==0.095)||(by1==1.465&&by2==1.535)||(by1==1.585&&by2==1.655)||(by1==3.025&&by2==3.095)||(by1==3.145&&by2==3.215)||(by1==4.585&&by2==4.655)||(by1==4.705&&by2==4.775)||(by1==6.145&&by2==6.215)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(0.6:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 rightpoly+0.11:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 rightpoly+0.11:by2)) + LeftLeaf=caar(bbox) + RightLeaf=caadr(bbox)-LeftLeaf + dbSet(SHAPE bbox "bBox")) ;moves the M3 GND/Vdd power wires + when((SHAPE~>layerName=="M3")&&((bx1==0.04&&by1==0.295)||(bx1==0.04&&by1==2.895)||(bx1==0.04&&by1==4.455)) + when(((cordnx1+0.06)0.21) + bbox=list((cordnx1-0.1):by1 bx2:by2)) + when(((cordnx1+0.06)=cordR2x4) + bbox=list((cordR2x4-0.1):by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins L.0/L.2/L.e on the left side + when((SHAPE~>layerName=="M3")&&(bx1==0.04&&by1==1.855) + when(((cordnx1+0.06)0.21) + bbox=list((cordnx1-0.1):by1 ixy1-0.385:by2)) + when(((cordnx1+0.06)=cordR2x4) + bbox=list((cordR2x4-0.1):by1 ixy1-0.385:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins L.1 on the left side + when((SHAPE~>layerName=="M3")&&(bx1==0.04&&by1==4.975) + when(((cordnx1+0.06)0.21) + bbox=list((cordnx1-0.1):by1 cordR2x3+0.15:by2)) + when(((cordnx1+0.06)=cordR2x4) + bbox=list((cordR2x4-0.1):by1 cordR2x3+0.15:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins L.3 on the left side + when((SHAPE~>layerName=="M3")&&(bx1==1.435&&by1==0.295) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + bbox=list(bx1:by1 cordrvNPx2+0.23:by2)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + bbox=list(bx1:by1 rightpoly+0.07:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins R.0 on the right side + when((SHAPE~>layerName=="M3")&&(bx1==3.32&&by1==1.855) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + bbox=list(ixy1:by1 cordrvNPx2+0.23:by2)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + bbox=list(ixy1:by1 rightpoly+0.07:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins R.1 on the right side + when((SHAPE~>layerName=="M3")&&(bx1==2.09&&by1==2.895) + when((cordR2x3+0.28>=cordLex2-0.055) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width>0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x3+0.28):by1 cordrvNPx2+0.23:by2)) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width>0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x3+0.28):by1 rightpoly+0.07:by2)) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width<0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list(cordR2x3+0.28:by1 cordrvNPx2+0.23:by2)) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width<0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list(cordR2x3+0.28:by1 rightpoly+0.07:by2)) + when(((cordnr3x1-0.06)<=cordR1x3)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x3+0.28):by1 cordrvNPx2+0.23:by2)) + when(((cordnr3x1-0.06)<=cordR1x3)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x3+0.28):by1 rightpoly+0.07:by2))) + when((cordR2x3+0.28cordR1x3)&&(Nr3Width>0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordLex2+0.075):by1 cordrvNPx2+0.23:by2)) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width>0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordLex2+0.075):by1 rightpoly+0.07:by2)) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width<0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list(cordLex2+0.075:by1 cordrvNPx2+0.23:by2)) + when(((cordnr3x1-0.06)>cordR1x3)&&(Nr3Width<0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list(cordLex2+0.075:by1 rightpoly+0.07:by2)) + when(((cordnr3x1-0.06)<=cordR1x3)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordLex2+0.075):by1 cordrvNPx2+0.23:by2)) + when(((cordnr3x1-0.06)<=cordR1x3)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordLex2+0.075):by1 rightpoly+0.07:by2))) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins R.e on the right side + when((SHAPE~>layerName=="M3")&&(bx1==1.435&&by1==4.455) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + bbox=list(1.45:by1 cordrvNPx2+0.23:by2)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + bbox=list(1.45:by1 rightpoly+0.07:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins R.2 on the right side + when((SHAPE~>layerName=="M3")&&(bx1==3.32&&by1==4.975) + when((cordrvNPx2+0.23)>=(rightpoly+0.07) + bbox=list(ixy1:by1 cordrvNPx2+0.23:by2)) + when((cordrvNPx2+0.23)<(rightpoly+0.07) + bbox=list(ixy1:by1 rightpoly+0.07:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M3 pins R.3 on the right side + + when((SHAPE~>layerName=="M3")&&(bx1==0.04&&by1==3.415) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordnx1-0.1):by1 cordrvNPx2+0.23:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(0.6:by1 cordrvNPx2+0.23:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x4-0.1):by1 cordrvNPx2+0.23:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordnx1-0.1):by1 rightpoly+0.07:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x4-0.1):by1 rightpoly+0.07:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the RESET M3 pin + when((SHAPE~>layerName=="PO")&&((bx1==0&&by2==0.08)||(bx1==0&&by2==0.21)||(bx1==0&&by2==0.34)||(bx1==0&&by2==0.47)||(bx1==0&&by2==0.6)||(bx1==0&&by2==0.73)||(bx1==0&&by2==0.86)||(bx1==0&&by2==0.99)||(bx1==0&&by2==1.12)||(bx1==0&&by2==1.25)||(bx1==0&&by2==1.38)||(bx1==0&&by2==1.51)||(bx1==0&&by2==1.64)||(bx1==0&&by2==1.77)||(bx1==0&&by2==1.9)||(bx1==0&&by2==2.03)||(bx1==0&&by2==2.16)||(bx1==0&&by2==2.29)||(bx1==0&&by2==2.42)||(bx1==0&&by2==2.55)||(bx1==0&&by2==2.94)||(bx1==0&&by2==3.07)||(bx1==0&&by2==3.46)||(bx1==0&&by2==3.59)||(bx1==0&&by2==3.72)||(bx1==0&&by2==3.85)||(bx1==0&&by2==3.98)||(bx1==0&&by2==4.11)||(bx1==0&&by2==4.24)||(bx1==0&&by2==4.37)||(bx1==0&&by2==4.5)||(bx1==0&&by2==4.63)||(bx1==0&&by2==4.76)||(bx1==0&&by2==4.89)||(bx1==0&&by2==5.28)||(bx1==0&&by2==5.41)||(bx1==0&&by2==5.54)||(bx1==0&&by2==5.67)||(bx1==0&&by2==5.8)||(bx1==0&&by2==5.93)||(bx1==0&&by2==6.06)||(bx1==0&&by2==6.19)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(0.6:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 rightpoly+0.11:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 rightpoly+0.11:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the dummy poly grids + when((SHAPE~>layerName=="PO")&&((bx1==0&&by2==2.68)||(bx1==0&&by2==2.81)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 cordrvNPx2+0.035:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(0.6:by1 cordrvNPx2+0.035:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 cordrvNPx2+0.035:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 rightpoly-0.125:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 rightpoly-0.125:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the 2 dummy polys near the 2nd NPLUG on the right side in 2nd coloumn + when((SHAPE~>layerName=="PO")&&((bx1==0.4&&by2==3.2)||(bx1==0.4&&by2==3.33)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordnx1+0.095):by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(0.695:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x4+0.095):by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordnx1+0.095):by1 rightpoly+0.11:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x4+0.095):by1 rightpoly+0.11:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the 2 dummy polys near the 1st NPLUG on the left side in 1st coloumn + when((SHAPE~>layerName=="PO")&&((bx1==2.46&&by2==5.15)||(bx1==2.46&&by2==5.02)) + when(cordR2x2>1.705 + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list(cordR2x2+0.33:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(cordR2x2+0.33:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list(cordR2x2+0.33:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list(cordR2x2+0.33:by1 rightpoly+0.11:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list(cordR2x2+0.33:by1 rightpoly+0.11:by2))) + when(cordR2x2<1.705 + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list(1.98:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(1.98:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list(1.98:by1 cordrvNPx2+0.27:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list(1.98:by1 rightpoly+0.11:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list(1.98:by1 rightpoly+0.11:by2))) + dbSet(SHAPE bbox "bBox")) ;moves the poly on the right side of the PPLUG + when((SHAPE~>layerName=="PO")&&((bx1==0&&by2==5.15)||(bx1==0&&by2==5.02)) + when(cordR2x2>1.705 + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 cordR2x2:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(0.6:by1 cordR2x2:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 cordR2x2:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 cordR2x2:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 cordR2x2:by2))) + when(cordR2x2<1.705 + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 1.82:by2)) + when(((cordnx1+0.06)=(rightpoly+0.07)) + bbox=list(0.6:by1 1.82:by2)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordrvNPx2+0.23)>=(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 1.82:by2)) + when(((cordnx1+0.06)0.21)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordnx1-0.14):by1 1.82:by2)) + when(((cordnx1+0.06)=cordR2x4)&&((cordrvNPx2+0.23)<(rightpoly+0.07)) + bbox=list((cordR2x4-0.14):by1 1.82:by2))) + dbSet(SHAPE bbox "bBox")) ;moves the poly on the right side of the PPLUG + + when((SHAPE~>layerName=="NP")&&(bx1==1.06&&by2==0.17) + bbox=list( bx1:(by1-0.13) ixy1:by2) + dbCreateRect(CellView NWellLPP list(leftNPLUG:(by1-0.13) rightNPLUG:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the NP layer in the bottom portion of the leaf cell and also draws NWell in the bottom portion + when((SHAPE~>layerName=="NP")&&(by1==6.07&&by2==6.24) + bbox=list( bx1:by1 ixy1:(by2+0.13) ) + dbCreateRect(CellView NWellLPP list(leftNPLUG:by1 rightNPLUG:(by2+0.13))) + dbSet(SHAPE bbox "bBox")) ; moves the NP layer in the top portion of the leaf cell and also draws NWell in the top portion + when(((SHAPE~>layerName=="CO")||(SHAPE~>layerName=="OD"))&&((by1==0.37&&by2==0.41)||(by1==0.365&&by2==0.415)||(by1==0.63&&by2==0.67)||(by1==0.625&&by2==0.675)||(by1==4.14&&by2==4.18)||(by1==4.135&&by2==4.185)||(by1==4.4&&by2==4.44)||(by1==4.395&&by2==4.445)||(by1==5.57&&by2==5.61)||(by1==5.565&&by2==5.615)||(by1==5.83&&by2==5.87)||(by1==5.825&&by2==5.875)||(by1==2.06&&by2==2.1)||(by1==2.055&&by2==2.105)||(by1==1.8&&by2==1.84)||(by1==1.795&&by2==1.845)) + dbDeleteObject(SHAPE) + ) + + + )) + + foreach(VIA CellView->vias + (let (vx1 vy1 bx1 by1 bx2 by2 vx1 vy1 orgn pnts) + bx1=caar(VIA~>bBox) + by1=cadar(VIA~>bBox) + bx2=caadr(VIA~>bBox) + by2=cadadr(VIA~>bBox) + vx1=car(VIA~>origin) + vy1=cadr(VIA~>origin) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.2")||(VIA~>net~>name=="_r.0"))&&(vx1==0.24)&&((vy1==5.745)||(vy1==1.975)) + when((ActualL2x+0.14)<=Actualr2x + dbDeleteObject(VIA) + when(((cordR2x4+0.07)<=0.545) + pnts=(cordR2x4+0.07:vy1-0.025)) + when(((cordR2x4+0.07)>0.545) + pnts=(0.545:vy1-0.025)) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1a_O" "layout" nil pnts "R90" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1XDefOverride" "float" 0.005) + list("layer1YDefOverride" "float" 0.03) + list("layer2XDefOverride" "float" 0.03) + list("layer2YDefOverride" "float" 0.005) ) ))) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.2")||(VIA~>net~>name=="_r.0"))&&(vx1==0.24) + when(ActualL2x+0.13>=Actualr2x + when(((cordR2x4+0.07)<=0.545) + orgn=(cordR2x4+0.07:vy1)) + when(((cordR2x4+0.07)>0.545) + orgn=(0.545:vy1)) + dbSet(VIA orgn "origin")) + when(ActualL2x+0.130.545) + orgn=(0.545:vy1+0.025)) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1a_O" "layout" nil orgn "R90" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1XDefOverride" "float" 0.005) + list("layer1YDefOverride" "float" 0.03) + list("layer2XDefOverride" "float" 0.03) + list("layer2YDefOverride" "float" 0.005) ) ))) + + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&& ((VIA~>net~>name=="L.2")||(VIA~>net~>name=="L.0"))&&(vx1==0.11) + when(((cordnx1+0.06)0.21)&&((cordR2x4+0.07)>(cordnx1-0.01)) + orgn=(cordnx1-0.03:vy1)) + when(((cordnx1+0.06)0.21)&&((cordR2x4+0.07)<=(cordnx1-0.01)) + orgn=(0.415:vy1)) + when(((cordnx1+0.06)=cordR2x4)&&((cordR2x4+0.07)<=0.545) + orgn=(cordR2x4-0.03:vy1)) + when(((cordnx1+0.06)>=cordR2x4)&&((cordR2x4+0.07)>0.545) + orgn=(0.415:vy1)) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.3")||(VIA~>net~>name=="_r.1"))&&(((vx1==4.14)&&(vy1==0.495))||((vx1==4.14)&&(vy1==4.265))) + when(Actualr1x=cordr3NPx2 + orgn=(Actualr1x+0.03:vy1) + dbSet(VIA orgn "origin")) + when(Actualr1xviaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.3")||(VIA~>net~>name=="_r.1"))&&((vx1==4.14&&vy1==5.89)||(vx1==4.14&&vy1==5.63)||(vx1==4.14&&vy1==5.37)||(vx1==4.14&&vy1==5.11)) + when(Actualr1x+0.13>ActualR3x + orgn=(Actualr1x+0.03:vy1) + dbSet(VIA orgn "origin")) + when(Actualr1x+0.13<=ActualR3x + dbDeleteObject(VIA)) + orgn=(Actualr1x+0.03:vy1+0.025) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1a_O" "layout" nil orgn "R90" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1XDefOverride" "float" 0.005) + list("layer1YDefOverride" "float" 0.03) + list("layer2XDefOverride" "float" 0.03) + list("layer2YDefOverride" "float" 0.005) ) )) + + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& ((VIA~>net~>name=="_r.3")||(VIA~>net~>name=="_r.1"))&&((vx1==4.14&&vy1==1.365)||(vx1==4.14&&vy1==1.625)||(vx1==4.14&&vy1==1.885)||(vx1==4.14&&vy1==2.145)||(vx1==4.14&&vy1==2.74)||(vx1==4.14&&vy1==3.91)) + orgn=(Actualr1x+0.03:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&& (VIA~>net~>name=="rv")&&(vx1==1.655) + orgn=(cordLex2-0.055:vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(VIA~>net~>name=="_RESET")&&(vx1==1.485) + orgn=(cordResx2-0.08:vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==3.32) + orgn=(ixy1:vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(VIA~>net~>name=="L.3")&&(vx1==1.97) + orgn=(cordR2x3+0.15:vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==2.1) + when((cordR2x3+0.28>=cordLex2-0.055) + orgn=(cordR2x3+0.28:vy1)) + when((cordR2x3+0.28viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==4.28) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width>0.21) + orgn=(cordr3NPx2+0.01:vy1)) + when(((cordr3NPx2-0.06)>cordR1x3)&&(Nr3Width<0.21) + orgn=(3.86:vy1)) + when(((cordr3NPx2-0.06)<=cordR1x3) + orgn=(cordR1x3+0.03:vy1)) + dbSet(VIA orgn "origin")) ; Moves the M2_M1/M3_M2 vias of R.e/L.1 on the right side of the C2 gates in the 2nd coloumn + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==2.935) + orgn=(ixy1-0.385:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==2.815) + orgn=(ixy1-0.505:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==3.705) + orgn=(ixy1+0.385:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==4.14) + when(((cordR3NPx2-0.1)>=(ixy1+0.415)) + orgn=(cordR3NPx2-0.07:vy1)) + when(((cordR3NPx2-0.1)<(ixy1+0.415)) + orgn=(ixy1+0.505:vy1)) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M3_M2_R_H")&& (vx1==3.515) + orgn=(ixy1+0.195:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M3_M2_R_H")&& (vx1==3.125) + orgn=(ixy1-0.195:vy1) + dbSet(VIA orgn "origin")) + )) + )) + + +(defun MakeBuffer_FullHeight (CellView ViewName) + (let (text parameter1 parameter2 parameter3 parameter4 cordM2_M1 INST SHAPE VIA Inst_Reset cordx cordx1 cordx2 cordR3y2 cordP2x cordP2x1 cordP1x cordP1x1 cordP0x cordP0x1 cordNx cordNx1 cordN2x cordN2x1 cordN1x cordN1x1 cordN0x cordN0x1 cordNx2 cordLx cordLx1 cordLx2 cordrvx cordrvx2 cordrvPx cordrv1 cordrv2 cordR2 cordR0 cordRx1 ActualcordRx1 ActualcordRx0 ActualResx ActualReset Actualcordr3x cordLe ResNWidth ResPWidth ResetNWidth R3NWidth R2PWidth LePWidth cordR2y2 cordR1y2 cordR1y1 cordR0y1 cordLey2 ActualPolyLeft ActualrvLeft cordR2x1 cordR0x1) + fl = infile("Parameter.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + parameter1 = nth(0 text) + parameter2 = nth(1 text) + parameter3 = nth(2 text) + parameter4 = nth(3 text) + +; setting instance parameters as per the spec file + foreach(INST CellView->instances + (let (N P Nparam Pparam paraN1 paraN2 paraP1 paraP2 paraP3 paraP4 paraP5 paraP6 paraP7 paraP8 paraP9 paraP10) + when( (INST->cellName=="gate.INV.0-L1_1-R")&& (INST->name==parameter1) + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.3") + R3NWidth=N) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.2") + R2PWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset") + ResPWidth=P + ResNWidth=N) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e") + LePWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="_Reset") + ResetNWidth=N) + dbReplaceProp(INST "NW1" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( ( (INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.NMOS_CHAIN_5.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")) + paraN1 = strcat( parameter1 "." "N1") + paraN2 = strcat( parameter1 "." "N2") + paraP1 = strcat( parameter1 "." "P1") + paraP2 = strcat( parameter1 "." "P2") + when(((INST->name==paraN1) || (INST->name==paraP1) || (INST->name==paraN2) || (INST->name==paraP2) ) + N=evalstring(parameter3) + Nparam=N/2000000 + P=evalstring(parameter4) + Pparam=P/2000000 + dbReplaceProp(INST "NW2" "float" Nparam) + dbReplaceProp(INST "NW5" "float" Nparam) + dbReplaceProp(INST "PW2" "float" Pparam) + )) + when( INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R" + paraP1 = strcat( parameter1 "." "P1") + paraP2 = strcat( parameter1 "." "P2") + paraP3 = strcat( parameter1 "." "P3") + paraP4 = strcat( parameter1 "." "P4") + paraP5 = strcat( parameter1 "." "P5") + paraP6 = strcat( parameter1 "." "P6") + paraP7 = strcat( parameter1 "." "P7") + paraP8 = strcat( parameter1 "." "P8") + paraP9 = strcat( parameter1 "." "P9") + paraP10 = strcat( parameter1 "." "P10") + when(((INST->name==paraP1) || (INST->name==paraP2) || (INST->name==paraP3) || (INST->name==paraP4) || (INST->name==paraP5) || (INST->name==paraP6) || (INST->name==paraP7) || (INST->name==paraP8) || (INST->name==paraP9) || (INST->name==paraP10) ) + P=evalstring(parameter4) + Pparam=P/2000000 + dbReplaceProp(INST "PW1" "float" Pparam) + )) + ))) + + foreach(INST CellView->instances + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.3.P1")) + cordx=caadr(INST~>bBox) + cordx1=cordx-0.02 + cordx2=cordx1+0.06) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.P1")) + cordP2x=caadr(INST~>bBox) + cordP2x1=cordP2x-0.02) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.1.P1")) + cordP1x=caadr(INST~>bBox) + cordP1x1=cordP1x-0.02) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.0.P1")) + cordP0x=caadr(INST~>bBox) + cordP0x1=cordP0x-0.02) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.3.N1")) + cordNx=caar(INST~>bBox) + cordNx1=cordNx+0.02 + cordNx2=cordNx1-0.06) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.2.N1")) + cordN2x=caar(INST~>bBox) + cordN2x1=cordN2x+0.02) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.1.N1")) + cordN1x=caar(INST~>bBox) + cordN1x1=cordN1x+0.02) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.0.N1")) + cordN0x=caar(INST~>bBox) + cordN0x1=cordN0x+0.02) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e")) + cordLx=caar(INST~>bBox) + cordLx1=cordLx+0.04 + cordLx2=cordLx1+0.06) + when(((INST->cellName=="stack.NMOS_CHAIN_5.0-L1-R") && (INST->name=="rv.N2")) + cordrvx=caar(INST~>bBox) + cordrvx2=caadr(INST~>bBox) + cordrv1=cordrvx+0.005 + cordrv2=cordrv1-0.06) + when((INST->cellName=="stack.PMOS_CHAIN_1.0-L1-R") && (INST->name=="rv.P1") + cordrvPx=caar(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.2") + cordR2y2=cadadr(INST~>bBox) + cordR2x1=caar(INST~>bBox) + cordR2=caadr(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0") + cordR0y1=cadar(INST~>bBox) + cordR0x1=caar(INST~>bBox) + cordR0=caadr(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.3") + cordR3y2=cadadr(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1") + cordR1y1=cadar(INST~>bBox) + cordR1y2=cadadr(INST~>bBox) + cordRx1=caar(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e") + cordLey2=cadadr(INST~>bBox) + cordLe=caadr(INST~>bBox)) + ) + + foreach(INST CellView->instances + (let ( xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->name=="PD3") || (INST->name=="PU3") || (INST->name=="PD2") || (INST->name=="PU2") || (INST->name=="PD1") || (INST->name=="PU1") || (INST->name=="PD0") || (INST->name=="PU0")) + XY=(cordx2+0.1:xy2) + dbSet(INST XY "xy")) ; moves M1_poly vias + when((INST->cellName=="gate.INV.0-L1_1-R") &&((INST->name=="R.3")||(INST->name=="R.1")) + when(cordR1y2==11.4 + when((R3NWidth/3)>=0.46 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when((R3NWidth/3)<0.46 + dbReplaceProp(INST "n_contact_offset" "float" (0.76-0.04-(R3NWidth/3)-0.2)))) + when(cordR1y2==11.27 + when((R3NWidth/2)>=0.46 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when((R3NWidth/2)<0.46 + dbReplaceProp(INST "n_contact_offset" "float" (0.76-0.04-(R3NWidth/2)-0.2)))) + when(cordR1y2==11.14 + when(R3NWidth>=0.46 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(R3NWidth<0.46 + dbReplaceProp(INST "n_contact_offset" "float" (0.76-0.04-R3NWidth-0.2)))) + ActualcordRx1=caar(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R") &&((INST->name=="R.2")||(INST->name=="R.0")) + when(cordR2y2==9.84 + when((R2PWidth/3)>=0.27 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R2PWidth/3)<0.27 + dbReplaceProp(INST "p_contact_offset" "float" (1.29-0.76-(R2PWidth/3)-0.2)))) + when(cordR2y2==9.71 + when((R2PWidth/2)>=0.27 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R2PWidth/2)<0.27 + dbReplaceProp(INST "p_contact_offset" "float" (1.29-0.76-(R2PWidth/2)-0.2)))) + when(cordR2y2==9.58 + when(R2PWidth>=0.27 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when(R2PWidth<0.27 + dbReplaceProp(INST "p_contact_offset" "float" (1.29-0.76-R2PWidth-0.2)))) + ActualcordRx0=caadr(INST~>bBox)) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset") + when(ResPWidth>=0.27 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when(ResPWidth<0.27 + dbReplaceProp(INST "p_contact_offset" "float" (0.54-ResPWidth-0.2))) + ActualReset=caadr(INST~>bBox)) + when(((INST->name=="ND3") || (INST->name=="NU3") || (INST->name=="ND2") || (INST->name=="NU2") || (INST->name=="ND1") || (INST->name=="NU1") || (INST->name=="ND0") || (INST->name=="NU0") || (INST->name=="R3") || (INST->name=="R2") || (INST->name=="R1") || (INST->name=="R0")) + XY=(cordNx2-0.1:xy2) + ActualPolyLeft=cordNx2-0.1 + dbSet(INST XY "xy")) ; moves M1_poly vias + )) + + foreach(INST CellView->instances + (let ( xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="_Reset") + when(ResetNWidth<0.27 + dbReplaceProp(INST "n_contact_offset" "float" (0.76-0.22-ResetNWidth-0.2))) + when(ResetNWidth>0.27 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + ActualResx=caar(INST~>bBox)) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.505&&xy2==4.16)||(xy1==1.015&&xy2==4.16)) + when((cordLey2==3.99)||(cordLey2==3.86)||(cordLey2==4.12) + dbDeleteObject(INST))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.505&&xy2==3.9)||(xy1==1.015&&xy2==3.9)) + when(cordLey2==3.86 + dbDeleteObject(INST))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.505&&xy2==11.18)||(xy1==1.015&&xy2==11.18)) + when(cordR3y2==11.14 + dbDeleteObject(INST))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.505&&xy2==9.62)||(xy1==1.015&&xy2==9.62)) + when(cordR2y2==9.58 + dbDeleteObject(INST))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.505&&xy2==2.73)||(xy1==1.015&&xy2==2.73)) + when(cordR1y1==2.77 + dbDeleteObject(INST))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.505&&xy2==1.3)||(xy1==1.015&&xy2==1.3)) + when(cordR0y1==1.34 + dbDeleteObject(INST))) + )) +;moving wires as per the new widths of instances + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="CO")&&((bx1==0.94&&by1==1.8)||(bx1==1.05&&by1==1.8)||(bx1==0.94&&by1==2.06)||(bx1==1.05&&by1==2.06)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.91:by1-0.01 cordP1x1-0.07:by2+0.01)) + when((bx1==0.94&&by1==1.8)||(bx1==0.94&&by1==2.06) + i = 0.94 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i+0.04:by2)) + when((i+0.15)>(cordP1x1-0.07) + k=20 + i = 0.94) + when((i+0.15)<=(cordP1x1-0.07) + k = k+1 + i = i + 0.11)))) ; draws CO's for r.1 C2 gates on PMOS side + when((SHAPE~>layerName=="CO")&&((bx1==0.94&&by1==12.07)||(bx1==1.05&&by1==12.07)||(bx1==0.94&&by1==11.81)||(bx1==1.05&&by1==11.81)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.91:by1-0.01 cordx1-0.07:by2+0.01)) + when((bx1==0.94&&by1==12.07)||(bx1==0.94&&by1==11.81) + i = 0.94 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i+0.04:by2)) + when((i+0.15)>(cordP1x1-0.07) + k=20 + i = 0.94) + when((i+0.15)<=(cordP1x1-0.07) + k = k+1 + i = i + 0.11)))); draws CO's for r.3 C2 gates on PMOS side + when((SHAPE~>layerName=="CO")&&((bx1==0.94&&by1==10.38)||(bx1==1.05&&by1==10.38)||(bx1==0.94&&by1==10.64)||(bx1==1.05&&by1==10.64)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.91:by1-0.01 cordP2x1-0.2:by2+0.01)) + when((bx1==0.94&&by1==10.38)||(bx1==0.94&&by1==10.64) + i = 0.94 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i+0.04:by2)) + when((i+0.15)>(cordP2x1-0.23) + k=20 + i = 0.94) + when((i+0.15)<=(cordP2x1-0.23) + k = k+1 + i = i + 0.11)))); draws CO's for r.2 C2 gates on PMOS side + when((SHAPE~>layerName=="CO")&&((bx1==0.94&&by1==0.37)||(bx1==1.05&&by1==0.37)||(bx1==0.94&&by1==0.63)||(bx1==1.05&&by1==0.63)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.91:by1-0.01 cordP0x1-0.2:by2+0.01)) + when((bx1==0.94&&by1==0.37)||(bx1==0.94&&by1==0.63) + i = 0.94 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i+0.04:by2)) + when((i+0.15)>(cordP0x1-0.23) + k=20 + i = 0.94) + when((i+0.15)<=(cordP0x1-0.23) + k = k+1 + i = i + 0.11)))); draws CO's for r.0 C2 gates on PMOS side + when((SHAPE~>layerName=="CO")&&((bx1==0.53&&by1==12.07)||(bx1==0.53&&by1==11.81)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.61:by1-0.01 cordNx1+0.07:by2+0.01)) + i = 0.57 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i-0.04:by2)) + when((i-0.15)<(cordNx1+0.07) + k=20 + i = 0.57) + when((i-0.15)>=(cordNx1+0.07) + k = k+1 + i = i - 0.11))) ; draws CO's for r.3 C2 gates on NMOS side + when((SHAPE~>layerName=="CO")&&((bx1==0.53&&by1==10.64)||(bx1==0.53&&by1==10.38)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.61:by1-0.01 cordN2x1+0.07:by2+0.01)) + i = 0.57 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i-0.04:by2)) + when((i-0.15)<(cordN2x1+0.07) + k=20 + i = 0.57) + when((i-0.15)>=(cordN2x1+0.07) + k = k+1 + i = i - 0.11))) ; draws CO's for r.2 C2 gates on NMOS side + when((SHAPE~>layerName=="CO")&&((bx1==0.525&&by1==2.06)||(bx1==0.525&&by1==1.8)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.61:by1-0.01 cordN1x1+0.07:by2+0.01)) + i = 0.57 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i-0.04:by2)) + when((i-0.15)<(cordN1x1+0.07) + k=20 + i = 0.57) + when((i-0.15)>=(cordN1x1+0.07) + k = k+1 + i = i - 0.11))) ; draws CO's for r.1 C2 gates on NMOS side + when((SHAPE~>layerName=="CO")&&((bx1==0.525&&by1==0.63)||(bx1==0.525&&by1==0.37)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.61:by1-0.01 cordN0x1+0.07:by2+0.01)) + i = 0.57 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i-0.04:by2)) + when((i-0.15)<(cordN0x1+0.07) + k=20 + i = 0.57) + when((i-0.15)>=(cordN0x1+0.07) + k = k+1 + i = i - 0.11))) ; draws CO's for r.0 C2 gates on NMOS side + when( (SHAPE~>net~>name=="PU.3") || (SHAPE~>net~>name=="PU.2") || (SHAPE~>net~>name=="PD.1") || (SHAPE~>net~>name=="PD.0") + pnts=list(cordx2:y1 x2:y2 x3:y3 cordx1:y4 cordx1:y5 x6:y6 x7:y7 cordx2:y8) + dbSet(SHAPE pnts "points")) ;moves M1 nets on the NMOS side of Van Berkel gate + when((SHAPE~>net~>name=="R.e") && ((SHAPE~>layerName=="M1") || (SHAPE~>layerName=="M2") || (SHAPE~>layerName=="M3")|| (SHAPE~>layerName=="PO")) + when(SHAPE~>layerName=="M1" + bbox=list(cordx1+0.13:by1 cordx1+0.19:by2) + dbSet(SHAPE bbox "bBox")) ; Moves R.e M1 wires + when(SHAPE~>layerName=="M2" + bbox=list(cordx2+0.115:by1 cordx2+0.115:by2) + dbSet(SHAPE bbox "points")) ; moves R.e M2 wires + when(SHAPE~>layerName=="M3" + when((ActualcordRx0>=cordx2+0.17) + bbox=list(bx1:by1 ActualcordRx0:by2)) + when((ActualcordRx0layerName=="PO" + bbox=list(bx1:by1 cordx2+0.115:by2) + dbSet(SHAPE bbox "bBox")) ; Moves R.e Poly wires + + ) + + when((((SHAPE~>net~>name=="_r.2") || (SHAPE~>net~>name=="_r.2fix") || (SHAPE~>net~>name=="_r.1") || (SHAPE~>net~>name=="rv") || (SHAPE~>net~>name=="_r.3poly") || (SHAPE~>net~>name=="_r.2mov") || (SHAPE~>net~>name=="_r.0") || (SHAPE~>net~>name=="_r.3") || (SHAPE~>net~>name=="_Reset") || (SHAPE~>net~>name=="Reset") || (SHAPE~>net~>name=="_Resetfix") || (SHAPE~>net~>name=="_r.0fix") || (SHAPE~>net~>name=="_r.0mov") || (SHAPE~>net~>name=="_r.1mov")) && ((SHAPE~>layerName=="M1") || (SHAPE~>layerName=="M2") || (SHAPE~>layerName=="CO") || (SHAPE~>layerName=="PO"))) + when((SHAPE~>layerName=="CO") && (SHAPE~>net~>name=="_Reset") + bbox=list((cordx2+0.08):by1 (cordx2+0.12):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO") && (SHAPE~>net~>name=="_Reset") + bbox=list(bx1:by1 (cordx2+0.17):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="CO") && (SHAPE~>net~>name=="_r.2") + bbox=list((cordx2-0.04):by1 cordx2:by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="CO") && (SHAPE~>net~>name=="_r.1") + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.05):by1 (cordrv1-0.01):by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.29:by1 0.33:by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="CO") && (SHAPE~>net~>name=="_r.3") + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.18):by1 (cordrv1-0.14):by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.16:by1 0.2:by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO") && (SHAPE~>net~>name=="_r.2") + bbox=list(bx1:by1 (cordx2+0.055):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO") && (SHAPE~>net~>name=="_r.1") + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.1):by1 bx2:by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.24:by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO") && (SHAPE~>net~>name=="_r.3") + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.23):by1 bx2:by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.11:by1 bx2:by2)) + ActualrvLeft=caar(bbox) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="CO") && (SHAPE~>net~>name=="_r.0") + bbox=list((cordx2-0.16):by1 (cordx2-0.12):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO") && (SHAPE~>net~>name=="_r.0") + bbox=list(bx1:by1 (cordx2-0.065):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M2") && (SHAPE~>net~>name=="_r.2") + bbox=list((cordx2-0.145):by1 (cordx2-0.145):by2) + dbSet(SHAPE bbox "points")) + when((SHAPE~>layerName=="M2") && (SHAPE~>net~>name=="_Reset") + bbox=list((cordx2-0.015):by1 (cordx2-0.015):by2) + dbSet(SHAPE bbox "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="rv") + pnts=list(x1:y1 cordLx1:y2 cordLx1:y3 cordLx2:y4 cordLx2:y5 x6:y6) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2") && (SHAPE~>net~>name=="_r.0") + bbox=list((cordx2-0.145):by1 (cordx2-0.145):by2) + dbSet(SHAPE bbox "points")) + when((SHAPE~>layerName=="M1") && ((SHAPE~>net~>name=="_r.0")||(SHAPE~>net~>name=="_r.2")) + bbox=list(bx1:by1 (cordx2-0.145):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_Resetfix") + pnts=list((cordx2+0.155):y1 (cordx2+0.13):y2 (cordx2+0.13):y3 (cordx2+0.07):y4 (cordx2+0.07):y5 (cordx2-0.015):y6 (cordx2-0.015):y7 (cordx2+0.155):y8) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.2fix") + pnts=list((cordx2+0.02):y1 (cordx2-0.145):y2 (cordx2-0.145):y3 (cordx2-0.05):y4 (cordx2-0.05):y5 (cordx2+0.01):y6 (cordx2+0.01):y7 (cordx2+0.02):y8) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.0fix") + pnts=list((cordx2-0.09):y1 (cordx2-0.11):y2 (cordx2-0.11):y3 (cordx2-0.17):y4 (cordx2-0.17):y5 (cordx2-0.2):y6 (cordx2-0.2):y7 (cordx2-0.09):y8) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_Reset") + pnts=list(x1:y1 (cordx2-0.015):y2 (cordx2-0.015):y3) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.2mov") + when((ActualcordRx0-0.11)>=(cordx2-0.145) + pnts=list((ActualcordRx0-0.04):y1 (cordx2-0.145):y2 (cordx2-0.145):y3 (ActualcordRx0-0.11):y4 (ActualcordRx0-0.11):y5 (cordx2-0.145):y6 (cordx2-0.145):y7 (ActualcordRx0-0.04):y8)) + when((ActualcordRx0-0.11)<(cordx2-0.145) + pnts=list((ActualcordRx0-0.11):y1 (cordx2-0.145):y2 (cordx2-0.145):y3 (ActualcordRx0-0.04):y4 (ActualcordRx0-0.04):y5 (cordx2-0.145):y6 (cordx2-0.145):y7 (ActualcordRx0-0.11):y8)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.1") + when((cordrv1-0.01<=0.33) + pnts=list(x1:y1 cordrv1:y2 cordrv1:y3 cordrv2:y4 cordrv2:y5 cordrv1:y6 cordrv1:y7 x8:y8)) + when((cordrv1-0.01>0.33) + pnts=list(x1:y1 0.34:y2 0.34:y3 0.28:y4 0.28:y5 0.34:y6 0.34:y7 x8:y8)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.3poly") + when((cordrv1-0.01<=0.33) + pnts=list(x1:y1 (cordrv2-0.07):y2 (cordrv2-0.07):y3 (cordrv2-0.13):y4 (cordrv2-0.13):y5 (cordrv2-0.07):y6 (cordrv2-0.07):y7 x8:y8)) + when((cordrv1-0.01>0.33) + pnts=list(x1:y1 0.21:y2 0.21:y3 0.15:y4 0.15:y5 0.21:y6 0.21:y7 x8:y8)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.0mov") + when((ActualcordRx0-0.11)>=(cordx2-0.145) + pnts=list(ActualcordRx0-0.05:y1 (ActualcordRx0-0.11):y2 (ActualcordRx0-0.11):y3 (cordx2-0.145):y4 (cordx2-0.145):y5 (ActualcordRx0-0.05):y6 )) + when((ActualcordRx0-0.11)<(cordx2-0.145) + pnts=list(ActualcordRx0-0.05:y1 (ActualcordRx0-0.11):y2 (ActualcordRx0-0.11):y5 (cordx2-0.145):y6 (cordx2-0.145):y4 (ActualcordRx0-0.05):y3 )) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.1mov") + pnts=list(x1:y1 (ActualcordRx1+0.04):y2 (ActualcordRx1+0.04):y3 (ActualcordRx1+0.1):y4 (ActualcordRx1+0.1):y5 x6:y6) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="Reset") + pnts=list(x1:y1 (ActualResx+0.03):y2 (ActualResx+0.03):y3 (ActualResx+0.09):y4 (ActualResx+0.09):y5 x6:y6) + dbSet(SHAPE pnts "points")) + ) + when((SHAPE~>net~>name=="_RESET") && (SHAPE~>layerName=="M1") + when(cordLey2==4.51 + when((LePWidth/6)>=0.27 + pnts=list(x1:y1 (cordLe+0.02):y2 (cordLe+0.02):y3 ActualReset-0.07:y4)) + when((LePWidth/6)<0.27 + pnts=list(x1:y1 1.21:y2 1.21:y3 ActualReset-0.07:y4))) + when(cordLey2==4.38 + when((LePWidth/5)>=0.27 + pnts=list(x1:y1 (cordLe+0.02):y2 (cordLe+0.02):y3 ActualReset-0.07:y4)) + when((LePWidth/5)<0.27 + pnts=list(x1:y1 1.21:y2 1.21:y3 ActualReset-0.07:y4))) + when(cordLey2==4.25 + when((LePWidth/4)>=0.27 + pnts=list(x1:y1 (cordLe+0.02):y2 (cordLe+0.02):y3 ActualReset-0.07:y4)) + when((LePWidth/4)<0.27 + pnts=list(x1:y1 1.21:y2 1.21:y3 ActualReset-0.07:y4))) + when(cordLey2==4.12 + when((LePWidth/3)>=0.27 + pnts=list(x1:y1 (cordLe+0.02):y2 (cordLe+0.02):y3 ActualReset-0.07:y4)) + when((LePWidth/3)<0.27 + pnts=list(x1:y1 1.21:y2 1.21:y3 ActualReset-0.07:y4))) + when(cordLey2==3.99 + when((LePWidth/2)>=0.27 + pnts=list(x1:y1 (cordLe+0.02):y2 (cordLe+0.02):y3 ActualReset-0.07:y4)) + when((LePWidth/2)<0.27 + pnts=list(x1:y1 1.21:y2 1.21:y3 ActualReset-0.07:y4))) + when(cordLey2==3.86 + when(LePWidth>=0.27 + pnts=list(x1:y1 (cordLe+0.02):y2 (cordLe+0.02):y3 ActualReset-0.07:y4)) + when(LePWidth<0.27 + pnts=list(x1:y1 1.21:y2 1.21:y3 ActualReset-0.07:y4))) + dbSet(SHAPE pnts "points")) + when(SHAPE~>net~>name=="NU.3" + pnts=list(x1:y1 cordNx2:y2 cordNx2:y3 x4:y4 x5:y5 cordNx1:y6 cordNx1:y7 x8:y8) + dbSet(SHAPE pnts "points")) + when(SHAPE~>net~>name=="NU.2" + pnts=list(x1:y1 cordNx1-0.03:y2 cordNx1-0.03:y3 x4:y4 ) + dbSet(SHAPE pnts "points")) + when(SHAPE~>net~>name=="ND.1" + pnts=list(x1:y1 cordNx1:y2 cordNx1:y3 x4:y4 x5:y5 cordNx2:y6 cordNx2:y7 x8:y8) + dbSet(SHAPE pnts "points")) + when(SHAPE~>net~>name=="ND.0" + pnts=list(x1:y1 cordNx1-0.03:y2 cordNx1-0.03:y3 x4:y4) + dbSet(SHAPE pnts "points")) ;moves M1 nets on the PMOS side of the Van Berkel gate + when((SHAPE~>layerName=="M3") && SHAPE~>net~>name=="_RESET" + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1:by1 ActualcordRx0:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1:by1 (cordx2+0.17):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 ActualcordRx0:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 (cordx2+0.17):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1:by1 ActualcordRx0:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1:by1 (cordx2+0.17):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 ActualcordRx0:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 (cordx2+0.17):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0layerName=="M3") && SHAPE~>net~>name=="L.e" + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.23):by1 bx2:by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.11:by1 bx2:by2)) + ActualrvLeft=caar(bbox) + when(ActualcordRx1>=(cordNx2-0.03)&&(ActualcordRx1<=ActualrvLeft) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=cordx2+0.17) + bbox=list(ActualrvLeft:by1 bx2:by2)) + when((ActualcordRx0net~>name=="L.3") || (SHAPE~>net~>name=="L.2") || (SHAPE~>net~>name=="L.1") || (SHAPE~>net~>name=="L.0")|| (SHAPE~>net~>name=="R.3") || (SHAPE~>net~>name=="R.2") || (SHAPE~>net~>name=="R.1") || (SHAPE~>net~>name=="R.0")) && ((SHAPE~>layerName=="M1") || (SHAPE~>layerName=="M2") || (SHAPE~>layerName=="M3")|| (SHAPE~>layerName=="PO")) + when((SHAPE~>layerName=="M1") && ((SHAPE~>net~>name=="L.3") || (SHAPE~>net~>name=="L.2") || (SHAPE~>net~>name=="L.1") || (SHAPE~>net~>name=="L.0")) + bbox=list(cordNx1-0.13:by1 cordNx1-0.19:by2) + dbSet(SHAPE bbox "bBox")) ; Moves R.e M1 wires + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="R.3") + when((cordRx1+0.505)>=(cordNx2+0.13) + pnts=list(x1:y1 (cordNx1-0.12):y2 (cordNx1-0.12):y3 (cordNx1-0.18):y4 (cordNx1-0.18):y5 x6:y6 x7:y7 x8:y8)) + when((cordRx1+0.505)<(cordNx2+0.13) + pnts=list(x1:y1 (cordNx1-0.12):y2 (cordNx1-0.12):y3 (cordNx1-0.18):y4 (cordNx1-0.18):y5 x6:y6 x7:y7 x8:y8)) + dbSet(SHAPE pnts "points")) ; Moves R.e M1 wires + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="R.1") + pnts=list(x1:y1 x2:y2 x3:y3 (cordNx1-0.18):y4 (cordNx1-0.18):y5 (cordNx1-0.12):y6 (cordNx1-0.12):y7 x8:y8) + dbSet(SHAPE pnts "points")) ; Moves R.e M1 wires + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="R.2") + when((cordNx1-0.12)<=cordR2x1-0.01 + pnts=list(x1:y1 (cordNx1-0.12):y2 (cordNx1-0.12):y3 (cordNx1-0.17):y4)) + when((cordNx1-0.12)>cordR2x1-0.01 + pnts=list(x1:y1 (cordR2x1-0.01):y2 (cordR2x1-0.01):y3 ActualPolyLeft:y4)) + dbSet(SHAPE pnts "points")) ; Moves R.e M1 wires + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="R.0") + when((cordNx1-0.12)<=cordR0x1-0.01 + pnts=list(x1:y1 (cordNx1-0.12):y2 (cordNx1-0.12):y3 (cordNx1-0.17):y4)) + when((cordNx1-0.12)>cordR0x1-0.01 + pnts=list(x1:y1 (cordR0x1-0.01):y2 (cordR0x1-0.01):y3 ActualPolyLeft:y4)) + dbSet(SHAPE pnts "points")) ; Moves R.e M1 wires + when((SHAPE~>layerName=="M3") && ((SHAPE~>net~>name=="L.3") || (SHAPE~>net~>name=="L.2") || (SHAPE~>net~>name=="L.1") || (SHAPE~>net~>name=="L.0")) + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.23):by1 bx2:by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.11:by1 bx2:by2)) + ActualrvLeft=caar(bbox) + when(ActualcordRx1>=(cordNx2-0.03)&&(ActualcordRx1<=ActualrvLeft) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.17:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=cordx2+0.17) + bbox=list(ActualrvLeft:by1 bx2:by2)) + when((ActualcordRx0layerName=="M3") && ((SHAPE~>net~>name=="R.3") || (SHAPE~>net~>name=="R.2") || (SHAPE~>net~>name=="R.1") || (SHAPE~>net~>name=="R.0")) + when((ActualcordRx0>=cordx2+0.17) + bbox=list(bx1:by1 ActualcordRx0:by2)) + when((ActualcordRx0layerName=="M2") && ((SHAPE~>net~>name=="L.3") || (SHAPE~>net~>name=="L.2") || (SHAPE~>net~>name=="L.1") || (SHAPE~>net~>name=="L.0")) + bbox=list(cordNx2-0.115:by1 cordNx2-0.115:by2) + dbSet(SHAPE bbox "points")) ; moves R.e M2 wires + when(SHAPE~>layerName=="PO" + bbox=list(cordNx2-0.115:by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) ; Moves R.e Poly wires + ) + when(((SHAPE~>net~>name=="_r.3") || (SHAPE~>net~>name=="_r.3mov"))&&((SHAPE~>layerName=="M1") || (SHAPE~>layerName=="M2")) + when(SHAPE~>layerName=="M2" + when(ActualcordRx1>=(cordNx2-0.03) + bbox=list((cordNx2+0.015):by1 (cordNx2+0.015):by2)) + when(ActualcordRx1<(cordNx2-0.03) + bbox=list((cordNx2-0.245):by1 (cordNx2-0.245):by2)) + dbSet(SHAPE bbox "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.3") + when(ActualcordRx1>=(cordNx2-0.03) + pnts=list(x1:y1 (cordNx2+0.015):y2 (cordNx2+0.015):y3 x4:y4 x5:y5 x6:y6)) + when(ActualcordRx1<(cordNx2-0.03) + pnts=list(x1:y1 (cordNx2-0.245):y2 (cordNx2-0.245):y3 x4:y4 x5:y5 x6:y6)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1") && (SHAPE~>net~>name=="_r.3mov") + when(ActualcordRx1>=(cordNx2-0.03) + bbox=list(ActualcordRx1+0.03:by1 (cordNx2+0.015):by2)) + when(ActualcordRx1<(cordNx2-0.03) + bbox=list(ActualcordRx1+0.03:by1 (cordNx2-0.245):by2)) + dbSet(SHAPE bbox "bBox"))) ; moves R.e M2 wires + when((SHAPE~>layerName=="prBoundary") + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.23):by1 bx2:by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.11:by1 bx2:by2)) + ActualrvLeft=caar(bbox) + dbDeleteObject(SHAPE)) + when((SHAPE~>layerName=="M3")&&((bx1==0&&by1==12.385)||(bx1==0&&by1==10.945)||(bx1==0&&by1==10.825)||(bx1==0&&by1==9.385)||(bx1==0&&by1==9.265)||(bx1==0&&by1==7.825)||(bx1==0&&by1==7.705)||(bx1==0&&by1==6.265)||(bx1==0&&by1==6.145)||(bx1==0&&by1==4.705)||(bx1==0&&by1==4.585)||(bx1==0&&by1==3.145)||(bx1==0&&by1==3.025)||(bx1==0&&by1==1.585)||(bx1==0&&by1==1.465)||(bx1==0&&by1==0.025)) + when((cordrv1-0.01<=0.33) + bbox=list((cordrv1-0.23):by1 bx2:by2)) + when((cordrv1-0.01>0.33) + bbox=list(0.11:by1 bx2:by2)) + ActualrvLeft=caar(bbox) + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (cordx2+0.21):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordx2+0.21):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (cordx2+0.21):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordx2+0.21):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0=cordx2+0.17) + bbox=list(ActualrvLeft-0.04:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="PO")&&((bx1==0&&by1==0.05)||(bx1==0&&by1==0.18)||(bx1==0&&by1==0.31)||(bx1==0&&by1==0.44)||(bx1==0&&by1==0.57)||(bx1==0&&by1==0.7)||(bx1==0&&by1==0.83)||(bx1==0&&by1==0.96)||(bx1==0&&by1==1.09)||(bx1==0&&by1==1.35)||(bx1==0&&by1==1.48)||(bx1==0&&by1==1.61)||(bx1==0&&by1==1.74)||(bx1==0&&by1==1.87)||(bx1==0&&by1==2)||(bx1==0&&by1==2.13)||(bx1==0&&by1==2.26)||(bx1==0&&by1==2.39)||(bx1==0&&by1==2.52)||(bx1==0&&by1==2.65)||(bx1==0&&by1==2.78)||(bx1==0&&by1==2.91)||(bx1==0&&by1==3.04)||(bx1==0&&by1==3.17)||(bx1==0&&by1==3.3)||(bx1==0&&by1==3.43)||(bx1==0&&by1==3.56)||(bx1==0&&by1==3.69)||(bx1==0&&by1==3.82)||(bx1==0&&by1==3.95)||(bx1==0&&by1==4.08)||(bx1==0&&by1==4.21)||(bx1==0&&by1==4.34)||(bx1==0&&by1==4.47)||(bx1==0&&by1==4.6)||(bx1==0&&by1==4.99)||(bx1==0&&by1==5.12)||(bx1==0&&by1==5.51)||(bx1==0&&by1==5.64)||(bx1==0&&by1==5.77)||(bx1==0&&by1==5.9)||(bx1==0&&by1==6.03)||(bx1==0&&by1==6.16)||(bx1==0&&by1==6.29)||(bx1==0&&by1==6.42)||(bx1==0&&by1==6.55)||(bx1==0&&by1==6.68)||(bx1==0&&by1==6.81)||(bx1==0&&by1==6.94)||(bx1==0&&by1==7.07)||(bx1==0&&by1==7.2)||(bx1==0&&by1==7.33)||(bx1==0&&by1==7.46)||(bx1==0&&by1==7.59)||(bx1==0&&by1==7.72)||(bx1==0&&by1==7.85)||(bx1==0&&by1==7.98)||(bx1==0&&by1==8.11)||(bx1==0&&by1==8.24)||(bx1==0&&by1==8.37)||(bx1==0&&by1==8.5)||(bx1==0&&by1==8.63)||(bx1==0&&by1==8.76)||(bx1==0&&by1==8.89)||(bx1==0&&by1==9.02)||(bx1==0&&by1==9.15)||(bx1==0&&by1==9.28)||(bx1==0&&by1==9.41)||(bx1==0&&by1==9.54)||(bx1==0&&by1==9.67)||(bx1==0&&by1==9.8)||(bx1==0&&by1==9.93)||(bx1==0&&by1==10.06)||(bx1==0&&by1==10.19)||(bx1==0&&by1==10.32)||(bx1==0&&by1==10.45)||(bx1==0&&by1==10.58)||(bx1==0&&by1==10.71)||(bx1==0&&by1==10.84)||(bx1==0&&by1==10.97)||(bx1==0&&by1==11.1)||(bx1==0&&by1==11.23)||(bx1==0&&by1==11.36)||(bx1==0&&by1==11.49)||(bx1==0&&by1==11.62)||(bx1==0&&by1==11.75)||(bx1==0&&by1==11.88)||(bx1==0&&by1==12.01)||(bx1==0&&by1==12.14)||(bx1==0&&by1==12.27)||(bx1==0&&by1==12.4)) + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (cordx2+0.21):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordx2+0.21):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (cordx2+0.21):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordx2+0.21):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0layerName=="PO")&&bx1==0&&by2==12.48 + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 ActualcordRx1:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordNx2-0.17):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 ActualcordRx1:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordNx2-0.17):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055layerName=="PO")&&((bx1==0.485&&by1==4.86)||(bx1==0.485&&by1==4.73)) + bbox=list(bx1:by1 (ActualcordRx0+0.04):by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&((bx1==0&&by1==5.38)||(bx1==0&&by1==5.25)) + bbox=list(ActualcordRx1-0.04:by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&bx1==1.52&&by2==12.48 + when((ActualcordRx0>=cordx2+0.17) + bbox=list(ActualcordRx0:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="NP")&&((bx1==0&&by2==0.17)||(bx1==0&&by2==12.48)) + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (cordx2+0.21):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordx2+0.21):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 (cordx2+0.21):by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(ActualcordRx0cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0>=cordx2+0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(ActualcordRx0=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 (cordx2+0.21):by2)) + when((ActualcordRx1>cordNx2-0.17)&&(ActualcordRx0layerName=="NP")&&(by1==8.71&&by2==12.31) + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055layerName=="NP")&&(by1==7.15&&by2==8.71) + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 cordrvx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 cordrvx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 cordrvx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 cordrvx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055layerName=="NP")&&(by1==0.17&&by2==4.615) + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055layerName=="NW")||(SHAPE~>layerName=="PM"))&&(by1==8.71&&by2==12.35) + when((ActualcordRx0>=cordx2+0.17) + bbox=list(bx1:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="NW")||(SHAPE~>layerName=="PM"))&&(by1==7.15&&by2==8.71) + when((ActualcordRx0>=cordx2+0.17) + bbox=list(cordrvx2:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="NW")||(SHAPE~>layerName=="PM"))&&(by1==5.33&&by2==7.15) + when((ActualcordRx0>=cordx2+0.17) + bbox=list(cordrvPx:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="NW")||(SHAPE~>layerName=="PM"))&&(by1==0.13&&by2==5.33) + when((ActualcordRx0>=cordx2+0.17) + bbox=list(bx1:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="PP"&&by1==8.71&&by2==12.31 + when((ActualcordRx0>=cordx2+0.17) + bbox=list(bx1:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="PP"&&by1==7.15&&by2==8.71 + when((ActualcordRx0>=cordx2+0.17) + bbox=list(cordrvx2:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="PP"&&by1==0.17&&by2==4.93 + when((ActualcordRx0>=cordx2+0.17) + bbox=list(bx1:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="PP"&&by1==5.455&&by2==7.15 + when((ActualcordRx0>=cordx2+0.17) + bbox=list(cordrvPx:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="PP"&&bx1==1.25&&by1==4.93 + when((ActualcordRx0>=cordx2+0.17) + bbox=list(bx1:by1 (ActualcordRx0+0.04):by2)) + when((ActualcordRx0layerName=="PP"&&bx1==0.51&&by1==4.93 + pnts=list(x1:y1 cordrvPx:y2 cordrvPx:y3 x4:y4 x5:y5 x6:y6) + dbSet(SHAPE pnts "points")) + when(SHAPE~>layerName=="NP"&&by1==5.33&&by2==7.15 + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 cordrvPx:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 cordrvPx:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 cordrvPx:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 cordrvPx:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055layerName=="NP"&&bx1==0&&by1==4.615 + when(ActualcordRx1>=(cordNx2-0.03) + Actualcordr3x=cordNx2+0.015 + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055=ActualcordRx1) + bbox=list(ActualcordRx1-0.04:by1 bx2:by2)) + when((ActualcordRx1<=cordNx2-0.17)&&(Actualcordr3x-0.055cordNx2-0.17)&&(Actualcordr3x-0.055>=ActualcordRx1) + bbox=list(cordNx2-0.21:by1 bx2:by2)) + when((ActualcordRx1>cordNx2-0.17)&&(Actualcordr3x-0.055vias + (let (vx1 vy1 bx1 by1 bx2 by2 vx1 vy1 orgn) + bx1=caar(VIA~>bBox) + by1=cadar(VIA~>bBox) + bx2=caadr(VIA~>bBox) + by2=cadadr(VIA~>bBox) + vx1=car(VIA~>origin) + vy1=cadr(VIA~>origin) + when((VIA~>viaHeader~>viaDefName=="M2_M1") && (VIA~>net~>name=="_r.3") + when(ActualcordRx1>=(cordNx2-0.03) + orgn=((cordNx2+0.015):vy1)) + when(ActualcordRx1<(cordNx2-0.03) + orgn=((cordNx2-0.245):vy1)) + dbSet(VIA orgn "origin")) ; moves M2_M1 vias as per new spec + when(((VIA~>viaHeader~>viaDefName=="M2_M1") || (VIA~>viaHeader~>viaDefName=="M3_M2")) && ((VIA~>net~>name=="L.3") || (VIA~>net~>name=="L.2") || (VIA~>net~>name=="L.1") || (VIA~>net~>name=="L.0")) + orgn=(cordNx2-0.115:vy1) + dbSet(VIA orgn "origin")) ; moves M2_M1 vias as per new spec + when((VIA~>viaHeader~>viaDefName=="M2_M1") && (VIA~>net~>name=="_r.2") + orgn=((cordx2-0.145):vy1) + dbSet(VIA orgn "origin")) ; moves M2_M1 vias as per new spec + when((VIA~>viaHeader~>viaDefName=="M2_M1") && (VIA~>net~>name=="_Reset") + orgn=((cordx2-0.015):vy1) + dbSet(VIA orgn "origin")) ; moves M2_M1 vias as per new spec + when((VIA~>viaHeader~>viaDefName=="M2_M1") && (VIA~>net~>name=="_r.0") + orgn=((cordx2-0.145):vy1) + dbSet(VIA orgn "origin")) ; moves M2_M1 vias as per new spec + when(((VIA~>viaHeader~>viaDefName=="M2_M1") || (VIA~>viaHeader~>viaDefName=="M3_M2")) && (VIA~>net~>name=="R.e") + orgn=(cordx2+0.115:vy1) + dbSet(VIA orgn "origin")) ; moves M2_M1 vias as per new spec + when((VIA~>viaHeader~>viaDefName=="M2_M1") && (VIA~>net~>name=="L.e")&&vx1==0.825&&vy1==4.29 + when((cordLey2==4.25)||(cordLey2==4.12)||(cordLey2==3.99)||(cordLey2==3.86) + dbDeleteObject(VIA))) + when((VIA~>viaHeader~>viaDefName=="M2_M1") && (VIA~>net~>name=="L.e")&&vx1==0.825&&vy1==4.03 + when((cordLey2==3.99)||(cordLey2==3.86) + dbDeleteObject(VIA))) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==0.825)&&(vy1==1.17) + when(cordR0y1==1.34 + dbDeleteObject(VIA))) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==0.825)&&(vy1==9.75) + when(cordR2y2==9.58 + dbDeleteObject(VIA))) + )) + BufCreatePrBound(CellView) +)) + +(defun CopyBuffer_fullheight ( CellView ViewName LibName CellName ) + (let (xy1 xy2 XY bx1 bx2 by1 by2 buf rightcord RightCord pnts SHAPE) + + when(minusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0.0:0 "R0")) + when(plusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" LeftLeaf:0 "R0")) + when(LeftLeaf==0 + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0:0 "R0")) + foreach(INST CellView~>instances + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + XY=(-bx1:xy2) + dbSet(INST XY "xy")) + dbFlattenInst(buf 1) + rightcord=round(((RightLeaf/0.26)/0.5)*0.5+0.5) + RightCord=0.26*rightcord + pnts=list(0:by1 0:by2 RightCord:by2 RightCord:by1) + dbCreatePRBoundary(CellView pnts) + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="NP")&&((by2==4.615&&by1==0.17)||(by2==5.33&&by1==4.615)||(by2==7.15&&by1==5.33)||(by2==8.71&&by1==7.15)||(by2==12.31&&by1==8.71)) + bbox=list(0:by1 bx2:by2) + dbSet(SHAPE bbox "bBox"));moves the NP layer on the left side of the gate + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="NP"))&&by2==12.48&&by1==12.31 + bbox=list(0:by1 RightCord:by2+0.13) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on top + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="NP"))&&(by2==0.17&&by1==0) + bbox=list(0:by1-0.13 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on bottom + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="PM"))&&((by2==12.35&&by1==8.71)||(by2==8.71&&by1==7.15)||(by2==7.15&&by1==5.33)||(by2==5.33&&by1==0.13)) + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/PM layer on the right side of the leaf cell + when((SHAPE~>layerName=="PP")&&((by2==4.93&&by1==0.17)||(by2==5.455&&by1==4.93)||(by2==7.15&&by1==5.455)||(by2==8.71&&by1==7.15)||(by2==12.31&&by1==8.71)) + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the PP layer on the right side of the leaf cell + when((SHAPE~>layerName=="M3")&&((by2==0.095&&by1==0.025)||(by2==1.535&&by1==1.465)||(by2==1.655&&by1==1.585)||(by2==3.095&&by1==3.025)||(by2==3.215&&by1==3.145)||(by2==4.655&&by1==4.585)||(by2==4.775&&by1==4.705)||(by2==6.215&&by1==6.145)||(by2==6.335&&by1==6.265)||(by2==7.775&&by1==7.705)||(by2==7.895&&by1==7.825)||(by2==9.335&&by1==9.265)||(by2==9.455&&by1==9.385)||(by2==10.895&&by1==10.825)||(by2==11.015&&by1==10.945)||(by2==12.455&&by1==12.385)) + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 power grid(GND/Vdd) wires + when((SHAPE~>layerName=="M3")&&((bx1!=0.04&&by1==1.335&&by2==1.395)||(bx1!=0.04&&by1==2.895&&by2==2.955)||(bx1!=0.04&&by1==3.285&&by2==3.345)||(bx1!=0.04&&by1==9.135&&by2==9.195)||(bx1!=0.04&&by1==10.695&&by2==10.755)) + bbox=list(bx1:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 R.o/R.1/R.e pins on the left side of the leaf cell + when((SHAPE~>layerName=="M3")&&by2==6.465&&by1==6.405 + bbox=list(bx1:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 _RESET pin + )) + DeleteGridPoly(?CellView CellView) + DrawGridPoly(?CellView CellView) + ddDeleteObj(ddGetObj(LibName CellName "scratch")) + dbSave(CellView) + dbPurge(CellView) + ) +) + +(defun CopyBuffer_template ( CellView ViewName LibName CellName ) + (let (xy1 xy2 XY bx1 bx2 by1 by2 buf rightcord RightCord pnts SHAPE) + when(minusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0.0:0 "R0")) + when(plusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0:0 "R0")) + when(LeftLeaf==0 + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0:0 "R0")) + foreach(INST CellView~>instances + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + XY=(-bx1:xy2) + dbSet(INST XY "xy")) + dbFlattenInst(buf 1) + rightcord=round(((RightLeaf/0.26)/0.5)*0.5+0.5) + RightCord=0.26*rightcord + pnts=list(0:by1 0:by2 RightCord:by2 RightCord:by1) + dbCreatePRBoundary(CellView pnts) + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.NPLUG.0") + XY=(0.155:xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="stack.PPLUG.0") + XY=(RightCord-0.155:xy2) + dbSet(INST XY "xy")) + )) + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="NP")&&by2==6.07&&by1==0.17 + pnts=list(x1:y1 0:y2 0:y3 0.26:y4 0.26:y5 0:y6 0:y7 x8:y8) + dbSet(SHAPE pnts "points"));moves the NP layer on the left side of the gate + when((SHAPE~>layerName=="NP")&&by2==6.24&&by1==6.07 + bbox=list(0:by1 RightCord:by2+0.13) + dbCreateRect(CellView "NW" bbox) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on top + when((SHAPE~>layerName=="NP")&&(by2==0.17&&by1==0) + bbox=list(0:by1-0.13 RightCord:by2) + dbCreateRect(CellView "NW" bbox) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on bottom + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="PM"))&&by2==6.11&&by1==0.13 + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/PM layer on the right side of the leaf cell + when((SHAPE~>layerName=="PP")&&by2==6.07&&by1==0.17 + pnts=list(RightCord:y1 RightCord-0.26:y2 RightCord-0.26:y3 RightCord:y4 RightCord:y5 x6:y6 x7:y7 RightCord:y8) + dbSet(SHAPE pnts "points")) ; moves the PP layer on the right side of the leaf cell + when((SHAPE~>layerName=="M3")&&((by2==0.095&&by1==0.025)||(by2==1.535&&by1==1.465)||(by2==1.655&&by1==1.585)||(by2==3.095&&by1==3.025)||(by2==3.215&&by1==3.145)||(by2==4.655&&by1==4.585)||(by2==4.775&&by1==4.705)||(by2==6.215&&by1==6.145)) + bbox=list(0:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 power grid(GND/Vdd) wires + when((SHAPE~>layerName=="M3")&&((bx1!=0.04&&by1==0.295&&by2==0.355)||(bx1!=0.04&&by1==1.855&&by2==1.915)||(bx1!=0.04&&by1==2.895&&by2==2.955)||(bx1!=0.04&&by1==4.455&&by2==4.515)||(bx1!=0.04&&by1==5.035&&by2==4.975)) + bbox=list(bx1:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 R.o/R.1/R.e pins on the left side of the leaf cell + when((SHAPE~>layerName=="M3")&&by2==3.475&&by1==3.415 + bbox=list(0.04:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 _RESET pin + when((SHAPE~>layerName=="M1")&&by1==1.995&&by2==2.25 + pnts=list(x1:y1 RightCord-0.155:y2 RightCord-0.155:y3) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&by2==2.5&&by1==2.185 + pnts=list(x1:y1 0.155:y2 0.155:y3) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="PP")&&by2==2.38&&by1==1.855 + bbox=list(0:by1 0.05:by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="NP")&&by2==2.355&&by1==1.83 + bbox=list(RightCord-0.09:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) + )) + DeleteGridPoly(?CellView CellView) + DrawGridPoly(?CellView CellView) + ddDeleteObj(ddGetObj(LibName CellName "scratch")) + dbSave(CellView) + dbPurge(CellView) + ) +) + +(defun CopyBuffer_template1 ( CellView ViewName LibName CellName ) + (let (xy1 xy2 XY bx1 bx2 by1 by2 buf rightcord RightCord pnts SHAPE) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0:0 "R0") + foreach(INST CellView~>instances + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + XY=(-bx1:xy2) + dbSet(INST XY "xy")) + dbFlattenInst(buf 1) + rightcord=round(((RightLeaf/0.26)/0.5)*0.5+0.5) + RightCord=0.26*rightcord + pnts=list(0:by1 0:by2 RightCord:by2 RightCord:by1) + dbCreatePRBoundary(CellView pnts) + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.NPLUG.0")&&(xy2==3.38) + XY=(0.13:xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="stack.NPLUG.0")&&(xy2==2.335) + XY=(RightCord-0.16:xy2) + dbSet(INST XY "xy")) + )) + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="NP")&&by2==6.24&&by1==0 + pnts=list(x1:y1 0:y2 0:y3 0.235:y4 0.235:y5 0:y6 0:y7 x8:y8) + dbSet(SHAPE pnts "points"));moves the NP layer on the left side of the gate + when((SHAPE~>layerName=="NP")&&by2==6.24&&by1==6.07 + bbox=list(0:by1 RightCord:by2+0.13) + dbCreateRect(CellView "NW" bbox) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on top + when((SHAPE~>layerName=="NP")&&(by2==0.17&&by1==0) + bbox=list(0:by1-0.13 RightCord:by2) + dbCreateRect(CellView "NW" bbox) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on bottom + when((SHAPE~>layerName=="NP")&&by2==6.24&&by1==2.99 + pnts=list(RightCord:y1 x2:y2 x3:y3 x4:y4 x5:y5 RightCord:y6) + dbSet(SHAPE pnts "points")) ; moves the NP layer on the right side of the leaf cell + when((SHAPE~>layerName=="NP")&&by2==2.99&&by1==0 + pnts=list(RightCord:y1 RightCord-0.265:y2 RightCord-0.265:y3 RightCord:y4 RightCord:y5 x6:y6 x7:y7 RightCord:y8) + dbSet(SHAPE pnts "points")) ; moves the NP layer on the right side of the leaf cell + when((SHAPE~>layerName=="M3")&&((by2==0.095&&by1==0.025)||(by2==1.535&&by1==1.465)||(by2==1.655&&by1==1.585)||(by2==3.095&&by1==3.025)||(by2==3.215&&by1==3.145)||(by2==4.655&&by1==4.585)||(by2==4.775&&by1==4.705)||(by2==6.215&&by1==6.145)) + bbox=list(0:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 power grid(GND/Vdd) wires + when((SHAPE~>layerName=="M3")&&((bx1!=0.04&&by1==0.295&&by2==0.355)||(bx1!=0.04&&by1==1.855&&by2==1.915)||(bx1!=0.04&&by1==2.895&&by2==2.955)||(bx1!=0.04&&by1==4.455&&by2==4.515)||(bx1!=0.04&&by1==5.035&&by2==4.975)) + bbox=list(bx1:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 R.o/R.1/R.e pins on the left side of the leaf cell + when((SHAPE~>layerName=="M3")&&by2==3.475&&by1==3.415 + bbox=list(0.04:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 _RESET pin + when((SHAPE~>layerName=="M1")&&by2==2.5&&by1==2.305 + pnts=list(x1:y1 RightCord-0.16:y2 RightCord-0.16:y3) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="PP")&&by2==3.905&&by1==3.38 + bbox=list(0:by1 0.08:by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PP")&&by1==2.335&&by2==2.86 + bbox=list(RightCord-0.055:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) + )) + DeleteGridPoly(?CellView CellView) + DrawGridPoly(?CellView CellView) + ddDeleteObj(ddGetObj(LibName CellName "scratch")) + dbSave(CellView) + dbPurge(CellView) + ) +) + +(defun CopyBuffer_template2 ( CellView ViewName LibName CellName ) + (let (xy1 xy2 XY bx1 bx2 by1 by2 buf rightcord RightCord pnts SHAPE) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0:0 "R0") + foreach(INST CellView~>instances + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + XY=(-bx1:xy2) + dbSet(INST XY "xy")) + dbFlattenInst(buf 1) + rightcord=round(((RightLeaf/0.26)/0.5)*0.5+0.5) + RightCord=0.26*rightcord + pnts=list(0:by1 0:by2 RightCord:by2 RightCord:by1) + dbCreatePRBoundary(CellView pnts) + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.NPLUG.0")&&(xy2==3.12) + XY=(0.13:xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="stack.NPLUG.0")&&(xy2==2.865) + XY=(RightCord-0.13:xy2) + dbSet(INST XY "xy")) + )) + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="NP")&&by2==6.24&&by1==0 + pnts=list(x1:y1 0:y2 0:y3 0.235:y4 0.235:y5 0:y6 0:y7 x8:y8) + dbSet(SHAPE pnts "points"));moves the NP layer on the left side of the gate + when((SHAPE~>layerName=="NP")&&by2==6.24&&by1==6.07 + bbox=list(0:by1 RightCord:by2+0.13) + dbCreateRect(CellView "NW" bbox) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on top + when((SHAPE~>layerName=="NP")&&(by2==0.17&&by1==0) + bbox=list(0:by1-0.13 RightCord:by2) + dbCreateRect(CellView "NW" bbox) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on bottom + when((SHAPE~>layerName=="NP")&&by2==6.24&&by1==2.34 + pnts=list(RightCord-0.235:y1 RightCord-0.235:y2 RightCord:y3 RightCord:y4 x5:y5 x6:y6) + dbSet(SHAPE pnts "points")) ; moves the NP layer on the right side of the leaf cell + when((SHAPE~>layerName=="NP")&&by2==2.34&&by1==0 + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NP layer on the right side of the leaf cell + when((SHAPE~>layerName=="M3")&&((by2==0.095&&by1==0.025)||(by2==1.535&&by1==1.465)||(by2==1.655&&by1==1.585)||(by2==3.095&&by1==3.025)||(by2==3.215&&by1==3.145)||(by2==4.655&&by1==4.585)||(by2==4.775&&by1==4.705)||(by2==6.215&&by1==6.145)) + bbox=list(0:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 power grid(GND/Vdd) wires + when((SHAPE~>layerName=="M3")&&((bx1!=0.04&&by1==0.295&&by2==0.355)||(bx1!=0.04&&by1==1.855&&by2==1.915)||(bx1!=0.04&&by1==2.895&&by2==2.955)||(bx1!=0.04&&by1==4.455&&by2==4.515)||(bx1!=0.04&&by1==5.035&&by2==4.975)) + bbox=list(bx1:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 R.o/R.1/R.e pins on the left side of the leaf cell + when((SHAPE~>layerName=="M3")&&by2==3.475&&by1==3.415 + bbox=list(0.04:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 _RESET pin + when((SHAPE~>layerName=="M1")&&by2==2.76&&by1==2.44 + pnts=list(x1:y1 RightCord-0.13:y2 RightCord-0.13:y3) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="PP")&&by2==3.645&&by1==3.12 + bbox=list(0:by1 0.08:by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PP")&&by1==2.34&&by2==2.865 + bbox=list(RightCord-0.08:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) + )) + DeleteGridPoly(?CellView CellView) + DrawGridPoly(?CellView CellView) + ddDeleteObj(ddGetObj(LibName CellName "scratch")) + dbSave(CellView) + dbPurge(CellView) + ) +) + + +(defun BufferCreator ( CellName ViewName ) + let( ( k l m n y s z ce cel piecess piecesss cv ncv mcv lcv vcv TemplateCellName pieces LibName Temp LeftLeaf RightLeaf chk) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + chk=nth( 3 pieces ) + k="0" + l="0" + m="0" + n="0" + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + when(chk=="BUF_1of4" + TemplateCellName = "lib.buffer.half.Template_BUF_1of4.buftemplate" + Temp = "Template3") + when(chk=="BUF_H_1of4" + TemplateCellName = "lib.buffer.half.Template_BUF_1of4.buftemplate" + Temp = Template()) +; Temp = "Template2" + + when(Temp=="Template" + mcv=nrOpenCellViewReadable( LibName TemplateCellName "template") + + when( cv != nil + printf( "Buffer type already exists %s\n" CellName) + ) + when( mcv == nil + printf("Template Cell doesnot exists %s\n" TemplateCellName)) + when( ((cv == nil)&&(mcv != nil)) + printf("yes\n") + dbCopyCellView(mcv LibName CellName "scratch" nil nil t) + ncv = nrOpenCellViewWritable( LibName CellName "scratch" ) + MakeBuffer1( ncv ViewName) + dbSave(ncv) + dbPurge(ncv) + lcv = nrOpenCellViewWritable( LibName CellName ViewName ) + CopyBuffer_template( lcv ViewName LibName CellName )) + ) + + when(Temp=="Template1" + printf("Template1\n") + mcv=nrOpenCellViewReadable( LibName TemplateCellName "template1") + + when( cv != nil + printf( "Buffer type already exists %s\n" CellName) + ) + when( mcv == nil + printf("Template Cell doesnot exists %s\n" TemplateCellName)) + when( ((cv == nil)&&(mcv != nil)) + printf("yes\n") + dbCopyCellView(mcv LibName CellName "scratch" nil nil t) + ncv = nrOpenCellViewWritable( LibName CellName "scratch" ) + MakeBuffer( ncv ViewName) + dbSave(ncv) + dbPurge(ncv) + lcv = nrOpenCellViewWritable( LibName CellName ViewName ) + CopyBuffer_template1( lcv ViewName LibName CellName )) + ) + + when(Temp=="Template2" + printf("Template2\n") + mcv=nrOpenCellViewReadable( LibName TemplateCellName "template2") + + when( cv != nil + printf( "Buffer type already exists %s\n" CellName) + ) + when( mcv == nil + printf("Template Cell doesnot exists %s\n" TemplateCellName)) + when( ((cv == nil)&&(mcv != nil)) + printf("Yes\n") + dbCopyCellView(mcv LibName CellName "scratch" nil nil t) + ncv = nrOpenCellViewWritable( LibName CellName "scratch" ) + MakeBuffer2( ncv ViewName) + dbSave(ncv) + dbPurge(ncv) + lcv = nrOpenCellViewWritable( LibName CellName ViewName ) + CopyBuffer_template2( lcv ViewName LibName CellName )) + ) + when(Temp=="Template3" + printf("Template3\n") + mcv=nrOpenCellViewReadable( LibName TemplateCellName "template_fullheight") + + when( cv != nil + printf( "Buffer type already exists %s\n" CellName) + ) + when( mcv == nil + printf("Template Cell doesnot exists %s\n" TemplateCellName)) + when( ((cv == nil)&&(mcv != nil)) + printf("Yes\n") + dbCopyCellView(mcv LibName CellName "scratch" nil nil t) + ncv = nrOpenCellViewWritable( LibName CellName "scratch" ) + MakeBuffer_FullHeight( ncv ViewName) + dbSave(ncv) + dbPurge(ncv) + lcv = nrOpenCellViewWritable( LibName CellName ViewName ) + CopyBuffer_fullheight( lcv ViewName LibName CellName )) + ) + + ) + ) + +(defun Parameter ( CellName) + (let (fl pieces piece specname initialpath InitialPath IntermediatePath finalpath k text Variable1 cst FinalPath variable1 variable2 variable3 variable4 Variable3 Variable4 var3 var4 Var3 varb4 Varb3 Var4 Outfl chk) + pieces=parseString( CellName "." ) + specname=nth( 4 pieces ) + chk=nth( 3 pieces) + cst=".cast" + when(chk=="BUF_1of4" + IntermediatePath="/lib/buffer/half/BUF_1of4/") + when(chk=="BUF_H_1of4" + IntermediatePath="/lib/buffer/half/BUF_H_1of4/") + initialpath=ConfigFileGetValue(TheCDSConfigTable "CAST_PATH") + piece=parseString( initialpath ":" ) + InitialPath=nth( 1 piece ) + finalpath=strcat(InitialPath IntermediatePath specname cst) + fl = infile(finalpath) + Outfl = outfile("Parameter.txt" "w") + while( gets(k fl) != nil + text = parseString( k " \n") + Variable1 = nth(0 text) + when((Variable1=="XReset")||(Variable1=="X_Reset")||(Variable1=="XL.e")||(Variable1=="XR.0")||(Variable1=="XR.1")||(Variable1=="XR.2")||(Variable1=="XR.3") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(6 text) + Variable3=nth(7 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(8 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) + when((Variable1=="X_r.0")||(Variable1=="X_r.1")||(Variable1=="X_r.2")||(Variable1=="X_r.3") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(8 text) + Variable3=nth(9 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(10 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) + when((Variable1=="Xrv") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(10 text) + Variable3=nth(11 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(12 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) + +) + close(Outfl) + close(fl) + )) + +(defun BC ( CellName) + +; fl = infile("buf.txt") +; while( gets(k fl) != nil +; text = parseString( k " \n") +; CellName = nth(0 text) + printf("Cell is %s\n" CellName) + Parameter(CellName) + BufferCreator(CellName "layout") +) + + + +defun( BufCreatePrBound (CellView) + (let ( + lpps + bBox + x1 x2 y1 y2 + Grid + ) + Grid=ManufacturingGrid*MicronsPerMeter + bBox=CellView~>bBox + x1=min(caar(bBox) caadr(bBox)) + x2=max(caar(bBox) caadr(bBox)) + y1=min(cadar(bBox) cadadr(bBox)) + y2=max(cadar(bBox) cadadr(bBox)) + x1=floor(x1/Grid)*Grid + y1=floor(y1/Grid)*Grid + x2=ceiling(x2/Grid)*Grid + y2=ceiling(y2/Grid)*Grid + bBox=list( x1:y1 x2:y2 ) + lpps=setof( lpp CellView~>lpps lpp~>layerName==car(BoundaryLPP) ) + foreach( shape CellView->shapes + when( shape->lpp==BoundaryLPP + dbDeleteObject( shape ) + ) + ) + llcorner=car(CellView->bBox) + urcorner=cadr(CellView->bBox) + ulcorner=(list car(llcorner) cadr(urcorner) ) + lrcorner=(list car(urcorner) cadr(llcorner) ) + dbCreatePRBoundary( CellView list(llcorner lrcorner urcorner ulcorner) ) + + dbSave( CellView ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreatorTwo.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreatorTwo.il new file mode 100644 index 0000000000..25a8dcd8da --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/BufferCreatorTwo.il @@ -0,0 +1,1149 @@ +(defun MakeBuffer (CellView ViewName) + (let (text parameter1 parameter2 parameter3 parameter4 cordnx1 cordnx2 cordr1nx1 cordr1nx2 cordr1px1 cordr1px2 cordR0x1 cordR0x2 cordR0y1 cordR0y2 cordR1x1 cordR1x2 cordR1y2 cordResx2 cordresx1 cordrvx1 cordrvx2 cordrvy2 cordLex1 cordLex2 cordLey2 R0NWidth R0PWidth R1NWidth R1PWidth LeNWidth Nr0Width Pr0Width LePWidth ResPWidth ResNWidth rvNWidth rvPWidth ActualcordR1x2 ActualcordR1x1 ActualcordR0x2 ActualcordR0x1 i Actualcordrvx1 ActualcordLex1 actualleftPoly ActualleftPoly ActualrightPoly Actualcordrvx2 prbound pry1 pry2 pry3 pry4 INST SHAPE VIA) + i=0 + fl = infile("Parameter.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + parameter1 = nth(0 text) + parameter2 = nth(1 text) + parameter3 = nth(2 text) + parameter4 = nth(3 text) + ;setting instance parameters as per the spec file + foreach(INST CellView->instances + (let (N P Nparam Pparam paraN1 paraN2 paraP1 paraP2 paraP3 paraP4 paraP5 paraP6 paraP7 paraP8 paraP9 paraP10) + when( (INST->name==parameter1) && (INST->cellName=="gate.INV.0-L1_1-R") + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0") + R0PWidth=P + R0NWidth=N) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1") + R1NWidth=N + R1PWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e") + LeNWidth=N + LePWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset") + ResPWidth=P) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="_Reset") + ResNWidth=N) + dbReplaceProp(INST "NW1" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( (INST->name==parameter1) && (INST->cellName=="gate.NAND3.0-L1_1-R") + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + rvPWidth=P + rvNWidth=N + dbReplaceProp(INST "NW3" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( ( (INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")) + paraN1 = strcat( parameter1 "." "N1") + paraN2 = strcat( parameter1 "." "N2") + paraP1 = strcat( parameter1 "." "P1") + paraP2 = strcat( parameter1 "." "P2") + when(((INST->name==paraN1) || (INST->name==paraP1) || (INST->name==paraN2) || (INST->name==paraP2) ) + N=evalstring(parameter3) + Nparam=N/2000000 + P=evalstring(parameter4) + Pparam=P/2000000 + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.0.N1")) + Nr0Width=N) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.0.P1")) + Pr0Width=P) + dbReplaceProp(INST "NW2" "float" Nparam) + dbReplaceProp(INST "PW2" "float" Pparam) + )) + ))) +; Calculates the XY origin and bBox to move instances w.r.t the new spec + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordr1Nx cordr1Nx1 cordr1Nx2 cordPx cordPx1 cordPx2 cordr1Px cordr1Px1 cordr1Px2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.0.N1")) + cordNx=caar(INST~>bBox) + cordNx1=cordNx+0.02 + cordnx1=cordNx1 + cordNx2=cordNx1-0.06 + cordnx2=cordNx2) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.1.N1")) + cordr1Nx=caar(INST~>bBox) + cordr1Nx1=cordr1Nx+0.02 + cordr1nx1=cordr1Nx1 + cordr1Nx2=cordr1Nx1-0.06 + cordr1nx2=cordr1Nx2) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.0.P1")) + cordPx=caadr(INST~>bBox) + Lpinx=caar(INST~>bBox) + cordPx1=cordPx-0.02 + cordpx1=cordPx1 + cordPx2=cordPx1+0.06 + cordpx2=cordPx2) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="_r.1.P1")) + cordr1Px=caadr(INST~>bBox) + cordr1Px1=cordr1Px-0.02 + cordr1px1=cordr1Px1 + cordr1Px2=cordr1Px1+0.06 + cordr1px2=cordr1Px2) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0")) + cordR0x1=caar(INST~>bBox) + cordR0x2=caadr(INST~>bBox) + cordR0y1=cadar(INST~>bBox) + cordR0y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1")) + cordR1x1=caar(INST~>bBox) + cordR1x2=caadr(INST~>bBox) + cordR1y2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="Reset")) + when(ResPWidth>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when(ResPWidth<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-ResPWidth))) + cordResx2=caadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="_Reset")) + when(ResNWidth>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(ResNWidth<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-ResNWidth))) + cordresx1=caar(INST~>bBox)) + when(((INST->cellName=="gate.NAND3.0-L1_1-R") && (INST->name=="rv")) + cordrvx1=caar(INST~>bBox) + cordrvx2=caadr(INST~>bBox) + cordrvy2=cadadr(INST~>bBox)) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e")) + cordLex1=caar(INST~>bBox) + cordLex2=caadr(INST~>bBox) + cordLey2=cadadr(INST~>bBox)) + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="L.e")) + when(cordLey2==2.95 + when(cordLex1+0.07>0.495 + dbReplaceProp(INST "n_contact_offset" "float" (0.525-0.2-(LeNWidth/6))) + ) + when(cordLex1+0.07<=0.495 + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + )) + when(cordLey2==2.82 + when(cordLex1+0.07>0.495 + dbReplaceProp(INST "n_contact_offset" "float" (0.525-0.2-(LeNWidth/5))) + ) + when(cordLex1+0.07<=0.495 + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + )) + when(cordLey2==2.69 + when(cordLex1+0.07>0.495 + dbReplaceProp(INST "n_contact_offset" "float" (0.525-0.2-(LeNWidth/4))) + ) + when(cordLex1+0.07<=0.495 + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + )) + when(cordLey2==2.56 + when(cordLex1+0.07>0.495 + dbReplaceProp(INST "n_contact_offset" "float" (0.525-0.2-(LeNWidth/3))) + ) + when(cordLex1+0.07<=0.495 + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + )) + when(cordLey2==2.43 + when(cordLex1+0.07>0.495 + dbReplaceProp(INST "n_contact_offset" "float" (0.525-0.2-(LeNWidth/2))) + ) + when(cordLex1+0.07<=0.495 + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + )) + when(cordLey2==2.3 + when(cordLex1+0.07>0.495 + dbReplaceProp(INST "n_contact_offset" "float" (0.525-0.2-LeNWidth)) + ) + when(cordLex1+0.07<=0.495 + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + )) + ActualcordLex1=caar(INST~>bBox)) + + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.1") + when(cordR1y2==6.07 + when((R1PWidth/6)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R1PWidth/6)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R1PWidth/6))))) + when(cordR1y2==5.94 + when((R1PWidth/5)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R1PWidth/5)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R1PWidth/5))))) + when(cordR1y2==5.81 + when((R1PWidth/4)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R1PWidth/4)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R1PWidth/4))))) + when(cordR1y2==5.68 + when((R1PWidth/3)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R1PWidth/3)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R1PWidth/3))))) + when(cordR1y2==5.55 + when((R1PWidth/2)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R1PWidth/2)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R1PWidth/2))))) + when(cordR1y2==5.42 + when(R1PWidth>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when(R1PWidth<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-R1PWidth)))) + ActualcordR1x2=caadr(INST~>bBox) + ActualcordR1x1=caar(INST~>bBox) + ) + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="R.0") + when(cordR0y2==1.13 + when((R0PWidth/6)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R0PWidth/6)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R0PWidth/6))))) + when(cordR0y2==1.0 + when((R0PWidth/5)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R0PWidth/5)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R0PWidth/5))))) + when(cordR0y2==0.87 + when((R0PWidth/4)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R0PWidth/4)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R0PWidth/4))))) + when(cordR0y2==0.74 + when((R0PWidth/3)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R0PWidth/3)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R0PWidth/3))))) + when(cordR0y2==0.61 + when((R0PWidth/2)>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when((R0PWidth/2)<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(R0PWidth/2))))) + when(cordR0y2==0.48 + when(R0PWidth>=0.21 + dbReplaceProp(INST "p_contact_offset" "float" 0.06)) + when(R0PWidth<0.21 + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-R0PWidth)))) + ActualcordR0x2=caadr(INST~>bBox) + ActualcordR0x1=caar(INST~>bBox) + ) + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->cellName=="gate.NAND3.0-L1_1-R") && (INST->name=="rv")) + when(cordrvy2==3.86 + when((rvPWidth/2<=0.21) + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-(rvPWidth/2))) + ) + when((rvPWidth/2>0.21) + dbReplaceProp(INST "p_contact_offset" "float" 0.06) + ) + when((cordrvx1+0.07>0.305)&&(ActualcordLex1>cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" (0.7-0.2-(rvNWidth/2))) + ) + when((cordrvx1+0.07>0.305)&&(ActualcordLex1<=cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" (abs(ActualcordLex1-0.17-0.95)-0.2-(rvNWidth/2))) + ) + when((cordrvx1+0.07<=0.305)&&(ActualcordLex1>cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + ) + when((cordrvx1+0.07<=0.305)&&(ActualcordLex1<=cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" (abs(ActualcordLex1-0.17-0.95)-0.2-(rvNWidth/2))) + )) + when(cordrvy2==3.47 + when((rvPWidth<=0.21) + dbReplaceProp(INST "p_contact_offset" "float" (0.475-0.2-rvPWidth)) + ) + when((rvPWidth>0.21) + dbReplaceProp(INST "p_contact_offset" "float" 0.06) + ) + when((cordrvx1+0.07>0.305)&&(ActualcordLex1>cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" (0.7-0.2-rvNWidth)) + ) + when((cordrvx1+0.07>0.305)&&(ActualcordLex1<=cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" (abs(ActualcordLex1-0.17-0.95)-0.2-rvNWidth)) + ) + when((cordrvx1+0.07<=0.305)&&(ActualcordLex1>cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" 0.06) + ) + when((cordrvx1+0.07<=0.305)&&(ActualcordLex1<=cordrvx1+0.13) + dbReplaceProp(INST "n_contact_offset" "float" (abs(ActualcordLex1-0.17-0.95)-0.2-rvNWidth)) + )) + Actualcordrvx1=caar(INST~>bBox) + Actualcordrvx2=caadr(INST~>bBox)) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==1.235)&&(xy1==0.11))||((xy2==1.495)&&(xy1==0.11))||((xy2==1.755)&&(xy1==0.11))||((xy2==4.355)&&(xy1==0.11))||((xy2==4.615)&&(xy1==0.11))||((xy2==5.005)&&(xy1==0.11))) + when(Nr0Width<=0.61 + when((ActualcordLex1+0.07)>0.435 + XY=(xy1+0.04:xy2)) + when((ActualcordLex1+0.07)<=0.435 + XY=(ActualcordLex1-0.215:xy2))) + when(Nr0Width>0.61 + when(((ActualcordLex1+0.07)>0.435)&&(cordnx1+0.06>=xy1+0.1) + XY=(xy1+0.04:xy2)) + when(((ActualcordLex1+0.07)>0.435)&&(cordnx1+0.06=ActualcordLex1-0.155) + XY=(ActualcordLex1-0.215:xy2)) + when(((ActualcordLex1+0.07)<=0.435)&&(cordnx1+0.06instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==1.235)&&(xy1==actualleftPoly))||((xy2==1.495)&&(xy1==actualleftPoly))||((xy2==1.755)&&(xy1==actualleftPoly))||((xy2==4.355)&&(xy1==actualleftPoly))||((xy2==4.615)&&(xy1==actualleftPoly))||((xy2==5.005)&&(xy1==actualleftPoly)))&&(ActualcordR1x1<=actualleftPoly)&&(ActualcordR1x1<=ActualcordR0x1) + XY=(ActualcordR1x1-0.02:xy2) + ActualleftPoly=car(XY) + dbSet(INST XY "xy")) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==1.235)&&(xy1==actualleftPoly))||((xy2==1.495)&&(xy1==actualleftPoly))||((xy2==1.755)&&(xy1==actualleftPoly))||((xy2==4.355)&&(xy1==actualleftPoly))||((xy2==4.615)&&(xy1==actualleftPoly))||((xy2==5.005)&&(xy1==actualleftPoly)))&&(ActualcordR0x1<=actualleftPoly)&&(ActualcordR0x1<=ActualcordR1x1) + XY=(ActualcordR0x1-0.02:xy2) + ActualleftPoly=car(XY) + dbSet(INST XY "xy")) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==1.235)&&(xy1==actualleftPoly))||((xy2==1.495)&&(xy1==actualleftPoly))||((xy2==1.755)&&(xy1==actualleftPoly))||((xy2==4.355)&&(xy1==actualleftPoly))||((xy2==4.615)&&(xy1==actualleftPoly))||((xy2==5.005)&&(xy1==actualleftPoly)))&&(ActualcordR0x1>actualleftPoly)&&(ActualcordR1x1>actualleftPoly) + ActualleftPoly=actualleftPoly) + when((INST~>cellName=="M1_POLYmin")&&(((xy2==1.625)&&(xy1==2.18))||((xy2==1.885)&&(xy1==2.18))||((xy2==4.485)&&(xy1==2.18))||((xy2==4.745)&&(xy1==2.18))) + when(((cordpx1-0.06)<=1.565)&&((Actualcordrvx2-0.2)<=1.565) + XY=(cordResx2+0.37:xy2)) + when(((cordpx1-0.06)>1.565)&&((Actualcordrvx2-0.2)<=1.565) + XY=(cordpx1+0.02:xy2)) + when(((cordpx1-0.06)<=(Actualcordrvx2-0.2))&&((Actualcordrvx2-0.2)>1.565) + XY=(Actualcordrvx2+0.06:xy2)) + when(((cordpx1-0.06)>(Actualcordrvx2-0.2))&&((Actualcordrvx2-0.2)>1.565) + XY=(cordpx1+0.02:xy2)) + ActualrightPoly=car(XY) + dbSet(INST XY "xy")) ; moves the M1_Polymin vias on the right side of the leaf cell + )) + + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.PPLUG.0")&&(xy1==2.125&&xy2==2.86) + XY=((ActualrightPoly-0.055):xy2) + dbSet(INST XY "xy")) + when((INST->cellName=="stack.NPLUG.0")&&(xy1==0.15&&xy2==3.935) + XY=((ActualleftPoly+0.045):xy2) + dbSet(INST XY "xy")) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.755&&xy2==5.98)||(xy1==1.145&&xy2==5.98)||(xy1==0.755&&xy2==5.72)||(xy1==1.145&&xy2==5.72)||(xy1==0.755&&xy2==5.46)||(xy1==1.145&&xy2==5.46)) + when(((cordR1y2==5.94)||(cordR1y2==5.81))&&((xy1==0.755&&xy2==5.98)||(xy1==1.145&&xy2==5.98)) + dbDeleteObject(INST)) + when(((cordR1y2==5.68)||(cordR1y2==5.55))&&((xy1==0.755&&xy2==5.98)||(xy1==1.145&&xy2==5.98)||(xy1==0.755&&xy2==5.72)||(xy1==1.145&&xy2==5.72)) + dbDeleteObject(INST)) + when((cordR1y2==5.42)&&((xy1==0.755&&xy2==5.98)||(xy1==1.145&&xy2==5.98)||(xy1==0.755&&xy2==5.72)||(xy1==1.145&&xy2==5.72)||(xy1==0.755&&xy2==5.46)||(xy1==1.145&&xy2==5.46)) + dbDeleteObject(INST)) + ) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.755&&xy2==1.04)||(xy1==1.145&&xy2==1.04)||(xy1==0.755&&xy2==0.78)||(xy1==1.145&&xy2==0.78)||(xy1==0.755&&xy2==0.52)||(xy1==1.145&&xy2==0.52)) + when(((cordR0y2==1.0)||(cordR0y2==0.87))&&((xy1==0.755&&xy2==1.04)||(xy1==1.145&&xy2==1.04)) + dbDeleteObject(INST)) + when(((cordR0y2==0.74)||(cordR0y2==0.61))&&((xy1==0.755&&xy2==1.04)||(xy1==1.145&&xy2==1.04)||(xy1==0.755&&xy2==0.78)||(xy1==1.145&&xy2==0.78)) + dbDeleteObject(INST)) + when((cordR0y2==0.48)&&((xy1==0.755&&xy2==1.04)||(xy1==1.145&&xy2==1.04)||(xy1==0.755&&xy2==0.78)||(xy1==1.145&&xy2==0.78)||(xy1==0.755&&xy2==0.52)||(xy1==1.145&&xy2==0.52)) + dbDeleteObject(INST)) + ) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==1.145&&xy2==3.51)||(xy1==1.145&&xy2==3.77)) + when((cordrvy2==3.47) + dbDeleteObject(INST))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.755&&xy2==2.86)||(xy1==0.755&&xy2==2.6)||(xy1==1.145&&xy2==2.6)||(xy1==0.755&&xy2==2.34)||(xy1==1.145&&xy2==2.34)) + when(((cordLey2==2.82)||(cordLey2==2.69))&&(xy1==0.755&&xy2==2.86) + dbDeleteObject(INST)) + when(((cordLey2==2.56)||(cordLey2==2.43))&&((xy1==0.755&&xy2==2.86)||(xy1==0.755&&xy2==2.6)||(xy1==1.145&&xy2==2.6)) + dbDeleteObject(INST)) + when((cordLey2==2.3)&&((xy1==0.755&&xy2==2.86)||(xy1==0.755&&xy2==2.6)||(xy1==1.145&&xy2==2.6)||(xy1==0.755&&xy2==2.34)||(xy1==1.145&&xy2==2.34)) + dbDeleteObject(INST))) + )) + + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="M1")&&((bx1==0.21&&by1==1.92)||(bx1==0.21&&by1==1.4)) + bbox=list((cordnx1+0.06):by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the GND terminals of the C2 gates on the NMOS side for r.o + when((SHAPE~>layerName=="M1")&&((bx1==0.21&&by1==4.78)||(bx1==0.21&&by1==4.26)) + bbox=list((cordr1nx1+0.06):by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the GND terminals of the C2 gates on the NMOS side for r.1 + when((SHAPE~>layerName=="M1")&&((bx1==1.04&&by1==1.92)||(bx1==1.04&&by1==1.4)) + bbox=list(bx1:by1 cordpx1-0.06:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the Vdd terminals of the C2 gates on the PMOS side for r.o + when((SHAPE~>layerName=="M1")&&((bx1==1.04&&by1==4.78)||(bx1==1.04&&by1==4.26)) + bbox=list(bx1:by1 cordr1px1-0.06:by2) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the Vdd terminals of the C2 gates on the PMOS side for r.1 + when((SHAPE~>layerName=="CO")&&((bx1==0.79&&by1==4.66)||(bx1==0.68&&by1==4.66)||(bx1==0.57&&by1==4.66)||(bx1==0.46&&by1==4.66)||(bx1==0.35&&by1==4.66)||(bx1==0.24&&by1==4.66)||(bx1==0.79&&by1==1.54)||(bx1==0.68&&by1==1.54)||(bx1==0.57&&by1==1.54)||(bx1==0.46&&by1==1.54)||(bx1==0.35&&by1==1.54)||(bx1==0.24&&by1==1.54)) + dbDeleteObject(SHAPE) + i = 0.83 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i-0.04:by2)) + when((i-0.15)<(cordnx1+0.07) + k=20 + i = 0.94) + when((i-0.15)>=(cordnx1+0.07) + k = k+1 + i = i - 0.11))) + when((SHAPE~>layerName=="CO")&&((bx1==0.79&&by1==4.4)||(bx1==0.68&&by1==4.4)||(bx1==0.57&&by1==4.4)||(bx1==0.46&&by1==4.4)||(bx1==0.35&&by1==4.4)||(bx1==0.24&&by1==4.4)||(bx1==0.79&&by1==1.8)||(bx1==0.68&&by1==1.8)||(bx1==0.57&&by1==1.8)||(bx1==0.46&&by1==1.8)||(bx1==0.35&&by1==1.8)||(bx1==0.24&&by1==1.8)) + dbDeleteObject(SHAPE) + i = 0.83 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i-0.04:by2)) + when((i-0.15)<(cordnx1+0.07) + k=20 + i = 0.94) + when((i-0.15)>=(cordnx1+0.07) + k = k+1 + i = i - 0.11))) + when((SHAPE~>layerName=="CO")&&((bx1==1.07&&by1==4.66)||(bx1==1.18&&by1==4.66)||(bx1==1.29&&by1==4.66)||(bx1==1.4&&by1==4.66)||(bx1==1.51&&by1==4.66)||(bx1==1.62&&by1==4.66)||(bx1==1.73&&by1==4.66)||(bx1==1.84&&by1==4.66)||(bx1==1.07&&by1==1.54)||(bx1==1.18&&by1==1.54)||(bx1==1.29&&by1==1.54)||(bx1==1.4&&by1==1.54)||(bx1==1.51&&by1==1.54)||(bx1==1.62&&by1==1.54)||(bx1==1.73&&by1==1.54)||(bx1==1.84&&by1==1.54)) + dbDeleteObject(SHAPE) + i = 1.07 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i+0.04:by2)) + when((i+0.15)>(cordpx1-0.07) + k=20 + i = 1.07) + when((i+0.15)<=(cordpx1-0.07) + k = k+1 + i = i + 0.11))) + when((SHAPE~>layerName=="CO")&&((bx1==1.07&&by1==4.4)||(bx1==1.18&&by1==4.4)||(bx1==1.29&&by1==4.4)||(bx1==1.4&&by1==4.4)||(bx1==1.51&&by1==4.4)||(bx1==1.62&&by1==4.4)||(bx1==1.73&&by1==4.4)||(bx1==1.84&&by1==4.4)||(bx1==1.07&&by1==1.8)||(bx1==1.18&&by1==1.8)||(bx1==1.29&&by1==1.8)||(bx1==1.4&&by1==1.8)||(bx1==1.51&&by1==1.8)||(bx1==1.62&&by1==1.8)||(bx1==1.73&&by1==1.8)||(bx1==1.84&&by1==1.8)) + dbDeleteObject(SHAPE) + i = 1.07 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i+0.04:by2)) + when((i+0.15)>(cordpx1-0.07) + k=20 + i = 1.07) + when((i+0.15)<=(cordpx1-0.07) + k = k+1 + i = i + 0.11))) + when((SHAPE~>layerName=="OD")&&((bx1==1.06&&by1==1.795)||(bx1==1.06&&by1==1.535)) + bbox=list(bx1:by1 cordpx1-0.06:by2) + dbSet(SHAPE bbox "bBox")) ;for r.o + when((SHAPE~>layerName=="OD")&&((bx1==1.06&&by1==4.655)||(bx1==1.06&&by1==4.395)) + bbox=list(bx1:by1 cordr1px1-0.06:by2) + dbSet(SHAPE bbox "bBox")) ; for r.1 + when((SHAPE~>layerName=="OD")&&((bx1==0.23&&by1==1.795)||(bx1==0.23&&by1==1.535)) + bbox=list(cordnx1+0.06:by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) ;for r.0 + when((SHAPE~>layerName=="OD")&&((bx1==0.23&&by1==4.395)||(bx1==0.23&&by1==4.655)) + bbox=list(cordr1nx1+0.06:by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) ;for r.1 + when((SHAPE~>layerName=="M1")&&bx1==0.21&&by1==1.53 + when((cordnx1+0.06<=0.38) + bbox=list(cordnx1+0.06:by1 bx2:by2)) + when((cordnx1+0.06>0.38) + bbox=list(0.38:by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the terminals connecting the internal nets of the C2 gates on the NMOS side for r.0 + when((SHAPE~>layerName=="M1")&&bx1==0.21&&by1==1.79 + when((cordnx1+0.06<=0.38) + bbox=list(cordnx1+0.06:by1 bx2:by2)) + when((cordnx1+0.06>0.38) + bbox=list(0.51:by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the terminals connecting the internal nets of the C2 gates on the NMOS side for r.0 + when((SHAPE~>layerName=="M1")&&bx1==0.21&&by1==4.65 + when((cordr1nx1+0.06<=0.38) + bbox=list(cordr1nx1+0.06:by1 bx2:by2)) + when((cordr1nx1+0.06>0.38) + bbox=list(0.38:by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the terminals connecting the internal nets of the C2 gates on the NMOS side for r.1 + when((SHAPE~>layerName=="M1")&&bx1==0.21&&by1==4.39 + when((cordr1nx1+0.06<=0.38) + bbox=list(cordr1nx1+0.06:by1 bx2:by2)) + when((cordr1nx1+0.06>0.38) + bbox=list(0.51:by1 bx2:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the terminals connecting the internal nets of the C2 gates on the NMOS side for r.1 + + when((SHAPE~>layerName=="M1")&&((bx1==1.04&&by1==4.65)||(bx1==1.04&&by1==4.39)||(bx1==1.06&&by1==1.535)||(bx1==1.06&&by1==4.655)) + when((SHAPE~>layerName=="CO")&&((bx1==1.07&&by1==4.66)||(bx1==1.18&&by1==4.66)||(bx1==1.29&&by1==4.66)||(bx1==1.4&&by1==4.66)||(bx1==1.51&&by1==4.66)||(bx1==1.62&&by1==4.66)||(bx1==1.73&&by1==4.66)||(bx1==1.84&&by1==4.66)||(bx1==1.07&&by1==1.54)||(bx1==1.18&&by1==1.54)||(bx1==1.29&&by1==1.54)||(bx1==1.4&&by1==1.54)||(bx1==1.51&&by1==1.54)||(bx1==1.62&&by1==1.54)||(bx1==1.73&&by1==1.54)||(bx1==1.84&&by1==1.54)) + dbDeleteObject(SHAPE)) + when(bx1==1.04&&by1==4.39 + when((cordr1px1-0.06>=1.52) + bbox=list(bx1:by1 cordr1px1-0.06:by2)) + when((cordr1px1-0.06<1.52) + bbox=list(bx1:by1 1.39:by2))) + when(bx1==1.04&&by1==4.65 + when((cordr1px1-0.06>=1.52) + bbox=list(bx1:by1 cordr1px1-0.06:by2)) + when((cordr1px1-0.06<1.52) + bbox=list(bx1:by1 1.52:by2))) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the terminals connecting the internal nets of the C2 gates on the PMOS side + when((SHAPE~>layerName=="M1")&&bx1==1.04&&by1==1.79 + when((cordpx1-0.06>=1.52) + bbox=list(bx1:by1 cordpx1-0.06:by2)) + when((cordpx1-0.06<1.52) + bbox=list(bx1:by1 1.39:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the terminals connecting the internal nets of the C2 gates on the PMOS side + when((SHAPE~>layerName=="M1")&&bx1==1.04&&by1==1.53 + when((cordpx1-0.06>=1.52) + bbox=list(bx1:by1 cordpx1-0.06:by2)) + when((cordpx1-0.06<1.52) + bbox=list(bx1:by1 1.52:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M1 layer on the terminals connecting the internal nets of the C2 gates on the PMOS side + when((SHAPE~>layerName=="M1")&&bx1==0.255&&by1==0.11 + when((ActualcordLex1+0.07)>0.435 + pnts=list(ActualcordR0x2-0.07:y1 ActualcordR0x2-0.07:y2 x3:y3)) + when((ActualcordLex1+0.07)<=0.435 + pnts=list(ActualcordR0x2-0.07:y1 ActualcordR0x2-0.07:y2 ActualcordLex1-0.06:y3)) + dbSet(SHAPE pnts "points")) ; moves the M1 connecting the _r.0 input from M2 to the input of R.0 INV gate + when((SHAPE~>layerName=="M1")&&bx1==0.555&&by1==1.66 + when((ActualcordLex1+0.07)>0.435 + bbox=list(0.305:by1 cordpx1-0.06:by2)) + when((ActualcordLex1+0.07)<=0.435 + bbox=list(ActualcordLex1-0.06:by1 cordpx1-0.06:by2)) + dbSet(SHAPE bbox "bBox")) ; moves the M1 output of _r.0 in C2 stat + when((SHAPE~>layerName=="M2")&&bx1==0.465&&by1==2.115 + pnts=list(ActualcordLex1+0.07:y1 ActualcordLex1+0.07:y2) + dbSet(SHAPE pnts "points")) ; moves the rv input on M2 on left side + when((SHAPE~>layerName=="M1")&&bx1==0.43&&by1==3.35 + pnts=list(ActualcordLex1+0.07:y1 0.95:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2")&&bx1==0.275&&by1==0.135 + when((ActualcordLex1+0.07)>0.435 + pnts=list(x1:y1 x2:y2)) + when((ActualcordLex1+0.07)<=0.435 + pnts=list(ActualcordLex1-0.06:y1 ActualcordLex1-0.06:y2)) ; moves the _r.0 input on the left side on M2 + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&bx1==0.195&&by1==3.155 + when((ActualcordLex1+0.07)>0.435 + pnts=list(Actualcordrvx1+0.06:y1 x2:y2)) + when((ActualcordLex1+0.07)<=0.435 + pnts=list(Actualcordrvx1+0.06:y1 ActualcordLex1-0.06:y2)) + when(cordrvy2==3.47 + dbCreatePath(CellView "M1" list(Actualcordrvx1+0.06:y1 0.82:y2) 0.06)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&((bx1==0.09&&by1==0.36)||(bx1==0.09&&by1==4.995)) + pnts=list(x1:y1 ActualleftPoly:y2 ActualleftPoly:y3) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&((bx1==0.08&&by1==1.465)||(bx1==0.08&&by1==4.325)) + pnts=list(ActualleftPoly:y1 ActualleftPoly:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2")&&((bx1==0.08&&by1==0.27)||(bx1==0.08&&by1==4.325)) + pnts=list(ActualleftPoly:y1 ActualleftPoly:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="PO")&&((bx1==0.055&&by1==1.22)||(bx1==0.11&&by1==1.48)||(bx1==0.11&&by1==1.74)||(bx1==0.11&&by1==4.34)||(bx1==0.11&&by1==4.6)||(bx1==0.11&&by1==4.99)) + pnts=list(ActualleftPoly:y1 x2:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&bx1==0.53&&by1==3.98 + pnts=list(x1:y1 cordresx1+0.07:y2 cordresx1+0.07:y3) + dbSet(SHAPE pnts "points")) ; moves the M1 connecting the Reset input to the _Reset INV gate + when((SHAPE~>layerName=="M2")&&bx1==1.435&&by1==3.4 + pnts=list(cordResx2-0.055:y1 cordResx2-0.055:y2) + dbSet(SHAPE pnts "points")) ; moves the M2 wire connecting to the M3 _RESET pin + when((SHAPE~>layerName=="M1")&&bx1==1.365&&by1==4.065 + pnts=list(cordResx2-0.055:y1 x2:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2")&&bx1==1.565&&by1==3.03 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(cordResx2+0.075:y1 cordResx2+0.075:y2)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(Actualcordrvx2-0.2:y1 Actualcordrvx2-0.2:y2)) + dbSet(SHAPE pnts "points")) ; moves the M2 wire connecting the _Reset input to the NAND3 rv gate + when((SHAPE~>layerName=="M1")&&bx1==0.82&&by1==3.87 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(x1:y1 cordResx2+0.075:y2)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(x1:y1 Actualcordrvx2-0.2:y2)) + dbSet(SHAPE pnts "points")); moves the M1 wire connecting the _Reset input + when((SHAPE~>layerName=="M1")&&bx1==1.33&&by1==3.025 + when(cordrvy2==3.86 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(Actualcordrvx2-0.2:y1 cordResx2+0.075:y2)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(Actualcordrvx2-0.17:y1 Actualcordrvx2-0.23:y2))) + when(cordrvy2==3.47 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(Actualcordrvx2-0.07:y1 cordResx2+0.075:y2)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(Actualcordrvx2-0.04:y1 Actualcordrvx2-0.23:y2))) + dbSet(SHAPE pnts "points")); moves the M1 wire connecting the _Reset input + when((SHAPE~>layerName=="M2")&&bx1==1.71&&by1==3.3 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(cordResx2+0.205:y1 cordResx2+0.205:y2)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(Actualcordrvx2-0.07:y1 Actualcordrvx2-0.07:y2)) + dbSet(SHAPE pnts "points")) ; moves the M2 wire connecting the _r.1 input to the NAND3 rv gate + when((SHAPE~>layerName=="M1")&&bx1==1.495&&by1==3.285 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(Actualcordrvx2-0.07:y1 cordResx2+0.205:y2)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(Actualcordrvx2-0.04:y1 Actualcordrvx2-0.1:y2)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&bx1==1.74&&by1==5.25 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(cordResx2+0.205:y1 ActualcordR1x2-0.07:y2 ActualcordR1x2-0.07:y3)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(Actualcordrvx2-0.07:y1 ActualcordR1x2-0.07:y2 ActualcordR1x2-0.07:y3)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&bx1==0.765&&by1==4.52 + when((Actualcordrvx2-0.2)<=1.565 + pnts=list(x1:y1 cordResx2+0.205:y2)) + when((Actualcordrvx2-0.2)>1.565 + pnts=list(x1:y1 Actualcordrvx2-0.07:y2)) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="PO")&&((bx1==0.95&&by1==1.61)||(bx1==0.95&&by1==1.87)||(bx1==0.95&&by1==4.47)||(bx1==0.95&&by1==4.73)) + pnts=list(ActualrightPoly:y1 x2:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M2")&&bx1==2.15&&by1==1.595 + pnts=list(ActualrightPoly:y1 ActualrightPoly:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&((bx1==2.15&&by1==1.595)||(bx1==2.15&&by1==4.455)) + pnts=list(ActualrightPoly:y1 ActualrightPoly:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&bx1==0.12&&by1==3.74 + pnts=list(x1:y1 ActualleftPoly+0.045:y2) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="M1")&&bx1==1.04&&by1==2.83 + pnts=list(x1:y1 ActualrightPoly-0.055:y2 ActualrightPoly-0.055:y3) + dbSet(SHAPE pnts "points")) + when((SHAPE~>layerName=="PP")&&bx1==0&&by1==3.41 + bbox=list(ActualleftPoly-0.105:by1 ActualleftPoly-0.025:by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="NP")&&bx1==2.23&&by1==2.86 + bbox=list(ActualrightPoly+0.11:by1 ActualrightPoly+0.05:by2) + dbSet(SHAPE bbox "bBox")) + when((SHAPE~>layerName=="PO")&&bx2==0.04&&by2==6.24 + bbox=list(ActualleftPoly-0.07:by1 ActualleftPoly-0.15:by2) + dbSet(SHAPE bbox "bBox")) ;moves the cut_poly on the left side of the leaf cell + when((SHAPE~>layerName=="PO")&&bx2==2.33&&by2==6.24 + bbox=list(ActualrightPoly+0.07:by1 ActualrightPoly+0.15:by2) + dbSet(SHAPE bbox "bBox")) ;moves the cut_poly on the right side of the leaf cell + when((SHAPE~>layerName=="PO")&&((bx1==-0.005&&by1==0.05)||(bx1==-0.005&&by1==0.18)||(bx1==-0.005&&by1==0.31)||(bx1==-0.005&&by1==0.44)||(bx1==-0.005&&by1==0.57)||(bx1==-0.005&&by1==0.7)||(bx1==-0.005&&by1==0.83)||(bx1==-0.005&&by1==0.96)||(bx1==-0.005&&by1==1.09)||(bx1==-0.005&&by1==1.22)||(bx1==-0.005&&by1==1.35)||(bx1==-0.005&&by1==1.48)||(bx1==-0.005&&by1==1.61)||(bx1==-0.005&&by1==1.74)||(bx1==-0.005&&by1==1.87)||(bx1==-0.005&&by1==2)||(bx1==-0.005&&by1==2.13)||(bx1==-0.005&&by1==2.26)||(bx1==-0.005&&by1==2.39)||(bx1==-0.005&&by1==2.52)||(bx1==-0.005&&by1==2.65)||(bx1==-0.005&&by1==2.78)||(bx1==-0.005&&by1==3.17)||(bx1==-0.005&&by1==3.3)||(bx1==-0.005&&by1==3.43)||(bx1==-0.005&&by1==3.56)||(bx1==-0.005&&by1==3.95)||(bx1==-0.005&&by1==4.08)||(bx1==-0.005&&by1==4.21)||(bx1==-0.005&&by1==4.34)||(bx1==-0.005&&by1==4.47)||(bx1==-0.005&&by1==4.6)||(bx1==-0.005&&by1==4.73)||(bx1==-0.005&&by1==4.86)||(bx1==-0.005&&by1==4.99)||(bx1==-0.005&&by1==5.12)||(bx1==-0.005&&by1==5.25)||(bx1==-0.005&&by1==5.38)||(bx1==-0.005&&by1==5.51)||(bx1==-0.005&&by1==5.64)||(bx1==-0.005&&by1==5.77)||(bx1==-0.005&&by1==5.9)||(bx1==-0.005&&by1==6.03)||(bx1==-0.005&&by1==6.16)) + bbox=list(ActualleftPoly-0.115:by1 ActualrightPoly+0.115:by2) + dbSet(SHAPE bbox "bBox")) ; moves the layout grid polys + when((SHAPE~>layerName=="M3")&&((bx1==0&&by1==0.025)||(bx1==0&&by1==1.465)||(bx1==0&&by1==1.585)||(bx1==0&&by1==3.025)||(bx1==0&&by1==3.145)||(bx1==0&&by1==4.585)||(bx1==0&&by1==4.705)||(bx1==0&&by1==6.145)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + bbox=list(ActualleftPoly-0.11:by1 ActualrightPoly+0.11:by2) + LeftLeaf=ActualleftPoly-0.11 + RightLeaf=(ActualrightPoly+0.11)-(ActualleftPoly-0.11)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + bbox=list(ActualcordR0x1-0.04:by1 ActualrightPoly+0.11:by2) + LeftLeaf=ActualcordR0x1-0.04 + RightLeaf=(ActualrightPoly+0.11)-(ActualcordR0x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + bbox=list(ActualcordR1x1-0.04:by1 ActualrightPoly+0.11:by2) + LeftLeaf=ActualcordR1x1-0.04 + RightLeaf=(ActualrightPoly+0.11)-(ActualcordR1x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + bbox=list(ActualcordR1x1-0.04:by1 ActualrightPoly+0.11:by2) + LeftLeaf=ActualcordR1x1-0.04 + RightLeaf=(ActualrightPoly+0.11)-(ActualcordR1x1-0.04)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + bbox=list(ActualcordR0x1-0.04:by1 ActualrightPoly+0.11:by2) + LeftLeaf=ActualcordR0x1-0.04 + RightLeaf=(ActualrightPoly+0.11)-(ActualcordR0x1-0.04)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualleftPoly-0.11:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualleftPoly-0.11 + RightLeaf=(ActualcordR0x2+0.04)-(ActualleftPoly-0.11)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualcordR0x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR0x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR0x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualcordR1x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR1x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR1x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR1x2) + bbox=list(ActualcordR1x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR1x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR1x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualcordR0x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR0x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR0x1-0.04)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR0x1)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualleftPoly-0.11:by1 ActualcordR1x2+0.04:by2) + LeftLeaf=ActualleftPoly-0.11 + RightLeaf=(ActualcordR1x2+0.04)-(ActualleftPoly-0.11)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualcordR0x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR0x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR0x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualcordR1x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR1x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR1x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR1x2) + bbox=list(ActualcordR1x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR1x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR1x1-0.04)) + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + bbox=list(ActualcordR0x1-0.04:by1 ActualcordR0x2+0.04:by2) + LeftLeaf=ActualcordR0x1-0.04 + RightLeaf=(ActualcordR0x2+0.04)-(ActualcordR0x1-0.04)) + dbSet(SHAPE bbox "bBox")) ;moves the M3 power grid(GND/Vdd) wires + when((SHAPE~>layerName=="M3")&&((bx1==0.04&&by1==0.295)||(bx1==0.04&&by1==2.895)||(bx1==0.04&&by1==4.975)) + bbox=list(ActualleftPoly-0.07:by1 bx2:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 L.o/L.1/L.e pins on the left side of the leaf cell + when((SHAPE~>layerName=="M3")&&((bx1==0.93&&by1==0.295)||(bx1==1.225&&by1==2.895)||(bx1==0.925&&by1==4.975)) + bbox=list(bx1:by1 ActualrightPoly+0.07:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 R.o/R.1/R.e pins on the left side of the leaf cell + when((SHAPE~>layerName=="M3")&&bx1==0.04&&by1==3.415 + bbox=list(ActualleftPoly-0.07:by1 ActualrightPoly+0.07:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 _RESET pin + when((SHAPE~>layerName=="PO")&&((bx1==-0.005&&by1==2.91)||(bx1==-0.005&&by1==3.04)) + bbox=list(ActualleftPoly-0.115:by1 ActualrightPoly-0.135:by2) + dbSet(SHAPE bbox "bBox")) ;moves the layout grid poly near the PPLUG + when((SHAPE~>layerName=="PO")&&((bx1==0.23&&by1==3.69)||(bx1==0.23&&by1==3.82)) + bbox=list(ActualleftPoly+0.125:by1 ActualrightPoly+0.115:by2) + dbSet(SHAPE bbox "bBox")) ;moves the layout grid poly near the NPLUG + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="NP"))&&((bx1==0&&by1==6.07)||(bx1==0&&by1==6.11)||(bx1==0&&by1==-0.13)) + bbox=list(ActualleftPoly-0.11:by1 ActualrightPoly+0.11:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on top and bottom + when((SHAPE~>layerName=="NP")&&bx1==0&&by1==0.17 + pnts=list(x1:y1 ActualleftPoly-0.11:y2 ActualleftPoly-0.11:y3 ActualleftPoly+0.15:y4 ActualleftPoly+0.15:y5 ActualleftPoly-0.11:y6 ActualleftPoly-0.11:y7 x8:y8) + dbSet(SHAPE pnts "points")) ; moves the NP layer on the left side of the leaf cell + when((SHAPE~>layerName=="PP")&&bx1==0.95&&by1==0.17 + pnts=list(ActualrightPoly+0.11:y1 ActualrightPoly-0.16:y2 ActualrightPoly-0.16:y3 ActualrightPoly+0.11:y4 ActualrightPoly+0.11:y5 x6:y6 x7:y7 ActualrightPoly+0.11:y8) + dbSet(SHAPE pnts "points")) ; moves the PP layer on the right side of the leaf cell + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="PM"))&&bx1==0.95&&by1==0.13 + bbox=list(bx1:by1 ActualrightPoly+0.11:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/PM layer on the right side of the leaf cell + + )) + when(prbound=GetPrbound(CellView) + pry1=cadar(prbound~>points) + pry2=cadadr(prbound~>points) + pry3=car(cdaddr(prbound~>points)) + pry4=cadr(cadddr(prbound~>points)) + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + pntss=list(ActualleftPoly-0.11:pry1 ActualleftPoly-0.11:pry2 ActualrightPoly+0.11:pry3 ActualrightPoly+0.11:pry4)) + + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + pntss=list(ActualcordR0x1-0.04:pry1 ActualcordR0x1-0.04:pry2 ActualrightPoly+0.11:pry3 ActualrightPoly+0.11:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + pntss=list(ActualcordR1x1-0.04:pry1 ActualcordR1x1-0.04:pry2 ActualrightPoly+0.11:pry3 ActualrightPoly+0.11:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + pntss=list(ActualcordR1x1-0.04:pry1 ActualcordR1x1-0.04:pry2 ActualrightPoly+0.11:pry3 ActualrightPoly+0.11:pry4)) + + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07>=ActualcordR1x2) + pntss=list(ActualcordR0x1-0.04:pry1 ActualcordR0x1-0.04:pry2 ActualrightPoly+0.11:pry3 ActualrightPoly+0.11:pry4)) + + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualleftPoly-0.11:pry1 ActualleftPoly-0.11:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualcordR0x1-0.04:pry1 ActualcordR0x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualcordR1x1-0.04:pry1 ActualcordR1x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR1x2) + pntss=list(ActualcordR1x1-0.04:pry1 ActualcordR1x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualcordR0x1-0.04:pry1 ActualcordR0x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07>=ActualcordR0x2)&&(ActualrightPoly+0.07ActualcordR0x1)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualleftPoly-0.11:pry1 ActualleftPoly-0.11:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07<=ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualcordR0x1-0.04:pry1 ActualcordR0x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07<=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualcordR1x1-0.04:pry1 ActualcordR1x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1=ActualcordR1x2) + pntss=list(ActualcordR1x1-0.04:pry1 ActualcordR1x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + + when((ActualleftPoly-0.07>ActualcordR1x1)&&(ActualleftPoly-0.07>ActualcordR0x1)&&(ActualcordR1x1>=ActualcordR0x1)&&(ActualrightPoly+0.07=ActualcordR1x2) + pntss=list(ActualcordR0x1-0.04:pry1 ActualcordR0x1-0.04:pry2 ActualcordR0x2+0.04:pry3 ActualcordR0x2+0.04:pry4)) + dbDeleteObject(prbound) + dbCreatePRBoundary(CellView pntss) + ) + + foreach(VIA CellView->vias + (let (vx1 vy1 bx1 by1 bx2 by2 vx1 vy1 orgn) + bx1=caar(VIA~>bBox) + by1=cadar(VIA~>bBox) + bx2=caadr(VIA~>bBox) + by2=cadadr(VIA~>bBox) + vx1=car(VIA~>origin) + vy1=cadr(VIA~>origin) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==1.465)&&(VIA~>net~>name=="_RESET") + orgn=(cordResx2-0.055:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==1.595)&&(VIA~>net~>name=="_Reset") + when((Actualcordrvx2-0.2)<=1.565 + orgn=(cordResx2+0.075:vy1)) + when((Actualcordrvx2-0.2)>1.565 + orgn=(Actualcordrvx2-0.2:vy1)) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==1.74)&&(VIA~>net~>name=="_r.1") + when((Actualcordrvx2-0.2)<=1.565 + orgn=(cordResx2+0.205:vy1)) + when((Actualcordrvx2-0.2)>1.565 + orgn=(Actualcordrvx2-0.07:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==2.18) + orgn=(ActualrightPoly:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==0.495) + orgn=(ActualcordLex1+0.07:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==0.305) + when((ActualcordLex1+0.07)>0.435 + orgn=(vx1:vy1)) + when((ActualcordLex1+0.07)<=0.435 + orgn=(ActualcordLex1-0.06:vy1)) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==0.11) + orgn=(ActualleftPoly:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&((vx1==0.95&&vy1==5.85)||(vx1==0.95&&vy1==5.59)) + when(((cordR1y2==5.81)||(cordR1y2==5.68))&&(vx1==0.95&&vy1==5.85) + dbDeleteObject(VIA)) + when(((cordR1y2==5.55)||(cordR1y2==5.42))&&((vx1==0.95&&vy1==5.85)||(vx1==0.95&&vy1==5.59)) + dbDeleteObject(VIA))) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&((vx1==0.95&&vy1==0.91)||(vx1==0.95&&vy1==0.65)) + when(((cordR0y2==0.87)||(cordR0y2==0.74))&&(vx1==0.95&&vy1==0.91) + dbDeleteObject(VIA)) + when(((cordR0y2==0.61)||(cordR0y2==0.48))&&((vx1==0.95&&vy1==0.91)||(vx1==0.95&&vy1==0.65)) + dbDeleteObject(VIA))) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&((vx1==0.95&&vy1==2.47)||(vx1==0.95&&vy1==2.73)) + when(((cordLey2==2.69)||(cordLey2==2.56))&&(vx1==0.95&&vy1==2.73) + dbDeleteObject(VIA)) + when(((cordLey2==2.43)||(cordLey2==2.3))&&((vx1==0.95&&vy1==2.47)||(vx1==0.95&&vy1==2.73)) + dbDeleteObject(VIA))) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&((vx1==0.495&&vy1==2.77)||(vx1==0.495&&vy1==2.58)||(vx1==0.495&&vy1==2.36)) + when((cordLey2==2.82)&&(vx1==0.495&&vy1==2.77) + dbDeleteObject(VIA)) + when(((cordLey2==2.69)||(cordLey2==2.56))&&((vx1==0.495&&vy1==2.77)||(vx1==0.495&&vy1==2.58)) + dbDeleteObject(VIA)) + when(((cordLey2==2.43)||(cordLey2==2.3))&&((vx1==0.495&&vy1==2.77)||(vx1==0.495&&vy1==2.58)||(vx1==0.495&&vy1==2.36)) + dbDeleteObject(VIA))) + + )) + )) +(defun BufferCreator ( CellName ViewName ) + let( ( k l m n y s z ce cel piecess piecesss cv ncv mcv lcv vcv TemplateCellName pieces LibName Temp LeftLeaf RightLeaf pntss) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + k="0" + l="0" + m="0" + n="0" + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + TemplateCellName = "lib.buffer.half.BUF_1of2.buftemplate" + mcv=nrOpenCellViewReadable( LibName TemplateCellName "Template") + + when( cv != nil + printf( "BUF_1of2 type already exists %s\n" CellName) + ) + when( mcv == nil + printf("Template Cell doesnot exists %s\n" TemplateCellName)) + when( ((cv == nil)&&(mcv != nil)) + printf("yes\n") + dbCopyCellView(mcv LibName CellName "scratch" nil nil t) + ncv = nrOpenCellViewWritable( LibName CellName "scratch" ) + MakeBuffer( ncv ViewName) + dbSave(ncv) + dbPurge(ncv) + lcv = nrOpenCellViewWritable( LibName CellName ViewName ) + CopyBuffer( lcv ViewName LibName CellName )) + )) + +(defun CopyBuffer ( CellView ViewName LibName CellName ) + (let (xy1 xy2 XY bx1 bx2 by1 by2 buf rightcord RightCord pnts SHAPE) + when(minusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0.04:0 "R0")) + when(plusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" LeftLeaf:0 "R0")) + when(LeftLeaf==0 + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0.04:0 "R0")) + foreach(INST CellView~>instances + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + XY=(-bx1:xy2) + dbSet(INST XY "xy")) + dbFlattenInst(buf 1) + rightcord=round(((RightLeaf/0.26)/0.5)*0.5+0.5) + RightCord=0.26*rightcord + pnts=list(0:by1+0.13 0:by2-0.13 RightCord:by2-0.13 RightCord:by1+0.13) + dbCreatePRBoundary(CellView pnts) + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.PPLUG.0") + XY=(RightCord-0.165:xy2) + dbSet(INST XY "xy")) + )) + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="NP"))&&((by2==6.37&&by1==6.07)||(by2==6.37&&by1==6.11)||(by2==0.13&&by1==-0.13)||(by2==0.17&&by1==-0.13)) + bbox=list(0:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on top and bottom + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="PM"))&&by2==6.11&&by1==0.13 + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/PM layer on the right side of the leaf cell + when((SHAPE~>layerName=="PP")&&by2==6.07&&by1==0.17 + pnts=list(RightCord:y1 RightCord-0.27:y2 RightCord-0.27:y3 RightCord:y4 RightCord:y5 x6:y6 x7:y7 RightCord:y8) + dbSet(SHAPE pnts "points")) ; moves the PP layer on the right side of the leaf cell + when((SHAPE~>layerName=="NP")&&by2==3.385&&by1==2.86 + bbox=list(RightCord-0.06:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NP layer on the right side of the leaf cell associated with PPLUG + when((SHAPE~>layerName=="M3")&&((bx1==0&&by1==0.025)||(bx1==0&&by1==1.465)||(bx1==0&&by1==1.585)||(bx1==0&&by1==3.025)||(bx1==0&&by1==3.145)||(bx1==0&&by1==4.585)||(bx1==0&&by1==4.705)||(bx1==0&&by1==6.145)) + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 power grid(GND/Vdd) wires + when((SHAPE~>layerName=="M3")&&((bx1!=0.04&&by1==0.295&&by2==0.355)||(bx1!=0.04&&by1==2.895&&by2==2.955)||(bx1!=0.04&&by1==4.975&&by2==5.035)) + bbox=list(bx1:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 R.o/R.1/R.e pins on the left side of the leaf cell + when((SHAPE~>layerName=="M3")&&bx1==0.04&&by1==3.415 + bbox=list(bx1:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 _RESET pin + when((SHAPE~>layerName=="M1")&&by2==3.065&&by1==2.83 + pnts=list(x1:y1 RightCord-0.17:y2 RightCord-0.17:y3) + dbSet(SHAPE pnts "points")) ; moves the M1 connecting the PPLUG to Vdd + )) + DeleteGridPoly(?CellView CellView) + DrawGridPoly(?CellView CellView) + ddDeleteObj(ddGetObj(LibName CellName "scratch")) + dbSave(CellView) + dbPurge(CellView) + + ) +) + +(defun Parameter ( CellName) + (let (fl pieces piece specname initialpath InitialPath IntermediatePath finalpath k text Variable1 cst FinalPath variable1 variable2 variable3 variable4 Variable3 Variable4 var3 var4 Var3 varb4 Varb3 Var4 Outfl) + println(CellName) + pieces=parseString( CellName "." ) + specname=nth( 4 pieces ) + cst=".cast" + IntermediatePath="/lib/buffer/half/BUF_1of2/" + initialpath=ConfigFileGetValue(TheCDSConfigTable "CAST_PATH") + piece=parseString( initialpath ":" ) + InitialPath=nth( 1 piece ) + finalpath=strcat(InitialPath IntermediatePath specname cst) + fl = infile(finalpath) + Outfl = outfile("Parameter.txt" "w") + while( gets(k fl) != nil + text = parseString( k " \n") + Variable1 = nth(0 text) + when((Variable1=="XReset")||(Variable1=="X_Reset")||(Variable1=="XL.e")||(Variable1=="XR.0")||(Variable1=="XR.1") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(6 text) + Variable3=nth(7 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(8 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) + when((Variable1=="X_r.0")||(Variable1=="X_r.1") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(8 text) + Variable3=nth(9 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(10 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) + when((Variable1=="Xrv") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(8 text) + Variable3=nth(9 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(10 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) + +) + close(Outfl) + close(fl) + )) + +(defun BC2 ( CellName) + +; fl = infile("buf.txt") +; while( gets(k fl) != nil +; text = parseString( k " \n") +; CellName = nth(0 text) + printf("Cell is %s\n" CellName) + Parameter(CellName) + BufferCreator(CellName "layout") +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/CtreeGenerator.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/CtreeGenerator.il new file mode 100644 index 0000000000..8c5b39f94d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/CtreeGenerator.il @@ -0,0 +1,680 @@ +(defun MakeCtree2 (CellView ViewName) + (let (text parameter1 parameter2 parameter3 parameter4 cordnx1 cordnx2 cordpx1 cordpx2 cordR0x1 cordR0x2 cordR0y2 PolyM1x2 ActualPolyM1x2 PolyM1x1 ActualPolyM1x1 PWidth NWidth cordx1 cordx2 INST SHAPE VIA i k) + fl = infile("Parameter.txt") + k=0 + i=0 + while( gets(k fl) != nil + text = parseString( k " \n") + parameter1 = nth(0 text) + parameter2 = nth(1 text) + parameter3 = nth(2 text) + parameter4 = nth(3 text) + foreach(INST CellView->instances + (let (N P Nparam Pparam paraN1 paraN2 paraP1 paraP2) + when( (INST->name==parameter1) && (INST->cellName=="gate.INV.0-L1_1-R") + N=evalstring(parameter3) + Nparam=N/1000000 + P=evalstring(parameter4) + Pparam=P/1000000 + when((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="x") + NWidth=N) + dbReplaceProp(INST "NW1" "float" Nparam) + dbReplaceProp(INST "PW1" "float" Pparam) + ) + when( ( (INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") || (INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R")) + paraN1 = strcat( parameter1 "." "N1") + paraN2 = strcat( parameter1 "." "N2") + paraP1 = strcat( parameter1 "." "P1") + paraP2 = strcat( parameter1 "." "P2") + when(((INST->name==paraN1) || (INST->name==paraP1) || (INST->name==paraN2) || (INST->name==paraP2)) + N=evalstring(parameter3) + Nparam=N/2000000 + P=evalstring(parameter4) + Pparam=P/2000000 + when((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="b.P1") + PWidth=(P/2)) + dbReplaceProp(INST "NW2" "float" Nparam) + dbReplaceProp(INST "PW2" "float" Pparam) + )) + ))) +; Calculates the XY origin and bBox to move instances w.r.t the new spec + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordPx cordPx1 cordPx2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when(((INST->cellName=="stack.NMOS_CHAIN_2.0-L1-R") && (INST->name=="b.N1")) + cordNx=caar(INST~>bBox) + cordNx1=cordNx+0.02 + cordnx1=cordNx1 + cordNx2=cordNx1-0.06 + cordnx2=cordNx2) + when(((INST->cellName=="stack.PMOS_CHAIN_2.0-L1-R") && (INST->name=="b.P1")) + cordPx=caadr(INST~>bBox) + cordPx1=cordPx-0.02 + cordpx1=cordPx1 + cordPx2=cordPx1+0.06 + cordpx2=cordPx2) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="x")) + cordR0x1=caar(INST~>bBox) + cordR0x2=caadr(INST~>bBox) + cordR0y2=cadadr(INST~>bBox)) + when((INST~>cellName=="M1_POLYmin")&&xy2==1.105&&xy1==0.11 + PolyM1x2=caadr(INST~>bBox)) + when((INST~>cellName=="M1_POLYmin")&&xy2==1.235&&xy1==1.19 + PolyM1x1=caar(INST~>bBox)) + )) + + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordPx cordPx1 cordPx2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST~>cellName=="M1_POLYmin")&&((xy2==1.105&&xy1==0.11)||(xy2==1.365&&xy1==0.11)) + when((cordnx1+0.06)-(PolyM1x2-0.03)<0.06 + XY=(cordnx1-0.04:xy2)) + when((cordnx1+0.06)-(PolyM1x2-0.03)>=0.06 + XY=(xy1:xy2)) + ActualPolyM1x2=car(XY) + dbSet(INST XY "xy")) + when((INST~>cellName=="M1_POLYmin")&&((xy2==1.235&&xy1==1.19)||(xy2==1.495&&xy1==1.19)) + when((PWidth<=0.21) + when((PolyM1x1+0.03)-(cordpx1-0.06)<0.06 + XY=(cordpx1+0.04:xy2)) + when((PolyM1x1+0.03)-(cordpx1-0.06)>=0.06 + XY=(xy1:xy2))) + when((PWidth>0.21) + XY=(cordpx1+0.15:xy2)) + ActualPolyM1x1=car(XY) + ActualPassPolyM1x1=ActualPolyM1x1 + dbSet(INST XY "xy")) + when(((INST->cellName=="gate.INV.0-L1_1-R") && (INST->name=="x")) + when(cordR0y2==2.95 + when(NWidth/8>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth/8<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-(NWidth/8)))) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.455:2.34) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.455:2.6) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.455:2.86) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.845:2.34) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.845:2.6) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.845:2.86) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) )) + when((cordR0y2==2.82)||(cordR0y2==2.69) + when((cordR0y2==2.82) + when(NWidth/7>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth/7<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-(NWidth/7)))) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox)) + when((cordR0y2==2.69) + when(NWidth/6>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth/6<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-(NWidth/6)))) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox)) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.455:2.34) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.455:2.6) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.845:2.34) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.845:2.6) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) )) + when((cordR0y2==2.56)||(cordR0y2==2.43) + when((cordR0y2==2.56) + when(NWidth/5>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth/5<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-(NWidth/5)))) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox)) + when((cordR0y2==2.43) + when(NWidth/4>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth/4<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-(NWidth/4)))) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox)) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.455:2.34) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) ) + dbCreateParamInstByMasterName(CellView "tsmc28" "M2_M1_2cut_p1_2" "layout" nil (0.845:2.34) "R0" 1 + list( list("column" "int" 1) + list("row" "int" 1) + list("layer1YEnclosure" "float" 0.005) + list("layer1XEnclosure" "float" 0.04) + list("layer2YEnclosure" "float" 0.03) + list("layer2XEnclosure" "float" 0.015) ) )) + when((cordR0y2==2.3)||(cordR0y2==2.17) + when((cordR0y2==2.3) + when(NWidth/3>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth/3<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-(NWidth/3)))) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox)) + when((cordR0y2==2.17) + when(NWidth/2>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth/2<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-(NWidth/2)))) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox))) + when(cordR0y2==2.04 + when(NWidth>=0.21 + dbReplaceProp(INST "n_contact_offset" "float" 0.06)) + when(NWidth<0.21 + dbReplaceProp(INST "n_contact_offset" "float" (0.47-0.2-NWidth))) + when((INST~>cellName=="M2_M1_2cut_p1_2")&&((xy1==0.455&&xy2==2.08)||(xy1==0.845&&xy2==2.08)) + dbDeleteObject(INST)) + cordx1=caar(INST~>bBox) + cordx2=caadr(INST~>bBox))) + )) + + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordPx cordPx1 cordPx2 xy1 xy2 XY bx1 bx2 by1 by2 diff) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.PPLUG.0")&&(xy1==1.13&&xy2==0.485) + when((cordx2>=ActualPolyM1x1+0.07) + Cordpassx2=cordx2 + XY=(cordx2-0.13:xy2)) + when((cordx2cellName=="stack.NPLUG.0")&&(xy1==0.165&&xy2==0.27) + when((cordx1<=ActualPolyM1x2-0.07) + XY=(cordx1+0.125:xy2)) + when((cordx1>ActualPolyM1x2-0.07) + XY=(ActualPolyM1x2+0.055:xy2)) + dbSet(INST XY "xy")) + )) + + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when((SHAPE~>layerName=="CO")&&((bx1==0.77&&by1==1.15)||(bx1==0.77&&by1==1.41)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.74:by1-0.01 cordpx1-0.07:by2+0.01)) + i = 0.77 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i+0.04:by2)) + when((i+0.15)>(cordpx1-0.07) + k=20 + i = 0.77) + when((i+0.15)<=(cordpx1-0.07) + k = k+1 + i = i + 0.11))) + when((SHAPE~>layerName=="CO")&&((bx1==0.46&&by1==1.15)||(bx1==0.46&&by1==1.41)) + dbDeleteObject(SHAPE) + dbCreateRect(CellView "M1" list(0.56:by1-0.01 cordnx1+0.07:by2+0.01)) + i = 0.5 + for(k 0 20 + dbCreateRect(CellView "CO" list(i:by1 i-0.04:by2)) + when((i-0.15)<(cordnx1+0.07) + k=20 + i = 0.5) + when((i-0.15)>=(cordnx1+0.07) + k = k+1 + i = i - 0.11))) + when((SHAPE~>layerName=="M1")&&(bx1==0.08)&&(by1==1.075) + pnts=list(ActualPolyM1x2:y1 ActualPolyM1x2:y2 ) + dbSet(SHAPE pnts "points")) ; moves the net connecting to the a0 + when((SHAPE~>layerName=="M2")&&(bx1==0.08)&&(by1==0.295) + pnts=list(ActualPolyM1x2:y1 ActualPolyM1x2:y2 ) + dbSet(SHAPE pnts "points")); moves the net connecting to the a0 + when((SHAPE~>layerName=="M1")&&(bx1==1.16)&&(by1==1.165) + pnts=list(ActualPolyM1x1:y1 ActualPolyM1x1:y2 ) + dbSet(SHAPE pnts "points")); moves the net connecting to the a1 + when((SHAPE~>layerName=="M2")&&(bx1==1.16)&&(by1==0.565) + pnts=list(ActualPolyM1x1:y1 ActualPolyM1x1:y2 ) + dbSet(SHAPE pnts "points")); moves the net connecting to the a1 + when((SHAPE~>layerName=="PO")&&((bx1==0.87&&by1==1.22)||(bx1==0.87&&by1==1.48)) + bbox=list(bx1:by1 ActualPolyM1x1:by2 ) + dbSet(SHAPE bbox "bBox")) ; moves the Poly connecting to the M1_Poly vias on the right side of the gate + when((SHAPE~>layerName=="PO")&&((bx1==0.065&&by1==1.09)||(bx1==0.065&&by1==1.35)) + bbox=list(ActualPolyM1x2:by1 bx2:by2 ) + dbSet(SHAPE bbox "bBox")) ; moves the Poly connecting to the M1_Poly vias on the left side of the gate + when((SHAPE~>layerName=="M1")&&(bx1==0.135)&&(by1==0.39) + when((cordx1<=ActualPolyM1x2-0.07) + pnts=list(x1:y1 cordx1+0.125:y2)) + when((cordx1>ActualPolyM1x2-0.07) + pnts=list(x1:y1 ActualPolyM1x2+0.055:y2)) + dbSet(SHAPE pnts "points")) ; Moves the M1 connecting the NPLUG to GND + when((SHAPE~>layerName=="M1")&&(bx1==0.835)&&(by1==0.39) + when((cordx2>=ActualPolyM1x1+0.07) + pnts=list(x1:y1 cordx2-0.13:y2 cordx2-0.13:y3)) + when((cordx2layerName=="M1")&&(bx1==0.74)&&(by1==0.88) + when((PWidth>0.21) + pnts=list(x1:y1 cordpx1+0.03:y2 cordpx1+0.03:y3 x4:y4)) + when((PWidth<=0.21) + pnts=list(x1:y1 x2:y2 x3:y3 x4:y4)) + dbSet(SHAPE pnts "points")) ; moves the M1 connecting the internal net of the C2_Stat on the right side of the leaf cell + when((SHAPE~>layerName=="M1")&&(bx1==0.235)&&(by1==2.95) + pnts=list(x1:y1 cordx1+0.07:y2 ) + dbSet(SHAPE pnts "points")) ; moves the M1 wire connecting the b net + when((SHAPE~>layerName=="M2")&&(bx1==0.22)&&(by1==1.86) + pnts=list(cordx1+0.07:y1 cordx1+0.07:y2 ) + dbSet(SHAPE pnts "points")) ; moves the M2 wire connecting the b input on the left side of the gate + when((SHAPE~>layerName=="prBoundary") + dbDeleteObject(SHAPE) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + pnts=list(cordx1-0.04:by1 cordx1-0.04:by2 cordx2+0.04:by2 cordx2+0.04:by1)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + pnts=list(ActualPolyM1x2-0.11:by1 ActualPolyM1x2-0.11:by2 cordx2+0.04:by2 cordx2+0.04:by1)) + when((cordx1>ActualPolyM1x2-0.07)&&(cordx2layerName=="M3")&&((bx1==0&&by1==0.025)||(bx1==0&&by1==1.465)||(bx1==0&&by1==1.585)||(bx1==0&&by1==3.025)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx1-0.04:by1 cordx2+0.04:by2) + LeftLeaf=cordx1-0.04 + RightLeaf=(cordx2+0.04)-(cordx1-0.04)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(ActualPolyM1x2-0.11:by1 cordx2+0.04:by2) + LeftLeaf=ActualPolyM1x2-0.11 + RightLeaf=(cordx2+0.04)-(ActualPolyM1x2-0.11)) + when((cordx1>ActualPolyM1x2-0.07)&&(cordx2layerName=="PO")&&((bx1==-0.005&&by1==0.05)||(bx1==-0.005&&by1==0.18)||(bx1==-0.005&&by1==0.83)||(bx1==-0.005&&by1==0.96)||(bx1==-0.005&&by1==1.09)||(bx1==-0.005&&by1==1.22)||(bx1==-0.005&&by1==1.35)||(bx1==-0.005&&by1==1.48)||(bx1==-0.005&&by1==1.61)||(bx1==-0.005&&by1==1.74)||(bx1==-0.005&&by1==1.87)||(bx1==-0.005&&by1==2)||(bx1==-0.005&&by1==2.13)||(bx1==-0.005&&by1==2.26)||(bx1==-0.005&&by1==2.39)||(bx1==-0.005&&by1==2.52)||(bx1==-0.005&&by1==2.65)||(bx1==-0.005&&by1==2.78)||(bx1==-0.005&&by1==2.91)||(bx1==-0.005&&by1==3.04)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx1-0.045:by1 cordx2+0.045:by2)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(ActualPolyM1x2-0.115:by1 cordx2+0.045:by2)) + when((cordx1>ActualPolyM1x2-0.07)&&(cordx2layerName=="PO")&&((bx1==0.245&&by1==0.31)||(bx1==0.245&&by1==0.44)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx1+0.205:by1 cordx2+0.045:by2)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(ActualPolyM1x2+0.135:by1 cordx2+0.045:by2)) + when((cordx1>ActualPolyM1x2-0.07)&&(cordx2layerName=="PO")&&((bx1==-0.005&&by1==0.57)||(bx1==-0.005&&by1==0.7)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx1-0.045:by1 cordx2-0.235:by2)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(ActualPolyM1x2-0.115:by1 cordx2-0.235:by2)) + when((cordx1>ActualPolyM1x2-0.07)&&(cordx2layerName=="PO")&&(bx1==-0.04&&by1==0) + when((cordx1<=ActualPolyM1x2-0.07) + bbox=list(cordx1-0.08:by1 cordx1:by2)) + when((cordx1>ActualPolyM1x2-0.07) + bbox=list(ActualPolyM1x2-0.16:by1 ActualPolyM1x2-0.07:by2)) + dbSet(SHAPE bbox "bBox")) ; Moves the cut_Poly on the left side + when((SHAPE~>layerName=="PO")&&(bx1==1.26&&by1==0) + when((cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx2:by1 cordx2+0.08:by2)) + when((cordx2layerName=="M3")&&((bx1==0.085&&by1==0.295)||(bx1==0.085&&by1==0.555)||(bx1==0.085&&by1==1.855)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx1:by1 cordx2:by2)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(ActualPolyM1x2-0.07:by1 cordx2:by2)) + when((cordx1>ActualPolyM1x2-0.07)&&(cordx2layerName=="NP")||(SHAPE~>layerName=="NW"))&&((bx1==0&&by1==2.99)||(bx1==0&&by2==0.13)||(bx1==0&&by1==1.585)||(bx1==0&&by1==3.025)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx1-0.04:by1 cordx2+0.04:by2)) + when((cordx1<=ActualPolyM1x2-0.07)&&(cordx2ActualPolyM1x2-0.07)&&(cordx2>=ActualPolyM1x1+0.07) + bbox=list(ActualPolyM1x2-0.11:by1 cordx2+0.04:by2)) + when((cordx1>ActualPolyM1x2-0.07)&&(cordx2layerName=="PP")&&(bx1==0&&by1==0.27) + when((cordx1<=ActualPolyM1x2-0.07) + bbox=list(cordx1-0.04:by1 cordx1+0.02:by2)) + when((cordx1>ActualPolyM1x2-0.07) + bbox=list(ActualPolyM1x2-0.11:by1 ActualPolyM1x2-0.05:by2)) + dbSet(SHAPE bbox "bBox")) ; Moves the PP layer next to the NPLUG on the left side + when((SHAPE~>layerName=="NP")&&(bx1==0&&by2==3.12) + when((cordx1<=ActualPolyM1x2-0.07) + pnts=list(x1:y1 cordx1-0.04:y2 cordx1-0.04:y3 cordx1+0.23:y4 cordx1+0.23:y5 cordx1-0.04:y6 cordx1-0.04:y7 x8:y8)) + when((cordx1>ActualPolyM1x2-0.07) + pnts=list(x1:y1 ActualPolyM1x2-0.11:y2 ActualPolyM1x2-0.11:y3 ActualPolyM1x2+0.16:y4 ActualPolyM1x2+0.16:y5 ActualPolyM1x2-0.11:y6 ActualPolyM1x2-0.11:y7 x8:y8)) + dbSet(SHAPE pnts "points")) ; Moves the NP layer on the left side + when((SHAPE~>layerName=="NP")&&(bx1==1.23&&by1==0.485) + when((cordx2>=ActualPolyM1x1+0.07) + bbox=list(cordx2-0.03:by1 cordx2+0.04:by2)) + when((cordx2layerName=="NW")||(SHAPE~>layerName=="PM"))&&(bx1==0.65&&by1==0.13) + when((cordx2>=ActualPolyM1x1+0.07) + bbox=list(bx1:by1 cordx2+0.04:by2)) + when((cordx2layerName=="PP")&&(bx1==0.65&&by1==0.13) + when((cordx2>=ActualPolyM1x1+0.07) + pnts=list(cordx2+0.04:y1 cordx2-0.235:y2 cordx2-0.235:y3 cordx2+0.04:y4 cordx2+0.04:y5 x6:y6 x7:y7 cordx2+0.04:y8)) + when((cordx2vias + (let (vx1 vy1 bx1 by1 bx2 by2 vx1 vy1 orgn) + bx1=caar(VIA~>bBox) + by1=cadar(VIA~>bBox) + bx2=caadr(VIA~>bBox) + by2=cadadr(VIA~>bBox) + vx1=car(VIA~>origin) + vy1=cadr(VIA~>origin) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==0.11) + orgn=(ActualPolyM1x2:vy1) + dbSet(VIA orgn "origin")) + when(((VIA~>viaHeader~>viaDefName=="M2_M1")||(VIA~>viaHeader~>viaDefName=="M3_M2"))&&(vx1==1.19) + orgn=(ActualPolyM1x1:vy1) + dbSet(VIA orgn "origin")) + when((VIA~>viaHeader~>viaDefName=="M2_M1")&&(vx1==0.25) + orgn=(cordx1+0.07:vy1) + dbSet(VIA orgn "origin")) + )) + )) +(defun CtreeCreator ( CellName ViewName ) + + let( ( k l m n y s z ce cel piecess piecesss cv ncv mcv lcv vcv TemplateCellName pieces LibName Temp LeftLeaf RightLeaf ActualPassPolyM1x1 Cordpassx2) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + k="0" + l="0" + m="0" + n="0" + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + TemplateCellName = "lib.util.ctree.CTREE2.ctreetemplate" + mcv=nrOpenCellViewReadable( LibName TemplateCellName "Template") + + when( cv != nil + printf( "CTREE type already exists %s\n" CellName) + ) + when( mcv == nil + printf("Template Cell doesnot exists %s\n" TemplateCellName)) + when( ((cv == nil)&&(mcv != nil)) + printf("yes\n") + dbCopyCellView(mcv LibName CellName "scratch" nil nil t) + ncv = nrOpenCellViewWritable( LibName CellName "scratch" ) + MakeCtree2( ncv ViewName) + dbSave(ncv) + dbPurge(ncv) + lcv = nrOpenCellViewWritable( LibName CellName ViewName ) + CopyBuffer( lcv ViewName LibName CellName )) + )) + +(defun CopyBuffer ( CellView ViewName LibName CellName ) + (let (xy1 xy2 XY bx1 bx2 by1 by2 buf rightcord RightCord pnts SHAPE) + when(minusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0.04:0 "R0")) + when(plusp(LeftLeaf) + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" LeftLeaf:0 "R0")) + when(LeftLeaf==0 + buf = dbCreateInstByMasterName(CellView LibName CellName "scratch" "buf" 0.04:0 "R0")) + foreach(INST CellView~>instances + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + XY=(-bx1:xy2) + dbSet(INST XY "xy")) + dbFlattenInst(buf 1) + rightcord=round(((RightLeaf/0.26)/0.5)*0.5+0.5) + RightCord=0.26*rightcord + pnts=list(0:by1+0.13 0:by2-0.13 RightCord:by2-0.13 RightCord:by1+0.13) + dbCreatePRBoundary(CellView pnts) + foreach(INST CellView->instances + (let (xy1 xy2 XY bx1 bx2 by1 by2) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + when((INST->cellName=="stack.PPLUG.0") + XY=(RightCord-0.17:xy2) + dbSet(INST XY "xy")) + )) + foreach(SHAPE CellView->shapes + (let (bx1 bx2 by1 by2 x1 x2 x3 x4 x5 x6 x7 x8 y1 y2 y3 y4 y5 y6 y7 y8 xy1 xy2 pnts bbox orgn) + bx1=caar(SHAPE~>bBox) + by1=cadar(SHAPE~>bBox) + bx2=caadr(SHAPE~>bBox) + by2=cadadr(SHAPE~>bBox) + xy1=car(SHAPE~>xy) + xy2=cadr(SHAPE~>xy) + x1=caar(SHAPE~>points) + y1=cadar(SHAPE~>points) + x2=caadr(SHAPE~>points) + y2=cadadr(SHAPE~>points) + x3=caaddr(SHAPE~>points) + y3=car(cdaddr(SHAPE~>points)) + x4=car(cadddr(SHAPE~>points)) + y4=cadr(cadddr(SHAPE~>points)) + x5=caar(cddddr(SHAPE~>points)) + y5=cadar(cddddr(SHAPE~>points)) + x6=caadr(cddddr(SHAPE~>points)) + y6=cadadr(cddddr(SHAPE~>points)) + x7=caaddr(cddddr(SHAPE~>points)) + y7=car(cdaddr(cddddr(SHAPE~>points))) + x8=car(cadddr(cddddr(SHAPE~>points))) + y8=cadr(cadddr(cddddr(SHAPE~>points))) + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="NP"))&&((by2==3.25&&by1==2.99)||(by2==0.13&&by1==-0.13)) + bbox=list(0:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/NP layers on top and bottom + when(((SHAPE~>layerName=="NW")||(SHAPE~>layerName=="PM"))&&by2==2.99&&by1==0.13 + bbox=list(bx1:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NW/PM layer on the right side of the leaf cell + when((SHAPE~>layerName=="PP")&&by2==2.99&&by1==0.13 + pnts=list(RightCord:y1 RightCord-0.275:y2 RightCord-0.275:y3 RightCord:y4 RightCord:y5 x6:y6 x7:y7 RightCord:y8) + dbSet(SHAPE pnts "points")) ; moves the PP layer on the right side of the leaf cell + when((SHAPE~>layerName=="NP")&&by2==1.01&&by1==0.485 + bbox=list(RightCord-0.07:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ; moves the NP layer on the right side of the leaf cell associated with PPLUG + when((SHAPE~>layerName=="M3")&&((by2==0.095&&by1==0.025)||(by2==1.535&&by1==1.465)||(by2==1.655&&by1==1.585)||(by2==3.095&&by1==3.025)) + bbox=list(0:by1 RightCord:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 power grid(GND/Vdd) wires + when((SHAPE~>layerName=="M3")&&((by2==0.355&&by1==0.295)||(by2==0.615&&by1==0.555)||(by2==1.915&&by1==1.855)) + bbox=list(0.04:by1 RightCord-0.04:by2) + dbSet(SHAPE bbox "bBox")) ;moves the M3 _RESET pin + when((SHAPE~>layerName=="M1")&&by2==0.69&&by1==0.39 + pnts=list(x1:y1 RightCord-0.17:y2 RightCord-0.17:y3) + dbSet(SHAPE pnts "points")) ; moves the M1 connecting the PPLUG to Vdd + )) + DeleteGridPoly(?CellView CellView) + DrawGridPoly(?CellView CellView) + ddDeleteObj(ddGetObj(LibName CellName "scratch")) + dbSave(CellView) + dbPurge(CellView) + ) +) + + +(defun Parameter ( CellName) + (let (fl pieces piece specname initialpath InitialPath IntermediatePath finalpath k text Variable1 cst FinalPath variable1 variable2 variable3 variable4 Variable3 Variable4 var3 var4 Var3 varb4 Varb3 Var4 Outfl) + println(CellName) + pieces=parseString( CellName "." ) + specname=nth( 4 pieces ) + cst=".cast" + IntermediatePath="/lib/util/ctree/CTREE2/" + initialpath=ConfigFileGetValue(TheCDSConfigTable "CAST_PATH") + piece=parseString( initialpath ":" ) + InitialPath=nth( 1 piece ) + finalpath=strcat(InitialPath IntermediatePath specname cst) + fl = infile(finalpath) + Outfl = outfile("Parameter.txt" "w") + while( gets(k fl) != nil + text = parseString( k " \n") + Variable1 = nth(0 text) + when((Variable1=="Xx") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(6 text) + Variable3=nth(7 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(8 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) + when((Variable1=="Xb") + variable1=car(parseString( Variable1 "X" )) + variable2=nth(8 text) + Variable3=nth(9 text) + Var3=parseString( Variable3 "=" ) + Varb3=nth( 1 Var3) + var3=parseString( Varb3 "u" ) + variable3=nth( 0 var3) + Variable4=nth(10 text) + Var4=parseString( Variable4 "=" ) + Varb4=nth( 1 Var4) + var4=parseString( Varb4 "u" ) + variable4=nth( 0 var4) + fprintf(Outfl "%s" variable1 ) + fprintf(Outfl " %s" variable2 ) + fprintf(Outfl " %s" variable3 ) + fprintf(Outfl " %s\n" variable4 ) + ) +) + close(Outfl) + close(fl) + )) +(defun Ctree ( CellName) + printf("Cell is %s\n" CellName) + Parameter(CellName) + CtreeCreator(CellName "layout") +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/DrawImplant.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/DrawImplant.il new file mode 100644 index 0000000000..d1f5e2445a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/DrawImplant.il @@ -0,0 +1,788 @@ +(defun MakeHVT (CellView ViewName) + +; dbCopyCellView(cv LibName newCellName ViewName) +; ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + vthn_shapes=setof( shape CellView->shapes + ( shape->lpp==NImplantLPP || shape->lpp==PImplantLPP )&& + cond( ( shape->objType=="polygon" && shape->nPoints > 4 shape->lpp==NImplantLPP ) + (t dbGetTrueOverlaps(CellView list(leftEdge(shape->bBox)+0.005:bottomEdge(shape->bBox)+0.005 rightEdge(shape->bBox)-0.005:topEdge(shape->bBox)-0.005 ) NWellLPP 1)==nil ) + ) + ) + foreach( shape vthn_shapes + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTH_N" layerName) + SetImpProp(newshape) + ) + vthp_shapes=setof( shape CellView->shapes (shape->lpp==PImplantLPP || shape->lpp==NImplantLPP ) && + cond( (shape->objType=="polygon" && shape->nPoints > 4 shape->lpp==PImplantLPP ) + (t dbGetTrueOverlaps(CellView list(leftEdge(shape->bBox)+0.005:bottomEdge(shape->bBox)+0.005 rightEdge(shape->bBox)-0.005:topEdge(shape->bBox)-0.005 ) NWellLPP 1)!=nil ) + ) + ) + foreach( shape vthp_shapes + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTH_P" layerName) + SetImpProp(newshape) + ) + + + + + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L3_3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->cellName=="M1_SUBmin" + c=inst->bBox + dbCreateRect(CellView "VTH_N" c) + ) +) + foreach(inst CellView->instances + when( inst->cellName=="M1_SUB" + c=inst->bBox + dbCreateRect(CellView "VTH_N" c) + ) +) + foreach(inst CellView->instances + when( inst->cellName=="M1_NWmin" + c=inst->bBox + dbCreateRect(CellView "VTH_P" c) + ) +) + + foreach(inst CellView->instances + when( inst->cellName=="M1_NW" + c=inst->bBox + dbCreateRect(CellView "VTH_P" c) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + +(defun MakeHSVT (CellView ViewName) + + + foreach(shape CellView->shapes + when( shape->lpp==NImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTH_N" layerName) + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L3_1-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + x=nth(1 pieces) + y = parseString(x "_") + when(nth(0 y)=="NMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + +(defun MakeHLVT (CellView ViewName) + + + foreach(shape CellView->shapes + when( shape->lpp==NImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTH_N" layerName) + SetImpProp(newshape) + ) + when( shape->lpp==PImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTL_P" layerName) + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L3_2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + x=nth(1 pieces) + y = parseString(x "_") + when(nth(0 y)=="NMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + when(nth(0 y)=="PMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + +(defun MakeLHVT (CellView ViewName) + + + foreach(shape CellView->shapes + when( shape->lpp==NImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTL_N" layerName) + SetImpProp(newshape) + ) + when( shape->lpp==PImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTH_P" layerName) + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L2_3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + x=nth(1 pieces) + y = parseString(x "_") + when(nth(0 y)=="NMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + when(nth(0 y)=="PMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + +(defun MakeLSVT (CellView ViewName) + + + foreach(shape CellView->shapes + when( shape->lpp==NImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTL_N" layerName) + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L2_1-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + x=nth(1 pieces) + y = parseString(x "_") + when(nth(0 y)=="NMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + + +(defun MakeSHVT (CellView ViewName) + + + foreach(shape CellView->shapes + when( shape->lpp==PImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTH_P" layerName) + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L1_3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + x=nth(1 pieces) + y = parseString(x "_") + when(nth(0 y)=="PMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L3-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + +(defun MakeSLVT (CellView ViewName) + + + foreach(shape CellView->shapes + when( shape->lpp==PImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTL_P" layerName) + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L1_2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + x=nth(1 pieces) + y = parseString(x "_") + when(nth(0 y)=="PMOS" + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil )) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + + +(defun MakeLVT (CellView ViewName) + + foreach(shape CellView->shapes + when( shape->lpp==NImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTL_N" layerName) + SetImpProp(newshape) + ) + when( shape->lpp==PImplantLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "VTL_P" layerName) + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L2_2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L2-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + +(defun MakeSVT (CellView ViewName) + + foreach(shape CellView->shapes + when( shape->lpp==NVtlLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "NP" layerName) + DeleteImpl() + SetImpProp(newshape) + ) + when( shape->lpp==NVhtLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "NP" layerName) + DeleteImpl() + SetImpProp(newshape) + ) + when( shape->lpp==PVtlLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "PP" layerName) + DeleteImpl() + SetImpProp(newshape) + ) + when( shape->lpp==PVhtLPP + newshape=dbCopyShape(shape CellView) + dbSetq(newshape "PP" layerName) + DeleteImpl() + SetImpProp(newshape) + ) + ) + + foreach(inst CellView->instances + when( inst->libName=="gate" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "gate" "." nth(1 pieces) "." "0-L1_1-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + foreach(inst CellView->instances + when( inst->libName=="stack" + cell = inst->cellName + pieces = parseString( cell "." ) + newcell = strcat( "stack" "." nth(1 pieces) "." "0-L1-R" ) + (leReplaceAnyInstMaster inst inst->libName newcell nil ) + ) +) + + dbSave( CellView ) + dbClose( CellView ) + +) + +; defining a implant property +(defun SetImpProp (obj) + (when obj + (dbReplaceProp obj "impl" "boolean" t) + ) +) + +(defun IsImpObject (obj) + (let (isImpl) + isImpl = nil + (when obj + (when (dbGetPropByName obj "impl")->value=="TRUE" + isImpl=t + ) + ) + isImpl + + ) +) + + + +;deletes implants + +(defun DeleteImpl () + (let (view shapes) + view = (geGetEditCellView) + shapes = (setof obj ncv->shapes (IsImpObject obj)) + (foreach shape shapes (dbDeleteObject shape)) + ) + t + ) + +(defun DELCell (CellName ViewName) + let((shape inst cv ncv mcv lcv newCellName pieces LibName) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_hvt") + mcv=nrOpenCellViewReadable( LibName newCellName ViewName) + lcv=nrOpenCellViewWritable( LibName newCellName ViewName) + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( mcv == nil + printf( "Cannot open HVT subtype %s\n" CellName) + ) + when( lcv == nil + printf( "HVT subtype already checked in %s\n" CellName) + ) + when( ((cv != nil)&&(mcv != nil)&&(lcv != nil)) +; foreach(shape mcv->shapes (dbDeleteObject shape)) +; foreach(inst cv->instances (dbDeleteObject inst)) + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeHVT( ncv ViewName) +))) + +(defun MakeHVTCell ( CellName ViewName ) + let( ( k l m n y s z ce cel piecess piecesss cv ncv mcv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + k="0" + l="0" + m="0" + n="0" + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_hvt") + mcv=nrOpenCellViewReadable( LibName newCellName ViewName) + foreach(x cv->shapes + when(((x->lpp==PVtlLPP)||(x->lpp==NVtlLPP)) + k="1")) + foreach(y cv->instances + when((y->libName=="gate") + ce = y->cellName + piecess = parseString(ce ".") + when(((nth(2 piecess)=="0-L2_2-R")||(nth(2 piecess)=="0-L2_1-R")||(nth(2 piecess)=="0-L1_2-R")||(nth(2 piecess)=="0-L1_3-R")||(nth(2 piecess)=="0-L3_1-R")) + l="1"))) + foreach(z cv->instances + when((z->libName=="stack") + cel = z->cellName + piecesss = parseString(cel ".") + when((nth(2 piecesss)=="0-L2-R") + m="1" ))) + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( mcv != nil + printf("HVT subtype already exists %s\n" newCellName)) + when( ((k=="1")||(l=="1")||(m=="1")) + printf("Cannot open %s. Cell has both lvt and hvt instances \n" CellName)) + when( ((cv != nil)&&(mcv == nil)&&(k!="1")&&(l!="1")&&(m!="1")) + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeHVT( ncv ViewName) + ) + ) + ) + +(defun MakeHSVTCell ( CellName ViewName ) + let( ( cv ncv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_hsvt") + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( cv != nil + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeHSVT( ncv ViewName) + ) + ) + ) + +(defun MakeSHVTCell ( CellName ViewName ) + let( ( cv ncv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_shvt") + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( cv != nil + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeSHVT( ncv ViewName) + ) + ) + ) + +(defun MakeSLVTCell ( CellName ViewName ) + let( ( cv ncv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_slvt") + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( cv != nil + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeSLVT( ncv ViewName) + ) + ) + ) + +(defun MakeLSVTCell ( CellName ViewName ) + let( ( cv ncv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_lsvt") + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( cv != nil + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeLSVT( ncv ViewName) + ) + ) + ) + +(defun MakeHLVTCell ( CellName ViewName ) + let( ( cv ncv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_hlvt") + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( cv != nil + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeHLVT( ncv ViewName) + ) + ) + ) + +(defun MakeLHVTCell ( CellName ViewName ) + let( ( cv ncv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_lhvt") + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( cv != nil + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeLHVT( ncv ViewName) + ) + ) + ) + +(defun MakeLVTCell ( CellName ViewName ) + let( ( k l y z ce cv cel piecess piecesss ncv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + k="0" + l="0" + m="0" + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CellName "_lvt") + foreach(x cv->shapes + when(((x->lpp==PVhtLPP)||(x->lpp==NVhtLPP)) + k="1")) + foreach(y cv->instances + when((y->libName=="gate") + ce = y->cellName + piecess = parseString(ce ".") + when(((nth(2 piecess)=="0-L3_3-R")||(nth(2 piecess)=="0-L3_1-R")||(nth(2 piecess)=="0-L1_3-R")||(nth(2 piecess)=="0-L1_2-R")||(nth(2 piecess)=="0-L2_1-R")) + l="1"))) + foreach(z cv->instances + when((z->libName=="stack") + cel = z->cellName + piecesss = parseString(cel ".") + when((nth(2 piecesss)=="0-L3-R") + m="1" ))) + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( ((k=="1")||(l=="1")||(m=="1")) + printf("Cannot open %s. Cell has both lvt and hvt instances \n" CellName)) + when( ((cv != nil)&&(k!="1")&&(l!="1")&&(m!="1")) + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeLVT( ncv ViewName) + ) + ) + ) + +(defun MakeSVTCell ( CellName ViewName ) + let( ( cv ncv newCellName pieces LibName CName) + pieces=parseString( CellName "." ) + CNames=parseString( CellName "_" ) + CName=nth( 0 CNames ) + for( n 1 length(CNames)-2 + CName = strcat( CName "_" nth( n CNames))) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + newCellName = strcat(CName "_svt") + when( cv == nil + printf( "Cannot open %s\n" CellName) + ) + when( cv != nil + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + MakeSVT( ncv ViewName) + ) + ) + ) + +(defun hvt () + (let (text CellName) + fl = infile("list_1.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + CellName = nth(0 text) + MakeHVTCell(CellName "layout") +))) + +(defun hvtdel () + (let (text CellName) + fl = infile("list_1.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + CellName = nth(0 text) + DELCell(CellName "layout") +))) + +(defun hlvt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeHLVTCell(CellName "layout") +))) + +(defun lhvt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeLHVTCell(CellName "layout") +))) + +(defun shvt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeSHVTCell(CellName "layout") +))) + +(defun hsvt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeHSVTCell(CellName "layout") +))) + +(defun lsvt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeLSVTCell(CellName "layout") +))) + +(defun slvt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeSLVTCell(CellName "layout") +))) + +(defun lvt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeLVTCell(CellName "layout") +))) + +(defun svt () + (let (text CellName) + fl = infile("/home/user/vjain/alpine/MakeVTH.list") + while( gets(k fl) != nil + text = parseString( k "\n") + CellName = nth(0 text) + MakeSVTCell(CellName "layout") +))) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/Implant.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/Implant.il new file mode 100644 index 0000000000..5ff7420083 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/Implant.il @@ -0,0 +1,653 @@ +(defvar Scratch0LPP ( list "y0" "drawing" ) ) +(defvar Scratch1LPP ( list "y1" "drawing" ) ) +(defvar Scratch2LPP ( list "y5" "drawing" ) ) +(defvar Scratch3LPP ( list "y6" "drawing" ) ) +(defvar Scratch4LPP ( list "y7" "drawing" ) ) +(defvar Scratch5LPP ( list "y8" "drawing" ) ) +(defun SetImpProp (obj) + (when obj + (dbReplaceProp obj "Imp_prop" "boolean" t) + ) +) + +;;;;;;;;Deletes Implants in a leaf cell;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun DeleteImplant ( @key (CellView (geGetEditCellView)) ) + let( (CellView shape) + CellView=geGetEditCellView() + foreach(shape CellView-> shapes + (when (dbGetPropByName shape "Imp_prop")->value=="TRUE" + dbDeleteObject(shape) + )) + )) + + +;;;;;;;;Draws Implants in a leaf cell;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun Implant ( @key (CellView (geGetEditCellView)) ) + let( (CellView left bx1 bx2 by1 by2 right top bottom ixy1 toplimit rightlimit lastPolyx initialPP initialPP1 initialPP2 initialNP initialNP1 initialNP2 i j k l x y y1 x1 newshape overlapNP overlapPP overlapNP2 overlapPP2 overlapNP3 overlapPP3 overlapNPBoth overlapPPBoth overlapNPBoth2 overlapPPBoth2 overlapSCN3 overlapSCP3 overlapSCN32 overlapSCP32 overlapSCN33 overlapSCP33 item SHP Flip Flip1 Flip2 NPimp NPimp1 PPimp PPimp1 NWimp PMimp Imp1 Imp2 Imp3 Imp4 imp1 imp2 imp3 imp4 Shape1 Shape2 Shape3 overlapSC3NP2 overlapSC3NP1 overlapSC3PP2 overlapSC3PP1 overlpy1 overlpy2 overlny1 overlny2 layer) + + CellView=geGetEditCellView() + i=0 + j=0 + k=0 + l=0 + ixy1=0 + declare(anx[10]) + declare(bnx[10]) + declare(any[10]) + declare(bny[10]) + declare(apx[10]) + declare(bpx[10]) + declare(apy[10]) + declare(bpy[10]) + overlapNP=nil + overlapPP=nil + overlapNP2=nil + overlapPP2=nil + overlapNP3=nil + overlapPP3=nil + overlapNPBoth=nil + overlapPPBoth=nil + overlapNPBoth2=nil + overlapPPBoth2=nil + overlapSCN3=nil + overlapSCN32=nil + overlapSCN33=nil + overlapSCP3=nil + overlapSCP32=nil + overlapSCP33=nil + + + + ;locating PrBound + GetPrbound(CellView) + left=caar(GetPrbound(CellView)->bBox) + bottom=cadar(GetPrbound(CellView)->bBox) + right=caadr(GetPrbound(CellView)->bBox) + top=cadadr(GetPrbound(CellView)->bBox) + + ;locating the left most instance type + foreach(INST CellView->instances + (let (cordNx cordNx1 cordNx2 cordPx cordPx1 cordPx2 xy1 xy2 XY diff Instname pieces piecess LibName libname chainname stackname) + xy1=car(INST~>xy) + xy2=cadr(INST~>xy) + bx1=caar(INST~>bBox) + by1=cadar(INST~>bBox) + bx2=caadr(INST~>bBox) + by2=cadadr(INST~>bBox) + Instname=INST->cellName + pieces=parseString( Instname "." ) + LibName=nth( 0 pieces ) + when((LibName=="stack") + libname=nth( 1 pieces ) + piecess=parseString( libname "_" ) + chainname=nth(0 piecess) + stackname = strcat( LibName "." chainname )) + when((stackname=="stack.NMOS")||(LibName=="gate")||(stackname=="stack.PMOS") + when((LibName=="gate")&&(ixy1==0) + when((INST~>orient=="R0")||(INST~>orient=="MX") + Flip = 0) + when((INST~>orient=="R180")||(INST~>orient=="MY") + Flip = 1) + ixy1=xy1) + when((LibName=="gate")&&(ixy1!=0) + when(xy1orient=="R0")||(INST~>orient=="MX") + Flip = 0) + when((INST~>orient=="R180")||(INST~>orient=="MY") + Flip = 1) + ixy1=xy1)) + when((stackname=="stack.NMOS")&&(ixy1==0) + Flip = 0 + ixy1=xy1) + when((stackname=="stack.NMOS")&&(ixy1!=0) + when(xy1 shapes + (when (dbGetPropByName shape "Imp_prop")->value=="TRUE" + dbDeleteObject(shape) + )) + + foreach(shape CellView-> shapes + when( (shape->lpp== Scratch1LPP)&&(shape==newshape) + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapNP=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) PImplantLPP 2) + overlapNPBoth=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) NImplantLPP 2) + overlapSCN3=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) Scratch3LPP 0) + when(overlapSCN3!=nil + overlny1=cadar(car(overlapSCN3~>bBox)) + overlny2=cadadr(car(overlapSCN3~>bBox)) + overlapSC3PP1=dbGetTrueOverlaps(CellView list(bx1+0.005:0.13 bx2-0.005:overlny1-0.025) PImplantLPP 2) + overlapSC3PP2=dbGetTrueOverlaps(CellView list(bx1+0.005:overlny2+0.005 bx2-0.005:toplimit) PImplantLPP 2) + ) + ; checks for overlaps of both NP/PP layer with Scratch 1 layer and switches the Scratch layer drawing to 0.065 pitch + when(((overlapNP!=nil)&&(overlapSCN3==nil)&&(overlapNPBoth!=nil))||((overlapSCN3!=nil)&&((overlapSC3PP1!=nil)||(overlapSC3PP2!=nil))) + dbDeleteObject(shape) + Flip1=0 + y = bottom + 0.13 + while( y < toplimit+0.13 + when(Flip1==0 + when(initialNP1==1 + initialNP1=0 + y=y-0.065) + newshape=dbCreateRect(CellView Scratch1LPP + list( x: y x+0.065: y + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch1LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapNP2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) PImplantLPP 2) + overlapNPBoth2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) NImplantLPP 2) + overlapSCN32=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) Scratch3LPP 0) + when((overlapNP2!=nil)&&(overlapSCN32==nil)&&(overlapNPBoth2!=nil) + dbDeleteObject(shape) + Flip2=0 + layer=0 + while( x1 shapes + when( shape->lpp== Scratch1LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapNP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) PImplantLPP 2) + overlapSCN33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapNP3!=nil)&&(overlapSCN33==nil) + Flip2 = 1 + initialPP2 = 1 + dbDeleteObject(shape) + )))) + when(Flip2==1 + newshape=dbCreateRect(CellView Scratch2LPP + list( x1: y1 x1+0.005: y1 + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch2LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapPP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) NImplantLPP 2) + overlapSCP33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapPP3!=nil)&&(overlapSCP33==nil) + Flip2 = 0 + initialNP2 = 1 + dbDeleteObject(shape) + )))) + when(y1==0.13 + Shape1=newshape) + when(y1==0.195 + Shape2=newshape) + when((y1==0.26)&&(newshape~>lpp==Scratch2LPP) + layer=1 + dbCreateRect(CellView Scratch2LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch2LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + when((y1==0.26)&&(newshape~>lpp==Scratch1LPP) + layer=2 + dbCreateRect(CellView Scratch1LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch1LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + y1 = y1 + 0.065) + x1 = x1 + 0.005) + when(((layer==1)&&(Shape1==Scratch1LPP)&&(Shape1==Scratch1LPP))||((layer==2)&&(Shape1==Scratch2LPP)&&(Shape1==Scratch2LPP)) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2)) + y = toplimit+0.13 + + ) + + + when((overlapNP2!=nil)&&(overlapSCN32==nil)&&(overlapNPBoth2==nil) + Flip1 = 1 + initialPP1 = 1 + dbDeleteObject(shape) + )))) + when(Flip1==1 + newshape=dbCreateRect(CellView Scratch2LPP + list( x: y x+0.065: y + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch2LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapPP2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) NImplantLPP 2) + overlapPPBoth2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) PImplantLPP 2) + overlapSCP32=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) Scratch3LPP 0) + when((overlapPP2!=nil)&&(overlapSCP32==nil)&&(overlapPPBoth2!=nil) + dbDeleteObject(shape) + Flip2=0 + layer=0 + while( x1 shapes + when( shape->lpp== Scratch1LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapNP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) PImplantLPP 2) + overlapSCN33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapNP3!=nil)&&(overlapSCN33==nil) + Flip2 = 1 + initialPP2 = 1 + dbDeleteObject(shape) + )))) + when(Flip2==1 + newshape=dbCreateRect(CellView Scratch2LPP + list( x1: y1 x1+0.005: y1 + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch2LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapPP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) NImplantLPP 2) + overlapSCP33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapPP3!=nil)&&(overlapSCP33==nil) + Flip2 = 0 + initialNP2 = 1 + dbDeleteObject(shape) + )))) + when(y1==0.13 + Shape1=newshape) + when(y1==0.195 + Shape2=newshape) + when((y1==0.26)&&(newshape~>lpp==Scratch2LPP) + layer=1 + dbCreateRect(CellView Scratch2LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch2LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + when((y1==0.26)&&(newshape~>lpp==Scratch1LPP) + layer=2 + dbCreateRect(CellView Scratch1LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch1LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + + y1 = y1 + 0.065) + x1 = x1 + 0.005) + when(((layer==1)&&(Shape1==Scratch1LPP)&&(Shape1==Scratch1LPP))||((layer==2)&&(Shape1==Scratch2LPP)&&(Shape1==Scratch2LPP)) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2)) + y = toplimit+0.13 + + ) + + when((overlapPP2!=nil)&&(overlapSCP32==nil)&&(overlapPPBoth2==nil) + Flip1 = 0 + initialNP1 = 1 + dbDeleteObject(shape) + )))) + when(y==0.13 + Shape1=newshape) + when(y==0.195 + Shape2=newshape) + when((y==0.26)&&(newshape~>lpp==Scratch2LPP) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2) + dbCreateRect(CellView Scratch2LPP + list( x: 0.13 x+0.065: 0.195 ) ) + dbCreateRect(CellView Scratch2LPP + list( x: 0.195 x+0.065: 0.26 ) ) + ) + when((y==0.26)&&(newshape~>lpp==Scratch1LPP) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2) + dbCreateRect(CellView Scratch1LPP + list( x: 0.13 x+0.065: 0.195 ) ) + dbCreateRect(CellView Scratch1LPP + list( x: 0.195 x+0.065: 0.26 ) ) + ) + y = y + 0.065) + ) + when((overlapNP!=nil)&&(overlapSCN3==nil)&&(overlapNPBoth==nil) + Flip = 1 + initialPP = 1 + dbDeleteObject(shape) + )))) +; starts drawing Scratch 2 layer + when(Flip==1 + newshape=dbCreateRect(CellView Scratch2LPP + list( x: y x+0.065: y + toplimit ) ) + foreach(shape CellView-> shapes + when( (shape->lpp== Scratch2LPP)&&(shape==newshape) + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapPP=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) NImplantLPP 2) + overlapPPBoth=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) PImplantLPP 2) + overlapSCP3=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) Scratch3LPP 0) + when(overlapSCP3!=nil + overlpy1=cadar(car(overlapSCP3~>bBox)) + overlpy2=cadadr(car(overlapSCP3~>bBox)) + overlapSC3NP1=dbGetTrueOverlaps(CellView list(bx1+0.005:0.13 bx2-0.005:overlpy1-0.025) NImplantLPP 2) + overlapSC3NP2=dbGetTrueOverlaps(CellView list(bx1+0.005:overlpy2+0.005 bx2-0.005:toplimit) NImplantLPP 2) + ) + when(((overlapPP!=nil)&&(overlapSCP3==nil)&&(overlapPPBoth!=nil))||((overlapSCP3!=nil)&&((overlapSC3NP1!=nil)||(overlapSC3NP2!=nil))) + dbDeleteObject(shape) + Flip1=1 + y = bottom + 0.13 + while( y < toplimit+0.13 + when(Flip1==0 + when(initialNP1==1 + initialNP1=0 + y=y-0.065) + newshape=dbCreateRect(CellView Scratch1LPP + list( x: y x+0.065: y + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch1LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapNP2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) PImplantLPP 2) + overlapNPBoth2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) NImplantLPP 2) + overlapSCN32=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) Scratch3LPP 0) + when((overlapNP2!=nil)&&(overlapSCN32==nil)&&(overlapNPBoth2!=nil) + dbDeleteObject(shape) + Flip2=0 + layer=0 + while( x1 shapes + when( shape->lpp== Scratch1LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapNP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) PImplantLPP 2) + overlapSCN33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapNP3!=nil)&&(overlapSCN33==nil) + Flip2 = 1 + initialPP2 = 1 + dbDeleteObject(shape) + )))) + when(Flip2==1 + newshape=dbCreateRect(CellView Scratch2LPP + list( x1: y1 x1+0.005: y1 + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch2LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapPP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) NImplantLPP 2) + overlapSCP33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapPP3!=nil)&&(overlapSCP33==nil) + Flip2 = 0 + initialNP2 = 1 + dbDeleteObject(shape) + )))) + when(y1==0.13 + Shape1=newshape) + when(y1==0.195 + Shape2=newshape) + when((y1==0.26)&&(newshape~>lpp==Scratch2LPP) + layer=1 + dbCreateRect(CellView Scratch2LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch2LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + when((y1==0.26)&&(newshape~>lpp==Scratch1LPP) + layer=2 + dbCreateRect(CellView Scratch1LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch1LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + y1 = y1 + 0.065) + x1 = x1 + 0.005) + when(((layer==1)&&(Shape1==Scratch1LPP)&&(Shape1==Scratch1LPP))||((layer==2)&&(Shape1==Scratch2LPP)&&(Shape1==Scratch2LPP)) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2)) + y = toplimit+0.13 + ) + + when((overlapNP2!=nil)&&(overlapSCN32==nil)&&(overlapNPBoth2==nil) + Flip1 = 1 + initialPP1 = 1 + dbDeleteObject(shape) + )))) + when(Flip1==1 + newshape=dbCreateRect(CellView Scratch2LPP + list( x: y x+0.065: y + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch2LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapPP2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) NImplantLPP 2) + overlapPPBoth2=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) PImplantLPP 2) + overlapSCP32=dbGetTrueOverlaps(CellView list(bx1+0.005:by1+0.005 bx2-0.005:by2-0.025) Scratch3LPP 0) + when((overlapPP2!=nil)&&(overlapSCP32==nil)&&(overlapPPBoth2!=nil) + dbDeleteObject(shape) + Flip2=0 + layer=0 + while( x1 shapes + when( shape->lpp== Scratch1LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapNP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) PImplantLPP 2) + overlapSCN33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapNP3!=nil)&&(overlapSCN33==nil) + Flip2 = 1 + initialPP2 = 1 + dbDeleteObject(shape) + )))) + when(Flip2==1 + newshape=dbCreateRect(CellView Scratch2LPP + list( x1: y1 x1+0.005: y1 + 0.065 ) ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch2LPP + bx1=caar(shape~>bBox) + by1=cadar(shape~>bBox) + bx2=caadr(shape~>bBox) + by2=cadadr(shape~>bBox) + overlapPP3=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) NImplantLPP 2) + overlapSCP33=dbGetTrueOverlaps(CellView list(bx1+0.001:by1+0.005 bx2-0.001:by2-0.025) Scratch3LPP 0) + when((overlapPP3!=nil)&&(overlapSCP33==nil) + Flip2 = 0 + initialNP2 = 1 + dbDeleteObject(shape) + )))) + when(y1==0.13 + Shape1=newshape) + when(y1==0.195 + Shape2=newshape) + when((y1==0.26)&&(newshape~>lpp==Scratch2LPP) + layer=1 + dbCreateRect(CellView Scratch2LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch2LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + when((y1==0.26)&&(newshape~>lpp==Scratch1LPP) + layer=2 + dbCreateRect(CellView Scratch1LPP + list( x1: 0.13 x1+0.005: 0.195 ) ) + dbCreateRect(CellView Scratch1LPP + list( x1: 0.195 x1+0.005: 0.26 ) ) + ) + y1 = y1 + 0.065) + x1 = x1 + 0.005) + when(((layer==1)&&(Shape1==Scratch1LPP)&&(Shape1==Scratch1LPP))||((layer==2)&&(Shape1==Scratch2LPP)&&(Shape1==Scratch2LPP)) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2)) + y = toplimit+0.13 + ) + + when((overlapPP2!=nil)&&(overlapSCP32==nil)&&(overlapPPBoth2==nil) + Flip1 = 0 + initialNP1 = 1 + dbDeleteObject(shape) + )))) + when(y==0.13 + Shape1=newshape) + when(y==0.195 + Shape2=newshape) + when((y==0.26)&&(newshape~>lpp==Scratch2LPP) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2) + dbCreateRect(CellView Scratch2LPP + list( x: 0.13 x+0.065: 0.195 ) ) + dbCreateRect(CellView Scratch2LPP + list( x: 0.195 x+0.065: 0.26 ) ) + ) + when((y==0.26)&&(newshape~>lpp==Scratch1LPP) + dbDeleteObject(Shape1) + dbDeleteObject(Shape2) + dbCreateRect(CellView Scratch1LPP + list( x: 0.13 x+0.065: 0.195 ) ) + dbCreateRect(CellView Scratch1LPP + list( x: 0.195 x+0.065: 0.26 ) ) + ) + y = y + 0.065) + ) + when((overlapPP!=nil)&&(overlapSCP3==nil)&&(overlapPPBoth==nil) + Flip = 0 + initialNP = 1 + dbDeleteObject(shape) + )))) + y = y + toplimit) + x = x + 0.065) + NPimp1=leLayerAndNot(CellView Scratch1LPP Scratch2LPP Scratch4LPP) + NPimp=leLayerAndNot(CellView Scratch4LPP Scratch3LPP NImplantLPP) + PPimp1=leLayerAndNot(CellView Scratch2LPP Scratch1LPP Scratch5LPP) + PPimp=leLayerAndNot(CellView Scratch5LPP Scratch3LPP PImplantLPP) + NWimp=leLayerAndNot(CellView Scratch2LPP Scratch1LPP NWellLPP) + PMimp=leLayerAndNot(CellView Scratch2LPP Scratch1LPP PMetLPP) + foreach( item NPimp + SetImpProp(item) + ) + foreach( item PPimp + SetImpProp(item) + ) + foreach( item NWimp + SetImpProp(item) + ) + foreach( item PMimp + SetImpProp(item) + ) + foreach(shape CellView-> shapes + when( shape->lpp== Scratch1LPP || shape->lpp== Scratch2LPP || shape->lpp== Scratch3LPP || shape->lpp== Scratch4LPP || shape->lpp== Scratch5LPP + dbDeleteObject(shape) + )) + Imp1=dbCreateRect(CellView NImplantLPP list(left:bottom-0.13 right:bottom+0.13)) + Imp2=dbCreateRect(CellView NWellLPP list(left:bottom-0.13 right:bottom+0.13)) + Imp3=dbCreateRect(CellView NImplantLPP list(left:top+0.13 right:top-0.13)) + Imp4=dbCreateRect(CellView NWellLPP list(left:top+0.13 right:top-0.13)) + imp1=list(Imp1) + imp2=list(Imp2) + imp3=list(Imp3) + imp4=list(Imp4) + foreach( item imp1 + SetImpProp(item) + ) + foreach( item imp2 + SetImpProp(item) + ) + foreach( item imp3 + SetImpProp(item) + ) + foreach( item imp4 + SetImpProp(item) + ) + + ) + ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/LayoutGridPoly.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/LayoutGridPoly.il new file mode 100644 index 0000000000..733b46b84c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/LayoutGridPoly.il @@ -0,0 +1,274 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Draw Grid Poly and CPO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; identify tool version, set as a cell property +gridPolyVersion = 4 + +; find cells with old grid poly and edit them +oldGridPolyFilter = (lambda (CV) + (dbGetPropByName CV "LeafCell")->value=="TRUE" && (OldGridPoly CV)) +(defun FindOldGridPolyLeaves (@key (CV (geGetEditCellView))) + (FindSubcells ?filter oldGridPolyFilter ?action editCellAction) + ) + +; Is CV gridPolyVersion < current gridPolyVersion? +(defun OldGridPoly (CV) + !(dbGetPropByName CV "gridPolyVersion") || + (dbGetPropByName CV "gridPolyVersion")->value < gridPolyVersion + ) + +; set the palette for manual CPO fixing +(defun CpoPalette () + (leSetEntryLayer (list "PO" "test1")) + (leSetAllLayerVisible nil) + (leSetAllLayerSelectable nil) + (leSetLayerVisible (list "PO" "drawing") t) + (leSetLayerVisible (list "PO" "grd") t) + (leSetLayerVisible (list "PO" "test1") t) + (leSetLayerVisible (list "PO" "block") t) + (leSetLayerVisible (list "PO" "dummy1") t) + (leSetLayerVisible (list "CO" "drawing") t) + (leSetLayerVisible (list "OD" "drawing") t) + (leSetLayerVisible (list "PM" "drawing1") t) + (leSetLayerSelectable (list "PO" "grd") t) + (leSetLayerSelectable (list "PO" "test1") t) + (leSetLayerSelectable (list "PO" "block") t) + (leSetLayerSelectable (list "PM" "drawing1") t) + ) + +; set a property to indicate which tool version was used on a CV +(defun SetGridPolyVersion (CV) + (dbReplaceProp CV "gridPolyVersion" "int" gridPolyVersion) + ) + +; Set a property to identify auto-generated to grid poly and CPO +(defun SetGridPolyProp (obj) + (dbReplaceProp obj "grd_poly" "boolean" t) + ) + +; Delete auto-generated grid poly and CPO +(defun DeleteGridPoly (@key (CV (geGetEditCellView))) + (foreach s (setof obj CV->shapes (dbGetPropByName obj "CPO")->value=="TRUE") + (dbDeleteObject s) + ) + (foreach s (setof obj CV->shapes (dbGetPropByName obj "grd_poly")->value=="TRUE") + (dbDeleteObject s) + ) + (dbSave CV) + t + ) + +; Count the overlaps on a given layer with bbox and bloat +(defun NumberOfOverlaps (CV lpp x0 y0 x1 y1 dx dy) + (length (dbGetTrueOverlaps CV + (list x0-dx+MfgGrid:y0-dy+MfgGrid + x1+dx-MfgGrid:y1+dy-MfgGrid) + lpp 32)) + ) + +; Return a list of the X coordinate of Scratch1LPP shapes that overlap bbox +(defun FindEdgesOfPM (CV x0 y0 x1 y1) + (let (shapes result) + shapes = (dbGetTrueOverlaps CV (list x0:y0 x1:y1) Scratch1LPP 32) + (foreach shape shapes + result = (cons (car (car shape->bBox)) result) + result = (cons (car (cadr shape->bBox)) result) + ) + (sort result (lambda (a b) abBox))-dx result) + result = (cons (car (cadr shape->bBox))+dx result) + ) + (sort result (lambda (a b) ax0-0.1 xbBox + cx0 = (car (car bbox)) + cy0 = (cadr (car bbox)) + cx1 = (car (cadr bbox)) + cy1 = (cadr (cadr bbox)) + rows = (ceiling (cy1-cy0)/poly_pitch) + + ; draw boundary CPO + x0 = cx0-cpo_width/2 + x1 = cx0+cpo_width/2 + (when (NumberOfOverlaps CV lpp x0 cy0 x1 cy1 0 0)==0 + (SetGridPolyProp (dbCreateRect CV lpp (list x0:cy0 x1:cy1)))) + x0 = cx1-cpo_width/2 + x1 = cx1+cpo_width/2 + (when (NumberOfOverlaps CV lpp x0 cy0 x1 cy1 0 0)==0 + (SetGridPolyProp (dbCreateRect CV lpp (list x0:cy0 x1:cy1)))) + + ; draw uniform grid poly + (for y 0 rows-1 + ya = cy0+(y+0.5)*poly_pitch + y0 = ya-poly_width/2 + y1 = ya+poly_width/2 + obj = (dbCreateRect CV (list "PO" "grd") (list cx0-overhang:y0 cx1+overhang:y1)) + grid_poly = (cons obj grid_poly) + ) + + ; create scratch view with some flattened layer intersections + obj = (ddGetObj CV->libName CV->cellName "cpo_scratch") + (when obj (ddDeleteObj obj)) + CV2 = (dbCopyCellView CV CV->libName CV->cellName "cpo_scratch" nil nil t) + (foreach inst CV2->instances (dbFlattenInst inst 32 t nil nil)) + (foreach via CV2->vias (dbFlattenInst via 32 t nil nil)) + (leMergeShapes (leLayerAnd CV2 (list "PM" "drawing1") (list "PO" "grd") Scratch1LPP)) + (leMergeShapes (leLayerAnd CV2 (list "PO" "drawing") (list "PO" "grd") Scratch2LPP)) + (foreach shape (leMergeShapes (leLayerAnd CV2 (list "PO" "block") + (list "PO" "block") (list "PO" "block"))) + block_shapes = (cons (dbCopyFig shape CV) block_shapes) + ) + (dbSave CV2) + + ; add legal CPO sites aligned to left and right of poly ends + (for y 0 rows-1 + ya = cy0+(y+0.5)*poly_pitch + y0 = ya-cpo_length/2 + y1 = ya+cpo_length/2 + (when (NumberOfOverlaps CV (list "PO" "drawing") cx0 y0 cx1 y1 0 0)>0 + pm_edges = (FindEdgesOfPM CV2 cx0 ya cx1 ya) + poly_locs = (FindCPOLocationsFromPoly CV2 cx0 ya cx1 ya poly_offset) + (foreach xa poly_locs + x0 = xa-cpo_width/2 + x1 = xa+cpo_width/2 + (when (IsLegalCPO CV x0 y0 x1 y1 pm_edges) + todraw = (cons (list x0:y0 x1:y1) todraw) + ) + ) + ) + ) + + ; add legal CPO sites aligned to PM edges + (for y 0 rows-1 + ya = cy0+(y+0.5)*poly_pitch + y0 = ya-cpo_length/2 + y1 = ya+cpo_length/2 + (when (NumberOfOverlaps CV (list "PO" "drawing") cx0 y0 cx1 y1 0 0)>0 + pm_edges = (FindEdgesOfPM CV2 cx0 ya cx1 ya) + (foreach xa pm_edges + x0 = xa-cpo_width/2 + x1 = xa+cpo_width/2 + (when (IsLegalCPO CV x0 y0 x1 y1 nil) + todraw = (cons (list x0:y0 x1:y1) todraw) + ) + ) + ) + ) + + ; draw CPOs + cpos = (DrawCPORects CV todraw) + todraw = nil + + ; draw PO block at left and right edges where necessary + (for y 0 rows-1 + ya = cy0+(y+0.5)*poly_pitch + y0 = ya-poly_width/2 + y1 = ya+poly_width/2 + (when (NumberOfOverlaps CV (list "PO" "drawing") cx0 y0 cx1 y1 0 0)>0 + poly_locs = (FindCPOLocationsFromPoly CV2 cx0 ya cx1 ya 0) + x0 = (car poly_locs) + x1 = (car (last poly_locs)) + (when (and x0-cx0 < max_edge x0-cx0 >= min_edge) + obj = (dbCreateRect CV (list "PO" "block") (list cx0-overhang:y0 x0:y1)) + (SetGridPolyProp obj) + block_shapes = (cons obj block_shapes) + ) + (when (and cx1-x1 < max_edge cx1-x1 >= min_edge) + obj = (dbCreateRect CV (list "PO" "block") (list x1:y0 cx1+overhang:y1)) + (SetGridPolyProp obj) + block_shapes = (cons obj block_shapes) + ) + ) + ) + + ; redraw grid poly avoiding blockages + (leLayerAndNot CV (list "PO" "grd") (list "PO" "block") Scratch2LPP) + (leLayerAndNot CV Scratch2LPP (list "PO" "dummy1") Scratch1LPP) + (foreach obj grid_poly (dbDeleteObject obj)) + (foreach obj block_shapes (dbDeleteObject obj)) + + ; delete short grid poly or keep it + (foreach obj (setof s CV->shapes s->lpp==Scratch1LPP) + x0 = (car (car obj->bBox)) + x1 = (car (cadr obj->bBox)) + (cond (x1-x0lpp=(list "PO" "grd") + (SetGridPolyProp obj)) + ) + ) + (foreach obj (setof s CV->shapes s->lpp==Scratch2LPP) (dbDeleteObject obj)) + + ; delete cpo_scratch view + obj = (ddGetObj CV->libName CV->cellName "cpo_scratch") + (when obj (ddDeleteObj obj)) + + ; set version and save + (SetGridPolyVersion CV) + (dbSave CV) + ) + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/decompact.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/decompact.il new file mode 100644 index 0000000000..614512ad1a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/decompact.il @@ -0,0 +1,282 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +Most of the time, we want genereated layout to be as compact as possible. +However, there are cases when we want to 'decompact' the layout to allow for +more routing bandwidth.
    +In particular, the results of placement/superstack compaction results in unused area in the top and bottom of each column. This module has code to spread out superstacks in the vertical direction. +
    +
    +
    InstanceTable +
    Maps a YRange to a list of instances in that range. +
    +
    +
    +*/ + + +defun( DeCompact ( CellView Recursive ) + + ( DeCompactVerticalKeepOrderFromCellRegionData + CellView + CellRegionData + `DeCompactVerticalKeepOrderMindfulOfPlugs + ( list + (lambda ( Instance ) + ( and + ( equal ( getq Instance libName ) WellPlugLibrary ) + ( or + ( equal ( getq Instance cellName ) NWellPlugCellName ) + ( equal ( getq Instance cellName ) PWellPlugCellName ) ) ) ) + ( times UserUnitsPerMeter MinWellSpacing ) + ( times UserUnitsPerMeter ManufacturingGrid ) + Recursive ) ) + + ( dbSave CellView ) + CellView + ) + +(defun DeCompactVerticalKeepOrderYRanges ( YRanges + EnclosingYRange + Recursive + ) + (let ( + ( Table ( makeTable `bla nil ) ) + ( Offset 0.0 ) + ( WhiteSpace + ( difference + ( RangeGetSize EnclosingYRange ) + (if YRanges ( RangeGetCover YRanges ) 0.0 ) ) ) + ( SortedRanges + ( sort ( copy YRanges ) + (lambda ( a b ) ( lessp ( car a ) ( car b ) ) ) ) ) ) + (cond ( + Recursive + (let ( + ( Spacing + (cond ( + ( lessp WhiteSpace 0.0 ) + ( quotient WhiteSpace + ( max + 1 + ( difference ( length YRanges ) 1 ) ) ) ) + ( + ( quotient WhiteSpace + ( plus ( length YRanges ) 1 ) ) ) ) ) ) + (let ( + ( Bottom + (cond ( + ( lessp WhiteSpace 0.0 ) + ( car EnclosingYRange ) ) + ( + ( plus + ( car EnclosingYRange ) + Spacing ) ) ) ) ) + ( foreach Range SortedRanges + (let ( + ( Size ( RangeGetSize Range ) ) ) + ( setarray Table Range + ( list Bottom ( plus Bottom Size ) ) ) + ( setq Bottom ( plus Bottom + Spacing + Size ) ) ) ) ) ) ) + ( + t + (let ( + ( Regions + ( plus + 1 + ( ceiling + ( quotient + ( RangeGetSize EnclosingYRange ) + 40.0 ) ) ) ) ) + (let ( + ( Spacing + ( quotient WhiteSpace ( difference Regions 1 ) ) ) + ( RegionSpacing + ( quotient ( RangeGetSize EnclosingYRange ) Regions ) ) + ( RegionBoundary + ( quotient ( RangeGetSize EnclosingYRange ) Regions ) ) + ( Below t ) + ( Bottom ( car EnclosingYRange ) ) ) + ( foreach + Range SortedRanges + (let ( + ( Size ( RangeGetSize Range ) ) ) + (when ( and + Below + ( greaterp ( car Range ) RegionBoundary ) ) + ( setq RegionBoundary + ( plus RegionBoundary RegionSpacing) ) + ( setq Bottom + ( plus Bottom Spacing ) ) ) + ( setq Below + ( leqp ( car Range ) RegionBoundary ) ) + ( setarray Table Range + ( list Bottom ( plus Bottom Size ) ) ) + ( setq Bottom + ( plus Bottom + Size ) ) ) ) ) ) ) ) + ( mapcar + (lambda ( Range ) + ( arrayref Table Range ) ) + YRanges ) + ) ) + + +(defun DeCompactGetInstanceTable ( Instances ) + ( FigGetClumpTable + Instances + ?Clumpify (lambda ( C ) ( RectGetYRange ( getq C bBox ) ) ) + ?ClumpUnion `RangeUnion + ?ClumpPredicate `RangeIntersection ) ) + +(defun DeCompactVerticalKeepOrderDefault ( Instances + BoundingRange + Grid + Recursive ) + (let ( + ( InstanceTable + ( DeCompactGetInstanceTable + Instances ) ) ) + (let ( + ( UnionRanges + ( mapcar `car ( tableToList InstanceTable ) ) ) ) + ( println ( tableToList InstanceTable ) ) + + ( DeCompactVerticalKeepOrder + InstanceTable + UnionRanges + BoundingRange + Grid + Recursive ) ) ) ) + + +(defun DeCompactVerticalKeepOrderMindfulOfPlugs ( Instances + BoundingRange + PlugPredicate + MinWellSpacing + Grid + Recursive ) + (let ( + ( InstanceTable + ( DeCompactGetInstanceTable + Instances ) ) ) + (let ( + ( UnionRanges + ( mapcar `car ( tableToList InstanceTable ) ) ) ) + (let ( + ( BottomRange + ( ListFindMinimumElement + UnionRanges + (lambda ( Range ) ( car Range ) ) ) ) + ( TopRange + ( ListFindMaximumElement + UnionRanges + (lambda ( Range ) ( cadr Range ) ) ) ) ) + (let ( + ( BoundingRangeToDecompact + ( list + (if ( exists + Instance + ( arrayref InstanceTable BottomRange ) + ( and + ( apply PlugPredicate ( list Instance ) ) + ( lessp + ( difference + ( RectGetBottom ( getq Instance bBox ) ) + ( car BottomRange ) ) + MinWellSpacing ) ) ) + ( cadr BottomRange ) ( car BoundingRange ) ) + (if ( exists + Instance + ( arrayref InstanceTable TopRange ) + ( and + ( apply PlugPredicate ( list Instance ) ) + ( lessp + ( difference + ( cadr TopRange ) + ( RectGetTop ( getq Instance bBox ) ) ) + MinWellSpacing ) ) ) + ( car TopRange ) ( cadr BoundingRange ) ) ) ) ) + (let ( + ( RangesToDecompact + ( setof Range UnionRanges + ( RangeIsRangeInRangeClose + Range + BoundingRangeToDecompact + 1e-9 ) ) ) ) + ( DeCompactVerticalKeepOrder + InstanceTable + RangesToDecompact + BoundingRangeToDecompact + Grid + Recursive ) + (let ( + ( Plugs + ( setof + Instance + Instances + ( apply PlugPredicate ( list Instance ) ) ) ) ) + ( PlugsClean + Plugs + MinWellSpacing ) + + ) ) ) ) ) ) ) + +(defun DeCompactVerticalKeepOrder ( InstanceTable + RangesToDecompact + BoundingRangeToDecompact + Grid + Recursive ) + + (let ( + ( NewRanges + ( DeCompactVerticalKeepOrderYRanges + RangesToDecompact + BoundingRangeToDecompact + Recursive ) ) ) + + ( mapcar + (lambda ( OldRange NewRange ) + (let ( + ( Offset + ( difference + ( MathRoundToNearest ( car NewRange ) Grid ) + ( car OldRange ) ) ) ) + ( foreach Instance ( arrayref InstanceTable OldRange ) + ( dbSetq Instance + ( list ( car ( getq Instance xy ) ) + ( plus ( cadr ( getq Instance xy ) ) + Offset ) ) + xy ) ) ) ) + RangesToDecompact + NewRanges ) ) ) + +(defun DeCompactVerticalKeepOrderFromCellRegionData ( CellView + CellRegionData + CompactFunc + CompactFuncParams ) + + ( foreach + ColumnData + ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) + (let ( + ( BoundingRect + ( PlacementRegionGetColumnBBox ColumnData ) ) ) + (let ( + ( Instances + ( setof Instance ( getq CellView instances ) + ( RangeIsRangeInRangeClose + ( RectGetXRange ( getq Instance bBox ) ) + ( RectGetXRange BoundingRect ) + 1e-9 ) ) ) ) + ( apply CompactFunc + ( cons Instances + ( cons ( RectGetYRange BoundingRect ) + CompactFuncParams ) ) ) ) ) ) + nil + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/spacestacks.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/spacestacks.il new file mode 100644 index 0000000000..68b79dce4c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/decompact/spacestacks.il @@ -0,0 +1,153 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: SpaceStacks +; Parameter: CellView (CVId) +; ColumnStackSpaceThreshold (float) +; ColumnStackSpaceMinSpacing (float) +; ColumnStackSpaceMaxShift (float) +; Return: CellView (CVId) +; +; Spacing the stacks +; +; +defun( SpaceStacks ( CellView + ColumnStackSpaceThreshold + ColumnStackSpaceMinSpacing + ColumnStackSpaceMaxShift) + ColumnStackSpaceThreshold = ColumnStackSpaceThreshold * UserUnitsPerMeter + ColumnStackSpaceMinSpacing = ColumnStackSpaceMinSpacing * UserUnitsPerMeter + ColumnStackSpaceMaxShift = ColumnStackSpaceMaxShift * UserUnitsPerMeter + + (let ( + ( Components + ( cadr + ( NameFilterInstances + ( getq CellView instances ) + ( append + ( append NSuperStackLibCellPairRegExs + PSuperStackLibCellPairRegExs ) + PlugLibCellPairRegExs ) ) ) ) + + ( MoveTest + (lambda ( Component ColumnStackSpaceThreshold Region ) + ( and + ( RangeIsNumberInRangeClose + ( car ( RectGetCenter ( getq Component bBox ) ) ) + ( RectGetXRange Region ) + 1e-9 ) + ( lessp + ( RectGetWidth ( getq Component bBox ) ) + ColumnStackSpaceThreshold ) + (let ( + ( Contacts + ( setof Conn ( getq Component conns ) + ( rexMatchp + ".*\\.[DS]$" + ( getq ( getq Conn term ) name ) ) ) ) ) + ( leqp + ( length + ( setof Conn Contacts + ( or + ( equal ( getq ( getq Conn net ) name ) GNDNetName ) + ( equal ( getq ( getq Conn net ) name ) VddNetName ) ) ) ) + ( round ( times ( length Contacts ) 0.4 ) ) + ) ) ) ) ) ) + ( foreach + Column + ( PlacementRegionsGetCellRegionDataColumnList + CellRegionData ) + (let ( + ( LeftRegion ( PlacementRegionGetColumnLeftRegionRect Column ) ) + ( RightRegion ( PlacementRegionGetColumnRightRegionRect Column ) ) + ) + + (let ( + ( LComponents + ( setof Component Components + ( apply + MoveTest + ( list Component ColumnStackSpaceThreshold LeftRegion) ) + ) ) + ( RComponents + ( setof Component Components + ( apply + MoveTest + ( list Component ColumnStackSpaceThreshold RightRegion ) ) + ) ) + ) + ( println ( list + LeftRegion + RightRegion + LComponents + RComponents + ColumnStackSpaceThreshold ) ) + ( foreach BoundAndClump + ( tableToList + ( FigGetClumpTable + LComponents + ?ClumpPredicate (lambda ( Rect1 Rect2 ) + ( RangeDoIntersect + ( RectGetYRange Rect1 ) + ( RectGetYRange Rect2 ) + 1e-9 ) ) ) ) + (let ( + ( Box ( car BoundAndClump ) ) + ( Clump ( cadr BoundAndClump ) ) + ) + (when ( cadr ( NameFilterInstances + Clump + SuperStackLibCellPairRegExs ) ) + ( FigStackHorizontalMaintainSep + Clump + ( min + ( RectGetLeft Box ) + ( max + ( difference + ( RectGetLeft Box ) + ColumnStackSpaceMaxShift ) + ( plus + ( RectGetLeft LeftRegion ) + ColumnStackSpaceMinSpacing ) ) ) ) ) ) ) + + + ( foreach BoundAndClump + ( tableToList + ( FigGetClumpTable + RComponents + ?ClumpPredicate (lambda ( Rect1 Rect2 ) + ( RangeDoIntersect + ( RectGetYRange Rect1 ) + ( RectGetYRange Rect2 ) + 1e-9 ) ) ) ) + (let ( + ( Box ( car BoundAndClump ) ) + ( Clump ( cadr BoundAndClump ) ) + ) + (when ( cadr ( NameFilterInstances + Clump + SuperStackLibCellPairRegExs ) ) + ( FigStackHorizontalMaintainSep + Clump + ( difference + ( max + ( RectGetRight Box ) + ( min + ( plus ( RectGetRight Box ) + ColumnStackSpaceMaxShift ) + ( difference + ( RectGetRight RightRegion ) + ColumnStackSpaceMinSpacing ) ) ) + ( RectGetWidth Box ) ) ) ) ) ) ) ) ) + ( dbSave CellView ) + ) +CellView +) + + + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/fill.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/fill.il new file mode 100644 index 0000000000..e2e6104c38 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/fill.il @@ -0,0 +1,70 @@ + +(defun fillCell ( CellName ViewName ) + let( ( lcv cv ncv mcv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + when( ((cv == nil)&&(ViewName == "distort")) + ViewName="layout" + lcv=nrOpenCellViewReadable( LibName CellName ViewName )) + when( ((cv == nil)&&(ViewName == "distort_pg")) + ViewName="layout_pg" + lcv=nrOpenCellViewReadable( LibName CellName ViewName )) + newCellName = strcat(CellName "_hvt") + mcv=nrOpenCellViewWritable( LibName newCellName ViewName) + when( cv == nil + printf( "Cannot open distort/distort_pg view for %s\n" CellName) + ) + when( lcv == nil + printf( "Cannot open layout/layout_pg view for %s\n" CellName) + ) + when( mcv == nil + printf("HVT subtype already exists %s\n" newCellName)) + when( ((cv != nil)&&(mcv != nil)) + printf("yes in distort/distort_pg\n") + ;dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + foreach(inst cv->instances + when( inst->libName=="synthesis.shared.fill" + dbCopyFig(inst ncv) + ;ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + ;Fill( ncv ViewName) + ;SyncToNetlist() + ) + when( inst->libName=="lib.util.spare" + dbCopyFig(inst ncv) + )) +dbSave( ncv ) +dbClose( ncv ) + ) + when( ((lcv != nil)&&(mcv != nil)) + printf("yes in layout/layout_pg\n") + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + foreach(inst lcv->instances + when( inst->libName=="synthesis.shared.fill" + dbCopyFig(inst ncv) + ) + when( inst->libName=="lib.util.spare" + dbCopyFig(inst ncv) + )) +dbSave( ncv ) +dbClose( ncv ) + ) + +)) + +(defun fill () + (let (text CellName num) + fl = infile("list_5.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + CellName = nth(0 text) + num = nth(1 text) + when( num != "0" + fillCell(CellName "distort") + fillCell(CellName "distort_pg") +)))) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/drawimplant.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/drawimplant.il new file mode 100644 index 0000000000..5c7a6c74cd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/drawimplant.il @@ -0,0 +1,244 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: DrawImplant +; Parameter: PlacedView (CVId) +; Return: CellView (CVId) +; +; Draw the implant boxes +; +; +defun( DrawImplant ( PlacedView ) + + ( DrawImplantOnCellView + PlacedView + CellRegionData + NImplantLPP + PImplantLPP + WellPlugLibrary + NWellPlugCellName + PWellPlugCellName + WellPlugViewName + ( times EvilGatePRegionOffset UserUnitsPerMeter ) + ContactLPP + ) + ( dbSave PlacedView ) + PlacedView + ) + + +(defun DrawImplantCompareRects ( R1 R2 ) + ( lessp + ( RectGetBottom + R1 ) + ( RectGetBottom + R2 ) ) ) + +(defun DrawImplantCutRectsOutOfRect ( RectToCutOutFrom RectsToCutOut ) + (let ( + ( LeftEdge ( RectGetLeft RectToCutOutFrom ) ) + ( RightEdge ( RectGetRight RectToCutOutFrom ) ) + ( BottomEdge ( RectGetBottom RectToCutOutFrom ) ) + ( TopEdge ( RectGetTop RectToCutOutFrom ) ) + ( SortedRectsToCutOut ( sort ( copy RectsToCutOut ) `DrawImplantCompareRects ) ) ) + (let ( + ( CurrY BottomEdge ) + ( RemainingRectsToCutOut SortedRectsToCutOut ) + ( Result nil ) ) + (while ( lessp CurrY TopEdge ) + (let ( + ( CurrRectToCutOut ( car RemainingRectsToCutOut ) ) ) + (if CurrRectToCutOut + (let ( + ( RectLeft ( RectGetLeft CurrRectToCutOut ) ) + ( RectRight ( RectGetRight CurrRectToCutOut ) ) + ( RectBottom ( RectGetBottom CurrRectToCutOut ) ) + ( NextY ( min + ( RectGetTop CurrRectToCutOut ) + TopEdge ) ) ) + ( setq RemainingRectsToCutOut ( cdr RemainingRectsToCutOut ) ) + (let ( + ( Rect0 ( list + ( list LeftEdge CurrY ) + ( list RightEdge RectBottom ) ) ) + ( Rect1 ( list + ( list LeftEdge RectBottom ) + ( list RectLeft NextY ) ) ) + ( Rect2 ( list + ( list RectRight RectBottom ) + ( list RightEdge NextY ) ) ) ) + ( setq + Result + ( cons + Rect0 + ( cons + Rect1 + ( cons Rect2 Result ) ) ) ) + ( setq CurrY NextY ) ) ) + (let () + ( setq + Result + ( cons + ( list + ( list LeftEdge CurrY ) + ( list RightEdge TopEdge ) ) + Result ) ) + ( setq CurrY TopEdge ) ) ) ) ) + Result ) ) ) + +(defun DrawImplantFindPlugs ( CellView + PlugLibName + PlugCellName + PlugViewName + ImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP ) + (let ( + ( PlugFilter + ( NameFilterInstances + ( getq CellView instances ) + ( list ( list PlugLibName PlugCellName ) ) ) ) ) + (let ( + ( Plugs ( cadr PlugFilter ) ) + ( Gates ( car PlugFilter ) ) ) + ( append + ( ListApplyFuncToListAndAccumulateNonNilResults + Gates + (lambda + ( Instance LibName CellName ViewName ) + ( FindPlugRectInGateInstance + Instance + LibName + CellName + ViewName + ImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP ) ) + ( list + PlugLibName + PlugCellName + PlugViewName ) ) + ( mapcar + (lambda ( PlugInstance ) + ( FindPlugRectInPlugInstance PlugInstance ImplantLPP ) ) + Plugs + ) ) ) ) ) + +(defun DrawImplantOnCellView ( CellView + CellRegionData + NImplantLPP + PImplantLPP + PlugLibName + NPlugCellName + PPlugCellName + PlugViewName + EvilGatePRegionOffset + ContactLPP + ) + (let ( + ( NWellPlugList ( DrawImplantFindPlugs + CellView + PlugLibName + NPlugCellName + PlugViewName + NImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP ) ) + ( PWellPlugList ( DrawImplantFindPlugs + CellView + PlugLibName + PPlugCellName + PlugViewName + PImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP ) ) ) + ;( printf "%L\n" NWellPlugList ) + ( foreach + Column + ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) + (let ( + ( NTransistorRegionRect ( PlacementRegionGetColumnNRegionRect + Column ) ) + ( PTransistorRegionRect ( PlacementRegionGetColumnPRegionRect + Column ) ) + ( BottomGateRegionRect ( PlacementRegionGetColumnBottomGateRegionRect + Column ) ) + ( TopGateRegionRect ( PlacementRegionGetColumnTopGateRegionRect + Column ) ) ) + (let ( + ( BottomOfBottomGateRegion ( RectGetBottom BottomGateRegionRect ) ) + ( TopOfBottomGateRegion ( RectGetTop BottomGateRegionRect ) ) + ( BottomOfTopGateRegion ( RectGetBottom TopGateRegionRect ) ) + ( TopOfTopGateRegion ( RectGetTop TopGateRegionRect ) ) + ( NImplantLeftEdge ( RectGetLeft NTransistorRegionRect ) ) + ( NImplantRightEdge ( RectGetRight NTransistorRegionRect ) ) + ( PImplantLeftEdge ( RectGetLeft PTransistorRegionRect ) ) + ( PImplantRightEdge ( RectGetRight PTransistorRegionRect ) ) ) + (let ( + ( ColumnNImplantRect ( list + ( list NImplantLeftEdge BottomOfBottomGateRegion ) + ( list NImplantRightEdge TopOfTopGateRegion ) ) ) + ( ColumnPImplantRect ( list + ( list PImplantLeftEdge BottomOfBottomGateRegion ) + ( list PImplantRightEdge TopOfTopGateRegion ) ) ) ) + (let ( + ( ColumnNPlugs ( setof + PlugRect + NWellPlugList + ( RectDoRectsOverlapOpenRects ColumnPImplantRect PlugRect ) ) ) + ( ColumnPPlugs ( setof + PlugRect + PWellPlugList + ( RectDoRectsOverlapOpenRects ColumnNImplantRect PlugRect ) ) ) ) + + (let ( + ( ColumnNImplantRects ( DrawImplantCutRectsOutOfRect + ColumnNImplantRect + ColumnPPlugs ) ) + ( ColumnPImplantRects ( DrawImplantCutRectsOutOfRect + ColumnPImplantRect + ColumnNPlugs ) ) ) + ( foreach + ImplantRect + ColumnNImplantRects + (if ( greaterp + ( RectGetArea + ImplantRect ) + 0.0576 ) + ( dbCreateRect + CellView + NImplantLPP + ImplantRect ) + ( dbCreateRect + CellView + PImplantLPP + ImplantRect ) ) ) + ( foreach + ImplantRect + ColumnPImplantRects + (if ( greaterp + ( RectGetArea + ImplantRect ) + 0.0576 ) then + ( dbCreateRect + CellView + PImplantLPP + ImplantRect ) + ( dbCreateRect + CellView + list("PM" "drawing1") + ImplantRect ) + else + ( dbCreateRect + CellView + NImplantLPP + ImplantRect ) ) ) ) ) ) ) ) ) + + t ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/findplugingateinstance.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/findplugingateinstance.il new file mode 100644 index 0000000000..f797e1698c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/implant/findplugingateinstance.il @@ -0,0 +1,126 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + + +(defun FindPlugRectInPlugInstance ( PlugInstance ImplantLPP ) + (when PlugInstance + (let ( + ( PlugMaster ( getq PlugInstance master ) ) ) + (let ( + ( PlugImplantShapes ( setof + Shape + ( getq + PlugMaster + shapes + ) + ( equal ( getq Shape lpp ) ImplantLPP ) ) ) ) + (let ( + ( PlugImplantBoundingRect ( ListApplyFuncToListAndAccumulateResult + PlugImplantShapes + (lambda + ( ImplantShape CurrResult ) + ( RectGetBoundRect + CurrResult + ( getq ImplantShape bBox ) + ) ) + nil + nil ) ) ) + (when PlugImplantBoundingRect + (let ( + ( PlugRectInPlug + ( dbTransformBBox + PlugImplantBoundingRect + ( getq + PlugInstance + transform ) ) ) ) + PlugRectInPlug ) ) ) ) ) ) ) + +(defun FindPlugRectInGateInstance ( GateInstance + PlugLibName + PlugCellName + PlugViewName + ImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP ) + (let ( + ( GateInstanceMaster ( getq GateInstance master ) ) + ( GateInstanceTransform ( getq GateInstance transform ) ) + ) + (let ( + ( Instances ( getq GateInstanceMaster instances ) ) + ) + (let ( + ( PlugInstance ( car + ( setof + Instance + Instances + ( and + ( equal + ( getq Instance libName ) + PlugLibName + ) + ( equal + ( getq Instance cellName ) + PlugCellName + ) + ( equal + ( getq Instance viewName ) + PlugViewName ) ) ) ) ) ) + + (let ( + ( PlugRectInPlug + ( FindPlugRectInPlugInstance + PlugInstance + ImplantLPP ) ) ) + (if PlugRectInPlug + ( dbTransformBBox + PlugRectInPlug + GateInstanceTransform ) + ( FindPlugRectInGateInstanceHack + GateInstance + ImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP + ) ) ) ) ) ) ) + +(defun FindPlugRectInGateInstanceHack ( GateInstance ImplantLPP EvilGatePRegionOffset NImplantLPP ContactLPP ) + (when GateInstance + (let ( + ( PlugMaster ( getq GateInstance master ) ) ) + (let ( + ( ContactShapes + ( setof + Shape + ( getq + PlugMaster + shapes + ) + ( equal ( getq Shape lpp ) + ContactLPP ) ) ) ) + (when ContactShapes + (let ( + ( PlugShape + ( car + ( exists + Shape + ( getq + PlugMaster + shapes + ) + ( and ( equal ( getq Shape lpp ) ImplantLPP ) + (if ( equal ImplantLPP NImplantLPP ) + ( greaterp ( RectGetRight ( getq Shape bBox ) ) EvilGatePRegionOffset ) + ( lessp ( RectGetLeft ( getq Shape bBox ) ) EvilGatePRegionOffset ) ) + ( exists ContactShape ContactShapes + ( RectIsRectInRectClose ( getq ContactShape bBox ) + ( getq Shape bBox ) 1e-9 ) ) ) ) ) ) ) + (when PlugShape + ( dbTransformBBox + ( getq PlugShape bBox ) + ( getq GateInstance transform ) ) ) ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/lvsnodes.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/lvsnodes.il new file mode 100644 index 0000000000..085535de3c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/lvsnodes.il @@ -0,0 +1,64 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun LVSNodesDrawFromDirectives ( CellView + DirectivesTable + LPP + LibCellPairRegExsToIgnore + ) + ( rexCompile "\\#" ) + (let ( + ( LVSNodeNames + ( mapcar + (lambda ( Name ) + ( rexReplace Name "-H" 0 ) + ) + ( CellInfoLookup + DirectivesTable + "lvs_labels" ) ) ) ) + ( LVSNodesDraw + CellView + LVSNodeNames + LPP + LibCellPairRegExsToIgnore + ) ) ) + +(defun LVSNodesDraw ( CellView + LVSNodeNames + LPP + LibCellPairRegExsToIgnore + ) + (let ( + ( Instances + ( car ( NameFilterInstances + ( getq CellView instances ) + LibCellPairRegExsToIgnore ) ) ) ) + + ( foreach + LVSNodeName + LVSNodeNames + ( println LVSNodeName ) + (let ( + ( LabelRect + ( car + ( PinUtilGetPinRectsForInstances + Instances + (lambda ( NetName ) ( equal NetName LVSNodeName ) ) + (lambda ( SomeLPP ) ( equal ( car SomeLPP ) ( car LPP ) ) ) ) ) ) ) + ( dbCreateLabel + CellView + LPP + ( RectGetCenter LabelRect ) + LVSNodeName + "centerCenter" + "R0" + "stick" + 0.1 + ) + ) ) + ) ) + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/open.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/open.il new file mode 100644 index 0000000000..3fc8a8fd60 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/open.il @@ -0,0 +1,53 @@ +(defun SyncCell ( CellName ViewName ) + let( ( lcv cv ncv mcv newCellName pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName ) + when( ((cv == nil)&&(ViewName == "distort")) + ViewName="layout" + lcv=nrOpenCellViewReadable( LibName CellName ViewName )) + when( ((cv == nil)&&(ViewName == "distort_pg")) + ViewName="layout_pg" + lcv=nrOpenCellViewReadable( LibName CellName ViewName )) + newCellName = strcat(CellName "_hvt") + mcv=nrOpenCellViewReadable( LibName newCellName ViewName) + when( cv == nil + printf( "Doesnot have distort/distort_pg view for %s\n" CellName) + ) + when( lcv == nil + printf( "Cannot open %s\n" CellName) + ) + when( mcv != nil + printf("HVT subtype already exists %s\n" newCellName)) + when( ((cv != nil)&&(mcv == nil)) + printf("yes\n") + dbCopyCellView(cv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + SyncToNetlist( ?CV ncv ) + dbSave( ncv ) + dbClose( ncv ) + ) + when(((lcv != nil)&&(mcv == nil)) + printf("yes\n") + dbCopyCellView(lcv LibName newCellName ViewName nil nil t) + ncv = nrOpenCellViewWritable( LibName newCellName ViewName ) + SyncToNetlist( ?CV ncv ) + dbSave( ncv ) + dbClose( ncv ) + ) + ) + ) + +(defun sync () + (let (text CellName num) + fl = infile("list_5.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + CellName = nth(0 text) + num = nth(1 text) + when( num != "0" + SyncCell(CellName "distort") + SyncCell(CellName "distort_pg") +)))) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.il new file mode 100644 index 0000000000..ed03ffeec2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.il @@ -0,0 +1,71 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: FoldGates +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Change the folding of the Gates to adjust the width of them. +; +; +; + + +defun( FoldGates ( CellView ) + + foreach( Gate cadr( NameFilterInstances( + CellView~>instances + GateLibCellPairRegExs ) ) + when( PCellGetParameterValue( Gate "allow_overfolding" ) + dbReplaceProp( Gate "allow_overfolding" "boolean" "FALSE" ) + ) + when( PCellGetParameterValue( Gate "use_poly_contact" ) && PCellGetParameterValue( Gate "NW1" ) + if( PCellGetParameterValue( Gate "NW1" )<0.72/MicronsPerMeter then + dbReplaceProp( Gate "use_poly_contact" "boolean" "FALSE" ) + ) + ) ; turn off poly contact for small gate.INV cells + when( PCellGetParameterValue( Gate "mid_poly_contact" ) + dbReplaceProp( Gate "mid_poly_contact" "boolean" "TRUE" ) + ) ; turn on mid_poly_contact for gate.WINV cells. + ) + NPSearchFoldGates( + cadr( NameFilterInstances( + getq( CellView instances ) + GateLibCellPairRegExs ) ) + NColumnWidthParamName + PColumnWidthParamName + NWidth + PWidth + UserUnitsPerMeter ) + dbSave( CellView ) + CellView +) + +defun( FixMustConnectTerm ( CellView ) + let((inst foo term2 term1) + foreach( inst CellView~>instances + foreach( term1 inst~>terminals + if( rexMatchp( "mustConnect_" term1->name) then + foo=parseString(term1->name "_") + rexCompile(strcat(car(foo) "_" cadr(foo) "_")) + term2Name=rexReplace(term1->name "" 0) + foreach( term2 inst->terminals + if( term2->name == term2Name then + term1->net=term2->net + ) + ) + ) + ) + if( inst->cellName=="stack.PPLUG.0" then + dbCreateConnByName( dbMakeNet( CellView VddNetName ) + inst "Vdd" ) + ) + if( inst->cellName=="stack.NPLUG.0" then + dbCreateConnByName( dbMakeNet( CellView GNDNetName ) + inst "GND" ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.rp b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.rp new file mode 100644 index 0000000000..f9a07891fc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/foldgates.rp @@ -0,0 +1,31 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defvar ParameterList ( RPGetRPParameter ) ) +(defvar TargetViewName ( nth 0 ParameterList ) ) + +(let ( + ( CellView ( dbOpenCellViewByType + LibName + CellName + TargetViewName + "maskLayout" + "a" ) ) ) + ( NPSearchFoldGates + ( cadr ( NameFilterInstances + ( getq CellView instances ) + GateLibCellPairRegExs ) ) + NColumnWidthParamName + PColumnWidthParamName + NWidth + PWidth + UserUnitsPerMeter ) + ( dbSave CellView ) + ) + + +(defun RPDone () + t ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/guessplacementregions.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/guessplacementregions.il new file mode 100644 index 0000000000..af17fcecca --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/guessplacementregions.il @@ -0,0 +1,108 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: GuessPlacementRegions +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Defines how large an region to contain all the components. +; +; +; + + +defun( GuessPlacementRegions ( CellView ) + +(defvar + GateRegionHeight + 0 ) + +(unless InitialColumnCount + (let ( + ( Filter1 + ( NameFilterInstances + ( getq CellView instances ) + GateSuperStackLibCellPairRegExs ) ) ) + (let ( + ( Filter2 + ( NameFilterInstances + ( car Filter1 ) + NSuperStackLibCellPairRegExs ) ) ) + (let ( + ( NComponents + ( cadr Filter2 ) ) + ( PComponents + ( car Filter2 ) ) + ( GateComponents + ( cadr Filter1 ) ) ) + (defvar InitialColumnCount + ( GuessPlacementRegionsGetInitialColumnCount + CellView + YPitch + LeafCellMinVerticalSpacingToBoundary + NComponents + PComponents + GateComponents + ) ) + + ( println + ( list ( NPSearchGetWidthFromIndex NWidthData 0 ) + ( NPSearchGetWidthFromIndex PWidthData 0 ) + TargetCellWidth ) ) + + ( LinearSearchInitTable + ColumnSearchTable + InitialColumnCount + ( ceiling + ( quotient + TargetCellWidth + ( plus ( NPSearchGetWidthFromIndex NWidthData 0 ) + ( NPSearchGetWidthFromIndex PWidthData 0 ) ) ) ) + InitialColumnCount ) + ) ) ) ) + + +( printf "ColumnSearchTable=" ) +( println ( tableToList ColumnSearchTable ) ) +(defvar ColumnCount + (if ( equal CurrentSearchTable ColumnSearchTable ) + ( arrayref ColumnSearchTable "trial" ) + ( arrayref ColumnSearchTable "max" ) ) + ) + +CellView +) + +(defun GuessPlacementRegionsGetHeightOfComponents ( + Components ) + ( ListFindSum + Components + (lambda ( Component ) ( RectGetHeight ( getq Component bBox ) ) ) ) +) + +(defun GuessPlacementRegionsGetInitialColumnCount ( CellView + YPitch + MinVerticalSpacingToBoundary + NComponents + PComponents + GateComponents + ) + (let ( + ( TotalComponentHeight + ( plus + ( max + ( GuessPlacementRegionsGetHeightOfComponents NComponents ) + ( GuessPlacementRegionsGetHeightOfComponents PComponents ) ) + ( GuessPlacementRegionsGetHeightOfComponents GateComponents ) ) ) + ( TotalAvailableHeight + ( PlacementRegionsCalculateTotalGateAndTransistorRegionsHeight + YPitch + MinVerticalSpacingToBoundary ) ) ) + ( ceiling + ( quotient + ( times 0.8 TotalComponentHeight ) + TotalAvailableHeight ) ) ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/initnp.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/initnp.il new file mode 100644 index 0000000000..41640743d7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/initnp.il @@ -0,0 +1,243 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: initnp +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Initialize NWidthData & PWidthData used for binary search. +; NwidthData are for N-type components and PWidthData are for +; P-type components. Finds the minimum NWidth and PWidth that +; will fit all the components. +; +; Their data structure looks like: +; NWidthData= +; (table:ComponentInfoListTable table:GateComponentInfoTable +; (1.92 2.4 2.88 3.36 3.84 5.28 6.24) +; 3.84 +; ) +; +; It means: +; (table:ComponentInfoListTable table:GateComponentInfoTable +; (all the possible widths of all components rounded up to +; the nearest multiple of pitch size 0.48) +; The smallest width that can fit all of the component +; ) +; +; There are two type of components: gate and stack. +; tables ComponentInfoListTable and GateComponentInfoTable +; contains all the possible length and width for the instances. +; ComponentInfoListTable contains instance who is a stack component; +; while GateComponentInfoTable contains instance who is a gate. +; A stack component is a group of gate stacked together. +; +; A such table looks like this: +; ( ("_r.0" +; (("_r.0" 1.82 5.06) +; ("_r.0" 1.91 4.23) +; ("_r.0" 2.05 3.4) +; ) +; ) +; ("R.3" +; (("R.3" 2.01 1.43)) +; ) +; ) +; +; It means: +; ( (instance1 +; ((instance1 possible_width1 possible_height1) +; (instance1 possible_width2 possible_height2) +; (instance1 possible_width3 possible_height3) +; ) +; ) There are three possible dimensions for this device. +; (instance2 +; ((instance2 possible_width1 possible_height1)) +; ) There is just one possible dimension for this device. +; .... +; ) +; +; NWidthSearchTable and PWidthSearchTable records the search effort and looks like: +; (("iters" 0) ("trial" 6) ("type" "binary") ("max" 6) ("done" nil) ("min" 0)) +; It means: +; ((iteration number) (index of trial compoent) (search type) +; (index of the component with max width) (done?) (index of the component with min width)) +; +; NWidth and PWidth will look up the actual width from NWidthSearchTable and PWidthSearchTable +; + +defun( initnp ( CellView ) + + ;get initial + (unless NWidthData + (defvar NWidthData + ( NPSearchGetWidthData + ( cadr ( NameFilterInstances + ( getq CellView instances ) + GateLibCellPairRegExs ) ) + ( cadr ( NameFilterInstances + ( getq CellView instances ) + NChainLibCellPairRegExs ) ) + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ( times UserUnitsPerMeter TransistorMinimumContactableWidth ) + ( times UserUnitsPerMeter TransistorDiffusionToBBoxDistance ) + MaximumComponentWidthRatio + ( times UserUnitsPerMeter NRegionOffsetFromColumnCenter ) + ( times UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectiveTable + Metal3LPP + DirectiveUnitsPerMeter ) ) + MaximumNColumnWidth + UserUnitsPerMeter + t + PreferEvenFolds + ( times UserUnitsPerMeter ExtraGateWidth ) ) ) + ( BinarySearchInitTable + NWidthSearchTable + 0 + ( difference ( length ( NPSearchGetWidthVectorFromWidthData NWidthData ) ) 1 ) + ( difference ( length ( NPSearchGetWidthVectorFromWidthData NWidthData ) ) 1 ) ) +) + + (unless PWidthData + (defvar PWidthData + ( NPSearchGetWidthData + ( cadr ( NameFilterInstances + ( getq CellView instances ) + GateLibCellPairRegExs ) ) + ( cadr ( NameFilterInstances + ( getq CellView instances ) + PChainLibCellPairRegExs ) ) + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ( times UserUnitsPerMeter TransistorMinimumContactableWidth ) + ( times UserUnitsPerMeter TransistorDiffusionToBBoxDistance ) + MaximumComponentWidthRatio + ( times UserUnitsPerMeter PRegionOffsetFromColumnCenter ) + ( times UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectiveTable + Metal3LPP + DirectiveUnitsPerMeter ) ) + MaximumPColumnWidth + UserUnitsPerMeter + nil + PreferEvenFolds + ( times UserUnitsPerMeter ExtraGateWidth ) + ) ) + ( BinarySearchInitTable + PWidthSearchTable + 0 + ( difference ( length ( NPSearchGetWidthVectorFromWidthData PWidthData ) ) 1 ) + ( difference ( length ( NPSearchGetWidthVectorFromWidthData PWidthData ) ) 1 ) ) + +) + + ; if we're searching width now, then make first real guess ( # of columns is final now ) + ; we have CellRegionData from the last run...all we care about is the number of columns, + ; and the height of the regions which will change only if the current search table + ; is the ColumnSearchTable + (cond ( + ( and ( equal CurrentSearchTable NWidthSearchTable ) + ( null NMinimumTrialMaximumTriple ) ) + (defvar NMinimumTrialMaximumTriple + ( NPSearchGetMinimumTrialMaximumTriple + ( PlacementRegionsGetTotalNRegionHeight CellRegionData ) + NWidthData + NColumnWidthParamName + PColumnWidthParamName + CellView + SuperStackLibraryName + NSuperStackCellName + GateSuperStackCellName + SuperStackViewName + NChainLibCellPairRegExs + GateLibCellPairRegExs + UserUnitsPerMeter + 1e-9 + ( list MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight ) + GNDNetName + VddNetName + PreferEvenFolds + nil ) ) + ( BinarySearchInitTable + NWidthSearchTable + ( car NMinimumTrialMaximumTriple ) + ( caddr NMinimumTrialMaximumTriple ) + ( min + ( caddr NMinimumTrialMaximumTriple ) + ( plus ( cadr NMinimumTrialMaximumTriple ) 1 ) ) ) ) + ( + ( and ( equal CurrentSearchTable PWidthSearchTable ) + ( null PMinimumTrialMaximumTriple ) ) + (defvar PMinimumTrialMaximumTriple + ( NPSearchGetMinimumTrialMaximumTriple + ( PlacementRegionsGetTotalPRegionHeight CellRegionData ) + PWidthData + PColumnWidthParamName + NColumnWidthParamName + CellView + SuperStackLibraryName + PSuperStackCellName + GateSuperStackCellName + SuperStackViewName + PChainLibCellPairRegExs + GateLibCellPairRegExs + UserUnitsPerMeter + 1e-9 + ( list MaxNonPowerMergeHeight + MaxPowerMergeHeight + MaxMergeHeight + ) + GNDNetName + VddNetName + PreferEvenFolds + nil ) ) + ( BinarySearchInitTable + PWidthSearchTable + ( car PMinimumTrialMaximumTriple ) + ( caddr PMinimumTrialMaximumTriple ) + ( min + ( caddr PMinimumTrialMaximumTriple ) + ( plus ( cadr PMinimumTrialMaximumTriple ) 1 ) ) ) ) ) + + + + ;choose widths + (defvar NWidth + ( NPSearchGetWidthFromIndex + NWidthData + (if ( equal CurrentSearchTable NWidthSearchTable ) + ( arrayref NWidthSearchTable "trial" ) + ( arrayref NWidthSearchTable "max" ) ) ) ) + (defvar PWidth + ( NPSearchGetWidthFromIndex + PWidthData + (if ( equal CurrentSearchTable PWidthSearchTable ) + ( arrayref PWidthSearchTable "trial" ) + ( arrayref PWidthSearchTable "max" ) ) ) ) + + + ( printf "NWidthData comp: %L\n" ( tableToList ( nth 0 NWidthData ) ) ) + ( printf "NWidthData gate: %L\n" ( tableToList ( nth 1 NWidthData ) ) ) + + ( printf "PWidthData comp: %L\n" ( tableToList ( nth 0 PWidthData ) ) ) + ( printf "PWidthData gate: %L\n" ( tableToList ( nth 1 PWidthData ) ) ) + + ( printf "NWidthSearchTable: %L\n" ( tableToList NWidthSearchTable ) ) + ( printf "PWidthSearchTable: %L\n" ( tableToList PWidthSearchTable ) ) + + + ( printf "NWidth: %f\n" NWidth ) + ( printf "PWidth: %f\n" PWidth ) + + + ( dbSave CellView ) + CellView + ) + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/npsearch.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/npsearch.il new file mode 100644 index 0000000000..fbd93a0bb4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/npsearch.il @@ -0,0 +1,949 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun NPSearchSnapToGrid ( GridWidth value ) + ceiling( (value - UserUnitsPerMeter*M2StrutOffset) /GridWidth)*GridWidth + UserUnitsPerMeter*M2StrutOffset +) +;snap to n+1/2 grid so that it lines up with Metal2 power strip. + +(defun NPSearchMakeWidthData ( ComponentInfoListTable + GateComponentInfoListTable + WidthVector + MinFitWidth ) + ( list ComponentInfoListTable + GateComponentInfoListTable + WidthVector + MinFitWidth ) ) + +;npwidth data +(defun NPSearchGetComponentInfoListTableFromWidthData ( WidthData ) + ( nth 0 WidthData ) ) + +(defun NPSearchGetGateComponentInfoListTableFromWidthData ( WidthData ) + ( nth 1 WidthData ) ) + +(defun NPSearchGetWidthVectorFromWidthData ( WidthData ) + ( nth 2 WidthData ) ) + +(defun NPSearchGetMinFitWidthFromWidthData ( WidthData ) + ( nth 3 WidthData ) ) + +;component info +(defun NPSearchMakeComponentInfo ( Instance Width Height ) + ( list ( getq Instance name ) Width Height ) ) + +(defun NPSearchGetInstance ( ComponentInfo ) + ( nth 0 ComponentInfo ) ) + +(defun NPSearchGetWidth ( ComponentInfo ) + ( nth 1 ComponentInfo ) ) + +(defun NPSearchGetHeight ( ComponentInfo ) + ( nth 2 ComponentInfo ) ) + +;componetn info lists are in order of increasing width +(defun NPSearchGetMinHeightComponentInfoFromColumnWidth ( ComponentInfoList ColumnWidth ) + ( while ( and ( cdr ComponentInfoList ) + ( leqp ( NPSearchGetWidth ( cadr ComponentInfoList ) ) ColumnWidth ) ) + (let () + ( setq ComponentInfoList ( cdr ComponentInfoList ) ) ) + ) + ( car ComponentInfoList ) ) + +(defun NPSearchGetMinHeightFromColumnWidth ( ComponentInfoList ColumnWidth ) + ( NPSearchGetHeight ( NPSearchGetMinHeightComponentInfoFromColumnWidth + ComponentInfoList + ColumnWidth ) ) ) + +(defun NPSearchGetMaxWidthFromColumnWidth ( ComponentInfoList ColumnWidth ) + ( NPSearchGetWidth ( NPSearchGetMinHeightComponentInfoFromColumnWidth + ComponentInfoList + ColumnWidth ) ) ) + + + + + + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Component Info Lists +;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;; +;; GATE +;;;;;;;;; + +(defun NPSearchGateGetNRange ( Gate EvilGatePRegionOffset ) + ( RectGetXRange + ( NPSearchGateGetNRect + Gate + EvilGatePRegionOffset ) ) ) + +(defun NPSearchGateGetPRange ( Gate EvilGatePRegionOffset ) + ( RectGetXRange + ( NPSearchGateGetPRect + Gate + EvilGatePRegionOffset ) ) ) + +(defun NPSearchGateGetNRect ( Gate EvilGatePRegionOffset ) + (let ( + ( Box ( getq ( getq Gate master ) bBox ) ) ) + ( dbTransformBBox + ( list + ( car Box ) + ( list + EvilGatePRegionOffset + ( RectGetTop Box ) ) ) + ( getq Gate transform ) ) ) ) + +(defun NPSearchGateGetPRect ( Gate EvilGatePRegionOffset ) + (let ( + ( Box ( getq ( getq Gate master ) bBox ) ) ) + ( dbTransformBBox + ( list + ( list + EvilGatePRegionOffset + ( RectGetBottom Box ) ) + ( cadr Box ) + ) + ( getq Gate transform ) ) ) ) + +(defun NPSearchGateGetNWidth ( Gate EvilGatePRegionOffset ) + ( RangeGetSize + ( NPSearchGateGetNRange + Gate + EvilGatePRegionOffset ) ) ) + +(defun NPSearchGateGetPWidth ( Gate EvilGatePRegionOffset ) + ( RangeGetSize + ( NPSearchGateGetPRange + Gate + EvilGatePRegionOffset ) ) ) + +(defun NPSearchGateGetComponentInfo ( Gate Folds EvilGatePRegionOffset ExtraGateWidth ReturnFunc ) + ( cond ( + ( NPSearchGateCanOverrideFolds Gate ) + ( NPSearchGateSetFolds Gate Folds ) ) ) + (let ( + ( NWidth ( plus ExtraGateWidth + ( NPSearchGateGetNWidth Gate EvilGatePRegionOffset ) ) ) + ( PWidth ( plus ExtraGateWidth + ( NPSearchGateGetPWidth Gate EvilGatePRegionOffset ) ) ) + ( Height ( RectGetHeight ( getq Gate bBox ) ) ) + ) + ( apply ReturnFunc ( list Gate NWidth PWidth Height ) ) ) ) + +;gets a list of infos in order of decreasing width +;includes with/without well plugs +(defun NPSearchGateGetComponentInfoList ( Gate MinFolds MaxFolds EvilGatePRegionOffset ExtraGateWidth ReturnFunc ) + (let ( + ( GateComponentInfoList nil ) + ) + ( cond ( + ( NPSearchGateCanOverrideFolds Gate ) + ( NPSearchGateSetOverrideFolds Gate "TRUE" ) + ( for Folds MinFolds MaxFolds + ( setq GateComponentInfoList + ( cons + ( NPSearchGateGetComponentInfo + Gate + Folds + EvilGatePRegionOffset + ExtraGateWidth + ReturnFunc ) + GateComponentInfoList ) ) + ) + ( NPSearchGateSetOverrideFolds Gate nil ) + ) + ( + t + ( setq GateComponentInfoList + ( cons + ( NPSearchGateGetComponentInfo + Gate + 0 + EvilGatePRegionOffset + ExtraGateWidth + ReturnFunc ) + GateComponentInfoList ) ) + ) ) + ;sort in decreasing width + ( ListUniq + ( sort ( copy GateComponentInfoList ) + (lambda ( ComponentInfo1 ComponentInfo2 ) + ( or ( lessp ( NPSearchGetWidth ComponentInfo1 ) + ( NPSearchGetWidth ComponentInfo2 ) ) + ( greaterp ( NPSearchGetHeight ComponentInfo1 ) + ( NPSearchGetHeight ComponentInfo2 ) ) + ) ) ) ) ) ) + +(defun NPSearchGateGetNComponentInfoList ( Gate MinFolds MaxFolds EvilGatePRegionOffset ExtraGateWidth ) + ( NPSearchGateGetComponentInfoList + Gate + MinFolds + MaxFolds + EvilGatePRegionOffset + ExtraGateWidth + (lambda ( Instance NWidth PWidth Height ) ( NPSearchMakeComponentInfo Instance NWidth Height ) ) ) ) + +(defun NPSearchGateGetPComponentInfoList ( Gate MinFolds MaxFolds EvilGatePRegionOffset ExtraGateWidth ) + ( NPSearchGateGetComponentInfoList + Gate + MinFolds + MaxFolds + EvilGatePRegionOffset + ExtraGateWidth + (lambda ( Instance NWidth PWidth Height ) ( NPSearchMakeComponentInfo Instance PWidth Height ) ) ) ) + +(defun NPSearchGateSetFolds ( Gate Folds ) + ( dbReplaceProp Gate "Folds" "int" Folds ) ) + +(defun NPSearchGateGetFolds ( Gate ) + ( PropGetPropValueForPropName ( getq ( getq Gate master ) prop ) "folds" ) ) + +(defun NPSearchGateSetOverrideFolds ( Gate Value ) + ( dbReplaceProp Gate "override_folds" "boolean" Value ) ) + +(defun NPSearchGateCanOverrideFolds ( Gate ) + ( exists Value ( getq ( NPSearchGateGetParameterProp Gate ) value ) ( equal ( getq Value name ) "override_folds" ) ) ) + +(defun NPSearchGateGetParameterProp ( Gate ) + ( car ( exists Property ( getq ( getq ( getq Gate master ) superMaster ) prop ) ( equal ( getq Property name ) "parameters" ) ) ) ) + + + + +;;;;;;;;;;;;;;;;;;;;;; +;; N and P components +;;;;;;;;;;;;;;;;;;;;;;; + +(defun NPSearchChainGetComponentInfo ( Component + Folds + ComponentRegionOffsetFromColumnCenter + TransistorDiffusionToBBoxDistance + ExtraGateWidth ) + (let ( + ( Strength ( difference ( RectGetWidth ( getq Component bBox ) ) + ( times 2.0 TransistorDiffusionToBBoxDistance ) ) ) + ) + (let ( + ( Width ( plus ComponentRegionOffsetFromColumnCenter + ( plus ( quotient Strength ( float ( plus Folds 1 ) ) ) + ( times 2.0 TransistorDiffusionToBBoxDistance ) + ExtraGateWidth + ) ) ) + ( Height ( times ( plus Folds 1 ) ( RectGetHeight ( getq Component bBox ) ) ) ) + ) + + ( NPSearchMakeComponentInfo Component Width Height ) ) ) ) + +(defun NPSearchChainGetComponentInfoList ( Component + MinFolds + MaxFolds + ComponentRegionOffsetFromColumnCenter + TransistorDiffusionToBBoxDistance + PreferEvenFolds + ExtraGateWidth ) + (let ( + ( ComponentInfoList nil ) ) + ( for Folds MinFolds MaxFolds + (if ( or ( not PreferEvenFolds ) + ( equal Folds 0 ) + ( equal ( mod Folds 2 ) 1 ) ) + ( setq ComponentInfoList + ( cons ( NPSearchChainGetComponentInfo + Component + Folds + ComponentRegionOffsetFromColumnCenter + TransistorDiffusionToBBoxDistance + ExtraGateWidth ) + ComponentInfoList ) ) ) ) + ComponentInfoList ) ) + +;;;;;;;;;;;; +;; API +;;;;;;;;;;;; + +(defun NPSearchGetMaxWidthMeanWidthRatioFromWidthData ( WidthData PossibleColumnWidth ) + ( NPSearchGetMaxWidthMeanWidthRatio + ( append + ( mapcar `cadr ( tableToList + ( NPSearchGetComponentInfoListTableFromWidthData WidthData ) ) ) + ( mapcar `cadr ( tableToList + ( NPSearchGetGateComponentInfoListTableFromWidthData WidthData ) ) ) ) + PossibleColumnWidth ) ) + + +(defun NPSearchGetMaxWidthMeanWidthRatio ( AllComponentInfoLists PossibleColumnWidth ) + ;max/mean/dev/null" TempDirForThisRun ) ) + + ) ) ) ) ) ) + + +(defun PlacerGetColumnsFromCellRegionData ( CellRegionData + GateClasses + NClasses + PClasses + NRegionOffsetFromColumnCenter + PRegionOffsetFromColumnCenter + EvilGatePRegionOffset ) + ( ListNonDestructiveMapCan + (lambda ( ColumnData ) + (let ( + ( NRegionRect ( PlacementRegionGetColumnNRegionRect + ColumnData ) ) + ( PRegionRect ( PlacementRegionGetColumnPRegionRect + ColumnData ) ) + ( NPRegionParity ( PlacementRegionGetNPRegionParity + ColumnData ) ) + ( TopGateRegionRect ( PlacementRegionGetColumnTopGateRegionRect + ColumnData ) ) + ( BottomGateRegionRect ( PlacementRegionGetColumnBottomGateRegionRect ColumnData ) ) + ( NPRegionParity + ( PlacementRegionGetNPRegionParity + ColumnData ) ) ) + ( list + ( list + ( PlacementRegionsGateRegionToPlacementRowRect + ( RectGetBoundRect ( PlacementRegionGetColumnBottomGateRegionRect ColumnData ) + ( PlacementRegionGetColumnTopGateRegionRect ColumnData ) ) + ( plus + (if NPRegionParity EvilGatePRegionOffset -EvilGatePRegionOffset ) + ( RectGetWidth + (if NPRegionParity PRegionRect NRegionRect ) ) ) ) + + "origin" + GateClasses + (if NPRegionParity ( list "MY" "R180" ) ( list "R0" "MX" ) ) ) + ( list + (if NPRegionParity + ( PlacementRegionsRightRegionToPlacementRowRect + NRegionRect + NRegionOffsetFromColumnCenter ) + ( PlacementRegionsLeftRegionToPlacementRowRect + NRegionRect + NRegionOffsetFromColumnCenter ) ) + (if NPRegionParity "left" "right" ) + NClasses + (if NPRegionParity ( list "MY" "R180" ) ( list "R0" "MX" ) ) ) + ( list + (if NPRegionParity + ( PlacementRegionsLeftRegionToPlacementRowRect + PRegionRect + PRegionOffsetFromColumnCenter ) + ( PlacementRegionsRightRegionToPlacementRowRect + PRegionRect + PRegionOffsetFromColumnCenter ) ) + (if NPRegionParity "right" "left" ) + PClasses + (if NPRegionParity ( list "MY" "R180" ) ( list "R0" "MX" ) ) ) ) ) ) + ( PlacementRegionsGetCellRegionDataColumnList + CellRegionData ) ) ) + +(defun PlacerGetBBoxString ( BBox ) + ( sprintf nil "%f %f %f %f" + ( caar BBox ) + ( cadar BBox ) + ( caadr BBox ) + ( cadadr BBox ) ) ) + +(defun PlacerGetOrientString ( Orient ) + (cond ( + ( equal ( substring Orient 1 1 ) "R" ) + ( substring + Orient + 2 + ( difference ( strlen Orient ) 1 ) + ) ) + ( + ( equal Orient "MX" ) + "X0" ) + ( + ( equal Orient "MY" ) + "Y0" ) + ( + ( equal Orient "MXR90" ) + "X90" ) + ( + ( equal Orient "MYR90" ) + "Y90" ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placer.pl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placer.pl new file mode 100755 index 0000000000..7e2f5755e7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placer.pl @@ -0,0 +1,49 @@ +#!/usr/intel/bin/perl + +$spec_file=$ARGV[0]; +$dsn_file=$ARGV[1]; + +open spec, "<$spec_file" or die; +while() { + chop; + if(!($_ =~ "^#")) { + if(! ($_ =~ "^define")) { + @fields = split(/ /); + $componentClass = $fields[0]; + $instanceMap{$componentClass} = []; + @components = @fields[1..$#fields]; + for $component (@components) { + $classMap{$component} = $componentClass; + } + } + } +} + +open dsn, "<$dsn_file" or die; +while() { + if(/[ \t]*\(constant image:(.*) (.*)\)/) { + $instance = $1; + $component = $2; + $componentClass = $classMap{$component}; + if($componentClass) { + push @{ $instanceMap{$componentClass} } , $instance; + } + } +} + +for $componentClass (keys(%instanceMap)) { + print "define (standard_cell (image_type $componentClass))\n"; + @instances = @{ @instanceMap{$componentClass} }; + foreach $instance (@instances) { + print "image_property $instance (type $componentClass)\n"; + } +} + +open spec, "<$spec_file" or die; +while() { + if(!($_ =~ "^#")) { + if($_ =~ "^define") { + print $_; + } + } +} diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placercheck.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placercheck.il new file mode 100644 index 0000000000..c4a192d989 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placercheck.il @@ -0,0 +1,33 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: PlacerCheck +; Parameter: CellView (CVId) +; Return: nil +; +; Run DRC on placed view. +; +; +defun( PlacerCheck ( TargetViewName PlacerCheckDRCAssuraSets ) + + (let ( + ( CellView ( dbOpenCellViewByType + LibName + CellName + TargetViewName + "maskLayout" + "a" ) ) + ) + + ( setq PlacementGood ( AssuraRunDRC + CellView + PlacerCheckDRCRuleFile + PlacerCheckDRCAssuraSets + WorkingDir + ( sprintf nil "%s/%s" AssuraPlacerCheckDRCDir TargetViewName ) + ) ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placerhack.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placerhack.il new file mode 100644 index 0000000000..cf1388d515 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placerhack.il @@ -0,0 +1,426 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ +(defun PlacerHackFindInstancesInRect ( Instances Rect ) + (setof + Instance + Instances + ( RectDoRectsOverlap + ( getq Instance bBox ) + Rect ) ) ) + +(defun PlacerHackInstancesSortFunc ( Instance0 Instance1 ) + (let ( + ( Rect0 ( getq Instance0 bBox ) ) + ( Rect1 ( getq Instance1 bBox ) ) ) + (let ( + ( Top0 ( RectGetBottom Rect0 ) ) + ( Top1 ( RectGetBottom Rect1 ) ) ) + ( lessp Top0 Top1 ) ) ) ) + + +(defun PlacerHackCreateTransitorToGroupTable ( TransistorGroups ) + (let ( + ( Ret ( makeTable "foo" ) ) ) + ( foreach + Group + TransistorGroups + ( foreach + Transistor + Group + ( setarray + Ret + ( getq Transistor name ) + Group ) ) ) + Ret ) ) + + +(defun PlacerHackGetBottomOfTransistorGateFromInstance ( Instance GateLengthParamName UserUnitsPerMeter ) + (let ( + ( RotationStr ( getq Instance orient ) ) + ( GateLengthProp ( dbSearchPropByName Instance GateLengthParamName ) ) ) + (let ( + ( GateLengthPropValue ( getq GateLengthProp value ) ) ) + (let ( + ( GateLength + (if ( stringp GateLengthPropValue ) + ( StringUtilParseLengthString GateLengthPropValue ) + GateLengthPropValue ) ) ) + (when GateLength + (cond + ( + ( equal RotationStr "R90" ) + ( cadr ( getq Instance xy ) ) ) + ( + ( equal RotationStr "R270" ) + ( difference + ( cadr ( getq Instance xy ) ) + ( times GateLength UserUnitsPerMeter ) ) ) + ( t + nil ) ) ) ) ) ) ) + + +(defun PlacerHackIsGateInstance ( Instance GateLibName ) + ( equal GateLibName ( getq Instance libName ) ) ) + + +(defun PlacerHackGetAdjacentTransistorPairInfos ( SortedInstancesList + TransistorLibName + TransistorCellName + TransistorViewName + TransistorToGroupTable ) + (let ( + ( LastTransistorInstance nil ) + ( BelowInstances nil ) + ( DuringInstances nil ) + ( CurrInstancesList SortedInstancesList ) + ( Infos nil ) ) + (while CurrInstancesList + (let ( + ( CurrInstance ( car CurrInstancesList ) ) ) + ( setq CurrInstancesList ( cdr CurrInstancesList ) ) + (if ( and + ( equal + TransistorLibName + ( getq CurrInstance libName ) ) + ( equal + TransistorCellName + ( getq CurrInstance cellName ) ) + ( equal + TransistorViewName + ( getq CurrInstance viewName ) ) ) + (let ( + ( CurrTransistorInstance CurrInstance ) ) + (when LastTransistorInstance + ( setq + Infos + ( cons + ( list + LastTransistorInstance + CurrTransistorInstance + BelowInstances + ( cons CurrTransistorInstance CurrInstancesList ) + ( ListRemoveDuplicates + ( ListApplyFuncToListAndAccumulateResult + DuringInstances + (lambda + ( DuringInstance CurrResult TransistorToGroupTable ) + (let ( + ( Group ( arrayref + TransistorToGroupTable + ( getq DuringInstance name ) ) ) ) + (if Group + (let ( + ( Ret CurrResult ) ) + ( foreach + GroupMember + Group + ( setq Ret ( cons GroupMember Ret ) ) ) + Ret ) + ( cons + DuringInstance + CurrResult ) ) ) ) + ( list TransistorToGroupTable ) + nil ) + (lambda + ( Inst0 Inst1 ) + ( equal ( getq Inst0 name ) ( getq Inst1 name ) ) ) + nil ) ) + Infos ) ) ) + ( setq DuringInstances nil ) + ( setq LastTransistorInstance CurrTransistorInstance ) ) + ( setq DuringInstances ( cons CurrInstance DuringInstances ) ) ) + ( setq BelowInstances ( cons CurrInstance BelowInstances ) ) ) ) + Infos ) ) + +(defun PlacerHackGetDiffusionRectsFromInstance ( TransistorInstance + DiffusionLPP ) + (let ( + ( DiffusionLayerName ( car DiffusionLPP ) ) + ( DiffusionPurposeName ( cadr DiffusionLPP ) ) + ( Master ( getq TransistorInstance master ) ) ) + ( dbComputeBBox Master ) + (let ( + ( DiffusionShapesInMaster ( dbProduceOverlap + Master + ( getq Master bBox ) + ( list 0 0 ) + DiffusionLayerName ) ) ) + (let ( + ( DiffusionRectsInMaster ( setof + Shape + DiffusionShapesInMaster + ( equal + "rect" + ( getq Shape objType ) ) ) ) ) + + ( ListApplyFuncToListAndAccumulateResults + DiffusionRectsInMaster + (lambda + ( Rect Transform ) + ( dbTransformBBox ( getq Rect bBox ) Transform ) ) + ( list + ( getq TransistorInstance transform ) ) ) ) ) ) ) + +(defun PlacerHackGetTopOfDiffusionFromInstance ( TransistorInstance + DiffusionLPP ) + (let ( + ( DiffusionRects ( PlacerHackGetDiffusionRectsFromInstance + TransistorInstance + DiffusionLPP ) ) + ( CurrTop nil ) ) + ( foreach + Rect + DiffusionRects + (when ( or + ( null CurrTop ) + ( greaterp + ( RectGetTop Rect ) + CurrTop ) ) + ( setq CurrTop ( RectGetTop Rect ) ) ) ) + CurrTop ) ) + +(defun PlacerHackGetBottomOfDiffusionFromInstance ( TransistorInstance + DiffusionLPP ) + (let ( + ( DiffusionRects ( PlacerHackGetDiffusionRectsFromInstance + TransistorInstance + DiffusionLPP ) ) + ( CurrBottom nil ) ) + ( foreach + Rect + DiffusionRects + (when ( or + ( null CurrBottom ) + ( lessp + ( RectGetBottom Rect ) + CurrBottom ) ) + ( setq CurrBottom ( RectGetBottom Rect ) ) ) ) + CurrBottom ) ) + + +(defun PlacerHackFindInstancePairsWithIllegalDiffusionSpacings ( InstancePairInfos + DiffusionLPP + MinDiffusionSpacing ) + ( ListApplyFuncToListAndAccumulateNonNilResults + InstancePairInfos + (lambda + ( InstancePairInfo DiffusionLPP MinDiffusionSpacing ) + (let ( + ( TopInstance ( cadr InstancePairInfo ) ) + ( BottomInstance ( car InstancePairInfo ) ) + ( BelowInstances ( caddr InstancePairInfo ) ) + ( AboveInstances ( cadddr InstancePairInfo ) ) + ( DuringInstances ( nth 4 InstancePairInfo ) ) ) + (let ( + ( BottomOfTopInstanceDiffusion + ( PlacerHackGetBottomOfDiffusionFromInstance + TopInstance + DiffusionLPP ) ) + ( TopOfBottomInstanceDiffusion + ( PlacerHackGetTopOfDiffusionFromInstance + BottomInstance + DiffusionLPP ) ) ) + (let ( + ( CurrDiffusionSpacing + ( difference + BottomOfTopInstanceDiffusion + TopOfBottomInstanceDiffusion ) ) ) + (unless ( or + ( lessp CurrDiffusionSpacing 0.0001 ) + ( equal CurrDiffusionSpacing MinDiffusionSpacing ) + ( greaterp CurrDiffusionSpacing MinDiffusionSpacing ) ) + ( list + BottomInstance + TopInstance + BelowInstances + AboveInstances + DuringInstances + CurrDiffusionSpacing ) ) ) ) ) ) + ( list + DiffusionLPP + MinDiffusionSpacing ) ) ) + +(defun PlacerHackFixIllegalSpacings ( IllegalSpacingInfos + TopInstance + BottomInstance + RegionTop + RegionBottom + CorrectSpacing ) + ( foreach + IllegalSpacingInfo + IllegalSpacingInfos + (let ( + ( RequiredDisplacement ( difference + ( float CorrectSpacing ) + ( float + ( nth 5 IllegalSpacingInfo ) ) ) ) + ( TopDistance ( abs + ( difference + RegionTop + ( RectGetTop + ( getq TopInstance bBox ) ) ) ) ) + ( BottomDistance ( abs + ( difference + RegionBottom + ( RectGetBottom + ( getq BottomInstance bBox ) ) ) ) ) + ( BelowInstances ( caddr IllegalSpacingInfo ) ) + ( AboveInstances ( cadddr IllegalSpacingInfo ) ) + ( DuringInstances ( nth 4 IllegalSpacingInfo ) ) ) + ( printf + "Top: %L %L Bottom:%L %L %L\n" + ( getq ( nth 1 IllegalSpacingInfo ) name ) + ( getq ( nth 1 IllegalSpacingInfo ) xy ) + ( getq ( nth 0 IllegalSpacingInfo ) name ) + ( getq ( nth 0 IllegalSpacingInfo ) xy ) + ( nth 5 IllegalSpacingInfo ) ) + (let ( + ( DirectedDisplacement (if ( greaterp BottomDistance TopDistance ) + ( difference 0.0 RequiredDisplacement ) + RequiredDisplacement ) ) + ( InstancesToMove ( ListRemoveDuplicates + ( append + (if DuringInstances + ( reverse DuringInstances ) + ( list ) ) + (if ( greaterp BottomDistance TopDistance ) + ( reverse BelowInstances ) + AboveInstances ) ) + (lambda + ( Inst0 Inst1 ) + ( equal ( getq Inst0 name ) ( getq Inst1 name ) ) ) + nil ) ) ) + ( foreach + Instance + InstancesToMove + (let () + ( dbMoveFig + Instance + nil + ( list + ( list 0 DirectedDisplacement ) + "R0" ) ) + ( printf + "Moved %L by %L\n" + ( getq Instance name ) + DirectedDisplacement ) ) ) ) ) ) ) + + + +(defun PlacerHackFixCell ( CellView + CellRegionData + LibsToIgnore + CellsToIgnore + TransistorLibName + NTransistorCellName + PTransistorCellName + TransistorViewName + DiffusionLPP + MinDiffusionSpacing ) + (let ( + ( CurrCol 0 ) + ( FilteredInstances ( UpdateNetlistFilterInstances + CellView + LibsToIgnore + CellsToIgnore ) ) ) + ( foreach + Column + ( PlacementRegionsGetCellRegionDataColumnList + CellRegionData ) + (let ( + ( ColumnRect ( PlacementRegionGetColumnBBox Column ) ) ) + ( setq CurrCol ( plus CurrCol 1 ) ) + (let ( + ( ColumnInstances ( PlacerHackFindInstancesInRect + FilteredInstances + ColumnRect ) ) ) + (when ColumnInstances + (let ( + ( SortedColumnInstances ( sort + ColumnInstances + `PlacerHackInstancesSortFunc ) ) ) + + (let ( + ( InstanceGroupsTable + ( PlacerHackCreateTransitorToGroupTable + ( GuessPlacementRegionsGroupTransistorInstances + SortedColumnInstances ) ) ) + ( TopInstance ( nth + ( difference + ( length SortedColumnInstances ) + 1 ) + SortedColumnInstances ) ) + ( BottomInstance ( car SortedColumnInstances ) ) + ( ColumnTop ( RectGetTop ColumnRect ) ) + ( ColumnBottom ( RectGetBottom ColumnRect ) ) ) + ( PlacerHackFixIllegalSpacings + ( PlacerHackFindInstancePairsWithIllegalDiffusionSpacings + ( PlacerHackGetAdjacentTransistorPairInfos + SortedColumnInstances + TransistorLibName + NTransistorCellName + TransistorViewName + InstanceGroupsTable ) + DiffusionLPP + MinDiffusionSpacing ) + TopInstance + BottomInstance + ColumnTop + ColumnBottom + MinDiffusionSpacing ) + + ( PlacerHackFixIllegalSpacings + ( PlacerHackFindInstancePairsWithIllegalDiffusionSpacings + ( PlacerHackGetAdjacentTransistorPairInfos + SortedColumnInstances + TransistorLibName + PTransistorCellName + TransistorViewName + InstanceGroupsTable ) + DiffusionLPP + MinDiffusionSpacing ) + TopInstance + BottomInstance + ColumnTop + ColumnBottom + MinDiffusionSpacing ) ) ) ) ) ) ) ) + t ) + + +(defun PlacerHackFixCellWithTechnologyInfo ( CellView + CellRegionData + LibsToIgnore + CellsToIgnore + TransistorLibName + NTransistorCellName + PTransistorCellName + TransistorViewName + DiffusionLPP ) + (let ( + ( MinDiffusionSpacing + ( SpacingGetSameLayerSpacingForLayer + CellView + DiffusionLPP ) ) ) + (if MinDiffusionSpacing + ( PlacerHackFixCell + CellView + CellRegionData + LibsToIgnore + CellsToIgnore + TransistorLibName + NTransistorCellName + PTransistorCellName + TransistorViewName + DiffusionLPP + MinDiffusionSpacing ) + ( printf "\nERROR: Unable to get minimum diffusion spacing.\n" ) ) ) ) + +;( PlacerHackFindInstancePairsWithIllegalDiffusionSpacings ( sort ( PlacerHackFindInstancesInRect ( UpdateNetlistFilterInstances ( geGetWindowCellView ) ( list ) ( list "M3_M2_min" ) ) ( PlacementRegionGetColumnNRegionRect ( car ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) ) ) ) `PlacerHackInstancesSortFunc ) "gate" ( list "DIFF" "drawing" ) 0.21 ) + +;( sort ( PlacerHackFindInstancesInRect ( UpdateNetlistFilterInstances ( getq ( geGetWindowCellView ) instances ) ( list ) ( list "M3_M2_min" ) ) ( PlacementRegionGetColumnNRegionRect ( car ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) ) ) ) `PlacerHackInstancesSortFunc ) + + + +;( PlacerHackFindInstancePairsWithIllegalDiffusionSpacings (let ( ( Instances ( sort ( PlacerHackFindInstancesInRect ( UpdateNetlistFilterInstances ( geGetWindowCellView ) ( list ) ( list "M3_M2_min" ) ) ( list ( list 0.105 0.910 ) ( list 14.105 37.490 ) ) ) `PlacerHackInstancesSortFunc ) ) ) ( PlacerHackGetAdjacentTransistorPairInfos Instances "tsmc13lg" "nmos1v" "layout" ( PlacerHackCreateTransitorToGroupTable ( GuessPlacementRegionsGroupTransistorInstances Instances ) ) ) ) ( list "DIFF" "drawing" ) 0.21 ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.il new file mode 100644 index 0000000000..d93e810e3c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.il @@ -0,0 +1,88 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: PlacerSearch +; Parameter: none +; Return: PlacerSearchStatus = nil We do not yet have a placed view +; RPlacerSearchStatus = 1 We have a placed view, but trying to do better +; PlacerSearchStatus = t Search is done +; +; Main program of running placer. +; +; + +defun( PlacerSearch ( ) + + +CurrentPlacedOnlyViewName= (if OptionKeepPlacerViewHistory + sprintf( nil "%s_%d" PlacedOnlyViewName CurrentStepNumber ) PlacedOnlyViewName ) +CurrentPlacedScratchViewName= (if OptionKeepPlacerViewHistory + sprintf( nil "%s_%d" PlacedScratchViewName CurrentStepNumber ) PlacedScratchViewName ) +CurrentPreRouteScratchViewName= (if OptionKeepPlacerViewHistory + sprintf( nil "%s_%d" PreRouteScratchViewName CurrentStepNumber ) PreRouteScratchViewName ) + +CurrentPlacedViewName= sprintf( nil "%s_%d" PlacedViewName CurrentStepNumber ) +CurrentPreRouteViewName= sprintf( nil "%s_%d" PreRouteViewName CurrentStepNumber ) +CurrentStepNumber= CurrentStepNumber + 1 + + +;NWidth = nth( arrayref(NWidthSearchTable "trial") caddr(NWidthData)) +;PWidth = nth( arrayref(PWidthSearchTable "trial") caddr(PWidthData)) +;if((PWidth > 2.8) then PWidth = 2.8) +;if((NWidth > 2.8) then NWidth = 2.8) + +CreateSchematicView() +ScratchView = CopyView( GenFromSourceViewName ScratchViewName ) +errset( initnp( ScratchView ) t) +;errset( WellPlugsOff( ScratchView ) t) +errset( FoldGates( ScratchView ) t) +errset( TurnOffGateContact( ScratchView ) t) +errset( FoldAndChain( ScratchView ) t) +errset( GuessPlacementRegions( ScratchView ) t) +errset( PlacementRegions( ScratchView ) t) +errset( AddPinsToCellView( ScratchView nil ?power nil) t) + +RunPlacer( ScratchViewName CurrentPlacedOnlyViewName ) + +ScratchView = CopyView( CurrentPlacedOnlyViewName ScratchViewName ) +errset( CompactSuperstacks( ScratchView ) t) +errset( InlineSuperstacks( ScratchView t ) t) +errset( TurnOffGateContact( ScratchView ) t) +;SnapGatesStacksToPitch( ScratchView ) + +; Well plugs are to satisfy DRC rule of a wellplug every 30um + +errset( DeCompact( ScratchView t ) t) +;errset( AddPlugs( ScratchView ) t) +;errset( DeCompact( ScratchView t ) t) +;errset( AddPlugs( ScratchView ) t) +;errset( DeCompact( ScratchView t ) t) + +errset( Squish( ScratchView ) t) +SnapGatesStacksToPitch( ScratchView ) +errset( RegionWell( ScratchView ) t) +errset( AddPlugs( ScratchView ) t) +FixMustConnectTerm( ScratchView ) +errset( AddPinsToCellView( ScratchView nil ?power t) t) +errset( CopyView( ScratchViewName CurrentPreRouteScratchViewName ) t) +;AddBlkCell( ScratchView ) +errset( RegionWell( ScratchView ) t) +errset( DrawImplant( ScratchView ) t) +;errset( ConnectWellPlugs( ScratchView ) t) +errset( VStruts( ScratchView ) t) +errset( CurrentPlacedScratchView = CopyView( ScratchViewName CurrentPlacedScratchViewName ) t) + +printf("Start Assura Checking for view: %s\n" CurrentPlacedScratchViewName) +errset( PlacerCheck( CurrentPlacedScratchViewName (if ( not PlugsInRoutingStage ) ( list "LATCH_UP" ) ) ) t) + +errset( PlacerSearchStatus = PlacerSearchDone( CurrentPlacedScratchViewName CurrentPlacedViewName CurrentPreRouteScratchViewName CurrentPreRouteViewName ) t) + +; PlecerSearchStatus = nil ---> We do not yet have a placed view +; PlecerSearchStatus = 1 ---> We have a placed view, but trying to do better +; PlecerSearchStatus = t ---> Search is done +errset( printf( "NWidth= %f PWidth= %f\n" NWidth PWidth) t) + +PlacerSearchStatus +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.rpl b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.rpl new file mode 100644 index 0000000000..58e1b0d3ae --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearch.rpl @@ -0,0 +1,36 @@ +(defvar CurrentPlacedOnlyViewName (if OptionKeepViewHistory ( sprintf nil "%s_%d" PlacedOnlyViewName CurrentStepNumber ) PlacedOnlyViewName ) ) +(defvar CurrentPlacedScratchViewName (if OptionKeepViewHistory ( sprintf nil "%s_%d" PlacedScratchViewName CurrentStepNumber ) PlacedScratchViewName ) ) +(defvar CurrentPlacedViewName (if OptionKeepViewHistory ( sprintf nil "%s_%d" PlacedViewName CurrentStepNumber ) PlacedViewName ) ) +(defvar CurrentPreRouteScratchViewName (if OptionKeepViewHistory ( sprintf nil "%s_%d" PreRouteScratchViewName CurrentStepNumber ) PreRouteScratchViewName ) ) +(defvar CurrentPreRouteViewName (if OptionKeepViewHistory ( sprintf nil "%s_%d" PreRouteViewName CurrentStepNumber ) PreRouteViewName ) ) +(defvar CurrentStepNumber ( plus CurrentStepNumber 1 ) ) +"../../../ui/automation/copyview.rp" ( list GenFromSourceViewName ScratchViewName ) +"initnp.rp" ( list ScratchViewName ) +"foldgates.rp" ( list ScratchViewName ) +"../../chain/foldandchain.rp" ( list ScratchViewName ) +"guessplacementregions.rp" ( list ScratchViewName ) +"placementregions.rp" ( list ScratchViewName ) +"../../pins/pinplace.rp" ( list ScratchViewName t ) +"placer.rp" ( list ScratchViewName CurrentPlacedOnlyViewName ) +"../../../ui/automation/copyview.rp" ( list CurrentPlacedOnlyViewName ScratchViewName ) +"../../chain/compactsuperstacks.rp" ( list ScratchViewName ) +"../../chain/inlinesuperstacks.rp" ( list ScratchViewName nil ) +"../plugs/wellplugson.rp" ( list ScratchViewName ) +"../decompact/decompact.rp" ( list ScratchViewName nil ) +"../well/regionwell.rp" ( list ScratchViewName ) +"../plugs/addplugs.rp" ( list ScratchViewName ) +"../decompact/decompact.rp" ( list ScratchViewName t ) +"../plugs/wellplugson.rp" ( list ScratchViewName ) +"../plugs/addplugs.rp" ( list ScratchViewName ) +"../decompact/decompact.rp" ( list ScratchViewName t ) +"../../chain/inlinesuperstacks.rp" ( list ScratchViewName t ) +"squish.rp" ( list ScratchViewName ) +"../../pins/pinplace.rp" ( list ScratchViewName nil ) +"../../../ui/automation/copyview.rp" ( list ScratchViewName CurrentPreRouteScratchViewName ) +"../well/regionwell.rp" ( list ScratchViewName ) +"../implant/drawimplant.rp" ( list ScratchViewName ) +"../plugs/connectwellplugs.rp" ( list ScratchViewName ) +"../../pins/vstruts.rp" ( list ScratchViewName ) +"../../../ui/automation/copyview.rp" ( list ScratchViewName CurrentPlacedScratchViewName ) +"placercheck.rp" ( list CurrentPlacedScratchViewName (if ( not PlugsInRoutingStage ) ( list "LATCH_UP" ) ) ) +"placersearchdone.rp" ( list CurrentPlacedScratchViewName CurrentPlacedViewName CurrentPreRouteScratchViewName CurrentPreRouteViewName ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearchdone.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearchdone.il new file mode 100644 index 0000000000..d5b7dd23e2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/placersearchdone.il @@ -0,0 +1,246 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: PlacerSearchDone +; Parameter: CurrentPlacedScratchViewName (string) +; CurrentPlacedViewName (string) +; CurrentPreRouteScratchViewName (string) +; CurrentPreRouteViewName (string) + +; Return: RPLRet = nil We do not yet have a placed view +; RPLRet = 1 We have a placed view, but trying to do better +; RPLRet = t Search is done +; +; Check if everything is done with placer search. +; +; +; +defun( PlacerSearchDone ( CurrentPlacedScratchViewName + CurrentPlacedViewName + CurrentPreRouteScratchViewName + CurrentPreRouteViewName + ) + + ;step + ( SearchFindSmallestStep + CurrentSearchTable + ( lambda ( Trial ) PlacementGood ) + nil ) + + (let ( + ( PlacementComplete + ( forall SearchTable + ( list ColumnSearchTable NWidthSearchTable PWidthSearchTable ) + ( arrayref SearchTable "done" ) ) ) ) + if( PlacementGood then + PlacedView = dbOpenCellViewByType( + LibName + CellName + CurrentPlacedScratchViewName + "maskLayout" + "a" ) + PlacedAreaBoundBox = PinUtilFindPRBoundBBox( + BoundaryLPP + PlacedView ) + if((PlacedAreaBoundBox == nil ) then + PlacementGood = nil + PlacementComplete = t ; Placer exist abnormally, so do not search any more. + PlacedArea = -1 + printf( "Placer exit abnormally.]n") + ) + ) + (cond ( + PlacementGood + (let ( + ( PlacedView + ( dbOpenCellViewByType + LibName + CellName + CurrentPlacedScratchViewName + "maskLayout" + "a" ) ) + ( PreRouteView + ( dbOpenCellViewByType + LibName + CellName + CurrentPreRouteScratchViewName + "maskLayout" + "a" ) ) ) + ( dbSave + ( dbCopyCellView + PlacedView + LibName + CellName + CurrentPlacedViewName + nil + nil + t ) ) + ( dbSave + ( dbCopyCellView + PreRouteView + LibName + CellName + CurrentPreRouteViewName + nil + nil + t ) ) + PlacedAreaBoundBox = PinUtilFindPRBoundBBox( + BoundaryLPP + PlacedView ) + if((PlacedAreaBoundBox != nil) then PlacedArea = RectGetArea( PlacedAreaBoundBox ) + printf( "Placement Passed\n" ) + printf( "PlacedArea %f BestPlacedViewArea %f\n" PlacedArea BestPlacedViewArea) + printf( "%s: Column %d NWidth %f PWidth %f\n " CurrentPlacedViewName + ( arrayref ColumnSearchTable "trial" ) + nth( arrayref(NWidthSearchTable "trial") caddr(NWidthData)) + nth( arrayref(PWidthSearchTable "trial") caddr(PWidthData)) + ) + else ; double check just in case. + printf( "Placer exit abnormally.]n") + PlacedArea = -1 + PlacementComplete = t ; Placer exist abnormally, so do not search any more. + ) + (when ( PlacedArea > 0 && + PlacedArea < BestPlacedViewArea ) + (defvar BestPlacedViewArea PlacedArea ) + (defvar BestPlacedViewName CurrentPlacedViewName ) + (defvar BestPreRouteViewName CurrentPreRouteViewName ) + ) + ) ) + ( + ( printf "Placement Failed\n" ) ) ) + + (cond ( + ( or PlacementGood ( arrayref CurrentSearchTable "done" ) ) + ;if placement is good, switch to another search + ;switch to the side that has worst width ratios + ( setq CurrentSearchTable + (cond ( + ( not ( arrayref ColumnSearchTable "done" ) ) + ColumnSearchTable ) + ( + ( ListFindMaximumElement + ( setof SearchTable + ( list NWidthSearchTable PWidthSearchTable ) + ( not ( arrayref SearchTable "done" ) ) ) + (lambda ( SearchTable ) + ( NPSearchGetMaxWidthMeanWidthRatioFromWidthData + (if ( equal SearchTable NWidthSearchTable ) + NWidthData PWidthData ) + (if ( equal SearchTable NWidthSearchTable ) + NWidth PWidth ) ) ) + ) ) + ( + CurrentSearchTable ) ) ) ) ) + (defvar RPLRet nil ) + (cond ( + ;If we have a placed view, but we can do better + ;reset everything and try the next column count + ( and PlacementComplete + ( ddGetObj LibName CellName BestPlacedViewName ) + (let ( + ( PossibleArea + ( times + YPitch + ( plus ColumnCount 1 ) + ( plus + ( NPSearchGetMinFitWidthFromWidthData + NWidthData ) + ( NPSearchGetMinFitWidthFromWidthData + PWidthData ) ) ) ) ) + ( printf "%f %f" PossibleArea BestPlacedViewArea ) + ( lessp + PossibleArea + BestPlacedViewArea ) ) ) + (defvar PlacementComplate nil ) + (defvar NMinimumTrialMaximumTriple nil ) + (defvar PMinimumTrialMaximumTriple nil ) + (defvar NWidthSearchTable ( makeTable `foo ) ) + (defvar PWidthSearchTable ( makeTable `bar ) ) + (defvar NWidthData nil ) + (defvar PWidthData nil ) + (defvar CellRegionData nil ) + (defvar ColumnCount ( plus ColumnCount 1 ) ) + ( BinarySearchInitTable + ColumnSearchTable + ColumnCount + ColumnCount + ColumnCount ) + (defvar CurrentSearchTable ColumnSearchTable ) + (defvar RPLRet 1 ) + ( printf "Search for %d Columns Completed. Trying %d Columns...\n" ColumnCount-1 ColumnCount ) + + ) + ( + ;Really done + PlacementComplete + ( printf "Completed Search\n" ) + ( setq CurrentSearchTable nil ) + (when ( and BestPlacedViewName + BestPreRouteViewName + ( ddGetObj LibName CellName BestPlacedViewName ) + ( ddGetObj LibName CellName BestPreRouteViewName ) ) + (when ( not ( equal BestPlacedViewName PlacedViewName ) ) + ( dbSave + ( dbCopyCellView + ( dbOpenCellViewByType + LibName + CellName + BestPlacedViewName + "maskLayout" + "a" ) + LibName + CellName + PlacedViewName + nil + nil + t ) ) ) + (when ( not ( equal BestPreRouteViewName PreRouteViewName ) ) + ( dbSave + ( dbCopyCellView + ( dbOpenCellViewByType + LibName + CellName + BestPreRouteViewName + "maskLayout" + "a" ) + LibName + CellName + PreRouteViewName + nil + nil + t ) ) ) + ( FileUtilAppendStringToFileAndClose + LogFileName + ( sprintf + nil + "%s placed density factor: %f / %f\n" + CellName + ( quotient ( RectGetArea + (cond ( PinUtilFindPRBoundBBox( + BoundaryLPP + ( dbOpenCellViewByType + LibName + CellName + PlacedViewName + "maskLayout" + "a" ) ) ) list(0:0 0:0) )) + TotalTransistorArea ) + ( CellInfoLookup DirectiveTable "density_factor" ) || 10.00 + ) ) ) + (defvar RPLRet t ) ) + ( + t + (defvar RPLRet 1 ) + ( printf "Search Not Complete\n" ) ) ) + + (when CurrentSearchTable + ( println ( tableToList ColumnSearchTable ) ) + ( println ( tableToList NWidthSearchTable ) ) + ( println ( tableToList PWidthSearchTable ) ) ) ) + +RPLRet +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.il new file mode 100644 index 0000000000..daa9146e00 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.il @@ -0,0 +1,155 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +; $Id$ +; $DateTime$ +; $Author$ + + +; Function: RunPlacer +; Parameter: ScratchViewName (string) +; CurrentPlacedOnlyViewName (string) +; Return: PlacedOnlyCellView (CVId) +; +; Run Placer. +; +; +; + +defun( CreateSchematicView () + let( (ViewDDObj CellView) + ViewDDObj=ddGetObj( LibName CellName "schematic" ) + if( and( + ViewDDObj + ddIsObjReadable( ViewDDObj ) + car( ViewDDObj~>files ) + ddIsObjReadable( car( ViewDDObj~>files ) )) then + schView=dbOpenCellViewByType( + LibName + CellName + "schematic" + "schematic" + "r" ) + else schView=dbOpenCellViewByType( + LibName + CellName + "schematic" + "schematic" + "w" ) + dbSave(schView) + + ) + schView + ) +) + +defun( RunPlacer ( TargetViewName TargetPlacerViewName ) + +;( LicenseGetLicense "Virtuoso_Layout_Suite_GXL" VirtuosoXLVersion 0 ) + +(let ( CellView PlacerView ) + PlacerView = CopyView( TargetViewName TargetPlacerViewName ) + +( LicenseGetLicense "Virtuoso_XL" VirtuosoXLVersion 0 ) + + +vcpfeRunCustomDigitalPlacer(schView PlacerView + ?groupCMOSPairs nil + ?preserveChains nil + ?groupMFactors nil + ?allowRotation nil + ?ecoMode nil + ?globalPlacement t + ?optimizePlacement t + ?runTime "moderate" + ?insertFillerCells nil + ?insertSubstrateContacts nil + ?componentEdge "Bounding Box" + ?vcpRulesConstraintGroup "virtuosoDefaultSetup" + +) + +dbSave( PlacerView ) + +;( LicenseReturnLicense "Virtuoso_Layout_Suite_GXL" ) +( LicenseReturnLicense "Virtuoso_XL" ) + +SnapInstancesToColums( PlacerView ) + +) +) + +defun( SnapInstancesToColums ( CellView ) + let((Columns Column GateColumns PColumns NColumns) + Columns= PlacerGetColumnsFromCellRegionData( + CellRegionData + ( list GateRegionComponentClassName ) + ( list NRegionComponentClassName ) + ( list PRegionComponentClassName ) + ( times UserUnitsPerMeter NRegionOffsetFromColumnCenter ) + ( times UserUnitsPerMeter PRegionOffsetFromColumnCenter ) + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ) + GateColumns= setof( Column Columns car(caddr(Column))=="GATE") + PColumns= setof( Column Columns car(caddr(Column))=="PSTACK") + NColumns= setof( Column Columns car(caddr(Column))=="NSTACK") + + foreach( inst CellView~>instances + if( inst~>cellName== GateSuperStackCellName then + SnapToColumn( inst GateColumns ) + ) + if( inst~>cellName== PSuperStackCellName then + SnapToColumn( inst PColumns ) + ) + if( inst~>cellName== NSuperStackCellName then + SnapToColumn( inst NColumns ) + ) + ) + ) + +) + +defun( SnapToColumn ( inst Columns ) + let( (thisDist thisOrient Column bBox alignment x instX instY orient) + thisDist=1e9 + thisOrient="R0" + instX=car(inst~>xy) + instY=cadr(inst~>xy) + foreach( Column Columns + bBox=car(Column) + alignment=cadr(Column) + if( alignment=="right" then x=rightEdge(bBox) + else x=leftEdge(bBox)) + orient=car(nth(3 Column)) + if( abs(x-instX)xy=list(instX+thisDist instY) + inst->orient=thisOrient + ) +) + +defun( TurnOffGateContact ( CellView ) + let((inst) + foreach( inst CellView~>instances + if( rexMatchp("gate.NAND" inst~>cellName) || rexMatchp("gate.NOR" inst~>cellName) then + dbReplaceProp( inst "a_poly_contact" "string" "none" ) + dbReplaceProp( inst "b_poly_contact" "string" "none" ) + + ) + if( rexMatchp("gate.INV" inst->cellName) then + if( PCellGetParameterValue( inst "Folds" )<2 then + dbReplaceProp( inst "poly_contact" "string" "none" ) + else + dbReplaceProp( inst "poly_contact" "string" "both" ) + ) + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.inst b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.inst new file mode 100755 index 0000000000..e43203b5f0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.inst @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +function exit_func() { + if [ -n "$placer_il_temp" ] ; then + rm -f "$placer_il_temp" + fi +} + +trap exit_func EXIT + +sedcmd=`which sed` +chmodcmd=`which chmod` + +package_root=$1 +install_share_bin=$2 +install_share_data=$3 +install_arch_bin=$4 +install_arch_data=$5 + +placer_dir="$package_root/share/skill/layout/leaf/placer" +placer_il="$placer_dir/placer.il" +placer_il_temp=`mktemp /tmp/runplacer.inst.XXXXXX` + +runplacer_sh="$placer_dir/runplacer.sh" +runplacer_base=`basename $runplacer_sh .sh` +runplacer="$placer_dir/$runplacer_base" + +$sedcmd -e "s=\\\$packageroot\\\$=$package_root=" "$runplacer_sh" >$runplacer +$chmodcmd "--reference=$runplacer_sh" "$runplacer" +rm "$runplacer_sh" + +$sedcmd -e "s=\\\$runplacer\\\$=$runplacer=" "$placer_il" > "$placer_il_temp" +$chmodcmd "--reference=$placer_il" "$placer_il_temp" +rm "$placer_il" +cp "$placer_il_temp" "$placer_il" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.sh new file mode 100755 index 0000000000..0a8c96d9c1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/runplacer.sh @@ -0,0 +1,260 @@ +#!/bin/bash + +function usage() { + echo "Usage: $0" + echo " --src-lib=lib" + echo " --src-cell=cell" + echo " --src-lib=view" + echo " --dest-lib=lib" + echo " --dest-cell=cell" + echo " --dest-lib=view" + echo " --rule-file=file" + echo " --spec-file=file" + echo " --working-dir=dir" + echo " --log-file=file" + echo " [--conductor-depth=int" + echo " [--keepout-depth=int]" + echo " [--quit]" + echo " [--space]" + echo " [--import]" + echo " [--nog]" +} + +function mywhich() { + which $1 | tail -1 +} + +package_root="$packageroot$" + +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" + +placer_pl="$package_root/share/skill/layout/leaf/placer/placer.pl" + +sedcmd=`mywhich sed` +place=`mywhich vcp.exe` +icc2cdba=`mywhich icc2cdba` +cdba2icc=`mywhich cdba2icc` + +check_executable_file "$sedcmd" \ + "Unable to find sed in \"$PATH\"." 2 +check_executable_file "$place" \ + "Unable to find ccar in \"$PATH\"." 2 +check_executable_file "$icc2cdba" \ + "Unable to find icc2cdba in \"$PATH\"." 2 +check_executable_file "$cdba2icc" \ + "Unable to find cdba2icc in \"$PATH\"." 2 + +src_lib= +src_cell= +src_view= +dest_lib= +dest_cell= +dest_view= +rule_file= +spec_file= +conductor_depth=32 +keepout_depth=32 +space= +nog= +quit= +import= +log_file=/dev/null +debug_log_file=/dev/null + +for arg in $@ ; do + + case "$arg" in + --src-lib=* ) + src_lib=`echo $arg | $sedcmd -e "s/--src-lib=//"` + ;; + --src-cell=* ) + src_cell=`echo $arg | $sedcmd -e "s/--src-cell=//"` + ;; + --src-view=* ) + src_view=`echo $arg | $sedcmd -e "s/--src-view=//"` + ;; + --dest-lib=* ) + dest_lib=`echo $arg | $sedcmd -e "s/--dest-lib=//"` + ;; + --dest-cell=* ) + dest_cell=`echo $arg | $sedcmd -e "s/--dest-cell=//"` + ;; + --dest-view=* ) + dest_view=`echo $arg | $sedcmd -e "s/--dest-view=//"` + ;; + --conductor-depth=* ) + conductor_depth=`echo $arg | $sedcmd -e "s/--conductor-depth=//"` + ;; + --keepout-depth=* ) + keepout_depth=`echo $arg | $sedcmd -e "s/--keepout-depth=//"` + ;; + --rule-file=* ) + rule_file=`echo $arg | $sedcmd -e "s/--rule-file=//"` + ;; + --spec-file=* ) + spec_file=`echo $arg | $sedcmd -e "s/--spec-file=//"` + ;; + --working-dir=* ) + working_dir=`echo $arg | $sedcmd -e "s/--working-dir=//"` + ;; + --log-file=* ) + log_file=`echo $arg | $sedcmd -e "s/--log-file=//"` + ;; + --debug-log-file=* ) + debug_log_file=`echo $arg | $sedcmd -e "s/--debug-log-file=//"` + ;; + --quit ) + quit=1 + ;; + --space ) + space=1 + ;; + --nog ) + nog=1 + ;; + --import ) + import=1 + ;; + esac +done + +check_for_empty_arg "$src_lib" \ + "The name of the library of the src cell view to operate on must be specified." 2 +check_for_empty_arg "$src_cell" \ + "The name of the src cell to operate on must be specified." 2 +check_for_empty_arg "$src_view" \ + "The name of the src view to operate on must be specified." 2 +check_for_empty_arg "$dest_lib" \ + "The name of the library of the dest cell view to operate on must be specified." 2 +check_for_empty_arg "$dest_cell" \ + "The name of the dest cell to operate on must be specified." 2 +check_for_empty_arg "$dest_view" \ + "The name of the dest view to operate on must be specified." 2 +check_for_empty_arg "$working_dir" \ + "The working directory must be specified." 2 +check_for_empty_arg "$conductor depth" \ + "The conductor depth must be specified." 2 +check_for_empty_arg "$keepout depth" \ + "The keepout depth must be specified." 2 + +check_readable_file "$rule_file" \ + "Rule File: \"$rule_file\" is not a readable file." 2 +conon_path "$rule_file" +rule_file="$ret" + +check_writeable_file "$spec_file" \ + "Spec File: \"$spec_file\" is not a writeable file." 2 +conon_path "$spec_file" +spec_file="$ret" + + + +if [ ! -e "$working_dir" ] ; then + mkdir -p "$working_dir" +fi + +echo "Exporting to sbtools..." >> $debug_log_file + +#export +$cdba2icc $src_lib $src_cell $src_view \ + -exportDirectory $working_dir \ + -conductorDepth $conductor_depth \ + -keepoutDepth $keepout_depth \ + -fullConnectivity \ + -interLayer \ + -template $rule_file \ + -pinConnect strong \ + -noIncrementalUpdate \ + &>/dev/null \ + +echo "Starting sbtools..." >> $debug_log_file + +mytemp=`mktemp -d $working_dir/placer.XXXXXX` + +do_file="$working_dir/$src_cell.do" +dsn_file="$working_dir/$src_cell.dsn" +wir_file="$working_dir/$src_cell.wir" + +#setup +echo 'application_mode placement' > $do_file +echo 'dlp_set serial_node_weight 15.0' >> $do_file +echo 'dlp_set (dp_design_style uniheight_std_cell)' >> $do_file +echo 'dlp_set auto_row_column on' >> $do_file + +$placer_pl $spec_file $dsn_file $wir_file >> $do_file + +bbox=`cat $spec_file | grep "^\#" | sed -e "s/\#//"` +echo "select all io_port" >> $do_file +echo "unprotect selected io_port" >> $do_file +echo "unselect all io_port" >> $do_file + +#place + +#echo 'dlp_set dp_permit_rotate on' >> $do_file +#echo "dlp_set (ch_compact_style vertical)" >> $do_file +#echo "dlp_set (allow_diff_row_sharing on)" >> $do_file +#echo 'dlp_set do_channel_compact on' >> $do_file +#echo 'dlp_set ch_check_component_spacing on' >> $do_file +#echo 'dlp_set ch_congestion_analysis on' >> $do_file + +echo 'dlp_set dp_penalty_violation 100.0' >> $do_file +echo 'dlp_set dp_permit_move on' >> $do_file +echo 'dlp_set dp_permit_swap on' >> $do_file +echo 'dlp_set dp_permit_group_move on' >> $do_file +echo 'dlp_set dp_permit_group_swap on' >> $do_file +echo 'dlp_set swap_ports off' >> $do_file +echo 'dlp_set fix_orient_flip off' >> $do_file +echo 'device_gplace' >> $do_file +echo 'dlp_set (dp_internal_loop 2)' >> $do_file +echo 'dlp_set (dp_external_loop 2)' >> $do_file +echo 'device_dplace (dp_run_quick_dplace on) (dp_run_move_n_swap on)' >> $do_file +#echo 'dlp_set dp_run_place_compaction on' >> $do_file +#echo "device_compact_design" >> $do_file + +#post place spacer +if [ -n "$space" ] ; then + cat $spec_file | grep "^define" | awk '{print "fence " $5 " " $6 " " $7 " " $8}' >> $do_file + echo "fence digitized" >> $do_file + echo "dlp_set (swap_ports off)" >> $do_file + echo "device_compact_design" >> $do_file + echo "delete fence" >> $do_file +fi + +#output +echo "report place_density "$working_dir/$src_cell.cng"" >> $do_file +echo "report place_status "$working_dir/$src_cell.pst"" >> $do_file +echo "report dlp_violation "$working_dir/$src_cell.vio"" >> $do_file +echo "write session "$working_dir/$src_cell.ses"" >> $do_file + +#place +place_cmd="$place -product 3100 $dsn_file -guidir "$working_dir" -do $do_file -noclean" +if [ -n "$quit" ] ; then + place_cmd="$place_cmd -quit" +fi + +if [ -n "$nog" ] ; then + place_cmd="$place_cmd -nog" +fi + +TEMP=$mytemp TMP=$mytemp LM_LICENSE_FILE=/usr/local/flexlm/licenses/license.0048546B71E0.cadence.dat $place_cmd >> $debug_log_file + +echo "Starting Import..." >> $debug_log_file + +#import +if [ -n "$import" ] ; then + $icc2cdba $dest_lib $dest_cell $dest_view \ + -session $working_dir/$src_cell.ses >> $debug_log_file +fi + +echo "Writing Results" >> $debug_log_file + +rm -rf $mytemp + +cat $working_dir/$src_cell.vio > $log_file + +echo "Exiting..." >> $debug_log_file + +sync diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/squish.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/squish.il new file mode 100644 index 0000000000..325e14b56b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/placer/squish.il @@ -0,0 +1,336 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: Squish +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; squish the cells in x direction to make it narrower.x + +defun( Squish ( CellView ) + + ;get new regions + (defvar CellRegionData + ( SquishSquishCellRegionDataAndComponentsNoRouterWidth + CellView + CellRegionData + ( times UserUnitsPerMeter MinRegionWidth ) + ( times UserUnitsPerMeter MinWellSpacing ) + ( times UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectiveTable + Metal3LPP + DirectiveUnitsPerMeter ) ) + LeftBuffer + RightBuffer + GateLibCellPairRegExs + ( cons + ( list WellPlugLibrary + PWellPlugCellName ) + NChainLibCellPairRegExs ) + ( cons + ( list WellPlugLibrary + NWellPlugCellName ) + PChainLibCellPairRegExs ) + WellPlugLibrary + PWellPlugCellName + NWellPlugCellName + WellPlugViewName + NImplantLPP + PImplantLPP + ( times EvilGatePRegionOffset UserUnitsPerMeter ) + ( times ExtraGateWidth UserUnitsPerMeter ) + ContactLPP ) ) + + ( dbSetq + ( PinUtilFindPRBoundShape + BoundaryLPP + CellView ) + ( PlacementRegionsGetCellRegionDataBBox + CellRegionData ) + bBox ) + + ( dbSave CellView ) + CellView + ) + +(defun SquishSquishCellRegionDataAndComponentsNoRouterWidth ( CellView + CellRegionData + MinRegionWidth + MinWellSpacing + GridWidth + LeftBuffer + RightBuffer + GateLibCellPairRegExs + NComponentLibCellPairRegExs + PComponentLibCellPairRegExs + PlugLibName + NRegionPlugCellName + PRegionPlugCellName + PlugViewName + NImplantLPP + PImplantLPP + EvilGatePRegionOffset + ExtraGateWidth + ContactLPP ) + ( SquishSquishCellRegionDataAndComponents + CellView + CellRegionData + MinRegionWidth + MinWellSpacing + GridWidth + LeftBuffer + RightBuffer + ( ListFillList + (lambda ( I ) 0.0 ) + ( plus + ( length ( PlacementRegionsGetCellRegionDataColumnList + CellRegionData ) ) 1 ) ) + GateLibCellPairRegExs + NComponentLibCellPairRegExs + PComponentLibCellPairRegExs + PlugLibName + NRegionPlugCellName + PRegionPlugCellName + PlugViewName + NImplantLPP + PImplantLPP + EvilGatePRegionOffset + ExtraGateWidth + ContactLPP ) ) + +(defun SquishSquishCellRegionDataAndComponents ( CellView + CellRegionData + MinRegionWidth + MinWellSpacing + GridWidth + LeftBuffer + RightBuffer + GapWidthList + GateLibCellPairRegExs + NComponentLibCellPairRegExs + PComponentLibCellPairRegExs + PlugLibName + NRegionPlugCellName + PRegionPlugCellName + PlugViewName + NImplantLPP + PImplantLPP + EvilGatePRegionOffset + ExtraGateWidth + ContactLPP ) + (let ( + ( NRegionPlugRects + ( DrawImplantFindPlugs + CellView + PlugLibName + NRegionPlugCellName + PlugViewName + PImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP ) ) + ( PRegionPlugRects + ( DrawImplantFindPlugs + CellView + PlugLibName + PRegionPlugCellName + PlugViewName + NImplantLPP + EvilGatePRegionOffset + NImplantLPP + ContactLPP ) ) + ( Gates ( cadr ( NameFilterInstances + ( getq CellView instances ) + GateLibCellPairRegExs ) ) ) + ( NComponents ( cadr ( NameFilterInstances + ( getq CellView instances ) + NComponentLibCellPairRegExs ) ) ) + ( PComponents ( cadr ( NameFilterInstances + ( getq CellView instances ) + PComponentLibCellPairRegExs ) ) ) + ( ColumnDataList ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) ) + ( NewColumnDataList nil ) + ( IsFirstColumn t ) + ( BoundaryBox ( PlacementRegionsGetCellRegionDataBBox CellRegionData ) ) ) + (let ( + ( PlugRects ( append NRegionPlugRects PRegionPlugRects ) ) + ( Components ( append ( append NComponents PComponents ) Gates ) ) + ( CurrColumnLeft ( RectGetLeft ( PlacementRegionGetColumnLeftRegionRect ( car ColumnDataList ) ) ) ) ) + (let ( + ( HorizontalDistanceToBoundary ( difference CurrColumnLeft ( caar BoundaryBox ) ) ) ) + (while ColumnDataList + (let ( + ( ColumnData ( car ColumnDataList ) ) + ( IsLastColumn ( null ( cdr ColumnDataList ) ) ) ) + (let ( + ( NPRegionParity ( PlacementRegionGetNPRegionParity ColumnData ) ) + ( ColumnBBox ( PlacementRegionGetColumnBBox ColumnData ) ) + ( LeftRegionRect ( PlacementRegionGetColumnLeftRegionRect ColumnData ) ) + ( RightRegionRect ( PlacementRegionGetColumnRightRegionRect ColumnData ) ) + ( TopGateRegionRect ( PlacementRegionGetColumnTopGateRegionRect ColumnData ) ) + ( BottomGateRegionRect ( PlacementRegionGetColumnBottomGateRegionRect ColumnData ) ) ) + (let ( + ( PlugRectsInColumn + ( setof PlugRect PlugRects + ( RectDoRectsOverlap PlugRect ColumnBBox ) ) ) + ( ComponentsInColumn + ( setof Component Components + ( RectDoRectsOverlap ( getq Component bBox ) ColumnBBox ) ) ) ) + + ( setq PlugRects + ( ListStringListDifference PlugRects PlugRectsInColumn ) ) + ( setq Components + ( ListStringListDifference Components ComponentsInColumn ) ) + + (let ( + ( MinLeftXMaxRightXPair + ( SquishGetMinLeftXMaxRightXPair + ( append + ( mapcar + (lambda ( C ) + ( RectShrinkInX + ( getq C bBox ) + -ExtraGateWidth ) ) + ComponentsInColumn ) + PlugRectsInColumn ) + ( PlacementRegionGetColumnNPJunction ColumnData ) ) ) ) + (let ( + ( LeftWidthNeededForPlugClearance + (if IsFirstColumn + ( difference + MinWellSpacing + ( difference + (cond ( + ( ListFindMinimum + PlugRectsInColumn + (lambda ( Rect ) + ( RectGetLeft Rect ) ) ) ) + ( + 1e99 ) ) + ( car MinLeftXMaxRightXPair ) ) ) + 0.0 + ) ) + ( RightWidthNeededForPlugClearance + (if IsLastColumn + ( difference + MinWellSpacing + ( difference + ( cadr MinLeftXMaxRightXPair ) + (cond ( + ( ListFindMaximum + PlugRectsInColumn + (lambda ( Rect ) + ( RectGetRight Rect ) ) ) ) + ( + ( difference 0 1e99 ) ) ) ) ) + 0.0 ) ) + ( LeftRouterWidthRequested + (if IsFirstColumn + ( car GapWidthList ) + ( quotient ( car GapWidthList ) 2.0 ) ) ) + ( RightRouterWidthRequested + (if IsLastColumn ( cadr GapWidthList ) + ( quotient ( cadr GapWidthList ) 2.0 ) ) ) + ) + (let ( + ( NewLeftRegionWidth + ( NPSearchSnapToGrid GridWidth + ( difference + ( max + ( plus ( difference ( RectGetRight LeftRegionRect ) ( car MinLeftXMaxRightXPair ) ) + ( max LeftWidthNeededForPlugClearance LeftRouterWidthRequested ) ) + MinRegionWidth ) + 1e-9 ) + ) ) + ( NewRightRegionWidth + ( NPSearchSnapToGrid GridWidth + ( difference + ( max + ( plus ( difference + ( cadr MinLeftXMaxRightXPair ) + ( RectGetLeft RightRegionRect ) ) + ( max RightWidthNeededForPlugClearance + RightRouterWidthRequested ) ) + MinRegionWidth ) + 1e-9 ) + ) ) ) + (when IsFirstColumn + ( setq NewLeftRegionWidth NewLeftRegionWidth+LeftBuffer ) ) + (when IsLastColumn + ( setq NewRightRegionWidth NewRightRegionWidth+RightBuffer ) ) + (let ( + ( NewGateRegionWidth ( plus NewLeftRegionWidth NewRightRegionWidth ) ) ) + (let ( + ( NewLeftRegionRect ( RectMakeRect + CurrColumnLeft + ( cadar LeftRegionRect ) + NewLeftRegionWidth + ( RectGetHeight LeftRegionRect ) ) ) + ( NewRightRegionRect ( RectMakeRect + ( plus CurrColumnLeft NewLeftRegionWidth ) + ( cadar RightRegionRect ) + NewRightRegionWidth + ( RectGetHeight RightRegionRect ) ) ) + ( NewTopGateRegionRect ( RectMakeRect + CurrColumnLeft + ( cadar TopGateRegionRect ) + NewGateRegionWidth + ( RectGetHeight TopGateRegionRect ) ) ) + ( NewBottomGateRegionRect ( RectMakeRect + CurrColumnLeft + ( cadar BottomGateRegionRect ) + NewGateRegionWidth + ( RectGetHeight BottomGateRegionRect ) ) ) ) + ( setq NewColumnDataList ( tconc + NewColumnDataList + ( PlacementRegionMakeColumnData + (if NPRegionParity NewRightRegionRect NewLeftRegionRect ) + (if NPRegionParity NewLeftRegionRect NewRightRegionRect ) + NPRegionParity + NewBottomGateRegionRect + NewTopGateRegionRect ) ) ) + ( foreach Component + ComponentsInColumn + ( dbMoveFig + Component + nil + ( list + ( list ( difference ( RectGetRight NewLeftRegionRect ) + ( RectGetRight LeftRegionRect ) ) + 0.0 ) + "R0" ) ) ) + ( setq GapWidthList ( cdr GapWidthList ) ) + ( setq ColumnDataList ( cdr ColumnDataList ) ) + ( setq IsFirstColumn nil ) + ( setq CurrColumnLeft ( plus CurrColumnLeft NewGateRegionWidth ) ) ) ) ) ) ) ) ) ) ) + (let ( + ( NewBoundaryBox + ( RectMakeRect + ( caar BoundaryBox ) + ( cadar BoundaryBox ) + ( plus ( difference CurrColumnLeft ( caar BoundaryBox ) ) + HorizontalDistanceToBoundary ) + ( RectGetHeight BoundaryBox ) ) ) ) + (let ( + ( NewCellRegionData ( PlacementRegionsMakeCellRegionData ( car NewColumnDataList ) NewBoundaryBox ) ) ) + NewCellRegionData ) ) ) ) ) ) + + +(defun SquishGetMinLeftXMaxRightXPair ( Rects + MiddleX ) + (let ( + ( MinLeftX MiddleX ) + ( MaxRightX MiddleX ) ) + ( foreach Rect Rects + (let ( + ( Right ( RectGetRight Rect ) ) + ( Left ( RectGetLeft Rect ) ) ) + (when ( lessp Left MinLeftX ) + ( setq MinLeftX Left ) ) + (when ( greaterp Right MaxRightX ) + ( setq MaxRightX Right ) ) ) ) + ( list MinLeftX MaxRightX ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/addplugs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/addplugs.il new file mode 100644 index 0000000000..dec2013be7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/addplugs.il @@ -0,0 +1,133 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: AddPlugs +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Force connect the well plugs +; +; +; + + +defun( AddPlugs ( CellView ) + + (let ( + ( WeGoodWithWellPlugs t ) + ( NRegionGatePlugRects + ( DrawImplantFindPlugs + CellView + WellPlugLibrary + PWellPlugCellName + WellPlugViewName + PImplantLPP + ( times EvilGatePRegionOffset UserUnitsPerMeter ) + NImplantLPP + ContactLPP ) ) + ( PRegionGatePlugRects + ( DrawImplantFindPlugs + CellView + WellPlugLibrary + NWellPlugCellName + WellPlugViewName + NImplantLPP + ( times EvilGatePRegionOffset UserUnitsPerMeter ) + NImplantLPP + ContactLPP ) ) ) + + ( foreach Column ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) + (let ( + ( ColumnBBox ( PlacementRegionGetColumnBBox Column ) ) + NPRegionParity + ) + NPRegionParity= ( PlacementRegionGetNPRegionParity Column ) + (let ( + ( NRegionRects + ( setof Rect NRegionGatePlugRects + ( RectIsRectInRectClose + Rect + ColumnBBox + 1e-9 ) ) ) + ( PRegionRects + ( setof Rect PRegionGatePlugRects + ( RectIsRectInRectClose + Rect + ColumnBBox + 1e-9 ) ) ) ) + (if ( or ( RangeGetAllRangesNotCovered + ( RectGetYRange ColumnBBox ) + ( mapcar + (lambda ( Rect ) + ( RangeMakeRangeFromCenter + ( cadr ( RectGetCenter Rect ) ) + ( times UserUnitsPerMeter + WellPlugEffectiveRadius ) ) ) + NRegionRects ) ) + ( RangeGetAllRangesNotCovered + ( RectGetYRange ColumnBBox ) + ( mapcar + (lambda ( Rect ) + ( RangeMakeRangeFromCenter + ( cadr ( RectGetCenter Rect ) ) + ( times UserUnitsPerMeter + WellPlugEffectiveRadius ) ) ) + PRegionRects ) ) ) + ( setq WeGoodWithWellPlugs nil ) ) ) ) ) + + (when ( not WeGoodWithWellPlugs ) + ( println "Drawing Plugs" ) + + (let ( + ( RegionShapes + ( PlacementRegionsDrawCellRegionData + CellView + CellRegionData + PWellLPP + NWellLPP ) ) ) + ( PlugsDrawPlugsOnCellView + CellView + CellRegionData + WorkingDir + PlugDRCRuleFile + GNDNetName + VddNetName + NRegionGatePlugRects + PRegionGatePlugRects + WellPlugLibrary + PWellPlugCellName ;M1_SUB + NWellPlugCellName ;M1_NWELL + WellPlugViewName + WellPlugLPP + NImplantLPP + PImplantLPP + ( times UserUnitsPerMeter WellPlugEffectiveRadius ) + ( times UserUnitsPerMeter MinWellSpacing ) + ?LeaveMess t + ) + ( foreach Shape RegionShapes + ( dbDeleteObject Shape ) ) + ) ) + ; rotate plus when neccessary. + foreach( inst CellView->instances + if( inst->cellName==PWellPlugCellName then + if( dbGetTrueOverlaps( CellView inst->bBox "NW" ) then + inst->orient="MY" + ) + ) + if( inst->cellName==NWellPlugCellName then + overlapShapes=dbGetTrueOverlaps( CellView inst->bBox "NW" ) + foreach( shape overlapShapes + if( rightEdge( shape ) < rightEdge( inst->bBox) then + inst->orient="MY" + ) + ) + ) + ) + ( dbSave CellView ) + ) +CellView +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/connectwellplugs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/connectwellplugs.il new file mode 100644 index 0000000000..65e3fc3ef6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/connectwellplugs.il @@ -0,0 +1,46 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +; Function: ConnectWellPlugs +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Force connect the well plugs +; +; +; + + +defun( ConnectWellPlugs ( CellView ) + (let ( + ( NRegionPlugs ( cadr ( NameFilterInstances + ( getq CellView instances ) + ( list ( list WellPlugLibrary + PWellPlugCellName ) ) ) ) ) + ( PRegionPlugs ( cadr ( NameFilterInstances + ( getq CellView instances ) + ( list ( list WellPlugLibrary + NWellPlugCellName ) ) ) ) ) ) + ( foreach NRegionPlug NRegionPlugs + ( PlugsForceConnectPlug + NRegionPlug + CellView + GNDNetName + WellPlugTerminalName ) ) + + ( foreach PRegionPlug PRegionPlugs + ( PlugsForceConnectPlug + PRegionPlug + CellView + VddNetName + WellPlugTerminalName ) ) + + + ( dbSave CellView ) + ) +CellView +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/plugs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/plugs.il new file mode 100644 index 0000000000..406011a41e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/plugs.il @@ -0,0 +1,574 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/*DOC +Code for drawing well plugs +The basic procedure is: +
      +
    1. Use assura rules to flood fill plug mosiacs everyhwere that is inside well but far aenoguh from diff/poly/m1/etc.. +
    2. Inline mosiacs into strips of plugs on left/right boundary +
    3. Sort plugs by distance from edge(we want them to be close to components for density reasons). +
    4. Add the best plugs (according to the sorting) until they cover the whole column. +
    5. Throw away plugs that redundantly cover part of the column. +
    + +

    Data Structures

    +
    +
    PlugInfo +
    (bbox (lib cell view)) +
    +*/ + +(defun PlugsForceConnectPlug ( Plug CellView NetName TerminalName ) + "Deletes existing connections/nets on TerminalName (e.g created by virtuoso XL) and connects TerminalName to NetName" + (let ( + ( ExistingInstTerm + ( car ( exists + InstTerm + ( getq Plug conns ) + ( equal + ( getq ( getq InstTerm term ) name ) + TerminalName ) ) ) ) ) + (when ( and + ExistingInstTerm + ( not + ( equal + ( getq ( getq ExistingInstTerm net ) name ) + NetName ) ) ) + ( dbDeleteObject ( getq ExistingInstTerm net ) ) + ( dbDeleteObject ExistingInstTerm ) ) + ( dbCreateConnByName + ( dbMakeNet CellView NetName ) + Plug + TerminalName ) ) ) + + + +(defun PlugsClean ( Plugs + MinWellSpacing ) + "Greedily deletes Plugs that are closer thatn MinWellSpacing" + (while + (let ( + ( PlugToRemove + ( car + ( exists + Plug + Plugs + ( exists + OtherPlug + Plugs + ( and + ( not + ( equal + Plug + OtherPlug ) ) + ( equal ( getq Plug cellName ) + ( getq OtherPlug cellName ) ) + ( lessp + ( RectGetDistanceFromRectToRect + ( getq Plug bBox ) + ( getq OtherPlug bBox ) ) + MinWellSpacing ) ) ) ) ) ) ) + (when PlugToRemove + ( setq Plugs ( remove PlugToRemove Plugs ) ) + ( dbDeleteObject PlugToRemove ) + t ) ) + t ) ) + +(defun PlugsInlineMosaic ( Mosaic ) + "Inlines a mosaic into a list of PlugInfos. Keeps only the left and right most two columns of the mosaics." + (let ( + ( UX ( getq Mosaic uX ) ) + ( UY ( getq Mosaic uY ) ) + ( XY ( getq Mosaic xy ) ) + ( Instance ( car ( getq Mosaic instanceList ) ) ) ) + (let ( + ( Info + ( list + ( getq ( getq Instance master ) libName ) + ( getq ( getq Instance master ) cellName ) + ( getq ( getq Instance master ) viewName ) ) ) ) + ( ListNonDestructiveMapCan + (lambda ( X ) X ) + ( ListFillList + (lambda ( I ) + ( list + ( list + ( RectMakeFromCenter + ( PointAdd + XY + ( list ( times ( difference ( getq Mosaic columns ) 1 ) UX ) + ( times ( difference I 1 ) UY ) ) ) + ( RectGetWidth ( getq Instance bBox ) ) + ( RectGetHeight ( getq Instance bBox ) ) ) + Info ) + ( list + ( RectMakeFromCenter + ( PointAdd + XY + ( list 0 + ( times ( difference I 1 ) UY ) ) ) + ( RectGetWidth ( getq Instance bBox ) ) + ( RectGetHeight ( getq Instance bBox ) ) ) + Info ) ) ) + ( getq Mosaic rows ) ) ) ) ) ) + +(defun PlugsDeleteUnNeededPlugs ( CellView + NRegionGatePlugRects + PRegionGatePlugRects + NPlugLibCellPairRegExs + PPlugLibCellPairRegExs + CellRegionData + PlugEffectiveRadius + MinWellSpacing ) + + (let ( + ( MosaicsToKeep nil ) + ( PlugInfosToKeep nil ) + ( NMosaics ( setof Mosaic ( getq CellView mosaics ) + ( cadr ( NameFilterInstances + ( getq Mosaic instanceList ) + NPlugLibCellPairRegExs ) ) ) ) + ( PMosaics ( setof Mosaic ( getq CellView mosaics ) + ( cadr ( NameFilterInstances + ( getq Mosaic instanceList ) + PPlugLibCellPairRegExs ) ) ) ) + ( IsFirst t ) + ( Regions ( PlacementRegionsGetRealRegions + CellRegionData ) ) + ) + + (while Regions + (let ( + ( RegionRect ( PlacementRegionGetRealRegionBBox + ( car Regions ) ) ) + ( IsP ( PlacementRegionGetRealRegionIsP + ( car Regions ) ) ) + ( IsLast ( null ( cdr Regions ) ) ) + ) + (let ( + ( GatePlugRects + ( setof Rect (if IsP + PRegionGatePlugRects + NRegionGatePlugRects ) + ( RectIsRectInRectClose + Rect + RegionRect + 1e-9 ) ) ) + ( Mosaics + ( setof Mosaic (if IsP + PMosaics + NMosaics ) + ( and ( getq Mosaic bBox ) + ( RectDoRectsOverlap + ( getq Mosaic bBox ) + RegionRect ) ) ) ) ) + (let ( + ;inline mosaics in column into PlugInfos + ( PlugsInfos + ( ListNonDestructiveMapCan + (lambda ( Mosaic ) + ( PlugsInlineMosaic + Mosaic + ) ) + Mosaics ) ) ) + ;printf("PlugsInfo %L\n" PlugsInfos) + ;determine which ones to keep + ( setq PlugInfosToKeep + ( append + PlugInfosToKeep + ( PlugsGetPlugsToKeep + PlugsInfos + GatePlugRects + RegionRect + PlugEffectiveRadius +; ( sqrt +; ( min 2.0 +; ( difference + ; ( times PlugEffectiveRadius +; PlugEffectiveRadius ) +; ( times ( RectGetWidth RegionRect ) +; ( RectGetWidth RegionRect ) ) ) ) ) + MinWellSpacing + IsFirst + IsLast + ) ) ) + ;printf("PlugInfoToKeep %L\n" PlugInfosToKeep) + + ( setq Regions ( cdr Regions ) ) + ( setq IsFirst nil ) + ) ) ) ) + + ;delete all mosaics + ( foreach Mosaic ( getq CellView mosaics ) + ( dbDeleteObject Mosaic ) ) + + ;instantiate the needed plugs from PlugInfos + (let ( + ( Plugs + ( mapcar + (lambda ( PlugInfo ) + ( dbCreateInstByMasterName + CellView + ( nth 0 ( cadr PlugInfo ) ) + ( nth 1 ( cadr PlugInfo ) ) + ( nth 2 ( cadr PlugInfo ) ) + nil + ( RectGetCenter + ( car PlugInfo ) ) + "R0" + 1 ) ) + PlugInfosToKeep + ) ) ) + ;delete plug that violate minimum well spacing + ( PlugsClean + Plugs + MinWellSpacing ) + Plugs + ) + ) ) + +(defun PlugInfoDistanceFromEdge ( PlugInfo + Rect + IsFirst + IsLast ) + (cond ( + IsFirst + ( abs + ( difference + ( RectGetRight Rect ) + ( car ( RectGetCenter ( car PlugInfo ) ) ) ) ) ) + ( + IsLast + ( abs + ( difference + ( RectGetLeft Rect ) + ( car ( RectGetCenter ( car PlugInfo ) ) ) ) ) ) + ( + t + ( min + ( abs + ( difference + ( RectGetLeft Rect ) + ( car ( RectGetCenter ( car PlugInfo ) ) ) ) ) + ( abs + ( difference + ( RectGetRight Rect ) + ( car ( RectGetCenter ( car PlugInfo ) ) ) ) ) ) + ) ) ) + +(defun PlugsGetPlugsToKeep ( PlugInfos + GatePlugRects + Rect + PlugEffectiveRadius + MinWellSpacing + IsFirst + IsLast + ) + "Greedily remove redundant plugs, and return the remaining PlugInfos." + ;only look at plugs that are enough from edge to be legal + +; PlugInfos = +; ( setof PlugInfo PlugInfos +; ( geqp ( RectGetDistanceFromRectToSurroundingRect +; ( car PlugInfo ) +; Rect ) +; MinWellSpacing ) ) + (let ( + ( RangeCompare + (lambda ( Range1 Range2 ) + ( lessp + ( PlugInfoDistanceFromEdge + ( arrayref PlugTable Range1 ) + Rect IsFirst IsLast) + ( PlugInfoDistanceFromEdge + ( arrayref PlugTable Range2 ) + Rect IsFirst IsLast) ) ) ) + ) + (let ( + ( RangeToCover ( RectGetYRange Rect ) ) + ( PlugTable ( makeTable `bla nil ) ) + ( GatePlugRanges + ( mapcar + (lambda ( GatePlugRect ) + ( RangeIntersection + ( RangeExpandRange + ( RectGetYRange GatePlugRect ) + PlugEffectiveRadius ) + ( RectGetYRange Rect ) ) ) + GatePlugRects ) ) ) + ;create a map from Range->PlugInfo + ;keep only the plugs closest to edge + ( foreach + PlugInfo + PlugInfos + (let ( + ( Range + ( RangeIntersection + ( RangeExpandRange + ( RectGetYRange ( car PlugInfo ) ) + PlugEffectiveRadius ) + RangeToCover ) ) ) + (let ( + ( OtherPlugInfo + ( arrayref PlugTable Range ) ) ) + ( setarray + PlugTable + Range + (if ( and + OtherPlugInfo + ( lessp + ( PlugInfoDistanceFromEdge + OtherPlugInfo Rect IsFirst IsLast ) + ( PlugInfoDistanceFromEdge + PlugInfo Rect IsFirst IsLast ) ) ) + OtherPlugInfo + PlugInfo ) ) ) ) ) + + + (let ( + ( NeededRanges nil ) + ( Ranges ( sort + ( mapcar + `car + ( tableToList PlugTable ) ) + RangeCompare ) ) ) + ;add ranges until we cover the RangeToCover + (while ( and Ranges + ( RangeGetAllRangesNotCovered + RangeToCover + ( append GatePlugRanges NeededRanges ) + ) ) + ( setq NeededRanges ( cons ( car Ranges ) NeededRanges ) ) + ( setq Ranges ( cdr Ranges ) ) ) + ;greedily throw away ranges that are redundant + (let ( + ( RangesToKeep + ( ListFindBestNonRedundantElementsPreSorted + NeededRanges + (lambda ( Range OtherRanges ) + ( RangeIsRangeContainedInUnionOfRangesClose + Range + ( append + GatePlugRanges + OtherRanges ) + 1e-9 ) ) ) ) ) + ;map back to PlugInfos + (let ( + ( PlugInfosToKeep + ( mapcar + (lambda ( Range ) + ( arrayref PlugTable Range ) ) + RangesToKeep ) ) ) + PlugInfosToKeep + ) ) ) ) ) ) + + + +(defun PlugsAlignToContacts ( Plugs + Contacts + CellView + CellRegionData + ImplantLPPs + MinWellSpacing ) + "attempt to move plugs next to a power contact" + ( foreach + Column + ( PlacementRegionsGetCellRegionDataColumnList + CellRegionData ) + (let ( + ( Plugs ( setof Plug Plugs + ( RectIsRectInRectClose + ( getq Plug bBox ) + ( PlacementRegionGetColumnBBox Column ) + 1e-9 ) ) ) + ( Contacts ( setof Contact Contacts + ( RectIsRectInRectClose + Contact + ( PlacementRegionGetColumnBBox Column ) + 1e-9 ) ) ) ) + ( foreach + Plug + Plugs + (let ( + ( XY ( getq Plug xy ) ) + ( Contact + ( ListFindMinimumElement + ( setof + Contact + Contacts + ( equal + ( lessp + ( car ( RectGetCenter Contact ) ) + ( PlacementRegionGetColumnNPJunction + Column ) ) + ( lessp + ( car ( RectGetCenter ( getq Plug bBox ) ) ) + ( PlacementRegionGetColumnNPJunction + Column ) ) ) ) + (lambda ( Contact ) + ( abs + ( difference + ( cadr ( RectGetCenter Contact ) ) + ( cadr ( RectGetCenter ( getq Plug bBox ) ) ) ) ) ) ) ) ) + (when Contact + ( dbSetq + Plug + ( list + ( car XY ) + ( cadr ( RectGetCenter Contact ) ) ) + xy ) + (when + ( or + ( lessp + ( RectGetDistanceFromRectToSurroundingRect + ( getq Plug bBox ) + ( PlacementRegionGetColumnBBox Column ) ) + MinWellSpacing ) + ( exists + LPP ImplantLPPs + ( exists + Overlap + ( dbGetTrueOverlaps + CellView + ( getq Plug bBox ) + LPP + 0:32 + ) + (if ( listp Overlap ) + ( equal ( car Overlap ) Plug ) + ( equal Overlap Plug ) + ) ) ) ) + ( dbSetq + Plug + XY + xy ) ) ) ) ) ) ) ) + + + + + +;IMPORTANT: here, nplug means the plug that goes in the n region +(defun PlugsDrawPlugsOnCellView ( CellView + CellRegionData + TempDir + RuleFile + GNDNetName + VddNetName + NRegionGatePlugRects + PRegionGatePlugRects + PlugLibName + M1_SUB + M1_NWELL + PlugViewName + PlugLPP + NImplantLPP + PImplantLPP + PlugEffectiveRadius + MinWellSpacing + @key + ( DrawPlugs t ) + ( DrawImplant nil ) + ( LeaveMess nil ) + ) + (let ( + ( TechLibFile ( techGetTechFileName CellView ) ) + ( TempLibName + ( LibCreateTempLibraryFromCellView CellView "PLUGS" TempDir ) ) + ( ErrorStr nil ) ) + ( setq + ErrorStr + ( AssuraRunAssuraLayerProcessor + CellView + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) + RuleFile + TempDir + ( append + (when DrawPlugs + ( list + ( list "nimp_add" NImplantLPP ) + ( list "pimp_add" PImplantLPP ) + ( list "M1_NWELL_fill" PlugLPP ) + ( list "M1_SUB_fill" PlugLPP ) + ) ) + (when DrawImplant + ( list + ( list "nimp_add" NImplantLPP ) + ( list "pimp_add" PImplantLPP ) ) ) ) + (when DrawPlugs + ( list + ( list + ( list + PlugLibName + M1_NWELL + PlugViewName ) + "M1_NWELL_fill" ) + ( list + ( list + PlugLibName + M1_SUB + PlugViewName ) + "M1_SUB_fill" ) ) ) + ?LeaveMess LeaveMess + ) ) + (unless ErrorStr + (let ( + ( CellWithGrid + ( dbOpenCellViewByType + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) + nil + "a" ) ) ) + (if CellWithGrid + ;remove redundant plugs + (let ( + ( Plugs + ( PlugsDeleteUnNeededPlugs + CellWithGrid + NRegionGatePlugRects + PRegionGatePlugRects + ( list + ( list PlugLibName + M1_SUB ) ) + ( list + ( list PlugLibName + M1_NWELL ) ) + CellRegionData + PlugEffectiveRadius + MinWellSpacing ) ) + ) + + + ;Copy the plugs to new cellview +printf( "plugs %L \n" Plugs) + (when DrawPlugs + ( foreach + Plug + Plugs + ( dbCopyFig Plug CellView ) ) ) + + ;or the implant + (when DrawImplant + ( AssuraCopyShapesFromCellView + CellWithGrid + CellView + (lambda (Shape) + ( or + ( equal ( getq Shape lpp ) NImplantLPP ) + ( equal ( getq Shape lpp ) PImplantLPP ) ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "%L %L %L does not exist." + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) ) + (unless LeaveMess ( ddDeleteObj ( ddGetObj TempLibName ) ) ) + ( techBindTechFile CellView TechLibFile ) + ErrorStr ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/wellplugsoff.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/wellplugsoff.il new file mode 100644 index 0000000000..fd1a988942 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/plugs/wellplugsoff.il @@ -0,0 +1,32 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: WellPlugsOn +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Force turn off the well plugs +; + + +defun( WellPlugsOff ( CellView ) + + + ( foreach Gate ( cadr ( NameFilterInstances + ( getq CellView instances ) + GateLibCellPairRegExs ) ) + (when ( PCellGetParameterValue Gate "worst_case_folding" ) + ( dbReplaceProp Gate "worst_case_folding" "boolean" "TRUE" ) ) + (when ( PCellGetParameterValue Gate "well_plugs" ) + ( dbReplaceProp Gate "well_plugs" "boolean" "FALSE" ) ) ) + + + ( dbSave CellView ) +CellView +) + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/property.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/property.il new file mode 100644 index 0000000000..f6d4512cec --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/property.il @@ -0,0 +1,85 @@ + +(defun SetLeafProp (cv val) + (when cv + (dbReplaceProp cv "LeafCell" "boolean" val) + ) +) + +(defun SetAvagoProp (cv val) + (when cv + (dbReplaceProp cv "AvagoCell" "boolean" val) + (dbReplaceProp cv "LeafCell" "boolean" nil) + ) +) + +(defun SetProteusProp (cv val) + (when cv + (dbReplaceProp cv "ProteusCell" "boolean" val) + (dbReplaceProp cv "AvagoCell" "boolean" nil) + (dbReplaceProp cv "LeafCell" "boolean" nil) + ) +) + + +(defun IsLeafCell (cellname @key (viewname "floorplan") + (tempdir ConfigFileGetValue(TheCDSConfigTable "TEMP")) + (castpath ConfigFileGetValue(TheCDSConfigTable "CAST_PATH")) ) + (let (isleaf cv) + isleaf=nil + cv=(nrOpenCellViewReadable (car (NameParseCellName cellname)) cellname viewname) +;(if cv then + (if cv && (dbGetPropByName cv "LeafCell") then + (when (dbGetPropByName cv "LeafCell")->value=="TRUE" + isleaf=t + ) + else + isleaf=(nrIsLeafCell nil cellname nil ?tempdir tempdir ?castpath castpath) + ) +;else +; isleaf=(nrIsLeafCell nil cellname nil ?tempdir tempdir ?castpath castpath) +;) + isleaf + ) +) + +(defun IsProteusCell (cellname @key (viewname "floorplan") + (tempdir ConfigFileGetValue(TheCDSConfigTable "TEMP")) + (castpath ConfigFileGetValue(TheCDSConfigTable "CAST_PATH")) ) + (let (isproteus cv) + isproteus=nil + cv=(nrOpenCellViewReadable (car (NameParseCellName cellname)) cellname viewname) +;(if cv then + + (if cv && (dbGetPropByName cv "ProteusCell") then + (when (dbGetPropByName cv "ProteusCell")->value=="TRUE" + isproteus=t + ) + else + isproteus=nil + ) +;else +; isleaf=(nrIsLeafCell nil cellname nil ?tempdir tempdir ?castpath castpath) +;) + isproteus + ) +) + +(defun IsAvagoCell (cellname @key (viewname "floorplan") + (tempdir ConfigFileGetValue(TheCDSConfigTable "TEMP")) + (castpath ConfigFileGetValue(TheCDSConfigTable "CAST_PATH")) ) + (let (isavago cv) + isavago=nil + cv=(nrOpenCellViewReadable (car (NameParseCellName cellname)) cellname viewname) + + (if cv && (dbGetPropByName cv "AvagoCell") then + (when (dbGetPropByName cv "AvagoCell")->value=="TRUE" + isavago=t + ) + else + isavago=nil + ) + isavago + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/removeinvalidlayers.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/removeinvalidlayers.il new file mode 100644 index 0000000000..de69c108e6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/removeinvalidlayers.il @@ -0,0 +1,20 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: RemoveInvalidLayers +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Remove invalide layers + +defun( RemoveInvalidLayers ( CellView ) + ( foreach LPP + InvalidLPPs + ( foreach Shape ( PinUtilGetAllShapesOnLPP CellView LPP ) + ( dbDeleteObject Shape ) ) ) + ( dbSave CellView ) + CellView +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/PreroutePowerVia.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/PreroutePowerVia.il new file mode 100644 index 0000000000..a97f7f6143 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/PreroutePowerVia.il @@ -0,0 +1,77 @@ +; Copyright 2008 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( PreroutePowerVia ( CellView ) + prog((prBoundShapes shape y1 y2 x1 x2 via23CellViewMaster M3GNDShapeBottom M3GNDShapeTop M2GNDShapes) + prBoundShapes= setof( shape CellView~>shapes shape~>layerName=="prBoundary" && shape~>objType=="rect") + shape=car(prBoundShapes) + prboundBottom=bottomEdge(shape~>bBox) + prboundTop=topEdge(shape~>bBox) + M3GNDShapeBottom=car(setof( shape CellView~>shapes + shape~>lpp==Metal3LPP && + shape~>net~>name==GNDNetName && + bottomEdge(shape)-prboundBottom<0.01 )) + M3GNDShapeTop=car(setof( shape CellView~>shapes + shape~>lpp==Metal3LPP && + shape~>net~>name==GNDNetName && + prboundTop-topEdge(shape)<0.01 )) + M2GNDShapes=setof( shape CellView~>shapes shape~>lpp==Metal2LPP && shape~>net~>name==GNDNetName ) + via23CellViewMaster=nrOpenCellViewReadable( TechLibName "M3_M2_H" "layout") + if( M3GNDShapeBottom then + foreach( shape M2GNDShapes + y1=bottomEdge(shape~>bBox) + y2=topEdge(M3GNDShapeBottom) + if( y1bBox=list( x1:y1 x2:topEdge(shape) ) + printf("%f %f %f %f\n" x1 x2 y1 y2 ) + dbCreateParamInst(CellView via23CellViewMaster nil + ((x1+x2)/2:(y1+y2)/2) "R0" 1 + list( + list("column" "int" 2) + list("row" "int" 1) + list( "layer1Direction" "string" "XY") + list( "layer1YEnclosure" "float" 0.01) + list( "layer1XEnclosure" "float" 0.04) + list( "layer2Direction" "string" "XY") + list( "layer2YEnclosure" "float" 0.01) + list( "layer2XEnclosure" "float" 0.04) + ) + ) + ) + ) + ) + if( M3GNDShapeTop then + foreach( shape M2GNDShapes + y1=bottomEdge(M3GNDShapeTop) + y2=topEdge(shape~>bBox) + if( y1bBox=list( x1:bottomEdge(shape) x2:y2 ) + printf("%f %f %f %f\n" x1 x2 y1 y2 ) + dbCreateParamInst(CellView via23CellViewMaster nil + ((x1+x2)/2:(y1+y2)/2) "R0" 1 + list( + list("column" "int" 2) + list("row" "int" 1) + list( "layer1Direction" "string" "XY") + list( "layer1YEnclosure" "float" 0.01) + list( "layer1XEnclosure" "float" 0.04) + list( "layer2Direction" "string" "XY") + list( "layer2YEnclosure" "float" 0.01) + list( "layer2XEnclosure" "float" 0.04) + ) + ) + ) + ) + ) + + + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/checkpolygons.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/checkpolygons.il new file mode 100644 index 0000000000..e5a33cc60d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/checkpolygons.il @@ -0,0 +1,34 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: CheckPolygons +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Check polygons + +defun( CheckPolygons ( CellView ) + + (let ( + ( Polygons ( setof Shape ( getq CellView shapes ) + ( equal ( getq Shape objType ) "polygon" ) ) ) ) +;find polygons with angled edges + ( println + ( setof Shape Polygons + ( PolygonIsAngled ( getq Shape points ) ) )~>bBox ) + +;find polygons with duplicate points + + ( foreach Shape Polygons + (let ( + ( Points ( PolygonCanonicalizePoints + ( getq Shape points ) ) ) ) + (when ( not ( equal Points ( getq Shape points ) ) ) + ( dbSetq Shape Points points ) ) ) ) + t ) + + ( dbSave CellView ) + CellView +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/delextrapolycontact.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/delextrapolycontact.il new file mode 100644 index 0000000000..7322e0c51e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/delextrapolycontact.il @@ -0,0 +1,81 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: FixWireExtension +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Fix Wire Extension + +defun( DelExtraPolyContact ( CellView ) + + ; get rid of unused contacts on inputs to gates + ; this is to get rid of m1 area violations and + ; to reduce stray capacitance + ( foreach + Gate + ( cadr ( NameFilterInstances + ( getq CellView instances ) + GateLibCellPairRegExs ) ) + ;if we can change poly contacts and there's a single fold + (when ( and + ( if ( NPSearchGateGetFolds Gate ) + ( leqp ( NPSearchGateGetFolds Gate ) 1 ) + t ) + ( PCellGetParameterValue Gate "poly_contact" ) ) + ( printf "gate: %L\n" Gate->name ) + ;find the first m1 contact shape... + ( exists + Fig + ( PinUtilGetPinFigsForInstance + Gate + (lambda ( Net ) t ) + (lambda ( LPP ) ( equal LPP Metal1LPP ) ) + ?TerminalP (lambda ( Term ) + ( or ( equal Term "a" ) + ( equal Term "in" ) + ) ) + ) + ;that doesn't overlap any m1 shapes in the cellview... + (let ( + ( Overlap + ( exists + Overlap + ( dbGetTrueOverlaps + CellView + ( dbTransformBBox + ( getq Fig bBox ) + ( getq Gate transform ) ) + Metal1LPP + 0:32 + ) + ;that aren't inside the gate instance + ( or + ( not ( listp Overlap ) ) + ( not ( equal ( car Overlap ) Gate ) ) ) ) ) ) + ( printf "overlap: %L %L\n" Overlap Overlap~>bBox ) + + (when ( null Overlap ) + ;this contact doesn't overlap anything + ;if it's to the right of the origin in instance master, + ;then only have poly contacts on left, and vice versa + (cond ( + ( geqp + ( car + ( RectGetCenter ( getq Fig bBox ) ) ) + 0.0 ) + ( dbReplaceProp + Gate "poly_contact" "string" "left" ) ) + ( + ( dbReplaceProp + Gate "poly_contact" "string" "right" ) ) ) ) ) ) ) ) + + + ( dbSave CellView ) + ( dbPurge CellView ) +CellView +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/importccar.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/importccar.sh new file mode 100755 index 0000000000..66f4ac0fb2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/importccar.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +function usage() { + echo "Usage: $0" + echo " --dest-lib=lib" + echo " --dest-cell=cell" + echo " --dest-lib=view" + echo " --working-dir=dir" +} + +function mywhich() { + which $1 | tail -1 +} + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} + +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" + +sedcmd=`mywhich sed` +icc2cdba=`mywhich icc2cdba` + +check_executable_file "$sedcmd" \ + "Unable to find sed in \"$PATH\"." 2 +check_executable_file "$icc2cdba" \ + "Unable to find icc2cdba in \"$PATH\"." 2 + +dest_lib= +dest_cell= +dest_view= +working_dir= + +for arg in $@ ; do + + case "$arg" in + --dest-lib=* ) + dest_lib=`echo $arg | $sedcmd -e "s/--dest-lib=//"` + ;; + --dest-cell=* ) + dest_cell=`echo $arg | $sedcmd -e "s/--dest-cell=//"` + ;; + --dest-view=* ) + dest_view=`echo $arg | $sedcmd -e "s/--dest-view=//"` + ;; + --working-dir=* ) + working_dir=`echo $arg | $sedcmd -e "s/--working-dir=//"` + ;; + esac +done + + +check_for_empty_arg "$dest_lib" \ + "The name of the library of the dest cell view to operate on must be specified." 2 +check_for_empty_arg "$dest_cell" \ + "The name of the dest cell to operate on must be specified." 2 +check_for_empty_arg "$dest_view" \ + "The name of the dest view to operate on must be specified." 2 +check_for_empty_arg "$working_dir" \ + "The working directory must be specified." 2 + + +ses_file=$(find "$working_dir" -name "*.ses" | tail -1 ) +icc2cdba "$dest_lib" "$dest_cell" "$dest_view" -session "$ses_file" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/lvsnodes.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/lvsnodes.il new file mode 100644 index 0000000000..556d591c2b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/lvsnodes.il @@ -0,0 +1,21 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: LVSNodes +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Remove LVS Nodes + +defun( LVSNodes ( CellView ) + ( LVSNodesDrawFromDirectives + CellView + DirectiveTable + Metal1LPP + ContactLibCellExpressionPairs + ) + ( dbSave CellView ) + CellView +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/router.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/router.il new file mode 100644 index 0000000000..6fe5cf1a0e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/router.il @@ -0,0 +1,253 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun RouterImport ( DestLibName DestCellName DestViewName WorkingDir ) + (let ( + ( ImportCommand + ( sprintf nil "%s/importccar" ( PackageGetBinRoot ) ) ) + ( ImportLog ( sprintf nil + "%s/import.log" + WorkingDir + ) ) + ) + ( setq ImportCommand + ( sprintf + nil + "%s --dest-lib=%s --dest-cell=%s --dest-view=%s --working-dir=%s" + ImportCommand + DestLibName + DestCellName + DestViewName + WorkingDir ) ) + ( println ImportCommand ) + ( printf "Log in %s\n" ImportLog ) + ( ipcWait ( ipcBatchProcess ImportCommand "" ImportLog ) ) + ) ) + +(defun RouterUseInstantiatorView ( CellView + InstantiatorView + FoldableCellLibCellPairRegExs + SuperStackLibCellPairRegExs + ) + (let ( + ( InstantiatorInst + (cond ( + ( dbFindAnyInstByName + CellView + "theInstantiators" ) ) + ( + ( dbCreateInst + CellView + InstantiatorView + "theInstantiators" + 0:0 + "R0" ) ) ) ) ) + + ;inline the instantator cell in the result + ;this will copy conductor shapes but not pins + (when InstantiatorInst + ( InlineInstances + CellView + CellView + ( list InstantiatorInst ) + "layout" + nil + FoldableCellLibCellPairRegExs + SuperStackLibCellPairRegExs + ?CopyPins nil + ?Verbose nil ) ) + ) + ) + +(defun RouterRunRouter ( SrcLibName SrcCellName SrcViewName + DestLibName DestCellName DestViewName + ConductorDepth + KeepoutDepth + RuleFile + DoFiles + WorkingDir + PowerNetNames + @key + ( FulcrumPDKRoot "" ) + ( PinConnect "strong" ) + ( Quit t ) + ( Import t ) + ( Blocking t ) + ( Graphics t ) + ( ExportPCells t ) + ( Area nil ) + ( UseConstraints t ) + ) + (let ( + ( TempDirForThisRun + (if Blocking + ( makeTempFileName + ( sprintf + nil + "%s/CCAR.XXXXXX" + WorkingDir ) ) + WorkingDir ) ) + ( DFIIDir + ( NameGetDFIIDirFromLibName "gate" ) ) + ( CellView + ( dbOpenCellViewByType + SrcLibName + SrcCellName + SrcViewName + "maskLayout" + "a" ) ) + ( DestCellViewObj + ( ddGetObj + DestLibName + DestCellName + DestViewName ) ) + ) + + (when ( and Import DestCellViewObj ) + ( printf "WARNING...overwriting dest cell view\n" ) + ( ddDeleteObj DestCellViewObj ) ) + + (let ( + ( ConstraintsDoFile + ( sprintf nil "%s/FulcrumConstraints.do" TempDirForThisRun ) ) + ( CCARLog + ( sprintf nil + "%s/ccar.log" + TempDirForThisRun + ) ) + ( CCARRunLog + ( sprintf nil "%s/runccar.log" TempDirForThisRun ) ) + ( CCARDebugLog + ( sprintf nil "%s/runccar.debug" TempDirForThisRun ) ) + ( CCARCommand + ( sprintf nil "%s/runccar" ( PackageGetBinRoot ) ) ) ) + + ( createDir TempDirForThisRun ) + + (when ( not + ( isReadable RuleFile ) ) + ( printf "Can't read rule file %s\n" RuleFile ) ) + + ( ConstraintsDumpICCToFile + CellView + ConstraintsDoFile + ICCUnitsPerMeter + PowerNetNames + ) + + ( setq + CCARCommand + ( sprintf nil "%s --src-lib=%s --src-cell=%s --src-view=%s --dest-lib=%s --dest-cell=%s --dest-view=%s --conductor-depth=%d --keepout-depth=%d --pin-connect=%s --rule-file=%s --working-dir=%s --fulcrum-pdk-root=%s --dfII-dir=%s --log-file=%s --debug-log-file=%s" + CCARCommand + SrcLibName SrcCellName SrcViewName + DestLibName DestCellName DestViewName + ConductorDepth KeepoutDepth PinConnect + RuleFile TempDirForThisRun FulcrumPDKRoot DFIIDir + CCARRunLog CCARDebugLog + ) ) + + + (when UseConstraints + ( setq DoFiles ( cons ConstraintsDoFile DoFiles ) ) ) + + ( foreach DoFile DoFiles + (cond ( + ( isReadable DoFile ) + ( setq CCARCommand ( sprintf nil "%s --do-file=%s" + CCARCommand + DoFile ) ) ) + ( + ( printf "Can't read do file %s...ignoring\n" DoFile ) ) ) ) + + (when ( not Graphics ) + ( setq CCARCommand + ( sprintf nil "%s --nog" CCARCommand ) ) ) + (when Quit + ( setq CCARCommand + ( sprintf nil "%s --quit " CCARCommand ) ) ) + (when Import + ( setq CCARCommand + ( sprintf nil "%s --import " CCARCommand ) ) ) + + (when ( null ExportPCells ) + ( setq CCARCommand + ( sprintf nil "%s --no-export-pcells " CCARCommand ) ) ) + + (when Area + ( setq CCARCommand + ( sprintf nil "%s --area=%f,%f,%f,%f " + CCARCommand + ( caar Area ) + ( cadar Area ) + ( caadr Area ) + ( cadadr Area ) + ) ) ) + + ( printf "%s\n" CCARCommand ) + + ( LicenseGetLicense "Virtuoso_Layout_Suite_GXL" 11.0 8 ) + ( LicenseReturnLicense "Virtuoso_Layout_Suite_GXL" ) + + (let ( + ( Crossing -1 ) + ( Clearance -1 ) + ( Unroutes -1 ) + ( Completion -1.0 ) + ( InPort nil ) ) + (cond ( + Blocking + ( shell CCARCommand ) + ) + ( + t + ( printf "Log in %s\n" CCARLog ) + ( ipcBatchProcess CCARCommand "" CCARLog ) ) ) + (let ( + ( InPort ( infile CCARRunLog ) ) ) + (when InPort + ( fscanf InPort "%d %d %d %f" Crossing Clearance Unroutes Completion ) + ( close InPort ) ) + ) + (when Blocking + t + ;( shell ( sprintf nil "rm -rf %s &>/dev/null" TempDirForThisRun ) ) + ) + + ( list Crossing Clearance Unroutes Completion ) ) ) ) ) + + + +(defun RouteLeaf () + (let ( CellView WorkingDir TclFile) + + CellView = UIGetCellView( ) + SetHandLayoutAllObjects( ) + WorkingDir = sprintf( nil + "%s/%s" + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + CellView->cellName ) + createDir( WorkingDir ) + + AddLeafBlockageCell( CellView ) + TclFile=strcat(WorkingDir "/router_temp.tcl") +; PDKRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + + mycmd=sprintf( nil "/usr/bin/sed -e \"s/LIBNAME/%s/g\" -e \"s/CELLNAME/%s/g\" -e \"s/VIEWNAME/%s/g\" -e \"s^EXCLUDENET^%s^g\" <%s >%s\n" CellView->libName CellView->cellName CellView->viewName UIRoute_Form->UIRoute_Form_ExcludeNet->value UIRoute_Form->UIRoute_Form_VsrTcl->value TclFile ) + println(mycmd) + system(mycmd) + deInstallApp(getCurrentWindow() "Virtuoso XL") +; ipcSleep(30) + + FixMustConnectTerm( CellView ) + ; move all fig in XL to add connectivity to via/path shapes + geSelectAllFig( CellView) + MoveAndSnap_MoveSelected( 1 1 ) + MoveAndSnap_MoveSelected( -1 -1 ) + geDeselectAll() + RoutingGood = rdeSource(TclFile) + DeleteLeafBlockageCell( CellView ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routercheck.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routercheck.il new file mode 100644 index 0000000000..816c597759 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routercheck.il @@ -0,0 +1,75 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: RouterCheck +; Parameter: CellView (CVId) +; DRCRuleFile (string) +; DRCAssuraSets (list) +; Return: RoutingGood (boolean) +; +; Check DRC on routed view + +defun( GetCastSpecDir ( CastPath ) + let((PathList SpecDirs SpecDir CastDirs CastDir) + PathList= parseString(CastPath ":") + SpecDirs=rexMatchList("spec" PathList) + CastDirs=rexMatchList("cast" PathList) + CastDir=car(CastDirs) + while(CastDirs=cdr(CastDirs) + CastDir=strcat(CastDir ":" car(CastDirs)) + ) + SpecDir=car(SpecDirs) + while(SpecDirs=cdr(SpecDirs) + SpecDir=strcat(SpecDir ":" car(SpecDirs)) + ) + list( CastDir SpecDir) + + ) +) + + +defun( RouterCheck ( CellView ) + let((glc_dfII_dir lve_dir lve_dfII_dir libdir libpath run_file p_out p_in hlvs_result_file hlvs_result ) + glc_dfII_dir=strcat( WorkingDir "/dfII" ) + lve_dir=strcat( WorkingDir "/lve" ) + lve_dfII_dir=strcat( WorkingDir "/lve/dfII" ) + system(strcat("mkdir -p " lve_dfII_dir)) + libname=car( NameParseCellName( CellName )) + rexCompile("\\.") + cadenceLibName=rexReplace(libname "#2e" 0) + libdir=rexReplace(libname "/" 0) + rexCompile("/[0-9a-zA-Z_]+$") + libpath=rexReplace(libdir "" 0) + system(sprintf( nil "mkdir -p %s/%s" lve_dfII_dir libpath)) + system(sprintf( nil "ln -s %s %s/%s" glc_dfII_dir lve_dfII_dir libdir)) + system(sprintf( nil "echo 'DEFINE %s %s' > %s/cds.lib.generated" cadenceLibName libdir lve_dfII_dir )) + + run_file=sprintf( nil "run_%s.sh" CellName ) + CastSpecDir = GetCastSpecDir( ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" )) + + p_out=outfile(strcat( lve_dir "/" run_file)) + fprintf( p_out "fulcrum --latest --pdk=tsmc28 --cadence=icc,assura_oa lve ") + fprintf( p_out "--cast-dir=%s " car(CastSpecDir)) + fprintf( p_out "--spec-dir=%s " cadr(CastSpecDir)) + fprintf( p_out "--dfII-dir=%s " lve_dfII_dir) + fprintf( p_out "--output-dir=%s " lve_dir) + fprintf( p_out "--task=hlvs --nowellplugs=1 ") + fprintf( p_out "--extracted-view=%s " CellView->viewName) + fprintf( p_out "%s " CellName) + close(p_out) + system(sprintf(nil "cd %s; sh %s" lve_dir run_file)) + + rexCompile("\\.") + celldir=rexReplace(CellName "/" 0) + hlvs_result_file=sprintf(nil "%s/%s/%s/hlvs.result" lve_dir celldir CellView->viewName) + p_in=infile(hlvs_result_file) + fscanf( p_in "%s" hlvs_result ) + close(p_in) + RoutingGood = hlvs_result=="PASS" + ) + RoutingGood +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearch.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearch.il new file mode 100644 index 0000000000..29fee5b086 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearch.il @@ -0,0 +1,80 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: RouterSearch +; Parameter: none +; Return: RouterSearchStatus = nil We do not yet have a placed view +; RouterSearchStatus = 1 We have a placed view, but trying to do better +; RouterSearchStatus = t Search is done +; +; Main program of running router. +; +; + +defun( RouterSearch ( ) + +CurrentPreKeepOutRoutedScratchViewName= (if OptionKeepRouterViewHistory + ( sprintf nil "%s_%d" PreKeepOutRoutedScratchViewName CurrentStepNumber ) + PreKeepOutRoutedScratchViewName ) +CurrentPreKeepOutRoutedViewName= (if OptionKeepRouterViewHistory + ( sprintf nil "%s_%d" PreKeepOutRoutedViewName CurrentStepNumber ) PreKeepOutRoutedViewName ) +CurrentRoutedScratchViewName= (if OptionKeepRouterViewHistory + ( sprintf nil "%s_%d" RoutedScratchViewName CurrentStepNumber ) RoutedScratchViewName ) + +CurrentRoutedViewName= ( sprintf nil "%s_%d" RoutedViewName CurrentStepNumber ) +CurrentStepNumber= ( plus CurrentStepNumber 1 ) + + +errset( RouterSearchInit( ) t) +errset( ScratchView = CopyView( CurrentPreRouteViewName ScratchViewName ) t) +errset( RouterWidth( ScratchView ) t) +errset( CreateSuperStacks( ScratchView ) t) +errset( SpaceStacks( ScratchView ColumnStackSpaceThreshold ColumnStackSpaceMinSpacing ColumnStackSpaceMaxShift ) t) +errset( InlineSuperstacks( ScratchView t ) t) + +;errset( (if PlugsInRoutingStage WellPlugsOn( ScratchView ) ) t) +;errset( (if PlugsInRoutingStage AddPlugs( ScratchView ) ) t) +errset( RegionWell( ScratchView ) t) +errset( DrawImplant( ScratchView ) t) +errset( AddPinsToCellView( ScratchView nil ?power t) t) +;errset( ConnectWellPlugs( ScratchView ) t) +errset( VStruts( ScratchView ) t) +;errset( if( AutoPinTemplateFound==0 SnapFatPins( ScratchView ))) +;errset( PreroutePowerVia( ScratchView )) +;errset( AddPrboundBoundary( ScratchView -0.24 )) +;errset( SetGLCParams( ScratchView "TRUE")) + +CurrentPreKeepOutRoutedScratchView = CopyView( ScratchViewName CurrentPreKeepOutRoutedScratchViewName ) +CurrentRoutedScratchView = CopyView( ScratchViewName CurrentRoutedScratchViewName ) +RoutingGood = Router( CurrentRoutedScratchViewName ) + +;errset( DeletePrboundBoundary( CurrentRoutedScratchView )) +;errset( fixNegativeExtension( CurrentRoutedScratchView )) +;errset( SetGLCParams( CurrentRoutedScratchView "FALSE")) + +(if RoutingGood then + errset( RoutingGood = RouterCheck( CurrentRoutedScratchView ) + t) +) + + +;(if RoutingGood then + +; DrawDirectiveKeepout( CurrentRoutedScratchView ) +; errset( fixFatPolyContact( CurrentRoutedScratchView )) +; errset( SwapVias( CurrentRoutedScratchView )) +; errset( DelExtraPolyContact( CurrentRoutedScratchView ) t) +; CurrentRoutedScratchView = nrOpenCellViewWritable( LibName CellName CurrentRoutedScratchViewName ) +; InvalidLPPs = list( "" ) +; RemoveInvalidLayers( CurrentRoutedScratchView ) +; errset( CheckPolygons( CurrentRoutedScratchView ) t) +; LVSNodes( CurrentRoutedScratchView ) +;) + +RouterSearchStatus= RouterSearchDone( CurrentRoutedScratchViewName CurrentRoutedViewName CurrentPreKeepOutRoutedScratchViewName CurrentPreKeepOutRoutedViewName ) +;LicenseReturnLicense( "300" ) + +RouterSearchStatus +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchdone.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchdone.il new file mode 100755 index 0000000000..cebe9bcd64 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchdone.il @@ -0,0 +1,290 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: RouterSearchDone +; Parameter: CurrentRoutedScratchViewName (string) +; CurrentRoutedViewName ( string ) +; CurrentPreKeepOutRoutedScratchViewName ( string ) +; CurrentPreKeepOutRoutedViewName ( string ) +; +; Return: RoutingComplete (boolean) +; +; Check if routing is done + +defun( RouterSearchDone ( CurrentRoutedScratchViewName + CurrentRoutedViewName + CurrentPreKeepOutRoutedScratchViewName + CurrentPreKeepOutRoutedViewName) + + ;do the search step + ( SearchFindSmallestStep + CurrentSearchTable + (lambda ( Trial ) RoutingGood ) + nil ) + + (cond ( + RoutingGood + ( printf "Routing Passed\n" ) + CurrentRoutedScratchView=dbOpenCellViewByType( + LibName + CellName + CurrentRoutedScratchViewName + "maskLayout" + "a" ) + ; I realize that this is the wrong place to do these + ; post-processing things, but it's the best place I could find. +; PinUtilDeleteM2PowerPins( CurrentRoutedScratchView ) + (let (NWList) + (foreach shape CurrentRoutedScratchView->shapes + (when (car shape->lpp)=="PW" + (dbDeleteObject shape) + ) + (when (car shape->lpp)=="NW" + (if !NWList then NWList=(list shape) + else NWList=(cons shape NWList) ) + ) + ) + (leMergeShapes NWList) + ) + + dbSave(CurrentRoutedScratchView) + + ( dbSave + ( dbCopyCellView + CurrentRoutedScratchView + LibName + CellName + CurrentRoutedViewName + nil + nil + t ) ) + ( dbSave + ( dbCopyCellView + ( dbOpenCellViewByType + LibName + CellName + CurrentPreKeepOutRoutedScratchViewName + "maskLayout" + "a" ) + LibName + CellName + CurrentPreKeepOutRoutedViewName + nil + nil + t ) ) + (let ( + ( CurrentRoutedViewArea + ( RectGetArea + ( dbOpenCellViewByType + LibName + CellName + CurrentRoutedViewName + "maskLayout" + "a" ) -> prBoundary -> bBox + ) ) ) + (when + ( lessp + CurrentRoutedViewArea + BestRoutedViewArea ) + (defvar BestRoutedViewName CurrentRoutedViewName ) + (defvar BestRoutedViewArea CurrentRoutedViewArea ) + (defvar BestPreKeepOutRoutedViewName CurrentPreKeepOutRoutedViewName ) ) ) ) + ( + ( printf "Routing Failed:\n" ) ) ) + + ;initial search + (when ( and RoutingGood + ( not InitialRoutingSearchDone ) ) + (defvar InitialRoutingSearchPassed t ) ) + (if ( arrayref RouterGapWidthInitialSearchTable "done" ) + (defvar InitialRoutingSearchDone t ) ) + + (let ( + ( RoutingComplete + ( and InitialRoutingSearchDone + ;if initial search, then we're done if + ; there was no success (failed run) + ; detailed routersearch is set off + ; we finished with no router width + ;if detailed search done if all gap searches are done + (if ( equal CurrentSearchTable RouterGapWidthInitialSearchTable ) + ( or ( not InitialRoutingSearchPassed ) + (or ( not OptionDetailedRouterSearch ) + ( equal ( arrayref CurrentSearchTable "trial" ) 0 ) ) ) + ( forall RouterGapWidthSearchTable RouterGapWidthSearchTableList + ( arrayref RouterGapWidthSearchTable "done" ) ) ) ) ) ) + + (cond ( + ( and InitialRoutingSearchDone OptionDetailedRouterSearch ) + (cond ( + ( or RoutingGood ( arrayref CurrentSearchTable "done" ) ) + ( setq CurrentSearchTable + (cond ( + ( ListFindMaximumElement + ( remove CurrentSearchTable + ( setof RouterGapWidthSearchTable RouterGapWidthSearchTableList + ( not ( arrayref RouterGapWidthSearchTable "done" ) ) ) ) + (lambda ( RouterGapWidthSearchTable ) + ( arrayref RouterGapWidthSearchTable "max" ) ) ) ) + ( + CurrentSearchTable ) ) ) ) ) ) + ) + + if( RoutingComplete then + printf( "Routing Search Completed\n" ) + else + printf( "Routing Search Not Complete\n" ) + ) + + ( printf "Route View: %s of %L\n" + ( car PreRouteViewNames ) + PreRouteViewNames ) + ;print current search tables + (cond ( + RouterGapWidthSearchTableList + ( mapcar + (lambda ( RouterGapWidthSearchTable ) + ( println ( tableToList RouterGapWidthSearchTable ) ) ) + RouterGapWidthSearchTableList ) ) + ( println ( tableToList CurrentSearchTable ) ) ) + + ;choose next view to chug on + (defvar PreRouteViewNames + (if RoutingComplete + (let () + ;reset + (defvar InitialRoutingSearchDone nil ) + (defvar InitialRoutingSearchPassed nil ) + (defvar RouterGapWidthInitialSearchTable nil ) + ( exists SomePreRouteViewName ( cdr PreRouteViewNames ) + ( lessp + ( RectGetArea + ( PinUtilFindPRBoundBBox + BoundaryLPP + ( dbOpenCellViewByType + LibName + CellName + SomePreRouteViewName + "maskLayout" + "a" ) + ) ) + BestRoutedViewArea ) ) ) + PreRouteViewNames ) ) + + (defvar RPLRet t ) + (cond ( + ;if more views to try, try them + ( car PreRouteViewNames ) + (defvar RPLRet 1 ) ) + ( + ;else we're done. If there's any routed view, turn it into THE routed view + ( and BestRoutedViewName + BestPreKeepOutRoutedViewName ) + (cond ( + ( and BestPreKeepOutRoutedViewName + BestRoutedViewName + ( ddGetObj LibName CellName BestPreKeepOutRoutedViewName ) + ( ddGetObj LibName CellName BestRoutedViewName ) + ) + (if ( not ( equal BestPreKeepOutRoutedViewName PreKeepOutRoutedViewName ) ) + ( dbSave + ( dbCopyCellView + ( dbOpenCellViewByType + LibName + CellName + BestPreKeepOutRoutedViewName + "maskLayout" + "a" ) + LibName + CellName + PreKeepOutRoutedViewName + nil + nil + t ) ) ) + (if ( not ( equal BestRoutedViewName RoutedViewName ) ) + ( dbSave + ( dbCopyCellView + ( dbOpenCellViewByType + LibName + CellName + BestRoutedViewName + "maskLayout" + "a" ) + LibName + CellName + RoutedViewName + nil + nil + t ) ) ) + + (let ( + ( CellView + ( dbCopyCellView + ( dbOpenCellViewByType + LibName + CellName + RoutedViewName + "maskLayout" + "a" ) + LibName + CellName + ScratchViewName + nil + nil + t ) ) ) + + ( dbReopen CellView "a" ) + + ( KeepOutDrawKeepOut + CellView + DirectiveTable + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ) ) + ( list Metal3LPP ) ) + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ) ) + nil ) + BoundaryLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + ( list GNDNetName VddNetName ) + ( list t nil ) + t + t + 1 ) + + ( KeepOutCreateAbstractView + CellView + LibName + CellName + AbstractViewName + KeepOutDRCRuleFile + WorkingDir + BoundaryLPP + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateAbstractLayerStruct LPP ) ) + ( list Metal3LPP ) ) + ( list GNDNetName VddNetName ) ) + + ( FileUtilAppendStringToFileAndClose + LogFileName + ( sprintf + nil + "%s routed density factor: %f / %f\n" + CellName + ( quotient ( RectGetArea + ( PinUtilFindPRBoundBBox + BoundaryLPP + CellView + ) ) + TotalTransistorArea ) + ( CellInfoLookup DirectiveTable "density_factor" ) + ) ) ) ) ) ) ) ) +RPLRet +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchinit.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchinit.il new file mode 100644 index 0000000000..c908c326b2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routersearchinit.il @@ -0,0 +1,44 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: RouterSearchInit +; Parameter: none +; Return: none +; +; Initialize the router + +defun( RouterSearchInit ( ) + +(when ( null PreRouteViewNames ) + + PreRouteViewList = setof( CellView ddGetObj( LibName CellName ) ~> views + rexMatchp( sprintf( nil "%s_[0-9]+" PreRouteViewName ) CellView~>name ) ) + + PreRouteViewTempList = + foreach( mapcar CellView PreRouteViewList + ViewName = CellView~>name + CellView = dbOpenCellViewByType( LibName CellName ViewName nil "r" ) + BoundaryBox = PinUtilFindPRBoundBBox( BoundaryLPP CellView) + Area = RectGetArea( BoundaryBox ) + list( ViewName Area ) + ) + + PreRouteViewTempList = + sort( copy( PreRouteViewTempList ) + (lambda ( arg1 arg2 ) + cadr(arg1) < cadr(arg2) + ) + ) + + PreRouteViewNames = + foreach( mapcar arg PreRouteViewTempList + car(arg) + ) +) +(printf "views: %L\n" PreRouteViewTempList ) +(printf "viewnames: %L\n" PreRouteViewNames ) +(defvar CurrentPreRouteViewName ( car PreRouteViewNames ) ) + +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routerwidth.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routerwidth.il new file mode 100644 index 0000000000..d652114b13 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/routerwidth.il @@ -0,0 +1,171 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: RouterWidth +; Parameter: TargetCellView (CVId) +; Return: TargetCellView (CVId) +; +; Calculates Router region width + +defun( RouterWidth ( TargetCellView ) + +;get old cell region data from cellview +(defvar CellRegionData + ( PlacementRegionsScrapeCellRegionDataFromCellView + TargetCellView + ( getq TargetCellView instances ) + NChainLibCellPairRegExs + PChainLibCellPairRegExs + GateLibCellPairRegExs + NPlugLibCellPairRegExs + PPlugLibCellPairRegExs + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ( times UserUnitsPerMeter MinWellSpacing ) + TargetCellView->prBoundary + ( times LeafCellMinHorizontalSpacingToBoundary UserUnitsPerMeter ) + ( times LeafCellMinVerticalSpacingToBoundary UserUnitsPerMeter ) + ) ) + +;the minimum of the metal wire pitches + RouterWidthPitch = DefaultWirePitch * UserUnitsPerMeter + +;setup the initial gap search table +(unless RouterGapWidthInitialSearchTable + (defvar RouterGapWidthInitialSearchTable + ( BinarySearchMakeTable + 0 + ( min + 16 + ( floor + ( quotient + ( difference + BestRoutedViewArea + ( RectGetArea + ( PinUtilFindPRBoundBBox + BoundaryLPP + TargetCellView ) ) ) + ( times + YPitch + RouterWidthPitch + ( plus 0.999 +; use plus 0.999 instead of plus 1, due to unpredictable behavior of +; floor(2.0) might give 1 or 2 depending on the machine rounding. + ( length ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) ) ) + ) ) ) ) + 0 ) ) + (defvar RouterGapWidthSearchTableList + ( ListFillList + (lambda ( I ) + RouterGapWidthInitialSearchTable ) + ( plus 1 ( length ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) ) ) ) ) + (defvar CurrentSearchTable RouterGapWidthInitialSearchTable ) ) + +;setup the individual gap search table +(when ( and InitialRoutingSearchDone + ( equal CurrentSearchTable RouterGapWidthInitialSearchTable ) ) + (let ( + ( Max ( arrayref CurrentSearchTable "trial" ) ) ) + (defvar RouterGapWidthSearchTableList + ( ListFillList + (lambda ( I ) + ( BinarySearchMakeTable 0 Max 0 ?MaxTested t ) ) + ( plus 1 + ( length ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) ) ) ) ) + (defvar CurrentSearchTable ( car RouterGapWidthSearchTableList ) ) ) ) + +;setup the current gap width list +(defvar RouterGapWidthList + ( mapcar + ( lambda ( RouterGapWidthTable ) + ( times + (if ( equal CurrentSearchTable RouterGapWidthTable ) + ( arrayref RouterGapWidthTable "trial" ) + ( arrayref RouterGapWidthTable "max" ) ) + RouterWidthPitch ) ) + RouterGapWidthSearchTableList ) ) + +(defvar CellRegionData + ( SquishSquishCellRegionDataAndComponents + TargetCellView + CellRegionData + ( times UserUnitsPerMeter MinRegionWidth ) + ( times UserUnitsPerMeter MinWellSpacing ) + ( times UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectiveTable + Metal3LPP + DirectiveUnitsPerMeter ) ) + LeftBuffer + RightBuffer + RouterGapWidthList + GateLibCellPairRegExs + ( cons + ( list WellPlugLibrary + PWellPlugCellName ) + NChainLibCellPairRegExs ) + ( cons + ( list WellPlugLibrary + NWellPlugCellName ) + PChainLibCellPairRegExs ) + WellPlugLibrary + PWellPlugCellName + NWellPlugCellName + WellPlugViewName + NImplantLPP + PImplantLPP + ( times EvilGatePRegionOffset UserUnitsPerMeter ) + ( times ExtraGateWidth UserUnitsPerMeter ) + ContactLPP ) ) + +( dbSetq + ( PinUtilFindPRBoundShape + BoundaryLPP + TargetCellView ) + ( PlacementRegionsGetCellRegionDataBBox + CellRegionData ) + bBox ) + +( dbSave TargetCellView ) + +TargetCellView +) + +(defun RouterWidthFuncDefault ( RegionRect + Components + Gates + RouterWidth + RouterWidthPitch + RouterWidthSigmoidFactor + NumInstTermsAtHalfRouterWidth ) + (let ( + ( NumInstTerms 0 ) ) + ( foreach Component Components + ( setq NumInstTerms ( plus NumInstTerms ( length ( getq Component conns ) ) ) ) ) + ( foreach Gate Gates + ( setq NumInstTerms + ( plus NumInstTerms ( length + ( setof InstTerm ( getq Gate conns ) + ( exists Pin ( getq ( getq InstTerm term ) pins ) + ( RectDoRectsOverlap + RegionRect + ( dbTransformBBox ( getq ( getq Pin fig ) bBox ) + ( getq ( getq InstTerm inst ) transform ) ) ) ) ) ) ) ) ) + (let ( + ( Alpha ( quotient + 1.0 + ( plus + 1.0 + ( exp + ( times + RouterWidthSigmoidFactor + ( difference + ( float NumInstTermsAtHalfRouterWidth ) + ( float NumInstTerms ) ) ) ) ) ) ) ) + (let ( + ( Ret ( times Alpha RouterWidth RouterWidthPitch ) ) ) + ( printf "# instance terminals in column: %d -> %f\n" NumInstTerms Ret ) + Ret ) ) ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runccar.sh b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runccar.sh new file mode 100755 index 0000000000..962848583f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runccar.sh @@ -0,0 +1,270 @@ +#!/bin/bash + +function usage() { + echo "Usage: $0" + echo " --src-lib=lib" + echo " --src-cell=cell" + echo " --src-lib=view" + echo " --dest-lib=lib" + echo " --dest-cell=cell" + echo " --dest-lib=view" + echo " --rule-file=file" + echo " --do-file=file" + echo " --working-dir=dir" + echo " --log-file=file" + echo " [--conductor-depth=int" + echo " [--pin-connect=strong|weak]" + echo " [--keepout-depth=int]" + echo " [--quit]" + echo " [--import]" + echo " [--no-export-pcells" + echo " [--nog]" +} + +function mywhich() { + which $1 | tail -1 +} + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} + +sh_lib_dir="$package_root/share/script/sh/sh-lib" + +source "$sh_lib_dir/file/filecheck.sh" +source "$sh_lib_dir/file/conon.sh" + +sedcmd=`mywhich sed` +ccar=`mywhich vcar` +icc2cdba=`mywhich icc2cdba` +cdba2icc=`mywhich cdba2icc` + +check_executable_file "$sedcmd" \ + "Unable to find sed in \"$PATH\"." 2 +check_executable_file "$ccar" \ + "Unable to find ccar in \"$PATH\"." 2 +check_executable_file "$icc2cdba" \ + "Unable to find icc2cdba in \"$PATH\"." 2 +check_executable_file "$cdba2icc" \ + "Unable to find cdba2icc in \"$PATH\"." 2 + +src_lib= +src_cell= +src_view= +dest_lib= +dest_cell= +dest_view= +rule_file= +do_files= +conductor_depth=32 +keepout_depth=32 +nog= +quit= +import= +log_file=/dev/null +debug_log_file=/dev/null +pids= +pinConnect=strong +noExportPCells= +fulcrum_pdk_root= +area= +dfII_dir= + +for arg in $@ ; do + + case "$arg" in + --dfII-dir=* ) + dfII_dir=`echo "$arg" | $sedcmd -e "s/--dfII-dir=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrum_pdk_root=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + --src-lib=* ) + src_lib=`echo $arg | $sedcmd -e "s/--src-lib=//"` + ;; + --src-cell=* ) + src_cell=`echo $arg | $sedcmd -e "s/--src-cell=//"` + ;; + --src-view=* ) + src_view=`echo $arg | $sedcmd -e "s/--src-view=//"` + ;; + --dest-lib=* ) + dest_lib=`echo $arg | $sedcmd -e "s/--dest-lib=//"` + ;; + --dest-cell=* ) + dest_cell=`echo $arg | $sedcmd -e "s/--dest-cell=//"` + ;; + --dest-view=* ) + dest_view=`echo $arg | $sedcmd -e "s/--dest-view=//"` + ;; + --conductor-depth=* ) + conductor_depth=`echo $arg | $sedcmd -e "s/--conductor-depth=//"` + ;; + --pin-connect=* ) + pinConnect=`echo $arg | $sedcmd -e "s/--pin-connect=//"` + ;; + --keepout-depth=* ) + keepout_depth=`echo $arg | $sedcmd -e "s/--keepout-depth=//"` + ;; + --do-file=* ) + do_file=`echo $arg | $sedcmd -e "s/--do-file=//"` + do_files="$do_files $do_file" + ;; + --rule-file=* ) + rule_file=`echo $arg | $sedcmd -e "s/--rule-file=//"` + ;; + --working-dir=* ) + working_dir=`echo $arg | $sedcmd -e "s/--working-dir=//"` + ;; + --log-file=* ) + log_file=`echo $arg | $sedcmd -e "s/--log-file=//"` + ;; + --area=* ) + area=`echo $arg | $sedcmd -e "s/--area=//"` + ;; + --debug-log-file=* ) + debug_log_file=`echo $arg | $sedcmd -e "s/--debug-log-file=//"` + ;; + --quit ) + quit=1 + ;; + --no-export-pcells ) + noExportPCells=1 + ;; + --nog ) + nog=1 + ;; + --import ) + import=1 + ;; + esac +done + + + +check_for_empty_arg "$src_lib" \ + "The name of the library of the src cell view to operate on must be specified." 2 +check_for_empty_arg "$src_cell" \ + "The name of the src cell to operate on must be specified." 2 +check_for_empty_arg "$src_view" \ + "The name of the src view to operate on must be specified." 2 +check_for_empty_arg "$dest_lib" \ + "The name of the library of the dest cell view to operate on must be specified." 2 +check_for_empty_arg "$dest_cell" \ + "The name of the dest cell to operate on must be specified." 2 +check_for_empty_arg "$dest_view" \ + "The name of the dest view to operate on must be specified." 2 +check_for_empty_arg "$working_dir" \ + "The working directory must be specified." 2 +check_for_empty_arg "$conductor depth" \ + "The conductor depth must be specified." 2 +check_for_empty_arg "$keepout depth" \ + "The keepout depth must be specified." 2 +check_for_empty_arg "$pinConnect" \ + "The pin connect type must be specified." 2 + +check_readable_file "$rule_file" \ + "Rule File: \"$rule_file\" is not a readable file." 2 +conon_path "$rule_file" +rule_file="$ret" + + +ccar_cmd="$ccar $working_dir/$src_cell.dsn -virtuoso" + +if [ -n "$quit" ] ; then + ccar_cmd="$ccar_cmd -quit" +fi + +if [ -n "$nog" ] ; then + ccar_cmd="$ccar_cmd -nog" +fi + +for do_file in $do_files ; do + check_readable_file "$do_file" \ + "Rule File: \"$do_file\" is not a readable file." 2 + conon_path "$do_file" + do_file="$ret" + ccar_cmd="$ccar_cmd -do $do_file" +done + +if [ ! -e "$working_dir" ] ; then + mkdir -p "$working_dir" +fi + +echo "Exporting to CCAR..." >> $debug_log_file + +if [ -n "$noExportPCells" ] ; then +grep SOFTINCLUDE cds.lib > "$working_dir/cds.lib" +cat<> "$working_dir/cds.lib" +UNDEFINE gate +UNDEFINE stack +UNDEFINE gate#2dfake +UNDEFINE stack#2dfake +DEFINE $gate_lib $fulcrum_pdk_root/share/Fulcrum/dfII/gate-fake +DEFINE $stack_lib $fulcrum_pdk_root/share/Fulcrum/dfII/stack-fake +EOF +cp display.drf "$working_dir" +pushd "$working_dir" +else +pushd "$PWD" +fi + +#export +if [ -n "$area" ] ; then + areaOpt="-area $(echo $area | sed -e 's/,/ /g')" +else + areaOpt= +fi + +cat< $working_dir/.cdsenv +iccTranslator exportVersion int 11 +iccTranslator keepViaImageOnly boolean nil +EOF + +cdba2icc $src_lib $src_cell $src_view \ + -exportDirectory $working_dir \ + -conductorDepth $conductor_depth \ + -keepoutDepth $keepout_depth \ + -fullConnectivity \ + -interLayer \ + $areaOpt \ + -template $rule_file \ + -pinConnect $pinConnect \ + -noIncrementalUpdate +popd + +[ $? == 0 ] || ( echo "Export Failed" && exit 2) +#route +mytemp=$working_dir + +ret=1 +while [[ ! ( $ret == 0 ) ]] ; do + echo "Starting CCAR..." >> $debug_log_file + TEMP=$mytemp TMP=$mytemp HOME=$working_dir LM_LICENSE_FILE=/usr/local/flexlm/licenses/license.0048546B71E0.cadence.dat OA_HOME=/mnt/fulcrum/local/common/cadence/install/OA-2.2-p056-Linux/OpenAccess $ccar_cmd 2> "$working_dir/ccar.err" 1> "$working_dir/ccar.out" + ret=$? + if [ -z "$quit" ] ; then + ret=0 + fi + # Don't do this hack any more(always leave the loop). + # Left here for posterity. + ret=0 + if [[ ! ( $ret == 0 ) ]] ; then sleep 10 ; fi +done + +#import +if [ -n "$import" ] ; then + icc2cdba \ + $dest_lib $dest_cell $dest_view \ + -session "$working_dir/$dest_cell.ses" +fi + +echo "Writing Results" >> $debug_log_file + +echo "Starting Import..." >> $debug_log_file +cross_clear_unroute=`cat $working_dir/monitor.sts | tail -2 | head -1 | cut -f4,5,7 -d "|" | sed -e "s/|//g"` +completion=`grep "Completion" $working_dir/monitor.sts | awk '{print $3}' | sed -e "s/\%//"` + +echo $cross_clear_unroute $completion > $log_file + +echo "Exiting..." >> $debug_log_file + +sync diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runrouter.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runrouter.il new file mode 100644 index 0000000000..16a80b716c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/runrouter.il @@ -0,0 +1,40 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: Router +; Parameter: TargetViewName (string) +; DoFile (string) +; Return: RoutingGood (boolean) +; +; Run Router + +defun( Router ( TargetViewName ) + + let( ( CellView mycmd TclFile) + CellView = dbOpenCellViewByType( + LibName + CellName + TargetViewName + "maskLayout" + "a" ) + AddLeafBlockageCell( CellView ) + TclFile=strcat(CellDir "/router_temp.tcl") + mycmd=sprintf( nil "/usr/bin/sed -e \"s/LIBNAME/%s/g\" -e \"s/CELLNAME/%s/g\" -e \"s/VIEWNAME/%s/g\" -e \"s^EXCLUDENET^%s^g\" <%s >%s\n" LibName CellName TargetViewName RouterExcludeNetFile RouterTemplateTclFile TclFile ) + println(mycmd) + system(mycmd) + geOpen(?lib LibName ?cell CellName ?view TargetViewName ?mode "a") + deInstallApp(getCurrentWindow() "Virtuoso XL") + + RoutingGood = rdeSource(TclFile) + DeleteLeafBlockageCell( CellView ) + dbSave( CellView ) + ) +RoutingGood +) + + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/setglcparams.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/setglcparams.il new file mode 100644 index 0000000000..01d8fe4b55 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/setglcparams.il @@ -0,0 +1,54 @@ +; Copyright 2007 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( SetGLCParams ( CellView glc ) + let( (instances inst ) + instances=cadr( NameFilterInstances( CellView~>instances + append( GateLibCellPairRegExs StackLibCellPairRegExs ))) + foreach( inst instances + dbReplaceProp(inst "glc" "boolean" glc) + ) + dbSave( CellView ) + ) +) + +defun( GrowPrbound ( CellView size ) + let((prBoundShapes shape x1 x2 y1 y2) + prBoundShapes= setof( shape CellView~>shapes shape~>layerName=="prBoundary" && shape~>objType=="rect") + foreach(shape prBoundShapes + x1=leftEdge(shape~>bBox) + x2=rightEdge(shape~>bBox) + y1=bottomEdge(shape~>bBox) + y2=topEdge(shape~>bBox) + shape~>bBox=list(x1:y1-size x2:y2+size) + ) + ) +) + +defun( AddPrboundBoundary ( CellView size ) + ; add prbound boundary for PO to route within NP, PP + let((prBoundShapes shape x1 x2 y1 y2) + prBoundShapes= setof( shape CellView~>shapes shape~>layerName=="prBoundary" && shape~>purpose=="drawing" && shape~>objType=="rect") + if( prBoundShapes then + shape=car( prBoundShapes ) + x1=leftEdge(shape~>bBox) + x2=rightEdge(shape~>bBox) + y1=bottomEdge(shape~>bBox) + y2=topEdge(shape~>bBox) + dbCreateRect( CellView list("prBoundary" "boundary" ) + list(x1:y1-size x2:y2+size) + ) + ) + ) +) + +defun( DeletePrboundBoundary ( CellView ) + let((prBoundShapes shape) + prBoundShapes= setof( shape CellView~>shapes shape~>layerName=="prBoundary" && shape~>purpose=="boundary") + foreach( shape prBoundShapes + dbDeleteObject( shape ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/snapFatPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/snapFatPins.il new file mode 100644 index 0000000000..ef1d3b3c52 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/snapFatPins.il @@ -0,0 +1,52 @@ +; Copyright 2007 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( SnapFatPinsGetClosestTrack ( CellView pin ) + let((wirePitch wireSpacing wirePitchOffset fig x1 x2 y1 y2 height track trackGood yy1 yy2 m3Shapes track_inc) + wirePitch=DefaultWirePitch*MicronsPerMeter + wireSpacing=DefaultWireSpacing*MicronsPerMeter + wirePitchOffset=0.06 + foreach( fig pin~>pins~>fig + x1=leftEdge(fig~>bBox) + x2=rightEdge(fig~>bBox) + y1=bottomEdge(fig~>bBox) + y2=topEdge(fig~>bBox) + height=y2-y1 + yy1=y1 + track=floor((y1-wirePitchOffset)/wirePitch) + track_inc=-1 + trackGood=t + while( (trackGood && y1-yy1<2.88 && yy1-max(y1 0)<2.88) + yy1=track*wirePitch+wirePitchOffset + yy2=yy1+height + m3Shapes=dbGetTrueOverlaps(CellView + list(list(x1-wireSpacing+0.001 yy1-wireSpacing+0.001) + list(x2+wireSpacing-0.001 yy2+wireSpacing-0.001)) + PinLPP + 0) + trackGood=setof( shape m3Shapes shape~>objType!="label" && !member(shape pin~>pins~>fig)) || yy2<0.0 + if(track<=0 then track_inc=1) + track=track+track_inc + ) + + if(!trackGood then + dbMoveFig(fig CellView list( 0.0:yy1-y1 "R0" 1.0 ) ) + ) + ) + ) +) + +defun( SnapFatPins ( CellView ) +; find all Fat Pins and those go outside of PrBound and fix them. + let((pins pin defaultPinWidth) + pins=setof( pin CellView~>terminals pin~>net~>name!="Vdd" && pin~>net~>name!="GND") + defaultPinWidth=CellInfoLookupParametrized( DirectiveTable "layer_wirewidth" "layer" PinLPP)*UserUnitsPerMeter + pins=setof( pin pins car(pin~>pins~>fig)~>bBox && (topEdge(car(pin~>pins~>fig)~>bBox)-bottomEdge(car(pin~>pins~>fig)~>bBox)>defaultPinWidth+0.001 || topEdge(car(pin~>pins~>fig)~>bBox)<0.0)) + foreach(pin pins + SnapFatPinsGetClosestTrack( CellView pin ) + ) + + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/swapvias.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/swapvias.il new file mode 100644 index 0000000000..bcc66916fb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/router/swapvias.il @@ -0,0 +1,175 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: SwapVias +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; Swap vias + +defun( hkBBoxEnclose ( bBox1 bBox2 ) + leftEdge(bBox1)<=leftEdge(bBox2) && + rightEdge(bBox1)>=rightEdge(bBox2) && + bottomEdge(bBox1)<=bottomEdge(bBox2) && + topEdge(bBox1)>=topEdge(bBox2) +) + +defun( hkSnapXToGrid (x Grid) + if( x floor(x/Grid+0.5)*Grid nil ) +) + +defun( fixBoundaryVia23 ( CellView ) + ;fix the M3_M2c via that at the boundary that violates M3 space to boundray 0.05 frc rule + ; by (1) make M3 extension vertical + ; or (2) move M3_M2c via inside by 0.02 + let((prBoundShapes shape x1 x2 y1 y2 allvia23 badvia23_1 badvia23_2 inst via1 via2) + prBoundShapes= setof( shape CellView~>shapes shape~>layerName=="prBoundary" && shape~>objType=="rect") + shape=car(prBoundShapes) + x1=leftEdge(shape~>bBox) + x2=rightEdge(shape~>bBox) + y1=bottomEdge(shape~>bBox) + y2=topEdge(shape~>bBox) + allvia23=setof( inst CellView~>instances inst~>cellName=="M3_M2c") + badvia23_1=setof( inst allvia23 car(inst~>xy)xy)>x2-0.14 ) + badvia23_3=setof( inst allvia23 cadr(inst~>xy)>y2-0.14 ) + via1=nrOpenCellViewReadable( TechLibName "M3_M2_V" "layout") + via2=nrOpenCellViewReadable( TechLibName "M3_M2_H" "layout") + ; fix M3_M2c via on the left side + foreach( inst badvia23_1 + if( length(dbGetTrueOverlaps( CellView + list( car(inst~>xy)-0.09:cadr(inst~>xy)-0.21 + car(inst~>xy)+0.09:cadr(inst~>xy)+0.21 ) + Metal3LPP + 0 ))>1 then + inst~>xy=list(car(inst~>xy)+0.02 cadr(inst~>xy)) + else + dbReplaceProp( inst "layer1Direction" "string" "XY") + dbReplaceProp( inst "layer1YEnclosure" "float" 0.04) + dbReplaceProp( inst "layer2Direction" "string" "XY") + dbReplaceProp( inst "layer2YEnclosure" "float" 0.04) + dbReplaceProp( inst "layer2XEnclosure" "float" 0.01) + inst~>master=via1 + ) + ) + ; fix M3_M2c via on the right side + foreach( inst badvia23_2 + if( length(dbGetTrueOverlaps( CellView + list( car(inst~>xy)-0.09:cadr(inst~>xy)-0.21 + car(inst~>xy)+0.09:cadr(inst~>xy)+0.21 ) + Metal3LPP + 0 ))>1 then + inst~>xy=list(car(inst~>xy)-0.02 cadr(inst~>xy)) + else + dbReplaceProp( inst "layer1Direction" "string" "XY") + dbReplaceProp( inst "layer1YEnclosure" "float" 0.04) + dbReplaceProp( inst "layer2Direction" "string" "XY") + dbReplaceProp( inst "layer2YEnclosure" "float" 0.04) + dbReplaceProp( inst "layer2XEnclosure" "float" 0.01) + inst~>master=via1 + ) + ) + ; fix M3_M2c via on the top side + foreach( inst badvia23_3 + if( length(dbGetTrueOverlaps( CellView + list( car(inst~>xy)-0.21:cadr(inst~>xy)-0.09 + car(inst~>xy)+0.21:cadr(inst~>xy)+0.09 ) + Metal3LPP + 0 ))>1 then + inst~>xy=list(car(inst~>xy) cadr(inst~>xy)-0.02) + else + dbReplaceProp( inst "layer1Direction" "string" "XY") + dbReplaceProp( inst "layer1YEnclosure" "float" 0.01) + dbReplaceProp( inst "layer1XEnclosure" "float" 0.04) + dbReplaceProp( inst "layer2Direction" "string" "XY") + dbReplaceProp( inst "layer2YEnclosure" "float" 0.01) + dbReplaceProp( inst "layer2XEnclosure" "float" 0.04) + inst~>orient="R0" + inst~>master=via2 + ) + ) + + ) +) + +defun( SwapVias ( CellView ) + ; replace double via M2_M1min with + ; (1) M2_M1c if M1 below has enough room for horizontal extension + ; or (2) M2_M1_V if M1 below does not have enough room for horizontal extension. + let((inst viaInst m1shape m2shape shape x left right via1) + viaInsts=setof( inst CellView~>instances inst~>cellName=="M2_M1min" ) + via1=nrOpenCellViewReadable( TechLibName "M2_M1c" "layout") + via2=nrOpenCellViewReadable( TechLibName "M2_M1_V" "layout") + foreach( inst viaInsts + m1shape=car( setof( shape dbGetTrueOverlaps( CellView inst~>bBox list("M1" "drawing") 0 ) hkBBoxEnclose( shape~>bBox inst~>bBox )))~>bBox + m2shape=car( setof( shape dbGetTrueOverlaps( CellView inst~>bBox list("M2" "drawing") 0 ) hkBBoxEnclose( shape~>bBox inst~>bBox )))~>bBox + left=0.0 right=0.0 + if( m1shape && m2shape then + left=max( leftEdge(m1shape)+0.03 leftEdge(m2shape)) + right=min( rightEdge(m1shape)-0.03 rightEdge(m2shape))) + if(right-left>=0.32 then + ; M1 below has enough room for horizontal extension + ; replace with M2_M1c + x=hkSnapXToGrid((right+left)/2 0.005) + dbReplaceProp( inst "layer1Direction" "string" "XY") + dbReplaceProp( inst "layer1XEnclosure" "float" 0.04) + dbReplaceProp( inst "layer2Direction" "string" "XY") + dbReplaceProp( inst "layer2YEnclosure" "float" 0.04) + inst~>xy=list( x cadr(inst~>xy) ) + inst~>master=via1 + else + ; M1 below does not have enough room for horizontal extension + ; replace with M2_M1_V + dbReplaceProp( inst "layer1YEnclosure" "float" 0.04) + dbReplaceProp( inst "layer2Direction" "string" "XY") + dbReplaceProp( inst "layer2YEnclosure" "float" 0.04) + inst~>master=via2 + ) + ) +; SwapSchematicMasters( +; CellView +; ViaMappings ) + + dbSave( CellView ) + ) +) + +defun( fixFatPolyContact ( CellView ) + let((polyContacts inst) + polyContacts=setof( inst CellView~>instances + inst~>cellName=="M1_POLY" ) + foreach( inst polyContacts + if( dbGetPropByName(inst "layer1XDefOverride")~>value && dbGetPropByName(inst "layer1XDefOverride")~>value>0.04 then + dbReplaceProp( inst "layer1XDefOverride" "float" 0.04) + printf("Fixing Poly Contact %L \n" inst~>xy) + ) + ) + t + ) +) + +defun( fixNegativeExtension ( CellView ) + let((polyContacts M2_M1c inst) + polyContacts=setof( inst CellView~>instances + inst~>cellName=="M1_POLY" ) + foreach( inst polyContacts + if( dbGetPropByName(inst "layer2XDefOverride")~>value && dbGetPropByName(inst "layer2XDefOverride")~>value<0.0 then + dbReplaceProp( inst "layer2XDefOverride" "float" 0.04) + dbReplaceProp( inst "layer2XEnclosure" "float" 0.04) + printf("Fixing Poly Contact %L \n" inst~>xy) + ) + ) + M2_M1c=setof( inst CellView~>instances + inst~>cellName=="M2_M1c" ) + foreach( inst M2_M1c + if( dbGetPropByName(inst "layer1XDefOverride")~>value && dbGetPropByName(inst "layer1XDefOverride")~>value<0.0 then + dbReplaceProp( inst "layer1XDefOverride" "float" 0.04) + dbReplaceProp( inst "layer1XEnclosure" "float" 0.04) + printf("Fixing M2_M1c %L \n" inst~>xy) + ) + ) + t + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/template.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/template.il new file mode 100644 index 0000000000..7b2acb1092 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/template.il @@ -0,0 +1,49 @@ +(defun DecideTemplate ( OutInvNW1 OutInvPW1 NandNW5 NandPW1 LeNW1 LePW1 ) + + when((OutInvNW1<=1.56)&&(OutInvPW1<=2.08)&&(NandNW5<1.69)&&(NandPW1<0.65)&&(LeNW1<2.21)&&(LePW1<3.9) + printf("Template\n") + Output="Template" + ) + + when((OutInvNW1<=1.56)&&(OutInvPW1<=2.08)&&(NandNW5>=1.69)&&(NandPW1>=0.65)&&(LeNW1>=2.21)&&(LePW1>=3.9) + printf("Template1\n") + Output="Template1" + ) + + when((OutInvNW1>=1.56)&&(OutInvPW1>=2.08) + printf("Template2\n") + Output="Template2" + ) + + Output + ) + + +(defun Template () + (let (text fl k parameter1 parameter2 parameter3 parameter4 OutInvNW1 OutInvPW1 NandNW5 NandPW1 LeNW1 LePW1 OutPut) + + + fl = infile("Parameter.txt") + while( gets(k fl) != nil + text = parseString( k " \n") + parameter1 = nth(0 text) + parameter2 = nth(1 text) + parameter3 = nth(2 text) + parameter4 = nth(3 text) + + when((parameter1=="R.0") + OutInvNW1=evalstring(parameter3) + OutInvPW1=evalstring(parameter4) + ) + when((parameter1=="rv") + NandNW5=evalstring(parameter3) + NandPW1=evalstring(parameter4) + ) + when((parameter1=="L.e") + LeNW1=evalstring(parameter3) + LePW1=evalstring(parameter4) + ) + ) + DecideTemplate( OutInvNW1 OutInvPW1 NandNW5 NandPW1 LeNW1 LePW1) +)) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/drawregionwell.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/drawregionwell.il new file mode 100644 index 0000000000..075a93efa2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/drawregionwell.il @@ -0,0 +1,34 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: RegionWell +; Parameter: CellView (CVId) +; Return: CellView (CVId) +; +; + + +defun( RegionWell ( CellView ) + + ( foreach Shape + ( append + ( PinUtilGetAllShapesOnLPP + CellView + NWellLPP ) + ( PinUtilGetAllShapesOnLPP + CellView + PWellLPP ) ) + ( dbDeleteObject Shape ) ) + + ( RegionWellDrawWellInTransistorRegions + CellView + CellRegionData + NWellLPP + PWellLPP + NImplantLPP + PImplantLPP ) + ( dbSave CellView ) + CellView +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/regionwell.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/regionwell.il new file mode 100644 index 0000000000..9ba49a2a10 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/leaf/well/regionwell.il @@ -0,0 +1,125 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun RegionWellDrawWellInTransistorRegions ( CellView + CellRegionData + NWellLPP + PWellLPP + NImplantLPP + PImplantLPP ) + + ( foreach + Column + ( PlacementRegionsGetCellRegionDataColumnList + CellRegionData ) + (let ( + ( NTransistorRegionRect ( PlacementRegionGetColumnNRegionRect + Column ) ) + ( PTransistorRegionRect ( PlacementRegionGetColumnPRegionRect + Column ) ) + ( BottomGateRegionRect ( PlacementRegionGetColumnBottomGateRegionRect + Column ) ) + ( TopGateRegionRect ( PlacementRegionGetColumnTopGateRegionRect + Column ) ) + ( ImplantMinWidth 0.0 ) ) + (let ( + ( PWellLeftEdge ( RectGetLeft NTransistorRegionRect ) ) + ( PWellRightEdge ( RectGetRight NTransistorRegionRect ) ) + ( NWellLeftEdge ( RectGetLeft PTransistorRegionRect ) ) + ( NWellRightEdge ( RectGetRight PTransistorRegionRect ) ) ) + (let ( + ;N Transistors go in a P-Well + ( TopPWellRect ( list + ( list + PWellLeftEdge + ( RectGetBottom TopGateRegionRect ) ) + ( list + PWellRightEdge + ( plus + ( RectGetTop TopGateRegionRect ) + ImplantMinWidth ) ) ) ) + ;N Transistors go in a P-Well + ( BottomPWellRect ( list + ( list + PWellLeftEdge + ( difference + ( RectGetBottom BottomGateRegionRect ) + ImplantMinWidth ) ) + ( list + PWellRightEdge + ( RectGetTop BottomGateRegionRect ) ) ) ) + + ;P Transistors go in a N-Well + ( TopNWellRect ( list + ( list + NWellLeftEdge + ( RectGetBottom TopGateRegionRect ) ) + ( list + NWellRightEdge + ( plus + ( RectGetTop TopGateRegionRect ) + ImplantMinWidth ) ) ) ) + ;P Transistors go in a N-Well + ( BottomNWellRect ( list + ( list + NWellLeftEdge + ( difference + ( RectGetBottom BottomGateRegionRect ) + ImplantMinWidth ) ) + ( list + NWellRightEdge + ( RectGetTop BottomGateRegionRect ) ) ) ) ) + + (when ( and + PWellLPP + ( greaterp ( RectGetArea NTransistorRegionRect ) 0.1 ) ) + ( dbCreateRect + CellView + PWellLPP + NTransistorRegionRect ) ) + + (when ( and + NWellLPP + ( greaterp ( RectGetArea PTransistorRegionRect ) 0.1 ) ) + ( dbCreateRect + CellView + NWellLPP + PTransistorRegionRect ) ) + + (when ( and + PWellLPP + ( greaterp ( RectGetArea TopPWellRect ) 0.1 ) + ) + ( dbCreateRect + CellView + PWellLPP + TopPWellRect ) ) + + (when ( and + NWellLPP + ( greaterp ( RectGetArea TopNWellRect ) 0.1 ) ) + ( dbCreateRect + CellView + NWellLPP + TopNWellRect ) ) + + (when ( and + PWellLPP + ( greaterp ( RectGetArea BottomPWellRect ) 0.1 ) ) + ( dbCreateRect + CellView + PWellLPP + BottomPWellRect ) ) + + (when ( and + NWellLPP + ( greaterp ( RectGetArea BottomNWellRect ) 0.1 ) + ) + ( dbCreateRect + CellView + NWellLPP + BottomNWellRect ) ) ) ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/apr_lefdef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/apr_lefdef.il new file mode 100644 index 0000000000..4fddf4302e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/apr_lefdef.il @@ -0,0 +1,494 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/rrc/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/apr_lefdef.il#1 $ +; $DateTime: 2013/06/18 14:33:02 $ +; $Author: pankala $ + +(defvar DefLibList list("vendor.avago.abstracts" "chip.rrc.fabric.fc.ffu" "lib.synchronous.conversion.a2s_hs" "lib.synchronous.conversion.s2a_hs" "lib.synchronous.conversion.a2s_ls" "lib.synchronous.conversion.s2a_ls")) + +(defvar APRList list( + "chip__rrc__fabric__fc__ffu__FFU_SLICE_4__1000" + "chip__rrc__fabric__fc__ffu__EACL__1000" + "chip__rrc__fabric__fc__PARSING__1000" + "chip__rrc__fabric__fc__FFU__1000" + "chip__rrc__fabric__fc__POST__1000" + "chip__rrc__fabric__fc__TAIL__1000" + "chip__rrc__fabric__fc__FRAME_CONTROL__1000" + "chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000" + "chip__rrc__fabric__scheduler__SCHEDULER__1000" + "chip__rrc__fabric__array__ARRAY_SUBSEG__1000" + "chip__rrc__mgmt__MGMT__1000" + "chip__rrc__port__epl__EPL__1000" + "chip__rrc__port__mgmt__PORTS_MGMT__1000" + "pep" + "pep_pcw" + "chip__rrc__hosts__visa_pads__VISA_PADS__1000" + "chip__rrc__hosts__pcie_host__PCIE_HOST__1000" + "chip__rrc__hosts__pcie_mgmt__PCIE_MGMT__1000" + "chip__rrc__te__tunnel_engine__TUNNEL_ENGINE__1000" + "chip__rrc__mgmt__linear_bus__FABRIC_MGMT_IN_OUT__1000" +)) + +(defun defLocation ( module ) + (let ( defLoc spar_dir dfII_dir libLoc dfIILoc + ) + + spar_dir = strcat( (userRootDir) "spar" ) + dfII_dir = ( ConfigFileGetValue TheCDSConfigTable "DFII_DIR" ) + case( module + ( "chip__rrc__fabric__fc__ffu__FFU_SLICE_4__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/fc/ffu/FFU_SLICE_4/1000/" module ".def") libLoc="chip.rrc.fabric.fc.ffu" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/fc/ffu/" module )) + ( "chip__rrc__fabric__fc__ffu__EACL__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/fc/ffu/EACL/1000/" module ".def") libLoc="chip.rrc.fabric.fc.ffu" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/fc/ffu/" module )) + ( "chip__rrc__fabric__fc__PARSING__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/fc/PARSING/1000/" module ".def") libLoc="chip.rrc.fabric.fc" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/fc/" module )) + ( "chip__rrc__fabric__fc__FFU__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/fc/FFU/1000/" module ".def") libLoc="chip.rrc.fabric.fc" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/fc/" module )) + ( "chip__rrc__fabric__fc__POST__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/fc/POST/1000/" module ".def") libLoc="chip.rrc.fabric.fc" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/fc/" module )) + ( "chip__rrc__fabric__fc__TAIL__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/fc/TAIL/1000/" module ".def") libLoc="chip.rrc.fabric.fc" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/fc/" module )) + ( "chip__rrc__fabric__fc__FRAME_CONTROL__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/fc/FRAME_CONTROL/1000/" module ".def") libLoc="chip.rrc.fabric.fc" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/fc/" module )) + ( "chip__rrc__fabric__modify__mod_sync__MOD_SYNC__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/modify/mod_sync/MOD_SYNC/1000/" module ".def") libLoc="chip.rrc.fabric.modify.mod_sync" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/modify/mod_sync/" module )) + ( "chip__rrc__fabric__scheduler__SCHEDULER__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/scheduler/SCHEDULER/1000/" module ".def") libLoc="chip.rrc.fabric.scheduler" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/scheduler/" module )) + ( "chip__rrc__fabric__array__ARRAY_SUBSEG__1000" defLoc=strcat(spar_dir "/chip/rrc/fabric/array/ARRAY_SUBSEG/1000/" module ".def") libLoc="chip.rrc.fabric.array" + dfIILoc=strcat(dfII_dir "/chip/rrc/fabric/array/" module )) + ( "chip__rrc__mgmt__MGMT__1000" defLoc=strcat(spar_dir "/chip/rrc/mgmt/MGMT/1000/" module ".def") libLoc="chip.rrc.mgmt" + dfIILoc=strcat(dfII_dir "/chip/rrc/mgmt/" module )) + ( "chip__rrc__port__epl__EPL__1000" defLoc=strcat(spar_dir "/chip/rrc/port/epl/EPL/1000/" module ".def") libLoc="chip.rrc.port.epl" + dfIILoc=strcat(dfII_dir "/chip/rrc/port/epl/" module )) + ( "chip__rrc__port__mgmt__PORTS_MGMT__1000" defLoc=strcat(spar_dir "/chip/rrc/port/mgmt/PORTS_MGMT/1000/" module ".def") libLoc="chip.rrc.port.mgmt" + dfIILoc=strcat(dfII_dir "/chip/rrc/port/mgmt/" module )) + ( "pep" defLoc=strcat(spar_dir "/chip/rrc/hosts/pep/" module ".def") libLoc="chip.rrc.hosts" + dfIILoc=strcat(dfII_dir "/chip/rrc/hosts/" module )) + ( "pep_pcw" defLoc=strcat(spar_dir "/chip/rrc/hosts/pep_pcw/" module ".def") libLoc="chip.rrc.hosts" + dfIILoc=strcat(dfII_dir "/chip/rrc/hosts/" module )) + ( "chip__rrc__hosts__visa_pads__VISA_PADS__1000" defLoc=strcat(spar_dir "/chip/rrc/hosts/visa_pads/VISA_PADS/1000/" module ".def") libLoc="chip.rrc.hosts.visa_pads" + dfIILoc=strcat(dfII_dir "/chip/rrc/hosts/visa_pads/" module )) + ( "chip__rrc__hosts__pcie_host__PCIE_HOST__1000" defLoc=strcat(spar_dir "/chip/rrc/hosts/pcie_host/PCIE_HOST/1000/" module ".def") libLoc="chip.rrc.hosts.pcie_host" + dfIILoc=strcat(dfII_dir "/chip/rrc/hosts/pcie_host/" module )) + ( "chip__rrc__hosts__pcie_mgmt__PCIE_MGMT__1000" defLoc=strcat(spar_dir "/chip/rrc/hosts/pcie_mgmt/PCIE_MGMT/1000/" module ".def") libLoc="chip.rrc.hosts.pcie_mgmt" + dfIILoc=strcat(dfII_dir "/chip/rrc/hosts/pcie_mgmt/" module )) + ( "chip__rrc__te__tunnel_engine__TUNNEL_ENGINE__1000" defLoc=strcat(spar_dir "/chip/rrc/te/tunnel_engine/TUNNEL_ENGINE/1000/" module ".def") libLoc="chip.rrc.te.tunnel_engine" + dfIILoc=strcat(dfII_dir "/chip/rrc/te/tunnel_engine/" module )) + ( "chip__rrc__mgmt__linear_bus__FABRIC_MGMT_IN_OUT__1000" defLoc=strcat(spar_dir "/chip/rrc/mgmt/linear_bus/FABRIC_MGMT_IN_OUT/1000/" module ".def") libLoc="chip.rrc.mgmt.linear_bus" + dfIILoc=strcat(dfII_dir "/chip/rrc/mgmt/linear_bus/" module )) + ) + + list(defLoc libLoc dfIILoc) + ) +) + +(defun importAvagoMem ( memName ) + (let ( + root_dir temp_lef + temp_dir lef_in + spar_dir dfII_dir + mem_lef +) + + + root_dir = (userRootDir) ; "/nfs/site/disks/wdisk.83/pankala1/rrc_1/" + temp_dir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ; strcat(root_dir "temp/") + spar_dir = strcat(root_dir "spar/vendor/avago/mem/") + dfII_dir = sprintf(nil "%sdfII/vendor/avago/abstracts/%s/" root_dir memName) + mem_lef = sprintf(nil "%s%s/%s.lef" spar_dir memName memName) + temp_lef = sprintf(nil "%s/%s.lef" temp_dir memName) + + sh(strcat("cp " mem_lef " " temp_dir)) + sh(strcat("chmod +w " temp_lef)) + sh(strcat("perl -pi.bak -e 's/metal/M/g;' " temp_lef)) + + + P4File( strcat(dfII_dir "abstract/master.tag") "edit" ) + P4File( strcat(dfII_dir "abstract/layout.oa") "edit" ) + P4File( strcat(dfII_dir "abstract/thumbnail_128x128.png") "edit" ) + P4File( strcat(dfII_dir "abstract/master.tag") "lock" ) + P4File( strcat(dfII_dir "abstract/layout.oa") "lock" ) + P4File( strcat(dfII_dir "abstract/thumbnail_128x128.png") "lock" ) + currCV = ddGetObj("vendor.avago.abstracts" memName "abstract" ) + when( currCV!=nil ddDeleteObj(currCV) ) + + lef_in = ldtrLefReadOA(temp_lef "vendor.avago.abstracts") + + currCV = nrOpenCellViewWritable("vendor.avago.abstracts" memName "abstract") + when(currCV + foreach(s currCV~>shapes when(s~>theLabel dbDeleteObject(s))) + foreach(s currCV~>shapes when(s~>net~>name MidPinsCreateLabel(currCV s))) + dbSave(currCV) + dbClose(currCV) + ) + + when(lef_in + P4File( strcat(dfII_dir "abstract/master.tag") "add" ) + P4File( strcat(dfII_dir "abstract/layout.oa") "add" ) + P4File( strcat(dfII_dir "abstract/thumbnail_128x128.png") "add" ) + ) + ) +) + + +(defun importCDCAbstract ( cdcName ) + (let ( + root_dir temp_lef cdcType + temp_dir lef_in cdcSpeed + spar_dir dfII_dir cdcOrient + mem_lef currCV cdcSize + cdcLib + +) + + parts = parseString( cdcName "_" ) + cdcType = nth( 0 parts ) + cdcSpeed = nth( 1 parts ) + cdcOrient = nth( 2 parts ) + cdcSize = nth( 3 parts ) + cdcLib = strcat( "lib.synchronous.conversion." cdcType "_" cdcSpeed ) + root_dir = (userRootDir) ; "/nfs/site/disks/wdisk.83/pankala1/rrc_1/" + temp_dir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ; strcat(root_dir "temp/") + spar_dir = strcat(root_dir "spar/lib/synchronous/conversion/" cdcType "_" cdcSpeed "/") + dfII_dir = sprintf(nil "%sdfII/lib/synchronous/conversion/%s_%s/%s/" root_dir cdcType cdcSpeed cdcName ) + mem_lef = sprintf(nil "%s%s/%s.lef" spar_dir cdcName cdcName) + + P4File( strcat(dfII_dir "abstract/master.tag") "edit" ) + P4File( strcat(dfII_dir "abstract/layout.oa") "edit" ) + P4File( strcat(dfII_dir "abstract/thumbnail_128x128.png") "edit" ) + P4File( strcat(dfII_dir "abstract/master.tag") "lock" ) + P4File( strcat(dfII_dir "abstract/layout.oa") "lock" ) + P4File( strcat(dfII_dir "abstract/thumbnail_128x128.png") "lock" ) + currCV = ddGetObj( cdcLib cdcName "abstract" ) + when( currCV!=nil ddDeleteObj(currCV) ) + + lef_in = ldtrLefReadOA( mem_lef cdcLib ) + currCV = nrOpenCellViewWritable( cdcLib cdcName "abstract" ) + + when(currCV + foreach(s currCV~>shapes when(s~>theLabel dbDeleteObject(s))) + foreach(s currCV~>shapes when(s~>net~>name MidPinsCreateLabel(currCV s))) + dbSave(currCV) + dbClose(currCV) + ) + + when(lef_in + P4File( strcat(dfII_dir "abstract/master.tag") "add" ) + P4File( strcat(dfII_dir "abstract/layout.oa") "add" ) + P4File( strcat(dfII_dir "abstract/thumbnail_128x128.png") "add" ) + ) + ) +) + +(defun recurseCDC ( memList ) + (let ( + infl + mem + ) + + inFl = infile(memList) + + while( gets(mem inFl) + printf("%s" car(parseString(mem "\n"))) + importCDCAbstract(car(parseString(mem "\n"))) + ) + + ) +) + + +(defun userRootDir () + (let ( parts root I ) + + parts = parseString(( ConfigFileGetValue TheCDSConfigTable "DFII_DIR" ) "/") + root = "/" + for(I 0 length(parts)-2 root = strcat(root nth(I parts) "/") ) + + root + ) +) + +(defun extractMem ( defFile ) + (let ( ) + + + sh(strcat("rm " defFile ".mem")) + sh(strcat("sort " defFile " | grep mem28 | awk '{print $3}' > " defFile ".mem")) + + + ) +) + +(defun recurseMem ( memList ) + (let ( + infl + mem + ) + + inFl = infile(memList) + + while( gets(mem inFl) + printf("%s" car(parseString(mem "\n"))) + importAvagoMem(car(parseString(mem "\n"))) + ) + + ) +) + +(defun recurseLefs ( memList ) + (let ( + infl + mem + ) + + inFl = infile(memList) + + while( gets(mem inFl) + printf("%s" car(parseString(mem "\n"))) + ldtrLefReadOA(car(parseString(mem "\n")) "vendor.avago.abstracts") + ) + + ) +) + +(defun preICCDef ( defFile ) + (let ( ) + sh(strcat("perl -pi.bak -e 's/\\./_/g; s/\\//\\./g; s/\\\\//g;' " defFile)) + ) +) + +(defun preICCDefVia ( defFile ) + (let ( ) + sh(strcat("perl -pi.bak -e 's/VIA910_1cut/M10_M9/g; s/VIA89_1cut/M9_M8/g; s/VIA78_LONG_H/M8_M7/g; s/VIA67_LONG_H/M7_M6/g; s/VIA56_LONG_H/M6_M5/g; s/VIA45_LONG_H/M5_M4/g; s/VIA34_LONG_H/M4_M3/g; s/VIA23_LONG_H/M3_M2/g; s/VIA12_LONG_H/M2_M1/g; ' " defFile)) + ) +) + +(defun preICCDefCus ( defFile cellName ) + (let ( ) + + case( cellName + ( "chip__rrc__port__mgmt__PORTS_MGMT__1000" + sh(strcat("perl -pi.bak -e 's/pad2pm\\\\\\[eth_refclk\\\\\\]/pad2pm\\\\\\[0\\\\\\]/g; ' " defFile)) + ) + ( "chip__rrc__mgmt__MGMT__1000" + sh(strcat("perl -pi.bak -e 's/pad2lsm\\\\\\[pcie_refclk\\\\\\]/pad2lsm\\\\\\[0\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/pad2lsm\\\\\\[ieee1588_refclk\\\\\\]/pad2lsm\\\\\\[1\\\\\\]/g; ' " defFile)) + ) + ( "pep" + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[clock1\\\\\\]/i_systime\\\\\\[0\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[clock0\\\\\\]/i_systime\\\\\\[1\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[plus1\\\\\\]/i_systime\\\\\\[2\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[minus1\\\\\\]/i_systime\\\\\\[3\\\\\\]/g; ' " defFile)) + ) + ( t t ) + ) + ) +) + +(defun postICCDef ( defFile ) + (let ( ) + sh(strcat("perl -pi.bak -e 's//\\]/g; s/\\[/\\\\[/g; s/\\]/\\\\]/g; ' " defFile)) + ) +) + +(defun postICCDefVia ( defFile ) + (let ( ) + sh(strcat("perl -pi.bak -e 's/M10_M9/VIA910_1cut/g; s/M9_M8/VIA89_1cut/g; s/M8_M7/VIA78_LONG_H/g; s/M7_M6/VIA67_LONG_H/g; s/M6_M5/VIA56_LONG_H/g; s/M5_M4/VIA45_LONG_H/g; s/M4_M3/VIA34_LONG_H/g; s/M3_M2/VIA23_LONG_H/g; s/M2_M1/VIA12_LONG_H/g; ' " defFile)) + ) +) + +(defun postICCDefCus ( defFile cellName ) + (let ( ) + + case( cellName + ( "chip__rrc__port__mgmt__PORTS_MGMT__1000" + sh(strcat("perl -pi.bak -e 's/pad2pm\\\\\\[0\\\\\\]/pad2pm\\\\\\[eth_refclk\\\\\\]/g; ' " defFile)) + ) + ( "chip__rrc__mgmt__MGMT__1000" + sh(strcat("perl -pi.bak -e 's/pad2lsm\\\\\\[0\\\\\\]/pad2lsm\\\\\\[pcie_refclk\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/pad2lsm\\\\\\[1\\\\\\]/pad2lsm\\\\\\[ieee1588_refclk\\\\\\]/g; ' " defFile)) + ) + ( "pep" + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[0\\\\\\]/i_systime\\\\\\[clock1\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[1\\\\\\]/i_systime\\\\\\[clock0\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[2\\\\\\]/i_systime\\\\\\[plus1\\\\\\]/g; ' " defFile)) + sh(strcat("perl -pi.bak -e 's/i_systime\\\\\\[3\\\\\\]/i_systime\\\\\\[minus1\\\\\\]/g; ' " defFile)) + ) + ( t t ) + ) + ) +) + + +(defun postDef ( defFile cellName ) + (let ( ) + postICCDef( defFile ) + postICCDefVia( defFile ) + postICCDefCus( defFile cellName ) + ) +) + +(defun readICCDef ( cellName ) + (let ( defFile temp_dir + libName libLoc + dfIILoc + viewName delCV newCV s PinLabel + ) + + println(cellName) + defFile = nth(0 defLocation(cellName)) + libLoc = nth(1 defLocation(cellName)) + dfIILoc = nth(2 defLocation(cellName)) + temp_dir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ; strcat(root_dir "temp/") + temp_def = strcat(temp_dir "/" cellName ".def") + println(strcat("cp " defFile " " temp_dir)) + sh(strcat("cp " defFile " " temp_dir)) + sh(strcat("chmod +w " temp_def)) + preICCDefCus(temp_def cellName) + preICCDef(temp_def) + preICCDefVia(temp_def) + + delCV=ddGetObj("scratch.icc_imports" cellName "import") + when( delCV!=nil ddDeleteObj(delCV)) + + status = (ldtrDefReadOA + temp_def ; t_fileName + "scratch.icc_imports" ; t_libName + (getShellEnvVar "DFII_DIR") ; [t_libPath libPath] + cellName ; [t_cellName cellName] + "import" ; [t_viewName viewName] + "tsmc28" ; [t_techName techName] + "floorplan abstract" ; [t_viewNameList viewNameList] + DefLibList ; [t_masterLibs masterLibs] + nil ; [ shared nil] + nil ; [ noRouting nil] + (strcat temp_def ".log") ; [ t_logName logName] + nil ; [ useCustomVias nil] + t ; [ overwrite nil] + nil ; [ createModHier nil] + ; [ t_commentChar commentChar] + ; [ t_templateFileName templateFileName] + ) + + when(status + delCV = nrOpenCellViewWritable("scratch.icc_imports" cellName "import") + foreach(s delCV~>shapes when(s~>theLabel dbDeleteObject(s))) + foreach(s delCV~>shapes when(s~>net~>name PinLabel=MidPinsCreateLabel(delCV s) PinLabel~>parent=s)) + dbSave(delCV) + fp_dir = strcat(dfIILoc "/floorplan/") + P4File(strcat(fp_dir "layout.oa" ) "edit") + P4File(strcat(fp_dir "master.tag" ) "edit") + P4File(strcat(fp_dir "thumbnail_128x128.png" ) "edit") + P4File(strcat(fp_dir "layout.oa" ) "lock") + P4File(strcat(fp_dir "master.tag" ) "lock") + P4File(strcat(fp_dir "thumbnail_128x128.png" ) "lock") + newCV = dbCopyCellView(delCV libLoc cellName "floorplan" nil nil t) + dbClose(delCV) + dbClose(newCV) + ) + + ) +) + +(defun P4AprCell ( @key (CV (geGetEditCellView)) + (CMD "edit" ) + ) + +(let ( + dfIILoc cellName + fp_dir +) + + cellName = CV->cellName + dfIILoc = nth(2 defLocation(cellName)) + fp_dir = strcat(dfIILoc "/floorplan/") + P4File(strcat(fp_dir "layout.oa" ) CMD) + P4File(strcat(fp_dir "master.tag" ) CMD) + P4File(strcat(fp_dir "thumbnail_128x128.png" ) CMD) + + when(CMD == "edit" + P4File(strcat(fp_dir "layout.oa" ) "lock") + P4File(strcat(fp_dir "master.tag" ) "lock") + P4File(strcat(fp_dir "thumbnail_128x128.png" ) "lock") + ) + + ) +) + +(defun P4Cell ( @key (CV (geGetEditCellView)) + (CMD "edit" ) + ) + +(let ( + dfIILoc cellName + fp_dir p4_fp_dir +) + + cellName = CV->cellName + dfIILoc = ( ConfigFileGetValue TheCDSConfigTable "DFII_DIR" ) + fp_dir = NameGetViewDirFromDFIIDirAndCellNameAndView( dfIILoc cellName CV~>viewName ) + p4_fp_dir = buildString( parseString(fp_dir "#") "%23") + P4File(strcat(p4_fp_dir "/layout.oa" ) CMD) + P4File(strcat(p4_fp_dir "/master.tag" ) CMD) + P4File(strcat(p4_fp_dir "/thumbnail_128x128.png" ) CMD) + + when(CMD == "edit" + P4File(strcat(p4_fp_dir "/layout.oa" ) "lock") + P4File(strcat(p4_fp_dir "/master.tag" ) "lock") + P4File(strcat(p4_fp_dir "/thumbnail_128x128.png" ) "lock") + ) + + ) +) + +(defun recursePinLabels ( memList ) + (let ( + infl currCV s + mem memName + ) + + inFl = infile(memList) + + while( gets(mem inFl) + memName = car(parseString(mem "\n")) + printf("%s\n" memName) + currCV = nrOpenCellViewWritable("vendor.avago.abstracts" memName "abstract") + when(currCV + foreach(s currCV~>shapes when(s~>theLabel dbDeleteObject(s))) + foreach(s currCV~>shapes when(s~>net~>name MidPinsCreateLabel(currCV s))) + dbSave(currCV) + dbClose(currCV) + ) + ) + + ) +) + +(defun aprDefRefresh () + (let ( apr ) + foreach(apr APRList readICCDef(apr)) +) +) + +(defun P4File (filename action) + (let (cmd) + if( action != "submit" + then + sprintf(cmd "p4 -c %s %s %s" + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + action + filename + ) + else + sprintf(cmd "p4 -c %s %s -d %s %s" + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + action + "\"Automated cable spec check-in.\"" + filename + ) + ) + + println(cmd) + shell(cmd) +t + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/lefdef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/lefdef.il new file mode 100644 index 0000000000..a642f00990 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/lefdef/lefdef.il @@ -0,0 +1,1140 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; lefdef package + +; globals + +defNxWarn=0 +defNxErr=0 + +(defvar powerNet list( "VDD" "VDDS" "VDDF" "Vdd" "AVDD" )) +(defvar groundNet list( "GND" "VSS" "AGND" )) + +;********************************************************************** +; sub functions +;********************************************************************** +defun( defnWarn ( nwarn ) + if(nwarn < 0 then + defNxWarn=0 + else + defNxWarn = defNxWarn + nwarn + ) + defNxWarn +) + +defun( defnErr ( nerr ) + if(nerr < 0 then + defNxErr=0 + else + defNxErr = defNxErr + nerr + ) + defNxErr +) + +; defPoint2String function will print out a point with format of "( x y )". +defun( defPoint2String ( point units ) + sprintf( nil "( %.0f %.0f )" car(point)*units cadr(point)*units ) +) +defun( defRectArea ( rect ) + let((point1 point2 x1 x2 y1 y2) + point1=car(rect) + point2=cadr(rect) + x1=car(point1) y1=cadr(point1) x2=car(point2) y2=cadr(point2) + abs((x2-x1)*(y2-y1)) + ) +) + +defun( defGenerateC2VTable ( cellName ignoreNetlist ) + let( ( map mapfile tempdir Command ) + map = nil + tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + mapfile = strcat( tempdir "/" cellName ".mapping.il" ) + Command=sprintf( nil + "cast2skill --cadence-name --cast-path=%s --cell=%s --output-dir=%s --cadence-name --root-only --max-heap-size=%dM --64" + ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) + cellName + tempdir + ( nrGetMaxHeapSize ) + ) + if( ignoreNetlist then + Command = strcat( Command " --ignore-netlist" ) ) + if( ! isFile( mapfile ) then + ( shell Command ) ) + if( isFile( mapfile ) then + load( mapfile ) + map = PinCastToVerilogTable() ) + map ) +) + +defun( defGenerateP2DTable ( cellName ignoreNetlist ) + let( ( map mapfile tempdir Command ) + map = nil + tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + mapfile = strcat( tempdir "/" cellName ".pindirection.il" ) + Command=sprintf( nil + "cast2skill --cadence-name --cast-path=%s --cell=%s --output-dir=%s --cadence-name --root-only --max-heap-size=%dM --64" + ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) + cellName + tempdir + ( nrGetMaxHeapSize ) + ) + if( ignoreNetlist then + Command = strcat( Command " --ignore-netlist" ) ) + if( ! isFile( mapfile ) then + ( shell Command ) ) + if( isFile( mapfile ) then + load( mapfile ) + map = PinDirectionTable() ) + map ) +) + +defun( lefPath2String ( path ) + returnString="" + width=path~>width + beginExt=path~>beginExt-width/2 + endExt=path~>endExt-width/2 + points=listToVector(path~>points) + for( i 0 length(points)-2 + x1=car(points[i]) + y1=cadr(points[i]) + x2=car(points[i+1]) + y2=cadr(points[i+1]) + if((i==0) then + cond( + ((x1==x2 && y1>y2) y1=y1+beginExt) + ((x1==x2 && y1x2) x1=x1+beginExt) + ((y1==y2 && x1y2) y2=y2-endExt) + ((x1==x2 && y1x2) x2=x2-endExt) + ((y1==y2 && x1y2) temp=y2 y2=y1 y1=temp) + ((y1==y2 && x1>x2) temp=x2 x2=x1 x1=temp) + ((x1!=x2 && y1!=y2) printf("Error: none straight path:") println(path)) + ) + returnString=sprintf(nil "%s RECT %.3f %.3f %.3f %.3f ;\n" + returnString + x1-width/2 y1-width/2 + x2+width/2 y2+width/2 + ) + ) + returnString +) + +defun( lefRect2String ( fig ) + sprintf(nil " RECT %.3f %.3f %.3f %.3f ;\n" + caar(fig~>bBox) cadar(fig~>bBox) + caadr(fig~>bBox) cadadr(fig~>bBox) + ) +) + +defun( lefPolygon2String ( fig ) + points=listToVector(fig~>points) + if((length(points)==4) then + x0=car(points[0]) y0=cadr(points[0]) + x1=car(points[1]) y1=cadr(points[1]) + x2=car(points[2]) y2=cadr(points[2]) + x3=car(points[3]) y3=cadr(points[3]) + ) + if((length(points)==4 && x0==x1 && x2==x3 && y1==y2 && y3==y0) || + (length(points)==4 && x1==x2 && x3==x0 && y0==y1 && y2==y3) then + returnString=sprintf( nil " RECT %.3f %.3f %.3f %.3f ;\n" + min(x0 x2) min(y0 y2) max(x0 x2) max(y0 y2)) + else + returnString=" POLYGON " + foreach( point fig~>points + returnString=sprintf( nil "%s %.3f %.3f" returnString car(point) cadr(point)) + ) + returnString=sprintf( nil "%s ;\n" returnString) + ) + returnString +) + +defun( lefFig2String ( pout figs layerName ) + thisFigs=setof( fig figs + (layerName==nil || fig~>layerName==layerName) && + fig~>objType!="label" ) + if((thisFigs!=nil) then + foreach( fig thisFigs + fprintf( pout " LAYER %s ;\n" fig~>layerName) + cond( + ((fig~>objType == "path" || fig~>objType == "pathSeg") + fprintf( pout "%s" lefPath2String(fig)) + shapes=setof( shape shapes shape!=fig) + ) + ((fig~>objType == "rect") + fprintf( pout "%s" lefRect2String(fig)) + shapes=setof( shape shapes shape!=fig) + ) + ((fig~>objType == "polygon") + fprintf( pout "%s" lefPolygon2String(fig)) + shapes=setof( shape shapes shape!=fig) + ) + ( t + printf( "Error: illegal shape %s\n" fig~>objType) + ) + ) + ) + ) +) + +defun( defShapeToText ( pout shapes transform ) + let((shape point bBox points line) + foreach( shape shapes + if(shape~>objType=="rect" then + if( transform then bBox=nrPointListTransform(shape~>bBox transform) + else bBox=shape~>bBox ) + fprintf( pout " RECT ( %.0f %.0f ) ( %.0f %.0f )\n" + leftEdge(bBox)*1000.0 bottomEdge(bBox)*1000.0 + rightEdge(bBox)*1000.0 topEdge(bBox)*1000.0 ) + ) + if(shape~>objType=="polygon" then + if( transform then points=nrPointListTransform(shape~>points transform) + else points=shape~>points ) + fprintf( pout " POLYGON" ) + foreach( point points + fprintf( pout " ( %.0f %.0f )" car(point)*1000.0 cadr(point)*1000.0 ) + ) + fprintf( pout "\n" ) + ) + ) + t + ) +) + +; report via orientation +(defun defIsRotatedVia (via) + (and via->libName==TechLibName + via->orient!="R0" via->orient!="R180" + via->orient!="MX" via->orient!="MY") + ) + +; rotate a via 90 degrees +(defun defRotateVia (via swapViaTable @key ( warnonly nil)) + (let (pair rest) + pair = (car swapViaTable) + rest = (cdr swapViaTable) + (cond (via->cellName==(car pair)->cellName + via->master=(cadr pair) + via->orient="R0") + (via->cellName==(cadr pair)->cellName + via->master=(car pair) + via->orient="R0") + (rest (defRotateVia via rest ?warnonly warnonly )) + (warnonly (printf "Warning: can't rotate via %s\n" via->cellName) defnWarn(1)) + (t defnErr(1) (error (sprintf nil "ERROR: can't rotate via %s" via->cellName))) + ) + ) + t + ) + +; return master of a via +(defun defViaMaster (name) + (dbOpenCellViewByType TechLibName name "layout" "maskLayout" "r") + ) +; return master of a via +(defun defViaMasterS (name) + (dbOpenCellViewByType TechLibName name "symbolic" "maskLayout" "r") + ) + +; make vias R0 before DEF export +(defun defCanonicalizeVias (CV @key ( warnonly nil ) ) + (let (swapViaTable) + swapViaTable = (list (list (defViaMaster "M2_M1_R0") (defViaMaster "M2_M1_R90")) + (list (defViaMaster "M3_M2_R0") (defViaMaster "M3_M2_R90")) + (list (defViaMaster "M4_M3_R0") (defViaMaster "M4_M3_R90")) + (list (defViaMaster "M5_M4_R0") (defViaMaster "M5_M4_R90")) + (list (defViaMaster "M6_M5_R0") (defViaMaster "M6_M5_R90")) + (list (defViaMaster "M7_M6_R0") (defViaMaster "M7_M6_R90")) + (list (defViaMaster "M2_M1_H") (defViaMaster "M2_M1_V")) + (list (defViaMaster "M3_M2_H") (defViaMaster "M3_M2_V")) + (list (defViaMaster "M4_M3_H") (defViaMaster "M4_M3_V")) + (list (defViaMaster "M5_M4_H") (defViaMaster "M5_M4_V")) + (list (defViaMaster "M6_M5_H") (defViaMaster "M6_M5_V")) + (list (defViaMaster "M7_M6_H") (defViaMaster "M7_M6_V")) + (list (defViaMaster "M2_M1_STACK") (defViaMaster "M2_M1_STACK_R90")) + (list (defViaMaster "M3_M2_STACK") (defViaMaster "M3_M2_STACK_R90")) + (list (defViaMaster "M4_M3_STACK") (defViaMaster "M4_M3_STACK_R90")) + (list (defViaMaster "M5_M4_STACK") (defViaMaster "M5_M4_STACK_R90")) + (list (defViaMaster "M6_M5_STACK") (defViaMaster "M6_M5_STACK_R90")) + (list (defViaMaster "M7_M6_STACK") (defViaMaster "M7_M6_STACK_R90")) + (list (defViaMasterS "3W_M2_M1_STACK") (defViaMasterS "3W_M2_M1_STACK_R90")) + (list (defViaMasterS "3W_M3_M2_STACK") (defViaMasterS "3W_M3_M2_STACK_R90")) + (list (defViaMasterS "3W_M4_M3_STACK") (defViaMasterS "3W_M4_M3_STACK_R90")) + (list (defViaMasterS "3W_M5_M4_STACK") (defViaMasterS "3W_M5_M4_STACK_R90")) + (list (defViaMasterS "3W_M6_M5_STACK") (defViaMasterS "3W_M6_M5_STACK_R90")) + (list (defViaMasterS "3W_M7_M6_STACK") (defViaMasterS "3W_M7_M6_STACK_R90")) + (list (defViaMasterS "RESET_3W3S_M4_M3_H") (defViaMasterS "RESET_3W3S_M4_M3_V")) + (list (defViaMaster "M2_M1_2CUT_H") (defViaMaster "M2_M1_2CUT_V")) + (list (defViaMaster "M3_M2_2CUT_H") (defViaMaster "M3_M2_2CUT_V")) + (list (defViaMaster "M4_M3_2CUT_H") (defViaMaster "M4_M3_2CUT_V")) + (list (defViaMaster "M5_M4_2CUT_H") (defViaMaster "M5_M4_2CUT_V")) + (list (defViaMaster "M6_M5_2CUT_H") (defViaMaster "M6_M5_2CUT_V")) + (list (defViaMaster "M7_M6_2CUT_H") (defViaMaster "M7_M6_2CUT_V"))) + (foreach via (CV->instances) + (cond ((via~>master~>libName == "tsmc65" && via~>prop ) defnWarn(1) printf( "Warning: via %s %s at (%.3f,%.3f) has modified properties, def may be not be valid.\n" via~>baseName via~>master~>cellName car(via~>xy) cadr(via~>xy)))) + (cond ((defIsRotatedVia via) (defRotateVia via swapViaTable ?warnonly warnonly))) + ) + ) + t + ) + +(defun exportClusterRegions (defPort cellView) + let( ( cl cvClusters bnd I rects rect ) + + fprintf(defPort, "REGIONS %d ;\n", length(cellView~>clusters)) + + foreach( cl cellView~>clusters + fprintf(defPort, "- %s ", cl~>name) + foreach( bnd cl~>boundaries + rects = convertPolyObjToRect(bnd) + foreach( rect rects + fprintf(defPort, "( %.0f %.0f ) ( %.0f %.0f ) ", + caar(rect)*UNITS, cadar(rect)*UNITS, + caadr(rect)*UNITS, cadadr(rect)*UNITS) + ) + ) + fprintf(defPort, ";\n") + ) + + fprintf(defPort, "END REGIONS\n\n") + +t + ) +) + +(defun exportPRBoundary (defPort cellView) + let( ( rect rects I pr ) + fprintf(defPort, "DIEAREA ") + rects = convertPolyObjToRect(cellView~>prBoundary) + pr = cellView~>prBoundary + for( I 0 length(pr~>points)-1 + when( nth(I pr~>points) + fprintf(defPort, "( %.0f %.0f ) ", car(nth(I pr~>points))*UNITS, cadr(nth(I pr~>points))*UNITS) + ) + ) + fprintf(defPort, ";\n\n") +t + ) +) + +(defun exportPlacementBlockages (defPort cellView) + let( ( blk pBlockage ) + I = 0 + pBlockage = setof(blk cellView~>blockages blk~>type=="placement") + + fprintf( pout "BLOCKAGES %d ;\n" length(pBlockage)) + when( pBlockage + fprintf( pout "- PLACEMENT \n") + ) + foreach( blk pBlockage + I = I+1 + if( blk~>nPoints == 4 + then + fprintf(defPort, " RECT ( %.0f %.0f ) ( %.0f %.0f ) ", + caar(blk~>bBox)*UNITS, cadar(blk~>bBox)*UNITS, + caadr(blk~>bBox)*UNITS, cadadr(blk~>bBox)*UNITS) + else + println("WARNING: POLYGON BLOCKAGES are not supported in DEF !!!!") +; fprintf(defPort, " POLYGON ") +; for( I 0 length(blk~>points)-1 +; when( nth(I blk~>points) +; fprintf(defPort, "( %.0f %.0f ) ", car(nth(I blk~>points))*UNITS, cadr(nth(I blk~>points))*UNITS) +; ) +; ) + ) + if( I == length(pBlockage) + then + fprintf(defPort, "; \n") + else + fprintf(defPort, "\n") + ) + ) + fprintf( pout "END BLOCKAGES\n\n" length(pBlockage)) +t + ) +) + +(defun exportRoutingBlockages (defPort cellView) + let( ( blk pBlockage ) + I = 0 + pBlockage = setof(blk cellView~>blockages blk~>type=="routing") + + fprintf( pout "BLOCKAGES %d ;\n" length(pBlockage)) + foreach( blk pBlockage + I = I+1 + if( blk~>nPoints == 4 + then +; when( blk~>BlockSignalRouting + fprintf( pout " - LAYER %s \n" blk~>layer) + fprintf(defPort, " RECT ( %.0f %.0f ) ( %.0f %.0f ) ; \n", + caar(blk~>bBox)*UNITS, cadar(blk~>bBox)*UNITS, + caadr(blk~>bBox)*UNITS, cadadr(blk~>bBox)*UNITS) +; ) + fprintf( pout " - LAYER %s + PUSHDOWN \n" blk~>layer) + fprintf(defPort, " RECT ( %.0f %.0f ) ( %.0f %.0f ) ; \n", + caar(blk~>bBox)*UNITS, cadar(blk~>bBox)*UNITS, + caadr(blk~>bBox)*UNITS, cadadr(blk~>bBox)*UNITS) + else + println("WARNING: POLYGON BLOCKAGES are not supported in DEF !!!!") + ) + ) + fprintf( pout "END BLOCKAGES\n\n" length(pBlockage)) +t + ) +) + +(defun convertPolyObjToRect ( obj ) + let( ( sct rects newlist rect ) + sct = dbCreatePolygon(obj~>cellView "y4" obj~>points) + rects = dbLayerTile(obj~>cellView "y5" list(sct)) + newlist = rects~>bBox + dbDeleteObject(sct) + foreach(rect rects dbDeleteObject(rect)) + newlist + ) +) + +;********************************************************************** +; main lef functions +;********************************************************************** + + +defun( lefInstanceOut ( pout libName cellName viewName + @key + ( Verbose nil ) + ) + +let( (( cellView dbOpenCellViewByType( libName cellName viewName ))) + printf("generating lef macro for %s %s (%s).\n" libName cellName viewName) + fprintf( pout "MACRO %s\n" cellView~>cellName ) + fprintf( pout " CLASS CORE ;\n" ) + + bBox=cellView->prBoundary->bBox + + x1=caar(bBox) + y1=cadar(bBox) + x2=caadr(bBox) + y2=cadadr(bBox) + + fprintf( pout " FOREIGN %s %.3f %.3f ;\n" cellView~>cellName x1 y1 ) + fprintf( pout " ORIGIN %.3f %.3f ;\n" -x1 -y1 ) + fprintf( pout " SIZE %.3f BY %.3f ;\n" x2-x1 y2-y1) + fprintf( pout " SYMMETRY X Y R90 ;\n" ) + fprintf( pout " SITE CoreSite ;\n" ) + + pins=cellView~>terminals + nets=cellView~>nets + shapes=cellView~>shapes + pinShapes=nil + + foreach( pin pins + fprintf( pout " PIN %s\n" pin~>name) + direction=upperCase(pin~>direction) + if((direction!="INPUT" && direction!="OUTPUT") direction="INOUT") + fprintf( pout " DIRECTION %s ;\n" direction) + (cond (pin~>name=="Vdd" (fprintf pout " USE power ;\n")) + (pin~>name=="GND" (fprintf pout " USE ground ; \n")) + ) + thisFigs= setof( fig shapes fig~>net~>name==pin~>net~>name) + fprintf( pout " PORT\n" ) + if( thisFigs==nil then + printf("Error: no fig for pin %s.\n" pin~>name) + else + lefFig2String( pout thisFigs nil) + pinShapes=append( pinShapes thisFigs ) + ) + fprintf( pout " END\n" ) + fprintf( pout " END %s\n" pin~>name) + ) + fprintf( pout " OBS\n" ) + obsShapes=setof( shape shapes !member( shape pinShapes ) && member( shape~>lpp MetalLPPs)) + foreach( lpp MetalLPPs lefFig2String( pout shapes car(lpp))) + fprintf( pout " END\n" ) + fprintf( pout "END %s\n\n" cellView~>cellName) +) +) + +;********************************************************************** +; main lef function: lefLefOut +;********************************************************************** + +defun( lefLefOut ( libName cellName viewName + outfileName + @key + ( Verbose nil ) + ( Overwrite t ) + ) + + prog( (cellView) + cellView=nrOpenCellViewReadable( libName cellName viewName ) + if( cellView==nil then + printf("Error: Can not open cellview %s\n" inst~>cellName) + return(nil) + ) + instances= setof( thisInst cellView~>instances + thisInst~>viewName!="symbolic"&& + thisInst~>libName!=TechLibName) + + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances=cons( inst uniqueInstances ) + ) + ) + abstract_missing=nil + foreach( inst uniqueInstances + if( nrOpenCellViewReadable( inst~>libName inst~>cellName "abstract" ) == nil then + abstract_missing=cons( inst~>cellName abstract_missing ) + printf("Error: Missing Abstract view %s\n" inst~>cellName) + ) + ) + if( abstract_missing then return(nil)) + if( Overwrite==nil then + p_in=infile(outfileName) + if( p_in then + close(p_in) + printf("Not Overwrite Existing Lef File: %s\n" outfileName) + return(nil) + ) + ) + pout=outfile(outfileName) + foreach( inst uniqueInstances + lefInstanceOut( pout inst~>libName inst~>cellName "abstract" + ?Verbose Verbose) + ) + fprintf( pout "END LIBRARY\n") + close(pout) + printf( "Successfully created LEF file: %s\n" outfileName ) + return(t) + ) +) + +defun( vendorBase ( cellName ) + let( ( baseName ) + baseName = cellName + if( rexMatchp( "^vendor\\." baseName ) then + rexCompile( "\\.[0-9]*$" ) + baseName = rexReplace( baseName "" 0 ) + rexCompile( "^.*\\." ) + baseName = rexReplace( baseName "" 0 ) + ) + baseName + ) +) + +;********************************************************************** +; main def function: defDefOut +;********************************************************************** + +defun( defDefOut ( libName cellName viewName + outfileName + @key + ( Verbose nil ) + ( DIVIDERCHAR "|" ) + ( BUSBITCHARS "<>" ) + ( UNITS 1000.0 ) + ( OutputNets t ) + ( OutputPins t ) + ( AllSpecialNets t ) + ( PowerPins t ) + ( transform nil ) + ( UseModuleName nil ) + ( Synchronous nil ) + ( PinMap nil ) + ( DirMap nil ) + ( BlockageCellView nil ) ;BlockageCellView is PowerGridCellView since our placement and routing blockages are in PowerGrid Cell + ( Warnonly nil ) + ( DialogBox t ) ; pop up dialog box on warnings or errors + ) + let( (pin_nocast pin_nodef pout pinserr + cellView cellView1 foundTieOffCell instances prelayouts + dieArea dieAreaXY1 dieAreaXY2 powerStr pathSegs + specialNets sourceDist temp macroType + ) + defnErr(-1) ; reset error count + defnWarn(-1) ; reset warning count + pin_nocast=0 + pin_nodef=0 + prelayouts=nil + + printf("generating def for %s %s (%s).\n" libName cellName viewName) + cellView=dbOpenCellViewByType( libName cellName viewName ) + cellView1=nil + foundTieOffCell=nil + noRotateCellnames=list( "M2_M1" "M2_M1min" + "M3_M2" "M3_M2min" + "M4_M3" "M4_M3min" + "M5_M4" "M5_M4min" + "M6_M5" "M6_M5min" + "M7_M6" "M7_M6min" + ) + if( transform then + cellView1=dbCopyCellView( cellView cellView~>libName cellView~>cellName strcat(cellView~>viewName "_" cadr(transform))) + foreach( fig cellView1~>shapes + dbMoveFig( fig cellView1 transform) + ) + foreach( prbobj list(cellView1~>prBoundary) + dbMoveFig( prbobj cellView1 transform) + ) + foreach( blockages cellView1~>blockages + dbMoveFig( blockages cellView1 transform) + ) + foreach( inst cellView1~>instances + if( member( inst~>cellName noRotateCellnames ) then + dbMoveFig( inst cellView1 list(car(transform) "R0" 1.0)) + else + dbMoveFig( inst cellView1 transform) + ) + ) + DeleteLabels(?CV cellView1) + defCanonicalizeVias( cellView1 ?warnonly Warnonly ) + dbSave(cellView1) + cellView=cellView1 + ) + + pout = outfile(outfileName) + if((pout == nil) then + defnErr(1) + error( sprintf( nil "Error: can not open %s for write.\n" outfileName)) + ) + + ; HEADER + fprintf( pout "# INTEL TOP SECRET\n" ) + fprintf( pout "# Copyright 2012 Intel Corporation. All Rights Reserved.\n" ) + fprintf( pout "#\n" ) + fprintf( pout "# created by Fulcrum defOut program on %s.\n" getCurrentTime() ) + fprintf( pout "# LIBRARY : %s\n" cellView~>libName ) + fprintf( pout "# CELLNAME : %s\n" cellView~>cellName ) + fprintf( pout "# VIEWNAME : %s\n" cellView~>viewName ) + if( transform then + fprintf( pout "# transform : %L\n" transform ) + ) + fprintf( pout "#\n" ) + if(Synchronous then fprintf( pout "VERSION 5.6 ;\n") else fprintf( pout "VERSION 5.5 ;\n")) + fprintf( pout "NAMESCASESENSITIVE ON ;\n") + fprintf( pout "DIVIDERCHAR \"%s\" ;\n" DIVIDERCHAR ) + fprintf( pout "BUSBITCHARS \"%s\" ;\n" BUSBITCHARS ) + fprintf( pout "DESIGN %s ;\n" if( UseModuleName then + cadr( reverse( parseString( cellView~>cellName "." ))) + else cellView~>cellName )) + fprintf( pout "TECHNOLOGY %s ;\n" TechLibName) + fprintf( pout "UNITS DISTANCE MICRONS %.0f ;\n" UNITS ) + + ; The DIEAREA is computed to enclose everything and be powergrid-aligned + dieArea=cellView~>prBoundary~>bBox + if( dieArea==nil then dieArea=cellView~>bBox ) +; dieArea = BBoxSnapOutwardToGrid(cellView~>bBox GridPitch) + dieAreaXY1 = car(dieArea) + dieAreaXY2 = cadr(dieArea) + +if(!Synchronous + then + fprintf( pout "\n" ) + fprintf( pout "DIEAREA ( %.0f %.0f ) ( %.0f %.0f ) ;\n" + car(dieAreaXY1)*UNITS + cadr(dieAreaXY1)*UNITS + car(dieAreaXY2)*UNITS + cadr(dieAreaXY2)*UNITS ) + fprintf( pout "\n" ) + else + exportPRBoundary(pout cellView) + exportClusterRegions(pout cellView) + ) + ; COMPONENTS + printf("generating COMPONENTS...\n") + instances= setof( thisInst cellView~>instances + thisInst~>viewName!="symbolic"&& + thisInst~>libName!=TechLibName) + fprintf( pout "COMPONENTS %d ;\n" length(instances) ) + foreach( inst instances + + if( inst~>status == "firm" + then + macroType = "FIXED" + else + macroType = "PLACED" + ) + + thisOrient=setof( orient ORIENTLIST car(orient)==inst~>orient ) + orientFunction=lambda((point) point) + if((thisOrient!=nil) then + thisOrient=car(thisOrient) + orientFunction=caddr(thisOrient) + thisOrient=cadr(thisOrient) + else printf( "Warning: instance %s (%s) has illegal orient. Use \"N\" instead.\n" + inst~>name inst~>cellName ) + thisOrient="N" + ) + + when( inst->viewName=="prelayout" + prelayouts=t + ) + + ; instance position is defined as lower_left corner of instance + ; prBoundary layer in the cellView. So it is not exactly inst~>xy. + ; In our cases, often lower_left corner of prBoundary is (0 -0.48), + ; so the instance position should be inst~>xy+(0 -0.48). + + unless( IsGuideInst(inst) ; don't export bus script guides + instMaster=nrOpenCellViewReadable( inst~>libName inst~>cellName "abstract_edit") + if( instMaster==nil then instMaster=nrOpenCellViewReadable( inst~>libName inst~>cellName "abstract")) + if( instMaster==nil then + printf("Error: abstract view of %s does not exist!\n" inst~>cellName) + instMaster=nrOpenCellViewReadable( inst~>libName inst~>cellName inst~>viewName) + ) + prBound=setof( lpp instMaster~>lpps lpp~>layerName=="prBoundary" ) + if(instMaster->prBoundary || (prBound !=nil) then + prBoundBox=nil + if( prBound then + foreach( thisLayer prBound + foreach( shape thisLayer~>shapes + if((shape~>objType!="label" && prBoundBox==nil) then + prBoundBox=shape~>bBox + ) + ) + ) + else + if( instMaster->prBoundary then + prBoundBox=instMaster->prBoundary->bBox) + ) + if((prBoundBox!=nil && inst~>xy!=nil) then + let((point1 point2 x y w1 h1 w2 h2) + point1=car(prBoundBox) + point2=cadr(prBoundBox) + w1=car(point2)-car(point1) + h1=cadr(point2)-cadr(point1) + point1=apply( orientFunction list(point1)) + point2=apply( orientFunction list(point2)) + x=min( car(point1) car(point2))+ car(inst~>xy) + y=min(cadr(point1) cadr(point2))+cadr(inst~>xy) + xy=list(x y) + w2=caadr(instMaster~>bBox)-caar(instMaster~>bBox) + h2=cadadr(instMaster~>bBox)-cadar(instMaster~>bBox) + ) + else + xy=car(inst~>bBox) + printf("Warning: %s (%s) does not have rectangle prBoundary. Use bBox instead.\n" + inst~>name inst~>cellName) + ) + else + xy=car(inst~>bBox) + printf("Warning: %s (%s) does not have prBoundary layer. Use bBox instead.\n" + inst~>name inst~>cellName) + + ) + + instName=inst~>name + if( Synchronous then + new=instName + if(rexCompile( "\\." ) + instName = rexReplace( new "/" 0 ) ) ) + ; If wiring cell, set SOURCE DIST flag as it is a physical component + if( cadr(NameFilterInstances( list(inst) WiringCellLibCellPairRegExs)) then + sourceDist=" + SOURCE DIST" + else + sourceDist="" + ) + + ; NOTE: all vendor cells have the FQCN converted to the BASE name! (bug 15615) + temp=sprintf( nil "- %s %s%s + %s %s %s ;\n" + instName vendorBase(inst~>cellName) sourceDist macroType defPoint2String(xy UNITS) + thisOrient ) + if( Verbose printf( "%s" temp ) ) + fprintf( pout "%s" temp ) + ) + ) + fprintf( pout "END COMPONENTS\n\n") + + ; PINS + pinShapes = makeTable( "pinShapes" nil) ; track which shapes are PINS + if( OutputPins then + pinserr=outfile("DEFpins.err") + printf("generating PINS...\n") + pins= cellView~>terminals + if( !PowerPins then pins=setof( pin pins pin~>name!="Vdd" && pin~>name!="GND")) + fprintf( pout "PINS %d ;\n" length(pins) ) + if( DirMap then + ValidPins=(let ( + ( NewTable ( makeTable `bla ( arrayref DirMap `unbound ) ) ) ) + ( foreach Key DirMap + ( setarray NewTable Key 0 ) ) + NewTable ) ) + foreach( pin pins + direction=upperCase(pin~>direction) + if((direction=="INPUTOUTPUT") then direction="INOUT") + if((direction!="INPUT" && direction!="OUTPUT" && direction!="INOUT" ) then + printf("Warning: illegal pin direction \"%s\" found at pin %s. Set it to \"INOUT\".\n" + direction pin~>name) + direction="INOUT" + ) + if( DirMap then + let( ( dir ) + dir = arrayref( DirMap pin~>name ) + if( dir then + direction = dir + if((pin~>pinCount > 0) then + ( setarray ValidPins pin~>name 1 ) ) + else + fprintf( pinserr "Error: pin %s is not in cast\n" pin~>name ) + pin_nocast=pin_nocast+1 + defnErr(1) + ) + ) + ) + if((pin~>pinCount == 0) then + fprintf( pout "- %s + NET %s + DIRECTION %s \n ;\n" + pin~>name pin~>net~>name direction ) + fprintf( pinserr "Warning: pin %s has no shapes associated to it.\n" + pin~>name) + defnWarn(1) + else + pinName=pin~>name + pinNetName=pin~>net~>name + if( PinMap then + (let ( vlg ) + vlg = arrayref( PinMap pin~>name ) + if( vlg != nil then + pinName = vlg + ) + vlg = arrayref( PinMap pin~>net~>name ) + if( vlg != nil then + pinNetName = vlg + ) + ) + ) + thisPinName=pinName + pinCount=0 + pinFigs=pin~>pins~>fig + foreach( pinFig pinFigs + cond( + ((pinFig~>objType=="rect" || ((pinFig~>objType=="path" || pinFig~>objType=="pathSeg" ) && pinFig~>nPoints==2)) + pinbBox=pinFig~>bBox + pinx1=caar(pinbBox) + piny1=cadar(pinbBox) + pinx2=caadr(pinbBox) + piny2=cadadr(pinbBox) + pinxc=floor((pinx1+pinx2)/2) + pinyc=floor((piny1+piny2)/2) + fprintf( pout "- %s + NET %s + DIRECTION %s " + thisPinName pinNetName direction ) + when( pin~>name=="GND" + fprintf( pout "+ USE GROUND " )) + when( pin~>name=="Vdd" + fprintf( pout "+ USE POWER " )) + fprintf( pout "+ LAYER %s %s %s " + pinFig~>layerName defPoint2String( list(pinx1-pinxc piny1-pinyc) UNITS) + defPoint2String( list(pinx2-pinxc piny2-pinyc) UNITS) ) + fprintf( pout "+ FIXED %s N ;\n" + defPoint2String( list(pinxc pinyc) UNITS) ) + pinShapes[pinFig]=t + ) + ( t printf( "Error: non rect pin fig found at pin %s.\n" pinName ) + ) + ) + pinCount=pinCount+1 + thisPinName=sprintf( nil "%s.extra%d" pinName pinCount ) + ) + ) + ) + if( DirMap then + ( foreach Key ValidPins + if( arrayref( ValidPins Key )==0 then + fprintf( pinserr "Warning: Cast Pin %s Not in DEF\n" Key ) + pin_nodef=pin_nodef+1 + defnWarn(1) + ) ) ) + fprintf( pout "END PINS\n\n") + ) + + ; NETS + if( OutputNets then + printf("generating NETS...\n") + + when( GetPathsForNet(nil) + printf("\n!!!-------------------------------------------------------\n") + printf("Paths found with no connectivity.\n") + printf("These will not be represented in DEF.\n") + printf("VirtuosoXL removes connectivity from floating wires,\n") + printf(" so be sure to close it and redraw wires before export.\n") + printf("----------------------------------------------------------\n") + defnErr(1) + ) + + FullViaWidth=(ContactExtension *2 + ContactCutWidth)*MicronsPerMeter + + specialNets=nil + + nets= cellView~>nets + if( !PowerPins then nets=setof( net nets net~>name!="Vdd" && net~>name!="GND")) + fprintf( pout "NETS %d ;\n" length(nets) ) + foreach( net nets + netName = net~>name + netTermName = net~>term~>name + if( PinMap then + (let ( vlg ) + vlg = arrayref( PinMap net~>name ) + if( vlg != nil then + netName = vlg + ) + ) + if( netTermName then + (let ( vlg ) + vlg = arrayref( PinMap net~>term~>name ) + if( vlg != nil then + netTermName = vlg + ) + ) + ) + ) + fprintf( pout "- %s\n" netName) + powerStr = "" + when(Synchronous + when( member(netName powerNet) powerStr = "+ USE POWER " fprintf( pout "+ USE POWER\n" ) ) + when( member(netName groundNet) powerStr = "+ USE GROUND" fprintf( pout "+ USE GROUND\n" ) ) + ) + + specialNetString=sprintf( nil "- %s %s\n" netName powerStr) + + if( Verbose printf( "- %s\n" netName)) + + if((net~>term!=nil) then + fprintf( pout " ( PIN %s )\n" netTermName) + ) + viaInstances=setof( instTerm net~>allInstTerms instTerm~>inst~>viewName=="symbolic" || + instTerm~>inst~>libName==TechLibName) + realInstances=setof( instTerm net~>allInstTerms instTerm~>inst~>viewName!="symbolic" && + instTerm~>inst~>libName!=TechLibName) + foreach( instTerm realInstances + fprintf( pout " ( %s %s )\n" instTerm~>inst~>name instTerm~>name) + ) + figs=append( net~>term~>pins~>fig net~>figs ) + + vias=append( setof( fig figs fig~>objType=="inst" || fig~>objType=="stdVia") viaInstances~>inst) + paths=setof( fig figs fig~>objType=="path" ) + pathSegs=setof( fig figs fig~>objType=="pathSeg" ) + rects=setof( fig figs fig~>objType=="rect" || (fig~>objType=="polygon" && fig~>nPoints<=5) ) + polys=setof( fig figs fig~>objType=="polygon" && fig~>nPoints>5 ) + others=setof( fig figs fig~>objType!="inst" && fig~>objType!="stdVia" && fig~>objType!="path" && fig~>objType!="pathSeg" && fig~>objType!="rect" && fig~>objType!="polygon" && fig~>objType!="route" && fig~>objType!="steiner") + + rects=setof( rect rects defRectArea(rect~>bBox)>FullViaWidth*FullViaWidth*1.01 || rect~>purpose=="pin") + polys=setof( poly polys defRectArea(poly~>bBox)>FullViaWidth*FullViaWidth*1.01 || poly~>purpose=="pin") + + rects=setof( rect rects !pinShapes[rect]) + paths=setof( path paths !pinShapes[path]) + pathSegs=setof( path pathSegs !pinShapes[path]) + + if((others!=nil) then + println(others~>??) +; error( sprintf( nil "Error: non path-or-inst net fig found at net %s.\n" +; net~>name )) +; defnErr(1) + ) + + ; convert net shapes to DEF + if( Synchronous + then + ROUTED="+ FIXED" + specialNetROUTED="+ FIXED" + else + ROUTED="+ ROUTED" + specialNetROUTED="+ ROUTED" + ) + ; paths + foreach( path paths + if( !AllSpecialNets then + fprintf( pout " %s %s " ROUTED path~>layerName ) + ROUTED=" NEW" + foreach( point path~>points + fprintf( pout "%s " defPoint2String(point UNITS)) + lastPoint=point + ) + fprintf( pout "\n" ) + else + specialNetString=sprintf( nil "%s %s %s %.0f " specialNetString specialNetROUTED path~>layerName path~>width*UNITS) + specialNetROUTED=" NEW" + foreach( point path~>points + specialNetString=sprintf( nil "%s%s " specialNetString defPoint2String(point UNITS)) + lastPoint=point + ) + specialNetString=sprintf( nil "%s\n" specialNetString ) + ) + ) + + foreach( path pathSegs + if( !AllSpecialNets then + fprintf( pout " %s %s " ROUTED path~>layerName ) + ROUTED=" NEW" + fprintf( pout "%s %s " defPoint2String(path~>beginPt UNITS) defPoint2String(path~>endPt UNITS)) + fprintf( pout "\n" ) + else + specialNetString=sprintf( nil "%s %s %s %.0f " specialNetString specialNetROUTED path~>layerName path~>width*UNITS) + specialNetROUTED=" NEW" + specialNetString=sprintf( nil "%s%s %s " specialNetString defPoint2String(path~>beginPt UNITS) defPoint2String(path~>endPt UNITS)) + specialNetString=sprintf( nil "%s\n" specialNetString ) + ) + ) + + ; rectangles + foreach( rect rects + point1=car(rect~>bBox) + point2=cadr(rect~>bBox) + x1=car(point1) y1=cadr(point1) x2=car(point2) y2=cadr(point2) + length=x2-x1 width=y2-y1 + if((length>width) then + point1=list( x1+width/2 (y1+y2)/2 ) + point2=list( x2-width/2 (y1+y2)/2 ) + else + width=length length=y2-y1 + point1=list( (x1+x2)/2 y1+width/2 ) + point2=list( (x1+x2)/2 y2-width/2 ) + ) + if( !AllSpecialNets then + fprintf( pout " %s %s " ROUTED rect~>layerName ) + ROUTED=" NEW" + fprintf( pout "%s %s " defPoint2String(point1 UNITS) defPoint2String(point2 UNITS)) + lastPoint=point2 + fprintf( pout "\n" ) + else + specialNetString=sprintf( nil "%s %s %s %.0f " specialNetString specialNetROUTED rect~>layerName width*UNITS) + specialNetROUTED=" NEW" + specialNetString=sprintf( nil "%s%s %s " specialNetString defPoint2String(point1 UNITS) defPoint2String(point2 UNITS)) + lastPoint=point2 + specialNetString=sprintf( nil "%s\n" specialNetString ) + ) + ) + + ; vias + if( !AllSpecialNets then + foreach( via vias + thisLpp=setof( lpp VIALPPS rexMatchp(cadr(lpp) via~>viaHeader~>viaDefName) ) + fprintf( pout " %s %s %s %s\n" + ROUTED caar(thisLpp) defPoint2String( via~>xy UNITS) via~>viaHeader~>viaDefName ) + ROUTED=" NEW" + ) + vias=nil + else + foreach( via vias + thisLpp=setof( lpp VIALPPS rexMatchp(cadr(lpp) via~>viaHeader~>viaDefName) ) + specialNetString=sprintf( nil "%s %s %s 0 %s %s\n" specialNetString + specialNetROUTED caar(thisLpp) defPoint2String( via~>xy UNITS) via~>viaHeader~>viaDefName ) + specialNetROUTED=" NEW" + ) + vias=nil + if( Verbose printf("%s" specialNetString)) + specialNets=cons( specialNetString specialNets) + ) + fprintf( pout " ;\n") + ) + fprintf( pout "END NETS\n\n") + if( specialNets then + printf("generating SPECIALNETS...\n") + fprintf( pout "SPECIALNETS %d ;\n" length(specialNets) ) + foreach( line specialNets fprintf( pout "%s ;\n" line) ) + fprintf( pout "END SPECIALNETS\n\n") + ) + + ) + + when(Synchronous exportPlacementBlockages(pout cellView)) + when(Synchronous exportRoutingBlockages(pout cellView)) + + if( BlockageCellView then + ;BlockageCellView is same as PowerGridCellView + blockageNum=0 + overlapShapes=setof( shape BlockageCellView~>shapes shape~>layerName=="OVERLAP") + if( overlapShapes then + blockageNum=blockageNum+1 + ) + foreach( metalLpp MetalLPPs + metalShapes=setof( shape BlockageCellView~>shapes shape~>layerName==car(metalLpp) && shape~>purpose=="boundary") + if( metalShapes then + blockageNum=blockageNum+1 + ) + ) + when(!Synchronous + if( blockageNum>0 then + fprintf( pout "BLOCKAGES %d ;\n" blockageNum) + + if( overlapShapes then + fprintf( pout " - PLACEMENT\n") + defShapeToText( pout overlapShapes transform) + fprintf( pout " ;\n") + ) + foreach( metalLpp MetalLPPs + metalShapes=setof( shape BlockageCellView~>shapes shape~>layerName==car(metalLpp) && shape~>purpose=="boundary") + if( metalShapes then + if( Synchronous + then + fprintf( pout " - LAYER %s + PUSHDOWN\n" car(metalLpp)) + else + fprintf( pout " - LAYER %s\n" car(metalLpp)) + ) + defShapeToText( pout metalShapes transform) + fprintf( pout " ;\n") + ) + ) + fprintf( pout "END BLOCKAGES\n\n") + ) + ) + ) + fprintf( pout "END DESIGN\n") + close(pout) + close(pinserr) + + when(prelayouts + defnWarn(1) + printf("\n!!!-------------------------------------------------------\n") + printf("Warning: Instances found that are \"prelayout\" view. Check flattening.\n") + printf("----------------------------------------------------------\n") + ) + + when(FindBusOverlaps() + defnWarn(1) + printf("\n!!!-------------------------------------------------------\n") + printf("Warning: Pin/wire overlaps found. Look for error markers.\n") + printf("----------------------------------------------------------\n") + ) + + if( pin_nocast > 0 || pin_nodef > 0 then + defnWarn(1) + printf("\n!!!-------------------------------------------------------\n") + printf("Warning: %d DEF pins are not in cast -- %d cast pins are not in DEF.\n + Check DEFpins.err for details.\n\n" pin_nocast pin_nodef ) + printf("----------------------------------------------------------\n") + ) + + if( defnErr(0) > 0 || defnWarn(0) > 0 then + printf("File %s is generated sucessfully with %d error(s) and %d warning(s)\n" outfileName defnErr(0) defnWarn(0)) + else + printf("File %s is generated sucessfully.\n" outfileName) + ) + if( cellView1 then + ddDeleteObj( ddGetObj( cellView1~>libName cellView1~>cellName cellView1~>viewName "")) + ) + if( (boundp 'UIStack ) then + if( (and DialogBox (or defnWarn(0)>0 defnErr(0)>0)) then + lefdefErrorDialog = hiDisplayAppDBox( + ?name 'defDefOutErrorDialogBox + ?dboxText "Errors or Warnings in defOut, check CIW" + ?dboxBanner "Errors/Warnings in defOut" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'Close + ) ) ) + ; return t if no errors + defnErr(0)==0 + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/compact.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/compact.il new file mode 100644 index 0000000000..827981f239 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/compact.il @@ -0,0 +1,268 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +/* +This module contains functions for horizontally compacting floorplan views.
    + +The primary function is .
    + +Compaction just means the instances are moved horizontally so that there is no more room to squeeze around in the x direction.
    + +This is accomplished by moving each floorplan instance to the left until its' boundary box runs into boundary boxes of other cells.
    + +Boundary boxes are the bounding box of the biggest BoundaryLPP (prBoundary/drawing) shape in the cell.
    + +This could be done hierarchically from the bottom up for best results.
    +This is used by .
    +*/ + +(defun MidLevelCompactInstances ( CellView + Instances + BoundaryLPP + XGrid ) + "For each instance, from left to right, move it left until it's BoundaryLPP bbox collides with another. Snap to XGrid." + (let ( + ( SortedInstances + ( sort + Instances + (lambda ( X Y ) + ( lessp ( RectGetLeft ( getq X bBox ) ) + ( RectGetLeft ( getq Y bBox ) ) ) ) ) ) ) + (let ( + ( Groups + ( ListSplitOnPredicate + SortedInstances + (lambda ( X Y ) + ( or + ( not ( equal ( getq X cellName ) + ( getq Y cellName ) ) ) + ( not ( equal ( RectGetLeft ( getq X bBox ) ) + ( RectGetLeft ( getq Y bBox ) ) ) ) ) ) ) ) ) + ( foreach Group Groups + (let ( + ( OffsetX + ( MidLevelGetOffsetX + CellView + Group + BoundaryLPP ) ) ) + ( foreach Instance Group + ;move + ( dbMoveFig + Instance + nil + ( list -OffsetX:0 "R0" ) ) + + ;snap to grid + (when ( greaterp XGrid 0.0 ) + ( dbSetq + Instance + ( list ( times + XGrid + ( ceiling + ( quotient + ( car ( getq Instance xy ) ) + XGrid ) ) ) + ( cadr ( getq Instance xy ) ) ) + xy ) + ) + + + ) ) ) ) ) ) + +(defun MidLeveGetOffendingBBoxes ( BBox Instances Paths BoundaryLPP ) + ( setof + OverlapBBox + ( mapcar + (lambda ( Path ) + (let ( + ( OverlapBBox + ( TransformGetBBoxFromPath + Path ) ) ) + (when ( and + ( not + ( exists Instance Instances + ( equal + ( car Path ) + Instance ) ) ) + ( leqp + ( RectGetLeft ( getq ( car Path ) bBox ) ) + ( RectGetLeft BBox ) + ) + ( exists + Instance + Instances + ( dbProduceOverlap + ( getq Instance master ) + ( dbTransformBBox + ( RectShrinkInX + ( RectShrinkInY + OverlapBBox + .005 ) + .005 ) + ( TransformGetInverseTransform + ( getq Instance transform ) ) ) + ( list 0 32 ) + BoundaryLPP ) + ) ) + OverlapBBox ) ) ) + Paths ) + OverlapBBox + ) ) + + +(defun MidLevelGetLPPs ( CellView + ) + ( ListRemoveDuplicatesNoTableElements + ( append + ( mapcar + (lambda ( LPP ) + ( list ( getq LPP layerName ) + ( getq LPP purpose ) ) ) + CellView->lpps ) + ( ListNonDestructiveMapCan + (lambda ( SubInstance ) + ( MidLevelGetLPPs + SubInstance->master + ) ) + ( getq CellView instances ) ) ) ) ) + + +(defun MidLevelGetBBoxes ( Instance + TheLPP ) + (let ( + ( LPP + ( car ( exists LPP + ( getq ( getq Instance master ) lpps ) + ( and + ( equal LPP->layerName ( car TheLPP ) ) + ( equal LPP->purpose ( cadr TheLPP ) ) ) ) ) ) ) + ( mapcar + (lambda ( BBox ) + ( dbTransformBBox + BBox + ( getq Instance transform ) ) ) + ( append + LPP->shapes~>bBox + ( ListNonDestructiveMapCan + (lambda ( SubInstance ) + ( MidLevelGetBBoxes + SubInstance + TheLPP ) ) + ( getq ( getq Instance master ) instances ) ) ) ) ) ) + +(defun MidLevelGetOffsetX ( CellView + Instances + BoundaryLPP ) + + (cond ( + ( ListFindMinimum + ( MidLevelGetLeftBBoxesForInstances + CellView + Instances + BoundaryLPP + ) + (lambda ( BBox ) + ( MidLevelGetOffsetXForBBox + CellView + BBox + Instances + BoundaryLPP ) ) ) ) + ( + 0.0 ) ) ) + +(defun MidLevelGetLeftBBoxesForInstances ( CellView + Instances + BoundaryLPP ) + ( setof + BBox + ( ListNonDestructiveMapCan + (lambda ( Instance ) + ( MidLevelGetBBoxes + Instance + BoundaryLPP ) ) + Instances ) + (let ( + ( OffendingInstance + ( caadr + ( dbGetNeighbor + CellView + ( RectShrinkInY + BBox + .005 ) + "left" + BoundaryLPP + 32 ) ) ) ) + ( println ( list "gingivitis" OffendingInstance ) ) + ( not + ( exists + Instance + Instances + ( equal + OffendingInstance + Instance + ) ) ) ) + ) ) + +(defun MidLevelGetLeftBBoxesForInstances ( CellView + Instances + BoundaryLPP ) + ( list + ( ListApplyFuncToListAndAccumulateResult + Instances + (lambda ( Instance BBox ) + ( RectGetBoundRect + ( getq Instance bBox ) + BBox ) ) + nil + nil ) ) ) + +(defun MidLevelGetOffsetXForBBox ( CellView + BBox + Instances + BoundaryLPP ) + ( min + (let ( + ( OverlapRet + ( dbProduceOverlap + CellView + ( RectShrinkInX + ( RectShrinkInY + BBox + .005 ) + .005 ) + ( list 0 32 ) + BoundaryLPP ) ) ) + (let ( + ( OverlapBBoxes + ( MidLeveGetOffendingBBoxes + BBox + Instances + OverlapRet + BoundaryLPP + ) ) ) + ( difference + ( RectGetLeft BBox ) + (cond ( + ( ListFindMaximum + OverlapBBoxes + `RectGetRight ) ) + ( + ( difference 0 1e99 ) + ) ) + ) ) ) + (let ( + ( NeighborRet + ( dbGetNeighbor + CellView + ( RectShrinkInY + BBox + .005 ) + "left" + BoundaryLPP + 32 ) ) ) + (cond ( + ( car NeighborRet ) ) + ( + 0.0 ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/mid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/mid.il new file mode 100644 index 0000000000..38f026b841 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/mid/mid.il @@ -0,0 +1,740 @@ + ; Copyright 2003 Fulcrum Microsystems. All rights reserved. + ; $Id$ + ; $DateTime$ + ; $Author$ + + + +(defun MidLevelGetRects ( CellView + LPP + LeafCellPredicate ) + ( append + (when ( apply LeafCellPredicate ( list CellView ) ) + ( mapcar + (lambda ( Shape ) + ( getq Shape bBox ) ) + ( PinUtilGetAllShapesOnLPP CellView LPP ) ) ) + ( ListNonDestructiveMapCan + (lambda ( Instance ) + ( mapcar + (lambda ( InstanceShape ) + ( dbTransformBBox + InstanceShape + (if ( equal ( getq Instance objType ) "mosaicInst" ) + ( list ( car Instance->bBox ) + ( car Instance->mosaic->tileArray ) ) + Instance->transform + ) ) ) + ( MidLevelGetRects + ( getq Instance master ) + LPP + LeafCellPredicate ) + ) ) + ( getq CellView instances ) + ) ) ) + + +(defun MidLevelGetTopMetalLPP ( CellView + MetalLayerFormat ) + ( ListFindMaximumElement + ( setof + LPP + ( MidLevelGetLPPs + CellView ) + ( equal ( cadr LPP ) "drawing" ) ) + (lambda ( LPP ) + (let ( + ( Num 0 ) ) + ( sscanf ( car LPP ) MetalLayerFormat Num ) + Num + ) ) ) ) + + +(defun MidLevelConvertFloorplanToLayout ( Floorplan + TargetLibName + DirectiveTable + PinsFile + LayoutViewName + CompactedViewName + RoutedViewNamePrefix + BoundaryLPP + PreDoFiles + PostDoFiles + LPPsToUse + LPPsToSearch + KeepOutDepth + RuleFile + WorkingDir + GNDNetName + VddNetName + ViaLibraryName + ViaNameFormat + MetalLayerRegEx + MetalLayerFormat + HorizontalMetalLPPs + VerticalMetalLPPs + UserUnitsPerMeter + DirectiveUnitsPerMeter + DRCRuleFile + DRCAssuraSets + LVSRuleFile + LVSBindFile + LVSCompareFile + LVSIncludeFile + SchematicFile + TechLibName + NotchDRCRuleFile + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ViaLayerRegEx + PinLength + PinLPP + HorizontalLPP + FoldableCellLibCellPairRegExs + SkillNetlistDir + DirectivesDir + Graphics + ) + (let ( + ( ConductorDepths + ( ListFillList + (lambda ( X ) ( difference X 1 ) ) + ( plus 1 ( HierarchyGetMaxDepth Floorplan ) ) ) ) + ( CellName ( getq Floorplan cellName ) ) ) + (let ( + ( Compacted + ( dbCopyCellView + Floorplan + TargetLibName + CellName + CompactedViewName + nil + nil + t ) ) ) + ;convert to layout views + ( SwapInstanceMasterViews + Compacted + LayoutViewName + "maskLayout" ) + ;die if failed + (let ( + ( LayoutDontExist + ( setof + Instance + ( getq Compacted instances ) + ( not ( equal + ( getq ( getq Instance master ) viewName ) + LayoutViewName ) ) ) ) ) + (when LayoutDontExist + (error + ( sprintf + nil + "Can't find layout view for these cells: %s\n" + ( StringUtilConvertStringListToSpaceSeperatedString + ( ListRemoveDuplicatesNoTableElements + LayoutDontExist~>cellName ) ) ) ) ) ) + + ( println + ( MidLevelGetTopMetalLPP + Compacted + MetalLayerFormat ) ) + + (let ( + ( BoundingBox nil ) + ( XGrid + ( PDKGetInstanceXGridForMetalLPP + ( MidLevelGetTopMetalLPP + Compacted + MetalLayerFormat ) ) ) ) + + ( MidLevelCompactInstances + Compacted + ( getq Compacted instances ) + BoundaryLPP + XGrid ) + + ;sync to netlist + + ( UpdateNetlistGenFromSkillNetlistUsingPDKInfo + Compacted + SkillNetlistDir + DirectivesDir ) + + ;draw pins + ( PinPlaceDraw + Compacted + UserUnitsPerMeter + BoundaryLPP + PinLength + PinLPP + HorizontalLPP + FoldableCellLibCellPairRegExs + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + MetalLayerRegEx + ViaLayerRegEx + ?PinsDirectory "." + ?ConnectivityViewName CompactedViewName + ?PinsFile PinsFile + ?DeleteOld nil + ?CreateLog nil + ?PowerGrid `inplace + ?InPlace t + ?DeleteExistingPins t + ) + + + ( foreach + Box + ( ListNonDestructiveMapCan + (lambda ( Instance ) + ( MidLevelGetBBoxes + Instance + BoundaryLPP ) ) + ( getq Compacted instances ) ) + ( setq BoundingBox ( RectGetBoundRect + BoundingBox + Box ) ) ) + + ; ( geSelectObject + ;( dbCreateRect + ; Compacted + ; BoundaryLPP + ; Box ) + ;) + ; ) + ; ( leHiMerge ) + ; ( geDeselectAll ) + + ( dbCreateRect + Compacted + BoundaryLPP + BoundingBox ) + + ( dbSave Compacted ) + + (let ( + ( CurrConductorDepths + ConductorDepths ) + ( Done nil ) + ( SuccessView nil ) + ) + (while ( not Done ) + (let ( + ( ConductorDepth + ( car CurrConductorDepths ) ) ) + (let ( + ( RoutedViewName + ( sprintf nil + "%s_%s_%d" + RoutedViewNamePrefix + ( ListApplyFuncToListAndAccumulateResult + ( mapcar + (lambda ( LPP ) + ( rexCompile "METAL" ) + ( rexReplace ( car LPP ) "" 0 ) ) + LPPsToUse ) + `strcat + nil + "" ) + ConductorDepth ) ) + ) + (let ( + ( WorkingDir + ( sprintf nil + "%s/%s" + WorkingDir + RoutedViewName ) ) + ( PreRoute + ( dbCopyCellView + Compacted + TargetLibName + CellName + "scratch" + nil + nil + t + ) ) + ( PowerGridMaster + ( dbOpenCellViewByType + PowerGridLibName + ( PDKGetPowerGridGetCellNameForMetalLPP + ( car ( last LPPsToUse ) ) ) + PowerGridViewName + "maskLayout" + "r" ) ) + ) + + + ;instantiate power grid + (when PowerGridMaster + ( dbCreateSimpleMosaic + PreRoute + PowerGridMaster + nil + ( list 0 0 ) + "R0" + ( ceiling + ( quotient + ( RectGetHeight BoundingBox ) + ( RectGetHeight ( getq PowerGridMaster bBox ) ) ) ) + ( ceiling + ( quotient + ( RectGetWidth BoundingBox ) + ( RectGetWidth ( getq PowerGridMaster bBox ) ) ) ) + ( RectGetHeight ( getq PowerGridMaster bBox ) ) + ( RectGetWidth ( getq PowerGridMaster bBox ) ) + ) ) + + ( dbSave PreRoute ) + ( dbPurge PreRoute ) + (unless ( or + ( isDir WorkingDir ) + ( createDir WorkingDir ) ) + (error + ( sprintf + nil + "Can't create %s" + WorkingDir ) ) ) + + + (let ( + ( Ret + ( MidLevelRouteWithLPPsAndConductorDepth + TargetLibName + CellName + "scratch" + RoutedViewName + LPPsToUse + ConductorDepth + KeepOutDepth + RuleFile + PreDoFiles + PostDoFiles + WorkingDir + GNDNetName + VddNetName + ViaLibraryName + ViaNameFormat + Graphics ) ) + ( MetalLPPs + ( setof LPP LPPsToUse ( rexMatchp + MetalLayerRegEx + ( car LPP ) ) ) ) + ) + + + ( printf "%s\n" RoutedViewName ) + ( printf "Router: Crossing Violations: %d\n" ( nth 0 Ret ) ) + ( printf "Router: Clearance Violations: %d\n" ( nth 1 Ret ) ) + ( printf "Router: Unroutes: %d\n" ( nth 2 Ret ) ) + ( printf "Router: Completion: %f\n" ( nth 3 Ret ) ) + + (let ( + ( Routed + ( dbOpenCellViewByType + TargetLibName + CellName + RoutedViewName + "maskLayout" + "a" + ) ) ) + + (let ( + ( RoutingGood + ( and + ( lessp ( nth 0 Ret ) 100 ) + ( equal ( nth 2 Ret ) 0 ) + (if (let ( + ( LVSStatus + ( AssuraRunLVS + Routed + LVSRuleFile + nil + LVSBindFile + LVSCompareFile + LVSIncludeFile + SchematicFile + WorkingDir + ( sprintf nil "%s/lvs" + WorkingDir ) ) ) + ) + ( printf "LVS Status: %s\n" + (if LVSStatus "Passed" "Failed" ) ) + LVSStatus ) + t + ) ) ) ) + + (when RoutingGood + ( setq SuccessView Routed ) + ( KeepOutDrawKeepOut + Routed + DirectiveTable + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) + ( ListIntersect HorizontalMetalLPPs MetalLPPs ) ) + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) + ( ListIntersect VerticalMetalLPPs MetalLPPs ) ) + BoundaryLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + ( list GNDNetName VddNetName ) + ( list nil ) + t + nil + 0 ) + + ( NotchesFillNotchesOnCellView + Routed + ( append + ( list ( list "polyfix" PolyLPP ) + ( list "notchpoly" PolyLPP ) ) + ( append + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile MetalLayerRegEx ) + ( rexExecute ( car MetalLPP ) ) + ( list ( rexSubstitute "area\\1" ) + MetalLPP ) ) + MetalLPPs ) + ( append + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile MetalLayerRegEx ) + ( rexExecute ( car MetalLPP ) ) + ( list ( rexSubstitute "notch\\1" ) + MetalLPP ) ) + MetalLPPs ) + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile MetalLayerRegEx ) + ( rexExecute ( car MetalLPP ) ) + ( list ( rexSubstitute "extension\\1" ) + MetalLPP ) ) + MetalLPPs ) ) ) ) + ( append + ( mapcar + (lambda ( MetalLPP ) + ( car MetalLPP ) ) + MetalLPPs ) + ( append + ( list "NOTCH" "AREA" "EXTENSION" "POLY" ) + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile MetalLayerRegEx ) + ( rexExecute ( car MetalLPP ) ) + ( rexSubstitute "M\\1_AREA_KEEPIN" ) ) + MetalLPPs ) ) ) + + NotchDRCRuleFile + WorkingDir ) + + ( println MetalLPPs ) + ( foreach + LPP + ( mapcar + (lambda ( LPP ) + ( list ( car LPP ) "dummy" ) ) + MetalLPPs ) + ( foreach Shape + ( PinUtilGetAllShapesOnLPP Routed LPP ) + ( dbDeleteObject Shape ) ) ) + + ( techBindTechFile + Routed + TechLibName + "techfile.cds" + t + ) + ) + + (when RoutingGood + ( setq Done t ) + ) + + ( dbSave Routed ) + (unless RoutingGood + ( dbPurge Routed ) ) + + ;cycle conductor depth, LPPs + ( setq CurrConductorDepths + (cond ( + ( cdr CurrConductorDepths ) ) + ( + t + ( setq LPPsToUse + ( append + LPPsToUse + ( list ( car LPPsToSearch ) ) ) ) + ( setq LPPsToSearch + (cond ( + ( cdr LPPsToSearch ) + ) + ( + t + ( setq Done t ) + nil ) ) ) + ConductorDepths + ) ) ) ) ) ) ) ) ) ) + ;end while + + (when SuccessView + (let ( + ( DRCStatus + ( AssuraRunDRC + SuccessView + DRCRuleFile + DRCAssuraSets + WorkingDir + ( sprintf nil "%s/drc" + WorkingDir + ) + ) ) ) + ( printf "DRC Status: %s\n" (if DRCStatus "Passed" "Failed" ) ) + (let ( + ( FinalView + ( dbCopyCellView + SuccessView + TargetLibName + CellName + (cond ( + DRCStatus + "drc_lvs_clean" ) + ( + "lvs_clean" ) ) + nil + nil + t ) ) ) + ( dbSave FinalView ) + ( dbPurge FinalView ) ) ) ) + + ( dbPurge Compacted ) + + + ) ) ) ) ) + +(defun MidLevelRouteWithLPPsAndConductorDepth ( TargetLibName + CellName + SrcViewName + RoutedViewName + LPPs + ConductorDepth + KeepOutDepth + RuleFile + PreDoFiles + PostDoFiles + WorkingDir + GNDNetName + VddNetName + ViaLibraryName + ViaNameFormat + Graphics ) + + (let ( + ( DoFileName + ( sprintf + nil + "%s/cell.do" + WorkingDir + ) ) ) + (let ( + ( DoFilePort + ( outfile DoFileName ) ) ) + (unless ( portp DoFilePort ) + (error + ( sprintf + nil + "Can't write to %s" + DoFileName ) ) ) + + ( ConstraintsDumpLayers_ICC + LPPs + ( ConstraintsConvertLPPListToViaNameList + LPPs + ViaLibraryName + ViaNameFormat ) + DoFilePort ) + ( close DoFilePort ) + + ( RouterRunRouter + TargetLibName + CellName + SrcViewName + TargetLibName + CellName + RoutedViewName + ConductorDepth + KeepOutDepth + RuleFile + ( append PreDoFiles + ( cons DoFileName PostDoFiles ) ) + WorkingDir + ( list GNDNetName VddNetName ) + ?Quit t + ?Import t + ?Blocking t + ?Graphics Graphics + ) + + ) ) ) + + + +(defun MidLevelAutoUsingPDKInfo ( CellName + TargetLibName + FulcrumPDKRoot + SchematicFile + WorkingDir + LPPsToUse + LPPsToSearch + @key + ( Graphics t ) + ( MinVia nil ) + ) + + (let ( + ( DirectivesDir + ( sprintf + nil + "%s/ildirectives" + WorkingDir ) ) + ( SkillNetlistDir + ( sprintf + nil + "%s/ilnets" + WorkingDir ) ) + ( FloorplanViewName "floorplan" ) + ( SrcLibName + ( car ( NameParseCellName CellName ) ) ) ) + (let ( + ( Floorplan + ( dbOpenCellViewByType + SrcLibName + CellName + FloorplanViewName + "maskLayout" + "r" + ) ) ) + (unless Floorplan + (error + ( sprintf + nil + "Can't open floorplan view %s %s %s" + SrcLibName + CellName + FloorplanViewName + ) ) ) + + (let ( + ( KeepOutDepth 32 ) + ( DirectiveTable + ( CellInfoGetTableForCellName + CellName + DirectivesDir + ) ) + ( PinsFile + ( sprintf + nil + "%s/autopins/%s.pins.il" + WorkingDir + CellName + ) ) + ( AllDoFile + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/router/all.do" + FulcrumPDKRoot ) ) + ( DoFile + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/router/mid.do" + FulcrumPDKRoot ) ) + ( RuleFile + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/router/all.rul" + FulcrumPDKRoot ) ) + ( DRCRuleFile + ( sprintf + nil + "%s/share/Fulcrum/assura/drc.rul" + FulcrumPDKRoot ) ) + ( DRCAssuraSets + ( list "LATCH_UP" ) ) + ( NotchDRCRuleFile + ( sprintf + nil + "%s/share/Fulcrum/notch/fill_notches.assura.rules.all" + FulcrumPDKRoot ) ) + ( LVSRuleFile + ( sprintf + nil + "%s/share/Fulcrum/assura/extract.rul" + FulcrumPDKRoot ) ) + ( LVSBindFile + ( sprintf + nil + "%s/share/Fulcrum/assura/bind.rul" + FulcrumPDKRoot ) ) + ( LVSCompareFile + ( sprintf + nil + "%s/share/Fulcrum/assura/compare.rul" + FulcrumPDKRoot ) ) + ( LVSIncludeFile + ( sprintf + nil + "%s/share/Fulcrum/assura/LVSinclude.rsf" + FulcrumPDKRoot ) ) + ) + + ( MidLevelConvertFloorplanToLayout + Floorplan + TargetLibName + DirectiveTable + PinsFile + "layout" + "compacted" + "routed" + BoundaryLPP + nil; ( list AllDoFile ) + ( list DoFile ) + LPPsToUse + LPPsToSearch + KeepOutDepth + RuleFile + WorkingDir + GNDNetName + VddNetName + ContactLibrary + (if MinVia ContactMinCellNameFormat ContactCellNameFormat ) + MetalLayerRegEx + MetalLayerFormat + HorizontalMetalLPPs + VerticalMetalLPPs + UserUnitsPerMeter + DirectiveUnitsPerMeter + DRCRuleFile + DRCAssuraSets + LVSRuleFile + LVSBindFile + LVSCompareFile + LVSIncludeFile + SchematicFile + TechLibName + NotchDRCRuleFile + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ViaLayerRegEx + PinLength + PinLPP + ( list ( car PinLPP ) "drawing" ) + FoldableCellLibCellPairRegExs + SkillNetlistDir + DirectivesDir + Graphics + ) + ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/fillnotches.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/fillnotches.il new file mode 100644 index 0000000000..19da03e458 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/fillnotches.il @@ -0,0 +1,295 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: FillNotches +; Parameter: CellView (CVId) +; Return: CellView (VIId) +; +; Fill Notches + +defun( FillNotches ( CellView + @key + ( NOTCH t ) + ( POLY t ) + ( AREA t ) + ( EXTENSION t ) + ) + + (let ( + ( MetalLPPs ( list Metal1LPP Metal2LPP Metal3LPP ) ) ) + ( NotchesFillNotchesOnCellView + CellView + ( append + (if PolyLPP && POLY ( list ( list "polyfix" PolyLPP ) + ( list "notchpoly" PolyLPP ) ) ) + ( append + (if AREA + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "METAL" ) + ( list ( rexReplace ( car MetalLPP ) "area" 0 ) MetalLPP ) ) + MetalLPPs ) ) + ( append + (if NOTCH + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "METAL" ) + ( list ( rexReplace ( car MetalLPP ) "notch" 0 ) MetalLPP ) ) + MetalLPPs ) ) + (if EXTENSION + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "METAL" ) + ( list ( rexReplace ( car MetalLPP ) "extension" 0 ) MetalLPP ) ) + MetalLPPs ) ) + ) + ) + ) + ( append + ( mapcar + (lambda ( MetalLPP ) + ( car MetalLPP ) ) + MetalLPPs ) + ( setof Set + ( list (if NOTCH "NOTCH") (if AREA "AREA") (if EXTENSION "EXTENSION") (if POLY "POLY") ) + ( stringp Set ) + ) ) + NotchDRCRuleFile + WorkingDir ) + + ( techBindTechFile + CellView + TechLibName + "techfile.cds" + t ) + + ( dbSave CellView ) + ) +CellView +) + +defun( FillNotches65 ( CellView + @key + ( DOUBLE_VIA t ) + ( NOTCH t ) + ( POLY t ) + ( AREA nil ) + ( EXTENSION nil ) + ) + + (let ( + ( MetalLPPs ( list Metal1LPP Metal2LPP Metal3LPP ) ) + ( MetalViaLPPs ( list Metal1LPP Metal2LPP Metal3LPP Via12LPP Via23LPP) ) ) + ( NotchesFillNotchesOnCellView + CellView + ( foreach mapcan Set + (list + (if PolyLPP && POLY ( list ( list "polyfix" PolyLPP ) + ( list "notchpoly" PolyLPP ) ) ) + (if AREA + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "area" 0 ) MetalLPP ) ) + MetalLPPs ) ) + (if NOTCH + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "notch" 0 ) MetalLPP ) ) + MetalLPPs ) ) + (if EXTENSION + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "extension" 0 ) MetalLPP ) ) + MetalLPPs ) ) + (if DOUBLE_VIA + list( + list( "add_via1" Via12LPP ) + list( "add_via2" Via23LPP ) + list( "add_via1_m1" Metal1LPP ) + list( "add_via1_m2" Metal2LPP ) + list( "add_via2_m2" Metal2LPP ) + list( "add_via2_m3" Metal3LPP ) + ) ) + ) + Set + ) + ( append + ( mapcar + (lambda ( MetalLPP ) + ( car MetalLPP ) ) + MetalViaLPPs ) + ( setof Set + ( list (if NOTCH "NOTCH") (if AREA "AREA") (if EXTENSION "EXTENSION") (if POLY "POLY") (if DOUBLE_VIA "DOUBLE_VIA" )) + ( stringp Set ) + ) ) + NotchDRCRuleFile + WorkingDir ) + + ( techBindTechFile + CellView + TechLibName + "techfile.cds" + t ) + + ( dbSave CellView ) + ) +CellView +) + +defun( nrFindInstancesOverlapShape ( shape instances ) + let( (xMin yMin xMax yMax x1 x2 y1 y2 ) + xMin=min(caar(shape~>bBox) caadr(shape~>bBox)) + yMin=min(cadar(shape~>bBox) cadadr(shape~>bBox)) + xMax=max(caar(shape~>bBox) caadr(shape~>bBox)) + yMax=max(cadar(shape~>bBox) cadadr(shape~>bBox)) + + foreach( mapcan inst instances + x1=min(caar(inst~>bBox) caadr(inst~>bBox)) + y1=min(cadar(inst~>bBox) cadadr(inst~>bBox)) + x2=max(caar(inst~>bBox) caadr(inst~>bBox)) + y2=max(cadar(inst~>bBox) cadadr(inst~>bBox)) + cond( + ( x1>xMax || x2yMax || y2bBox )) + ( length(thisVia)>1 printf( "Found more than one via overlaping shape %L" shape~>bBox )) + ( t + thisVia=car(thisVia) + xx=(caar(shape~>bBox)+caadr(shape~>bBox))/2 + yy=(cadar(shape~>bBox)+cadadr(shape~>bBox))/2 + xx=floor(xx/Grid)*Grid + yy=floor(yy/Grid)*Grid + dbCreateParamInst(CellView viaCellViewMaster nil + (xx:yy) "R0" 1 + list( + list("column" "int" 1) + list("row" "int" 1) + ) + ) + if( width1>0 && height1>0 then + dbCreateRect(CellView LPP1 + list((xx-width1/2:yy-height1/2) (xx+width1/2:yy+height1/2))) + ) + if( width2>0 && height2>0 then + dbCreateRect(CellView LPP2 + list((xx-width2/2:yy-height2/2) (xx+width2/2:yy+height2/2))) + ) + viaInstances=setof( inst viaInstances inst!=thisVia ) + dbDeleteObject(thisVia) + dbDeleteObject(shape) + ) + ) + ) + viaInstances + + ) +) + +defun( nrFixViaExtension ( CellView + @key + ( SkipAssuraRun nil ) + ( CONT t ) + ( VIA12 t ) + ( VIA23 t ) + ) + + (let ( Via12Instances newVia1_1 newVia1_2 newVia1_3 newVia1_4 via12Master + Via23Instances newVia2_1 newVia2_2 newVia2_3 newVia2_4 via23Master + contInstances newCont_1 newCont_2 contMaster) + if( SkipAssuraRun==nil then + NotchesFillNotchesOnCellView( + CellView + append( if( CONT list( list( "newCont_1" list( "CONT" "dummy1")) + list( "newCont_2" list( "CONT" "dummy2")))) + append( if( VIA12 list( list( "newVia1_1" list( "VIA12" "dummy1")) + list( "newVia1_2" list( "VIA12" "dummy2")) + list( "newVia1_3" list( "VIA12" "dummy3")) + list( "newVia1_4" list( "VIA12" "dummy4")))) + if( VIA23 list( list( "newVia2_1" list( "VIA23" "dummy1")) + list( "newVia2_2" list( "VIA23" "dummy2")) + list( "newVia2_3" list( "VIA23" "dummy3")) + list( "newVia2_4" list( "VIA23" "dummy4")))) + )) + setof( Set + list( if( CONT "CONT") if( VIA12 "VIA12") if( VIA23 "VIA23") ) + stringp( Set ) + ) + NotchDRCRuleFile + WorkingDir ) + + ( techBindTechFile + CellView + TechLibName + "techfile.cds" + t ) + dbSave( CellView ) + ) + +; ViaInstances= cadr( NameFilterInstances( CellView~>instances ContactLibCellExpressionPairs )) +; ViaPolyInstances= setof( inst ViaInstances inst~>cellName==CCAR_M1POLY1ContactName ) + newCont_1 = setof( shape CellView~>shapes shape~>layerName=="CONT" && shape~>purpose=="dummy1") + newCont_2 = setof( shape CellView~>shapes shape~>layerName=="CONT" && shape~>purpose=="dummy2") + + if( newCont_1 || newCont_2 then + + contInstances= setof( inst CellView~>instances inst~>cellName==CCAR_M1POLY1ContactName ) + contMaster = dbOpenCellViewByType(TechLibName CCAR_M1POLY1ContactName "layout" "maskLayout") + + contInstances=nrReplaceVia( CellView contMaster newCont_1 contInstances PolyLPP Metal1LPP 0 0 0.26 0.17) + contInstances=nrReplaceVia( CellView contMaster newCont_2 contInstances PolyLPP Metal1LPP 0 0 0.17 0.26) + ) + + newVia1_1 = setof( shape CellView~>shapes shape~>layerName=="VIA12" && shape~>purpose=="dummy1") + newVia1_2 = setof( shape CellView~>shapes shape~>layerName=="VIA12" && shape~>purpose=="dummy2") + newVia1_3 = setof( shape CellView~>shapes shape~>layerName=="VIA12" && shape~>purpose=="dummy3") + newVia1_4 = setof( shape CellView~>shapes shape~>layerName=="VIA12" && shape~>purpose=="dummy4") + + if( newVia1_1 || newVia1_2 || newVia1_3 || newVia1_4 then + + Via12Instances= setof( inst CellView~>instances inst~>cellName==CCAR_M2M1ViaName ) + via12Master = dbOpenCellViewByType(TechLibName CCAR_M2M1ViaName "layout" "maskLayout") + + Via12Instances=nrReplaceVia( CellView via12Master newVia1_1 Via12Instances Metal1LPP Metal2LPP 0.29 0.21 0.2 0.29) + Via12Instances=nrReplaceVia( CellView via12Master newVia1_2 Via12Instances Metal1LPP Metal2LPP 0.21 0.29 0.2 0.29) + Via12Instances=nrReplaceVia( CellView via12Master newVia1_3 Via12Instances Metal1LPP Metal2LPP 0.29 0.21 0.29 0.2) + Via12Instances=nrReplaceVia( CellView via12Master newVia1_4 Via12Instances Metal1LPP Metal2LPP 0.21 0.29 0.29 0.2) + ) + + newVia2_1 = setof( shape CellView~>shapes shape~>layerName=="VIA23" && shape~>purpose=="dummy1") + newVia2_2 = setof( shape CellView~>shapes shape~>layerName=="VIA23" && shape~>purpose=="dummy2") + newVia2_3 = setof( shape CellView~>shapes shape~>layerName=="VIA23" && shape~>purpose=="dummy3") + newVia2_4 = setof( shape CellView~>shapes shape~>layerName=="VIA23" && shape~>purpose=="dummy4") + + if( newVia2_1 || newVia2_2 || newVia2_3 || newVia2_4 then + + Via23Instances= setof( inst CellView~>instances inst~>cellName==CCAR_M3M2ViaName ) + via23Master = dbOpenCellViewByType(TechLibName CCAR_M3M2ViaName "layout" "maskLayout") + + Via23Instances=nrReplaceVia( CellView via23Master newVia2_1 Via23Instances Metal2LPP Metal3LPP 0.2 0.29 0.29 0.2) + Via23Instances=nrReplaceVia( CellView via23Master newVia2_2 Via23Instances Metal2LPP Metal3LPP 0.29 0.2 0.29 0.2) + Via23Instances=nrReplaceVia( CellView via23Master newVia2_3 Via23Instances Metal2LPP Metal3LPP 0.2 0.29 0.2 0.29) + Via23Instances=nrReplaceVia( CellView via23Master newVia2_4 Via23Instances Metal2LPP Metal3LPP 0.29 0.2 0.2 0.29) + ) + dbSave( CellView ) + + CellView + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/notches.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/notches.il new file mode 100644 index 0000000000..a8744f5386 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/notches/notches.il @@ -0,0 +1,117 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun NotchesFillNotchesOnCellView ( CellView + AssuraLayerMappings + AssuraSets + RuleFile + TempDir + @key + ( Area nil ) + ( NoPCells nil ) + ) + + (let ( + ( TechLibName ( techGetTechFileName CellView ) ) + ( TempLibName ( LibCreateTempLibraryFromCellView + CellView + ( sprintf nil "NOTCHES_%s" ( getq CellView cellName ) ) + TempDir ) ) + ( ErrorStr nil ) ) + ( setq + ErrorStr + ( AssuraRunAssuraLayerProcessor + CellView + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) + RuleFile + TempDir + AssuraLayerMappings + nil + ?LeaveMess nil + ?AssuraSets AssuraSets + ?Area Area + ?NoPCells NoPCells + ) ) + + ( println ErrorStr ) + + (unless ErrorStr + (let ( + ( OutputCellDDObj ( ddGetObj TempLibName ( getq CellView cellName ) ( getq CellView viewName ) ) ) ) + (if ( and OutputCellDDObj ( getq OutputCellDDObj files ) ) + (let ( + ( CellWithNotches ( dbOpenCellViewByType + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) + nil + "a" ) ) ) + (if CellWithNotches + (let () + ( AssuraCopyShapesFromCellView + CellWithNotches + CellView + nil ) + ;( NotchesRemoveShortingShapes + ; CellView ) + ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to open cell view %L %L %L, even though DDObj exists." + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "%L %L %L does not exist." + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) ) + ( ddDeleteObj ( ddGetObj TempLibName ) ) + ( techBindTechFile CellView TechLibName ) + ErrorStr ) ) + + +(defun NotchesRemoveShortingShapes ( CellView ) + (let ( + ( PolygonTable ( makeTable `polygon nil ) ) + ( AllShapes ( getq CellView shapes ) ) ) + + ( foreach Shape AllShapes + ( setarray PolygonTable Shape + ( FigGetPolygonEdgesForFig Shape ) ) ) + ( mapcar + (lambda ( Shape ) + ( dbDeleteObject Shape ) ) + ( setof Shape ( getq CellView shapes ) + (let ( + ( AbuttingShapes + ( NotchesGetAbuttingFigsOnSameLPP + PolygonTable + Shape + AllShapes ) ) ) + (let ( + ( AbuttingNet ( getq + ( car ( exists AbutShape AbuttingShapes + ( getq Shape net ) ) ) + net ) ) ) + ( not ( forall AbuttingShape AbuttingShapes + ( or ( null ( getq AbuttingShape net ) ) + ( equal ( getq AbuttingShape net ) AbuttingNet ) ) ) ) ) ) ) ) ) ) + + +(defun NotchesGetAbuttingFigsOnSameLPP ( PolygonTable Shape Shapes ) + ( setof OtherShape Shapes + ( and ( equal ( getq Shape lpp ) ( getq OtherShape lpp ) ) + ( PolygonEdgesAbut + ( arrayref PolygonTable Shape ) + ( arrayref PolygonTable OtherShape ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/ScanPinToAutoPinFile.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/ScanPinToAutoPinFile.il new file mode 100644 index 0000000000..c80f180ee2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/ScanPinToAutoPinFile.il @@ -0,0 +1,127 @@ +; Copyright 2008 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( glcFindPinTemplate ( CellName + @key + (PinGlobalWirePitch DefaultWiringPitch) + (PinGlobalWireWidth DefaultWiringWidth) + (PinGlobalWireSpacing 0.12) + (PowerGridTrackOffset -1) + (AutoPinFileName "autopin.il") + (templateViewName "layout") + ) + prog((fin cellRootName templateCellName libName BakPinFileName CellView) + AutoPinTemplateFound=0 + ; AutoPinTemplateFound is a global variable used also in snapFatPins + BakPinFileName=strcat(AutoPinFileName "_bak") + fin=infile(BakPinFileName) + if( fin then close(fin) AutoPinTemplateFound=1 return(nil)) + rexCompile(".[0-9]+$") + cellRootName=rexReplace(CellName "" 0) + templateCellName=strcat( cellRootName ".pintemplate" ) + libName=car( NameParseCellName( CellName )) + CellView=nrOpenCellViewReadable( libName templateCellName templateViewName ) + if( CellView==nil then return(nil)) + system(sprintf(nil "mv -f %s %s" AutoPinFileName BakPinFileName)) + AutoPinTemplateFound=1 + glcScanPinsToAutoPin( CellView + ?PinGlobalWirePitch PinGlobalWirePitch + ?PinGlobalWireWidth PinGlobalWireWidth + ?PinGlobalWireSpacing PinGlobalWireSpacing + ?PowerGridTrackOffset PowerGridTrackOffset + ?AutoPinFileName AutoPinFileName ) + ) +) + + +defun( glcScanPinsToAutoPin ( CellView + @key + (PinGlobalWirePitch DefaultWiringPitch) + (PinGlobalWireWidth DefaultWiringWidth) + (PinGlobalWireSpacing 0.12) + (PinGlobalWireOffset 0.12) + (PowerGridTrackOffset -1) + (AutoPinFileName "autopin.il") + ) + prog((pins pin fout prbound x1 x2 y1 y2 fig xMin xMax pinData pinOrient height) + fout=outfile(AutoPinFileName) + if( fout==nil then + printf("Unable to open file %s for write.\n" AutoPinFileName) + return(nil) + ) + fprintf( fout "( defvar PinGlobalWirePitch %.4e )\n" PinGlobalWirePitch/UserUnitsPerMeter ) + fprintf( fout "( defvar PinGlobalWireWidth %.4e )\n" PinGlobalWireWidth/UserUnitsPerMeter ) + fprintf( fout "( defvar PinGlobalWireSpacing %.4e )\n" PinGlobalWireSpacing/UserUnitsPerMeter ) + fprintf( fout "( PinPlacePowerGrid \"Vdd\" %.0f %.0f %.4e )\n" + PowerGridTrackOffset+PowerGridPitch/PinGlobalWirePitch + PowerGridPitch/PinGlobalWirePitch*2 + PowerGridWireWidth/UserUnitsPerMeter) + fprintf( fout "( PinPlacePowerGrid \"GND\" %.0f %.0f %.4e )\n" + PowerGridTrackOffset+0.0 + PowerGridPitch/PinGlobalWirePitch*2 + PowerGridWireWidth/UserUnitsPerMeter) + prbound=car(setof( lpp CellView~>lpps lpp~>layerName=="prBoundary" && lpp~>purpose=="drawing")) + xMin=leftEdge(car(prbound~>shapes)~>bBox) + xMax=rightEdge(car(prbound~>shapes)~>bBox) + foreach( fig prbound~>shapes + if(leftEdge(fig~>bBox)bBox)) + if(rightEdge(fig~>bBox)>xMax then xMax=rightEdge(fig~>bBox)) + ) + + pins=setof( pin CellView~>terminals pin~>net~>name!=GNDNetName && pin~>net~>name!=VddNetName) + foreach( pin pins + pinData=makeTable(`pinData nil) + pinWidth=makeTable(`pinWidth "") + foreach( fig pin~>pins~>fig +; printf("%s\n" pin~>net~>name) + cond( + (fig~>objType=="rect" || fig~>objType=="polgon" + bBox=fig~>bBox + y1=bottomEdge(bBox) + y2=topEdge(bBox) + x1=leftEdge(bBox) + x2=rightEdge(bBox) + track=floor((y2-PinGlobalWireOffset)/PinGlobalWirePitch) + ; metal3 track offset is 0.12 + height=y2-y1 + if( abs(height-PinGlobalWireWidth)<0.001 then + pinWidth[track]="" + else + pinWidth[track]=sprintf(nil "%.4e" height/UserUnitsPerMeter) + ) + cond( + (x1-xMinobjType)) + ) + ) + foreach( track pinData + if(pinData[track]!="none" then + fprintf(fout "( %s \"%s\" %d %s )\n" pinData[track] pin~>net~>name track pinWidth[track]) + else + printf("Error pin %s found.\n" pin~>net~>name) + ) + ) + ) + close(fout) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/abstractpin.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/abstractpin.il new file mode 100644 index 0000000000..9218e28ae7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/abstractpin.il @@ -0,0 +1,976 @@ +; Copyright 2005 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; IMPORTANT: while much of this LOOKs like it would work for naming the abstract +; view something else, it does not really work! + +defun( nrPointTransform ( point transform ) + let((xy orient temp ) + xy=car(transform) + function=caddar(setof(orient ORIENTLIST car(orient)==cadr(transform))) + if( function then + temp=apply( function list(point) ) + temp=list( car(temp)+car(xy) cadr(temp)+cadr(xy)) + else + printf("Invalid orient.\n") + temp=nil + ) + temp + ) +) + +defun( nrPointListTransform (pointList transform) + foreach( mapcar point pointList nrPointTransform( point transform )) +) + +defun( nrRectListTransform (rectList transform ) + foreach( mapcar bBox rectList nrPointListTransform( bBox transform )) +) + +defun( nrConvertPathToRectList ( path ) + "returns a list of rectangles" + let((returnList width beginExt endExt points x1 y1 x2 y2 temp) + returnList=nil + width=path~>width + beginExt=path~>beginExt-width/2 + endExt=path~>endExt-width/2 + points=listToVector(path~>points) + for( i 0 length(points)-2 + x1=car(points[i]) + y1=cadr(points[i]) + x2=car(points[i+1]) + y2=cadr(points[i+1]) + if((i==0) then + cond( + ((x1==x2 && y1>y2) y1=y1+beginExt) + ((x1==x2 && y1x2) x1=x1+beginExt) + ((y1==y2 && x1y2) y2=y2-endExt) + ((x1==x2 && y1x2) x2=x2-endExt) + ((y1==y2 && x1y2) temp=y2 y2=y1 y1=temp) + ((y1==y2 && x1>x2) temp=x2 x2=x1 x1=temp) + ((x1!=x2 && y1!=y2) printf("Error: none straight path:") println(path)) + ) + returnList=cons( list( x1-width/2:y1-width/2 x2+width/2:y2+width/2) returnList) + ) + returnList + ) +) + +defun( nrConvertPolygonToRectList ( poly ) + "returns a list of rectangles" + let((temp bBox returnList) + foreach( mapcar temp dbLayerTile( poly~>cellView poly~>lpp list(poly)) bBox=temp~>bBox dbDeleteObject(temp) bBox) + ) +) + + + +defun( nrGetInstanceNetShapes ( inst instNetName layerName ) + let((cellView shapes temp) + cellView=inst~>master + shapes=setof( shape cellView~>shapes + shape~>net~>name==instNetName && shape~>layerName==layerName && shape~>purpose=="drawing") + rectList=foreach( mapcan shape shapes + cond( + (shape~>objType=="rect" list(shape~>bBox)) + (shape~>objType=="path" nrConvertPathToRectList(shape)) + (shape~>objType=="polygon" nrConvertPolygonToRectList(shape)) + (t printf( "Warning: Non rect/path/polygon shape will be ignored!\n") nil) + ) + ) + rectList=nrRectListTransform(rectList inst~>transform) + ) +) + +; check if a rectangle overlaps with a pin within a maxPinLength radius +; returns nil for rectangles contained inside pins for some unfathomable reason +defun( nrFilterRect ( pinRect rect maxPinLength + @key + ( MustOverlap t ) + ) + let((returnRect pinX1 pinX2 pinY1 pinY2 x1 x2 y1 y2 xMin yMin xMax yMax) + pinX1=min(caar(pinRect) caadr(pinRect)) + pinY1=min(cadar(pinRect) cadadr(pinRect)) + pinX2=max(caar(pinRect) caadr(pinRect)) + pinY2=max(cadar(pinRect) cadadr(pinRect)) + + xMin=pinX2-maxPinLength + yMin=pinY2-maxPinLength + xMax=pinX1+maxPinLength + yMax=pinY1+maxPinLength + + x1=min(caar(rect) caadr(rect)) + y1=min(cadar(rect) cadadr(rect)) + x2=max(caar(rect) caadr(rect)) + y2=max(cadar(rect) cadadr(rect)) + + if( x1>xMax || x2yMax || y2=pinX1 && y1>=pinY1 && x2<=pinX2 && y2<=pinY2 then + returnRect=nil + else + returnRect=list( x1:y1 x2:y2 ) + ) + if(x1==x2 || y1==y2 then + returnRect=nil + ) + if( MustOverlap && (x1>pinX2 || x2pinY2 || y2terminals + net=pin~>net + if(PowerNets || (net~>name != "Vdd" && net~>name!="GND") then + layerName=car(pin~>pins~>fig~>layerName) + foreach( instTerm net~>allInstTerms + if(layerName==nil layerName=car(instTerm~>term~>pins~>fig~>layerName)) + if( PinExtension then + rectList=nrGetInstanceNetShapes(instTerm~>inst instTerm~>name layerName) + rectList=foreach( mapcan rect rectList + foreach( mapcar pinRect pin~>pins~>fig~>bBox + nrFilterRect( pinRect rect 10000 ?MustOverlap t ))) + else + rectList=pin~>pins~>fig~>bBox + ) + rectList=setof( rect rectList rect ) + foreach( rect rectList + dbAddFigToNet( dbCreateRect( cellView list(layerName "drawing") rect ) net ) + ) + ) + ) + ) + ) +) + +; Copy pins to pins with "net" purpose, which are used by the Assura +; deck to extend pins into touching metal. +(defun nrCreateAbstractPin + (CV @key (PowerNets nil)) + (let (Vdd GND net) + Vdd = (dbMakeNet CV "Vdd") + GND = (dbMakeNet CV "GND") + (foreach term CV->terminals + net = term->net + (when PowerNets || (net != Vdd && net != GND) + (foreach pinFig term~>pins~>fig + if( pinFig then + pinFig = (dbCopyFig pinFig CV) + pinFig->lpp = (list (car pinFig->lpp) "net") + (dbCreatePin net pinFig) + ) + ) + ) + ) + t + ) +) + +; is this type a contact or pcell? +(defun isPdkCell (CellView) + (or CellView->libName==TechLibName + CellView->libName==GateLibraryName + CellView->libName==StackLibraryName + ) + ) + +; Copies CellView to abstract_prep view, copys overlapping +; abstract_edit/abstract subcells, flattens them, swaps "net" to +; "drawing", returns new abstract_prep CellView. +(defun nrPrepareAbstract (CellView @key (keepLayoutSubcells t) (abstractView "abstract")) + (let (views hasAbstractView hasAbstractEditView) + ; copy to abstract_prep view + CellView=(dbCopyCellView CellView CellView->libName CellView->cellName + "abstract_prep" nil nil t ) + + ; substitute abstract_edit or abstract subcells and flatten + (rexCompile "\\.wires\\.") + (foreach inst CellView->instances + (cond ((and !(isPdkCell inst->master) !(rexExecute inst->cellName)) + views = (dbAllCellViews inst->master->lib inst->master->cellName) + hasAbstractEditView = (setof view views view=="abstract_edit") + hasAbstractView = (setof view views view==abstractView) + (cond (hasAbstractEditView + (cond (keepLayoutSubcells inst = (dbCopyFig inst nil))) + inst->master = (dbOpenCellViewByType inst->master->lib + inst->master->cellName + "abstract_edit") + (dbFlattenInst inst 1 nil nil nil)) + (hasAbstractView + (cond (keepLayoutSubcells inst = (dbCopyFig inst nil))) + inst->master = (dbOpenCellViewByType inst->master->lib + inst->master->cellName + abstractView) + (dbFlattenInst inst 1 nil nil nil)) + (t + (printf "WARNING: subcell %s of type %s has no abstract view\n", + inst->name inst->cellName )) + ) + ) + ) + ) + + ; replace "net" layer with "drawing" layer + (foreach shape CellView->shapes + (cond (shape->purpose=="net" shape->purpose="drawing")) + ) + ) + + ; return abstract_prep view + CellView + ) + +defun( nrCreateLeafAbstract ( libName cellName viewName + @key + ( DeleteInstances t ) + ( DeleteDrawingLayers t ) + ( AssuraSets nil ) + ( AssuraRuleFile nil ) + ( maxPinLength 9.6 ) + ( useAbstractSubcells nil ) + ( keepLayoutSubcells t ) + ( PowerNets t ) + ( PowerGridPitch PowerGridPitch ) + ( targetViewName "abstract" ) + ) + let(() + + + + nrCreateMidAbstract( libName cellName viewName + ?DeleteInstances DeleteInstances + ?DeleteDrawingLayers DeleteDrawingLayers + ?AssuraSets AssuraSets + ?AssuraRuleFile AssuraRuleFile + ?maxPinLength maxPinLength + ?useAbstractSubcells useAbstractSubcells + ?keepLayoutSubcells keepLayoutSubcells + ?PowerNets PowerNets + ?PowerGridPitch PowerGridPitch + ?targetViewName targetViewName + ) + ) +) + +defun( nrCreateMidAbstract ( libName cellName viewName + @key + ( DeleteInstances t ) + ( DeleteDrawingLayers t ) + ( AssuraSets nil ) + ( AssuraRuleFile nil ) + ( maxPinLength 9.6 ) + ( useAbstractSubcells nil ) + ( keepLayoutSubcells t ) + ( PowerNets nil ) + ( PowerGridPitch PowerGridPitch ) + ( targetViewName "abstract" ) + ( CDCPowerGrid nil ) + ( allbloat nil ) + ( labelPins t ) + ) + let((gec3Foreign srcCellView AssuraLayerMappings TempDirForThisRun AssuraRunLog + ErrorStr prBound bBox netShapes connectedNetShapes overlapPin bBox) + if(targetViewName != "abstract" printf("Error: generating abstract with view other than 'abstract' does not work, trying anyway.\n")) + srcCellView = dbOpenCellViewByType( libName cellName viewName) + (cond (useAbstractSubcells + srcCellView = (nrPrepareAbstract srcCellView + ?keepLayoutSubcells keepLayoutSubcells ?abstractView targetViewName))) + CellView=nrOpenCellViewWritable( libName cellName targetViewName) + if( CellView && srcCellView then + dbClose(CellView) + CellView=dbCopyCellView( srcCellView libName cellName targetViewName nil nil t ) + printf("Creating abstract pin...\n") + nrCreateAbstractPin( CellView ?PowerNets PowerNets) + + AssuraLayerMappings=cons( + list( "bound" list( car( BoundaryLPP ) "boundary" ) ) + append( + foreach( mapcan LPP MetalLPPs + sscanf( car( LPP ) MetalLayerFormat Num ) + list( + list( sprintf( nil "m%dKeepout" Num ) list( car( LPP ) "boundary" ) ) + list( sprintf( nil "m%dAddPin" Num ) list( car( LPP ) "net" ) ) + ) + ) + foreach( mapcan LPP list( Metal4LPP Metal5LPP Metal6LPP Metal7LPP Metal8LPP ) + sscanf( car( LPP ) MetalLayerFormat Num ) + list( + list( sprintf( nil "m%dVdd" Num ) list( car( LPP ) "vdd" ) ) + list( sprintf( nil "m%dGnd" Num ) list( car( LPP ) "gnd" ) ) + ) + ) + ) + ) + TempDirForThisRun=makeTempFileName( + sprintf( nil "%s/ASSURA.XXXXXX" ConfigFileGetValue( TheCDSConfigTable "TEMP" ))) + createDir( TempDirForThisRun ) + if( AssuraRuleFile==nil then AssuraRuleFile= sprintf( nil "%s/share/Fulcrum/cell_automation/abstract_mid.rul" + ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT" ))) + AssuraRunLog= sprintf( nil "%s/assura.log" TempDirForThisRun ) + ErrorStr= AssuraRunAssuraLayerProcessor( + CellView + CellView~>libName + CellView~>cellName + "abstract_temp" + AssuraRuleFile + TempDirForThisRun + AssuraLayerMappings + nil + ?AssuraSets AssuraSets + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ?allbloat allbloat + ) + + AssuraCopyShapesFromCellView( nrOpenCellViewReadable(libName cellName "abstract_temp") CellView nil) + + cv= ddGetObj(libName cellName "abstract_temp") + if(cv then ddDeleteObj(cv)) + (cond (useAbstractSubcells ddDeleteObj( ddGetObj(libName cellName "abstract_prep") ))) + + ; delete mosaics + if( DeleteInstances foreach( inst CellView~>instances + if( inst~>objType=="mosaicInst" dbDeleteObject( inst~>mosaic ) dbDeleteObject( inst )))) + + ; delete vias + if( DeleteInstances foreach( inst CellView~>vias + if( inst~>objType=="mosaicInst" dbDeleteObject( inst~>mosaic ) dbDeleteObject( inst )))) + + ; delete shapes that aren't "boundary" or "net" purpose (BUG 17554) + if( DeleteDrawingLayers then + foreach( shape CellView~>shapes + if( shape~>purpose!="net" && shape~>purpose!="boundary" dbDeleteObject( shape ))) + ) + + ; Make pins out of net shapes touching original pins. Requires + ; the original pin shapes to be rectangles, unfortunately. + ; Deletes the original pins in favor of touching net shapes. + netShapes = (setof shape CellView~>shapes shape~>purpose=="net") + connectedNetShapes = (setof shape netShapes shape~>net) + (foreach shape connectedNetShapes + (cond (shape->objType!="rect" + (printf "WARNING: can't attach net shapes to non-rectangle pin %s\n" + shape->net->name) + ) + (t + ; find overlapping net shapes + overlaps = (dbGetTrueOverlaps CellView shape->bBox shape->lpp 0) + (foreach overlap overlaps + (when !overlap->net + (dbCreatePin shape->net overlap) + (when labelPins (LabelPin CellView overlap ?bBox shape->bBox)) + ) + ) + ; delete original pin shapes in favor of connected ones + (cond (overlaps (dbDeleteObject shape)) + (labelPins (LabelPin CellView shape)) + ) + ) + ) + ) + + ; Convert vdd and gnd purpose to power pins. + leMergeShapes( setof( shape CellView~>shapes shape~>purpose=="gnd")) + leMergeShapes( setof( shape CellView~>shapes shape~>purpose=="vdd")) + foreach( shape CellView~>shapes + if( shape~>purpose=="gnd" then + shape~>purpose="net" + dbCreatePin( dbFindNetByName( CellView GNDNetName ) shape ) + ) + if( shape~>purpose=="vdd" then + shape~>purpose="net" + dbCreatePin( dbFindNetByName( CellView VddNetName ) shape ) + ) + ) + if( CDCPowerGrid then + prBoundd=setof( shape CellView~>shapes shape~>layerName=="prBoundary" && shape~>purpose=="drawing") + if( prBoundd then + top=cadr(cadar(prBoundd~>bBox)) + right=car(cadar(prBoundd~>bBox)) + shape = dbCreateRect( CellView list( "M1" "net" ) list( list( 0.06 -0.05 ) list( right-0.06 0.09 ) ) ) + p = dbCreatePin( dbFindNetByName( CellView GNDNetName ) shape ) + dbCreateRect( CellView list( "M1" "net" ) list( list( 0.06 -0.05 ) list( right-0.06 0.09 ) ) ) + shape = dbCreateRect( CellView list( "M1" "net" ) list( list( 0.06 top-0.09 ) list( right-0.06 top+0.05 ) ) ) + if( abs( top/4.4 - floor(top/4.4) ) < 0.1 then + p=dbCreatePin( dbFindNetByName( CellView GNDNetName ) shape ) + ) + if( abs( top/4.4 - floor(top/4.4) ) > 0.1 then + p=dbCreatePin( dbFindNetByName( CellView VddNetName ) shape ) + ) + dbCreateRect( CellView list( "M1" "net" ) list( list( 0.06 top-0.09 ) list( right-0.06 top+0.05 ) ) ) + ) + ) + + ; copy m1 keepout to OVERLAP + m1by=setof( lpp CellView~>lpps lpp~>layerName=="M1" && lpp~>purpose=="boundary") + foreach( lpp m1by + foreach( shape lpp~>shapes + when( shape~>objType=="rect" + m1points = shape~>bBox + dbCreateRect( CellView OverlapLPP m1points ) + ) + when( shape~>objType=="polygon" + m1points = shape~>points + dbCreatePolygon( CellView OverlapLPP m1points ) + ) + ) + ) + + ; merge keepout + leMergeShapes( setof( shape CellView~>shapes shape~>purpose=="boundary")) + prBound=setof( shape CellView~>shapes shape~>layerName=="prBoundary" && + shape~>purpose=="boundary") + if( prBound then bBox=car(prBound)~>bBox else bBox=CellView~>bBox ) + + ; set properties + sprintf( gec3Foreign "%s %f %f" CellView~>cellName caar(bBox) cadar(bBox) ) + dbReplacePropList( CellView list( + list("prCellClass" "string" "block") + list("prCellType" "string" "macro") + list("maskLayoutSubType" "string" targetViewName) + list("symmetry" "string" "X Y") + list("gec3Foreign" "string" gec3Foreign) + ) + ) + + ; delete pins with no shapes + foreach( pin CellView~>terminals + if( pin~>pins~>fig == nil then + printf("Delete pin with no shape: %s\n" pin~>name ) + dbDeleteObject( pin ) + ) + ) + + ; combine "prBoundary" "boundary" shapes into a single rectangle (BUG 17829) + bBox = nil + (foreach shape CellView->shapes + (when (and shape->layerName=="prBoundary" shape->purpose=="boundary") + bBox = (BBoxCombine shape->bBox bBox) + (dbDeleteObject shape) + ) + ) + (when bBox (dbCreateRect CellView (list "prBoundary" "boundary") bBox)) + + ; save and return abstract CellView + (dbSave CellView) + CellView + + else + printf("%s(%s) is not writable.\n" cellName targetViewName) + nil + ) + ) +) + +; Convert a figure to a rectangle list +(defun nrConvertFigToRectList (fig) + (cond (fig->objType=="rect" (list fig->bBox)) + (fig->objType=="path" (nrConvertPathToRectList fig)) + (fig->objType=="inst" (list fig->bBox)) + (fig->objType=="polygon" (nrConvertPolygonToRectList fig)) + (t (printf "Error: illegal pin shape for pin %s (%s).\n" + instTerm->name thisInst->name) nil) + ) + ) + +; Find subcell pins connecting to given net. Returns a list of lists, +; where the inner list is a layerName followed by a list of rectangles +; in the parent coordinate system. +(defun nrFindPinShapes (net pinLPPs) + (let (layerName inst transform tmp pinRectList lppList ret) + (foreach lpp pinLPPs + layerName = (car lpp) + pinRectList = nil + (foreach instTerm net->instTerms + inst = instTerm->inst + (when inst->libName!=TechLibName + transform = (geGetInstTransform inst) + (foreach pin instTerm->term->pins + (when (car pin->fig->lpp)==layerName + tmp = (nrConvertFigToRectList pin->fig) + tmp = (nrRectListTransform tmp transform) + pinRectList = (append tmp pinRectList) + ) + ) + ) + ) + (when pinRectList ret = (cons (list layerName pinRectList) ret)) + ) + ret + ) + ) + +defun( nrFindInstPinShapes ( thisInst pinName pinLPPs ) +; Find all Rectagles of subcell pin that connects to a paticular top level net + let((realInstances pinFigs pinRectList thisPinFigs shapes lpp) + terminalInstName=makeTable("a" "") + terminalInstName["METAL1"]="m1_T" + terminalInstName["METAL2"]="m2_T" + terminalInstName["METAL3"]="m3_T" + terminalInstName["METAL4"]="m4_T" + terminalInstName["METAL5"]="m5_T" + terminalInstName["METAL6"]="m6_T" + terminalInstName["METAL7"]="m7_T" + terminalInstName["METAL8"]="m8_T" + foreach( mapcan lpp pinLPPs + instPins=setof( terminal thisInst~>master~>terminals terminal~>name==pinName ) + pinFigs=foreach( mapcan instPin instPins instPin~>pins~>fig ) + thisPinFigs=setof( pinFig pinFigs pinFig~>layerName==car(lpp) || (pinFig~>objType=="inst" && pinFig~>cellName==terminalInstName[car(lpp)])) + pinRectList=foreach( mapcan pinFig thisPinFigs + cond( + (pinFig~>objType=="rect" list(pinFig~>bBox) ) + (pinFig~>objType=="path" nrConvertPathToRectList( pinFig ) ) + (pinFig~>objType=="inst" list(pinFig~>bBox) ) + (pinFig~>objType=="polygon" nrConvertPolygonToRectList( pinFig )) + (t printf("Error: illegal pin shape for pin %s (%s).\n" instTerm~>name thisInst~>name) nil) + ) + ) + shapes=nrRectListTransform(pinRectList thisInst~>transform ) + if( shapes list( list( car(lpp) shapes)) nil) + ) + ) +) + +defun( nrConvertRectToPath ( rect + @key + (minWidth nil) + ) + let((returnRect x1 x2 y1 y2 x y w) + x1=min(caar(rect) caadr(rect)) + y1=min(cadar(rect) cadadr(rect)) + x2=max(caar(rect) caadr(rect)) + y2=max(cadar(rect) cadadr(rect)) + x= (x2+x1)/2 + y= (y2+y1)/2 + if(x2-x1<=y2-y1 then + w= x2-x1 + if(minWidth then y1=max( y1 y-0.12) y2=min(y2 y+0.12)) + returnPath=list( list( x:y1 x:y2 ) w ) + else + w= y2-y1 + if(minWidth then x1=max( x1 x-0.12) x2=min( x2 x+0.12)) + returnPath=list( list( x1:y x2:y ) w ) + ) + returnPath + ) +) + +defun( nrFindOverlapRect ( thisRect rectList maxDistance @key (maxWidth 2*DefaultWiringWidth)) +; Find all rectangles in rectList that overlaps thisRect + let((returnRect pinX1 pinX2 pinY1 pinY2 x1 x2 y1 y2 xMin yMin xMax yMax x y w) + pinX1=min(caar(thisRect) caadr(thisRect)) + pinY1=min(cadar(thisRect) cadadr(thisRect)) + pinX2=max(caar(thisRect) caadr(thisRect)) + pinY2=max(cadar(thisRect) cadadr(thisRect)) + + xMin=pinX1-maxDistance-1e-9 + yMin=pinY1-maxDistance-1e-9 + xMax=pinX2+maxDistance+1e-9 + yMax=pinY2+maxDistance+1e-9 + + foreach( mapcan rect rectList + x1=min(caar(rect) caadr(rect)) + y1=min(cadar(rect) cadadr(rect)) + x2=max(caar(rect) caadr(rect)) + y2=max(cadar(rect) cadadr(rect)) + returnPath=nil + if( x1>xMax || x2yMax || y2=x2) || (pinX1+1e-9>=x1 && pinX2<=x2+1e-9) + ; need to add 1e-9 to avoid rounding error in float numbers + x= (min(pinX2 x2)+max(pinX1 x1))/2 + w= min(maxWidth min(pinX2 x2)-max(pinX1 x1)) + returnPath=list( list( x:min(pinY2 y2)-0.12 x:max(pinY1 y1)+0.12 ) w ) + ) + ((pinY1<=y1+1e-9 && pinY2+1e-9>=y2) || (pinY1+1e-9>=y1 && pinY2<=y2+1e-9) + ; need to add 1e-9 to avoid rounding error in float numbers + y= (min(pinY2 y2)+max(pinY1 y1))/2 + w= min(pinY2 y2)-max(pinY1 y1) + returnPath=list( list( min(pinX2 x2)-0.12:y max(pinX1 x1)+0.12:y ) w ) + ) + ( t returnPath=nil ) + ) + ) + if( returnPath list(returnPath) nil ) + ) + ) +) + +defun( nrCreateNeighborNetConnector ( cellView maxDistance pinLPPs + @key (maxFanout nil) ; set to 2 to avoid NanoRoute confusion + (maxWidth 2*DefaultWiringWidth) + (reportPort nil)) + let((pinRectList totalRectList newNetShapes rect figCount) + figCount=0 + nets=setof( net cellView~>nets net->term==nil && net->figs==nil && + (maxFanout==nil || net->instTermCount<=maxFanout)) + foreach( net nets + MasterRectList=nrFindPinShapes( net pinLPPs ) + foreach( pinRectList MasterRectList + layerName=car(pinRectList) + pinRectList=cadr(pinRectList) + totalRectList=pinRectList + newNetShapes=foreach( mapcan thisRect totalRectList + pinRectList=setof( rect pinRectList rect!=thisRect ) + nrFindOverlapRect( thisRect pinRectList maxDistance ?maxWidth maxWidth) + ) + foreach( returnPath newNetShapes + if(returnPath then + if( reportPort then + fprintf(reportPort "Net %s: Create neighbor connector: %L\n" net->name returnPath) + figCount=figCount+1 + else + path=dbCreatePath( cellView list(layerName "drawing") car(returnPath) cadr(returnPath) "truncateExtend" ) + if( path then + dbAddFigToNet( path net ) + figCount=figCount+1 + else printf("Warning: no valid returnPath %L (net %s).\n" returnPath net->name) + ) + ) + ) + ) + ) + ) + if( reportPort then + if( figCount == 0 then fprintf(reportPort "PASS: No neighbor connector needed in %s.\n" cellView~>cellName) + else fprintf(reportPort "ERROR: %d neighbor connectors needed in cell %s.\n" figCount cellView~>cellName)) + else + dbSave( cellView ) + printf("Done: Total %d shapes added.\n" figCount) + ) + ) +) + +defun( nrCreateSingleNetConnector ( cellView pinLPPs + @key + (reportOnly nil) + (reportPort poport) + (MaxHeapSize 2000) + ) +; Put a single metal piece over pins that does not route to other nets +; so that extraction spice will have top level net. + let((pinRectList totalRectList newNetShapes rect pathpoints figCount CDLFile CellListFile DoneFunc Command + instances inst uniqueInstances OutputFile p) + figCount=0 + if( reportOnly then + fprintf(reportPort "Processing %s ...\n" cellView~>cellName) + ) + CDLFile=sprintf( nil "%s/%s.cdl" + ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + cellView~>cellName ) + CellListFile=sprintf( nil "%s/%s.cell_list" + ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + cellView~>cellName ) + OutputFile=sprintf( nil "%s/%s.dangling_out" + ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + cellView~>cellName ) + when( !isFile( CDLFile ) + Command=sprintf( nil + "%s/cast2cdl --cast-path=%s --cell=%s --cadence-name --output=%s --max-heap-size=%dM --name-map=%s/share/Fulcrum/lve/transistor.map --process-dependent-name --64" + PackageGetBinRoot() + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + cellView~>cellName + CDLFile + MaxHeapSize + ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT" ) + ) + printf( "%s\n" Command ) + system( Command ) + ) + instances=setof( inst cellView~>instances inst~>libName!=TechLibName && inst~>libName!="gate" && inst~>libName!="stack" ) + + p=outfile(CellListFile) + uniqueInstances=nil + foreach( inst instances~>cellName + if( !member(inst uniqueInstances) then + uniqueInstances=cons( inst uniqueInstances) + fprintf( p "%s\n" inst ) + ) + ) + close(p) + + Command=sprintf( nil "%s/dangling %s %s %s" PackageGetBinRoot() CDLFile CellListFile OutputFile) + printf( "%s\n" Command ) + system( Command ) + + danglingNodeList=nil + load(OutputFile) + + foreach( node danglingNodeList + netName=car(node) + instName=cadr(node) + pinName=caddr(node) + cellName=cadddr(node) + net=dbFindNetByName( cellView netName ) + if( net==nil then + printf("Net %s does not exist. Creating Net.\n" netName) + if( reportOnly then + fprintf(reportPort "dbCreateNet %s\n" netName) + else + net=dbCreateNet( cellView netName ) + ) + ) + if(net~>figs==nil && net~>pins==nil && length(net~>allInstTerms)<=1 then + thisInst=dbFindAnyInstByName( cellView instName ) + if( thisInst==nil then printf( "Error: Inst %s does not exit.\n" instName ) + else + MasterRectList=nrFindInstPinShapes( thisInst pinName pinLPPs) + foreach( pinRectList MasterRectList + layerName=car(pinRectList) + pinRectList=cadr(pinRectList) + newNetShapes=foreach( mapcan thisRect pinRectList + list( nrConvertRectToPath( thisRect ?minWidth t ) ) ) + ) + foreach( returnPath newNetShapes + if(returnPath then + if( reportOnly then + fprintf(reportPort "Net %s: Dangling Node found at ( %s %L )\n" netName netName returnPath) + figCount=figCount+1 + else + pathpoints = PathRoundPointsToGrid( car(returnPath) ) + path=dbCreatePath( cellView list(layerName "drawing") pathpoints cadr(returnPath) "truncateExtend" ) + if( path then + dbAddFigToNet( path net ) + figCount=figCount+1 + else printf("Warning: no valid returnPath %L (net %s).\n" returnPath net->name) + ) + ) + ) + ) + + ) + ) + ) + if( reportOnly then + if( figCount == 0 then fprintf(reportPort "PASS: No dangling node found in cell %s.\n" cellView~>cellName) + else fprintf(reportPort "ERROR: %d dangling nodes found in cell %s.\n" figCount cellView~>cellName)) + else + dbSave( cellView ) + printf("Done: Total %d shapes added.\n" figCount) + ) + ) +) + +defun( nrCreateAbstractCB ( CellView + @key + (ERASE_POWERGRID t) + (PIN_CUTOUT 0.42) + (PIN_LENGTH 9.6) + (M1BLOAT -1.0) + (M2BLOAT -1.0) + (M3BLOAT -1.0) + (M4BLOAT 4.8) + (M5BLOAT 4.8) + (M6BLOAT 4.8) + (M7BLOAT 4.8) + (M8BLOAT 0.0) + (useAbstractSubcells t) + (keepLayoutSubcells t) + (PowerNets nil) + (M4PowerNets nil) + (M5PowerNets nil) + (M6PowerNets nil) + (M7PowerNets nil) + (PowerGridPitch PowerGridPitch) + (NO_HOLES_ABOVE_PINS nil) + (targetViewName "abstract") + (CDCPowerGrid nil) + (allbloat nil) + (labelPins t) + ) + + (let ( TEMP FulcrumPDKRoot RuleFileTemplate AssuraRuleFile p_in p_out) + + TEMP=ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + FulcrumPDKRoot=ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT") + RuleFileTemplate= sprintf( nil "%s/share/Fulcrum/cell_automation/abstract_mid.rul" + ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT" )) + if( !isFile(RuleFileTemplate) then + error(sprintf(nil "Do File Template %s does not exist!" RuleFileTemplate)) + ) + AssuraRuleFile=sprintf( nil "%s/%s_abstract.rul" TEMP CellView~>cellName ) + + p_in=infile(RuleFileTemplate) + if( !p_in then + errorMsg=sprintf( nil "Can Read File %s!\n" RuleFileTemplate) + error(errorMsg) + ) + p_out=outfile(AssuraRuleFile) + if( !p_out then + errorMsg=sprintf( nil "Can Write To File %s!\n" AssuraRuleFile) + error(errorMsg) + ) + + ; replace parameters of the template rul file + while( p_in && gets(line p_in) + cond( + ( rexMatchp( "^PIN_CUTOUT=" line) line=sprintf( nil "PIN_CUTOUT=%f\n" (float PIN_CUTOUT))) + ( rexMatchp( "^PIN_LENGTH=" line) line=sprintf( nil "PIN_LENGTH=%f\n" (float PIN_LENGTH))) + ( rexMatchp( "^M1BLOAT=" line) line=sprintf( nil "M1BLOAT=%f\n" (float M1BLOAT))) + ( rexMatchp( "^M2BLOAT=" line) line=sprintf( nil "M2BLOAT=%f\n" (float M2BLOAT))) + ( rexMatchp( "^M3BLOAT=" line) line=sprintf( nil "M3BLOAT=%f\n" (float M3BLOAT))) + ( rexMatchp( "^M4BLOAT=" line) line=sprintf( nil "M4BLOAT=%f\n" (float M4BLOAT))) + ( rexMatchp( "^M5BLOAT=" line) line=sprintf( nil "M5BLOAT=%f\n" (float M5BLOAT))) + ( rexMatchp( "^M6BLOAT=" line) line=sprintf( nil "M6BLOAT=%f\n" (float M6BLOAT))) + ( rexMatchp( "^M7BLOAT=" line) line=sprintf( nil "M7BLOAT=%f\n" (float M7BLOAT))) + ( rexMatchp( "^M8BLOAT=" line) line=sprintf( nil "M8BLOAT=%f\n" (float M8BLOAT))) + ( rexMatchp( "^CDCPowerGrid=" line) line=sprintf( nil "CDCPowerGrid=%s\n" + if( CDCPowerGrid "t" "nil"))) + ) + fprintf(p_out "%s" line) + ) + close(p_in) + close(p_out) + + printf( "Assura Rule File %s is created.\n" AssuraRuleFile) + + nrCreateMidAbstract(CellView~>libName CellView~>cellName CellView~>viewName + ?DeleteInstances t + ?DeleteDrawingLayers t + ?AssuraSets + setof( Set + list("DRAW_KEEPOUT" "KEEP_KEEPOUT" + when( ERASE_POWERGRID "ERASE_POWER_GRID") + when( NO_HOLES_ABOVE_PINS "NO_HOLES_ABOVE_PINS") + when( M4PowerNets "M4POWER_PIN" ) + when( M5PowerNets "M5POWER_PIN" ) + when( M6PowerNets "M6POWER_PIN" ) + when( M7PowerNets "M7POWER_PIN" ) + ) + stringp( Set ) ) + ?AssuraRuleFile AssuraRuleFile + ?maxPinLength PIN_LENGTH + ?useAbstractSubcells useAbstractSubcells + ?keepLayoutSubcells keepLayoutSubcells + ?PowerNets PowerNets + ?PowerGridPitch PowerGridPitch + ?targetViewName targetViewName + ?CDCPowerGrid CDCPowerGrid + ?allbloat allbloat + ?labelPins labelPins + ) + ) +) + +;;;;;;;;;;;;;;;;;;; Process abstract view before LEF export ;;;;;;;;;;;;;;;;;;;;;; + +; is this a M3/M5/M7 power stripe? +defun( isPowerStripe (fig) + prog((y1 y2 track) + if( or( fig~>layerName=="M3" fig~>layerName=="M5" fig~>layerName=="M7") then + y1=bottomEdge(fig~>bBox) + y2=topEdge(fig~>bBox) + track=round(y1/2.88) + if( y1>=track*2.88-0.18 && y2<=track*2.88+0.18 then return(t)) + ) + return(nil) + ) +) + +; Create an abstract_tmp view, deleting power stripes, converting power to keepout +defun( createAbstractTmp ( abstractView ) + let((abstractTmpView powerNets pin thisPin) + powerNets=list("Vdd" "GND") + ; allows this to work where the originating dfII dir is not writable +; this may not be compatible with later versions +; abstractTmpView=dbOpenCellViewByType( abstractView~>libName +; abstractView~>libName abstractView~>cellName "abstract_tmp" nil "s" ) + abstractTmpView=dbCopyCellView( abstractView + "abstract_tmp" abstractView~>cellName "abstract_tmp" nil nil t ) +; abstractTmpView=dbCopyCellView( abstractView +; abstractView~>libName abstractView~>cellName "abstract_tmp" nil nil t ) + foreach( pin abstractTmpView~>terminals + if( member( pin~>net~>name powerNets ) then + foreach( thisPin pin~>pins + if( isPowerStripe(thisPin~>fig) then + ; delete power pins that overlap power grid stripes + dbDeleteObject(thisPin~>fig) + else + ; turn other power pins into keepout + thisPin~>fig~>purpose="boundary" + ) + dbDeleteObject(thisPin) + ) + ) + ) + dbSave(abstractTmpView) + abstractTmpView + ) +) + +; Create abstract_tmp views for a list of abstract views +defun( copyViewToAbstractTmp (leflist pg_cellName) + let((p_in p_out line temp tempCV tempLib) + p_in=infile(leflist) + p_out=outfile(strcat( leflist ".tmp")) + tempLib=ddGetObj("abstract_tmp") + while( gets( line p_in ) + temp= parseString( StringUtilChompNewline(line) " ") + libName=car(temp) + cellName=cadr(temp) + viewName=caddr(temp) + cellView=nrOpenCellViewReadable(libName cellName viewName) + if(cellView then + if( tempLib == nil then + tempLib=dbCreateLib("abstract_tmp", strcat( ConfigFileGetValue( TheCDSConfigTable "TEMP" ) "/abstract_tmp")) + techBindTechFile(tempLib techGetTechLibName(ddGetObj(libName)))) + if( cellName then + tempCV=createAbstractTmp(cellView) + ; allows this to work where the originating dfII dir is not writable + fprintf( p_out "%s %s %s\n" tempCV~>libName tempCV~>cellName tempCV~>viewName) + else + fprintf( p_out "%s %s %s\n" libName cellName viewName) + ) + else + printf("Not Readable: %s %s %s\n" libName cellName viewName) + ) + ) + close(p_in) + close(p_out) + ) +) + +; Delete a list of abstract_tmp views +defun( deleteAbstractTmp (leflist) + let((p_in p_out line temp cv) + p_in=infile(leflist) + while( gets( line p_in ) + temp= parseString( StringUtilChompNewline(line) " ") + libName=car(temp) + cellName=cadr(temp) + cv=ddGetObj(libName cellName "abstract_tmp") + if( cv then ddDeleteObj(cv)) + ) + close(p_in) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/autopin.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/autopin.il new file mode 100644 index 0000000000..a711cdbfc5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/autopin.il @@ -0,0 +1,1614 @@ + ; Copyright 2002 Fulcrum Microsystems. All rights reserved. + ; $Id$ + ; $DateTime$ + ; $Author$ + + + + ;Label Info +(defun AutoPinMakeLabelInfo ( LPP ) + ( list LPP ) + ) + +(defun AutoPinGetLPPFromLabelInfo ( LabelInfo ) + ( car LabelInfo ) ) + + ; Rect Info +(defun AutoPinMakePinRectInfo ( LayerPurposePair BBox LabelInfo MakePin ObjType ) + ( list LayerPurposePair BBox LabelInfo MakePin ObjType ) ) + +(defun AutoPinGetLPPFromRectInfo ( RectInfo ) + ( car RectInfo ) ) + +(defun AutoPinGetRectFromRectInfo ( RectInfo ) + ( cadr RectInfo ) ) + +(defun AutoPinGetLabelInfoFromRectInfo ( RectInfo ) + ( caddr RectInfo ) ) + +(defun AutoPinGetMakePinFromRectInfo ( RectInfo ) + ( nth 3 RectInfo ) ) + +(defun AutoPinGetObjTypeFromRectInfo ( RectInfo ) + ( nth 4 RectInfo ) ) + + ;Pin Info +(defun AutoPinMakePinInfo ( NetName PinName RectInfoList InstanceInfoList @key (InPlace t) ) + ( list NetName PinName RectInfoList InstanceInfoList InPlace ) ) + +(defun AutoPinGetNetNameFromPinInfo ( PinInfo ) + ( car PinInfo ) ) + +(defun AutoPinGetPinNameFromPinInfo ( PinInfo ) + ( cadr PinInfo ) ) + +(defun AutoPinGetRectInfoListFromPinInfo ( PinInfo ) + ( caddr PinInfo ) ) + +(defun AutoPinGetInstanceInfoListFromPinInfo ( PinInfo ) + ( cadddr PinInfo ) ) + +(defun AutoPinGetInPlaceInfoFromPinInfo ( PinInfo ) + ( car ( cddddr PinInfo ) ) + ) + + ;InPlace Pin Info + +(defun AutoPinMakeInPlaceInfo ( LayerPurposePair BoundaryPolygonEdges MakePin ) + ( list LayerPurposePair BoundaryPolygonEdges MakePin ) ) + +(defun AutoPinMakeInPlacePinInfo ( NetName PinName InPlaceInfo ) + ( list NetName PinName nil nil InPlaceInfo ) ) + +(defun AutoPinIsInPlacePinInfo ( PinInfo ) + ( not ( equal ( AutoPinGetInPlaceInfoFromPinInfo PinInfo ) t ) ) ) + +(defun AutoPinGetLPPFromInPlacePinInfo ( InPlacePinInfo ) + ( car ( AutoPinGetInPlaceInfoFromPinInfo InPlacePinInfo ) ) ) + +(defun AutoPinGetBoundaryPolygonEdgesFromInPlacePinInfo ( InPlacePinInfo ) + ( cadr ( AutoPinGetInPlaceInfoFromPinInfo InPlacePinInfo ) ) ) + +(defun AutoPinGetMakePinFromInPlacePinInfo ( InPlacePinInfo ) + ( caddr ( AutoPinGetInPlaceInfoFromPinInfo InPlacePinInfo ) ) ) + + + ;reserved pitches +(defun AutoPinIsPitchReserved ( ReservedPitchTable Pitch ) + ( neq ( arrayref ReservedPitchTable Pitch ) `unbound ) + ) + + ; PinTable +(defun AutoPinQueuePinInfo ( PinTable PinInfo ) + ;( printf "%s\n" ( AutoPinGetNetNameFromPinInfo PinInfo ) ) + ( setarray PinTable ( AutoPinGetPinNameFromPinInfo PinInfo ) PinInfo ) ) + + ; Instance Info +(defun AutoPinMakeInstanceInfo ( LibraryName MasterName ViewName Suffix Location AlignObj LabelInfo MakePin PCellParams ) + ( list ( list LibraryName MasterName ViewName Suffix ) ( list Location AlignObj LabelInfo MakePin PCellParams ) ) ) + +(defun AutoPinGetLibraryNameFromInstanceInfo ( InstanceInfo ) + ( car ( car InstanceInfo ) ) ) + +(defun AutoPinGetMasterNameFromInstanceInfo ( InstanceInfo ) + ( cadr ( car InstanceInfo ) ) ) + +(defun AutoPinGetViewNameFromInstanceInfo ( InstanceInfo ) + ( caddr ( car InstanceInfo ) ) ) + +(defun AutoPinGetSuffixFromInstanceInfo ( InstanceInfo ) + ( cadddr ( car InstanceInfo ) ) ) + + +(defun AutoPinGetLocationFromInstanceInfo ( InstanceInfo ) + ( car ( cadr InstanceInfo ) ) ) + +(defun AutoPinGetAlignObjFromInstanceInfo ( InstanceInfo ) + ( cadr ( cadr InstanceInfo ) ) ) + +(defun AutoPinGetLabelInfoFromInstanceInfo ( InstanceInfo ) + ( caddr ( cadr InstanceInfo ) ) ) + +(defun AutoPinGetMakePinFromInstanceInfo ( InstanceInfo ) + ( cadddr ( cadr InstanceInfo ) ) ) + +(defun AutoPinGetPCellParamsFromInstanceInfo ( InstanceInfo ) + ( car ( cddddr ( cadr InstanceInfo ) ) ) ) + + + + ;Functions +(defun AutoPinGetName ( PinName Suffix RectCount ) + ( sprintf nil "%s.%s%d" PinName Suffix RectCount ) + ) + + +(defun AutoPinIsPinInNet (PinName NetName) + ( let ( + ( AppendedNetName ( strcat NetName ".") ) + ) + ( equal ( substring PinName 1 ( strlen AppendedNetName) ) AppendedNetName ) + ) + ) + + + +(defun AutoPinGetExistingPinTable ( TargetCellView ) + (let ( + ( AllPins ( PinUtilGetExistingPinFigs TargetCellView ) ) + ( ExistingPinTable ( makeTable `ExistingPinTable nil ) ) + ) + ( foreach Pin AllPins + (let ( + ( NetName ( getq ( getq Pin net ) name ) ) ) + (let ( + ( PinsInNet ( arrayref ExistingPinTable NetName ) ) + ) + ( setarray ExistingPinTable NetName ( cons Pin PinsInNet ) ) ) ) ) + ExistingPinTable ) ) + + +(defun AutoPinGetCellHeight ( BoundaryPolygonEdges XPosition) + (let ( + ( BoundaryBottomEdge ( PolygonGetBottomMostEdgeAtX BoundaryPolygonEdges XPosition ) ) + ( BoundaryTopEdge ( PolygonGetTopMostEdgeAtX BoundaryPolygonEdges XPosition ) ) + ) + (let ( + ( BoundaryBottom ( float ( LineGetSegmentMaxY BoundaryBottomEdge ) ) ) + ( BoundaryTop ( float ( LineGetSegmentMinY BoundaryTopEdge ) ) ) + ) + + ( MathRoundToNearest ( difference BoundaryTop BoundaryBottom ) 1e-4 ) ) ) ) + +(defun AutoPinGetCellWidth ( BoundaryPolygonEdges YPosition ) + (let ( + ( BoundaryLeftEdge ( PolygonGetLeftMostEdgeAtY BoundaryPolygonEdges YPosition ) ) + ( BoundaryRightEdge ( PolygonGetRightMostEdgeAtY BoundaryPolygonEdges YPosition ) ) + ) + (let ( + ( BoundaryLeft ( float ( LineGetSegmentMaxX BoundaryLeftEdge ) ) ) + ( BoundaryRight ( float ( LineGetSegmentMinX BoundaryRightEdge ) ) ) + ) + ( MathRoundToNearest ( difference BoundaryRight BoundaryLeft ) 1e-4 ) ) ) ) + + ;Instances +(defun AutoPinUpdateInstance ( Instance Location ) + ( dbSetq Instance Location xy ) + ) + +(defun AutoPinCreateInstance ( TargetCellView + InstanceInfo + InstanceName + ) + (cond ( + PCellParams + ( dbCreateParamInstByMasterName + TargetCellView + ( AutoPinGetLibraryNameFromInstanceInfo InstanceInfo ) + ( AutoPinGetMasterNameFromInstanceInfo InstanceInfo ) + ( AutoPinGetViewNameFromInstanceInfo InstanceInfo ) + InstanceName + ( AutoPinGetLocationFromInstanceInfo InstanceInfo ) + "R0" + 1 + ( AutoPinGetPCellParamsFromInstanceInfo InstanceInfo ) ) ) + ( + t + ( dbCreateInstByMasterName + TargetCellView + ( AutoPinGetLibraryNameFromInstanceInfo InstanceInfo ) + ( AutoPinGetMasterNameFromInstanceInfo InstanceInfo ) + ( AutoPinGetViewNameFromInstanceInfo InstanceInfo ) + InstanceName + ( AutoPinGetLocationFromInstanceInfo InstanceInfo ) + "R0" + 1 + ) ) ) ) + + + +(defun AutoPinCreateLabel ( TargetCellView LabelInfo NetName Fig ) + (let ( + ( Rect ( getq Fig bBox ) ) + ) + (when LabelInfo + (let ( + ( Text + ( dbCreateLabel + TargetCellView + ( AutoPinGetLPPFromLabelInfo LabelInfo ) + ( FigGetValidPoint Fig ) + NetName + "centerCenter" + "R0" + "stick" + ( min ( BBoxGetHeight Rect ) LeafPinLabelHeight ) + ) + ) + ) + ( dbSetq Text Fig parent ) ) ) ) ) + +(defun AutoPinUpdateLabel ( Label LabelInfo ) + ( dbSetq Label ( AutoPinGetLPPFromLabelInfo LabelInfo ) lpp ) ) + +(defun AutoPinCreateConnectivity ( TargetCellView NetName Fig ) + (let ( + ( Net ( dbMakeNet TargetCellView NetName ) ) ) + (let ( + ( Term (cond ( + ( getq Net term ) + ) + ( + ( dbCreateTerm Net NetName "inputOutput" ) ) ) ) ) + (let ( + ( Pin ( dbCreatePin Net Fig ) ) ) + ( dbSetq Pin (list "left" "right" "top" "bottom" ) accessDir ) ) ) ) ) + + + ; rod Rects +(defun AutoPinMoveShape ( Shape BBox ) + (let ( + ( OldBBox ( getq Shape bBox ) ) ) + ;move it ( so labels move ) + ( dbMoveFig Shape nil ( list ( list ( difference ( caar BBox ) ( caar OldBBox ) ) + ( difference ( cadar BBox ) ( cadar OldBBox ) ) + ) + "R0" + ) ) ) ) + +(defun AutoPinUpdateRodShape ( RodObject LPP BBox ) + (let ( + ( Shape ( getq RodObject dbId ) ) ) + ( dbSetq Shape BBox bBox ) + ( AutoPinMoveShape Shape BBox ) + ;reset lpp + ( dbSetq Shape LPP lpp ) + ) ) + +(defun AutoPinCreateRodShape ( TargetCellView PinName NetName LayerPP Rect ) + "Draws a rect and creates a pin that is strongly connected to other pins in the terminal" + ; draw the shape unless there's already a shape with the same name + (while ( not ( rodIsFigNameUnused PinName TargetCellView ) ) + ( setq PinName ( sprintf nil "%s.0" PinName ) ) ) + ( rodCreateRect + ?name PinName + ?layer LayerPP + ?bBox Rect + ?cvId TargetCellView + ) ) + +(defun AutoPinGetViaMasterName ( LibraryName MasterNameFormat Layer1 Layer2 ) + "guesses the name of the cellview master for a via connecting LPP1 to LPP2" + ( let ( + ( TestStrings ( list "METAL" "met" "M" ) ) + ( MasterName nil ) + ( MetalNum1 nil ) + ( MetalNum2 nil ) + ( Found nil ) + ) + (while TestStrings + ( sscanf Layer1 ( strcat ( car TestStrings ) "%d" ) MetalNum1 ) + ( sscanf Layer2 ( strcat ( car TestStrings ) "%d" ) MetalNum2 ) + (when ( and MetalNum1 MetalNum2 ) + (cond ( + ( ddGetObj LibraryName ( sprintf MasterName MasterNameFormat MetalNum1 MetalNum2 ) ) ) + ( + ( ddGetObj LibraryName ( sprintf MasterName MasterNameFormat MetalNum2 MetalNum1 ) ) ) ) ) + ( setq TestStrings ( cdr TestStrings ) ) + ) + MasterName + ) + ) + +(defun AutoPinMakeViaInstanceInfo ( LibraryName + MasterNameFormat + Suffix + ViewName + VerticalLayerPP + HorizontalLayerPP + Location + Width + Height + @key + ( Row 1 ) + ( Column 1 ) + ) + ( let ( + ( MasterName ( AutoPinGetViaMasterName LibraryName MasterNameFormat ( car HorizontalLayerPP) ( car VerticalLayerPP ) ) ) + ) + ( AutoPinMakeInstanceInfo + LibraryName + MasterName + ViewName + Suffix + Location + nil + nil + nil + ( list ( list "xPitch" "float" Width ) + ( list "yPitch" "float" Height ) + ( list "row" "int" Row ) + ( list "column" "int" Column ) + ) + ) + ) + ) + +(defun AutoPinUpdateInstanceInfoList ( TargetCellView NetName PinName InstanceInfoList PinInstancesInNet AddOnly ) + ( setq ExistingInstanceList nil ) + ( foreach PinInstance PinInstancesInNet + ( cond ( + ( AutoPinIsPinInNet ( getq PinInstance name ) PinName ) + ( setq ExistingInstanceList ( cons PinInstance ExistingInstanceList ) ) ) ) ) + + (let ( + ( CurrInstanceNum 0 ) + ) + ( foreach + InstanceInfo + InstanceInfoList + (let ( + ( InstanceName + ( AutoPinGetName + PinName + ( AutoPinGetSuffixFromInstanceInfo InstanceInfo ) + CurrInstanceNum ) ) ) + (let ( + ( Instance + ( dbFindAnyInstByName TargetCellView InstanceName ) ) ) + + (cond ( + ;if in list, it updates it and removes it from list + ( and + Instance + ( not AddOnly ) ) + ( AutoPinUpdateInstance + Instance + ( AutoPinGetLocationFromInstanceInfo InstanceInfo ) ) + ( setq ExistingInstanceList + ( remove Instance ExistingInstanceList ) ) + ) + ;if not in list, creates it + ( + ( not Instance ) + (let ( + ( Instance + ( AutoPinCreateInstance + TargetCellView + InstanceInfo + InstanceName ) ) ) + ( AutoPinCreateLabel + TargetCellView + ( AutoPinGetLabelInfoFromInstanceInfo InstanceInfo ) + NetName + Instance ) + (when ( AutoPinGetMakePinFromInstanceInfo InstanceInfo ) + ( AutoPinCreateConnectivity + TargetCellView + NetName + Instance ) + ) ) ) ) + ( setq CurrInstanceNum ( plus CurrInstanceNum 1 ) ) ) ) ) ) ) + + +(defun AutoPinUpdateRectInfoList ( TargetCellView + NetName + PinName + RectInfoList + PinShapesInNet + AddOnly + IsInPlace + ) + + ;looks for all rodObjects with name PinName.* and puts them in a list + (let ( + ( ExistingPinTable + ( makeTable `foo nil ) ) ) + ( foreach Pin PinShapesInNet + (let ( + ( RodObject ( rodGetObj Pin ) ) + ) + (when ( and + RodObject + ( AutoPinIsPinInNet ( getq RodObject name ) PinName ) ) + ( setarray ExistingPinTable ( getq RodObject name ) RodObject ) ) ) ) + (let ( + ( CurrRectNum 0 ) + ) + ( foreach + RectInfo + RectInfoList + (let ( + ( PinName ( AutoPinGetName PinName "" CurrRectNum ) ) + ) + (let ( + ( RodObject ( rodGetObj PinName TargetCellView ) ) + ) + (cond ( + ;if in list, it update it and remove it from list + ( and RodObject + ( not AddOnly ) ) + ( AutoPinUpdateRodShape + RodObject + ( AutoPinGetLPPFromRectInfo RectInfo ) + ( AutoPinGetRectFromRectInfo RectInfo ) + ) + (let ( + ( Label ( car ( exists Label ( getq ( getq RodObject dbId ) children ) + ( PinUtilIsLabelForNetName Label NetName ) ) ) ) ) + (if ( AutoPinGetLabelInfoFromRectInfo RectInfo ) + (if ( null Label ) + ( AutoPinCreateLabel + TargetCellView + ( AutoPinGetLabelInfoFromRectInfo RectInfo ) + NetName + ( getq RodObject dbId ) ) + ( AutoPinUpdateLabel + Label + ( AutoPinGetLabelInfoFromRectInfo RectInfo ) ) ) + (if Label + ( dbDeleteObject Label ) ) ) ) + (let ( + ( Pin ( getq ( getq RodObject dbId ) pin ) ) ) + (if Pin + (if ( null ( AutoPinGetMakePinFromRectInfo RectInfo ) ) + ( dbDeleteObject Pin ) ) ) ) + ( remove PinName ExistingPinTable ) ) + ;if not in list, creates it + ( + ( not RodObject ) + (let ( + ( RodRect + ( AutoPinCreateRodShape + TargetCellView + PinName + NetName + ( AutoPinGetLPPFromRectInfo RectInfo ) + ( AutoPinGetRectFromRectInfo RectInfo ) ) ) ) + + ( AutoPinCreateLabel + TargetCellView + ( AutoPinGetLabelInfoFromRectInfo RectInfo ) + NetName + ( getq RodRect dbId ) ) + (when ( AutoPinGetMakePinFromRectInfo RectInfo ) + (if IsInPlace then + (dbReplaceProp (getq RodRect dbId) "PinType" "string" "InPlace") + else + (dbReplaceProp (getq RodRect dbId) "PinType" "string" "UserPin") + ) + ( AutoPinCreateConnectivity + TargetCellView + NetName + ( getq RodRect dbId ) ) + ) ) ) ) + ( setq CurrRectNum ( plus CurrRectNum 1 ) ) ) ) ) ) + + ;deletes all remaining corresponding rodObjects in list + (when ( not AddOnly ) + ( foreach ExistingPin + ( mapcar `cadr ( tableToList ExistingPinTable ) ) + ( dbDeleteObject ( getq ExistingPin dbId ) ) ) + ) ) ) + +(defun AutoPinUpdatePinInfo ( PinInfo + TargetCellView + ConnectivityCellView + LayoutInstanceMap + ExistingPinTable + DrawFigs + AddOnly + MetalLayerRegEx + ViaLayerRegEx + LogPort ) + (cond ( + ( and ( AutoPinIsInPlacePinInfo PinInfo ) + ( AutoPinGetInPlaceInfoFromPinInfo PinInfo ) ) + ( setq PinInfo ( AutoPinMakePinInfoFromInPlacePinInfo + ( AutoPinGetNetNameFromPinInfo PinInfo ) + ( AutoPinGetPinNameFromPinInfo PinInfo ) + TargetCellView + ConnectivityCellView + LayoutInstanceMap + ( AutoPinGetBoundaryPolygonEdgesFromInPlacePinInfo PinInfo ) + MetalLayerRegEx + ViaLayerRegEx + ?MakeLabel t + ?MakePin ( AutoPinGetMakePinFromInPlacePinInfo PinInfo ) + ?LogPort LogPort ) ) ) ) + ( AutoPinUpdatePinInfoSimple PinInfo TargetCellView ExistingPinTable DrawFigs AddOnly) ) + +(defun AutoPinUpdatePinInfoSimple ( PinInfo + TargetCellView + ExistingPinTable + DrawFigs + AddOnly ) + (if DrawFigs + (let ( + ( PinName ( AutoPinGetPinNameFromPinInfo PinInfo ) ) + ( NetName ( AutoPinGetNetNameFromPinInfo PinInfo ) ) + ( RectInfoList ( AutoPinGetRectInfoListFromPinInfo PinInfo ) ) + ( IsInPlace ( AutoPinGetInPlaceInfoFromPinInfo PinInfo ) ) + ( InstanceInfoList ( AutoPinGetInstanceInfoListFromPinInfo PinInfo ) ) + ) + ( AutoPinUpdateRectInfoList + TargetCellView + NetName + PinName + RectInfoList + ( setof Fig ( arrayref ExistingPinTable NetName ) ( equal ( getq Fig "objType" ) "rect" ) ) + AddOnly + IsInPlace + ) + ( AutoPinUpdateInstanceInfoList + TargetCellView + NetName + PinName + InstanceInfoList + ( setof Fig ( arrayref ExistingPinTable NetName ) ( equal ( getq Fig "objType" ) "inst" ) ) + AddOnly + ) ) ) ) + + +(defun AutoPinUpdateQueuedPins ( PinTable + TargetCellView + ConnectivityViewName + FoldableCellLibCellRegExPairs + MetalLayerRegEx + ViaLayerRegEx + @key + ( DrawFigs t ) + ( AddOnly nil ) + ( LogPort poport ) + ) + (let ( + ( ExistingPinTable ( AutoPinGetExistingPinTable TargetCellView ) ) + ( ConnectivityCellView ( dbOpenCellViewByType + ( getq TargetCellView libName ) + ( getq TargetCellView cellName ) + ConnectivityViewName + nil + "r" ) ) ) + (when ConnectivityCellView + (let ( + ( LayoutInstanceMap ( NameMakeInstanceMapFromCellView + TargetCellView + FoldableCellLibCellRegExPairs ) ) ) + ( foreach + PinName + PinTable + (let ( + ( CurrPinInfo ( arrayref PinTable PinName ) ) + ) + ( AutoPinUpdatePinInfo + CurrPinInfo + TargetCellView + ConnectivityCellView + LayoutInstanceMap + ExistingPinTable + DrawFigs + AddOnly + MetalLayerRegEx + ViaLayerRegEx + LogPort ) ) ) ) ) ) ) + +(defun AutoPinUpdateQueuedPinsSimple ( PinTable + TargetCellView + @key + ( DrawFigs t ) + ( AddOnly nil ) + ) + (let ( + ( ExistingPinTable ( AutoPinGetExistingPinTable TargetCellView ) ) ) + ( foreach + PinName + PinTable + (let ( + ( CurrPinInfo ( arrayref PinTable PinName ) ) + ) + ( AutoPinUpdatePinInfoSimple + CurrPinInfo + TargetCellView + ExistingPinTable + DrawFigs + AddOnly + ) ) ) ) ) + + +(defun AutoPinGetHorizontalPinBottomAndTop ( PitchIndex + WidthInPitches + WireWidth + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinSpacing + XPosition + ManufacturingGrid ) + (let ( + ( BoundaryBottomEdge ( PolygonGetBottomMostEdgeAtX BoundaryPolygonEdges XPosition ) ) ) + (let ( + ( BoundaryBottom ( float ( LineGetSegmentMaxY BoundaryBottomEdge ) ) ) + ) + (let ( + ( PinBottom + ( MathRoundToNearest + ( plus + BoundaryBottom + BoundaryPinSpacing + ( times PitchIndex WirePitch ) + ( times 0.5 WireSpacing ) ) + ManufacturingGrid + ) ) ) + ( list + PinBottom + ( plus PinBottom WireWidth ) ) ) ) ) ) + + + +(defun AutoPinMakeLeftPinRectInfo ( PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + @key ( MakeLabel t ) + ) + (let ( + ( BoundaryLeft + ( LineGetSegmentMaxX + ( PolygonGetLeftMostEdge BoundaryPolygonEdges ) ) ) ) + (let ( + ( PinBottomTop ( AutoPinGetHorizontalPinBottomAndTop + PitchIndex + 1 + PinWidth + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinVerticalSpacing + BoundaryLeft + ManufacturingGrid + ) ) ) + (let ( + ( PinLeft ( plus BoundaryLeft BoundaryPinHorizontalSpacing ) ) + ( PinBottom ( car PinBottomTop ) ) + ( PinTop ( cadr PinBottomTop ) ) ) + (let ( + ( PinRight ( plus PinLeft PinLength ) ) + ( LabelInfo ( cond ( + MakeLabel + ( AutoPinMakeLabelInfo + ( list ( car LayerPurposePair ) "drawing" ) + ) + ) + ( + nil + ) + ) + ) + ) + (let ( + ( Rect ( list + ( list PinLeft PinBottom ) + ( list PinRight PinTop ) + ) ) ) + ( AutoPinMakePinRectInfo + LayerPurposePair + Rect + LabelInfo + t + "rect" + ) ) ) ) ) ) ) + +(defun AutoPinMakeRightPinRectInfo ( PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + @key ( MakeLabel t ) + ) + (let ( + ( BoundaryRight + ( LineGetSegmentMinX + ( PolygonGetRightMostEdge BoundaryPolygonEdges ) ) ) ) + (let ( + ( PinBottomTop ( AutoPinGetHorizontalPinBottomAndTop + PitchIndex + 1 + PinWidth + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinVerticalSpacing + BoundaryRight + ManufacturingGrid + ) ) ) + (let ( + ( PinRight ( difference BoundaryRight BoundaryPinHorizontalSpacing ) ) + ( PinBottom ( car PinBottomTop ) ) + ( PinTop ( cadr PinBottomTop ) ) ) + (let ( + ( PinLeft ( difference PinRight PinLength ) ) + ( LabelInfo ( cond ( + MakeLabel + ( AutoPinMakeLabelInfo + ( list ( car LayerPurposePair ) "drawing" ) + ) + ) + ( + nil + ) + ) + ) + ) + (let ( + ( Rect ( list + ( list PinLeft PinBottom ) + ( list PinRight PinTop ) + ) ) ) + ( AutoPinMakePinRectInfo + LayerPurposePair + Rect + LabelInfo + t + "rect" + ) ) ) ) ) ) ) + + +(defun AutoPinMakeHorizontalStrutRectInfo (PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ReservedPitchTable + @key + ( MakeLabel t ) + ) + "returns a RectInfo representing a horizontal strut" + ;assume a horizontal strut can be drawn from left to right edge + ;reserve pitches + (let ( + ;width + spacing <= pitch * n + ;n = ceiling ( w+s / p ) + ( WidthInPitches ( ceiling ( quotient ( plus PinWidth WireSpacing ) WirePitch ) ) ) + ( BoundaryLeft + ( LineGetSegmentMaxX + ( PolygonGetLeftMostEdge BoundaryPolygonEdges ) ) ) + ( BoundaryRight + ( LineGetSegmentMinX + ( PolygonGetRightMostEdge BoundaryPolygonEdges ) ) ) + ) + (if ReservedPitchTable + ( for I PitchIndex ( plus PitchIndex ( difference WidthInPitches 1 ) ) + ( setarray ReservedPitchTable I t ) + ) ) + (let ( + ( PinBottomTop ( AutoPinGetHorizontalPinBottomAndTop + PitchIndex + WidthInPitches + PinWidth + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinVerticalSpacing + ( caar + ( PolygonGetBottomMostEdge + BoundaryPolygonEdges ) ) + ManufacturingGrid + + ) ) ) + (let ( + ( LeftAndRight ( PolygonGetHorizontalLeftAndRightBoundaryFromBottomAndTop + PinBottomTop + BoundaryPolygonEdges ) ) ) + (let ( + ( BoundaryLeft ( car LeftAndRight ) ) + ( BoundaryRight ( cadr LeftAndRight ) ) ) + (let ( + ( PinLeft ( plus BoundaryLeft BoundaryPinHorizontalSpacing ) ) + ( PinRight ( difference BoundaryRight BoundaryPinHorizontalSpacing ) ) + ( PinBottom ( car PinBottomTop ) ) + ( PinTop ( cadr PinBottomTop ) ) + ) + (let ( + ( LabelInfo ( cond ( + MakeLabel + ( AutoPinMakeLabelInfo + ( list ( car LayerPurposePair ) "drawing" ) ) ) + ( nil ) ) ) + ( Rect ( list + ( list PinLeft PinBottom ) + ( list PinRight PinTop ) ) ) ) + ( AutoPinMakePinRectInfo + LayerPurposePair + Rect + LabelInfo + t + "rect" + ) ) ) ) ) ) ) ) + + +(defun AutoPinCalculateNumHorizontalWirePitches ( BoundaryPolygonEdges + WirePitch + WirePitchOffset ) + ( floor + ( quotient + ( difference + ( plus + 1e-9 + ( PolygonGetHeight + BoundaryPolygonEdges ) ) + WirePitchOffset ) + WirePitch ) ) ) + +(defun AutoPinCalculateNumVerticalWirePitches ( BoundaryPolygonEdges + WirePitch + WirePitchOffset + ) + ( floor + ( quotient + ( difference + ( plus + 1e-9 + ( PolygonGetWidth + BoundaryPolygonEdges ) ) + WirePitchOffset + ) + WirePitch ) ) ) + +(defun AutoPinMakePowerGridRectAndInstanceInfoLists ( + NetName + GridOffset + GridSpacing + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ReservedPitchTable + ) + "returns a list of RectInfo's for the power grid" + + (let ( + ( CurrentPitch GridOffset) + ( RectInfoList nil ) + ( InstanceInfoList nil ) + ( WidthInPitches ( ceiling ( quotient ( plus PinWidth WireSpacing ) WirePitch ) ) ) + ( NumPitchesInCell ( AutoPinCalculateNumHorizontalWirePitches + BoundaryPolygonEdges + WirePitch + 0.0 ) ) + ( MakeLabel t ) ) + ; horizontal struts + ( while ( leqp ( plus CurrentPitch WidthInPitches ) NumPitchesInCell ) + if( CurrentPitch==-1 then + ( setq RectInfoList ( cons ( AutoPinMakeHorizontalStrutRectInfo + -2 + LayerPurposePair + PinWidth/2 + PinLength + WireSpacing + WirePitch/8 + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ReservedPitchTable + ?MakeLabel MakeLabel + ) + RectInfoList ) ) + ( setq RectInfoList ( cons ( AutoPinMakeHorizontalStrutRectInfo + NumPitchesInCell*8-8 + LayerPurposePair + PinWidth/2 + PinLength + WireSpacing + WirePitch/8 + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ReservedPitchTable + ?MakeLabel nil + ) + RectInfoList ) ) + else + ( setq RectInfoList ( cons ( AutoPinMakeHorizontalStrutRectInfo + CurrentPitch + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ReservedPitchTable + ?MakeLabel MakeLabel + ) + RectInfoList ) ) + ) + ( setq MakeLabel nil ) + ( setq CurrentPitch ( plus CurrentPitch GridSpacing ) ) ) + ( list RectInfoList InstanceInfoList ) ) ) + +(defun AutoPinQueuePin ( PinTable + NetName + BBox + LayerPurposePair + @key + ( CreateRectInfo t ) + ( MakeLabel t ) + ( InPlace t ) + ) + + (let ( + ( LabelInfo + (if MakeLabel + ( AutoPinMakeLabelInfo + ( list ( car LayerPurposePair ) "drawing" ) ) ) ) ) + ( AutoPinQueuePinInfo + PinTable + ( AutoPinMakePinInfo + NetName + ( EscapeString NetName ) + (if CreateRectInfo + ( list ( AutoPinMakePinRectInfo + LayerPurposePair + BBox + LabelInfo + t + "rect" ) ) ) + nil + ?InPlace InPlace + ) ) ) ) + + +(defun AutoPinQueueLeftPin ( PinTable + PitchIndex + NetName + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + @key ( CreateRectInfo t ) + ( Strut nil ) + ) + + ( AutoPinQueuePinInfo + PinTable + ( AutoPinMakePinInfo + NetName + ( EscapeString NetName ) + (if CreateRectInfo + ( list + (if Strut + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeHorizontalStrutRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + nil + ) + + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeLeftPinRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ) ) ) ) + nil ) ) ) + + +(defun AutoPinQueueRightPin ( PinTable + PitchIndex + NetName + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + @key + ( CreateRectInfo t ) + ( Strut nil ) + ) + ( AutoPinQueuePinInfo + PinTable + ( AutoPinMakePinInfo + NetName + ( EscapeString NetName ) + (if CreateRectInfo + ( list + (if Strut + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeHorizontalStrutRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + nil + ) + + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeRightPinRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ) ) + ) ) + nil ) ) ) + + +(defun AutoPinQueuePowerGrid ( PinTable + NetName + GridOffset + GridSpacing + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + @key + ( CreateRectInfo t ) + ) + "enqueues a power grid pinInfo in the PinTable" + (let ( + ( RectAndInstanceInfoLists + (if CreateRectInfo + ( CacheGetValue + FunctionCacheTable + `AutoPinMakePowerGridRectAndInstanceInfoLists + NetName + GridOffset + GridSpacing + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ReservedPitchTable + ) ) ) ) +; ( AutoPinQueuePinInfo +; PinTable +; ( AutoPinMakePinInfo +; NetName +; ( EscapeString NetName ) +; ( car RectAndInstanceInfoLists ) +; ( cadr RectAndInstanceInfoLists ) +; ) ) +t +) ) + +(defun AutoPinQueueHorizontalStrut ( PinTable + PitchIndex + NetName + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + @key + ( CreateRectInfo t ) + ) + "enqueues a horizontal strut pin of a given width" + ( AutoPinQueuePinInfo + PinTable + ( AutoPinMakePinInfo + NetName + ( EscapeString NetName ) + (if CreateRectInfo + ( list + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeHorizontalStrutRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ReservedPitchTable + ) + ) ) + nil ) ) ) + +(defun AutoPinQueueLeftRightPin ( PinTable + PitchIndex + NetName + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + @key + ( CreateRectInfo t ) + ( Strut nil ) + ) + "enqueues a pin on the left and right connected to the same net" + + ( AutoPinQueuePinInfo + PinTable + ( AutoPinMakePinInfo + NetName + ( EscapeString NetName ) + ( cond ( CreateRectInfo + (if Strut + ( list + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeHorizontalStrutRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + nil + ) ) + ( list + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeLeftPinRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ?MakeLabel t + ) + + ( CacheGetValue + FunctionCacheTable + `AutoPinMakeRightPinRectInfo + PitchIndex + LayerPurposePair + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + ?MakeLabel nil + ) + ) + ) + ) + ( nil ) + ) + nil + ) + ) + ;reserve pitch + ( setarray ReservedPitchTable PitchIndex t ) + ) + +(defun AutoPinQueueInPlacePin ( PinTable + NetName + LayerPurposePair + BoundaryPolygonEdges + @key ( CreateRectInfo t ) + ( MakePin t ) + ) + ( AutoPinQueuePinInfo + PinTable + ( AutoPinMakeInPlacePinInfo + NetName + ( EscapeString NetName ) + (if CreateRectInfo + ( AutoPinMakeInPlaceInfo + LayerPurposePair + BoundaryPolygonEdges + MakePin ) ) ) ) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; InPlace +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun AutoPinLayerValue ( LPP MetalRegEx ) + (cond ( + ( rexMatchp MetalRegEx ( car LPP ) ) + ( difference 0 ( atoi ( rexSubstitute "\\1" ) ) ) ) + ( + t + 0 ) ) ) + +(defun AutoPinPreferredLayerTest ( LPP1 LPP2 MetalRegEx ) + ( difference ( AutoPinLayerValue LPP1 MetalRegEx ) + ( AutoPinLayerValue LPP2 MetalRegEx ) ) ) + +(defun AutoPinBBoxValue ( BBox BoundaryPolygonEdges ) + ;lower is better + ( AutoPinGetMinDistanceFromBoundaryPolygonEdges + BoundaryPolygonEdges + ( BBoxGetPolygonEdges BBox ) ) ) + +(defun AutoPinPreferredBBoxTest ( BBox1 BBox2 BoundaryPolygonEdges ) + ( difference ( AutoPinBBoxValue BBox1 BoundaryPolygonEdges ) + ( AutoPinBBoxValue BBox2 BoundaryPolygonEdges ) ) ) + +(defun AutoPinTypeValue ( Type ) + (cond + ( + ( equal Type "label" ) + 5 + ) + ( + ( equal Type "donut" ) + 4 + ) + ( + ( equal Type "polygon" ) + 3 + ) + ( + ( equal Type "path" ) + 2 + ) + ( + ( equal Type "inst" ) + 1 + ) + ( + ( equal Type "rect" ) + 0 + ) ) ) + +(defun AutoPinPreferredTypeTest ( Type1 Type2 ) + if( Type1=="label" || Type2=="label" then -1 + else + ( difference ( AutoPinTypeValue Type1 ) + ( AutoPinTypeValue Type2 ) ) ) ) + +(defun AutoPinMakePinInfoFromInPlacePinInfo ( NetName + PinName + TargetCellView + ConnectivityCellView + LayoutInstanceMap + BoundaryPolygonEdges + MetalLayerRegEx + ViaLayerRegEx + @key + ( MakeLabel t ) + ( MakePin t ) + ( LogPort poport ) + ) + (let ( + ( PinInstancePairs ( PinUtilGetConnectedPinInstancePairs_2 + ConnectivityCellView + TargetCellView + LayoutInstanceMap + NetName ) ) ) + ; get a list of all pin-instance pairs + (let ( + ( PinInfos ( mapcar + (lambda ( PinInstancePair ) + ( AutoPinGetPinInfoFromPinFigForceRect + ( getq ( car PinInstancePair ) fig ) + ViaLayerRegEx + ?ParentInstance ( cadr PinInstancePair ) + ?MakePin MakePin ) ) + PinInstancePairs ) ) ) + (let ( + ( ClosestPinToBoundaryPinInfo + ( ListFindBestElement + PinInfos + (lambda ( PinInfo1 PinInfo2 ) + (let ( + ( PinRectInfo1 ( car ( AutoPinGetRectInfoListFromPinInfo PinInfo1 ) ) ) + ( PinRectInfo2 ( car ( AutoPinGetRectInfoListFromPinInfo PinInfo2 ) ) ) ) + (let ( + ( LayerPreference + ( AutoPinPreferredLayerTest + ( AutoPinGetLPPFromRectInfo PinRectInfo1 ) + ( AutoPinGetLPPFromRectInfo PinRectInfo2 ) + MetalLayerRegEx + ) ) ) + (if ( lessp LayerPreference 0 ) + t + (if ( greaterp LayerPreference 0 ) + nil + (let ( + ( TypePreference ( AutoPinPreferredTypeTest + ( AutoPinGetObjTypeFromRectInfo PinRectInfo1 ) + ( AutoPinGetObjTypeFromRectInfo PinRectInfo1 ) ) ) ) + (if ( lessp TypePreference 0 ) + t + (if ( greaterp TypePreference 0 ) + nil + (let ( + ( BBoxPreference + ( AutoPinPreferredBBoxTest + ( AutoPinGetRectFromRectInfo PinRectInfo1 ) + ( AutoPinGetRectFromRectInfo PinRectInfo2 ) + BoundaryPolygonEdges ) ) ) + (if ( lessp BBoxPreference 0 ) + t + nil ) ) ) ) ) ) ) ) ) ) + nil + ) ) ) + (if ( null ClosestPinToBoundaryPinInfo ) + ( fprintf LogPort "WARNING: No underlying pin for net : %s\n" NetName ) + ;use net name given, not underlying net name + ( fprintf LogPort "made pin for %s on layer %s %s\n" + NetName + ( car ( AutoPinGetLPPFromRectInfo ( car ( AutoPinGetRectInfoListFromPinInfo ClosestPinToBoundaryPinInfo ) ) ) ) + ( cadr ( AutoPinGetLPPFromRectInfo ( car ( AutoPinGetRectInfoListFromPinInfo ClosestPinToBoundaryPinInfo ) ) ) ) ) ) + + ( AutoPinMakePinInfo + NetName + PinName + ( AutoPinGetRectInfoListFromPinInfo ClosestPinToBoundaryPinInfo ) + ( AutoPinGetInstanceInfoListFromPinInfo ClosestPinToBoundaryPinInfo ) ) ) ) ) ) + + ;only left or right edges count +(defun AutoPinGetMinDistanceFromBoundaryPolygonEdges ( BoundaryPolygonEdges PolygonEdges ) + ( let ( + ( BoundaryLeftEdge ( PolygonGetLeftMostEdge BoundaryPolygonEdges ) ) + ( BoundaryRightEdge ( PolygonGetRightMostEdge BoundaryPolygonEdges ) ) + ( LeftEdge ( PolygonGetLeftMostEdge PolygonEdges ) ) + ( RightEdge ( PolygonGetRightMostEdge PolygonEdges ) ) + ) + ( let ( + ( DistLeft ( AutoPinGetMinDistanceBetweenEdges BoundaryLeftEdge LeftEdge ) ) + ( DistRight ( AutoPinGetMinDistanceBetweenEdges BoundaryRightEdge RightEdge ) ) + ) + ( min DistLeft DistRight ) + ) + ) + ) + + ;TODO - make a better algorithm, +(defun AutoPinGetMinDistanceBetweenEdges ( Edge1 Edge2 ) + ( let ( + ( Point11 ( car Edge1 ) ) + ( Point12 ( cadr Edge1 ) ) + ( Point21 ( car Edge2 ) ) + ( Point22 ( cadr Edge2 ) ) + ) + ( let ( + ( Segment11 ( list Point11 ( LineGetClosestPointOnSegmentToPoint Point11 Edge2 ) ) ) + ( Segment12 ( list Point12 ( LineGetClosestPointOnSegmentToPoint Point12 Edge2 ) ) ) + ( Segment21 ( list Point21 ( LineGetClosestPointOnSegmentToPoint Point21 Edge1 ) ) ) + ( Segment22 ( list Point22 ( LineGetClosestPointOnSegmentToPoint Point22 Edge1 ) ) ) + ) + ( min ( LineGetSegmentLength Segment11 ) + ( LineGetSegmentLength Segment12 ) + ( LineGetSegmentLength Segment21 ) + ( LineGetSegmentLength Segment22 ) + ) + ) + ) + ) + +(defun AutoPinGetSmallestBoundingShape ( TargetCellView + Shape + @key + ( LPPPredicate (lambda ( x ) t ) ) ) + (let ( + ( Rect ( getq Shape bBox ) ) ) + (if ( not ( BBoxIsPoint Rect ) ) + Shape + (let ( + ( MinArea 1000000000 ) + ( MinShape nil ) ) + ( foreach Shape ( getq TargetCellView shapes ) + (when ( apply LPPPredicate ( list ( getq Shape lpp ) ) ) + (let ( + ( ShapeRect ( getq Shape bBox ) ) ) + (if ( RectIsRectInRect Rect ShapeRect ) + (let ( + ( ShapeArea ( RectGetArea ShapeRect ) ) ) + (cond ( + ( and ( not ( eqv ShapeArea 0.0 ) ) ( lessp ShapeArea MinArea ) ) + ( setq MinArea ShapeArea ) + ( setq MinShape Shape ) ) ) ) ) ) ) ) + MinShape ) ) ) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Existing Pin Info +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;HACK +(defun AutoPinGetExistingPinInfosForceRect ( TargetCellView ViaLayerRegEx ) + "returns a list of pininfos for each existing pin in cellview " + ( mapcar (lambda ( PinFig ) ( AutoPinGetPinInfoFromPinFigForceRect PinFig ViaLayerRegEx ) ) + ( PinUtilGetExistingPinFigs TargetCellView ) ) ) + +(defun AutoPinGetPinInfoFromPinFigForceRect ( Fig + ViaLayerRegEx + @key + ( ParentInstance nil ) + ( MakePin t ) ) + + (cond ( + ;instance pins + ( equal ( getq Fig objType ) "inst" ) + ( AutoPinGetPinInfoFromPinInstanceForceRect + Fig + ViaLayerRegEx + ?ParentInstance ParentInstance + ?MakePin MakePin ) + ) + ( + ;shape pins + ( AutoPinGetPinInfoFromPinShape + Fig + ViaLayerRegEx + ?ParentInstance ParentInstance + ?MakePin MakePin ) ) ) ) + +(defun AutoPinGetPinInfoFromPinShape ( Shape + ViaLayerRegEx + @key + ( ParentInstance nil ) + ( MakePin t ) + ) + + (let ( + ;use the smallest bounding shape in the parent instance + ( InPlaceShape + (if ParentInstance + ( AutoPinGetSmallestBoundingShape + ( getq ParentInstance master ) Shape ) + Shape ) ) ) + (let ( + ( BBox + (if ParentInstance + ( dbTransformBBox + ( FigGetRectInsideFig InPlaceShape ) + ( getq ParentInstance transform ) ) + ( FigGetRectInsideFig InPlaceShape ) ) ) + ( LayerPurposePair ( getq InPlaceShape lpp ) ) ) + + ( AutoPinMakePinInfo + ( getq ( getq Shape net ) name ) + ( EscapeString ( getq ( getq Shape net ) name ) ) + ( list + ( AutoPinMakePinRectInfo + ( PinUtilGetValidLayer LayerPurposePair ViaLayerRegEx ) + BBox + ( AutoPinMakeLabelInfo + ( list + ( car + ( PinUtilGetValidLayer LayerPurposePair ViaLayerRegEx ) ) + "drawing" ) ) + MakePin + ( getq InPlaceShape objType ) + ) ) + nil ) ) ) ) + +(defun AutoPinGetPinInfoFromPinInstanceForceRect ( Instance + ViaLayerRegEx + @key + ( ParentInstance nil ) + ( MakePin t ) + ) + (let ( + ;get the first pin shape in the instance + ( PinShape ( car ( exists Shape ( getq ( getq Instance master ) shapes ) ( getq Shape pin ) ) ) ) ) + (let ( + ; get the bounding shape in the instance + ( InPlaceShape ( AutoPinGetSmallestBoundingShape ( getq Instance master ) PinShape ) ) ) + (let ( + ( NetName ( getq ( getq ( getq Instance pin ) net ) name ) ) + ( LayerPurposePair ( getq InPlaceShape lpp ) ) + ;transform into parent instance coordinates + ( BBox ( dbTransformBBox ( FigGetRectInsideFig InPlaceShape ) ( getq Instance transform ) ) ) ) + (let ( + ;transform into cellview coordinates + ( BBox (if ParentInstance + ( dbTransformBBox BBox ( getq ParentInstance transform ) ) + BBox ) ) ) + ( AutoPinMakePinInfo + NetName + ( EscapeString NetName ) + ( list ( AutoPinMakePinRectInfo + ( PinUtilGetValidLayer LayerPurposePair ViaLayerRegEx ) + BBox + ( AutoPinMakeLabelInfo + ( list + ( car + ( PinUtilGetValidLayer LayerPurposePair ViaLayerRegEx ) ) + "drawing" ) ) + MakePin + "inst" + ) ) + nil ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/canonicalize.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/canonicalize.il new file mode 100644 index 0000000000..58db99d04b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/canonicalize.il @@ -0,0 +1,123 @@ + +(defun CanonicalizeLoadTable (castCell @key (tempdir nil) ) + (let (mapfile table Command) + (cond (tempdir==nil tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) ) + mapfile = strcat( tempdir "/" castCell ".canon.il" ) + (when !(isFile mapfile) && tempdir!=nil && (ConfigFileGetValue TheCDSConfigTable "CAST_PATH")!=nil + Command=sprintf( nil + "cast2skill --cadence-name --cast-path=%s --cell=%s --output-dir=%s --cadence-name --root-only --max-heap-size=%dM --64" + ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) + castCell + tempdir + ( nrGetMaxHeapSize ) + ) + (shell Command) + ) + (if (isFile mapfile) then + (load mapfile) + table = (PinCanonicalTable) + else + table = nil + (printf "Cast didn't parse.") + ) + table + ) +) + +(defun CanonicalizePins ( @key (cv (geGetEditCellView)) + (tempdir (ConfigFileGetValue TheCDSConfigTable "TEMP")) + (castCell nil)) + (let (table pinname canon allpins pincount renamecount ) + (cond (castCell==nil castCell=cv->cellName)) + table = (CanonicalizeLoadTable castCell ?tempdir tempdir ) + pincount=0 + renamecount=0 + + allpins = (PinUtilGetExistingPinFigs cv) + (when table + (foreach pin allpins + pinname = pin->net->name + (when pinname + pincount=pincount+1 + canon = (arrayref table pinname) + (when canon!=nil && canon!=pinname + (PinUtilRenamePin cv pin canon) + (dbReplaceProp pin "CanonicalizedFrom" "string" pinname) + renamecount=renamecount+1 + ) + ) + ) + ) + (DeleteUnusedNets) + (printf "Renamed %d of %d pins.\n" renamecount pincount) + ) +) + +defun( CreatePinShapes ( CellView ) + let((pinShapes label shape net n u Labels) + Labels=setof( shape CellView~>shapes shape~>objType=="label" ) + n=0 + u=0 + foreach( label Labels + n=n+1 + if( label~>parent==nil then + pinShapes=dbGetTrueOverlaps( + CellView + list( label~>xy label~>xy ) + label~>lpp + 1 + ) + foreach( pinShape pinShapes + if( pinShape~>objType!="label" && label~>parent == nil then + u=u+1 + net=dbMakeNet( CellView label~>theLabel ) + dbCreatePin( net pinShape ) + label~>parent=pinShape + ) + ) + ) + ) + printf( "%d/%d pins created from labels\n" u n) + ) +) + +; Warn/Delete redundant non-canonical pins (after CanonicalizePins) +(defun DeleteRedundantPins + (@key (CV (geGetEditCellView)) + (warnOnly nil) + ) + (let (to_delete (num 0)) + (foreach net CV->nets + (unless (or (length net->pins)<=1 net->name=="Vdd" net->name=="GND") + ; find canonicalized pins + to_delete = nil + (foreach pin net->pins + (when (dbGetPropByName pin->fig "CanonicalizedFrom") + to_delete = (cons pin->fig to_delete) + ) + ) + ; keep last pin if all were canonicalized + (when (length to_delete)==(length net->pins) + to_delete = (cdr to_delete) + ) + ; delete pins and ROD objects + (when to_delete + num=num+1 + (printf "WARNING: %s%d redundant pins on net %s\n" + (if warnOnly "" "Deleting ") (length to_delete) net->name) + (foreach obj to_delete + (cond (warnOnly + (geCreateMarker obj "warning" "pins" "redundant pin" "") + ) + (t + (foreach child obj->children (dbDeleteObject child)) + (dbDeleteObject obj) + ) + ) + ) + ) + ) + ) + num + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/channels/e1ofn.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/channels/e1ofn.il new file mode 100644 index 0000000000..7882a81a36 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/channels/e1ofn.il @@ -0,0 +1,308 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun E1ofNInsertEnable ( EnableNetName DataRailNets ) + (let ( + ( NumDataRails ( length DataRailNets ) ) ) + (let ( + ( CurrPos 0 ) + ( RemainingNets DataRailNets ) + ( Result nil ) + ( EnableInsertPos ( ceiling + ( quotient + ( float NumDataRails ) + ( float 2 ) ) ) ) ) + (if DataRailNets + (while ( leqp CurrPos NumDataRails ) + (if ( equal CurrPos EnableInsertPos ) + ( setq Result ( tconc Result EnableNetName ) ) + (let () + ( setq Result ( tconc Result ( car RemainingNets ) ) ) + ( setq RemainingNets ( cdr RemainingNets ) ) + ) + ) + ( setq CurrPos ( plus CurrPos 1 ) ) + ) + ( setq Result ( tconc Result EnableNetName ) ) + ) + ( car Result ) ) ) ) + +(defun E1ofNCalculatePinPitchIndexes ( EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + ReservedPitchTable + PinOffsets + ) + + (let ( + ( ChannelNets ( E1ofNInsertEnable EnableNetName DataRailNets ) ) + ) + (let ( + ( NetArray ( listToVector ChannelNets ) ) + ( NetPitchArray ( makeVector ( length ChannelNets ) ) ) + ( OffsetArray ( listToVector PinOffsets ) ) + ( EnableIndex ( quotient ( length ChannelNets ) 2 ) ) + ) + + ( setarray NetPitchArray EnableIndex + ( list EnableNetName ( plus EnablePinPitchIndex ( arrayref OffsetArray EnableIndex ) ) ) ) + + (let ( + ( CurrPitch EnablePinPitchIndex ) + ) + ( for I 1 EnableIndex + (let ( + ( CurrIndex ( difference EnableIndex I ) ) + ) + (let ( + ( PitchCount 0 ) + ) + (while + ( lessp PitchCount PitchesBetweenPins ) + ( setq CurrPitch ( difference CurrPitch 1 ) ) + ( cond ( + ( AutoPinIsPitchReserved ReservedPitchTable CurrPitch ) + ) + ( + ( setq PitchCount ( plus PitchCount 1 ) ) + ) + ) + ) + ( setarray NetPitchArray CurrIndex + ( list ( arrayref NetArray CurrIndex ) ( plus CurrPitch ( arrayref OffsetArray CurrIndex ) ) ) + ) + ) + ) + ) + ) + + (let ( + ( CurrPitch EnablePinPitchIndex ) + ) + ( for I ( plus EnableIndex 1 ) ( difference ( length NetPitchArray ) 1 ) + (let ( + ( CurrIndex I ) + ) + (let ( + ( PitchCount 0 ) + ) + (while + ( lessp PitchCount PitchesBetweenPins ) + ( setq CurrPitch ( plus CurrPitch 1 ) ) + ( cond ( + ( AutoPinIsPitchReserved ReservedPitchTable CurrPitch ) + ) + ( + ( setq PitchCount ( plus PitchCount 1 ) ) + ) + ) + ) + ( setarray NetPitchArray CurrIndex + ( list ( arrayref NetArray CurrIndex ) ( plus CurrPitch ( arrayref OffsetArray CurrIndex ) ) ) + ) + ) + ) + ) + ) + + ( vectorToList NetPitchArray ) + ) + ) +) + + +(defun E1ofNQueueLeftE1ofNPins ( PinTable + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + PinOffsets + LayerPurposePair + PinWidths + PinLength + WireSpacings + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + @key ( CreateRectInfo t ) + ( Strut nil ) + ) + (let ( + ( PinPitches + ( E1ofNCalculatePinPitchIndexes + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + ReservedPitchTable + (cond ( + ( null PinOffsets ) + ( vectorToList ( makeVector ( plus ( length DataRailNets ) 1 ) 0 ) ) + ) + ( + PinOffsets + ) + ) ) ) ) + + ( mapcar + (lambda ( PinPitch Width Spacing ) + ( AutoPinQueueLeftPin + PinTable + ( cadr PinPitch ) + ( car PinPitch ) + LayerPurposePair + Width + PinLength + Spacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ?CreateRectInfo CreateRectInfo + ?Strut Strut + ) ) + PinPitches + PinWidths + WireSpacings ) + t ) ) + +(defun E1ofNQueueRightE1ofNPins ( PinTable + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + PinOffsets + LayerPurposePair + PinWidths + PinLength + WireSpacings + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + @key ( CreateRectInfo t ) + ( Strut nil ) + ) + + (let ( + ( PinWidths + (cond ( + ( numberp PinWidths ) + ( ListFillList + (lambda ( N ) PinWidths ) + ( plus 1 ( length DataRailNets ) ) ) ) + ( PinWidths ) ) ) + ( PinPitches + ( E1ofNCalculatePinPitchIndexes + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + ReservedPitchTable + ( cond ( + ( null PinOffsets ) + ( vectorToList ( makeVector ( plus ( length DataRailNets ) 1 ) 0 ) ) + ) + ( + PinOffsets + ) + ) ) ) ) + + ( mapcar + (lambda ( PinPitch Width Spacing ) + ( AutoPinQueueRightPin + PinTable + ( cadr PinPitch ) + ( car PinPitch ) + LayerPurposePair + Width + PinLength + Spacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ?CreateRectInfo CreateRectInfo + ?Strut Strut + ) ) + PinPitches + PinWidths + WireSpacings ) + t ) ) + +(defun E1ofNQueueLeftRightE1ofNPins ( PinTable + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + PinOffsets + LayerPurposePair + PinWidths + PinLength + WireSpacings + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + @key ( CreateRectInfo t ) + ( Strut nil ) + ) + (let ( + ( PinPitches + ( E1ofNCalculatePinPitchIndexes + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + ReservedPitchTable + (cond ( + ( null PinOffsets ) + ( vectorToList ( makeVector ( plus ( length DataRailNets ) 1 ) 0 ) ) + ) + ( + PinOffsets + ) + ) ) ) ) + + ( mapcar + (lambda ( PinPitch Width Spacing ) + ( AutoPinQueueLeftRightPin + PinTable + ( cadr PinPitch ) + ( car PinPitch ) + LayerPurposePair + Width + PinLength + Spacing + WirePitch + BoundaryPolygonEdges + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + ?CreateRectInfo CreateRectInfo + ?Strut Strut + ) ) + PinPitches + PinWidths + WireSpacings ) + t ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/detailed_abstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/detailed_abstract.il new file mode 100644 index 0000000000..ae26448a53 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/detailed_abstract.il @@ -0,0 +1,187 @@ +; write the standard part of an Assura rule file +(defun WriteAssuraRuleFileHeader (file) + (fprintf file "(drcExtractRules\n") + + ; define layers + (fprintf file "(layerDefs \"df2\"\n") + (for n 1 8 + (fprintf file "m%d = (layer \"METAL%d\" (type \"drawing\" \"pin\"))\n" + n n) + ) + (for n 1 7 + (fprintf file "via%d = (layer \"VIA%d%d\" (type \"drawing\"))\n" + n n n+1) + ) + (for n 1 8 + (fprintf file "m%d_text = (textToPin \"METAL%d\" (type \"drawing\" \"pin\"))\n" + n n) + ) + (fprintf file ")\n") + + ; turn individual via shapes into via regions + (for Num 1 7 + (fprintf out "via%d = (geomOverlap (geomAnd m%d m%d) via%d)\n" + Num Num Num+1 Num) + ) + + ; define connectivity + (fprintf file "(geomConnect\n") + (for n 1 7 + (fprintf file "(via via%d m%d m%d)\n" n n+1 n) + ) + (for n 1 8 + (fprintf file "(label m%d_text m%d)\n" n n) + ) + (fprintf file ")\n") + t + ) + +; write footer +(defun WriteAssuraRuleFileFooter (file) + (for n 1 8 (fprintf file "(keepLayer m%dkeep)\n" n)) + (for n 1 7 (fprintf file "(keepLayer via%dkeep)\n" n)) + (fprintf file ")\n") + t + ) + +; Use Assura DRC to create very detailed abstract pins. Then launch +; Virtuoso XL to propagate net connectivity onto the attached shapes. +(defun CreateAbstractDetailedView (@key (CellView nil) + (targetView "abstract_detailed")) + (let (libName cellName in out line layers + AssuraLayerMappings AssuraRuleFile AssuraRunLog + ErrorStr TempDir window dstView) + (cond (CellView==nil CellView = (geGetEditCellView))) + libName = CellView->libName + cellName = CellView->cellName + + ; create layer mappings for rsf file + AssuraLayerMappings = nil + layers = nil + (for Num 1 8 + layers = (cons (sprintf nil "m%d" Num) layers) + from = (sprintf nil "m%dkeep" Num) + to = (sprintf nil "METAL%d" Num) + AssuraLayerMappings = (cons + (list from (list to "drawing")) + AssuraLayerMappings + ) + ) + (for Num 1 7 + layers = (cons (sprintf nil "via%d" Num) layers) + from = (sprintf nil "via%dkeep" Num) + to = (sprintf nil "VIA%d%d" Num Num+1) + AssuraLayerMappings = (cons + (list from (list to "drawing")) + AssuraLayerMappings + ) + ) + + ; create a modified rul file for this cell + TempDir = (ConfigFileGetValue TheCDSConfigTable "TEMP") + AssuraRuleFile = (sprintf nil "%s/%s.%s.rul" TempDir CellView->cellName targetView) + out = (outfile AssuraRuleFile) + (WriteAssuraRuleFileHeader out) + (foreach layer layers + (fprintf out "%skeep = (geomAndNot (geomGetNet %s \"*\")\n" layer layer) + (fprintf out " (geomCat (geomGetNet %s \"Vdd*\")\n" layer) + (fprintf out " (geomGetNet %s \"GND*\")))\n" layer) + ) + (WriteAssuraRuleFileFooter out) + (close out) + + ; run assura + AssuraRunLog = (sprintf nil "%s/%s.%s.log" TempDir CellView->cellName targetView) + ErrorStr = (AssuraRunAssuraLayerProcessor + CellView + CellView->libName + CellView->cellName + targetView + AssuraRuleFile + TempDir + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + + ; open destination cell for edit + window = (geOpen ?lib libName ?cell cellName ?view targetView ?mode "a") + dstView = (geGetWindowCellView window) + + ; copy pins to target view + (foreach shape CellView->shapes + (cond (shape->pin!=nil + fig = (dbCopyFig shape dstView) + (dbCreatePin (dbMakeNet dstView shape->net->name) fig) + ) + ) + ) + + ; create prBoundary + (dbCreateRect dstView (list "prBoundary" "boundary") CellView->bBox) + ) + ) + +; delete any shapes that didn't get stamped by VXL, except prBoundary +(defun DeleteUnconnectedShapes (@key (view nil)) + (cond (view==nil view = (geGetEditCellView))) + (foreach shape view->shapes + (cond ((and shape->net==nil shape->layerName!="prBoundary") + (dbDeleteObject shape) + ) + ) + ) + t + ) + +; Convert metal shapes with connectivity into "net" pins, delete +; everything else. Run through VXL first to propagate connectivity. +(defun FinishAbstractDetailedView (@key (view nil)) + (let (pin) + (cond (view==nil view = (geGetEditCellView))) + + ; delete unconnected shapes and all instances + (DeleteUnconnectedShapes ?view view) + (foreach inst view->instances (dbDeleteObject inst)) + + ; convert remaining metal shapes to net pins + (foreach shape view->shapes + (cond (shape->layerName=="prBoundary" t) + ((and (isMetal shape->layerName) + (or shape->purpose=="drawing" shape->purpose=="pin") + shape->net!=nil) + pin = (dbCreatePin shape->net shape) + pin->accessDir = (list "left" "right" "top" "bottom") + pin->term->direction = "inputOutput" + shape->purpose="net" + ) + (t (dbDeleteObject shape)) + ) + ) + + ; delete unused nets + (foreach net view->nets + (cond ((and net->term!=nil net->term->pins==nil) + (dbDeleteObject net)) + ) + ) + + ; set necessary properties + (dbReplacePropList view (list + (list "prCellClass" "string" "block") + (list "prCellType" "string" "macro") + (list "maskLayoutSubType" "string" "abstract") + (list "symmetry" "string" "X Y") + (list "gec3Foreign" "string" + (sprintf nil "%s %f %f" view->cellName + (leftEdge view->bBox) (bottomEdge view->bBox)) + ) + ) + ) + + ; save + (dbSave view) + ) + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/expand_pins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/expand_pins.il new file mode 100644 index 0000000000..e11c4c3832 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/expand_pins.il @@ -0,0 +1,52 @@ +; Expand rectangle pins to cover all touching metal +(defun ExpandPins (@key (CV (geGetEditCellView))) + (let (tempCV overlaps fig dd_CV) + + ; flatten pcells and vias to temp view + tempCV=(dbCopyCellView CV CV->libName CV->cellName "layout_temp" nil nil t) + (when !tempCV (error "Couldn't edit layout_temp view for %s\n" CV->cellName)) + (foreach inst tempCV->instances (dbFlattenInst inst 32 t)) + (foreach inst tempCV->vias (dbFlattenInst inst 32 t)) + + ; copy pins to non-pin shapes + (foreach shape tempCV->shapes + (when shape->pin + fig = (dbCopyFig shape tempCV) + fig->lpp = (list (car fig->lpp) "drawing") + ) + ) + (DeleteLabels ?CV tempCV) + + ; merge shapes + (leMergeShapes tempCV->shapes) + + ; shapes that overlap original rectangle pins become new polygon pins + (foreach shape CV->shapes + (when shape->pin && (cadr shape->lpp)=="drawing" && shape->objType=="rect" + overlaps = (dbGetTrueOverlaps tempCV shape->bBox shape->lpp 0) + (foreach fig overlaps + (when !fig->pin && fig->objType!="label" + fig = (dbCopyFig fig CV) + (leConvertShapeToPolygon fig) + (dbAddFigToPin shape->pin fig) + ) + ) + ) + ) + + ; delete layout_temp view + dd_CV = (ddGetObj tempCV->libName tempCV->cellName "layout_temp") + (when dd_CV (ddDeleteObj dd_CV)) + ) + t + ) + +; Delete polygon pins, such as those created by ExpandPins +(defun DeletePolygonPins (@key (CV (geGetEditCellView))) + (foreach shape CV->shapes + (when shape->pin && shape->objType=="polygon" + (dbDeleteObject shape) + ) + ) + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/leafpins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/leafpins.il new file mode 100644 index 0000000000..3c03609ba1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/leafpins.il @@ -0,0 +1,856 @@ +/** + * INTEL TOP SECRET + * Copyright 2002-2012 Intel Corporation. All Rights Reserved. + * $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/leafpins.il#0 $ + */ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defvar( LeafPinE1of2Q list(10 2 22) ) +defvar( LeafPinE1of2H list(22 2 46) ) +defvar( LeafPinE1of2F list(22 10 82) ) + +defvar( LeafPinE1ofNQ list(10 2 6 18 22 2 6 18 22) ) +defvar( LeafPinE1ofNH list(22 2 14 34 46 2 14 34 46) ) +defvar( LeafPinE1ofNF list(46 4 10 16 22 36 70 72 82 4 10 16 22 36 70 72 82) ) + +defvar( LeafPinNodeQ list(10) ) +defvar( LeafPinNodeH list(22) ) +defvar( LeafPinNodeF list(46) ) + +defvar( LeafPinStrutQ list(12) ) +defvar( LeafPinStrutH list(26) ) +defvar( LeafPinStrutF list(50) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( DrawLeafPins ( @key (CellVue (UIGetCellView)) (power nil)) + let( ( + ( ExecCmd + (cond ( + ( and ( boundp `ExecCmd ) ( stringp ExecCmd ) ) + ExecCmd ) + ( + "" ) ) ) + ) + + let( (PinFile LineText PinType + StringList I ScannedPins + DrawnPins CurrPinList PinOp ScanOP + CellHeight LeftPinSlots RightPinSlots + + ( PinsFile + ( sprintf + nil + "%s/autopins/%s.pins.il" + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( getq CellVue cellName ) ) ) + + ( PinsCommand + ( sprintf + nil + "%s %s/cast2skill --cast-path=%s --cell=%s --output-dir=%s --cadence-name --root-only --max-heap-size=%dM --64" + ExecCmd + ( PackageGetBinRoot ) + ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) + ( getq CellVue cellName ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( nrGetMaxHeapSize ) + ) ) + + ) + + when( GetPrbound(CellVue) == nil + error("Cellview doesnot contain a PRBoundary !") + ) + + when( power + (DrawLeafM3Power ?cv CellVue) + ) + + ScannedPins = ScanFromPinTemplate(?CellVue CellVue) + + when( !ScannedPins + CellHeight = cadadr(GetPrbound(CellVue)~>bBox) + LeftPinSlots = LeafPinCreatePGSlotList(CellHeight) + RightPinSlots = LeafPinCreatePGSlotList(CellHeight) + + printf("%s\n" PinsCommand ) + shell(PinsCommand ) + println(PinsFile) + + PinFile = infile(PinsFile) + + ScanOP = ScanLeafPins(CellVue) + DrawnPins = nth(0 ScanOP) + + LeftPinSlots = append(nth(1 ScanOP) LeftPinSlots) + RightPinSlots = append(nth(2 ScanOP) RightPinSlots) + + while( gets(LineText PinFile) != nil + + StringList = parseString(LineText " ") + + PinType = nth(1 StringList) + + case( PinType + + ( "PinPlaceLeft" || "PinPlaceLeftRightPin" + CurrPinList = list(evalstring(nth(2 StringList))) + PinOp = LeafDrawPins(CurrPinList DrawnPins LeftPinSlots "LeftNode" ?CellVue CellVue) + LeftPinSlots = nth(0 PinOp) + DrawnPins = nth(1 PinOp) + ) + + ( "PinPlaceRight" + CurrPinList = list(evalstring(nth(2 StringList))) + PinOp = LeafDrawPins(CurrPinList DrawnPins RightPinSlots "RightNode" ?CellVue CellVue) + RightPinSlots = nth(0 PinOp) + DrawnPins = nth(1 PinOp) + ) + + ( "PinPlaceLeft1ofN" || "PinPlaceLeftRight1ofN" + CurrPinList = CreatePinList(StringList) + PinOp = LeafDrawPins(CurrPinList DrawnPins LeftPinSlots "Left" ?CellVue CellVue) + LeftPinSlots = nth(0 PinOp) + DrawnPins = nth(1 PinOp) + ) + + ( "PinPlaceRight1ofN" + CurrPinList = CreatePinList(StringList) + PinOp = LeafDrawPins(CurrPinList DrawnPins RightPinSlots "Right" ?CellVue CellVue) + RightPinSlots = nth(0 PinOp) + DrawnPins = nth(1 PinOp) + ) + + ( "PinPlaceHorizontalStrut" + CurrPinList = CreatePinList(StringList) + PinOp = LeafDrawStruts(CurrPinList DrawnPins LeftPinSlots RightPinSlots "Strut" ?CellVue CellVue) + RightPinSlots = nth(1 PinOp) + LeftPinSlots = nth(0 PinOp) + DrawnPins = nth(2 PinOp) + ) + + ( "PinPlaceInPlace" + CurrPinList = list(evalstring(nth(2 StringList))) + println(CurrPinList) + PinOp = LeafDrawPins(CurrPinList DrawnPins LeftPinSlots "LeftNode" ?CellVue CellVue) + LeftPinSlots = nth(0 PinOp) + DrawnPins = nth(1 PinOp) + ) + + ) + ) + + close(PinFile) + ) + t + ) + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CreatePinList (StringList) + let( ( I Eval + PinList + ) + + PinList = nil + + for( I 2 length(StringList)-2 + when( nth(I StringList) != "(" && nth(I StringList) != ")" && nth(I StringList) != "list" + Eval = evalstring(nth(I StringList)) + when( ! integerp(Eval) + PinList = cons(Eval PinList) + ) + ) + ) + + reverse(PinList) + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( CreatePinList (StringList) + let( ( I Eval + PinList + ) + + PinList = nil + + for( I 2 length(StringList)-2 + when( nth(I StringList) != "(" && nth(I StringList) != ")" && nth(I StringList) != "list" + Eval = evalstring(nth(I StringList)) + when( ! integerp(Eval) + PinList = cons(Eval PinList) + ) + ) + ) + + reverse(PinList) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( ScanLeafPins (CellVue) + let( ( + PinNameList LeftPinSlotList RightPinSlotList + PinShape PinCenter + ) + + foreach( PinShape CellVue~>shapes + when( PinShape~>pin~>net~>name && PinShape~>pin~>net~>name != "GND" && PinShape~>pin~>net~>name != "Vdd" && car(PinShape~>lpp) == "M3" + PinNameList = cons(PinShape~>pin~>net~>name PinNameList) + PinCenter = cadar(PinShape~>bBox) + (cadadr(PinShape~>bBox)-cadar(PinShape~>bBox))/2 + when( caar(PinShape~>bBox) <= caar(GetPrbound(CellVue)~>bBox) + DefaultWiringPitch + LeftPinSlotList = cons(round((PinCenter - DefaultWiringPitch/2)/DefaultWiringPitch) LeftPinSlotList) + ) + when( caadr(PinShape~>bBox) >= caadr(GetPrbound(CellVue)~>bBox) - DefaultWiringPitch + RightPinSlotList = cons(round((PinCenter - DefaultWiringPitch/2)/DefaultWiringPitch) RightPinSlotList) + ) + ) + ) + + list(PinNameList LeftPinSlotList RightPinSlotList) + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( ScanToPinTemplate (@key (CellVue (UIGetCellView))) + let( ( StrNoSub PinTemp I + TemplateCellVue + PinShape PinCenter PinDrawn LibName CellName + ) + + LibName = CellVue~>libName + CellName = CellVue~>cellName + + StrNoSub = parseString(CellName ".") + PinTemp = nth(0 StrNoSub) + + for( I 1 length(StrNoSub)-1 + when( I < length(StrNoSub)-1 + PinTemp = strcat(PinTemp "." nth(I StrNoSub)) + ) + when( I == length(StrNoSub)-1 + PinTemp = strcat(PinTemp ".pintemplate") + ) + ) + + TemplateCellVue = nrOpenCellViewWritableByName(PinTemp "layout") + when( GetPrbound(TemplateCellVue) + dbDeleteObject(GetPrbound(TemplateCellVue)) + ) + foreach( PinShape TemplateCellVue~>shapes + when( PinShape + dbDeleteObject(PinShape) + ) + ) + + if( TemplateCellVue + then + if( GetPrbound(CellVue)~>points != nil + then + dbCreatePRBoundary(TemplateCellVue GetPrbound(CellVue)~>points) + else + error("Unable to find PR Boundary !") + ) + foreach( PinShape CellVue~>shapes + when( PinShape~>pin~>net~>name && PinShape~>pin~>net~>name != "GND" && PinShape~>pin~>net~>name != "Vdd" && car(PinShape~>lpp) == "M3" + PinCenter = cadar(PinShape~>bBox) + (cadadr(PinShape~>bBox)-cadar(PinShape~>bBox))/2 + PinSlot = round((PinCenter - DefaultWiringPitch/2)/DefaultWiringPitch) + when( caar(PinShape~>bBox) <= caar(GetPrbound(CellVue)~>bBox) + DefaultWiringPitch && caadr(PinShape~>bBox) >= caadr(GetPrbound(CellVue)~>bBox) - DefaultWiringPitch && !PinDrawn + LeafPinPlaceHorizontalStrut(PinShape~>pin~>net~>name PinSlot ?CellVue TemplateCellVue) + PinDrawn = t + ) + when( caar(PinShape~>bBox) <= caar(GetPrbound(CellVue)~>bBox) + DefaultWiringPitch && !PinDrawn + LeafPinPlaceLeft(PinShape~>pin~>net~>name PinSlot ?CellVue TemplateCellVue) + PinDrawn = t + ) + when( caadr(PinShape~>bBox) >= caadr(GetPrbound(CellVue)~>bBox) - DefaultWiringPitch && !PinDrawn + LeafPinPlaceRight(PinShape~>pin~>net~>name PinSlot ?CellVue TemplateCellVue) + PinDrawn = t + ) + PinDrawn = nil + ) + ) + else + println("Pin Template %s is locked !" PinTemp) + ) + + dbSave(TemplateCellVue) + dbPurge(TemplateCellVue) + + printf("Scanned Pins to \"%s\"\n" PinTemp) + + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( ScanFromPinTemplate (@key (CellVue (UIGetCellView))) + let( ( StrNoSub PinTemp I + TemplateCellVue ScannedPins + PinShape PinCenter PinDrawn LibName CellName + ) + + (DeletePinsByType "LeafCell") + + LibName = CellVue~>libName + CellName = CellVue~>cellName + ScannedPins = nil + StrNoSub = parseString(CellName ".") + PinTemp = nth(0 StrNoSub) + + for( I 1 length(StrNoSub)-1 + when( I < length(StrNoSub)-1 + PinTemp = strcat(PinTemp "." nth(I StrNoSub)) + ) + when( I == length(StrNoSub)-1 + PinTemp = strcat(PinTemp ".pintemplate") + ) + ) + + TemplateCellVue = nrOpenCellViewReadable(LibName PinTemp "layout") + + foreach( PinShape TemplateCellVue~>shapes + when( PinShape~>pin~>net~>name && PinShape~>pin~>net~>name != "GND" && PinShape~>pin~>net~>name != "Vdd" && car(PinShape~>lpp) == "M3" + PinCenter = cadar(PinShape~>bBox) + (cadadr(PinShape~>bBox)-cadar(PinShape~>bBox))/2 + PinSlot = round((PinCenter - DefaultWiringPitch/2)/DefaultWiringPitch) + when( caar(PinShape~>bBox) <= caar(GetPrbound(TemplateCellVue)~>bBox) + DefaultWiringPitch && caadr(PinShape~>bBox) >= caadr(GetPrbound(TemplateCellVue)~>bBox) - DefaultWiringPitch && !PinDrawn + LeafPinPlaceHorizontalStrut(PinShape~>pin~>net~>name PinSlot ?CellVue CellVue) + PinDrawn = t + ) + when( caar(PinShape~>bBox) <= caar(GetPrbound(TemplateCellVue)~>bBox) + DefaultWiringPitch && !PinDrawn + LeafPinPlaceLeft(PinShape~>pin~>net~>name PinSlot ?CellVue CellVue) + PinDrawn = t + ) + when( caadr(PinShape~>bBox) >= caadr(GetPrbound(TemplateCellVue)~>bBox) - DefaultWiringPitch && !PinDrawn + LeafPinPlaceRight(PinShape~>pin~>net~>name PinSlot ?CellVue CellVue) + PinDrawn = t + ) + PinDrawn = nil + ) + ScannedPins = t + printf("Scanned Pins from %s\n" PinTemp) + ) + + ScannedPins + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafDrawPins (PinList DrawnPins PinSlots Edge @key (CellVue (UIGetCellView))) + let( ( + TrackScope CellHeight + PinSlot PinHop + NewPinSlots + NewDrawnPins + OutPutList + PinSeed PinSeedStr + ) + + NewPinSlots = PinSlots + NewDrawnPins = DrawnPins + PinHop = 2 + + CellHeight = cadadr(GetPrbound(CellVue)~>bBox) + + when( power + (DelLeafM3Power ?cv CellVue ) + (DrawLeafM3Power ?cv CellVue) + ) + + case( round(CellHeight*1000) + ( 3120 + sprintf(PinSeedStr "Q") + ) + ( 6240 + sprintf(PinSeedStr "H") + ) + ( 12480 + sprintf(PinSeedStr "F") + ) + ( t + sprintf(PinSeedStr "H") + ) + ) + + when( Edge == "Left" || Edge == "Right" + if( length(PinList) <= 3 + then + PinSeedStr = strcat("LeafPinE1of2" PinSeedStr) + else + PinSeedStr = strcat("LeafPinE1ofN" PinSeedStr) + ) + ) + + when( Edge == "LeftNode" || Edge == "RightNode" + PinSeedStr = strcat("LeafPinNode" PinSeedStr) + ) + + PinSeed = evalstring(PinSeedStr) + + for( I 0 length(PinList)-1 + when( member(nth(I PinList) DrawnPins) == nil + case( Edge + ( "Left" || "Right" + TrackScope = list(round(nth(I PinSeed)/12)*12 ((round(nth(I PinSeed)/12)+1)*12)-1) + ) + ( "LeftNode" || "RightNode" + TrackScope = list(((round(nth(I PinSeed)/12)-1)*12)+1 ((round(nth(I PinSeed)/12)+1)*12)-1) + ) + ) + PinSlot = LeafPinFindPinSlot(NewPinSlots nth(I PinSeed) TrackScope PinHop) + when( PinSlot != nil + NewPinSlots = cons(PinSlot NewPinSlots) + NewDrawnPins = cons(nth(I PinList) NewDrawnPins) + case( Edge + ( "Left" || "LeftNode" + LeafPinPlaceLeft(nth(I PinList) PinSlot ?CellVue CellVue) + ) + ( "Right" || "RightNode" + LeafPinPlaceRight(nth(I PinList) PinSlot ?CellVue CellVue ) + ) + ) + ) + when( PinSlot == nil + printf("*ERROR* Unable to place \"%s\" pin" nth(I PinList)) + ) + ) + ) + + list(NewPinSlots NewDrawnPins) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafDrawStruts (PinList DrawnPins LeftPinSlots RightPinSlots Edge @key (CellVue (UIGetCellView))) + let( ( + TrackScope CellHeight + PinSlot PinHop + NewPinSlots NewLeftPinSlots NewRightPinSlots + NewDrawnPins + OutPutList + PinSeed PinSeedStr + ) + + NewPinSlots = append(LeftPinSlots RightPinSlots) + NewLeftPinSlots = LeftPinSlots + NewRightPinSlots = RightPinSlots + + NewDrawnPins = DrawnPins + PinHop = 2 + + CellHeight = cadadr(GetPrbound(CellVue)~>bBox) + + case( round(CellHeight*1000) + ( 3120 + sprintf(PinSeedStr "Q") + ) + ( 6240 + sprintf(PinSeedStr "H") + ) + ( 12480 + sprintf(PinSeedStr "F") + ) + ( t + sprintf(PinSeedStr "H") + ) + ) + + + PinSeedStr = strcat("LeafPinStrut" PinSeedStr) + PinSeed = evalstring(PinSeedStr) + + for( I 0 length(PinList)-1 + when( member(nth(I PinList) DrawnPins) == nil + + TrackScope = list(((round(nth(I PinSeed)/12)-1)*12)+1 ((round(nth(I PinSeed)/12)+1)*12)-1) + PinSlot = LeafPinFindPinSlot(NewPinSlots nth(I PinSeed) TrackScope PinHop) + + when( PinSlot != nil + NewPinSlots = cons(PinSlot NewPinSlots) + NewLeftPinSlots = cons(PinSlot NewLeftPinSlots) + NewRightPinSlots = cons(PinSlot NewRightPinSlots) + NewDrawnPins = cons(nth(I PinList) NewDrawnPins) + LeafPinPlaceHorizontalStrut(nth(I PinList) PinSlot ?CellVue CellVue) + ) + when( PinSlot == nil + printf("*ERROR* Unable to place \"%s\" pin" nth(I PinList)) + ) + + ) + ) + + list(NewLeftPinSlots NewRightPinSlots NewDrawnPins) + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlace (CurrPinList ExclPinList PinList PinSlots PinSeed PinHop) + let( ( + TrackScope + PinSlot + NewPinSlots + NewPinList + OutPutList + ) + + NewPinList = CurrPinList + + for( I 0 length(PinList)-1 + + TrackScope = list(round(nth(I PinSeed)/12)*12 ((round(nth(I PinSeed)/12)+1)*12)-1) + + PinSlot = LeafPinFindPinSlot(PinSlots nth(I PinSeed) TrackScope PinHop) + + when( !member(nth(I PinList) ExclPinList) && !member(nth(I PinList) CurrPinList) + LeafPinPlaceLeft(nth(I PinList) PinSlot ?CellVue CellVue) + NewPinSlots = cons(PinSlot NewPinSlots) + NewPinList = cons(nth(I PinList) NewPinSlots) + ) + ) + + OutPutList = list(NewPinList NewPinSlots) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinFindPinSlot (PinSlotList SuggTrack TrackScope TrackHop) + let( ( I + AvailTracks + UpperBound + LowerBound + PinSlot + PinSlotFound + AboveCurrTrack + BelowCurrTrack + TempHop SearchCount + ) + UpperBound = cadr(TrackScope) + LowerBound = car(TrackScope) + + TempHop = TrackHop + SearchCount = 0 +;;; Searches with given TrackHop. +;;; Decrements 2 tracks in the next search but ends with TrackHop = 1 +;;; (eventually tries to insert in nearest available odd track) + + + while( !PinSlotFound && TempHop != 0 && SearchCount < 24 + + AvailTracks = round((UpperBound - LowerBound + 1)/TempHop) + + for( I 0 AvailTracks + + BelowCurrTrack = SuggTrack - I*TempHop + AboveCurrTrack = SuggTrack + I*TempHop + + when( !PinSlotFound && greaterp(BelowCurrTrack LowerBound) && !member(BelowCurrTrack PinSlotList) + PinSlot = BelowCurrTrack + PinSlotFound = t + ) + + when( !PinSlotFound && lessp(AboveCurrTrack UpperBound) && !member(AboveCurrTrack PinSlotList) + PinSlot = AboveCurrTrack + PinSlotFound = t + ) + ) + + if( evenp(TempHop) + then + if( TempHop == 2 + then + TempHop = 1 + else + TempHop = TempHop - 2 + ) + else + TemnpHop = 0 + ) + SearchCount = SearchCount + 1 + ) + PinSlot + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinCreatePGSlotList (CellHeight) + let( ( I + PGSlotList + PGTracks + ) + PGTracks = round(CellHeight/1.56) + for( I 0 PGTracks-1 + PGSlotList = cons(I*12 PGSlotList) + PGSlotList = cons((12*(I+1))-1 PGSlotList) + ) + PGSlotList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlaceHorizontalStrut (PinName PitchIndex @key (CellVue (UIGetCellView))) + let( ( + CellLeftEdge + CellRightEdge + CellBottomEdge + PinRect + PinFig + PinNet + PinPitchY + ) + + CellLeftEdge = caar(GetPrbound(CellVue)~>bBox) + CellRightEdge = caadr(GetPrbound(CellVue)~>bBox) + CellBottomEdge = cadar(GetPrbound(CellVue)~>bBox) + PinPitchY = (PitchIndex+0.5)*DefaultWirePitch*MicronsPerMeter + PinRect = list( CellLeftEdge+LineEndSpace/2:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellRightEdge-LineEndSpace/2:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig PinName) + + PinFig + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlaceLeft (PinName PitchIndex @key (CellVue (UIGetCellView))) + let( ( + CellLeftEdge + CellRightEdge + CellBottomEdge + PinRect + PinFig + PinNet + PinPitchY + LeafPinLength + ) + + CellLeftEdge = caar(GetPrbound(CellVue)~>bBox) + CellRightEdge = caadr(GetPrbound(CellVue)~>bBox) + CellBottomEdge = cadar(GetPrbound(CellVue)~>bBox) + + if( (CellRightEdge - CellLeftEdge) >= 2.56 + then + LeafPinLength = PinLength + else + LeafPinLength = ((CellRightEdge - CellLeftEdge)-0.16)/(2*MicronsPerMeter) + ) + + PinPitchY = (PitchIndex+0.5)*DefaultWirePitch*MicronsPerMeter + PinRect = list( CellLeftEdge+LineEndSpace/2:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellLeftEdge+LeafPinLength*MicronsPerMeter:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig PinName) + + PinFig + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlaceRight (PinName PitchIndex @key (CellVue (UIGetCellView))) + let( ( + CellLeftEdge + CellRightEdge + CellBottomEdge + PinRect + PinFig + PinNet + PinPitchY LeafPinLength + ) + + CellLeftEdge = caar(GetPrbound(CellVue)~>bBox) + CellRightEdge = caadr(GetPrbound(CellVue)~>bBox) + CellBottomEdge = cadar(GetPrbound(CellVue)~>bBox) + + if( (CellRightEdge - CellLeftEdge) >= 2.56 + then + LeafPinLength = PinLength + else + LeafPinLength = ((CellRightEdge - CellLeftEdge)-0.16)/(2*MicronsPerMeter) + ) + + PinPitchY = (PitchIndex+0.5)*DefaultWirePitch*MicronsPerMeter + PinRect = list( CellRightEdge-LeafPinLength*MicronsPerMeter:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellRightEdge-LineEndSpace/2:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig PinName) + + PinFig + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlaceLeft1ofN (EnableNet DataRailNets EnablePitchIndex DataPinPitch @key (CellVue (UIGetCellView))) + let( ( + I + CellLeftEdge + CellRightEdge + CellBottomEdge + PinRect + PinFig + PinNet + N + PinPitchY + DataPinBaseIndex + OutPins + ) + + CellLeftEdge = caar(GetPrbound(CellVue)~>bBox) + CellRightEdge = caadr(GetPrbound(CellVue)~>bBox) + CellBottomEdge = cadar(GetPrbound(CellVue)~>bBox) + N = length(DataRailNets) + DataPinBaseIndex = EnablePitchIndex - round(N/2.0)*DataPinPitch + + for( I 0 N-1 + if( I < round(N/2.0) + then + PinPitchY = (DataPinBaseIndex+I*DataPinPitch+0.5)*DefaultWirePitch*MicronsPerMeter + else + PinPitchY = (DataPinBaseIndex+(I+1)*DataPinPitch+0.5)*DefaultWirePitch*MicronsPerMeter + ) + PinRect = list( CellLeftEdge+LineEndSpace/2:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellLeftEdge+PinLength*MicronsPerMeter:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig nth(I DataRailNets)) + OutPins = cons(PinFig OutPins) + ) + + PinPitchY = (EnablePitchIndex+0.5)*DefaultWirePitch*MicronsPerMeter + PinRect = list( CellLeftEdge+LineEndSpace/2:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellLeftEdge+PinLength*MicronsPerMeter:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig EnableNet) + OutPins = cons(PinFig OutPins) + + OutPins + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlaceRight1ofN (EnableNet DataRailNets EnablePitchIndex DataPinPitch @key (CellVue (UIGetCellView))) + let( ( + I + CellLeftEdge + CellRightEdge + CellBottomEdge + PinRect + PinFig + PinNet + N + PinPitchY + DataPinBaseIndex + OutPins + ) + + CellLeftEdge = caar(GetPrbound(CellVue)~>bBox) + CellRightEdge = caadr(GetPrbound(CellVue)~>bBox) + CellBottomEdge = cadar(GetPrbound(CellVue)~>bBox) + N = length(DataRailNets) + DataPinBaseIndex = EnablePitchIndex - round(N/2.0)*DataPinPitch + + for( I 0 N-1 + if( I < round(N/2.0) + then + PinPitchY = (DataPinBaseIndex+I*DataPinPitch+0.5)*DefaultWirePitch*MicronsPerMeter + else + PinPitchY = (DataPinBaseIndex+(I+1)*DataPinPitch+0.5)*DefaultWirePitch*MicronsPerMeter + ) + PinRect = list( CellRightEdge-PinLength*MicronsPerMeter:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellRightEdge-LineEndSpace/2:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig nth(I DataRailNets)) + OutPins = cons(PinFig OutPins) + ) + + PinPitchY = (EnablePitchIndex+0.5)*DefaultWirePitch*MicronsPerMeter + PinRect = list( CellRightEdge-PinLength*MicronsPerMeter:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellRightEdge-LineEndSpace/2:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig EnableNet) + OutPins = cons(PinFig OutPins) + + OutPins + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlaceLeftRight1ofN (EnableNet DataRailNets EnablePitchIndex DataPinPitch @key (CellVue (UIGetCellView))) + let( ( + I + CellLeftEdge + CellRightEdge + CellBottomEdge + PinRect + PinFig + PinNet + N + PinPitchY + DataPinBaseIndex + OutPins + ) + + CellLeftEdge = caar(GetPrbound(CellVue)~>bBox) + CellRightEdge = caadr(GetPrbound(CellVue)~>bBox) + CellBottomEdge = cadar(GetPrbound(CellVue)~>bBox) + N = length(DataRailNets) + DataPinBaseIndex = EnablePitchIndex - round(N/2.0)*DataPinPitch + + for( I 0 N-1 + if( I < round(N/2.0) + then + PinPitchY = (DataPinBaseIndex+I*DataPinPitch+0.5)*DefaultWirePitch*MicronsPerMeter + else + PinPitchY = (DataPinBaseIndex+(I+1)*DataPinPitch+0.5)*DefaultWirePitch*MicronsPerMeter + ) + PinRect = list( CellLeftEdge+LineEndSpace/2:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellLeftEdge+PinLength*MicronsPerMeter:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig nth(I DataRailNets)) + OutPins = cons(PinFig OutPins) + printf("%s is a bi-directional pin and is being placed on the left edge" nth(I DataRailNets)) + ) + + PinPitchY = (EnablePitchIndex+0.5)*DefaultWirePitch*MicronsPerMeter + PinRect = list( CellLeftEdge+LineEndSpace/2:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellLeftEdge+PinLength*MicronsPerMeter:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig EnableNet) + OutPins = cons(PinFig OutPins) + printf("%s is a bi-directional pin and is being placed on the left edge" EnableNet) + + + OutPins + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinPlaceLeftRight (PinName PitchIndex @key (CellVue (UIGetCellView))) + let( ( + CellLeftEdge + CellRightEdge + CellBottomEdge + PinRect + PinFig + PinNet + PinPitchY + ) + + CellLeftEdge = caar(GetPrbound(CellVue)~>bBox) + CellRightEdge = caadr(GetPrbound(CellVue)~>bBox) + CellBottomEdge = cadar(GetPrbound(CellVue)~>bBox) + PinPitchY = (PitchIndex+0.5)*DefaultWirePitch*MicronsPerMeter + PinRect = list( CellLeftEdge+LineEndSpace/2:PinPitchY-DefaultWireWidth*MicronsPerMeter/2 CellLeftEdge+PinLength*MicronsPerMeter:PinPitchY+DefaultWireWidth*MicronsPerMeter/2 ) + PinFig = dbCreateRect(CellVue PinLPP PinRect) + CoverPinLayerWithDrawing(CellVue PinFig) + LeafPinsCreatePin(CellVue PinFig PinName) + printf("\"%s\" is a bi-directional pin and is being placed on the left edge" PinName) + + PinFig + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( LeafPinsCreatePin (CellVue PinShape PinName) + let( ( PinNet Pin PinLabel ) + PinNet = dbMakeNet(CellVue PinName) + Pin = dbCreatePin(PinNet PinShape) + dbSetq( Pin ( list "top" "bottom" "left" "right" ) accessDir ) + dbSet(PinShape "LeafCell" "PinType") + PinLabel = MidPinsCreateLabel(CellVue PinShape) + PinLabel~>parent = PinShape + ) +t +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/midlevelpins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/midlevelpins.il new file mode 100644 index 0000000000..0162fe9531 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/midlevelpins.il @@ -0,0 +1,222 @@ +/** + * INTEL TOP SECRET + * Copyright 2002-2012 Intel Corporation. All Rights Reserved. + * $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/midlevelpins.il#0 $ + */ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +/*DOC + + DrawMidLevelPins() +--> Draws pins in a mid level cell +--> Exits with an error when run on a Leaf Cell +--> Returns "CWD/cellname.pins.warn" with the pins drawn inplace from a leaf cell +--> Returns "CWD/cellname.pins.err" if a pin is missing in a subcell instance + + MidPinsInheritPin() +--> Promotes a pin from the subcell to top level +--> Returns the FigId of the created pin + + MidPinsScanBusPins() +--> Scans for the pins drawn with BusScript +--> Returns a list of the same + +*/ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( DrawMidLevelPins ( @key (CellVue (UIGetCellView)) ) + let( ( + CellTerms + Term + InstTerm + CellPins + BusPinList + InPlacePinFig + WarningFile + ErrorFile + Warnport + Errport + ) + +; when( IsLeafCell(CellVue~>cellName) +; error("This is a leaf cell. DrawLeafCellPins() should be used instead !") +; ) + + WarningFile = strcat(getWorkingDir() "/" CellVue~>cellName ".pins.warn") + ErrorFile = strcat(getWorkingDir() "/" CellVue~>cellName ".pins.err") + + warnport = outfile(WarningFile "w") + Errport = outfile(ErrorFile "w") + + CellTerms = CellVue~>terminals + BusPinList = MidPinsScanBusPins(CellVue) + + foreach( Term CellTerms + unless( (Term~>name == "GND") || (Term~>name == "Vdd") + foreach( InstTerm Term~>net~>instTerms +; when( InstTerm~>inst~>Protected + unless( member(Term~>name BusPinList) || member(Term~>name CellPins) + InPlacePinFig = MidPinsInheritPin(CellVue InstTerm~>inst InstTerm~>name Term~>name) + when( InPlacePinFig~>LeafInPlacePin + printf("*WARNING* Top Level pin \"%s\" is drawn inplace from leaf cell instance \"%s\" \n" Term~>name InstTerm~>inst~>name) + fprintf(warnport "*WARNING* Top Level pin \"%s\" is drawn inplace from leaf cell instance \"%s\" \n" Term~>name InstTerm~>inst~>name) + ) + when( !InPlacePinFig + printf("*ERROR* Failed to make top pin \"%s\" due to missing pin \"%s\" inside instance \"%s\" \n" Term~>name InstTerm~>name InstTerm~>inst~>name) + fprintf(Errport "*ERROR* Failed to make top pin \"%s\" due to missing pin \"%s\" inside instance \"%s\" \n" Term~>name InstTerm~>name InstTerm~>inst~>name) + ) + CellPins = cons(InPlacePinFig~>net~>name CellPins) + ) +; ) ; Checks if Instance is protected + ) + ) + ) + close(warnport) + close(Errport) + ) +t +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( MidPinsInheritPin (CellVue Inst TermName PinName) + let( ( + InPlacePinFig InPlacePinFigList + InPlacePinTrf + TopPinFig + TopPinNet + TopPin + PinLabel PinShape PinList + ) + +; InPlacePinFigList = dbFindTermByName(Inst->master TermName)~>pins~>fig +; hasty fix by stevemc because it wasn't getting all of the subcell pins + PinList=dbFindTermByName(Inst->master TermName)~>pins + foreach(pin PinList + when(pin->fig + InPlacePinFigList = list(pin->fig) + ) + ) + + when( !InPlacePinFigList + InPlacePinFigList = setof(PinShape Inst->master~>shapes PinShape~>pin~>net~>name==TermName) + ) + + InPlacePinFig = car(setof(PinShape InPlacePinFigList !InValidPinLayer(PinShape))) + + when( InPlacePinFig + InPlacePinTrf = dbTransformBBox(InPlacePinFig~>bBox Inst~>transform) + TopPinFig = dbCreateRect(CellVue InPlacePinFig~>lpp InPlacePinTrf) + TopPinNet = dbMakeNet(CellVue PinName) + TopPin = dbCreatePin(TopPinNet TopPinFig) + dbSetq( TopPin ( list "top" "bottom" "left" "right" ) accessDir ) + PinLabel = MidPinsCreateLabel(CellVue TopPinFig) + + PinLabel~>parent = TopPinFig + + if( (InPlacePinFig~>PinType == "BusScript") || (InPlacePinFig~>BusPin == "TRUE") + then + MidPinsSetPinType(TopPinFig "bus") + else + MidPinsSetPinType(TopPinFig "leaf") + ) + ) +TopPinFig + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( InValidPinLayer (PinShape) + (car(PinShape~>lpp) == "CO" || car(PinShape~>lpp) == "PO" || car(PinShape~>lpp) == "M1") +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( MidPinsSetPinType (PinShape InPlacePinType) + + when( InPlacePinType == "leaf" + + dbSet(PinShape "InPlace" "PinType") + dbReplaceProp(PinShape "LeafInPlacePin" "boolean" "TRUE") + ) + + when( InPlacePinType == "bus" + + dbSet(PinShape "InPlace" "PinType") + dbReplaceProp(PinShape "BusInPlacePin" "boolean" "TRUE") + ) + +t +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( MidPinsScanBusPins (CellVue) + let( ( + BusPinList + PinShape + ) + + foreach( PinShape CellVue~>shapes + + when( PinShape~>pin~>net~>name && (PinShape~>PinType == "BusScript") + BusPinList = cons(PinShape~>pin~>net~>name BusPinList) + dbReplaceProp(PinShape "BusInPlacePin" "boolean" "TRUE") + ) + ) +BusPinList + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +defun( MidPinsCreateLabel (CellVue PinShape) + let( ( + UpRtX + LwLtX + UpRrY + LwLtY + PinHt + PinWd + LabelPt + LabelName + LabelRot + LabelHt + PinLabel + ) + + UpRtX = caadr(PinShape~>bBox) + LwLtX = caar(PinShape~>bBox) + UpRrY = cadadr(PinShape~>bBox) + LwLtY = cadar(PinShape~>bBox) + + PinHt = UpRrY - LwLtY + PinWd = UpRtX - LwLtX + + LabelPt = list(LwLtX+PinWd/2 LwLtY+PinHt/2) + LabelName = PinShape~>net~>name + + if( PinWd > PinHt + then + LabelRot = "R0" + LabelHt = PinHt/2 + else + LabelRot = "R90" + LabelHt = PinWd/2 + ) + PinLabel = dbCreateLabel(CellVue PinShape~>lpp LwLtX+PinWd/2:LwLtY+PinHt/2 LabelName "centerCenter" LabelRot "stick" LabelHt) + + PinLabel + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun RefreshPinDatabase ( @key (CellVue (UIGetCellView)) ) + let( (TermPin CellTerms Term) + + CellTerms = CellVue~>terminals + + foreach( Term CellTerms + unless( (Term~>name == "GND") || (Term~>name == "Vdd") + foreach( TermPin Term~>pins when(TermPin!=nil dbDeleteObject(TermPin)) ) + ) + ) + t + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinlayer.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinlayer.il new file mode 100644 index 0000000000..c13ad464a8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinlayer.il @@ -0,0 +1,43 @@ +/** + * INTEL TOP SECRET + * Copyright 2002-2012 Intel Corporation. All Rights Reserved. + * $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinlayer.il#0 $ + */ + +;variety of functions to deal with the change in flow +;whereby we stop streaming "pin" purpose as real metal +;This is in fitting with industry practice, and is now +;required because of Avago's memory layouts. + + + +(defun CoverPinLayerWithDrawing (CV fig) + (let (pin_bbox) + (when (cadr fig->lpp)=="pin" + (dbCreateRect CV (list (car fig->lpp) "drawing") fig->bBox) + ) + ) +) + +(defun CoverPinLayers (@key (CV (UIGetCellView))) + (foreach shape CV->shapes + (when (cadr shape->lpp)=="pin" + (CoverPinLayerWithDrawing CV shape) + ) + ) +) + + + +(defun CheckPinLayer (@key (CV (UIGetCellView))) + (let (pin_bbox) + (foreach shape CV->shapes + (when (cadr shape->lpp)=="pin" + (printf "pin shape\n") +;this needs to be updated to actually check that the +;pin layer is covered completely by drawing layer + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinplace.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinplace.il new file mode 100644 index 0000000000..abd58cc063 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinplace.il @@ -0,0 +1,725 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; Function: PinPlace +; Parameter: CellView (CVId) +; PrePlacement (boolean) +; Return: CellView (CVId) +; +; Place pin for the placer to run. +; +; +; + +defun( LockAllPins ( CellView ) +; this is to lock leaf pins so that placer can not move them. + let((termianl pin) + foreach( terminal CellView~>terminals + foreach( pin terminal~>pins + pin~>status="locked" + ) + ) + ) +) + +defun( DeleteAllPins ( CellView ) + let((termianl pin) + foreach( terminal CellView~>terminals + foreach( pin terminal~>pins + if( pin~>fig then dbDeleteObject( pin~>fig )) + if( pin then dbDeleteObject( pin )) + ) + ) + ) +) + +defun( UpdatePrBoundary (CellView bBox) + let((x0 y0 x1 y1) + x0=leftEdge(bBox) + y0=bottomEdge(bBox) + x1=rightEdge(bBox) + y1=topEdge(bBox) + if( CellView~>prBoundary dbDeleteObject(CellView~>prBoundary)) + dbCreatePRBoundary(CellView list(x0:y0 x1:y0 x1:y1 x0:y1)) + ) +) + +defun( AddPinsToCellView ( CellView PrePlacement + @key (power nil) + ) + TargetViewName = CellView ~> viewName + + (let ( + ( Boundary ( PinUtilFindPRBoundShape BoundaryLPP CellView ) ) + ( HorizontalLPP Metal3LPP ) + ( PinLPP ( CellInfoGetPinLayer DirectiveTable ) ) + ) + println("here0") + (when PrePlacement + ;tweak boundary so as not to mess with placement + ( dbSetq Boundary + ( BBoxExpandHorizontal + ( PlacementRegionsGetCellRegionDataBBox + CellRegionData ) + ( times UserUnitsPerMeter WirePitch ) ) + bBox ) + + ) + UpdatePrBoundary(CellView Boundary->bBox) + DeleteAllPins( CellView ) + DrawLeafPins( ?CellVue CellView ?power power) + LockAllPins( CellView ) + dbSave( CellView ) + + CellView + ) +) + +(defun PinPlace (NetName + BBox + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( LPP LPP ) + ) + ( AutoPinQueuePin + PinPlacePinTable + NetName + BBox + LPP + ?CreateRectInfo ( not delete) + ?InPlace nil + ) + ) + + ; doesnt handle instances ! +(defun PinPlaceMetaString ( OutFile + PinInfo ) + + ( foreach RectInfo ( AutoPinGetRectInfoListFromPinInfo PinInfo ) + ( let ( + ( Rect ( AutoPinGetRectFromRectInfo RectInfo ) ) + ( LPP ( AutoPinGetLPPFromRectInfo RectInfo ) ) + ) + (if ( not ( equal ( AutoPinGetObjTypeFromRectInfo RectInfo ) "inst" ) ) + ( fprintf OutFile + "( PinPlace \"%s\" ( list %f:%f %f:%f )\n + ?LPP ( list \"%s\" \"%s\" ) )\n" + ( AutoPinGetNetNameFromPinInfo PinInfo ) + ( caar Rect ) + ( cadar Rect ) + ( caadr Rect ) + ( cadadr Rect ) + ( car LPP ) + ( cadr LPP ) ) ) ) ) ) + +(defun PinPlaceLeft ( NetName + PitchIndex + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( LPP PinLPP ) + ( PinLength PinLength ) + ( HOffset BoundaryPinHorizontalSpacing ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest ) + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidth (if ( car Rest ) + ( times UserUnitsPerMeter ( car Rest ) ) + ( times UserUnitsPerMeter DefaultWireWidth ) ) ) + ( WireSpacing (if ( cadr Rest ) + ( times UserUnitsPerMeter ( cadr Rest ) ) + ( times UserUnitsPerMeter DefaultWireSpacing ) ) ) ) + + ( AutoPinQueueLeftPin + PinPlacePinTable + PitchIndex + NetName + LPP + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ?CreateRectInfo ( not delete ) + ) ) ) + +(defun PinPlaceRight ( NetName + PitchIndex + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( LPP PinLPP ) + ( PinLength PinLength ) + ( HOffset BoundaryPinHorizontalSpacing ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest ) + + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidth (if ( car Rest ) + ( times UserUnitsPerMeter ( car Rest ) ) + ( times UserUnitsPerMeter DefaultWireWidth ) ) ) + ( WireSpacing (if ( cadr Rest ) + ( times UserUnitsPerMeter ( cadr Rest ) ) + ( times UserUnitsPerMeter DefaultWireSpacing ) ) ) ) + + ( AutoPinQueueRightPin + PinPlacePinTable + PitchIndex + NetName + LPP + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ?CreateRectInfo ( not delete ) + ) ) ) + +(defun PinPlacePowerGrid (NetName + GridOffset + GridSpacing + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( HLPP HorizontalLPP ) + ( PinLength PinLength ) + ( HOffset 0.0 ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest + ) + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidth (if ( car Rest ) + ( times UserUnitsPerMeter ( car Rest ) ) + ( times UserUnitsPerMeter DefaultWireWidth ) ) ) + ( WireSpacing (if ( cadr Rest ) + ( times UserUnitsPerMeter ( cadr Rest ) ) + ( times UserUnitsPerMeter DefaultWireSpacing ) ) ) ) + + (cond ( + ( equal `inplace PowerGrid ) + ( PinPlaceInPlace + NetName + ?delete delete + ?LPP HLPP + ?MakePin t ) ) + ( + t + ( AutoPinQueuePowerGrid + PinPlacePinTable + NetName + GridOffset + GridSpacing + HLPP + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + ?CreateRectInfo ( and ( not delete ) PowerGrid ) + ) ) ) ) ) + +(defun PinPlaceInPlace ( NetName + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( LPP nil ) + ( MakePin t ) + ) + ( AutoPinQueueInPlacePin + PinPlacePinTable + NetName + LPP + BoundaryPolygonEdges + ?CreateRectInfo ( and ( not delete ) InPlace ) + ?MakePin MakePin + ) + ) + + +(defun PinPlaceParseParams ( Param + Default + UserUnitsPerMeter + N ) + ( mapcar + (lambda ( Spacing ) + ( times UserUnitsPerMeter Spacing ) ) + (cond ( + ( and Param ( listp Param ) ) + Param ) + ( + ( ListFillList + (lambda ( N ) (cond ( Param ) ( Default ) ) ) + N ) ) ) ) ) + +(defun PinPlaceLeft1ofN ( EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( PinOffsets nil ) + ( LPP PinLPP ) + ( PinLength PinLength ) + ( HOffset BoundaryPinHorizontalSpacing ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest + ) + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidths + ( PinPlaceParseParams + ( car Rest ) + DefaultWireWidth + UserUnitsPerMeter + ( plus 1 ( length DataRailNets ) ) ) ) + ( WireSpacings + ( PinPlaceParseParams + ( cadr Rest ) + DefaultWireSpacing + UserUnitsPerMeter + ( plus 1 ( length DataRailNets ) ) ) ) + ) + + ( E1ofNQueueLeftE1ofNPins + PinPlacePinTable + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + PinOffsets + LPP + PinWidths + PinLength + WireSpacings + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + ?CreateRectInfo ( not delete ) + ) ) ) + +(defun PinPlaceRight1ofN (EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( LPP PinLPP ) + ( PinOffsets nil ) + ( PinLength PinLength ) + ( HOffset BoundaryPinHorizontalSpacing ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest + ) + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidths + ( PinPlaceParseParams + ( car Rest ) + DefaultWireWidth + UserUnitsPerMeter + ( plus 1 ( length DataRailNets ) ) ) ) + ( WireSpacings + ( PinPlaceParseParams + ( cadr Rest ) + DefaultWireSpacing + UserUnitsPerMeter + ( plus 1 ( length DataRailNets ) ) ) ) + ) + + ( E1ofNQueueRightE1ofNPins + PinPlacePinTable + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + PinOffsets + LPP + PinWidths + PinLength + WireSpacings + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + ?CreateRectInfo ( not delete ) + ) ) ) + +(defun PinPlaceLeftRight1ofN ( EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( PinOffsets nil ) + ( LPP PinLPP ) + ( PinLength PinLength ) + ( HOffset BoundaryPinHorizontalSpacing ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest + ) + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidths + ( PinPlaceParseParams + ( car Rest ) + DefaultWireWidth + UserUnitsPerMeter + ( plus 1 ( length DataRailNets ) ) ) ) + ( WireSpacings + ( PinPlaceParseParams + ( cadr Rest ) + DefaultWireSpacing + UserUnitsPerMeter + ( plus 1 ( length DataRailNets ) ) ) ) + ) + + ( E1ofNQueueLeftRightE1ofNPins + PinPlacePinTable + EnableNetName + DataRailNets + EnablePinPitchIndex + PitchesBetweenPins + PinOffsets + LPP + PinWidths + PinLength + WireSpacings + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + ?CreateRectInfo ( not delete ) + ) ) ) + +(defun PinPlaceHorizontalStrut ( NetName + PitchIndex + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( LPP HorizontalLPP ) + ( PinLength PinLength ) + ( HOffset BoundaryPinHorizontalSpacing ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest + ) + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidth (if ( car Rest ) + ( times UserUnitsPerMeter ( car Rest ) ) + ( times UserUnitsPerMeter DefaultWireWidth ) ) ) + ( WireSpacing (if ( cadr Rest ) + ( times UserUnitsPerMeter ( cadr Rest ) ) + ( times UserUnitsPerMeter DefaultWireSpacing ) ) ) ) + ( AutoPinQueueHorizontalStrut + PinPlacePinTable + PitchIndex + NetName + PinLPP + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + ?CreateRectInfo ( not delete ) + ) ) ) + +(defun PinPlaceLeftRightPin (NetName + PitchIndex + @key ( delete ( not PinPlaceCreateRectInfo ) ) + ( LPP PinLPP ) + ( PinLength PinLength ) + ( HOffset BoundaryPinHorizontalSpacing ) + ( VOffset BoundaryPinVerticalSpacing ) + @rest Rest + ) + (let ( + ( WirePitch ( times UserUnitsPerMeter DefaultWirePitch ) ) + ( PinWidth (if ( car Rest ) + ( times UserUnitsPerMeter ( car Rest ) ) + ( times UserUnitsPerMeter DefaultWireWidth ) ) ) + ( WireSpacing (if ( cadr Rest ) + ( times UserUnitsPerMeter ( cadr Rest ) ) + ( times UserUnitsPerMeter DefaultWireSpacing ) ) ) ) + + ( AutoPinQueueLeftRightPin + PinPlacePinTable + PitchIndex + NetName + LPP + PinWidth + PinLength + WireSpacing + WirePitch + BoundaryPolygonEdges + HOffset + VOffset + ManufacturingGrid + FunctionCacheTable + ReservedPitchTable + ?CreateRectInfo ( not delete ) + ) ) ) + +(defun PinPlaceDrawUsingPDKInfo ( TargetCellView + @key + ( PinLength PinLength ) + ( PinLPP PinLPP ) + ( HorizontalLPP Metal3LPP ) + ( PinLength PinLength ) + ( BoundaryPinHorizontalSpacing + BoundaryPinHorizontalSpacing ) + ( BoundaryPinVerticalSpacing + BoundaryPinVerticalSpacing ) + ( ConnectivityViewName "netlist" ) + ( PinsDirectory nil ) + ( PinsFile "pins.il" ) + ( UserPinsFile "userpins.il" ) + ( DeleteOld t ) + ( CreateLog t ) + ( PowerGrid t ) + ( InPlace t ) + ( DeleteExistingPins nil ) + ( AddOnly nil ) + ) + if( PowerGrid + then + DrawLeafM3Power() + else + DelLeafM3Power() + ) + + ( PinPlaceDraw + TargetCellView + UserUnitsPerMeter + BoundaryLPP + PinLength + PinLPP + HorizontalLPP + FoldableCellLibCellPairRegExs + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + PhysicalManufacturingGrid + MetalLayerRegEx + ViaLayerRegEx + ?PinsDirectory PinsDirectory + ?ConnectivityViewName ConnectivityViewName + ?PinsFile PinsFile + ?UserPinsFile UserPinsFile + ?DeleteOld DeleteOld + ?CreateLog CreateLog + ?PowerGrid t + ?InPlace InPlace + ?DeleteExistingPins DeleteExistingPins + ?AddOnly AddOnly + ) ) + +(defun PinPlaceDraw ( + TargetCellView + UserUnitsPerMeter + PRBoundaryLPP + PinLength + PinLPP + HorizontalLPP + FoldableCellLibCellPairRegExs + BoundaryPinHorizontalSpacing + BoundaryPinVerticalSpacing + ManufacturingGrid + MetalLayerRegEx + ViaLayerRegEx + @key + ( ConnectivityViewName "netlist" ) + ( PinsDirectory nil ) + ( PinsFile "pins.il" ) + ( UserPinsFile "userpins.il" ) + ( DeleteOld t ) + ( CreateLog t ) + ( PowerGrid t ) + ( InPlace t ) + ( DeleteExistingPins nil ) + ( AddOnly nil ) + ) + ;adjust units + ( setq PinLength + ( times PinLength UserUnitsPerMeter ) ) + ( setq BoundaryPinHorizontalSpacing + ( times BoundaryPinHorizontalSpacing UserUnitsPerMeter ) ) + ( setq BoundaryPinVerticalSpacing + ( times BoundaryPinVerticalSpacing UserUnitsPerMeter ) ) + ( setq ManufacturingGrid + ( times ManufacturingGrid UserUnitsPerMeter ) ) + + ; get polygon edges + (let ( + ( PinsLogFile ( sprintf nil "%s.log" PinsFile ) ) + ( BoundaryPolygonEdges + ( PinUtilGetBoundaryPolygonEdgesFromCellView + PRBoundaryLPP + TargetCellView ) ) ) + ; get pins directory + (let ( + ( PinsDirectory + (if PinsDirectory PinsDirectory + ( NameGetCellPathFromCellName ( getq CellView cellName ) ) ) ) ) + (cond ( + ( not ( boundp `FunctionCacheTable ) ) + (defvar FunctionCacheTable ( CacheCreate ) ) + ) + ( + ( not ( tablep FunctionCacheTable ) ) + (defvar FunctionCacheTable ( CacheCreate ) ) ) ) + ;create tables + ( setq ReservedPitchTable makeTable('TheReservedPitchTable) ) + ( setq PinPlacePinTable makeTable('ThePinPlacePinTable) ) + + ( setq PinsFile ( PathGetPathForFile PinsDirectory PinsFile ) ) + ( setq PinsLogFile ( PathGetPathForFile PinsDirectory PinsLogFile ) ) + ( setq UserPinsFile ( PathGetPathForFile PinsDirectory UserPinsFile ) ) + + ; Get Existing Pins that this program wrote last time + ; Dont create PinRectInfo so if this object is not in the pins or userpins files, the pins + ; are deleted when updated + ( setq PinPlaceCreateRectInfo nil ) + (cond ( + ( and ( isReadable PinsLogFile ) DeleteOld ) + ( load PinsLogFile ) ) ) + ;Add to queue the following pins in pins and userpins files, overwriting old entries + ; create PinRectInfo so the pins are created properly + ( setq PinPlaceCreateRectInfo t ) + (cond ( + ( isReadable PinsFile ) + ( load PinsFile ) ) + ( + (error "No pins file found at %s\n" PinsFile ) ) ) + (cond ( + ( isReadable UserPinsFile ) + ( printf "Using userpins.il file %s\n" UserPinsFile ) + ( load UserPinsFile ) ) ) + + ;delete old pins + (if DeleteExistingPins + ( PinUtilDeleteExistingPins TargetCellView ) ) + ;update pins + ( AutoPinUpdateQueuedPins + PinPlacePinTable + TargetCellView + ConnectivityViewName + FoldableCellLibCellPairRegExs + MetalLayerRegEx + ViaLayerRegEx + ?AddOnly AddOnly + ) + ;center labels + ( PinUtilCenterChildLabels TargetCellView BoundaryPolygonEdges ) + + ;write log + (when ( isWritable PinsLogFile ) + (let ( + ( PinsLogFilePort ( outfile PinsLogFile "w") ) + ) + (cond ( + ( and ( isFile PinsFile ) CreateLog ) + ( FileUtilAppendFile PinsLogFilePort PinsFile ) + ( cond ( + ( isFile UserPinsFile ) + ( FileUtilAppendFile PinsLogFilePort UserPinsFile ) ) ) ) ) + ( close PinsLogFilePort ) ) ) ) ) ) + +(defun PinPlacePinScan ( TargetCellView + ViaLayerRegEx + Pitched + BoundaryPolygonEdges + WirePitch + NetNamesToIgnore + @key + ( UserPinsFile "userpins.il" ) + ( FileMode "w" ) + ( PinsDirectory nil ) + ) + ; get pins directory + (let ( + ( PinsDirectory + (if PinsDirectory PinsDirectory + ( NameGetCellPathFromCellName ( getq TargetCellView cellName ) ) ) ) + ( WriteFunc (cond ( + Pitched + `PinPlaceMetaStringPitched ) + ( + `PinPlaceMetaString ) ) ) ) + ( setq UserPinsFile ( PathGetPathForFile PinsDirectory UserPinsFile ) ) + + (let ( + ( OutFile ( outfile UserPinsFile FileMode ) ) ) + ( foreach + Fig + ( PinUtilGetExistingPinFigs TargetCellView ) + (cond ( + ( exists NetName NetNamesToIgnore + ( equal NetName + ( getq ( getq ( getq Fig pin ) net ) name ) ) ) + nil ) + ( + Pitched + (let ( + ( LeftOffset + ( difference + ( caar ( getq Fig bBox ) ) + ( caar + ( PolygonGetLeftMostEdge + BoundaryPolygonEdges + ) ) ) ) + ( RightOffset + ( difference + ( caadr + ( PolygonGetRightMostEdge + BoundaryPolygonEdges + ) ) + ( caadr ( getq Fig bBox ) ) ) ) ) + ( fprintf + OutFile + (cond ( + ( lessp LeftOffset RightOffset ) + "( PinPlaceLeft \"%s\" %d ?HOffset %f )\n" ) + ( + ( greaterp LeftOffset RightOffset ) + "( PinPlaceRight \"%s\" %d ?HOffset %f )\n" ) + ( + "( PinPlaceHorizontalStrut \"%s\" %d ?HOffset %f )\n" ) ) + + ( getq ( getq ( getq Fig pin ) net ) name ) + ( car + ( PinUtilGetHorizontalPitchWidthPairForRect + ( getq Fig bBox ) + BoundaryPolygonEdges + WirePitch + 0.0 ) ) + ( min + LeftOffset RightOffset ) ) + ) ) + ( + ( PinPlaceMetaString + OutFile + ( AutoPinGetPinInfoFromPinFigForceRect + Fig + ViaLayerRegEx ) ) ) ) ) + + ( close OutFile ) + + ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pintemplates.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pintemplates.il new file mode 100644 index 0000000000..712e44f806 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pintemplates.il @@ -0,0 +1,108 @@ + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;; Generic power pins function +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +procedure( DrawPowerPins( x y layer ) + PinPlace( "GND" list( x:y x+GridWidth/2:y+GridWidth/2 ) + ?LPP layer ) + PinPlace( "Vdd" list( x:y+GridPitch/2 + x+GridWidth/2:y+GridWidth/2+GridPitch/2 ) + ?LPP layer ) +) + +procedure( DrawM3_PowerPins( x y ) + DrawPowerPins( x y Metal3pinLPP ) +) +procedure( DrawM5_PowerPins( x y ) + DrawPowerPins( x y Metal5pinLPP ) +) +procedure( DrawM7_PowerPins( x y ) + DrawPowerPins( x y Metal7pinLPP ) +) + + + +;leaf cell template +; LeafTilePowerTemplate in pdkinfo describes the metals in a +; half-tile, assuming that the next track above mirrors. this allows +; either split- or solid- stripes. +(defun DrawLeafM3Power ( @key (cv (UIGetCellView)) ) + (let (track i x1 x2 template stripe1 stripe2 stripe1y stripe2y + fig1 fig2) + (DelLeafM3Power ?cv cv) + track=0.0 + i=0 + x1=(car (car (GetPrbound cv)->bBox)) + x2=(car (cadr (GetPrbound cv)->bBox)) + (while track < (cadr (cadr (GetPrbound cv)->bBox)) + template=LeafTilePowerTemplate + + (if (mod i 2)==0 then + stripe1=(car template) + stripe2=(cadr template) + stripe1y=track+(nth 2 stripe1) + stripe2y=track+(nth 2 stripe2) + else + stripe2=(car template) + stripe1=(cadr template) + stripe1y=track+(nth 2 stripe2) + stripe2y=track+(nth 2 stripe1) + ) + + fig1=(dbCreateRect cv + (nth 1 stripe1) + (list x1:stripe1y x2:stripe1y+PowerGridWireWidth) ) + SetLeafM3PowerProp(fig1) + (dbCreatePin (dbFindNetByName cv (nth 0 stripe1)) fig1) + fig2=(dbCreateRect cv + (nth 1 stripe2) + (list x1:stripe2y x2:stripe2y+PowerGridWireWidth) ) + SetLeafM3PowerProp(fig2) + (dbCreatePin (dbFindNetByName cv (nth 0 stripe2)) fig2) + + (when i==0 + (dbCreateLabel cv + (nth 1 (car template)) + (list x1+0.03 track+(nth 2 (car template))+PowerGridWireWidth/2) + (nth 0 (car template)) + "centerLeft" "R0" "stick" 0.03) + (dbCreateLabel cv + (nth 1 (cadr template)) + (list x1+0.03 track+(nth 2 (cadr template))+PowerGridWireWidth/2) + (nth 0 (cadr template)) + "centerLeft" "R0" "stick" 0.03) + ) + + track=track+PowerGridPitch + i=i+1 + ) + + ) +) + +defun( DelLeafM3Power ( @key (cv (UIGetCellView)) ) + let( (Shape) + + foreach( Shape cv~>shapes + + when( Shape~>LeafM3Power == "TRUE" + dbDeleteObject(Shape) + ) + + when( ( Shape~>theLabel == "GND" && cadr(Shape~>lpp) == "gnd" ) || ( Shape~>theLabel == "Vdd" && cadr(Shape~>lpp) == "vdd" ) + dbDeleteObject(Shape) + ) + ) + + ) +t +) + +defun( SetLeafM3PowerProp (Fig) + + dbReplaceProp(Fig "LeafM3Power" "boolean" "TRUE") + +t +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinutil.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinutil.il new file mode 100644 index 0000000000..8b69d795da --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/pinutil.il @@ -0,0 +1,612 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun PinUtilGetValidLayer ( LPP ViaLayerRegEx ) + ( cadr + ( PinUtilGetValidLayers LPP ViaLayerRegEx ) ) ) + +(defun PinUtilGetValidLayers ( LPP ViaLayerRegEx ) + (cond ( + ( rexMatchp ViaLayerRegEx ( car LPP ) ) + (let ( + ( Digit ( rexSubstitute "\\1" ) ) ) + (if ( equal Digit "" ) + ( list + ( list "POLYG" ( cadr LPP ) ) + ( list "METAL1" ( cadr LPP ) ) + ) + ( list + ( list ( strcat "METAL" + ( sprintf nil "%d" ( difference ( atoi Digit ) 1 ) ) ) + ( cadr LPP ) ) + ( list ( strcat "METAL" Digit ) ( cadr LPP ) ) + ) ) ) ) + ( + t + ( list LPP LPP ) ) ) ) + +(defun PinUtilGetLayoutCellView ( CellName Permission ) + (let ( + ( LibCellPair ( NameParseCellName CellName ) ) ) + ( dbOpenCellViewByType + ( car LibCellPair ) + ( cadr LibCellPair ) + "layout" + "maskLayout" + Permission ) ) ) + +(defun PinUtilGetNetListCellView ( CellName Permission ) + (let ( + ( LibCellPair ( NameParseCellName CellName ) ) ) + ( dbOpenCellViewByType + ( car LibCellPair ) + ( cadr LibCellPair ) + "netlist" + nil + Permission ) ) ) + +(defun PinUtilFindPRBoundBBox ( PRBoundaryLPP TargetCellView ) + ( getq ( PinUtilFindPRBoundShape PRBoundaryLPP TargetCellView ) bBox ) +) + +(defun PinUtilFindPRBoundShape ( PRBoundaryLPP TargetCellView ) + ( car + ( sort + ( setof Shape ( getq TargetCellView shapes ) ( equal ( getq Shape lpp ) PRBoundaryLPP ) ) + ( lambda ( Shape1 Shape2 ) ( lessp ( difference ( RectGetArea ( getq Shape2 bBox ) ) + ( RectGetArea ( getq Shape1 bBox ) ) ) 0 ) ) ) ) ) + +(defun PinUtilGetBoundaryPolygonEdgesFromCellView ( PRBoundaryLPP TargetCellView ) + (cond ( + ( PinUtilGetBoundaryPolygonEdgesFromShape + ( PinUtilFindPRBoundShape + PRBoundaryLPP + TargetCellView ) ) ) + ( + t + ( dbComputeBBox TargetCellView ) + ( BBoxGetPolygonEdges ( getq TargetCellView bBox ) ) ) ) ) + + + +(defun PinUtilGetBoundaryPolygonEdgesFromShape ( PRBoundaryShape ) + (cond ( + ;polygon + ( getq PRBoundaryShape points ) + ( PolygonGetEdges ( getq PRBoundaryShape points ) ) ) + ( + ( getq PRBoundaryShape bBox ) + ;bbox + ( BBoxGetPolygonEdges ( getq PRBoundaryShape bBox ) ) ) ) ) + + +(defun PinUtilIsShapeInPlaceForNet ( Shape Net ) + ( exists InstTerm ( getq Net allInstTerms ) + ( exists Shape ( getq ( getq InstTerm inst ) shapes ) + (let ( + ( BBox1 ( dbTransformBBox ( getq Shape bBox ) ( getq ( getq InstTerm inst ) transform ) ) ) + ( BBox2 ( getq Shape bBox ) ) ) + ( BBoxClose BBox1 BBox2 1e-10 ) ) ) ) ) + + + +(defun PinUtilGetAllShapesOnLPP ( CellView TheLPP ) + ( getq ( car ( exists LPP ( getq CellView lpps ) + ( and ( equal ( getq LPP layerName ) ( car TheLPP ) ) + ( equal ( getq LPP purpose ) ( cadr TheLPP ) ) ) ) ) + shapes ) ) + +;;;;;;;;;;;;;;;;;;;;;;;; +;; pitchwidthpair <-> rect + +(defun PinUtilGetHorizontalPitchWidthPairForRect ( Rect + BoundaryPolygonEdges + WirePitch + WirePitchOffset ) + (let ( + ( PinHeight ( RectGetHeight Rect ) ) + ( YPosition ( cadar Rect ) ) + ( XPosition ( caar Rect ) ) ) + (let ( + ( BoundaryBottomEdge + (cond ( + ( PolygonGetBottomMostEdgeAtX BoundaryPolygonEdges XPosition ) ) + ( + ( PolygonGetBottomMostEdge BoundaryPolygonEdges ) ) ) ) ) + (let ( + ( BoundaryBottom ( float ( LineGetSegmentMaxY BoundaryBottomEdge ) ) ) ) + (let ( + ( Pitch ( floor ( quotient ( difference YPosition BoundaryBottom WirePitchOffset ) + WirePitch ) ) ) + ( Width ( ceiling ( quotient PinHeight WirePitch ) ) ) ) + ( list Pitch Width ) ) ) ) ) ) + +(defun PinUtilGetVerticalPitchWidthPairForRect ( Rect + BoundaryPolygonEdges + WirePitch + WirePitchOffset ) + + (let ( + ( PinWidth ( RectGetWidth Rect ) ) + ( YPosition ( cadar Rect ) ) + ( XPosition ( caar Rect ) ) ) + (let ( + ( BoundaryLeftEdge + (cond ( + ( PolygonGetLeftMostEdgeAtY BoundaryPolygonEdges YPosition ) ) + ( + ( PolygonGetLeftMostEdge BoundaryPolygonEdges ) ) ) ) ) + (let ( + ( BoundaryLeft ( float ( LineGetSegmentMaxX BoundaryLeftEdge ) ) ) ) + (let ( + ( Pitch ( floor ( quotient ( difference XPosition BoundaryLeft WirePitchOffset ) + WirePitch ) ) ) + ( Width ( ceiling ( quotient PinWidth WirePitch ) ) ) ) + ( list Pitch Width ) ) ) ) ) ) + + + +(defun PinUtilGetYRangeForHorizontalPitch ( Pitch + NumPitches + ActualWireWidth + WirePitch + WirePitchOffset + BoundaryPolygonEdges ) + (let ( + ( BoundaryBottom + ( LineGetSegmentMaxY + ( PolygonGetBottomMostEdge BoundaryPolygonEdges ) ) ) ) + (let ( + ( PinVerticalMidpoint + ( plus BoundaryBottom + WirePitchOffset + ( times 0.5 ( plus ( times WirePitch Pitch ) + ( times WirePitch ( plus Pitch NumPitches ) ) ) ) ) ) ) + (let ( + ( PinBottom ( difference PinVerticalMidpoint ( times 0.5 ActualWireWidth ) ) ) + ( PinTop ( plus PinVerticalMidpoint ( times 0.5 ActualWireWidth ) ) ) ) + ( list PinBottom PinTop ) ) ) ) ) + + + +(defun PinUtilGetXRangeForVerticalPitch ( Pitch + NumPitches + ActualWireWidth + WirePitch + WirePitchOffset + BoundaryPolygonEdges ) + (let ( + ( BoundaryLeft + ( LineGetSegmentMaxX + ( PolygonGetLeftMostEdge BoundaryPolygonEdges ) ) ) ) + (let ( + ( PinHorizontalMidpoint + ( plus BoundaryLeft + WirePitchOffset + ( times 0.5 ( plus ( times WirePitch Pitch ) + ( times WirePitch ( plus Pitch NumPitches ) ) ) ) ) ) ) + (let ( + ( PinLeft ( difference PinHorizontalMidpoint ( times 0.5 ActualWireWidth ) ) ) + ( PinRight ( plus PinHorizontalMidpoint ( times 0.5 ActualWireWidth ) ) ) ) + ( list PinLeft PinRight ) ) ) ) ) + + + +;note - this treats wirewidth from a directive pov, ie.e +;width = wirewidth + ( width in pitches - 1 ) * WirePitch +(defun PinUtilGetYRangeForHorizontalPitchWidthPair ( PitchWidthPair + WirePitch + WireWidth + WirePitchOffset + BoundaryPolygonEdges ) + ( PinUtilGetYRangeForHorizontalPitch + ( car PitchWidthPair ) + ( cadr PitchWidthPair ) + ( plus ( times ( difference ( cadr PitchWidthPair ) 1 ) WirePitch ) WireWidth ) + WirePitch + WirePitchOffset + BoundaryPolygonEdges ) ) + +(defun PinUtilGetXRangeForVerticalPitchWidthPair ( PitchWidthPair + WirePitch + WireWidth + WirePitchOffset + BoundaryPolygonEdges ) + ( PinUtilGetXRangeForVerticalPitch + ( car PitchWidthPair ) + ( cadr PitchWidthPair ) + ( plus ( times ( difference ( cadr PitchWidthPair ) 1 ) WirePitch ) WireWidth ) + WirePitch + WirePitchOffset + BoundaryPolygonEdges ) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun PinUtilGetPinRectsForCellView ( CellView + NetNamePredicate + LPPPredicate ) + ( mapcar + (lambda ( Fig ) + ( getq Fig bBox ) ) + ( PinUtilGetPinFigsForCellView + CellView + NetNamePredicate + LPPPredicate ) ) ) + +(defun PinUtilGetPinFigsForCellView ( CellView + NetNamePredicate + LPPPredicate ) + ( setof Shape ( getq CellView shapes ) + ( and ( getq Shape pin ) + ( apply LPPPredicate ( list ( getq Shape lpp ) ) ) + ( apply NetNamePredicate ( list ( getq ( getq ( getq Shape pin ) net ) name ) ) ) ) ) ) + +(defun PinUtilGetPinRectsForInstances ( Instances + NetNamePredicate + LPPPredicate ) + ( ListNonDestructiveMapCan + ( lambda ( Instance ) + ( PinUtilGetPinRectsForInstance + Instance + NetNamePredicate + LPPPredicate ) ) + Instances ) ) + +(defun PinUtilGetPinRectsForInstance ( Instance + NetNamePredicate + LPPPredicate + @key ( TerminalP nil ) + ) + ( mapcar + (lambda ( Shape ) + (let ( + ( RealShape + ( AutoPinGetSmallestBoundingShape + ( getq Instance master ) + Shape + ?LPPPredicate LPPPredicate ) ) ) + (when RealShape + ( dbTransformBBox + ( getq + RealShape + bBox ) + ( getq Instance transform ) ) ) ) ) + ( PinUtilGetPinFigsForInstance + Instance + NetNamePredicate + LPPPredicate + ?TerminalP TerminalP ) ) ) + + +(defun PinUtilGetPinFigsForInstance ( Instance + NetNamePredicate + LPPPredicate + @key ( TerminalP nil ) + ) + ( setof + Fig + ( mapcar + (lambda ( Pin ) + ( getq Pin fig ) ) + ( ListNonDestructiveMapCan + (lambda ( InstTerm ) + ( getq ( getq InstTerm term ) pins ) ) + ( setof InstTerm ( getq Instance conns ) + ( and + ( or ( null TerminalP ) + ( apply + TerminalP + ( list ( getq ( getq InstTerm term ) name ) ) ) ) + ( apply + NetNamePredicate + ( list ( getq ( getq InstTerm net ) name ) ) ) ) ) ) ) + ( and Fig ( apply LPPPredicate ( list ( getq Fig lpp ) ) ) ) ) ) + + +(defun PinUtilGetPCellParams ( Instance ) + ( getq ( car ( exists Property ( getq ( getq ( getq Gate master ) superMaster ) prop ) ( equal ( getq Property name ) "parameters" ) ) ) "value" ) ) + +(defun PinUtilIsLabelForNetName ( Shape NetName ) + ( and ( equal ( getq Shape objType ) "label" ) + ( equal ( getq Shape theLabel ) NetName ) ) ) + +;;;;;;;;;;;;;;;; + +(defun PinUtilGetConnectedPinInstancePairs_1 ( ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) + ( ListNonDestructiveMapCan + ( lambda ( TerminalInstancePair ) + ( mapcar ( lambda ( Pin ) + ( list Pin ( cadr TerminalInstancePair ) ) ) + ( getq ( dbFindTermByName ( getq ( cadr TerminalInstancePair ) master ) + ( car TerminalInstancePair ) ) pins ) ) ) + ( PinUtilGetConnectedTerminalInstancePairs ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) ) ) + +(defun PinUtilGetConnectedTerminalInstancePairs ( ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) + (let ( + ( Net ( dbFindNetByName ConnectivityCellView NetName ) ) ) + ( ListNonDestructiveMapCan + ( lambda ( InstTerm ) + ( mapcar ( lambda ( Instance ) ( list ( getq ( getq InstTerm term ) name ) Instance ) ) + ( NameGetInstancesForCanonicalName + LayoutInstanceMap + ( getq ( getq InstTerm inst ) name ) ) ) ) + ( getq Net allInstTerms ) ) ) ) + +;;;;;;;;;;;;;;; + +(defun PinUtilGetConnectedPinInstancePairs_2 ( ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) + ( ListNonDestructiveMapCan + ( lambda ( InstTerm ) + ( mapcar ( lambda ( Pin ) + ( list Pin ( getq InstTerm inst ) ) ) + ( getq ( getq InstTerm term ) pins ) ) ) + ( PinUtilGetConnectedInstTerms ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) ) ) + +(defun PinUtilGetConnectedInstances ( ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) + (let ( + ( Net ( dbFindNetByName ConnectivityCellView NetName ) ) ) + ( ListNonDestructiveMapCan + ( lambda ( InstTerm ) + ( NameGetInstancesForCanonicalName + LayoutInstanceMap + ( getq ( getq InstTerm inst ) name ) ) ) + ( getq Net allInstTerms ) ) ) ) + +(defun PinUtilGetConnectedInstTerms ( ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) + ( ListNonDestructiveMapCan + ( lambda ( Instance ) + ( setof InstTerm ( getq Instance conns ) + ( equal ( getq ( getq InstTerm net ) name ) NetName ) ) ) + ( PinUtilGetConnectedInstances ConnectivityCellView LayoutCellView LayoutInstanceMap NetName ) ) ) + +;;;;;;;;;;;;;;;; + + +;centers pin on the correct handle if rod, centers to center of bbox of shape if no rod +(defun PinUtilCenterChildLabels ( TargetCellViews BoundaryPolygonEdges ) + ( foreach Fig ( PinUtilGetExistingFigs TargetCellView ) + ( foreach Label ( setof Shape ( getq Fig children ) + ( equal ( getq Shape objType ) "label" ) ) + ( dbSetq Label + ( BBoxGetCenter ( getq Fig bBox ) ) + xy ) + ( dbSetq Label + ( PinUtilGetJustification + BoundaryPolygonEdges + ( getq Fig bBox ) + Label ) + justify ) ) ) ) + +(defun PinUtilGetJustification ( BoundaryPolygonEdges + ParentBBox + Label ) + ( dbSetq Label "centerCenter" justify ) + + (let ( + ( BoundaryLeft + ( LineGetSegmentMaxX + ( PolygonGetLeftMostEdge BoundaryPolygonEdges ) ) ) + ( BoundaryRight + ( LineGetSegmentMinX + ( PolygonGetRightMostEdge BoundaryPolygonEdges ) ) ) + ( BoundaryBottom + ( LineGetSegmentMaxY + ( PolygonGetBottomMostEdge BoundaryPolygonEdges ) ) ) + ( BoundaryTop + ( LineGetSegmentMinY + ( PolygonGetTopMostEdge BoundaryPolygonEdges ) ) ) + ( BBox ( getq Label bBox ) ) + ) + + ( cond ( + ;too far left + ( leqp ( caar BBox ) BoundaryLeft ) + "leftCenter" + ) + ( + ;too far right + ( geqp ( caadr BBox ) BoundaryRight ) + "rightCenter" + ) + ( + "centerCenter" + ) + ) ) ) + + + +(defun PinUtilGetExistingPinFigs ( TargetCellView ) + ( append ( PinUtilGetExistingPinInstances TargetCellView ) + ( PinUtilGetExistingPinShapes TargetCellView ) ) ) + +(defun PinUtilGetExistingFigs ( TargetCellView ) + ( append ( getq TargetCellView instances ) + ( getq TargetCellView shapes ) ) ) + +(defun PinUtilGetExistingPinInstances ( TargetCellView ) + ( setof Instance ( getq TargetCellView instances ) ( getq Instance pin ) ) ) + +(defun PinUtilGetExistingPinShapes ( TargetCellView ) + "returns a list of pininfos for each existing pin in cellview " + ( setof Shape ( getq TargetCellView shapes ) ( getq Shape pin ) ) ) + +;deletes all pin shapes and symbolic pins +(defun PinUtilDeleteExistingPins ( TargetCellView ) + ( foreach Pin ( PinUtilGetExistingPinFigs TargetCellView ) + ( printf "Deleting pin for net: %s" ( getq ( getq Pin net ) name ) ) + ( dbDeleteObject Pin ) ) ) + +(defun PinUtilFixPinAccess ( TargetCellView ) + ( foreach PinFig ( PinUtilGetExistingPinFigs TargetCellView ) + ( dbSetq ( getq PinFig pin ) (list "left" "right" "top" "bottom" ) accessDir ) ) ) + +(defun PinUtilGetPinsForNetName ( TargetCellView NetName ) + ( let (Pins) + ( foreach Pin ( PinUtilGetExistingPinFigs TargetCellView ) + ( when ( equal Pin->net->name NetName ) + ( setq Pins ( cons Pin Pins ) ) ) ) + Pins ) ) + +(defun PinUtilDeleteM2PowerPins ( TargetCellView ) + ( let (Pins) + ( setq Pins ( PinUtilGetPinsForNetName TargetCellView "GND" ) ) + ( setq Pins ( append Pins ( PinUtilGetPinsForNetName TargetCellView "Vdd" ) ) ) + ( foreach Pin Pins + ( when ( equal Pin->lpp Metal2LPP ) + ( dbDeleteObject Pin->pin ) ) ) ) ) + + +; delete pins and labels +(defun DeletePins (@key (cv nil)) + (let (view) + (if cv then + view=cv + else + view=(geGetEditCellView) + ) + (foreach obj view->shapes + (cond ((or obj->pin obj->objType=="label") + (dbDeleteObject obj)) + ) + ) + ) + t + ) + +(defun RecursiveDeletePins (@key (cv nil)) + (let (view uniqueInstances cell) + (if cv then + view=cv + else + view=(geGetEditCellView) + ) + (DeletePins ?cv cv) + uniqueInstances=nil + (foreach inst view->instances + (if !(member inst->cellName uniqueInstances->cellName ) then + uniqueInstances= (cons inst uniqueInstances ) + ) + ) + (foreach inst uniqueInstances + cell = (nrOpenCellViewWritable inst->libName inst->cellName inst->viewName) + (when cell + (RecursiveDeletePins ?cv cell) + ) + ) + ) +) + + +(defun DeletePinsByType (type) + (let ((view (geGetEditCellView))) + (foreach obj view->shapes + (when ( obj->pin ) + (when ( dbGetPropByName obj "PinType" )->value == type + (dbDeleteObject obj) + ) + ) + ) + ) + t ) + +(defun DeletePinsExcludeType (type) + (let ((view (geGetEditCellView))) + (foreach obj view->shapes + (when ( obj->pin ) + (when ( dbGetPropByName obj "PinType" )->value != type + (dbDeleteObject obj) + ) + ) + ) + ) + t ) + +(defun DeletePinsByPurpose (purpose) + (let ((view (geGetEditCellView))) + (foreach obj view->shapes + (when ( obj->pin ) + (when (cadr obj->lpp) == purpose + (dbDeleteObject obj) + ) + ) + ) + ) + t ) + +(defun PinUtilDeletePinsByType (view type) + (let (obj) + (foreach obj view->shapes + (when ( obj->pin ) + (when ( dbGetPropByName obj "PinType" )->value == type + (dbDeleteObject obj) + ) + ) + ) + ) + t ) + +defun( PinUtilDeleteAllSubPins (view) + let( (obj inst subCellView) + (foreach obj view->shapes + (cond ((or obj->pin obj->objType=="label") + (dbDeleteObject obj)) + ) + ) + foreach( inst view~>instances + subCellView=nrOpenCellViewWritable( inst~>libName inst~>cellName inst~>viewName ) + if( subCellView then PinUtilDeleteAllSubPins( subCellView ) + else printf("error open cell for write: %s %s %s" view~>libName view~>cellName view~>viewName )) + ) + dbSave(view) + ) +) + +; Rename pin, label, shape, and connected instance terms +(defun PinUtilRenamePin (cv fig newname) + (let (oldnet oldname newnet newpin) + oldnet = fig->net + oldname = oldnet->name + (when oldname && newname && oldname!=newname + + ; rename pins + (printf "Renaming pin %s to %s\n" oldname newname) + newnet = (dbMakeNet cv newname) + newpin = (dbCreatePin newnet fig) + newpin->term->direction = "inputOutput" + + ; rename labels and shape connectivity + (foreach shape cv->shapes + (when shape->objType=="label" && shape->theLabel==oldname + shape->theLabel = newname + ) + (when shape->net==oldnet + shape->net=nil + shape->net=newnet + ) + ) + + ; rename instTerms + (foreach term oldnet->instTerms + term->net=nil + term->net=newnet + ) + ) + ) + ) + +(defun PinUtilOrientLabels (cv) + (let (labels) + (foreach shape cv->shapes + (when shape->objType=="label" + (when (IsInList shape->lpp HorizontalMetalLPPs) + shape->orient="R0" + ) + (when (IsInList shape->lpp VerticalMetalLPPs) + shape->orient="R90" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/sync_pins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/sync_pins.il new file mode 100644 index 0000000000..e85ce3eddc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/sync_pins.il @@ -0,0 +1,157 @@ +(defun DrawSyncPins (@key (CV (geGetEditCellView))) + (let (props points layer isPin startVias endVias doubleVias flipX flipY pattern layers + pitch busShield rotateMetals newpoints paths guideInst guideInstName + patlist prelist pre buspat lo hi lohi options evens odds s pat I brkIdx path) + + + (rexCompile "^\\(.*\\)\\[\\([0-9]+\\)[\\.]*\\([0-9]*\\)\\]$") + (DeleteBusWires) + paths = nil + pattern = nil + layers = nil + lohi = nil + paths = (GetSyncGuides ?CV CV) + (foreach path paths + lohi = nil + props = (car path) + points = (cadr path) + patlist = (parseString (nth 0 props) " ") + layer = (nth 1 props) + prelist = (parseString (nth 2 props) " ") + isPin = (nth 3 props) + startVias = (nth 4 props) + endVias = (nth 5 props) + flipX = (nth 6 props) + flipY = (nth 7 props) + doubleVias = (nth 9 props) + busShield = (nth 10 props) + rotateMetals = (nth 11 props) + + ; iterate over BusPattern/BusPrefix lists + (for n 0 (length patlist)-1 + pat = (nth n patlist) + pre = (if prelist (nth (mod n (length prelist)) prelist) nil) + + ; pick pattern and array range automatically + (when (and pattern==nil lohi==nil (rexExecute pat)) + pat = (rexSubstitute "\\1") + lo = (rexSubstitute "\\2") + hi = (rexSubstitute "\\3") + (cond (hi=="" hi=(atoi lo)-1 lo=0) + (t hi=(atoi hi) lo=(atoi lo)) + ) + lohi = (list lo hi) + ) + buspat = (if pattern==nil (MapBusPattern pat) pattern) + println(pat) + println(pre) + println(lohi) + + ; draw + (when (and buspat pre lohi) + when( pat == "node_1W" ; && length(points)==2 + brkIdx = expandSyncIdx(lo hi) + for( I 0 length(brkIdx)-2 + when( I == 0 + println("hello") + println(pre) + DrawChannelArray((ChooseLayers layers layer ?rotateMetals rotateMetals) + buspat pre nth(0 brkIdx):nth(1 brkIdx) list(0 0.13 0) + points ?isPin t ?drawShield nil) + newpoints = points + ) + when( I > 0 + println(newpoints) + newpoints = computeNewPts(newpoints) + DrawChannelArray((ChooseLayers layers layer ?rotateMetals rotateMetals) + buspat pre nth(I brkIdx)+1:nth(I+1 brkIdx) list(0 0.13 0) + newpoints ?isPin t ?drawShield nil) + ) + ) + ) + ) + when( pat == "node_1W" && lohi == nil + DrawChannel((ChooseLayers layers layer ?rotateMetals rotateMetals) + buspat pre points ?isPin t ?drawShield nil) + ) + ) + ) + +fixSyncPinDirection(?CV CV) +t + ) +) + +(defun expandSyncIdx (lo hi) + (let ( s curr ) + + s = list(lo) + curr = lo + 9 + while( curr < hi + s = append(s list(curr)) + curr = curr+10 + ) + + s = append(s list(hi)) + +s + ) +) + +(defun computeNewPts (points) + (let ( newpoints ) + + when(car(ClassifyPoints(points)) == "EH" || car(ClassifyPoints(points)) == "HE" + newpoints = list(caar(points)+3.12:cadar(points) caadr(points)+3.12:cadadr(points)) + ) + + when(car(ClassifyPoints(points)) == "EV" || car(ClassifyPoints(points)) == "VE" + newpoints = list(caar(points):cadar(points)+3.12 caadr(points):cadadr(points)+3.12) + ) + +newpoints + ) +) + +(defun fixSyncPinDirection (@key (CV (geGetEditCellView))) + (let ( ne pname d_prefix e_prefix pnew ) + + foreach( ne CV~>nets + when( ne~>term~>name + pname = parseString(ne~>term~>name "_") +; when( member("i" pname ) ne~>term~>direction = "input" ) +; when( member("o" pname ) ne~>term~>direction = "output" ) + when( nth(0 pname) == "i" ne~>term~>direction = "input" ) + when( nth(0 pname) == "o" ne~>term~>direction = "output" ) +; when( member("in" pname ) ne~>term~>direction = "input" ) +; when( member("out" pname ) ne~>term~>direction = "output" ) + ) + ) +t + ) +) + +(defun GetSyncGuides (@key (CV (geGetEditCellView))) + (let (paths shapes pattern pre isPin startVias endVias flipX flipY pitch double shield rotate props) + paths = nil + (foreach obj CV~>shapes + pattern = (GetProp obj "BusPattern" nil ) + pre = (GetProp obj "BusPrefix" "" ) + isPin = (GetProp obj "BusPin" nil ) + startVias = (GetProp obj "BusStartVias" nil ) + endVias = (GetProp obj "BusEndVias" nil ) + flipX = (GetProp obj "BusFlipX" nil ) + flipY = (GetProp obj "BusFlipY" nil ) + pitch = (GetProp obj "BusArrayPitch" TrackPitch ) + double = (GetProp obj "BusDoubleVias" nil ) + shield = (GetProp obj "DrawBusShields" nil ) + rotate = (GetProp obj "RotateMetalOrientation" nil ) + props = (list pattern obj->lpp pre isPin startVias endVias flipX flipY pitch double shield rotate) + (cond ((and obj->objType=="path" pattern!=nil ) ; (or name==nil pattern==name)) + paths = (cons (list props obj->points) paths)) + ) + ) + + paths + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/vstruts.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/vstruts.il new file mode 100644 index 0000000000..e9de311870 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/pins/vstruts.il @@ -0,0 +1,1141 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( VStruts ( CellView ) + (VStrutsDrawStruts t t "All" ?CellView CellView) + (VStrutsDropM12Vias t t "All" ?CellView CellView) + (VStrutsDropM23Vias t t ?CellView CellView) + + dbSave( CellView ) + CellView +) + +; anything below this line is old code and to be deleted. + +(defun VStrutsSetProp (obj) + (when obj + (dbReplaceProp obj "VStrutObject" "boolean" t) + ) +) + +(defun VStrutsIsObject (obj) + (let (isobj) + isobj = nil + (when obj + (when (dbGetPropByName obj "VStrutObject")->value=="TRUE" + isobj=t + ) + ) + isobj + ) +) + +(defun VStrutsMakeRectFromVStrutInfo ( VStrutInfo Pitch NumPitches WireWidth WireSpacing WirePitch WirePitchOffset ) + (let ( + ( Left ( difference + ( plus WirePitchOffset + ( times WirePitch Pitch ) ) + ( times 0.5 WireWidth ) ) ) + ( Right ( plus WirePitchOffset + ( times WirePitch + ( difference ( plus Pitch NumPitches ) 1 ) ) + ( times 0.5 WireWidth ) ) ) ) + ( list + ( list + Left + ( car VStrutInfo ) ) + ( list + Right + ( cadr VStrutInfo ) ) ) ) ) + + +(defun VStrutsGetVStrutInfoTableForPitch ( PitchTable Pitch ) + ( arrayref PitchTable Pitch ) ) + +(defun VStrutsAddVStrutInfo ( PitchTable + Pitch + VStrutInfo + IsUsed ) + (let ( + ( VStrutInfoTable + (cond ( + ( arrayref PitchTable Pitch ) ) + ( + ( makeTable `vstrut nil ) ) ) ) ) + ( setarray PitchTable Pitch VStrutInfoTable ) + ( setarray VStrutInfoTable + VStrutInfo + IsUsed ) ) ) + +(defun VStrutRemoveVStrutInfo ( PitchTable + Pitch + VStrutInfo ) + (let ( + ( VStrutInfoTable ( arrayref PitchTable Pitch ) ) ) + ( remove VStrutInfo VStrutInfoTable ) ) ) + +(defun VStrutsGetDistanceToVStrut ( VStrutInfo + YRange ) + (if ( RangeDoIntersect + YRange + VStrutInfo + 1e-9 ) + ( difference + 0 + ( RangeGetSize + ( RangeIntersection + YRange + VStrutInfo ) ) ) + ( RangeGetDistance VStrutInfo YRange ) ) ) + +(defun VStrutsGetPitchForColumnData ( ColumnData + WirePitch + WirePitchOffset + Left ) + (let ( + ( Junction + ( PlacementRegionGetColumnNPJunction + ColumnData ) ) ) + (cond ( + Left + ( difference + ( round + ( quotient + ( difference + Junction + WirePitch WirePitchOffset ) + WirePitch ) ) + 1 ) ) + ( + ( difference + ( round + ( quotient + ( difference + ( plus + Junction + WirePitch ) + WirePitchOffset ) + WirePitch ) ) + 0 + ) ) ) ) ) + + +(defun VStrutsGetPitchForContactRects ( + ContactRects + WirePitch + WireSpacing + WirePitchOffset + Justification ) + (let ( + ( MinPitch + ( difference + ( ceiling + ( quotient + ( plus + ( ListFindMinimum + ContactRects + (lambda ( Rect ) + ( RectGetLeft Rect ) ) ) + ( difference + WireSpacing + WirePitchOffset + 1e-9 ) ) + WirePitch ) ) + 2 ) ) + ( MaxPitch + ( floor ( quotient + ( difference + ( ListFindMaximum + ContactRects + (lambda ( Rect ) + ( RectGetRight Rect ) ) ) + WirePitchOffset + WireSpacing + -1e-9 ) + WirePitch ) ) ) ) + (let ( + ( Range + ( ListFillList (lambda ( N ) ( plus MinPitch N ) ) + ( difference MaxPitch MinPitch -1 ) ) ) ) + ( ListFindMaximumElement + Range + (lambda ( Pitch ) + ( ListFindSum + ContactRects + (lambda ( ContactRect ) + ( RangeGetSize + (cond ( + ( RangeIntersection + ( list + ( plus WirePitchOffset + ( times WirePitch Pitch ) ) + ( plus WirePitchOffset + ( times WirePitch ( plus Pitch 2 ) ) ) ) + ( RectGetXRange ContactRect ) ) ) + ( + ( list 0 0 ) ) ) ) ) ) ) ) ) ) ) + +(defun VStrutsUpdateVStrutsForPitch ( PitchTable + Pitch + YRange + IsUsed ) + (when YRange + (let ( + ( VStrutInfoTable + ( arrayref PitchTable Pitch ) ) ) + (let ( + ( VStrutInfoToUse + (when ( tablep VStrutInfoTable ) + ( ListFindMinimumElement + ( mapcar `car ( tableToList VStrutInfoTable ) ) + (lambda ( VStrutInfo ) + ( VStrutsGetDistanceToVStrut VStrutInfo YRange ) ) ) ) ) ) + ( VStrutsMergeVStrutInfos + PitchTable + Pitch + VStrutInfoToUse + YRange + IsUsed ) ) ) ) ) + +(defun VStrutsMergeVStrutInfos ( PitchTable + Pitch + Range1 + Range2 + IsUsed ) + ( VStrutRemoveVStrutInfo + PitchTable + Pitch + Range1 ) + ( VStrutRemoveVStrutInfo + PitchTable + Pitch + Range2 ) + ( VStrutsAddVStrutInfo + PitchTable + Pitch + ( RangeUnion + Range1 + Range2 ) + IsUsed + ) ) + + +(defun VStrutsInitializePitchTablePitchTableFromHorizontalRects ( PitchTable + HorizontalRects + WirePitch + WirePitchOffset ) + ( foreach HorizontalRect HorizontalRects + (let ( + ( MinPitch + ( ceiling ( quotient ( difference + ( RectGetLeft HorizontalRect ) WirePitchOffset ) + WirePitch ) ) ) + ( MaxPitch + ( floor ( quotient ( difference + ( RectGetRight HorizontalRect ) WirePitchOffset ) + WirePitch ) ) ) ) + ( for Pitch MinPitch MaxPitch + ( VStrutsUpdateVStrutsForPitch + PitchTable + Pitch + ( RectGetYRange HorizontalRect ) + nil ) ) ) ) ) + + +(defun VStrutsGetFinalVStrutRectsFromPitchTable ( PitchTable + WireWidth + WireSpacing + WirePitch + WirePitchOffset ) + (let ( + ( VStrutRectInfos nil ) ) + ( foreach CurrPitch PitchTable + (let ( + ( CurrVStrutInfoTable ( arrayref PitchTable CurrPitch ) ) ) + ( foreach CurrVStrutInfo CurrVStrutInfoTable + (let ( + ( IsUsed ( arrayref CurrVStrutInfoTable CurrVStrutInfo ) ) ) + (if IsUsed + ( setq VStrutRectInfos + ( cons + ( VStrutsMakeRectFromVStrutInfo + CurrVStrutInfo + CurrPitch + 2 + WireWidth + WireSpacing + WirePitch + WirePitchOffset + ) + VStrutRectInfos ) ) ) ) ) ) ) + VStrutRectInfos ) ) + +(defun VStrutsGetContactRectsForInstances ( Instances + NetName + LPP ) + ( PinUtilGetPinRectsForInstances + Instances + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( SomeLPP ) ( equal ( car SomeLPP ) ( car LPP ) ) ) ) ) + + +(defun VStrutsGetBoundRectForContactRects ( ContactRects ) + ( ListApplyFuncToListAndAccumulateResult + ContactRects + (lambda ( Rect BoundRect ) + ( RectGetBoundRect + Rect + BoundRect ) ) + nil + nil ) ) + +(defun VStrutsDrawVStrutsOnCellView ( CellView + CellRegionData + NetName + Instances + WireWidth + WireSpacing + WirePitch + WirePitchOffset + ComponentContactLPP + VStrutLPP + HStrutLPP + Extension + IsNRegion + ) + (let ( + ( PitchTable ( makeTable `pitch nil ) ) ) + (let ( + ( HorizontalRects + ( PinUtilGetPinRectsForCellView + CellView + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( SomeLPP ) ( equal ( car SomeLPP ) ( car HStrutLPP ) ) ) ) ) ) + + ( VStrutsInitializePitchTablePitchTableFromHorizontalRects + PitchTable + HorizontalRects + WirePitch + WirePitchOffset ) + + (if CellRegionData + ( foreach + ColumnData + ( PlacementRegionsGetCellRegionDataColumnList CellRegionData ) + (let ( + ( ContactRects + ( VStrutsGetContactRectsForInstances + ( setof Instance Instances + ( RectIsRectInRectClose + ( getq Instance bBox ) + ( PlacementRegionGetColumnBBox ColumnData ) + 1e-9 ) ) + NetName + ComponentContactLPP + ) ) ) + (when ContactRects + ( VStrutsUpdateVStrutsForPitch + PitchTable + ( VStrutsGetPitchForColumnData + ColumnData + WirePitch + WirePitchOffset + ( equal ( not IsNRegion ) + ( PlacementRegionGetNPRegionParity ColumnData ) ) + ) + ( RectGetYRange + ( RectShrinkInY + ( VStrutsGetBoundRectForContactRects + ContactRects ) + -Extension + ) + ) + t ) + ) ) ) + (let ( + RectFig + ( ContactRects + ( VStrutsGetContactRectsForInstances + Instances + NetName + ComponentContactLPP ) ) ) + (when ContactRects + ( VStrutsUpdateVStrutsForPitch + PitchTable + ( VStrutsGetPitchForContactRects + ContactRects + WirePitch + WireSpacing + WirePitchOffset ) + ( RectGetYRange + ( RectShrinkInY + ( VStrutsGetBoundRectForContactRects ContactRects ) + ( quotient WireSpacing -4.0 ) + ) ) + t ) ) ) ) + + ( foreach VerticalRect + ( VStrutsGetFinalVStrutRectsFromPitchTable + PitchTable + WireWidth + WireSpacing + WirePitch + WirePitchOffset ) + RectFig = ( dbCreateRect + CellView + VStrutLPP + VerticalRect ) + ( VStrutsSetProp RectFig ) + ( dbCreatePin + ( dbMakeNet CellView NetName ) + RectFig ) ) ) ) ) + + + + + + + + +(defun VStrutsGetExtendedConnectToRectsToFromRects ( CellView + ConnectToRects + ConnectFromRects + ConnectToLPP + ) + (mapcar + (lambda ( ConnectToRect ) + (let ( + ( Intersect + ( VStrutsGetExtendedConnectToRectToFromRects + ConnectToRect + ConnectFromRects + ConnectToLPP ) ) ) + Intersect ) ) + ConnectToRects ) ) + + +(defun VStrutsGetExtendedConnectToRectToFromRects ( ConnectToRect + ConnectFromRects + ConnectToLPP ) + (let ( + RectFig + ( ConnectFromRect + ( ListFindMinimumElement + ConnectFromRects + (lambda ( ConnectFromRect ) + ( RectGetDistanceFromRectToRect + ConnectToRect + ConnectFromRect ) ) ) ) ) + (when ConnectFromRect + (let ( + ( Rect + ( VStrutsGetFootInTheDoorExtendedConnectToRectToFromRect + ConnectToRect + ConnectFromRect + .005 ) ) ) + (when ( not ( RectIsRectInRectClose + Rect + ConnectToRect + 1e-9 ) ) + RectFig = ( dbCreateRect + CellView + ConnectToLPP + Rect ) + ( VStrutsSetProp RectFig ) + ) + Rect ) ) ) ) + +(defun VStrutsGetFootInTheDoorExtendedConnectToRectToFromRect ( ConnectToRect + ConnectFromRect + Distance + ) + ( RectGetBoundRect + ConnectToRect + ( BBoxCanonicalize + (cond ( + ;left + ( leqp + ( RectGetRight ConnectToRect ) + ( RectGetLeft ConnectFromRect ) + ) + ( list + ( list + ( RectGetLeft ConnectToRect ) + ( RectGetBottom ConnectToRect ) ) + ( list + ( plus ( RectGetLeft ConnectFromRect ) Distance ) + ( RectGetTop ConnectToRect ) ) ) ) + ( + ;right + ( geqp + ( RectGetLeft ConnectToRect ) + ( RectGetRight ConnectFromRect ) + ) + ( list + ( list + ( difference ( RectGetRight ConnectFromRect ) Distance ) + ( RectGetBottom ConnectToRect ) ) + ( list + ( RectGetRight ConnectToRect ) + ( RectGetTop ConnectToRect ) ) ) ) + ( + ;overlaps + ConnectToRect + ) ) ) ) ) + +(defun VStrutsGetGetMinimalExtendedConnectToRectToFromRect ( + ConnectToRect + ConnectFromRect + ViaCutWidth + ViaMinExtension + ViaXExtension + ViaYExtension + ) + ( println ( list ConnectToRect ConnectFromRect ) ) + + (let ( + ( CenterY + ( cadr ( RectGetCenter ConnectToRect ) ) ) + ( HalfHeight + ( plus + ( times 0.5 ViaCutWidth ) + ViaYExtension ) ) ) + (let ( + ( Bottom + ( difference CenterY HalfHeight ) ) + ( Top + ( plus CenterY HalfHeight ) ) + ) + ( BBoxCanonicalize + (cond ( + ( leqp + ( RectGetRight ConnectFromRect ) + ( RectGetRight ConnectToRect ) ) + ( list + ( list + ( difference + ( RectGetRight ConnectFromRect ) + ( plus + ( plus ViaMinExtension ViaXExtension ) + ViaCutWidth ) ) + Bottom + ) + ( list + ( plus + ( RectGetRight ConnectFromRect ) + ( difference + ViaXExtension ViaMinExtension ) ) + Top + ) ) ) + ( + ( geqp + ( RectGetLeft ConnectFromRect ) + ( RectGetLeft ConnectToRect ) ) + ( list + ( list + ( difference + ( RectGetLeft ConnectFromRect ) + ( difference + ViaXExtension ViaMinExtension ) ) + Bottom + ) + ( list + ( plus + ( RectGetLeft ConnectFromRect ) + ( plus + ( plus ViaMinExtension ViaXExtension ) + ViaCutWidth ) ) + Top + ) ) ) + ( t ConnectToRect ) + ) ) ) ) ) + + +(defun VStrutsTestRect ( CellView + Rect + ContactRect + Spacing + LPP ) + (let ( + ( Rect + ( RectShrinkInX + ( RectShrinkInY + Rect + -Spacing+.005 ) + -Spacing+.005 ) ) ) + (let ( + ( Ret + (if ( not + ( exists + Path + ( dbProduceOverlap + CellView + Rect + ( list 1 4 ) + LPP ) + ( not + ( RectIsRectInRectClose + ( TransformGetBBoxFromPath + Path ) + ( RectGetBoundRect + Rect + ContactRect ) + 1e-9 + ) ) ) ) + t ) ) ) + Ret + ) ) ) + + + + +(defun VStrutsDrawContactsAtIntersectionOfRects ( CellView + ConnectToLPP + ConnectFromLPP + ConnectToSpacing + ConnectToRects + ConnectFromRects + ViaLibraryName + ViaMasterNameFormat + ViaViewName + ViaCutWidth + ViaMinExtension + ViaExtension + ViaXSpacing + ViaYSpacing + ConnectAll + DrawRect + ExtendTo + ) + (let ( + ( GetInstanceInfoFunc + (lambda ( RectIntersection ) + ( VStrutsGetViaInstanceInfoForRect + RectIntersection + ViaLibraryName + ViaMasterNameFormat + ViaViewName + ConnectToLPP + ConnectFromLPP + ViaCutWidth + ViaMinExtension + ViaExtension + ViaXSpacing + ViaYSpacing ) ) ) + ( Func (if ConnectAll `foreach `exists ) ) ) + ( eval + ( ExpressionReplaceSymbolsWithValues + `( foreach + ConnectToRect + ConnectToRects + ( Func + ConnectFromRect + ConnectFromRects + (let ( + ( RectIntersection + ( RectGetIntersection + ConnectToRect + ConnectFromRect ) ) + ( RectM1BL ( list + ( RectGetLeft ConnectFromRect ) + ( RectGetBottom ConnectToRect ) ) ) + ( RectM1UR ( list + ( RectGetRight ConnectFromRect ) + ( RectGetTop ConnectToRect ) ) ) + ) + +;(setq RectIntersection ( RectGetIntersection ConnectToRect ConnectFromRect ) ) +;(when (equal ConnectToLPP Metal1LPP) +; (setq RectIntersection (list RectM1BL RectM1UR) ) +;) + (if RectIntersection + (let ( + ( InstanceInfo + ( apply + GetInstanceInfoFunc + ( list RectIntersection ) ) ) ) +; ( list ( list RectBL RectUR ) ) ) ) ) + + (when ( and DrawRect InstanceInfo ) + ( dbCreateRect + CellView + ConnectToLPP + RectIntersection ) ) +; ( list RectBL RectUR ) ) ) + + ;try extending the ToRect to FromRect horizontally + (when ( and + ( null InstanceInfo ) + ) + (let ( + ( NewRect + ( VStrutsGetGetMinimalExtendedConnectToRectToFromRect + ConnectToRect + ConnectFromRect + ViaCutWidth + ViaMinExtension + ViaExtension + ViaExtension + ) ) ) + (when ( VStrutsTestRect + CellView + NewRect + ConnectToRect + ConnectToSpacing + ConnectToLPP ) + ( setq + InstanceInfo + ( apply + GetInstanceInfoFunc + ( list + NewRect + ) ) ) ) + + (when ( null InstanceInfo ) + ( setq + NewRect + ( VStrutsGetGetMinimalExtendedConnectToRectToFromRect + ConnectToRect + ConnectFromRect + ViaCutWidth + ViaMinExtension + ViaExtension + ViaMinExtension + ) ) + (when ( VStrutsTestRect + CellView + NewRect + ConnectToRect + ConnectToSpacing + ConnectToLPP ) + ( setq + InstanceInfo + ( apply + GetInstanceInfoFunc + ( list + NewRect + ) ) ) ) ) + + + (when ( null InstanceInfo ) + ( setq + NewRect + ( VStrutsGetGetMinimalExtendedConnectToRectToFromRect + ConnectToRect + ConnectFromRect + ViaCutWidth + ViaMinExtension + ViaMinExtension + ViaExtension + + ) ) + (when ( VStrutsTestRect + CellView + NewRect + ConnectToRect + ConnectToSpacing + ConnectToLPP ) + ( setq + InstanceInfo + ( apply + GetInstanceInfoFunc + ( list + NewRect + ) ) ) ) ) + + (when InstanceInfo + ( dbCreateRect + CellView + ConnectToLPP + NewRect ) ) ) ) + + ;try using the whole connecttorect + (when ( null InstanceInfo ) + ( setq InstanceInfo + ( apply + GetInstanceInfoFunc + ( list ConnectToRect ) ) ) + (when InstanceInfo + ( dbCreateRect + CellView + ConnectFromLPP + ConnectToRect ) + ( dbCreateRect + CellView + ConnectToLPP + ConnectToRect ) ) + ) + + ;try adding on some extension + (when ( null InstanceInfo ) + (let ( + ( NewRect + ( VStrutsGetCrappyHackRect + ConnectFromRect + ConnectToRect + ViaLibraryName + ViaMasterNameFormat + ViaViewName + ConnectToLPP + ConnectFromLPP + ViaCutWidth + ViaMinExtension + ViaExtension + ViaXSpacing + ViaYSpacing ) ) ) + ( setq InstanceInfo + ( apply + GetInstanceInfoFunc + ( list NewRect ) ) ) + ( dbCreateRect + CellView + ConnectToLPP + NewRect ) + ( dbCreateRect + CellView + ConnectFromLPP + NewRect ) ) ) + + ( VStrutsDrawViaInstanceInfo + CellView + InstanceInfo ) + + ) ) ) ) ) + ( list `Func ) ) ) ) ) + + +(defun VStrutsDrawViaInstanceInfo ( CellView InstanceInfo ) + (when InstanceInfo + ( AutoPinCreateInstance + CellView + InstanceInfo + nil ) ) ) + + +(defun VStrutsGetViaInstanceInfoForRect ( Rect + ViaLibraryName + ViaMasterNameFormat + ViaViewName + ConnectToLPP + ConnectFromLPP + ViaCutWidth + ViaMinExtension + ViaExtension + ViaXSpacing + ViaYSpacing ) + (when Rect + (let ( + ( ColumnRowPair + ( ListFindMaximumElement + ( setof + ColumnRowPair + ( list ( list 1 1 ) ( list 1 2 ) + ( list 2 1 ) ( list 2 2 ) ) + ( exists + WidthHeightPair + ( ListNonDestructiveMapCan + (lambda ( WidthHeightPair ) + ( list + ( list ( plus ( car WidthHeightPair ) ( times 2.0 ViaExtension ) ) + ( plus ( cadr WidthHeightPair ) ( times 2.0 ViaMinExtension ) ) ) + ( list ( plus ( car WidthHeightPair ) ( times 2.0 ViaMinExtension ) ) + ( plus ( cadr WidthHeightPair ) ( times 2.0 ViaExtension ) ) ) ) ) + ( list + ( list + ( plus ( times ( car ColumnRowPair ) ViaCutWidth ) + ( times ( difference ( car ColumnRowPair ) 1 ) ViaXSpacing ) ) + ( plus ( times ( cadr ColumnRowPair ) ViaCutWidth ) + ( times ( difference ( cadr ColumnRowPair ) 1 ) ViaYSpacing ) ) ) ) + ) + ( and + ( lessp ( car WidthHeightPair ) + ( plus ( RectGetWidth Rect ) 1e-9 ) ) + ( lessp ( cadr WidthHeightPair ) + ( plus ( RectGetHeight Rect ) 1e-9 ) ) ) ) ) + (lambda ( ColumnRowPair ) ( plus ( times 1.1 ( car ColumnRowPair ) ) + ( times 1.0 ( cadr ColumnRowPair ) ) ) ) ) ) ) + ( println ColumnRowPair ) + (if ColumnRowPair + ( AutoPinMakeViaInstanceInfo + ViaLibraryName + ViaMasterNameFormat + nil + ViaViewName + ConnectToLPP + ConnectFromLPP + ( RectGetCenter Rect ) + ( plus ViaXSpacing ViaCutWidth ) + ( plus ViaYSpacing ViaCutWidth ) + ?Row ( cadr ColumnRowPair ) + ?Column ( car ColumnRowPair ) ) ) ) ) ) + + + ;in the case the interesection is not big enough for a via, do the crappy thing + ;and make a via justified to outsied edge of ConnectToRect and rect on both layers + ;big enough to satisfy via extension +(defun VStrutsGetCrappyHackRect ( ConnectFromRect + ConnectToRect + ViaLibraryName + ViaMasterNameFormat + ViaViewName + ConnectToLPP + ConnectFromLPP + ViaCutWidth + ViaMinExtension + ViaExtension + ViaXSpacing + ViaYSpacing ) + (let ( + ( YOffset ( plus ViaExtension ( times 0.5 ViaCutWidth ) ) ) + ( XOffset ( plus ( times 2.0 ViaMinExtension ) ( times 0.5 ViaCutWidth ) ) ) + ( YCenter ( RangeGetMidpoint ( RectGetYRange ConnectToRect ) ) ) ) + (let ( + ( FillRect (cond ( + ( lessp ( caar ConnectToRect ) ( caar ConnectFromRect ) ) + ( list + ( list ( caar ConnectToRect ) + ( difference YCenter YOffset ) ) + ( list ( caadr ConnectToRect ) + ( plus YCenter YOffset ) ) ) ) + ( + t + ( list + ( list ( caar ConnectToRect ) + ( difference YCenter YOffset ) ) + ( list ( caadr ConnectToRect ) + ( plus YCenter YOffset ) ) ) ) ) ) ) + FillRect ) ) ) + + + + + + +(defun VStrutsDrawStruts ( DoGND DoVdd Extent @key (CellView (UIGetCellView))) + (let ( Instances Gates Chains ConnectFromRects ChainPins GatePins Regions) + Instances= (if ( equal Extent "All" ) + ( getq CellView instances ) + ( setof Selected ( geGetSelectedSet ) + ( equal ( getq Selected objType ) "inst" ) ) ) + ( foreach NetName ( append (if DoGND ( list GNDNetName ) ) + (if DoVdd ( list VddNetName ) ) ) + Regions=( PlacementRegionsScrapeCellRegionDataFromCellView + CellView + Instances + NChainLibCellPairRegExs + PChainLibCellPairRegExs + GateLibCellPairRegExs + NPlugLibCellPairRegExs + PPlugLibCellPairRegExs + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ( times UserUnitsPerMeter MinWellSpacing ) + CellView->prBoundary + 0.0 + ( times UserUnitsPerMeter DefaultWiringSpacing/2) + ) + (when !(car Regions) + (printf "Can't find gates to place strut for %s.\n" NetName) + ) + + ( VStrutsDrawVStrutsOnCellView + CellView + Regions + NetName + Instances + ( times UserUnitsPerMeter DefaultWireWidth ) + ( times UserUnitsPerMeter DefaultWireSpacing ) + ( times UserUnitsPerMeter DefaultWirePitch ) + ( times UserUnitsPerMeter M2StrutOffset ) + Metal1LPP + Metal2LPP + Metal3LPP + ( times UserUnitsPerMeter ContactExtension ) + ( equal NetName GNDNetName ) + ) + ) + ;;;;;;;;;;;;;;;;;;; + ;;; TSMC28 specific tweaks + ;;;;;;;;;;;;;;;;;;; + ;to meet drc, we have to shorten the GND struts away from the prbound, + ;extend the Vdd struts to extend to the end of the via, + ;and shrink their width for fat wire spacing + ( foreach shape CellView->shapes + ( when (VStrutsIsObject shape) && shape->lpp==Metal2LPP + shape->bBox = ( RectShrinkInX shape->bBox 0.015 ) + ( when shape->net->name==GNDNetName + shape->bBox = ( RectShrinkInY shape->bBox 0.01 ) + ) + ( when shape->net->name==VddNetName + shape->bBox = ( RectShrinkInY shape->bBox -0.035 ) + ) + ) + ) + ;;;;;;;;;;;;;;;;;;; + ;;;;;;;;;;;;;;;;;;; + ) +) + + + +(defun VStrutsDropM12Vias ( DoGND DoVdd Extent @key (CellView (UIGetCellView) )) + (let ( Instances Gates Chains ConnectFromRects ChainPins GatePins ThisNet) + Instances= (if ( equal Extent "All" ) + ( getq CellView instances ) + ( setof Selected ( geGetSelectedSet ) + ( equal ( getq Selected objType ) "inst" ) ) ) + WellPlugLibCellPairRegExs=list( list( "^stack$" "stack\\.[NP]PLUG\\.0")) + Gates= ( cadr ( NameFilterInstances + Instances + GateLibCellPairRegExs ) ) + Chains= ( cadr ( NameFilterInstances + Instances + ChainLibCellPairRegExs ) ) + WellPlugs= ( cadr ( NameFilterInstances + Instances + WellPlugLibCellPairRegExs ) ) + + ( foreach NetName ( append (if DoGND ( list GNDNetName ) ) + (if DoVdd ( list VddNetName ) ) ) + ThisNet=dbMakeNet( CellView NetName ) + ConnectFromRects= ( PinUtilGetPinRectsForCellView + CellView + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( LPP ) ( equal ( car LPP ) ( car Metal2LPP ) ) ) ) + + ChainPins= (VStrutsGetExtendedConnectToRectsToFromRects + CellView + ( PinUtilGetPinRectsForInstances + Chains + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( LPP ) ( equal ( car LPP ) ( car Metal1LPP ) ) ) ) + ConnectFromRects + Metal1LPP + ) + GatePins= (PinUtilGetPinRectsForInstances + Gates + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( LPP ) ( equal ( car LPP ) ( car Metal1LPP ) ) ) ) + WellPlugPins= (PinUtilGetPinRectsForInstances + WellPlugs + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( LPP ) ( equal ( car LPP ) ( car Metal1LPP ) ) ) ) + + (foreach Stripe ConnectFromRects + (foreach Pin (append (append GatePins ChainPins ) WellPlugPins ) + (when (RectGetIntersection Stripe Pin) + Via=(dbCreateVia + CellView + ( techFindViaDefByName TechLib LeafM12PwrVia ) + ( list (car (RectGetCenter Stripe)) (cadr (RectGetCenter Pin)) ) + "R0") + (VStrutsSetProp Via) + Via->net=ThisNet + ) + ) + ) + + ) + +)) + + +(defun VStrutsDropM23Vias ( DoGND DoVdd @key (CellView (UIGetCellView))) + (let ( + ConnectFromRects ConnectToRects Intersection Via xCoordVia yCoordVia ThisNet + ) + + ( foreach NetName ( append (if DoGND ( list GNDNetName ) ) + (if DoVdd ( list VddNetName ) ) ) + ThisNet=dbMakeNet( CellView NetName ) + ConnectFromRects = ( PinUtilGetPinRectsForCellView + CellView + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( LPP ) ( equal ( car LPP ) ( car Metal2LPP ) ) ) ) + ConnectToRects = ( PinUtilGetPinRectsForCellView + CellView + (lambda ( SomeNetName ) ( equal SomeNetName NetName ) ) + (lambda ( LPP ) ( equal ( car LPP ) ( car Metal3LPP ) ) ) ) + + (foreach Strut ConnectFromRects + (foreach Stripe ConnectToRects + Intersection=(RectGetIntersection Strut Stripe) + (when Intersection + + (if (cadr (car Intersection)) < 2*DefaultWiringPitch || + (cadr (car Intersection)) > (cadr (cadr (GetPrbound CellView)->bBox))-2*DefaultWiringPitch then + Via=(dbCreateVia + CellView + ( techFindViaDefByName TechLib LeafM23EdgePwrVia ) + (RectGetCenter Intersection) + "R0") + (VStrutsSetProp Via) + Via->net=ThisNet + else + Via=(dbCreateVia + CellView + ( techFindViaDefByName TechLib LeafM23PwrVia ) + (RectGetCenter Intersection) + "R0") + (VStrutsSetProp Via) + Via->net=ThisNet + ) + ) + ) + ) + ) + + ;;;;;;;;;;;;;;;;;;; + ;;; TSMC28 specific tweaks + ;;;;;;;;;;;;;;;;;;; + ;to meet drc, we have to fix the placement of the vias to be space = 0.08 + (foreach item CellView->vias + (when (item->viaHeader->viaDefName==LeafM23EdgePwrVia || item->viaHeader->viaDefName==LeafM23PwrVia) && + (VStrutsIsObject item) + yCoordVia=(cadr item -> origin) + xCoordVia=(car item -> origin) + ;except we don't have to at the edges because those struts were already shortened + if(yCoordVia<2*DefaultWiringPitch then + item->origin = (list xCoordVia (yCoordVia - 0.005) )) + if(yCoordVia>(cadr (cadr (GetPrbound CellView)->bBox))-2*DefaultWiringPitch then + item->origin = (list xCoordVia (yCoordVia + 0.005) )) + (unless yCoordVia<2*DefaultWiringPitch || + yCoordVia>(cadr (cadr (GetPrbound CellView)->bBox))-2*DefaultWiringPitch + (if (yCoordVia-(floor yCoordVia/PowerGridPitch)*PowerGridPitch) < PowerGridPitch/2 then + item->origin = (list xCoordVia (yCoordVia + 0.005) ) + else + item->origin = (list xCoordVia (yCoordVia - 0.005) ) + ) + ) + ) + ) + ;;;;;;;;;;;;;;;;;;; + ;;;;;;;;;;;;;;;;;;; + + ) +) + + +(defun VStrutsDeleteObjects ( @key (CellView (UIGetCellView) )) + (let ( Shapes) + (foreach shape CellView->shapes + (when (VStrutsIsObject shape) + (dbDeleteObject shape) + ) + ) + (foreach shape CellView->vias + (when (VStrutsIsObject shape) + (dbDeleteObject shape) + ) + ) + ) +) + + +(defun ConnectLeafPower ( @key (cv (UIGetCellView)) ) + (VStrutsDrawStruts t t "All") + (VStrutsDropM12Vias t t "All") + (VStrutsDropM23Vias t t) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/power_grid/power_grid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/power_grid/power_grid.il new file mode 100644 index 0000000000..8fa2251fe5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/power_grid/power_grid.il @@ -0,0 +1,160 @@ +; add a standard power grid to a cellview +(defun AddPowerGrid (@key (CellView nil) (bbox nil)) + (let (x0 y0 x1 y1 power) + (cond (CellView==nil CellView = (geGetEditCellView))) + (cond (bbox==nil bbox = CellView->bBox)) + gp = 2*PowerGridPitch + x0 = (leftEdge bbox) + y0 = (bottomEdge bbox) + x1 = (rightEdge bbox) + y1 = (topEdge bbox) + x0 = (floor x0/gp) + y0 = (floor y0/gp) + x1 = (ceiling x1/gp) + y1 = (ceiling y1/gp) + power = (dbOpenCellViewByType "globals" "globals.wires.POWER_GRID_M34567" "layout") + (dbCreateSimpleMosaic CellView power "power" + gp*x0:gp*y0 "R0" + y1-y0 x1-x0 + gp gp) + ) + t + ) + +; check if a lib/cell/view is legal +(defun ViewExists (view viewName) + (let (views) + views = (dbAllCellViews view->lib view->cellName) + (setof v views v==viewName)!=nil + ) + ) + +; creates a layout_nogrid view without power grid or POWER_GRID_TIEOFF subcells +; processes subcells recursively if they don't already have layout_nogrid views +(defun CreateNoGridView (@key (CellView nil)) + (let (libName cellName hasNoGridView) + + ; select view to start from + (cond (CellView==nil CellView = (geGetEditCellView))) + libName = CellView->libName + cellName = CellView->cellName + + ; recursively generate layout_nogrid views if they don't exist + (cond ((ViewExists CellView "layout_nogrid")==nil + (printf "Creating %s %s layout_nogrid\n",CellView->libName,CellView->cellName) + (dbSave CellView CellView->libName CellView->cellName "layout_nogrid") + CellView = (dbOpenCellViewByType CellView->libName CellView->cellName + "layout_nogrid" nil "a") + + ; delete POWER_GRID mosaics + (rexCompile "^globals\\.wires\\.POWER_GRID_.*") + (foreach mosaic CellView->mosaics + (cond ((rexExecute (car mosaic->instanceList)->cellName) + (dbDeleteObject mosaic)))) + + ; delete any *POWER_GRID* instances + (rexCompile "POWER_GRID") + (foreach inst CellView->instances + (cond ((and inst->objType=="inst" (rexExecute inst->cellName)) + (dbDeleteObject inst)))) + + ; delete any y1..y7 layers + (foreach shape CellView->shapes + (cond ((or shape->layerName=="y1" + shape->layerName=="y2" + shape->layerName=="y3" + shape->layerName=="y4" + shape->layerName=="y5" + shape->layerName=="y6" + shape->layerName=="y7") + (dbDeleteObject shape) + ) + ) + ) + + ; recursively create and swap in layout_nogrid subcells + (rexCompile "^vendor\\..*") + (foreach inst CellView->instances + (cond ((and inst->objType=="inst" + inst->viewName=="layout" + !(rexExecute inst->libName) + !(GetProp inst->master "isSynchronous" nil) + inst->libName!="globals" + inst->libName!="gate" + inst->libName!="stack" + inst->libName!="tsmc13lg") + (CreateNoGridView ?CellView inst->master) + inst->master = (dbOpenCellViewByType inst->master->lib + inst->master->cellName + "layout_nogrid") + ) + ) + ) + + ) + ) + (dbOpenCellViewByType libName cellName "layout_nogrid" nil "a") + ) + ) + +; flatten any y1 shapes of selected view to power_grid view +(defun CreatePowerGridView (@key (CellView nil)) + (let (libName cellName AssuraLayerMappings TempDir + AssuraRuleFile PdkRoot AssuraRunLog ErrorStr) + + ; select view to start from + (cond (CellView==nil CellView = (geGetEditCellView))) + libName = CellView->libName + cellName = CellView->cellName + + ; flatten power_grid view if it doesn't already exist + (cond ((ViewExists CellView "power_grid")==nil + AssuraLayerMappings = (list (list "m3keep" Metal3LPP) + (list "m4keep" Metal4LPP) + (list "m5keep" Metal5LPP) + (list "m6keep" Metal6LPP) + (list "m7keep" Metal7LPP) + (list "via3keep" Via34LPP) + (list "via4keep" Via45LPP) + (list "via5keep" Via56LPP) + (list "via6keep" Via67LPP) + ) + TempDir = (ConfigFileGetValue TheCDSConfigTable "TEMP") + AssuraRuleFile = "flattenPowerGrid.rul" + PdkRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + AssuraRuleFile = (sprintf nil "%s/share/Fulcrum/cell_automation/%s" + PdkRoot AssuraRuleFile) + AssuraRunLog = (sprintf nil "%s/%s.power_grid.log" TempDir cellName ) + ErrorStr = (AssuraRunAssuraLayerProcessor + CellView libName cellName "power_grid" + AssuraRuleFile TempDir AssuraLayerMappings nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + ) + ) + (dbOpenCellViewByType libName cellName "power_grid" nil "a") + ) + ) + +; create the layout_topgrid view by combining layout_nogrid and power_grid views +(defun CreateTopGridView (@key (CellView nil)) + (let (libName cellName noGridView powerGridView topGridView) + + ; select view to start from + (cond (CellView==nil CellView = (geGetEditCellView))) + libName = CellView->libName + cellName = CellView->cellName + + ; create power_grid and layout_nogrid views + noGridView = (CreateNoGridView ?CellView CellView) + powerGridView = (CreatePowerGridView ?CellView CellView) + + ; combine them into layout_topgrid view + (dbSave noGridView libName cellName "layout_topgrid") + topGridView = (dbOpenCellViewByType libName cellName "layout_topgrid" nil "a") + (foreach shape powerGridView->shapes (dbCopyFig shape topGridView)) + (foreach inst powerGridView->instances (dbCopyFig inst topGridView)) + topGridView + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/AutoGeneratePowerGrid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/AutoGeneratePowerGrid.il new file mode 100644 index 0000000000..62d38b458e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/AutoGeneratePowerGrid.il @@ -0,0 +1,391 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( AutoGeneratePowerGrid ( CellView powerCellName + @key + (powerViewName "layout") + (powerAbstractViewName "abstract") + (OBSCellName "") + (OBSViewName "layout") + (overhang t) ; add an extra grid around the outside + ) + prog(( powerTempView powerGridView x1 x2 y1 y2 x y x1box x2box y1box y2box + AssuraLayerMappings AssuraRuleFile powerGridView layoutWithPowerGridView powerGridAbstractView + count lpp shape ReplaceCellNameTable pinLayerName pinLayerPurpose tmp OBSView blockShapes) + PowerGridSize=2*PowerGridPitch + PowerGridLib="globals" + ReplaceCellNameTable=makeTable("a" "") + ReplaceCellNameTable["M3"]="globals.wires.POWER_GRID_M34567" + ReplaceCellNameTable["M4"]="globals.wires.POWER_GRID_M4567" + ReplaceCellNameTable["M5"]="globals.wires.POWER_GRID_M567" + ReplaceCellNameTable["M6"]="globals.wires.POWER_GRID_M67" + ReplaceCellNameTable["M7"]="globals.wires.POWER_GRID_M78" + ReplaceCellNameTable["M8"]="globals.wires.POWER_GRID_M8" + if( setof( lpp CellView~>lpps lpp~>layerName=="prBoundary" ) == nil then + printf("Error: There is no prBoundary layer defined in cellview %s. \n" CellView~>cellName) + return(nil) + ) + powerTempView=dbOpenCellViewByType( CellView~>libName CellView~>cellName "autoPowerGrid_temp" "maskLayout" "w" ) + if( powerTempView == nil then + printf("Error: Can not open cellview %s (autoPowerGrid_temp) for write. \n" CellView~>cellName) + return(nil) + ) + powerGridView=nrOpenCellViewWritable(CellView~>libName powerCellName powerViewName) + if( powerGridView == nil then + printf("Error: Can not open cellview %s (%s) for write. \n" powerCellName powerViewName) + return(nil) + ) + dbCreateInst( powerTempView CellView "I0" list(0 0) "R0" ) + + ; Draw 5.76 x 5.76 rectangle grid + x1box=leftEdge( powerTempView~>bBox ) + x2box=rightEdge( powerTempView~>bBox ) + y1box=bottomEdge( powerTempView~>bBox ) + y2box=topEdge( powerTempView~>bBox ) + + ; minimum sized power grid + x1=floor(x1box/PowerGridSize) + y1=floor(y1box/PowerGridSize) + x2=floor(x2box/PowerGridSize) + y2=floor(y2box/PowerGridSize) + + when( modulo( floor(x2box*1000) floor(PowerGridSize*1000) )==0 + x2=x2-1 + ) + when( modulo( floor(y2box*1000) floor(PowerGridSize*1000) )==0 + y2=y2-1 + ) + + ; expand the power grid + when( overhang + x1 = x1-1 + y1 = y1-1 + x2 = x2+1 + y2 = y2+1 + ) + + ; create rectangles for Assura processing + for( i x1 x2 + x=i*PowerGridSize + for( j y1 y2 + y=j*PowerGridSize + dbCreateRect(powerTempView list("y0" "drawing") list(x:y x+PowerGridSize-0.005:y+PowerGridSize-0.005)) + ) + ) + + dbSave( powerTempView ) + printf("Creating %s layout\n" powerCellName ) + ; run layer processing + AssuraLayerMappings = (list + (list "power345678" (list "M3" "block")) + (list "power45678" (list "M4" "block")) + (list "power5678" (list "M5" "block")) + (list "power678" (list "M6" "block")) + (list "power78" (list "M7" "block")) + (list "power8" (list "M8" "block")) + (list "m1Keepout" (list "M1" "boundary")) + (list "m1Keepout" (list "M1" "boundary")) + (list "m2Keepout" (list "M2" "boundary")) + (list "m3Keepout" (list "M3" "boundary")) + (list "m4Keepout" (list "M4" "boundary")) + (list "m5Keepout" (list "M5" "boundary")) + (list "m6Keepout" (list "M6" "boundary")) + (list "m7Keepout" (list "M7" "boundary")) + (list "m8Keepout" (list "M8" "boundary")) + ) + AssuraRuleFile = sprintf( nil "%s/share/Fulcrum/cell_automation/%s" + ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT") + "generatePowerGrid.rul") + AssuraRunLog = sprintf( nil "%s/%s.power_grid.log" + ConfigFileGetValue( TheCDSConfigTable "TEMP") + CellView~>cellName ) + ErrorStr = AssuraRunAssuraLayerProcessor( + powerTempView CellView~>libName powerCellName powerViewName + AssuraRuleFile + ConfigFileGetValue( TheCDSConfigTable "TEMP") + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + ddDeleteObj(ddGetObj(powerTempView~>libName powerTempView~>cellName powerTempView~>viewName)) + powerGridView=nrOpenCellViewWritable(CellView~>libName powerCellName powerViewName) + + count=0 + x1=nil + y1=nil + foreach( lpp powerGridView~>lpps + if(ReplaceCellNameTable[lpp~>layerName]!="" && lpp~>purpose=="block" then + powerMosaicView=nrOpenCellViewReadable( PowerGridLib ReplaceCellNameTable[lpp~>layerName] "layout" ) + foreach( shape lpp~>shapes + if( shape~>objType == "rect" || (shape~>objType == "polygon" && shape~>nPoints==5) then + x2=leftEdge(shape~>bBox) + y2=bottomEdge(shape~>bBox) + dbCreateInst(powerGridView powerMosaicView + sprintf( nil "I%d" count ) + list(x2 y2) + "R0" ) + dbDeleteObject(shape) + count=count+1 + cond((y1==nil y1=y2 x1=x2) + (y2layerName) + ) + ) + ) + ) + if( x1!=nil && y1!=nil then + CreatePowerPins( powerGridView "M7" list(x1 y1) nil ) + else + printf("Error: no shape created in PowerGrid View.\n") + return(nil) + ) + + foreach( shape CellView->shapes + when( car(shape->lpp)=="prBoundary" && shape->objType=="rect" + dbCreateRect( powerGridView shape->lpp shape->bBox) + ) + when( car(shape->lpp)=="prBoundary" && shape->objType=="polygon" + dbCreatePolygon( powerGridView shape->lpp shape->points) + ) + ) + + dbSave(powerGridView) + OBSView=nrOpenCellViewReadable( powerGridView->libName OBSCellName OBSViewName ) + if( OBSView then + dbCreateInst( powerGridView OBSView "obs" list(0 0) "R0" ) + dbSave(powerGridView) + printf("OBS %s instantiated in powerGrid. \n" OBSCellName ) + else + if( OBSCellName != "" then + printf("Info: OBS view %s (%s) does not exist. \n" OBSCellName OBSViewName ) + ) + ) + blockShapes= (setof shape CellView~>shapes + (or shape~>purpose=="boundary" + (and shape~>layerName=="prBoundary" + shape~>purpose=="block"))) + foreach( shape blockShapes dbCopyFig( shape powerGridView)) + foreach( shape blockShapes dbDeleteObject(shape)) + printf("Done: %s (%s) created. \n" powerCellName powerViewName) + return(powerGridView) + ) +) + +defun( AutoGeneratePowerGridAbstract ( CellView powerCellName + @key + (powerViewName "layout") + (powerAbstractViewName "abstract") + (OBSCellName "") + (OBSViewName "layout") + (M3PowerPins t) + (M5PowerPins nil) + (M7PowerPins nil) + (ResolveMacroBlockageConflict nil) + (M1M2_Ring t) + (Class "block") + ) + + prog(( powerGridView powerGridAbstractView AssuraLayerMappings + powerGridViewTemp NewInst InstAbstractView ViewToAssura + AssuraRuleFile AssuraRunLog ErrorStr power_layers + blockCells blockShapes m1points) + + ; open power grid CV + powerGridView=nrOpenCellViewWritable(CellView~>libName powerCellName powerViewName) + if( powerGridView == nil then + printf("Error: Can not open cellview %s (%s) for write. \n" powerCellName powerViewName) + return(nil) + ) + powerGridViewTemp=nil + ViewToAssura=powerGridView + + ; copy abstract views of subcells so stripes avoid their keepout too + if( ResolveMacroBlockageConflict then + powerGridViewTemp=dbCopyCellView( powerGridView CellView~>libName powerCellName + strcat(powerViewName "_temp") nil nil t ) + if( powerGridViewTemp == nil then + printf("Error: Can not open cellview %s (%s_temp) for write. \n" + powerCellName powerViewName) + return(nil) + ) + foreach( inst CellView~>instances + when( inst~>libName!=TechLibName && inst~>master!=powerGridView + InstAbstractView=nrOpenCellViewReadable(inst~>libName inst~>cellName "abstract_edit" ) + unless( InstAbstractView InstAbstractView=nrOpenCellViewReadable(inst~>libName inst~>cellName "abstract" ) ) + if( InstAbstractView then + NewInst=dbCreateInst( powerGridViewTemp InstAbstractView inst->name inst->xy inst->orient ) + else + printf("Can't open abstract view for %s\n" inst->cellName) + ) + ) + ) + dbSave(powerGridViewTemp) + ViewToAssura=powerGridViewTemp + ) + + ; check writeability of target CV + powerGridAbstractView=nrOpenCellViewWritable( CellView~>libName + powerCellName powerAbstractViewName ) + if( powerGridAbstractView == nil then + printf("Error: Can not open cellview %s (%s) for write. \n" + powerCellName powerAbstractViewName) + return(nil) + ) + + ; run Assura abstract_PowerGrid.rul + printf("Creating %s abstract\n" powerCellName ) + AssuraLayerMappings = (list + (list "prb" (list "prBoundary" "drawing")) + (list "m3Vdd" (list "M3" "vdd")) + (list "m3GND" (list "M3" "gnd")) + (list "m5Vdd" (list "M5" "vdd")) + (list "m5GND" (list "M5" "gnd")) + (list "m7Vdd" (list "M7" "vdd")) + (list "m7GND" (list "M7" "gnd")) + (list "m1Keepout" (list "M1" "boundary")) + (list "m2Keepout" (list "M2" "boundary")) + (list "m3Keepout" (list "M3" "boundary")) + (list "m4Keepout" (list "M4" "boundary")) + (list "m5Keepout" (list "M5" "boundary")) + (list "m6Keepout" (list "M6" "boundary")) + (list "m7Keepout" (list "M7" "boundary")) + (list "overlap" (list "OVERLAP" "boundary")) + ) + AssuraRuleFile = sprintf( nil "%s/share/Fulcrum/cell_automation/%s" + ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT") + "abstract_PowerGrid.rul") + AssuraRunLog = sprintf( nil "%s/%s.abstract_pg.log" + ConfigFileGetValue( TheCDSConfigTable "TEMP") + CellView~>cellName ) + ErrorStr = AssuraRunAssuraLayerProcessor( + ViewToAssura CellView~>libName powerCellName powerAbstractViewName + AssuraRuleFile + ConfigFileGetValue( TheCDSConfigTable "TEMP") + AssuraLayerMappings + nil + ?AssuraSets (when M1M2_Ring (list "M1M2_RING")) + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + powerGridAbstractView=nrOpenCellViewWritable( CellView~>libName + powerCellName powerAbstractViewName ) + if( powerGridAbstractView~>shapes==nil then + printf("Error: %s (%s) is empty. \n" powerCellName powerAbstractViewName) + dbSave(powerGridAbstractView) + return(nil) + ) + + ; convert shapes to rectangles + leMergeShapes( powerGridAbstractView~>shapes ) + foreach( shape powerGridAbstractView~>shapes + dbLayerTile(powerGridAbstractView shape~>lpp list(shape)) + dbDeleteObject(shape) + ) + + ; create power pins on specified horizontal metal layers + when( M3PowerPins power_layers = cons( "M3" power_layers ) ) + when( M5PowerPins power_layers = cons( "M5" power_layers ) ) + when( M7PowerPins power_layers = cons( "M7" power_layers ) ) + foreach( shape setof( shape powerGridAbstractView~>shapes + member( shape~>layerName power_layers) && + shape~>purpose=="vdd") + shape~>purpose="net" + dbCreatePin( dbMakeNet( powerGridAbstractView VddNetName ) shape ) + ) + foreach( shape setof( shape powerGridAbstractView~>shapes + member( shape~>layerName power_layers) && + shape~>purpose=="gnd") + shape~>purpose="net" + dbCreatePin( dbMakeNet( powerGridAbstractView GNDNetName ) shape ) + ) + foreach( shape setof( shape powerGridAbstractView~>shapes + or( shape~>purpose=="vdd" shape~>purpose=="gnd")) + shape~>purpose="boundary" + ) + + ; finish up + dbCreateRect( powerGridAbstractView list("prBoundary" "boundary") powerGridAbstractView~>bBox ) + sprintf( gec3Foreign "%s %f %f" powerGridAbstractView~>cellName + caar(powerGridAbstractView~>bBox) + cadar(powerGridAbstractView~>bBox) ) + dbReplacePropList( powerGridAbstractView list( + list("prCellClass" "string" Class) + list("prCellType" "string" "macro") + list("maskLayoutSubType" "string" powerGridAbstractView~>viewName) + list("symmetry" "string" "X Y") + list("gec3Foreign" "string" gec3Foreign) + ) + ) + dbSave(powerGridAbstractView) + printf("Done: %s (%s) created. \n" powerCellName powerAbstractViewName) + if( powerGridViewTemp then + ddDeleteObj( ddGetObj( powerGridViewTemp~>libName powerGridViewTemp~>cellName powerGridViewTemp~>viewName "")) + powerGridView=nrOpenCellViewWritable(CellView~>libName powerCellName powerViewName) + ) + blockCells=setof( inst powerGridView~>instances inst~>cellName==OBSCellName && inst~>viewName==OBSViewName) + foreach( inst blockCells dbDeleteObject( inst )) + blockShapes= setof( shape powerGridView~>shapes shape~>purpose=="boundary" ) + foreach( shape blockShapes dbDeleteObject(shape)) + dbSave( powerGridView ) + + return(powerGridAbstractView) + ) +) + + + +defun( IsPowerGridCell ( inst ) + let( (istrue) + foreach( part parseString( inst->cellName "_" ) + when( part=="TIEOFF" istrue=t ) + ) + istrue + ) +) + + +defun( DeletePowerGridInstance ( srcView ) + let( (pwrgridcell pwrgridobj) + foreach( inst srcView->instances + when( IsPowerGridCell(inst) + pwrgridcell=inst->cellName + dbDeleteObject( inst ) + ) + ) +)) + +defun( DeletePowerGridCell ( srcView ) + let( (pwrgridcell pwrgridobj) + foreach( inst srcView->instances + when( IsPowerGridCell(inst) + pwrgridcell=inst->cellName + dbDeleteObject( inst ) + ) + ) + when( pwrgridcell + pwrgridobj=ddGetObj( srcView->libName pwrgridcell ) + when( pwrgridobj ddDeleteObj(pwrgridobj) ) + ) +)) + +; instantiate the power grid in specified CV +(defun AddPowerGridInstance + (@key (CV (geGetEditCellView)) + ) + (let (RComponenets type_sub PowerGridCellName pgCV) + (unless (dbFindAnyInstByName CV "tiehilo") + RComponents = (reverse (parseString CV->cellName ".")) + (when (length RComponents)<3 (error "Cell name violates CAST conventions\n")) + type_sub = (sprintf nil "%s_%s" (cadr RComponents) (car RComponents)) + PowerGridCellName = (strcat CV->libName ".wires." type_sub "_POWER_GRID_TIEOFF") + pgCV = (nrOpenCellViewReadable CV->libName PowerGridCellName "layout") + (when pgCV (dbCreateInst CV pgCV "tiehilo" 0:0 "R0")) + ) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/powergrid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/powergrid.il new file mode 100644 index 0000000000..760fac6537 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/powergrid/powergrid.il @@ -0,0 +1,542 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + +(defun PowerGridFlattenOverlap ( Overlap ) + (let ( + ( Stack nil ) + ( CurrOverlap Overlap ) + ( Result nil ) ) + (while ( listp CurrOverlap ) + ( setq Stack ( cons ( car CurrOverlap ) Stack ) ) + ( setq CurrOverlap ( cadr CurrOverlap ) ) ) + (when CurrOverlap + ( setq Result ( getq CurrOverlap bBox ) ) + (while Stack + ( setq + Result + ( dbTransformBBox Result ( getq ( car Stack ) transform ) ) ) + ( setq Stack ( cdr Stack ) ) ) ) + Result ) ) + + + + +(defun PowerGridFlattenOverlaps ( Overlaps ) + ( ListApplyFuncToListAndAccumulateResults + Overlaps + (lambda + ( Overlap ) + ( PowerGridFlattenOverlap Overlap ) ) + nil ) ) + +(defun PowerGridGetFlatListOfRectsOnLayer ( CellView LayerPP Levels ) + ( dbComputeBBox CellView ) + ( PowerGridFlattenOverlaps + ( dbGetTrueOverlaps + CellView + ( getq CellView bBox ) + LayerPP + Levels ) ) ) + +(defun PowerGridIsHorizontalWire ( WireRect ) + ( lessp + ( RectGetHeight WireRect ) + ( RectGetWidth WireRect ) ) ) + + +(defun PowerGridGetPitchOffset ( EdgeOfWire WireSpacing WirePitch ) + (let ( + ( HalfWireSpacing ( quotient WireSpacing 2.0 ) ) ) + (let ( + ( EdgeOfPitch ( difference EdgeOfWire HalfWireSpacing ) ) ) + ( difference + ( times + ( round + ( quotient + EdgeOfPitch + WirePitch ) ) + WirePitch ) + EdgeOfPitch ) ) ) ) + + + +(defun PowerGridTranslatePositionToPitch ( Position + WirePitch + PitchOffset ) + ( floor + ( quotient + ( float + ( plus + Position + PitchOffset ) ) + ( float WirePitch ) ) ) ) + +(defun PowerGridTranslatePitchToEdges ( Pitch WirePitch PitchOffset ) + (let ( + ( FirstEdge ( difference ( times Pitch WirePitch ) PitchOffset ) ) + ( SecondEdge ( difference ( times ( plus Pitch 1 ) WirePitch ) PitchOffset ) ) ) + ( list FirstEdge SecondEdge ) ) ) + + +(defun PowerGridGetPitchesUsed ( LayerRects + PitchOffset + WirePitch + WireSpacing + PowerGridWidth + PowerGridHeight + LeftEdgeOfPowerGrid + BottomEdgeOfPowerGrid ) + (let ( + ( HalfWireSpacing ( difference ( quotient WireSpacing 2.0 ) 0.000001 ) ) + ( LeftmostPitch ( PowerGridTranslatePositionToPitch LeftEdgeOfPowerGrid WirePitch PitchOffset ) ) + ( BottommostPitch ( PowerGridTranslatePositionToPitch BottomEdgeOfPowerGrid WirePitch PitchOffset ) ) + ( IsHorizontal ( PowerGridIsHorizontalWire ( car LayerRects ) ) ) ) + (let ( + ( TotalNumPitches ( quotient + (if IsHorizontal + PowerGridHeight + PowerGridWidth ) + WirePitch ) ) + ( PitchTable ( makeTable "foo" nil ) ) ) + ( foreach + LayerRect + LayerRects + (let ( + ( RectStartPitch ( PowerGridTranslatePositionToPitch + ( difference + (if IsHorizontal + ( RectGetBottom + LayerRect ) + ( RectGetLeft + LayerRect ) ) + HalfWireSpacing ) + WirePitch + PitchOffset ) ) + ( RectEndPitch ( PowerGridTranslatePositionToPitch + ( plus + (if IsHorizontal + ( RectGetTop + LayerRect ) + ( RectGetRight + LayerRect ) ) + HalfWireSpacing ) + WirePitch + PitchOffset ) ) ) + ( printf + "%L %L %L\n" + LayerRect + RectStartPitch + RectEndPitch ) + ( for + Pitch + RectStartPitch + RectEndPitch + ( setarray PitchTable Pitch t ) ) ) ) + ( car + ( CounterCountAndAccumulateResult + (if IsHorizontal + BottommostPitch + LeftmostPitch ) + ( plus + ( difference TotalNumPitches 1 ) + (if IsHorizontal + BottommostPitch + LeftmostPitch ) ) + 1 + (lambda + ( Pitch CurrResult PitchTable ) + ( tconc + CurrResult + ( arrayref PitchTable Pitch ) ) ) + ( list PitchTable ) + nil ) ) ) ) ) + +(defun PowerGridGetHorizontalPitchRects ( BottomEdge + WirePitch + Height + PitchOffset ) + (let ( + ( NumPitches ( floor + ( quotient + Height + WirePitch ) ) ) + ( FirstPitch ( PowerGridTranslatePositionToPitch + BottomEdge + WirePitch + PitchOffset ) ) ) + ( CounterCountAndAccumulateResult + FirstPitch + ( plus + FirstPitch + ( difference NumPitches 1 ) ) + 1 + (lambda + ( Pitch CurrResult WirePitch PitchOffset ) + (let ( + ( PitchEdges ( PowerGridTranslatePitchToEdges Pitch WirePitch PitchOffset ) ) ) + (let ( + ( FirstEdge ( car PitchEdges ) ) + ( SecondEdge ( cadr PitchEdges ) ) ) + ( cons + ( list + ( list 0 FirstEdge ) + ( list WirePitch SecondEdge ) ) + CurrResult ) ) ) ) + ( list WirePitch PitchOffset ) + nil ) ) ) + +(defun PowerGridGetVerticalPitchRects ( LeftEdge + WirePitch + Width + PitchOffset ) + (let ( + ( NumPitches ( floor + ( quotient + Width + WirePitch ) ) ) + ( FirstPitch ( PowerGridTranslatePositionToPitch + LeftEdge + WirePitch + PitchOffset ) ) ) + ( CounterCountAndAccumulateResult + FirstPitch + ( plus + FirstPitch + ( difference NumPitches 1 ) ) + 1 + (lambda + ( Pitch CurrResult WirePitch PitchOffset ) + (let ( + ( FirstEdge ( difference ( times Pitch WirePitch ) PitchOffset ) ) + ( SecondEdge ( difference ( times ( plus Pitch 1 ) WirePitch ) PitchOffset ) ) ) + ( cons + ( list + ( list FirstEdge 0 ) + ( list SecondEdge WirePitch ) ) + CurrResult ) ) ) + ( list WirePitch PitchOffset ) + nil ) ) ) + +(defun PowerGridAnalyzePowerGridLayer ( CellView + LayerPP + HierarchyDepth + WirePitch + WireSpacing + PowerGridWidth + PowerGridHeight + LeftEdgeOfPowerGrid + BottomEdgeOfPowerGrid ) + (let ( + ( LayerRects ( sort + ( PowerGridGetFlatListOfRectsOnLayer + CellView + LayerPP + HierarchyDepth ) + `RectCompareRects ) ) ) + (when LayerRects + (let ( + ( IsHorizontal ( PowerGridIsHorizontalWire ( car LayerRects ) ) ) ) + (let ( + ( PitchOffset (if IsHorizontal + ( PowerGridGetPitchOffset + ( RectGetBottom ( cadr LayerRects ) ) + WireSpacing + WirePitch ) + ( PowerGridGetPitchOffset + ( RectGetLeft ( cadr LayerRects ) ) + WireSpacing + WirePitch ) ) ) ) + ( list + LayerPP + IsHorizontal + PitchOffset + ( PowerGridGetPitchesUsed + LayerRects + PitchOffset + WirePitch + WireSpacing + PowerGridWidth + PowerGridHeight + LeftEdgeOfPowerGrid + BottomEdgeOfPowerGrid ) + (if IsHorizontal + ( PowerGridGetHorizontalPitchRects + BottomEdgeOfPowerGrid + WirePitch + PowerGridHeight + PitchOffset ) + ( PowerGridGetVerticalPitchRects + LeftEdgeOfPowerGrid + WirePitch + PowerGridWidth + PitchOffset ) ) ) ) ) ) ) ) + +(defun PowerGridGetPowerGridInfo ( PowerGridLibName + PowerGridCellName + PowerGridViewName + MetalLayerPurposePairs + DirectivesTable + UserUnitsPerMeter + DirectivesUnitsPerMeter + HierarchyDepth ) + (let ( + ( PowerGridCellViewDDObj ( ddGetObj PowerGridLibName PowerGridCellName PowerGridViewName ) ) ) + (when ( and PowerGridCellViewDDObj ( getq PowerGridCellViewDDObj files ) ) + (let ( + ( PowerGridCellView ( dbOpenCellViewByType + PowerGridLibName + PowerGridCellName + PowerGridViewName + nil + "r" ) ) ) + (when PowerGridCellView + ( dbComputeBBox PowerGridCellView ) + (let ( + ( PowerGridBBox ( getq PowerGridCellView bBox ) ) ) + (let ( + ( PowerGridWidth ( RectGetWidth PowerGridBBox ) ) + ( PowerGridHeight ( RectGetHeight PowerGridBBox ) ) ) + ( list + ( list + PowerGridWidth + PowerGridHeight ) + ( ListApplyFuncToListAndAccumulateNonNilResults + MetalLayerPurposePairs + (lambda + ( MetalLayerPurposePair + PowerGridCellView + DirectivesTable + UserUnitsPerMeter + DirectivesUnitsPerMeter + PowerGridWidth + PowerGridHeight + LeftEdgeOfPowerGrid + BottomEdgeOfPowerGrid + HierarchyDepth ) + (let ( + ( WirePitch ( times + UserUnitsPerMeter + ( CellInfoGetLayerWirePitchInMeters + DirectivesTable + MetalLayerPurposePair + DirectivesUnitsPerMeter ) ) ) + ( WireSpacing ( times + UserUnitsPerMeter + ( CellInfoGetLayerWireSpacingInMeters + DirectivesTable + MetalLayerPurposePair + DirectivesUnitsPerMeter ) ) ) ) + (when ( and WirePitch WireSpacing ) + ( PowerGridAnalyzePowerGridLayer + PowerGridCellView + MetalLayerPurposePair + HierarchyDepth + WirePitch + WireSpacing + PowerGridWidth + PowerGridHeight + LeftEdgeOfPowerGrid + BottomEdgeOfPowerGrid ) ) ) ) + ( list + PowerGridCellView + DirectivesTable + UserUnitsPerMeter + DirectivesUnitsPerMeter + PowerGridWidth + PowerGridHeight + ( RectGetLeft PowerGridBBox ) + ( RectGetBottom PowerGridBBox ) + HierarchyDepth ) ) ) ) ) ) ) ) ) ) + + + +(defun PowerGridGetPowerGridPatternForMetalLPP ( PowerGridInfo + MetalLPP ) + (let ( + ( MetalInfo ( car ( exists SomeMetalInfo ( cadr PowerGridInfo ) + ( equal ( nth 0 SomeMetalInfo ) MetalLPP ) ) ) ) ) + ( nth 3 MetalInfo ) ) ) + + + +(defun PowerGridCopyAndAlignInstances ( SrcCellView + TargetCellView + PowerGridLibName + PowerGridCellName + PowerGridAlignmentInUserUnits ) + (let ( + ( FilterRet ( NameFilterInstances + ( getq SrcCellView instances ) + ( list ( list PowerGridLibName PowerGridCellName ) ) ) ) ) + (let ( + ( CurrCount ( stringToTime ( getCurrentTime ) ) ) + ( PowerGridInstances ( cadr + FilterRet ) ) ) + ( foreach + Instance + PowerGridInstances + (let ( + ( CurrInstanceName ( sprintf nil "power_grid_%d" CurrCount ) ) ) + ( setq CurrCount ( plus CurrCount 1 ) ) + ( dbSetq Instance CurrInstanceName name ) + ( InstanceAlignInstance Instance PowerGridAlignmentInUserUnits ) + (let ( + ( ObjToCopy (if ( equal ( getq Instance objType ) "mosaicInst" ) + ( getq Instance mosaic ) + Instance ) ) ) + ( dbSetq ObjToCopy CurrInstanceName name ) + ( dbCopyFig ObjToCopy TargetCellView ) ) ) ) ) ) ) + + +(defun PowerGridDrawPowerGridOnCellView ( CellView + TempDir + PDKPackageRoot + PowerGridLibName + PowerGridCellName + PowerGridViewName + PowerGridAlignmentInUserUnits + PowerGridExclusionLPP ) + (let ( + ( RuleFile ( sprintf nil "%s/share/Fulcrum/powergrid/powergrid.assura.rules" PDKPackageRoot ) ) + ( TempLibName ( LibCreateTempLibraryFromCellView CellView "POWERGRID" TempDir ) ) + ( ErrorStr nil ) ) + ( setq + ErrorStr + ( AssuraRunAssuraLayerProcessor + CellView + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) + RuleFile + TempDir + ( list ( list "powergrid_fill" PowerGridExclusionLPP ) ) + ( list + ( list + ( list + PowerGridLibName + PowerGridCellName + PowerGridViewName ) + "grid" ) ) ) ) + (unless ErrorStr + (let ( + ( OutputCellDDObj ( ddGetObj TempLibName ( getq CellView cellName ) ( getq CellView viewName ) ) ) ) + (if ( and OutputCellDDObj ( getq OutputCellDDObj files ) ) + (let ( + ( CellWithGrid ( dbOpenCellViewByType + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) + nil + "a" ) ) ) + (if CellWithGrid + (let () + ( PowerGridCopyAndAlignInstances + CellWithGrid + CellView + PowerGridLibName + PowerGridCellName + PowerGridAlignmentInUserUnits ) + ( dbSave CellWithGrid ) + ( dbPurge CellWithGrid ) ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to open cell view %L %L %L, even though DDObj exists." + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "%L %L %L does not exist." + TempLibName + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) ) + ( ddDeleteObj ( ddGetObj TempLibName ) ) + ErrorStr ) ) + + +(defun PowerGridCreatePowerGridPatternFromDirectives ( DirectiveTable LPP ) + (cond ( + ( and + ( CellInfoLookupParametrized DirectiveTable "layer_wirepitch" "layer" LPP ) + ( CellInfoLookupParametrized DirectiveTable "layer_wirespacing" "layer" LPP ) + ( CellInfoLookupParametrized DirectiveTable "layer_powergrid_wirewidth" "layer" LPP ) + ( CellInfoLookupParametrized DirectiveTable "layer_powergrid_offset" "layer" LPP ) + ( CellInfoLookupParametrized DirectiveTable "layer_powergrid_spacing" "layer" LPP ) + ) + (let ( + ( LayerWirePitch + ( CellInfoLookupParametrized + DirectiveTable "layer_wirepitch" "layer" LPP ) ) + ( LayerWireSpacing + ( CellInfoLookupParametrized + DirectiveTable "layer_wirespacing" "layer" LPP ) ) + ( LayerPowerGridWireWidth + ( CellInfoLookupParametrized + DirectiveTable "layer_powergrid_wirewidth" "layer" LPP ) ) + ( LayerPowerGridOffset + ( CellInfoLookupParametrized + DirectiveTable "layer_powergrid_offset" "layer" LPP ) ) + ( LayerPowerGridSpacing + ( quotient + ( CellInfoLookupParametrized + DirectiveTable "layer_powergrid_spacing" "layer" LPP ) + 2 ) ) + ) + (let ( + ( PowerGridPitches + ( ceiling + ( quotient + ( plus LayerPowerGridWireWidth LayerWireSpacing ) + LayerWirePitch ) ) ) ) + (let ( + ( PitchVector ( makeVector LayerPowerGridSpacing nil ) ) ) + ( for I LayerPowerGridOffset + ( plus LayerPowerGridOffset + ( difference PowerGridPitches 1 ) ) + ( setarray PitchVector I t ) ) + ( vectorToList PitchVector ) ) ) ) ) + ( + ( list nil ) ) ) ) + + + +; Reports types that are not layout views or any power grid instances +(defun ReportPowerGridsInSubcells (@key (CV (geGetEditCellView))) + (let (done) + done = (makeTable "done" nil) + (rexCompile "POWER_GRID") + (ReportPowerGridsInSubcellsRecurse CV t) + ) + t + ) + +; Reports types that are not layout views or any power grid instances +(defun ReportPowerGridsInSubcellsRecurse (CV top) + (cond ((and !top CV->viewName!="layout") + (printf "Cell %s found with view %s\n" CV->cellName CV->viewName) + ) + ((and !top (setof inst CV->instances (rexExecute inst->cellName))) + (printf "Cell %s layout view has POWER_GRID instance\n" CV->cellName) + ) + (t + (foreach inst CV->instances + (when (and inst->libName!=TechLibName + inst->libName!="stack" + inst->libName!="gate" + !done[inst->master]) + (ReportPowerGridsInSubcellsRecurse inst->master nil) + ) + ) + ) + ) + done[CV]=t + t + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/proteus/proteus.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/proteus/proteus.il new file mode 100644 index 0000000000..dcda4d8a36 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/proteus/proteus.il @@ -0,0 +1,586 @@ +; Skill scripts to construct Proteus library LEF. Source information +; is floorplan views from supersize. Layout views are generated and +; pins are added. Abstract views are created from the layout views. +; LEF is written from the abstract views. +; +; Author: Andrew Lines +; Copyright 2007 Fulcrum Microsystems + +; default globals +(defun ProteusDefaults () + ProteusScaleX = 1 + ProteusScaleY = 1 + ProteusDeleteSubcells = nil + DefaultWiringPitchX = DefaultWiringPitch + ProteusPinY = 8 + ProteusPinX = (list 0.5 1.5 4.5 5.5 6.5 7.5 10.5 11.5 + 12.5 13.5 16.5 17.5 18.5 19.5 22.5 23.5 + 24.5 25.5 28.5 29.5 30.5 31.5 34.5 35.5 + 36.5 37.5 40.5 41.5 42.5 43.5 46.5 47.5) + ProteusPinVddW = 0.16 + ProteusPinGNDW = 0.16 + ProteusPinGNDX = (list 3 21 27 45) + ProteusPinVddX = (list 9 15 33 39) + ProteusPinCutout = 0.06 + ProteusLayoutViewName = "layout" + ProteusAbstractViewName = "abstract" + ProteusAbstractProteusViewName = "abstract_proteus" + ProteusStrengths = (list 0 1 2 3 4 5 6 7 8) + ProteusType = "qdi" + ) + +(ProteusDefaults) + +; do all steps +(defun ProteusAll () + (ProteusAutoPlace) + (ProteusSortCells "floorplan") + (ProteusLayoutViews) + (ProteusPins) + (ProteusSortCells ProteusLayoutViewName) + (ProteusAbstract) + (ProteusLef) + t + ) + +; just do Abstract and Lef steps again (use for final real layout) +(defun ProteusAbstractLefs () + (ProteusAbstract) + (ProteusLef) + t + ) + +; sort and arrange cells by instance name +(defun SortCells (@key (CV nil)) + (let (X x0 x1 names inst) + (cond (CV==nil CV = (geGetEditCellView))) + names = nil + (foreach inst CV->instances names = (cons inst->name names)) + X = 0 + (foreach name (sort names nil) + inst = (dbFindAnyInstByName CV name) + x0 = (car (car inst->master->bBox)) + x1 = (car (cadr inst->master->bBox)) + inst->xy = (list X-x0 0) + X = X+x1-x0 + ) + ) + t + ) + +; sort subcells of top-level cells +(defun ProteusSortCells (view @key (ProteusType ProteusType) (Strengths ProteusStrengths)) + (let (CV) + (foreach strength Strengths + CV = (dbOpenCellViewByType + (sprintf nil "synthesis.%s.sizing" ProteusType) + (sprintf nil "synthesis.%s.sizing.SIZE-L%d-R.%d" + ProteusType strength strength) + view nil "a") + (SortCells ?CV CV) + ) + ) + t + ) + +; generate abstracts +(defun ProteusAbstract (@key (ProteusType ProteusType)) + (let (filename cells) + filename = (sprintf nil "%s.gates" ProteusType) + cells = (OpenCellViewsFromFile filename ProteusLayoutViewName "r") + (foreach CV cells + (MakeLeafAbstract ?CV CV + ?cutout ProteusPinCutout + ?floodfillM1Keepout t + ?floodfillM2Keepout nil + ?floodfillM3Keepout nil + ?extendM3Keepout nil + ?extendM2Keepout nil) + ) + ) + t + ) + +; export lef +(defun ProteusLef (@key (ProteusType ProteusType)) + (let (filename cells statusLef) + filename = (sprintf nil "%s.gates" ProteusType) + cells = (OpenCellViewsFromFile filename ProteusAbstractViewName "r") + (sh "mkdir -p lef") + (foreach CV cells + CV = (ProteusTransformAbstract ?CV CV) + statusLef = (ldtrLefWriteOA + (sprintf nil "lef/%s.lef" CV->cellName) + CV->libName + CV->cellName + nil + CV->viewName + (sprintf nil "lef/%s.lef.log" CV->cellName) + t + "5.7") + (unless statusLef (error "can't write lef for %s" CV->cellName)) + ) + ) + t + ) + +; transform proteus abstract (swap X and Y coordinates) +(defun ProteusTransformAbstract (@key (CV (geGetEditCellView))) + CV = (dbCopyCellView CV CV->libName CV->cellName + ProteusAbstractProteusViewName nil nil t) + (foreach label (setof s CV->shapes s->objType=="label") label->parent=nil) + (foreach shape (cons CV->prBoundary (append CV->shapes CV->blockages)) + (dbMoveFig shape CV (list 0:0 "MXR90" 1)) + ) + CV->cellType = "core" ; CLASS CORE + CV->site = "CoreSite" ; PROPERTY site "CoreSite" + (dbSetCellViewSymmetry CV "XY") ; SYMMETRY X Y + (dbSave CV) + CV + ) + +; draw a single proteus pin +(defun ProteusDrawPin ( name layer width xy0 xy1 ) + (DrawSegment name layer width xy0 xy1 nil nil t) + ) + +; advance to next legal xy pin location given current xy and upper right bbox +; xy is x_index:y_pitch not coordinates +(defun ProteusNextXY (xy xy1 @key (inc 2)) + (let (x y x1 y1 rx) + x = (car xy) + y = (cadr xy) + x1 = (car xy1) + y1 = (cadr xy1) + x=x+inc + rx = (nth x ProteusPinX) + (when rx==nil || rx*DefaultWiringPitchX>=x1 y=y+ProteusPinY x=0) + x:y + ) + ) + +; draw a single pin on metal2 at current location, advance location +(defun ProteusPin ( name xy xy1 @key (inc 2)) + (let (x y y0 y1) + ; draw pin + x = (car xy) + y = (cadr xy) + x = (nth x ProteusPinX)*DefaultWiringPitchX + y = y*DefaultWiringPitch + y0 = y + DefaultWiringPitch/2 + y1 = y + ProteusPinY*DefaultWiringPitch - DefaultWiringPitch/2 + (ProteusDrawPin name Metal2LPP DefaultWiringWidth x:y0 x:y1) + (ProteusNextXY xy xy1 ?inc inc) + ) + ) + +; draw a pair of pins on metal2 at current location, advance location +(defun ProteusPinList ( names xy xy1 @key (inc 2)) + (foreach name names + xy = (ProteusPin name xy xy1 ?inc inc) + ) + xy + ) + +; draw power pins +(defun ProteusDrawPowerPins ( bbox ) + (let (x0 y0 x1 y1) + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + (foreach i ProteusPinGNDX + x = i*DefaultWiringPitchX + (when x>x0 && xx0 && xshapes + (cond (obj->objType=="label" (dbDeleteObject obj))) + ) + t + ) + +; redraw power grid pins (used to patch final layout) +(defun ProteusRedrawPowerPins (@key (ProteusType ProteusType) (view ProteusLayoutViewName)) + (let (filename cells bbox) + filename = (sprintf nil "%s.gates" ProteusType) + cells = (OpenCellViewsFromFile filename view "a") + (foreach CV (setof cell cells cell->mode=="a") + ; open cell + (printf "%s\n" CV->cellName) + (geOpen ?lib CV->libName ?cell CV->cellName + ?view view ?viewType "maskLayout" ?mode "a") + + ; get prBoundary + (unless CV->prBoundary (error "no prBoundary")) + bbox = CV->prBoundary->bBox + + ; delete old power pins + (foreach obj CV->shapes + (cond ((and obj->pin + (or obj->pin->net->name == VddNetName + obj->pin->net->name == GNDNetName)) + (dbDeleteObject obj)) + ) + ) + + ; draw power pins + (ProteusDrawPowerPins bbox) + + ; regenerate labels + (DeleteLabels ?CV CV) + (LabelPins ?CV CV) + + ; close cell + (dbSave CV CV->libName CV->cellName CV->viewName) + (leCloseWindow) + ) + ) + t + ) + +; autoplace any subcells +(defun ProteusAutoPlace (@key (ProteusType ProteusType)) + (let (filename cells type) + filename = (sprintf nil "%s.gates" ProteusType ) + cells = (OpenCellViewsFromFile filename "floorplan" "a") + (foreach CV cells + ; open cell + type = CV->cellName + + ; autoplace any subcells at origin + (foreach obj CV->instances + (cond (obj->name == "reg" obj->xy=0:0 obj->orient="MX") + (obj->name == "reg[0]" obj->xy=0:0 obj->orient="MX") + (obj->name == "reg[1]" obj->xy=2*PowerGridPitch:0 obj->orient="MX") + (t obj->xy=0:0 obj->orient="R0") + ) + ) + + ; close cell + (dbSave CV CV->libName CV->cellName CV->viewName) + ) + ) + ) + +; place pins for Proteus logic cells +(defun ProteusPins (@key (ProteusType ProteusType)) + (let (filename cells type + bbox xy xy0 xy1 x0 y0 x1 y1 + inputs rails bits qdi + logic edff send recv from to buf tie inv op cfg tok scan reset) + filename = (sprintf nil "%s.gates" ProteusType ) + cells = (OpenCellViewsFromFile filename ProteusLayoutViewName "a") + (foreach CV (setof cell cells cell->mode=="a") + ; open cell + type = CV->cellName + (printf "%s\n" type ) + (geOpen ?lib CV->libName ?cell CV->cellName + ?view ProteusLayoutViewName ?viewType "maskLayout" ?mode "a") + + ; save bounding box + bbox = CV->bBox + xy0 = (car bbox) + xy1 = (cadr bbox) + x0 = (car xy0) + y0 = (cadr xy0) + x1 = (car xy1) + y1 = (cadr xy1) + x0 = x0 * ProteusScaleX + x1 = x1 * ProteusScaleX + y0 = y0 * ProteusScaleY + y1 = y1 * ProteusScaleY + y0 = DefaultWiringPitch * floor(y0/DefaultWiringPitch) + y1 = DefaultWiringPitch * ceiling(y1/DefaultWiringPitch) + bbox = (list x0:y0 x1:y1) + xy0 = (car bbox) + xy1 = (cadr bbox) + x0 = (car xy0) + y0 = (cadr xy0) + x1 = (car xy1) + y1 = (cadr xy1) + + ; delete old pins and shapes + (when CV->prBoundary (dbDeleteObject CV->prBoundary)) + (foreach obj CV->shapes (dbDeleteObject obj)) + (foreach obj CV->nets (dbDeleteObject obj)) + (foreach obj CV->terminals (dbDeleteObject obj)) + + ; optionally delete subcells + (when ProteusDeleteSubcells + (foreach obj CV->instances (dbDeleteObject obj)) + ) + + ; classify library type + qdi = ProteusType=="qdi" + + ; classify cell type + (rexCompile "logic") logic = (rexExecute type) + (rexCompile "EDFF") edff = (rexExecute type) + (rexCompile "SEND_") send = (rexExecute type) + (rexCompile "RECV_") recv = (rexExecute type) + (rexCompile "FROM_") from = (rexExecute type) + (rexCompile "TO_") to = (rexExecute type) + (rexCompile "BUF") buf = (rexExecute type) + (rexCompile "TIE") tie = (rexExecute type) + (rexCompile "INV") inv = (rexExecute type) + (rexCompile "CTREE") op = (rexExecute type) + (rexCompile "NOR") op = (or op (rexExecute type)) + (rexCompile "AND") op = (or op (rexExecute type)) + (rexCompile "CONFIG") cfg = (rexExecute type) + (rexCompile "TOK_") tok = (rexExecute type) + (rexCompile "SCAN_") scan = (rexExecute type) + (rexCompile "RESET_") reset = (rexExecute type) + + ; classify number of inputs + inputs = 0 + (for i 1 6 + (rexCompile (sprintf nil "logic%d" i)) + (cond ((rexExecute type) inputs=i)) + (rexCompile (sprintf nil "CTREE%d" i)) + (cond ((rexExecute type) inputs=i)) + (rexCompile (sprintf nil "NOR%d" i)) + (cond ((rexExecute type) inputs=i)) + (rexCompile (sprintf nil "AND%d" i)) + (cond ((rexExecute type) inputs=i)) + ) + + ; classify 1ofN + rails = 2 + bits = 1 + (rexCompile "_1of4") + (cond ((rexExecute type) rails=4 bits=2)) + + ; adjust width and height to H/W <= 3/2 aspect ratio + (unless scan + (cond (y1/x1>=24 y1=y1/4 x1=4*x1) + (y1/x1>=6 y1=y1/2 x1=2*x1) + ) + ) + + ; adjust height to match wire pitch + y0 = DefaultWiringPitch * floor(y0/DefaultWiringPitch) + y1 = DefaultWiringPitch * ceiling(y1/DefaultWiringPitch) + (when y1bBox)) + (car (cadr bbox))!=(car (cadr CV->bBox)) + (cadr (car bbox))!=(cadr (car CV->bBox)) + (cadr (cadr bbox))!=(cadr (cadr CV->bBox))) + (printf "WARNING: bBox is larger than prBoundary\n") + ) + ) + + ; close cell + (dbSave CV CV->libName CV->cellName CV->viewName) + (leCloseWindow) + ) + ) + t + ) + +; generate ProteusType.gates file +(defun GenerateGatesFile (@key (ProteusType ProteusType) (Strengths ProteusStrengths)) + (let (outFileName pout) + outFileName = (sprintf nil "%s.gates" ProteusType) + pout = (outfile outFileName) + (foreach strength Strengths + CV = (dbOpenCellViewByType + (sprintf nil "synthesis.%s.sizing" ProteusType) + (sprintf nil "synthesis.%s.sizing.SIZE-L%d-R.%d" + ProteusType strength strength) + "floorplan" nil "a") + (foreach inst CV->instances + (fprintf pout (sprintf nil "%s\n" inst->master->cellName)) + ) + ) + (close pout) + ) + t + ) + +; copy floorplan to layout views +(defun ProteusLayoutViews (@key (ProteusType ProteusType) (Strengths ProteusStrengths)) + (let (master) + (foreach strength Strengths + CV = (dbOpenCellViewByType + (sprintf nil "synthesis.%s.sizing" ProteusType) + (sprintf nil "synthesis.%s.sizing.SIZE-L%d-R.%d" + ProteusType strength strength) + "floorplan" "maskLayout" "r") + (dbSave CV CV->libName CV->cellName ProteusLayoutViewName) + CV = (dbOpenCellViewByType + (sprintf nil "synthesis.%s.sizing" ProteusType) + (sprintf nil "synthesis.%s.sizing.SIZE-L%d-R.%d" + ProteusType strength strength) + ProteusLayoutViewName "maskLayout" "a") + (foreach inst CV->instances + (cond (inst->viewName=="floorplan" + master = inst->master + (when master + (dbSave master master->libName master->cellName ProteusLayoutViewName) + master = (dbOpenCellViewByType inst->master->lib + inst->master->cellName + ProteusLayoutViewName + "maskLayout" "r") + ) + (cond (master inst->master=master) + (t (dbDeleteObject inst)) + ) + ) + ) + ) + (dbSave CV CV->libName CV->cellName CV->viewName) + ) + ) + t + ) + +; write type.finished.gates for layout views with vias +(defun ProteusListFinishedCells (@key (ProteusType ProteusType)) + (let (filename cells out n) + n=0 + filename = (sprintf nil "%s.gates" ProteusType) + cells = (OpenCellViewsFromFile filename ProteusLayoutViewName "r") + out = (outfile (sprintf nil "%s.finished.gates" ProteusType)) + (foreach CV cells + (when CV->vias + n++ + (fprintf out "%s\n" CV->cellName)) + ) + (close out) + n + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/abstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/abstract.il new file mode 100644 index 0000000000..83864c0c4b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/abstract.il @@ -0,0 +1,108 @@ +; Create abstracts using settings in wires.il +; +; Copyright 2011 Fulcrum Microsystems. All rights reserved. + +; make mid-level abstract using information from wires.il +(defun MakeAbstract + (@key (CV (geGetEditCellView))) + (let (win abstractPinCutout abstractPinLength abstractBloatM1 + abstractBloatM2 abstractBloatM3 abstractBloatM4 + abstractBloatM5 abstractBloatM6 abstractBloatM7 + abstractCutHolesAbovePins) + (unless CV->viewName=="layout_pg" + (printf "WARNING: recommend MakeAbstract from layout_pg\n") + ) + + ; load settings from wires.il + (LoadWires) + + ; create abstract + CV = (nrCreateAbstractCB CV + ?ERASE_POWERGRID t + ?PIN_CUTOUT abstractPinCutout + ?PIN_LENGTH abstractPinLength + ?M1BLOAT abstractBloatM1 + ?M2BLOAT abstractBloatM2 + ?M3BLOAT abstractBloatM3 + ?M4BLOAT abstractBloatM4 + ?M5BLOAT abstractBloatM5 + ?M6BLOAT abstractBloatM6 + ?M7BLOAT abstractBloatM7 + ?M8BLOAT 0 + ?useAbstractSubcells t + ?keepLayoutSubcells abstractKeepLayoutSubcells + ?NO_HOLES_ABOVE_PINS !abstractCutHolesAbovePins + ?targetViewName "abstract" + ?PowerNets nil + ?M4PowerNets nil + ?M5PowerNets nil + ?M6PowerNets nil + ?M7PowerNets nil) + + ; change to abstract view + win = (hiGetCurrentWindow) + (when win + (geOpen ?window win + ?lib CV->libName + ?cell CV->cellName + ?view CV->viewName + ?viewType "maskLayout" + ?mode "a") + ) + + ; return abstract view + CV + ) + ) + +; default options for mid-cell abstract generation, called by LoadWires +(defun AbstractDefaults () + abstractPinCutout = 2*DefaultWiringSpacing + abstractPinLength = 2*DefaultWiringWidth + abstractBloatM1 = -1 + abstractBloatM2 = -1 + abstractBloatM3 = -1 + abstractBloatM4 = -1 + abstractBloatM5 = -1 + abstractBloatM6 = PowerGridPitch + abstractBloatM7 = PowerGridPitch + abstractCutHolesAbovePins = nil + abstractKeepLayoutSubcells = nil + t + ) + +; make abstract for a leaf cell +(defun MakeLeafAbstract + (@key (CV (geGetEditCellView)) + (pinCutout 0.36) + (pinLength 2.88) + (bloatM2 -1) + (bloatM3 0) + ) + (unless CV->viewName=="layout" (error "MakeLeafAbstract on a layout view\n")) + (unless (setof sub CV->instances + sub->libName!=TechLibName && sub->libName!="stack" && sub->libName!="gate") + (printf "Creating abstract of %s\n" CV->cellName) + (nrCreateAbstractCB CV + ?ERASE_POWERGRID nil + ?PIN_CUTOUT pinCutout + ?PIN_LENGTH pinLength + ?M1BLOAT -1 + ?M2BLOAT bloatM2 + ?M3BLOAT bloatM3 + ?M4BLOAT 0 + ?M5BLOAT 0 + ?M6BLOAT 0 + ?M7BLOAT 0 + ?M8BLOAT 0 + ?useAbstractSubcells nil + ?keepLayoutSubcells t + ?NO_HOLES_ABOVE_PINS nil + ?targetViewName "abstract" + ?PowerNets t + ?M4PowerNets nil + ?M5PowerNets nil + ?M6PowerNets nil + ?M7PowerNets nil) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/canonicalize.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/canonicalize.il new file mode 100644 index 0000000000..29fccba2ad --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/canonicalize.il @@ -0,0 +1,241 @@ +; Copyright 2010 Fulcrum Microsy\stems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/canonicalize.il#1 +; $DateTime$ +; $Author$ + +; note, file names are not conducive to concurrent runs of the same cell +; in the same directory.. a hopefully very unlikely situation. + +; Canonical Query, run cast_query generates table of cadence names to cadence canonical names +; from a list of vaid cast names NOT cadence names! +(defun CanonicalQuery + (namefilename skillfile cellName @key + (maxheap nil) ; max memory, nil to use MaxHeapSize form + (verbose nil) ; verbose reporting + ) + let( (machine mnfile cmd rv ) + rv=t + ; get an automatic max-heap-size + if(isFile(namefilename) then + if(maxheap==nil maxheap=nrGetMaxHeapSize()) + ; find the cast path if not specified + castpath=ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + if(castpath then + if(verbose printf("Finding canonical names...\n")) + cmd=sprintf( nil "cast_query --cadence-name --no-header --translate=cadence --cast-path='%s' --task=canonical_name='%s:skill' --output='%s' --cell='%s' --routed --max-heap-size=%dM" + castpath namefilename skillfile cellName maxheap ) + if(verbose printf("%s\n" cmd)) + if(shell(cmd) then + if( isFile(skillfile) then + if(verbose printf("Done\n")) + else + rv=nil + if(verbose printf("%s\nFailed\n" cmd)) + ) + else + rv=nil + if(verbose printf("%s\nFailed\n" cmd)) + ) + else + rv=nil + printf("Error: CAST_PATH not defined, cannot proceed\n") + ) + else + rv=nil + ) + rv + ) +) + +; Convert net names to canonical CAST (actually cadence) names (see BUG 17471) +(defun CanonicalizeNetNames + (names @key + (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (maxheap nil) ; max memory, nil to use MaxHeapSize form + (query t) ; force rerunning cast_query + (verbose nil) ; verbose reporting + (dofix t) ; rename nets, or nil for report only + ) + let( (namefile cmd skillfile NodeCanonicalMap ) + NodeCanonicalMap=nil + if(names && length(names) then + skillfile=sprintf( nil "%s/%s.ncanon.il" ConfigFileGetValue( TheCDSConfigTable "TEMP") CV~>cellName) + ; create name file for cast_query + namefile=outfile(sprintf(nil "%s.names" CV~>cellName )) + foreach(name names fprintf(namefile "%s\n" name)) + close( namefile ) + ; uniqify the list, just in case + shell(sprintf(nil "sort -u %s.names -o %s.names" CV~>cellName CV~>cellName)) + ; convert names to cast names for cast_query, output of cast_query is still cadence names + shell(sprintf(nil "cat %s.names | rename --type=node --from=cadence --to=cast > %s.names1" CV~>cellName CV~>cellName)) + if(CanonicalQuery( sprintf(nil "%s.names1" CV~>cellName) skillfile CV~>cellName ?verbose verbose) then + load( skillfile ) + NodeCanonicalMap=NodeCanonicalTable() + ) + ) + NodeCanonicalMap + ) +) + +; Convert net names on shapes and vias to canonical CAST (actually cadence) names (see BUG 17471) +(defun CanonicalizeNets +(@key + (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (maxheap nil) ; max memory, nil to use MaxHeapSize form + (query t) ; force rerunning cast_query + (verbose nil) ; verbose reporting + (dofix t) ; rename nets, or nil for report only + ) + let( (namefile namefilename cmd rv skillfile) + rv=t + skillfile=sprintf( nil "%s/%s.ncanon.il" ConfigFileGetValue( TheCDSConfigTable "TEMP") CV~>cellName) + if(query || ! isFile(skillfile) then + ; create a list of names... lots of duplicates + namefilename=sprintf(nil "%s.names" CV~>cellName ) + namefile=outfile(namefilename) + foreach( path setof(shape CV~>shapes shape~>net && shape~>net~>name) + fprintf(namefile "%s\n" path~>net~>name)) + foreach( inst CV~>instances + foreach( term setof(te inst~>instTerms te~>net && te~>net~>name ) + fprintf(namefile "%s\n" term~>net~>name))) + close( namefile ) + ; uniqify the list + shell(sprintf(nil "sort -u %s -o %s" namefilename namefilename)) + ; convert names to cast names for cast_query + shell(sprintf(nil "cat %s | rename --type=node --from=cadence --to=cast > %s1" namefilename namefilename)) + ; get an automatic max-heap-size + rv=CanonicalQuery( sprintf(nil "%s1" namefilename) skillfile CV~>cellName ?verbose verbose ?maxheap maxheap) + ) + if(rv && isFile(skillfile) then + rv=DoFixCanonical(CV + ?tfile skillfile + ?verbose verbose + ?dofix dofix ) + else + rv=nil + ) + DeleteUnusedNets( ?CV CV) + rv + ) +) + +; actually fix up the net names identified above +(defun DoFixCanonical + (CV @key + (tfile "cqc.out.il") + (dofix t) + (verbose nil) + ) + let((nnil tnnil ccnt pcnt ncnt tccnt tpcnt tncnt NodeCanonicalMap errfile errname rv termname) + load( tfile ) + rv=t + NodeCanonicalMap=NodeCanonicalTable() + ccnt=0 + pcnt=0 + ncnt=0 + errname=sprintf(nil "%s.canon.err" CV~>cellName ) + errfile=outfile(errname) + nnil=length(setof(shape CV~>shapes shape~>objType=="path" && shape~>net==nil && + shape->purpose!="bus" && shape->purpose!="boundary")) + if(nnil then + if(verbose printf( "Error: paths exist without connectivity\n")) + if(errfile fprintf( errfile "Error: paths exist without connectivity\n")) + rv=nil) + foreach( path setof(shape CV~>shapes shape~>net && shape~>net~>name) + let( (newname net ) + pcnt=pcnt+1 + newname=arrayref( NodeCanonicalMap path~>net~>name ) + (cond (newname == nil + ncnt=ncnt+1 + rv=nil + if(verbose printf( "Error: Unrecognized net name %s\n" path~>net~>name )) + if(errfile fprintf(errfile "Error: Unrecognized net name %s\n" path~>net~>name )) + ) + ( newname != path~>net~>name + if(verbose printf("Rename path %s to %s\n" path~>net~>name newname )) + if(errfile fprintf(errfile "Rename path %s to %s\n" path~>net~>name newname )) + if( dofix then + net = dbFindNetByName( CV newname ) + (cond (net == nil + if(verbose printf("Canonical net %s did not exist, Sync To Netlist?\n" newname )) + if(errfile fprintf(errfile "Canonical net %s did not exist, Sync To Netlist?\n" newname )) + rv=nil + net = dbCreateNet( CV newname ))) + dbSubFigFromNet( path ) + if( !dbAddFigToNet( path net) + printf("Error: cound not attach new net %s to shape\n" newname)) + ) + ccnt = ccnt+1)) + ) + ) + tccnt=0 + tpcnt=0 + tncnt=0 + tnnil=0 + foreach( inst CV~>instances + tnnil=tnnil+length(setof(te inst~>instTerms te~>net==nil) ) + foreach( term setof(te inst~>instTerms te~>net && te~>net~>name ) + tpcnt=tpcnt+1 + let( ( newname net ) + newname=arrayref( NodeCanonicalMap term~>net~>name ) + (cond (newname == nil + tncnt=tncnt+1 + rv=nil + if(verbose printf( "Error: Unrecognized %s instance->pin %s->%s\n" term~>net~>name inst~>name term~>name)) + if(errfile fprintf(errfile "Error: Unrecognized %s instance->pin %s->%s\n" term~>net~>name inst~>name term~>name)) + ) + ( newname != term~>net~>name + if(verbose printf("Rename inst %s term %s %s to %s\n" inst~>name term~>name term~>net~>name newname ) ) + if(errfile fprintf(errfile "Rename inst %s term %s %s to %s\n" inst~>name term~>name term~>net~>name newname ) ) + if( dofix then + net = dbFindNetByName( CV newname ) + (cond (net == nil + if(verbose printf("Canonical net %s did not exist, Sync To Netlist?\n" newname )) + if(errfile fprintf(errfile "Canonical net %s did not exist, Sync To Netlist?\n" newname )) + rv=nil + net = dbCreateNet( CV newname ) + )) + termname=term~>name + dbDeleteObject( term ) + if( !dbCreateConnByName( net inst termname ) + printf("Error: cound not attach new net %s to terminal %s\n" newname termname)) + ) + tccnt = tccnt+1)) + ) + ) + ) + if(tnnil > 0 then + if(verbose printf( "Error: inst terms exist without connectivity\n")) + if(errfile fprintf( errfile "Error: inst terms exist without connectivity\n")) + rv=nil + ) + if( verbose then + printf("%d nets total\n" pcnt ) + printf("%d nets renamed\n" ccnt ) + printf("%d nets ok\n" pcnt-ccnt-ncnt ) + printf("%d nets not recognized\n" ncnt )) + if(errfile then + fprintf(errfile "%d nets total\n" pcnt ) + fprintf(errfile "%d nets renamed\n" ccnt ) + fprintf(errfile "%d nets ok\n" pcnt-ccnt-ncnt ) + fprintf(errfile "%d nets not recognized\n" ncnt )) + if(verbose then + printf("%d inst terms total\n" tpcnt ) + printf("%d inst terms renamed\n" tccnt ) + printf("%d inst terms ok\n" tpcnt-tccnt-tncnt ) + printf("%d inst terms not recognized\n" tncnt )) + if(errfile then + fprintf(errfile "%d inst terms total\n" tpcnt ) + fprintf(errfile "%d inst terms renamed\n" tccnt ) + fprintf(errfile "%d inst terms ok\n" tpcnt-tccnt-tncnt ) + fprintf(errfile "%d inst terms not recognized\n" tncnt )) + if(errfile then + if( rv then + printf( "Info see %s\n" errname) + else + printf( "%d errors, see %s\n" ncnt+tncnt errname))) + close(errfile) + if(dofix DeleteUnusedNets()) + rv + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/flatten.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/flatten.il new file mode 100644 index 0000000000..7a2ab9328b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/flatten.il @@ -0,0 +1,750 @@ +; Replacement for ui/Nano/Flatten/FlattenView.il + +; Top-level function to make a flatten view and switch to it +(defun MakeFlatten + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (RegenerateFromCast nil) ; force CAST query + (Proteus nil) ; Proteus compatible POWER_GRID_TIEOFF + (Verbose nil) ; verbose + (ConnectDanglingPins t) ; paint metal on top of one-terminal subcell pins + (ConnectAbuttingPins t) ; paint metal between nearby pins on the same net + (doFillPoly t) ; fill poly + (doMakePowerGrid t) ; make power grid + (doPowerGridAbstract t) ; generate abstract view of power grid + ) + (let (MaxHeapSize FlattenCellsList Components RComponents CellBaseName + type_sub PowerGridCellName OBSCellName flattenCV xalign yalign + pgCV win temp) + + ; check viewName + (when (and CV->viewName!="floorplan" CV->viewName!="prelayout") + (error "Wrong view: Call MakePrelayout or MakeFlatten on floorplan/prelayout view\n")) + + ; create prelayout view if necessray + (when CV->viewName=="floorplan" CV = (MakePrelayout ?CV CV)) + + ; save prelayout view + (dbSave CV) + + ; options + (LoadWires) + MaxHeapSize = (nrGetMaxHeapSize) + + ; generated cell or file names + FlattenCellsList = (strcat CV->cellName ".flatten_cells_list") + Components = (parseString CV->cellName ".") + RComponents = (reverse Components) + CellBaseName = (cadr RComponents) + (when (length RComponents)<3 (error "Cell name violates CAST conventions\n")) + type_sub = (sprintf nil "%s_%s" (cadr RComponents) (car RComponents)) + OBSCellName = (strcat CV->libName ".wires." type_sub "_OBS") + PowerGridCellName = (strcat CV->libName ".wires." type_sub "_POWER_GRID_TIEOFF") + + ; Create flatten view + flattenCV = (nrFlattenView CV "flatten" PowerGridCellName "layout" + FlattenCellsList ?Verbose Verbose + ?DeleteWires nil + ?RegenerateFromCast RegenerateFromCast + ?MaxHeapSize MaxHeapSize) + (unless flattenCV (error "Unable to create flatten view\n")) + + ; set properties + xalign = (GetXAlignmentProp CV) + yalign = (GetYAlignmentProp CV) + (SetXAlignmentProp flattenCV (max (if xalign xalign 0) TrackPitch)) + (SetYAlignmentProp flattenCV (max (if yalign yalign 0) GridPitch)) + (dbSave flattenCV) + + ; Create Poly Fill + (when doFillPoly && !Proteus + polyfillCV = (FillPoly ?CV flattenCV) + (unless polyfillCV (error "Unable to create poly fill\n")) + ) + + ; Create power grid + (when doMakePowerGrid + pgCV = (MakePowerGrid ?CV flattenCV ?Proteus Proteus) + (unless pgCV (error "Unable to create power grid\n")) + ) + + ; Create power grid abstract + (when doPowerGridAbstract + pgCV = (MakePowerGridAbstract ?CV flattenCV) + (unless pgCV (error "Unable to create power grid abstract\n")) + ) + + ; switch current window + CV = flattenCV + win = (hiGetCurrentWindow) + (when win (geOpen ?window win + ?lib CV->libName + ?cell CV->cellName + ?view CV->viewName + ?viewType "maskLayout" + ?mode "a") + ) + + ; create FlattenCellsList file + celllist_filename = FlattenCellsList + instances= setof( inst CV~>instances inst->libName!=TechLibName && inst->viewName!="polyfill") + instances= append( car( NameFilterInstances( instances LibCellsToIgnore )) + cadr( NameFilterInstances( instances PowerGridCellPairRegExs ))) + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances=cons( inst uniqueInstances ) + ) + ) + pout=outfile(celllist_filename) + if( pout then + foreach( inst uniqueInstances + fprintf( pout "%s %s %s\n" inst~>libName inst~>cellName "abstract") + ) + close(pout) + ) + + ; draw pins + (RedrawAllPins) + + ; canonicalize prerouted nets + (CanonicalizeNets ?CV CV) + + ; warn or delete redundant non-canonical pins + (DeleteRedundantPins ?CV CV ?warnOnly !delete_redundant_pins) + + ; place metal on top of dangling subcell pins for StarRC extraction + (when ConnectDanglingPins + (nrCreateSingleNetConnector CV MetalLPPs ?MaxHeapSize MaxHeapSize) + ) + + ; route abutting pins too + (when ConnectAbuttingPins + (nrCreateNeighborNetConnector CV 2*KeepoutPrBoundSpacing MetalLPPs ?maxFanout 2) + ) + + ; fill in fields for DEF export + (foreach inst CV->instances + (unless inst->typeName==TechLibName + inst->status = "locked" ; FIXED + (when inst->cellName==PowerGridCellName inst->source = "dist") ; SOURCE DIST + ) + ) + + ; fix pin directions TODO: use existing *.il file in temp + dirmap = (defGenerateP2DTable CV->cellName nil) + (when dirmap + (foreach term CV->terminals + ; lock pin location + (foreach pin term->pins + (when pin->fig (dbSetPinFigPlacementStatus pin->fig "locked"))) + ; set term direction + (cond (dirmap[term->name]=="INPUT" term->direction = "input") + (dirmap[term->name]=="OUTPUT" term->direction = "output") + (dirmap[term->name]=="INOUT" term->direction = "inputOutput")) + ) + ) + + ; set fields for LEF export + (SetLefProperties CV) + + ; for DEF export + (CopyKeepoutToBlockage CV) + + ; return flatten view + (dbSave CV) + CV + ) + ) + +; MakePowerGrid +(defun MakePowerGrid + (@key (CV (geGetEditCellView)) ; flatten CV + (Proteus nil) ; include M2 stripes + ) + (let (Components RComponents type_sub powerCellName + inst prb PowerGridSize PGS prbObjPoints prb1 + x1box x2box y1box y2box x1 y1 x2 x2 xy + AssuraLayerMappings AssuraRuleFile AssuraRunLog ErrorStr + powerCV ReplaceCellNameTable blks + count gridName gridCV rows cols transform points + tiehilo GND Vdd instGND instVdd) + + ; generated cell or file names + Components = (parseString CV->cellName ".") + RComponents = (reverse Components) + (when (length RComponents)<3 (error "Cell name violates CAST conventions\n")) + type_sub = (sprintf nil "%s_%s" (cadr RComponents) (car RComponents)) + powerCellName = (strcat CV->libName ".wires." type_sub "_POWER_GRID_TIEOFF") + + ; delete old power grid instance if it exists + inst = (dbFindAnyInstByName CV "tiehilo") + (when inst (dbDeleteObject inst)) + + ; get prBoundary boundary shapes + prbObjPoints = CV->prBoundary->points + prb1 = (dbCreatePolygon CV list("prBoundary" "drawing") prbObjPoints) + copyprb1 = (setof x CV->shapes (car x->lpp) == "prBoundary" && (cadr x->lpp) == "drawing") + + ; checks for prBoundary drawing, if only one exists, if vertices are on 3.12u grid + (cond ((length copyprb1)==1 (letseq + ((copyprb (car copyprb1))) + vertprb = (setof vertprb copyprb->points (CheckOffGrid vertprb)) + vertprbrec = (setof vertprbrec copyprb->bBox (CheckOffGrid vertprbrec)) + (when vertprb (error "Not All prBoundary Vertices Are On 3.12u Grid: %L" vertprb)) + (when vertprbrec (error "Not All prBoundary Vertices Are On 3.12u Grid: %L" vertprbrec)) + prb = (dbCopyShape copyprb CV ) + prb->lpp=(list "prBoundary" "boundary"))) + (t (error "ERROR: Check prBoundary layer. Either no prBoundary or more than one exists."))) + + ; get bounding box as an integer multiple of MfgGrid + x1box = 1.0*(round (leftEdge prb->bBox)/MfgGrid) + x2box = 1.0*(round (rightEdge prb->bBox)/MfgGrid) + y1box = 1.0*(round (bottomEdge prb->bBox)/MfgGrid) + y2box = 1.0*(round (topEdge prb->bBox)/MfgGrid) + + ; minimum sized power grid + PowerGridSize = 2*PowerGridPitch + PGS = (round PowerGridSize/MfgGrid) + x1 = (floor x1box/PGS) + y1 = (floor y1box/PGS) + x2 = (ceiling x2box/PGS) + y2 = (ceiling y2box/PGS) + + ; avoid M2 overlapping prBoundary of subcells (looks only one level down) + (when Proteus blks = (PaintOverSubcellPrBoundary (list "M2" "block") ?CV CV)) + + ; avoid M2 power grid everywhere + (unless Proteus blks = (list (dbCreatePolygon CV (list "M2" "block") (GetPrboundPoints CV)))) + + ; find bottom vertices of prbound to place Vdd/GND pins + (if prb->objType == "polygon" + (letseq () + botprbverts = (setof botprbverts prb->points + (CheckBotVert botprbverts ((ceiling y1box/PGS)*PowerGridSize))) + xy = (car botprbverts)) + xy = (list (ceiling x1box/PGS)*PowerGridSize + (ceiling y1box/PGS)*PowerGridSize) + ) + + ; run layer processing + AssuraLayerMappings = (list + (list "power2" (list "M2" "block")) + (list "power3" (list "M3" "block")) + (list "power4" (list "M4" "block")) + (list "power5" (list "M5" "block")) + (list "power6" (list "M6" "block")) + (list "power7" (list "M7" "block")) + (list "prblk" (list "prBoundary" "block")) + ) + AssuraRuleFile = (sprintf nil "%s/share/Fulcrum/cell_automation/%s" + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + "makePowerGrid.rul") + AssuraRunLog = (sprintf nil "%s/%s.power_grid.log" + (ConfigFileGetValue TheCDSConfigTable "TEMP") + CV->cellName) + ErrorStr = (AssuraRunAssuraLayerProcessor + CV CV->libName powerCellName "layout" + AssuraRuleFile + (ConfigFileGetValue TheCDSConfigTable "TEMP") + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + powerCV = (nrOpenCellViewWritable CV->libName powerCellName "layout") + + ; define power grid cell names + ReplaceCellNameTable=makeTable("a" "") + ReplaceCellNameTable["M2"]="globals.wires.POWER_GRID_M2345678" + ReplaceCellNameTable["M3"]="globals.wires.POWER_GRID_M345678" + ReplaceCellNameTable["M4"]="globals.wires.POWER_GRID_M45678" + ReplaceCellNameTable["M5"]="globals.wires.POWER_GRID_M5678" + ReplaceCellNameTable["M6"]="globals.wires.POWER_GRID_M678" + ReplaceCellNameTable["M7"]="globals.wires.POWER_GRID_M78" + + ; replace block shapes with power mosaics + count=0 + (foreach lpp powerCV->lpps + gridName = ReplaceCellNameTable[lpp->layerName] + (when gridName!="" && lpp->purpose=="block" + gridCV = (nrOpenCellViewReadable "globals" gridName "layout") + (foreach shape lpp->shapes + x1 = (leftEdge shape->bBox) + y1 = (bottomEdge shape->bBox) + x2 = (rightEdge shape->bBox) + y2 = (topEdge shape->bBox) + cols = (round (x2-x1)/PowerGridSize) + rows = (round (y2-y1)/PowerGridSize) + (dbCreateSimpleMosaic powerCV gridCV + (sprintf nil "I%d" count) x1:y1 "R0" + rows cols PowerGridSize PowerGridSize) + count = count+1 + (dbDeleteObject shape) + ) + ) + ) + + ; copy prBoundary object to powergrid view + (dbCreatePRBoundary powerCV CV->prBoundary->points) + + ; delete temporary prBoundary shape + (dbDeleteObject prb) + (dbDeleteObject prb1) + + ; delete temporary leaf M2 block shapes from flatten CV + (foreach x blks (dbDeleteObject x)) + + ; create power pins + (CreatePowerPins powerCV "M8" xy t) + (CreatePowerPins CV "M8" xy t) + + ; instantiate power grid and connect power pins + tiehilo = (dbCreateInst CV powerCV "tiehilo" 0:0 "R0") + (AnchorInstance tiehilo) + GND = (dbFindNetByName CV GNDNetName) + Vdd = (dbFindNetByName CV VddNetName) + instGND = (dbFindTermByName powerCV GNDNetName) + instVdd = (dbFindTermByName powerCV VddNetName) + (dbCreateInstTerm GND tiehilo instGND) + (dbCreateInstTerm Vdd tiehilo instVdd) + + ; save and return + (dbSave CV) + (dbSave powerCV) + (dbClose powerCV) + powerCV + ) + ) + +; Fill grided poly between custom leaf cells +(defun FillPoly + (@key (CV (geGetEditCellView)) ; select CV + ) + (let (Components RComponents type_sub polyCellName + inst prb PowerGridSize PGS prbObjPoints prb1 + x1box x2box y1box y2box x1 y1 x2 x2 xy + AssuraLayerMappings AssuraRuleFile AssuraRunLog ErrorStr + polyCV blks + count gridName gridCV rows cols leafcell leafbbox + polyfill XdirGridSize PolyGridSize PolyColSize) + + ; generated cell or file names + Components = (parseString CV->cellName ".") + RComponents = (reverse Components) + (when (length RComponents)<3 (error "Cell name violates CAST conventions\n")) + type_sub = (sprintf nil "%s_%s" (cadr RComponents) (car RComponents)) + polyCellName = (CV->cellName) + + ; delete old poly grid instance if it exists + inst = (dbFindAnyInstByName CV "polyfill") + (when inst (dbDeleteObject inst)) + + ; get prBoundary boundary shapes + prbObjPoints = CV->prBoundary->points + prb1 = (dbCreatePolygon CV list("prBoundary" "drawing") prbObjPoints) + copyprb1 = (setof x CV->shapes (car x->lpp)=="prBoundary"&&(cadr x->lpp)=="drawing") + + ; checks for prBoundary drawing, if only one exists, if vertices are on 3.12u grid + (cond ((length copyprb1)==1 (letseq + ((copyprb (car copyprb1))) + vertprb = (setof vertprb copyprb->points (CheckOffGrid vertprb)) + vertprbrec = (setof vertprbrec copyprb->bBox (CheckOffGrid vertprbrec)) + (when vertprb (error "Not All prBoundary Vertices Are On 3.12u Grid: %L" vertprb)) + (when vertprbrec (error "Not All prBoundary Vertices Are On 3.12u Grid: %L" vertprbrec)) + prb = (dbCopyShape copyprb CV ) + prb->lpp=(list "prBoundary" "boundary"))) + (t (error "ERROR: Check prBoundary layer. Either no prBoundary or more than one exists."))) + + ;create prBoundary leaf boxes for fill block + blks = (PaintOverSubcellPrBoundary (list "prBoundary" "leaf") ?CV CV) + + ; minimum sized power grid y-axis + PowerGridSize = 2*PowerGridPitch + + ; minimum sized poly x-axis grid + PolyGridSize = 2*0.13 + + ; number of polyfill columns per powergrid + OneCol = 1 + TwoCol = 2 + ThreeCol = 3 + PolyColSize = PowerGridSize/PolyGridSize + + ; run layer processing + AssuraLayerMappings = (list + (list "fillpoly" (list "M7" "block")) + ) + AssuraRuleFile = (sprintf nil "%s/share/Fulcrum/cell_automation/%s" + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + "fillPoly.rul") + AssuraRunLog = (sprintf nil "%s/%s.fillpoly.log" + (ConfigFileGetValue TheCDSConfigTable "TEMP") + CV->cellName) + ErrorStr = (AssuraRunAssuraLayerProcessor + CV CV->libName polyCellName "polyfill" + AssuraRuleFile + (ConfigFileGetValue TheCDSConfigTable "TEMP") + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + polyCV = (nrOpenCellViewWritable CV->libName polyCellName "polyfill") + + ; replace block shapes with poly mosaics + count=0 + (foreach lpp polyCV->lpps + (when lpp->layerName=="M7" && lpp->purpose=="block" + (foreach shape lpp->shapes + x1 = (leftEdge shape->bBox) + y1 = (bottomEdge shape->bBox) + x2 = (rightEdge shape->bBox) + y2 = (topEdge shape->bBox) + cols = (round (x2-x1)/PolyGridSize) + rows = (round (y2-y1)/PowerGridSize) + XdirGridSize = PolyGridSize + (cond (cols >= PolyColSize (let () + gridCV = (nrOpenCellViewReadable + "globals" "globals.wires.POLY_FILL_DCAP" "layout") + cols = (round cols/PolyColSize) + XdirGridSize = PowerGridSize)) + + (cols >= ThreeCol (let () + gridCV = (nrOpenCellViewReadable + "globals" "globals.wires.POLY_FILL_S78" "layout") + cols = (round cols/ThreeCol) + XdirGridSize = 3*PolyGridSize)) + + (cols >= TwoCol (let () + gridCV = (nrOpenCellViewReadable + "globals" "globals.wires.POLY_FILL_S52" "layout") + cols = (round cols/TwoCol) + XdirGridSize = 2*PolyGridSize)) + + (cols >= OneCol (let () + gridCV = (nrOpenCellViewReadable + "globals" "globals.wires.POLY_FILL_S26" "layout") + cols = (round cols/OneCol) + XdirGridSize = PolyGridSize)) + (t (error)) + ) + (dbCreateSimpleMosaic polyCV gridCV + (sprintf nil "I%d" count) x1:y1 "R0" + rows cols PowerGridSize XdirGridSize) + + count = count+1 + (dbDeleteObject shape) + ) + ) + ) + + ; copy prBoundary object to poly fill view + (dbCreatePRBoundary polyCV CV->prBoundary->points) + + ; delete temporary prBoundary shape + (dbDeleteObject prb) + (dbDeleteObject prb1) + + ; delete temporary leaf prBoundary shapes + (foreach x blks (dbDeleteObject x)) + + ; instantiate poly grid + polyfill = (dbCreateInst CV polyCV "polyfill" 0:0 "R0") + (AnchorInstance polyfill) + + ; save and return + (dbSave CV) + (dbSave polyCV) + (dbClose polyCV) + polyCV + ) + ) + +(defun WriteNanoTcl + (@key (CV (geGetEditCellView)) ; select CV + (topLayer 7) + (bottomLayer 3) + ) + (let (polyfillinst tclImportFile tclRunFile top bottom instances uniqueInstances pout pout2 Command + ) + + tclImportFile = (strcat CV->cellName ".import.tcl") + tclRunFile = (strcat CV->cellName ".run.tcl") + nondefaultDefFile = (strcat CV->cellName "_nondefault.def") + nondefaultDefLogFile = (strcat CV->cellName "_nondefault.def.log") + top=topLayer + bottom=bottomLayer + + NonDefaultLefFile = (sprintf nil "%s/share/Fulcrum/cell_automation/router/%s" + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + "nondefault.lef") + + ; delete poly grid instance if it exists + polyfillinst = (dbFindAnyInstByName CV "polyfill") + (when polyfillinst (dbDeleteObject polyfillinst)) + + instances= setof( inst CV~>instances inst->libName!=TechLibName && inst->viewName!="polyfill") + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>libName uniqueInstances~>libName ) then + uniqueInstances=cons( inst uniqueInstances ) + ) + ) + + Command = sprintf( nil + "%s/cast2def --cast-path=%s --cell=%s --outfile=%s --cadence-name --max-heap-size=4G &> %s" + PackageGetBinRoot( ) + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + CV->cellName + nondefaultDefFile + nondefaultDefLogFile + ) + printf( "%s\n" Command ) + shell( Command ) + printf( "Nondefault Rule File %s is created.\n" nondefaultDefFile) + + pout=outfile(tclImportFile) + if( pout then + fprintf(pout "%s%s%s\n" "set rda_Input(ui_oa_designLib) {" CV~>libName "}") + fprintf(pout "%s%s%s\n" "set rda_Input(ui_oa_designCell) {" CV~>cellName "}") + fprintf(pout "%s%s%s\n" "set rda_Input(ui_oa_designView) {" CV~>viewName "}") + fprintf(pout "%s\n" "set rda_Input(ui_oa_abstractname) {abstract}") + fprintf(pout "%s\n" "set rda_Input(ui_oa_layoutname) {layout}") + fprintf(pout "%s\n" "set rda_Input(ui_pwrnet) {Vdd}") + fprintf(pout "%s\n" "set rda_Input(ui_gndnet) {GND}") + fprintf(pout "%s" "set rda_Input(ui_oa_reflib) {tsmc28") + foreach( inst uniqueInstances + fprintf( pout " %s" inst~>libName) + ) + fprintf(pout "%s\n" "}") + close(pout) + ) + printf( "Encounter import file %s is created.\n" tclImportFile) + + pout2=outfile(tclRunFile) + if( pout2 then + fprintf(pout2 "%s\n" "setOaxMode -updateMode true") + fprintf(pout2 "%s %s\n" "loadConfig" tclImportFile) + fprintf(pout2 "%s %s\n" "loadLefFile" NonDefaultLefFile) + fprintf(pout2 "%s %s\n" "defIn" nondefaultDefFile) + fprintf(pout2 "%s%s%s\n" "set TOP \"" CV~>cellName "\"") + fprintf(pout2 "%s%s%s\n" "set LIB \"" CV~>libName "\"") + fprintf(pout2 "%s\n" "set VIEW \"nano\"") + fprintf(pout2 "%s %d\n" "set TOP_LAYER" top) + fprintf(pout2 "%s %d\n" "set BOTTOM_LAYER" bottom) + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeAllowPowerGroundPin true") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeWithLithoDriven false") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeWithSIDriven false") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeWithTimingDriven false") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeStrictlyHonorNonDefaultRule true") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeAutoGgrid false") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -drouteFixAntenna false") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -drouteUseMultiCutViaEffort medium") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -drouteAutoStop true") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeTopRoutingLayer $TOP_LAYER") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeBottomRoutingLayer $BOTTOM_LAYER") + fprintf(pout2 "%s\n" "setAttribute -net GND -skip_routing true") + fprintf(pout2 "%s\n" "setAttribute -net Vdd -skip_routing true") + fprintf(pout2 "%s\n" "setNanoRouteMode -quiet -routeSelectedNetOnly false") + fprintf(pout2 "%s\n" "generateTracks +-m1HOffset 0.065 -m1HPitch 0.13 -m1VOffset 0.065 -m1VPitch 0.13 +-m2HOffset 0.065 -m2HPitch 0.13 -m2VOffset 0.065 -m2VPitch 0.13 +-m3HOffset 0.065 -m3HPitch 0.13 -m3VOffset 0.065 -m3VPitch 0.13 +-m4HOffset 0.065 -m4HPitch 0.13 -m4VOffset 0.065 -m4VPitch 0.13 +-m5HOffset 0.065 -m5HPitch 0.13 -m5VOffset 0.065 -m5VPitch 0.13 +-m6HOffset 0.065 -m6HPitch 0.13 -m6VOffset 0.065 -m6VPitch 0.13 +-m7HOffset 0.065 -m7HPitch 0.13 -m7VOffset 0.065 -m7VPitch 0.13 +-m8HOffset 0.065 -m8HPitch 0.13 -m8VOffset 0.065 -m8VPitch 0.13") + fprintf(pout2 "%s\n" "routeDesign -globalDetail -noPlacementCheck") + fprintf(pout2 "%s\n" "saveOaDesign $LIB $TOP $VIEW") + fprintf(pout2 "%s\n" "exit") + close(pout2) + ) + printf( "Encounter run file %s is created.\n" tclRunFile) + ) +) + +; generate abstract of a power grid cell +; flattens and merges vdd and gnd purpose shapes +; converts those on specified layers to pins with strong connectivity +; others layers become boundary purpose +(defun MakePowerGridAbstract + (@key (CV (geGetEditCellView)) ; flatten CellView + (powerLayers (list "M2" "M3" "M8"))) ; which layers to keep as pins + (let (inst pgCV dd pgaCV AssuraLayerMappings AssuraRuleFile AssuraRunLog figsVdd figsGND) + + ; fing powergrid CV + inst = (dbFindAnyInstByName CV "tiehilo") + (unless inst (error "No tiehilo instance")) + pgCV = inst->master + + ; run Assura makePowerGridAbstract.rul + AssuraLayerMappings = (list + (list "m2v" (list "M2" "vdd")) + (list "m2g" (list "M2" "gnd")) + (list "m3v" (list "M3" "vdd")) + (list "m3g" (list "M3" "gnd")) + (list "m4v" (list "M4" "vdd")) + (list "m4g" (list "M4" "gnd")) + (list "m5v" (list "M5" "vdd")) + (list "m5g" (list "M5" "gnd")) + (list "m6v" (list "M6" "vdd")) + (list "m6g" (list "M6" "gnd")) + (list "m7v" (list "M7" "vdd")) + (list "m7g" (list "M7" "gnd")) + (list "m8v" (list "M8" "vdd")) + (list "m8g" (list "M8" "gnd")) + ) + AssuraRuleFile = (sprintf nil "%s/share/Fulcrum/cell_automation/%s" + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + "makePowerGridAbstract.rul") + AssuraRunLog = (sprintf nil "%s/%s.abstract_pg.log" + (ConfigFileGetValue TheCDSConfigTable "TEMP") + pgCV->cellName) + (AssuraRunAssuraLayerProcessor + pgCV + pgCV->libName pgCV->cellName "abstract" + AssuraRuleFile + (ConfigFileGetValue TheCDSConfigTable "TEMP") + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + + ; open power grid abstract + pgaCV = (dbOpenCellViewByType pgCV->libName pgCV->cellName "abstract" "maskLayout" "a") + (unless pgaCV (error "Unable to read %s abstract\n" pgCV->cellName)) + + ; merge shapes (too damn slow) + ; (leMergeShapes pgaCV->shapes) + + ; create prBoundary object + (dbCreatePRBoundary pgaCV (GetPrboundPoints pgCV)) + (dbCreatePolygon pgaCV BoundaryLPP (GetPrboundPoints pgCV)) + + ; create power pins on specified metal layers + ; only create 1 pin each for Vdd and GND and add figures to it + ; this represents strongly connected pins needed for correct LEF + (foreach shape (setof shape pgaCV->shapes (member shape->layerName powerLayers)) + (cond (shape->purpose=="vdd" + shape->purpose="drawing" ; net? + figsVdd = (cons shape figsVdd) + ) + (shape->purpose=="gnd" + shape->purpose="drawing" ; net? + figsGND = (cons shape figsGND) + ) + ) + ) + (dbAddFigsToPin (dbCreatePin (dbMakeNet pgaCV VddNetName) nil) figsVdd) + (dbAddFigsToPin (dbCreatePin (dbMakeNet pgaCV GNDNetName) nil) figsGND) + + ; convert remaining shapes to boundary + (foreach shape (setof shape pgaCV->shapes !(member shape->layerName powerLayers)) + shape->purpose="boundary" + ) + (CopyKeepoutToBlockage pgaCV) + + ; set fields for LEF export + (SetLefProperties pgaCV ?powergrid t) + + ; save and return + (dbSave pgaCV) + (dbClose pgaCV) + pgaCV + ) + ) + +; Mod operation converting float number to integer in terms of MfgGrid +(defun GetNonZeroMod ( div dis ) + (mod (round div/MfgGrid) (round dis/MfgGrid)) != 0 +) + +; Check vertices are on powergrid pitch +(defun CheckOffGrid ( pt @key (XGrid 2*PowerGridPitch) (YGrid 2*PowerGridPitch) ) + (let ((x (car pt)) + (y (cadr pt))) + (GetNonZeroMod x XGrid) || (GetNonZeroMod y YGrid) + ) +) + +; Check vertices are on lowest Y-coord +(defun CheckBotVert ( pt bottom ) + (let ((x (car pt)) + (y (cadr pt))) + y == bottom + ) +) + +; Paint an lpp over all subcell prBoundary +(defun PaintOverSubcellPrBoundary (lpp @key (CV (geGetEditCellView))) + (let (transform points shapes) + (foreach inst CV->instances + transform = inst->transform + points = (GetPrboundPoints inst->master) + (when points + points = (TransformPoints points transform) + shape = (dbCreatePolygon CV lpp points) + shapes = (cons shape shapes) + ) + ) + shapes + ) + ) + + +; apply a transform to a list of points +(defun TransformPoints (points transform) + (when points + (cons (geTransformUserPoint (car points) transform) + (TransformPoints (cdr points) transform)) + ) + ) + +; Draw Vdd/GND pins +(defun CreatePowerPins (CV layer xy label) + (let (x y fig net) + x = (car xy) + y = (cadr xy) + + ; GND pin + net = (MakeNet CV GNDNetName) + fig = (dbCreateRect CV (list layer "gnd") + (list x-0.09:y+3.12-0.09 x+0.09:y+3.12+0.09)) + (dbReplaceProp fig "PinType" "string" "Power") + (dbCreatePin net fig) + (when label (LabelPin CV fig)) + + ; Vdd pin + net = (MakeNet CV VddNetName) + fig = (dbCreateRect CV (list layer "vdd") + (list x-0.09:y+1.56-0.09 x+0.09:y+1.56+0.09)) + (dbReplaceProp fig "PinType" "string" "Power") + (dbCreatePin net fig) + (when label (LabelPin CV fig)) + ) + t + ) + + + + +defun( CreateMissingAbstractList ( CellView CellsListFileName ) + let((inst cellList fout) + cellList=nil + fout=outfile(CellsListFileName) + if( fout then + foreach(inst CellView~>instances + if(!nrOpenCellViewReadable(inst->libName inst->cellName "abstract") && + !member(inst->cellName cellList) then + cellList=cons(inst~>cellName cellList) + fprintf(fout "%s\n" inst~>cellName) + ) + ) + close(fout) + else printf("Error: file %s not writable\n" CellsListFileName) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/ground.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/ground.il new file mode 100644 index 0000000000..bc00cf7401 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/ground.il @@ -0,0 +1,159 @@ +; Connect prerouted GND shields to power supply stripes by adding only +; vias. +; +; Copyright 2011 Fulcrum Microsystems. All rights reserved. + +; Connect as many GND shields as possible using only vias. +(defun ConnectGroundShields + (@key (CV (geGetEditCellView))) + (ConnectVerticalGroundShieldsToStripes ?CV CV) + + (ConnectHorizontalGroundShields ?CV CV) + ) + +; check for existing contact +(defun CheckForContactOverlap (xy lpps @key (CV (geGetEditCellView))) + (let (overlaps ret) + ret = nil + (foreach lpp lpps + overlaps = (dbGetOverlaps CV (list xy xy) (list lpp->layerName lpp->purpose) 1) + (when (setof ovl overlaps !(atom ovl) && (car ovl)->libName==TechLibName) + ret = t + ) + ) + ret + ) + ) + +; create a GND contact +(defun CreateGroundShieldContact (xy type @key (CV (geGetEditCellView))) + (let (n contCV inst) + n = 0 + contCV = (dbOpenCellViewByType TechLibName type "layout") + (unless (CheckForContactOverlap xy contCV->lpps ?CV CV) + inst = (dbCreateParamInst CV contCV (NextContactName CV) xy "R0" 0 nil) + (dbReplaceProp inst "GroundShieldContact" "boolean" t) + (dbCreateConnByName GND inst "pdd") + (SetBusProp inst) + n = 1 + ) + n + ) + ) + +; Delete contacts added by ConnectGroundShields +(defun DeleteGroundShieldContacts + (@key (CV (geGetEditCellView))) + (foreach obj CV->instances + (when (and obj->libName==TechLibName + (dbGetPropByName obj "GroundShieldContact") + (dbGetPropByName obj "GroundShieldContact")->value) + (dbDeleteObject obj) + ) + ) + t + ) + +; Connect vertical GND shields to horizontal stripes on layer above. +(defun ConnectVerticalGroundShieldsToStripes + (@key (CV (geGetEditCellView))) + (let ((n 0) GND shields xy0 xy1 x0 y0 x1 y1 x y yg type) + + ; find vertical GND shields + GND = (dbFindNetByName CV "GND") + (unless GND (error "No GND net\n")) + shields = (setof shape CV->shapes + (and shape->net==GND + (or (and shape->objType=="path" (length shape->points)==2) + shape->objType=="rect") + (or shape->layerName=="M2" + shape->layerName=="M4" + shape->layerName=="M6"))) + + ; process each shield shape + (foreach shield shields + xy0 = (car shield->bBox) + xy1 = (cadr shield->bBox) + x0 = (car xy0) + y0 = (cadr xy0) + x1 = (car xy1) + y1 = (cadr xy1) + x = (x0 + x1)/2 + y = (y0 + y1)/2 + yg = (round y/5.76)*5.76 + (when (and yg>=(min y0 y1)+DefaultWiringPitch yg<=(max y0 y1)-DefaultWiringPitch) + (cond (shield->layerName=="M2" type = "M3_M2_2CUT_V") + (shield->layerName=="M4" type = "M5_M4_2CUT_V") + (shield->layerName=="M6" type = "M7_M6_2CUT_V") + (t (error)) + ) + n=n+(CreateGroundShieldContact x:yg type ?CV CV) + ) + ) + n + ) + ) + +; Connect horizontal GND shields to all crossing vertical GND wires. +(defun ConnectHorizontalGroundShields + (@key (CV (geGetEditCellView)) (overhang DefaultWiringPitch)) + (let ((n 0) GND shields xy0 xy1 x0 y0 x1 y1 x y oxy0 oxy1 ox0 oy0 ox1 oy1 + layers overlaps type) + + ; find vertical GND shields + GND = (dbFindNetByName CV "GND") + (unless GND (error "No GND net\n")) + shields = (setof shape CV->shapes + (and shape->net==GND + (or (and shape->objType=="path" (length shape->points)==2) + shape->objType=="rect") + (or shape->layerName=="M3" + shape->layerName=="M5" + shape->layerName=="M7"))) + + ; process each shield shape + (foreach shield shields + xy0 = (car shield->bBox) + xy1 = (cadr shield->bBox) + x0 = (car xy0) + y0 = (cadr xy0) + x1 = (car xy1) + y1 = (cadr xy1) + y = (y0+y1)/2 + (cond (shield->layerName=="M3" layers = (list "M4" "M2")) + (shield->layerName=="M5" layers = (list "M6" "M4")) + (shield->layerName=="M7" layers = (list "M6")) + (t (error)) + ) + (foreach layer layers + (cond ((and shield->layerName=="M3" layer=="M2") type = "M3_M2min") + ((and shield->layerName=="M3" layer=="M4") type = "M4_M3min") + ((and shield->layerName=="M5" layer=="M4") type = "M5_M4min") + ((and shield->layerName=="M5" layer=="M6") type = "M6_M5min") + ((and shield->layerName=="M7" layer=="M6") type = "M7_M6min") + (t (error)) + ) + overlaps = (dbGetOverlaps CV shield->bBox (list layer "drawing") 0) + (foreach overlap overlaps + oxy0 = (car overlap->bBox) + oxy1 = (cadr overlap->bBox) + ox0 = (car oxy0) + oy0 = (cadr oxy0) + ox1 = (car oxy1) + oy1 = (cadr oxy1) + x = (ox0+ox1)/2 + (when (and overlap->net==GND + (or (and overlap->objType=="path" + (length overlap->points)==2) + overlap->objType=="rect") + x>=x0+overhang + x<=x1-overhang + y>=oy0+overhang + y<=oy1-overhang) + n=n+(CreateGroundShieldContact x:y type ?CV CV) + ) + ) + ) + ) + n + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/layout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/layout.il new file mode 100644 index 0000000000..cd5998c2ff --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/layout.il @@ -0,0 +1,18 @@ +; Create a layout view from layout_pg view + +(defun MakeLayout + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + ) + (let (layoutCV tiehilo) + (when CV->viewName=="layout_pg" + layoutCV = (dbCopyCellView CV CV->libName CV->cellName "layout" nil nil t) + (when !layoutCV (error "Unable to write layout view\n")) + tiehilo = (dbFindAnyInstByName layoutCV "tiehilo") + (when tiehilo (dbDeleteObject tiehilo)) + tiehilo = (dbFindMosaicByName layoutCV "tiehilo") + (when tiehilo (dbDeleteObject tiehilo)) + (dbSave layoutCV) + ) + layoutCV + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/nanoroute.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/nanoroute.il new file mode 100644 index 0000000000..c7acbfdb0f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/nanoroute.il @@ -0,0 +1,585 @@ +; Automated routing using VCAR. Wastes less time than the old UI. +; +; Copyright 2010 Fulcrum Microsystems. All rights reserved. + +; Export, Route, Import using Nanoroute +(defun NanoRoute + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (bottomMetal nil) ; bottom metal layer to use, or nil to use wires.il + (topMetal nil) ; top metal layer to use, or nil to use wires.il + (SaveQuit nil) ; automatically save and quit NanoRoute + (Background t) ; select foreground or background + (importView "layout_pg") ; view name to import wiring back to + (Ticket "np") ; QSUB ticket: np, nano + (Mem 4000) ; QSUB mem to request + (Soc (getShellEnvVar "SOC_SCRIPT")) ; which version of Encounter to use + (timingDriven nil) ; use proteus script to route with timing constraints + (Verify t) ; run VerifyGeom and VerifyConn at the end + (SkipCompleteNets t) ; auto-skip complete nets + (strictNondefault t) ; strict nondefault width/spacing rules + (AutoStop t) ; stop routing if too many errors + (routeGND nil) ; route GND net + (routeVdd nil) ; route Vdd net + (doVerilog t) ; create .v + (doLef t) ; create .lef + (doDef t) ; create .def + (doNondefaultDef t) ; create _nondefault.def + (doTracksDef nil) ; create _tracks.def + (doSkipRouting t) ; create SetSkipRouting.tcl + ) + (let () + ; load wires.il and set options + (LoadWires) + (unless bottomMetal bottomMetal = bundled_bottom_layer) + (unless topMetal topMetal = bundled_top_layer) + + ; export files for NanoRoute + CV = (NanoRouteExport ?CV CV ?timingDriven timingDriven + ?doVerilog doVerilog + ?doLef doLef ?doDef doDef ?doNondefaultDef doNondefaultDef + ?doTracksDef doTracksDef ?doSkipRouting doSkipRouting) + + ; write TCL and config files + (ProteusConfig ?CV CV ?bottomMetal bottomMetal ?topMetal topMetal) + (NanoRouteTcl ?CV CV ?bottomMetal bottomMetal ?topMetal topMetal + ?SkipCompleteNets SkipCompleteNets + ?SaveQuit (or SaveQuit Background) + ?Verify Verify ?AutoStop AutoStop + ?strictNondefault strictNondefault + ?routeGND routeGND ?routeVdd routeVdd) + + ; run NanoRoute + (cond (timingDriven (ProteusRun ?CV CV ?Background Background ?Mem Mem)) + (t (NanoRouteRun ?CV CV ?Background Background ?Ticket Ticket ?Mem Mem ?Soc Soc)) + ) + + ; import from NanoRoute + (cond (Background + (printf "NanoRoute running in background, finish with NanoRouteImport\n") + ) + (t + (NanoRouteImport ?CV CV ?viewName importView) + ) + ) + CV + ) + ) + +; Export files for Proteus +(defun NanoRouteExport + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (Proteus nil) ; target Proteus flow + (Synchronous nil) ; target synchronous flow + (timingDriven nil) ; target timing driven flow + (Verbose nil) ; verbose feedback + (doVerilog t) ; create .v + (doLef t) ; create .lef + (doDef t) ; create .def + (doNondefaultDef t) ; create _nondefault.def + (doTracksDef nil) ; create _tracks.def + (doSkipRouting t) ; create SkipRouting.tcl + ) + (let (FulcrumPDKRoot BinRoot TEMP MaxHeapSize CAST_PATH DFII_DIR + Components RComponents CellBaseName type_sub + PowerGridCellName abstractCV + VerilogFileName Command (statusVerilog t) + LefCellsList pout (statusLef t) + pinmap dirmap (statusDef t) + SkipRoutingFileName inplacedPins + (statusNonDefault t) (statusTracks t) errorStr Custom) + + ; global settings + FulcrumPDKRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + BinRoot = (PackageGetBinRoot) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + MaxHeapSize = ( nrGetMaxHeapSize ) + CAST_PATH = (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + DFII_DIR = (ConfigFileGetValue TheCDSConfigTable "DFII_DIR") + Custom = !(or Proteus timingDriven Synchronous) + + ; make flatten view automatically + (when (or CV->viewName=="floorplan" CV->viewName=="prelayout") + CV = (MakeFlatten ?CV CV ?Proteus Proteus)) + + ; cell and file names + Components = (parseString CV->cellName ".") + RComponents = (reverse Components) + CellBaseName = (cadr RComponents) + (when (length RComponents)<3 (error "Cell name violates CAST conventions\n")) + type_sub = (sprintf nil "%s_%s" (cadr RComponents) (car RComponents)) + PowerGridCellName = (strcat CV->libName ".wires." type_sub "_POWER_GRID_TIEOFF") + + ; export Verilog + (when (and Custom doVerilog) + VerilogFileName = (strcat CV->cellName ".v") + Command = (sprintf nil + (strcat "%s/prs2verilog" + " --cast-path=%s" + " --cell=%s" + " --outfile=%s" + " --max-heap-size=%dM" + " --converter=netlist" + " --skip-power-rail" + " --routed" + " --translate=cadence" + " --cadence-name" + "&> exportVerilogNetlist.log") + BinRoot + CAST_PATH + CV->cellName + VerilogFileName + MaxHeapSize) + (printf "%s\n" Command) + statusVerilog = (shell Command) + ) + + ; export LEF + (when doLef + ; write lef cells list + LefCellsList = (sprintf nil "%s.lef_cells_list" CV->cellName) + pout = (outfile LefCellsList) + (foreach sub (ListLefSubcells ?CV CV ?includeWiringCellNames + (list PowerGridCellName)) + (fprintf pout "%s %s abstract\n" sub->libName sub->cellName)) + (close pout) + + ; export LEF for subcells + statusLef = (ldtrLefWriteOA + (sprintf nil "%s.lef" CV->cellName) + TechLibName + nil + LefCellsList + nil + (sprintf nil "%s.lef.log" CV->cellName) + t + "5.7") + ) + + ; export DEF + (when doDef + statusDef = t + ExportCV = (dbCopyCellView CV CV->libName CV->cellName "export_tmp" nil nil t) + (when Proteus (dbTransformCellView ExportCV 1.0 90.0)) ; rotate for Proteus + (foreach inst ExportCV->instances + abstractCV = (dbOpenCellViewByType inst->libName inst->cellName "abstract") + (cond (abstractCV inst->master=abstractCV) + (!abstractCV && (IsWiringCell inst) (dbDeleteObject inst)) + (t + (printf "ERROR: %s has no abstract view\n" inst->cellName) + statusDef=nil) + ) + ) + (dbSave ExportCV) + + ; export DEF + (when statusDef + statusDef = (ldtrDefWriteOA + (sprintf nil "%s.def" CV->cellName) + ExportCV->libName + ExportCV->cellName + ExportCV->viewName + (sprintf nil "%s.def.log" CV->cellName) + "5.7") + ) + ) + + ; write SetSkipRouting.tcl + (when doSkipRouting + SkipRoutingFileName = (strcat CV->cellName ".SetSkipRouting.tcl") + pout=(outfile SkipRoutingFileName) + (fprintf pout "proc ProteusUserSetSkipRouting {} {\n") + inplacedPins=(FindInplacedPins CV) + (foreach pinName inplacedPins + rexCompile("\\[") + pinName=(rexReplace pinName "\\\\[" 0) + rexCompile("\\]") + pinName=(rexReplace pinName "\\\\]" 0) + (fprintf pout " setAttribute -net \"%s\" -skip_routing true\n" pinName)) + (fprintf pout "}\n") + (close pout) + ) + + ; export DEF for nondefault rules + (when doNondefaultDef + Command = (sprintf nil + (strcat "%s/cast2def" + " --cast-path=%s" + " --cell=%s" + " --outfile=%s" + " --cadence-name" + " --max-heap-size=%dM" + " &> exportNondefaultRuleDEF.log") + BinRoot + CAST_PATH + CV->cellName + (strcat CV->cellName "_nondefault.def") + MaxHeapSize) + (printf "%s\n" Command) + statusNonDefault = (shell Command) + ) + + ; export DEF for wiring tracks + (when doTracksDef + Command = (sprintf nil + (strcat "%s/genTracks" + " --refdef=%s" + " --outfile=%s" + " --track-pitch=%.3f" + " %s") + BinRoot + (strcat CV->cellName ".def") + (strcat CV->cellName "_tracks.def") + DefaultWiringPitch + (if Proteus "--rotate" "")) + (printf "%s\n" Command) + statusTracks = (shell Command) + ) + + ; save + (dbSave CV) + + ; summarize errors + errorStr = "" + (unless statusVerilog (strcat errorStr " Verilog")) + (unless statusLef (strcat errorStr " LEF")) + (unless statusDef (strcat errorStr " DEF")) + (unless statusNonDefault (strcat errorStr "NonDefaultDEF")) + (unless statusTracks (strcat errorStr "TracksDEF")) + (when errorStr!="" (error errorStr)) + + ; return CV + CV + ) + ) + +; utility to find the list of subcells that need LEF +; includes power grid, excludes other wiring cells +(defun ListLefSubcells + (@key (CV (geGetEditCellView)) ; specify CellView + (includeWiringCellNames nil) ; include specified wiring cells + ) + (let (str subcells) + subcells = nil + (foreach inst CV->instances + str = (strcat inst->libName ".wires") + (when (and inst->libName!=TechLibName + (member inst->master->cellView subcells)==nil + (or (strncmp inst->cellName str (strlen str))!=0 + (member inst->cellName includeWiringCellNames) + ) + ) + subcells = (cons inst->master->cellView subcells) + ) + ) + subcells + ) + ) + +; Shortcut for Proteus asynchronous defaults +(defun ProteusExport (@key (CV (geGetEditCellView))) + (NanoRouteExport ?CV CV ?Proteus t)) + +; Shortcut for Proteus synchronous defaults +(defun SynchronousExport (@key (CV (geGetEditCellView))) + (NanoRouteExport ?CV CV ?Synchronous t)) + +; Write TCL file to run NanoRoute +(defun NanoRouteTcl + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (bottomMetal 3) ; bottom metal layer + (topMetal 7) ; top metal layer + (Verify t) ; run VerifyGeom and VerifyConn at the end + (SkipCompleteNets t) ; auto-skip complete nets + (SaveQuit nil) ; automatically save and quit NanoRoute + (strictNondefault t) ; strict nondefault width/spacing rules + (AutoStop t) ; stop routing if too many errors + (routeGND nil) ; route GND net + (routeVdd nil) ; route Vdd net + ) + (let (CmdFile file) + ; write TCL + CmdFile = (strcat CV->cellName ".tcl") + file = (outfile CmdFile) + (unless file (error "Unable to write %s\n" CmdFile)) + (fprintf file "set PDK_ROOT %s\n" + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT")) + (fprintf file "set TOP \"%s\"\n" CV->cellName) + (fprintf file "set TOP_LAYER %d\n" topMetal) + (fprintf file "set BOTTOM_LAYER %d\n" bottomMetal) + (fprintf file "source $PDK_ROOT/share/Fulcrum/nano/nano.tcl\n") + (fprintf file "setNanoRouteMode -quiet -routeStrictlyHonorNonDefaultRule %s\n" + (if strictNondefault "true" "false")) + (fprintf file "setNanoRouteMode -quiet -drouteAutoStop %s\n" + (if AutoStop "true" "false")) + (fprintf file "FulcrumLoad\n") + (when SkipCompleteNets (fprintf file "FulcrumSkipCompleteNets\n")) + (unless routeGND (fprintf file "setAttribute -net GND -skip_routing true\n")) + (unless routeVdd (fprintf file "setAttribute -net Vdd -skip_routing true\n")) + (fprintf file "FulcrumRoute\n") + (when Verify (fprintf file "FulcrumVerify\n")) + (fprintf file "FulcrumSave\n") + (when SaveQuit (fprintf file "exit\n")) + (close file) + ) + t + ) + +; launch NanoRoute +(defun NanoRouteRun + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (Background t) ; run in foreground or background + (Ticket "np") ; QSUB ticket: np, nano + (Mem 4000) ; QSUB mem to request + (Soc (getShellEnvVar "SOC_SCRIPT")) ; which version of Encounter to use + ) + (let (CmdFile LicenseStr QsubOptions Command defFile status) + ; files and options + CmdFile = (strcat CV->cellName ".tcl") + LicenseStr = "-socel" + QsubOptions = (sprintf nil "-cwd -now n -l %s=1,mem=%dM,a=lx24-amd64 -N NanoRoute" + Ticket Mem) + defFile = (strcat CV->cellName "_routed.def") + + ; run + (shell (strcat "rm -rf " defFile)) + Command = (sprintf nil "qrsh %s %s encounter -64 %s -init %s %s" + QsubOptions Soc + LicenseStr CmdFile (if Background "-nowin &" "-win")) + (printf "%s\n" Command) + status = (shell Command) + (unless status (error "Nanoroute failed\n")) + + ; wait for slow filesystem until def is created + (or Background (WaitForFile defFile 60)) + ) + ) + +; write proteus.config +(defun ProteusConfig + (@key (CV (geGetEditCellView)) ; specify CellView or use edit view + (bottomMetal 3) ; bottom metal layer + (topMetal 7) ; top metal layer + ) + (let (CAST_PATH DFII_DIR SPAR_DIR TEMP file) + ; files and options + CAST_PATH = (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + DFII_DIR = (ConfigFileGetValue TheCDSConfigTable "DFII_DIR") + SPAR_DIR = "/mnt/fulcrum/local/checkouts/alta/alta/layout/tsmc65/spar" + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + + ; write config file + file = (outfile (strcat CV->cellName ".config")) + (fprintf file "--cast-path=%s\n" CAST_PATH) + (fprintf file "--dfII-dir=%s\n" DFII_DIR) + (fprintf file "--spar-dir=%s\n" SPAR_DIR) + (fprintf file "--cast-dir=%s/cast\n" TEMP) + (fprintf file "--spec-dir=%s/spec\n" TEMP) + (fprintf file "--lefdef-dir=.\n") + (fprintf file "--lve-path=lve:/mnt/fulcrum/alta/lve/lve\n") + (fprintf file "--output-dir=%s/proteus\n" TEMP) + (fprintf file "--scratch-dir=\n") + (fprintf file "--base=%s\n" CV->cellName) + (fprintf file "--cell=%s\n" CV->cellName) + (fprintf file "--scan-mode=off\n") + (fprintf file "--macro-integration=1\n") + (fprintf file "--bottom-layer=%d\n" bottomMetal) + (fprintf file "--top-layer=%d\n" topMetal) + (fprintf file "--task=cast2rtl,rc,clockfree,encounter,summarize\n") + (close file) + ) + ) + +; timing driven routing with Proteus script +(defun ProteusRun + (@key (CV (geGetEditCellView)) ; specify CellView or use edit view + (Background t) ; run in background + (Mem 4000) ; qsub memory + (bottomMetal 3) ; bottom metal layer + (topMetal 7) ; top metal layer + ) + (let (TEMP defFile Command status) + ; files and options + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + defFile = (strcat TEMP "/proteus/" (cadr (reverse (parseString CV->cellName "."))) + ".qdi.def") + + ; run + (shell (strcat "rm -rf " defFile)) + (shell (strcat "ln -sf " defFile " " CV->cellName "_routed.def")) + Command = (sprintf nil "proteus --include=%s.config --mem=%dM%s" + CV->cellName Mem (if Background " &" "")) + (printf "%s\n" Command) + status = (shell Command) + (unless status (error "Proteus failed\n")) + + ; wait for slow filesystem until def is created + (or Background (WaitForFile defFile 60)) + ) + ) + +; wait for file to appear on filesystem +(defun WaitForFile (FileName MaxSeconds) + (let (n) + n=0 + (while (and nlibName) + (cellName CV->cellName) + (viewName "layout") + (defFile (strcat (geGetEditCellView)->cellName "_routed.def")) ; def input file + (proteus nil) ; import from Proteus? + ) + (let (SubcellLibNames Command status ImportCV layoutCV floorplanCV win instmap nodemap) + + ; create library + (when libName!=CV->libName + (GDSIIHierMakeLibrary libName (getShellEnvVar "DFII_DIR") TechLibName) + ) + + ; figure out libNames for all exported subcells + SubcellLibNames = (GetSubcellLibNames defFile) + + ; import def + status = (ldtrDefReadOA + defFile ; t_fileName + libName ; t_libName + (getShellEnvVar "DFII_DIR") ; [t_libPath libPath] + cellName ; [t_cellName cellName] + viewName ; [t_viewName viewName] + TechLibName ; [t_techName techName] + "abstract_proteus abstract" ; [t_viewNameList viewNameList] + (buildString SubcellLibNames) ; [t_masterLibs masterLibs] + nil ; [ shared nil] + nil ; [ noRouting nil] + (strcat defFile ".log") ; [ t_logName logName] + nil ; [ useCustomVias nil] + t ; [ overwrite nil] + nil ; [ createModHier nil] + ; [ t_commentChar commentChar] + ; [ t_templateFileName templateFileName] + ) + (unless status (error "Unsuccessful defin\n")) + ImportCV = (dbOpenCellViewByType libName cellName viewName "maskLayout" "a") + + ; unrotate Proteus cells and wires, rename instances and nodes + (when proteus + instmap = (PinInstXrefTable) + nodemap = (PinNodeXrefTable) + (foreach inst (setof obj ImportCV->instances obj->viewName=="abstract_proteus") + (ImportProteusInstance CV instmap inst) + ) + (dbTransformCellView ImportCV 1.0 -90.0) + ) + + ; label pins + (LabelPins ?CV ImportCV) + + ; change abstract instances to layout or floorplan view + (foreach inst (setof obj ImportCV->instances obj->viewName=="abstract") + layoutCV = (dbOpenCellViewByType inst->libName inst->cellName "layout") + floorplanCV = (dbOpenCellViewByType inst->libName inst->cellName "floorplan") + (cond (layoutCV inst->master=layoutCV) + (floorplanCV inst->master=floorplanCV) + ) + ) + + ; change window to ImportCV + win = (hiGetCurrentWindow) + (cond (win + (geOpen ?lib libName ?cell cellName ?view viewName + ?viewType "maskLayout" ?mode "a" ?window win)) + (t + (geOpen ?lib libName ?cell cellName ?view viewName + ?viewType "maskLayout" ?mode "a")) + ) + + ; execute custom function + (FinishRouterImport) + + ; save layout + (dbSave ImportCV) + + ; create floorplan view for Proteus + (when proteus (MakeProteusFloorplanView ?CV ImportCV)) + + ;return layout + ImportCV + ) + ) + +; defaults for importing Proteus cells +(defun NanoProteusImport (defFile libName cellName @key (CV (geGetEditCellView))) + (NanoRouteImport ?libName libName ?cellName cellName ?defFile defFile ?proteus t ?CV CV) + ) + +; HACK: special processing of Proteus instances +(defun ImportProteusInstance (CV map inst) + (let (newname) + ; unrotate (swap X and Y) + (cond (inst->orient=="R0" inst->orient="MXR90") + (inst->orient=="R180" inst->orient="MYR90") + (inst->orient=="MX" inst->orient="R270") + (inst->orient=="MY" inst->orient="R90") + ) + ; change to layout view + inst->master = (dbOpenCellViewByType inst->libName inst->cellName "layout") + ; translate instance name + newname = (arrayref map inst->name) + (when newname && inst->name!=newname inst->name=newname) + inst + ) + ) + +; Finish router import, user over-ridable in wires.il +(defun FinishRouterImport () + (DeleteKeepout) + (defun RunAfterImportDef () t) + (LoadWires) + (RunAfterImportDef) + ) + +; make a floorplan view +(defun MakeProteusFloorplanView (@key (CV (geGetEditCellView))) + (let (fCV) + fCV = (dbOpenCellViewByType CV->libName CV->cellName "floorplan" "maskLayout" "w") + (foreach inst (setof s CV->instances s->libName!=TechLibName && s->name!="tiehilo") + inst = (dbCopyFig inst fCV (list 0:0 "R0")) + inst->master = (dbOpenCellViewByType inst->libName inst->cellName "floorplan") + ) + (when CV->prBoundary + (dbCopyFig CV->prBoundary fCV (list 0:0 "R0")) + ) + fCV + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/prelayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/prelayout.il new file mode 100644 index 0000000000..fd8ea85429 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/prelayout.il @@ -0,0 +1,157 @@ +; Replacement for ui/Nano/Prelayout/CreatePrelayout.il +; +; Refers to nrCastQuery, nrIsRoutedCell, nrSyncToNetlist, NameFilterInstances, +; CreateInstWithAlignmentProps, SetCellAlignment, CheckRoutedAlignment + +; Top-level function to make a prelayout view and switch to it +(defun MakePrelayout + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (RegenerateFromCast nil) ; force CAST query + (Overwrite t) ; overwrite existing editable prelayout views + (SyncToNetlist t) ; sync-to-netlist on prelayout view + (Verbose nil) ; verbose + ) + (let (routedDirectiveList LibCellsToIgnore win) + ; check viewName + (when CV->viewName!="floorplan" (error "Call MakePrelayout on floorplan view\n")) + + ; save floorplan view + (dbSave CV) + + ; query routed directives + routedDirectiveList = (nrCastQuery CV ?RegenerateFromCast RegenerateFromCast) + + ; construct list of cellName regexp's to skip + LibCellsToIgnore = + (append WiringCellLibCellPairRegExs + (append TechLibCellPairRegExs + (append GateLibCellPairRegExs StackLibCellPairRegExs))) + + ; recurse + mapToPrelayout = (makeTable "mapToPrelayout" nil) + CV = (MakePrelayoutRecurse CV mapToPrelayout + ?RegenerateFromCast RegenerateFromCast + ?Overwrite Overwrite + ?SyncToNetlist SyncToNetlist + ?Verbose Verbose + ?routedDirectiveList routedDirectiveList + ?LibCellsToIgnore LibCellsToIgnore) + + ; add buswires instance + (AddBusWires ?CV CV) + + ; switch current window + win = (hiGetCurrentWindow) + (when win + (geOpen ?window win + ?lib CV->libName + ?cell CV->cellName + ?view CV->viewName + ?viewType "maskLayout" + ?mode "r") + + ; draw bus wires (specifically keepout) + (LoadWires) + (RefreshAllBuswires) + ) + + ; set nonleaf property + (SetLeafProp CV nil) + + ; convert prbound + (ConvertPrboundToObject ?CV CV) + + ; return prelayout view + (dbSave CV) + CV + ) + ) + +; add buswires if it exists +(defun AddBusWires (@key (CV (geGetEditCellView)) (name "buswires")) + (let (typeName buswires busCV) + typeName = (cadr (reverse (parseString CV->cellName "."))) + buswires = (strcat CV->libName ".wires." typeName "_" name) + busCV = (dbOpenCellViewByType CV->libName buswires "layout" "maskLayout" "r") + (when (and busCV (dbFindAnyInstByName CV name)==nil) + (dbCreateInst CV busCV name 0:0 "R0") + ) + ) + t + ) + +; recursively create prelayout views +(defun MakePrelayoutRecurse (CV mapToPrelayout @key + (RegenerateFromCast t) (Overwrite t) + (SyncToNetlist t) (Verbose nil) + (routedDirectiveList nil) (LibCellsToIgnore nil)) + (let (prelayoutCV instances instName transform instCV) + + ; terminate on routed=true cells or recurse + (cond ((nrIsRoutedCell CV->libName CV->cellName CV->viewName + ?routedDirectiveList routedDirectiveList + ?Verbose Verbose + ?RegenerateFromCast RegenerateFromCast) + ; return CV for layout, prelayout, or floorplan in that order + prelayoutCV = (dbOpenCellViewByType CV->libName CV->cellName + "layout" "maskLayout" "r") || + (dbOpenCellViewByType CV->libName CV->cellName + "prelayout" "maskLayout" "r") || + (dbOpenCellViewByType CV->libName CV->cellName + "floorplan" "maskLayout" "r") + ) + (mapToPrelayout[CV] ; already created + prelayoutCV = mapToPrelayout[CV] + ) + (t + ; create new prelayout view + prelayoutCV = (dbCopyCellView CV CV->libName CV->cellName + "prelayout" nil nil Overwrite) + (cond (prelayoutCV + (DeletePins ?cv prelayoutCV) + (CopyAlignmentProps CV prelayoutCV) + instances = (setof inst prelayoutCV->instances inst->libName!=TechLibName) + instances = (car (NameFilterInstances instances LibCellsToIgnore)) + ; recurse on each instance + (foreach inst instances + instName = inst->name + transform = inst->transform + instCV = (MakePrelayoutRecurse + inst->master->cellView + mapToPrelayout + ?routedDirectiveList routedDirectiveList + ?Verbose Verbose + ?RegenerateFromCast RegenerateFromCast + ?Overwrite Overwrite + ?LibCellsToIgnore LibCellsToIgnore + ?SyncToNetlist SyncToNetlist) + (dbDeleteObject inst) + (CreateInstWithAlignmentProps prelayoutCV instCV + instName (car transform) (cadr transform)) + ) + (when SyncToNetlist (nrSyncToNetlist prelayoutCV)) + (dbSave prelayoutCV) + (printf "Created %s(%s)...\n" + prelayoutCV->cellName prelayoutCV->viewName) + ) + (t + ; unwritable prelayout view + prelayoutCV = (dbOpenCellViewByType CV->libName CV->cellName + "prelayout" "maskLayout" "r") + ) + ) + + ; check alignments + (SetCellAlignment prelayoutCV) + (when (CheckRoutedAlignment prelayoutCV) + (printf "WARNING: Instances misaligned in %s(%s)\n" + prelayoutCV->cellName prelayoutCV->viewName) + ) + ) + ) + + ; save mapping and return prelayoutCV + mapToPrelayout[CV] = prelayoutCV + prelayoutCV + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/reset.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/reset.il new file mode 100644 index 0000000000..3535f7953e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/reset.il @@ -0,0 +1,198 @@ +; Print closest reset net for unconnected reset pins of subcells. +; +; Copyright 2011 Fulcrum Microsystems. All rights reserved. + +; find bounding box of everything connected to a net +(defun FindNetBBox (net) + (let (bbox pins) + bbox = nil + (foreach pin net->pins bbox = (BBoxCombine bbox pin->fig->bBox)) + (foreach fig net->figs bbox = (BBoxCombine bbox fig->bBox)) + pins = (nrFindPinShapes net MetalLPPs) + (foreach entry pins + (foreach rect (cadr entry) + rect = (BBoxCanonicalize rect) + bbox = (BBoxCombine bbox rect) + ) + ) + (unless pins + (foreach term net->instTerms + bbox = (BBoxCombine bbox term->inst->bBox)) + ) + bbox + ) + ) + +; Distance between two bbox's. Zero if bbox'es overlap. +(defun DistanceBetweenBBoxes (bbox1 bbox2 @key (scaleX 1) (scaleY 1)) + (let (bbox dx dy) + bbox = (BBoxCombine bbox1 bbox2) + dx = (BBoxGetWidth bbox) - (BBoxGetWidth bbox1) - (BBoxGetWidth bbox2) + dy = (BBoxGetHeight bbox) - (BBoxGetHeight bbox1) - (BBoxGetHeight bbox2) + dx = (max dx 0) + dy = (max dy 0) + scaleX*dx + scaleY*dy + ) + ) + +; Find output nets of all RAMP_RESET cells +(defun FindRampResetNets + (@key (CV (geGetEditCellView)) + (ramptype "standard.reset.RAMP_RESET")) + (let (ramps resets) + ramps = (setof inst CV->instances + (strncmp inst->cellName ramptype (strlen ramptype))==0) + resets = nil + (foreach inst ramps + (foreach term inst->instTerms + (when term->name=="_RES" resets = (cons term->net resets)) + ) + ) + resets + ) + ) + +; Find unconnected reset pins of subcells +(defun FindUnconnectedResetNets (@key (CV (geGetEditCellView)) (resets nil)) + (let (unconnected) + (unless resets resets = (FindRampResetNets ?CV CV)) + unconnected = nil + (foreach net (setof net CV->nets net->term==nil && !(memq net resets)) + (when (setof term net->instTerms + ((strncmp term->name "_reset" 6)==0 || + (strncmp term->name "_RESET" 6)==0)) + unconnected = (cons net unconnected) + ) + ) + unconnected + ) + ) + +; Print CAST connecting all subcells with unconnected _reset or _RESET +; pins to the closest RAMP_RESET output +(defun FindClosestResets + (@key (CV (geGetEditCellView)) + (filename "closest_reset.cast") + (ramptype "standard.reset.RAMP_RESET") + (scaleX 1) + (scaleY 1) + ) + (let (file ramps resets best_reset best_distance distance unconnected + net_bBox reset_bBox lines name1 name2 sub_dist best_sub_dist) + (unless CV->viewName=="prelayout" || CV->viewName=="floorplan" + (error "Run on floorplan or prelayout view\n")) + file = (outfile filename) + (unless file (error "Can't write %s\n" filename)) + (fprintf file " // connect reset using (FindClosestResets)\n") + + ; find available RAMP_RESET output nets + resets = (FindRampResetNets ?CV CV ?ramptype ramptype) + + ; find unconnected local reset nets + unconnected = (FindUnconnectedResetNets ?CV CV ?resets resets) + + ; connect each to closest reset + (rexCompile "\\]\\[") ; convert ][ to , + lines = nil + (foreach net unconnected + net_bBox = (FindNetBBox net) + best_reset = nil + best_distance = 0 + best_sub_dist = 0 + (foreach reset resets + reset_bBox = (FindNetBBox reset) + ; primary metric is the distance between bounding boxes + distance = (DistanceBetweenBBoxes net_bBox reset_bBox + ?scaleX scaleX ?scaleY scaleY) + ; tie-breaker metric is half perimeter of the reset_bBox + sub_dist = scaleX*(BBoxGetWidth reset_bBox) + + scaleY*(BBoxGetHeight reset_bBox) + ; track best reset choice + (when !best_reset || distancename "," 0) + name2 = (rexReplace net->name "," 0) + lines = (cons (sprintf nil " %s = %s;\n" name1 name2) lines) + ) + ) + + ; finish file + lines = (sort lines nil) + (foreach line lines (fprintf file "%s" line)) + (close file) + (printf "Wrote %s\n" filename) + t + ) + ) + +; Check if two sets of pin shapes overlap +(defun DoPinShapesConnect (pins1 pins2) + (let (layer1 layer2 overlap) + overlap = nil + (foreach shapes1 pins1 + layer1 = (car shapes1) + (foreach bbox1 (cadr shapes1) + (foreach shapes2 pins2 + layer2 = (car shapes2) + (when layer1==layer2 + (foreach bbox2 (cadr shapes2) + (when (BBoxAnd bbox1 bbox2) overlap=t) + ) + ) + ) + ) + ) + overlap + ) + ) + +; Print CAST connecting resets that are already shorted in the layout. +; Used for ARRAY. +(defun FindShortedResets + (@key (CV (geGetEditCellView)) + (filename "shorted_reset.cast") + (ramptype "standard.reset.RAMP_RESET") + (pin_lpps MetalLPPs) + ) + (let (file resets unconnected net1 net2 pins1 pins2 name1 name2) + (unless CV->viewName=="prelayout" || CV->viewName=="floorplan" + (error "Run on floorplan or prelayout view\n")) + file = (outfile filename) + (unless file (error "Can't write %s\n" filename)) + (fprintf file " // connect reset using (FindShortedResets)\n") + + ; find available RAMP_RESET output nets + resets = (FindRampResetNets ?CV CV ?ramptype ramptype) + + ; find unconnected local reset nets + unconnected = (FindUnconnectedResetNets ?CV CV ?resets resets) + + ; report overlapping pins + (rexCompile "\\]\\[") ; convert ][ to , + (for i 0 (length unconnected)-1 + net1 = (nth i unconnected) + pins1 = (nrFindPinShapes net1 pin_lpps) + (for j i+1 (length unconnected)-1 + net2 = (nth j unconnected) + pins2 = (nrFindPinShapes net2 pin_lpps) + (when net1!=net2 && (DoPinShapesConnect pins1 pins2) + name1 = (rexReplace net1->name "," 0) + name2 = (rexReplace net2->name "," 0) + (fprintf file " %s = %s;\n" name1 name2) + ) + ) + ) + + ; close file + (close file) + (printf "Wrote %s\n" filename) + t + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/route.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/route.il new file mode 100644 index 0000000000..925fa525c1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/route.il @@ -0,0 +1,235 @@ +; Automated routing using VCAR. Wastes less time than the old UI. +; +; Copyright 2010 Fulcrum Microsystems. All rights reserved. + +; Export, Route, Import using CCAR +(defun Route + (@key (CV (geGetEditCellView)) ; specify CellView or nil to use edit view + (type "mid") ; routing rul/do file to use from PDK ("mid"/"leaf") + (viaType "c") ; via type ("c"/"min") + (routeGND nil) ; route GND net + (routeVdd nil) ; route Vdd net + (bottomMetal nil) ; bottom metal layer to use, or nil to use wires.il + (topMetal nil) ; top metal layer to use, or nil to use wires.il + (SaveQuit nil) ; automatically save and quit CCAR + (Background nil) ; run in foreground or background + (subcellView "abstract_edit abstract") ; alternate views of subcells to export to CCAR + (importView "layout_pg") ; view name to import wiring back to + (conductorDepth 0) ; sets CCAR conductor depth + (retry t) ; automatic retry + ) + (let (TEMP FulcrumPDKRoot RouterPDK DoFile RouterDoFile SaveQuitStr + rules options session status tiehilo win cmd) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + + ; make flatten view automatically + (when (or CV->viewName=="floorplan" CV->viewName=="prelayout") + CV = (MakeFlatten ?CV CV)) + + ; get config settings + FulcrumPDKRoot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + RouterPDK = (sprintf nil "%s/share/Fulcrum/cell_automation/router" FulcrumPDKRoot) + DoFile = (sprintf nil "%s/%s.do" RouterPDK type) + + ; load wires.il and set options + (LoadWires) + (unless bottomMetal bottomMetal = (if type=="leaf" 1 bundled_bottom_layer)) + (unless topMetal topMetal = (if type=="leaf" 3 bundled_top_layer)) + + ; write do file + RouterDoFile = (WriteRouterDoFile CV ?viaType viaType + ?routeGND routeGND ?routeVdd routeVdd + ?bottomMetal bottomMetal + ?topMetal topMetal) + + ; options + SaveQuit = (or SaveQuit Background) + rules = (sprintf nil "%s/%s.rul" RouterPDK type) + SaveQuitStr = (sprintf nil "-do %s/savequit.do" RouterPDK) + options = (sprintf nil "-guidir %s -noclean -virtuoso -do %s -do %s %s" + TEMP RouterDoFile DoFile + (if SaveQuit SaveQuitStr "")) + session = (sprintf nil "%s/%s.ses" TEMP CV->cellName) + (shell (sprintf nil "rm -f %s" session)) + + ; export + status = (iccExportCellview + ?layoutLCV (list CV->libName CV->cellName CV->viewName) + ?background nil + ?exportDirectory TEMP + ?rulesFile rules + ?conductorDepth conductorDepth + ?keepoutDepth 32 + ?pinConnection "strong" + ?optionList (list "fullConnectivity" "interLayer") + ?alternateViews (if subcellView!="" (parseString subcellView " ") nil) + ?startICC nil) + (unless status (error "Unable to export to VCAR\n")) + + ; route + cmd = (sprintf nil "vcar %s/%s.dsn %s %s" + TEMP CV->cellName options (if Background "-nog &" "")) + (printf "%s\n" cmd) + status = nil + (while !status + status = (shell cmd) + (unless status || retry (error "VCAR failed. Inspect *.did file.\n")) + (unless status + (printf "Unable to run VCAR, retrying...\n") + (sleep 30) + ) + ) + + ; import from VCAR + (cond (Background (printf "Running in background, finish with RouteImport\n")) + (t CV = (RouteImport ?CV CV ?importView importView)) + ) + CV + ) + ) + +; Import from CCAR +(defun RouteImport + (@key (CV (geGetEditCellView)) + (importView "layout_pg") + ) + (let (TEMP session status win) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + session = (sprintf nil "%s/%s.ses" TEMP CV->cellName) + + ; copy flatten view to importView + (when (and importView!="" CV->viewName!=importView) + CV = (dbCopyCellView CV CV->libName CV->cellName importView nil nil t)) + + ; import from CCAR + status = (iccImportCellview + ?layoutLCV (list CV->libName CV->cellName CV->viewName) + ?iccFile session + ?sectionList (list "routes") + ?background nil) + (unless status (error "Unable to import from VCAR\n")) + + ; change to importView + win = (hiGetCurrentWindow) + (unless win (error "Can't change to view %s\n" importView)) + (geOpen ?window win + ?lib CV->libName + ?cell CV->cellName + ?view CV->viewName + ?viewType "maskLayout" + ?mode "a") + + ; execute custom function + (FinishRouterImport) + + ; save layout_pg + (dbSave CV) + + ; create layout view + (MakeLayout ?CV CV) + + ;return layout_pg + CV + ) + ) + +; shortcut for leaf cells +(defun DeprecatedRouteLeaf + (@key (CV (geGetEditCellView)) + (type "custom_leaf") + (viaType "c") + (importView "layout") + ) + (Route ?CV CV + ?type type + ?viaType viaType + ?bottomMetal 1 + ?topMetal 3 + ?routeGND t + ?routeVdd t + ?importView importView + ) + ) + +; write FQCN.do for VCAR +(defun WriteRouterDoFile (CV @key (viaType "c") + (routeGND nil) (routeVdd nil) + (bottomMetal 3) (topMetal 7) + (maxheap (nrGetMaxHeapSize))) + (let (TEMP DoFile SkillFile Command p_out wireType width space extension netProps + status) + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP" ) + DoFile = (sprintf nil "%s/%s.do" TEMP CV->cellName) + + ; get information from CAST + SkillFile = (sprintf nil "%s/%s_routing.skill" TEMP CV->cellName ) + Command = (sprintf nil + "%s/cast2def --cast-path=%s --cell=%s --outfile=%s --format=skill --cadence-name --max-heap-size=%dM > %s" + (PackageGetBinRoot) + (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + CV->cellName + SkillFile + maxheap + (sprintf nil "%s/%s_routing.log" TEMP CV->cellName) + ) + (printf "%s\n" Command) + status = (shell Command) + (unless status (error "cast2def failed\n")) + (load SkillFile) + + ; write do file + p_out = (outfile DoFile) + (unless p_out (error (sprintf( nil "Unable to write %s\n" DoFile)))) + + ; emit width/clearance/extension directives + (fprintf p_out "# wiring directives\n") + (fprintf p_out "define (class RESET_3W3S)\n") ; make sure it exists + (foreach nets NondefaultRoutingDirective + wireType = (car nets) + nets = (cdr nets) + netProps = (arrayref NondefaultRouting wireType ) + nets = (setof net nets (GetProp (dbFindNetByName CV net) "BundledNet" nil)==nil) + + ; define nets + (fprintf p_out "define (class %s" wireType) + (foreach net nets (fprintf p_out " %s" net)) + (fprintf p_out ")\n") + + ; define rules + width = (car netProps) + space = (cadr netProps) + extension = (caddr netProps) + (fprintf p_out "rule class %s (width %f)\n" wireType width) + (fprintf p_out "rule class %s (clearance %f (type wire_wire))\n" wireType space) + (fprintf p_out "rule class %s (clearance %f (type area_wire))\n" wireType space) + (fprintf p_out "rule class %s (wire_extension %f)\n" wireType extension) + ) + (fprintf p_out "\n") + + ; select metal and vias + (fprintf p_out "# select metal and vias\n") + (fprintf p_out "unselect all layers\n") + (fprintf p_out "unselect all vias\n") + (for layer bottomMetal topMetal + (fprintf p_out "select layer M%d\n" layer) + (when layer>=3 + (fprintf p_out "select via M%d_M%d%s\n" layer layer-1 viaType) + ) + ) + (fprintf p_out "\n") + + ; optionally protect Vdd/GND + (unless routeGND + (fprintf p_out "# dont route power\n") + (fprintf p_out "fix net GND\n\n") + ) + (unless routeVdd + (fprintf p_out "# dont route power\n") + (fprintf p_out "fix net Vdd\n\n") + ) + + ; end of generated do file + (close p_out) + DoFile + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/routepath.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/routepath.il new file mode 100644 index 0000000000..590f2ed08b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/routepath.il @@ -0,0 +1,8851 @@ +/* vim:ts=4:sw=4:expandtab + * (No tabs, indent level is 4 spaces) */ + +(defun RouteBuffers (path bufferList layerPatternList @key + (bufDist 460.0) (startDist nil) (termDist nil) + (firstPattern nil) (lastPattern nil) + (colPathGuide nil) + (flipSegPattern nil) + (reserveGap nil) + (turnGap nil) + (inlinePrefix nil) + (guideX nil) (guideY nil) + (locException nil) + (sramCfg nil) + (bufSegOffset 0) + (balance nil) + (nestedArray nil) + (outfp nil) (checkPath t) + (debug 0) (drawGuide nil) (h nil) ) + (prog (bufSegNum sramSegNum segPropList lastCellLoc segPoints leftList len + rightList result segIdx entry col colPathList x y turnGapX turnGapY + bufAlignList sramSegIndex bufPrefixName numCols colBufDist seg + cnt point nextPoint pathOffset shiftDist busMaxOff el hasErr ) + (if !startDist startDist = bufDist) + (if !termDist termDist = bufDist) + (if h then + printf("\n\n") + printf("Route buffers along a given path\n") + printf("Usage: RouteBuffers(path bufferList layerPatternList [OPTION])\n") + printf(" ?h t - this help\n") + printf(" ?bufDist - Specify distance between segments. Default %.1f\n" bufDist) + printf(" ?startDist - Specify distance of first segment. Default %.1f\n" startDist) + printf(" ?termDist - Specify distance of last segment. Default %.1f\n" termDist) + printf(" ?locException - Overide segment location\n") + + printf(" ?colPathGuide - Route along the specify node path or bus path with specified offsets\n") + printf(" Either a list of node entries or list of offsets for each column\n") + printf(" list(\".RX_KEY_CPU_CODE[2].e\" \".RX_STATS_EACL_COUNT[7].e\")") + printf(" list(list( [firstSegOffset] [lastSegOffset]))\n") + printf(" ?firstPattern - Pattern of first segment from input pin\n") + printf(" ?lastPattern - Pattern of last segment to output pin\n") + printf(" ?flipSegPattern - List of segments to flip bus pattern\n") + printf(" ?reserveGap - List of gaps to prevent buffers being placed within this reserved space\n") + printf(" ?turnGap - Gap to reserve when turning corner. A single value for both vertical + and horizontal reserve distance or a list for each value\n") + printf(" ?inlinePrefix - Name preappended to buffer due to inline\n") + printf(" ?balance - Balance left and right side of vertical buffer stack\n") + printf(" ?checkPath - Perform some sanity of path alignment\n") + printf(" ?drawGuide - Draw debug guide paths\n") + return(t) + ) + + (if debug >= 3 printf("RouteBuffers along path %L with bufDist %L\n" path bufDist)) + + (if stringp(car(car(bufferList))) bufferList = list(bufferList)) + (if debug >= 1 then + cnt = 0 + (foreach col bufferList + printf("##################### Col#%d:######################\n" cnt) + bufSegNum = 0 + (foreach entry col + bufSegNum++ + printf(" Seg#%d: %L\n" bufSegNum entry) + ) + cnt++ + ) + ) + busMaxOff = -9999.99 + (foreach el layerPatternList + (if busMaxOff < nth(2 el) busMaxOff = nth(2 el)) + ) + + (if drawGuide then + dbCreatePath((geGetEditCellView) list("M2" "bus") path 0.8) + ru_drawPathGuide(path guideX guideY) + (if reserveGap then + (foreach el reserveGap + segIdx = nth(0 el) + (if ru_getSegDir(nth(segIdx path) nth(segIdx+1 path))=="VERT" then + x = xCoord(nth(segIdx path)) + floor(busMaxOff)/2 + seg = list(x:nth(1 el) x:nth(2 el)) + else + y = yCoord(nth(segIdx path)) + floor(busMaxOff)/2 + seg = list(nth(1 el):y nth(2 el):y) + ) + dbCreatePath((geGetEditCellView) list("M5" "block") seg floor(busMaxOff)) + ) + ) + ) + + (if !layerPatternList error("RouteBuffers: layerPatternList is nil\n")) + (if !path error("RouteBuffers: path is nil\n")) + (if checkPath then + cnt = 0 + hasErr = nil + (foreach point path + (if mod(floor((yCoord(point)+TrackPitch/64)/TrackPitch) 2) == 1 then + len = length(path) + (cond + (cnt == 0 || cnt == len-1 + (if debug >= 2 printf("RouteBuffers: Y coord of point#%d path points on even track but got %L or (%.2f,%.2f) in tracks\n" + cnt point xCoord(point)/TrackPitch yCoord(point)/TrackPitch)) + ) + ((cnt <= 1 && Ru_GetDistance(car(path) cadr(path)) < 400.0) || + (cnt >= len-2 && Ru_GetDistance(nth(len-2 path) nth(len-1 path)) < 400.0) + (if debug >= 1 printf("WARN: RouteBuffers: Y coord of point#%d path points should be on even track but got %L or (%.2f,%.2f) in tracks\n" + cnt point xCoord(point)/TrackPitch yCoord(point)/TrackPitch)) + ) + (t + printf("ERROR: RouteBuffers: Y coord of point#%d path points must on even track but got %L or (%.2f,%.2f) in tracks\n" + cnt point xCoord(point)/TrackPitch yCoord(point)/TrackPitch) + hasErr = t + ) + ) + ) + (if mod(floor((xCoord(point)+TrackPitch/64)/TrackPitch) 2) == 1 then + printf("WARN: RouteBuffers: X coord of point#%d path points should be on even track but got %L or (%.2f,%.2f) in tracks\n" + cnt point xCoord(point)/TrackPitch yCoord(point)/TrackPitch) + ) + (if cnt > 1 && cnt < length(path)-2 then + (if !ru_AlignTo((xCoord(point)+TrackPitch/2) TrackPitch) then + printf("ERROR: RouteBuffers: X coord of point#%d path points should be aligned to middle of track but got %L or (%f,%f) in tracks\n" + cnt point xCoord(point)/TrackPitch yCoord(point)/TrackPitch) + hasErr = t + ) + (if !ru_AlignTo((yCoord(point)+TrackPitch/2) TrackPitch) then + printf("ERROR: RouteBuffers: Y coord of point#%d path points should be aligned to middle of track but got %L or (%f,%f) in tracks\n" + cnt point xCoord(point)/TrackPitch yCoord(point)/TrackPitch) + hasErr = t + ) + ) + nextPoint = nth(cnt+1 path) + (if nextPoint && ((almostEqual(xCoord(point) xCoord(nextPoint)) && almostEqual(yCoord(point) yCoord(nextPoint))) || + (!almostEqual(xCoord(point) xCoord(nextPoint)) && !almostEqual(yCoord(point) yCoord(nextPoint))) ) then + (if cnt == 1 || cnt == length(path)-3 then + printf("WARN: RouteBuffers: segment #%d is neither vertical or horizontal, could be okay for zero-length turn segment\n" cnt ) + else + printf("ERROR: RouteBuffers: segment #%d is neither vertical or horizontal\n" cnt ) + hasErr = t + ) + ) + cnt++ + ) + (if hasErr then + printf("Path: %L\n" ToTrack(path)) + error("There are errors above. Please check your path. Use ?checkPath option to disable if deemed okay\n") + ) + + ) + + numCols = length(bufferList) + (for colCnt 0 numCols-1 + (if colPathGuide then + (if stringp(nth(colCnt colPathGuide)) then + colPath = Ru_GetPathNode(path layerPatternList nth(colCnt colPathGuide) + ?firstPattern firstPattern ?lastPattern lastPattern) + else + pathOffset = nth(0 nth(colCnt colPathGuide)) + colPath = OffsetPath(path pathOffset pathOffset + ?firstOffset nth(1 nth(colCnt colPathGuide)) + ?lastOffset nth(2 nth(colCnt colPathGuide))) + (if flipSegPattern then + (foreach el flipSegPattern + /* + (if el == 0 && firstPattern then + error("Does not support flipping first segment when firstPattern is specified. Use ModifyChannel\n")) + (if el == length(colPath)-1 && lastPattern then + error("Does not support flipping last segment when lastPattern is specified. Use ModifyChannel\n")) + */ + (if ru_getSegDir(nth(el colPath) nth(el+1 colPath))=="VERT" then + x = -2*pathOffset + RoundUpTrack(busMaxOff) + y = 0 + else + x = 0 + y = -2*pathOffset + RoundUpTrack(busMaxOff) + ) + (if debug >= 1 printf("Flip column #%d segment #%d pattern by x=%f y=%f tracks\n" colCnt el x/TrackPitch y/TrackPitch)) + colPath = OffsetSomePoints(colPath el (el+1) x y) + ) + ) + ) + else colPath = path) + colPathList = append(colPathList list(colPath)) + ) + ;must rearrange path segment to avoid paths crossing each other +; (if numCols > 1 colPathList = Ru_FixPath(colPathList)) + +;FIXME not very accurate, need to fix logic to know when to turn + turnGapX = ru_getColParm(turnGap 0) + turnGapY = ru_getColParm(turnGap 1) + (if !turnGapX turnGapX = RoundUpTrack(4*TrackPitch + busMaxOff/2/numCols)) + (if !turnGapY turnGapY = RoundUpTrack(4*TrackPitch + busMaxOff/2/numCols)) + (if debug >= 1 printf("turnGapXY %.1f %.1f busMaxOffset %.1f\n" turnGapX/TrackPitch turnGapY/TrackPitch busMaxOff/TrackPitch)) + + (for colCnt 0 numCols-1 + colPath = nth(colCnt colPathList) + (if drawGuide && colPathGuide then dbCreatePath((geGetEditCellView) list("M4" "bus") colPath 0.8)) + bufSegNum = 0 + sramSegNum = 0 + segPropList = nil + bufPrefixName = "MBUF_GROUP" + (if numCols > 1 bufPrefixName = sprintf(nil "COL#%d MBUF_GROUP" colCnt)) + lastCellLoc = nth(0 colPath) + segPoints = ru_getNextSegment(lastCellLoc colPath ru_getColParm(startDist colCnt) guideX guideY sramCfg ru_getColParm(termDist colCnt)) + sramSegIndex = ru_getSramSegmentIndex(lastCellLoc segPoints sramCfg) + + (while segPoints && bufSegNum < 200 && sramSegNum < 200 + colBufDist = ru_getColParm(bufDist colCnt) + (if sramSegIndex >= 0 then nextCellLoc = nth(2 nth(sramSegIndex sramCfg)) + else nextCellLoc = nth((length(segPoints)-1) segPoints)) + + (if debug >= 2 printf("###### %s bufSegNum#%d points %L bufLoc %L sramSegNum %d sramSegIndex %L\n" + bufPrefixName bufSegNum segPoints nextCellLoc sramSegNum sramSegIndex)) + ; any exception + (if locException then + nextBufX = xCoord(nextCellLoc) + nextBufY = yCoord(nextCellLoc) + exception = nil + (if sramSegIndex < 0 exception = ru_getLocException(locException bufPrefixName bufSegNum colCnt)) + (if exception then + type = nth(2 exception) + (case type + ( type == "D" t) + ( type == "S" t ) + ( type == "F" + nextBufX = nth(3 exception) ; + nextBufY = nth(4 exception); + (if debug >= 1 printf("%s[%d] is FIXED to %f,%f\n" + bufPrefixName bufSegNum nextBufX nextBufY ) ) + ) + ( type == "OX" + offset = nth(3 exception) + nextBufX = nextBufX + offset ; + (if debug >= 1 printf("%s[%d]: OFFSET to %f,%f by %f in XCoord\n" + bufPrefixName bufSegNum nextBufX nextBufY offset) ) + ) + ( type == "OY" + offset = nth(3 exception) + nextBufY = nextBufY + offset ; + (if debug >= 1 printf("%s[%d]: OFFSET to %f,%f by %f in YCoord\n" + bufPrefixName bufSegNum nextBufX nextBufY offset) ) + ) + ( t printf("ERROR: Unknown exception type [%s]\n" type) + ) + ) + nextCellLoc = nextBufX:nextBufY + ;replace last segPoint + tempSegPoints = nil + (for cnt 0 (length(segPoints)-2) + tempSegPoints = append(tempSegPoints list(nth(cnt segPoints))) + ) + segPoints = append(tempSegPoints list(nextCellLoc)) + ) + ) + (if sramSegIndex >= 0 then + sramName = nth(0 nth(sramSegIndex sramCfg)) + ;replace last segPoint + tempSegPoints = nil + (for cnt 0 (length(segPoints)-2) + tempSegPoints = append(tempSegPoints list(nth(cnt segPoints))) + ) + segPoints = append(tempSegPoints list(nextCellLoc)) + + segProp = list(list(list("SRAM" sramName nextCellLoc sramSegIndex) segPoints)) + (if bufSegNum == 0 then segPropList = segProp + else segPropList = append(segPropList segProp) + ) + (if debug >= 1 printf("################# %s SRAM#%d Loc %L bufSeg %L\n" + sramName sramSegNum nextCellLoc segPoints)) + sramSegNum++ + else + bufName = sprintf(nil "%s[%d]" bufPrefixName (bufSegNum+bufSegOffset)) + segProp = list(list(list("BUF" bufName nextCellLoc (bufSegNum+bufSegOffset)) segPoints)) + (if bufSegNum == 0 then segPropList = segProp + else segPropList = append(segPropList segProp) + ) + (if debug >= 1 printf("################# BUF#%d %s Loc %L=(%.1f,%.1f) bufSeg %L\n" + bufSegNum bufName nextCellLoc xCoord(nextCellLoc)/TrackPitch yCoord(nextCellLoc)/TrackPitch segPoints)) + bufSegNum++ + ) + lastCellLoc = nextCellLoc + exception = nil + (if sramSegIndex < 0 exception = ru_getLocException(locException bufPrefixName bufSegNum colCnt)) + type = "" + (if exception then + type = nth(2 exception) + (case type + ( type == "D" + colBufDist = nth(3 exception) ; + (if debug >= 1 printf("%s[%d] distance from previous buffer is set to %f\n" + bufPrefixName bufSegNum colBufDist ) ) + ) + ( type == "S" + (if shiftDist error("%s[%d] Cannot have shift option consecutively. Last shiftDist %L New %L\n" + bufPrefixName bufSegNum shiftDist nth(3 exception)) + ) + shiftDist = nth(3 exception); + colBufDist = colBufDist + shiftDist + (if debug >= 0 printf("%s[%d] shift buffer back by %f, distance from previous buffer is now %f\n" + bufPrefixName bufSegNum shiftDist colBufDist ) ) + ) + ) + ) + ;previous buffer is shifted by shiftDist, adjust current buffer so it is at the same place + (if type != "S" && shiftDist then + colBufDist = colBufDist - shiftDist + shiftDist = nil + ) + segPoints = ru_getNextSegment(lastCellLoc colPath + colBufDist guideX guideY sramCfg ru_getColParm(termDist colCnt)) + sramSegIndex = ru_getSramSegmentIndex(lastCellLoc segPoints sramCfg) + ) + + result = ru_getPathSegment(lastCellLoc colPath) + segIdx = nth(0 result) + segPoints = nil + (for cnt segIdx+1 length(colPath)-1 + segPoints = append(segPoints list(nth(cnt colPath))) + ) + segProp = list(list(list("END" "" car(last(colPath)) (bufSegNum+bufSegOffset)) segPoints)) + segPropList = append(segPropList segProp) + (if debug >= 1 printf("################# ENDPATH Seg %L\n" + segPoints)) + + (if debug >= 1 printf("%s: segList: %L\n" bufPrefixName segPropList)) + + (if debug >= 1 printf("############################## Stacking Buffers ###############################\n")) + bufSegNum = 0 + (if colPathGuide then + (if stringp(nth(colCnt colPathGuide)) then + pathOffset = Ru_GetChannelNodeOffset(layerPatternList nth(colCnt colPathGuide) ?nestedArray nestedArray) + else + pathOffset = nth(0 nth(colCnt colPathGuide)) + ) + else pathOffset = 4*TrackPitch) + (foreach segProp segPropList + cellLocProp = nth(0 segProp) + cellType = nth(0 cellLocProp) + cellName = nth(1 cellLocProp) + cellLoc = Ru_AlignBufXY(nth(2 cellLocProp)) + index = nth(3 cellLocProp) + segPath = append(last(nth(1 nth(bufSegNum segPropList))) nth(1 nth(bufSegNum+1 segPropList))) + mbufList = nth(bufSegNum nth(colCnt bufferList)) + (if mbufList then + colList = mbufList + (if length(segPath) <= 1 error("Too many buffer segments for the given path. Either decrease number of buffer segment\n %s %L" + "or decrease bufDist option so all the buffers can fit along the given path.\n" segPath)) + (if debug >= 2 printf("%s[%d]: Loc %L for column#%d buffers: %L\n" + bufPrefixName bufSegNum cellLoc colCnt colList) ) +;FIXME +singleCol = balance + (if singleCol then + leftList = colList + rightList = nil + + else + leftList = nil + rightList = nil + (foreach bufName colList + nodeBaseName = Ru_GetNodeBaseNameFromBufName(bufName) + nodeName = sprintf(nil ".%s.e" nodeBaseName) + + (if rexMatchp("bufReset" bufName) || rexMatchp("rampReset" bufName) then + nodeOffset = TrackPitch/2 + else + ;The test below check between track, but node offset is in the middle of track + result = Ru_GetChannelNodeOffset(layerPatternList nodeName ?nestedArray nestedArray) + (if !result result = Ru_GetChannelNodeOffset(layerPatternList sprintf(nil ".%s.D.e" nodeBaseName) ?nestedArray nestedArray)) ;DFT + (if !result error("%s: Unable to find %L in %L\n" bufName nodeName layerPatternList)) + nodeOffset = result + TrackPitch/2 + ) + ;printf("%s: %s %s: pathOffset %L(%L) nodeOffset %L(%L) leftRightLimit %L(%L) %L(%L)\n" + ; bufName nodeBaseName nodeName + ; pathOffset pathOffset/TrackPitch nodeOffset nodeOffset/TrackPitch + ; (floor(pathOffset/TrackPitch)+2)*TrackPitch (floor(pathOffset/TrackPitch)+2) + ; (floor(Ru_AlignY(pathOffset)/TrackPitch)+2)*TrackPitch (floor(Ru_AlignY(pathOffset)/TrackPitch)+2)) + (if !nodeOffset error("%s: Node: %s pathOffset %L nodeOffset %L. Unable to find nodeOffset\n" + bufName nodeName pathOffset nodeOffset)) + + (if nodeOffset < (floor(Ru_AlignY(pathOffset)/TrackPitch)+2)*TrackPitch then + leftList = append(leftList list(bufName)) + else rightList = append(rightList list(bufName))) + ) + ) + (if debug >= 2 printf("LEFT COL#%d Seg#%d: %L\n" colCnt bufSegNum leftList)) + (if debug >= 2 printf("RIGHT COL#%d Seg#%d: %L\n" colCnt bufSegNum rightList)) + + bufAlignList = Ru_StackBuffer(segPath leftList rightList turnGapX turnGapY + ?flipSegPattern flipSegPattern ?bufferPath colPath + ?reserveGap reserveGap ?bufPrefix inlinePrefix + ?balance balance ?bufSegNum bufSegNum) + else + (if length(segPropList) < bufSegNum + printf("%s[%d]: WARN No buffer specified at %L. %L\n" bufPrefixName bufSegNum cellLoc segPropList)) + ) + bufSegNum++ + ) ;for segPropList + + (if outfp then + printf("%s: uses %d MBUFs\n" bufPrefixName bufSegNum) + (if bufSegOffset == 0 then fprintf(outfp "%s: uses %d MBUFs\n" bufPrefixName bufSegNum) + else fprintf(outfp "%s: uses %d MBUFs starting with %s\n" bufPrefixName bufSegNum + sprintf(nil "%s[%d]" bufPrefixName bufSegOffset))) + ) + ) ;for colCnt + return(segPropList) + ) +) ; + + +(defun Ru_RemoveLastEl (name delim) + (let (el ret cnt) + el = parseString(name delim) + ret = car(el) + (for cnt 1 length(el)-2 + ret = strcat(ret sprintf(nil "[%s]" nth(cnt el))) + ) + ret + ) +) + +;return the node base name given the buf instance name +(defun Ru_GetNodeBaseNameFromBufName (bufName) + (prog (nodeBaseName cnt el prefixEnd) +;FIXME + ;remove segment index + el = parseString(bufName "[]") + nodeBaseName = car(el) + (for cnt 1 length(el)-2 + nodeBaseName = strcat(nodeBaseName sprintf(nil "[%s]" nth(cnt el))) + ) + ;remove the mbuf prefix + prefixEnd = 1 + (while prefixEnd < strlen(nodeBaseName) && substring(nodeBaseName prefixEnd 1) != "_" prefixEnd++) + prefixEnd++ + ;printf("bufName %L nodeBaseName %L prefixEnd %L\n" bufName nodeBaseName prefixEnd) + (if prefixEnd > strlen(nodeBaseName) then return(nodeBaseName)) + nodeBaseName = substring(nodeBaseName prefixEnd strlen(nodeBaseName)) + ;printf("Ru_GetNodeBaseNameFromBufName %s %s\n" bufName nodeBaseName) + rexCompile( "_V$" ) + nodeBaseName = rexReplace( nodeBaseName ".V" 1) + rexCompile( "_D$" ) + nodeBaseName = rexReplace( nodeBaseName ".D" 1) + rexCompile( "_D\\[" ) + nodeBaseName = rexReplace( nodeBaseName ".D[" 1) + return(nodeBaseName) + ) +) + +(defun Ru_GetNodeBaseNameFromNodeName (nodeName) + (let (nodeBaseName) +;FIXME + nodeBaseName = substring(nodeName 2 strlen(nodeName)-3) + Ru_ReplaceDotWithDash(nodeBaseName) + ) +) + +(defun Ru_SplitNodeName (nodeName @key (delim "_")) + (let (nodeBaseName elName el) +;FIXME + el = parseString(nodeName ".") + ;printf("NodeName %L el %L %d\n" nodeName el length(el)) + (if length(el) == 3 && rexMatchp("^DFT" car(el)) && (cadr(el)=="D"||cadr(el)=="C") then ;FIXME hardcoded for DFT + elName = sprintf(nil "%s.%s" nth(1 el) nth(2 el)) + nodeBaseName = car(el) + else + elName = nth(length(el)-1 el) + nodeBaseName = car(el) + (for cnt 1 length(el)-2 + nodeBaseName = strcat(nodeBaseName sprintf(nil "%s%s" delim nth(cnt el))) + ) + ) + list(nodeBaseName elName) + ) +) + +;matched to the nodeList entry +(defun Ru_BaseNameMatched (subName name) + (prog (subResult result cnt idx range max min value entry) + subResult = parseString(subName ".[]_") + result = parseString(name ".[]_") + ;printf("Ru_BaseNameMatched: subName: %L name: %L\n" subResult result) + ;should match all the sub fields + (for cnt 0 length(subResult)-1 + (if nth(cnt subResult) == nth(0 result) then + matched = t + (for idx cnt+1 length(subResult)-1 + ;printf("subResult#%d:%L Result#%d: %L matched %L\n" (cnt+idx) nth((cnt+idx) subResult) idx nth(idx result) nth((cnt+idx) subResult) != nth(idx result)) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") + entry = nth((cnt+idx) subResult) + (if !entry return(nil)) ;does not match completely + (if matched && entry!=nth(idx result) then + range = parseString(entry "-") + (if length(range) == 2 then + min = Ru_StringToInt(car(range)) + max = Ru_StringToInt(cadr(range)) + value = Ru_StringToInt( nth(idx result)) + ;printf("Range %L min %L max %L value %L\n" range min max value) + (if value < min && value > max then + ;printf("Field #%d %L not matched %d %L\n" (cnt+idx) nth((cnt+idx) subResult) idx nth(idx result)) + matched = nil + else + value = 0 ;stub + ;printf("Field #%d %L is within range %d %L\n" (cnt+idx) nth((cnt+idx) subResult) idx nth(idx result)) + ) + + else + ;printf("Field #%d %L not matched %d %L\n" (cnt+idx) nth((cnt+idx) subResult) idx nth(idx result)) + matched = nil + ) + ) + ) + (if matched return(t)) + else + idx = 0 ;stub + ;printf("First Field #%d %L not matched %d %L\n" cnt nth(cnt subResult) 0 nth(cnt result)) + ;find next match if there is one + ) + ) + return(nil) + ) +) + +(defun Ru_GetChannelNodeOffset (channel node @key (nestedArray nil)) + (let (ch ret exactMatch nd nodeLen el + subNode subNodeE fieldList indexList fieldListE indexListE) +exactMatch = nil + nodeLen = strlen(node) + subNode = parseString(node (if nestedArray "._[]" "._")) + ;printf("GetChannelNodeOffset: node %L nestedArray %L channel %L \n" node nestedArray channel) + (foreach ch channel + (if !ret then + (cond + (nestedArray + nd = nth(0 ch) + subNodeE = parseString(nd "._[]") + indexList = nil + fieldList = nil + indexListE = nil + fieldListE = nil + (foreach el subNode + (if Ru_StringIsInt(el) then indexList = append(indexList list(el)) + else fieldList = append(fieldList list(el))) + ) + (foreach el subNodeE + (if Ru_StringIsInt(el) then indexListE = append(indexListE list(el)) + else fieldListE = append(fieldListE list(el))) + ) + ;printf("ENTRY %L %L %L indexList %L %L\n" nd subNodeE strlen(nd) indexListE fieldListE) + ;printf("NODE %L %L %L indexList %L %L\n" node subNode nodeLen indexList fieldList) + (if indexListE == indexList && fieldListE == fieldList then + ret = caddr(ch) + ;printf("FOUND1 subNode %L subNodeE: %L ret: %L %L\n" subNodeE subNode ret ch) + ) + ) + (!exactMatch + nd = nth(0 ch) + ;printf("entry %L node %L\n" nd node) + (if nodeLen == strlen(nd) then + ;since we replace . with _ for wire node name + subNodeE = parseString(nd "._") + (if subNodeE == subNode ret = caddr(ch)) + ;(if ret printf("FOUND1 subNode %L subNodeE: %L ret: %L %L\n" subNodeE subNode ret ch)) + ) + ) + (t + (if node == nth(0 ch) then + ret = caddr(ch) + ;(if ret printf("FOUND2 subNode %L subNodeE: %L ret: %L %L\n" subNodeE subNode ret ch)) + ) + ) + ) + ) + ) ;foreach + ret + ) +) + +(defun Ru_GetChannelEntry (channel node) + (let (ch ret) + (foreach ch channel + (if !ret && node == nth(0 ch) then + ret = ch + ) + ) + ret + ) +) + +(defun Ru_GetBusPatternEntry (busPattern name node) + (let (bp layerPattern ret) + (foreach bp busPattern + (if !ret && name == nth(0 bp) then + layerPattern = nth(1 bp) + ret = Ru_GetChannelEntry(layerPattern node) + ) + ) + ret + ) +) + +(defun Ru_CanUseDoubleVias (pattern nodeEntry) + (prog (minOff el nodeName) + ;printf("nodeEntry %L withinGrid %L off %L\n" nodeEntry ru_WithinGrid((nth(2 nodeEntry)-TrackPitch/2) TrackPitch 4*TrackPitch/24) Ru_TrackOffset(nth(2 nodeEntry))) + (if ru_WithinGrid((nth(2 nodeEntry)-TrackPitch/2) TrackPitch 4*TrackPitch/24) return(nil)) + minOff = 99999.0 + nodeName = nth(0 nodeEntry) + (foreach el pattern + (if abs(nth(2 nodeEntry)-nth(2 el)) < minOff && + nodeName != nth(0 el) && nth(3 nodeEntry) == nth(3 el) then + minOff = abs(nth(2 nodeEntry)-nth(2 el)) + (if minOff <= 2.5*wirePitch then + ;printf("%L Only use single vias minOff: %L\n" nodeName minOff) + return(nil) + ) + ) + ) + return(t) + ) +) + +(defun RouteNode (path nodeList layerPatternList + @key (prefix "") (bufPrefix "mbuf") (wirePrefix "w") (postFix "") + (firstPattern nil) (lastPattern nil) (inlinePrefix nil) + (flipSegPattern nil) (turnToStartPinLayer t) (turnToEndPinLayer t) + (segLException nil) (segRException nil) (enableProp nil) + (startViasLoc nil) (endViasLoc nil) (forceSingleVias nil) + (reserveStartPinGap t) (reserveEndPinGap t) + (skipTermToStartPin nil) (skipTermToEndPin nil) + (startSwitchPattern nil) (endSwitchPattern nil) + (replaceDotWithDash t) (ignoreGnd nil) + (filterList nil) (filterExcludeList nil) + (maxManDist 480.0) (maxManDistFirstSeg nil) (maxManDistLastSeg nil) + (debug 0) (debugStackVias nil) (h nil) ) + (if debug >= 1 printf("RouteNode path %L\n" path )) + (prog (wirePitch bp nodeName width layer termWire termWire filterNode bufInst lastBufInst numExtraBufs + wireName lastBufSegNum nodeBaseName nodeElName result el cnt idx minOff temp wireDir parseNode + x y flipSegX flipSegY maxEntry minEntry indexList fieldList entry routeNode + busMaxOff maxFirstOff maxLastOff termToStartPin termToEndPin skipFirstSeg skipLastSeg + DEFAULT_WIRE_PREFIX) + (if h then + printf("\n\n") + printf("Route wires to the buffers along a given path and channel pattern\n") + printf("Usage: RouteNode(path [maxBuffers,nodeList] layerPatternList [OPTION])\n") + printf(" ?h t - this help\n") + printf(" ?firstPattern - Pattern of first segment from input pin\n") + printf(" ?lastPattern - Pattern of last segment to output pin\n") + printf(" ?filterList - Only route nodes in this list. Uses regexp matching\n") + printf(" ?filterExcludeList - Only route nodes not in this list. Uses regexp matching\n") + printf(" ?maxManDist - Warn if wire segment is above this value\n") + printf(" ?maxManDistFirstSeg - Warn if first wire segment is above this value. Default is 80 percent of maxManDist\n") + printf(" ?maxManDistLastSeg - Warn if last wire segment is above this value. Default is 80 percent of maxManDist\n") + printf(" ?flipSegPattern - Specify a list of segments to flip bus pattern\n") + printf(" ?turnToStartPinLayer - Specify whether first segment to turn to pin layer\n") + printf(" ?turnToEndPinLayer - Specify whether last segment to turn to pin layer\n") + printf(" ?doubleVias - Specify if channel turn vias are single or double\n") + printf(" ?startViasLoc - Specify vias X or Y location for channel to escape to start pin\n") + printf(" ?endViasLoc - Specify vias X or Y location for channel to escape to end pin\n") + printf(" ?skipTermToStartPin - Specify whether to terminate to start pins or let routing connecting them\n") + printf(" ?skipTermToEndPin - Specify whether to terminate to end pins or let routing connecting them\n") + printf(" ?ignoreGnd - Specify whether to route GND wires. Default is nil\n") + printf(" ?replaceDotWithDash - Specify whether to replace dot separator with dash. Default is true\n") + printf(" ?debugStackVias - Used to check if a wire crossing stacked vias\n") + + return(t) + ) + ;can't have "mbuf_" due to wireDir + DEFAULT_WIRE_PREFIX = "w" + (if bufPrefix == "mbuf" && prefix != "" bufPrefix = sprintf(nil "mbuf%s" prefix)) + (if wirePrefix == DEFAULT_WIRE_PREFIX && prefix != "" wirePrefix = sprintf(nil "w%s" prefix)) +;printf("PREFIX: %L %L %L\n" bufPrefix wirePrefix prefix) + wirePitch = TrackPitch/24 + numExtraBufs = 0 +; (if wirePrefix != "w_" && nodeList error("Not support wirePrefix of %L\n" wirePrefix)) ;due to wireDir + wirePitch = TrackPitch/24 + (if flipSegPattern then + busMaxOff = -9999.99 + (foreach el layerPatternList + (if busMaxOff < nth(2 el) busMaxOff = nth(2 el)) + ) + (foreach el flipSegPattern + (if el == 0 && firstPattern then + error("Does not support flipping first segment when firstPattern is specified. Use ModifyChannel instead\n")) + (if el == length(path)-1 && lastPattern then + error("Does not support flipping last segment when lastPattern is specified. Use ModifyChannel instead\n")) + (if Ru_GetDistance(nth(el path) nth(el+1 path)) == 0.0 then ;zero length then use next next segment + (if ru_getSegDir(nth(el+1 path) nth(el+2 path))!="VERT" then + flipSegX = append(flipSegX list(el)) + ;shift the segment + path = OffsetSomePoints(path el (el+1) RoundDownTrack(busMaxOff) 0) + else + flipSegY = append(flipSegY list(el)) + path = OffsetSomePoints(path el (el+1) 0 RoundDownTrack(busMaxOff)) + ) + else + (if ru_getSegDir(nth(el path) nth(el+1 path))=="VERT" then + flipSegX = append(flipSegX list(el)) + ;shift the segment + path = OffsetSomePoints(path el (el+1) RoundDownTrack(busMaxOff) 0) + else + flipSegY = append(flipSegY list(el)) + path = OffsetSomePoints(path el (el+1) 0 RoundDownTrack(busMaxOff)) + ) + ) + (if debug >= 0 printf("Flip segment #%d pattern. busMaxOff %f flipSegX %L flipSegY %L\n" el busMaxOff/TrackPitch flipSegX flipSegY)) + ) + ) + + ;check to see if we can use double vias + firstSegViasTable = makeTable("firstSegViasTable" 0) + lastSegViasTable = makeTable("lastSegViasTable" 0) + busViasTable = makeTable("busViasTable" 0) + maxFirstOff = -9999.99 + (foreach bp firstPattern + (if maxFirstOff < nth(2 bp) maxFirstOff = nth(2 bp)) + nodeName = nth(0 bp) + firstSegViasTable[nodeName] = (if forceSingleVias nil Ru_CanUseDoubleVias(firstPattern bp)) + ) + maxLastOff = -9999.99 + (foreach bp lastPattern + (if maxLastOff < nth(2 bp) maxLastOff = nth(2 bp)) + nodeName = nth(0 bp) + lastSegViasTable[nodeName] = (if forceSingleVias nil Ru_CanUseDoubleVias(lastPattern bp)) + ) + busMaxOff = -9999.99 + (foreach bp layerPatternList + (if busMaxOff < nth(2 bp) busMaxOff = nth(2 bp)) + nodeName = nth(0 bp) + busViasTable[nodeName] = (if forceSingleVias nil Ru_CanUseDoubleVias(layerPatternList bp)) + ) + + +(if firstPattern && startSwitchPattern==t then +segOff = 0.0 +segNegDir = nil; going from max to min instead from min to max + (if ru_getSegDir(nth(0 path) nth(1 path))=="VERT" then + segOff = xCoord(nth(0 path)) - xCoord(nth(2 path)) + (if yCoord(nth(2 path)) > yCoord(nth(0 path)) segNegDir = t ) + else + segOff = yCoord(nth(0 path)) - yCoord(nth(2 path)) + (if xCoord(nth(2 path)) > xCoord(nth(0 path)) segNegDir = t ) + ) + startSwitchPattern = GenerateSwitchPattern(layerPatternList firstPattern segOff segNegDir ?debug debug) +) +(if lastPattern && endSwitchPattern==t then +segOff = 0.0 +segNegDir = nil; going from max to min instead from min to max +pathLen = length(path) + (if ru_getSegDir(nth(pathLen-1 path) nth(pathLen-2 path))=="VERT" then + segOff = xCoord(nth(pathLen-3 path)) - xCoord(nth(pathLen-1 path)) + (if yCoord(nth(pathLen-3 path)) > yCoord(nth(pathLen-1 path)) segNegDir = t ) + else + segOff = yCoord(nth(pathLen-1 path)) - yCoord(nth(pathLen-3 path)) + (if xCoord(nth(pathLen-3 path)) > xCoord(nth(pathLen-1 path)) segNegDir = t ) + ) + endSwitchPattern = GenerateSwitchPattern(layerPatternList lastPattern segOff segNegDir ?debug debug) +) + + (foreach bp layerPatternList + nodeName = nth(0 bp) + width = nth(1 bp) + nodeOff = nth(2 bp) + layer = nth(3 bp) + termWire = t + (if filterList then + filterNode = ru_GetFilterList(filterList nodeName) + (if debug >= 2 then + (if filterNode then printf("%s Found in filter list: %L\n" nodeName filterNode) + else printf("%s Not Found in filter list %L\n" nodeName filterList)) + ) + termWire = (filterNode!=nil) + ) + (if filterExcludeList then + filterNode = ru_GetFilterList(filterExcludeList nodeName) + (if debug >= 4 && filterNode printf("%L Found in filter exclude list: %L\n" nodeName filterNode)) + (if debug >= 4 && !filterNode printf("%L Not Found in filter exclude list\n" nodeName)) + termWire = !(filterNode!=nil) + ) + +; hasBuffer gndPath gndLayer start end gridLoc viasLoc cuts segDir + hasBuffer = t + (if termWire && nodeName == "GND" then + (if !ignoreGnd then + nodePath = OffsetPath(path nodeOff nodeOff) + (foreach cnt flipSegPattern + segDir = ru_getSegDir(nth(cnt nodePath) nth(cnt+1 nodePath)) + ;path has been offset once, so need to do 2 times here + nodePath = OffsetSomePoints(nodePath cnt cnt+1 + (if segDir == "HOR" 0 -2*nodeOff) + (if segDir == "HOR" -2*nodeOff 0)) + ) + gndPath = nil + start = (if firstPattern 1 0) + end = length(nodePath)-1 + (if lastPattern end = end - 1) + (for cnt start end + (cond ;offset 1 track to prevent overlap to pins + (cnt == 0 + segDir = ru_getSegDir(nth(cnt nodePath) nth(cnt+1 nodePath) ?detail t) + (cond + (segDir == "RIGHT" offX = TrackPitch offY = 0) + (segDir == "LEFT" offX = -TrackPitch offY = 0) + (segDir == "UP" offX = 0 offY = TrackPitch) + (segDir == "DOWN" offX = 0 offY = -TrackPitch) + ) + gndPath = append(gndPath list(OffsetPoint(nth(cnt nodePath) offX offY))) + ) + (cnt == length(nodePath)-1 + segDir = ru_getSegDir(nth(cnt-1 nodePath) nth(cnt nodePath) ?detail t) + (cond + (segDir == "RIGHT" offX = -TrackPitch offY = 0) + (segDir == "LEFT" offX = TrackPitch offY = 0) + (segDir == "UP" offX = 0 offY = -TrackPitch) + (segDir == "DOWN" offX = 0 offY = TrackPitch) + ) + gndPath = append(gndPath list(OffsetPoint(nth(cnt nodePath) offX offY))) + ) + (t gndPath = append(gndPath list(nth(cnt nodePath)))) + ) + ) + (DrawWire layer nodeName width gndPath ?doubleVias nil) + ;draw the vias in the middle of each segment + (for cnt 0 length(gndPath)-2 + pA = nth(cnt gndPath) + pB = nth(cnt+1 gndPath) + (if Ru_GetDistance(pA pB) > 8*TrackPitch then + segDir = ru_getSegDir(pA pB) + gndLayer = nth(2 layer) + (if segDir == "HOR" then + viasLoc = RoundDownTrack((xCoord(pA)+xCoord(pB))/2 ?numTrack 2):yCoord(pA) + (if gndLayer == "M3_M2" then gndLayer = "M4_M3") + cuts = "_2CUT_H" + else + viasLoc = xCoord(pA):RoundDownTrack((yCoord(pA)+yCoord(pB))/2 ?numTrack 2) + cuts = "_2CUT_V" + ) + DrawVia("GND" gndLayer viasLoc width cuts ?doubleVias t) + ) + ) + ) ;ignoreGnd + termWire = nil + ) + + (if termWire then + nodePath = Ru_GetPathNode(path layerPatternList nodeName + ?firstPattern firstPattern ?lastPattern lastPattern + ?firstSwitchPattern startSwitchPattern + ?lastSwitchPattern endSwitchPattern + ?flipSegX flipSegX ?flipSegY flipSegY) + ;(DrawWire BusMetal67 nodeName wirePitch nodePath) + result = Ru_SplitNodeName(nodeName ?delim (if replaceDotWithDash "_" ".")) + nodeBaseName = car(result) + nodeElName = cadr(result) + (cond + (nodeList == nil || nodeName == "GND" + hasBuffer = nil + minBufSeg = 0 + maxBufSeg = 0 + ) + (integerp(nodeList) then + ;simple range from 0 to max value + minBufSeg = 0 + maxBufSeg = nodeList + ) + (t + minBufSeg = nil + (foreach el nodeList + (if !minBufSeg then ;don't know how to break out + ;printf("ROUTE: nodeName %L nodeBaseName %L nodeElName %L \n" car(el) nodeBaseName el) + temp = car(el) ;FIXME find a better way + (if substring(temp 1 1) == "-" || + substring(temp 1 1) == "+" then ;remove direction flag + temp = substring(temp 2 strlen(temp)-1) + ) + ;printf("##### NodeListEntry: %L nodeName: %L matched: %L\n" temp nodeBaseName Ru_BaseNameMatched(temp nodeBaseName)) + (if Ru_BaseNameMatched(temp nodeBaseName) then + minEntry = nil + parseNode = parseString(car(el) "[]") + (if length(parseNode) == 3 then + result = parseString(nth(1 parseNode) "-") + minEntry = Ru_StringToInt(car(result)) + maxEntry = Ru_StringToInt(cadr(result)) + idx = Ru_StringToInt(cadr(parseString(nodeBaseName "[]"))) + else + (if nth(1 el) then + result = parseString(nth(1 el) ".") + minEntry = Ru_StringToInt(car(result)) + maxEntry = Ru_StringToInt(cadr(result)) + idx = Ru_StringToInt(car(last(parseString(nodeBaseName "[]")))) + ) + ) + ;printf("nodeBaseName: %L parse: %L parseNode %L idx %L min %L max %L NodeList entry %L %L\n" nodeBaseName parseString(nodeBaseName "[]") parseNode idx minEntry maxEntry el result) + (if !minEntry || !idx || (idx >= minEntry && idx <= maxEntry) then + (if !nth(3 el) then ;no buffer for this entry + hasBuffer = nil + minBufSeg = 0 + maxBufSeg = 0 + else + result = parseString(nth(3 el) ".") + minBufSeg = Ru_StringToInt(car(result)) + maxBufSeg = Ru_StringToInt(cadr(result))+1 + (if debug >= 1 printf("%s minBufSeg %d maxBufSeg %d matched to nodeList entry %L\n" nodeBaseName minBufSeg maxBufSeg el)) + (if length(parseNode) == 3 then + result = parseString(nodeBaseName "[]") + (if debug >= 1 printf("%s has embedded array %L parseNode %L\n" nodeBaseName result parseNode )) + indexList = nil + fieldList = nil + (foreach temp result + (if Ru_StringIsInt(temp) then indexList = append(indexList list(temp)) + else fieldList = append(fieldList list(temp))) + ) + result = "" + (foreach entry fieldList + result = strcat(result entry) + ) + (foreach entry indexList + result = strcat(result sprintf(nil "[%s]" entry)) + ) + (if debug >= 1 printf("%s is changed to %s. fieldList %L indexList %L" nodeBaseName result fieldList indexList)) + nodeBaseName = result + ) + ) ;if !nth(3 el) + ) + ) + ) + ) + ) + ) ;cond + +(if !minBufSeg error("Unable to match node name %L in nodeList %L\n" nodeName nodeList)) + + bufSegNum = minBufSeg-1 + lastBufSeg = nil + lastBufInst = nil + wireDir = "" + (while bufSegNum < maxBufSeg + lastBufInst = bufInst + ;find next buffer + bufInst = nil + lastBufSegNum = bufSegNum + (while hasBuffer && !bufInst && bufSegNum < maxBufSeg + bufSegNum++ + bufName = sprintf(nil "%s%s_%s[%d]" + (if inlinePrefix inlinePrefix "") + bufPrefix nodeBaseName bufSegNum) + bufInst = (dbFindAnyInstByName (geGetEditCellView) bufName) + (if !bufInst then ;FIXME find a better way? + temp = sprintf(nil "%s%sr_%s[%d]" + (if inlinePrefix inlinePrefix "") + bufPrefix nodeBaseName bufSegNum) +;printf("%s: Trying to find if the buffer is reverse direction\n" temp) + bufInst = (dbFindAnyInstByName (geGetEditCellView) temp) + (if bufInst then wireDir = "r" bufName = temp) + ) + ) + (if bufInst && bufSegNum == maxBufSeg then + ;printf("WARN: RouteNode: max buffer index is %d but found a buffer %s. %s\n" maxBufSeg-1 bufName nodeElName) + bufInst = nil + (if rexMatchp("e$" nodeElName) numExtraBufs++) + ) + (cond + (!hasBuffer + (if nodeBaseName == "GND" then + wireName = "GND" + else + wireName = sprintf(nil "%s%s%s%s%s.%s" (if inlinePrefix inlinePrefix "") wirePrefix + (if substring(nodeName 1 1)=="." "." "") nodeBaseName postFix nodeElName) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") +;printf("%L: inlinePrefix %L wirePrefix %L nodeBaseName %L nodeName %L postFix %L %L\n" wireName inlinePrefix wirePrefix nodeBaseName nodeName postFix nodeElName) + ) + bufSegNum = maxBufSeg + bufName = "NO_BUF" + ) + (bufInst + wireName = sprintf(nil "%s%s%s_%s[%d].%s" (if inlinePrefix inlinePrefix "") wirePrefix wireDir nodeBaseName bufSegNum nodeElName) + ) + (t + wireName = sprintf(nil "%s%s%s_%s[%d].%s" (if inlinePrefix inlinePrefix "") wirePrefix wireDir nodeBaseName lastBufSegNum+1 nodeElName) + ) + ) +;printf("#### %L: %L maxBufSeg %L nodeList %L\n" bufName bufSegNum maxBufSeg nodeList) + (if debug >= 1 printf("RouteNode: %s: wireName %s: nodeName %s nodeBaseName %s bufSegNum %d layer %L nodePath %L\n" + bufName wireName nodeName nodeBaseName bufSegNum layer nodePath)) + + (if !lastBufInst && !bufInst && hasBuffer + error("Ru_TerminateNode: %s There is no buffer %s found along the path. nodeName %L nodeBaseName %L nodeElName %L\n" + wireName bufName nodeName nodeBaseName nodeElName) + ) + + (if bufInst temp = Ru_LocatePathSeg(nodePath bufInst->xy 0)) + (if bufInst && !nth(temp nodePath) then + temp = car(last(nodePath)) + x = xCoord(bufInst->xy)-xCoord(temp) + y = yCoord(bufInst->xy)-yCoord(temp) + printf("ERROR: %s position %L (DIFF: %L:%L) is not located along the path %L\n" bufInst->name bufInst->xy x y nodePath) + bufSegNum = maxBufSeg ; done + bufInst = nil + else + routeNode = t + termToStartPin = t + termToEndPin = t + skipFirstSeg = nil + skipLastSeg = nil + (if skipTermToStartPin then + (if listp(skipTermToStartPin) then + filterNode = ru_GetFilterList(skipTermToStartPin nodeName) + (if filterNode then + (if cadr(filterNode) then skipFirstSeg = t + else termToStartPin = nil) + ) + else termToStartPin = nil) + (if !termToStartPin && debug >=1 printf("%L: Skip terminate to start pin\n" wireName)) + ) + (if skipTermToEndPin then + (if listp(skipTermToEndPin) then + filterNode = ru_GetFilterList(skipTermToEndPin nodeName) + (if filterNode then + (if cadr(filterNode) then skipLastSeg = t + else termToEndPin = nil) + ) + else termToEndPin = nil) + (if !termToEndPin && debug >=1 printf("%L: Skip terminate to end pin\n" wireName)) + ) + (if termToStartPin==nil && lastBufInst==nil routeNode = nil) ;first segment + + (if termToEndPin==nil && lastBufInst!=nil && bufInst== nil routeNode = nil) ;last segment + + (if routeNode then + temp = substring(nodeElName 1 2) + Ru_TerminateNode(nodeName wireName lastBufInst bufInst nodePath layer path + ?firstPattern firstPattern ?lastPattern lastPattern + ?skipFirstSeg skipFirstSeg ?skipLastSeg skipLastSeg + ?firstDoubleVias firstSegViasTable[nodeName] + ?lastDoubleVias lastSegViasTable[nodeName] + ?doubleVias busViasTable[nodeName] + ?maxManDist maxManDist + ?startViasLoc startViasLoc ?endViasLoc endViasLoc + ?reserveStartPinGap reserveStartPinGap ?reserveEndPinGap reserveEndPinGap + ?segLException segLException ?segRException segRException + ?backwardDir (wireDir=="r") + ?flipSegPattern flipSegPattern + ?termPin (temp!="C.") ?enableProp enableProp + ?turnToStartPinLayer turnToStartPinLayer ?turnToEndPinLayer turnToEndPinLayer + ?maxManDistFirstSeg maxManDistFirstSeg ?maxManDistLastSeg maxManDistLastSeg + ?debugStackVias debugStackVias ?debug debug) + else + (if debug >= 1 printf("%L: %L: %L: Skipping bufSegNum %d\n" bufName wireName nodeName bufSegNum)) + ) + ) + ) + ) ;termWire + ) ;foreach + ;count is per node, so estimate number of buffers + (if numExtraBufs > 0 then printf("There are at least %d unused mbufs\n" numExtraBufs)) + ) + t +) + +(defun Ru_TerminateNodeR (nodeName wireName bufInst layer bufSegDir bufSegX bufSegY + @key (debug 0) (doubleVias t) (termPin t) (backwardDir nil) + (bufSegNum nil) (flipSegPattern nil) (segRException nil) (enableProp nil) + (debugStackVias nil)) + (let (bufLoc pinROff pinRLoc reSegOff layerList X Y reSeg dblVias flipX flipY pinExt pinExtLayer cuts + fromLayer toLayer viasList reLayer rsLayer turnLayer startPoint nodeOff turnSeg segDist + prop propValue) + + (if !nodeName || !stringp(nodeName) error("Ru_TerminateNodeR: Invalid nodeName %L\n" nodeName)) + (if !wireName || !stringp(wireName) error("Ru_TerminateNodeR: Invalid wireName %L\n" wireName)) + (if !listp(layer) || length(layer) <= 1 error("Ru_TerminateNodeR: Invalid layer %L\n" layer)) + + (if debug >= 3 printf("Ru_TerminateNodeR: wireName %L layer %L dir %L bufSegX %L bufSegY %L\n" + wireName layer bufSegDir bufSegX bufSegY)) + nodeOff = 0.0 ; path is already the node path + bufLoc = bufInst->xy + flipX = (bufInst->orient == "MX" || bufInst->orient == "R180") + flipY = (bufInst->orient == "MY" || bufInst->orient == "R180") + (if backwardDir then + pinROff = Ru_getPinLLoc(bufInst->master->cellName nodeName bufInst->orient) + else + pinROff = Ru_getPinRLoc(bufInst->master->cellName nodeName bufInst->orient) + ) + pinRLoc = Ru_OffsetBox(pinROff bufLoc) + (if debug >= 1 printf("Ru_TerminateNodeR: %s bufSegDir %s backwardDir %L PINR off %L pinLLoc %L\n" + wireName bufSegDir backwardDir pinROff pinRLoc)) + reSegOff = 0.0 + layerList = nil + dblVias = t + pinExt = nil + pinExtLayer = 3 + segDist = 0.0 +turnSeg = t + (if bufSegDir == "HOR" then + X = bufSegX + ru_getTurnOffset(bufLoc bufInst->master->cellName nodeName (backwardDir==t) flipY bufInst) + Y = bufSegY + fromLayer = ru_layerToValue(nth(0 nth(0 layer))) + toLayer = (if fromLayer == 3 4 (fromLayer-1)) + (if toLayer == 4 then + reSeg = list( Ru_OffsetPoint(X:Y 0.0:nodeOff) X:Ru_MidY(pinRLoc)) + else + startPoint = Ru_OffsetPoint(X:Y nodeOff:0.0) +pinSwitchOff = wirePitch*4 +(if member(bufSegNum flipSegPattern) pinSwitchOff = -pinSwitchOff) +(if rexMatchp("1of1" bufInst->master->cellName) then + (if (GetProp bufInst "Position" "")=="TOP" pinSwitchOff = (2*TrackPitch-pinSwitchOff)) +else + (if yCoord(startPoint) > (yCoord(bufLoc)+2*TrackPitch) then + (if member(bufSegNum flipSegPattern) then + pinSwitchOff = pinSwitchOff;FIXME + else pinSwitchOff = (4*TrackPitch-pinSwitchOff)) + + ) +) + reSeg = list( startPoint X:(yCoord(bufLoc)+pinSwitchOff)) +; (if flipX -1 1)*(if yCoord(startPoint) > (yCoord(bufLoc)+2*TrackPitch) && +; !rexMatchp("1of1" bufInst->master->cellName) (4*TrackPitch-pinSwitchOff) pinSwitchOff)) ) + pinExt = list(car(last(reSeg)) X:Ru_MidY(pinRLoc)) + pinExtLayer = 4 + (if Ru_PathDistance(pinExt) < TrackPitch/24/4 pinExt = nil) ; already on top of pin + ) + + startPoint = car(reSeg) + dblVias = (if ru_WithinGrid(xCoord(car(reSeg)) TrackPitch 4*TrackPitch/24) nil t) + dist = Ru_GetDistance(nth(0 reSeg) nth(1 reSeg)) + (if dist < TrackPitch/24/4 then + reSeg = nil ; no need to turn, on top on pin + turnSeg = nil + ) + viasList = GenViasList(fromLayer toLayer) + layerList = ru_GenLayerList(toLayer pinExtLayer) ; going to multiple layers + viasList = GenViasList(toLayer 3) + reLayer = sprintf(nil "M%d" toLayer) + else + X = bufSegX + fromLayer = ru_layerToValue(nth(0 nth(1 layer))) + toLayer = (if fromLayer == 2 3 5) + viasList = GenViasList(fromLayer toLayer) + + Y = Ru_MidY(pinRLoc) + reSeg = nil + segExcep = ru_GetSegException(segRException wireName) + (if enableProp then + (if !segExcep then + ;special case for SchedToIngress to prevent bus overlap + prop = (GetProp bufInst "OffsetNodeMatch" "") + ;printf("%s: OffsetNodeMatch %L by %L\n" wireName prop propValue->value) + (if prop && prop!="" && rexMatchp(prop wireName) then + propValue = (dbFindProp bufInst "OffsetNodeValue") + segExcep = list(nil (if propValue->value propValue->value 0)*wirePitch) + ;printf("%s: OffsetNode by %L\n" wireName propValue->value) + termPin = nil + ) + ) + prop = (GetProp bufInst "SingleViasMatch" "") + (if prop && prop!="" && rexMatchp(prop wireName) then + propValue = (dbFindProp bufInst "SingleViasValue") + dblVias = (if propValue->value=="TRUE" nil t) +;printf("%s: R SingleVias %L\n" wireName propValue->value) + ) + ) +; (if !segExcep && !(GetProp bufInst "LeftRightAlign" t) then +; segExcep = list(nil TrackPitch) +; termPin = nil +; ) + (if segExcep then + reSegOff = nth(1 segExcep) + (if debug >= 1 printf("%s R horizontal segment X %f Y %f is offset by %L\n" wireName X Y reSegOff)) + Y = Y + reSegOff + termPin = nil + ) + startPoint = Ru_OffsetPoint(X:Y nodeOff:0.0) + (if nil && Ru_IsBetween(xCoord(lowerLeft(pinRLoc)) (X+nodeOff) xCoord(upperRight(pinRLoc))) then + reSeg = nil ; no need to turn + turnSeg = nil + else + (if toLayer == 3 then + reSeg = list( Ru_OffsetPoint(X:Y nodeOff:0.0) Ru_MidX(pinRLoc):Y) + else +pinSwitchOff = wirePitch*4 + reSeg = list( Ru_OffsetPoint(X:Y nodeOff:0.0) (RoundDownTrack(xCoord(bufLoc))+(if flipY -pinSwitchOff pinSwitchOff)):Y) + pinExt = list(car(last(reSeg)) Ru_MidX(pinRLoc):Y) + (if Ru_PathDistance(pinExt) < TrackPitch/2 pinExt = nil) ; already on top of pin + ) + ) + dblVias = (if ru_WithinGrid(yCoord(car(reSeg)) TrackPitch 4*TrackPitch/24) nil dblVias) + layerList = ru_GenLayerList(toLayer pinExtLayer) ; going to multiple layers + viasList = GenViasList(toLayer 3) + reLayer = sprintf(nil "M%d" toLayer) + ) + (if debug >= 1 printf("R_END %s startPoint %L layer %L dblVias %L bufSegDir %s\n" + wireName startPoint layer dblVias bufSegDir)) + (if debug >= 1 printf("R_END: %s segment %L to buffer going from layer %d to %d. reLayer %L\n" + wireName reSeg fromLayer toLayer reLayer)) + ;can use double vias + turnLayer = GenViasList(fromLayer toLayer) + (if dblVias then DrawVia(wireName turnLayer startPoint wirePitch + (if bufSegDir == "HOR" "_2CUT_H" "_2CUT_V")) + else DrawVia(wireName turnLayer startPoint wirePitch "" ?doubleVias nil)) + (if reSeg && Ru_PathDistance(reSeg) > TrackPitch/64 then + Ru_ValidatePath(reSeg sprintf(nil "%s R_END" wireName)) + segDist = segDist + Ru_PathDistance(reSeg) + (DrawSegment wireName reLayer wirePitch nth(0 reSeg) nth(1 reSeg) t t nil) + ) + (if termPin && pinExt then + Ru_ValidatePath(pinExt sprintf(nil "%s R_PINEXT" wireName)) + (DrawSegment wireName sprintf(nil "M%d" pinExtLayer) wirePitch nth(0 pinExt) nth(1 pinExt) t t nil) + segDist = segDist + Ru_PathDistance(pinExt) + (if pinExtLayer != 3 then ;HOR connection + cuts = (if dblVias "_2CUT_H" "") + (if !dblVias then dblVias = t cuts = "_2CUT_V") + DrawVia(wireName GenViasList(pinExtLayer 3) car(last(pinExt)) + wirePitch cuts ?doubleVias dblVias) + ) + ) + + (if termPin && toLayer!=3 + (if pinExtLayer != 3 then ;HOR connection + (if toLayer != 6 error("R_END: %s Unexpected toLayer %L with pinExtLayer %L\n" wireName toLayer pinExtLayer)) + cuts = "_2CUT_V" + DrawVia(wireName GenViasList(toLayer pinExtLayer) car(pinExt) + wirePitch cuts ?doubleVias t) + else + cuts = (if dblVias "_2CUT_H" "") + (if !dblVias && bufSegDir == "HOR" then cuts = "_2CUT_V") + dblVias = t + DrawVia(wireName viasList (if reSeg car(last(reSeg)) startPoint) + wirePitch cuts ?doubleVias dblVias) + ) + ) + ;debug stacked vias + (if debugStackVias && layerList then + (if cuts == "_2CUT_H" then X = 2*wirePitch Y = 0.0 else X = 0.0 Y = 2*wirePitch) + (if turnSeg then + reSeg = list(Ru_OffsetPoint(car(last(reSeg)) -X:-Y) Ru_OffsetPoint(car(last(reSeg)) X:Y)) + else reSeg = list(Ru_OffsetPoint(startPoint -X:-Y) Ru_OffsetPoint(startPoint X:Y))) + (if debug >= 2 printf("VIAS R SEG %s seg %L layer %L\n" wireName reSeg layerList)) + (foreach layer layerList + (DrawWire layer wireName wirePitch reSeg) + ) + ) + list(startPoint toLayer segDist) + ) +) + +(defun Ru_TerminateNode (nodeName wireName startBufInst endBufInst nodePath layer busPath + @key (firstPattern nil) (lastPattern nil) + (firstDoubleVias nil) (lastDoubleVias nil) + (skipFirstSeg nil) (skipLastSeg nil) + (segLException nil) (segRException nil) + (doubleVias t) (maxManDist 500.0) + (maxManDistFirstSeg nil) (maxManDistLastSeg nil) + (startViasLoc nil) (endViasLoc nil) + (reserveStartPinGap t) (reserveEndPinGap t) + (turnToStartPinLayer t) + (turnToEndPinLayer t) + (flipSegPattern nil) + (backwardDir nil) (termPin t) (enableProp nil) + (debugStackVias nil) (debug 0)) + (prog (bufLoc flipX flipY nodeSeg bufSegX bufSegY bufSegNum startSegNum cuts maxWarnDist viasLoc + result bufSegDir segNum leSegOff layerList X Y lsSeg leSeg dblVias turnSeg segDist + fromLayer toLayer viasList lsLayer leLayer turnLayer segExcep leSegOff beginExt pinExt pinExtLayer + startPoint endPoint rStartLayer pathLen segDir startNode startLayer endNode endLayer segLayer noBuffer + ll ur ) + + (if !wireName || !stringp(wireName) error("Ru_TerminateNode: Invalid wireName %L\n" wireName)) + (if !nodeName || !stringp(nodeName) error("Ru_TerminateNode: Invalid nodeName %L\n" nodeName)) + (if !listp(nodePath) || length(nodePath) <= 1 error("Ru_TerminateNode: Invalid nodePath %L\n" nodePath)) + (if !listp(layer) || length(layer) <= 1 error("Ru_TerminateNode: Invalid layer %L\n" layer)) + +rexMagic(t) + startPoint = nil + endPoint = nil + turnSeg = t ; need to turn to the buffer + noBuffer = nil + segDist = 0.0 + (if startBufInst && !dbIsId(startBufInst) + error("Ru_TerminateNode: %s Invalid startBufInst %L parameter.\n" wireName startBufInst)) + (if endBufInst && !dbIsId(endBufInst) + error("Ru_TerminateNode: %s Invalid endBufInst %L parameter.\n" wireName endBufInst)) + (if !endBufInst && !startBufInst then + ;error("Ru_TerminateNode: %s Both startBufInst %L endBufInst %L are nil.\n" wireName startBufInst endBufInst)) + noBuffer = t + ) +;debug = 3 + (if debug >= 3 printf("Ru_TerminateNode: node %L wire %L startInst %L endInst %L path %L layer %L\n" + nodeName wireName startBufInst endBufInst nodePath layer)) + ;find location of the buffer along the nodePath + (if !startBufInst then ;start path + (if firstPattern then + leSeg = list(car(nodePath) cadr(nodePath)) + bufSegDir = ru_getSegDir(car(nodePath) cadr(nodePath)) + startNode = Ru_GetChannelEntry(firstPattern nodeName) + (if !startNode error("Unable to find %L in firstPattern %L\n" nodeName firstPattern)) + startLayer = nth(3 startNode) + (if !startLayer error("%L in firstPattern must have BusMetal specified\n" startNode)) + (if bufSegDir == "VERT" then + fromLayer = ru_layerToValue(nth(0 nth(0 layer))) + segLayer = ru_layerToValue(nth(0 nth(1 layer))) + toLayer = ru_layerToValue(nth(0 nth(1 startLayer))) + else + fromLayer = ru_layerToValue(nth(0 nth(1 layer))) + segLayer = ru_layerToValue(nth(0 nth(0 layer))) + toLayer = ru_layerToValue(nth(0 nth(0 startLayer))) + ) + (if turnToStartPinLayer segLayer = (if fromLayer < toLayer fromLayer+1 fromLayer-1)) + viasList = GenViasList(fromLayer segLayer) + (if debug >= 1 printf("L_START %s: Start segment layer %L leSeg %L startLayer %L fromLayer %L toLayer %L startSegLayer %L\n" + wireName layer leSeg startLayer fromLayer toLayer segLayer)) + +(if skipFirstSeg then + (if debug >= 1 printf("L_START %s: Skipping first segment to pin\n")) + +else + (if firstDoubleVias then DrawVia(wireName viasList cadr(leSeg) wirePitch + (if bufSegDir == "HOR" "_2CUT_V" "_2CUT_H")) + else DrawVia(wireName viasList cadr(leSeg) wirePitch "" ?doubleVias nil)) + leLayer = sprintf(nil "M%d" segLayer) + segDist = segDist + Ru_PathDistance(leSeg) + + ;need to use buspath when there are pos and neg offsets + segDir = ru_getSegDir(car(busPath) cadr(busPath) ?detail t) + dist = Ru_PathDistance(leSeg) + dblVias = (if dist > wirePitch*5 firstDoubleVias nil) + viasLoc = Ru_GetViasToPinLoc(wireName nth(0 nodePath) nth(1 nodePath) startViasLoc segDir) +pinViasOff = 5 +toPinLoc = nil + (if reserveStartPinGap then + (if (segLayer==toLayer) then + viasLoc = Ru_OffsetPoint(car(leSeg) Ru_GetDirLocOffset(segDir -TrackPitch)) + else + viasLoc = Ru_OffsetPoint(viasLoc Ru_GetDirLocOffset(segDir -wirePitch*pinViasOff)) + toPinLoc = Ru_OffsetPoint(car(leSeg) Ru_GetDirLocOffset(segDir -TrackPitch)) + ) + else + (if (segLayer==toLayer) then + ;if we don't need vias and don't have pins, then start from begining + viasLoc = car(leSeg) + else + viasLoc = Ru_OffsetPoint(viasLoc Ru_GetDirLocOffset(segDir -wirePitch*pinViasOff)) + toPinLoc = car(leSeg) + ) + ) +;printf("START: leSeg %L segDir %L viasLoc %L toPinLoc %L\n" leSeg segDir viasLoc toPinLoc) + ;turn to vias + (if Ru_GetDistance(viasLoc nth(1 leSeg)) > wirePitch/4 then + Ru_ValidatePath(list(viasLoc nth(1 leSeg)) sprintf(nil "%s L_START_SEGVIAS" wireName)) + DrawSegment(wireName leLayer wirePitch viasLoc + nth(1 leSeg) (segLayer!=toLayer) t nil) + ) + ;vias to pin if needed, Not needed when on the same track as the pin + (if toPinLoc && (!reserveStartPinGap || Ru_GetDistance(viasLoc toPinLoc) > TrackPitch) then + ;extend to the start of the pin when vias is not next to pin end + Ru_ValidatePath(list(toPinLoc viasLoc) sprintf(nil "%s L_START_VIAS_TO_PIN" wireName)) + DrawSegment(wireName sprintf(nil "M%d" toLayer) wirePitch + toPinLoc viasLoc nil (segLayer!=toLayer) nil) + ) + (if segLayer != toLayer then ; need to switch layer in order to get up to pin + viasList = GenViasList(segLayer toLayer) +; (if dist <= wirePitch*5 then ;see above check +; printf("WARN: %s start turn too short %.1f to create vias to pin\n" wireName dist) +; printf(" Move to a different layer to avoid vias to pin, or move\n") +; printf(" to a different track, or replace with e1of2 shifted by 4 wirePitch.\n") +; ) + ;(if dblVias then DrawVia(wireName viasList viasLoc wirePitch + ; (if bufSegDir == "HOR" "_2CUT_H" "_2CUT_V") ?stacked t) + ;else + Ru_DrawStackedVias(wireName viasList viasLoc wirePitch bufSegDir) + (if debugStackVias then + (if segDir == "LEFT" || segDir == "RIGHT" then + leSeg = list(Ru_OffsetPoint(viasLoc -2*wirePitch:0) + Ru_OffsetPoint(viasLoc 2*wirePitch:0)) + else + leSeg = list(Ru_OffsetPoint(viasLoc 0:-2*wirePitch) + Ru_OffsetPoint(viasLoc 0:2*wirePitch)) + ) + layerList = ru_GenLayerList(segLayer toLayer) + (if debug >= 2 printf("VIAS L_START SEG %s seg %L layer %L\n" wireName leSeg layerList)) + (foreach layer layerList + DrawWire(layer wireName wirePitch leSeg) + ) + ) + + ) +) ;skipFirstSeg + startPoint = cadr(nodePath) + bufSegDir = ru_getSegDir(nth(1 nodePath) nth(2 nodePath)) + startSegNum = 1 + beginExt = t + + else + ;no firstpattern + (if reserveStartPinGap then + segDir = ru_getSegDir(car(busPath) cadr(busPath) ?detail t) + startPoint = Ru_OffsetPoint(car(nodePath) Ru_GetDirLocOffset(segDir -TrackPitch)) + else + startPoint = car(nodePath) + ) + result = ru_getPathSegment(startPoint nodePath) + bufSegDir = ru_getSegDir(car(nodePath) cadr(nodePath)) + startSegNum = 0 + beginExt = nil + ) + else +startSegNum = 0 + ;start location is a buffer + bufSegNum = Ru_LocatePathSeg(nodePath startBufInst->xy startSegNum) + bufLoc = startBufInst->xy + startPoint = nth(bufSegNum nodePath) + (if !startPoint then + (DrawWire BusMetal2 startBufInst->name wirePitch nodePath) + error("Nil startPoint %d: %s is not located along the path %L\n" + bufSegNum startBufInst->name nodePath)) + (if !nth(bufSegNum+1 nodePath) error("Nil point#%d: %s is not located along the path %L\n" + bufSegNum+1 startBufInst->name nodePath)) + bufSegDir = ru_getSegDir(startPoint nth(bufSegNum+1 nodePath)) + (if bufSegDir == "HOR" then + bufSegX = xCoord(bufLoc) + bufSegY = yCoord(startPoint) + else + bufSegX = xCoord(startPoint) + bufSegY = yCoord(bufLoc) + ) + + result = Ru_TerminateNodeR(nodeName wireName startBufInst layer bufSegDir bufSegX bufSegY + ?doubleVias doubleVias ?termPin termPin ?segRException segRException + ?bufSegNum bufSegNum ?flipSegPattern flipSegPattern + ?backwardDir backwardDir ?enableProp enableProp ?debug debug) + startPoint = car(result) + rStartLayer = cadr(result) + segDist = segDist + nth(2 result) + startSegNum = bufSegNum + beginExt = t + ) + + ;EndPoint + nodeSeg = list(startPoint) + bufSegX = 0.0 + bufSegY = 0.0 + nodeOff = 0.0 ; path is already node path + ;printf("########### Ru_TerminateNode: startSegNum %d startPoint %L nodePath %L \n" startSegNum startPoint nodePath) + (if endBufInst then + (if debug >= 4 printf("CellView: %L\n" endBufInst->master->cellName)) + bufLoc = endBufInst->xy + flipX = (endBufInst->orient == "MX" || endBufInst->orient == "R180") + flipY = (endBufInst->orient == "MY" || endBufInst->orient == "R180") + bufSegNum = Ru_LocatePathSeg(nodePath bufLoc (if startSegNum > 0 (startSegNum-1) 0)) + (for segNum startSegNum+1 bufSegNum + nodeSeg = append(nodeSeg list(nth(segNum nodePath))) + ) + startPoint = nth(bufSegNum nodePath) + (if !startPoint then + Ru_DrawMarker(bufLoc) + DrawWire(BusMetal2 endBufInst->name wirePitch nodePath) + error("Nil endPoint #%d startSegNum %d: %s is not located along the path %L\n" + bufSegNum startSegNum endBufInst->name nodePath)) + bufSegDir = ru_getSegDir(startPoint nth(bufSegNum+1 nodePath)) + (if bufSegDir == "HOR" then + bufSegX = xCoord(bufLoc) + bufSegY = yCoord(startPoint) + else + bufSegX = xCoord(startPoint) + bufSegY = yCoord(bufLoc) + ) + + (if debug >=2 printf("%s startSegNum %L bufSegNum %d nodeSeg %L X %f Y %f \n" + wireName startSegNum bufSegNum nodeSeg bufSegX bufSegY)) + + (if bufSegNum < 0 printf("ERROR: Ru_TerminateNode: Unable to match buffer(%s) location %L to nodePath %L\n" + endBufInst->cellName bufLoc nodePath)) +;pinLOff + (if backwardDir then + pinLOff = Ru_getPinRLoc(endBufInst->master->cellName nodeName endBufInst->orient) + else + pinLOff = Ru_getPinLLoc(endBufInst->master->cellName nodeName endBufInst->orient) + ) + pinLLoc = Ru_OffsetBox(pinLOff bufLoc) + (if debug >= 1 printf("Ru_TerminateNode: %s bufSegDir %s backwardDir %L PINL off %L pinLLoc %L\n" + wireName bufSegDir backwardDir pinLOff pinLLoc)) + ;dbCreatePath((geGetEditCellView) list("M4" "bus") nodeSeg 0.4) + + leSegOff = 0.0 + layerList = nil + dblVias = t + pinExt = nil + pinExtLayer = 3 + (if bufSegDir == "HOR" then + X = bufSegX + ru_getTurnOffset(bufLoc endBufInst->master->cellName nodeName (backwardDir==nil) flipY endBufInst) + Y = bufSegY + fromLayer = ru_layerToValue(nth(0 nth(0 layer))) + toLayer = (if fromLayer == 3 4 (fromLayer-1)) + lsSeg = Ru_OffsetPoints(append(nodeSeg list(X:Y)) 0.0:nodeOff) + dblVias = (if ru_WithinGrid(xCoord(car(last(lsSeg))) TrackPitch 4*TrackPitch/24) nil t) + (if toLayer == 4 then + leSeg = list( Ru_OffsetPoint(X:Y 0.0:nodeOff) X:Ru_MidY(pinLLoc)) + else + startPoint = Ru_OffsetPoint(X:Y nodeOff:0.0) +pinSwitchOff = wirePitch*4 +(if member(bufSegNum flipSegPattern) pinSwitchOff = -pinSwitchOff) +(if rexMatchp("1of1" endBufInst->master->cellName) then + (if (GetProp endBufInst "Position" "")=="TOP" pinSwitchOff = (2*TrackPitch-pinSwitchOff)) +else + (if yCoord(startPoint) > (yCoord(bufLoc)+2*TrackPitch) then + (if member(bufSegNum flipSegPattern) then + pinSwitchOff = pinSwitchOff ;FIXME redundant with above member check + else pinSwitchOff = (4*TrackPitch-pinSwitchOff)) + ) +) + leSeg = list( startPoint X:(yCoord(bufLoc)+pinSwitchOff)) +; (if flipX -1 1)*(if yCoord(startPoint) > (yCoord(bufLoc)+2*TrackPitch) && +; !rexMatchp("1of1" endBufInst->master->cellName) (4*TrackPitch-pinSwitchOff) pinSwitchOff)) ) + pinExt = list(car(last(leSeg)) X:Ru_MidY(pinLLoc)) + pinExtLayer = 4 + (if Ru_PathDistance(pinExt) < TrackPitch/24/4 pinExt = nil) ; already on top of pin + ) + dist = Ru_GetDistance(nth(0 leSeg) nth(1 leSeg)) + (if dist < TrackPitch/24/4 then + leSeg = nil ; no need to turn, on top on pin + turnSeg = nil + ) + ll = lowerLeft(endBufInst->bBox) + ur = upperRight(endBufInst->bBox) +;(if fromLayer == 5 printf("wireName %s fromLayer %d toLayer %d %L %L %L\n" wireName fromLayer toLayer yCoord(ll) (Y+nodeOff) yCoord(ur))) + (if fromLayer <=3 && Ru_IsBetween(yCoord(ll) (Y+nodeOff) yCoord(ur)) then +printf("@@@@@@@@@ ERROR: %s is using the buffer tracks with layer %d. Move it to another track or layer\n" wireName fromLayer) + ) +pinSwitchOff = wirePitch*4 + (if fromLayer == 5 && + (Ru_IsBetween(yCoord(ll) (Y+nodeOff) (yCoord(ll)+pinSwitchOff+3*wirePitch)) || + (Ru_IsBetween(yCoord(ll)-(pinSwitchOff+3*wirePitch) (Y+nodeOff-4*TrackPitch) yCoord(ll))&& + !rexMatchp("1of1" endBufInst->master->cellName)) ) then +printf("@@@@@@@@@ ERROR: %s is using the reserved area for vias to turn down. Move it off a bit or use different track or layer, or use inlv_e1of2_X3 or X4.\n" wireName) + ) +;leSeg = ru_AdjustSegLength(leSeg TrackPitch/2) + viasList = GenViasList(fromLayer toLayer) + lsLayer = layer + layerList = ru_GenLayerList(toLayer pinExtLayer) ; going to multiple layers + viasList = GenViasList(toLayer 3) + leLayer = sprintf(nil "M%d" toLayer) + (if debug >= 3 printf("%s HOR SegStart %L %L SegEnd %L %L layerList %L\n" + wireName lsSeg lsLayer leSeg leLayer layerList)) + else + X = bufSegX + fromLayer = ru_layerToValue(nth(0 nth(1 layer))) + toLayer = (if fromLayer == 2 3 5) + viasList = GenViasList(fromLayer toLayer) + lsLayer = layer + ;vertical wires on layer2 must be on the side of the buffer + Y = Ru_MidY(pinLLoc) + leSeg = nil + segExcep = ru_GetSegException(segLException wireName) + (if enableProp then + (if !segExcep then + ;special case for SchedToIngress to prevent bus overlap + prop = (GetProp endBufInst "OffsetNodeMatch" "") + ;printf("%s: OffsetNodeMatch %L by %L\n" wireName prop propValue->value) + (if prop && prop!="" && rexMatchp(prop wireName) then + propValue = (dbFindProp endBufInst "OffsetNodeValue") + segExcep = list(nil (if propValue->value propValue->value 0)*wirePitch) + ;printf("%s: OffsetNode by %L\n" wireName propValue->value) + termPin = nil + ) + ) + prop = (GetProp endBufInst "SingleViasMatch" "") + (if prop && prop!="" && rexMatchp(prop wireName) then + propValue = (dbFindProp endBufInst "SingleViasValue") + dblVias = (if propValue->value=="TRUE" nil t) +;printf("%s: L dblVias %L SingleVias %L \n" wireName dblVias propValue->value) + ) + ) +; (if !segExcep && !(GetProp endBufInst "LeftRightAlign" t) then +; ;Offset by 1 TrackPitch to prevent overlapping when buffer is not aligned on correct side +; segExcep = list(nil -TrackPitch) +; termPin = nil +; ) + (if segExcep then + leSegOff = nth(1 segExcep) + (if debug >= 1 printf("%s L horizontal segment X %f Y %f is offset by %L\n" wireName X Y leSegOff)) + lsSeg = Ru_OffsetPoints(append(nodeSeg list(X:(Y+leSegOff))) nodeOff:0.0) + leSeg = append(last(lsSeg) list(Ru_MidX(pinLLoc):(Y+leSegOff))) ;just close by + else + lsSeg = Ru_OffsetPoints(append(nodeSeg list(X:Y)) nodeOff:0.0) + (if nil && Ru_IsBetween(xCoord(lowerLeft(pinLLoc)) (X+nodeOff) xCoord(upperRight(pinLLoc))) then + leSeg = nil ; no need to turn + turnSeg = nil + else + (if toLayer == 3 then + leSeg = list( Ru_OffsetPoint(X:Y nodeOff:0.0) Ru_MidX(pinLLoc):Y) + else +pinSwitchOff = wirePitch*4 + leSeg = list( Ru_OffsetPoint(X:Y nodeOff:0.0) (RoundDownTrack(xCoord(bufLoc))+(if flipY -pinSwitchOff pinSwitchOff)):Y) + pinExt = list(car(last(leSeg)) Ru_MidX(pinLLoc):Y) + (if Ru_PathDistance(pinExt) < TrackPitch/2 pinExt = nil) ; already on top of pin + ) + ) + ) + dblVias = (if ru_WithinGrid(yCoord(car(last(lsSeg))) TrackPitch 4*TrackPitch/24) nil dblVias) + layerList = ru_GenLayerList(toLayer pinExtLayer) ; going to multiple layers + viasList = GenViasList(toLayer 3) + leLayer = sprintf(nil "M%d" toLayer) + (if debug >= 3 printf("%s VERT SegStart %L %L SegEnd %L %L layerList %L\n" + wireName lsSeg lsLayer leSeg leLayer layerList)) + ) + (if debug >= 2 printf("[%s pinLLoc %L bufLoc %L nodeSeg %L pattern %L layer: %L]\n" + wireName pinLLoc bufLoc nodeSeg width layer)) + (if debug >= 1 printf("L_START %s: segment %L from pin using %L leSeg %L fromLayer %L toLayer %L pinExt %L doubleVias %L dblVias %L\n" + wireName lsSeg lsLayer leSeg fromLayer toLayer pinExt doubleVias dblVias)) + + Ru_ValidatePath(lsSeg sprintf(nil "%s L_START" wireName)) + Ru_DrawWire(lsLayer wireName wirePitch lsSeg ?beginExt beginExt ?endExt t ?doubleVias doubleVias) + segDist = segDist + Ru_PathDistance(lsSeg) + + turnLayer = GenViasList(fromLayer toLayer) + (if dblVias then DrawVia(wireName turnLayer car(last(lsSeg)) wirePitch + (if bufSegDir == "HOR" "_2CUT_H" "_2CUT_V")) + else DrawVia(wireName turnLayer car(last(lsSeg)) wirePitch "" ?doubleVias nil)) + + (if debug >= 1 printf("L_END segment %L to buffer going between layer %d to %d. leLayer %L turnLayer %L\n" + leSeg toLayer 3 leLayer turnLayer)) + (if leSeg && Ru_PathDistance(leSeg) > TrackPitch/64 then + Ru_ValidatePath(leSeg sprintf(nil "%s L_END" wireName)) + segDist = segDist + Ru_PathDistance(leSeg) + DrawSegment(wireName leLayer wirePitch nth(0 leSeg) nth(1 leSeg) t t nil) + ) + + (if termPin && pinExt then + Ru_ValidatePath(pinExt sprintf(nil "%s L_PINEXT" wireName)) + segDist = segDist + Ru_PathDistance(pinExt) + DrawSegment(wireName sprintf(nil "M%d" pinExtLayer) wirePitch nth(0 pinExt) nth(1 pinExt) t t nil) + (if pinExtLayer != 3 then ;HOR connection + cuts = (if dblVias "_2CUT_H" "") + (if !dblVias then dblVias = t cuts = "_2CUT_V") + DrawVia(wireName GenViasList(pinExtLayer 3) car(last(pinExt)) + wirePitch cuts ?doubleVias dblVias) + ) + ) + + (if termPin && toLayer!=3 + (if pinExtLayer != 3 then ;HOR connection + (if toLayer != 6 error("L_END: %s Unexpected toLayer %L with pinExtLayer %L\n" wireName toLayer pinExtLayer)) + cuts = "_2CUT_V" + DrawVia(wireName GenViasList(toLayer pinExtLayer) car(pinExt) + wirePitch "_2CUT_V" ?doubleVias t) + else + cuts = (if dblVias "_2CUT_H" "") + (if !dblVias && bufSegDir == "HOR" then cuts = "_2CUT_V") + dblVias = t + DrawVia(wireName viasList (if leSeg car(last(leSeg)) car(last(lsSeg))) + wirePitch cuts ?doubleVias dblVias) + ) + ) + (if debugStackVias && layerList then + (if cuts == "_2CUT_H" then X = 2*wirePitch Y = 0.0 else X = 0.0 Y = 2*wirePitch) + (if turnSeg then + leSeg = list(Ru_OffsetPoint(car(last(leSeg)) -X:-Y) + Ru_OffsetPoint(car(last(leSeg)) X:Y)) + else leSeg = list(Ru_OffsetPoint(car(last(lsSeg)) -X:-Y) + Ru_OffsetPoint(car(last(lsSeg)) X:Y))) + (if debug >= 2 printf("VIAS L SEG %s seg %L layer %L\n" wireName leSeg layerList)) + (foreach layer layerList + DrawWire(layer wireName wirePitch leSeg) + ) + ) + else + ;to end path + lsLayer = layer + lsSeg = list(startPoint) + pathLen = length(nodePath) + (if lastPattern then + (for segNum startSegNum+1 pathLen-2 + lsSeg = append(lsSeg list(nth(segNum nodePath))) + ) + (if length(lsSeg) <= 1 then + printf("@@@@@@@@@ ERROR: %s Must have a turn at the end when specifying lastPattern option\n" wireName) + else + leSeg = list(nth(pathLen-2 nodePath) nth(pathLen-1 nodePath)) + bufSegDir = ru_getSegDir(nth(pathLen-2 nodePath) nth(pathLen-1 nodePath)) + endNode = Ru_GetChannelEntry(lastPattern nodeName) + (if !endNode error("Unable to find %L in lastPattern %L\n" nodeName lastPattern)) + endLayer = nth(3 endNode) + (if !endLayer error("%L in lastPattern must have BusMetal specified\n" endLayer)) + (if bufSegDir == "VERT" then + fromLayer = ru_layerToValue(nth(0 nth(0 layer))) + segLayer = ru_layerToValue(nth(0 nth(1 layer))) + toLayer = ru_layerToValue(nth(0 nth(1 endLayer))) + else + fromLayer = ru_layerToValue(nth(0 nth(1 layer))) + segLayer = ru_layerToValue(nth(0 nth(0 layer))) + toLayer = ru_layerToValue(nth(0 nth(0 endLayer))) + ) + (if turnToEndPinLayer segLayer = (if fromLayer < toLayer fromLayer+1 fromLayer-1)) + viasList = GenViasList(fromLayer segLayer) + (if debug >= 1 printf("R_END %s: End segment %d layer %L leSeg %L endLayer %L fromLayer %L toLayer %L endSegLayer %L\n" + wireName startSegNum layer leSeg endLayer fromLayer toLayer segLayer)) + +(if skipLastSeg then + (if debug >= 1 printf("L_START %s: Skipping first segment to pin\n")) + +else + (if lastDoubleVias then DrawVia(wireName viasList car(leSeg) wirePitch + (if bufSegDir == "HOR" "_2CUT_V" "_2CUT_H")) + else DrawVia(wireName viasList car(leSeg) wirePitch "" ?doubleVias nil)) + leLayer = sprintf(nil "M%d" segLayer) + segDist = segDist + Ru_PathDistance(leSeg) + + ;need to use busPath when there are neg and pos offsets + segDir = ru_getSegDir(nth(pathLen-2 busPath) nth(pathLen-1 busPath) ?detail t) + dist = Ru_PathDistance(leSeg) + ;turn distance is too short to use double vias to pin + dblVias = (if dist > wirePitch*5 lastDoubleVias nil) + viasLoc = Ru_GetViasToPinLoc(wireName nth(pathLen-1 nodePath) nth(pathLen-2 nodePath) endViasLoc segDir) +pinViasOff = 5 +toPinLoc = nil + (if reserveEndPinGap then + (if (segLayer==toLayer) then + ;only to the edge of pin location to prevent routing violation + viasLoc = Ru_OffsetPoint(cadr(leSeg) Ru_GetDirLocOffset(segDir TrackPitch)) + else + viasLoc = Ru_OffsetPoint(viasLoc Ru_GetDirLocOffset(segDir wirePitch*pinViasOff)) + toPinLoc = Ru_OffsetPoint(cadr(leSeg) Ru_GetDirLocOffset(segDir TrackPitch)) + ) + else + (if (segLayer==toLayer) then + ;if we don't need vias and don't have pins, then start from begining + viasLoc = cadr(leSeg) + else + viasLoc = Ru_OffsetPoint(viasLoc Ru_GetDirLocOffset(segDir wirePitch*pinViasOff)) + toPinLoc = cadr(leSeg) + ) + ) +;printf("END: leSeg %L viasLoc %L toPinLoc %L\n" leSeg viasLoc toPinLoc) + ;only to the vias location to prevent routing violation + (if Ru_GetDistance(nth(0 leSeg) viasLoc) > wirePitch/4 then + Ru_ValidatePath(list(nth(0 leSeg) viasLoc) sprintf(nil "%s L_END_SEGVIAS" wireName)) + DrawSegment(wireName leLayer wirePitch nth(0 leSeg) + viasLoc t (segLayer!=toLayer) nil) + ) + + ;Not needed when on the same track as the pin + (if toPinLoc && (!reserveEndPinGap || Ru_GetDistance(viasLoc toPinLoc) > TrackPitch) then + Ru_ValidatePath(list(viasLoc toPinLoc) sprintf(nil "%s L_END_VIA_TO_PIN" wireName)) + ;extend to the end of the pin when vias is not next to pin + DrawSegment(wireName sprintf(nil "M%d" toLayer) wirePitch viasLoc + toPinLoc (segLayer!=toLayer) nil nil) + ) + (if segLayer != toLayer then ;need to switch layer in order to get up to pin + viasList = GenViasList(segLayer toLayer) + ;(if dist <= wirePitch*5 then ;see above test + ; printf("WARN: %s end turn too short %.1f to create vias to pin.\n" wireName dist) + ; printf(" Move to a different layer to avoid vias to pin, or move\n") + ; printf(" to a different track, or replace with e1of2 shifted by 4 wirePitch.\n") + ;) + + ;(if dblVias then DrawVia(wireName viasList viasLoc wirePitch + ; (if bufSegDir == "HOR" "_2CUT_H" "_2CUT_V") ?stacked t) + ;else + ;will cause drc error if using double vias + Ru_DrawStackedVias(wireName viasList viasLoc wirePitch bufSegDir) + + (if debugStackVias then + (if bufSegDir == "HOR" then + leSeg = list(Ru_OffsetPoint(viasLoc -2*wirePitch:0) + Ru_OffsetPoint(viasLoc 2*wirePitch:0)) + else + leSeg = list(Ru_OffsetPoint(viasLoc 0:-2*wirePitch) + Ru_OffsetPoint(viasLoc 0:2*wirePitch)) + ) + layerList = ru_GenLayerList(segLayer toLayer) + (if debug >= 2 printf("VIAS R_END SEG %s seg %L layer %L\n" wireName leSeg layerList)) + (foreach layer layerList + DrawWire(layer wireName wirePitch leSeg) + ) + ) + ) + ) ;if length(lsSeg) <= 1 +) ;skipLastSeg + + else + ;no lastPattern + (for segNum startSegNum+1 pathLen-1 + (if segNum == pathLen-1 && reserveEndPinGap then + segDir = ru_getSegDir(nth(pathLen-2 busPath) nth(pathLen-1 busPath) ?detail t) + lsSeg = append(lsSeg list(Ru_OffsetPoint(nth(segNum nodePath) Ru_GetDirLocOffset(segDir TrackPitch)))) + else + lsSeg = append(lsSeg list(nth(segNum nodePath))) + ) + ) + ) + (if length(lsSeg) > 1 /*&& Ru_PathDistance(lsSeg) > TrackPitch/24*/ then ;valid segment + (if debug >= 1 printf("R_END %s: End segment %d rStartLayer %L layer %L lsSeg %L\n" wireName startSegNum rStartLayer layer lsSeg)) + Ru_ValidatePath(lsSeg sprintf(nil "%s R_END" wireName)) + segDist = segDist + Ru_PathDistance(lsSeg) + Ru_DrawWire(lsLayer wireName wirePitch lsSeg ?beginExt t ?endExt nil ?doubleVias doubleVias) + ) + ) + + (cond + (startBufInst == nil result = "first " maxWarnDist = (if maxManDistFirstSeg maxManDistFirstSeg maxManDist*0.80)) + (endBufInst == nil result = "last " maxWarnDist = (if maxManDistLastSeg maxManDistLastSeg maxManDist*0.80)) + (t result = "" maxWarnDist = maxManDist) + ) + (if segDist > maxWarnDist printf("WARN: %s Total %ssegment distance %.2f is over limit %.2f\n" + wireName result segDist maxWarnDist)) + return(segDist) + ) + +) + +(defun Ru_GetDirLocOffset (segDir offset) + (let (locOff) + (cond + (segDir == "UP" + locOff = 0:-offset) + (segDir == "DOWN" + locOff = 0:offset) + (segDir == "LEFT" + locOff = offset:0) + (segDir == "RIGHT" + locOff = -offset:0) + (t error("Ru_GetDirOffset: Unknown %L\n" segDir)) + ) + locOff + ) +) + +;Manually tie path to ground, in case BundledRoute not doing it and don't want to use NanoRoute +;vertDir direction of the pattern +(defun TieGNDToGrid (point pattern vertDir @key (doubleVias t)) + (let (el nodeName wirePitch nodeOff layer viasLoc gridLoc cuts) + (if vertDir then + gridLoc = RoundDownTrack(xCoord(point) ?numTrack 2):yCoord(point) + else + gridLoc = xCoord(point):RoundDownTrack(yCoord(point) ?numTrack 2) + ) + cuts = strcat((if doubleVias "_2CUT" "") (if vertDir "_H" "_V")) + (foreach el pattern + nodeName = nth(0 el) + (if nodeName == "GND" then + wirePitch = nth(1 el) + nodeOff = nth(2 el) + layer = nth(2 nth(3 el)) + (if vertDir && layer == "M3_M2" then layer = "M4_M3") + viasLoc = OffsetPoint(gridLoc (if vertDir 0 nodeOff) (if vertDir nodeOff 0)) + ;use stacked vias to avoid DRC + DrawVia("GND" layer viasLoc wirePitch cuts ?doubleVias doubleVias) + ) + ) + ) + t +) + +(defun CreateShield (path pattern) + (let (el nodeName wirePitch nodeOff layer nodePath pA pB segDir gndLayer cuts viasLoc) + (foreach el pattern + nodeName = nth(0 el) + (if nodeName == "GND" then + wirePitch = nth(1 el) + nodeOff = nth(2 el) + layer = nth(3 el) + ;FIXME + (if length(path) == 2 then + (if ru_getSegDir(car(path) cadr(path)) == "HOR" then + nodePath = OffsetPoints(path 0 nodeOff) + else + nodePath = OffsetPoints(path nodeOff 0) + ) + else + nodePath = OffsetPoints(path nodeOff nodeOff) + ) + (DrawWire layer nodeName wirePitch nodePath ?doubleVias nil) + ;draw the vias in the middle of each segment + (for cnt 0 length(nodePath)-2 + pA = nth(cnt nodePath) + pB = nth(cnt+1 nodePath) + (if Ru_GetDistance(pA pB) > 8*TrackPitch then + segDir = ru_getSegDir(pA pB) + gndLayer = nth(2 layer) + (if segDir == "HOR" then + viasLoc = RoundDownTrack((xCoord(pA)+xCoord(pB))/2 ?numTrack 2):yCoord(pA) + (if gndLayer == "M3_M2" then gndLayer = "M4_M3") + cuts = "_2CUT_H" + else + viasLoc = xCoord(pA):RoundDownTrack((yCoord(pA)+yCoord(pB))/2 ?numTrack 2) + cuts = "_2CUT_V" + ) + DrawVia("GND" gndLayer viasLoc wirePitch cuts ?doubleVias t) + ) + ) + ) + ) + ) +) + + +;single stacked vias +(defun Ru_DrawStackedVias (wireName viasList viasLoc wirePitch segDir) + (let (vias) + (foreach vias viasList + DrawVia(wireName vias viasLoc wirePitch (if bufSegDir == "HOR" "_2CUT_H" "_2CUT_V") ?doubleVias nil ?stacked t) + ) + ) +) + +(defun ToTrack (points) + (prog (newPath point) + (if !listp(points) return(points/TrackPitch)) + (if !listp(car(points)) return(xCoord(points)/TrackPitch:yCoord(points)/TrackPitch)) + (foreach point points + newPath = append(newPath list(xCoord(point)/TrackPitch:yCoord(point)/TrackPitch)) + ) + return(newPath) + ) +) + +(defun Ru_GetViasToPinLoc (wireName pinLoc turnLoc viasLocCfg segDir) + (prog (viasLoc loc locSel vert pinVal turnVal defaultLoc) + (if !viasLocCfg return(pinLoc)) + (if !listp(viasLocCfg) viasLocCfg = list(viasLocCfg)) + locSel = 99999.0 + vert = (segDir=="UP" || segDir=="DOWN") + ;printf("pinLoc %L turnLoc %L viasLocCfg %L\n" pinLoc turnLoc viasLocCfg) + (foreach loc viasLocCfg + (if listp(loc) then + (if ru_IsNameMatched(car(loc) wireName ?exactMatch t) then + (if vert return(xCoord(pinLoc):cadr(loc)) + return(cadr(loc):yCoord(pinLoc))) + ) + else + (if !defaultLoc defaultLoc = loc) + (if vert then + pinVal = yCoord(pinLoc) + turnVal = yCoord(turnLoc) + else + pinVal = xCoord(pinLoc) + turnVal = xCoord(turnLoc) + ) + ;printf("pinVal %L loc %L turnVal %L between %L\n" pinVal loc turnVal Ru_IsBetween(pinVal loc turnVal)) + (if Ru_IsBetween(pinVal loc turnVal) && + abs(loc-turnVal) < abs(locSel-turnVal) then + ;printf("New loc %f old %f\n" loc locSel) + locSel = loc + ) + ) + ) + (if locSel==99999.0 locSel = defaultLoc) + (if vert return(xCoord(pinLoc):locSel) + return(locSel:yCoord(pinLoc))) + ) +) + +(defun RoundDownTrack (value @key (numTrack 1)) + (floor((value+TrackPitch/64)/(numTrack*TrackPitch))*(numTrack*TrackPitch)) +) + +(defun RoundUpTrack (value) + (ceiling((value-TrackPitch/64)/TrackPitch)*TrackPitch) +) + +(defun busMetalToStr (busMetal) + (let (busMetalStr) + layerStr = nth(0 nth(0 busMetal)) + (cond + (layerStr=="M7" busMetalStr = "BusMetal67") + (layerStr=="M5" busMetalStr = "BusMetal45") + (t busMetalStr = "BusMetal23") + ) + busMetalStr + ) +) + +;busPattern is multiple layer pattern +;toPattern is a single layer pattern +;offset is the offset from busPattern to toPattern +(defun GenerateSwitchPattern (busPattern toPattern offset dirNeg @key (debug 0)) + (let (outsideList insideList bp el fromOffset toOffset nodeOff + maxOff minOff layer pat len sortOffset trackOffi layerStr) + maxOff = -9999.0 + minOff = 9999.0 + (foreach bp busPattern + (if minOff > nth(2 bp) minOff = nth(2 bp)) + (if maxOff < nth(2 bp) maxOff = nth(2 bp)) + ) + minOff = floor(ToTrack(minOff+TrackPitch/2)) + maxOff = floor(ToTrack(maxOff+TrackPitch/2)) + + declare( m3InUsed[maxOff+1]) + declare( m5InUsed[maxOff+1]) + declare( m7InUsed[maxOff+1]) + + (for cnt minOff maxOff + m3InUsed[cnt] = 0 + m5InUsed[cnt] = 0 + m7InUsed[cnt] = 0 + ) + (foreach bp busPattern + nodeName = nth(0 bp) + len = strlen(nodeName) + (if substring(nodeName len len) == "e" then ;baseNode + result = Ru_SplitNodeName(nodeName) + nodeBaseName = car(result) + nodeElName = cadr(result) + pat = nth(1 bp) + nodeOff = nth(2 bp) + fromOffset = floor(ToTrack(nodeOff+TrackPitch/2)) + layer = nth(3 bp) + layerStr = nth(0 nth(0 layer)) + ;printf("fromOFffset %L %L\n" fromOffset bp) + (cond + (layerStr == "M6" || layerStr == "M7" m7InUsed[fromOffset] = m7InUsed[fromOffset] + 1 ) + (layerStr == "M4" || layerStr == "M5" m5InUsed[fromOffset] = m5InUsed[fromOffset] + 1 ) + (layerStr == "M2" || layerStr == "M3" m3InUsed[fromOffset] = m3InUsed[fromOffset] + 1 ) + (t error("Unknown %L\n" layerStr)) + ) + + (foreach el toPattern + (if nodeName == nth(0 el) then + toOffset = floor(ToTrack(nth(2 el) + TrackPitch/2 + offset)) + sortOffset = - fromOffset + (cond + (toOffset < minOff || toOffset > maxOff outsideList = append(outsideList list(list(sortOffset nodeBaseName layer fromOffset toOffset)))) + (t insideList = append(insideList list(list(sortOffset nodeBaseName layer fromOffset toOffset)))) + ) + ) + ) + ) + ) + + (foreach el outsideList + layerStr = nth(0 nth(0 nth(2 el))) + fromOffset = nth(3 el) + ;printf("%L %L\n" el fromOffset) + (cond + (layerStr == "M6" || layerStr == "M7" m7InUsed[fromOffset] = m7InUsed[fromOffset] - 1) + (layerStr == "M4" || layerStr == "M5" m5InUsed[fromOffset] = m5InUsed[fromOffset] - 1) + (layerStr == "M2" || layerStr == "M3" m3InUsed[fromOffset] = m3InUsed[fromOffset] - 1) + (t error("Unknown %L\n" el)) + ) + ) + + declare( trackOff[maxOff+1]) + (if dirNeg then + startOff = maxOff + endOff = minOff + else + startOff = minOff + endOff = maxOff + ) + declare( switchTrackInUse[maxOff+1]) + (for cnt minOff maxOff + switchTrackInUse[cnt] = nil + ) + (for cnt minOff maxOff + trackOff[cnt] = startOff + ) + showPat = t + c = nil + (foreach el outsideList + ;printf("EL: %L LAYER: %L \n" el nth(1 nth(2 el))) + layer = nth(0 nth(1 nth(2 el))) + result = Ru_GetFreeTrack(nth(1 el) switchTrackInUse layer startOff endOff) + trackIdx = car(result) + inlv = cadr(result) + busMetal = nth(2 result) + fromOffset = nth(3 el) + (if !dirNeg trackOff[fromOffset] < trackIdx trackOff[fromOffset] = trackIdx) + (if dirNeg trackOff[fromOffset] > trackIdx trackOff[fromOffset] = trackIdx) + (if debug >= 1 printf("TRACK: %L %L result %L EL: %L\n" trackIdx inlv result el )) + (if showPat printf(" (list \"%s\" inlv_e1of4%s %d*TrackPitch %s)\n" nth(1 el) inlv trackIdx busMetalToStr(busMetal))) + c = (cons (list nth(1 el) (if inlv=="_A" inlv_e1of4_A inlv_e1of4_B) trackIdx*TrackPitch busMetal) c) + ) + (if debug >= 2 then + (for cnt minOff maxOff + printf("TRACK: %L offset %L\n" cnt trackOff[cnt]) + ) + (for cnt minOff maxOff + printf("INUSE: %L layer %L\n" cnt switchTrackInUse[cnt]) + ) + ) + + ;figuring trackOffset for inside tracks that the opposide end is done + trackFree = t ; at least run once + runCnt = 0 + newTracksAdded = 1 + (while newTracksAdded!=0 + trackFree = nil + newTracksAdded = 0 + runCnt++ + remainingList = reverse(insideList);make a copy + (for cnt minOff maxOff + ;printf("TRACK#%d: %L %L %L\n" cnt m3InUsed[cnt] m5InUsed[cnt] m7InUsed[cnt]) + (if m7InUsed[cnt]==0 && m5InUsed[cnt]==0 && m3InUsed[cnt]==0 then + trackFree = append(trackFree list(cnt)) + + (foreach el insideList + ;printf("cnt %d el %L\n" cnt el) + (if cnt == nth(4 el) then + newTracksAdded++ + toOffset = nth(4 el) + (if debug >= 1 printf("Adding toOffset %L trackOff %L %L\n" toOffset trackOff[toOffset] el)) + layerStr = nth(0 nth(1 nth(2 el))) + result = Ru_GetFreeTrack(nth(1 el) switchTrackInUse layerStr trackOff[toOffset] endOff) + trackIdx = car(result) + inlv = cadr(result) + busMetal = nth(2 result) + fromOffset = nth(3 el) + (if !dirNeg trackOff[fromOffset] < trackIdx trackOff[fromOffset] = trackIdx) + (if dirNeg trackOff[fromOffset] > trackIdx trackOff[fromOffset] = trackIdx) + (if debug >= 1 printf("TRACKIN: %L %L result %L EL: %L\n" trackIdx inlv result el )) + remainingList = Ru_RemoveFromList(el remainingList) + (cond + (layerStr == "M6" || layerStr == "M7" m7InUsed[fromOffset] = m7InUsed[fromOffset] - 1) + (layerStr == "M4" || layerStr == "M5" m5InUsed[fromOffset] = m5InUsed[fromOffset] - 1) + (layerStr == "M2" || layerStr == "M3" m3InUsed[fromOffset] = m3InUsed[fromOffset] - 1) + (t error("Unknown %L\n" el)) + ) + + (if showPat printf(" (list \"%s\" inlv_e1of4%s %d*TrackPitch %s)\n" nth(1 el) inlv trackIdx busMetalToStr(busMetal))) + c = (cons (list nth(1 el) (if inlv=="_A" inlv_e1of4_A inlv_e1of4_B) trackIdx*TrackPitch busMetal) c) + ) + ) + ) + ) + + (if debug >= 2 then + printf("##################### RUN %L Added %L ####################\n" runCnt newTracksAdded) + printf("TRACKFREE: %L len %L %L\n" trackFree length(remainingList) length(insideList) ) + (for cnt minOff maxOff + printf("TRACK: %L offset %L\n" cnt trackOff[cnt]) + ) + (for cnt minOff maxOff + printf("INUSE: %L layer %L\n" cnt switchTrackInUse[cnt]) + ) + ) + insideList = remainingList + ) ;while + + (if debug >= 1 printf("##################### SECOND RUN\n")) + trackFree = nil + insideList = remainingList + remainingList = reverse(insideList);make a copy + (for cnt minOff maxOff + ;printf("TRACK#%d: %L %L %L\n" cnt m3InUsed[cnt] m5InUsed[cnt] m7InUsed[cnt]) + trackFree = append(trackFree list(cnt)) + (foreach el insideList + ;printf("cnt %d el %L\n" cnt el) + (if cnt == nth(4 el) then + toOffset = nth(4 el) + (if debug >= 1 printf("Adding toOffset %L trackOff %L endOff %L EL: %L\n" toOffset trackOff[toOffset] endOff el)) + layerStr = nth(0 nth(1 nth(2 el))) + result = Ru_GetFreeTrack(nth(1 el) switchTrackInUse layerStr trackOff[toOffset] endOff) + trackIdx = car(result) + inlv = cadr(result) + busMetal = nth(2 result) + fromOffset = nth(3 el) + (if !dirNeg trackOff[fromOffset] < trackIdx trackOff[fromOffset] = trackIdx) + (if dirNeg trackOff[fromOffset] > trackIdx trackOff[fromOffset] = trackIdx) + (if debug >= 1 printf("TRACKIN: %L %L result %L EL: %L\n" trackIdx inlv result el )) + ;outsideList = append(list(el) outsideList) + remainingList = Ru_RemoveFromList(el remainingList) + (cond + (layerStr == "M6" || layerStr == "M7" m7InUsed[fromOffset] = m7InUsed[fromOffset] - 1) + (layerStr == "M4" || layerStr == "M5" m5InUsed[fromOffset] = m5InUsed[fromOffset] - 1) + (layerStr == "M2" || layerStr == "M3" m3InUsed[fromOffset] = m3InUsed[fromOffset] - 1) + (t error("Unknown %L\n" el)) + ) + + (if showPat printf(" (list \"%s\" inlv_e1of4%s %d*TrackPitch %s)\n" nth(1 el) inlv trackIdx busMetalToStr(busMetal))) + c = (cons (list nth(1 el) (if inlv=="_A" inlv_e1of4_A inlv_e1of4_B) trackIdx*TrackPitch busMetal) c) + ) + ) + ) + (if debug >= 2 then + printf("TRACKFREE: %L len %L %L\n" trackFree length(remainingList) length(insideList) ) + (for cnt minOff maxOff + printf("TRACK: %L offset %L\n" cnt trackOff[cnt]) + ) + (for cnt minOff maxOff + printf("INUSE: %L layer %L\n" cnt switchTrackInUse[cnt]) + ) + ) + ) + (DefChan c) +) + +(defun Ru_RemoveFromList (entry elList) + (let (el newList) + (foreach el elList + (if entry != el newList = append(newList list(el))) + ) + newList + ) +) + +(defun Ru_GetFreeTrack (nodeName switchTrackInUse layer startOff endOff) + (prog (cnt freeTrack freePat) + (if startOff < endOff then endCnt = (endOff+1) incrCnt = 1 cnt = startOff + else endCnt = (endOff-1) incrCnt = -1 cnt = startOff) +;printf("############### layer %L %L startOff %L %L %L %L %L\n" layer (layer == "M6") startOff endOff endCnt incrCnt cnt) + (while cnt != endCnt +(cond + (layer == "M6" +;printf("####INUSE: %L %L member %L %L\n" cnt switchTrackInUse[cnt] !member("M6_A" switchTrackInUse[cnt]) !member("M6_B" switchTrackInUse[cnt])) + (if !member("M6_A" switchTrackInUse[cnt]) then + switchTrackInUse[cnt] = append(switchTrackInUse[cnt] list("M6_A")) +;printf("FOUND: %L %L\n" cnt switchTrackInUse[cnt]) + return(list(cnt "_A" BusMetal67)) + ) + (if !member("M6_B" switchTrackInUse[cnt]) then + switchTrackInUse[cnt] = append(switchTrackInUse[cnt] list("M6_B")) +;printf("FOUND: %L %L\n" cnt switchTrackInUse[cnt]) + return(list(cnt "_B" BusMetal67)) + ) + ) + (layer == "M4" + (if !member("M4_A" switchTrackInUse[cnt]) then + switchTrackInUse[cnt] = append(switchTrackInUse[cnt] list("M4_A")) + return(list(cnt "_A" BusMetal45)) + ) + (if !member("M4_B" switchTrackInUse[cnt]) then + switchTrackInUse[cnt] = append(switchTrackInUse[cnt] list("M4_B")) + return(list(cnt "_B" BusMetal45)) + ) + ) + (layer == "M2" + (if !member("M2_A" switchTrackInUse[cnt]) then + switchTrackInUse[cnt] = append(switchTrackInUse[cnt] list("M2_A")) + return(list(cnt "_A" BusMetal23)) + ) + (if !member("M2_B" switchTrackInUse[cnt]) then + switchTrackInUse[cnt] = append(switchTrackInUse[cnt] list("M2_B")) + return(list(cnt "_B" BusMetal23)) + ) + ) + (t error("Ru_GetFreeTrack: Unsupported layer %L\n" layer)) +) + + cnt = cnt + incrCnt + ) +cnt = endOff +switchTrackInUse[cnt] = append(switchTrackInUse[cnt] list("M6_A_X")) +printf("#### %L: NO MORE FREE TRACKS\n" nodeName) + return(list(cnt "_A" BusMetal67)) + ) +) + + + + + +(defun DrawPathPrBound (path layerPatternList @key + (firstPattern nil) (lastPattern nil) + (firstResetPattern nil) (lastResetPattern nil) + (deletePrBound t) + (debug 0) ) + (let (tempPath lowerBound upperBound point busMinOff busMaxOff poly + el firstMaxOff firstMinOff lastMaxOff lastMinOff limit) + + (if deletePrBound then + (foreach shape (geGetEditCellView)->shapes + (if shape~>layerName=="prBoundary" (dbDeleteObject shape)) + ) + ) + + busMaxOff = -9999.99 + busMinOff = 9999.99 + (foreach el layerPatternList + (if busMaxOff < nth(2 el) busMaxOff = nth(2 el)) + (if busMinOff > nth(2 el) busMinOff = nth(2 el)) + ) + + (if firstPattern then + firstMaxOff = -9999.99 + firstMinOff = 9999.99 + (foreach el firstPattern + (if firstMaxOff < nth(2 el) firstMaxOff = nth(2 el)) + (if firstMinOff > nth(2 el) firstMinOff = nth(2 el)) + ) + ) + (if firstResetPattern then + (foreach el firstResetPattern + (if firstMaxOff < nth(2 el) firstMaxOff = nth(2 el)) + (if firstMinOff > nth(2 el) firstMinOff = nth(2 el)) + ) + ) + (if lastPattern then + lastMaxOff = -9999.99 + lastMinOff = 9999.99 + (foreach el lastPattern + (if lastMaxOff < nth(2 el) lastMaxOff = nth(2 el)) + (if lastMinOff > nth(2 el) lastMinOff = nth(2 el)) + ) + ) + (if lastResetPattern then + (foreach el lastResetPattern + (if lastMaxOff < nth(2 el) lastMaxOff = nth(2 el)) + (if lastMinOff > nth(2 el) lastMinOff = nth(2 el)) + ) + ) + tempPath = OffsetPath(path busMinOff busMinOff ?firstOffset firstMinOff ?lastOffset lastMinOff) +;dbCreatePath((geGetEditCellView) list("M2" "bus") tempPath 0.8) + limit = TrackPitch/24/4 + (foreach point tempPath + lowerBound = append(lowerBound list(RoundDownTrack(xCoord(point)):RoundDownTrack(yCoord(point)))) + ) + tempPath = OffsetPath(path busMaxOff busMaxOff ?firstOffset firstMaxOff ?lastOffset lastMaxOff) +;dbCreatePath((geGetEditCellView) list("M2" "bus") tempPath 0.8) + (foreach point tempPath + upperBound = append(upperBound list(RoundUpTrack(xCoord(point)):RoundUpTrack(yCoord(point)))) + ) + + result = Ru_FixPath(list(lowerBound upperBound) ?debug debug) + poly = append(nth(0 result) reverse(nth(1 result))) + dbCreatePolygon((geGetEditCellView) list("prBoundary" "drawing") poly) + poly + ) +) + +(defun Ru_FixPath (pathList @key (debug 0)) + (let (lowerBound upperBound + el segDir lastSegDir nextSegDir pathLen segLow segHi x1 x2 y1 y2 + p1 p2 segLowDir segHiDir swapX swapY temp) + + lastSegDir == "" + temp = 0.0 + lowerBound = nth(0 pathList) + upperBound = nth(1 pathList) + pathLen = length(lowerBound) + p1 = list(car(lowerBound)) + p2 = list(car(upperBound)) + + (for cnt 0 pathLen-2 + segLow = list(nth(cnt lowerBound) nth(cnt+1 lowerBound)) + segHi = list(nth(cnt upperBound) nth(cnt+1 upperBound)) + (if Ru_PathDistance(segLow) > TrackPitch/24 then + segDir = ru_getSegDir(car(segLow) cadr(segLow) ?detail t) + else + segDir = ru_getSegDir(car(segHi) cadr(segHi) ?detail t) + ) + (if cnt < pathLen-2 then + (if Ru_PathDistance(list(nth(cnt+1 lowerBound) nth(cnt+2 lowerBound))) > TrackPitch/24 then + nextSegDir = ru_getSegDir(nth(cnt+1 lowerBound) nth(cnt+2 lowerBound) ?detail t) + else + nextSegDir = ru_getSegDir(nth(cnt+1 upperBound) nth(cnt+2 upperBound) ?detail t) + ) + else nextSegDir = "END" + ) + (if debug >= 1 printf("lastSegDir %L segDir %L nextSegDir %L\n" lastSegDir segDir nextSegDir)) + + swapX = nil + swapY = nil + (if (segDir == "UP" || segDir == "DOWN") then + y1 = yCoord(car(last(p1))) + y2 = yCoord(car(last(p2))) + x1 = xCoord(car(segLow)) + x2 = xCoord(car(segHi)) + (if debug >= 1 then + printf("SwapX p2 seg %d %L %f %f %f %L %f %f %f\n" cnt + Ru_IsBetween(yCoord(car(last(p1))) yCoord(car(last(p2))) yCoord(cadr(segLow))) + yCoord(car(last(p1))) yCoord(car(last(p2))) yCoord(cadr(segLow)) + Ru_IsBetween(xCoord(cadr(segHi)) x1 xCoord(car(last(p2)))) + xCoord(cadr(segHi)) x1 xCoord(car(last(p2))) ) + printf("SwapX p1 seg %d %L %f %f %f %L %f %f %f\n" cnt + Ru_IsBetween(yCoord(car(last(p2))) yCoord(car(last(p1))) yCoord(cadr(segHi))) + yCoord(car(last(p2))) yCoord(car(last(p1))) yCoord(cadr(segHi)) + Ru_IsBetween(xCoord(cadr(segLow)) x2 xCoord(car(last(p1)))) + xCoord(cadr(segLow)) x2 xCoord(car(last(p1))) ) + ) + (if (Ru_IsBetween(yCoord(car(last(p1))) yCoord(car(last(p2))) yCoord(cadr(segLow))) && + Ru_IsBetween(xCoord(cadr(segHi)) x1 xCoord(car(last(p2)))) ) || + (Ru_IsBetween(yCoord(car(last(p2))) yCoord(car(last(p1))) yCoord(cadr(segHi))) && + Ru_IsBetween(xCoord(cadr(segLow)) x2 xCoord(car(last(p1)))) ) then + swapX = t + (if debug >= 1 printf("#### SwapX %d\n" cnt)) + ) + ) + (if (segDir == "LEFT" || segDir == "RIGHT") then + x1 = xCoord(car(last(p1))) + x2 = xCoord(car(last(p2))) + y1 = yCoord(car(segLow)) + y2 = yCoord(car(segHi)) + (if debug >= 1 then + printf("SwapY p2 seg %d %L %f %f %f %L %f %f %f\n" cnt + Ru_IsBetween(xCoord(car(last(p1))) xCoord(car(last(p2))) xCoord(cadr(segLow))) + xCoord(car(last(p1))) xCoord(car(last(p2))) xCoord(cadr(segLow)) + Ru_IsBetween(yCoord(cadr(segHi)) y1 yCoord(car(last(p2)))) + yCoord(cadr(segHi)) y1 yCoord(car(last(p2))) ) + printf("SwapY p1 seg %d %L %f %f %f %L %f %f %f\n" cnt + Ru_IsBetween(xCoord(car(last(p2))) xCoord(car(last(p1))) xCoord(cadr(segHi))) + xCoord(car(last(p2))) xCoord(car(last(p1))) xCoord(cadr(segHi)) + Ru_IsBetween(yCoord(cadr(segLow)) y2 yCoord(car(last(p1)))) + yCoord(cadr(segLow)) y2 yCoord(car(last(p1))) ) + ) + (if (Ru_IsBetween(xCoord(car(last(p1))) xCoord(car(last(p2))) xCoord(cadr(segLow))) && + Ru_IsBetween(yCoord(cadr(segHi)) y1 yCoord(car(last(p2)))) ) || + (Ru_IsBetween(xCoord(car(last(p2))) xCoord(car(last(p1))) xCoord(cadr(segHi))) && + Ru_IsBetween(yCoord(cadr(segLow)) y2 yCoord(car(last(p1)))) ) then + swapY = t + (if debug >= 1 printf("#### SwapY seg %d\n" cnt)) + ) + ) + (cond + (swapX + p1 = append(p1 list(x2:y1)) + p2 = append(p2 list(x1:y2)) + ;dbCreatePath((geGetEditCellView) list("M7" "bus") p1 0.8) + ;dbCreatePath((geGetEditCellView) list("M4" "bus") p2 0.8) + ) + (swapY + p1 = append(p1 list(x1:y2)) + p2 = append(p2 list(x2:y1)) + ;dbCreatePath((geGetEditCellView) list("M7" "bus") p1 0.8) + ;dbCreatePath((geGetEditCellView) list("M4" "bus") p2 0.8) + ) + (t + p1 = append(p1 list(x1:y1)) + p2 = append(p2 list(x2:y2)) + ) + ) + lastSegDir = segDir + ) + x1 = xCoord(car(last(lowerBound))) + x2 = xCoord(car(last(upperBound))) + y1 = yCoord(car(last(lowerBound))) + y2 = yCoord(car(last(upperBound))) + (cond + (swapX + p1 = append(p1 list(x2:y1)) + p2 = append(p2 list(x1:y2)) + ) + (swapY + p1 = append(p1 list(x1:y2)) + p2 = append(p2 list(x2:y1)) + ) + (t + p1 = append(p1 list(x1:y1)) + p2 = append(p2 list(x2:y2)) + ) + ) + list(p1 p2) + ) +) + +(defun Ru_GetChannelPattern (nodeType nodeList freeTrackList startIdx) + (let (node nodeBaseName size type result es ee nodeCnt nodeStr arraySize + freeTrack trackCnt inlvStr channelList numTracks) + nodeCnt = 0 + numTracks = 0 + (foreach node nodeList + result = Ru_NodeNameToLable(nth(0 node)) + nodeBaseName = nth(2 result) + size = nth(1 node) + type = nth(2 node) + arraySize = (if size parseString(size ",") size) + (cond + (arraySize==nil + freeTrack = nth((numTracks+startIdx) freeTrackList) + name = sprintf(nil "\".%s\"" nodeBaseName) + (if !freeTrack freeTrack = list(99 "BusMetalXX")) + (cond + (rexMatchp("1of2" nodeType) || rexMatchp("1of3" nodeType) || rexMatchp("1of4" nodeType) + inlvStr = "A" + (if mod(nodeCnt 2)==1 then inlvStr = "B" numTracks++) + nodeStr = sprintf(nil "inlv_%s_%s" nodeType inlvStr) + (if rexMatchp("1of2" nodeType) nodeStr = strcat(nodeStr "3")) + ) + (t nodeStr = nodeType numTracks++) + ) + (cond + (cadr(freeTrack) == "BusMetal67" offset = -10000) + (cadr(freeTrack) == "BusMetal45" offset = -1000) + (cadr(freeTrack) == "BusMetal23" offset = -100) + (t offset = 0) + ) + offset = offset + mod(nodeCnt 2)*0.1 ;for sorting _A, _B + nodeCnt++ + ;printf(" (list %-30s %s %2d*TrackPitch %s)\n" name nodeStr car(freeTrack) cadr(freeTrack)) + channelList = append(channelList + list(list(offset+car(freeTrack) sprintf(nil " (list %-30s %s %2d*TrackPitch %s)\n" name nodeStr car(freeTrack) cadr(freeTrack))))) + ) + (length(arraySize)==1 + result = Ru_RangeToInt(size) + (for i car(result) cadr(result) + freeTrack = nth((numTracks+startIdx) freeTrackList) + name = sprintf(nil "\".%s[%d]\"" nodeBaseName i) + (if !freeTrack freeTrack = list(99 "BusMetalXX")) + (cond + (rexMatchp("1of2" nodeType) || rexMatchp("1of3" nodeType) || rexMatchp("1of4" nodeType) + inlvStr = "A" + (if mod(nodeCnt 2)==1 then inlvStr = "B" numTracks++) + nodeStr = sprintf(nil "inlv_%s_%s" nodeType inlvStr) + (if rexMatchp("1of2" nodeType) nodeStr = strcat(nodeStr "3")) + ) + (t nodeStr = nodeType numTracks++) + ) + (cond + (cadr(freeTrack) == "BusMetal67" offset = -10000) + (cadr(freeTrack) == "BusMetal45" offset = -1000) + (cadr(freeTrack) == "BusMetal23" offset = -100) + (t offset = 0) + ) + offset = offset + mod(nodeCnt 2)*0.1 + nodeCnt++ + ;printf(" (list %-30s %s %2d*TrackPitch %s)\n" name nodeStr car(freeTrack) cadr(freeTrack)) + channelList = append(channelList + list(list(offset+car(freeTrack) sprintf(nil " (list %-30s %s %2d*TrackPitch %s)\n" name nodeStr car(freeTrack) cadr(freeTrack))))) + ) + ) + (length(arraySize)==2 + result = Ru_RangeToInt(car(arraySize)) + result2 = Ru_RangeToInt(cadr(arraySize)) + (for i car(result) cadr(result) + (for j car(result2) cadr(result2) + freeTrack = nth((numTracks+startIdx) freeTrackList) + name = sprintf(nil "\".%s[%d][%d]\"" nodeBaseName i j) + (if !freeTrack freeTrack = list(99 "BusMetalXX")) + (cond + (rexMatchp("1of2" nodeType) || rexMatchp("1of3" nodeType) || rexMatchp("1of4" nodeType) + inlvStr = "A" + (if mod(nodeCnt 2)==1 then inlvStr = "B" numTracks++) + nodeStr = sprintf(nil "inlv_%s_%s" nodeType inlvStr) + (if rexMatchp("1of2" nodeType) nodeStr = strcat(nodeStr "3")) + ) + (t nodeStr = nodeType numTracks++) + ) + (cond + (cadr(freeTrack) == "BusMetal67" offset = -10000) + (cadr(freeTrack) == "BusMetal45" offset = -1000) + (cadr(freeTrack) == "BusMetal23" offset = -100) + (t offset = 0) + ) + offset = offset + mod(nodeCnt 2)*0.1 + nodeCnt++ + ;printf(" (list %-30s %s %2d*TrackPitch %s)\n" name nodeStr car(freeTrack) cadr(freeTrack)) + channelList = append(channelList + list(list(offset+car(freeTrack) sprintf(nil " (list %-30s %s %2d*TrackPitch %s)\n" name nodeStr car(freeTrack) cadr(freeTrack))))) + ) + ) + ) + (t error("Unsupported arraySize %L\n" arraySize)) + ) + ) + (if inlvStr == "A" numTracks++) + list(numTracks channelList nodeCnt) + ) +) + +;distribute the pattern evenly +(defun Ru_GenerateFreeTrackList (startTrack endTrack) + (let (freeList right start end) + (if startTrack > endTrack error("start %d must be less than end %d\n" startTrack endTrack)) + start = startTrack + end = endTrack + (while start<=end + (if right then + freeList = append(freeList list(list(end "BusMetal67"))) + end-- + else + freeList = append(freeList list(list(start "BusMetal67"))) + start++ + ) + right = !right + ) + start = startTrack + end = endTrack + (while start<=(end-4) + (if right then + freeList = append(freeList list(list(end "BusMetal45"))) + end-- + else + freeList = append(freeList list(list(start "BusMetal45"))) + start++ + ) + right = !right + ) + start = startTrack + end = endTrack + (while start<=(end-4) + (if right then + freeList = append(freeList list(list(end "BusMetal23"))) + end-- + else + freeList = append(freeList list(list(start "BusMetal23"))) + start++ + ) + right = !right + ) + freeList + ) +) + +(defun GenerateChannelPattern (nodeColList @key (channelName "XXX") (colList nil) (colMaxTrack nil)) + (let (nodeName node cnt size type label nodeType name addNext result el + colCnt col bufName bufNodeName nodeEntries nodeBaseName nodeList nodeCnt totalNode + e1of1List e1of2List e1of3List e1of4List chanDftList channelList + trackCnt totalTracks freeTrackList startTrack endTrack) + printf(";Pattern auto generated by GenerateChannelPattern. Edit X to assign track\n") + printf("%sBusPattern = (DefChan\n" channelName) + printf(" (list\n") + + totalTracks = 0 + totalNode = 0 + startTrack = 0 + (if !colList then + colCnt = 0 + (if stringp(car(car(nodeColList))) nodeColList = list(nodeColList)) + (foreach nodeList nodeColList + (if colMaxTrack then + endTrack = nth(colCnt colMaxTrack) + else + trackCnt = 0 + (foreach node nodeList + size = nth(1 node) + result = Ru_RangeToInt(size) + (if size then + trackCnt = trackCnt + cadr(result) - car(result) + 1 + else trackCnt++) + ) + endTrack = ceiling((trackCnt/2+6)/3.0/2)*2 - 1;assume one column + printf("No colMaxTrack specified: Estimated TotalTracks %L, TotalNodeCnt\n" endTrack+1 trackCnt) + ) + freeTrackList = Ru_GenerateFreeTrackList(startTrack endTrack) + startTrack = endTrack+1 + + colCnt++ + trackCnt = 0 + nodeCnt = 0 + e1of1List = nil + e1of2List = nil + e1of3List = nil + e1of4List = nil + chanDftList = nil + channelList = nil + (if length(nodeColList)!=1 printf(";Column #%d: \n%L\n" colCnt nodeColList)) + (foreach node nodeList + type = nth(2 node) + (cond + (rexMatchp("1of1" type) e1of1List = append(e1of1List list(node))) + (rexMatchp("1of2" type) e1of2List = append(e1of2List list(node))) + (rexMatchp("1of3" type) e1of3List = append(e1of3List list(node))) + (rexMatchp("1of4" type) e1of4List = append(e1of4List list(node))) + (rexMatchp("ChanDft" type) chanDftList = append(chanDftList list(node))) + (t error("Unsupported type: %L\n" type)) + ) + ) + result = Ru_GetChannelPattern("ChanDft2" chanDftList freeTrackList trackCnt) + (if cadr(result) then channelList = append(channelList cadr(result)) trackCnt = trackCnt + car(result) nodeCnt = nodeCnt + nth(2 result)) + result = Ru_GetChannelPattern("e1of4" e1of4List freeTrackList trackCnt) + (if cadr(result) then channelList = append(channelList cadr(result)) trackCnt = trackCnt + car(result) nodeCnt = nodeCnt + nth(2 result)) + result = Ru_GetChannelPattern("e1of3" e1of3List freeTrackList trackCnt) + (if cadr(result) then channelList = append(channelList cadr(result)) trackCnt = trackCnt + car(result) nodeCnt = nodeCnt + nth(2 result)) + result = Ru_GetChannelPattern("e1of2" e1of2List freeTrackList trackCnt) + (if cadr(result) then channelList = append(channelList cadr(result)) trackCnt = trackCnt + car(result) nodeCnt = nodeCnt + nth(2 result)) + result = Ru_GetChannelPattern("e1of1" e1of1List freeTrackList trackCnt) + (if cadr(result) then channelList = append(channelList cadr(result)) trackCnt = trackCnt + car(result) nodeCnt = nodeCnt + nth(2 result)) + totalTracks = totalTracks + trackCnt + totalNode = totalNode + nodeCnt + channelList = sort(channelList 'Ru_SortCarChannelElByTrack) + + (foreach el channelList + printf("%s" cadr(el)) + ) + printf(";Column #%d: %d channels using %d tracks\n" colCnt nodeCnt trackCnt) + ) + else +error("Need proper support for ?colList option\n") + colCnt = 0 + rexMagic(nil) + (foreach col colList + printf(";Column #%d: \n%L\n" colCnt col) + colCnt++ + (foreach bufName nth(length(col)/2 col) ; get the middle one, assume it has all the entries + matchNode = nil + (foreach node nodeColList + nodeBaseName = nth(0 node) + size = nth(1 node) + result = Ru_RangeToInt(size) + es = car(result) + ee = cadr(result) + nodeEntries = nil + (if !size then + nodeEntries = append(nodeEntries list(nodeBaseName)) + else + (for i es ee + nodeEntries = append(nodeEntries list(sprintf(nil "%s[%d]" nodeBaseName i))) + ) + ) + + ;printf("bufName: %L nodeBaseName: %L nodeEntries: %L\n" bufName nodeBaseName nodeEntries) + (foreach nodeName nodeEntries + ;FIXME might need to make this more accurate + (if !matchNode && rexMatchp(nodeName bufName) then + ;printf("bufName: %L node: %L\n" bufName nodeName) + label = Ru_ReplaceDotWithDash(nodeName) + size = nth(1 node) + type = nth(2 node) + nodeType = "e1of4" + addNext = nil + (cond + (rexMatchp("FAST_MBUF_2_1of2" type) nodeType = "inlv_e1of2_X" addNext = t) + (rexMatchp("FAST_MBUF_4" type) nodeType = "inlv_e1of4_X" addNext = t) + (rexMatchp("1of1" type) nodeType = "e1of1") + (rexMatchp("1of2" type) nodeType = "inlv_e1of2_X") + (rexMatchp("1of3" type) nodeType = "e1of3") + (rexMatchp("1of4" type) nodeType = "inlv_e1of4_X") + (t error("Unsupported type: %L\n" type)) + ) + name = sprintf(nil "\".%s\"" nodeName) + printf(" (list %-30s %s x*TrackPitch BusMetal67)\n" name nodeType) + (if addNext then + result = parseString(nodeName "[]") + (if length(result)!=2 error("Unexpected nodeName %L\n" nodeName)) + name = sprintf(nil "\".%s[%d]\"" car(result) Ru_StringToInt(cadr(result))+1) + printf(" (list %-30s %s x*TrackPitch BusMetal67)\n" name nodeType) + ) + ) + + ) + ) + ) + ) + rexMagic(t) + ) + printf(" )\n") + printf(")\n\n\n") + printf(";This %d channels can fit into %.1f tracks wide using %d columns\n" totalNode (totalTracks+6*colCnt)/3.0 colCnt) + ) +) + +;Dump the node order based on pin pattern +(defun DumpNodeOrder (pattern) + (let (lastName el offset nameList result name) + lastName = "" + (foreach el pattern + result= parseString(nth(0 el) ".") + name = car(result) + (for cnt 1 length(result)-2 + name = strcat(name ".") + name = strcat(name nth(cnt result)) + ) + (if lastName != name then + offset = -nth(2 el) + nameList = append(nameList list(list(offset name))) + ) + lastName = name + ) + nameList = sort(nameList 'Ru_SortCarChannelElByTrack) + (foreach el nameList + (if cadr(el) != "GND" then + printf("Offset: %8.1f(%4.0fT) %L\n" -car(el) -car(el)/TrackPitch cadr(el)) + ) + ) + t + ) +) + +(defun GetColIndex (colCfg offset) + (prog (el colIdx) + colIdx = 0 + offset = offset/TrackPitch + (foreach el colCfg + (if (el+1) > offset return(colIdx)) + colIdx++ + ) + return(colIdx) + ) +) +;colMaxTrack, busPattern - given a bus pattern generate columns specified by colMaxTrack +;segRange - only generate from given range +;inlinePrefix - for inline routing +;prefix - for multiple paths in a single cell +(defun GenerateMbuf (nodeList @key (nMbufs nil) (numColumns 1) (colMaxTrack nil) (busPattern nil) + (reverseList nil) (sortPattern nil) (segRange nil) (lastSeg nil) (startSeg 9999) + (resetGroup nil) (resetBaseName "Reset") (noReset nil) + (reverseResetDir nil) (collapseSegList nil) (inlinePrefix "") (prefix "") + (debug 0) ) + (prog (nodeName mbufList n i size type label nodeDir name col1 col2 range nodeMin nodeMax arrayStr + segMbufs bufPrefix leftRightList el offset segMbufsOff es ee ss se temp addSeg nestedArray + resetBase endSeg maxSeg result result2 collapseSeg entry resetN busOffset segList) + + (if resetBaseName == "Reset" && prefix != "" resetBaseName = strcat(resetBaseName prefix)) + segment = t + (if !resetGroup resetGroup = resetBaseName) + (foreach node nodeList + (if length(node) > 3 segment = nil) + ) + (if busPattern && !colMaxTrack error("colMaxTrack must be specified when busPattern is specified\n")) + (if !busPattern && colMaxTrack error("Pattern must be specified when colMaxTrack is specified\n")) + + (if segment then + (foreach node nodeList + result = Ru_NodeNameToLable(nth(0 node)) + label = car(result) + nodeDir = cadr(result) + bufPrefix = sprintf(nil "%smbuf%s%s" inlinePrefix prefix nodeDir) + size = nth(1 node) + type = nth(2 node) + arraySize = (if size parseString(size ",") size) + (cond + (arraySize==nil mbufList = append(mbufList list(sprintf(nil "%smbuf%s_%s" inlinePrefix prefix label)))) + (length(arraySize)==1 + result = Ru_RangeToInt(car(arraySize)) + (for i car(result) cadr(result) + mbufList = append(mbufList list(sprintf(nil "%s_%s[%d]" bufPrefix label i))) + ) + ) + (length(arraySize)==2 ;2-D array both at end + result = Ru_RangeToInt(car(arraySize)) + result2 = Ru_RangeToInt(cadr(arraySize)) + (for i car(result) cadr(result) + (for j car(result2) cadr(result2) + mbufList = append(mbufList list(sprintf(nil "%s_%s[%d][%d]" bufPrefix label i j))) + ) + ) + ) + (t error("Unsupported arraySize %L\n" arraySize)) + ) + ) + return(mbufList) + ) + + (if !nMbufs then + + endSeg = 0 + maxSeg = 0 + (foreach node nodeList + seg = nth(3 node) + result = Ru_RangeToInt(seg) + se = cadr(result) + (if maxSeg < se maxSeg = se) + ) + declare(segBufList[maxSeg+1]) + declare(segMbufsOff[maxSeg+1]) + declare(mbufCol[maxSeg+1]) + (for n 0 maxSeg segBufList[n] = nil) + (for n 0 maxSeg segMbufsOff[n] = nil) + (for n 0 maxSeg mbufCol[n] = nil) + numCols = 1 + (if colMaxTrack numCols = length(colMaxTrack)) + declare(colList[numCols+1]) + (for n 0 numCols colList[n] = nil) + + + (foreach node nodeList + collapseSeg = nth(5 node) + (if collapseSeg then + result = parseString(collapseSeg ",") + (foreach entry result + (if !member(entry collapseSegList) collapseSegList = append(collapseSegList list(entry))) + ) + ) + ) +(if collapseSegList printf("collapseSegList: %L\n" collapseSegList)) + + (foreach node nodeList + result = Ru_NodeNameToLable(nth(0 node)) + label = car(result) + nodeDir = cadr(result) + nodeName = nth(2 result) + bufPrefix = sprintf(nil "%smbuf%s%s" inlinePrefix prefix nodeDir) + size = nth(1 node) + type = nth(2 node) + seg = nth(3 node) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + resetBase = nth(4 node) + (if !resetBase resetBase = resetBaseName) + + (if resetGroup == resetBase then + (if startSeg > ss startSeg = ss) + (if endSeg < se endSeg = se) + collapseSeg = nil + (if nth(5 node) then + collapseSeg = parseString(nth(5 node) ",") + ) + ;check for nested array + nestedArray = nil + temp = parseString(nodeName "[]") + (if length(temp) == 3 then + range = parseString(nth(1 temp) "-") + (if length(range) == 2 then + nodeMin = Ru_StringToInt(car(range)) + nodeMax = Ru_StringToInt(cadr(range)) + else + printf("ERROR: Unhandled node format %L\n" node) + ) + nodeName = strcat(nth(0 temp) nth(2 temp)) + temp = parseString(label "[]") + (if length(temp) != 3 error("Unexpected lable %L\n" label)) + label = strcat(nth(0 temp) nth(2 temp)) + nestedArray = t + else + nodeMin = -1 + nodeMax = -1 + ) + + (for aidx nodeMin nodeMax + (if aidx >=0 then arrayStr = sprintf(nil "[%d]" aidx) + else arrayStr = "") + +(if lastSeg ss = se) + (for n ss se + (if !member(sprintf(nil "%d" n) collapseSeg) then + arraySize = (if size parseString(size ",") size) + (cond + (arraySize==nil + busOffset = 0 + (if busPattern then + name = sprintf(nil ".%s.e" nodeName) + busOffset = Ru_GetChannelNodeOffset(busPattern name ?nestedArray nestedArray) + (if !busOffset error("Unable to find %s in busPattern %L\n" name busPattern)) + ) + (if sortPattern then + name = sprintf(nil ".%s.e" nodeName) + offset = Ru_GetChannelNodeOffset(sortPattern name ?nestedArray nestedArray) + (if !offset error("Unable to find %s in sortPattern %L\n" name sortPattern)) + segMbufsOff[n] = append(segMbufsOff[n] list(list(offset sprintf(nil "%s_%s%s[%d]" bufPrefix label arrayStr n) busOffset))) + else + bufName = sprintf(nil "%s_%s%s[%d]" bufPrefix label arrayStr n) + segBufList[n] = append(segBufList[n] list(list(bufName busOffset))) + ) + ) + (length(arraySize)==1 + (if type == "FAST_MBUF_4" || type == "FAST_MBUF_2_1of2" then + error("No support for %L\n" type) + else + result = Ru_RangeToInt(car(arraySize)) + (for i car(result) cadr(result) + busOffset = 0 + (if busPattern then + name = sprintf(nil ".%s[%d].e" nodeName i) + busOffset = Ru_GetChannelNodeOffset(busPattern name ?nestedArray nestedArray) + (if !busOffset error("Unable to find %s in busPattern %L\n" name busPattern)) + ) + (if sortPattern then + name = sprintf(nil ".%s[%d].e" nodeName i) + offset = Ru_GetChannelNodeOffset(sortPattern name ?nestedArray nestedArray) + (if !offset error("Unable to find %s in sortPattern %L\n" name sortPattern)) + segMbufsOff[n] = append(segMbufsOff[n] list(list(offset sprintf(nil "%s_%s%s[%d][%d]" bufPrefix label arrayStr i n) busOffset))) + else + bufName = sprintf(nil "%s_%s%s[%d][%d]" bufPrefix label arrayStr i n) + segBufList[n] = append(segBufList[n] list(list(bufName busOffset))) + ) + ) + ) + ) + (length(arraySize)==2 + result = Ru_RangeToInt(car(arraySize)) + result2 = Ru_RangeToInt(cadr(arraySize)) + (for i car(result) cadr(result) + (for j car(result2) cadr(result2) + busOffset = 0 + (if busPattern then + name = sprintf(nil ".%s[%d][%d].e" nodeName i j) + busOffset = Ru_GetChannelNodeOffset(busPattern name ?nestedArray nestedArray) + (if !busOffset error("Unable to find %s in busPattern %L\n" name busPattern)) + ) + (if sortPattern then + name = sprintf(nil ".%s[%d][%d].e" nodeName i j) + offset = Ru_GetChannelNodeOffset(sortPattern name ?nestedArray nestedArray) + (if !offset error("Unable to find %s in sortPattern %L\n" name sortPattern)) + segMbufsOff[n] = append(segMbufsOff[n] list(list(offset sprintf(nil "%s_%s%s[%d][%d][%d]" bufPrefix label arrayStr i j n) busOffset))) + else + bufName = sprintf(nil "%s_%s%s[%d][%d][%d]" bufPrefix label arrayStr i j n) + segBufList[n] = append(segBufList[n] list(list(bufName busOffset))) + ) + ) + ) + ) + (t error("Unsupported arraySize %L\n" arraySize)) + ) ;cond + ) ;collapseList + ) ;for + ) ;for arrayIdx + ) + ) + (for n startSeg endSeg + (if segRange==nil || (n>=car(segRange) && n<=cadr(segRange)) then + addSeg = nil + (if segMbufsOff[n] then + segMbufsOff[n] = sort(segMbufsOff[n] 'Ru_SortCarChannelElByTrack) + (foreach el segMbufsOff[n] + busOffset = nth(2 el) + colIdx = GetColIndex(colMaxTrack busOffset) +;printf("colIdx1 %L el %L bufOffset %L\n" colIdx el busOffset) + colList[colIdx] = append(colList[colIdx] list(cadr(el))) + ) + else + segList = nil + (if busPattern then ;FIXME + (foreach el segBufList[n] + busOffset = nth(1 el) + colIdx = GetColIndex(colMaxTrack busOffset) +;printf("colIdx3 %L el %L bufOffset %L\n" colIdx el busOffset) +; segList = append(segList list(car(el))) + colList[colIdx] = append(colList[colIdx] list(car(el))) + ) + (if reverseList error("No support with busPattern\n")) +; colList[colIdx] = append(colList[colIdx] segList) + else + (foreach el segBufList[n] + busOffset = nth(1 el) + colIdx = GetColIndex(colMaxTrack busOffset) ;FIXME might have a problem if this is different +;printf("colIdx2 %L el %L bufOffset %L\n" colIdx el busOffset) + segList = append(segList list(car(el))) + ;colList[colIdx] = append(colList[colIdx] list(car(el))) + ) + (if reverseList segList = reverse(segList)) ;only reverse per segment + colList[colIdx] = append(colList[colIdx] segList) + ) +;printf("reverseList %L colIdx %L %L\n" reverseList colIdx colList[colIdx]) + ) + segMbufs = append(segMbufs addSeg) + + (if !resetN resetN = n) + (if member(sprintf(nil "%d" n+1) collapseSegList) then + (if nil printf("Seg#%d is collapse to previous segment\n" n+1)) + else + (for colIdx 0 numCols-1 + (if !noReset && colIdx==0 then + (if reverseResetDir then + ;reset at end of column + colList[colIdx] = append(colList[colIdx] list(sprintf(nil "ramp%s[%d]" resetGroup resetN) sprintf(nil "buf%s[%d]" resetGroup resetN) )) + else + colList[colIdx] = append(list(sprintf(nil "buf%s[%d]" resetGroup resetN) sprintf(nil "ramp%s[%d]" resetGroup resetN) ) colList[colIdx]) + ) + ) + mbufCol[colIdx] = append(mbufCol[colIdx] list(colList[colIdx])) +;printf("Seg#%d COL#%L: %L\n" n colIdx colList[colIdx]) + colList[colIdx] = nil + ) + resetN = nil + ) + ) + ) + mbufList = nil + (if numCols == 1 then + mbufList = mbufCol[0] +;printf("COL%d: %L\n" colIdx mbufCol[0]) + else + (for colIdx 0 numCols-1 +;printf("COL#%d: %L\n" colIdx mbufCol[colIdx]) + mbufList = append(mbufList list(mbufCol[colIdx])) + ) + ) + else ; all segments having the same number of buffers + ; deprecated + (for n 0 nMbufs-1 + segMbufs = nil + segMbufsOff = nil + segMbufs = append(segMbufs list(sprintf(nil "bufReset[%d]" n))) + segMbufs = append(segMbufs list(sprintf(nil "rampReset[%d]" n))) + + (foreach node nodeList + nodeName = nth(0 node) + label = Ru_ReplaceDotWithDash(nodeName) + size = nth(1 node) + type = nth(2 node) + (if !size || size < 0 then + (if sortPattern then + name = sprintf(nil ".%s.e" nodeName) + offset = Ru_GetChannelNodeOffset(sortPattern name) + (if !offset error("Unable to find %s in sortPattern %L\n" name sortPattern)) + segMbufsOff = append(segMbufsOff list(list(offset sprintf(nil "mbuf_%s[%d]" label n)))) + else + segMbufs = append(segMbufs list(sprintf(nil "mbuf_%s[%d]" label n))) + ) + else + (for i 0 size-1 + (if sortPattern then + name = sprintf(nil ".%s[%d].e" nodeName i) + offset = Ru_GetChannelNodeOffset(sortPattern name) + (if !offset error("Unable to find %s in sortPattern %L\n" name sortPattern)) + segMbufsOff = append(segMbufsOff list(list(offset sprintf(nil "mbuf_%s[%d][%d]" label i n)))) + else + segMbufs = append(segMbufs list(sprintf(nil "mbuf_%s[%d][%d]" label i n))) + ) + ) + ) + ) + (if segMbufsOff then + segMbufsOff = sort(segMbufsOff 'Ru_SortCarChannelElByTrack) + + segMbufs = nil + (foreach el segMbufsOff + segMbufs = append(segMbufs list(cadr(el))) + ) + ) + (if reverseList segMbufs = reverse(segMbufs)) + (cond + (numColumns==1 mbufList = append(mbufList list(list(segMbufs)))) + (numColumns==2 + leftRightList = Ru_SplitList(segMbufs (length(segMbufs)+1)/2) + (if reverseList leftRightList = reverse(leftRightList)) + mbufList = append(mbufList list(leftRightList)) + ) + (t error("Ru_GenerateMbuf: No support for numColumns = %d\n")) + ) + ) + ) + (if !mbufList then + error("No buffer found: nodeList %L \n in resetGroup %L resetBase %L resetBaseName %L\n" nodeList resetGroup resetBase resetBaseName) + ) + return(mbufList) + ) +) + +(defun Ru_RangeToInt (range) + (let (es ee result) + (if range && integerp(range) then + es = 0 + ee = range + ) + (if range && !integerp(range) then + result = parseString(range ".") + es = Ru_StringToInt(car(result)) + ee = Ru_StringToInt(cadr(result)) + ) + list(es ee) + ) +) + +(defun Ru_NodeNameToLable (nodeStr) + (let (nodeDir label nodeName) + nodeDir = "" + nodeName = nodeStr + (cond + (substring(nodeName 1 1) == "-" + nodeDir = "r" + nodeName = substring(nodeStr 2 strlen(nodeStr)-1) + ) + (substring(nodeName 1 1) == "+" + nodeName = substring(nodeStr 2 strlen(nodeStr)-1) + ) + ) + label = Ru_ReplaceDotWithDash(nodeName) + list(label nodeDir nodeName) + ) +) +;nMbufs - assume all channels have the same number of buffers and generate slack directive +(defun GenerateCast (nodeList @key (inPrefix "L") (outPrefix "R") (channelName "XXX") + (implicitReset nil) (collapse "") (inline nil) (prefix "") (nMbufs nil) + (resetBaseName "Reset") (reverseResetDir nil)) + (prog (nodeName nodeStr node size arraySize type label nodeDir nodeType seg es ee ss se result result2 + str passthru collapseSeg collapseSegList collapseSegStrA collapseSegStrB entry hasCollapseSeg + startSeg endSeg resetBase el resetList resetStartSeg resetEndSeg bufPrefix wirePrefix + parseNode range nodeMin nodeMax parseLabel nestedArray directive) + + segment = t + (if inPrefix == "L" && prefix != "" inPrefix = strcat(inPrefix prefix)) + (if outPrefix == "R" && prefix != "" outPrefix = strcat(outPrefix prefix)) + (if resetBaseName == "Reset" && prefix != "" resetBaseName = strcat(resetBaseName prefix)) + (foreach node nodeList + (if length(node) > 3 segment = nil) + ) + (if segment then + printf("\n\n") + printf("define ROUTE_%s_XX() (%s -L, +R; node -_L_RESET, +_R_RESET)\n" channelName channelName) + printf(" <+ AltaConstants <+ routed <+ floorplan_hierarchy <: NO_RESET_CELL {\n") + printf(" /*Auto generated by GenerateCast()*/\n") + printf(" subcells {\n") + printf(" node _RESET;\n") + printf(" RAMP_RESET ramp%s(_L_RESET,_RESET);\n" resetBaseName) + printf(" BUF_RESET buf%s(_RESET,_R_RESET);\n" resetBaseName) + (foreach node nodeList + nodeName = nth(0 node) + result = Ru_NodeNameToLable(nodeName) + label = car(result) + nodeDir = cadr(result) + size = nth(1 node) + result = Ru_RangeToInt(size) + es = car(result) + ee = cadr(result) + type = nth(2 node) + (if type then + (if !size then + printf(" %s mbuf_%s (%s.%s,%s.%s);\n" + type label inPrefix label outPrefix label) + else + result = sprintf(nil "%d..%d:" es ee) + printf(" \n" + result type label inPrefix label outPrefix label) + ) + else + passthru = t + printf(" %s.%s = %s.%s;\n" outPrefix nodeName inPrefix nodeName) + ) + ) + printf("\n") + printf(" }\n") + (if passthru printf(" directives { wiring = true; }\n")) + printf("}\n") + printf("\n\n") + return(t) + ) + printf("\n\n") + (if inline then + printf("define PATH_%s() (\n" channelName) + (foreach node nodeList + result = Ru_NodeNameToLable(nth(0 node)) + label = car(result) + size = nth(1 node) + result = Ru_RangeToInt(size) + ee = cadr(result) + type = nth(2 node) + (if type then + cond( + (rexMatchp("1of4" type) nodeType = "e1of4") + (rexMatchp("1of3" type) nodeType = "e1of3") + (rexMatchp("1of2" type) nodeType = "e1of2") + (rexMatchp("1of1" type) nodeType = "e1of1") + (rexMatchp("ChanDft" type) + (if !rexMatchp("^DFT" label) error("ChanDft channel must start with DFT but got %L\n" label)) + nodeType = "ChanDft" + ) + (t error("Unsupported type %L\n" type)) + ) + (if !size then printf(" %s -%s_%s, +%s_%s;\n" nodeType inPrefix label outPrefix label) + else printf(" %s[%d] -%s_%s, +%s_%s;\n" nodeType ee+1 inPrefix label outPrefix label )) + ) + ) + else printf("define PATH_%s() (%s -%s, +%s;\n" channelName channelName inPrefix outPrefix)) + (if implicitReset then printf(" )\n") + else printf(" node -_L_RESET, +_R_RESET)\n")) + printf(" <+AltaAssemblyConstants\n") + printf(" <+AltaConstants\n") + printf(" <+routed\n") + printf(" <+floorplan_hierarchy {\n") + printf(" /*Auto generated by GenerateCast()*/\n") + (if nMbufs then + printf(" int NBUFS = %d; //Adjust to change number of buffers segments\n\n" nMbufs) +directive = t + ) + (if directive then + (foreach node nodeList + nodeStr = nth(0 node) + result = Ru_NodeNameToLable(nodeStr) + label = car(result) + printf(" float T_%s = 0.0;\n" label) + ) + printf("\n") + ) + printf(" subcells {\n") + (if t then + startSeg = 9999 + endSeg = 0 + ;Node declaration + (foreach node nodeList + nodeStr = nth(0 node) + result = Ru_NodeNameToLable(nodeStr) + label = car(result) + nodeDir = cadr(result) + nodeName = nth(2 result) + wirePrefix = sprintf(nil "w%s%s" prefix nodeDir) + size = nth(1 node) + type = nth(2 node) + + (if type then + (if nMbufs then + startSeg = 0 + endSeg = nil ;should not be used + ss = 0 + endSegStr = "(NBUFS-1)" + endSegStr1 = "NBUFS" + else + seg = nth(3 node) + (if !seg error("Must specify number of segments\n")) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + (if startSeg > ss startSeg = ss) + (if endSeg < se endSeg = se) + endSegStr = sprintf(nil "%d" se) + endSegStr1 = sprintf(nil "%d" se+1) + ) + nodeType = "UNKNOWN" + cond( + (rexMatchp("1of4" type) nodeType = "e1of4") + (rexMatchp("1of3" type) nodeType = "e1of3") + (rexMatchp("1of2" type) nodeType = "e1of2") + (rexMatchp("1of1" type) nodeType = "e1of1") + (rexMatchp("ChanDft" type) + (if !rexMatchp("^DFT" label) error("ChanDft channel must start with DFT but got %L\n" label)) + nodeType = "ChanDft" + ) + ) + arraySize = (if size parseString(size ",") nil) + ;check for nested array + parseNode = parseString(nodeName "[]") + (if length(parseNode) == 3 then + range = parseString(nth(1 parseNode) "-") + (if length(range) == 2 then + nodeMin = Ru_StringToInt(car(range)) + nodeMax = Ru_StringToInt(cadr(range)) + arraySize = append(list(sprintf(nil "%d..%d" nodeMin nodeMax)) arraySize ) + parseLabel = parseString(label "[]") + (if length(parseLabel) != 3 error("Unexpected lable %L\n" label)) + label = strcat(nth(0 parseLabel) nth(2 parseLabel)) + ) + ) + + (cond + (arraySize==nil printf(" %s %s_%s[%d..%s];\n" nodeType wirePrefix label ss endSegStr1)) + (length(arraySize)==1 + result = Ru_RangeToInt(car(arraySize)) + printf(" %s %s_%s[%d..%d,%d..%s];\n" nodeType wirePrefix label car(result) cadr(result) ss endSegStr1) + ) + (length(arraySize)==2 + result = Ru_RangeToInt(car(arraySize)) + result2 = Ru_RangeToInt(cadr(arraySize)) + printf(" %s %s_%s[%d..%d,%d..%d,%d..%s];\n" nodeType wirePrefix label car(result) cadr(result) car(result2) cadr(result2) ss endSegStr1) + ) + (t error("Unsupported arraySize %L\n" arraySize)) + ) + ) + ) + printf("\n") + printf(" node w_buf%s[%d..%s];\n" resetBaseName startSeg (if nMbufs endSegStr1 sprintf(nil "%d" endSeg+1))) + printf(" node w_ramp%s[%d..%s];\n" resetBaseName startSeg (if nMbufs endSegStr sprintf(nil "%d" endSeg))) + (if implicitReset then + printf(" w_buf%s[%d] = _RESET;\n" resetBaseName startSeg) + else + (if reverseResetDir printf(" //Reset is in reverse direction\n")) + printf(" w_buf%s[%d] = %s;\n" resetBaseName startSeg (if reverseResetDir "_R_RESET" "_L_RESET")) + ) + ;L wires + (foreach node nodeList + nodeStr = nth(0 node) + result = Ru_NodeNameToLable(nodeStr) + label = car(result) + nodeDir = cadr(result) + nodeName = nth(2 result) + wirePrefix = sprintf(nil "w%s%s" prefix nodeDir) + size = nth(1 node) + type = nth(2 node) + collapseSeg = nth(5 node) + (if collapseSeg then + hasCollapseSeg = t + result = parseString(collapseSeg ",") + (foreach entry result + (if !member(entry collapseSegList) collapseSegList = append(collapseSegList list(entry))) + ) + ) + (if type then + (if nMbufs then + ss = 0 + else + seg = nth(3 node) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + ) + arraySize = (if size parseString(size ",") nil) + ;check for nested array + nestedArray = nil + parseNode = parseString(nodeName "[]") + (if length(parseNode) == 3 then + range = parseString(nth(1 parseNode) "-") + (if length(range) == 2 then + nodeMin = Ru_StringToInt(car(range)) + nodeMax = Ru_StringToInt(cadr(range)) + parseLabel = parseString(label "[]") + (if length(parseLabel) != 3 error("Unexpected lable %L\n" label)) + label = strcat(nth(0 parseLabel) nth(2 parseLabel)) + nestedArray = t + ) + ) + (cond + (arraySize==nil + (if nestedArray then + str = sprintf(nil "%d..%d:" nodeMin nodeMax) + printf(" \n" + str wirePrefix label ss + inPrefix (if inline "_" ".") nth(0 parseNode) nth(2 parseNode)) + else + printf(" %s_%s[%d] = %s%s%s;\n" + wirePrefix label ss inPrefix (if inline "_" ".") nodeName) + ) + ) + (length(arraySize)==1 + (if nestedArray then + result = Ru_RangeToInt(car(arraySize)) + printf(" \n" + str wirePrefix label ss + inPrefix (if inline "_" ".") nth(0 parseNode) nth(2 parseNode)) + printf(" >\n") + else + result = Ru_RangeToInt(car(arraySize)) + str = sprintf(nil "%d..%d:" car(result) cadr(result)) + printf(" \n" + str wirePrefix label ss + inPrefix (if inline "_" ".") nodeName) + ) + ) + (length(arraySize)==2 + (if nestedArray error("No support yet\n")) + result = Ru_RangeToInt(car(arraySize)) + result2 = Ru_RangeToInt(cadr(arraySize)) + printf(" \n" + str wirePrefix label ss + inPrefix (if inline "_" ".") nodeName) + printf(" >\n") + ) + (t error("Unsupported arraySize %L\n" arraySize)) + ) + ) + ) + printf("\n") + + printf(" \n" collapse collapseSegStrA)) + (if reverseResetDir then + printf(" BUF_RESET buf%s[n](w_buf%s[n+1],w_buf%s[n]);\n" resetBaseName resetBaseName resetBaseName) + printf(" RAMP_RESET ramp%s[n](w_buf%s[n],w_ramp%s[n]);\n" resetBaseName resetBaseName resetBaseName) + else + printf(" BUF_RESET buf%s[n](w_buf%s[n],w_buf%s[n+1]);\n" resetBaseName resetBaseName resetBaseName) + printf(" RAMP_RESET ramp%s[n](w_buf%s[n+1],w_ramp%s[n]);\n" resetBaseName resetBaseName resetBaseName) + ) + (if collapse then + printf(" ]\n") + printf(" [%scollapse_channel_buffering%s ->\n" collapse collapseSegStrB) + printf(" w_buf%s[n] = w_buf%s[n+1];\n" resetBaseName resetBaseName) + printf(" w_buf%s[n+1] = w_ramp%s[n];\n" resetBaseName resetBaseName) + printf(" ]\n") + ) ;collapse + printf(" >\n") + resetList = nil + (foreach node nodeList + resetBase = nth(4 node) + (if resetBase && !member(resetBase resetList) resetList = append(resetList list(resetBase))) + ) + (foreach el resetList + resetStartSeg = 9999 + resetEndSeg = 0 + (foreach node nodeList + resetBase = nth(4 node) + (if resetBase && resetBase==el then + seg = nth(3 node) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + (if resetStartSeg > ss resetStartSeg = ss) + (if resetEndSeg < se resetEndSeg = se) + ) + ) + printf(" //Alternate Reset, edit to hook up to main reset properly\n") + printf(" node w_buf%s[%d..%d];\n" el resetStartSeg resetEndSeg+1) + printf(" node w_ramp%s[%d..%d];\n" el resetStartSeg resetEndSeg) + printf(" \n" collapse collapseSegStrA)) + printf(" BUF_RESET buf%s[n](w_buf%s[n+1],w_buf%s[n]);\n" el el el) + printf(" RAMP_RESET ramp%s[n](w_buf%s[n],w_ramp%s[n]);\n" el el el) + (if collapse then + printf(" ]\n") + printf(" [%scollapse_channel_buffering%s ->\n" collapse collapseSegStrB) + printf(" w_buf%s[n+1] = w_buf%s[n];\n" el el) + printf(" w_buf%s[n] = w_ramp%s[n];\n" el el) + printf(" ]\n") + ) ;collapse + printf(" >\n") + ) + printf("\n") + + ;Buffers + (foreach node nodeList + nodeStr = nth(0 node) + result = Ru_NodeNameToLable(nodeStr) + label = car(result) + nodeDir = cadr(result) + nodeName = nth(2 result) + bufPrefix = sprintf(nil "mbuf%s%s" prefix nodeDir) + wirePrefix = sprintf(nil "w%s%s" prefix nodeDir) + size = nth(1 node) + type = nth(2 node) + (if type then + (if nMbufs then + ss = 0 + endSegStr = "(NBUFS-1)" + endSegStr1 = "NBUFS" + else + seg = nth(3 node) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + endSegStr = sprintf(nil "%d" se) + endSegStr1 = sprintf(nil "%d" se+1) + ) + resetBase = nth(4 node) + (if !resetBase resetBase = resetBaseName) + + printf(" \n" collapse collapseSegStrA)) + printf(" %s %s_%s[n] (%s_%s[n%s],%s_%s[n%s])(Vdd,GND,w_ramp%s[n]);\n" + type bufPrefix label wirePrefix label (if nodeDir == "" "" "+1") + wirePrefix label (if nodeDir == "" "+1" "") resetBase) + (if collapse then + printf(" ]\n") + printf(" [%scollapse_channel_buffering%s ->\n" collapse collapseSegStrB) + printf(" %s_%s[n] = %s_%s[n+1];\n" + wirePrefix label wirePrefix label) + printf(" ]\n") + ) ;collapse + ) + (length(arraySize)==1 + result = Ru_RangeToInt(car(arraySize)) + str = sprintf(nil "%d..%d:" car(result) cadr(result)) + (if collapse printf(" [~%scollapse_channel_buffering%s ->\n" collapse collapseSegStrA)) + printf(" \n" + str type bufPrefix label wirePrefix label (if nodeDir == "" "" "+1") + wirePrefix label (if nodeDir == "" "+1" "") resetBase) + (if collapse then printf(" ]\n") + printf(" [%scollapse_channel_buffering%s ->\n" collapse collapseSegStrB) + printf(" \n" + str wirePrefix label wirePrefix label) + printf(" ]\n") + ) ;collapse + ) + (length(arraySize)==2 + result = Ru_RangeToInt(car(arraySize)) + result2 = Ru_RangeToInt(cadr(arraySize)) + printf(" \n" collapse collapseSegStrA)) + printf(" \n" + str type bufPrefix label wirePrefix label (if nodeDir == "" "" "+1") + wirePrefix label (if nodeDir == "" "+1" "") resetBase) + (if collapse then printf(" ]\n") + printf(" [%scollapse_channel_buffering%s ->\n" collapse collapseSegStrB) + printf(" \n" + str wirePrefix label wirePrefix label) + printf(" ]\n") + printf(" >\n") + ) ;collapse + ) + (t error("Unsupported arraySize %L\n" arraySize)) + ) + printf(" >\n") + ) ;if type + ) + printf("\n") + ;R wires + (foreach node nodeList + nodeStr = nth(0 node) + result = Ru_NodeNameToLable(nodeStr) + label = car(result) + nodeDir = cadr(result) + nodeName = nth(2 result) + wirePrefix = sprintf(nil "w%s%s" prefix nodeDir) + size = nth(1 node) + type = nth(2 node) + (if type then + (if nMbufs then + ss = 0 + endSegStr = "(NBUFS-1)" + endSegStr1 = "NBUFS" + else + seg = nth(3 node) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + endSegStr = sprintf(nil "%d" se) + endSegStr1 = sprintf(nil "%d" se+1) + ) + arraySize = (if size parseString(size ",") nil) + ;check for nested array + nestedArray = nil + parseNode = parseString(nodeName "[]") + (if length(parseNode) == 3 then + range = parseString(nth(1 parseNode) "-") + (if length(range) == 2 then + nodeMin = Ru_StringToInt(car(range)) + nodeMax = Ru_StringToInt(cadr(range)) + parseLabel = parseString(label "[]") + (if length(parseLabel) != 3 error("Unexpected lable %L\n" label)) + label = strcat(nth(0 parseLabel) nth(2 parseLabel)) + nestedArray = t + ) + ) + (cond + (arraySize==nil + (if nestedArray then + str = sprintf(nil "%d..%d:" nodeMin nodeMax) + printf(" \n" + str wirePrefix label endSegStr1 + outPrefix (if inline "_" ".") nth(0 parseNode) nth(2 parseNode)) + else + printf(" %s_%s[%s] = %s%s%s;\n" + wirePrefix label endSegStr1 outPrefix (if inline "_" ".") nodeName) + ) + ) + (length(arraySize)==1 + (if nestedArray then + result = Ru_RangeToInt(car(arraySize)) + printf(" \n" + str wirePrefix label endSegStr1 + outPrefix (if inline "_" ".") nth(0 parseNode) nth(2 parseNode)) + printf(" >\n") + else + result = Ru_RangeToInt(car(arraySize)) + str = sprintf(nil "%d..%d:" car(result) cadr(result)) + printf(" \n" + str wirePrefix label endSegStr1 + outPrefix (if inline "_" ".") nodeName) + ) + ) + (length(arraySize)==2 + result = Ru_RangeToInt(car(arraySize)) + result2 = Ru_RangeToInt(cadr(arraySize)) + printf(" \n" + str wirePrefix label endSegStr1 + outPrefix (if inline "_" ".") nodeName) + printf(" >\n") + ) + (t error("Unsupported arraySize %L\n" arraySize)) + ) + else + passthru = t + printf(" %s.%s = %s%s%s;\n" outPrefix nodeName + inPrefix (if inline "_" ".") nodeName) + ) + ) + (if !implicitReset then + printf(" w_buf%s[%s] = %s;\n" resetBase + (if nMbufs endSegStr1 sprintf(nil "%d" endSeg+1)) + (if reverseResetDir "_L_RESET" "_R_RESET")) + ) + + + else ;same number of buffer for all segments + printf(" int NBUFS = xx;\n\n") + printf(" node w_bufReset[0..NBUFS];\n") + printf(" node w_rampReset[0..NBUFS];\n") + (foreach node nodeList + nodeName = nth(0 node) + label = Ru_ReplaceDotWithDash(nodeName) + size = nth(1 node) + type = nth(2 node) + nodeType = "UNKNOWN" + cond( + (rexMatchp("1of4" type) nodeType = "e1of4") + (rexMatchp("1of3" type) nodeType = "e1of3") + (rexMatchp("1of2" type) nodeType = "e1of2") + (rexMatchp("1of1" type) nodeType = "e1of1") + (rexMatchp("ChanDft" type) nodeType = "ChanDft") + (t error("Unsupported type %L\n" type)) + ) + (if !size || size < 0 then printf(" %s w_%s[0..NBUFS];\n" nodeType label) + else printf(" %s w_%s[0..%d,0..NBUFS];\n" nodeType label size)) + ) + printf("\n\n") + printf(" w_bufReset[0] = _RESET;\n") + (foreach node nodeList + nodeName = nth(0 node) + label = Ru_ReplaceDotWithDash(nodeName) + size = nth(1 node) + type = nth(2 node) + (if !size || size < 0 then printf(" w_%s[0] = %s.%s;\n" label inPrefix nodeName) + else printf(" \n" size label inPrefix nodeName)) + ) + printf("\n\n") + + printf(" \n" + size type label label label) + ) + ) + printf(" >\n") + printf("\n") + (foreach node nodeList + nodeName = nth(0 node) + label = Ru_ReplaceDotWithDash(nodeName) + size = nth(1 node) + type = nth(2 node) + (if !size || size < 0 then printf(" w_%s[NBUFS] = %s.%s;\n" label outPrefix nodeName) + else printf(" \n" size label outPrefix nodeName)) + ) + ) + printf("\n") + printf(" }\n") + ;(if passthru printf(" directives { wiring = true; }\n")) + (if directive then + printf(" directives {\n") + printf(" slacker_leaf = false;\n") + (foreach node nodeList + nodeStr = nth(0 node) + result = Ru_NodeNameToLable(nodeStr) + label = car(result) + nodeDir = cadr(result) + nodeName = nth(2 result) + printf(" slacker_time(%s.%s) = T_%s;\n" inPrefix label label) + printf(" slacker_time(%s.%s) = T_%s + 2.0*NBUFS;\n" outPrefix label label) + ) + printf(" }\n") + ) + + (if !inline then + printf(" env {\n") + printf(" digital {\n") + printf(" subcells {\n") + (if !implicitReset printf(" _RESET = _L_RESET;\n")) + printf(" rsource_%s _(%s);\n" channelName inPrefix) + printf(" bitbucket_%s _(%s);\n" channelName outPrefix) + printf(" }\n") + printf(" directives {\n") + result = Ru_NodeNameToLable(car(car(nodeList))) + nodeName = nth(2 result) + printf(" ntpc_spec(%s.%s%s.e) = 18;\n" outPrefix nodeName (if cadr(car(nodeList)) "[0]" "")) + printf(" }\n") + printf(" }\n") + printf(" }\n") + ) ;inline + printf("}\n") + printf("\n\n") + + (if hasCollapseSeg then + printf("################ Channel Segments: ##################\n") + (foreach node nodeList + seg = nth(3 node) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + collapseSeg = nth(5 node) + result = 0 + (if collapseSeg then + result = length(parseString(collapseSeg ",")) + ) + printf("%-40s: %d\n" nth(0 node) (se-ss+1-result)) + ) + printf("\n\n") + ) + + return(t) + ) +) + +(defun Ru_DumpBundledList (entries name) + (let (cnt) + (if entries then + printf(" (list\n") + printf(" (list %s)\n" name) + cnt = 0 + (foreach el entries + (if mod(cnt 3) == 0 then printf("\n ")) + printf(" %L" el) + cnt++ + ) + printf("\n )\n") + printf(" )\n") + ) + ) +) + +(defun GenerateBundledList (nodeList @key (inPrefix "L") (outPrefix "R")) + (let (nodeName node size type label nodeType seg es ee ss se result + resetBase el resetList resetStartSeg resetEndSeg + e1of1List e1of2List e1of4List e1of2InlvList e1of4InlvList) + printf("; auto-bundled-routing channels\n") + printf("bundled_channels = list( \n") + (if t then + (foreach node nodeList + nodeName = nth(0 node) + label = Ru_ReplaceDotWithDash(nodeName) + size = nth(1 node) + result = Ru_RangeToInt(size) + es = car(result) + ee = cadr(result) + type = nth(2 node) + seg = nth(3 node) + result = Ru_RangeToInt(seg) + ss = car(result) + se = cadr(result) + resetBase = nth(4 node) + (if !resetBase resetBase = "Reset") + +; (for n ss se+1 + (if !size then +; wireName = sprintf(nil "w_%s[%d]" label n) + wireName = sprintf(nil "w_%s[%d..%d]" label ss se+1) + (cond + (rexMatchp("1of1" type) e1of1List = append(e1of1List list(wireName))) + (rexMatchp("1of2" type) e1of2List = append(e1of2List list(wireName))) + (rexMatchp("1of4" type) e1of4List = append(e1of4List list(wireName))) + (t error("Unsupported type: %L\n" type)) + ) + else +; (for i es ee +; wireName = sprintf(nil "w_%s[%d,%d]" label i n) + wireName = sprintf(nil "w_%s[%d..%d,%d..%d]" label es ee ss se+1) + (cond + (rexMatchp("FAST_MBUF_2_1of2" type) e1of2InlvList = append(e1of2InlvList list(wireName))) + (rexMatchp("FAST_MBUF_4" type) e1of4InlvList = append(e1of4InlvList list(wireName))) + (rexMatchp("1of1" type) e1of1List = append(e1of1List list(wireName))) + (rexMatchp("1of2" type) e1of2List = append(e1of2List list(wireName))) + (rexMatchp("1of4" type) e1of4List = append(e1of4List list(wireName))) + (t error("Unsupported type: %L\n" type)) + ) +; ) + ) +; ) + ) + ) + Ru_DumpBundledList(e1of1List "\"e1of1\"") + Ru_DumpBundledList(e1of2List "\"e1of2\"") + Ru_DumpBundledList(e1of4List "\"e1of4\"") + Ru_DumpBundledList(e1of2InlvList "\"inlv_e1of2_A\" \"inlv_e1of2_B\"") + Ru_DumpBundledList(e1of4InlvList "\"inlv_e1of4_A\" \"inlv_e1of4_B\"") + ) +) + +;validate path for zero length segments and return total distance +(defun Ru_ValidatePath (points msg) + (let (dist totalDist) + totalDist = 0.0 + (if length(points)<=1 printf("ERROR: %s: Invalid path %L\n" msg dist points)) + (for cnt 0 length(points)-2 + dist = Ru_GetDistance(nth(cnt points) nth(cnt+1 points)) + (if dist < TrackPitch/24/4 then + printf("ERROR: %s: Distance %f between to points is zero in path %L\n" msg dist points) + ) + totalDist = totalDist + dist + ) + + totalDist + ) +) + +(defun Ru_TrimLeadingDots (name) + (let (entries ret) + entries = parseString(name ".") + ret = nth(0 entries) + (for cnt 1 length(entries)-1 + ret = strcat(ret ".") + ret = strcat(ret nth(cnt entries)) + ) + ret + ) +) +(defun Ru_ReplaceDotWithDash (name) + (let (entries ret) + entries = parseString(name ".") + ret = nth(0 entries) + (for cnt 1 length(entries)-1 + ret = strcat(ret "_") + ret = strcat(ret nth(cnt entries)) + ) + ret + ) +) + +(defun DeletePaths (@key (CV (geGetEditCellView))) + (let (cnt shape) + cnt = 0 + (foreach shape CV->shapes + (if shape->objType=="path" then + (dbDeleteObject shape) + cnt=cnt+1 + ) + ) + cnt + ) +) + +(defun DeleteObstructions (@key (CV (geGetEditCellView)) (all t)) + (let (cnt shape) + cnt = 0 + (foreach shape CV->shapes + (if shape->objType=="rect" && shape->layerName=="OBS" then + (if all || (GetProp shape "AutoGenerated" nil) then + (dbDeleteObject shape) + cnt=cnt+1 + ) + ) + ) + cnt + ) +) + +(defun ViasSummary (@key (CV (geGetEditCellView))) + (let (viasCnt dblViasCnt contact) + viasCnt = 0 + dblViasCnt = 0 + (foreach contact CV->instances + (if contact->terminals then + ;printf("%L\n" contact->cellName) + viasCnt++ + (if rexMatchp("2CUT" contact->cellName) dblViasCnt++) + ) + ) + printf("Total Vias: %d\n" viasCnt) + printf("Total Double Vias: %d, %.2f\n" dblViasCnt (dblViasCnt*100.0)/viasCnt) + + ) +) + +(defun FindInstOverlaps (@key (CV (geGetEditCellView))) + (let (cnt inst1 inst2 len i j urx1 ury1 llx1 lly1 urx2 ury2 llx2 lly2) + cnt = 0 + len = length(CV->instances) + printf("Total: %d\n" len) + (if len > 200 printf("Please be patience, this might take some time\n")) + (for i 0 len-2 + ;(if mod(i 100) == 0 printf("%d\n" i)) + (for j i+1 len-1 + ;(if mod(j 100) == 0 printf("%d-%d" i j)) + inst1 = nth(i CV->instances) + inst2 = nth(j CV->instances) + urx1 = xCoord( upperRight( inst1->bBox )) + ury1 = yCoord( upperRight( inst1->bBox )) + llx1 = xCoord( lowerLeft( inst1->bBox )) + lly1 = yCoord( lowerLeft( inst1->bBox )) + urx2 = xCoord( upperRight( inst2->bBox )) + ury2 = yCoord( upperRight( inst2->bBox )) + llx2 = xCoord( lowerLeft( inst2->bBox )) + lly2 = yCoord( lowerLeft( inst2->bBox )) + (if !((urx1 <= urx2 && llx1 <= urx2 && urx1 <= llx2 && llx1 <= llx2) || + (urx1 >= urx2 && llx1 >= urx2 && urx1 >= llx2 && llx1 >= llx2) || + (ury1 <= ury2 && lly1 <= ury2 && ury1 <= lly2 && lly1 <= lly2) || + (ury1 >= ury2 && lly1 >= ury2 && ury1 >= lly2 && lly1 >= lly2) ) then + printf("\nOverlap: %L %L %L %L" inst1->name inst1->bBox inst2->name inst2->bBox) + cnt=cnt+1 + ) + ) + ) + cnt + ) +) + +(defun Ru_DrawMarker (point) + (let (seg) + seg = list(Ru_OffsetPoint(point 0.0:-1*TrackPitch/24) Ru_OffsetPoint(point 0.0:1*TrackPitch/24)) + (DrawWire BusMetal67 "MARKER" TrackPitch seg) + ) +) + +(defun ru_getColParm (parm idx) + (let (ret) + (if listp(parm) then + ret = nth(idx parm) + (if !ret ret = nth(0 parm)) + else ret = parm) + ret + ) +) + +(defun Ru_IsPoint (point) + (listp(point) && length(point) == 2) +) + +(defun Ru_LocatePathSeg (path bufLoc startSegNum) + (let (minOffset offset segNum lastPoint nextPoint segDir bufSegNum) + minOffset = 9999.0 + ;find which path segment the buffer is located + lastPoint = nth(startSegNum path) + bufSegNum = -1 + (for segNum startSegNum (length(path)-2) + nextPoint = nth((segNum+1) path) + segDir = ru_getSegDir(lastPoint nextPoint) + ;printf("SegNum %d bufSegNum %d segDir %L minOffset %f lastPoint %L nextPoint %L offX %f offY %f\n" + ; segNum bufSegNum segDir minOffset lastPoint nextPoint + ; abs(xCoord(bufLoc)-xCoord(lastPoint)) abs(yCoord(bufLoc)-yCoord(lastPoint))) + (cond + (segDir == "HOR" && + Ru_IsBetween(xCoord(lastPoint) xCoord(bufLoc) xCoord(nextPoint)) + offset = abs(yCoord(bufLoc)-yCoord(lastPoint)) + (if offset < minOffset then + minOffset = offset + bufSegNum = segNum + ) + ) + (segDir == "VERT" && + Ru_IsBetween(yCoord(lastPoint) yCoord(bufLoc) yCoord(nextPoint)) + offset = abs(xCoord(bufLoc)-xCoord(lastPoint)) + (if offset < minOffset then + minOffset = offset + bufSegNum = segNum + ) + ) + ) + lastPoint = nextPoint + ) + bufSegNum + ) +) + +;handle zero length point, assume some direction base on previous direction +(defun Ru_ClassifyPoints (points) + (let (a b types lastDirV) + a = (car points) + b = (cadr points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "EV")) lastDirV = t) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "EH")) lastDirV = nil)) + (for i 1 (length points)-2 + a = (nth i-1 points) + b = (nth i points) + (cond ((almostEqual (car a) (car b)) && (almostEqual (cadr a) (cadr b)) types=(append types (list (if lastDirV "VH" "HV")))) + ((almostEqual (car a) (car b)) types=(append types (list "VH")) lastDirV = nil) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "HV")) lastDirV = t)) + ) + a = (nth (length points)-2 points) + b = (nth (length points)-1 points) + (cond ((almostEqual (car a) (car b)) types=(append types (list "VE"))) + ((almostEqual (cadr a) (cadr b)) types=(append types (list "HE"))) + ) + types + ) + ) + +(defun OffsetPath (points offsetX offsetY @key (firstOffset nil) (lastOffset nil)) + (let (newpoints index x y hv offX offY nextOffsetX curOffsetX nextOffsetY curOffsetY + (types (Ru_ClassifyPoints points))) + newpoints = nil + index = 0 + numPoints = length(points) + (foreach point points + x = (car point) + y = (cadr point) + hv = (nth index types) + nextOffsetX = offsetX + curOffsetX = offsetX + nextOffsetY = offsetY + curOffsetY = offsetY + (if index <= 1 && firstOffset then + curOffsetX = firstOffset + curOffsetY = firstOffset + ) + (if index >= numPoints-2 && lastOffset then + nextOffsetX = lastOffset + nextOffsetY = lastOffset + (if index >= numPoints-1 then + curOffsetX = nextOffsetX + curOffsetY = nextOffsetY + ) + ) + (cond + ( hv == "EH" || hv == "HV" + offX = nextOffsetX + offY = curOffsetY) + ( hv == "VE" || hv == "HE" + offX = curOffsetX + offY = curOffsetY) + (t + offX = curOffsetX + offY = nextOffsetY + ) + ) + x = x+(if (and hv!="HE" hv!="EH") offX 0) + y = y+(if (and hv!="VE" hv!="EV") offY 0) + newpoints = (append newpoints (list (list x y))) + index = index+1 + ) + newpoints + ) +) + +(defun Ru_GetPathNode (points layerPatternList nodeName + @key (flipSegX nil) (flipSegY nil) + (firstPattern nil) (lastPattern nil) + (firstSwitchPattern nil) (lastSwitchPattern nil) ) + (let (node offset newpoints index offsetX offsetY x y hv numPoints flipX flipY el temp + (types (Ru_ClassifyPoints points))) + numPoints = length(points) + (foreach node_offset layerPatternList + node = (car node_offset) + (if (node == nodeName) then + offset = (caddr node_offset) + newpoints = nil + index = 0 + (foreach point points + x = (car point) + y = (cadr point) + hv = (nth index types) + flipX = nil + flipY = nil + ; no alternate pattern + nextOffset = offset + curOffset = offset + (if index <= 1 && firstPattern then + (foreach node_offset firstPattern + (if ((car node_offset) == nodeName) then + curOffset = (caddr node_offset) + ) + ) + ) + (if index >= 1 && index <= 2 && firstSwitchPattern then + (foreach node_offset firstSwitchPattern + (if ((car node_offset) == nodeName) then + temp = (caddr node_offset) + (if index == 1 nextOffset = temp) + (if index == 2 curOffset = temp) + ) + ) + ) + (if index >= numPoints-2 && lastPattern then + (foreach node_offset lastPattern + (if ((car node_offset) == nodeName) then + nextOffset = (caddr node_offset) + (if index >= numPoints-1 curOffset = nextOffset) + ) + ) + ) + (if index >= numPoints-3 && index <= numPoints-2 && lastSwitchPattern then + (foreach node_offset lastSwitchPattern + (if ((car node_offset) == nodeName) then + temp = (caddr node_offset) + (if index == numPoints-3 nextOffset = temp) + (if index == numPoints-2 curOffset = temp) + ) + ) + ) + (cond + ( hv == "EH" || hv == "HV" + offsetX = nextOffset + offsetY = curOffset) + ( hv == "VE" || hv == "HE" + offsetX = curOffset + offsetY = curOffset) + (t + offsetX = curOffset + offsetY = nextOffset + ) + ) + (if flipSegX then + (foreach el flipSegX + (if el == index || (el+1) == index flipX = t) + ) + ) + (if flipSegY then + (foreach el flipSegY + (if el == index || (el+1) == index flipY = t) + ) + ) + x = x+(if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0) + y = y+(if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0) + newpoints = (append newpoints (list (list x y))) + index = index+1 + ) + ) + ) + newpoints + ) +) + +(defun ru_GetBufSize (inst) + (let (sizeX sizeY) + (if inst then + sizeY = yCoord(upperRight(inst->bBox))-yCoord(lowerLeft(inst->bBox)) + sizeX = xCoord(upperRight(inst->bBox))-xCoord(lowerLeft(inst->bBox)) + sizeX = ceiling(sizeX/TrackPitch-TrackPitch/48)*TrackPitch + else + sizeX = 2*TrackPitch + sizeY = 4*TrackPitch + ) + list(sizeX sizeY) + ) +) + +;Stack multiple buffer columns along a path +;colLeftList and colRightList is mainly for vertical path +;horizontal path just round robin the two list +(defun Ru_StackBuffer (path colLeftList colRightList reserveX reserveY + @key (offsetX 0.0) (offsetY 0.0) (bufPrefix nil) + (flipSegPattern nil) (reserveGap nil) (bufferPath nil) + (balance nil) (bufSegNum 0) ) + (prog (bufLoc bufOffset curPoint lastPoint nextPoint pathSegIdx dir colPath result advance advanceOff sizeOff + orient inst bufSizeX bufSizeY lastBufSizeX lastBufSizeY maxBufY reserveDist bufOffX x y gapLow gapHi + leftCnt rightCnt leftListLen rightListLen segNum segNumOff valLow valHi cnt entry bufLen leftRightOrder position) + (if debug >= 3 printf("#############Ru_StackBuffer path %L offset %f %f reserve %f %f \n" + path offsetX offsetY reserveX reserveY)) + (if length(path) <= 1 error("Path %L must have at least 2 points\n" path)) + (foreach point path + colPath = append(colPath list(Ru_AlignX(xCoord(point)):Ru_AlignY(yCoord(point)))) + ) + ;dbCreatePath((geGetEditCellView) list("M7" "bus") colPath 0.8) + segNumOff = 0 + + (if flipSegPattern || reserveGap then + (if !bufferPath error("Must have valid bufferPath option when passing flipSegPattern or reserveGap option\n")) + segNumOff = car(ru_getPathSegment(car(path) bufferPath)) + (if debug >= 1 printf("Buffer segment %L start from segment %d of bufferPath %L\n" path segNumOff bufferPath)) + ) + pathSegIdx = 0 + curPoint = car(colPath) + lastPoint = curPoint + nextPoint = nth((pathSegIdx+1) colPath) + dir = ru_getSegDir(lastPoint nextPoint ?detail t) + orient = "R0" + lastBufSizeX = 4*TrackPitch + lastBufSizeY = 4*TrackPitch + bufOffX = 0.0 + leftListLen = length(colLeftList) + rightListLen = length(colRightList) + leftCnt = 0 + rightCnt = 0 + colPos = "LEFT" + (cond + (dir == "DOWN" || dir == "UP" + reserveDist = reserveY + lastBufSizeY + ) + (dir == "LEFT" || dir == "RIGHT" + reserveDist = reserveX + lastBufSizeX + ) + ) + maxBufY = lastBufSizeX + advance = t + inst = nil + (while leftCnt < leftListLen || rightCnt < rightListLen + result = ru_GetBufSize(inst) + lastBufSizeX = car(result) + lastBufSizeY = cadr(result) + +;FIXME Need to redo this logic a little better, have curPos for 2 columns and check each individually +CHECK_RESERVE_GAP_LABEL = t +(while CHECK_RESERVE_GAP_LABEL +;(if bufSegNum == 1 printf("#### %L colPos %L dir %L\n" bufName colPos dir)) +advanceNextSeg = nil + (if reserveGap && !(colPos == "RIGHT" && (dir == "DOWN" || dir == "UP")) then + (foreach entry reserveGap + segNum = segNumOff + pathSegIdx +;(if bufSegNum == 1 printf("######## %L segNum %L pathSegIdx: %L %L\n" bufName segNum pathSegIdx entry)) + (if car(entry) == segNum then + (cond + (dir=="LEFT" advanceOff = -2*TrackPitch:0 sizeOff = advanceOff sizeOffHi = advanceOff ) + (dir=="RIGHT" advanceOff = 2*TrackPitch:0 sizeOff = advanceOff sizeOffHi = advanceOff) + (dir=="DOWN" advanceOff = 0:-2*TrackPitch sizeOff = 0:-4*TrackPitch sizeOffHi = 0:(if balance -6 -4)*TrackPitch) + (dir=="UP" advanceOff = 0:2*TrackPitch sizeOff = 0:4*TrackPitch sizeOffHi = 0:(if balance 6 4)*TrackPitch) + ) + result = Ru_OffsetPoint(curPoint sizeOff) + valLow = (if dir=="LEFT"||dir=="RIGHT" xCoord(result) yCoord(result)) + result = Ru_OffsetPoint(result sizeOffHi) + valHi = (if dir=="LEFT"||dir=="RIGHT" xCoord(result) yCoord(result)) + + cnt = 0 + gapLow = (nth(1 entry)+TrackPitch/24) + gapHi = (nth(2 entry)-TrackPitch/24) +;(if bufSegNum == 1 printf("#### %L GAP %L: %L [bufRange: %L %L] %L\n" bufName entry gapLow valLow valHi gapHi)) + (while Ru_IsBetween(gapLow valLow gapHi) || Ru_IsBetween(gapLow valHi gapHi) || Ru_IsBetween(gapLow (valLow+valHi)/2 gapHi) + cnt++ + curPoint = Ru_OffsetPoint(curPoint advanceOff) + (if debug >=1 printf("%L: Next buffer is in the reserve gap %L, advance #%d to %L\n" bufName entry cnt curPoint)) + result = Ru_OffsetPoint(curPoint sizeOff) + valLow = (if dir=="LEFT"||dir=="RIGHT" xCoord(result) yCoord(result)) + result = Ru_OffsetPoint(result sizeOffHi) + valHi = (if dir=="LEFT"||dir=="RIGHT" xCoord(result) yCoord(result)) +;printf("#### %L GAP %L: %L [%L %L] %L\n" bufName entry gapLow valLow valHi gapHi) +advanceNextSeg = t + ) + ) + ) + (if nextPoint remDist = Ru_GetDistance(curPoint nextPoint)) + (if debug >= 2 printf("Ru_StackBuffer: ADVANCE %L pathSegIdx %d reserveDist %f lastPoint %L curPoint %L nextPoint %L dir %s remDist %f bufOffX %f\n" + bufName pathSegIdx reserveDist lastPoint curPoint nextPoint dir remDist bufOffX)) + ) + + + ;next buffer location is on next path + (if nextPoint remDist = Ru_GetDistance(curPoint nextPoint)) + (if debug >= 2 printf("Ru_StackBuffer: %L pathSegIdx %d reserveDist %f lastPoint %L curPoint %L nextPoint %L dir %s remDist %f bufOffX %f\n" + bufName pathSegIdx reserveDist lastPoint curPoint nextPoint dir remDist bufOffX)) +;(if bufName == "mbuf_LAG_MASK[7][10]" || bufName == "mbuf_LAG_MASK[2][10]" printf("Ru_StackBuffer: %L pathSegIdx %d reserveDist %f lastPoint %L curPoint %L nextPoint %L dir %s remDist %f bufOffX %f\n" +; bufName pathSegIdx reserveDist lastPoint curPoint nextPoint dir remDist bufOffX)) + bufLen = (if dir=="LEFT"||dir=="RIGHT" lastBufSizeX lastBufSizeY) + (while remDist < (reserveDist+bufLen) && nextPoint + lastPoint = nextPoint + nextPoint = nth((pathSegIdx+2) colPath) + (if debug >= 2 printf("Ru_StackBuffer: Advance to pathSegIdx %d lastPoint %L curPoint %L nextPoint %L dir %s remDist %f\n" + pathSegIdx lastPoint curPoint nextPoint dir remDist)) + (if nextPoint then +advanceNextSeg = t + pathSegIdx++ + dir = ru_getSegDir(lastPoint nextPoint ?detail t) + result = AdvanceCurPoint(curPoint lastPoint dir reserveX reserveY lastBufSizeY lastBufSizeX) + curPoint = car(result) + reserveDist = cadr(result) + remDist = Ru_GetDistance(curPoint nextPoint) + (if debug >=2 printf("Ru_StackBuffer: Advance to pathSegIdx %d lastPoint %L curPoint %L nextPoint %L dir %s remDist %f\n" + pathSegIdx lastPoint curPoint nextPoint dir remDist)) + ) + bufLen = (if dir=="LEFT"||dir=="RIGHT" lastBufSizeX lastBufSizeY) + ) +CHECK_RESERVE_GAP_LABEL = nil +(if advanceNextSeg && reserveGap then + (if debug >= 1 printf("CurPos: %L(%L-%L) Advance to next segment so go back and check for reserve gap\n" curPoint dir colPos)) + CHECK_RESERVE_GAP_LABEL = t +) +) ;while CHECK_RESERVE_GAP_LABEL + + ;printf("%s Loc %L sizeXY %f %f tracks\n" bufName curPoint lastBufSizeX/TrackPitch lastBufSizeY/TrackPitch) +(if debug >=2 printf("leftCnt %d leftListLen %d rightCnt %d rightListLen %d\n" + leftCnt leftListLen rightCnt rightListLen)) + + ;find next location + orient = "R0" +segNum = segNumOff + pathSegIdx + leftRightOrder = t ; alignment of left or right column + position = ""; buffer to the right or top + (cond + (dir == "DOWN" || dir == "UP" + reserveDist = reserveY + lastBufSizeY + (if colPos == "RIGHT" then + position = "RIGHT" + ;don't advance just offset right + advance = nil + bufOffset = (offsetX+4*TrackPitch):(if balance 2*TrackPitch 0.0) + bufOffX = bufOffX+lastBufSizeX + bufName = nth(rightCnt colRightList) + rightCnt++ + (if !bufName && balance then + ;place the left to the right to balance the column + bufName = nth(leftCnt colLeftList) + leftCnt++ + leftRightOrder = nil + ) + colPos = "LEFT" +;printf("%L: RIGHT segNum %d flipSeg %L\n" bufName segNum member(segNum flipSegPattern)) + (if member(segNum flipSegPattern) then + orient = (if dir=="DOWN" "MX" "R0") + bufOffset = -(offsetX+4*TrackPitch):(if balance 2*TrackPitch 0.0) ;subtract 1 more due to round down + (if bufName && substring(bufName 5 1) == "r" then ;FIXME hardcoded + ;printf("%s channel direction is reversed\n" bufName) + bufOffset = Ru_OffsetPoint(bufOffset 0:(if dir=="DOWN" -4 4)*TrackPitch) + orient = (if dir=="DOWN" "R0" "MX") + ) + else + (if bufName && substring(bufName 5 1) == "r" then ;FIXME hardcoded + ;printf("%s channel direction is reversed\n" bufName) + bufOffset = Ru_OffsetPoint(bufOffset 0:(if dir=="DOWN" -4 4)*TrackPitch) + orient = (if dir=="DOWN" "MY" "R180") + else + orient = (if dir=="DOWN" "R180" "MY")) + ) + else + position = "LEFT" + advance = t + advanceOff = 0.0:(if dir=="DOWN" -maxBufY maxBufY) + ;curPoint = Ru_OffsetPoint(curPoint 0.0:(if dir=="DOWN" -maxBufY maxBufY)) + bufOffset = offsetX:0.0 + bufOffX = lastBufSizeX + bufName = nth(leftCnt colLeftList) + leftCnt++ + (if !bufName && balance then + ;place the left to the right to balance the column + bufName = nth(rightCnt colRightList) + rightCnt++ + leftRightOrder = nil + ) + colPos = "RIGHT" +;printf("%L: segNum %d flipSeg %L\n" bufName segNum member(segNum flipSegPattern)) + (if member(segNum flipSegPattern) then + orient = (if dir=="DOWN" "R180" "MY") + bufOffset = -(offsetX+0*TrackPitch):0.0 +;printf("%L: LEFT bufOffset %L offsetX %L\n" bufName bufOffset offsetX) + (if bufName && substring(bufName 5 1) == "r" then ;FIXME hardcoded + ;printf("%s channel direction is reversed\n" bufName) + bufOffset = Ru_OffsetPoint(bufOffset 0:(if dir=="DOWN" -4 4)*TrackPitch) + orient = (if dir=="DOWN" "MY" "R180") + ) + else + (if bufName && substring(bufName 5 1) == "r" then ;FIXME hardcoded + ;printf("%s channel direction is reversed\n" bufName) + bufOffset = Ru_OffsetPoint(bufOffset 0:(if dir=="DOWN" -4 4)*TrackPitch) + orient = (if dir=="DOWN" "R0" "MX") + else orient = (if dir=="DOWN" "MX" "R0")) + ) + ) + (if bufName then + inst = (dbFindAnyInstByName (geGetEditCellView) (if bufPrefix sprintf(nil "%s%s" bufPrefix bufName) bufName) ) + result = ru_GetBufSize(inst) + bufSizeX = car(result) + bufSizeY = cadr(result) + (if advance then maxBufY = bufSizeY + else (if maxBufY < bufSizeY maxBufY = bufSizeY)) + ;printf("%s: %L %L %L advance %L\n" bufName bufSizeY lastBufSizeY maxBufY advance) + ) + ) + (dir == "LEFT" || dir == "RIGHT" + (if colPos == "LEFT" then + bufName = nth(leftCnt colLeftList) + leftCnt++ + colPos = "RIGHT" + (if !bufName then + bufName = nth(rightCnt colRightList) + rightCnt++ + ) + else + bufName = nth(rightCnt colRightList) + rightCnt++ + colPos = "LEFT" + (if !bufName then + bufName = nth(leftCnt colLeftList) + leftCnt++ + ) + ) +;printf("%s: dir %L segNum %L %L %L flip %L orient %L \n" bufName dir segNum segNumOff pathSegIdx flipSegPattern orient) + (if bufName then + inst = (dbFindAnyInstByName (geGetEditCellView) (if bufPrefix sprintf(nil "%s%s" bufPrefix bufName) bufName) ) + result = ru_GetBufSize(inst) + bufSizeX = car(result) + bufSizeY = cadr(result) + ) + + ;printf("%s: %f %f advance %L\n" bufName bufSizeY lastBufSizeY advance) + (if advance && bufSizeY <= 2.01*TrackPitch && lastBufSizeY <= 2.01*TrackPitch then + ;for e1of1 + position = "TOP" + reserveDist = reserveX + lastBufSizeX + ;don't advance just offset + advance = nil + bufOffset = Ru_OffsetPoint(0.0:offsetY (if dir=="LEFT" -TrackPitch TrackPitch):2*TrackPitch) + else + position = "BOTTOM" + advance = t + advanceOff = (if dir=="LEFT" -lastBufSizeX lastBufSizeX):0.0 + ;curPoint = Ru_OffsetPoint(curPoint (if dir=="LEFT" -lastBufSizeX lastBufSizeX):0.0) + reserveDist = reserveX + lastBufSizeX + bufOffset = 0.0:offsetY + ) + (if member(segNum flipSegPattern) then + orient = (if dir == "LEFT" "R180" "MX") + bufOffset = -(offsetX-1*TrackPitch):0.0 + (if bufName && substring(bufName 5 1) == "r" then ;FIXME hardcoded + ;printf("%s channel direction is reversed\n" bufName) + bufOffset = Ru_OffsetPoint(bufOffset (if dir=="LEFT" -2 2)*TrackPitch:0) + orient = (if dir=="LEFT" "R180" "MX") + ) + else + (if bufName && substring(bufName 5 1) == "r" then ;FIXME hardcoded + ;printf("%s channel direction is reversed\n" bufName) + bufOffset = Ru_OffsetPoint(bufOffset (if dir=="LEFT" -2 2)*TrackPitch:0) + orient = (if dir=="LEFT" "R0" "MY") + else orient = (if dir == "LEFT" "MY" "R0")) + ) + ) + ) + + (if advance then + (if !advanceOff error("advanceOff is nil whereas advance is set\n")) + curPoint = Ru_OffsetPoint(curPoint advanceOff) +/* + (foreach entry reserveGap + segNum = segNumOff + pathSegIdx + ;printf("#### %L segNum %L pathSegIdx: %L %L\n" bufName segNum pathSegIdx entry) + (if car(entry) == segNum then + val = (if dir=="LEFT"||dir=="RIGHT" xCoord(curPoint) yCoord(curPoint)) + cnt = 0 + ;printf("#### %L GAP: %L %L %L\n" bufName nth(1 entry) val nth(2 entry)) + (while Ru_IsBetween(nth(1 entry) val nth(2 entry)) + cnt++ + (if debug >=1 printf("%L is in the reserve gap, advance #%d\n" bufName cnt)) + curPoint = Ru_OffsetPoint(curPoint advanceOff) + val = (if dir=="LEFT"||dir=="RIGHT" xCoord(curPoint) yCoord(curPoint)) + ) + ) + ) + advanceOff = nil ;reset + (if nextPoint remDist = Ru_GetDistance(curPoint nextPoint)) + (if debug >= 2 printf("Ru_StackBuffer: ADVANCE %L pathSegIdx %d reserveDist %f lastPoint %L curPoint %L nextPoint %L dir %s remDist %f bufOffX %f\n" + bufName pathSegIdx reserveDist lastPoint curPoint nextPoint dir remDist bufOffX)) +*/ + + bufLen = (if dir=="LEFT"||dir=="RIGHT" bufSizeX bufSizeY) + (if bufName && nextPoint && remDist < (reserveDist+bufLen-4*TrackPitch) then + printf("WARN: %L Reserve gap %L is not met %L in tracks. bufLen %L\n" bufName ToTrack(remDist) ToTrack(reserveDist) ToTrack(bufLen)) + ) + ) + + (if debug >= 2 printf("Ru_StackBuffer: %L pathSegIdx %d curPoint %L bufOffset %L nextColPos %s dir %s remDist %f lastBufSize %f %f\n" + bufName pathSegIdx curPoint bufOffset colPos dir remDist lastBufSizeX lastBufSizeY)) + (if bufName then + bufLoc = Ru_OffsetPoint(curPoint bufOffset) + x = Ru_AlignX(xCoord(bufLoc)) + y = Ru_AlignY(yCoord(bufLoc)) + (if !almostEqual(xCoord(bufLoc) x) then + printf("ERROR: Ru_StackBuffer: %s is not aligned in xCoord got %f expect %f\n" + bufName xCoord(bufLoc) y ) + ) + (if !almostEqual(yCoord(bufLoc) y) then + printf("ERROR: Ru_StackBuffer: %s is not aligned in yCoord got %f expect %f\n" + bufName yCoord(bufLoc) y ) + ) + (if inst then + inst->xy = bufLoc + inst->orient = orient + (dbReplaceProp inst "LeftRightAlign" "boolean" leftRightOrder) + (dbReplaceProp inst "Position" "string" position) + ) +;(if leftCnt >= 2 error("Loc: %L" bufOffset)) + ;stack the ramp reset next to buf reset + (if leftCnt == 1 && rexMatchp("bufReset" bufName) && + rexMatchp("rampReset" nth(1 colLeftList)) then + ;printf("%L %L\n" bufName nth(1 colLeftList)) + inst = (dbFindAnyInstByName (geGetEditCellView) (if bufPrefix sprintf(nil "%s%s" bufPrefix nth(1 colLeftList)) nth(1 colLeftList))) + leftCnt++ + (if inst then + inst->xy = Ru_OffsetPoint(bufLoc (if member(segNum flipSegPattern) -1 1)*TrackPitch:0) + (if orient inst->orient = orient) + ) + (if (dir=="LEFT" || dir=="RIGHT" ) then + curPoint = Ru_OffsetPoint(curPoint (if dir=="LEFT" -TrackPitch TrackPitch):0.0) + ) + ) + ) + ) + (if !nextPoint printf("WARN: Visual inspect for any buffer overlap. Path segment might be too short for all the buffers: %L.\n" + list(leftList rightList))) + return(t) + ) +) + +(defun AdvanceCurPoint (curPoint lastPoint dir reserveX reserveY lastBufSizeY lastBufSizeX) + (cond + (dir == "DOWN" + curPoint = Ru_OffsetPoint(lastPoint 0.0:-reserveY) + curPoint = xCoord(curPoint):Ru_AlignY(yCoord(curPoint)) + reserveDist = reserveY + lastBufSizeY + ) + (dir == "UP" + curPoint = Ru_OffsetPoint(lastPoint 0.0:reserveY) + curPoint = xCoord(curPoint):Ru_AlignY(yCoord(curPoint)) + reserveDist = reserveY + lastBufSizeY + ) + (dir == "LEFT" + curPoint = Ru_OffsetPoint(lastPoint -reserveX:0.0) + curPoint = Ru_AlignX(xCoord(curPoint)):yCoord(curPoint) + reserveDist = reserveX + lastBufSizeX + ) + (dir == "RIGHT" + curPoint = Ru_OffsetPoint(lastPoint reserveX:0.0) + curPoint = Ru_AlignX(xCoord(curPoint)):yCoord(curPoint) + reserveDist = reserveX + lastBufSizeX + ) + ) + list(curPoint reserveDist) +) + +;replace - return only entries matching match and replace them with replace +;retAll - return all entries with match and replace option +(defun ModifyChannel (channel @key (flipOffset nil) (filterGnd nil) (filterOffset nil) + (offset nil) (normalizeTrackOffset nil) + (match nil) (replace nil) (retAll nil) (exclude nil) + (trimLeadingDots nil) (trimLeadingExtraDots nil) + (forceLayer nil) (clearLayer nil) + (combine nil) (combineOffset nil) (rexMagicMode nil)) + (let (ret newOff node add layer nodeName el layerIdx baseOff trackIdx) + rexMagic(rexMagicMode) + (if combine&&!combineOffset error("Must specify combineOffset option when using combine option\n")) + (if !combine&&combineOffset error("Must specify combine option when using combineOffset option\n")) + + (if replace rexCompile(match)) + (foreach el channel + nodeName = nth(0 el) + newOff = nth(2 el) + layer = nth(3 el) + (if offset newOff = newOff+offset) + (if flipOffset newOff = -newOff) + (if normalizeTrackOffset then + newOff = newOff + TrackPitch/2 + baseOff = RoundDownTrack(newOff ?numTrack normalizeTrackOffset) + newOff = newOff - baseOff + layerIdx = mod(floor(ToTrack(newOff)) 3) + trackIdx = floor(ToTrack(newOff)) + ;every 3 tracks into one track + newOff = (trackIdx/3)*TrackPitch + (newOff - RoundDownTrack(newOff)) + (if trackIdx == normalizeTrackOffset-1 then + (cond + (layerIdx == 0 layer = BusMetal23) + (layerIdx == 1 layer = BusMetal67) + (t layer = BusMetal45) + ) + else + (cond + (layerIdx == 0 layer = BusMetal67) + (layerIdx == 1 layer = BusMetal45) + (t layer = BusMetal23) + ) + ) + +; (if almostEqual(RoundDownTrack(newOff+TrackPitch/2) 0.0) && replaceLayer then +; layer = replaceLayer +; else newOff = newOff - TrackPitch) +;(if nth(2 el) < 9*TrackPitch printf("%L Offset %L newOff %L TrackIdx %L baseOff %L layerIdx %L trackIdx %L baseOff %L normalize %L\n" nodeName nth(2 el) newOff ToTrack(newOff) baseOff layerIdx trackIdx mod(floor(ToTrack(baseOff)) 2) normalizeTrackOffset)) + newOff = newOff - TrackPitch/2 + ) + (if forceLayer layer = forceLayer) + (if clearLayer layer = nil) + (if trimLeadingDots||trimLeadingExtraDots nodeName = Ru_TrimLeadingDots(nodeName)) + (if trimLeadingExtraDots && nodeName != "GND" nodeName = strcat("." nodeName)) ;only one leading dot + add = retAll + (if match then + (if rexMatchp(match nodeName) then + (if replace then + nodeName = rexReplace( nodeName replace 0) + ) + add = t + ) + else + add = t + ) + (if filterOffset then +;printf("filterOff: Add %L %L %L %L\n" Ru_IsBetween(car(filterOffset) newOff cadr(filterOffset)) car(filterOffset) newOff cadr(filterOffset)) + add = Ru_IsBetween(car(filterOffset) newOff cadr(filterOffset)) + ) + (if exclude then + (if rexMatchp(exclude nodeName) then + add = nil + ) + ) + (if filterGnd && nodeName == "GND" add = nil) + (if add ret = append(ret list(list(nodeName nth(1 el) newOff layer)))) + ) + + (foreach el combine + nodeName = nth(0 el) + newOff = nth(2 el) + newOff = newOff+combineOffset + layer = nth(3 el) + (if forceLayer layer = forceLayer) + (if flipOffset newOff = -newOff) + (if trimLeadingDots||trimLeadingExtraDots nodeName = Ru_TrimLeadingDots(nodeName)) + (if trimLeadingExtraDots && nodeName != "GND" nodeName = strcat("." nodeName)) + add = nil + (if match then + (if rexMatchp(match nodeName) then + (if replace then + nodeName = rexReplace( nodeName replace 0) + ) + add = t + ) + else + add = t + ) + (if exclude then + (if rexMatchp(exclude nodeName) then + add = nil + ) + ) + (if filterGnd && nodeName == "GND" add = nil) + (if add ret = append(ret list(list(nodeName nth(1 el) newOff layer)))) + ) + rexMagic(t) + ret + ) +) + +(defun GetPinStartPath (path) + (let (a pin) + a = car(path) + dir = ru_getSegDir(a cadr(path) ?detail t) + (cond + (dir == "UP" pin = list(a Ru_OffsetPoint(a 0:TrackPitch))) + (dir == "DOWN" pin = list(a Ru_OffsetPoint(a 0:-TrackPitch))) + (dir == "LEFT" pin = list(a Ru_OffsetPoint(a -TrackPitch:0))) + (dir == "RIGHT" pin = list(a Ru_OffsetPoint(a TrackPitch:0))) + ) + pin + ) +) + +(defun GetPinEndPath (path) + (let (a pin len) + len = length(path) + a = nth(len-1 path) + dir = ru_getSegDir(a nth(len-2 path) ?detail t) + (cond + (dir == "UP" pin = list(a Ru_OffsetPoint(a 0:TrackPitch))) + (dir == "DOWN" pin = list(a Ru_OffsetPoint(a 0:-TrackPitch))) + (dir == "LEFT" pin = list(a Ru_OffsetPoint(a -TrackPitch:0))) + (dir == "RIGHT" pin = list(a Ru_OffsetPoint(a TrackPitch:0))) + ) + pin + ) +) + +(defun Ru_CreatePinPath (points busPattern busPrefix) + (let (pathL) + pathL = dbCreatePath((geGetEditCellView) list("M6" "bus") points 0.12) + (dbReplaceProp pathL "BusArrayPitch" "float" 2.88) + (dbReplaceProp pathL "BusPattern" "string" busPattern) + (dbReplaceProp pathL "BusPrefix" "string" busPrefix) + (dbReplaceProp pathL "BusPin" "boolean" t) + (dbReplaceProp pathL "BusFlipX" "boolean" nil) + (dbReplaceProp pathL "BusFlipY" "boolean" nil) + (dbReplaceProp pathL "BusStartVias" "boolean" nil) + (dbReplaceProp pathL "BusEndVias" "boolean" nil) + (dbReplaceProp pathL "BusDoubleVias" "boolean" t) + pathL + ) +) + +(defun LoadBusPattern (filenameList) + (let (DFII_dir buspatternfile ) + DFII_dir = ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + (printf "loading channel pattern %L ... ", filenameList) + (if !listp(filenameList) filenameList = list(filenameList)) + (foreach filename filenameList + buspatternfile = (sprintf nil "%s/chip/alta/route/buspattern/%s" DFII_dir filename) + (if (load buspatternfile) then + (printf "%s loaded.\n" filename) + else (printf "ERROR: Failed loading %s.\n" filename)) + ) + ) +) + +(defun LoadPinPattern (filenameList) + (let (DFII_dir pinpatternfile busLen cnt) + busLen = length(busPatterns) + DFII_dir = ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + (printf "loading pin pattern %L ... ", filenameList) + (if !listp(filenameList) filenameList = list(filenameList)) + (foreach filename filenameList + pinpatternfile = (sprintf nil "%s/%s" DFII_dir filename) + (if (load pinpatternfile) then + (printf "%s loaded.\n" filename) + else (printf "ERROR: Failed loading %s.\n" filename)) + ) + printf("New pattern loaded: \n") + (for cnt busLen length(busPatterns)-1 + printf("%L \n" car(nth(cnt busPatterns))) + ) + printf("\n") + ) +) + + + + +(defun ru_getPathSegment (loc path @key (detail nil)) + (if boundp('debug) && debug >= 3 printf("getPathSegment loc %L path %L\n" loc path)) + (let (locSeg dir pathSegIdx startPoint endPoint) + locSeg = -1 + dir = "UNKNOWN" + pathSegIdx = 0 + (while locSeg < 0 && pathSegIdx < (length(path)-1) + startPoint = nth(pathSegIdx path) + endPoint = nth((pathSegIdx+1) path) + (if almostEqual(xCoord(startPoint) xCoord(endPoint)) then + (if detail then dir = (if yCoord(startPoint) < yCoord(endPoint) "UP" "DOWN") + else dir = "VERT") + (if boundp('debug) && debug >= 4 printf("a. Path#%d segment is %s\n" pathSegIdx dir)) + (if almostEqual(xCoord(startPoint) xCoord(loc)) && + Ru_IsBetween(yCoord(startPoint) yCoord(loc) yCoord(endPoint)) locSeg = pathSegIdx) + else + (if detail then dir = (if xCoord(startPoint) < xCoord(endPoint) "RIGHT" "LEFT") + else dir = "HOR") + (if boundp('debug) && debug >= 4 printf("a. Path#%d segment is %s\n" pathSegIdx dir)) + (if almostEqual(yCoord(startPoint) yCoord(loc)) && + Ru_IsBetween(xCoord(startPoint) xCoord(loc) xCoord(endPoint)) locSeg = pathSegIdx) + ) + pathSegIdx++ + ) + (if boundp('debug) && debug >= 3 printf("getPathSegment return pathSeg %d dir %s\n" locSeg dir)) + list(locSeg dir) + ) +) + +(defun ru_getNextSegment (lastBufLoc path bufDist guideX guideY sramCfg termDist) + (if boundp('debug) && debug >= 3 printf("getNextSegment lastBufLoc %L bufDist %L path %L\n" lastBufLoc bufDist path)) + (if !path || !bufDist error("ru_getNextSegment Nil parameter path %L bufDist\n" path bufDist)) + (let (lastBufLocSeg dir pathSegIdx startPoint endPoint pointList + nextPoint endPoint segDist totalDist nextGuideLoc adjDist result) + ;find which path segment is the last location + result = ru_getPathSegment(lastBufLoc path) + lastBufLocSeg = nth(0 result) + dir = nth(1 result) + (if lastBufLocSeg < 0 then + printf("GetNextSegment: ERROR: Unable to locate buffer location %L to path %L\n" lastBufLoc path) + ) + + ; get next path location + pointList = nil + pathSegIdx = lastBufLocSeg + lastPoint = lastBufLoc + nextPoint = nth((pathSegIdx+1) path) + segDist = Ru_GetDistance(lastPoint nextPoint) + totalDist = segDist + nextGuideLoc = ru_findNextGuideLoc(guideX guideY dir lastPoint nextPoint bufDist) + (if boundp('debug) && debug >= 2 printf("getNextSegment: lastBufLocSeg %d %s totalDist %f lastPoint %L nextPoint %L nextGuideLoc %L\n" + lastBufLocSeg dir segDist lastPoint nextPoint nextGuideLoc)) + + (while totalDist < bufDist && pathSegIdx < (length(path)-2) && !nextGuideLoc + pathSegIdx++ + pointList = append(pointList list(nextPoint)) + lastPoint = nextPoint + nextPoint = nth((pathSegIdx+1) path) + (if almostEqual(xCoord(lastPoint) xCoord(nextPoint)) then + dir = "VERT" + (if boundp('debug) && debug >= 4 printf("b. Path#%d segment is %s\n" pathSegIdx dir)) + else + dir = "HOR" + (if boundp('debug) && debug >= 4 printf("b. Path#%d segment is %s\n" pathSegIdx dir)) + ) + nextGuideLoc = ru_findNextGuideLoc(guideX guideY dir lastPoint nextPoint bufDist) + segDist = Ru_GetDistance(lastPoint nextPoint) + totalDist = totalDist + segDist + (if boundp('debug) && debug >= 2 printf("getNextSegment: pathSegIdx %d %s totalDist %f segDist %f lastPoint %L nextPoint %L nextGuideLoc %L\n" + pathSegIdx dir totalDist segDist lastPoint nextPoint nextGuideLoc)) + ) + + (cond + (nextGuideLoc + nextPoint = nextGuideLoc + ) + (totalDist > bufDist + ;adjust next point if distance longer than desired + dir = ru_getSegDir(lastPoint nextPoint) + adjDist = ru_roundUp(totalDist-bufDist) + (if dir == "VERT" then + (if yCoord(nextPoint) > yCoord(lastPoint) + then nextPoint = xCoord(nextPoint):round((yCoord(nextPoint)-adjDist)/2/TrackPitch)*2*TrackPitch + else nextPoint = xCoord(nextPoint):round((yCoord(nextPoint)+adjDist)/2/TrackPitch)*2*TrackPitch ) + else + (if xCoord(nextPoint) > xCoord(lastPoint) + then nextPoint = round((xCoord(nextPoint)-adjDist)/TrackPitch)*TrackPitch:yCoord(nextPoint) + else nextPoint = round((xCoord(nextPoint)+adjDist)/TrackPitch)*TrackPitch:yCoord(nextPoint)) + ) + ) + ) + + (if totalDist < 0.01 + then pointList = nil + else pointList = append(pointList list(nextPoint)) + ) + ;end + (if pointList then + endPoint = car(last(path)) + bufDist = Ru_GetDistance(lastBufLoc endPoint) + (if bufDist < termDist then + printf("Last buffer is within %f from endpoint\n" bufDist) + pointList = nil + ) + ) + pointList + ) +) + +(defun ru_getSramSegmentIndex (lastBufLoc segPoints sramCfgList) + (if boundp('debug) && debug >= 3 printf("getSramSegmentIndex lastBufLoc %L segPoints %L sramCfg %L\n" lastBufLoc segPoints sramCfgList)) + + sramSegIndex = -1 + segPath = append(list(lastBufLoc) segPoints) + sramIdx = 0 + (foreach sramCfg sramCfgList + sramLoc = nth(2 sramCfg) + pathSegIdx = 0 + (while sramSegIndex < 0 && pathSegIdx < (length(segPath)-1) + startPoint = nth(pathSegIdx segPath) + endPoint = nth((pathSegIdx+1) segPath) + + (if boundp('debug) && debug >= 4 printf("sramIdx %d pathSegIdx %d sramSegIndex %d SRAM %L %L %L\n" + sramIdx pathSegIdx sramSegIndex startPoint sramLoc endPoint)) + (if almostEqual(xCoord(startPoint) xCoord(endPoint)) then + (if almostEqual(xCoord(startPoint) xCoord(sramLoc)) && + !almostEqual(yCoord(startPoint) yCoord(sramLoc)) && + Ru_IsBetween(yCoord(startPoint) yCoord(sramLoc) yCoord(endPoint)) then + (if boundp('debug) && debug >= 4 printf("VERT: Found matching SRAM %L %L %L\n" startPoint sramLoc endPoint)) + sramSegIndex = sramIdx + ) + else + (if almostEqual(yCoord(startPoint) yCoord(sramLoc)) && + !almostEqual(xCoord(startPoint) xCoord(sramLoc)) && + Ru_IsBetween(xCoord(startPoint) xCoord(sramLoc) xCoord(endPoint)) then + ( if debug >= 4 printf("HOR: Found matching SRAM %L %L %L\n" startPoint sramLoc endPoint)) + sramSegIndex = sramIdx + ) + ) + pathSegIdx++ + ) + sramIdx++ + ) + + (if sramSegIndex >= 0 && boundp('debug) && debug >= 1 printf("getSramSegmentIndex: Found a SRAM location at index %d Cfg: %L\n" + sramSegIndex nth(sramSegIndex sramCfgList))) + sramSegIndex +) + +(defun ru_openCellView (viewProp) + view = dbOpenCellViewByType(nth(0 viewProp) nth(1 viewProp) nth(2 viewProp)) + (if !view then + printf("ERROR: Unable to find view %L\n" viewProp) + ) + view +) + +(defun ru_getViewParms (viewProp) + (if boundp('debug) && debug >= 3 printf("getViewParms viewProp %L\n" viewProp)) + (let (cellView cellOffset gapHor gapVert subView baseName len idx value) + cellView = ru_openCellView(viewProp) + cellOffset = 0.0:0.0 + gapHor = ru_roundUp(abs(xCoord(lowerLeft(cellView->bBox))-xCoord(upperRight(cellView->bBox)))) + gapVert = ru_roundUp(abs(yCoord(lowerLeft(cellView->bBox))-yCoord(upperRight(cellView->bBox)))) + subView = nil + baseName = nil + + len = length(viewProp) + (for idx 3 (len-1) + value = nth(idx viewProp) + (cond + ((listp(value) && length(value)==2 && numberp(nth(0 value)) && numberp(nth(1 value))) cellOffset = value) /*location format*/ + (numberp(value) gapVert = value gapHor = value) + (listp(value) subView = value) + (stringp(value) baseName = value) + (t printf("getViewParms: ERROR: Unhandled entry type %L\n" value)) + ) + ) + list(cellView cellOffset gapHor gapVert subView baseName) + ) +) + +(defun ru_roundUp (value) + ;printf("floor %f %d %f\n" value floor(value/TrackPitch) (floor(value/TrackPitch)+1)*TrackPitch) + (floor(value/TrackPitch - TrackPitch/10)+1)*TrackPitch +) + +(defun ru_roundDown (value) + (floor(value/TrackPitch)+1)*TrackPitch +) + +(defun ru_drawCellSegments (bufPrefixName bufirePrefixName path segPropList layerPattern + bufView viewExceptionList sramCfgList + firstPathLayerPat lastPathLayerPat altLayerPattern doubleVias drawPat ) + (if boundp('debug) && debug >= 3 printf("drawCellSegments segPropList %L\n" segPropList) ) + + ; get the various views and offsets + bufOffsetVert = 0.0:0.0 + bufOffsetHor = 0.0:0.0 + bufGapVert = 1*TrackPitch + bufGapHor = 1*TrackPitch + rightViewProp = nth(0 bufView) + rightViewParms = ru_getViewParms(rightViewProp) + rightView = nth(0 rightViewParms) + bufOffsetHor = nth(1 rightViewParms) + bufGapHor = nth(2 rightViewParms) + bufGapVert = nth(3 rightViewParms) + bufRightSubViewProp = nth(4 rightViewParms) + + bufViewLen = length(bufView) + (if boundp('debug) && debug >= 5 printf("BufView %L len %d\n" bufView bufViewLen) ) + (if bufViewLen >= 2 then + upViewProp = nth(1 bufView) + upViewParms = ru_getViewParms(upViewProp) + upView = nth(0 upViewParms) + bufOffsetVert = nth(1 upViewParms) + bufGapVert = nth(3 upViewParms) + bufUpSubViewProp = nth(4 upViewParms) + else + upView = rightView + bufUpSubViewProp = bufRightSubViewProp + ) + + (if bufViewLen >= 3 then + leftViewProp = nth(2 bufView) + leftViewParms = ru_getViewParms(leftViewProp) + leftView = nth(0 leftViewParms) + bufLeftSubViewProp = nth(4 leftViewParms) + else + leftView = rightView + bufLeftSubViewProp = bufRightSubViewProp + ) + (if bufViewLen >= 4 then + downViewProp = nth(3 bufView) + downViewParms = ru_getViewParms(downViewProp) + downView = nth(0 downViewParms) + bufDownSubViewProp = nth(4 downViewParms) + else + (if bufViewLen == 2 then + downView = upView + bufDownSubViewProp = bufUpSubViewProp + else + downView = rightView + bufDownSubViewProp = bufRightSubViewProp + ) + ) + + segNum = 0 + lastPoint = nth(0 path) + lastCellLoc = nth(0 path) + (foreach segProp segPropList + (if boundp('debug) && debug >= 2 printf("drawCellSegments#%d: %L\n" segNum segProp)) + cellLocProp = nth(0 segProp) + cellType = nth(0 cellLocProp) + cellName = nth(1 cellLocProp) + cellLoc = Ru_AlignBufXY(nth(2 cellLocProp)) + index = nth(3 cellLocProp) + + viewExptCfg = nil + lastSegment = (segNum == (length(segPropList)-1)) + (if !lastSegment viewExptCfg = ru_getViewException(viewExceptionList cellName)) + (cond + (viewExptCfg + exptViewProp = nth(1 viewExptCfg) + (if boundp('debug) && debug >= 1 printf("%s: Cellview is overrided with %L\n" cellName exptViewProp)) + exptViewParms = ru_getViewParms(exptViewProp) + exptView = nth(0 exptViewParms) + exptCellOffset = nth(1 exptViewParms) + exptGapHor = nth(2 exptViewParms) + exptGapVert= nth(3 exptViewParms) + exptSubViewProp = nth(4 exptViewParms) + ;assuming view exception is only for BUF cell + wireName = sprintf(nil "%s[%d]" bufWirePrefixName index) + cellGapVert = exptGapVert + cellGapHor = exptGapHor + ) + (cellType == "BUF" + wireName = sprintf(nil "%s[%d]" bufWirePrefixName index) + cellGapVert = bufGapVert + cellGapHor = bufGapHor + ) + (cellType == "SRAM" + sramCfg = nth(index sramCfgList) + wireName = nth(1 sramCfg) + sramViewProp = nth(3 sramCfg) + sramViewParms = ru_getViewParms(sramViewProp) + sramView = nth(0 sramViewParms) + sramCellOffset = nth(1 sramViewParms) + sramGapHor = nth(2 sramViewParms) + sramGapVert= nth(3 sramViewParms) + sramSubViewProp = nth(4 sramViewParms) + + cellGapVert = sramGapVert + cellGapHor = sramGapHor + ) + (cellType == "END" + printf("Last segment\n") + wireName = sprintf(nil "%s[%d]" bufWirePrefixName index) + cellGapVert = bufGapVert + cellGapHor = bufGapHor + ) + (t printf("drawCellSegments: ERROR Unhandle cellType %s\n" cellType)) + ) + + dist = abs(xCoord(cellLoc)-xCoord(lastCellLoc)) + abs(yCoord(cellLoc)-yCoord(lastCellLoc)) + maxDist = 470.0 + (if dist > maxDist then + printf("drawCellSegments: ERROR: %s (%L) distance to last cell (%L) is %f, maxManDist is %f\n" + cellName cellLoc lastCellLoc dist maxDist) + ) + lastCellLoc= cellLoc + seg = nth(1 segProp) + + offsetOrientX = 0.0 + offsetOrientY = 0.0 + offsetEndX = 0.0 + offsetEndY = 0.0 + cellOrient = "R0" + nextPoint = nth(0 seg) + endPoint = nth((length(seg)-1) seg) + (if length(seg) > 1 then + prevPoint = nth((length(seg)-2) seg) + else + prevPoint = lastPoint + ) + + ;printf("NEXTPOINT %L %L %f %f %f %f\n" lastPoint nextPoint xCoord(nextPoint) xCoord(lastPoint) yCoord(nextPoint) yCoord(lastPoint) ) + (if xCoord(nextPoint) == xCoord(lastPoint) then + (if yCoord(nextPoint) < yCoord(lastPoint) then + offsetStartY = 0.0 + ;printf("Start Vertical going down\n") + else + offsetStartY = 0.0 + ;printf("Start Vertical going up\n") + ) + ) + (if xCoord(endPoint) == xCoord(prevPoint) then + (if yCoord(endPoint) < yCoord(prevPoint) then + (if !lastSegment offsetEndY = cellGapVert) + cellOrient = "MX" + offsetOrientX = 0.0 + offsetOrientY = cellGapVert + direction = "DOWN" + ;printf("End Vertical going down\n") + else + (if !lastSegment offsetEndY = offsetEndY = -cellGapVert) + direction = "UP" + offsetOrientX = 0.0 + offsetOrientY = -cellGapVert + ;printf("End Vertical going up\n") + ) + ) + + (if yCoord(nextPoint) == yCoord(lastPoint) then + (if xCoord(nextPoint) < xCoord(lastPoint) then + ;printf("Start Horizontal going left\n") + else + ;printf("Start Horizontal going right\n") + ) + ) + (if yCoord(endPoint) == yCoord(prevPoint) then + (if xCoord(endPoint) < xCoord(prevPoint) then + (if !lastSegment offsetEndX = cellGapHor) + offsetOrientX = cellGapHor + offsetOrientY = 0.0 + cellOrient = "MY" + direction = "LEFT" + ;printf("End Horizontal going left\n") + else + (if !lastSegment offsetEndX = -cellGapHor) + offsetOrientX = -cellGapHor + offsetOrientY = 0.0 + direction = "RIGHT" + ;printf("End Horizontal going right\n") + ) + ) + + (if yCoord(nextPoint) == yCoord(lastPoint) then + ;printf("Start Horizontal\n") + offsetX = cellGapHor + (if xCoord(nextPoint) < xCoord(lastPoint) offsetX = -offsetX) + ) + + (if boundp('debug) && debug >= 2 printf("%s segNum %d start %L list %L end %L endOff %L cellGapHor %f cellGapVert %f\n" + cellName segNum lastPoint seg endPoint (offsetEndX:offsetEndY) cellGapHor cellGapVert)) + + ;not used + offsetStartX = 0.0 + offsetStartY = 0.0 + pointList = list((xCoord(lastPoint)+offsetStartX):(yCoord(lastPoint)+offsetStartY)) + (for cnt 0 length(seg)-2 + pointList = append(pointList list(nth(cnt seg))) + ) + pointList = append(pointList list((xCoord(endPoint)+offsetEndX):(yCoord(endPoint)+offsetEndY))) + + (if boundp('debug) && debug >= 0 printf("drawCellSegments: length %d segNum %d dir %s PointList %L cellLoc %L offset %L %L\n" + length(segPropList) segNum direction pointList cellLoc (offsetStartX:offsetStartY) (offsetEndX:offsetEndY))) + + (if drawPath then + pathSeg = dbCreatePath(geGetEditCellView() list("M8" "bus") pointList 0.12 ) + busPattern = "" + (foreach lp layerPattern + (if strlen(busPattern) > 1 busPattern = strcat(busPattern " ")) + busPattern = strcat(busPattern nth(0 lp)) + ) + (dbReplaceProp pathSeg "BusArrayPitch" "float" 2.88) + (dbReplaceProp pathSeg "BusPattern" "string" busPattern) + (dbReplaceProp pathSeg "BusPrefix" "string" wireName) + (dbReplaceProp pathSeg "BusPin" "boolean" nil) + (dbReplaceProp pathSeg "BusFlipX" "boolean" nil) + (dbReplaceProp pathSeg "BusFlipY" "boolean" nil) + (dbReplaceProp pathSeg "BusStartVias" "boolean" nil) + (dbReplaceProp pathSeg "BusEndVias" "boolean" nil) + (dbReplaceProp pathSeg "BusDoubleVias" "boolean" t) + else + ru_createWireSegment(wireName segNum pointList lastSegment path layerPattern + firstPathLayerPat lastPathLayerPat altLayerPattern doubleVias) + ) +forceView = nil + (if !lastSegment then + inst = (dbFindAnyInstByName (geGetEditCellView) cellName) + (if !inst then + cna = parseString(cellName "[]") + (foreach extra list("_V" "_H") + instName = sprintf(nil "%s%s[%s]" nth(0 cna) extra nth(1 cna)) + (if !inst then + inst = (dbFindAnyInstByName (geGetEditCellView) instName) + ) + ) + ) + (if inst then + subViewPropList = nil + (cond + (viewExptCfg + cellOffset = exptCellOffset + (if forceView inst->master = exptView) + subViewPropList = exptSubViewProp + ) + (cellType == "BUF" + (if direction == "RIGHT" then (if forceView inst->master = rightView) cellOffset = bufOffsetHor subViewPropList = bufRightSubViewProp) + (if direction == "UP" then (if forceView inst->master = upView) cellOffset = bufOffsetVert subViewPropList = bufUpSubViewProp) + (if direction == "LEFT" then (if forceView inst->master = leftView) cellOffset = bufOffsetHor subViewPropList = bufLeftSubViewProp) + (if direction == "DOWN" then (if forceView inst->master = downView) cellOffset = bufOffsetVert subViewPropList = bufDownSubViewProp) + ) + (cellType == "SRAM" + cellOffset = sramCellOffset + (if forceView inst->master = sramView) + subViewPropList = sramSubViewProp + ) + (t printf("drawCellSegments: ERROR Unhandle cellType %s\n" cellType)) + ) + instOff = (xCoord(cellOffset)+offsetOrientX):(yCoord(cellOffset)+offsetOrientY) + (if boundp('debug) && debug >= 2 printf("%s: instOff %L cellOffset %L %f %f\n" cellName instOff cellOffset offsetOrientX offsetOrientY)) + inst->xy = Ru_OffsetPoint(cellLoc instOff) + inst->orient = cellOrient + (if subViewPropList then + (if boundp('debug) && debug >= 3 printf("%s: Adding subviewList %L\n" cellName subViewPropList)) + (foreach subViewProp subViewPropList + (if boundp('debug) && debug >= 5 printf("%s: Adding subview %L\n" cellName subViewProp)) + + svParms = ru_getViewParms(subViewProp) + ;printf("%s: subViewParms %L\n" cellName svParms) + subView = nth(0 svParms) + svCellOffset = nth(1 svParms) + svGapHor = nth(2 svParms) + svGapVert= nth(3 svParms) + svBaseName = nth(5 svParms) + (if !svBaseName || !stringp(svBaseName) then + printf("ERROR: %s: Need a proper base name (%L) for the subView %L\n" + cellName svBaseName subViewProp) + else + svCellName = sprintf(nil "%s[%d]" svBaseName segNum) + printf("%s: Move to %s with offset %L\n" svCellName cellName svCellOffset) + MoveInst(svCellName Ru_OffsetPoint(inst->xy svCellOffset)) + ) + ) + ) + else + printf("drawCellSegments: ERROR: Unable to find %s\n" cellName) + ) + ) + + lastPoint = nth((length(seg)-1) seg) + segNum++ + ) +) + +(defun ru_createWireSegment (wireName segNum points lastSegment path layerPattern + firstPathLayerPat lastPathLayerPat altLayerPattern doubleVias ) + (if boundp('debug) && debug >= 3 printf("createWireSegment: %s points %L lastSeg %L\n" wireName points lastSegment )) + (let (segLp altLp altPatternList altPatCfg cnt altLayerPatternList lp layer pattern + pathSegIdx dir result) + segLp = nil + altPatternList = nil + (if altLayerPattern then + altPatCfg = nth(segNum altLayerPattern) + segLp = nth(0 altPatCfg) + altLp = nth(1 altPatCfg) + (if boundp('debug) && debug >= 5 then + (if segLp printf("###createWireSegment: %s Using alternate pattern configuration %L\n" + wireName segLp)) + (if altLp printf("altPatternList %L\n" altLp)) + ) + ) + (if !segLp segLp = layerPattern) + + cnt = 0 + altLayerPatternList = nil + forceLayerPattern = nil + forceAltLayerPattern = nil + dir = "UNKNOWN" + (if firstPathLayerPat || lastPathLayerPat then + numPoints = length(points) + result = ru_getPathSegment(nth(0 points) path) + pathSegIdx = nth(0 result) + dir = nth(1 result) + ;printf("result %L %d %s numPoints %d\n" result pathSegIdx dir numPoints) + (if pathSegIdx == 0 then + (if numPoints == 2 then + (if boundp('debug) && debug >= 1 printf("%s First path segment using firstPathLayerPat\n" wireName)) + forceLayerPattern = firstPathLayerPat + else + (if boundp('debug) && debug >= 1 printf("%s First path segment switching firstPathLayerPat to layerPattern\n" wireName)) + forceLayerPattern = firstPathLayerPat + forceAltLayerPattern = layerPattern + ) + ) + (if pathSegIdx == (length(path)-2) && numPoints == 2 then + (if boundp('debug) && debug >= 1 printf("%s Last path segment using lastPathLayerPat\n" wireName)) + forceLayerPattern = lastPathLayerPat + ) + (if pathSegIdx == (length(path)-3) && numPoints > 2 then + (if boundp('debug) && debug >= 1 printf("%s Last path segment switching layerPattern to lastPathLayerPat\n" wireName)) + forceLayerPattern = layerPattern + forceAltLayerPattern = lastPathLayerPat + ) + ) + + (foreach lp segLp + (if forceLayerPattern then + layer = nth(0 nth(cnt forceLayerPattern)) + pattern = nth(1 nth(cnt forceLayerPattern)) + (if boundp('debug) && debug >= 2 printf("%s: Layer#%d: Using layer %L Pattern %L\n" wireName cnt layer pattern)) + else + layer = nth(0 lp) + pattern = nth(1 lp) + ) + (if altLp altLayerPatternList = nth(cnt altLp)) + (if boundp('debug) && debug >= 3 printf("###### Seg %d layer#%d %L pattern %L \naltPattern %L \n" + segNum cnt layer pattern altLayerPatternList)) + (if forceAltLayerPattern then + layer2 = nth(0 nth(cnt forceAltLayerPattern)) + (if dir == "HOR" then + hLayer = nth(0 layer) + vLayer = nth(1 layer2) + else + hLayer = nth(1 layer) + vLayer = nth(0 layer2) + ) + + hl = ru_layerToValue(nth(0 hLayer)) + vl = ru_layerToValue(nth(0 vLayer)) + viasList = nil + (if hl < vl then + (for l hl (vl-1) + viasList = append(viasList list(sprintf(nil "M%d_M%d" l+1 l))) + ) + else + (for l vl (hl-1) + viasList = append(viasList list(sprintf(nil "M%d_M%d" l+1 l))) + ) + ) + (if boundp('debug) && debug >= 2 printf("%s: hLayer %L vLayer %L hl %d vl %d viasList %L\n" + wireName hLayer vLayer hl vl viasList)) + + layer = list(hLayer vLayer viasList "V") + altLayerPatternList = list(list(layer nth(1 nth(cnt forceAltLayerPattern)))) + (if boundp('debug) && debug >= 2 printf("%s: Forcing layer %L Pattern %L\n" wireName layer pattern)) + (if boundp('debug) && debug >= 2 printf("%s: Forcing altLayerPattern %L\n" wireName altLayerPatternList)) + ) + (DrawChannel layer pattern wireName points + ?altLayerPatternList altLayerPatternList + ?doubleVias doubleVias) + cnt++ + ) + (if boundp('debug) && debug >= 3 printf("createWireSegment: DONE\n")) + ) +) + +(defun ru_getNextGuide (guideMap lastLoc dirRight) + (if boundp('debug) && debug >= 4 printf( "getNextGuide %L dirRight %L\n" guideMap lastLoc dirRight) ) + (let (lastPosIdx lastNegIdx idx val delta negDelta posDelta ret) + lastPosIdx = length(guideMap)-1 + lastNegIdx = 0 + idx = 0 + (foreach val guideMap + delta = val - lastLoc + negDelta = nth(lastNegIdx guideMap) - lastLoc + posDelta = nth(lastPosIdx guideMap) - lastLoc + (if boundp('debug) && debug >= 5 printf("guideMap#%d: %f delta %f lastLoc %f lastNegIdx %d negDelta %f lastPosIdx %d posDelta %f\n" + idx nth(idx guideMap) delta lastLoc lastNegIdx negDelta lastPosIdx posDelta) ) + + (if (delta > 2.8*8 && delta < posDelta ) lastPosIdx = idx ) + (if (delta < -2.8*8 && delta > negDelta ) lastNegIdx = idx ) + idx++ + ) + (if boundp('debug) && debug >= 3 printf( "getNextGuideX return %d guide loc %f\n",lastNegIdx nth(lastNegIdx guideMap)) ) + (if dirRight then ret = nth(lastPosIdx guideMap) + else ret = nth(lastNegIdx guideMap) + ) + ) +) + +(defun ru_findNextGuideLoc (guideX guideY dir lastPoint nextPoint bufDist) + (if boundp('debug) && debug >= 4 printf( "findNextGuideLoc dir %s lastPoint %L nextPoint %L\n" dir lastPoint nextPoint) ) + (let (nextGuideLoc nextGuideX dist) + nextGuideLoc = nil + (if dir == "HOR" && guideX then + nextGuideX = ru_getNextGuide(guideX xCoord(lastPoint) (xCoord(nextPoint)>xCoord(lastPoint))) + nextGuideLoc = nextGuideX:yCoord(lastPoint) + dist = Ru_GetDistance(lastPoint nextGuideLoc) + ;printf("last %L guideX %f next %L dist %f\n" lastPoint nextGuideX nextPoint dist) + (if Ru_IsBetween(xCoord(lastPoint) nextGuideX xCoord(nextPoint)) && + dist > TrackPitch && dist < bufDist then + (if boundp('debug) && debug >= 2 printf("Found a guide xCoord at %f and %f from last buffer\n" nextGuideX dist)) + else + nextGuideLoc = nil + ) + ) + (if dir == "VERT" && guideY then + nextGuideY = ru_getNextGuide(guideY yCoord(lastPoint) (yCoord(nextPoint)>yCoord(lastPoint))) + nextGuideLoc = xCoord(lastPoint):nextGuideY + dist = Ru_GetDistance(lastPoint nextGuideLoc) + (if Ru_IsBetween(yCoord(lastPoint) nextGuideY yCoord(nextPoint)) && + dist > TrackPitch && dist < bufDist then + (if boundp('debug) && debug >= 2 printf("Found a guide yCoord at %f and %f from last buffer\n" nextGuideY dist)) + else + nextGuideLoc = nil + ) + ) + nextGuideLoc + ) +) + +(defun ru_drawPathGuide (path guideX guideY) + (let (maxX maxY minX minY point) + maxX = -9999.0 + maxY = -9999.0 + minX = 9999.0 + minY = 9999.0 + + (foreach point path + (if xCoord(point) > maxX maxX = xCoord(point)) + (if xCoord(point) < minX minX = xCoord(point)) + (if yCoord(point) > maxY maxY = yCoord(point)) + (if yCoord(point) < minY minY = yCoord(point)) + ) + + (if guideX then + (foreach X guideX + dbCreatePath((geGetEditCellView) list("M2" "drawing") list(X:minY X:maxY) 1 "extendExtend") + ) + ) + (if guideY then + (foreach Y guideY + dbCreatePath((geGetEditCellView) list("M3" "drawing") list(minX:Y maxX:Y) 1 "extendExtend") + ) + ) + ) +) + +(defun ru_getLocException (locExceptionList bufName bufIdx colIdx) + (let (listLen foundIdx idx exception nameList name colMatched bufSeg + nameMatched numMatched result val1 val2) + rexMagic(t) + listLen = length(locExceptionList) + foundIdx = -1 + (if boundp('debug) && debug >= 4 printf( "getLocException %s.%d listLen %d\n" bufName bufIdx listLen) ) + (for idx 0 listLen-1 + exception = nth(idx locExceptionList) + nameList = nth(0 exception) + (if !nameList then nameMatched = t + else + (if !listp(nameList) nameList = list(nameList)) + (foreach name nameList + (if rexMatchp(name bufName) nameMatched = t) + ) + ) + result = parseString(nth(1 exception) ":") + colMatched = t + (cond + (length(result)==1 + bufSeg = nth(1 exception) + ) + (length(result)==2 + colMatched = (Ru_StringToInt(nth(0 result))==colIdx) + bufSeg = nth(1 result) + ) + (t error("Not support for %L\n" result)) + ) + ;printf("nameMatched %L colMatched %L colIdx %L bufSeg %L result %L\n" nameMatched colMatched colIdx bufSeg result) + (if nameMatched && colMatched then + numMatched = nil + (if integerp(bufSeg) then + (if bufIdx == bufSeg numMatched = 1) + else + result = parseString(bufSeg "-") + (if length(result) == 2 then + val1 = Ru_StringToInt(car(result)) + val2 = Ru_StringToInt(cadr(result)) + (if bufIdx >= val1 && bufIdx <= val2 numMatched = t) + ) + result = parseString(bufSeg ",") + (if member(sprintf(nil "%d" bufIdx) result) numMatched = 1) + ) + (if numMatched then + (if boundp('debug) && debug >= 3 + printf("getLocException: %s.%d: Found in exception list index %d : %L\n" + bufName bufIdx idx exception) + ) + foundIdx = idx + ) + ) + ) + (if foundIdx >=0 then ret = nth(foundIdx locExceptionList) + else ret = nil + ) + ) +) + +(defun ru_getViewException (viewExceptionList cellName) + (if boundp('debug) && debug >= 4 printf( "getViewException %s ExptList %L\n" cellName viewExceptionList) ) + (let (listLen foundIdx idx exception nameList name) + listLen = length(viewExceptionList) + foundIdx = -1 + (if boundp('debug) && debug >= 4 printf( "getViewException %s listLen %d\n" cellName listLen) ) + (for idx 0 listLen-1 + exception = nth(idx viewExceptionList) + nameList = nth(0 exception) + (foreach name nameList + (if name == cellName then + (if boundp('debug) && debug >= 3 + printf("getviewException: %s: Found in exception list index %d : %L\n" + cellName idx exception) + ) + foundIdx = idx + ) + ) + ) + (if foundIdx >=0 then ret = nth(foundIdx viewExceptionList) + else ret = nil + ) + ) +) + +(defun ru_layerToValue (layer) + (let (ret) + (case layer + ("M2" ret = 2) + ("M3" ret = 3) + ("M4" ret = 4) + ("M5" ret = 5) + ("M6" ret = 6) + ("M7" ret = 7) + (t printf("layerToValue: Unhandled layer %L\n" layer)) + ) + ret + ) +) + +(defun ru_getSegDir (startPoint endPoint @key (detail nil)) + (let (dir) + (if !startPoint || !endPoint + error("ru_getSegDir Invalid startPoint %L or endPoint %L\n" startPoint endPoint)) + (if almostEqual(xCoord(startPoint) xCoord(endPoint)) then + (if detail then dir = (if yCoord(startPoint) < yCoord(endPoint) "UP" "DOWN") + else dir = "VERT") + else + (if detail then dir = (if xCoord(startPoint) < xCoord(endPoint) "RIGHT" "LEFT") + else dir = "HOR") + ) + (if boundp('debug) && debug >= 5 printf("getSegDir %L %L -> %s\n" startPoint endPoint dir)) + dir + ) +) + +(defun Ru_PathDistance (path) + (let (totalDist cnt) + totalDist = 0.0 + (if path then + (for cnt 1 length(path)-1 + totalDist = totalDist + Ru_GetDistance(nth(cnt-1 path) nth(cnt path)) + ) + ) + totalDist + ) +) + +(defun Ru_GetDistance (a b) + (if boundp('debug) && debug >= 5 printf("getDistance %L %L\n" a b)) + (let (ret) + ret = abs(xCoord(a)-xCoord(b)) + abs(yCoord(a)-yCoord(b)) + ) +) + +;if b is between a c +(defun Ru_IsBetween (a b c) + (if boundp('debug) && debug >= 5 printf("isBetween %f %f %f\n" a b c)) + (let (ret) + ;not a very good way to figure out + (if c > a && b <= c && b >= a ret = t) + (if c < a && b >= c && b <= a ret = t) + ret + ) +) + +(defun OffsetPoint (point dx dy) + (let (retPoint) + retPoint = (xCoord( point)+dx):(yCoord(point)+dy) + ) +) + +(defun Ru_OffsetPoint (point offset) + (if boundp('debug) && debug >= 4 printf( "offsetPoint %L %L\n" point offset) ) + (let (retPoint) + retPoint = ( xCoord( point)+xCoord(offset)):(yCoord(point)+yCoord(offset)) + ) +) + +(defun Ru_OffsetPoints (points offset) + (if boundp('debug) && debug >= 4 printf( "offsetPoints %L %L\n" points offset) ) + (let (retPoints = list(nil)) + (foreach point points + retPoints = append(retPoints list((xCoord(point)+xCoord(offset)):(yCoord(point)+yCoord(offset)))) + ) + retPoints + ) +) + +(defun MoveInst (name loc @key (orient nil)) + (if boundp('debug) && debug >= 3 printf("moveInst %s to %L\n" name loc)) + (let (inst) + inst = (dbFindAnyInstByName (geGetEditCellView) name) + (if inst then + inst->xy = loc + (if orient inst->orient = orient) + else + printf("ERROR: Unable to find %s. Need a buffer at %L\n" name, loc) + ) + inst + ) +) + +(defun ShiftInst (name loc @key (orient nil) (bufPrefix "")) + (if boundp('debug) && debug >= 3 printf("ShiftInst %s to %L\n" name loc)) + (let (inst) + inst = (dbFindAnyInstByName (geGetEditCellView) sprintf(nil "%s%s" bufPrefix name)) + (if inst then + inst->xy = Ru_OffsetPoint(inst->xy loc) + (if orient inst->orient = orient) + else + printf("ERROR: Unable to find %s%s. Need to shift buffer by %L\n" bufPrefix name loc) + ) + ) + t +) + +(defun Ru_MoveInstVH (prefix num loc @key (orient nil)) + (if boundp('debug) && debug >= 3 printf("moveInst %s to %L\n" name loc)) + (let (inst) + inst = nil + (foreach extra list("" "_V" "_H") + instName = sprintf(nil "%s%s[%d]" prefix extra num) + (if !inst inst = (dbFindAnyInstByName (geGetEditCellView) instName)) + ) + (if inst then + inst->xy = loc + (if orient inst->orient = orient) + else + printf("ERROR: Unable to find %s[%d]. Need a buffer at %L\n" prefix num loc) + ) + inst + ) +) + +(defun Ru_AlignX (locX) + floor((locX+TrackPitch/64)/TrackPitch)*TrackPitch +) +(defun Ru_AlignY (locY) + floor((locY+TrackPitch/64)/(2*TrackPitch))*2*TrackPitch +) + +(defun Ru_AlignBufY (loc) + locY = yCoord(loc) + locX = xCoord(loc) + locX:Ru_AlignY(locY) +) + +(defun Ru_AlignBufXY (loc) + locY = yCoord(loc) + locX = xCoord(loc) + round((locX-TrackPitch/2)/TrackPitch)*TrackPitch:Ru_AlignY(locY) +) + + +;very slow +(defun Ru_StringToInt (str) + (let (p value) + p = instring(str) + fscanf(p "%d" value) + value + ) +) + +(defun Ru_StringIsInt (str) + rexMatchp("[0-9]" str) +) + + +(defun Ru_SortChannelElByTrack (a b) + a < b +) +(defun Ru_SortCarChannelElByTrack (a b) + car(a) < car(b) +) +(defun Ru_SortChannelElByWireLength (a b) + nth(6 a) < nth(6 b) +) + +(defun Ru_SortChannelElByName (a b) + (let (resulta resultb) + resulta = parseString(a "[]") + resultb = parseString(b "[]") + (cond + (length(resulta)==2 + (if strcmp(car(resulta) car(resultb)) == 0 then + Ru_StringToInt(cadr(resulta)) < Ru_StringToInt(cadr(resultb)) + else strcmp(car(resulta) car(resultb)) < 0) + ) + (t (strcmp(a b) < 0)) + ) + ) +) +(defun Ru_SortCarChannelElByName (a b) + Ru_SortChannelElByName(cadr(a) cadr(b)) +) + +(defun Ru_CastToPatternName (name) + sprintf(nil "smr_%s" name) +) +(defun Ru_LayoutToPatternName (name) + (cond + (name == "e1of4" sprintf(nil "smr_%s" name)) + (name == "e1of3" sprintf(nil "smr_%s" name)) + (name == "e1of2" sprintf(nil "smr_%s" name)) + (t name) + ) +) + +(defun Ru_LayerToBusMetal (layer) + (let (busMetal) + (cond + (layer == "M2" busMetal = "BusMetal23") + (layer == "M3" busMetal = "BusMetal23") + (layer == "M4" busMetal = "BusMetal45") + (layer == "M5" busMetal = "BusMetal45") + (layer == "M6" busMetal = "BusMetal67") + (layer == "M7" busMetal = "BusMetal67") + (t busMetal = "BusMetal67") + ) + busMetal + ) +) + + +(defun Ru_GetNodeMap (nodeMap nodeList) + (let (ret retOff e cnt nodeMatched) + retOff = 0.0 + (foreach e nodeMap + (if !ret then + nodeMatched = t + (for cnt 1 length(e)-1 + (if nodeMatched && nth(1 nth(cnt-1 nodeList)) != nth(0 nth(cnt e)) nodeMatched = nil) + (if nodeMatched && !almostEqual(nth(2 nth(cnt-1 nodeList)) nth(1 nth(cnt e))) nodeMatched = nil) + ) + (if nodeMatched ret = car(e)) + ) + ) + (if !ret then ;maybe it is not centered + (foreach e nodeMap + (if !ret then + nodeMatched = t + (for cnt 1 length(e)-1 + (if nodeMatched && nth(1 nth(cnt-1 nodeList)) != nth(0 nth(cnt e)) nodeMatched = nil) + ;offset from the first entry + (if nodeMatched && !almostEqual(nth(2 nth(cnt-1 nodeList))-nth(2 nth(0 nodeList)) + nth(1 nth(cnt e))-nth(1 nth(1 e)) ) nodeMatched = nil) + /* + printf("%L %L\n" nodeList e) + printf("nodeMatched %L %f %f = %f %f %f = %f\n" + nodeMatched nth(2 nth(cnt-1 nodeList)) nth(2 nth(0 nodeList)) + nth(2 nth(cnt-1 nodeList))-nth(2 nth(0 nodeList)) + nth(1 nth(cnt e)) nth(1 nth(1 e)) + nth(1 nth(cnt e))-nth(1 nth(1 e))) + */ + ) + (if nodeMatched then + ret = car(e) + retOff = nth(2 nth(0 nodeList)) - nth(1 nth(1 e)); - 1.44 + ;printf("retOff %L nodeList %L foundE %L\n" retOff nodeList e) + ) + ) + ) + ) + (if ret then list(ret retOff) else ret) + ) +) + +(defun Ru_GetNodePattern (nodeList) + (let (ret nodeLen nodePatternMap e) + e1of1Map = list( + list("smr_e1of1" list("0" 1.32) list("e" 0.54)) + list("e1of1" list("0" 1.2) list("e" 1.44)) + list("e1of1a" list("0" -0.48) list("e" -0.9)) + list("e1of1b" list("0" -0.6) list("e" -0.18)) + ) + e1of2Map = list( + list("smr_e1of2" list("0" 1.32) list("1" 1.68) list("e" 0.54)) +; list("e1of2" list("0" 0.0) list("1" 0.48) list("e" 0.24)) + list("inlv_e1of2_A" list("0" 0.84) list("1" 1.80) list("e" 1.32)) + list("inlv_e1of2_B" list("0" 1.08) list("1" 2.04) list("e" 1.56)) + list("smr_1of3" list("0" 1.32) list("1" 1.68) list("2" 2.04)) ;3 elements + ) + e1of3Map = list( + list("smr_e1of3" list("0" 1.32) list("1" 1.68) list("2" 2.04) list("e" 0.54)) + ) + e1of4Map = list( + list("smr_e1of4" list("0" 1.32) list("1" 1.68) list("2" 2.04) list("3" 2.4) list("e" 0.54)) +; list("e1of4" list("0" 0.0) list("1" 0.24) list("2" 0.72) list("3" 0.96) list("e" 0.48)) + list("inlv_e1of4_A" list("0" 0.36) list("1" 0.84) list("2" 1.8) list("3" 2.28) list("e" 1.32)) + list("inlv_e1of4_B" list("0" 0.6) list("1" 1.08) list("2" 2.04) list("3" 2.52) list("e" 1.56)) + ) + ret = nil + nodeLen = length(nodeList) + (cond + (nodeLen == 2 ret = Ru_GetNodeMap(e1of1Map nodeList)) + (nodeLen == 3 ret = Ru_GetNodeMap(e1of2Map nodeList)) + (nodeLen == 4 ret = Ru_GetNodeMap(e1of3Map nodeList)) + (nodeLen == 5 ret = Ru_GetNodeMap(e1of4Map nodeList)) + ;(t printf("Ru_GetNodePattern: ERROR: Unhandled node pattern: %L. Please report so it can be added\n" nodeList)) + ) + (if !ret ret = list("UNKNOWN_PATTERN" 0.0)) + ret + ) +) + +(defun matchedList (matchList name) + (prog (el) + (if !listp(matchList) then return(rexMatchp(matchList name)) + else + (foreach el matchList + (if rexMatchp(el name) return(t) ) + ) + ) + return(nil) + ) +) + + +; Pin(?pf "fc/hal/pins.il" ?cv halView ?debug 1 ?m "HD_L2F" ?c "HalToL2fHdChannel") +; Pin(?pf "fc/rxt_dist/pins.il" ?v rxtView ?sn t ?m "OUT_FT_SCA" ?c "RxtDistToScArFtC result2 %Lhannel") +(defun Pin (@key (M nil) (m nil) (o 0.0) (st nil) (sn nil) (sl nil) (pf nil) (c nil) (d nil) (e nil) + (g nil) (map nil) (h nil) (v nil) (f nil) (w t) (l nil) (L nil) (p nil) + (x nil) (y nil) (pinOffset nil) + (help nil) (debug 0)) + (prog (entries shape busPrefix busPattern busArrayPitch bbox x0 y0 x1 y1 name start end temp postFix skip baseNode entryCnt + busMetal points dir entry n match notMatch trackOff wireOff wireOffStr + cnt arrayCnt size view flipOffset offset offsetBase minOff + channel channelName el aka channelTable DFII_dir cmdLine layer idx wireLen wireLenMax wireLenMin wireLenSum wireLenCnt + filename inPort nextLine foundChannel result result2 arrayOffset nodeArrayPattern nodeEl iStr exactMatch + nodeBaseName nodeTable lastName nodeList castStart castEnd castPattern layoutStart layoutEnd layoutPattern + dumpPinPattern rangeX rangeY trackBaseOff pinName nameLen warnAbstract) + + (if !(help || h) then + rexMagic(t) + entries = nil + chanFound = nil + channelName = c + dumpPinPattern = p + match = m + notMatch = M + exactMatch = e + trackOff = o + rangeX = x + rangeY = y + (flipOffset = f) + (if v then view = v + else view = (geGetEditCellView)) + ; warn using abstract to generate pattern since the pins might be a polygon which incorrect generate the pattern + warnAbstract = nil + + cmdLine = "Pin(" + ;cmdLine = strcat(cmdLine sprintf(nil "?v %L" view->cellName)) + (if pf cmdLine = strcat(cmdLine sprintf(nil " ?pf %L" pf))) + (if m cmdLine = strcat(cmdLine sprintf(nil " ?m %s%L" (if listp(m) "list" "") m))) + (if M cmdLine = strcat(cmdLine sprintf(nil " ?M %s%L" (if listp(M) "list" "") M))) + (if e cmdLine = strcat(cmdLine sprintf(nil " ?e %L" e))) + (if o!= 0.0 cmdLine = strcat(cmdLine sprintf(nil " ?o %L" o))) + (if st cmdLine = strcat(cmdLine sprintf(nil " ?st %L" st))) + (if d cmdLine = strcat(cmdLine sprintf(nil " ?d %L" d))) + (if c cmdLine = strcat(cmdLine sprintf(nil " ?c %L" c))) + (if p cmdLine = strcat(cmdLine sprintf(nil " ?p %L" p))) + (if map cmdLine = strcat(cmdLine sprintf(nil " ?map %L" map))) + (if g cmdLine = strcat(cmdLine sprintf(nil " ?g %L" g))) + (if f cmdLine = strcat(cmdLine sprintf(nil " ?f %L" f))) + (if x cmdLine = strcat(cmdLine sprintf(nil " ?x list%L" x))) + (if y cmdLine = strcat(cmdLine sprintf(nil " ?y list%L" y))) + cmdLine = strcat(cmdLine ")") + (if pf then + (if p error("Cannot have both ?pf and ?p option at the same time\n")) + (if !channelName error("Must specify channelName when specify file\n")) + DFII_dir = ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + filename = (sprintf nil "%s/chip/alta/%s" DFII_dir pf) + (printf "Reading file %s ... \n", filename) + inPort = infile(filename) + (if !inPort error("Unable to open %s\n" filename)) + printf("Searching for %s\n" channelName) + (when inPort + (while gets( nextLine inPort ) + nextLine = substring(nextLine 1 strlen(nextLine)-1) ;remove \n, don't know a better way + (if foundChannel then + (if !rexMatchp(";" nextLine) foundChannel = nil) + (if rexMatchp("defchan" nextLine) foundChannel = nil) + ;(if !rexMatchp("\\{\\}" nextLine) foundChannel = nil) + (if debug >= 2 && !foundChannel printf("##### End of Channel: %L\n" nextLine)) + ) + (if foundChannel then + (if debug >= 2 printf("LINE: [%L]\n" nextLine)) + el = parseString(nextLine ";+ =-") + aka = nil + (for cnt 2 length(el)-2 + (if nth(cnt el) == "LAYOUT" aka = nth(cnt+1 el)) + ) + (foreach entry map + (if !aka && cadr(el) == car(entry) aka = cadr(entry)) + ) + (if debug >= 1 printf("EL: [%L] aka: %L\n" el aka)) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin(?pf "fc/l3_ar/pins.il" ?M "TCAM_" ?range list(-100 0) ?c "FfuToL3ArHdChannel_MID") +; Pin( ?pf "fc/l3_ar/output/pins.il" ?c "OutputOf0ToBsChannel_Hi" ?debug 5) + + (if length(el) >= 2 && (rexMatchp("^e1of" car(el)) || rexMatchp("^1of" car(el))) then + result = parseString(car(el) "[]") + temp = nil + (cond + (length(result) <= 2 + (if aka then temp = sprintf(nil "%s" aka)) + nodeList = list(list(sprintf(nil "%s" nth(0 el)) sprintf(nil "%s" nth(1 el)) temp) ) + ) + (length(result) == 3 ;2-D array + nodeList = nil + (for cnt 0 Ru_StringToInt(nth(1 result))-1 + (if aka then temp = sprintf(nil "%s[%d]" aka cnt)) + nodeList = append(nodeList list(list(sprintf(nil "%s[%s]" nth(0 result) nth(2 result)) sprintf(nil "%s[%d]" nth(1 el) cnt) temp))) + ) + ) + (t error("Unsupport this pattern %L\n" el)) + ) + (foreach el nodeList + (if rexMatchp("^e1of4v" car(el)) then + result = parseString(car(el) "()") + (if !cadr(result) error("Is e1of4v(n) delared correctly?\n")) + (if !cadr(el) error("Unexpected nil in nodeName: %L \n" el )) + channel = append(channel list(list(sprintf(nil "e1of4[%s]" cadr(result)) sprintf(nil "%s.D" cadr(el)) nth(2 el)))) + channel = append(channel list(list("e1of2" sprintf(nil "%s.V" cadr(el)) nth(2 el)))) + else + channel = append(channel list(list(car(el) cadr(el) nth(2 el)))) + ) + ) + ) + ) + (if rexMatchp(sprintf(nil "defchan %s[^a-zA-Z0-9_]" channelName) nextLine) then + foundChannel = t + (if channel error("Multiple instance of defchan for %L found. %L\n" channelName nextLine)) + (if debug >= 2 printf("##### Channel Found: %L\n" nextLine)) + else + (if debug >= 2 && rexMatchp("defchan" nextLine) then + printf("Found a [%L], looking for %L\n" nextLine channelName) + ) + ) + ) + ) + + (if g then + printf("############################### CHANNEL PATTERN ###############################\n\n\n") + printf("NOTE: Also copy the cmdLine below for reproducibility\n") + printf(";Generated by just assigning sequential track order with cmdLine:\n" ) + printf("; %s\n" cmdLine) + printf("c = nil\n") + cnt = 0 + (foreach el channel + busMetal = "BusMetal67" + busPattern = nth(0 el) + result = parseString(busPattern "[]") + (if debug >=2 printf("Entry: %L busPattern %L result %L\n" el busPattern result)) + (cond + (length(result) == 1 + printf("c = (cons (list \".%s\" %s %d*TrackPitch %s) c)\n" + nth(1 el) Ru_CastToPatternName(busPattern) cnt busMetal) + cnt++ + ) + (length(result) == 2 + size = Ru_StringToInt(nth(1 result)) + printf("(for i 0 %d\n" (size-1)) + printf(" name = (sprintf nil \".%s%s\" i)\n" nth(1 el) "[%d]") + printf(" c = (cons (list name %s (i*%d+%d)*TrackPitch %s) c)\n" + Ru_CastToPatternName(nth(0 result)) 1 cnt busMetal) + cnt = cnt + size + printf(")\n") + ) + (t printf("Unhandled busPattern of %L\n" busPattern)) + ) + ) + postFix = "" + printf("%s%s = (DefChan c)\n" channelName postFix) + printf("busPatterns = (cons (list \"%s%s\" %s%s) busPatterns)\n" channelName postFix channelName postFix) + printf("\n\n") + printf("Total channels: %L\n" cnt) + return(t) + else + (if debug >= 1 then + printf("Entries found for %s\n" channelName) + (foreach el channel + printf("channel: %L\n" el) + ) + ) + (if !channel error("ERROR: No entries found for %L\n" channelName)) + ) + ) +(if debug == 5 return(t)) + + channelTable = makeTable("channelTable" 0) + (foreach ch channel + el = nth(1 ch) + channelTable[el] = nil + ) + + (foreach shape view->shapes + (cond ((and shape->objType=="path" + (or shape->lpp==BusPath23 + shape->lpp==BusPath34 + shape->lpp==BusPath45 + shape->lpp==BusPath56 + shape->lpp==BusPath67)) + ;printf("CellView %L points %L\n" shape->cellView->cellName shape->points) + busPrefix = nil + busPattern = nil + busArrayPitch = nil + (foreach prop shape->prop + ;printf("prop: %L value: %L\n" prop->name prop->value) + (if prop->name == "BusPrefix" busPrefix = prop->value) + (if prop->name == "BusPattern" busPattern = prop->value) + (if prop->name == "BusArrayPitch" busArrayPitch = prop->value) + ) + points = shape->points + dir = ru_getSegDir(car(points) cadr(points)) + (if debug >= 2 printf("%s Path: %L BusPrefix: %L BusPattern: %L BusArrayPitch: %L\n" + dir points busPrefix busPattern busArrayPitch)) + (if busPrefix && (d==nil || d == dir) && (match==nil || matchedList(match busPrefix)) then + (if dir == "HOR" then offset = yCoord(car(points)) + else offset = xCoord(car(points))) + offset = offset - trackOff*TrackPitch + entry = list(list(offset busPrefix busPattern busArrayPitch shape->lpp dir)) + entries = append(entries entry) + (foreach ch channel + el = nth(1 ch) + aka = nth(2 ch) + rexMagic(nil) + (if aka && rexMatchp(aka busPrefix) then + (if debug >=2 printf("Appending AKA NODE %L: %L\n" aka busPrefix)) + channelTable[el] = append(channelTable[el] entry) + ) + (if !aka && rexMatchp(el busPrefix) then + (if debug >=2 printf("Appending NODE %L: %L\n" el busPrefix)) + result = parseString(busPrefix ".[]") + ;printf("el %L result %L\n" el result) + (if member(el result) then ;prevent a short name matching a long name + channelTable[el] = append(channelTable[el] entry) + ) + ) + rexMagic(t) + ) + ) + ) + (shape->pin + bbox = shape->bBox + x0 = (car (car bbox)) + y0 = (cadr (car bbox)) + x1 = (car (cadr bbox)) + y1 = (cadr (cadr bbox)) + name = shape->net->name + (if debug >=3 printf("(PinPlace \"%s\" (list %g:%g %g:%g) ?LPP (list \"%s\" \"%s\"))\n" + name x0 y0 x1 y1 shape->layerName shape->purpose)) + + (if !(name=="GND"||name=="Vdd") && (match == nil || matchedList(match name)) && + (notMatch == nil || !matchedList(notMatch name)) then + skip = nil + (if abs(y1-y0) > abs(x1-x0) then + dir = "VERT" + offset = (x0+x1)/2 + (if rangeY then + skip = !Ru_IsBetween(car(rangeY) y1 cadr(rangeY)) + ) + (if rangeX && !skip then + skip = !Ru_IsBetween(car(rangeX) x1 cadr(rangeX)) + ) +;printf("VERT:skip %L y1 %L %L x1 %L %L\n" skip y1 Ru_IsBetween(car(rangeY) y1 cadr(rangeY)) x1 Ru_IsBetween(car(rangeX) x1 cadr(rangeX))) + else + dir = "HOR" + offset = (y0+y1)/2 + (if rangeY then + skip = !Ru_IsBetween(car(rangeY) y1 cadr(rangeY)) + ) + (if rangeX && !skip then + skip = !Ru_IsBetween(car(rangeX) x1 cadr(rangeX)) + ) +;printf("HOR:skip %L y1 %L %L x1 %L %L\n" skip y1 Ru_IsBetween(car(rangeY) y1 cadr(rangeY)) x1 Ru_IsBetween(car(rangeX) x1 cadr(rangeX))) + ) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") + (if flipOffset offset = -offset) + (if !skip && (d==nil || d == dir) && + (l==nil || l == shape->layerName) && + (L==nil || L != shape->layerName) then + offset = offset - trackOff*TrackPitch + (if shape->net then + result = CheckLengthRouted(shape->net) + else + result = list(0 0) + ) +(if debug == 100 return(shape)) + entry = list(list(offset name "PIN" "PIN" shape->layerName dir (car(result)+cadr(result)) x0:y0)) + entries = append(entries entry) + (foreach ch channel + el = nth(1 ch) + aka = nth(2 ch) + rexMagic(nil) + (if aka then + (if exactMatch then + temp = (aka==Ru_RemoveLastEl(Ru_RemoveLastEl(name ".") "[]")) + else temp = rexMatchp(aka name)) + + (if temp then + (if debug >=2 printf("Appending AKA NODE %L: %L\n" aka name)) + channelTable[el] = append(channelTable[el] entry) + ) + else + (if exactMatch then + ;remove node element and array index + result = Ru_RemoveLastEl(Ru_RemoveLastEl(name ".") "[]") + temp = (el == result) + else temp = rexMatchp(el name)) + (if debug >= 2 printf("MATCH TEST el %L name %L result %L match %L\n" el name result temp)) + (if temp then + (if debug >= 2 printf("Appending NODE %L: %L\n" el name)) + result = parseString(name ".[]") + result2 = parseString(el ".[]") + ;should match all the sub fields + (for cnt 0 length(result)-1 + (if nth(cnt result) == nth(0 result2) then + (for idx 1 length(result2)-1 + (if nth(cnt+idx result) != nth(idx result2) temp = nil) + ) + ) + ) + (if debug >= 2 printf("MATCH POS el %L result %L result2 %L match %L\n" el result result2 temp)) + (if temp then + channelTable[el] = append(channelTable[el] entry) + ) + ) + ) + rexMagic(t) + ) + ) + ) + ) + + ) ; cond + ) ; foreach shapes +(if dumpPinPattern then + (if st error("Does not support sorting by track when dumping pin pattern for all pins\n")) + sn = t + st = nil +) +showEntries = !channel || debug >= 2 || length(entries) < 100 + (if showEntries then + ;must make a new copy, since channelTable is using the same one + ;don't know proper way to make copy, reverse will do for now + (if sl entries = sort(reverse(entries) 'Ru_SortChannelElByWireLength)) + (if st entries = sort(reverse(entries) 'Ru_SortCarChannelElByTrack)) + (if sn entries = sort(reverse(entries) 'Ru_SortCarChannelElByName)) + printf("\n############################### PINS FOUND ####################################\n") + busPattern = nth(2 car(entries)) + (if busPattern == "PIN" then + printf("%-40s %6s %L %L %L\n" "Name" "Tracks" "Layer" "DIR" "wireLen") + else + printf("%-40s %6s %-20s %L %L %L\n" "Name" "Tracks" "busPattern" "busArrayPitch" "busMetal" "DIR") + ) + minOff = 999999.0 + (foreach entry entries + offset = nth(0 entry) + busPrefix = nth(1 entry) + busPattern = nth(2 entry) + busArrayPitch = nth(3 entry) + busMetal = nth(4 entry) + dir = nth(5 entry) + wireLen = nth(6 entry) + (if busPattern == "PIN" then + (if !pinOffset || (pinOffset && substring(busPrefix strlen(busPrefix) strlen(busPrefix))=="e") then + printf("%-40s %6.2f %L %L %L\n" busPrefix offset/TrackPitch busMetal dir wireLen) + ) + else + printf("%-40s %6.2f %-20s %L %L %L\n" busPrefix offset/TrackPitch busPattern busArrayPitch busMetal dir) + ) + (if offset < minOff then + minOff = offset + baseNode = entry + ) + ) + ) + + ;dump out all pins found +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin(?m "^LS") +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin(?d "HOR" ?y list(700.0 1850.0) ?p t ?c "CtrlToMidAbuttPins") +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin(?d "VERT" ?y list(1850.0 2000.0) ?p t ?c "MidToOutputAbuttPins") + (if dumpPinPattern then + printf("############################### PIN PATTERN ###############################\n\n\n") + printf("NOTE: Also copy the cmdLine below for reproducibility\n") + printf(";Generated from %s:%s with cmdLine:\n" view->cellName view->viewName ) + printf("; %s\n" cmdLine) + (if cadr(baseNode) then + printf("; Base pin location: %L at %L or %L Tracks\n" + car(Ru_SplitNodeName(cadr(baseNode))) nth(7 baseNode) car(ToTrack(list(nth(7 baseNode))))) + ) + printf("c = nil\n") + entryCnt = length(entries) + cnt = 0 + (while cnt < entryCnt + entry = nth(cnt entries) + offset = nth(0 entry) + pinName = nth(1 entry) + nameLen = strlen(pinName) + busMetal = nth(4 entry) + dir = nth(5 entry) + wireLen = nth(6 entry) + nodeBaseName = substring(pinName 1 nameLen-2) + lastName = nodeBaseName + busPattern = nth(2 entry) + (if busPattern != "PIN" error("##### ERROR: Not support pins from busWires with busPattern %L\n" busPattern)) + + offsetBase = RoundDownTrack(offset) + nextCnt = cnt + busPattern = nil + wireLenMax = -9999.0 + ;looking for a pattern + nodeEl = substring(pinName nameLen nameLen) + (if nodeEl == "0" then + nodeTable = makeTable("nodeTable" 0) + (while lastName == nodeBaseName && nextCnt < entryCnt + nodeEl = substring(pinName nameLen nameLen) + (if wireLen > wireLenMax wireLenMax = wireLen) + nodeTable[nodeEl] = list(list(nodeBaseName nodeEl offset-offsetBase offset layer wireLen)) + ;printf("ADDING EL: %L entry %L\n" nodeEl nodeTable[nodeEl]) + lastName = nodeBaseName + nextCnt++ + pinName = nth(1 nth(nextCnt entries)) + (if pinName then + offset = nth(0 nth(nextCnt entries)) + nameLen = strlen(pinName) + nodeBaseName = substring(pinName 1 nameLen-2) + wireLen = nth(6 nth(nextCnt entries)) + ) + ) + ;the .e should be last entry + result = nil + (foreach el list("0" "1" "2" "3" "e") + (if nodeTable[el]&&nodeTable[el]!=0 result = append(result nodeTable[el])) + ) + busPattern = Ru_GetNodePattern(result) + ;printf("cnt %L %L busPattern %L nodeTable %L\n" cnt nextCnt busPattern result) + ) + + (if busPattern&&car(busPattern) != "UNKNOWN_PATTERN" then +;printf("WireOff %L offsetBase %L minOff %L trackOff %L layer %L\n" wireOff offsetBase minOff trackOff busMetal) + layoutPattern = car(busPattern) + trackBaseOff = (offsetBase-RoundDownTrack(minOff))/TrackPitch + (if almostEqual(cadr(busPattern) 0.0) then + temp = sprintf(nil "c = (cons (list \"%s\" %s %.0f*TrackPitch %s) c)" + lastName layoutPattern (trackBaseOff-trackOff) Ru_LayerToBusMetal(busMetal)); + else + wireOff = cadr(busPattern) + temp = sprintf(nil "c = (cons (list \"%s\" %s %.0f*TrackPitch%s%.3f %s) c)" + lastName car(busPattern) (trackBaseOff-trackOff) + (if wireOff < 0.0 "" "+") wireOff Ru_LayerToBusMetal(busMetal)); + ) + printf("%-80s" temp) + (if !integerp(wireLenMax) then printf(";%5.1f um\n" wireLenMax) + else printf("\n")) + cnt = nextCnt + else + ;individual node + offset = nth(0 entry) + wireOff = offset - RoundDownTrack(minOff) + trackBaseOff = RoundDownTrack(wireOff)/TrackPitch + wireOff = (wireOff-trackBaseOff*TrackPitch) - TrackPitch/2 +;printf("WireOff %L offset %L minOff %L trackOff %L layer %L\n" wireOff offset minOff trackOff busMetal) + temp = sprintf(nil " c = (cons (list \"%s\" node_2W %.0f*TrackPitch%s%.3f %s) c)" + nth(1 entry) + (trackBaseOff-trackOff) + (if wireOff < 0.0 "" "+") wireOff Ru_LayerToBusMetal(busMetal)) + printf("%-80s" temp) + printf(";%5.1f um\n" wireLen) + cnt++ + ) + ) + (if channelName then + printf("%s = (DefChan c)\n" channelName) + printf("busPatterns = (cons (list \"%s\" %s) busPatterns)\n" channelName channelName) + printf("\n\n") + ) + ) + (if channel then + (if debug >= 2 printf("\n############################# CHANNEL ######################################\n")) + minOff = 999999.0 + wireLenMax = -9999.0 + wireLenMin = 99999.9 + wireLenCnt = 0 + wireLenSum = 0.0 + (foreach ch channel + el = nth(1 ch) + (if channelTable[el] != nil then + (foreach entry channelTable[el] + (if car(entry) < minOff then + minOff = car(entry) + baseNode = entry + ) + wireLen = nth(6 entry) + (if wireLen < wireLenMin wireLenMin = wireLen) + (if wireLen > wireLenMax wireLenMax = wireLen) + wireLenSum = wireLenSum + wireLen + wireLenCnt++ + ) + ) + ) + (foreach ch channel + el = nth(1 ch) + (if debug >= 2 printf("############# %L ############\n" el)) + (if channelTable[el] == nil then + (if debug >= 2 printf("No entry found for %L\n" el)) + else + (foreach entry channelTable[el] + (if debug >= 2 printf("%s: %L\n" el entry)) + ) + ) + ) + ) + + (if channel then + printf("############################### CHANNEL PATTERN ###############################\n\n\n") + printf("NOTE: Also copy the cmdLine below for reproducibility\n") + printf(";Generated from %s:%s with cmdLine:\n" view->cellName view->viewName ) + printf("; %s\n" cmdLine) + (if !(integerp(wireLenMax) || wireLenCnt == 0) then + printf("; MaxWireLen: %.2f AvgWireLen: %.2f MinWireLen: %L\n" wireLenMax wireLenSum/wireLenCnt wireLenMin) + else + (if view->viewName=="layout" || view->viewName=="layout_pg" then + printf("WARN: No connectivity?\n") + ) + ) + (if cadr(baseNode) then + printf("; Base pin location: %L at %L or %L Tracks\n" + car(Ru_SplitNodeName(cadr(baseNode))) nth(7 baseNode) car(ToTrack(list(nth(7 baseNode))))) + ) + printf("c = nil\n") + (foreach ch channel + el = nth(1 ch) + (if channelTable[el] == nil then + printf("######################## ERROR: No entry found for %L ######################\n" el) + ) + ;from the pin pattern + (if channelTable[el] && nth(2 car(channelTable[el])) == "PIN" then + nodeTable = makeTable("nodeTable" 0) + channelTable[el] = sort(channelTable[el] 'Ru_SortCarChannelElByName) + (if debug >= 1 printf("############# %L ############\n" ch)) + lastName = "" + nodeList = nil + (foreach entry channelTable[el] + (if !cadr(entry) error("Nil second entry %L\n" entry)) + result = parseString(cadr(entry) ".") +idx = 1 +rexMagic(nil) +;too short of a name might falsely match +aka = nth(2 ch) +temp = (if aka aka el) +(if (strlen(temp) > 1) && rexMatchp(temp nth(0 result)) idx = 0) +(if temp == el idx = 0) +(if debug >= 2 printf("#### idx %d MATCH %L ch %L el %L result %L\n" idx temp ch el nth(0 result))) +rexMagic(t) + nodeBaseName = nth(idx result) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin( ?pf "fc/next_hop/pins.il" ?e t ?c "SramNextHopToMgmtChannel") +;Pin( ?pf "fc/l3_ar/mid/pins.il" ?m "TRAP_" ?c "MidToOutputThMgmtChannel") +;Pin( ?pf "fc/l3_ar/mid/pins.il" ?m "TCAM_ADDR" ?c "SeqCtrlToMidChannel" ?debug 2) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin( ?pf "fc/l3_ar/proteus_ctrl/pins.il" ?m "MGMT_WR" ?c "SeqCtrlToMidChannel_H" ?debug 1) +; load("/scratch/alta5/virtuoso/skill/layout/route/routepath.il") Pin(?pf "datapath/modify/stats/pins.il" ?c "HalToL2fHdChannel") + (for cnt idx+1 length(result)-2 + nodeBaseName = strcat(nodeBaseName sprintf(nil ".%s" nth(cnt result))) + ) + offset = nth(0 entry) + layer = nth(4 entry) + wireLen = nth(6 entry) + nodeEl = car(last(result)) + (cond + (nodeEl == "d[0]" nodeEl = "0") + (nodeEl == "d[1]" nodeEl = "1") + (nodeEl == "d[2]" nodeEl = "2") + (nodeEl == "d[3]" nodeEl = "3") + ) + (if lastName != nodeBaseName then + offsetBase = RoundDownTrack(offset) + nodeTable[nodeBaseName] = list(list(nodeBaseName nodeEl offset-offsetBase offset layer wireLen)) + nodeList = append(nodeList list(nodeBaseName)) + else + nodeTable[nodeBaseName] = append(nodeTable[nodeBaseName] list(list(nodeBaseName nodeEl offset-offsetBase offset layer wireLen))) + ) + lastName = nodeBaseName + + (if debug >= 2 printf("%s: node: [%s] %L\n" el nodeBaseName entry)) + + ) ;foreach + arrayOffset = nil + nodeArrayPattern = nil + cnt = 0 + nodeList = sort(nodeList 'Ru_SortChannelElByName) + (foreach entry nodeList + offset = (nth(3 car(nodeTable[entry])) - nth(3 car(nodeTable[car(nodeList)])))/TrackPitch*TrackPitch + (if cnt != 0 then + arrayOffset = append(arrayOffset list(offset)) + ) + temp = offset - floor((offset+TrackPitch/64)/TrackPitch)*TrackPitch + busPattern = Ru_GetNodePattern(nodeTable[entry]) + nodeArrayPattern = append(nodeArrayPattern list(busPattern)) + (if debug >= 1 printf("EL: %s: %L baseOff: %.2f %.2f %L\n" entry busPattern offset temp nodeTable[entry])) + cnt++ + ) + ;verify busPattern + (if !nth(0 ch) error("Nil first ch entry %L\n" ch)) + result = parseString(nth(0 ch) "[]") + (if nth(1 result) then + result2 = parseString(cadr(result) ".") + (if cadr(result2) then castStart = car(result2) castEnd = cadr(result2) + else + castStart = "0" + size = Ru_StringToInt(car(result2)) + castEnd = sprintf(nil "%d" size-1) + ) + else + ;not an array + castStart = nil + castEnd = nil + ) + castPattern = car(result) + (if !car(nodeList) error("Nil first nodeList entry %L\n" nodeList)) + ;find layout array index + result = parseString(car(nodeList) "[]") + (if length(result) > 1 then + layoutStart = car(last(result)) + layoutEnd = car(last(parseString(car(last(nodeList)) "[]"))) + else layoutStart = nil layoutEnd = nil + ) + layoutPattern = car(car(nodeArrayPattern)) ;just assume the first one + + (if !rexMatchp(castPattern layoutPattern) then + (if w printf("cast pattern: %L layoutPattern: %L\n" castPattern layoutPattern)) + (if w printf("###### ERROR: Cast pattern and layout pattern does not match for %L. Using individual element\n" el)) + ) + (if castStart!=layoutStart || castEnd!=layoutEnd then + (if w printf("castSize: %L..%L layoutSize: %L..%L\n" castStart castEnd layoutStart layoutEnd)) + (if w printf("###### WARN: Cast pattern and layout size does not match for %L\n" el)) + layoutStart = castStart ; using cast + layoutEnd = castEnd + ) + minOff = minOff/TrackPitch*TrackPitch + offset = nth(3 car(nodeTable[car(nodeList)])) + layer = nth(4 car(nodeTable[car(nodeList)])) + ;printf("NodeTable: %L\n" nodeTable[car(nodeList)]) + busMetal = Ru_LayerToBusMetal(layer) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin( ?pf "fc/l3_ar/mid/pins.il" ?m "TCAM_" ?c "SeqCtrlToMidChannel" ?debug 2) +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") Pin( ?pf "fc/l3_ar/mid/pins.il" ?c "SeqCtrlToMidChannelTest" ?debug 1) +; Pin( ?pf "fc/l3_ar/mid/pins.il" ?m "TCAM" ?c "SeqCtrlToMidChannel" ?debug 1) +; Pin( ?pf "fc/l3_ar/mid/pins.il" ?m "TCAM_ADDR" ?c "SeqCtrlToMidChannel" ?debug 2) + wireLenMax = -9999.9 + (foreach n nodeTable[car(nodeList)] + wireLen = nth(5 n) + (if wireLen > wireLenMax wireLenMax = wireLen) + ) + (if !layoutEnd then ;not an array + + (if layoutPattern == "UNKNOWN_PATTERN" then + warnAbstract = t + (if w printf("###### WARN: Please report if this pattern if known so it can be added. %L\n" nodeTable[car(nodeList)])) + cnt = 0 + (foreach n nodeTable[car(nodeList)] + wireOff = nth(2 n) - TrackPitch/2 + trackBaseOff = RoundDownTrack(offset-minOff)/TrackPitch + temp = sprintf(nil " c = (cons (list \".%s.%s\" node_2W %.0f*TrackPitch%s%.3f %s) c)" + el nth(1 n) (trackBaseOff-trackOff) + (if wireOff < 0.0 "" "+") wireOff busMetal); + printf("%-80s" temp) + (if cnt == 0 && !integerp(wireLenMax) then printf(";%5.1f um\n" wireLenMax) + else printf("\n")) + cnt++ + ) + else + cnt = 0 + trackBaseOff = RoundDownTrack(offset-minOff)/TrackPitch + (if almostEqual(cadr(nth(cnt nodeArrayPattern)) 0.0) then + temp = sprintf(nil "c = (cons (list \".%s\" %s %.0f*TrackPitch %s) c)" + el layoutPattern (trackBaseOff-trackOff) busMetal); + else + wireOff = cadr(nth(cnt nodeArrayPattern)) + temp = sprintf(nil "c = (cons (list \".%s\" %s %.0f*TrackPitch%s%.3f %s) c)" + el car(nth(cnt nodeArrayPattern)) (trackBaseOff-trackOff) + (if wireOff < 0.0 "" "+") wireOff busMetal); + ) + printf("%-80s" temp) + (if !integerp(wireLenMax) then printf(";%5.1f um\n" wireLenMax) + else printf("\n")) + ) + else + result = nil + (for cnt 1 length(arrayOffset)-1 + (if !result && !almostEqual(nth(0 arrayOffset)*(cnt+1) nth(cnt arrayOffset)) then + (if w printf("###### WARN: %s Can't use for loop: Inconsistent array pitch %L. expect: %f got: %f\n" el arrayOffset + nth(0 arrayOffset)*(cnt+1) nth(cnt arrayOffset) )) + result = t + ) + ) + (for cnt 1 length(nodeArrayPattern)-1 + (if !result && car(nth(0 nodeArrayPattern)) != car(nth(cnt nodeArrayPattern)) then + (if w printf("###### WARN: %s Can't use for loop: Inconsistent array node pattern %L. expect: %L got: %L\n" el nodeArrayPattern + nth(0 nodeArrayPattern) nth(cnt nodeArrayPattern) )) + result = t + ) + ) + (if result then ;inconsistent pitch or node pattern + arrayCnt = 0 + (foreach entry nodeList + offset = nth(3 car(nodeTable[entry])) + wireLenMax = -9999.9 + (foreach n nodeTable[entry] + wireLen = nth(5 n) + (if wireLen > wireLenMax wireLenMax = wireLen) + ) + busMetal = Ru_LayerToBusMetal(nth(4 car(nodeTable[entry]))) + result2 = parseString(entry "[]") + idx = nth(length(result2)-1 result2) + (if w && idx != sprintf(nil "%d" arrayCnt) + printf("###### WARN: Layout index %L is not the same as arrayCnt %d. %L\n" idx arrayCnt result2)) + (if car(nth(arrayCnt nodeArrayPattern)) == "UNKNOWN_PATTERN" then + warnAbstract = t + (if w printf("###### WARN: Please report if this pattern if known so it can be added. %L\n" nodeTable[entry])) + cnt = 0 + (foreach n nodeTable[entry] + wireOff = nth(2 n) - TrackPitch/2 + trackBaseOff = RoundDownTrack(offset-minOff)/TrackPitch +;printf("WireOff %L offset %L minOff %L trackOff %L track %L\n" wireOff offset minOff trackOff (RoundDownTrack(offset-minOff)/TrackPitch)) + temp = sprintf(nil " c = (cons (list \".%s[%s].%s\" node_2W %.1f*TrackPitch%s%.3f %s) c)" + el idx nth(1 n) + (trackBaseOff-trackOff) + (if wireOff < 0.0 "" "+") wireOff busMetal) + printf("%-80s" temp) + (if cnt == 0 && !integerp(wireLenMax) then printf(";%5.1f um\n" wireLenMax) + else printf("\n")) + cnt++ + ) + else + trackBaseOff = RoundDownTrack(offset-minOff+TrackPitch/2)/TrackPitch + (if almostEqual(cadr(nth(arrayCnt nodeArrayPattern)) 0.0) then + temp = sprintf(nil "c = (cons (list \".%s[%s]\" %s %.0f*TrackPitch %s) c)" + el idx car(nth(arrayCnt nodeArrayPattern)) (trackBaseOff-trackOff) busMetal); + else + wireOff = cadr(nth(arrayCnt nodeArrayPattern)) +;printf("ENTRY %L: wireOff %L offset %L minOff %L trackOff %L track %L %L nodeArrayPattern %L \n" entry wireOff offset minOff trackOff ((offset-minOff)/TrackPitch-trackOff) (RoundDownTrack(offset-minOff)/TrackPitch-trackOff) nodeArrayPattern) + temp = sprintf(nil "c = (cons (list \".%s[%s]\" %s %.0f*TrackPitch%s%.3f %s) c)" + el idx car(nth(arrayCnt nodeArrayPattern)) (trackBaseOff-trackOff) + (if wireOff < 0.0 "" "+") wireOff busMetal); + ) + printf("%-80s" temp) + (if !integerp(wireLenMax) then printf(";%5.1f um\n" wireLenMax) + else printf("\n")) + ) + arrayCnt++ + ) + else ;consistent pitch + (if !arrayOffset arrayOffset = list(1)) ;single entry array + printf("(for i %s %s\n" castStart castEnd) + iStr = "i" + (if castStart != "0" iStr = sprintf(nil "(i-%s)" castStart)) + (if layoutPattern == "UNKNOWN_PATTERN" then + warnAbstract = t + (if w printf("###### WARN: Please report if this pattern if known so it can be added. %L\n" nodeTable[car(nodeList)])) + cnt = 0 + (foreach n nodeTable[car(nodeList)] + wireOff = nth(2 n) - TrackPitch/2 + trackBaseOff = RoundDownTrack(offset-minOff)/TrackPitch + printf(" name = (sprintf nil \".%s%s.%s\" i)\n" el "[%d]" nth(1 n)) + temp = sprintf(nil " c = (cons (list name node_2W (%.0f*%s+%.0f)*TrackPitch%s%.3f %s) c)" + car(arrayOffset)/TrackPitch iStr (trackBaseOff-trackOff) + (if wireOff < 0.0 "" "+") wireOff busMetal) + printf("%-80s" temp) + (if cnt == 0 && !integerp(wireLenMax) then printf(";%5.1f um\n" wireLenMax) + else printf("\n")) + cnt++ + ) + else + wireOff = cadr(nth(0 nodeArrayPattern)) + (if almostEqual(wireOff 0.0) then + wireOffStr = "" + else + wireOffStr = sprintf(nil "%s%.3f" (if wireOff < 0.0 "" "+") wireOff) + ) + printf(" name = (sprintf nil \".%s%s\" i)\n" el "[%d]") + trackBaseOff = RoundDownTrack(offset-minOff)/TrackPitch + temp = sprintf(nil " c = (cons (list name %s (%.0f*%s+%.0f)*TrackPitch%s %s) c)" + layoutPattern car(arrayOffset)/TrackPitch iStr (trackBaseOff-trackOff) + wireOffStr busMetal) + printf("%-80s" temp) + (if !integerp(wireLenMax) then printf(";%5.1f um\n" wireLenMax) + else printf("\n")) + ) + printf(")\n") + ) + ) + else ;from the buswire pattern + (foreach entry channelTable[el] + (cond + (nth(4 entry)==BusPath23 busMetal = "BusMetal23") + (nth(4 entry)==BusPath45 busMetal = "BusMetal45") + (nth(4 entry)==BusPath56 busMetal = "BusMetal56") + (t busMetal = "BusMetal67") + ) + busPattern = nth(2 entry) + result = parseString(busPattern "[]") + ;verify busPattern + result2 = parseString(nth(0 ch) "[]") + (if cadr(result)!=cadr(result2) || !rexMatchp(car(result2) car(result)) then + printf("cast: %L\nlayout: %L\n" ch entry) + printf("cast pattern %L\n" nth(0 ch)) + printf("layout pattern %L\n" busPattern) + printf("###### ERROR: Cast pattern and layout pattern does not match for %L\n" el) + ) + (cond + (length(result) == 1 + printf("c = (cons (list \".%s\" %s %.0f*TrackPitch %s) c)\n" + el Ru_LayoutToPatternName(nth(2 entry)) ((nth(0 entry)-minOff)/TrackPitch-trackOff) busMetal) + ) + (length(result) == 2 + size = nth(1 result) + arrayOffset = nth(3 entry)/TrackPitch + temp = parseString(size ".") + (if length(temp) == 2 then + start = Ru_StringToInt(car(temp)) + end = Ru_StringToInt(cadr(temp)) + else + start = 0 + end = Ru_StringToInt(size) + ) + printf("(for i %d %d\n" start end) + printf(" name = (sprintf nil \".%s%s\" i)\n" el "[%d]") + printf(" c = (cons (list name %s (i*%.0f+%.0f)*TrackPitch %s) c)\n" + Ru_LayoutToPatternName(nth(0 result)) arrayOffset ((nth(0 entry)-minOff)/TrackPitch-trackOff-start) busMetal) + printf(")\n") + ) + (t printf("Unhandled busPattern of %L\n" busPattern)) + ) + ) + (if length(channelTable[el]) > 1 + printf("###### WARN: More than one entry found for %L\n" el) + ) + ) + ) + result = "" + printf("%s%s = (DefChan c)\n" channelName result) + printf("busPatterns = (cons (list \"%s%s\" %s%s) busPatterns)\n" channelName result channelName result) + printf("\n\n") + (if warnAbstract && view->viewName == "abstract" then + printf("##################### WARN WARN WARN ########################\n") + printf("Patterns with node element might be incorrect due to generated from abstract\n") + ) + ) + else + printf("\n\n") + printf("Dump out pin offset from busWire view or any view containing pin pattern\n") + printf("Auto generate a channel pattern given a channel definition\n") + printf("Verify a pattern with the busWire view or any view containing pin pattern\n") + printf("Usage: Pin([OPTION])\n") + printf(" ?help t - this help\n") + printf(" ?st t - Sort the output by trackOffset\n") + printf(" ?sn t - Sort the output by name\n") + printf(" ?m - Filter entries with a regular expression or a list of regexp before further processing\n") + printf(" ?M - Excluding entries with a regular expression or a list of regexp before further processing\n") + printf(" ?v - Specify the view name instead of the current view\n") + printf(" ?o - Normalize channel track offset with \n") + printf(" ?c - Specify channelName to build or verify\n") + printf(" ?pf - Specify pins.il name relative to layout/tsmc65/dfII/chip/alta base directory\n") + printf(" Used to build channel pattern list. Must specify channelName also\n") + printf(" ?p t - Generate pattern for all pins found.\n") + printf(" ?d - Only use pins in one direction, used for pins spanning multiple directions\n") + printf(" ?l - Only use pins with specified layer\n") + printf(" ?L - Only use pins not matching specified layer\n") + printf(" ?x - Only use pins with xCoord within this range") + printf(" ?y - Only use pins with yCoord within this range") + printf(" ?pinOffset t - Only print out the .e offset for manually creating pin pattern\n") + printf(" ?g t - Generate a pattern in order of the elements\n") + printf(" ?w nil - Use to suppress warning messages once deemed okay to copy bus pattern cleanly\n") + printf(" ?f t - Flip offset before generating pin pattern due to pin flipped\n") + ;printf(" ?p - Verify the channel pattern with pins in a view(Not implemented yet)\n") + printf(" ?map - Specify a list of (list(list ))\n") + printf(" to associate the cast entry name to layout name, where it differs\n") + printf("NOTE:\n") + printf("In some instances the cast channel entry name does not match with the layout name,\n") + printf("one can add a \"LAYOUT=\" in pins.il to associate the cast entry name to the\n") + printf("layout name as below. This is prefered since it will be reproducible. Or use map option\n") + printf(" ; e1of4v(3) +ALU13_CMD_PROFILE; LAYOUT=L3AR_ALU13_OP_PROFILE_TABLE_CMD\n") + printf("Example: Pin(?pf \"fc/hal/pins.il\" ?cv halBusView ?m \"IN_HD\" ?c \"L2LookupToHalHdChannel\")\n") + printf(" Obtain all the busPrefix containing \"IN_HD\" in busWires view specified by halBusView.\n") + printf(" Using the result to generate channel pattern for L2LookupToHalHdChannel with definition in pins.il\n") + printf("\n") + printf("DefChan Example:\n") + printf(";defchan ExampleChannel\n") + printf("; e1of4[4] +Array;\n") + printf("; e1of4[32..63] +Array1;\n") + printf("; e1of4[4][2] +2DArray;\n") + + ) ; help + return(t) + ) + +) + + +(defun ru_WithinGrid (value grid limit) + (let (delta) + delta = abs((value - round(value/grid)*grid)) + ((delta < limit) || delta > (grid-limit)) + ) +) + +(defun ru_AdjustSegLength (seg len) + (let (dist x1 y1 x2 y2) + x1 = xCoord(nth(0 seg)) + x2 = xCoord(nth(1 seg)) + y1 = yCoord(nth(0 seg)) + y2 = yCoord(nth(1 seg)) + dist = abs(x1-x2)+abs(y1-y2) + (if dist < len/2 len = dist/2) + (if almostEqual(x1 x2) then ;vert + (if y1 > y2 then y2 = y2 + len + else y2 = y2 - len) + else + (if x1 > x2 then x2 = x2 + len + else x2 = x2 - len) + ) + list(x1:y1 x2:y2) + ) +) + +(defun ru_IsNameMatched (matchEntry wireName @key (exactMatch nil)) + (prog (entry result result2 idx minEntry maxEntry temp len cnt el matchEntryIntIndx) + rexMagic(nil) ;we want to match [] in normal sense +;printf("######## IsNameMatched: %L %L rexMatchp %L\n" matchEntry wireName rexMatchp(matchEntry wireName) ) + (if (matchEntry == wireName || rexMatchp(matchEntry wireName) ) then + rexMagic(t) + return(t) + ) + result = parseString(matchEntry "\\[]") +;printf(" IsNameMatched matchEntry %L wireName %L result %L\n" matchEntry wireName result) + (if rexMatchp(car(result) wireName) then + len = length(result) + (if exactMatch then + result2 = parseString(wireName "\\[]") + (for cnt 0 len-2 + (if nth(cnt result)!=nth(cnt result2) then + ;printf(" NOT EXACT MATCH at index %d %L %L\n" cnt nth(cnt result) nth(cnt result2)) + rexMagic(t) + return(nil) + ) + ) + ) + minEntry = nil + + matchEntryIntIndx = nil + (if rexMatchp(".." nth(len-1 result)) matchEntryIntIndx = len-1) ;in the form of RD[0..15] + rexMagic(t) +;Ru_StringIsInt requires rexMagic(t) +(if !matchEntryIntIndx then +(cond + ( Ru_StringIsInt(nth(len-1 result)) matchEntryIntIndx = len-1) + ( Ru_StringIsInt(nth(len-2 result)) + ;must match the last entry + (if nth(len-1 result)!=nth(length(result2)-1 result2) return(nil)) + matchEntryIntIndx = len-2 + ) + (t matchEntryIntIndx = len) +) +) + +;printf(" wireName: %L result %L result2 %L matchEntryIntIndx %L len %L\n" wireName result result2 matchEntryIntIndx len) + ;must match the last index + (if matchEntryIntIndx < len then + result = parseString(nth(matchEntryIntIndx result) ".") + (if cadr(result) then + minEntry = Ru_StringToInt(car(result)) + maxEntry = Ru_StringToInt(cadr(result)) + else + minEntry = Ru_StringToInt(car(result)) + maxEntry = minEntry + ) + result = parseString(wireName "[]") + temp = nil + (foreach el result + (if !temp && Ru_StringIsInt(el) temp = el) + ) + (if temp idx = Ru_StringToInt(temp)) + ) +;printf(" wireName: %L matchEntry %L idx %L min %L max %L %L temp %L \n" wireName matchEntry idx minEntry maxEntry result temp ) + (if !minEntry || (idx && idx >= minEntry && idx <= maxEntry) then +;printf(" FOUND wireName: %L idx %L min %L max %L matchEntry %L %L\n" wireName idx minEntry maxEntry matchEntry result) + return(t) + ) + ) + return(nil) + ) +) + +(defun ru_GetFilterList (filterList wireName) + (prog (entry) + (foreach entry filterList + (if ru_IsNameMatched(nth(0 entry) wireName ?exactMatch t) return(entry)) + ) + return(nil) + ) +) + +(defun ru_GetSegException (segException wireName) + (prog (segExcep) + (foreach segExcep segException + (if ru_IsNameMatched(nth(0 segExcep) wireName ?exactMatch t) return(segExcep)) + ) + return(nil) + ) +) + +(defun Ru_GetLastField (name) + (let (array entry) + array = parseString(name ".") + (if length(array) == 3 && rexMatchp("^DFT" car(array)) && (cadr(array)=="D"||cadr(array)=="C") then ;FIXME DFT + entry = sprintf(nil "%s.%s" cadr(array) nth(2 array)) + else + entry = nth((length(array)-1) array) + ) + ;printf("Ru_GetLastField: Array %L entry %s\n" array entry) + entry + ) +) +(defun Ru_GetFirstField (name) + (let (array entry) + array = parseString(name ".") + entry = nth(0 array) + ;printf("Ru_GetFirstField: Array %L entry %s\n" array entry) + entry + ) +) + +(defun Ru_gete1of1PinLLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(0.06:0.48 4.14:0.60)) + (field == "0" loc = list(0.06:1.26 4.14:1.38)) + (t printf("ERROR: Ru_gete1of1PinLLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_gete1of1PinRLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(0.06:3.36 4.14:3.48)) + (field == "0" loc = list(0.06:4.14 4.14:4.26)) + (t printf("ERROR: Ru_gete1of1PinRLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) + +(defun Ru_gete1of2aPinLLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(0.06:4.14 3.12:4.26)) + (field == "0" loc = list(0.06:3.66 3.12:3.78)) + (field == "1" loc = list(0.06:4.62 3.12:4.74)) + (t printf("ERROR: Ru_gete1of2aPinLLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_gete1of2aPinRLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(0.06:7.02 3.12:7.14)) + (field == "0" loc = list(0.06:6.54 3.12:6.66)) + (field == "1" loc = list(0.06:7.50 3.12:7.62)) + (t printf("ERROR: Ru_gete1of2aPinRLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) + +(defun Ru_gete1of4PinLLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(0.12:3.36 2.7:3.48)) + (field == "0" loc = list(0.12:4.14 2.7:4.26)) + (field == "1" loc = list(0.12:4.50 2.7:4.62)) + (field == "2" loc = list(0.12:4.86 2.7:4.98)) + (field == "3" loc = list(0.12:5.22 2.7:5.34)) + (t printf("ERROR: Ru_gete1of4PinLLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_gete1of4PinRLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(3.06:3.36 5.64:3.48)) + (field == "0" loc = list(3.06:4.14 5.64:4.26)) + (field == "1" loc = list(3.06:4.50 5.64:4.62)) + (field == "2" loc = list(3.06:4.86 5.64:4.98)) + (field == "3" loc = list(3.06:5.22 5.64:5.34)) + (t error("ERROR: Ru_gete1of4PinRLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_gete1of3aPinLLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(0.06:4.14 2.82:4.26)) + (field == "0" loc = list(0.06:3.18 2.82:3.30)) + (field == "1" loc = list(0.06:3.66 2.82:3.78)) + (field == "2" loc = list(0.06:4.62 2.82:4.74)) + (t error("ERROR: Ru_gete1of3aPinLLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_gete1of3aPinRLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(2.94:7.02 5.70:7.14)) + (field == "0" loc = list(2.94:6.06 5.70:6.18)) + (field == "1" loc = list(2.94:6.54 5.70:6.66)) + (field == "2" loc = list(2.94:7.50 5.70:7.62)) + (t error("ERROR: Ru_gete1of3aPinRLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_gete1of4aPinLLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(0.06:4.14 2.82:4.26)) + (field == "0" loc = list(0.06:3.18 2.82:3.30)) + (field == "1" loc = list(0.06:3.66 2.82:3.78)) + (field == "2" loc = list(0.06:4.62 2.82:4.74)) + (field == "3" loc = list(0.06:5.10 2.82:5.22)) + (t error("ERROR: Ru_gete1of4aPinLLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_gete1of4aPinRLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "e" loc = list(2.94:7.02 5.70:7.14)) + (field == "0" loc = list(2.94:6.06 5.70:6.18)) + (field == "1" loc = list(2.94:6.54 5.70:6.66)) + (field == "2" loc = list(2.94:7.50 5.70:7.62)) + (field == "3" loc = list(2.94:7.98 5.70:8.10)) + (t error("ERROR: Ru_gete1of4aPinRLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_getDftPinLLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "D.e" loc = list(0.06:3.36 3.12:3.48)) + (field == "D.0" loc = list(0.06:4.14 3.12:4.26)) + (field == "D.1" loc = list(0.06:4.5 3.12:4.62)) + (field == "C.0" loc = list(0.06+3.18:0.12*4 1.68+3.18:0.12*5)) ;not real pin location + (field == "C.1" loc = list(0.06+3.18:2*TrackPitch+0.12*16.5 1.68+3.18:2*TrackPitch+0.12*17.5)) ;not real pin location + (field == "C.2" loc = list(0.06+4.92:2*TrackPitch+0.12*19.5 1.68+4.92:2*TrackPitch+0.12*20.5)) ;not real pin location + (t printf("ERROR: Ru_getDftPinLLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) +(defun Ru_getDftPinRLoc (pinName) + (let (loc field) + field = Ru_GetLastField(pinName) + (cond + (field == "D.e" loc = list(0.06:6.24 3.12:6.36)) + (field == "D.0" loc = list(0.06:7.02 3.12:7.14)) + (field == "D.1" loc = list(0.06:7.38 3.12:7.5)) + (field == "C.0" loc = list(0.06+3.18:TrackPitch+0.12*18 1.68+3.18:TrackPitch+0.12*19)) ;not real pin location + (field == "C.1" loc = list(0.06+3.18:3*TrackPitch+0.12*8 1.68+3.18:3*TrackPitch+0.12*9)) ;not real pin location + (field == "C.2" loc = list(0.06+4.92:3*TrackPitch+0.12*12 1.68+4.92:3*TrackPitch+0.12*13)) ;not real pin location + (t printf("ERROR: Ru_getDftPinRLoc: Unknown pin name [%s] field [%s]\n" pinName field)) + ) + loc + ) +) + +procedure( offsetBox( box ) + (if debug >= 4 printf( "offsetBox %L %L\n" box offset) ) + let( ( llx lly urx ury ) + urx = xCoord( upperRight( box )) + ury = yCoord( upperRight( box )) + llx = xCoord( lowerLeft( box )) + lly = yCoord( lowerLeft( box )) + offx = xCoord(offset) + offy = yCoord(offset) + list((llx+offx):(lly+offy) (urx+offx):(ury+offy)) + ) ; let +) + +(defun Ru_getPinLLoc (cellTypeName name orient) + (let (loc flipX flipY) + (cond + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of1.1000" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of1.1000" loc = Ru_gete1of1PinLLoc(name)) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of2.1000a" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of2.1000a" loc = Ru_gete1of2aPinLLoc(name)) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of3.1000a" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of3.1000a" loc = Ru_gete1of3aPinLLoc(name)) +; (cellTypeName == "lib.buffer.half.FAST_MBUF_1of4.1000" || +; cellTypeName == "lib.buffer.half.DENSE_MBUF_1of4.1000" loc = Ru_gete1of4PinLLoc(name)) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of4.1000a" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of4.1000a" loc = Ru_gete1of4aPinLLoc(name)) + (cellTypeName == "lib.serial.scan.MBUF_ChanDft.1003" loc = Ru_getDftPinLLoc(name)) + (t error("ERROR: Ru_getPinLLoc: Unsupported cell type [%s]\n" cellTypeName)) + ) + flipX = (orient == "MX" || orient == "R180") + flipY = (orient == "MY" || orient == "R180") + (if flipY loc = list(-xCoord(lowerLeft(loc)):yCoord(lowerLeft(loc)) -xCoord(upperRight(loc)):yCoord(upperRight(loc)))) + (if flipX loc = list(xCoord(lowerLeft(loc)):-yCoord(lowerLeft(loc)) xCoord(upperRight(loc)):-yCoord(upperRight(loc)))) + loc + ) +) +(defun Ru_getPinRLoc (cellTypeName name orient) + (let (loc flipX flipY) + (cond + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of1.1000" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of1.1000" loc = Ru_gete1of1PinRLoc(name)) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of2.1000a" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of2.1000a" loc = Ru_gete1of2aPinRLoc(name)) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of3.1000a" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of3.1000a" loc = Ru_gete1of3aPinRLoc(name)) +; (cellTypeName == "lib.buffer.half.FAST_MBUF_1of4.1000" || +; cellTypeName == "lib.buffer.half.DENSE_MBUF_1of4.1000" loc = Ru_gete1of4PinRLoc(name)) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of4.1000a" || + cellTypeName == "lib.buffer.half.DENSE_MBUF_1of4.1000a" loc = Ru_gete1of4aPinRLoc(name)) + (cellTypeName == "lib.serial.scan.MBUF_ChanDft.1003" loc = Ru_getDftPinRLoc(name)) + (t error("ERROR: Ru_getPinRLoc: Unsupported cell type [%s]\n" cellTypeName)) + ) + flipX = (orient == "MX" || orient == "R180") + flipY = (orient == "MY" || orient == "R180") + (if flipY loc = list(-xCoord(lowerLeft(loc)):yCoord(lowerLeft(loc)) -xCoord(upperRight(loc)):yCoord(upperRight(loc)))) + (if flipX loc = list(xCoord(lowerLeft(loc)):-yCoord(lowerLeft(loc)) xCoord(upperRight(loc)):-yCoord(upperRight(loc)))) + loc + ) +) + +(defun ru_getCellType (name) + (let (cellType) + (cond + (name == "lib.buffer.half.FAST_MBUF_1of1.1000" cellType = "FAST_MBUF_1of1") + (name == "lib.buffer.half.DENSE_MBUF_1of1.1000" cellType = "DENSE_MBUF_1of1") + (name == "lib.buffer.half.FAST_MBUF_1of2.1000a" cellType = "FAST_MBUF_1of2") + (name == "lib.buffer.half.DENSE_MBUF_1of2.1000a" cellType = "DENSE_MBUF_1of2") + (name == "lib.buffer.half.FAST_MBUF_1of2.1000" cellType = "FAST_MBUF_1of2") + (name == "lib.buffer.half.DENSE_MBUF_1of2.1000" cellType = "DENSE_MBUF_1of2") + (name == "lib.buffer.half.FAST_MBUF_1of3.1000a" cellType = "FAST_MBUF_1of3") + (name == "lib.buffer.half.DENSE_MBUF_1of3.1000a" cellType = "DENSE_MBUF_1of3") + (name == "lib.buffer.half.FAST_MBUF_1of4.1000" cellType = "FAST_MBUF_1of4") + (name == "lib.buffer.half.DENSE_MBUF_1of4.1000" cellType = "DENSE_MBUF_1of4") + (name == "lib.buffer.half.FAST_MBUF_1of4.1000a" cellType = "FAST_MBUF_1of4") + (name == "lib.buffer.half.DENSE_MBUF_1of4.1000a" cellType = "DENSE_MBUF_1of4") + (name == "lib.buffer.half.FAST_MBUF_4.1000" cellType = "FAST_MBUF_4") + (name == "lib.buffer.half.FAST_MBUF_2_1of2.1000" cellType = "FAST_MBUF_2_1of2") + (t error("ERROR: ru_getCellType: Unsupported cell type [%L]\n" name)) + ) + cellType + ) +) + +(defun Ru_TrackOffset (value) + (let (diff wirePitch grid) + grid = TrackPitch + diff = value - round(value/grid)*grid + ;printf("value %f grid %f round %d diff %f\n" value grid round(value/grid) diff) + (if diff < 0.0 diff = diff + TrackPitch) + diff + ) +) + +(defun ru_AlignTo (value grid) + (let (diff wirePitch) + wirePitch = TrackPitch/24 + diff = value - round(value/grid)*grid + ;printf("value %f grid %f round %d diff %f\n" value grid round(value/grid) diff) + (abs(diff) < wirePitch/128) + ) +) + +(defun VerifyInstAlignment (@key (xgrid 2*TrackPitch) (ygrid 2*TrackPitch) + (match "chip.alta") (exclude nil) (view nil) (debug nil) + (recurseList list("chip.alta.CORE-L76-R.1000" + "chip.alta.datapath.DATAPATH-L76-R.1000" + "chip.alta.fc.FRAME_CONTROL-L76-R.1000" + "chip.alta.fc.early.EARLY-L76-R.1000" + "chip.alta.fc.early.A-L76-R.1000" + "chip.alta.fc.early.B-L76-R.1000" + "chip.alta.fc.late.LATE-L76-R.1000" + "chip.alta.fc.late.A-L76-R.1000" + "chip.alta.fc.late.B-L76-R.1000" + "chip.alta.fc.late.C-L76-R.1000" + "chip.alta.fc.late.D-L76-R.1000" + ) + ) + ) + (let (inst rView) + (if !view view = (geGetEditCellView)) + (foreach inst view->instances + (if debug printf("INST: %L-%L %L\n" inst->cellName inst->viewName inst->xy)) + (if (!match || (rexMatchp match inst->cellName)) && + !(exclude && (rexMatchp exclude inst->cellName)) then + (if !ru_AlignTo(xCoord(inst->xy) xgrid) then + printf("%L:%L xCoord %.1f is not aligned to %.1f-track\n" + inst->name inst->cellName xCoord(inst->xy)/TrackPitch xgrid/TrackPitch) + ) + (if !ru_AlignTo(yCoord(inst->xy) ygrid) then + printf("%L:%L yCoord %.1f is not aligned to %.1f-track\n" + inst->name inst->cellName yCoord(inst->xy)/TrackPitch ygrid/TrackPitch) + ) + ) + (if member(inst->cellName recurseList) then + printf("########### RecurseDown: %L-%L ############\n" inst->cellName inst->viewName) + rView = dbOpenCellViewByType(inst->libName inst->cellName inst->viewName) + VerifyInstAlignment(?view rView ?xgrid xgrid ?ygrid ygrid + ?match match ?exclude exclude ?recurseList recurseList) + + ) + ) + ) +t +) + +(defun VerifyViasAlignment (@key (xgrid 1*TrackPitch) (ygrid 1*TrackPitch) + (match nil) (exclude "chip.alta") (view nil) (debug nil) + ) + (let (inst rView) + (if !view view = (geGetEditCellView)) + (foreach inst view->instances + (if debug printf("INST: %L-%L %L\n" inst->cellName inst->viewName inst->xy)) + (if (!match || (rexMatchp match inst->cellName)) && + !(exclude && (rexMatchp exclude inst->cellName)) then + (if xgrid && ru_AlignTo(xCoord(inst->xy) xgrid) then + printf("%L:%L-%L xCoord %.1f is aligned to %.1f-track\n" + inst->name inst->cellName inst->xy xCoord(inst->xy)/TrackPitch xgrid/TrackPitch) + ) + (if ygrid && ru_AlignTo(yCoord(inst->xy) ygrid) then + printf("%L:%L-%L yCoord %.1f is aligned to %.1f-track.\n" + inst->name inst->cellName inst->xy yCoord(inst->xy)/TrackPitch ygrid/TrackPitch) + ) + ) + ) + ) +t +) + +;compare location of two different viewName +(defun VerifyInstLoc (cViewName @key (debug nil) + (match "chip.alta") (exclude nil) (view nil) + (recurseList list("chip.alta.CORE-L76-R.1000" + "chip.alta.datapath.DATAPATH-L76-R.1000" + "chip.alta.fc.FRAME_CONTROL-L76-R.1000" + "chip.alta.fc.early.EARLY-L76-R.1000" + "chip.alta.fc.late.LATE-L76-R.1000" + ) + ) + ) + (let (inst rView cView cInst cnt cellName) + (if !view view = (geGetEditCellView)) + (cond + (view == "chip.alta.fc.early.EARLY-L76-R.1000" + cellList = list(view + "chip.alta.fc.early.A-L76-R.1000" + "chip.alta.fc.early.B-L76-R.1000" + ) + ) + (view == "chip.alta.fc.late.LATE-L76-R.1000" + cellList = list(view + "chip.alta.fc.late.A-L76-R.1000" + "chip.alta.fc.late.B-L76-R.1000" + "chip.alta.fc.late.C-L76-R.1000" + "chip.alta.fc.late.D-L76-R.1000" + ) + ) + (t cellList = list(view)) + ) + (foreach cellName cellList + printf("############# Verify cell locations of %L between %L and %L ############\n" + cellName view->viewName cViewName) + cView = dbOpenCellViewByType(view->libName cellName cViewName) + (if !cView then + printf("Unable to open %L:%L\n" inst->cellName cViewName) + else + (foreach inst view->instances + (if debug printf("INST: %L-%L %L\n" inst->cellName inst->viewName inst->xy)) + (if (!match || (rexMatchp match inst->cellName)) && + !(exclude && (rexMatchp exclude inst->cellName)) then + cnt = 0 + (foreach cInst cView->instances + (if (!match || (rexMatchp match cInst->cellName)) && + !(exclude && (rexMatchp exclude cInst->cellName)) then + (if inst->cellName == cInst->cellName then + cnt++ + (if debug printf("CINST: %L-%L %L\n" cInst->cellName cInst->viewName cInst->xy)) + (if inst->xy != cInst->xy then + printf("%L:%L-%L loc %L is not the same as %L:%L-%L loc %L\n" + inst->name inst->cellName inst->viewName inst->xy + cInst->name cInst->cellName cInst->viewName cInst->xy) + ) + ) + ) + ) + (if cnt == 0 then + printf("%L:%L-%L loc %L is not found in %L\n" + inst->name inst->cellName inst->viewName inst->xy + cViewName) + ) + ) + (if member(inst->cellName recurseList) then + printf("########### RecurseDown: %L-%L ############\n" inst->cellName inst->viewName) + rView = dbOpenCellViewByType(inst->libName inst->cellName inst->viewName) + VerifyInstLoc(cViewName ?view rView + ?match match ?exclude exclude ?recurseList recurseList) + + ) + ) + ) + );foreach cellList + ) +t +) + +(defun DumpInst (@key (filterCell nil) (filterView nil)) + (let (inst view cnt add) + view = (geGetEditCellView) + cnt = 0 + (foreach inst view->instances + add = nil + (if (!filterView && !filterCell) || (filterView && rexMatchp(filterView inst->viewName)) then + add = t + ) + (if (!filterView && !filterCell) || (filterCell && rexMatchp(filterCell inst->cellName)) then + add = t + ) + (if add then + printf("%-60s %L %L\n" inst->cellName inst->viewName inst->xy) + cnt++ + ) + ) + cnt + ) +) + +(defun ru_getTurnOffset (bufLoc cellTypeName pinName dirIn flipY bufInst) + (let (offset off field wirePitch) + wirePitch = TrackPitch/24 + (cond + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of1.1000" || cellTypeName == "lib.buffer.half.DENSE_MBUF_1of1.1000" + field = Ru_GetLastField(pinName) + (cond + (ru_AlignTo(xCoord(bufLoc) TrackPitch) + (cond + (field == "e" + (if dirIn then offset = wirePitch*5 + else offset = wirePitch*14) + ) + (field == "0" + (if dirIn then offset = wirePitch*10 + else offset = wirePitch*19) + ) + ) + ) + ((!flipY && ru_AlignTo((xCoord(bufLoc)-7*wirePitch) TrackPitch)) + (flipY && ru_AlignTo((xCoord(bufLoc)+7*wirePitch) TrackPitch)) + (cond + (field == "e" + (if dirIn then offset = wirePitch*2 + else offset = wirePitch*21) + ) + (field == "0" + (if dirIn then offset = wirePitch*5 + else offset = wirePitch*24) + ) + ) + (if ru_AlignTo(yCoord(bufLoc) 4*TrackPitch) offset = offset + 8*wirePitch) + + ) + (t error("ERROR: ru_getTurnOffset: %s: Unsupported cell [%s] alignment. Must align to TrackPitch or offset by %f(7*wirePitch). Got %f wirePitch. flipX %L flipY %L bufLoc %L\n" + bufInst->name cellTypeName 7*wirePitch (xCoord(bufLoc)-RoundDownTrack(xCoord(bufLoc)))/wirePitch flipX flipY xCoord(bufLoc))) + ) + (if flipY offset = -offset) + ) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of2.1000a" || cellTypeName == "lib.buffer.half.DENSE_MBUF_1of2.1000a" + field = Ru_GetLastField(pinName) + (cond + (ru_AlignTo(xCoord(bufLoc) 2.88) + ; buffer location is aligned to grid + (cond + (field == "e" + (if dirIn then offset = wirePitch*3 + else offset = wirePitch*18) + ) + (field == "0" + (if dirIn then offset = wirePitch*6 + else offset = wirePitch*14) + ) + (field == "1" + (if dirIn then offset = wirePitch*10 + else offset = wirePitch*21) + ) + ) + ) + ((!flipY && ru_AlignTo((xCoord(bufLoc)-4*wirePitch) 2.88)) || + (flipY && ru_AlignTo((xCoord(bufLoc)+4*wirePitch) 2.88)) + ; buffer location is aligned to grid + (cond + (field == "e" + (if dirIn then offset = wirePitch*1 + else offset = wirePitch*15) + ) + (field == "0" + (if dirIn then offset = wirePitch*5 + else offset = wirePitch*11) + ) + (field == "1" + (if dirIn then offset = wirePitch*8 + else offset = wirePitch*25) + ) + ) + ) + ((!flipY && ru_AlignTo((xCoord(bufLoc)-20*wirePitch) 2.88)) || + (flipY && ru_AlignTo((xCoord(bufLoc)+20*wirePitch) 2.88)) + ; buffer location is aligned to grid + (cond + (field == "e" + (if dirIn then offset = wirePitch*1 + else offset = wirePitch*21) + ) + (field == "0" + (if dirIn then offset = wirePitch*9 + else offset = wirePitch*17) + ) + (field == "1" + (if dirIn then offset = wirePitch*13 + else offset = wirePitch*25) + ) + ) + ) + (t error("ERROR: ru_getTurnOffset: Unsupported cell [%s] alignment. Must align to 2.88 or offset by %f. Got %f wirePitch. flipX %L flipY %L\n" + cellTypeName 4*wirePitch (RoundDownTrack(xCoord(bufLoc))-xCoord(bufLoc))/wirePitch flipX flipY )) + ) + (if flipY offset = -offset) + ) + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of3.1000a" || cellTypeName == "lib.buffer.half.DENSE_MBUF_1of3.1000a" + field = Ru_GetLastField(pinName) + (cond + (ru_AlignTo(xCoord(bufLoc) 2.88) + ; buffer location is aligned to grid + (cond + (field == "e" + offset = (if flipY -wirePitch*18 wirePitch*6) + ) + (field == "0" + offset = (if flipY -wirePitch*14 wirePitch*10) + ) + (field == "1" + offset = (if flipY -wirePitch*10 wirePitch*14) + ) + (field == "2" + offset = (if flipY -wirePitch*6 wirePitch*18) + ) + ) + ) + (t error("ERROR: ru_getTurnOffset: Unsupported cell [%s] alignment. Must align to 2.88\n" cellTypeName )) + ) + (if !dirIn offset = offset + (if flipY -TrackPitch TrackPitch)) + ) + + (cellTypeName == "lib.buffer.half.FAST_MBUF_1of4.1000a" || cellTypeName == "lib.buffer.half.DENSE_MBUF_1of4.1000a" ;cellTypeName == "lib.buffer.half.FAST_MBUF_1of4.1000" + field = Ru_GetLastField(pinName) + (cond + (ru_AlignTo(xCoord(bufLoc) 2.88) + ; buffer location is aligned to grid + (cond + (field == "e" + offset = (if flipY -wirePitch*19 wirePitch*3) + ) + (field == "0" + offset = (if flipY -wirePitch*15 wirePitch*7) + ) + (field == "1" + offset = (if flipY -wirePitch*11 wirePitch*11) + ) + (field == "2" + offset = (if flipY -wirePitch*7 wirePitch*15) + ) + (field == "3" + offset = (if flipY -wirePitch*3 wirePitch*19) + ) + ) + ) + (t error("ERROR: ru_getTurnOffset: Unsupported cell [%s] alignment. Must align to 2.88\n" cellTypeName )) + ) + (if !dirIn offset = offset + (if flipY -TrackPitch TrackPitch)) + ) + (cellTypeName == "lib.serial.scan.MBUF_ChanDft.1003" + field = Ru_GetLastField(pinName) + (cond + (ru_AlignTo(xCoord(bufLoc) 2.88) + ; buffer location is aligned to grid + (cond + (field == "D.e" + (if dirIn then offset = (if flipY -wirePitch*3 wirePitch*3) + else offset = (if flipY -wirePitch*21 wirePitch*21)) ;swap with 1 to prevent vias violation + ) + (field == "D.0" + (if dirIn then offset = (if flipY -wirePitch*6 wirePitch*6) + else offset = (if flipY -wirePitch*14 wirePitch*14)) + ) + (field == "D.1" + (if dirIn then offset = (if flipY -wirePitch*10 wirePitch*10) + else offset = (if flipY -wirePitch*18 wirePitch*18)) + ) + (field == "C.0" + (if dirIn then offset = (if flipY -wirePitch*28 wirePitch*28) + else offset = (if flipY -wirePitch*35 wirePitch*35)) + ) + (field == "C.1" + (if dirIn then offset = (if flipY -wirePitch*32 wirePitch*32) + else offset = (if flipY -wirePitch*39 wirePitch*39)) + ) + (field == "C.2" + (if dirIn then offset = (if flipY -wirePitch*44 wirePitch*44) + else offset = (if flipY -wirePitch*52 wirePitch*52)) + ) + ) + ) + (t error("ERROR: ru_getTurnOffset: Unsupported cell [%s] alignment. Must align to 2.88 or offset by %f\n" cellTypeName 4*wirePitch)) + ) + ) + (t error("ERROR: ru_getTurnOffset: Unsupported cell type [%s]\n" cellTypeName)) + ) + (if !offset error("ERROR: ru_getTurnOffset: Unknown pin name [%s] field [%s]\n" pinName field)) + offset + ) +) + + +;##################################################################################### +(defun TerminateChannel (path busPatternsList busPrefix @key + (filterList nil) (filterExcludeList nil) (forceViasDir nil) (forceLayerIdx -1) (doubleVias t) + (debugStackVias nil) (flipX nil) (flipY nil) (busPosfix "") (debug 0)) + (let (numErr wirePitch forceLayer offsetTurn drawPath wireName nodeName result) + (if debug >= 1 printf("TerminateChannel %s path %L\n" busPrefix path)) + pointTypes = (Ru_ClassifyPoints path) + (if length(busPatternsList) != (length(path)-1) + error("busPatternsList (%d) must be the same as number of segments(%d)\n" + length(busPatternsList) (length(path)-1)) + ) + wirePitch = TrackPitch/24 + numSeg = length(busPatternsList) + declare(segLp[numSeg]) + declare(segLayerNum[numSeg+1]) + + numErr = 0 + (foreach bp car(busPatternsList) + chName = nth(0 bp) + channel = nth(1 bp) + ;printf("########## Looking for chName %L channel %L\n" chName channel) + (foreach ch channel + skip = nil + forceLayer = nil + segLp[0] = ch + (if debug >= 3 printf("SegLp#%d: %L\n" 0 segLp[0])) + node = nth(0 ch) + +termWire = t +(if filterList then + filterNode = ru_GetFilterList(filterList node) + (if debug >= 3 && filterNode printf("%L Found in filter list: %L\n" node filterNode)) + (if debug >= 4 && !filterNode printf("%L Not Found in filter list\n" node)) + + termWire = (filterNode!=nil) + (if filterNode && nth(1 filterNode) == "OffsetTurn" offsetTurn = nth(2 filterNode)) +) +(if filterExcludeList then + filterNode = ru_GetFilterList(filterExcludeList node) + (if debug >= 1 && filterNode printf("%L Found in filter exclude list: %L\n" node filterNode)) + (if debug >= 4 && !filterNode printf("%L Not Found in filter exclude list\n" node)) + + termWire = !(filterNode!=nil) +) + +(if termWire then + width = nth(1 ch) + offset = nth(2 ch) + layer = nth(3 ch) + (if forceLayerIdx == 0 && !forceLayer then forceLayer = layer) + filteredNode = (if strlen(node)>1 substring(node 2) node) + result = Ru_SplitNodeName(filteredNode) + filteredNode = sprintf(nil "%s%s.%s" Ru_TrimLeadingDots(car(result)) busPosfix cadr(result)) + pattern = list(list(filteredNode cadr(car(node_2W)) offset nil)) ;(DefChan (BuildDefChanList nil filteredNode 1 node_2W offset nil)) + (if debug >= 2 printf("Node#0: [%L] width %L layer %L pattern %L\n" node width layer pattern)) + layerPatternList = list(layer pattern) + altLayerPatternList = nil + hv = nth(0 pointTypes) + segLayerNum[0] = ru_layerToValue(car((if (hv=="EH"||hv=="VH") nth(0 layer) nth(1 layer)))) + segLayerNum[1] = segLayerNum[0] + + ;get each layer and pattern for each segment + (for segNum 1 (numSeg-1) + (if nth(segNum busPatternsList) then + segLp[segNum] = Ru_GetBusPatternEntry(nth(segNum busPatternsList) chName node) + else + segLp[segNum] = segLp[0] + ) + ch = segLp[segNum] + (if ch then + node = nth(0 ch) + offset = nth(2 ch) + layer = nth(3 ch) + (if forceLayerIdx == segNum && !forceLayer then + (if debug >= 2 printf("Layer is forced to %L\n" layer)) + forceLayer = layer + ) + filteredNode = (if strlen(node)>1 substring(node 2) node) + result = Ru_SplitNodeName(filteredNode) + filteredNode = sprintf(nil "%s%s.%s" Ru_TrimLeadingDots(car(result)) busPosfix cadr(result)) + pattern = list(list(filteredNode cadr(car(node_2W)) offset nil)) ;(DefChan (BuildDefChanList nil filteredNode 1 node_2W offset nil)) + (if debug >= 2 printf("Node#%d: [%L] width %L layer %L pattern %L\n" segNum node width layer pattern)) + altLayerPatternList = append(altLayerPatternList list(list(layer pattern))) + hv = nth(segNum pointTypes) + segLayerNum[segNum] = ru_layerToValue(car((if (hv=="EH"||hv=="VH") nth(0 layer) nth(1 layer)))) + segLayerNum[segNum+1] = segLayerNum[segNum] + else + skip = t + numErr++ + (if numErr < 20 printf("ERROR: Unable to find node %L in segment %d: %L\n" node segNum nth(segNum busPatternsList))) + ) + (if debug >=2 printf("SegLp#%d: %L\n" segNum segLp[segNum])) + ) + (if !skip then + (for segNum 0 (numSeg-1) + fromLayer = segLayerNum[segNum] + toLayer = segLayerNum[segNum+1] + (if !toLayer toLayer = fromLayer) + viasList = GenViasList(fromLayer toLayer) + (if mod(fromLayer 2) == 1 then + layer = list(list(sprintf(nil "M%d" fromLayer)) list(sprintf(nil "M%d" toLayer)) viasList forceViasDir) + else + layer = list(list(sprintf(nil "M%d" toLayer)) list(sprintf(nil "M%d" fromLayer)) viasList forceViasDir) + ) + (if debug >=2 printf("SegLp#%d: CfgLayer: %L fromLayer %d toLayer %d viasList: %L Layer %L\n" + segNum segLp[segNum] fromLayer toLayer viasList layer)) + (if segNum == 0 layerPatternList = list(layer nth(1 layerPatternList))) + ) + (if forceLayer then + (if debug >=2 printf("Layer is forced to %L\n" forceLayer)) + layerPatternList = list(forceLayer nth(1 layerPatternList)) + tmpList = nil + (foreach el altLayerPatternList + tmpList = append(tmpList list(list(forceLayer nth(1 el)))) + ) + altLayerPatternList = tmpList + ) + (if offsetTurn then + (if length(path) != 4 error("Only support OffsetTurn with 3 segments path, but got %d segments\n" length(path)-1)) + (let (p1 p2) + p1 = nth(1 path) + p2 = nth(2 path) + (if almostEqual(xCoord(p1) xCoord(p2)) then + p1 = (xCoord(p1)+offsetTurn):yCoord(p1) + p2 = (xCoord(p2)+offsetTurn):yCoord(p2) + else + p1 = xCoord(p1):(yCoord(p1)+offsetTurn) + p2 = xCoord(p2):(yCoord(p2)+offsetTurn) + ) + drawPath = list(nth(0 path) p1 p2 nth(3 path)) + (if debug >= 1 printf("Path is offset to %L from %L\n" drawPath path)) + ) + else + drawPath = path + ) + nodeName = car(car(nth(1 layerPatternList))) + wireName = sprintf(nil "%s%s" busPrefix nodeName) + (if debug >=1 printf("%s path: %L layerPattern: %L altLayerPatternList: %L \n" + wireName drawPath layerPatternList altLayerPatternList)) + (if debug >=2 printf("layer: %L pattern: %L\n" car(layerPatternList) nth(1 layerPatternList))) + + DrawChannel( nth(0 layerPatternList) nth(1 layerPatternList) busPrefix drawPath + ?flipX flipX ?flipY flipY + ?altLayerPatternList altLayerPatternList ?doubleVias doubleVias) + (if debugStackVias then + (for segNum 0 length(altLayerPatternList)-1 + (if segNum == 0 then + layer = car(layerPatternList) + pattern = nth(1 layerPatternList) + nextPattern = nth(1 nth(0 altLayerPatternList)) + else + layer = car(nth(numSeg-1 altLayerPatternList)) + pattern = nth(1 (nth(numSeg-1 altLayerPatternList))) + nextPattern = nth(1 (nth(numSeg altLayerPatternList))) + ) + viasList = nth(2 layer) + (if !listp(viasList) viasList = list(viasList)) + (if debug >= 2 printf("VIAS SEG#%d %s seg %L layer %L\n" segNum wireName nth(segNum+1 drawPath) viasList)) + (foreach node_offset pattern + node = (car node_offset) + offset = (caddr node_offset) + nextNode = Ru_GetChannelEntry(nextPattern node) + nextOffset = (caddr nextNode) + hv = nth(numSeg+1 pointTypes) + (if hv == "EH" || hv == "HV" then + offsetX = offset + offsetY = nextOffset + else + (if hv == "VE" || hv == "HE" then + offsetX = nextOffset + offsetY = nextOffset + else + offsetX = nextOffset + offsetY = offset + ) + ) + corner = Ru_OffsetPoint(nth(segNum+1 drawPath) + (if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0): + (if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0)) + + seg = list(Ru_OffsetPoint(corner -1*wirePitch:0.0) Ru_OffsetPoint(corner 1*wirePitch:0.0)) + + (for nVias 1 length(viasList)-2 + vias = nth(nVias viasList) + slayer = car(parseString(vias "_")) + DrawWire( list(list(slayer) list(slayer)) (AddSuffix busPrefix node) wirePitch seg + ?flipX flipX ?flipY flipY) + ) + ) + ) + ) + ) + + +);termWire + ) ;foreach + (if numErr > 20 printf("ERROR: Too many errors to list all\n")) + ) + ) +) + + + + + +(defun Ru_MidX (box) + ret = (xCoord(lowerLeft(box)) + xCoord(upperRight(box)))/2 +) + +(defun Ru_MidY (box) + ret = (yCoord(lowerLeft(box)) + yCoord(upperRight(box)))/2 +) + +(defun Ru_OffsetBox (box offset) +let( ( llx lly urx ury ) + urx = xCoord( upperRight( box )) + ury = yCoord( upperRight( box )) + llx = xCoord( lowerLeft( box )) + lly = yCoord( lowerLeft( box )) + offx = xCoord(offset) + offy = yCoord(offset) + list((llx+offx):(lly+offy) (urx+offx):(ury+offy)) +) ; let +) + +(defun GenViasList (hl vl @key (forceDir nil)) + (let (viasList) + (if hl < vl then + (for l hl (vl-1) + viasList = append(viasList list(sprintf(nil "M%d_M%d" l+1 l))) + ) + else + (for l vl (hl-1) + viasList = append(viasList list(sprintf(nil "M%d_M%d" l+1 l))) + ) + ) + (if forceDir then + viasList = list(viasList forceDir) + else viasList) + ) +) + +;generate intermediate layers when not going to adjacent layer +(defun ru_GenLayerList (hl vl) + (let (layerList) + (cond + (abs(hl-vl) <= 1 + layerList = nil + ) + (hl < vl + (for l (hl+1) (vl-1) + layerList = append(layerList list(list(list(sprintf(nil "M%d" l)) list(sprintf(nil "M%d" l)) nil nil))) + ) + ) + (t + (for l (vl+1) (hl-1) + layerList = append(layerList list(list(list(sprintf(nil "M%d" l)) list(sprintf(nil "M%d" l)) nil nil))) + ) + ) + ) + layerList + ) +) + +;points - can be one point or list of points +(defun DrawStackedVias (wireName points fromLayer toLayer @key (doubleVias t) (extend TrackPitch/2)) + (let (viasList viasPoint wirePitch) + wirePitch = TrackPitch/24 + viasList = GenViasList(fromLayer toLayer) + (if listp(car(point)) then + viasPoint = Ru_OffsetPoint(length(points)-1 points) + DrawVia(wireName viasList viasPoint wirePitch cuts ?doubleVias doubleVias) + else + ;single point + DrawVia(wireName viasList points wirePitch cuts ?doubleVias doubleVias) + ) + ) +) + +(defun Ru_LocateBuffers (bufPrefix busPattern range typeList @key (bufPosfix "") (bufMap nil) (debug 0) ) + (let (bufList lastName bp name bufName inst entry) + lastName = "" + (if !listp(typeList) typeList = list(typeList)) + (foreach bp busPattern + name = nth(0 bp) + (if strncmp(lastName name (strlen(name)-2)) != 0 then + bufName = nil + (if bufMap then + rexMagic(nil) + (foreach entry bufMap + ;printf("Node %s: Entry %L\n" name entry) + (if !bufName && rexMatchp(nth(0 entry) substring(name 1 strlen(name)-2)) then + bufName = nth(1 entry) + ;printf("%s matched to buf %s\n" name bufName) + ) + ) + rexMagic(t) + ) + (if !bufName bufName = sprintf(nil "%s%s%s" bufPrefix Ru_GetFirstField(name) bufPosfix)) + inst = (dbFindAnyInstByName (geGetEditCellView) bufName) + (if inst && member(ru_getCellType(inst->master->cellName) typeList) then + wireOff = nth(2 bp) + TrackPitch/2 + (if debug >= 1 printf("bufName %s wireOff %f range %L \n" bufName wireOff range)) + (if wireOff >= nth(0 range) && wireOff <= nth(1 range) then + ;printf(" %s: CellView: %s\n" bufName inst->master->cellName) + (if !member(bufName bufList) bufList = append(bufList list(bufName))) + ) + ) + (if !inst then + printf("Ru_LocateBuffers: No such buffer %L found. Node %s First Field %s\n" bufName name Ru_GetFirstField(name) ) +indexList = parseString(name "[]") +printf("Index %L\n" indexList) +(if integerp(nth(1 indexList)) then + printf("INDEX %d\n" nth(1 indexList)) +) + ) + ) + lastName = name + ) + bufList + ) +) + +(defun StackBuffersVert (bufList startLoc @key (offset nil) (orient nil) + (postFix "") (errorMsg t) (reserveGap nil) (setProp nil)) + (let (loc entry bufName sizeY inst gap cnt val) + sizeY = 4*TrackPitch + loc = startLoc + (foreach entry bufList + bufName = strcat(entry postFix) + inst = (dbFindAnyInstByName (geGetEditCellView) bufName) + (if inst then + (foreach gap reserveGap + val = yCoord(loc) + cnt = 0 + (while Ru_IsBetween(nth(0 gap) val nth(1 gap)) + cnt++ + printf("%L is in the reserve gap, advance #%d\n" bufName cnt) + loc = Ru_OffsetPoint(loc 0:(if offset offset sizeY)) + val = yCoord(loc) + ) + ) + inst->xy = loc + (foreach prop setProp + (dbReplaceProp inst car(prop) cadr(prop) nth(2 prop)) + ) + (if orient inst->orient = orient) + sizeY = (if offset offset yCoord(upperRight(inst->bBox))-yCoord(lowerLeft(inst->bBox))) + loc = Ru_OffsetPoint(loc 0.0:sizeY) + else + (if errorMsg printf("ERROR: Unable to find %s. Need a buffer at %L\n" bufName loc)) + ) + ) + loc + ) +) + +(defun StackBuffersHor (bufList startLoc @key (offset nil) (orient nil) + (minDist nil) (postFix "") (errorMsg t) (setProp nil) + (offsetPattern nil) (numTrack 4) (e1of2Offset nil)) + (let (loc entry bufName sizeX inst nodeBaseName nodeName nodeOffset curOffY curOffYTracks maxOff) + loc = startLoc + curOffYTracks = 0 + maxOff = 0 + (if offsetPattern maxOff = 1000) ;hardcoded + declare( baseY[maxOff+1]) + (for cnt 0 maxOff + baseY[cnt] = 0 + ) + (foreach entry bufList + bufName = strcat(entry postFix) + inst = (dbFindAnyInstByName (geGetEditCellView) bufName) + (if inst then + (if offsetPattern then + nodeBaseName = Ru_GetNodeBaseNameFromBufName(bufName) + nodeName = sprintf(nil ".%s.e" nodeBaseName) + nodeOffset = Ru_GetChannelNodeOffset(offsetPattern nodeName ?nestedArray nil) + (if !nodeOffset error("%s: Unable to find %L in offsetPattern %L\n" bufName nodeName offsetPattern)) + nodeOffset = nodeOffset + TrackPitch/2 + curOffYTracks = floor((nodeOffset+TrackPitch/64)/(numTrack*TrackPitch)) + ;(if curOffY != floor(nodeOffset/offsetMod) then + ; curOffY = nodeOffset-floor(nodeOffset/offsetMod) + ;) +;printf("%s nodeOffset %L curOffY %L %L loc %L\n" bufName nodeOffset curOffY curOffYTracks loc) + ) + loc = Ru_OffsetPoint(startLoc baseY[curOffYTracks]:curOffYTracks*numTrack*TrackPitch) + (if e1of2Offset && rexMatchp("1of2" inst->master->cellName) then + loc = OffsetPoint(loc e1of2Offset 0) + ) + inst->xy = loc + (foreach prop setProp + (dbReplaceProp inst car(prop) cadr(prop) nth(2 prop)) + ) + (if orient inst->orient = orient) + sizeX = (if offset offset xCoord(upperRight(inst->bBox))-xCoord(lowerLeft(inst->bBox))) + (if minDist && sizeX < minDist sizeX = minDist) + baseY[curOffYTracks] = baseY[curOffYTracks] + sizeX + ;loc = Ru_OffsetPoint(loc sizeX:0.0) + else + (if errorMsg printf("ERROR: Unable to find %s. Need a buffer at %L\n" bufName loc)) + ) + ) + loc + ) +) + +(defun SpaceBuffers (bufPrefix firstIdx lastIdx spacingX spacingY) + (let (inst incr) + inst = (dbFindAnyInstByName (geGetEditCellView) sprintf(nil "%s[%d]" bufPrefix firstIdx)) + (if !inst error("ERROR: Unable to find %s.\n" sprintf(nil "%s[%d]" bufPrefix firstIdx))) + baseLoc = inst->xy + (if firstIdx < lastIdx then + (for i firstIdx+1 lastIdx + incr = i - firstIdx + MoveInst(sprintf(nil "%s[%d]" bufPrefix i) OffsetPoint(baseLoc (incr*spacingX) (incr*spacingY))) + ) + else + (for i lastIdx firstIdx-1 + incr = firstIdx-i + MoveInst(sprintf(nil "%s[%d]" bufPrefix i) OffsetPoint(baseLoc (incr*spacingX) (incr*spacingY))) + ) + ) + ) +) + +(defun CombineList (listA listB every) + (let (listEntry cnt i entry) + cnt = 0 + (while cnt < length(listA) + (for i 0 every-1 + entry = nth(cnt+i listA) + (if entry listEntry = append(listEntry list(entry))) + ) + (for i 0 every-1 + entry = nth(cnt+i listB) + (if entry listEntry = append(listEntry list(entry))) + ) + cnt = cnt + every + ) + (for i cnt length(listB)-1 + entry = nth(i listB) + (if entry listEntry = append(listEntry list(entry))) + ) + listEntry + ) +) + +(defun Ru_SplitList (listEntry every) + (let (leftList rightList) + leftList = nil + rightList = nil + (for cnt 0 (length(listEntry)-1) + (if mod(cnt every*2) < every then + leftList = append(leftList list(nth(cnt listEntry))) + else + rightList = append(rightList list(nth(cnt listEntry))) + ) + ) + list(leftList rightList) + ) +) + +;Add channel overide the layer +(defun Ru_AddChannel (channel layer) + (let (ret) + (foreach el channel + (if nth(0 el) != "GND" ret = append(ret list(list( nth(0 el) list(list("" nth(1 el) 0)) nth(2 el) layer)))) + ) + ret = DefChan(ret) + ) +) + + +;These use global variable bundledList, node2BufMap, node2BufMap +(defun Ru_AddMbufList2A (prefix cnt) + (let (name bufName) + name = car(parseString(prefix ".")) + bundledList = append(bundledList list(sprintf(nil "%s[0..%d]" prefix cnt)) ) + (for i 0 cnt + bufName = sprintf(nil "mbuf_%s[%d]" name i) + mbufList = append(mbufList list(bufName)) + node2BufMap = append(node2BufMap list(list(sprintf(nil "%s[%d]" prefix i*2) bufName)) ) + node2BufMap = append(node2BufMap list(list(sprintf(nil "%s[%d]" prefix i*2+1) bufName)) ) + ) + ) +) +(defun Ru_AddMbufList2 (bufName node1 node2) + bundledList = append(bundledList list(node1)) + bundledList = append(bundledList list(node2)) + mbufList = append(mbufList list(bufName)) + node2BufMap = append(node2BufMap list(list(node1 bufName))) + node2BufMap = append(node2BufMap list(list(node2 bufName))) +) +(defun Ru_AddMbufList (bufName node1) + bundledList = append(bundledList list(node1)) + mbufList = append(mbufList list(bufName)) + node2BufMap = append(node2BufMap list(list(node1 bufName))) +) + +(defun Ru_DumpChannelList () + (let (entry) + printf("%d entries\n" length(node2BufMap)) + printf("============= Channel List ===============\n") + (foreach entry node2BufMap + printf(" (list \".%s\" inlv_e1of4_X 0*TrackPitch BusMetal67)\n" car(entry)) + ) + printf("============= Bundled List ===============\n") + (foreach entry bundledList + printf(" \"L.%s\" \"R.%s\"\n" entry entry) + + ) + ) +) + +; load("/home/user/tnguyen/alta4/virtuoso/skill/layout/route/routepath.il") +(defun InstantiateSubCellsPowerGrid (@key (debug nil)) + (let (inst result cnt pgName) + view = (geGetEditCellView) + (foreach inst view->instances + printf("%L\n" inst->cellName) + result = parseString(inst->cellName ".") + pgName = car(result) + len = length(result) + (for cnt 1 len-2 + pgName = strcat(pgName sprintf(nil ".%s" nth(cnt result))) + (if cnt == len-3 pgName = strcat(pgName ".wires")) + ) + cnt = len-1 + pgName = strcat(pgName sprintf(nil "_%s_POWER_GRID_TIEOFF" nth(cnt result))) + printf("PG: %L\n" pgName) + pgView = dbOpenCellViewByType(inst->libName pgName "layout") + (if pgView then + dbCreateInst(view pgView strcat(inst->name ".tiehilow") inst->xy inst->orient 1) + else + printf("ERROR: Unable to open layout view for %L\n" pgName) + ) + ) +;chip.alta.route.ffu_to_nexthop.wires.PATH_FfuToNextHopHdChannel_1000_POWER_GRID_TIEOFF +;chip.alta.route.ffu_to_l3ar.wires.PATH_FfuToL3ArHdChannelA_1000_POWER_GRID_TIEOF +;chip.alta.route.ffu_to_l3ar.wires.PATH_FfuToL3ArHdChannelA_1000_POWER_GRID_TIEOFF + ) +) + +(defun Ru_DrawChannel (layers pattern prefix points + @key (flipX nil) (flipY nil) (isPin nil) + (startVias nil) (endVias nil) (doubleVias t) + (altLayerPatternList nil) + (guideInstName nil) (guideInst nil)) + (let (newpoints node width offset index x y hv + offsetX offsetY nextOffset curOffset lastLayer curLayer tmpx tmpy cuts nodeIdx + curPattern nextLayer nextPattern stVias eVias segNum layer_override lastx lasty + (types (ClassifyPoints points))) + + ; set guide instance + guideInst = (GetGuideInst guideInst guideInstName) + + ; go through all nodes in channel + nodeIdx = 0 + (foreach node_offset pattern + node = (car node_offset) + width = (cadr node_offset) + offset = (caddr node_offset) + layer_override = (cadddr node_offset) + newpoints = nil + index = 0 + segNum = 0 ; for multiple segment due to changing layers + lastLayer = curLayer + (foreach point points + x = (car point) + y = (cadr point) + hv = (nth index types) + (if altLayerPatternList || listp(startVias) || listp(endVias) then + ;altLayerPatternList either a list of patterns for each segments or a single one + ;if a single one it will be used for the second segment to the end + ;a nil entry in the altLayerPatternList will use the original layer and pattern + nextOffset = offset + curOffset = offset + curLayer = layers + (if length(altLayerPatternList) > 1 + then + ;current pattern + (if index >= 2 && nth(1 nth(index-2 altLayerPatternList)) + then + curLayerPattern = nth(index-2 altLayerPatternList) + curLayer = nth(0 curLayerPattern ) + curPattern = nth(1 curLayerPattern ) + (if car(nth(nodeIdx curPattern)) == node then ;assume the same index order + curOffset = caddr(nth(nodeIdx curPattern)) + else + (foreach cur_node_offset curPattern + (if node == (car cur_node_offset) then + curOffset = (caddr cur_node_offset) + ) + ) + ) + ) + ;next pattern + (if index >= 1 && nth(1 nth(index-1 altLayerPatternList)) + then + nextLayer = nth(0 nth(index-1 altLayerPatternList)) + nextPattern = nth(1 nth(index-1 altLayerPatternList)) + (if car(nth(nodeIdx nextPattern)) == node then ;assume the same index order + nextOffset = caddr(nth(nodeIdx nextPattern)) + else + (foreach next_node_offset nextPattern + (if node == (car next_node_offset) then + nextOffset = (caddr next_node_offset) + ) + ) + ) + ) + else +; load "/home/user/tnguyen/alta4/virtuoso/skill/layout/bus/bus.il" + ;single alternate pattern + altLayerPattern = nth(0 altLayerPatternList) + altLayer = nth(0 altLayerPattern) + (if !altLayer altLayer = layers) ;for viasList + altPattern = nth(1 altLayerPattern) + (if !altPattern altPattern = pattern) + (if car(nth(nodeIdx altPattern)) == node then ;assume the same index order + altOffset = caddr(nth(nodeIdx altPattern)) + else + (foreach alt_node_offset altPattern + (if node == (car alt_node_offset) then + altOffset = (caddr alt_node_offset) + ) + ) + ) + (if index <= 1 + then curLayer = layers nextLayer = (if (index == 0) layers altLayer) curOffset = offset nextOffset = altOffset + else curLayer = altLayer nextLayer = altLayer curOffset = altOffset nextOffset = altOffset + ) + ) + (if hv == "EH" || hv == "HV" then + offsetX = nextOffset + offsetY = curOffset + else + (if hv == "VE" || hv == "HE" then + offsetX = curOffset + offsetY = curOffset + else + offsetX = curOffset + offsetY = nextOffset + ) + ) + ;layer info is in the startVias to draw multiple vias + stVias = (segNum == 0 && startVias == t) + (if (caddr curLayer) != (caddr lastLayer) && length(newpoints) >= 1 then + ;switch layers if via list is different + tmpx = x + (if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0.0) + tmpy = y + (if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0.0) + newpoints = (append newpoints (list (list ((lastx+tmpx)/2.0) ((lasty+tmpy)/2.0)))) + (DrawWire lastLayer (AddSuffix prefix node) + width newpoints + ?isPin isPin ?startVias stVias ?endVias nil + ?doubleVias doubleVias ?guideInst guideInst) + newpoints = (list (list ((lastx+tmpx)/2.0) ((lasty+tmpy)/2.0))) + ) + lastLayer = curLayer + lastx= x+(if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0) + lasty = y+(if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0) + (if segNum == 0 && startVias && startVias!=t then + ;startVias can draw multiple vias or force direction + (if listp(car(startVias)) then + cuts = strcat("_2CUT_" cadr(startVias)) + stVias = car(startVias) + else + cuts = (if (and hv!="HE" hv!="EH") "_2CUT_V" "_2CUT_H") + stVias = startVias + ) + DrawVia((AddSuffix prefix node) stVias lastx:lasty + width cuts ?doubleVias doubleVias ?stacked !doubleVias) + stVias = nil + ) + eVias = endVias + (if segNum == length(points)-1 && endVias && endVias!=t then + ;endVias can draw multiple vias or force direction + (if listp(car(endVias)) then + cuts = strcat("_2CUT_" cadr(endVias)) + eVias = car(endVias) + else + cuts = (if (and hv!="HE" hv!="EH") "_2CUT_V" "_2CUT_H") + eVias = endVias + ) + DrawVia((AddSuffix prefix node) eVias lastx:lasty + width cuts ?doubleVias doubleVias ?stacked !doubleVias) + eVias = nil + ) + segNum++ + else + ; no alternate pattern + offsetX = offset + offsetY = offset + stVias = startVias + eVias = endVias + curLayer = layers + ) + + x = x+(if flipX -1 1)*(if (and hv!="HE" hv!="EH") offsetX 0) + y = y+(if flipY -1 1)*(if (and hv!="VE" hv!="EV") offsetY 0) + newpoints = (append newpoints (list (list x y))) + index = index+1 + ) + ; draw wire for this node + (DrawWire (if layer_override layer_override curLayer) + (AddSuffix prefix node) width newpoints + ?isPin isPin ?startVias stVias ?endVias eVias + ?doubleVias doubleVias ?guideInst guideInst) + nodeIdx++ + ) + ) + t + ) + + +;Allow to extend end points +(defun Ru_DrawWire (layers name width points + @key (isPin nil) (startVias nil) (endVias nil) (doubleVias t) (vias2Cut t) + (beginExt nil) (endExt nil) + (guideInst nil)) + (let (horz_layer vert_layer via viadir last first lastIndex index cuts layer) +;Ru_ValidatePath(points sprintf(nil "Ru_DrawWire: %L points %L" name points)) + horz_layer = (car layers) + vert_layer = (cadr layers) + via = (caddr layers) + viadir = (cadddr layers) + points = (CanonicalizePoints points) + last = (car points) + first = t + lastIndex = (length points)-2 + index = 0 + (if vias2Cut cuts = (if (almostEqual (car (cadr points)) (car last)) "_2CUT_V" "_2CUT_H")) + (if startVias (DrawVia name via last width cuts ?doubleVias doubleVias ?guideInst guideInst)) + (foreach point (cdr points) + layer = (if (almostEqual (car point) (car last)) vert_layer horz_layer) + (DrawSegment name layer width last point + (index!=0||beginExt) + (index!=lastIndex || endExt) + isPin ?guideInst guideInst) + cuts = (if (and doubleVias viadir) (strcat "_2CUT_" viadir) "") + (if (not first) (DrawVia name via last width cuts + ?doubleVias doubleVias ?guideInst guideInst)) + first = nil + (if vias2Cut cuts = (if (almostEqual (car point) (car last)) "_2CUT_V" "_2CUT_H")) + last = point + index = index+1 + ) + (if endVias (DrawVia name via last width cuts ?doubleVias doubleVias ?guideInst guideInst)) + ) + t + ) + +(defun Ru_SegmentDirection (a b) + (let (dx dy) + dx = (nth 0 b) - (nth 0 a) + dy = (nth 1 b) - (nth 1 a) + (if (dx != 0.0) then + dx = dx/(abs dx)) + (if (dy != 0.0) then + dy = dy/(abs dy)) + list(floor(dx) floor(dy)))) + +(defun Ru_isMultiple (x m) + (floor x/m) == (x/m)) + +(defun Ru_isPitchMultiple (x) + Ru_isMultiple(x 1.44)) + +(defun Ru_roundToMultiple (x n) + (n * (round x/n))) + +(defun Ru_ComputePathListFromGuide (@key (cellCat "chip.alta") + (cellInst "chip.alta.ALTA-L76-R.1000") + (cellView "abstract") + (guideName nil) + (trackWidth nil) + (trackOffset nil) + (startingPoint nil) + (endingPoint nil) + (reverseList nil) + (debug nil)) + (let (shape cv channelName points propName guidePath cx cy nx ny tx ty delta offset dir) + + (if !cellView + then + cv = (geGetEditCellView) + else + cv = (dbOpenCellViewByType cellCat cellInst cellView)) + + (if guideName != nil + then + ; look for all paths in the current view + (foreach shape cv->shapes + + ; process only shapes with type "path" + (when shape->objType=="path" + + ; look for the "Channel" or "myProp" property + propName = "Channel" + channelName = (GetProp shape propName nil) + (when channelName == nil + propName = "myProp" + channelName = (GetProp shape propName nil) + ) + ; typically the name is FooBar,.* so we trim up to the , + (if (channelName != nil) && ((nindex channelName ",") != nil) + then + (setq channelName (substring channelName 1 ((nindex channelName ",") - 1)))) + + ; matching entry? + (if (channelName == guideName) && (channelName != nil) + then + (printf "Found guide path %s\n" channelName) + + ; check points + (if Ru_isPitchMultiple((nth 0 startingPoint)) || + Ru_isPitchMultiple((nth 1 startingPoint)) || + Ru_isPitchMultiple((nth 0 endingPoint)) || + Ru_isPitchMultiple((nth 1 endingPoint)) then + (printf "WARNING: starting or ending points are not multiples of 1.44\n")) + + points = shape->points + + (if reverseList then + points = reverse(points)) + (printf "%d points in list\n" length(points)) + + delta = (trackWidth / 2) * 2.88 + (printf "Computed delta as %3.2f\n" delta) + offset = (trackOffset * 2.88) + 1.44 + (printf "Computed offset as %3.2f\n" offset) + + ; clear starting path + guidePath = list(startingPoint) + cx = (nth 0 startingPoint) + cy = (nth 1 startingPoint) + (printf "Initial point %3.2f %3.2f\n" cx cy) + + ; first point + dir = (Ru_SegmentDirection (nth 0 points) (nth 1 points)) + (printf "Segment direction is (%d, %d)\n" (nth 0 dir) (nth 1 dir)) + + (if (nth 1 dir) == 0 + then + ; segment is left-to-right but does not extend to starting point + (if ((nth 0 (nth 0 points)) > cx) && ((nth 0 dir) > 0) + then + (printf "WARNING: first segment (rightward) does not extend to starting point\n")) + + ; segment is right-to-left but does not extend to starting point + (if ((nth 0 (nth 0 points)) < cx) && ((nth 0 dir) < 0) + then + (printf "WARNING: first segment (leftward) does not extend to starting point\n")) + + ; horizontal path + nx = cx + ; y-coordinate of 1st point in path + ny = (nth 1 (nth 0 points)) - delta + offset + else + ; segment is bottom-to-top but does not extend to starting point + (if ((nth 0 (nth 1 points)) > cx) && ((nth 1 dir) > 0) + then + (printf "WARNING: first segment (upward) does not extend to starting point\n")) + + ; segment is top-to-bottom but does not extend to starting point + (if ((nth 0 (nth 1 points)) < cx) && ((nth 1 dir) < 0) + then + (printf "WARNING: first segment (downward) does not extend to starting point\n")) + ; vertical path + ny = cy + ; x-coordinate of 1st point in path + nx = (nth 0 (nth 0 points)) - delta + offset + + ) ; end if + + + ; add point and update + guidePath = append(guidePath list(list(nx ny))) + cx = nx + cy = ny + (printf "First segment point %3.2f %3.2f\n" cx cy) + + (for i 1 (length points)-2 + nx = (nth 0 (nth i points)) + ny = (nth 1 (nth i points)) + dir = (Ru_SegmentDirection (nth i points) (nth i+1 points)) + (printf "Raw point #%d is %3.2f %3.2f, direction is (%d, %d)\n" i nx ny (nth 0 dir) (nth 1 dir)) + + (if (nth 1 dir) == 0 + then + ; horizontal path + nx = cx + ; y-coordinate of 1st point in path + ny = ny - delta + offset + else + ; vertical path + ny = cy + ; x-coordinate of 1st point in path + nx = nx - delta + offset + + ) ; end if + + + ; add point and update + guidePath = append(guidePath list(list(nx ny))) + cx = nx + cy = ny + (printf "Segment point #%d is %3.2f %3.2f\n" i cx cy) + + ) ; end for + + cx = (nth 0 endingPoint) + cy = (nth 1 endingPoint) + nx = (nth 0 (nth length(points)-1 points)) + ny = (nth 1 (nth length(points)-1 points)) + + (if (nth 1 dir) == 0 + then + ; segment is left-to-right but does not extend to starting point + (if (nx < cx) && ((nth 0 dir) > 0) + then + (printf "WARNING: last segment (rightward) does not extend to ending point\n")) + + ; segment is right-to-left but does not extend to starting point + (if (nx > cx) && ((nth 0 dir) < 0) + then + (printf "WARNING: last segment (leftward) does not extend to ending point\n")) + + ; horizontal path + nx = cx + ; y-coordinate of last point in path + ny = ny - delta + offset + else + ; segment is bottom-to-top but does not extend to ending point + (if (ny < cy) && ((nth 1 dir) > 0) + then + (printf "WARNING: last segment (upward) does not extend to ending point\n")) + + ; segment is top-to-bottom but does not extend to ending point + (if (ny > cy) && ((nth 1 dir) < 0) + then + (printf "WARNING: last segment (downward) does not extend to ending point\n")) + ; vertical path + ny = cy + ; x-coordinate of last point in path + nx = nx - delta + offset + + ) ; end if + + ; add point and update + guidePath = append(guidePath list(list(nx ny))) + (printf "Last segment point %3.2f %3.2f\n" nx ny) + guidePath = append(guidePath list(list(cx cy))) + (printf "Last point %3.2f %3.2f\n" cx cy) + + ; round to 1.44 multiples + guidePath = mapcar('(lambda (x) (list Ru_roundToMultiple((nth 0 x) 1.44) + Ru_roundToMultiple((nth 1 x) 1.44))) guidePath) + + ; draw in prBound if needed + (if debug then dbCreatePath(cv list("prBoundary") guidePath 0.5)) + + (printf "----\n") + (printf "list(\n") + (for i 0 length(guidePath)-1 + (printf " list(%3.2f %3.2f) ; tracks (%3.2f %3.2f)\n" + (nth 0 (nth i guidePath)) + (nth 1 (nth i guidePath)) + (nth 0 (nth i guidePath))/1.44 + (nth 1 (nth i guidePath))/1.44 )) + (printf ")\n") + + ) ; end if + + ) ; end when + + ) ; end foreach + else + (printf "No guidename specified\n") + ) ; end if + + ) ; end let +) + +;wrapper function for CopyGuidePath +(defun GenObstructions ( propValue + @key (libName "chip.alta") + (cellName "chip.alta.PATHS-L76-R.1000") + (viewType "abstract") + (deleteObs t) ;delete any existing obstructions + (segOff nil) ;adjust segment number + (reversePath nil) ;path is drawn reverse order + ) + + CopyGuidePath(propValue ?libName libName ?cellName cellName ?viewType viewType + ?deleteObs deleteObs ?segOff segOff ?reversePath reversePath + ?addBound nil) + +) + +; copy a guide path from one cellview to the current +; identify potential obstruction and create them +; in the destination cellview +(defun CopyGuidePath ( propValue + @key (libName "chip.alta") + (cellName "chip.alta.PATHS-L76-R.1000") + (viewType "abstract") + (propList (list "Channel" "myProp")) + (cleanup nil) + (deleteObs t) ;delete any existing obstructions + (segOff nil) ;adjust segment number + (reversePath nil) ;path is drawn reverse order + (addBound t) ;copy over pr bound + ) + (prog ( curView srcView channelName properties propName shape shapeCount + dstShape points p0 p1 x0 x1 y0 y1 width ) + + ; determine the current cellview + curView = ( geGetEditCellView ) + (when curView == nil + (printf "No destination cellview selected!\n") + (return nil) + ) ; end (when curView ... ) + + ; determine the source cellview + srcView = ( dbOpenCellViewByType libName cellName viewType ) + (when srcView == nil + (printf "Invalid source cellview: %s - %s - %s\n" libName cellName viewType) + (return nil) + ) ; end (when srcView ... ) + + ; perform the initial cleanup of the destination cellview + ; if required. That consists in deleting guidepaths featuring + ; at least one of the properties in propList matching propValue + (when cleanup == t + ( DeleteGuidePath propValue ?curView curView ?propList propList ) + ) ; end (when cleanup ... ) + (when deleteObs == t + ( DeleteObstructions ?all nil) + ) ; end (when deleteObs ... ) + + ; now look for all matching paths in the source cellView. + ; Every matching path will be copied over to the destination + ; cellview. Also for every matching path, we'll be looking + ; for other paths featuring at least one of the the properties + ; in propList that intersect it. For each intersection an + ; obstruction will be created in the destination cellview + (foreach shape srcView->shapes + + ; is this a matching path? + channelName = (Ru_MatchPathShape shape propValue propList) + (when channelName != nil + ; yes it is. Copy it to the destination cellview to start with. + (if addBound + then + dstShape = (dbCopyFig shape curView) + (if dstShape != nil + then + ; copy successful. Now: + + ; 1. Transform the path in a polygon + (dbConvertPathToPolygon dstShape) + ; 2. change the layer to prBound + dstShape->lpp = (list "prBoundary" "drawing") + ; 3. save the destination cellview + (dbSave curView) + + else + ; copy failed, just log that + (printf "Couldn't copy shape %s" shape) + ) ; end if (dbCopyFig ... ) + ) + ; crossing paths + (printf ";------------------------------------------------\n") + (printf ";Generated with: %s %L %s %s %s\n" + (if addBound "CopyGuidePath" "GenObstructions") propValue + (if segOff sprintf(nil "?segOff %d" segOff) "" ) + (if reversePath sprintf(nil "?reversePath t") "" ) + (if cellName!="chip.alta.PATHS-L76-R.1000" sprintf(nil "?cellName %s" cellName) "") + ) + (printf ";Obstructions for path %s:\n" channelName) + (Ru_CreatePathObstructions shape srcView propList curView segOff reversePath) + ) ; end (when (PathShapeMatch ... ) + ) ; end foreach + (return t) + ) ; end prog + ) ; end CopyGuidePath + + +; delete guide paths and obstructions from a cellview +(defun DeleteGuidePath ( propValue + @key (curView (geGetEditCellView) ) + (propList (list "Channel" "myProp"))) + (let ( shape ) + (foreach shape curView->shapes + (if (Ru_MatchPathShape shape propValue propList) != nil + then (dbDeleteObject shape) + else + (when (Ru_isPathObstruction shape) + (dbDeleteObject shape) + ) ; end ( when (isBusOps ... ) + ) ; end (if ... ) + ) ; end (foreach ... ) + (dbSave curView) + ) ; end let + ) ; end DeleteGuidePath + + +; function to see if a given shape matches at least one +; guide path's property +(defun Ru_MatchPathShape ( shape propValue propList ) + (let ( channelName properties propName regexp matches) + + ; create the regular expression for path property matching if needed + matches = nil + (when propValue != nil regexp = (sprintf nil "^%s" propValue)) + + ; in order for this shape to match a given guide path + ; three conditions have to be true + ; 1. The shape object has to be of type "path" or "polygon" + ; 2. The shape must feature one of the properties in propList + ; 3. If a propValue is given the property must be equal to propValue + + (when (or shape->objType=="path" shape->objType=="polygon") + + ; look for any of the valid properties + channelName = nil + properties = propList + + ; scan the property list + (while (and channelName == nil properties != nil matches == nil) + propName = (car properties) + properties = (cdr properties) + channelName = (GetProp shape propName nil) + + ; is this a matching path? + (when (and channelName != nil + ( or propValue == nil ( rexMatchp regexp channelName ) == t )) + matches = t + ) ; end (when channelName ... ) + ) ; end (while ... ) + ) ; end (when shape->objType ... ) + + (if matches == t then channelName else nil) + ) ; end let + ) ; end Ru_MatchPathShape + +; create obstructions for each path in a cellview crossing a given path +(defun Ru_CreatePathObstructions ( path srcView propList curView segOff reversePath) + (let ( bbox dir points_i bbox_i points_j bbox_j shapet dstShape obs prop) + + ; output list of obstructions to console using the format + ; needed by the single cell flow + (printf "\nreserveGap = list(\n") + + points_i = path->points + (for i 0 (length points_i)-2 + bbox = (Ru_CreateBboxFromPathSegment + (nth i points_i) + (nth i+1 points_i) + path->width) + bbox_i = (car bbox) + dir = (cadr bbox) + + ; now copy the shapes to the destination cellview + (foreach shape srcView->shapes + (when (and shape != path + (or ((Ru_MatchPathShape shape nil propList) != nil && shape->width != nil) ;a path + (shape->objType == "rect" && cadr(shape->lpp) == "boundary" && car(shape->lpp) != "M7") ;a bypass rectangle + ) ;or + ) ;and + points_j = shape->points + (if shape->objType == "rect" points_j = list(1:1 2:2)) ;fake for the for loop + (for j 0 (length points_j)-2 + (if shape->objType == "rect" then + bbox_j = shape->bBox + else + bbox = (Ru_CreateBboxFromPathSegment + (nth j points_j) + (nth j+1 points_j) + shape->width) + bbox_j = (car bbox) + ) + + obs = (RectGetIntersection bbox_i bbox_j) + (when obs != nil && (RectGetArea obs) >= TrackPitch**2/4 + ; create an obstruction in the destination cellview + ; for the intersection between these two path segments + (printf " list( %d" (if reversePath ((length points_i)-1-i) i)+(if segOff segOff 0)) + (if dir == 0 + then (printf " %8.2f %8.2f )\n" + (leftEdge obs) (rightEdge obs)) + else (printf " %8.2f %8.2f )\n" + (bottomEdge obs) (topEdge obs)) + ) + dstShape = (dbCreateRect curView (list "OBS" "bus") obs) + (if dstShape == nil + then (printf "Couldn't create obstruction\n") + else + (CreateObsProps ?shapes (list dstShape)) + (if dir == 0 + then + prop = (dbGetPropByName dstShape "M2") + prop->value = "TRUE" + prop = (dbGetPropByName dstShape "M4") + prop->value = "TRUE" + prop = (dbGetPropByName dstShape "M6") + prop->value = "TRUE" + else + prop = (dbGetPropByName dstShape "M3") + prop->value = "TRUE" + prop = (dbGetPropByName dstShape "M5") + prop->value = "TRUE" + prop = (dbGetPropByName dstShape "M7") + prop->value = "TRUE" + ) ; end (if dir ... ) + ;set property so we only delete autogenerated obstruction + (dbReplaceProp dstShape "AutoGenerated" "boolean" t) + ) ; end ( if dstShape ... ) + ) ; end (when obs ... ) + ) ; end ( for j ... ) + ) ; end (when ... ) + ) ; end (foreach shape ... ) + ) ; end ( for i ... ) + (printf " )\n") + (dbSave curView) + ) ; end let + ) ; end Ru_CreatePathObstructions + + +; create a bounding box from a path segment +; identified by start point, end point, width +(defun Ru_CreateBboxFromPathSegment ( p0 p1 width ) + (let (bbox x0 x1 y0 y1 dir) + x0 = (car p0) + y0 = (cadr p0) + x1 = (car p1) + y1 = (cadr p1) + (if !width || width < TrackPitch width = TrackPitch) + ; determine the direction + (if x1 == x0 + then + ; we're moving vertically + bbox = (list x0-width/2:(min y0 y1) x0+width/2:(max y0 y1)) + dir = 1 + else + ; we're moving horizontally + bbox = (list (min x0 x1):y0-width/2 (max x0 x1):y0+width/2) + dir = 0 + ) ; end ( if x1 == x0 ) + (list bbox dir) + ) ; end let + ) ; end Ru_CreateBboxFromPathSegment + + + +; check if a given shape is a path obstruction +(defun Ru_isPathObstruction ( shape ) + (let ( isPathObs ) + isPathObs = + (cond + ((isBusObs shape) t) + ((and shape->objType == "rect" shape->lpp = (list "M2" "boundary")) t) + ((and shape->objType == "rect" shape->lpp = (list "M3" "boundary")) t) + ((and shape->objType == "rect" shape->lpp = (list "M4" "boundary")) t) + ((and shape->objType == "rect" shape->lpp = (list "M5" "boundary")) t) + ((and shape->objType == "rect" shape->lpp = (list "M6" "boundary")) t) + ((and shape->objType == "rect" shape->lpp = (list "M7" "boundary")) t) + (t nil) + ) ;end conditions + + isPathObs + ) ; end let + ) ; end Ru_isPathObstruction + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CreateSimpleAbstract ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun CreateBlackboxAbstract (@key (cv nil) (cutaroundpins nil) (abstractName "abstract") ) + (let (abstractcv name net fig term nonDwShapesCnt + havem2pins havem3pins havem4pins havem5pins havem6pins havem7pins) + (when !cv + cv=(geGetEditCellView) + ) + (if rexMatchp("^abstract" cv->viewName) error("Cannot create %L from %L\n" abstractName cv->viewName)) + abstractcv=(nrOpenCellViewWritable cv->libName cv->cellName abstractName) + (when !abstractcv + (printf "Couldn't edit abstract view for %s\n" cv->cellName) + (error "Cellview not writable.\n") + ) + (printf "Starting abstract of %s at %s\n" cv->cellName (getCurrentTime)) + (foreach shape abstractcv->shapes + (when shape (dbDeleteObject shape) ) + ) + + ;copy prbound to abstract and make keepouts + (foreach prb (setof shape cv->shapes shape->lpp==BoundaryLPP) + (dbCopyFig prb abstractcv) + ) + (AbstractInvertKeepout Metal1byLPP cv abstractcv) + (AbstractInvertKeepout Metal2byLPP cv abstractcv) + (AbstractInvertKeepout Metal3byLPP cv abstractcv) + (AbstractInvertKeepout Metal4byLPP cv abstractcv) + (AbstractInvertKeepout Metal5byLPP cv abstractcv) + (AbstractInvertKeepout Metal6byLPP cv abstractcv) + (AbstractInvertKeepout Metal7byLPP cv abstractcv) + + ;copy pins to abstract + havem2pins=nil + havem3pins=nil + havem4pins=nil + havem5pins=nil + havem6pins=nil + havem7pins=nil + nonDwShapesCnt = 0 + (foreach shape cv->shapes + (when shape->pin + (when shape->net->name!="GND" && shape->net->name!="Vdd" + name=shape->net->name + net=(dbFindNetByName abstractcv name) + (when !net net=(dbCreateNet abstractcv name)) + term=(dbFindTermByName abstractcv name) + (when !term (dbCreateTerm net name "inputOutput")) + fig=(dbCopyFig shape abstractcv) +(if cadr(fig->lpp) != "drawing" then + nonDwShapesCnt++ + fig->lpp = (list car(fig->lpp) "drawing") +) + (dbCreatePin net fig) + ) + (when shape->lpp==Metal2LPP || shape->lpp==Metal2pinLPP + havem2pins=t + ) + (when shape->lpp==Metal3LPP || shape->lpp==Metal3pinLPP + havem3pins=t + ) + (when shape->lpp==Metal4LPP || shape->lpp==Metal4pinLPP + havem4pins=t + ) + (when shape->lpp==Metal5LPP || shape->lpp==Metal5pinLPP + havem5pins=t + ) + (when shape->lpp==Metal6LPP || shape->lpp==Metal6pinLPP + havem6pins=t + ) + (when shape->lpp==Metal7LPP || shape->lpp==Metal7pinLPP + havem7pins=t + ) + ) + ) + (PinUtilOrientLabels abstractcv) + + ;chop keepouts around pins + (when cutaroundpins + (when havem2pins (AbstractCutAroundPins abstractcv Metal2LPP Metal2byLPP ?otherpinlpp Metal2pinLPP)) + (when havem3pins (AbstractCutAroundPins abstractcv Metal3LPP Metal3byLPP ?otherpinlpp Metal3pinLPP)) + (when havem4pins (AbstractCutAroundPins abstractcv Metal4LPP Metal4byLPP ?otherpinlpp Metal4pinLPP)) + (when havem5pins (AbstractCutAroundPins abstractcv Metal5LPP Metal5byLPP ?otherpinlpp Metal5pinLPP)) + (when havem6pins (AbstractCutAroundPins abstractcv Metal6LPP Metal6byLPP ?otherpinlpp Metal6pinLPP)) + (when havem7pins (AbstractCutAroundPins abstractcv Metal7LPP Metal7byLPP ?otherpinlpp Metal7pinLPP)) + ) + ;create power pins + powerPinLoc = Ru_AlignX(Ru_MidX(abstractcv->bBox)):Ru_AlignY(Ru_MidY(abstractcv->bBox)) + (CreatePowerPins abstractcv "M7" powerPinLoc t) + (printf "Power pins location is at %L\n" powerPinLoc) + (printf "Finished abstract of %s at %s\n" cv->cellName (getCurrentTime)) + (if nonDwShapesCnt!=0 printf("%d pins converted to drawing shapes\n" nonDwShapesCnt)) + (dbSave abstractcv) + t + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/sync.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/sync.il new file mode 100644 index 0000000000..66cca6418d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/sync.il @@ -0,0 +1,69 @@ +; Sync-to-Netlist with default options. +; +; Copyright 2010 Fulcrum Microsystems. All rights reserved. + +; Sync-to-netlist with appropriate options +(defun SyncToNetlist (@key (CV (geGetEditCellView)) (old nil)) + (let (routed TEMP NetFile DirectivesFile ExecCmd Command status) + + ; check usage + (unless CV->viewName=="layout_pg" || CV->viewName=="layout" || + CV->viewName=="flatten" || + CV->viewName=="floorplan" || CV->viewName=="prelayout" + (printf "Can't identify view type for %s. SyncToNetlist will run in flat mode.\n" CV->cellName)) + + ; select routed mode + routed = !(CV->viewName=="floorplan" || CV->viewName=="prelayout") + + ; load wires.il to set maxHeapSize + (LoadWires ?CV CV) + + ; paths, files, commands + TEMP = (ConfigFileGetValue TheCDSConfigTable "TEMP") + NetFile = (sprintf nil "%s/ilnets/%s.netlist.il" TEMP CV->cellName) + DirectivesFile = (sprintf nil "%s/ildirectives/%s.directives.il" + TEMP CV->cellName) + ExecCmd = (if (and (boundp `ExecCmd) (stringp ExecCmd)) ExecCmd "") + + ; run cast2skill + Command = (sprintf nil + "%s %s/cast2skill --cast-path=%s --cell=%s %s --output-dir=%s --cadence-name --root-only --suppress-pins --max-heap-size=%dM %s --64" + ExecCmd + (PackageGetBinRoot) + (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + CV->cellName + (if routed "--routed" "") + TEMP + (nrGetMaxHeapSize) + (nrGetJavaArguments) + ) + (printf "%s\n" Command) + status = (shell Command) + (unless status (error "Cast/Spec didn't parse.\n")) + + ; update DFII information + if( old then + (UpdateNetlistGenFromSkillNetlistUsingPDKInfo + CV (sprintf nil "%s/ilnets" TEMP) (sprintf nil "%s/ildirectives" TEMP)) + else + (SyncNetlistGenFromSkillNetlistUsingPDKInfo + CV (sprintf nil "%s/ilnets" TEMP) (sprintf nil "%s/ildirectives" TEMP)) + ) + + ; set protected property on subcells + (foreach inst CV->instances + (unless inst->libName==TechLibName (ProtectInstance inst))) + + ; set routed property + (dbReplaceProp CV "routed" "string" + (if (setof key DirectiveTable key=="routed") + (if (arrayref DirectiveTable "routed") "yes" "no") + "undefined")) + t + ) + ) + +; obsolete form for backward compatibility +(defun nrSyncToNetlist (CV @key (routed nil)) + (SyncToNetlist ?CV CV ?old t) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/trim.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/trim.il new file mode 100644 index 0000000000..ec493fe6aa --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/route/trim.il @@ -0,0 +1,247 @@ +; Trim dangling paths and contacts after routing. +; +; Copyright 2011 Fulcrum Microsystems. All rights reserved. + +; Trim dangling paths and contacts for all nets except Vdd/GND. +(defun TrimDanglingWires + (@key (CV (geGetEditCellView)) + (overhang 2*DefaultWiringPitch) + (nets nil) + (depth 32) + ) + (let (Vdd GND progress total) + GND = (dbFindNetByName CV "GND") + Vdd = (dbFindNetByName CV "Vdd") + (unless nets nets = (setof net CV->nets (and net!=GND net!=Vdd))) + total = 0 + (foreach net nets + progress = 1 + (while progress>0 + progress = 0 + progress = progress + (MergePaths net) + progress = progress + (TrimDuplicateContacts net) + progress = progress + (TrimDanglingPaths net ?CV CV + ?overhang overhang ?depth depth) + progress = progress + (TrimDanglingContacts net ?CV CV ?depth depth) + total = total + progress + ) + ) + total + ) + ) + +; Check if two 2-point paths have the same net, lpp, and width, and +; touch at endpoints and are same direction. +(defun ArePathsMergable (path1 path2) + (let (a1 b1 a2 b2 vert1 vert2) + (when (and path1 path2 + path1->objType=="path" + path2->objType=="path" + (length path1->points)==2 + (length path2->points)==2 + path1->lpp==path2->lpp + path1->net==path2->net + path1->width==path2->width) + a1 = (car path1->points) + b1 = (cadr path1->points) + a2 = (car path2->points) + b2 = (cadr path2->points) + vert1 = (car a1)==(car b1) + vert2 = (car a2)==(car b2) + (and vert1==vert2 (or a1==a2 a1==b2 b1==a2 b1==b2)) + ) + ) + ) + +; Merge paths before trimming them. Only merges 2-point paths to +; generate new 2-point paths. +(defun MergePaths (net) + (let (n paths mpaths npaths path1) + n = 0 + (foreach lpp MetalLPPs + paths = (setof obj net->figs + (and obj->objType=="path" + obj->lpp==lpp + (length obj->points)==2)) + ; NOTE: quadratic algorithm in number of paths on each layer of net + (while paths + path1 = (car paths) + paths = (cdr paths) + npaths = nil + (foreach path2 paths + (cond ((ArePathsMergable path1 path2) + mpaths = (leMergeShapes (list path1 path2)) + (when (length mpaths)==1 n = n+1) + (foreach path mpaths + (when path!=path1 npaths = (cons path npaths)) + ) + ) + (t + ; add non-merged shape to npaths + npaths = (cons path2 npaths) + ) + ) + ) + paths = npaths + ) + ) + n + ) + ) + +; Trim dangling paths on a net. Delete if it only overlaps one +; contact or path, otherwise leave at least some overhang to meet +; minimum area on stacked vias. +(defun TrimDanglingPaths + (net @key (CV (geGetEditCellView)) (overhang 2*DefaultWiringPitch) (depth 32)) + (let (progress paths xy0 xy1 x0 y0 x1 y1 bbox overlaps unknown + xy bxy0 bxy1 bx0 by1 bx1 by1 + nx0 ny0 nx1 xy1 n progress) + progress = 0 + paths = (setof obj net->figs + (and obj->objType=="path" (length obj->points)==2 + (isMetalDrawing (car obj->lpp) (cadr obj->lpp)))) + (foreach path paths + ; create bbox from 2 points of path + xy0 = (car path->points) + xy1 = (cadr path->points) + x0 = (car xy0) + y0 = (cadr xy0) + x1 = (car xy1) + y1 = (cadr xy1) + bbox = path->bBox + + ; find bbox of overlapping paths and contacts + overlaps = (append (dbGetOverlaps CV bbox (list path->layerName "drawing") depth) + (dbGetOverlaps CV bbox (list path->layerName "pin") depth)) + bbox = nil + unknown = nil + n = 0 + (foreach overlap overlaps + (cond (overlap==path nil) ; ignore self-overlap + ; combine bBox of overlapping paths or rects + ((and (atom overlap) + (or overlap->objType=="path" overlap->objType=="rect")) + bbox = (BBoxCombine bbox overlap->bBox) + n = n+1 + ) + ; combine xy of overlapping contacts + ((and !(atom overlap) (car overlap)->libName==TechLibName) + xy = (car overlap)->xy + bbox = (BBoxCombine bbox (list xy xy)) + n = n+1 + ) + ; subcell pin uses bBox of entire subcell (not optimal) + (!(atom overlap) + bbox = (BBoxCombine bbox (car overlap)->bBox) + n = n+1 + ) + ; unknown overlap disables trimming + (t unknown=t) + ) + ) + + ; trim path to fit inside bbox (bloated by DefaultWiringPitch) + (cond (unknown nil) ; unknown overlaps, leave path alone + ; if one or less overlapping path or contact, delete dangling path + (n<=1 + (dbDeleteObject path) + progress = progress+1 + ) + ; trim path->points to bbox + (bbox + bxy0 = (car bbox) + bxy1 = (cadr bbox) + bx0 = (car bxy0) - overhang + by0 = (cadr bxy0) - overhang + bx1 = (car bxy1) + overhang + by1 = (cadr bxy1) + overhang + nx0 = (min bx1 (max bx0 x0)) + nx1 = (min bx1 (max bx0 x1)) + ny0 = (min by1 (max by0 y0)) + ny1 = (min by1 (max by0 y1)) + (when (or (abs nx0-x0)>=MfgGrid (abs ny0-y0)>=MfgGrid + (abs nx1-x1)>=MfgGrid (abs ny1-y1)>=MfgGrid) + path->points = (list nx0:ny0 nx1:ny1) + progress = progress+1 + ) + ) + ) + ) + progress + ) + ) + + +; find contacts on this net +(defun FindContactsOnNet (net) + (let (contacts) + contacts = nil + (foreach instTerm net->instTerms + (when instTerm->inst->libName==TechLibName + contacts = (cons instTerm->inst contacts)) + ) + (foreach fig net->figs + (when fig->libName==TechLibName + contacts = (cons fig contacts)) + ) + contacts + ) + ) + +; Delete duplicate contacts +(defun TrimDuplicateContacts (net) + (let (contacts duplicates) + ; find contacts on this net + contacts = (FindContactsOnNet net) + + ; delete duplicates + duplicates=nil + (for i 0 (length contacts)-1 + (for j i+1 (length contacts)-1 + (when (AreViasDuplicate (nth i contacts) (nth j contacts)) + duplicates = (cons (nth j contacts) duplicates) + ) + ) + ) + (foreach contact duplicates (dbDeleteObject contact)) + (length duplicates) + ) + ) + +; Delete dangling contacts on a net that don't overlap multiple lpp's +(defun TrimDanglingContacts + (net @key (CV (geGetEditCellView)) (depth 32)) + (let (progress contacts bbox nlayers n overlaps) + progress = 0 + + ; find contacts on this net + contacts = (FindContactsOnNet net) + + ; process contacts + (foreach contact contacts + + ; count overlapping paths or contacts on each layer of the contact + bbox = contact->bBox + nlayers = 0 + (foreach lpp contact->master->lpps + (when (isMetal lpp->layerName) + n = 0 + overlaps = (append (dbGetOverlaps CV bbox (list lpp->layerName "drawing") depth) + (dbGetOverlaps CV bbox (list lpp->layerName "pin") depth)) + (foreach overlap overlaps + (when (or (atom overlap) (car overlap)!=contact) n=1) + ) + nlayers = nlayers + n + ) + ) + + ; delete dangling contact if <=1 different layers have overlaps + (when nlayers<=1 + (dbDeleteObject contact) + progress = progress+1 + ) + ) + progress + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/tech/spacing.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/tech/spacing.il new file mode 100644 index 0000000000..1c7fd6d1fd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/tech/spacing.il @@ -0,0 +1,98 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun SpacingGetSpacingRuleName ( SpacingRule ) + ( car SpacingRule ) ) + +(defun SpacingGetSpacingRuleSpacing ( SpacingRule ) + ( nth 1 SpacingRule ) ) + +(defun SpacingGetSpacingRuleLayers ( SpacingRule ) + (if ( not ( SpacingIsSameLayerSpacingRule SpacingRule ) ) + ( list + ( nth 2 SpacingRule ) + ( nth 3 SpacingRule ) ) + ( list + ( nth 2 SpacingRule ) ) ) ) + +(defun SpacingIsSameLayerSpacingRule ( SpacingRule ) + ( null ( nth 3 SpacingRule ) ) ) + + +(defun SpacingGetSpacingRulesForLayer ( CellView LayerPurposePair RuleName ) + (let ( + ( LayerName ( car LayerPurposePair ) ) + ( PurposeName ( car ( cdr LayerPurposePair ) ) ) + ( TechFileData ( techGetTechFile CellView ) ) ) + (when TechFileData + ( ListApplyFuncToListAndAccumulateNonNilResults + ( techGetSpacingRules TechFileData ) + (lambda + ( Rule LayerName ) + (let ( + ( RuleLayers ( SpacingGetSpacingRuleLayers Rule ) ) ) + (when ( and + ( or + ( and + ( not ( SpacingIsSameLayerSpacingRule Rule ) ) + ( equal LayerName ( car ( cdr RuleLayers ) ) ) ) + ( equal LayerName ( car RuleLayers ) ) ) + ( equal RuleName ( SpacingGetSpacingRuleName Rule ) ) ) + Rule ) ) ) + ( list + LayerName ) ) ) ) ) + + +(defun SpacingGetMinSpacingRulesForLayer ( CellView LayerPurposePair ) + ( SpacingGetSpacingRulesForLayer CellView LayerPurposePair "minSpacing" ) ) + +(defun SpacingGetMinWidthRuleMinWidth ( Rule ) + ( nth 1 Rule ) ) + +(defun SpacingGetMinWidthRuleForLayer ( CellView LayerPurposePair ) + ( car ( SpacingGetSpacingRulesForLayer CellView LayerPurposePair "minWidth" ) ) ) + +(defun SpacingGetMinWidthForLayer ( CellView LayerPurposePair ) + ( SpacingGetMinWidthRuleMinWidth + ( SpacingGetMinWidthRuleForLayer CellView LayerPurposePair ) ) ) + +(defun SpacingGetSameLayerSpacingRuleForLayer ( CellView LayerPurposePair ) + (let ( + ( SpacingRules ( SpacingGetMinSpacingRulesForLayer CellView LayerPurposePair ) ) + ) + ( ListFindElement + SpacingRules + (lambda + ( Rule ) + ( SpacingIsSameLayerSpacingRule Rule ) ) + nil ) ) ) + +(defun SpacingGetSameLayerSpacingForLayer ( CellView LayerPurposePair ) + (let ( + ( Rule ( SpacingGetSameLayerSpacingRuleForLayer CellView LayerPurposePair ) ) ) + (when Rule + ( SpacingGetSpacingRuleSpacing + Rule ) ) ) ) + + +(defun SpacingGetLayerSpacingForLayers ( CellView LPP1 LPP2 ) + ( nth + 1 + ( ListFindElement + ( SpacingGetMinSpacingRulesForLayer + CellView + LPP1 ) + (lambda + ( Rule ) + ( or + ( and + ( equal ( nth 2 Rule ) ( car LPP1 ) ) + ( equal ( nth 3 Rule ) ( car LPP2 ) ) ) + ( and + ( equal ( nth 3 Rule ) ( car LPP1 ) ) + ( equal ( nth 2 Rule ) ( car LPP2 ) ) ) + ) ) + nil ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/transform/transform.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/transform/transform.il new file mode 100644 index 0000000000..90cf4a8a7b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/transform/transform.il @@ -0,0 +1,163 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +;FIXME - should deal with mosaics +; + +; a path is a path through the hierarchy as returned by dbGetOverlaps +; ( I1 ( I2 ( I3 Fig ) ) ) +(defun TransformGetBBoxFromPath ( Path ) + (let ( + ( Stack ( reverse ( TransformCanonicalizeInstancePath Path ) ) ) ) + ( dbTransformBBox + ( getq ( car Stack ) bBox ) + ( TransformGetTransformFromInstanceStack ( cdr Stack ) ) + ) + ) ) + +(defun TransformGetTransformFromInstancePath ( Path ) + ( TransformGetTransformFromInstanceStack + ( reverse ( TransformCanonicalizeInstancePath Path ) ) ) ) + +(defun TransformGetTransformFromInstanceStack ( StackOfInstances ) + (let ( + ( FullTransform ( list 0:0 "R0" ) ) + ) + (while StackOfInstances + (let ( + ( CurrInstance ( car StackOfInstances ) ) ) + ( setq StackOfInstances ( cdr StackOfInstances ) ) + + (let ( + ( Transform + (cond ( + ( listp CurrInstance ) + ( TransformGetMosaicInstTransform + ( car CurrInstance ) + ( cadr CurrInstance ) + ( caddr CurrInstance ) + ) ) + ( + ( getq CurrInstance transform ) ) + ) ) + ) + (cond ( ( equal ( getq CurrInstance objType ) "stdVia" ) + ( setq Transform ( list + ( getq CurrInstance origin ) + ( getq CurrInstance orient ) ) ) ) ) + + ( setq + FullTransform + ( dbConcatTransform + FullTransform + Transform + ) ) + + +) ) ) + FullTransform ) ) + +(defun TransformCanonicalizeInstancePath ( Path ) + (let ( + ( Components + (cond ( + ( listp Path ) + ( ListFlatten Path ) + ) + ( + ( list Path ) ) ) ) + ( Ret nil ) + ) + (while Components + (cond ( + ( and + ( equal ( getq ( car Components ) objType ) "mosaicInst" ) + ( numberp ( cadr Components ) ) + ( numberp ( caddr Components ) ) ) + ( setq Ret ( tconc Ret ( list ( car Components ) + ( caddr Components ) + ( cadr Components ) ) + ) ) + ( setq Components ( cdddr Components ) ) + ) + ( + ( equal ( getq ( car Components ) objType ) "mosaicInst" ) + ( setq Ret ( tconc Ret ( list ( car Components ) + 1 + 1 ) ) ) ) + ( + ( setq Ret ( tconc Ret ( car Components ) ) ) + ( setq Components ( cdr Components ) ) + ) + ) ) + + ( car Ret ) ) ) + + +;convert a instancenamelist +(defun TransformGetInstancePathFromInstanceNamePath + ( CellView + InstanceNamePath ) + ( mapcar + (lambda ( InstanceName ) + (let ( + ( Instance + (if CellView + ( dbFindAnyInstByName + CellView + InstanceName ) ) ) ) + ( setq CellView + ( getq Instance master ) ) + Instance ) ) + InstanceNamePath ) ) + +(defun TransformIsValidInstanceNamePath ( CellView + InstanceNamePath ) + ( not + ( exists + Instance + ( TransformGetInstancePathFromInstanceNamePath + CellView + InstanceNamePath ) + ( null Instance ) ) ) ) + +(defun TransformGetMosaicInstTransform ( MosaicInst I J ) + (let ( + ( Mosaic ( getq MosaicInst mosaic ) ) ) + ( list + ( PointAdd + ( list + ( times I ( getq Mosaic uX ) ) + ( times J ( getq Mosaic uY ) ) ) + ( getq Mosaic xy ) + ) + ( car ( getq Mosaic tileArray ) ) ) ) ) + + +(defun TransformGetInverseTransform ( Transform ) + (let ( + ( Unscaled + ( dbConcatTransform + ( list ( PointDifference 0:0 ( car Transform ) ) + "R0" + 1.0 ) + ( list 0:0 + (cond ( + ( equal ( cadr Transform ) "R90" ) + "R270" ) + ( + ( equal ( cadr Transform ) "R270" ) + "R90" ) + ( + t + ( cadr Transform ) ) ) + 1.0 ) ) ) ) + (if ( caddr Transform ) + ( dbConcatTransform Unscaled + ( list 0:0 + "R0" + ( quotient 1.0 ( caddr Transform ) ) ) ) + Unscaled ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.il new file mode 100644 index 0000000000..cd56e45178 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.il @@ -0,0 +1,1208 @@ +; Support All Orientations +; R0 R90 R180 R270 MY MX MXR90 MYR90 +; +; Symbolic Pins (objType == "inst") have been filtered out +; The script won't do anything +; +; Limitation +; 1. NOT recognize SUBSTRATE pins (eg NWELL Pin) -> won't virtually join them +; 2. Gates MUST have well plugs to begin with +; +; +; Useful Skill +; ------------ +; car( caddr( car( geGetSelectedSet())->instTerms)->term->pins)->fig->objType +; +; +; Global Variables +; ---------------- +; 1. TR_AssuraLVS_VLVS_BlackBoxFile +; 2. TR_AssuraLVS_VLVS_ReplayFile +; 3. TR_AssuraLVS_NetlistPath +; 4. TR_AssuraLVS_DeleteAllTempFiles +; 5. TR_AssuraLVS_VirtualJoinedPinList + + +TR_AssuraLVS_cellName = geGetWindowCellView()->cellName +TR_AssuraLVS_LVSParameterList = list( + "runName" + "runDir" + "technology" +; "extract" +; "compare" +; "bind" +; "rsfInclude" + "layLibrary" + "layCell" + "layView" + "schCellName" + "schNetlists" + "blackBoxCell" +; "runBlackBox" +; "runVirtual" + ) + + +TR_AssuraLVS_VLVS_BlackBoxFile = "./VLVS_BlackBoxFile.txt" +TR_AssuraLVS_VLVS_ReplayFile = "./VLVS_ReplayFile.txt" +TR_AssuraLVS_NetlistPath = ( ConfigFileGetValue TheCDSConfigTable "CDL_DIR" ) +(when TR_AssuraLVS_NetlistPath=="" + TR_AssuraLVS_NetlistPath = "./netlist" +) +TR_AssuraLVS_DeleteAllTempFiles = nil +TR_AssuraLVS_VirtualJoinedPinList = nil + +procedure( DrawPinsLabels( @key + ( Pin list( "drawing" t )) + ( Label list( "drawing" t )) + ( runPartialVirtual nil ) + ( DebugOn nil ) + ) + +let( ( l_d_Selected + x_inst y_inst + xlow_instTerm ylow_instTerm + xhigh_instTerm yhigh_instTerm + xlow_instTerm_new ylow_instTerm_new + xhigh_instTerm_new yhigh_instTerm_new + d_Pin DrawPin PinLayer PinPurpose + d_Label DrawLabel LabelLayer LabelPurpose + d_Net l_Net + bBox_instTerm xy_instTerm + l_BlackBoxCells l_BlackBoxCells_temp Previous_BlackBoxCells + isContinue + lpp lpp_List lpp_Selectable lpp_Visible + pin_Selectable inst_Selectable + ) + + + ; ============================================= + ; Set up the LSW Window to the correct settings + ; ============================================= + pin_Selectable = leIsPinSelectable( ) + inst_Selectable = leIsInstSelectable( ) + + leSetPinSelectable( t ) + leSetInstSelectable( t ) + lpp_List = leGetValidLayerList( techGetTechFile( geGetWindowCellView()) ) + lpp_List = foreach( mapcar lpp lpp_List + + lpp_Selectable = leIsLayerSelectable( lpp ) + lpp_Visible = leIsLayerVisible( lpp ) + + leSetLayerSelectable( lpp t ) + leSetLayerVisible( lpp t ) + + list( lpp lpp_Selectable lpp_Visible ) + + ); end foreach + + + + + + + + isContinue = t + + ; This is the return list containing the netNames that needed to be "joinable" + l_BlackBoxCells = nil + + TR_AssuraLVS_VirtualJoinedPinList = nil + + DrawPin = cadr( Pin ) + DrawLabel = cadr( Label ) + PinPurpose = car( Pin ) + LabelPurpose = car( Label ) + + geSelectAllFig( ) + l_d_Selected = geGetSelectedSet( ) + + ; Getting all the nets in the layout + foreach( d_Selected l_d_Selected + foreach( d_instTerm d_Selected->instTerms + if( !member( d_instTerm->net->name TR_AssuraLVS_VirtualJoinedPinList ) && d_instTerm->net->name != nil + then + TR_AssuraLVS_VirtualJoinedPinList = cons( d_instTerm->net->name TR_AssuraLVS_VirtualJoinedPinList ) + ) + ) + ); end foreach d_Selected l_d_Selected + + if( runPartialVirtual + isContinue = TR_GenerateVirtualJoinedPin( ) + ); end if + + if( isContinue + then + + foreach( d_Selected l_d_Selected + + if( d_Selected->objType == "inst" && d_Selected->viewName != "symbolic" + then + + DebugOn && printf( "DrawPinsLabels --> Start cell \"%s\" \"%s\" \n" d_Selected->cellName d_Selected->name ) + + l_BlackBoxCells = cons( d_Selected->cellName l_BlackBoxCells ) + + x_inst = car( d_Selected->xy ) + y_inst = cadr( d_Selected->xy ) + + + + ; Go thru each instTerms (IO pins) + foreach( d_instTerm d_Selected->instTerms + + DebugOn && printf( "DrawPinsLabels --> --> Start instTerms = %s -> %s \n" d_instTerm->name d_instTerm->net->name ) + + ; Process only if user wants to virtually join the pin + if( member( d_instTerm->net->name TR_AssuraLVS_VirtualJoinedPinList ) + then + + foreach( d_instTermPin d_instTerm->term->pins + + ; Filter out Symbolic Pins + if( d_instTermPin->fig->objType != "inst" + then + + + xlow_instTerm = caar( d_instTermPin->fig->bBox ) + ylow_instTerm = cadar( d_instTermPin->fig->bBox ) + xhigh_instTerm = caadr( d_instTermPin->fig->bBox ) + yhigh_instTerm = cadadr( d_instTermPin->fig->bBox ) + + if( member( d_instTermPin->fig->objType list( "polygon" "path" )) + then + xlow_instTerm = car( car( d_instTermPin->fig->points ) ) - 0.01 + ylow_instTerm = cadr( car( d_instTermPin->fig->points ) ) - 0.01 + xhigh_instTerm = car( car( d_instTermPin->fig->points ) ) + 0.01 + yhigh_instTerm = cadr( car( d_instTermPin->fig->points ) ) + 0.01 + ); end if + + case( d_Selected->orient + + ( "R0" + xlow_instTerm = x_inst + xlow_instTerm + ylow_instTerm = y_inst + ylow_instTerm + xhigh_instTerm = x_inst + xhigh_instTerm + yhigh_instTerm = y_inst + yhigh_instTerm + ) + + ( "R90" + xlow_instTerm_new = x_inst - ylow_instTerm + ylow_instTerm_new = y_inst + xlow_instTerm + xhigh_instTerm_new = x_inst - yhigh_instTerm + yhigh_instTerm_new = y_inst + xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + ( "R180" + xlow_instTerm = x_inst - xlow_instTerm + ylow_instTerm = y_inst - ylow_instTerm + xhigh_instTerm = x_inst - xhigh_instTerm + yhigh_instTerm = y_inst - yhigh_instTerm + + ) + + ( "R270" + xlow_instTerm_new = x_inst + ylow_instTerm + ylow_instTerm_new = y_inst - xlow_instTerm + xhigh_instTerm_new = x_inst + yhigh_instTerm + yhigh_instTerm_new = y_inst - xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + ( "MY" + xlow_instTerm = x_inst - xlow_instTerm + ylow_instTerm = y_inst + ylow_instTerm + xhigh_instTerm = x_inst - xhigh_instTerm + yhigh_instTerm = y_inst + yhigh_instTerm + ) + + ( "MYR90" + xlow_instTerm_new = x_inst - ylow_instTerm + ylow_instTerm_new = y_inst - xlow_instTerm + xhigh_instTerm_new = x_inst - yhigh_instTerm + yhigh_instTerm_new = y_inst - xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + + ( "MX" + xlow_instTerm = x_inst + xlow_instTerm + ylow_instTerm = y_inst - ylow_instTerm + xhigh_instTerm = x_inst + xhigh_instTerm + yhigh_instTerm = y_inst - yhigh_instTerm + ) + + ( "MXR90" + xlow_instTerm_new = x_inst + ylow_instTerm + ylow_instTerm_new = y_inst + xlow_instTerm + xhigh_instTerm_new = x_inst + yhigh_instTerm + yhigh_instTerm_new = y_inst + xhigh_instTerm + + xlow_instTerm = xlow_instTerm_new + ylow_instTerm = ylow_instTerm_new + xhigh_instTerm = xhigh_instTerm_new + yhigh_instTerm = yhigh_instTerm_new + + ) + + ( t + xlow_instTerm = x_inst + xlow_instTerm + ylow_instTerm = y_inst + ylow_instTerm + xhigh_instTerm = x_inst + xhigh_instTerm + yhigh_instTerm = y_inst + yhigh_instTerm + ) + + ); end case + + + bBox_instTerm = list( + xlow_instTerm:ylow_instTerm + xhigh_instTerm:yhigh_instTerm + ) + xy_instTerm = list( + ( xlow_instTerm+xhigh_instTerm )/2 + ( ylow_instTerm+yhigh_instTerm )/2 + ) + if( DrawPin + then + PinLayer = d_instTermPin->fig->layerName + + ; First, draw the pin + d_Pin = dbCreateRect( geGetWindowCellView( ) list( PinLayer PinPurpose ) bBox_instTerm ) + + ; Second, Fill up Connectivity + d_Net = dbMakeNet( geGetWindowCellView() d_instTerm->net->name ) + dbCreatePin( d_Net d_Pin ) + ); end if + + + if( DrawLabel + then + LabelLayer = d_instTermPin->fig->layerName + + d_Label = dbCreateLabel( + geGetWindowCellView( ) + list( LabelLayer LabelPurpose ) + xy_instTerm + sprintf( nil "%s:1" d_instTerm->net->name ) + "centerCenter" + "R0" + "stick" + 0.05 + ) + );end if + + ); end if filter out inst type pins + + );foreach d_instTermPin + + ); end if filter for virtual Pins + + ); foreach instTerm + + DebugOn && printf( "DrawPinsLabels --> Finish Cell \"%s\" \"%s\" \n" d_Selected->cellName d_Selected->name ) + + ); end if + + + + ; Deal with IO pins on the top level + ; Jan 27 2003 + ; Now deals with "path "polygon" and "rect" + ; ========================================= + if( member( d_Selected->objType list( "rect" "path" "polygon")) && + member( d_Selected->net->name TR_AssuraLVS_VirtualJoinedPinList ) + + then + if( member( d_Selected->objType list( "rect" )) + then + bBox_instTerm = d_Selected->bBox + xy_instTerm = car( d_Selected->bBox ) + else + bBox_instTerm = list( + list( + car( car( d_Selected->points ) ) - 0.01 + cadr( car( d_Selected->points ) ) - 0.01 + ) + list( + car( car( d_Selected->points ) ) + 0.01 + cadr( car( d_Selected->points ) ) + 0.01 + ) + ) + xy_instTerm = car( d_Selected->points ) + ); end if + + + if( DrawPin + then + PinLayer = d_Selected->layerName + + ; First, draw the pin + d_Pin = dbCreateRect( geGetWindowCellView( ) list( PinLayer PinPurpose ) bBox_instTerm ) + + ; Second, Fill up Connectivity + d_Net = dbMakeNet( geGetWindowCellView() d_Selected->net->name ) + dbCreatePin( d_Net d_Pin ) + ); end if + + + if( DrawLabel + then + LabelLayer = d_Selected->layerName + + d_Label = dbCreateLabel( + geGetWindowCellView( ) + list( LabelLayer LabelPurpose ) + xy_instTerm + sprintf( nil "%s:1" d_Selected->net->name ) + "centerCenter" + "R0" + "stick" + 0.05 + ) + );end if + + ); end if + + + ); end foreach + + + ; ============================================= + ; Restore the LSW Window to the correct settings + ; ============================================= + leSetPinSelectable( pin_Selectable ) + leSetInstSelectable( inst_Selectable ) + foreach( lpp lpp_List + + leSetLayerSelectable( car(lpp) cadr(lpp) ) + leSetLayerVisible( car(lpp) caddr(lpp) ) + + ); end foreach + + + + + ;===================================================================================================== + ; Removing Duplicate Entries in the BlackBox Cell List + ;===================================================================================================== + + l_BlackBoxCells_temp = sort( l_BlackBoxCells `alphalessp ) + l_BlackBoxCells = cons( car( l_BlackBoxCells_temp ) nil ) + Previous_BlackBoxCells_temp = car( l_BlackBoxCells_temp ) + + foreach( BlackBoxCells_temp l_BlackBoxCells_temp + + if( BlackBoxCells_temp != Previous_BlackBoxCells_temp + then + l_BlackBoxCells = cons( BlackBoxCells_temp l_BlackBoxCells ) + );end if + + Previous_BlackBoxCells_temp = BlackBoxCells_temp + + );end foreach + + println( l_BlackBoxCells ) + + ); end if isContinue + + ;===================================================================================================== + ; Return Value + ;===================================================================================================== + + l_BlackBoxCells + +); end let + +);end procedure + + + +; ============================================================================================================ +; ============================================================================================================ +; This is the procedure that run the Virtual LVS +; This will operate on the current cell you opened +; Requirements +; 1. Netlist located at ./netlist/[cellname].cdl +; 2. You have correct setup for "extract.rul" "compare.rul" "bind.rul" and "switch" +; 3. It always use /scratch/$USER_VLVS as the working directory + + +procedure( AssuraLVS_31( @key ( runVirtual nil ) + ( runBlackBox nil ) + ( runPartialVirtual nil ) + ( VLVSViewName "layout.VLVS" ) + ( DebugOn nil ) + ) + + let( ( l_BlackBoxCells + VLVS_ReplayFile + scratchdir + isContinue) + + + ; Echo Function Call + ; ================== + DebugOn && printf( "AssuraLVS_31 --> AssuraLVS( ?runVirtual %L ?runBlackBox %L ?runPartialVirtual %L ?VLVSViewName %L )\n" + runVirtual + runBlackBox + runPartialVirtual + VLVSViewName ) + + + isContinue = t +; VLVSViewName = "layout.VLVS" + + ; find the proper grid TMP dir if it is set + scratchdir = getShellEnvVar( "TMP" ) + if( ! scratchdir then scratchdir="/scratch" ) + VLVS_runDir = sprintf( nil "%s/%s_VLVS/" scratchdir getShellEnvVar( "USER" )) + Original_viewName = geGetWindowCellView()->viewName + + ; Ripped off unused/unwanted stuff + sh( sprintf( nil "rm -rf %s" VLVS_runDir )) + + ; ================================================================================= + ; Create the VLVS_Layout and run Virtual LVS + ; ================================================================================= + + if( runVirtual + then + ;Backup Current CellView + + geSaveAs( geGetCellViewWindow( geGetWindowCellView( ) ) + geGetWindowCellView( )->libName + geGetWindowCellView( )->cellName + VLVSViewName + ) + + + + geOpen( ?window geGetCellViewWindow( geGetWindowCellView( ) ) + ?lib geGetWindowCellView( )->libName + ?cell geGetWindowCellView( )->cellName + ?view VLVSViewName + ?viewType "maskLayout" + ?mode "a" ) + + + l_BlackBoxCells = DrawPinsLabels( ?runPartialVirtual runPartialVirtual ) + + geSave( ) + + ); end if runVirtual + + + + + ; ================================================================================= + ; Create "lvs..state" File used for LVS + ; ================================================================================= + + TR_AssuraLVS_cellName = geGetWindowCellView( )->cellName + TR_AssuraLVS_Variable_runName = TR_AssuraLVS_cellName + TR_AssuraLVS_Variable_runDir = VLVS_runDir + TR_AssuraLVS_Variable_technology = "Assura_tsmc13lg" + TR_AssuraLVS_Variable_layLibrary = geGetWindowCellView( )->libName + TR_AssuraLVS_Variable_layCell = TR_AssuraLVS_cellName + TR_AssuraLVS_Variable_layView = geGetWindowCellView( )->viewName + TR_AssuraLVS_Variable_schCellName = TR_AssuraLVS_cellName + TR_AssuraLVS_Variable_schNetlists = sprintf( nil "%s/%s.cdl" TR_AssuraLVS_NetlistPath geGetWindowCellView()->cellName ) + TR_AssuraLVS_Variable_blackBoxCell = TR_AssuraLVS_VLVS_BlackBoxFile + + TR_AssuraLVS_ProcGenerateLVSStateFile( ) + + + ; ================================================================================= + ; Deals with Blackboxing + ; ================================================================================= + + if( l_BlackBoxCells && runBlackBox + then + isContinue = TR_GenerateBlackBoxFile( l_BlackBoxCells ) + ) + + + + ; ================================================================================= + ; Create the VLVS_ReplayFile + ; ================================================================================= + + if( l_BlackBoxCells && isContinue + then + + VLVS_ReplayFile = TR_AssuraLVS_VLVS_ReplayFile + + outPort = outfile( VLVS_ReplayFile ) + + fprintf( outPort "deInstallApp(getCurrentWindow() \"Assura\")\n" ) + + fprintf( outPort "vuiLVSRun()\n" ) + fprintf( outPort "hiiSetCurrentForm('vuiLVSForm)\n" ) + + fprintf( outPort "_vuiStateCB( \"LVS\" 'load )\n" ) + fprintf( outPort "hiiSetCurrentForm('vuiLVSstateForm)\n" ) + fprintf( outPort "vuiLVSstateForm->stateList->value = '(\"%s\" )\n" geGetWindowCellView( )->cellName ) + fprintf( outPort "hiFormDone(vuiLVSstateForm)\n" ) + + fprintf( outPort "hiiSetCurrentForm('vuiLVSForm)\n" ) + fprintf( outPort "hiFormDone(vuiLVSForm)\n" ) + + close( outPort ) + + hiReplayFile( TR_AssuraLVS_VLVS_ReplayFile ) + ); end if + + ; ================================================================================= + ; Wait for VLVS Result + ; ================================================================================= + + if( runVirtual && isContinue && l_BlackBoxCells + then + + TR_AssuraLVS_DialogBox = hiDisplayAppDBox( + ?name 'TR_AssuraLVS_DialogBox + ?dboxText "Does your Virtual LVS Pass?" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'YesNo + ) + + + if( TR_AssuraLVS_DialogBox + then + geOpen( ?window geGetCellViewWindow( geGetWindowCellView( ) ) + ?lib geGetWindowCellView( )->libName + ?cell geGetWindowCellView( )->cellName + ?view Original_viewName + ?viewType "maskLayout" + ?mode "a" ) + + ddDeleteLocal( ddGetObj( geGetWindowCellView( )->libName + geGetWindowCellView( )->cellName + VLVSViewName ) ) + + else + println( "Do your own debugging" ) + + );end if + + ); end if runVirtual + + );end let + +); end procedure + +; CC221 +; ==================================================================================================== +; This procedure is used to generate the blackboxed file used for VLVS +; Users are prompted to input "filename" and "cellnames" he/she wanna to blackboxed +; ==================================================================================================== + +procedure( TR_GenerateBlackBoxFile( l_BlackBoxCells @key ( DebugOn nil ) ) + + + let(( + BlackBoxCells + BlackBoxCells_String + ) + + + BlackBoxCells_String = "" + + foreach( BlackBoxCells l_BlackBoxCells + + BlackBoxCells_String = sprintf( nil "%s%s\n" BlackBoxCells_String BlackBoxCells ) + + ); end foreach + + TR_GenerateBlackBoxFile_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateBlackBoxFile_TextWindowField + ?prompt "" + ?defValue BlackBoxCells_String + ) + + TR_GenerateBlackBoxFile_LoadButtonField = hiCreateButton( + ?name `TR_GenerateBlackBoxFile_LoadButtonField + ?buttonText "--LOAD FILE--" + ?callback "TR_GenerateBlackBoxFile_LoadButtonField_CB( hiGetCurrentForm() )" + ) + + TR_GenerateBlackBoxFile_SaveButtonField = hiCreateButton( + ?name `TR_GenerateBlackBoxFile_SaveButtonField + ?buttonText "--SAVE FILE--" + ?callback "TR_GenerateBlackBoxFile_SaveButtonField_CB( hiGetCurrentForm() )" + ) + + TR_GenerateBlackBoxFile_Form = hiCreateAppForm( + ?name 'TR_GenerateBlackBoxFile_Form + ?initialSize list( 600 1000 ) + ?fields list( + list( TR_GenerateBlackBoxFile_TextWindowField 0:0 600:800 0 ) + list( TR_GenerateBlackBoxFile_LoadButtonField 0:800 200:30 0 ) + list( TR_GenerateBlackBoxFile_SaveButtonField 200:800 200:30 0 ) + ) + ?formTitle "" + ) + + hiDisplayForm( TR_GenerateBlackBoxFile_Form ) + + ); end let + +); end procedure + + + +;============= +; LOAD +;============= + +procedure( TR_GenerateBlackBoxFile_LoadButtonField_CB( theForm ) + + ; Local Variables + let(( inPort + BlackBoxCells_String + word + ) + + BlackBoxCells_String = "" + + ; Global Variable + ; TR_AssuraLVS_VLVS_BlackBoxFile + + inPort = infile( TR_AssuraLVS_VLVS_BlackBoxFile ) + + when( inPort + while( fscanf( inPort "%s\n" word ) + BlackBoxCells_String = sprintf( nil "%s%s\n" BlackBoxCells_String word ) + ) + );end when + + close( inPort ) + + theForm->TR_GenerateBlackBoxFile_TextWindowField->value = BlackBoxCells_String + + ); end let + +); end procedure + + +;============= +; SAVE +;============= + +procedure( TR_GenerateBlackBoxFile_SaveButtonField_CB( theForm ) + + ; Local Variables + let(( outPort + BlackBoxCells_String + word + ) + + BlackBoxCells_String = theForm->TR_GenerateBlackBoxFile_TextWindowField->value + + ; Global Variable + ; TR_AssuraLVS_VLVS_BlackBoxFile + + outPort = outfile( TR_AssuraLVS_VLVS_BlackBoxFile ) + + fprintf( outPort "%s" BlackBoxCells_String ) + + close( outPort ) + + ); end let + +); end procedure + + + + + + + + + + + + + + + + + + + + +; ==================================================================================================== +; This procedure is used to generate all the virtual joined pins for VLVS +; Users are prompted to check pins he/she wanna to virtually joined +; ==================================================================================================== +procedure( TR_GenerateVirtualJoinedPin( @key ( DebugOn nil ) ) + + + let(( ; l_Cells_ChoiceString + ; l_Cells_DefaultString + ; Counter + ; NumRows + ) + + ;Global + ;TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinList = sort( TR_AssuraLVS_VirtualJoinedPinList `alphalessp ) + + TR_AssuraLVS_VirtualJoinedPinListString = "" + + foreach( Pin TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinListString = sprintf( nil, "%s%s\n" TR_AssuraLVS_VirtualJoinedPinListString Pin ) + + ); end foreach + + TR_GenerateVirtualJoinedPin_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateVirtualJoinedPin_TextWindowField + ?prompt "" + ?defValue TR_AssuraLVS_VirtualJoinedPinListString + ) + + TR_GenerateVirtualJoinedPin_TextWindowRevertButtonField = hiCreateButton( + ?name `TR_GenerateVirtualJoinedPin_TextWindowRevertButtonField + ?buttonText "Load File" + ?callback "TR_GenerateVirtualJoinedPin_TextWindowRevertButtonField( hiGetCurrentForm() )" + ) + + TR_GenerateVirtualJoinedPin_TextWindowUpdateButtonField = hiCreateButton( + ?name `TR_GenerateVirtualJoinedPin_TextWindowUpdateButtonField + ?buttonText "Save File" + ?callback "TR_GenerateVirtualJoinedPin_TextWindowUpdateButtonField( hiGetCurrentForm() )" + ) + + TR_GenerateVirtualJoinedPin_RemoveNetStringField = hiCreateStringField( + ?name `TR_GenerateVirtualJoinedPin_RemoveNetStringField + ?prompt "" + ?defValue "" + ) + + TR_GenerateVirtualJoinedPin_RemoveNetButtonField = hiCreateButton( + ?name `TR_GenerateVirtualJoinedPin_RemoveNetButtonField + ?buttonText "Remove Net" + ?callback "TR_GenerateVirtualJoinedPin_RemoveNetButtonField( hiGetCurrentForm() )" + ) + + TR_GenerateVirtualJoinedPin_AddNetStringField = hiCreateStringField( + ?name `TR_GenerateVirtualJoinedPin_AddNetStringField + ?prompt "" + ?defValue "" + ) + + TR_GenerateVirtualJoinedPin_AddNetButtonField = hiCreateButton( + ?name `TR_GenerateVirtualJoinedPin_AddNetButtonField + ?buttonText "Add Net" + ?callback "TR_GenerateVirtualJoinedPin_AddNetButtonField( hiGetCurrentForm() )" + ) + + + TR_GenerateVirtualJoinedPin_Form = hiCreateAppForm( + ?name 'TR_GenerateVirtualJoinedPin_Form + ?initialSize list( 600 1000 ) + ?fields list( + list( TR_GenerateVirtualJoinedPin_TextWindowField 0:0 600:600 0 ) + + list( TR_GenerateVirtualJoinedPin_TextWindowRevertButtonField 0:600 300:30 0 ) + list( TR_GenerateVirtualJoinedPin_TextWindowUpdateButtonField 300:600 300:30 0 ) + + + list( TR_GenerateVirtualJoinedPin_RemoveNetStringField 0:630 200:30 0 ) + list( TR_GenerateVirtualJoinedPin_RemoveNetButtonField 200:630 100:30 0 ) + list( TR_GenerateVirtualJoinedPin_AddNetStringField 300:630 200:30 0 ) + list( TR_GenerateVirtualJoinedPin_AddNetButtonField 500:630 100:30 0 ) + ) + ) + + hiDisplayForm( TR_GenerateVirtualJoinedPin_Form ) + + ); end let + +); end procedure + + +procedure( TR_GenerateVirtualJoinedPin_RemoveNetButtonField( theForm ) + + + TR_AssuraLVS_VirtualJoinedPinList = setof( x + TR_AssuraLVS_VirtualJoinedPinList + x != theForm->TR_GenerateVirtualJoinedPin_RemoveNetStringField->value + ) + + TR_AssuraLVS_VirtualJoinedPinListString = "" + + foreach( Pin TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinListString = sprintf( nil, "%s%s\n" TR_AssuraLVS_VirtualJoinedPinListString Pin ) + + ); end foreach + + hiDeleteField( theForm `TR_GenerateVirtualJoinedPin_TextWindowField ) + + TR_GenerateVirtualJoinedPin_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateVirtualJoinedPin_TextWindowField + ?prompt "" + ?defValue TR_AssuraLVS_VirtualJoinedPinListString + ) + + hiAddField( theForm list( TR_GenerateVirtualJoinedPin_TextWindowField 0:0 600:600 0 )) + +); end procedure + + +procedure( TR_GenerateVirtualJoinedPin_AddNetButtonField( theForm ) + + if( !member( theForm->TR_GenerateVirtualJoinedPin_AddNetStringField->value TR_AssuraLVS_VirtualJoinedPinList ) + then + + TR_AssuraLVS_VirtualJoinedPinList = cons( theForm->TR_GenerateVirtualJoinedPin_AddNetStringField->value + TR_AssuraLVS_VirtualJoinedPinList + ) + + + ); end if + + TR_AssuraLVS_VirtualJoinedPinList = sort( TR_AssuraLVS_VirtualJoinedPinList `alphalessp ) + + TR_AssuraLVS_VirtualJoinedPinListString = "" + + foreach( Pin TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinListString = sprintf( nil, "%s%s\n" TR_AssuraLVS_VirtualJoinedPinListString Pin ) + + ); end foreach + + hiDeleteField( theForm `TR_GenerateVirtualJoinedPin_TextWindowField ) + + TR_GenerateVirtualJoinedPin_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateVirtualJoinedPin_TextWindowField + ?prompt "" + ?defValue TR_AssuraLVS_VirtualJoinedPinListString + ) + + hiAddField( theForm list( TR_GenerateVirtualJoinedPin_TextWindowField 0:0 600:600 0 )) + +); end procedure + + +procedure( TR_GenerateVirtualJoinedPin_TextWindowRevertButtonField( theForm ) + + TR_AssuraLVS_VirtualJoinedPinListString = "" + + foreach( Pin TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinListString = sprintf( nil, "%s%s\n" TR_AssuraLVS_VirtualJoinedPinListString Pin ) + + ); end foreach + + hiDeleteField( theForm `TR_GenerateVirtualJoinedPin_TextWindowField ) + + TR_GenerateVirtualJoinedPin_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateVirtualJoinedPin_TextWindowField + ?prompt "" + ?defValue TR_AssuraLVS_VirtualJoinedPinListString + ) + + hiAddField( theForm list( TR_GenerateVirtualJoinedPin_TextWindowField 0:0 600:600 0 )) + +); end procedure + +procedure( TR_GenerateVirtualJoinedPin_TextWindowUpdateButtonField( theForm ) + + TR_AssuraLVS_VirtualJoinedPinList = parseString( theForm->TR_GenerateVirtualJoinedPin_TextWindowField->value "\n" ) + + TR_AssuraLVS_VirtualJoinedPinList = sort( TR_AssuraLVS_VirtualJoinedPinList `alphalessp ) + + TR_AssuraLVS_VirtualJoinedPinListString = "" + + foreach( Pin TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinListString = sprintf( nil, "%s%s\n" TR_AssuraLVS_VirtualJoinedPinListString Pin ) + + ); end foreach + + hiDeleteField( theForm `TR_GenerateVirtualJoinedPin_TextWindowField ) + + TR_GenerateVirtualJoinedPin_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateVirtualJoinedPin_TextWindowField + ?prompt "" + ?defValue TR_AssuraLVS_VirtualJoinedPinListString + ) + + hiAddField( theForm list( TR_GenerateVirtualJoinedPin_TextWindowField 0:0 600:600 0 )) + +); end procedure + + +procedure( TR_GenerateVirtualJoinedPin_TextWindowUpdateButtonField( theForm ) + + let(( outPort + inPort + VLVS_PinFile + word + ) +; drain() + + VLVS_PinFile = "VLVS_PinFile.txt" + + + outPort = outfile( VLVS_PinFile ) + + fprintf( outPort theForm->TR_GenerateVirtualJoinedPin_TextWindowField->value ) + + close( outPort ) + + + TR_AssuraLVS_VirtualJoinedPinList = nil + + inPort = infile( VLVS_PinFile ) + + when( inPort + while( fscanf( inPort "%s\n" word ) + TR_AssuraLVS_VirtualJoinedPinList = cons( word TR_AssuraLVS_VirtualJoinedPinList ) + ) + );end when + + close( inPort ) + + + + + + + ; DUMB stuff + + TR_AssuraLVS_VirtualJoinedPinList = sort( TR_AssuraLVS_VirtualJoinedPinList `alphalessp ) + + TR_AssuraLVS_VirtualJoinedPinListString = "" + + foreach( Pin TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinListString = sprintf( nil, "%s%s\n" TR_AssuraLVS_VirtualJoinedPinListString Pin ) + + ); end foreach + + hiDeleteField( theForm `TR_GenerateVirtualJoinedPin_TextWindowField ) + + TR_GenerateVirtualJoinedPin_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateVirtualJoinedPin_TextWindowField + ?prompt "" + ?defValue TR_AssuraLVS_VirtualJoinedPinListString + ) + + hiAddField( theForm list( TR_GenerateVirtualJoinedPin_TextWindowField 0:0 600:600 0 )) + + + + ); end let + +); end procedure + + + +procedure( TR_GenerateVirtualJoinedPin_TextWindowRevertButtonField( theForm ) + + let(( outPort + inPort + VLVS_PinFile + word + ) + + VLVS_PinFile = "VLVS_PinFile.txt" + + TR_AssuraLVS_VirtualJoinedPinList = nil + +; drain() + + inPort = infile( VLVS_PinFile ) + + when( inPort + while( fscanf( inPort "%s\n" word ) + TR_AssuraLVS_VirtualJoinedPinList = cons( word TR_AssuraLVS_VirtualJoinedPinList ) + ) + );end when + + close( inPort ) + + + + ; DUMB stuff + + TR_AssuraLVS_VirtualJoinedPinList = sort( TR_AssuraLVS_VirtualJoinedPinList `alphalessp ) + + TR_AssuraLVS_VirtualJoinedPinListString = "" + + foreach( Pin TR_AssuraLVS_VirtualJoinedPinList + + TR_AssuraLVS_VirtualJoinedPinListString = sprintf( nil, "%s%s\n" TR_AssuraLVS_VirtualJoinedPinListString Pin ) + + ); end foreach + + hiDeleteField( theForm `TR_GenerateVirtualJoinedPin_TextWindowField ) + + TR_GenerateVirtualJoinedPin_TextWindowField = hiCreateMLTextField( + ?name `TR_GenerateVirtualJoinedPin_TextWindowField + ?prompt "" + ?defValue TR_AssuraLVS_VirtualJoinedPinListString + ) + + hiAddField( theForm list( TR_GenerateVirtualJoinedPin_TextWindowField 0:0 600:600 0 )) + + + + ); end let + +); end procedure + + + +; ==================================================================================================== +; This procedure is used to generate the "lvs..state" used by the LVS GUI +; ==================================================================================================== +procedure( TR_AssuraLVS_ProcGenerateLVSStateFile( @key ( DebugOn nil ) + ( AssuraVersion 3.1 ) + ) + + let(( + outPort + inPort + line + LVSParameter + ) + + outPort = outfile( sprintf( nil ".lvs.%s.state" TR_AssuraLVS_cellName )) +; inPort = infile( "/home/user/stevemc/cadence/skill/TR_AssuraLVS.lvs.state" ) + inPort = infile( sprintf( nil "%s/share/skill/layout/vlvs/vlvs.state.template" PackageGetPackageRoot() ) ) + + when( inPort + while( gets( line inPort ) + + + rexCompile( "\\$\\$" ) + + if( rexExecute( line ) + then + foreach( LVSParameter TR_AssuraLVS_LVSParameterList + + DebugOn && printf( "TR_AssuraLVS_ProcGenerateLVSStateFile --> Matching Variable \"$$%s\"\n" LVSParameter ) + rexCompile( sprintf( nil "\\$\\$%s" LVSParameter )) + + if( rexExecute( line ) + then + DebugOn && printf( "TR_AssuraLVS_ProcGenerateLVSStateFile --> --> \"$$%s\" Matched\n" LVSParameter ) + line = rexReplace( line evalstring( sprintf( nil "TR_AssuraLVS_Variable_%s" LVSParameter )) 0) + else + DebugOn && printf( "TR_AssuraLVS_ProcGenerateLVSStateFile --> --> \"$$%s\" Failed Matching\n" LVSParameter ) + ); end if + + ); end foreach + ); end if + + fprintf( outPort "%s" line ) + + + ); end while + );end when + + close( inPort ) + close( outPort ) + + ); end let + +); end procedure + + + + + + + + + + + +; ==================================================================================================== +; This procedure is the main setup screen +; ==================================================================================================== + +procedure( TR_AssuraLVS( ) + + let( ( TR_GenerateBlackBoxFile_FilenameField + + ) + + TR_AssuraLVS_NetlistField = hiCreateStringField( + ?name 'TR_AssuraLVS_NetlistField + ?prompt "Default Netlist Path" + ?defValue TR_AssuraLVS_NetlistPath + ?enabled t + ) + + TR_GenerateBlackBoxFile_FilenameField = hiCreateStringField( + ?name 'TR_GenerateBlackBoxFile_FilenameField + ?prompt "Enter Filename for Blackboxing" + ?defValue TR_AssuraLVS_VLVS_BlackBoxFile + ?enabled t + ) + + TR_AssuraLVS_VLVSViewNameField = hiCreateStringField( + ?name 'TR_AssuraLVS_VLVSViewNameField + ?prompt "Enter ViewName for VLVS" + ?defValue "layout.VLVS" + ) + TR_AssuraLVS_StartVLVS_31 = hiCreateButton( + ?name 'TR_AssuraLVS_StartVLVS_31 + ?buttonText "Assura VLVS 3.1" + ?callback "AssuraLVS_31( ?runVirtual t + ?runBlackBox t + ?runPartialVirtual t + ?VLVSViewName TR_AssuraLVS_VLVSViewNameField->value)" + ) + + TR_AssuraLVS_Separator1 = hiCreateSeparatorField( + ?name `TR_AssuraLVS_Separator1 + ) + + TR_AssuraLVS_Form = hiCreateAppForm( + ?name 'TR_AssuraLVS_Form + ?initialSize list( 1000 600 ) + ?fields list( + list( TR_AssuraLVS_NetlistField 0:0 600:30 200 ) + list( TR_GenerateBlackBoxFile_FilenameField 0:30 600:30 200 ) + list( TR_AssuraLVS_VLVSViewNameField 0:60 600:30 200 ) + list( TR_AssuraLVS_Separator1 0:94 600:0 0 ) + + list( TR_AssuraLVS_StartVLVS_31 0:100 300:30 0 ) + + ) + ?formTitle "Cadence Assura Fulcrum Interface" + ) + + hiDisplayForm( TR_AssuraLVS_Form ) + + ); end let + +); end procedure + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.state.template b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.state.template new file mode 100644 index 0000000000..2e8abfbb76 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/layout/vlvs/vlvs.state.template @@ -0,0 +1,957 @@ +;---------------------------------------------------------------------------- +; @(#)$CDS: assura version av3.1:Production:dfII5.0.0 01/09/2004 14:40 (sjpvlin1) $ +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; Assura 3.1 LVS saved state +;---------------------------------------------------------------------------- + + + +vuiLVSFormTable = '( + schematicSource "Netlist" + layoutSource "DFII" + runName "$$runName" + runDir "$$runDir" + machineLoc "local" + viewRules t + technologyField "$$technology" + layLibrary "$$layLibrary" + layCell "$$layCell" + layView "$$layView" + schCellName "$$schCellName" + schNetlists ("cdl :: $$schNetlists") + blackBoxCell "$$blackBoxCell" + runBlackBox "$$runBlackBox" + runVirtual "$$runVirtual" + runsetField "default" + varTag "None" + varVal "" + varDefVal "" + varDesc "" + avView nil + avCompareView nil + additionalFunctionsButton nil + layUseExistingNL nil + extractButton nil + compareButton nil + bindButton nil + rsfIncludeButton nil + +) + + + +vuiLVSFormVarTable = '( +) + + +additionalFunctionsFieldsTable = '( + AFflattenCellFlag nil + AFjoinableNetsFlag nil + AFoutFileFlag nil + AFchangeLabelFlag nil + AFmustJoinNetFlag nil + AFdeleteCellTextFlag nil +) + + +vuiLVSFormAdditionalFunctionsTable = '( + flattenCell nil + joinableNets nil + changeLabel nil + mustJoinNet nil + outFile nil + deleteCellText nil +) + + + +vuiLVSschNLoptionFormTable = '( + viewList "auLvs schematic symbol" + stopList "auLvs" + deviceInformation "" + avSimName "" + avMFactorPropName "" + ignoreNamePrefix (nil) + avErrorOnMissingMaster (nil) + avUseModelPropOnInstance (nil) + netlistCyclic "CDL" + netlistFileHolding "" + netlistFile nil + deviceInformationButton nil +) + + +;---------------------------------------------------------------------------- +; @(#)$CDS: assura version av3.1:Production:dfII5.0.0 01/09/2004 14:40 (sjpvlin1) $ +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; Assura 3.1 Template Version 1 +;---------------------------------------------------------------------------- + +vuiLVSOptions = '( + (( ?autoGrid ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( disableGridding nil ) + ( keepGridCells nil ) + ( autoGrid nil ) + ( cells nil ) + ( excludeCells nil ) + ( layers nil ) + ) + (( ?avrpt ) + ( "view" t ) + ( "edit" t ) + ( "use" t ) + ( avrpt t ) + ( spacer nil ) + ( spacer2 nil ) + ( useOption nil ) + ( maxErrorShapesPerCell 1000 ) + ) + (( ?blackBoxCell ) + ( "view" t ) + ( "edit" t ) + ( "use" t ) + ( label nil ) + ( standardCell nil ) + ( blackBoxCell "File" ) + ( blackBoxCellList nil ) + ( blackBoxCellFile "$$blackBoxCell" ) + ) + (( ?compileOnly ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( compileOnly nil ) + ) + (( ?dbuPerUU ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( dbuPerUU 1000 ) + ) + (( ?diskList ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( dir nil ) + ( diskList nil ) + ) + (( ?dspfCells ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( source nil ) + ( fileName nil ) + ) + (( ?expandCellToParent ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( areaPercent (51 999) ) + ( cells nil ) + ( excludeCells nil ) + ) + (( ?expandCellToTop ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( areaPercent (51 999) ) + ( cells nil ) + ( excludeCells nil ) + ) + (( ?expandUniqueCells ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( expandUniqueCells nil ) + ) + (( ?flagAcuteAngle ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( flag nil ) + ) + (( ?flagMalformed ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( flag nil ) + ) + (( ?flagNon45 ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( flag nil ) + ) + (( ?flagOffGrid ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( gridSize 0.25 ) + ( markerSize 1.0 ) + ) + (( ?flagUnconnectedVias ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( flagUnconnectedVias nil ) + ) + (( ?flattenCellContents ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( flattenCellContents nil ) + ( label nil ) + ( cell nil ) + ( file nil ) + ) + (( ?gateArray ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( siteCells nil ) + ( personality nil ) + ( personalityLayer nil ) + ( personalityCell nil ) + ( label nil ) + ( label2 nil ) + ( excludeScell nil ) + ( excludePcell nil ) + ) + (( ?ignoreCell ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( ignoreCell nil ) + ( ignoreCellFile nil ) + ) + (( ?ignoreGetAngledEdgeDifference ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( ignoreGetAngledEdgeDifference t ) + ) + (( ?joinPins ) + ( "view" t ) + ( "edit" t ) + ( "use" t ) + ( joinPins "Top" ) + ) + (( ?keepData ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( keepData nil ) + ) + (( ?keepOriginal ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( keepOriginal nil ) + ) + (( ?labelPriority ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( textLabel nil ) + ( ignoreLabelType nil ) + ) + (( ?multiCPU ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( mode nil ) + ( multiCPU nil ) + ( number 1 ) + ( slaves 1 ) + ( subtasks 1 ) + ( memsize 0 ) + ) + (( ?netTextFile ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( netText nil ) + ) + (( ?outputErrorLib ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( outputErrorLib nil ) + ( modifyExistingLibrary nil ) + ) + (( ?overwrite ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( overwrite t ) + ) + (( ?pinTextFile ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( pinText nil ) + ) + (( ?preserveCells ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( preserveCellsFile nil ) + ) + (( ?rcxFile ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( rcxFile nil ) + ) + (( ?resolution ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( resolution 1.0 ) + ) + (( ?rom ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( romBlockName nil ) + ( romBitName nil ) + ) + (( ?saveByRule ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( saveByRule nil ) + ) + (( ?standardCell ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( standardCell nil ) + ( standardCellList nil ) + ( standardCellFile nil ) + ) + (( ?simInfo ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( simInfo nil ) + ) + (( ?simInfoUseDevName ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( simInfoUseDevName nil ) + ) + (( ?textLevel ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( from 0 ) + ( to 0 ) + ) + (( ?textPriOnly ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( textPriOnly nil ) + ) + (( ?time ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( time nil ) + ) + (( ?treatFourthTerminalAsBulk ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( treatFourthTerminalAsBulk t ) + ) + (( ?userUnits ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( userUnits nil ) + ) + (( ?useRsfOutLayer ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( useRsfOutLayer nil ) + ) + (( ?verbose ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( verbose nil ) + ) + (( ?warnIgnoredFlattenedLabel ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( warnIgnoredFlattenedLabel nil ) + ) +) + +;---------------------------------------------------------------------------- +; @(#)$CDS: assura version av3.1:Production:dfII5.0.0 01/09/2004 14:40 (sjpvlin1) $ +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; Assura 3.1 Template Version 1 +;---------------------------------------------------------------------------- + +vuiAVCGenOptions = '( + (( abortOnUnboundDevices ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( abortOnUnboundDevices t ) + ) + (( alwaysContinue ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( alwaysContinue nil ) + ) + (( autoPinSwap ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( autoPinSwap t ) + ( thresholdValue 1000 ) + ( cell nil ) + ( selectSubCells nil ) + ( unBoundPinsOnly nil ) + ( autoPinSwapListBox nil ) + ) + (( bindVariants ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( bindVariants t ) + ) + (( blackBox ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( blackBox nil ) + ) + (( combineTolerance ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( combineTolerance nil ) + ) + (( compareParameter ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( compareParameter nil ) + ) + (( defineDerivedInstances ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( defineDerivedInstances nil ) + ) + (( dramReduce ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( dramReduce nil ) + ) + (( echoUsedAvCompareRules ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( echoUsedAvCompareRules nil ) + ) + (( enableDeviceFixing ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( enableDeviceFixing nil ) + ) + (( enableRewire ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( enableRewire t ) + ) + (( expandOnError ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( enableSwap nil ) + ( enableReduce nil ) + ( enablePins nil ) + ( enableMatch nil ) + ( enableSwapThres nil ) + ( instCount t ) + ( skipMatchOnReduceError t ) + ( ambiguousPinAssignment nil ) + ( parameter nil ) + ) + (( filter ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( filter nil ) + ) + (( filterLDDasMOS ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( filterLDDasMOS nil ) + ) + (( filterReduceStatistics ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( filterReduceStatistics t ) + ) + (( filterReduceLoop ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( filterReduceLoop nil ) + ) + (( formGate ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( formGate nil ) + ( mos nil ) + ( cells nil ) + ( devicename nil ) + ( noldd nil ) + ( formGateListBox nil ) + ) + (( groupModels ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( deviceType nil ) + ( groupModelsListBox nil ) + ) + (( keepSeriesLoop ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( keepSeriesLoop nil ) + ) + (( lineLimit ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( lineLimit 20000 ) + ) + (( listFilteredDevices ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( listFilteredDevices nil ) + ) + (( listXRef ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( listXRef nil ) + ) + (( mergeParallel ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( mergeParallel nil ) + ) + (( mergeSeries ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( mergeSeries nil ) + ) + (( mergeSplitGate ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( mode nil ) + ( deviceName nil ) + ( deviceType nil ) + ( mergeSplitGate nil ) + ( mergeSplitGateListBox nil ) + ) + (( nameBinding ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( bindCell t ) + ( bindNet nil ) + ( bindInstance nil ) + ( bindPin "t" ) + ) + (( nameBindingOptions ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( nameBindingOptions nil ) + ) + (( nameBindingStyle ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( nameBindingStyle "cellName" ) + ) + (( parameterModifiedDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( parameterModifiedDevice nil ) + ) + (( romReduce ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( romReduce nil ) + ) + (( rootCell ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( rootCell nil ) + ) + (( runName ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( runName nil ) + ) + (( sectionLineLimit ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( sectionLineLimit 1000 ) + ) + (( showErrorNetwork ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( showErrorNetwork nil ) + ) + (( showTree ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( showTree "none" ) + ) + (( simpleAutoPinSwap ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( simpleAutoPinSwap nil ) + ) + (( smartCaseForAutoBind ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( bindCell t ) + ( bindPin t ) + ( bindNet t ) + ( bindInstance t ) + ) + (( sramReduce ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( sramReduce nil ) + ) + (( unmatchedNetDetail ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( unmatchedNetDetail nil ) + ) + (( verifyTopLayPins ) + ( "view" t ) + ( "edit" t ) + ( "use" t ) + ( verifyTopLayPins nil ) + ( floatingPins nil ) + ) + (( verifyTopSchPins ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( verifyTopSchPins t ) + ( floatingPins nil ) + ) +) + +;---------------------------------------------------------------------------- +; @(#)$CDS: assura version av3.1:Production:dfII5.0.0 01/09/2004 14:40 (sjpvlin1) $ +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; Assura 3.1 Template Version 1 +;---------------------------------------------------------------------------- + +vuiAVCLayOptions = '( + (( bjtDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( bjtDevice nil ) + ) + (( capDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( capDevice nil ) + ) + (( cdlGlobalMode ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( cdlGlobalMode nil ) + ) + (( defaultParameter ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( defaultParameter nil ) + ) + (( deleteCellPin ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( deleteCellPin nil ) + ) + (( dioDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( dioDevice nil ) + ) + (( filterDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( filterDevice nil ) + ) + (( filterOptions ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( filterOptions nil ) + ) + (( fixDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( cell nil ) + ( inst nil ) + ( pins nil ) + ( fixDeviceListBox nil ) + ) + (( genericDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( genericDevice nil ) + ) + (( ignoreCell ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( ignoreCell nil ) + ( ignoreCellFile nil ) + ) + (( joinNets ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( joinNets nil ) + ) + (( lddDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( lddDevice nil ) + ) + (( mosDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( mosDevice nil ) + ) + (( resDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( resDevice nil ) + ) + (( setGround ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( setGround nil ) + ) + (( setPower ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( setPower nil ) + ) + (( swapPins ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( swapPins nil ) + ) +) + +;---------------------------------------------------------------------------- +; @(#)$CDS: assura version av3.1:Production:dfII5.0.0 01/09/2004 14:40 (sjpvlin1) $ +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; Assura 3.1 Template Version 1 +;---------------------------------------------------------------------------- + +vuiAVCSchOptions = '( + (( bjtDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( bjtDevice ("" "" "" "nil" "") ) + ) + (( capDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( capDevice ("" "" "" "nil" "") ) + ) + (( cdlGlobalMode ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( cdlGlobalMode nil ) + ) + (( defaultParameter ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( defaultParameter nil ) + ) + (( deleteCellPin ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( deleteCellPin nil ) + ) + (( dioDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( dioDevice ("" "" "" "nil" "") ) + ) + (( filterDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( filterDevice "" ) + ) + (( filterOptions ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( filterOptions nil ) + ) + (( fixDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( cell nil ) + ( inst nil ) + ( pins nil ) + ( fixDeviceListBox nil ) + ) + (( genericDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( genericDevice nil ) + ) + (( ignoreCell ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( label nil ) + ( ignoreCell nil ) + ( ignoreCellFile nil ) + ) + (( joinNets ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( joinNets nil ) + ) + (( lddDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( lddDevice ("" "" "" "" "" "" "" "") ) + ) + (( mosDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( mosDevice nil ) + ) + (( resDevice ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( resDevice ("" "" "" "nil" "") ) + ) + (( setGround ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( setGround nil ) + ) + (( setPower ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( setPower nil ) + ) + (( swapPins ) + ( "view" t ) + ( "edit" t ) + ( "use" nil ) + ( swapPins nil ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/cellview.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/cellview.il new file mode 100644 index 0000000000..2cb865a8a2 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/cellview.il @@ -0,0 +1,115 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( nrOpenCellViewReadable (libName cellName viewName) + let( (ViewDDObj CellView) + ViewDDObj=ddGetObj( libName cellName viewName ) + if( and( + ViewDDObj + ddIsObjReadable( ViewDDObj ) + car( ViewDDObj~>files ) + ddIsObjReadable( car( ViewDDObj~>files ) )) then + CellView=dbOpenCellViewByType( + libName + cellName + viewName + "maskLayout" + "r" ) + else CellView=nil + ) + CellView + ) +) + +defun( nrOpenCellViewWritable (libName cellName viewName + @key + (mode "a") + ) + let( (ViewDDObj CellView) + ViewDDObj=ddGetObj( libName cellName viewName ) + if( !ViewDDObj || and( + ViewDDObj + ddIsObjWritable( ViewDDObj ) + car( ViewDDObj~>files ) + ddIsObjWritable( car( ViewDDObj~>files ) )) then + CellView=dbOpenCellViewByType( + libName + cellName + viewName + "maskLayout" + mode ) + else CellView=nil + ) + CellView + ) +) + +defun( nrIsCellViewWritable (CellView) + let( (ViewDDObj writable filename) + writable=nil + (when CellView + ViewDDObj=ddGetObj( CellView->libName CellView->cellName CellView->viewName ) + filename = strcat( "/" + buildString( reverse( cddr( reverse( parseString( CellView~>fileName "/")))) "/") + "/" CellView->viewName "/layout.cdb") + writable=and( ddIsObjWritable(ViewDDObj) ddIsObjWritable(car(ViewDDObj->files)) isWritable(filename) ) + ) + writable + ) +) + + +defun( nrOpenCellViewReadableByName (cellName viewName) + let( (ViewDDObj CellView libstr libName) + libstr=reverse( cddr( reverse(parseString(cellName ".")))) + libName=car(libstr) + libstr=cdr(libstr) + foreach( str libstr + libName=strcat(libName "." str) + ) + ViewDDObj=ddGetObj( libName cellName viewName ) + if( and( + ViewDDObj + ddIsObjReadable( ViewDDObj ) + car( ViewDDObj~>files ) + ddIsObjReadable( car( ViewDDObj~>files ) )) then + CellView=dbOpenCellViewByType( + libName + cellName + viewName + "maskLayout" + "r" ) + else CellView=nil + ) + CellView + ) +) + +defun( nrOpenCellViewWritableByName (cellName viewName) + let( (ViewDDObj CellView libstr libName) + libstr=reverse( cddr( reverse(parseString(cellName ".")))) + libName=car(libstr) + libstr=cdr(libstr) + foreach( str libstr + libName=strcat(libName "." str) + ) + ViewDDObj=ddGetObj( libName cellName viewName ) + if( !ViewDDObj || and( + ViewDDObj + ddIsObjWritable( ViewDDObj ) + car( ViewDDObj~>files ) + ddIsObjWritable( car( ViewDDObj~>files ) )) then + CellView=dbOpenCellViewByType( + libName + cellName + viewName + "maskLayout" + "a" ) + else CellView=nil + ) + CellView + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/flatten.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/flatten.il new file mode 100644 index 0000000000..b6d8edbd09 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/flatten.il @@ -0,0 +1,318 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +defun( nrFlattenView ( CellView flattenViewName + powerCellName + powerViewName + celllist_filename + @key + ( OBSCellName "" ) + ( OBSViewName "layout" ) + ( BusWireCellName "" ) + ( BusWireViewName "layout" ) + ( Verbose nil ) + ( DeleteWires t ) + ( DeleteObs t ) + ( RegenerateFromCast nil ) + ( CheckAlignment t ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ) + let((FlattenView FlattenViewTemp temp instances uniqueInstances routedDirectiveList + prbounds ignore_align ignore_prbound ignore_routed floorplans prelayouts pout) + + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + + ;check if this cell is actually supposed to be routed + ignore_routed=t + (when !(nrIsRoutedCell CellView->libName CellView->cellName CellView->viewName) + ignore_routed = hiDisplayAppDBox( + ?name 'RoutedErrorDialogBox + ?dboxText "The current cell is not set to be routed.\nDo you want to proceed anyway?" + ?dboxBanner "Routed Directive Error" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'YesNo + ?defaultButton 2 + ) + ) + (when ignore_routed + ;continue + + ;check if subcells are aligned + ignore_align=t + when( CheckAlignment + when( CheckRoutedAlignment(CellView) + ignore_align = hiDisplayAppDBox( + ?name 'FlattenErrorDialogBox + ?dboxText "One or more cells are misaligned.\nDo you want to proceed anyway?" + ?dboxBanner "Alignment Errors" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'YesNo + ?defaultButton 2 + ) + )) + + when( ignore_align + ; do the rest of the steps + + ;look for prbound + ignore_prbound=t + when( !GetPrbound(CellView) + ignore_prbound = hiDisplayAppDBox( + ?name 'PrboundErrorDialogBox + ?dboxText "No top-level prbound present.\nThis is likely to make the power grid abstract incorrect.\nDo you want to proceed anyway?" + ?dboxBanner "No Prbound" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'YesNo + ?defaultButton 2 + ) + ) + + when( ignore_prbound + ; do the rest of the steps + + + FlattenView= dbCopyCellView( CellView CellView~>libName CellView~>cellName flattenViewName nil nil t) + dbSave( FlattenView ) + instances = t + routedDirectiveList=nrCastQuery( FlattenView ?RegenerateFromCast RegenerateFromCast ?MaxHeapSize MaxHeapSize) + + while( instances != nil + instances= setof( inst FlattenView~>instances inst->libName!=TechLibName) + instances= car( NameFilterInstances( instances LibCellsToIgnore )) + instances= setof( inst instances + !nrIsRoutedCell( inst~>libName + inst~>cellName + inst~>viewName + ?routedDirectiveList routedDirectiveList + ?RegenerateFromCast RegenerateFromCast + ?Verbose Verbose + ?MaxHeapSize MaxHeapSize + ) + ) + if( instances then + println( foreach( mapcar inst instances inst~>cellName )) + InlineInstances( FlattenView + FlattenView + instances + CellView~>viewName + nil + nil + nil + ?CopyPins nil + ?Verbose nil + ?CopyFigs t + ) + ) + + ; merge any flattened prbounds + prbounds = nil + foreach( shape FlattenView~>shapes + when( car(shape->lpp)=="prBoundary" + prbounds = cons( shape prbounds ) + ) + ) + leMergeShapes( prbounds ) + + dbSave( FlattenView ) + ) + if(DeleteWires then + if( Verbose printf("Deleting existing wirings...\n")) + instances= setof( inst FlattenView~>instances inst->libName!=TechLibName) + instances= setof( inst cadr( NameFilterInstances( instances WiringCellLibCellPairRegExs )) inst~>cellName!=powerCellName) + if( instances then + if( Verbose then printf("Deleting wiring instances:") println( instances~>cellName )) + foreach( inst instances dbDeleteObject( inst ) ) + ) + nrDeleteLayers( FlattenView Metal1LPP ) + nrDeleteLayers( FlattenView Metal2LPP ) + nrDeleteLayers( FlattenView Metal3LPP ) + nrDeleteLayers( FlattenView Metal4LPP ) + nrDeleteLayers( FlattenView Metal5LPP ) + nrDeleteLayers( FlattenView Metal6LPP ) + nrDeleteLayers( FlattenView Metal7LPP ) + if( Verbose printf("Deleting existing vias...\n")) + instances = setof( inst FlattenView~>instances inst->libName==TechLibName) + foreach( inst instances dbDeleteObject(inst)) + dbSave( FlattenView ) + ) + if( Verbose printf("%s flatten done.\n" CellView~>cellName)) + ) + + pout=outfile(celllist_filename) + if( pout then + foreach( inst uniqueInstances + fprintf( pout "%s %s %s\n" inst~>libName inst~>cellName "abstract") + ) + close(pout) + ) + + ; post-flatten check for missing layout views + prelayouts=nil + floorplans=nil + foreach( inst FlattenView->instances + when( inst->viewName=="prelayout" + prelayouts=t + ) + when( inst->viewName=="floorplan" + floorplans=t + ) + ) + (unless ExpertMode + (when prelayouts + UIPopUpDialog( "Instances found with prelayout view.\n" ) + ) + (when floorplans + UIPopUpDialog( "Instances found with floorplan view.\n" ) + ) + ) + + ; switch current window + win = (hiGetCurrentWindow) + (when win (geOpen ?window win + ?lib FlattenView->libName + ?cell FlattenView->cellName + ?view FlattenView->viewName + ?viewType "maskLayout" + ?mode "a") + ) + + FlattenView +)))) + + +defun( nrFlattenViewPG ( CellView flattenViewName + powerCellName + powerViewName + celllist_filename + @key + ( OBSCellName "" ) + ( OBSViewName "layout" ) + ( BusWireCellName "" ) + ( BusWireViewName "layout" ) + ( Verbose nil ) + ( DeleteWires t ) + ( DeleteObs t ) + ( RegenerateFromCast nil ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ( overhang t ) + ) + let((FlattenView FlattenViewTemp temp instances uniqueInstances routedDirectiveList + prbounds xalign tiehilo GND Vdd instGND instVdd x0 y0 pout ) + + FlattenView=dbOpenCellViewByType( CellView~>libName CellView~>cellName flattenViewName "maskLayout" "a" ) + unless( FlattenView error("Flatten View (%s) does not exist!\n" flattenViewName ) ) + + ; regenerate power grid, or open existing one read only + powerGridView=AutoGeneratePowerGrid( FlattenView powerCellName + ?OBSCellName OBSCellName + ?OBSViewName OBSViewName + ?powerViewName powerViewName + ?overhang overhang + ) + unless( powerGridView + printf( "WARNING: using read-only power grid %s %s\n" powerCellName powerViewName) + powerGridView=dbOpenCellViewByType( CellView~>libName powerCellName powerViewName + "maskLayout" "r" ) + ) + unless( powerGridView error("Error: AutoGeneratePowerGrid failed.\n") ) + + instances= setof( inst FlattenView~>instances inst->libName!=TechLibName) + instances= cadr( NameFilterInstances( instances PowerGridCellPairRegExs )) + foreach( inst instances if( inst~>objType=="mosaicInst" dbDeleteObject(inst~>mosaic) dbDeleteObject(inst) ) ) + + ; draw power pins + x0 = (car (car FlattenView->bBox)) + y0 = (cadr (car FlattenView->bBox)) + x0 = (ceiling (x0/PowerGridPitch))*PowerGridPitch + y0 = (ceiling (y0/(2*PowerGridPitch)))*(2*PowerGridPitch) + CreatePowerPins( FlattenView "M7" x0:y0 t ) + + ; instantiate tiehilo + tiehilo = dbCreateInst( FlattenView powerGridView "tiehilo" list(0 0) "R0" ) + AnchorInstance( tiehilo ) + GND = dbFindNetByName( FlattenView "GND") + Vdd = dbFindNetByName( FlattenView "Vdd") + instGND = dbFindTermByName( powerGridView "GND") + instVdd = dbFindTermByName( powerGridView "Vdd") + dbCreateInstTerm( GND tiehilo instGND) + dbCreateInstTerm( Vdd tiehilo instVdd) + + xalign=GetXAlignmentProp(CellView) + if( xalign then + when( xaligninstances inst->libName!=TechLibName) + instances= append( car( NameFilterInstances( instances LibCellsToIgnore )) + cadr( NameFilterInstances( instances PowerGridCellPairRegExs ))) + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances=cons( inst uniqueInstances ) + ) + ) + pout=outfile(celllist_filename) + if( pout then + foreach( inst uniqueInstances + fprintf( pout "%s %s %s\n" inst~>libName inst~>cellName "abstract") + ) + close(pout) + ) + + dbSave( FlattenView ) + + ; switch current window + win = (hiGetCurrentWindow) + (when win (geOpen ?window win + ?lib FlattenView->libName + ?cell FlattenView->cellName + ?view FlattenView->viewName + ?viewType "maskLayout" + ?mode "a") + ) + + FlattenView +)) + + +;attempt to compare floorplan to prelayout placements +(defun ComparePlacement (cv) + (let (floorplan prelayout flattenlist flat1 flat2 cells1 cells2 + x y oldy1 oldy2 + ) + floorplan=(nrOpenCellViewReadable cv->libName cv->cellName "floorplan") + prelayout=(nrOpenCellViewReadable cv->libName cv->cellName "prelayout") + flattenlist = (strcat cv->cellName ".flatten_cells_list") + flat1=(nrFlattenView floorplan nil nil flattenlist) + flat2=(nrFlattenView prelayout nil nil flattenlist) + + cells1=flat1->instances + cells2=flat2->instances + (foreach inst cells1 + x=(car inst->xy) + y=(cadr inst->xy) + (when !(IsInList y oldy1) + oldy1=(cons oldy1 y) + ) + ) + + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/floorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/floorplan.il new file mode 100644 index 0000000000..24f81f6eee --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/floorplan.il @@ -0,0 +1,80 @@ + +defun( nrCreateFloorplan (libName cellName viewName floorplanViewName + @key + ( Verbose nil ) + ) + prog( (CellView FloorplanView LayoutView LibCellsToIgnore routedStatus + transform InstName NewMasterCellView) + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + FloorplanView=nrOpenCellViewWritable(libName cellName floorplanViewName) + if( FloorplanView==nil then + printf("Error: CellView %s(%s) is not writable.\n" cellName floorplanViewName) + FloorplanView=nrOpenCellViewReadable(libName cellName floorplanViewName) + return(FloorplanView) + ) + if( viewName==floorplanViewName then + return(FloorplanView) + ) + if( member( cellName doneCellList ) then + return(FloorplanView) + ) + doneCellList=cons( cellName doneCellList ) + if( nrIsLeafCell( libName cellName viewName) then + CellView=nrOpenCellViewReadable(libName cellName viewName) + FloorplanView=dbCopyCellView( CellView libName cellName floorplanViewName nil nil t) + foreach( inst FloorplanView~>instances + if( inst~>objType=="mosaicInst" dbDeleteObject(inst~>mosaic) dbDeleteObject(inst) ) + ) + foreach( lpp FloorplanView~>lpps + if( lpp~>layerName!="prBoundary" then + foreach( shape lpp~>shapes if( dbIsId(shape) then dbDeleteObject(shape))) + ) + ) + dbSave(FloorplanView) + if( Verbose then printf("Done Creating leaf cell: %s(%s)...\n" FloorplanView~>cellName FloorplanView~>viewName)) + else + if( nrIsRoutedCell(libName cellName viewName) then + CellView=nrOpenCellViewReadable(libName cellName "prelayout") + when( !CellView + printf("Can't find view: %s(%s)...\n" cellName "prelayout") + CellView=nrOpenCellViewReadable(libName cellName viewName) + ) + if( Verbose then printf("Found routed mid cell: %s(%s)...\n" FloorplanView~>cellName FloorplanView~>viewName)) + else + CellView=nrOpenCellViewReadable(libName cellName viewName) + ) + FloorplanView=dbCopyCellView(CellView libName cellName floorplanViewName nil nil t) + if( Verbose then printf("Creating mid cell: %s(%s)...\n" FloorplanView~>cellName FloorplanView~>viewName)) + instances= car( NameFilterInstances( FloorplanView~>instances LibCellsToIgnore )) + if( instances then nrDeleteLayers( FloorplanView BoundaryLPP )) + foreach( inst instances + InstName=inst~>name + transform=inst~>transform + NewMasterCellView=nrCreateFloorplan(inst~>libName inst~>cellName inst~>viewName floorplanViewName + ?Verbose Verbose + ) + dbDeleteObject(inst) + dbCreateInst( + FloorplanView + NewMasterCellView + InstName + car( transform ) + cadr( transform ) ) + ) + dbSave(FloorplanView) + foreach( inst cadr( NameFilterInstances( FloorplanView~>instances LibCellsToIgnore )) + if( inst~>objType=="mosaicInst" dbDeleteObject(inst~>mosaic) dbDeleteObject(inst) ) + ) + foreach( lpp FloorplanView~>lpps + if( lpp~>layerName!="prBoundary" then + foreach( shape lpp~>shapes if( dbIsId(shape) then dbDeleteObject( shape ))) + ) + ) + dbSave(FloorplanView) + if( Verbose then printf("Done Creating mid cell: %s(%s)...\n" FloorplanView~>cellName FloorplanView~>viewName)) + ) + return(FloorplanView) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/routed.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/routed.il new file mode 100644 index 0000000000..156d6580d7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/routed.il @@ -0,0 +1,178 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +defun( nrLoadRoutedDirective ( CellView + @key + ( Verbose nil ) + ( RegenerateFromCast nil ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ) + let( ( TargetDFIIPath NetFile DirectivesFile Command routed DirectiveTable) + TargetDFIIPath = ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + if( !isDir( TargetDFIIPath ) then createDir( TargetDFIIPath )) + NetFile = sprintf( nil "%s/ilnets/%s.netlist.il" + TargetDFIIPath + CellView~>cellName ) + DirectiveDir = sprintf( nil "%s/ildirectives" TargetDFIIPath ) + if( !isDir( DirectiveDir ) + if( !createDir( DirectiveDir ) error( "Error: Failed to create dir %s.\n" DirectiveDir ) ) + ) + + DirectivesFile = sprintf( nil "%s/ildirectives/%s.directives.il" + TargetDFIIPath + CellView~>cellName ) + ExecCmd = cond( ( ( boundp( `ExecCmd ) && stringp( ExecCmd ) ) + ExecCmd ) + ( "" ) ) + when( (!isFile( DirectivesFile ) || !isFile( NetFile ) || + (RegenerateFromCast && compareTime( getCurrentTime() timeToString( fileTimeModified(DirectivesFile)))>100) ) +; regenerate only if the skill file is more than 120 seconds old. + + Command = sprintf( nil + "%s %s/cast2skill --cast-path=%s --cell=%s --output-dir=%s --cadence-name --root-only --suppress-pins --max-heap-size=%dM --64" + ExecCmd + PackageGetBinRoot( ) + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + CellView~>cellName + ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + MaxHeapSize + ) + printf( "%s\n" Command ) + shell( Command ) + ) + if( isFile(DirectivesFile) then + load( DirectivesFile ) + routed=if( setof( key DirectiveTable key=="routed" ) + if( arrayref( DirectiveTable "routed" ) "yes" "no") + "undefined") + else + printf("----------ERROR----------\n") + printf("Cast/Spec didn't parse. Check your terminal.\n") + routed="fail" + ) + routed + ) +) + +defun( nrIsRoutedCell ( libname cellname viewname + @key + ( routedDirectiveList nil ) + ( Verbose nil ) + ( RegenerateFromCast nil ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ) + let( ( isRoutedCell CellView temp routedStatus routedStatus1 InstLibNames InstCellNames) + isRoutedCell= nil + + CellView=dbOpenCellViewByType( libname cellname viewname ) + +; if there is any cell from "gate" "stack" "tsmc13lg" "globals", don't inline them + if( (strncmp( cellname "gate" 4)==0 || strncmp( cellname "stack" 5)==0 ) then + isRoutedCell= t) + +; assume all leaf cell to be routed. + if( nrIsLeafCell( libname cellname viewname ) then isRoutedCell= t) +; if there is no routing directive, run cast2skill + if(( RegenerateFromCast || isRoutedCell==nil ) then + if( routedDirectiveList then + routedStatus=cond( + ( member( cellname routedDirectiveList ) "yes" ) + ( t "no" ) ) + else + routedStatus = nrLoadRoutedDirective( CellView ?RegenerateFromCast RegenerateFromCast ?Verbose Verbose ?MaxHeapSize MaxHeapSize ) + ) + if(Verbose + printf("Loading cast Directive \"%s\" for cell %s... \n" routedStatus CellView~>cellName )) + ) + if((routedStatus=="yes") isRoutedCell= t ) + isRoutedCell + ) +) + + + +defun( nrIsLeafCell ( libname cellname viewname + @key (tempdir ConfigFileGetValue(TheCDSConfigTable "TEMP")) + (castpath ConfigFileGetValue(TheCDSConfigTable "CAST_PATH")) ) + let((isLeafCell Command filename file line) + + isLeafCell = nil + + filename = strcat( tempdir "/" cellname ".leaf" ) + ExecCmd = cond( ( ( boundp( `ExecCmd ) && stringp( ExecCmd ) ) + ExecCmd ) + ( "" ) ) + when( !isFile(filename) + Command = sprintf( nil + "%s %s/cast_query --cast-path=%s --cell=%s --output=%s --cadence-name --max-heap-size=%dM --task=subcells --filter=\"leaf&!ancestor=standard.base.proteus\"" + ExecCmd + PackageGetBinRoot( ) + castpath + cellname + filename + nrGetMaxHeapSize( ) + ) + printf( "%s\n" Command ) + shell( Command ) + ) + + file=infile( filename ) + if( file then + while( gets( line file ) + when( car(parseString(line " "))==cellname + isLeafCell= t + ) + ) + else + printf("Can't open file %s.\n" filename) + ) + close( file ) + isLeafCell + ) +) + + +defun( nrCastQuery ( CellView + @key + ( RegenerateFromCast t ) + ( MaxHeapSize (nrGetMaxHeapSize) ) + ) + + let((routedTrueFile routedFalseFile p_in Command routedTrueList routedFalseList line) + + TargetDFIIPath = ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + DirectiveDir = sprintf( nil "%s/ildirectives" TargetDFIIPath ) + if( !isDir( DirectiveDir ) +; if( !ictMkDir( DirectiveDir ) error( "Error: Failed to create dir %s.\n" DirectiveDir ) ) + if( system(strcat("mkdir " DirectiveDir))==1 error( "Error: Failed to create dir %s.\n" DirectiveDir ) ) + ) + + routedTrueFile = sprintf( nil "%s/ildirectives/%s.routedTrue.txt" + TargetDFIIPath + CellView~>cellName ) + when( !isFile( routedTrueFile ) || RegenerateFromCast + Command = sprintf( nil + "%s/cast_query --cast-path=%s --cell=%s --task=subcells --filter=routed --translate=cadence --cadence-name --output=%s --max-heap-size=%dM --64" + PackageGetBinRoot( ) + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + CellView~>cellName + routedTrueFile + MaxHeapSize + ) + printf( "%s\n" Command ) + shell( Command ) + ) + p_in=infile(routedTrueFile) + routedTrueList=nil + while( gets( line p_in) + sscanf( line "%s" cellName ) + if( cellName != CellView~>cellName then routedTrueList= cons( cellName routedTrueList )) + ) + close(p_in) + routedTrueList + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/sync.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/sync.il new file mode 100644 index 0000000000..ea8155b701 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/sync.il @@ -0,0 +1,16 @@ +(defun FlushDesignFiles (cv) + (let (tempdir cmd cell) + cell = cv->cellName + tempdir = ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + + cmd = (strcat "rm -f ./" cell "*") + (shell cmd) + cmd = (strcat "rm -rf " tempdir "/*") + (shell cmd) + ) +) + +(defun FlushAndSync (cv) + (FlushDesignFiles cv) + (nrSyncToNetlist cv) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/util.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/util.il new file mode 100644 index 0000000000..b94807e32d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/nano/util.il @@ -0,0 +1,100 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + +defun( nrDeleteLayers ( CellView layerLLP ) + let((num_deleted) + num_deleted=0 + foreach( lpp CellView~>lpps + if( lpp~>layerName==car(layerLLP) && lpp~>purpose==cadr(layerLLP) then + foreach( shape lpp~>shapes + dbDeleteObject( shape ) + num_deleted=num_deleted+1 ) + ) + ) + num_deleted + ) +) + +defun( nrDeleteInstances ( CellView libName cellName viewName ) + let((num_deleted) + num_deleted=0 + foreach( inst CellView~>instances + if( inst~>libName==libName && inst~>cellName==cellName && inst~>viewName==viewName then + dbDeleteObject( inst ) + num_deleted=num_deleted+1 + ) + ) + num_deleted + ) +) + +; does not really belong here, but it does not 'belong' anywhere. +(defun nrGetMaxHeapSize () + (cond ((and (boundp 'maxHeapSize) maxHeapSize!=nil) maxHeapSize) + ((boundp 'UIOptions_Form) + UIOptions_Form->UIOptions_Form_MaxHeapSize->value) + (t + (shell "uname -m > /tmp/uname-machine") + mnfile = (infile "/tmp/uname-machine") + (gets machine mnfile) + (close mnfile) + (deleteFile "/tmp/uname-machine") + (if machine=="x86_64\n" 4096 1800) + ) + ) + ) + +; this function should be combined with nrGetMaxHeapSize +(defun nrGetJavaArguments () + (cond ((and (boundp 'javaArguments) javaArguments!=nil) javaArguments) + ((boundp 'UIOptions_Form) + UIOptions_Form->UIOptions_Form_JavaArguments->value) + (t ""))) + +; moved from a UI function skill to be allowed in nograph mode +defun( FindInplacedPins (cellView) + let((powerNetNames InplacedPinsList terminal pinShapes net pin overlapShape obj SetshapeSet ) + powerNetNames=list("Vdd" "GND" "Vss" "gnd") + InplacedPinsList=nil + foreach( terminal cellView~>terminals + pinShapes=(setof f terminal~>pins~>fig f!=nil) ; why are there nil figs? + net=terminal~>net + if( !member( net~>name powerNetNames ) then + foreach( pin pinShapes + overlapShapeSet=append( dbGetOverlaps( cellView pin~>bBox list(pin~>layerName "drawing") 1:20 ) + dbGetOverlaps( cellView pin~>bBox list(pin~>layerName "net") 1:20 ) ) + overlapShapeSet=setof( obj overlapShapeSet car(obj)~>libName!="tsmc65" ) + + foreach( shapeSet overlapShapeSet + inst=car(shapeSet) + shape=cadr(shapeSet) +; if(shape~>net then printf("Found top leve pin %s overlaping %s\n" net~>name inst~>name)) + ) + if( overlapShapeSet then + InplacedPinsList=cons( net~>name InplacedPinsList ) + ) + ) + ) + ) + if( InplacedPinsList then printf("Found %d inplaced pins \n" length(InplacedPinsList))) + InplacedPinsList + ) +) + + +; +; delete tool summary file +; +defun( nrDeleteToolSum ( LogFileName ) + let( (SumFileName Command) + SumFileName = substring( LogFileName 1 ( strlen( LogFileName ) - 3 )) + SumFileName = strcat( SumFileName "sum" ) + Command = sprintf( nil "rm -f %s" SumFileName ) + shell( Command ) + printf( "Delete old summary file %s\n" SumFileName) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/p4/p4.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/p4/p4.il new file mode 100644 index 0000000000..0cf52f531c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/p4/p4.il @@ -0,0 +1,507 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Simple utility functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun cdsp4 (command @key (CV (geGetEditCellView)) + (client (ConfigFileGetValue TheCDSConfigTable "P4CLIENT"))) + (let (DFII_DIR P4CLIENT) + DFII_DIR = (ConfigFileGetValue TheCDSConfigTable "DFII_DIR") + (shell (sprintf nil "cdsp4%s --dfII-dir=%s --client-spec=%s --view-name=%s %s" + command DFII_DIR client CV->viewName CV->cellName)) + ) + ) + +(defun cdsp4add (@key (CV (geGetEditCellView)) + (client (ConfigFileGetValue TheCDSConfigTable "P4CLIENT"))) + (cdsp4 "add" ?CV CV ?client client) + ) + +(defun cdsp4edit (@key (CV (geGetEditCellView)) + (client (ConfigFileGetValue TheCDSConfigTable "P4CLIENT"))) + (cdsp4 "edit" ?CV CV ?client client) + (dbReopen CV "a") ; change the mode + ) + +(defun cdsp4revert (@key (CV (geGetEditCellView)) + (client (ConfigFileGetValue TheCDSConfigTable "P4CLIENT"))) + (dbSave CV) + (dbReopen CV "r") ; change the mode + (cdsp4 "revert" ?CV CV ?client client) + (dbRefreshCellView CV) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Complex stuff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun CDSP4IPCWait ( Proc ) + ( ipcWait Proc ) ) + +(defun CDSP4IsCellViewWriteable ( LibName CellName ViewName ) + (let ( + ( ViewDDObj ( ddGetObj LibName CellName ViewName ) ) ) + (when ( getq ViewDDObj files ) + ( ddIsObjWritable ( car ( getq ViewDDObj files ) ) ) ) ) ) + +(defun CDSP4IsLibCellViewTrippleWriteable ( LibCellViewTripple ) + ( CDSP4IsCellViewWriteable + ( car LibCellViewTripple ) + ( cadr LibCellViewTripple ) + ( caddr LibCellViewTripple ) ) ) + +(defun CDSP4BinLibCellViewTripples ( LibCellViewTripples ) + (let ( + ( Ret ( makeTable "foo" nil ) ) ) + ( foreach + Tripple + LibCellViewTripples + (let ( + ( ViewName ( caddr Tripple ) ) ) + ( setarray + Ret + ViewName + ( cons + Tripple + ( arrayref Ret ViewName ) ) ) ) ) + Ret ) ) + +(defun CDSP4SplitList ( OriginalList SplitLength ) + (let ( + ( Ret nil ) + ( CurrList nil ) + ( Count 0 ) ) + ( foreach + Item + OriginalList + (let () + (when ( equal Count SplitLength ) + ( setq + Ret + ( tconc Ret ( car CurrList ) ) ) + ( setq CurrList nil ) + ( setq Count 0 ) ) + ( setq CurrList ( tconc CurrList Item ) ) + ( setq Count ( plus Count 1 ) ) ) ) + (when CurrList + ( setq Ret ( tconc Ret ( car CurrList ) ) ) ) + ( car Ret ) ) ) + + +(defun CDSP4MakeCommandScript ( CommandStr TempDir ) + (let ( + ( CommandFileName ( makeTempFileName + ( sprintf nil "%s/cdsp4command" TempDir ) ) ) ) + (let ( + ( CommandFile ( outfile CommandFileName "w" ) ) ) + ( fprintf CommandFile "#!/bin/bash\n%s\n" CommandStr ) + ( close CommandFile ) ) + ( shell + ( sprintf nil "chmod u+x \"%s\"" CommandFileName ) ) + CommandFileName ) ) + + +(defun CDSP4MakePerforceCommandScript ( P4CommandString + P4User + P4Passwd + P4Client + P4Config + P4Changelist + P4LogFileName + TempDir + CellNameList + ) + (let ( + ( CellNameListString ( ListApplyFuncToListAndAccumulateResult + CellNameList + (lambda + ( CellName CurrString ) + ( sprintf nil "%s \"%s\"" CurrString CellName ) ) + nil + "" ) ) + ( CommandScriptFileName ( makeTempFileName + ( sprintf nil "%s/cdsp4cmd" TempDir ) ) ) ) + (let ( + ( CommandScriptPort ( outfile CommandScriptFileName "w" ) ) ) + ( fprintf CommandScriptPort "#!/bin/bash\n" ) + ( fprintf CommandScriptPort "P4CONFIG=%s\n" P4Config ) + ( fprintf CommandScriptPort "export P4CONFIG\n" ) + ( fprintf CommandScriptPort "cd %s\n" ( NameGetDFIIDirFromCellName ( car CellNameList ) ) ) + (let ( + ( CommandStringWithClientSpec + ( sprintf + nil + "%s --change-list=%s " + P4CommandString + P4Changelist ) ) ) + + (when ( and P4User ( not ( equal P4User "" ) ) ) + ( setq CommandStringWithClientSpec + ( sprintf nil "%s --perforce-user=%s" + CommandStringWithClientSpec + P4User ) ) ) + (when ( and P4Client ( not ( equal P4Client "" ) ) ) + ( setq CommandStringWithClientSpec + ( sprintf nil "%s --client-spec=%s" + CommandStringWithClientSpec + P4Client ) ) ) + + (when ( and P4Passwd ( not ( equal P4Passwd "" ) ) ) + ( setq CommandStringWithClientSpec + ( sprintf nil "%s --perforce-password=%s" + CommandStringWithClientSpec + P4Passwd ) ) ) + + + ( setq CommandStringWithClientSpec + ( sprintf + nil + "%s %s 1>>%s 2>>%s\n" + CommandStringWithClientSpec + CellNameListString + P4LogFileName + P4LogFileName + ) ) + + (let ( + ( LogPort ( outfile P4LogFileName ) ) ) + ( fprintf LogPort + CommandStringWithClientSpec ) + ( close LogPort ) ) + + ( fprintf CommandScriptPort + CommandStringWithClientSpec ) + ( close CommandScriptPort ) + ( shell ( sprintf nil "chmod u+x \"%s\"" CommandScriptFileName ) ) ) + CommandScriptFileName ) ) ) + +(defun CDSP4RunCommandOnLibCellViewTripples ( P4CommandString + P4User + P4Passwd + P4Client + P4Config + P4Changelist + LibCellViewTripples + CellsPerCommand + LogFileName + TempDir + IncludeView + ) + + (let ( + ( CommandList nil ) + ( P4CommandList nil ) + ( LogFileList nil ) + ( TripplesTable ( CDSP4BinLibCellViewTripples + LibCellViewTripples ) ) ) + ( foreach + ViewName + TripplesTable + (let ( + ( CurrTripples ( arrayref TripplesTable ViewName ) ) ) + (let ( + ( CellNames ( ListApplyFuncToListAndAccumulateResults + CurrTripples + (lambda + ( Tripple ) + ( cadr Tripple ) ) + nil ) ) ) + (let ( + ( CellNameLists ( CDSP4SplitList + CellNames + CellsPerCommand ) ) ) + ( foreach + CellNameList + CellNameLists + (let ( + ( CellNameListString ( ListApplyFuncToListAndAccumulateResult + CellNameList + (lambda + ( CellName CurrString ) + ( sprintf nil "%s \"%s\"" CurrString CellName ) ) + nil + "" ) ) ) + (let ( + ( CurrLogFileName ( makeTempFileName + ( sprintf nil "%s/cdsp4output" TempDir ) ) ) ) + (let ( + ( LogOutput ( outfile CurrLogFileName "w" ) ) ) + ( close LogOutput ) ) + ( setq LogFileList ( cons CurrLogFileName LogFileList ) ) + (let ( + ( P4CommandScript ( CDSP4MakePerforceCommandScript + (if IncludeView + ( sprintf nil "%s --view-name=%s" + P4CommandString + ViewName ) + P4CommandString ) + P4User + P4Passwd + P4Client + P4Config + P4Changelist + CurrLogFileName + TempDir + CellNameList + ) ) ) + ( setq P4CommandList ( cons P4CommandScript P4CommandList ) ) + (let ( + ( Command + ( sprintf + nil + "/p/rrc/tools/bin/fulcrum %s" + P4CommandScript ) ) ) + + (let ( + ( CommandFile ( CDSP4MakeCommandScript + Command + TempDir ) ) ) + ( setq + CommandList + ( cons CommandFile CommandList ) ) + ) ) ) ) ) ) ) ) ) ) + (let ( + ( ProcIdList ( ListApplyFuncToListAndAccumulateResults + CommandList + (lambda + ( CurrCommand ) + ( ipcBatchProcess + CurrCommand + "" + "/dev/null" ) ) + nil ) ) ) + ( foreach + ProcId + ProcIdList + ( CDSP4IPCWait ProcId ) ) ) + + (let ( + ( LogPort ( outfile LogFileName "a" ) ) ) + ( foreach + LogFile + LogFileList + (let ( ) + ( FileUtilAppendFile LogPort LogFile ) + ( deleteFile LogFile ) ) ) + ( close LogPort ) ) + + ( foreach + Command + CommandList + ( deleteFile Command ) ) + ( foreach + Command + P4CommandList + ( deleteFile Command ) ) ) + nil ) + + + +;Returns list of cells that could not be editted. +(defun CDSP4EditLibCellViewTripples ( P4User + P4Passwd + P4Client + P4Config + P4Changelist + LibCellViewTripples + CellsPerCommand + LogFileName + TempDir ) + ( CDSP4RunCommandOnLibCellViewTripples + ( sprintf nil "%s/cdsp4edit \"--dfII-dir=%s\"" + ( PackageGetBinRoot ) + ( NameGetDFIIDirFromCellName ( cadr ( car LibCellViewTripples ) ) ) ) + P4User + P4Passwd + P4Client + P4Config + P4Changelist + LibCellViewTripples + CellsPerCommand + LogFileName + TempDir + t ) + + (let ( + ( Ret nil ) ) + ( foreach + LibCellViewTripple + LibCellViewTripples + (unless ( CDSP4IsLibCellViewTrippleWriteable + LibCellViewTripple ) + ( setq + Ret + ( tconc Ret LibCellViewTripple ) ) ) ) + ( car Ret ) ) ) + +(defun CDSP4MakeEditErrorString ( EditRet ) + (let ( + ( ErrorStr nil ) ) + ( foreach + Tripple + EditRet + (let ( + ( CurrErrorStr ( sprintf + nil + "Unable to edit %L %L %L.\n" + ( car Tripple ) + ( cadr Tripple ) + ( caddr Tripple ) ) ) ) + ( setq + ErrorStr + (if ErrorStr + ( strcat ErrorStr CurrErrorStr ) + CurrErrorStr ) ) ) ) + ErrorStr ) ) + +(defun CDSP4AddLibCellViewTripples ( P4User + P4Passwd + P4Client + P4Config + P4Changelist + LibCellViewTripples + CellsPerCommand + LogFileName + TempDir ) + ( CDSP4RunCommandOnLibCellViewTripples + ( sprintf nil "%s/cdsp4add \"--dfII-dir=%s\"" + ( PackageGetBinRoot ) + ( NameGetDFIIDirFromCellName ( cadr ( car LibCellViewTripples ) ) ) ) + P4User + P4Passwd + P4Client + P4Config + P4Changelist + LibCellViewTripples + CellsPerCommand + LogFileName + TempDir + t ) ) + +(defun CDSP4RevertLibCellViewTripples ( P4User + P4Passwd + P4Client + P4Config + P4Changelist + LibCellViewTripples + CellsPerCommand + LogFileName + TempDir + ) + ( CDSP4RunCommandOnLibCellViewTripples + ( sprintf nil "%s/cdsp4revert \"--dfII-dir=%s\"" + ( PackageGetBinRoot ) + ( NameGetDFIIDirFromCellName ( cadr ( car LibCellViewTripples ) ) ) ) + P4User + P4Passwd + P4Client + P4Config + P4Changelist + LibCellViewTripples + CellsPerCommand + LogFileName + TempDir + t ) ) + +(defun CDSP4Edit ( P4User P4Passwd P4Client P4Config CellView TempDir ) + (let ( + ( EditRet ( CDSP4EditLibCellViewTripples + P4User + P4Passwd + P4Client + P4Config + "default" + ( list + ( list + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) + 1 + ( strcat TempDir "/p4.log" ) + TempDir ) ) ) + (if EditRet + (error ( CDSP4MakeEditErrorString EditRet ) ) + ( dbReopen CellView "a" ) ) ) ) + +(defun CDSP4Add ( P4User P4Passwd P4Client P4Config CellView TempDir ) + ( CDSP4AddLibCellViewTripples + P4User + P4Passwd + P4Client + P4Config + "default" + ( list + ( list + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) + 1 + ( strcat TempDir "/p4.log" ) + TempDir ) ) + +(defun CDSP4Revert ( P4User P4Passwd P4Client P4Config CellView TempDir ) + ( CDSP4RevertLibCellViewTripples + P4User + P4Passwd + P4Client + P4Config + "default" + ( list + ( list + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) + 1 + ( strcat TempDir "/p4.log" ) + TempDir ) + ( dbReopen CellView "r" ) ) + + +(defun CDSP4CellView (cv action) + (when action=="add" + ( CDSP4Add + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cv + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + (when action=="edit" + ( CDSP4Edit + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cv + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + (when action=="revert" + ( CDSP4Revert + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cv + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + cv +) + +(defun CDSP4CellFile (cv filename action) + (let (Command) + Command = ( sprintf nil "%s/cdsp4%s \"--dfII-dir=%s\" \"--client-spec=%s\" \"--file=%s\" %s" + ( PackageGetBinRoot ) + action + ( ConfigFileGetValue TheCDSConfigTable "DFII_DIR" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + filename + cv->cellName + ) + ( shell Command ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/distinst.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/distinst.il new file mode 100644 index 0000000000..6f322c98f0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/distinst.il @@ -0,0 +1,62 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun DistributeInstances ( CellView StartX StartY MaxX ) + (let ( + ( Instances ( getq CellView instances ) ) + ( CurrX StartX ) + ( CurrY StartY ) + ( CurrMaxHeight 0 ) + ) + ( foreach + Inst + Instances + (let ( + ( InstBBox ( getq Inst bBox ) ) + ) + (let ( + ( InstX ( RectGetLeft InstBBox ) ) + ( InstY ( RectGetBottom InstBBox ) ) + ( InstWidth ( RectGetWidth InstBBox ) ) + ( InstHeight ( RectGetHeight InstBBox ) ) + ) + + (when ( greaterp + ( plus CurrX InstWidth ) + MaxX + ) + + ( setq CurrY ( plus CurrY CurrMaxHeight ) ) + ( setq CurrMaxHeight 0 ) + ( setq CurrX StartX ) + ) + ( dbMoveFig + Inst + nil + ( list + ( list + ( difference + CurrX + InstX + ) + ( difference + CurrY + InstY + ) + ) + "R0" + ) + ) + ( setq CurrX ( plus CurrX InstWidth ) ) + (when ( lessp CurrMaxHeight InstHeight ) + ( setq CurrMaxHeight InstHeight ) + ) + ) + + ) + ) + ) + nil + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/inlineconnections.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/inlineconnections.il new file mode 100644 index 0000000000..f293c3f7af --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/inlineconnections.il @@ -0,0 +1,348 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + + +(defun InlineConnectionsGetInstancesFromInlinedInstance ( NameOfInstanceToInline + OriginalNetlistTable + TargetNetlistTable + GetNetlistTableFunc + GetNetlistTableFuncParams ) + (let ( + ( InstanceToInline ( NetlistTableGetInstance OriginalNetlistTable NameOfInstanceToInline ) ) ) + (if InstanceToInline + (let ( + ( MasterCellName ( NetlistTableGetInstanceMasterCellName InstanceToInline ) ) + ( OriginalConnections ( NetlistTableGetInstanceConnectionsTable InstanceToInline ) ) ) + (let ( + ( MasterNetlistTable ( apply + GetNetlistTableFunc + ( cons + MasterCellName + GetNetlistTableFuncParams ) ) ) ) + (if ( tablep MasterNetlistTable ) + (let ( + ( MasterCellInstances ( NetlistTableGetInstancesTable MasterNetlistTable ) ) ) + ( foreach + InstanceName + MasterCellInstances + (let ( + ( NewInstanceName ( sprintf + nil + "%s.%s" + NameOfInstanceToInline + InstanceName ) ) + ( CurrInstance ( NetlistTableGetInstance MasterNetlistTable InstanceName ) ) ) + (let ( + ( NewInstance ( NetlistTableCreateInstanceInNetlist + TargetNetlistTable + NewInstanceName + ( NetlistTableGetInstanceMasterLibName CurrInstance ) + ( NetlistTableGetInstanceMasterCellName CurrInstance ) ) ) ) + ( foreach + ParamPair + ( NetlistTableGetInstanceParametersPairs CurrInstance ) + (let ( + ( ParamName ( car ParamPair ) ) + ( ParamValue ( cadr ParamPair ) ) ) + ( NetlistTableAddParameterToInstance NewInstance ParamName ParamValue ) ) ) + ( foreach + ConnectionPair + ( NetlistTableGetInstanceConnectionPairs CurrInstance ) + (let ( + ( TerminalName ( car ConnectionPair ) ) + ( NetNameInInlinedInstance ( cadr ConnectionPair ) ) ) + (let ( + ( NetNameInContainingCell ( NetlistTableGetNetNameForInstanceTerminalName + InstanceToInline + NetNameInInlinedInstance ) ) ) + (if NetNameInContainingCell + ( NetlistTableAddConnectionToInstance + NewInstance + TerminalName + NetNameInContainingCell ) + (let ( + ( NewNetName ( sprintf nil "%s.%s" NameOfInstanceToInline NetNameInInlinedInstance ) ) ) + ( NetlistTableAddNet TargetNetlistTable NewNetName ) + ( NetlistTableAddConnectionToInstance NewInstance TerminalName NewNetName ) ) ) ) ) ) ) ) ) + nil ) + MasterNetlistTable ) ) ) + ( sprintf nil "Unable to find the instance \"%s\" NetlistTable." NameOfInstanceToInline ) ) ) ) + +(defun InlineConnectionsTransformNetlistTable ( OriginalNetlistTable + GetNetlistTableFunc + GetNetlistTableFuncParams + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) + (let ( + ( ErrorStr nil ) + ( LibName ( NetlistTableGetLibName OriginalNetlistTable ) ) + ( CellName ( NetlistTableGetCellName OriginalNetlistTable ) ) ) + (let ( + ( NewNetlistTable ( NetlistTableCreateEmptyNetlistTable + ( NetlistTableGetLibName OriginalNetlistTable ) + ( NetlistTableGetCellName OriginalNetlistTable ) ) ) ) + (let ( + ( OriginalInstanceTripples ( NetlistTableGetInstanceTripples OriginalNetlistTable ) ) ) + (unless ErrorStr + ( foreach + InstanceTripple + OriginalInstanceTripples + (let ( + ( InstanceName ( car InstanceTripple ) ) + ( InstanceMasterLibName ( cadr InstanceTripple ) ) + ( InstanceMasterCellName ( caddr InstanceTripple ) ) ) + (if ( apply + ShouldInlineConnectionsFunc + ( cons + LibName + ( cons + CellName + ( cons + InstanceName + ( cons + InstanceMasterLibName + ( cons + InstanceMasterCellName + ShouldInlineConnectionsFuncParams ) ) ) ) ) ) + ( setq + ErrorStr + ( InlineConnectionsGetInstancesFromInlinedInstance + InstanceName + OriginalNetlistTable + NewNetlistTable + GetNetlistTableFunc + GetNetlistTableFuncParams ) ) + ( NetlistTableCopyInstanceInToNetlist + ( NetlistTableGetInstance + OriginalNetlistTable + InstanceName ) + NewNetlistTable + InstanceName ) ) ) ) ) ) + ( foreach + NetName + ( NetlistTableGetNetNames OriginalNetlistTable ) + ( NetlistTableAddNet NewNetlistTable NetName ) ) + ( foreach + TerminalName + ( NetlistTableGetTerminalNames OriginalNetlistTable ) + ( NetlistTableAddTerminal NewNetlistTable TerminalName ) ) + ( foreach + StatisticPair + ( NetlistTableGetStatisticsPairs OriginalNetlistTable ) + ( NetlistTableAddStatistic + NewNetlistTable + ( car StatisticPair ) + ( cadr StatisticPair ) ) ) + (if ErrorStr + ErrorStr + NewNetlistTable ) ) ) ) + + +(defun InlineConnectionsGetOrderedListOfNetlistTablesToTransformMakeStackFrame ( NetlistTable + InstanceTripples ) + ( list NetlistTable InstanceTripples ) ) + +(defun InlineConnectionsGetOrderedListOfNetlistTablesToTransformPush ( Stack NetlistTable InstanceTripples ) + ( cons + ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformMakeStackFrame NetlistTable InstanceTripples ) + Stack ) ) + +(defun InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartPush ( Stack + VisitedTable + NetlistTable + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParam ) + (let ( + ( LibName ( NetlistTableGetLibName NetlistTable ) ) + ( CellName ( NetlistTableGetCellName NetlistTable ) ) + ( InstanceTripples ( NetlistTableGetInstanceTripples NetlistTable ) ) ) + (if ( arrayref VisitedTable ( list LibName CellName ) ) + Stack + (let ( + ( InstanceTripplesToVisit ( setof + InstanceTripple + InstanceTripples + (let ( + ( InstanceName ( car InstanceTripple ) ) + ( InstanceMasterLibName ( cadr InstanceTripple ) ) + ( InstanceMasterCellName ( caddr InstanceTripple ) ) ) + ( and + ( not + ( arrayref + VisitedTable + ( list + InstanceMasterLibName + InstanceMasterCellName ) ) ) + ( apply + ShouldInlineConnectionsFunc + ( cons + LibName + ( cons + CellName + ( cons + InstanceName + ( cons + InstanceMasterLibName + ( cons + InstanceMasterCellName + ShouldInlineConnectionsFuncParams ) ) ) ) ) ) ) ) ) ) ) + ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformPush + Stack + NetlistTable + InstanceTripplesToVisit ) ) ) ) ) + +(defun InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartGetCurrNetlistTable ( Stack ) + ( car ( car Stack ) ) ) + +(defun InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartGetCurrInstanceTripple ( Stack ) + ( car ( cadr ( car Stack ) ) ) ) + +(defun InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartNextInstanceTripple ( Stack ) + ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformPush + ( cdr Stack ) + ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartGetCurrNetlistTable Stack ) + ( cdr ( cadr ( car Stack ) ) ) ) ) + +(defun InlineConnectionsGetOrderedListOfNetlistTablesToTransform ( RootNetlistTable + SkillNetlistDir + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) + (let ( + ( Result nil ) + ( ErrorStr nil ) + + ( VisitedTable ( makeTable "visitedTable" nil ) ) ) + (let ( + ( Stack ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartPush + nil + VisitedTable + RootNetlistTable + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) ) ) + (while ( and ( null ErrorStr ) Stack ) + (let ( + ( CurrNetlistTable ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartGetCurrNetlistTable + Stack ) ) + ( CurrInstanceTripple ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartGetCurrInstanceTripple + Stack ) ) ) + (if CurrInstanceTripple + (let ( + ( CurrInstanceName ( car CurrInstanceTripple ) ) + ( CurrInstanceMasterLibName ( cadr CurrInstanceTripple ) ) + ( CurrInstanceMasterCellName ( caddr CurrInstanceTripple ) ) ) + (let ( + ( MasterNetlistTable ( NetlistTableGetSkillNetlistTableForCellName + CurrInstanceMasterCellName + SkillNetlistDir ) ) ) + (if ( tablep MasterNetlistTable ) + (let () + ( setq + Stack + ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartNextInstanceTripple Stack ) ) + ( setq + Stack + ( InlineConnectionsGetOrderedListOfNetlistTablesToTransformSmartPush + Stack + VisitedTable + MasterNetlistTable + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) ) ) + ( setq ErrorStr MasterNetlistTable ) ) ) ) + (let ( + ( LibName ( NetlistTableGetLibName CurrNetlistTable ) ) + ( CellName ( NetlistTableGetCellName CurrNetlistTable ) ) ) + ( setq Result ( tconc Result CurrNetlistTable ) ) + ( setarray VisitedTable ( list LibName CellName ) t ) + ( setq Stack ( cdr Stack ) ) ) ) ) ) ) + ( car Result ) ) ) + +(defun InlineConnectionsGetTableOfTransformedNetlistTables ( RootNetlistTable + SkillNetlistDir + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) + (let ( + ( ErrorStr nil ) + ( NetlistTablesToTransform ( InlineConnectionsGetOrderedListOfNetlistTablesToTransform + RootNetlistTable + SkillNetlistDir + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) ) + ( TableOfNetlistTables ( makeTable "netlistTablesTable" nil ) ) ) + ( foreach + NetlistTable + NetlistTablesToTransform + (unless ErrorStr + (let ( + ( TransformedNetlistTable ( InlineConnectionsTransformNetlistTable + NetlistTable + (lambda ( CellName TableOfNetlistTables ) + (let ( + ( NetlistTable ( arrayref TableOfNetlistTables CellName ) ) ) + (if NetlistTable + NetlistTable + ( sprintf + nil + "%L has not been transformed yet." + CellName ) ) ) ) + ( list TableOfNetlistTables ) + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) ) ) + (if ( tablep TransformedNetlistTable ) + (let () + ( setarray + TableOfNetlistTables + ( NetlistTableGetCellName TransformedNetlistTable ) + TransformedNetlistTable ) ) + ( setq ErrorStr TransformedNetlistTable ) ) ) ) ) + (if ErrorStr + ErrorStr + TableOfNetlistTables ) ) ) + +(defun InlineConnectionsHierTransformTable ( RootNetlistTable + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams + SkillNetlistDir ) + (let ( + ( ErrorStr nil ) + ( TableOfNetlistTables ( InlineConnectionsGetTableOfTransformedNetlistTables + RootNetlistTable + SkillNetlistDir + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) ) ) + (when ( not ( tablep TableOfNetlistTables ) ) + ( setq ErrorStr TableOfNetlistTables ) ) + (if ErrorStr + ErrorStr + (let ( + ( TransformedNetlistTable ( arrayref + TableOfNetlistTables + ( NetlistTableGetCellName RootNetlistTable ) ) ) ) + (if ( tablep TransformedNetlistTable ) + TransformedNetlistTable + ( sprintf + nil + "Root Netlist Table for %L was never transformed." + ( NetlistTableGetCellName RootNetlistTable ) ) ) ) ) ) ) + + + +(defun InlineConnectionsGetNetlistTable ( CellName + SkillNetlistDir + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) + (let ( + ( OriginalNetlistTable ( NetlistTableGetSkillNetlistTableForCellName CellName SkillNetlistDir ) ) ) + (if ( tablep OriginalNetlistTable ) + ( InlineConnectionsTransformNetlistTable + OriginalNetlistTable + SkillNetlistDir + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) + OriginalNetlistTable ) ) ) + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/lvsnodes.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/lvsnodes.il new file mode 100644 index 0000000000..291de8a0ad --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/lvsnodes.il @@ -0,0 +1,71 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun LVSNodesMakeEmptyLVSNodesTable ( cellName ) + (let ( + ( NewLVSNodesTable ( makeTable "lvsNodesTable" nil ) ) ) + ( setarray NewLVSNodesTable "cn" cellName ) + ( setarray NewLVSNodesTable "i" ( makeTable "lvsNodesInstancesTable" nil ) ) + NewLVSNodesTable ) ) + + +(defun LVSNodesGetCellName ( LVSNodesTable ) + ( arrayref LVSNodesTable "cn" ) ) + +(defun LVSNodesGetLVSNodesInstancesTable ( LVSNodesTable ) + ( arrayref LVSNodesTable "i" ) ) + +(defun LVSNodesGetLVSNodes ( LVSNodesTable ) + ( arrayref LVSNodesTable "n" ) ) + +(defun LVSNodesMakeLVSNodesInstance ( LVSNodesTable InstanceName ) + (let ( + ( LVSNodesInstancesTable ( LVSNodesGetLVSNodesInstancesTable LVSNodesTable ) ) + ( LVSNodesInstance ( makeTable "lvsNodesInstance" nil ) ) ) + ( setarray + LVSNodesInstance + "n" + InstanceName ) + ( setarray + LVSNodesInstance + "c" + ( makeTable "lvsNodeInstanceConnections" nil ) ) + ( setarray + LVSNodesInstancesTable + InstanceName + LVSNodesInstance ) + LVSNodesInstance ) ) + +(defun LVSNodesGetLVSNodesInstance ( LVSNodesTable InstanceName ) + ( arrayref + ( LVSNodesGetLVSNodesInstancesTable LVSNodesTable ) + InstanceName ) ) + +(defun LVSNodesGetLVSNodesInstanceName ( LVSNodeInstance ) + ( arrayref LVSNodesInstance "n" ) ) + +(defun LVSNodesGetLVSNodesInstanceConnections ( LVSNodesInstance ) + ( arrayref LVSNodesInstance "c" ) ) + +(defun LVSNodesMakeLVSNodesInstanceConnection ( LVSNodesInstance Node NodeInInstance ) + ( setarray + ( LVSNodesGetLVSNodesInstanceConnections + LVSNodesInstance ) + Node + NodeInInstance ) ) + +(defun LVSNodesAddLVSNode ( LVSNodesTable NodeName ) + ( setarray + LVSNodesTable + "n" + ( cons + NodeName + ( LVSNodesGetLVSNodes LVSNodesTable ) ) ) ) + +(defun LVSNodesGetLVSNodesInstanceConnectionPairs ( LVSNodesInstance ) + ( tableToList + ( LVSNodesGetLVSNodesInstanceConnections + LVSNodesInstance ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/netlisttable.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/netlisttable.il new file mode 100644 index 0000000000..458eee3b71 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/netlisttable.il @@ -0,0 +1,297 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun NetlistTableGetCellName ( NetlistTable ) + NetlistTable["cn"] +) + +(defun NetlistTableGetLibName ( NetlistTable ) + NetlistTable["ln"] +) + +(defun NetlistTableGetInstancesTable ( NetlistTable ) + NetlistTable["i"] +) + +(defun NetlistTableGetInstanceTripples ( NetlistTable ) + ( ListApplyFuncToListAndAccumulateResults + ( tableToList ( NetlistTableGetInstancesTable NetlistTable ) ) + (lambda + ( TableEntry ) + ( list + ( car TableEntry ) + ( NetlistTableGetInstanceMasterLibName ( cadr TableEntry ) ) + ( NetlistTableGetInstanceMasterCellName ( cadr TableEntry ) ) ) ) + nil ) ) + +(defun NetlistTableGetInstance ( NetlistTable InstanceName ) + NetlistTable["i"][InstanceName] +) + +(defun NetlistTableGetInstanceMasterLibName ( Instance ) + (when Instance Instance["ln"] ) ) + +(defun NetlistTableGetInstanceInNetlistMasterLibName ( NetlistTable InstanceName ) + ( NetlistTableGetInstanceMasterLibName NetlistTable["i"][InstanceName] ) +) + +(defun NetlistTableGetInstanceMasterCellName ( Instance ) + (when Instance Instance["cn"] ) +) + +(defun NetlistTableGetInstanceInNetlistMasterCellName ( NetlistTable InstanceName ) + ( NetlistTableGetInstanceMasterCellName NetlistTable["i"][InstanceName] ) +) + +(defun NetlistTableGetInstanceParametersTable ( Instance ) + (when Instance Instance["p"] ) +) + +(defun NetlistTableGetInstanceParametersPairs ( Instance ) + ( tableToList ( NetlistTableGetInstanceParametersTable Instance ) ) ) + +(defun NetlistTableGetInstanceInNetlistParametersPairs ( NetlistTable InstanceName ) + ( NetlistTableGetInstanceParametersPairs NetlistTable["i"][InstanceName] ) +) + +(defun NetlistTableGetInstanceParameterValue ( Instance ParameterName ) + (when Instance + ( arrayref ( NetlistTableGetInstanceParametersTable Instance ) ParameterName ) ) ) + +(defun NetlistTableGetInstanceConnectionsTable ( Instance ) + (when Instance Instance["c"] ) +) + +(defun NetlistTableGetInstanceConnectionPairs ( Instance ) + ( tableToList ( NetlistTableGetInstanceConnectionsTable Instance ) ) ) + +(defun NetlistTableGetInstanceInNetlistConnectionPairs ( NetlistTable InstanceName ) + ( NetlistTableGetInstanceConnectionPairs + ( NetlistTableGetInstance NetlistTable InstanceName ) ) ) + +(defun NetlistTableGetNetNameForInstanceTerminalName ( Instance TerminalName ) + ( arrayref ( NetlistTableGetInstanceConnectionsTable Instance ) TerminalName ) ) + +(defun NetlistTableGetNetNameForInstanceInNetlistTerminalName ( NetlistTable InstanceName TerminalName ) + ( NetlistTableGetNetNameForInstanceTerminalName + ( NetlistTableGetInstance NetlistTable InstanceName ) + TerminalName ) ) + +(defun NetlistTableGetNetsTable ( NetlistTable ) + ( arrayref NetlistTable "n" ) ) + +(defun NetlistTableGetNetNames ( NetlistTable ) + ( ListApplyFuncToListAndAccumulateResults + ( tableToList ( NetlistTableGetNetsTable NetlistTable ) ) + (lambda + ( NetEntry ) + ( car NetEntry ) ) + nil ) ) + +(defun NetlistTableGetTerminalNames ( NetlistTable ) + ( ListApplyFuncToListAndAccumulateResults + ( setof + NetEntry + ( tableToList ( NetlistTableGetNetsTable NetlistTable ) ) + ( car ( cadr NetEntry ) ) ) + (lambda + ( NetEntry ) + ( car NetEntry ) ) + nil ) ) + +(defun NetlistTableNetExists ( NetlistTable NetName ) + ( arrayref ( NetlistTableGetNetsTable NetlistTable ) NetName ) ) + +(defun NetlistTableTerminalExists ( NetlistTable TerminalName ) + ( car ( arrayref ( NetlistTableGetNetsTable NetlistTable ) TerminalName ) ) ) + + +(defun NetlistTableGetStatisticsTable ( NetlistTable ) + ( arrayref NetlistTable "s" ) ) + +(defun NetlistTableGetStatistic ( NetlistTable StatisticName ) + ( arrayref ( NetlistTableGetStatisticsTable NetlistTable ) StatisticName ) ) + +(defun NetlistTableGetStatisticsPairs ( NetlistTable ) + ( tableToList ( NetlistTableGetStatisticsTable NetlistTable ) ) ) + +(defun NetlistTableGetTotalTransistorGateArea ( NetlistTable ) + ( NetlistTableGetStatistic NetlistTable "a" ) ) + +(defun NetlistTableGetTotalTransistorWidth ( NetlistTable ) + ( NetlistTableGetStatistic NetlistTable "w" ) ) + +(defun NetlistTableGetTotalTransistorLength ( NetlistTable ) + ( NetlistTableGetStatistic NetlistTable "l" ) ) + +(defun NetlistTableGetTotalTransistorCount ( NetlistTable ) + ( NetlistTableGetStatistic NetlistTable "c" ) ) + +(defun NetlistTableGetCellWidth ( NetlistTable ) + ( NetlistTableGetStatistic NetlistTable "cw" ) ) + +(defun NetlistTableGetCellHeight ( NetlistTable ) + ( NetlistTableGetStatistic NetlistTable "ch" ) ) + + + + +(defun NetlistTableCreateEmptyNetlistTable ( LibName CellName ) + (let ( + ( NewNetlistTable ( makeTable "skillNetlistTable" nil ) ) ) + ( setarray NewNetlistTable "ln" LibName ) + ( setarray NewNetlistTable "cn" CellName ) + ( setarray NewNetlistTable "i" ( makeTable "instancesTable" nil ) ) + ( setarray NewNetlistTable "n" ( makeTable "netsTable" nil ) ) + ( setarray NewNetlistTable "s" ( makeTable "statisticsTable" nil ) ) + NewNetlistTable ) ) + +(defun NetlistTableAddTerminal ( NetlistTable TerminalName ) + ( setarray ( NetlistTableGetNetsTable NetlistTable ) TerminalName ( list t ) ) ) + +(defun NetlistTableAddNet ( NetlistTable NetName ) + ( setarray ( NetlistTableGetNetsTable NetlistTable ) NetName ( list nil ) ) ) + +(defun NetlistTableCreateInstance ( InstanceName MasterLibName MasterCellName ) + (let ( + ( NewInstance ( makeTable "instanceTable" nil ) ) ) + ( setarray NewInstance "n" InstanceName ) + ( setarray NewInstance "ln" MasterLibName ) + ( setarray NewInstance "cn" MasterCellName ) + ( setarray NewInstance "c" ( makeTable "connectionsTable" nil ) ) + ( setarray NewInstance "p" ( makeTable "parametersTable" nil ) ) + NewInstance ) ) + +(defun NetlistTableCreateInstanceInNetlist ( NetlistTable InstanceName MasterLibName MasterCellName ) + (let ( + ( NewInstance ( NetlistTableCreateInstance + InstanceName + MasterLibName + MasterCellName ) ) ) + ( setarray + ( NetlistTableGetInstancesTable + NetlistTable ) + InstanceName + NewInstance ) + NewInstance ) ) + +(defun NetlistTableAddConnectionToInstance ( Instance TerminalName NetName ) + ( setarray + ( NetlistTableGetInstanceConnectionsTable Instance ) + TerminalName + NetName ) ) + +(defun NetlistTableAddConnectionToInstanceInNetlist ( NetlistTable InstanceName TerminalName NetName ) + (unless ( NetlistTableNetExists NetlistTable NetName ) + ( NetlistTableAddNet NetlistTable NetName ) ) + ( NetlistTableAddConnectionToInstance + ( NetlistTableGetInstance + NetlistTable + InstanceName ) + TerminalName + NetName ) ) + +(defun NetlistTableAddParameterToInstance ( Instance ParamName ParamValue ) + ( setarray + ( NetlistTableGetInstanceParametersTable + Instance ) + ParamName + ParamValue ) ) + +(defun NetlistTableAddParameterToInstanceInNetlist ( NetlistTable InstanceName ParamName ParamValue ) + ( NetlistTableAddParameterToInstance + ( NetlistTableGetInstance NetlistTable InstanceName ) + ParamName + ParamValue ) ) + +(defun NetlistTableAddStatistic ( NetlistTable StatisticName StatisticValue ) + ( setarray + ( NetlistTableGetStatisticsTable NetlistTable ) + StatisticName + StatisticValue ) ) + +(defun NetlistTableSetTotalTransistorGateArea ( NetlistTable TotalGateArea ) + ( NetlistTableAddStatistic NetlistTable "a" TotalGateArea ) ) + +(defun NetlistTableSetTotalTransistorWidth ( NetlistTable TotalTransistorWidth ) + ( NetlistTableAddStatistic NetlistTable "w" TotalTransistorWidth ) ) + +(defun NetlistTableSetTotalTransistorLength ( NetlistTable TotalTransistorLength ) + ( NetlistTableAddStatistic NetlistTable "l" TotalTransistorLength ) ) + +(defun NetlistTableSetTotalTransistorCount ( NetlistTable TotalTransistorCount ) + ( NetlistTableAddStatistic NetlistTable "c" TotalTransistorCount ) ) + +(defun NetlistTableSetCellWidth ( NetlistTable CellWidth ) + ( NetlistTableAddStatistic NetlistTable "cw" CellWidth ) ) + +(defun NetlistTableSetCellHeight ( NetlistTable CellHeight ) + ( NetlistTableAddStatistic NetlistTable "ch" CellHeight ) ) + + + +(defun NetlistTableCopyInstanceInToNetlist ( SrcInstance TargetNetlistTable TargetIntanceName ) + (let ( + ( InstanceMasterLibName ( NetlistTableGetInstanceMasterLibName SrcInstance ) ) + ( InstanceMasterCellName ( NetlistTableGetInstanceMasterCellName SrcInstance ) ) + ( ParamPairs ( NetlistTableGetInstanceParametersPairs SrcInstance ) ) + ( ConnectionPairs ( NetlistTableGetInstanceConnectionPairs SrcInstance ) ) ) + (let ( + ( NewInstance ( NetlistTableCreateInstanceInNetlist + TargetNetlistTable + TargetIntanceName + InstanceMasterLibName + InstanceMasterCellName ) ) ) + ( foreach + ParamPair + ParamPairs + (let ( + ( ParamName ( car ParamPair ) ) + ( ParamValue ( cadr ParamPair ) ) ) + ( NetlistTableAddParameterToInstance NewInstance ParamName ParamValue ) ) ) + + ( foreach + ConnectionPair + ConnectionPairs + (let ( + ( TerminalName ( car ConnectionPair ) ) + ( NetName ( cadr ConnectionPair ) ) ) + (unless ( NetlistTableNetExists TargetNetlistTable NetName ) + ( NetlistTableAddNet TargetNetlistTable NetName ) ) + ( NetlistTableAddConnectionToInstance + NewInstance + TerminalName + NetName ) ) ) + NewInstance ) ) ) + + + + + +(defun NetlistTableGetSkillNetlistForCellName ( CellName SkillNetlistDir ) + ( sprintf nil "%s/%s.netlist.il" SkillNetlistDir CellName ) ) + + +(defun NetlistTableGetSkillNetlistTableForCellName ( CellName SkillNetlistDir ) + (let ( + ( SkillNetlistFileName ( NetlistTableGetSkillNetlistForCellName + CellName + SkillNetlistDir ) ) ) + (if ( isReadable + SkillNetlistFileName ) + (let () + (defvar NetListTable nil ) + ( load SkillNetlistFileName ) + (if NetListTable + NetListTable + ( sprintf + nil + "Could not load %L even though it is readable." + SkillNetlistFileName ) ) ) + ( sprintf + nil + "%L is not a readable file." + SkillNetlistFileName ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/swapmasters.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/swapmasters.il new file mode 100644 index 0000000000..fd92bd9ef1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/swapmasters.il @@ -0,0 +1,124 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun SwapSchematicTransistorMasters ( TargetCellView TechLibName NTransistorName PTransistorName ) + ( SwapSchematicMasters + TargetCellView + ( list + ( list + ( list + TechLibName + "nfet" + "symbol" + ) + ( list + TechLibName + NTransistorName + "symbol" + "schematicSymbol" + ) + ) + ( list + ( list + TechLibName + "pfet" + "symbol" + ) + ( list + TechLibName + PTransistorName + "symbol" + "schematicSymbol" + ) + ) + ) + ) + ) + +(defun SwapSchematicMasters ( TargetCellView Mappings ) + + (let ( + ( ReplaceParamsTable ( makeTable "FooTable" nil ) ) + ( MappingTable ( makeTable "FooTable" nil ) ) + ) + ( foreach + Mapping + Mappings + (let ( + ( ExistingTripple ( car Mapping ) ) + ( NewQuadruple ( cadr Mapping ) ) + ( ReplaceParams ( caddr Mapping ) ) + ) + (let ( + ( ExistingLibName ( car ExistingTripple ) ) + ( ExistingCellName ( nth 1 ExistingTripple ) ) + ( ExistingViewName ( nth 2 ExistingTripple ) ) + ( NewLibName ( car NewQuadruple ) ) + ( NewCellName ( nth 1 NewQuadruple ) ) + ( NewViewName ( nth 2 NewQuadruple ) ) + ( NewViewType ( nth 3 NewQuadruple ) ) + ) + (when ( ddGetObj + NewLibName NewCellName NewViewName ) + (let ( + ( Key + ( list ExistingLibName ExistingCellName ExistingViewName ) ) + ( NewCellView + ( dbOpenCellViewByType + NewLibName NewCellName NewViewName NewViewType "r" ) ) + ) + ( setarray ReplaceParamsTable Key ReplaceParams ) + (when NewCellView + ( setarray MappingTable Key NewCellView ) ) + ) ) ) ) ) + + ( foreach + Instance + ( getq TargetCellView instances ) + (let ( + ( Key + ( list + ( getq + Instance + libName + ) + ( getq + Instance + cellName + ) + ( getq + Instance + viewName + ) + ) ) ) + (let ( + ( NewCellView ( arrayref MappingTable Key ) ) + ( Params (if ( not ( arrayref ReplaceParamsTable Key ) ) + ( PCellGetParameterList Instance ) ) ) + ) + (when NewCellView + ( dbSetq Instance NewCellView master ) + ) + (when Params + ( PCellSetParameterList Instance Params ) ) + ) ) ) ) ) + + +(defun SwapInstanceMasterViews ( TargetCellView DestViewName DestViewType ) + (let ( + ( MasterMap ( makeTable `master nil ) ) ) + ( foreach Instance ( getq TargetCellView instances ) + (let ( + ( LibName ( getq Instance libName ) ) + ( CellName ( getq Instance cellName ) ) + ( ViewName ( getq Instance viewName ) ) ) + (if ( not ( arrayref MasterMap ( list LibName CellName ViewName ) ) ) + (if ( ddGetObj LibName CellName DestViewName ) + ( setarray + MasterMap + ( list LibName CellName ViewName ) + ( list LibName CellName DestViewName DestViewType ) ) ) ) ) ) + ( SwapSchematicMasters TargetCellView ( tableToList MasterMap ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/syncnetlist.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/syncnetlist.il new file mode 100644 index 0000000000..cdeeaf7668 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/syncnetlist.il @@ -0,0 +1,483 @@ +; Copyright 2011 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +defun( SyncNetlistGetInstanceParametersToSet ( ConnectivityInstanceName InstanceMap InstanceTable ) + let( ( Ret CurrInstances ConnecitivityInstanceParamPairs ParamName ParamValue ParaRet TotalWidth ExistingParam) + Ret=nil + CurrInstances=NameGetInstancesForCanonicalName( InstanceMap ConnectivityInstanceName ) + ConnecitivityInstanceParamPairs=InstanceTable["p"] + foreach( ParamName ConnecitivityInstanceParamPairs + ParamValue= ConnecitivityInstanceParamPairs[ParamName] + ParamRet=nil + ParamValueNum=if( stringp( ParamValue ) then + StringUtilParseLengthString( ParamValue ) else ParamValue ) + cond( + ; if chain width parameter, calculate total of all folds + ( rexMatchp( "^[NP]*[Ww]+[0-9]*$" ParamName ) + ParamRet= if( CurrInstances + then + TotalWidth= PDKCombineFolds( + mapcar( + (lambda ( CurrInstance ) + (let ( WidthValue ) + WidthValue=dbSearchPropByName( CurrInstance ParamName ) ~>value + if( WidthValue then + if( stringp( WidthValue ) + then StringUtilParseLengthString( WidthValue ) + else WidthValue ) + else -1e9 ) + ) + ) + CurrInstances + ) + ) + if( abs( TotalWidth - ParamValueNum )> 1e-10 + then list( ConnectivityInstanceName ParamName ParamValueNum/length(CurrInstances) TotalWidth ) + ) + else list( ConnectivityInstanceName ParamName ParamValueNum ) + ) + ) + ; all other parameter, compare value + ( t + if( CurrInstances then + foreach( CurrInstance CurrInstances + ExistingParam=dbSearchPropByName( CurrInstance ParamName ) + ParamRet= if( ExistingParam then + ExistingValue = ExistingParam~>value + ExistingValueNum = if( stringp( ExistingValue ) + then StringUtilParseLengthString( ExistingValue ) + else ExistingValue ) + if( abs( ExistingValueNum - ParamValueNum ) > 1e-10 + then list( ConnectivityInstanceName ParamName ParamValueNum ExistingValueNum ) + else ParamRet + ) + else list( ConnectivityInstanceName ParamName ParamValueNum ) + ) + ) + else ParamRet = list( ConnectivityInstanceName ParamName ParamValueNum ) ) + ) + ) + if( ParamRet Ret=cons( ParamRet Ret ) ) + ) + Ret + ) +) + +defun( SyncNetlistCompareCellInstances ( Instances InstanceMap ) + let( ( inst InstanceTable InstanceName InstanceNameExist InstancesToDelete InstancesToCreate InstancesToFix ParametersToSet InstancesToChange ) + + InstanceNameExist=nil + InstancesTable=NetListTable["i"] + InstancesToDelete=nil + InstancesToCreate=nil + InstancesToFix=nil + ParametersToSet=nil + InstancesToChange=nil + + foreach( Instance Instances + InstanceName=Instance~>name + CanonicalInstanceName = NameGetCanonicalInstanceNameForInstance( InstanceMap Instance ) + InstanceTable=InstancesTable[CanonicalInstanceName] + if( tablep( InstanceTable ) then + InstanceNameExist=cons( InstanceName InstanceNameExist ) + printf("Found %s\n" InstanceName) + if( Instance~>libName != InstanceTable["ln"] || Instance~>cellName != InstanceTable["cn"] then + InstancesToChange=cons( list( CanonicalInstanceName InstanceTable["ln"] InstanceTable["cn"] Instance Instance~>transform nil ) InstancesToChange ) + ) + ParametersToSet=append( ParametersToSet SyncNetlistGetInstanceParametersToSet( InstanceName InstanceMap InstanceTable )) + else + printf("Deleting %s\n" InstanceName) + InstancesToDelete=cons(Instance InstancesToDelete) + ) + ) + foreach( InstanceName InstancesTable + if( !member( InstanceName InstanceNameExist ) then + InstanceTable=InstancesTable[InstanceName] + printf("Creating %s\n" InstanceName) + InstancesToCreate=cons( list(InstanceName InstanceTable["ln"] InstanceTable["cn"] nil) InstancesToCreate) + ParametersToSet=append( ParametersToSet SyncNetlistGetInstanceParametersToSet( InstanceName InstanceMap InstanceTable )) + ) + ) + when( or( InstancesToDelete + InstancesToChange + InstancesToCreate + InstancesToFix + ParametersToSet ) + if( InstancesToCreate printf( "%L\n" InstancesToCreate ) ) + list( + InstancesToDelete + InstancesToChange + InstancesToCreate + InstancesToFix + ParametersToSet ) + ) + ) +) + +defun( SyncNetlistFindNetByInstTerm ( Instance InstTermName ) + let((netName instTerm) + netName=nil + foreach( instTerm Instance~>instTerms + if( instTerm~>name == InstTermName then netName=instTerm~>net~>name ) + ) + netName + ) +) + +defun( SyncNetlistCompareCellConnectivity ( CellView InstanceMap ) + let( ( ConnectionsToDelete ConnectionsToCreate TerminalsToDelete TerminalsToCreate NetsToDelete NetsToCreate NetsToChange + net term NetName TermName CurrentConnectionsToCreate ConnectionsToCreate) + NetsTable=NetListTable["n"] + InstancesTable=NetListTable["i"] + TerminalsList = setof( NetName NetsTable car(NetsTable[NetName] )) + ConnectionsToDelete=nil + ConnectionsToCreate=nil + foreach( InstanceName InstancesTable + CurrConnectivityInstTerms=InstancesTable[InstanceName]["c"] + CurrInstances = NameGetInstancesForCanonicalName( InstanceMap InstanceName ) + CurrentConnectionsToCreate=nil + CurrentConnectionsToDelete=nil + if( CurrInstances then + foreach( CurrInstance CurrInstances + ; CurrentConnectionsToCreate + foreach( TermName InstancesTable[InstanceName]["c"] + NetName=SyncNetlistFindNetByInstTerm(CurrInstance TermName) + ConnectivityNetName=CurrConnectivityInstTerms[TermName] + if( !NetName || NetName!=ConnectivityNetName then + CurrentConnectionsToCreate=cons( list( CurrInstance~>name TermName ConnectivityNetName ) CurrentConnectionsToCreate ) + ) + ) + ; CurrentConnectionsToDelete + CurrentConnectionsToDelete=setof( instTerm CurrInstance~>instTerm !CurrConnectivityInstTerms[instTerm~>name]) + ) + else + foreach( TermName CurrConnectivityInstTerms + CurrentConnectionsToCreate=cons( list( InstanceName TermName CurrConnectivityInstTerms[TermName] ) CurrentConnectionsToCreate ) + ) + ) + ConnectionsToDelete=append( ConnectionsToDelete CurrentConnectionsToDelete ) + ConnectionsToCreate=append( ConnectionsToCreate CurrentConnectionsToCreate ) + ) + TerminalsToDelete=setof( term CellView~>terminals !member( term~>name TerminalsList )) + TerminalsToCreate=setof( TermName TerminalsList !dbFindTermByName( CellView TermName )) + NetsToDelete = setof( net CellView~>nets !NetsTable[net~>name] ) + NetsToCreate = setof( NetName NetsTable !dbFindNetByName( CellView NetName )) + NetsToChange = nil ; wirelength and wirewidth parameteres are outdated + when( or( + ConnectionsToDelete + ConnectionsToCreate + TerminalsToDelete + TerminalsToCreate + NetsToDelete + NetsToCreate + NetsToChange + ) + list( + list( + ConnectionsToDelete + ConnectionsToCreate ) + list( + TerminalsToDelete + TerminalsToCreate ) + list( + NetsToDelete + NetsToCreate + NetsToChange ) + ) + ) + ) +) + +; To compare cell height and width in +defun( SyncNetlistCompareCellBoundary ( CellView LayoutViewName UserUnitsPerMeter LockBound ) + let( ( Shapes ExistingBoundaryBBox LibName CellName ViewName HeightOfExistingBoundary WidthOfExistingBoundary ConnectivityCellHeight ConnectivityCellWidth LayoutCellView LayoutBoundaryBBox ) + Shapes=CellView->shapes + ExistingBoundaryBBox = CellView~>prBoundary~>bBox + LibName=CellView->libName + CellName=CellView->cellName + ViewName=CellView->viewName + unless( LockBound && ExistingBoundaryBBox + HeightOfExistingBoundary = when( ExistingBoundaryBBox RectGetHeight( ExistingBoundaryBBox )/float(UserUnitsPerMeter) ) + WidthOfExistingBoundary = when( ExistingBoundaryBBox RectGetWidth( ExistingBoundaryBBox )/float(UserUnitsPerMeter) ) + PositionOfExistingBoundary = when( ExistingBoundaryBBox list( leftEdge( ExistingBoundaryBBox )/float(UserUnitsPerMeter) bottomEdge(ExistingBoundaryBBox)/float(UserUnitsPerMeter))) + ConnectivityCellHeight = NetlistTableGetCellHeight( NetlistTable ) + ConnectivityCellWidth = NetlistTableGetCellWidth( NetlistTable ) + ConnectivityBoundaryPosition = DirectivesTable["boundary_position"] + ConnectivityCellHeightWarning = DirectivesTable["boundary_height_warning"] + ConnectivityCellWidthWarning = DirectivesTable["boundary_width_warning"] + ConnectivityBoundaryPositionWarning = DirectivesTable["boundary_position_warning"] + LayoutCellView=nrOpenCellViewReadable( LibName CellName LayoutViewName ) + LayoutBoundaryBBox= when( LayoutCellView LayoutCellView~>prBoundary~>bBox ) + if( LayoutBoundaryBBox then + NewHeight=RectGetHeight(LayoutBoundaryBBox)/float(UserUnitsPerMeter) + NewWidth=RectGetWidth(LayoutBoundaryBBox)/float(UserUnitsPerMeter) + NewBoundaryPosition=list( leftEdge(LayoutBoundaryBBox)/float(UserUnitsPerMeter) bottomEdge(LayoutBoundaryBBox)/float(UserUnitsPerMeter)) + else + NewHeight=ConnectivityCellHeight + NewWidth=ConnectivityCellWidth + NewBoundaryPosition=ConnectivityBoundaryPosition + ) + HeightCompareResult= + if( HeightOfExistingBoundary && NewHeight then + when( abs( NewHeight - HeightOfExistingBoundary ) > 1e-10 + list( NewHeight HeightOfExistingBoundary ConnectivityCellHeightWarning ) + ) + else + when( NewHeight list( NewHeight nil ConnectivityCellHeightWarning )) + ) + WidthCompareResult= + if( WidthOfExistingBoundary && NewWidth then + when( abs( NewWidth - WidthOfExistingBoundary ) > 1e-10 + list( NewWidth WidthOfExistingBoundary ConnectivityCellWidthWarning ) + ) + else + when( NewWidth list( NewWidth nil ConnectivityCellWidthWarning )) + ) + PositionCompareResult= + if( PositionOfExistingBoundary then + when( abs( car(NewBoundaryPosition) - car(PositionOfExistingBoundary) ) > 1e-10 + || abs( cadr(NewBoundaryPosition) - cadr(PositionOfExistingBoundary) ) > 1e-10 + list( NewBoundaryPosition PositionOfExistingBoundary ConnectivityBoundaryPositionWarning ) + ) + else + list( NewBoundaryPosition nil ConnectivityBoundaryPositionWarning ) + ) + + + when( HeightCompareResult || WidthCompareResult || PositionCompareResult + list( + if( HeightCompareResult + HeightCompareResult + list( ConnectivityCellHeight nil ConnectivityCellHeightWarning ) ) + if( WidthCompareResult + WidthCompareResult + list( ConnectivityCellWidth nil ConnectivityCellWidthWarning ) ) + if( PositionCompareResult + PositionCompareResult + list( ConnectivityBoundaryPosition nil ConnectivityBoundaryPositionWarning ) ) + CellView~>prBoundary ) ) + + ) + ) +) + +defun( SyncNetlistComparePins ( CompareResult SuppressPins ForcePins ) + nil +) + +(defun SyncNetlistCompareCellView ( CellViewToCheck + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + InstanceMap + Instances + BoundaryLayerLPP + UserUnitsPerMeter + LockBound + SuppressPins + ForcePins + ) + (let ( isLeaf InstanceName InstanceTable ) + + isLeaf=nil + if( rexMatchp("floorplan" CellViewToCheck~>viewName) then + foreach( InstanceName NetListTable["i"] + InstanceTable=NetListTable["i"][InstanceName] + if( InstanceTable["ln"] == "gate" || InstanceTable["ln"] == "stack" then isLeaf=t ) + ) + ) + if(isLeaf then + NetListTable["i"]=makeTable( "tableOfInstancesTables" nil ) + ) + printf("Running SyncNetlistCompareCellInstances... isLeaf=%L\n" isLeaf) + InstancesCompareResult = SyncNetlistCompareCellInstances( Instances InstanceMap ) + println("Done: Running SyncNetlistCompareCellInstances.") + printf("Running SyncNetlistCompareCellConnectivity... isLeaf=%L\n" isLeaf) + ConnectivityCompareResult = SyncNetlistCompareCellConnectivity( CellViewToCheck InstanceMap ) + println("Done: Running SyncNetlistCompareCellConnectivity.") + if( CellViewToCheck->cellViewType == "maskLayout" && isLeaf then + println("Running SyncNetlistCompareCellBoundary...") + BoundaryCompareResult = SyncNetlistCompareCellBoundary( CellViewToCheck "layout" UserUnitsPerMeter LockBound ) + println("Done: Running SyncNetlistCompareCellBoundary.") + else BoundaryCompareResult = nil ) + PinCompareResult = nil + (when ( or + InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult + PinCompareResult ) + ( list + InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult + PinCompareResult + CellViewToCheck~>viewName + CellViewToCheck~>cellName + ) ) ) ) + + +(defun SyncNetlistGenFromSource ( TargetCellView + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + BoundaryLPP + UserUnitsPerMeter + @key + ( DoNotMoveExistingInstances t ) + ( Verbose t ) + ) + + (let ( Ret InstanceMap Istances ) + Ret= nil + InstanceMap= ( NameMakeEmptyInstanceMap ) + Instances= (when TargetCellView + ( UpdateNetlistFilterInstances + TargetCellView + LibCellExpressionPairsToIgnore ) ) + NamePopulateInstanceMapWithInstances( + InstanceMap + Instances + FoldableLibCellExpressionPairs ) + CompareResult= SyncNetlistCompareCellView( TargetCellView + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + InstanceMap Instances + BoundaryLPP + UserUnitsPerMeter + nil nil nil + ) + if( CompareResult || geGetSelectedSet() then + if( Verbose then println("Running UpdateNetlistPrintDifferences...") UpdateNetlistPrintDifferences( CompareResult poport ) ) + println("Running UpdateNetlistUpdateCellViewWithCompareResult...") + Ret = UpdateNetlistUpdateCellViewWithCompareResult( + TargetCellView + CompareResult + InstanceMap + BoundaryLPP + UserUnitsPerMeter + ?DoNotMoveExistingInstances DoNotMoveExistingInstances + ) + println("Done: UpdateNetlistUpdateCellViewWithCompareResult") + if( Ret then printf( "Error: %L\n" Ret ) ) + ) + Ret + ) +) + + +(defun SyncNetlistGenFromSkillNetlistUsingPDKInfo ( TargetCellView + SkillNetlistDir + SkillDirectivesDir + @key + ( LibCellsToIgnore nil ) + ( DoNotMoveExistingInstances t ) + ) + let( ( ) + NetlistTable = NetlistTableGetSkillNetlistTableForCellName( TargetCellView~>cellName SkillNetlistDir ) + if( tablep( NetlistTable ) then + DirectivesTable= CellInfoGetTableForCellName( TargetCellView~>cellName SkillDirectivesDir ) + if( tablep( DirectivesTable ) then + TransformedNetlistTable=InlineConnectionsHierTransformTable( + NetlistTable + UpdateNetlistGetDefaultShouldInLineConnectionsFunc( ) + list( DirectivesTable SkillDirectivesDir ) + SkillNetlistDir ) + TransformedNetlistsTablesTable=makeTable( "tableOfNetlistTables" nil ) + TransformedNetlistsTablesTable[TargetCellView~>viewName]=TransformedNetlistTable + InstancesTable=NetListTable["i"] + NetsTable=NetListTable["n"] + StatisticsTable=NetListTable["s"] + ; if viewName=="floorplan" && subcell libName == "gate" || "stack", delete all subcells from NetListTable + LibCellExpressionPairsToIgnore= + append( LibCellsToIgnore + append( WiringCellLibCellPairRegExs + TechLibExceptTransistorsLibCellPairRegExs + ) ) + FoldableLibCellExpressionPairs=FoldableCellLibCellPairRegExs + SyncNetlistGenFromSource( + TargetCellView + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + BoundaryLPP + UserUnitsPerMeter + ?DoNotMoveExistingInstances DoNotMoveExistingInstances + ) + + else DirectivesTable ) + else NetlistTable ) + ) +) + +defun( SyncNetlistInitFloorplan ( CellView InstancesToCreate InstanceMap + @key + ( DoNotMoveExistingInstances t ) + ) + let( (InstanceToCreate InstName InstLibName InstCellName InstTransform InstancesTable) + InstancesTable=car( InstanceMap ) + GatesToCreate = nil + PStacksToCreate = nil + NStacksToCreate = nil + SubcellsToCreate = nil + println(InstancesToCreate) + foreach( InstanceToCreate InstancesToCreate + InstName = UpdateNetlistGetInstanceNameFromInstanceToCreate( InstanceToCreate ) + InstLibName = UpdateNetlistGetLibNameFromInstanceToCreate( InstanceToCreate ) + InstCellName = UpdateNetlistGetCellNameFromInstanceToCreate( InstanceToCreate ) + InstTransform = UpdateNetlistGetInstanceTransformFromInstanceToCreate( InstanceToCreate ) + cond( + ( InstLibName == "gate" + GatesToCreate=cons( InstancesTable[InstName] GatesToCreate ) + ) + ( InstLibName == "stack" + cond( + ( rexMatchp( "NMOS" InstCellName ) NStacksToCreate=cons( InstancesTable[InstName] NStacksToCreate )) + ( rexMatchp( "PMOS" InstCellName ) PStacksToCreate=cons( InstancesTable[InstName] PStacksToCreate )) + ( t GatesToCreate=cons( InstancesTable[InstName] GatesToCreate )) + ) + ) + ( t + SubcellsToCreate=cons( InstName SubcellsToCreate ) + ) + ) + ) + + if( GatesToCreate || PStacksToCreate || NStacksToCreate then + CurrX=rightEdge(CellView~>bBox)+6.0 + CurrY=0.0 + foreach( instances PStacksToCreate + foreach( inst instances + inst~>xy=list( CurrX CurrY ) + CurrY=topEdge(inst~>bBox)+0.04 + ) + ) + CurrX=rightEdge(CellView~>bBox)+6.0 + CurrY=0.0 + foreach( instances NStacksToCreate + foreach( inst instances + inst~>xy=list( CurrX CurrY ) + CurrY=topEdge(inst~>bBox)+0.04 + ) + ) + CurrX=rightEdge(CellView~>bBox)+6.0 + CurrY=0.0 + foreach( instances GatesToCreate + foreach( inst instances + inst~>xy=list( CurrX CurrY ) + CurrY=topEdge(inst~>bBox)+0.04 + ) + ) + else + ; flInitFloorplan + CurrX=if( DoNotMoveExistingInstances rightEdge(CellView~>bBox) 0.0) + CurrY=0.0 + flInitFloorplanWithInstOrderList( CellView~>libName CellView~>cellName CellView~>viewName + ?SubcellsToCreate SubcellsToCreate + ?DoNotMoveExistingInstances DoNotMoveExistingInstances + ?x_offset CurrX + ?y_offset CurrY + ?RunSyncToNetlist nil + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/update_floorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/update_floorplan.il new file mode 100644 index 0000000000..e87fc96da8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/update_floorplan.il @@ -0,0 +1,267 @@ +; Much faster alternative to SyncToNetlist. Great for supersize +; floorplanning iterations. Includes net connectivity and pcells in +; layout leaf cells. +; +; Author: a very impatient person +; +; TODO: Place pcells in leaf cells according to better heuristic. + +; user interface +(defun UpdateFloorplan + (@key (CV (geGetEditCellView)) ; provide a CV + (libName nil) (cellName nil) (viewName "floorplan") ; or lib/cell/view names + (recurse t) ; recursively update subcells + (cast2skill t) ; run cast2skill first + (verbose nil) ; spam net and parameter changes too + ) + (let (mastersVisited cmd temp dir routed LOG pcre) + + ; open CV + (when cellName + (unless libName libName = (GetCastLibName cellName)) + CV = (UpdateFloorplanOpenCV libName cellName viewName) + ) + routed = (CV->viewName!="floorplan" && CV->viewName!="prelayout") + + ; call cast2skill + temp = (ConfigFileGetValue TheCDSConfigTable "TEMP") + dir = (sprintf nil "%s/ilnets" temp) + cmd = (sprintf nil + (strcat "%s/cast2skill --max-heap-size=4G --cadence-name " + "--suppress-pins --suppress-wiring-directives " + "--function-prefix=UpdateFloorplan " + "--cast-path=%s --cell=%s --output-dir=%s %s " + " &> %s/cast2skill.log") + (PackageGetBinRoot) + (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + CV->cellName + dir + (if routed "--routed" "") + temp + ) + (when cast2skill (shell cmd)) + + ; compile regular expression to identify arrays + pcre = (pcreCompile "\\[[0-9]+\\][^\\[]*$") + + ; update floorplan + LOG = (outfile (strcat temp "/UpdateFloorplan.log")) + mastersVisited = (makeTable "mastersVisited" nil) + (UpdateFloorplanCore CV "") + (close LOG) + CV + ) + ) + +; process one cell +(defun UpdateFloorplanCore (CV indent) + (let (file NetListTable rx ux uy w h instanceTable netTable termTable + lastArrayName layoutCV points realInstances) + (fprintf LOG "%sUpdate floorplan of %s\n" indent CV->cellName) + mastersVisited[CV] = t + + ; coordinates for new instances + rx = (car (cadr (CV->bBox))) + ux = rx + uy = 0.0 + + ; track correct instances and nets and terms + instanceTable = (makeTable "instanceTable" nil) + netTable = (makeTable "netTable" nil) + termTable = (makeTable "termTable" nil) + lastArrayName = nil + + ; load netlist.il + file = (strcat dir "/ilnets/" CV->cellName ".netlist.il") + (load file) + + ; delete incorrect nets + (foreach net CV->nets + (unless netTable[net] + (when verbose (fprintf LOG "%sDelete net %s\n" indent net->name)) + (dbDeleteObject net) + ) + ) + + ; delete incorrect terminals + (foreach term CV->terminals + (unless termTable[term] + (when verbose (fprintf LOG "%sDelete term %s\n" indent term->name)) + (dbDeleteObject term) + ) + ) + + ; delete incorrect instances + (foreach inst CV->instances + (unless instanceTable[inst] || (IsWiringCell CV) + (fprintf LOG "%sDelete instance %s of %s\n" indent inst->name inst->cellName) + (dbDeleteObject inst) + ) + ) + + ; update prBoundary, from layout view if it exists + (when CV->prBoundary (dbDeleteObject CV->prBoundary)) + (unless realInstances + (when CV->viewName=="floorplan" && (ddGetObj CV->libName CV->cellName "layout") + layoutCV = (dbOpenCellViewByType CV->libName CV->cellName "layout" "maskLayout" "r") + points = layoutCV->prBoundary->points + ) + (unless points + w = NetListTable["width"] + h = NetListTable["height"] + points = (list 0:0 w:0 w:h 0:h 0:0) + ) + (dbCreatePRBoundary CV points) + ) + + ; save + (dbSave CV) + ) + ) + +; Open a CellView and create lib if necessary +(defun UpdateFloorplanOpenCV (libName cellName viewName) + (let (lib libDir mode) + (unless (ddGetObj libName) + libDir = (strcat (ConfigFileGetValue TheCDSConfigTable "DFII_DIR") "/" + (buildString (parseString libName ".") "/")) + (shell (strcat "mkdir -p " libDir)) + lib = (dbCreateLib libName libDir) + (techBindTechFile lib TechLibName "techfile.cds" t) + ) + mode = (if (IsCellViewWritable libName cellName viewName) "a" "r") + (dbOpenCellViewByType libName cellName viewName "maskLayout" mode) + ) + ) + +; Improved function to see if a CV is writable +(defun IsCellViewWritable (libName cellName viewName) + (let (ddObj) + ddObj = (ddGetObj libName cellName viewName) + !ddObj || ; assume you can create CV if it doesn't exist + (ddIsObjWritable ddObj) && ; database object must not be locked + !(setof f ddObj->files !(ddIsObjWritable f)) ; all files must be writable + ) + ) + +;;;;;;;;;;;;;;;;; functions called by cast2skill netlist.il files ;;;;;;;;;;;;;;;;;;;; + +(defun UpdateFloorplanCreateInstanceInNetlist (table instName libName cellName) + (let (inst master viewName w h x0 y0 arrayName gate_stack) + gate_stack = libName=="gate" || libName=="stack" || libName==TechLibName + realInstances = realInstances || !gate_stack + (when CV->viewName!="floorplan" || !gate_stack + ; find existing inst and its viewName + inst = (dbFindAnyInstByName CV instName) + viewName = (if inst inst->viewName CV->viewName) + + ; recurse into master + master = (dbOpenCellViewByType libName cellName viewName "maskLayout" "r") + (when !master || recurse && !mastersVisited[master] && master->viewName==CV->viewName + master = (UpdateFloorplanOpenCV libName cellName CV->viewName) + (when master->mode=="a" (UpdateFloorplanCore master (strcat indent " "))) + ) + (unless master + (error "Unable to create libName=%s cellName=%s viewName=%s\n" + libName cellName viewName) + ) + + ; add instance + arrayName = (pcreReplace pcre instName "" 0) + (unless inst + w = (car (cadr master->bBox)) - (car (car master->bBox)) + h = (cadr (cadr master->bBox)) - (cadr (car master->bBox)) + (cond (lastArrayName==arrayName + x0 = ux + y0 = uy + rx = (max ux+w rx) + uy = uy+h) + (t + x0 = rx + y0 = 0 + ux = rx + uy = h + rx = rx+w) + ) + x0 = x0 - (car (car master->bBox)) + y0 = y0 - (cadr (car master->bBox)) + (fprintf LOG "%sCreate instance %s of %s\n" indent instName cellName) + inst = (dbCreateInst CV master instName x0:y0 "R0") + ) + (unless inst->master==master + (fprintf LOG "%sChange master of instance %s to %s\n" indent instName cellName) + inst->master = master + ) + lastArrayName = arrayName + instanceTable[inst] = t + (foreach term inst->terminals (dbDeleteObject term)) ; delete old connections + ) + ) + ) + +(defun UpdateFloorplanCreateEmptyNetlistTable (libName cellName) + (makeTable "NetListTable" nil) + ) + +(defun UpdateFloorplanAddTerminal (table termName) + (let (net term) + net = (dbMakeNet CV termName) + term = (dbFindTermByName CV termName) + (unless term + term=(dbCreateTerm net termName "inputOutput") + (when verbose (fprintf LOG "%sCreate term %s\n" indent termName)) + ) + netTable[net] = t + termTable[term] = t + ) + ) + +(defun UpdateFloorplanAddNet (table netName) + (let (net) + net = (dbFindNetByName CV netName) + (unless net + net = (dbMakeNet CV netName) + (when verbose (fprintf LOG "%sCreate net %s\n" indent netName)) + ) + netTable[net] = t + ) + ) + +(defun UpdateFloorplanAddConnectionToInstanceInNetlist (table instName termName netName) + (let (inst term net) + ; too spammy, since I can't figure out how to detect if connection changed + ;(when verbose + ; (fprintf LOG "%sAdding instance term to inst=%s term=%s net=%s\n" + ; indent instName termName netName) + ; ) + net = (dbFindNetByName CV netName) + inst = (dbFindAnyInstByName CV instName) + (when inst + term = (dbFindTermByName inst->master termName) + (when term && net (dbCreateInstTerm net inst term)) + ) + ) + ) + + (defun UpdateFloorplanAddParameterToInstanceInNetlist (table instName parmName parmValue) + (let (inst prop) + inst = (dbFindAnyInstByName CV instName) + (when inst + prop = (dbFindProp inst parmName) + (unless prop && prop->valueType=="float" && prop->value==parmValue + (dbReplaceProp inst parmName "float" (StringUtilParseLengthString parmValue)) + (when verbose + (fprintf LOG "%sSet parameter %s in instance %s to %s\n" + indent parmName instName parmValue) + ) + ) + ) + ) + ) + +(defun UpdateFloorplanSetTotalTransistorCount (table count) nil) +(defun UpdateFloorplanSetTotalTransistorGateArea (table area) nil) +(defun UpdateFloorplanSetTotalTransistorWidth (table width) nil) +(defun UpdateFloorplanSetTotalTransistorLength (table length) nil) +(defun UpdateFloorplanSetCellWidth (table width) table["width"] = width*1e6) +(defun UpdateFloorplanSetCellHeight (table height) table["height"] = height*1e6) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/updatenetlist.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/updatenetlist.il new file mode 100644 index 0000000000..e07f94f402 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/schematic/updatenetlist.il @@ -0,0 +1,4521 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +defun( UpdateNetlistTablifyNets ( CellView TargetTable ) + foreach( Net CellView~>nets + TargetTable[Net~>name] = Net + ) +) + +defun( UpdateNetlistTablifyTerminals ( CellView TargetTable ) + foreach( Term CellView~>terminals + TargetTable[Term~>name] = Term + ) +) + +defun( UpdateNetlistTablifyInstanceTerms ( Instance TargetTable ) + foreach( InstTerm Instance~>conns + TargetTable[InstTerm~>term~>name] = InstTerm + ) +) + +defun( UpdateNetlistCompareConnections ( InstTerm1 InstTerm2 ) + InstTerm1 && InstTerm2 && InstTerm1~>net~>name==InstTerm2~>net~>name && InstTerm1~>name==InstTerm2~>name +) + +(defun UpdateNetlistGetInstancesToDelete ( Instances + InstanceMap + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams ) + ( setof + Instance + Instances + ( null + ( apply + ConnectivityInstanceExistsFunc + ( cons + ( NameGetCanonicalInstanceNameForInstance InstanceMap Instance ) + ConnectivityInstanceExistsFuncParams ) ) ) ) ) + + +(defun UpdateNetlistGetInstancesToFix ( Instances ) + nil ) + + +(defun UpdateNetlistGetInstanceCoincidences ( Instances + InstanceMap + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + ) + temp=( Partition + Instances + (lambda ( Instance ) + (let ( + ( CanonicalInstanceName + ( NameGetCanonicalInstanceNameForInstance + InstanceMap + Instance ) ) ) + (let ( + ( Transform + ( apply + ConnectivityGetInstanceTransformFunc + ( cons + CanonicalInstanceName + ConnectivityGetInstanceTransformFuncParams ) ) ) + ( LibName + ( apply + ConnectivityGetInstanceMasterLibNameFunc + ( cons + CanonicalInstanceName + ConnectivityGetInstanceMasterLibNameFuncParams ) ) ) + ( CellName + ( apply + ConnectivityGetInstanceMasterCellNameFunc + ( cons + CanonicalInstanceName + ConnectivityGetInstanceMasterCellNameFuncParams ) ) ) + ) + ( list + ( list + LibName + CellName ) + (when Transform + ( list + ( mapcar + (lambda ( Coord ) ( MathRoundToNearest Coord 1e-3 ) ) + ( car Transform ) ) + ( cadr Transform ) ) ) ) + + ) ) ) ) ) + + +(defun UpdateNetlistGetInstancesToChange ( Instances + InstanceMap + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + + ) + + (let ( + ( InstanceCoincidences + ( UpdateNetlistGetInstanceCoincidences + Instances + InstanceMap + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + ) ) ) + ( ListApplyFuncToListAndAccumulateNonNilResults + Instances + (lambda ( Instance + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) + (let ( + ( CanonicalInstanceName + ( NameGetCanonicalInstanceNameForInstance InstanceMap Instance ) ) ) + (let ( + ( InstanceTransform ( getq Instance transform ) ) + ( ConnectivityInstanceMasterLibName + ( apply + ConnectivityGetInstanceMasterLibNameFunc + ( cons + CanonicalInstanceName + ConnectivityGetInstanceMasterLibNameFuncParams ) ) ) + ( ConnectivityInstanceMasterCellName + ( apply + ConnectivityGetInstanceMasterCellNameFunc + ( cons + CanonicalInstanceName + ConnectivityGetInstanceMasterCellNameFuncParams ) ) ) + ( ConnectivityInstanceTransform + ( apply + ConnectivityGetInstanceTransformFunc + ( cons + CanonicalInstanceName + ConnectivityGetInstanceTransformFuncParams ) ) ) ) + (when ( or + ;coincidences + ( and + ;the location is not null + ( cadr + ( car + ( arrayref InstanceCoincidences + Instance ) ) ) + ;there is more than one instance at the location + ( greaterp + ( length + ( cadr + ( arrayref InstanceCoincidences + Instance ) ) ) + 1 ) ) + ( not + ( or + ( null ConnectivityInstanceMasterLibName ) + ( null ConnectivityInstanceMasterCellName ) + ( and + ( equal + CanonicalInstanceName + ( getq Instance name ) ) + ( equal + ConnectivityInstanceMasterCellName + ( getq Instance cellName ) ) + ( equal + ConnectivityInstanceMasterLibName + ( getq Instance libName ) ) + ( or + ( null ConnectivityInstanceTransform ) + (let ( + ( InstancePos ( car InstanceTransform ) ) + ( InstanceRotation ( cadr InstanceTransform ) ) + ( ConnectivityInstancePos ( car ConnectivityInstanceTransform ) ) + ( ConnectivityInstanceRotation ( cadr ConnectivityInstanceTransform ) ) ) + ( and + ( lessp + ( abs + ( difference + ( car InstancePos ) + ( car ConnectivityInstancePos ) ) ) + ( quotient 0.0001 1000000.0 ) ) + ( lessp + ( abs + ( difference + ( cadr InstancePos ) + ( cadr ConnectivityInstancePos ) ) ) + ( quotient 0.0001 1000000.0 ) ) + ( equal InstanceRotation ConnectivityInstanceRotation ) ) ) ) ) ) ) ) + ( list + CanonicalInstanceName + ConnectivityInstanceMasterLibName + ConnectivityInstanceMasterCellName + Instance + ConnectivityInstanceTransform + ( arrayref InstanceCoincidences Instance ) + ) ) ) ) ) + ( list + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) ) ) ) + +(defun UpdateNetlistGetInstancesToCreate ( InstanceMap + ConnectivityInstanceNames + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) + + ( ListApplyFuncToListAndAccumulateNonNilResults + ConnectivityInstanceNames + (lambda + ( ConnectivityInstanceName + InstanceMap + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) + (unless ( NameGetInstancesForCanonicalName InstanceMap ConnectivityInstanceName ) + ( list + ConnectivityInstanceName + ( apply + ConnectivityGetInstanceMasterLibNameFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceMasterLibNameFuncParams ) ) + ( apply + ConnectivityGetInstanceMasterCellNameFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceMasterCellNameFuncParams ) ) + ( apply + ConnectivityGetInstanceTransformFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceTransformFuncParams ) ) ) ) ) + list( + InstanceMap + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) ) ) + +(defun UpdateNetlistGetInstanceParametersToSet ( InstanceMap + ConnectivityInstanceNames + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams ) + (let ( + ( Ret nil ) ) + ( foreach + ConnectivityInstanceName + ConnectivityInstanceNames + (let ( + ( CurrInstances + ( NameGetInstancesForCanonicalName + InstanceMap ConnectivityInstanceName ) ) + ( ConnecitivityInstanceParamPairs + ( apply + ConnectivityGetInstanceParameterPairsFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceParameterPairsFuncParams ) ) ) ) + ( foreach + ParamPair + ConnecitivityInstanceParamPairs + (let ( + ( ParamName ( car ParamPair ) ) + ( ParamValue ( cadr ParamPair ) ) ) + (let ( + ( ParamRet nil ) + ( ParamValueNum + (if ( stringp ParamValue ) + ( StringUtilParseLengthString ParamValue ) + ParamValue ) ) ) + (cond ( + ;chain width, check all folds + ( rexMatchp "^[NP]*[Ww]+[0-9]*$" ParamName ) + ( setq ParamRet + (if CurrInstances + (let ( + ( TotalWidth + ( PDKCombineFolds + ( mapcar + (lambda ( CurrInstance ) + (let ( + ( WidthValue + ( getq + ( dbSearchPropByName + CurrInstance + ParamName ) + value ) ) ) + (if WidthValue + (if ( stringp WidthValue ) + ( StringUtilParseLengthString WidthValue ) + WidthValue ) + -1e9 ) ) ) + CurrInstances ) ) ) ) + + (if ( greaterp + ( abs + ( difference + TotalWidth + ParamValueNum ) ) + ( quotient 0.0001 1000000.0 ) ) + ( list ConnectivityInstanceName + ParamName + ( quotient ParamValueNum ( length CurrInstances ) ) + TotalWidth ) ) ) + ( list ConnectivityInstanceName ParamName ParamValueNum ) ) ) ) + ( + t + (if CurrInstances + ( foreach CurrInstance CurrInstances + (let ( + ( ExistingParam + ( dbSearchPropByName + CurrInstance + ParamName ) ) ) + ( setq ParamRet + (if ExistingParam + (let ( + ( ExistingValue ( getq ExistingParam value ) ) ) + (let ( + ( ExistingValueNum + (if ( stringp ExistingValue ) + ( StringUtilParseLengthString + ExistingValue ) + ExistingValue ) ) ) + (if ( greaterp + ( abs + ( difference + ExistingValueNum + ParamValueNum ) ) + ( quotient 0.0001 1000000.0 ) ) + ( list ConnectivityInstanceName ParamName ParamValueNum ExistingValueNum ) + ParamRet ) ) ) + ( list ConnectivityInstanceName ParamName ParamValueNum ) ) ) ) ) + ( setq ParamRet ( list ConnectivityInstanceName ParamName ParamValueNum ) ) ) ) ) + + (if ParamRet + ( setq Ret ( cons ParamRet Ret ) ) ) ) ) ) ) ) + Ret ) ) + +(defun UpdateNetlistCompareCellInstances ( Instances + InstanceMap + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityInstanceNames + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) + (let ( + ( InstancesToDelete ( UpdateNetlistGetInstancesToDelete + Instances + InstanceMap + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams ) ) + ( InstancesToCreate ( UpdateNetlistGetInstancesToCreate + InstanceMap + ConnectivityInstanceNames + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) ) + ( InstancesToFix ( UpdateNetlistGetInstancesToFix + Instances ) ) + ( ParametersToSet ( UpdateNetlistGetInstanceParametersToSet + InstanceMap + ConnectivityInstanceNames + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams ) ) + ) + (let ( + ( InstancesToChange ( UpdateNetlistGetInstancesToChange + ( ListDifferenceNoTableElements + Instances + InstancesToDelete + ) + InstanceMap + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) ) + ) + + (when ( or InstancesToDelete + InstancesToChange + InstancesToCreate + InstancesToFix + ParametersToSet ) + (when InstancesToCreate + ( printf "%L\n" InstancesToCreate ) ) + tempCompareCellInstances = ( list + InstancesToDelete + InstancesToChange + InstancesToCreate + InstancesToFix + ParametersToSet ) ) ) ) ) + +(defun UpdateNetlistGetBoundaryLayerBBox ( CellView BoundaryLPP Recurse ) + (when CellView + (if CellView->prBoundary CellView->prBoundary->bBox ) ) ) + + +(defun UpdateNetlistCompareCellBoundary ( CellView + ConnectivityInstanceNames + BoundaryLayerLPP + UserUnitsPerMeter + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams + LockBound ) + + (let ( + ( Shapes ( getq CellView shapes ) ) + ( ExistingBoundaryBBox ( UpdateNetlistGetBoundaryLayerBBox CellView BoundaryLayerLPP nil ) ) + ( LibName ( getq CellView libName ) ) + ( CellName ( getq CellView cellName ) ) + ( ViewName ( getq CellView viewName ) ) ) + ;If we are allowed to change the boundary + ;or if there is no boundary shape then figure + ;out what the boundayr shape should be and compare + ;that to the boundary shape in the cell. + (unless ( and LockBound ExistingBoundaryBBox ) + (let ( + ;Get Height and width of existing shape. + ( HeightOfExistingBoundary (when ExistingBoundaryBBox + ( quotient + ( RectGetHeight ExistingBoundaryBBox ) + ( float UserUnitsPerMeter ) ) ) ) + ( WidthOfExistingBoundary (when ExistingBoundaryBBox + ( quotient + ( RectGetWidth ExistingBoundaryBBox ) + ( float UserUnitsPerMeter ) ) ) ) ) + (let ( + ;Ask the netlist what it thinks the height should be. + ;See UpdateNetlistGetDefaultGetFloorplanViewHeightFunc, + ;UpdateNetlistGetDefaultGetLayoutViewHeightFunc, and + ;UpdateNetlistGetDefaultGetNetlistViewHeightFunc which are all called + ;by the lambda function returned by UpdateNetlistGetDefaultGetCellHeightFunc. + ;If the ConnectivityGetCellHeightFunc returns nil then this function will return nil, + ;otherwise the ConnectivityGetCellHeightFunc should return a pair + ;whose first element is the desired height of the cell and whose second element is nil + ;or a string containing a warning message. + ( ConnectivityCellHeightRet ( apply + ConnectivityGetCellHeightFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + HeightOfExistingBoundary + ( cons + ConnectivityInstanceNames + ConnectivityGetCellHeightFuncParams ) ) ) ) ) ) ) ) + (when ConnectivityCellHeightRet + (let ( + ( ConnectivityCellHeight ( car ConnectivityCellHeightRet ) ) + ( ConnectivityCellHeightWarning ( cadr ConnectivityCellHeightRet ) ) ) + (let ( + ( HeightCompareResult (if HeightOfExistingBoundary + (when ( greaterp + ( abs + ( difference + HeightOfExistingBoundary + ConnectivityCellHeight ) ) + ( quotient + 0.0001 + 1000000 ) ) + ( list + ConnectivityCellHeight + HeightOfExistingBoundary + ConnectivityCellHeightWarning ) ) + ( list + ConnectivityCellHeight + nil + ConnectivityCellHeightWarning ) ) ) ) + ;check width if there aren't any non-pin, non-label, non-boundary shapes + ;and there are no connectivity instances. In other words if the cell + ;contains any shapes that we are not expecting assume the width in the + ;cell is correct. + (if ( not + ( or + ( exists + Shape + Shapes + ( and + ( not + ( equal ( getq Shape lpp ) + BoundaryLayerLPP ) ) + ( null ( getq Shape pin ) ) + ( not ( equal ( getq Shape objType ) "label" ) ) ) ) + ConnectivityInstanceNames ) ) + (let ( + ;Find the DB object for the existing boundary if there is one + ;so that we can put it in our return value so people using our return + ;value won't have to go looking for it. + ( ExistingBoundary CellView->prBoundary ) + + ;Ask the netlist what it thinks the width should be. + ;See UpdateNetlistGetDefaultGetLayoutViewWidthFunc, UpdateNetlistGetDefaultGetFloorplanViewWidthFunc, + ;and UpdateNetlistGetDefaultGetNetlistViewWidthFunc which are all called + ;by the lambda function returned by UpdateNetlistGetDefaultGetCellWidthFunc. + ;If the ConnectivityEstimateCellWidthFunc returns nil then this function will return nil, + ;otherwise the ConnectivityEstimateCellWidthFunc should return a pair + ;whose first element is the desired width of the cell and whose second elementn is nil + ;or a string containing a warning message. + ( ConnectivityEstimatedCellWidthRet + ( apply + ConnectivityEstimateCellWidthFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + ConnectivityCellHeight + ConnectivityEstimateCellWidthFuncParams ) ) ) ) ) ) ) + (let ( + ( ConnectivityEstimatedCellWidth ( car ConnectivityEstimatedCellWidthRet ) ) + ( ConnectivityCellWidthWarning ( cadr ConnectivityEstimatedCellWidthRet ) ) ) + (when ConnectivityEstimatedCellWidth + ;If the width was successfully estimated + (let ( + ;Ask the netlist wheree the boundary should be positioned in the cell. + ;See UpdateNetlistGetDefaultGetNetlistViewPositionFunc, UpdateNetlistGetDefaultGetLayoutViewPositionFunc, + ;and UpdateNetlistGetDefaultGetFloorplanViewPositionFunc which are all called by the + ;lambda function returned by UpdateNetlistGetDefaultGetCellPositionFunc. + ;If the ConnectivityGetBoundaryPositionFunc returns nil then this function will return nil, + ;otherwise the ConnectivityGetBoundaryPositionFunc should return a pair + ;whose first element is the desired position of the cell boundayr and whose second element is nil + ;or a string containing a warning message. + ( ConnectivityBoundaryPositionRet ( apply + ConnectivityGetBoundaryPositionFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ConnectivityGetBoundaryPositionFuncParams ) ) ) ) ) ) + (let ( + ( ConnectivityBoundaryPosition ( car ConnectivityBoundaryPositionRet ) ) + ( ConnectivityBoundaryPositionWarning ( cadr ConnectivityBoundaryPositionRet ) ) ) + (when ConnectivityBoundaryPosition + (let ( + ( PositionOfExistingBoundary (when ExistingBoundaryBBox + ( list + ( quotient + ( RectGetLeft ExistingBoundaryBBox ) + ( float UserUnitsPerMeter ) ) + ( quotient + ( RectGetBottom ExistingBoundaryBBox ) + ( float UserUnitsPerMeter ) ) ) ) ) ) + ;Compare width and position of boundary to netlist. + (let ( + ( WidthCompareResult (if WidthOfExistingBoundary + (when ( greaterp + ( abs + ( difference + WidthOfExistingBoundary + ConnectivityEstimatedCellWidth ) ) + ( quotient + 0.0001 + 1000000 ) ) + ( list + ConnectivityEstimatedCellWidth + WidthOfExistingBoundary + ConnectivityCellWidthWarning ) ) + ( list ConnectivityEstimatedCellWidth nil ConnectivityCellWidthWarning ) ) ) + ( PositionCompareResult (if PositionOfExistingBoundary + (let ( + ( ConnectivityBoundaryXPos + ( car ConnectivityBoundaryPosition ) ) + ( ConnectivityBoundaryYPos + ( cadr ConnectivityBoundaryPosition ) ) + ( XPosOfExistingBoundary + ( car PositionOfExistingBoundary ) ) + ( YPosOfExistingBoundary + ( cadr PositionOfExistingBoundary ) ) ) + (when ( or + ( greaterp + ( abs + ( difference + ConnectivityBoundaryXPos + XPosOfExistingBoundary ) ) + ( quotient + 0.0001 + 1000000 ) ) + ( greaterp + ( abs + ( difference + ConnectivityBoundaryYPos + YPosOfExistingBoundary ) ) + ( quotient + 0.0001 + 1000000 ) ) ) + ( list + ConnectivityBoundaryPosition + PositionOfExistingBoundary + ConnectivityBoundaryPositionWarning ) ) ) + ( list ConnectivityBoundaryPosition + nil + ConnectivityBoundaryPositionWarning ) ) ) ) + (when ( or HeightCompareResult WidthCompareResult PositionCompareResult ) + ( list + (if HeightCompareResult + HeightCompareResult + ( list ConnectivityCellHeight nil ConnectivityCellHeightWarning ) ) + (if WidthCompareResult + WidthCompareResult + ( list ConnectivityEstimatedCellWidth nil ConnectivityCellWidthWarning ) ) + (if PositionCompareResult + PositionCompareResult + ( list ConnectivityBoundaryPosition nil ConnectivityBoundaryPositionWarning ) ) + ExistingBoundary ) ) ) ) ) ) ) ) ) ) + (when HeightCompareResult + ( list + HeightCompareResult + nil + nil + nil ) ) ) ) ) ) ) ) ) ) ) + + +(defun UpdateNetlistCompareEmptyCellBoundary ( ConnectivityInstanceNames + LibName + CellName + ViewName + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams ) + (unless ConnectivityInstanceNames + (let ( + ( ConnectivityCellHeightRet ( apply + ConnectivityGetCellHeightFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + nil + ( cons + ConnectivityInstanceNames + ConnectivityGetCellHeightFuncParams ) ) ) ) ) ) ) ) + + + + (let ( + ( ConnectivityCellHeight ( car ConnectivityCellHeightRet ) ) + ( ConnectivityCellHeightWarning ( cadr ConnectivityCellHeightRet ) ) ) + (when ConnectivityCellHeightRet + (let ( + ( ConnectivityEstimatedCellWidthRet ( apply + ConnectivityEstimateCellWidthFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + ConnectivityCellHeight + ConnectivityEstimateCellWidthFuncParams ) ) ) ) ) ) ) + (let ( + ( ConnectivityEstimatedCellWidth ( car ConnectivityEstimatedCellWidthRet ) ) + ( ConnectivityEstimatedCellWidthWarning ( cadr ConnectivityEstimatedCellWidthRet ) ) ) + (when ConnectivityEstimatedCellWidthRet + (let ( + ( ConnectivityBoundaryPositionRet ( apply + ConnectivityGetBoundaryPositionFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ConnectivityGetBoundaryPositionFuncParams ) ) ) ) ) ) + (let ( + ( ConnectivityBoundaryPosition ( car ConnectivityBoundaryPositionRet ) ) + ( ConnectivityBoundaryPositionWarning ( cadr ConnectivityBoundaryPositionRet ) ) ) + (when ConnectivityBoundaryPositionRet + ( list + ( list ConnectivityCellHeight nil ConnectivityCellHeightWarning ) + ( list ConnectivityEstimatedCellWidth nil ConnectivityEstimatedCellWidthWarning ) + ( list ConnectivityBoundaryPosition nil ConnectivityBoundaryPositionWarning ) + nil ) ) ) ) ) ) ) ) ) ) ) ) + +(defun UpdateNetlistCompareEmptyCellInstances ( ConnectivityInstanceNames + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) + ( list + nil + nil + ( ListApplyFuncToListAndAccumulateResults + ConnectivityInstanceNames + (lambda + ( ConnectivityInstanceName + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) + ( list + ConnectivityInstanceName + ( apply + ConnectivityGetInstanceMasterLibNameFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceMasterLibNameFuncParams ) ) + ( apply + ConnectivityGetInstanceMasterCellNameFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceMasterCellNameFuncParams ) ) + ( apply + ConnectivityGetInstanceTransformFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceTransformFuncParams ) ) ) ) + ( list + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) ) + nil + ( ListApplyFuncToListAndAccumulateResult + ConnectivityInstanceNames + (lambda + ( ConnectivityInstanceName + CurrParamsToSet + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams ) + (let ( + ( ParamPairs ( apply + ConnectivityGetInstanceParameterPairsFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceParameterPairsFuncParams ) ) ) ) + ( ListApplyFuncToListAndAccumulateResult + ParamPairs + (lambda + ( ParamPair CurrResult InstanceName ) + ( cons + ( list + InstanceName + ( car ParamPair ) + (let ( + ( ParamVal ( cadr ParamPair ) ) ) + (if ( stringp ParamVal ) + ( StringUtilParseLengthString ParamVal ) + ParamVal ) ) ) + CurrResult ) ) + ( list + ConnectivityInstanceName ) + CurrParamsToSet ) ) ) + ( list + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams ) + nil ) ) ) + + + +(defun UpdateNetlistGetConnectionsToDelete ( InstanceMap + ConnectivityInstanceNames + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams ) + (let ( + ( Ret nil ) ) + ( foreach + ConnectivityInstanceName + ConnectivityInstanceNames + (let ( + ( CurrInstances ( NameGetInstancesForCanonicalName InstanceMap ConnectivityInstanceName ) ) ) + (when CurrInstances + ( foreach + CurrInstance + CurrInstances + (let ( + ( CurrInstanceConnectionsToDelete ( setof + CurrInstanceConnection + ( getq CurrInstance conns ) + ( not + ( apply + ConnectivityInstanceHasConnectionFunc + ( cons + ConnectivityInstanceName + ( cons + ( getq CurrInstanceConnection name ) + ( cons + ( getq ( getq CurrInstanceConnection net ) name ) + ConnectivityInstanceHasConnectionFuncParams ) ) ) ) ) ) ) ) + (when CurrInstanceConnectionsToDelete + ( setq Ret ( lconc Ret CurrInstanceConnectionsToDelete ) ) ) ) ) ) ) ) + ( car Ret ) ) ) + +(defun UpdateNetlistInstanceHasMaster ( Instance ) + (let ( + ( MasterLibName ( getq Instance libName ) ) + ( MasterCellName ( getq Instance cellName ) ) + ( MasterViewName ( getq Instance viewName ) ) ) + (let ( + ( MasterDDObj ( ddGetObj MasterLibName MasterCellName MasterViewName ) ) ) + ( and + MasterDDObj + ( getq MasterDDObj files ) ) ) ) ) + +(defun UpdateNetlistGetConnectionsToCreate ( InstanceMap + ConnectivityInstanceNames + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams ) + (let ( + ( Ret nil ) ) + ( foreach + ConnectivityInstanceName + ConnectivityInstanceNames + (let ( + ( CurrInstance ( car ( NameGetInstancesForCanonicalName InstanceMap ConnectivityInstanceName ) ) ) + ( ConnectivityInstanceConnections ( apply + ConnectivityGetInstanceConnectionsFunc + ( cons + ConnectivityInstanceName + ConnectivityGetInstanceConnectionsFuncParams ) ) ) ) + (let ( + ( CurrInstanceConnectionsToCreate (if ( and + CurrInstance + ( UpdateNetlistInstanceHasMaster + CurrInstance ) ) + (let ( + ( CurrInstanceConnectionsTable ( makeTable "bar" nil ) ) ) + ( UpdateNetlistTablifyInstanceTerms + CurrInstance + CurrInstanceConnectionsTable ) + ( setof + ConnectivityInstanceConnection + ConnectivityInstanceConnections + (let ( + ( CurrConnection ( arrayref + CurrInstanceConnectionsTable + ( car ConnectivityInstanceConnection ) ) ) ) + ( not + ( and + CurrConnection + ( equal + ( getq ( getq CurrConnection net ) name ) + ( cadr ConnectivityInstanceConnection ) ) ) ) ) ) ) + ConnectivityInstanceConnections ) ) ) + ( setq + Ret + ( lconc + Ret + ( ListApplyFuncToListAndAccumulateResults + CurrInstanceConnectionsToCreate + (lambda ( ConnectionToCreate ConnectivityInstanceName ) + ( cons ConnectivityInstanceName ConnectionToCreate ) ) + ( list ConnectivityInstanceName ) ) ) ) ) ) ) + ( car Ret ) ) ) + +(defun UpdateNetlistGetTerminalsToDelete ( CellView + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams ) + ( setof + Term + ( getq CellView terminals ) + ( null + ( apply + ConnectivityTerminalExistsFunc + ( cons + ( getq Term name ) + ConnectivityTerminalExistsFuncParams ) ) ) ) ) + +(defun UpdateNetlistGetTerminalsToCreate ( CellView ConnectivityTerminalNames ) + (let ( + ( TerminalsTable ( makeTable "foo" nil ) ) ) + ( UpdateNetlistTablifyTerminals CellView TerminalsTable ) + ( setof + ConnectivityTerminalName + ConnectivityTerminalNames + ( null ( arrayref TerminalsTable ConnectivityTerminalName ) ) ) ) ) + +(defun UpdateNetlistGetNetsToDelete ( CellView + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams ) + ( setof + Net + ( getq CellView nets ) + ( null + ( apply + ConnectivityNetExistsFunc + ( cons + ( getq Net name ) + ConnectivityNetExistsFuncParams ) ) ) ) ) + +(defun UpdateNetlistGetNetsToCreate ( CellView ConnectivityNetNames ) + (let ( + ( NetsTable ( makeTable "foo" nil ) ) ) + ( UpdateNetlistTablifyNets CellView NetsTable ) + ( setof + ConnectivityNetName + ConnectivityNetNames + ( null ( arrayref NetsTable ConnectivityNetName ) ) ) ) ) + +(defun UpdateNetlistGetNetsToChange ( CellView + ConnectivityNetNames + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams ) + ( setof + Change + ( mapcar + (lambda ( NetName ) + (let ( + ( WireSpacing + ( apply ConnectivityGetNetWireSpacingFunc + ( cons NetName + ConnectivityGetNetWireSpacingFuncParams ) ) ) + ( WireWidth + ( apply ConnectivityGetNetWireWidthFunc + ( cons NetName + ConnectivityGetNetWireWidthFuncParams ) ) ) + ( Net ( dbFindNetByName CellView NetName ) ) + ) + (when ( or + ( null Net ) + ( not + ( equal + WireSpacing + ( ConstraintsGetNetWireSpacing + Net ) ) ) + ( not + ( equal + WireWidth + ( ConstraintsGetNetWireWidth + Net ) ) ) ) + ( list + NetName + WireSpacing + WireWidth ) ) ) ) + ConnectivityNetNames ) + Change ) ) + + +(defun UpdateNetlistCompareCellConnectivity ( CellView + InstanceMap + ConnectivityInstanceNames + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams + ConnectivityTerminalNames + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams + ConnectivityNetNames + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams ) + (let ( + ( ConnectionsToDelete ( UpdateNetlistGetConnectionsToDelete + InstanceMap + ConnectivityInstanceNames + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams ) ) + ( ConnectionsToCreate ( UpdateNetlistGetConnectionsToCreate + InstanceMap + ConnectivityInstanceNames + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams ) ) + ( TerminalsToDelete ( UpdateNetlistGetTerminalsToDelete + CellView + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams ) ) + ( TerminalsToCreate ( UpdateNetlistGetTerminalsToCreate + CellView + ConnectivityTerminalNames ) ) + ( NetsToDelete ( UpdateNetlistGetNetsToDelete + CellView + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams ) ) + ( NetsToCreate ( UpdateNetlistGetNetsToCreate + CellView + ConnectivityNetNames ) ) + ( NetsToChange ( UpdateNetlistGetNetsToChange + CellView + ConnectivityNetNames + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams ) ) + ) + (when ( or + ConnectionsToDelete + ConnectionsToCreate + TerminalsToDelete + TerminalsToCreate + NetsToDelete + NetsToCreate + NetsToChange + ) + ( list + ( list + ConnectionsToDelete + ConnectionsToCreate ) + ( list + TerminalsToDelete + TerminalsToCreate ) + ( list + NetsToDelete + NetsToCreate + NetsToChange + ) ) ) ) ) + +(defun UpdateNetlistCompareEmptyCellConnectivity ( ConnectivityInstanceNames + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalNames + ConnectivityNetNames ) + (let ( + ( InstanceMap ( NameMakeEmptyInstanceMap ) ) ) + (let ( + ( ConnectionsToCreate ( UpdateNetlistGetConnectionsToCreate + InstanceMap + ConnectivityInstanceNames + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams ) ) ) + ( list + ( list + nil + ConnectionsToCreate ) + ( list + nil + ConnectivityTerminalNames ) + ( list + nil + ConnectivityNetNames ) ) ) ) ) + + +(defun UpdateNetlistFilterInstances ( CellView LibCellExpressionPairsToIgnore ) + ( car + ( NameFilterInstances + ( getq CellView instances ) + LibCellExpressionPairsToIgnore ) ) ) + +(defun UpdateNetlistComparePins ( CompareResult + ConnectivityPinChangeFunc + ConnectivityPinChangeFuncParams + SuppressPins + ForcePins ) + (unless SuppressPins + ( apply ConnectivityPinChangeFunc + ( cons + ( or + ( UpdateNetlistGetConnectionsToCreateFromCompareResult CompareResult ) + ( UpdateNetlistGetConnectionsToDeleteFromCompareResult CompareResult ) + ( UpdateNetlistGetTerminalsToDeleteFromCompareResult CompareResult ) + ( UpdateNetlistGetTerminalsToCreateFromCompareResult CompareResult ) + ( UpdateNetlistGetNetsToDeleteFromCompareResult CompareResult ) + ( UpdateNetlistGetNetsToCreateFromCompareResult CompareResult ) + ( UpdateNetlistGetBoundaryHeightFromCompareResult CompareResult ) + ( UpdateNetlistGetBoundaryWidthFromCompareResult CompareResult ) + ( UpdateNetlistGetBoundaryPositionFromCompareResult CompareResult ) ) + ( cons + ForcePins + ConnectivityPinChangeFuncParams ) ) ) ) ) + +(defun UpdateNetlistCompareCellView ( CellViewToCheck + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + InstanceMap + Instances + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityInstanceNames + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams + ConnectivityTerminalNames + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams + ConnectivityNetNames + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams + ConnectivityGetLayerWireSpacingFunc + ConnectivityGetLayerWireSpacingFuncParams + ConnectivityGetLayerWireWidthFunc + ConnectivityGetLayerWireWidthFuncParams + ConnectivityGetGlobalWireSpacingFunc + ConnectivityGetGlobalWireSpacingFuncParams + ConnectivityGetGlobalWireWidthFunc + ConnectivityGetGlobalWireWidthFuncParams + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams + ConnectivityPinChangeFunc + ConnectivityPinChangeFuncParams + BoundaryLayerLPP + UserUnitsPerMeter + LockBound + SuppressPins + ForcePins ) + (let ( + ( InstancesCompareResult ( UpdateNetlistCompareCellInstances + Instances + InstanceMap + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityInstanceNames + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) ) + ( ConnectivityCompareResult ( UpdateNetlistCompareCellConnectivity + CellViewToCheck + InstanceMap + ConnectivityInstanceNames + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams + ConnectivityTerminalNames + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams + ConnectivityNetNames + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams ) + ) + ( BoundaryCompareResult (when ( and + ( null ConnectivityInstanceNames ) + ( equal + ( getq CellViewToCheck cellViewType ) + "maskLayout" ) ) + ( UpdateNetlistCompareCellBoundary + CellViewToCheck + ConnectivityInstanceNames + BoundaryLayerLPP + UserUnitsPerMeter + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams + LockBound ) ) ) ) + (let ( + ( PinCompareResult + ( UpdateNetlistComparePins + ( list InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult + nil ) + ConnectivityPinChangeFunc + ConnectivityPinChangeFuncParams + SuppressPins + ForcePins ) ) ) + (when ( or + InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult + PinCompareResult ) + ( list + InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult + PinCompareResult + ( getq CellViewToCheck viewName ) + ( getq CellViewToCheck cellName ) + ) ) ) ) ) + + + + +(defun UpdateNetlistCompareEmptyCellView ( LibName + CellName + ViewName + ConnectivityInstanceNames + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalNames + ConnectivityNetNames + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams + ConnectivityPinChangeFunc + ConnectivityPinChangeFuncParams + NetlistViewName + SuppressPins + ForcePins ) + (let ( + ( InstancesCompareResult ( UpdateNetlistCompareEmptyCellInstances + ConnectivityInstanceNames + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams ) ) + ( ConnectivityCompareResult ( UpdateNetlistCompareEmptyCellConnectivity + ConnectivityInstanceNames + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalNames + ConnectivityNetNames ) ) + ( BoundaryCompareResult (unless ( and NetlistViewName ( equal ViewName NetlistViewName ) ) + ( UpdateNetlistCompareEmptyCellBoundary + ConnectivityInstanceNames + LibName + CellName + ViewName + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams ) ) ) ) + (let ( + ( PinCompareResult + ( UpdateNetlistComparePins + ( list InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult + nil ) + ConnectivityPinChangeFunc + ConnectivityPinChangeFuncParams + SuppressPins + ForcePins ) ) ) + (when ( or + InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult ) + ( list + InstancesCompareResult + ConnectivityCompareResult + BoundaryCompareResult + PinCompareResult + ViewName + CellName ) ) ) ) ) + + +(defun UpdateNetlistGetViewNameFromCompareResult ( CompareResult ) + ( nth 4 CompareResult ) ) + +(defun UpdateNetlistGetCellNameFromCompareResult ( CompareResult ) + ( nth 5 CompareResult ) ) + +(defun UpdateNetlistGetInstancesToDeleteFromCompareResult ( CompareResult ) + ( caar CompareResult ) ) + +(defun UpdateNetlistGetInstancesToChangeFromCompareResult ( CompareResult ) + ( cadar CompareResult ) ) + +(defun UpdateNetlistGetInstancesToCreateFromCompareResult ( CompareResult ) + ( caddar CompareResult ) ) + +(defun UpdateNetlistGetInstancesToFixFromCompareResult ( CompareResult ) + ( nth 3 ( car CompareResult ) ) ) + +(defun UpdateNetlistGetParametersToSetFromCompareResult ( CompareResult ) + ( nth 4 ( car CompareResult ) ) ) + +(defun UpdateNetlistGetBoundaryShapeFromCompareResult ( CompareResult ) + ( nth 3 ( caddr CompareResult ) ) ) + +(defun UpdateNetlistGetBoundaryHeightFromCompareResult ( CompareResult ) + ( car ( car ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetOldBoundaryHeightFromCompareResult ( CompareResult ) + ( cadr ( car ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetBoundaryHeightWarningFromCompareResult ( CompareResult ) + ( caddr ( car ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetBoundaryWidthFromCompareResult ( CompareResult ) + ( car ( cadr ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetOldBoundaryWidthFromCompareResult ( CompareResult ) + ( cadr ( cadr ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetBoundaryWidthWarningFromCompareResult ( CompareResult ) + ( caddr ( cadr ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetBoundaryPositionFromCompareResult ( CompareResult ) + ( car ( nth 2 ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetOldBoundaryPositionFromCompareResult ( CompareResult ) + ( cadr ( nth 2 ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetBoundaryPositionWarningFromCompareResult ( CompareResult ) + ( caddr ( nth 2 ( caddr CompareResult ) ) ) ) + +(defun UpdateNetlistGetConnectionsToDeleteFromCompareResult ( CompareResult ) + ( caaadr CompareResult ) ) + +(defun UpdateNetlistGetConnectionsToCreateFromCompareResult ( CompareResult ) + ( car ( cdr ( car ( car ( cdr CompareResult ) ) ) ) ) ) + +(defun UpdateNetlistGetTerminalsToDeleteFromCompareResult ( CompareResult ) + ( car ( car ( cdr ( car ( cdr CompareResult ) ) ) ) ) ) + +(defun UpdateNetlistGetTerminalsToCreateFromCompareResult ( CompareResult ) + ( car ( cdr ( car ( cdr ( car ( cdr CompareResult ) ) ) ) ) ) ) + +(defun UpdateNetlistGetNetsToDeleteFromCompareResult ( CompareResult ) + ( car ( car ( cdr ( cdr ( car ( cdr CompareResult ) ) ) ) ) ) ) + +(defun UpdateNetlistGetNetsToCreateFromCompareResult ( CompareResult ) + ( cadr ( car ( cdr ( cdr ( car ( cdr CompareResult ) ) ) ) ) ) ) + +(defun UpdateNetlistGetNetsToChangeFromCompareResult ( CompareResult ) + ( caddr ( car ( cdr ( cdr ( car ( cdr CompareResult ) ) ) ) ) ) ) + +(defun UpdateNetlistGetPinChangeFromCompareResult ( CompareResult ) + ( cadddr CompareResult ) ) + +(defun UpdateNetlistGetPinsFileFromCompareResult ( CompareResult ) + ( car ( cadddr CompareResult ) ) ) + +(defun UpdateNetlistGetWirePitchFromCompareResult ( CompareResult ) + ( cadr ( cadddr CompareResult ) ) ) + +(defun UpdateNetlistGetWireWidthFromCompareResult ( CompareResult ) + ( caddr ( cadddr CompareResult ) ) ) + +(defun UpdateNetlistGetWireSpacingFromCompareResult ( CompareResult ) + ( cadddr ( cadddr CompareResult ) ) ) + +(defun UpdateNetlistGetPinLPPFromCompareResult ( CompareResult ) + ( car ( cddddr ( cadddr CompareResult ) ) ) ) + + +(defun UpdateNetlistGetInstanceNameFromInstanceToCreate ( InstanceToCreate ) + ( car InstanceToCreate ) ) + +(defun UpdateNetlistGetLibNameFromInstanceToCreate ( InstanceToCreate ) + ( cadr InstanceToCreate ) ) + +(defun UpdateNetlistGetCellNameFromInstanceToCreate ( InstanceToCreate ) + ( caddr InstanceToCreate ) ) + +(defun UpdateNetlistGetInstanceTransformFromInstanceToCreate ( InstanceToCreate ) + ( nth 3 InstanceToCreate ) ) + +(defun UpdateNetlistGetInstanceNameFromInstanceToChange ( InstanceToChange ) + ( car InstanceToChange ) ) + +(defun UpdateNetlistGetLibNameFromInstanceToChange ( InstanceToChange ) + ( cadr InstanceToChange ) ) + +(defun UpdateNetlistGetCellNameFromInstanceToChange ( InstanceToChange ) + ( caddr InstanceToChange ) ) + +(defun UpdateNetlistGetInstanceTransformFromInstanceToChange ( InstanceToChange ) + ( nth 4 InstanceToChange ) ) + +(defun UpdateNetlistGetInstanceCoincidencesFromInstanceToChange ( InstanceToChange ) + ( nth 5 InstanceToChange ) ) + +(defun UpdateNetlistGetInstanceNameFromParameterToSet ( ParameterToSet ) + ( car ParameterToSet ) ) + +(defun UpdateNetlistGetParameterNameFromParameterToSet ( ParameterToSet ) + ( cadr ParameterToSet ) ) + +(defun UpdateNetlistGetParameterValueFromParameterToSet ( ParameterToSet ) + ( caddr ParameterToSet ) ) + +(defun UpdateNetlistGetInstanceDBObjFromInstanceToChange ( InstanceToChange ) + ( cadddr InstanceToChange ) ) + +(defun UpdateNetlistGetInstanceNameFromConnectionToCreate ( ConnectionToCreate ) + ( car ConnectionToCreate ) ) + +(defun UpdateNetlistGetTerminalNameFromConnectionToCreate ( ConnectionToCreate ) + ( cadr ConnectionToCreate ) ) + +(defun UpdateNetlistGetNetNameFromConnectionToCreate ( ConnectionToCreate ) + ( caddr ConnectionToCreate ) ) + + +(defun UpdateNetlistGetErrorsFromCompareResult ( CompareResult ) + + (let ( + ( CellName ( UpdateNetlistGetCellNameFromCompareResult CompareResult ) ) + ( ViewName ( UpdateNetlistGetViewNameFromCompareResult CompareResult ) ) + ( InstancesToFix ( UpdateNetlistGetInstancesToFixFromCompareResult CompareResult ) ) + ( InstancesToChange ( UpdateNetlistGetInstancesToChangeFromCompareResult CompareResult ) ) + ( BoundaryShape ( UpdateNetlistGetBoundaryShapeFromCompareResult CompareResult ) ) + ( BoundaryHeight ( UpdateNetlistGetBoundaryHeightFromCompareResult CompareResult ) ) + ( BoundaryWidth ( UpdateNetlistGetBoundaryWidthFromCompareResult CompareResult ) ) + ( BoundaryPosition ( UpdateNetlistGetBoundaryPositionFromCompareResult CompareResult ) ) + ( OldBoundaryHeight ( UpdateNetlistGetOldBoundaryHeightFromCompareResult CompareResult ) ) + ( OldBoundaryPosition ( UpdateNetlistGetOldBoundaryPositionFromCompareResult CompareResult ) ) ) + + (let ( + ( Ret + ( ListApplyFuncToListAndAccumulateResults + InstancesToFix + (lambda + ( InstanceToFix + CellName + ViewName ) + (let ( + ( InstCellName ( getq InstanceToFix cellName ) ) + ( InstLibName ( getq InstanceToFix libName ) ) + ( InstViewName ( getq InstanceToFix viewName ) ) ) + ( sprintf + nil + "\"%s\" in library \"%s\" does not have a view \"%s\" which is referenced by instance \"%s\" in \"%s\" \"%s\"." + InstCellName + InstLibName + InstViewName + ( getq InstanceToFix name ) + CellName + ViewName ) ) ) + ( list CellName ViewName ) ) ) ) + + (when BoundaryShape + (unless ( and BoundaryHeight BoundaryWidth BoundaryPosition ) + ( setq + Ret + ( cons + ( sprintf + nil + "\"%s\" \"%s\" Boundary needs to change, but either the height( %L ), the width( %L ) or position( %L ) is nil." + CellName + ViewName + BoundaryHeight + BoundaryWidth + BoundaryPosition ) + Ret ) ) ) ) + (when BoundaryHeight + (unless ( and OldBoundaryHeight BoundaryShape ) + (when OldBoundaryHeight + ( setq + Ret + ( cons + ( sprintf + nil + "HEIGHT \"%s\" \"%s\" directive specifies %.9e non-empty cell has height of %.9e." + CellName + ViewName + BoundaryHeight + OldBoundaryHeight ) + Ret ) ) ) ) ) + ( setq + Ret + ( append + Ret + ( ListApplyFuncToListAndAccumulateNonNilResults + InstancesToChange + (lambda ( InstanceToChange ) + (let ( + ( InstName + ( UpdateNetlistGetInstanceNameFromInstanceToChange InstanceToChange ) ) + ( InstCellName + ( UpdateNetlistGetCellNameFromInstanceToChange InstanceToChange ) ) + ( InstLibName + ( UpdateNetlistGetLibNameFromInstanceToChange InstanceToChange ) ) + ( InstCoincidences + ( UpdateNetlistGetInstanceCoincidencesFromInstanceToChange + InstanceToChange ) ) ) + (when ( and ( cadr ( car InstCoincidences ) ) + ( greaterp ( length ( cadr InstCoincidences ) ) + 1 ) ) + ( sprintf + nil + "COINCIDENCE Instance \"%s\" of type \"%s\" in library \"%s\" is coincident with another instance at %L\n" + InstName + InstCellName + InstLibName + ( cadr ( car InstCoincidences ) ) + ) ) ) ) + nil + ) ) ) + Ret ) ) ) + + + +(defun UpdateNetlistPrintDifferences ( CompareResult + OutputPort ) + (let ( + ( InstancePrefix "INSTANCE:" ) + ( NetPrefix "NET:" ) + ( ParamPrefix "PARAM:" ) + ( ErrorPrefix "ERROR:" ) + ( BoundaryPrefix "BOUNDARY:" ) + ( CellsToCreateTable ( makeTable "foo" nil ) ) + ( CellName ( UpdateNetlistGetCellNameFromCompareResult CompareResult ) ) + ( ViewName ( UpdateNetlistGetViewNameFromCompareResult CompareResult ) ) + ( InstancesToDelete ( UpdateNetlistGetInstancesToDeleteFromCompareResult CompareResult ) ) + ( InstancesToChange ( UpdateNetlistGetInstancesToChangeFromCompareResult CompareResult ) ) + ( InstancesToCreate ( UpdateNetlistGetInstancesToCreateFromCompareResult CompareResult ) ) + ( ParametersToSet ( UpdateNetlistGetParametersToSetFromCompareResult CompareResult ) ) + ( ConnectionsToDelete ( UpdateNetlistGetConnectionsToDeleteFromCompareResult CompareResult ) ) + ( ConnectionsToCreate ( UpdateNetlistGetConnectionsToCreateFromCompareResult CompareResult ) ) + ( TerminalsToDelete ( UpdateNetlistGetTerminalsToDeleteFromCompareResult CompareResult ) ) + ( TerminalsToCreate ( UpdateNetlistGetTerminalsToCreateFromCompareResult CompareResult ) ) + ( NetsToDelete ( UpdateNetlistGetNetsToDeleteFromCompareResult CompareResult ) ) + ( NetsToCreate ( UpdateNetlistGetNetsToCreateFromCompareResult CompareResult ) ) + ( NetsToChange ( UpdateNetlistGetNetsToChangeFromCompareResult CompareResult ) ) + ( BoundaryShape ( UpdateNetlistGetBoundaryShapeFromCompareResult CompareResult ) ) + ( BoundaryHeight ( UpdateNetlistGetBoundaryHeightFromCompareResult CompareResult ) ) + ( BoundaryWidth ( UpdateNetlistGetBoundaryWidthFromCompareResult CompareResult ) ) + ( BoundaryWidthWarning ( UpdateNetlistGetBoundaryWidthWarningFromCompareResult CompareResult ) ) + ( BoundaryPosition ( UpdateNetlistGetBoundaryPositionFromCompareResult CompareResult ) ) + ( BoundaryPositionWarning ( UpdateNetlistGetBoundaryPositionWarningFromCompareResult CompareResult ) ) + ( OldBoundaryHeight ( UpdateNetlistGetOldBoundaryHeightFromCompareResult CompareResult ) ) + ( OldBoundaryWidth ( UpdateNetlistGetOldBoundaryWidthFromCompareResult CompareResult ) ) + ( OldBoundaryPosition ( UpdateNetlistGetOldBoundaryPositionFromCompareResult CompareResult ) ) + ( BoundaryHeightWarning ( UpdateNetlistGetBoundaryHeightWarningFromCompareResult CompareResult ) ) + ( PinChange ( UpdateNetlistGetPinChangeFromCompareResult CompareResult ) ) + ( ErrorList ( UpdateNetlistGetErrorsFromCompareResult CompareResult ) ) ) + + ( foreach + InstanceToDelete + InstancesToDelete + ( fprintf + OutputPort + "%L Delete Instance \"%L\" of type \"%L\" in library \"%L\".\n" + InstancePrefix + ( getq InstanceToDelete name ) + ( getq InstanceToDelete cellName ) + ( getq InstanceToDelete libName ) ) ) + + ( foreach + InstanceToChange + InstancesToChange + (let ( + ( InstName ( UpdateNetlistGetInstanceNameFromInstanceToChange InstanceToChange ) ) + ( InstCellName ( UpdateNetlistGetCellNameFromInstanceToChange InstanceToChange ) ) + ( InstLibName ( UpdateNetlistGetLibNameFromInstanceToChange InstanceToChange ) ) + ( InstToChangeDBObj ( UpdateNetlistGetInstanceDBObjFromInstanceToChange InstanceToChange ) ) + ( InstTransform ( UpdateNetlistGetInstanceTransformFromInstanceToChange InstanceToChange ) ) + ) + ( fprintf + OutputPort + "%L Change Instance \"%L\" of type \"%L\" in library \"%L\" to \"%L\" of type \"%L\" in library \"%L\".\n" + InstancePrefix + ( getq InstToChangeDBObj name ) + ( getq InstToChangeDBObj cellName ) + ( getq InstToChangeDBObj libName ) + InstName + InstCellName + InstLibName ) + (when InstTransform + ( fprintf + OutputPort + "%s Move Instance \"%s\" from %L to %L.\n" + InstancePrefix + InstName + ( getq InstToChangeDBObj transform ) + InstTransform ) ) + ) ) + + ( foreach + InstanceToCreate + InstancesToCreate + (let ( + ( InstName ( UpdateNetlistGetInstanceNameFromInstanceToCreate InstanceToCreate ) ) + ( InstLibName ( UpdateNetlistGetLibNameFromInstanceToCreate InstanceToCreate ) ) + ( InstCellName ( UpdateNetlistGetCellNameFromInstanceToCreate InstanceToCreate ) ) + ( InstTransform ( UpdateNetlistGetInstanceTransformFromInstanceToCreate InstanceToCreate ) ) ) + (if InstTransform + ( fprintf + OutputPort + "%s Create Instance \"%s\" of type \"%s\" in library \"%s\" at %L.\n" + InstancePrefix + InstName + InstCellName + InstLibName + InstTransform ) + ( fprintf + OutputPort + "%s Create Instance \"%s\" of type \"%s\" in library \"%s\".\n" + InstancePrefix + InstName + InstCellName + InstLibName ) ) ) ) + + + ( foreach + ParameterToSet + ParametersToSet + (let ( + ( InstanceName ( UpdateNetlistGetInstanceNameFromParameterToSet ParameterToSet ) ) + ( ParamName ( UpdateNetlistGetParameterNameFromParameterToSet ParameterToSet ) ) + ( ParamValue ( UpdateNetlistGetParameterValueFromParameterToSet ParameterToSet ) ) ) + ( fprintf + OutputPort + "%s Set \"%s\" to \"%e\" on instance \"%s\".\n" + ParamPrefix + ParamName + ParamValue + InstanceName ) ) ) + ( foreach + ConnectionToDelete + ConnectionsToDelete + ( fprintf + OutputPort + "%s Delete Connection of \"%s\" to \"%s.%s\".\n" + NetPrefix + ( getq ( getq ConnectionToDelete net ) name ) + ( getq ( getq ConnectionToDelete inst ) name ) + ( getq ConnectionToDelete name ) ) ) + ( foreach + ConnectionToCreate + ConnectionsToCreate + (let ( + ( ConnectionInstanceName ( UpdateNetlistGetInstanceNameFromConnectionToCreate + ConnectionToCreate ) ) + ( ConnectionTerminalName ( UpdateNetlistGetTerminalNameFromConnectionToCreate + ConnectionToCreate ) ) + ( ConnectionNetName ( UpdateNetlistGetNetNameFromConnectionToCreate + ConnectionToCreate ) ) ) + ( fprintf + OutputPort + "%s Create Connection of \"%s\" to \"%s.%s\".\n" + NetPrefix + ConnectionNetName + ConnectionInstanceName + ConnectionTerminalName ) ) ) + ( foreach + TerminalToDelete + TerminalsToDelete + ( fprintf + OutputPort + "%s Delete Terminal \"%L\".\n" + NetPrefix + ( getq TerminalToDelete name ) ) ) + ( foreach + TerminalToCreate + TerminalsToCreate + ( fprintf + OutputPort + "%s Create Terminal \"%s\".\n" + NetPrefix + TerminalToCreate ) ) + ( foreach + NetToDelete + NetsToDelete + ( fprintf + OutputPort + "%s Delete Net \"%L\".\n" + NetPrefix + ( getq NetToDelete name ) ) ) + ( foreach + NetToCreate + NetsToCreate + ( fprintf + OutputPort + "%s Create Net \"%s\".\n" + NetPrefix + NetToCreate ) ) + ( foreach + NetToChangeSpec + NetsToChange + (let ( + ( NetToChange ( car NetToChangeSpec ) ) + ( WireSpacing ( cadr NetToChangeSpec ) ) + ( WireWidth ( caddr NetToChangeSpec ) ) + ) + (when WireSpacing + ( fprintf + OutputPort + "%s Change Net \"%s\" wire spacing to %g meters.\n" + NetPrefix + NetToChange + WireSpacing ) ) + (when WireWidth + ( fprintf + OutputPort + "%s Change Net \"%s\" wire width to %g meters.\n" + NetPrefix + NetToChange + WireWidth ) ) + ) ) + + (when BoundaryShape + (when ( and BoundaryHeight BoundaryWidth BoundaryPosition ) + ( fprintf + OutputPort + "%s CHANGE.\n" + BoundaryPrefix ) ) ) + + (when BoundaryHeight + (if ( and OldBoundaryHeight BoundaryShape ) + ( fprintf + OutputPort + "%s CHANGE HEIGHT from %.9e to %.9e.\n" + BoundaryPrefix + OldBoundaryHeight + BoundaryHeight ) + (unless OldBoundaryHeight + ( fprintf + OutputPort + "%s HEIGHT will be %.9e.\n" + BoundaryPrefix + BoundaryHeight ) ) ) ) + + (when BoundaryHeightWarning + ( fprintf + OutputPort + "%s HEIGHT WARNING %s\n" + BoundaryPrefix + BoundaryHeightWarning ) ) + + (when BoundaryWidth + (if ( and OldBoundaryWidth BoundaryShape ) + ( fprintf + OutputPort + "%s CHANGE WIDTH from %.9e to %.9e.\n" + BoundaryPrefix + OldBoundaryWidth + BoundaryWidth ) + (unless BoundaryShape + ( fprintf + OutputPort + "%s WIDTH will be %.9e.\n" + BoundaryPrefix + BoundaryWidth ) ) ) ) + (when BoundaryWidthWarning + ( fprintf + OutputPort + "%s WIDTH WARNING %s\n" + BoundaryPrefix + BoundaryWidthWarning ) ) + (when BoundaryPosition + (if ( and OldBoundaryPosition BoundaryShape ) + ( fprintf + OutputPort + "%s CHANGE POSITION from %L to %L.\n" + BoundaryPrefix + OldBoundaryPosition + BoundaryPosition ) + (unless BoundaryShape + ( fprintf + OutputPort + "%s POSITION will be %L.\n" + BoundaryPrefix + BoundaryPosition ) ) ) ) + (when BoundaryPositionWarning + ( fprintf + OutputPort + "%s POSITION WARNING %L\n" + BoundaryPrefix + BoundaryPositionWarning ) ) + + (when PinChange + ( fprintf + OutputPort + "PINS: will change\n" ) ) + + ( foreach + ErrorStr + ErrorList + ( fprintf + OutputPort + "%s %s\n" + ErrorPrefix + ErrorStr ) ) ) ) + + +(defun UpdateNetlistGetInstanceNamesFromCellView ( CellView ) + ( ListApplyFuncToListAndAccumulateResults + ( getq CellView instances ) + (lambda + ( Instance ) + ( getq Instance name ) ) + nil ) ) + +(defun UpdateNetlistCompareCellViews ( LibName + CellName + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + RequiredViews + ViewsToUpdate + UpdateOnlyViews + NetlistViewName + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityGetInstanceTripplesFunc + ConnectivityGetInstanceTripplesFuncParams + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams + ConnectivityGetTerminalNamesFunc + ConnectivityGetTerminalNamesFuncParams + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams + ConnectivityGetNetNamesFunc + ConnectivityGetNetNamesFuncParams + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams + ConnectivityGetLayerWireSpacingFunc + ConnectivityGetLayerWireSpacingFuncParams + ConnectivityGetLayerWireWidthFunc + ConnectivityGetLayerWireWidthFuncParams + ConnectivityGetGlobalWireSpacingFunc + ConnectivityGetGlobalWireSpacingFuncParams + ConnectivityGetGlobalWireWidthFunc + ConnectivityGetGlobalWireWidthFuncParams + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams + ConnectivityPinChangeFunc + ConnectivityPinChangeFuncParams + BoundaryLayerLPP + UserUnitsPerMeter + LockBound + SuppressPins + ForcePins ) + (let ( + ( ViewInfoTable ( makeTable "viewInfoTable" nil ) ) + ( Ret nil ) ) + + ( foreach + ViewName + RequiredViews + (let ( + ( ViewObj ( ddGetObj LibName CellName ViewName ) ) + ( InstanceMap ( NameMakeEmptyInstanceMap ) ) ) + (let ( + ( ConnectivityInstanceTripples ( apply + ConnectivityGetInstanceTripplesFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ConnectivityGetInstanceTripplesFuncParams ) ) ) ) ) + ( MyLibCellExpressionPairsToIgnore (if ( and + NetlistViewName + ( equal ViewName NetlistViewName ) ) + ( list ) + LibCellExpressionPairsToIgnore ) ) ) + (let ( + ( FilteredInstanceNames ( ListApplyFuncToListAndAccumulateResults + ( car + ( NameFilterInstanceTripples + ConnectivityInstanceTripples + LibCellExpressionPairsToIgnore ) ) + (lambda + ( InstanceTripple ) + ( car InstanceTripple ) ) + nil ) ) + ( InstanceNames ( ListApplyFuncToListAndAccumulateResults + ConnectivityInstanceTripples + (lambda + ( InstanceTripple ) + ( car InstanceTripple ) ) + nil ) ) + ( ConnectivityTerminalNames ( apply + ConnectivityGetTerminalNamesFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ConnectivityGetTerminalNamesFuncParams ) ) ) ) ) + ( ConnectivityNetNames ( apply + ConnectivityGetNetNamesFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ConnectivityGetNetNamesFuncParams ) ) ) ) ) ) + (let ( + ( ConnectivityInstanceNames (if ( and + NetlistViewName + ( equal ViewName NetlistViewName ) ) + InstanceNames + FilteredInstanceNames ) ) + ( CellView (when ( and + ( car ( getq ViewObj files ) ) + ( ddIsObjReadable ( car ( getq ViewObj files ) ) ) ) + ( dbOpenCellViewByType + LibName + CellName + ViewName + nil + "r" ) ) ) ) + (let ( + ( Instances (when CellView + ( UpdateNetlistFilterInstances + CellView + MyLibCellExpressionPairsToIgnore ) ) ) ) + ( NamePopulateInstanceMapWithInstances + InstanceMap + Instances + FoldableLibCellExpressionPairs ) + + ( setarray + ViewInfoTable + ViewName + ( list + CellView + MyLibCellExpressionPairsToIgnore + InstanceMap + Instances + ConnectivityInstanceNames + ConnectivityTerminalNames + ConnectivityNetNames ) ) + ) ) ) ) ) ) + + + ( foreach + ViewName + ViewsToUpdate + (let ( + ( ViewInfo ( arrayref ViewInfoTable ViewName ) ) ) + (let ( + ( CellView ( car ViewInfo ) ) + ( MyLibCellExpressionPairsToIgnore ( cadr ViewInfo ) ) + ( InstanceMap ( caddr ViewInfo ) ) + ( Instances ( nth 3 ViewInfo ) ) + ( ConnectivityInstanceNames ( nth 4 ViewInfo ) ) + ( ConnectivityTerminalNames ( nth 5 ViewInfo ) ) + ( ConnectivityNetNames ( nth 6 ViewInfo ) ) ) + ( printf "Comparing %L %L\n" CellName ViewName ) + ( setq + Ret + ( tconc + Ret + ( list + ViewName + (if CellView + ( SyncNetlistCompareCellView + CellView + MyLibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + InstanceMap + Instances + BoundaryLayerLPP + UserUnitsPerMeter + LockBound + SuppressPins + ForcePins ) + (when ( forall + UpdateOnlyView + UpdateOnlyViews + ( not ( equal ViewName UpdateOnlyView ) ) ) + ( UpdateNetlistCompareEmptyCellView + LibName + CellName + ViewName + ConnectivityInstanceNames + ConnectivityGetInstanceMasterLibNameFunc + ( cons ViewName ConnectivityGetInstanceMasterLibNameFuncParams ) + ConnectivityGetInstanceMasterCellNameFunc + ( cons ViewName ConnectivityGetInstanceMasterCellNameFuncParams ) + ConnectivityGetInstanceConnectionsFunc + ( cons ViewName ConnectivityGetInstanceConnectionsFuncParams ) + ConnectivityTerminalNames + ConnectivityNetNames + ConnectivityGetInstanceParameterPairsFunc + ( cons ViewName ConnectivityGetInstanceParameterPairsFuncParams ) + ConnectivityGetInstanceTransformFunc + ( cons + ViewName + ( cons ViewInfoTable ConnectivityGetInstanceTransformFuncParams ) ) + ConnectivityGetCellHeightFunc + ConnectivityGetCellHeightFuncParams + ConnectivityEstimateCellWidthFunc + ConnectivityEstimateCellWidthFuncParams + ConnectivityGetBoundaryPositionFunc + ConnectivityGetBoundaryPositionFuncParams + ConnectivityPinChangeFunc + ConnectivityPinChangeFuncParams + NetlistViewName + SuppressPins + ForcePins + ) ) ) + InstanceMap ) ) ) ) ) ) + ( list ( list LibName CellName ) ( car Ret ) ) ) ) + +(defun UpdateNetlistGetSkillNetlistInstanceExistsFunc ( ) + (lambda + ( InstanceName ViewName NetlistsTablesTable ) + ( not + ( null + ( NetlistTableGetInstance + ( arrayref NetlistsTablesTable ViewName ) + InstanceName ) ) ) ) ) + +defun( UpdateNetlistGetSkillNetlistInstanceExists ( InstanceName ViewName NetlistsTablesTable ) + NetlistsTablesTable[ViewName]["i"][InstanceName] != nil +) + + +(defun UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc ( ) + (lambda + ( InstanceName ViewName NetlistsTablesTable ) + ( NetlistTableGetInstanceInNetlistMasterLibName + ( arrayref NetlistsTablesTable ViewName ) + InstanceName ) ) ) + +defun( UpdateNetlistGetSkillNetlistGetInstanceMasterLibName ( InstanceName ViewName NetlistsTablesTable ) + NetlistTableGetInstanceInNetlistMasterLibName( NetlistsTablesTable[ViewName] InstanceName ) +) + +(defun UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc ( ) + (lambda + ( InstanceName ViewName NetlistsTablesTable ) + ( NetlistTableGetInstanceInNetlistMasterCellName + ( arrayref NetlistsTablesTable ViewName ) + InstanceName ) ) ) + +defun( UpdateNetlistGetSkillNetlistGetInstanceMasterCellName ( InstanceName ViewName NetlistsTablesTable ) + NetlistTableGetInstanceInNetlistMasterCellName( NetlistsTablesTable[ViewName] InstanceName ) +) + +(defun UpdateNetlistGetSkillNetlistGetInstanceTripplesFunc () + (lambda + ( LibName CellName ViewName NetlistsTablesTable ) + ( NetlistTableGetInstanceTripples + ( arrayref NetlistsTablesTable ViewName ) ) ) ) + +defun( UpdateNetlistGetSkillNetlistGetInstanceTripples ( LibName CellName ViewName NetlistsTablesTable ) + NetlistTableGetInstanceTripples( NetlistsTablesTable[ViewName] ) +) + +(defun UpdateNetlistGetSkillNetlistGetInstanceParameterPairsFunc ( ) + (lambda + ( InstanceName ViewName NetlistsTablesTable ) + ( NetlistTableGetInstanceInNetlistParametersPairs + ( arrayref NetlistsTablesTable ViewName ) + InstanceName ) ) ) + +(defun UpdateNetlistGetSkillNetlistInstanceHasConnectionFunc ( ) + (lambda + ( InstanceName TerminalName NetName ViewName NetlistsTablesTable ) + (let ( + ( ConnectivityNetName ( NetlistTableGetNetNameForInstanceInNetlistTerminalName + ( arrayref NetlistsTablesTable ViewName ) + InstanceName + TerminalName ) ) ) + ( and + ConnectivityNetName + ( equal ConnectivityNetName NetName ) ) ) ) ) + +(defun UpdateNetlistGetSkillNetlistGetInstanceConnectionsFunc ( ) + (lambda + ( InstanceName ViewName NetlistsTablesTable ) + ( NetlistTableGetInstanceInNetlistConnectionPairs + ( arrayref NetlistsTablesTable ViewName ) + InstanceName ) ) ) + +(defun UpdateNetlistGetSkillNetlistTerminalExistsFunc ( ) + (lambda + ( TerminalName ViewName NetlistsTablesTable ) + ( NetlistTableTerminalExists + ( arrayref NetlistsTablesTable ViewName ) + TerminalName ) ) ) + +(defun UpdateNetlistGetSkillNetlistGetTerminalNamesFunc ( ) + (lambda + ( LibName CellName ViewName NetlistsTablesTable ) + ( NetlistTableGetTerminalNames + ( arrayref NetlistsTablesTable ViewName ) ) ) ) + +(defun UpdateNetlistGetSkillNetlistNetExistsFunc ( ) + (lambda + ( NetName ViewName NetlistsTablesTable ) + ( NetlistTableNetExists + ( arrayref NetlistsTablesTable ViewName ) + NetName ) ) ) + +(defun UpdateNetlistGetSkillGetNetlistNetNamesFunc ( ) + (lambda + ( LibName CellName ViewName NetlistsTablesTable ) + ( NetlistTableGetNetNames + ( arrayref NetlistsTablesTable ViewName ) ) ) ) + +(defun UpdateNetListGetSkillGetNetlistNetWireSpacingFunc () + (lambda ( NetName + DirectiveTable + DirectiveUnitsPerMeter ) + ( CellInfoGetNetWireSpacingInMeters + DirectiveTable + NetName + DirectiveUnitsPerMeter ) ) ) + +(defun UpdateNetListGetSkillGetNetlistNetWireWidthFunc () + (lambda ( NetName + DirectiveTable + DirectiveUnitsPerMeter ) + ( CellInfoGetNetWireWidthInMeters + DirectiveTable + NetName + DirectiveUnitsPerMeter ) ) ) + +(defun UpdateNetListGetSkillGetNetlistLayerWireSpacingFunc () + (lambda ( Layer + DirectiveTable + DirectiveUnitsPerMeter ) + ( CellInfoGetLayerWireSpacingInMeters + DirectiveTable + Layer + DirectiveUnitsPerMeter ) ) ) + +(defun UpdateNetListGetSkillGetNetlistLayerWireWidthFunc () + (lambda ( Layer + DirectiveTable + DirectiveUnitsPerMeter ) + ( CellInfoGetLayerWireWidthInMeters + DirectiveTable + Layer + DirectiveUnitsPerMeter ) ) ) + +(defun UpdateNetListGetSkillGetNetlistGlobalWireSpacingFunc () + (lambda ( DirectiveTable + DirectiveUnitsPerMeter ) + ( CellInfoGetGlobalWireSpacingInMeters + DirectiveTable + DirectiveUnitsPerMeter ) ) ) + +(defun UpdateNetListGetSkillGetNetlistGlobalWireWidthFunc () + (lambda ( DirectiveTable + DirectiveUnitsPerMeter ) + ( CellInfoGetGlobalWireWidthInMeters + DirectiveTable + DirectiveUnitsPerMeter ) ) ) + +(defun UpdateNetlistGetSkillNetlistGetCellHeightFunc ( ) + (lambda + ( LibName + CellName + ViewName + HeightOfExistingBoundaryInMeters + ConnectivityInstanceNames + DirectivesTable + DirectiveUnitsPerMeter + GetCellHeightFunc + GetCellHeightFuncParams ) + (let ( + ( BitPitch ( arrayref DirectivesTable "bitpitch" ) ) + ( HeightInBitPitches ( arrayref DirectivesTable "height" ) ) ) + ( apply + GetCellHeightFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + HeightOfExistingBoundaryInMeters + ( cons + ConnectivityInstanceNames + ( cons + (when ( and BitPitch ( numberp BitPitch ) ) + ( quotient BitPitch DirectiveUnitsPerMeter ) ) + ( cons + (when ( and HeightInBitPitches ( numberp HeightInBitPitches ) ) + HeightInBitPitches ) + GetCellHeightFuncParams ) ) ) ) ) ) ) ) ) ) ) + +(defun UpdateNetlistGetSkillNetlistEstimateCellWidthFunc ( ) + (lambda + ( LibName + CellName + ViewName + CellHeightInMeters + NetlistsTablesTable + DirectivesTable + DirectiveUnitsPerMeter + EstimationFunc + EstimationFuncParams ) + (let ( + ( TotalTransistorGateAreaInMetersSquared ( NetlistTableGetTotalTransistorGateArea + ( arrayref NetlistsTablesTable ViewName ) ) ) + ( TotalTransistorGateLengthInMeters ( NetlistTableGetTotalTransistorLength + ( arrayref NetlistsTablesTable ViewName ) ) ) + ) + (when ( and TotalTransistorGateAreaInMetersSquared + TotalTransistorGateLengthInMeters ) + ( apply + EstimationFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + TotalTransistorGateAreaInMetersSquared + ( cons + TotalTransistorGateLengthInMeters + ( cons + CellHeightInMeters + ( cons + DirectivesTable + ( cons + DirectiveUnitsPerMeter + EstimationFuncParams ) ) ) ) ) ) ) ) ) ) ) ) ) + +(defun UpdateNetlistGetSkillNetlistEstimateCellPositionFunc ( ) + (lambda + ( LibName + CellName + ViewName + EstimationFunc + EstimationFuncParams ) + ( apply + EstimationFunc + ( cons + LibName + ( cons + CellName + ( cons + ViewName + EstimationFuncParams ) ) ) ) ) ) + +(defun UpdateNetlistGetPinChangeFunc ( ) + (lambda ( ConnectivityChanged + ForcePins + PinsFile + DirectiveTable + DirectiveUnitsPerMeter ) + (if ( or + ForcePins + ConnectivityChanged ) + (let ( + ( PinLPP ( CellInfoGetPinLayer DirectiveTable ) ) ) + (let ( + ( WirePitch ( CellInfoGetLayerWirePitchInMeters DirectiveTable PinLPP DirectiveUnitsPerMeter ) ) + ( WireWidth ( CellInfoGetLayerWireWidthInMeters DirectiveTable PinLPP DirectiveUnitsPerMeter ) ) + ( WireSpacing ( CellInfoGetLayerWireSpacingInMeters DirectiveTable PinLPP DirectiveUnitsPerMeter ) ) ) + ( list PinsFile WirePitch WireWidth WireSpacing PinLPP ) + ) ) ) ) ) + + + +(defun UpdateNetlistCompareCellViewsToSkillNetlist ( LibName + CellName + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + RequiredViews + ViewsToUpdate + UpdateOnlyViews + NetlistViewName + SkillNetlistDir + DirectivesSkillDir + AutopinsSkillDir + BoundaryLayerLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + GetInstanceTransformFunc + GetInstanceTransformFuncParams + GetCellHeightFunc + GetCellHeightFuncParams + WidthEstimationFunc + WidthEstimationFuncParams + PositionFunc + PositionFuncParams + NetlistTableTransformationFunc + NetlistTableTransformationFuncParams + LockBound + SuppressPins + ForcePins ) + ( printf "Loading Netlist for %L\n" CellName ) + (let ( + ( NetlistTable ( NetlistTableGetSkillNetlistTableForCellName + CellName + SkillNetlistDir ) ) ) + (if ( tablep NetlistTable ) + (let ( + ( PinsFile ( sprintf nil + "%s/%s.pins.il" + AutopinsSkillDir + CellName ) ) + ( DirectivesTable ( CellInfoGetTableForCellName + CellName + DirectivesSkillDir ) ) ) + (if ( tablep DirectivesTable ) + (let ( + ( ErrorStr nil ) + ( TransformedNetlistsTablesTable ( makeTable "tableOfNetlistTables" nil ) ) ) + ( foreach + ViewName + RequiredViews + (unless ErrorStr + (let ( + ( TransformedNetlistTable ( apply + NetlistTableTransformationFunc + ( cons + NetlistTable + ( cons + SkillNetlistDir + ( cons + DirectivesTable + ( cons + ViewName + NetlistTableTransformationFuncParams ) ) ) ) ) ) ) + (if ( tablep TransformedNetlistTable ) + ( setarray TransformedNetlistsTablesTable ViewName TransformedNetlistTable ) + ( setq ErrorStr TransformedNetlistTable ) ) ) ) ) + (if ( not ErrorStr ) + ( cons + nil + ( UpdateNetlistCompareCellViews + LibName + CellName + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + RequiredViews + ViewsToUpdate + UpdateOnlyViews + NetlistViewName + ( UpdateNetlistGetSkillNetlistInstanceExistsFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceTripplesFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceParameterPairsFunc ) + ( list TransformedNetlistsTablesTable ) + GetInstanceTransformFunc + GetInstanceTransformFuncParams + ( UpdateNetlistGetSkillNetlistInstanceHasConnectionFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceConnectionsFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistTerminalExistsFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetTerminalNamesFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistNetExistsFunc ) + ( list TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillGetNetlistNetNamesFunc ) + ( list TransformedNetlistsTablesTable ) + + ( UpdateNetListGetSkillGetNetlistNetWireSpacingFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistNetWireWidthFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + + ( UpdateNetListGetSkillGetNetlistLayerWireSpacingFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistLayerWireWidthFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + + ( UpdateNetListGetSkillGetNetlistGlobalWireSpacingFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistGlobalWireWidthFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + + ( UpdateNetlistGetSkillNetlistGetCellHeightFunc ) + ( list + DirectivesTable + DirectiveUnitsPerMeter + GetCellHeightFunc + GetCellHeightFuncParams ) + ( UpdateNetlistGetSkillNetlistEstimateCellWidthFunc ) + ( list + TransformedNetlistsTablesTable + DirectivesTable + DirectiveUnitsPerMeter + WidthEstimationFunc + WidthEstimationFuncParams ) + ( UpdateNetlistGetSkillNetlistEstimateCellPositionFunc ) + ( list + PositionFunc + PositionFuncParams ) + ( UpdateNetlistGetPinChangeFunc ) + ( list + PinsFile + DirectivesTable + DirectiveUnitsPerMeter ) + BoundaryLayerLPP + UserUnitsPerMeter + LockBound + SuppressPins + ForcePins ) ) + ( list + ErrorStr + ( list LibName CellName ) + nil ) ) ) + ( list + DirectivesTable + ( list LibName CellName ) + nil ) ) ) + ( list + NetlistTable + ( list LibName CellName ) + nil ) ) ) ) + +(defun UpdateNetlistCompareCellsToSkillNetlists ( LibCellPairList + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + RequiredViews + ViewsToUpdate + UpdateOnlyViews + NetlistViewName + SkillNetlistDir + DirectivesSkillDir + AutopinsSkillDir + BoundaryLayerLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + GetInstanceTransformFunc + GetInstanceTransformFuncParams + GetCellHeightFunc + GetCellHeightFuncParams + WidthEstimationFunc + WidthEstimationFuncParams + PositionFunc + PositionFuncParams + NetlistTableTransformationFunc + NetlistTableTransformationFuncParams + LockBound + SuppressPins + ForcePins ) + (let ( + ( Ret nil ) ) + ( foreach + LibCellPair + LibCellPairList + ( setq + Ret + ( tconc + Ret + (let ( + ( LibName ( car LibCellPair ) ) + ( CellName ( cadr LibCellPair ) ) ) + ( UpdateNetlistCompareCellViewsToSkillNetlist + ( car LibCellPair ) + ( cadr LibCellPair ) + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + RequiredViews + ViewsToUpdate + UpdateOnlyViews + NetlistViewName + SkillNetlistDir + DirectivesSkillDir + AutopinsSkillDir + BoundaryLayerLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + GetInstanceTransformFunc + GetInstanceTransformFuncParams + GetCellHeightFunc + GetCellHeightFuncParams + WidthEstimationFunc + WidthEstimationFuncParams + PositionFunc + PositionFuncParams + NetlistTableTransformationFunc + NetlistTableTransformationFuncParams + LockBound + SuppressPins + ForcePins ) ) ) ) ) + ( car Ret ) ) ) + +(defun UpdateNetlistAppendCompareResultsToPort ( CompareResults OutputPort ) + ( foreach + CellCompareResult + CompareResults + (let ( + ( LibCellPair ( cadr CellCompareResult ) ) + ( ViewCheckResults ( caddr CellCompareResult ) ) ) + ( foreach + ViewCheckResult + ViewCheckResults + (let ( + ( ViewName ( car ViewCheckResult ) ) + ( CompareResult ( cadr ViewCheckResult ) ) ) + (if CompareResult + (let () + (if ( ddGetObj ( car LibCellPair ) ( cadr LibCellPair ) ViewName ) + ( fprintf OutputPort "CELL: %s %s %s\n" ( car LibCellPair ) ( cadr LibCellPair ) ViewName ) + ( fprintf OutputPort "CREATE: %s %s %s\n" ( car LibCellPair ) ( cadr LibCellPair ) ViewName ) ) + ( UpdateNetlistPrintDifferences + CompareResult + OutputPort ) ) + (let () + ( fprintf OutputPort "IGNORE: %s %s %s\n" ( car LibCellPair ) ( cadr LibCellPair ) ViewName ) ) ) ) ) ) ) ) + +(defun UpdateNetlistAppendCompareResultsToFile ( CompareResults FileName ) + (let ( + ( OutputPort ( outfile FileName "a" ) ) ) + ( UpdateNetlistAppendCompareResultsToPort CompareResults OutputPort ) + ( close OutputPort ) ) ) + +(defun UpdateNetlistGetDescendantLibCellPairs ( RootCellView + LibCellExpressionPairsToIgnore ) + ( HierarchyGetDescendantLibCellPairs + RootCellView + LibCellExpressionPairsToIgnore + (lambda ( CellView ) + nil ) + nil ) ) + + +(defun UpdateNetlistSafeOpenCellViewForReading ( LibName CellName ViewName ) + (let ( + ( ViewDDObj ( ddGetObj LibName CellName ViewName ) ) ) + (when ( and + ViewDDObj + ( ddIsObjReadable ViewDDObj ) + ( car ( getq ViewDDObj files ) ) + ( ddIsObjReadable ( car ( getq ViewDDObj files ) ) ) ) + ( dbOpenCellViewByType + LibName + CellName + ViewName + nil + "r" ) ) ) ) + +(defun UpdateNetlistGetDefaultGetFloorplanInstanceTransformFunc () + (lambda + ( InstanceName ViewInfoTable LayoutViewName ) + (let ( + ( LayoutViewInfo ( arrayref ViewInfoTable LayoutViewName ) ) ) + (when LayoutViewInfo + (let ( + ( LayoutCellView ( car LayoutViewInfo ) ) + ( LayoutInstanceMap ( caddr LayoutViewInfo ) ) ) + (when LayoutCellView + (let ( + ( LayoutInstance ( car + ( NameGetInstancesForCanonicalName + LayoutInstanceMap + InstanceName ) ) ) ) + (when LayoutInstance + (let ( + ( LayoutTransform ( getq LayoutInstance transform ) ) ) + LayoutTransform ) ) ) ) ) ) ) ) ) + + +(defun UpdateNetlistGetDefaultGetFloorplanInstanceTransformFuncParams ( LayoutViewName ) + ( list LayoutViewName ) ) + +(defun UpdateNetlistGetNullGetInstanceTransformFunc () + (lambda + ( InstanceName ViewInfoTable ) + nil ) ) + +(defun UpdateNetlistGetNullGetInstanceTransformFuncParams () + nil ) + + +(defun UpdateNetlistGetDefaultGetInstanceTransformFunc () + (lambda + ( InstanceName ViewName ViewInfoTable FunctionTable ) + (let ( + ( ViewFunctions ( arrayref FunctionTable ViewName ) ) ) + (when ViewFunctions + (let ( + ( GetInstanceTransformFuncEntry ( car ViewFunctions ) ) ) + (let ( + ( GetInstanceTransformFunc ( car GetInstanceTransformFuncEntry ) ) + ( GetInstanceTransformFuncParams ( cadr GetInstanceTransformFuncEntry ) ) ) + ( apply + GetInstanceTransformFunc + ( cons + InstanceName + ( cons ViewInfoTable GetInstanceTransformFuncParams ) ) ) ) ) ) ) ) ) + +(defun UpdateNetlistGetFunctionTableForDefaultInstanceTransformFunctions ( NetlistViewName + LayoutViewName + FloorplanViewName ) + (let ( + ( Ret ( makeTable "instancePositionFunctionTable" nil ) ) ) + (when NetlistViewName + ( setarray + Ret + NetlistViewName + ( list + ( list + ( UpdateNetlistGetNullGetInstanceTransformFunc ) + ( UpdateNetlistGetNullGetInstanceTransformFuncParams ) ) ) ) ) + ( setarray + Ret + LayoutViewName + ( list + ( list + ( UpdateNetlistGetNullGetInstanceTransformFunc ) + ( UpdateNetlistGetNullGetInstanceTransformFuncParams ) ) ) ) + ( setarray + Ret + FloorplanViewName + ( list + ( list + ( UpdateNetlistGetDefaultGetFloorplanInstanceTransformFunc ) + ( UpdateNetlistGetDefaultGetFloorplanInstanceTransformFuncParams + LayoutViewName ) ) ) ) + Ret ) ) + + +(defun UpdateNetlistGetDefaultGetNetlistViewHeightFunc () + (lambda + ( LibName + CellName + ViewName + HeightOfExistingBoundaryInMeters + ConnectivityInstanceNames + BitPitchInMeters + HeightInBitPitches ) + nil ) ) + +(defun UpdateNetlistGetDefaultGetNetlistViewHeightFuncParams () + nil ) + +(defun UpdateNetlistGetDefaultGetNetlistViewWidthFunc () + (lambda + ( LibName + CellName + ViewName + TotalTransistorGateAreaInMetersSquared + TotalTransistorGateLengthInMeters + CellHeightInMeters ) + nil ) ) + +(defun UpdateNetlistGetDefaultGetNetlistViewWidthFuncParams () + nil ) + +(defun UpdateNetlistGetDefaultGetNetlistViewPositionFunc () + (lambda + ( LibName + CellName + ViewName ) + nil ) ) + +(defun UpdateNetlistGetDefaultGetNetlistViewPositionFuncParams () + nil ) + +(defun UpdateNetlistGetDefaultGetLayoutViewHeightFunc () + (lambda + ( LibName + CellName + ViewName + HeightOfExistingBoundaryInMeters + ConnectivityInstanceNames + BitPitchInMeters + HeightInBitPitches + BoundaryLPP + UserUnitsPerMeter + SmallCellWarningCutOff ) + + (let ( + ( DirectivesHeightInMeters (when ( and BitPitchInMeters HeightInBitPitches ) + ( times BitPitchInMeters HeightInBitPitches ) ) ) ) + (if ( and HeightOfExistingBoundaryInMeters DirectivesHeightInMeters ) + (if ( lessp HeightOfExistingBoundaryInMeters DirectivesHeightInMeters ) + ( list + HeightOfExistingBoundaryInMeters + (unless ( lessp HeightInBitPitches SmallCellWarningCutOff ) + ( sprintf + nil + "Height of boundary of \"%s\" \"%s\" \"%s\" is %0.9e, which is smaller than the %0.9e." + LibName + CellName + ViewName + HeightOfExistingBoundaryInMeters + DirectivesHeightInMeters ) ) ) + ( list DirectivesHeightInMeters nil ) ) + (if HeightOfExistingBoundaryInMeters + ( list HeightOfExistingBoundaryInMeters nil ) + (when ( and + DirectivesHeightInMeters + ( null ConnectivityInstanceNames ) ) + ( list DirectivesHeightInMeters nil ) ) ) ) ) ) ) + + +(defun UpdateNetlistGetDefaultGetLayoutViewHeightHeightFuncParams ( BoundaryLPP + UserUnitsPerMeter + SmallCellWarningCutOff ) + ( list BoundaryLPP UserUnitsPerMeter SmallCellWarningCutOff ) ) + +(defun UpdateNetlistGetDefaultGetLayoutViewWidthFunc () + (lambda + ( LibName + CellName + ViewName + TotalTransistorGateAreaInMetersSquared + TotalTransistorGateLengthInMeters + CellHeightInMeters + DirectivesTable + DirectiveUnitsPerMeter ) + nil ) ) + +(defun UpdateNetlistGetDefaultGetLayoutViewWidthFuncParams () + nil ) + +(defun UpdateNetlistGetDefaultGetLayoutViewPositionFunc () + (lambda + ( LibName + CellName + ViewName ) + nil ) ) + +(defun UpdateNetlistGetDefaultGetLayoutViewPositionFuncParams () + nil ) + +;If this function returns nil, UpdateNetlistCompareCellBoundary will +;return nil which means that if there is a boundary shape it will not +;be change and if there is not a boundary shape none will be created. +;This function should otherwise return a pair whose first element +;is the desire height of the boundary shape and whose second element +;is nil or a string containing a warning message. +(defun UpdateNetlistGetDefaultGetFloorplanViewHeightFunc () + (lambda + ( LibName + CellName + ViewName + HeightOfExistingBoundaryInMeters + ConnectivityInstanceNames + BitPitchInMeters + HeightInBitPitches + BoundaryLPP + UserUnitsPerMeter + SmallCellWarningCutOff + UseLayoutHeight + LayoutViewName ) + + (let ( + ;What does the height directive say? + ( DirectivesHeightInMeters (when ( and BitPitchInMeters HeightInBitPitches ) + ( times BitPitchInMeters HeightInBitPitches ) ) ) + ;Find the height of the boundary in the layout view if there is one. + ( BoundaryHeightInLayoutViewInMeters + (let ( + ( LayoutCellView ( UpdateNetlistSafeOpenCellViewForReading + LibName + CellName + LayoutViewName ) ) ) + (when LayoutCellView + (let ( + ( LayoutBoundaryBBox ( UpdateNetlistGetBoundaryLayerBBox + LayoutCellView + BoundaryLPP + t ) ) ) + (when LayoutBoundaryBBox + ( quotient + ( RectGetHeight LayoutBoundaryBBox ) + UserUnitsPerMeter ) ) ) ) ) ) ) + (if ( and BoundaryHeightInLayoutViewInMeters DirectivesHeightInMeters ) + ;If the layout has a boundary and the directive is specified + ;Or the user specified that we use the layout height + (if ( or + UseLayoutHeight + ( lessp BoundaryHeightInLayoutViewInMeters DirectivesHeightInMeters ) + ) + ;If boundary shape in the layout had a height less than + ;the height specified by the directive, use the height in the layout. + ( list + BoundaryHeightInLayoutViewInMeters + ;If the height specified by the directive is smaller + ;than the SmallCellWarningCutOff then don't emit a warning. + (unless ( lessp HeightInBitPitches SmallCellWarningCutOff ) + ( sprintf + nil + "Height of boundary of \"%s\" \"%s\" \"%s\" is %0.9e, which is smaller than the height directive value %0.9e." + LibName + CellName + LayoutViewName + BoundaryHeightInLayoutViewInMeters + DirectivesHeightInMeters ) ) ) + ;The height of the boundary shape in the layout was greater than + ;or equal to the height specified by the directive so just use the + ;directive value. + ( list DirectivesHeightInMeters nil ) ) + ;Either there is no Boundary shape in the layout + ;or the height directive did not have a value. + + (if BoundaryHeightInLayoutViewInMeters + ;If the layout does have a boundary shape, + ;use the height of that shape as the height for the floorplane view. + ( list BoundaryHeightInLayoutViewInMeters nil ) + ;There was no boundary shape in the layout so + ;use the directive value for the height if there is one + ;unless the cell is not a leaf cells. + (when ( and + DirectivesHeightInMeters + ( null ConnectivityInstanceNames ) ) + ( list DirectivesHeightInMeters nil ) ) ) ) ) ) ) + +(defun UpdateNetlistGetDefaultGetFloorplanViewHeightFuncParams ( BoundaryLPP + UserUnitsPerMeter + SmallCellWarningCutOff + UseLayoutHeight + LayoutViewName ) + ( list + BoundaryLPP + UserUnitsPerMeter + SmallCellWarningCutOff + UseLayoutHeight + LayoutViewName ) ) + + + +(defun UpdateNetlistGetDefaultGetFloorplanViewWidthFunc () + (lambda + ( LibName + CellName + ViewName + TotalTransistorGateAreaInMetersSquared + TotalTransistorGateLengthInMeters + CellHeightInMeters + DirectivesTable + DirectiveUnitsPerMeter + BoundaryLPP + LayoutViewName + UserUnitsPerMeter + WidthIncrement + BoundaryWidthWarningCutOff + DefaultDensityFactor + BoundaryScalingFactor ) + + (let ( + ;Get the width of the boundary shape in the layout if there is on. + ( WidthFromLayoutViewInMeters (let ( + ( LayoutCellView ( UpdateNetlistSafeOpenCellViewForReading + LibName + CellName + LayoutViewName ) ) ) + (when LayoutCellView + (let ( + ( LayoutBoundaryBBox ( UpdateNetlistGetBoundaryLayerBBox + LayoutCellView + BoundaryLPP + t ) ) ) + (when LayoutBoundaryBBox + ( quotient + ( RectGetWidth LayoutBoundaryBBox ) + UserUnitsPerMeter ) ) ) ) ) ) + ( DensityScaleFactorToUse (let ( + ( DensityScaleFactor ( arrayref DirectivesTable "density_scale_factor" ) ) ) + (if ( and + DensityScaleFactor + ( numberp DensityScaleFactor ) ) + ( float DensityScaleFactor ) + 1.0 ) ) ) + ( TransistorBaseWidthInMeters (let ( + ( TransistorBaseWidthInMeters + ( arrayref DirectivesTable "base_transistor_layout_width" ) ) ) + (if ( and + TransistorBaseWidthInMeters + ( numberp TransistorBaseWidthInMeters ) ) + ( float TransistorBaseWidthInMeters ) + 0.0 ) ) ) + ( DensityFactorToUse (let ( + ( DensityFactor ( arrayref DirectivesTable "density_factor" ) ) ) + (if ( and + DensityFactor + ( numberp DensityFactor ) ) + DensityFactor + DefaultDensityFactor ) ) ) ) + (if WidthFromLayoutViewInMeters + ;If the layout view had a boundary shape, use the width of that shape. + ( list WidthFromLayoutViewInMeters nil ) + ;If the layout view did not have a boundary shape then we'll have to guess. + (let ( + ;Guess the width. You can read the code as well as I can. + ;Notice that width is always rounded up to nearest multiple + ;of WidthIncrement. + ( Width ( times + ( ceiling + ( quotient + ( times + ( quotient + ( plus + ( times + TotalTransistorGateLengthInMeters + TransistorBaseWidthInMeters ) + TotalTransistorGateAreaInMetersSquared ) + CellHeightInMeters ) + ( times + DensityFactorToUse + DensityScaleFactorToUse + BoundaryScalingFactor ) ) + WidthIncrement ) ) + WidthIncrement ) ) ) + (if ( geqp Width BoundaryWidthWarningCutOff ) + ;If the guessed width is greater than minimum allowed width + ;use the guessed width. + ( list Width nil ) + ;If the guessed width is smaller than the minimum allowed width + ;use the minimum allowed width and generate a warning. + ( list BoundaryWidthWarningCutOff + ( sprintf nil + "Estimated width %.9e below cutoff of %.9e...enforcing cutoff" + Width + BoundaryWidthWarningCutOff ) ) ) ) ) ) ) ) + +(defun UpdateNetlistGetDefaultGetFloorplanViewWidthFuncParams ( BoundaryLPP + LayoutViewName + UserUnitsPerMeter + WidthIncrement + BoundaryWidthWarningCutOff + DefaultDensityFactor + BoundaryScalingFactor ) + ( list + BoundaryLPP + LayoutViewName + UserUnitsPerMeter + WidthIncrement + BoundaryWidthWarningCutOff + DefaultDensityFactor + BoundaryScalingFactor ) ) + +(defun UpdateNetlistGetDefaultGetFloorplanViewPositionFunc ( ) + ( lambda + ( LibName + CellName + ViewName + UserUnitsPerMeter + LayoutViewName + BoundaryLPP + DefaultBoundaryPosition ) + (let ( + ( BoundaryPositionInLayoutViewInMeters + (let ( + ( LayoutCellView ( UpdateNetlistSafeOpenCellViewForReading + LibName + CellName + LayoutViewName ) ) ) + (when LayoutCellView + (let ( + ( LayoutBoundaryBBox ( UpdateNetlistGetBoundaryLayerBBox + LayoutCellView + BoundaryLPP + t ) ) ) + (when LayoutBoundaryBBox + ( list + ( quotient ( caar LayoutBoundaryBBox ) UserUnitsPerMeter ) + ( quotient ( cadar LayoutBoundaryBBox ) UserUnitsPerMeter ) ) ) ) ) ) ) ) + (if BoundaryPositionInLayoutViewInMeters + ( list BoundaryPositionInLayoutViewInMeters nil ) + ( list DefaultBoundaryPosition nil ) ) ) ) ) + + +(defun UpdateNetlistGetDefaultGetFloorplanViewPositionFuncParams ( UserUnitsPerMeter + LayoutViewName + BoundaryLPP + DefaultBoundaryPosition ) + ( list + UserUnitsPerMeter + LayoutViewName + BoundaryLPP + DefaultBoundaryPosition ) ) + + +(defun UpdateNetlistGetDefaultGetCellHeightFunc ( ) + (lambda + ( LibName + CellName + ViewName + HeightOfExistingBoundaryInMeters + ConnectivityInstanceNames + BitPitchInMeters + HeightInBitPitches + FunctionTable ) + (let ( + ( ViewFunctions ( arrayref FunctionTable ViewName ) ) ) + (when ViewFunctions + (let ( + ( HeightFunctionEntry ( car ViewFunctions ) ) ) + (let ( + ( HeightFunction ( car HeightFunctionEntry ) ) + ( HeightFunctionParams ( cadr HeightFunctionEntry ) ) ) + ( apply + HeightFunction + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + HeightOfExistingBoundaryInMeters + ( cons + ConnectivityInstanceNames + ( cons + BitPitchInMeters + ( cons + HeightInBitPitches + HeightFunctionParams ) ) ) ) ) ) ) ) ) ) ) ) ) ) + +(defun UpdateNetlistGetDefaultGetCellWidthFunc ( ) + (lambda + ( LibName + CellName + ViewName + TotalTransistorGateAreaInMetersSquared + TotalTransistorGateLengthInMeters + CellHeightInMeters + DirectivesTable + DirectiveUnitsPerMeter + FunctionTable ) + (let ( + ( ViewFunctions ( arrayref FunctionTable ViewName ) ) ) + (when ViewFunctions + (let ( + ( WidthFunctionEntry ( cadr ViewFunctions ) ) ) + (let ( + ( WidthFunction ( car WidthFunctionEntry ) ) + ( WidthFunctionParams ( cadr WidthFunctionEntry ) ) ) + ( apply + WidthFunction + ( cons + LibName + ( cons + CellName + ( cons + ViewName + ( cons + TotalTransistorGateAreaInMetersSquared + ( cons + TotalTransistorGateLengthInMeters + ( cons + CellHeightInMeters + ( cons + DirectivesTable + ( cons + DirectiveUnitsPerMeter + WidthFunctionParams ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) + +(defun UpdateNetlistGetDefaultGetCellPositionFunc ( ) + (lambda + ( LibName + CellName + ViewName + FunctionTable ) + (let ( + ( ViewFunctions ( arrayref FunctionTable ViewName ) ) ) + (when ViewFunctions + (let ( + ( PositionFunctionEntry ( caddr ViewFunctions ) ) ) + (let ( + ( PositionFunction ( car PositionFunctionEntry ) ) + ( PositionFunctionParams ( cadr PositionFunctionEntry ) ) ) + ( apply + PositionFunction + ( cons + LibName + ( cons + CellName + ( cons + ViewName + PositionFunctionParams ) ) ) ) ) ) ) ) ) ) + + +(defun UpdateNetlistGetFunctionTableForDefaultWidthAndHeightAndPositionFunctions ( NetlistViewName + LayoutViewName + FloorplanViewName + BoundaryLPP + UserUnitsPerMeter + WidthIncrement + BoundaryWidthWarningCutOff + DefaultDensityFactor + BoundaryScalingFactor + SmallCellWarningCutOff + UseLayoutHeight + DefaultBoundaryPosition ) + (let ( + ( Ret ( makeTable "boundaryFunctionTable" nil ) ) ) + (when NetlistViewName + ( setarray + Ret + NetlistViewName + ( list + ( list + ( UpdateNetlistGetDefaultGetNetlistViewHeightFunc ) + ( UpdateNetlistGetDefaultGetNetlistViewHeightFuncParams ) ) + ( list + ( UpdateNetlistGetDefaultGetNetlistViewWidthFunc ) + ( UpdateNetlistGetDefaultGetNetlistViewWidthFuncParams ) ) + ( list + ( UpdateNetlistGetDefaultGetNetlistViewPositionFunc ) + ( UpdateNetlistGetDefaultGetNetlistViewPositionFuncParams ) ) ) ) ) + ( setarray + Ret + LayoutViewName + ( list + ( list + ( UpdateNetlistGetDefaultGetLayoutViewHeightFunc ) + ( UpdateNetlistGetDefaultGetLayoutViewHeightHeightFuncParams + BoundaryLPP + UserUnitsPerMeter + SmallCellWarningCutOff ) ) + ( list + ( UpdateNetlistGetDefaultGetLayoutViewWidthFunc ) + ( UpdateNetlistGetDefaultGetLayoutViewWidthFuncParams ) ) + ( list + ( UpdateNetlistGetDefaultGetLayoutViewPositionFunc ) + ( UpdateNetlistGetDefaultGetLayoutViewPositionFuncParams ) ) ) ) + ( setarray + Ret + FloorplanViewName + ( list + ( list + ( UpdateNetlistGetDefaultGetFloorplanViewHeightFunc ) + ( UpdateNetlistGetDefaultGetFloorplanViewHeightFuncParams + BoundaryLPP + UserUnitsPerMeter + SmallCellWarningCutOff + UseLayoutHeight + LayoutViewName ) ) + ( list + ( UpdateNetlistGetDefaultGetFloorplanViewWidthFunc ) + ( UpdateNetlistGetDefaultGetFloorplanViewWidthFuncParams + BoundaryLPP + LayoutViewName + UserUnitsPerMeter + WidthIncrement + BoundaryWidthWarningCutOff + DefaultDensityFactor + BoundaryScalingFactor ) ) + ( list + ( UpdateNetlistGetDefaultGetFloorplanViewPositionFunc ) + ( UpdateNetlistGetDefaultGetFloorplanViewPositionFuncParams + UserUnitsPerMeter + LayoutViewName + BoundaryLPP + DefaultBoundaryPosition ) ) ) ) + Ret ) ) + + +(defun UpdateNetlistGetNullNetlistTransformationFunc () + (lambda + ( OriginalNetlistTable + SkillNetlistDir + DirectivesTable + ViewName ) + OriginalNetlistTable ) ) + +(defun UpdateNetlistTransformNetlistTableForLayoutView () + (lambda + ( OriginalNetlistTable + SkillNetlistDir + DirectivesTable + ViewName + ShouldInlineConnectionsFunc + ShouldInlineConnectionsFuncParams ) + ( InlineConnectionsHierTransformTable + OriginalNetlistTable + ShouldInlineConnectionsFunc + ( cons + DirectivesTable + ShouldInlineConnectionsFuncParams ) + SkillNetlistDir ) ) ) + +(defun UpdateNetlistGetDefaultNetlistTransformationFunc () + (lambda + ( OriginalNetlistTable + SkillNetlistDir + DirectivesTable + ViewName + TransformationFunctionTable ) + (let ( + ( TransformationFuncEntry ( arrayref TransformationFunctionTable ViewName ) ) ) + (let ( + ( TransformationFunc ( car TransformationFuncEntry ) ) + ( TransformationFuncParams ( cadr TransformationFuncEntry ) ) ) + ( apply + TransformationFunc + ( cons + OriginalNetlistTable + ( cons + SkillNetlistDir + ( cons + DirectivesTable + ( cons + ViewName + TransformationFuncParams ) ) ) ) ) ) ) ) ) + + +(defun UpdateNetlistGetDefaultShouldInLineConnectionsFunc () + (lambda + ( LibName + CellName + InstanceName + InstanceMasterLibName + InstanceMasterCellName + DirectivesTable + DirectivesSkillDir ) +; (let ( +; ( CurrDirectivesTable ( CellInfoGetTableForCellName +; CellName +; DirectivesSkillDir ) ) ) +; ( and +; nil +; ( CellInfoLookupParametrizedInBlock +; DirectivesTable +; "subcell" +; "inline_layout" +; "instance" +; InstanceName ) +; ) ) + nil + ) ) + +(defun UpdateNetlistGetFunctionTableForNetlistTransformationFunctions ( NetlistViewName + LayoutViewName + FloorplanViewName + DirectivesSkillDir ) + (let ( + ( NetlistTransformationFunctionsTable ( makeTable "functionTable" nil ) ) ) + (when NetlistViewName + ( setarray + NetlistTransformationFunctionsTable + NetlistViewName + ( list + ( UpdateNetlistGetNullNetlistTransformationFunc ) + nil ) ) ) + ( setarray + NetlistTransformationFunctionsTable + FloorplanViewName + ( list + ( UpdateNetlistGetNullNetlistTransformationFunc ) + nil ) ) + ( setarray + NetlistTransformationFunctionsTable + LayoutViewName + ( list + ( UpdateNetlistTransformNetlistTableForLayoutView ) + ( list + ( UpdateNetlistGetDefaultShouldInLineConnectionsFunc ) + ( list DirectivesSkillDir ) ) ) ) + NetlistTransformationFunctionsTable ) ) + +; lookup a CAST directive by name, if not found, use default value +(defun CellInfoLookupWithDefault ( DirectivesTable name default ) + (let ((x (CellInfoLookup DirectivesTable name))) + (cond (x x) ((not x) default)) + ) + ) + +(defun UpdateNetlistCompareCellsToSkillNetlistsInToFileUsingPDKInfo ( LibCellPairList + NetlistViewName + LayoutViewName + FloorplanViewName + SkillNetlistDir + DirectivesSkillDir + AutopinsSkillDir + DefaultDensityFactor + BoundaryScalingFactor + OutputFileName + LockBound + SuppressPins + ForcePins + UseLayoutHeight + LockLayoutView ) + (let ( + ( FilteredLibCellPairList + ( setof + LibCellPair + LibCellPairList + ( not + ( or + ( equal ( car LibCellPair ) StackLibraryName ) + ( equal ( car LibCellPair ) GateLibraryName ) ) ) ) ) ) + (let ( + ( DirectivesTable + ( CellInfoGetTableForCellName + ( cadr ( car FilteredLibCellPairList ) ) + DirectivesSkillDir ) ) ) + (let ( + ( BoundaryPosition + (CellInfoLookupWithDefault + DirectivesTable "boundary_position" BoundaryPosition)) + ( BoundaryWidthIncrement + (CellInfoLookupWithDefault + DirectivesTable "boundary_width_increment" BoundaryWidthIncrement)) + ( BoundaryWidthWarningCutOff + (CellInfoLookupWithDefault + DirectivesTable "boundary_width_warning_cutoff" BoundaryWidthWarningCutOff)) + ( BoundarySmallCellWarningCutOff + (CellInfoLookupWithDefault + DirectivesTable "boundary_small_cell_warning_cutoff" BoundarySmallCellWarningCutOff)) + ) + + + (let ( + ( InstanceTransformFunctionTable ( UpdateNetlistGetFunctionTableForDefaultInstanceTransformFunctions + NetlistViewName + LayoutViewName + FloorplanViewName ) ) + + ( HeightWidthFunctionTable ( UpdateNetlistGetFunctionTableForDefaultWidthAndHeightAndPositionFunctions + NetlistViewName + LayoutViewName + FloorplanViewName + BoundaryLPP + UserUnitsPerMeter + BoundaryWidthIncrement + BoundaryWidthWarningCutOff + DefaultDensityFactor + BoundaryScalingFactor + BoundarySmallCellWarningCutOff + UseLayoutHeight + BoundaryPosition ) ) + ( NetlistTransformationFunctionTable ( UpdateNetlistGetFunctionTableForNetlistTransformationFunctions + NetlistViewName + LayoutViewName + FloorplanViewName + DirectivesSkillDir ) ) ) + (let ( + ( CompareResults ( UpdateNetlistCompareCellsToSkillNetlists + FilteredLibCellPairList\ + ( cons + ( list ".*" ".+\\.wires\\..+" ) + ( cons + ( list + ( sprintf nil "^%s$" GateLibraryName ) + ".*" ) + ( cons + ( list + ( sprintf nil "^%s$" StackLibraryName ) + ".*" ) + ( cons + ( list TechLibName ".*" ) + ( cons + ( list "^$" "" ) + TransistorLibCellPairs + ) ) ) ) ) + TransistorLibCellPairs + ( setof + ViewName + ( list + FloorplanViewName + NetlistViewName + LayoutViewName ) + ViewName ) + ( setof + ViewName + ( list + FloorplanViewName + NetlistViewName + (unless LockLayoutView + LayoutViewName ) ) + ViewName ) + ( list LayoutViewName ) + NetlistViewName + SkillNetlistDir + DirectivesSkillDir + AutopinsSkillDir + BoundaryLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + ( UpdateNetlistGetDefaultGetInstanceTransformFunc ) + ( list InstanceTransformFunctionTable ) + ( UpdateNetlistGetDefaultGetCellHeightFunc ) + ( list HeightWidthFunctionTable ) + ( UpdateNetlistGetDefaultGetCellWidthFunc ) + ( list HeightWidthFunctionTable ) + ( UpdateNetlistGetDefaultGetCellPositionFunc ) + ( list HeightWidthFunctionTable ) + ( UpdateNetlistGetDefaultNetlistTransformationFunc ) + ( list NetlistTransformationFunctionTable ) + LockBound + SuppressPins + ForcePins ) ) ) + ( UpdateNetlistAppendCompareResultsToFile + CompareResults + OutputFileName ) + nil ) ) ) ) ) ) + +; Resolve BUG 13423: Compute GetPinLength = min(PinLength,BoundaryWidth/2-WireSpacing) +(defun GetPinLength (CellView BoundaryLPP WireSpacing) + (let ((BBox (UpdateNetlistGetBoundaryLayerBBox CellView BoundaryLPP nil))) + (if BBox (min PinLength (RectGetWidth BBox)/UserUnitsPerMeter/2-WireSpacing) + PinLength))) + +(defun UpdateNetlistUpdateCellViewWithCompareResult ( CellView + CompareResult + InstanceMap + BoundaryLPP + UserUnitsPerMeter + @key + ( DoNotMoveExistingInstances t ) + ) + (let ( + ( ErrorStr nil ) + ( CurrY 0 ) + ( InstancesToDelete ( UpdateNetlistGetInstancesToDeleteFromCompareResult CompareResult ) ) + ( InstancesToChange ( UpdateNetlistGetInstancesToChangeFromCompareResult CompareResult ) ) + ( InstancesToCreate ( UpdateNetlistGetInstancesToCreateFromCompareResult CompareResult ) ) + ( ParametersToSet ( UpdateNetlistGetParametersToSetFromCompareResult CompareResult ) ) + ( ConnectionsToDelete ( UpdateNetlistGetConnectionsToDeleteFromCompareResult CompareResult ) ) + ( ConnectionsToCreate ( UpdateNetlistGetConnectionsToCreateFromCompareResult CompareResult ) ) + ( TerminalsToDelete ( UpdateNetlistGetTerminalsToDeleteFromCompareResult CompareResult ) ) + ( TerminalsToCreate ( UpdateNetlistGetTerminalsToCreateFromCompareResult CompareResult ) ) + ( NetsToDelete ( UpdateNetlistGetNetsToDeleteFromCompareResult CompareResult ) ) + ( NetsToCreate ( UpdateNetlistGetNetsToCreateFromCompareResult CompareResult ) ) + ( NetsToChange ( UpdateNetlistGetNetsToChangeFromCompareResult CompareResult ) ) + ( BoundaryShape ( UpdateNetlistGetBoundaryShapeFromCompareResult CompareResult ) ) + ( BoundaryHeight ( UpdateNetlistGetBoundaryHeightFromCompareResult CompareResult ) ) + ( BoundaryWidth ( UpdateNetlistGetBoundaryWidthFromCompareResult CompareResult ) ) + ( BoundaryPosition ( UpdateNetlistGetBoundaryPositionFromCompareResult CompareResult ) ) + ( OldBoundaryHeight ( UpdateNetlistGetOldBoundaryHeightFromCompareResult CompareResult ) ) ) + + ( foreach + TerminalToDelete + TerminalsToDelete + ( when TerminalToDelete ( dbDeleteObject + TerminalToDelete ) ) ) + + ( foreach + ConnectionToDelete + ConnectionsToDelete + ( when ConnectionToDelete ( dbDeleteObject + ConnectionToDelete ) ) ) + + ( foreach + NetToDelete + NetsToDelete + ( when NetToDelete ( dbDeleteObject + NetToDelete ) ) ) + + ( foreach + InstanceToDelete + InstancesToDelete + ( when InstanceToDelete ( dbDeleteObject + InstanceToDelete ) ) ) + + if( InstancesToChange then println("Updating InstancesToChange...")) + + ( foreach + InstanceToChange + InstancesToChange + (unless ErrorStr + (let ( + ( InstName ( UpdateNetlistGetInstanceNameFromInstanceToChange InstanceToChange ) ) + ( InstCellName ( UpdateNetlistGetCellNameFromInstanceToChange InstanceToChange ) ) + ( InstLibName ( UpdateNetlistGetLibNameFromInstanceToChange InstanceToChange ) ) + ( InstToChangeDBObj ( UpdateNetlistGetInstanceDBObjFromInstanceToChange InstanceToChange ) ) + ( InstTransform ( UpdateNetlistGetInstanceTransformFromInstanceToChange InstanceToChange ) ) ) + + ;TODO - remove...this will prevent swapping out of subtypes in + ; layout that have no counterpart in the spec + (when nil + (when ( rexMatchp ( sprintf nil "%s.*" InstCellName ) + InstToChangeDBObj->cellName ) + ( setq InstCellName InstToChangeDBObj->cellName ) + ( printf "Not actually changing %s of type %s\n" + InstToChangeDBObj->name + InstToChangeDBObj->cellName ) + ) + ) + + (let ( + ( NewMasterCellViewDDObj + (let ( + ( MasterViewDDObjWithSameViewName + ( ddGetObj + InstLibName + InstCellName + InstToChangeDBObj~>viewName + ) ) ) + (if MasterViewDDObjWithSameViewName + MasterViewDDObjWithSameViewName + (if ( equal ( getq CellView cellViewType ) "schematic" ) + ( ddGetObj + InstLibName + InstCellName + "symbol" ) + (if ( equal ( getq CellView cellViewType ) "maskLayout" ) + ( ddGetObj + InstLibName + InstCellName + "layout" ) ) ) ) ) ) ) + (if NewMasterCellViewDDObj + (let ( + ( NewMasterCellView ( dbOpenCellViewByType + InstLibName + InstCellName + ( getq NewMasterCellViewDDObj name ) + nil + "r" ) ) ) + (if NewMasterCellView + (if ( UpdateNetlistInstanceHasMaster + InstToChangeDBObj ) + (let () + ( dbSetq InstToChangeDBObj NewMasterCellView master ) + ( dbSetq InstToChangeDBObj InstName name ) + (when InstTransform + ( dbSetq InstToChangeDBObj InstTransform transform ) ) ) + (let ( + ( MyInstTransform (if InstTransform InstTransform ( getq InstToChangeDBObj transform ) ) ) + ( InstOrient ( getq InstToChangeDBObj orient ) ) ) + ( dbDeleteObject InstToChangeDBObj ) + ( dbCreateInst + CellView + NewMasterCellView + InstName + ( car MyInstTransform ) + ( cadr MyInstTransform ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "DDObj for %L %L %L exists but the CellView could not be opened." + InstLibName + InstCellName + ( getq CellView viewName ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "%L in %L does not have a %L view for %L in %L." + InstCellName + InstLibName + ( getq CellView viewName ) + InstName + ( getq CellView cellName ) ) ) ) ) ) ) ) + + if( InstancesToCreate then println("Updating InstancesToCreate...")) + + ( foreach + InstanceToCreate + InstancesToCreate + (unless ErrorStr + (let ( + ( InstName ( UpdateNetlistGetInstanceNameFromInstanceToCreate InstanceToCreate ) ) + ( InstLibName ( UpdateNetlistGetLibNameFromInstanceToCreate InstanceToCreate ) ) + ( InstCellName ( UpdateNetlistGetCellNameFromInstanceToCreate InstanceToCreate ) ) + ( InstTransform ( UpdateNetlistGetInstanceTransformFromInstanceToCreate InstanceToCreate ) ) ) + (let ( + ( NewMasterCellViewDDObj + (let ( + ( MasterViewDDObjWithSameViewName + ( ddGetObj + InstLibName + InstCellName + ( getq CellView viewName ) ) ) ) + (if MasterViewDDObjWithSameViewName + MasterViewDDObjWithSameViewName + (if ( equal ( getq CellView cellViewType ) "schematic" ) + ( ddGetObj + InstLibName + InstCellName + "symbol" ) + (if ( equal ( getq CellView cellViewType ) "maskLayout" ) + ( ddGetObj + InstLibName + InstCellName + "layout" ) ) ) ) ) ) ) + (if NewMasterCellViewDDObj + (let ( + ( NewMasterCellView ( dbOpenCellViewByType + InstLibName + InstCellName + ( getq NewMasterCellViewDDObj name ) + nil + "r" ) ) ) + (if NewMasterCellView + (let ( + ( NewMasterBBox ( dbComputeBBoxNoNLP NewMasterCellView ) ) ) + (let ( + ( NewInst + ( dbCreateInst + CellView + NewMasterCellView + InstName + (if InstTransform + ( car InstTransform ) + ( list + ( difference 0 ( RectGetRight NewMasterBBox ) ) + ( difference CurrY ( RectGetTop NewMasterBBox ) ) ) ) + (if InstTransform + ( cadr InstTransform ) + "R0" ) ) ) ) + ( NameAddNonFoldableInstanceToInstanceMap + InstanceMap + NewInst ) + (unless InstTransform + ( setq CurrY ( difference + ( RectGetBottom ( getq NewInst bBox ) ) + 6.0 ) ) + + + ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "DDObj for %L %L %L exists but the CellView could not be opened." + InstLibName + InstCellName + ( getq CellView viewName ) ) ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "%L in %L does not have a %L view for %L in %L." + InstCellName + InstLibName + ( getq CellView viewName ) + InstName + ( getq CellView cellName ) ) ) ) ) ) ) ) + if( ParametersToSet then println("Updating ParemetersToSet...")) + + ( foreach + ParameterToSet + ParametersToSet + (let ( + ( InstanceName ( UpdateNetlistGetInstanceNameFromParameterToSet ParameterToSet ) ) + ( ParamName ( UpdateNetlistGetParameterNameFromParameterToSet ParameterToSet ) ) + ( ParamValue ( UpdateNetlistGetParameterValueFromParameterToSet ParameterToSet ) ) ) + (let ( + ( Instances ( NameGetInstancesForCanonicalName InstanceMap InstanceName ) ) ) + ( foreach Instance Instances + (let ( + ( ParamType ( PCellGetParamTypeForSchematicInstance Instance ParamName ) ) ) + ( dbReplaceProp + Instance + ParamName + (if ParamType + ParamType + "float" ) + (cond + ( + ( equal ParamType "boolean" ) + (if ( equal ParamValue 0.0 ) + nil + t ) ) + ( + ( equal ParamType "string" ) + ( sprintf nil "%e" ParamValue ) ) + ( + t + ParamValue ) ) ) ) ) ) ) ) + + SyncNetlistInitFloorplan( CellView InstancesToCreate InstanceMap + ?DoNotMoveExistingInstances DoNotMoveExistingInstances + ) + + (unless ErrorStr + ( foreach + NetToCreate + NetsToCreate + ( dbCreateNet CellView NetToCreate ) ) ) + + ( foreach + NetToChangeSpec + NetsToChange + (let ( + ( NetToChange ( car NetToChangeSpec ) ) + ( WireSpacing ( cadr NetToChangeSpec ) ) + ( WireWidth ( caddr NetToChangeSpec ) ) + ) + (when WireSpacing + ( ConstraintsReplaceNetWireSpacing + ( dbFindNetByName CellView NetToChange ) + WireSpacing ) ) + (when WireWidth + ( ConstraintsReplaceNetWireWidth + ( dbFindNetByName CellView NetToChange ) + WireWidth ) + ) ) ) + + ( foreach + ConnectionToCreate + ConnectionsToCreate + (unless ErrorStr + (let ( + ( ConnectionInstanceName ( UpdateNetlistGetInstanceNameFromConnectionToCreate + ConnectionToCreate ) ) + ( ConnectionTerminalName ( UpdateNetlistGetTerminalNameFromConnectionToCreate + ConnectionToCreate ) ) + ( ConnectionNetName ( UpdateNetlistGetNetNameFromConnectionToCreate + ConnectionToCreate ) ) ) + (let ( + ( InstanceToConnectTo ( car + ( NameGetInstancesForCanonicalName + InstanceMap + ConnectionInstanceName ) ) ) ) + (if InstanceToConnectTo + (let ( + ( TerminalToConnectTo ( ListFindElement + ( getq ( getq InstanceToConnectTo master ) terminals ) + (lambda + ( Terminal TerminalToFind ) + ( equal + ( getq Terminal name ) + TerminalToFind ) ) + ( list ConnectionTerminalName ) ) ) ) + (if TerminalToConnectTo then + OldInstTerm=car(setof( instTerm InstanceToConnectTo~>instTerms instTerm~>name==ConnectionTerminalName)) + if( OldInstTerm dbDeleteObject( OldInstTerm )) + ( dbCreateConn + ( dbMakeNet CellView ConnectionNetName ) + InstanceToConnectTo + TerminalToConnectTo ) + else ( printf + "WARNING: The master of instance %L in %L %L, %L %L %L, does not have a terminal %L.\n" + ( getq InstanceToConnectTo name ) + ( getq CellView cellName ) + ( getq CellView viewName ) + ( getq InstanceToConnectTo libName ) + ( getq InstanceToConnectTo cellName ) + ( getq InstanceToConnectTo viewName ) + ConnectionTerminalName ) ) ) + ( setq + ErrorStr + ( sprintf + nil + "Unable to find instance %L in %L %L %L." + ConnectionInstanceName + ( getq CellView libName ) + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) ) ) ) ) ) + (unless ErrorStr + ( foreach + TerminalToCreate + TerminalsToCreate + ( dbCreateTerm + ( dbMakeNet CellView TerminalToCreate ) + TerminalToCreate + "inputOutput" ) ) ) + + (unless ErrorStr + (when BoundaryShape + (if ( and BoundaryHeight BoundaryWidth BoundaryPosition ) + ( dbDeleteObject + BoundaryShape ) + ( setq + ErrorStr + ( sprintf + nil + "%L %L Boundary needs to change, but either the height( %L ), width( %L ), or position( %L ) is nil." + ( getq CellView cellName ) + ( getq CellView viewName ) + BoundaryHeight + BoundaryWidth + BoundaryPosition ) ) ) ) ) + + (unless ErrorStr + (when ( and BoundaryHeight BoundaryWidth BoundaryPosition ) + println("Updating PRBoundary...") + ( dbCreatePRBoundary + CellView + ( RectGetPolygonPoints ( RectMakeRect + ( times UserUnitsPerMeter ( car BoundaryPosition ) ) + ( times UserUnitsPerMeter ( cadr BoundaryPosition ) ) + ( times UserUnitsPerMeter BoundaryWidth ) + ( times UserUnitsPerMeter BoundaryHeight ) ) ) ) + ( SetXAlignmentProp CellView DefaultWiringPitch*2 ) + ( SetYAlignmentProp CellView GridPitch ) + ( SetLeafProp CellView t ) + ) + ) + + (unless ErrorStr + (when ( and + ( equal ( getq CellView cellViewType ) "maskLayout" ) + ( UpdateNetlistGetPinChangeFromCompareResult CompareResult ) + ( stringp ( UpdateNetlistGetPinsFileFromCompareResult CompareResult) ) + ( isFile ( UpdateNetlistGetPinsFileFromCompareResult CompareResult) ) + ( numberp ( UpdateNetlistGetWirePitchFromCompareResult CompareResult) ) + ( numberp ( UpdateNetlistGetWireWidthFromCompareResult CompareResult) ) + ( numberp ( UpdateNetlistGetWireSpacingFromCompareResult CompareResult) ) ) + +; ( errset + ( PinPlaceDrawUsingPDKInfo + CellView + ?PowerGrid nil + ?InPlace t + ?PinsDirectory nil ;use dfii cell dir + ?ConnectivityViewName ( getq CellView viewName ) + ?PinsFile ( UpdateNetlistGetPinsFileFromCompareResult CompareResult) + ?PinLength (GetPinLength CellView BoundaryLPP (UpdateNetlistGetWireSpacingFromCompareResult CompareResult)) + ?PinLPP + ( list + ( car ( UpdateNetlistGetPinLPPFromCompareResult CompareResult) ) + "pin" ) + ?BoundaryPinHorizontalSpacing + ( quotient + ( UpdateNetlistGetWireSpacingFromCompareResult CompareResult) + 2.0 ) + ?BoundaryPinVerticalSpacing 0.0 + ) + ;) + ) ) + + ErrorStr ) ) + + +(defun UpdateNetlistGetErrorsFromCompareResults ( CompareResults ) + (let ( + ( Result nil ) ) + ( foreach + CellCompareResult + CompareResults + (let ( + ( LibName ( car ( cadr CellCompareResult ) ) ) + ( CellName ( cadr ( cadr CellCompareResult ) ) ) + ( ViewCheckResults ( caddr CellCompareResult ) ) ) + ( foreach + ViewCheckResult + ViewCheckResults + (let ( + ( ViewName ( car ViewCheckResult ) ) + ( ViewCompareResult ( cadr ViewCheckResult ) ) + ( InstanceMap ( caddr ViewCheckResult ) ) ) + (when ViewCompareResult + (let ( + ( ErrorsForView ( UpdateNetlistGetErrorsFromCompareResult ViewCompareResult ) ) ) + (when ErrorsForView + ( setq + Result + ( tconc + Result + ErrorsForView ) ) ) ) ) ) ) ) ) + + ( car Result ) ) ) + +(defun UpdateNetlistUpdateCellsFromCompareResults ( CompareResults + WriteableCellViewTable + BoundaryLPP + UserUnitsPerMeter + OutputPort ) + (let ( + ( Result nil ) ) + + ( foreach + CellCompareResult + CompareResults + (let ( + ( LibName ( car ( cadr CellCompareResult ) ) ) + ( CellName ( cadr ( cadr CellCompareResult ) ) ) + ( ViewCheckResults ( caddr CellCompareResult ) ) ) + ( foreach + ViewCheckResult + ViewCheckResults + (let ( + ( ViewName ( car ViewCheckResult ) ) + ( ViewCompareResult ( cadr ViewCheckResult ) ) + ( InstanceMap ( caddr ViewCheckResult ) ) ) + (when ViewCompareResult + ( setq + Result + ( tconc + Result + ( list + ( list LibName CellName ViewName ) + (let ( + ( CurrCellView ( arrayref + WriteableCellViewTable + ( list LibName CellName ViewName ) ) ) ) + (if CurrCellView + (let () + ( printf "Updating %L %L\n" CellName ViewName ) + (let ( + ( UpdateResult + ( UpdateNetlistUpdateCellViewWithCompareResult + CurrCellView + ViewCompareResult + InstanceMap + BoundaryLPP + UserUnitsPerMeter ) ) ) + ( printf "Saving and Purging %L %L\n" CellName ViewName ) + (if ( dbSave CurrCellView ) + ( fprintf OutputPort "SAVED: %s %s\n" CellName ViewName ) ) + ( dbReopen CurrCellView "r" ) + UpdateResult ) ) + ( sprintf + nil + "Unable to get writeable view for %L %L %L.\n" + LibName + CellName + ViewName ) ) ) ) ) ) ) ) ) ) ) + ( car Result ) ) ) + +(defun UpdateNetlistUpdateCellsFromCompareResultsToPort ( CompareResults + WriteableCellViewTable + BoundaryLPP + UserUnitsPerMeter + OutputPort ) + (let ( + ( HadError nil ) ) + ( foreach + UpdateResult + ( UpdateNetlistUpdateCellsFromCompareResults + CompareResults + WriteableCellViewTable + BoundaryLPP + UserUnitsPerMeter + OutputPort ) + (let ( + ( ErrorStr ( cadr UpdateResult ) ) ) + (when ErrorStr + ( setq HadError t ) + ( fprintf OutputPort "Error: %s\n" ErrorStr ) ) ) ) + HadError ) ) + +(defun UpdateNetlistGetCellViewTripplesToAddAndEditFromCompareResults ( CompareResults ) + (let ( + ( Result nil ) ) + ( foreach + CellCompareResult + CompareResults + (let ( + ( LibName ( car ( cadr CellCompareResult ) ) ) + ( CellName ( cadr ( cadr CellCompareResult ) ) ) + ( ViewCheckResults ( caddr CellCompareResult ) ) ) + ( foreach + ViewCheckResult + ViewCheckResults + (let ( + ( ViewName ( car ViewCheckResult ) ) + ( ViewCompareResult ( cadr ViewCheckResult ) ) ) + (when ViewCompareResult + ( setq Result ( cons ( list LibName CellName ViewName ) Result ) ) ) ) ) ) ) + Result ) ) + + + +(defun UpdateNetlistMakeWriteableCellViewTableFromCompareResults ( CompareResult + NetlistViewName ) + (let ( + ( Result ( makeTable "cellViewTable" nil ) ) + ( ErrorStr nil ) + ( ListOfLibCellViewTripplesToCreate nil ) + ( ListOfLibCellViewTripplesToEdit nil ) ) + ( foreach + CellCompareResult + CompareResults + (let ( + ( LibName ( car ( cadr CellCompareResult ) ) ) + ( CellName ( cadr ( cadr CellCompareResult ) ) ) + ( ViewCheckResults ( caddr CellCompareResult ) ) ) + ( foreach + ViewCheckResult + ViewCheckResults + (let ( + ( ViewName ( car ViewCheckResult ) ) + ( ViewCompareResult ( cadr ViewCheckResult ) ) ) + (when ViewCompareResult + (let ( + ( CellViewDDObj ( ddGetObj LibName CellName ViewName ) ) ) + (if CellViewDDObj + ( setq + ListOfLibCellViewTripplesToEdit + ( tconc + ListOfLibCellViewTripplesToEdit + ( list LibName CellName ViewName ) ) ) + ( setq + ListOfLibCellViewTripplesToCreate + ( tconc + ListOfLibCellViewTripplesToCreate + ( list LibName CellName ViewName ) ) ) ) ) ) ) ) ) ) + ( foreach + LibCellViewTripple + ( car ListOfLibCellViewTripplesToCreate ) + (let () + ( printf + "Creating %L %L\n" + ( cadr LibCellViewTripple ) + ( caddr LibCellViewTripple ) ) + (let ( + ( CellView ( dbOpenCellViewByType + ( car LibCellViewTripple ) + ( cadr LibCellViewTripple ) + ( caddr LibCellViewTripple ) + (if ( and + NetlistViewName + ( equal + ( caddr LibCellViewTripple ) + NetlistViewName ) ) + "schematic" + "maskLayout" ) + "w" ) ) ) + (when CellView + ( setarray Result LibCellViewTripple CellView ) ) ) ) ) + ( foreach + LibCellViewTripple + ( car ListOfLibCellViewTripplesToEdit ) + (let ( + ( LibName ( car LibCellViewTripple ) ) + ( CellName ( cadr LibCellViewTripple ) ) + ( ViewName ( caddr LibCellViewTripple ) ) ) + (let ( + ( CellViewDDObj ( ddGetObj LibName CellName ViewName ) ) ) + (when ( and + CellViewDDObj + ( getq CellViewDDObj files ) + ( forall + FileDDObj + ( getq CellViewDDObj files ) + ( ddIsObjWritable FileDDObj ) ) ) + ( printf "Opening %L %L %L for append.\n" LibName CellName ViewName ) + (let ( + ( CellView ( dbOpenCellViewByType + LibName + CellName + ViewName + (if ( and NetlistViewName ( equal ViewName NetlistViewName ) ) + "schematic" + "maskLayout" ) + "a" ) ) ) + ( setarray Result LibCellViewTripple CellView ) ) ) ) ) ) + (if ErrorStr + ErrorStr + Result ) ) ) + +(defun UpdateNetlistUpdateCellsFromSkillNetlistsToFileUsingPDKInfo ( LibCellPairList + NetlistViewName + LayoutViewName + FloorplanViewName + SkillNetlistDir + DirectivesSkillDir + AutopinsSkillDir + DefaultDensityFactor + BoundaryScalingFactor + FileName + LockBound + SuppressPins + ForcePins + UseLayoutHeight + LockLayoutView ) + + + + (let ( + ( FilteredLibCellPairList + ( setof + LibCellPair + LibCellPairList + ( not + ( or + ( equal ( car LibCellPair ) StackLibraryName ) + ( equal ( car LibCellPair ) GateLibraryName ) ) ) ) ) ) + (let ( + ( DirectivesTable + ( CellInfoGetTableForCellName + ( cadr ( car FilteredLibCellPairList ) ) + DirectivesSkillDir ) ) ) + (let ( + ( BoundaryPosition + (CellInfoLookupWithDefault + DirectivesTable "boundary_position" BoundaryPosition)) + ( BoundaryWidthIncrement + (CellInfoLookupWithDefault + DirectivesTable "boundary_width_increment" BoundaryWidthIncrement)) + ( BoundaryWidthWarningCutOff + (CellInfoLookupWithDefault + DirectivesTable "boundary_width_warning_cutoff" BoundaryWidthWarningCutOff)) + ( BoundarySmallCellWarningCutOff + (CellInfoLookupWithDefault + DirectivesTable "boundary_small_cell_warning_cutoff" BoundarySmallCellWarningCutOff)) + ) + + (let ( + ( InstanceTransformFunctionTable ( UpdateNetlistGetFunctionTableForDefaultInstanceTransformFunctions + NetlistViewName + LayoutViewName + FloorplanViewName ) ) + ( HeightWidthFunctionTable ( UpdateNetlistGetFunctionTableForDefaultWidthAndHeightAndPositionFunctions + NetlistViewName + LayoutViewName + FloorplanViewName + BoundaryLPP + UserUnitsPerMeter + BoundaryWidthIncrement + BoundaryWidthWarningCutOff + DefaultDensityFactor + BoundaryScalingFactor + BoundarySmallCellWarningCutOff + UseLayoutHeight + BoundaryPosition ) ) + ( NetlistTransformationFunctionTable ( UpdateNetlistGetFunctionTableForNetlistTransformationFunctions + NetlistViewName + LayoutViewName + FloorplanViewName + DirectivesSkillDir ) ) ) + (let ( + ( OutputPort ( outfile FileName "a" ) ) + ( CompareResults ( UpdateNetlistCompareCellsToSkillNetlists + FilteredLibCellPairList + ( cons + ( list ".*" ".+\\.wires\\..+" ) + ( cons + ( list + ( sprintf nil "^%s$" GateLibraryName ) + ".*" ) + ( cons + ( list + ( sprintf nil "^%s$" StackLibraryName ) + ".*" ) + ( cons + ( list TechLibName ".*" ) + ( cons + ( list "^$" "" ) + TransistorLibCellPairs + ) ) ) ) ) + TransistorLibCellPairs + ( setof + ViewName + ( list + FloorplanViewName + NetlistViewName + LayoutViewName ) + ViewName ) + ( setof + ViewName + ( list + FloorplanViewName + NetlistViewName + (unless LockLayoutView + LayoutViewName ) ) + ViewName ) + ( list LayoutViewName ) + NetlistViewName + SkillNetlistDir + DirectivesSkillDir + AutopinsSkillDir + BoundaryLPP + UserUnitsPerMeter + DirectiveUnitsPerMeter + ( UpdateNetlistGetDefaultGetInstanceTransformFunc ) + ( list InstanceTransformFunctionTable ) + ( UpdateNetlistGetDefaultGetCellHeightFunc ) + ( list HeightWidthFunctionTable ) + ( UpdateNetlistGetDefaultGetCellWidthFunc ) + ( list HeightWidthFunctionTable ) + ( UpdateNetlistGetDefaultGetCellPositionFunc ) + ( list HeightWidthFunctionTable ) + ( UpdateNetlistGetDefaultNetlistTransformationFunc ) + ( list NetlistTransformationFunctionTable ) + LockBound + SuppressPins + ForcePins ) ) ) + ( UpdateNetlistAppendCompareResultsToPort + CompareResults + OutputPort ) + (unless ( UpdateNetlistGetErrorsFromCompareResults CompareResults ) + (let ( + ( CellViewTable ( UpdateNetlistMakeWriteableCellViewTableFromCompareResults + CompareResults + NetlistViewName ) ) ) + (if ( tablep CellViewTable ) + ( UpdateNetlistUpdateCellsFromCompareResultsToPort + CompareResults + CellViewTable + BoundaryLPP + UserUnitsPerMeter + OutputPort ) + ( fprintf OutputPort "Error: %s\n" CellViewTable ) ) ) ) + ( close OutputPort ) ) ) ) + nil ) ) ) + + +(defun UpdateNetlistGenFromSource ( TargetCellView + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + ConnectivityInstanceTripples + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams + ConnectivityTerminalNames + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams + ConnectivityNetNames + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams + ConnectivityGetLayerWireSpacingFunc + ConnectivityGetLayerWireSpacingFuncParams + ConnectivityGetLayerWireWidthFunc + ConnectivityGetLayerWireWidthFuncParams + ConnectivityGetGlobalWireSpacingFunc + ConnectivityGetGlobalWireSpacingFuncParams + ConnectivityGetGlobalWireWidthFunc + ConnectivityGetGlobalWireWidthFuncParams + BoundaryLPP + UserUnitsPerMeter + @key + ( Verbose t ) ) + + (let ( + ( Ret nil ) + ( InstanceNames + ( ListApplyFuncToListAndAccumulateResults + ( car + ( NameFilterInstanceTripples + ConnectivityInstanceTripples + LibCellExpressionPairsToIgnore ) ) + (lambda + ( InstanceTripple ) + ( car InstanceTripple ) ) + nil ) ) + ( InstanceMap ( NameMakeEmptyInstanceMap ) ) + ( Instances (when TargetCellView + ( UpdateNetlistFilterInstances + TargetCellView + LibCellExpressionPairsToIgnore ) ) ) ) + ( NamePopulateInstanceMapWithInstances + InstanceMap + Instances + FoldableLibCellExpressionPairs ) + (let ( + ( CompareResult ( UpdateNetlistCompareCellView + TargetCellView + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + InstanceMap + Instances + ConnectivityInstanceExistsFunc + ConnectivityInstanceExistsFuncParams + ConnectivityGetInstanceMasterLibNameFunc + ConnectivityGetInstanceMasterLibNameFuncParams + ConnectivityGetInstanceMasterCellNameFunc + ConnectivityGetInstanceMasterCellNameFuncParams + InstanceNames + ConnectivityGetInstanceParameterPairsFunc + ConnectivityGetInstanceParameterPairsFuncParams + ConnectivityGetInstanceTransformFunc + ConnectivityGetInstanceTransformFuncParams + ConnectivityInstanceHasConnectionFunc + ConnectivityInstanceHasConnectionFuncParams + ConnectivityGetInstanceConnectionsFunc + ConnectivityGetInstanceConnectionsFuncParams + ConnectivityTerminalExistsFunc + ConnectivityTerminalExistsFuncParams + ConnectivityTerminalNames + ConnectivityNetExistsFunc + ConnectivityNetExistsFuncParams + ConnectivityNetNames + ConnectivityGetNetWireSpacingFunc + ConnectivityGetNetWireSpacingFuncParams + ConnectivityGetNetWireWidthFunc + ConnectivityGetNetWireWidthFuncParams + ConnectivityGetLayerWireSpacingFunc + ConnectivityGetLayerWireSpacingFuncParams + ConnectivityGetLayerWireWidthFunc + ConnectivityGetLayerWireWidthFuncParams + ConnectivityGetGlobalWireSpacingFunc + ConnectivityGetGlobalWireSpacingFuncParams + ConnectivityGetGlobalWireWidthFunc + ConnectivityGetGlobalWireWidthFuncParams + (lambda + ( LibName CellName ViewName HeightOfExistingBoundaryInMeters BlaBlabl ) + nil ) + nil + (lambda + ( LibName + CellName + ViewName + CellHeightInMeters ) + nil ) + nil + (lambda + () + nil ) + nil + (lambda + ( x y) + nil ) + nil + BoundaryLPP + UserUnitsPerMeter + nil + nil + nil ) ) ) + (when CompareResult + (when Verbose + ( UpdateNetlistPrintDifferences + CompareResult + poport ) ) + ( setq + Ret + ( UpdateNetlistUpdateCellViewWithCompareResult + TargetCellView + CompareResult + InstanceMap + BoundaryLPP + UserUnitsPerMeter ) ) + (when Ret ( printf "Error: %L\n" Ret ) ) + ) + Ret ) ) ) + +(defun UpdateNetlistGenFromSkillNetlist ( TargetCellView + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + BoundaryLPP + WidthEstimationFunc + WidthEstimationFuncParams + SkillNetlistDir + SkillDirectivesDir + UserUnitsPerMeter + DirectiveUnitsPerMeter + ) + NetlistTable = NetlistTableGetSkillNetlistTableForCellName( TargetCellView~>cellName SkillNetlistDir ) + if( tablep( NetlistTable ) then + DirectivesTable= CellInfoGetTableForCellName( TargetCellView~>cellName SkillDirectivesDir ) + if( tablep( DirectivesTable ) then + TransformedNetlistTable=InlineConnectionsHierTransformTable( + NetlistTable + UpdateNetlistGetDefaultShouldInLineConnectionsFunc( ) + list( DirectivesTable SkillDirectivesDir ) + SkillNetlistDir ) + TransformedNetlistsTablesTable=makeTable( "tableOfNetlistTables" nil ) + TransformedNetlistsTablesTable[TargetCellView~>viewName]=TransformedNetlistTable + InstancesTable=NetListTable["i"] + NetsTable=NetListTable["n"] + StatisticsTable=NetlistTable["s"] + UpdateNetlistGenFromSource( + TargetCellView + LibCellExpressionPairsToIgnore + FoldableLibCellExpressionPairs + ( UpdateNetlistGetSkillNetlistInstanceExistsFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceMasterLibNameFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceMasterCellNameFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + ( NetlistTableGetInstanceTripples TransformedNetlistTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceParameterPairsFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + (lambda ( InstanceName ) nil ) + nil + ( UpdateNetlistGetSkillNetlistInstanceHasConnectionFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistGetInstanceConnectionsFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + ( UpdateNetlistGetSkillNetlistTerminalExistsFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + ( NetlistTableGetTerminalNames TransformedNetlistTable ) + ( UpdateNetlistGetSkillNetlistNetExistsFunc ) + ( list ( getq TargetCellView viewName ) TransformedNetlistsTablesTable ) + ( NetlistTableGetNetNames TransformedNetlistTable ) + ( UpdateNetListGetSkillGetNetlistNetWireSpacingFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistNetWireWidthFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistLayerWireSpacingFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistLayerWireWidthFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistGlobalWireSpacingFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + ( UpdateNetListGetSkillGetNetlistGlobalWireWidthFunc ) + ( list DirectivesTable DirectiveUnitsPerMeter ) + BoundaryLPP + UserUnitsPerMeter ) + + else DirectivesTable ) + else NetlistTable ) +) + + +(defun UpdateNetlistGenFromSkillNetlistUsingPDKInfo ( TargetCellView + SkillNetlistDir + SkillDirectivesDir + @key + ( LibCellsToIgnore nil ) + ) + ( UpdateNetlistGenFromSkillNetlist + TargetCellView + ( append + LibCellsToIgnore + ( append + WiringCellLibCellPairRegExs + TechLibExceptTransistorsLibCellPairRegExs + ) ) + FoldableCellLibCellPairRegExs + BoundaryLPP + (lambda + ( LibName + CellName + ViewName + TotalTransistorGateAreaInMetersSquared + TotalTransistorGateLengthInMeters + CellHeightInMeters + DirectivesTable ) + nil ) + nil + SkillNetlistDir + SkillDirectivesDir + UserUnitsPerMeter + DirectiveUnitsPerMeter ) ) + +(defun UpdateNetlistEasyGen ( CellName + ViewName + SkillNetlistDir + SkillDirectivesDir ) + + (let ( + ( LibCellPair ( NameParseCellName CellName ) ) ) + (let ( + ( CellView + ( dbOpenCellViewByType + ( car LibCellPair ) + ( cadr LibCellPair ) + ViewName + "maskLayout" + "w" ) ) ) + ( UpdateNetlistGenFromSkillNetlistUsingPDKInfo + CellView + SkillNetlistDir + SkillDirectivesDir ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/.menu new file mode 100755 index 0000000000..fcc6e16a39 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/.menu @@ -0,0 +1 @@ +( list "Floorplan" "UIFloorplan" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ArrayCells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ArrayCells.il new file mode 100644 index 0000000000..ef0201c7ae --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ArrayCells.il @@ -0,0 +1,58 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "7.Array Cells" "UIArrayCells" ) +( UICreateMenuItemCallBack + `UIArrayCellsCB + (lambda () + let(() + hiDisplayForm( UIArrayCells_Form ) + ) + ) +) + +( UICreateAction + 'UIArrayCellsFormCB + (lambda () + let( (CellView matrix) + + matrix=UIArrayCells_Form->UIArrayCells_Matrix->value + ArrayCells(evalstring( sprintf(nil "list( %s )" matrix)) + ?WildCardString UIArrayCells_Form->UIArrayCells_WildCardString->value + ?Inline UIArrayCells_Form->UIArrayCells_Inline->value + ) + ) + ) +) + +( UICreateComponent + "UIArrayCells_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIArrayCells_Matrix + ?prompt "Matrix" + ?defValue "0:2*11.52" ) + ( hiCreateStringField + ?name `UIArrayCells_WildCardString + ?prompt "WildCardString" + ?defValue "" ) + ( hiCreateBooleanButton + ?name `UIArrayCells_Inline + ?buttonText "Inline" + ?defValue t ) + ) + ( hiCreateAppForm + ?name `UIArrayCells_Form + ?formTitle "Array Cells" + ?fields Fields + ?callback "( UIArrayCellsFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FLOverlap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FLOverlap.il new file mode 100644 index 0000000000..cf430717a5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FLOverlap.il @@ -0,0 +1,13 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "8.FL_Overlap" "UIFLOverlap" ) +( UICreateMenuItemCallBack + `UIFLOverlapCB + (lambda () + FL_Overlap() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanAllSubcells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanAllSubcells.il new file mode 100644 index 0000000000..c452065ce6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanAllSubcells.il @@ -0,0 +1,216 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "6.Init Floorplan All Subcells" "UIFloorplanAllSubcells" ) + + +defun( flCompareCellNameSubType ( cellName1 cellName2 ) + prog((cellRootName1 cellRootName2 subType1 subType2) + rexCompile(".[0-9]*$") + cellRootName1=rexReplace( cellName1 "" 0) + cellRootName2=rexReplace( cellName2 "" 0) + if( strcmp( cellRootName1 cellRootName2 )!=0 then + return( strcmp( cellRootName1 cellRootName2 )) + ) + rexCompile(sprintf(nil "^%s." cellRootName1)) + subType1=rexReplace( cellName1 "" 0 ) + subType2=rexReplace( cellName2 "" 0 ) + return( cond( + (evalstring(subType1)>evalstring(subType2) 1) + (evalstring(subType1)cellName + if( member( cellName1 processedCellList ) || CellView~>instances==nil then + return(t) + else + processedCellList=cons( cellName1 processedCellList ) + ) + + ; find the lowest sybtype number. + libName=car( NameParseCellName( cellName1 ) ) + cellNameList=ddGetObj(libName)~>cells~>name + rexCompile(".[0-9]*$") + cellRootName=rexReplace( cellName1 "" 0) + cellNameList=rexMatchList( sprintf(nil "^%s.[0-9]*$" cellRootName ) cellNameList ) + cellNameList=setof( cellName2 cellNameList flCompareCellNameSubType( cellName2 sprintf( nil "%s.%s" cellRootName SubType ))>=0 && flCompareCellNameSubType( cellName2 sprintf( nil "%s.%s" cellRootName SubTypeEnd ))<0 && strcmp(cellName1 cellName2)!=0) + cellNameList=sort( cellNameList nil) + + cellView2=nil + while( cellNameList && cellView2==nil + cellName2=car(cellNameList) + cellView2=nrOpenCellViewReadable( libName cellName2 viewName ) + cellNameList=cdr(cellNameList) + ) + + if( cellView2 then + printf("Running FloorplanTemplating: %s(%s) %s \n" CellView~>libName CellView~>cellName CellView~>viewName ) + flFloorplanTemplating( CellView + cellName2 + ?srcLibName libName + ?srcViewName viewName + ?SnapXGrid SnapXGrid + ?Recursive t + ?DeletePins t + ?SkipCellList SkipCellList + ?ResolveOverlap ResolveOverlap + ) + else + uniqueInstList=nil + foreach( inst CellView~>instances + if( !member( inst~>cellName uniqueInstList~>cellName ) && inst~>libName !="gate" && inst~>libName !="stack" && inst~>libName != TechLibName then + uniqueInstList=cons( inst uniqueInstList) + ) + ) + foreach( inst uniqueInstList + subcellView=nrOpenCellViewWritable( inst~>libName inst~>cellName inst~>viewName ) + if(subcellView then + flFloorplanSubcells( subcellView + ?SubType SubType + ?SnapXGrid SnapXGrid + ?viewName viewName + ?ResolveOverlap ResolveOverlap + ?SkipCellList SkipCellList + ) + else + printf("Error: cell view %s(%s) %s not writable.\n" inst~>cellName inst~>libName inst~>viewName ) + ) + ) + printf("Running InitFloorplan: %s(%s) %s \n" CellView~>libName CellView~>cellName CellView~>viewName ) + flInitFloorplan( CellView~>libName CellView~>cellName CellView~>viewName + ?Verbose UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_Verbose->value + ?RegenerateFromCast UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_RegenerateFromCast->value + ?SnapXGrid SnapXGrid + ?ScriptFileName UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_ScriptFileName->value + ?MaxHeapSize nrGetMaxHeapSize( ) + ) + return(t) + ) + ) +) + + +( UICreateMenuItemCallBack + `UIFloorplanAllSubcellsCB + (lambda () + let(() + UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_AutoSaveFileName->value=sprintf( nil "%s.autosave" UIGetCellView()~>cellName) + hiDisplayForm( UIFloorplanAllSubcells_Form ) + ) + ) +) + +( UICreateAction + 'UIFloorplanAllSubcellsFormCB + (lambda () + let( (CellView processedCellList) + + CellView= UIGetCellView() + processedCellList=nil + SkipCellList=nil + if( UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_SkipCellFileName->value!="" then + p=infile(UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_SkipCellFileName->value) + if( p then + while( fscanf( p "%s" s) SkipCellList=cons( s SkipCellList )) + else + SkipCellList=nil + ) + SkipCellList=nil + ) + + if( UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_AutoSave->value then + flSaveCoordinates( CellView + UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_AutoSaveFileName->value + ?SkipCellList SkipCellList + ?BlockLayer list("LOGO" "drawing") + ) + ) + flFloorplanSubcells( CellView + ?SubType UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_SubTypeStart->value + ?SubTypeEnd UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_SubTypeEnd->value + ?viewName UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_ViewName->value + ?SnapXGrid UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_SnapXGrid->value + ?ResolveOverlap UIFloorplanAllSubcells_Form->UIFloorplanAllSubcells_ResolveOverlap->value + ?SkipCellList SkipCellList + ) + ) + ) +) + +( UICreateComponent + "UIFloorplanAllSubcells_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateBooleanButton + ?name `UIFloorplanAllSubcells_RegenerateFromCast + ?buttonText "Regenerate From Cast" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIFloorplanAllSubcells_Verbose + ?buttonText "Verbose" + ?defValue nil ) + ( hiCreateStringField + ?name `UIFloorplanAllSubcells_SubTypeStart + ?prompt "Template From Subtype" + ?defValue "1000" ) + ( hiCreateStringField + ?name `UIFloorplanAllSubcells_SubTypeEnd + ?prompt "Template To Subtype" + ?defValue "9999" ) + ( hiCreateStringField + ?name `UIFloorplanAllSubcells_ViewName + ?prompt "Template From ViewName" + ?defValue "floorplan" ) + ( hiCreateBooleanButton + ?name `UIFloorplanAllSubcells_ResolveOverlap + ?buttonText "Resolve Overlap" + ?defValue t ) + ( hiCreateStringField + ?name `UIFloorplanAllSubcells_ScriptFileName + ?prompt "Filter Script" + ?defValue "" ) + ( hiCreateStringField + ?name `UIFloorplanAllSubcells_SkipCellFileName + ?prompt "Skip Cell File Name" + ?defValue "" ) + ( hiCreateBooleanButton + ?name `UIFloorplanAllSubcells_AutoSave + ?buttonText "AutoSave" + ?defValue nil ) + ( hiCreateStringField + ?name `UIFloorplanAllSubcells_AutoSaveFileName + ?prompt "AutoSaveFileName" + ?defValue "autosave.sav" ) + ( hiCreateFloatField + ?name `UIFloorplanAllSubcells_SnapXGrid + ?prompt "Snap X to Grid" + ?defValue 0.01 )) + ( hiCreateAppForm + ?name `UIFloorplanAllSubcells_Form + ?formTitle "Init Floorplan All Subcells" + ?fields Fields + ?callback "( UIFloorplanAllSubcellsFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanTemplate.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanTemplate.il new file mode 100644 index 0000000000..29126acdb0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/FloorplanTemplate.il @@ -0,0 +1,101 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "5.Template Floorplan" "UITemplateFloorplan" ) +( UICreateMenuItemCallBack + `UITemplateFloorplanCB + (lambda () + let((cellName) + cellName=UIGetCellView()~>cellName + UITemplateFloorplan_Form->UITemplateFloorplan_TemplateCellName->value=cellName + UITemplateFloorplan_Form->UITemplateFloorplan_TemplateLibName->value=car( NameParseCellName( cellName )) + UITemplateFloorplan_Form->UITemplateFloorplan_AutoSaveFileName->value=sprintf( nil "%s.autosave" UIGetCellView()~>cellName) + hiDisplayForm( UITemplateFloorplan_Form ) + ) + ) +) + +( UICreateAction + 'UITemplateFloorplanFormCB + (lambda () + let( () + if( UITemplateFloorplan_Form->UITemplateFloorplan_AutoSave->value + flSaveCoordinates( UIGetCellView() + UITemplateFloorplan_Form->UITemplateFloorplan_AutoSaveFileName->value + ?SkipCellList nil + ?BlockLayer list("LOGO" "drawing") + ) + ) + flFloorplanTemplating( UIGetCellView() + UITemplateFloorplan_Form->UITemplateFloorplan_TemplateCellName->value + ?srcLibName UITemplateFloorplan_Form->UITemplateFloorplan_TemplateLibName->value + ?srcViewName UITemplateFloorplan_Form->UITemplateFloorplan_TemplateViewName->value + ?ResolveOverlap UITemplateFloorplan_Form->UITemplateFloorplan_ResolveOverlap->value + ?SnapXGrid UITemplateFloorplan_Form->UITemplateFloorplan_SnapXGrid->value + ?SnapXInst UITemplateFloorplan_Form->UITemplateFloorplan_SnapXInst->value + ?Recursive UITemplateFloorplan_Form->UITemplateFloorplan_Recursive->value + ?DeletePins UITemplateFloorplan_Form->UITemplateFloorplan_DeletePins->value + ) + ) + ) +) + +( UICreateComponent + "UITemplateFloorplan_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UITemplateFloorplan_TemplateLibName + ?prompt "Template LibName" + ?defValue "" ) + ( hiCreateStringField + ?name `UITemplateFloorplan_TemplateCellName + ?prompt "Template CellName" + ?defValue "" ) + ( hiCreateStringField + ?name `UITemplateFloorplan_TemplateViewName + ?prompt "Template ViewName" + ?defValue "floorplan" ) + ( hiCreateStringField + ?name `UITemplateFloorplan_AutoSaveFileName + ?prompt "AutoSave FileName" + ?defValue "" ) + ( hiCreateBooleanButton + ?name `UITemplateFloorplan_AutoSave + ?buttonText "AutoSave" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UITemplateFloorplan_Recursive + ?buttonText "Recursive" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UITemplateFloorplan_ResolveOverlap + ?buttonText "Resolve Overlaps" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UITemplateFloorplan_DeletePins + ?buttonText "Delete Pins and Wires" + ?defValue t ) + ( hiCreateFloatField + ?name `UITemplateFloorplan_SnapXGrid + ?prompt "Snap X to Grid" + ?defValue 0.01 ) + ( hiCreateBooleanButton + ?name `UITemplateFloorplan_SnapXInst + ?buttonText "Snap X to Instance Alignment Property" + ?defValue nil ) + ) + ( hiCreateAppForm + ?name `UITemplateFloorplan_Form + ?formTitle "Template Floorplan" + ?fields Fields + ?callback "( UITemplateFloorplanFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/InitFloorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/InitFloorplan.il new file mode 100755 index 0000000000..0b0e69a07e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/InitFloorplan.il @@ -0,0 +1,76 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "4.Init Floorplan" "UIInitFloorplan" ) +( UICreateMenuItemCallBack + `UIInitFloorplanCB + (lambda () + let(() + if( !geGetSelectedSet() then UIInitFloorplan_Form->UIInitFloorplan_DoNotMoveExistingInstances->value=nil ) + hiDisplayForm( UIInitFloorplan_Form ) + ) + ) +) + +( UICreateAction + 'UIInitFloorplanFormCB + (lambda () + let( (CellView) + + TEMP=ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + CellView= UIGetCellView() + flInitFloorplan( CellView~>libName CellView~>cellName CellView~>viewName + ?Verbose UIInitFloorplan_Form->UIInitFloorplan_Verbose->value + ?RegenerateFromCast UIInitFloorplan_Form->UIInitFloorplan_RegenerateFromCast->value + ?SnapXGrid UIInitFloorplan_Form->UIInitFloorplan_SnapXGrid->value + ?ScriptFileName UIInitFloorplan_Form->UIInitFloorplan_ScriptFileName->value + ?MaxHeapSize nrGetMaxHeapSize( ) + ?DoNotMoveExistingInstances UIInitFloorplan_Form->UIInitFloorplan_DoNotMoveExistingInstances->value + ) + ) + ) +) + +( UICreateComponent + "UIInitFloorplan_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateBooleanButton + ?name `UIInitFloorplan_DoNotMoveExistingInstances + ?buttonText "Do Not Move Existing Instances" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIInitFloorplan_RegenerateFromCast + ?buttonText "Regenerate From Cast" + ?defValue nil ) + ( hiCreateFloatField + ?name `UIInitFloorplan_SnapXGrid + ?prompt "Snap X to Grid" + ?defValue 0.01 ) + ( hiCreateBooleanButton + ?name `UIInitFloorplan_Verbose + ?buttonText "Verbose" + ?defValue nil ) + ( hiCreateStringField + ?name `UIInitFloorplan_ScriptFileName + ?prompt "Filter Script" + ?defValue "" ) + ( hiCreateFormButton + ?name `UIInitFloorplan_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Resolve_Overlaps_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIInitFloorplan_Form + ?formTitle "Init Floorplan" + ?fields Fields + ?callback "( UIInitFloorplanFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/LoadFloorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/LoadFloorplan.il new file mode 100644 index 0000000000..86eebb347b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/LoadFloorplan.il @@ -0,0 +1,69 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "3.Load Floorplan" "UILoadFloorplan" ) +( UICreateMenuItemCallBack + `UILoadFloorplanCB + (lambda () + let(() + UILoadFloorplan_Form->UILoadFloorplan_FileName->value=sprintf( nil "%s.autosave" UIGetCellView()~>cellName) + hiDisplayForm( UILoadFloorplan_Form ) + ) + ) +) + +( UICreateAction + 'UILoadFloorplanFormCB + (lambda () + let( (CellView p s SkipCellList) + SkipCellList=nil + if( UILoadFloorplan_Form->UILoadFloorplan_SkipCellFileName->value!="" then + p=infile(UILoadFloorplan_Form->UILoadFloorplan_SkipCellFileName->value) + if( p then + while( fscanf( p "%s" s) SkipCellList=cons( s SkipCellList )) + else + SkipCellList=nil + ) + SkipCellList=nil + ) + CellView= UIGetCellView() + flLoadCoordinates( CellView + UILoadFloorplan_Form->UILoadFloorplan_FileName->value + ?SkipCellList SkipCellList + ?BlockLayer list("LOGO" "drawing") + ?SaveCellView UILoadFloorplan_Form->UILoadFloorplan_SaveCellView->value ) + ) + ) +) + +( UICreateComponent + "UILoadFloorplan_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UILoadFloorplan_SkipCellFileName + ?prompt "SkipCellFileName" + ?defValue "skipCell.list" ) + ( hiCreateStringField + ?name `UILoadFloorplan_FileName + ?prompt "FileName" + ?defValue "autosave.sav" ) + ( hiCreateBooleanButton + ?name `UILoadFloorplan_SaveCellView + ?buttonText "Save All CellViews" + ?defValue t ) + ) + ( hiCreateAppForm + ?name `UILoadFloorplan_Form + ?formTitle "Load Floorplan" + ?fields Fields + ?callback "( UILoadFloorplanFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/PromoteInplacePins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/PromoteInplacePins.il new file mode 100644 index 0000000000..71117aa509 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/PromoteInplacePins.il @@ -0,0 +1,89 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "9.Promote Inplace Pins" "UIPromoteInplacePins" ) + +(defun PromoteInplacePins ( view M2To M3To M4To) + (let (obj child) + (foreach obj view->shapes + (when ( obj->pin ) + (when ( dbGetPropByName obj "PinType" )->value == "InPlace" + case( obj~>layerName + ("M2" ToLayerName=M2To ) + ("M3" ToLayerName=M3To ) + ("M4" ToLayerName=M4To ) + ( t ToLayerName="No Promote" ) + ) + if( ToLayerName!="No Promote" then + obj~>layerName=ToLayerName + foreach( child obj~>children + if( child~>objType=="label" then + child~>layerName=ToLayerName + ) + ) + ) + ) + ) + ) + ) + t +) + + + +( UICreateMenuItemCallBack + `UIPromoteInplacePinsCB + (lambda () + let(() + hiDisplayForm( UIPromoteInplacePins_Form ) + ) + ) +) + +( UICreateAction + 'UIPromoteInplacePinsFormCB + (lambda () + let( ( ) + PromoteInplacePins( UIGetCellView() + UIPromoteInplacePins_Form->UIPromoteInplacePins_M2->value + UIPromoteInplacePins_Form->UIPromoteInplacePins_M3->value + UIPromoteInplacePins_Form->UIPromoteInplacePins_M4->value + ) + ) + ) +) + +( UICreateComponent + "UIPromoteInplacePins_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateRadioField + ?name `UIPromoteInplacePins_M2 + ?prompt "Promote M2 Inplace Pins to:" + ?choices list( "No Promote" "M4" "M6") + ?defValue "M6" ) + ( hiCreateRadioField + ?name `UIPromoteInplacePins_M3 + ?prompt "Promote M3 Inplace Pins to:" + ?choices list( "No Promote" "M5" "M7") + ?defValue "M5" ) + ( hiCreateRadioField + ?name `UIPromoteInplacePins_M4 + ?prompt "Promote M4 Inplace Pins to:" + ?choices list( "No Promote" "M6") + ?defValue "M6" ) + ) + ( hiCreateAppForm + ?name `UIPromoteInplacePins_Form + ?formTitle "Array Cells" + ?fields Fields + ?callback "( UIPromoteInplacePinsFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ReplaceSubcells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ReplaceSubcells.il new file mode 100644 index 0000000000..ead5b418c0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ReplaceSubcells.il @@ -0,0 +1,8 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ReplaceSubcells.il#1 $ +; $DateTime: 2005/11/07 15:21:21 $ +; $Author: aubrey $ + + +( list "Recursively Replace Subcell Views" "UIReplaceSubcells" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ResolveOverlap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ResolveOverlap.il new file mode 100644 index 0000000000..1fa5dc5152 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/ResolveOverlap.il @@ -0,0 +1,181 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "1.Resolve Overlap" "UIResolveOverlap" ) +( UICreateMenuItemCallBack + `UIResolveOverlapCB + (lambda () + let(() + if(UIResolveOverlap_Form->UIResolveOverlap_ProjectName->value== "default" then + UIResolveOverlap_Form->UIResolveOverlap_ProjectName->value=UIGetCellView()~>cellName) + UIResolveOverlap_Form->UIResolveOverlap_AutoSaveFileName->value=sprintf( nil "%s.autosave" UIGetCellView()~>cellName) + hiDisplayForm( UIResolveOverlap_Form ) + ) + ) +) + +defun( addInstToList (instance) + let((vName instcv inst) + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + vName=sprintf( nil "%s|%s" instance~>cellView~>cellName instance~>name ) + if( !member( vName FreezeCellList ) then + FreezeCellList=cons( vName FreezeCellList ) + instcv=nrOpenCellViewReadable( instance~>libName instance~>cellName instance~>viewName) + foreach( inst car( NameFilterInstances( instcv~>instances LibCellsToIgnore )) + addInstToList( inst ) + ) + ) + ) +) + +( UICreateAction + 'UIResolveOverlapFormCB + (lambda () + let( (CellView projectName xtotal) + + TEMP=ConfigFileGetValue( TheCDSConfigTable "TEMP" ) + CellView= UIGetCellView() + projectName=UIResolveOverlap_Form->UIResolveOverlap_ProjectName->value + SkipCellList=nil + if( UIResolveOverlap_Form->UIResolveOverlap_SkipCellFileName->value!="" then + p=infile(UIResolveOverlap_Form->UIResolveOverlap_SkipCellFileName->value) + if( p then + while( fscanf( p "%s" s) SkipCellList=cons( s SkipCellList )) + else + printf("Skip Cell File %s does not exist.\n" UIResolveOverlap_Form->UIResolveOverlap_SkipCellFileName->value!="") + SkipCellList=nil + ) + else + SkipCellList=nil + ) + FreezeCellList=nil + if( UIResolveOverlap_Form->UIResolveOverlap_Scope->value=="Selected" then + if( geGetSelectedSet() then + foreach( inst setof( inst CellView~>instances !member(inst geGetSelectedSet())) + addInstToList( inst ) + ) + else + printf("No instance is selected. Run resolve overlap on whole cellview.\n") + ) + ) + createDir( sprintf( nil "%s/glpsol/" TEMP)) + xtotal=flResolveOverlap( CellView + ?SkipCellList SkipCellList + ?LPMacroFileName sprintf( nil "%s/glpsol/%s.lpt" TEMP projectName) + ?LPOutputFileName sprintf( nil "%s/glpsol/%s.out" TEMP projectName) + ?LPLogFileName sprintf( nil "%s/glpsol/%s.log" TEMP projectName) + ?LPmemoFileName sprintf( nil "%s/glpsol/%s.memo" TEMP projectName) + ?SaveFileName UIResolveOverlap_Form->UIResolveOverlap_AutoSaveFileName->value + ?BlockLayer list("LOGO" "drawing") + ?SaveCellView UIResolveOverlap_Form->UIResolveOverlap_SaveCellView->value + ?AbutCellKeepOrder UIResolveOverlap_Form->UIResolveOverlap_AbutCellKeepOrder->value + ?SingleHierarchy UIResolveOverlap_Form->UIResolveOverlap_SingleHierarchy->value + ?SnapXGrid UIResolveOverlap_Form->UIResolveOverlap_SnapXGrid->value + ?FreezeCellList FreezeCellList + ) + printf("Total Width: %f\n" xtotal) + if( xtotal!=0 && (UIResolveOverlap_Form->UIResolveOverlap_Mode->value!="No" ) then + if( UIResolveOverlap_Form->UIResolveOverlap_Mode->value=="Least Move" then + flResolveOverlap( CellView + ?SkipCellList SkipCellList + ?LPMacroFileName sprintf( nil "%s/glpsol/%s.lpt" TEMP projectName) + ?LPOutputFileName sprintf( nil "%s/glpsol/%s.out" TEMP projectName) + ?LPLogFileName sprintf( nil "%s/glpsol/%s.log" TEMP projectName) + ?LPmemoFileName sprintf( nil "%s/glpsol/%s.memo" TEMP projectName) + ?SaveFileName UIResolveOverlap_Form->UIResolveOverlap_AutoSaveFileName->value + ?BlockLayer list("LOGO" "drawing") + ?SaveCellView UIResolveOverlap_Form->UIResolveOverlap_SaveCellView->value + ?AbutCellKeepOrder UIResolveOverlap_Form->UIResolveOverlap_AbutCellKeepOrder->value + ?SingleHierarchy UIResolveOverlap_Form->UIResolveOverlap_SingleHierarchy->value + ?xtotal xtotal + ?Mode 1 + ?SnapXGrid UIResolveOverlap_Form->UIResolveOverlap_SnapXGrid->value + ?FreezeCellList FreezeCellList + ) + else + flResolveOverlap( CellView + ?SkipCellList SkipCellList + ?LPMacroFileName sprintf( nil "%s/glpsol/%s.lpt" TEMP projectName) + ?LPOutputFileName sprintf( nil "%s/glpsol/%s.out" TEMP projectName) + ?LPLogFileName sprintf( nil "%s/glpsol/%s.log" TEMP projectName) + ?LPmemoFileName sprintf( nil "%s/glpsol/%s.memo" TEMP projectName) + ?SaveFileName UIResolveOverlap_Form->UIResolveOverlap_AutoSaveFileName->value + ?BlockLayer list("LOGO" "drawing") + ?SaveCellView UIResolveOverlap_Form->UIResolveOverlap_SaveCellView->value + ?AbutCellKeepOrder UIResolveOverlap_Form->UIResolveOverlap_AbutCellKeepOrder->value + ?SingleHierarchy UIResolveOverlap_Form->UIResolveOverlap_SingleHierarchy->value + ?xtotal xtotal + ?Mode 0 + ?SnapXGrid UIResolveOverlap_Form->UIResolveOverlap_SnapXGrid->value + ?FreezeCellList FreezeCellList + ) + ) + + ) + ) + ) +) + +( UICreateComponent + "UIResolveOverlap_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateRadioField + ?name `UIResolveOverlap_Scope + ?prompt "Scope: " + ?choices list( "CellView" "Selected") + ?defValue "CellView" ) + ( hiCreateStringField + ?name `UIResolveOverlap_ProjectName + ?prompt "glpsol Project Name" + ?defValue "default" ) + ( hiCreateStringField + ?name `UIResolveOverlap_SkipCellFileName + ?prompt "SkipCellFileName" + ?defValue "skipCell.list" ) + ( hiCreateStringField + ?name `UIResolveOverlap_AutoSaveFileName + ?prompt "AutoSaveFileName" + ?defValue "autosave.sav" ) + ( hiCreateBooleanButton + ?name `UIResolveOverlap_AbutCellKeepOrder + ?buttonText "Y-Abutting Cells Keep Their Relative X Order" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIResolveOverlap_SingleHierarchy + ?buttonText "Run on Just Top One Hierarchy" + ?defValue t ) + ( hiCreateRadioField + ?name `UIResolveOverlap_Mode + ?prompt "Run Second Pass: " + ?choices list( "No" "Compact Left" "Least Move") + ?defValue "No" ) + ( hiCreateBooleanButton + ?name `UIResolveOverlap_SaveCellView + ?buttonText "Save All CellViews" + ?defValue t ) + ( hiCreateFloatField + ?name `UIResolveOverlap_SnapXGrid + ?prompt "Snap X to Grid" + ?defValue 0.0 ) + ( hiCreateFormButton + ?name `UIResolveOverlap_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Resolve_Overlaps_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIResolveOverlap_Form + ?formTitle "Resolve Overlaps" + ?fields Fields + ?callback "( UIResolveOverlapFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/SaveFloorplan.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/SaveFloorplan.il new file mode 100644 index 0000000000..1523a0ec19 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Floorplan/SaveFloorplan.il @@ -0,0 +1,64 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "2.Save Floorplan" "UISaveFloorplan" ) +( UICreateMenuItemCallBack + `UISaveFloorplanCB + (lambda () + let(() + UISaveFloorplan_Form->UISaveFloorplan_FileName->value=sprintf( nil "%s.sav" UIGetCellView()~>cellName) + hiDisplayForm( UISaveFloorplan_Form ) + ) + ) +) + +( UICreateAction + 'UISaveFloorplanFormCB + (lambda () + let( (CellView p s SkipCellList) + SkipCellList=nil + if( UISaveFloorplan_Form->UISaveFloorplan_SkipCellFileName->value!="" then + p=infile(UISaveFloorplan_Form->UISaveFloorplan_SkipCellFileName->value) + if( p then + while( fscanf( p "%s" s) SkipCellList=cons( s SkipCellList )) + else + SkipCellList=nil + ) + SkipCellList=nil + ) + CellView= UIGetCellView() + flSaveCoordinates( CellView + UISaveFloorplan_Form->UISaveFloorplan_FileName->value + ?SkipCellList SkipCellList + ?BlockLayer list("LOGO" "drawing") ) + ) + ) +) + +( UICreateComponent + "UISaveFloorplan_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UISaveFloorplan_SkipCellFileName + ?prompt "SkipCellFileName" + ?defValue "skipCell.list" ) + ( hiCreateStringField + ?name `UISaveFloorplan_FileName + ?prompt "FileName" + ?defValue "autosave.sav" ) + ) + ( hiCreateAppForm + ?name `UISaveFloorplan_Form + ?formTitle "Save Floorplan" + ?fields Fields + ?callback "( UISaveFloorplanFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/.menu new file mode 100644 index 0000000000..dfcd04d136 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/.menu @@ -0,0 +1 @@ +( list "Fulcrum" "UIFulcrum" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/.menu new file mode 100644 index 0000000000..2add0cd1e9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/.menu @@ -0,0 +1 @@ +( list "Cell Alignment" "UICellAlignment" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/CheckAlignment.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/CheckAlignment.il new file mode 100644 index 0000000000..c5ff5739e1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/CheckAlignment.il @@ -0,0 +1,13 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $DateTime: 2009/10/05 15:21:21 $ +; $Author: stevemc $ + +( list "Check Alignment" "UICheckAlignment" ) + +( UICreateMenuItemCallBack + `UICheckAlignmentCB + (lambda () + (CheckRoutedAlignment (geGetWindowCellView) ?dialog t) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/FixAlignment.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/FixAlignment.il new file mode 100644 index 0000000000..fbbf6a8fdf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/FixAlignment.il @@ -0,0 +1,13 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $DateTime: 2009/10/05 15:21:21 $ +; $Author: stevemc $ + +( list "Fix X Alignment" "UIFixXAlignment" ) + +( UICreateMenuItemCallBack + `UIFixXAlignmentCB + (lambda () + (fixXAlignment ?cv (geGetWindowCellView)) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/SetAlignment.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/SetAlignment.il new file mode 100644 index 0000000000..e0d19540b9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Align/SetAlignment.il @@ -0,0 +1,48 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LeafAbstractList.il#1 $ +; $DateTime: 2009/10/05 15:21:21 $ +; $Author: stevemc $ + +( list "Set Cell Align Property" "UISetAlignment" ) + +( UICreateMenuItemCallBack + `UISetAlignmentCB + (lambda () + ( hiDisplayForm UISetAlignment_Form ) ) ) + +( UICreateAction + 'UISetAlignmentFormCB + (lambda () + (let (leaflist abstracts overwrite layouts) + (SetAlignmentUI) + ) + ) +) + + +( UICreateComponent + "UISetAlignment_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateFloatField + ?name `UISetAlignment_Form_XAlign + ?prompt "X Alignment Value" + ?defValue (GetXAlignmentProp (geGetWindowCellView)) ) + ( hiCreateFloatField + ?name `UISetAlignment_Form_YAlign + ?prompt "Y Alignment Value" + ?defValue 5.76 ) + ) + )) + + + ( hiCreateAppForm + ?name `UISetAlignment_Form + ?formTitle "Attach Cell Alignment Property" + ?fields Fields + ?callback "(UISetAlignmentFormCB)" + ) ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGrid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGrid.il new file mode 100755 index 0000000000..5ff955c0e7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGrid.il @@ -0,0 +1,88 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/AutoPowerGrid.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Auto PowerGrid" "UIAutoPowerGrid" ) + + +( UICreateMenuItemCallBack + `UIAutoPowerGridCB + (lambda () + let((CellView powerCellName OBSCellName Components RComponents) + CellView= UIGetCellView() + Components= parseString( CellView~>cellName "." ) + RComponents= reverse( Components ) + if( length(RComponents)>=3 then + powerCellName=sprintf( nil "%s_%s" cadr(RComponents) car(RComponents)) + OBSCellName=sprintf( nil "%s.wires.%s_OBS" car( NameParseCellName( CellView~>cellName )) powerCellName ) + powerCellName=sprintf( nil "%s.wires.%s_POWER_GRID_TIEOFF" car( NameParseCellName( CellView~>cellName )) powerCellName ) + UIAutoPowerGrid_Form->UIAutoPowerGrid_Form_OBSCellName->value = OBSCellName + UIAutoPowerGrid_Form->UIAutoPowerGrid_Form_PowerGridCellName->value = powerCellName + ) + ( hiDisplayForm UIAutoPowerGrid_Form ) ) ) ) + + +( UICreateAction + 'UIAutoPowerGridFormCB + (lambda () + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + + (let (CellView powerGridView) + CellView = UIGetCellView( ) + powerGridView=AutoGeneratePowerGrid( CellView + UIAutoPowerGrid_Form->UIAutoPowerGrid_Form_PowerGridCellName->value + ?OBSCellName UIAutoPowerGrid_Form->UIAutoPowerGrid_Form_OBSCellName->value + ?OBSViewName UIAutoPowerGrid_Form->UIAutoPowerGrid_Form_OBSViewName->value + ?powerViewName UIAutoPowerGrid_Form->UIAutoPowerGrid_Form_PowerGridViewName->value + ) + if( powerGridView then + dbCreateInst( CellView powerGridView "tiehilo" list(0 0) "R0" ) + dbSave( CellView ) + else + printf("Error: AutoGeneratePowerGrid failed.\n") + ) + ) + ) +) + + +( UICreateComponent + "UIAutoPowerGrid_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIAutoPowerGrid_Form_PowerGridCellName + ?prompt "Power Grid Cell Name" + ?defValue "powerGridTieOff" ) + ( hiCreateStringField + ?name `UIAutoPowerGrid_Form_PowerGridViewName + ?prompt "Power Grid View Name" + ?defValue "layout" ) + ( hiCreateStringField + ?name `UIAutoPowerGrid_Form_OBSCellName + ?prompt "Routing Obstruction Cell Name" + ?defValue "OBS" ) + ( hiCreateStringField + ?name `UIAutoPowerGrid_Form_OBSViewName + ?prompt "Routing Obstruction View Name" + ?defValue "layout" ) + ( hiCreateFormButton + ?name `UIAutoPowerGrid_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Power_Grid_Cell_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIAutoPowerGrid_Form + ?formTitle "Create Power Grid Cell" + ?fields Fields + ?callback "( UIAutoPowerGridFormCB )" + ) + ) + ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGridAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGridAbstract.il new file mode 100755 index 0000000000..0567fc17aa --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/AutoPowerGridAbstract.il @@ -0,0 +1,77 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/AutoPowerGridAbstract.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Auto PowerGrid Abstract" "UIAutoPowerGridAbstract" ) + + +( UICreateMenuItemCallBack + `UIAutoPowerGridAbstractCB + (lambda () + let((CellView powerCellName Components RComponents) + CellView = UIGetCellView() + ( hiDisplayForm UIAutoPowerGridAbstract_Form ) + ) + ) +) + + +( UICreateAction + 'UIAutoPowerGridAbstractFormCB + (lambda () + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + + (let (CellView powerGridView Command OptionList) + CellView = UIGetCellView() + AutoGeneratePowerGridAbstract( CellView CellView~>cellName + ?powerViewName CellView~>viewName + ?powerAbstractViewName UIAutoPowerGridAbstract_Form->UIAutoPowerGridAbstract_Form_PowerGridAbstractViewName->value + ) + + ; log abstract options + OptionList = "Create Power Grid Abstract" + Command = sprintf( nil + "%s/createAbstractCellLog --cell=%s:%s:%s --client-spec=%s --dfII-dir=%s --opt-str=\"%s\"" + PackageGetBinRoot( ) + CellView~>libName + CellView~>cellName + CellView~>viewName + ConfigFileGetValue( TheCDSConfigTable "P4CLIENT" ) + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + OptionList + ) + printf( "Update abstract log.\n%s\n" Command ) + shell( Command ) + ) + ) +) + + +( UICreateComponent + "UIAutoPowerGridAbstract_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIAutoPowerGridAbstract_Form_PowerGridAbstractViewName + ?prompt "Power Grid Abstract View Name" + ?defValue "abstract" ) + ( hiCreateFormButton + ?name `UIAutoPowerGridAbstract_Form_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Power_Grid_Abstract_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIAutoPowerGridAbstract_Form + ?formTitle "Create Power Grid Abstract" + ?fields Fields + ?callback "( UIAutoPowerGridAbstractFormCB )" + ) + ) + ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/.menu new file mode 100644 index 0000000000..f2dfbf4ba6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/.menu @@ -0,0 +1 @@ +( list "Bus Scripts" "UIBusScript" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CopyBusGuidesToPrelayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CopyBusGuidesToPrelayout.il new file mode 100644 index 0000000000..b714dc1de9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CopyBusGuidesToPrelayout.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Copy Guides to Prelayout" "UICopyBusGuidesToPrelayout" ) + + +( UICreateMenuItemCallBack + `UICopyBusGuidesToPrelayoutCB + (lambda () + (CopyBusGuidesToPrelayout) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CreateGuideInst.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CreateGuideInst.il new file mode 100644 index 0000000000..a582ce3627 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/CreateGuideInst.il @@ -0,0 +1,74 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +( list "Create Guide Instance" "UICreateGuideInst" ) + + +( UICreateMenuItemCallBack + `UICreateGuideInstCB + (lambda () + let((CellView) + CellView = UIGetCellView() + CellBase = cadr( reverse( parseString( CellView~>cellName "." ) )) + UICreateGuideInst_Form->UICreateGuideInst_cellname->value = + strcat( CellView~>libName ".wires." CellBase "_buswires") + hiDisplayForm( UICreateGuideInst_Form ) + )) +) + + +( UICreateComponent + "UICreateGuideInst_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateGuideInst_cellname + ?prompt "Cell Name" + ?defValue "" ) + ( hiCreateStringField + ?name `UICreateGuideInst_instname + ?prompt "Instance Name" + ?defValue "buswires" ) + ( hiCreateBooleanButton + ?name `UICreateGuideInst_wires + ?buttonText "Create wires.il" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateGuideInst_defchans + ?buttonText "Include global DefChans in wires.il" + ?defValue t ) + ) + ( hiCreateAppForm + ?name `UICreateGuideInst_Form + ?formTitle "Create Guide Instance" + ?fields Fields + ?callback "( UICreateGuideInstFormCB )" + ) + ) + ) + ) +) + + +( UICreateAction + 'UICreateGuideInstFormCB + (lambda () + let((CellView) + CellView = UIGetCellView() + MakeGuideInst( UICreateGuideInst_Form->UICreateGuideInst_cellname->value + UICreateGuideInst_Form->UICreateGuideInst_instname->value ) + when( UICreateGuideInst_Form->UICreateGuideInst_wires->value + MakeWiresSkill( CellView + UICreateGuideInst_Form->UICreateGuideInst_instname->value + UICreateGuideInst_Form->UICreateGuideInst_defchans->value ) + ) + )) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteBusWires.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteBusWires.il new file mode 100644 index 0000000000..9f4feb226e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteBusWires.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Delete Bus Wires" "UIDeleteBusWires" ) + + +( UICreateMenuItemCallBack + `UIDeleteBusWiresCB + (lambda () + DeleteBusWires() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteOverlapMarkers.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteOverlapMarkers.il new file mode 100644 index 0000000000..2c696e76d6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteOverlapMarkers.il @@ -0,0 +1,19 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Nano/Preroute +; +; reference function from layout/bus/bus.il +; +( list "Delete Overlap Markers" "UIDeleteOverlapMarkers" ) + +( UICreateMenuItemCallBack + `UIDeleteOverlapMarkersCB + (lambda () + DeleteMarkers() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteWires.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteWires.il new file mode 100644 index 0000000000..1a963fbaf5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DeleteWires.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Delete Wires Alt-d" "UIDeleteWires" ) + + +( UICreateMenuItemCallBack + `UIDeleteWiresCB + (lambda () + DeleteWires() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawAllPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawAllPins.il new file mode 100644 index 0000000000..7729e7539b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawAllPins.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Draw All Pins Ctrl-Alt-g" "UIDrawAllPins" ) + + +( UICreateMenuItemCallBack + `UIDrawAllPinsCB + (lambda () + RedrawAllPins() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawWires.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawWires.il new file mode 100644 index 0000000000..f11a525f66 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/DrawWires.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Draw Wires Alt-b" "UIDrawWires" ) + + +( UICreateMenuItemCallBack + `UIDrawWiresCB + (lambda () + DrawWires() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindCopies.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindCopies.il new file mode 100644 index 0000000000..1411dec690 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindCopies.il @@ -0,0 +1,26 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Find Copied Guidepaths" "UIFindCopies" ) + + +( UICreateMenuItemCallBack + `UIFindCopiesCB + (lambda () + copies=(FindDuplicateBuswires ?check_points nil) + (when copies + (UIPopUpDialog "Paths found which are possibly copies.") + (foreach path copies + (printf "Pattern: %s Prefix: %s\n" (GetProp path "BusPattern" nil) (GetProp path "BusPrefix" nil) ) + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindOverlaps.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindOverlaps.il new file mode 100644 index 0000000000..4bd17e3b78 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/FindOverlaps.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Find Bus Overlaps" "UIFindBusOverlaps" ) + + +( UICreateMenuItemCallBack + `UIFindBusOverlapsCB + (lambda () + FindBusOverlaps() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/MoveGuidesToBuswires.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/MoveGuidesToBuswires.il new file mode 100644 index 0000000000..b503e46e4c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/MoveGuidesToBuswires.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Move Guides to buswires cell" "UIMoveGuidesToBuswires" ) + + +( UICreateMenuItemCallBack + `UIMoveGuidesToBuswiresCB + (lambda () + (MoveGuidesToBuswiresCell) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RefreshAll.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RefreshAll.il new file mode 100644 index 0000000000..294bbc8699 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RefreshAll.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Refresh All Ctrl-Alt-b" "UIRefreshAll" ) + + +( UICreateMenuItemCallBack + `UIRefreshAllCB + (lambda () + RefreshAllBuswires() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RoundGuidePaths.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RoundGuidePaths.il new file mode 100644 index 0000000000..b83931c8f5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/RoundGuidePaths.il @@ -0,0 +1,49 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +( list "Round Guidepaths to Grid" "UIRoundGuides" ) + + +( UICreateMenuItemCallBack + `UIRoundGuidesCB + (lambda () + hiDisplayForm( UIRoundGuides_Form ) + ) +) + + +( UICreateComponent + "UIRoundGuides_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateFloatField + ?name `UIRoundGuides_grid + ?prompt "Grid" + ?defValue TrackPitch/2 ) + ) + ( hiCreateAppForm + ?name `UIRoundGuides_Form + ?formTitle "Round Guidpaths to Grid" + ?fields Fields + ?callback "( UIRoundGuidesFormCB )" + ) + ) + ) + ) +) + + +( UICreateAction + 'UIRoundGuidesFormCB + (lambda () + RoundGuidesToGrid( ?grid UIRoundGuides_Form->UIRoundGuides_grid->value ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/SetBusPattern.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/SetBusPattern.il new file mode 100644 index 0000000000..fadbfcdfc1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Bus/SetBusPattern.il @@ -0,0 +1,51 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "Set Bus Wire Pattern Ctrl-b" "UISetBusPattern" ) + + +( UICreateMenuItemCallBack + `UISetBusPatternCB + (lambda () + hiDisplayForm( UISetBusPattern_Form ) + ) +) + + +( UICreateComponent + "UISetBusPattern_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UISetBusPattern_Pattern + ?prompt "Bus Pattern" + ?defValue "e1of4" ) + ) + ( hiCreateAppForm + ?name `UISetBusPattern_Form + ?formTitle "Set Bus Wire Pattern" + ?fields Fields + ?callback "( UISetBusPatternFormCB )" + ) + ) + ) + ) +) + + +( UICreateAction + 'UISetBusPatternFormCB + (lambda () + SetPattern( UISetBusPattern_Form->UISetBusPattern_Pattern->value ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CCAR.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CCAR.il new file mode 100644 index 0000000000..1334880c2a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CCAR.il @@ -0,0 +1,145 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/SyncToNetList.il#13 $ +; $DateTime: 2004/11/24 12:59:08 $ +; $Author: khe $ + + +( list "CCAR" "UICCARFile" ) + +( UICreateMenuItemCallBack + `UICCARFileCB + (lambda () + hiDisplayForm( UICCARFile_Form ) + ) +) + +( UICreateAction + 'UICCARFileFormCB + (lambda () + (let (routeType viaType botMetal topMetal routeGND routeVdd routeWires + subcellView importView conductorDepth SaveQuit) + routeType = UICCARFile_Form->UICCARFile_RouteType->value + viaType = UICCARFile_Form->UICCARFile_ViaType->value + botMetal = UICCARFile_Form->UICCARFile_BotMetal->value + topMetal = UICCARFile_Form->UICCARFile_TopMetal->value + routeGND = UICCARFile_Form->UICCARFile_RouteGND->value + routeVdd = UICCARFile_Form->UICCARFile_RouteVdd->value + routeWires = UICCARFile_Form->UICCARFile_RouteWires->value + SaveQuit = UICCARFile_Form->UICCARFile_SaveQuit->value + subcellView = UICCARFile_Form->UICCARFile_SubcellView->value + importView = UICCARFile_Form->UICCARFile_ImportView->value + conductorDepth = UICCARFile_Form->UICCARFile_ConductorDepth->value + botMetal = (if botMetal=="wires.il" nil (atoi botMetal)) + topMetal = (if topMetal=="wires.il" nil (atoi topMetal)) + (cond (routeType=="fat" + (BundledRoute ?bottomMetal botMetal ?topMetal topMetal + ?viaType viaType ?routeWires routeWires + ?subcellView subcellView ?importView importView + ?SaveQuit SaveQuit)) + (t + (Route ?type routeType ?viaType viaType + ?routeGND routeGND ?routeVdd routeVdd + ?bottomMetal botMetal ?topMetal topMetal + ?subcellView subcellView ?importView importView + ?conductorDepth conductorDepth ?SaveQuit SaveQuit)) + ) + ) + ) + ) + +( UICreateAction + 'UICCARFile_RouteTypeCB + (lambda () + (let ( + ( routeType UICCARFile_Form->UICCARFile_RouteType->value ) ) + (cond (routeType == "custom_leaf" + UICCARFile_Form->UICCARFile_ViaType->value = "c" + UICCARFile_Form->UICCARFile_BotMetal->value = "1" + UICCARFile_Form->UICCARFile_TopMetal->value = "3" + UICCARFile_Form->UICCARFile_RouteGND->value = t + UICCARFile_Form->UICCARFile_RouteVdd->value = t + UICCARFile_Form->UICCARFile_ImportView->value = "layout") + (t + UICCARFile_Form->UICCARFile_ViaType->value = + UICCARFile_Form->UICCARFile_ViaType->defValue + UICCARFile_Form->UICCARFile_BotMetal->value = + UICCARFile_Form->UICCARFile_BotMetal->defValue + UICCARFile_Form->UICCARFile_TopMetal->value = + UICCARFile_Form->UICCARFile_TopMetal->defValue + UICCARFile_Form->UICCARFile_RouteGND->value = + UICCARFile_Form->UICCARFile_RouteGND->defValue + UICCARFile_Form->UICCARFile_RouteVdd->value = + UICCARFile_Form->UICCARFile_RouteVdd->defValue + UICCARFile_Form->UICCARFile_ImportView->value = + UICCARFile_Form->UICCARFile_ImportView->defValue) + ) + ) + ) +) + +( UICreateComponent + "UICCARFile_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateRadioField + ?name `UICCARFile_RouteType + ?prompt "Route Type" + ?choices list( "leaf" "custom_leaf" "mid" "fat") + ?defValue "mid" + ?callback list( "UICCARFile_RouteTypeCB") ) + ( hiCreateRadioField + ?name `UICCARFile_ViaType + ?prompt "Via Type" + ?choices list( "min" "c") + ?defValue "c" ) + ( hiCreateRadioField + ?name `UICCARFile_BotMetal + ?prompt "Bottom Metal Layer" + ?choices list( "1" "2" "3" "4" "5" "6" "7" "wires.il") + ?defValue "wires.il" ) + ( hiCreateRadioField + ?name `UICCARFile_TopMetal + ?prompt "Top Metal Layer" + ?choices list( "2" "3" "4" "5" "6" "7" "wires.il") + ?defValue "wires.il" ) + ( hiCreateStringField + ?name `UICCARFile_SubcellView + ?prompt "Subcell View(s)" + ?defValue "abstract_edit abstract" ) + ( hiCreateStringField + ?name `UICCARFile_ImportView + ?prompt "Import View" + ?defValue "layout_pg" ) + ( hiCreateIntField + ?name `UICCARFile_ConductorDepth + ?prompt "Conductor Depth (not fat mode)" + ?defValue 0 ) + ( hiCreateBooleanButton + ?name `UICCARFile_RouteGND + ?buttonText "Route GND (not fat mode)" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICCARFile_RouteVdd + ?buttonText "Route Vdd (not fat mode)" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICCARFile_RouteWires + ?buttonText "Route Wires (fat mode only)" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICCARFile_SaveQuit + ?buttonText "Save and Quit automatically" + ?defValue nil ) + ) + ( hiCreateAppForm + ?name `UICCARFile_Form + ?formTitle "CCAR" + ?fields Fields + ?callback "( UICCARFileFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CheckSubcell.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CheckSubcell.il new file mode 100644 index 0000000000..2581592030 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CheckSubcell.il @@ -0,0 +1,64 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/CreateCDL.il#11 $ +; $DateTime: 2004/08/21 16:39:54 $ +; $Author: clayton $ + + +( list "Check Subcell Connectivity" "UICheckSubcell" ) + +( UICreateMenuItemCallBack + `UICheckSubcellCB + (lambda () + (let ( CellView subCellView reportList uniqueInstances instances subCellView shapes) + CellView= UIGetCellView() + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + instances= car( NameFilterInstances( CellView~>instances LibCellsToIgnore )) + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances=cons( inst uniqueInstances ) + ) + ) + reportList=nil + foreach( inst uniqueInstances + subCellView=nrOpenCellViewReadable( inst~>libName inst~>cellName inst~>viewName ) + shapes=setof( shape subCellView~>shapes + strncmp( shape~>layerName "METAL" 5)==0 && + (shape~>purpose=="drawing" || shape~>purpose=="pin") && shape~>objType!="label") + totalMetalShapes=length(shapes) + FullViaWidth=(ContactExtension *2 + ContactCutWidth)*MicronsPerMeter + shapes=setof( shape shapes defRectArea(shape~>bBox)>FullViaWidth*FullViaWidth*1.01 ) + shapes=setof( shape shapes shape~>net==nil ) + noConnectivityShapes=length(shapes) + reportList=cons( list( inst~>cellName totalMetalShapes noConnectivityShapes) reportList) + ) + UICheckSubcell_Form->UICheckSubcell_Report->choices=reportList + hiDisplayForm( UICheckSubcell_Form ) + ) + ) +) +( UICreateComponent + "UICheckSubcell_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( list( + ( hiCreateReportField + ?name 'UICheckSubcell_Report + ?headers '(("Cell Name" 270 'left 'string t 'strcmp) + ("Total Metal Shapes" 150 'left 'int t lambda((x y) cond((x>y 1)(xy 1)(xlibName CellView~>cellName CellView~>viewName + UICreateFloorplan_Form->UICreateFloorplan_ViewName->value + ?Verbose UICreateFloorplan_Form->UICreateFloorplan_Verbose->value + ) + ) + ) +) + +( UICreateComponent + "UICreateFloorplan_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateFloorplan_ViewName + ?prompt "Floorplan View Name" + ?defValue "floorplan" ) + ( hiCreateBooleanButton + ?name `UICreateFloorplan_Verbose + ?buttonText "Verbose" + ?defValue nil ) + ) + ( hiCreateAppForm + ?name `UICreateFloorplan_Form + ?formTitle "Create Floorplan Views" + ?fields Fields + ?callback "( UICreateFloorplanFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreateLib.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreateLib.il new file mode 100755 index 0000000000..8dc56b1ace --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreateLib.il @@ -0,0 +1,82 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Nano/CreateLib.il#13 $ +; $DateTime: 2004/11/24 12:59:08 $ +; $Author: khe $ + +; +; menu item Nano/Lib +; +( list "Create Library" "UICreateLib" ) + +( UICreateMenuItemCallBack + `UICreateLibCB + (lambda () + UICreateLib_Form->UICreateLib_dfIIDir->value=ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + UICreateLib_Form->UICreateLib_P4Client->value=ConfigFileGetValue( TheCDSConfigTable "P4CLIENT" ) + hiDisplayForm( UICreateLib_Form ) + ) +) + +( UICreateAction + 'UICreateLibFormCB + (lambda () + let( (CellView libName libId libDir cmd) + libName=UICreateLib_Form->UICreateLib_LibName->value + GDSIIHierMakeLibrary( + libName + UICreateLib_Form->UICreateLib_dfIIDir->value + TechLibName ) + libId=ddGetObj( libName ) + if(libId==nil then + printf("unable to create lib %s \n" libName)) + if(UICreateLib_Form->UICreateLib_P4CheckIn->value && libId then + libDir=ddGetObjReadPath(libId) + rexCompile("/mnt/fulcrum") + libDir=rexReplace(libDir "" 0) + cmd=sprintf( nil "p4 -c %s add %s/data.dm" UICreateLib_Form->UICreateLib_P4Client->value + libDir) + printf("%s \n" cmd) + system(cmd) + cmd=sprintf( nil "p4 -c %s add %s/cdsinfo.tag" UICreateLib_Form->UICreateLib_P4Client->value + libDir) + printf("%s \n" cmd) + system(cmd) + ) + + ) + ) +) + +( UICreateComponent + "UICreateLib_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateLib_LibName + ?prompt "Library Name" + ?defValue "" ) + ( hiCreateStringField + ?name `UICreateLib_dfIIDir + ?prompt "dfII dir" + ?defValue "" ) + ( hiCreateBooleanButton + ?name `UICreateLib_P4CheckIn + ?buttonText "P4 Check In" + ?defValue nil ) + ( hiCreateStringField + ?name `UICreateLib_P4Client + ?prompt "P4 Client" + ?defValue "" ) + ) + ( hiCreateAppForm + ?name `UICreateLib_Form + ?formTitle "Create Lib Views" + ?fields Fields + ?callback "( UICreateLibFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreatePrBound.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreatePrBound.il new file mode 100644 index 0000000000..315eb5f26d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/CreatePrBound.il @@ -0,0 +1,46 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/CreateCDL.il#11 $ +; $DateTime: 2004/08/21 16:39:54 $ +; $Author: clayton $ + + +( list "Create prBound" "UICreatePrBound" ) + +( UICreateMenuItemCallBack + `UICreatePrBoundCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) + lpps + bBox + x1 x2 y1 y2 + Grid + ) + Grid=ManufacturingGrid*MicronsPerMeter + bBox=CellView~>bBox + x1=min(caar(bBox) caadr(bBox)) + x2=max(caar(bBox) caadr(bBox)) + y1=min(cadar(bBox) cadadr(bBox)) + y2=max(cadar(bBox) cadadr(bBox)) + x1=floor(x1/Grid)*Grid + y1=floor(y1/Grid)*Grid + x2=ceiling(x2/Grid)*Grid + y2=ceiling(y2/Grid)*Grid + bBox=list( x1:y1 x2:y2 ) + lpps=setof( lpp CellView~>lpps lpp~>layerName==car(BoundaryLPP) ) + foreach( shape CellView->shapes + when( shape->lpp==BoundaryLPP + dbDeleteObject( shape ) + ) + ) + llcorner=car(CellView->bBox) + urcorner=cadr(CellView->bBox) + ulcorner=(list car(llcorner) cadr(urcorner) ) + lrcorner=(list car(urcorner) cadr(llcorner) ) + dbCreatePRBoundary( CellView list(llcorner lrcorner urcorner ulcorner) ) + + dbSave( CellView ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DeleteAllShapes.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DeleteAllShapes.il new file mode 100644 index 0000000000..cbfa2ab4a7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DeleteAllShapes.il @@ -0,0 +1,17 @@ +; Copyright 2008 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ +( list "Delete All Shapes" "UIDeleteAllShapes" ) + +( UICreateMenuItemCallBack + `UIDeleteAllShapesCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + foreach( shape CellView~>shapes + dbDeleteObject( shape ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DiffLayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DiffLayout.il new file mode 100644 index 0000000000..1bddc85ee3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/DiffLayout.il @@ -0,0 +1,207 @@ +; Copyright 2007 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Diff Layout" "UIDiffLayout" ) + + +defun( nrDiffLayout ( CellView1 CellView2 p_out ) + let((instTable1 instTable2 inst instName + shapeTable1 shapeTable2 shape shapeID + countInst1 countInst2 countShape1 countShape2) + instTable1=makeTable(`instTable nil) + instTable2=makeTable(`instTable nil) + fprintf(p_out "Layout1: %L(%L)\n vs \nLayout2: %L(%L) ...\n" CellView1~>cellName CellView1~>viewName CellView2~>cellName CellView2~>viewName) + printf("Layout1: %L(%L)\n vs \nLayout2: %L(%L) ...\n" CellView1~>cellName CellView1~>viewName CellView2~>cellName CellView2~>viewName) + fprintf(p_out "Comparing instances...\n") + printf("Comparing instances...\n") + foreach( inst CellView1~>instances instTable1[inst~>name]=inst ) + foreach( inst CellView2~>instances instTable2[inst~>name]=inst ) + foreach( instName instTable1 + if( instTable2[instName] then + cond( + ( instTable1[instName]~>cellName!=instTable2[instName]~>cellName + fprintf(p_out " %L has different cellName %L %L\n" instName instTable1[instName]~>cellName instTable2[instName]~>cellName) + ) + ( instTable1[instName]~>orient!=instTable2[instName]~>orient + fprintf(p_out " %L %L has different orient %L %L\n" instName instTable1[instName]~>cellName instTable1[instName]~>orient instTable2[instName]~>orient) + ) + ( instTable1[instName]~>xy!=instTable2[instName]~>xy + fprintf(p_out " %L %L has different xy %L %L\n" instName instTable1[instName]~>cellName instTable1[instName]~>xy instTable2[instName]~>xy) + ) + ( t instTable1[instName]=nil instTable2[instName]=nil ) + ) + ) + ) + printf("Comparing shapes...\n") + shapeTable1=makeTable(`shapeTable nil) + shapeTable2=makeTable(`shapeTable nil) + foreach( shape CellView1~>shapes + shapeID= list( shape~>layerName shape~>purpose shape~>objType shape~>bBox shape~>points) + shapeTable1[shapeID]=shape + ) + foreach( shape CellView2~>shapes + shapeID= list( shape~>layerName shape~>purpose shape~>objType shape~>bBox shape~>points) + shapeTable2[shapeID]=shape + ) + foreach( shapeID shapeTable1 + if( shapeTable2[shapeID] then + shapeTable1[shapeID]=nil shapeTable2[shapeID]=nil + ) + ) + countInst1=0 + countInst2=0 + countShape1=0 + countShape2=0 + fprintf(p_out "\nSUMMARY:\n\n") + fprintf(p_out "CellView1: %L %L %L\n" CellView1~>libName CellView1~>cellName CellView1~>viewName) + foreach( instName instTable1 + if( instTable1[instName] then + fprintf(p_out " instName: %L cellName: %L xy: %L orient %L\n" + instName + instTable1[instName]~>cellName + if(instTable1[instName]~>objType=="mosaicInst" then + instTable1[instName]~>mosaic~>xy + else + instTable1[instName]~>xy + ) + if(instTable1[instName]~>objType=="mosaicInst" then + sprintf( nil "mosaic columns=%d rows=%d" instTable1[instName]~>mosaic~>columns instTable1[instName]~>mosaic~>rows) + else + instTable1[instName]~>orient + ) + ) + countInst1++ + ) + ) + fprintf(p_out "Unique shapes:\n") + foreach( shapeID shapeTable1 + if( shapeTable1[shapeID] then + fprintf(p_out " %L\n" shapeID ) + countShape1++ + ) + ) + fprintf(p_out "\nCellView2: %L %L %L\n" CellView2~>libName CellView2~>cellName CellView2~>viewName) + foreach( instName instTable2 + if( instTable2[instName] then + fprintf(p_out " instName: %L cellName: %L xy: %L orient %L\n" + instName + instTable2[instName]~>cellName + if(instTable2[instName]~>objType=="mosaicInst" then + instTable2[instName]~>mosaic~>xy + else + instTable2[instName]~>xy + ) + if(instTable2[instName]~>objType=="mosaicInst" then + sprintf( nil "mosaic columns=%d rows=%d" instTable2[instName]~>mosaic~>columns instTable2[instName]~>mosaic~>rows) + else + instTable2[instName]~>orient + ) + ) + countInst2++ + ) + ) + fprintf(p_out "Unique shapes:\n") + foreach( shapeID shapeTable2 + if( shapeTable2[shapeID] then + fprintf(p_out " %L\n" shapeID ) + countShape2++ + ) + ) + printf("CellView1 unique inst count: %d\n" countInst1) + printf("CellView2 unique inst count: %d\n" countInst2) + printf("CellView1 unique shape count: %d\n" countShape1) + printf("CellView2 unique shape count: %d\n" countShape2) + ) +) + +( UICreateMenuItemCallBack + `UIDiffLayoutCB + (lambda () + let((libName cellName) + libName = UIGetCellView()~>libName + cellName = UIGetCellView()~>cellName + UIDiffLayout_Form->UIDiffLayout_LibName1->value=libName + UIDiffLayout_Form->UIDiffLayout_LibName2->value=libName + UIDiffLayout_Form->UIDiffLayout_CellName1->value=cellName + UIDiffLayout_Form->UIDiffLayout_CellName2->value=cellName + hiDisplayForm( UIDiffLayout_Form ) + ) + ) +) + +( UICreateAction + 'UIDiffLayoutFormCB + (lambda () + (let ( cv1 cv2 p_out ) + CellView=UIGetCellView() + cv1=nrOpenCellViewReadable(UIDiffLayout_Form->UIDiffLayout_LibName1->value + UIDiffLayout_Form->UIDiffLayout_CellName1->value + UIDiffLayout_Form->UIDiffLayout_ViewName1->value + ) + cv2=nrOpenCellViewReadable(UIDiffLayout_Form->UIDiffLayout_LibName2->value + UIDiffLayout_Form->UIDiffLayout_CellName2->value + UIDiffLayout_Form->UIDiffLayout_ViewName2->value + ) + p_out=outfile(UIDiffLayout_Form->UIDiffLayout_LogFilename->value) + cond( + ( cv1==nil printf("Can not open %s(%s) for read.\n" + UIDiffLayout_Form->UIDiffLayout_CellName1->value + UIDiffLayout_Form->UIDiffLayout_ViewName1->value )) + ( cv2==nil printf("Can not open %s(%s) for read.\n" + UIDiffLayout_Form->UIDiffLayout_CellName1->value + UIDiffLayout_Form->UIDiffLayout_ViewName1->value )) + ( p_out==nil printf("Can not open %s for write.\n" UIDiffLayout_Form->UIDiffLayout_LogFilename->value )) + ( t nrDiffLayout( cv1 cv2 p_out )) + ) + close(p_out) + ) + ) +) + +( UICreateComponent + "UIDiffLayout_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIDiffLayout_LibName1 + ?prompt "LibName 1" + ?defValue "" ) + ( hiCreateStringField + ?name `UIDiffLayout_CellName1 + ?prompt "CellName 1" + ?defValue "" ) + ( hiCreateStringField + ?name `UIDiffLayout_ViewName1 + ?prompt "ViewName 1" + ?defValue "layout" ) + ( hiCreateStringField + ?name `UIDiffLayout_LibName2 + ?prompt "LibName 2" + ?defValue "" ) + ( hiCreateStringField + ?name `UIDiffLayout_CellName2 + ?prompt "CellName 2" + ?defValue "" ) + ( hiCreateStringField + ?name `UIDiffLayout_ViewName2 + ?prompt "ViewName 2" + ?defValue "layout_pg" ) + ( hiCreateStringField + ?name `UIDiffLayout_LogFilename + ?prompt "Compare Log" + ?defValue "compare.log" ) + ) ) ) + ( hiCreateAppForm + ?name `UIDiffLayout_Form + ?formTitle "Diff Layout" + ?fields Fields + ?callback "( UIDiffLayoutFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/EstimateWireDistance.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/EstimateWireDistance.il new file mode 100644 index 0000000000..3dd3b80bac --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/EstimateWireDistance.il @@ -0,0 +1,94 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Estimate Pin Wire Distance" "UIEstimateWireDistance" ) + +defun( flEstimateWireDistance (CellView) + let((Msg pinDistanceTable pins pin pinFigs instPinBBoxList instPinBBox + pinBBox x1 x2 y1 y2 pinDistanceList) + printf("Processing cell %s :\n" CellView~>cellName) + Msg=sprintf(nil "Processing cell %s :\n" CellView~>cellName) + pinDistanceTable=makeTable("myTable" 0.0) + pins=setof( pin CellView~>terminals !member( pin~>name list("Vdd" "GND"))) + foreach( pin pins + pinFigs=pin~>pins~>fig~>bBox + instPinBBoxList=foreach( mapcan instTerm pin~>net~>instTerms + foreach( mapcar bBox instTerm~>term~>pins~>fig~>bBox + geTransformUserBBox( bBox instTerm~>inst~>transform ) + ) + ) + cond( + (pinFigs==nil + Msg=sprintf(nil "%s Error: Unbound Pin Found: %s \n" Msg pin~>name) + ) + ( instPinBBoxList==nil pinDistanceTable[pin~>name]=0.0 ) + ( t + foreach( instPinBBox instPinBBoxList + x1=(leftEdge(instPinBBox)+rightEdge(instPinBBox))/2.0 + y1=(topEdge(instPinBBox)+bottomEdge(instPinBBox))/2.0 + foreach( pinBBox pinFigs + x2=(leftEdge(pinBBox)+rightEdge(pinBBox))/2.0 + y2=(topEdge(pinBBox)+bottomEdge(pinBBox))/2.0 + distance=abs(x1-x2)+abs(y1-y2) + pinDistanceTable[pin~>name]=max(pinDistanceTable[pin~>name] distance) + ) + ) + ) + ) + ) + pinDistanceList=sort( tableToList(pinDistanceTable) lambda((x y) cadr(x)>cadr(y))) + if( pinDistanceList printf("Longest Wire is %s : %f \n" caar(pinDistanceList) cadar(pinDistanceList))) + Msg=sprintf(nil "%sListing Pins in order: \n" Msg) + foreach(pin pinDistanceList + Msg=sprintf(nil "%s Pin %s : %f \n" Msg car(pin) cadr(pin)) + ) + Msg + ) +) + +( UICreateMenuItemCallBack + `UIEstimateWireDistanceCB + (lambda () + ( hiDisplayForm UIEstimateWireDistance_Form ) ) ) + +( UICreateAction + 'UIEstimateWireDistanceFormCB + (lambda () + (let ( CellView Msg p) + CellView=UIGetCellView() + Msg= flEstimateWireDistance(CellView) + p=outfile(UIEstimateWireDistance_Form->UIEstimateWireDistance_Filename->value) + if( p then + fprintf(p "%s" Msg) + close(p) + else + printf("Fail to write to file %s/n" UIEstimateWireDistance_Form->UIEstimateWireDistance_Filename->value) + ) + + ) + ) +) + +( UICreateComponent + "UIEstimateWireDistance_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIEstimateWireDistance_Filename + ?prompt "Output Filename" + ?defValue "PinWireEstimate.txt" ) + ) ) ) + ( hiCreateAppForm + ?name `UIEstimateWireDistance_Form + ?formTitle "Estimate Wire Distance" + ?fields Fields + ?callback "( UIEstimateWireDistanceFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/.menu new file mode 100644 index 0000000000..664a79f0b3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/.menu @@ -0,0 +1 @@ +( list "Fiji" "UIFiji" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/AttachPinShape.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/AttachPinShape.il new file mode 100644 index 0000000000..e673000dc6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/AttachPinShape.il @@ -0,0 +1,116 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Attach Pin Shape" "UIAttachPinShape" ) + +( UICreateMenuItemCallBack + `UIAttachPinShapeCB + (lambda () + let(( CellView ) + CellView=UIGetCellView() + fxAttachPinShapes(CellView) +; dbSave(CellView) + ) + ) +) + +defun( fxGetLabelFromPinShape ( pinBBox labels ) + let((x1 x2 y1 y2 x y label) + x1=leftEdge(pinBBox) + x2=rightEdge(pinBBox) + y1=bottomEdge(pinBBox) + y2=topEdge(pinBBox) + foreach( mapcan label labels + x=car(label~>xy) + y=cadr(label~>xy) + if( x>=x1 && x<=x2 && y>=y1 && y<=y2 then list(label) + else nil + ) + ) + ) +) + +defun( fxAttachPinShapes ( CellView ) + let((pinShapes pinLabels labels label shape shapes net + n lpp prbound shape w1 w2 h1 h2 x1 x2 y1 y2 m3power m3shape) + pinShapes=setof( shape CellView~>shapes shape~>purpose=="pin") + pinLabels=setof( shape CellView~>shapes shape~>objType=="label") + foreach( pinShape pinShapes + labels=setof( shapes fxGetLabelFromPinShape( pinShape~>bBox pinLabels) + shapes~>objType=="label" && shapes~>layerName==pinShape~>layerName ) + if( length( labels ) != 1 then + printf("Warning: error pin shape found at %L\n" pinShape~>bBox ) + else + label=car( labels ) + net=dbMakeNet( CellView label~>theLabel ) + dbCreatePin( net pinShape ) + label~>parent=pinShape + if( label~>theLabel=="Vdd" then + if( bottomEdge(pinShape~>bBox)<=2.7 && bottomEdge(pinShape~>bBox)>=0.18 then + dbMoveFig( pinShape CellView list( list( 0 2.88-(bottomEdge(pinShape~>bBox)+topEdge(pinShape~>bBox))/2) "R0")) + ) + ) + if( label~>theLabel=="GND" then + if( bottomEdge(pinShape~>bBox)<=-0.18 && bottomEdge(pinShape~>bBox)>=-2.7 then + dbMoveFig( pinShape CellView list( list( 0 -(bottomEdge(pinShape~>bBox)+topEdge(pinShape~>bBox))/2) "R0")) + ) + ) + ) + ) + unconnectLabels=setof( shape CellView~>shapes shape~>objType=="label" && shape~>parent==nil) + foreach( label unconnectLabels + pinShapes=dbGetTrueOverlaps( CellView + list( label~>xy label~>xy ) + label~>lpp + 1 + ) + foreach(pinShape pinShapes + net=dbMakeNet( CellView label~>theLabel ) + dbCreatePin( net pinShape ) + label~>parent=pinShape + if( label~>theLabel=="Vdd" then + if( bottomEdge(pinShape~>bBox)<=2.7 && bottomEdge(pinShape~>bBox)>=0.18 then + dbMoveFig( pinShape CellView list( list( 0 2.88-(bottomEdge(pinShape~>bBox)+topEdge(pinShape~>bBox))/2) "R0")) + ) + ) + if( label~>theLabel=="GND" then + if( bottomEdge(pinShape~>bBox)<=-0.18 && bottomEdge(pinShape~>bBox)>=-2.7 then + dbMoveFig( pinShape CellView list( list( 0 -(bottomEdge(pinShape~>bBox)+topEdge(pinShape~>bBox))/2) "R0")) + ) + ) + ) + ) + + ; Attach Power Grid Pin + prbound=car( car( setof( lpp CellView~>lpps lpp~>layerName=="prBoundary"))~>shapes) + w1=leftEdge(prbound~>bBox) + w2=rightEdge(prbound~>bBox) + height=topEdge(prbound~>bBox) + net=dbMakeNet( CellView "GND" ) + for( n 0 floor(height/5.76) + h1=n*5.76-0.18 h2=n*5.76+0.18 + bBox=list(w1:h1 w2:h2) + m3power=dbGetOverlaps( CellView bBox Metal3LPP) + m3shape=setof( shape m3power shape~>objType!="label" ) + if( length(m3shape)==1 then + dbCreatePin( net car(m3shape)) + ) + ) + net=dbMakeNet( CellView "Vdd" ) + for( n 0 floor(height/5.76) + h1=n*5.76+2.88-0.18 h2=n*5.76+2.88+0.18 + bBox=list(w1:h1 w2:h2) + m3power=dbGetOverlaps( CellView bBox Metal3LPP) + m3shape=setof( shape m3power shape~>objType!="label" ) + if( length(m3shape)==1 then + dbCreatePin( net car(m3shape)) + ) + ) + unconnectLabels=setof( shape CellView~>shapes shape~>objType=="label" && shape~>parent==nil) + if( unconnectLabels then + printf( "Labels not attached to pin layers: %L " unconnectLabels~>theLabel ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/CheckSubcellPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/CheckSubcellPins.il new file mode 100644 index 0000000000..778fc0b437 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/CheckSubcellPins.il @@ -0,0 +1,98 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Check Subcell Pins" "UICheckSubcellPins" ) + +( UICreateMenuItemCallBack + `UICheckSubcellPinsCB + (lambda () + let( (cellName bufferString) + CheckSubcellPinsFailedInstances=fjCheckSubcellPins( UIGetCellView()) + if( CheckSubcellPinsFailedInstances then + bufferString="" + foreach( cellName CheckSubcellPinsFailedInstances~>cellName + bufferString=sprintf( nil "%s%s\n" bufferString cellName) + ) + UICheckSubcellPins_Form->UICheckSubcellPins_Subcells->value= bufferString + hiDisplayForm( UICheckSubcellPins_Form ) + else printf("Success: All subcell labels have pins.\n") + ) + ) +) ) +( UICreateAction + 'UICheckSubcellPinsFormCB + (lambda () + (let (bufferString outPort inPort subcellCellView) + foreach( inst CheckSubcellPinsFailedInstances + subcellCellView=nrOpenCellViewWritable( inst~>master~>libName inst~>master~>cellName inst~>master~>viewName) + if( subcellCellView then + if( UICheckSubcellPins_Form->UICheckSubcellPins_AttachPins->value then + fxAttachPinShapes(subcellCellView)) + if( UICheckSubcellPins_Form->UICheckSubcellPins_SnapPowerGrid->value then + SnapM3PowerGrid(subcellCellView )) + dbSave( subcellCellView ) + else + printf("Error: unable to open %s %s(%s) for write.\n" inst~>master~>libName inst~>master~>cellName inst~>master~>viewName) + ) + ) + ) + ) +) +( UICreateComponent + "UICheckSubcellPins_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateMLTextField + ?name `UICheckSubcellPins_Subcells + ?prompt "Failed Subcells" + ?editable nil + ?defValue "" ) + ( hiCreateBooleanButton + ?name `UICheckSubcellPins_AttachPins + ?buttonText "Run Subcell Attach Pin Shapes" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICheckSubcellPins_SnapPowerGrid + ?buttonText "Run Snap M3 Power Grid" + ?defValue t ) + ( hiCreateButton + ?name `UICheckSubcellPins_OK + ?buttonText "Run on Above Subcells" + ?callback "hiFormDone(UICheckSubcellPins_Form)" + ) + ) ) ) + ( hiCreateAppForm + ?name `UICheckSubcellPins_Form + ?formTitle "Check Subcell Pins" + ?fields Fields + ?callback "( UICheckSubcellPinsFormCB )" + ) ) ) +) ) + + + + +defun( fjCheckSubcellPins ( CellView ) + let((uniqueInstances inst shape unconnectLabels failedInstances) + uniqueInstances=nil + foreach(inst CellView~>instances + if( inst~>libName!=TechLibName && !member( inst~>cellName uniqueInstances~>cellName) then + uniqueInstances=cons( inst uniqueInstances) + ) + ) + failedInstances=nil + foreach( inst uniqueInstances + unconnectLabels=setof( shape inst~>master~>shapes shape~>objType=="label" && shape~>parent==nil) + if( unconnectLabels then + printf( "Error: %s Labels not attached to pin layers: %L \n" inst~>cellName unconnectLabels~>theLabel ) + failedInstances=cons( inst failedInstances) + ) + ) + failedInstances + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkBaliToFiji.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkBaliToFiji.il new file mode 100644 index 0000000000..d9d4a54678 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkBaliToFiji.il @@ -0,0 +1,250 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Shrink Bali To Fiji" "UIShrinkBaliToFiji" ) + +( UICreateMenuItemCallBack + `UIShrinkBaliToFijiCB + (lambda () + let( (CellName LibName LibName130 ViewName130) + CellName= UIGetCellView()~>cellName + LibName= car( NameParseCellName( CellName ) ) + LibName130=strcat( "130" LibName ) + ViewName130=UIGetCellView()~>viewName + UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_CellName->value=UIGetCellView()~>cellName + UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_LibName65->value=LibName + UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_LibName130->value=LibName130 + UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_ViewName130->value=ViewName130 + hiDisplayForm( UIShrinkBaliToFiji_Form ) + ) +) ) + +( UICreateAction + 'UIShrinkBaliToFijiFormCB + (lambda () + (let ( ) + fjShrinkCellView( UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_CellName->value + ?LibName130 UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_LibName130->value + ?LibName65 UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_LibName65->value + ?ViewName130 UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_ViewName130->value + ?ViewName65 UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_ViewName65->value + ?ratio UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_Ratio->value + ?Grid UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_Grid->value + ?DeleteWires UIShrinkBaliToFiji_Form->UIShrinkBaliToFiji_DeleteWires->value + ) + ) + ) +) + +( UICreateComponent + "UIShrinkBaliToFiji_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIShrinkBaliToFiji_CellName + ?prompt "CellName" + ?defValue "" ) + ( hiCreateStringField + ?name `UIShrinkBaliToFiji_LibName130 + ?prompt "LibName 130n" + ?defValue "" ) + ( hiCreateStringField + ?name `UIShrinkBaliToFiji_ViewName130 + ?prompt "ViewName 130n" + ?defValue "" ) + ( hiCreateStringField + ?name `UIShrinkBaliToFiji_LibName65 + ?prompt "LibName 65n" + ?defValue "" ) + ( hiCreateStringField + ?name `UIShrinkBaliToFiji_ViewName65 + ?prompt "ViewName 65n" + ?defValue "shrink" ) + ( hiCreateFloatField + ?name `UIShrinkBaliToFiji_Ratio + ?prompt "Shrink Ratio" + ?defValue 0.6 ) + ( hiCreateFloatField + ?name `UIShrinkBaliToFiji_Grid + ?prompt "Snap To Grid" + ?defValue 0.005 ) + ( hiCreateBooleanButton + ?name `UIShrinkBaliToFiji_DeleteWires + ?buttonText "Delete Wires" + ?defValue t ) + ) ) ) + ( hiCreateAppForm + ?name `UIShrinkBaliToFiji_Form + ?formTitle "Go To Location" + ?fields Fields + ?callback "( UIShrinkBaliToFijiFormCB )" + ) ) ) +) ) + + +defun( fxSnapXToGrid (x Grid) + if( x floor(x/Grid+0.5)*Grid nil ) +) +defun( fxSnapPointToGrid (point Grid) + let((x) + foreach( mapcar x point fxSnapXToGrid( x Grid)) + ) +) +defun( fxSnapPointListToGrid (pointList Grid) + let((point) + foreach( mapcar point pointList fxSnapPointToGrid( point Grid)) + ) +) +defun( fxShrinkXToGrid (x ratio Grid) + if( x floor(x*ratio/Grid+0.5)*Grid nil ) +) + +defun( fxShrinkPointToGrid ( point ratio Grid) + let((x) + foreach( mapcar x point fxShrinkXToGrid( x ratio Grid)) + ) +) + +defun( fxShrinkPointListToGrid (pointList ratio Grid) + let((point) + foreach( mapcar point pointList fxShrinkPointToGrid( point ratio Grid)) + ) +) +defun( fxViaSize (bBox size + @key + (Grid 0.005) + ) + prog((x1 y1 x2 y2 x y) + x1=leftEdge(bBox) + x2=rightEdge(bBox) + y1=bottomEdge(bBox) + y2=topEdge(bBox) + if(abs(x1-y1)==size && abs(x2-y2)==size then return bBox) + x=fxSnapXToGrid((x1+x2)/2 Grid) + y=fxSnapXToGrid((y1+y2)/2 Grid) + return(list( x-size/2:y-size/2 x+size/2:y+size/2 )) + ) +) +defun( fxFixCellViewViaSize ( CellView ) + let((shape) + foreach( shape CellView~>shapes + if( shape~>purpose=="drawing" && shape~>objType=="rect" then + case( shape~>layerName + ("CO" + shape~>bBox=fxViaSize( shape~>bBox 0.09 ) + ) + ("VIA1" + shape~>bBox=fxViaSize( shape~>bBox 0.10 ) + ) + ("VIA2" + shape~>bBox=fxViaSize( shape~>bBox 0.10 ) + ) + ("VIA3" + shape~>bBox=fxViaSize( shape~>bBox 0.10 ) + ) + ("VIA4" + shape~>bBox=fxViaSize( shape~>bBox 0.10 ) + ) + ("VIA5" + shape~>bBox=fxViaSize( shape~>bBox 0.10 ) + ) + ("VIA6" + shape~>bBox=fxViaSize( shape~>bBox 0.10 ) + ) + ("VIA7" + shape~>bBox=fxViaSize( shape~>bBox 0.20 ) + ) + ("VIA8" + shape~>bBox=fxViaSize( shape~>bBox 0.20 ) + ) + ) + ) + ) + CellView + ) +) + +procedure( fjShrinkCellView( CellName + @key + (LibName65 "") + (LibName130 "") + (ViewName130 "layout") + (ViewName65 "shrink") + (ratio 0.6) + (Grid 0.005) + (DeleteWires nil) + ) + let((DFIIDir CellView130 CellView65 inst shape temp) + if( LibName65=="" then LibName65=car( NameParseCellName( CellName ) )) + DFIIDir=ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + GDSIIHierMakeLibrary( LibName65 DFIIDir "tsmc65" ) + if( LibName130=="" then LibName130=strcat( "130" LibName65 )) + CellView130=nrOpenCellViewReadable( LibName130 CellName ViewName130 ) + if( CellView130 == nil then + printf("Error: Unable to open CellView %s %s(%s) for read." LibName130 CellName ViewName130) + return() + ) + CellView65=dbCopyCellView( CellView130 LibName65 CellName ViewName65 nil nil t) + if( CellView65 == nil then + printf("Error: Unable %s %s(%s) for write" LibName130 CellName ViewName130) + return() + ) + foreach(inst CellView65~>instances + if( inst~>libName=="tsmc13lg" then + if( DeleteWires then dbDeleteObject(inst) + else dbFlattenInst( inst 32 t t t)) + ) + ) + dbSave(CellView65) + foreach(inst CellView65~>instances + inst~>xy=fxShrinkPointToGrid(inst~>xy ratio Grid) + if( temp=nrOpenCellViewReadable( inst~>libName inst~>cellName "shrink" ) then + inst~>master=temp + else printf("Error: %s %s (shrink or layout) view not found" inst~>libName inst~>cellName) + ) + ) + if( DeleteWires then + foreach( shape CellView65~>shapes +; if(shape~>objType!="label" && shape~>purpose!="pin" then + if(shape~>objType!="label" && shape~>layerName!="prBoundary" && shape~>pin==nil then + dbDeleteObject(shape) + ) + ) + ) + dbSave(CellView65) + foreach( shape CellView65~>shapes + case( shape~>objType + ("rect" + shape~>bBox=fxShrinkPointListToGrid(shape~>bBox ratio 0.01) + ) + ("polygon" + shape~>points=fxShrinkPointListToGrid(shape~>points ratio Grid) + ) + ("path" + shape~>points=fxShrinkPointListToGrid(shape~>points ratio Grid) + shape~>width=fxShrinkXToGrid( shape~>width ratio 0.01) + shape~>beginExt=fxShrinkXToGrid( shape~>beginExt ratio Grid) + shape~>endExt=fxShrinkXToGrid( shape~>endExt ratio Grid) + ) + ("label" + shape~>xy=fxShrinkPointToGrid(shape~>xy ratio Grid) + shape~>height=0.06 + ) + ("dot" + shape~>xy=fxShrinkPointToGrid(shape~>xy ratio Grid) + ) + ( t + printf("Error: unknown objType %s \n" shape~>objType) + ) + ) + ) + fxFixCellViewViaSize( CellView65 ) + dbSave(CellView65) + CellView65 + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkPrelayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkPrelayout.il new file mode 100755 index 0000000000..b27ea43447 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/ShrinkPrelayout.il @@ -0,0 +1,215 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Shrink Bali To Fiji Prelayout" "UIShrinkPrelayout" ) + +( UICreateMenuItemCallBack + `UIShrinkPrelayoutCB + (lambda () + let( (CellName LibName LibName130 ViewName130) + CellName= UIGetCellView()~>cellName + LibName= car( NameParseCellName( CellName ) ) + LibName130=strcat( "130" LibName ) + ViewName130=UIGetCellView()~>viewName + UIShrinkPrelayout_Form->UIShrinkPrelayout_CellName->value=UIGetCellView()~>cellName + UIShrinkPrelayout_Form->UIShrinkPrelayout_LibName65->value=LibName + UIShrinkPrelayout_Form->UIShrinkPrelayout_LibName130->value=LibName130 + hiDisplayForm( UIShrinkPrelayout_Form ) + ) +) ) + +( UICreateAction + 'UIShrinkPrelayoutFormCB + (lambda () + (let ( ) + ProcessedCellList=nil + fjShrinkPrelayout( UIShrinkPrelayout_Form->UIShrinkPrelayout_CellName->value + ?LibName130 UIShrinkPrelayout_Form->UIShrinkPrelayout_LibName130->value + ?LibName65 UIShrinkPrelayout_Form->UIShrinkPrelayout_LibName65->value + ?ViewName130 UIShrinkPrelayout_Form->UIShrinkPrelayout_ViewName130->value + ?ViewName65 UIShrinkPrelayout_Form->UIShrinkPrelayout_ViewName65->value + ?ratio UIShrinkPrelayout_Form->UIShrinkPrelayout_Ratio->value + ?Grid UIShrinkPrelayout_Form->UIShrinkPrelayout_Grid->value + ?DeleteWires UIShrinkPrelayout_Form->UIShrinkPrelayout_DeleteWires->value + ?OverwritePrelayout UIShrinkPrelayout_Form->UIShrinkPrelayout_OverwritePrelayout->value + ) + ) + ) +) + +( UICreateComponent + "UIShrinkPrelayout_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIShrinkPrelayout_CellName + ?prompt "CellName" + ?defValue "" ) + ( hiCreateStringField + ?name `UIShrinkPrelayout_LibName130 + ?prompt "LibName 130n" + ?defValue "" ) + ( hiCreateStringField + ?name `UIShrinkPrelayout_ViewName130 + ?prompt "ViewName 130n" + ?defValue "prelayout" ) + ( hiCreateStringField + ?name `UIShrinkPrelayout_LibName65 + ?prompt "LibName 65n" + ?defValue "" ) + ( hiCreateStringField + ?name `UIShrinkPrelayout_ViewName65 + ?prompt "ViewName 65n" + ?defValue "prelayout" ) + ( hiCreateFloatField + ?name `UIShrinkPrelayout_Ratio + ?prompt "Shrink Ratio" + ?defValue 0.6 ) + ( hiCreateFloatField + ?name `UIShrinkPrelayout_Grid + ?prompt "Snap To Grid" + ?defValue 0.005 ) + ( hiCreateBooleanButton + ?name `UIShrinkPrelayout_DeleteWires + ?buttonText "Delete Wires" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIShrinkPrelayout_OverwritePrelayout + ?buttonText "Overwrite Existing Prelayout" + ?defValue t ) + ) ) ) + ( hiCreateAppForm + ?name `UIShrinkPrelayout_Form + ?formTitle "Go To Location" + ?fields Fields + ?callback "( UIShrinkPrelayoutFormCB )" + ) ) ) +) ) + + +defun( fjShrinkPrelayout ( CellName + @key + (LibName65 "") + (LibName130 "") + (ViewName130 "prelayout") + (ViewName65 "prelayout") + (ratio 0.6) + (Grid 0.005) + (DeleteWires t) + (OverwritePrelayout t) + ) + let((temp CellView130 CellView65 DFIIDir) + + if( LibName65=="" then LibName65=car( NameParseCellName( CellName ) )) + DFIIDir=ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + GDSIIHierMakeLibrary( LibName65 DFIIDir "tsmc65" ) + if( LibName130=="" then LibName130=strcat( "130" LibName65 )) + if( nrOpenCellViewWritable( LibName65 CellName ViewName65 )==nil then + printf("Prelayout %s %s(%s) was not writable, ignore OverwritePrelayout.\n" + LibName65 CellName ViewName65) + CellView65=nrOpenCellViewReadable( LibName65 CellName ViewName65 ) + ProcessedCellList=cons( CellView65 ProcessedCellList) + ) + + if( member( CellName ProcessedCellList~>cellName ) then + CellView65=car(setof( temp ProcessedCellList temp~>cellName==CellName )) + else + printf("Processing %s ...\n" CellName ) + CellView130=nrOpenCellViewReadable( LibName130 CellName ViewName130 ) + if( CellView130 == nil then + printf("Unable to open CellView %s %s(%s) for read." LibName130 CellName ViewName130) + ) + CellView65=dbCopyCellView( CellView130 LibName65 CellName ViewName65 nil nil t) + if( CellView65 == nil then + printf("Unable %s %s(%s) for write" LibName130 CellName ViewName130) + ) + foreach(inst CellView65~>instances + if( inst~>libName=="tsmc13lg" then + if( DeleteWires then dbDeleteObject(inst) + else dbFlattenInst( inst 32 t t t)) + ) + ) + dbSave(CellView65) + if( DeleteWires then + foreach( shape CellView65~>shapes + if(shape~>objType!="label" && shape~>layerName!="prBoundary" && shape~>pin==nil then + dbDeleteObject(shape) + ) + ) + foreach( inst cadr( NameFilterInstances( CellView65~>instances WiringCellLibCellPairRegExs )) + dbDeleteObject(inst) + ) + ) + dbSave(CellView65) + foreach( shape CellView65~>shapes + case( shape~>objType + ("rect" + shape~>bBox=fxShrinkPointListToGrid(shape~>bBox ratio 0.01) + ) + ("polygon" + shape~>points=fxShrinkPointListToGrid(shape~>points ratio Grid) + ) + ("path" + shape~>points=fxShrinkPointListToGrid(shape~>points ratio Grid) + shape~>width=fxShrinkXToGrid( shape~>width ratio 0.01) + shape~>beginExt=fxShrinkXToGrid( shape~>beginExt ratio Grid) + shape~>endExt=fxShrinkXToGrid( shape~>endExt ratio Grid) + ) + ("label" + shape~>xy=fxShrinkPointToGrid(shape~>xy ratio Grid) + shape~>height=0.06 + ) + ("dot" + shape~>xy=fxShrinkPointToGrid(shape~>xy ratio Grid) + ) + ( t + printf("Warning: unknown objType %s \n" shape~>objType) + ) + ) + ) + fxFixCellViewViaSize( CellView65 ) + foreach(inst CellView65~>instances + inst~>xy=fxShrinkPointToGrid(inst~>xy ratio Grid) + cond( + ( temp=nrOpenCellViewReadable( inst~>libName inst~>cellName "prelayout" ) + if( OverwritePrelayout then temp=fjShrinkPrelayout( inst~>cellName + ?LibName65 "" + ?LibName130 "" + ?ViewName130 ViewName130 + ?ViewName65 ViewName65 + ?ratio ratio + ?Grid Grid + ?DeleteWires DeleteWires + ?OverwritePrelayout OverwritePrelayout + ) + ) + inst~>master=temp ) + ( temp=nrOpenCellViewReadable( inst~>libName inst~>cellName "layout" ) + inst~>master=temp ) + ( temp=nrOpenCellViewReadable( inst~>libName inst~>cellName "shrink" ) + inst~>master=temp ) + ( t temp=fjShrinkPrelayout( inst~>cellName + ?LibName65 "" + ?LibName130 "" + ?ViewName130 ViewName130 + ?ViewName65 ViewName65 + ?ratio ratio + ?Grid Grid + ?DeleteWires DeleteWires + ?OverwritePrelayout OverwritePrelayout + ) + inst~>master=temp ) + ) + ) + dbSave(CellView65) + ProcessedCellList=cons( CellView65 ProcessedCellList) + ) + CellView65 + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/SnapPowerGrid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/SnapPowerGrid.il new file mode 100644 index 0000000000..111d1a8c58 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fiji/SnapPowerGrid.il @@ -0,0 +1,64 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Snap Leaf M3 Power Grid" "UISnapPowerGrid" ) + +( UICreateMenuItemCallBack + `UISnapPowerGridCB + (lambda () + let( (CellView) + CellView= UIGetCellView() + if( nrOpenCellViewWritable(CellView~>libName CellView~>cellName CellView~>viewName) then + SnapM3PowerGrid( CellView ) + else + printf("Unable to open CellView for write.\n") + ) + ) +) ) + + +defun( SnapM3PowerGrid ( CellView ) + let((n lpp prbound shape w1 w2 h1 h2 x1 x2 y1 y2 m3power m3shape m3label move) + prbound=car( car( setof( lpp CellView~>lpps lpp~>layerName=="prBoundary"))~>shapes) + w1=leftEdge(prbound~>bBox) + w2=rightEdge(prbound~>bBox) + heigth=topEdge(prbound~>bBox) + for( n 0 floor(heigth/2.88) + h1=n*2.88-0.18 h2=n*2.88+0.18 + bBox=list(w1:h1 w2:h2) + m3power=dbGetOverlaps( CellView bBox Metal3LPP) + m3label=car(setof( shape m3power shape~>objType=="label" )) + m3shape=setof( shape m3power shape~>objType!="label" ) + if( length(m3shape)==1 then + shape=car(m3shape) + x1=leftEdge(shape~>bBox) + x2=rightEdge(shape~>bBox) + y1=bottomEdge(shape~>bBox) + y2=topEdge(shape~>bBox) + move=h1-y1 + if( abs(h1-y1)1e-6 || abs(x2-w2)>1e-6 || abs(y1-h1)>1e-6 || abs(y2-h2)>1e-6 then + if( shape~>objType=="rect" then + via2shape=dbGetOverlaps( CellView shape~>bBox Via23LPP ) + shape~>bBox=bBox + else + via2shape=dbGetOverlaps( CellView bBox Via23LPP ) + dbMoveFig( shape CellView list( list(0 move) "R0"))) + printf("M3 Power Grid moved to: %L\n" bBox) + foreach( shape via2shape dbMoveFig( shape CellView list( list(0 move) "R0"))) + if( m3label then m3label~>xy=list((w1+w2)/2.0 (h1+h2)/2.0) ) + ) + if(n == floor(n/2)*2 then net=dbMakeNet( CellView "GND" ) + else net=dbMakeNet( CellView "Vdd" )) + dbCreatePin( net car(m3shape)) + ) + if( length(m3shape)>1 then + printf("Error: Power Grid %L can not be created from multiple overlapping m3 shapes: %L\n" bBox m3shape~>bBox) + ) + + ) + + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fill.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fill.il new file mode 100644 index 0000000000..071e2a18a4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Fill.il @@ -0,0 +1,47 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Fill with metal" "UIFillMetal" ) + + +( UICreateMenuItemCallBack + `UIFillMetalCB + (lambda () + hiDisplayForm( UIFillMetal_Form ) + ) +) + +( UICreateAction + 'UIFillMetalFormCB + (lambda () + (let ( CellView Msg p) + CellView=UIGetCellView() + Fill( CellView ?Type "grid" ?Layers if( UIFillMetal_Form->UIFillMetal_Layers->value=="M2 to M7" t nil)) + ) + ) +) + +( UICreateComponent + "UIFillMetal_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateRadioField + ?name `UIFillMetal_Layers + ?prompt "Layers" + ?choices list( "OD to M2" "M2 to M7") + ?defValue "M2 to M7" ) + ) ) ) + ( hiCreateAppForm + ?name `UIFillMetal_Form + ?formTitle "Fill Metal" + ?fields Fields + ?callback "( UIFillMetalFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/FillSpareGate.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/FillSpareGate.il new file mode 100644 index 0000000000..1cfc796978 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/FillSpareGate.il @@ -0,0 +1,138 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Fill Spare Gate & Metal" "UIFillSpareGate" ) + + +( UICreateMenuItemCallBack + `UIFillSpareGateCB + (lambda () + let((cellView cellBase cellSubType) + cellView = UIGetCellView() + when( cellView + cellBase = cadr( reverse( parseString( cellView->cellName "." ) )) + cellSubtype = car( reverse( parseString( cellView->cellName "." ) )) + UIFillSpareGate_Form->UIFillSpareGate_FillCellName->value = + strcat( cellView->libName ".wires." cellBase "_" cellSubtype "_fill") + ) + hiDisplayForm( UIFillSpareGate_Form ) + ) + ) +) + +( UICreateAction + 'UIFillSpareGateFormCB + (lambda () + (let ( CellView Msg p ) + CellView=UIGetCellView() + if(AutoSpareCell( CellView UIFillSpareGate_Form->UIFillSpareGate_FillCellName->value + ?fillViewName "layout" + ?PowerGridSize 5.76 + ?FillWithSpareCell UIFillSpareGate_Form->UIFillSpareGate_ODM2Fill->value=="spare gates" + ?FillWithDcapCell UIFillSpareGate_Form->UIFillSpareGate_ODM2Fill->value=="DCAP" + ?FillWithM2M7 UIFillSpareGate_Form->UIFillSpareGate_M2M7Fill->value=="M2M7" + ?SpareCellLibName UIFillSpareGate_Form->UIFillSpareGate_SpareCellLibName->value + ?LargeSpareCellName UIFillSpareGate_Form->UIFillSpareGate_LargeSpareCellName->value + ?SmallSpareCellName UIFillSpareGate_Form->UIFillSpareGate_SmallSpareCellName->value + ?LargeSpaceCellGridX 3 + ?LargeSpaceCellGridY 4 + ?FillCellLibName UIFillSpareGate_Form->UIFillSpareGate_FillCellLibName->value + ?DcapFillCellName UIFillSpareGate_Form->UIFillSpareGate_DcapCellName->value + ?ODPOM1FillCellName UIFillSpareGate_Form->UIFillSpareGate_ODPOM1CellName->value + ?ODM1FillCellName UIFillSpareGate_Form->UIFillSpareGate_ODM1CellName->value + ?ODPOFillCellName UIFillSpareGate_Form->UIFillSpareGate_ODPOCellName->value + ?ODSMALLFillCellName UIFillSpareGate_Form->UIFillSpareGate_ODSMALLCellName->value + ?M2FillCellName "globals.fill.M2" + ?M3FillCellName "globals.fill.M3" + ?M4FillCellName "globals.fill.M4" + ?M5FillCellName "globals.fill.M5" + ?M6FillCellName "globals.fill.M6" + ?M7FillCellName "globals.fill.M7" + ?M23FillCellName "globals.fill.M23" + ?M34FillCellName "globals.fill.M34" + ?M45FillCellName "globals.fill.M45" + ?M56FillCellName "globals.fill.M56" + ?M67FillCellName "globals.fill.M67" + ?LeaveMess UIFillSpareGate_Form->UIFillSpareGate_Debug->value + ) + dbCreateInstByMasterName( CellView CellView~>libName + UIFillSpareGate_Form->UIFillSpareGate_FillCellName->value + "layout" "fill" (list 0 0) "R0") + ) + ) + ) +) + +( UICreateComponent + "UIFillSpareGate_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIFillSpareGate_FillCellName + ?prompt "Fill Cell Name" + ?defValue "fill" ) + ( hiCreateRadioField + ?name `UIFillSpareGate_ODM2Fill + ?prompt "Fill OD to M2 with" + ?choices list( "DCAP" "spare gates" "none") + ?defValue "DCAP" ) + ( hiCreateRadioField + ?name `UIFillSpareGate_M2M7Fill + ?prompt "Fill M2 to M7 with" + ?choices list( "M2M7" "none" ) + ?defValue "M2M7" ) + ( hiCreateStringField + ?name `UIFillSpareGate_SpareCellLibName + ?prompt "Spare Cell Lib Name" + ?defValue "lib.util.spare" ) + ( hiCreateStringField + ?name `UIFillSpareGate_LargeSpareCellName + ?prompt "Large Spare Cell Name" + ?defValue "lib.util.spare.LARGE_SPARE_GATES.1000" ) + ( hiCreateStringField + ?name `UIFillSpareGate_SmallSpareCellName + ?prompt "Small Spare Cell Name" + ?defValue "lib.util.spare.SMALL_SPARE_GATES.1000" ) + ( hiCreateStringField + ?name `UIFillSpareGate_FillCellLibName + ?prompt "Fill Cell Lib Name" + ?defValue "globals" ) + ( hiCreateStringField + ?name `UIFillSpareGate_DcapCellName + ?prompt "DCAP Cell Name" + ?defValue "globals.fill.DCAP" ) + ( hiCreateStringField + ?name `UIFillSpareGate_ODPOM1CellName + ?prompt "ODPOM1 Cell Name" + ?defValue "globals.fill.ODPOM1" ) + ( hiCreateStringField + ?name `UIFillSpareGate_ODM1CellName + ?prompt "ODM1 Cell Name" + ?defValue "globals.fill.ODM1" ) + ( hiCreateStringField + ?name `UIFillSpareGate_ODPOCellName + ?prompt "ODPO Cell Name" + ?defValue "globals.fill.ODPO" ) + ( hiCreateStringField + ?name `UIFillSpareGate_ODSMALLCellName + ?prompt "OD SMALL Cell Name" + ?defValue "globals.fill.OD_SMALL" ) + ( hiCreateBooleanButton + ?name `UIFillSpareGate_Debug + ?buttonText "Debug (leave Assura Run)" + ?defValue nil ) + ) ) ) + ( hiCreateAppForm + ?name `UIFillSpareGate_Form + ?formTitle "Fill Spare Gate & Metal" + ?fields Fields + ?callback "( UIFillSpareGateFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetCellArea.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetCellArea.il new file mode 100644 index 0000000000..224bcca01e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetCellArea.il @@ -0,0 +1,11 @@ +( list "Get Cell Area" "UIGetCellArea" ) + +( UICreateMenuItemCallBack + `UIGetCellAreaCB + (lambda () + (let (area) + area=(GetCellArea (geGetWindowCellView)) + (printf "%s -- %3.3fmm^2\n" (geGetWindowCellView)~>cellName area/1000000) + ) +)) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetFigArea.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetFigArea.il new file mode 100644 index 0000000000..32cb81f355 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GetFigArea.il @@ -0,0 +1,17 @@ +( list "Get Selected Fig Area" "UIGetFigArea" ) + +( UICreateMenuItemCallBack + `UIGetFigAreaCB + (lambda () + (let (area fig) + fig = car(geGetSelectedSet()) + area=GetFigArea(fig) + if( fig~>objType == "inst" + then + (printf "%s -- %3.3fmm^2\n" fig~>cellName area/1000000) + else + (printf "Selected Fig Area -- %3.3fmm^2\n" area/1000000) + ) + ) +)) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GoTo.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GoTo.il new file mode 100755 index 0000000000..2d5e0a0a7b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/GoTo.il @@ -0,0 +1,88 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "Go To Location" "UIGoToLocation" ) + +( UICreateMenuItemCallBack + `UIGoToLocationCB + (lambda () + ( hiDisplayForm UIGoToLocation_Form ) ) ) + +; create common function +(defun GoToLocation ( x y zoom ) + (let ( winId ) + winID=hiGetCurrentWindow() + hiZoomAbsoluteScale(winID zoom) + hiPan(winID x:y) + ) +) + +; function to parse hdrc string +(defun HdrcGoToLocation ( string zoom ) + (let ( x y strings ) + x=0.0 + y=0.0 + strings=parseString( string " (,)" ) + x=(evalstring(nth(1 strings))+evalstring(nth(3 strings)))/2 + y=(evalstring(nth(2 strings))+evalstring(nth(4 strings)))/2 + GoToLocation( x y zoom) + ) +) + +; callback for he Go To Location dialog with added HDRC +( UICreateAction + 'UIGoToLocationFormCB + (lambda () + (let ( winID x y hdrc s) + hdrc=UIGoToLocation_Form->UIGoToLocation_Form_HDRC->value + s=parseString( hdrc " (,)" ) + if( length(s) < 4 then + x=evalstring(UIGoToLocation_Form->UIGoToLocation_Form_X->value) + y=evalstring(UIGoToLocation_Form->UIGoToLocation_Form_Y->value) + GoToLocation( x y UIGoToLocation_Form->UIGoToLocation_Form_Zoom->value) + else + UIGoToLocation_Form->UIGoToLocation_Form_X->value=sprintf(nil "%.3f" (evalstring(nth(1 s))+evalstring(nth(3 s)))/2) + UIGoToLocation_Form->UIGoToLocation_Form_Y->value=sprintf(nil "%.3f" (evalstring(nth(2 s))+evalstring(nth(4 s)))/2) + HdrcGoToLocation( hdrc UIGoToLocation_Form->UIGoToLocation_Form_Zoom->value) + ) + ) + ) +) + +( UICreateComponent + "UIGoToLocation_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIGoToLocation_Form_X + ?prompt "x" + ?editable t + ?defValue "0" ) + ( hiCreateStringField + ?name `UIGoToLocation_Form_Y + ?prompt "y" + ?editable t + ?defValue "0" ) + ( hiCreateFloatField + ?name `UIGoToLocation_Form_Zoom + ?prompt "zoom" + ?defValue 2000.0 ) + ( hiCreateStringField + ?name `UIGoToLocation_Form_HDRC + ?prompt "hdrc string" + ?editable t + ?defValue "" ) + ) ) ) + ( hiCreateAppForm + ?name `UIGoToLocation_Form + ?formTitle "Go To Location" + ?fields Fields + ?callback "( UIGoToLocationFormCB )" + ) ) ) + ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/.menu new file mode 100644 index 0000000000..0ebf8ca1ee --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/.menu @@ -0,0 +1 @@ +( list "Hand Layout" "UIHandLayout" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/DeleteNotHand.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/DeleteNotHand.il new file mode 100644 index 0000000000..fbeed9789a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/DeleteNotHand.il @@ -0,0 +1,16 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + + +( list "Delete All Objects Not Hand Layout" "UIDeleteNotHand" ) + + +( UICreateMenuItemCallBack + `UIDeleteNotHandCB + (lambda () + (DeleteObjectsNotHandLayout) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandAll.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandAll.il new file mode 100644 index 0000000000..1bca347a13 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandAll.il @@ -0,0 +1,16 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + + +( list "Set Prop on All Objects" "UISetHandAll" ) + + +( UICreateMenuItemCallBack + `UISetHandAllCB + (lambda () + (SetHandLayoutAllObjects) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandSelected.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandSelected.il new file mode 100644 index 0000000000..86180f564a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/SetHandSelected.il @@ -0,0 +1,16 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + + +( list "Set Prop on Selected Objects Ctrl-h" "UISetHandSelected" ) + + +( UICreateMenuItemCallBack + `UISetHandSelectedCB + (lambda () + (SetHandLayoutSelectedObjects) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/Struts.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/Struts.il new file mode 100644 index 0000000000..fe6472c316 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/HandLayout/Struts.il @@ -0,0 +1,94 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Struts" "UIStruts" ) + +( UICreateMenuItemCallBack + `UIStrutsCB + (lambda () + ( hiDisplayForm UIStruts_Form ) ) ) + + +( UICreateAction + 'UIStruts_FormCB + (lambda () nil ) ) + +( UICreateAction + 'UIDrawVStrutsCB + (lambda () + (VStrutsDrawStruts + UIStruts_Form->UIStruts_Form_GND->value + UIStruts_Form->UIStruts_Form_Vdd->value + UIStruts_Form->UIStruts_Form_Extent->value) +) ) + + +( UICreateAction + 'UIDrop12ContactsCB + (lambda () + (VStrutsDropM12Vias + UIStruts_Form->UIStruts_Form_GND->value + UIStruts_Form->UIStruts_Form_Vdd->value + UIStruts_Form->UIStruts_Form_Extent->value) + )) + +( UICreateAction + 'UIDrop23ContactsCB + (lambda () + (VStrutsDropM23Vias + UIStruts_Form->UIStruts_Form_GND->value + UIStruts_Form->UIStruts_Form_Vdd->value ) + )) + +( UICreateAction + 'UIDeleteObjectsCB + (lambda () + (VStrutsDeleteObjects) + )) + + +( UICreateComponent + "UIStruts_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIStruts_Form_GND + ?buttonText "GND" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIStruts_Form_Vdd + ?buttonText "Vdd" + ?defValue t ) + ( hiCreateCyclicField + ?name `UIStruts_Form_Extent + ?prompt "Which Instances" + ?choices ( list "All" "Selected" ) ) + ( hiCreateButton + ?name `UIStruts_Form_DrawVStruts + ?buttonText "Draw VStruts" + ?callback "( UIDrawVStrutsCB )" ) + ( hiCreateButton + ?name `UIStruts_Form_Drop12Contacts + ?buttonText "Drop M12 Contacts" + ?callback "( UIDrop12ContactsCB )" ) + ( hiCreateButton + ?name `UIStruts_Form_Drop23Contacts + ?buttonText "Drop M23 Contacts" + ?callback "( UIDrop23ContactsCB )" ) + ( hiCreateButton + ?name `UIStruts_Form_DeleteObjects + ?buttonText "Delete All" + ?callback "( UIDeleteObjectsCB )" ) + ) ) ) + ( hiCreateAppForm + ?name `UIStruts_Form + ?formTitle "Struts" + ?fields Fields + ?callback "( UIStruts_FormCB )" + ) ) ) + ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/.menu new file mode 100644 index 0000000000..0e039ea820 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/.menu @@ -0,0 +1 @@ +( list "Hierarchy" "UIHierarchy" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Inline.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Inline.il new file mode 100644 index 0000000000..737836ea5c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Inline.il @@ -0,0 +1,69 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +( list "Inline" "UIInline" ) + +( UICreateMenuItemCallBack + `UIInlineCB + (lambda () + + UIInline_Form->UIInline_Form_ConnectivityViewName->value = + ( getq ( UIGetCellView ) viewName ) + + ( hiDisplayForm UIInline_Form ) ) ) + +( UICreateAction + 'UIInlineFormCB + (lambda () + (let ( + ( SelectedInstances + ( setof Obj ( geGetSelectedSet ) ( equal ( getq Obj objType ) "inst" ) ) ) ) + ( InlineInstances + ( UIGetCellView ) + ( UIGetCellView ) + SelectedInstances + UIInline_Form->UIInline_Form_ConnectivityViewName->value + UIInline_Form->UIInline_Form_UpdateConnectivityCellView->value + FoldableCellLibCellPairRegExs + SuperStackLibCellPairRegExs + ?Verbose UIInline_Form->UIInline_Form_Verbose->value + ?CopyPins UIInline_Form->UIInline_Form_CopyPins->value + ) ) ) ) + +( UICreateComponent + "UIInline_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIInline_Form_ConnectivityViewName + ?prompt "Connectivity View Name" + ?defValue "" ) + ( hiCreateBooleanButton + ?name `UIInline_Form_UpdateConnectivityCellView + ?buttonText "Update Connectivity CellView" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIInline_Form_Verbose + ?buttonText "Verbose" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIInline_Form_CopyPins + ?buttonText "Copy Pins" + ?defValue nil ) + + ) ) ) + ( hiCreateAppForm + ?name `UIInline_Form + ?formTitle "Inline" + ?fields Fields + ?callback "( UIInlineFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Instanciators.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Instanciators.il new file mode 100644 index 0000000000..8c4bae0105 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/Instanciators.il @@ -0,0 +1,131 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Get Instantiators" "UIGetInstantiators" ) + +;(when ( geqp ( atoi ( VersionGetMajorVersion ) ) 5.0 ) +(when t + ( UICreateMenuItemCallBack + `UIGetInstantiatorsCB + (lambda () + ( hiDisplayForm UIGetInstantiators_Form ) ) ) + + ( UICreateComponent + "UIGetInstantiators_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list, + ( list + ( hiCreateListBoxField + ?name `UIGetInstantiators_Instantiators + ?prompt "Instantiators" ) + ( list + 0 0 ) + ( list + 500 500 ) + 100 ) + ( list ( hiCreateButton + ?name `UIGetInstantiators_Refresh + ?buttonText "Refresh" + ?callback "( UIGetInstantiatorsFormMapCB )" + ) + ( list 0 20 ) + ( list 100 20 ) + 100 ) + ) ) ) + ( defvar UICellsInstantiatorsTable nil ) + ( hiCreateAppForm + ?name `UIGetInstantiators_Form + ?formTitle "Instantiators" + ?fields Fields + ?attachmentList ( list + ( bor + hicTopPositionSet + hicLeftPositionSet + hicRightPercentSet + hicBottomPercentSet ) + ( bor + hicTopPositionSet + hicLeftPositionSet + hicRightPercentSet + hicBottomPercentSet ) + ) + ?initialSize ( list 500 500 ) + ?callback "( UIGetInstantiatorsFormCB )" + ?mapCB "( UIGetInstantiatorsFormMapCB )" ) ) ) ) ) + + ( UICreateAction + `UIGetInstantiatorsFormCB + (lambda () + (let ( + ( CellNameToOpen ( car + ( getq + ( getq + UIGetInstantiators_Form + UIGetInstantiators_Instantiators ) + value ) ) ) ) + (let ( + ( CurrCellView ( geGetWindowCellView ) ) + ( LibCellPair ( NameParseCellName CellNameToOpen ) ) ) + (let ( + ( DEOpenParam ( list + nil + 'libName ( car LibCellPair ) + 'cellName ( cadr LibCellPair ) + 'viewName "floorplan" ) ) ) + ( deOpen DEOpenParam nil "r" ) + (let ( + ( OpenedCellView ( geGetWindowCellView ) ) ) + ( geDeselectAll ) + ( foreach + Instance + ( getq OpenedCellView instances ) + (when ( and + ( equal + ( getq Instance cellName ) + ( getq CurrCellView cellName ) ) + ( equal + ( getq Instance libName ) + ( getq CurrCellView libName ) ) ) + ( geSelectObject Instance ) ) ) ) ) ) ) ) ) + + ( UICreateAction + `UIGetInstantiatorsFormMapCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + ( hiChangeFormTitle + UIGetInstantiators_Form + ( sprintf + nil + "Instantiators of %s" + ( getq CellView cellName ) ) ) + ( putpropq + ( getq + UIGetInstantiators_Form + UIGetInstantiators_Instantiators ) + ( sprintf + nil + "Instantiators of %s" + ( getq CellView cellName ) ) + prompt ) + (unless UICellsInstantiatorsTable + ( setq UICellsInstantiatorsTable + ( HierarchyMakeCellsInstantiatorsTable + "floorplan" + "floorplan" + nil ) ) ) + ( putpropq + ( getq + UIGetInstantiators_Form + UIGetInstantiators_Instantiators ) + ( HierarchyGetInstantiatorsOfCell + UICellsInstantiatorsTable + ( getq CellView cellName ) ) + choices ) ) ) ) + +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReplaceSubcells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReplaceSubcells.il new file mode 100644 index 0000000000..08c6e61aab --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReplaceSubcells.il @@ -0,0 +1,50 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReplaceSubcells.il#1 $ +; $DateTime: 2005/11/07 15:21:21 $ +; $Author: stevemc $ + + +( list "Recursively Replace Subcell Views" "UIReplaceSubcells" ) + +( UICreateMenuItemCallBack + `UIReplaceSubcellsCB + (lambda () + ( hiDisplayForm UIReplaceSubcells_Form ) ) +) + +( UICreateAction + 'UIReplaceSubcellsFormCB + (lambda () + ( RecursiveReplaceSubcells + ( UIReplaceSubcells_Form->UIReplaceSubcells_Form_FromViewName->value ) + ( UIReplaceSubcells_Form->UIReplaceSubcells_Form_ToViewName->value ) + ) ) +) + + +( UICreateComponent + "UIReplaceSubcells_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIReplaceSubcells_Form_FromViewName + ?prompt "From View Name" + ?defValue "floorplan" ) + ( hiCreateStringField + ?name `UIReplaceSubcells_Form_ToViewName + ?prompt "To View Name" + ?defValue "layout" ) + ) ) ) + ( hiCreateAppForm + ?name `UIReplaceSubcells_Form + ?formTitle "Replace Subcells" + ?fields Fields + ?callback "( UIReplaceSubcellsFormCB )" + ) ) ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReportInstances.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReportInstances.il new file mode 100644 index 0000000000..2ad2dc5b93 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Hierarchy/ReportInstances.il @@ -0,0 +1,16 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + + +( list "Report Instances" "UIReportInstances" ) + + +( UICreateMenuItemCallBack + `UIReportInstancesCB + (lambda () + (ReportInstances) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/.menu new file mode 100644 index 0000000000..9ef4ea1390 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/.menu @@ -0,0 +1 @@ +( list "'Leaf Layout'" "UILeafLayout" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/Clean.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/Clean.il new file mode 100644 index 0000000000..79019863d6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/Clean.il @@ -0,0 +1,300 @@ + +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Clean.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + +( list "11. RouteClean" "UILeafRouteClean" ) + +( UICreateMenuItemCallBack + `UILeafRouteCleanCB + (lambda () + ( hiDisplayForm UILeafRouteClean_Form ) ) ) + +( UICreateAction + 'UIRouteCleanFormCB + (lambda () + (let ( left bottom right top + ( CellView ( UIGetCellView ) ) + ( DirectiveTable + ( CellInfoGetTableForCellName + "null" + ( sprintf + nil + "%s/share/Fulcrum" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ) ) + + ( Area + (when UILeafRouteClean_Form->UIRouteClean_Form_Area->value + ( enterBox ?prompts ( list "Select area to clean" ) ) ) ) + ) + left=round(caar(GetPrbound(CellView)->bBox)*1000) + bottom=round(cadar(GetPrbound(CellView)->bBox)*1000) + right=round(caadr(GetPrbound(CellView)->bBox)*1000) + top=round(cadadr(GetPrbound(CellView)->bBox)*1000) + dbCreateRect(CellView BoundaryLPP list(left/1000.0:bottom/1000.0 right/1000.0:top/1000.0)) + (cond ( + ( PinUtilFindPRBoundShape BoundaryLPP CellView ) + (let ( + ( MetalLPPs + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Metal1->value + ( list Metal1LPP ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Metal2->value + ( list Metal2LPP ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Metal3->value + ( list Metal3LPP ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Metal4->value + ( list Metal4LPP ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Metal5->value + ( list Metal5LPP ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Metal6->value + ( list Metal6LPP ) ) + (if UILeafRouteClean_Form->UIRouteClean_Form_Metal7->value + ( list Metal7LPP ) ) ) ) ) ) ) ) ) ) + + +; (when UIRouteClean_Form->UIRouteClean_Form_OnGrid->value +; (let ( +; ( Command +; ( sprintf +; nil +; "%s/cast2skill --cast-path=%s --cell=%s --output-dir=%s --cadence-name --suppress-pins --root-only" +; ( PackageGetBinRoot ) +; ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) +; "standard.null.NULL" +; ( ConfigFileGetValue TheCDSConfigTable "CDS_CACHE_DIR" ) +; ) ) ) +; ( printf "%s\n" Command ) +; ( shell Command ) ) +; +; ( KeepOutDrawKeepOut +; CellView +; ( CellInfoGetTableForCellName +; "null" +; ( sprintf +; nil +; "%s/ildirectives" +; ( ConfigFileGetValue +; TheCDSConfigTable +; "CDS_CACHE_DIR" ) ) ) +; ( mapcar +; (lambda ( LPP ) +; ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) +; ( ListIntersect HorizontalMetalLPPs MetalLPPs ) ) +; ( mapcar +; (lambda ( LPP ) +; ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) +; ( ListIntersect VerticalMetalLPPs MetalLPPs ) ) +; BoundaryLPP +; UserUnitsPerMeter +; DirectiveUnitsPerMeter +; ( list GNDNetName VddNetName ) +; ( list nil ) ; nil +; t +; nil +; 0 +; ?Area Area +; ) ) + + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ( NotchesFillNotchesOnCellView + CellView + + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_NWell->value + ( list ( list "nwellFix" NWellLPP ) ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_NWell->value + ( list ( list "npFix" NImplantLPP ) ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_NWell->value + ( list ( list "ppFix" PImplantLPP ) ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Poly->value + ( list ( list "polyfix" PolyLPP ) + ( list "notchpoly" PolyLPP ) ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_AreaFix->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "area" 0 ) + MetalLPP ) ) + MetalLPPs ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_Notch->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "notch" 0 ) MetalLPP ) ) + MetalLPPs ) ) + (if UILeafRouteClean_Form->UIRouteClean_Form_Extension->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "extension" 0 ) MetalLPP ) ) + MetalLPPs ) ) ) ) ) ) ) ) + + ( append + ( mapcar + (lambda ( MetalLPP ) + ( car MetalLPP ) ) + MetalLPPs ) + ( append + ( setof + Set + ( list + (if UILeafRouteClean_Form->UIRouteClean_Form_Poly->value + "POLY" ) + (if UILeafRouteClean_Form->UIRouteClean_Form_AreaFix->value + "AREA" ) + (if UILeafRouteClean_Form->UIRouteClean_Form_Notch->value + "NOTCH" ) + (if UILeafRouteClean_Form->UIRouteClean_Form_Extension->value + "EXTENSION" ) + (if UILeafRouteClean_Form->UIRouteClean_Form_NImp->value + "NIMP" ) + (if UILeafRouteClean_Form->UIRouteClean_Form_PImp->value + "PIMP" ) + (if UILeafRouteClean_Form->UIRouteClean_Form_NWell->value + "NWELL" ) ) + ( stringp Set ) ) + ( append + (if UILeafRouteClean_Form->UIRouteClean_Form_OnGrid->value + ( list + "M2_AREA_KEEPIN" + "M3_AREA_KEEPIN" + "M4_AREA_KEEPIN" + "M5_AREA_KEEPIN" + "M6_AREA_KEEPIN" + "M7_AREA_KEEPIN" ) ) + (if ( equal + ( VersionGetMajorVersion ) + "4" ) + ( list "VERSION_4X" ) ) ) ) ) + + ( sprintf + nil + "%s/share/Fulcrum/notch/fill_notches.assura.rules.all" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ?Area Area + ?NoPCells UILeafRouteClean_Form->UIRouteClean_Form_NoPCells->value + ) + ( foreach LPP + ( mapcar + (lambda ( LPP ) + ( list ( car LPP ) "dummy" ) ) + MetalLPPs ) + ( foreach Shape ( PinUtilGetAllShapesOnLPP CellView LPP ) + ( dbDeleteObject Shape ) ) ) + foreach(SHAPE CellView-> shapes + when( SHAPE~>layerName=="prBoundary" + dbDeleteObject(SHAPE) + )) + ) ) + ( + ( printf "No prBoundary shape!!!\n" ) ) + ) ) ) ) + + + + ( UICreateComponent + "UILeafRouteClean_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Area + ?buttonText "Select Area" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_NoPCells + ?buttonText "Don't export gates/stacks" + ?defValue nil ) +; ( hiCreateBooleanButton +; ?name `UIRouteClean_Form_OnGrid +; ?buttonText "On Grid" +; ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Notch + ?buttonText "Notch" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_AreaFix + ?buttonText "Area" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Extension + ?buttonText "Extension" + ?defValue nil ) +; ( hiCreateBooleanButton +; ?name `UIRouteClean_Form_Poly +; ?buttonText "Poly" +; ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_NWell + ?buttonText "NWell" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_NImp + ?buttonText "N Implant" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_PImp + ?buttonText "P Implant" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal1 + ?buttonText "Metal 1" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal2 + ?buttonText "Metal 2" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal3 + ?buttonText "Metal 3" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal4 + ?buttonText "Metal 4" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal5 + ?buttonText "Metal 5" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal6 + ?buttonText "Metal 6" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal7 + ?buttonText "Metal 7" + ?defValue nil ) + ( hiCreateFormButton + ?name `UIRouteClean_Form_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Clean_Base_Layers_help.html\" )" ) + ) ) ) + ( hiCreateAppForm + ?name `UILeafRouteClean_Form + ?formTitle "Route Clean" + ?fields Fields + ?callback "( UIRouteCleanFormCB )" + ) + hiSetFormSize( UILeafRouteClean_Form list(601 630)) + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawImplant.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawImplant.il new file mode 100644 index 0000000000..55a92c1c7a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawImplant.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "07. Draw Implant" "UILeafDrawImplant" ) + + +( UICreateMenuItemCallBack + `UILeafDrawImplantCB + (lambda () (Implant)) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPins.il new file mode 100644 index 0000000000..379d2ee0b6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPins.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "02. DrawPins" "UILeafDrawPins" ) + + +( UICreateMenuItemCallBack + `UILeafDrawPinsCB + (lambda () (DrawLeafPins ?power t)) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPoly.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPoly.il new file mode 100644 index 0000000000..9a4a65f64e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawPoly.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "09. Draw Poly/CPO" "UILeafDrawPoly" ) + + +( UICreateMenuItemCallBack + `UILeafDrawPolyCB + (lambda () (RedrawGridPoly)) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawStruts.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawStruts.il new file mode 100644 index 0000000000..138714e377 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/DrawStruts.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "05. Draw Power Struts" "UILeafDrawStruts" ) + + +( UICreateMenuItemCallBack + `UILeafDrawStrutsCB + (lambda () (VStruts (UIGetCellView))) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/GroupChains.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/GroupChains.il new file mode 100644 index 0000000000..d5a8ef4aec --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/GroupChains.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "03. Group Chains" "UILeafGroupChains" ) + + +( UICreateMenuItemCallBack + `UILeafGroupChainsCB + (lambda () (GroupChains)) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/MakeAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/MakeAbstract.il new file mode 100644 index 0000000000..74c49bb61b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/MakeAbstract.il @@ -0,0 +1,17 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "10. MakeAbstract" "UILeafAbstract" ) + + +( UICreateMenuItemCallBack + `UILeafAbstractCB + (lambda () + (MakeLeafAbstract) + (View "abstract") + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlaceGates.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlaceGates.il new file mode 100644 index 0000000000..19c38fdd82 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlaceGates.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "04. Place Gates" "UILeafPlaceGates" ) + + +( UICreateMenuItemCallBack + `UILeafPlaceGatesCB + (lambda () (UIPopUpDialog "Not implemented yet. Ask Kai.")) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlacePlugs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlacePlugs.il new file mode 100644 index 0000000000..65bdb5f3f3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/PlacePlugs.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "06. Place Well Plugs" "UILeafPlacePlugs" ) + + +( UICreateMenuItemCallBack + `UILeafPlacePlugsCB + (lambda () (UIPopUpDialog "Not implemented yet. Ask Kai.")) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/RouteLeaf.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/RouteLeaf.il new file mode 100644 index 0000000000..7dfdb1911f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/RouteLeaf.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "08. Route" "UILeafRoute" ) + + +( UICreateMenuItemCallBack + `UILeafRouteCB + (lambda () (RouteLeaf)) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/SyncToNetlist.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/SyncToNetlist.il new file mode 100644 index 0000000000..57fcbfe0e9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Leaf/SyncToNetlist.il @@ -0,0 +1,14 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "01. Sync To NetList" "UILeafSyncToNetList" ) + + +( UICreateMenuItemCallBack + `UILeafSyncToNetListCB + (lambda () (SyncToNetlist ?CV (UIGetCellView))) + ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LeafAbstractList.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LeafAbstractList.il new file mode 100644 index 0000000000..dca5e734d8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LeafAbstractList.il @@ -0,0 +1,100 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LeafAbstractList.il#1 $ +; $DateTime: 2009/10/05 15:21:21 $ +; $Author: stevemc $ + +( list "Leaf Abstract List" "UILeafAbstracts" ) + +( UICreateMenuItemCallBack + `UILeafAbstractsCB + (lambda () + ( hiDisplayForm UILeafAbstracts_Form ) ) ) + +( UICreateAction + 'UILeafAbstractsFormCB + (lambda () + (let (leaflist abstracts overwrite layouts OptionList newlist p4add) + + leaflist=UILeafAbstracts_Form->UILeafAbstracts_Form_List->value + newlist=UILeafAbstracts_Form->UILeafAbstracts_Form_Newlist->value + overwrite=UILeafAbstracts_Form->UILeafAbstracts_Form_Edit->value + p4add=UILeafAbstracts_Form->UILeafAbstracts_Form_Add->value + + ; generate new cell list + (when newlist + (CreateMissingAbstractList (wcv) UILeafAbstracts_Form->UILeafAbstracts_Form_List->value ) + ) + + abstracts=(OpenCellViewsFromFile leaflist "abstract" "r") + (foreach cell abstracts + (when overwrite + (CDSP4Edit + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cell + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + ) + layouts=(OpenCellViewsFromFile leaflist "layout" "r") + (foreach cell layouts + ; create abstract + (MakeLeafAbstract ?CV cell) + ) + + ; p4 add abstract views + (when p4add + abstracts=(OpenCellViewsFromFile leaflist "abstract" "r") + (foreach cell abstracts + (CDSP4Add + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cell + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + ) + + ) + ) +) + + +( UICreateComponent + "UILeafAbstracts_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UILeafAbstracts_Form_List + ?prompt "Cell List" + ?defValue "missingAbstracts.leaf" ) + ( hiCreateBooleanButton + ?name `UILeafAbstracts_Form_Newlist + ?buttonText "Create list of missing abstracts" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UILeafAbstracts_Form_Add + ?buttonText "P4 Add abstracts" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UILeafAbstracts_Form_Edit + ?buttonText "P4 Edit and overwrite existing abstracts" + ?defValue nil ) + ) + )) + + + ( hiCreateAppForm + ?name `UILeafAbstracts_Form + ?formTitle "Create Leaf Abstracts" + ?fields Fields + ?callback "(UILeafAbstractsFormCB)" + ) ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LockFolds.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LockFolds.il new file mode 100644 index 0000000000..5bde798662 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/LockFolds.il @@ -0,0 +1,22 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Lock Folds" "UILockFolds" ) + +( UICreateMenuItemCallBack + `UILockFoldsCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + (let ( + ( Gates ( cadr ( NameFilterInstances + ( setof Fig ( geGetSelectedSet ) ( equal ( getq Fig objType ) "inst" ) ) + GateLibCellPairRegExs ) ) ) ) + ( foreach Gate Gates + (let ( + ( Folds ( NPSearchGateGetFolds Gate ) ) ) + (when Folds + ( NPSearchGateSetFolds Gate Folds ) + ( NPSearchGateSetOverrideFolds Gate t ) ) ) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/.menu new file mode 100644 index 0000000000..5542462914 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/.menu @@ -0,0 +1 @@ +( list "'MidLevel Layout'" "UIMidLevel" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/Clean.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/Clean.il new file mode 100644 index 0000000000..aa66580a89 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/Clean.il @@ -0,0 +1,300 @@ + + +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Clean.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + +( list "5. RouteClean" "UIMidRouteClean" ) + +( UICreateMenuItemCallBack + `UIMidRouteCleanCB + (lambda () + ( hiDisplayForm UIMidRouteClean_Form ) ) ) + +( UICreateAction + 'UIMidRouteCleanFormCB + (lambda () + (let ( left bottom right top + ( CellView ( UIGetCellView ) ) + ( DirectiveTable + ( CellInfoGetTableForCellName + "null" + ( sprintf + nil + "%s/share/Fulcrum" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ) ) + + ( Area + (when UIMidRouteClean_Form->UIMidRouteClean_Form_Area->value + ( enterBox ?prompts ( list "Select area to clean" ) ) ) ) + ) + left=round(caar(GetPrbound(CellView)->bBox)*1000) + bottom=round(cadar(GetPrbound(CellView)->bBox)*1000) + right=round(caadr(GetPrbound(CellView)->bBox)*1000) + top=round(cadadr(GetPrbound(CellView)->bBox)*1000) + dbCreateRect(CellView BoundaryLPP list(left/1000.0:bottom/1000.0 right/1000.0:top/1000.0)) + (cond ( + ( PinUtilFindPRBoundShape BoundaryLPP CellView ) + (let ( + ( MetalLPPs + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Metal1->value + ( list Metal1LPP ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Metal2->value + ( list Metal2LPP ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Metal3->value + ( list Metal3LPP ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Metal4->value + ( list Metal4LPP ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Metal5->value + ( list Metal5LPP ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Metal6->value + ( list Metal6LPP ) ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Metal7->value + ( list Metal7LPP ) ) ) ) ) ) ) ) ) ) + + +; (when UIRouteClean_Form->UIRouteClean_Form_OnGrid->value +; (let ( +; ( Command +; ( sprintf +; nil +; "%s/cast2skill --cast-path=%s --cell=%s --output-dir=%s --cadence-name --suppress-pins --root-only" +; ( PackageGetBinRoot ) +; ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) +; "standard.null.NULL" +; ( ConfigFileGetValue TheCDSConfigTable "CDS_CACHE_DIR" ) +; ) ) ) +; ( printf "%s\n" Command ) +; ( shell Command ) ) +; +; ( KeepOutDrawKeepOut +; CellView +; ( CellInfoGetTableForCellName +; "null" +; ( sprintf +; nil +; "%s/ildirectives" +; ( ConfigFileGetValue +; TheCDSConfigTable +; "CDS_CACHE_DIR" ) ) ) +; ( mapcar +; (lambda ( LPP ) +; ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) +; ( ListIntersect HorizontalMetalLPPs MetalLPPs ) ) +; ( mapcar +; (lambda ( LPP ) +; ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) +; ( ListIntersect VerticalMetalLPPs MetalLPPs ) ) +; BoundaryLPP +; UserUnitsPerMeter +; DirectiveUnitsPerMeter +; ( list GNDNetName VddNetName ) +; ( list nil ) ; nil +; t +; nil +; 0 +; ?Area Area +; ) ) + + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ( NotchesFillNotchesOnCellView + CellView + + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_NWell->value + ( list ( list "nwellFix" NWellLPP ) ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_NWell->value + ( list ( list "npFix" NImplantLPP ) ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_NWell->value + ( list ( list "ppFix" PImplantLPP ) ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Poly->value + ( list ( list "polyfix" PolyLPP ) + ( list "notchpoly" PolyLPP ) ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_AreaFix->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "area" 0 ) + MetalLPP ) ) + MetalLPPs ) ) + ( append + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Notch->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "notch" 0 ) MetalLPP ) ) + MetalLPPs ) ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Extension->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "extension" 0 ) MetalLPP ) ) + MetalLPPs ) ) ) ) ) ) ) ) + + ( append + ( mapcar + (lambda ( MetalLPP ) + ( car MetalLPP ) ) + MetalLPPs ) + ( append + ( setof + Set + ( list + (if UIMidRouteClean_Form->UIRouteClean_Form_Poly->value + "POLY" ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_AreaFix->value + "AREA" ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Notch->value + "NOTCH" ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_Extension->value + "EXTENSION" ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_NImp->value + "NIMP" ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_PImp->value + "PIMP" ) + (if UIMidRouteClean_Form->UIMidRouteClean_Form_NWell->value + "NWELL" ) ) + ( stringp Set ) ) + ( append + (if UIMidRouteClean_Form->UIRouteClean_Form_OnGrid->value + ( list + "M2_AREA_KEEPIN" + "M3_AREA_KEEPIN" + "M4_AREA_KEEPIN" + "M5_AREA_KEEPIN" + "M6_AREA_KEEPIN" + "M7_AREA_KEEPIN" ) ) + (if ( equal + ( VersionGetMajorVersion ) + "4" ) + ( list "VERSION_4X" ) ) ) ) ) + + ( sprintf + nil + "%s/share/Fulcrum/notch/fill_notches.assura.rules.all" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ?Area Area + ?NoPCells UIMidRouteClean_Form->UIRouteClean_Form_NoPCells->value + ) + ( foreach LPP + ( mapcar + (lambda ( LPP ) + ( list ( car LPP ) "dummy" ) ) + MetalLPPs ) + ( foreach Shape ( PinUtilGetAllShapesOnLPP CellView LPP ) + ( dbDeleteObject Shape ) ) ) + foreach(SHAPE CellView-> shapes + when( SHAPE~>layerName=="prBoundary" + dbDeleteObject(SHAPE) + )) + ) ) + ( + ( printf "No prBoundary shape!!!\n" ) ) + ) ) ) ) + + + + ( UICreateComponent + "UIMidRouteClean_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Area + ?buttonText "Select Area" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_NoPCells + ?buttonText "Don't export gates/stacks" + ?defValue nil ) +; ( hiCreateBooleanButton +; ?name `UIRouteClean_Form_OnGrid +; ?buttonText "On Grid" +; ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Notch + ?buttonText "Notch" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_AreaFix + ?buttonText "Area" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Extension + ?buttonText "Extension" + ?defValue nil ) +; ( hiCreateBooleanButton +; ?name `UIRouteClean_Form_Poly +; ?buttonText "Poly" +; ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_NWell + ?buttonText "NWell" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_NImp + ?buttonText "N Implant" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_PImp + ?buttonText "P Implant" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Metal1 + ?buttonText "Metal 1" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Metal2 + ?buttonText "Metal 2" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Metal3 + ?buttonText "Metal 3" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Metal4 + ?buttonText "Metal 4" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Metal5 + ?buttonText "Metal 5" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Metal6 + ?buttonText "Metal 6" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMidRouteClean_Form_Metal7 + ?buttonText "Metal 7" + ?defValue t ) + ( hiCreateFormButton + ?name `UIRouteClean_Form_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Clean_Base_Layers_help.html\" )" ) + ) ) ) + ( hiCreateAppForm + ?name `UIMidRouteClean_Form + ?formTitle "Route Clean" + ?fields Fields + ?callback "( UIMidRouteCleanFormCB )" + ) + hiSetFormSize( UIMidRouteClean_Form list(601 630)) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeAbstract.il new file mode 100644 index 0000000000..fd7756cdda --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeAbstract.il @@ -0,0 +1,17 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawPins.il#4 $ +; $DateTime: 2012/07/11 17:39:18 $ +; $Author: pankala $ + +( list "4. Make Abstract" "UIMakeAbstract" ) + + +( UICreateMenuItemCallBack + `UIMakeAbstractCB + (lambda () + (MakeMidAbstract) + (View "abstract") + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeFlatten.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeFlatten.il new file mode 100644 index 0000000000..ec5193dd31 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeFlatten.il @@ -0,0 +1,56 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawPins.il#4 $ +; $DateTime: 2012/07/11 17:39:18 $ +; $Author: pankala $ + +( list "2. Make Flatten" "UIMakeFlatten" ) + + +( UICreateMenuItemCallBack + `UIMakeFlattenCB + (lambda () + ( hiDisplayForm UIMakeFlatten_Form ) ) +) + + +( UICreateAction + 'UIMakeFlattenFormCB + (lambda () + ( MakeFlatten + ?RegenerateFromCast UIMakeFlatten_Form->UIMakeFlatten_Form_RegenerateCast->value + ?doFillPoly UIMakeFlatten_Form->UIMakeFlatten_Form_FillPoly->value + ?doPowerGridAbstract UIMakeFlatten_Form->UIMakeFlatten_Form_PGAbstract->value ) + ) +) + + + +( UICreateComponent + "UIMakeFlatten_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIMakeFlatten_Form_RegenerateCast + ?buttonText "Force Cast Refresh" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMakeFlatten_Form_FillPoly + ?buttonText "Poly Fill" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMakeFlatten_Form_PGAbstract + ?buttonText "Power Grid Abstract" + ?defValue t ) + ) ) ) + ( hiCreateAppForm + ?name `UIMakeFlatten_Form + ?formTitle "Make Flatten" + ?fields Fields + ?callback "( UIMakeFlattenFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeLayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeLayout.il new file mode 100644 index 0000000000..b4313bc499 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakeLayout.il @@ -0,0 +1,15 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il#1 $ +; $DateTime: 2011/10/03 13:24:55 $ +; $Author: aubrey $ + + +( list "3. Make Layout" "UIMakeLayout" ) + + +( UICreateMenuItemCallBack + `UIMakeLayoutCB + (lambda () (UIPopUpDialog "Not implemented yet. Ask Tom.")) + ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakePrelayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakePrelayout.il new file mode 100644 index 0000000000..9091eca012 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/MidLevel/MakePrelayout.il @@ -0,0 +1,56 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/intel/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawPins.il#4 $ +; $DateTime: 2012/07/11 17:39:18 $ +; $Author: pankala $ + +( list "1. Make Prelayout" "UIMakePrelayout" ) + + +( UICreateMenuItemCallBack + `UIMakePrelayoutCB + (lambda () + ( hiDisplayForm UIMakePrelayout_Form ) ) +) + + +( UICreateAction + 'UIMakePrelayoutFormCB + (lambda () + ( MakePrelayout + ?RegenerateFromCast UIMakePrelayout_Form->UIMakePrelayout_Form_RegenerateCast->value + ?Overwrite UIMakePrelayout_Form->UIMakePrelayout_Form_Overwrite->value + ?SyncToNetlist UIMakePrelayout_Form->UIMakePrelayout_Form_SyncToNetlist->value ) + ) +) + + + +( UICreateComponent + "UIMakePrelayout_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIMakePrelayout_Form_RegenerateCast + ?buttonText "Force Cast Refresh" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIMakePrelayout_Form_Overwrite + ?buttonText "Overwrite Existing Views" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIMakePrelayout_Form_SyncToNetlist + ?buttonText "Sync To Netlist" + ?defValue t ) + ) ) ) + ( hiCreateAppForm + ?name `UIMakePrelayout_Form + ?formTitle "Make Prelayout" + ?fields Fields + ?callback "( UIMakePrelayoutFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Options.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Options.il new file mode 100644 index 0000000000..2c9607271f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Options.il @@ -0,0 +1,32 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Max Heap Size" "UIOptions" ) + +( UICreateMenuItemCallBack + `UIOptionsCB + (lambda () + ( hiDisplayForm UIOptions_Form ) ) ) + +( UICreateComponent + "UIOptions_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateIntField + ?name `UIOptions_Form_MaxHeapSize + ?prompt "Max Heap Size (M)" + ?defValue 1800 ) + ( hiCreateStringField + ?name `UIOptions_Form_JavaArguments + ?prompt "Additional Java Arguments" + ?defValue "" ) ) ) ) + ( hiCreateAppForm + ?name `UIOptions_Form + ?formTitle "Java Options" + ?fields Fields + ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/.menu new file mode 100644 index 0000000000..a15f352f73 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/.menu @@ -0,0 +1 @@ +( list "P4" "UIP4" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4Cell.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4Cell.il new file mode 100755 index 0000000000..cde36a1044 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4Cell.il @@ -0,0 +1,151 @@ + +( list "P4 Cell Components" "UIP4WholeCell" ) + +( UICreateMenuItemCallBack + `UIP4WholeCellCB + (lambda () + ( hiDisplayForm UIP4WholeCell_Form ) ) +) + +defun( P4WholeCell ( cellView p4action) + let( (cv instances uniqueInstances pgname busname autobusname basename subtype client nraction) + + (when UIP4WholeCell_Form->UIP4WholeCell_Form_floorplan->value + cv = ( dbOpenCellViewByType cellView->libName cellView->cellName "floorplan" ) + (when cv ( CDSP4CellView cv p4action )) + ) + (when UIP4WholeCell_Form->UIP4WholeCell_Form_prelayout->value + cv = ( dbOpenCellViewByType cellView->libName cellView->cellName "prelayout" ) + (when cv ( CDSP4CellView cv p4action )) + ) + (when UIP4WholeCell_Form->UIP4WholeCell_Form_layout->value + cv = ( dbOpenCellViewByType cellView->libName cellView->cellName "layout" ) + (when cv ( CDSP4CellView cv p4action )) + ) + (when UIP4WholeCell_Form->UIP4WholeCell_Form_layoutpg->value + cv = ( dbOpenCellViewByType cellView->libName cellView->cellName "layout_pg" ) + (when cv ( CDSP4CellView cv p4action )) + ) + (when UIP4WholeCell_Form->UIP4WholeCell_Form_abstract->value + cv = ( dbOpenCellViewByType cellView->libName cellView->cellName "abstract" ) + (when cv ( CDSP4CellView cv p4action )) + ) + + basename = (cadr (reverse (parseString cellView->cellName "."))) + subtype = (car (reverse (parseString cellView->cellName "."))) + pgname = (strcat cellView->libName ".wires." basename "_" subtype "_POWER_GRID_TIEOFF") + (when UIP4WholeCell_Form->UIP4WholeCell_Form_pg->value + cv = ( dbOpenCellViewByType cellView->libName pgname "layout" ) + (when cv ( CDSP4CellView cv p4action )) + ) + + busname = (strcat cellView->libName ".wires." basename "_buswires") + (when UIP4WholeCell_Form->UIP4WholeCell_Form_buswires->value + cv = ( dbOpenCellViewByType cellView->libName busname "layout" ) + (when cv ( CDSP4CellView cv p4action )) + ) + + autobusname = (strcat cellView->libName ".wires." basename "_autobuswires") + (when UIP4WholeCell_Form->UIP4WholeCell_Form_autobuswires->value + cv = ( dbOpenCellViewByType cellView->libName autobusname "layout" ) + (when cv ( CDSP4CellView cv p4action )) + ) + + (when UIP4WholeCell_Form->UIP4WholeCell_Form_skill->value + ( CDSP4CellFile cellView "wires.il" p4action ) + ) + + (when UIP4WholeCell_Form->UIP4WholeCell_Form_wires->value + client = ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + (cond (p4action=="add" nraction="Add") + (p4action=="edit" nraction="Edit") + (p4action=="revert" nraction="Revert") + ) + (foreach inst cellView->instances + (when (IsCustomWiringCell inst) + cv = (dbOpenCellViewByType inst->libName inst->cellName inst->viewName) + (nrP4EditSubcells cv cv->viewName client nraction) + ) + ) + ) + + ) +) + + +( UICreateAction + 'UIP4WholeCellFormCB + (lambda () + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + + (let (CellView pinLpps) + CellView = UIGetCellView( ) + P4WholeCell( CellView + UIP4WholeCell_Form->UIP4WholeCell_Form_P4Action->value + ) + ) + ) +) + +( UICreateComponent + "UIP4WholeCell_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateRadioField + ?name `UIP4WholeCell_Form_P4Action + ?prompt "P4 Action" + ?choices list( "add" "edit" "revert") + ?defValue "add" ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_floorplan + ?buttonText "floorplan view" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_prelayout + ?buttonText "prelayout view" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_layout + ?buttonText "layout view" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_layoutpg + ?buttonText "layout_pg view" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_abstract + ?buttonText "abstract view" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_pg + ?buttonText "POWER_GRID layout view" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_buswires + ?buttonText "buswires cell" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_autobuswires + ?buttonText "autobuswires cell" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_skill + ?buttonText "wires.il" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIP4WholeCell_Form_wires + ?buttonText "custom wiring cells" + ?defValue t ) + ) ) ) + ( hiCreateAppForm + ?name `UIP4WholeCell_Form + ?formTitle "P4 Cell Components" + ?fields Fields + ?callback "( UIP4WholeCellFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4EditAllSubcells.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4EditAllSubcells.il new file mode 100755 index 0000000000..f1bae358c7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/P4EditAllSubcells.il @@ -0,0 +1,115 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "P4 All Subcells" "UIP4EditAllSubcells" ) + +( UICreateMenuItemCallBack + `UIP4EditAllSubcellsCB + (lambda () + if( ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) != "" then + UIP4EditAllSubcells_Form->UIP4EditAllSubcells_Form_P4Client->value=( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" )) + ( hiDisplayForm UIP4EditAllSubcells_Form ) ) ) + +defun( nrP4EditSubcells ( cellView viewName p4client p4action) + let((instances uniqueInstances ErrorStr inst) + cond( + (p4action=="Edit" + (if ExpertUser then + ErrorStr=CDSP4Edit( ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + p4client + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cellView + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + printf("P4Edit cell %s\n" cellView~>cellName) + else + (UIPopUpDialog "P4 Edit All Subcells has been disabled.\nIf you really must do it, see Steve and he may or may not oblige.") + (error "Operation not permitted.") + ) + ) + (p4action=="Add" + ErrorStr=CDSP4Add( ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + p4client + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cellView + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + printf("P4Add cell %s\n" cellView~>cellName) + ) + (p4action=="Revert" + ErrorStr=CDSP4Revert( ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + p4client + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + cellView + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + printf("P4Revert cell %s\n" cellView~>cellName) + ) + ) + instances=setof( inst cellView~>instances + inst~>viewName==viewName && inst~>libName!=TechLibName && inst~>libName != "gate" && inst~>libName != "stack") + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances= cons( inst uniqueInstances ) + ) + ) + foreach( inst uniqueInstances + nrP4EditSubcells( inst~>master viewName p4client p4action) + ) + ) +) + + +( UICreateAction + 'UIP4EditAllSubcellsFormCB + (lambda () + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + + (let (CellView pinLpps) + CellView = UIGetCellView( ) + nrP4EditSubcells( CellView + UIP4EditAllSubcells_Form->UIP4EditAllSubcells_Form_ViewName->value + UIP4EditAllSubcells_Form->UIP4EditAllSubcells_Form_P4Client->value + UIP4EditAllSubcells_Form->UIP4EditAllSubcells_Form_P4Action->value + ) + printf("Done P4Edit All Subcells.\n") + ) + ) +) + +( UICreateComponent + "UIP4EditAllSubcells_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIP4EditAllSubcells_Form_ViewName + ?prompt "Edit View Name" + ?defValue "prelayout" ) + ( hiCreateStringField + ?name `UIP4EditAllSubcells_Form_P4Client + ?prompt "P4 Client" + ?defValue "" ) + ( hiCreateRadioField + ?name `UIP4EditAllSubcells_Form_P4Action + ?prompt "P4 Action" + ?choices list( "Add" "Edit" "Revert") + ?defValue "Add" ) + ) ) ) + ( hiCreateAppForm + ?name `UIP4EditAllSubcells_Form + ?formTitle "P4 All Subcells" + ?fields Fields + ?callback "( UIP4EditAllSubcellsFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4add.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4add.il new file mode 100644 index 0000000000..c22325d4c3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4add.il @@ -0,0 +1,26 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "cdsp4add" "UIcdsp4add" ) + +( UICreateMenuItemCallBack + `UIcdsp4addCB + (lambda () + (if ( and + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) "" ) + ( or + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) "" ) + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) "" ) ) ) + (error "Must specify P4CONFIG or P4USER and P4CLIENT in envirnoment or cds.config" ) ) + (let ( + ( ErrorStr ( CDSP4Add + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + ( UIGetCellView ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) ) ) + (if ( stringp ErrorStr ) + ( println ErrorStr ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4edit.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4edit.il new file mode 100644 index 0000000000..8967121e2b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4edit.il @@ -0,0 +1,26 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "cdsp4edit" "UIcdsp4edit" ) + +( UICreateMenuItemCallBack + `UIcdsp4editCB + (lambda () + (if ( and + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) "" ) + ( or + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) "" ) + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) "" ) ) ) + (error "Must specify P4CONFIG or P4USER and P4CLIENT in envirnoment or cds.config" ) ) + (let ( + ( ErrorStr ( CDSP4Edit + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + ( UIGetCellView ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) ) ) + (if ( stringp ErrorStr ) + ( println ErrorStr ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4revert.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4revert.il new file mode 100644 index 0000000000..bc06a7e9dc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4revert.il @@ -0,0 +1,26 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "cdsp4revert" "UIcdsp4revert" ) + +( UICreateMenuItemCallBack + `UIcdsp4revertCB + (lambda () + (if ( and + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) "" ) + ( or + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) "" ) + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) "" ) ) ) + (error "Must specify P4CONFIG or P4USER and P4CLIENT in envirnoment or cds.config" ) ) + (let ( + ( ErrorStr ( CDSP4Revert + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + ( UIGetCellView ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) ) ) + (if ( stringp ErrorStr ) + ( println ErrorStr ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4submit.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4submit.il new file mode 100644 index 0000000000..6ba0878453 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/P4/cdsp4submit.il @@ -0,0 +1,41 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "cdsp4submit" "UIcdsp4submit" ) + +( UICreateMenuItemCallBack + `UIcdsp4submitCB + (lambda () + (if ( equal ( ConfigFileGetValue TheCDSConfigTable "P4LOG" ) "" ) + (error "Must specify P4LOG in envirnoment or cds.config" ) ) + (if ( equal ( ConfigFileGetValue TheCDSConfigTable "P4HOST" ) "" ) + (error "Must specify P4HOST in envirnoment or cds.config" ) ) + (if ( and + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) "" ) + ( or + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) "" ) + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) "" ) ) ) + (error "Must specify P4CONFIG or P4USER and P4CLIENT in envirnoment or cds.config" ) ) + ( hiDisplayAppDBox + ?name `UIcdsp4submitDBox + ?dboxText "Submit?" + ?callback "( UIcdsp4submitOKCB )" ) + ) ) + +( UICreateAction + `UIcdsp4submitOKCB + (lambda () + (let ( + ( ErrorStr ( CDSP4Submit + ( ConfigFileGetValue TheCDSConfigTable "P4HOST" ) + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + ( UIGetCellView ) + ( ConfigFileGetValue TheCDSConfigTable "P4LOG" ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) ) ) + (if ( stringp ErrorStr ) + ( println ErrorStr ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/.menu new file mode 100644 index 0000000000..2070f53763 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/.menu @@ -0,0 +1 @@ +( list "Pins" "UIPins" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/CanonicalizePins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/CanonicalizePins.il new file mode 100644 index 0000000000..0d28ee3216 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/CanonicalizePins.il @@ -0,0 +1,18 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrelayout.il#5 $ +; $DateTime: 2007/01/11 17:54:06 $ +; $Author: khe $ + +; +; menu item Nano/Prelayout +; +( list "Canonicalize Pin Names" "UICanonicalizePins" ) + +( UICreateMenuItemCallBack + `UICanonicalizePinsCB + (lambda () + CanonicalizePins() + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawPins.il new file mode 100644 index 0000000000..055d509801 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawPins.il @@ -0,0 +1,245 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Draw Pins" "UIDrawPins" ) + + +( UICreateMenuItemCallBack + `UIDrawPinsCB + (lambda () +; UIDrawPins_Form->UIDrawPins_Form_UserPinsFile->value = +; ( sprintf +; nil +; "%s/userpins.il" +; ( NameGetCellPathFromCellName +; ( getq ( UIGetCellView ) cellName ) ) ) + +; UIDrawPins_Form->UIDrawPins_Form_ConnectivityViewName->value = ( getq ( UIGetCellView ) viewName ) + CellViewName = ( getq ( UIGetCellView ) viewName ) + ( hiDisplayForm UIDrawPins_Form ) + ) +) + + +( UICreateAction + 'UIDrawPinsFormCB + (lambda () + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + (let ( + ( CellView ( UIGetCellView ) ) ( DrawPins t ) ) + (let ( + ( TargetDFIIPath + ( NameGetCellDirFromDFIIDirAndCellName + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( getq CellView cellName ) ) ) ) + (let ( + ( PinsFile + ( sprintf + nil + "%s/autopins/%s.pins.il" + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( getq CellView cellName ) ) ) +; ( UserPinsFile +; UIDrawPins_Form->UIDrawPins_Form_UserPinsFile->value ) + ( ExecCmd + (cond ( + ( and ( boundp `ExecCmd ) ( stringp ExecCmd ) ) + ExecCmd ) + ( + "" ) ) ) + ) + + ;check if this is a leaf cell +; (when !(IsLeafCell CellView->cellName) +; DrawPins = (hiDisplayAppDBox +; ?name 'PinsErrorDialogBox +; ?dboxText "This is not a leaf cell. You almost certainly should not be running this menu.\n Use the Nano menu or Ctrl-Alt-g to draw pins using bus scripts.\n Are you sure you want to proceed anyway?" +; ?dboxBanner "Alert!" +; ?dialogType hicQuestionDialog +; ?dialogStyle 'modal +; ?buttonLayout 'YesNo +; ?defaultButton 2 +; ) +; ) + + (when UIDrawPins_Form->UIDrawPins_Form_DrawInplace->value + if( (IsLeafCell CellView->cellName) + then + (DrawLeafPins) + else + (RedrawAllPins) + ) + ) + + if( UIDrawPins_Form->UIDrawPins_Form_DrawPowerGrid->value + then + (DrawLeafM3Power) + else + (DelLeafM3Power) + ) + +; ;if forced to, run cast2skill again +; ; to create pins file +; (when +; ( or +; ( not ( isFile PinsFile ) ) +; ( not UIDrawPins_Form->UIDrawPins_Form_NoRerun->value ) ) +; +; ( printf "%s doesn't exist...creating\n" PinsFile ) +; (let ( +; ( PinsCommand +; ( sprintf +; nil +; "%s %s/cast2skill --cast-path=%s --cell=%s --output-dir=%s --cadence-name --root-only --max-heap-size=%dM --64" +; ExecCmd +; ( PackageGetBinRoot ) +; ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) +; ( getq CellView cellName ) +; ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) +; ( nrGetMaxHeapSize ) +; ) ) ) +; (when ( not +; ( equal +; UIDrawPins_Form->UIDrawPins_Form_PinType->value +; "auto" ) ) +; ( setq PinsCommand +; ( sprintf +; nil +; "%s --cell-height=%g --pin-type=%s" +; PinsCommand +; ( quotient +; ( RectGetHeight +; ( PinUtilFindPRBoundBBox BoundaryLPP CellView ) ) +; UserUnitsPerMeter ) +; UIDrawPins_Form->UIDrawPins_Form_PinType->value ) ) ) +; +; ( setq PinsFile +; ( sprintf +; nil +; "%s/autopins/%s.pins.il" +; ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) +; ( getq CellView cellName ) ) ) +; ( printf "%s\n" PinsCommand ) +; ( shell PinsCommand ) ) ) +; println("start") +; ( PinPlaceDrawUsingPDKInfo +; CellView +; ?PinsFile PinsFile +; ?PinLength UIDrawPins_Form->UIDrawPins_Form_PinLength->value +; ?PinsDirectory "" +; ?UserPinsFile UserPinsFile +; ?ConnectivityViewName CellViewName +; ?PowerGrid UIDrawPins_Form->UIDrawPins_Form_DrawPowerGrid->value +; ?InPlace UIDrawPins_Form->UIDrawPins_Form_DrawInplace->value +; ?AddOnly UIDrawPins_Form->UIDrawPins_Form_AddOnly->value +; ) +; println("end") +; +; ) +; if( UIDrawPins_Form->UIDrawPins_Form_PinExtension->value +; nrInplacePins( CellView ?PinExtension UIDrawPins_Form->UIDrawPins_Form_PinExtension->value) +; ) + + ) + ) + ) + ) +) + + +;( UICreateAction +; 'UICreateUserPinsFileCB +; (lambda () +; ( PinPlacePinScan +; ( UIGetCellView ) +; ViaLayerRegEx +; (when (equal UIDrawPins_Form->UIDrawPins_Form_PinType->value "pitched" ) t ) +; ( PinUtilGetBoundaryPolygonEdgesFromCellView +; BoundaryLPP +; ( UIGetCellView ) ) +; ( times UserUnitsPerMeter DefaultWirePitch ) +; ( list GNDNetName VddNetName ) +; ?PinsDirectory "" +; ?UserPinsFile UIDrawPins_Form->UIDrawPins_Form_UserPinsFile->value +; ?FileMode (if ( equal UIDrawPins_Form->UIDrawPins_Form_FileMode->value "Append" ) "a" "w" ) +; ) +; ) +;) + + +( UICreateComponent + "UIDrawPins_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list +; ( hiCreateStringField +; ?name `UIDrawPins_Form_UserPinsFile +; ?prompt "User Pins File" +; ?defValue "" ) +; ( hiCreateStringField +; ?name `UIDrawPins_Form_ConnectivityViewName +; ?prompt "Connectivity View Name" +; ?defValue "" ) +; ( hiCreateFloatField +; ?name `UIDrawPins_Form_PinLength +; ?prompt "Pin Length" +; ?defValue PinLength ) +; ( hiCreateBooleanButton +; ?name `UIDrawPins_Form_AddOnly +; ?buttonText "Only Add Pins" +; ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIDrawPins_Form_DrawPowerGrid + ?buttonText "Draw Leaf Cell Power Grid" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIDrawPins_Form_DrawInplace + ?buttonText "Draw Pins" + ?defValue t ) + ( hiCreateFormButton + ?name `UIDrawPins_Form_Help + ?buttonText "Scan Pins to --> Pin Template" + ?callback "ScanToPinTemplate" ) +; ( hiCreateBooleanButton +; ?name `UIDrawPins_Form_PinExtension +; ?buttonText "Regard Metal Overlapping Pin Shapes As Pins" +; ?defValue nil ) +; ( hiCreateBooleanButton +; ?name `UIDrawPins_Form_NoRerun +; ?buttonText "Don't Recreate Pins File" +; ?defValue t ) +; ( hiCreateCyclicField +; ?name `UIDrawPins_Form_PinType +; ?choices ( list "auto" "inplace" "pitched" ) +; ?defValue "auto" +; ?prompt "Pin Type" ) +; ( hiCreateButton +; ?name `UIDrawPins_Form_CreateUserPinsFile +; ?buttonText "Scan Existing Pins To User Pins File" +; ?callback "( UICreateUserPinsFileCB )" ) +; ( hiCreateCyclicField +; ?name `UIDrawPins_Form_FileMode +; ?choices ( list "Append" "Write" ) +; ?defValue "Append" +; ?prompt "User Pins File Mode" ) +; ( hiCreateFormButton +; ?name `UIDrawPins_Form_Help +; ?buttonText "Tool Help" +; ?callback "nrOpenHtml( \"Draw_Pins_help.html\" )" ) + ) ) ) + ( hiCreateAppForm + ?name `UIDrawPins_Form + ?formTitle "Draw Pins" + ?fields Fields + ?callback "( UIDrawPinsFormCB )" + ) + ) + ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawResetPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawResetPins.il new file mode 100644 index 0000000000..c02196028d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawResetPins.il @@ -0,0 +1,192 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/DrawPins.il#24 $ +; $DateTime: 2004/12/10 10:42:22 $ +; $Author: rliu $ + +( list "Draw Reset Pins" "UIDrawResetPins" ) + +( UICreateMenuItemCallBack + `UIDrawResetPinsCB + (lambda () + + ( hiDisplayForm UIDrawResetPins_Form ) ) ) + +( UICreateAction + 'UIDrawResetPinsFormCB + (lambda () + let( (CellView xMin xMax yMin yMax + xPitch yPitch xOffset yOffset xWidth yWidth + m n x y resetNet path rect) + CellView=( UIGetCellView ) + xMin=1e12 xMax=-1e12 yMin=1e12 yMax=-1e12 + xPitch=UIDrawResetPins_Form->UIDrawResetPins_Form_xPitch->value + yPitch=UIDrawResetPins_Form->UIDrawResetPins_Form_yPitch->value + xOffset=UIDrawResetPins_Form->UIDrawResetPins_Form_xOffset->value + yOffset=UIDrawResetPins_Form->UIDrawResetPins_Form_yOffset->value + xWidth=UIDrawResetPins_Form->UIDrawResetPins_Form_xWidth->value + yWidth=UIDrawResetPins_Form->UIDrawResetPins_Form_yWidth->value + xMetalLPP=list(UIDrawResetPins_Form->UIDrawResetPins_Form_xMetalName->value "drawing") + xMetalPin=list(UIDrawResetPins_Form->UIDrawResetPins_Form_xMetalName->value "pin") + yMetalLPP=list(UIDrawResetPins_Form->UIDrawResetPins_Form_yMetalName->value "drawing") + yMetalPin=list(UIDrawResetPins_Form->UIDrawResetPins_Form_yMetalName->value "pin") + resetNet=dbMakeNet( CellView UIDrawResetPins_Form->UIDrawResetPins_Form_NetName~>value ) + + prBound=setof( lpp CellView~>lpps lpp~>layerName==car(BoundaryLPP) && lpp~>purpose==cadr(BoundaryLPP)) + if( prBound==nil then bBox=CellView~>bBox + xMin=min(xMin caar(bBox)) + yMin=min(yMin cadar(bBox)) + xMax=max(xMax caadr(bBox)) + yMax=max(yMax cadadr(bBox)) + else prBound=car(prBound) + foreach( shape prBound~>shapes + bBox=shape~>bBox + xMin=min(xMin caar(bBox)) + yMin=min(yMin cadar(bBox)) + xMax=max(xMax caadr(bBox)) + yMax=max(yMax cadadr(bBox)) + ) + bBox=list( xMin:yMin xMax:yMax ) + ) + + for( m ceiling((xMin-xOffset)/xPitch) floor((xMax-xOffset)/xPitch) + x=m*xPitch+xOffset + path=dbCreatePath( CellView + xMetalLPP + list( x:yMin+DefaultWireSpacing*MicronsPerMeter+yWidth/2 + x:yMax-DefaultWireSpacing*MicronsPerMeter-yWidth/2 + ) + yWidth + ) + dbSetq( path "varExtendExtend" pathStyle ) + dbSetq( path yWidth/2 beginExt ) + dbSetq( path yWidth/2 endExt ) + rect=dbCreateRect( CellView + xMetalPin + list( x-yWidth/2:yMin+DefaultWireSpacing*MicronsPerMeter + x+yWidth/2:yMax-DefaultWireSpacing*MicronsPerMeter + ) + ) + dbCreatePin( resetNet path ) + dbCreatePin( resetNet rect ) + ) + for( n ceiling((yMin-yOffset)/yPitch) floor((yMax-yOffset)/yPitch) + y=n*yPitch+yOffset + path=dbCreatePath( CellView + yMetalLPP + list( xMin+DefaultWireSpacing*MicronsPerMeter+xWidth/2:y + xMax-DefaultWireSpacing*MicronsPerMeter-xWidth/2:y + ) + xWidth + ) + dbSetq( path "varExtendExtend" pathStyle ) + dbSetq( path xWidth/2 beginExt ) + dbSetq( path xWidth/2 endExt ) + rect=dbCreateRect( CellView + yMetalPin + list( xMin+DefaultWireSpacing*MicronsPerMeter:y-xWidth/2 + xMax-DefaultWireSpacing*MicronsPerMeter:y+xWidth/2 + ) + ) + dbCreatePin( resetNet path ) + dbCreatePin( resetNet rect ) + ) + for( m ceiling((xMin-xOffset)/xPitch) floor((xMax-xOffset)/xPitch) + for( n ceiling((yMin-yOffset)/yPitch) floor((yMax-yOffset)/yPitch) + x=m*xPitch+xOffset + y=n*yPitch+yOffset + leCreateContact( CellView + UIDrawResetPins_Form->UIDrawResetPins_Form_ViaName->value + list(x y) + "R0" + UIDrawResetPins_Form->UIDrawResetPins_Form_ViaWidth->value + UIDrawResetPins_Form->UIDrawResetPins_Form_ViaWidth->value + UIDrawResetPins_Form->UIDrawResetPins_Form_ViaRows->value + UIDrawResetPins_Form->UIDrawResetPins_Form_ViaCols->value + UIDrawResetPins_Form->UIDrawResetPins_Form_ViaSpacing->value + UIDrawResetPins_Form->UIDrawResetPins_Form_ViaSpacing->value + "center" "center" + ) + ) + ) + + ) + ) +) + + + +( UICreateComponent + "UIDrawResetPins_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIDrawResetPins_Form_NetName + ?prompt "Reset Net Name" + ?defValue "_RESET" ) + ( hiCreateCyclicField + ?name `UIDrawResetPins_Form_xMetalName + ?prompt "Vertical Strip Metal Layer" + ?choices foreach( mapcar lpp MetalLPPs car(lpp)) + ?defValue car(Metal4LPP) ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_xPitch + ?prompt "Vertical Strip Pitch" + ?defValue 4.8 ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_xWidth + ?prompt "Vertical Strip Width" + ?defValue 0.72 ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_xOffset + ?prompt "Vertical Strip Offset" + ?defValue 1.08 ) + ( hiCreateCyclicField + ?name `UIDrawResetPins_Form_yMetalName + ?prompt "Horizontal Strip Metal Layer" + ?choices foreach( mapcar lpp MetalLPPs car(lpp)) + ?defValue car(Metal5LPP) ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_yPitch + ?prompt "Horizontal Strip Pitch" + ?defValue 4.8 ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_yWidth + ?prompt "Horizontal Strip Width" + ?defValue 0.72 ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_yOffset + ?prompt "Horizontal Strip Offset" + ?defValue 1.08 ) + ( hiCreateStringField + ?name `UIDrawResetPins_Form_ViaName + ?prompt "Via Type" + ?defValue "M5_M4L" ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_ViaWidth + ?prompt "Via Width" + ?defValue 0.19 ) + ( hiCreateFloatField + ?name `UIDrawResetPins_Form_ViaSpacing + ?prompt "Via Spacing" + ?defValue 0.22 ) + ( hiCreateIntField + ?name `UIDrawResetPins_Form_ViaCols + ?prompt "Via Columns" + ?defValue 2 ) + ( hiCreateIntField + ?name `UIDrawResetPins_Form_ViaRows + ?prompt "Via Rows" + ?defValue 2 ) + ) ) ) + ( hiCreateAppForm + ?name `UIDrawResetPins_Form + ?formTitle "Draw Pins" + ?fields Fields + ?callback "( UIDrawResetPinsFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawSubPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawSubPins.il new file mode 100644 index 0000000000..054209020b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Pins/DrawSubPins.il @@ -0,0 +1,243 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/DrawPins.il#24 $ +; $DateTime: 2004/12/10 10:42:22 $ +; $Author: rliu $ + +( list "Draw Pins and Sub Level Pins" "UIDrawSubPins" ) + +( UICreateMenuItemCallBack + `UIDrawSubPinsCB + (lambda () + + UIDrawSubPins_Form->UIDrawSubPins_Form_ConnectivityViewName->value = + ( getq ( UIGetCellView ) viewName ) + + ( hiDisplayForm UIDrawSubPins_Form ) ) ) + +defun( UIDrawCellViewPins ( CellView pinFilename + @key + ( PinExtension t ) + ) + (let ( + ( TargetDFIIPath + ( NameGetCellDirFromDFIIDirAndCellName + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( getq CellView cellName ) ) ) ) + (let ( + ( PinsFile + ( sprintf + nil + "%s/autopins/%s.pins.il" + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( getq CellView cellName ) ) ) + ( UserPinsFile + pinFilename ) + ( ExecCmd + (cond ( + ( and ( boundp `ExecCmd ) ( stringp ExecCmd ) ) + ExecCmd ) + ( + "" ) ) ) + ) + + ;if forced to, run cast2skill again + ; to create pins file + (when + ( or + ( not ( isFile PinsFile ) ) + ( not UIDrawSubPins_Form->UIDrawSubPins_Form_NoRerun->value ) ) + + ( printf "%s doesn't exist...creating\n" PinsFile ) + (let ( + ( PinsCommand + ( sprintf + nil + "%s %s/cast2skill --cast-path=%s --cell=%s --output-dir=%s --cadence-name --root-only --max-heap-size=%dM --64" + ExecCmd + ( PackageGetBinRoot ) + ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) + ( getq CellView cellName ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( nrGetMaxHeapSize ) + ) ) ) + (when ( not + ( equal + UIDrawSubPins_Form->UIDrawSubPins_Form_PinType->value + "auto" ) ) + ( setq PinsCommand + ( sprintf + nil + "%s --cell-height=%g --pin-type=%s" + PinsCommand + ( quotient + ( RectGetHeight + ( PinUtilFindPRBoundBBox BoundaryLPP CellView ) ) + UserUnitsPerMeter ) + UIDrawSubPins_Form->UIDrawSubPins_Form_PinType->value ) ) ) + + ( setq PinsFile + ( sprintf + nil + "%s/autopins/%s.pins.il" + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ( getq CellView cellName ) ) ) + ( printf "%s\n" PinsCommand ) + ( shell PinsCommand ) ) ) + + ( PinPlaceDrawUsingPDKInfo + CellView + ?PinsFile PinsFile + ?PinLength UIDrawSubPins_Form->UIDrawSubPins_Form_PinLength->value + ?PinsDirectory "" + ?UserPinsFile UserPinsFile + ?ConnectivityViewName UIDrawSubPins_Form->UIDrawSubPins_Form_ConnectivityViewName->value + ?PowerGrid UIDrawSubPins_Form->UIDrawSubPins_Form_DrawPowerGrid->value + ?InPlace UIDrawSubPins_Form->UIDrawSubPins_Form_DrawInplace->value + ?AddOnly UIDrawSubPins_Form->UIDrawSubPins_Form_AddOnly->value + ) + nrInplacePins( CellView ?PinExtension PinExtension) + ) + ) +) + +defun( UIDrawSubCellViewPins ( CellView drawnCellList + @key + ( routedDirectiveList nil ) + ( Verbose nil ) + ( PinExtension t) + ) + let(( TargetDFIIPath pinFilename instances uniqueInstances temp LibCellsToIgnore) + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + TargetDFIIPath=NameGetCellDirFromDFIIDirAndCellName( ConfigFileGetValue( TheCDSConfigTable "TEMP" ) CellView~>cellName ) + pinFilename=sprintf( nil "%s/userpins.il" NameGetCellPathFromCellName( CellView~>cellName ) ) + if( CellView~>terminals==nil || setof( pin CellView~>terminals pin~>pins==nil ) then + temp=nrOpenCellViewWritable( CellView~>libName CellView~>cellName CellView~>viewName ) + if( temp then + CellView=temp + printf("Drawing Pins on %s...\n" CellView~>cellName ) + if( Verbose printf("Drawing Pins on %s...\n" CellView~>cellName )) + if( member( CellView~>cellName routedDirectiveList ) then UIDrawCellViewPins( CellView pinFilename ?PinExtension PinExtension) + else + instances= car( NameFilterInstances( CellView~>instances LibCellsToIgnore )) + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances=cons( inst uniqueInstances ) + ) + ) + instances=setof( inst uniqueInstances !member( inst~>cellName drawnCellList )) + foreach( inst instances + drawnCellList=UIDrawSubCellViewPins( inst~>master drawnCellList + ?routedDirectiveList routedDirectiveList ?Verbose Verbose ?PinExtension PinExtension) + ) + UIDrawCellViewPins( CellView pinFilename ?PinExtension PinExtension) + ) + dbSave(CellView) + else + printf("ERROR: can not open %s(%s) for write.\n" CellView~>cellName CellView~>libName) + ) + ) + drawnCellList=cons( CellView~>cellName drawnCellList) + ) +) + +( UICreateAction + 'UIDrawSubPinsFormCB + (lambda () + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + + let( ( CellView uniqueInstances instances instCellView ) + + CellView= UIGetCellView( ) + routedDirectiveList = nrCastQuery( CellView ?RegenerateFromCast UIDrawSubPins_Form->UIDrawSubPins_Form_RegenerateFromCast->value) + UIDrawSubCellViewPins( CellView nil + ?routedDirectiveList routedDirectiveList + ?PinExtension UIDrawSubPins_Form->UIDrawSubPins_Form_PinExtension->value + ) + + ) + ) +) + +( UICreateAction + 'UICreateUserPinsFileCB + (lambda () + ( PinPlacePinScan + ( UIGetCellView ) + ViaLayerRegEx + (when (equal UIDrawSubPins_Form->UIDrawSubPins_Form_PinType->value "pitched" ) t ) + ( PinUtilGetBoundaryPolygonEdgesFromCellView + BoundaryLPP + ( UIGetCellView ) ) + ( times UserUnitsPerMeter DefaultWirePitch ) + ( list GNDNetName VddNetName ) + ?PinsDirectory "" + ?UserPinsFile UIDrawSubPins_Form->UIDrawSubPins_Form_UserPinsFile->value + ?FileMode (if ( equal UIDrawSubPins_Form->UIDrawSubPins_Form_FileMode->value "Append" ) "a" "w" ) ) ) ) + + +( UICreateComponent + "UIDrawSubPins_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIDrawSubPins_Form_RegenerateFromCast + ?buttonText "Regenerate Routed Directive From Cast" + ?defValue t ) + ( hiCreateStringField + ?name `UIDrawSubPins_Form_ConnectivityViewName + ?prompt "Connectivity View Name" + ?defValue "" ) + ( hiCreateFloatField + ?name `UIDrawSubPins_Form_PinLength + ?prompt "Pin Length" + ?defValue PinLength ) + ( hiCreateBooleanButton + ?name `UIDrawSubPins_Form_AddOnly + ?buttonText "Only Add Pins" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIDrawSubPins_Form_DrawPowerGrid + ?buttonText "Draw Power Grid" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIDrawSubPins_Form_DrawInplace + ?buttonText "Draw Inplace pins" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIDrawSubPins_Form_PinExtension + ?buttonText "Regard Metal overlapping Pin Shapes as Pins" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIDrawSubPins_Form_NoRerun + ?buttonText "Don't recreate pins file" + ?defValue nil ) + ( hiCreateCyclicField + ?name `UIDrawSubPins_Form_PinType + ?choices ( list "auto" "inplace" "pitched" ) + ?defValue "auto" + ?prompt "PinType..." ) + ( hiCreateButton + ?name `UIDrawSubPins_Form_CreateUserPinsFile + ?buttonText "Scan existing pins to userpins.il file" + ?callback "( UICreateUserPinsFileCB )" ) + ( hiCreateCyclicField + ?name `UIDrawSubPins_Form_FileMode + ?choices ( list "Append" "Write" ) + ?defValue "Append" + ?prompt "userpins.il file mode" ) + ) ) ) + ( hiCreateAppForm + ?name `UIDrawSubPins_Form + ?formTitle "Draw Pins" + ?fields Fields + ?callback "( UIDrawSubPinsFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/PreroutePins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/PreroutePins.il new file mode 100755 index 0000000000..9258202192 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/PreroutePins.il @@ -0,0 +1,108 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Pins/PreroutePins.il#26 $ +; $DateTime: 2005/06/17 14:39:47 $ +; $Author: khe $ + +( list "PreRoute Close-By Pins" "UIPreroutePins" ) + +( UICreateMenuItemCallBack + `UIPreroutePinsCB + (lambda () + ( hiDisplayForm UIPreroutePins_Form ) ) ) + +( UICreateAction + 'UIPreroutePinsFormCB + (lambda () + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + + (let (CellView pinLpps) + CellView = UIGetCellView( ) + pinLpps=list( + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal1->value Metal1LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal2->value Metal2LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal3->value Metal3LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal4->value Metal4LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal5->value Metal5LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal6->value Metal6LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal7->value Metal7LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal8->value Metal8LPP ) + if( UIPreroutePins_Form->UIPreroutePins_Form_Metal9->value Metal9LPP ) + ) + pinLpps=setof( lpp pinLpps lpp ) + if( UIPreroutePins_Form->UIPreroutePins_Form_CloseByPins->value then + printf("Running Preroute Close-by Pins ...\n") + nrCreateNeighborNetConnector( CellView UIPreroutePins_Form->UIPreroutePins_Form_MaxDistance->value pinLpps) + ) + if( UIPreroutePins_Form->UIPreroutePins_Form_DummyPins->value then + printf("Running Preroute Dummy Subcell Pins ...\n") + nrCreateSingleNetConnector( CellView pinLpps ?MaxHeapSize nrGetMaxHeapSize( ) ) + ) + ) + ) +) + +( UICreateComponent + "UIPreroutePins_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_CloseByPins + ?buttonText "Preroute Close-by Pins" + ?defValue t ) + ( hiCreateFloatField + ?name `UIPreroutePins_Form_MaxDistance + ?prompt "Max Pin Distance To Be PreRouted" + ?defValue 0.24 ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_DummyPins + ?buttonText "Preroute Dummy Subcell Pins (for proper extraction)" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal1 + ?buttonText "Metal1" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal2 + ?buttonText "Metal2" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal3 + ?buttonText "Metal3" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal4 + ?buttonText "Metal4" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal5 + ?buttonText "Metal5" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal6 + ?buttonText "Metal6" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal7 + ?buttonText "Metal7" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal8 + ?buttonText "Metal8" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIPreroutePins_Form_Metal9 + ?buttonText "Metal9" + ?defValue t ) + ) ) ) + ( hiCreateAppForm + ?name `UIPreroutePins_Form + ?formTitle "PreRoute Close-By Pins" + ?fields Fields + ?callback "( UIPreroutePinsFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/.menu new file mode 100644 index 0000000000..bd722f9379 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/.menu @@ -0,0 +1 @@ +( list "Route" "UIRoute" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Clean.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Clean.il new file mode 100644 index 0000000000..ae0657f6ee --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Clean.il @@ -0,0 +1,292 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "RouteClean" "UIRouteClean" ) + +( UICreateMenuItemCallBack + `UIRouteCleanCB + (lambda () + ( hiDisplayForm UIRouteClean_Form ) ) ) + +( UICreateAction + 'UIRouteCleanFormCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) + ( DirectiveTable + ( CellInfoGetTableForCellName + "null" + ( sprintf + nil + "%s/share/Fulcrum" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ) ) + + ( Area + (when UIRouteClean_Form->UIRouteClean_Form_Area->value + ( enterBox ?prompts ( list "Select area to clean" ) ) ) ) + ) + + (cond ( + ( PinUtilFindPRBoundShape BoundaryLPP CellView ) + (let ( + ( MetalLPPs + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Metal1->value + ( list Metal1LPP ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Metal2->value + ( list Metal2LPP ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Metal3->value + ( list Metal3LPP ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Metal4->value + ( list Metal4LPP ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Metal5->value + ( list Metal5LPP ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Metal6->value + ( list Metal6LPP ) ) + (if UIRouteClean_Form->UIRouteClean_Form_Metal7->value + ( list Metal7LPP ) ) ) ) ) ) ) ) ) ) + + +; (when UIRouteClean_Form->UIRouteClean_Form_OnGrid->value +; (let ( +; ( Command +; ( sprintf +; nil +; "%s/cast2skill --cast-path=%s --cell=%s --output-dir=%s --cadence-name --suppress-pins --root-only" +; ( PackageGetBinRoot ) +; ( ConfigFileGetValue TheCDSConfigTable "CAST_PATH" ) +; "standard.null.NULL" +; ( ConfigFileGetValue TheCDSConfigTable "CDS_CACHE_DIR" ) +; ) ) ) +; ( printf "%s\n" Command ) +; ( shell Command ) ) +; +; ( KeepOutDrawKeepOut +; CellView +; ( CellInfoGetTableForCellName +; "null" +; ( sprintf +; nil +; "%s/ildirectives" +; ( ConfigFileGetValue +; TheCDSConfigTable +; "CDS_CACHE_DIR" ) ) ) +; ( mapcar +; (lambda ( LPP ) +; ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) +; ( ListIntersect HorizontalMetalLPPs MetalLPPs ) ) +; ( mapcar +; (lambda ( LPP ) +; ( KeepOutCreateRoutingLayerStruct LPP ?Purpose "dummy" ) ) +; ( ListIntersect VerticalMetalLPPs MetalLPPs ) ) +; BoundaryLPP +; UserUnitsPerMeter +; DirectiveUnitsPerMeter +; ( list GNDNetName VddNetName ) +; ( list nil ) ; nil +; t +; nil +; 0 +; ?Area Area +; ) ) + + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ( NotchesFillNotchesOnCellView + CellView + + ( append + (if UIRouteClean_Form->UIRouteClean_Form_NWell->value + ( list ( list "nwellFix" NWellLPP ) ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_NWell->value + ( list ( list "npFix" NImplantLPP ) ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_NWell->value + ( list ( list "ppFix" PImplantLPP ) ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Poly->value + ( list ( list "polyfix" PolyLPP ) + ( list "notchpoly" PolyLPP ) ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_AreaFix->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "area" 0 ) + MetalLPP ) ) + MetalLPPs ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_Notch->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "notch" 0 ) MetalLPP ) ) + MetalLPPs ) ) + (if UIRouteClean_Form->UIRouteClean_Form_Extension->value + ( mapcar + (lambda ( MetalLPP ) + ( rexCompile "M" ) + ( list ( rexReplace ( car MetalLPP ) "extension" 0 ) MetalLPP ) ) + MetalLPPs ) ) ) ) ) ) ) ) + + ( append + ( mapcar + (lambda ( MetalLPP ) + ( car MetalLPP ) ) + MetalLPPs ) + ( append + ( setof + Set + ( list + (if UIRouteClean_Form->UIRouteClean_Form_Poly->value + "POLY" ) + (if UIRouteClean_Form->UIRouteClean_Form_AreaFix->value + "AREA" ) + (if UIRouteClean_Form->UIRouteClean_Form_Notch->value + "NOTCH" ) + (if UIRouteClean_Form->UIRouteClean_Form_Extension->value + "EXTENSION" ) + (if UIRouteClean_Form->UIRouteClean_Form_NImp->value + "NIMP" ) + (if UIRouteClean_Form->UIRouteClean_Form_PImp->value + "PIMP" ) + (if UIRouteClean_Form->UIRouteClean_Form_NWell->value + "NWELL" ) ) + ( stringp Set ) ) + ( append + (if UIRouteClean_Form->UIRouteClean_Form_OnGrid->value + ( list + "M2_AREA_KEEPIN" + "M3_AREA_KEEPIN" + "M4_AREA_KEEPIN" + "M5_AREA_KEEPIN" + "M6_AREA_KEEPIN" + "M7_AREA_KEEPIN" ) ) + (if ( equal + ( VersionGetMajorVersion ) + "4" ) + ( list "VERSION_4X" ) ) ) ) ) + + ( sprintf + nil + "%s/share/Fulcrum/notch/fill_notches.assura.rules.all" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ?Area Area + ?NoPCells UIRouteClean_Form->UIRouteClean_Form_NoPCells->value + ) + ( foreach LPP + ( mapcar + (lambda ( LPP ) + ( list ( car LPP ) "dummy" ) ) + MetalLPPs ) + ( foreach Shape ( PinUtilGetAllShapesOnLPP CellView LPP ) + ( dbDeleteObject Shape ) ) ) + ) ) + ( + ( printf "No prBoundary shape!!!\n" ) ) + + ) ) ) ) + + + + ( UICreateComponent + "UIRouteClean_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Area + ?buttonText "Select Area" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_NoPCells + ?buttonText "Don't export gates/stacks" + ?defValue nil ) +; ( hiCreateBooleanButton +; ?name `UIRouteClean_Form_OnGrid +; ?buttonText "On Grid" +; ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Notch + ?buttonText "Notch" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_AreaFix + ?buttonText "Area" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Extension + ?buttonText "Extension" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Poly + ?buttonText "Poly" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_NWell + ?buttonText "NWell" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_NImp + ?buttonText "N Implant" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_PImp + ?buttonText "P Implant" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal1 + ?buttonText "Metal 1" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal2 + ?buttonText "Metal 2" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal3 + ?buttonText "Metal 3" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal4 + ?buttonText "Metal 4" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal5 + ?buttonText "Metal 5" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal6 + ?buttonText "Metal 6" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean_Form_Metal7 + ?buttonText "Metal 7" + ?defValue t ) + ( hiCreateFormButton + ?name `UIRouteClean_Form_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Clean_Base_Layers_help.html\" )" ) + ) ) ) + ( hiCreateAppForm + ?name `UIRouteClean_Form + ?formTitle "Route Clean" + ?fields Fields + ?callback "( UIRouteCleanFormCB )" + ) + hiSetFormSize( UIRouteClean_Form list(601 630)) + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/CreateMidAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/CreateMidAbstract.il new file mode 100644 index 0000000000..c5d05b61ba --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/CreateMidAbstract.il @@ -0,0 +1,307 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Route/Keepout.il#15 $ +; $DateTime: 2004/09/22 19:55:39 $ +; $Author: khe $ +( list "Create Mid-level Abstract..." "UICreateMidAbstract" ) + + +( UICreateMenuItemCallBack + `UICreateMidAbstractCB + (lambda () + ( hiDisplayForm UICreateMidAbstract_Form ) + ) +) + + +( UICreateAction + 'UICreateMidAbstract_FormCB + (lambda () + (let ( cellListFile CellView CellList libName cellName file line Command OptionList bloatdialog ) + + bloatdialog=1 + ; bloatdialog == 1 means dialog returned Go Ahead Anyway + if( bloatdialog == 1 then + ; create list of cells to process + cellListFile = UICreateMidAbstract_Form->UICreateMidAbstract_Form_cellListFile->value + (cond (cellListFile=="" CellList = (list (UIGetCellView))) + (t + file = (infile cellListFile) + (cond (file==nil (printf "ERROR: can't read %s\n" cellListFile)) + (t + CellList = nil + (while (gets line file) + cellName = (StringUtilChompNewline line) + temp = (parseString cellName ".") + libName = nil + (for i 0 (length temp)-3 + libName = (append libName (list (nth i temp))) + ) + libName = (buildString libName ".") + CellView = (dbOpenCellViewByType libName cellName "layout") + (cond (CellView!=nil CellList = (cons CellView CellList)) + (t (printf "ERROR: can't open %s %s\n" libName cellName)) + ) + ) + (close file) + ) + ) + ) + ) + + ; create abstracts for all CellViews in CellList + (foreach CellView CellList + nrCreateAbstractCB( CellView + ?ERASE_POWERGRID UICreateMidAbstract_Form->UICreateMidAbstract_Form_ErasePowerGrid->value + ?PIN_CUTOUT UICreateMidAbstract_Form->UICreateMidAbstract_Form_PIN_CUTOUT->value + ?PIN_LENGTH UICreateMidAbstract_Form->UICreateMidAbstract_Form_PIN_LENGTH->value + ?M1BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M1BLOAT->value + ?M2BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M2BLOAT->value + ?M3BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M3BLOAT->value + ?M4BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M4BLOAT->value + ?M5BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M5BLOAT->value + ?M6BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M6BLOAT->value + ?M7BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M7BLOAT->value + ?M8BLOAT UICreateMidAbstract_Form->UICreateMidAbstract_Form_M8BLOAT->value + ?useAbstractSubcells UICreateMidAbstract_Form->UICreateMidAbstract_Form_useAbstractSubcells->value + ?keepLayoutSubcells UICreateMidAbstract_Form->UICreateMidAbstract_Form_keepLayoutSubcells->value + ?allbloat UICreateMidAbstract_Form->UICreateMidAbstract_Form_AllBloat->value + ?PowerNets UICreateMidAbstract_Form->UICreateMidAbstract_Form_PowerNets->value + ?NO_HOLES_ABOVE_PINS UICreateMidAbstract_Form->UICreateMidAbstract_Form_NoHolesAbovePins->value + ?targetViewName UICreateMidAbstract_Form->UICreateMidAbstract_Form_targetViewName->value + ?M4PowerNets UICreateMidAbstract_Form->UICreateMidAbstract_Form_M4PowerNets->value + ?M5PowerNets UICreateMidAbstract_Form->UICreateMidAbstract_Form_M5PowerNets->value + ?M6PowerNets UICreateMidAbstract_Form->UICreateMidAbstract_Form_M6PowerNets->value + ?M7PowerNets UICreateMidAbstract_Form->UICreateMidAbstract_Form_M7PowerNets->value + ) + + ; create options list (all options but cellListFile in same order as form): + ; ErasePowerGrid useAbstractSubcells keepLayoutSubcells PowerNets targetViewName CUTOUT LENGTH M1-M8BLOAT + OptionList = sprintf( nil + "Create Mid-level Abstract options: %s %s %s %s %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %s %s" + (B2S UICreateMidAbstract_Form->UICreateMidAbstract_Form_ErasePowerGrid->value) + (B2S UICreateMidAbstract_Form->UICreateMidAbstract_Form_useAbstractSubcells->value) + (B2S UICreateMidAbstract_Form->UICreateMidAbstract_Form_keepLayoutSubcells->value) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_targetViewName->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_PIN_CUTOUT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_PIN_LENGTH->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M1BLOAT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M2BLOAT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M3BLOAT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M4BLOAT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M5BLOAT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M6BLOAT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M7BLOAT->value + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M8BLOAT->value + (B2S UICreateMidAbstract_Form->UICreateMidAbstract_Form_PowerNets->value) + (B2S UICreateMidAbstract_Form->UICreateMidAbstract_Form_NoHolesAbovePins->value) + ) + + ; log abstract options + Command = sprintf( nil + "%s/createAbstractCellLog --cell=%s:%s:%s --client-spec=%s --dfII-dir=%s --opt-str=\"%s\"" + PackageGetBinRoot( ) + CellView~>libName + CellView~>cellName + CellView~>viewName + ConfigFileGetValue( TheCDSConfigTable "P4CLIENT" ) + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + OptionList + ) + printf( "Update abstract log.\n%s\n" Command ) + shell( Command ) + ) + ) + ) + ) +) + +; stupid helper function to turn a boolean as a string +(defun B2S (b) + (cond (b "t") + (t "nil") + ) + ) + +( UICreateComponent + "UICreateMidAbstract_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_ErasePowerGrid + ?buttonText "Erase power grid" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_useAbstractSubcells + ?buttonText "Preserve keepout from abstract_edit/abstract subcells" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_keepLayoutSubcells + ?buttonText "Keep layout subcells even if abstract views exist" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_AllBloat + ?buttonText "Ignore subcells entirely (faster for flood-filling)" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_PowerNets + ?buttonText "Create M3 pins for Vdd/GND" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_M4PowerNets + ?buttonText "Create M4 pins for Vdd/GND" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_M5PowerNets + ?buttonText "Create M5 pins for Vdd/GND" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_M6PowerNets + ?buttonText "Create M6 pins for Vdd/GND" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_M7PowerNets + ?buttonText "Create M7 pins for Vdd/GND" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateMidAbstract_Form_NoHolesAbovePins + ?buttonText "Don't cut holes above buried pins" + ?defValue nil ) + ( hiCreateStringField + ?name `UICreateMidAbstract_Form_cellListFile + ?prompt "Cell list filename" + ?defValue "" ) + ( hiCreateStringField + ?name `UICreateMidAbstract_Form_targetViewName + ?prompt "Target view name" + ?defValue "abstract" ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_PIN_CUTOUT + ?prompt "Pin Cut Out" + ?defValue 0.36 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_PIN_LENGTH + ?prompt "Pin Length" + ?defValue 2.88 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M1BLOAT + ?prompt "Metal 1 Bloat (negative means floodfill)" + ?defValue -1.0 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M2BLOAT + ?prompt "Metal 2 Bloat (negative means floodfill)" + ?defValue -1.0 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M3BLOAT + ?prompt "Metal 3 Bloat (negative means floodfill)" + ?defValue -1.0 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M4BLOAT + ?prompt "Metal 4 Bloat (negative means floodfill)" + ?defValue -1.0 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M5BLOAT + ?prompt "Metal 5 Bloat (negative means floodfill)" + ?defValue -1.0 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M6BLOAT + ?prompt "Metal 6 Bloat (negative means floodfill)" + ?defValue 2.88 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M7BLOAT + ?prompt "Metal 7 Bloat (negative means floodfill)" + ?defValue 2.88 ) + ( hiCreateFloatField + ?name `UICreateMidAbstract_Form_M8BLOAT + ?prompt "Metal 8 Bloat (negative means floodfill)" + ?defValue 0.0 ) + ( hiCreateFormButton + ?name `UICreateMidAbstract_Form_loadOptions + ?buttonText "Load Previous Run Options" + ?callback "UICreateMidAbstract_LoadOptions(UIGetCellView())" ) + ( hiCreateFormButton + ?name `UICreateMidAbstract_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Mid-level_Abstract_help.html\" )" ) + ) + ) + ) + ( hiCreateAppForm + ?name `UICreateMidAbstract_Form + ?formTitle "Create Mid-level Abtract" + ?fields Fields + ?callback "( UICreateMidAbstract_FormCB )" + ) + hiSetFormSize( UICreateMidAbstract_Form list(601 635)) + ) + ) + ) +) + + +; function to read abstract.log options and update form +defun( UICreateMidAbstract_LoadOptions ( CellView ) + let( (LogFile Success Options Msg) + LogFile = strcat( "/" + buildString( reverse( cddr( reverse( parseString( CellView~>fileName "/")))) "/") + "/abstract.log") + Success = nil + pin = infile( LogFile ) + if( pin then + Options = car( ReadFileReadFileLines( LogFile )) + if( strncmp( "Create Mid-level Abstract options:" Options 34) == 0 then + Options = cddddr( parseString( Options )) + if( length(Options) >= 14 then + UICreateMidAbstract_Form->UICreateMidAbstract_Form_ErasePowerGrid->value = car(Options) == "t" + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_useAbstractSubcells->value = car(Options) == "t" + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_keepLayoutSubcells->value = car(Options) == "t" + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_targetViewName->value = car(Options) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_PIN_CUTOUT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_PIN_LENGTH->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M1BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M2BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M3BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M4BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M5BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M6BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M7BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_M8BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_PowerNets->value = car(Options) == "t" + Options = cdr(Options) + UICreateMidAbstract_Form->UICreateMidAbstract_Form_NoHolesAbovePins->value = car(Options) == "t" + Success = t + printf( "Options loaded from %s" LogFile ) + ) + ) + ) + close(pin) + + ; if unable to load options display error message + if( !Success then + Msg = strcat( "Attempt to load options FAILED.\nOptions file: " LogFile ) + hiDisplayAppDBox( + ?name `UICreateMidAbstract_LoadOptions_StatusDbox + ?dboxBanner "Load options FAILED" + ?dboxText Msg + ?buttonLayout 'Close + ) + printf( "%s" Msg) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/DrawPlugs.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/DrawPlugs.il new file mode 100644 index 0000000000..be8002f896 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/DrawPlugs.il @@ -0,0 +1,170 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "DrawPlugs" "UIDrawPlugs" ) + +( UICreateMenuItemCallBack + `UIDrawPlugsCB + (lambda () + ( hiDisplayForm UIDrawPlugs_Form ) ) ) + + +(defun UIDrawPlugsGetCellRegionData ( CellView ) + ( PlacementRegionsScrapeCellRegionDataFromCellView + CellView + ( getq CellView instances ) + NChainLibCellPairRegExs + PChainLibCellPairRegExs + GateLibCellPairRegExs + NPlugLibCellPairRegExs + PPlugLibCellPairRegExs + ( times UserUnitsPerMeter EvilGatePRegionOffset ) + ( times UserUnitsPerMeter MinWellSpacing ) + BoundaryLPP + 0.0 + ( times UserUnitsPerMeter MinWellSpacing ) + ) ) + +( UICreateAction + `UIDrawPlugs_DrawWellCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + (let ( + ( CellRegionData + ( UIDrawPlugsGetCellRegionData CellView ) + ) ) + ( PlacementRegionsDrawCellRegionData + CellView + CellRegionData + PWellLPP + NWellLPP ) ) ) ) ) + +( UICreateAction + `UIDrawPlugs_ConnectPlugsCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + ( foreach NRegionPlug + ( cadr ( NameFilterInstances + ( getq CellView instances ) + ( list ( list WellPlugLibrary + PWellPlugCellName ) ) ) ) + ( PlugsForceConnectPlug + NRegionPlug + CellView + GNDNetName + WellPlugTerminalName ) ) + + ( foreach PRegionPlug + ( cadr ( NameFilterInstances + ( getq CellView instances ) + ( list ( list WellPlugLibrary + NWellPlugCellName ) ) ) ) + ( PlugsForceConnectPlug + PRegionPlug + CellView + VddNetName + WellPlugTerminalName ) ) + ) ) ) + +( UICreateAction + `UIDrawPlugs_DrawPlugsCB + (lambda () + ( UIDrawPlugsAndImplant nil ) ) ) + +( UICreateAction + `UIDrawPlugs_DrawImplantCB + (lambda () + ( UIDrawPlugsAndImplant t ) ) ) + +(defun UIDrawPlugsAndImplant ( Mode ) + (let ( + ( CellView ( UIGetCellView ) ) ) + (let ( + ( WorkingDir + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ( PlugDRCRuleFile + ( sprintf + nil + "%s/share/Fulcrum/plugs/plugs.assura.rules" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) ) + ( CellRegionData + ( UIDrawPlugsGetCellRegionData CellView ) + ) + ) + ( PlugsDrawPlugsOnCellView + CellView + CellRegionData + WorkingDir + PlugDRCRuleFile + GNDNetName + VddNetName + ( DrawImplantFindPlugs + CellView + WellPlugLibrary + PWellPlugCellName + WellPlugViewName + PImplantLPP + ( times EvilGatePRegionOffset UserUnitsPerMeter ) + NImplantLPP + ContactLPP ) + ( DrawImplantFindPlugs + CellView + WellPlugLibrary + NWellPlugCellName + WellPlugViewName + NImplantLPP + ( times EvilGatePRegionOffset UserUnitsPerMeter ) + NImplantLPP + ContactLPP ) + WellPlugLibrary + PWellPlugCellName + NWellPlugCellName + WellPlugViewName + WellPlugLPP + NImplantLPP + PImplantLPP + ( times UserUnitsPerMeter WellPlugEffectiveRadius ) + ( times UserUnitsPerMeter MinWellSpacing ) + ?LeaveMess t + ?DrawPlugs ( not Mode ) + ?DrawImplant Mode + ) ) ) ) + + + +( UICreateComponent + "UIDrawPlugs_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateButton + ?name `UIDrawPlugs_Form_DrawWell + ?buttonText "Draw Well" + ?callback "( UIDrawPlugs_DrawWellCB )" ) + ( hiCreateButton + ?name `UIDrawPlugs_Form_DrawPlugs + ?buttonText "Draw Plugs" + ?callback "( UIDrawPlugs_DrawPlugsCB )" ) + ( hiCreateButton + ?name `UIDrawPlugs_Form_DrawImplant + ?buttonText "Draw Implied Implant" + ?callback "( UIDrawPlugs_DrawImplantCB )" ) + ( hiCreateButton + ?name `UIDrawPlugs_Form_ConnectPlugs + ?buttonText "ConnectPlugs" + ?callback "( UIDrawPlugs_ConnectPlugsCB )" ) + ) ) ) + ( hiCreateAppForm + ?name `UIDrawPlugs_Form + ?formTitle "Draw Plugs/Implant" + ?fields Fields + ) ) ) ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Keepout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Keepout.il new file mode 100644 index 0000000000..b5863f83d6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Keepout.il @@ -0,0 +1,170 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Create Abstract Views" "UIKeepout" ) + +( UICreateMenuItemCallBack + `UIKeepoutCB + (lambda () + ( hiDisplayForm UIKeepout_Form ) ) ) + +( UICreateAction + `UIKeepout_FormCB + (lambda () nil ) ) + + +( UICreateAction + 'UIKeepout_DrawRoutingCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + ( KeepOutCreateRoutingView + CellView + ( getq CellView libName ) + ( getq CellView cellName ) + UIKeepout_Form->UIKeepout_Form_RoutingViewName->value + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/keepout.rules" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + + ( mapcar + (lambda ( LPP ) + ( KeepOutCreateRoutingLayerStruct LPP ) ) + ( ListAppend + (if UIKeepout_Form->UIKeepout_Form_Metal3->value + ( list Metal3LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal5->value + ( list Metal5LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal7->value + ( list Metal7LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal4->value + ( list Metal4LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal6->value + ( list Metal6LPP ) ) ) ) + + ( list GNDNetName VddNetName ) ) + ) ) ) + + +( UICreateAction + 'UIKeepout_DrawAbstractCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + ( AbstractCreateAbstractView + CellView + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/abstract.rul" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ViaLayerFormat + MetalLayerFormat + ( ListAppend + (if UIKeepout_Form->UIKeepout_Form_Metal3->value + ( list Metal3LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal4->value + ( list Metal4LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal5->value + ( list Metal5LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal6->value + ( list Metal6LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal7->value + ( list Metal7LPP ) ) + ) + + ( ListAppend + (if UIKeepout_Form->UIKeepout_Form_Metal3->value + ( list Metal3LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal4->value + ( list Metal4LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal5->value + ( list Metal5LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal6->value + ( list Metal6LPP ) ) + (if UIKeepout_Form->UIKeepout_Form_Metal7->value + ( list Metal7LPP ) ) + ) + + ( ListAppend + (if ( or + UIKeepout_Form->UIKeepout_Form_Metal3->value + UIKeepout_Form->UIKeepout_Form_Metal4->value ) + ( list Via34LPP ) ) + (if ( or + UIKeepout_Form->UIKeepout_Form_Metal4->value + UIKeepout_Form->UIKeepout_Form_Metal5->value ) + ( list Via45LPP ) ) + (if ( or + UIKeepout_Form->UIKeepout_Form_Metal5->value + UIKeepout_Form->UIKeepout_Form_Metal6->value ) + ( list Via56LPP ) ) + (if ( or + UIKeepout_Form->UIKeepout_Form_Metal6->value + UIKeepout_Form->UIKeepout_Form_Metal7->value ) + ( list Via67LPP ) ) ) + + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + FoldableCellLibCellPairRegExs + GNDNetName + VddNetName + ContactLibrary + ContactMinCellNameFormat + ContactViewName + BoundaryLPP + ) ) ) ) + +( UICreateComponent + "UIKeepout_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateButton + ?name `UIKeepout_Form_DrawAbstract + ?buttonText "Create abstract view" + ?callback "( UIKeepout_DrawAbstractCB )" ) +; ( hiCreateButton +; ?name `UIKeepout_Form_DrawRouting +; ?buttonText "Create routing view" +; ?callback "( UIKeepout_DrawRoutingCB )" ) + ( hiCreateBooleanButton + ?name `UIKeepout_Form_Metal3 + ?buttonText "Metal 3" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIKeepout_Form_Metal4 + ?buttonText "Metal 4" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIKeepout_Form_Metal5 + ?buttonText "Metal 5" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIKeepout_Form_Metal6 + ?buttonText "Metal 6" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIKeepout_Form_Metal7 + ?buttonText "Metal 7" + ?defValue nil ) + + ( hiCreateStringField + ?name `UIKeepout_Form_RoutingViewName + ?prompt "Routing View Name" + ?defValue "routing" ) + + ) ) ) + ( hiCreateAppForm + ?name `UIKeepout_Form + ?formTitle "Abtract View" + ?fields Fields + ?callback "( UIKeepout_FormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Route.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Route.il new file mode 100644 index 0000000000..46da20cc96 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/Route.il @@ -0,0 +1,58 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +( list "Route" "UIRoute" ) + +( UICreateMenuItemCallBack + `UIRouteCB + (lambda () + UIRoute_Form->UIRoute_Form_VsrTcl->value = + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/router/leaf_vsr.tcl" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + UIRoute_Form->UIRoute_Form_ExcludeNet->value = + ( sprintf + nil + "%s/share/Fulcrum/cell_automation/router/leaf.excludenet" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ( hiDisplayForm UIRoute_Form ) ) + + ) + + +( UICreateAction + 'UIRoute_FormCB + (lambda () + ( UIWritePreferences + `UIRoute_Form ) + (RouteLeaf) + ) +) + +( UICreateComponent + "UIRoute_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateStringField + ?name `UIRoute_Form_VsrTcl + ?prompt "Vsr Tcl File" + ?defValue "" ) + ( hiCreateStringField + ?name `UIRoute_Form_ExcludeNet + ?prompt "Exclude Net File" + ?defValue "" ) + ) ) ) + ( hiCreateAppForm + ?name `UIRoute_Form + ?formTitle "Route" + ?fields Fields + ?callback "( UIRoute_FormCB )" + ) ) ) + ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/ViaExtension.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/ViaExtension.il new file mode 100644 index 0000000000..721837d51c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Route/ViaExtension.il @@ -0,0 +1,101 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/Route/Clean.il#17 $ +; $DateTime: 2005/02/14 13:21:27 $ +; $Author: khe $ + +( list "RouteClean2:Fix Via Extension" "UIRouteClean2" ) + +( UICreateMenuItemCallBack + `UIRouteClean2CB + (lambda () + ( hiDisplayForm UIRouteClean2_Form ) ) ) + +( UICreateAction + 'UIRouteClean2FormCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) + ( DirectiveTable + ( CellInfoGetTableForCellName + "null" + ( sprintf + nil + "%s/share/Fulcrum" + ( ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ) )) + + + (cond (( PinUtilFindPRBoundShape BoundaryLPP CellView ) + + ( createDir ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) + ( NotchesFillNotchesOnCellView + CellView + append( + (if UIRouteClean2_Form->UIRouteClean2_Form_CONT->value + list( list( "newCont_1" list( "CONT" "dummy1")) + list( "newCont_2" list( "CONT" "dummy2")))) + append( + (if UIRouteClean2_Form->UIRouteClean2_Form_VIA12->value + list( list( "newVia1_1" list( "VIA12" "dummy1")) + list( "newVia1_2" list( "VIA12" "dummy2")) + list( "newVia1_3" list( "VIA12" "dummy3")) + list( "newVia1_4" list( "VIA12" "dummy4")))) + (if UIRouteClean2_Form->UIRouteClean2_Form_VIA23->value + list( list( "newVia2_1" list( "VIA23" "dummy1")) + list( "newVia2_2" list( "VIA23" "dummy2")) + list( "newVia2_3" list( "VIA23" "dummy3")) + list( "newVia2_4" list( "VIA23" "dummy4")))) + )) + + setof( Set + list( + (if UIRouteClean2_Form->UIRouteClean2_Form_CONT->value + "CONT" ) + (if UIRouteClean2_Form->UIRouteClean2_Form_VIA12->value + "VIA12" ) + (if UIRouteClean2_Form->UIRouteClean2_Form_VIA12->value + "VIA23" )) + stringp( Set ) ) + + sprintf( nil + "%s/share/Fulcrum/notch/fill_notches.assura.rules.all" + ConfigFileGetValue( TheCDSConfigTable "FULCRUM_PDK_ROOT" ) ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + dbSave( CellView ) + nrFixViaExtension( CellView ?SkipAssuraRun t ) + ) + ( t printf( "No prBoundary shape!!!\n" ) ) + ) + ) + ) +) + + ( UICreateComponent + "UIRouteClean2_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UIRouteClean2_Form_CONT + ?buttonText "M1_POLY1_minL" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean2_Form_VIA12 + ?buttonText "M2_M1_minL" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIRouteClean2_Form_VIA23 + ?buttonText "M3_M2_minL" + ?defValue t ) + + ) ) ) + ( hiCreateAppForm + ?name `UIRouteClean2_Form + ?formTitle "Route Clean 2: Fix Via Extension" + ?fields Fields + ?callback "( UIRouteClean2FormCB )" + ) ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/.menu new file mode 100644 index 0000000000..7e2104c1e5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/.menu @@ -0,0 +1 @@ +( list "Chains" "UIChains" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Fold.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Fold.il new file mode 100644 index 0000000000..e6f324e8bb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Fold.il @@ -0,0 +1,87 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +( list "Fold Chains" "UIFoldChains" ) + +( UICreateMenuItemCallBack + `UIFoldChainsCB + (lambda () + ( hiDisplayForm UIFoldChains_Form ) ) ) + +( UICreateAction + 'UIFoldChainsFormCB + (lambda () + (let ( + ( SelectedChains ( cadr ( NameFilterInstances + ( setof Selected ( geGetSelectedSet ) + ( and ( equal ( getq Selected objType ) "inst" ) + ( equal ( getq Selected cellView ) ( UIGetCellView ) ) ) ) + ChainLibCellPairRegExs ) ) ) ) + + + ( RefoldRefoldChains + ( UIGetCellView ) + SelectedChains + ChainLibCellPairRegExs + UserUnitsPerMeter + ( equal UIFoldChains_Form->UIFoldChains_Extent->value "Entire Domain" ) + (if ( not UIFoldChains_Form->UIFoldChains_OverrideFolds->value ) + ( RefoldGetDefaultFoldFunc + ( UIGetCellView ) + UIFoldChains_Form->UIFoldChains_ColumnWidth->value + UserUnitsPerMeter + ManufacturingGrid + UIFoldChains_Form->UIFoldChains_PreferEvenFolds->value + ) + ( RefoldGetOverrideFoldsFoldFunc + ( UIGetCellView ) + UIFoldChains_Form->UIFoldChains_ExplicitFolds->value + ManufacturingGrid + ) ) + GNDNetName + VddNetName + ) ) ) ) + + + + +( UICreateComponent + "UIFoldChains_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateCyclicField + ?name `UIFoldChains_Extent + ?choices ( list "Selected" "Entire Domain" ) + ?defValue "Selected" + ?prompt "Fold..." ) + ( hiCreateBooleanButton + ?name `UIFoldChains_OverrideFolds + ?defValue nil + ?buttonText "Override Folds" ) + ( hiCreateBooleanButton + ?name `UIFoldChains_PreferEvenFolds + ?defValue t + ?buttonText "Prefer Even Folds" ) + ( hiCreateIntField + ?name `UIFoldChains_ExplicitFolds + ?prompt "Folds" ) + ( hiCreateFloatField + ?name `UIFoldChains_ColumnWidth + ?prompt "Column Width" ) + + ) ) ) + ( hiCreateAppForm + ?name `UIFoldChains_Form + ?formTitle "Fold Chains" + ?fields Fields + ?callback "( UIFoldChainsFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Inline.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Inline.il new file mode 100644 index 0000000000..0400e229f9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Inline.il @@ -0,0 +1,179 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Stack.il#1 $ +; $DateTime: 2005/11/07 15:21:21 $ +; $Author: aubrey $ + + +( list "Inline Gate to Stacks" "UIInlineGates" ) + +defun( khWithinBBox (rect bBox) +; test if rect is inside bBox + leftEdge(rect)>=leftEdge(bBox) && + rightEdge(rect)<=rightEdge(bBox) && + bottomEdge(rect)>=bottomEdge(bBox) && + topEdge(rect)<=topEdge(bBox) +) + + +defun( khConnectShapes ( fig allFigs ) +; propagates connectivy for fig to all connecting shapes + let((shapes shape filterLPPs) + cond( + (fig~>lpp==Metal2LPP filterLPPs=list( Metal2LPP Via23LPP Via12LPP )) + (fig~>lpp==Via12LPP filterLPPs=list( Metal1LPP Metal2LPP )) + (fig~>lpp==Metal1LPP filterLPPs=list( Metal1LPP ContactLPP Via12LPP )) + (fig~>lpp==ContactLPP filterLPPs=list( Metal1LPP PolyLPP )) + (fig~>lpp==PolyLPP filterLPPs=list( ContactLPP PolyLPP )) + ) + shapes=setof( shape dbGetTrueOverlaps( fig~>cellView fig~>bBox ) shape~>net==nil && member( shape~>lpp filterLPPs) && member( shape allFigs )) + foreach( shape shapes + dbAddFigToNet( shape fig~>net) + khConnectShapes( shape allFigs ) + ) + ) +) + +defun( khConnectInstances ( instances allFigs ) +; connects instTerms of instances with shape that overlaps and has connectivity + let((inst instTerm shapes shape net fig pinRect) + foreach( inst instances + foreach( instTerm inst~>instTerms + net=nil + foreach( pin instTerm~>term~>pins + fig=pin~>fig + pinRect=dbTransformBBox( fig~>bBox inst~>transform ) + shapes=setof( shape dbGetTrueOverlaps( inst~>cellView pinRect ) shape~>net!=nil && shape~>lpp==fig~>lpp && member( shape allFigs )) + if(shapes then + net=car(shapes)~>net + dbCreateConn(net inst instTerm~>term) + ) + ) + if( net!=nil then + ; feed through connectivity to all other shapes that overlap instTerms + foreach( pin instTerm~>term~>pins + fig=pin~>fig + pinRect=dbTransformBBox( fig~>bBox inst~>transform ) + shapes=setof( shape dbGetTrueOverlaps( inst~>cellView pinRect ) shape~>net==nil && shape~>lpp==fig~>lpp && member( shape allFigs )) + foreach( shape shapes + dbAddFigToNet( shape net) + khConnectShapes( shape allFigs ) + ) + ) + ) + ) + ) + ) +) +defun( khCreateInstTerms ( instances ) +; create instTerms for instances + let((inst term) + foreach( inst instances + foreach( term inst~>master~>terminals + if( term~>name!=GNDNetName && term~>name!=VddNetName then + dbCreateInstTerm( nil inst term ) + ) + ) + ) + ) +) + +defun( khInlineGateToStacks ( CellView inst + @key + ( DeletePcellWiring nil ) + ) + let((tempPinRectList term bBox instName pinRect pin stacks pstacks nstacks count figs obj allFigs) + tempPinRectList=nil + foreach( term inst~>instTerms + foreach( pin term~>term~>pins + pinRect=dbCreateRect( CellView pin~>fig~>lpp dbTransformBBox(pin~>fig~>bBox inst~>transform)) + tempPinRectList=cons( pinRect tempPinRectList ) + dbCreatePin( term~>net pinRect) + ) + ) + instName=inst~>name + bBox=inst~>bBox + leFlattenInst( inst 1 t nil ) + stacks=setof( obj dbGetTrueOverlaps( CellView bBox ) obj~>objType=="inst" && obj~>libName=="stack" ) + pstacks=cadr( NameFilterInstances( stacks PChainLibCellPairRegExs)) + nstacks=cadr( NameFilterInstances( stacks NChainLibCellPairRegExs)) + count=1 + foreach( obj pstacks + if(rexMatchp("I[0-9]*" obj~>name) then + obj~>name=sprintf(nil "%s.P%d" instName count) + count=count+1 + ) + ) + count=1 + foreach( obj nstacks + if(rexMatchp("I[0-9]*" obj~>name) then + obj~>name=sprintf(nil "%s.N%d" instName count) + count=count+1 + ) + ) + khCreateInstTerms( stacks ) + figs=setof( obj dbGetOverlaps( CellView bBox ) obj~>objType=="inst" && obj~>libName==TechLibName && khWithinBBox(obj~>bBox bBox)) + foreach( obj figs leFlattenInst( obj 1 t nil )) + allFigs=setof( obj dbGetOverlaps( CellView bBox ) obj~>objType!="inst" && khWithinBBox(obj~>bBox bBox)) + foreach( pinRect tempPinRectList khConnectShapes( pinRect allFigs )) + khConnectInstances( stacks allFigs ) + khConnectInstances( stacks allFigs ) + foreach( pinRect tempPinRectList dbDeleteObject( pinRect )) + if( DeletePcellWiring then + figs=setof( obj dbGetOverlaps( CellView bBox ) obj~>objType!="inst" && khWithinBBox(obj~>bBox bBox)) + foreach( obj figs dbDeleteObject( obj )) + ) + ) +) + +( UICreateMenuItemCallBack + `UIInlineGatesCB + (lambda () + ( hiDisplayForm UIInlineGates_Form ) ) ) + +( UICreateAction + 'UIInlineGatesFormCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) + ( Selected ( setof Fig ( geGetSelectedSet ) + ( equal Fig->objType "inst" ) + ) ) + instances inst + ) + instances= cadr( NameFilterInstances( Selected GateLibCellPairRegExs )) + if( UIInlineGates_Form->UIInlineGates_Extent->value=="Entire Domain" then + instances=cadr( NameFilterInstances( CellView~>instances GateLibCellPairRegExs )) + ) + foreach( inst instances + khInlineGateToStacks( CellView inst + ?DeletePcellWiring UIInlineGates_Form->UIInlineGates_DeletePcellWiring->value + ) + ) + ) ) ) + +( UICreateComponent + "UIInlineGates_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateCyclicField + ?name `UIInlineGates_Extent + ?choices ( list "Selected" "Entire Domain" ) + ?defValue "Selected" + ?prompt "Gate..." ) + ( hiCreateBooleanButton + ?name `UIInlineGates_DeletePcellWiring + ?buttonText "Delete Pcell Wiring" + ?defValue nil ) + ) ) ) + ( hiCreateAppForm + ?name `UIInlineGates_Form + ?formTitle "Inline Gate to Stacks" + ?fields Fields + ?callback "( UIInlineGatesFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Stack.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Stack.il new file mode 100644 index 0000000000..3cfef69913 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Stacks/Stack.il @@ -0,0 +1,156 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +( list "Stack Chains" "UIStackChains" ) + +( UICreateMenuItemCallBack + `UIStackChainsCB + (lambda () + ( hiDisplayForm UIStackChains_Form ) ) ) + +( UICreateAction + 'UIStackChainsFormCB + (lambda () + (let ( + ( Selected ( setof Fig + ( geGetSelectedSet ) + ( equal Fig->objType "inst" ) + ) ) ) + (let ( + ( GateFilter + ( NameFilterInstances + Selected + GateLibCellPairRegExs ) ) + ( NFilter + ( NameFilterInstances + Selected + NChainLibCellPairRegExs ) ) + ( PFilter + ( NameFilterInstances + Selected + PChainLibCellPairRegExs ) ) ) + + ( RefoldReStackChains + ( UIGetCellView ) + ( cadr GateFilter ) + StackLibraryName + GateSuperStackCellName + SuperStackViewName + GateChainPrefix + `SuperStackGetDefaultMergeFuncInfoLists_Gate + ( list UIStackChains_Form->UIStackChains_MaxNonPowerMergeHeight->value + UIStackChains_Form->UIStackChains_MaxPowerMergeHeight->value + UIStackChains_Form->UIStackChains_MaxMergeHeight->value + GNDNetName + VddNetName + ) + GNDNetName + VddNetName + GateLibCellPairRegExs + ( equal UIStackChains_Form->UIStackChains_Extent->value "Entire Domain" ) + nil + nil + UIStackChains_Form->UIStackChains_PreserveOrder->value ) + + ( RefoldReStackChains + ( UIGetCellView ) + ( cadr NFilter ) + StackLibraryName + NSuperStackCellName + SuperStackViewName + NChainPrefix + `SuperStackGetDefaultMergeFuncInfoLists_Chain + ( list UIStackChains_Form->UIStackChains_MaxNonPowerMergeHeight->value + UIStackChains_Form->UIStackChains_MaxPowerMergeHeight->value + UIStackChains_Form->UIStackChains_MaxMergeHeight->value ) + GNDNetName + VddNetName + NChainLibCellPairRegExs + ( equal UIStackChains_Form->UIStackChains_Extent->value "Entire Domain" ) + t + nil + UIStackChains_Form->UIStackChains_PreserveOrder->value ) + + ( RefoldReStackChains + ( UIGetCellView ) + ( cadr PFilter ) + StackLibraryName + PSuperStackCellName + SuperStackViewName + PChainPrefix + `SuperStackGetDefaultMergeFuncInfoLists_Chain + ( list UIStackChains_Form->UIStackChains_MaxNonPowerMergeHeight->value + UIStackChains_Form->UIStackChains_MaxPowerMergeHeight->value + UIStackChains_Form->UIStackChains_MaxMergeHeight->value ) + GNDNetName + VddNetName + PChainLibCellPairRegExs + ( equal UIStackChains_Form->UIStackChains_Extent->value "Entire Domain" ) + t + nil + UIStackChains_Form->UIStackChains_PreserveOrder->value ) + + (if ( equal UIStackChains_Form->UIStackChains_Inline->value t ) + ( InlineInstances + ( UIGetCellView ) + ( UIGetCellView ) + ( cadr ( NameFilterInstances + ( getq ( UIGetCellView ) instances ) + SuperStackLibCellPairRegExs ) ) + "netlist" + nil + FoldableCellLibCellPairRegExs + SuperStackLibCellPairRegExs + ?Verbose nil) ) + + UnStackAdjustDiffusion(Selected) + + UnStackAdjustPolyContacts(Selected) + + ) ) ) ) + +( UICreateComponent + "UIStackChains_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateCyclicField + ?name `UIStackChains_Extent + ?choices ( list "Selected" "Entire Domain" ) + ?defValue "Selected" + ?prompt "Stack..." ) + ( hiCreateFloatField + ?name `UIStackChains_MaxNonPowerMergeHeight + ?prompt "Maximum Non-Power Merge Height" + ?defValue 10.0 ) + ( hiCreateFloatField + ?name `UIStackChains_MaxPowerMergeHeight + ?prompt "Maximum Power Merge Height" + ?defValue 10.0 ) + ( hiCreateFloatField + ?name `UIStackChains_MaxMergeHeight + ?prompt "Maximum Merge Height" + ?defValue 10.0 ) + ( hiCreateBooleanButton + ?name `UIStackChains_Inline + ?buttonText "Inline Superstacks" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIStackChains_PreserveOrder + ?buttonText "Preserve Y Order of Stacked Instances" + ?defValue t ) + ) ) ) + ( hiCreateAppForm + ?name `UIStackChains_Form + ?formTitle "Stack Chains" + ?fields Fields + ?callback "( UIStackChainsFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/StartVLVS.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/StartVLVS.il new file mode 100644 index 0000000000..f8a8727132 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/StartVLVS.il @@ -0,0 +1,8 @@ +( list "Start VLVS" "UIvlvs" ) + +( UICreateMenuItemCallBack + `UIvlvsCB + (lambda () + + (TR_AssuraLVS) +)) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il new file mode 100644 index 0000000000..26e5bdc509 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/SyncToNetList.il @@ -0,0 +1,13 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +( list "Sync To NetList" "UISyncToNetList" ) + + +( UICreateMenuItemCallBack + `UISyncToNetListCB + (lambda () (SyncToNetlist ?CV (UIGetCellView))) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/.menu new file mode 100644 index 0000000000..6546d1a7d9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/.menu @@ -0,0 +1 @@ +( list "Verify" "UIVerify" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/Signoff.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/Signoff.il new file mode 100644 index 0000000000..dcf20bd057 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/Signoff.il @@ -0,0 +1,89 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Signoff" "UISignoff" ) + +( UICreateMenuItemCallBack + `UISignoffCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + (let ( + ( TargetSignoffFile + ( sprintf + nil + "%s/drc_signoff" + ( NameGetCellPathFromCellNameAndView + CellView->cellName + CellView->viewName ) ) ) + ( SignoffFile + ( ddGetStartup ( strcat CellView->cellName ".evd" ) ) ) + ) + + ( system ( sprintf nil "touch %s" TargetSignoffFile ) ) + + (if ( not SignoffFile ) + (error ( sprintf nil "signoff file %s doesn't exist. Create it by running assura ui or avview" SignoffFile ) ) ) + (if ( equal ( ConfigFileGetValue TheCDSConfigTable "P4LOG" ) "" ) + (error "Must specify P4LOG in envirnoment or cds.config" ) ) + (if ( equal ( ConfigFileGetValue TheCDSConfigTable "P4HOST" ) "" ) + (error "Must specify P4HOST in envirnoment or cds.config" ) ) + (if ( and + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) "" ) + ( or + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) "" ) + ( equal ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) "" ) ) ) + (error + "Must specify P4CONFIG or P4USER and P4CLIENT in envirnoment or cds.config" ) ) + (let ( + ( ErrorStr + ( CDSP4RunCommandOnLibCellViewTripples + ( sprintf nil "%s/%s \"--dfII-dir=%s\" --file=drc_signoff" + ( PackageGetBinRoot ) + (cond ( + ( isWritable TargetSignoffFile ) + "cdsp4add" ) + ( + "cdsp4edit" ) ) + ( NameGetDFIIDirFromCellName + CellView->cellName ) ) + ( ConfigFileGetValue TheCDSConfigTable "P4HOST" ) + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CLIENT" ) + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + "default" + ( list ( list + CellView->libName + CellView->cellName + CellView->viewName ) ) + 1 + ( ConfigFileGetValue TheCDSConfigTable "P4LOG" ) + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + t ) ) ) + (if ( stringp ErrorStr ) + ( println ErrorStr ) + (let ( + ( Append nil ) ) + + ( hiDisplayAppDBox + ?name `UISignoff_SaveDBox + ?dboxBanner "Hello" + ?dboxText "Choose Mode" + ?buttons ( list "Overwrite" "Append" ) + ?callback ( list "Append = nil" "Append = t" ) + ?buttonLayout `UserDefined + ) + + ( system + ( sprintf nil "%s/signoff %s %s %s" + ( PackageGetBinRoot ) + SignoffFile + (if Append ">>" ">" ) + TargetSignoffFile ) ) + ) ) ) ) ) ) ) + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/SignoffInclude.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/SignoffInclude.il new file mode 100644 index 0000000000..662db66db7 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Verify/SignoffInclude.il @@ -0,0 +1,63 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "Create Signoff Include" "UISignoffInclude" ) + +( UICreateMenuItemCallBack + `UISignoffIncludeCB + (lambda () + (let ( + ( CellView ( UIGetCellView ) ) ) + (let ( + ( RunName ( getq CellView cellName ) ) + ( TargetIncludeDir + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) ) ) + (let ( + ( TargetInclude + ( sprintf + nil "%s/%s.rsf" + TargetIncludeDir + RunName ) ) + ( SignoffFiles + ( mapcar + (lambda ( CellView ) + ( sprintf + nil + "%s/drc_signoff" + ( NameGetCellPathFromCellNameAndView + CellView->cellName + CellView->viewName ) ) ) + ( HierarchyGetAllCellsInTree + CellView + ( append + TechLibCellPairRegExs + ( append + StackLibCellPairRegExs + GateLibCellPairRegExs ) ) ) ) ) ) + + (let ( + ( Cmd + ( sprintf + nil + "/usr/intel/bin/perl -I%s/share/script/perl/ve/front-end -I%s/share/script/perl/ve/back-end %s/share/script/perl/ve/front-end/vfe VerificationType=SignOffInclude RunName=%s WorkingDir=%s FlattenCellRegEx.='%s' FlattenCellRegEx.='%s' FlattenCellRegEx.='%s' " + ( PackageGetPackageRoot ) + ( PackageGetPackageRoot ) + ( PackageGetPackageRoot ) + RunName + TargetIncludeDir + ( sprintf nil ".* layout %s" GateLibraryName ) + ( sprintf nil ".* layout %s" StackLibraryName ) + ( sprintf nil ".* .* %s" TechLibName ) + ) ) ) + + ( foreach SignoffFile SignoffFiles + (when ( isFile SignoffFile ) + ( setq Cmd ( strcat Cmd "SignOff.=" SignoffFile " " ) ) ) ) + + ( printf "%s\n" Cmd ) + ( system Cmd ) + ( printf "Include file is %s\n" TargetInclude ) + +) ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/.menu new file mode 100644 index 0000000000..c5e8bf12d4 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/.menu @@ -0,0 +1 @@ +( list "Wiring" "UIWiring" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/CheckBusWires.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/CheckBusWires.il new file mode 100644 index 0000000000..382341d1b5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/CheckBusWires.il @@ -0,0 +1,25 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +( list "Check BusWires" "UICheckBusWires" ) + + +( UICreateMenuItemCallBack + `UICheckBusWiresCB + (lambda () + (let (cv filein fileout cmd) + cv=(geGetWindowCellView) + filein=(sprintf nil "%s.wirelengths.sorted" cv->cellName) + fileout=(sprintf nil "%s.wirelengths.buswires" cv->cellName) + (CompareBusWireLengthsToManhattan filein fileout) + + cmd=(sprintf nil "sort -k2n,2 %s > %s.sorted" fileout fileout) + (shell cmd) + + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/InteractiveReport.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/InteractiveReport.il new file mode 100644 index 0000000000..6b94e1a1ca --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/InteractiveReport.il @@ -0,0 +1,19 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +( list "Interactive Report" "UICheckWireInteractive" ) + + +( UICreateMenuItemCallBack + `UICheckWireInteractiveCB + (lambda () + (let (cv filein fileout cmd) + cv=(geGetWindowCellView) + filein=(sprintf nil "%s.wirelengths" cv->cellName) + (CheckLengthReportForm (CheckLengthReadFullReport filein)) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportMBUFChannels.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportMBUFChannels.il new file mode 100644 index 0000000000..01ca83c545 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportMBUFChannels.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +( list "Report MBUF Channels" "UIReportMBUFChannels" ) + + +( UICreateMenuItemCallBack + `UIReportMBUFChannelsCB + (lambda () + (let (cv filename) + cv=(geGetWindowCellView) + filename=(sprintf nil "%s.bundled_channels" cv->cellName) + (ReportMBUFChannels filename ?filter_buswires t) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportWirelengths.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportWirelengths.il new file mode 100644 index 0000000000..426c061140 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Fulcrum/Wiring/ReportWirelengths.il @@ -0,0 +1,24 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +( list "Report Wirelengths" "UIReportWirelengths" ) + + +( UICreateMenuItemCallBack + `UIReportWirelengthsCB + (lambda () + (let (cv filename cellname cmd) + cv=(geGetWindowCellView) + cellname=cv->cellName + filename=(sprintf nil "%s.wirelengths" cellname) + + (CheckLengthReportAll cv filename) + cmd=(sprintf nil "sort -k5n,5 %s > %s.sorted" filename filename) + (shell cmd) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/.menu new file mode 100644 index 0000000000..0059c2e6ba --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/.menu @@ -0,0 +1,5 @@ +( list "Hercules" "UIHercules" ) + +load("/nfs/site/eda/tools/synopsys/icv/2011.09-SP2/common/etc/VUE/SkillVueMenu.il") + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/clearHighlights.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/clearHighlights.il new file mode 100644 index 0000000000..0f3bf3ff4e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/clearHighlights.il @@ -0,0 +1,7 @@ +list( "3.Clear VUE Highlights" "clearHighlights" ) + +( UICreateMenuItemCallBack + `clearHighlightsCB + (lambda () + snpsHvLayRemoveHilites() +) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/createTagView.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/createTagView.il new file mode 100644 index 0000000000..7b1155c476 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/createTagView.il @@ -0,0 +1,11 @@ +list( "0. Create Tag View" "createTagView" ) + + +( UICreateMenuItemCallBack + `createTagViewCB + (lambda () + let(( CellView cellName newCV) + CellView= UIGetCellView() + MakeLayoutTag(CellView) + ) +) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/runVue.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/runVue.il new file mode 100644 index 0000000000..872e9dfcda --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/runVue.il @@ -0,0 +1,146 @@ +list( "1.Run VUE" "runVUE" ) + +; hack to prevent loading errors +if( isFile(strcat(getShellEnvVar("ICV_HOME_DIR") "/etc/VUE/SkillVueWrapper.il")) then + load(strcat(getShellEnvVar("ICV_HOME_DIR") "/etc/VUE/SkillVueMenu.il")) +else + load("/nfs/site/eda/tools/synopsys/icv/2011.09-SP2/common/etc/VUE/SkillVueMenu.il") +) + +(defvar origVueSetLayTopCell nil) +(defvar origVueLayOpen nil) +(defvar origVueCmd nil) +(defvar runVueLibraryFormat nil) +(defvar runVueBlock nil) +(defvar runVueLibrary nil) + +(defun vueReplaceFunctions () + (unless origVueSetLayTopCell + (putd 'origVueSetLayTopCell (getd 'vueSetLayTopCell)) + (putd 'vueSetLayTopCell + (lambda (t_cellName t_uniqueCellName) + ;(printf "vueSetLayTopCell 1: %s %s\n" t_cellName t_uniqueCellName) + (let ((CID (NameStartRename "cell" "gds2" "cadence"))) + t_cellName = (NameDoRename CID t_cellName) + t_uniqueCellName = (NameDoRename CID t_uniqueCellName) + (ipcKillProcess CID) + ;(printf "vueSetLayTopCell 2: %s %s\n" t_cellName t_uniqueCellName) + (origVueSetLayTopCell t_cellName t_uniqueCellName))))) + + (unless origVueLayOpen + (putd 'origVueLayOpen (getd 'vueLayOpen)) + (putd 'vueLayOpen + (lambda (t_cellName @optional (t_uniqueCellName nil)) + ;(printf "vueLayOpen 1: %s %s\n" t_cellName t_uniqueCellName) + (let ((CID (NameStartRename "cell" "gds2" "cadence"))) + t_cellName = (NameDoRename CID t_cellName) + (if t_uniqueCellName + t_uniqueCellName = (NameDoRename CID t_uniqueCellName)) + (ipcKillProcess CID) + ;(printf "vueLayOpen 2: %s %s\n" t_cellName t_uniqueCellName) + (origVueLayOpen t_cellName t_uniqueCellName))))) + + ; in recent versions of ICV, user defined settings in .icv_vuerc are + ; overwritten by values auto-populated by SKILL, intercept those calls to + ; substitute with correct names + (unless origVueCmd + (putd 'origVueCmd (getd 'vueCmd)) + (putd 'vueCmd + (lambda (t_cmd) + ;(printf "vueCmd 1: %s\n" t_cmd) + (cond + ((and (StringStartsWith t_cmd "vueSetLayInfo -lib ") + runVueLibrary) + t_cmd = (sprintf nil "vueSetLayInfo -lib %s" runVueLibrary)) + ((and (StringStartsWith t_cmd "vueSetLayInfo -format ") + runVueLibraryFormat) + t_cmd = (sprintf nil "vueSetLayInfo -format %s" runVueLibraryFormat)) + ((and (StringStartsWith t_cmd "vueSetLayInfo -block ") + runVueBlock) + t_cmd = (sprintf nil "vueSetLayInfo -block %s" runVueBlock))) + ;(printf "vueCmd 2: %s\n" t_cmd) + (origVueCmd t_cmd)))) +) + +(defun translateName (type from to input) + (let ((CID (NameStartRename type from to)) output) + output = (NameDoRename CID input) + (ipcKillProcess CID) + output)) + +(defun createGDS2 (@key (CV (geGetEditCellView)) + (heap (nrGetMaxHeapSize)) + (output nil) + (outputRoot nil)) + (let (temp cid castname cmd pdkroot result) + temp = (ConfigFileGetValue TheCDSConfigTable "TEMP") + pdkroot = (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + (unless output + (sprintf output "%s/%s.gds2" temp CV->cellName)) + (unless outputRoot + outputRoot = (translateName "cell" "cadence" "gds2" CV->cellName)) + castname = (translateName "cell" "cadence" "cast" CV->cellName) + (sprintf cmd "gdsIIWrite --noproperties \ + --65mode=0 \ + --use-tag \ + --tag-orientation=MXR90 \ + --flatten-pcells \ + --max-heap-size='%dM' \ + --fulcrum-pdk-root='%s' \ + --working-dir='%s' \ + --cast-path='%s' \ + --dfII-dir='%s' \ + --cell='%s' \ + --view='%s' \ + --output='%s' \ + --output-root-cell-name='%s'" + heap + pdkroot + temp + (ConfigFileGetValue TheCDSConfigTable "CAST_PATH") + (ConfigFileGetValue TheCDSConfigTable "DFII_DIR") + castname + CV->viewName + output + outputRoot) + result = (shell cmd) + (unless result + (printf "Command returned non-zero status: %s\n" cmd)) + result)) + +(defun prepareICV (@key (CV (geGetEditCellView))) + (let ((custom CV->viewName == "custom_tag")) + (if !custom && (rexMatchp ".*_tag" CV->viewName) + (error "Cannot run on non-custom tag view!") + (let ((wid (geGetCellViewWindow CV)) + (gds2 (sprintf nil "%s/%s.gds2" + (ConfigFileGetValue TheCDSConfigTable "TEMP") + CV->cellName)) + (gdsname (translateName "cell" "cadence" "gds2" CV->cellName)) + port) + (unless (createGDS2 ?CV CV ?output gds2 ?outputRoot gdsname) + (error "Can't create a GDS2 file")) + (if !custom + (geChangeCellView wid + CV->libName + CV->cellName + (sprintf nil "%s_tag" CV->viewName) + "a")) + runVueLibraryFormat = "GDSII" + runVueBlock = gdsname + runVueLibrary = gds2 + port = (outfile ".icv_vuerc") + (fprintf port "vue_set runDirectoryField %s\n" + (ConfigFileGetValue TheCDSConfigTable "TEMP")) + (fprintf port "vue_set inputBlockField %s\n" gdsname) + (fprintf port "vue_set inputLibraryField %s\n" gds2) + (fprintf port "vue_set runsetFileField %s/share/Fulcrum/icv/drc.rul\n" + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT")) + (close port) + (vueRunVUE "-lay virtuoso"))))) + +(vueReplaceFunctions) + +( UICreateMenuItemCallBack + `runVUECB + (lambda () (prepareICV ?CV (UIGetCellView)))) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/setVueWindow.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/setVueWindow.il new file mode 100644 index 0000000000..36bd36242f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Hercules/setVueWindow.il @@ -0,0 +1,18 @@ +list( "2.Create Rotate View" "createRotateView" ) + +( UICreateMenuItemCallBack + `createRotateViewCB + (lambda () + let(( CellView cellName newCV) + CellView= UIGetCellView() + cellName=CellView~>cellName + if( rexMatchp( "_tag" cellName ) then + println("Can not run from an already rotated view") + else + newCV=dbOpenCellViewByType( CellView~>libName strcat(cellName "_tag") "layout" "maskLayout" "w") + dbCreateInstByMasterName( newCV CellView~>libName CellView~>cellName CellView~>viewName nil list(0 0) "MXR90" ) + dbSave(newCV) + geOpen(?lib newCV->libName ?cell newCV->cellName ?view newCV->viewName ?mode "a") + ) + ) +) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/.menu new file mode 100644 index 0000000000..098a057b9c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/.menu @@ -0,0 +1 @@ +( list "Nano" "UINano" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/.menu new file mode 100644 index 0000000000..375628cf16 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/.menu @@ -0,0 +1 @@ +( list "4.Create Abstracts" "UIAbstracts" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateLeafAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateLeafAbstract.il new file mode 100644 index 0000000000..c04e47390f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateLeafAbstract.il @@ -0,0 +1,292 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ +( list "Create Leaf Cell Abstract..." "UICreateLeafAbstract" ) + + +( UICreateMenuItemCallBack + `UICreateLeafAbstractCB + (lambda () + ( hiDisplayForm UICreateLeafAbstract_Form ) + ) +) + + +( UICreateAction + 'UICreateLeafAbstract_FormCB + (lambda () + (let ( cellListFile CellView CellList libName cellName file line Command OptionList ) + + ; create list of cells to process + cellListFile = UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_cellListFile->value + (cond (cellListFile=="" CellList = (list (UIGetCellView))) + (t + file = (infile cellListFile) + (cond (file==nil (printf "ERROR: can't read %s\n" cellListFile)) + (t + CellList = nil + (while (gets line file) + cellName = (StringUtilChompNewline line) + temp = (parseString cellName ".") + libName = nil + (for i 0 (length temp)-3 + libName = (append libName (list (nth i temp))) + ) + libName = (buildString libName ".") + CellView = (dbOpenCellViewByType libName cellName UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_sourceViewName->value) + (cond (CellView!=nil CellList = (cons CellView CellList)) + (t (printf "ERROR: can't open %s %s\n" libName cellName)) + ) + ) + (close file) + ) + ) + ) + ) + + ; create abstracts for all CellViews in CellList + (foreach CellView CellList + nrCreateAbstractCB( CellView + ?ERASE_POWERGRID UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_ErasePowerGrid->value + ?PIN_CUTOUT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PIN_CUTOUT->value + ?PIN_LENGTH UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PIN_LENGTH->value + ?M1BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M1BLOAT->value + ?M2BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M2BLOAT->value + ?M3BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M3BLOAT->value + ?M4BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M4BLOAT->value + ?M5BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M5BLOAT->value + ?M6BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M6BLOAT->value + ?M7BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M7BLOAT->value + ?M8BLOAT UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M8BLOAT->value + ?useAbstractSubcells UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_useAbstractSubcells->value + ?keepLayoutSubcells UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_keepLayoutSubcells->value + ?PowerNets UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PowerNets->value + ?PowerGridPitch UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PowerGridPitch->value + ?NO_HOLES_ABOVE_PINS UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_NoHolesAbovePins->value + ?targetViewName UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_targetViewName->value + ?CDCPowerGrid UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_CDCPowerGrid->value + ) + + ; create options list (all options but cellListFile in same order as form): + ; ErasePowerGrid useAbstractSubcells keepLayoutSubcells PowerNets targetViewName CUTOUT LENGTH M1-M8BLOAT + OptionList = sprintf( nil + "Create Leaf Cell Abstract options: %s %s %s %s %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %s %s" + (B2S UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_ErasePowerGrid->value) + (B2S UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_useAbstractSubcells->value) + (B2S UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_keepLayoutSubcells->value) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_targetViewName->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PIN_CUTOUT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PIN_LENGTH->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M1BLOAT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M2BLOAT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M3BLOAT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M4BLOAT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M5BLOAT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M6BLOAT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M7BLOAT->value + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M8BLOAT->value + (B2S UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PowerNets->value) + (B2S UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_NoHolesAbovePins->value) + ) + + ; log abstract options + Command = sprintf( nil + "%s/createAbstractCellLog --cell=%s:%s:%s --client-spec=%s --dfII-dir=%s --opt-str=\"%s\"" + PackageGetBinRoot( ) + CellView~>libName + CellView~>cellName + CellView~>viewName + ConfigFileGetValue( TheCDSConfigTable "P4CLIENT" ) + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + OptionList + ) + printf( "Update abstract log.\n%s\n" Command ) + shell( Command ) + ) + ) + ) +) + +; stupid helper function to turn a boolean as a string +(defun B2S (b) + (cond (b "t") + (t "nil") + ) + ) + +( UICreateComponent + "UICreateLeafAbstract_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UICreateLeafAbstract_Form_ErasePowerGrid + ?buttonText "Erase power grid" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateLeafAbstract_Form_useAbstractSubcells + ?buttonText "Preserve keepout from abstract_edit/abstract subcells" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateLeafAbstract_Form_keepLayoutSubcells + ?buttonText "Keep layout subcells even if abstract views exist" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateLeafAbstract_Form_PowerNets + ?buttonText "Create pins for Vdd/GND" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateLeafAbstract_Form_CDCPowerGrid + ?buttonText "CDC Power Grid" + ?defValue nil ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_PowerGridPitch + ?prompt "Power Grid Pitch" + ?defValue PowerGridPitch ) + ( hiCreateBooleanButton + ?name `UICreateLeafAbstract_Form_NoHolesAbovePins + ?buttonText "Don't cut holes above buried pins" + ?defValue nil ) + ( hiCreateStringField + ?name `UICreateLeafAbstract_Form_cellListFile + ?prompt "Cell list filename" + ?defValue "" ) + ( hiCreateStringField + ?name `UICreateLeafAbstract_Form_sourceViewName + ?prompt "Source View Name" + ?defValue "layout" ) + ( hiCreateStringField + ?name `UICreateLeafAbstract_Form_targetViewName + ?prompt "Target view name" + ?defValue "abstract" ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_PIN_CUTOUT + ?prompt "Pin Cut Out" + ?defValue 0.13 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_PIN_LENGTH + ?prompt "Pin Length" + ?defValue 2.4 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M1BLOAT + ?prompt "Metal 1 Bloat (negative means floodfill)" + ?defValue -1.0 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M2BLOAT + ?prompt "Metal 2 Bloat (negative means floodfill)" + ?defValue -1.0 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M3BLOAT + ?prompt "Metal 3 Bloat (negative means floodfill)" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M4BLOAT + ?prompt "Metal 4 Bloat (negative means floodfill)" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M5BLOAT + ?prompt "Metal 5 Bloat (negative means floodfill)" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M6BLOAT + ?prompt "Metal 6 Bloat (negative means floodfill)" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M7BLOAT + ?prompt "Metal 7 Bloat (negative means floodfill)" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateLeafAbstract_Form_M8BLOAT + ?prompt "Metal 8 Bloat (negative means floodfill)" + ?defValue 0.0 ) + ( hiCreateFormButton + ?name `UICreateLeafAbstract_Form_loadOptions + ?buttonText "Load Previous Run Options" + ?callback "UICreateLeafAbstract_LoadOptions(UIGetCellView())" ) + ( hiCreateFormButton + ?name `UICreateLeafAbstract_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Leaf-level_Abstract_help.html\" )" ) + ) + ) + ) + ( hiCreateAppForm + ?name `UICreateLeafAbstract_Form + ?formTitle "Create Leaf-level Abtract" + ?fields Fields + ?callback "( UICreateLeafAbstract_FormCB )" + ) + hiSetFormSize( UICreateLeafAbstract_Form list(601 635)) + ) + ) + ) +) + + +; function to read abstract.log options and update form +defun( UICreateLeafAbstract_LoadOptions ( CellView ) + let( (LogFile Success Options Msg) + LogFile = strcat( "/" + buildString( reverse( cddr( reverse( parseString( CellView~>fileName "/")))) "/") + "/abstract.log") + Success = nil + pin = infile( LogFile ) + if( pin then + Options = car( ReadFileReadFileLines( LogFile )) + if( strncmp( "Create Leaf-level Abstract options:" Options 34) == 0 then + Options = cddddr( parseString( Options )) + if( length(Options) >= 14 then + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_ErasePowerGrid->value = car(Options) == "t" + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_useAbstractSubcells->value = car(Options) == "t" + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_keepLayoutSubcells->value = car(Options) == "t" + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_targetViewName->value = car(Options) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PIN_CUTOUT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PIN_LENGTH->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M1BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M2BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M3BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M4BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M5BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M6BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M7BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_M8BLOAT->value = atof(car(Options)) + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_PowerNets->value = car(Options) == "t" + Options = cdr(Options) + UICreateLeafAbstract_Form->UICreateLeafAbstract_Form_NoHolesAbovePins->value = car(Options) == "t" + Success = t + printf( "Options loaded from %s" LogFile ) + ) + ) + ) + close(pin) + + ; if unable to load options display error message + if( !Success then + Msg = strcat( "Attempt to load options FAILED.\nOptions file: " LogFile ) + hiDisplayAppDBox( + ?name `UICreateLeafAbstract_LoadOptions_StatusDbox + ?dboxBanner "Load options FAILED" + ?dboxText Msg + ?buttonLayout 'Close + ) + printf( "%s" Msg) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateMidAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateMidAbstract.il new file mode 100644 index 0000000000..4757c72027 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateMidAbstract.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Abstracts +; +; reference function from Fulcrum/Route/CreateMidAbstract.il +; +( list "Create Mid-level Abstract..." "UICreateMidAbstract" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePowerGridAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePowerGridAbstract.il new file mode 100644 index 0000000000..08d5cd7c7d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePowerGridAbstract.il @@ -0,0 +1,11 @@ +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Abstracts +; +; reference function from CreateAbstract.il +; +( list "Create Power Grid Abstract..." "UIAutoPowerGridAbstract" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePrBound.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePrBound.il new file mode 100644 index 0000000000..eac6455ca5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePrBound.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Abstracts +; +; reference function from Floorplan/CreatePrBound.il +; +( list "Create prBound" "UICreatePrBound" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/ListMissingAbstracts.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/ListMissingAbstracts.il new file mode 100644 index 0000000000..970d44a327 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/ListMissingAbstracts.il @@ -0,0 +1,135 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Abstracts +; +( list "List Missing Abstracts..." "UIListMissingAbstracts" ) + + +; +; menu item callback +; +( UICreateMenuItemCallBack + `UIListMissingAbstractsCB + (lambda () + let((CellView) + CellView = UIGetCellView() + if(UIListMissingAbstracts_Form->UIListMissingAbstracts_CastPath->value == "default" then + UIListMissingAbstracts_Form->UIListMissingAbstracts_CastPath->value = + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + ) + if(UIListMissingAbstracts_Form->UIListMissingAbstracts_DfIIDir->value== "default" then + UIListMissingAbstracts_Form->UIListMissingAbstracts_DfIIDir->value= + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + ) + if(UIListMissingAbstracts_Form->UIListMissingAbstracts_CellListFile->value== "default" then + UIListMissingAbstracts_Form->UIListMissingAbstracts_CellListFile->value= + strcat( CellView->cellName ".flatten_cells_list" ) + ) + hiDisplayForm( UIListMissingAbstracts_Form ) + ) + ) +) + + +; +; form +; +( UICreateComponent + "UIListMissingAbstracts_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIListMissingAbstracts_CastPath + ?prompt "Cast Path" + ?defValue "default" ) + ( hiCreateStringField + ?name `UIListMissingAbstracts_DfIIDir + ?prompt "DfII Dir" + ?defValue "default" ) + ( hiCreateStringField + ?name `UIListMissingAbstracts_CellListFile + ?prompt "Cells List" + ?defValue "default" ) + ( hiCreateStringField + ?name `UIListMissingAbstracts_LogFile + ?prompt "Log Filename" + ?defValue "listMissingAbstracts.log" ) + ( hiCreateStringField + ?name `UIListMissingAbstracts_MaxHeapSize + ?prompt "Max Heap Size" + ?defValue "1800M" ) + ( hiCreateBooleanButton + ?name `UIListMissingAbstracts_RegenLeafList + ?buttonText "Regenerate Leaf Cell List" + ?defValue nil ) + ( hiCreateFormButton + ?name `UIListMissingAbstracts_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"List_Missing_Abstracts_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIListMissingAbstracts_Form + ?formTitle "List Missing Abstracts" + ?fields Fields + ?callback "( UIListMissingAbstractsFormCB )" + ) + ) + ) + ) +) + + + +; +; form callback +; +( UICreateAction + 'UIListMissingAbstractsFormCB + (lambda () + let( (CellView Command SumFileName Msg Lines fin) + CellView= UIGetCellView() + + ; delete summary file if it exists + nrDeleteToolSum( UIListMissingAbstracts_Form->UIListMissingAbstracts_LogFile->value ) + + fin=infile(UIListMissingAbstracts_Form->UIListMissingAbstracts_CellListFile->value) + if( fin==nil then + printf("CellListFile %s not exist. Creating CellListFile...\n" UIListMissingAbstracts_Form->UIListMissingAbstracts_CellListFile->value) + nrCreateCellList( CellView + UIListMissingAbstracts_Form->UIListMissingAbstracts_CellListFile->value + t ) + else + close(fin) + ) + ; invoke createAbstract + Command = sprintf( nil + "%s/listMissingAbstracts --cast-path=%s --cell-list=%s --design=%s --dfII-dir=%s --log=%s --max-heap-size=%s" + PackageGetBinRoot( ) + UIListMissingAbstracts_Form->UIListMissingAbstracts_CastPath->value + UIListMissingAbstracts_Form->UIListMissingAbstracts_CellListFile->value + CellView~>cellName + UIListMissingAbstracts_Form->UIListMissingAbstracts_DfIIDir->value + UIListMissingAbstracts_Form->UIListMissingAbstracts_LogFile->value + UIListMissingAbstracts_Form->UIListMissingAbstracts_MaxHeapSize->value + ) + if( UIListMissingAbstracts_Form->UIListMissingAbstracts_RegenLeafList->value then + Command = strcat( Command " --regen-leaf-list") + ) + printf( "%s\n" Command ) + shell( Command ) + + ; display results + nrDisplayToolStatus( "List Missing Abstracts" + sprintf( nil "List Missing Abstracts for %s" CellView~>cellName ) + UIListMissingAbstracts_Form->UIListMissingAbstracts_LogFile->value + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/.menu new file mode 100644 index 0000000000..5c590825ba --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/.menu @@ -0,0 +1 @@ +( list "5.Export Design Files" "UIExport" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/CreateTracksDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/CreateTracksDef.il new file mode 100644 index 0000000000..3587e05ecd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/CreateTracksDef.il @@ -0,0 +1,126 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Export +; +( list "5.Create Tracks DEF..." "UICreateTracksDef" ) + + +( UICreateMenuItemCallBack + `UICreateTracksDefCB + (lambda () + let(() + UICreateTracksDef_Form->UICreateTracksDef_RefDef->value = + strcat(UIGetCellView()~>cellName ".def") + UICreateTracksDef_Form->UICreateTracksDef_OutDef->value = + strcat(UIGetCellView()~>cellName "_tracks.def") + + hiDisplayForm( UICreateTracksDef_Form ) + ) + ) +) + + +( UICreateComponent + "UICreateTracksDef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateTracksDef_RefDef + ?prompt "Reference Design DEF Filename" + ?defValue "" ) + ( hiCreateStringField + ?name `UICreateTracksDef_OutDef + ?prompt "Output DEF Filename" + ?defValue "tracks.def" ) + ( hiCreateBooleanButton + ?name `UICreateTracksDef_E1of4 + ?buttonText "Use E1of4 Style Tracks" + ?defValue t ) + + ( hiCreateSeparatorField + ?name `UICreateFlattenView_sep1 ) + + ( hiCreateBooleanButton + ?name `UICreateTracksDef_AutoOffsets + ?buttonText "Use Auto-Generated Offsets" + ?defValue t ) + ( hiCreateFloatField + ?name `UICreateTracksDef_OffsetX + ?prompt " X Offset" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateTracksDef_OffsetY + ?prompt " Y Offset" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateTracksDef_OffsetE1of4X + ?prompt " E1of4 X Offset" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateTracksDef_OffsetE1of4Y + ?prompt " E1of4 Y Offset" + ?defValue 0.0 ) + + ( hiCreateSeparatorField + ?name `UICreateFlattenView_sep2 ) + + ( hiCreateFloatField + ?name `UICreateTracksDef_TrackPitch + ?prompt "Base Track Pitch" + ?defValue DefaultWiringPitch ) + + ( hiCreateFormButton + ?name `UICreateTracksDef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Tracks_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UICreateTracksDef_Form + ?formTitle "Create Tracks DEF" + ?fields Fields + ?callback "( UICreateTracksDefFormCB )" + ) + hiSetFormSize( UICreateTracksDef_Form list(601 585)) + ) + ) + ) +) + + +( UICreateAction + 'UICreateTracksDefFormCB + (lambda () + let( (Command) + Command = sprintf( nil + "%s/genTracks --refdef=%s --outfile=%s --track-pitch=%.3f" + PackageGetBinRoot( ) + UICreateTracksDef_Form->UICreateTracksDef_RefDef->value + UICreateTracksDef_Form->UICreateTracksDef_OutDef->value + UICreateTracksDef_Form->UICreateTracksDef_TrackPitch->value + ) + if( UICreateTracksDef_Form->UICreateTracksDef_AutoOffsets->value == nil then + Command = sprintf( nil "%s --offsetx=%.3f --offsety=%.3f --offset-e1of4x=%.3f --offset-e1of4y=%.3f" + Command + UICreateTracksDef_Form->UICreateTracksDef_OffsetX->value + UICreateTracksDef_Form->UICreateTracksDef_OffsetY->value + UICreateTracksDef_Form->UICreateTracksDef_OffsetE1of4X->value + UICreateTracksDef_Form->UICreateTracksDef_OffsetE1of4Y->value) + ) + if( UICreateTracksDef_Form->UICreateTracksDef_E1of4->value then + Command = sprintf( nil "%s --e1of4" Command) + ) + printf( "%s\n" Command ) + shell( Command ) + printf( "Create Tracks DEF finished.\n" ) + + ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignDef.il new file mode 100644 index 0000000000..168321f822 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignDef.il @@ -0,0 +1,136 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Export +; +( list "3.Export Design DEF..." "UIExportDesignDef" ) + + +( UICreateMenuItemCallBack + `UIExportDesignDefCB + (lambda () + let((CellView powerCellName Components RComponents) + CellView = UIGetCellView() + Components = parseString( CellView~>cellName "." ) + RComponents = reverse( Components ) + if( length(RComponents)>=3 then + powerCellName = sprintf( nil "%s_%s" cadr(RComponents) car(RComponents)) + powerCellName = sprintf( nil "%s.wires.%s_POWER_GRID_TIEOFF" + car( NameParseCellName( CellView~>cellName )) powerCellName ) + UIExportDesignDef_Form->UIExportDesignDef_BlockageCellName->value = powerCellName + ) + UIExportDesignDef_Form->UIExportDesignDef_DefFileName->value = + strcat( UIGetCellView()~>cellName ".def") + hiDisplayForm( UIExportDesignDef_Form ) + ) + ) +) + +( UICreateAction + 'UIExportDesignDefFormCB + (lambda () + let( (CellView pinmap mapfile tempdir Synchronous BlockageCellView) + CellView= UIGetCellView() + BlockageCellView= nil + Synchronous=UIExportDesignDef_Form->UIExportDesignDef_Synchronous->value + pinmap = nil + dirmap = defGenerateP2DTable( ( getq CellView cellName ) nil ) + (CanonicalizePins) + if( Synchronous then + pinmap = defGenerateC2VTable( ( getq CellView cellName ) nil ) ) + if( dirmap == nil then + let( ( basename cn ) + cn = ( getq CellView cellName ) + basename = cn + if(rexCompile( "\\.[^\\.]+$" ) then + basename=rexReplace( cn "" 0 ) ) + dirmap = defGenerateP2DTable( basename t ) + ) ) + if( Synchronous && ! pinmap then + let( ( basename cn ) + cn = ( getq CellView cellName ) + basename = cn + if(rexCompile( "\\.[^\\.]+$" ) then + basename=rexReplace( cn "" 0 ) ) + pinmap = defGenerateC2VTable( basename t ) + ) ) + if( UIExportDesignDef_Form->UIExportDesignDef_ExportBlockage->value then + BlockageCellView=nrOpenCellViewReadable( CellView~>libName + UIExportDesignDef_Form->UIExportDesignDef_BlockageCellName->value + "abstract" ) + ) + defDefOut( CellView~>libName CellView~>cellName CellView~>viewName + UIExportDesignDef_Form->UIExportDesignDef_DefFileName->value + ?Verbose UIExportDesignDef_Form->UIExportDesignDef_Verbose->value + ?DIVIDERCHAR "|" + ?BUSBITCHARS "<>" + ?UNITS UIExportDesignDef_Form->UIExportDesignDef_Units->value + ?OutputNets UIExportDesignDef_Form->UIExportDesignDef_OutputNets->value + ?AllSpecialNets UIExportDesignDef_Form->UIExportDesignDef_AllSpecialNets->value + ?PowerPins UIExportDesignDef_Form->UIExportDesignDef_PowerNets->value + ?Synchronous UIExportDesignDef_Form->UIExportDesignDef_Synchronous->value + ?PinMap pinmap + ?DirMap dirmap + ?BlockageCellView BlockageCellView + ) + ) + ) +) + + +( UICreateComponent + "UIExportDesignDef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIExportDesignDef_DefFileName + ?prompt "DEF Filename" + ?defValue "def.out" ) + ( hiCreateBooleanButton + ?name `UIExportDesignDef_OutputNets + ?buttonText "Output Nets" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIExportDesignDef_AllSpecialNets + ?buttonText "Regard All Existing Wires As SPECIALNETS" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIExportDesignDef_PowerNets + ?buttonText "Export Power Nets" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIExportDesignDef_Synchronous + ?buttonText "Synchronous" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIExportDesignDef_ExportBlockage + ?buttonText "ExportBlockage" + ?defValue nil ) + ( hiCreateStringField + ?name `UIExportDesignDef_BlockageCellName + ?prompt "Blockage Cell Name" + ?defValue "" ) + ( hiCreateFloatField + ?name `UIExportDesignDef_Units + ?prompt "Units" + ?defValue 1000.0 ) + ( hiCreateFormButton + ?name `UIExportDesignDef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Design_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIExportDesignDef_Form + ?formTitle "Export Design DEF" + ?fields Fields + ?callback "( UIExportDesignDefFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignLef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignLef.il new file mode 100644 index 0000000000..7ca0a2fb8f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignLef.il @@ -0,0 +1,93 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Export +; +( list "2.Export Design LEF..." "UIExportDesignLef" ) + + +( UICreateMenuItemCallBack + `UIExportDesignLefCB + (lambda () + let((CellView powerCellName Components RComponents) + CellView = UIGetCellView() + Components = parseString( CellView~>cellName "." ) + RComponents = reverse( Components ) + if( length(RComponents)>=3 then + powerCellName = sprintf( nil "%s_%s" cadr(RComponents) car(RComponents)) + powerCellName = sprintf( nil "%s.wires.%s_POWER_GRID_TIEOFF" + car( NameParseCellName( CellView~>cellName )) powerCellName ) + UIExportDesignLef_Form->UIExportDesignLef_PowerGridCellName->value = powerCellName + ) + UIExportDesignLef_Form->UIExportDesignLef_OutFile->value = + strcat( CellView~>cellName ".lef") + hiDisplayForm( UIExportDesignLef_Form ) + ) + ) +) + + +( UICreateAction + 'UIExportDesignLefFormCB + (lambda () + let( (errorMsg CellView libName cellName viewName LogFile ignore_keepout) + CellView=UIGetCellView() + + ;check if keepouts are drawn + ignore_keepout=t + when( HasKeepout(CellView) + ignore_keepout = hiDisplayAppDBox( + ?name 'KeepoutErrorDialogBox + ?dboxText "Routing obstructions exist in flatten view.\n This may mean that you should reflatten from the prelayout view.\n Do you want to proceed anyway?" + ?dboxBanner "Keepouts Exist" + ?dialogType hicQuestionDialog + ?dialogStyle 'modal + ?buttonLayout 'YesNo + ?defaultButton 2 + ) + ) + + when( ignore_keepout + lefLefOut( CellView~>libName + CellView~>cellName + CellView~>viewName + UIExportDesignLef_Form->UIExportDesignLef_OutFile->value + ) + ) + ) + ) +) + + +( UICreateComponent + "UIExportDesignLef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIExportDesignLef_OutFile + ?prompt "LEF Filename" + ?defValue "lef.out" ) + ( hiCreateStringField + ?name `UIExportDesignLef_PowerGridCellName + ?prompt "Power Grid Cell Name" + ?defValue "default" ) + ( hiCreateFormButton + ?name `UIExportDesignLef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Design_LEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIExportDesignLef_Form + ?formTitle "Export Design LEF" + ?fields Fields + ?callback "( UIExportDesignLefFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportNondefaultRuleDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportNondefaultRuleDef.il new file mode 100644 index 0000000000..374165d34c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportNondefaultRuleDef.il @@ -0,0 +1,107 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Export +; +( list "4.Export Nondefault Rule DEF..." "UIExportNondefaultRuleDef" ) + + +( UICreateMenuItemCallBack + `UIExportNondefaultRuleDefCB + (lambda () + UIExportNondefaultRuleDef_Form->UIExportNondefaultRuleDef_OutFile->value= + strcat( UIGetCellView()~>cellName "_nondefault.def") + hiDisplayForm( UIExportNondefaultRuleDef_Form ) + ) +) + + +( UICreateAction + 'UIExportNondefaultRuleDefFormCB + (lambda () + let( (CellName Command ToolName filename) + CellName = UIGetCellView()~>cellName + ; check for existence of file saved in cell dir + filename = strcat( "/" + buildString( reverse( cddr( reverse( parseString( + UIGetCellView()~>fileName "/")))) "/") + "/" CellName "_nondefault.def") + if( isFile(filename) then + ;create a soft link + hiDisplayAppDBox( + ?name 'NDdefExistsDbox + ?dboxBanner "Notice" + ?dboxText "A nondefault.def file is already saved in the cell directory.\n + Creating a symbolic link." + ?dialogType hicQuestionDialog + ?buttonLayout 'Close + ) + Command = strcat( "ln -s " filename " .") + shell(Command) + else + ;create a new one + + Command = sprintf( nil + "%s/cast2def --cast-path=%s --cell=%s --outfile=%s --cadence-name --max-heap-size=%s &> %s" + PackageGetBinRoot( ) + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + CellName + UIExportNondefaultRuleDef_Form->UIExportNondefaultRuleDef_OutFile->value + UIExportNondefaultRuleDef_Form->UIExportNondefaultRuleDef_HeapSize->value + UIExportNondefaultRuleDef_Form->UIExportNondefaultRuleDef_LogFile->value + ) + printf( "%s\n" Command ) + shell( Command ) + + ; display results + printf( "Nondefault Rule File %s is created.\n" UIExportNondefaultRuleDef_Form->UIExportNondefaultRuleDef_OutFile->value) + ToolName = "Export Nondefault Rule DEF" + hiDisplayAppDBox( + ?name `UIExportNondefaultRuleDef_StatusDbox + ?dboxBanner strcat( ToolName " Status") + ?dboxText sprintf( nil "%s finished. View log file?" ToolName) + ?buttonLayout 'YesNo + ?defaultButton 1 + ?callback "nrDisplayLogFile( ToolName UIExportNondefaultRuleDef_Form->UIExportNondefaultRuleDef_LogFile->value )" + ) + ) + ) +)) + + +( UICreateComponent + "UIExportNondefaultRuleDef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIExportNondefaultRuleDef_OutFile + ?prompt "DEF Filename" + ?defValue "routing.def" ) + ( hiCreateStringField + ?name `UIExportNondefaultRuleDef_LogFile + ?prompt "Log Filename" + ?defValue "exportNondefaultRuleDEF.log" ) + ( hiCreateStringField + ?name `UIExportNondefaultRuleDef_HeapSize + ?prompt "Max Memory Heap Size" + ?defValue "1800M" ) + ( hiCreateFormButton + ?name `UIExportNondefaultRuleDef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Nondefault_Rule_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIExportNondefaultRuleDef_Form + ?formTitle "Export Nondefault Rule DEF" + ?fields Fields + ?callback "( UIExportNondefaultRuleDefFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportVerilog.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportVerilog.il new file mode 100644 index 0000000000..55a8bd776b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportVerilog.il @@ -0,0 +1,87 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Export +; +( list "1.Export Verilog Netlist..." "UICreateVerilog" ) + + +( UICreateMenuItemCallBack + `UICreateVerilogCB + (lambda () + UICreateVerilog_Form->UICreateVerilog_OutFile->value= + strcat( UIGetCellView()~>cellName ".v") + hiDisplayForm( UICreateVerilog_Form ) + ) +) + + +( UICreateAction + 'UICreateVerilogFormCB + (lambda () + let( (CellView Command ToolName) + CellView= UIGetCellView() + Command = sprintf( nil + "%s/prs2verilog --cast-path=%s --cell=%s --outfile=%s --max-heap-size=%s --converter=netlist --skip-power-rail --routed --translate=cadence --cadence-name &> %s" + PackageGetBinRoot( ) + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + CellView~>cellName + UICreateVerilog_Form->UICreateVerilog_OutFile->value + UICreateVerilog_Form->UICreateVerilog_MaxHeapSize->value + UICreateVerilog_Form->UICreateVerilog_LogFile->value + ) + printf( "%s\n" Command ) + shell( Command ) + + ; display results + printf( "Verilog File %s is created.\n" UICreateVerilog_Form->UICreateVerilog_OutFile->value) + ToolName = "Export Verilog Netlist" + hiDisplayAppDBox( + ?name `UICreateVerilog_StatusDbox + ?dboxBanner strcat( ToolName " Status") + ?dboxText sprintf( nil "%s finished. View log file?" ToolName) + ?buttonLayout 'YesNo + ?defaultButton 1 + ?callback "nrDisplayLogFile( ToolName UICreateVerilog_Form->UICreateVerilog_LogFile->value )" + ) + ) + ) +) + + +( UICreateComponent + "UICreateVerilog_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateVerilog_OutFile + ?prompt "Verilog Filename" + ?defValue "verilog.v" ) + ( hiCreateStringField + ?name `UICreateVerilog_LogFile + ?prompt "Log Filename" + ?defValue "exportVerilogNetlist.log" ) + ( hiCreateStringField + ?name `UICreateVerilog_MaxHeapSize + ?prompt "Max Heap Size" + ?defValue "1800M" ) + ( hiCreateFormButton + ?name `UICreateVerilog_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Verilog_Netlist_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UICreateVerilog_Form + ?formTitle "Export Verilog Netlist" + ?fields Fields + ?callback "( UICreateVerilogFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/.menu new file mode 100644 index 0000000000..5f7b9a6489 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/.menu @@ -0,0 +1 @@ +( list "3.Create Flatten" "UIFlatten" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CopyBusGuidesToPrelayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CopyBusGuidesToPrelayout.il new file mode 100644 index 0000000000..303a981eb1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CopyBusGuidesToPrelayout.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "4.Copy Guides to Prelayout" "UICopyBusGuidesToPrelayout" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreateCellList.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreateCellList.il new file mode 100644 index 0000000000..79148a6e86 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreateCellList.il @@ -0,0 +1,79 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il#11 $ +; $DateTime: 2007/01/25 16:03:31 $ +; $Author: khe $ + +; +; menu item Nano/Flatten +; +( list "4.Create Flatten Cell List..." "UICreateCellList" ) + + +( UICreateMenuItemCallBack + `UICreateCellListCB + (lambda () + let((CellView powerCellName OBSCellName BusWireCellName Components RComponents) + CellView = UIGetCellView() + UICreateCellList_Form->UICreateCellList_FlattenCellsList->value= + strcat( CellView~>cellName ".flatten_cells_list") + hiDisplayForm( UICreateCellList_Form ) + ) + ) +) + + +( UICreateComponent + "UICreateCellList_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateCellList_FlattenCellsList + ?prompt "Flatten Cells List" + ?defValue "flatten_cells_list" ) + ( hiCreateBooleanButton + ?name `UICreateCellList_ViewName + ?buttonText "Use \"abstract\" as viewName" + ?defValue t ) + ) + ( hiCreateAppForm + ?name `UICreateCellList_Form + ?formTitle "Create Flatten Cell List" + ?fields Fields + ?callback "( UICreateCellListFormCB )" + ) + ) + ) + ) +) + + +( UICreateAction + 'UICreateCellListFormCB + (lambda () + let( (CellView cellList fout inst) + CellView= UIGetCellView() + nrCreateCellList( CellView + UICreateCellList_Form->UICreateCellList_FlattenCellsList->value + UICreateCellList_Form->UICreateCellList_ViewName->value ) + ) + ) +) + +defun( nrCreateCellList ( CellView CellsListFileName UseAbstractViewName ) + let((inst cellList fout) + cellList=nil + fout=outfile(CellsListFileName) + if( fout then + foreach(inst CellView~>instances + if(!member( inst~>cellName cellList) then + cellList=cons(inst~>cellName cellList) + fprintf(fout "%s %s %s\n" inst~>libName inst~>cellName if(UseAbstractViewName "abstract" inst~>viewName)) + ) + ) + close(fout) + else printf("Error: file %s not writable\n" CellsListFileName) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreatePowerGrid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreatePowerGrid.il new file mode 100644 index 0000000000..ff3bbb50a0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreatePowerGrid.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Flatten +; +; reference function from Fulcrum/AutoPowerGrid.il +; +( list "2.Create Power Grid Cell..." "UIAutoPowerGrid" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/DrawPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/DrawPins.il new file mode 100644 index 0000000000..253bab9269 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/DrawPins.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Flatten +; +; reference function from Fulcrum/Pins/DrawPins.il +; +( list "3.Draw Pins..." "UIDrawAllPins" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il new file mode 100644 index 0000000000..3cc0a72390 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il @@ -0,0 +1,312 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Flatten +; +( list "1.Create Flatten View..." "UICreateFlattenView" ) + + +( UICreateMenuItemCallBack + `UICreateFlattenViewCB + (lambda () + let((CellView powerCellName CellBaseName OBSCellName BusWireCellName Components RComponents) + CellView = UIGetCellView() + Components = parseString( CellView~>cellName "." ) + CellBaseName = cadr( reverse( parseString( CellView~>cellName "." ) )) + RComponents = reverse( Components ) + if( length(RComponents) >= 3 then + powerCellName = sprintf( nil "%s_%s" cadr(RComponents) car(RComponents)) + OBSCellName = strcat( CellView~>libName ".wires." CellBaseName) + BusWireCellName = strcat( CellView~>libName ".wires." CellBaseName "_buswires") + powerCellName = sprintf( nil "%s.wires.%s_POWER_GRID_TIEOFF" + car( NameParseCellName( CellView~>cellName )) powerCellName ) + UICreateFlattenView_Form->UICreateFlattenView_OBSCellName->value = OBSCellName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value = powerCellName + UICreateFlattenView_Form->UICreateFlattenView_BusWireCellName->value = BusWireCellName + ) + UICreateFlattenView_Form->UICreateAbstract_FulcrumPDKRoot->value= + getShellEnvVar( "FULCRUM_PDK_ROOT" ) + if(UICreateFlattenView_Form->UICreateAbstract_DfIIDir->value== "default" then + UICreateFlattenView_Form->UICreateAbstract_DfIIDir->value= + NameGetDFIIDirFromCellName( UIGetCellView()~>cellName) + ) + if(UICreateFlattenView_Form->UICreateAbstract_P4Client->value== "default" then + UICreateFlattenView_Form->UICreateAbstract_P4Client->value= + ConfigFileGetValue( TheCDSConfigTable "P4CLIENT" ) + ) + UICreateFlattenView_Form->UICreateFlattenView_FlattenCellsList->value= + strcat( CellView~>cellName ".flatten_cells_list") + UICreateFlattenView_Form->UICreateFlattenView_M3PowerPins->value=t + UICreateFlattenView_Form->UICreateFlattenView_ResolveM3MacroConflict->value=nil + hiDisplayForm( UICreateFlattenView_Form ) + ) + ) +) + + +( UICreateComponent + "UICreateFlattenView_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateAbstract_FulcrumPDKRoot + ?prompt "Fulcrum PDK Root" + ?defValue "default" ) + ( hiCreateStringField + ?name `UICreateAbstract_DfIIDir + ?prompt "DfII Dir" + ?defValue "default" ) + ( hiCreateStringField + ?name `UICreateAbstract_P4Client + ?prompt "Client Spec" + ?defValue "default" ) + + ( hiCreateSeparatorField + ?name `UICreateFlattenView_sep1 ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_Stage1 + ?buttonText "Stage1: Create Flatten CellView" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_RegenerateFromCast + ?buttonText " Regenerate Routed Directive From Cast" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_CheckAlignment + ?buttonText " Check Cell Alignment" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_DeleteWires + ?buttonText " Delete Top Level Wires After Flatten" + ?defValue nil ) + ( hiCreateStringField + ?name `UICreateFlattenView_FlattenViewName + ?prompt " Flatten View Name" + ?defValue "flatten" ) + + ( hiCreateSeparatorField + ?name `UICreateFlattenView_sep2 ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_Stage2 + ?buttonText "Stage2: Create Power Grid Cell Layout and Abstract" + ?defValue t ) + ( hiCreateStringField + ?name `UICreateFlattenView_FlattenCellsList + ?prompt " Flatten Cells List" + ?defValue "flatten_cells_list" ) + ( hiCreateStringField + ?name `UICreateFlattenView_PowerGridCellName + ?prompt " Power Grid Cell Name" + ?defValue "powerGridTieOff" ) + ( hiCreateStringField + ?name `UICreateFlattenView_OBSCellName + ?prompt " Routing Obstruction Cell Name" + ?defValue "OBS" ) + ( hiCreateStringField + ?name `UICreateFlattenView_BusWireCellName + ?prompt " Bus Wires Cell Name" + ?defValue "BUSWIRES" ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_M3PowerPins + ?buttonText "Create M3 Power Pins" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_ResolveM3MacroConflict + ?buttonText "Chop M3 pin shapes overlapping M3 macro blockage" + ?defValue nil ) + ( hiCreateRadioField + ?name `UICreateFlattenView_Class + ?prompt "Power Grid Macro Class" + ?choices list("block" "cover") + ?defValue "block" ) + + ( hiCreateSeparatorField + ?name `UICreateFlattenView_sep3 ) + ( hiCreateBooleanButton + ?name `UICreateFlattenView_Verbose + ?buttonText "Verbose" + ?defValue nil ) + ( hiCreateFormButton + ?name `UICreateFlattenView_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Flatten_View_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UICreateFlattenView_Form + ?formTitle "Create Flatten View" + ?fields Fields + ?callback "( UICreateFlattenViewFormCB )" + ) + hiSetFormSize( UICreateFlattenView_Form list(601 585)) + ) + ) + ) +) + + +( UICreateAction + 'UICreateFlattenViewFormCB + (lambda () + let( (CellView powerGridCellView Command ErrorStr TMP t1 t2 t3 changeSpec changeNumber + powerCellViewName powerGridCellAbstractView flattenView power powerTemp OptionList) + CellView= UIGetCellView() + + ; stage 1 -- create flatten view + if( UICreateFlattenView_Form->UICreateFlattenView_Stage1->value then + flattenView=nrFlattenView( + CellView + UICreateFlattenView_Form->UICreateFlattenView_FlattenViewName->value + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + powerCellViewName + UICreateFlattenView_Form->UICreateFlattenView_FlattenCellsList->value + ?Verbose UICreateFlattenView_Form->UICreateFlattenView_Verbose->value + ?DeleteWires UICreateFlattenView_Form->UICreateFlattenView_DeleteWires->value + ?RegenerateFromCast UICreateFlattenView_Form->UICreateFlattenView_RegenerateFromCast->value + ?CheckAlignment UICreateFlattenView_Form->UICreateFlattenView_CheckAlignment->value + ?MaxHeapSize nrGetMaxHeapSize( ) + ) + ) + + ; stage 2 -- create power grid cell + when( flattenView + if( UICreateFlattenView_Form->UICreateFlattenView_Stage2->value then + powerGridCellView=ddGetObj( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + "layout" + ) + powerCellViewName="layout" + if( powerGridCellView then + powerGridCellView=nrOpenCellViewWritable( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + powerCellViewName + ) + if( powerGridCellView == nil then + powerGridCellView=nrOpenCellViewReadable( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + powerCellViewName + ) + ErrorStr=CDSP4Edit( + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + UICreateFlattenView_Form->UICreateAbstract_P4Client->value + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + powerGridCellView + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + else + powerGridCellView=dbOpenCellViewByType( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + "layout" + "maskLayout" + "w" + ) + ErrorStr=CDSP4Add( + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + UICreateFlattenView_Form->UICreateAbstract_P4Client->value + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + powerGridCellView + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + if( stringp( ErrorStr ) println( ErrorStr )) + flattenView=nrFlattenViewPG( + CellView + UICreateFlattenView_Form->UICreateFlattenView_FlattenViewName->value + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + powerCellViewName + UICreateFlattenView_Form->UICreateFlattenView_FlattenCellsList->value + ?Verbose UICreateFlattenView_Form->UICreateFlattenView_Verbose->value + ?DeleteWires UICreateFlattenView_Form->UICreateFlattenView_DeleteWires->value + ?RegenerateFromCast nil + ?MaxHeapSize nrGetMaxHeapSize( ) + ?OBSCellName UICreateFlattenView_Form->UICreateFlattenView_OBSCellName->value + ?OBSViewName "layout" + ?BusWireCellName UICreateFlattenView_Form->UICreateFlattenView_BusWireCellName->value + ?BusWireViewName "buswires" + ) + + ; create power grid abstract + powerGridCellAbstractView=ddGetObj( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + "abstract" + ) + if( powerGridCellAbstractView then + powerGridCellAbstractView=nrOpenCellViewWritable( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + "abstract" + ) + if( powerGridCellAbstractView == nil then + powerGridCellAbstractView=nrOpenCellViewReadable( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + "abstract" + ) + ErrorStr=CDSP4Edit( + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + UICreateFlattenView_Form->UICreateAbstract_P4Client->value + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + powerGridCellAbstractView + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + else + powerGridCellAbstractView=dbOpenCellViewByType( + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + "abstract" "maskLayout" "w" + ) + ErrorStr=CDSP4Add( + ( ConfigFileGetValue TheCDSConfigTable "P4USER" ) + ( ConfigFileGetValue TheCDSConfigTable "P4PASSWD" ) + UICreateFlattenView_Form->UICreateAbstract_P4Client->value + ( ConfigFileGetValue TheCDSConfigTable "P4CONFIG" ) + powerGridCellAbstractView + ( ConfigFileGetValue TheCDSConfigTable "TEMP" ) + ) + ) + AutoGeneratePowerGridAbstract( + flattenView + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + ?powerViewName "layout" + ?powerAbstractViewName "abstract" + ?OBSCellName UICreateFlattenView_Form->UICreateFlattenView_OBSCellName->value + ?OBSViewName "layout" + ?M3PowerPins UICreateFlattenView_Form->UICreateFlattenView_M3PowerPins->value + ?ResolveMacroBlockageConflict UICreateFlattenView_Form->UICreateFlattenView_ResolveM3MacroConflict->value + ?Class UICreateFlattenView_Form->UICreateFlattenView_Class->value + ?M5PowerPins t + ?M7PowerPins t + ) + + ; log abstract options + OptionList = "Create Power Grid Abstract" + Command = sprintf( nil + "%s/createAbstractCellLog --cell=%s:%s:%s --client-spec=%s --dfII-dir=%s --opt-str=\"%s\"" + PackageGetBinRoot( ) + CellView~>libName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value + "layout" + ConfigFileGetValue( TheCDSConfigTable "P4CLIENT" ) + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + OptionList + ) + printf( "Update abstract log.\n%s\n" Command ) + shell( Command ) + ) + ) + )) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/.menu new file mode 100644 index 0000000000..6826599218 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/.menu @@ -0,0 +1 @@ +( list "7.Import Routed Design" "UIImport" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/CreateLayoutView.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/CreateLayoutView.il new file mode 100644 index 0000000000..9265b93494 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/CreateLayoutView.il @@ -0,0 +1,102 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Import +; +( list "2.Create Layout Cellview..." "UICreateLayoutView" ) + + +( UICreateMenuItemCallBack + `UICreateLayoutViewCB + (lambda () + UICreateLayoutView_Form->UICreateLayoutView_RoutedView->value = UIGetCellView()~>viewName + hiDisplayForm( UICreateLayoutView_Form ) + ) +) + + +( UICreateComponent + "UICreateLayoutView_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateLayoutView_RoutedView + ?prompt "Routed View Name" + ?defValue "layout_pg" ) + ( hiCreateStringField + ?name `UICreateLayoutView_LayoutView + ?prompt "Layout View Name" + ?defValue "layout" ) + ( hiCreateBooleanButton + ?name `UICreateLayoutView_Overwrite + ?buttonText "Overwrite Layout View" + ?defValue t ) + ( hiCreateFormButton + ?name `UICreateLayoutView_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Layout_Cellview_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UICreateLayoutView_Form + ?formTitle "Create Layout Cellview" + ?fields Fields + ?callback "( UICreateLayoutViewFormCB )" + ) + ) + ) + ) +) + + +( UICreateAction + 'UICreateLayoutViewFormCB + (lambda () + let(( CellView LayoutCellView PowerGrid Msg Inst NumDeleted ) + CellView = UIGetCellView() + + ; copy source cellview to layout cellview + LayoutCellView = dbCopyCellView( CellView CellView~>libName CellView~>cellName + UICreateLayoutView_Form->UICreateLayoutView_LayoutView->value + nil nil + UICreateLayoutView_Form->UICreateLayoutView_Overwrite->value + ) + + if( LayoutCellView then + dbSave(LayoutCellView) + + ; delete power grid (and routing obstructions since it should be a subcell) + PowerGrid = dbGetInstanceByName( LayoutCellView "tiehilo" ) + if( PowerGrid then + dbDeleteObject(PowerGrid) + dbSave(LayoutCellView) + else + Msg = sprintf( nil "ERROR: Unable to delete Power Grid instance from %s cellview." + UICreateLayoutView_Form->UICreateLayoutView_LayoutView->value ) + nrToolStatus( "Create Layout View" Msg ) + ) + + ; delete any buswires cellviews + NumDeleted = 0 + foreach( Inst CellView~>instances + if( Inst~>viewName == "buswires" then + printf( "Deleting %s (%s).\n" Inst~>cellName Inst~>viewName ) + dbDeleteObject( Inst ) + NumDeleted = NumDeleted + 1 + ) + ) + printf( "Found and deleted %d buswire instances.\n" NumDeleted) + else + Msg = sprintf( nil "WARNING: Can not overwrite existing cellview %s (%s).\n" + CellView~>cellName + UICreateLayoutView_Form->UICreateLayoutView_LayoutView->value) + nrToolStatus( "Create Layout Cellview" Msg ) + ) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/ImportDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/ImportDef.il new file mode 100644 index 0000000000..282eaf49f8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/ImportDef.il @@ -0,0 +1,72 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Import +; +( list "1.Import Routed DEF..." "UIImportRoutedDef" ) + + +( UICreateMenuItemCallBack + `UIImportRoutedDefCB + (lambda () + hiDisplayForm( UIImportRoutedDef_Form ) + ) +) + + +( UICreateAction + 'UIImportRoutedDefFormCB + (lambda () + let( (CellView Command RoutedFileName DefNetsFileName RoutedCellView Msg ChildId + Status CellMsg LogFile SumFile InPort ) + CellView = UIGetCellView() + + ; check that we are properly in the flatten view + when( CellView->viewName!="flatten" + UIPopUpDialog("You should probably be running this menu from a \"flatten\" view.") + ) + + NanoRouteImport( ?CV CellView + ?importView UIImportRoutedDef_Form->UIImportRoutedDef_routedView->value + ?deleteGNDShield UIImportRoutedDef_Form->UIImportRoutedDef_deletetiedown->value + ) + ) + ) +) + + +( UICreateComponent + "UIImportRoutedDef_Form" + ( UICreateConstructor + (lambda ( Children ) + let(( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIImportRoutedDef_routedView + ?prompt "Routed View Name" + ?defValue "layout_pg" ) + ( hiCreateBooleanButton + ?name `UIImportRoutedDef_deletetiedown + ?buttonText "Delete GNDShield Cell" + ?defValue t ) + ( hiCreateFormButton + ?name `UIImportRoutedDef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Import_Routed_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIImportRoutedDef_Form + ?formTitle "Import Routed DEF" + ?fields Fields + ?callback "( UIImportRoutedDefFormCB )" + ) + ) + ) + ) +) + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/SaveFiles.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/SaveFiles.il new file mode 100755 index 0000000000..63445cdde5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Import/SaveFiles.il @@ -0,0 +1,98 @@ + +( list "3.Save modified design files" "UINanoSaveFiles" ) + +( UICreateMenuItemCallBack + `UINanoSaveFilesCB + (lambda () + ( hiDisplayForm UINanoSaveFiles_Form ) ) +) + +defun( NanoSaveFiles ( cellView ) + let( (CellName celldir filename file Command) + CellName = cellView->cellName + (when UINanoSaveFiles_Form->UINanoSaveFiles_Form_nondefault->value + celldir = strcat( "/" + buildString( reverse( cddr( reverse( parseString( + UIGetCellView()~>fileName "/")))) "/") + "/" ) + filename = strcat(CellName "_nondefault.def") + file = strcat(celldir filename) + if( isFile(file) then + hiDisplayAppDBox( + ?name 'NDdefExistsDbox + ?dboxBanner "Notice" + ?dboxText "A nondefault.def file is already saved in the cell directory." + ?dialogType hicQuestionDialog + ?buttonLayout 'Close + ) + else + Command = strcat( "mv " filename " " celldir ) + shell(Command) + ) + Command = strcat( "ln -s " file " ." ) + shell(Command) + CDSP4CellFile( cellView filename "add" ) + ) + + (when UINanoSaveFiles_Form->UINanoSaveFiles_Form_init->value + celldir = strcat( "/" + buildString( reverse( cddr( reverse( parseString( + UIGetCellView()~>fileName "/")))) "/") + "/" ) + filename = strcat(CellName "_initNanoroute.tcl") + file = strcat(celldir filename) + if( isFile(file) then + hiDisplayAppDBox( + ?name 'initExistsDbox + ?dboxBanner "Notice" + ?dboxText "An initNanoroute.tcl file is already saved in the cell directory." + ?dialogType hicQuestionDialog + ?buttonLayout 'Close + ) + else + Command = strcat( "mv " filename " " celldir ) + shell(Command) + ) + Command = strcat( "ln -s " file " ." ) + shell(Command) + CDSP4CellFile( cellView filename "add" ) + ) + ) +) + + +( UICreateAction + 'UINanoSaveFilesFormCB + (lambda () + (let (CellView) + CellView = UIGetCellView( ) + NanoSaveFiles( CellView ) + ) + ) +) + +( UICreateComponent + "UINanoSaveFiles_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( + ( Fields + ( list + ( hiCreateBooleanButton + ?name `UINanoSaveFiles_Form_init + ?buttonText "_initNanoroute.tcl" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UINanoSaveFiles_Form_nondefault + ?buttonText "_nondefault.def" + ?defValue nil ) + ) ) ) + ( hiCreateAppForm + ?name `UINanoSaveFiles_Form + ?formTitle "Save Nanoroute Design Files" + ?fields Fields + ?callback "( UINanoSaveFilesFormCB )" + ) ) ) + ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/.menu new file mode 100644 index 0000000000..fb508ed118 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/.menu @@ -0,0 +1 @@ +( list "6.Nanoroute" "UINanoroute" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/InitNanoroute.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/InitNanoroute.il new file mode 100644 index 0000000000..9d31ef1fe1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/InitNanoroute.il @@ -0,0 +1,55 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +( list "1.Create Nanoroute Init..." "UIInitNanoroute" ) + + +( UICreateMenuItemCallBack + `UIInitNanorouteCB + (lambda () + ( let (cellName) + ( hiDisplayForm UIInitNanoroute_Form ) + ) + ) +) + + +( UICreateComponent + "UIInitNanoroute_Form" + ( UICreateConstructor + (lambda ( Children ) + ( let ( Fields ) + Fields = ( list + ( hiCreateCyclicField + ?name `UIInitNanoroute_TopLayer + ?prompt " Top Routing Layer" + ?choices list("2" "3" "4" "5" "6" "7") + ?defValue "5" ) + ( hiCreateCyclicField + ?name `UIInitNanoroute_BottomLayer + ?prompt " Bottom Routing Layer" + ?choices list("2" "3" "4" "5" "6" "7") + ?defValue "3" ) + ) + ( hiCreateAppForm + ?name `UIInitNanoroute_Form + ?formTitle "Create Nanoroute Init" + ?fields Fields + ?callback "( UIInitNanorouteFormCB )" + ) + ) + ) +)) + + +( UICreateAction + 'UIInitNanorouteFormCB + (lambda () + (NanoRouteTcl ?bottomMetal (atoi UIInitNanoroute_Form->UIInitNanoroute_BottomLayer->value) + ?topMetal (atoi UIInitNanoroute_Form->UIInitNanoroute_TopLayer->value) + ?Verify nil + ) +)) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/RunNanoroute.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/RunNanoroute.il new file mode 100644 index 0000000000..84d40b5803 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Nanoroute/RunNanoroute.il @@ -0,0 +1,190 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Nanoroute +; +( list "2.Run Nanoroute..." "UIRunNanoroute" ) + + +( UICreateMenuItemCallBack + `UIRunNanorouteCB + (lambda () + let((cellName) + cellName=UIGetCellView()~>cellName + UIRunNanoroute_Form->UIRunNanoroute_CmdFile->value=strcat( cellName ".tcl" ) + + hiDisplayForm( UIRunNanoroute_Form ) + ) + ) +) + + +( UICreateComponent + "UIRunNanoroute_Form" + ( UICreateConstructor + ( lambda ( Children ) + ( let ( Field1 Field2 Field3 Field4 Field5 Field6 AllFields License ) + + ; head fields + Field1=( hiCreateRadioField + ?name `UIRunNanoroute_Mode + ?prompt "Nanoroute Execution Mode" + ?choices list("Batch" "Local") + ?defValue "Batch" + ?callback list( + "UIRunNanorouteFormModeCB(\"Batch\" hiGetCurrentForm())" + "UIRunNanorouteFormModeCB(\"Local\" hiGetCurrentForm())" + ) + ) + Field2=( hiCreateStringField + ?name `UIRunNanoroute_CmdFile + ?prompt "Nanoroute Init Filename" + ?defValue "initNanoroute.tcl" + ) + + ; specify SOC license to use + Field2B=( hiCreateRadioField + ?name `UIRunNanoroute_License + ?prompt "SOC Encounter License to Use" + ?choices list("DBS" "GPS" "Full") + ?defValue "DBS" + ) + + ; specify grid ticket to use + Field2C=( hiCreateRadioField + ?name `UIRunNanoroute_Ticket + ?prompt "Grid Ticket to Use (use nano if queue is full and job is quick.)" + ?choices list("nano" "np") + ?defValue "np" + ) + + ; batch fields + Field3=( hiCreateStringField + ?name `UIRunNanoroute_SubFile + ?prompt "Qsub Command Filename" + ?defValue "sub_nanoroute" + ) + Field4=( hiCreateRadioField + ?name `UIRunNanoroute_Arch + ?prompt "Compute Host Architecture" + ?choices list("32-bit" "64-bit") + ?defValue "64-bit" + ) + Field5=( hiCreateIntField + ?name `UIRunNanoroute_Mem + ?prompt "Compute Host Memory (MB)" + ?range list(2000 16000) + ?defValue 4000 + ) + + ; tail fields + Field6=( hiCreateFormButton + ?name `UIRunNanoroute_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Run_Nanoroute_help.html\" )" + ) + AllFields = list( Field1 Field2 Field2B Field2C Field3 Field4 Field5 Field6 ) + + ; global var used in UIRunNanorouteFormModeCB + RunNanoroute_Form_BatchFields = list( Field3 Field4 Field6 ) + + ( hiCreateAppForm + ?name `UIRunNanoroute_Form + ?formTitle "Run Nanoroute" + ?fields AllFields + ?callback "UIRunNanorouteFormCB()" + ) + ) + ) + ) +) + + +( UICreateAction + 'UIRunNanorouteFormCB + (lambda () + let( ( Command pout Success Msg ) + Success = t + if( UIRunNanoroute_Form->UIRunNanoroute_Mode->value == "Batch" then + if( UIRunNanoroute_Form->UIRunNanoroute_SubFile->value == "" then + Msg = sprintf( nil "Qsub command file required in Batch mode." ) + nrToolStatus( "Run Nanoroute" Msg ) + Success = nil + else + pout = outfile( UIRunNanoroute_Form->UIRunNanoroute_SubFile->value ) + if( pout then + fprintf( pout "#! /bin/tcsh\n" ) + fprintf( pout "fulcrum --cadence=soc.101usr2 encounter" ) + if( UIRunNanoroute_Form->UIRunNanoroute_Arch->value == "64-bit" then + fprintf( pout " -64" ) + ) + cond( (UIRunNanoroute_Form->UIRunNanoroute_License->value == "DBS" + fprintf( pout " -socel" ) ) + (UIRunNanoroute_Form->UIRunNanoroute_License->value == "GPS" + fprintf( pout " -socexl" ) ) + (t fprintf( pout " -SOCE" ) ) + ) + if( UIRunNanoroute_Form->UIRunNanoroute_CmdFile->value != "" then + fprintf( pout " -init %s -nowin\n" UIRunNanoroute_Form->UIRunNanoroute_CmdFile->value ) + else + Msg = sprintf( nil + "ERROR: Run Nanoroute FAILED. Nanoroute command file required in Batch mode.") + nrToolStatus( "Run Nanoroute" Msg ) + Success = nil + ) + close(pout) + else + Msg = sprintf( nil "ERROR: Run Nanoroute FAILED. Unable to open qsub command file '%s'." + UIRunNanoroute_Form->UIRunNanoroute_SubFile->value ) + nrToolStatus( "Run Nanoroute" Msg ) + Success = nil + ) + Command = sprintf( nil "qsub -cwd -now n -l %s=1,mem=%dM" + UIRunNanoroute_Form->UIRunNanoroute_Ticket->value + UIRunNanoroute_Form->UIRunNanoroute_Mem->value ) + if( UIRunNanoroute_Form->UIRunNanoroute_Arch->value == "64-bit" then + Command = strcat( Command ",a=lx24-amd64" ) + ) + Command = sprintf( nil "%s %s" + Command UIRunNanoroute_Form->UIRunNanoroute_SubFile->value ) + ) + else + Command = sprintf( nil "qrsh -now n -cwd -l a=lx24-amd64,%s=1,mem=%dM fulcrum --cadence=soc.101usr2 encounter" + UIRunNanoroute_Form->UIRunNanoroute_Ticket->value + UIRunNanoroute_Form->UIRunNanoroute_Mem->value ) + if( UIRunNanoroute_Form->UIRunNanoroute_CmdFile->value != "" then + Command = sprintf( nil "%s -init %s" + Command UIRunNanoroute_Form->UIRunNanoroute_CmdFile->value ) + ) + Command = strcat(Command " &") + ) + + if(Success then + printf( "%s\n" Command ) + shell( Command ) + ) + ) + ) +) + + +; update form based on Mode +defun( UIRunNanorouteFormModeCB ( Mode FormID ) + if( Mode == "Local" then + hiDeleteFields( FormID list(`UIRunNanoroute_SubFile `UIRunNanoroute_Arch )) + ) + if( Mode == "Batch" then + hiDeleteFields( FormID list(`UIRunNanoroute_Help) ) + hiAddFields( FormID RunNanoroute_Form_BatchFields ) + hiFormDefaults( FormID ) +; hiSetFormSize( FormID list(601 242)) + hiSetFormSize( FormID list(601 276)) + ) + cellName=UIGetCellView()~>cellName + UIRunNanoroute_Form->UIRunNanoroute_CmdFile->value=strcat( cellName ".tcl" ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/NanorouteDoc.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/NanorouteDoc.il new file mode 100644 index 0000000000..a76d043629 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/NanorouteDoc.il @@ -0,0 +1,125 @@ +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/ +; +; Loads Nanoroute flow documentation in web browser +; +( list "Nanoroute Flow Help" "UINanoFlowHelp" ) + +( UICreateMenuItemCallBack + `UINanoFlowHelpCB + (lambda () + ( nrOpenHtml "Route_Upper_Level_Cells_frame.html" ) ) ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Utility Functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; load html file +; +; Assumes doc root html path is "http://internal.avlsi.com/eng/depot/sw/cad/doc/flow/AsicDesignFlow/html/" +; +defun( nrOpenHtml (Html) + let( ( Command DocRoot Doc ) + DocRoot = "http://internal.avlsi.com/eng/depot/sw/cad/doc/flow/AsicDesignFlow/html/" + Doc = strcat( DocRoot Html ) + Command = sprintf( nil "LD_LIBRARY_PATH= firefox %s &" Doc ) + printf( "%s\n" Command ) + shell( Command ) + ) +) + + +; +; display tool summary file +; +; IntroStr is tool run text such that the message is ' finished/FAILED' +; +defun( nrDisplayToolStatus ( ToolName IntroStr LogFileName ) + let( (Lines Msg Banner SumFileName pin) + SumFileName = substring( LogFileName 1 ( strlen( LogFileName ) - 3 )) + SumFileName = strcat( SumFileName "sum" ) + Banner = strcat( ToolName " Status") + pin = infile( SumFileName ) + if( pin then + Lines = ( ReadFileReadFileLines SumFileName ) + Msg = strcat( IntroStr " finished.\n\n" ) + while( !atom( Lines ) + if( car( Lines ) then + Msg = strcat( Msg car( Lines ) "\n") + else + Msg = strcat( Msg "\n" ) + ) + Lines = cdr( Lines ) + ) + Msg = strcat( Msg "\nView log file?" ) + hiDisplayAppDBox( + ?name `UINanorouteToolStatusDbox + ?dboxBanner Banner + ?dboxText Msg + ?buttonLayout 'YesNo + ?defaultButton 1 + ?callback "nrDisplayLogFile( ToolName LogFileName )" + ) + close( pin ) + else + Msg = strcat( IntroStr " FAILED.\n" ) + hiDisplayAppDBox( + ?name `UINanorouteToolStatusDbox + ?dboxBanner Banner + ?dboxText Msg + ?buttonLayout 'Close + ) + ) + printf( "%s" Msg ) + ) +) + + +; +; display tool log file +; +defun( nrDisplayLogFile ( ToolName LogFileName ) + let( (Msg Str pin) + Str = strcat( ToolName " Log File" ) + printf( "View log file %s\n" LogFileName ) + pin = infile( LogFileName ) + if( pin then + view( LogFileName nil Str ) + else + Msg = sprintf( nil "ERROR -- Unable to open log file %s\n" LogFileName ) + hiDisplayAppDBox( + ?name `UINanorouteToolLogDbox + ?dboxBanner Str + ?dboxText Msg + ?buttonLayout 'Close + ) + ) + close( pin ) + ) +) + + + + +; +; status message box +; +defun( nrToolStatus ( Tool Msg ) + let(() + printf( "%s\n" Msg ) + hiDisplayAppDBox( + ?name `UINanorouteStatusMsgDbox + ?dboxBanner strcat(Tool " Status") + ?dboxText Msg + ?buttonLayout 'Close + ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/.menu new file mode 100644 index 0000000000..097de709c5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/.menu @@ -0,0 +1 @@ +( list "1.Create Prelayout" "UIPrelayout" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CheckAlignment.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CheckAlignment.il new file mode 100644 index 0000000000..57665c3fe0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CheckAlignment.il @@ -0,0 +1,6 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $DateTime: 2009/10/05 15:21:21 $ +; $Author: stevemc $ + +( list "3.Check Alignment" "UICheckAlignment" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/Clean.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/Clean.il new file mode 100644 index 0000000000..fffb38a4be --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/Clean.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Prelayout +; +; reference function from Fulcrum/Route/Clean.il +; +( list "5.Route Clean..." "UIRouteClean" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrBound.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrBound.il new file mode 100644 index 0000000000..078dcd8c37 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrBound.il @@ -0,0 +1,8 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/CreateCDL.il#11 $ +; $DateTime: 2004/08/21 16:39:54 $ +; $Author: clayton $ + + +( list "4.Create prBound" "UICreatePrBound" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrelayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrelayout.il new file mode 100644 index 0000000000..9c199539d6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrelayout.il @@ -0,0 +1,146 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Prelayout +; +( list "1.Create Prelayout Cellviews..." "UICreatePrelayout" ) + +( UICreateMenuItemCallBack + `UICreatePrelayoutCB + (lambda () + hiDisplayForm( UICreatePrelayout_Form ) + ) +) + +defun( nrCreatePrelayout (libName cellName viewName prelayoutViewName + @key + ( routedDirectiveList nil ) + ( Verbose nil ) + ( RegenerateFromCast nil ) + ( Overwrite nil ) + ( SyncToNetlist t ) + ) + let( (CellView PrelayoutView LayoutView LibCellsToIgnore routedStatus + transform InstName NewMasterCellView) + LibCellsToIgnore = append( WiringCellLibCellPairRegExs + append( TechLibCellPairRegExs + append( GateLibCellPairRegExs StackLibCellPairRegExs ) ) ) + if( nrIsRoutedCell( libName cellName viewName + ?routedDirectiveList routedDirectiveList + ?Verbose Verbose + ?RegenerateFromCast RegenerateFromCast) then + CellView=nrOpenCellViewReadable(libName cellName "layout") || nrOpenCellViewReadable(libName cellName "prelayout" ) || + nrOpenCellViewReadable(libName cellName "floorplan") + else + PrelayoutView=nrOpenCellViewReadable(libName cellName prelayoutViewName) + if( !PrelayoutView || ( Overwrite && !member( cellName processedCellList) ) then + CellView=nrOpenCellViewReadable(libName cellName viewName) + PrelayoutView=dbCopyCellView(CellView libName cellName + prelayoutViewName nil nil Overwrite) + if( PrelayoutView then + DeletePins( ?cv PrelayoutView ) + CopyAlignmentProps( CellView PrelayoutView ) + instances= car( NameFilterInstances( PrelayoutView~>instances LibCellsToIgnore )) + foreach( inst instances + InstName=inst~>name + transform=inst~>transform + NewMasterCellView=nrCreatePrelayout(inst~>libName inst~>cellName inst~>viewName prelayoutViewName + ?routedDirectiveList routedDirectiveList + ?Verbose Verbose + ?RegenerateFromCast RegenerateFromCast + ?Overwrite Overwrite + ?SyncToNetlist SyncToNetlist + ) + dbDeleteObject( inst ) +; dbCreateInst( + CreateInstWithAlignmentProps( + PrelayoutView + NewMasterCellView + InstName + car( transform ) + cadr( transform ) ) + ) + dbSave(PrelayoutView) + printf("Creating %s(%s)...\n" PrelayoutView~>cellName PrelayoutView~>viewName) + processedCellList=cons( PrelayoutView~>cellName processedCellList ) + if( SyncToNetlist nrSyncToNetlist(PrelayoutView)) + dbSave(PrelayoutView) + else + PrelayoutView=nrOpenCellViewReadable(libName cellName + prelayoutViewName) + ) + ) + CellView=PrelayoutView + SetCellAlignment(CellView) + when( CheckRoutedAlignment(CellView) + printf("There are already cell misalignments inherited from the floorplan.") + ) + ) + CellView + ) +) + + +( UICreateAction + 'UICreatePrelayoutFormCB + (lambda () + let( (CellView) + CellView= UIGetCellView() + processedCellList=nil + nrCreatePrelayout(CellView~>libName CellView~>cellName CellView~>viewName + UICreatePrelayout_Form->UICreatePrelayout_ViewName->value + ?routedDirectiveList nrCastQuery( CellView + ?RegenerateFromCast UICreatePrelayout_Form->UICreatePrelayout_RegenerateFromCast->value) + ?Verbose UICreatePrelayout_Form->UICreatePrelayout_Verbose->value + ?RegenerateFromCast UICreatePrelayout_Form->UICreatePrelayout_RegenerateFromCast->value + ?Overwrite UICreatePrelayout_Form->UICreatePrelayout_Overwrite->value + ?SyncToNetlist UICreatePrelayout_Form->UICreatePrelayout_SyncToNetlist->value + ) + ) + ) +) + +( UICreateComponent + "UICreatePrelayout_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreatePrelayout_ViewName + ?prompt "Prelayout View Name" + ?defValue "prelayout" ) + ( hiCreateBooleanButton + ?name `UICreatePrelayout_SyncToNetlist + ?buttonText "Run Sync To Netlist on created Prelayout" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreatePrelayout_Overwrite + ?buttonText "Overwrite Existing Prelayout" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UICreatePrelayout_RegenerateFromCast + ?buttonText "Regenerate Routed Directive From Cast" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UICreatePrelayout_Verbose + ?buttonText "Verbose" + ?defValue nil ) + ( hiCreateFormButton + ?name `UICreatePrelayout_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Prelayout_Cellviews_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UICreatePrelayout_Form + ?formTitle "Create Prelayout Cellviews" + ?fields Fields + ?callback "( UICreatePrelayoutFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/ResolveOverlap.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/ResolveOverlap.il new file mode 100644 index 0000000000..901589f4f9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/ResolveOverlap.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +; +; menu item Nano/Prelayout +; +; reference function from Floorplan/ResolveOverlap.il +; +( list "2.Resolve Overlaps..." "UIResolveOverlap" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/.menu new file mode 100644 index 0000000000..bd30183fb8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/.menu @@ -0,0 +1 @@ +( list "2.Preroute Nets" "UIPreroute" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteOverlapMarkers.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteOverlapMarkers.il new file mode 100644 index 0000000000..bb04c0372b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteOverlapMarkers.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Nano/Preroute +; +; reference function from layout/bus/bus.il +; +( list "Delete Overlap Markers" "UIDeleteOverlapMarkers" ) + + +( UICreateMenuItemCallBack + `UIDeleteOverlapMarkersCB + (lambda () + DeleteMarkers() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteWires.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteWires.il new file mode 100644 index 0000000000..def463d3b5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DeleteWires.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Nano/Preroute +; +; reference function from layout/bus/bus.il +; +( list "Delete Wires" "UIDeleteWires" ) + + +( UICreateMenuItemCallBack + `UIDeleteWiresCB + (lambda () + DeleteWires() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DrawBusWire.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DrawBusWire.il new file mode 100644 index 0000000000..389d8652fc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/DrawBusWire.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Nano/Preroute +; +; reference function from layout/bus/bus.il +; +( list "Draw Bus Wires" "UIDrawBusWires" ) + + +( UICreateMenuItemCallBack + `UIDrawBusWiresCB + (lambda () + DrawWires() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/FindBusOverlaps.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/FindBusOverlaps.il new file mode 100644 index 0000000000..bdd384307e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/FindBusOverlaps.il @@ -0,0 +1,20 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Nano/Preroute +; +; reference function from layout/bus/bus.il +; +( list "Find Bus Wire Overlaps" "UIFindBusOverlaps" ) + + +( UICreateMenuItemCallBack + `UIFindBusOverlapsCB + (lambda () + FindBusOverlaps() + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/SetBusPattern.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/SetBusPattern.il new file mode 100644 index 0000000000..686cb6bc27 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Preroute/SetBusPattern.il @@ -0,0 +1,55 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Nano/Preroute +; +; reference function from layout/bus/bus.il +; +( list "Set Bus Wire Pattern..." "UISetBusPattern" ) + + +( UICreateMenuItemCallBack + `UISetBusPatternCB + (lambda () + hiDisplayForm( UISetBusPattern_Form ) + ) +) + + +( UICreateComponent + "UISetBusPattern_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UISetBusPattern_Pattern + ?prompt "Bus Pattern" + ?defValue "" ) + ( hiCreateFormButton + ?name `UISetBusPattern_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Preroute_Nets_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UISetBusPattern_Form + ?formTitle "Set Bus Wire Pattern" + ?fields Fields + ?callback "( UISetBusPatternFormCB )" + ) + ) + ) + ) +) + + +( UICreateAction + 'UISetBusPatternFormCB + (lambda () + SetPattern( UISetBusPattern_Form->UISetBusPattern_Pattern->value ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/.menu new file mode 100644 index 0000000000..fa89ee72ad --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/.menu @@ -0,0 +1 @@ +( list "Proteus" "UIProteus" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/.menu new file mode 100644 index 0000000000..fbcc1e12c8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/.menu @@ -0,0 +1 @@ +( list "3.Create Abstracts" "UIAbstracts" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateLeafAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateLeafAbstract.il new file mode 100644 index 0000000000..f34bd2d0fa --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateLeafAbstract.il @@ -0,0 +1,6 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateLeafAbstract.il#9 $ +; $DateTime: 2008/08/12 12:06:11 $ +; $Author: khe $ +( list "Create Leaf Cell Abstract..." "UICreateLeafAbstract" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateMidAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateMidAbstract.il new file mode 100644 index 0000000000..69bb33790b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreateMidAbstract.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreateMidAbstract.il#3 $ +; $DateTime: 2006/05/30 09:26:14 $ +; $Author: tomjones $ + +; +; menu item Nano/Abstracts +; +; reference function from Fulcrum/Route/CreateMidAbstract.il +; +( list "Create Mid-level Abstract..." "UICreateMidAbstract" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePowerGridAbstract.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePowerGridAbstract.il new file mode 100644 index 0000000000..4b10b8ceb6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePowerGridAbstract.il @@ -0,0 +1,11 @@ +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePowerGridAbstract.il#2 $ +; $DateTime: 2006/05/30 09:26:14 $ +; $Author: tomjones $ + +; +; menu item Nano/Abstracts +; +; reference function from CreateAbstract.il +; +( list "Create Power Grid Abstract..." "UIAutoPowerGridAbstract" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePrBound.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePrBound.il new file mode 100644 index 0000000000..9780a6b075 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/CreatePrBound.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Abstracts/CreatePrBound.il#2 $ +; $DateTime: 2006/05/30 09:26:14 $ +; $Author: tomjones $ + +; +; menu item Nano/Abstracts +; +; reference function from Floorplan/CreatePrBound.il +; +( list "Create prBound" "UICreatePrBound" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/ListMissingAbstracts.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/ListMissingAbstracts.il new file mode 100644 index 0000000000..2e2d7ccbcb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/ListMissingAbstracts.il @@ -0,0 +1,10 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Abstracts/ListMissingAbstracts.il#3 $ +; $DateTime: 2007/12/04 15:11:05 $ +; $Author: khe $ + +; +; menu item Nano/Abstracts +; +( list "List Missing Abstracts..." "UIListMissingAbstracts" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/.menu new file mode 100644 index 0000000000..333a0788d9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/.menu @@ -0,0 +1 @@ +( list "4.Export Design Files" "UIExport" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/CreateTracksDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/CreateTracksDef.il new file mode 100644 index 0000000000..1759595d08 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/CreateTracksDef.il @@ -0,0 +1,126 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/CreateTracksDef.il#10 $ +; $DateTime: 2008/01/15 10:43:46 $ +; $Author: stevemc $ + +; +; menu item Nano/Export +; +( list "5.Create Tracks DEF..." "UICreateTracksDefP" ) + + +( UICreateMenuItemCallBack + `UICreateTracksDefPCB + (lambda () + let(() + UICreateTracksDefP_Form->UICreateTracksDefP_RefDef->value = + strcat(UIGetCellView()~>cellName ".def") + UICreateTracksDefP_Form->UICreateTracksDefP_OutDef->value = + strcat(UIGetCellView()~>cellName "_tracks.def") + + hiDisplayForm( UICreateTracksDefP_Form ) + ) + ) +) + + +( UICreateComponent + "UICreateTracksDefP_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateTracksDefP_RefDef + ?prompt "Reference Design DEF Filename" + ?defValue "" ) + ( hiCreateStringField + ?name `UICreateTracksDefP_OutDef + ?prompt "Output DEF Filename" + ?defValue "tracks.def" ) + ( hiCreateBooleanButton + ?name `UICreateTracksDefP_E1of4 + ?buttonText "Use E1of4 Style Tracks" + ?defValue t ) + + ( hiCreateSeparatorField + ?name `UICreateFlattenView_sep1 ) + + ( hiCreateBooleanButton + ?name `UICreateTracksDefP_AutoOffsets + ?buttonText "Use Auto-Generated Offsets" + ?defValue t ) + ( hiCreateFloatField + ?name `UICreateTracksDefP_OffsetX + ?prompt " X Offset" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateTracksDefP_OffsetY + ?prompt " Y Offset" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateTracksDefP_OffsetE1of4X + ?prompt " E1of4 X Offset" + ?defValue 0.0 ) + ( hiCreateFloatField + ?name `UICreateTracksDefP_OffsetE1of4Y + ?prompt " E1of4 Y Offset" + ?defValue 0.0 ) + + ( hiCreateSeparatorField + ?name `UICreateFlattenView_sep2 ) + + ( hiCreateFloatField + ?name `UICreateTracksDefP_TrackPitch + ?prompt "Base Track Pitch" + ?defValue DefaultWiringPitch ) + + ( hiCreateFormButton + ?name `UICreateTracksDefP_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Create_Tracks_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UICreateTracksDefP_Form + ?formTitle "Create Tracks DEF" + ?fields Fields + ?callback "( UICreateTracksDefPFormCB )" + ) + hiSetFormSize( UICreateTracksDefP_Form list(601 585)) + ) + ) + ) +) + + +( UICreateAction + 'UICreateTracksDefPFormCB + (lambda () + let( (Command) + Command = sprintf( nil + "%s/genTracks --refdef=%s --outfile=%s --track-pitch=%.3f --rotate" + PackageGetBinRoot( ) + UICreateTracksDefP_Form->UICreateTracksDefP_RefDef->value + UICreateTracksDefP_Form->UICreateTracksDefP_OutDef->value + UICreateTracksDefP_Form->UICreateTracksDefP_TrackPitch->value + ) + if( UICreateTracksDefP_Form->UICreateTracksDefP_AutoOffsets->value == nil then + Command = sprintf( nil "%s --offsetx=%.3f --offsety=%.3f --offset-e1of4x=%.3f --offset-e1of4y=%.3f" + Command + UICreateTracksDefP_Form->UICreateTracksDefP_OffsetX->value + UICreateTracksDefP_Form->UICreateTracksDefP_OffsetY->value + UICreateTracksDefP_Form->UICreateTracksDefP_OffsetE1of4X->value + UICreateTracksDefP_Form->UICreateTracksDefP_OffsetE1of4Y->value) + ) + if( UICreateTracksDefP_Form->UICreateTracksDefP_E1of4->value then + Command = sprintf( nil "%s --e1of4" Command) + ) + printf( "%s\n" Command ) + shell( Command ) + printf( "Create Tracks DEF finished.\n" ) + + ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportDesignLef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportDesignLef.il new file mode 100644 index 0000000000..d05bab0c40 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportDesignLef.il @@ -0,0 +1,119 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignLef.il#3 $ +; $DateTime: 2006/07/07 15:13:59 $ +; $Author: tomjones $ + +; +; menu item Nano/Export +; +( list "2.Export Design LEF..." "UIExportDesignLefP" ) + + +( UICreateMenuItemCallBack + `UIExportDesignLefPCB + (lambda () + let((CellView powerCellName Components RComponents) + CellView = UIGetCellView() + Components = parseString( CellView~>cellName "." ) + RComponents = reverse( Components ) + if( length(RComponents)>=3 then + powerCellName = sprintf( nil "%s_%s" cadr(RComponents) car(RComponents)) + powerCellName = sprintf( nil "%s.wires.%s_POWER_GRID_TIEOFF" + car( NameParseCellName( CellView~>cellName )) powerCellName ) + UIExportDesignLefP_Form->UIExportDesignLefP_PowerGridCellName->value = powerCellName + ) + UIExportDesignLefP_Form->UIExportDesignLefP_OutFile->value = + strcat( CellView~>cellName ".lef") + UIExportDesignLefP_Form->UICreateAbstract_FulcrumPDKRoot->value = + getShellEnvVar( "FULCRUM_PDK_ROOT" ) + if(UIExportDesignLefP_Form->UICreateAbstract_DfIIDir->value == "default" then + UIExportDesignLefP_Form->UICreateAbstract_DfIIDir->value = + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + ) + + UIExportDesignLefP_Form->UIExportDesignLefP_LefCellsList->value = + strcat( CellView~>cellName ".flatten_cells_list") + hiDisplayForm( UIExportDesignLefP_Form ) + ) + ) +) + + +( UICreateAction + 'UIExportDesignLefPFormCB + (lambda () + let( (errorMsg CellView libName cellName viewName LogFile) + LogFile = "exportDesignLef.log" + nrDeleteToolSum( LogFile ) + CellView=UIGetCellView() + Command = sprintf( nil + "%s/exportDesignLef --cell-list=%s --dfII-dir=%s --design=%s --fulcrum-pdk-root=%s --lefout=%s --power-grid-cell=%s --include-USE" + PackageGetBinRoot( ) + UIExportDesignLefP_Form->UIExportDesignLefP_LefCellsList->value + UIExportDesignLefP_Form->UICreateAbstract_DfIIDir->value + CellView~>cellName + UIExportDesignLefP_Form->UICreateAbstract_FulcrumPDKRoot->value + UIExportDesignLefP_Form->UIExportDesignLefP_OutFile->value + UIExportDesignLefP_Form->UIExportDesignLefP_PowerGridCellName->value + ) + if( UIExportDesignLefP_Form->UIExportDesignLefP_OverWrite->value then + Command = sprintf( nil "%s --write-lef" Command) + ) + printf( "%s\n" Command ) + shell( Command ) + + ; display results + nrDisplayToolStatus( "Export Design LEF" + sprintf( nil "Export Design LEF for %s" CellView~>cellName ) + LogFile + ) + ) + ) +) + + +( UICreateComponent + "UIExportDesignLefP_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateAbstract_FulcrumPDKRoot + ?prompt "Fulcrum PDK Root" + ?defValue "default" ) + ( hiCreateStringField + ?name `UICreateAbstract_DfIIDir + ?prompt "DfII Dir" + ?defValue "default" ) + ( hiCreateStringField + ?name `UIExportDesignLefP_OutFile + ?prompt "LEF Filename" + ?defValue "lef.out" ) + ( hiCreateStringField + ?name `UIExportDesignLefP_LefCellsList + ?prompt "LEF Cells List" + ?defValue "flatten_cells_list" ) + ( hiCreateStringField + ?name `UIExportDesignLefP_PowerGridCellName + ?prompt "Power Grid Cell Name" + ?defValue "default" ) + ( hiCreateBooleanButton + ?name `UIExportDesignLefP_OverWrite + ?buttonText "Over Write Existing LEF File" + ?defValue t ) + ( hiCreateFormButton + ?name `UIExportDesignLefP_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Design_LEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIExportDesignLefP_Form + ?formTitle "Export Design LEF" + ?fields Fields + ?callback "( UIExportDesignLefPFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportNondefaultRuleDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportNondefaultRuleDef.il new file mode 100644 index 0000000000..ef631f9b46 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportNondefaultRuleDef.il @@ -0,0 +1,10 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportNondefaultRuleDef.il#2 $ +; $DateTime: 2006/05/30 09:26:14 $ +; $Author: tomjones $ + +; +; menu item Nano/Export +; +( list "4.Export Nondefault Rule DEF..." "UIExportNondefaultRuleDef" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportProteusFloorplanDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportProteusFloorplanDef.il new file mode 100644 index 0000000000..d3a5c839f3 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Export/ExportProteusFloorplanDef.il @@ -0,0 +1,201 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignDef.il#4 $ +; $DateTime: 2008/09/25 16:44:29 $ +; $Author: khe $ + +; +; menu item Proteus/ExportProteusFloorplanDef +; +; reference to Fulcrum/ExportProteusFloorplanDef +( list "3.Export Proteus Floorplan DEF..." "UIExportProteusDef" ) + +; moved FindInplacedPins to nano/util.il + +( UICreateMenuItemCallBack + `UIExportProteusDefCB + (lambda () + let((CellView powerCellName Components RComponents) + CellView = UIGetCellView() + Components = parseString( CellView~>cellName "." ) + RComponents = reverse( Components ) + if( length(RComponents)>=3 then + powerCellName = sprintf( nil "%s_%s" cadr(RComponents) car(RComponents)) + powerCellName = sprintf( nil "%s.wires.%s_POWER_GRID_TIEOFF" + car( NameParseCellName( CellView~>cellName )) powerCellName ) + UIExportProteusDef_Form->UIExportProteusDef_BlockageCellName->value = powerCellName + ) + UIExportProteusDef_Form->UIExportProteusDef_DefFileName->value = + strcat(UIGetCellView()~>cellName ".def") + UIExportProteusDef_Form->UIExportProteusDef_SetSkipRoutingFileName->value = + strcat(UIGetCellView()~>cellName ".SetSkipRouting.tcl") + hiDisplayForm( UIExportProteusDef_Form ) + ) + ) +) + +( UICreateAction + 'UIExportProteusDefFormCB + (lambda () + let( (CellView BlockageCellView) + CellView = UIGetCellView() + BlockageCellView= nil + + ; bbox should be aligned to power grid + grid = floor( UIExportProteusDef_Form->UIExportProteusDef_Grid->value*UIExportProteusDef_Form->UIExportProteusDef_Units->value) + printf("Grid %f\n" UIExportProteusDef_Form->UIExportProteusDef_Grid->value) + prBound=setof( lpp CellView~>lpps lpp~>layerName=="prBoundary" && lpp~>objType!="label" && lpp~>shapes ) + dieAreaXY1 = car(CellView~>bBox) + dieAreaXY2 = cadr(CellView~>bBox) + minX=floor( car(dieAreaXY1)*UIExportProteusDef_Form->UIExportProteusDef_Units->value) + minY=floor( car(dieAreaXY1)*UIExportProteusDef_Form->UIExportProteusDef_Units->value) + maxX=floor( car(dieAreaXY2)*UIExportProteusDef_Form->UIExportProteusDef_Units->value) + maxY=floor( car(dieAreaXY2)*UIExportProteusDef_Form->UIExportProteusDef_Units->value) + + warncnt=0; + if( ( modulo(minX,grid) != 0 ) then + printf( "Warning LLX is off grid (%d,%d)\n" minX,grid) + warncnt=1 + ) + if( ( modulo(minY,grid) != 0 ) then + printf( "Warning LLY is off grid (%d,%d)\n" minY,grid) + warncnt=1 + ) + if( ( modulo(maxX,grid) != 0 ) then + printf( "Warning URX is off grid (%d,%d)\n" maxX,grid) + warncnt=1 + ) + if( ( modulo(maxY,grid) != 0 ) then + printf( "Warning URY is off grid (%d,%d)\n" maxY,grid) + warncnt=1 + ) + + (let ( ( Cancel nil ) ) + if( ( warncnt == 1 ) then + ( hiDisplayAppDBox + ?name `UIExportProteusDefWarnForm + ?dboxBanner "DEF Off Grid Warning" + ?dboxText "Bounding box is not a multiple of the 5.76um power +grid.\nCannot export Proteus DEF.\nRegenerate POWER_GRID overlay." + ?buttons ( list "Write Anyway" "Cancel" ) + ?callback ( list "Cancel = nil" "Cancel = t" ) + ?buttonLayout `UserDefined + ?help nil + ) + ) + (CanonicalizePins) + dirmap = defGenerateP2DTable( ( getq CellView cellName ) nil ) + if( dirmap == nil then + let( ( basename cn ) + cn = ( getq CellView cellName ) + basename = cn + if(rexCompile( "\\.[^\\.]+$" ) then + basename=rexReplace( cn "" 0 ) ) + dirmap = defGenerateP2DTable( basename t ) + ) ) + + if( ( Cancel == nil ) then + if( UIExportProteusDef_Form->UIExportProteusDef_ExportBlockage->value then + BlockageCellView=nrOpenCellViewReadable( CellView~>libName + UIExportProteusDef_Form->UIExportProteusDef_BlockageCellName->value + "abstract" ) + ) + defDefOut( CellView~>libName CellView~>cellName CellView~>viewName + UIExportProteusDef_Form->UIExportProteusDef_DefFileName->value + ?Verbose UIExportProteusDef_Form->UIExportProteusDef_Verbose->value + ?DIVIDERCHAR "|" + ?BUSBITCHARS "<>" + ?UNITS UIExportProteusDef_Form->UIExportProteusDef_Units->value + ?OutputNets UIExportProteusDef_Form->UIExportProteusDef_OutputNets->value + ?OutputPins UIExportProteusDef_Form->UIExportProteusDef_OutputPins->value + ?AllSpecialNets UIExportProteusDef_Form->UIExportProteusDef_AllSpecialNets->value + ?PowerPins UIExportProteusDef_Form->UIExportProteusDef_PowerNets->value + ?transform list(0:0 UIExportProteusDef_Form->UIExportProteusDef_Rotation->value 1.0) + ?UseModuleName t + ?DirMap dirmap + ?BlockageCellView BlockageCellView + ) + pout=outfile(UIExportProteusDef_Form->UIExportProteusDef_SetSkipRoutingFileName->value) + fprintf(pout "proc ProteusUserSetSkipRouting {} {\n") + inplacedPins=FindInplacedPins(CellView) + foreach( pinName inplacedPins + rexCompile("\\[") + pinName=rexReplace(pinName "\\\\[" 0) + rexCompile("\\]") + pinName=rexReplace(pinName "\\\\]" 0) + fprintf(pout " setAttribute -net \"%s\" -skip_routing true\n" pinName) + ) + fprintf(pout "}\n") + close(pout) + ) + ) + ) + ) +) + + +( UICreateComponent + "UIExportProteusDef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UIExportProteusDef_DefFileName + ?prompt "DEF Filename" + ?defValue "def.out" ) + ( hiCreateStringField + ?name `UIExportProteusDef_SetSkipRoutingFileName + ?prompt "Set Skip Routing Filename" + ?defValue "skip.out" ) + ( hiCreateRadioField + ?name `UIExportProteusDef_Rotation + ?prompt "Rotation" + ?choices list( "R90") + ?defValue "R90" ) + ( hiCreateBooleanButton + ?name `UIExportProteusDef_OutputPins + ?buttonText "Output Pins" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIExportProteusDef_OutputNets + ?buttonText "Output Nets" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIExportProteusDef_AllSpecialNets + ?buttonText "Regard All Existing Wires As SPECIALNETS" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UIExportProteusDef_PowerNets + ?buttonText "Export Power Nets" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UIExportProteusDef_ExportBlockage + ?buttonText "ExportBlockage" + ?defValue t ) + ( hiCreateStringField + ?name `UIExportProteusDef_BlockageCellName + ?prompt "Blockage Cell Name" + ?defValue "" ) + ( hiCreateFloatField + ?name `UIExportProteusDef_Units + ?prompt "Units" + ?defValue 1000.0 ) + ( hiCreateFloatField + ?name `UIExportProteusDef_Grid + ?prompt "Grid" + ?defValue 5.76 ) + ( hiCreateFormButton + ?name `UIExportProteusDef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Design_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UIExportProteusDef_Form + ?formTitle "Export Design DEF" + ?fields Fields + ?callback "( UIExportProteusDefFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/.menu new file mode 100644 index 0000000000..d7b1e7d9fd --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/.menu @@ -0,0 +1 @@ +( list "2.Create Flatten" "UIFlatten" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreateCellList.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreateCellList.il new file mode 100644 index 0000000000..bedb145970 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreateCellList.il @@ -0,0 +1,10 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il#11 $ +; $DateTime: 2007/01/25 16:03:31 $ +; $Author: khe $ + +; +; menu item Nano/Flatten +; +( list "4.Create Flatten Cell List..." "UICreateCellList" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreatePowerGrid.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreatePowerGrid.il new file mode 100644 index 0000000000..6c5f9b0916 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/CreatePowerGrid.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/CreatePowerGrid.il#2 $ +; $DateTime: 2006/05/30 09:26:14 $ +; $Author: tomjones $ + +; +; menu item Nano/Flatten +; +; reference function from Fulcrum/AutoPowerGrid.il +; +( list "2.Create Power Grid Cell..." "UIAutoPowerGrid" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/DrawPins.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/DrawPins.il new file mode 100644 index 0000000000..3afb184078 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/DrawPins.il @@ -0,0 +1,12 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/DrawPins.il#3 $ +; $DateTime: 2006/05/30 09:26:14 $ +; $Author: tomjones $ + +; +; menu item Nano/Flatten +; +; reference function from Fulcrum/Bus/DrawAllPins.il +; +( list "2.Draw Pins" "UIDrawAllPins" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/FlattenView.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/FlattenView.il new file mode 100644 index 0000000000..00899c5d50 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Flatten/FlattenView.il @@ -0,0 +1,47 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il#13 $ +; $DateTime: 2009/05/18 11:19:56 $ +; $Author: stevemc $ + +; +; menu item Nano/Flatten +; +( list "1.Create Flatten View..." "UICreateProteusFlattenView" ) + +( UICreateMenuItemCallBack + `UICreateProteusFlattenViewCB + (lambda () + let((CellView powerCellName CellBaseName OBSCellName BusWireCellName Components RComponents) + CellView = UIGetCellView() + Components = parseString( CellView~>cellName "." ) + CellBaseName = cadr( reverse( parseString( CellView~>cellName "." ) )) + RComponents = reverse( Components ) + if( length(RComponents) >= 3 then + powerCellName = sprintf( nil "%s_%s" cadr(RComponents) car(RComponents)) + OBSCellName = strcat( CellView~>libName ".wires." CellBaseName) + BusWireCellName = strcat( CellView~>libName ".wires." CellBaseName "_buswires") + powerCellName = sprintf( nil "%s.wires.%s_POWER_GRID_TIEOFF" + car( NameParseCellName( CellView~>cellName )) powerCellName ) + UICreateFlattenView_Form->UICreateFlattenView_OBSCellName->value = OBSCellName + UICreateFlattenView_Form->UICreateFlattenView_PowerGridCellName->value = powerCellName + UICreateFlattenView_Form->UICreateFlattenView_BusWireCellName->value = BusWireCellName + ) + UICreateFlattenView_Form->UICreateAbstract_FulcrumPDKRoot->value= + getShellEnvVar( "FULCRUM_PDK_ROOT" ) + if(UICreateFlattenView_Form->UICreateAbstract_DfIIDir->value== "default" then + UICreateFlattenView_Form->UICreateAbstract_DfIIDir->value= + NameGetDFIIDirFromCellName( UIGetCellView()~>cellName) + ) + if(UICreateFlattenView_Form->UICreateAbstract_P4Client->value== "default" then + UICreateFlattenView_Form->UICreateAbstract_P4Client->value= + ConfigFileGetValue( TheCDSConfigTable "P4CLIENT" ) + ) + UICreateFlattenView_Form->UICreateFlattenView_FlattenCellsList->value= + strcat( CellView~>cellName ".flatten_cells_list") + UICreateFlattenView_Form->UICreateFlattenView_M3PowerPins->value=t + UICreateFlattenView_Form->UICreateFlattenView_ResolveM3MacroConflict->value=t + UICreateFlattenView_Form->UICreateFlattenView_Class->value="cover" + hiDisplayForm( UICreateFlattenView_Form ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/.menu new file mode 100644 index 0000000000..097de709c5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/.menu @@ -0,0 +1 @@ +( list "1.Create Prelayout" "UIPrelayout" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrBound.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrBound.il new file mode 100644 index 0000000000..e41b44437f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrBound.il @@ -0,0 +1,8 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/CreateCDL.il#11 $ +; $DateTime: 2004/08/21 16:39:54 $ +; $Author: clayton $ + + +( list "2.Create prBound" "UICreatePrBound" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrelayout.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrelayout.il new file mode 100644 index 0000000000..d71837e42c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/CreatePrelayout.il @@ -0,0 +1,10 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Prelayout/CreatePrelayout.il#5 $ +; $DateTime: 2007/01/11 17:54:06 $ +; $Author: khe $ + +; +; menu item Nano/Prelayout +; +( list "1.Create Prelayout Cellviews..." "UICreatePrelayout" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/DrawWires.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/DrawWires.il new file mode 100644 index 0000000000..660759ccc0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/DrawWires.il @@ -0,0 +1,13 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Fulcrum/Bus +; +; reference function from layout/bus/bus.il +; +( list "4.Draw Bus Scripts Alt-b" "UIDrawWires" ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/FlushAndSync.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/FlushAndSync.il new file mode 100644 index 0000000000..2ce27d43b9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/FlushAndSync.il @@ -0,0 +1,15 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/CreateCDL.il#11 $ +; $DateTime: 2004/08/21 16:39:54 $ +; $Author: clayton $ + + +( list "5.Flush Design and Sync" "UIFlushAndSync" ) + + +( UICreateMenuItemCallBack + `UIFlushAndSyncCB + (lambda () + (FlushAndSync (geGetEditCellView)) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/GetCellArea.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/GetCellArea.il new file mode 100644 index 0000000000..85685a862b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Prelayout/GetCellArea.il @@ -0,0 +1,8 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/CreateCDL.il#11 $ +; $DateTime: 2004/08/21 16:39:54 $ +; $Author: clayton $ + + +( list "3.Calculate Area" "UIGetCellArea" ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/.menu b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/.menu new file mode 100644 index 0000000000..571d5a588d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/.menu @@ -0,0 +1 @@ +( list "Synchronous" "UISynch" ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/AllSync.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/AllSync.il new file mode 100644 index 0000000000..0e24c0a412 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/AllSync.il @@ -0,0 +1,345 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Synch/All + +; 0.All SyncExport +; 1.Flush Design +; 2.Create Guide Instance +; 3.Create Cells List... +; 4.Create GND Shield TieOff Cell +; 5.Export Design LEF... +; 6.Export Design DEF... +; 7.Export Nondefault Rule DEF... + + +( list "0.All SyncExport" "UISyAllExport" ) + + + +( UICreateMenuItemCallBack + `UISyAllExportCB + (lambda () + let((CellView) + CellView = UIGetCellView() + CellBase = cadr( reverse( parseString( CellView~>cellName "." ) )) + UISyAllExport_Form->UISyAllExport_cellname->value = + strcat( CellView~>libName ".wires." CellBase "_buswires") + ) + let((CellView CellBase) + CellView = UIGetCellView() + CellBase=cadr( reverse( parseString( CellView~>cellName ".") ) ) + UISyAllExport_Form->UISyAllExport_BusWireCellName->value= + strcat(CellView~>libName ".wires." CellBase "_buswires") + UISyAllExport_Form->UISyAllExport_CellsList->value= + strcat( CellView~>cellName ".flatten_cells_list") + ) + let((CellView) + CellView = UIGetCellView() + CellBase = cadr( reverse( parseString( CellView~>cellName "." ) )) + UISyAllExport_Form->UISyAllExport_TieDownCellName->value = + strcat( CellView~>libName ".wires." CellBase "_" TieDownCellName) + UISyAllExport_Form->UISyAllExport_CellList->value = + strcat( CellView~>cellName ".flatten_cells_list") + ) + let((CellView) + CellView = UIGetCellView() + UISyAllExport_Form->UISyAllExport_LefFile->value = + strcat( CellView~>cellName ".lef") + UISyAllExport_Form->UICreateAbstract_FulcrumPDKRoot->value = + getShellEnvVar( "FULCRUM_PDK_ROOT" ) + if(UISyAllExport_Form->UICreateAbstract_DfIIDir->value == "default" then + UISyAllExport_Form->UICreateAbstract_DfIIDir->value = + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + ) + + UISyAllExport_Form->UISyAllExport_LefCellsList->value = + strcat( CellView~>cellName ".flatten_cells_list") + ) + let((CellView Components RComponents) + CellView = UIGetCellView() + UISyAllExport_Form->UISyAllExport_BlockageCellName->value = CellView~>cellName + UISyAllExport_Form->UISyAllExport_BlockageCellView->value = CellView~>viewName + UISyAllExport_Form->UISyAllExport_DefFileName->value = + strcat( CellView~>cellName ".def") + ) + hiDisplayForm( UISyAllExport_Form ) + ) +) + + +( UICreateComponent + "UISyAllExport_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateBooleanButton + ?name `UISyAllExport_doFlush + ?buttonText ">>> Flush" + ?defValue t ) + ( hiCreateSeparatorField + ?name `UISyAllExport_sep0 ) + ( hiCreateBooleanButton + ?name `UISyAllExport_doGuide + ?buttonText ">>> Create Guide Instance" + ?defValue t ) + ( hiCreateStringField + ?name `UISyAllExport_cellname + ?prompt " Cell Name" + ?defValue "" ) + ( hiCreateStringField + ?name `UISyAllExport_instname + ?prompt " Instance Name" + ?defValue "buswires" ) + ( hiCreateBooleanButton + ?name `UISyAllExport_wires + ?buttonText " Create wires.il" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UISyAllExport_defchans + ?buttonText " Include global DefChans in wires.il" + ?defValue t ) + ( hiCreateSeparatorField + ?name `UISyAllExport_sep1 ) + ( hiCreateBooleanButton + ?name `UISyAllExport_doCellsList + ?buttonText ">>> Create Cells List" + ?defValue t ) + ( hiCreateStringField + ?name `UISyAllExport_CellsList + ?prompt " Cells List" + ?defValue "flatten_cells_list" ) + ( hiCreateStringField + ?name `UISyAllExport_BusWireCellName + ?prompt " Bus Wires Cell Name" + ?defValue "BUSWIRES" ) + + ( hiCreateBooleanButton + ?name `UISyAllExport_Verbose + ?buttonText " Verbose" + ?defValue nil ) + ( hiCreateSeparatorField + ?name `UISyAllExport_sep2 ) + ( hiCreateBooleanButton + ?name `UISyAllExport_doTieCell + ?buttonText ">>> Create GND Tie Down Cell" + ?defValue t ) + ( hiCreateStringField + ?name `UISyAllExport_TieDownCellName + ?prompt " Tie Down Cell Name" + ?defValue "default" ) + ( hiCreateStringField + ?name `UISyAllExport_TieDownViewName + ?prompt " Tie Down View Name" + ?defValue "layout" ) + ( hiCreateStringField + ?name `UISyAllExport_CellList + ?prompt " LEF Cells List" + ?defValue "default" ) + ( hiCreateBooleanButton + ?name `UISyAllExport_TreatGndNetAsPin + ?buttonText " Treat GND Nets as Pins" + ?defValue t ) + ( hiCreateSeparatorField + ?name `UISyAllExport_sep3 ) + ( hiCreateBooleanButton + ?name `UISyAllExport_doExportLef + ?buttonText ">>> Export Design Lef" + ?defValue t ) + ( hiCreateStringField + ?name `UICreateAbstract_FulcrumPDKRoot + ?prompt " Fulcrum PDK Root" + ?defValue "default" ) + ( hiCreateStringField + ?name `UICreateAbstract_DfIIDir + ?prompt " DfII Dir" + ?defValue "default" ) + ( hiCreateStringField + ?name `UISyAllExport_LefFile + ?prompt " LEF Filename" + ?defValue "lef.out" ) + ( hiCreateStringField + ?name `UISyAllExport_LefCellsList + ?prompt " LEF Cells List" + ?defValue "flatten_cells_list" ) + ( hiCreateBooleanButton + ?name `UISyAllExport_OverWrite + ?buttonText " Over Write Existing LEF File" + ?defValue t ) + ( hiCreateSeparatorField + ?name `UISyAllExport_sep4 ) + ( hiCreateBooleanButton + ?name `UISyAllExport_doDEF + ?buttonText ">>> Export Design DEF" + ?defValue t ) + ( hiCreateStringField + ?name `UISyAllExport_DefFileName + ?prompt " DEF Filename" + ?defValue "def.out" ) + ( hiCreateBooleanButton + ?name `UISyAllExport_OutputNets + ?buttonText " Output Nets" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UISyAllExport_AllSpecialNets + ?buttonText " Regard All Existing Wires As SPECIALNETS" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UISyAllExport_PowerNets + ?buttonText " Export Power Nets" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UISyAllExport_ExportBlockage + ?buttonText " ExportBlockage" + ?defValue t ) + ( hiCreateStringField + ?name `UISyAllExport_BlockageCellName + ?prompt " Blockage Cell Name" + ?defValue "" ) + ( hiCreateStringField + ?name `UISyAllExport_BlockageCellView + ?prompt " Blockage Cell View" + ?defValue "floorplan" ) + ( hiCreateFloatField + ?name `UISyAllExport_Units + ?prompt " Units" + ?defValue 1000.0 ) + ) + ( hiCreateAppForm + ?name `UISyAllExport_Form + ?formTitle " Synchrnonous Export All (Experimental!)" + ?fields Fields + ?callback "( UISyAllExportFormCB )" + ) + hiSetFormMinMaxSize( UISyAllExport_Form list(901 400) list(2000 2000)) + hiSetFormSize( UISyAllExport_Form list(801 985)) + ) + ) + ) +) + + +( UICreateAction + 'UISyAllExportFormCB + (lambda () + if( UISyAllExport_Form->doFlush (FlushDesignFiles ( UIGetCellView() ) ) ) + if( UISyAllExport_Form->doGuide + print( "Guide\n" ) + let( (CellView) + CellView=UIGetCellView() + MakeGuideInst( UISyAllExport_Form->UISyAllExport_cellname->value + UISyAllExport_Form->UISyAllExport_instname->value ) + when( UISyAllExport_Form->UISyAllExport_wires->value + MakeWiresSkill( UISyAllExport_Form->UISyAllExport_instname->value + UISyAllExport_Form->UISyAllExport_defchans->value ) + ) + ) + ) + if( UISyAllExport_Form->doCellsList + print( "CellsList\n" ) + let( (CellView) + CellView= UIGetCellView() + clCreateCellList( + CellView + UISyAllExport_Form->UISyAllExport_CellsList->value + UISyAllExport_Form->UISyAllExport_BusWireCellName->value + ?Verbose UISyAllExport_Form->UISyAllExport_Verbose->value + ) + ) + ) + if( UISyAllExport_Form->doTieCell + print( "TieCell\n" ) + let( (errorMsg CellView libName cellName viewName LogFile ToolName) + CellView=UIGetCellView() + CreateTieDownCell( CellView + ?dstLibName CellView~>libName + ?dstCellName UISyAllExport_Form->UISyAllExport_TieDownCellName->value + ?dstViewName UISyAllExport_Form->UISyAllExport_TieDownViewName->value + ?dstSynchronous t + ?dstCustom t + ?dstSynchronous t + ?treatGNDNetsAsPins UISyAllExport_Form->UISyAllExport_TreatGndNetAsPin->value + ) + ; add the line to lef list file. + if( system(sprintf(nil "grep %s %s" UISyAllExport_Form->UISyAllExport_TieDownCellName->value UISyAllExport_Form->UISyAllExport_CellList->value ))==1 then + system(sprintf(nil "echo '%s %s abstract' >> %s" CellView~>libName UISyAllExport_Form->UISyAllExport_TieDownCellName->value UISyAllExport_Form->UISyAllExport_CellList->value)) + ) + + ) + ) + if( UISyAllExport_Form->doExportLef + print( "Lef\n" ) + let( (errorMsg CellView libName cellName viewName LogFile) + LogFile = "exportDesignLef.log" + nrDeleteToolSum( LogFile ) + CellView=UIGetCellView() + Command = sprintf( nil + "%s/exportDesignLef --cell-list=%s --dfII-dir=%s --design=%s --fulcrum-pdk-root=%s --power-grid-cell=none --lefout=%s" + PackageGetBinRoot( ) + UISyAllExport_Form->UISyAllExport_LefCellsList->value + UISyAllExport_Form->UICreateAbstract_DfIIDir->value + CellView~>cellName + UISyAllExport_Form->UICreateAbstract_FulcrumPDKRoot->value + UISyAllExport_Form->UISyAllExport_LefFile->value + ) + if( UISyAllExport_Form->UISyAllExport_OverWrite->value then + Command = sprintf( nil "%s --write-lef" Command) + ) + printf( "%s\n" Command ) + shell( Command ) + + ) + ) + if( UISyAllExport_Form->doExportDef + print( "Def\n" ) + let( (CellView pinmap mapfile tempdir Synchronous BlockageCellView) + CellView= UIGetCellView() + BlockageCellView= nil + Synchronous=t + pinmap = nil + dirmap = defGenerateP2DTable( ( getq CellView cellName ) nil ) + if( Synchronous then + pinmap = defGenerateC2VTable( ( getq CellView cellName ) nil ) ) + if( dirmap == nil then + let( ( basename cn ) + cn = ( getq CellView cellName ) + basename = cn + if(rexCompile( "\\.[^\\.]+$" ) then + basename=rexReplace( cn "" 0 ) ) + dirmap = defGenerateP2DTable( basename t ) + ) ) + if( Synchronous && ! pinmap then + let( ( basename cn ) + cn = ( getq CellView cellName ) + basename = cn + if(rexCompile( "\\.[^\\.]+$" ) then + basename=rexReplace( cn "" 0 ) ) + pinmap = defGenerateC2VTable( basename t ) + ) ) + if( UISyAllExport_Form->UISyAllExport_ExportBlockage->value then + BlockageCellView=nrOpenCellViewReadable( CellView~>libName + UISyAllExport_Form->UISyAllExport_BlockageCellName->value + UISyAllExport_Form->UISyAllExport_BlockageCellView->value ) + ) + defDefOut( CellView~>libName CellView~>cellName CellView~>viewName + UISyAllExport_Form->UISyAllExport_DefFileName->value + ?Verbose UISyAllExport_Form->UISyAllExport_Verbose->value + ?DIVIDERCHAR "|" + ?BUSBITCHARS "<>" + ?UNITS UISyAllExport_Form->UISyAllExport_Units->value + ?OutputNets UISyAllExport_Form->UISyAllExport_OutputNets->value + ?AllSpecialNets UISyAllExport_Form->UISyAllExport_AllSpecialNets->value + ?PowerPins UISyAllExport_Form->UISyAllExport_PowerNets->value + ?Synchronous t + ?PinMap pinmap + ?DirMap dirmap + ?BlockageCellView BlockageCellView + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateCellList.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateCellList.il new file mode 100644 index 0000000000..31e111bbb8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateCellList.il @@ -0,0 +1,101 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Flatten/FlattenView.il#13 $ +; $DateTime: 2009/05/18 11:19:56 $ +; $Author: stevemc $ + +; +; menu item Sync/CreateCellList +; +( list "3.Create Cells List..." "UISyCreateCellList" ) + +defun( clCreateCellList (CellView + celllist_filename + BusWireCellName + @key + ( Verbose nil ) + ) + + let((temp) + + instances= CellView~>instances + uniqueInstances=nil + foreach( inst instances + if( !member( inst~>cellName uniqueInstances~>cellName ) then + uniqueInstances=cons( inst uniqueInstances ) + ) + ) + pout=outfile(celllist_filename) + if( pout then + foreach( inst uniqueInstances + unless( inst~>cellName == BusWireCellName || rexMatchp( "^vendor\\." inst~>cellName ) fprintf( pout "%s %s %s\n" inst~>libName inst~>cellName "abstract") ) + ) + close(pout) + ) + + ) +) + +( UICreateMenuItemCallBack + `UISyCreateCellListCB + (lambda () + let((CellView CellBase) + CellView = UIGetCellView() + CellBase=cadr( reverse( parseString( CellView~>cellName ".") ) ) + UISyCreateCellList_Form->UISyCreateCellList_BusWireCellName->value= + strcat(CellView~>libName ".wires." CellBase "_buswires") + UISyCreateCellList_Form->UISyCreateCellList_CellsList->value= + strcat( CellView~>cellName ".flatten_cells_list") + hiDisplayForm( UISyCreateCellList_Form ) + ) + ) +) + + +( UICreateComponent + "UISyCreateCellList_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UISyCreateCellList_CellsList + ?prompt " Cells List" + ?defValue "flatten_cells_list" ) + ( hiCreateStringField + ?name `UISyCreateCellList_BusWireCellName + ?prompt " Bus Wires Cell Name" + ?defValue "BUSWIRES" ) + + ( hiCreateSeparatorField + ?name `UISyCreateCellList_sep0 ) + ( hiCreateBooleanButton + ?name `UISyCreateCellList_Verbose + ?buttonText "Verbose" + ?defValue nil ) + ) + ( hiCreateAppForm + ?name `UISyCreateCellList_Form + ?formTitle "Create Cell List" + ?fields Fields + ?callback "( UISyCreateCellListFormCB )" + ) + hiSetFormSize( UISyCreateCellList_Form list(601 585)) + ) + ) + ) +) + +( UICreateAction + 'UISyCreateCellListFormCB + (lambda () + let( (CellView) + CellView= UIGetCellView() + clCreateCellList( + CellView + UISyCreateCellList_Form->UISyCreateCellList_CellsList->value + UISyCreateCellList_Form->UISyCreateCellList_BusWireCellName->value + ?Verbose UISyCreateCellList_Form->UISyCreateCellList_Verbose->value + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateGuideInst.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateGuideInst.il new file mode 100644 index 0000000000..a18eacc191 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/CreateGuideInst.il @@ -0,0 +1,71 @@ +; Copyright 2006 Fulcrum Microsystems. All rights reserved. +; $Id: $ +; $DateTime: $ +; $Author: $ + +; +; menu item Synch/Bus +( list "2.Create Guide Instance,,," "UISyCreateGuideInst" ) + + +( UICreateMenuItemCallBack + `UISyCreateGuideInstCB + (lambda () + let((CellView) + CellView = UIGetCellView() + CellBase = cadr( reverse( parseString( CellView~>cellName "." ) )) + UISyCreateGuideInst_Form->UISyCreateGuideInst_cellname->value = + strcat( CellView~>libName ".wires." CellBase "_buswires") + hiDisplayForm( UISyCreateGuideInst_Form ) + )) +) + + +( UICreateComponent + "UISyCreateGuideInst_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UISyCreateGuideInst_cellname + ?prompt "Cell Name" + ?defValue "" ) + ( hiCreateStringField + ?name `UISyCreateGuideInst_instname + ?prompt "Instance Name" + ?defValue "buswires" ) + ( hiCreateBooleanButton + ?name `UISyCreateGuideInst_wires + ?buttonText "Create wires.il" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UISyCreateGuideInst_defchans + ?buttonText "Include global DefChans in wires.il" + ?defValue t ) + ) + ( hiCreateAppForm + ?name `UISyCreateGuideInst_Form + ?formTitle "Create Guide Instance" + ?fields Fields + ?callback "( UISyCreateGuideInstFormCB )" + ) + ) + ) + ) +) + + +( UICreateAction + 'UISyCreateGuideInstFormCB + (lambda () + MakeGuideInst( UISyCreateGuideInst_Form->UISyCreateGuideInst_cellname->value + UISyCreateGuideInst_Form->UISyCreateGuideInst_instname->value ) + when( UISyCreateGuideInst_Form->UISyCreateGuideInst_wires->value + MakeWiresSkill( UISyCreateGuideInst_Form->UISyCreateGuideInst_instname->value + UISyCreateGuideInst_Form->UISyCreateGuideInst_defchans->value ) + ) + ) +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignDef.il new file mode 100644 index 0000000000..865bf6b53c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignDef.il @@ -0,0 +1,127 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignDef.il#12 $ +; $DateTime: 2009/09/10 16:49:16 $ +; $Author: khe $ + +; +; menu item Nano/Export +; +( list "6.Export Design DEF..." "UISyExportDesignDef" ) + + +( UICreateMenuItemCallBack + `UISyExportDesignDefCB + (lambda () + let((CellView Components RComponents) + CellView = UIGetCellView() + UISyExportDesignDef_Form->UISyExportDesignDef_BlockageCellName->value = CellView~>cellName + UISyExportDesignDef_Form->UISyExportDesignDef_BlockageCellView->value = CellView~>viewName + UISyExportDesignDef_Form->UISyExportDesignDef_DefFileName->value = + strcat( UIGetCellView()~>cellName ".def") + hiDisplayForm( UISyExportDesignDef_Form ) + ) + ) +) + +( UICreateAction + 'UISyExportDesignDefFormCB + (lambda () + let( (CellView pinmap mapfile tempdir Synchronous BlockageCellView) + CellView= UIGetCellView() + BlockageCellView= nil + Synchronous=t + pinmap = nil + dirmap = nil + if( dirmap == nil then + let( ( basename cn ) + cn = ( getq CellView cellName ) + basename = cn + if(rexCompile( "\\.[^\\.]+$" ) then + basename=rexReplace( cn "" 0 ) ) + dirmap = defGenerateP2DTable( basename t ) + ) ) + if( Synchronous && ! pinmap then + let( ( basename cn ) + cn = ( getq CellView cellName ) + basename = cn + if(rexCompile( "\\.[^\\.]+$" ) then + basename=rexReplace( cn "" 0 ) ) + pinmap = defGenerateC2VTable( basename t ) + ) ) + if( UISyExportDesignDef_Form->UISyExportDesignDef_ExportBlockage->value then + BlockageCellView=nrOpenCellViewReadable( CellView~>libName + UISyExportDesignDef_Form->UISyExportDesignDef_BlockageCellName->value + UISyExportDesignDef_Form->UISyExportDesignDef_BlockageCellView->value ) + ) + defDefOut( CellView~>libName CellView~>cellName CellView~>viewName + UISyExportDesignDef_Form->UISyExportDesignDef_DefFileName->value + ?Verbose UISyExportDesignDef_Form->UISyExportDesignDef_Verbose->value + ?DIVIDERCHAR "|" + ?BUSBITCHARS "<>" + ?UNITS UISyExportDesignDef_Form->UISyExportDesignDef_Units->value + ?OutputNets UISyExportDesignDef_Form->UISyExportDesignDef_OutputNets->value + ?AllSpecialNets UISyExportDesignDef_Form->UISyExportDesignDef_AllSpecialNets->value + ?PowerPins UISyExportDesignDef_Form->UISyExportDesignDef_PowerNets->value + ?Synchronous t + ?PinMap pinmap + ?DirMap dirmap + ?BlockageCellView BlockageCellView + ) + ) + ) +) + + +( UICreateComponent + "UISyExportDesignDef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UISyExportDesignDef_DefFileName + ?prompt "DEF Filename" + ?defValue "def.out" ) + ( hiCreateBooleanButton + ?name `UISyExportDesignDef_OutputNets + ?buttonText "Output Nets" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UISyExportDesignDef_AllSpecialNets + ?buttonText "Regard All Existing Wires As SPECIALNETS" + ?defValue nil ) + ( hiCreateBooleanButton + ?name `UISyExportDesignDef_PowerNets + ?buttonText "Export Power Nets" + ?defValue t ) + ( hiCreateBooleanButton + ?name `UISyExportDesignDef_ExportBlockage + ?buttonText "ExportBlockage" + ?defValue t ) + ( hiCreateStringField + ?name `UISyExportDesignDef_BlockageCellName + ?prompt "Blockage Cell Name" + ?defValue "" ) + ( hiCreateStringField + ?name `UISyExportDesignDef_BlockageCellView + ?prompt "Blockage Cell View" + ?defValue "floorplan" ) + ( hiCreateFloatField + ?name `UISyExportDesignDef_Units + ?prompt "Units" + ?defValue 1000.0 ) + ( hiCreateFormButton + ?name `UISyExportDesignDef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Design_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UISyExportDesignDef_Form + ?formTitle "Export Design DEF" + ?fields Fields + ?callback "( UISyExportDesignDefFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignLef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignLef.il new file mode 100644 index 0000000000..8d0ef6b065 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportDesignLef.il @@ -0,0 +1,106 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportDesignLef.il#4 $ +; $DateTime: 2009/08/18 11:38:11 $ +; $Author: stevemc $ + +; +; menu item Nano/Export +; +( list "5.Export Design LEF..." "UISyExportDesignLef" ) + + +( UICreateMenuItemCallBack + `UISyExportDesignLefCB + (lambda () + let((CellView) + CellView = UIGetCellView() + UISyExportDesignLef_Form->UISyExportDesignLef_OutFile->value = + strcat( CellView~>cellName ".lef") + UISyExportDesignLef_Form->UICreateAbstract_FulcrumPDKRoot->value = + getShellEnvVar( "FULCRUM_PDK_ROOT" ) + if(UISyExportDesignLef_Form->UICreateAbstract_DfIIDir->value == "default" then + UISyExportDesignLef_Form->UICreateAbstract_DfIIDir->value = + ConfigFileGetValue( TheCDSConfigTable "DFII_DIR" ) + ) + + UISyExportDesignLef_Form->UISyExportDesignLef_LefCellsList->value = + strcat( CellView~>cellName ".flatten_cells_list") + hiDisplayForm( UISyExportDesignLef_Form ) + ) + ) +) + + +( UICreateAction + 'UISyExportDesignLefFormCB + (lambda () + let( (errorMsg CellView libName cellName viewName LogFile) + LogFile = "exportDesignLef.log" + nrDeleteToolSum( LogFile ) + CellView=UIGetCellView() + Command = sprintf( nil + "%s/exportDesignLef --cell-list=%s --dfII-dir=%s --design=%s --fulcrum-pdk-root=%s --power-grid-cell=none --lefout=%s" + PackageGetBinRoot( ) + UISyExportDesignLef_Form->UISyExportDesignLef_LefCellsList->value + UISyExportDesignLef_Form->UICreateAbstract_DfIIDir->value + CellView~>cellName + UISyExportDesignLef_Form->UICreateAbstract_FulcrumPDKRoot->value + UISyExportDesignLef_Form->UISyExportDesignLef_OutFile->value + ) + if( UISyExportDesignLef_Form->UISyExportDesignLef_OverWrite->value then + Command = sprintf( nil "%s --write-lef" Command) + ) + printf( "%s\n" Command ) + shell( Command ) + + ; display results + nrDisplayToolStatus( "Export Design LEF" + sprintf( nil "Export Design LEF for %s" CellView~>cellName ) + LogFile + ) + ) + ) +) + + +( UICreateComponent + "UISyExportDesignLef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UICreateAbstract_FulcrumPDKRoot + ?prompt "Fulcrum PDK Root" + ?defValue "default" ) + ( hiCreateStringField + ?name `UICreateAbstract_DfIIDir + ?prompt "DfII Dir" + ?defValue "default" ) + ( hiCreateStringField + ?name `UISyExportDesignLef_OutFile + ?prompt "LEF Filename" + ?defValue "lef.out" ) + ( hiCreateStringField + ?name `UISyExportDesignLef_LefCellsList + ?prompt "LEF Cells List" + ?defValue "flatten_cells_list" ) + ( hiCreateBooleanButton + ?name `UISyExportDesignLef_OverWrite + ?buttonText "Over Write Existing LEF File" + ?defValue t ) + ( hiCreateFormButton + ?name `UISyExportDesignLef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Design_LEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UISyExportDesignLef_Form + ?formTitle "Export Design LEF" + ?fields Fields + ?callback "( UISyExportDesignLefFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportNondefaultRuleDef.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportNondefaultRuleDef.il new file mode 100644 index 0000000000..35c51fd25c --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/ExportNondefaultRuleDef.il @@ -0,0 +1,87 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/ui/Nano/Export/ExportNondefaultRuleDef.il#2 $ +; $DateTime: 2006/05/30 09:26:14 $ +; $Author: tomjones $ + +; +; menu item Nano/Export +; +( list "7.Export Nondefault Rule DEF..." "UISyExportNondefaultRuleDef" ) + + +( UICreateMenuItemCallBack + `UISyExportNondefaultRuleDefCB + (lambda () + UISyExportNondefaultRuleDef_Form->UISyExportNondefaultRuleDef_OutFile->value= + strcat( UIGetCellView()~>cellName "_nondefault.def") + hiDisplayForm( UISyExportNondefaultRuleDef_Form ) + ) +) + + +( UICreateAction + 'UISyExportNondefaultRuleDefFormCB + (lambda () + let( (CellView Command ToolName) + CellView= UIGetCellView() + Command = sprintf( nil + "%s/cast2def --cast-path=%s --cell=%s --outfile=%s --cadence-name --max-heap-size=%s &> %s" + PackageGetBinRoot( ) + ConfigFileGetValue( TheCDSConfigTable "CAST_PATH" ) + CellView~>cellName + UISyExportNondefaultRuleDef_Form->UISyExportNondefaultRuleDef_OutFile->value + UISyExportNondefaultRuleDef_Form->UISyExportNondefaultRuleDef_HeapSize->value + UISyExportNondefaultRuleDef_Form->UISyExportNondefaultRuleDef_LogFile->value + ) + printf( "%s\n" Command ) + shell( Command ) + + ; display results + printf( "Nondefault Rule File %s is created.\n" UISyExportNondefaultRuleDef_Form->UISyExportNondefaultRuleDef_OutFile->value) + ToolName = "Export Nondefault Rule DEF" + hiDisplayAppDBox( + ?name `UISyExportNondefaultRuleDef_StatusDbox + ?dboxBanner strcat( ToolName " Status") + ?dboxText sprintf( nil "%s finished. View log file?" ToolName) + ?buttonLayout 'YesNo + ?defaultButton 1 + ?callback "nrDisplayLogFile( ToolName UISyExportNondefaultRuleDef_Form->UISyExportNondefaultRuleDef_LogFile->value )" + ) + ) + ) +) + + +( UICreateComponent + "UISyExportNondefaultRuleDef_Form" + ( UICreateConstructor + (lambda ( Children ) + (let ( Fields ) + Fields = list( + ( hiCreateStringField + ?name `UISyExportNondefaultRuleDef_OutFile + ?prompt "DEF Filename" + ?defValue "routing.def" ) + ( hiCreateStringField + ?name `UISyExportNondefaultRuleDef_LogFile + ?prompt "Log Filename" + ?defValue "exportNondefaultRuleDEF.log" ) + ( hiCreateStringField + ?name `UISyExportNondefaultRuleDef_HeapSize + ?prompt "Max Memory Heap Size" + ?defValue "1800M" ) + ( hiCreateFormButton + ?name `UISyExportNondefaultRuleDef_Help + ?buttonText "Tool Help" + ?callback "nrOpenHtml( \"Export_Nondefault_Rule_DEF_help.html\" )" ) + ) + ( hiCreateAppForm + ?name `UISyExportNondefaultRuleDef_Form + ?formTitle "Export Nondefault Rule DEF" + ?fields Fields + ?callback "( UISyExportNondefaultRuleDefFormCB )" + ) + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/Flush.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/Flush.il new file mode 100644 index 0000000000..340b61d31b --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/Proteus/Synch/Flush.il @@ -0,0 +1,15 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id: //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/ui/Fulcrum/CreateCDL.il#11 $ +; $DateTime: 2004/08/21 16:39:54 $ +; $Author: clayton $ + + +( list "1.Flush Design " "UIFlush" ) + + +( UICreateMenuItemCallBack + `UIFlushCB + (lambda () + (FlushDesignFiles (geGetEditCellView)) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys new file mode 100644 index 0000000000..05ad8a7f9a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys @@ -0,0 +1,151 @@ +; Standard Fulcrum bindkeys. If you want to add bindkeys, etc, just put a file in your /autoload directory. Don't edit this file. +(FulcrumDefaults) + +( hiSetBindKey "Layout" "Ctrlm" "leHiMarkNet()" ) +( hiSetBindKey "Layout" "Altm" "leHiUnmarkNet(nil)" ) +( hiSetBindKey "Layout" "y" "leToggleGravity()" ) +( hiSetBindKey "Layout" "n" "ToggleNameDisplay()" ) +( hiSetBindKey "Layout" "Ctrlr" "hiRedraw()" ) +( hiSetBindKey "Layout" "F1" "nil" ) + +( hiSetBindKey "Layout" "Delete" "DeleteWithProtect()" ) +( hiSetBindKey "Layout" "ShiftDelete" "leHiDelete()" ) +( hiSetBindKey "Layout" "m" "MoveWithAnchor()" ) +( hiSetBindKey "Layout" "v" "MoveWithAnchor()" ) +( hiSetBindKey "Layout" "s" "StretchWithAnchor()" ) +( hiSetBindKey "Layout" "" "SelBoxOrStretchWithAnchor()" ) + +( hiSetBindKey "Layout" "t" "leHiCreateRuler()" ) +( hiSetBindKey "Layout" "T" "leHiClearRuler()" ) +( hiSetBindKey "Layout" "K" "leHiTree()" ) +( hiSetBindKey "Layout" "d" "geDeselectPoint()" ) +( hiSetBindKey "Layout" "Ctrlw" "leCloseWindow()" ) +( hiSetBindKey "Layout" "Ctrlv" "leSetEnv(\"orientation\" \"MX\")" ) +( hiSetBindKey "Layout" "Altv" "leSetEnv(\"orientation\" \"MY\")" ) +( hiSetBindKey "Layout" "Ctrle" "CycleSnapGrids()" ) +( hiSetBindKey "Layout" "Ctrl Altv" "CycleViews()" ) +( hiSetBindKey "Layout" "Ctrl Altf" "StepViewBack()" ) + +; bindkeys for bus scripts +( hiSetBindKey "Layout" "Ctrlb" "SetPattern(nil)" ) +( hiSetBindKey "Layout" "Altb" "DrawWires( )" ) +( hiSetBindKey "Layout" "Altd" "DeleteWiresAndKeepout( )" ) +( hiSetBindKey "Layout" "Ctrl Altb" "RefreshAllBuswires()" ) +( hiSetBindKey "Layout" "Ctrl Altg" "RedrawAllPins()" ) +( hiSetBindKey "Layout" "Ctrlx" "EditGuideInstInPlace()" ) +( hiSetBindKey "Layout" "Ctrl Altx" "EditAutoGuideInstInPlace()" ) + +;mouse scroll button +( hiSetBindKey "Layout" "" "(geScroll nil \"n\" nil)" ) +( hiSetBindKey "Layout" "" "(geScroll nil \"s\" nil)" ) +( hiSetBindKey "Layout" "Shift" "(hiZoomRelativeScale (hiGetCurrentWindow) 1.5)" ) +( hiSetBindKey "Layout" "Shift" "(hiZoomRelativeScale (hiGetCurrentWindow) 0.75)" ) + +; leaf cell gate/stack functions +( hiSetBindKey "Layout" "Altk" "(UIStackChainsFormCB)") +( hiSetBindKey "Layout" "Altf" "(UIFoldChainsFormCB)") +( hiSetBindKey "Layout" "Alti" "(UIInlineCB)") +( hiSetBindKey "Layout" "Shiftl" "(AddHiLiteLabels)" ) +( hiSetBindKey "Layout" "Altl" "(TR_AddHiLiteLabels)" ) +( hiSetBindKey "Layout" "Altl" "(TR_AddHiLiteLabels)" ) +( hiSetBindKey "Layout" "Ctrlh" "(SetHandLayoutSelectedObjects)" ) +( hiSetBindKey "Layout" "Ctrl Alth" "(SetHandLayoutAllObjects)" ) + +;adding grid poly and cut poly to layout +( hiSetBindKey "Layout" "Ctrly" "DrawGridPoly()" ) +( hiSetBindKey "Layout" "Alty" "DeleteGridPoly()" ) + +;adding Implants to layout +( hiSetBindKey "Layout" "Ctrli" "Implant()" ) +( hiSetBindKey "Layout" "Ctrlq" "DeleteImplant()" ) + +; cell alignment form +( hiSetBindKey "Layout" "g" "OpenAlignForm()" ) +( hiSetBindKey "Layout" "Altg" "AlignSelectedV()" ) +( hiSetBindKey "Layout" "Ctrlg" "AlignSelectedH()" ) + + +hiSetBindKey( "Layout" "h" "AlignCells( PowerGridPitch 2*PowerGridPitch 0 0 )" ) +hiSetBindKey( "Layout" "j" "AlignCells( 0.24 2*PowerGridPitch 0 0 )" ) + +hiSetBindKey( "Layout" "o" "GetOverlaps( )" ) + +hiSetBindKey( "Layout" "1" "SetViewLevels( 0 1 )" ) +hiSetBindKey( "Layout" "2" "SetViewLevels( 0 2 )" ) +hiSetBindKey( "Layout" "3" "SetViewLevels( 0 3 )" ) +hiSetBindKey( "Layout" "4" "SetViewLevels( 0 4 )" ) +hiSetBindKey( "Layout" "5" "SetViewLevels( 0 5 )" ) +hiSetBindKey( "Layout" "6" "SetViewLevels( 0 6 )" ) +hiSetBindKey( "Layout" "7" "SetViewLevels( 0 7 )" ) +hiSetBindKey( "Layout" "8" "SetViewLevels( 0 8 )" ) +hiSetBindKey( "Layout" "9" "SetViewLevels( 0 32 )" ) +hiSetBindKey( "Layout" "0" "DeleteViewLevels()" ) + +hiSetBindKey( "Layout" "1" "SetViewLevels( 1 1 )" ) +hiSetBindKey( "Layout" "2" "SetViewLevels( 2 2 )" ) +hiSetBindKey( "Layout" "3" "SetViewLevels( 3 3 )" ) +hiSetBindKey( "Layout" "4" "SetViewLevels( 4 4 )" ) +hiSetBindKey( "Layout" "5" "SetViewLevels( 5 5 )" ) +hiSetBindKey( "Layout" "6" "SetViewLevels( 6 6 )" ) +hiSetBindKey( "Layout" "7" "SetViewLevels( 7 7 )" ) +hiSetBindKey( "Layout" "8" "SetViewLevels( 8 8 )" ) + +hiSetBindKey( "Layout" "1" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "2" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "3" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "4" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "5" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "6" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "7" "DeleteViewLevels()" ) +hiSetBindKey( "Layout" "8" "DeleteViewLevels()" ) + +hiSetBindKey( "Layout" "Left" "MoveToSnap( \"L\" )" ) +hiSetBindKey( "Layout" "Right" "MoveToSnap( \"R\" )" ) +hiSetBindKey( "Layout" "Up" "MoveToSnap( \"T\" )" ) +hiSetBindKey( "Layout" "Down" "MoveToSnap( \"B\" )" ) + +hiSetBindKey( "Layout" "Left" "MoveToSnapAlignV( \"L\" )" ) +hiSetBindKey( "Layout" "Right" "MoveToSnapAlignV( \"R\" )" ) +hiSetBindKey( "Layout" "Up" "MoveToSnapAlignV( \"T\" )" ) +hiSetBindKey( "Layout" "Down" "MoveToSnapAlignV( \"B\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Left" "MoveToSnapAlignV( \"L\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Right" "MoveToSnapAlignV( \"R\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Up" "MoveToSnapAlignV( \"T\" )" ) +hiSetBindKey( "Layout" "Ctrl Shift Down" "MoveToSnapAlignV( \"B\" )" ) + +hiSetBindKey( "Layout" "s" "SelectSameMaster( )" ) + +hiSetBindKey( "Layout" "Ctrl Shiftp" "Floorplan( )" ) +hiSetBindKey( "Layout" "Alt Ctrlp" "TR_FloorplanArray( )" ) +hiSetBindKey( "Layout" "Altp" "ArrayCells( )" ) +hiSetBindKey( "Layout" "Ctrlp" "TR_Floorplanner( )" ) + +hiSetBindKey( "Layout" "F6" "hiDisplayForm( A )" ) + +hiSetBindKey( "Layout" "Altn" "AnchorSelectedInstances( )" ) +hiSetBindKey( "Layout" "Ctrln" "UnAnchorSelectedInstances( )" ) + + +; MoveAndSnap +; =========== +(hiSetBindKey "Layout" "AltLeft" "(MoveAndSnap \"L\" )" ) +(hiSetBindKey "Layout" "AltRight" "(MoveAndSnap \"R\" )" ) +(hiSetBindKey "Layout" "AltUp" "(MoveAndSnap \"U\" )" ) +(hiSetBindKey "Layout" "AltDown" "(MoveAndSnap \"D\" )" ) +(hiSetBindKey "Layout" "Altz" "(MoveAndSnap \"L\" )" ) +(hiSetBindKey "Layout" "Altc" "(MoveAndSnap \"R\" )" ) +(hiSetBindKey "Layout" "Alts" "(MoveAndSnap \"U\" )" ) +(hiSetBindKey "Layout" "Altx" "(MoveAndSnap \"D\" )" ) +(hiSetBindKey "Layout" "F5" "TR_MoveAndSnap( )" ) +(hiSetBindKey "Layout" "Ctrl ShiftLeft" "(LockMoveAndSnap)" ) +(hiSetBindKey "Layout" "Ctrl ShiftRight" "(LockMoveAndSnap)" ) +(hiSetBindKey "Layout" "Ctrl ShiftUp" "(LockMoveAndSnap)" ) +(hiSetBindKey "Layout" "Ctrl ShiftDown" "(LockMoveAndSnap)" ) + +(hiSetBindKey "Layout" "F4" "TR_FindInstance( )" ) +(hiSetBindKey "Layout" "Ctrl Shifto" "FL_Overlap( )" ) +(hiSetBindKey "Layout" "Alt q" "TR_ChangeInstNameProcGUI( )" ) + + + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys_hand b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys_hand new file mode 100644 index 0000000000..f49259ab76 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/autoload/bindkeys_hand @@ -0,0 +1,71 @@ + +when( boundp('custom_layout) + + +hiSetBindKey( "Layout" "a" "leHiCreatePath()" ) + + +;quick start paths + procedure( start_path( layer ) + leSetEntryLayer( layer ) + leHiCreatePath() + ) + +hiSetBindKey( "Layout" "=" "start_path(PolyLPP)" ) +hiSetBindKey( "Layout" "`" "start_path(PolyLPP)" ) +hiSetBindKey( "Layout" "1" "start_path(Metal1LPP)" ) +hiSetBindKey( "Layout" "2" "start_path(Metal2LPP)" ) +hiSetBindKey( "Layout" "3" "start_path(Metal3LPP)" ) +hiSetBindKey( "Layout" "4" "start_path(Metal4LPP)" ) +hiSetBindKey( "Layout" "5" "start_path(Metal5LPP)" ) +hiSetBindKey( "Layout" "6" "start_path(Metal6LPP)" ) +hiSetBindKey( "Layout" "7" "start_path(Metal7LPP)" ) +hiSetBindKey( "Layout" "F6" "start_path(Metal6LPP)" ) +hiSetBindKey( "Layout" "F7" "start_path(Metal7LPP)" ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + procedure( drop_cont( via ) + point = hiGetPoint( hiGetCurrentWindow() ) + cv = geGetEditCellView() + dbCreateVia(cv techFindViaDefByName(TechLib via) point "R0") + ) +hiSetBindKey( "Layout" "Ctrl2" "drop_cont(Metal12RectViaV)" ) +hiSetBindKey( "Layout" "Ctrl3" "drop_cont(Metal23RectViaH)" ) +hiSetBindKey( "Layout" "Ctrl4" "drop_cont(Metal34RectViaH)" ) +hiSetBindKey( "Layout" "Ctrl5" "drop_cont(Metal45RectViaH)" ) +hiSetBindKey( "Layout" "Ctrl6" "drop_cont(Metal56RectViaH)" ) +hiSetBindKey( "Layout" "Ctrl7" "drop_cont(Metal67RectViaH)" ) +hiSetBindKey( "Layout" "CtrlF6" "drop_cont(Metal56RectViaH)" ) +hiSetBindKey( "Layout" "CtrlF7" "drop_cont(Metal67RectViaH)" ) + +hiSetBindKey( "Layout" "Alt2" "drop_cont(Metal12Via)" ) +hiSetBindKey( "Layout" "Alt3" "drop_cont(Metal23Via)" ) +hiSetBindKey( "Layout" "Alt4" "drop_cont(Metal34Via)" ) +hiSetBindKey( "Layout" "Alt5" "drop_cont(Metal45Via)" ) +hiSetBindKey( "Layout" "Alt6" "drop_cont(Metal56Via)" ) +hiSetBindKey( "Layout" "Alt7" "drop_cont(Metal67Via)" ) +hiSetBindKey( "Layout" "AltF6" "drop_cont(Metal56Via)" ) +hiSetBindKey( "Layout" "AltF7" "drop_cont(Metal67Via)" ) + + +procedure( drop_M1_PO_min( ) +let( (point cv viaid encparams) + point = hiGetPoint( hiGetCurrentWindow() ) + cv = geGetEditCellView() + viaid = techFindViaDefByName(techGetTechFile(cv) PolyContact) + encparams = list(list("layer1Enc" list(0.05 -0.005)) list("layer2Enc" list(0.02 0.01))) + dbCreateVia(cv viaid point "R0" encparams) + ) +) + +hiSetBindKey( "Layout" "Ctrl1" "drop_M1_PO_min( )" ) +hiSetBindKey( "Layout" "Alt1" "drop_M1_PO_min( )" ) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + + +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/automation/copyview.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/automation/copyview.il new file mode 100644 index 0000000000..4207b29857 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/automation/copyview.il @@ -0,0 +1,49 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +; Function: CopyView +; Parameter: SourceViewName (string) +; DestViewName (string) +; Return: DestCellView (CVId) +; +; Copy Cellview +; +; + + + +defun( CopyView ( SourceViewName DestViewName ) + + (let ( + ( SourceView ( dbOpenCellViewByType + LibName + CellName + SourceViewName + "maskLayout" + "a" ) ) + DestView obj + ) + obj=ddGetObj(LibName CellName DestViewName) + if( obj then ddDeleteObj(obj)) + + DestView= ( dbCopyCellView + SourceView + LibName + CellName + DestViewName + nil + nil + t ) + dbSave( DestView ) + DestView = ( dbOpenCellViewByType + LibName + CellName + DestViewName + "maskLayout" + "a" ) + DestView + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.il new file mode 100644 index 0000000000..482bbd11c6 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.il @@ -0,0 +1,506 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun UIRedraw () + ( UIInit ) + ( UIDrawUITableOnWindow + TheUITable + ( getCurrentWindow ) ) ) +;;; + +(defun UIGetCellView () + (cond ( + (let ( + ( NonIconified + ( setof Window ( hiGetWindowList ) ( and + ( getq Window cellView ) + ( equal ( hiGetWindowState Window ) `mapped ) ) ) ) ) + (if ( equal ( length NonIconified ) 1 ) + ( getq ( car NonIconified ) cellView ) ) ) ) + ( + ( getq + ( car ( exists Selected ( geGetSelectedSet ) + ( getq Selected cellView ) ) ) + cellView ) ) + ( + ( geGetWindowCellView ) ) ) ) + +(defun UIGetUIFileHeader ( UIFile ) + (let ( + ( InPort ( infile UIFile ) ) + ( Expression nil ) ) + (when InPort + ( while ( or ( null Expression ) + ( not ( listp Expression ) ) ) + ( setq Expression ( eval ( read InPort ) ) ) ) + ( close InPort ) + Expression ) ) ) + +(defun UIGetUIDirectoryHeader ( UIDir ) + ( UIGetUIFileHeader ( sprintf nil "%s/.menu" UIDir ) ) ) + +(defun UICreateUIIntermediateFromUIDirectory ( UIDirectory ) + (when ( isReadable UIDirectory ) + (defvar UIStack nil ) + (let ( + ( Header ( UIGetUIDirectoryHeader UIDirectory ) ) ) + ( UIPushUI ( UICreateMenu + ( car Header ) + ( car Header ) ) ) + ( UICreateUIIntermediateFromUIDirectoryImpl + UIDirectory ) + ( UIGetCurrentUI ) ) ) ) + +(defun UICreateUIIntermediateFromUIDirectoryImpl ( UIDirectory ) + (when ( isReadable UIDirectory ) + ( mapcar + ( lambda ( File ) + (cond ( + ( and ( isFile File ) + ( equal ( car ( last ( parseString File "." ) ) ) "il" ) ) + (let ( + ( Header ( UIGetUIFileHeader File ) ) ) + ; printf "file header: %L\n" Header ) + ( UIPushUI ( UICreateMenuItem + ( cadr Header ) + ( car Header ) + ( sprintf nil "( %sCB )" ( cadr Header ) ) ) ) + ( load File ) + ( UIPopUI ) ) ) + ( + ( isDir File ) + (let ( + ( Header ( UIGetUIDirectoryHeader File ) ) ) + (if Header + (let () + ( UIPushUI ( UICreateSubMenu + ( cadr Header ) + ( car Header ) ) ) + ( UICreateUIIntermediateFromUIDirectoryImpl + File ) + ( UIPopUI ) ) + ( printf "UI Error: No .menu file %s\n" File ) ) + ) ) ) ) + ( mapcar + ( lambda ( File ) + ( sprintf nil "%s/%s" UIDirectory File ) ) + ( setof File ( getDirFiles UIDirectory ) + ( and ( not ( equal File ".menu" ) ) + ( not ( equal File "." ) ) + ( not ( equal File ".." ) ) ) ) ) ) ) ) + +(defun UIReplaceWithEnv ( CDSConfigTable Key ) + (let ( + ( Value ( getShellEnvVar Key ) ) + ( ShellVar ( sprintf nil "${%s}" Key ) ) ) + (when Key + ( rexCompile ShellVar ) + ( foreach + Key + CDSConfigTable + ( setarray + CDSConfigTable + Key + ( rexReplace + ( arrayref CDSConfigTable Key ) + Value 1 ) ) ) ) ) ) + +(defun UILoadDir ( Dir @rest argsRE ) + ( foreach + File + ( setof + File + ( getDirFiles Dir ) + ( and + ( not ( equal File "." ) ) + ( not ( equal File ".." ) ) + ( not ( rexMatchp "~$" File ) ) + ( not ( rexMatchp "\\.rp$" File ) ) + ( forall RE argsRE ( rexMatchp RE File ) ) ) ) + ( load ( strcat Dir "/" File ) ) ) ) + +; +; this function loads all of the files in the user's autoload directory and +; is currently not used and remains for reference +; + +(defun UIAutoLoad ( CDSConfigTable ) + (let ( + ( DirectoryString ( ConfigFileGetValue CDSConfigTable "AUTOLOAD_DIRS" ) ) ) + (let ( + ( Directories ( append ( parseString DirectoryString ":" ) ( list "autoload" ) ) ) ) + ( foreach Directory Directories + (if ( isDir Directory ) + ( foreach File ( setof File ( getDirFiles Directory ) + ( and ( not ( equal File "." ) ) + ( not ( equal File ".." ) ) ) ) + ( load ( sprintf nil "%s/%s" Directory File ) ) ) ) ) ) ) t ) + +(defun UIInit ( @rest args ) + (let ( + ( VirtuosoHome ( getShellEnvVar "VIRTUOSO_HOME" ) ) + ( FulcrumPDKRoot ( getShellEnvVar "FULCRUM_PDK_ROOT" ) ) ) + + (if VirtuosoHome + ( printf "VIRTUOSO_HOME: %s\n" VirtuosoHome ) + (error "No $VIRTUOSO_HOME (root of virtuoso-integration package)" ) ) + (if FulcrumPDKRoot + ( printf "FULCRUM_PDK_ROOT: %s\n" FulcrumPDKRoot ) + (error "No $FULCRUM_PDK_ROOT (root of fulcrum-*-pdk package installation)" ) ) + + (let ( + ( LoadMe + ( list + ".cdsinit.user" + ( strcat FulcrumPDKRoot + "/share/Fulcrum/autoload/bindkeys" ) + ( strcat VirtuosoHome + "/share/skill/ui/ui/build/share/autoload/bindkeys" ) + ( strcat VirtuosoHome + "/share/skill/ui/ui/build/share/autoload/bindkeys_hand" ) + ) ) + ) + + (defvar TheCDSConfigTable ( makeTable `cdsconfig nil ) ) + (defvar TheUITable ( makeTable `ui nil ) ) + ( ConfigFileGetShellEnv TheCDSConfigTable ) + ( ConfigFileParseConfigFileToTable + TheCDSConfigTable + "cds.config" ) + ( ConfigFileParseConfigFileToTable + TheCDSConfigTable + ( strcat FulcrumPDKRoot "/share/Fulcrum/pdk.config" ) ) + ( load + ( strcat FulcrumPDKRoot "/share/Fulcrum/pdkinfo.il" ) ) + ( load + ( strcat FulcrumPDKRoot "/share/Fulcrum/businfo.il" ) ) + ( load + ( strcat FulcrumPDKRoot "/share/Fulcrum/cableinfo.il" ) ) + + ( UIReplaceWithEnv TheCDSConfigTable "VIRTUOSO_HOME" ) + ( UIReplaceWithEnv TheCDSConfigTable "FULCRUM_PDK_ROOT" ) + ( setarray TheCDSConfigTable "FULCRUM_PDK_ROOT" FulcrumPDKRoot ) + + ( foreach File LoadMe (when ( isFile File ) ( load File ) ) ) + ; replaces UIAutoLoad, left as list for expansion if needed (AAG) + (let ( + ( Directories ( list "autoload" ) ) ) + ( foreach Directory Directories + (if ( isDir Directory ) + ( foreach File ( setof File ( getDirFiles Directory ) + ( and ( not ( equal File "." ) ) + ( not ( equal File ".." ) ) ) ) + ( load ( sprintf nil "%s/%s" Directory File ) ) ) ) ) ) + + (when ( hiGraphicMode ) + ( createDir "temp" ) + ( foreach + Directory + ( setof + Directory + ( append + ( parseString + (cond ( ( arrayref TheCDSConfigTable "UI_DIRECTORY" ) ) ( "" ) ) + ":" ) + ( list ( strcat FulcrumPDKRoot "/share/Fulcrum/menu" ) + ( strcat VirtuosoHome "/share/skill/ui/ui/build/share/Fulcrum" ) + ( strcat VirtuosoHome "/share/skill/ui/ui/build/share/Nano" ) + ( strcat VirtuosoHome "/share/skill/ui/ui/build/share/Floorplan" ) + ( strcat VirtuosoHome "/share/skill/ui/ui/build/share/Hercules" ) + ( strcat VirtuosoHome "/share/skill/ui/ui/build/share/Proteus" ) + "usermenu" ) ) + ( isDir Directory ) ) + ( setarray + TheUITable + Directory + ( UIGetNativeRootMenu + ( UICreateUIIntermediateFromUIDirectory Directory ) ) ) ) + (deUnRegUserTriggers "maskLayout" ) + (deUnRegUserTriggers "schematic" ) + (deRegUserTriggers "maskLayout" nil 'UIGetTheUITableNativeRootMenus nil ) + (deRegUserTriggers "schematic" nil 'UIGetTheUITableNativeRootMenus nil ) + (if (not (null (deGetAppInfo "maskLayoutXL"))) + (let () + (deUnRegUserTriggers "maskLayoutXL" ) + (deRegUserTriggers "maskLayoutXL" nil 'UIGetTheUITableNativeRootMenus nil ) ) ) ) ) ) ) + + +(defun UIGetTheUITableNativeRootMenus ( Args ) + ( UIGetUITableNativeRootMenus TheUITable ) ) + +(defun UIGetUITableNativeRootMenus ( UITable ) + (let ( + ( NativeMenuList nil ) ) + ( foreach + Directory + UITable + (let ( + ( NativeMenu ( arrayref UITable Directory ) ) ) + (if NativeMenu + ( setq NativeMenuList ( cons NativeMenu NativeMenuList ) ) ) ) ) + NativeMenuList ) ) + +(defun UIDrawUITableOnWindow ( UITable Window ) + ( foreach NativeMenu ( UIGetUITableNativeRootMenus UITable ) + ( UIDrawNativeRootMenu NativeMenu Window ) ) ) + +(defun UIDrawNativeRootMenu ( BannerMenu Window ) + (let ( + ( BannerIndex + ( ListFindIndex + ( hiGetBannerMenus Window ) + ( getq BannerMenu hiMenuSym ) ) ) ) + (if BannerIndex + ( hiDeleteBannerMenu + Window + BannerIndex ) ) + ( hiInsertBannerMenu + Window + BannerMenu + (cond ( + BannerIndex ) + ( + 1000 ) ) ) ) ) + +(defun UIGetNativeRootMenu ( UIRootComponent ) + (let ( + ( BannerMenu + ( UICreateNative + UIRootComponent + `UIDefaultFactory + t ) ) ) + BannerMenu ) ) + +(defun UICreateNative ( UIRootComponent UIFactory TopLevel ) + ; do children first + (let ( + ( Children + ;the actual db structs + ( mapcar + ( lambda ( UIComponent ) + ( UICreateNative UIComponent UIFactory nil ) ) + ;the UIs + ( mapcar + `cadr + ( tableToList ( UIGetChildren UIRootComponent ) ) ) ) ) ) + (if ( or Children ( not TopLevel ) ) + ( apply UIFactory ( list UIRootComponent Children ) ) ) ) ) + + +(defun UIDefaultFactory ( UIComponent Children ) + (let ( + ( Constructor ( UIGetConstructor UIComponent ) ) ) + (let ( + ( Args (if Children ( list Children ) ( list nil ) ) ) ) + ( apply ( car Constructor ) Args ) + ) ) ) + +;UI Stack +(defun UIPushUI ( UIComponent ) + ( setq UIStack ( cons UIComponent UIStack ) ) ) + +(defun UIPopUI () + (let ( + ( Element ( car UIStack ) ) ) + ( setq UIStack ( cdr UIStack ) ) + Element ) ) + +(defun UIGetCurrentUI () + ( car UIStack ) ) + +;;UI interface +(defun UISetName ( UIComponent Name ) + ( setarray UIComponent "name" Name ) ) + +(defun UIGetName ( UIComponent ) + ( arrayref UIComponent "name" ) ) + +(defun UISetConstructor ( UIComponent Constructor ) + ( setarray UIComponent "constructor" Constructor ) ) + +(defun UIGetConstructor ( UIComponent ) + ( arrayref UIComponent "constructor" ) ) + +(defun UICreateConstructor ( ConstructorFunc ) + ( list ConstructorFunc ) ) + +(defun UIGetChildren ( UIComponent ) + (let ( + ( Children + (cond ( + ( arrayref UIComponent "children" ) ) + ( + ( makeTable "children" nil ) ) ) ) ) + ( setarray UIComponent "children" Children ) + Children ) ) + +(defun UIAddChild ( UIComponent ChildUI ) + (when UIComponent + ( setarray ( UIGetChildren UIComponent ) ( UIGetName ChildUI ) ChildUI ) ) ) + + +;;;UI Creation +(defun UICreateMenuItemCallBack ( FuncSymbol Func ) + ( putd FuncSymbol + ( ExpressionReplaceSymbolsWithValues + `(lambda ( ) + ( apply Func nil ) ) + ( list `Func ) ) ) ) + +(defun UICreateAction ( FuncSymbol Func ) + ( putd FuncSymbol + ( ExpressionReplaceSymbolsWithValues + `(lambda ( ) + ( apply Func nil ) ) + ( list `Func ) ) ) ) + +(defun UICreateComponent ( Name Constructor ) + (let ( + ( CurrentUI ( UIGetCurrentUI ) ) + ( NewUI ( makeTable `ui nil ) ) ) + ( UISetName NewUI Name ) + ( UISetConstructor NewUI Constructor ) + ( UIAddChild CurrentUI NewUI ) + NewUI ) ) + + +(defun UICreateMenu ( Name Text ) + (let ( + ( Constructor ( UICreateConstructor + ( ExpressionReplaceSymbolsWithValues + `( lambda ( Items ) + ( hiCreatePulldownMenu + ( stringToSymbol Name ) + Text + sort( Items lambda((x y) strcmp(x~>hiItemText y~>hiItemText)<0)) + ) ) + ( list `Name `Text ) ) ) ) ) + ( UICreateComponent + Name + Constructor ) ) ) + +(defun UICreateSubMenu ( Name Text ) + (let ( + ( Constructor ( UICreateConstructor + ( ExpressionReplaceSymbolsWithValues + `( lambda ( Items ) + ( hiCreateSliderMenuItem + ?name ( stringToSymbol ( sprintf nil "%s_slider" Name ) ) + ?itemText Text + ?subMenu ( hiCreatePulldownMenu + ( stringToSymbol Name ) + Text + sort( Items lambda((x y) strcmp(x~>hiItemText y~>hiItemText)<0)) ) ) ) + ( list `Name `Text ) ) ) ) ) + ( UICreateComponent + Name + Constructor ) ) ) + +(defun UICreateMenuItem ( Name Text CallBack ) + (let ( + ( Constructor ( UICreateConstructor + ( ExpressionReplaceSymbolsWithValues + `( lambda ( Children ) + ( hiCreateMenuItem + ?name ( stringToSymbol Name ) + ?itemText Text + ?callback CallBack ) ) + ( list `Name `Text `CallBack ) ) ) ) ) + ( UICreateComponent + Name + Constructor ) ) ) + + +(defun UILoadPreferences ( FormSymbol ) + (let ( + ( PreferencesDir + ( ddGetStartup ".UIPreferences" ) ) ) + (cond ( + ( stringp PreferencesDir ) + ( UILoadPreferencesImpl + PreferencesDir + FormSymbol ) ) + ( + t ) ) ) ) + +(defun UILoadPreferencesImpl ( PreferencesDir + FormSymbol ) + (when ( isDir PreferencesDir ) + (let ( + ( PreferencesFile + ( sprintf + nil + "%s/%s" + PreferencesDir + ( symbolToString FormSymbol ) ) ) + ( Form ( symeval FormSymbol ) ) ) + (let ( + ( KeyValue t ) + ( InPort ( infile PreferencesFile ) ) + ) + (while + ( setq KeyValue + ( eval ( read InPort ) ) ) + (let ( + ( Field ( get Form ( car KeyValue ) ) ) + ( Value ( cadr KeyValue ) ) ) + (unless ( equal Field->value Value ) + Field->value = Value + ) ) ) + ( close InPort ) + ) ) ) ) + +(defun UICreateForm ( Name + CallBack ) + ( UICreateComponent + Name + ( UICreateConstructor CallBack )) ) + +(defun UIWritePreferences ( FormSymbol ) + (let ( + ( PreferencesDir + ( sprintf + nil + "%s.UIPreferences" + ( ddGetStartup "" ) ) ) ) + ( createDir + PreferencesDir ) + ( UIWritePreferencesImpl + PreferencesDir + FormSymbol ) +) ) + +(defun UIWritePreferencesImpl ( PreferencesDir + FormSymbol ) + (let ( + ( Form ( symeval FormSymbol ) ) + ( PreferencesFile + ( sprintf + nil + "%s/%s" + PreferencesDir + ( symbolToString FormSymbol ) ) ) ) + (let ( + ( OutPort ( outfile PreferencesFile "w" ) ) ) + ( foreach + Field + ( getq Form fieldList ) + ( fprintf + OutPort + "( list `%s %L)\n" + ( symbolToString Field ) + ( get Form Field )->value + ) ) + ( close OutPort ) ) ) ) + +(defun UIPopUpDialog (string) + ( hiDisplayAppDBox + ?name `UIWarnBox + ?dboxBanner "Warning" + ?dboxText string + ?buttonLayout 'Close + ?help nil + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.package new file mode 100644 index 0000000000..c8ff296823 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/ui.package @@ -0,0 +1,287 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +< Description +

    The implementation of the Fulcrum ui, a menu usable when editing layout. See for the SKILL implementation.

    + +

    Many of the features share their implementation with and the automated flow. The same SKILL code is run, but with parameters filled in from a menu, or from information in the cds.config file, created by .

    + +

    The Menus

    +A quick overview of how it works: +
      +
    • The menus are initialized with UInit in the generated .cdsinit. +
    • The file share/A/B/.menu turns into a hierarchical layout editor menu A/B +
    • The top level menu is named Fulcrum +
    • The .menu file should have ( list "menu-name" "menu-symbol" ) +
    +DOC + +# Top level menu +share/Fulcrum/.menu Fulcrum/.menu 644 p + +# General options for other menus(e.g. max-heap-size) +#share/Fulcrum/Options.il Fulcrum/Options.il 644 p + +#

    Importing CAST to layout

    +# Effectively calls updatenetlist on the current cellview. +# The hierarchy/parameters will be made to match CAST +#share/Fulcrum/SyncToNetList.il Fulcrum/SyncToNetList.il 644 pA + +# Starts a background process to run cast2cdl +share/Fulcrum/CreateCDL.il Fulcrum/CreateCDL.il 644 p + +# Create prBound +share/Fulcrum/CreatePrBound.il Fulcrum/CreatePrBound.il 644 p +share/Fulcrum/GetCellArea.il Fulcrum/GetCellArea.il 644 p +share/Fulcrum/GetFigArea.il Fulcrum/GetFigArea.il 644 p + +# Create floorplan +share/Fulcrum/CreateFloorplan.il Fulcrum/CreateFloorplan.il 644 p + +# Delete all shapes +#share/Fulcrum/DeleteAllShapes.il Fulcrum/DeleteAllShapes.il 644 p + +# Create floorplan +share/Fulcrum/EstimateWireDistance.il Fulcrum/EstimateWireDistance.il 644 p + +# Opens the dialog to run Virtual lvs +#share/Fulcrum/StartVLVS.il Fulcrum/StartVLVS.il 644 p + +# Create and abstracts for a list of leaf cells +share/Fulcrum/LeafAbstractList.il Fulcrum/LeafAbstractList.il 644 p + +# cell alignment +share/Fulcrum/Align/.menu Fulcrum/Align/.menu 644 p +share/Fulcrum/Align/SetAlignment.il Fulcrum/Align/SetAlignment.il 644 p +share/Fulcrum/Align/CheckAlignment.il Fulcrum/Align/CheckAlignment.il 644 p +share/Fulcrum/Align/FixAlignment.il Fulcrum/Align/FixAlignment.il 644 p + + +# common leaf cell functions +share/Fulcrum/Leaf/.menu Fulcrum/Leaf/.menu 644 p +share/Fulcrum/Leaf/SyncToNetlist.il Fulcrum/Leaf/SyncToNetlist.il 644 p +share/Fulcrum/Leaf/DrawPins.il Fulcrum/Leaf/DrawPins.il 644 p +share/Fulcrum/Leaf/GroupChains.il Fulcrum/Leaf/GroupChains.il 644 p +share/Fulcrum/Leaf/Clean.il Fulcrum/Leaf/Clean.il 644 p +share/Fulcrum/Leaf/PlaceGates.il Fulcrum/Leaf/PlaceGates.il 644 p +share/Fulcrum/Leaf/DrawStruts.il Fulcrum/Leaf/DrawStruts.il 644 p +share/Fulcrum/Leaf/PlacePlugs.il Fulcrum/Leaf/PlacePlugs.il 644 p +share/Fulcrum/Leaf/DrawImplant.il Fulcrum/Leaf/DrawImplant.il 644 p +share/Fulcrum/Leaf/RouteLeaf.il Fulcrum/Leaf/RouteLeaf.il 644 p +share/Fulcrum/Leaf/DrawPoly.il Fulcrum/Leaf/DrawPoly.il 644 p +share/Fulcrum/Leaf/MakeAbstract.il Fulcrum/Leaf/MakeAbstract.il 644 p + + +# top level menu MidLevel +share/Fulcrum/MidLevel/.menu Fulcrum/MidLevel/.menu 644 p +share/Fulcrum/MidLevel/MakePrelayout.il Fulcrum/MidLevel/MakePrelayout.il 644 p +share/Fulcrum/MidLevel/MakeFlatten.il Fulcrum/MidLevel/MakeFlatten.il 644 p +share/Fulcrum/MidLevel/MakeLayout.il Fulcrum/MidLevel/MakeLayout.il 644 p +share/Fulcrum/MidLevel/MakeAbstract.il Fulcrum/MidLevel/MakeAbstract.il 644 p +share/Fulcrum/MidLevel/Clean.il Fulcrum/MidLevel/Clean.il 644 p + +# top level menu for Cable Flow +#share/Fulcrum/Cable/.menu Fulcrum/Cable/.menu 644 p +#share/Fulcrum/Cable/Placer.il Fulcrum/Cable/Placer.il 644 p + + + +#

    Pins

    +#share/Fulcrum/Pins/.menu Fulcrum/Pins/.menu 644 p +# Draw pitched/inplace pins and powergrid. +#share/Fulcrum/Pins/DrawPins.il Fulcrum/Pins/DrawPins.il 644 p +#share/Fulcrum/Pins/DrawResetPins.il Fulcrum/Pins/DrawResetPins.il 644 p +#share/Fulcrum/Pins/DrawSubPins.il Fulcrum/Pins/DrawSubPins.il 644 p +#share/Fulcrum/Pins/CanonicalizePins.il Fulcrum/Pins/CanonicalizePins.il 644 p +#share/Fulcrum/PreroutePins.il Fulcrum/PreroutePins.il 644 p + +#

    Bus Scripts

    +share/Fulcrum/Bus/.menu Fulcrum/Bus/.menu 644 p +share/Fulcrum/Bus/SetBusPattern.il Fulcrum/Bus/SetBusPattern.il 644 p +share/Fulcrum/Bus/DrawWires.il Fulcrum/Bus/DrawWires.il 644 p +share/Fulcrum/Bus/DeleteWires.il Fulcrum/Bus/DeleteWires.il 644 p +share/Fulcrum/Bus/DrawAllPins.il Fulcrum/Bus/DrawAllPins.il 644 p +share/Fulcrum/Bus/RefreshAll.il Fulcrum/Bus/RefreshAll.il 644 p +share/Fulcrum/Bus/DeleteBusWires.il Fulcrum/Bus/DeleteBusWires.il 644 p +share/Fulcrum/Bus/CreateGuideInst.il Fulcrum/Bus/CreateGuideInst.il 644 p +share/Fulcrum/Bus/CopyBusGuidesToPrelayout.il Fulcrum/Bus/CopyBusGuidesToPrelayout.il 644 p +share/Fulcrum/Bus/RoundGuidePaths.il Fulcrum/Bus/RoundGuidePaths.il 644 p +share/Fulcrum/Bus/FindOverlaps.il Fulcrum/Bus/FindOverlaps.il 644 p +share/Fulcrum/Bus/DeleteOverlapMarkers.il Fulcrum/Bus/DeleteOverlapMarkers.il 644 p +share/Fulcrum/Bus/MoveGuidesToBuswires.il Fulcrum/Bus/MoveGuidesToBuswires.il 644 p +share/Fulcrum/Bus/FindCopies.il Fulcrum/Bus/FindCopies.il 644 p + +#

    Wirelengths

    +share/Fulcrum/Wiring/.menu Fulcrum/Wiring/.menu 644 p +share/Fulcrum/Wiring/ReportWirelengths.il Fulcrum/Wiring/ReportWirelengths.il 644 p +share/Fulcrum/Wiring/InteractiveReport.il Fulcrum/Wiring/InteractiveReport.il 644 p +share/Fulcrum/Wiring/CheckBusWires.il Fulcrum/Wiring/CheckBusWires.il 644 p +share/Fulcrum/Wiring/ReportMBUFChannels.il Fulcrum/Wiring/ReportMBUFChannels.il 644 p + +#

    Stacking/Folding

    +share/Fulcrum/Stacks/.menu Fulcrum/Stacks/.menu 644 p +# Uses stack.*_SUPERSTACK.0 pcells and +# +# +# to share contacts or place instances as close as possible together +# Relies on contact sharing properties csBottom/csTop defined in +# the gate/chain pcells. +share/Fulcrum/Stacks/Stack.il Fulcrum/Stacks/Stack.il 644 p +# Uses PDKCombineFolds and PDKFoldChain, defined in the pdk in +# Fulcrum/pdkinfo.il +share/Fulcrum/Stacks/Fold.il Fulcrum/Stacks/Fold.il 644 p +share/Fulcrum/Stacks/Inline.il Fulcrum/Stacks/Inline.il 644 p + + +#

    Perforce Integration

    +# Uses P4HOST, P4USER, P4PASSWD, P4CLIENT, P4CONFIG, P4LOG, TEMP +# environment variables, and shells out to cdsp4* +share/Fulcrum/P4/.menu Fulcrum/P4/.menu 644 p +share/Fulcrum/P4/cdsp4edit.il Fulcrum/P4/cdsp4edit.il 644 p +share/Fulcrum/P4/cdsp4add.il Fulcrum/P4/cdsp4add.il 644 p +share/Fulcrum/P4/cdsp4revert.il Fulcrum/P4/cdsp4revert.il 644 p +share/Fulcrum/P4/P4EditAllSubcells.il Fulcrum/P4/P4EditAllSubcells.il 644 p +share/Fulcrum/P4/P4Cell.il Fulcrum/P4/P4Cell.il 644 p + + +# Inline selected cells, making sure to preserve hierarchical names, connections +share/Fulcrum/Hierarchy/.menu Fulcrum/Hierarchy/.menu 644 p +share/Fulcrum/Hierarchy/Inline.il Fulcrum/Hierarchy/Inline.il 644 p +share/Fulcrum/Hierarchy/ReplaceSubcells.il Fulcrum/Hierarchy/ReplaceSubcells.il 644 p +share/Fulcrum/Hierarchy/ReportInstances.il Fulcrum/Hierarchy/ReportInstances.il 644 p + +# leaf cell hand layout functions +share/Fulcrum/HandLayout/.menu Fulcrum/HandLayout/.menu 644 p +share/Fulcrum/HandLayout/SetHandAll.il Fulcrum/HandLayout/SetHandAll.il 644 p +share/Fulcrum/HandLayout/SetHandSelected.il Fulcrum/HandLayout/SetHandSelected.il 644 p +share/Fulcrum/HandLayout/DeleteNotHand.il Fulcrum/HandLayout/DeleteNotHand.il 644 p +share/Fulcrum/HandLayout/Struts.il Fulcrum/HandLayout/Struts.il 644 p + + +share/Fulcrum/GoTo.il Fulcrum/GoTo.il 644 p +#share/Fulcrum/AutoPowerGrid.il Fulcrum/AutoPowerGrid.il 644 p +#share/Fulcrum/AutoPowerGridAbstract.il Fulcrum/AutoPowerGridAbstract.il 644 p + + + +#

    Routing

    + +# Traverses entire dfII database for floorplan views. +# Builds a type hierarchy from this, and returns a list of cells that instanciate the current cell. +share/Fulcrum/Hierarchy/Instanciators.il Fulcrum/Hierarchy/Instanciators.il 644 p +share/Fulcrum/Route/.menu Fulcrum/Route/.menu 644 p + +# Routing. Calls CCAR, using templates from PDK. +share/Fulcrum/Route/Route.il Fulcrum/Route/Route.il 644 p + +# Create routing views. See . +share/Fulcrum/Route/CreateMidAbstract.il Fulcrum/Route/CreateMidAbstract.il 644 p + +# Attempts to fix area/extension/notch violations from CCAR. +# Calls pdk/Fulcrum/notches/fill_notches.assura.rules.all +#share/Fulcrum/Route/Clean.il Fulcrum/Route/Clean.il 644 p +share/Fulcrum/Route/ViaExtension.il Fulcrum/Route/ViaExtension.il 644 p + +# Draw's implant/well/plugs +#share/Fulcrum/Route/DrawPlugs.il Fulcrum/Route/DrawPlugs.il 644 p +#share/Fulcrum/Verify/.menu Fulcrum/Verify/.menu 644 p + +#

    DRC Signoffs

    +# Signoff will create a signoff file for check-in based on a drc signoff file created with assura DRC. Signoff files should go in the dfII cell directory in a file called drc_signoff. This way, will also understand the signoffs. +# This uses . +# This processing will add gds2 names to the list of cellnames that get the signoffs. +# This will not be relevant if gds2 renaming is not done. +# gds2 renaming is done because certain tools like have trouble with structure in gds2 files. +#share/Fulcrum/Verify/Signoff.il Fulcrum/Verify/Signoff.il 644 p + +# SignoffInclude creates an rsf that can be used in any assura run +# based on a signoff file. +#share/Fulcrum/Verify/SignoffInclude.il Fulcrum/Verify/SignoffInclude.il 644 p + + +# standard bindkeys independent of PDK +share/autoload/bindkeys autoload/bindkeys 644 p +share/autoload/bindkeys_hand autoload/bindkeys_hand 644 p + +# CCAR menu +#share/Fulcrum/CCAR.il Fulcrum/CCAR.il 644 p +share/Fulcrum/CheckSubcell.il Fulcrum/CheckSubcell.il 644 p + + +# +# Floorplan menus +# +share/Floorplan/.menu Floorplan/.menu 644 p +share/Floorplan/LoadFloorplan.il Floorplan/LoadFloorplan.il 644 p +share/Floorplan/ResolveOverlap.il Floorplan/ResolveOverlap.il 644 p +share/Floorplan/SaveFloorplan.il Floorplan/SaveFloorplan.il 644 p +share/Floorplan/InitFloorplan.il Floorplan/InitFloorplan.il 644 p +share/Floorplan/FloorplanTemplate.il Floorplan/FloorplanTemplate.il 644 p +share/Floorplan/FloorplanAllSubcells.il Floorplan/FloorplanAllSubcells.il 644 p +share/Floorplan/ArrayCells.il Floorplan/ArrayCells.il 644 p +share/Floorplan/FLOverlap.il Floorplan/FLOverlap.il 644 p +share/Floorplan/PromoteInplacePins.il Floorplan/PromoteInplacePins.il 644 p +share/Floorplan/ReplaceSubcells.il Floorplan/ReplaceSubcells.il 644 p + +# Fill Spare Gate +#share/Fulcrum/FillSpareGate.il Fulcrum/FillSpareGate.il 644 p +#share/Fulcrum/Fill.il Fulcrum/Fill.il 644 p + +# Fill Spare Gate +#share/Fulcrum/DiffLayout.il Fulcrum/DiffLayout.il 644 p + +# Fiji Functions +#share/Fulcrum/Fiji/.menu Fulcrum/Fiji/.menu 644 p +#share/Fulcrum/Fiji/AttachPinShape.il Fulcrum/Fiji/AttachPinShape.il 644 p +#share/Fulcrum/Fiji/ShrinkBaliToFiji.il Fulcrum/Fiji/ShrinkBaliToFiji.il 644 p +#share/Fulcrum/Fiji/ShrinkPrelayout.il Fulcrum/Fiji/ShrinkPrelayout.il 644 p +#share/Fulcrum/Fiji/SnapPowerGrid.il Fulcrum/Fiji/SnapPowerGrid.il 644 p +#share/Fulcrum/Fiji/CheckSubcellPins.il Fulcrum/Fiji/CheckSubcellPins.il 644 p + +# Create new library +share/Fulcrum/CreateLib.il Fulcrum/CreateLib.il 644 p + +# Hercules Menu +share/Hercules/.menu Hercules/.menu 644 p +share/Hercules/runVue.il Hercules/runVue.il 644 p +#share/Hercules/setVueWindow.il Hercules/setVueWindow.il 644 p +share/Hercules/createTagView.il Hercules/createTagView.il 644 p + +# Proteus Menu +share/Proteus/.menu Proteus/.menu 644 p +share/Proteus/Abstracts/.menu Proteus/Abstracts/.menu 644 p +share/Proteus/Abstracts/CreateLeafAbstract.il Proteus/Abstracts/CreateLeafAbstract.il 644 p +share/Proteus/Abstracts/CreateMidAbstract.il Proteus/Abstracts/CreateMidAbstract.il 644 p +share/Proteus/Abstracts/ListMissingAbstracts.il Proteus/Abstracts/ListMissingAbstracts.il 644 p +share/Proteus/Export/.menu Proteus/Export/.menu 644 p +share/Proteus/Export/ExportDesignLef.il Proteus/Export/ExportDesignLef.il 644 p +share/Proteus/Export/ExportProteusFloorplanDef.il Proteus/Export/ExportProteusFloorplanDef.il 644 p +share/Proteus/Export/ExportNondefaultRuleDef.il Proteus/Export/ExportNondefaultRuleDef.il 644 p +share/Proteus/Export/CreateTracksDef.il Proteus/Export/CreateTracksDef.il 644 p +share/Proteus/Flatten/.menu Proteus/Flatten/.menu 644 p +share/Proteus/Flatten/DrawPins.il Proteus/Flatten/DrawPins.il 644 p +share/Proteus/Flatten/FlattenView.il Proteus/Flatten/FlattenView.il 644 p +share/Proteus/Prelayout/.menu Proteus/Prelayout/.menu 644 p +share/Proteus/Prelayout/CreatePrelayout.il Proteus/Prelayout/CreatePrelayout.il 644 p +share/Proteus/Prelayout/CreatePrBound.il Proteus/Prelayout/CreatePrBound.il 644 p +share/Proteus/Prelayout/GetCellArea.il Proteus/Prelayout/GetCellArea.il 644 p +share/Proteus/Prelayout/DrawWires.il Proteus/Prelayout/DrawWires.il 644 p +share/Proteus/Prelayout/FlushAndSync.il Proteus/Prelayout/FlushAndSync.il 644 p +share/Proteus/Synch/Flush.il Proteus/Synch/Flush.il 644 p +share/Proteus/Synch/AllSync.il Proteus/Synch/AllSync.il 644 p + +# +# The Proteus/Synch menu represents the steps in the Synch Flow. +# The menu items are in flow order. +# +share/Proteus/Synch/.menu Proteus/Synch/.menu 644 p +share/Proteus/Synch/CreateCellList.il Proteus/Synch/CreateCellList.il 644 p +share/Proteus/Synch/CreateGuideInst.il Proteus/Synch/CreateGuideInst.il 644 p +share/Proteus/Synch/ExportDesignDef.il Proteus/Synch/ExportDesignDef.il 644 p +share/Proteus/Synch/ExportDesignLef.il Proteus/Synch/ExportDesignLef.il 644 p +# does not work anyway +#share/Proteus/Synch/ExportNondefaultRuleDef.il Proteus/Synch/ExportNondefaultRuleDef.il 644 p diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/util/license.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/util/license.il new file mode 100644 index 0000000000..d8ec432975 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/ui/util/license.il @@ -0,0 +1,48 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun LicenseGetLicense ( LicenseName Version NumLicensesToLeave + @key (LicenseType "WAIT") + (LicenseCount 1) + (Verbose t) ) + (while + ( lessp + ( LicenseGetNumAvailable LicenseName ) + NumLicensesToLeave ) + (if Verbose ( printf "Waiting for %s license...\n" LicenseName ) ) + ( ipcSleep 10 ) ) + (let ( + ( Status + ( lmCheckOut + LicenseName + Version + LicenseCount + LicenseType ) ) ) + (if Verbose + (if Status + ( printf "Got %s license\n" LicenseName ) + ( printf "Failed to get %s license\n" LicenseName ) ) ) + Status ) +) + +(defun LicenseGetNumAvailable ( LicenseName ) + (let ( + ( ServerList + ( lmUserList LicenseName ) ) ) + (let ( + ( UniqueServers ( ListUniq ( sort ServerList + (lambda ( X Y ) ( lessp ( cadr X ) ( cadr Y ) ) ) ) ) ) ) + ( ListFindSum + UniqueServers + (lambda ( Server ) + ( difference + ( nth 1 Server ) + ListFindSum( nth(2 Server) + lambda((Machine) nth(3 Machine) ) ) + ) ) ) ) ) ) + +(defun LicenseReturnLicense ( LicenseName ) + ( lmCheckIn LicenseName ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/binarysearch.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/binarysearch.il new file mode 100644 index 0000000000..ee923f3672 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/binarysearch.il @@ -0,0 +1,139 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun BinarySearchFindSmallestStep ( BinarySearchTable + SmallerTestFunc + SmallerTestFuncArgs + ) + (let ( + ( Min ( arrayref BinarySearchTable "min" ) ) + ( Max ( arrayref BinarySearchTable "max" ) ) + ( Trial ( arrayref BinarySearchTable "trial" ) ) ) + (let ( + ( Success + ( apply SmallerTestFunc ( cons Trial SmallerTestFuncArgs ) ) ) ) + ( printf "%d %d %d\n" Min Max Trial ) + (cond ( + ;should we go smaller + Success + (cond ( + ( equal Min Trial ) + ( setarray BinarySearchTable "max" Min ) ) + ( + t + ( setarray BinarySearchTable "max" Trial ) ) ) ) + ( + ;or bigger + t + ( setarray BinarySearchTable "min" ( plus Trial 1 ) ) ) ) + (cond ( + ( and + ( not Success ) + ( equal ( arrayref BinarySearchTable "iters" ) 0 ) ) + ( setarray BinarySearchTable "trial" Max ) ) + ( + t + ( setarray BinarySearchTable "trial" + ( quotient + ( plus ( arrayref BinarySearchTable "min" ) + ( arrayref BinarySearchTable "max" ) ) 2 ) ) ) ) + ( setarray + BinarySearchTable "iters" + ( plus + ( arrayref BinarySearchTable "iters" ) + 1 ) ) + (cond ( + ( geqp ( arrayref BinarySearchTable "min" ) + ( arrayref BinarySearchTable "max" ) ) + ( setarray BinarySearchTable "done" t ) + t ) + ( + t + ( setarray BinarySearchTable "done" nil ) + nil ) ) ) ) ) + +(defun BinarySearchFindGreatest ( Min + Max + GreaterTestFunc + GreaterTestFuncArgs + ) + (let ( + ( Ret + ( BinarySearchFindSmallest + Min + Max + ( lambda ( Trial ) + ( not ( apply GreaterTestFunc ( cons Trial GreaterTestFuncArgs ) ) ) ) + nil ) ) ) + (cond ( + ( equal Ret Min ) + Min ) + ( + ( equal Ret Max ) + Max ) + ( + t + ( difference Ret 1 ) ) ) ) ) + + + + + + +(defun BinarySearchMakeTable ( Min + Max + Trial + @key + ( MaxTested nil ) ) + (let ( + ( BinarySearchTable ( makeTable `binarysearch nil ) ) ) + ( BinarySearchInitTable BinarySearchTable Min Max Trial ) + (when MaxTested + ( setarray BinarySearchTable "iters" 1 ) ) + BinarySearchTable ) ) + +(defun BinarySearchInitTable ( BinarySearchTable Min Max Trial ) + ( setarray BinarySearchTable "min" Min ) + ( setarray BinarySearchTable "max" Max ) + ( setarray BinarySearchTable "trial" Trial ) + ( setarray BinarySearchTable "iters" 0 ) + ( setarray BinarySearchTable "type" "binary" ) + (if ( geqp Min Max ) + ( setarray BinarySearchTable "done" t ) + ( setarray BinarySearchTable "done" nil ) ) ) + + +(defun BinarySearchFindSmallest ( Min + Max + SmallerTestFunc + SmallerTestFuncArgs + ) + ( BinarySearchFindSmallestWithGuess + Min + Max + ( quotient ( plus Min Max ) 2 ) + SmallerTestFunc + SmallerTestFuncArgs ) ) + +(defun BinarySearchFindSmallestWithGuess ( Min + Max + Trial + SmallerTestFunc + SmallerTestFuncArgs + ) + (cond ( + ( lessp Max Min ) + Min ) + ( + (let ( + ( BinarySearchTable ( BinarySearchMakeTable Min Max Trial ) ) ) + (while ( not ( BinarySearchFindSmallestStep + BinarySearchTable + SmallerTestFunc + SmallerTestFuncArgs ) ) + t ) + ( arrayref BinarySearchTable "trial" ) ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/search.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/search.il new file mode 100644 index 0000000000..87b03ee686 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/binarysearch/search.il @@ -0,0 +1,59 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun SearchFindSmallestStep ( SearchTable + SmallerTestFunc + SmallerTestFuncArgs ) + (cond ( + ( equal ( arrayref SearchTable "type" ) "binary" ) + ( BinarySearchFindSmallestStep + SearchTable + SmallerTestFunc + SmallerTestFuncArgs ) ) + ( + ( equal ( arrayref SearchTable "type" ) "linear" ) + ( LinearSearchFindSmallestStep + SearchTable + SmallerTestFunc + SmallerTestFuncArgs ) ) ) ) + +(defun LinearSearchFindSmallestStep ( LinearSearchTable + SmallerTestFunc + SmallerTestFuncArgs ) + (let ( + ( Min ( arrayref LinearSearchTable "min" ) ) + ( Max ( arrayref LinearSearchTable "max" ) ) + ( Trial ( arrayref LinearSearchTable "trial" ) ) ) + ( printf "%d %d %d\n" Min Max Trial ) + (cond ( + ;should we go smaller + ( apply SmallerTestFunc ( cons Trial SmallerTestFuncArgs ) ) + ( setarray LinearSearchTable "max" Trial ) + ( setarray LinearSearchTable "trial" ( difference Trial 1 ) ) + ) + ( + ( setarray LinearSearchTable "trial" ( plus Trial 1 ) ) + ( setarray LinearSearchTable "min" ( plus Trial 1 ) ) ) ) + (let ( + ( Min ( arrayref LinearSearchTable "min" ) ) + ( Max ( arrayref LinearSearchTable "max" ) ) ) + ;if done + (cond ( + ( geqp Min Max ) + ( setarray LinearSearchTable "trial" Min ) + ( setarray LinearSearchTable "done" t ) ) ) + ( arrayref LinearSearchTable "done" ) ) ) ) + +(defun LinearSearchInitTable ( LinearSearchTable + Min + Max + Trial ) + ( setarray LinearSearchTable "min" Min ) + ( setarray LinearSearchTable "max" Max ) + ( setarray LinearSearchTable "trial" Trial ) + ( setarray LinearSearchTable "type" "linear" ) + (if ( geqp Min Max ) + ( setarray LinearSearchTable "done" t ) + ( setarray LinearSearchTable "done" nil ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cache/cache.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cache/cache.il new file mode 100644 index 0000000000..aafc66b044 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cache/cache.il @@ -0,0 +1,49 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun CacheCreate ( ) + ( makeTable `FunctionCache ) +) + +(defun CacheClear ( FunctionCacheTable ) + ( foreach FunSymbol FunctionCacheTable + ( remprop FunSymbol `CacheTable ) + ) +) + +(defun CacheGetValue ( FunctionCacheTable FunSymbol @rest Args ) + ( setarray FunctionCacheTable FunSymbol t ) + ( let ( + ( Function ( getd FunSymbol ) ) + ( CacheTable ( get FunSymbol `CacheTable ) ) + ) + ( cond ( + ( null CacheTable ) + ( setq CacheTable ( makeTable FunSymbol ) ) + ( putprop FunSymbol CacheTable `CacheTable ) + ) + ) + ( let ( + ( CachedValue ( arrayref CacheTable Args ) ) + ) + ( let ( + ( Value + ( cond ( + ( boundp `CachedValue ) + CachedValue + ) + ( + ( apply Function Args ) + ) + ) + ) + ) + ( setarray CacheTable Args Value ) + Value + ) + ) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cellview.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cellview.il new file mode 100644 index 0000000000..ae7ca9c499 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/cellview.il @@ -0,0 +1,123 @@ +; Copyright 2010 Fulcrum Microsystems. All rights reserved. +; $Author: lines$ +; +; User interface skill commands for opening cells and changing views. + +; decode libName from a CAST FQCN (all but the last 2 dot-seperated fields) +(defun GetCastLibName (cellName) + (let (libName) + libName = (parseString cellName ".") + libName = (reverse (cddr (reverse libName))) + (when libName libName = (buildString libName ".")) + ) + ) + +; open a new window from a CAST name and view +(defun Open + (cellName ; CAST FQCN + viewName ; view name + @key (mode "a") ; mode: r, w, a + ) + (let (libName CV) + libName = (GetCastLibName cellName) + (when libName + (when (ddGetObj libName cellName viewName) + (geOpen ?lib libName ?cell cellName ?view viewName ?mode mode) + ) + ) + ) + ) + +; open a new window from a CAST name and view in read mode +(defun Read + (cellName ; CAST FQCN + viewName ; view name + ) + (Open cellName viewName ?mode "r") + ) + +; change views of the current cell +(defun View + (viewName ; view name + ) + (let (CV WIN newCV) + CV = (geGetEditCellView) + (when CV + WIN = (geGetCellViewWindow CV) + (when (and WIN (ddGetObj CV->libName CV->cellName viewName)) + (geChangeCellView WIN CV->libName CV->cellName viewName CV->mode) + ) + ) + ) + ) + +; cycle between available view in the given window +(defun CycleViews () + (when (mod CycleView 6)==0 + (unless (View "floorplan") CycleView=CycleView+1 ) + ) + (when (mod CycleView 6)==1 + (unless (View "prelayout") CycleView=CycleView+1 ) + ) + (when (mod CycleView 6)==2 + (unless (View "flatten") CycleView=CycleView+1 ) + ) + (when (mod CycleView 6)==3 + (unless (View "layout_pg") CycleView=CycleView+1 ) + ) + (when (mod CycleView 6)==4 + (unless (View "layout") CycleView=CycleView+1 ) + ) + (when (mod CycleView 6)==5 + (unless (View "abstract") CycleView=0 (View "floorplan") ) + ) + CycleView=CycleView+1 +) + +(defun CycleViewsBack () + (when (mod CycleView 6)==0 + (unless (View "floorplan") CycleView=5 (View "abstract") ) + ) + (when (mod CycleView 6)==1 + (unless (View "prelayout") CycleView=CycleView-1 ) + ) + (when (mod CycleView 6)==2 + (unless (View "flatten") CycleView=CycleView-1 ) + ) + (when (mod CycleView 6)==3 + (unless (View "layout_pg") CycleView=CycleView-1 ) + ) + (when (mod CycleView 6)==4 + (unless (View "layout") CycleView=CycleView-1 ) + ) + (when (mod CycleView 6)==5 + (unless (View "abstract") CycleView=-1 ) + ) + CycleView=CycleView-1 +) + +(defun InitCycleViews () + CycleView = 0 +) +InitCycleViews() + + + +(defun StepViewBack () + (let (viewname) + viewname=(geGetEditCellView)->viewName + (when viewname=="prelayout" + (View "floorplan") + ) + (when viewname=="flatten" + (View "prelayout") + ) + (when viewname=="layout_pg" + (View "flatten") + ) + (when viewname=="layout" + (View "layout_pg") + ) + CycleView=CycleView-1 + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/counter.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/counter.il new file mode 100644 index 0000000000..94a6842adc --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/counter.il @@ -0,0 +1,83 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun CounterFillList ( Start Final Increment ) + (let ( + ( List nil ) + ( Curr Start ) ) + ( while ( leqp Curr Final ) + ( setq List ( tconc List Curr ) ) + ( setq Curr ( plus Curr Increment ) ) ) + ( car List ) ) ) + +(defun CounterCountAndAccumulateResult ( StartIndex + FinalIndex + Increment + Func + FuncParams + InitialResult ) + (let ( + ( Curr StartIndex ) + ( CurrResult InitialResult ) + ( GoingUp ( lessp StartIndex FinalIndex ) ) ) + + (when ( or + ( and + GoingUp + ( leqp Increment 0 ) ) + ( and + ( not GoingUp ) + ( geqp Increment 0 ) ) ) + (error "CounterCountAndAccumulateResult: Invalid Increment." ) ) + + (while ( or + ( and + GoingUp + ( geqp FinalIndex Curr ) ) + ( and + ( not + GoingUp ) + ( leqp FinalIndex Curr ) ) ) + (let () + ( setq + CurrResult + ( apply + Func + ( cons + Curr + ( cons + CurrResult + FuncParams ) ) ) ) + ( setq Curr ( plus Curr Increment ) ) ) ) + CurrResult ) ) + + +(defun CounterCountAndAccumulateResults ( StartIndex + FinalIndex + Increment + Func + FuncParams ) + ( car + ( CounterCountAndAccumulateResult + StartIndex + FinalIndex + Increment + (lambda + ( CurrCount + CurrResults + Func + FuncParams ) + ( tconc + CurrResults + ( apply + Func + ( cons + CurrCount + FuncParams ) ) ) ) + ( list + Func + FuncParams ) + nil ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/db.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/db.il new file mode 100644 index 0000000000..cb84257537 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/db.il @@ -0,0 +1,17 @@ +; Copyright 2004 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun wcv () + "Quick helper function for getting cellview handles" + ( geGetWindowCellView ) ) + +(defun DDOpen ( DDObj ) + "Opens the layout view associated with a lib/cell ddObj." + ( dbOpenCellViewByType + DDObj->lib->name + DDObj->name + "layout" + nil + "a" ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/defaults.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/defaults.il new file mode 100644 index 0000000000..b39ae595ff --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/defaults.il @@ -0,0 +1,13 @@ + + +;shortcuts +(defun wcv () ( geGetWindowCellView ) ) ;Window Cell View +(defun ss () ( geGetSelectedSet ) ) ; Selected Set + + +(defun FulcrumDefaults () + ;ssh, don't tell anyone! + ExpertUser=nil +) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/expression/expression.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/expression/expression.il new file mode 100644 index 0000000000..9766c65e77 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/expression/expression.il @@ -0,0 +1,31 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + +(defun ExpressionReplaceSymbolsWithValues ( Expression Symbols ) + "Replaces all symbols in Expression that match a Symbol name in Symbols. Alternatively, if Symbols is t, it replaces all of the symbols. If Symbols is nil, it replaces none of them." + (cond ( + ( null Expression ) + nil ) + ( + ( listp Expression ) + ( cons + ( ExpressionReplaceSymbolsWithValues ( car Expression ) Symbols ) + ( ExpressionReplaceSymbolsWithValues ( cdr Expression ) Symbols ) ) ) + ( + ( symbolp Expression ) + (if ( equal Symbols t ) + ( symeval Expression ) + (let ( + ( Symbol + ( exists Symbol Symbols + ( equal Symbol Expression ) ) ) ) + (if Symbol + ( symeval ( car Symbol ) ) + Expression ) ) ) ) + ( + t + Expression ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/configfile.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/configfile.il new file mode 100644 index 0000000000..44b5830ca9 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/configfile.il @@ -0,0 +1,57 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun ConfigFileAppendKeyValuePairsToString ( String CDSP4ConfigTable Keys ) + (let ( + ( RetString String ) ) + ( foreach Key Keys + ( setq RetString + ( sprintf + nil + "%s --%s=%s" + RetString + Key + ( ConfigFileGetValue CDSP4ConfigTable Key ) ) ) ) + RetString ) ) + + +(defun ConfigFileGetValue ( ConfigTable Key ) + (cond ( + ( arrayref ConfigTable Key ) ) + ( + t + "" ) ) ) + +(defun ConfigFileParseConfigFileToTable ( ConfigTable ConfigFile ) + (let ( + ( Lines ( ReadFileReadFileLines ConfigFile ) ) ) + ( foreach + Line + Lines + (unless ( or + ( equal Line "^[ \t\n]$" ) ;empty + ( rexMatchp "^[ \t\n]*#" Line ) ;comments + ) + (let ( + ( ParsedLine ( parseString Line "=" ) ) ) + (let ( + ( Key ( car ParsedLine ) ) + ( Value ( buildString ( cdr ParsedLine ) "=" ) ) ) + (cond ( + ( equal Key "config" ) + ( ConfigFileParseConfigFileToTable + ConfigTable + ( PathGetPathForFile ( PathDirName ConfigFile ) Value ) ) ) + ( + ( setarray ConfigTable Key Value ) ) ) ) ) ) ) ) ) + +(defun ConfigFileGetShellEnv ( ConfigTable ) + (let ( + ( EnvDumpFile ( TempFileGetTempFileName "envdump" ) ) ) + ( shell ( sprintf nil "env > %s" EnvDumpFile ) ) + ( ConfigFileParseConfigFileToTable ConfigTable EnvDumpFile ) + ( shell ( sprintf nil "rm %s" EnvDumpFile ) ) ) ) + + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/dirtree.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/dirtree.il new file mode 100644 index 0000000000..43dbff4b2e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/dirtree.il @@ -0,0 +1,33 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun DirTreeMakeStackFrame ( Directory ) + (let ( + ( Entries ( getDirFiles Directory ) ) ) + (let ( + ( Files ( ListApplyFuncToListAndAccumulateNonNilResults + Entries + (lambda + ( Entry Directory ) + (let ( + ( EntryFullName ( sprintf nil "%s/%s" Directory Entry ) ) ) + (when ( isFile EntryFullName ) + EntryFullName ) ) ) + ( list Directory ) ) ) + ( Dirs ( ListApplyFuncToListAndAccumulateNonNilResults + Entries + (lambda + ( Entry Directory ) + (unless ( or ( equal Entry "." ) ( equal Entry ".." ) ) + (let ( + ( EntryFullName ( sprintf nil "%s/%s" Directory Entry ) ) ) + (when ( isDir EntryFullName ) + EntryFullName ) ) ) ) + ( list Directory ) ) ) ) + ( list + Directory + Files + Dirs ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/fileutil.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/fileutil.il new file mode 100644 index 0000000000..430295a081 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/fileutil.il @@ -0,0 +1,65 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun FileUtilAppendFile ( OutPort InFileName ) + (let ( + ( InFilePort ( infile InFileName ) ) + ( Line nil ) + ) + (while ( and ( portp InFilePort ) + ( gets Line InFilePort ) ) + ( fprintf OutPort "%s" Line ) ) + ) +) + + +(defun FileUtilReadExpressionFromFile ( InFileName ) + (let ( + ( InFilePort ( infile InFileName ) ) + ) + (let ( + ( Ret ( read InFilePort ) ) ) + ( close InFilePort ) + Ret + ) ) ) + +(defun FileUtilAppendStringToFileAndClose ( FileName String ) + (let ( + ( OutPort ( outfile FileName "a" ) ) + ) + ( fprintf OutPort String ) + ( close OutPort ) ) ) + + +(defun FileUtilDirFiles ( DirName ) + ( mapcar + (lambda ( FileName ) + ( strcat DirName "/" FileName ) ) + ( getDirFiles DirName ) ) ) + + +; returns 0 if directory created +; returns 1 if MakeParents was nil and parent directory did not exist. +; returns nil if createDir returns nil. +(defun FileUtilMakeDir ( DirName + @optional + ( MakeParents nil ) ) + (let ( + ( PathParts ( PathGetPathComponents + ( PathMakePathAbsolute + DirName ) ) ) + ( CurrPath "" ) + ( Ret 0 ) ) + (while ( and + ( equal Ret 0 ) + PathParts ) + ( setq CurrPath ( strcat CurrPath ( strcat "/" ( car PathParts ) ) ) ) + ( setq PathParts ( cdr PathParts ) ) + (unless ( isDir CurrPath ) + (if MakeParents + (unless ( createDir CurrPath ) + ( setq Ret nil ) ) + ( setq Ret 1 ) ) ) ) + Ret ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/libcellview.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/libcellview.il new file mode 100644 index 0000000000..45ffbcb4cf --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/libcellview.il @@ -0,0 +1,69 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + + +;Code for reading a file of library, cell, view tripples in to a list. + + + + +(defun LibCellViewReadLibCellViewTripplesFromPort ( InputPort ) + (let ( + ( FileLines ( ReadFileReadFileLinesFromPort + InputPort ) ) ) + ( rexComile "#.*" ) + ( ListApplyFuncToListAndAccumulateNonNilResults + FileLines + (lambda + ( CurrLine ) + (let ( + ( NewCurrLine ( rexReplace CurrLine "" -1 ) ) ) + (let ( + ( Components ( setof + Component + ( parseString NewCurrLine " " ) + ( not ( equal Component "" ) ) ) ) ) + (when ( equal ( length Components ) 3 ) + Components ) ) ) ) + nil ) ) ) + +(defun LibCellViewReadLibCellViewTripplesFromFile ( FileName ) + (let ( + ( InputPort ( infile FileName ) ) ) + (let ( + ( LibCellViewTripples ( LibCellViewReadLibCellViewTripplesFromPort InputPort ) ) ) + ( close InputPort ) + LibCellViewTripples ) ) ) + + +(defun LibCellViewReadLibCellPairsFromPort ( InputPort ) + (let ( + ( FileLines ( ReadFileReadFileLinesFromPort + InputPort ) ) ) + ( rexCompile "#.*" ) + ( ListApplyFuncToListAndAccumulateNonNilResults + FileLines + (lambda + ( CurrLine ) + (let ( + ( NewCurrLine ( rexReplace CurrLine "" -1 ) ) ) + (let ( + ( Components ( setof + Component + ( parseString NewCurrLine " " ) + ( not ( equal Component "" ) ) ) ) ) + (when ( equal ( length Components ) 2 ) + Components ) ) ) ) + nil ) ) ) + +(defun LibCellViewReadLibCellPairsFromFile ( FileName ) + (let ( + ( InputPort ( infile FileName ) ) ) + (let ( + ( LibCellPairs ( LibCellViewReadLibCellPairsFromPort InputPort ) ) ) + ( close InputPort ) + LibCellPairs ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/path.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/path.il new file mode 100644 index 0000000000..f95cfbcb5e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/path.il @@ -0,0 +1,68 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun PathIsAbsolutePath ( PathStr ) + ( equal ( substring PathStr 1 1 ) "/" ) ) + +(defun PathIsRelativeToHome ( PathStr ) + ( equal ( substring PathStr 1 1 ) "~" ) ) + +(defun PathGetPathComponents ( PathStr ) + (if ( PathIsAbsolutePath PathStr ) + (cons "" ( parseString PathStr "/" ) ) + ( parseString PathStr "/" ) ) ) + +(defun PathDirName ( PathStr ) + (let ( + ( Components ( PathGetPathComponents PathStr ) ) ) + (let ( + ( RevComponents ( cdr ( reverse Components ) ) ) ) + (let ( + ( NewComponents (if RevComponents + ( reverse RevComponents ) + ( ncons "." ) + ) + ) + ( ResultStr nil ) ) + ( foreach + Component + NewComponents + (if ResultStr + ( setq ResultStr ( sprintf nil "%s/%s" ResultStr Component ) ) + ( setq ResultStr Component ) ) ) + ResultStr ) ) ) ) + +(defun PathBaseName ( PathStr ) + ( car ( last ( PathGetPathComponents PathStr ) ) ) ) + +(defun PathGetPathForFile ( Dir File ) + if( Dir==nil || Dir=="" || PathIsAbsolutePath( File ) || PathIsRelativeToHome( File ) + File + (if ( equal ( substring Dir ( strlen Dir ) ) "/" ) + ( strcat Dir File ) + ( strcat Dir ( strcat "/" File ) ) ) ) ) + +(defun PathMakePathAbsolute ( PathStr ) + (cond + ( + ( PathIsAbsolutePath PathStr ) + PathStr ) + ( + ( PathIsRelativeToHome PathStr ) + (let ( + ( PathWithoutTilda ( substring PathStr 2 ) ) ) + (if PathWithoutTilda + ( strcat + ( getShellEnvVar "HOME" ) + PathWithoutTilda ) + ( getShellEnvVar "HOME" ) ) ) ) + ( + t + ( strcat + ( PathMakePathAbsolute + ( getWorkingDir ) ) + "/" + PathStr ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/readfile.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/readfile.il new file mode 100644 index 0000000000..35d0264aa0 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/readfile.il @@ -0,0 +1,27 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun ReadFileReadFileLinesFromPort ( Input ) + (let ( + ( ReadRet t ) + ( CurrLine nil) + ( Ret nil ) ) + (while ReadRet + ( setq ReadRet ( gets CurrLine Input ) ) + (when ReadRet + (let ( + ( CleanCurrLine ( StringUtilChompNewline CurrLine ) ) ) + (if Ret + ( tconc Ret CleanCurrLine ) + ( setq Ret ( tconc nil CleanCurrLine ) ) ) ) ) ) + ( car Ret ) ) ) + +(defun ReadFileReadFileLines ( FileName ) + (let ( + ( Input ( infile FileName ) ) ) + (let ( + ( Lines ( ReadFileReadFileLinesFromPort Input ) ) ) + ( close Input ) + Lines ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/tempfile.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/tempfile.il new file mode 100644 index 0000000000..b99af743ff --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/file/tempfile.il @@ -0,0 +1,55 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun TempFileInnerGetTempFileName ( NamePrefix ) + (let ( + ( TempDirName ( getTempDir ) ) + ) + (let ( + ( CurrNum 0 ) + ( CurrName ( sprintf nil "%s/%s%d" TempDirName NamePrefix 0 ) ) + ) + (while ( isFileName CurrName ) + ( setq CurrNum ( plus CurrNum 1 ) ) + ( setq CurrName ( sprintf nil "%s/%s%d" TempDirName NamePrefix CurrNum ) ) + ) + CurrName + ) + ) + ) + +(defun TempFileGetOutputPort ( NamePrefix ) + (let ( + ( Port + ( outfile ( TempFileInnerGetTempFileName + NamePrefix + ) + "w" + ) + ) + ) + Port + ) + ) + +(defun TempFileGetTempFileName ( NamePrefix ) + (let ( + ( TempFileName ( TempFileInnerGetTempFileName + NamePrefix + ) + ) + ) + (let ( + ( Port + ( outfile TempFileName "w" ) + ) + ) + ( close + Port + ) + TempFileName + ) + ) + ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/lib.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/lib.il new file mode 100644 index 0000000000..9d8760a2bb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/lib.il @@ -0,0 +1,52 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun LibCreateEmptyView ( LibName CellName LibPath TechLibName ViewName ViewType ) + (cond ( + ( not ( ddGetObj LibName CellName ViewName ) ) + (cond ( + ( not ( ddGetObj LibName ) ) + ( ddCreateLib LibName LibPath ) + ( hiiSetCurrentForm 'tcAttachTechForm) + tcAttachTechForm->tcDesignLibCyclic->value = LibName + tcAttachTechForm->tcBinaryTFLibCyclic->value = TechLibName + ( hiFormDone tcAttachTechForm) + ) ) + (let ( + ( CellView ( dbOpenCellViewByType LibName CellName ViewName ViewType "a" ) ) ) + ( dbSave CellView ) + ( dbPurge CellView ) ) ) ) ) + +(defun LibGetUnusedLibName ( Prefix LibDir ) + (let ( + ( CurrNum 0 ) + ( CurrName ( sprintf nil "%s%d" Prefix 0 ) ) ) + (while ( or ( ddGetObj CurrName ) + ( isDir ( sprintf nil "%s/%s" LibDir CurrName ) ) ) + ( setq CurrNum ( plus CurrNum 1 ) ) + ( setq CurrName ( sprintf nil "%s%d" Prefix CurrNum ) ) ) + ( println CurrName ) + CurrName ) ) + + +(defun LibCreateTempLibrary ( TechFileData TempLibNamePrefix LibDir ) + (let ( + ( TempLibName ( LibGetUnusedLibName TempLibNamePrefix LibDir ) ) ) + (let ( + ( TempLibDir ( sprintf nil "%s/%s" LibDir TempLibName ) ) ) + (let ( + ( TempLib ( ddCreateLib TempLibName TempLibDir ) ) ) + ( techBindTechFile TempLib ( getq TechFileData libName ) ) + TempLibName ) ) ) ) + + +(defun LibCreateTempLibraryFromCellView ( CellView TempLibNamePrefix LibDir ) + (let ( + ( TechFileDBObj ( techGetTechFile CellView ) ) ) + ( LibCreateTempLibrary + TechFileDBObj + TempLibNamePrefix + LibDir ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/list.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/list.il new file mode 100644 index 0000000000..30ade7cfe5 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/list.il @@ -0,0 +1,657 @@ + + ;Non-recursive function to process a list and store + ;list of the results from processing + ;each element in the list. + +(defun ListApplyFuncToListAndAccumulateResults ( List ApplyFunc ApplyFuncParams ) + ( mapcar + '(lambda + ( Element ) + ( apply + ApplyFunc + ( cons + Element + ApplyFuncParams ) ) ) + List ) ) + + +(defun ListApplyFuncToListAndAccumulateNonNilResults ( List ApplyFunc ApplyFuncParams ) + ( setof + Ele + ( ListApplyFuncToListAndAccumulateResults + List + ApplyFunc + ApplyFuncParams + ) + ( not ( null Ele ) ) ) ) + +(defun ListApplyFuncToListAndAccumulateResult ( List ApplyFunc ApplyFuncParams InitialResult ) + (let ( + ( CurrentResult InitialResult ) + ) + ( foreach + Item + List + ( setq + CurrentResult + ( apply + ApplyFunc + ( cons + Item + ( cons + CurrentResult + ApplyFuncParams ) ) ) ) ) + CurrentResult ) ) + + +(defun ListFindBestNonRedundantElements ( List RedundantFunc CrappinessCompareFunc ) + (let ( + ( SortedElements ( sort ( copy List ) CrappinessCompareFunc ) ) ) + ( ListFindBestNonRedundantElementsPreSorted + SortedElements + RedundantFunc ) ) ) + +(defun ListFindBestNonRedundantElementsPreSorted ( SortedElements RedundantFunc ) + (let ( + ( ElementsToKeep nil ) + ( Table ( makeTable `bla nil ) ) ) + (while SortedElements + (if ( not ( apply RedundantFunc ( list ( car SortedElements ) ( append ElementsToKeep ( cdr SortedElements ) ) ) ) ) + ( setq ElementsToKeep ( cons ( car SortedElements ) ElementsToKeep ) ) ) + ( setq SortedElements ( cdr SortedElements ) ) ) + ElementsToKeep ) ) + + +(defun ListGreedilyFindMinimalElementsWithSortFuncAndExclusionPredicate ( List + SortFunc + ExclusionPredicate ) + (let ( + ( MinimalElements nil ) + ( SortedElements ( sort + ( copy List ) + SortFunc ) ) ) + (while SortedElements + (let ( + ( MinimalElement ( car SortedElements ) ) ) + ( setq MinimalElements ( tconc MinimalElements MinimalElement ) ) + ( setq + SortedElements + ( setof + Element + SortedElements + ( and + ( not ( equal Element MinimalElement ) ) + ( not ( apply ExclusionPredicate ( list MinimalElement Element ) ) ) ) ) ) ) ) + ( car MinimalElements ) ) ) + +(defun ListGreedilyFindMinimalElementsWithValueFuncAndExclusionPredicate ( List + ValueFunc + ExclusionPredicate ) + ( ListGreedilyFindMinimalElementsWithSortFuncAndExclusionPredicate + List + (lambda ( x y ) + ( lessp + ( apply ValueFunc ( list x ) ) + ( apply ValueFunc ( list y ) ) ) ) + ExclusionPredicate ) ) + + +(defun ListMap ( Func List + @key + ( PreFirst (lambda ( x ) x ) ) + ( PostFirst (lambda ( x ) x ) ) + ( PreLast (lambda ( x ) x ) ) + ( PostLast (lambda ( x ) x ) ) + ) + (let ( + ( First t ) + ( Last nil ) + ( Ret nil ) ) + (while List + (let ( + ( Arg ( car List ) ) ) + ( setq + Ret + ( tconc + Ret + (cond ( + First + ( apply + PostFirst + ( list + ( apply + Func + ( list + ( apply + PreFirst + ( list Arg ) ) ) ) ) ) ) + ( + Last + ( apply + PostLast + ( list + ( apply + Func + ( list + ( apply + PreLast + ( list Arg ) ) ) ) ) ) ) + ( + ( apply + Func + ( list Arg ) ) ) ) ) ) + ( setq List ( cdr List ) ) + ( setq Last ( null ( cdr List ) ) ) ) ) + ( car Ret ) ) ) + +(defun ListGroup ( Size List ) + (let ( + ( Ret nil ) + ( Group nil ) + ( I 0 ) ) + (while List + ( setq Group ( tconc Group ( car List ) ) ) + ( setq List ( cdr List ) ) + (when ( or ( null List ) + ( equal ( setq I ( mod ( plus I 1 ) Size ) ) 0 ) ) + ( setq Ret ( tconc Ret ( car Group ) ) ) + ( setq Group nil ) ) + ) + ( car Ret ) ) ) + +(defun ListFillList ( FillFunc N ) + (let ( + ( RetList nil ) ) + ( for + I + 1 + N + ( setq RetList ( tconc RetList ( apply FillFunc ( list I ) ) ) ) ) + ( car RetList ) ) ) + +(defun ListRemoveLastNElements ( List N ) + (let ( + ( RetList ( reverse List ) ) ) + ( for + I + 1 + N + ( setq RetList ( cdr RetList ) ) ) + ( reverse RetList ) ) ) + +(defun ListFindMean ( List ElementToValueFunc ) + ( quotient + ( ListFindSum List ElementToValueFunc ) + ( length List ) ) ) + +(defun ListFindSum ( List ElementToValueFunc ) + ( ListApplyFuncToListAndAccumulateResult + List + (lambda ( Element CurrentResult ) + (let ( + ( Value (if ElementToValueFunc + ( apply ElementToValueFunc ( list Element ) ) + Element ) ) ) + ( plus Value CurrentResult ) ) ) + nil + 0.0 ) ) + +(defun ListFindMinimum ( List ElementToValueFunc ) + ( cadr ( ListFindMinimumElementValuePair List ElementToValueFunc ) ) ) + +(defun ListFindMinimumElement ( List ElementToValueFunc ) + ( car ( ListFindMinimumElementValuePair List ElementToValueFunc ) ) ) + +(defun ListFindMinimumElementValuePair ( List ElementToValueFunc ) + ( ListApplyFuncToListAndAccumulateResult + List + ( lambda ( Element CurrentResult ) + (let ( + ( Value (if ElementToValueFunc + ( apply ElementToValueFunc ( list Element ) ) + Element ) ) ) + (if ( or ( null ( cadr CurrentResult ) ) + ( lessp Value ( cadr CurrentResult ) ) ) + ( list Element Value ) + CurrentResult ) ) ) + nil + ( list nil nil ) ) ) + +(defun ListFindBestElement ( List CompareFunc Params ) + ( ListApplyFuncToListAndAccumulateResult + List + (lambda ( Element CurrentResult ) + (if ( apply CompareFunc ( list Element CurrentResult ) ) + Element CurrentResult ) ) + Params + ( car List ) ) ) + +(defun ListFindMaximum ( List ElementToValueFunc ) + ( cadr ( ListFindMaximumElementValuePair List ElementToValueFunc ) ) ) + +(defun ListFindMaximumElement ( List ElementToValueFunc ) + ( car ( ListFindMaximumElementValuePair List ElementToValueFunc ) ) ) + +(defun ListFindMaximumElementValuePair ( List ElementToValueFunc ) + ( ListApplyFuncToListAndAccumulateResult + List + (lambda ( Element CurrentResult ) + (let ( + ( Value (if ElementToValueFunc + ( apply ElementToValueFunc ( list Element ) ) + Element ) ) ) + (if ( or ( null ( cadr CurrentResult ) ) + ( geqp Value ( cadr CurrentResult ) ) ) + ( list Element Value ) + CurrentResult ) ) ) + nil + ( list nil nil ) ) ) + +(defun ListFindIndex ( List Element ) + (let ( + ( Index 0 ) ) + (while ( and + ( car List ) + ( not ( equal Element ( car List ) ) ) ) + ( setq Index ( plus Index 1 ) ) + ( setq List ( cdr List ) ) ) + (if ( equal ( car List ) Element ) + Index + nil ) ) ) + +;Non-recursive function that finds an element in list and returns it. +;Calles the PredicateFunc for each element with element as the +;first parameter and the PredicateFuncParams as the subsequent parameters. +;If PredicateFunc returns t then the passed element is returned from this function. +;NOTE: A nil element cannot be returned. +(defun ListFindElement ( List PredicateFunc PredicateFuncParams ) + ( car + ( exists + Element + List + ( apply + PredicateFunc + ( cons + Element + PredicateFuncParams ) ) ) ) ) + +(defun ListRemoveDuplicates ( List CompareFunc CompareFuncParams ) + (let ( + ( Ret nil ) + ( CurrList List ) ) + (while CurrList + (let ( + ( CurrEle ( car CurrList ) ) ) + ( setq CurrList ( cdr CurrList ) ) + (unless ( ListFindElement + ( car + Ret + ) + (lambda + ( CurrFindEle EleToFind CompareFunc CompareFuncParams ) + ( apply + CompareFunc + ( cons + CurrFindEle + ( cons + EleToFind + CompareFuncParams ) ) ) ) + ( list + CurrEle + CompareFunc + CompareFuncParams + ) + ) + ( setq + Ret + ( tconc + Ret + CurrEle ) ) ) ) ) + ( car + Ret ) ) ) + +(defun ListRemoveDuplicatesNoTableElements ( List ) + (let ( + ( RemoveDupTable ( makeTable "RemoveDuplicatesTable" nil ) ) + ( Result nil ) ) + ( foreach + Element + List + (unless ( arrayref + RemoveDupTable + Element ) + ( setq Result ( tconc Result Element ) ) + ( setarray RemoveDupTable Element t ) ) ) + ( car Result ) ) ) + +(defun ListRemoveDuplicatesFromStringList ( StringList ) + ( ListRemoveDuplicatesNoTableElements + StringList ) ) + +(defun ListDifference ( Set SubSet CompareFunc CompareFuncParams ) + ( ListApplyFuncToListAndAccumulateNonNilResults + Set + (lambda + ( SetEle CompareFunc CompareFuncParams ) + (unless ( ListFindElement + SubSet + (lambda + ( SubSetEle SetEle CompareFunc CompareFuncParams ) + ( apply + CompareFunc + ( cons + SubSetEle + ( cons + SetEle + CompareFuncParams ) ) ) ) + ( list + SetEle + CompareFunc + CompareFuncParams ) ) + SetEle ) ) + ( list + CompareFunc + CompareFuncParams ) ) ) + +(defun ListSymmetricDifferenceNoTableElements ( SetA SetB ) + ( ListUnionNoTableElements + ( ListDifferenceNoTableElements SetA SetB ) + ( ListDifferenceNoTableElements SetB SetA ) ) ) + +(defun ListDifferenceNoTableElements ( Set SubSet ) + (let ( + ( SubSetTable ( makeTable "ListDifferenceSubSetTable" nil ) ) ) + ( foreach + Element + SubSet + ( setarray + SubSetTable + Element + t ) ) + + ( ListApplyFuncToListAndAccumulateNonNilResults + Set + (lambda + ( Element SubSetTable ) + (unless ( arrayref SubSetTable Element ) + Element ) ) + ( list + SubSetTable ) ) ) ) + +(defun ListStringListDifference ( StringSet StringSubSet ) + ( ListDifferenceNoTableElements StringSet StringSubSet ) ) + +(defun ListSameElementsNoTableElements ( List1 List2 ) + (let ( + ( ElementTable ( makeTable `element nil ) ) ) + ( foreach + Element + List1 + ( setarray ElementTable Element t ) ) + ( and + ( equal ( length List1 ) ( length List2 ) ) + ( forall + Element + List2 + ( arrayref ElementTable Element ) ) ) ) ) + +;non number does nothing ( same as 0 ) +;number n rotates so n is beginning of list +(defun ListRotate ( List Value ) + (let ( + ( StartEnd ( ListSplit List Value ) ) ) + ( append ( cadr StartEnd ) ( car StartEnd ) ) ) ) + +(defun ListSplit ( List Value ) + (cond ( + ( integerp Value ) + (let ( + ( StartList nil ) + ( EndList nil ) + ( CurrPos 0 ) ) + ( foreach + Element + List + (if ( lessp CurrPos Value ) + ( setq StartList ( tconc StartList Element ) ) + ( setq EndList ( tconc EndList Element ) ) ) + ( setq CurrPos ( plus CurrPos 1 ) ) ) + ( list ( car StartList ) ( car EndList ) ) ) ) + ( + ( list nil List ) ) ) ) + + +(defun ListSplitOnPredicate ( List Predicate ) + (when ( listp List ) + (let ( + ( ListOfLists nil ) + ( CurrList nil ) ) + (while List + ( setq CurrList ( tconc CurrList ( car List ) ) ) + (when ( or + ( null ( cdr List ) ) + ( apply Predicate ( list ( car List ) ( cadr List ) ) ) ) + ( setq ListOfLists ( tconc ListOfLists ( car CurrList ) ) ) + ( setq CurrList nil ) ) + ( setq List ( cdr List ) ) ) + ( car ListOfLists ) ) ) ) + + +;n^2 so we can have table elements +(defun ListIntersect ( List1 List2 ) + ( setof + Element + List1 + ( exists OtherElement List2 ( equal Element OtherElement ) ) ) ) + +;tables not allowed +(defun ListUniqNoTableElements ( List ) + ( ListUnionNoTableElements List List ) ) + +(defun ListUnionNoTableElements ( List1 List2 ) + (let ( + ( ElementTable ( makeTable `element nil ) ) ) + ( foreach + Element + List1 + ( setarray ElementTable Element t ) ) + ( foreach + Element + List2 + ( setarray ElementTable Element t ) ) + ( mapcar ( lambda ( Pair ) ( car Pair ) ) + ( tableToList ElementTable ) ) ) ) + +(defun ListIntersectionNoTableElements ( List1 List2 ) + (let ( + ( ElementTable ( makeTable `element nil ) ) ) + ( foreach + Element List1 + ( setarray ElementTable Element t ) ) + ( setof Element List2 ( arrayref ElementTable Element ) ) ) ) + +(defun ListNonDestructiveMapCan ( Func + @rest Args ) + (let ( + ( Result nil ) ) + ( foreach + List + ( apply `mapcar ( cons Func Args ) ) + ( setq Result ( append List Result ) ) ) + Result ) ) + +;FuncInfoList is a list of pairs ( function, arglist )...returns non-nil if all return non-nil +;You can, of course, use a lambda function instead +(defun ListAndFuncs ( FuncInfoList ) + ( forall + FuncInfo + FuncInfoList + ( apply + ( car FuncInfo ) + ( cadr FuncInfo ) ) ) ) + + +;all subsets of Set of size N +(defun ListGetSubsets ( Set N ) + (let ( + ( Vector ( listToVector Set ) ) ) + ( mapcar + (lambda ( SubsetOfZ ) + ( mapcar + (lambda ( K ) + ( arrayref Vector ( difference K 1 ) ) ) + SubsetOfZ ) ) + ( ListSubsetsOfZ + ( length Set ) + K ) ) ) ) + +(defun ListSubsetsOfZ ( N K ) + ( ListSubsetsOfZInner N K nil nil ) ) + +(defun ListSubsetsOfZInner ( N K S T ) + (cond ( + ( equal K 0 ) + ( setq T ( cons S T ) ) ) + ( + t + (when ( lessp K N ) + ( setq T + ( ListSubsetsOfZInner + ( difference N 1 ) + K + S + T ) ) ) + ( setq T + ( ListSubsetsOfZInner + ( difference N 1 ) + ( difference K 1 ) + ( cons N S ) + T + ) ) ) ) + T ) + + +;removes any repertive successive elements +(defun ListUniq ( List ) + (let ( + ( Ret ( tconc nil ( car List ) ) ) + ( LastElement ( car List ) ) ) + ( foreach + Element + ( cdr List ) + (if ( not ( equal Element LastElement ) ) + ( setq Ret ( tconc Ret Element ) ) ) + ( setq LastElement Element ) ) + ( car Ret ) ) ) + + +;returns a pair, ( passing, failing ) +(defun ListFilter ( List + Predicate + PredicateArgs ) + (let ( + ( PassList nil ) + ( FailList nil ) ) + ( foreach + Element + List + (if ( apply Predicate ( cons Element PredicateArgs ) ) + ( setq PassList ( tconc PassList Element) ) + ( setq FailList ( tconc FailList Element) ) ) ) + ( list ( car PassList ) ( car FailList ) ) ) ) + +(defun ListFilterByIntersection ( List1 + List2 ) + (let ( + ( ElementTable ( makeTable `element nil ) ) ) + ( foreach + Element + List2 + ( setarray ElementTable Element t ) ) + ( ListFilter + List1 + (lambda ( x ) ( arrayref ElementTable x ) ) + nil ) ) ) + +(defun ListFindElementsInList ( ListToFindElementsIn + ElementsToFind + CompareFunc + CompareFuncParams ) + (let ( + ( Ret nil ) + ( CurrElementsToFind ElementsToFind ) ) + ( foreach + Element + ListToFindElementsIn + (let ( + ( CopyOfCurrElementsToFind CurrElementsToFind ) + ( NewListOfElementsToFind nil ) ) + (while CopyOfCurrElementsToFind + (let ( + ( CurrElementToFind ( car CopyOfCurrElementsToFind ) ) ) + ( setq CopyOfCurrElementsToFind ( cdr CopyOfCurrElementsToFind ) ) + (if ( apply + CompareFunc + ( cons + Element + ( cons + CurrElementToFind + CompareFuncParams ) ) ) + ( setq Ret ( cons ( list Element CurrElementToFind ) Ret ) ) + ( setq + NewListOfElementsToFind + ( cons CurrElementToFind NewListOfElementsToFind ) ) ) ) ) + ( setq CurrElementsToFind NewListOfElementsToFind ) ) ) + Ret ) ) + +(defun ListFlatten ( List ) + (let ( + ( Ret nil ) + ( Path nil ) + ) + (while ( or List Path ) + (cond ( + ( null List ) + ( setq List ( car Path ) ) + ( setq Path ( cdr Path ) ) + ) + ( + t + ( setq Element ( car List ) ) + ( setq List ( cdr List ) ) + (cond ( + + ( listp Element ) + ( setq Path ( cons List Path ) ) + ( setq List Element ) ) + ( + t + ( setq Ret ( tconc Ret Element ) ) + ) ) ) ) ) + ( car Ret ) + ) ) + +(defun ListAppend ( @rest Lists ) + (let ( + ( Ret nil ) ) + ( foreach List ( reverse Lists ) + ( setq Ret ( append List Ret ) ) ) + Ret +) ) + + +(defun IsInList ( Obj List ) + (member Obj List)!=nil + ) + +(defun RemoveFromList ( Obj List ) + (let (newlist) + (foreach item List + (when Obj!=item + newlist = (cons item newlist) + ) + ) + newlist + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/partition.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/partition.il new file mode 100644 index 0000000000..230df36cec --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/list/partition.il @@ -0,0 +1,40 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +;given List(x1, x2...xn), Func() +;run y=Func(x) for x1...xn +;returns Table[y]=list(all_xs_that_Func(x)=y) +(defun PartitionInverse ( List + Func ) + (let ( + ( Map ( makeTable `partition nil ) ) ) + ( foreach Element List + (let ( + ( Value + ( apply Func ( list Element ) ) ) ) + ( setarray Map + Value + ( cons Element ( arrayref Map Value ) ) ) ) ) + Map ) ) + +;given List(x1, x2...xn), Func() +;run y=Func(x) for x1...xn +;returns Table[x]=list(y all_xs_that_Func(x)=y) +(defun Partition ( List + Func ) + (let ( + ( PartitionInverse ( PartitionInverse List Func ) ) ) + ( PartitionInvertInverse + PartitionInverse ) ) ) + +(defun PartitionInvertInverse ( PartitionInverse ) + (let ( + ( Partition ( makeTable `inverse nil ) ) ) + ( foreach Value PartitionInverse + (let ( + ( Elements ( arrayref PartitionInverse Value ) ) ) + ( foreach Element Elements + ( setarray Partition Element ( list Value Elements ) ) ) ) ) + Partition ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makelayouttag.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makelayouttag.il new file mode 100644 index 0000000000..c00e93b35a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makelayouttag.il @@ -0,0 +1,513 @@ +; skill to do layout_tag cell +; AAG +; $Id$ +; $DateTime$ + +(defun MakeALabel ( cv lpp point label ) + let( ( x y ) + x=car(point) + y=cadr(point) + dbCreateLabel(cv lpp point label "centerCenter" "R0" "stick" 0.08) + dbCreateRect(cv lpp list(list(x-0.005 y-0.005) list(x+0.005 y+0.005))) + ) +) + +(defun MakeLeafTag ( CellView @key (orientation "MXR90") (TargetViewName "layout_tag") ) + let( (point trans inst rcv box x y x1 y1 fill) + trans=list(0:0 orientation 1.0) + rcv=nrOpenCellViewWritable( + CellView~>libName + CellView~>cellName + TargetViewName ?mode "w" ) + if( rcv != nil then + foreach( label setof( l CellView~>shapes l~>objType=="label" && l~>theLabel != "GND" && l~>theLabel != "Vdd") + point = dbTransformPoint( label~>xy trans) + dbCreateLabel( + rcv + label~>lpp + point + label~>theLabel + "centerCenter" + "R0" + label~>font label~>height ) + ; interchange x and y + x = car(point) + y = cadr(point) + dbCreateRect(rcv, label~>lpp list(list(x-0.005 y-0.005) list(x+0.005 y+0.005))) + ) + inst = dbCreateInst( rcv CellView "layout1" 0:0 orientation ) + if( inst == nil + printf( "Cannot create inst\n" )) + + + ;I have completely removed the original code drawing stripes of implants and wells around the perimeter. + ;Instead, it will tile fill cells around the edges, more representative of the real usage + + ; the below ASSUMES that the rotation is MXR90, it breaks if it is not MXR90 + ; also note that x and y are interchanged because of the MXR90 rotation + maxx=caadr(GetPrbound(CellView)->bBox) + maxy=cadadr(GetPrbound(CellView)->bBox) + x=caar(GetPrbound(CellView)->bBox)-4*DefaultWiringPitch + y=cadar(GetPrbound(CellView)->bBox) + dbCreateRect(rcv BoundaryLPP list(y:caar(GetPrbound(CellView)->bBox) maxy:maxx)) ; adds a prBoundary shape to the tag view + while(x <= maxx+4*DefaultWiringPitch + dbCreateInstByMasterName( rcv "globals" "globals.wires.POLY_FILL_S52" "layout" nil list(y x) "R90" ) + dbCreateInstByMasterName( rcv "globals" "globals.wires.POLY_FILL_S52" "layout" nil list(maxy x) "MXR90" ) + x=x+4*DefaultWiringPitch + ) + x=caar(GetPrbound(CellView)->bBox) + y=cadar(GetPrbound(CellView)->bBox) + while(y < maxy + dbCreateInstByMasterName( rcv "globals" "globals.wires.POLY_FILL_S52" "layout" nil list(y x) "R270" ) + dbCreateInstByMasterName( rcv "globals" "globals.wires.POLY_FILL_S52" "layout" nil list(y maxx) "MXR90" ) + y=y+2*TrackPitch + ) + maxx=caadr(GetPrbound(CellView)->bBox) + maxy=cadadr(GetPrbound(CellView)->bBox) + x1=caar(GetPrbound(CellView)->bBox) + x=x1 + n=0 + dbCreateLabel( rcv list("M3" "gnd") cadar(GetPrbound(CellView)->bBox)+0.06:caar(GetPrbound(CellView)->bBox)+0.06 "GND" "centerCenter" "R0" "roman" 0.005 ) + dbCreateLabel( rcv list("M3" "gnd") cadadr(GetPrbound(CellView)->bBox)-0.06:caar(GetPrbound(CellView)->bBox)+0.06 "GND" "centerCenter" "R0" "roman" 0.005 ) + while(x <= maxx+4*DefaultWiringPitch + y1=cadar(GetPrbound(CellView)->bBox) + y=y1 + while(y <= maxy+2*TrackPitch + dbCreateInstByMasterName( rcv "globals" "globals.wires.POWER_GRID_M34" "layout" nil list(y x) "R90" ) + MakeALabel( rcv list("M4" "gnd") y:x sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M4" "gnd") y:x+TrackPitch sprintf(nil "GND" n++) ) + if(y==y1 MakeALabel( rcv list("M4" "gnd") y-2*TrackPitch:x sprintf(nil "GND" n++) )) + if(y==y1 MakeALabel( rcv list("M4" "gnd") y-2*TrackPitch:x+TrackPitch sprintf(nil "GND" n++) )) + MakeALabel( rcv list("M4" "vdd") y-TrackPitch:x "Vdd" ) + MakeALabel( rcv list("M4" "vdd") y-TrackPitch:x+TrackPitch "Vdd") + if(x+2*TrackPitch > maxx+4*DefaultWiringPitch then + MakeALabel( rcv list("M4" "vdd") y-TrackPitch:x+2*TrackPitch "Vdd" ) + MakeALabel( rcv list("M4" "gnd") y:x+2*TrackPitch sprintf(nil "GND" n++) ) + if(y==y1 MakeALabel( rcv list("M4" "gnd") y-2*TrackPitch:x+2*TrackPitch sprintf(nil "GND" n++) )) + ) + y=y+2*TrackPitch + ) + x=x+2*TrackPitch + ) + + dbSave( rcv ) + dbClose( rcv ) + else + printf( "Cannot open cell\n" ) + ) + t + ) +) + +(defun MakeProteusTag ( CellView @key (orientation "MXR90") (TargetViewName "layout_tag") ) + let( (point trans inst rcv box x y x1 y1 y2 y3 maxy1 fill) + trans=list(0:0 orientation 1.0) + rcv=nrOpenCellViewWritable( + CellView~>libName + CellView~>cellName + TargetViewName ?mode "w" ) + if( rcv != nil then + foreach( label setof( l CellView~>shapes l~>objType=="label" && l~>theLabel != "GND" && l~>theLabel != "Vdd") + point = dbTransformPoint( label~>xy trans) + dbCreateLabel( + rcv + label~>lpp + point + label~>theLabel + "centerCenter" + "R0" + label~>font label~>height ) + ; interchange x and y + x = car(point) + y = cadr(point) + dbCreateRect(rcv, label~>lpp list(list(x-0.005 y-0.005) list(x+0.005 y+0.005))) + ) + inst = dbCreateInst( rcv CellView "layout1" 0:0 orientation ) + if( inst == nil + printf( "Cannot create inst\n" )) + + maxx=caadr(GetPrbound(CellView)->bBox) + maxy=cadadr(GetPrbound(CellView)->bBox) + x=caar(GetPrbound(CellView)->bBox) + x1=x+24*DefaultWiringPitch + x3=x+36*DefaultWiringPitch + x4=x+48*DefaultWiringPitch + x5=x+72*DefaultWiringPitch + y=cadar(GetPrbound(CellView)->bBox)-4*DefaultWiringPitch + y1=y-6*DefaultWiringPitch + y2=y-2*DefaultWiringPitch + maxy1=maxy+6*DefaultWiringPitch + n=0 + dbCreateRect(rcv BoundaryLPP list(y:caar(GetPrbound(CellView)->bBox) maxy:maxx)) ; adds a prBoundary shape to the tag view + when(maxx==1.56 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "R270" ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.17 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):2.72 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.945 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):-0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):-1.17 sprintf(nil "Vdd" n++) ) + ) + when(maxx==3.12 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "MXR90" ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.17 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):2.72 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.945 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):-0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):-1.17 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):3.51 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):4.29 sprintf(nil "Vdd" n++) ) + ) + when(maxx==4.68 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x4) "R270" ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.17 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):2.72 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.945 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):3.5 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):4.29 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):5.85 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):5.07 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):-0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):-1.17 sprintf(nil "Vdd" n++) ) + + ) + when(maxx==6.24 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x4) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x4) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x4) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x4) "MXR90" ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.17 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):2.72 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.945 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):3.5 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):4.29 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):5.85 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):5.07 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):6.63 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):7.41 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):-0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):-1.17 sprintf(nil "Vdd" n++) ) + ) + when(maxx==9.36 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x1) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x4) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x4) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x4) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x4) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x4) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x5) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x5) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(y2 x5) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.PLUG.0" "layout" nil list(maxy x5) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x5) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x5) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_BOT.0" "layout" nil list(y1 x5) "MXR90" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.END_TOP.0" "layout" nil list(maxy1 x5) "MXR90" ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.17 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):2.72 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):1.945 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):3.5 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):4.29 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):5.85 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):5.07 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):6.63 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):7.41 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):-0.39 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):-1.17 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):8.98 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):8.2 sprintf(nil "Vdd" n++) ) + MakeALabel( rcv list("M2" "gnd") (y2+0.13):9.76 sprintf(nil "GND" n++) ) + MakeALabel( rcv list("M2" "vdd") (y2+0.13):10.54 sprintf(nil "Vdd" n++) ) + ) + + + x=caar(GetPrbound(CellView)->bBox) + y=cadar(GetPrbound(CellView)->bBox)-0*DefaultWiringPitch + maxy2=maxy-1*DefaultWiringPitch + y4=cadar(GetPrbound(CellView)->bBox)-10*DefaultWiringPitch + maxy4=maxy+13*DefaultWiringPitch + when((maxx==6.24)||(maxx==3.12)||(maxx==9.36) + while(y < maxy2 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.FILL2.0" "layout" nil list(y x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.FILL2.0" "layout" nil list(y maxx) "MXR90" ) + y=y+2*DefaultWiringPitch + )) + when(maxx==1.56 + while(y < maxy2 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.FILL2.0" "layout" nil list(y x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.FILL2.0" "layout" nil list(y x1) "R270" ) + y=y+2*DefaultWiringPitch + )) + when(maxx==4.68 + while(y < maxy2 + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.FILL2.0" "layout" nil list(y x) "R270" ) + dbCreateInstByMasterName( rcv "synthesis.fill" "synthesis.fill.FILL2.0" "layout" nil list(y x4) "R270" ) + y=y+2*DefaultWiringPitch + )) + + maxx=caadr(GetPrbound(CellView)->bBox) + maxy=cadadr(GetPrbound(CellView)->bBox) + x1=caar(GetPrbound(CellView)->bBox) + x=x1 + n=0 + while(x <= maxx+4*DefaultWiringPitch + y1=cadar(GetPrbound(CellView)->bBox) + y=y1 + while(y <= maxy+2*TrackPitch + dbCreateInstByMasterName( rcv "globals" "globals.wires.POWER_GRID_M34" "layout" nil list(y x) "R90" ) +; MakeALabel( rcv list("M4" "gnd") y:x sprintf(nil "GND" n++) ) +; MakeALabel( rcv list("M4" "gnd") y:x+TrackPitch sprintf(nil "GND" n++) ) +; if(y==y1 MakeALabel( rcv list("M4" "gnd") y-2*TrackPitch:x sprintf(nil "GND" n++) )) +; if(y==y1 MakeALabel( rcv list("M4" "gnd") y-2*TrackPitch:x+TrackPitch sprintf(nil "GND" n++) )) +; MakeALabel( rcv list("M4" "vdd") y-TrackPitch:x "Vdd" ) +; MakeALabel( rcv list("M4" "vdd") y-TrackPitch:x+TrackPitch "Vdd") +; if(x+2*TrackPitch > maxx+4*DefaultWiringPitch then +; MakeALabel( rcv list("M4" "vdd") y-TrackPitch:x+2*TrackPitch "Vdd" ) +; MakeALabel( rcv list("M4" "gnd") y:x+2*TrackPitch sprintf(nil "GND" n++) ) +; if(y==y1 MakeALabel( rcv list("M4" "gnd") y-2*TrackPitch:x+2*TrackPitch sprintf(nil "GND" n++) )) +; ) + y=y+4*DefaultWiringPitch + ) + x=x+2*TrackPitch + ) + + dbSave( rcv ) + dbClose( rcv ) + else + printf( "Cannot open cell\n" ) + ) + t + ) +) + + +(defun MakeAvagoTag ( CellView @key (orientation "R0") (TargetViewName "layout_tag") ) + let( (point trans inst rcv box x y x1 y1 fill) + trans=list(0:0 orientation 1.0) + rcv=nrOpenCellViewWritable( + CellView~>libName + CellView~>cellName + TargetViewName ?mode "w" ) + if( rcv != nil then + foreach( label setof( l CellView~>shapes l~>objType=="label" ) + point = dbTransformPoint( label~>xy trans) + dbCreateLabel( + rcv + label~>lpp + point + label~>theLabel + "centerCenter" + "R0" + label~>font label~>height ) + ; interchange x and y + x = car(point) + y = cadr(point) + dbCreateRect(rcv, label~>lpp list(list(x-0.005 y-0.005) list(x+0.005 y+0.005))) + ) + inst = dbCreateInst( rcv CellView "layout1" 0:0 orientation ) + if( inst == nil + printf( "Cannot create inst\n" )) + + + ;I have completely removed the original code drawing stripes of implants and wells around the perimeter. + ;Instead, it will tile vendor.avago.svt.a28_filltap1_a1.0 cells around the edges, + + maxx=caadr(GetPrbound(CellView)->bBox) + maxy=cadadr(GetPrbound(CellView)->bBox) + x=caar(GetPrbound(CellView)->bBox) + y=cadar(GetPrbound(CellView)->bBox) + dbCreateRect(rcv BoundaryLPP list(caar(GetPrbound(CellView)->bBox):y maxx:maxy)) ; adds a prBoundary shape to the tag view + while(y < maxy-1 + if( (mod (round (y/1.1)) 2) != 0 + then + dbCreateInstByMasterName( rcv "vendor.avago.svt" "vendor.avago.svt.a28_filltap1_a1.0" "layout" nil list(x y+1.1) "R180" ) + dbCreateInstByMasterName( rcv "vendor.avago.svt" "vendor.avago.svt.a28_filltap1_a1.0" "layout" nil list(maxx y+1.1) "MX" ) + else + dbCreateInstByMasterName( rcv "vendor.avago.svt" "vendor.avago.svt.a28_filltap1_a1.0" "layout" nil list(x y) "MY" ) + dbCreateInstByMasterName( rcv "vendor.avago.svt" "vendor.avago.svt.a28_filltap1_a1.0" "layout" nil list(maxx y) "R0" ) + ) + y=y+1.1 + ) + + dbSave( rcv ) + dbClose( rcv ) + else + printf( "Cannot open cell\n" ) + ) + t + ) +) + + +(defun MakeLeafTagCell ( CellName @key ( ViewName "layout" ) (orientation "MXR90") (TargetViewName "layout_tag") ) + let( ( cv pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName) + if( cv == nil + printf( "Cannot open %s\n" CellName) + MakeLeafTag( cv ?orientation orientation ?TargetViewName TargetViewName )) + t + ) +) + +(defun MakeAvagoTagCell ( CellName @key ( ViewName "layout" ) (orientation "R0") (TargetViewName "layout_tag") ) + let( ( cv pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName) + if( cv == nil + printf( "Cannot open %s\n" CellName) + MakeAvagoTag( cv ?orientation orientation ?TargetViewName TargetViewName )) + t + ) +) + +(defun MakeProteusTagCell ( CellName @key ( ViewName "layout" ) (orientation "R0") (TargetViewName "layout_tag") ) + let( ( cv pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName) + if( cv == nil + printf( "Cannot open %s\n" CellName) + MakeProteusTag( cv ?orientation orientation ?TargetViewName TargetViewName )) + t + ) +) + + +(defun MakeLayoutTag ( CellView @key (orientation "MXR90") (TargetViewName "layout_tag") ) + (if (IsLeafCell CellView->cellName) then + (MakeLeafTag CellView ?orientation orientation ?TargetViewName TargetViewName) + else + (MakeMidLayoutTag CellView ?orientation orientation ?TargetViewName TargetViewName) + ) +) + +;(defun MakeLayoutTagCell ( CellName @key (ViewName "layout") +; (orientation "MXR90") +; (TargetViewName "layout_tag") +; (CastPath ConfigFileGetValue(TheCDSConfigTable "CAST_PATH")) +; (TempDir ConfigFileGetValue(TheCDSConfigTable "TEMP")) ) +; (if (IsLeafCell CellName ?tempdir TempDir ?castpath CastPath) then +; (MakeLeafTagCell CellName ?ViewName ViewName ?orientation orientation ?TargetViewName TargetViewName) +; else +; (MakeMidLayoutTagCell CellName ?ViewName ViewName ?orientation orientation ?TargetViewName TargetViewName) +; ) +;) + +(defun MakeLayoutTagCell ( CellName @key (ViewName "layout") + (orientation "MXR90") + (TargetViewName "layout_tag") + (CastPath ConfigFileGetValue(TheCDSConfigTable "CAST_PATH")) + (TempDir ConfigFileGetValue(TheCDSConfigTable "TEMP")) ) + let( (isleaf isavago isoproteus ) + + isleaf = (IsLeafCell CellName ?viewname ViewName ?tempdir TempDir ?castpath CastPath) + isproteus = (IsProteusCell CellName ?viewname ViewName ?tempdir TempDir ?castpath CastPath) + isavago = (IsAvagoCell CellName ?viewname ViewName ?tempdir TempDir ?castpath CastPath) + + (cond ((when isleaf + (MakeLeafTagCell CellName ?ViewName ViewName ?orientation orientation ?TargetViewName TargetViewName))) + ((when isproteus + (MakeProteusTagCell CellName ?ViewName ViewName ?orientation orientation ?TargetViewName TargetViewName))) + ((when isavago + (MakeAvagoTagCell CellName ?ViewName ViewName ?orientation "R0" ?TargetViewName TargetViewName))) + (t (MakeMidLayoutTagCell CellName ?ViewName ViewName ?orientation orientation ?TargetViewName TargetViewName)) + ) + ) +) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makemidlayouttag.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makemidlayouttag.il new file mode 100644 index 0000000000..572ccf2dfb --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/makemidlayouttag.il @@ -0,0 +1,375 @@ +; skill to do layout_tag cell +; AAG +; $Id: //depot/sw/main/cad/external-tools-integration/cadence/virtuoso/skill/util/makelayouttag.il#5 $ +; $DateTime: 2012/04/26 09:34:35 $ + +(defun MakeMidLayoutTag ( CellView @key (orientation "MXR90") (TargetViewName "layout_tag") ) + let( (point trans inst rcv box x y valuex1 valueex1 valuey1 valueey1 valueyy1 valueeyy1 valuex2 valueex2 valuey2 valueey2 valueyy2 valueeyy2 prbbboxx1 prbbboxy1 prbbboxx2 prbbboxy2 leftx lefttx lefty leftty leftyy lefttyy rightx righttx righty rightty rightyy righttyy numofrows numofcols INST) + trans=list(0:0 orientation 1.0) + makePloc( CellView~>libName CellView~>cellName CellView~>viewName sprintf(nil "%s.ploc" CellView~>cellName) ) + rcv=nrOpenCellViewWritable( + CellView~>libName + CellView~>cellName + TargetViewName ?mode "w" ) + if( rcv != nil then + foreach( label setof( l CellView~>shapes l~>objType=="label" ) + point = dbTransformPoint( label~>xy trans) + dbCreateLabel( + rcv + label~>lpp + point + label~>theLabel + "centerCenter" + "R0" + label~>font label~>height ) + ; interchange x and y + x = car(point) + y = cadr(point) + dbCreateRect(rcv, label~>lpp list(list(x-0.005 y-0.005) list(x+0.005 y+0.005))) + ) + inst = dbCreateInst( rcv CellView "inst_layout" 0:0 orientation ) + if( inst == nil + printf( "Cannot create inst\n" )) + + if((GetPrbound(CellView)==nil) then + println("Error: Missing PrBound in the cellview ") + else + prbbboxx1 = caar(GetPrbound(CellView)->bBox) + prbbboxy1 = cadar(GetPrbound(CellView)->bBox) + prbbboxx2 = caadr(GetPrbound(CellView)->bBox) + prbbboxy2 = cadadr(GetPrbound(CellView)->bBox) + if(negativep(prbbboxx1)==t then + valueex1 = round((prbbboxx1/3.12)-0.5) + lefttx = (3.12*valueex1)-3.12 + else if(prbbboxx1==0 then + lefttx = -3.12 + else + valueex1 = round((prbbboxx1/3.12)-0.5) + lefttx = (3.12*valueex1)-3.12)) + if(negativep(prbbboxy1)==t then + valueey1 = round((prbbboxy1/3.12)-0.5) + leftty = (3.12*valueey1)-3.12 + valueeyy1 = round((prbbboxy1/8.8)-0.5) + lefttyy = (8.8*valueeyy1)-8.8 + else if(prbbboxy1==0 then + leftty = -3.12 + lefttyy = -8.8 + else + valueey1 = round((prbbboxy1/3.12)-0.5) + leftty = (3.12*valueey1)-3.12 + valueeyy1 = round((prbbboxy1/8.8)-0.5) + lefttyy = (8.8*valueeyy1)-8.8)) + if(negativep(prbbboxx2)==t then + valueex2 = round((prbbboxx2/3.12)+0.5) + righttx = (3.12*valueex2)+3.12 + else + valueex2 = round((prbbboxx2/3.12)+0.5) + righttx = (3.12*valueex2)+3.12) + if(negativep(prbbboxy2)==t then + valueey2 = round((prbbboxy2/3.12)+0.5) + rightty = (3.12*valueey2)+3.12 + valueeyy2 = round((prbbboxy2/8.8)+0.5) + righttyy = (8.8*valueeyy2)+8.8 + else + valueey2 = round((prbbboxy2/3.12)+0.5) + rightty = (3.12*valueey2)+3.12 + valueeyy2 = round((prbbboxy2/8.8)+0.5) + righttyy = (8.8*valueeyy2)+8.8) + + if(negativep(prbbboxy1)==t then + valuex1 = round((prbbboxy1/3.12)-0.5) + leftx = (3.12*valuex1)-3.12 + else if(prbbboxy1==0 then + leftx = -3.12 + else + valuex1 = round((prbbboxy1/3.12)+0.5) + leftx = (3.12*valuex1)-3.12)) + if(negativep(prbbboxx1)==t then + valuey1 = round((prbbboxx1/3.12)-0.5) + lefty = (3.12*valuey1)-3.12 + valueyy1 = round((prbbboxx1/8.8)-0.5) + leftyy = (8.8*valueyy1)-8.8 + else if(prbbboxx1==0 then + lefty = -3.12 + leftyy = -8.8 + else + valuey1 = round((prbbboxx1/3.12)+0.5) + lefty = (3.12*valuey1)-3.12 + valueyy1 = round((prbbboxx1/8.8)+0.5) + leftyy = (8.8*valueyy1)-8.8)) + if(negativep(prbbboxy2)==t then + valuex2 = round((prbbboxy2/3.12)-0.5) + rightx = (3.12*valuex2)+3.12 + else + valuex2 = round((prbbboxy2/3.12)+0.5) + rightx = (3.12*valuex2)+3.12) + if(negativep(prbbboxx2)==t then + valuey2 = round((prbbboxx2/3.12)-0.5) + righty = (3.12*valuey2)+3.12 + valueyy2 = round((prbbboxx2/8.8)-0.5) + rightyy = (8.8*valueyy2)+8.8 + else + valuey2 = round((prbbboxx2/3.12)+0.5) + righty = (3.12*valuey2)+3.12 + valueyy2 = round((prbbboxx2/8.8)+0.5) + rightyy = (8.8*valueyy2)+8.8) + dbCreateRect(CellView "y1" list(lefttx:leftty righttx:rightty)); adds a y1 shape to the layout view + numofrows = ceiling((rightx-leftx)/3.12)+3 + numofcols = ceiling((rightyy-leftyy)/8.8)+3 + gridCV = (nrOpenCellViewReadable "globals.avago" "globals.avago.wires.POWER_GRID_M89_CONV" "layout") + FillTag(rcv ?CV CellView) + (dbCreateSimpleMosaic rcv gridCV "taggrid" (leftx-3.12):(leftyy-8.8) "R0" numofcols numofrows 8.8 3.12) + foreach(INST rcv->instances + when((INST~>name=="taggrid") + INST~>uX=3.12 + )) + ) + + dbSave( rcv ) + dbClose( rcv ) + else + printf( "Cannot open cell\n" ) + ) + t + ) +) + +(defun FillTag + (tagView @key (CV (geGetEditCellView)) ; select CV + (overhang t) ; should power grid overhang by 1 tile + ) + (let (Components RComponents type_sub polyCellName + inst prb PowerGridSize PGS prbObjPoints prb1 + x1box x2box y1box y2box x1 y1 x2 x2 xy + AssuraLayerMappings AssuraRuleFile AssuraRunLog ErrorStr + polyCV ReplaceCellNameTable + count gridName gridCV rows cols leafcell leafbbox + filltag XdirGridSize PolyGridSize PolyColSize filltagname LName CName) + + ; generated cell or file names + filltagname = strcat( CV~>viewName "_" "filltag") + LName = CV~>libName + CName = CV~>cellName + Components = (parseString CV->cellName ".") + RComponents = (reverse Components) + (when (length RComponents)<3 (error "Cell name violates CAST conventions\n")) + type_sub = (sprintf nil "%s_%s" (cadr RComponents) (car RComponents)) + polyCellName = (CV->cellName) + + ; delete old poly grid instance if it exists + inst = (dbFindAnyInstByName CV "filltag") + (when inst (dbDeleteObject inst)) + + ; get prBoundary boundary shapes + foreach(SHAPE CV->shapes + when((SHAPE~>layerName=="y1") + prbObjPoints = SHAPE~>bBox)) + prb1 = (dbCreateRect CV list("prBoundary" "drawing") prbObjPoints) + copyprb1 = (setof copyprb1 CV~>shapes (car copyprb1->lpp) == "prBoundary"&&(cadr copyprb1->lpp) == "drawing") + + ; checks for prBoundary drawing, if only one exists, if vertices are on 3.12u grid + (cond ((length copyprb1)==1 (letseq + ((copyprb (car copyprb1))) + vertprb = (setof vertprb copyprb->points (CheckOffGrid vertprb)) + vertprbrec = (setof vertprbrec copyprb->bBox (CheckOffGrid vertprbrec)) + (when vertprb (error "Not All prBoundary Vertices Are On 3.12u Grid: %L" vertprb)) + (when vertprbrec (error "Not All prBoundary Vertices Are On 3.12u Grid: %L" vertprbrec)) + prb = (dbCopyShape copyprb CV ) + prb->lpp=(list "prBoundary" "boundary"))) + (t (error "ERROR: Check prBoundary layer. Either no prBoundary or more than one exists."))) + + ;create prBoundary leaf boxes for fill block + leafbboxx1 = GetPrbound(CellView)->points + dbCreatePolygon(CV list("prBoundary" "leaf") leafbboxx1) + + ; minimum sized power grid y-axis + PowerGridSize = 2*PowerGridPitch + + ; minimum sized poly x-axis grid + PolyGridSize = 2*0.13 + + ; number of polyfill columns per powergrid + OneCol = 1 + TwoCol = 2 + ThreeCol = 3 + PolyColSize = PowerGridSize/PolyGridSize + + ; run layer processing + AssuraLayerMappings = (list + (list "filltag" (list "M7" "block")) + ) + AssuraRuleFile = (sprintf nil "%s/share/Fulcrum/cell_automation/%s" + (ConfigFileGetValue TheCDSConfigTable "FULCRUM_PDK_ROOT") + "filltag.rul") + AssuraRunLog = (sprintf nil "%s/%s.filltag.log" + (ConfigFileGetValue TheCDSConfigTable "TEMP") + CV->cellName) + ErrorStr = (AssuraRunAssuraLayerProcessor + CV CV->libName polyCellName filltagname + AssuraRuleFile + (ConfigFileGetValue TheCDSConfigTable "TEMP") + AssuraLayerMappings + nil + ?AssuraRunLog AssuraRunLog + ?LeaveMess nil + ) + polyCV = (nrOpenCellViewWritable CV->libName polyCellName filltagname) + + ; define poly cell names + ReplaceCellNameTable=makeTable("a" "") + ReplaceCellNameTable["M7"]="globals.wires.POLY_FILL_S23" + + ; replace block shapes with poly mosaics + count=0 + (foreach lpp polyCV->lpps + gridName = ReplaceCellNameTable[lpp->layerName] + (when gridName!="" && lpp->purpose=="block" + gridCV = (nrOpenCellViewReadable "globals" gridName "layout") + (foreach shape lpp->shapes + x1 = (leftEdge shape->bBox) + y1 = (bottomEdge shape->bBox) + x2 = (rightEdge shape->bBox) + y2 = (topEdge shape->bBox) + cols = (round (x2-x1)/PolyGridSize) + rows = (round (y2-y1)/PowerGridSize) + XdirGridSize = PolyGridSize + (cond (cols >= ThreeCol (let () + gridCV = (nrOpenCellViewReadable "globals" "globals.wires.POLY_FILL_S78" "layout") + cols = (round cols/ThreeCol) + XdirGridSize = 3*PolyGridSize)) + + (cols >= ThreeCol (let () + gridCV = (nrOpenCellViewReadable "globals" "globals.wires.POLY_FILL_S78" "layout") + cols = (round cols/ThreeCol) + XdirGridSize = 3*PolyGridSize)) + + (cols >= TwoCol (let () + gridCV = (nrOpenCellViewReadable "globals" "globals.wires.POLY_FILL_S52" "layout") + cols = (round cols/TwoCol) + XdirGridSize = 2*PolyGridSize)) + + (cols >= OneCol (let () + gridCV = (nrOpenCellViewReadable "globals" "globals.wires.POLY_FILL_S26" "layout") + cols = (round cols/OneCol) + XdirGridSize = PolyGridSize)) + ) + + (dbCreateSimpleMosaic polyCV gridCV + (sprintf nil "I%d" count) x1:y1 "R0" + rows cols PowerGridSize XdirGridSize) + + count = count+1 + (dbDeleteObject shape) + ) + ) + ) + + ; copy prBoundary object to poly fill view + (dbCreatePRBoundary polyCV CV->prBoundary->points) + + ; delete temporary prBoundary shape + (dbDeleteObject prb) + + ; delete temporary leaf prBoundary shapes + leafprb = (setof leafprb (wcv)~>shapes (car leafprb->lpp) == "prBoundary"&&(cadr leafprb->lpp) == "leaf") + (foreach templeafprb leafprb + (dbDeleteObject templeafprb)) + + ; instantiate poly grid + + foreach(SHAPE CV->shapes + when((SHAPE~>layerName=="y1")||(SHAPE~>layerName=="prBoundary") + dbDeleteObject(SHAPE) + )) + + filler = (dbCreateInst tagView polyCV "filltag" 0:0 "MXR90") + (AnchorInstance filler) + dbFlattenInst(filler 1) + ;ddDeleteObj(ddGetObj(LName CName filltagname)) + ; save and return + (dbSave polyCV) + polyCVID = polyCV + (dbClose polyCV) + ddDeleteObj(ddGetObj(LName CName filltagname)) + (dbSave CV) + (dbClose CV) + (dbSave tagView) + polyCVID + ) + ) +(defun MakeMidLayoutTagCell ( CellName @key ( ViewName "layout" ) (orientation "MXR90") (TargetViewName "layout_tag") ) + let( ( cv pieces LibName ) + pieces=parseString( CellName "." ) + LibName=nth( 0 pieces ) + for( n 1 length(pieces)-3 + LibName = strcat( LibName "." nth( n pieces ))) + cv=nrOpenCellViewReadable( LibName CellName ViewName) + if( cv == nil + printf( "Cannot open %s\n" CellName) + MakeMidLayoutTag( cv ?orientation orientation ?TargetViewName TargetViewName )) + t + ) +) + +(defun getPloc ( cellView instance transform fout) + (let (sub nv ng xlim ylim tx tm hiername subname orient isProteus isSram isPG x y) + if(transform == nil transform=list(list( 0 0 ) "R0" 1.0)) + if(instance~>objType == "inst" + orient=instance~>orient + orient=car(instance~>tileArray) + ) + if(instance==nil + tx=transform + tx=dbConcatTransform(list(instance~>xy orient 1.0) transform) + ) + if((cellView~>cellName == "globals.wires.POWER_GRID_M78") then + ng=1 + nv=1 + for(nx 0 instance~>rows-1 + for(ny 0 instance~>columns-1 + x=car(instance~>xy)+nx*instance~>uX + y=cadr(instance~>xy)+ny*instance~>uY + if(nx == instance->rows-1 + limx=2 + limx=1 + ) + if(ny == instance->columns-1 + limy=1 + limy=0 + ) + for(ax 0 limx + for(ay 0 limy + tm=dbConcatTransform(list(list(x+ax*1.56 y+ay*3.12) orient 1.0) transform) + fprintf( fout "GND.extra%03d %.3f %.3f M8 GROUND\n" ng round(car(car(tm))*1000)/1000.0 round(cadr(car(tm))*1000)/1000.0 tm) + ng++ + )) + for(ax 0 limx + for(ay 0 0 + tm=dbConcatTransform(list(list(x+ax*1.56 y+ay*3.12+1.56) orient 1.0) transform) + fprintf( fout "Vdd.extra%03d %.3f %.3f M8 POWER\n" nv round(car(car(tm))*1000)/1000.0 round(cadr(car(tm))*1000)/1000.0 tm) + nv++ + )) + )) + ) + foreach(ix setof( ix cellView~>instances t) + getPloc( ix~>master~>cellView, ix, tx fout) + ) +)) + +(defun makePloc ( libName cellName viewName fileName ) + (let (cv fout) + cv=nrOpenCellViewReadable(libName cellName viewName) + if(cv then + fout=outfile(fileName) + if( fout then + getPloc(cv nil nil fout) + close(fout); + system(sprintf(nil "/bin/sort %s -o %s" fileName fileName)) + else + printf("Cannot open %s\n" fileName)) + else + printf("Cannot read %s %s %s\n" libName cellName viewName) + ) + t + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/math/math.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/math/math.il new file mode 100644 index 0000000000..7fff91dcd8 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/math/math.il @@ -0,0 +1,8 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun MathRoundToNearest ( Value Step ) + ( times Step ( round ( quotient Value Step ) ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/name.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/name.il new file mode 100644 index 0000000000..1f7bd865ad --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/name.il @@ -0,0 +1,592 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun NameStartRename ( type from to ) + (let ( + ( Cmd + ( sprintf + nil + "%s/rename --type=%s --from=%s --to=%s" + ( PackageGetBinRoot ) type from to) ) ) + (let ( + ( CID + ( ipcBeginProcess Cmd ) ) ) + (ipcWaitForProcess CID) + (unless ( ipcIsAliveProcess CID ) + (error "rename failed" ) ) + CID ) ) ) + +(defun NameDoRename ( CID name ) + (unless + ( ipcWriteProcess + CID + ( sprintf nil "%s\n" name ) ) + (error "rename failed" ) ) + ( StringUtilReadLine CID 10 ) + ) + +(defun NameStartCastToCadenceCellName ( ) + (let ( + ( Cmd + ( sprintf + nil + "%s/rename --type=cell --from=cast --to=cadence" + ( PackageGetBinRoot ) ) ) ) + (let ( + ( CID + ( ipcBeginProcess Cmd ) ) ) + (ipcWaitForProcess CID) + (unless ( ipcIsAliveProcess CID ) + (error "rename failed" ) ) + CID ) ) ) + +(defun NameDoCastToCadenceCellName ( CID CellName ) + (unless + ( ipcWriteProcess + CID + ( sprintf nil "%s\n" CellName ) ) + (error "rename failed" ) ) + ( StringUtilReadLine CID 10 ) + ) + +(defun NameGetViewDirFromDFIIDirAndCellView ( DFIIDir CellView ) + ( NameGetViewDirFromDFIIDirAndCellNameAndView + DFIIDir + ( getq CellView cellName ) + ( getq CellView viewName ) ) ) + +(defun NameGetViewDirFromDFIIDirAndCellNameAndView ( DFIIDir CellName ViewName ) + ( sprintf nil "%s/%s" + ( NameGetCellDirFromDFIIDirAndCellName + DFIIDir + CellName ) + ViewName ) ) + +(defun NameGetCellDirFromDFIIDirAndCellName ( DFIIDir CellName ) + (let ( + ( LibCellPair ( NameParseCellName CellName ) ) ) + (let ( + ( LibDir ( buildString ( parseString ( car LibCellPair ) "." ) "/" ) ) + ( CellDir ( buildString ( parseString + ( buildString ( parseString + ( cadr LibCellPair ) "." ) "#2e" ) + "-" ) "#2d" ) ) ) + ( sprintf nil "%s/%s/%s" DFIIDir LibDir CellDir ) ) ) ) + + +(defun NameGetLibDirFromDFIIDirAndLibName ( DFIIDir LibName ) + ( rexCompile "\\." ) + ( strcat + ( PathMakePathAbsolute DFIIDir ) + ( strcat + "/" + ( rexReplace LibName "/" 0 ) ) ) ) + +(defun NameGetLibDirFromDFIIDirAndCellName ( DFIIDir CellName ) + (let ( + ( LibName ( car + ( NameParseCellName + CellName ) ) ) ) + (when LibName + ( NameGetLibDirFromDFIIDirAndLibName DFIIDir LibName ) ) ) ) + + +(defun NameGetDFIIDirFromCellName ( CellName ) + ( NameGetDFIIDirFromLibName + ( car ( NameParseCellName CellName ) ) ) ) + +(defun NameGetDFIIDirFromLibName ( LibName ) + (let ( + ( LibDirObj ( ddGetObj LibName ) ) ) + (if ( null LibDirObj ) + (error ( sprintf + nil + "NameGetDFIIDirFromLibName: LibName %s not valid" + LibName ) ) + (let ( + ( Path ( ddGetObjWritePath LibDirObj ) ) ) + (if ( null Path ) + (error "NameGetDFIIDirectoryFromLibName: Lib path not valid" ) + (let ( + ( ParsedLibName ( parseString LibName "." ) ) + ( ParsedPath ( parseString Path "/" ) ) ) + (let ( + ( DFIIPath + ( buildString + ( ListRemoveLastNElements + ParsedPath + ( length ParsedLibName ) ) "/" ) ) ) + (if ( equal ( substring Path 1 1 ) "/" ) + DFIIPath = ( strcat "/" DFIIPath )) + if( rexMatchp( "^/mnt/fulcrum/home" DFIIPath) then + DFIIPath = substring( DFIIPath 13 strlen(DFIIPath)-12)) + DFIIPath + ) ) ) ) ) ) ) + + +(defun NameGetCellPathFromCellName ( CellName ) + (let ( + ( LibCellPair ( NameParseCellName CellName ) ) ) + (let ( + ( CellDirObj ( ddGetObj ( car LibCellPair ) ( cadr LibCellPair ) ) ) ) + (if ( null CellDirObj ) + (error "NameGetCellDirectoryFromCellName: CellName not valid" ) + (let ( + ( Path ( ddGetObjWritePath CellDirObj ) ) ) + (if ( null Path ) + (error "NameGetCellDirectoryFromCellName: Cell path not valid" ) + Path ) ) ) ) ) ) + +(defun NameGetCellPathFromCellNameAndView ( CellName ViewName ) + (let ( + ( LibCellPair ( NameParseCellName CellName ) ) ) + (let ( + ( CellDirObj ( ddGetObj ( car LibCellPair ) ( cadr LibCellPair ) ViewName ) ) ) + (if ( null CellDirObj ) + (error "NameGetCellDirectoryFromCellNameAndView: CellName or ViewName not valid" ) + (let ( + ( Path ( ddGetObjWritePath CellDirObj ) ) ) + (if ( null Path ) + (error "NameGetCellDirectoryFromCellNameAndView: Cell path not valid" ) + Path ) ) ) ) ) ) + + +(defun NameParseCellName ( CellName ) + (let ( + ( Components ( parseString CellName "." ) ) ) + (let ( + ( RComponents ( reverse Components ) ) ) + (let ( + ( RLibNameComponents ( cdr ( cdr RComponents ) ) ) + ( LibName nil ) ) + if( rexMatchp("^[a-z_0-9]+$" car(RLibNameComponents))==nil then + RLibNameComponents=cdr(RLibNameComponents) + ) + ( foreach + Component + ( reverse RLibNameComponents ) + (if LibName + ( setq LibName ( sprintf nil "%s.%s" LibName Component ) ) + ( setq LibName Component ) ) ) + ( list LibName CellName ) ) ) ) ) + +(defun NameFilterInstanceTripples ( InstanceTripples LibCellExpressionPairs ) + (let ( + ( FilteredInstanceTripples nil ) + ( PassingInstanceTripples InstanceTripples ) ) + ( foreach + LibCellExpressionPair + LibCellExpressionPairs + (let ( + ( LibExpression ( car LibCellExpressionPair ) ) + ( CellExpression ( cadr LibCellExpressionPair ) ) + ( FilteredByLib nil ) + ( PassedByCurrPair nil ) ) + ( rexCompile LibExpression ) + ( foreach + InstanceTripple + PassingInstanceTripples + (if ( rexExecute ( cadr InstanceTripple ) ) + ( setq FilteredByLib ( cons InstanceTripple FilteredByLib ) ) + ( setq PassedByCurrPair ( cons InstanceTripple PassedByCurrPair ) ) ) ) + ( rexCompile CellExpression ) + ( foreach + InstanceTripple + FilteredByLib + (if ( rexExecute ( caddr InstanceTripple ) ) + ( setq FilteredInstanceTripples ( cons InstanceTripple FilteredInstanceTripples ) ) + ( setq PassedByCurrPair ( cons InstanceTripple PassedByCurrPair ) ) ) ) + ( setq PassingInstanceTripples PassedByCurrPair ) ) ) + ( list PassingInstanceTripples FilteredInstanceTripples ) ) ) + +(defun NameFilterObjects ( Objects LibCellExpressionPairs LibNameFunc CellNameFunc ) + + (let ( + ( FilteredObjects nil ) + ( PassingObjects Objects ) ) + ( foreach + LibCellExpressionPair + LibCellExpressionPairs + (let ( + ( LibExpression ( car LibCellExpressionPair ) ) + ( CellExpression ( cadr LibCellExpressionPair ) ) + ( FilteredByLib nil ) + ( PassedByCurrPair nil ) ) + ( rexCompile LibExpression ) + ( foreach + Object + PassingObjects + (if ( rexExecute ( apply LibNameFunc ( list Object ) ) ) + ( setq FilteredByLib ( cons Object FilteredByLib ) ) + ( setq PassedByCurrPair ( cons Object PassedByCurrPair ) ) ) ) + ( rexCompile CellExpression ) + ( foreach + Object + FilteredByLib + (if ( rexExecute ( apply CellNameFunc ( list Object ) ) ) + ( setq FilteredObjects ( cons Object FilteredObjects ) ) + ( setq PassedByCurrPair ( cons Object PassedByCurrPair ) ) ) ) + ( setq PassingObjects PassedByCurrPair ) ) ) + ( list PassingObjects FilteredObjects ) ) ) + +(defun NameFilterInstances ( Instances LibCellExpressionPairs ) + ( NameFilterObjects + Instances + LibCellExpressionPairs + (lambda ( Instance ) + ( getq Instance libName ) ) + (lambda ( Instance ) + ( getq Instance cellName ) ) ) ) + + +(defun NameFilterInstanceMasters ( InstanceMasters LibCellExpressionPairs ) + ( NameFilterObjects + InstanceMasters + LibCellExpressionPairs + (lambda ( InstanceMaster ) + ( getq InstanceMaster libName ) ) + (lambda ( InstanceMaster ) + ( getq InstanceMaster cellName ) ) ) ) + + +(defun NameTablifyInstancesFullNamesFromFilterResult ( FilterResult + TargetTable ) + (let ( + ( NonFoldableInstances ( car FilterResult ) ) + ( FoldableInstances ( cadr FilterResult ) ) ) + ( foreach + Instance + NonFoldableInstances + ( setarray + TargetTable + ( getq Instance name ) + ( NameCanonicalizeNonFoldableInstanceName + ( getq Instance name ) ) ) ) + ( foreach + Instance + FoldableInstances + ( setarray + TargetTable + ( getq Instance name ) + ( NameCanonicalizeNonFoldableInstanceName + ( getq Instance name ) ) ) ) + t ) ) + +(defun NameTablifyInstancesFullNames ( Instances + TargetTable + FoldableLibCellExpressionPairs ) + (let ( + ( FilterResult ( NameFilterInstances + Instances + FoldableLibCellExpressionPairs ) ) ) + ( NameTablifyInstancesFullNamesFromFilterResult + FilterResult + TargetTable ) ) ) + + +(defun NameTablifyInstancesNamesFromFilterResult ( FilterResult + TargetTable ) + (let ( + ( NonFoldableInstances ( car FilterResult ) ) + ( FoldableInstances ( cadr FilterResult ) ) ) + ( foreach + Instance + NonFoldableInstances + ( setarray + TargetTable + ( getq Instance name ) + ( NameCanonicalizeNonFoldableInstanceName + ( getq Instance name ) ) ) ) + ( foreach + Instance + FoldableInstances + ( setarray + TargetTable + ( getq Instance name ) + ( NameCanonicalizeFoldableInstanceName + ( getq Instance name ) ) ) ) + t ) ) + +(defun NameTablifyInstancesNames ( Instances + TargetTable + FoldableLibCellExpressionPairs ) + (let ( + ( FilterResult ( NameFilterInstances + Instances + FoldableLibCellExpressionPairs ) ) ) + ( NameTablifyInstancesNamesFromFilterResult + FilterResult + TargetTable ) ) ) + +(defun NameTablifyInstancesFromFilterResult ( FilterResult + TargetTable ) + (let ( + ( NonFoldableInstances ( car FilterResult ) ) + ( FoldableInstances ( cadr FilterResult ) ) ) + ( foreach + Instance + NonFoldableInstances + ( setarray + TargetTable + ( NameCanonicalizeNonFoldableInstanceName ( getq Instance name ) ) + ( list Instance ) ) ) + ( foreach + Instance + FoldableInstances + (let ( + ( CanonicalInstanceName ( NameCanonicalizeFoldableInstanceName ( getq Instance name ) ) ) ) + + ( setarray + TargetTable + CanonicalInstanceName + ( cons Instance ( arrayref TargetTable CanonicalInstanceName ) ) ) ) ) + t ) ) + +(defun NameTablifyInstancesTable ( Instances + TargetTable + FoldableLibCellExpressionPairs ) + (let ( + ( FilterResult ( NameFilterInstances + Instances + FoldableLibCellExpressionPairs ) ) ) + ( NameTablifyInstancesFromFilterResult + FilterResult + TargetTable ) ) ) + + +(defun NameTablifyInstancesAndInstancesNames ( Instances + FoldableLibCellExpressionPairs + TargetInstancesTable + TargetInstancesNameTable + TargetInstancesFullNameTable + ) + (let ( + ( FilterResult ( NameFilterInstances + Instances + FoldableLibCellExpressionPairs ) ) ) + ( NameTablifyInstancesFromFilterResult + FilterResult + TargetInstancesTable ) + ( NameTablifyInstancesNamesFromFilterResult + FilterResult + TargetInstancesNameTable ) + ( NameTablifyInstancesFullNamesFromFilterResult + FilterResult + TargetInstancesFullNameTable ) + ) ) + + +(defun NameMakeInstancesNameTable ( Instances + FoldableLibCellExpressionPairs ) + (let ( + ( Result ( makeTable "instancesNameTable" nil ) ) ) + ( NameTablifyInstancesNames + Instances + Result + FoldableLibCellExpressionPairs ) + Result ) ) + +(defun NameMakeInstancesTable ( Instances + FoldableLibCellExpressionPairs ) + (let ( + ( Result ( makeTable "instancesTable" nil ) ) ) + ( NameTablifyInstances + Instances + Result + FoldableLibCellExpressionPairs ) + Result ) ) + +(defun NameMakeInstancesFullNameTable ( Instances + FoldableLibCellExpressionPairs ) + (let ( + ( Result ( makeTable "instancesFullNameTable" nil ) ) ) + ( NameTablifyInstancesFullNames + Instances + Result + FoldableLibCellExpressionPairs ) + Result ) ) + +(defun NameMakeEmptyInstanceMap () + ( list + ( makeTable "instancesTable" nil ) + ( makeTable "instancesNameTable" nil ) + ( makeTable "instancesFullNameTable" nil ) + ) ) + +(defun NamePopulateInstanceMapWithInstances ( InstanceMap + Instances + FoldableLibCellExpressionPairs ) + ( NameTablifyInstancesAndInstancesNames + Instances + FoldableLibCellExpressionPairs + ( car InstanceMap ) + ( cadr InstanceMap ) + ( caddr InstanceMap ) + ) ) + +(defun NamePopulateInstanceMapWithCellView ( InstanceMap + CellView + FoldableLibCellExpressionPairs ) + ( NameTablifyInstancesAndInstancesNames + ( getq CellView instances ) + FoldableLibCellExpressionPairs + ( car InstanceMap ) + ( cadr InstanceMap ) + ( caddr InstanceMap ) + ) ) + + +(defun NameMakeInstanceMapFromInstances ( Instances + FoldableLibCellExpressionPairs ) + (let ( + ( Ret ( NameMakeEmptyInstanceMap ) ) ) + ( NamePopulateInstanceMapWithInstances + Ret + Instances + FoldableLibCellExpressionPairs ) + Ret ) ) + +(defun NameMakeInstanceMapFromCellView ( CellView + FoldableLibCellExpressionPairs ) + (let ( + ( Ret ( NameMakeEmptyInstanceMap ) ) ) + ( NamePopulateInstanceMapWithCellView + Ret + CellView + FoldableLibCellExpressionPairs ) + Ret ) ) + +(defun NameGetInstancesForCanonicalName ( InstanceMap + CanonicalName ) + ( arrayref + ( car InstanceMap ) + CanonicalName ) ) + + +(defun NameGetCanonicalInstanceNameForInstanceName ( InstanceMap + InstanceName ) + ( arrayref + ( cadr InstanceMap ) + InstanceName ) ) + +(defun NameGetCanonicalInstanceNameForInstance ( InstanceMap + Instance ) + ( NameGetCanonicalInstanceNameForInstanceName + InstanceMap + ( getq Instance name ) ) ) + +(defun NameGetFullCanonicalInstanceNameForInstanceName ( InstanceMap + InstanceName ) + ( arrayref + ( caddr InstanceMap ) + InstanceName ) ) + +(defun NameGetFullCanonicalInstanceNameForInstance ( InstanceMap + Instance ) + ( NameGetFullCanonicalInstanceNameForInstanceName + InstanceMap + ( getq Instance name ) ) ) + +(defun NameGetCanonicalInstanceNames ( InstanceMap ) + ( ListApplyFuncToListAndAccumulateResults + ( tableToList ( car InstanceMap ) ) + (lambda + ( InstanceEntry ) + ( car InstanceEntry ) ) + nil ) ) + +(defun NameAddNonFoldableInstanceToInstanceMap ( InstanceMap Instance ) + (let ( + ( InstanceTable ( car InstanceMap ) ) + ( InstanceNameTable ( cadr InstanceMap ) ) + ( InstanceFullNameTable ( caddr InstanceMap ) ) + ( CanonicalInstanceName ( NameCanonicalizeNonFoldableInstanceName + ( getq Instance name ) ) ) ) + ( setarray + InstanceTable + CanonicalInstanceName + ( list Instance ) ) + ( setarray + InstanceNameTable + ( getq Instance name ) + CanonicalInstanceName ) + ( setarray + InstanceFullNameTable + ( getq Instance name ) + CanonicalInstanceName ) ) ) + +(defun NameCanonicalizeNonFoldableInstanceName ( Name ) + (let ( + ( Result "" ) ) + ( for + StrIndex + ;avoid leading | + (if ( equal ( substring Name 1 1 ) "|" ) + 2 + 1 ) + ( strlen Name ) + (let ( + ( CurrChar ( substring Name StrIndex 1 ) ) ) + ( setq + Result + ( strcat + Result + (cond + ( + ;convert ( to [ + ( equal CurrChar "(" ) + "[" ) + ( + ( equal CurrChar ")" ) + "]" ) + ( + t + CurrChar ) ) ) ) ) ) + Result ) ) + +(defun NameCanonicalizeFoldableInstanceName ( Name ) + + (let ( + ( Components ( reverse ( parseString Name "." ) ) ) ) + (let ( + ( RootName ( buildString ( reverse (if ( rexMatchp "^[0-9]*$" ( car Components ) ) + ( cdr Components ) + Components ) ) + "." ) ) ) + ( NameCanonicalizeNonFoldableInstanceName RootName ) ) ) ) + + + + + + + +(defun NameTablifyInstances ( CellView ) + (let ( + ( TargetTable ( makeTable `instances nil ) ) ) + ( foreach Instance ( getq CellView instances ) + (let ( + ( CanonName ( NameCanonicalizeInstanceName ( getq Instance name ) ) ) ) + ( setarray TargetTable + CanonName + ( cons Instance ( arrayref TargetTable CanonName ) ) ) ) ) + TargetTable ) ) + + +(defun NameGetLayoutInstancesFromNetListInstanceName ( InstanceMapping InstanceName ) + ( NameGetInstancesFromInstanceName ( car InstanceMapping ) InstanceName ) ) + +(defun NameGetNetListInstancesFromLayoutInstanceName ( InstanceMapping InstanceName ) + ( NameGetInstancesFromInstanceName ( cadr InstanceMapping ) InstanceName ) ) + +(defun NameGetInstancesFromInstanceName ( CanonTable InstanceName ) + ( arrayref CanonTable ( NameCanonicalizeInstanceName InstanceName ) ) ) + +(defun NameCreateCellInstanceMapping ( ConnectivityCellView LayoutCellView ) + (let ( + ( LayoutTable ( NameTablifyInstances LayoutCellView ) ) + ( ConnectivityTable ( NameTablifyInstances ConnectivityCellView ) ) ) + ( list LayoutTable ConnectivityTable ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il new file mode 100644 index 0000000000..a11f5f1024 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il @@ -0,0 +1,12 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ + +(defun PackageGetPackageRoot () + "$packageroot$" ) + +(defun PackageGetBinRoot () + getShellEnvVar("VIRTUOSO_BIN") ) + +(defun PackageGetBinRootForArch ( ArchString ) + ( sprintf nil "%s/%s/bin" ( PackageGetPackageRoot ) ArchString ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il.inst b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il.inst new file mode 100755 index 0000000000..88ffbbbd60 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/package/package.il.inst @@ -0,0 +1,26 @@ +function exit_func() { + if [ -n "$package_il_temp" ] ; then + rm -f "$package_il_temp" + fi +} + +trap exit_func EXIT + + +sedcmd=`which sed` +chmodcmd=`which chmod` + +package_root=$1 +install_share_bin=$2 +install_share_data=$3 +install_arch_bin=$4 +install_arch_data=$5 + +package_dir="$package_root/share/skill/util/package" +package_il="$package_dir/package.il" +package_il_temp=`mktemp /tmp/package.inst.XXXXXX` + +$sedcmd -e "s=\\\$packageroot\\\$=$package_root=" -e "s=\\\$archpath\\\$=$install_arch_bin=" "$package_il" >$package_il_temp +$chmodcmd "--reference=$package_il" "$package_il_temp" +rm "$package_il" +cp "$package_il_temp" "$package_il" diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/pcell/pcell.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/pcell/pcell.il new file mode 100644 index 0000000000..c74314d57a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/pcell/pcell.il @@ -0,0 +1,90 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun PCellGetParameters ( PCell ) + ( PropGetParameters + ( getq ( getq PCell master ) superMaster ) ) ) + +(defun PCellGetParameterType ( PCellSuperMaster ParameterName ) + (let ( + ( Params ( PropGetParameters PCellSuperMaster ) ) ) + (let ( + ( TheParam ( car + ( setof + Param + Params + ( equal ( getq Param name ) ParameterName ) ) ) ) ) + (when TheParam + ( getq TheParam valueType ) ) ) ) ) + +(defun PCellGetSuperMasterForInstance ( Instance ) + ( getq ( getq Instance master ) superMaster ) ) + + +(defun PCellGetParamTypeForSchematicInstance ( Instance ParamName ) + (let ( + ( LibName ( getq Instance libName ) ) + ( CellName ( getq Instance cellName ) ) + ( LayoutViewName "layout" ) ) + (let ( + ( LayoutViewDDObj ( ddGetObj LibName CellName LayoutViewName ) ) ) + (when ( and + LayoutViewDDObj + ( getq LayoutViewDDObj files ) ) + (let ( + ( LayoutCellView ( dbOpenCellViewByType + LibName + CellName + LayoutViewName + nil + "r" ) ) ) + (when LayoutCellView + ( PCellGetParameterType LayoutCellView ParamName ) ) ) ) ) ) ) + +(defun PCellGetParameterList ( PCell ) + ( PropGetPropertyListFromListOfProps + ( list ( PropGetParameters + ( PCellGetSuperMasterForInstance PCell ) ) + ( getq PCell prop ) ) ) ) + +(defun PCellSetParameterList ( PCell ParameterList ) + ( foreach + Parameter + ParameterList + ( dbReplaceProp + Instance + ( car Parameter ) + ( cadr Parameter ) + ( caddr Parameter ) ) ) ) + +(defun PCellGetParameterValue ( PCell ParameterName ) + ( PropGetPropValueFromListOfProps + ( list ( getq PCell prop ) + ( PropGetParameters + ( PCellGetSuperMasterForInstance PCell ) ) ) + ParameterName ) ) + + +;we have code organized by cell +;we want certain gate/model pairs to be made +;we can either +;1) get code location from gate/model pair OR +;2) get gate/model pair from code location + +(defun PCellCreateProcessLibs ( PDKRoot + Technology + DFIIDir + DirectivesFile ) + (let ( + ( Directives ( CellInfoGetTableForFileName + DirectivesFile ) ) ) + ( load ( sprintf + nil + "%s/share/Fulcrum/skill/pcell.il" + PDKRoot ) ) + ( PDKCreateProcessLibs + ( PackageGetBinRoot ) + PDKRoot Technology DFIIDir Directives ) + ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/profile.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/profile.il new file mode 100644 index 0000000000..d81619e67a --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/profile.il @@ -0,0 +1,29 @@ +; Profiling macro, usage: (Profile "file.prof" (Function ...)) +; Fail immediately if a SKILL developement license cannot be acquired +(defmacro Profile (file @key (licenseName "skillDev") + (licenseType "NOWAIT") + (profileField ''time) + @rest body) + `(if (LicenseGetLicense ,licenseName (getLicVersion) 0 + ?LicenseType ,licenseType + ?Verbose nil) + (let (ret errSet) + (profileReset) + (profile ,profileField) + ret=(errset ,@body) ; trap error so license can be released + errSet=errset.errset + (profileSummary ?children t ?file ,file) + (LicenseReturnLicense ,licenseName) + + ; return the value from evaluating body, rethrow error if necessary + (if ret + (car ret) + (let ((msg (car (nth 4 errSet)))) + (if msg + (error (substring msg 9)) ; strip off initial "*Error* " + (error "%L" errSet))) + ) + ) + (error "Cannot acquire %s license; try again later" ,licenseName) + ) +) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/prop/prop.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/prop/prop.il new file mode 100644 index 0000000000..68c5577e3d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/prop/prop.il @@ -0,0 +1,57 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun PropGetPropForPropName ( Props PropName ) + ( car ( exists Prop Props + ( equal ( getq Prop name ) PropName ) ) ) ) + +(defun PropGetPropValueForPropName ( Props PropName ) + ( getq ( PropGetPropForPropName Props PropName ) value ) ) + +(defun PropGetParameters ( DBId ) + ( PropGetPropValueForPropName + ( getq DBId prop ) + "parameters" ) ) + +(defun PropGetPropValueFromListOfProps ( PropsList ParameterName ) + (let ( + ( Value nil ) ) + (while ( and PropsList + ( null Value ) ) + ( setq Value + ( PropGetPropValueForPropName + ( car PropsList ) + ParameterName ) ) + ( setq PropsList ( cdr PropsList ) ) ) + Value ) ) + +(defun PropGetPropertyListFromProps ( Props ) + ( PropGetPropertyListFromListOfProps + ( list Props ) ) ) + +(defun PropGetPropertyListFromListOfProps ( PropsList ) + (let ( + ( PropTable ( makeTable `foo nil ) ) ) + ( foreach Props PropsList + ( foreach Prop Props + ( setarray PropTable + ( list + ( getq Prop name ) + ( getq Prop valueType ) ) + ( getq Prop value ) ) ) ) + ( mapcar + (lambda ( x ) + ( list ( car ( car x ) ) + ( cadr ( car x ) ) + ( cadr x ) ) ) + ( tableToList PropTable ) ) ) ) + +(defun PropGetPropTripleFromPropertyList ( PropertyList PropertyName ) + ( car ( last ( setof Triple PropertyList + ( equal ( car Triple ) PropertyName ) ) ) ) ) + +(defun PropGetPropValueFromPropertyList ( PropertyList PropertyName ) + ( nth 2 + ( PropGetPropTripleFromPropertyList PropertyList PropertyName ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/recurse.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/recurse.il new file mode 100644 index 0000000000..91612a694f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/recurse.il @@ -0,0 +1,27 @@ +; Recursively find subcells of a cell that match a filter and apply an +; action. Returns the list of cells that passed the filter. +(defun FindSubcells (@key (CV (geGetEditCellView)) + (visited (makeTable "visited" nil)) + (filter nil) ; (filter CV) function + (action nil) ; (action CV) function + ) + (let (result) + (when !visited[CV] + visited[CV]=t + (foreach inst CV->instances + result = (append result (FindSubcells ?filter filter ?action action + ?CV inst->master ?visited visited)) + ) + (when !filter || (apply filter (list CV)) + (printf "%s\n" CV->cellName) + (when action (apply action (list CV))) + result = (cons CV result) + ) + ) + result + ) + ) + +; Filter and action functions for use with FindSubcells. +leafCellFilter = (lambda (CV) (dbGetPropByName CV "LeafCell")->value=="TRUE") +editCellAction = (lambda (CV) (cdsp4edit ?CV CV)) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/stack/stack.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/stack/stack.il new file mode 100644 index 0000000000..87ac0a234e --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/stack/stack.il @@ -0,0 +1,16 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun StackCreateNew ( Stack ) + ( putprop Stack ( list ) `value ) ) + +(defun StackPush ( Stack Element ) + ( putprop Stack ( cons Element ( get Stack `value ) ) `value ) ) + +(defun StackPop ( Stack ) + (let ( + ( Element ( car ( symeval Stack ) ) ) ) + ( putprop Stack ( cdr ( get Stack `value ) ) `value ) + Element ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/escapestring.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/escapestring.il new file mode 100644 index 0000000000..b4d847c769 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/escapestring.il @@ -0,0 +1,116 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + + +(defun EscapeStringIsAlpha ( CharStr ) + ( or + ( and ( geqp ( strcmp CharStr "a" ) 0 ) ( leqp ( strcmp CharStr "z" ) 0 ) ) + ( and ( geqp ( strcmp CharStr "A" ) 0 ) ( leqp ( strcmp CharStr "Z" ) 0 ) ) ) ) + +(defun EscapeStringIsDigit ( CharStr ) + ( and ( geqp ( strcmp CurrChar "0" ) 0 ) ( leqp ( strcmp CurrChar "9" ) 0 ) ) ) + +(defun EscapeStringIsAlphaNum ( CharStr ) + ( or ( EscapeStringIsAlpha CharStr ) + ( EscapeStringIsDigit CharStr ) ) ) + +(defun EscapeStringEscapeChar ( CharStr ) + (cond + ( + ( EscapeStringIsAlphaNum CharStr ) + CharStr ) + ( + ( equal "." CharStr ) + "_D_" ) + ( + ( equal "," CharStr ) + "_C_" ) + ( + ( equal "[" CharStr ) + "_l_" ) + ( + ( equal "]" CharStr ) + "_r_" ) + ( + ( equal "(" CharStr ) + "_L_" ) + ( + ( equal ")" CharStr ) + "_R_" ) + ( + ( equal "-" CharStr ) + "_M_" ) + ( + ( equal "_" CharStr ) + "_U_" ) + ( + t + ( sprintf nil "_%02x_" ( charToInt ( stringToSymbol CharStr ) ) ) + ) + ) ) + + +(defun EscapeStringImpl ( String EscapeStringEscapeCharFunc ) + (let ( + ( Len ( strlen String ) ) + ( CurrIndex 1 ) + ( Result "" ) ) + + (while ( leqp CurrIndex Len ) + (let ( + ( CurrChar ( substring String CurrIndex 1 ) ) ) + + ( setq Result ( strcat Result ( apply EscapeStringEscapeCharFunc ( list CurrChar ) ) ) ) + ( setq CurrIndex ( plus CurrIndex 1 ) ) ) ) + Result ) ) + + + +(defun EscapeStringEscapeRex ( String ) + ( EscapeStringImpl String + ( lambda ( Char ) + (cond ( + ( equal Char "[" ) + "\\[" + ) + ( + ( equal Char "]" ) + "\\]" + ) + ( + ( equal Char "*" ) + "\\*" + ) + ( + ( equal Char "+" ) + "\\+" + ) + ( + ( equal Char "." ) + "\\." + ) + ( + Char + ) ) ) ) ) + + +(defun EscapeString ( String ) + ( EscapeStringImpl String `EscapeStringEscapeChar ) ) + + +(defun EscapeQuotes ( String ) + ( EscapeStringImpl + String + (lambda ( Char ) + (cond ( + ( equal Char "\\" ) + "\\\\" + ) + ( + ( equal Char "\"" ) + "\\\"" + ) + ( + Char ) ) ) ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/strutil.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/strutil.il new file mode 100644 index 0000000000..381e769473 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/string/strutil.il @@ -0,0 +1,234 @@ +; Copyright 2002 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +ReadLineCache = ( makeTable `readline nil ) +(defun StringUtilReadLine ( CID TimeOut ) + (let ( + Ret + Accum + Bit ) + + (while (let () + ( setq Bit ( ipcReadProcess CID TimeOut ) ) + (when ( not ( equal "\n" Bit ) ) + ( setq Accum Bit ) ) + ( equal Bit "\n" ) + ) t ) + ReadLineCache[CID] = ( append + ReadLineCache[CID] + (cond ( + ( stringp Accum ) + ( parseString Accum "\n" ) ) ) + ) + Ret = ( car ReadLineCache[CID] ) + ReadLineCache[CID] = ( cdr ReadLineCache[CID] ) + Ret + ) ) + + +;Remove an optional new line character from the end of a string. +(defun StringUtilChompNewline ( String ) + (let ( + ( StringLen ( strlen String ) ) ) + (if ( equal StringLen 0 ) + "" + (let ( + ( LastChar ( substring String StringLen ) ) ) + (if ( equal LastChar "\n" ) + (when ( greaterp StringLen 1 ) + ( substring String 1 ( difference StringLen 1 ) ) ) + String ) ) ) ) ) + +(defun StringUtilStripWhiteSpace ( String ) + (let ( + ( Result "" ) + ( LeftIndex 1 ) + ( GotNonSpace nil ) + ( Len ( strlen String ) ) ) + (while ( not + ( or + GotNonSpace + ( lessp Len LeftIndex ) ) ) + (let ( + ( CurrChar ( substring String LeftIndex 1 ) ) ) + (if ( StringUtilIsWhiteSpace CurrChar ) + ( setq LeftIndex ( plus LeftIndex 1 ) ) + ( setq GotNonSpace t ) ) ) ) + (let ( + ( RightIndex Len ) ) + ( setq GotNonSpace nil ) + (while ( not + ( or + GotNonSpace + ( lessp RightIndex LeftIndex ) ) ) + (let ( + ( CurrChar ( substring String RightIndex 1 ) ) ) + (if ( StringUtilIsWhiteSpace CurrChar ) + ( setq RightIndex ( difference RightIndex 1 ) ) + ( setq GotNonSpace t ) ) ) ) + (if ( greaterp + ( difference + ( plus RightIndex 1 ) + LeftIndex ) + 0 ) + ( substring + String + LeftIndex + ( difference + ( plus RightIndex 1 ) + LeftIndex ) ) + "" ) ) ) ) + + + +(defun StringUtilIsWhiteSpace ( CharStr ) + ( or + ( equal + CharStr + " " ) + ( equal + CharStr + "\n" ) + ( equal + CharStr + "\t" ) ) ) + + +(defun StringUtilIsCharDigit ( CharStr ) + ( and + ( geqp ( strcmp CharStr "0" ) 0 ) + ( leqp ( strcmp CharStr "9" ) 0 ) ) ) + +(defun StringUtilIsCharLetter ( CharStr ) + ( or + ( and + ( geqp ( strcmp CharStr "A" ) 0 ) + ( leqp ( strcmp CharStr "Z" ) 0 ) ) + ( and + ( geqp ( strcmp CharStr "a" ) 0 ) + ( leqp ( strcmp CharStr "z" ) 0 ) ) ) ) + +(defun StringUtilGetDigitValue ( CharStr ) + (cond + ( ( equal CharStr "0" ) 0 ) + ( ( equal CharStr "1" ) 1 ) + ( ( equal CharStr "2" ) 2 ) + ( ( equal CharStr "3" ) 3 ) + ( ( equal CharStr "4" ) 4 ) + ( ( equal CharStr "5" ) 5 ) + ( ( equal CharStr "6" ) 6 ) + ( ( equal CharStr "7" ) 7 ) + ( ( equal CharStr "8" ) 8 ) + ( ( equal CharStr "9" ) 9 ) + ( t nil ) ) ) + + +(defun StringUtilInnerParseNumber ( String ) + (let ( + ( CurrValue 0 ) + ( CurrOffset 1 ) + ( CurrDigitMult 1 ) + ( GotNonDigit nil ) + ( Sign 1 ) + ( FirstChar ( substring String 1 1 ) ) + ( Len ( strlen String ) ) ) + + (when ( and + FirstChar + ( equal FirstChar "-" ) ) + ( setq Sign -1 ) + ( setq CurrOffset ( plus CurrOffset 1 ) ) ) + + (when ( and + FirstChar + ( equal FirstChar "+" ) ) + ( setq Sign 1 ) + ( setq CurrOffset ( plus CurrOffset 1 ) ) ) + + (while ( and + ( not ( lessp Len CurrOffset ) ) + ( not GotNonDigit ) + CurrValue ) + (let ( + ( CurrChar ( substring String CurrOffset 1 ) ) ) + ( setq CurrOffset ( plus CurrOffset 1 ) ) + (if ( StringUtilIsCharDigit CurrChar ) + (let () + ( setq + CurrValue + ( plus + (if ( equal CurrDigitMult 1 ) + ( times + CurrValue + 10 ) + CurrValue ) + ( times + ( float CurrDigitMult ) + ( float ( StringUtilGetDigitValue CurrChar ) ) ) ) ) + (unless ( equal CurrDigitMult 1 ) + ( setq CurrDigitMult ( quotient ( float CurrDigitMult ) ( float 10 ) ) ) ) ) + (if ( equal CurrChar "." ) + ( setq CurrDigitMult ( quotient ( float CurrDigitMult ) ( float 10 ) ) ) + ( setq GotNonDigit t ) ) ) ) ) + ( list + ( times CurrValue Sign ) + (if ( greaterp CurrOffset 1 ) + (if ( and + ( not GotNonDigit ) + ( lessp Len CurrOffset ) ) + "" + ( substring + String + ( difference CurrOffset 1 ) + Len ) ) + String ) ) ) ) + +(defun StringUtilParseNumber ( String ) + ( car ( StringUtilInnerParseNumber ( StringUtilStripWhiteSpace String ) ) ) ) + +(defun StringUtilParseLengthString ( String ) + (let ( + ( ParseResult ( StringUtilInnerParseNumber String ) ) ) + (let ( + ( Num ( car ParseResult ) ) + ( Rest ( StringUtilStripWhiteSpace ( cadr ParseResult ) ) ) ) + (let ( + ( FirstCharOfRest ( substring Rest 1 1 ) ) ) + (cond + ( + ( or ( equal FirstCharOfRest "n" ) ( equal FirstCharOfRest "m" ) ) + ( quotient ( float Num ) ( float 1000000000 ) ) ) + ( + ( equal FirstCharOfRest "u" ) + ( quotient ( float Num ) ( float 1000000 ) ) ) + ( + ( or + ( equal FirstCharOfRest "e" ) + ( equal FirstCharOfRest "E" ) ) + (let ( + ( Exponent ( StringUtilParseNumber ( substring Rest 2 ( strlen Rest ) ) ) ) ) + ( times + Num + ( exp + ( times Exponent ( log 10.0 ) ) ) ) ) ) + ( + t + Num ) ) ) ) ) ) + +(defun StringUtilGetFirstChar ( String ) + ( substring String 1 1 ) ) + +(defun StringUtilGetAllButFirstChar ( String ) + ( substring String 2 ( difference ( strlen String ) 1 ) ) ) + + +(defun StringUtilConvertStringListToSpaceSeperatedString ( StringList ) + ( buildString StringList " " ) ) + +(defun StringUtilPrefix ( Prefix StringList ) + ( strcat Prefix ( buildString StringList ( strcat " " Prefix ) ) ) ) + +(defun StringStartsWith ( String Prefix ) + ( strncmp String Prefix ( strlen Prefix ) ) == 0 ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/table/table.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/table/table.il new file mode 100644 index 0000000000..2b08353052 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/table/table.il @@ -0,0 +1,40 @@ +; Copyright 2003 Fulcrum Microsy\stems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun TableCopy ( Table ) + (let ( + ( NewTable ( makeTable `bla ( arrayref Table `unbound ) ) ) ) + ( foreach Key Table + ( setarray NewTable Key ( arrayref Table Key ) ) ) + NewTable ) ) + +(defun TableCreateFromPairs ( Pairs ) + (let ( + ( Table ( makeTable `foo nil ) ) ) + ( foreach Pair Pairs + ( setarray Table ( car Pair ) ( cadr Pair ) ) ) + Table ) ) + +(defun TableGetKeyList ( Table ) + ( mapcar `car ( tableToList Table ) ) ) + +(defun TableGetValueList ( Table ) + ( mapcar `cadr ( tableToList Table ) ) ) + +(defun TableGetEntryList ( Table ) + ( tableToList Table ) ) + +;Gets all elements x in SourceList such that there is an element y in CorrespondingList such that +; ( SourceKeyFunc x ) = ( CorrespondingKeyFunc y ) +(defun TableGetCorrespondingList ( SourceList CorrespondingList SourceKeyFunc CorrespondingKeyFunc ) + (let ( + ( SourceTable ( makeTable `src nil ) ) ) + ( foreach Element SourceList + ( setarray SourceTable ( apply SourceKeyFunc ( list Element ) ) Element ) ) + ( mapcar + ( lambda ( CorrespondingElement ) + ( arrayref SourceTable ( apply CorrespondingKeyFunc ( list CorrespondingElement ) ) ) ) + CorrespondingList ) ) ) + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/version.il b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/version.il new file mode 100644 index 0000000000..0c48f8ecc1 --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/skill/util/version.il @@ -0,0 +1,7 @@ +; Copyright 2003 Fulcrum Microsystems. All rights reserved. +; $Id$ +; $DateTime$ +; $Author$ + +(defun VersionGetMajorVersion () + ( substring ( nth 2 ( parseString ( getVersion ) " " ) ) 1 1 ) ) diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/updatenetlist.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/updatenetlist.package new file mode 100644 index 0000000000..d042d9d23f --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/updatenetlist.package @@ -0,0 +1,63 @@ +2 2 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +### This is used by ubersize to keep floorplan dfII data consistent with +### cast hierarcy. It also estimated floorplan bounding boxes/etc based +### on schematic statistics (e.g. transistor width, density_factor) +### It is also used synctonetlist/genfromsource to keep gate/stack instances +### up to date + +# need to create a cadence working directory to run layoutPlus +include script/sh/setup/cds_wd.package script/sh/setup ^share->share/script/sh/setup + +# SH library +include ../../../../infrastructure/sh-lib/sh-lib.package.inc ../../../../infrastructure/sh-lib +# SH wrapper scripts +$arch/bin/updatenetlist.sh script/sh/cell-automation/multi_cell_commands/updatenetlist.sh 775 +$arch/bin/cast2skill.sh ../../../java/src/com/avlsi/tools/cast2skill/cast2skill.sh 775 + +# JAVA +java com.avlsi.tools.cast2skill.Cast2Skill + +# don't use cdsp4 any more +#include cdsp4.package . + +### SKILL +share/skill/layout/cell/cellinfo.il skill/layout/cell/cellinfo.il 664 p +share/skill/layout/geometry/bbox.il skill/layout/geometry/bbox.il 664 p +share/skill/layout/geometry/fig.il skill/layout/geometry/fig.il 664 p +share/skill/layout/geometry/line.il skill/layout/geometry/line.il 664 p +share/skill/layout/geometry/polygon.il skill/layout/geometry/polygon.il 664 p +share/skill/layout/geometry/rect.il skill/layout/geometry/rect.il 664 p +share/skill/layout/transform/transform.il skill/layout/transform/transform.il 664 p +share/skill/layout/cell/constraints.il skill/layout/cell/constraints.il 664 p +share/skill/layout/pins/autopin.il skill/layout/pins/autopin.il 664 p +share/skill/layout/pins/channels/e1ofn.il skill/layout/pins/channels/e1ofn.il 664 p +share/skill/layout/pins/pinplace.il skill/layout/pins/pinplace.il 664 p +share/skill/layout/pins/pinutil.il skill/layout/pins/pinutil.il 664 p +share/skill/schematic/inlineconnections.il skill/schematic/inlineconnections.il 664 p +share/skill/schematic/netlisttable.il skill/schematic/netlisttable.il 664 p +share/skill/schematic/updatenetlist.il skill/schematic/updatenetlist.il 664 p +share/skill/schematic/syncnetlist.il skill/schematic/syncnetlist.il 664 p +share/skill/util/cache/cache.il skill/util/cache/cache.il 664 p +share/skill/util/file/libcellview.il skill/util/file/libcellview.il 664 p +share/skill/util/file/path.il skill/util/file/path.il 664 p +share/skill/util/file/readfile.il skill/util/file/readfile.il 664 p +share/skill/util/list/list.il skill/util/list/list.il 664 p +share/skill/util/list/partition.il skill/util/list/partition.il 664 p +share/skill/util/math/math.il skill/util/math/math.il 664 p +share/skill/util/name.il skill/util/name.il 664 p +share/skill/util/pcell/pcell.il skill/util/pcell/pcell.il 664 p +share/skill/util/prop/prop.il skill/util/prop/prop.il 664 p +share/skill/util/string/escapestring.il skill/util/string/escapestring.il 664 p +share/skill/util/string/strutil.il skill/util/string/strutil.il 664 p + +### MISC +share/script/sh/cell-automation/lib_commands/mkcdslib script/sh/cell-automation/lib_commands/mkcdslib 775 p +share/script/sh/util/parsecellname script/sh/util/parsecellname 664 p +share/data/change_list_template.txt script/sh/p4/change_list_template.txt 664 p +install/share/bin/gen_autoload skill/gen_autoload 775 p + diff --git a/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/virtuoso-integration.package b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/virtuoso-integration.package new file mode 100644 index 0000000000..f8e64cde0d --- /dev/null +++ b/async-toolkit/jtools/cad/external-tools-integration/cadence/virtuoso/virtuoso-integration.package @@ -0,0 +1,410 @@ +2 2 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# This package is for all the Physical Design Tools +# It implements the flow. + +#

    Documentation

    +doc/updatenetlist/index.html doc/updatenetlist/index.html 664 p +doc/updatenetlist/calls.dot doc/updatenetlist/calls.dot 664 p + +# The Fulcrum ui menu package. +# extra dir added to match existing structure (AAG) +# the 'build' directory replaces the version number which package-inst.pl would put in +include skill/ui/ui.package skill/ui ^share->share/skill/ui/ui/build/share + +# ve - used by everything that calls assura - Fulcrum menu / gen_leaf_cells +include script/perl/ve/ve.package script/perl/ve ^share->share/script/perl/ve + +# cds_wd - For creating working directories. For users and for most top level scripts +include script/sh/setup/cds_wd.package script/sh/setup ^share->share/script/sh/setup + +# +include gdsIIWrite.package . + +# +include lefdef.package . + +# +include nano.package . + +# +include fulcrum_cds_setup.inc . + +# cdsp4 - cadence perforce integration used by fulcrum menu/from command line +include cdsp4.package . + +# updatenetlist - used by synctonetlist/genfromsource step of gen_leaf_cells +include updatenetlist.package . + +# subtype splitting +include dfII_split_subtypes.package . + +# jflat +include ../../../java/src/com/avlsi/tools/jflat/jflat.package ../../../java/src/com/avlsi/tools/jflat + +# jauto +include ../../../java/src/com/avlsi/tools/jauto/jauto.package ../../../java/src/com/avlsi/tools/jauto + +# +include ../../../java/src/com/avlsi/tools/prs2verilog/prs2verilog.package ../../../java/src/com/avlsi/tools/prs2verilog + +# proteus_setup +# include ../../../proteus/setup/proteus_setup.inc ../../../proteus/setup + +# Tools (sh java wrappers) +$arch/bin/generate_ip_data.sh ../../../java/src/com/avlsi/tools/ipgen/generate_ip_data.sh 775 +$arch/bin/cdl2cast.sh ../../../java/src/com/avlsi/tools/cdl2cast/cdl2cast.sh 775 +$arch/bin/netlistDistance.sh ../../../java/src/com/avlsi/tools/jauto/netlistDistance.sh 775 + +# rename - rename cast cells/instances/models/etc from +# cast<->cadence<->gds2 names +# used in +include ../../../java/src/com/avlsi/file/cdl/util/rename/cdlrenamer.package ../../../java/src/com/avlsi/file/cdl/util/rename + +# Tool (lib tools) +$arch/bin/fakelib.sh script/sh/setup/fakelib.sh 775 p +# for importing gds2/cdl for IP cells +$arch/bin/importIP script/perl/util/importIP.pl 775 p +$arch/bin/fixportdirection script/perl/util/fixportdirection 775 p +# for importing gds2/cdl for std cell libraries +$arch/bin/importPR.sh script/sh/util/importPR.sh 775 p +$arch/bin/cdl2cast2 script/perl/util/cdl2cast2 775 p +$arch/bin/fixcdl script/perl/util/fixcdl.pl 775 p +$arch/bin/fixgds script/perl/util/fixgds.pl 775 p +$arch/bin/importSR.pl script/perl/util/importSR.pl 775 p +$arch/bin/gen_sram_scan_wrap.pl script/perl/util/gen_sram_scan_wrap.pl 775 p +$arch/bin/compilemem.pl script/perl/util/compilemem.pl 775 p +$arch/bin/compile_lib ../../../scripts/compile_lib.sh 775 p +$arch/bin/lmwait script/sh/setup/lmwait.pl 775 p +$arch/lib/rescuedb.so ../../../scripts/rescuedb.so 664 + +# for exporting gds2/cdl +$arch/bin/genIP.sh script/sh/cell-automation/one_cell_commands/genIP.sh 775 p + +# +$arch/bin/gen_leaf_cells.sh script/sh/cell-automation/multi_cell_commands/gen_leaf_cells.sh 775 p +share/script/sh/cell-automation/templates/leaf_cell.il.template script/sh/cell-automation/templates/leaf_cell.il.template 664 p +$arch/bin/dfIIflat2tree.sh script/sh/cell-automation/multi_cell_commands/dfIIflat2tree.sh 775 p + +# other scripts that use layoutPlus and SKILL +$arch/bin/gen_mid_cells.sh script/sh/cell-automation/multi_cell_commands/gen_mid_cells.sh 775 p +$arch/bin/gen_instantiator_views.sh script/sh/cell-automation/multi_cell_commands/gen_instantiator_views.sh 775 p +$arch/bin/gen_abstract_views.sh script/sh/cell-automation/multi_cell_commands/gen_abstract_views.sh 775 p +$arch/bin/density.sh script/sh/cell-automation/multi_cell_commands/density.sh 775 p + +# - qrsh batch wrapper - used by +$arch/bin/qb.pl ../../../lve/script/perl/qsub/qb 775 p +$arch/bin/qbwrapper ../../../lve/script/perl/qsub/qbwrapper 775 p + +# Used in /Fulcrum/Verify/Signoff +$arch/bin/signoff.pl script/perl/signoff.pl 775 p + +# misc tools - not referenced by any other tools +$arch/bin/gen_branch_spec.sh script/sh/p4/gen_branch_spec.sh 775 p +$arch/bin/findclosestwithlayout.sh script/sh/util/findclosestwithlayout.sh 775 p +$arch/bin/mosaicify.pl script/perl/mosaicify.pl 775 p +$arch/bin/plotdensity.pl script/perl/plotdensity.pl 775 p +$arch/bin/checkpgvia.pl script/perl/checkpgvia.pl 775 p +$arch/bin/dangling.pl script/perl/dangling.pl 775 p + +# routing - needed for UI/gen_leaf_cells +$arch/bin/runccar.sh skill/layout/leaf/router/runccar.sh 775 p +$arch/bin/importccar.sh skill/layout/leaf/router/importccar.sh 775 p + +# nograph vnc wrapper +$arch/bin/nograph.sh script/sh/vnc/nograph.sh 775 p +share/script/sh/vnc/getvncserver.sh script/sh/vnc/getvncserver.sh 775 p +share/script/sh/vnc/.fvwm2/Main-8-bit script/sh/vnc/.fvwm2/Main-8-bit 664 p +# sh scripts to build dfII libraries +share/script/sh/cell-automation/lib_commands/getlibs script/sh/cell-automation/lib_commands/getlibs 775 p +share/script/sh/cell-automation/lib_commands/mkcdslibs script/sh/cell-automation/lib_commands/mkcdslibs 775 p +share/script/sh/cell-automation/lib_commands/mkcdslib script/sh/cell-automation/lib_commands/mkcdslib 775 p + +# sh library +share/script/sh/util/parsecellname script/sh/util/parsecellname 664 p +share/script/sh/sh-lib/file/filecheck.sh ../../../../infrastructure/sh-lib/file/filecheck.sh 775 p +share/script/sh/sh-lib/file/conon.sh ../../../../infrastructure/sh-lib/file/conon.sh 775 p +share/script/sh/sh-lib/file/config.sh ../../../../infrastructure/sh-lib/file/config.sh 775 p +share/script/sh/sh-lib/script/generate_script_with_libs.sh ../../../../infrastructure/sh-lib/script/generate_script_with_libs.sh 775 p + +# JAVA classes +java com.avlsi.tools.ipgen.GenerateIPData com.avlsi.tools.cdl2cast.CDL2Cast +java com.avlsi.tools.jauto.NetlistDistance + +#

    SKILL

    +# This is all the skill we use. + +# utility +share/skill/ui/util/license.il skill/ui/util/license.il 664 p +share/skill/util/db.il skill/util/db.il 664 p +share/skill/util/defaults.il skill/util/defaults.il 664 p +share/skill/util/counter.il skill/util/counter.il 664 p +share/skill/util/math/math.il skill/util/math/math.il 664 p +share/skill/util/expression/expression.il skill/util/expression/expression.il 664 p +share/skill/util/lib.il skill/util/lib.il 664 p +share/skill/util/makemidlayouttag.il skill/util/makemidlayouttag.il 664 p +share/skill/util/makelayouttag.il skill/util/makelayouttag.il 664 p +share/skill/util/name.il skill/util/name.il 664 p +share/skill/util/version.il skill/util/version.il 664 p +share/skill/util/cache/cache.il skill/util/cache/cache.il 664 p +share/skill/util/package/package.il skill/util/package/package.il 664 p +share/skill/util/pcell/pcell.il skill/util/pcell/pcell.il 664 p +share/skill/util/prop/prop.il skill/util/prop/prop.il 664 p +share/skill/util/file/readfile.il skill/util/file/readfile.il 664 p +share/skill/util/file/tempfile.il skill/util/file/tempfile.il 664 p +share/skill/util/file/path.il skill/util/file/path.il 664 p +share/skill/util/file/fileutil.il skill/util/file/fileutil.il 664 p +share/skill/util/file/libcellview.il skill/util/file/libcellview.il 664 p +share/skill/util/file/configfile.il skill/util/file/configfile.il 664 p +share/skill/util/list/list.il skill/util/list/list.il 664 p +share/skill/util/table/table.il skill/util/table/table.il 664 p +share/skill/util/string/strutil.il skill/util/string/strutil.il 664 p +share/skill/util/string/escapestring.il skill/util/string/escapestring.il 664 p +share/skill/util/binarysearch/binarysearch.il skill/util/binarysearch/binarysearch.il 664 p +share/skill/util/binarysearch/search.il skill/util/binarysearch/search.il 664 p +share/skill/util/cellview.il skill/util/cellview.il 664 p +share/skill/util/profile.il skill/util/profile.il 664 p +share/skill/util/recurse.il skill/util/recurse.il 664 p + +# geometry +share/skill/layout/geometry/segmenttree.il skill/layout/geometry/segmenttree.il 664 p +share/skill/layout/geometry/line.il skill/layout/geometry/line.il 664 p +share/skill/layout/geometry/range.il skill/layout/geometry/range.il 664 p +share/skill/layout/geometry/polygon.il skill/layout/geometry/polygon.il 664 p +share/skill/layout/geometry/corner.il skill/layout/geometry/corner.il 664 p +share/skill/layout/geometry/point.il skill/layout/geometry/point.il 664 p +share/skill/layout/geometry/rect.il skill/layout/geometry/rect.il 664 p +share/skill/layout/geometry/fig.il skill/layout/geometry/fig.il 664 p +share/skill/layout/geometry/path.il skill/layout/geometry/path.il 664 p +share/skill/layout/geometry/bbox.il skill/layout/geometry/bbox.il 664 p +share/skill/layout/geometry/area.il skill/layout/geometry/area.il 664 p + + +# updatenetlist +share/skill/schematic/swapmasters.il skill/schematic/swapmasters.il 664 p +share/skill/schematic/distinst.il skill/schematic/distinst.il 664 p +share/skill/schematic/inlineconnections.il skill/schematic/inlineconnections.il 664 p +share/skill/schematic/netlisttable.il skill/schematic/netlisttable.il 664 p +share/skill/schematic/updatenetlist.il skill/schematic/updatenetlist.il 664 p +share/skill/schematic/update_floorplan.il skill/schematic/update_floorplan.il 664 p + + +# hand layout +share/skill/layout/hand/rectonpitch.il skill/layout/hand/rectonpitch.il 664 p +share/skill/layout/hand/wiring.il skill/layout/hand/wiring.il 664 p +share/skill/layout/hand/length.il skill/layout/hand/length.il 664 p +share/skill/layout/hand/checklength.il skill/layout/hand/checklength.il 664 p + +# ui +share/skill/ui/ui.il skill/ui/ui.il 664 p + +# vlvs +share/skill/layout/vlvs/vlvs.il skill/layout/vlvs/vlvs.il 664 p +share/skill/layout/vlvs/vlvs.state.template skill/layout/vlvs/vlvs.state.template 664 p + +# assura +share/skill/layout/assura/assura.il skill/layout/assura/assura.il 664 p +share/skill/layout/assura/drc.il skill/layout/assura/drc.il 664 p +share/skill/layout/assura/lvs.il skill/layout/assura/lvs.il 664 p +share/skill/layout/assura/area.rul skill/layout/assura/area.rul 664 p + +# misc +share/skill/layout/keepout/keepout.il skill/layout/keepout/keepout.il 664 p +share/skill/layout/keepout/abstract.il skill/layout/keepout/abstract.il 664 p +share/skill/layout/keepout/conductor.il skill/layout/keepout/conductor.il 664 p +share/skill/layout/notches/notches.il skill/layout/notches/notches.il 664 p +share/skill/layout/floorplanning/import/getcellmappings.il skill/layout/floorplanning/import/getcellmappings.il 664 p +share/skill/layout/floorplanning/import/importfloorplan.il skill/layout/floorplanning/import/importfloorplan.il 664 p +share/skill/layout/floorplanning/resolveOverlap.il skill/layout/floorplanning/resolveOverlap.il 664 p +share/skill/layout/floorplanning/initFloorplan.il skill/layout/floorplanning/initFloorplan.il 664 p +share/skill/layout/floorplanning/floorplanTemplating.il skill/layout/floorplanning/floorplanTemplating.il 664 p +share/skill/layout/floorplanning/optimizeXY.il skill/layout/floorplanning/optimizeXY.il 664 p +share/skill/layout/floorplanning/align.il skill/layout/floorplanning/align.il 664 p +share/skill/layout/floorplanning/anchor.il skill/layout/floorplanning/anchor.il 664 p +share/skill/layout/floorplanning/util.il skill/layout/floorplanning/util.il 664 p +share/skill/layout/floorplanning/updatefromlayout.il skill/layout/floorplanning/updatefromlayout.il 664 p +share/skill/layout/gdsII/gdsIIhier.il skill/layout/gdsII/gdsIIhier.il 664 p +share/skill/layout/import/import.il skill/layout/import/import.il 664 p +share/skill/layout/import/fp.il skill/layout/import/fp.il 664 p +share/skill/layout/leaf/well/regionwell.il skill/layout/leaf/well/regionwell.il 664 p +share/skill/layout/leaf/AddBlkCell.il skill/layout/leaf/AddBlkCell.il 664 p +share/skill/layout/leaf/placer/guessplacementregions.il skill/layout/leaf/placer/guessplacementregions.il 664 p +share/skill/layout/leaf/placer/placementregions.il skill/layout/leaf/placer/placementregions.il 664 p +share/skill/layout/leaf/placer/placer.il skill/layout/leaf/placer/placer.il 664 p +share/skill/layout/leaf/placer/runplacer.sh skill/layout/leaf/placer/runplacer.sh 775 p +share/skill/layout/leaf/placer/placer.pl skill/layout/leaf/placer/placer.pl 775 p +share/skill/layout/hierarchy/inline.il skill/layout/hierarchy/inline.il 664 p +share/skill/p4/p4.il skill/p4/p4.il 664 p +share/skill/layout/density/density.il skill/layout/density/density.il 664 p +share/skill/layout/leaf/placer/squish.il skill/layout/leaf/placer/squish.il 664 p +share/skill/layout/leaf/placer/npsearch.il skill/layout/leaf/placer/npsearch.il 664 p +share/skill/layout/leaf/router/router.il skill/layout/leaf/router/router.il 664 p +share/skill/layout/fig/fig.il skill/layout/fig/fig.il 664 p +share/skill/layout/leaf/decompact/decompact.il skill/layout/leaf/decompact/decompact.il 664 p +share/skill/layout/leaf/plugs/plugs.il skill/layout/leaf/plugs/plugs.il 664 p +share/skill/layout/chain/chain.il skill/layout/chain/chain.il 664 p +share/skill/layout/chain/refold.il skill/layout/chain/refold.il 664 p +share/skill/layout/chain/superstack.il skill/layout/chain/superstack.il 664 p +share/skill/layout/chain/superstack_tools.il skill/layout/chain/superstack_tools.il 664 p +share/skill/layout/chain/domino.il skill/layout/chain/domino.il 664 p +share/skill/layout/chain/domain.il skill/layout/chain/domain.il 664 p +share/skill/layout/chain/componentinfo.il skill/layout/chain/componentinfo.il 664 p +share/skill/layout/chain/unstack.il skill/layout/chain/unstack.il 664 p +share/skill/layout/chain/group.il skill/layout/chain/group.il 664 p +share/skill/layout/filler/filler.il skill/layout/filler/filler.il 664 p +share/skill/layout/filler/SpareCellFill.il skill/layout/filler/SpareCellFill.il 664 p +share/skill/layout/leaf/implant/findplugingateinstance.il skill/layout/leaf/implant/findplugingateinstance.il 664 p +share/skill/layout/leaf/implant/drawimplant.il skill/layout/leaf/implant/drawimplant.il 664 p +share/skill/layout/leaf/Implant.il skill/layout/leaf/Implant.il 664 p +share/skill/layout/tech/spacing.il skill/layout/tech/spacing.il 664 p +share/skill/layout/genfromsource/genfromsource.il skill/layout/genfromsource/genfromsource.il 664 p +share/skill/layout/hierarchy/hierarchy.il skill/layout/hierarchy/hierarchy.il 664 p +share/skill/layout/hierarchy/instantiator.il skill/layout/hierarchy/instantiator.il 664 p +share/skill/layout/hierarchy/instance.il skill/layout/hierarchy/instance.il 664 p +share/skill/layout/transform/transform.il skill/layout/transform/transform.il 664 p +share/skill/layout/cell/cellinfo.il skill/layout/cell/cellinfo.il 664 p +share/skill/layout/cell/constraints.il skill/layout/cell/constraints.il 664 p +share/skill/layout/powergrid/powergrid.il skill/layout/powergrid/powergrid.il 664 p +share/skill/layout/hierarchy/inline.il skill/layout/hierarchy/inline.il 664 p +share/skill/layout/leaf/lvsnodes.il skill/layout/leaf/lvsnodes.il 664 p +share/skill/layout/leaf/LayoutGridPoly.il skill/layout/leaf/LayoutGridPoly.il 664 p +share/skill/layout/leaf/property.il skill/layout/leaf/property.il 664 p +share/skill/layout/mid/mid.il skill/layout/mid/mid.il 664 p +share/skill/layout/mid/compact.il skill/layout/mid/compact.il 664 p + +# cable +share/skill/layout/cable/optimus.il skill/layout/cable/optimus.il 664 p +share/skill/layout/cable/placer.il skill/layout/cable/placer.il 664 p +share/skill/layout/cable/router.il skill/layout/cable/router.il 664 p +share/skill/layout/cable/templates.il skill/layout/cable/templates.il 664 p +share/skill/layout/cable/util.il skill/layout/cable/util.il 664 p + +# used by mk_instances to dump floorplan info to text file for jauto. +share/skill/layout/instancesfile/instance.il skill/layout/instancesfile/instance.il 664 p + +# power grids and tieoffs +share/skill/layout/powergrid/AutoGeneratePowerGrid.il skill/layout/powergrid/AutoGeneratePowerGrid.il 664 p + + +# pins +share/skill/layout/pins/autopin.il skill/layout/pins/autopin.il 664 p +share/skill/layout/pins/pinutil.il skill/layout/pins/pinutil.il 664 p +share/skill/layout/pins/channels/e1ofn.il skill/layout/pins/channels/e1ofn.il 664 p +share/skill/layout/pins/pinplace.il skill/layout/pins/pinplace.il 664 p +share/skill/layout/pins/canonicalize.il skill/layout/pins/canonicalize.il 664 p +share/skill/layout/pins/vstruts.il skill/layout/pins/vstruts.il 664 p +share/skill/layout/pins/abstractpin.il skill/layout/pins/abstractpin.il 664 p +share/skill/layout/pins/detailed_abstract.il skill/layout/pins/detailed_abstract.il 664 p +share/skill/layout/pins/pintemplates.il skill/layout/pins/pintemplates.il 664 p +share/skill/layout/pins/ScanPinToAutoPinFile.il skill/layout/pins/ScanPinToAutoPinFile.il 664 p +share/skill/layout/pins/midlevelpins.il skill/layout/pins/midlevelpins.il 664 p +share/skill/layout/pins/leafpins.il skill/layout/pins/leafpins.il 664 p +share/skill/layout/pins/expand_pins.il skill/layout/pins/expand_pins.il 664 p +share/skill/layout/pins/sync_pins.il skill/layout/pins/sync_pins.il 664 p +share/skill/layout/pins/pinlayer.il skill/layout/pins/pinlayer.il 664 p + + +# proteus +share/skill/layout/proteus/proteus.il skill/layout/proteus/proteus.il 664 p + +# For only. +share/skill/layout/chain/compactsuperstacks.il skill/layout/chain/compactsuperstacks.il 664 p +share/skill/layout/chain/createsuperstacks.il skill/layout/chain/createsuperstacks.il 664 p +share/skill/layout/chain/foldandchain.il skill/layout/chain/foldandchain.il 664 p +share/skill/layout/chain/inlinesuperstacks.il skill/layout/chain/inlinesuperstacks.il 664 p +share/skill/layout/leaf/decompact/spacestacks.il skill/layout/leaf/decompact/spacestacks.il 664 p +share/skill/layout/leaf/placer/foldgates.il skill/layout/leaf/placer/foldgates.il 664 p +share/skill/layout/leaf/placer/initnp.il skill/layout/leaf/placer/initnp.il 664 p +share/skill/layout/leaf/placer/placementregions.il skill/layout/leaf/placer/placementregions.il 664 p +share/skill/layout/leaf/placer/placercheck.il skill/layout/leaf/placer/placercheck.il 664 p +share/skill/layout/leaf/placer/placersearch.il skill/layout/leaf/placer/placersearch.il 664 p +share/skill/layout/leaf/placer/placersearchdone.il skill/layout/leaf/placer/placersearchdone.il 664 p +share/skill/layout/leaf/placer/runplacer.il skill/layout/leaf/placer/runplacer.il 664 p +share/skill/layout/leaf/plugs/addplugs.il skill/layout/leaf/plugs/addplugs.il 664 p +share/skill/layout/leaf/plugs/connectwellplugs.il skill/layout/leaf/plugs/connectwellplugs.il 664 p +share/skill/layout/leaf/plugs/wellplugsoff.il skill/layout/leaf/plugs/wellplugsoff.il 664 p +share/skill/layout/leaf/removeinvalidlayers.il skill/layout/leaf/removeinvalidlayers.il 664 p +share/skill/layout/leaf/router/checkpolygons.il skill/layout/leaf/router/checkpolygons.il 664 p +share/skill/layout/leaf/router/delextrapolycontact.il skill/layout/leaf/router/delextrapolycontact.il 664 p +share/skill/layout/leaf/router/lvsnodes.il skill/layout/leaf/router/lvsnodes.il 664 p +share/skill/layout/leaf/router/routercheck.il skill/layout/leaf/router/routercheck.il 664 p +share/skill/layout/leaf/router/routersearch.il skill/layout/leaf/router/routersearch.il 664 p +share/skill/layout/leaf/router/routersearchdone.il skill/layout/leaf/router/routersearchdone.il 664 p +share/skill/layout/leaf/router/routersearchinit.il skill/layout/leaf/router/routersearchinit.il 664 p +share/skill/layout/leaf/router/routerwidth.il skill/layout/leaf/router/routerwidth.il 664 p +share/skill/layout/leaf/router/runrouter.il skill/layout/leaf/router/runrouter.il 664 p +share/skill/layout/leaf/router/swapvias.il skill/layout/leaf/router/swapvias.il 664 p +share/skill/layout/leaf/router/setglcparams.il skill/layout/leaf/router/setglcparams.il 664 p +share/skill/layout/leaf/router/snapFatPins.il skill/layout/leaf/router/snapFatPins.il 664 p +share/skill/layout/leaf/router/PreroutePowerVia.il skill/layout/leaf/router/PreroutePowerVia.il 664 p +share/skill/layout/leaf/well/drawregionwell.il skill/layout/leaf/well/drawregionwell.il 664 p +share/skill/layout/notches/fillnotches.il skill/layout/notches/fillnotches.il 664 p +share/skill/ui/automation/copyview.il skill/ui/automation/copyview.il 664 p + +# install scripts +$arch/bin/gen_autoload skill/gen_autoload 775 p +install/share/bin/gen_autoload skill/gen_autoload 775 p +install/share/bin/package.il.inst skill/util/package/package.il.inst 775 p +install/share/bin/runplacer.inst skill/layout/leaf/placer/runplacer.inst 775 p + +# vendor release scripts +$arch/bin/cdl4Qualcore.pl ../../../vendor-release/cdl4Qualcore.pl 775 p +$arch/bin/def4Qualcore.pl ../../../vendor-release/def4Qualcore.pl 775 p +$arch/bin/gds24Qualcore.pl ../../../vendor-release/gds24Qualcore.pl 775 p +$arch/bin/lef4Qualcore.pl ../../../vendor-release/lef4Qualcore.pl 775 p +$arch/bin/chkpins4Qualcore.pl ../../../vendor-release/chkpins4Qualcore.pl 775 p +$arch/bin/release2Qualcore.pl ../../../vendor-release/release2Qualcore.pl 775 p +$arch/bin/bali2Qualcore.pl ../../../vendor-release/bali2Qualcore.pl 775 p + +#add bus.il, fat.il, power_grid.il +share/skill/layout/bus/bus.il skill/layout/bus/bus.il 664 p +share/skill/layout/bus/shield.il skill/layout/bus/shield.il 664 p +share/skill/layout/bus/obs.il skill/layout/bus/obs.il 664 p +share/skill/layout/bus/util.il skill/layout/bus/util.il 664 p +share/skill/layout/bus/patterns.il skill/layout/bus/patterns.il 664 p +#share/skill/layout/bus/fat.il skill/layout/bus/fat.il 664 p +share/skill/layout/power_grid/power_grid.il skill/layout/power_grid/power_grid.il 664 p + +# Router +#share/skill/layout/route/route.il skill/layout/route/route.il 664 p +share/skill/layout/route/nanoroute.il skill/layout/route/nanoroute.il 664 p +share/skill/layout/route/prelayout.il skill/layout/route/prelayout.il 664 p +share/skill/layout/route/flatten.il skill/layout/route/flatten.il 664 p +share/skill/layout/route/layout.il skill/layout/route/layout.il 664 p +share/skill/layout/route/routepath.il skill/layout/route/routepath.il 664 p +share/skill/layout/route/canonicalize.il skill/layout/route/canonicalize.il 664 p +share/skill/layout/route/trim.il skill/layout/route/trim.il 664 p +share/skill/layout/route/ground.il skill/layout/route/ground.il 664 p +#share/skill/layout/route/abstract.il skill/layout/route/abstract.il 664 p +share/skill/layout/route/reset.il skill/layout/route/reset.il 664 p +share/skill/layout/route/sync.il skill/layout/route/sync.il 664 p + +# Laygen +share/skill/layout/laygen/import.il skill/layout/laygen/import.il 664 p +share/skill/layout/laygen/pr.il skill/layout/laygen/pr.il 664 p + +# distort to fix VIA7 overhang +share/skill/layout/distort/distort.il skill/layout/distort/distort.il 664 p + +#new gds2cdl script +$arch/bin/gds2cdl.pl script/perl/gds2cdl.pl 775 p +$arch/bin/importQ.pl script/perl/importQ.pl 775 p +$arch/bin/importGDS.pl script/perl/importGDS.pl 775 p +$arch/bin/vs2calibre.pl script/perl/vs2calibre.pl 775 p +$arch/bin/vs2cast.pl script/perl/vs2cast.pl 775 p +$arch/bin/cdl2snp.pl script/perl/cdl2snp.pl 775 p + +#misc +$arch/bin/dfIIhier script/perl/dfIIhier.pl 775 p + +#new supersize procedure script +$arch/bin/initFloorplan.sh script/sh/floorplan/initFloorplan.sh 775 p + +#misc +$arch/bin/hlvs ../../../lve/script/perl/spice/hlvs.pl 775 p +$arch/bin/lef2rp script/perl/lef2rp.pl 775 p +$arch/bin/vs2et script/perl/vs2et.pl 775 p diff --git a/async-toolkit/jtools/cad/java/Makefile b/async-toolkit/jtools/cad/java/Makefile new file mode 100755 index 0000000000..0bb781bf10 --- /dev/null +++ b/async-toolkit/jtools/cad/java/Makefile @@ -0,0 +1,297 @@ +# +# Copyright 2000-2003 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# Author: Jesse Rosenstock +# Version: $Name: $ $Date$ +# + +# Make settings +# Clean out default rules. We don't want them. +.SUFFIXES: + +# Phony rules +.PHONY: all extraclean clean install default help test javadoc +.PHONY: test_no_build install_jar install_ext2aspice install_iosim +.PHONY: cleandoc makefiles dsim_clean dsim install_dsim install_jflat +.PHONY: install_jlvs install_cadencize install_cdl2aspice remove_stale +.PHONY: some %/some + + +#default rule to build. +default: clean all test + + +# locations. +CHECKOUT=/home/lines +JCAST:=$(shell pwd) +space:= $(empty) $(empty) + +CLASSES_DIR:=classes +JRE_LIB:=/usr/intel/pkgs/java/1.6.0.10-64/jre/lib +JRE_JARS:=$(JRE_LIB)/rt.jar:$(subst $(space),:,$(wildcard $(JRE_LIB)/ext/*.jar)) + +ifndef CLASSPATH + export CLASSPATH:=$(JAVAFILES_CLASSES_JAR_ROOT)/antlr-2.7.2.jar:CLASSPATH:=$(JAVAFILES_CLASSES_JAR_ROOT)/concurrent.jar:jars/javancss.jar:jars/jcsp-std-J2.jar:src:$(CLASSES_DIR) +else + export CLASSPATH:=src:$(CLASSES_DIR):$(CLASSPATH) +endif + +UNAME:=$(shell uname) + +ifeq ($(UNAME),Darwin) + export JIKESPATH:=$(CLASSPATH):$(subst $(space),:,$(wildcard /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/*.jar)) +else + export JIKESPATH:=$(CLASSPATH):$(JRE_JARS) +endif + +# programs to use. +# JAVADEPENDS:=jikes +M +P # does not yet work. +ifeq ($(UNAME),Darwin) + JAVAC ?= jikes +Pno-modifier-order -source 1.4 +else + JAVAC ?= jikes +Pno-modifier-order +Pno-unchecked-exception -source 1.4 +endif +JAVA=java +JAVAH=javah +JAVAC_FLAGS=-g -d classes +ANTLR=java antlr.Tool +CTAGS:=ctags +INSTALL = install -m 775 +SED=sed + +#JAVADOC=scripts/javadoc-1.2 +JAVADOC_CLASSPATH := jars/antlrall-2.7.2.jar:$(CLASSPATH) +JAVADOC:=javadoc -source 1.4 -classpath $(JAVADOC_CLASSPATH) +JAVADOC_FLAGS:=-private -version -author -breakiterator -splitindex \ + -windowtitle "jcast javadoc" \ + -tag todo:a:"To Do:" -tag design:a:"Design Note:" \ + -tag review:a:"Should be Reviewed:" -tag bug:a:"Possible Bug:" \ + -link http://java.sun.com/j2se/1.3/docs/api/ \ + -link http://internal.avlsi.com/technical/docs/antlr-docs \ + -link http://internal.avlsi.com/technical/docs/jcsp-docs +JAVADOC_DIR=javadoc + +FIND_JAVA_FILES:=find src -name '*.java' +FIND_CLASS_FILES:=find classes -name '*.class' +FIND_ANTLR_FILES:=find src -name '*.g' +REALIGNORES:=$(find src -name '.realignore') + +SUBDIRS:=$(shell find src -type d) +SUBDIR_MAKEFILES:=$(SUBDIRS:%=%/Makefile) + + +#build directory +BUILD := $(JCAST)/build + +ANTLR_SOURCES:=$(shell $(FIND_ANTLR_FILES)) +# ANTLR_TARGETS:=$(ANTLR_SOURCES:%.g=%Parser.java) \ +# $(ANTLR_SOURCES:%.g=%TokenTypes.java) \ +# $(ANTLR_SOURCES:%.g=%Lexer.java) +# +# Not all of them produced. *sigh* +ANTLR_TARGETS := + + +#Get all antlr rules from file in make files fragments in the build directory. +ANTLR_GRAMMER_BUILD_INCLUDES := $(wildcard $(BUILD)/antlr-grammers/*/antlrrules.mk) + +include $(ANTLR_GRAMMER_BUILD_INCLUDES) + + +# Produced when grammars extend each other +ANTLR_BYPRODUCTS:=\ + src/com/avlsi/cast2/impl/extendedCastPrs.g\ + src/com/avlsi/cast2/impl/extendedCastSubcells.g + +ALL_CVS_JAVA_FILES:=$(filter-out $(ANTLR_TARGETS), $(shell $(FIND_JAVA_FILES))) +ALL_JAVA_FILES:=$(ALL_CVS_JAVA_FILES) $(ANTLR_TARGETS) +ALL_CLASS_FILES:=$(ALL_JAVA_FILES:src/%.java=classes/%.class) + +BUILD_INFRASTRUCTURE:=$(SUBDIR_MAKEFILES) + + +help: + @echo '"make" rebuilds all stale .class files in large batches' + @echo '"make clean" removes all .class files' + @echo '"make extraclean" also removes autogenerated Makefiles, and dependancy (.u) files' + @echo '"make makefiles" rebuilds Makefiles in all dirs' + @echo '"make javadoc" builds javadoc in' "$(JAVADOC_DIR)" + @echo '"make cleandoc" removes' "$(JAVADOC_DIR)" + @echo '"make test" runs tests' + @echo '"make tags" makes a "tags" file. (vim -t identifier) jumps to it.' + @echo '"make install" installs jars' + @echo '"make install_dsim" installs dsim shared library' + +all: $(BUILD_INFRASTRUCTURE) $(ANTLR_TARGETS) $(ALL_CLASS_FILES) + +tags: $(BUILD_INFRASTRUCTURE) $(ALL_JAVA_FILES) + $(FIND_JAVA_FILES) -print | $(CTAGS) -L- + +%/tags: $(BUILD_INFRASTRUCTURE) $(ANTLR_TARGETS) + cd `dirname "$@"` && $(CTAGS) *.java + +clean: + rm -rf apps-build + find classes -name '*.class' -print0 | xargs -0 rm -f + find src -name '*.class' -print0 | xargs -0 rm -f + +extraclean: clean + -rm -f $(BUILD_INFRASTRUCTURE) + -rm -f $(ANTLR_TARGETS) + -rm -f $(ANTLR_BYPRODUCTS) + find classes -name '*.u' -print0 | xargs -0 rm -f + find . -name 'tags' -print0 | xargs -0 rm -f + +# installation + +install: all install_jar install_ext2aspice install_iosim install_jflat \ + install_cadencize install_jlvs install_cdl2aspice install_csp2java + @echo "libDSIMServer.so not installed, make install_dsim to install" + +install_jar: jcast.jar + $(INSTALL) jcast.jar jars/jcast.jar + +install_ext2aspice: scripts/ext2aspice + $(INSTALL) scripts/ext2aspice /usr/local/cad/bin/java_ext2aspice + +install_cdl2aspice: scripts/cdl2aspice + $(INSTALL) scripts/cdl2aspice /usr/local/cad/bin/java_cdl2aspice + +install_cadencize: scripts/cadencize + $(INSTALL) scripts/cadencize /usr/local/cad/bin/cadencize + +install_jflat: scripts/jflat + $(INSTALL) scripts/jflat /usr/local/cad/bin/jflat + +install_jlvs: scripts/jlvs + $(INSTALL) scripts/jlvs /usr/local/cad/bin/jlvs + +install_iosim: scripts/iosim + $(INSTALL) scripts/iosim /usr/local/cad/bin/iosim + +install_mgn: scripts/mgn + $(INSTALL) scripts/mgn /usr/local/cad/bin/mgn + +install_csp2java: jcast.jar scripts/csp2java + $(INSTALL) scripts/csp2java /usr/local/cad/bin/csp2java + $(INSTALL) jcast.jar jars/csp2java.jar + +jcast.jar: all + jar cf jcast.jar -C classes . + +$(CLASSES_DIR): + mkdir $(CLASSES_DIR) + +# Excluding cmdline/ is a hack to get rid of the javadoc error +# produced there so javadoc can actually be generated. +javadoc: cleandoc + mkdir $(JAVADOC_DIR) + $(JAVADOC) $(JAVADOC_FLAGS) -d $(JAVADOC_DIR) \ + `$(FIND_JAVA_FILES) -and -not -path '*com/avlsi/util/cmdline/*' \ + -exec dirname '{}' \; | sort | uniq | \ + $(SED) 's:src/::; s:/:.:g;' ` + +cleandoc: + rm -rf $(JAVADOC_DIR) + +test: all + $(JAVA) com.avlsi.test.TestEverything + +makefiles: $(SUBDIR_MAKEFILES) + +$(SUBDIR_MAKEFILES): scripts/make_subdir_makefile + scripts/make_subdir_makefile `dirname $@` + +%/some: + $(JAVAC) $(JAVAC_FLAGS) $(*)/*.java + +# rules for java +# Can not compile some of these until the ANTLR targets they reference +# get made. +$(ALL_CLASS_FILES) : $(ANTLR_TARGETS) $(CLASSES_DIR) + +ifdef JAVADEPENDS +### +# Okay, this is tricky... +# We want to batch up compilations to minimize time spent starting +# up the compiler. OTOH, we also don't want to compile java files +# unnecessarily. So, we want make to compile all things that are +# out-of-date whenever any one thing is out-of-date. +# We can do this by having make invoke itself to collect the list of +# files to compile, and only then compiling them. +ifndef JAVA_MAKE_COLLECTION_HACK +classes/%.class classes/%.u : src/%.java + : > collecting + make JAVA_MAKE_COLLECTION_HACK=1 all + sort < collecting | uniq > out-of-date + $(JAVADEPENDS) $(JAVAC_FLAGS) @out-of-date + rm out-of-date collecting +else +# should also remove all inner classes here. +classes/%.class classes/%.u : src/%.java + @echo -n . + @echo $< >> collecting +endif + +# - -- do not complain if missing +# $(wildcard ...) -- only use pre-existing depends. Otherwise make +# will try to build them. +ifneq (,$(wildcard $(ALL_CLASS_FILES:%.class=%.u))) +-include $(wildcard $(ALL_CLASS_FILES:%.class=%.u)) +endif +else +#### +# not trying to save time with dependencies. All class files get rebuilt when anything changes. +$(ALL_CLASS_FILES) : $(ALL_JAVA_FILES) $(CLASSES_DIR) + @[ -z "$(MAKE_DEBUG)" ] || echo compiling $(@:classes/%.class=src/%.java) + $(FIND_JAVA_FILES) -print0 | xargs -0 $(JAVAC) $(JAVAC_FLAGS) +endif + +# We start with a list of all extant .class files, and remove the ones +# we think we can generate from the list of java files. This skips inner +# classes that may have been eliminated, but we will handle those cases +# in building. +# +remove_stale: + -rm -f $(filter-out $(ALL_JAVA_FILES:src/%.java=classes/%.class) $(ALL_JAVA_FILES:src/%.java=classes/%$*.class), $(shell $(FIND_CLASS_FILES))) + +# DSIM Stuff + +DSIMOBJ=src/com/avlsi/dsim/DSIMServer.o \ + $(CHECKOUT)/cast/aspice/source/obj.i686/dsimlib.o \ + $(CHECKOUT)/cast/aspice/source/obj.i686/aspicelib.a \ + $(CHECKOUT)/cast/lib/obj.i686/castlib.a + +src/com/avlsi/dsim/com_avlsi_dsim_DSIMServer.h: classes/com/avlsi/dsim/DSIMServer.class + $(JAVAH) -jni -o $@ com.avlsi.dsim.DSIMServer + +src/com/avlsi/dsim/DSIMServer.o: src/com/avlsi/dsim/DSIMServer.c src/com/avlsi/dsim/com_avlsi_dsim_DSIMServer.h + $(CC) -Wall -I$(CHECKOUT)/cast/aspice/source -I/usr/local/java/include -Isrc/com/avlsi/dsim -c src/com/avlsi/dsim/DSIMServer.c -o $@ + +src/com/avlsi/dsim/libDSIMServer.so: $(DSIMOBJ) + $(CC) -shared -Wl,-soname,libDSIMServe.so -o $@ $(DSIMOBJ) + +dsim_clean: + -rm -rf src/com/avlsi/dsim/DSIMServer.o src/com/avlsi/dsim/libDSIMServer.so src/com/avlsi/dsim/com_avlsi_dsim_DSIMServer.h + +dsim: all src/com/avlsi/dsim/libDSIMServer.so + +install_dsim: dsim + cp src/com/avlsi/dsim/libDSIMServer.so jars/native + +CPPFLAGS=-I/usr/local/java/include -I/usr/local/java/include/linux -I/usr/local/java/include/solaris -I/usr/include +include src/com/avlsi/util/readline/submakefile +include src/com/avlsi/util/cmdline/submakefile +include src/com/avlsi/tools/tsim/denali/submakefile + + +# Import rules for building applications +APPS_TARGET_DIRS := apps-build + + + +APP_BUILD_INCLUDES := $(wildcard $(BUILD)/apps/*/apprules.mk) +APP_BUILD_BASE_CLASSPATH := $(JRE_JARS) +include $(APP_BUILD_INCLUDES) diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/CDL/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/CDL/antlrrules.mk new file mode 100644 index 0000000000..da47ac307f --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/CDL/antlrrules.mk @@ -0,0 +1,10 @@ +CDL_ANTLR_TARGETS = src/com/avlsi/file/cdl/parser/CDLLexer.java \ + src/com/avlsi/file/cdl/parser/CDLParser.java \ + src/com/avlsi/file/cdl/parser/CDLWalker.java \ + src/com/avlsi/file/cdl/parser/CDLLexerTokenTypes.java +ANTLR_TARGETS += $(CDL_ANTLR_TARGETS) + +# CDL.g + +$(CDL_ANTLR_TARGETS): src/com/avlsi/file/cdl/parser/CDL.g + cd src/com/avlsi/file/cdl/parser && $(ANTLR) CDL.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/Cast/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/Cast/antlrrules.mk new file mode 100644 index 0000000000..0e4a4c078d --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/Cast/antlrrules.mk @@ -0,0 +1,27 @@ + +ANTLR_TARGETS += src/com/avlsi/cast/impl/CastLexer.java \ + src/com/avlsi/cast/impl/CastParser.java \ + src/com/avlsi/cast/impl/CastTokenTypes.java \ + src/com/avlsi/cast/impl/CastTreeParser.java \ + src/com/avlsi/cast/impl/CastTreeParserTokenTypes.java \ + src/com/avlsi/cast/impl/DumbLexer.java \ + src/com/avlsi/cast/impl/DumbParser.java \ + src/com/avlsi/cast/impl/DumbTokenTypes.java +# Cast.g + +src/com/avlsi/cast/impl/CastParser.java \ +src/com/avlsi/cast/impl/CastLexer.java \ +src/com/avlsi/cast/impl/CastTokenTypes.java: src/com/avlsi/cast/impl/Cast.g + cd src/com/avlsi/cast/impl && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) Cast.g +# CastTree.g + +src/com/avlsi/cast/impl/CastTreeParser.java \ +src/com/avlsi/cast/impl/CastTreeParserTokenTypes.java: src/com/avlsi/cast/impl/CastTree.g + cd src/com/avlsi/cast/impl && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) CastTree.g + +# Dumb.g + +src/com/avlsi/cast/impl/DumbParser.java \ +src/com/avlsi/cast/impl/DumbLexer.java \ +src/com/avlsi/cast/impl/DumbTokenTypes.java: src/com/avlsi/cast/impl/Dumb.g + cd src/com/avlsi/cast/impl && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) Dumb.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/CastQuery/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/CastQuery/antlrrules.mk new file mode 100644 index 0000000000..e5c5ab82db --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/CastQuery/antlrrules.mk @@ -0,0 +1,10 @@ +CASTQUERY_ANTLR_TARGETS = src/com/avlsi/tools/jauto/CastQueryLexer.java \ + src/com/avlsi/tools/jauto/CastQueryParser.java \ + src/com/avlsi/tools/jauto/CastQueryParserTokenTypes.java + +ANTLR_TARGETS += $(CASTQUERY_ANTLR_TARGETS) + +# CastQuery.g + +$(CASTQUERY_ANTLR_TARGETS): src/com/avlsi/tools/jauto/CastQuery.g + cd src/com/avlsi/tools/jauto && $(ANTLR) CastQuery.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/CastTwo/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/CastTwo/antlrrules.mk new file mode 100644 index 0000000000..5e4cd01802 --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/CastTwo/antlrrules.mk @@ -0,0 +1,71 @@ +ANTLR_TARGETS += src/com/avlsi/cast2/impl/CastPrsParser.java \ + src/com/avlsi/cast2/impl/CastPrsParserTokenTypes.java \ + src/com/avlsi/cast2/impl/CastSubcellsParser.java \ + src/com/avlsi/cast2/impl/CastSubcellsParserTokenTypes.java \ + src/com/avlsi/cast2/impl/CastAliasesParser.java \ + src/com/avlsi/cast2/impl/CastAliasesParserTokenTypes.java \ + src/com/avlsi/cast2/impl/CastAssertParser.java \ + src/com/avlsi/cast2/impl/CastAssertParserTokenTypes.java \ + src/com/avlsi/cast2/impl/CastSubtypesParser.java \ + src/com/avlsi/cast2/impl/CastSubtypesParserTokenTypes.java \ + src/com/avlsi/cast2/impl/CastTwoLexer.java \ + src/com/avlsi/cast2/impl/CastTwoParser.java \ + src/com/avlsi/cast2/impl/CastTwoTokenTypes.java \ + src/com/avlsi/cast2/impl/CastTwoTreeParser.java \ + src/com/avlsi/cast2/impl/CastTwoTreeParserTokenTypes.java \ + src/com/avlsi/cast2/impl/DumbTwoLexer.java \ + src/com/avlsi/cast2/impl/DumbTwoParser.java \ + src/com/avlsi/cast2/impl/DumbTwoTokenTypes.java + + +# CastPrs.g + +src/com/avlsi/cast2/impl/CastPrsParser.java \ +src/com/avlsi/cast2/impl/CastPrsParserTokenTypes.java: src/com/avlsi/cast2/impl/CastPrs.g src/com/avlsi/cast2/impl/CastTwoTokenTypes.java + cd src/com/avlsi/cast2/impl && $(ANTLR) -glib CastTwo.g CastPrs.g + + +# CastAliases.g + +src/com/avlsi/cast2/impl/CastAliasesParser.java \ +src/com/avlsi/cast2/impl/CastAliasesParserTokenTypes.java: src/com/avlsi/cast2/impl/CastAliases.g src/com/avlsi/cast2/impl/CastTwoTokenTypes.java + cd src/com/avlsi/cast2/impl && $(ANTLR) -glib CastTwo.g CastAliases.g + +# CastAssert.g + +src/com/avlsi/cast2/impl/CastAssertParser.java \ +src/com/avlsi/cast2/impl/CastAssertParserTokenTypes.java: src/com/avlsi/cast2/impl/CastAssert.g src/com/avlsi/cast2/impl/CastTwoTokenTypes.java + cd src/com/avlsi/cast2/impl && $(ANTLR) -glib "CastPrs.g;CastTwo.g" CastAssert.g + +# CastSubcells.g + +src/com/avlsi/cast2/impl/CastSubcellsParser.java \ +src/com/avlsi/cast2/impl/CastSubcellsParserTokenTypes.java: src/com/avlsi/cast2/impl/CastSubcells.g src/com/avlsi/cast2/impl/CastTwoTokenTypes.java + cd src/com/avlsi/cast2/impl && $(ANTLR) -glib CastTwo.g CastSubcells.g + +# CastSubtypes.g + +src/com/avlsi/cast2/impl/CastSubtypesParser.java \ +src/com/avlsi/cast2/impl/CastSubtypesParserTokenTypes.java: src/com/avlsi/cast2/impl/CastSubtypes.g src/com/avlsi/cast2/impl/CastTwoTokenTypes.java + cd src/com/avlsi/cast2/impl && $(ANTLR) -glib CastTwo.g CastSubtypes.g + +# CastTwo.g + +src/com/avlsi/cast2/impl/CastTwoParser.java \ +src/com/avlsi/cast2/impl/CastTwoLexer.java \ +src/com/avlsi/cast2/impl/CastTwoTokenTypes.java: src/com/avlsi/cast2/impl/CastTwo.g + cd src/com/avlsi/cast2/impl && $(ANTLR) CastTwo.g + +# CastTwoTree.g + +src/com/avlsi/cast2/impl/CastTwoTreeParser.java \ +src/com/avlsi/cast2/impl/CastTwoTreeParserTokenTypes.java: src/com/avlsi/cast2/impl/CastTwoTree.g src/com/avlsi/cast2/impl/CastTwoTokenTypes.java + cd src/com/avlsi/cast2/impl && $(ANTLR) CastTwoTree.g + +# DumbTwo.g + +src/com/avlsi/cast2/impl/DumbTwoParser.java \ +src/com/avlsi/cast2/impl/DumbTwoLexer.java \ +src/com/avlsi/cast2/impl/DumbTwoTokenTypes.java: src/com/avlsi/cast2/impl/DumbTwo.g + cd src/com/avlsi/cast2/impl && $(ANTLR) DumbTwo.g + diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/CellHierarchyDump/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/CellHierarchyDump/antlrrules.mk new file mode 100644 index 0000000000..be1b1d834e --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/CellHierarchyDump/antlrrules.mk @@ -0,0 +1,9 @@ + +ANTLR_TARGETS += src/com/avlsi/tools/jauto/CellHierarchyDumpLexer.java \ + src/com/avlsi/tools/jauto/CellHierarchyDumpParser.java + +# CellHierarchyDump.g + +src/com/avlsi/tools/jauto/CellHierarchyDumpLexer.java\ +src/com/avlsi/tools/jauto/CellHierarchyDumpParser.java : src/com/avlsi/tools/jauto/CellHierarchyDump.g + cd src/com/avlsi/tools/jauto && $(ANTLR) CellHierarchyDump.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/CoSim/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/CoSim/antlrrules.mk new file mode 100644 index 0000000000..d77ea4eb1f --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/CoSim/antlrrules.mk @@ -0,0 +1,9 @@ + +ANTLR_TARGETS += src/com/avlsi/tools/cosim/spec/CoSimParser.java \ + src/com/avlsi/tools/cosim/spec/CoSimLexer.java \ + src/com/avlsi/tools/cosim/spec/CoSimParserTokenTypes.java + +src/com/avlsi/tools/cosim/spec/CoSimParser.java \ +src/com/avlsi/tools/cosim/spec/CoSimLexer.java \ +src/com/avlsi/tools/cosim/spec/CoSimParserTokenTypes.java : src/com/avlsi/tools/cosim/spec/CoSim.g + cd src/com/avlsi/tools/cosim/spec && $(ANTLR) CoSim.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/Csp/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/Csp/antlrrules.mk new file mode 100644 index 0000000000..785d38db49 --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/Csp/antlrrules.mk @@ -0,0 +1,9 @@ + +ANTLR_TARGETS += src/com/avlsi/csp/grammar/CspParser.java \ + src/com/avlsi/csp/grammar/CspLexer.java \ + src/com/avlsi/csp/grammar/CspParserTokenTypes.java + +src/com/avlsi/csp/grammar/CspParser.java \ +src/com/avlsi/csp/grammar/CspLexer.java \ +src/com/avlsi/csp/grammar/CspParserTokenTypes.java : src/com/avlsi/csp/grammar/Csp.g + cd src/com/avlsi/csp/grammar && $(ANTLR) Csp.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/MathExpression/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/MathExpression/antlrrules.mk new file mode 100644 index 0000000000..a81cb5a1f6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/MathExpression/antlrrules.mk @@ -0,0 +1,11 @@ +ANTLR_TARGETS += src/com/avlsi/util/mathexpression/impl/parser/MathExpressionParser.java \ + src/com/avlsi/util/mathexpression/impl/parser/MathExpressionLexer.java \ + src/com/avlsi/util/mathexpression/impl/parser/MathExpressionParserTokenTypes.java + + +# MathExpression.g + +src/com/avlsi/util/mathexpression/impl/parser/MathExpressionParser.java\ +src/com/avlsi/util/mathexpression/impl/parser/MathExpressionLexer.java\ +src/com/avlsi/util/mathexpression/impl/parser/MathExpressionParserTokenTypes.java: src/com/avlsi/util/mathexpression/impl/parser/MathExpression.g + cd src/com/avlsi/util/mathexpression/impl/parser && $(ANTLR) MathExpression.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/Shape/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/Shape/antlrrules.mk new file mode 100644 index 0000000000..2308ba31fa --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/Shape/antlrrules.mk @@ -0,0 +1,11 @@ +ANTLR_TARGETS += src/com/avlsi/fast/shapes/impl/parser/ShapeLexer.java \ + src/com/avlsi/fast/shapes/impl/parser/ShapeParser.java \ + src/com/avlsi/fast/shapes/impl/parser/ShapeLexerTokenTypes.java + + +# Shape.g + +src/com/avlsi/fast/shapes/impl/parser/ShapeLexer.java\ +src/com/avlsi/fast/shapes/impl/parser/ShapeParser.java\ +src/com/avlsi/fast/shapes/impl/parser/ShapeLexerTokenTypes.java: src/com/avlsi/fast/shapes/impl/parser/Shape.g + cd src/com/avlsi/fast/shapes/impl/parser && $(ANTLR) Shape.g diff --git a/async-toolkit/jtools/cad/java/build/antlr-grammers/StringExpression/antlrrules.mk b/async-toolkit/jtools/cad/java/build/antlr-grammers/StringExpression/antlrrules.mk new file mode 100644 index 0000000000..221561ba3f --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/antlr-grammers/StringExpression/antlrrules.mk @@ -0,0 +1,11 @@ + +ANTLR_TARGETS += src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpressionParser.java \ + src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpressionLexer.java \ + src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpressionParserTokenTypes.java + +# StringExpression.g + +src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpressionParser.java\ +src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpressionLexer.java\ +src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpressionParserTokenTypes.java: src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpression.g + cd src/com/avlsi/fast/shapes/stringexpression/impl/parser && $(ANTLR) StringExpression.g diff --git a/async-toolkit/jtools/cad/java/build/apps/dsim/apprules.mk b/async-toolkit/jtools/cad/java/build/apps/dsim/apprules.mk new file mode 100644 index 0000000000..41822404f1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/apps/dsim/apprules.mk @@ -0,0 +1,18 @@ +dsimjar : $(APPS_TARGET_DIRS)/dsim.jar + +DSIM_BUILD_TEMP := $(APPS_TARGET_DIRS)/dsim.jar-tempdir + +DSIM_JAVA_FILES := src/com/avlsi/tools/dsim/DSimMain.java \ + src/com/avlsi/util/cmdline/DSimModule.java + +$(DSIM_BUILD_TEMP): + mkdir -p $@ + +$(DSIM_BUILD_TEMP)/appmanifest: $(DSIM_BUILD_TEMP) + echo "Main-Class: com.avlsi.tools.dsim.DSimMain" > $@ + +$(APPS_TARGET_DIRS)/dsim.jar: $(ALL_JAVA_FILES) $(DSIM_BUILD_TEMP) $(DSIM_BUILD_TEMP)/appmanifest + $(JAVAC) -g -deprecation -classpath $(APP_BUILD_BASE_CLASSPATH):src:$(JAVAFILES_CLASSES_JAR_ROOT)/antlr.jar: \ + -d $(DSIM_BUILD_TEMP) $(DSIM_JAVA_FILES) + jar cmf $(DSIM_BUILD_TEMP)/appmanifest $@ -C $(DSIM_BUILD_TEMP) com + rm -rf $(DSIM_BUILD_TEMP) diff --git a/async-toolkit/jtools/cad/java/build/apps/jauto/apprules.mk b/async-toolkit/jtools/cad/java/build/apps/jauto/apprules.mk new file mode 100644 index 0000000000..84e2e8b28d --- /dev/null +++ b/async-toolkit/jtools/cad/java/build/apps/jauto/apprules.mk @@ -0,0 +1,17 @@ +jauto : $(APPS_TARGET_DIRS)/jauto.jar + +JAUTO_BUILD_TEMP := $(APPS_TARGET_DIRS)/jauto.jar-tempdir + +JAUTO_JAVA_FILE := src/com/avlsi/tools/jauto/Jauto.java + +$(JAUTO_BUILD_TEMP): + mkdir -p $@ + +$(JAUTO_BUILD_TEMP)/appmanifest: $(JAUTO_BUILD_TEMP) + echo "Main-Class: com.avlsi.tools.jauto.Jauto" > $@ + +$(APPS_TARGET_DIRS)/jauto.jar: $(ALL_JAVA_FILES) $(JAUTO_BUILD_TEMP) $(JAUTO_BUILD_TEMP)/appmanifest + $(JAVAC) -g -deprecation -classpath $(APP_BUILD_BASE_CLASSPATH):src: $(JAVAFILES_CLASSES_JAR_ROOT)/antlr.jar: \ + -d $(JAUTO_BUILD_TEMP) $(JAUTO_JAVA_FILE) + jar cmf $(JAUTO_BUILD_TEMP)/appmanifest $@ -C $(JAUTO_BUILD_TEMP) com + rm -rf $(JAUTO_BUILD_TEMP) diff --git a/async-toolkit/jtools/cad/java/custom.mk b/async-toolkit/jtools/cad/java/custom.mk new file mode 100644 index 0000000000..ab6457cad1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/custom.mk @@ -0,0 +1 @@ +CURR_NON_BUILD_DIRS := apps-build build classes CVS javadoc projects scripts tests $(CURR_NON_BUILD_DIRS) diff --git a/async-toolkit/jtools/cad/java/scripts/cadencize b/async-toolkit/jtools/cad/java/scripts/cadencize new file mode 100755 index 0000000000..6b03eb5672 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/cadencize @@ -0,0 +1,227 @@ +#!/bin/bash +# $Id$ + +function output() { + if [ "$VERBOSE" = "1" ]; then + echo "$1" + fi +} + +function usage() { + echo "Usage: cadencize cell" + echo + echo " -v: verbose" + echo " -o: do not overwrite existing .auto file" + echo " -f: take floorplanning info from mag file" + echo " -m: specify memory usage for java (ex 128M)" + echo " -d: debug mode( honor CLASSPATH )" + echo " -i: import hand layout from magic" + echo " -c: Generate cdl file" + exit 1 +} + +VERBOSE=0 +OVERWRITE=0 +FLOORPLAN=AUTO +DEBUG=0 +IMPORT=0 +CDLOUT=0 + +while getopts ":vofdhcm:i" opt; do + case $opt in + v ) VERBOSE=1 ;; + o ) OVERWRITE=0 ;; + f ) FLOORPLAN=MAG ;; + m ) JAVAMEM=$OPTARG ;; + d ) DEBUGMODE=1;; + i ) IMPORT=1;; + h ) usage ;; + c ) CDLOUT=1 ;; + \? ) usage + esac +done +shift $(($OPTIND - 1)) + +if [ -z "$1" ]; then + usage +fi + +CELLNAME=`basename $1` + +output "Cell name is $CELLNAME" + +if [ `dirname $1` = "." ]; then + NEEDPOPD=0 + UNITNAME=`pwd` + UNITNAME=`basename $UNITNAME` + CELLDIRNAME="." +else + NEEDPOPD=1 + + output "Looking up cell dir." + + CELLDIRNAME=`new_fc -dC $1` + + output "Cell dir is: $CELLDIRNAME" + + UNITNAME=`dirname $1` + + output "Cell unit is: $UNITNAME" + + CELLDIRNAME="$CELLDIRNAME/$1" + + + + CELLDIRNAME=`dirname $CELLDIRNAME` + pushd $CELLDIRNAME > /dev/null +fi + +if [ "$IMPORT" = "1" ]; then + output "Importing cell from magic" + mkdir $CELLNAME-blocks 2> /dev/null + dirname=`pwd | rev | cut -d'/' -f1 | rev` + cd $CELLNAME-blocks + auto ../$CELLNAME.mag $CELLNAME.il < $CAST_HOME/lib/auto/magicimport.in + echo "$HARDWARE_HOME/ADD7M/$dirname/$CELLNAME-blocks $dirname-$CELLNAME Leaf" > $HARDWARE_HOME/.cadencized + exit +fi + +output "Verbose mode" + +if [ "$OVERWRITE" = "1" ]; then + output "CVS updating auto file" + rm -f $CELLNAME.auto.bak + cp $CELLNAME.auto $CELLNAME.auto.bak 2> /dev/null + rm -f $CELLNAME.auto + cvs update $CELLNAME.auto > /dev/null 2> /dev/null + output "CVS updating cast file" + cvs update `stlookup -cp "$CELLNAME"` +else + echo 'Do not forget to cvs commit your auto file if' + echo 'you make any changes to it!' +fi + +if [ "$FLOORPLAN" = "MAG" ]; then + if [ "$OVERWRITE" = "1" ]; then + output "CVS updating mag file" + rm -f $CELLNAME.mag + cvs update $CELLNAME.mag > /dev/null 2> /dev/null + fi + chmod u+w $CELLNAME.auto + output "Running fp_mag2auto on $UNITNAME/$CELLNAME" + fp_mag2auto $UNITNAME/$CELLNAME + if [ -z "`grep inplace $CELLNAME.auto`" ]; then + echo 'WARNING: no inplace directive!!! Are you sure you do not need one?' + fi +fi +magtype=`mag_is $HARDWARE_HOME/ADD7M/$UNITNAME/$CELLNAME.mag` +output "mag file is type: $magtype" + +if [ ! -e $HARDWARE_HOME/cast/sram32/link_sram32.cast ]; then + output "Creating link to real_sram32.cast" + ln -s $HARDWARE_HOME/cast/sram32/real_sram32.cast $HARDWARE_HOME/cast/sram32/link_sram32.cast +fi + +if [ -a "$CELLNAME.auto" ] ; then + output "running auto" + auto_skill "$CELLNAME" + rm -f $CELLNAME-blocks/$CELLNAME.auto + cp $CELLNAME.auto $CELLNAME-blocks +else + mkdir "$CELLNAME-blocks" + pushd "$CELLNAME-blocks" > /dev/null + if [ -a "../$CELLNAME.mag" ] ; then + output "running auto" + auto "../$CELLNAME.mag" $CELLNAME.il <$CAST_HOME/lib/auto/floor.in + else + echo "Unable to find auto file or mag file for $CELLNAME." + fi + popd > /dev/null +fi + +output "finding cast file" + +CELLCASTFILE="`stlookup -c -p $CELLNAME`" +CELLCASTNAME="`stlookup -c $CELLNAME`" + +# ensure that there is only one cast file +if [ `echo "$CELLCASTFILE" | wc -l` != 1 ]; then + echo "Multiple cast files found for $CELLNAME:" + echo "$CELLCASTFILE" + exit 2 +fi + +if [ -z $CELLCASTFILE ] ; then + echo "Unable to get cast file for $CELLNAME." + exit 1 +fi + +if [ -z $CELLCASTNAME ] ; then + echo "Unable to get cast cell name for $CELLNAME." + exit 1 +fi + +output "found cell $CELLCASTNAME in file $CELLCASTFILE" + + +MYCLASSPATH=$HOME/jars/jcast.jar:$HOME/jars/antlr.jar + +if [ "$DEBUGMODE" = "1" ] ; then + MYCLASSPATH=$CLASSPATH +else + echo "$DEBUGMODE" +fi + +#TMPFILENAME=`date -u +"/tmp/%d-%m-%Y-%H-%M-%S-cadencize-$USER"` +CASTTMPFILENAME="tmp.$$.0" + +output "creating cast temp file $TMPFILENAME" + +cat $CELLCASTFILE > $CASTTMPFILENAME +echo "$CELLCASTNAME cadencize_inst ;" >> $CASTTMPFILENAME + +output "creating subcells file" +SUBCELLSTEMPFILENAME="tmp.$$.1" + +magic_subcells "$UNITNAME/$CELLNAME" >$SUBCELLSTEMPFILENAME + +output "creating extract files" +output "running java cadencize" + +if [ -z "$JAVAMEM" ]; then + JAVAMEM=128M +fi +if [ "$CDLOUT" = "1" ]; then + magicextract "$UNITNAME/$CELLNAME" &>/dev/null + EXTRACTFILENAME="$CELLDIRNAME/$CELLNAME.ext" + output "Extract file name is $EXTRACTFILENAME" + CLASSPATH=$MYCLASSPATH /usr/intel/bin/java -Xmx$JAVAMEM -DHOME="$HOME" com.avlsi.tools.cadencize.Cadencize "$UNITNAME" "$CELLCASTNAME" "$CELLNAME" "$CASTTMPFILENAME" "$SUBCELLSTEMPFILENAME" $CELLNAME-blocks/castinfo.il $CELLNAME-blocks/$CELLNAME.cdl $EXTRACTFILENAME +else + CLASSPATH=$MYCLASSPATH /usr/intel/bin/java -Xmx$JAVAMEM -DHOME="$HOME" com.avlsi.tools.cadencize.Cadencize "$UNITNAME" "$CELLCASTNAME" "$CELLNAME" "$CASTTMPFILENAME" "$SUBCELLSTEMPFILENAME" $CELLNAME-blocks/castinfo.il +fi + +output "removing temp files" + +rm $CASTTMPFILENAME +rm $SUBCELLSTEMPFILENAME + +dirname=`pwd | rev | cut -d'/' -f1 | rev` +rm -f $HARDWARE_HOME/.cadencized + +SAFECELLNAME=`echo $CELLNAME | sed -e "s/(/%40/g ; s/)/%41/g ; s/,/%44/g"` + +echo "$HARDWARE_HOME/ADD7M/$dirname/$CELLNAME-blocks $dirname-$SAFECELLNAME $magtype" > $HARDWARE_HOME/.cadencized + +if [ "$NEEDPOPD" = "1" ] ; then + popd > /dev/null +fi + +foo="$HARDWARE_HOME/ADD7M/$dirname/$CELLNAME-blocks/castinfo.il" +footmp="$HARDWARE_HOME/ADD7M/$dirname/$CELLNAME-blocks/castinfo.tmp" +cat $foo | sed -e "s/,/][/g" > $footmp +mv $footmp $foo +foo="$HARDWARE_HOME/ADD7M/$dirname/$CELLNAME-blocks/$CELLNAME.il" +footmp="$HARDWARE_HOME/ADD7M/$dirname/$CELLNAME-blocks/$CELLNAME.tmp" +cat $foo | sed -e "s/%40/##28/g" | sed -e "s/%41/##29/g" > $footmp +mv $footmp $foo + diff --git a/async-toolkit/jtools/cad/java/scripts/cdl2aspice b/async-toolkit/jtools/cad/java/scripts/cdl2aspice new file mode 100755 index 0000000000..5dfe9082a9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/cdl2aspice @@ -0,0 +1,20 @@ +#! /bin/sh -p + +# +# Copyright 2001 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# author: Jesse Rosenstock +# + +# +# wrapper for convenient use of cdl2aspice +# handles setting of CLASSPATH and CAST_PATH +# + +CLASSPATH=$HOME/jars/antlr.jar:$HOME/jars/jcast.jar +export CLASSPATH + +exec /usr/intel/bin/java -Xmx256M -DHOME="$HOME" \ + com.avlsi.tools.cdl2aspice.CDL2Aspice "$@" diff --git a/async-toolkit/jtools/cad/java/scripts/csp2java b/async-toolkit/jtools/cad/java/scripts/csp2java new file mode 100755 index 0000000000..6ad833b205 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/csp2java @@ -0,0 +1,9 @@ +#!/bin/sh -- +# + +CLASSPATH=$HOME/jars/antlr.jar:$HOME/jars/csp2java.jar +export CLASSPATH + +exec /usr/intel/bin/java -Xmx256M -DHOME="$HOME" \ + com.avlsi.csp.csp2java.CSP2Java "$@" + diff --git a/async-toolkit/jtools/cad/java/scripts/ext2aspice b/async-toolkit/jtools/cad/java/scripts/ext2aspice new file mode 100755 index 0000000000..c02c5cc8b8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/ext2aspice @@ -0,0 +1,24 @@ +#! /bin/sh -p + +# +# Copyright 2000 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# author: Jesse Rosenstock +# + +# +# wrapper for convenient use of ext2aspice +# handles setting of CLASSPATH and CAST_PATH +# + +if [ $# != 1 ]; then + echo "Usage: $0 cellname" + exit 1 +fi + +CLASSPATH=$HOME/jars/jcast.jar ; export CLASSPATH + +exec /usr/intel/bin/java -Xmx256M -DHOME="$HOME" \ + com.avlsi.tools.ext2aspice.Ext2Aspice "$1" diff --git a/async-toolkit/jtools/cad/java/scripts/fakecadencize b/async-toolkit/jtools/cad/java/scripts/fakecadencize new file mode 100644 index 0000000000..94391d86a4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/fakecadencize @@ -0,0 +1,145 @@ +#!/bin/bash +# $Id$ + +function output() { + if [ "$VERBOSE" = "1" ]; then + echo "$1" + fi +} + +function usage() { + echo "Usage: cadencize cell" + echo + echo " -v: verbose" + echo " -o: do not overwrite existing .auto file" + echo " -f: take floorplanning info from mag file" + echo " -m: specify memory usage for java (ex 128M)" + echo " -d: debug mode( honor CLASSPATH )" + echo " -i: import hand layout from magic" + echo " -c: Generate cdl file" + exit 1 +} + +VERBOSE=0 +OVERWRITE=0 +FLOORPLAN=AUTO +DEBUG=0 +IMPORT=0 +CDLOUT=0 + +while getopts ":vofdhcm:i" opt; do + case $opt in + v ) VERBOSE=1 ;; + o ) OVERWRITE=0 ;; + f ) FLOORPLAN=MAG ;; + m ) JAVAMEM=$OPTARG ;; + d ) DEBUGMODE=1;; + i ) IMPORT=1;; + h ) usage ;; + c ) CDLOUT=1 ;; + \? ) usage + esac +done +shift $(($OPTIND - 1)) + +if [ -z "$1" ]; then + usage +fi + +CELLNAME=`basename $1` + +output "Cell name is $CELLNAME" + +mkdir $CELLNAME-blocks 2> /dev/null + +if [ `dirname $1` = "." ]; then + NEEDPOPD=0 + UNITNAME=`pwd` + UNITNAME=`basename $UNITNAME` + CELLDIRNAME="." +else + NEEDPOPD=1 + + output "Looking up cell dir." + + CELLDIRNAME=`new_fc -dC $1` + + output "Cell dir is: $CELLDIRNAME" + + UNITNAME=`dirname $1` + + output "Cell unit is: $UNITNAME" + + CELLDIRNAME="$CELLDIRNAME/$1" + + + + CELLDIRNAME=`dirname $CELLDIRNAME` + pushd $CELLDIRNAME > /dev/null +fi + +output "Verbose mode" + +if [ ! -e $HARDWARE_HOME/cast/sram32/link_sram32.cast ]; then + output "Creating link to real_sram32.cast" + ln -s $HARDWARE_HOME/cast/sram32/real_sram32.cast $HARDWARE_HOME/cast/sram32/link_sram32.cast +fi + +output "finding cast file" + +CELLCASTFILE="`stlookup -c -p $CELLNAME`" +CELLCASTNAME="`stlookup -c $CELLNAME`" + +# ensure that there is only one cast file +if [ `echo "$CELLCASTFILE" | wc -l` != 1 ]; then + echo "Multiple cast files found for $CELLNAME:" + echo "$CELLCASTFILE" + exit 2 +fi + +if [ -z $CELLCASTFILE ] ; then + echo "Unable to get cast file for $CELLNAME." + exit 1 +fi + + +output "found cell $CELLCASTNAME in file $CELLCASTFILE" + + +MYCLASSPATH=$HOME/jars/jcast.jar:$HOME/jars/antlr.jar + +if [ "$DEBUGMODE" = "1" ] ; then + MYCLASSPATH=$CLASSPATH + +fi + +#TMPFILENAME=`date -u +"/tmp/%d-%m-%Y-%H-%M-%S-cadencize-$USER"` +CASTTMPFILENAME="tmp.$$.0" + +output "creating cast temp file $TMPFILENAME" + +cat $CELLCASTFILE > $CASTTMPFILENAME +echo "$CELLCASTNAME cadencize_inst ;" >> $CASTTMPFILENAME + + + +output "creating extract files" +output "running java cadencize" + +if [ -z "$JAVAMEM" ]; then + JAVAMEM=128M +fi +if [ "$CDLOUT" = "1" ]; then + output "creating extract files" + magicextract "$UNITNAME/$CELLNAME" &>/dev/null + EXTRACTFILENAME="$CELLDIRNAME/$CELLNAME.ext" + output "Extract file name is $EXTRACTFILENAME" + echo \"$UNITNAME\" \"$CELLCASTNAME\" \"$CELLNAME\" \"$CASTTMPFILENAME\" \"$SUBCELLSTEMPFILENAME\" $CELLNAME-blocks/castinfo.il $CELLNAME-blocks/$CELLNAME.cdl $EXTRACTFILENAME +else + echo \"$UNITNAME\" \"$CELLCASTNAME\" \"$CELLNAME\" \"$CASTTMPFILENAME\" \"$SUBCELLSTEMPFILENAME\" $CELLNAME-blocks/castinfo.il +fi + +output "removing temp files" + +rm $CASTTMPFILENAME + diff --git a/async-toolkit/jtools/cad/java/scripts/fulcrum-java.sh.template b/async-toolkit/jtools/cad/java/scripts/fulcrum-java.sh.template new file mode 100644 index 0000000000..060819c845 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/fulcrum-java.sh.template @@ -0,0 +1,323 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# this comment is to add the pdk to the command line +# fulcrum-pdk-root + +function exit_func() { + if [ -f "$strace_dump" ] ; then + rm -f $strace_dump + fi +} + +trap exit_func EXIT + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} + +app_name=$appname$ + + +os_type=`uname -s` + +arch_type=`uname -m` + +grepcmd=`which grep` +sedcmd=`which sed` + + +verbose= +jre_to_use="/usr/intel/pkgs/java/1.6.0.25-64"; +jre_args= +max_heap_size=384m +min_heap_size= +run_debugger= +debug_suspend=1 +terminal= +debug_env=0 +class_cache= +strace_output= +strace_dep_target= +strace_regex='"*"' +d64= + +command_args= +for arg in "$@" ; do + + case "$arg" in + --script-verbose ) + verbose=1 + ;; + --jre=* ) + jre_to_use=`echo $arg | $sedcmd -e "s/--jre=//"` + ;; + --jre-args=* ) + jre_args=`echo $arg | $sedcmd -e "s/--jre-args=//"` + ;; + --max-heap-size=* ) + max_heap_size=`echo $arg | $sedcmd -e "s/--max-heap-size=//"` + ;; + --min-heap-size=* ) + min_heap_size=`echo $arg | $sedcmd -e "s/--min-heap-size=//"` + ;; + --64 ) + d64=1 + ;; + --strace-regex=* ) + strace_regex=`echo $arg | $sedcmd -e "s/--strace-regex=//"` + ;; + --strace-output=* ) + strace_output=`echo $arg | $sedcmd -e "s/--strace-output=//"` + ;; + --strace-dep-target=* ) + strace_dep_target=`echo $arg | $sedcmd -e "s/--strace-dep-target=//"` + ;; + --run-debugger ) + run_debugger=1 + ;; + --no-suspend-debugger ) + debug_suspend=0 + ;; + --terminal=* ) + terminal=`echo $arg | $sedcmd -e "s/--terminal=//"` + ;; + --debug-environment ) + debug_env=1 + ;; + --class-cache=* ) + class_cache=`echo $arg | $sedcmd -e "s/--class-cache=//"` + ;; + * ) + if [ -n "$command_args" ] ; then + command_args="$command_args \"$arg\"" + else + command_args="\"$arg\"" + fi + ;; + esac +done + +if [ -d $package_root/$os_type-$arch_type/lib ] ; then + libs_in_package=`find $package_root/$os_type-$arch_type/lib -follow -name "*.so" -type f` +else + libs_in_package= +fi + +if [ -n "$verbose" ] ; then + echo "Libraries in package:" + for lib in $libs_in_package ; do + echo $lib + done + echo "" +fi + +#case "$arch_type" in +# i?86 ) +# preload_libs="$jre_to_use/lib/i386/libjsig.so $preload_libs" +# ;; +#esac + +pre_load_str= +pre_load_list= +for lib in $preload_libs ; do + if [ -f $lib ] ; then + pre_load_str="$lib:$pre_load_str" + pre_load_list="$pre_load_list $lib" + fi +done + +if [ -n "$verbose" ] ; then + echo "Libraries to preload:" + for lib in $pre_load_list ; do + echo $lib + done + echo "" +fi + + +jarroot="$package_root/share/java" +# antlr jar handling + +antlr_jar= + +if [ -z $ANTLR_JAR ] ; then + antlr_jar=$jarroot/antlr-2.7.2.jar +else + antlr_jar=$ANTLR_JAR +fi + +if [ -n "$verbose" ] ; then + echo "Antlr JAR file is \"$antlr_jar\"." +fi + +# concurrent util jar handling + +concurrent_jar= + +if [ -z $CONCURRENT_JAR ] ; then + concurrent_jar=$jarroot/concurrent.jar +else + concurrent_jar=$CONCURRENT_JAR +fi + +if [ -n "$verbose" ] ; then + echo "Concurrent util JAR file is \"$concurrent_jar\"." +fi + +# stringtemplate jar handling + +stringtemplate_jar= + +if [ -z $STRINGTEMPLATE_JAR ] ; then + stringtemplate_jar=$jarroot/stringtemplate.jar +else + stringtemplate_jar=$STRINGTEMPLATE_JAR +fi + +if [ -n "$verbose" ] ; then + echo "stringtemplate JAR file is \"$stringtemplate_jar\"." +fi + +# tools jar handling + +tools_jar= + +if [ -z $TOOLS_JAR ] ; then + tools_jar="$jarroot/tools.jar" +else + tools_jar=$TOOLS_JAR +fi + +if [ -n "$verbose" ] ; then + echo "tools JAR file is \"$tools_jar\"." +fi + +jars_in_package= + +if [ -d "$jarroot" ] ; then + jars_in_package=`find "$jarroot" -follow -name "*.jar" "(" -type f -o -type l ")"` +fi + +if [ -n "$verbose" ] ; then + echo "Jars in package:" + for jar in $jars_in_package ; do + echo $jar + done + echo "" +fi + +class_path=$antlr_jar:$concurrent_jar:$stringtemplate_jar:$tools_jar + +if [ -n "$class_cache" ] ; then + class_path="$class_path:$class_cache" +fi + +for jar in $jars_in_package ; do + class_path="$class_path:$jar" +done + +if [ -n "$verbose" ] ; then + echo "CLASSPATH is \"$class_path\"." +fi + +if [ "$arch_type" == "x86_64" ]; then + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib:/usr/lib64:/lib64" +elif [ "$os_type" == "SunOS" ]; then + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib/sparcv9:/usr/lib/64:/lib/64" +else + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib:/usr/lib:/lib" +fi + +if [ -n "$pre_load_str" ] ; then + exec_str="$exec_str LD_PRELOAD=$pre_load_str" +fi + +if [ -n "$terminal" ] ; then + TERM=$terminal + export TERM + exec_str="$exec_str TERM=$terminal" +fi + +if [ -n "$strace_output" ] ; then + strace_dump=`mktemp /tmp/strace.XXXXXX` + if [ "$os_type" == "SunOS" ] ; then + trace_cmd="truss -o $strace_dump -t open -t _exit" + elif [ "$os_type" == "Linux" ] ; then + trace_cmd="strace -o $strace_dump -e trace=open,_exit" + fi + exec_str="$exec_str $trace_cmd" +fi + +if [[ "$debug_env" == "1" ]] ; then + print_env_str="$exec_str printenv" +fi + +exec_str="$exec_str $jre_to_use/bin/java" + +if [ -n "$max_heap_size" ] ; then + exec_str="$exec_str -Xmx$max_heap_size" +fi + +if [[ "$os_type" == "SunOS" ]] ; then + exec_str="$exec_str -d64" +fi + +if [ -n "$min_heap_size" ] ; then + exec_str="$exec_str -Xms$min_heap_size" +fi + +if [ -n "$run_debugger" ] ; then + + debug_str="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y" + + if [[ "$debug_suspend" == "1" ]] ; then + debug_str="$debug_str,suspend=y" + else + debug_str="$debug_str,suspend=n" + fi + exec_str="$exec_str $debug_str" +fi + +exec_str="$exec_str -Djava.util.logging.config.class=com.avlsi.util.logging.Configurator" + +if [ -n "$class_path" ] ; then + exec_str="$exec_str -classpath $class_path" +fi + +if [ -n "$jre_args" ] ; then + exec_str="$exec_str $jre_args" +fi + +exec_str="$exec_str $app_name \"--package-root=$package_root\" $command_args" + +if [ -n "$verbose" ] ; then + echo "eval $exec_str" +fi + +eval $exec_str +ret=$? + +if [[ "$debug_env" == "1" ]] ; then + if [ -n "$verbose" ] ; then + echo "eval $print_env_str" + fi + eval $print_env_str +fi + +if [ -n "$strace_output" ] ; then + cat "$strace_dump" | $grepcmd "$strace_regex" | $sedcmd -e "s/open(\"\(.*\)\".*/\1/" > "$strace_output" + ret=$(grep "^_exit" "$strace_dump" | sed -e "s/_exit(\([0-9]*\)).*/\1/" ) + if [ -n "$strace_dep_target" ] ; then + echo -n 'AUTODEP_TARGET_FILES := ' > "$strace_dump" + echo "$strace_dep_target" | sed -e "s/\#/\\\#/g" >> "$strace_dump" + echo -n '$(AUTODEP_TARGET_FILES): ' >> "$strace_dump" + cat "$strace_output" | $grepcmd -v "$strace_dep_target" | sed -e "s/\#/\\\#/g" | awk '{print $1 "\\"}' >> "$strace_dump" + echo '' >> "$strace_dump" + cp "$strace_dump" "$strace_output" + fi +fi + +exit $ret diff --git a/async-toolkit/jtools/cad/java/scripts/fulcrum-rename.sh.template b/async-toolkit/jtools/cad/java/scripts/fulcrum-rename.sh.template new file mode 100644 index 0000000000..2672ad47f4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/fulcrum-rename.sh.template @@ -0,0 +1,323 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +# this comment is to add the pdk to the command line +# fulcrum-pdk-root + +function exit_func() { + if [ -f "$strace_dump" ] ; then + rm -f $strace_dump + fi +} + +trap exit_func EXIT + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} + +app_name=$appname$ + + +os_type=`uname -s` + +arch_type=`uname -m` + +grepcmd=`which grep` +sedcmd=`which sed` + + +verbose= +jre_to_use="/usr/intel/pkgs/java/1.6.0.10-64"; +jre_args= +max_heap_size=80m +min_heap_size= +run_debugger= +debug_suspend=1 +terminal= +debug_env=0 +class_cache= +strace_output= +strace_dep_target= +strace_regex='"*"' +d64= + +command_args= +for arg in "$@" ; do + + case "$arg" in + --script-verbose ) + verbose=1 + ;; + --jre=* ) + jre_to_use=`echo $arg | $sedcmd -e "s/--jre=//"` + ;; + --jre-args=* ) + jre_args=`echo $arg | $sedcmd -e "s/--jre-args=//"` + ;; + --max-heap-size=* ) + max_heap_size=`echo $arg | $sedcmd -e "s/--max-heap-size=//"` + ;; + --min-heap-size=* ) + min_heap_size=`echo $arg | $sedcmd -e "s/--min-heap-size=//"` + ;; + --64 ) + d64=1 + ;; + --strace-regex=* ) + strace_regex=`echo $arg | $sedcmd -e "s/--strace-regex=//"` + ;; + --strace-output=* ) + strace_output=`echo $arg | $sedcmd -e "s/--strace-output=//"` + ;; + --strace-dep-target=* ) + strace_dep_target=`echo $arg | $sedcmd -e "s/--strace-dep-target=//"` + ;; + --run-debugger ) + run_debugger=1 + ;; + --no-suspend-debugger ) + debug_suspend=0 + ;; + --terminal=* ) + terminal=`echo $arg | $sedcmd -e "s/--terminal=//"` + ;; + --debug-environment ) + debug_env=1 + ;; + --class-cache=* ) + class_cache=`echo $arg | $sedcmd -e "s/--class-cache=//"` + ;; + * ) + if [ -n "$command_args" ] ; then + command_args="$command_args \"$arg\"" + else + command_args="\"$arg\"" + fi + ;; + esac +done + +if [ -d $package_root/$os_type-$arch_type/lib ] ; then + libs_in_package=`find $package_root/$os_type-$arch_type/lib -follow -name "*.so" -type f` +else + libs_in_package= +fi + +if [ -n "$verbose" ] ; then + echo "Libraries in package:" + for lib in $libs_in_package ; do + echo $lib + done + echo "" +fi + +#case "$arch_type" in +# i?86 ) +# preload_libs="$jre_to_use/lib/i386/libjsig.so $preload_libs" +# ;; +#esac + +pre_load_str= +pre_load_list= +for lib in $preload_libs ; do + if [ -f $lib ] ; then + pre_load_str="$lib:$pre_load_str" + pre_load_list="$pre_load_list $lib" + fi +done + +if [ -n "$verbose" ] ; then + echo "Libraries to preload:" + for lib in $pre_load_list ; do + echo $lib + done + echo "" +fi + + +jarroot="$package_root/share/java" +# antlr jar handling + +antlr_jar= + +if [ -z $ANTLR_JAR ] ; then + antlr_jar=$jarroot/antlr-2.7.2.jar +else + antlr_jar=$ANTLR_JAR +fi + +if [ -n "$verbose" ] ; then + echo "Antlr JAR file is \"$antlr_jar\"." +fi + +# concurrent util jar handling + +concurrent_jar= + +if [ -z $CONCURRENT_JAR ] ; then + concurrent_jar=$jarroot/concurrent.jar +else + concurrent_jar=$CONCURRENT_JAR +fi + +if [ -n "$verbose" ] ; then + echo "Concurrent util JAR file is \"$concurrent_jar\"." +fi + +# stringtemplate jar handling + +stringtemplate_jar= + +if [ -z $STRINGTEMPLATE_JAR ] ; then + stringtemplate_jar=$jarroot/stringtemplate.jar +else + stringtemplate_jar=$STRINGTEMPLATE_JAR +fi + +if [ -n "$verbose" ] ; then + echo "stringtemplate JAR file is \"$stringtemplate_jar\"." +fi + +# tools jar handling + +tools_jar= + +if [ -z $TOOLS_JAR ] ; then + tools_jar="$jarroot/tools.jar" +else + tools_jar=$TOOLS_JAR +fi + +if [ -n "$verbose" ] ; then + echo "tools JAR file is \"$tools_jar\"." +fi + +jars_in_package= + +if [ -d "$jarroot" ] ; then + jars_in_package=`find "$jarroot" -follow -name "*.jar" "(" -type f -o -type l ")"` +fi + +if [ -n "$verbose" ] ; then + echo "Jars in package:" + for jar in $jars_in_package ; do + echo $jar + done + echo "" +fi + +class_path=$antlr_jar:$concurrent_jar:$stringtemplate_jar:$tools_jar + +if [ -n "$class_cache" ] ; then + class_path="$class_path:$class_cache" +fi + +for jar in $jars_in_package ; do + class_path="$class_path:$jar" +done + +if [ -n "$verbose" ] ; then + echo "CLASSPATH is \"$class_path\"." +fi + +if [ "$arch_type" == "x86_64" ]; then + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib:/usr/lib64:/lib64" +elif [ "$os_type" == "SunOS" ]; then + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib/sparcv9:/usr/lib/64:/lib/64" +else + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib:/usr/lib:/lib" +fi + +if [ -n "$pre_load_str" ] ; then + exec_str="$exec_str LD_PRELOAD=$pre_load_str" +fi + +if [ -n "$terminal" ] ; then + TERM=$terminal + export TERM + exec_str="$exec_str TERM=$terminal" +fi + +if [ -n "$strace_output" ] ; then + strace_dump=`mktemp /tmp/strace.XXXXXX` + if [ "$os_type" == "SunOS" ] ; then + trace_cmd="truss -o $strace_dump -t open -t _exit" + elif [ "$os_type" == "Linux" ] ; then + trace_cmd="strace -o $strace_dump -e trace=open,_exit" + fi + exec_str="$exec_str $trace_cmd" +fi + +if [[ "$debug_env" == "1" ]] ; then + print_env_str="$exec_str printenv" +fi + +exec_str="$exec_str $jre_to_use/bin/java" + +if [ -n "$max_heap_size" ] ; then + exec_str="$exec_str -Xmx$max_heap_size" +fi + +if [[ "$os_type" == "SunOS" ]] ; then + exec_str="$exec_str -d64" +fi + +if [ -n "$min_heap_size" ] ; then + exec_str="$exec_str -Xms$min_heap_size" +fi + +if [ -n "$run_debugger" ] ; then + + debug_str="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y" + + if [[ "$debug_suspend" == "1" ]] ; then + debug_str="$debug_str,suspend=y" + else + debug_str="$debug_str,suspend=n" + fi + exec_str="$exec_str $debug_str" +fi + +exec_str="$exec_str -Djava.util.logging.config.class=com.avlsi.util.logging.Configurator" + +if [ -n "$class_path" ] ; then + exec_str="$exec_str -classpath $class_path" +fi + +if [ -n "$jre_args" ] ; then + exec_str="$exec_str $jre_args" +fi + +exec_str="$exec_str $app_name \"--package-root=$package_root\" $command_args" + +if [ -n "$verbose" ] ; then + echo "eval $exec_str" +fi + +eval $exec_str +ret=$? + +if [[ "$debug_env" == "1" ]] ; then + if [ -n "$verbose" ] ; then + echo "eval $print_env_str" + fi + eval $print_env_str +fi + +if [ -n "$strace_output" ] ; then + cat "$strace_dump" | $grepcmd "$strace_regex" | $sedcmd -e "s/open(\"\(.*\)\".*/\1/" > "$strace_output" + ret=$(grep "^_exit" "$strace_dump" | sed -e "s/_exit(\([0-9]*\)).*/\1/" ) + if [ -n "$strace_dep_target" ] ; then + echo -n 'AUTODEP_TARGET_FILES := ' > "$strace_dump" + echo "$strace_dep_target" | sed -e "s/\#/\\\#/g" >> "$strace_dump" + echo -n '$(AUTODEP_TARGET_FILES): ' >> "$strace_dump" + cat "$strace_output" | $grepcmd -v "$strace_dep_target" | sed -e "s/\#/\\\#/g" | awk '{print $1 "\\"}' >> "$strace_dump" + echo '' >> "$strace_dump" + cp "$strace_dump" "$strace_output" + fi +fi + +exit $ret diff --git a/async-toolkit/jtools/cad/java/scripts/gen-build-id b/async-toolkit/jtools/cad/java/scripts/gen-build-id new file mode 100755 index 0000000000..46cbff9d11 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/gen-build-id @@ -0,0 +1,2 @@ +#!/bin/sh +echo `id -un`-`date +'%Y%m%d-%H%M%S' -u` diff --git a/async-toolkit/jtools/cad/java/scripts/grabRegisterData.pl b/async-toolkit/jtools/cad/java/scripts/grabRegisterData.pl new file mode 100755 index 0000000000..3dea237018 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/grabRegisterData.pl @@ -0,0 +1,115 @@ +#!/usr/intel/bin/perl + +## This script siphons data printed by tsim for that generated by +## Reg4.java and prints that data in a more useful format. It doesn't +## account for the different ending times of Reg4 blocks based on the +## last data each processes. + + +#Functions for taking fields of output lines +sub timestamp { + my @fields = split (/ +/,@_[0]); + chop($fields[0]); # Remove the colon + return $fields[0]; +} +sub instr { + my @fields = split (/ +/,@_[0]); + return $fields[2]; +} +sub reg { + my @fields = split (/ +/,@_[0]); + my @reg = split("reg=",(split "\t", $fields[3])[0]); + return $reg[1]; +} +sub stalltime { + my @fields = split (/ +/,@_[0]); + my @reg = split("time=",$fields[4]); + chomp $reg[1]; + return $reg[1]; +} +sub plainreads { + my @fields = split (/ +/,@_[0]); + my @reg = split("\t",$fields[7]); + return $reg[0]; +} +sub dupreads { + my @fields = split (/ +/,@_[0]); + my @reg = split("\t",$fields[8]); + return $reg[0]; +} +sub fullnesses { + my @fields = split (/ +/,@_[0]); + return join ("\t", (split ("\t",@fields[3]))[1..9]); +} + +if ($#ARGV != 0) { + die "usage:\tgrabRegisterdata.pl [filename of tsim output]\n"; +} + +$tsimOutputFile = $ARGV[0]; + +### Read in the output of tsim +open TSIM_OUTPUT, "< $tsimOutputFile" or die "can't open $tsimOutputFile"; +# Only check register lines +while () { + if (/REG/) { + @lines[$lineNum++] = $_; + } +} + +### Get read proportions +foreach $line (@lines) { + if (instr($line) eq "reads") { + $plain += plainreads($line); + $dup += dupreads($line); + } +} +print "$plain normal reads and $dup duplicating reads\n"; + +### Get fullness histograms for each register +@fullnesses; +foreach $line (@lines) { + if (instr($line) eq "fullness") { + $fullnesses[reg($line)] = fullnesses($line); + } +} + +print "amount of time each register spends containing n tokens\n"; +print "\t0\t1\t2\t3\t4\t5\t6\t7\t8\n"; +for ($i=0; $i<16; $i++) { + print "reg: $i\t$fullnesses[$i]"; +} + + + + + + +### Get all stalls +foreach $line (@lines) { + if (instr($line) eq "readstall") { + push @{$readstalls[reg($line)]}, stalltime($line); + } +} +print "Stall times while trying to read in data:\n"; +for ($i=0; $i<16; $i++) { + print "reg: $i\t"; + foreach $time (sort {$a <=> $b} (@{$readstalls[$i]})) { + print " $time"; + } + print "\n"; +} +foreach $line (@lines) { + if (instr($line) eq "writestall") { + push @{$writestalls[reg($line)]}, stalltime($line); + } +} +print "Stall times while trying to write out data:\n"; +for ($i=0; $i<16; $i++) { + print "reg: $i\t"; + foreach $time (sort {$a <=> $b} (@{$writestalls[$i]})) { + print " $time"; + } + print "\n"; +} + diff --git a/async-toolkit/jtools/cad/java/scripts/iosim b/async-toolkit/jtools/cad/java/scripts/iosim new file mode 100755 index 0000000000..af0540ea67 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/iosim @@ -0,0 +1,26 @@ +#! /bin/sh -p + +# +# Copyright 2000 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# author: Jesse Rosenstock +# + +# +# wrapper for convenient use of iosim +# handles setting of CLASSPATH and LD_LIBRARY_PATH +# + +if [ $# -lt 2 ]; then + echo "Usage: $0 module [modules ...] csimfile" + exit 1 +fi + +CLASSPATH=$HOME/jars/jcast.jar:${IOSIM_CLASSPATH}:. +export CLASSPATH +LD_LIBRARY_PATH=/usr/intel/jars/native:${LD_LIBRARY_PATH} +export LD_LIBRARY_PATH + +exec /usr/intel/bin/java -Diosim.class.path="${IOSIM_CLASSPATH}:." -Xmx256M com.avlsi.tools.iosim.IOSIM "$@" diff --git a/async-toolkit/jtools/cad/java/scripts/jauto b/async-toolkit/jtools/cad/java/scripts/jauto new file mode 100755 index 0000000000..d91ad3549f --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/jauto @@ -0,0 +1,9 @@ +#!/bin/sh +mkdir -p cdlout +cell="$2" +cast="$1" +shift 2 +java -DHOME=$HOME com.avlsi.tools.jauto.Jauto --noFloorplan \ + --castInRoot=.:/home/user/denney/hardware/cast:/home/user/denney/hardware/cast/standard:/usr/local/cad/cast \ + --cellName="$cell" --cdlRoot=cdlout --unitSize \ + --outRoot=cdlout --project=none "$cast" "$@" diff --git a/async-toolkit/jtools/cad/java/scripts/jauto_espresso b/async-toolkit/jtools/cad/java/scripts/jauto_espresso new file mode 100755 index 0000000000..2a70528990 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/jauto_espresso @@ -0,0 +1,5 @@ +#!/bin/csh +jflat --tool=auto --cell=$1 > $1.auto +auto_espresso $1.auto $1.auto +sed "s/<30> / /g" $1.auto | grep "\->" +rm $1.auto diff --git a/async-toolkit/jtools/cad/java/scripts/jespresso b/async-toolkit/jtools/cad/java/scripts/jespresso new file mode 100644 index 0000000000..2a70528990 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/jespresso @@ -0,0 +1,5 @@ +#!/bin/csh +jflat --tool=auto --cell=$1 > $1.auto +auto_espresso $1.auto $1.auto +sed "s/<30> / /g" $1.auto | grep "\->" +rm $1.auto diff --git a/async-toolkit/jtools/cad/java/scripts/jflat b/async-toolkit/jtools/cad/java/scripts/jflat new file mode 100755 index 0000000000..697373a8aa --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/jflat @@ -0,0 +1,19 @@ +#! /bin/sh -p + +# +# Copyright 2000 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# author: Jesse Rosenstock +# + +# +# wrapper for convenient use of jflat +# handles setting of CLASSPATH and CAST_PATH +# + +CLASSPATH=$HOME/jars/antlr.jar:$HOME/jars/jcast.jar ; export CLASSPATH + +exec /usr/intel/bin/java -Xmx256M -DHOME="$HOME" \ + com.avlsi.tools.jflat.JFlat "$@" diff --git a/async-toolkit/jtools/cad/java/scripts/jlvs b/async-toolkit/jtools/cad/java/scripts/jlvs new file mode 100755 index 0000000000..521693201f --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/jlvs @@ -0,0 +1,67 @@ +#! /bin/zsh + +# +# Copyright 2001 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# author: Jesse Rosenstock +# + +# +# wrapper for convenient use of lvs +# handles setting of CLASSPATH, and instantiating cell to be lvs'd +# + +layout_dir=$HOME/hardware/ADD7M +cast_dir=$HOME/hardware/cast + +# -d option to use original classpath +if [ x"$1" = x-d ]; then + shift +else + CLASSPATH=$HOME/jars/antlr.jar:$HOME/jars/jcast.jar + export CLASSPATH +fi + + +# usage: lvs [ -d ] cast_file cast_cell +# ( --ext ext_file ext_cell +# | --cdl cdl_file cdl_cell ) + +if [ $# -le 4 ]; then + echo "Usage: $0 [ -d ] cast_file cast_cell " + echo " ( --ext ext_file ext_cell | --cdl cdl_file cdl_cell ) " + echo " [--noSubcells] [--noWires] [--noUnwired] [--noPrs]" + echo " [--minStaticizerRatio rmin] [--maxStaticizerRatio rmax]" + exit 1 +fi + +CASTFILE=`cast_which $1` +if [ x"$CASTFILE" = x ]; then + echo "Couldn't find $1" + exit 2 +fi + +# make cast file that instantiates cell, until we can do this in java +tmp_cast=`mktemp /tmp/jlvs.XXXXXX` +cat $CASTFILE > $tmp_cast +echo "$2 __lvs_instance__;" >> $tmp_cast + +# make file with all the subtype information in it +tmp_subtypes=`mktemp /tmp/jlvs.XXXXXX` +tmp_equivtypes=`mktemp /tmp/jlvs.XXXXXX` +find $layout_dir/. -name directives -or -name subtypes | xargs cat | \ + awk '/^[A-Za-z0-9_,(){}]+:/ { print $1 }' | sort -u > $tmp_subtypes +find $cast_dir/. -name equivtypes | xargs cat | sort -u > $tmp_equivtypes + +/usr/intel/bin/java -Xmx2G -DHOME="$HOME" \ + com.avlsi.tools.lvs.LVS "$tmp_cast" "$2" "$3" "$4" "$5" \ + "$tmp_subtypes" "$tmp_equivtypes" "$6" "$7" "$8" "$9" "$10" "$11" +lvs_status=$? + +rm -f $tmp_cast +rm -f $tmp_subtypes +rm -f $tmp_equivtypes + +exit $lvs_status diff --git a/async-toolkit/jtools/cad/java/scripts/make_subdir_makefile b/async-toolkit/jtools/cad/java/scripts/make_subdir_makefile new file mode 100755 index 0000000000..0c6e1b0283 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/make_subdir_makefile @@ -0,0 +1,42 @@ +#! /bin/sh + +# +# Copyright 2000 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# Author: Jesse Rosenstock +# Version: $Name: $ $Date$ +# + +subdirname="$1" +[ -n "$subdirname" ] && cd $subdirname +up=`echo $subdirname | sed -e 's:[^/]\+:..:g'` +classesname=`echo $subdirname | sed -e 's:src:classes:g'` + +cat > Makefile << EOF +# AUTOGENERATED FILE -- DO NOT EDIT!!! +default: + @\$(MAKE) -C $up + +# AUTOGENERATED FILE -- DO NOT EDIT!!! +tags: + @\$(MAKE) -C $up "$subdirname/\$@" + +# AUTOGENERATED FILE -- DO NOT EDIT!!! +some %/some: + @\$(MAKE) -C $up "$subdirname/\$@" + +# AUTOGENERATED FILE -- DO NOT EDIT!!! +%.class: + @\$(MAKE) -C $up "$classesname/\$@" + +# AUTOGENERATED FILE -- DO NOT EDIT!!! +%:: + @\$(MAKE) -C $up "\$@" + +# AUTOGENERATED FILE -- DO NOT EDIT!!! +EOF + +# the last is not a valid subdirectory target, so we pass it up, and +# hope it is a valid top level target. diff --git a/async-toolkit/jtools/cad/java/scripts/mgn b/async-toolkit/jtools/cad/java/scripts/mgn new file mode 100755 index 0000000000..894830a7d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/mgn @@ -0,0 +1,34 @@ +#! /bin/zsh + +# -d option to use original classpath +if [ x"$1" = x-d ]; then + shift +else + CLASSPATH=$HOME/jars/antlr.jar:$HOME/jars/jcast.jar + export CLASSPATH +fi + +if [ $# -lt 2 ]; then + echo "Usage: $0 cast_file cast_cell [more]" + exit 1 +fi + +CASTFILE=`cast_which $1` +if [ x"$CASTFILE" = x ]; then + echo "Couldn't find $1" + exit 2 +fi +shift + +# make cast file that instantiates cell, until we can do this in java +tmp_cast=`mktemp /tmp/jlvs.XXXXXX` +cat $CASTFILE > $tmp_cast +echo "$1 __lvs_instance__;" >> $tmp_cast + +/usr/intel/bin/java -Xmx256M -DHOME="$HOME" \ + com.avlsi.tools.lvs.PrsToNet "$tmp_cast" $* +lvs_status=$? + +rm -f $tmp_cast + +exit $lvs_status diff --git a/async-toolkit/jtools/cad/java/scripts/mips-dis b/async-toolkit/jtools/cad/java/scripts/mips-dis new file mode 100755 index 0000000000..e758f4351a --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/mips-dis @@ -0,0 +1 @@ +java com.avlsi.tools.tsim.mips32.Instruction --disassemble --binary-image --big-endian $1 $2 diff --git a/async-toolkit/jtools/cad/java/scripts/output-source-files b/async-toolkit/jtools/cad/java/scripts/output-source-files new file mode 100755 index 0000000000..8aedac29be --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/output-source-files @@ -0,0 +1,3 @@ +#!/bin/zsh +p4 files 'src/...#have' 'Makefile#have' 'scripts/...#have' \ + 'build/...#have' 'custom.mk#have' | awk '{ print $1 }' diff --git a/async-toolkit/jtools/cad/java/scripts/run-all-tests b/async-toolkit/jtools/cad/java/scripts/run-all-tests new file mode 100755 index 0000000000..696edea9ce --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/run-all-tests @@ -0,0 +1,45 @@ +#!/bin/zsh +# +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# +# $Id$ +# +# Author: Aaron Denney +# +# See http://internal/~denney/software-regression-test-harness/ +# +# Zsh necessary for the coprocess, which is necessary to get the status +# of the test rather than the awk filter. +# +location=$1 +if [ -z "$location" ]; then + location=`pwd`/classes +fi +subset=$2 +if [ -z "$subset" ]; then + subset=tests +fi +testroot=`pwd`/tests +logfile=report +finalstatus=0 +failures=0 +successes=0 +testscripts=(`find $subset -name 'run-this-test' -perm -a+x`) +for i in ${testscripts}; do + testname=`dirname $i` + coproc awk "{ print ${testname} \$0 }" >> ${logfile} + (cd $testname; exec env - ./run-this-test ${location} ${testroot}) >& /dev/null 3>&p + testresult=$? + coproc exit + + if [ $testresult != 0 ]; then + echo "$testname failed" + failures=`expr $failures + 1` + else + echo "$testname passed" + successes=`expr $successes + 1` + fi; + finalstatus=`expr $finalstatus '|' $testresult` +done +echo "$failures failures, $successes successes" +exit $finalstatus diff --git a/async-toolkit/jtools/cad/java/scripts/run-one-test b/async-toolkit/jtools/cad/java/scripts/run-one-test new file mode 100755 index 0000000000..e44f5922a2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/scripts/run-one-test @@ -0,0 +1,30 @@ +#!/bin/sh + +# +# Copyright 2000 Asynchronous Digital Design. All rights reserved. +# +# $Id$ +# +# author: Aaron Denney +# +# runs one test. See +# http://internal/~denney/software-regression-test-harness/ + +testname="$1" +location="$2" +if [ -z "$location" ]; then + location=`pwd`/classes +fi +testroot=`pwd`/classes +if [ ! -x "${testname}/run-this-test" ]; then + echo "No such test $testname" + exit 2 +fi +(cd ${testname}; env - ./run-this-test ${location} ${testroot}) 3>&1 +if [ $? != 0 ]; then + echo test failed + exit 1 +else + echo test succeeded + exit 0 +fi diff --git a/async-toolkit/jtools/cad/java/src/cfiles-custom.mk b/async-toolkit/jtools/cad/java/src/cfiles-custom.mk new file mode 100644 index 0000000000..77add26d26 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/cfiles-custom.mk @@ -0,0 +1,6 @@ +CFILES_COMPILER := $(GCC) +CFILES_PREPROCESSOR := $(CFILES_COMPILER) -E +CFILES_C_COMPILE_FLAGS := -fpic +ifeq ($(MAKEFILE_KERNEL_NAME),SunOS) + CFILES_C_COMPILE_FLAGS += -m64 +endif diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/benchmarks/JavaSyncCost.java b/async-toolkit/jtools/cad/java/src/com/avlsi/benchmarks/JavaSyncCost.java new file mode 100644 index 0000000000..35855dd631 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/benchmarks/JavaSyncCost.java @@ -0,0 +1,364 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.benchmarks; + +import EDU.oswego.cs.dl.util.concurrent.*; +import com.avlsi.util.debug.Debug; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.util.Random; + +/** + *

    Measure the cost of context switching on various kinds of synchronization + * constructs in Java.

    + * + * @author Joseph Kiniry + * @version $Revision$ $Date$ + **/ + +public class JavaSyncCost implements Runnable +{ + // Static Private Attributes + + private static final boolean DEBUG = false; + + private static Mutex mutex = new Mutex(); + private static CyclicBarrier barrier; + private static Semaphore semaphore = new Semaphore(1); + + private static final byte NONE = -1, + MUTEX = 0, BARRIER = 1, SEMAPHORE = 2, + SYNCBLOCK = 3, SYNCMETHOD = 4, WAITNOTIFY = 5, PIPE = 6; + private static final long COUNTS_PER_TEST = 10000; + private static final long TOTAL_NUMBER_OF_TESTS = 10; + private static final long MICROSECONDS_PER_MILLISECOND = 1000; + private static byte testType; + private static volatile boolean headerPrinted = false, resultPrinted = false; + private static int numThreads = 2; + private static Random random = new Random(); + + + // Private Attributes + + private long counter = 0; + private long startTime = System.currentTimeMillis(); + private long runTime = 0; + private DecimalFormat formatter = new DecimalFormat("###,###,###.##"); + private int threadNumber; + + private double cost = 0.0; + private double totalCost = 0.0; + private double costPerOperationInMicrosections = 0.0; + + + // Constructors + + public JavaSyncCost(byte type, int threadNumber) + { + this.testType = type; + this.threadNumber = threadNumber; + } + + // Public Methods + + // Inner computation loop. + + public synchronized void synchronizedCompute() + { + compute(); + } + + public void compute() + { + counter++; + if (counter % COUNTS_PER_TEST == 0) { + runTime = System.currentTimeMillis() - startTime; + costPerOperationInMicrosections = + (double)runTime / COUNTS_PER_TEST * MICROSECONDS_PER_MILLISECOND; + totalCost += costPerOperationInMicrosections; + if (DEBUG) { + System.out.println(COUNTS_PER_TEST + " operations in " + + formatter.format(runTime) + + "ms = cost of " + + formatter.format(costPerOperationInMicrosections) + + "us"); + System.out.println("Total cost thus far: " + + formatter.format(totalCost) + "us"); + } + startTime = System.currentTimeMillis(); + } + if (counter > TOTAL_NUMBER_OF_TESTS * COUNTS_PER_TEST) + printTestResult(); + } + + synchronized void printTestResult() + { + if (!resultPrinted) { + resultPrinted = true; + System.out.println("Average cost: " + + formatter.format(totalCost/(double)TOTAL_NUMBER_OF_TESTS) + "us"); + System.exit(0); + } + } + + synchronized void printTestHeader(String testName) + { + if (!headerPrinted) { + headerPrinted = true; + System.out.println("Running " + testName + " test."); + } + } + + public void mutexTest() + { + printTestHeader("mutex"); + + while (true) { + try { + mutex.acquire(); + try { + compute(); + } finally { + mutex.release(); + } + } catch (InterruptedException ie) { + Debug.log("A thread was interrupted."); + } + } + } + + public void barrierTest() + { + printTestHeader("barrier"); + + while (true) { + try { + barrier.barrier(); + compute(); + } catch (BrokenBarrierException bbe) { + Debug.log("A barrier was broken."); + } catch (InterruptedException ie) { + Debug.log("A thread was interrupted."); + } + } + } + + public void semaphoreTest() + { + printTestHeader("semaphore"); + + while (true) { + try { + semaphore.acquire(); + compute(); + semaphore.release(); + } catch (InterruptedException ie) { + Debug.log("A thread was interrupted."); + } + } + } + + public void synchronizedBlockTest() + { + printTestHeader("synchronized block"); + + while (true) { + synchronized(JavaSyncCost.class) { + compute(); + } + } + } + + public void synchronizedMethodTest() + { + printTestHeader("synchronized method"); + + while (true) { + synchronizedCompute(); + } + } + + // @todo kiniry 15 Aug 2002 - Not yet correct or working. + + public void waitNotifyTest() + { + printTestHeader("wait-notify"); + } + + public void pipeTest() throws IOException, ClassNotFoundException + { + printTestHeader("pipe"); + + if (DEBUG) + System.out.println("Current counter = " + counter + "\n" + + "Thread number = " + threadNumber); + + // Build two pipes through which the threads can communicate. + PipedOutputStream posZero = new PipedOutputStream(); + PipedOutputStream posOne = new PipedOutputStream(); + PipedInputStream pisZero = new PipedInputStream(posZero); + PipedInputStream pisOne = new PipedInputStream(posOne); + ObjectOutputStream oosZero = new ObjectOutputStream(posZero); + ObjectOutputStream oosOne = new ObjectOutputStream(posOne); + ObjectInputStream oisZero = new ObjectInputStream(pisZero); + ObjectInputStream oisOne = new ObjectInputStream(pisOne); + + if (DEBUG) + System.out.println("Built channels."); + + // +-----------+ +-----------+ + // | Process 0 |-->oosZero-->posZero-->pisZero-->oisZero-->| Process 1 | + // | |<--oisOne<---pisOne<---posOne<---oosOne<---| | + // +-----------+ +-----------+ + + BigInteger message = new BigInteger(64, new Random()); + if (threadNumber == 0) { + if (DEBUG) + System.out.println("Zero starts sending."); + + // Process/Thread 0 starts things off. + while (true) { + oosZero.writeObject(message); + oosZero.flush(); + message = (BigInteger)oisOne.readObject(); + } + } else { + if (DEBUG) + System.out.println("One starts receiving."); + + // Process/Thread One + while (true) { + message = (BigInteger)oisZero.readObject(); + oosOne.writeObject(message); + oosOne.flush(); + compute(); + } + } + } + + /** + * Run method of test. Eternally attempt to acquire and release a mutex as + * quickly as possible. + **/ + + public void run() + { + switch (testType) { + case MUTEX: + mutexTest(); + break; + case BARRIER: + barrierTest(); + break; + case SEMAPHORE: + semaphoreTest(); + break; + case SYNCBLOCK: + synchronizedBlockTest(); + break; + case SYNCMETHOD: + synchronizedMethodTest(); + break; + case WAITNOTIFY: + waitNotifyTest(); + break; + case PIPE: + try { + pipeTest(); + } catch (Exception e) { + System.err.println("Pipe test failed: " + e.getMessage()); + System.exit(-1); + } + break; + } + } + + + // Static Methods + + /** + * Main method that sets up test. + * + * @param args command-line arguments. The first argument is the test + * name, the second is the number of threads that should be used in + * the test. If the arguments are not recognized, a usage message + * is printed. + * @exception InterruptedException if the main thread is interrupted. + **/ + + public static void main(String [] args) throws InterruptedException + { + byte testType = NONE; + + if ((args == null) || (args.length == 0)) + testType = BARRIER; + else if (args[0].compareToIgnoreCase("barrier") == 0) + testType = BARRIER; + else if (args[0].compareToIgnoreCase("mutex") == 0) + testType = MUTEX; + else if (args[0].compareToIgnoreCase("semaphore") == 0) + testType = SEMAPHORE; + else if (args[0].compareToIgnoreCase("syncblock") == 0) + testType = SYNCBLOCK; + else if (args[0].compareToIgnoreCase("syncmethod") == 0) + testType = SYNCMETHOD; + else if (args[0].compareToIgnoreCase("waitnotify") == 0) + testType = WAITNOTIFY; + else if (args[0].compareToIgnoreCase("pipe") == 0) + testType = PIPE; + else usage(); + + if (args != null) { + if (args.length >= 2) { + try { + numThreads = Integer.parseInt(args[1]); + } catch (NumberFormatException nfe) { + System.out.println(nfe.getMessage()); + usage(); + } + if (numThreads < 1) + numThreads = 1; + } + } + + if (DEBUG) + System.out.println("Running with " + numThreads + " thread(s)."); + + barrier = new CyclicBarrier(numThreads); + Thread [] threads = new Thread [numThreads]; + for (int i = 0; i < numThreads; i++) { + threads[i] = new Thread(new JavaSyncCost(testType, i)); + } + for (int i = 0; i < numThreads; i++) { + threads[i].start(); + } + } + + static void usage() + { + System.out.println("Usage: JavaSyncCost " + + "[barrier|mutex|semaphore|syncblock" + + "|syncmethod|waitnotify|pipe] " + + "[# threads}"); + System.out.println(" No parameters indicates a barrier " + + "test with 2 threads."); + } + +} // end of class JavaSyncCost + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastCacheManager.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastCacheManager.java new file mode 100644 index 0000000000..86e3477da1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastCacheManager.java @@ -0,0 +1,110 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast; + +import java.util.HashMap; +import java.util.Map; +import java.io.IOException; + +import com.avlsi.cast2.impl.CastParsingOption; +import com.avlsi.io.SearchPath; + +/** + * FREDERIK-UNDOCUMENTED + * + * @author Frederik Eaton + * @version $Revision$ $Date$ + **/ +public class CastCacheManager { + private static CastCacheManager def = null; + private CastFileParser appointed = null; + + /** cache can be a HashMap for the nonce, but we will want to use + * a specialized class for this data if it gets more + * complicated. **/ + HashMap cache; + + HashMap getData() { + if(cache == null) + cache = new HashMap(); + return cache; + } + + public static CastCacheManager getDefault() { + if (def == null) def = new CastCacheManager(); + return def; + } + + /** + * Return a cast file parser, using our common cache (if it + * exists). + * + * We could add more methods corresponding to other CastFileParser + * constructors, or to create CastParserEnvironment, but this is + * all that is currently needed. + **/ + public CastFileParser getCastFileParser(final SearchPath castPath, + String castVersion, + boolean verbose) + throws CastSemanticException, CastSyntaxException, + IOException { + return appointed == null ? + new CastFileParser(castPath, castVersion, verbose, getData()) + : appointed; + } + + public CastFileParser getCastFileParser(final SearchPath castPath, + String castVersion, + CastParsingOption opt) + throws CastSemanticException, CastSyntaxException, + IOException { + return getCastFileParser(castPath, castVersion, false, opt); + } + + public CastFileParser getCastFileParser(final SearchPath castPath, + String castVersion, + boolean verbose, + CastParsingOption opt) + throws CastSemanticException, CastSyntaxException, + IOException { + return appointed == null ? + new CastFileParser(castPath, castVersion, verbose, getData(), opt) + : appointed; + } + + public void setCastFileParser(final CastFileParser appointed) { + this.appointed = appointed; + } + + boolean neverClearCache = false; + + + /** + * Clear any caches. Used to save memory after parsing is done. + * + * @see com.avlsi.tools.jauto.Jauto + **/ + public void clearCache() { + if(!neverClearCache && cache != null) { + synchronized(cache) { + cache.clear(); + } + } + } + + /** + * Overrides the effects of clearCache. This is used when a tool + * which would normally clear the cast cache once or more in a + * single run, is being called multiple times from some meta-tool + * which desires to keep the cache intact for efficiency. This is + * not normally called by most tools. See JobServer for an + * example usage. + **/ + public void setNeverClear(boolean b) { + neverClearCache = b; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFile.java new file mode 100644 index 0000000000..7fe9f559b5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFile.java @@ -0,0 +1,180 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast; + +import java.util.Map.Entry; +import java.util.NoSuchElementException; + +import antlr.ASTFactory; +import antlr.RecognitionException; +import antlr.collections.AST; + +import com.avlsi.cast.impl.CastParserEnvironment; +import com.avlsi.cast.impl.AmbiguousLookupException; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentEntry; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.UserDefinedValue; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.InstanceValue; +import com.avlsi.cast.impl.SemanticWrapperException; + +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellInterface; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.file.common.HierName; + +import com.avlsi.cast.impl.CellInterfaceCollectionIterator; +import com.avlsi.cast.impl.EnvironmentIterator; + +/** + * Class to represent a parsed cast file. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CastFile { + private final Environment env; + + /** + * For the "no explicit instantiation" hack, the file needs to + * have an environment. + **/ + private final CastParserEnvironment cpe; + + /** + CellImpl that contains instantiations from the root environment of the cast file. + */ + private final CellImpl envCell; + + CastFile(final CastParserEnvironment cpe, final Environment env, final CellImpl envCell ) { + + this.cpe = cpe; + this.env = env; + this.envCell = envCell; + + } + + /** + * Get the cell interface for a user-defined cell instantiated in + * the file. + * + * [This is being added as a hack so that the regression test suite without + * env blocks will work with a corresponding CSP2Java hack. --dhilvert] + **/ + public CellInterface getCellForInstanceName(final String instanceName) { + try { + Value v; + InstanceValue iv; + CellInterface cell; + + v = env.lookup(Symbol.create(instanceName)); + assert v != null : "no such symbol: " + instanceName; + + if (!(v instanceof InstanceValue)) { + throw new AssertionFailure("Not an instance name."); + } + + iv = (InstanceValue) v; + cell = iv.getCell(); + + return cell; + + } catch (AmbiguousLookupException e) { + // XXX: should throw a real exception + throw (AssertionFailure) + new AssertionFailure("more than one such symbol") + .initCause(e); + } + } + + /** + * Get the cell interface for a cell defined in the file. + **/ + public CellInterface getCell(final String cellName) + throws CastSemanticException { + return getCell(cellName, null, null); + } + + /** + * Get the cell interface for a cell defined in the file. + **/ + public CellInterface getCell(final String cellName, CellImpl parent, + final HierName inst) + throws CastSemanticException { + try { + return cpe.getCell(env, cellName, parent, inst); + } catch (SemanticWrapperException e) { + throw new CastSemanticException(e.getCause(), + e.getFilename(), e.getLine(), e.getColumn()); + } + } + + public CellInterface getEnvironmentCell( ) { + return envCell; + } + + public final CellInterfaceCollectionIterator getAllCellsPossible( ) { + + + + return new CellInterfaceCollectionIterator() { + private final EnvironmentIterator m_EnvIter = env.iterator(); + + private UserDefinedValue m_nextUDV = null; + + private final void updateNextUDV() { + try { + while ( ( m_nextUDV == null ) && ( m_EnvIter.hasNext() ) ) { + final EnvironmentEntry currValue = m_EnvIter.next(); + if ( currValue.getValue() instanceof UserDefinedValue ) { + UserDefinedValue currUDV = ( UserDefinedValue ) currValue.getValue(); + + if ( ! currUDV.hasMetaParams() ) { + m_nextUDV = ( UserDefinedValue ) currValue.getValue(); + } + } + } + } + catch ( NoSuchElementException e ) { + throw (AssertionFailure) + new AssertionFailure + ( "Any iterator's next method failed even though"+ + " hasNext returned true." ).initCause(e); + } + } + + public final boolean hasNext() { + updateNextUDV(); + return m_nextUDV != null; + } + + public CellInterface next() throws CastSemanticException { + + updateNextUDV(); + if ( m_nextUDV != null ) { + final CellInterface ret = + getCell('"' + m_nextUDV.getCellTypeName() + '"'); + m_nextUDV = null; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + + }; + + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFileParser.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFileParser.java new file mode 100644 index 0000000000..a67869d94d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastFileParser.java @@ -0,0 +1,323 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.LinkedList; +import java.util.Map; + +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.TokenStreamRecognitionException; + +import com.avlsi.cast.impl.CastParserEnvironment; +import com.avlsi.cast.impl.CircularImportException; +import com.avlsi.cast.impl.SelfImportException; +import com.avlsi.cast.impl.SemanticWrapperException; +import com.avlsi.cast2.impl.CastParsingOption; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellImpl; +import com.avlsi.io.SearchPath; +import com.avlsi.io.SearchPathFile; +import com.avlsi.util.debug.Debug; +import com.avlsi.file.common.HierName; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; + +/** + * Parser for cast files. Adds some convenience to CastParserEnvironment. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CastFileParser { + public static final String defaultCastVersion = "2"; + /** + * The cast parser environment that stores the environment + * CellInterface, cast search path, and other globally needed + * information for the parsing. + **/ + final CastParserEnvironment cpe; + + /** + * Keeps track of which version of cast this parses. + **/ + private final String castVersion; + + /** + * Whether the cast 2 parser should warn of outdated syntax or + * not. Not used for the cast 1 parser. + **/ + private final boolean verbose; + + /** + * Returns a new CastSemanticException, with the specified + * detail message, using the file / line / col information + * from the specified RecognitionException. + **/ + private CastSemanticException castSemanticException( + final RecognitionException re) { + return new CastSemanticException(re, + re.getFilename(), re.getLine(), re.getColumn()); + } + + /** + * Returns a new CastSyntaxException, with the specified + * detail message, using the file / line / col information + * from the specified RecognitionException. + **/ + private CastSyntaxException castSyntaxException( + final RecognitionException re) { + return new CastSyntaxException(re, + re.getFilename(), re.getLine(), re.getColumn()); + } + + public CastFileParser(final SearchPath castPath) + throws CastSemanticException, + CastSyntaxException, + IOException { + this(castPath, "1"); + } + + public CastFileParser(final SearchPath castPath, + String castVersion) + throws CastSemanticException, + CastSyntaxException, + IOException { + this(castPath, castVersion, true); + } + + public CastFileParser(final SearchPath castPath, + String castVersion, + final CastParsingOption opt) + throws CastSemanticException, + CastSyntaxException, + IOException { + this(castPath, castVersion, true, null, opt); + } + + public CastFileParser(final SearchPath castPath, + String castVersion, + boolean verbose) + throws CastSemanticException, + CastSyntaxException, + IOException { + this(castPath, castVersion, verbose, null); + } + + public CastFileParser(final SearchPath castPath, + String castVersion, + boolean verbose, + Map importedEnvMap) + throws CastSemanticException, + CastSyntaxException, + IOException { + this(castPath, castVersion, verbose, importedEnvMap, null); + } + + public CastFileParser(final SearchPath castPath, + String castVersion, + boolean verbose, + Map importedEnvMap, + final CastParsingOption opt) + throws CastSemanticException, + CastSyntaxException, + IOException { + if (castVersion == null) castVersion = defaultCastVersion; + this.castVersion = castVersion; + this.verbose = verbose; + Debug.assertTrue(castVersion.equals("1") || castVersion.equals("2"), + "castversion "+castVersion+" not recognized"); + + try { + cpe = new CastParserEnvironment(castPath, "standard", + castVersion, verbose, + importedEnvMap, opt); + } catch (TokenStreamRecognitionException e) { + throw castSemanticException(e.recog); + } catch (RecognitionException e) { + throw castSyntaxException(e); + } catch (TokenStreamException e) { + throw new CastSyntaxException(e, "", 0, 0); + } catch (CircularImportException e) { + throw new CastSemanticException(e, "", 0, 0); + } + } + + /** + * Parse the given file. + **/ + public CastFile parse(final String fileName) + throws CastSemanticException, + CastSyntaxException, + IOException { + try { + final CellImpl envCell = new CellImpl("$env", null, + CellImpl.SYNTHETIC_CELL); + return new CastFile(cpe, + cpe.parseFile(fileName, new LinkedList(), envCell ), + envCell ); + } catch (TokenStreamRecognitionException e) { + throw castSemanticException(e.recog); + } catch (RecognitionException e) { + throw castSyntaxException(e); + } catch (TokenStreamException e) { + throw new CastSyntaxException(e, "", 0, 0); + } catch (CircularImportException e) { + throw new CastSemanticException(e, "", 0, 0); + } catch (SelfImportException e) { + throw new CastSemanticException(e, "", 0, 0); + } + } + + /** + * Parse the given file, bypassing the normal CAST searching mechanism. + **/ + public CastFile parse(final SearchPathFile file) + throws CastSemanticException, + CastSyntaxException, + IOException { + try { + final CellImpl envCell = new CellImpl("$env", null, + CellImpl.SYNTHETIC_CELL); + return new CastFile(cpe, + cpe.parseFile(file, new LinkedList(), envCell), + envCell); + } catch (TokenStreamRecognitionException e) { + throw castSemanticException(e.recog); + } catch (RecognitionException e) { + throw castSyntaxException(e); + } catch (TokenStreamException e) { + throw new CastSyntaxException(e, "", 0, 0); + } catch (CircularImportException e) { + throw new CastSemanticException(e, "", 0, 0); + } catch (SelfImportException e) { + throw new CastSemanticException(e, "", 0, 0); + } + } + + /** + * Parses the file that moduleName is defined in, searching + * all possible locations. + **/ + public CastFile parseModule(final String moduleName) + throws CastSemanticException, + CastSyntaxException, + IOException { + try { + final CellImpl envCell = new CellImpl("$env", null, + CellImpl.SYNTHETIC_CELL); + return new CastFile(cpe, + cpe.parseModule(new LinkedList(), envCell, moduleName), + envCell); + } catch (TokenStreamRecognitionException e) { + throw castSemanticException(e.recog); + } catch (RecognitionException e) { + throw castSyntaxException(e); + } catch (TokenStreamException e) { + throw new CastSyntaxException(e, + "", 0, 0); + } catch (CircularImportException e) { + throw new CastSemanticException(e, + "", 0, 0); + } catch (SelfImportException e) { + throw new CastSemanticException(e, + "", 0, 0); + } + } + + /** + * Takes a module name and cell name, returns the relevant + * CellInterface. Doesn't give any metaparameters. + **/ + public CellInterface getFullyQualifiedCell(String moduleName, + String cellName) + throws CastSemanticException { + return getFullyQualifiedCell(moduleName, cellName, null, null); + } + + /** + * Takes a module name and cell name, returns the relevant + * CellInterface. Doesn't give any metaparameters. + **/ + public CellInterface getFullyQualifiedCell(String moduleName, + String cellName, + CellImpl parent, + final HierName instance) + throws CastSemanticException { + + try { + return cpe.getFullyQualifiedCell( moduleName, cellName, parent, + instance ); + } catch (SemanticWrapperException e ) { + throw new CastSemanticException(e.getCause(), + e.getFilename(), e.getLine(), e.getColumn()); + } + + } + + public CellInterface getFullyQualifiedCell(String fullyQualifiedCellName) + throws CastSemanticException { + return getFullyQualifiedCell(fullyQualifiedCellName, null, null); + } + + public CellInterface getFullyQualifiedCellPretty( + String fullyQualifiedCellName) { + return getFullyQualifiedCellPretty(fullyQualifiedCellName, System.out); + } + + public CellInterface getFullyQualifiedCellPretty( + String fullyQualifiedCellName, PrintStream out) { + try { + return getFullyQualifiedCell(fullyQualifiedCellName); + } catch (CastSemanticException e) { + ExceptionPrettyPrinter.printException(e, out); + return null; + } + } + + public CellInterface getFullyQualifiedCellPretty( + String fullyQualifiedCellName, int exitStatus) { + return getFullyQualifiedCellPretty(fullyQualifiedCellName, System.out, + exitStatus); + } + + public CellInterface getFullyQualifiedCellPretty( + String fullyQualifiedCellName, PrintStream out, int exitStatus) { + final CellInterface result = + getFullyQualifiedCellPretty(fullyQualifiedCellName, out); + if (result == null) System.exit(exitStatus); + return result; + } + + + public CellInterface getFullyQualifiedCell(String fullyQualifiedCellName, + CellImpl parent, + final HierName instance) + throws CastSemanticException { + + try { + return cpe.getFullyQualifiedCell( fullyQualifiedCellName, parent, + instance ); + } catch (SemanticWrapperException e) { + throw new CastSemanticException(e.getCause(), + e.getFilename(), e.getLine(), e.getColumn()); + } + + } + + public CastParserEnvironment getParserEnvironment() { + return cpe; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSemanticException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSemanticException.java new file mode 100644 index 0000000000..24037e37bf --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSemanticException.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * Exception thrown by {@link CastFileParser} for semantic errors in + * cast files. Wraps another exception for the stack dump, but stores + * its own file/line/column info so it can wrap exceptions without + * file/line/column info, like CircularImportExceptions. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CastSemanticException extends Exception { + + private final String fileName; + private final int lineNumber; + private final int columnNumber; + + public CastSemanticException(final Throwable e, + final String fileName, + final int lineNumber, + final int columnNumber) { + super(e); + this.fileName = fileName; + this.lineNumber = lineNumber; + this.columnNumber = columnNumber; + } + + public String getFileName() { + return fileName; + } + + public int getColumnNumber() { + return columnNumber; + } + + public int getLineNumber() { + return lineNumber; + } + + public String toString() { + return getHeader() + ": wrapping " + getCause().getMessage(); + } + + private String getHeader() { + return "CastSemanticException[" + + super.getMessage() + " at " + + getFileName() + ":" + + getLineNumber() + "," + + getColumnNumber() + "]"; + } + + public String getMessage() { + return toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSyntaxException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSyntaxException.java new file mode 100644 index 0000000000..eac79c32b9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/CastSyntaxException.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * Exception thrown by {@link CastFileParser} for syntax errors in cast + * files. Wraps another exception for the stack dump, but stores + * its own file/line/column info so it can wrap exceptions without + * file/line/column info, like CircularImportExceptions. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CastSyntaxException extends Exception { + + private final String fileName; + private final int lineNumber; + private final int columnNumber; + + public CastSyntaxException(final Exception e, + final String fileName, + final int lineNumber, + final int columnNumber) { + super(e); + this.fileName = fileName; + this.lineNumber = lineNumber; + this.columnNumber = columnNumber; + } + + public String getFileName() { + return fileName; + } + + public int getColumnNumber() { + return columnNumber; + } + + public int getLineNumber() { + return lineNumber; + } + + public String toString() { + return "CastSyntaxException[" + + getFileName() + ":" + + getLineNumber() + "," + + getColumnNumber() + "]: " + + "wrapping " + getCause().getMessage(); + } + + public String getMessage() { + return getCause().getMessage(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ASTWithInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ASTWithInfo.java new file mode 100644 index 0000000000..1df6a41903 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ASTWithInfo.java @@ -0,0 +1,97 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import antlr.CommonAST; +import antlr.Token; +import antlr.collections.AST; + +/** + * AST with filename, line number, and column number. + * Used to give decent error messages in the tree parser. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class ASTWithInfo extends CommonAST { + private int line = 0; + private int column = 0; + private String filename = null; + + public void initialize(Token tok) { + super.initialize(tok); + setLine(tok.getLine()); + setColumn(tok.getColumn()); + setFilename(((TokenWithInfo) tok).getFilename()); + } + + public void initialize(final AST ast) { + super.initialize(ast); + copyInfo((ASTWithInfo) ast); + } + + public int getLine(){ + return line; + } + + public void setLine(final int line) { + this.line = line; + } + + public String getFilename() { + return filename; + } + + public void setFilename(final String filename) { + this.filename = filename; + } + + public int getColumn() { + return column; + } + + public void setColumn(final int column) { + this.column = column; + } + + /** + * Copies file/line/column info from ast into this one, + * overwriting whatever was set in this one. + **/ + public void copyInfo(final ASTWithInfo ast) { + setLine(ast.getLine()); + setColumn(ast.getColumn()); + setFilename(ast.getFilename()); + } + + public String toString() { + return "ASTWithInfo(line=" + getLine() + + ", column=" + getColumn() + + ", file=" + getFilename() + + ", type=" + getType() + + ", super=" + super.toString() + ")"; + } + + /** + * Returns a copy of this tree with all the info, but with no + * children or siblings. + **/ + public ASTWithInfo getRoot() { + ASTWithInfo result = new ASTWithInfo(); + result.initialize(this); + result.removeChildren(); + result.setNextSibling(null); + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AbstractSplicingEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AbstractSplicingEnvironment.java new file mode 100644 index 0000000000..b0d182a18d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AbstractSplicingEnvironment.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; +import com.avlsi.cast.impl.ChainedEnvironmentIterator; + +/** + * This class represents environments with a parent and a local + * environment. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +abstract class AbstractSplicingEnvironment implements Environment { + protected Environment parentEnv; + + protected AbstractSplicingEnvironment(final Environment parentEnv) { + if (parentEnv == null) + throw new IllegalArgumentException("parentEnv was null"); + + this.parentEnv = parentEnv; + } + + protected abstract Environment getLocalEnvironment(); + + /** + * Looks up the value in the local environment. If + * it is not found there, lookup in the parent environment. + * This necessitates using a NullEnvironment at the top level. + **/ + public Value lookup(final Symbol sym) + throws AmbiguousLookupException { + final Value v = getLocalEnvironment().lookup(sym); + if (v != null) + return v; + return parentEnv.lookup(sym); + } + + /** Checks the local environment first, then the parent. **/ + public boolean contains(final Symbol sym) { + return(getLocalEnvironment().contains(sym) || + parentEnv.contains(sym)); + } + + public EnvironmentIterator iterator() { + return new ChainedEnvironmentIterator( getLocalEnvironment(), + parentEnv ); + } + + public EnvironmentEntryIterator entryIterator() { + return new ChainedEnvironmentEntryIterator(getLocalEnvironment(), + parentEnv); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AlintFaninValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AlintFaninValue.java new file mode 100644 index 0000000000..f03e80372e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AlintFaninValue.java @@ -0,0 +1,60 @@ +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.file.common.HierName; + +public final class AlintFaninValue extends Value { + public enum State { + ZERO ("=0"), + ONE ("=1"), + RISING ("+"), + FALLING("-"); + + private final String text; + private State(final String text) { + this.text = text; + } + public String toString() { + return text; + } + } + + private final Value node; + private final State state; + + public AlintFaninValue(final Value node, final State state) { + super(true); + this.node = node; + this.state = state; + } + + public Value duplicate() { + throw new AssertionError("can't dup alint fanins; can't happen"); + } + + public Value assign(final Value v, final CellImpl Cell) + throws InvalidOperationException { + throw new InvalidOperationException(); + } + + public Type getType() throws InvalidOperationException { + throw new InvalidOperationException(); + } + + public State getState() { + return state; + } + + public HierName getNode() { + return node.getInstanceName(); + } + + public String toString() { + return "AlintFaninValue(" + node + " " + state + ")"; + } + + public Value newInstanceName(final HierName newInstanceName) { + return new AlintFaninValue(node.newInstanceName(newInstanceName), + state); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AmbiguousLookupException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AmbiguousLookupException.java new file mode 100644 index 0000000000..b2d1d4c3b8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AmbiguousLookupException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * Exception thrown by {@link ImportEnvironment#lookup} when a symbol has + * been declared in multiple environments. + * + * @see ImportEnvironment + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class AmbiguousLookupException extends Exception { + private final Symbol sym; + + public AmbiguousLookupException() { + super(); + + this.sym = null; + } + + public AmbiguousLookupException(final Symbol sym, + final String env1, + final String env2) { + super(); + + this.sym = sym; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AnonymousValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AnonymousValue.java new file mode 100644 index 0000000000..b8af43ac3e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/AnonymousValue.java @@ -0,0 +1,49 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.util.exception.AssertionFailure; + +/** + * This class is just a tagging class, none of its methods should ever + * be called. AnonymousValues can appear inside expression lists + * for the port list initializer. The only operation that will + * be performed on an AnonymousValue is an instanceof check in + * InstanceValue.assign, for the TupleValue case. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class AnonymousValue extends Value { + + /** + * Constructor. + **/ + public AnonymousValue() { + super(true); + } + + public Value assign(final Value v, final CellImpl cell) { + throw new AssertionFailure("Can't call assign() on an anonymous value."); + } + + public Value duplicate() { + throw new AssertionFailure("Can't call duplicate() on an anonymous value."); + } + + public Type getType() { + throw new AssertionFailure("Can't call getType() on an anonymous value."); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ArrayValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ArrayValue.java new file mode 100644 index 0000000000..44bf45e348 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ArrayValue.java @@ -0,0 +1,733 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.fast.metaparameters.ArrayMetaParam; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.tools.cosim.CoSimChannelNames; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; + +import java.util.Arrays; +import java.util.Iterator; + +/** + * This class represents an array. Assignment is element by element - + * elements from the RHS are assigned into the corresponding index in + * the LHS array. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ArrayValue + extends Value + implements MetaParamValueInterface { + + /** None of the Values in vals are ever ArrayValues. **/ + private Value[] vals; + private SubscriptSpecInterface spec; + private final HierName instanceName; + /** + * Whether the last dimension of this array is actually a channel width. + **/ + private final boolean wideChannelP; + + /** + * Construct an ArrayValue with the given values, spec, and + * instanceName. The instanceName will be null if the array + * was constructed from a tuple (anonymous array). + **/ + public ArrayValue(final Value[] vals, + final SubscriptSpecInterface spec, + final HierName instanceName, + final boolean wideChannelP) { + super(true); + + if (vals.length != spec.getNumElements()) + throw new IllegalArgumentException("sizes don't match"); + + this.spec = spec; + this.vals = new Value[vals.length]; + + for (int i = 0; i < vals.length; ++i) + this.vals[i] = vals[i]; + + // TODO: somewhere, we need to make sure that the element + // type is homogeneous and that none of them are ArrayValues + + this.instanceName = instanceName; + this.wideChannelP = wideChannelP; + } + + /** + * Convert if the value is an ArrayValue, return it with + * type ArrayValue. Otherwise, throw an InvalidOperationException. + **/ + public static ArrayValue valueOf(final Value val) + throws InvalidOperationException { + if (val instanceof ArrayValue) + return (ArrayValue) val; + else + throw new InvalidOperationException("value named " + val.getInstanceName() + " isn't an array."); + } + + public Value duplicate() { + assert isDefined(); // arrays are always defined + + final Value[] newVals = new Value[vals.length]; + + for (int i = 0; i < vals.length; ++i) + newVals[i] = vals[i].duplicate().newInstanceName(instanceName.appendString(DenseSubscriptSpec.idxToString(spec.indexOf(i)))); + + return new ArrayValue(newVals, spec, instanceName, wideChannelP); + } + + /** + * Return a copy of the array, duplicating only the subscript spec. + * The underlying pointers are the same. Thus, changes to the + * elements of the new array affect the old. Changes to the + * size do not. + **/ + public Value shallowCopy() { + assert isDefined(); // arrays are always defined + + return new ArrayValue(vals, spec, instanceName, wideChannelP); + } + + /** + * Returns the value resulting from subscripting. This will be + * an ArrayValue if there is more than one element, or some + * other kind of Value if there is only one. This prevents + * all other types from needing to know how to convert from array. + *

    + * In order for the access to be valid, the specifications must + * both have the same number of dimensions, and all the indices of the + * accessSpec must present in the array's spec. + **/ + public Value accessArray(final SubscriptSpecInterface accessSpec) + throws InvalidOperationException { + if (spec.getNumDimensions() != accessSpec.getNumDimensions()) + throw new InvalidOperationException("dims don't agree. array has " + spec.getNumDimensions() + " dimensions but accessor has " + accessSpec.getNumDimensions()); + + final Value[] newVals = new Value[accessSpec.getNumElements()]; + + for (int i = 0; i < newVals.length; ++i) { + // spec.positionOf(idx) will throw IndexOutOfBoundsException + // if idx is not in the spec + final int[] idx = accessSpec.indexOf(i); + final int pos; + + try { + pos = spec.positionOf(idx); + } catch (IndexOutOfBoundsException e) { + throw new InvalidOperationException("bad array access of " + + instanceName + ": index " + + DenseSubscriptSpec.idxToString(idx) + + " not in spec " + spec, e); + } + + newVals[i] = vals[pos]; + } + + if (newVals.length == 1) { + if (instanceName == null) + return newVals[0]; + else if (instanceName.isGlobal()) { + // code in CastTree.type duplicates this + final int bangIdx = + instanceName.getSuffixString().indexOf('!'); + assert bangIdx == instanceName.getSuffixString().length() - 1; + return newVals[0].newInstanceName( + HierName.makeSiblingName(instanceName, + instanceName.getSuffixString().substring(0, + bangIdx) + + DenseSubscriptSpec.idxToString( + accessSpec.indexOf(0)) + '!')); + } else { + // code in CastTree.type duplicates this + return newVals[0].newInstanceName( + HierName.makeSiblingName(instanceName, + instanceName.getSuffixString() + + DenseSubscriptSpec.idxToString( + accessSpec.indexOf(0)))); + } + } else + return new ArrayValue(newVals, accessSpec, instanceName, + wideChannelP); + } + + /** + * Access a single index. + **/ + public Value accessArray(final int[] idx) { + try { + final Range[] rs = new Range[idx.length]; + + for (int i = 0; i < rs.length; ++i) + rs[i] = new Range(idx[i], idx[i]); + + return accessArray(new DenseSubscriptSpec(rs)); + } catch (InvalidOperationException e) { + throw (AssertionFailure) + new AssertionFailure("bad index? " + e).initCause(e); + } + } + + + public void replaceArray(final ArrayValue other) + throws InvalidOperationException { + if (spec.getNumDimensions() != other.spec.getNumDimensions()) + throw new InvalidOperationException("dims don't agree. array has " + spec.getNumDimensions() + " dimensions but replace has " + other.spec.getNumDimensions()); + + final int elements = other.spec.getNumElements(); + + for (int i = 0; i < elements; ++i) { + // spec.positionOf(idx) will throw IndexOutOfBoundsException + // if idx is not in the spec + final int[] idx = other.spec.indexOf(i); + final int pos; + + try { + pos = spec.positionOf(idx); + } catch (IndexOutOfBoundsException e) { + throw new InvalidOperationException("bad array access of " + + instanceName + ": index " + + DenseSubscriptSpec.idxToString(idx) + + " not in spec " + spec, e); + } + + vals[pos] = other.vals[i]; + } + } + + /** + * Array assignment is valid as long as the sizes are conforming. + * The sizes conform if the sequences of non-one sizes for each + * dimension are the same. Performs implicit conversion from + * singleton to array[1]. + **/ + public Value assign (final Value v, final CellImpl cell) + throws InvalidOperationException { + final ArrayValue av; + if (v instanceof ArrayValue) + av = (ArrayValue) v; + else + av = new ArrayValue( + new Value[]{v}, + new DenseSubscriptSpec(new Range[]{new Range(0, 0)}), + // PR 228, use null here + null, + false); + + if (spec.getNumElements() != av.spec.getNumElements()) + throw new InvalidOperationException + ("sizes don't conform: trying to assign " + av.spec + + " with " + av.spec.getNumElements() + " elements to " + spec + + " with " + spec.getNumElements() + " elements."); + + // do assignment in lexicographic order + assert vals.length == av.vals.length; + for (int i = 0; i < vals.length; ++i) { + accessArray(spec.indexOf(i)).assign( + av.accessArray(av.spec.indexOf(i)), cell); + } + + return this; + } + + /** + * Attempt to augment the existing array with additional indices. + * Several conditions must be met for this to be legal: + *

      + *
    • The element types must agree + *
    • The number of dimensions must agree + *
    • The indices that exist in the old array must be disjoint + * from the ones that are augmenting it. + *
    + * The resulting array will have a sparse spec. + * The augmenting array must have a dense spec. + **/ + public void augment(final ArrayValue av) throws InvalidOperationException + { + if (!typeCompatible(getElementType(), av.getElementType())) + throw new InvalidOperationException("element types don't agree"); + + if (spec.getNumDimensions() != av.spec.getNumDimensions()) + throw new InvalidOperationException("dims must agree"); + + final int n1 = vals.length; + final int n2 = av.vals.length; + + final Value[] newVals = new Value[n1 + n2]; + + spec = SparseSubscriptSpec.augment(spec, vals, + av.spec, av.vals, + newVals); + vals = newVals; + } + + /** + * Makes an array with the given index specification, filled with + * copies of the value v. Assumes that the array is + * not a wide channel. + **/ + public static ArrayValue makeArray(final Value v, + final SubscriptSpecInterface spec) + { + return makePossiblyWideArray(v, spec, false); + } + + public static ArrayValue makeWideArray(final Value v, + final SubscriptSpecInterface spec) + { + return makePossiblyWideArray(v, spec, true); + } + + private static ArrayValue makePossiblyWideArray(final Value v, + final SubscriptSpecInterface spec, + final boolean wideP) + { + final Value[] vals = new Value[spec.getNumElements()]; + final HierName instanceName; + if (v.getInstanceName() == null) + instanceName = HierName.makeHierName(""); + else + instanceName = v.getInstanceName(); + + for (int i = 0; i < vals.length; ++i) + vals[i] = v.duplicate().newInstanceName( + instanceName.appendString(DenseSubscriptSpec.idxToString(spec.indexOf(i)))); + + // v.getInstanceName() may be null, ie it is an integer array + + // spec is be immutable + return new ArrayValue(vals, spec, instanceName, wideP); + } + + /** + * Turns the tuple into an array. Fails if the types are + * not all the same. Used to provide support for anonymous arrays. + **/ + public static ArrayValue fromTuple(final Value val) + throws InvalidOperationException { + + final TupleValue tv = TupleValue.valueOf(val); + + final int n = tv.getSize(); + + if (n == 0) + throw new InvalidOperationException("0-tuple connot be " + + "converted to an array"); + + final Type t = tv.accessTuple(0).getType(); + final Value[] vals = new Value[n]; + + // make sure the types agree, and copy pointer to value + for (int i = 0; i < n; ++i) { + final Value v = tv.accessTuple(i); + if (!v.getType().equals(t)) + throw new InvalidOperationException("types don't agree " + + "for elems " + i + " and 0"); + vals[i] = v; + } + + if (t instanceof ArrayValueType) { + // We must manually construct a multi-dimensional array or + // we will end up with an array of arrays, which none of + // the other code supports. + final ArrayValueType avt = (ArrayValueType) t; + final int m = avt.getSubscriptSpec().getNumElements(); + final Value[] vs = new Value[n * m]; + + // make the new value array + int k = 0; + for (int j = 0; j < n; ++j) { + // The Value must be an ArrayValue because the type + // was ArrayValueType. + final ArrayValue v = (ArrayValue) vals[j]; + final SubscriptSpecInterface spec = v.getSpec(); + for (int i = 0; i < m; ++i, ++k) + vs[k] = v.accessArray(spec.indexOf(i)); + } + + // make the new subscript spec + // XXX: when we support SparseSubscriptSpecs, we will + // need to pass all the specs, not just the first + final SubscriptSpecInterface spec = + repeatSubscriptSpec(avt.getSubscriptSpec(), n); + + return new ArrayValue(vs, spec, val.getInstanceName(), false); + } else { + return new ArrayValue(vals, + new DenseSubscriptSpec(new Range[]{new Range(0, n - 1)}), + val.getInstanceName(), + false); + } + } + + /** + * Returns a new subscript spec of with one more dimension than + * spec, the first dimension of the new spec will + * have bounds [0..n - 1]. + * + *
    
    +     *   private normal_behavior
    +     *     requires spec != null;
    +     *     requires spec instanceof DenseSubscriptSpec;
    +     *     requires n > 0;
    +     *     ensures \result != null;
    +     * 
    + **/ + private static /*@ non_null @*/ SubscriptSpecInterface + repeatSubscriptSpec( + final /*@ non_null @*/ SubscriptSpecInterface spec, + final int n) + throws InvalidOperationException { + if (!(spec instanceof DenseSubscriptSpec)) + throw new InvalidOperationException("Cannot yet create " + + "anonymous multi-dimensional arrays from sparse arrays."); + + return repeatSubscriptSpec((DenseSubscriptSpec) spec, + new Range(0, n - 1)); + } + + /** + * Returns a new subscript spec of with one more dimension than + * spec, the first dimension of the new spec will + * have bounds specified by r. + **/ + private static /*@ non_null @*/ DenseSubscriptSpec + repeatSubscriptSpec( + final /*@ non_null @*/ DenseSubscriptSpec spec, final Range r) { + + final Range[] newRanges = new Range[spec.getNumDimensions() + 1]; + newRanges[0] = r; + for (int i = 1; i < newRanges.length; ++i) + newRanges[i] = spec.getRange(i - 1); + + return new DenseSubscriptSpec(newRanges); + } + + /** + * Returns a new anonymous array, created by combining the arrays specified + * in vals into a new dimension. All the constituent arrays + * must be dense arrays with the same shape. + **/ + public static /*@ non_null @*/ ArrayValue + augmentDimension(final ArrayValue[] vals, final Range r) + throws InvalidOperationException { + if (vals.length != r.size()) + throw new InvalidOperationException("Size of new dimension does " + + "not agree with number of elements in new dimension."); + for (int i = 1; i < vals.length; ++i) { + if (!vals[0].getSpec().equals(vals[i].getSpec())) { + throw new InvalidOperationException("All elements of the " + + "array must have the same shape"); + } + } + if (!(vals[0].getSpec() instanceof DenseSubscriptSpec)) + throw new InvalidOperationException("Cannot yet create " + + "anonymous multi-dimensional arrays from sparse arrays."); + + final DenseSubscriptSpec newSpec = + repeatSubscriptSpec((DenseSubscriptSpec) vals[0].getSpec(), r); + final Value[] newVals = new Value[newSpec.getNumElements()]; + final int[] idx = new int[newSpec.getNumDimensions()]; + + final DenseSubscriptSpec spec = (DenseSubscriptSpec) vals[0].getSpec(); + for (int i = 0; i < spec.getNumElements(); ++i) { + final int[] subidx = spec.indexOf(i); + System.arraycopy(subidx, 0, idx, 1, subidx.length); + for (int j = 0; j < vals.length; ++j) { + idx[0] = r.getMin() + j; + newVals[newSpec.positionOf(idx)] = vals[j].accessArray(subidx); + } + } + return new ArrayValue(newVals, newSpec, null, false); + } + + public Type getType() throws InvalidOperationException { + return new ArrayValueType(getElementType(), spec); + } + + private static final class ArrayValueType extends Type { + private final Type elementType; + private final SubscriptSpecInterface spec; + + private ArrayValueType(final Type elementType, + final SubscriptSpecInterface spec) { + this.elementType = elementType; + this.spec = spec; + } + + public boolean equals(final Object o) { + if (!(o instanceof ArrayValueType)) + return false; + + final ArrayValueType that = (ArrayValueType) o; + return typeCompatible(elementType, that.elementType) && + spec.getNumElements() == that.spec.getNumElements(); + } + + private Type getElementType() { + return elementType; + } + + private SubscriptSpecInterface getSubscriptSpec() { + return spec; + } + + public String getString() { + // XXX: shouldn't use toString, but it does what we want + return elementType.getString() + spec.toString(); + } + } + + private static boolean typeCompatible(final Type t, final Type s) { + if (t instanceof InstanceValue.InstanceValueType && + s instanceof InstanceValue.InstanceValueType) { + final InstanceValue.InstanceValueType ivt = + (InstanceValue.InstanceValueType) t; + final InstanceValue.InstanceValueType ivs = + (InstanceValue.InstanceValueType) s; + return ivt.typeEquals(ivs); + } else { + return t.equals(s); + } + } + + public Type getElementType() { + assert vals.length > 0; + Type t = null; + + try { + t = vals[0].getType(); + for (int i = 1; i < vals.length; ++i) + assert typeCompatible(t, vals[i].getType()); + } catch (InvalidOperationException e) { + // FIXME This should be handled properly + throw new AssertionError("getElementType() called on " + this + + " produced error message: " + e); + } + return t; + } + + public HierName getInstanceName() { + return instanceName; + } + + public Value newInstanceName(final HierName newInstanceName) { + assert isDefined(); // arrays are always defined + + return new ArrayValue(vals, spec, newInstanceName, wideChannelP); + } + + public String getMetaParamString() throws InvalidOperationException { + final StringBuffer sb = new StringBuffer(); + sb.append('{'); + + for (int i = 0; i < vals.length; ++i) { + final Value v = vals[i]; + + if (i > 0) + sb.append(","); + + // code similiar to UserDefinedValue.getTypeName + if (v instanceof IntValue) + sb.append(((IntValue) v).getValue()); + else if (v instanceof BoolValue) + sb.append(((BoolValue) v).getValue()); + else + throw new AssertionFailure("bad meta-param type"); + } + + sb.append('}'); + return sb.toString(); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("ArrayValue(\n size: "); + sb.append(vals.length + ",\n bounds: "); + sb.append(spec + ",\n"); + + for (int i = 0; i < vals.length; ++i) { + final int[] idx = spec.indexOf(i); + sb.append(DenseSubscriptSpec.idxToString(idx)); + sb.append(": "); + sb.append(vals[i].toString()); + sb.append("\n"); + } + + sb.append(")\n"); + + return sb.toString(); + } + + /** + * Two arrays are equal if they have exactly the same subscript + * specification, and all elements are the same according + * to their equals methods. + **/ + public boolean equals(final Object o) { + if (!(o instanceof ArrayValue)) + return false; + else + return equals((ArrayValue) o); + } + + public boolean equals(final ArrayValue av) { + if (!spec.equals(av.spec)) + return false; + else { + assert vals.length == av.vals.length; + for (int i = 0; i < vals.length; ++i) + if (!vals[i].equals(av.vals[i])) + return false; + return true; + } + } + + public int hashCode() { + int hc = 0; + + for (int i = 0; i < vals.length; ++i) + hc ^= vals[i].hashCode(); + + return hc; + } + + // + // implements MetaParamValueInterface + // + + public MetaParamTypeInterface toMetaParam() { + final DenseSubscriptSpec denseSpec = (DenseSubscriptSpec) spec; + + return new ArrayMetaParam( + toMetaParam(0, new int[denseSpec.getNumDimensions()]), + denseSpec.getRange(0).getMin(), + denseSpec.getRange(0).getMax()); + } + + /** + * idx is a partially-specified coordinate into the array. All of + * the dimensions before dim are specified. + **/ + private MetaParamTypeInterface[] toMetaParam(final int dim, + final int[] idx) { + final DenseSubscriptSpec denseSpec = (DenseSubscriptSpec) spec; + + final MetaParamTypeInterface[] subArray = + new MetaParamTypeInterface[denseSpec.getSizeForDimension(dim)]; + + // If this is the last dimension, describe a point value + if (dim == denseSpec.getNumDimensions() - 1) { + for (int i = 0; i < subArray.length; ++i) { + idx[dim] = i + denseSpec.getRange(dim).getMin(); + /* The code commented out should work, and be functionally + * equivalent to the 3 lines below, but does not due to an + * apparent JIT bug in Sun's JVM build 1.4.2-b28, in mixed and + * 64-bit mode. See bug 3043 for more information. + subArray[i] = + (MetaParamTypeInterface) vals[denseSpec.positionOf(idx)]; + **/ + final int posOf = denseSpec.positionOf(idx); + subArray[i] = + (MetaParamTypeInterface) vals[posOf]; + } + } + // If this isn't the last dimension, get ArrayMetaParams which + // wrap up the following dimensions. + else { + for (int i = 0; i < subArray.length; ++i) { + idx[dim] = i + denseSpec.getRange(dim).getMin(); + subArray[i] = new ArrayMetaParam( + toMetaParam(dim + 1, idx), + denseSpec.getRange(dim + 1).getMin(), + denseSpec.getRange(dim + 1).getMax()); + } + } + + return subArray; + } + + /** + * Utility function. Value returned should not be modified. + **/ + + public SubscriptSpecInterface getSpec() { + return spec; + } + + /** + * Iterate over the values in the array. If ArrayValues a and b + * have the same SubscriptSpecInterface, their values are + * guaranteed to be iterated in the same order. + **/ + + public Iterator getIterator() { + return Arrays.asList(vals).iterator(); + } + + /** + * For an array to be a specialization of another array, they have + * to have matching SubscriptSpecInterface and each position in + * the first must specialize the equivalent position in the second + **/ + public boolean eventuallyRefinesFrom(Value v) + throws InvalidOperationException { + if (! (v instanceof ArrayValue)) + throw new InvalidOperationException("Can't refine an array value from " + v.getType().getString()); + ArrayValue av = (ArrayValue) v; + if (this.spec.getNumElements() != av.spec.getNumElements()) + return false; + + Iterator thisVals = this.getIterator(); + Iterator otherVals = av.getIterator(); + + while (thisVals.hasNext()) { + Value thisVal = (Value) thisVals.next(); + Value otherVal = (Value) otherVals.next(); + if (! (thisVal.eventuallyRefinesFrom(otherVal))) + return false; + } + + assert !otherVals.hasNext() : "problem comparing arrays: contents theoretically match up, but not really"; + + return true; + } + + /** + * Returns a name or array of names. Under the cosim framework, + * each of these names corresponds to a NodeChannel. Note that + * wide channels are handled properly here (one name for the whole + * wide channel). + **/ + public CoSimChannelNames getCoSimChannelNames() { + return spec.getCoSimChannelNames(instanceName.getAsString('.'), + wideChannelP); + } + + /** + * Return whether the last dimension of this array is actually a channel + * width. + **/ + public boolean isWideChannel() { + return wideChannelP; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BlockEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BlockEnvironment.java new file mode 100644 index 0000000000..3c3276be27 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BlockEnvironment.java @@ -0,0 +1,111 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; +import com.avlsi.cast.impl.ChainedEnvironmentIterator; + +/** + * This class represents environments for block scoping. Declarations + * are made within the environment, and will disappear at the end of the + * block. Lookups that fail locally are forwarded to the parent + * environment. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class BlockEnvironment extends AbstractSplicingEnvironment { + protected LocalEnvironment localEnv; + + public BlockEnvironment(final Environment parentEnv) { + super(parentEnv); + + this.localEnv = new LocalEnvironment(); + } + + public BlockEnvironment(final Environment parentEnv, + final LocalEnvironment localEnv) { + super(parentEnv); + + if (localEnv == null) + throw new IllegalArgumentException("localEnv was null"); + + this.localEnv = localEnv; + } + + protected Environment getLocalEnvironment() { + return localEnv; + } + + /** + * Binds the value to the symbol in the local environment. Allows + * binding of a symbol already bound in the parent environment. + **/ + public void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + localEnv.bind(sym, val); + } + + /** + * Returns a new environment with the same parent, + * but a separate LocalEnvironment, which is a copy this + * LocalEnvironment. + **/ + public BlockEnvironment getSiblingEnvironment() { + return new BlockEnvironment(parentEnv, localEnv.duplicate()); + } + + public String getLocalEnvironmentString() { + return localEnv.toString(); + } + + /** + * Return an environment with the same parent, and same values, + * but arrays are shallow copied. + **/ + public BlockEnvironment protectedArrayEnvironment() { + return new BlockEnvironment(parentEnv, + localEnv.protectedArrayEnvironment()); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("BlockEnvironment(\n"); + sb.append("parent:"); + sb.append(parentEnv.toString()); + sb.append(",me:\n"); + sb.append(localEnv.toString()); + sb.append(")\n"); + + return sb.toString(); + } + + /** + * Add all of the key-value pairs in env to this environment, with + * appropriate duplication warnings. + **/ + public void absorbEnv(LocalEnvironment env) + throws SymbolRedeclaredException { + localEnv.absorbEnv(env); + } + + public EnvironmentIterator iterator() { + return new ChainedEnvironmentIterator( localEnv, parentEnv ); + } + + public EnvironmentEntryIterator entryIterator() { + return new ChainedEnvironmentEntryIterator( localEnv, parentEnv ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BoolValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BoolValue.java new file mode 100644 index 0000000000..b137330e67 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/BoolValue.java @@ -0,0 +1,189 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.fast.metaparameters.BooleanMetaParam; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; + +/** + * This class represents boolean values. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class BoolValue + extends Value + implements BooleanMetaParam, MetaParamValueInterface { + + /** + * Value, a boolean. + **/ + private boolean val; + + /** + * Returns a BoolValue whose value is equal to that of the specified + * boolean. + **/ + public static BoolValue valueOf(final boolean val) { + return new BoolValue(val); + } + + /** + * Returns a BoolValue whose value is equal to that of the specified + * Value. Thrown InvalidOperationException if the value is not + * an BoolValue + **/ + public static BoolValue valueOf(final Value v) + throws InvalidOperationException { + if (v instanceof BoolValue) + return (BoolValue) v; + else + throw new InvalidOperationException(v + " is not a bool"); + } + + public static BoolValue castFrom(final Value v) + throws InvalidOperationException { + if (v instanceof BoolValue) + return (BoolValue) v; + else if (v instanceof IntValue) + return valueOf(((IntValue) v).getValue().compareTo(java.math.BigInteger.ZERO) != 0); + else if (v instanceof FloatValue) + return valueOf(((FloatValue) v).getValue() != 0); + else + throw new InvalidOperationException( + "Cannot cast " + v.getType().getString() + " to " + + TYPE.getString()); + + } + + /** + * Class constructor. + **/ + private BoolValue(final boolean val) { + super(true); + this.val = val; + } + + /** + * Class constructor, constructs an undefined BoolValue. + **/ + public BoolValue() { + super(false); + this.val = false; + } + + public Value duplicate() { + if (isDefined()) + return new BoolValue(val); + else + return new BoolValue(); + } + + /** + * Returns the value, throws InvalidOperationException if + * value is not defined. + **/ + public boolean getValue() throws InvalidOperationException { + ensureDefined(); + return val; + } + + // logical + public Value or (final Value v) throws InvalidOperationException + { return valueOf(getValue() | valueOf(v).getValue()); } + public Value and (final Value v) throws InvalidOperationException + { return valueOf(getValue() & valueOf(v).getValue()); } + public Value not () throws InvalidOperationException + { return valueOf(!getValue()); } + public Value xor (final Value v) throws InvalidOperationException + { return valueOf(getValue() ^ valueOf(v).getValue()); } + + + // relational, we only want eq, ne + + public Value eq (final Value v) throws InvalidOperationException + { return valueOf(getValue() == valueOf(v).getValue()); } + public Value ne (final Value v) throws InvalidOperationException + { return valueOf(getValue() != valueOf(v).getValue()); } + + public Value assign(final Value v, final CellImpl cell) + throws InvalidOperationException { + if (isDefined()) + throw new InvalidOperationException("value already assigned"); + + // throw InvalidOperationException if v not defined + val = valueOf(v).getValue(); + setDefined(); + + return this; + } + + + public static final Type TYPE = new ClassType("bool"); + + public Type getType() { + return TYPE; + } + + public String toString() { + return "BoolValue(" + + (isDefined() ? String.valueOf(val) : "?") + + ")"; + } + + /** + * Two BoolValues are equal if they are both defined, + * and have the same value. + **/ + public boolean equals(final Object o) { + if (!(o instanceof BoolValue)) + return false; + else + return equals((BoolValue) o); + } + + /** + * Two BoolValues are equal if they are both defined, + * and have the same value. + **/ + public boolean equals(final BoolValue bv) { + if (!isDefined()) + return false; + else if (!bv.isDefined()) + return false; + else + return val == bv.val; + } + + public int hashCode() { + return val ? 1 : 0; + } + + // + // implements BooleanMetaParam + // + + public boolean toBoolean() { + return val; + } + + // + // implements MetaParamValueInterface + // + + public MetaParamTypeInterface toMetaParam() { + return this; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Cast.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Cast.g new file mode 100644 index 0000000000..a3dd3a904b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Cast.g @@ -0,0 +1,839 @@ +// +// Copyright 2000 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// CAST Parser Grammar (for use with antlr http://www.antlr.org/) +// +// author: Jesse Rosenstock +// + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2000 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify Cast.g instead. + // + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast.impl; +} + +// Import the necessary classes +{ + import java.io.*; + import antlr.TokenStreamSelector; + + import antlr.ASTFactory; + import com.avlsi.cast.impl.TupleValue; + import com.avlsi.cast.impl.SemanticWrapperException; + import com.avlsi.cast.impl.IntValue; + import com.avlsi.cast.impl.InvalidOperationException; + import com.avlsi.util.debug.Debug; + +} + +// todo: +// currently, we cannot support {a, b} = {c, d} +// because of blocks vs. anonymous arrays issue. +// this could be fixed by using () for arrays +// or using lookahead +// clean up dumbBlock -- use { in lookahead, but parse it in dumb.g +// handle bad spec blocks, ie not csp, hse, prs, ... + +// flat or tree, that is the question: +// ie, (op a b c) or (op (op a b) c) via passing lhs into parse of rhs + +// better handling of initializers / params in formal param list than [identP] + + +//--------------------------------------------------------------------------- +// Define a Parser, calling it CastParser +//--------------------------------------------------------------------------- +class CastParser extends Parser; +options { + classHeaderSuffix = CastParserInterface; + k = 2; + exportVocab = Cast; + buildAST = true; + defaultErrorHandler = false; + ASTLabelType = "ASTWithInfo"; +} + +tokens { + ARRAY; + ARRAY_SUB; + ARRAY_ACCESS; + BLOCK; + BODY_STATEMENT_LIST; + EXPRESSION; + EXPRESSION_LIST; + FIELD_ACCESS; + FIELD_IDENT; + FORMALS; + IF; + LEVEL_BLOCK; + LOOP; + LOOP_AND; + LOOP_OR; + PORT_LIST; + PRS_AND; + PRS_NOT; + PRS_OR; + PRS_EXPRESSION; + COSIM_EXPRESSION; + RANGE; + SELECTION; + TYPE; + TYPE_BODY; + TYPE_DEFINITION; + UNARY_PLUS; + UNARY_MINUS; + USER_TYPE; + VAR_DECL; + STRING; +} + +{ + private TokenStreamSelector selector = null; + + public void setSelector(final TokenStreamSelector selector) { + this.selector = selector; + } + + + + private static AST makeMetasAST( final ASTFactory factory, + final TupleValue metas ) throws SemanticWrapperException { + + final AST metasAST; + + metasAST = factory.create(CastTreeParserTokenTypes.EXPRESSION_LIST); + + final int length = metas.getSize(); + for (int i=0; i dumbBlock + | ( IDENT LPAREN IDENT RPAREN LCURLY ) => levelBlock + | typeBody + | variableDeclarationStatement + | loopStatement + | ifStatement + | assignmentStatement + ; + +typeDeclaration + : typeHeader typeBody + { #typeDeclaration = #( [TYPE_DEFINITION], #typeDeclaration ); } + ; + +typeHeader + : DEFINE! id:IDENT {checkIdent(id);} + LPAREN! parameterList RPAREN! + LPAREN! parameterList RPAREN! + ; + +parameterList + : ( v:variableDeclaration[true] ( SEMI! variableDeclaration[true] )* )? + { #parameterList = #( [FORMALS], #parameterList ); + if (#v != null) + #parameterList.copyInfo(#v); } + ; + +typeBody + : lc:LCURLY^ {#lc.setType(BLOCK);} bodyStatements RCURLY! + ; + +instantiation + : variableDeclaration[false] + ; + +variableDeclarationStatement + : variableDeclaration[false] SEMI! + ; + +variableDeclaration![boolean formalP] + : ( { !formalP }? ( i:INLINE | i1:INLINE1 | f:FLATTEN ) )? + t:type v:variableDeclarators[formalP, #t, #i, #i1, #f] + { #variableDeclaration = #v; } + ; + +variableDeclarators[boolean formalP, AST t, AST inlineAST, AST inline1AST, + AST flattenAST] + : variableDeclarator[formalP, getASTFactory().dupTree(t), + getASTFactory().dupTree(inlineAST), + getASTFactory().dupTree(inline1AST), + getASTFactory().dupTree(flattenAST)] + ( COMMA! variableDeclarator[formalP, getASTFactory().dupTree(t), + getASTFactory().dupTree(inlineAST), + getASTFactory().dupTree(inline1AST), + getASTFactory().dupTree(flattenAST)] )* + ; + +variableDeclarator![boolean formalP, AST t, AST inlineAST, AST inline1AST, + AST flattenAST] + : id:IDENT {checkIdent(id);} ( a:arraySelector )? + ( { !formalP }? vi:variableInitializer )? + { #variableDeclarator + = #( [VAR_DECL], id, inlineAST, inline1AST, flattenAST, #([TYPE], t, a), vi ); } + ; + +variableInitializer + : lp:LPAREN^ {#lp.setType(PORT_LIST);} expressionList RPAREN! + | ASSIGN^ expression + ; + +arraySelector + : lb:LBRACK^ {#lb.setType(ARRAY_SUB);} ranges RBRACK! + ; + +ranges + : range ( COMMA! range )* + ; + +range + : expression ( DOTDOT! expression )? + { #range = #( [RANGE], range ); } + ; + +type + : primitiveType + | id:IDENT {checkIdent(id);} typeParameterList { #type = #( [USER_TYPE], #type ); } + ; + +typeParameterList + : LPAREN! expressionList RPAREN! + |! /* empty */ { #typeParameterList = #( [EXPRESSION_LIST], #typeParameterList ) ; } + ; + +primitiveType + : BOOL + | FLOAT + | INT + | NODE + ; + +loopStatement + : lt:LT^ {#lt.setType(LOOP);} id:IDENT {checkIdent(id);} COLON! range COLON! bodyStatements GT! + ; + +ifStatement + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! bodyStatements RBRACK! + ; + +assignmentStatement + : assignment SEMI! + ; + +assignment + : assignableExpression ( ASSIGN! expression )+ + { #assignment = #( [ASSIGN], #assignment ); } + ; + +// fix me up later! +// ugh, duplication +assignableExpression + : id:IDENT {checkIdent(id);} + (! i:DOT_IDENT {checkIdent(i);} + { final String s = i.getText(); + #assignableExpression = #( [FIELD_ACCESS], + #assignableExpression, + #[ FIELD_IDENT, s ] ); } + |! as:arraySelector + { #assignableExpression = #( [ARRAY_ACCESS], #assignableExpression, #as ); } + )* + ; + +dumbBlock! + : id:IDENT {checkIdent(id);} LCURLY + { + final String[] a = new String[] { + "asp", "aspice", "csp", "hse", "sprs" + }; + + int i = 0; + for (; i < a.length; ++i) + if (a[i].equals(id.getText())) + break; + + if (i == a.length) + System.err.println("Unknown body " + id.getText() + " ignored."); + + selector.push("dumblexer"); + new DumbParser(getInputState()).goal(); + selector.pop(); + } + ; + +levelBlock! + : id1:IDENT LPAREN id2:IDENT RPAREN tb:typeBody + { + if (!"level".equals(id1.getText())) { + // XXX: throw exception + System.err.println(id1.getText() + " is not level"); + System.exit(1); + } + checkIdent(id2); + + #levelBlock = #([LEVEL_BLOCK], id2, tb); + } + ; + +// hack, to support X x(a,b,,,,). +// urk, accidentally supports ,, where we don't want to +expressionList + : ( /* empty */ + | expression ( COMMA! expressionListExpression )* + ) { #expressionList = #( [EXPRESSION_LIST], #expressionList); } + // commented out version causes non-determinism, above should + // be equivalent + //: ( expressionListExpression ( COMMA! expressionListExpression )* )? + ; + +// hack , as above +expressionListExpression + :! /* empty, */ + { #expressionListExpression = #( [EXPRESSION], #[IDENT, "_"] ); } + | expression + ; + +expression + : co:conditionalOrExpression + { + #expression = #( [EXPRESSION], #expression); + #expression.copyInfo(#co); + } + ; + +conditionalOrExpression + : conditionalAndExpression ( OR^ conditionalAndExpression )* + ; + +conditionalAndExpression + : relationalExpression ( AND^ relationalExpression )* + ; + +relationalExpression + : additiveExpression ( ( EQ^ | NE^ | LT^ | LE^ | GT^ | GE^ ) additiveExpression )* + ; + +additiveExpression + : multiplicativeExpression ( ( PLUS^ | MINUS^ ) multiplicativeExpression )* + ; + +multiplicativeExpression + : unaryExpression ( ( TIMES^ | DIV^ | MOD^ ) unaryExpression )* + ; + +unaryExpression + : PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression + | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression + | NOT^ unaryExpression + | selectionExpression + ; + +// treeify me +// ugh, duplication +selectionExpression + : primaryExpression + (! i:DOT_IDENT {checkIdent(i);} + { final String s = i.getText(); + #selectionExpression = #( [FIELD_ACCESS], #selectionExpression, #[ FIELD_IDENT, s ] ); #selectionExpression.copyInfo(#i); } + |! as:arraySelector + { #selectionExpression = #( [ARRAY_ACCESS], #selectionExpression, #as ); #selectionExpression.copyInfo(#as); } + )* + ; + +primaryExpression + : id:IDENT {checkIdent(id);} + | NUM_INT + | NUM_REAL + | TRUE + | FALSE + | anonymousArray + | LPAREN! conditionalOrExpression RPAREN! + ; + +/* +selector![AST lhs] + : i:DOT_IDENT { final String s = i.getText(); + #selector = #( [FIELD_ACCESS], #lhs, #[ FIELD_IDENT, s ] ); } + | as:arraySelector { #selector = #( [ARRAY_ACCESS], #lhs, #as ); } + ; +*/ + +anonymousArray + : lc:LCURLY^ {#lc.setType(ARRAY);} expressionList RCURLY! + ; + +// +// PRS stuff +// + +prsBlock + : PRS^ LCURLY! prsStatements RCURLY! + ; + +// an env block that occurs in a prs block +prsEnvBlock + : ENV^ LCURLY! prsStatements RCURLY! + ; + +prsStatements + : ( prsStatement )* + { #prsStatements = #( [BODY_STATEMENT_LIST], #prsStatements ); } + ; + +prsStatement + : prsIfStatement + | prsLoopStatement + | prsAction + | prsEnvBlock + ; + +prsIfStatement + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! prsStatements RBRACK! + ; + +prsLoopStatement + : lt:LT^ {#lt.setType(LOOP);} id:IDENT {checkIdent(id);} + COLON! range COLON! prsStatements GT! + ; + +prsAction + : prsModifiers + prsExpression ( ARROW^ | CELEM_ARROW^ | COMB_ARROW^ ) + prsNodeExpression ( PLUS | MINUS ) + ; + +prsModifiers + : ( UNSTAB )? ( AFTER expression )? + ; + +prsExpression + : poe:prsOrExpression + { + #prsExpression = #( [PRS_EXPRESSION], #prsExpression); + #prsExpression.copyInfo(#poe); + } + ; + +prsOrExpression + : prsAndExpression ( o:OR^ {#o.setType(PRS_OR);} prsAndExpression )* + ; + +prsAndExpression + : prsNotExpression ( a:AND^ {#a.setType(PRS_AND);} prsNotExpression )* + ; + +prsNotExpression + : n:NOT^ {#n.setType(PRS_NOT);} prsNotExpression + | prsLoopedExpression + ; + +prsLoopedExpression + // XXX: LT_AND / LT_OR are hacks! We should fix this! + // we want: LT ( AND | OR ) + : ( la:LT_AND^ {#la.setType(LOOP_AND);} + | lo:LT_OR^ {#lo.setType(LOOP_OR); } ) + id:IDENT {checkIdent(id);} COLON! range COLON! prsExpression GT! + | prsSelectionExpression + ; + +// review, this allows (foo | bar).baz[0], too general! +prsSelectionExpression +//ugh, duplication + : prsPrimaryExpression + (! id:DOT_IDENT {checkIdent(id);} + { final String s = id.getText(); + #prsSelectionExpression + = #( [FIELD_ACCESS], + #prsSelectionExpression, #[ FIELD_IDENT, s ] ); } + |! as:arraySelector + { #prsSelectionExpression + = #( [ARRAY_ACCESS], #prsSelectionExpression, #as ); } + )* + ; + +prsPrimaryExpression + : IDENT + | LPAREN! prsOrExpression RPAREN! + ; + +prsNodeExpression +//ugh, duplication + : IDENT + (! id:DOT_IDENT {checkIdent(id);} + { final String s = id.getText(); + #prsNodeExpression + = #( [FIELD_ACCESS], + #prsNodeExpression, #[ FIELD_IDENT, s ] ); } + |! as:arraySelector + { #prsNodeExpression + = #( [ARRAY_ACCESS], #prsNodeExpression, #as ); } + )* + ; + +// a Java block to specify co-sim parameters +javaBlock + : JAVA^ LCURLY! javaStatements RCURLY! + ; + +javaStatements + : ( javaStatement )* + { #javaStatements = #( [BODY_STATEMENT_LIST], #javaStatements ); } + ; + +javaStatement + : javaClassStatement + | inputChannelStatement + | outputChannelStatement + | internalChannelStatement + ; + +javaClassStatement + : JAVACLASS^ QuotedString + ; + +inputChannelStatement + : INPUTCHAN^ QuotedString + ; + +outputChannelStatement + : OUTPUTCHAN^ QuotedString + ; + +internalChannelStatement + : INTERNALCHAN^ QuotedString + ; + + +// +// SPEC stuff +// + +specBlock + : SPEC^ LCURLY! specStatements RCURLY! + ; + +specStatements + : ( specStatement )* + ; + +specStatement + : specExclStatement + | specAttribStatement + ; + +specExclStatement + : ( EXCLHI^ | EXCLLO^ ) LPAREN! specNodeList RPAREN! + ; + +specAttribStatement! + : ATTRIB IDENT IDENT LPAREN! specNodeList SEMI! prsNodeExpression RPAREN! + { #specAttribStatement = #( [ATTRIB] ); } + ; + +specNodeList + : prsNodeExpression ( COMMA! prsNodeExpression )* + ; + +//--------------------------------------------------------------------------- +// The Cast scanner +//--------------------------------------------------------------------------- + +class CastLexer extends Lexer; + +options { + classHeaderSuffix = CastLexerInterface; + charVocabulary = '\0'..'\377'; + exportVocab = Cast; // call the vocabulary "Cast" + testLiterals = true; // automatically test for literals + k = 2; // two characters of lookahead + caseSensitive = true; + caseSensitiveLiterals = true; + defaultErrorHandler = false; +} + +tokens { + BOOL = "bool" ; + DEFINE = "define" ; + FLOAT = "float" ; + FLATTEN = "flatten" ; + IMPORT = "import" ; + INLINE = "inline" ; + INLINE1 = "inline1" ; + INT = "int" ; + NODE = "node" ; + TRUE = "true" ; + FALSE = "false" ; + ENV = "env" ; + // prs + PRS = "prs" ; + AFTER = "after" ; + UNSTAB = "unstab" ; + // java + JAVA = "java" ; + JAVACLASS = "javaclass" ; + INPUTCHAN = "inputchannel" ; + OUTPUTCHAN = "outputchannel" ; + INTERNALCHAN = "internalchannel" ; + // spec + SPEC = "spec" ; + EXCLHI = "exclhi" ; + EXCLLO = "excllo" ; + ATTRIB = "attrib" ; +} + +{ + public Token makeToken(final int t) { + final Token tok = super.makeToken(t); + tok.setColumn(getColumn()); + ((TokenWithInfo) tok).setFilename(getFilename()); + return tok; + } +} + +//--------------------------------------------------------------------------- +// OPERATORS +//--------------------------------------------------------------------------- + +ARROW : "->" ; +PLUS : '+' ; +MINUS : '-' ; +TIMES : '*' ; +DIV : '/' ; +MOD : '%' ; +AND : '&' ; +OR : '|' ; +NOT : '~' ; +COMMA : ',' ; +SEMI : ';' ; +COLON : ':' ; +ASSIGN : '=' ; +EQ : "==" ; +NE : "!=" ; +LT : '<' ; +LE : "<=" ; +GE : ">=" ; +GT : '>' ; +LPAREN : '(' ; +RPAREN : ')' ; +LCURLY : '{' ; +RCURLY : '}' ; +LBRACK : '[' ; +RBRACK : ']' ; +//DOT : '.' ; +DOTDOT : ".." ; +CELEM_ARROW : "#>" ; +COMB_ARROW : "=>" ; +LT_AND : "<&" ; +LT_OR : "<|" ; + +WS + : ( ' ' | '\t' | '\f' | ( '\n' { newline(); } ) ) + { $setType(Token.SKIP); } + ; + +COMMENT_1 + : "/*" + ( options { generateAmbigWarnings=false; } + : { LA(2) != '/' }? '*' + | '\n' {newline();} + | ~('*' | '\n' | '\r') + )* + "*/" + {$setType(Token.SKIP);} + ; + +COMMENT_2 + : "//" (~ '\n' )* '\n' + { $setType(Token.SKIP); newline(); } + ; + +// an identifier. Note that testLiterals is set to true! This means +// that after we match the rule, we look in the literals table to see +// if it's a literal or really an identifer +// XXX: need to fix the "ident" part. This should only accept real +// identifiers. When import is changed to be 'import foo/bar' or +// 'import foo.bar', we can clamp down on what is accepted. +// For now we'll use the horrible hack checkIdent() +IDENT + options {testLiterals=true;} + : ( LETTER | '_' ) ( LETTER | '_' | DIGIT )* + | '"' ( LETTER | DIGIT | '_' | '/' | '.' | '*' )+ '"' + { + final String s = $getText; + final String ss = s.substring(1, s.length() - 1); + $setText(ss); + } + ; + +// a numeric literal or an identifier +NUM_INT + { boolean identP = false; } + : ( DIGIT )+ ( IDENT { $setType(IDENT); identP = true; } )? + ( { LA(2) != '.' && LA(3) != '.' && !identP}? + '.' ( DIGIT )+ ( EXPONENT )? + { $setType(NUM_REAL); } + )? + ; + +DOT_IDENT + : '.' ( IDENT | NUM_INT ) + { + final String s = $getText; + final String ss = s.substring(1); + $setText(ss); + } + ; + +QuotedString + : '\'' (~'\'')* '\'' + { + // strip leading and trailing single quotes + final String s = $getText; + final String ss = s.substring(1, s.length() - 1); + $setText(ss); + } + ; + +protected +EXPONENT + : ( 'e' | 'E' ) ( '+' | '-' )? ( DIGIT )+ + ; + +protected +LETTER + : 'a'..'z' | 'A'..'Z' + ; + +protected +DIGIT + : '0'..'9' + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastLexerInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastLexerInterface.java new file mode 100644 index 0000000000..e786a25595 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastLexerInterface.java @@ -0,0 +1,20 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import antlr.LexerSharedInputState; + +/** + * Lets tools handle multiple versions of cast with specific code only + * for constructors. + **/ +public interface CastLexerInterface { + LexerSharedInputState getInputState(); + void setTokenObjectClass(String cl); + void setFilename(String f); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserEnvironment.java new file mode 100644 index 0000000000..f7ba676807 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserEnvironment.java @@ -0,0 +1,840 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import antlr.ASTFactory; +import antlr.CharScanner; +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.TokenStreamRecognitionException; +import antlr.TokenStreamSelector; +import antlr.collections.AST; + +import com.avlsi.cast2.impl.CastTwoLexer; +import com.avlsi.cast2.impl.CastTwoParser; +import com.avlsi.cast2.impl.CastTwoTreeParser; +import com.avlsi.cast2.impl.CastParsingOption; +import com.avlsi.cast2.impl.DumbTwoLexer; +import com.avlsi.cell.CellImpl; + + +import com.avlsi.util.debug.Debug; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.text.StringUtil; +import com.avlsi.cast2.impl.CastTwoTreeParserTokenTypes; +import com.avlsi.cast2.directive.impl.DirectiveImpl; +import com.avlsi.cast.impl.AmbiguousLookupException; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast.impl.SemanticWrapperException; +import com.avlsi.file.common.HierName; + + +import com.avlsi.io.SearchPath; +import com.avlsi.io.SearchPathFile; +import com.avlsi.io.SearchPathFileFilter; +import com.avlsi.io.SearchPathDirectory; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.SearchPathFileIterator; + +/** + * This class parses a cast file and returns its exported environment. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CastParserEnvironment { + /** + * Map from canonical file name to imported environment. + **/ + private final Map importedEnvMap; + + /** + * The search path for cast files. + **/ + private SearchPath castPath; + + /** + * The environment that is imported by default. This is + * passed to the constructor of every ImportEnvironment. + **/ + private final ImportEnvironment defaultImportEnv; + + + + /** + * The number of anonymous names that have been given out. + * Used by nextAnonymousName to pick the next name. + **/ + private int numAnonymousNames = 0; + + /** + * Keeps track of which version of cast this parses. + **/ + private final String castVersion; + + /** + * Whether the cast 2 parser should warn of outdated syntax or + * not. Not used for the cast 1 parser. + **/ + private final boolean verbose; + + /** + * Caches the file containing a module or a cell. For a module, the key is + * a String. For a cell, the key is a Pair of + * module name, and cell name. The value is the corresponding + * SearchPathFile. + **/ + private final Map /**/ fileForModuleCell; + + /** + * CAST parsing options to be passed to CastTwoTree. + **/ + private final CastParsingOption opt; + + /** + * Number of directive warnings. + **/ + private int directiveWarnings = 0; + + /** + * Constructs a CastParserEnvironment with the given search + * path for cast files. If the defaultImportDir is specified, + * that directory will be searched for in castPath. + * All files in the first occurence of that directory will + * be parsed, and added to the default environment. + * + * @throws FileNotFoundException if the defaultImportDir + * could not be found. + **/ + public CastParserEnvironment(final SearchPath castPath, + final String defaultImportDir) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException + { + this(castPath, defaultImportDir, "1"); + } + + /** + * Constructs a CastParserEnvironment with the given search + * path for cast files. If the defaultImportDir is specified, + * that directory will be searched for in castPath. + * All files in the first occurence of that directory will + * be parsed, and added to the default environment. + * + * @throws FileNotFoundException if the defaultImportDir + * could not be found. + **/ + public CastParserEnvironment(final SearchPath castPath, + final String defaultImportDir, + final String castVersion) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException + { + this(castPath, defaultImportDir, castVersion, false); + } + + /** + * Constructs a CastParserEnvironment with the given search + * path for cast files. If the defaultImportDir is specified, + * that directory will be searched for in castPath. + * All files in the first occurence of that directory will + * be parsed, and added to the default environment. + * + * @throws FileNotFoundException if the defaultImportDir + * could not be found. + **/ + public CastParserEnvironment(final SearchPath castPath, + final String defaultImportDir, + final String castVersion, + final boolean verbose) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException + { + this(castPath,defaultImportDir,castVersion,verbose, + null); + } + + public CastParserEnvironment(final SearchPath castPath, + final String defaultImportDir, + final String castVersion, + final boolean verbose, + final Map importedEnvMap) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException + { + this(castPath, defaultImportDir, castVersion, verbose, importedEnvMap, + null); + } + + public CastParserEnvironment(final SearchPath castPath, + final String defaultImportDir, + final String castVersion, + final boolean verbose, + final Map importedEnvMap, + final CastParsingOption opt) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException + { + this.castPath = castPath; + this.defaultImportEnv = new ImportEnvironment(); + this.castVersion = castVersion; + this.verbose = verbose; + this.importedEnvMap = importedEnvMap==null ? + new HashMap() : importedEnvMap; + this.opt = opt; + this.fileForModuleCell = new HashMap(); + Debug.assertTrue(castVersion.equals("1") || castVersion.equals("2"), + "castversion "+castVersion+" not recognized"); + + if (defaultImportDir != null) { + /** @bug jmr parseDirectory ignores SelfImportException **/ + final Environment[] envs + = parseDirectory(defaultImportDir, new LinkedList()); + for (int i = 0; i < envs.length; ++i) + defaultImportEnv.addEnvironment(envs[i]); + } + } + + public final Environment parseFile( final String fileName, + final LinkedList fileList ) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + return parseFile( fileName, fileList, + new CellImpl( "$env", null, + CellImpl.SYNTHETIC_CELL ) ); + } + + /** + * If the file has not been parsed, parse it, and add it to + * the store of parsed environments. If it has been + * parsed, just return the environment. This handles imports. + * @review jmr we should differentiate between tree errors + * and errors in parsing / lexing + * @param fileList list of files that are currently on the parse + * stack. Used to detect circular and self-importation. + * @param envCell A CellImpl into which instantiations and nodes found outside + * of cell definitions go. + **/ + public final Environment parseFile(final String filename, + final LinkedList fileList, + final CellImpl envCell ) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException + { + return parseFile(castPath.findFile(filename), fileList, envCell ); + } + + public final Environment parseFile( final SearchPathFile file, + final LinkedList fileList ) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + return parseFile( file, fileList, + new CellImpl( "$env", null, + CellImpl.SYNTHETIC_CELL ) ); + } + + public Environment parseFile(final SearchPathFile file, + final LinkedList fileList, + final CellImpl envCell) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + return parseFile(file, fileList, envCell, null); + } + + /** + * If the file has not been parsed, parse it, and add it to + * the store of parsed environments. If it has been + * parsed, just return the environment. This handles imports. + * @review jmr we should differentiate between tree errors + * and errors in parsing / lexing + * @param fileList list of files that are currently on the parse + * stack. Used to detect circular and self-importation. + * @param envCell A CellImpl into which instantiations and nodes found outside + * of cell definitions go. + **/ + private Environment parseFile(final SearchPathFile file, + final LinkedList fileList, + final CellImpl envCell, + final String moduleName) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException + { + final String canonicalFilename = file.getName(); + + final int idx = fileList.indexOf(canonicalFilename); + if (idx == 0) + throw new SelfImportException(); + if (idx > 0) + throw new CircularImportException( + canonicalFilename, new ArrayList(fileList)); + + synchronized(importedEnvMap) { + Environment env + = (Environment) importedEnvMap.get(canonicalFilename); + + if (env == null) { + final InputStream ins = + new BufferedInputStream(file.getStream()); + final AST t = getStreamAST( ins, canonicalFilename); + ins.close(); + final CastTreeParserInterface ctp = getTreeParser(); + ctp.setCastParserEnvironment(this); + + fileList.addFirst(canonicalFilename); + env = ctp.goal(t, envCell, moduleName, fileList); + fileList.removeFirst(); + + importedEnvMap.put(canonicalFilename, env); + } + + return env; + } + } + + /** + * Returns a list of the possible files that a cell could be defined in. + **/ + public static String[] possibleFilenamesForCell( + final String moduleName, + final String cellName) { + + final String[] components = StringUtil.split(moduleName, '.'); + + if (components.length == 1) { + return new String[] { + components[0] + ".cast", + components[0] + File.separatorChar + components[0] + ".cast", + components[0] + File.separatorChar + cellName + ".cast", + }; + } else { + final String fullPath = + StringUtil.join(components, File.separatorChar); + final String[] partialPathComponents = + new String[components.length - 1]; + System.arraycopy(components, 0, + partialPathComponents, 0, + partialPathComponents.length); + final String partialPath = + StringUtil.join(partialPathComponents, File.separatorChar) + + File.separatorChar + components[components.length - 2] + + File.separatorChar + components[components.length - 1]; + return new String[] { + fullPath + ".cast", + fullPath + File.separatorChar + + components[components.length - 1] + ".cast", + fullPath + File.separatorChar + cellName + ".cast", + partialPath + ".cast", + partialPath + File.separatorChar + cellName + ".cast", + }; + } + } + + /** + * Returns a list of the possible files that a module could be defined in. + **/ + public String[] possibleFilenamesForModule(final String moduleName) { + // module t1.t2. ... . tN could be defined in the following files: + // 1: t1/t2/.../tN-1/tN.cast + // 2: t1/t2/.../tN-1/tN/tN.cast + // 3: t1/t2/.../tN-1/tN-1/tN.cast (if N > 1) + + // TODO: factor common code with possibleFilenamesForCell into + // a private possible prefixesForModule + + final String[] components = StringUtil.split(moduleName, '.'); + + if (components.length == 1) { + return new String[] { + components[0] + ".cast", + components[0] + File.separatorChar + components[0] + ".cast", + }; + } else { + final String fullPath = + StringUtil.join(components, File.separatorChar); + final String[] partialPathComponents = + new String[components.length - 1]; + System.arraycopy(components, 0, + partialPathComponents, 0, + partialPathComponents.length); + final String partialPath = + StringUtil.join(partialPathComponents, File.separatorChar) + + File.separatorChar + components[components.length - 2] + + File.separatorChar + components[components.length - 1]; + return new String[] { + fullPath + ".cast", + fullPath + File.separatorChar + + components[components.length - 1] + ".cast", + partialPath + ".cast", + }; + } + } + + public Environment parseFirstFileOf (final String[] fileNames, + final LinkedList fileList, + final String moduleName) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + return parseFirstFileOf(fileNames, fileList, + new CellImpl("$env", null, CellImpl.SYNTHETIC_CELL), + moduleName); + } + + public Environment parseFirstFileOf (final String[] fileNames, + final LinkedList fileList, + final CellImpl envCell, + final String moduleName) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + return parseFile(castPath.findFirstFileOf(fileNames), + fileList, envCell, moduleName); + } + + public Environment parseCell (final LinkedList fileList, + final String moduleName, + final String cellName) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + final Pair p = new Pair(moduleName, cellName); + SearchPathFile firstFile = (SearchPathFile) fileForModuleCell.get(p); + if (firstFile == null) { + final String[] fileNames = + possibleFilenamesForCell(moduleName, cellName); + firstFile = castPath.findFirstFileOf(fileNames); + fileForModuleCell.put(p, firstFile); + } + return parseFile(firstFile, fileList, + new CellImpl("$env", null, CellImpl.SYNTHETIC_CELL), + moduleName); + } + + public Environment parseModule (final LinkedList fileList, + final String moduleName) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + return parseModule(fileList, + new CellImpl("$env", null, CellImpl.SYNTHETIC_CELL), + moduleName); + } + + public Environment parseModule (final LinkedList fileList, + final CellImpl envCell, + final String moduleName) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException, + SelfImportException { + SearchPathFile firstFile = + (SearchPathFile) fileForModuleCell.get(moduleName); + if (firstFile == null) { + final String[] fileNames = possibleFilenamesForModule(moduleName); + firstFile = castPath.findFirstFileOf(fileNames); + fileForModuleCell.put(moduleName, firstFile); + } + return parseFile(firstFile, fileList, envCell, moduleName); + } + + /** + * Returns the AST for the given stream. Does not use the cast path. + * + * @param s input stream to use + * @param filename filename to use for error messages. + * For informational purposes, not used to open the file. + **/ + public AST getStreamAST(final InputStream s, final String filename) + throws RecognitionException, + TokenStreamException + { + final CastParserInterface parser = getParser(s, filename); + + // start parsing at the program rule + parser.goal(); + + return parser.getAST(); + } + + public AST getInstantiationAST( + final String cellName, + final HierName instName) + throws RecognitionException, + TokenStreamException + { + final String instantiation = + cellName + ' ' + instName.getAsString('.'); + final CastParserInterface parser = + getParser(new ByteArrayInputStream(instantiation.getBytes()), + ""); + + // start parsing at the instantiation rule + parser.instantiation(); + + return parser.getAST(); + } + + private CastParserInterface getParser(final InputStream input, + final String filename) { + final TokenStreamSelector selector = new TokenStreamSelector(); + + // Create a scanner that reads from the input stream passed to us + final CastLexerInterface castLexer; + final DumbLexerInterface dumbLexer; + if (castVersion.equals("1")) { + castLexer = new CastLexer(input); + dumbLexer = new DumbLexer(castLexer.getInputState()); + } + else { + castLexer = new CastTwoLexer(input); + dumbLexer = new DumbTwoLexer(castLexer.getInputState()); + } + + castLexer.setFilename(filename); + castLexer.setTokenObjectClass(TokenWithInfo.class.getName()); + + // notify selector about various lexers; + // name them for convenient reference later + selector.addInputStream((CharScanner)castLexer, "castlexer"); + selector.addInputStream((CharScanner)dumbLexer, "dumblexer"); + selector.select("castlexer"); // start with main java lexer + + // Create a parser that reads from the scanner + final CastParserInterface castParser; + if (castVersion.equals("1")) { + castParser = new CastParser(selector); + } + else { + castParser = new CastTwoParser(selector); + ((CastTwoParser) castParser).setVerbosity(verbose); + } + + castParser.setFilename(filename); + castParser.setASTNodeClass(ASTWithInfo.class.getName()); + castParser.setSelector(selector); + + return castParser; + } + + public CastTreeParserInterface getTreeParser() { + if (castVersion.equals("1")) { + return new CastTreeParser(); + } else { + CastTwoTreeParser ctp2 = new CastTwoTreeParser(); + ctp2.setVerbosity(verbose); + if (opt != null) ctp2.setCastParsingOption(opt); + ctp2.setDirectiveErrorHandler( + new DirectiveImpl.ErrorHandler() { + public void error(String message) { + System.err.println("SYNTAX: " + message); + ++directiveWarnings; + } + }); + return ctp2; + } + } + + + public final Environment[] parseDirectory( final String dirName, + final LinkedList fileList ) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException { + return parseDirectory( dirName, fileList, + new CellImpl( "$env", null, + CellImpl.SYNTHETIC_CELL ) ); + } + + /** + * Looks for the first occurence of directory in the cast path, + * throwing an exception if it is not found. Returns an + * array of Environments generated from + * all the .cast files in that directory. Self-imports are ignored. + * @param fileList list of files that are currently on the parse + * stack. Used to detect circular and self-importation. + * + * @bug jmr parseDirectory ignores SelfImportException + * we want things in lib to be able to import lib/*.cast, + * without triggering self-import exception, + * but if lib/foo.cast imports lib/foo.cast explicitly, that is bad! + **/ + public Environment[] parseDirectory(final String dirname, + final LinkedList fileList, + final CellImpl topLevelEnv ) + throws IOException, + RecognitionException, + TokenStreamException, + CircularImportException + { + final SearchPathDirectory f = castPath.findDirectory(dirname); + + final SearchPathFileFilter castFilter = new SearchPathFileFilter() { + public boolean accept(final SearchPathFile pathname) { + return pathname.getName().endsWith(".cast"); + } + }; + + final SearchPathFileIterator fileIter = f.getFiles( castFilter ); + + + final List envList = new ArrayList(); + + while ( fileIter.hasNext() ) { + SearchPathFile currFile = fileIter.next(); + try { + envList.add( parseFile( currFile, fileList, topLevelEnv, + castVersion.equals("1") ? null : + dirname.replace( File.separatorChar, + '.' ) + '.' + + StringUtil.chompEnd( + StringUtil.chompStart( + currFile.getName(), + f.getName() + + File.separatorChar), + ".cast" ) ) ); + } catch (SelfImportException e) { + continue; + } + } + + return (Environment[]) envList.toArray(new Environment[0]); + } + + /** + * Returns a new ImportEnvironment, with the default imports + * already added. + **/ + public ImportEnvironment newImportEnvironment() { + return new ImportEnvironment(defaultImportEnv); + } + + + + /** + * Returns a sequence of strings of the form "$0", "$1", + * "$2", ... . Increments numAnonymousNames as a side effect. + **/ + public String nextAnonymousName() { + return "$" + (numAnonymousNames++); + } + + + private static String getModuleNameFromFullyQualifiedName( final String fullyQualifiedCellName ) { + + final int dotIndex = fullyQualifiedCellName.lastIndexOf( '.' ); + + if ( dotIndex >= 0 ) { + return fullyQualifiedCellName.substring( 0, dotIndex ); + } + else { + return null; + } + } + + private static String getCellNameFromFullyQualifiedName( final String fullyQualifiedCellName ) { + final int dotIndex = fullyQualifiedCellName.lastIndexOf( '.' ); + + if ( dotIndex >= 0 ) { + return fullyQualifiedCellName.substring( dotIndex + 1 ); + } + else { + return null; + } + } + + public CellInterface getFullyQualifiedCell( final String fullyQualifiedCellName) + throws SemanticWrapperException { + + return getFullyQualifiedCell( fullyQualifiedCellName, null, null, new LinkedList() ); + } + + public CellInterface getFullyQualifiedCell( final String fullyQualifiedCellName, + CellImpl parent, + final HierName instance) + throws SemanticWrapperException { + return getFullyQualifiedCell(fullyQualifiedCellName, parent, instance, + new LinkedList()); + } + + public CellInterface getFullyQualifiedCell( final String moduleName, + final String cellName) + throws SemanticWrapperException { + + return getFullyQualifiedCell( moduleName, cellName, new LinkedList()); + } + + public CellInterface getFullyQualifiedCell( final String moduleName, + final String cellName, + CellImpl parent, + final HierName instance) + throws SemanticWrapperException { + return getFullyQualifiedCell( moduleName, cellName, parent, + instance, new LinkedList()); + } + + public CellInterface getFullyQualifiedCell( final String moduleName, + final String cellName, + final LinkedList fileList ) + throws SemanticWrapperException { + return getFullyQualifiedCell( moduleName, cellName, null, null, + fileList); + } + + public CellInterface getFullyQualifiedCell( final String moduleName, + final String cellName, + CellImpl parent, + final HierName inst, + final LinkedList fileList ) + throws SemanticWrapperException { + + Debug.assertTrue( ( moduleName.length() > 0 ), "Module name was empty." ); + + return getCell(NullEnvironment.getInstance(), + moduleName + '.' + cellName, + parent, inst); + } + + public CellInterface getFullyQualifiedCell( final String fullyQualifiedCellName, + CellImpl parent, + final HierName instance, + final LinkedList fileList ) + throws SemanticWrapperException { + + final String cellName = getCellNameFromFullyQualifiedName( fullyQualifiedCellName ); + final String moduleName = getModuleNameFromFullyQualifiedName( fullyQualifiedCellName ); + + if ( moduleName == null ) { + final String s = "fully qualified cell name required, found " + + fullyQualifiedCellName; + throw new SemanticWrapperException(s, + new RecognitionException(s, "", -1, -1)); + } + + return getFullyQualifiedCell( moduleName, cellName, parent, instance, + fileList ); + + } + + public CellInterface getCell(final Environment env, final String cellName) + throws SemanticWrapperException { + return getCell(env, cellName, null, null); + } + + public CellInterface getCell(final Environment env, final String cellName, + CellImpl parent, HierName instName) + throws SemanticWrapperException { + return getCell(env, cellName, parent, instName, null); + } + + /** + * Get the cell interface for a cell, defined in the specified + environment. + **/ + public CellInterface getCell(final Environment env, final String cellName, + CellImpl parent, HierName instName, CellInterface envContainer) + throws SemanticWrapperException { + + + try { + // parent and instName can be null. I'm not sure if this + // is the best way to solve it, but it seems to work --jmr + if (parent == null) + parent = new CellImpl("$fakeEnv", null, + CellImpl.SYNTHETIC_CELL); + if (instName == null) + instName = HierName.makeHierName("__"); + + final AST ast = getInstantiationAST(cellName, instName); + + final CastTreeParserInterface parser = getTreeParser(); + parser.setCastParserEnvironment(this); + + parser.doInstantiation(ast, + getModuleNameFromFullyQualifiedName(cellName), + env, parent, envContainer); + + return parent.getSubcell(instName); + } catch (RecognitionException e) { + throw new SemanticWrapperException("trouble getting a cell", e); + } catch (TokenStreamException e) { + throw new SemanticWrapperException("trouble getting a cell", e); + } + } + + public boolean searchPathContains(final String directoryName) { + return castPath.containsDirectory(directoryName); + } + + public void clearDirectiveWarnings() { + directiveWarnings = 0; + } + + public int getDirectiveWarnings() { + return directiveWarnings; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserInterface.java new file mode 100644 index 0000000000..d28d0d3535 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastParserInterface.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import antlr.collections.AST; +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.TokenStreamSelector; +import antlr.LLkParser; + +/** + * Lets tools handle multiple versions of cast with specific code only + * for constructors. + **/ +public interface CastParserInterface { + void setSelector(final TokenStreamSelector selector); + void goal() throws RecognitionException, TokenStreamException; + void instantiation() throws RecognitionException, TokenStreamException; + void setASTNodeClass(String nodeType); + AST getAST(); + void setFilename(String f); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTree.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTree.g new file mode 100644 index 0000000000..8fd0726315 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTree.g @@ -0,0 +1,1176 @@ +// +// Copyright 2000 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// CAST Tree Parser Grammar (for use with antlr http://www.antlr.org/) +// +// author: Jesse Rosenstock +// + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2000 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastTree.g instead. + // + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast.impl; + + import java.io.FileNotFoundException; + import java.io.IOException; + import java.util.*; + import com.avlsi.cell.CellImpl; + import com.avlsi.cell.CellInterface; + import com.avlsi.cell.ExclusiveNodeSet; + import com.avlsi.cell.NoSuchSubcellException; + import com.avlsi.cell.SubcellCreationException; + import com.avlsi.file.common.HierName; + import com.avlsi.file.common.InvalidHierNameException; + import com.avlsi.prs.ProductionRule; + import com.avlsi.prs.ProductionRuleSet; + import com.avlsi.util.bool.AndBooleanExpression; + import com.avlsi.util.bool.BooleanExpressionInterface; + import com.avlsi.util.bool.HierNameAtomicBooleanExpression; + import com.avlsi.util.bool.OrBooleanExpression; + import com.avlsi.util.debug.Debug; + import com.avlsi.util.exception.AssertionFailure; + import com.avlsi.util.text.StringUtil; +} + +// bring this into sync with cast.g +// rationalize the names + +// import +// handle _ for name + +// spiff up using ideas from TinyBasicTreeWalker.g + +// _ explanation: +// _ allowed? Places where identifiers appear +// Y variableDeclarationStatement T _ +// Y metaParam def T(X _)() +// Y portParam def T()(X _) +// Y loopStatement < _ : N : ... > +// Y/N expression:ident _ +// N expression:field +// N baseType +// N typeDeclaration +// +// The only time a _ is allowed as part of an expression +// is as part of the port real parameter list. Ie X x(a, _) +// +// For var decl / meta param / port param / loop statement, a variable +// is created with an autogenerated name that can never be specifed by +// a user. +// +// For the port real parameter list, a variable of the appropriate +// type and autogenerated name is created. Ie +// define X()(T t) { } +// X x(_) +// is equivalent to +// T autogen_name; +// X x(autogen_name) + +// misc todo: +// ensure only algebraic types in meta params, and non-alg in port +// catch illegal array access + +class CastTreeParser extends TreeParser; + +options { + classHeaderSuffix = CastTreeParserInterface; + importVocab = Cast; + ASTLabelType = "ASTWithInfo"; + defaultErrorHandler = false; +} + +{ + private CastParserEnvironment cpe = null; + + public void setCastParserEnvironment(final CastParserEnvironment cpe) { + this.cpe = cpe; + } + + private SemanticWrapperException semanticWrapperException( + final String message, + final Exception e, + final ASTWithInfo ast) { + return semanticWrapperException(message, e, ast.getFilename(), + ast.getLine(), ast.getColumn()); + } + + private SemanticWrapperException semanticWrapperException( + final Exception e, + final ASTWithInfo ast) { + return semanticWrapperException(e, ast.getFilename(), + ast.getLine(), ast.getColumn()); + } + + private SemanticWrapperException semanticWrapperException( + final Exception e, + final String file, + final int line, + final int column) { + return new SemanticWrapperException(e, file, line, column); + } + + private SemanticWrapperException semanticWrapperException( + final String message, + final Exception e, + final String file, + final int line, + final int column) { + return new SemanticWrapperException(message, e, file, line, column); + } + + private String getLocation(ASTWithInfo ast) { + return ast.getFilename() + ":" + + ast.getLine() + "," + + ast.getColumn(); + } + + /** + * Used to issue warnings. + **/ + private void warn(final String s, final ASTWithInfo astForLoc) { + System.err.println(s + " at " + getLocation(astForLoc)); + } + + // + // commonly used operations to catch and map exceptions + // + + /** + * Lookup sym in env. Turn all exception into + * SemanticWrapperExceptions. + **/ + private Value lookup(final Environment env, + final Symbol sym, + final ASTWithInfo symAST) + throws SemanticWrapperException { + try { + final Value v = env.lookup(sym); + if (v == null) + throw semanticWrapperException("symbol " + symAST.getText() + + " undefined.", new Exception(), symAST); + return v; + } catch (AmbiguousLookupException e) { + throw semanticWrapperException("Symbol " + symAST.getText() + + " exists in multiple imported files. " + + "Use (currently non-existent) import ... as.", + e, symAST); + } + } + + /** + * @param cell the cell that will be affected by any connections + **/ + private void assign(final Value dest, + final Value source, + final CellImpl cell, + final ASTWithInfo astLoc, + final String message) + throws SemanticWrapperException { + try { + dest.assign(source, cell); + } catch (InvalidOperationException e) { + throw semanticWrapperException(message, e, astLoc); + } + } + + private int getInt(final Value v, final ASTWithInfo ast) + throws SemanticWrapperException { + try { + return IntValue.valueOf(v).getValue().intValue(); + } catch (InvalidOperationException e) { + throw semanticWrapperException(e, ast); + } + + } + + /** + * Turns the string into a Symbol. + * If the string is "_", return a symbol of an auto-generated name, + * otherwise, return a symbol of the name. + **/ + private Symbol generateSymbol(final String s) { + return Symbol.create(generateName(s)); + } + + /** + * If the string is "_", return an auto-generated name, + * otherwise, return the string. + **/ + private String generateName(final String s) { + if (s.equals("_")) + return cpe.nextAnonymousName(); + else + return s; + } + + /** + * Returns a collection of BooleanExpressionInterfaces for + * use by LOOP_OR / LOOP_AND (ie the <| ... > / + * <& ... > syntax. + **/ + private Collection loopedExpression( + final ASTWithInfo id, + final Range r, + final Environment env, + final ASTWithInfo prsExpr) + throws RecognitionException { + final List l = new ArrayList(); + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + + l.add(prsExpression(prsExpr, loopEnv)); + } + + return l; + } + + /** + * Converts Value to BoolValue for use in an if guard. + **/ + private BoolValue ifGuard(final Value v, final ASTWithInfo expr) + throws SemanticWrapperException { + try { + return BoolValue.valueOf(v); + } catch (InvalidOperationException e) { + throw semanticWrapperException("if guard " + v + " not bool", + e, expr); + } + } + + /** + * Attempts to convert a value to a PRSExpressionValue, throwing + * a SemanticWrapperException if the conversion is not possible. + **/ + private PRSExpressionValue toPRSExpressionValue( + final Value v, + final ASTWithInfo expr) + throws SemanticWrapperException { + try { + return PRSExpressionValue.valueOf(v); + } catch (InvalidOperationException e) { + throw semanticWrapperException("type not valid for lhs" + + " of a production rule", e, expr); + } + } + + private HierName oppositePowerSupply( + final Environment env, + final HierName powerSupply, + final ASTWithInfo errorAST) throws SemanticWrapperException { + + final String newPowerSupply; + + if (powerSupply.getAsString('.').equals("Vdd!")) + newPowerSupply = "GND"; + else if (powerSupply.getAsString('.').equals("GND!")) + newPowerSupply = "Vdd"; + else + throw new AssertionFailure("bad power supply"); + + try { + return NodeValue.valueOf( + lookup(env, Symbol.create(newPowerSupply), errorAST)) + .getInstanceName(); + } catch (InvalidOperationException exn) { + throw semanticWrapperException("Non-node type for " + + newPowerSupply + ", implied by complex production rule", + exn, errorAST); + } + } + + public void doInstantiation( + final AST t, + final String moduleName, + final Environment env, + final CellImpl parent, + final CellInterface envContainer) + throws RecognitionException { + variableDeclarationStatement(t, new BlockEnvironment(env), + false, parent); + } +} + +goal[CellImpl cell, String moduleName, LinkedList fileList] +returns [Environment exportedEnv] + { + exportedEnv = null; + Debug.assertTrue(cpe != null); + Debug.assertTrue(moduleName == null, "Cast v1 can't handle modules"); + } + : exportedEnv=compilationUnit[cell, fileList] + ; + +compilationUnit[CellImpl cell, LinkedList fileList] +returns [Environment exportedEnv] + { + exportedEnv = null; + final ImportEnvironment importEnv = cpe.newImportEnvironment(); + final TopLevelEnvironment env = new TopLevelEnvironment(importEnv); + } + : ( importDeclaration[cell, importEnv, fileList] )* + ( bodyStatement[env, true, cell] | typeDeclaration[env] )* + { exportedEnv = env.getExportedEnvironment(); } + ; + +importDeclaration[CellImpl cell, ImportEnvironment importEnv, + LinkedList fileList] + : #( IMPORT id:IDENT ) + { + String filename = id.getText(); + + // check for import names of the form foo/foo.cast, + // change them to foo/*.cast + // this will be a temporary hack until we convert the old source + // code + + final String[] splitSlash = StringUtil.split(filename, '/'); + + // if there is one slash + if (splitSlash.length == 2) { + final String[] splitDot = StringUtil.split(splitSlash[1], '.'); + + // if there is one dot after the slash + // and the part before it is the same as before the slash, + // and after the dot is .cast, then change to * + if (splitDot.length == 2 + && splitDot[0].equals(splitSlash[0]) + && splitDot[1].equals("cast")) { + filename = splitSlash[0] + "/*." + splitDot[1]; + } + } + + try { + final String dir = StringUtil.chompEnd(filename, "/*.cast"); + + if (dir != null) { + final Environment[] envs + = cpe.parseDirectory(dir, fileList, cell); + + for (int i = 0; i < envs.length; ++i) + importEnv.addEnvironment(envs[i]); + } else + importEnv.addEnvironment( + cpe.parseFile( filename, fileList, cell)); + } catch (CircularImportException e) { + throw semanticWrapperException(e, id); + } catch (SelfImportException e) { + warn("Warning: self-import of " + filename, id); + } catch (FileNotFoundException e) { + throw semanticWrapperException( "Imported file not found: " + + filename, e, id); + } catch (IOException e) { + throw semanticWrapperException("Error in import", e, id); + } catch (antlr.RecognitionException e) { + throw semanticWrapperException("Error in import", e, id); + } catch (antlr.TokenStreamException e) { + throw semanticWrapperException("Error in import", e, id); + } + } + ; + +// bodyStatementLists don't appear at the top level, so we can +// pass globalP == false to bodyStatement +bodyStatementList[Environment env, CellImpl cell] + : #( BODY_STATEMENT_LIST ( bodyStatement[env, false, cell] )* ) + ; + +// globalP: whether the body statement is at a global level +bodyStatement[Environment env, boolean globalP, CellImpl cell] + : prsBlock[env, cell] + | specBlock[env, cell] + | javaBlock[env, cell] + | dumbBlock + | levelBlock[env, cell] + | block[env, cell, false] + | variableDeclarationStatement[env, globalP, cell] + | loopStatement[env, cell] + | ifStatement[env, cell] + | assignmentStatement[env, cell] + ; + +// bodyP indicates if the block is the body of a function, +// and thus a new environment should NOT be started (because +// the args and body are in the same environment to support +// stupidity such as this: define Y()(T x[0..1]) { T x[2] = z; } +// this should only be temporary. Later, when cflat +// compatability is not an issue, we can do: +// T y[0..2] = x @ { z }; +block[Environment env, CellImpl cell, boolean bodyP] + { final Environment blockEnv = bodyP ? env : new BlockEnvironment(env); } + : #( BLOCK bodyStatementList[blockEnv, cell] ) + ; + +dumbBlock + : DUMB_BLOCK + ; + +levelBlock[Environment env, CellImpl cell] + : #( LEVEL_BLOCK IDENT block[env, cell, false] ) + ; + +// globalP: true if the variableDeclarationStatement occurs at the +// top-level (globally). If so, then a ! will be appended to the +// node name in primitiveType. +variableDeclarationStatement[Environment env, boolean globalP, CellImpl cell] + { final Value v; Value vInit = null; String varName = null; + boolean inlineP = false, flattenP = false; } + : #( VAR_DECL id:IDENT { varName = generateName(id.getText()); } + ( INLINE { flattenP = true; } )? + ( INLINE1 { inlineP = true; } )? + ( FLATTEN { flattenP = true; } )? + v=type[env, cell, HierName.makeHierName(varName), globalP, + inlineP, flattenP, false] + ( vInit=variableInitializer[env] )? ) + { + final Symbol sym = Symbol.create(varName); + + // NOTE that the environment is augmented after the initializer + // is walked + + try { + env.bind(sym, v); + } catch (SymbolRedeclaredException e) { + // it could be a sparse array, check + + // 1: get the old value + final Value vOld = lookup(env, sym, id); + + // 2: The old and new values must both be arrays. + if (!(v instanceof ArrayValue && vOld instanceof ArrayValue)) + throw semanticWrapperException("variable " + id.getText() + + " redeclared", e, id); + + final ArrayValue av = (ArrayValue) v; + final ArrayValue avOld = (ArrayValue) vOld; + + // 3: attempt to augment the array with the new indices + // this may fail if: + // the element types are not the same + // the dimensions don't agree + // the indices are not disjoint + try { + avOld.augment(av); + } catch (InvalidOperationException ee) { + throw semanticWrapperException("Unable to augment sparse" + + " array " + id.getText(), e, id); + } + } + + // foobarbaz + + // assignment of value = tuple takes care of connections. + if (vInit != null) + assign(v, vInit, cell, id, "Incompatible types for initializer" + + " or port list."); + } + ; + +// ASSIGN: returns a non-tuple expression +// PORT_LIST: returns a tuple expression +variableInitializer[Environment env] returns [Value v] + { v = null; } + : #( ASSIGN v=expression[env, false] ) + | #( PORT_LIST v=expressionList[env, true] ) + ; + +// returns an uninitialized value of the appropriate type +// cell: the cell to which nodes and connections should be added +// if processing a port-param list, or body variable declaration, +// null if processing a meta-param list +type[Environment env, CellImpl cell, HierName varName, boolean globalP, + boolean inlineP, boolean flattenP, boolean portP] +returns [Value v] + { final Value vb; SubscriptSpecInterface s = null; v = null; } + : #( TYPE vb=bt:baseType[env, cell, varName, globalP] + ( s=arraySelector[env] )? ) + { + try { + if (s == null) + v = vb; + else + v = ArrayValue.makeArray(vb, s); + + // XXX: keep track of which subcells are port subcells + + // if we have a subcell or node, then add to the list of subcells + if (vb instanceof InstanceValue || vb instanceof NodeValue) { + final HierName name; + final CellInterface subcell; + // TODO: refactor this shit, maybe getting rid of NodeValue + if (vb instanceof InstanceValue) { + final InstanceValue iv = (InstanceValue) vb; + name = iv.getInstanceName(); + subcell = iv.getCell(); + } else { + final NodeValue nv = (NodeValue) vb; + name = nv.getInstanceName(); + subcell = nv.getCell(); + } + + if (s == null) { + cell.addSubcellPair(name, subcell, portP); + + Debug.assertTrue(!(inlineP && flattenP)); + + if (inlineP) + cell.inlineSubcell(name); + if (flattenP) + cell.flattenSubcell(name); + } else { + // we have an array! + final int nElems = s.getNumElements(); + + for (int i = 0; i < nElems; ++i) { + // this duplicates code in ArrayValue.accessArray() + final HierName subcellName; + if (name.isGlobal()) { + final int bangIdx = + name.getSuffixString().indexOf('!'); + Debug.assertTrue(bangIdx == + name.getSuffixString().length() - 1); + subcellName = HierName.makeSiblingName(name, + name.getSuffixString().substring(0, bangIdx) + + DenseSubscriptSpec.idxToString(s.indexOf(i)) + + '!'); + } else { + subcellName = HierName.makeSiblingName(name, + name.getSuffixString() + + DenseSubscriptSpec.idxToString(s.indexOf(i))); + } + cell.addSubcellPair(subcellName, subcell, portP); + + if (inlineP) + cell.inlineSubcell(subcellName); + if (flattenP) + cell.flattenSubcell(subcellName); + } + } + } + + } catch (NoSuchSubcellException e) { + throw (AssertionFailure) + new AssertionFailure("subcell not found to be " + + "flattened or inlined.").initCause(e); + } catch (SubcellCreationException e) { + Debug.assertTrue(false, "original cast cells don't have prs blocks, shouldn't get inlining exceptions: "+e); + } + } + ; + +// returns an instance value of the given type. +// cell: the cell to which nodes and connections should be added +// if processing a port-param list, or body variable declaration, +// null if processing a meta-param list +baseType[Environment env, CellImpl cell, + HierName varName, boolean globalP] returns [Value v] + { v = null; } + : { TupleValue tupleVal; } + #( USER_TYPE id:IDENT tupleVal=expressionList[env, false] ) + { + // 1: check that there is a symbol of the given name + // 2: check that the symbol has a type value + // 3: Restore the environment under which the + // body should be evaluated (the definitin could + // have come from another file) + // Restore the AST for the parameters and bod4y + // 4: make a local environment that will be used for + // the parameters + // 5: bind the meta parameters w/ values + // 6: bind the port parameters w/o values + // 6.5: have we already generated the CellInterface + // for this type + meta params? If so, use it. + // If not, generate it. + // 7: evaluate the body, + + // the port params are bound in variableDeclarationStatement + // by assigning a tuple to the value + + // 1 + final Symbol sym = Symbol.create(id.getText()); + final Value val = lookup(env, sym, id); + + // 2 + if (!(val instanceof UserDefinedValue)) + throw new RuntimeException(val + " not a user defined type"); + final UserDefinedValue typeVal = (UserDefinedValue) val; + + // 3 + final Environment bodyEnv = typeVal.getEnvironment(); + final AST metaParamList = typeVal.getMetaParamList(); + final AST portParamList = typeVal.getPortParamList(); + final AST body = typeVal.getBody(); + + // 4 + final BlockEnvironment paramEnv = new BlockEnvironment(bodyEnv); + + // 5 + metaParamList(metaParamList, paramEnv, tupleVal); + + // 6 + final String typeName + = UserDefinedValue.getTypeName(id.getText(), tupleVal); + // make a temporary subcell to add the nodes / subcells + // in the port list to. It will be thrown away if + // a cached cell is found. + final CellImpl tempSubCell = new CellImpl(typeName); + final ArrayList portList = new ArrayList(); + portParamList(portParamList, paramEnv, tempSubCell, portList); + + // 6.5 + CellImpl subCell = (CellImpl) typeVal.getCell(tupleVal); + if (subCell == null) { + subCell = tempSubCell; + + // 7 + // protect the types of paramter arrays from being + // changed by the body. This is for the same nonsenst + // as the boolean param to block + block(body, paramEnv.protectedArrayEnvironment(), subCell, true); + + typeVal.putCell(tupleVal, subCell); + } + + v = new InstanceValue(varName, subCell, sym, tupleVal, paramEnv, + null, null, + (Symbol []) portList.toArray(new Symbol[0]), new Symbol[0], + new String[0], new int[] { InstanceValue.INLINE_NONE }); + } + | v=primitiveType[env, cell, varName, globalP] + ; + +// return the default value of the appropriate type +// (default is un-initialized, for algebraic types). +// cell: the cell to which nodes and connections should be added +// if processing a port-param list, or body variable declaration, +// null if processing a meta-param list +primitiveType[Environment env, CellImpl cell, HierName varName, + boolean globalP] +returns [Value v] + { v = null; } + : BOOL { v = new BoolValue(); } + | INT { v = new IntValue(); } + | FLOAT { v = new FloatValue(); } + | NODE + { + Debug.assertTrue(varName.getNumComponents() == 1); + + // if the node was declared globally, append '!' to the name + // to flag that it is a global node. this will be used by + // flatten() so that the cell name in not prepended. + if (globalP) { + varName = HierName.makeHierName( + varName.getSuffixString() + '!'); + } + + cell.addNode(varName); + v = new NodeValue(varName); + } + ; + +// all declarations occur in the same environment +typeDeclaration[Environment env] + : #( TYPE_DEFINITION id:IDENT m:FORMALS p:FORMALS b:BLOCK ) + { + try { + final Symbol cellTypeSymbol = Symbol.create( id.getText() ); + env.bind( + cellTypeSymbol, + new UserDefinedValue(env, cellTypeSymbol, m, p, null, b)); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException("type " + id.getText() + + " redeclared", e, id); + } + } + ; + +metaParamList[Environment env, TupleValue tupleVal] + { int i = 0; } + : #( f:FORMALS ( metaParam[env, tupleVal, i++] )* ) + { + if (i != tupleVal.getSize()) + throw semanticWrapperException( + new Exception("wrong # of meta params"), f); + } + ; + +// XXX: enforce that only int,bool,float can be meta-params +metaParam[Environment env, TupleValue tupleVal, int i] + { Value v; } + : #( VAR_DECL id:IDENT + v=type[env, null, HierName.makeHierName(id.getText()), false, false, + false, false] ) + { + try { + final Symbol sym = generateSymbol(id.getText()); + env.bind(sym, v); + // cell is null because it shouldn't be used by assign + v.assign(tupleVal.accessTuple(i), null); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException("meta param " + id.getText() + + " redeclared ", e, id); + } catch (InvalidOperationException e) { + throw semanticWrapperException(e, id); + // XXX: assignment of meta params didn't work! + // probably want to catch this elsewhere! + } + } + ; + +// modifies portList to contain a list of the variable names +// declared in the port parameter list, +// also modifies env by binding an uninitialized value to +// all the variables declared in the port list. +// env: the environment for the subcell +portParamList[Environment env, CellImpl cell, ArrayList portList] + : #( FORMALS ( portParam[env, cell, portList] )* ) + ; + +portParam[Environment env, CellImpl cell, ArrayList portList] + { Value v; } + : #( VAR_DECL id:IDENT + v=type[env, cell, HierName.makeHierName(id.getText()), false, false, + false, true] ) + { + try { + final Symbol sym = generateSymbol(id.getText()); + env.bind(sym, v); + portList.add(sym); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException("port param " + id.getText() + + " redeclared", e, id); + } + } + ; + +// refactor: remove duplication with prsLoopStatement +loopStatement[Environment env, CellImpl cell] + { Range r; } + : #( LOOP id:IDENT r=range[env, true] slist:BODY_STATEMENT_LIST ) + { + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + bodyStatementList(slist, loopEnv, cell); + } + } + ; + +// refactor: remove duplication with prsIfStatement +ifStatement[Environment env, CellImpl cell] + { Value v; } + : #( IF v=expr:expression[env, false] slist:BODY_STATEMENT_LIST ) + { + final BoolValue bv = ifGuard(v, expr); + + try { + if (bv.getValue()) + bodyStatementList(slist, env, cell); + } catch (InvalidOperationException e) { + throw semanticWrapperException("If guard uninitialized.", + e, expr); + } + } + ; + +// fix me up later? +// ( = expr+ expr ) +assignmentStatement[Environment env, CellImpl cell] + { final ArrayList l = new ArrayList(), eList = new ArrayList(); + Value v0, vv; } + : #( ASSIGN v0=e0:expr[env, false] + ( vv=ee:expression[env, false] { l.add(vv); eList.add(ee);} )* ) + { + // xxx use the cell + + // change the * to a +, and this goes away! + Debug.assertTrue(l.size() > 0); + + for (int i = l.size() - 1; i > 0; --i) + assign((Value) l.get(i - 1), (Value) l.get(i), cell, + (ASTWithInfo) eList.get(i - 1), + "assignment failed"); + + assign(v0, (Value) l.get(0), cell, e0, "assignment failed"); + } + ; + +// returns a tuple, this will be converted to an array if needed +// anonymousAllowedP: true if anonymous variables (_) are allowed +// as expressions in the expressionList +expressionList[Environment env, + boolean anonymousAllowedP] returns [TupleValue v] + { final List l = new ArrayList(); Value ve; v = null; } + : #( EXPRESSION_LIST + ( ve=expression[env, anonymousAllowedP] { l.add(ve); } )* ) + { v = new TupleValue((Value []) l.toArray(new Value[0])); } + ; + +// anonymousAllowedP: true if anonymous variables (_) are allowed +// as expressions +expression[Environment env, boolean anonymousAllowedP] returns [Value v] + { v = null; } + : #( EXPRESSION v=expr[env, anonymousAllowedP] ) + ; + +// anonymousAllowedP: true if anonymous variables (_) are allowed +// as expressions +expr[Environment env, boolean anonymousAllowedP] returns [Value v] + // logical + { Value v1, v2; v = null; ASTWithInfo t = null; + Range r; } + : #( o01:OR v1=expr[env, false] v2=expr[env, false] ) + { t = o01; v = v1.or(v2); } + | #( o02:AND v1=expr[env, false] v2=expr[env, false] ) + { t = o02; v = v1.and(v2); } + | #( o03:NOT v1=expr[env, false] ) + { t = o03; v = v1.not(); } + // arithmetic + | #( o04:PLUS v1=expr[env, false] v2=expr[env, false] ) + { t = o04; v = v1.add(v2); } + | #( o05:MINUS v1=expr[env, false] v2=expr[env, false] ) + { t = o05; v = v1.subtract(v2); } + | #( o06:TIMES v1=expr[env, false] v2=expr[env, false] ) + { t = o06; v = v1.multiply(v2); } + | #( o07:DIV v1=expr[env, false] v2=expr[env, false] ) + { t = o07; v = v1.divide(v2); } + | #( o08:MOD v1=expr[env, false] v2=expr[env, false] ) + { t = o08; v = v1.mod(v2); } + | #( o09:UNARY_PLUS v1=expr[env, false] ) + { t = o09; v = v1.unaryPlus(); } + | #( o10:UNARY_MINUS v1=expr[env, false] ) + { t = o10; v = v1.negate(); } + // relational + | #( o11:LT v1=expr[env, false] v2=expr[env, false] ) + { t = o11; v = v1.lt(v2); } + | #( o12:LE v1=expr[env, false] v2=expr[env, false] ) + { t = o12; v = v1.le(v2); } + | #( o13:EQ v1=expr[env, false] v2=expr[env, false] ) + { t = o13; v = v1.eq(v2); } + | #( o14:NE v1=expr[env, false] v2=expr[env, false] ) + { t = o14; v = v1.ne(v2); } + | #( o15:GE v1=expr[env, false] v2=expr[env, false] ) + { t = o15; v = v1.ge(v2); } + | #( o16:GT v1=expr[env, false] v2=expr[env, false] ) + { t = o16; v = v1.gt(v2); } + // selection + | #( o17:FIELD_ACCESS v1=expr[env, false] fi:FIELD_IDENT ) + { t = o17; v = InstanceValue.valueOf(v1).accessField( + Symbol.create(fi.getText()), + FieldedValueInterface.INSTANCE_PERMISSION); } + | { SubscriptSpecInterface s; } + #( o18:ARRAY_ACCESS v1=expr[env, false] s=arraySelector[env] ) + { t = o18; v = ArrayValue.valueOf(v1).accessArray(s); } + // primary + | id:IDENT + { + t = id; + + final String s = id.getText(); + + if (s.equals("_")) { + if (anonymousAllowedP) + v = new AnonymousValue(); + else { + final SemanticException se + = new SemanticException("_ not allowed here", + id.getFilename(), id.getLine(), id.getColumn()); + se.column = id.getColumn(); + throw se; + } + } else + v = lookup(env, Symbol.create(s), id); + } + | n:NUM_INT { t = n; v = IntValue.valueOf(n.getText()); } + | f:NUM_REAL { t = f; v = FloatValue.valueOf(f.getText()); } + | o19:TRUE { t = o19; v = BoolValue.valueOf(true); } + | o20:FALSE { t = o20; v = BoolValue.valueOf(false); } + | #( o21:ARRAY v1=expressionList[env, false] ) + { t = o21; v = ArrayValue.fromTuple(v1); } + // prs stuff + /// XXX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // uhm!!! should be looking symbols up in symbol table!!!!!!! + | #( o22:PRS_AND v1=expr[env, false] v2=expr[env, false] ) + { t = o22; v = PRSExpressionValue.valueOf(v1).and(v2); } + | #( o23:PRS_OR v1=expr[env, false] v2=expr[env, false] ) + { t = o23; v = PRSExpressionValue.valueOf(v1).or(v2); } + | #( o24:PRS_NOT v1=expr[env, false] ) + { t = o24; v = PRSExpressionValue.valueOf(v1).not(); } + // merge these two into something like: + // LOOPED_OP ( AND | OR ) IDENT range EXPRESSION + | #( o25:LOOP_OR id2:IDENT r=range[env, true] e2:PRS_EXPRESSION ) + { v = new PRSExpressionValue( + new OrBooleanExpression(true, + loopedExpression(id2, r, env, e2))); } + | #( o26:LOOP_AND id3:IDENT r=range[env, true] e3:PRS_EXPRESSION ) + { v = new PRSExpressionValue( + new AndBooleanExpression(true, + loopedExpression(id3, r, env, e3))); } + ; + exception + catch [InvalidOperationException e] { + throw semanticWrapperException(e, t); + } + +// loopP indicates how a singleton range should be interpreted +// true: it will be interpreted as 0..n-1 +// false: it will be interpreted as n..n +range[Environment env, boolean loopP] returns [Range r] + { Value v1, v2 = null; r = null; } + : #( RANGE v1=e1:expression[env, false] + ( v2=e2:expression[env, false] )? ) + { + final int i1 = getInt(v1, e1); + + if (v2 == null) { + if (loopP) + r = new Range(0, i1 - 1); + else + r = new Range(i1, i1); + } else { + final int i2 = getInt(v2, e2); + + r = new Range(i1, i2); + } + } + ; + +arraySelector[Environment env] returns [SubscriptSpecInterface s] + { ArrayList l = new ArrayList(); Range r; s = null; } + : #( ARRAY_SUB ( r=range[env, false] { l.add(r); } )* ) + { s = new DenseSubscriptSpec((Range []) l.toArray(new Range[0])); } + //: #( RANGE_LIST ( range )* ) + ; + +// +// PRS stuff +// + +prsBlock[Environment env, CellImpl cell] + : #( PRS prsStatements[env, cell, false] ) + ; + +/// xxx: do the env shit! +prsEnvBlock[Environment env, CellImpl cell] + : #( ENV prsStatements[env, cell, true] ) + ; + +// envP: flag saying if the pr was declared in an env block +prsStatements[Environment env, CellImpl cell, boolean envP] + : #( BODY_STATEMENT_LIST ( prsStatement[env, cell, envP] )* ) + ; + +// envP: flag saying if the pr was declared in an env block +prsStatement[Environment env, CellImpl cell, boolean envP] + : prsIfStatement[env, cell, envP] + | prsLoopStatement[env, cell, envP] + | prsAction[env, cell, envP] + | prsEnvBlock[env, cell] + ; + +// envP: flag saying if the pr was declared in an env block +// todo: refactor: remove duplication with ifStatement +prsIfStatement[Environment env, CellImpl cell, boolean envP] + { Value v; } + : #( IF v=expr:expression[env, false] prslist:BODY_STATEMENT_LIST ) + { + final BoolValue bv = ifGuard(v, expr); + + try { + if (bv.getValue()) + prsStatements(prslist, env, cell, envP); + } catch (InvalidOperationException e) { + throw semanticWrapperException("If guard uninitialized.", + e, expr); + } + } + ; + +// envP: flag saying if the pr was declared in an env block +// todo: refactor, remove duplication with loopStatement +prsLoopStatement[Environment env, CellImpl cell, boolean envP] + { Range r; } + : #( LOOP id:IDENT r=range[env, true] prslist:BODY_STATEMENT_LIST ) + { + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + prsStatements(prslist, loopEnv, cell, envP); + } + } + ; + +// envP: flag saying if the pr was declared in an env block +prsAction[Environment env, CellImpl cell, boolean envP] + { ProductionRule pr1, pr2 = null; + ProductionRuleSet prs; + if (envP) + prs = cell.getAssertedProductionRuleSet(); + else + prs = cell.getProductionRuleSet(); + } + // merge these + : ( #( ARROW pr1=prsActionBody[env, cell] ) + | #( celem:CELEM_ARROW pr1=pab:prsActionBody[env, cell] ) + { pr2 = + pr1.cElementComplement( + oppositePowerSupply(env, pr1.getPowerSupply(), celem)); } + | #( comb:COMB_ARROW pr1=prsActionBody[env, cell] ) + { pr2 = + pr1.combinationalComplement( + oppositePowerSupply(env, pr1.getPowerSupply(), comb)); } + ) { prs.addProductionRule(pr1); + if (pr2 != null) + prs.addProductionRule(pr2); + } + ; + +prsActionBody[Environment env, CellImpl cell] +returns [ProductionRule pr] + { + Value av, rhsv; + BooleanExpressionInterface be; + boolean unstabP = false, timedP = false; + int afterTimeSteps = -1; // negative means unspecified -- AML + int dir; + ASTWithInfo exp; + } + : ( UNSTAB {unstabP = true;} )? + ( AFTER av=e:expression[env, false] + { afterTimeSteps = getInt(av, e); } )? + be=prsExpression[env] rhsv=expr[env, false] + ( p:PLUS { dir=ProductionRule.UP; exp=p; } + | m:MINUS { dir=ProductionRule.DOWN; exp=m; } ) + { + final NodeValue nv = (NodeValue) rhsv; + final HierName rhsNode = nv.getInstanceName(); + + final String rail = dir == ProductionRule.UP ? "Vdd" : "GND"; + final HierName railName; + try { + final Symbol s = Symbol.create(rail); + final Value v = lookup(env, s, exp); + railName = NodeValue.valueOf(v).getInstanceName(); + final NodeValue railNode = new NodeValue(railName); + + cell.addNode(railName); + } catch (InvalidOperationException exn) { + throw semanticWrapperException("Non-node type for " + rail + + ", implied by production rule", + exn, exp); + } + + pr = new ProductionRule(be, rhsNode, railName, dir, false, unstabP, + false, timedP, afterTimeSteps, false); + } + ; + +// this returns a BooleanExpressionInterface, suitable for use as the +// lhs of a production rule, and nowhere else +prsExpression[Environment env] returns [BooleanExpressionInterface be] + { Value prsv; } + : #( PRS_EXPRESSION prsv=exp:expr[env, false] ) + { be = toPRSExpressionValue(prsv, exp).getBooleanExpression(); } + ; + +// Java Block +javaBlock[Environment env, CellImpl cell] + : #( JAVA javaStatements[env, cell] ) + ; + +javaStatements[Environment env, CellImpl cell] + : #( BODY_STATEMENT_LIST ( javaStatement[env, cell] )* ) + ; + +javaStatement[Environment env, CellImpl cell] + : javaClassStatement[env, cell] + | inputChannelStatement[env, cell] + | outputChannelStatement[env, cell] + | internalChannelStatement[env, cell] + ; + +javaClassStatement[Environment env, CellImpl cell] + : #( JAVACLASS cls:QuotedString ) { cell.setJavaClass(cls.getText()); } + ; + +inputChannelStatement[Environment env, CellImpl cell] + : #( INPUTCHAN cls:QuotedString ) { cell.setInputChannel(cls.getText()); } + ; + +outputChannelStatement[Environment env, CellImpl cell] + : #( OUTPUTCHAN cls:QuotedString ) { cell.setOutputChannel(cls.getText()); } + ; + +internalChannelStatement[Environment env, CellImpl cell] + : #( INTERNALCHAN cls:QuotedString ) { cell.setInternalChannel(cls.getText()); } + ; + + + +// +// SPEC stuff +// + +specBlock[Environment env, CellImpl cell] + : #( SPEC specStatements[env, cell] ) + ; + +specStatements[Environment env, CellImpl cell] + : ( specStatement[env, cell] )* + ; + +specStatement[Environment env, CellImpl cell] + : specExclStatement[env, cell] + | specAttribStatement[env, cell] + ; + +specExclStatement[Environment env, CellImpl cell] + { int hiLo; List l; } + : ( #( EXCLHI l=specNodeList[env] {hiLo = ExclusiveNodeSet.HI;} ) + | #( EXCLLO l=specNodeList[env] {hiLo = ExclusiveNodeSet.LO;} ) + ) + { cell.getLocalExclusiveNodeSets().addExclusiveNodeSet(new ExclusiveNodeSet(hiLo, l)); } + ; + +specAttribStatement[Environment env, CellImpl cell] + : ATTRIB + ; + +// returns a List of HierNames +specNodeList[Environment env] returns [ArrayList l] + { Value v; l = new ArrayList(); } + : ( v=exp:expr[env, false] + { + try { + l.add(NodeValue.valueOf(v).getInstanceName()); + } catch (InvalidOperationException e) { + throw semanticWrapperException("Non-node type where " + + "node type expected.", e, exp); + } + } + )+ + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTreeParserInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTreeParserInterface.java new file mode 100644 index 0000000000..9cd395b693 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CastTreeParserInterface.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import java.util.LinkedList; +import antlr.collections.AST; +import antlr.RecognitionException; +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.common.HierName; + +/** + * Lets tools handle multiple versions of cast with specific code only + * for constructors. + **/ +public interface CastTreeParserInterface { + void setCastParserEnvironment(final CastParserEnvironment cpe); + Environment goal(AST _t, CellImpl cell, String moduleName, + LinkedList fileList) + throws RecognitionException; + void doInstantiation(AST t, String moduleName, + Environment env, CellImpl parent, + CellInterface envContainer) + throws RecognitionException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CellInterfaceCollectionIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CellInterfaceCollectionIterator.java new file mode 100644 index 0000000000..794d8a312b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CellInterfaceCollectionIterator.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cell.CellInterface; + + +/** + Iterator that iterates over collections of CellInterfaces. + @see com.avlsi.cell.CellInterface + */ +public interface CellInterfaceCollectionIterator { + + /** + Determines if there is another CellInterface in the collection being iterated. + @return true if there is another CellInterface in the collection being iterated. + */ + boolean hasNext(); + + /** + Gets the next CellInterface in the collection being iterated. + @return The next CellInterface in the collection being iterated. + + @throws NoSuchElementException + */ + CellInterface next() throws CastSemanticException; + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainEnvironment.java new file mode 100644 index 0000000000..536e8fc27d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainEnvironment.java @@ -0,0 +1,90 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + + +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; +import com.avlsi.cast.impl.ChainedEnvironmentIterator; + +/** + * This class represents environments for block scoping. Declarations + * are made within the environment, and will disappear at the end of the + * block. Lookups that fail locally are forwarded to the parent + * environment. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class ChainEnvironment implements Environment { + private Environment parentEnv; + private Environment childEnv; + + public ChainEnvironment(final Environment parentEnv, + final Environment childEnv) { + if (parentEnv == null) + throw new IllegalArgumentException("parentEnv was null"); + if (childEnv == null) + throw new IllegalArgumentException("childEnv was null"); + + this.parentEnv = parentEnv; + this.childEnv = childEnv; + } + + /** + * Binds the value to the symbol in the child environment. + **/ + public void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + childEnv.bind(sym, val); + } + + /** + * Looks up the value in the child environenment. If + * it is not found there, lookup in the parent environment. + * This nececcisates using a NullEnvironment at the top level. + **/ + public Value lookup(final Symbol sym) + throws AmbiguousLookupException { + final Value v = childEnv.lookup(sym); + if (v != null) + return v; + return parentEnv.lookup(sym); + } + + /** Checks the child environment first, then the parent. **/ + public boolean contains(final Symbol sym) { + return(childEnv.contains(sym) || parentEnv.contains(sym)); + } + + public EnvironmentIterator iterator() { + return new ChainedEnvironmentIterator( childEnv, parentEnv ); + } + + public EnvironmentEntryIterator entryIterator() { + return new ChainedEnvironmentEntryIterator( childEnv, parentEnv ); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("ChainEnvironment(\n"); + sb.append("parent:"); + sb.append(parentEnv.toString()); + sb.append(",me:\n"); + sb.append(childEnv.toString()); + sb.append(")\n"); + + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentEntryIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentEntryIterator.java new file mode 100644 index 0000000000..138c41e921 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentEntryIterator.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.cast.impl; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Set; + +import com.avlsi.util.container.FlatteningIterator; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.functions.UnaryPredicate; + +/** + An iterator that will iterate over one environment and then another. + */ +public class ChainedEnvironmentEntryIterator implements EnvironmentEntryIterator { + /** + * Makes an EnvironmentEntryIterator an Iterator. + **/ + private static class IteratorAdapter implements Iterator { + private final EnvironmentEntryIterator eei; + public IteratorAdapter(final EnvironmentEntryIterator eei) { + this.eei = eei; + } + public boolean hasNext() { + return eei.hasNext(); + } + public Object next() { + return eei.next(); + } + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * Only iterate over EnvironmentEntries that haven't been seen before. + **/ + private Iterator uniqueIterator(final EnvironmentEntryIterator iter) { + return new FilteringIterator( + new IteratorAdapter(iter), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + final EnvironmentEntry ee = (EnvironmentEntry) o; + return seen.add(ee.getName()); + }}); + } + + /** + * The underlying iterator. + **/ + private final Iterator iter; + + /** + * Contains symbols already seen + **/ + private final Set seen; + + /** + @param first The first environment to iterate over. + @param second The second environment to iterate over. + */ + public ChainedEnvironmentEntryIterator( Environment first, + Environment second ){ + this( first.entryIterator(), second.entryIterator() ); + } + + /** + @param first An iterator into the first environment to iterate over. + @param second An iterator into the second environment to iterate over. + */ + public ChainedEnvironmentEntryIterator( EnvironmentEntryIterator first, + EnvironmentEntryIterator second ) { + seen = new HashSet(); + iter = + new FlatteningIterator( + Arrays.asList( + new Object[] { + uniqueIterator(first), + uniqueIterator(second) }).iterator()); + } + + public final boolean hasNext() { + return iter.hasNext(); + } + + public final EnvironmentEntry next() { + return (EnvironmentEntry) iter.next(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentIterator.java new file mode 100644 index 0000000000..8d1cb4d6e3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ChainedEnvironmentIterator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.cast.impl; + +import java.util.Map.Entry; +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; + + +/** + An iterator that will iterate over one environment and then another. + */ +public class ChainedEnvironmentIterator implements EnvironmentIterator { + + private final EnvironmentIterator m_FirstIter; + private final EnvironmentIterator m_SecondIter; + + /** + @param first The first environment to iterate over. + @param second The second environment to iterate over. + */ + public ChainedEnvironmentIterator( Environment first, Environment second ){ + this( first.iterator(), second.iterator() ); + } + + /** + @param first An iterator into the first environment to iterate over. + @param second An iterator into the second environment to iterate over. + */ + public ChainedEnvironmentIterator( EnvironmentIterator first, EnvironmentIterator second ) { + m_FirstIter = first; + m_SecondIter = second; + } + + public final boolean hasNext() { + return m_SecondIter.hasNext() || m_FirstIter.hasNext(); + } + + public final EnvironmentEntry next() { + if ( m_FirstIter.hasNext() ) { + return m_FirstIter.next(); + } + else { + return m_SecondIter.next(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CircularImportException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CircularImportException.java new file mode 100644 index 0000000000..91c7941011 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/CircularImportException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import java.util.Collection; + +/** + * Exception thrown when a cast file tries to import a file that + * has imported it. + * + * @see CastParserEnvironment + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CircularImportException extends Exception { + private final String currentImport; + private final Collection importedFiles; + public CircularImportException(final String currentImport, + final Collection importedFiles) { + this.currentImport = currentImport; + this.importedFiles = importedFiles; + } + public Collection getImportedFiles() { + return importedFiles; + } + public String getCurrentImport() { + return currentImport; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ClassType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ClassType.java new file mode 100644 index 0000000000..5b49a18302 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ClassType.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * An implementation of Type that compares only based on the type name. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class ClassType extends Type { + private final String typeName; + + public ClassType(final String typeName) { + this.typeName = typeName; + } + + public boolean equals(final Object o) { + return o instanceof ClassType && equals((ClassType) o); + } + + public boolean equals(final ClassType ct) { + // == is ok because the strings are all hardcoded at + // compile time + return typeName == ct.typeName; + } + + public int hashCode() { + return typeName.hashCode(); + } + + public String toString() { + return "ClassType(" + typeName + ")"; + } + + public String getString() { + return typeName; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DenseSubscriptSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DenseSubscriptSpec.java new file mode 100644 index 0000000000..1f11fb1795 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DenseSubscriptSpec.java @@ -0,0 +1,214 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.tools.cosim.CoSimChannelNames; +import com.avlsi.util.debug.Debug; + +/** + * This class represents subscripting specification for arrays, + * ie [K..L,M..N] + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class DenseSubscriptSpec implements SubscriptSpecInterface { + private final Range[] ranges; + + /** + * Class constructor. + * + * @throws IllegalArgumentException If the min exceeds the max for + * any of the ranges. + **/ + public DenseSubscriptSpec(final Range[] ranges) { + this.ranges = new Range[ranges.length]; + + for (int i = 0; i < ranges.length; ++i) { + if (ranges[i].getMin() > ranges[i].getMax()) + throw new IllegalArgumentException("range min > max in spec: " + + ranges[i].getMin() + ">" + + ranges[i].getMax()); + this.ranges[i] = ranges[i]; + } + } + + public int getNumElements() { + int s = 1; + for (int i = 0; i < ranges.length; ++i) + s *= getSizeForDimension(i); + return s; + } + + public int getNumDimensions() { + return ranges.length; + } + + public int getSizeForDimension(int nDim) { + return ranges[nDim].size(); + } + + public int positionOf(final int[] idx) { + if (idx.length != getNumDimensions()) + throw new IllegalArgumentException("dims don't agree: " + + idx.length + "!=" + + getNumDimensions()); + + int pos = 0; + for (int i = 0; i < idx.length; ++i) { + if (!ranges[i].contains(idx[i])) + throw new IndexOutOfBoundsException("subscript " + idx[i] + + " out of range " + + ranges[i]); + + pos = pos * getSizeForDimension(i) + + (idx[i] - ranges[i].getMin()); + } + + return pos; + } + + public int[] indexOf(int pos) { + if (pos < 0 || pos >= getNumElements()) + throw new IllegalArgumentException("This array doesn't have a " + + pos + "th element"); + + final int[] a = new int[getNumDimensions()]; + int off = getNumElements(); + + for (int i = 0; i < a.length; ++i) { + off /= getSizeForDimension(i); + final int zeroIdxPos = pos / off; + pos -= zeroIdxPos * off; + a[i] = zeroIdxPos + ranges[i].getMin(); + } + + Debug.assertTrue(off == 1); + + return a; + } + + /** + * Returns the range for dimension idim. Safe because Range is + * immutable. + **/ + public Range getRange(int idim) { + return ranges[idim]; + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("["); + + for (int i = 0; i < ranges.length; ++i) { + if (i > 0) + sb.append(","); + + sb.append(ranges[i].toString()); + } + + sb.append("]"); + + return sb.toString(); + } + + public static String idxToString(final int[] idx) { + final StringBuffer sb = new StringBuffer(); + + sb.append("["); + + for (int i = 0; i < idx.length; ++i) { + if (i > 0) + sb.append(","); + + sb.append(idx[i]); + } + + sb.append("]"); + + return sb.toString(); + } + + /** + * Returns true if the two subscript specs have exactly the + * same number of dimensions, and the same indexes exist in + * each dimension. + **/ + public boolean equals(final Object o) { + return o instanceof DenseSubscriptSpec + && equals((DenseSubscriptSpec) o); + } + + /** + * Returns true if the two subscript specs have exactly the + * same number of dimensions, and the same indexes exist in + * each dimension. + **/ + public boolean equals(final DenseSubscriptSpec s) { + if (ranges.length != s.ranges.length) + return false; + else { + for (int i = 0; i < ranges.length; ++i) + if (!ranges[i].equals(s.ranges[i])) + return false; + + return true; + } + } + + /** + * Constructs the spec for CoSimChannelNames, based on this spec. + **/ + private DenseSubscriptSpec getCoSimSpec(boolean ignoreLastDimension) { + final int numDimensions; + if (ignoreLastDimension) + numDimensions = this.getNumDimensions() - 1; + else + numDimensions = this.getNumDimensions(); + + final Range[] ranges = new Range[numDimensions]; + // Bug 917: Previously, new ranges were being created + // [0 .. old_max - old_min]. I think that this was a mistake, + // so now we will use the same range --jmr + System.arraycopy(this.ranges, 0, ranges, 0, ranges.length); + + return new DenseSubscriptSpec(ranges); + } + + /** + * Returns an array of names. Under the cosim framework, each of + * these names corresponds to a NodeChannel. + * + * @param baseName the name of the overall array + * @param ignoreLastDimension Arrays of wide channels use the last + * dimension as channelwidth, so cosim names for that array should + * ignore that dimension + **/ + public CoSimChannelNames getCoSimChannelNames(String baseName, + boolean ignoreLastDimension) { + final DenseSubscriptSpec newSpec = getCoSimSpec(ignoreLastDimension); + final String[] vals = new String[newSpec.getNumElements()]; + + for (int i=0; i 0 ) { + System.err.println("Parsing..."); + + // for each directory/file specified on the command line + for(int i=0; i< args.length;i++) + doFile(new File(args[i])); // parse it + } + else + System.err.println("Usage: java DumbParser "); + + } + catch(Exception e) { + System.err.println("exception: "+e); + e.printStackTrace(System.err); // so we can get stack trace + } + } + + + // This method decides what action to take based on the type of + // file we are looking at + public static void doFile(File f) throws Exception { + // If this is a directory, walk each file/dir in that directory + if (f.isDirectory()) { + String files[] = f.list(); + for(int i=0; i < files.length; i++) + doFile(new File(f, files[i])); + } + + // otherwise, if this is a Dumb file, parse it! + else { + System.err.println(f.getName()); + System.err.println(" "+f.getAbsolutePath()); + parseFile(new FileInputStream(f)); + } + } + + // Here's where we do the real work... + public static void parseFile(InputStream s) throws Exception { + try { + // Create a scanner that reads from the input stream passed to us + DumbLexer lexer = new DumbLexer(s); + + // Create a parser that reads from the scanner + DumbParser parser = new DumbParser(lexer); + + // start parsing at the program rule + parser.goal(); + } + catch (Exception e) { + System.err.println("parser exception: "+e); + e.printStackTrace(); // so we can get stack trace + } + +} +} + +goal + : (dumbBlock)* RCURLY + ; + +dumbBlock + : d:DUMB_BLOCK + //{ System.err.println(d.getText()); } + ; + +class DumbLexer extends Lexer; + +options { + classHeaderSuffix = DumbLexerInterface; + charVocabulary = '\0'..'\377'; + exportVocab = Dumb; + filter = true; +} + +RCURLY : '}' ; + +DUMB_BLOCK + : ( '{' (DUMB_BLOCK)* '}' | ('\n' { newline(); }) | NONBRACE ) + ; + +protected +NONBRACE + : (options { generateAmbigWarnings = false; } : + ('\n' { newline(); } ) | ('\0'..'z') | '|' | ('~'..'\377')) + { $setType(Token.SKIP); } + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbLexerInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbLexerInterface.java new file mode 100644 index 0000000000..784ddfcda4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbLexerInterface.java @@ -0,0 +1,20 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import antlr.LexerSharedInputState; + +/** + * Lets tools handle multiple versions of cast with specific code only + * for constructors. + **/ +public interface DumbLexerInterface { + LexerSharedInputState getInputState(); + void setTokenObjectClass(String cl); + void setFilename(String f); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbParserInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbParserInterface.java new file mode 100644 index 0000000000..62753213bd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/DumbParserInterface.java @@ -0,0 +1,15 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +/** + * Lets tools handle multiple versions of cast with specific code only + * for constructors. + **/ +public interface DumbParserInterface { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Environment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Environment.java new file mode 100644 index 0000000000..6dd14b2f5a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Environment.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cast.impl.EnvironmentIterator; + +/** + * This class represents environments. You can bind a value to a symbol, + * and lookup the value of a symbol. The value contains the type + * information, and is responsible for allowing and disallowing operations. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public interface Environment { + /** + * @throws InvalidBindException + **/ + void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException; + + boolean contains(final Symbol sym); + + Value lookup(final Symbol sym) throws AmbiguousLookupException; + + EnvironmentIterator iterator(); + + /** + * Returns an iterator over all key/value pairs in the environment. + **/ + EnvironmentEntryIterator entryIterator(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntry.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntry.java new file mode 100644 index 0000000000..dc65cd41e6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntry.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +/** + * A type-safe key/value pair of {@link Symbol} and {@link Value} + * representing names accessable in an {@link Environment} and their + * value. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class EnvironmentEntry { + private final Symbol name; + private final Value value; + + EnvironmentEntry(Symbol name, Value value) { + this.name = name; + this.value = value; + } + + public Symbol getName() { + return name; + } + + public Value getValue() { + return value; + } + + public String toString() { + return getClass().getName() + '[' + name + ':' + value + ']'; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntryIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntryIterator.java new file mode 100644 index 0000000000..4f16fc8507 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentEntryIterator.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + + +/** + * Interface to an iterator that iterates over all the values in an + * environment. The set of entries returned by the iterator must be exactly + * the same set of entries that could be looked up through the Environment + * interface. This means that one key must never appear in more than one + * entry. + **/ +public interface EnvironmentEntryIterator { + /** + * Determines if the iteration has another element. + * @return true if there is another element in the iteration, false + * otherwise. + **/ + boolean hasNext(); + + /** + * Retrieves the next element in the iteration. + * @return The next element in the iteration. + * @throws NoSuchElementException + **/ + EnvironmentEntry next(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentIterator.java new file mode 100644 index 0000000000..86c481f0d8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/EnvironmentIterator.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + + +import com.avlsi.cast.impl.Value; + +/** + Interface to an iterator that iterates over all the values in an environment. + */ +public interface EnvironmentIterator { + /** + Determines if the iteration has another element. + @return true if there is another element in the iteration, false otherwise. + */ + boolean hasNext(); + + /** + Retrieves the next element in the iteration. + @return The next element in the iteration. + @throws NoSuchElementException + */ + EnvironmentEntry next(); +// Value next(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FieldedValueInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FieldedValueInterface.java new file mode 100644 index 0000000000..9791a6fce1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FieldedValueInterface.java @@ -0,0 +1,18 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +/** + * Interface for Values which can have fields accessed. + **/ +public interface FieldedValueInterface { + int ALL_PERMISSION = 0; + int INSTANCE_PERMISSION = 1; + Value accessField(final Symbol sym, final int permission) + throws InvalidOperationException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FixedBlockEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FixedBlockEnvironment.java new file mode 100644 index 0000000000..07e660bd6f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FixedBlockEnvironment.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + +/** + * Like BlockEnvironment, but doesn't allow definitions in the parent + * environment to be overriden by definitions in the child + * environment. "Fixed" in this case means fixed in place, static. + **/ + +public class FixedBlockEnvironment extends BlockEnvironment { + + public FixedBlockEnvironment(final Environment parentEnv) { + super(parentEnv); + } + + public FixedBlockEnvironment(final Environment parentEnv, + final LocalEnvironment localEnv) { + super(parentEnv, localEnv); + } + + /** + * Binds the value to the symbol in the local environment. Does + * not allow binding of a symbol already bound in the parent + * environment. + **/ + public void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + if (parentEnv.contains(sym)) { + throw new SymbolRedeclaredException(sym); + } + localEnv.bind(sym, val); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FloatValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FloatValue.java new file mode 100644 index 0000000000..17ef5ab6e7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/FloatValue.java @@ -0,0 +1,217 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.fast.metaparameters.FloatMetaParam; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; + +/** + * This class represents floating point values. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class FloatValue + extends Value + implements FloatMetaParam, MetaParamValueInterface { + + /** + * Value, a double. + **/ + private double val; + + /** + * Returns a FloatValue whose value is equal to that of the specified + * double. + **/ + public static FloatValue valueOf(double val) { + return new FloatValue(val); + } + + /** + * Returns an FloatValue whose value is equal to that of the specified + * Value. Throws InvalidOperationException if the value is not + * an FloatValue or an IntValue. + **/ + public static FloatValue valueOf(Value v) + throws InvalidOperationException { + if (v instanceof IntValue) + return valueOf(((IntValue) v).doubleValue()); + if (v instanceof FloatValue) + return (FloatValue) v; + else + throw new InvalidOperationException + (v.getType().getString() + " is not an integer or a float"); + } + + public static FloatValue castFrom(final Value v) + throws InvalidOperationException { + if (v instanceof IntValue || v instanceof FloatValue) + return valueOf(v); + else if (v instanceof BoolValue) + return valueOf(((BoolValue) v).getValue() ? 1 : 0); + else + throw new InvalidOperationException( + "Cannot cast " + v.getType().getString() + " to " + + TYPE.getString()); + } + + public static FloatValue valueOf(final String s) + throws InvalidOperationException { + try { + return valueOf(Double.parseDouble(s)); + } catch (NumberFormatException e) { + throw new InvalidOperationException("bad float val;" + + e.getMessage(), e); + } + } + + /** + * Class constructor. + **/ + public FloatValue(double val) { + super(true); + this.val = val; + } + + public FloatValue() { + super(false); + this.val = Double.NaN; + } + + public double getValue() throws InvalidOperationException { + ensureDefined(); + return val; + } + + public Value duplicate() { + if (isDefined()) + return new FloatValue(val); + else + return new FloatValue(); + } + + + // arithmetic + + public Value add (final Value v) throws InvalidOperationException { + return valueOf(getValue() + valueOf(v).getValue()); + } + + public Value subtract (final Value v) throws InvalidOperationException { + return valueOf(getValue() - valueOf(v).getValue()); + } + + public Value multiply (final Value v) throws InvalidOperationException { + return valueOf(getValue() * valueOf(v).getValue()); + } + + public Value divide (final Value v) throws InvalidOperationException { + return valueOf(getValue() / valueOf(v).getValue()); + } + + public Value unaryPlus() throws InvalidOperationException { + return valueOf(getValue()); + } + + public Value negate () throws InvalidOperationException { + return valueOf(-getValue()); + } + + + // relational, screwey floating point ordering, but that's hidden + + public Value lt (final Value v) throws InvalidOperationException + { return BoolValue.valueOf(getValue() < valueOf(v).getValue()); } + public Value le (final Value v) throws InvalidOperationException + { return BoolValue.valueOf(getValue() <= valueOf(v).getValue()); } + public Value eq (final Value v) throws InvalidOperationException + { return BoolValue.valueOf(getValue() == valueOf(v).getValue()); } + public Value ne (final Value v) throws InvalidOperationException + { return BoolValue.valueOf(getValue() != valueOf(v).getValue()); } + public Value ge (final Value v) throws InvalidOperationException + { return BoolValue.valueOf(getValue() >= valueOf(v).getValue()); } + public Value gt (final Value v) throws InvalidOperationException + { return BoolValue.valueOf(getValue() > valueOf(v).getValue()); } + + public Value assign(final Value v, final CellImpl cell) + throws InvalidOperationException { + if (isDefined()) + throw new InvalidOperationException("value already assigned"); + + // throw InvalidOperationException if v not defined + val = valueOf(v).getValue(); + setDefined(); + + return this; + } + + public static final Type TYPE = new ClassType("float"); + + public Type getType() { + return TYPE; + } + + public String toString() { + return "FloatValue(" + + (isDefined() ? String.valueOf(val) : "?") + + ")"; + } + + /** + * Two FloatValues are equal if they are both defined, + * and have the same value. + **/ + public boolean equals(final Object o) { + if (!(o instanceof FloatValue)) + return false; + else + return equals((FloatValue) o); + } + + /** + * Two FloatValues are equal if they are both defined, + * and have the same value. + **/ + public boolean equals(final FloatValue fv) { + if (!isDefined()) + return false; + else if (!fv.isDefined()) + return false; + else + return val == fv.val; + } + + public int hashCode() { + return (int) (Double.doubleToRawLongBits(val) & 0xFFFFFFFFL); + } + + // + // implements FloatMetaParam + // + + public float toFloat() { + return (float) val; + } + + // + // implements MetaParamValueInterface + // + + public MetaParamTypeInterface toMetaParam() { + return this; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ImportEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ImportEnvironment.java new file mode 100644 index 0000000000..7c9e8d5edd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/ImportEnvironment.java @@ -0,0 +1,201 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.cast.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; + + +/** + * Looks up the symbol in all of the imported environments; + * an exception will be thrown unless it is found in exactly one + * environment. Binding to imported environments is not allowed, + * that has already been done. + *

    + * @todo jmr This will need modification when you can "import foo as bar". + **/ +public final class ImportEnvironment implements Environment { + private final ArrayList envs; + + public ImportEnvironment() { + envs = new ArrayList(); + } + + public ImportEnvironment(final ImportEnvironment defaultImportEnv) { + this(); + envs.addAll(defaultImportEnv.envs); + } + + /** + * Looks up the symbol in all of the imported environments; + * an exception will be thrown unless it is found in exactly one + * environment. + **/ + public Value lookup(final Symbol sym) + throws AmbiguousLookupException + { + final String env1 = ""; + String env2 = ""; + + Value val = null; + + for (int iEnv = 0; iEnv < envs.size(); ++iEnv) { + final Value v = ((Environment) envs.get(iEnv)).lookup(sym); + + if (v == null) + continue; + + // if we have already found a value, it is an error + if (val != null) + throw new AmbiguousLookupException(sym, env1, env2); + else + val = v; + } + + return val; + } + + /** + * Looks up the symbol in all of the imported environments; + **/ + public boolean contains(final Symbol sym) { + for (int iEnv = 0; iEnv < envs.size(); ++iEnv) { + if (((Environment) envs.get(iEnv)).contains(sym)) + return true; + } + return false; + } + + /** @throws InvalidBindException Always. **/ + public void bind(final Symbol sym, final Value val) { + throw new InvalidBindException("can't bind to import env"); + } + + /** + * Adds the environment to the list of imported environments, + * if it is not already there (this prevents spurious + * AmbiguousLookupExceptions, and allows multiple importation + * in the same file). + **/ + public void addEnvironment(final Environment env) { + if (!envs.contains(env)) + envs.add(env); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + sb.append("ImportEnvironment(\n"); + for (Iterator envIterator = envs.iterator(); + envIterator.hasNext(); + ) { + sb.append(envIterator.next().toString()); + sb.append("\n"); + } + sb.append(")"); + return sb.toString(); + } + + public EnvironmentIterator iterator() { + return new EnvironmentIterator () { + + private final Iterator m_EnvsIter = envs.iterator(); + private EnvironmentIterator m_CurrEnvIter = null; + private boolean noNext = false; + /** + Updates m_CurrEnvIter to be an iterator into the next non-empty + environment in the collection iterated by m_EnvsIter. + */ + private final void updateCurrIter() { + if ( m_CurrEnvIter == null ) { + final Environment nextEnv = ( Environment ) m_EnvsIter.next(); + m_CurrEnvIter = nextEnv.iterator(); + } + + while ( ! ( m_CurrEnvIter.hasNext() ) ) { + final Environment nextEnv = ( Environment ) m_EnvsIter.next(); + m_CurrEnvIter = nextEnv.iterator(); + } + } + + public final boolean hasNext() { + if ( ! noNext ) { + try { + updateCurrIter(); + return true; + } + catch( NoSuchElementException e ) { + noNext = true; + return false; + } + } + else { + return false; + } + } + + public final EnvironmentEntry next() { + updateCurrIter(); + return m_CurrEnvIter.next(); + } + }; + } + + public EnvironmentEntryIterator entryIterator() { + return new EnvironmentEntryIterator () { + + private final Iterator m_EnvsIter = envs.iterator(); + private EnvironmentEntryIterator m_CurrEnvEntryIter = null; + private boolean noNext = false; + /** + Updates m_CurrEnvEntryIter to be an iterator into the next non-empty + environment in the collection iterated by m_EnvsIter. + */ + private final void updateCurrIter() { + if ( m_CurrEnvEntryIter == null ) { + final Environment nextEnv = ( Environment ) m_EnvsIter.next(); + m_CurrEnvEntryIter = nextEnv.entryIterator(); + } + + while ( ! ( m_CurrEnvEntryIter.hasNext() ) ) { + final Environment nextEnv = ( Environment ) m_EnvsIter.next(); + m_CurrEnvEntryIter = nextEnv.entryIterator(); + } + } + + public final boolean hasNext() { + if ( ! noNext ) { + try { + updateCurrIter(); + return true; + } + catch( NoSuchElementException e ) { + noNext = true; + return false; + } + } + else { + return false; + } + } + + public final EnvironmentEntry next() { + updateCurrIter(); + return m_CurrEnvEntryIter.next(); + } + }; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InstanceValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InstanceValue.java new file mode 100644 index 0000000000..0aa4592bad --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InstanceValue.java @@ -0,0 +1,432 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellInterface; +import com.avlsi.util.debug.Debug; +import com.avlsi.file.common.HierName; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.container.Pair; + +/** + * A value of an instantiated type. Its fields may be accessed. + * An instance value needs to know the name and type of its ports. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class InstanceValue + extends Value + implements FieldedValueInterface { + + public static final int INLINE_NONE = 0; + public static final int INLINE_INLINE = 1; + public static final int INLINE_FLATTEN = 2; + private final HierName instanceName; + + /** + * The cell definition for this instance. + **/ + private final CellInterface defCell; + private final Symbol typeName; + private final TupleValue metaParams; + private final BlockEnvironment paramEnv; + private final Environment prsEnv; + private final Environment subcellsEnv; + private final Symbol[] portParams; + private final Symbol[] impliedPortParams; + private final String[] impliedPortParentNodes; + private final int[] inlineState; + + public static InstanceValue valueOf(final Value val) + throws InvalidOperationException{ + if (val instanceof InstanceValue) + return (InstanceValue) val; + else + throw new InvalidOperationException( + "no conversion of " + + (val.getInstanceName() == null ? + "unamed value " + val : + "value named " + val.getInstanceName()) + + " to instance value"); + } + + /** + * The environment that is passed in should be have an entry for each + * field in the type. + **/ + public InstanceValue(final HierName instanceName, + final CellInterface defCell, + final Symbol typeName, + final TupleValue metaParams, + final BlockEnvironment paramEnv, + final Environment prsEnv, + final Environment subcellsEnv, + final Symbol[] portParams, + final Symbol[] impliedPortParams, + final String[] impliedPortParentNodes, + final int[] inlineState) { + super(true); + + this.instanceName = instanceName; + this.defCell = defCell; + this.typeName = typeName; + this.metaParams = metaParams; + this.paramEnv = paramEnv; + this.prsEnv = prsEnv; + this.subcellsEnv = subcellsEnv; + this.portParams = portParams; + this.impliedPortParams = impliedPortParams; + this.impliedPortParentNodes = impliedPortParentNodes; + this.inlineState = inlineState; + } + + /** + * Return a duplicate suitable for use in constructing an array. + * Everying is the same, but the environment is a sibling + * of the original environment (same parent, copied local contents). + **/ + public Value duplicate() { + return new InstanceValue(instanceName, defCell, typeName, metaParams, + paramEnv.getSiblingEnvironment(), prsEnv, subcellsEnv, + portParams, impliedPortParams, impliedPortParentNodes, + new int[] { inlineState[0] }); + } + + public Pair processSubtypes(final boolean duplicate) { + final Environment env; + final BlockEnvironment envParam; + final Environment envSubcells; + + assert inlineState[0] == INLINE_NONE || + inlineState[0] == INLINE_INLINE : + "Cannot flatten in the subtypes block: " + this; + + if (inlineState[0] == INLINE_NONE) { + envParam = new BlockEnvironment(paramEnv); + envSubcells = subcellsEnv; + env = envParam; + } else { + if (subcellsEnv == null) { + envParam = new BlockEnvironment(paramEnv); + envSubcells = subcellsEnv; + env = envParam; + } else { + envParam = paramEnv; + envSubcells = new BlockEnvironment(subcellsEnv); + env = envSubcells; + } + } + + final InstanceValue iv = + duplicate ? new InstanceValue(instanceName, defCell, typeName, + metaParams, envParam, prsEnv, + envSubcells, portParams, + impliedPortParams, + impliedPortParentNodes, + new int[] { inlineState[0] }) + : this; + + return new Pair(env, iv); + } + + private Value accessField(final Symbol sym) throws + InvalidOperationException { + return accessField(sym, FieldedValueInterface.INSTANCE_PERMISSION); + } + + public Value accessField(final Symbol sym, final int permission) + throws InvalidOperationException { + assert permission == FieldedValueInterface.ALL_PERMISSION || + permission == FieldedValueInterface.INSTANCE_PERMISSION : + "Unknown field access permission: " + permission; + try { + final Environment env; + // prsEnv and subcellsEnv will be null if this is a channel + if (inlineState[0] == INLINE_NONE && + permission != FieldedValueInterface.ALL_PERMISSION) + env = paramEnv; + else if (inlineState[0] == INLINE_INLINE && + permission != FieldedValueInterface.ALL_PERMISSION) + env = subcellsEnv == null ? paramEnv : subcellsEnv; + else { + if (subcellsEnv != null && prsEnv != null) { + env = new SplicingEnvironment(subcellsEnv, prsEnv); + } else if (subcellsEnv != null) { + env = subcellsEnv; + } else if (prsEnv != null) { + env = prsEnv; + } else { + env = paramEnv; + } + } + final Value v = env.lookup(sym); + if (v == null) + throw new InvalidOperationException("symbol not bound: " + + sym); + final HierName newName = + HierName.makeHierName(getInstanceName(), v.getInstanceName()); + final Value result; + if (v instanceof InstanceValue && + inlineState[0] == INLINE_FLATTEN) { + final InstanceValue iv = (InstanceValue) v; + result = new InstanceValue(newName, iv.defCell, iv.typeName, + iv.metaParams, iv.paramEnv, + iv.prsEnv, iv.subcellsEnv, + iv.portParams, iv.impliedPortParams, + iv.impliedPortParentNodes, + new int[] { INLINE_FLATTEN } ); + } else { + result = v.newInstanceName(newName); + } + return result; + } catch (AmbiguousLookupException e) { + throw (AssertionFailure) + new AssertionFailure("ambiguous lookup in cell/channel") + .initCause(e); + } + } + + /** + * Helper function for assign: matches port lists (implied or not) + * to values. Not used when the implied ports aren't specified. + **/ + private void assignPorts(Symbol[] ports, TupleValue values, CellImpl cell) + throws InvalidOperationException { + if (values.getSize()==0) return; // empty () is OK and makes no connections + if (ports.length != values.getSize()) + throw new InvalidOperationException( + "Initializer with wrong number of ports: " + + ports.length + "!=" + values.getSize()); + for (int i = 0; i < ports.length; ++i) { + final Value fieldValue = values.accessTuple(i); + + if (!(fieldValue instanceof AnonymousValue)) + try { + accessField(ports[i]).assign(fieldValue, cell); + } catch (InvalidOperationException e) { + throw new InvalidOperationException( + "cannot connect port " + ports[i].getString(), e); + } + } + } + + /** + * Looks up the implied port symbols in the parent cell and pulls + * them into the child cell too. Called when assign isn't, + * because the implied ports should always be hooked up. + * @param cell parent cell for this cell + **/ + public void assignDefaultsToImpliedPorts(CellImpl cell) + throws InvalidOperationException { + for (int i = 0; i < impliedPortParams.length; ++i) { + final HierName parentNodeName = + HierName.makeHierName(impliedPortParentNodes[i]); + CellInterface defaultCell = + (CellInterface) cell.getSubcell(parentNodeName); + + // If the node isn't in the parent cell, then the parent + // cell ought to be a top-level cell which isn't expected + // to necessarily have globals. If it's a top-level cell, + // it ought to alias names with a '!' after them to their + // '!'less forms, because external tools expect both forms + // to be available. + if (defaultCell == null) { + if (cell.isSyntheticP()) { + final CellInterface node = + new NodeValue(parentNodeName).getCell(); + + Debug.assertTrue(!parentNodeName.isGlobal()); + cell.addSubcellPair(parentNodeName, node, false); + defaultCell = node; + } else { + throw new InvalidOperationException( + "implied port " + impliedPortParams[i].getString() + + " not bound in parent cell: " + + cell.getFullyQualifiedType() + + " so can't bind it in child: " + + defCell.getFullyQualifiedType()); + } + } + + // If the name isn't a node + if (! defaultCell.isNode()) { + throw new InvalidOperationException("implied port " + impliedPortParams[i] + " must be a node"); + } + final Value defaultValue = new NodeValue(parentNodeName); + + accessField(impliedPortParams[i]).assign(defaultValue, cell); + } + } + + /** + * Assignment from another InstanceValue or a + * TupleValue/TupleGroupValue. A TupleValue or TupleGroupValue + * can only come from an initializer. If the value is a + * TupleValue/TupleGroupValue, each component is assigned unless + * it is an AnonymousValue. + **/ + public Value assign(final Value v, final CellImpl cell) + throws InvalidOperationException { + if (v instanceof TupleValue) { + final TupleValue tv = (TupleValue) v; + assignPorts(portParams, tv, cell); + assignDefaultsToImpliedPorts(cell); + } + else if (v instanceof TupleGroupValue) { + final TupleGroupValue tgv = (TupleGroupValue) v; + final TupleValue portValues = tgv.getPortList(); + final TupleValue impliedPortValues = tgv.getImpliedPortList(); + assignPorts(portParams, portValues, cell); + + // If the implied port list is explictly empty, it means the + // implied connections should be skipped + if (impliedPortValues.getSize() != 0) { + assignPorts(impliedPortParams, impliedPortValues, cell); + } + } + else { + final InstanceValue instanceVal = valueOf(v); + + // cell.addConnection(getInstanceName(), instanceVal.getInstanceName()); + + if (!getCell().eventuallyRefinesFrom(instanceVal.getCell()) && + !instanceVal.getCell().eventuallyRefinesFrom(getCell())) + throw new InvalidOperationException( + "Types are not compatible: " + + getType().getString() + " / " + + instanceVal.getType().getString()); + + // recursively assign the port parameters + Debug.assertTrue(portParams.length == instanceVal.portParams.length); + + for (int i = 0; i < portParams.length; ++i) { + final Symbol sym1 = portParams[i]; + final Symbol sym2 = instanceVal.portParams[i]; + + Debug.assertTrue(sym1.equals(sym2)); + + accessField(sym1).assign(instanceVal.accessField(sym1), cell); + } + } + + return this; + } + + public String getTypeName() { + return typeName.getString(); + } + + public CellInterface getCell() { + return defCell; + } + + public HierName getInstanceName() { + return instanceName; + } + + public Environment getParamEnv() { + return paramEnv; + } + + public Symbol[] getPortParams() { + return portParams; + } + + public Value newInstanceName(final HierName newInstanceName) { + return new InstanceValue(newInstanceName, defCell, typeName, + metaParams, paramEnv, prsEnv, subcellsEnv, portParams, + impliedPortParams, impliedPortParentNodes, inlineState); + } + + public String toString() { + return "InstanceValue(typeName: " + + typeName + ", metaParams: " + + metaParams + ", paramEnv: " + + paramEnv.getLocalEnvironmentString() + ", prsEnv: " + + prsEnv + ", subcellsEnv: " + + subcellsEnv + ")"; + } + + public Type getType() { + return new InstanceValueType(this); + } + + public boolean eventuallyRefinesFrom(Value v) + throws InvalidOperationException { + if (! (v instanceof InstanceValue)) + throw new InvalidOperationException("Can't refine an instance value from " + v.getType().getString()); + InstanceValue iv = (InstanceValue) v; + return this.getCell().eventuallyRefinesFrom(iv.getCell()); + } + + public void setInline(final int inlineState) { + assert inlineState == INLINE_NONE || inlineState == INLINE_INLINE || + inlineState == INLINE_FLATTEN : + "Invalid inline state: " + inlineState; + + this.inlineState[0] = inlineState; + } + + final class InstanceValueType extends Type { + private final InstanceValue iv; + + // for some reason, inner classes aren't working like I want, + // so I need to do this. What's the right syntax? + // + // public class X { + // int n = 0; + // + // class Y { + // void f(Y y) { + // n = 3; + // y.n = 4; + // } + // } + // } + + public InstanceValueType(final InstanceValue iv) { + this.iv = iv; + } + + public boolean equals(final Object o) { + if (o instanceof InstanceValueType) + return equals((InstanceValueType) o); + else + return false; + } + + public boolean equals(final InstanceValueType ivt) { + return iv.typeName.equals(ivt.iv.typeName) + && iv.metaParams.equals(ivt.iv.metaParams); + } + + public boolean typeEquals(final InstanceValueType ivt) { + return iv.typeName.equals(ivt.iv.typeName); + } + + public String toString() { + return "InstanceValueType( typeName: " + + iv.typeName + ", metaParams: " + + iv.metaParams + ")"; + } + + public String getString() { + return UserDefinedValue.getTypeName(iv.typeName.getString(), + iv.metaParams); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/IntValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/IntValue.java new file mode 100644 index 0000000000..6202b8cae5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/IntValue.java @@ -0,0 +1,305 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + +import java.math.BigInteger; + +import com.avlsi.cell.CellImpl; +import com.avlsi.fast.metaparameters.IntegerMetaParam; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; + +/** + * This class represents integer values. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class IntValue + extends Value + implements IntegerMetaParam, MetaParamValueInterface { + + /** + * Value, an arbitary precision integer. + **/ + private BigInteger val; + + /** + * Returns an IntValue whose value is equal to that of the specified + * BigInteger. + **/ + public static IntValue valueOf(BigInteger val) { + return new IntValue(val); + } + + /** + * Returns an IntValue whose value is equal to that of the specified + * int. + **/ + public static IntValue valueOf(int val) { + return new IntValue(val); + } + + /** + * Returns an IntValue whose value is represented by the specified + * String. + **/ + public static IntValue valueOf(final String s) + throws InvalidOperationException { + try { + return valueOf(new BigInteger(s)); + } catch (NumberFormatException e) { + throw new InvalidOperationException + ("bad int;" + e.getMessage(), e); + } + } + + public static IntValue hexValueOf(final String s) + throws InvalidOperationException { + try { + return valueOf(new BigInteger(s, 16)); + } catch (NumberFormatException e) { + throw new InvalidOperationException + ("bad int;" + e.getMessage(), e); + } + } + + /** + * Returns an IntValue whose value is equal to that of the specified + * Value. Thrown InvalidOperationException if the value is not + * an IntValue. + **/ + public static IntValue valueOf(Value v) throws InvalidOperationException { + if (v instanceof IntValue) + return (IntValue) v; + else + throw new InvalidOperationException(v.getType().getString() + + " is not an integer"); + } + + public static IntValue castFrom(Value v) throws InvalidOperationException { + if (v instanceof IntValue) + return (IntValue) v; + else if (v instanceof FloatValue) + return valueOf((int) ((FloatValue) v).getValue()); + else if (v instanceof BoolValue) + return valueOf(((BoolValue) v).getValue() ? 1 : 0); + else + throw new InvalidOperationException( + "Cannot cast " + v.getType().getString() + " to " + + TYPE.getString()); + } + + /** + * Class constructor. + **/ + public IntValue(int val) { + super(true); + this.val = BigInteger.valueOf(val); + } + + public IntValue(BigInteger val) { + super(true); + this.val = val; + } + + public IntValue() { + super(false); + this.val = null; + } + + public Value duplicate() { + if (isDefined()) + return new IntValue(val); + else + return new IntValue(); + } + + // accessor + public double doubleValue() throws InvalidOperationException { + return getValue().doubleValue(); + } + + public BigInteger getValue() throws InvalidOperationException { + ensureDefined(); + return val; + } + + // logical + + public Value or (final Value v) throws InvalidOperationException { + return valueOf(getValue().or(valueOf(v).getValue())); + } + + public Value and (final Value v) throws InvalidOperationException { + return valueOf(getValue().and(valueOf(v).getValue())); + } + + public Value not () throws InvalidOperationException { + return valueOf(getValue().not()); + } + + public Value xor (final Value v) throws InvalidOperationException { + return valueOf(getValue().xor(valueOf(v).getValue())); + } + + // arithmetic + + public Value add (final Value v) throws InvalidOperationException { + if (v.getType().equals(FloatValue.TYPE)) + return v.add(this); + else + return valueOf(getValue().add(valueOf(v).getValue())); + } + + public Value subtract (final Value v) throws InvalidOperationException { + if (v.getType().equals(FloatValue.TYPE)) + return FloatValue.valueOf(this).subtract(v); + else + return valueOf(getValue().subtract(valueOf(v).getValue())); + } + + public Value multiply (final Value v) throws InvalidOperationException { + if (v.getType().equals(FloatValue.TYPE)) + return v.multiply(this); + else + return valueOf(getValue().multiply(valueOf(v).getValue())); + } + + public Value divide (final Value v) throws InvalidOperationException { + if (v.getType().equals(FloatValue.TYPE)) + return FloatValue.valueOf(this).divide(v); + else + return valueOf(getValue().divide(valueOf(v).getValue())); + } + + public Value mod (final Value v) throws InvalidOperationException { + try { + return valueOf(getValue().mod(valueOf(v).getValue())); + } catch (final ArithmeticException e) { + throw new InvalidOperationException("can't mod by non-positive: " + + valueOf(v).getValue(), e); + } + } + + public Value pow (final Value v) throws InvalidOperationException { + try { + return valueOf(getValue().pow(valueOf(v).getValue().intValue())); + } catch (final ArithmeticException e) { + throw new InvalidOperationException("can't exponentiate by " + + "negative: " + valueOf(v).getValue(), e); + } + } + + public Value unaryPlus() throws InvalidOperationException { + return valueOf(getValue()); + } + + public Value negate () throws InvalidOperationException { + return valueOf(getValue().negate()); + } + + + // relational, total order + + public Value lt (final Value v) throws InvalidOperationException { + return BoolValue.valueOf( + getValue().compareTo(valueOf(v).getValue()) < 0); + } + public Value le (final Value v) throws InvalidOperationException { + return BoolValue.valueOf( + getValue().compareTo(valueOf(v).getValue()) <= 0); + } + public Value eq (final Value v) throws InvalidOperationException { + return BoolValue.valueOf( + getValue().compareTo(valueOf(v).getValue()) == 0); + } + public Value ne (final Value v) throws InvalidOperationException { + return BoolValue.valueOf( + getValue().compareTo(valueOf(v).getValue()) != 0); + } + public Value ge (final Value v) throws InvalidOperationException { + return BoolValue.valueOf( + getValue().compareTo(valueOf(v).getValue()) >= 0); + } + public Value gt (final Value v) throws InvalidOperationException { + return BoolValue.valueOf( + getValue().compareTo(valueOf(v).getValue()) > 0); + } + + public Value assign(final Value v, final CellImpl cell) + throws InvalidOperationException { + if (isDefined()) + throw new InvalidOperationException("value already assigned"); + + // this is ok because BigIntegers are immutable + // throw InvalidOperationException if v not defined + val = valueOf(v).getValue(); + setDefined(); + + return this; + } + + + public static final Type TYPE = new ClassType("int"); + + public Type getType() { + return TYPE; + } + + public String toString() { + return "IntValue(" + (isDefined() ? String.valueOf(val) : "?") + ")"; + } + + /** + * Two IntValues are equal if they are both defined, + * and have the same value. + **/ + public boolean equals(final Object o) { + if (!(o instanceof IntValue)) + return false; + else + return equals((IntValue) o); + } + + /** + * Two IntValues are equal if they are both defined, + * and have the same value. + **/ + public boolean equals(final IntValue iv) { + if (!isDefined()) + return false; + else if (!iv.isDefined()) + return false; + else + return val.equals(iv.val); + } + + public int hashCode() { + if (val == null) + return 0; + else + return val.hashCode(); + } + + // + // implements IntegerMetaParam + // + + public BigInteger toBigInteger() { + return val; + } + + // + // implements MetaParamValueInterface + // + + public MetaParamTypeInterface toMetaParam() { + return this; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidBindException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidBindException.java new file mode 100644 index 0000000000..662250f4c4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidBindException.java @@ -0,0 +1,33 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * Exception thrown by {@link TopLevelEnvironment.UnbindableEnvironment#bind} + * when a bind attempt is made. + * + * @see TopLevelEnvironment.UnbindableEnvironment + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class InvalidBindException extends RuntimeException { + public InvalidBindException() { + super(); + } + + public InvalidBindException(final String detail) { + super(detail); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidOperationException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidOperationException.java new file mode 100644 index 0000000000..3bde778f49 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/InvalidOperationException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * Exception thrown when an illegal operation occurs. Ie + * bool + bool, * or int / 0. + * + * @see Value + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class InvalidOperationException extends Exception { + public InvalidOperationException() { + super(); + } + + public InvalidOperationException(final String detail) { + super(detail); + } + + public InvalidOperationException(final String detail, Throwable cause) { + super(detail, cause); + } + + public InvalidOperationException(Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelContainerValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelContainerValue.java new file mode 100644 index 0000000000..82dccfe653 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelContainerValue.java @@ -0,0 +1,128 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.debug.Debug; + +/** + * This class represents javablock-internal channels (and arrays of + * same) to the cast parser. It provides the fields "in" and "out" so + * that the devices in the javablock can specify whether they're + * sending or receiving. Immutable. + **/ + +public class JavaChannelContainerValue + extends Value + implements FieldedValueInterface { + + private static final Type TYPE = + new ClassType(""); + + private final HierName instanceName; + + /** + * Should be either a JavaChannelValue or an ArrayValue containing them. + **/ + private final Value in; + + /** + * Should be either a JavaChannelValue or an ArrayValue containing them. + **/ + private final Value out; + + /** + * Creates the JavaChannelContainerValue for a single channel + * @param name name of the channel and this Value + **/ + public JavaChannelContainerValue(final HierName name) { + super(true); + instanceName = name; + + final HierName inName, outName; + try { + inName = HierName.makeHierName(name, "in"); + outName = HierName.makeHierName(name, "out"); + } catch (InvalidHierNameException e) { + throw new RuntimeException("neither 'in' nor 'out' contains a period, so this should never happen: " + e.getMessage(), e); + } + + in = new JavaChannelValue(inName, true); + out = new JavaChannelValue(outName, false); + } + + /** + * Creates the JavaChannelContainerValue for an array of channels + * @param name base name for the array and the name of this Value + * @param spec specification of the array + **/ + public JavaChannelContainerValue(final HierName name, + final SubscriptSpecInterface spec) { + super(true); + instanceName = name; + + final HierName inName, outName; + try { + inName = HierName.makeHierName(name, "in"); + outName = HierName.makeHierName(name, "out"); + } catch (InvalidHierNameException e) { + throw new RuntimeException("neither 'in' nor 'out' contains a period, so this should never happen: " + e.getMessage(), e); + } + + in = ArrayValue.makeArray(new JavaChannelValue(inName, true), spec); + out = ArrayValue.makeArray(new JavaChannelValue(outName, false), spec); + } + + public String toString() { + return "javablock channel(" + instanceName + ")"; + } + + public Value accessField(final Symbol sym, final int permission) + throws InvalidOperationException { + if (sym.equals(Symbol.create("in"))) { + return in; + } else if (sym.equals(Symbol.create("out"))) { + return out; + } else { + throw new InvalidOperationException("java channels can only be accessed by .in and .out, not ." + sym.getString()); + } + } + + // + // functions implementing Value + // + + public Value assign(final Value v, final CellImpl cell) { + Debug.assertTrue(false, "should never assign JavaChannelContainerValues"); + return null; // make compiler happy + } + + /** + * Will be needed if array statements are allowed in the javablock + * in the future. However, since JavaChannelContainerValues are + * immutable, this function is trivial. + **/ + public Value duplicate () { + return this; + } + + public HierName getInstanceName() { + return this.instanceName; + } + + public Type getType() { + return TYPE; + } + + public Value newInstanceName(final HierName newInstanceName) { + Debug.assertTrue(false, "no reason why you should ever do this, so it's not implemented yet"); + return null; // make compiler happy + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelValue.java new file mode 100644 index 0000000000..8e33f23713 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/JavaChannelValue.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.file.common.HierName; +import com.avlsi.util.debug.Debug; + +/** + * This class represents one direction (either sending or receiving) + * of a javablock-internal channel to the cast parser. Immutable. + **/ +public class JavaChannelValue extends Value { + private final HierName instanceName; + /** Input or output channel? **/ + private final boolean inputChannelP; + + private static final Type TYPE = + new ClassType(""); + + public JavaChannelValue(final HierName instanceName, + final boolean inputChannelP) { + super(true); + this.instanceName = instanceName; + this.inputChannelP = inputChannelP; + } + + // + // functions implementing Value + // + + public Value assign(final Value v, final CellImpl cell) { + Debug.assertTrue(false, "should never assign JavaChannelValues"); + return null; // make compiler happy + } + + /** + * Will be needed if array statements are allowed in the javablock + * in the future. However, since JavaChannelContainerValues are + * immutable, this function is trivial. + **/ + public Value duplicate () { + return this; + } + + public HierName getInstanceName() { + return this.instanceName; + } + + public Type getType() { + return TYPE; + } + + public Value newInstanceName(final HierName newInstanceName) { + return new JavaChannelValue(newInstanceName, inputChannelP); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LocalEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LocalEnvironment.java new file mode 100644 index 0000000000..2b9485cc9e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LocalEnvironment.java @@ -0,0 +1,179 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; + + +import com.avlsi.util.exception.AssertionFailure; + +/** + * Local environment, has no parent capabilities, + * implements a mapping from Symbol to Value. + * It's just a HashMap with some type safety. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class LocalEnvironment implements Environment { + private final Map map; + + public LocalEnvironment() { + this(new HashMap()); + } + + public LocalEnvironment(final Map map) { + this.map = map; + } + + /** + * If the Symbol is global, binds both the global + * and the local forms to the value. + * Global signals end with a '!'. + **/ + public void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + + internalBind(sym, val); + if (sym.isGlobal()) + internalBind(sym.stripBang(), val); + } + /** + * Like bind, but without the duplication of globals. For + * internal use only. + **/ + private void internalBind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + if (map.containsKey(sym)) { + // If two values have the same address, then they must really be + // the same value, and only appears to be redeclared due to + // multiple inheritence; we don't count this as an error. This + // means that we must never reuse the same value object to bind to + // different symbols. + if (map.get(sym) != val) + throw new SymbolRedeclaredException(sym); + } else { + map.put(sym, val); + } + } + + public Value lookup(final Symbol sym) { + return (Value) map.get(sym); + } + + public boolean contains(final Symbol sym) { + return map.containsKey(sym); + } + + /** + * Returns a deep copy of the environment. + **/ + public LocalEnvironment duplicate() { + final LocalEnvironment env = new LocalEnvironment(); + + for (final Iterator i = map.entrySet().iterator(); i.hasNext(); ) { + final Entry entry = (Entry) i.next(); + final Symbol sym = (Symbol) entry.getKey(); + final Value val = (Value) entry.getValue(); + + try { + env.internalBind(sym, val.duplicate()); + } catch (SymbolRedeclaredException e) { + throw (AssertionFailure) + new AssertionFailure(sym + " = " + val + " redeclared!") + .initCause(e); + } + } + + return env; + } + + /** + * Return an environment with the same values, but arrays are shallow + * copied. + **/ + public LocalEnvironment protectedArrayEnvironment() { + final LocalEnvironment env = new LocalEnvironment(); + + for (final Iterator i = map.entrySet().iterator(); i.hasNext(); ) { + final Entry entry = (Entry) i.next(); + final Symbol sym = (Symbol) entry.getKey(); + final Value val = (Value) entry.getValue(); + + if (val instanceof ArrayValue) + env.map.put(sym, ((ArrayValue) val).shallowCopy()); + else + env.map.put(sym, val); + + } + + return env; + } + + public String toString() { + return "LocalEnvironment(" + map.toString() + ")"; + } + + /** + * Add all of the key-value pairs in env to this environment, with + * appropriate duplication warnings. + **/ + public void absorbEnv(Environment env) + throws SymbolRedeclaredException { + if (env == null) return; + EnvironmentEntryIterator entries = env.entryIterator(); + while (entries.hasNext()) { + EnvironmentEntry entry = entries.next(); + internalBind(entry.getName(), entry.getValue()); + } + } + + public EnvironmentIterator iterator() { + return new EnvironmentIterator () { + + private final Iterator m_Iter = map.entrySet().iterator(); + + public final boolean hasNext() { + return m_Iter.hasNext(); + } + + public final EnvironmentEntry next() { + final Entry entry = ( Entry ) m_Iter.next(); + return new EnvironmentEntry((Symbol) entry.getKey(), + (Value) entry.getValue()); + } + }; + } + + public EnvironmentEntryIterator entryIterator() { + return new EnvironmentEntryIterator () { + + private final Iterator m_Iter = map.entrySet().iterator(); + + public final boolean hasNext() { + return m_Iter.hasNext(); + } + + public final EnvironmentEntry next() { + final Entry entry = ( Entry ) m_Iter.next(); + return new EnvironmentEntry((Symbol) entry.getKey(), + (Value) entry.getValue()); + } + }; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LoopEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LoopEnvironment.java new file mode 100644 index 0000000000..ed50d2f25e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/LoopEnvironment.java @@ -0,0 +1,117 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; + +/** + * A LoopEnvironment, binds loop index. All lookups are first checked + * against the loop index, then passed to the parent environment. + * All declarations are made in the outer environment. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class LoopEnvironment implements Environment { + private final Environment env; + private final Symbol loopSym; + private final Value val; + + public LoopEnvironment(final Environment env, + final Symbol loopSym, + final Value val) { + if (env == null) + throw new IllegalArgumentException("parent env was null"); + + this.env = env; + this.loopSym = loopSym; + this.val = val; + + } + + public void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + // all bindings are put off into the outer environment + // except for redeclaring the loop var -- that's an error + if (sym.equals(loopSym)) + throw new SymbolRedeclaredException(sym); + + env.bind(sym, val); + } + + public Value lookup(final Symbol sym) + throws AmbiguousLookupException { + if (sym.equals(loopSym)) + return val; + else + return env.lookup(sym); + } + + public boolean contains(final Symbol sym) { + return (sym.equals(loopSym) || env.contains(sym)); + } + + public String toString() { + return "LoopEnvironment(\n" + env + "\n)"; + } + + public EnvironmentIterator iterator() { + return new EnvironmentIterator () { + + private boolean m_didValue = false; + private final Value m_Val = val; + private final Symbol m_Name = loopSym; + private final EnvironmentIterator m_EnvIter = env.iterator(); + + public final boolean hasNext() { + return ( ( ! m_didValue ) || ( m_EnvIter.hasNext() ) ); + } + + public final EnvironmentEntry next() { + if ( ! m_didValue ) { + m_didValue = true; + return new EnvironmentEntry(m_Name, m_Val); + } + else { + return m_EnvIter.next(); + } + } + }; + } + + public EnvironmentEntryIterator entryIterator() { + return new EnvironmentEntryIterator () { + + private boolean m_didEntry = false; + private final EnvironmentEntry m_Entry = + new EnvironmentEntry(loopSym, val); + private final EnvironmentEntryIterator m_EnvEntryIter = + env.entryIterator(); + + public final boolean hasNext() { + return ( ( ! m_didEntry ) || + ( m_EnvEntryIter.hasNext() ) ); + } + + public final EnvironmentEntry next() { + if ( ! m_didEntry ) { + m_didEntry = true; + return m_Entry; + } + else { + return m_EnvEntryIter.next(); + } + } + }; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/MetaParamValueInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/MetaParamValueInterface.java new file mode 100644 index 0000000000..b01ddb62d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/MetaParamValueInterface.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; + +/** + * Tagging interface for values that are meta params. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface MetaParamValueInterface { + MetaParamTypeInterface toMetaParam(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NodeValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NodeValue.java new file mode 100644 index 0000000000..aa108c2488 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NodeValue.java @@ -0,0 +1,107 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.util.debug.Debug; + +/** + * Class to represent node values. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class NodeValue extends Value { + + /** + * Don't use static initializers because they are evil. + **/ + private static CellInterface NODE_CELL = null; + + /** + * The name of the variable that this node value represents. + * Used for connections. + **/ + private final HierName instanceName; + + // maybe this will have an Alias reference or something someday? + + public static NodeValue valueOf(final Value val) + throws InvalidOperationException { + if (val instanceof NodeValue) + return (NodeValue) val; + else + throw new InvalidOperationException(val + " is not a node"); + } + + public static NodeValue castFrom(final Value v) + throws InvalidOperationException { + if (v instanceof NodeValue) + return (NodeValue) v; + else + throw new InvalidOperationException( + "Cannot cast " + v.getType().getString() + " to " + + TYPE.getString()); + } + + public NodeValue(final HierName instanceName) { + super(true); + + this.instanceName = instanceName; + } + + public Value duplicate() { + // What do we want to do here? + Debug.assertTrue(isDefined()); + return new NodeValue(instanceName); + } + + public Value assign(final Value v, final CellImpl cell) + throws InvalidOperationException { + Debug.assertTrue(isDefined()); + final NodeValue nv = valueOf(v); + cell.addConnection(getInstanceName(), nv.getInstanceName()); + return this; + } + + public HierName getInstanceName() { + return instanceName; + } + + public Value newInstanceName(final HierName newInstanceName) { + Debug.assertTrue(isDefined()); + return new NodeValue(newInstanceName); + } + + public static final Type TYPE = new ClassType("node"); + + public Type getType() { + return TYPE; + } + + public String toString() { + return "NodeValue(" + getInstanceName() + ")"; + } + + public CellInterface getCell() { + if (NODE_CELL == null) + NODE_CELL = new CellImpl(CellImpl.NODE_TYPE); + + return NODE_CELL; + } + + public boolean eventuallyRefinesFrom(Value v) + throws InvalidOperationException { + if (! (v instanceof NodeValue)) + throw new InvalidOperationException("Can't refine an node value from " + v.getType().getString()); + return true; // All nodes are the same; no problem + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NullEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NullEnvironment.java new file mode 100644 index 0000000000..a6bfa8909c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/NullEnvironment.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; + +/** + * Null environment class. Cannot binds and lookups fail. Used at the top + * of the environment chain. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class NullEnvironment implements Environment { + private static NullEnvironment singleton = null; + + private NullEnvironment() { } + + /** @throws InvalidBindException Always. **/ + public void bind(final Symbol sym, final Value val) { + throw new InvalidBindException("can't bind in null env"); + } + + public Value lookup(final Symbol sym) { + return null; + } + + public boolean contains(final Symbol sym) { + return false; + } + + + public EnvironmentIterator iterator() { + return new EnvironmentIterator () { + + public final boolean hasNext() { + return false; + } + + public final EnvironmentEntry next() { + throw new NoSuchElementException(); + } + }; + } + + public EnvironmentEntryIterator entryIterator() { + return new EnvironmentEntryIterator () { + + public final boolean hasNext() { + return false; + } + + public final EnvironmentEntry next() { + throw new NoSuchElementException(); + } + }; + } + + public static NullEnvironment getInstance() { + if (singleton == null) singleton = new NullEnvironment(); + return singleton; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/PRSExpressionValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/PRSExpressionValue.java new file mode 100644 index 0000000000..ee655fc216 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/PRSExpressionValue.java @@ -0,0 +1,124 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.avlsi.cell.CellImpl; +import com.avlsi.file.common.HierName; +import com.avlsi.util.bool.AndBooleanExpression; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.HierNameAtomicBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpression; +import com.avlsi.util.exception.AssertionFailure; + +/** + * Class to build up expressions for use in productions rules. + * The left hand side of a production rules corresponds to a + * PRSExpressionValue. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class PRSExpressionValue extends Value { + + private final BooleanExpressionInterface be; + + /** + * Class constructor. + **/ + public PRSExpressionValue(final BooleanExpressionInterface be) { + super(true); + + this.be = be; + } + + /** + * Class constructor. + **/ + public PRSExpressionValue(final HierName hn) { + this(new HierNameAtomicBooleanExpression(true, hn)); + } + + public Value duplicate() { + throw new AssertionFailure("Don't call me!"); + } + + /** + * Converts a PRSExpressionValue or NodeValue to a PRSExpressionValue, + * throws InvalidOperationException if the Value is not one of + * these subclasses. + **/ + public static PRSExpressionValue valueOf(Value v) + throws InvalidOperationException { + if (v instanceof PRSExpressionValue) + return (PRSExpressionValue) v; + else if (v instanceof NodeValue) { + final NodeValue nv = (NodeValue) v; + return new PRSExpressionValue( + new HierNameAtomicBooleanExpression( + true, nv.getInstanceName())); + } else + throw new InvalidOperationException("Cannot convert type " + + v.getClass().getName() + " to prs expression."); + } + + /** + * Makes a collection from two BooleanExpressionInterfaces, + * for use by or and and. + **/ + private Collection booleanExpressionsToCollection( + final BooleanExpressionInterface be1, + final BooleanExpressionInterface be2) { + final List l = new ArrayList(2); + l.add(be1); + l.add(be2); + return l; + } + + // logical + public Value or (final Value v) throws InvalidOperationException { + final PRSExpressionValue prsExprVal = valueOf(v); + return new PRSExpressionValue( + new OrBooleanExpression( + true, + booleanExpressionsToCollection(be, prsExprVal.be))); + } + + public Value and (final Value v) throws InvalidOperationException { + final PRSExpressionValue prsExprVal = valueOf(v); + return new PRSExpressionValue( + new AndBooleanExpression( + true, + booleanExpressionsToCollection(be, prsExprVal.be))); + } + + public Value not () throws InvalidOperationException { + return new PRSExpressionValue(be.negated()); + } + + public Value assign (final Value v, final CellImpl cell) { + throw new AssertionFailure("Don't call me!"); + } + + public Type getType() { + throw new AssertionFailure("Don't call me!"); + } + + public BooleanExpressionInterface getBooleanExpression() { + return be; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Range.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Range.java new file mode 100644 index 0000000000..1086556bb5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Range.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * Range class, for array subscripts and loop indices. + * Currently supports only increasing, consecutive ranges. Will + * be amended to support funkier ranges. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Range { + private final int min; + private final int max; + + public Range(final int min, final int max) { + this.min = min; + this.max = max; + } + + public int size() { + return max - min + 1; + } + + public boolean contains(final int i) { + return min <= i && i <= max; + } + + public int getMin() { + return min; + } + + public int getMax() { + return max; + } + + public Iterator iterator() { + return new Iterator(); + } + + public final class Iterator { + private int cur = min; + + public boolean hasNext() { + return cur <= max; + } + + public int next() { + return cur++; + } + + } + + public String toString() { + return min + ".." + max; + } + + public boolean equals(final Object o) { + if (!(o instanceof Range)) + return false; + else + return equals((Range) o); + + } + + public boolean equals(final Range r) { + return min == r.min && max == r.max; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SelfImportException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SelfImportException.java new file mode 100644 index 0000000000..5fc51b64f1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SelfImportException.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * Exception thrown when a cast file tries to import itself. + * + * @see CastParserEnvironment + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class SelfImportException extends Exception { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SemanticWrapperException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SemanticWrapperException.java new file mode 100644 index 0000000000..cd9edf467b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SemanticWrapperException.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import java.io.PrintStream; +import java.io.PrintWriter; + +import antlr.SemanticException; + +import com.avlsi.util.exception.ExceptionUtils; + +/** + * Semantic exception class that wraps another exception. This + * is used in cast_tree.g, and thrown for any errors in walking the tree. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class SemanticWrapperException extends SemanticException { + + /** + * Construct a SemanticWrapperException wrapping the given + * exception, with the error occuring at the specified + * filename, line, column. + **/ + public SemanticWrapperException(final Exception e, + final String filename, + final int line, + final int column) + { + this("", e, filename, line, column); + } + + /** + * Construct a SemanticWrapperException without knowing + * file/line/column info. + **/ + public SemanticWrapperException(final String message, final Exception e) + { + this(message, e, "", -1, -1); + } + + /** + * Class constructor + **/ + public SemanticWrapperException(final String message, + final Exception e, + final String filename, + final int line, + final int column) + { + super(message, filename, line, column); + initCause(e); + } + + public String getMessage() { + return toString(); + } + + /** + * Returns the message that was passed into the constructor. + * Needed to fix bug 3746. + */ + public String getMessageOnly() { + return super.getMessage(); + } + + public String toString() { + return getHeader() + " ( wrapping:\n" + getCause() + ")"; + } + + private String getHeader() { + return getClass().getName() + ": " + super.getMessage() + + " at " + getPositionInfo(); + } + + private String getPositionInfo() { + return getFilename() + ":" + getLine() + ":" + getColumn(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SparseSubscriptSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SparseSubscriptSpec.java new file mode 100644 index 0000000000..21fe6b83a7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SparseSubscriptSpec.java @@ -0,0 +1,215 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.tools.cosim.CoSimChannelNames; +import com.avlsi.util.exception.AssertionFailure; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * This class represents subscripting specification for sparse arrays, + * ie arrays with indices [0,0], [1,2], [3,1] defined. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class SparseSubscriptSpec implements SubscriptSpecInterface { + /** + * Comparator to lexicographically compare int[] used as + * indices. + **/ + private static final Comparator/**/ indexComparator = + new Comparator/**/() { + public int compare(final /*@ non_null @*/ Object o1, + final /*@ non_null @*/ Object o2) { + final int[] a1 = (int[]) o1; + final int[] a2 = (int[]) o2; + + assert a1.length == a2.length; + for (int i = 0; i < a1.length; ++i) { + // do subtraction as long to avoid overflow + final long v1 = a1[i]; + final long v2 = a2[i]; + final long c = v1 - v2; + + if (c != 0) + return c < 0 ? -1 : 1; + } + + return 0; + } + }; + + /** + * A list of the indices that exist in the subscript spec. + * If [0,0], [1,2], [3,1] existed, then + * indices = {{0, 0}, {1,2}, {3,1}} . + * Must always be sorted. + **/ + private final int[][] indices; + + /** + * The number of dimensions of the array spec. + **/ + private final int numDimensions; + + /** + * Constructs a sparse spec from a dense one. + **/ + public SparseSubscriptSpec(final DenseSubscriptSpec spec) { + numDimensions = spec.getNumDimensions(); + indices = new int[spec.getNumElements()][]; + + for (int i = 0; i < indices.length; ++i) + indices[i] = spec.indexOf(i); + } + + /** + * Constructor used by augment() to construct a + * spec from existing indices. Requires that the indices be + * sorted in lexicographic order. + **/ + private SparseSubscriptSpec(final /*@ non_null @*/ int[][] indices, + final int numDimensions) { + this.indices = indices; + this.numDimensions = numDimensions; + } + + public int getNumElements() { + return indices.length; + } + + public int getNumDimensions() { + return numDimensions; + } + + public int positionOf(final int[] idx) { + if (idx.length != numDimensions) + throw new IllegalArgumentException("dims don't agree: " + + idx.length + "!=" + + numDimensions); + + final int index = Arrays.binarySearch(indices, idx, indexComparator); + + if (index < 0) + throw new IndexOutOfBoundsException("subscript out of range"); + else + return index; + } + + public int[] indexOf(int pos) { + final int[] a = new int[numDimensions]; + + for (int i = 0; i < numDimensions; ++i) + a[i] = indices[pos][i]; + + return a; + } + + /** + * Returns a new SparseSubscriptSpec containing all the indices from + * oldSpec and augmentingSpec. + * + * @throws InvalidOperationException + * If oldSpec is not disjoint with + * augmentingSpec or if the + * dimensions do not agree. + * + *

    
    +     *   normal_behavior
    +     *     requires newValues.length ==
    +     *                oldValues.length + augmentingValues.length;
    +     *     requires oldSpec.getNumElements() == oldValues.length;
    +     *     requires augmentingSpec.getNumElements() == augmentingValues.length;
    +     * 
    + **/ + static /*@ non_null @*/ SparseSubscriptSpec augment + (/*@ non_null @*/ SubscriptSpecInterface oldSpec, + /*@ non_null @*/ Value[] oldValues, + /*@ non_null @*/ SubscriptSpecInterface augmentingSpec, + /*@ non_null @*/ Value[] augmentingValues, + /*@ non_null @*/ Value[] newValues) + throws InvalidOperationException { + + final int numDimensions = oldSpec.getNumDimensions(); + if (numDimensions != augmentingSpec.getNumDimensions()) + throw new InvalidOperationException("dims don't agree: " + + oldSpec.getNumDimensions() + "!=" + + augmentingSpec.getNumDimensions()); + + int[][] indices = new int[newValues.length][]; + + // merge indices and values into new arrays + int iOld = 0; + int iAugmenting = 0; + int iNew = 0; + for ( ; iOld < oldValues.length && + iAugmenting < augmentingValues.length; ++iNew) { + final int[] oldIndex = oldSpec.indexOf(iOld); + final int[] augmentingIndex = + augmentingSpec.indexOf(iAugmenting); + final int c = indexComparator.compare(oldIndex, augmentingIndex); + if (c == 0) { + throw new InvalidOperationException("Cannot augment. " + + "Both old and augmenting indices contain " + + DenseSubscriptSpec.idxToString(oldIndex)); + } else if (c < 0) { + indices[iNew] = oldIndex; + newValues[iNew] = oldValues[iOld]; + iOld++; + } else { + indices[iNew] = augmentingIndex; + newValues[iNew] = augmentingValues[iAugmenting]; + iAugmenting++; + } + } + + // copy over remainder + for ( ; iOld < oldValues.length; ++iNew, ++iOld) { + indices[iNew] = oldSpec.indexOf(iOld); + newValues[iNew] = oldValues[iOld]; + } + + for ( ; iAugmenting < augmentingValues.length; + ++iNew, ++iAugmenting) { + indices[iNew] = augmentingSpec.indexOf(iAugmenting); + newValues[iNew] = augmentingValues[iAugmenting]; + } + + return new SparseSubscriptSpec(indices, numDimensions); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("["); + + for (int i = 0; i < indices.length; ++i) { + if (i > 0) + sb.append(", "); + sb.append(DenseSubscriptSpec.idxToString(indices[i])); + } + + sb.append("]"); + + return sb.toString(); + } + + public CoSimChannelNames getCoSimChannelNames(String baseName, + boolean ignoreLastDimension) { + throw new AssertionFailure("can't handle sparse arrays as javablock device parameters yet. " + baseName + " is a sparse array"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SplicingEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SplicingEnvironment.java new file mode 100644 index 0000000000..0eda2c80cb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SplicingEnvironment.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.cast.impl; + +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; +import com.avlsi.cast.impl.ChainedEnvironmentIterator; + +/** + * This class merges two environments in a tree. Binds are not allowed, + * only lookups. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class SplicingEnvironment extends AbstractSplicingEnvironment { + protected Environment localEnv; + + public SplicingEnvironment(final Environment parentEnv, + final Environment localEnv) { + super(parentEnv); + + if (localEnv == null) + throw new IllegalArgumentException("localEnv was null"); + + this.localEnv = localEnv; + } + + protected Environment getLocalEnvironment() { + return localEnv; + } + + /** + * Bind not allowed; throws InvalidBindException. + * + * @throws InvalidBindException Always. + **/ + public void bind(final Symbol sym, final Value val) { + throw new InvalidBindException("SplicingEnvironment " + + "doesn't allow bind()."); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("SplicingEnvironment(\n"); + sb.append("parent:"); + sb.append(parentEnv.toString()); + sb.append(",me:\n"); + sb.append(localEnv.toString()); + sb.append(")\n"); + + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SubscriptSpecInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SubscriptSpecInterface.java new file mode 100644 index 0000000000..87a153831b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SubscriptSpecInterface.java @@ -0,0 +1,70 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.tools.cosim.CoSimChannelNames; + +/** + * This class represents subscripting specification for arrays, + * ie [K..L,M..N] for dense arrays or even sparse + * arrays with indices [0,0], [1,2], [3,1] defined. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public interface SubscriptSpecInterface { + /** + * Returns the number of elements in the subscript specification. + **/ + int getNumElements(); + + /** + * Returns the number of dimensions in the subscript specification. + **/ + int getNumDimensions(); + + /** + * Returns the position in a 1-D array indexed by this + * SubscriptSpec at which the specified element will be found. + * The order is row-major. positionOf(new int[]{1,2}) means + * a[1,2]. + * + * @exception IllegalArgumentException + * if idx.length != getNumDimensions() + * @exception IndexOutOfBoundsException + * if idx is not a subscript contained in the + * subscript specification + **/ + int positionOf(final int[] idx); + + /** + * Returns the subscripted spec for the given position. + * + * @exception ArrayIndexOutOfBoundsException + * if pos < 0 || pos >= getNumElements() + **/ + int[] indexOf(int pos); + + /** + * Returns an array of names. Under the cosim framework, each of + * these names corresponds to a NodeChannel. + * + * @param baseName the name of the overall array + * @param ignoreLastDimension Arrays of wide channels use the last + * dimension as channelwidth, so cosim names for that array should + * ignore that dimension + **/ + CoSimChannelNames getCoSimChannelNames(String baseName, + boolean ignoreLastDimension); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Symbol.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Symbol.java new file mode 100644 index 0000000000..333c2c8ea2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Symbol.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * Symbol class, just a string, but could, in the future, use + * a WeakHashSet of these guys. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Symbol { + private final String s; + + private Symbol(final String s) { + this.s = s; + } + + /** Return a non-global form of this Symbol. Doesn't change original. **/ + public Symbol stripBang() { + if (s.endsWith("!")) + return new Symbol(s.substring(0, s.length()-1)); + else + return this; + } + + /** Does this Symbol represent a global name (ends in !)? **/ + public boolean isGlobal() { + return s.endsWith("!"); + } + + public static Symbol create(final String s) { + return new Symbol(s); + } + + public String getString() { + return s; + } + + /** + * Is the module name part of the symbol, or just the type name? + **/ + public boolean fullyQualified() { + return (s.indexOf('.') != -1); + } + + public int hashCode() { + return s.hashCode(); + } + + public boolean equals(Object o) { + if (o instanceof Symbol) + return equals((Symbol) o); + else + return false; + } + + public boolean equals(Symbol sym) { + return s.equals(sym.s); + } + + public String toString() { + return "Symbol(" + s + ")"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SymbolRedeclaredException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SymbolRedeclaredException.java new file mode 100644 index 0000000000..4c63621ef2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/SymbolRedeclaredException.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +/** + * Exception thrown by {@link Environment#bind} when a symbol has already + * been declared. + * + * @see Environment + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class SymbolRedeclaredException extends Exception { + private final Symbol sym; + + public SymbolRedeclaredException() { + super(); + + this.sym = null; + } + + public SymbolRedeclaredException(final Symbol sym) { + super("Symbol \"" + sym.getString() + + "\" redeclared. Did you array cells with different metaparameters?"); + + this.sym = sym; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TestDenseSubscriptSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TestDenseSubscriptSpec.java new file mode 100644 index 0000000000..5fa746a99e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TestDenseSubscriptSpec.java @@ -0,0 +1,100 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import com.avlsi.test.AbstractTestCase; + +/** + * Test case for DenseSubscriptSpec + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class TestDenseSubscriptSpec extends AbstractTestCase { + public void test() { + // array[a..b,c..d,e..f] + // Make an array a[1..3,-3..0,10..11] + // this has 3 * 4 * 2 = 24 elements + + // we will go manually through the order [1,-3,10], [1,-3,11], ... + // and ensure that the positions are correct. + + final int a = 1; + final int b = 30; + final int c = -30; + final int d = -30; + final int e = 10; + final int f = 110; + + final DenseSubscriptSpec spec = new DenseSubscriptSpec(new Range[]{ + new Range(a, b), new Range(c, d), new Range(e, f) + }); + + int n = 0; + + for (int i = a; i <= b; ++i) + for (int j = c; j <= d; ++j) + for (int k = e; k <= f; ++k) { + final int[] idx = new int[]{i, j, k}; + final int pos = spec.positionOf(idx); + + if (pos != n) { + final StringWriter sw = new StringWriter(); + final PrintWriter ps = new PrintWriter(sw); + + ps.println("Error for " + n); + ps.println("got " + pos); + for (int s = 0; s < 3; ++s) + ps.print(idx[s] + " "); + ps.println(); + + assertTrue(false, sw.toString()); + } + + final int[] inverseIdx = spec.indexOf(n); + + boolean err = false; + for (int s = 0; s < 3; ++s) + if (inverseIdx[s] != idx[s]) + err = true; + + if (err) { + final StringWriter sw = new StringWriter(); + final PrintWriter ps = new PrintWriter(sw); + + ps.println("bad inverse"); + ps.print("got: "); + for (int s = 0; s < 3; ++s) + ps.print(inverseIdx[s] + " "); + ps.println(); + ps.print("wanted: "); + for (int s = 0; s < 3; ++s) + ps.print(idx[s] + " "); + ps.println(); + + assertTrue(false, sw.toString()); + } + + ++n; + } + } + + public static void main(String[] args) { + AbstractTestCase.testOne(new TestDenseSubscriptSpec()); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TokenWithInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TokenWithInfo.java new file mode 100644 index 0000000000..fc6cdc6aa3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TokenWithInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import antlr.CommonToken; + +/** + * This class adds filename information to CommonToken. + * + * @see antlr.CommonToken + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TokenWithInfo extends CommonToken { + private String filename = null; + + public TokenWithInfo() { + super(); + } + + public TokenWithInfo(final int t, final String text) { + super(t, text); + } + + public TokenWithInfo(final String text) { + super(text); + } + + public String getFilename() { + return filename; + } + + public void setFilename(final String filename) { + this.filename = filename; + } + + public String toString() { + return "[\""+getText()+"\",<"+getType()+">,line="+getLine() + +",column="+getColumn()+",filename="+getFilename()+"]"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TopLevelEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TopLevelEnvironment.java new file mode 100644 index 0000000000..453e46c77e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TopLevelEnvironment.java @@ -0,0 +1,131 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.cast.impl; + + +import java.util.NoSuchElementException; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentIterator; +import com.avlsi.cast.impl.ChainedEnvironmentIterator; + +/** + * Environment for top level of file. This consists of a local environment, + * and the environments imported from elsewhere. Lookups first occur + * in the local environment, then are passed on to the imported + * environments. Declarations happen in the local environment. + *

    + * In the future, there will be a distinction private symbols that are + * not exported. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TopLevelEnvironment implements Environment { + private final ImportEnvironment importEnv; + private final BlockEnvironment topEnv; + + public TopLevelEnvironment(final ImportEnvironment importEnv) { + this.importEnv = importEnv; + // Disallow "import foo.bar.FOO; define FOO()() {...}" + this.topEnv = new FixedBlockEnvironment(NullEnvironment.getInstance()); + } + + + /** + * Prevents rebinding of a symbol which has been imported. + **/ + public void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + if (importEnv.contains(sym)) + throw new SymbolRedeclaredException(sym); + topEnv.bind(sym, val); + } + + public Value lookup(final Symbol sym) + throws AmbiguousLookupException { + final Value v = topEnv.lookup(sym); + if (v != null) + return v; + return importEnv.lookup(sym); + } + + public boolean contains(final Symbol sym) { + return (topEnv.contains(sym) || importEnv.contains(sym)); + } + + public Environment getExportedEnvironment() { + return new UnbindableEnvironment(topEnv); + } + + /** + * Environment that does not allow binds to occur. + **/ + private static final class UnbindableEnvironment implements Environment { + private final Environment env; + + public UnbindableEnvironment(final Environment env) { + if (env == null) + throw new IllegalArgumentException("env was null"); + + this.env = env; + } + + /** @throws InvalidBindException Always. **/ + public void bind(final Symbol sym, final Value val) { + throw new InvalidBindException("can't bind to this env"); + } + + public Value lookup(final Symbol sym) + throws AmbiguousLookupException { + return env.lookup(sym); + } + + public boolean contains(final Symbol sym) { + return env.contains(sym); + } + + public String toString() { + return "UnbindableEnvironment(" + env.toString() + ")"; + } + + public EnvironmentIterator iterator() { + return env.iterator(); + } + + public EnvironmentEntryIterator entryIterator() { + return env.entryIterator(); + } + + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("TopLevelEnvironment(\n"); + sb.append(topEnv.toString()); + sb.append("\nImportEnv:\n"); + sb.append(importEnv.toString()); + sb.append(")\n"); + + return sb.toString(); + } + + + public EnvironmentIterator iterator() { + return new ChainedEnvironmentIterator( topEnv, importEnv ); + } + + public EnvironmentEntryIterator entryIterator() { + return new ChainedEnvironmentEntryIterator( topEnv, importEnv ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleGroupValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleGroupValue.java new file mode 100644 index 0000000000..c9bb2a6aa9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleGroupValue.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.util.exception.AssertionFailure; + +/** + * This class bundles tuples together to create one Value for cell + * instantiation. Currently it contains the port list and implied + * port list; if CAST is extended further it might contain more. + **/ + +public final class TupleGroupValue extends Value { + private final TupleValue portList; + private final TupleValue impliedPortList; + + public TupleGroupValue(TupleValue portList, TupleValue impliedPortList) { + super(true); + this.portList = portList; + this.impliedPortList = impliedPortList; + } + + public TupleValue getPortList() { return portList; } + public TupleValue getImpliedPortList() { return impliedPortList; } + + // stuff to implement Value. + public Value duplicate() { + throw new AssertionFailure("can't dup tuple groups; can't happen"); + } + + public Value assign (final Value v, final CellImpl cell) + throws InvalidOperationException { + throw new InvalidOperationException("can't assign tuple groups; can't happen"); + } + + public Type getType() throws InvalidOperationException { + throw new InvalidOperationException("not yet implemented"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleValue.java new file mode 100644 index 0000000000..89906ed3d8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/TupleValue.java @@ -0,0 +1,145 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import java.util.Arrays; +import java.util.Iterator; + +import com.avlsi.cell.CellImpl; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; + +/** + * This class represents values for tuple expressions. + * These only occur in instantiation expressions: + * T(v1,v2,v3) x(v4,v5,v6). (v1,v2,v3) + * and (v4,v5,v6) are tuple values. Assignments to + * tuples assign to the contained values. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class TupleValue extends Value { + + private final Value[] vals; + + public TupleValue(final Value[] vals) { + super(true); + this.vals = vals; + } + + public static TupleValue valueOf(final Value val) + throws InvalidOperationException { + if (val instanceof TupleValue) + return (TupleValue) val; + else + throw new InvalidOperationException("no conversion of " + + val.getInstanceName() + + " to tuple"); + } + + public Value duplicate() { + throw new AssertionFailure("can't dup tuples; can't happen"); + } + + public int getSize() { + return vals.length; + } + + // container + public Value accessTuple(int i) throws InvalidOperationException { + try { + return vals[i]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new InvalidOperationException("Index out of bounds: tried to access a tuple of length " + vals.length + " with index " + i, e); + } + } + + // assignment + public Value assign (final Value v, final CellImpl cell) + throws InvalidOperationException { + final TupleValue tv = valueOf(v); + + if (tv.vals.length != vals.length) + throw new InvalidOperationException( + "sizes don't agree for assignment: " + tv.vals.length + + "!=" + vals.length); + + for (int i = 0; i < vals.length; ++i) + vals[i].assign(tv.vals[i], cell); + + return this; + } + + public Type getType() throws InvalidOperationException { + throw new InvalidOperationException("not implemented yet"); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("("); + for (int i = 0; i < vals.length; ++i) { + if (i > 0) + sb.append(","); + sb.append(vals[i].toString()); + } + sb.append(")"); + + return sb.toString(); + } + + /** + * Returns true if all of the values in the tuple are + * equal according to their equals methods. + **/ + public boolean equals(final Object o) { + if (!(o instanceof TupleValue)) + return false; + else + return equals((TupleValue) o); + } + + /** + * Returns true if all of the values in the tuple are + * equal according to their equals methods. + **/ + public boolean equals(final TupleValue tv) { + if (getSize() != tv.getSize()) + return false; + + for (int i = 0; i < getSize(); ++i) + if (!vals[i].equals(tv.vals[i])) + return false; + + return true; + } + + public int hashCode() { + int hc = 0; + + for (int i = 0; i < getSize(); ++i) + hc ^= vals[i].hashCode(); + + return hc; + } + + /** + * Iterate over the values in the tuple, in order, starting from the first + * element. + **/ + public Iterator getIterator() { + return Arrays.asList(vals).iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Type.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Type.java new file mode 100644 index 0000000000..fd19e67468 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Type.java @@ -0,0 +1,20 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.cast.impl; + +/** + * Cookie for types. Can only be tested for compatability. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public abstract class Type { + public abstract String getString(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/UserDefinedValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/UserDefinedValue.java new file mode 100644 index 0000000000..48695f0ad3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/UserDefinedValue.java @@ -0,0 +1,452 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import java.util.HashMap; +import java.util.Map; + +import antlr.collections.AST; + +import com.avlsi.cell.CellImpl; +import com.avlsi.util.container.Pair; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.debug.Debug; +import com.avlsi.file.common.HierName; +import com.avlsi.util.text.StringUtil; + +/** + * This class contains information CastTwoTree needs to + * generate a CellImpl for types defined in CAST files by + * define or defchan. This information is: + *

      + *
    • The environment in place before the type definition was parsed + *
    • The AST for the meta parameter list + *
    • The AST for the port parameter list + *
    • The AST for the implied port parameter list + *
    • The AST for the refinement parent + *
    • The AST for the body of the type definition + *
    • The module in which the type was declared + *
    • A flag indicating which of the following keywords was used + * to define the type: define or defchan + *
    + * + *

    For efficency, this class caches (in the {@link #cellMap}) the + * CellImpl corresponding to each combination of + * metaparameters. Similiar maps are kept for the tree parser's + * use ({@link aliasesMap}, {@link cellConstantsMap}, {@link prsEnvMap} + * and {@link subcellsEnvMap}). To explain that would be to explain + * CastTwoTree.g, and that is beyond the scope of this comment. + * All these maps map from a {@link TupleValue} of the metaparameter values + * to whatever the map is mapping to. + * + *

    Note that this class extends {@link Value}. This was done + * so the CAST implementation could treat types somewhat like first + * class objects, even though types are not first class objects in + * the CAST language. This may have been a good decision. This may + * have been a bad decision. Pointless arguments about this decision + * may ensue. + * + *

    This class is called UserDefinedValue and + * represents the type definitions of user defined types (those + * defined with define or defchan). Do not + * confuse it with {@link InstanceValue}, which represents instances + * of these types. UserDefinedValue was chosen over + * something like CellValue because in the future + * additional user defined types may be added, perhaps functions. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class UserDefinedValue extends Value { + + private final Environment env; + private final AST metaParamList; + private AST portParamList; + private AST impliedPortParamList; + private AST envExtraParamList; + private final AST inheritanceList; + private final AST refinementParent; + private AST body; + private final String moduleName; + /** Whether it's a cell, attributes cell, alias cell, or a channel **/ + private final int structureType; + + // cellMap, aliasesMap, cellConstantsMap, prsEnvMap and subcellsEnvMap + // are conceptually very similar, but accessed at different points + // in the parsing. + + /** + * Precomputed cells for this UDV and specific metaparameters. + * TupleValue (metaparameters) -> CellImpl. + **/ + private final Map cellMap; + + /** + * Precomputed aliases this channel should export. TupleValue + * (metaparameters) -> LocalEnvironment + **/ + private final Map aliasesMap; + + /** + * Precomputed top-level environments for this UDV and specific + * metaparameters. These contain the ints/bools/floats defined at + * the top-level of the cell. This map exists to allow these + * constants to be passed along via refinement. + * + * TupleValue (metaparameters) -> LocalEnvironment. + **/ + private final Map cellConstantsMap; + + /** + * Environment containing nodes and cells declared in the prs block. + * This map exists to allow these constants to be passed along via + * refinement. + * + * TupleValue (metaparameters) -> Environment. + **/ + private final Map prsEnvMap; + + /** + * Environment containing nodes and cells declared in the subcells + * or subtypes block. This map exists to allow these constants to + * be passed along via refinement. + * + * TupleValue (metaparameters) -> Environment. + **/ + private final Map subcellsEnvMap; + + /** + * Environment containing metaparameters, and imported cells. This map + * exists to allow refinement children to omit the port list. + * + * TupleValue (metaparameters) -> Environment. + **/ + private final Map portEnvMap; + + private boolean portListInherited; + + /** Symbol for the cell type. **/ + private final Symbol cellTypeSymbol; + + /** + * The cell containing this cell, if this cell is an environment; otherwise + * null. + **/ + private UserDefinedValue environmentContainer; + + /** Available structureTypes **/ + public static final int CELL = 0, ATTRIBUTES_CELL = 1, CHANNEL = 2, + ALIAS_CELL = 3; + + public UserDefinedValue( + final Environment env, + final Symbol cellTypeSymbol, + final AST metaParamList, + final AST portParamList, + final AST impliedPortParamList, + final AST body) + { + this(env, cellTypeSymbol, metaParamList, portParamList, impliedPortParamList, null, null, null, body, null, CELL); + } + + public UserDefinedValue( + final Environment env, + final Symbol cellTypeSymbol, + final AST metaParamList, + final AST portParamList, + final AST impliedPortParamList, + final AST envExtraParamList, + final AST inheritanceList, + final AST refinementParent, + final AST body, + final String moduleName, + final int structureType) + { + super(true); + + this.env = env; + this.cellTypeSymbol = cellTypeSymbol; + this.metaParamList = metaParamList; + this.portParamList = portParamList; + this.impliedPortParamList = impliedPortParamList; + this.envExtraParamList = envExtraParamList; + this.inheritanceList = inheritanceList; + this.refinementParent = refinementParent; + this.body = body; + this.moduleName = moduleName; + this.cellMap = new HashMap(); + this.aliasesMap = new HashMap(); + this.cellConstantsMap = new HashMap(); + this.prsEnvMap = new HashMap(); + this.subcellsEnvMap = new HashMap(); + this.portEnvMap = new HashMap(); + this.portListInherited = false; + Debug.assertTrue((structureType == CELL) || + (structureType == ATTRIBUTES_CELL) || + (structureType == CHANNEL) || + (structureType == ALIAS_CELL), + "UserDefinedValue given bad structure type: " + structureType); + this.structureType = structureType; + } + + public Value assign(final Value v, final CellImpl cell) + throws InvalidOperationException { + throw new InvalidOperationException("can't assign types!"); + } + + public Value duplicate() { + throw new AssertionFailure("can't dup types!"); + } + + // + // accessors + // + + public Environment getEnvironment() { + return env; + } + + public AST getMetaParamList() { + return metaParamList; + } + + public boolean hasMetaParams() { + return metaParamList != null && metaParamList.getFirstChild() != null; + } + + public AST getPortParamList() { + return portParamList; + } + + /* The port list of a refinement child may be empty to mean it has the same + * ports as the parent. This lets us update the port list accordinly. */ + public void updatePortParamList(AST inherited) { + portListInherited = true; + portParamList = inherited; + } + + public boolean isPortListInherited() { + return portListInherited; + } + + public AST getImpliedPortParamList() { + return impliedPortParamList; + } + + /** To let refinement change the implied ports. **/ + public void updateImpliedPortParamList(AST inherited) { + impliedPortParamList = inherited; + } + + public AST getEnvExtraParamList() { + return envExtraParamList; + } + + /** To let refinement change the extra ports. **/ + public void updateEnvExtraParamList(AST inherited) { + envExtraParamList = inherited; + } + + public AST getInheritanceList() { + return inheritanceList; + } + + public AST getRefinementParent() { + return refinementParent; + } + + public AST getBody() { + return body; + } + + public void clearBody() { + body = null; + } + + public String getModuleName() { + return moduleName; + } + + public String getCellTypeName() { + return cellTypeSymbol.getString(); + } + + public String getFullyQualifiedType() { + if (moduleName == null) + return getCellTypeName(); + else + return moduleName + '.' + getCellTypeName(); + } + + public int getStructureType() { + return structureType; + } + + public Type getType() throws InvalidOperationException { + throw new InvalidOperationException ("not yet implemented"); + } + + public String toString() { + return "UserDefinedValue()"; + } + + // + // Cell stuff + // + + /** + * Add an instantiation of the cell for the given meta-parameters. + **/ + public void putCell(final TupleValue metaParams, final CellImpl cell) { + cellMap.put(metaParams, cell); + } + + /** + * Get the instantiation of the cell for the given meta-parameters. + **/ + public CellImpl getCell(final TupleValue metaParams) { + return (CellImpl) cellMap.get(metaParams); + } + + /** + * Add aliases for the given metaparameters (only relevant to channels) + **/ + public void putAliases(final TupleValue metaParams, + final LocalEnvironment aliases) { + aliasesMap.put(metaParams, aliases); + } + + /** + * Get aliases for the given metaparameters (only relevant to channels) + **/ + public LocalEnvironment getAliases(final TupleValue metaParams) { + return (LocalEnvironment) aliasesMap.get(metaParams); + } + + /** + * Take ints/bools/floats from the top-level of the cell for the + * given metaparameters and add them to the internal cache. + **/ + public void putCellConstants(final TupleValue metaParams, + final Environment cellConstants) { + cellConstantsMap.put(metaParams, cellConstants); + } + + /** + * Return cell-top-level ints/bools/floats for the given + * metaparameters. + **/ + public Environment getCellConstants(final TupleValue metaParams) { + return (Environment) cellConstantsMap.get(metaParams); + } + + /** + * Take nodes/cells defined in the prs block and add them to the + * internal cache for use in refining cells. + **/ + public void putPrsEnvironment(final TupleValue metaParams, + final Environment prsEnv) { + prsEnvMap.put(metaParams, prsEnv); + } + + /** + * Return nodes/cells defined in the prs block. Needed for refining + * cells. + **/ + public Environment getPrsEnvironment(final TupleValue metaParams) { + return (Environment) prsEnvMap.get(metaParams); + } + + /** + * Take nodes/cells defined in the subcells or subtypes block and add + * them to the internal cache for use in refining cells. + **/ + public void putSubcellsEnvironment(final TupleValue metaParams, + final Environment subcellsEnv) { + subcellsEnvMap.put(metaParams, subcellsEnv); + } + + /** + * Return nodes/cells defined in the subcells or subtypes block. + * Needed for refining cells. + **/ + public Environment getSubcellsEnvironment(final TupleValue metaParams) { + return (Environment) subcellsEnvMap.get(metaParams); + } + + public void putPortEnvironment(final TupleValue metaParams, + final Environment portListEnv) { + portEnvMap.put(metaParams, portListEnv); + } + + public Environment getPortEnvironment(final TupleValue metaParams) { + return (Environment) portEnvMap.get(metaParams); + } + + /** + * Return the cell where this cell is an environment, or null + * if this cell is not an environment. + **/ + public UserDefinedValue getEnvironmentContainer() { + return environmentContainer; + } + + /** + * Set the cell where this cell is an environment. + **/ + public void updateEnvironmentContainer(final UserDefinedValue cell) { + environmentContainer = cell; + } + + /** + * Returns a string representation of the name with meta parameters. + * This is what we should expect the .mag file to be called. + * Ie "SLACK_1of2(2)" + **/ + public static String getTypeName(final String baseName, + final TupleValue metaParams) { + if (metaParams.getSize() == 0) + return baseName; + else { + final StringBuffer sb = new StringBuffer(baseName); + + sb.append('('); + try { + for (int i = 0; i < metaParams.getSize(); ++i) { + final Value v = metaParams.accessTuple(i); + + if (i > 0) + sb.append(","); + + // code similiar to ArrayValue.getMetaParamString + if (v instanceof IntValue) + sb.append(((IntValue) v).getValue()); + else if (v instanceof BoolValue) + sb.append(((BoolValue) v).getValue()); + else if (v instanceof ArrayValue) + sb.append(((ArrayValue) v).getMetaParamString()); + else + throw new AssertionFailure("bad meta-param type"); + } + } catch (InvalidOperationException e) { + throw (AssertionFailure) + new AssertionFailure("invalid operation?" + + " can't happen").initCause(e); + } + sb.append(')'); + + return sb.toString(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Value.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Value.java new file mode 100644 index 0000000000..ef1c8302dd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/Value.java @@ -0,0 +1,178 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast.impl; + +import com.avlsi.cell.CellImpl; +import com.avlsi.file.common.HierName; +import com.avlsi.util.exception.AssertionFailure; + +/** + * Each object of this class represents the value of an expression. + * Every variable has a Value. Every value has a type. Each value type + * corresponds to a subclass of Value: ie FloatValue, IntValue, + * BooleanValue, etc. + * + * The default implementation of every operations just throws + * InvalidOperationException. If a subclass wants to support the + * operation, it should override the method. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public abstract class Value { + + /** + * Specifies if the value is defined. + **/ + private boolean definedP; + + /** + * Class constructor, specifies if the value is defined. + **/ + protected Value(final boolean definedP) { this.definedP = definedP; } + + /** + * Tells if the value is defined. + **/ + public boolean isDefined() { return definedP; } + + /** + * Throws InvalidOperationException if the value is not defined. + **/ + public void ensureDefined() throws InvalidOperationException { + if (!isDefined()) + throw new InvalidOperationException("Undefined value"); + } + + /** + * Makes the value defined. + **/ + protected void setDefined() { + definedP = true; + } + + /** + * Returns a duplicate of the value. Changes made to the duplicate + * should not affect the original in any way. This probably means a + * deep copy. + **/ + public abstract Value duplicate(); + + // logical + public Value or (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value and (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value not () throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value xor (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + + // arithmetic + public Value add (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value subtract (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value multiply (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value divide (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value mod (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value pow (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value unaryPlus() throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value negate () throws InvalidOperationException + { throw new InvalidOperationException(); } + + // relational + public Value lt (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value le (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value eq (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value ne (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value ge (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + public Value gt (final Value v) throws InvalidOperationException + { throw new InvalidOperationException(); } + + // container + // public Value accessField(Ident xxx) + public Value accessArray(final SubscriptSpecInterface accessSpec) + throws InvalidOperationException + { throw new InvalidOperationException(); } + + public Value accessTuple(final int i) throws InvalidOperationException + { throw new InvalidOperationException(); } + + // user defined type instantiation + // would it make sense to do int/bool/float/... similiarly? + // public InstanceValue instantiate(final TupleValue v1, + public Value instantiate(final TupleValue v1, + final TupleValue v2) + throws InvalidOperationException { + throw new InvalidOperationException(); + } + + /** + * Assigns v to this. + * + * @param v the value to assign + * @param cell the cell in which the assignment occured. + * This is needed if the assignment is of a NodeValue + * or InstanceValue, because a connection must + * be added to the connection list of the cell. + **/ + public abstract Value assign (final Value v, final CellImpl cell) + throws InvalidOperationException; + + /** + * Returns the instance name of the NodeValue, InstanceValue, + * or ArrayValue; otherwise returns null. Ie "a[0].b[2].c.d" + * + * @design jmr Consider a NamedValue wrapper class. This + * could avoid constructing new instances just to change the name. + **/ + public HierName getInstanceName() { + return null; + } + + /** + * Returns a value alike in all ways, but with a different instance + * name. + **/ + public Value newInstanceName(final HierName newInstanceName) { + return this; + } + + /** + * Throws the exception if getType() isn't implemented on that + * type of Value yet. + **/ + public abstract Type getType() throws InvalidOperationException; + + /** + * Returns true if this is v or refined from v or refined from a + * Value which is refined from v or.... Meaningless for any Value + * which doesn't correspond to a chunk of silicon. + **/ + public boolean eventuallyRefinesFrom(Value v) + throws InvalidOperationException { + throw new InvalidOperationException("This value doesn't correspond to actual hardware: " + this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/custom.mk new file mode 100644 index 0000000000..8fbf27c198 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast/impl/custom.mk @@ -0,0 +1,27 @@ +MAKE_ANTLR_RULES_G_FILE_NAME := Cast.g +MAKE_ANTLR_RULES_LEXER_NAME := CastLexer +MAKE_ANTLR_RULES_PARSER_NAME := CastParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := Cast + +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk + +MAKE_ANTLR_RULES_G_FILE_NAME := Dumb.g +MAKE_ANTLR_RULES_LEXER_NAME := DumbLexer +MAKE_ANTLR_RULES_PARSER_NAME := DumbParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := DumbParser + +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk + +CURR_INTERMEDIATE_FILES := $(CURR_TARGET_DIR)/DumbTokenTypes.java \ + $(CURR_TARGET_DIR)/DumbTokenTypes.txt \ + $(CURR_INTERMEDIATE_FILES) + +MAKE_ANTLR_RULES_G_FILE_NAME := CastTree.g +MAKE_ANTLR_RULES_LEXER_NAME := +MAKE_ANTLR_RULES_PARSER_NAME := CastTreeParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := CastTreeParser + +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk + +$(CURR_TARGET_DIR)/CastTreeParser.java: $(CURR_TARGET_DIR)/CastParser.java + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveConstants.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveConstants.java new file mode 100644 index 0000000000..d9f0a82af5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveConstants.java @@ -0,0 +1,254 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive; + +/** + * An interface that contains directive constants. + **/ +public interface DirectiveConstants { + /** + * Define directive names here to enable external access. To add a new + * directive, add a type name here, and then add a line to the static + * section in DirectiveTable.java to register the directive. + **/ + String CYCLE_COUNT = "cycle_count"; + String RESET_CYCLE_COUNT = "reset_cycle_count"; + String CYCLE_NODE = "cycle_node"; + String CYCLE_TIME = "cycle_time"; + String NTPC_SPEC = "ntpc_spec"; + String ASPICE_DIGITAL_CYCLES = "aspice_digital_cycles"; + String ASPICE_ANALOG_CYCLES = "aspice_analog_cycles"; + String ASPICE_TIME_MAX = "aspice_time_max"; + String NTPC_SCALING = "ntpc_scaling"; + String RTE_COSIM_SPEC = "rte_cosim_spec"; + String RTE_ENV_COSIM_SPEC = "rte_env_cosim_spec"; + String RTE_IGNORE = "rte_ignore"; + String ASPICE_IGNORE = "aspice_ignore"; + String JAUTO_IGNORE = "jauto_ignore"; + String FRAGMENT = "fragment"; + String CELLNONOBSERVABLE = "cellnonobservable"; + String FLOORPLAN = "floorplan"; + String SYNCHRONOUS = "synchronous"; + String UNIMPL = "unimplementable"; + String NO_STAT = "nostaticizer"; + String SYMMETRIZE = "symmetrize"; + String SHARED = "shared"; + String DELAYBIAS = "delaybias"; + String EXTRA_DELAY = "extra_delay"; + String ASTA_EXTRA_DELAY = "asta_extra_delay"; + String DEFAULT_UP_DELAY = "default_up_delay"; + String DEFAULT_DN_DELAY = "default_dn_delay"; + String SIGNOFF = "sign_off"; + String SIGNOFF_CONSTANT = "signoff_constant"; + String UNUSED_PRS = "unused_prs"; + String CUTPATH = "cutpath"; + String FIXED_SIZE = "fixed_size"; + String MIN_WIRELENGTH = "min_wirelength"; + String MIN_WIRESPAN = "min_wirespan"; + String WIRELENGTH = "wirelength"; + String WIRESPAN = "wirespan"; + String WIREWIDTH = "wirewidth"; + String WIRESPACE = "wirespace"; + String EXTERNAL_WIRELENGTH = "external_wirelength"; + String EXTERNAL_LOADCAP = "external_loadcap"; + String EXTERNAL_DRIVER = "external_driver"; + String INTERNAL_WIRELENGTH = "internal_wirelength"; + String INTERNAL_LOADCAP = "internal_loadcap"; + String INTERNAL_DRIVER = "internal_driver"; + String CDLSCALE = "cdlscale"; + String HEIGHT = "height"; + String WIDTH = "width"; + String SPLITTABLE = "splittable"; + String OWNER = "owner"; + String CHANNEL_BUNCHED = "bunched"; + String PINLAYER = "pinlayer"; + String BITPITCH = "bitpitch"; + String PINTYPE = "pintype"; + String PINTYPE_INPLACE = "inplace"; + String PINTYPE_PITCHED = "pitched"; + String LOADCAP = "loadcap"; + String PASSGATE = "passgate"; + String DENSITY_FACTOR = "density_factor"; + String INLINE_LAYOUT = "inline_layout"; + String RESISTANCE_SCALE = "resistance_scale"; + String STACK_GATE = "stack_gate"; + String STATICIZER_GATE = "staticizer_gate"; + String TAU = "tau"; + String MINDELAY = "mindelay"; + String STRENGTHBIAS = "strength_bias"; + String LAYOUT_ATTRIBUTES = "layout_attributes"; + String EXTRA_LAYOUT_ATTRIBUTES = "extra_layout_attributes"; + String LAYER_KEEPOUT_PATTERN = "layer_keepout_pattern"; + String LAYER_WIREPITCH = "layer_wirepitch"; + String LAYER_WIRESPACING = "layer_wirespacing"; + String LAYER_WIREWIDTH = "layer_wirewidth"; + String LAYER_POWERGRID_OFFSET = "layer_powergrid_offset"; + String LAYER_POWERGRID_SPACING = "layer_powergrid_spacing"; + String LAYER_POWERGRID_WIREWIDTH = "layer_powergrid_wirewidth"; + String DENSITY_SCALE_FACTOR = "density_scale_factor"; + String BASE_TRANSISTOR_LAYOUT_WIDTH = "base_transistor_layout_width"; + String BOUNDARY_SMALL_CELL_WARNING_CUTOFF = "boundary_small_cell_warning_cutoff"; + String WIDTH_MINIMUM = "width_minimum"; + String HEIGHT_MINIMUM = "height_minimum"; + String BOUNDARY_POSITION = "boundary_position"; + String WIDTH_INCREMENT = "width_increment"; + String HEIGHT_INCREMENT = "height_increment"; + String WIDTH_OVERHEAD = "width_overhead"; + String HEIGHT_OVERHEAD = "height_overhead"; + String NETLIST_PRIMITIVE = "netlist_primitive"; + String PRECHARGE_PRIMITIVE = "precharge_primitive"; + String CAP = "cap"; + String ANTENNA_DIODE = "antenna_diode"; + String ESTIMATED_DELAY = "estimated_delay"; + String MEASURED_DELAY = "measured_delay"; + String ESTIMATED_CAP = "estimated_cap"; + String MEASURED_CAP = "measured_cap"; + String DEFAULT_SLEW = "default_slew"; + String MEASURED_CHARGE = "measured_charge"; + String CSP_COSIM_WILL_FAIL = "csp_cosim_will_fail"; + String TIMED = "timed"; + String TIMED_JITTER = "timed_jitter"; + String PRS_NETLIST_MISMATCH_OK = "prs_netlist_mismatch_ok"; + String PROTEUS_TAG = "proteus_tag"; // for taging proteus imported cast + + String POWERGRID_GNDNET = "powergrid_gndnet"; + String POWERGRID_VDDNET = "powergrid_vddnet"; + + String LVS_NODES = "lvs_labels"; + + String ESTIMATED_DELAY_SIGNOFF = "estimated_delay_signoff"; + String NTPC_SCALING_SIGNOFF = "ntpc_scaling_signoff"; + String SLEW_SIGNOFF = "slew_signoff"; + String SKEW_SIGNOFF = "skew_signoff"; + String ALINT_SIGNOFF = "alint_signoff"; + String STATICIZER_RATIO_SIGNOFF = "staticizer_ratio_signoff"; + String BUMP_SIGNOFF = "bump_signoff"; + String ALINT_IGNORE = "alint_ignore"; + String ACTIVITY_FACTOR = "activity_factor"; + String DC_WIRING_SPEC = "dc_wiring_spec"; + String AC_WIRING_SPEC = "ac_wiring_spec"; + String EFFECTIVE_RESISTANCE = "effective_resistance"; + String INTRINSIC_DELAY = "intrinsic_delay"; + String INTRINSIC_CAPACITANCE = "intrinsic_capacitance"; + String TRANSISTOR_TYPE = "transistor_type"; + String FAST_TRANSISTOR_TYPE = "fast_transistor_type"; + String SLOW_TRANSISTOR_TYPE = "slow_transistor_type"; + String TRANSISTOR_NAME = "transistor_name"; + String PLUS_NODE = "plus_node"; + String MINUS_NODE = "minus_node"; + String LEAKY = "leaky"; + String ROUTED = "routed"; + String AUTO_LAYOUT = "auto_layout"; + String COVERAGE_IGNORE = "coverage_ignore"; + String ALINT_MAX_BUMP_FANIN = "alint_max_bump_fanin"; + String ALINT_DEFAULT_SCENARIOS = "alint_default_scenarios"; + String ALINT_SCENARIO = "alint_scenario"; + String ALINT_DELAY_SCENARIO = "alint_delay_scenario"; + String ALINT_LEAK_SCENARIO = "alint_leak_scenario"; + String ALINT_BUMP_SCENARIO = "alint_bump_scenario"; + String EXCLCC = "exclcc"; + String NOCC_NODES = "nocc_nodes"; + String RESET_NET = "reset_net"; + String STATICIZER_RATIO = "staticizer_ratio"; + String STATICIZER_TYPE = "staticizer_type"; + String PHANTOM_PORT_SIGNOFF = "phantom_port_signoff"; + String PORT_GROUP = "port_group"; + String GROUP_FREQUENCY = "group_frequency"; + String GROUP_CLOCK = "group_clock"; + String DEFAULT_INTEGER_WIDTH = "default_integer_width"; + String SYNTHESIZABLE = "synthesizable"; + String FLOORPLAN_ARRAY = "floorplan_array"; + String NAME_MAPPING = "name_mapping"; + String STRENGTH_GROUP = "strength_group"; + String IDLE_STATE = "idle_state"; + + /** CSP timing directives */ + String SLACK = "slack"; + String STAGES = "stages"; + String LATENCY = "latency"; + String LATENCY_PER_STAGE = "latency_per_stage"; + String SLACK_PER_STAGE = "slack_per_stage"; + String DEFAULT_CYCLE_TIME = "default_cycle_time"; + String FB = "fb"; + String FB_NEUTRAL = "fb_neutral"; + String FB_VALID = "fb_valid"; + String BF = "bf"; + String TIME_UNIT = "time_unit"; + String CYCLE_TIME_IN = "cycle_time_in"; + String CYCLE_TIME_OUT = "cycle_time_out"; + String STRICT_VARS = "strict_vars"; + String DISABLE_CHANDFT_HANDLER = "disable_chandft_handler"; + String WIRING = "wiring"; + String SUPPRESS_FAULTS = "suppress_faults"; + String DYNAMIC_SLACK = "dynamic_slack"; + String IMPLICIT_INIT = "implicit_init"; + + /** Scan related directives */ + String ASYNC_SCAN_INPUTS = "async_scan_inputs"; + String ASYNC_SCAN_OUTPUTS = "async_scan_outputs"; + String ASYNC_SCAN = "async_scan"; + String PROTEUS_SCAN_MODEL = "proteus_scan_model"; + String PROTEUS_SCAN_MACROS = "proteus_scan_macros"; + String PROTEUS_SCAN_DECLONE = "proteus_scan_declone"; + + /** Slacker directives */ + String SLACKER_LEAF = "slacker_leaf"; + String SLACKER_PRIMITIVE = "slacker_primitive"; + String SLACKER_IS_SLACK = "slacker_is_slack"; + String SLACKER_TIME = "slacker_time"; + String SLACKER_FREE_SLACK = "slacker_free_slack"; + String SLACKER_ELASTICITY = "slacker_elasticity"; + String SLACKER_HANDSHAKES = "slacker_handshakes"; + String SLACKER_INITIAL_TOKENS = "slacker_initial_tokens"; + String SLACKER_ALIGNMENT = "slacker_alignment"; + String SLACKER_IGNORE = "slacker_ignore"; + String SLACKER_NTPC = "slacker_ntpc"; + String SLACKER_DONT_TOUCH = "slacker_dont_touch"; + String SLACKER_TRANSITIONS = "slacker_transitions"; + String SLACKER_COST = "slacker_cost"; + + /** ASTA directives */ + String ASTA_BLACKBOX = "asta_blackbox"; + String ASTA_GRAYBOX = "asta_graybox"; + String ASTA_IGNORE = "asta_ignore"; + String SLINT_IGNORE = "slint_ignore"; + + /** VDCVerify directives */ + String VDC_LEAF = "vdc_leaf"; + String VDD_DEFAULT_DOMAIN = "vdd_default_domain"; + String VDD_DOMAIN = "vdd_domain"; + + /** Verilog block directives */ + String BOUNDS = "bounds"; + + /** Java block directives */ + String GROUP = "group"; + + /** Define data types here to enable external access */ + String INT_TYPE = "int"; + String FLOAT_TYPE = "float"; + String DOUBLE_TYPE = "double"; + String BOOLEAN_TYPE = "boolean"; + String STRING_TYPE = "string"; + String NODE_TYPE = "node"; + String HALFOP_TYPE = "halfop"; + String UNCHECKED_NODE_TYPE = "unchecked_node"; + String UNCHECKED_HALFOP_TYPE = "unchecked_halfop"; + String DEEP_NODE_TYPE = "deep_node"; + String DEEP_HALFOP_TYPE = "deep_halfop"; + String RULE_TYPE = "rule"; + String DEEP_RULE_TYPE = "deep_rule"; + String CHANNEL_TYPE = "channel"; + String WIDE_CHANNEL_TYPE = "wide_channel"; + String POSSIBLY_WIDE_CHANNEL_TYPE = "possibly_wide_channel"; + String INSTANCE_TYPE = "instance"; + String ARRAYED_INSTANCE_TYPE = "arrayed_instance"; + String LAYER_TYPE = "layer"; + String COSIM_SPEC_TYPE = "cosim_spec"; + String ALINT_SCENARIO_TYPE = "alint_scenario"; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterface.java new file mode 100644 index 0000000000..4b3eaa4448 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterface.java @@ -0,0 +1,97 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive; + +import java.util.Map; +import java.util.Iterator; + +import com.avlsi.cast2.directive.UnknownDirectiveException; + +/** + API between directives blocks and their consumers. + */ +public interface DirectiveInterface { + /** + Get the default value for a parameterized directive. + @param key Name of a directive + @param memberType Type of parameter + @return The default value for the specified directive, or + null if there is no default value. + @throws UnknownDirectiveException if the key is not a valid directive + */ + Object getDefaultValue(String key, String memberType) throws UnknownDirectiveException; + + /** + Get non default values specified for a parameterized directive. + @param key Name of a directive + @param memberType Type of parameter + @return A map, possibly empty, from String to + Value. The keys of the map are the parameters. + @throws UnknownDirectiveException if the key is not a valid directive + */ + Map getValues(String key, String memberType) throws UnknownDirectiveException; + + /** + Get the value for a non-parameterized directive. + @param key Name of a directive + @return Value for the specified directive. + @throws UnknownDirectiveException if the key is not a valid directive + */ + Object lookup(String key) throws UnknownDirectiveException; + + /** + Returns whether a non-parameterized directive has been assigned a value. + This information is not available from lookup, which always returns a + value, regardless if a directive is actually present. The only user of + this call should be MergeDirective, which is called on refinement. + @param key Name of a directive + @return True if a directive statement assigns a value to this directive; + false otherwise. + @throws UnknownDirectiveException if the key is not a valid directive + */ + boolean containsDirective(String key) throws UnknownDirectiveException; + + /** + Get the value for a parameterized directive. Returns the default value + if no value specified for the parameter. + @param key Name of a directive + @param memberType Type of the parameter + @param parameter The parameter as a String + @return Value for the specified parameterized directive. + @throws UnknownDirectiveException if the key is not a valid directive + */ + Object lookup(String key, String memberType, Object parameter) throws UnknownDirectiveException; + + /** + Returns whether the specified key is valid. + @param key Name of a directive + @return true if key is a valid directive, + false otherwise. + */ + boolean isKey(String key); + + /** + Returns whether the specified key/parameter type combination is valid. + @param key Name of a directive + @param memberType Type of the parameter + @return true if key/parameter type is a valid directive, + false otherwise. + */ + boolean isKey(String key, String memberType); + + /** + Returns an Iterator over entries of parametrized directives. + The values in the entries are maps from parameter strings to values + */ + Iterator paramEntryIterator(); + + /** + Returns an Iterator over entries of nonParametrized directives. + */ + Iterator noparamEntryIterator(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterfaceFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterfaceFactory.java new file mode 100644 index 0000000000..b7c442b7b6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/DirectiveInterfaceFactory.java @@ -0,0 +1,5 @@ +package com.avlsi.cast2.directive; + +public interface DirectiveInterfaceFactory { + DirectiveInterface getDirectiveInterface(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/UnknownDirectiveException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/UnknownDirectiveException.java new file mode 100644 index 0000000000..ec03b554ab --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/UnknownDirectiveException.java @@ -0,0 +1,18 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive; + +public class UnknownDirectiveException extends Exception { + public UnknownDirectiveException() { + super(); + } + + public UnknownDirectiveException(String s) { + super(s); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/CastEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/CastEmitter.java new file mode 100644 index 0000000000..7e8a154073 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/CastEmitter.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.Pair; + +/** + * API used to convert a value type to a string representation. + **/ +public class CastEmitter implements DirectiveEmitter { + private static CastEmitter singleton = null; + + private CastEmitter() { + } + + public String emit(final String block, final String type, + final Object value) { + if (type.equals(DirectiveConstants.INT_TYPE) || + type.equals(DirectiveConstants.FLOAT_TYPE) || + type.equals(DirectiveConstants.DOUBLE_TYPE) || + type.equals(DirectiveConstants.BOOLEAN_TYPE) || + type.equals(DirectiveConstants.WIDE_CHANNEL_TYPE) || + type.equals(DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE)) { + return value.toString(); + } else if (type.equals(DirectiveConstants.STRING_TYPE)) { + // XXX: escape single quotes inside the string? + return "'" + (String) value + "'"; + } else if (type.equals(DirectiveConstants.NODE_TYPE) || + type.equals(DirectiveConstants.CHANNEL_TYPE) || + type.equals(DirectiveConstants.INSTANCE_TYPE)) { + return ((HierName) value).getCadenceString(); + } else if (type.equals(DirectiveConstants.HALFOP_TYPE)) { + final Pair p = (Pair) value; + final String node = ((HierName) p.getFirst()).getCadenceString(); + final Boolean up = (Boolean) p.getSecond(); + if (up == null) { + return node; + } else { + return node + (up.booleanValue() ? "+" : "-"); + } + } else if (type.equals(DirectiveConstants.LAYER_TYPE)) { + final Pair p = (Pair) value; + return "( '" + p.getFirst() + "' '" + p.getSecond() + "' )"; + } else { + throw new RuntimeException("Do not know how to handle type: " + type); + } + } + + public static CastEmitter getInstance() { + if (singleton == null) singleton = new CastEmitter(); + return singleton; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DefaultCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DefaultCallback.java new file mode 100644 index 0000000000..9f940e0841 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DefaultCallback.java @@ -0,0 +1,195 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import java.math.BigDecimal; +import java.io.StringReader; +import java.util.Iterator; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.cast.impl.AmbiguousLookupException; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentEntry; +import com.avlsi.cast.impl.EnvironmentEntryIterator; +import com.avlsi.cast.impl.BoolValue; +import com.avlsi.cast.impl.IntValue; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.NodeValue; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.cast2.impl.CastTwoParser; +import com.avlsi.cast2.impl.CastTwoTreeParser; +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringExpressionFactory; +import com.avlsi.fast.shapes.stringexpression.impl.StringExpressionFactoryImpl; +import com.avlsi.fast.shapes.stringexpression.impl.parser.StringExpressionLexer; +import com.avlsi.fast.shapes.stringexpression.impl.parser.StringExpressionParser; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariable; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionaryIterator; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.mathexpression.NotAConstantValueException; + +class DefaultCallback implements DirectiveCallback { + private Object resolveCastExpr(String type, String value, Environment env) { + try { + final CastTwoParser castParser = + CastTwoParser.getParser(value, 0, 0, ""); + castParser.startExpression(); + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + final Value v = treeParser.expression(castParser.getAST(), env, false); + if (type.equals(DirectiveConstants.INT_TYPE)) { + return new Integer(IntValue.valueOf(v).getValue().intValue()); + } else if (type.equals(DirectiveConstants.FLOAT_TYPE)) { + return new Float(FloatValue.valueOf(v).getValue()); + } else if (type.equals(DirectiveConstants.DOUBLE_TYPE)) { + return new Double(FloatValue.valueOf(v).getValue()); + } else if (type.equals(DirectiveConstants.BOOLEAN_TYPE)) { + if (BoolValue.valueOf(v).getValue()) return Boolean.TRUE; + else return Boolean.FALSE; + } else { + return null; + } + } catch (Exception e) { + return null; + } + } + + private static class EnvironmentDictionary + implements StringVariableDictionary { + private final Environment env; + private final StringExpressionFactory factory; + public EnvironmentDictionary(final Environment env, + final StringExpressionFactory factory) { + this.env = env; + this.factory = factory; + } + + private String getString(final Value v) { + String s = null; + try { + if (v instanceof IntValue) { + s = ((IntValue) v).getValue().toString(); + } else if (v instanceof BoolValue) { + s = Boolean.toString(((BoolValue) v).getValue()); + } else if (v instanceof FloatValue) { + s = Double.toString(((FloatValue) v).getValue()); + } else if (v instanceof NodeValue) { + s = ((NodeValue) v).getInstanceName().toString(); + } + } catch (InvalidOperationException e) { } + return s; + } + + public StringExpression getVariableValue(final String VariableName) { + String s = null; + try { + final Value v = env.lookup(Symbol.create(VariableName)); + s = getString(v); + } catch (AmbiguousLookupException e) { } + + return s == null ? null : factory.makeConstant(s); + } + + public StringVariableDictionaryIterator getIterator() { + final EnvironmentEntryIterator envIter = env.entryIterator(); + final Iterator entries = new Iterator() { + public boolean hasNext() { + return envIter.hasNext(); + } + public Object next() { + return envIter.next(); + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + + final UnaryPredicate pred = new UnaryPredicate() { + public boolean evaluate(Object o) { + final EnvironmentEntry entry = (EnvironmentEntry) o; + return getString(entry.getValue()) != null; + } + }; + + final Iterator filtered = new FilteringIterator(entries, pred); + + return new StringVariableDictionaryIterator() { + public boolean hasNext() { + return filtered.hasNext(); + } + public StringVariable next() { + final EnvironmentEntry entry = + (EnvironmentEntry) filtered.next(); + return new StringVariable() { + public String getName() { + return entry.getName().getString(); + } + public StringExpression getValue() { + final String s = getString(entry.getValue()); + return factory.makeConstant(s); + } + }; + } + }; + } + } + + private Object resolveStringExpression(String value, Environment env) { + /* If the value does not contain "'", then trim it, and return the + * result. */ + if (value.indexOf('\'') == -1) { + return value.trim(); + } + + StringExpressionLexer lexer = + new StringExpressionLexer(new StringReader(value), true); + StringExpressionFactory factory = new StringExpressionFactoryImpl(); + StringExpressionParser parser = new StringExpressionParser(lexer, factory); + StringExpression result; + + try { + result = parser.goal(); + } catch (RecognitionException e) { + return null; + } catch (TokenStreamException e) { + return null; + } + + result = result.evaluate(new EnvironmentDictionary(env, factory)); + + String str; + try { + str = result.getConstantValue(); + } catch (NotAConstantValueException e) { + return null; + } + + return str; + } + + public Object resolve(String type, String value, Environment env) { + Object ret = null; + value = value.trim(); + if (type.equals(DirectiveConstants.INT_TYPE) || + type.equals(DirectiveConstants.FLOAT_TYPE) || + type.equals(DirectiveConstants.DOUBLE_TYPE) || + type.equals(DirectiveConstants.BOOLEAN_TYPE)) { + ret = resolveCastExpr(type, value, env); + } else if (type.equals(DirectiveConstants.STRING_TYPE)) { + ret = resolveStringExpression(value, env); + } + return ret; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveCallback.java new file mode 100644 index 0000000000..ae3182c4ba --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveCallback.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast.impl.Environment; + +/** + * API used by the directives factory to resolve parameters in a block specific + * way. + **/ +public interface DirectiveCallback { + /** + * Resolves a block specific parameter given the specified environment. + * @param type type of the parameter + * @param value value of the parameter + * @param env Environment containing any loop variables + * @return If the parameter is of the correct type, whatever is necessary + * to the consumer of directives should be returned, otherwise + * null. + **/ + Object resolve(String type, String value, Environment env); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveComparator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveComparator.java new file mode 100644 index 0000000000..364b58e5db --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveComparator.java @@ -0,0 +1,23 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +/** + * API used to compare 2 values. + **/ +public interface DirectiveComparator { + /** + * Compare 2 block specific parameters. + * @param block block where the parameter is located + * @param type type of the parameter + * @param value1 first value of the parameter + * @param value2 second value of the parameter + * @return true if the values are equivalent; false otherwise. + **/ + boolean compare(String block, String type, Object value1, Object value2); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveConditional.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveConditional.java new file mode 100644 index 0000000000..ce04f4e969 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveConditional.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast2.directive.impl.DirectiveStatement; +import com.avlsi.cast2.directive.impl.DirectiveVisitor; +import com.avlsi.cast2.directive.impl.TokenInfo; + +public class DirectiveConditional implements DirectiveStatement { + private final String guard; + private final DirectiveStatement[] body; + private final TokenInfo info; + + public DirectiveConditional(final String guard, + final DirectiveStatement[] body, + final TokenInfo info) { + this.guard = guard; + this.body = body; + this.info = info; + } + + public void visit(final DirectiveVisitor v) { + v.conditional(guard, body, info); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDefinition.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDefinition.java new file mode 100644 index 0000000000..a58138605d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDefinition.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.directive.impl.DirectiveStatement; +import com.avlsi.cast2.directive.impl.DirectiveVisitor; +import com.avlsi.cast2.directive.impl.TokenInfo; + +public class DirectiveDefinition implements DirectiveStatement { + private final String key, parameter, val; + private final TokenInfo info; + + public DirectiveDefinition(String key, String val, TokenInfo info) { + this(key, null, val, info); + } + + public DirectiveDefinition(String key, String parameter, String val, + TokenInfo info) { + this.key = key; + this.parameter = parameter; + this.val = val; + this.info = info; + } + + public void visit(final DirectiveVisitor v) { + if (parameter == null) { + v.definition(key, val, info); + } else { + v.definition(key, parameter, val, info); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDifference.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDifference.java new file mode 100644 index 0000000000..6d8a20754f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveDifference.java @@ -0,0 +1,92 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.cast2.directive.impl; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.DirectiveInterfaceFactory; +import com.avlsi.cast2.directive.impl.DirectiveImpl; +import com.avlsi.cast2.util.DirectiveActionInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.util.container.Pair; + +// Take advantage of the inability to remove directives. +public class DirectiveDifference implements DirectiveActionInterface, + DirectiveInterfaceFactory { + private final String block; + private final Map paramDefinition, nonparamDefinition; + private boolean add = true; + + public DirectiveDifference(final String block) { + this.block = block; + this.paramDefinition = new LinkedHashMap(); + this.nonparamDefinition = new LinkedHashMap(); + } + + public void setMode(final boolean add) { + this.add = add; + } + + public void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType) + throws IOException { + if (add) { + nonparamDefinition.put(directive, value); + } else { + final Object old = nonparamDefinition.get(directive); + if (old.equals(value)) { + nonparamDefinition.remove(directive); + } + } + } + + public void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) + throws IOException { + final Pair key = new Pair(directive, parameterType); + Map m = (Map) paramDefinition.get(key); + if (add) { + if (m == null) { + m = new LinkedHashMap(); + paramDefinition.put(key, m); + } + m.put(parameter, value); + } else { + final Object old = m.get(parameter); + if (old.equals(value)) { + m.remove(parameter); + } + } + } + + public void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) + throws IOException { } + + public void doBlockInterface(BlockInterface block) + throws IOException { } + + public DirectiveInterface getDirectiveInterface() { + return new DirectiveImpl.Impl(block, paramDefinition, + nonparamDefinition); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveEmitter.java new file mode 100644 index 0000000000..19d7cf5347 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveEmitter.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +/** + * API used to convert a value type to a string representation. + **/ +public interface DirectiveEmitter { + /** + * Converts a block specific parameter to a string. + * @param block block where the parameter is located + * @param type type of the parameter + * @param value value of the parameter + * @return The string representation of value. + **/ + String emit(String block, String type, Object value); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactory.java new file mode 100644 index 0000000000..73d1bbc2cc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.util.container.Pair; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.cast2.directive.impl.DirectiveStatement; +import com.avlsi.cast2.directive.impl.TokenInfo; + +/** + Used by the parser to create directives. + */ +public class DirectiveFactory implements DirectiveFactoryInterface { + public DirectiveStatement makeConditional(String guard, + final DirectiveStatement[] body, + TokenInfo info) { + return new DirectiveConditional(guard, body, info); + } + public DirectiveStatement makeLoop(String var, String to, String from, + final DirectiveStatement[] body, + TokenInfo info) { + return new DirectiveLoop(var, to, from, body, info); + } + + public DirectiveStatement makeDefinition(String key, String val, + TokenInfo info) { + return new DirectiveDefinition(key, val, info); + } + + public DirectiveStatement makeDefinition(String key, String parameter, + String val, TokenInfo info) { + return new DirectiveDefinition(key, parameter, val, info); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactoryInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactoryInterface.java new file mode 100644 index 0000000000..7c0f8759cd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveFactoryInterface.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.cast2.directive.impl.DirectiveStatement; +import com.avlsi.cast2.directive.impl.TokenInfo; + +/** + * Used by the parser to create directives. + **/ +public interface DirectiveFactoryInterface { + /** + * Return a DirectiveStatement that represents an if-statement. + **/ + DirectiveStatement makeConditional(String guard, + final DirectiveStatement[] body, + TokenInfo info); + + /** + * Return a DirectiveStatement that represents a loop. + **/ + DirectiveStatement makeLoop(String var, String from, String to, + final DirectiveStatement[] body, + TokenInfo info); + + /** + * Return a DirectiveStatement that assigns a value to a parameterized + * directive. + **/ + DirectiveStatement makeDefinition(String key, String parameter, String val, + TokenInfo info); + + /** + * Return a DirectiveStatement that assigns a value to a directive. + **/ + DirectiveStatement makeDefinition(String key, String val, TokenInfo info); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveImpl.java new file mode 100644 index 0000000000..e2c554062d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveImpl.java @@ -0,0 +1,319 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.HashSet; +import java.util.Set; +import java.util.Iterator; +import java.util.StringTokenizer; + +import com.avlsi.cast.impl.IntValue; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.LoopEnvironment; +import com.avlsi.cast.impl.Range; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cast2.directive.impl.DirectiveVisitor; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.directive.impl.TokenInfo; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; + +public class DirectiveImpl implements DirectiveVisitor { + public interface ErrorHandler { + void error(String message); + } + + private ErrorHandler handler; + private String block; + private Environment current; + private Map paramDefinition, noparamDefinition; + + public DirectiveImpl(String block, Environment base) { + this(block, base, null); + } + + public DirectiveImpl(String block, Environment base, ErrorHandler handler) { + this.block = block; + this.handler = handler; + paramDefinition = new HashMap(); + noparamDefinition = new HashMap(); + current = base; + } + + private void error(final String s) { + if (handler == null) { + System.err.println("SYNTAX: " + s); + } else { + handler.error(s); + } + } + + /** only report unknown directives once per cell */ + private Set unknown = new HashSet(); + private void unknownDirective(final String key, final TokenInfo info) { + if (unknown.add(key)) { + error("Unknown directive " + key + " [" + info + "]!"); + } + } + + public void conditional(String guard, DirectiveStatement[] body, + TokenInfo info) { + final DirectiveCallback cb = DirectiveTable.lookupCallback(block, DirectiveConstants.BOOLEAN_TYPE); + if (cb == null) { + error("Cannot resolve if guard [" + info + "]!"); + return; + } + + final Boolean resolved = (Boolean) cb.resolve(DirectiveConstants.BOOLEAN_TYPE, guard, current); + if (resolved == null) { + error("Cannot resolve if guard [" + info + "]!"); + return; + } + + if (resolved.booleanValue()) { + for (int i = 0; i < body.length; ++i) { + body[i].visit(this); + } + } + } + + public void loop(String var, String from, String to, + DirectiveStatement[] body, TokenInfo info) { + var = var.trim(); + + DirectiveCallback cb = + DirectiveTable.lookupCallback(block, DirectiveConstants.INT_TYPE); + if (cb == null) { + error("Cannot resolve loop bounds [" + info + "]!"); + return; + } + + Integer resolvedFrom = + (Integer) cb.resolve(DirectiveConstants.INT_TYPE, from, current); + if (resolvedFrom == null) { + error("Cannot resolve loop bounds [" + info + "]!"); + return; + } + + Integer resolvedTo; + if (to == null) { + resolvedTo = new Integer(resolvedFrom.intValue() - 1); + resolvedFrom = new Integer(0); + } else { + resolvedTo = + (Integer) cb.resolve(DirectiveConstants.INT_TYPE, to, current); + if (resolvedTo == null) { + error("Cannot resolve loop bounds [" + info + "]!"); + return; + } + } + + Range r = new Range(resolvedFrom.intValue(), resolvedTo.intValue()); + Symbol sym = Symbol.create(var); + for (Range.Iterator ri = r.iterator(); ri.hasNext(); ) { + final int i = ri.next(); + Environment old = current; + current = new LoopEnvironment(old, sym, IntValue.valueOf(i)); + for (int l = 0; l < body.length; l++) { + body[l].visit(this); + } + current = old; + } + } + + private Object resolve(String type, String str) { + if (DirectiveTable.isArray(type)) { + return resolve(DirectiveTable.deArray(type), parseArray(str)); + } else { + DirectiveCallback cb = DirectiveTable.lookupCallback(block, type); + if (cb == null) return null; + return cb.resolve(type, str, current); + } + } + + private Object resolve(String type, String[] str) { + if (str == null) return null; + ArrayList result = new ArrayList(str.length); + for (int i = 0; i < str.length; i++) { + final Object obj = resolve(type, str[i]); + if (obj == null) return null; + result.add(obj); + } + return Collections.unmodifiableList(result); + } + + private String[] parseArray(String s) { + s = s.trim(); + if (!s.startsWith("{") || !s.endsWith("}")) return null; + s = s.substring(s.indexOf('{') + 1, s.lastIndexOf('}')); + final ArrayList list = new ArrayList(); + StringBuffer buf = new StringBuffer(); + int parens = 0; + boolean inString = false; + for (int i = 0; i < s.length(); ++i) { + final char c = s.charAt(i); + if (c == '[' || c == '(' || c == '{') { + ++parens; + } else if (c == ']' || c == ')' || c == '}') { + --parens; + } else if (c == '"') { + inString = !inString; + } + if (c == ',' && parens == 0 && !inString) { + list.add(buf.toString()); + buf = new StringBuffer(); + } else { + buf.append(c); + } + } + if (buf.length() > 0) { + list.add(buf.toString()); + } + if (list.size() == 0) return null; + else return (String[]) list.toArray(new String[0]); + } + + public void definition(String key, String val, TokenInfo info) { + Pair p = DirectiveTable.lookupDirective(block, key); + if (p == null) { + unknownDirective(key,info); + return; + } + String valueType = (String) p.getFirst(); + + final Object value = resolve(valueType, val); + + if (value == null) { + error("Expecting type " + valueType + ", found " + val + " [" + + info + "]!"); + return; + } + noparamDefinition.put(key, value); + } + + public void definition(String key, String parameter, String val, + TokenInfo info) { + Triplet[] candidates = DirectiveTable.lookupParameterizedDirective(block, key); + if (candidates == null) { + unknownDirective(key,info); + return; + } + for (int i = 0; i < candidates.length; i++) { + String memberType = (String) candidates[i].getFirst(); + final Object param = resolve(memberType, parameter); + if (param == null) { + error("Expecting type " + memberType + ", found " + parameter + + " [" + info + "]!"); + return; + } + + String valueType = (String) candidates[i].getSecond(); + + final Object value = resolve(valueType, val); + + if (value == null) { + error("Expecting type " + valueType + ", found " + val + " [" + + info + "]!"); + return; + } + + Map m = (Map) paramDefinition.get(new Pair(key, memberType)); + if (m == null) { + m = new HashMap(); + paramDefinition.put(new Pair(key, memberType), m); + } + m.put(param, value); + } + } + + public DirectiveInterface getDirectiveInterface() { + return new Impl(block, paramDefinition, noparamDefinition); + } + + static class Impl implements DirectiveInterface { + private final String block; + private final Map paramDefinition, noparamDefinition; + public Impl(final String block, final Map paramDefinition, + final Map noparamDefinition) { + this.block = block; + this.paramDefinition = paramDefinition; + this.noparamDefinition = noparamDefinition; + } + + private Triplet findMemberType(String key, String memberType) + throws UnknownDirectiveException { + Triplet[] candidates = DirectiveTable.lookupParameterizedDirective(block, key); + if (candidates == null) throw new UnknownDirectiveException(key); + for (int i = 0; i < candidates.length; i++) { + String mType = (String) candidates[i].getFirst(); + if (memberType.equals(mType)) + return candidates[i]; + } + throw new UnknownDirectiveException(key + ":" + memberType); + } + + public Object getDefaultValue(String key, String memberType) + throws UnknownDirectiveException { + Triplet info = findMemberType(key, memberType); + return info.getThird(); + } + + public Map getValues(String key, String memberType) + throws UnknownDirectiveException { + final Triplet info = findMemberType(key, memberType); + final Map result = (Map) paramDefinition.get(new Pair(key, memberType)); + return result == null ? Collections.EMPTY_MAP : result; + } + + public Object lookup(String key) throws UnknownDirectiveException { + if (noparamDefinition.containsKey(key)) { + return noparamDefinition.get(key); + } else { + Pair p = DirectiveTable.lookupDirective(block, key); + if (p == null) throw new UnknownDirectiveException(key); + return p.getSecond(); + } + } + + public boolean containsDirective(String key) throws UnknownDirectiveException { + return noparamDefinition.containsKey(key); + } + + public Object lookup(String key, String memberType, Object parameter) throws UnknownDirectiveException { + Triplet info = findMemberType(key, memberType); + Map map = (Map) paramDefinition.get(new Pair(key, memberType)); + if (map == null) return info.getThird(); + Object ret = map.get(parameter); + if (ret == null) return info.getThird(); + else return ret; + } + + public boolean isKey(String key) { + return DirectiveTable.lookupDirective(block, key) != null; + } + + public boolean isKey(String key, String memberType) { + return DirectiveTable.lookupParameterizedDirective(block, key) != null; + } + + public Iterator noparamEntryIterator() { + return noparamDefinition.entrySet().iterator(); + } + + public Iterator paramEntryIterator() { + return paramDefinition.entrySet().iterator(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveLoop.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveLoop.java new file mode 100644 index 0000000000..e398a9b0dc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveLoop.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast2.directive.impl.DirectiveStatement; +import com.avlsi.cast2.directive.impl.DirectiveVisitor; +import com.avlsi.cast2.directive.impl.TokenInfo; + +public class DirectiveLoop implements DirectiveStatement { + private final String var, from, to; + private final DirectiveStatement[] body; + private final TokenInfo info; + + public DirectiveLoop(String var, String from, String to, + final DirectiveStatement[] body, + final TokenInfo info) { + this.var = var; + this.from = from; + this.to = to; + this.body = body; + this.info = info; + } + + public void visit(final DirectiveVisitor v) { + v.loop(var, from, to, body, info); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveParser.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveParser.java new file mode 100644 index 0000000000..db4e63b50c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveParser.java @@ -0,0 +1,420 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.Stack; + +import com.avlsi.cast2.directive.impl.DirectiveFactoryInterface; +import com.avlsi.cast2.directive.impl.DirectiveStatement; +import com.avlsi.cast2.directive.impl.DirectiveSyntaxException; +import com.avlsi.cast2.directive.impl.TokenInfo; +import com.avlsi.io.PositionStackReader; + +public class DirectiveParser { + private final PositionStackReader reader; + private final DirectiveFactoryInterface factory; + private static final HashSet valueSet = new HashSet(); + private static final HashSet identSet = new HashSet(); + private int lineNum, colNum; + private final String file; + private final Stack lineStack; + + static { + valueSet.add(new Character(';')); + identSet.add(new Character(':')); + } + + public DirectiveParser(Reader in, DirectiveFactoryInterface factory, + int lineNum, int colNum, String file) { + this.reader = new PositionStackReader(in); + this.factory = factory; + this.lineNum = lineNum; + this.colNum = colNum; + this.file = file; + this.lineStack = new Stack(); + } + + private int read() throws IOException { + int c = reader.read(); + colNum++; + if (c == '\n') { + lineNum++; + colNum = 0; + } + return c; + } + + private void save() throws IOException { + reader.savePosition(); + lineStack.push(new int[] { lineNum, colNum }); + } + + private void restore() throws IOException { + reader.restorePosition(); + int[] saved = (int[]) lineStack.pop(); + lineNum = saved[0]; + colNum = saved[1]; + } + + private void discard() throws IOException { + reader.discardPosition(); + lineStack.pop(); + } + + private boolean skipCPPComment() throws IOException { + boolean status = false; + save(); + int c = read(); + if (c != '/') { restore(); return status; } + c = read(); + if (c != '/') { restore(); return status; } + discard(); save(); + c = read(); + while (c != -1 && c != '\n') { + status = true; + discard(); + save(); + c = read(); + } + restore(); + return status; + } + + private boolean skipCComment() throws IOException { + boolean status = false; + boolean nostar = true; + save(); + int c = read(); + if (c != '/') { restore(); return status; } + c = read(); + if (c != '*') { restore(); return status; } + discard(); save(); + c = read(); + while (c != -1 && (nostar || c != '/')) { + status = true; + discard(); + save(); + nostar = c != '*'; + c = read(); + } + if (c == '/') discard(); + else restore(); + return status; + } + + private boolean skipRealWS() throws IOException { + boolean status = false; + save(); + int c = read(); + while (c != -1 && Character.isWhitespace((char) c)) { + status = true; + discard(); + save(); + c = read(); + } + restore(); + return status; + } + + private void skipWS() throws IOException { + while (skipCComment() || skipCPPComment() || skipRealWS()); + } + + private String lexKey() throws IOException { + StringBuffer buf = new StringBuffer(); + save(); + char c = (char) read(); + if (Character.isLetter(c) || c == '_') { + discard(); + buf.append(c); + } else { + restore(); + return null; + } + + save(); + c = (char) read(); + while (Character.isLetter(c) || Character.isDigit(c) || c == '_') { + discard(); + buf.append(c); + save(); + c = (char) read(); + } + + if (c == '+' || c == '-') { + buf.append(c); + discard(); + } else { + restore(); + } + +//System.err.println("key = " + buf); + return buf.toString(); + } + + private String lexUntil(Set until) throws IOException { + StringBuffer buf = new StringBuffer(); + int c; + save(); + c = read(); + while (c != -1 && !until.contains(new Character((char) c))) { + buf.append((char) c); + discard(); + save(); + c = read(); + } + if (c == -1) { + discard(); + } else { + restore(); + } +//System.err.println("lexUntil = " + buf); + return buf.toString(); + } + + private String lexUntil(final String str) throws IOException { + StringBuffer buf = new StringBuffer(); + StringBuffer sstr = new StringBuffer(); + int c; + c = read(); + while (c != -1 && !str.equals(sstr.toString())) { + buf.append((char) c); + if (sstr.length() == str.length()) { + sstr.deleteCharAt(0); + } + sstr.append((char) c); + c = read(); + } +//System.err.println("lexUntil = " + buf); + return buf.toString(); + } + + private String lexParameter() throws IOException { + StringBuffer buf = new StringBuffer(); + int c, count = 0; + save(); + c = read(); + while (c != -1 && (count != 0 || c != ')')) { + if (c == '(') count++; + else if (c == ')') { + count--; + if (count < 0) System.err.println("Unmatched parenthesis"); + } + buf.append((char) c); + discard(); + save(); + c = read(); + } + if (c == -1) { + discard(); + System.err.println("Premature EOF while reading parameter"); + } else { + restore(); + } +//System.err.println("parameter = " + buf); + return buf.toString(); + } + + private String lexIdent() throws IOException { + String ident = lexUntil(identSet); + return ident; + } + + private String lexValue() throws IOException { + String value = lexUntil(valueSet); + return value; + } + + public DirectiveStatement parseDirective() throws IOException { + skipWS(); + final int current = lineNum; + String key = lexKey(); + if (key == null) return null; + skipWS(); + save(); + char c = (char) read(); + String param = null, value = null; + if (c == '(') { + param = lexParameter(); + c = (char) read(); + if (c != ')') { + restore(); + return null; + } + skipWS(); + c = (char) read(); + } + if (c != '=') { + restore(); + return null; + } + value = lexValue(); + if (value == null) return null; + + c = (char) read(); + if (c != ';') { + restore(); + return null; + } + + // XXX: In the future, need to handle an array of values + if (param == null) { + return factory.makeDefinition(key, value, + new TokenInfo(current, file)); + } else { + return factory.makeDefinition(key, param, value, + new TokenInfo(current, file)); + } + } + + public void parseRange(String[] range) throws IOException { + skipWS(); + String fromto = lexUntil(identSet); + final int index = fromto.indexOf(".."); + if (index < 0) { + range[0] = fromto; + range[1] = null; + } else { + range[0] = fromto.substring(0, index); + range[1] = fromto.substring(index + 2); + } + } + + public DirectiveStatement parseConditional() + throws IOException, DirectiveSyntaxException { + save(); + char c = (char) read(); + final int current = lineNum; + if (c != '[') { + restore(); + return null; + } + + String guard = lexUntil("->"); + if (guard.endsWith("->")) { + guard = guard.substring(0, guard.length() - 2); + } else { + restore(); + return null; + } + + DirectiveStatement[] body = parseStatements(true); + + c = (char) read(); + if (c != ']') { + restore(); + return null; + } +//System.err.println("loop " + ident + " " + range[0] + " " + range[1]); + discard(); + return factory.makeConditional(guard, body, new TokenInfo(current, file)); + } + + public DirectiveStatement parseLoop() throws IOException, + DirectiveSyntaxException { + save(); + char c = (char) read(); + final int current = lineNum; + if (c != '<') { + restore(); + return null; + } + + String ident = lexIdent(); + + if (ident == null) { + restore(); + return null; + } + + c = (char) read(); + if (c != ':') { + restore(); + return null; + } + + String[] range = new String[2]; + parseRange(range); + + c = (char) read(); + if (c != ':') { + restore(); + return null; + } + + DirectiveStatement[] body = parseStatements(true); + + c = (char) read(); + if (c != '>') { + restore(); + return null; + } +//System.err.println("loop " + ident + " " + range[0] + " " + range[1]); + discard(); + return factory.makeLoop(ident, range[0], range[1], body, + new TokenInfo(current, file)); + } + + public DirectiveStatement parseStatement(boolean failOkay) + throws IOException, DirectiveSyntaxException { + save(); + int c = read(); + final int curLine = lineNum; + final int curCol = colNum; + restore(); + DirectiveStatement stmnt; + if (c == '<') { + stmnt = parseLoop(); + if (stmnt == null) + throw new DirectiveSyntaxException( + "Malformed directive loop statement", file, curLine, curCol); + } else if (c == '[') { + stmnt = parseConditional(); + if (stmnt == null) + throw new DirectiveSyntaxException( + "Malformed directive if statement", file, curLine, curCol); + } else { + stmnt = parseDirective(); + if (stmnt == null && !failOkay) + throw new DirectiveSyntaxException( + "Malformed directive statement", file, curLine, curCol); + } + return stmnt; + } + + public DirectiveStatement[] parseStatements() throws IOException, + DirectiveSyntaxException { + return parseStatements(false); + } + + public DirectiveStatement[] parseStatements(boolean failOkay) + throws IOException, DirectiveSyntaxException { + ArrayList body = new ArrayList(); + int count = 0; + skipWS(); + save(); + int c = read(); + while (c != -1) { +//System.err.println("count = " + count); + restore(); + DirectiveStatement line = parseStatement(failOkay); + if (line == null) break; + else body.add(line); + skipWS(); + save(); + c = read(); + count++; + } + return (DirectiveStatement[]) body.toArray(new DirectiveStatement[0]); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSource.java new file mode 100644 index 0000000000..9805b7b3d9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSource.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.DirectiveInterfaceFactory; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cast2.directive.impl.DirectiveVisitor; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.directive.impl.TokenInfo; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; + +public class DirectiveSource implements DirectiveInterfaceFactory { + private String block; + private Map paramDefinition, noparamDefinition; + + public DirectiveSource(String block) { + this.block = block; + paramDefinition = new HashMap(); + noparamDefinition = new HashMap(); + } + + public void definition(String key, Object val) { + noparamDefinition.put(key, val); + } + + public void definition(String key, String memberType, Object param, + Object value) { + Map m = (Map) paramDefinition.get(new Pair(key, memberType)); + if (m == null) { + m = new HashMap(); + paramDefinition.put(new Pair(key, memberType), m); + } + m.put(param, value); + } + + public DirectiveInterface getDirectiveInterface() { + return new DirectiveImpl.Impl(block, paramDefinition, noparamDefinition); + } + + public int hashCode() { + return paramDefinition.hashCode() + noparamDefinition.hashCode(); + } + + public boolean equal(final Object o) { + if (o instanceof DirectiveSource) { + final DirectiveSource s = (DirectiveSource) o; + return block.equals(s.block) && + paramDefinition.equals(s.paramDefinition) && + noparamDefinition.equals(s.noparamDefinition); + } else { + return false; + } + } + + public String toString() { + return "Non-parameterized: " + noparamDefinition.toString() + "\n" + "Parameterized: " + paramDefinition.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveStatement.java new file mode 100644 index 0000000000..f36a0ba580 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveStatement.java @@ -0,0 +1,14 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast2.directive.impl.DirectiveVisitor; + +public interface DirectiveStatement { + void visit(final DirectiveVisitor v); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSyntaxException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSyntaxException.java new file mode 100644 index 0000000000..870de5c4eb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveSyntaxException.java @@ -0,0 +1,17 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id: $ + * $DateTime: $ + * $Author: $ + */ + +package com.avlsi.cast2.directive.impl; + +import antlr.SemanticException; + +public class DirectiveSyntaxException extends SemanticException { + public DirectiveSyntaxException(String s, String fileName, int line, + int column) { + super(s, fileName, line, column); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveTable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveTable.java new file mode 100644 index 0000000000..b9d079bc02 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveTable.java @@ -0,0 +1,1471 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.file.common.HierName; +import com.avlsi.csp.util.CspCallback; +import com.avlsi.layout.InstanceCallback; +import com.avlsi.layout.LayerCallback; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.impl.PrsCallback; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DefaultCallback; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.tools.cosim.spec.CoSimSpecCallback; + +//imports specific for adding the different directives +import com.avlsi.fast.BlockInterface; + + +/** + * A class that acts as a central registry for valid Directives. + **/ +public class DirectiveTable { + protected static Map callback = new HashMap(); + protected static Map directive = new HashMap(); + protected static MultiMap paramDirective = new MultiMap(); + + static { + DirectiveCallback cb = new DefaultCallback(); + registerCallback(null, DirectiveConstants.INT_TYPE, cb); + registerCallback(null, DirectiveConstants.FLOAT_TYPE, cb); + registerCallback(null, DirectiveConstants.DOUBLE_TYPE, cb); + registerCallback(null, DirectiveConstants.BOOLEAN_TYPE, cb); + registerCallback(null, DirectiveConstants.STRING_TYPE, cb); + registerCallback(null, DirectiveConstants.NODE_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.HALFOP_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.UNCHECKED_NODE_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.UNCHECKED_HALFOP_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.DEEP_NODE_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.DEEP_HALFOP_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.RULE_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.DEEP_RULE_TYPE, PrsCallback.getInstance()); + registerCallback(null, DirectiveConstants.CHANNEL_TYPE, InstanceCallback.getInstance()); + registerCallback(null, DirectiveConstants.WIDE_CHANNEL_TYPE, CspCallback.getInstance()); + registerCallback(null, DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, CspCallback.getInstance()); + registerCallback(null, DirectiveConstants.INSTANCE_TYPE, InstanceCallback.getInstance()); + registerCallback(null, DirectiveConstants.ARRAYED_INSTANCE_TYPE, InstanceCallback.getInstance()); + registerCallback(null, DirectiveConstants.LAYER_TYPE, LayerCallback.getInstance()); + registerCallback(null, DirectiveConstants.COSIM_SPEC_TYPE, CoSimSpecCallback.getInstance()); + registerCallback(null, DirectiveConstants.ALINT_SCENARIO_TYPE, PrsCallback.getInstance()); + + /** + * Register RTE directives and set default values + */ + registerDirective(BlockInterface.ENV, DirectiveConstants.CYCLE_COUNT, + DirectiveConstants.INT_TYPE, null); + registerDirective(BlockInterface.ENV, + DirectiveConstants.RESET_CYCLE_COUNT, + DirectiveConstants.INT_TYPE, null); + + registerDirective(BlockInterface.ENV, DirectiveConstants.CYCLE_NODE, + DirectiveConstants.NODE_TYPE, null); + + registerDirective(BlockInterface.ENV, DirectiveConstants.CYCLE_TIME, + DirectiveConstants.INT_TYPE, null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.RTE_COSIM_SPEC, + DirectiveConstants.COSIM_SPEC_TYPE, + null); + + registerDirective(BlockInterface.ENV, + DirectiveConstants.RTE_COSIM_SPEC, + DirectiveConstants.COSIM_SPEC_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.RTE_ENV_COSIM_SPEC, + DirectiveConstants.COSIM_SPEC_TYPE, + null); + + registerDirective(BlockInterface.ENV, + DirectiveConstants.RTE_ENV_COSIM_SPEC, + DirectiveConstants.COSIM_SPEC_TYPE, + null); + + registerDirective(BlockInterface.ENV, DirectiveConstants.RTE_IGNORE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.ENV, DirectiveConstants.ASPICE_IGNORE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.ENV, DirectiveConstants.NTPC_SPEC, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASPICE_DIGITAL_CYCLES, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + null); + + registerDirective(BlockInterface.ENV, + DirectiveConstants.ASPICE_DIGITAL_CYCLES, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + null); + + registerDirective(BlockInterface.ENV, + DirectiveConstants.ASPICE_ANALOG_CYCLES, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASPICE_ANALOG_CYCLES, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.ENV, + DirectiveConstants.ASPICE_TIME_MAX, + DirectiveConstants.FLOAT_TYPE, + null); + + registerDirective(BlockInterface.CELL, DirectiveConstants.NTPC_SCALING, + DirectiveConstants.FLOAT_TYPE, new Float(1)); + + registerDirective(BlockInterface.ENV, DirectiveConstants.TIMED, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.ENV, DirectiveConstants.TIMED_JITTER, + DirectiveConstants.FLOAT_TYPE, null); + + registerDirective(BlockInterface.CELL, DirectiveConstants.TIMED, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.TIMED_JITTER, + DirectiveConstants.FLOAT_TYPE, null); + + registerDirective(BlockInterface.ENV, + DirectiveConstants.CSP_COSIM_WILL_FAIL, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + /** + * Register top-level directives used by rte and jauto + **/ + registerDirective(BlockInterface.CELL, DirectiveConstants.FRAGMENT, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.CELLNONOBSERVABLE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.FLOORPLAN, + DirectiveConstants.BOOLEAN_TYPE, Boolean.TRUE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.SYNCHRONOUS, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.UNIMPL, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.RTE_IGNORE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.ASPICE_IGNORE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.SIGNOFF, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + /* Arguably, this should be inside the netlist block, but it would make + * parsing more difficult. In any case, this directive is only + * effective when specified in a cell with a netlist block. */ + registerDirective(BlockInterface.CELL, DirectiveConstants.FIXED_SIZE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.TRUE); + registerDirective(BlockInterface.CELL, DirectiveConstants.CDLSCALE, + DirectiveConstants.FLOAT_TYPE, new Float(1.0)); + + registerDirective(BlockInterface.CELL, DirectiveConstants.WIRING, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + /** Jauto wiring directives **/ + registerDirective(BlockInterface.PRS, DirectiveConstants.MIN_WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.PRS, DirectiveConstants.MIN_WIRESPAN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.PRS, DirectiveConstants.WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.PRS, DirectiveConstants.WIRESPAN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.PRS, DirectiveConstants.WIREWIDTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.PRS, DirectiveConstants.WIRESPACE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.MIN_WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.MIN_WIRESPAN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.WIRESPAN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.WIREWIDTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.WIRESPACE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + + registerDirective(BlockInterface.CELL, DirectiveConstants.MIN_WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.MIN_WIRESPAN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIRESPAN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIRESPACE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0) ); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIREWIDTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + + registerDirective(BlockInterface.CELL, DirectiveConstants.MIN_WIRELENGTH, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.MIN_WIRESPAN, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIRELENGTH, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIRESPAN, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIREWIDTH, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIRESPACE, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + + /** other sizing/simulation directives **/ + registerDirective(BlockInterface.CELL, DirectiveConstants.HEIGHT, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.WIDTH, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.SPLITTABLE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + registerDirective(BlockInterface.CELL, DirectiveConstants.DELAYBIAS, + DirectiveConstants.FLOAT_TYPE, new Float(1.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.DEFAULT_UP_DELAY, + DirectiveConstants.FLOAT_TYPE, new Float(100)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.DEFAULT_DN_DELAY, + DirectiveConstants.FLOAT_TYPE, new Float(100)); + registerDirective(BlockInterface.CELL, DirectiveConstants.OWNER, + DirectiveConstants.STRING_TYPE, null); + registerDirective(BlockInterface.CELL, DirectiveConstants.PASSGATE, + DirectiveConstants.STRING_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, DirectiveConstants.STACK_GATE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.STATICIZER_GATE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, DirectiveConstants.TAU, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYOUT_ATTRIBUTES, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.EXTRA_LAYOUT_ATTRIBUTES, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.NETLIST_PRIMITIVE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.PRECHARGE_PRIMITIVE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.COVERAGE_IGNORE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.STATICIZER_RATIO, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.STATICIZER_RATIO, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.STATICIZER_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.STATICIZER_TYPE, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.STRENGTH_GROUP, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.INT_TYPE, + null); + + /* + * Register PRS synthesis directives; used by jauto "p2n", and PrsToNet + * "mgn", and lvs, "nvp". + */ + /* this next one should probably be a half operators. */ + registerDirective(BlockInterface.PRS, DirectiveConstants.NO_STAT, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.PRS, DirectiveConstants.DELAYBIAS, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(1.0)); + + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.DELAYBIAS, + DirectiveConstants.INSTANCE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(1.0)); + + registerDirective(BlockInterface.PRS, DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + + registerDirective(BlockInterface.PRS, + DirectiveConstants.ASTA_EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ASTA_EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + + registerDirective(BlockInterface.PRS, DirectiveConstants.SYMMETRIZE, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.INT_TYPE, + null); + + registerDirective(BlockInterface.PRS, DirectiveConstants.SHARED, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.INT_TYPE, + null); + + registerDirective(BlockInterface.PRS, DirectiveConstants.CUTPATH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.CUTPATH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.PRS, DirectiveConstants.LOADCAP, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.LOADCAP, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.RESISTANCE_SCALE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(1.0)); + registerDirective(BlockInterface.PRS, DirectiveConstants.MINDELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.PRS, DirectiveConstants.STRENGTHBIAS, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.PRS, DirectiveConstants.CAP, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); // power estimate in DSim, bug 2154 + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.CAP, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); // power estimate in DSim, bug 2154 + registerDirective(BlockInterface.PRS, + DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); // delay estimate in DSim, bug 2156 + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); // delay estimate in DSim, bug 2156 + registerDirective(BlockInterface.PRS, + DirectiveConstants.MEASURED_DELAY, + arrayify(DirectiveConstants.UNCHECKED_HALFOP_TYPE), + arrayify(arrayify(DirectiveConstants.FLOAT_TYPE)), + new Float(0.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.MEASURED_DELAY, + arrayify(DirectiveConstants.UNCHECKED_HALFOP_TYPE), + arrayify(arrayify(DirectiveConstants.FLOAT_TYPE)), + new Float(0.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.MEASURED_CHARGE, + arrayify(DirectiveConstants.UNCHECKED_HALFOP_TYPE), + arrayify(arrayify(DirectiveConstants.FLOAT_TYPE)), + new Float(0.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.MEASURED_CHARGE, + arrayify(DirectiveConstants.UNCHECKED_HALFOP_TYPE), + arrayify(arrayify(DirectiveConstants.FLOAT_TYPE)), + new Float(0.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ESTIMATED_CAP, + DirectiveConstants.UNCHECKED_NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ESTIMATED_CAP, + DirectiveConstants.UNCHECKED_NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.MEASURED_CAP, + DirectiveConstants.UNCHECKED_NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.MEASURED_CAP, + DirectiveConstants.UNCHECKED_NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, DirectiveConstants.DEFAULT_SLEW, + DirectiveConstants.FLOAT_TYPE, + new Float(30.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.PRS_NETLIST_MISMATCH_OK, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.PRS, + DirectiveConstants.PRS_NETLIST_MISMATCH_OK, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, DirectiveConstants.JAUTO_IGNORE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.SIGNOFF_CONSTANT, + DirectiveConstants.DEEP_NODE_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.SIGNOFF_CONSTANT, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.UNUSED_PRS, + DirectiveConstants.DEEP_RULE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.PRS, + DirectiveConstants.UNUSED_PRS, + DirectiveConstants.RULE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.EXTERNAL_WIRELENGTH, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.EXTERNAL_WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.EXTERNAL_LOADCAP, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.EXTERNAL_LOADCAP, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.EXTERNAL_DRIVER, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.EXTERNAL_DRIVER, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTERNAL_WIRELENGTH, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTERNAL_WIRELENGTH, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTERNAL_LOADCAP, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTERNAL_LOADCAP, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTERNAL_DRIVER, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTERNAL_DRIVER, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.NAME_MAPPING, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.VERILOG, + DirectiveConstants.NAME_MAPPING, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.IDLE_STATE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.IDLE_STATE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + null); + + /** + * Register Directives for Automated Layout. Used by autopins, autobus + **/ + + registerDirective(BlockInterface.CELL, DirectiveConstants.PINTYPE, + DirectiveConstants.STRING_TYPE, + DirectiveConstants.PINTYPE_PITCHED ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.CHANNEL_BUNCHED, + DirectiveConstants.CHANNEL_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CELL, DirectiveConstants.BITPITCH, + DirectiveConstants.FLOAT_TYPE, new Float(-1.0) ); + registerDirective(BlockInterface.CELL, DirectiveConstants.PINLAYER, + DirectiveConstants.LAYER_TYPE, null ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.POWERGRID_GNDNET, + DirectiveConstants.STRING_TYPE, null ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.POWERGRID_VDDNET, + DirectiveConstants.STRING_TYPE, null ); + + registerDirective(BlockInterface.PRS, DirectiveConstants.ANTENNA_DIODE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0) ); + registerDirective(BlockInterface.SUBCELL, DirectiveConstants.ANTENNA_DIODE, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0) ); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYER_WIREPITCH, + DirectiveConstants.LAYER_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0) ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYER_WIRESPACING, + DirectiveConstants.LAYER_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0) ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYER_WIREWIDTH, + DirectiveConstants.LAYER_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0) ); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYER_POWERGRID_OFFSET, + DirectiveConstants.LAYER_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(0) ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYER_POWERGRID_SPACING, + DirectiveConstants.LAYER_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(-1) ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYER_POWERGRID_WIREWIDTH, + DirectiveConstants.LAYER_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0) ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.LAYER_KEEPOUT_PATTERN, + DirectiveConstants.LAYER_TYPE, + DirectiveConstants.STRING_TYPE, + "0" ); + registerDirective(BlockInterface.CELL, + DirectiveConstants.AUTO_LAYOUT, + DirectiveConstants.INT_TYPE, + new Integer(0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.RESET_NET, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.RESET_NET, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.FLOORPLAN_ARRAY, + DirectiveConstants.ARRAYED_INSTANCE_TYPE, + DirectiveConstants.STRING_TYPE, + null); + + /** updatenetlist directives **/ + registerDirective(BlockInterface.CELL, + DirectiveConstants.BASE_TRANSISTOR_LAYOUT_WIDTH, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.DENSITY_FACTOR, + DirectiveConstants.FLOAT_TYPE, + new Float(1.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.DENSITY_SCALE_FACTOR, + DirectiveConstants.FLOAT_TYPE, + new Float(1.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.INLINE_LAYOUT, + DirectiveConstants.INSTANCE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.INLINE_LAYOUT, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.ROUTED, + DirectiveConstants.BOOLEAN_TYPE, + null); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ROUTED, + DirectiveConstants.INSTANCE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.TRUE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.BOUNDARY_POSITION, + arrayify(DirectiveConstants.FLOAT_TYPE), + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.WIDTH_MINIMUM, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.HEIGHT_MINIMUM, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.WIDTH_INCREMENT, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.HEIGHT_INCREMENT, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.WIDTH_OVERHEAD, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.HEIGHT_OVERHEAD, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.BOUNDARY_SMALL_CELL_WARNING_CUTOFF, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + + /** LVE Signoff Directives **/ + registerDirective(BlockInterface.PRS, + DirectiveConstants.ESTIMATED_DELAY_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ESTIMATED_DELAY_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.SLEW_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.SLEW_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.SKEW_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.SKEW_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.0)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.NTPC_SCALING_SIGNOFF, + DirectiveConstants.FLOAT_TYPE, new Float(1)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ALINT_SIGNOFF, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ALINT_SIGNOFF, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.PRS, + DirectiveConstants.STATICIZER_RATIO_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.FLOAT_TYPE), + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.BUMP_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.BUMP_SIGNOFF, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ALINT_MAX_BUMP_FANIN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(-1)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ALINT_MAX_BUMP_FANIN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(-1)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ALINT_DEFAULT_SCENARIOS, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + null); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ALINT_DEFAULT_SCENARIOS, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ALINT_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ALINT_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ALINT_DELAY_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ALINT_DELAY_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ALINT_LEAK_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ALINT_LEAK_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ALINT_BUMP_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ALINT_BUMP_SCENARIO, + DirectiveConstants.HALFOP_TYPE, + arrayify(DirectiveConstants.ALINT_SCENARIO_TYPE), + null); + registerDirective(BlockInterface.CELL,DirectiveConstants.ALINT_IGNORE, + DirectiveConstants.BOOLEAN_TYPE,Boolean.FALSE); + + registerDirective(BlockInterface.PRS, + DirectiveConstants.ACTIVITY_FACTOR, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ACTIVITY_FACTOR, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(-1.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.DC_WIRING_SPEC, + DirectiveConstants.NODE_TYPE, + arrayify(DirectiveConstants.FLOAT_TYPE), + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.DC_WIRING_SPEC, + DirectiveConstants.NODE_TYPE, + arrayify(DirectiveConstants.FLOAT_TYPE), + new Float(-1.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.AC_WIRING_SPEC, + DirectiveConstants.NODE_TYPE, + arrayify(DirectiveConstants.FLOAT_TYPE), + new Float(-1.0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.AC_WIRING_SPEC, + DirectiveConstants.NODE_TYPE, + arrayify(DirectiveConstants.FLOAT_TYPE), + new Float(-1.0)); + registerDirective(BlockInterface.PRS, + DirectiveConstants.LEAKY, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.LVS_NODES, + arrayify(DirectiveConstants.STRING_TYPE), null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.EFFECTIVE_RESISTANCE, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTRINSIC_DELAY, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.INTRINSIC_CAPACITANCE, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.HALFOP_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(1)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.FAST_TRANSISTOR_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(1)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLOW_TRANSISTOR_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(1)); + registerDirective(BlockInterface.CELL, + DirectiveConstants.TRANSISTOR_NAME, + DirectiveConstants.INT_TYPE, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.PLUS_NODE, + DirectiveConstants.NODE_TYPE, + HierName.makeHierName("Vdd")); + registerDirective(BlockInterface.CELL, + DirectiveConstants.MINUS_NODE, + DirectiveConstants.NODE_TYPE, + HierName.makeHierName("GND")); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.EXCLCC, + arrayify(DirectiveConstants.UNCHECKED_NODE_TYPE), + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.EXCLCC, + arrayify(DirectiveConstants.UNCHECKED_NODE_TYPE), + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.NOCC_NODES, + arrayify(DirectiveConstants.UNCHECKED_NODE_TYPE), + null); + registerDirective(BlockInterface.PRS, + DirectiveConstants.NOCC_NODES, + arrayify(DirectiveConstants.UNCHECKED_NODE_TYPE), + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.PHANTOM_PORT_SIGNOFF, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.DEFAULT_INTEGER_WIDTH, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.SYNTHESIZABLE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + /** CSP timing directives */ + registerDirective(BlockInterface.CSP, + DirectiveConstants.SLACK, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.DYNAMIC_SLACK, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.STAGES, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.LATENCY, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.LATENCY_PER_STAGE, + DirectiveConstants.FLOAT_TYPE, + new Float(2.0)); + registerDirective(BlockInterface.CSP, + DirectiveConstants.SLACK_PER_STAGE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.5)); + registerDirective(BlockInterface.CSP, + DirectiveConstants.CYCLE_TIME, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.CYCLE_TIME_IN, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.CYCLE_TIME_OUT, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.DEFAULT_CYCLE_TIME, + DirectiveConstants.FLOAT_TYPE, + new Float(18)); + registerDirective(BlockInterface.CSP, + DirectiveConstants.FB, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.FB_NEUTRAL, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.FB_VALID, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.BF, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.CSP, + DirectiveConstants.TIME_UNIT, + DirectiveConstants.INT_TYPE, + new Integer(100)); + + // see bug 6085 + registerDirective(BlockInterface.CSP, + DirectiveConstants.STRICT_VARS, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CSP, + DirectiveConstants.DISABLE_CHANDFT_HANDLER, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CSP, + DirectiveConstants.IMPLICIT_INIT, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.TRUE); + + /** Proteus directives */ + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASYNC_SCAN_INPUTS, + DirectiveConstants.BOOLEAN_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASYNC_SCAN_OUTPUTS, + DirectiveConstants.BOOLEAN_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASYNC_SCAN, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.BOOLEAN_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.PROTEUS_SCAN_MODEL, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.PROTEUS_SCAN_MACROS, + DirectiveConstants.BOOLEAN_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.PROTEUS_SCAN_DECLONE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + /** Slacker directives */ + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_LEAF, + DirectiveConstants.BOOLEAN_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_PRIMITIVE, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_NTPC, + DirectiveConstants.FLOAT_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_IS_SLACK, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_TIME, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0)); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_FREE_SLACK, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0)); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.SLACKER_FREE_SLACK, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0)); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_ELASTICITY, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + new Float(0)); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_HANDSHAKES, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(0)); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_INITIAL_TOKENS, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(0)); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_ALIGNMENT, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + new Integer(0)); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_ALIGNMENT, + DirectiveConstants.INT_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_IGNORE, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.SLACKER_IGNORE, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_DONT_TOUCH, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_DONT_TOUCH, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.SLACKER_DONT_TOUCH, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.BOOLEAN_TYPE, Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_TRANSITIONS, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLACKER_COST, + DirectiveConstants.FLOAT_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.SUPPRESS_FAULTS, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.PORT_GROUP, + DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE, + DirectiveConstants.STRING_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.GROUP_FREQUENCY, + DirectiveConstants.STRING_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.GROUP_CLOCK, + DirectiveConstants.STRING_TYPE, + DirectiveConstants.STRING_TYPE, null); + + registerDirective(BlockInterface.VERILOG, + DirectiveConstants.BOUNDS, + DirectiveConstants.STRING_TYPE, + arrayify(DirectiveConstants.INT_TYPE), + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.PROTEUS_TAG, + DirectiveConstants.STRING_TYPE, null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASTA_BLACKBOX, + DirectiveConstants.BOOLEAN_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASTA_GRAYBOX, + DirectiveConstants.BOOLEAN_TYPE, + null); + + registerDirective(BlockInterface.CELL, + DirectiveConstants.ASTA_IGNORE, + arrayify(DirectiveConstants.DEEP_HALFOP_TYPE), + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.PRS, + DirectiveConstants.ASTA_IGNORE, + arrayify(DirectiveConstants.DEEP_HALFOP_TYPE), + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.ASTA_IGNORE, + arrayify(DirectiveConstants.DEEP_HALFOP_TYPE), + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.SLINT_IGNORE, + arrayify(DirectiveConstants.DEEP_HALFOP_TYPE), + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.PRS, + DirectiveConstants.SLINT_IGNORE, + arrayify(DirectiveConstants.DEEP_HALFOP_TYPE), + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.SUBCELL, + DirectiveConstants.SLINT_IGNORE, + arrayify(DirectiveConstants.DEEP_HALFOP_TYPE), + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + + /** VDCVerify directives */ + registerDirective(BlockInterface.CELL, + DirectiveConstants.VDC_LEAF, + DirectiveConstants.BOOLEAN_TYPE, + Boolean.FALSE); + registerDirective(BlockInterface.CELL, + DirectiveConstants.VDD_DEFAULT_DOMAIN, + DirectiveConstants.NODE_TYPE, + null); + registerDirective(BlockInterface.CELL, + DirectiveConstants.VDD_DOMAIN, + DirectiveConstants.NODE_TYPE, + DirectiveConstants.NODE_TYPE, + null); + + /** Java block directives */ + registerDirective(BlockInterface.JAVA, + DirectiveConstants.GROUP, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.STRING_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.SLACK, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.DYNAMIC_SLACK, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.STAGES, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.INT_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.LATENCY, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.LATENCY_PER_STAGE, + DirectiveConstants.FLOAT_TYPE, + new Float(2.0)); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.SLACK_PER_STAGE, + DirectiveConstants.FLOAT_TYPE, + new Float(0.5)); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.CYCLE_TIME, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.CYCLE_TIME_IN, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.CYCLE_TIME_OUT, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, + null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.DEFAULT_CYCLE_TIME, + DirectiveConstants.FLOAT_TYPE, + new Float(18)); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.FB, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.FB_NEUTRAL, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.FB_VALID, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.BF, + DirectiveConstants.WIDE_CHANNEL_TYPE, + DirectiveConstants.FLOAT_TYPE, null); + registerDirective(BlockInterface.JAVA, + DirectiveConstants.TIME_UNIT, + DirectiveConstants.INT_TYPE, + new Integer(100)); + } + + /** + * This class should not be instantiated. + **/ + private DirectiveTable() { } + + /** + * Register a callback object to parse parameters or values. + * @param block Block in which the callback object is valid. Use + * null to use this callback object globally. + * @param memberType Type that this callback object parses. + * @param newCallback The callback object. + **/ + public static + DirectiveCallback registerCallback(String block, String memberType, + DirectiveCallback newCallback) { + final Pair key = new Pair(block, memberType); + return (DirectiveCallback) callback.put(key, newCallback); + } + + /** + * Return the callback object associated with a given block and type. + **/ + static + DirectiveCallback lookupCallback(String block, String memberType) { + Pair key = new Pair(block, memberType); + DirectiveCallback cb = (DirectiveCallback) callback.get(key); + if (cb == null) { + key = new Pair(null, memberType); + cb = (DirectiveCallback) callback.get(key); + } + return cb; + } + + /** + * Register a nonparameterized directive. + * @param block Block in which the directive is valid. + * @param key Name of the directive. + * @param valueType Type of the value. + * @param defval Default value. Use null is no default value. + **/ + public static + void registerDirective(String block, String key, + String valueType, Object defval) { + directive.put(new Pair(block, key), new Pair(valueType, defval)); + } + + /** + * Register a parameterized directive. + * @param block Block in which the directive is valid. + * @param key Name of the directive. + * @param memberType Type of the parameter. + * @param valueType Type of the value. + * @param defval Default value. Use null is no default value. + **/ + public static + void registerDirective(String block, String key, String memberType, + String valueType, Object defval) { + paramDirective.put(new Pair(block, key), + new Triplet(memberType, valueType, defval)); + } + + /** + * Return a nonparameterized directive given the block and its name. + **/ + public static + Pair lookupDirective(String block, String key) { + return (Pair) directive.get(new Pair(block, key)); + } + + /** + * Return a parameterized directive given the block and its name. + **/ + public static + Triplet[] lookupParameterizedDirective(String block, String key) { + Collection c = paramDirective.get(new Pair(block, key)); + if (c == null) return null; + return (Triplet[]) c.toArray(new Triplet[0]); + } + + public static String arrayify(final String type) { + return type + "[]"; + } + + public static boolean isArray(final String type) { + return type.endsWith("[]"); + } + + public static String deArray(final String type) { + return type.substring(0, type.lastIndexOf("[]")); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveVisitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveVisitor.java new file mode 100644 index 0000000000..9e2818780a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/DirectiveVisitor.java @@ -0,0 +1,23 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.directive.impl.DirectiveStatement; +import com.avlsi.cast2.directive.impl.TokenInfo; + +public interface DirectiveVisitor { + void conditional(String guard, DirectiveStatement[] body, TokenInfo info); + + void loop(String var, String from, String to, DirectiveStatement[] body, + TokenInfo info); + + void definition(String key, String val, TokenInfo info); + + void definition(String key, String parameter, String val, TokenInfo info); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/TokenInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/TokenInfo.java new file mode 100644 index 0000000000..32ebdbbc17 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/directive/impl/TokenInfo.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.directive.impl; + +class TokenInfo extends Object { + private final int line; + private final String file; + public TokenInfo(int line, String file) { + this.line = line; + this.file = file; + } + public int getLine() { + return line; + } + public String getFile() { + return file; + } + public String toString() { + return file + ":" + line; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAliases.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAliases.g new file mode 100644 index 0000000000..196b65e4fd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAliases.g @@ -0,0 +1,69 @@ +// +// Copyright 2002 Asynchronous Digital Design. All rights reserved. +// +// $Id: //depot/sw/cad/java/main/src/com/avlsi/cast2/impl/CastSubcells.g#8 $ +// + +// +// CAST Sub-Parser Grammar for alias blocks (for use with antlr +// http://www.antlr.org/) + + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2002 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastAliases.g instead. + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; +} + +// Import the necessary classes +{ +} + +//--------------------------------------------------------------------------- +// Define a Parser, calling it CastAliasesParser +//--------------------------------------------------------------------------- +class CastAliasesParser extends CastTwoParser; +options { +} + +goal + : aliasInternalBlock EOF + ; + +// Doesn't have surrounding "alias {" and "}" -- those were removed at +// the cell level +aliasInternalBlock + : aliasStatements + ; + +aliasStatements + : ( aliasStatement )* + { #aliasStatements = #( [BODY_STATEMENT_LIST], #aliasStatements ); } + ; + +aliasStatement + : variableDeclarationStatement[IN_ALIAS_BLOCK] + | aliasLoopStatement + | aliasIfStatement + ; + +// TODO: refactor so it shares with other loops +aliasLoopStatement + : lt:LT^ {#lt.setType(LOOP);} id:IDENT + COLON! range COLON! aliasStatements GT! + ; + +// TODO: refactor so it shares with other if statements +aliasIfStatement + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! aliasStatements RBRACK! + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAssert.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAssert.g new file mode 100644 index 0000000000..296427973a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastAssert.g @@ -0,0 +1,83 @@ +// +// Copyright 2002 Fulcrum Microsystems. All rights reserved. +// +// $Id: $ +// + +// +// CAST Sub-Parser Grammar for assert blocks (for use with antlr +// http://www.antlr.org/) + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2002 Fulcrum Microsystems. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastAssert.g instead. + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; +} + + +// Import the necessary classes +{ +} + +//--------------------------------------------------------------------------- +// Define a Parser, calling it CastAssertParser +//--------------------------------------------------------------------------- +class CastAssertParser extends CastPrsParser; +options { + importVocab = CastTwo; +} + +goal + : assertInternalBlock EOF + ; + +// Doesn't have surrounding "assert {" and "}" -- those were removed at +// the cell level +assertInternalBlock + : assertStatements + ; + +assertStatements + : ( assertStatement )* + { #assertStatements = #( [BODY_STATEMENT_LIST], #assertStatements ); } + ; + +assertStatement + : assertPrsStatement + | assertExclStatement + | assertLoopStatement + | assertIfStatement + ; + +assertPrsStatement + : prsExpression SEMI! + ; + +assertExclStatement + : ( EXCLHI^ | EXCLLO^ | EXCLCC^ | NOCC^ ) LPAREN! assertNodeList RPAREN! SEMI! + ; + +assertNodeList + : prsNodeExpression ( COMMA! prsNodeExpression )* + ; + +// TODO: refactor so it shares with other loops +assertLoopStatement + : lt:LT^ {#lt.setType(LOOP);} id:IDENT + COLON! range COLON! assertStatements GT! + ; + +// TODO: refactor so it shares with other if statements +assertIfStatement + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! assertStatements RBRACK! + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastInfo.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastInfo.g new file mode 100644 index 0000000000..a927f303f4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastInfo.g @@ -0,0 +1,52 @@ +// +// Copyright 2001 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// quick CAST Parser Grammar (for use with antlr http://www.antlr.org/) + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2001 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastInfo.g instead. + // + // Warning: does not get all information and will fail on valid cast + // files with complicated channels. + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; +} + +{ + import java.io.*; + import antlr.TokenStreamSelector; + import com.avlsi.cast.impl.ASTWithInfo; + import com.avlsi.cast.impl.CastParserInterface; + import com.avlsi.cast.impl.TokenWithInfo; +} + +class CastInfoParser extends CastTwoParser; + +importDeclaration! + : IMPORT + ( IDENT { syntaxError("Using old import syntax"); } + | importIdent + ) + SEMI! + ; + +subcellsBlock! + : SUBCELLS LCURLY + { + getDumbBlockString(); + } + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastParsingOption.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastParsingOption.java new file mode 100644 index 0000000000..37a27e4c02 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastParsingOption.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.impl; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Value; +import com.avlsi.cell.CellInterface; + +/** + * A collection of methods called by the CAST parser to get information on how + * parsing should proceed. + **/ +public interface CastParsingOption { + /** + * Should requests to inline a cell contain subcells be processed? + * + * @return true if inlining should be respected, and + * false otherwise. + **/ + boolean processInline(CellInterface cell); + + /** + * Get the value that has been override at runtime for variable + * var in the cell cell. + * + * @return the overriden value, or null to indicate the + * variable has not been overriden. + **/ + Value getOverrideValue(CellInterface cell, Symbol var, Value init, + Environment env); + + /** + * Signal the start of CellImpl creation. At this point, only the name of + * the cell is defined. + **/ + void beginCellConstruction(CellInterface cell); + + /** + * Signal the end of of CellImpl creation. At this point, the + * cell should be complete. + **/ + void endCellConstruction(CellInterface cell); + + /** + * Tells the parser if it should be compatible with CAST source before the + * fix for bug 3771. So far, the only cell that is found to be + * incompatible is chip.x6.core.CORE, but no one is willing to modernize + * the CAST. + **/ + boolean bug3771HackEnabled(); + + /** + * Tells the parser if it should be compatible with CAST source before the + * fix for bug 7068. + **/ + boolean bug7068HackEnabled(); + + /** + * Tells the parser if it should be compatible with CAST source before the + * fix for bug 16459. + **/ + boolean bug16459HackEnabled(); + + /** + * The default choice. + **/ + class DefaultParsingOption implements CastParsingOption { + public boolean processInline(final CellInterface cell) { return true; } + public Value getOverrideValue(CellInterface cell, Symbol val, + Value init, Environment env) { + return null; + } + public void beginCellConstruction(final CellInterface cell) { } + public void endCellConstruction(final CellInterface cell) { } + public boolean bug3771HackEnabled() { return false; } + public boolean bug7068HackEnabled() { return false; } + public boolean bug16459HackEnabled() { return false; } + } + + CastParsingOption DEFAULT = new DefaultParsingOption(); + + /** + * Simulators should use this option. Currently, it turns inlining off, so + * that CSP definitions inside inlined subcells can be found properly. + **/ + CastParsingOption SIMULATOR = new DefaultParsingOption() { + public boolean processInline(final CellInterface cell) { return false; } + }; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastPrs.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastPrs.g new file mode 100644 index 0000000000..002c85cd53 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastPrs.g @@ -0,0 +1,147 @@ +// +// Copyright 2000 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// CAST Sub-Parser Grammar for PRS blocks (for use with antlr +// http://www.antlr.org/) +// +// author: Jesse Rosenstock +// + + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2000 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastPrs.g instead. + // + // FIXME: doesn't syntax-check well + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; +} + +// Import the necessary classes +{ +} + +//--------------------------------------------------------------------------- +// Define a Parser, calling it CastPrsParser +//--------------------------------------------------------------------------- +class CastPrsParser extends CastTwoParser; +options { +} + +goal + : prsInternalBlock EOF + ; + +// Doesn't have surrounding "prs {" and "}" -- those were removed at +// the cell level +prsInternalBlock + : prsStatements + ; + +prsStatements + : ( prsStatement )* + { #prsStatements = #( [BODY_STATEMENT_LIST], #prsStatements ); } + ; + +prsStatement + : prsIfStatement + | prsLoopStatement + | (prsModifiers prsExpression ( ARROW | CELEM_ARROW | COMB_ARROW )) => + prsAction + | directiveBlock + | (assignableExpression ASSIGN) => assignmentStatement + | variableDeclarationStatement[IN_PRS_BLOCK] + | assertBlock + ; + +prsIfStatement + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! prsStatements RBRACK! + ; + +prsLoopStatement + : lt:LT^ {#lt.setType(LOOP);} id:IDENT + COLON! range COLON! prsStatements GT! + ; + +startPrsAction + : prs:prsAction EOF! { #startPrsAction = #prs; } + ; + +prsAction + : prsModifiers + prsExpression ( ARROW^ | CELEM_ARROW^ | COMB_ARROW^ ) + prsNodeExpression ( PLUS | MINUS ) + ; + +prsModifiers + : ( ISOCHRONIC )? ( UNSTAB | METASTABLE )? + ( ( AFTER | AFTER_PS ) expression )? + ; + +prsExpression + : poe:prsOrExpression + { + #prsExpression = #( [PRS_EXPRESSION], #prsExpression); + #prsExpression.copyInfo(#poe); + } + ; + +prsOrExpression + : prsAndExpression ( o:OR^ {#o.setType(PRS_OR);} prsAndExpression )* + ; + +prsAndExpression + : prsNotExpression ( a:AND^ {#a.setType(PRS_AND);} prsNotExpression )* + ; + +prsNotExpression + : n:NOT^ {#n.setType(PRS_NOT);} prsNotExpression + | prsLoopedExpression + ; + +prsLoopedExpression + // XXX: LT_AND / LT_OR are hacks! We should fix this! + // we want: LT ( AND | OR ) + : ( la:LT_AND^ {#la.setType(LOOP_PRS_AND);} + | lo:LT_OR^ {#lo.setType(LOOP_PRS_OR); } ) + id:IDENT COLON! range COLON! prsExpression GT! + | prsSelectionExpression + ; + +// review, this allows (foo | bar).baz[0], too general! +prsSelectionExpression +//ugh, duplication + : prsPrimaryExpression + (! id:DOT_IDENT + { final String s = id.getText(); + #prsSelectionExpression + = #( [FIELD_ACCESS], + #prsSelectionExpression, #[ FIELD_IDENT, s ] ); + #prsSelectionExpression.copyInfo(#id); + } + |! as:arraySelector + { #prsSelectionExpression + = #( [ARRAY_ACCESS], #prsSelectionExpression, #as ); + #prsSelectionExpression.copyInfo(#as); + } + )* + ; + +prsPrimaryExpression + : IDENT + | LPAREN! prsOrExpression RPAREN! + ; + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubcells.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubcells.g new file mode 100644 index 0000000000..f2c0ca71c0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubcells.g @@ -0,0 +1,83 @@ +// +// Copyright 2000 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// CAST Sub-Parser Grammar for subcells blocks (for use with antlr +// http://www.antlr.org/) +// +// author: Jesse Rosenstock +// + + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2000 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastSubcells.g instead. + // + // FIXME: doesn't syntax-check well + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; +} + +// Import the necessary classes +{ +} + +//--------------------------------------------------------------------------- +// Define a Parser, calling it CastSubcellsParser +//--------------------------------------------------------------------------- +class CastSubcellsParser extends CastTwoParser; +options { + classHeaderSuffix = CastTwoParserCallback; +} + +goal + : subcellStatements EOF + ; + +goalCallback[CastTwoUtil.ParserCallback cb] + : subcellStatementsCallback[cb] EOF + ; + +// Doesn't have surrounding "subcells {" and "}" -- those were removed at +// the cell level +subcellStatements + : ( subcellStatement )* + { #subcellStatements = #( [BODY_STATEMENT_LIST], #subcellStatements ); } + ; + +subcellStatementsCallback[CastTwoUtil.ParserCallback cb] + : ( stmt:subcellStatement! { cb.bodyStatement(#stmt); } )* + ; + +subcellStatement + : (assignableExpression ASSIGN) => assignmentStatement + | variableDeclarationStatement[IN_SUBCELLS_BLOCK] + | subcellLoopStatement + | subcellIfStatement + | assertBlock + | directiveBlock + ; + +// TODO: refactor so it shares with other loops +subcellLoopStatement + : lt:LT^ {#lt.setType(LOOP);} id:IDENT + COLON! range COLON! subcellStatements GT! + ; + +// TODO: refactor so it shares with other if statements +subcellIfStatement + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! subcellStatements RBRACK! + ; + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubtypes.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubtypes.g new file mode 100644 index 0000000000..5a5f3283cd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastSubtypes.g @@ -0,0 +1,85 @@ +// +// Copyright 2001 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// CAST Sub-Parser Grammar for subtypes blocks (for use with antlr +// http://www.antlr.org/) + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2001 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastSubcells.g instead. + // + // FIXME: doesn't syntax-check well + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; +} + +// Import the necessary classes +{ +} + +//--------------------------------------------------------------------------- +// Define a Parser, calling it CastSubtypesParser +//--------------------------------------------------------------------------- +class CastSubtypesParser extends CastTwoParser; +options { + classHeaderSuffix = CastTwoParserCallback; +} + +goal + : subtypesStatements EOF + ; + +goalCallback[CastTwoUtil.ParserCallback cb] + : subtypesStatementsCallback[cb] EOF + ; + +// Doesn't have surrounding "subtypes {" and "}" -- those were removed at +// the cell level +subtypesStatements + : ( subtypesStatement )* + { #subtypesStatements = #( [BODY_STATEMENT_LIST], #subtypesStatements ); } + ; + +subtypesStatementsCallback[CastTwoUtil.ParserCallback cb] + : ( stmt:subtypesStatement! { cb.bodyStatement(#stmt); } )* + ; + +subtypesStatement + : subtypesRefinement + | subtypesLoopStatement + | subtypesIfStatement + | directiveBlock + ; + +subtypesRefinement! + : ( inline:INLINE )? + parent:type[true] COLON! GT! child:type[true] ae:assignableExpression SEMI! + { + #subtypesRefinement = #( [VAR_DECL], inline, ae, + #( [TYPE], parent, [CHANNEL_WIDTH] ), + #( [TYPE], child, [CHANNEL_WIDTH] )); + } + ; + +subtypesLoopStatement + : lt:LT^ {#lt.setType(LOOP);} id:IDENT + COLON! range COLON! subtypesStatements GT! + ; + +subtypesIfStatement + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! subtypesStatements RBRACK! + ; + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwo.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwo.g new file mode 100644 index 0000000000..0ea0f7f5ae --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwo.g @@ -0,0 +1,1420 @@ +// +// Copyright 2000 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// CAST Parser Grammar (for use with antlr http://www.antlr.org/) +// +// author: Jesse Rosenstock +// + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2000 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastTwo.g instead. + // + // This parses version two of cast (fast, castv2, whatever it's + // being called). + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; + +} + +// Import the necessary classes +{ + /* It's best to avoid importing any classes, because antlr will not + * automatically replicate this section when emitting the extended .g files + * for grammar inheritance. This means that you would have to go edit the + * .g files for all the subparsers, and also add the import line there, + * which is inconvenient. + */ +} + +// todo: +// currently, we cannot support {a, b} = {c, d} +// because of blocks vs. anonymous arrays issue. +// this could be fixed by using () for arrays +// or using lookahead + +// flat or tree, that is the question: +// ie, (op a b c) or (op (op a b) c) via passing lhs into parse of rhs + +// better handling of initializers / params in formal param list than [identP] + + +//--------------------------------------------------------------------------- +// Define a Parser, calling it CastTwoParser +//--------------------------------------------------------------------------- +class CastTwoParser extends Parser; +options { + classHeaderSuffix = CastTwoParserInterface; + k = 2; // This is a problem if set too high + exportVocab = CastTwo; + buildAST = true; + defaultErrorHandler = false; + ASTLabelType = "com.avlsi.cast.impl.ASTWithInfo"; +} + +tokens { + ALINT_FANIN; + ARRAY; + ARRAY_SUB; + ARRAY_ACCESS; + BLOCK; + BODY_STATEMENT_LIST; + CHANNEL_TIMING_INFO; + CHANNEL_WIDTH; + CSP_PORTS; + DUMB_BLOCK; + EXPRESSION; + EXPRESSION_LIST; + FIELD_ACCESS; + FIELD_IDENT; + FORMALS; + IF; + IMPORT_IDENT; + INHERITANCE; + INHERITANCE_LIST; + JAVA_CLASS_INITIALIZERS; + JAVA_CLASS_META_PARAMETERS; + JAVA_CLASS_PARAMETER; + JAVA_CLASS_PARAMETERS; + LOOP; + LOOP_AND; + LOOP_OR; + LOOP_TIMES; + LOOP_PLUS; + LOOP_PRS_AND; + LOOP_PRS_OR; + LOOP_XOR; + NAMED_ENV; + NEW_JAVA; + NEW_JAVA_CLASS; + PORT_LIST; + PRS_AND; + PRS_NOT; + PRS_OR; + PRS_EXPRESSION; + COSIM_EXPRESSION; + RANGE; + REFINEMENT; + SELECTION; + TYPE; + TYPE_BODY; + TYPE_DEFINITION; + UNARY_PLUS; + UNARY_MINUS; + USER_TYPE; + VAR_DECL; + STRING; +} + +{ + // flags used by variableDeclaration[] to indicate where variable + // is declared. Modified from CastTwoTree.g; should share later. + private static final int PORT_PARAM = 0; + private static final int META_PARAM = 1; + private static final int IMPLIED_PORT_PARAM = 6; + private static final int ENV_EXTRA_PARAM = 7; + // These three are expanded out of LOCAL_VAR. TOP_LEVEL is used + // for all variable declaration statements not in one of the two + // blocks. + private static final int TOP_LEVEL = 2; + private static final int IN_PRS_BLOCK = 3; + private static final int IN_SUBCELLS_BLOCK = 4; + private static final int IN_ALIAS_BLOCK = 5; + + private boolean verbose = false; + + /** + * To enable more sophisticated control of syntax error handling + * than commenting out the body of syntaxError(). + **/ + public void setVerbosity(boolean verbose) { + this.verbose = verbose; + } + + private antlr.TokenStreamSelector selector = null; + + public void setSelector(final antlr.TokenStreamSelector selector) { + this.selector = selector; + } + + private void getDumbBlockString(final com.avlsi.cast.impl.ASTWithInfo ast, + final Token token) + throws RecognitionException, TokenStreamException { + ast.setText(CastTwoUtil.getDumbBlockString(selector, this)); + ast.setLine(token.getLine()); + ast.setColumn(token.getColumn() + 1); + } + + static CastTwoParserInterface getParser(Class parser, String s, int lineNum, + int colNum, String fileName) { + final antlr.TokenStreamSelector + selector = CastTwoUtil.getSelector(s, lineNum, colNum, fileName); + final Class[] formals = new Class[] { antlr.TokenStream.class }; + final Object[] actuals = new Object[] { selector }; + final CastTwoParserInterface result; + + try { + result = (CastTwoParserInterface) parser.getConstructor(formals) + .newInstance(actuals); + } catch (Exception e) { + throw new RuntimeException("Valid constructor not found for " + + parser.getName()); + } + + result.setSelector(selector); + result.setFilename(fileName); + // Use fully qualified class name so we don't have to add import lines + // to each subparser's grammar + result.setASTNodeClass(com.avlsi.cast.impl.ASTWithInfo.class.getName()); + return result; + } + + public static CastTwoParser getParser(String s, int lineNum, int colNum, + String fileName) { + return (CastTwoParser) getParser(CastTwoParser.class, s, lineNum, + colNum, fileName); + } + + private String getLineNumber() { + try { + return String.valueOf(LT(1).getLine()); + } catch (TokenStreamException e) { + return "unknown line"; + } + } + + /** + * All syntax warning messages about old cast syntax that's no longer + * allowed go through here. Controlled by verbose. + **/ + private void syntaxError(String errorMsg) { + if (verbose) { + System.err.println("SYNTAX: " + getFilename() + ": " + + getLineNumber() + ": " + errorMsg); + } + } + + private void warn(final String message) { + System.err.println("Warning: " + getFilename() + ": " + + getLineNumber() + ": " + message); + } + + /** + * Like syntaxError(), but stops parsing, even if verbose is off. + **/ + private void fatalError(String errorMsg) { + throw new AssertionError("fatal error in " + getFilename() + " at " + + getLineNumber() + ": " + errorMsg); + } +} + +goal + { + if (selector == null) { + // XXX: throw exception + System.err.println("CastTwo selector not set"); + System.exit(1); + } + } + : compilationUnit EOF + ; + +compilationUnit + : moduleDeclaration + ( importDeclaration )* + ( fileLevelBodyStatement )* + ; + +moduleDeclaration + : MODULE^ moduleIdent SEMI! + | /* empty */ + { #moduleDeclaration = #( [MODULE], [IDENT, ""] ); + syntaxError("No module declaration"); + } + ; + +importDeclaration + : IMPORT^ importIdent SEMI! + ; + +moduleIdent! + { StringBuffer accum = new StringBuffer(); } + : id:IDENT { accum.append(id.getText()); } + ( moduleMetaParamList[accum] )? + ( di:DOT_IDENT { accum.append("." + di.getText()); } + ( moduleMetaParamList[accum] )? )* + { + #moduleIdent = #( [IDENT, accum.toString()] ); + #moduleIdent.copyInfo(#id); + } + ; + +moduleMetaParamList![StringBuffer accum] + : LPAREN {accum.append('(');} + moduleMetaParams[accum] + RPAREN {accum.append(')');} + ; + +moduleMetaParams![StringBuffer accum] + : moduleMetaParam[accum] + ( COMMA {accum.append(',');} moduleMetaParam[accum] )* + ; + +moduleMetaParam![StringBuffer accum] + { boolean negP = false; } + : ( MINUS {negP = true;} )? i:integer + { + // Don't just append '-' because we want -0 to be 0 + java.math.BigInteger v = CastTwoUtil.bigIntegerValue(#i.getText()); + if (negP) + v = v.negate(); + accum.append(v.toString()); + } + | TRUE {accum.append("true");} + | FALSE {accum.append("false");} + | LCURLY {accum.append('{');} + moduleMetaParams[accum] + RCURLY {accum.append('}');} + ; + +// module.cellname (no meta params) +// ident ( (metas)? . ident )* +cellTypeIdent! + { StringBuffer accum = new StringBuffer(); } + : id:IDENT { accum.append(id.getText()); } + cellTypeTail[accum] + { + #cellTypeIdent = #( [IDENT, accum.toString()] ); + #cellTypeIdent.copyInfo(#id); + } + ; + +cellTypeTail![StringBuffer accum] + : ( ( moduleMetaParamList[null] )? DOT_IDENT ) => + ( moduleMetaParamList[accum] )? + di:DOT_IDENT {accum.append('.' + di.getText());} + cellTypeTail[accum] + | /*empty*/ + ; + +dottedIdent + { StringBuffer accum = new StringBuffer(); } + : id:IDENT! { accum.append(id.getText()); } + ( di:DOT_IDENT! { accum.append("." + di.getText()); } )+ + { + #dottedIdent = #( [IDENT, accum.toString()] ); + #dottedIdent.copyInfo(#id); + } + ; + +// module ( . module )* . ( cell | * ) +// ident (metas)? ( . ident (metas)? )* . ( ident | * ) +importIdent + { StringBuffer accum = new StringBuffer(); } + : id:IDENT^ { accum.append(id.getText()); } + ( moduleMetaParamList[accum] )? + ( di:DOT_IDENT {accum.append('.' + di.getText());} + ( moduleMetaParamList[accum] )? )* + ( di2:DOT_IDENT {accum.append('.' + di2.getText());} + | DOT TIMES {accum.append(".*");} ) + { #id.setText(accum.toString()); #id.setType(IMPORT_IDENT); } + ; + +bodyStatements[boolean fileLevelP] + : ( { fileLevelP }? ( fileLevelBodyStatement )* + | { ! fileLevelP }? ( internalBodyStatement[false] )* + ) + { #bodyStatements = #( [BODY_STATEMENT_LIST], #bodyStatements ); } + ; + +// statements that can be at the top level of a file (or inside +// loops/ifs at the top level of a file) +fileLevelBodyStatement + : typeDeclaration + | channelDeclaration + | aliasDeclaration + | typeBody[true] + | (assignableExpression ASSIGN) => assignmentStatement + | variableDeclarationStatement[TOP_LEVEL] + | loopStatement[true] + | ifStatement[true] + | prsBlock + { syntaxError("prs block outside of cell definition"); } + ; + +internalBodyStatement[boolean isEnv] + // lookahead is used here to avoid having keywords for level / csp / ... + : ( ( FRAGMENT )? PRS ) => prsBlock + | cspBlock + | subcellsBlock + | { !isEnv }? envBlock + | javaBlock + | netlistBlock + | directiveBlock + | typeBody[false] + | ( topLevelConstantType ) => topLevelConstantDeclaration + | (assignableExpression ASSIGN) => assignmentStatement + // XXX: Allowing assignmentStatements at the top level for the + // sake of top-level constant assignments (like "int d[0..2]; + // d[1] = 4;"). This will let assignments of ports to each + // other slip through without warning. + | variableDeclarationStatement[TOP_LEVEL] + | loopStatement[false] + | ifStatement[false] + | subtypesBlock + | verilogBlock + ; + +channelDeclaration + : DEFCHAN^ + name:IDENT + ( metaParameterList ( portParameterList )? )? + ( inheritanceList[false] )? + ( ref:refinement[false] )? + channelBody + ; + +channelBody + : LCURLY! channelStatements RCURLY! + ; + +channelStatements + : ( channelStatement )* + { #channelStatements = #( [BODY_STATEMENT_LIST], #channelStatements ); } + ; + +channelStatement + : aliasBlock + | assertBlock + | directiveBlock + ; + +// Packages up a string; CastTwoTreeParser will deal with it. +aliasBlock + : alias:ALIAS^ l:LCURLY! + { + getDumbBlockString(#alias, l); + } + ; + +assertBlock + : assertion:ASSERT^ l:LCURLY! + { + getDumbBlockString(#assertion, l); + } + ; + +typeDeclaration + : typeHeader typeBody[false] + { #typeDeclaration = #( [TYPE_DEFINITION], #typeDeclaration ); } + ; + +typeHeader + : DEFINE! id:IDENT + ( metaParameterList ( portParameterList ( impliedParameterList )? )? )? + inheritanceAndRefinement[false] + ; + +aliasDeclaration + : DEFALIAS^ id:IDENT ( metaParameterList )? refinement[false] SEMI! + ; + +inheritanceAndRefinement[boolean inEnv] + : ATTRIBUTES ( inheritanceList[inEnv] )? + | ( inheritanceList[inEnv] )? ( refinement[inEnv] )? + ; + +inheritanceList[boolean inEnv] + : inheritance[inEnv] ( inheritance[inEnv] )* + { #inheritanceList = #( [INHERITANCE_LIST], #inheritanceList ); } + ; + +inheritance[boolean inEnv] + : l:LT^ { #l.setType(INHERITANCE); } PLUS! cellTypeIdent + // metaparameters + ( (LPAREN expressionList RPAREN) => typeParameterList + | /* empty */ ) + ( { inEnv }? COLON! cellTypeIdent + // env metaparameters + ( (LPAREN expressionList RPAREN) => typeParameterList + | /* empty */ ) + )? + ; + +refinement[boolean inEnv] + : l:LT^ { #l.setType(REFINEMENT); } COLON! cellTypeIdent + // metaparameters + ( (LPAREN expressionList RPAREN) => typeParameterList + | /* empty */ ) + ( { inEnv }? COLON! cellTypeIdent + // env metaparameters + ( (LPAREN expressionList RPAREN) => typeParameterList + | /* empty */ ) + )? + ; + +metaParameterList + : LPAREN! parameterList[META_PARAM] RPAREN! + ; + +portParameterList + : LPAREN! parameterList[PORT_PARAM] RPAREN! + ; + +impliedParameterList + : LPAREN! parameterList[IMPLIED_PORT_PARAM] RPAREN! + ; + +envExtraParameterList + : LPAREN! parameterList[ENV_EXTRA_PARAM] RPAREN! + ; + +// Declaration of ports of a cell. +parameterList[int declKind] + : ( v:variableDeclaration[declKind] + ( options { warnWhenFollowAmbig = false; } : + SEMI! variableDeclaration[declKind] + )* + ( SEMI! )? + )? + { #parameterList = #( [FORMALS], #parameterList ); + if (#v != null) + #parameterList.copyInfo(#v); } + ; + +typeBody[boolean fileLevelP] + : lc:LCURLY^ {#lc.setType(BLOCK);} bodyStatements[fileLevelP] RCURLY! + ; + +// Shares a fair amount of code with variableDeclarationStatement and +// its children, but not enough to make it worth working another flag +// through everything +topLevelConstantDeclaration! + : t:topLevelConstantType id:IDENT + ( a:arraySelector )? ( ASSIGN assign:expression )? + SEMI + { + final com.avlsi.cast.impl.ASTWithInfo assignmentBit; + if (#assign == null) + assignmentBit = null; + else + assignmentBit = #( [ASSIGN], #assign ); + + // nulls are inline/flatten. + #topLevelConstantDeclaration = + #( [VAR_DECL], #id, + null, null, + #( [TYPE], #t, #a, #([CHANNEL_WIDTH]) ), + assignmentBit + ); + } + ; + +topLevelConstantType + : INT + | FLOAT + | BOOL + ; + +instantiation + : variableDeclaration[IN_SUBCELLS_BLOCK] + ; + +// declKind can only be one of the LOCAL_VAR types +variableDeclarationStatement[int declKind] + : variableDeclaration[declKind] SEMI! + ; + +variableDeclaration![int declKind] + : ( i:INLINE { if (declKind != IN_SUBCELLS_BLOCK) fatalError("cells may only be inlined in subcells blocks"); } + | f:FLATTEN + { warn("flatten is deprecated"); + if (declKind != IN_PRS_BLOCK) + fatalError("cells may only be flattened in prs blocks"); + } + )? + t:type[declKind == IN_SUBCELLS_BLOCK || declKind == IN_PRS_BLOCK || + declKind == PORT_PARAM || declKind == IMPLIED_PORT_PARAM || + declKind == ENV_EXTRA_PARAM || declKind == IN_ALIAS_BLOCK ] + c:channelWidth v:variableDeclarators[declKind, #t, #c, #i, #f] + { #variableDeclaration = #v; } + ; + +variableDeclarators[int declKind, AST t, AST width, AST inlineAST, + AST flattenAST] + : variableDeclarator[declKind, getASTFactory().dupTree(t), + getASTFactory().dupTree(width), + getASTFactory().dupTree(inlineAST), + getASTFactory().dupTree(flattenAST)] + ( COMMA! variableDeclarator[declKind, getASTFactory().dupTree(t), + getASTFactory().dupTree(width), + getASTFactory().dupTree(inlineAST), + getASTFactory().dupTree(flattenAST)] )* + ; + +variableDeclarator![int declKind, AST t, AST width, AST inlineAST, + AST flattenAST] + { final boolean formalP = + declKind == PORT_PARAM || declKind == IMPLIED_PORT_PARAM || + declKind == ENV_EXTRA_PARAM; + boolean p = false, m = false; } + : ( {formalP}? ( p1:PLUS {p=true;} ( m1:MINUS {m=true;} )? + | m2:MINUS {m=true;} ( p2:PLUS {p=true;} )? ) )? + id:IDENT ( a:arraySelector )? + ( { declKind == IMPLIED_PORT_PARAM }? c:COLON id2:IDENT )? + ( { declKind == ENV_EXTRA_PARAM }? COLON ae:assignableExpression )? + ( { !formalP }? vi:variableInitializer )? + { // REVIEW: this is really ugly!!! is there a better way? + if (! formalP && (p || m)) + syntaxError("shouldn't have directionality on metaparameters"); + if (p && m) + #variableDeclarator + = #( [VAR_DECL], id, [PLUS], [MINUS], inlineAST, + flattenAST, #([TYPE], t, a, width), c, id2, ae, vi ); + else if (p) + #variableDeclarator + = #( [VAR_DECL], id, [PLUS], inlineAST, + flattenAST, #([TYPE], t, a, width), c, id2, ae, vi ); + else if (m) + #variableDeclarator + = #( [VAR_DECL], id, [MINUS], inlineAST, + flattenAST, #([TYPE], t, a, width), c, id2, ae, vi ); + else { + if (formalP) syntaxError("no directionality declared on port"); + #variableDeclarator + = #( [VAR_DECL], id, inlineAST, + flattenAST, #([TYPE], t, a, width), c, id2, ae, vi ); + } + } + ; + + +variableInitializer + : lp:LPAREN^ {#lp.setType(PORT_LIST);} expressionList RPAREN! // normal ports + ( LPAREN! expressionList RPAREN! ) ? // implied + | ASSIGN^ expression + ; + +arraySelector + : lb:LBRACK^ {#lb.setType(ARRAY_SUB);} ranges RBRACK! + ; + +ranges + : range ( COMMA! range )* + ; + +// For external access from the CDL parser +startRange + : r:range EOF! + { + #startRange = #r; + } + ; + +range + : expression ( DOTDOT! expression )? + { #range = #( [RANGE], range ); } + ; + +cellType + : cellTypeIdent typeParameterList EOF! + { #cellType = #( [USER_TYPE], #cellType ); } + ; + +type[boolean nonprimitiveAllowed] + : primitiveType + | cellTypeIdent { + if (!nonprimitiveAllowed) + syntaxError("Non-primitive declarations allowed inside PRS and subcells block only."); + } + typeParameterList + { #type = #( [USER_TYPE], #type ); } + ; + +channelWidth + : l:LBRACK^ { #l.setType(CHANNEL_WIDTH); } expression RBRACK! + | /* empty */ { #channelWidth = #( [CHANNEL_WIDTH] ); } + ; + +typeParameterList + : LPAREN! expressionList RPAREN! + |! /* empty */ { #typeParameterList = #( [EXPRESSION_LIST], #typeParameterList ) ; } + ; + +primitiveType + : BOOL + | FLOAT + | INT + | NODE + ; + +loopStatement[boolean fileLevelP] + : lt:LT^ {#lt.setType(LOOP);} id:IDENT COLON! range COLON! bodyStatements[fileLevelP] GT! + ; + +ifStatement[boolean fileLevelP] + : lb:LBRACK^ {#lb.setType(IF);} expression ARROW! bodyStatements[fileLevelP] RBRACK! + ; + +assignmentStatement + : assignment SEMI! + ; + +assignment + : assignableExpression assignmentRhs + { #assignment = #( [ASSIGN], #assignment ); } + ; + +assignmentRhs + : ( ASSIGN! expression )+ + ; + +// fix me up later! +// ugh, duplication +assignableExpression + : id:IDENT + (! i:DOT_IDENT + { final String s = i.getText(); + #assignableExpression = #( [FIELD_ACCESS], + #assignableExpression, + #[ FIELD_IDENT, s ] ); + #assignableExpression.copyInfo(#i); + } + |! as:arraySelector + { #assignableExpression = #( [ARRAY_ACCESS], + #assignableExpression, + #as + ); + #assignableExpression.copyInfo(#as); + } + )* + ; + +expressionList + : ( /* empty */ { #expressionList = #( [EXPRESSION_LIST] ); } + | e:expression + ( options { warnWhenFollowAmbig = false; } : COMMA! expression )* + ( COMMA! )? + { #expressionList = #( [EXPRESSION_LIST], #expressionList); + #expressionList.copyInfo(#e); + } + ) + // commented out version causes non-determinism, above should + // be equivalent + //: ( expression ( COMMA! expression )* )? + ; + +startExpressionList + : expressionList EOF! + ; + +arrayComprehension + : e:arrayComprehensionItem ( COMMA! arrayComprehensionItem )* + { #arrayComprehension = #( [EXPRESSION_LIST], #arrayComprehension); + #arrayComprehension.copyInfo(#e); + } + ; + +arrayComprehensionItem + : ( expression + | LT_COMMA! IDENT COLON! range COLON! arrayComprehension GT! + ) + ; + +startExpression + : expr:expression EOF! + { + #startExpression = #expr; + } + ; + +expression + : co:conditionalInclusiveOrExpression + { + #expression = #( [EXPRESSION], #expression); + #expression.copyInfo(#co); + } + ; + +conditionalInclusiveOrExpression + : conditionalExclusiveOrExpression ( OR^ conditionalExclusiveOrExpression )* + ; + +conditionalExclusiveOrExpression + : conditionalAndExpression ( XOR^ conditionalAndExpression )* + ; + +conditionalAndExpression + : relationalExpression ( AND^ relationalExpression )* + ; + +relationalExpression + : additiveExpression + ( options { greedy = true; } : // turn off warning from arrayComprehension + ( EQ^ | NE^ | LT^ | LE^ | GT^ | GE^ ) additiveExpression )* + ; + +additiveExpression + : multiplicativeExpression ( ( PLUS^ | MINUS^ ) multiplicativeExpression )* + ; + +additiveExpr + : ae:additiveExpression + { + #additiveExpr = #( [EXPRESSION], #additiveExpr); + #additiveExpr.copyInfo(#ae); + } + ; + +multiplicativeExpression + : unaryExpression ( ( TIMES^ | DIV^ | MOD^ ) unaryExpression )* + ; + +unaryExpression + : PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression + | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression + | NOT^ unaryExpression + | exponentialExpression + ; + +exponentialExpression + : selectionExpression ( EXP^ exponentialExpression )? + ; + +// treeify me +// ugh, duplication +selectionExpression + : primaryExpression + (! i:DOT_IDENT + { final String s = i.getText(); + #selectionExpression = + #( [FIELD_ACCESS], #selectionExpression, #[ FIELD_IDENT, s ] ); + #selectionExpression.copyInfo(#i); + } + |! as:arraySelector + { #selectionExpression = + #( [ARRAY_ACCESS], #selectionExpression, #as ); + #selectionExpression.copyInfo(#as); + } + )* + ; + +integer + : NUM_INT | NUM_HEX + ; + +primaryExpression + : (IDENT LPAREN) => IDENT LPAREN! expressionList RPAREN! + | IDENT + | integer + | NUM_REAL + | TRUE + | FALSE + | anonymousArray + | LPAREN! conditionalInclusiveOrExpression RPAREN! + | primitiveType LPAREN! coe:conditionalInclusiveOrExpression! RPAREN! { + #primaryExpression = #( #primaryExpression, #coe ); + } + | loop:LT^ ( PLUS! { #loop.setType(LOOP_PLUS); } + | TIMES! { #loop.setType(LOOP_TIMES); } + | XOR! { #loop.setType(LOOP_XOR); } ) + IDENT COLON! range COLON! additiveExpr GT! + | loop_or:LT_OR^ { #loop_or.setType(LOOP_OR); } + IDENT COLON! range COLON! additiveExpr GT! + | loop_and:LT_AND^ { #loop_and.setType(LOOP_AND); } + IDENT COLON! range COLON! additiveExpr GT! + ; + +anonymousArray + : lc:LCURLY^ {#lc.setType(ARRAY);} arrayComprehension RCURLY! + ; + +// +// env stuff. Lots of syntactic sugar with curly-brace position +// + +envBlock + : ENV^ (( LCURLY! ( namedEnv )* RCURLY! ) + | namedEnv ) + ; + +namedEnv + : name:IDENT ( metaParameterList ( envExtraParameterList )? )? + inheritanceAndRefinement[true] + (( LCURLY! envBlockStatements RCURLY! ) + | singleEnvBlockStatement ) + { #namedEnv = #( [NAMED_ENV], #( [TYPE_DEFINITION], #namedEnv ) ); } + ; + +envBlockStatements + : ( internalBodyStatement[true] )* + { #envBlockStatements = #( [BLOCK], #( [BODY_STATEMENT_LIST], #envBlockStatements ) ); } + ; + +singleEnvBlockStatement + : envBlockStatement + { #singleEnvBlockStatement = #( [BLOCK], #( [BODY_STATEMENT_LIST], #singleEnvBlockStatement ) ); } + ; + +// Subset of bodyStatement +envBlockStatement + : ( ( FRAGMENT )? PRS ) => prsBlock + | subcellsBlock + | subtypesBlock + | directiveBlock + | cspBlock + | netlistBlock + | javaBlock + | verilogBlock + ; + +// +// PRS stuff now done as a string passed to a separate parser. No +// lazy evaluation yet. +// + +prsBlock + : ( f:FRAGMENT )? p:PRS^ l:LCURLY! + { + getDumbBlockString(#p, l); + } + ; + +// For external use by PrsCallback +startPrsNodeExpression! + : node:prsNodeExpression EOF! + { + #startPrsNodeExpression = #node; + } + ; + +prsNodeExpression +//ugh, duplication + : IDENT + (! id:DOT_IDENT + { final String s = id.getText(); + #prsNodeExpression + = #( [FIELD_ACCESS], + #prsNodeExpression, #[ FIELD_IDENT, s ] ); + #prsNodeExpression.copyInfo(#id); + } + |! as:arraySelector + { #prsNodeExpression + = #( [ARRAY_ACCESS], #prsNodeExpression, #as ); + #prsNodeExpression.copyInfo(#as); + } + )* + ; + +// +// Contains the csp for the cell +// +cspBlock + : csp:CSP^ ( cspPorts )? l:LCURLY! + { + getDumbBlockString(#csp, l); + } + ; + +// +// A csp block can have ports explicitly specified to limit its +// creation of NodeChannels. +// +cspPorts + : l:LPAREN^ { #l.setType(CSP_PORTS); } + cspPort ( COMMA! cspPort )* RPAREN! + ; + +// Array access currently doesn't and might never work, so it's not accepted +cspPort + : id:IDENT^ + ; + +// +// Contains directives which are contained within other blocks. +// +directiveBlock + : directive:DIRECTIVE^ l:LCURLY! + { + getDumbBlockString(#directive, l); + } + ; + +// +// Contains a CDL body. FIXME: A CDL body should be mutually exclusive with +// a subcell body. +// +netlistBlock + : netlist:NETLIST^ l:LCURLY! + { + getDumbBlockString(#netlist, l); + } + ; + +// +// Contains the non-flattenend subcells. Conflicts with the prs block +// handled by the tree parser. FIXME: permits internal node definition +// +// XXXXX +subcellsBlock + : ( i:INLINE | f:FRAGMENT )? subcells:SUBCELLS^ l:LCURLY! + { + getDumbBlockString(#subcells, l); + } + ; + +// +// Contains the definition of how subcells are refined in a refinement +// +subtypesBlock + : subtypes:SUBTYPES^ l:LCURLY! + { + getDumbBlockString(#subtypes, l); + } + ; + +// a Java block to specify co-sim parameters +javaBlock + : j:JAVA^ LCURLY! + ( oldJavaStatements + | newJavaStatements { #j.setType(NEW_JAVA); } + ) RCURLY! + ; + +// +// new java syntax handling +// + +newJavaStatements + : ( newJavaStatement )+ + { #newJavaStatements = #( [BODY_STATEMENT_LIST], #newJavaStatements ); } + ; + +newJavaStatement + : newJavaClassStatement + | javaChannelStatement + | directiveBlock + ; + +newJavaClassStatement + : ( id:IDENT + | d:dottedIdent { #id = #d; } + ) + ( javaClassMetaParameters )? + instanceName:IDENT // May be anonymous + ( javaClassParameters )? + ( javaClassInitializers )? + SEMI! + { + #newJavaClassStatement = #( [NEW_JAVA_CLASS], #newJavaClassStatement ); + #newJavaClassStatement.copyInfo(#id); + } + ; + +javaClassMetaParameters + : l:LPAREN^ javaClassMetaParameter + ( COMMA! javaClassMetaParameter )* + RPAREN! + { #l.setType(JAVA_CLASS_META_PARAMETERS); } + ; + +javaClassMetaParameter + : expression + ; + +// channel/node order not enforced until tree-parsing. +javaClassParameters + : l:LPAREN^ javaClassParameter ( COMMA! javaClassParameter )* RPAREN! + { #l.setType(JAVA_CLASS_PARAMETERS); } + ; + +// Includes nodes and channels. +javaClassParameter + : ( selectionExpression ) + ( javaChannelTimingInfo ) ? + { #javaClassParameter = #( [JAVA_CLASS_PARAMETER], #javaClassParameter ); } + ; + +javaChannelTimingInfo + : c:COLON^ { #c.setType(CHANNEL_TIMING_INFO); } + ( integer + | LPAREN! integer COMMA! integer COMMA! integer COMMA! integer + COMMA! integer + RPAREN! + ) + ; + +// These are the things which will be fed into enqueue() after the +// device in question has been start()ed. +javaClassInitializers + : c:COLON^ { #c.setType(JAVA_CLASS_INITIALIZERS); } + javaClassInitializer ( COMMA! javaClassInitializer )* + ; + +javaClassInitializer + : TRUE + | FALSE + | integer + | NUM_REAL + | QuotedString + ; + +// Creates a BufferedChannel between java devices +javaChannelStatement + : CHANNEL^ id:IDENT + ( arraySelector )? + ( javaChannelTimingInfo )? + SEMI! + ; + +// +// old java syntax handling +// + +oldJavaStatements + : ( oldJavaStatement )+ + { #oldJavaStatements = #( [BODY_STATEMENT_LIST], #oldJavaStatements ); } + ; + +oldJavaStatement + : oldJavaClassStatement + | inputChannelStatement + | outputChannelStatement + | internalChannelStatement + ; + +oldJavaClassStatement + : JAVACLASS^ QuotedString + ; + +inputChannelStatement + : INPUTCHAN^ QuotedString + ; + +outputChannelStatement + : OUTPUTCHAN^ QuotedString + ; + +internalChannelStatement + : INTERNALCHAN^ QuotedString + ; + +// +// Verilog block +// +verilogBlock + : VERILOG^ ( ( LCURLY! ( verilogNamed )* RCURLY! ) | verilogNamed ) + ; + +verilogNamed + : name:IDENT LCURLY! verilogStatements RCURLY! + ; + +verilogStatements + : ( verilogStatement )* + { #verilogStatements = #( [BODY_STATEMENT_LIST], #verilogStatements ); } + ; + +verilogStatement + : verilogIdent ( POUND! LPAREN! expressionList RPAREN! )? + LPAREN! ( verilogParameters )? RPAREN! ( COLON! verilogFiles )? SEMI + | COLON! verilogFiles SEMI + | directiveBlock + ; + +verilogIdent + : IDENT | dottedIdent + ; + +verilogParameters + : verilogImplicitParameter ( COMMA! verilogImplicitParameter )* + | verilogExplicitParameter ( COMMA! verilogExplicitParameter )* + ; + +// mid style +verilogImplicitParameter + : selectionExpression + ; + +// snovak style +verilogExplicitParameter + : DOT_IDENT LPAREN! ( selectionExpression )? RPAREN + // RPAREN instead of RPAREN!, because it resolves non-determinism later + // in the tree parser + ; + +verilogFiles + : QuotedString ( COMMA! QuotedString )* + ; + +// Parse fully qualified cell name minus plus for partial extraction +partialExtraction + : cellTypeIdent + ( ( LPAREN expressionList RPAREN ) => typeParameterList | /* empty */ ) + ( ( PLUS | MINUS ) ( PLUS | MINUS )? assignableExpression )* + ( COLON! + ( cellTypeIdent + ( + ( LPAREN expressionList RPAREN ) => typeParameterList + | /* empty */ + ) + | TIMES + ) + )? + EOF! + ; + +// Parse alint scenarios +alintFanin + : node:prsNodeExpression + ( ASSIGN! s:NUM_INT { s.getText().equals("0") || + s.getText().equals("1") }? + | PLUS + | MINUS ) + { #alintFanin = #( [EXPRESSION], #( [ALINT_FANIN], #alintFanin ) ); + #alintFanin.copyInfo(#node); + } + ; + +alintScenario + : e:alintScenarioItem ( COMMA! alintScenarioItem )* + { #alintScenario = #( [EXPRESSION_LIST], #alintScenario ); + #alintScenario.copyInfo(#e); + } + ; + +alintScenarioItem + : ( alintFanin + | LT_COMMA! IDENT COLON! range COLON! alintScenario GT! + ) + ; + +startAlintScenario! + : LCURLY! ( scenario:alintScenario )? RCURLY! EOF! + { + #startAlintScenario = #scenario; + } + ; + +//--------------------------------------------------------------------------- +// The CastTwo scanner +//--------------------------------------------------------------------------- + +class CastTwoLexer extends Lexer; +options { + classHeaderSuffix = com.avlsi.cast.impl.CastLexerInterface; + charVocabulary = '\0'..'\377'; + exportVocab = CastTwo; // call the vocabulary "CastTwo" + testLiterals = false; // do not automatically test for literals + k = 2; // two characters of lookahead + caseSensitive = true; + caseSensitiveLiterals = true; + defaultErrorHandler = false; +} + +tokens { + ATTRIBUTES = "attributes" ; + BOOL = "bool" ; + DEFINE = "define" ; + FLOAT = "float" ; + FLATTEN = "flatten" ; + IMPORT = "import" ; + INLINE = "inline" ; + INT = "int" ; + MODULE = "module" ; + NODE = "node" ; + TRUE = "true" ; + FALSE = "false" ; + ENV = "env" ; + FRAGMENT = "fragment" ; + // channels + DEFCHAN = "defchan" ; + ALIAS = "alias" ; + ASSERT = "assert" ; + // prs + PRS = "prs" ; + AFTER = "after" ; + AFTER_PS = "after_ps" ; + UNSTAB = "unstab" ; + METASTABLE = "metastab" ; + ISOCHRONIC = "isochronic" ; + // subcells + SUBCELLS = "subcells" ; + SUBTYPES = "subtypes" ; + // directive + DIRECTIVE = "directives" ; + // netlist + NETLIST = "netlist" ; + // csp + CSP = "csp" ; + // java + CHANNEL = "Channel" ; + JAVA = "java" ; + JAVACLASS = "javaclass" ; + INPUTCHAN = "inputchannel" ; + OUTPUTCHAN = "outputchannel" ; + INTERNALCHAN = "internalchannel" ; + // spec + EXCLHI = "exclhi" ; + EXCLLO = "excllo" ; + EXCLCC = "exclcc" ; + NOCC = "nocc" ; + // verilog + VERILOG = "verilog" ; + // aliased types + DEFALIAS = "defalias" ; +} + +{ + public Token makeToken(final int t) { + final Token tok = super.makeToken(t); + ((com.avlsi.cast.impl.TokenWithInfo) tok).setFilename(getFilename()); + return tok; + } +} + +//--------------------------------------------------------------------------- +// OPERATORS +//--------------------------------------------------------------------------- + +ARROW : "->" ; +EXP : "**" ; +PLUS : '+' ; +MINUS : '-' ; +TIMES : '*' ; +DIV : '/' ; +MOD : '%' ; +AND : '&' ; +OR : '|' ; +XOR : '^' ; +NOT : '~' ; +COMMA : ',' ; +SEMI : ';' ; +COLON : ':' ; +ASSIGN : '=' ; +EQ : "==" ; +NE : "!=" ; +LT : '<' ; +LE : "<=" ; +GE : ">=" ; +GT : '>' ; +LPAREN : '(' ; +RPAREN : ')' ; +LCURLY : '{' ; +RCURLY : '}' ; +LBRACK : '[' ; +RBRACK : ']' ; +DOT : '.' ; +DOTDOT : ".." ; +POUND : "#" ; +CELEM_ARROW : "#>" ; +COMB_ARROW : "=>" ; +LT_AND : "<&" ; +LT_OR : "<|" ; +LT_COMMA : "<," ; + +WS + : ( ' ' | '\t' | '\f' | ( '\n' { newline(); } ) ) + { $setType(Token.SKIP); } + ; + +COMMENT_1 + : "/*" + ( options { generateAmbigWarnings=false; } + : { LA(2) != '/' }? '*' + | '\n' {newline();} + | ~('*' | '\n' | '\r') + )* + "*/" + {$setType(Token.SKIP);} + ; + +COMMENT_2 + : "//" (~ '\n' )* '\n' + { $setType(Token.SKIP); newline(); } + ; + +IDENT + : id:REAL_IDENT { $setType(id.getType()); } + | ESCAPED_IDENT ; + +// an identifier. Note that testLiterals is set to true! This means +// that after we match the rule, we look in the literals table to see +// if it's a literal or really an identifer +protected REAL_IDENT + options {testLiterals=true;} + : ( LETTER | '_' ) ( LETTER | '_' | DIGIT )* + { $setType(IDENT); } + ; + +protected ESCAPED_IDENT + : '"' ( LETTER | DIGIT | '_' | '!' )+ '"' + { + final String s = $getText; + final String ss = s.substring(1, s.length() - 1); + $setText(ss); + } + ; + +// a numeric literal or an identifier +NUM_INT + { boolean identP = false; } + // Hexadecimal case + : { LA(1) == '0' && LA(2) == 'x' }? + DIGIT! LETTER! ( DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | + 'a' | 'b' | 'c' | 'd' | 'e' | 'f' )+ + { $setType(NUM_HEX); } + // Normal number/identifier case + | ( DIGIT )+ ( IDENT { $setType(IDENT); identP = true; } )? + ( { LA(2) != '.' && LA(3) != '.' && !identP}? + '.' ( DIGIT )+ ( EXPONENT )? + { $setType(NUM_REAL); } + )? + ; + +DOT_IDENT + : '.' ( IDENT | NUM_INT ) + { + final String s = $getText; + final String ss = s.substring(1); + $setText(ss); + } + ; + +QuotedString + : '\'' (~'\'')* '\'' + { + // strip leading and trailing single quotes + final String s = $getText; + final String ss = s.substring(1, s.length() - 1); + $setText(ss); + } + ; + +protected +EXPONENT + : ( 'e' | 'E' ) ( '+' | '-' )? ( DIGIT )+ + ; + +protected +LETTER + : 'a'..'z' | 'A'..'Z' + ; + +protected +DIGIT + : '0'..'9' + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserCallback.java new file mode 100644 index 0000000000..6e2bb42cb9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserCallback.java @@ -0,0 +1,19 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.impl; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +/** + * An interface which implements a tree parser callback. + **/ +public interface CastTwoParserCallback extends CastTwoParserInterface { + void goalCallback(CastTwoUtil.ParserCallback cb) + throws RecognitionException, TokenStreamException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserInterface.java new file mode 100644 index 0000000000..435f854561 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoParserInterface.java @@ -0,0 +1,17 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.impl; + +import com.avlsi.cast.impl.CastParserInterface; + +/** + * An interface which all subparsers implement. + **/ +public interface CastTwoParserInterface extends CastParserInterface { + void setVerbosity(boolean verbose); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoTree.g b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoTree.g new file mode 100644 index 0000000000..25f7195555 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoTree.g @@ -0,0 +1,4519 @@ +// +// Copyright 2000 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// +// CAST Tree Parser Grammar (for use with antlr http://www.antlr.org/) +// +// author: Jesse Rosenstock +// + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2000 Asynchronous Digital Design. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastTwoTree.g instead. + // + // TODO: make the AST factory a singleton member to save initialization + // costs + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.cast2.impl; + + import antlr.ASTFactory; + import antlr.TokenStreamException; + import antlr.TokenStreamSelector; + import java.io.FileNotFoundException; + import java.io.IOException; + import java.io.StringReader; + import java.math.BigDecimal; + import java.math.BigInteger; + import java.util.*; + import com.avlsi.cast.impl.AmbiguousLookupException; + import com.avlsi.cast.impl.AlintFaninValue; + import com.avlsi.cast.impl.ArrayValue; + import com.avlsi.cast.impl.AnonymousValue; + import com.avlsi.cast.impl.ASTWithInfo; + import com.avlsi.cast.impl.BlockEnvironment; + import com.avlsi.cast.impl.BoolValue; + import com.avlsi.cast.impl.CastParserEnvironment; + import com.avlsi.cast.impl.CastTreeParserInterface; + import com.avlsi.cast.impl.ChainEnvironment; + import com.avlsi.cast.impl.CircularImportException; + import com.avlsi.cast.impl.DenseSubscriptSpec; + import com.avlsi.cast.impl.Environment; + import com.avlsi.cast.impl.EnvironmentEntry; + import com.avlsi.cast.impl.EnvironmentEntryIterator; + import com.avlsi.cast.impl.EnvironmentIterator; + import com.avlsi.cast.impl.FieldedValueInterface; + import com.avlsi.cast.impl.FixedBlockEnvironment; + import com.avlsi.cast.impl.FloatValue; + import com.avlsi.cast.impl.ImportEnvironment; + import com.avlsi.cast.impl.InstanceValue; + import com.avlsi.cast.impl.IntValue; + import com.avlsi.cast.impl.InvalidOperationException; + import com.avlsi.cast.impl.JavaChannelContainerValue; + import com.avlsi.cast.impl.LocalEnvironment; + import com.avlsi.cast.impl.LoopEnvironment; + import com.avlsi.cast.impl.MetaParamValueInterface; + import com.avlsi.cast.impl.NodeValue; + import com.avlsi.cast.impl.NullEnvironment; + import com.avlsi.cast.impl.PRSExpressionValue; + import com.avlsi.cast.impl.Range; + import com.avlsi.cast.impl.SelfImportException; + import com.avlsi.cast.impl.SemanticWrapperException; + import com.avlsi.cast.impl.SplicingEnvironment; + import com.avlsi.cast.impl.SubscriptSpecInterface; + import com.avlsi.cast.impl.Symbol; + import com.avlsi.cast.impl.SymbolRedeclaredException; + import com.avlsi.cast.impl.TokenWithInfo; + import com.avlsi.cast.impl.TopLevelEnvironment; + import com.avlsi.cast.impl.TupleValue; + import com.avlsi.cast.impl.TupleGroupValue; + import com.avlsi.cast.impl.Type; + import com.avlsi.cast.impl.UserDefinedValue; + import com.avlsi.cast.impl.Value; + import com.avlsi.cast2.directive.impl.DirectiveParser; + import com.avlsi.cast2.directive.impl.DirectiveFactory; + import com.avlsi.cast2.directive.impl.DirectiveStatement; + import com.avlsi.cast2.directive.impl.DirectiveImpl; + import com.avlsi.cast2.directive.impl.DirectiveSyntaxException; + import com.avlsi.csp.ast.ArrayAccessExpression; + import com.avlsi.csp.ast.AssignmentStatement; + import com.avlsi.csp.ast.BooleanExpression; + import com.avlsi.csp.ast.BooleanType; + import com.avlsi.csp.ast.CSPProgram; + import com.avlsi.csp.ast.DeclaratorList; + import com.avlsi.csp.ast.Declaration; + import com.avlsi.csp.ast.Declarator; + import com.avlsi.csp.ast.ExpressionInterface; + import com.avlsi.csp.ast.IdentifierExpression; + import com.avlsi.csp.ast.IntegerExpression; + import com.avlsi.csp.ast.IntegerType; + import com.avlsi.csp.ast.SequentialStatement; + import com.avlsi.csp.ast.StatementInterface; + import com.avlsi.csp.ast.VarStatement; + import com.avlsi.csp.grammar.CspLexer; + import com.avlsi.csp.grammar.CspParser; + import com.avlsi.cell.AttributeInheritanceException; + import com.avlsi.cell.BadCSPPortException; + import com.avlsi.cell.CellImpl; + import com.avlsi.cell.CellInterface; + import com.avlsi.cell.CellUtils; + import com.avlsi.cell.ExclusiveNodeSet; + import com.avlsi.cell.NoSuchSubcellException; + import com.avlsi.cell.RefinementException; + import com.avlsi.cell.SubcellCreationException; + import com.avlsi.fast.BlockInterface; + import com.avlsi.fast.DirectiveBlock; + import com.avlsi.fast.EnvBlock; + import com.avlsi.fast.NetlistBlock; + import com.avlsi.fast.NamedEnvironmentRedeclaredException; + import com.avlsi.fast.ParamTypeInterface; + import com.avlsi.fast.VerilogBlock; + import com.avlsi.fast.metaparameters.ArrayMetaParam; + import com.avlsi.fast.metaparameters.BooleanMetaParam; + import com.avlsi.fast.metaparameters.FloatMetaParam; + import com.avlsi.fast.metaparameters.IntegerMetaParam; + import com.avlsi.fast.metaparameters.MetaParamDefinition; + import com.avlsi.fast.metaparameters.MetaParamTypeInterface; + import com.avlsi.fast.ports.ArrayType; + import com.avlsi.fast.ports.ChannelType; + import com.avlsi.fast.ports.NodeType; + import com.avlsi.fast.ports.PortDefinition; + import com.avlsi.fast.ports.PortTypeInterface; + import com.avlsi.fast.ports.StructureType; + import com.avlsi.file.cdl.parser.CDLLexer; + import com.avlsi.file.cdl.parser.CDLParser; + import com.avlsi.file.cdl.parser.CDLWalker; + import com.avlsi.file.cdl.parser.Template; + import com.avlsi.file.common.HierName; + import com.avlsi.file.common.InvalidHierNameException; + import com.avlsi.prs.ProductionRule; + import com.avlsi.prs.ProductionRuleSet; + import com.avlsi.tools.cosim.CoSimChannelNames; + import com.avlsi.tools.cosim.JavaClassParameter; + import com.avlsi.tools.cosim.JavaCoSimDevice; + import com.avlsi.tools.cosim.JavaCoSimInfo; + import com.avlsi.tools.cosim.CoSimParameters; + import com.avlsi.util.bool.AndBooleanExpression; + import com.avlsi.util.bool.BooleanExpressionInterface; + import com.avlsi.util.bool.HierNameAtomicBooleanExpression; + import com.avlsi.util.bool.OrBooleanExpression; + import com.avlsi.util.container.Pair; + import com.avlsi.util.container.Triplet; + import com.avlsi.util.debug.Debug; + import com.avlsi.util.exception.AssertionFailure; + import com.avlsi.util.text.StringUtil; +} + +// bring this into sync with cast.g +// rationalize the names + +// import +// handle _ for name + +// spiff up using ideas from TinyBasicTreeWalker.g + +// _ explanation: +// _ allowed? Places where identifiers appear +// Y variableDeclarationStatement T _ +// Y metaParam def T(X _)() +// Y portParam def T()(X _) +// Y loopStatement < _ : N : ... > +// Y/N expression:ident _ +// N expression:field +// N baseType +// N typeDeclaration +// +// The only time a _ is allowed as part of an expression +// is as part of the port real parameter list. Ie X x(a, _) +// +// For var decl / meta param / port param / loop statement, a variable +// is created with an autogenerated name that can never be specifed by +// a user. +// +// For the port real parameter list, a variable of the appropriate +// type and autogenerated name is created. Ie +// define X()(T t) { } +// X x(_) +// is equivalent to +// T autogen_name; +// X x(autogen_name) + +// misc todo: +// ensure only algebraic types in meta params, and non-alg in port +// catch illegal array access + +class CastTwoTreeParser extends TreeParser; + +options { + classHeaderSuffix = CastTreeParserInterface; + importVocab = CastTwo; + ASTLabelType = "ASTWithInfo"; + defaultErrorHandler = false; +} + +{ + // flags used be type[] to indicate where variable is declared + private static final int PORT_PARAM = 0; + private static final int META_PARAM = 1; + private static final int LOCAL_VAR = 2; + + /** Syntax warning printout? **/ + private boolean verbose = false; + + /** control syntax warning level **/ + public void setVerbosity(boolean verbose) { + this.verbose = verbose; + } + + /** + * Cell name that signifies the default refinement hierarchy root. + * This is the cellname used to look up the default refinement root. + **/ + private static final String refinementRootCellName = "CELL"; + + /** + * Cell name that signifies an alternate refinement hierarchy root. + * This cell does not refine refinementRootCellName. + **/ + private static final String refinementNullCellName = "NULL"; + + /** + * The module name for the file being parsed. Will be null until + * we encounter the module line, which must be first. + **/ + private String moduleName = null; + + private CastParserEnvironment cpe = null; + + public void setCastParserEnvironment(final CastParserEnvironment cpe) { + this.cpe = cpe; + } + + /** + * Set of cells that is currently being generated. + **/ + private Set cellList = new HashSet(); + + /** + * CAST parsing options that may change how the parser works. + **/ + private CastParsingOption opt = CastParsingOption.DEFAULT; + + public void setCastParsingOption(final CastParsingOption opt) { + this.opt = opt; + } + + /** + * A stack of UserDefinedValues that are currently being processed. A UDV + * is pushed to/popped from the stack just before/after the body of the + * UDV is tree parsed. This is to help a cell defined in the environment + * block get at the container cell's port list. + **/ + private LinkedList activeUDV = new LinkedList(); + + /** + * A stack of missing imports due to bug 7068. This helps the user add the + * missing imports so the workaround for bug 7068 can be removed. + **/ + private static LinkedList bug7068Warnings = new LinkedList(); + + /** + * Handler to process directive warnings. + **/ + private DirectiveImpl.ErrorHandler directiveErrHandler = null; + + public void setDirectiveErrorHandler( + final DirectiveImpl.ErrorHandler directiveErrHandler) { + this.directiveErrHandler = directiveErrHandler; + } + + /** + * The RecognitionException has more accurate position information + * on the error than anything else. + **/ + private SemanticWrapperException semanticWrapperException( + final String message, + final RecognitionException e, + final ASTWithInfo ast) { + return semanticWrapperException(message, e, e.getFilename(), + e.getLine(), -1); + } + + private SemanticWrapperException semanticWrapperException( + final String message, + final Exception e, + final ASTWithInfo ast) { + return semanticWrapperException(message, e, ast.getFilename(), + ast.getLine(), ast.getColumn()); + } + + /** + * The RecognitionException has more accurate position information + * on the error than anything else. + **/ + private SemanticWrapperException semanticWrapperException( + final RecognitionException e, + final ASTWithInfo ast) { + return semanticWrapperException(e, e.getFilename(), e.getLine(), -1); + } + + private SemanticWrapperException semanticWrapperException( + final Exception e, + final ASTWithInfo ast) { + return semanticWrapperException(e, ast.getFilename(), + ast.getLine(), ast.getColumn()); + } + + private SemanticWrapperException semanticWrapperException( + final Exception e, + final String file, + final int line, + final int column) { + return new SemanticWrapperException(e, file, line, column); + } + + private SemanticWrapperException semanticWrapperException( + final String message, + final Exception e, + final String file, + final int line, + final int column) { + return new SemanticWrapperException(message, e, file, line, column); + } + + private String getLocation(ASTWithInfo ast) { + return ast.getFilename() + ":" + + ast.getLine() + "," + + ast.getColumn(); + } + + /** + * Used to issue warnings. + **/ + private void warn(final String s, final ASTWithInfo astForLoc) { + System.err.println(s + " at " + getLocation(astForLoc)); + } + + // + // commonly used operations to catch and map exceptions + // + + /** + * Lookup sym in env. Turn all exception into + * SemanticWrapperExceptions. + **/ + private Value lookup(final Environment env, + final Symbol sym, + final ASTWithInfo symAST) + throws SemanticWrapperException { + return lookup(env, sym, symAST, true); + } + + /** + * Lookup sym in env. Turn all exception into + * SemanticWrapperExceptions. + **/ + private Value lookup(final Environment env, + final Symbol sym, + final ASTWithInfo symAST, + final boolean tryFullyQualified) + throws SemanticWrapperException { + try { + final Value v = env.lookup(sym); + if (v == null) { + if (sym.fullyQualified()) { + // cache it in case we need it again. + return getFullyQualifiedCellValue(sym, env, symAST); + } + /* + else if (tryFullyQualified && moduleName != null) + return getFullyQualifiedCellValue + (Symbol.create(moduleName + '.' + sym.getString()), + env, symAST); + */ + else + throw semanticWrapperException("symbol undefined: " + + sym, new Exception(), + symAST); + } + return v; + } catch (AmbiguousLookupException e) { + throw semanticWrapperException("Symbol " + symAST.getText() + + " exists in multiple imported files. " + + "Use (currently non-existent) import ... as.", + e, symAST); + } + } + + /** + * @param cell the cell that will be affected by any connections + **/ + private void assign(final Value dest, + final Value source, + final CellImpl cell, + final ASTWithInfo astLoc, + final String message) + throws SemanticWrapperException { + try { + dest.assign(source, cell); + } catch (InvalidOperationException e) { + throw semanticWrapperException(message, e, astLoc); + } + } + + /** + * Produces an int from the given Value or throws an exception trying. + **/ + private int getInt(final Value v, final ASTWithInfo ast) + throws SemanticWrapperException { + try { + return IntValue.valueOf(v).getValue().intValue(); + } catch (InvalidOperationException e) { + throw semanticWrapperException(e, ast); + } + + } + + /** + * Turns the string into a Symbol. + * If the string is "_", return a symbol of an auto-generated name, + * otherwise, return a symbol of the name. + **/ + private Symbol generateSymbol(final String s) { + return Symbol.create(generateName(s)); + } + + /** + * If the string is "_", return an auto-generated name, + * otherwise, return the string. + **/ + private String generateName(final String s) { + if (s.equals("_")) + return cpe.nextAnonymousName(); + else + return s; + } + + /** + * Returns a collection of BooleanExpressionInterfaces for + * use by LOOP_OR / LOOP_AND (ie the <| ... > / + * <& ... > syntax. + **/ + private Collection loopedExpression( + final ASTWithInfo id, + final Range r, + final Environment env, + final ASTWithInfo prsExpr) + throws RecognitionException { + final List l = new ArrayList(); + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + + l.add(prsExpression(prsExpr, loopEnv, false)); + } + + return l; + } + + private interface CombineValue { + Value combine(final Value a, final Value b) + throws InvalidOperationException; + Value identity() throws InvalidOperationException; + } + + private Value loopedExpression(final ASTWithInfo id, final Range r, + final Environment env, + final ASTWithInfo expr, + final CombineValue f) + throws RecognitionException, InvalidOperationException { + final Symbol sym = generateSymbol(id.getText()); + Value result = f.identity(); + for (final Range.Iterator ri = r.iterator(); ri.hasNext(); ) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + final Value v = expression(expr, loopEnv, false); + result = f.combine(result, v); + } + + return result; + } + + /** + * Converts Value to BoolValue for use in an if guard. + **/ + private BoolValue ifGuard(final Value v, final ASTWithInfo expr) + throws SemanticWrapperException { + try { + return BoolValue.valueOf(v); + } catch (InvalidOperationException e) { + throw semanticWrapperException("if guard " + v + " not bool", + e, expr); + } + } + + /** + * Attempts to convert a value to a PRSExpressionValue, throwing + * a SemanticWrapperException if the conversion is not possible. + **/ + private PRSExpressionValue toPRSExpressionValue( + final Value v, + final ASTWithInfo expr) + throws SemanticWrapperException { + try { + return PRSExpressionValue.valueOf(v); + } catch (InvalidOperationException e) { + throw semanticWrapperException("type not valid for lhs" + + " of a production rule", e, expr); + } + } + + private HierName oppositePowerSupply( + final Environment env, + final HierName powerSupply, + final ASTWithInfo errorAST) throws SemanticWrapperException { + + final String newPowerSupply; + + if (powerSupply.isVdd()) + newPowerSupply = "GND"; + else if (powerSupply.isGND()) + newPowerSupply = "Vdd"; + else + throw new AssertionFailure("bad power supply: "+powerSupply.getAsString('.')); + + try { + return NodeValue.valueOf( + lookup(env, Symbol.create(newPowerSupply), errorAST)) + .getInstanceName(); + } catch (InvalidOperationException exn) { + throw semanticWrapperException("Non-node type for " + + newPowerSupply + ", implied by complex production rule", + exn, errorAST); + } + } + + public void doInstantiation( + final AST t, + final String moduleName, + final Environment env, + final CellImpl parent, + final CellInterface envContainer) + throws RecognitionException { + this.moduleName = moduleName; + variableDeclarationStatement(t, new BlockEnvironment(env), + false, parent, envContainer, null, false); + } + + /** + * Create the proper fake AST to specify the given cell as a + * refinement parent in the UDV. errorAST supplies + * file/line/column info for all of the fake tree. + **/ + // TODO: caching? + private ASTWithInfo fakeRefinementAST(String cellName, + ASTWithInfo errorAST) { + final ASTFactory factory = new ASTFactory(); + factory.setASTNodeClass(ASTWithInfo.class.getName()); + final ASTWithInfo result; + result = (ASTWithInfo) factory.create( + CastTwoTreeParserTokenTypes.REFINEMENT); + result.copyInfo(errorAST); + final ASTWithInfo child = (ASTWithInfo) factory.create( + CastTwoTreeParserTokenTypes.IDENT, cellName); + child.copyInfo(errorAST); + result.addChild(child); + return result; + } + + /** + * Creates the proper fake AST for an implied parameter list that + * isn't there. errorAST supplies file/line/column info for the + * fake tree + **/ + private ASTWithInfo fakeEmptyPorts(ASTWithInfo errorAST) { + final ASTFactory factory = new ASTFactory(); + factory.setASTNodeClass(ASTWithInfo.class.getName()); + final ASTWithInfo result = (ASTWithInfo) factory.create( + CastTwoTreeParserTokenTypes.FORMALS); + result.copyInfo(errorAST); + return result; + } + + /** + * Creates the proper fake AST for the implied empty block in a + * defalias declaration. + **/ + private ASTWithInfo fakeEmptyBlock(ASTWithInfo errorAST) { + final ASTFactory factory = new ASTFactory(); + factory.setASTNodeClass(ASTWithInfo.class.getName()); + final ASTWithInfo result = (ASTWithInfo) + factory.create(CastTwoTreeParserTokenTypes.BLOCK); + result.copyInfo(errorAST); + final ASTWithInfo bodyStmts = (ASTWithInfo) + factory.create(CastTwoTreeParserTokenTypes.BODY_STATEMENT_LIST); + bodyStmts.copyInfo(errorAST); + result.addChild(bodyStmts); + return result; + } + + /** + * Looks up the UserDefinedValue for the cell and inserts it into + * the specified environment by the fully qualified name only. + * Also returns it. FIXME: doesn't insert it into the environment yet. + **/ + public Value getFullyQualifiedCellValue(Symbol sym, Environment env, + final ASTWithInfo errorAST) + throws SemanticWrapperException { + try { + final String fullName = sym.getString(); + final int lastDot = fullName.lastIndexOf('.'); + final String moduleName = fullName.substring(0, lastDot); + final String cellName = fullName.substring(lastDot + 1); + final Environment parsed = + cpe.parseCell(new LinkedList(), moduleName, cellName); + Value result = lookup(parsed, Symbol.create(cellName), errorAST, + false); + // env.bind(sym, result); + return result; + } + catch (Exception e) { + throw semanticWrapperException(e, errorAST); + } + } + + /** + * Remove all layers of arrays and return the unarrayed base type. + **/ + private static PortTypeInterface getBaseType(final PortTypeInterface p) { + return p instanceof ArrayType ? ((ArrayType) p).getArrayedType() : p; + } + + /** + * Used to be part of baseType[]. This handles the case when the + * CellImpl had been generated before and only needs to be + * attached. Still shouldn't be called by anything but baseType[] + **/ + // FIXME: variable names suck + private void attachGeneratedCell(TupleValue tupleVal, + BlockEnvironment paramEnv, + LocalEnvironment localEnv, + UserDefinedValue typeVal, + ArrayList portList, + ArrayList impliedPortList, + ArrayList impliedPortParentNodes, + LocalEnvironment aliasesEnv) + throws SymbolRedeclaredException, RecognitionException { + + final UserDefinedValue envUDV = typeVal.getEnvironmentContainer(); + final AST portParamList; + final AST impliedPortParamList; + final AST envExtraPortParamList = typeVal.getEnvExtraParamList(); + final boolean reverseDir; // should port directionality be reversed? + if (envUDV == null) { + portParamList = typeVal.getPortParamList(); + impliedPortParamList = typeVal.getImpliedPortParamList(); + reverseDir = false; + } else { + // environments have identical ports as their parent containers, + // but with the port directions reversed + portParamList = envUDV.getPortParamList(); + impliedPortParamList = envUDV.getImpliedPortParamList(); + reverseDir = true; + } + + final CellImpl tempCell = new CellImpl("temp_cell", "temp_module", + CellImpl.SYNTHETIC_CELL); + + // portParamList maybe null if port list has been elided for an + // attribute cell; in all other cases, because of refinement, this + // cannot be null. + assert (portParamList != null || + typeVal.getStructureType() == UserDefinedValue.ATTRIBUTES_CELL); + + if (portParamList != null) { + final Environment portEnv = typeVal.getPortEnvironment(tupleVal); + portParamList(portParamList, + new BlockEnvironment(portEnv, localEnv), tempCell, + portList, null, reverseDir); + } + if (impliedPortParamList != null) + portParamList(impliedPortParamList, paramEnv, tempCell, + impliedPortList, impliedPortParentNodes, false); + if (envExtraPortParamList != null) + portParamList(envExtraPortParamList, paramEnv, tempCell, + null, null, false); + paramEnv.absorbEnv(aliasesEnv); + } + + private static class CellData { + public final UserDefinedValue udv; + public final CellImpl cell; + public final InstanceValue instance; + public final TupleValue metaParams; + public CellData(final UserDefinedValue udv, + final CellImpl cell, + final InstanceValue instance, + final TupleValue metaParams) { + this.udv = udv; + this.cell = cell; + this.instance = instance; + this.metaParams = metaParams; + } + } + + /** + * @param metaEnv environment used to evaluate the metaparameter list + **/ + private CellData getCellFromAST(final ASTWithInfo cellName, + final ASTWithInfo metaParams, + final ASTWithInfo errorAST, + final Environment paramEnv, + final Environment metaEnv, + final CellInterface envContainer) + throws RecognitionException { + final String name = cellName.getText(); + final Pair baseType = + baseType(CastTwoUtil.makeBaseTypeAST(name, metaParams, cellName), + metaEnv, paramEnv, null, envContainer, null, false); + final UserDefinedValue udv = + (UserDefinedValue) lookup(paramEnv, Symbol.create(name), errorAST); + + final TupleValue metaParamsTuple; + if (metaParams == null) { + metaParamsTuple = new TupleValue(new Value[0]); + } else { + metaParamsTuple = expressionList(metaParams, metaEnv, false); + } + + final CellImpl cell = udv.getCell(metaParamsTuple); + + return new CellData(udv, cell, (InstanceValue) baseType.getFirst(), + metaParamsTuple); + } + + private CellData getCellFromAST(final ASTWithInfo cellName, + final ASTWithInfo cellMeta, + final ASTWithInfo envName, + final ASTWithInfo envMeta, + final ASTWithInfo errorAST, + final Environment env) + throws RecognitionException { + final CellData data = getCellFromAST(cellName, cellMeta, errorAST, + env, env, null); + if (envName == null) { + assert envMeta == null; + return data; + } + + return getCellFromAST(envName, envMeta, errorAST, + data.cell.getEnvironments().getEnvironment(), + env, data.cell); + } + + private class Bug7068Environment implements Environment { + private final Environment correct, workaround; + + public Bug7068Environment(Environment correct, Environment workaround) { + this.correct = correct; + this.workaround = workaround; + } + + public void bind(final Symbol sym, final Value val) + throws SymbolRedeclaredException { + // this will create the same binding in correct, because both share + // the same LocalEnvironment where the binding occurs + workaround.bind(sym, val); + } + + public boolean contains(final Symbol sym) { + return workaround.contains(sym); + } + + public Value lookup(final Symbol sym) throws AmbiguousLookupException { + Value c = null; + AmbiguousLookupException ce = null; + try { + c = correct.lookup(sym); + } catch (AmbiguousLookupException e) { + ce = e; + } + + Value w = null; + AmbiguousLookupException we = null; + try { + w = workaround.lookup(sym); + } catch (AmbiguousLookupException e) { + we = e; + } + + if (c == null && w instanceof UserDefinedValue) { + final UserDefinedValue udv = (UserDefinedValue) w; + final Collection warns = (Collection) bug7068Warnings.getLast(); + warns.add(udv.getFullyQualifiedType()); + } + + if (we != null) throw we; + else return w; + } + + public EnvironmentIterator iterator() { + return workaround.iterator(); + } + + public EnvironmentEntryIterator entryIterator() { + return workaround.entryIterator(); + } + } + + // Convert a MetaParamTypeInterface to a Value + private Value fromMetaParam(final MetaParamTypeInterface ty) { + if (ty instanceof BooleanMetaParam) { + return BoolValue.valueOf(((BooleanMetaParam) ty).toBoolean()); + } else if (ty instanceof FloatMetaParam) { + return FloatValue.valueOf(((FloatMetaParam) ty).toFloat()); + } else if (ty instanceof IntegerMetaParam) { + return IntValue.valueOf(((IntegerMetaParam) ty).toBigInteger()); + } else if (ty instanceof ArrayMetaParam) { + final ArrayMetaParam am = (ArrayMetaParam) ty; + final int min = am.getMinIndex(); + final int max = am.getMaxIndex(); + final Value[] vals = new Value[max - min + 1]; + for (int i = 0; i < vals.length; ++i) { + vals[i] = fromMetaParam(am.get(i + min)); + } + + final Range r = new Range(min, max); + + if (vals[0] instanceof ArrayValue) { + final ArrayValue[] newVals = new ArrayValue[vals.length]; + System.arraycopy(vals, 0, newVals,0, vals.length); + try { + return ArrayValue.augmentDimension(newVals, r); + } catch (InvalidOperationException e) { + throw new AssertionError("Cannot augment array"); + } + } else { + return new ArrayValue(vals, + new DenseSubscriptSpec(new Range[] { r }), + null, false); + } + } else { + throw new AssertionError("Cannot create value from: " + ty); + } + } + + // Reconstruct the metaparameter list of a cell + private TupleValue fromMetaParam(final UserDefinedValue udv, + final CellInterface ci) { + if (CellUtils.getBaseType(ci.getFullyQualifiedType()) + .equals(udv.getFullyQualifiedType())) { + final ArrayList vals = new ArrayList(); + for (Iterator i = ci.getMetaParamDefinitions(); i.hasNext(); ) { + final MetaParamDefinition def = (MetaParamDefinition) i.next(); + vals.add(fromMetaParam(def.getType())); + } + return new TupleValue(vals.toArray(new Value[0])); + } else { + return fromMetaParam(udv, ci.getDirectRefinementParent()); + } + } + + /** + * Used to be part of baseType[]. This handles the case where the + * CellImpl hadn't been generated before. Still shouldn't be + * called by anything but baseType[]. + * @param localEnv the child environment of paramEnv. + * + * @throws RecognitionException + **/ + // FIXME: variable names suck + private CellImpl generateAndAttachCell(TupleValue tupleVal, + ASTWithInfo errorAST, + final UserDefinedValue typeVal, + BlockEnvironment paramEnv, + LocalEnvironment inheritedConstants, + BlockEnvironment portEnv, + LocalEnvironment metaEnv, + LocalEnvironment localEnv, + List metaParams, + String typeName, + ArrayList portList, + ArrayList impliedPortList, + ArrayList impliedPortParentNodes, + CellInterface envContainer) + throws RecognitionException { + + final UserDefinedValue envUDV = typeVal.getEnvironmentContainer(); + final AST portParamList; + final AST impliedPortParamList; + final AST envExtraPortParamList = typeVal.getEnvExtraParamList(); + final boolean reverseDir; // should port directionality be reversed? + if (envUDV == null) { + portParamList = typeVal.getPortParamList(); + impliedPortParamList = typeVal.getImpliedPortParamList(); + reverseDir = false; + } else { + // environments have identical ports as their parent containers, + // but with the port directions reversed + portParamList = envUDV.getPortParamList(); + impliedPortParamList = envUDV.getImpliedPortParamList(); + // save the container's port list and implied port list as our own + typeVal.updatePortParamList(portParamList); + typeVal.updateImpliedPortParamList(impliedPortParamList); + typeVal.updateEnvExtraParamList(envExtraPortParamList); + reverseDir = true; + } + final AST inheritanceList = typeVal.getInheritanceList(); + ArrayList inheritanceCellList = null; + ArrayList inheritanceCellConstantsList = null; + ArrayList inheritancePrsEnvList = null; + ArrayList inheritanceSubcellsEnvList = null; + AST refinementParent = typeVal.getRefinementParent(); + final String moduleName = typeVal.getModuleName(); + final int typeValType = typeVal.getStructureType(); + final boolean isAttributesCell = + typeValType == UserDefinedValue.ATTRIBUTES_CELL; + + // To be filled out, attached, and returned + final CellImpl subCell; + + final InstanceValue parentInstance; + final CellImpl parentCell; // Doesn't come from + // parentInstance, but from + // the environment + final LocalEnvironment parentAliases; + final Environment parentCellConstants; + Environment parentPrsEnvironment; + Environment parentSubcellsEnvironment; + final String refinementName; + final AST parentImpliedPorts; + final AST parentPortParamList; + final AST parentEnvExtraPorts; + + // handle <+ inheritance + if (inheritanceList != null) { + inheritanceCellList = new ArrayList(); + inheritanceCellConstantsList = new ArrayList(); + inheritancePrsEnvList = new ArrayList(); + inheritanceSubcellsEnvList = new ArrayList(); + + for (AST inheritance = inheritanceList.getFirstChild(); + inheritance != null; + inheritance = inheritance.getNextSibling()) { + + final CellData inheritanceInfo = + getCellData(inheritance.getFirstChild(), errorAST, + paramEnv, envContainer); + + final CellImpl inheritanceCell = inheritanceInfo.cell; + final UserDefinedValue inheritanceUDV = inheritanceInfo.udv; + final TupleValue inheritanceMetaParamsTuple = + inheritanceInfo.metaParams; + + if (!inheritanceCell.isAttributesCell()) { + throw semanticWrapperException( + new AttributeInheritanceException( + "Only attributes cells may be inherited from " + + "with <+", + typeName, inheritanceCell.getFullyQualifiedType()), + errorAST); + } + + final Environment inheritanceCellConstants = + inheritanceUDV + .getCellConstants(inheritanceMetaParamsTuple); + final Environment inheritancePrsEnvironment = + inheritanceUDV + .getPrsEnvironment(inheritanceMetaParamsTuple); + final Environment inheritanceSubcellsEnvironment = + inheritanceUDV + .getSubcellsEnvironment(inheritanceMetaParamsTuple); + + inheritanceCellList.add(inheritanceCell); + inheritanceCellConstantsList.add(inheritanceCellConstants); + inheritancePrsEnvList.add(inheritancePrsEnvironment); + inheritanceSubcellsEnvList.add(inheritanceSubcellsEnvironment); + } + } + + // 8 + final UserDefinedValue parentUDV; + final TupleValue parentMetaParamsTuple; + if (refinementParent != null) { + // The grammar should not allow this to happen + Debug.assertTrue(!isAttributesCell, + "Attributes cells are not allowed to refine with <:"); + + final CellData refinementInfo = + getCellData(refinementParent.getFirstChild(), errorAST, + paramEnv, envContainer); + + parentCell = refinementInfo.cell; + parentInstance = refinementInfo.instance; + refinementName = parentCell.getFullyQualifiedType(); + parentMetaParamsTuple = refinementInfo.metaParams; + parentUDV = refinementInfo.udv; + + final int parentUDVType = parentUDV.getStructureType(); + if (parentUDVType == UserDefinedValue.ATTRIBUTES_CELL) { + throw semanticWrapperException( + new RefinementException( + "can't <: an attributes cell", + typeName, + refinementName), + errorAST); + } else if ((typeValType == UserDefinedValue.CHANNEL) ^ + (parentUDVType == UserDefinedValue.CHANNEL)) { + throw semanticWrapperException( + new RefinementException( + "only a channel can <: a channel", + typeName, + refinementName), + errorAST); + } + + parentAliases = parentUDV.getAliases(parentMetaParamsTuple); + + parentCellConstants = parentUDV.getCellConstants(parentMetaParamsTuple); + parentPrsEnvironment = + parentUDV.getPrsEnvironment(parentMetaParamsTuple); + parentSubcellsEnvironment = + parentUDV.getSubcellsEnvironment(parentMetaParamsTuple); + + // For future comparison with the child's implied ports + parentImpliedPorts = parentUDV.getImpliedPortParamList(); + parentPortParamList = parentUDV.getPortParamList(); + parentEnvExtraPorts = parentUDV.getEnvExtraParamList(); + } + else { + parentInstance = null; + refinementName = null; + parentMetaParamsTuple = null; + parentUDV = null; + parentCell = null; + parentImpliedPorts = null; + parentAliases = null; + parentCellConstants = null; + parentPrsEnvironment = NullEnvironment.getInstance(); + parentSubcellsEnvironment = NullEnvironment.getInstance(); + parentPortParamList = null; + parentEnvExtraPorts = null; + } + + // map the UserDefinedValue structure types to the CellImpl + // definition types + final int definitionKind; + if (typeValType == UserDefinedValue.CHANNEL) + definitionKind = CellImpl.CHANNEL; + else if (typeValType == UserDefinedValue.CELL) + definitionKind = CellImpl.CELL; + else if (typeValType == UserDefinedValue.ALIAS_CELL) + definitionKind = CellImpl.ALIAS_CELL; + else { + Debug.assertTrue + (typeValType == UserDefinedValue.ATTRIBUTES_CELL); + definitionKind = CellImpl.ATTRIBUTES_CELL; + } + + // 9 + subCell = new CellImpl( + envContainer == null ? + typeName : envContainer.getType() + "_" + typeName + "Env", + moduleName, definitionKind, + ((ASTWithInfo) typeVal.getBody()).getFilename()); + opt.beginCellConstruction(subCell); + if (opt.bug7068HackEnabled()) { + bug7068Warnings.addLast(new TreeSet()); + } + for (final Iterator i = metaParams.iterator(); i.hasNext(); ) { + final MetaParamDefinition metaParam = + (MetaParamDefinition) i.next(); + subCell.addMetaParamDefinition(metaParam); + } + + // <+ inherit top-level constants from attributes cells + final LocalEnvironment childCellConstants = new LocalEnvironment(); + if (inheritanceCellConstantsList != null) { + final Iterator j = inheritanceCellList.iterator(); + for (Iterator i = inheritanceCellConstantsList.iterator(); + i.hasNext(); ) { + final CellImpl inheritanceCell = (CellImpl) j.next(); + try { + final Environment inheritedEnv = + (Environment) i.next(); + inheritedConstants.absorbEnv(inheritedEnv); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException + ("trouble importing the top-level constants " + + "of the <+ inheritance parent " + + inheritanceCell.getFullyQualifiedType(), + e, errorAST); + } + } + } + + // <: inherit top-level constants from refinement parent + if (parentCellConstants != null) { + try { + inheritedConstants.absorbEnv(parentCellConstants); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException + ("trouble importing the top-level constants " + + "of the <: refinement parent", + e, errorAST); + } + } + + final boolean childHadPorts; + if (portParamList == null) { + childHadPorts = false; + } else { + childHadPorts = true; + final Environment childPortEnv; + if (typeVal.isPortListInherited() && envUDV == null) { + Environment parentPortEnv = + typeVal.getPortEnvironment(tupleVal); + if (parentPortEnv == null) { + parentPortEnv = + parentUDV.getPortEnvironment(parentMetaParamsTuple); + typeVal.putPortEnvironment(tupleVal, parentPortEnv); + } + childPortEnv = new BlockEnvironment(parentPortEnv, localEnv); + } else if (envUDV != null && envContainer != null) { + Environment envPortEnv = typeVal.getPortEnvironment(tupleVal); + if (envPortEnv == null) { + envPortEnv = + envUDV.getPortEnvironment( + fromMetaParam(envUDV, envContainer)); + typeVal.putPortEnvironment(tupleVal, envPortEnv); + } + childPortEnv = new BlockEnvironment(envPortEnv, localEnv); + } else { + childPortEnv = paramEnv; + typeVal.putPortEnvironment(tupleVal, portEnv); + } + portParamList(portParamList, childPortEnv, subCell, portList, null, + reverseDir); + } + + // 10 + if (refinementParent != null) {// Give the child the proper port param list + // Need to compare the child and parent lists before binding anything. + if (!childHadPorts) { + // the port list in the refinement child is optional, if it is + // exactly the same as the port list of the parent + final Environment parentPortEnv = + parentUDV.getPortEnvironment(parentMetaParamsTuple); + portParamList(parentPortParamList, + new BlockEnvironment(parentPortEnv, localEnv), + subCell, portList, null, reverseDir); + typeVal.updatePortParamList(parentPortParamList); + typeVal.putPortEnvironment(tupleVal, parentPortEnv); + } + final boolean childHadImpliedPorts; + if (impliedPortParamList == null) { + childHadImpliedPorts = false; + } else { + childHadImpliedPorts = true; + portParamList(impliedPortParamList, paramEnv, + subCell, impliedPortList, impliedPortParentNodes, false); + } + if (! childHadImpliedPorts) { // Adopt from parent + portParamList(parentImpliedPorts, paramEnv, + subCell, impliedPortList, impliedPortParentNodes, false); + typeVal.updateImpliedPortParamList(parentImpliedPorts); + } + else { + // Check to make sure the parent implied port list is empty + // or the implied lists agree + if (parentImpliedPorts.getFirstChild() != null && + !impliedPortParamList.equalsTree(parentImpliedPorts)) { + throw semanticWrapperException( + new RefinementException( + "implied port parameter lists differ", + typeName, + refinementName), + errorAST); + } + } + + final boolean childHadExtraPorts; + if (envExtraPortParamList == null) { + childHadExtraPorts = false; + } else { + childHadExtraPorts = true; + portParamList(envExtraPortParamList, paramEnv, subCell, null, + null, false); + } + if (parentEnvExtraPorts != null) { + if (! childHadExtraPorts) { + portParamList(parentEnvExtraPorts, paramEnv, subCell, null, + null, false); + } + else { + // Check to make sure the parent extra port list is empty + // or the implied lists agree + if (parentEnvExtraPorts.getFirstChild() != null && + !envExtraPortParamList.equalsTree(parentEnvExtraPorts)) { + throw semanticWrapperException( + new RefinementException( + "env extra port parameter lists differ", + typeName, + refinementName), + errorAST); + } + } + } + + } + else { + // No refinement, go ahead and process implied ports + if (impliedPortParamList != null) { + portParamList(impliedPortParamList, paramEnv, subCell, + impliedPortList, impliedPortParentNodes, false); + } + if (envExtraPortParamList != null) { + portParamList(envExtraPortParamList, paramEnv, subCell, null, + null, false); + } + } + + // 11 protect the types of parameter arrays from being changed + // by the body, because the parameters and body are in the + // same environment to support this: "define Y()(T x[0..1]) { + // T x[2] = z; }". This might only be temporary. Later, when + // cflat compatability is not an issue, we can do: "T y[0..2] = + // x @ { z };" + if (typeValType != UserDefinedValue.CHANNEL) { + // childCellConstants will be changed by the call to block() + final BlockEnvironment bodyEnvironment = + new FixedBlockEnvironment(paramEnv.protectedArrayEnvironment(), + childCellConstants); + + // chain the <+ prs environments + if (inheritancePrsEnvList != null) + parentPrsEnvironment = + chainEnvironments(inheritancePrsEnvList, + parentPrsEnvironment); + + final LocalEnvironment localPrsEnvironment = + new LocalEnvironment(); + final Environment childPrsEnvironment = + spliceEnvironments(childCellConstants, + paramEnv.protectedArrayEnvironment(), + parentPrsEnvironment, + localPrsEnvironment); + + // chain the <+ subcells/subtypes environments + if (inheritanceSubcellsEnvList != null) + parentSubcellsEnvironment = + chainEnvironments(inheritanceSubcellsEnvList, + parentSubcellsEnvironment); + + final LocalEnvironment localSubcellsEnvironment = + new LocalEnvironment(); + final Environment splicedSubcellsEnvironment = + spliceEnvironments(childCellConstants, + paramEnv.protectedArrayEnvironment(), + parentSubcellsEnvironment); + final Environment childSubcellsEnvironment = + new FixedBlockEnvironment(splicedSubcellsEnvironment, + localSubcellsEnvironment); + final Environment childSubtypesEnvironment = + new BlockEnvironment(splicedSubcellsEnvironment, + localSubcellsEnvironment); + + // Copy node subcells from parent to child. + // This is needed because setRefinementParent is not called + // until after we parse the child's body, but we must have + // the node subcells in the child cell in order for + // assignDefaultsToImpliedPorts to work if one of the implied + // ports was inherited from the parent. + // We should really figure out a way to do setRefinementParent + // before we parse the body. --jmr + if (parentCell != null) + subCell.inheritNodes(parentCell); + + // Make cell constants visible to the environment block. + final BlockEnvironment paramConstantEnv = + new BlockEnvironment( + new SplicingEnvironment(paramEnv, childCellConstants)); + + // Treeparse the body of the cell + activeUDV.addLast(typeVal); + block(typeVal.getBody(), bodyEnvironment, subCell, envContainer, + paramConstantEnv, childPrsEnvironment, + childSubcellsEnvironment, childSubtypesEnvironment); + if (metaParams.isEmpty()) typeVal.clearBody(); + activeUDV.removeLast(); + + // Archive the cell-level constants. + typeVal.putCellConstants(tupleVal, + new SplicingEnvironment(inheritedConstants, + childCellConstants)); + + final Environment paramWithoutBodyEnv = + new BlockEnvironment( + new BlockEnvironment(inheritedConstants, metaEnv), + localEnv.protectedArrayEnvironment()); + + // Archive the prs environment + final Environment splicedPrs = + spliceEnvironments(childCellConstants, paramWithoutBodyEnv, + parentPrsEnvironment, localPrsEnvironment); + typeVal.putPrsEnvironment(tupleVal, + opt.bug7068HackEnabled() ? + new Bug7068Environment(splicedPrs, + childPrsEnvironment) + : splicedPrs); + + // Archive the subcells/subtypes environment + final Environment splicedSubcells = + spliceEnvironments(childCellConstants, paramWithoutBodyEnv, + parentSubcellsEnvironment, + localSubcellsEnvironment); + typeVal.putSubcellsEnvironment(tupleVal, + opt.bug7068HackEnabled() ? + new Bug7068Environment(splicedSubcells, + childSubcellsEnvironment) + : splicedSubcells); + } + else { + try { + paramEnv.absorbEnv(parentAliases); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException + ("trouble importing the aliases of the refinement parent", + e, errorAST); + } + final LocalEnvironment localAliases = + channelBody(typeVal.getBody(), paramEnv, subCell); + if (metaParams.isEmpty()) typeVal.clearBody(); + final LocalEnvironment childAliases = + localAliases == null ? parentAliases : localAliases; + if (childAliases != parentAliases) { + try { + childAliases.absorbEnv(parentAliases); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException + ("child redeclares aliases defined in refinement parent", + e, errorAST); + } + } + typeVal.putAliases(tupleVal, childAliases); + } + + try { + // finish <+ inheritance handling + if (inheritanceCellList != null) { + for (Iterator i = inheritanceCellList.iterator(); + i.hasNext(); ) { + final CellImpl inheritanceCell = (CellImpl) i.next(); + subCell.setInheritance(inheritanceCell); + } + } + + // 12 + if (refinementParent != null) { + // Ports should match or the parent port list should be null. + boolean portsMatched = false; // Initialized to placate the compiler + Symbol[] refinedPorts = (Symbol [])portList.toArray(new Symbol[0]); + Symbol[] parentPorts = parentInstance.getPortParams(); + if (refinedPorts.length != parentPorts.length) { + if (parentPorts.length == 0) { + portsMatched = false; + } + else { + throw new RefinementException("mismatch between the "+ + "lengths of port lists", typeName, refinementName); + } + } + else if (!childHadPorts) { + // if the child has no ports, then the ports are copied + // from the parent, so there cannot be any mismatch + portsMatched = true; + } + else { + AST currentPort = portParamList.getFirstChild(); + for (int i=0; iinheritanceEnvList. Symbols in environments with + * lower indices take priority. Helper function for + * generateAndAttachCell. + **/ + private Environment chainEnvironments(final ArrayList inheritanceEnvList, + Environment parentEnv) { + // chain the <+ environments + for (int i = inheritanceEnvList.size(); --i >= 0; ) { + final Environment inheritanceEnv = + (Environment) inheritanceEnvList.get(i); + parentEnv = new SplicingEnvironment(parentEnv, inheritanceEnv); + } + + return parentEnv; + } + + private Environment spliceEnvironments(final Environment e1, + final Environment e2, + final Environment e3) { + return new SplicingEnvironment( + // parent + e3, + // local + new SplicingEnvironment(e2, e1)); + } + + /** + * Returns a new environment with all symbols defined in + * the three environments. Symbols in e1 take precedence + * over those in e2, etc. Helper function for + * generateAndAttachCell. + **/ + private Environment spliceEnvironments(final Environment e1, + final Environment e2, + final Environment e3, + final LocalEnvironment le) { + return new FixedBlockEnvironment(spliceEnvironments(e1, e2, e3), le); + } + + // TODO: make this a method on PortTypeInterface to avoid the ugly elseifs + private PortTypeInterface substituteChannelWidth( + final ParamTypeInterface type, + final int width, + final ASTWithInfo errorAST) + throws SemanticException { + if (type instanceof ArrayType) { + final ArrayType arrayType = (ArrayType) type; + return new ArrayType( + substituteChannelWidth(arrayType.getArrayedType(), width, errorAST), + arrayType.getMinIndex(), arrayType.getMaxIndex()); + } else if (type instanceof ChannelType) { + final ChannelType channelType = (ChannelType) type; + + Debug.assertTrue(channelType.getWidth() == 1); + return new ChannelType(channelType.iterator(), + channelType.getTypeName(), width); + } else if (type instanceof NodeType) { + final NodeType nodeType = (NodeType) type; + + Debug.assertTrue(nodeType.getWidth() == 1); + return new NodeType(width); + } else if (type instanceof StructureType) { + final StructureType structureType = (StructureType) type; + return new ArrayType(structureType, 0, width-1); + } else { + throw semanticWrapperException("Type " + type + + " not a channel type and hence unsuitable for channel" + + " width specification.", new Exception(), errorAST); + } + } + + /** + * Similar to CastTwoParser's syntaxError(). Takes a message and + * an AST for location information, spits out a warning. + * Eventually will turn into exceptions or some other method of + * halting parsing. + **/ + private void syntaxError(String message, ASTWithInfo ast) { + if (verbose) { + System.err.println("SYNTAX: " + ast.getFilename() + ": " + + ast.getLine() + ": " + message); + } + } + + /** Prints message and dies. **/ + private void fatalError(String message, ASTWithInfo ast) { + System.err.println("fatal error in " + ast.getFilename() + " at " + + ast.getLine() + ":" + ast.getColumn() + ":"); + System.err.println(message); + System.exit(1); + } + + /** + * Binds the symbol to the value in the environment, properly + * augmenting if the symbol is already bound to an array that can + * be augmented by the new value + **/ + private void bindAndAugment(Environment env, Symbol sym, Value v, + ASTWithInfo errorAST, boolean aliasP) + throws SemanticWrapperException { + try { + env.bind(sym, v); + } catch (SymbolRedeclaredException e) { + // it could be a sparse array, check + + // 1: get the old value + final Value vOld = lookup(env, sym, errorAST); + + // 2: The old and new values must both be arrays. + if (!(v instanceof ArrayValue && vOld instanceof ArrayValue)) + throw semanticWrapperException("variable " + sym.getString() + + " redeclared", e, errorAST); + + // this function is called twice for each declaration in an alias + // block; don't augment during the second call, since the same + // ArrayValue object must have been successfully augmented already + // in the previous call + if (!aliasP) { + final ArrayValue av = (ArrayValue) v; + final ArrayValue avOld = (ArrayValue) vOld; + + // 3: attempt to augment the array with the new indices + // this may fail if: + // the element types are not the same + // the dimensions don't agree + // the indices are not disjoint + try { + avOld.augment(av); + } catch (InvalidOperationException ee) { + throw semanticWrapperException("Unable to augment sparse" + + " array " + sym.getString(), ee, errorAST); + } + } + } + } + + private static SequentialStatement makeCSPConstantInitializers + (final Environment env) throws InvalidOperationException { + final SequentialStatement stmt = new SequentialStatement(); + for (EnvironmentEntryIterator iEE = env.entryIterator(); + iEE.hasNext(); ) { + final EnvironmentEntry entry = (EnvironmentEntry) iEE.next(); + final String name = entry.getName().getString(); + final Value val = entry.getValue(); + + final IdentifierExpression lhs = new IdentifierExpression(name); + if (val instanceof BoolValue || val instanceof IntValue) { + // jikes 1.17 thinks these can't be final + /*final*/ com.avlsi.csp.ast.Type type; + /*final*/ ExpressionInterface initExpr; + if (val instanceof BoolValue) { + final BoolValue bv = (BoolValue) val; + // System.out.println("bool " + name + " = " + + // bv.getValue()); + type = new BooleanType(true); + initExpr = + new BooleanExpression(bv.getValue()); + } else { + final IntValue iv = (IntValue) val; + // System.out.println("int " + name + " = " + + // iv.getValue()); + type = new IntegerType(true); + initExpr = + new IntegerExpression(iv.getValue().toString(), 10); + } + + // make the DeclaratorList for the VarStatement + final DeclaratorList declList = new DeclaratorList(); + final Declarator declarator = + new Declarator(lhs, null, initExpr); + declList.addDeclarator(declarator); + + // make the VarStatement and add it + stmt.addStatement + (new VarStatement(new Declaration(declList, type))); + } else if (val instanceof ArrayValue) { + final ArrayValue av = (ArrayValue) val; + final SubscriptSpecInterface spec = av.getSpec(); + if (spec instanceof DenseSubscriptSpec) { + final DenseSubscriptSpec denseSpec = + (DenseSubscriptSpec) spec; + + // get the base type + com.avlsi.csp.ast.Type type; + if (av.getElementType() == IntValue.TYPE) { + // System.out.println("int[] " + name); + type = new IntegerType(true); + } else if (av.getElementType() == BoolValue.TYPE) { + // System.out.println("bool[] " + name); + type = new BooleanType(true); + } else { + continue; + } + + // build up the array type + final int nDims = denseSpec.getNumDimensions(); + for (int i = nDims; --i >= 0; ) { + final Range r = denseSpec.getRange(i); + type = new com.avlsi.csp.ast.ArrayType + (new com.avlsi.csp.ast.Range + (new IntegerExpression(r.getMin()), + new IntegerExpression(r.getMax())), + type); + } + + // declare the array + final DeclaratorList declList = new DeclaratorList(); + final Declarator declarator = + new Declarator(lhs, null, null); + declList.addDeclarator(declarator); + stmt.addStatement + (new VarStatement(new Declaration(declList, type))); + + // fill in all the values + final int nVals = denseSpec.getNumElements(); + for (int i = 0; i < nVals; ++i) { + final int[] idx = spec.indexOf(i); + final Value v = av.accessArray(idx); + stmt.addStatement + (new AssignmentStatement + (makeArrayLHS(name, idx), makeCSPValue(v))); + } + } + } + } + + return stmt; + } + + private static ExpressionInterface makeArrayLHS(String name, int[] idx) { + ExpressionInterface lhs = new IdentifierExpression(name); + + final int nDims = idx.length; + for (int i = 0; i < nDims; ++i) { + lhs = new ArrayAccessExpression(lhs, + new IntegerExpression(idx[i])); + } + + return lhs; + } + + private static ExpressionInterface makeCSPValue(Value val) + throws InvalidOperationException { + if (val instanceof BoolValue) { + final BoolValue bv = (BoolValue) val; + return new BooleanExpression(bv.getValue()); + } else { + final IntValue iv = (IntValue) val; + return new IntegerExpression(iv.getValue().toString(), 10); + } + } + + /** + * Given a pair of HierNames which represent Nodes (although they + * may be in arrays, in which case the relevant NodeValues won't + * exist) into a BooleanExpressionInterface which can either + * become the guard of a production rule or be combined with other + * BooleanExpressionInterfaces to become the guard. + **/ + private BooleanExpressionInterface makeAssertPair(final Environment env, + final int hiLo, + final HierName node1, + final HierName node2, + final ASTWithInfo errorAST) + throws SemanticWrapperException { + final List nodes = new ArrayList(2); + nodes.add(0, new HierNameAtomicBooleanExpression(true, node1)); + nodes.add(1, new HierNameAtomicBooleanExpression(true, node2)); + + if (hiLo == ExclusiveNodeSet.HI) { + return new AndBooleanExpression(true, nodes); + } else if (hiLo == ExclusiveNodeSet.LO) { + return new OrBooleanExpression(true, nodes); + } else { + throw new AssertionFailure("Invalid hiLo value: " + hiLo); + } + } + + /** + * Given a list of BooleanExpressionInterfaces representing pairs + * of nodes (see comment inside assertExclStatement[]) and the + * exclusivity type, produces an asserted production rule. + **/ + private ProductionRule makeAssertRule(final int hiLo, + final List guards) { + if (hiLo == ExclusiveNodeSet.HI) { + final BooleanExpressionInterface guard = new OrBooleanExpression(true, guards); + return new ProductionRule(guard, HierName.makeHierName("ERROR!"), + HierName.makeHierName("GND!"), + ProductionRule.UP, false, false, false, + false, 100, false); + } + else if (hiLo == ExclusiveNodeSet.LO) { + final BooleanExpressionInterface guard = new AndBooleanExpression(false, guards); + return new ProductionRule(guard, HierName.makeHierName("ERROR!"), + HierName.makeHierName("GND!"), + ProductionRule.UP, false, false, false, + false, 100, false); + } else { + throw new AssertionFailure("Invalid hiLo value: " + hiLo); + } + } + + private static String modulizeOldJavaChannel(String channelDecl) { + final int idx = channelDecl.indexOf('('); + if (idx == -1 || idx == channelDecl.length() - 1) + return channelDecl; + else + return channelDecl.substring(0, idx + 1) + + "standard.channel." + + channelDecl.substring(idx + 1); + } + + private ASTWithInfo parseDumbBlockAs(final ASTWithInfo info, + final CastTwoUtil.ParserFactory f) + throws RecognitionException, TokenStreamException { + return (ASTWithInfo) + CastTwoUtil.parseStringAs(info.getText(), info.getLine(), + info.getColumn(), info.getFilename(), + verbose, f); + } + + private void parseDumbBlockAs(final ASTWithInfo info, + final CastTwoUtil.ParserFactory f, + final CastTwoUtil.ParserCallback cb) + throws RecognitionException, TokenStreamException { + CastTwoUtil.parseStringAs(info.getText(), info.getLine(), + info.getColumn(), info.getFilename(), + verbose, f, cb); + } + + private void parseDirectives(final String s, final int lineNum, + final int column, final String filename, + final Environment env, final String type, + final BlockInterface parent) + throws RecognitionException { + final DirectiveParser parser = + new DirectiveParser(new StringReader(s), new DirectiveFactory(), + lineNum, column - 1, filename); + final DirectiveStatement[] statements; + try { + statements = parser.parseStatements(); + } catch (IOException e) { + throw semanticWrapperException("IOException while parsing directive block", e, filename, lineNum, column); + } catch (DirectiveSyntaxException e) { + throw semanticWrapperException(e, e.getFilename(), e.getLine(), + e.getColumn()); + } + final DirectiveImpl impl = + new DirectiveImpl(type, env, directiveErrHandler); + for (int i = 0; i < statements.length; ++i) { + statements[i].visit(impl); + } + parent.iterator(BlockInterface.DIRECTIVE).merge(new DirectiveBlock(impl.getDirectiveInterface())); + } + + private void initializeImpliedPorts(final Value v, final CellImpl cell, + final ASTWithInfo errorAST) + throws RecognitionException { + if (v instanceof InstanceValue) { + try { + ((InstanceValue) v).assignDefaultsToImpliedPorts(cell); + } catch (InvalidOperationException e) { + throw semanticWrapperException("unable to bind implied ports to defaults", e, errorAST); + } + } else if (!opt.bug3771HackEnabled() && v instanceof ArrayValue) { + for (Iterator i = ((ArrayValue) v).getIterator(); i.hasNext(); ) { + initializeImpliedPorts((Value) i.next(), cell, errorAST); + } + } + } + + public Value expr(AST ast, Environment env, boolean anonymousAllowedP) + throws RecognitionException { + return expr(ast, env, anonymousAllowedP, false); + } + + public TupleValue expressionList(AST ast, Environment env, + boolean anonymousAllowedP) + throws RecognitionException { + return expressionList(ast, env, anonymousAllowedP, false); + } + + public Value expression(AST ast, Environment env, boolean anonymousAllowedP) + throws RecognitionException { + return expression(ast, env, anonymousAllowedP, false); + } + + + private interface Binder { + Value lookup() throws AmbiguousLookupException, + InvalidOperationException; + void bind(Value v) throws SymbolRedeclaredException, + InvalidOperationException; + } + + private static class SimpleBinder implements Binder { + private final Environment env; + private final Symbol sym; + public SimpleBinder(final Environment env, final Symbol sym) { + this.env = env; + this.sym = sym; + } + public Value lookup() throws AmbiguousLookupException, + InvalidOperationException { + return env.lookup(sym); + } + public void bind(Value v) throws SymbolRedeclaredException, + InvalidOperationException { + env.bind(sym, v); + } + } + + private static class ArrayBinder implements Binder { + private final ArrayValue val; + private final SubscriptSpecInterface index; + public ArrayBinder(final ArrayValue val, + final SubscriptSpecInterface index) { + this.val = val; + this.index = index; + } + public Value lookup() throws AmbiguousLookupException, + InvalidOperationException { + return val.accessArray(index); + } + public void bind(Value v) throws SymbolRedeclaredException, + InvalidOperationException { + val.replaceArray( + new ArrayValue(new Value[] { v }, index, + val.getInstanceName(), false)); + } + } + + private static class TrivialParserCallback + implements CastTwoUtil.ParserCallback { + public void bodyStatement(final ASTWithInfo ast) + throws RecognitionException {} + public void ifStart(final ASTWithInfo expr) + throws RecognitionException {} + public void ifEnd() throws RecognitionException {} + public void loopStart(final ASTWithInfo ident, final ASTWithInfo range) + throws RecognitionException {} + public void loopEnd() throws RecognitionException {} + } + + private class SubcellsParserCallback extends TrivialParserCallback { + private final Environment env; + private final CellImpl cell; + SubcellsParserCallback(final Environment env, + final CellImpl cell) { + this.env = env; + this.cell = cell; + } + + public void bodyStatement(final ASTWithInfo ast) + throws RecognitionException { + CastTwoTreeParser.this.subcellsStatements(ast, env, cell); + } + } + + private class SubtypesParserCallback extends TrivialParserCallback { + private final Environment env; + private final Map copied; + private final CellImpl cell; + SubtypesParserCallback(final Environment env, + final Map copied, + final CellImpl cell) { + this.env = env; + this.copied = copied; + this.cell = cell; + } + + public void bodyStatement(final ASTWithInfo ast) + throws RecognitionException { + CastTwoTreeParser.this.subtypesStatements(ast, env, copied, cell); + } + } +} + +goal[CellImpl cell, String moduleName, LinkedList fileList] +returns [Environment exportedEnv] + { + exportedEnv = null; + Debug.assertTrue(cpe != null); + // We'd like to be able to assert this, but it breaks + // parsing by file name in jflat, and possibly other places + // Debug.assertTrue(moduleName != null, + // "Not parsed via fully qualified name"); + } + : exportedEnv=compilationUnit[cell, moduleName, fileList] + EOF + ; + +compilationUnit[CellImpl cell, + String instantiatorModuleName, + LinkedList fileList] +returns [Environment exportedEnv] + { + exportedEnv = null; + final ImportEnvironment importEnv = cpe.newImportEnvironment(); + final TopLevelEnvironment env = new TopLevelEnvironment(importEnv); + } + : ( moduleDeclaration[instantiatorModuleName] ) + ( importDeclaration[cell, importEnv, fileList] )* + ( globalBodyStatement[env, cell] + | typeDeclaration[env, false] + | channelDeclaration[env] + | aliasDeclaration[env] + )* + { exportedEnv = env.getExportedEnvironment(); } + ; + +moduleDeclaration[String instantiatorModuleName] + : #( m:MODULE id:IDENT ) + { + moduleName = id.getText(); + if (instantiatorModuleName != null && + !instantiatorModuleName.equals(moduleName)) { + final SemanticException se + = new SemanticException("Declared module name '" + + moduleName + + "' doesn't match instantiator module name '" + + instantiatorModuleName + '\'', + id.getFilename(), id.getLine(), id.getColumn()); + se.column = id.getColumn(); + throw se; + } + } + ; + +importDeclaration[CellImpl cell, ImportEnvironment importEnv, + LinkedList fileList] + : #( IMPORT id:IMPORT_IDENT ) + { + final String imported; + imported = id.getText(); + int lastDot = imported.lastIndexOf('.'); + Debug.assertTrue(lastDot != -1); + + final String moduleName = imported.substring(0, lastDot); + String cellName = imported.substring(lastDot + 1); + if (cellName.equals("*")) cellName = null; + + try { + final Environment parsed = cellName == null ? + // all cells in file + cpe.parseModule(fileList, moduleName) : + cpe.parseCell(fileList, moduleName, cellName); + if (cellName == null) { + importEnv.addEnvironment(parsed); + } + else { + final Environment cellEnv = new LocalEnvironment(); + Symbol cellSymbol = Symbol.create(cellName); + try { + cellEnv.bind(cellSymbol, lookup(parsed, cellSymbol, id)); + } + catch (SymbolRedeclaredException e) { + throw semanticWrapperException(e, id); + } + importEnv.addEnvironment(cellEnv); + } + } catch (CircularImportException e) { + throw semanticWrapperException("Circular import of " + + e.getCurrentImport() + "; " + "already imported " + + e.getImportedFiles(), e, id); + } catch (SelfImportException e) { + warn("Warning: self-import " + imported, id); + } catch (FileNotFoundException e) { + throw semanticWrapperException("Import not found: " + + imported, e, id); + } catch (IOException e) { + throw semanticWrapperException("Error in import", e, id); + } catch (antlr.RecognitionException e) { + throw semanticWrapperException("Error in import", e, id); + } catch (antlr.TokenStreamException e) { + throw semanticWrapperException("Error in import", e, id); + } + } + ; + +// bodyStatementLists don't appear at the top level +// pass globalP == false to bodyStatement +// +// See block[] for description of prsEnv +// +// paramEnv can be null if an env block is not allowed at this level. +// Otherwise it's the environment in which the metaparameters, ports, +// and implied ports of cell are bound, but none of the body of cell. +// It's read-only. +bodyStatementList[Environment env, CellImpl cell, CellInterface envContainer, + BlockEnvironment paramEnv, Environment prsEnv, + Environment subcellsEnv, Environment subtypesEnv] + : #( BODY_STATEMENT_LIST + ( bodyStatement[env, false, cell, envContainer, paramEnv, prsEnv, + subcellsEnv, subtypesEnv] )* ) + ; + +globalBodyStatement[Environment env, CellImpl cell] + : bodyStatement[env, true, cell, null, null, null, null, null] + ; + +// globalP: whether the body statement is at a global level +// +// See block[] for description of prsEnv +// +// paramEnv can be null if an env block is not allowed at this level. +// Otherwise it's the environment in which the metaparameters, ports, +// implied ports, and constants of cell are bound, but none of the body of +// cell. It's read-only. +bodyStatement[Environment env, boolean globalP, CellImpl cell, + CellInterface envContainer, BlockEnvironment paramEnv, + Environment prsEnv, Environment subcellsEnv, + Environment subtypesEnv] + { + //boolean processEnv = !globalP && null != + // ((UserDefinedValue) activeUDV.getLast()).getEnvironmentContainer(); + boolean processEnv = envContainer != null; + BlockInterface dirBlock = processEnv ? + cell.getBlockInterface().iterator(BlockInterface.ENV).next() + : cell.getBlockInterface(); + } + : prs:prsBlock[prsEnv, cell] + { if (cell.containsSubcells()) + fatalError("shouldn't have prs and subcells in the same cell", + prs); + } + | subs:subcellsBlock[subcellsEnv, cell] + { if (cell.containsCompletePrs() || cell.containsFragmentPrs()) + fatalError("shouldn't have prs and subcells in the same cell", + subs); + } + | cspBlock[env, cell, envContainer] + | envBlock[cell, paramEnv] + | javaBlock[new FixedBlockEnvironment(env), cell, !processEnv] + | netlistBlock[new FixedBlockEnvironment(env), cell] + | directiveBlock[env, dirBlock, + processEnv ? BlockInterface.ENV : BlockInterface.CELL ] + | block[new FixedBlockEnvironment(env), cell, envContainer, null, null, + null, null] + | variableDeclarationStatement[env, globalP, cell, envContainer, null, + false] + | loopStatement[env, cell, envContainer, paramEnv, prsEnv, subcellsEnv, + subtypesEnv] + | ifStatement[env, cell, envContainer, paramEnv, prsEnv, subcellsEnv, + subtypesEnv] + | assignmentStatement[env, cell] + | subtypesBlock[subtypesEnv, cell] + | verilogBlock[new FixedBlockEnvironment(env), cell] + ; + +// paramEnv can be null if an env block is not allowed at this level. +// Otherwise it's the environment in which the metaparameters, ports, +// and implied ports of cell are bound, but none of the body of cell. +// It's read-only. +// +// prsEnv can be null if a prs block is not allowed at this level. +// Otherwise it's the environment in which the production rules +// are defined. Its local environment is initially empty, but variables +// declared in prs blocks are added to it. Its parent environment +// has a local environment of the cell constants and a parent of +// the inheritance parent's prsEnv. +// NB: Multiple prs blocks go in the same environment with this +// implementation. We should probably allow only one prs block +// to hide this. +// +// env is the Environment block[] should be modifying. It may already +// have some values in it. When block[] finishes, env will contain +// any constants defined at the top-level of this block. +block[Environment env, CellImpl cell, CellInterface envContainer, + BlockEnvironment paramEnv, Environment prsEnv, Environment subcellsEnv, + Environment subtypesEnv] + : #( BLOCK bodyStatementList[env, cell, envContainer, paramEnv, prsEnv, + subcellsEnv, subtypesEnv] ) + ; + +// globalP: true if the variableDeclarationStatement occurs at the +// top-level (globally). If so, then a ! will be appended to the +// node name in primitiveType. +// aliasesEnv is null if this statement is anywhere but in an aliases block. +// In an aliases block it is the running accumulator of aliases to export +// prsP: true if this declaration is in a prs block. If so, then all +// subcell defns are automatically flattened +// envContainer: if processing an environment cell, the cell containing the +// environment, or null otherwise. +variableDeclarationStatement[Environment env, boolean globalP, CellImpl cell, + CellInterface envContainer, LocalEnvironment aliasesEnv, boolean prsP] + { final Pair p; Value vInit = null; String varName = null; + boolean inlineP = false, flattenP = prsP, aliasP = (aliasesEnv != null); } + : #( VAR_DECL id:IDENT { varName = generateName(id.getText()); } + ( INLINE { inlineP = true; } )? + ( FLATTEN { flattenP = true; } )? + p=type[env, cell, envContainer, HierName.makeHierName(varName), + globalP, inlineP, flattenP, id, LOCAL_VAR] + ( vInit=variableInitializer[env] )? ) + { + // Variables declared in the alias block must be + // externally accessible. The environment passed in to + // the alias block is the parameter environment for this + // reason. The call to type[] bound them externally. + final Symbol sym = Symbol.create(varName); + final Value v = (Value) p.getFirst(); + + if (aliasP && vInit == null) + throw semanticWrapperException("aliases must be initialized as part of their declaration", new Exception(), id); + + // NOTE that the environment is augmented after the initializer + // is walked + + bindAndAugment(env, sym, v, id, false); + if (aliasP) bindAndAugment(aliasesEnv, sym, v, id, true); + + final Value override = opt.getOverrideValue(cell, sym, vInit, env); + if (override != null) vInit = override; + + // assignment of value = tuple takes care of connections. + if (vInit != null) + assign(v, vInit, cell, id, "Incompatible types for " + + (override == null ? "initializer" : "overrider") + + " or port list."); + else + initializeImpliedPorts(v, cell, id); + } + ; + +// ASSIGN: returns a non-tuple expression +// PORT_LIST: returns a tuple expression or a pair of tuples (real and implied ports) +variableInitializer[Environment env] returns [Value v] + { v = null; + TupleValue implied = null; } + : #( ASSIGN v=expression[env, false] ) + | #( PORT_LIST + v=expressionList[env, true] + ( implied=expressionList[env, true] + { v = new TupleGroupValue((TupleValue)v, implied); } + )? + ) + ; + +// Returns the definitive pair of Value and ParamTypeInterface for type[], +// adjusting based on channel width if necessary. +setFinalWidth[Environment env, Pair baseTypePair, Pair arrayedPair] +returns [Pair p] + { + final Value baseValue = (Value) baseTypePair.getFirst(); + final Value startingValue; + final ParamTypeInterface baseParamType = (ParamTypeInterface) baseTypePair.getSecond(); + final ParamTypeInterface startingType; + final int startingDimensions; + final DenseSubscriptSpec s; + final int channelWidth; + final Value channelWidthValue; + } + : #( errorAST:CHANNEL_WIDTH + ( channelWidthValue=expr:expression[env,false] + | /* empty */ { channelWidthValue = null; } + ) + ) + { + // Dimensions before allowing for possible channel width + if (arrayedPair == null) { + s = null; + startingDimensions = 0; + startingValue = baseValue; + startingType = baseParamType; + } + else { + s = (DenseSubscriptSpec) arrayedPair.getFirst(); + startingDimensions = s.getNumDimensions(); + startingValue = ArrayValue.makeArray(baseValue, s); + startingType = (ParamTypeInterface) arrayedPair.getSecond(); + } + + // If channel didn't really have a width, leave it alone + if (channelWidthValue == null) + p = new Pair(startingValue, startingType); + else { + // Interpreting channel width + try { + channelWidth = ((IntValue) channelWidthValue).getValue().intValue(); + } catch (InvalidOperationException e) { + throw semanticWrapperException("error understanding channelwidth", + e, errorAST); + } + if (channelWidth < 1) + throw semanticWrapperException("channel width must be positive, not: " + channelWidth, new Exception(), errorAST); + else { + // augment the spec with the new dimension + Range[] newDimensions = new Range[startingDimensions + 1]; + for (int i=0; i +// ERROR-" (~guard -> ERROR+), because ERROR is already being driven +// low by default. +assertPrsStatement[Environment env, CellImpl cell] + { + BooleanExpressionInterface guard; + } + : guard=errorAST:prsExpression[env, false] + { + final HierName errorName = HierName.makeHierName("ERROR!"); + final HierName railName = HierName.makeHierName("GND!"); + final ProductionRule pr = + new ProductionRule(guard.negated(), errorName, railName, + ProductionRule.UP, false, false, false, + false, 100, false); + cell.getAssertedProductionRuleSet().addProductionRule(pr); + } + ; + +assertExclStatement[Environment env, CellImpl cell] + { int hiLo; List l; ASTWithInfo errorAST; } + : ( #( hi:EXCLHI l=assertExclNodes[env] { hiLo = ExclusiveNodeSet.HI; errorAST=hi; } ) + | #( lo:EXCLLO l=assertExclNodes[env] { hiLo = ExclusiveNodeSet.LO; errorAST=lo; } ) + | #( cc:EXCLCC l=assertExclNodes[env] { hiLo = ExclusiveNodeSet.CC; errorAST=cc; } ) + | #( nocc:NOCC l=assertExclNodes[env] { hiLo = ExclusiveNodeSet.NOCC; errorAST=nocc; } ) + ) + { + cell.getLocalExclusiveNodeSets().addExclusiveNodeSet(new ExclusiveNodeSet(hiLo, l)); + // Generate all the asserted production rules which + // correspond to the excl node set. + + // "assert { exclhi(a,b,c,d); }" corresponds to + // "assert { ~(a&b | a&c | a&d | b&c ...); }" + // "assert { excllo(w,x,y,z); }" corresponds to + // "assert { ((a|b) & (a|c) & ...); }" + + int numNodes = l.size(); + if (numNodes == 1 || hiLo == ExclusiveNodeSet.CC + || hiLo == ExclusiveNodeSet.NOCC) { + // One node is automatically exclhi and excllo with + // itself. It can be ignored. + + // Do not generate asserted rules for cap coupling. + } + else { + int position = 0; + // Will contain BooleanExpressionInterfaces + final List guards = new ArrayList(numNodes*(numNodes-1)/2); + for (int i=0; i= tupleVal.getSize()) { + int expected = 0; + AST child = f.getFirstChild(); + while (child != null) { + expected++; + child = child.getNextSibling(); + } + throw new InvalidOperationException("too few metaparameters: got " + tupleVal.getSize() + " and expected " + expected); + } + } + metaParam[env, metaParams, tupleVal.accessTuple(i++)] )* + ) + | /* nothing */ + ) + { + if (i != tupleVal.getSize()) + throw new InvalidOperationException("too many metaparameters: got " + tupleVal.getSize() + " and expected " + i); + } + ; + +// XXX: enforce that only int,bool,float can be meta-params +metaParam[Environment env, List metaParams, Value tv] +throws InvalidOperationException // If assignment of metas doesn't work + { Pair p; } + : #( VAR_DECL id:IDENT + p=type[env, null, null, HierName.makeHierName(id.getText()), false, + false, false, id, META_PARAM] ) + { + try { + final Value v = (Value) p.getFirst(); + final Symbol sym = generateSymbol(id.getText()); + env.bind(sym, v); + // cell is null because it shouldn't be used by assign + v.assign(tv, null); + + // save MetaParamDefinition for later addition to cell + metaParams.add(new MetaParamDefinition( + id.getText(), + ((MetaParamValueInterface) tv).toMetaParam())); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException("meta param " + id.getText() + + " redeclared ", e, id); + } + } + ; + +// modifies portList to contain a list of the variable names +// declared in the port parameter list, +// also modifies env by binding an uninitialized value to +// all the variables declared in the port list. +// env: the environment for the subcell +// impliedPortParentNodes: the neames of the nodes in the parent to +// which the implied ports should be connected, null if the port +// list is not an implied port list +// reverseDirection: whether to interpret - as output and + as input, which is +// the opposite of the usual interpretation; useful for constructing the port +// list of a environment cell +// Implied ports can only be nodes. +portParamList[Environment env, CellImpl cell, ArrayList portList, + ArrayList impliedPortParentNodes, boolean reverseDirection] + : #( FORMALS ( portParam[env, cell, portList, impliedPortParentNodes, + reverseDirection] )* ) + ; + +envExtraPortIdent[Environment env, StringBuffer buf] + : #( id:IDENT { + buf.append(id.getText()); + }) + | #( FIELD_ACCESS envExtraPortIdent[env, buf] fi:FIELD_IDENT ) { + buf.append('.'); + buf.append(fi.getText()); + } + | #( ARRAY_ACCESS envExtraPortIdent[env, buf] { buf.append('['); } + subtypesArraySelector[env, buf] { buf.append(']'); } ) + ; + +portParam[Environment env, CellImpl cell, ArrayList portList, + ArrayList impliedPortParentNodes, boolean reverseDirection] + { Pair p; boolean in = false , out = false; + StringBuffer buf = new StringBuffer(); + } + : #( VAR_DECL + id:IDENT + ( PLUS {if (reverseDirection) in=true; else out=true;} )? + ( MINUS {if (reverseDirection) out=true; else in=true;} )? + p=type[env, cell, null, HierName.makeHierName(id.getText()), false, + false, false, id, PORT_PARAM] + // :ident will only be there in the case of implied ports + ( COLON id2:IDENT )? + ( envExtraPortIdent[env, buf] )? + ) + { + final boolean impliedP = impliedPortParentNodes != null; + final boolean envExtraP = buf.length() > 0; + assert !impliedP || !envExtraP : + "Implied ports and env extra ports are mutually exclusive"; + try { + final Value v = (Value) p.getFirst(); + if (impliedP && ! (v instanceof NodeValue)) + throw semanticWrapperException("implied ports must be nodes", new Exception(), id); + final Symbol sym = generateSymbol(id.getText()); + env.bind(sym, v); + if (portList != null) portList.add(sym); + if (impliedP) { + final String parentNode = + id2 != null ? id2.getText() : id.getText(); + impliedPortParentNodes.add(parentNode); + cell.addImpliedPortMapping(id.getText(), parentNode); + } + if (envExtraP) { + cell.addEnvExtraPortMapping(id.getText(), buf.toString()); + } + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException("port param " + id.getText() + + " redeclared", e, id); + } + + // add port definition + if (! (p.getSecond() instanceof PortTypeInterface)) { + throw semanticWrapperException("invalid type for port: " + p.getSecond() + ". Ports should be nodes, channels, or arrays of same", new Exception(), id); + } + final PortTypeInterface portType = (PortTypeInterface) p.getSecond(); + final int dir = in ? (out ? PortDefinition.INOUT : PortDefinition.IN) + : (out ? PortDefinition.OUT : PortDefinition.NONE); + cell.addPortDefinition(new PortDefinition(id.getText(), portType, dir)); + } + ; + +// refactor: remove duplication with prsLoopStatement +loopStatement[Environment env, CellImpl cell, CellInterface envContainer, + BlockEnvironment paramEnv, Environment prsEnv, + Environment subcellEnv, Environment subtypesEnv] + { Range r; } + : #( LOOP id:IDENT r=range[env, true] slist:BODY_STATEMENT_LIST ) + { + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + bodyStatementList(slist, loopEnv, cell, envContainer, paramEnv, + prsEnv, subcellEnv, subtypesEnv); + } + } + ; + +// refactor: remove duplication with prsIfStatement +ifStatement[Environment env, CellImpl cell, CellInterface envContainer, + BlockEnvironment paramEnv, Environment prsEnv, + Environment subcellEnv, Environment subtypesEnv] + { Value v; } + : #( IF v=expr:expression[env, false] slist:BODY_STATEMENT_LIST ) + { + final BoolValue bv = ifGuard(v, expr); + + try { + if (bv.getValue()) + bodyStatementList(slist, env, cell, envContainer, paramEnv, + prsEnv, subcellEnv, subtypesEnv); + } catch (InvalidOperationException e) { + throw semanticWrapperException("If guard uninitialized.", + e, expr); + } + } + ; + +// fix me up later? +// ( = expr+ expr ) +assignmentStatement[Environment env, CellImpl cell] + { final ArrayList l = new ArrayList(), eList = new ArrayList(); + Value v0, vv; } + : #( ASSIGN v0=e0:expr[env, false] + ( vv=ee:expression[env, false] { l.add(vv); eList.add(ee);} )* ) + { + // xxx use the cell + + // change the * to a +, and this goes away! + Debug.assertTrue(l.size() > 0); + + for (int i = l.size() - 1; i > 0; --i) + assign((Value) l.get(i - 1), (Value) l.get(i), cell, + (ASTWithInfo) eList.get(i - 1), + "assignment failed"); + + assign(v0, (Value) l.get(0), cell, e0, "assignment failed"); + } + ; + +// returns a tuple, this will be converted to an array if needed +// anonymousAllowedP: true if anonymous variables (_) are allowed +// as expressions in the expressionList +expressionList[Environment env, + boolean anonymousAllowedP, + boolean deepP] returns [TupleValue v] + { final List l = new ArrayList(); Value ve; Range r = null; v = null; } + : #( EXPRESSION_LIST + ( + ve=expression[env, anonymousAllowedP, deepP] { l.add(ve); } + | ( id:IDENT r = range[env, true] expr:EXPRESSION_LIST ) { + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv = + new LoopEnvironment(env, sym, IntValue.valueOf(i)); + final TupleValue tv = + expressionList(expr, loopEnv, anonymousAllowedP, deepP); + for (int j = 0; j < tv.getSize(); ++j) { + try { + l.add(tv.accessTuple(j)); + } catch (InvalidOperationException e) { + throw semanticWrapperException(e, id); + } + } + } + } + )* + ) + { v = new TupleValue((Value []) l.toArray(new Value[0])); } + ; + +// anonymousAllowedP: true if anonymous variables (_) are allowed +// as expressions +expression[Environment env, boolean anonymousAllowedP, + boolean deepP] returns [Value v] + { v = null; } + : #( EXPRESSION v=expr[env, anonymousAllowedP, deepP] ) + ; + +// Used by CspCallback to verify channel types +arrayAccessExpr[Environment env] returns [Pair p] + { Value v; p = null; } + : #( o18:ARRAY_ACCESS v=expr[env, false] + p=arraySelector[env, null, false] ) + { p = new Pair(v, p.getFirst()); } + ; + +// anonymousAllowedP: true if anonymous variables (_) are allowed +// as expressions +// deepP: true if field access restrictions should not be observed; +// use with caution +expr[Environment env, boolean anonymousAllowedP, boolean deepP] +returns [Value v] + // logical + { Value v1, v2; v = null; ASTWithInfo t = null; + Range r; } + : #( o01:OR v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o01; v = v1.or(v2); } + | #( o02:AND v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o02; v = v1.and(v2); } + | #( o03:NOT v1=expr[env, false, deepP] ) + { t = o03; v = v1.not(); } + | #( oXOR:XOR v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = oXOR; v = v1.xor(v2); } + // arithmetic + | #( oExp:EXP v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = oExp; v = v1.pow(v2); } + | #( o04:PLUS v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o04; v = v1.add(v2); } + | #( o05:MINUS v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o05; v = v1.subtract(v2); } + | #( o06:TIMES v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o06; v = v1.multiply(v2); } + | #( o07:DIV v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o07; v = v1.divide(v2); } + | #( o08:MOD v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o08; v = v1.mod(v2); } + | #( o09:UNARY_PLUS v1=expr[env, false, deepP] ) + { t = o09; v = v1.unaryPlus(); } + | #( o10:UNARY_MINUS v1=expr[env, false, deepP] ) + { t = o10; v = v1.negate(); } + // relational + | #( o11:LT v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o11; v = v1.lt(v2); } + | #( o12:LE v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o12; v = v1.le(v2); } + | #( o13:EQ v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o13; v = v1.eq(v2); } + | #( o14:NE v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o14; v = v1.ne(v2); } + | #( o15:GE v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o15; v = v1.ge(v2); } + | #( o16:GT v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o16; v = v1.gt(v2); } + // selection + | #( o17:FIELD_ACCESS v1=expr[env, false, deepP] fi:FIELD_IDENT ) + { + t = o17; + if (! (v1 instanceof FieldedValueInterface)) + throw semanticWrapperException("can't access fields of value " + v, new Exception(), t); + v = ((FieldedValueInterface) v1).accessField( + Symbol.create(fi.getText()), + deepP ? FieldedValueInterface.ALL_PERMISSION + : FieldedValueInterface.INSTANCE_PERMISSION); + } + | { Pair p; } + #( o18:ARRAY_ACCESS v1=expr[env, false, deepP] + p=arraySelector[env, null, false] ) + { t = o18; v = ArrayValue.valueOf(v1).accessArray( + (SubscriptSpecInterface) p.getFirst()); } + // primary + | { v2 = null; } + id:IDENT ( v2 = expressionList[env, false] )? + { + t = id; + final String s = id.getText(); + + if (v2 == null) { + if (s.equals("_")) { + if (anonymousAllowedP) + v = new AnonymousValue(); + else { + final SemanticException se + = new SemanticException("_ not allowed here", + id.getFilename(), id.getLine(), id.getColumn()); + se.column = id.getColumn(); + throw se; + } + } else + v = lookup(env, Symbol.create(s), id); + } else { + v = Functions.invokeFunction(s, (TupleValue) v2); + } + } + | n:NUM_INT { t = n; v = IntValue.valueOf(n.getText()); } + | h:NUM_HEX { t = h; v = IntValue.hexValueOf(h.getText()); } + | f:NUM_REAL { t = f; v = FloatValue.valueOf(f.getText()); } + | o19:TRUE { t = o19; v = BoolValue.valueOf(true); } + | o20:FALSE { t = o20; v = BoolValue.valueOf(false); } + | #( o21:ARRAY v1=expressionList[env, false] ) + { t = o21; v = ArrayValue.fromTuple(v1); } + // prs stuff + /// XXX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // uhm!!! should be looking symbols up in symbol table!!!!!!! + | #( o22:PRS_AND v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o22; v = PRSExpressionValue.valueOf(v1).and(v2); } + | #( o23:PRS_OR v1=expr[env, false, deepP] v2=expr[env, false, deepP] ) + { t = o23; v = PRSExpressionValue.valueOf(v1).or(v2); } + | #( o24:PRS_NOT v1=expr[env, false, deepP] ) + { t = o24; v = PRSExpressionValue.valueOf(v1).not(); } + // merge these two into something like: + // LOOPED_OP ( AND | OR ) IDENT range EXPRESSION + | #( o25:LOOP_PRS_OR id2:IDENT r=range[env, true] e2:PRS_EXPRESSION ) + { v = new PRSExpressionValue( + new OrBooleanExpression(true, + loopedExpression(id2, r, env, e2))); } + | #( o26:LOOP_PRS_AND id3:IDENT r=range[env, true] e3:PRS_EXPRESSION ) + { v = new PRSExpressionValue( + new AndBooleanExpression(true, + loopedExpression(id3, r, env, e3))); } + | #( o27:LOOP_TIMES id4:IDENT r=range[env, true] e4:EXPRESSION ) + { final ASTWithInfo ast = e4; + t = o27; + v = loopedExpression(id4, r, env, e4, new CombineValue() { + public Value combine(final Value a, final Value b) + throws InvalidOperationException { + return a.multiply(b); + } + public Value identity() throws InvalidOperationException { + return IntValue.valueOf(1); + } + }); + } + | #( o28:LOOP_PLUS id5:IDENT r=range[env, true] e5:EXPRESSION ) + { final ASTWithInfo ast = e5; + t = o28; + v = loopedExpression(id5, r, env, e5, new CombineValue() { + public Value combine(final Value a, final Value b) + throws InvalidOperationException { + return a.add(b); + } + public Value identity() throws InvalidOperationException { + return IntValue.valueOf(0); + } + }); + } + | #( o28x:LOOP_XOR id6:IDENT r=range[env, true] e6:EXPRESSION ) + { final ASTWithInfo ast = e6; + t = o28x; + v = loopedExpression(id6, r, env, e6, new CombineValue() { + public Value combine(final Value a, final Value b) + throws InvalidOperationException { + return a.xor(b); + } + public Value identity() throws InvalidOperationException { + return IntValue.valueOf(0); + } + }); + } + | #( o28o:LOOP_OR id7:IDENT r=range[env, true] e7:EXPRESSION ) + { final ASTWithInfo ast = e7; + t = o28o; + v = loopedExpression(id7, r, env, e7, new CombineValue() { + public Value combine(final Value a, final Value b) + throws InvalidOperationException { + return a.or(b); + } + public Value identity() throws InvalidOperationException { + return IntValue.valueOf(0); + } + }); + } + | #( o28a:LOOP_AND id8:IDENT r=range[env, true] e8:EXPRESSION ) + { final ASTWithInfo ast = e8; + t = o28a; + v = loopedExpression(id8, r, env, e8, new CombineValue() { + public Value combine(final Value a, final Value b) + throws InvalidOperationException { + return a.and(b); + } + public Value identity() throws InvalidOperationException { + return IntValue.valueOf(-1); + } + }); + } + // cast expressions + | #( o29:BOOL v1 = expr[env, false, deepP] ) + { t = o29; v = BoolValue.castFrom(v1); } + | #( o30:INT v1 = expr[env, false, deepP] ) + { t = o30; v = IntValue.castFrom(v1); } + | #( o31:FLOAT v1 = expr[env, false, deepP] ) + { t = o31; v = FloatValue.castFrom(v1); } + | #( o32:NODE v1 = expr[env, false, deepP] ) + { t = o32; v = NodeValue.castFrom(v1); } + // alint scenario directives + | #( o33:ALINT_FANIN v = alintFanin[env] ) + { t = o33; } + ; + exception + catch [InvalidOperationException e] { + throw semanticWrapperException(e, t); + } + catch [ArithmeticException e] { + throw semanticWrapperException(e, t); + } + +// loopP indicates how a singleton range should be interpreted +// true: it will be interpreted as 0..n-1 +// false: it will be interpreted as n..n +range[Environment env, boolean loopP] returns [Range r] + { Value v1, v2 = null; r = null; } + : #( RANGE v1=e1:expression[env, false] + ( v2=e2:expression[env, false] )? ) + { + final int i1 = getInt(v1, e1); + + if (v2 == null) { + if (loopP) + r = new Range(0, i1 - 1); + else + r = new Range(i1, i1); + } else { + final int i2 = getInt(v2, e2); + + r = new Range(i1, i2); + } + } + ; + +// returns Pair of SubscriptSpecInterface and ArrayType or ArrayMetaParam +// metaParamP only matters if baseType != null +arraySelector[Environment env, ParamTypeInterface baseType, boolean metaParamP] +returns [Pair p] + { ArrayList l = new ArrayList(); p = null; } + : #( arrayExpr:ARRAY_SUB + ( {Range r;} r=rangeExpr:range[env, false] + { if (r.getMin() > r.getMax()) + throw semanticWrapperException + ("Array subscript minimum value of " + r.getMin() + + " is greater than maximum of " + r.getMax(), + new Exception(), arrayExpr); + l.add(r); + } + )* + ) + { + for (int i = l.size() - 1; i >= 0; --i) { + final Range r = (Range) l.get(i); + if (baseType != null) { + if (metaParamP) { + baseType = null; + /* baseType = new ArrayMetaParam( */ + /* (MetaParamTypeInterface) baseType, */ + /* r.getMin(), r.getMax()); */ + } else { + baseType = new ArrayType( + (PortTypeInterface) baseType, + r.getMin(), r.getMax()); + } + } + } + + p = new Pair( + new DenseSubscriptSpec((Range []) l.toArray(new Range[0])), + baseType); + } + ; + + +// +// PRS stuff +// + +prsBlock[Environment env, CellImpl cell] + { boolean isFragment = false; } + : #( prs:PRS ( FRAGMENT { isFragment=true; } )? ) + { + final ASTWithInfo prsAST; + try { + prsAST = parseDumbBlockAs(prs, CastTwoUtil.PRS_PARSER); + } catch (TokenStreamException e) { + throw semanticWrapperException("error parsing prs block", e, prs); + } + prsStatements(prsAST, env, cell); + + if (isFragment) + cell.setHasFragmentPrsBlock(); + else + cell.setHasCompletePrsBlock(); + + } + ; + +prsStatements[Environment env, CellImpl cell] + : #( BODY_STATEMENT_LIST ( prsStatement[env, cell] )* ) + ; + +prsStatement[Environment env, CellImpl cell] + : prsIfStatement[env, cell] + | prsLoopStatement[env, cell] + | prsAction[env, cell, cell.getProductionRuleSet(), false] + | directiveBlock[env, + cell.getBlockInterface() + .iterator(BlockInterface.PRS) + .next(), + BlockInterface.PRS] + | variableDeclarationStatement[env, false, cell, null, null, true] + | assignmentStatement[env, cell] + | assertBlock[env, cell] + ; + +// todo: refactor: remove duplication with ifStatement +prsIfStatement[Environment env, CellImpl cell] + { Value v; } + : #( IF v=expr:expression[env, false] prslist:BODY_STATEMENT_LIST ) + { + final BoolValue bv = ifGuard(v, expr); + + try { + if (bv.getValue()) + prsStatements(prslist, env, cell); + } catch (InvalidOperationException e) { + throw semanticWrapperException("If guard uninitialized.", + e, expr); + } + } + ; + +// todo: refactor, remove duplication with loopStatement +prsLoopStatement[Environment env, CellImpl cell] + { Range r; } + : #( LOOP id:IDENT r=range[env, true] prslist:BODY_STATEMENT_LIST ) + { + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + prsStatements(prslist, loopEnv, cell); + } + } + ; + +prsAction[Environment env, CellImpl cell, ProductionRuleSet prs, boolean deepP] + { ProductionRule pr1, pr2 = null; } + // merge these + : ( #( ARROW pr1=prsActionBody[env, cell, deepP] ) + | #( celem:CELEM_ARROW pr1=pab:prsActionBody[env, cell, deepP] ) + { pr2 = + pr1.cElementComplement( + oppositePowerSupply(env, pr1.getPowerSupply(), celem)); } + | #( comb:COMB_ARROW pr1=prsActionBody[env, cell, deepP] ) + { pr2 = + pr1.combinationalComplement( + oppositePowerSupply(env, pr1.getPowerSupply(), comb)); } + ) { prs.addProductionRule(pr1); + if (pr2 != null) + prs.addProductionRule(pr2); + } + ; + +prsActionBody[Environment env, CellImpl cell, boolean deepP] +returns [ProductionRule pr] + { + Value av, rhsv; + BooleanExpressionInterface be; + boolean isochronicP = false, unstabP = false, timedP = false; + boolean metastableP = false; + int afterTimeSteps = -1; // negative means unspecified -- AML + int dir; + ASTWithInfo exp; + boolean afterPs = false; + } + : ( ISOCHRONIC {isochronicP = true;} )? + ( UNSTAB {unstabP = true;} | METASTABLE { metastableP = true; } )? + ( ( AFTER | AFTER_PS { afterPs = true; } ) av=e:expression[env, false] + { afterTimeSteps = getInt(av, e); } )? + be=prsExpression[env, deepP] rhsv=e2:expr[env, false, deepP] + ( p:PLUS { dir=ProductionRule.UP; exp=p; } + | m:MINUS { dir=ProductionRule.DOWN; exp=m; } ) + { + final NodeValue nv; + try { + nv = (NodeValue) rhsv; + } catch (ClassCastException exn) { + throw semanticWrapperException("Non-node type for " + + "target of production rule", exn, e2); + } + final HierName rhsNode = nv.getInstanceName(); + + final String rail = dir == ProductionRule.UP ? "Vdd" : "GND"; + final HierName railName; + try { + final Symbol s = Symbol.create(rail); + final Value v = lookup(env, s, exp); + railName = NodeValue.valueOf(v).getInstanceName(); + + // cell is null if we are parsing a rule in a directive block + if (cell != null) cell.addNode(railName); + } catch (InvalidOperationException exn) { + throw semanticWrapperException("Non-node type for " + rail + + ", implied by production rule", + exn, exp); + } + + pr = new ProductionRule(be, rhsNode, railName, dir, isochronicP, + unstabP, metastableP, timedP, afterTimeSteps, + afterPs); + } + ; + +// this returns a BooleanExpressionInterface, suitable for use as the +// lhs of a production rule or an assert, and nowhere else +prsExpression[Environment env, boolean deepP] +returns [BooleanExpressionInterface be] + { Value prsv; } + : #( PRS_EXPRESSION prsv=exp:expr[env, false, deepP] ) + { be = toPRSExpressionValue(prsv, exp).getBooleanExpression(); } + ; + +// +// subcells stuff +// + +subcellsBlock[Environment env, CellImpl cell] + : #( subcells:SUBCELLS ( inline:INLINE | fragment:FRAGMENT )? ) + { + try { + parseDumbBlockAs(subcells, CastTwoUtil.SUBCELLS_PARSER, + new SubcellsParserCallback(env, cell)); + } catch (TokenStreamException e) { + throw semanticWrapperException("error parsing subcells block", e, subcells); + } + if (fragment == null) cell.setHasCompleteSubcellsBlock(); + else cell.setHasFragmentSubcellsBlock(); + cell.setAutoInline(inline!=null && opt.processInline(cell)); + } + ; + +subcellsStatementsList[Environment env, CellImpl cell] + : #( BODY_STATEMENT_LIST subcellsStatements[env, cell] ) + ; + +subcellsStatements[Environment env, CellImpl cell] + : ( subcellsStatement[env, cell] )* + ; + +subcellsStatement[Environment env, CellImpl cell] + : variableDeclarationStatement[env, false, cell, null, null, false] + | assignmentStatement[env, cell] + | subcellsIfStatement[env, cell] + | subcellsLoopStatement[env, cell] + | assertBlock[env, cell] + | directiveBlock[env, + cell.getBlockInterface() + .iterator(BlockInterface.SUBCELL) + .next(), + BlockInterface.SUBCELL] + ; + +// TODO: refactor with other loops and ifs +subcellsIfStatement[Environment env, CellImpl cell] + { Value v; } + : #( IF v=expr:expression[env, false] subcellsList:BODY_STATEMENT_LIST ) + { + final BoolValue bv = ifGuard(v, expr); + + try { + if (bv.getValue()) + subcellsStatementsList(subcellsList, env, cell); + } catch (InvalidOperationException e) { + throw semanticWrapperException("If guard uninitialized.", + e, expr); + } + } + ; + +// TODO: refactor with other loops and ifs +subcellsLoopStatement[Environment env, CellImpl cell] + { Range r; } + : #( LOOP id:IDENT r=range[env, true] subcellsList:BODY_STATEMENT_LIST ) + { + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + subcellsStatementsList(subcellsList, loopEnv, cell); + } + } + ; + +// +// subtypes stuff +// + +// Doesn't change env +subtypesBlock[Environment env, CellImpl cell] + : subtypes:SUBTYPES + { + try { + parseDumbBlockAs(subtypes, CastTwoUtil.SUBTYPES_PARSER, + new SubtypesParserCallback(env, + new IdentityHashMap(), + cell)); + } catch (TokenStreamException e) { + throw semanticWrapperException("error parsing subtypes block", e, subtypes); + } + cell.setHasSubtypesBlock(); + } + ; + +subtypesStatementsList[Environment env, Map copied, CellImpl cell] + : #( BODY_STATEMENT_LIST subtypesStatements[env, copied, cell] ) + ; + +subtypesStatements[Environment env, Map copied, CellImpl cell] + : ( subtypesStatement[env, copied, cell] )* + ; + +subtypesStatement[Environment env, Map copied, CellImpl cell] + : subtypesRefinement[env, copied, cell] + | subtypesIfStatement[env, copied, cell] + | subtypesLoopStatement[env, copied, cell] + | directiveBlock[env, + cell.getBlockInterface() + .iterator(BlockInterface.SUBCELL) + .next(), + BlockInterface.SUBCELL] + ; + +subtypesArraySelector[Environment env, StringBuffer buf] + : #( ARRAY_SUB subtypesRange[env, buf] + ( { buf.append(','); } subtypesRange[env, buf] )* + ) + ; + +subtypesRange[Environment env, StringBuffer buf] + { Range r; } + : r = range[env, false] { buf.append(r.getMin()); } + ; + +subtypesIdent[Environment env, Map copied, StringBuffer buf] +returns [Binder next] + { Binder prev; next = null; } + : #( id:IDENT { + final String s = id.getText(); + buf.append(s); + + next = new SimpleBinder(env, Symbol.create(s)); + }) + | #( FIELD_ACCESS prev=subtypesIdent[env, copied, buf] fi:FIELD_IDENT ) { + buf.append('.'); + buf.append(fi.getText()); + + try { + final Value v = prev == null ? null : prev.lookup(); + if (v instanceof InstanceValue) { + final boolean found = copied.containsKey(v); + final Pair processed = + ((InstanceValue) v).processSubtypes(found); + if (!found) { + copied.put(v, null); + prev.bind((Value) processed.getSecond()); + } + next = new SimpleBinder((Environment) processed.getFirst(), + Symbol.create(fi.getText())); + } + } catch (Exception e) { + // e.printStackTrace(); + } + } + | #( ARRAY_ACCESS prev=subtypesIdent[env, copied, buf] { buf.append('['); } + sub:subtypesArraySelector[env, buf] { buf.append(']'); } ) + { + + try { + if (prev != null) { + final Value v = prev.lookup(); + final SubscriptSpecInterface spec = (SubscriptSpecInterface) + arraySelector(sub, env, null, false).getFirst(); + if (v instanceof ArrayValue) { + final ArrayValue av; + if (copied.containsKey(v)) { + av = (ArrayValue) v; + } else { + av = (ArrayValue) v.duplicate(); + copied.put(av, null); + prev.bind(av); + } + next = new ArrayBinder(av, spec); + } + } + } catch (Exception e) { + // e.printStackTrace(); + } + } + ; + +// Types need parent cells for creation, so these get throwaway parent +// cells. The connections are taken care of by the subcell +// declaration in the refinement parent. +subtypesRefinement[Environment env, Map copied, CellImpl cell] + { + final StringBuffer buf = new StringBuffer(); + final Pair parentPair, childPair; + final HierName subcellName; + Pair arrayIndexPair = null; + CellImpl throwawayCell = new CellImpl("fake", null, + CellImpl.SYNTHETIC_CELL); + Binder binder; + } + : #( v:VAR_DECL + ( inline:INLINE )? + binder=subtypesIdent[env, copied, buf] + { + // It's impossible to subtype anonymous cells, so it + // doesn't need to pass through generateName(). + + try { + subcellName = HierName.makeHierName(buf.toString(), '.'); + } catch (InvalidHierNameException e) { + throw new AssertionFailure + ("Can't make HierName from " + buf); + } + } + parentPair=type[env, throwawayCell, null, + HierName.makeHierName("fake"), + false, false, false, null, LOCAL_VAR] + childPair=type[env, throwawayCell, null, + HierName.makeHierName("fake"), + false, false, false, null, LOCAL_VAR] + ) + { + final CellInterface parent = + ((InstanceValue) parentPair.getFirst()).getCell(); + final InstanceValue childInst = (InstanceValue) childPair.getFirst(); + + final CellInterface child = childInst.getCell(); + try { + final boolean inlineP = + (inline != null || child.isAutoInline()) && + opt.processInline(parent); + cell.addSubtype(subcellName, parent, child, inlineP, + opt.bug16459HackEnabled()); + if (inlineP) { + childInst.setInline(InstanceValue.INLINE_INLINE); + } + } + catch (RefinementException e) { + throw semanticWrapperException(e, v); + } + + // Rely on methods in CellImpl to determine the correctness of the + // subtypes block. It might be better to do that earlier, perhaps + // here. + try { + final Value curr = binder == null ? null : binder.lookup(); + if (curr != null) { + Value next = childInst; + Value[] vals; + if (curr instanceof ArrayValue) { + final ArrayValue av = (ArrayValue) curr; + final SubscriptSpecInterface spec = av.getSpec(); + vals = new Value[spec.getNumElements()]; + for (int i = 0; i < vals.length; ++i) { + final int[] idx = spec.indexOf(i); + final Value elem = av.accessArray(idx); + vals[i] = + childInst.duplicate() + .newInstanceName(elem.getInstanceName()); + } + next = new ArrayValue(vals, spec, av.getInstanceName(), + av.isWideChannel()); + } else { + next = childInst.newInstanceName(curr.getInstanceName()); + } + if (!copied.containsKey(curr)) { + binder.bind(next); + copied.put(next, null); + } + } + } catch (Exception e) { + // e.printStackTrace(); + } + } + ; + +// TODO: refactor with other loops and ifs +subtypesIfStatement[Environment env, Map copied, CellImpl cell] + { Value v; } + : #( IF v=expr:expression[env, false] subtypeStmts:BODY_STATEMENT_LIST ) + { + final BoolValue bv = ifGuard(v, expr); + + try { + if (bv.getValue()) + subtypesStatementsList(subtypeStmts, env, copied, cell); + } catch (InvalidOperationException e) { + throw semanticWrapperException("If guard uninitialized.", + e, expr); + } + } + ; + +// TODO: refactor with other loops and ifs +subtypesLoopStatement[Environment env, Map copied, CellImpl cell] + { Range r; } + : #( LOOP id:IDENT r=range[env, true] subtypeStmts:BODY_STATEMENT_LIST ) + { + final Symbol sym = generateSymbol(id.getText()); + final Range.Iterator ri = r.iterator(); + while (ri.hasNext()) { + final int i = ri.next(); + final Environment loopEnv + = new LoopEnvironment(env, sym, IntValue.valueOf(i)); + subtypesStatementsList(subtypeStmts, loopEnv, copied, cell); + } + } + ; + +// +// csp stuff +// + +// Doesn't change env +cspBlock[Environment env, CellImpl cell, CellInterface envContainer] + : #( csp:CSP + { + // System.err.println("csp text: " + #csp.getText()); + try { + final CspLexer cspLexer = + new CspLexer(new StringReader(#csp.getText())); + cspLexer.setTokenObjectClass(TokenWithInfo.class.getName()); + final TokenStreamSelector selector = + CastTwoUtil.getSelector(cspLexer, "csplexer", + #csp.getLine(), #csp.getColumn(), + #csp.getFilename()); + + final CspParser cspParser = new CspParser(selector); + cspParser.setSelector(selector); + + cspParser.setFilename(#csp.getFilename()); + final Pair p = cspParser.program(); + final CSPProgram cspProgram = (CSPProgram) p.getFirst(); + final TokenWithInfo dir = (TokenWithInfo) p.getSecond(); + if (dir != null) { + parseDirectives(dir.getText(), dir.getLine(), + dir.getColumn(), dir.getFilename(), env, + BlockInterface.CSP, + cell.getBlockInterface() + .iterator(BlockInterface.CSP) + .next()); + } + + cspProgram.setInitializerStatement + (makeCSPConstantInitializers(env)); + if (envContainer != null) { + cspProgram.refineDeclarationsFrom( + envContainer.getCSPProgram()); + } + + cell.setCSPProgram(cspProgram); + } catch (RecognitionException e) { + throw semanticWrapperException(e, csp); + } catch (TokenStreamException e) { + throw semanticWrapperException(e, csp); + } catch (InvalidOperationException e) { + throw semanticWrapperException(e, csp); + } + } + ( cspPorts[env, cell] )? + ) + ; + +cspPorts[Environment env, CellImpl cell] + : #( CSP_PORTS ( cspPort[env, cell] )+ ) + ; + +cspPort[Environment env, CellImpl cell] + : id:IDENT + { + try { + cell.addCSPPort(id.getText()); + } catch (BadCSPPortException e) { + throw semanticWrapperException(e, id); + } + } + ; + +// +// Directive block +// + +// Doesn't change env +directiveBlock[Environment env, BlockInterface parent, String type] + : #( directive:DIRECTIVE { + parseDirectives(#directive.getText(), #directive.getLine(), + #directive.getColumn(), #directive.getFilename(), + env, type, parent); + } + ) + ; + +// +// Netlist block +// + +netlistBlock[Environment env, CellImpl cell] + : #( netlist:NETLIST { + final CDLLexer lexer = + new CDLLexer(new StringReader(#netlist.getText()), true); + lexer.setFilename(#netlist.getFilename()); + lexer.setColumn(#netlist.getColumn()); + lexer.setLine(#netlist.getLine()); + final CDLParser parser = new CDLParser(lexer); + + parser.setASTNodeClass(CDLParser.ASTWithToken.class.getName()); + try { + parser.startDeviceList(); + } catch (TokenStreamException e) { + throw semanticWrapperException("Error parsing netlist block", e, netlist); + } + final AST ast = parser.getAST(); + final CDLWalker walker = new CDLWalker(); + final Template templ = new Template(Collections.EMPTY_MAP); + final Map params = new HashMap(); + walker.deviceList(ast, new BlockEnvironment( + CDLWalker.sanitizeEnvironment(env), + new LocalEnvironment(params)), templ); + ((NetlistBlock) cell.getBlockInterface().iterator(BlockInterface.NETLIST).next()).setCDLTemplate(templ, params); + } + ) + ; + +// +// env block stuff +// + +// paramEnv can be null if an env block is not allowed at this level. +// Otherwise it's the environment in which the metaparameters, ports, +// implied ports, and constants of cell are bound, but none of the body of +// cell. It's read-only. +envBlock[CellImpl cell, BlockEnvironment paramEnv] + { + final Environment blockEnv = new LocalEnvironment(new LinkedHashMap()); + final Environment namedEnvBindings = + new ChainEnvironment(paramEnv, blockEnv); + } + : #( ENV ( envNameBlock[namedEnvBindings] )* ) + { EnvBlock block = cell.getEnvironments(); + block.setEnvironment(namedEnvBindings, blockEnv, cpe); + // iterate over defined environments, and set the container cell for + // each of the environment + final UserDefinedValue container = + (UserDefinedValue) activeUDV.getLast(); + for (EnvironmentEntryIterator i = blockEnv.entryIterator(); + i.hasNext(); ) { + final EnvironmentEntry entry = i.next(); + final Value val = entry.getValue(); + if (val instanceof UserDefinedValue) { + ((UserDefinedValue) val).updateEnvironmentContainer(container); + } + } + } + ; + +// A single named environment +envNameBlock[Environment namedEnvBindings] + : #( NAMED_ENV typeDeclaration[namedEnvBindings, true] ) + ; + +// +// Java block +// + +// This doesn't change env +javaBlock[Environment env, CellImpl cell, boolean isEnv] + : oldJavaBlock[env, cell] + | newJavaBlock[env, cell, isEnv] + ; + +// +// New syntax Java block +// + +newJavaBlock[Environment env, CellImpl cell, boolean isEnv] + : #( j:NEW_JAVA + newJavaStatements[ + env, + cell.getBlockInterface().iterator(BlockInterface.JAVA).next(), + (JavaCoSimInfo) cell.getCoSimInfo(CoSimParameters.JAVA), + isEnv + ] + ) + ; + +newJavaStatements[Environment env, BlockInterface javaBlock, + JavaCoSimInfo cosimInfo, boolean isEnv] + : #( BODY_STATEMENT_LIST + ( newJavaStatement[env, javaBlock, cosimInfo, isEnv] )* + ) + ; + +newJavaStatement[Environment env, BlockInterface javaBlock, + JavaCoSimInfo cosimInfo, boolean isEnv] + : newJavaClassStatement[env, cosimInfo, isEnv] + | javaChannelStatement[env, cosimInfo] + | directiveBlock[env, javaBlock, BlockInterface.JAVA] + ; + +newJavaClassStatement[Environment env, JavaCoSimInfo cosimInfo, boolean isEnv] + { + MetaParamDefinition[] metaParameters = null; + // Only contains Strings and arrays of Strings. See comments in + // JavaCoSimDevice. + Vector channelAndNodeNames = new Vector(); + // See comments in JavaCoSimDevice. + Vector initializers = null; + } + + : #( NEW_JAVA_CLASS + className:IDENT + ( metaParameters=javaClassMetaParameters[env] )? + instanceName:IDENT + ( javaClassParameters[env, channelAndNodeNames] )? + ( initializers=javaClassInitializers[env] )? + ) + { + String realInstanceName = instanceName.getText(); + if (realInstanceName.equals("_")) + realInstanceName = "anonymous device"; + if (metaParameters == null) + metaParameters = new MetaParamDefinition[0]; + + // channelAndNodeNames can be optionally empty (for bug 11893), we + // could define this to mean that all ports are to be passed to the + // Java class; however, since the Java block seems to be phased out, + // this has not yet been implemented + + // this constructor is only called here + final JavaCoSimDevice classDescriptor = + new JavaCoSimDevice(className.getText(), + // pass null for device name if we are + // non-env so the device will be called + // pr.ef.ix instead of pr.ef.ix.inst + isEnv ? realInstanceName : null, + metaParameters, + channelAndNodeNames, + initializers); + cosimInfo.addClass(classDescriptor); + } + ; + +javaClassMetaParameters[Environment env] +returns [MetaParamDefinition[] metaParams] + { + final Vector accum = new Vector(); + Object metaParam = null; + } + : #( JAVA_CLASS_META_PARAMETERS + ( metaParam=javaClassMetaParameter[env] { accum.add(metaParam); } )+ + ) + { metaParams = (MetaParamDefinition[]) accum.toArray(new MetaParamDefinition[0]); } + ; + +javaClassMetaParameter[Environment env] returns [MetaParamDefinition metaParam] + { Value v = null; } + : #( EXPRESSION v=expr[env, false] + { + final String name; + if (v.getInstanceName() == null) + name = null; + else + name = v.getInstanceName().getAsString('.'); + metaParam = new MetaParamDefinition( + name, + ((MetaParamValueInterface) v).toMetaParam()); + } + ) + ; + +// returns Vector +javaClassParameters[Environment env, Vector params] + { + JavaClassParameter param = null; + } + : #( JAVA_CLASS_PARAMETERS + ( param=javaClassParameter[env] { params.add(param); } )+ + ) + ; + +javaClassParameter[Environment env] returns [JavaClassParameter param] + { Value v = null; int[] timingParams = null; } + : #( JAVA_CLASS_PARAMETER v=expr[env, false] + ( timingParams=javaChannelTimingInfo[env] )? + { + if (v instanceof ArrayValue) { + final ArrayValue av = (ArrayValue) v; + final CoSimChannelNames names = av.getCoSimChannelNames(); + // If there's only one element, unwrap it + if (names.hasOneElement()) { + param = new JavaClassParameter(names.getFirstElement()); + } else { + param = new JavaClassParameter(names); + } + } else { + // v is a channel? TODO: better error reporting, + // commenting + param = + new JavaClassParameter + (v.getInstanceName().getAsString('.')); + } + if(timingParams != null) { + param.setTimingParams(timingParams); + } + } + ) + ; + +// STUB +javaClassInitializers[Environment env] returns [Vector rv] + { rv = null; } + : JAVA_CLASS_INITIALIZERS + ; + +/** + * Adds the channel to the environment and the cosimInfo. + **/ +javaChannelStatement[Environment env, JavaCoSimInfo cosimInfo] + { + int[] timingParams = null; + Pair arrayPair = null; + } + : #( CHANNEL + id:IDENT + ( arrayPair=arraySelector[env, null, false] )? + ( timingParams=javaChannelTimingInfo[env] )? + ) + { + final String channelName = id.getText(); + final HierName channelHierName = HierName.makeHierName(channelName); + final JavaChannelContainerValue channelValue; + final SubscriptSpecInterface arraySpec; + System.out.println("arrayPair is " + arrayPair); + if (arrayPair == null) { + arraySpec = null; + channelValue = new JavaChannelContainerValue(channelHierName); + } else { + arraySpec = (SubscriptSpecInterface) arrayPair.getFirst(); + channelValue = new JavaChannelContainerValue(channelHierName, + arraySpec); + } + + try { + env.bind(Symbol.create(channelName), channelValue); + } catch (SymbolRedeclaredException e) { + throw semanticWrapperException("trouble making java channel", e, id); + } + cosimInfo.addInternalChannel(channelName, timingParams, arraySpec); + } + ; + +javaChannelTimingInfo[Environment env] + returns [int [] rv] + { + // There can't be array accesses in the antlr code, only in + // the included java code, so this can't be an array + Value slackValue, ffValue, bbValue, fbValue, bfValue; + } + : #( c:CHANNEL_TIMING_INFO + slackValue=slack:expr[env, false] + ( /* empty */ + { + rv = new int[1]; + rv[0] = getInt(slackValue, slack); + } + | ffValue=ff:expr[env, false] + bbValue=bb:expr[env, false] + fbValue=fb:expr[env, false] + bfValue=bf:expr[env, false] + { + rv = new int[5]; + rv[0] = getInt(slackValue, slack); + rv[1] = getInt(ffValue, ff); + rv[2] = getInt(bbValue, bb); + rv[3] = getInt(fbValue, fb); + rv[4] = getInt(bfValue, bf); + } + ) + ) + ; + +// +// Old syntax Java block +// + +oldJavaBlock[Environment env, CellImpl cell] + : #( JAVA oldJavaStatements[env, cell] ) + ; + +oldJavaStatements[Environment env, CellImpl cell] + : #( BODY_STATEMENT_LIST ( oldJavaStatement[env, cell] )* ) + ; + +oldJavaStatement[Environment env, CellImpl cell] + : oldJavaClassStatement[env, cell] + | inputChannelStatement[env, cell] + | outputChannelStatement[env, cell] + | internalChannelStatement[env, cell] + ; + +oldJavaClassStatement[Environment env, CellImpl cell] + : #( JAVACLASS cls:QuotedString ) { cell.setJavaClass(cls.getText()); } + ; + +inputChannelStatement[Environment env, CellImpl cell] + : #( INPUTCHAN cls:QuotedString ) + { cell.setInputChannel(modulizeOldJavaChannel(cls.getText())); } + ; + +outputChannelStatement[Environment env, CellImpl cell] + : #( OUTPUTCHAN cls:QuotedString ) + { cell.setOutputChannel(modulizeOldJavaChannel(cls.getText())); } + ; + +internalChannelStatement[Environment env, CellImpl cell] + : #( INTERNALCHAN cls:QuotedString ) + { cell.setInternalChannel(modulizeOldJavaChannel(cls.getText())); } + ; + +// +// Verilog block +// + +verilogBlock[Environment env, CellImpl cell] + { + final VerilogBlock vb = new VerilogBlock(); + } + : #( VERILOG ( verilogNamed[env, vb] )* ) { + cell.getBlockInterface().iterator(BlockInterface.VERILOG).add(vb); + } + ; + + +verilogNamed[Environment env, VerilogBlock vb] + { + String n = null; + VerilogBlock.NamedBlock nb = null; + } + : name:IDENT { n = name.getText(); + nb = new VerilogBlock.SimpleNamedBlock(n); } + verilogStatements[env, nb] + { + if (vb.getNamedBlock(n) != null) { + syntaxError("Redefining named verilog block " + n, name); + } + vb.addNamedBlock(nb); + } + ; + +verilogStatements[Environment env, VerilogBlock.NamedBlock nb] + : #( BODY_STATEMENT_LIST ( verilogStatement[env, nb] )* ) + ; + +verilogStatement[Environment env, VerilogBlock.NamedBlock nb] + { + final List implied = new ArrayList(); + final Map specified = new LinkedHashMap(); + final List files = new ArrayList(); + TupleValue tuple = null; + final List params = new ArrayList(); + } + : module:IDENT + ( tuple = expressionList[env, false] { + for (int i = 0; i < tuple.getSize(); ++i) { + final Value elem; + try { + elem = tuple.accessTuple(i); + } catch (InvalidOperationException e) { + throw new AssertionError("Cannot accessTuple on: " + tuple); + } + if (elem instanceof IntValue || elem instanceof FloatValue) { + params.add(elem); + } else { + final SemanticException se = new SemanticException("Only int and float expressions allowed as module parameters", module.getFilename(), module.getLine(), module.getColumn()); + throw se; + } + } + } )? + ( verilogParameters[env, implied, specified] )? + ( verilogFiles[env, files] )? { + nb.addInstance(new VerilogBlock.Instance( + module.getText(), + params, + implied.size() == 0 && specified.size() != 0 ? null : implied, + specified.size() == 0 ? null : specified, + files)); + } + SEMI + | verilogFiles[env, files] { + nb.addFiles(files); + } + SEMI + | directiveBlock[env, nb, BlockInterface.VERILOG] + ; + +verilogParameters[Environment env, List implied, Map specified] + : ( verilogParameter[env, implied, specified] )+ + ; + +verilogParameter[Environment env, List implied, Map specified] + : verilogImplictParameter[env, implied] + | verilogExplictParameter[env, specified] + ; + +verilogImplictParameter[Environment env, List implied] + { + Value v = null; + } + : v = expr[env, true] { implied.add(v); } + ; + +verilogExplictParameter[Environment env, Map specified] + { + Value v = null; + } + : p:DOT_IDENT ( v = expr[env, true] )? RPAREN { + final String port = p.getText(); + if (specified.containsKey(port)) { + final SemanticException se + = new SemanticException("Port '" + port + "' redeclared", + p.getFilename(), p.getLine(), p.getColumn()); + throw se; + } + specified.put(port, v); + } + ; + +verilogFiles[Environment env, List files] + : ( s:QuotedString { files.add(s.getText()); } )+ + ; + +partialExtract returns [Triplet p] + { + p = null; + final Collection c = new ArrayList(); + String envName = null; + TupleValue metas = null; + String cellName; + String special = ""; + } + : type:IDENT { cellName = type.getText(); } + ( metas = expressionList[new LocalEnvironment(), false] { + cellName = UserDefinedValue.getTypeName(cellName, metas); + })? + ( { Boolean plus = null; } + ( PLUS { plus = Boolean.TRUE; } | MINUS { plus = Boolean.FALSE; } ) + ( PLUS { special = "+"; } | MINUS { special = "-"; } )? + { final StringBuffer sb = new StringBuffer(special); } + ( partialExtractExpr[sb] ) { c.add(new Pair(sb.toString(), plus)); } + )* + ( env:IDENT { envName = env.getText(); } + ( metas = expressionList[new LocalEnvironment(), false] { + envName = UserDefinedValue.getTypeName(envName, metas); + })? + | times:TIMES { envName = "*"; } )? + { p = new Triplet(cellName, envName, c); } + ; + +partialExtractExpr[StringBuffer sb] + : #( FIELD_ACCESS partialExtractExpr[sb] fi:FIELD_IDENT + { sb.append('.'); sb.append(fi.getText()); } + ) + | #( ARRAY_ACCESS partialExtractExpr[sb] { sb.append('['); } + partialExtractArraySelector[sb] { sb.append(']'); } ) + | id:IDENT { sb.append(id.getText()); } + ; + +partialExtractArraySelector[StringBuffer sb] + : #( arrayExpr:ARRAY_SUB + partialExtractRange[sb] + ( { sb.append(','); } partialExtractRange[sb] )* + ) + ; + +partialExtractRange[StringBuffer sb] + : #( RANGE #( EXPRESSION n:NUM_INT { sb.append(n.getText()); }) ) + ; + +getHeaderAST returns [Pair p] + : #( VAR_DECL IDENT ( INLINE )? ( FLATTEN )? + #( TYPE + #( USER_TYPE id:IDENT metas:EXPRESSION_LIST) ) ) { + p = new Pair(id, metas); + } + ; + +getCellData[ASTWithInfo errorAST, Environment paramEnv, + CellInterface envContainer] +returns [CellData data] + { + data = null; + } + : cell:IDENT ( cellMeta:EXPRESSION_LIST )? + ( env:IDENT ( envMeta:EXPRESSION_LIST )? )? { + if (envContainer != null && env == null) { + env = cell; + envMeta = cellMeta; + try { + final AST ast = + cpe.getInstantiationAST( + envContainer.getFullyQualifiedType(), + HierName.makeHierName("__")); + final Pair p = getHeaderAST(ast); + cell = (ASTWithInfo) p.getFirst(); + cellMeta = (ASTWithInfo) p.getSecond(); + } catch (antlr.TokenStreamException e) { } + } + data = getCellFromAST(cell, cellMeta, env, envMeta, errorAST, paramEnv); + } + ; + +alintFanin[Environment env] returns [Value v] + { AlintFaninValue.State st = null; Value node = null; v = null; } + : node = expr[env, false, true] + ( s:NUM_INT + { st = s.getText().equals("0") ? AlintFaninValue.State.ZERO + : AlintFaninValue.State.ONE; + } + | PLUS { st = AlintFaninValue.State.RISING; } + | MINUS { st = AlintFaninValue.State.FALLING; } + ) + { v = new AlintFaninValue(node, st); } + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoUtil.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoUtil.java new file mode 100644 index 0000000000..b13a83b723 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/CastTwoUtil.java @@ -0,0 +1,239 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id: //depot/sw/cad/java/main/src/com/avlsi/cast/impl/CastParserInterface.jav +a#4 $ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.impl; + +import java.io.StringReader; +import java.math.BigInteger; + +import antlr.ASTFactory; +import antlr.CharScanner; +import antlr.Parser; +import antlr.RecognitionException; +import antlr.TokenStream; +import antlr.TokenStreamException; +import antlr.TokenStreamSelector; +import antlr.collections.AST; + +import com.avlsi.cast.impl.ASTWithInfo; +import com.avlsi.cast.impl.IntValue; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.SemanticWrapperException; +import com.avlsi.cast.impl.TokenWithInfo; +import com.avlsi.cast.impl.TupleValue; +import com.avlsi.util.functions.UnaryFunction; + +public class CastTwoUtil { + /** + * This class should not be instantiated. + **/ + private CastTwoUtil() { } + + interface ParserFactory { + CastTwoParserInterface getParser(TokenStream stream); + } + + interface ParserCallback { + void bodyStatement(ASTWithInfo ast) throws RecognitionException; + void ifStart(ASTWithInfo expr) throws RecognitionException; + void ifEnd() throws RecognitionException; + void loopStart(ASTWithInfo ident, ASTWithInfo range) + throws RecognitionException; + void loopEnd() throws RecognitionException; + } + + static final ParserFactory PRS_PARSER = new ParserFactory() { + public CastTwoParserInterface getParser(TokenStream stream) { + return new CastPrsParser(stream); + } + }; + + static final ParserFactory SUBCELLS_PARSER = new ParserFactory() { + public CastTwoParserInterface getParser(TokenStream stream) { + return new CastSubcellsParser(stream); + } + }; + + static final ParserFactory SUBTYPES_PARSER = new ParserFactory() { + public CastTwoParserInterface getParser(TokenStream stream) { + return new CastSubtypesParser(stream); + } + }; + + static final ParserFactory ASSERT_PARSER = new ParserFactory() { + public CastTwoParserInterface getParser(TokenStream stream) { + return new CastAssertParser(stream); + } + }; + + static final ParserFactory ALIASES_PARSER = new ParserFactory() { + public CastTwoParserInterface getParser(TokenStream stream) { + return new CastAliasesParser(stream); + } + }; + + public static TokenStreamSelector getSelector(final CharScanner lexer, + final String lexerName, + final int lineNum, + final int columnNum, + final String fileName) { + lexer.setLine(lineNum); + lexer.setColumn(columnNum); + lexer.setFilename(fileName); + final DumbTwoLexer dumbLexer = new DumbTwoLexer(lexer.getInputState()); + + final TokenStreamSelector selector = new TokenStreamSelector(); + selector.addInputStream(lexer, lexerName); + selector.addInputStream(dumbLexer, "dumblexer"); + selector.select(lexer); + return selector; + } + + static TokenStreamSelector getSelector(String s, int lineNum, + int columnNum, String fileName) { + final StringReader input = new StringReader(s); + final CastTwoLexer castLexer = new CastTwoLexer(input); + castLexer.setTokenObjectClass(TokenWithInfo.class.getName()); + + return getSelector(castLexer, "castlexer", lineNum, columnNum, fileName); + } + + public static String getDumbBlockString(final TokenStreamSelector selector, + final Parser current) + throws RecognitionException, TokenStreamException { + selector.push("dumblexer"); + final String dum = new DumbTwoParser(current.getInputState()).goal(); + selector.pop(); + return dum; + } + + /** + * Parse the given string using the specified subparser, and return the AST. + **/ + static AST parseStringAs(String s, int lineNum, int columnNum, + String fileName, boolean verbose, + ParserFactory factory) + throws RecognitionException, TokenStreamException { + final TokenStreamSelector selector = + getSelector(s, lineNum, columnNum, fileName); + final CastTwoParserInterface parser = factory.getParser(selector); + parser.setVerbosity(verbose); + parser.setSelector(selector); + parser.setFilename(fileName); + parser.setASTNodeClass(ASTWithInfo.class.getName()); + parser.goal(); + return parser.getAST(); + } + + /** + * Parse the given string using the specified subparser, the call the + * specified callback object. + **/ + static void parseStringAs(String s, int lineNum, int columnNum, + String fileName, boolean verbose, + ParserFactory factory, + ParserCallback cb) + throws RecognitionException, TokenStreamException { + final TokenStreamSelector selector = + getSelector(s, lineNum, columnNum, fileName); + final CastTwoParserCallback parser = + (CastTwoParserCallback) factory.getParser(selector); + parser.setVerbosity(verbose); + parser.setSelector(selector); + parser.setFilename(fileName); + parser.setASTNodeClass(ASTWithInfo.class.getName()); + parser.goalCallback(cb); + } + + private static ASTWithInfo makeMetasAST( final ASTFactory factory, + final TupleValue metas ) throws SemanticWrapperException { + + final AST metasAST; + + metasAST = factory.create(CastTwoTreeParser.EXPRESSION_LIST); + + final int length = metas.getSize(); + for (int i=0; i 0 ) { + System.err.println("Parsing..."); + + // for each directory/file specified on the command line + for(int i=0; i< args.length;i++) + doFile(new File(args[i])); // parse it + } + else + System.err.println("Usage: java DumbTwoParser "); + + } + catch(Exception e) { + System.err.println("exception: "+e); + e.printStackTrace(System.err); // so we can get stack trace + } + } + + + // This method decides what action to take based on the type of + // file we are looking at + public static void doFile(File f) throws Exception { + // If this is a directory, walk each file/dir in that directory + if (f.isDirectory()) { + String files[] = f.list(); + for(int i=0; i < files.length; i++) + doFile(new File(f, files[i])); + } + + // otherwise, if this is a DumbTwo file, parse it! + else { + System.err.println(f.getName()); + System.err.println(" "+f.getAbsolutePath()); + parseFile(new FileInputStream(f)); + } + } + + // Here's where we do the real work... + public static void parseFile(InputStream s) throws Exception { + try { + // Create a scanner that reads from the input stream passed to us + DumbTwoLexer lexer = new DumbTwoLexer(s); + + // Create a parser that reads from the scanner + DumbTwoParser parser = new DumbTwoParser(lexer); + + // start parsing at the program rule + parser.goal(); + } + catch (Exception e) { + System.err.println("parser exception: "+e); + e.printStackTrace(); // so we can get stack trace + } + +} +} + +goal returns [String content] +{ content = null; + StringBuffer g = new StringBuffer(); } + : (d:DUMB_BLOCK { g.append(d.getText()); })* RCURLY! + { + content = g.toString(); + } + ; + +class DumbTwoLexer extends Lexer; + +options { + classHeaderSuffix = com.avlsi.cast.impl.DumbLexerInterface; + charVocabulary = '\0'..'\377'; + exportVocab = DumbTwo; + filter = true; +} + +RCURLY : '}' ; + +DUMB_BLOCK + : ( BRACED_BLOCK | NONBRACE ) + ; + +protected +BRACED_BLOCK + : '{' (DUMB_BLOCK)* '}' + ; + +protected +NONBRACE + : (options { generateAmbigWarnings = false; } : + ('\n' { newline(); } ) | ('\0'..'z') | '|' | ('~'..'\377'))+ + { $setType(Token.SKIP); } + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/Functions.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/Functions.java new file mode 100644 index 0000000000..828c762166 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/Functions.java @@ -0,0 +1,147 @@ +package com.avlsi.cast2.impl; + +import java.math.BigInteger; +import java.util.Iterator; +import java.util.Map; + +import com.avlsi.cast.impl.ArrayValue; +import com.avlsi.cast.impl.BoolValue; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.IntValue; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.TupleValue; +import com.avlsi.cast.impl.Type; +import com.avlsi.cast.impl.Value; +import com.avlsi.util.math.BigIntegerUtil; +import com.avlsi.util.container.CollectionUtils; + +public class Functions { + private interface Function { + Value invoke(final TupleValue args) throws InvalidOperationException; + } + + private static void checkType(final Value v, final Type t, final int n) + throws InvalidOperationException { + if (v.getType() != t) { + throw new InvalidOperationException("Expecting argument " + n + " to have type " + t.getString() + "; found type " + v.getType().getString()); + } + } + + private static void checkLength(final TupleValue v, final int size) + throws InvalidOperationException { + if (v.getSize() != size) { + throw new InvalidOperationException("Expecting " + size + " arguments; found " + v.getSize() + " arguments"); + } + } + + private static class MinMax implements Function { + private boolean min; + public MinMax(boolean min) { + this.min = min; + } + private Value op(final Value v1, final Value v2) + throws InvalidOperationException { + return ((BoolValue) (min ? v1.lt(v2) : v1.gt(v2))).getValue() ? v1 + : v2; + } + private Value invoke(final Iterator i, final String type) + throws InvalidOperationException { + Value result = null; + int k = 1; + while (i.hasNext()) { + final Value v = (Value) i.next(); + if (v instanceof IntValue) { + result = result == null ? v : op(result, v); + } else if (v instanceof FloatValue) { + result = result == null ? v + : FloatValue.valueOf(op(v, result)); + } else { + throw new InvalidOperationException("Expecting " + type + " " + k + " to be int or float; found " + v.getType().getString()); + } + ++k; + } + return result; + } + public Value invoke(final TupleValue args) + throws InvalidOperationException { + final int size = args.getSize(); + if (size == 0) { + throw new InvalidOperationException("At least one argument expected; found none"); + } else if (size == 1) { + final Value v = args.accessTuple(0); + if (v instanceof ArrayValue) { + return invoke(((ArrayValue) v).getIterator(), + "array element"); + } else if (v instanceof IntValue || v instanceof FloatValue) { + return v; + } else { + throw new InvalidOperationException("Expecting int or float; found " + v.getType().getString()); + } + } else { + return invoke(args.getIterator(), "argument"); + } + } + } + + private static Map table = CollectionUtils.mapify(new Object[] { + "ceil", new Function() { + public Value invoke(final TupleValue args) + throws InvalidOperationException { + checkLength(args, 1); + final Value v = args.accessTuple(0); + final Value result; + if (v instanceof IntValue) { + result = v; + } else if (v instanceof FloatValue) { + result = IntValue.valueOf( + String.format("%.0f", + Math.ceil(((FloatValue) v).getValue()))); + } else { + throw new InvalidOperationException("Expecting int or float; found " + v.getType().getString()); + } + return result; + } + }, + "log2", new Function() { + public Value invoke(final TupleValue args) + throws InvalidOperationException { + checkLength(args, 1); + final Value v = args.accessTuple(0); + checkType(v, IntValue.TYPE, 1); + return IntValue.valueOf(BigIntegerUtil.log2(((IntValue) v).getValue())); + } + }, + "log4", new Function() { + public Value invoke(final TupleValue args) + throws InvalidOperationException { + checkLength(args, 1); + final Value v = args.accessTuple(0); + checkType(v, IntValue.TYPE, 1); + return IntValue.valueOf(BigIntegerUtil.log4(((IntValue) v).getValue())); + } + }, + "log", new Function() { + public Value invoke(final TupleValue args) + throws InvalidOperationException { + checkLength(args, 2); + final Value base = args.accessTuple(0); + checkType(base, IntValue.TYPE, 1); + final Value v = args.accessTuple(1); + checkType(v, IntValue.TYPE, 2); + return IntValue.valueOf(BigIntegerUtil.log(((IntValue) base).getValue(), ((IntValue) v).getValue())); + } + }, + "min", new MinMax(true), + "max", new MinMax(false) + }); + + public static Value invokeFunction(final String name, final TupleValue args) + throws InvalidOperationException { + final Function func = (Function) table.get(name); + if (func == null) { + throw new InvalidOperationException("Invalid function: " + name); + } else { + return func.invoke(args); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/PrsCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/PrsCallback.java new file mode 100644 index 0000000000..1f4056db77 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/PrsCallback.java @@ -0,0 +1,188 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.impl; + +import java.io.StringReader; + +import antlr.RecognitionException; +import antlr.TokenStreamSelector; +import antlr.TokenStreamException; +import antlr.collections.AST; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.cast.impl.ASTWithInfo; +import com.avlsi.cast.impl.ChainEnvironment; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.FieldedValueInterface; +import com.avlsi.cast.impl.NodeValue; +import com.avlsi.cast.impl.TokenWithInfo; +import com.avlsi.cast.impl.TupleValue; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.impl.CastTwoLexer; +import com.avlsi.cast2.impl.CastTwoParser; +import com.avlsi.cast2.impl.CastTwoTreeParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.util.container.Pair; + +public class PrsCallback implements DirectiveCallback { + private static PrsCallback singleton = null; + + private HierName resolveNode(String value, Environment env, boolean check, + boolean deep) { + final CastTwoParser castParser = + CastTwoParser.getParser(value, 0, 0, ""); + try { + castParser.startPrsNodeExpression(); + } catch (RecognitionException e) { + return null; + } catch (TokenStreamException e) { + return null; + } + + final AST node = castParser.getAST(); + + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + + Value v; + + try { + v = treeParser.expr(node, env, false, deep); + } catch (RecognitionException e) { + if (check || value.indexOf('.') == -1) return null; + else { + /* XXX: We might like to support referencing a node that is in + * a non-inlined subcell, but that's difficult. Instead, we + * give up (but trim any spaces), and assume what is specified + * is valid. It must already be syntactically correct. + **/ + try { + return HierName.makeHierName(value.trim(), '.'); + } catch (InvalidHierNameException ee) { + return null; + } + } + } + + if (v instanceof NodeValue) return ((NodeValue) v).getInstanceName(); + else return null; + } + + private Pair resolveHalfOp(String value, Environment env, boolean check, + boolean deep) { + value = value.trim(); + final boolean plus = value.endsWith("+"); + final boolean minus = value.endsWith("-"); + final Boolean up; + final String nodePart; + if (plus || minus) { + up = plus ? Boolean.TRUE : Boolean.FALSE; + nodePart = value.substring(0, value.length() - 1); + } else { + up = null; + nodePart = value; + } + + final HierName node = resolveNode(nodePart, env, check, deep); + if (node == null) return null; + else return new Pair(node, up); + } + + // Return a rule set because one textual production rule may be represented + // by 2 rules + private ProductionRuleSet resolveRule(String value, Environment env, + boolean deep) { + final CastPrsParser prsParser = (CastPrsParser) + CastTwoParser.getParser(CastPrsParser.class, value, 0, 0, + ""); + try { + prsParser.startPrsAction(); + } catch (RecognitionException e) { + return null; + } catch (TokenStreamException e) { + return null; + } + + final AST prs = prsParser.getAST(); + + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + + final ProductionRuleSet result = new ProductionRuleSet(); + + try { + treeParser.prsAction(prs, env, null, result, deep); + } catch (RecognitionException e) { + return null; + } + + return result; + } + + private Value resolveAlintScenario(String value, Environment env) { + final CastTwoParser castParser = + CastTwoParser.getParser(value, 0, 0, ""); + try { + castParser.startAlintScenario(); + } catch (RecognitionException e) { + return null; + } catch (TokenStreamException e) { + return null; + } + + final AST node = castParser.getAST(); + + // parsed an empty scenario + if (node == null) return new TupleValue(new Value[0]); + + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + + Value v; + + try { + v = treeParser.expressionList(node, env, false, true); + } catch (RecognitionException e) { + return null; + } + + return v; + } + + private PrsCallback() { + } + + public Object resolve(String type, String value, Environment env) { + Object ret = null; + if (type.equals(DirectiveConstants.NODE_TYPE)) { + ret = resolveNode(value, env, true, false); + } else if (type.equals(DirectiveConstants.HALFOP_TYPE)) { + ret = resolveHalfOp(value, env, true, false); + } else if (type.equals(DirectiveConstants.UNCHECKED_NODE_TYPE)) { + ret = resolveNode(value, env, false, false); + } else if (type.equals(DirectiveConstants.UNCHECKED_HALFOP_TYPE)) { + ret = resolveHalfOp(value, env, false, false); + } else if (type.equals(DirectiveConstants.DEEP_NODE_TYPE)) { + ret = resolveNode(value, env, true, true); + } else if (type.equals(DirectiveConstants.DEEP_HALFOP_TYPE)) { + ret = resolveHalfOp(value, env, true, true); + } else if (type.equals(DirectiveConstants.RULE_TYPE)) { + ret = resolveRule(value, env, false); + } else if (type.equals(DirectiveConstants.DEEP_RULE_TYPE)) { + ret = resolveRule(value, env, true); + } else if (type.equals(DirectiveConstants.ALINT_SCENARIO_TYPE)) { + ret = resolveAlintScenario(value, env); + } + return ret; + } + + public static PrsCallback getInstance() { + if (singleton == null) singleton = new PrsCallback(); + return singleton; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/custom.mk new file mode 100644 index 0000000000..c17cdc05d6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/custom.mk @@ -0,0 +1,113 @@ +MAKE_ANTLR_RULES_G_FILE_NAME := CastTwo.g +MAKE_ANTLR_RULES_LEXER_NAME := CastTwoLexer +MAKE_ANTLR_RULES_PARSER_NAME := CastTwoParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := CastTwo +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk + + + + + + +cast_prs_results := $(CURR_TARGET_DIR)/CastPrsParser.java \ + $(CURR_TARGET_DIR)/CastPrsParserTokenTypes.java \ + $(CURR_TARGET_DIR)/CastPrsParserTokenTypes.txt \ + $(CURR_TARGET_DIR)/expandedCastPrs.g + +$(CURR_TARGET_DIR)/CastPrs.g: $(CURR_PROJECT_DIR)/CastPrs.g + cp $< $@ + chmod u+w $@ + +$(cast_prs_results): $(CURR_TARGET_DIR)/CastTwoParser.java $(CURR_TARGET_DIR)/CastPrs.g $(CURR_TARGET_DIR)/CastTwo.g + cd $(@D) && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) -glib CastTwo.g CastPrs.g + touch $@ + + +CURR_INTERMEDIATE_FILES := $(cast_prs_results) $(CURR_TARGET_DIR)/CastPrs.g $(CURR_INTERMEDIATE_FILES) + + +cast_prs_results := $(CURR_TARGET_DIR)/CastSubtypesParser.java \ + $(CURR_TARGET_DIR)/CastSubtypesParserTokenTypes.java \ + $(CURR_TARGET_DIR)/CastSubtypesParserTokenTypes.txt \ + $(CURR_TARGET_DIR)/expandedCastSubtypes.g + +$(CURR_TARGET_DIR)/CastSubtypes.g: $(CURR_PROJECT_DIR)/CastSubtypes.g + cp $< $@ + chmod u+w $@ + +$(cast_prs_results): $(CURR_TARGET_DIR)/CastTwoParser.java $(CURR_TARGET_DIR)/CastSubtypes.g $(CURR_TARGET_DIR)/CastTwo.g + cd $(@D) && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) -glib CastTwo.g CastSubtypes.g + touch $@ + + +CURR_INTERMEDIATE_FILES := $(cast_prs_results) $(CURR_TARGET_DIR)/CastSubtypes.g $(CURR_INTERMEDIATE_FILES) + + +cast_subcells_results := $(CURR_TARGET_DIR)/CastSubcellsParser.java \ + $(CURR_TARGET_DIR)/CastSubcellsParserTokenTypes.java \ + $(CURR_TARGET_DIR)/CastSubcellsParserTokenTypes.txt \ + $(CURR_TARGET_DIR)/expandedCastSubcells.g + +$(CURR_TARGET_DIR)/CastSubcells.g: $(CURR_PROJECT_DIR)/CastSubcells.g + cp $< $@ + chmod u+w $@ + +$(cast_subcells_results): $(CURR_TARGET_DIR)/CastTwoParser.java $(CURR_TARGET_DIR)/CastSubcells.g $(CURR_TARGET_DIR)/CastTwo.g + cd $(@D) && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) -glib CastTwo.g CastSubcells.g + touch $@ + + +CURR_INTERMEDIATE_FILES := $(cast_subcells_results) $(CURR_TARGET_DIR)/CastSubcells.g $(CURR_INTERMEDIATE_FILES) + + +cast_aliases_results := $(CURR_TARGET_DIR)/CastAliasesParser.java \ + $(CURR_TARGET_DIR)/CastAliasesParserTokenTypes.java \ + $(CURR_TARGET_DIR)/CastAliasesParserTokenTypes.txt \ + $(CURR_TARGET_DIR)/expandedCastAliases.g + +$(CURR_TARGET_DIR)/CastAliases.g: $(CURR_PROJECT_DIR)/CastAliases.g + cp $< $@ + chmod u+w $@ + +$(cast_aliases_results): $(CURR_TARGET_DIR)/CastTwoParser.java $(CURR_TARGET_DIR)/CastAliases.g $(CURR_TARGET_DIR)/CastTwo.g + cd $(@D) && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) -glib CastTwo.g CastAliases.g + touch $@ + + +CURR_INTERMEDIATE_FILES := $(cast_aliases_results) $(CURR_TARGET_DIR)/CastAliases.g $(CURR_INTERMEDIATE_FILES) + + +cast_assert_results := $(CURR_TARGET_DIR)/CastAssertParser.java \ + $(CURR_TARGET_DIR)/CastAssertParserTokenTypes.java \ + $(CURR_TARGET_DIR)/CastAssertParserTokenTypes.txt \ + $(CURR_TARGET_DIR)/expandedCastAssert.g + +$(CURR_TARGET_DIR)/CastAssert.g: $(CURR_PROJECT_DIR)/CastAssert.g + cp $< $@ + chmod u+w $@ + +$(cast_assert_results): $(CURR_TARGET_DIR)/CastTwoParser.java $(CURR_TARGET_DIR)/CastAssert.g $(CURR_TARGET_DIR)/CastPrs.g + cd $(@D) && JAVAFILES_CLASSES_JAR_ROOT='$(JAVAFILES_CLASSES_JAR_ROOT)' $(ANTLR) -glib "CastPrs.g;CastTwo.g" CastAssert.g + touch $@ + + +CURR_INTERMEDIATE_FILES := $(cast_assert_results) $(CURR_TARGET_DIR)/CastAssert.g $(CURR_INTERMEDIATE_FILES) + + +MAKE_ANTLR_RULES_G_FILE_NAME := CastTwoTree.g +MAKE_ANTLR_RULES_LEXER_NAME := +MAKE_ANTLR_RULES_PARSER_NAME := CastTwoTreeParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := CastTwoTreeParser +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk + +$(CURR_TARGET_DIR)/CastTwoTreeParser.java : $(CURR_TARGET_DIR)/CastTwoParser.java + +MAKE_ANTLR_RULES_G_FILE_NAME := DumbTwo.g +MAKE_ANTLR_RULES_LEXER_NAME := DumbTwoLexer +MAKE_ANTLR_RULES_PARSER_NAME := DumbTwoParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := DumbTwo +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk + +CURR_INTERMEDIATE_FILES := $(CURR_TARGET_DIR)/DumbTwoParserTokenTypes.java \ + $(CURR_TARGET_DIR)/DumbTwoParserTokenTypes.txt \ + $(CURR_INTERMEDIATE_FILES) diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/package.html b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/package.html new file mode 100644 index 0000000000..3f26080fec --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/impl/package.html @@ -0,0 +1,187 @@ + + +Internals of the Cast Parser + + + + +

    +Cast is parsed by ANTLR-generated +Java. There were massive syntax changes at the end of 2001 which +caused the creation of a new parser. The main files of the old parser +are com/avlsi/cast/impl/Cast.g and com/avlsi/cast/impl/CastTree.g. +The equivalent files in the new parser are +com/avlsi/cast2/impl/CastTwo.g and +com/avlsi/cast2/impl/CastTwoTree.g. The old parser is deprecated. It +should be kept working, but no bug fixes or code tidying are +occuring. Many of the Java utility files in com/avlsi/cast/ and +com/avlsi/cast/impl are used by both the old and the new parsers. All +tools work with the old and the new parsers, controlled by the option +"--cast-version=#", where the number is either 1 or 2. Other utility +files are in com/avlsi/cell and com/avlsi/tools/cosim. + +

    +CastTwo.g produces a lexer and a parser. For each file, the parser +generates an abstract +syntax tree of lexer tokens which retains information on the file, +line, and column each token came from. Error handling in the tree parser uses this information to +print out informative error messages. Many tokens are artificially +generated. If these tokens are used for file/line/column info, they +must have it set, either by cloning it from a real token using the +copyInfo() function, or by converting one of the tokens originally +discarded by the parser into another token type. Lack of +file/line/column info can be hard to find programmatically, so bug 762 is a +dropbox for cast that causes error messages with bad file/line/column +information. + +

    +Much of the complexity of cast parsing is in CastTwoTree.g, the tree parser. Complex, +hard-to-understand, and likely to fail parts of this include baseType, the many +meanings of "environment", and refinement, +the inheritance process. + +

    +The tree parser can accept the ASTs of files generated by the +first-sweep parser, but most of its work is done on individual cells, +not files. When given a file, the tree parser pulls in the imported +files and cells, handles the instantiation of anything at the top +level (which shouldn't happen any +more), and makes UserDefinedValues +out of the cell and channel definitions. UserDefinedValues are very +close to the original AST and contain most of it, split into different +trees for the body, the ports, and so on. + +

    +The main work of the tree parser is producing InstanceValues. +InstanceValues represent instances of cells or channels. They have +their metaparameters filled in and they have been fully-processed, +lacking only context (the cell they will be instantiated in). In +fact, they contain a CellInterface. +The CastParserEnvironment +requests instances via doBaseType(), +or they may be triggered in response to subcells and ports of a cell +that has already been requested. + +

    Error Handling

    + +

    +There are three basic sorts of error handling in cast parsing: +syntaxError, fatalError, and SemanticWrapperException. +syntaxError is a function in both CastTwo.g and CastTwoTree.g. It's +not properly an error. Its purpose is to report, without stopping or +changing the parsing, on deprecated or otherwise frowned-upon syntax. +It is controlled by the verbose flag. fatalError produces the same +sort of message as syntaxError does, but halts parsing immediately and +doesn't heed the verbose flag. It might be implemented via +SemanticWrapperException in the future. + +

    +Each antlr function in the tree parser evaluates to a java function +which throws RecognitionException and SemanticException. These mean, +respectively, "got a weirdly-formed tree/got an unexpected token" and +"something more complicated went wrong". We've subclassed +SemanticException to SemanticWrapperException, +which wraps another exception together with file/line/column +information. SemanticWrapperException preserves the original stack +trace to make debugging easier. It gets the file/line/column info +from an ASTWithInfo. In some cases +the ASTWithInfo doesn't have proper info; bug 762 +addresses these. They're almost always easy to fix. (bug 589 is an +example of one which is harder to fix) + +

    +Any thrown exception which doesn't go through +SemanticWrapperException confuses later tools. This includes any sort +of RunTimeException, and, in most places, RecognitionException. +RecognitionExceptions have their own file/line numbers, but they're +still annoying for tools like dsim, which often want to catch parsing +errors and continue. + +

    Ambiguous Terms

    + + +

    Differences Between Old and New Cast Syntax

    + +

    +First of all, the transition is not +complete. The new javablock syntax is useful for most current tasks, +but not +complete. Much of the old syntax is still accepted with only a +syntaxError (warning), even though parts of it will misbehave when +combined with refinement. All tools are designed to use either one, and +most internal data structures are part of both parsers. (Some of the +data structures are unique to new cast.) + +

    Mike's spec for +new cast + +

    Dangerous Areas

    + +

    baseType, in the tree parser. It's been +split up into a couple of utility functions, but it needs refactoring +and care. Much of the work of refinment is here; the rest is in +CellImpl and the data structures inside CellImpl. + +

    IDENT parsing in the lexer. There's currently no good way to fix +bug 501. A +possible way around this might be to make DOT_IDENT a lexer-generated +token instead of a parser rule. + +

    Refinement. Refinement mostly uses data from +CellImpl, which is a datatype intended for the users of the +cast parser. Many of the restrictions on things not changing during +refinement (removing ports, refining flattened cells, etc) are due to +this. + +

    Ex-globals. Implied ports and refinable constants in the top-level +of a cell have taken the place of globals, but there's still a lot of +code extant that either supports the scoped global +hack (a previous solution to having different "globals" in +different areas of the chip) or otherwise treats nodes with names +ending in '!' differently. + + + + + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/CastFileServer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/CastFileServer.java new file mode 100644 index 0000000000..41fc0664a7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/CastFileServer.java @@ -0,0 +1,181 @@ +package com.avlsi.cast2.util; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.io.OutputStream; +import java.security.Permission; +import java.util.StringTokenizer; + +import com.avlsi.cast.CastCacheManager; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +public class CastFileServer { + private boolean exitOkay; + + private static class NoCloseOutputStream extends FilterOutputStream { + public NoCloseOutputStream(OutputStream os) { + super(os); + } + public void close() throws IOException { + flush(); + } + } + + private void installSM() { + final SecurityManager sm = new SecurityManager() { + public void checkExit(int status) { + if (status != 0 && !exitOkay) { + super.checkExit(status); + throw new SecurityException(Integer.toString(status)); + } + } + public void checkPermission(Permission perm) { } + }; + System.setSecurityManager(sm); + } + + public CastFileServer() { + exitOkay = false; + installSM(); + } + + private void processLine(final String line) throws Exception { + final StringTokenizer tokenizer = new StringTokenizer(line); + if (tokenizer.countTokens() < 4) { + throw new IllegalArgumentException("Invalid line: " + line); + } + + // Where to redirect stdout, and stderr of the program + final String output = tokenizer.nextToken(); + final String error = tokenizer.nextToken(); + + // Use reflection to get main(String[]) + final String className = tokenizer.nextToken(); + final Class app = Class.forName(className); + final Method mainRoutine = + app.getMethod("main", new Class[] { + Class.forName("[Ljava.lang.String;") + }); + + // Setup arguments to the program + final String realargs[] = new String[tokenizer.countTokens()]; + int i = 0; + while (tokenizer.hasMoreTokens()) { + realargs[i++] = tokenizer.nextToken(); + } + + // Redirect stdout + final OutputStream fout; + if (output.equals("-")) { + fout = new NoCloseOutputStream(System.out); + } else { + fout = new FileOutputStream(output); + } + System.setOut(new PrintStream(fout)); + + // Redirect stderr + final OutputStream ferr; + if (error.equals("-")) { + ferr = new NoCloseOutputStream(System.err); + } else { + ferr = new FileOutputStream(error); + } + System.setErr(new PrintStream(ferr)); + + // Invoke program + mainRoutine.invoke(null, new Object[] { realargs }); + + // Flush the streams + System.out.flush(); + System.err.flush(); + + // Close any open file handles + System.out.close(); + System.err.close(); + } + + private static void status(final String x) { + System.err.println("CastFileServer: " + x); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + + final CastFileParser castParser = + CastCacheManager.getDefault().getCastFileParser( + new FileSearchPath(castRoot), castVersion, + new StandardParsingOption(theArgs)); + CastCacheManager.getDefault().setCastFileParser(castParser); + + final BufferedReader br = + new BufferedReader(new InputStreamReader(System.in)); + + final CastFileServer server = new CastFileServer(); + String line; + final PrintStream out = System.out; + final PrintStream err = System.err; + while ((line = br.readLine()) != null) { + server.exitOkay = false; + String exited = null; + Exception error = null; + AssertionError assertion = null; + try { + server.processLine(line); + } catch (InvocationTargetException e) { + final Throwable cause = e.getCause(); + if (cause instanceof SecurityException) { + exited = cause.getMessage(); + } else if (cause instanceof Exception) { + error = (Exception) cause; + } else if (cause instanceof AssertionError) { + assertion = (AssertionError) cause; + } else { + throw new Error(cause); + } + } catch (Exception e) { + error = e; + } + System.setOut(out); + System.setErr(err); + if (exited != null) { + status("EXIT " + exited); + } else if (error != null) { + status("EXCEPTION"); + error.printStackTrace(); + } else if (assertion != null) { + status("EXCEPTION"); + assertion.printStackTrace(); + } else { + status("SUCCESS"); + } + status("READY"); + System.out.flush(); + System.err.flush(); + } + server.exitOkay = true; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionFilter.java new file mode 100644 index 0000000000..1d66a2380c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionFilter.java @@ -0,0 +1,21 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.util; + +public interface DirectiveActionFilter { + /** + * Intercept calls to the given DirectiveActionInterface, do + * processing on the arguments of the call, and optionally forward the + * call. + * + * @param action The underlying DirectiveActionInterface + * @return a new DirectiveActionInterface that does the + * appropriate manipulations. + **/ + DirectiveActionInterface filter(DirectiveActionInterface action); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionInterface.java new file mode 100644 index 0000000000..8060b2b62a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveActionInterface.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.util; + +import java.io.IOException; + +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.BlockInterface; + +public interface DirectiveActionInterface { + + + void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType ) throws IOException ; + void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) throws IOException ; + void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) throws IOException; + void doBlockInterface(BlockInterface block) throws IOException ; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveFilter.java new file mode 100644 index 0000000000..570153f86c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveFilter.java @@ -0,0 +1,146 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.cast2.util; + +import java.io.IOException; +import java.util.Set; + +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.DirectiveBlock; + +/** + * A utility class containing useful DirectiveActionFilter + * implementations that filters directives. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ + +public final class DirectiveFilter { + public static final DirectiveActionFilter NULL = new DirectiveActionFilter() + { + public DirectiveActionInterface filter(final DirectiveActionInterface action) + { + return new DirectiveActionInterface() { + public void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType) + throws IOException { + action.doUnParameterizedDirective(block, db, directive, + value, valueType); + } + public void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) + throws IOException { + action.doParameterizedDirectiveValue(block, db, directive, + parameter, value, + parameterType, + valueType); + } + public void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) + throws IOException { + action.doParameterizedDirectiveType(block, db, directive, + parameterType, + valueType); + } + public void doBlockInterface(BlockInterface block) + throws IOException { + action.doBlockInterface(block); + } + }; + } + }; + + /** + * Filtering based on the names of directives. + **/ + public static class ByDirective implements DirectiveActionFilter { + private final Set set; + private final boolean mode; + + /** + * Constructs a new filter. The filter has two modes: + *

      + *
    • include: any directive not in the set is filtered out. + *
    • exclude: any directive in the set is filtered out. + *
    + * + * @param mode true if include mode is desired, false if exclude mode + * is desired. + * @param set a set of directives. + **/ + public ByDirective(final boolean mode, final Set set) { + this.set = set; + this.mode = mode; + } + + public ByDirective getReverse() { + return new ByDirective(!mode, set); + } + + public DirectiveActionInterface filter(final DirectiveActionInterface action) + { + return new DirectiveActionInterface() { + public void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType) + throws IOException { + if (set.contains(directive) == mode) { + action.doUnParameterizedDirective(block, db, directive, + value, valueType); + } + } + public void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) + throws IOException { + if (set.contains(directive) == mode) { + action.doParameterizedDirectiveValue(block, db, + directive, + parameter, value, + parameterType, + valueType); + } + } + public void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) + throws IOException { + if (set.contains(directive) == mode) { + action.doParameterizedDirectiveType(block, db, + directive, + parameterType, + valueType); + } + } + public void doBlockInterface(BlockInterface block) + throws IOException { + action.doBlockInterface(block); + } + }; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveOverride.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveOverride.java new file mode 100644 index 0000000000..c4abac043b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveOverride.java @@ -0,0 +1,102 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.Iterator; + +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.util.container.Pair; + +/** + * Redirect all operations related to a particular directive to another + * directive interface. + **/ +public class DirectiveOverride implements DirectiveInterface { + private final DirectiveInterface original, replacement; + private final String which; + public DirectiveOverride(final DirectiveInterface original, + final DirectiveInterface replacement, + final String which) { + assert which != null && original != null && replacement != null; + this.original = original; + this.replacement = replacement; + this.which = which; + } + + public Object getDefaultValue(final String key, final String memberType) + throws UnknownDirectiveException { + return which.equals(key) ? replacement.getDefaultValue(key, memberType) + : original.getDefaultValue(key, memberType); + } + + public Map getValues(final String key, final String memberType) + throws UnknownDirectiveException { + return which.equals(key) ? replacement.getValues(key, memberType) + : original.getValues(key, memberType); + } + + public Object lookup(final String key) throws UnknownDirectiveException { + return which.equals(key) ? replacement.lookup(key) + : original.lookup(key); + } + + public boolean containsDirective(final String key) + throws UnknownDirectiveException { + return which.equals(key) ? replacement.containsDirective(key) + : original.containsDirective(key); + } + + public Object lookup(final String key, final String memberType, + final Object parameter) + throws UnknownDirectiveException { + return which.equals(key) ? replacement.lookup(key, memberType, parameter) + : original.lookup(key, memberType, parameter); + } + + public boolean isKey(final String key) { + return which.equals(key) ? replacement.isKey(key) + : original.isKey(key); + } + + public boolean isKey(final String key, final String memberType) { + return which.equals(key) ? replacement.isKey(key, memberType) + : original.isKey(key, memberType); + } + + public Iterator paramEntryIterator() { + final Collection result = new ArrayList(); + for (Iterator i = original.paramEntryIterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Pair p = (Pair) entry.getKey(); + if (!p.getFirst().equals(which)) result.add(entry); + } + for (Iterator i = replacement.paramEntryIterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Pair p = (Pair) entry.getKey(); + if (p.getFirst().equals(which)) result.add(entry); + } + return result.iterator(); + } + + public Iterator noparamEntryIterator() { + final Collection result = new ArrayList(); + for (Iterator i = original.noparamEntryIterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + if (!entry.getKey().equals(which)) result.add(entry); + } + for (Iterator i = replacement.noparamEntryIterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + if (entry.getKey().equals(which)) result.add(entry); + } + return result.iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveUtils.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveUtils.java new file mode 100644 index 0000000000..7386606417 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveUtils.java @@ -0,0 +1,1001 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cast2.util; + +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.List; +import java.util.HashSet; +import java.util.HashMap; +import java.util.LinkedHashMap; + +import com.avlsi.cast2.directive.impl.DirectiveComparator; +import com.avlsi.cast2.directive.impl.DirectiveSource; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.layout.LayerCallback; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cosim.ChannelTimingInfo; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Pair; + +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.BinaryFunction; + +/** + * Class to hold functions operating on the maps returned by the + * directive parser. + * @author Aaron Denney + * @version $Date$ + **/ + +public final class DirectiveUtils { + /** + * Static class. Unconstructable. + * @deprecated + **/ + private DirectiveUtils() { + } + + public static Object gruntDirective(BlockInterface b, + String directive) { + final DirectiveBlock db = getDirectiveBlock(b); + if (db == null) { + return DirectiveTable.lookupDirective(b.getType(), directive).getSecond(); + } else { + Object o = null; + assert db.isKey(directive) : "Directive " + directive + + " not defined in " + b.getType() + + " block"; + try { + o = db.lookup(directive); + } catch (UnknownDirectiveException e) { + System.err.println(directive + " not registered?"); + } + return o; + } + } + + /** + * Does the grunt work to get a nonparametrized directive attached to the + * cell. + * + * @param cell Cell to look in + * @param directive Name of directive to look up + * + * @return The value of the directive. If this cell (and its supercells) do not + * set this directive, the default value (which may be null) is returned. + **/ + public static Object getTopLevelDirective(CellInterface cell, String directive) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(cellBlock, directive); + } + + /** + * Does the grunt work to get a parametrized directive attached to the + * given block. + * + * @param b block to look for directives block in. + * @param directive Name of directive to look up. + * @param type type directive is parameterized on. + * + * @return A (possibly empty) map having all the non-default values that have been set. + **/ + public static Map gruntDirective(BlockInterface b, String directive, + String type) { + Map m = Collections.EMPTY_MAP; + final DirectiveBlock db = getDirectiveBlock(b); + if (db == null) { return m; } // no directive block. + assert db.isKey(directive, type) : "Directive " + directive + "(" + + type + ") not defined in " + + b.getType() + " block"; + try { + m = db.getValues(directive, type); + } catch (UnknownDirectiveException e) { + System.err.println(directive + "<"+type+"> not registered?"); + } + return m; + } + + /** + * Gets a parameterized directive that can be defined in multiple blocks. + * + * @param blocks An list of BlockInterfaces, eqach one overriding the next + * @param directive Name of directive to look up + * @param type type directive is parameterized on. + * + * @return A (possibly empty) map having all the non-default values that have been set. + **/ + public static Map getMultipleBlockDirective(List blocks, + String directive, + String type) { + final Map map = new HashMap(); + for(Iterator i = blocks.iterator(); i.hasNext();) { + final BlockInterface block = (BlockInterface) i.next(); + map.putAll(gruntDirective(block, directive, type)); + } + return map; + } + + public static BlockInterface getUniqueBlock(BlockInterface block, + String type ) { + + BlockIterator subBlockIter = block.iterator(type); + + Debug.assertTrue(subBlockIter.hasNext(), "No " + type + " block exists!"); + BlockInterface b = subBlockIter.next(); + Debug.assertTrue(!subBlockIter.hasNext(), "Multiple " + type + " blocks?"); + + return b; + } + + public static Object getBlockDirective(CellInterface cell, String block, + String directive) { + return gruntDirective(getUniqueBlock(cell.getBlockInterface(), block), + directive); + } + + public static Map getBlockDirective(CellInterface cell, String block, + String directive, String type) { + return gruntDirective(getUniqueBlock(cell.getBlockInterface(), block), + directive, type); + } + + /** + * Does the grunt work to get a parametrized directive attached to the + * cell. + * + * @param cell Cell to look in + * @param directive Name of directive to look up + * @param type type directive is parameterized on. + * + * @return A (possibly empty) map having all the non-default values that have been set. + **/ + public static Map getTopLevelDirective(CellInterface cell, String directive, String type) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(cellBlock, directive, type); + } + + /** + * Does the grunt work to get a parametrized directive attached to the prs + * block. + * + * @param cell Cell to look in for directives attached to prs block. + * @param directive Name of directive to look up + * @param type type directive is parameterized on. + * + * @return A (possibly empty) map having all the non-default values that have been set. + **/ + public static Map getPrsDirective(CellInterface cell, String directive, String type) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.PRS), directive, type); + } + + public static Object getPrsDirective(CellInterface cell, String directive) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.PRS), directive); + } + + /** + * Does the grunt work to get a parametrized directive attached to the + * subcell block. + * + * @param cell Cell to look in for directives attached to subcell block. + * @param directive Name of directive to look up + * @param type type directive is parameterized on. + * + * @return A (possibly empty) map having all the non-default values that have been set. + **/ + public static Map getSubcellDirective(CellInterface cell, String directive, String type) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.SUBCELL), directive, type); + } + + public static Object getSubcellDirective(CellInterface cell, String directive) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.SUBCELL), directive); + } + + /** + * Does the grunt work to get a parametrized directive attached to the + * a cell specified in the env block. + * + * @param cell Cell to look in for directives attached to subcell block. + * @param directive Name of directive to look up + * @param type type directive is parameterized on. + * + * @return A (possibly empty) map having all the non-default values that have been set. + **/ + public static Map getEnvDirective(CellInterface cell, String directive, String type) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.ENV), directive, type); + } + + public static Object getEnvDirective(CellInterface cell, String directive) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.ENV), directive); + } + + public static Map getCspDirective(CellInterface cell, String directive, + String type) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.CSP), + directive, type); + } + + public static Object getCspDirective(CellInterface cell, String directive) { + BlockInterface cellBlock = cell.getBlockInterface(); + return gruntDirective(getUniqueBlock(cellBlock,BlockInterface.CSP), + directive); + } + + public static Map getJavaDirective(CellInterface cell, String directive, + String type) { + return getBlockDirective(cell, BlockInterface.JAVA, directive, type); + } + + /** + * Returns true if there is a directive block associated with + * block of type blk in cell, and if + * directive parameterized on type is a valid + * directive in that directive block. + **/ + public static boolean containsDirective(CellInterface cell, + String blk, + String directive, + String type) { + final BlockInterface cellBlock = cell.getBlockInterface(); + final BlockInterface selected = + blk.equals(BlockInterface.CELL) ? cellBlock + : getUniqueBlock(cellBlock, blk); + final DirectiveBlock db = getDirectiveBlock(selected); + return db != null && db.isKey(directive, type); + } + + /** + * Given a Map from to Boolean, give back + * the set of those that are set to TRUE. + * + * Also verify that all values are Boolean. + **/ + public static Set getExplicitTrues(Map m) { + Set s = new HashSet(); + Iterator i = m.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry e = (Map.Entry) i.next(); + if (Boolean.TRUE.equals((Boolean)e.getValue())) { + s.add(e.getKey()); + } + } + return s; + } + + /** + * Given a Map from to Boolean, give back + * the set of those that are set to FALSE. + * + * Also verify that all values are Boolean. + **/ + public static Set getExplicitFalses(Map m) { + Set s = new HashSet(); + Iterator i = m.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry e = (Map.Entry) i.next(); + if (Boolean.FALSE.equals((Boolean)e.getValue())) { + s.add(e.getKey()); + } + } + return s; + } + + /** + * Given a Map from to Integer, give back + * the set of those that are set to non-zero. + * + * Also verify that all values are Integer. + **/ + public static Set getExplicitNonZeroIntegers(Map m) { + Set s = new HashSet(); + Iterator i = m.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry e = (Map.Entry) i.next(); + Integer x = (Integer) e.getValue(); + if ((x!=null) && (x.intValue()>0)) { + s.add(e.getKey()); + } + } + return s; + } + + /* + * HalfOperators are returned as (HierName, Boolean) pairs, + * with the Boolean possibly being null to specify both up and Down. See PrsCallback. + */ + + /** + * Extracts the kvps whose keys are up or both up and down + * from a map of into a map of . + **/ + public static Map getUps(Map m) { + Map rv = new LinkedHashMap(); + Iterator i = m.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry e = (Map.Entry) i.next(); + Pair p = (Pair) e.getKey(); + Boolean direction = (Boolean) p.getSecond(); + HierName h = (HierName) p.getFirst(); + + if (Boolean.TRUE.equals(direction) || direction == null) { + rv.put(h,e.getValue()); + } + } + + return rv; + } + + /** + * Extracts the kvps whose keys are down or both up and down + * from a map of into a map of . + **/ + public static Map getDowns(Map m) { + Map rv = new LinkedHashMap(); + Iterator i = m.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry e = (Map.Entry) i.next(); + Pair p = (Pair) e.getKey(); + Boolean direction = (Boolean) p.getSecond(); + HierName h = (HierName) p.getFirst(); + + if (Boolean.FALSE.equals(direction) || direction == null) { + rv.put(h,e.getValue()); + } + } + + return rv; + } + + /** + * Return a new map whose keys are those of m, + * but canonicalized according to a. + * + * @param a The aliased set determining canonicalness. + * @param m The map whose keys are to be canonized. + * + * @return A new map with the specified properties. + **/ + public static Map canonizeKey(AliasedSet a, Map m) { + return canonizeKey(a, m, REPLACE); + } + + public static BinaryFunction REPLACE = new BinaryFunction() { + public Object execute(final Object a, final Object b) { + return b; + } + }; + + public static BinaryFunction MIN = new BinaryFunction() { + public Object execute(final Object a, final Object b) { + return ((Comparable) a).compareTo(b) <= 0 ? a : b; + } + }; + + public static BinaryFunction MAX = new BinaryFunction() { + public Object execute(final Object a, final Object b) { + return ((Comparable) a).compareTo(b) >= 0 ? a : b; + } + }; + + public static Map canonizeKey(AliasedSet a, Map m, BinaryFunction merge) { + Map rv = new LinkedHashMap(); + Iterator i = m.keySet().iterator(); + while (i.hasNext()) { + Object o = i.next(); + Object x = a.getCanonicalKey(o); + Object key = x == null ? o : x; + + Object value = m.get(o); + if (rv.containsKey(key)) value = merge.execute(rv.get(key), value); + + rv.put(key, value); + } + return rv; + } + + /** + * Return a new set whose members are those of s, + * but canonicalized according to a. + * + * @param a The aliased set determining canonicalness. + * @param s The set whose members are to be canonized. + * + * @return A new set with the specified properties. + **/ + public static Set canonize(AliasedSet a, Set s) { + Set rv = new HashSet(); + Iterator i = s.iterator(); + while (i.hasNext()) { + Object o = i.next(); + Object x = a.getCanonicalKey(o); + if (x == null) { + rv.add(o); + } else { + rv.add(x); + } + } + return rv; + } + + /* + * Return a DirectiveInterface that has values of type + * NODE_TYPE and HALFOP_TYPE canonicalized + * according to the given AliasedSet. + * + * @param alias An AliasedSet containing alias information. + * @param db The DirectiveInterface to canonicalize. + * + * @return a canonicalized DirectiveInterface. + */ + /* + // XXX: Perhaps some day. + public static DirectiveInterface canonize(final AliasedSet alias, + final DirectiveInterface db) { + + return new DirectiveInterface() { + public Object getDefaultValue(String key, String memberType) + throws UnknownDirectiveException { + return alias.getDefaultValue(key, memberType); + } + + public Map getValues(String key, String memberType) + throws UnknownDirectiveException { + } + + public Object lookup(String key) throws UnknownDirectiveException { + } + + public boolean containsDirective(String key) + throws UnknownDirectiveException { + } + + public Object lookup(String key, String memberType, + Object parameter) + throws UnknownDirectiveException { + } + + public boolean isKey(String key) { + } + + public boolean isKey(String key, String memberType) { + } + + public Iterator paramEntryIterator() { + } + + public Iterator noparamEntryIterator() { + } + }; + } + */ + + /** + * Looks up h in map m returning the value of the Float that corresponds + * to key h. If h is not in the map returns nokey. + * + * @param h The HierName to look up. + * @param m The map to look it up in. + * @param nokey The return value if h is not in the map. + **/ + public static float getFromFloatMap(HierName h, Map m, float nokey) { + float rv = nokey; + if (m != null) { + Float x = (Float) m.get(h); + if (x != null) { + rv = x.floatValue(); + } + } + return rv; + } + + /** + * Return the directive block associated with a block. + * + * @param block Where to get the directive block. + * @return The directive block associated with the given block, or + * null if there is no directive block. + **/ + public static DirectiveBlock getDirectiveBlock(BlockInterface block) { + final BlockIterator bi = block.iterator(BlockInterface.DIRECTIVE); + if(!bi.hasNext()) return null; + + final DirectiveBlock db = (DirectiveBlock) bi.next(); + assert !bi.hasNext() : "Multiple directive blocks attached to " + block.getType() + " block?"; + return db; + } + + private static class CompareDirective implements DirectiveActionInterface { + private static class Exception extends RuntimeException { + public Exception(final String message) { + super(message); + } + + public Exception(final String message, final Throwable cause) { + super(message, cause); + } + } + + private final DirectiveBlock target; + private final DirectiveComparator test; + + public CompareDirective(final DirectiveBlock target, + final DirectiveComparator test) { + this.target = target; + this.test = test; + } + + public void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType) + throws IOException { + final Object v; + try { + v = target.lookup(directive); + } catch (UnknownDirectiveException e) { + throw new Exception("Invalid directive: " + directive, e); + } + if (!test.compare(block.getType(), valueType, value, v)) + { + throw new Exception("Values are not equivalent: " + v + " vs " + value); + } + } + + public void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) + throws IOException { + final Object v; + try { + v = target.lookup(directive, parameterType, parameter); + } catch (UnknownDirectiveException e) { + throw new Exception("Invalid directive: " + directive, e); + } + if (!test.compare(block.getType(), valueType, value, v)) + { + throw new Exception("Values are not equivalent: " + v + " vs " + value); + } + } + + public void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) + throws IOException { } + + public void doBlockInterface(BlockInterface block) throws IOException { + } + } + + public static boolean equalDirectiveBlock(final BlockInterface block1, + final DirectiveActionFilter f1, + final BlockInterface block2, + final DirectiveActionFilter f2, + final DirectiveComparator comp) { + return equalDirectiveBlock(block1, getDirectiveBlock(block1), f1, + block2, getDirectiveBlock(block2), f2, + comp); + } + + public static boolean equalDirectiveBlock(final BlockInterface block1, + final DirectiveBlock db1, + final DirectiveActionFilter f1, + final BlockInterface block2, + final DirectiveBlock db2, + final DirectiveActionFilter f2, + final DirectiveComparator comp) { + if ((db1 == null || db2 == null) && db1 != db2) return false; + try { + final DirectiveWalker walker1 = + new DirectiveWalker(f2.filter(new CompareDirective(db2, comp))); + walker1.walk(block1, db1); + + final DirectiveWalker walker2 = + new DirectiveWalker(f1.filter(new CompareDirective(db1, comp))); + walker2.walk(block2, db2); + } catch (UnknownDirectiveException e) { + return false; + } catch (IOException e) { + throw new AssertionError("Cannot happen."); + } catch (CompareDirective.Exception e) { + return false; + } + return true; + } + + private static HierName makeHierName(final String s) { + try { + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName from " + s, e); + } + } + + public static Object parseDirective(final String type, final String val) { + if (type.equals(DirectiveConstants.INT_TYPE)) { + return Integer.valueOf(val); + } else if (type.equals(DirectiveConstants.FLOAT_TYPE)) { + return Float.valueOf(val); + } else if (type.equals(DirectiveConstants.DOUBLE_TYPE)) { + return Double.valueOf(val); + } else if (type.equals(DirectiveConstants.BOOLEAN_TYPE)) { + return Boolean.valueOf(val); + } else if (type.equals(DirectiveConstants.STRING_TYPE)) { + return val; + } else if (type.equals(DirectiveConstants.NODE_TYPE)) { + return makeHierName(val); + } else if (type.equals(DirectiveConstants.HALFOP_TYPE)) { + return makeHierName(val); + } else if (type.equals(DirectiveConstants.CHANNEL_TYPE)) { + return makeHierName(val); + } else if (type.equals(DirectiveConstants.INSTANCE_TYPE)) { + return makeHierName(val); + } else if (type.equals(DirectiveConstants.LAYER_TYPE)) { + return LayerCallback.getInstance().resolve(DirectiveConstants.LAYER_TYPE, val, null); + } else { + return null; + } + } + + public static Map scaleFloatMap(final Map spec, + final float scale) { + assert spec != null; + if (scale == 1) return spec; + final LinkedHashMap result = new LinkedHashMap(); + for (Iterator i = spec.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + result.put(entry.getKey(), + new Float(((Float) entry.getValue()).floatValue() * scale)); + } + return result; + } + + /** + * Scales the ntpc_spec directives specified in an environment + * cell appropriately by the value specified by the + * ntpc_scaling top-level directive. + * + * @param cell Top level cell containing the environment + * @param spec A map of nodes to ntpc_spec. + * @return A map of nodes to ntpc_spec, taking into account ntpc_scaling. + * If ntpc_scaling is 1, then spec will be returned. + **/ + public static Map scaleNtpcSpec(final CellInterface cell, + final Map spec ) { + final float scale = + ((Float) getTopLevelDirective + (cell, + DirectiveConstants.NTPC_SCALING)).floatValue(); + return scaleFloatMap(spec, scale); + } + + /** + * Scales the ntpc_spec directives specified in an environment + * cell appropriately by the value specified by the + * ntpc_scaling_signoff top-level directive. + * + * @param cell Top level cell containing the environment + * @param spec A map of nodes to ntpc_spec. + * @return A map of nodes to ntpc_spec, taking into account ntpc_scaling_signoff. + * If ntpc_scaling_signoff is 1, then spec will be returned. + **/ + public static Map scaleNtpcSpecSignoff(final CellInterface cell, + final Map spec ) { + final float scale = + ((Float) getTopLevelDirective + (cell, + DirectiveConstants.NTPC_SCALING_SIGNOFF)).floatValue(); + return scaleFloatMap(spec, scale); + } + + /** + * Gets the value of a half-operator directive for the specified cell, + * node, and direction. + **/ + public static Object getHalfOpDirectiveValue( + final /*@ non_null @*/ CellInterface cell, + final /*@ non_null @*/ String directive, + final /*@ non_null @*/ HierName nodeName, + final boolean direction, + final /*@ non_null @*/ Cadencize cadencize) { + final Map/*,Object>*/ halfOpMap = + getTopLevelDirective(cell, directive, + DirectiveConstants.HALFOP_TYPE); + final Map/**/ nodeMap; + if (direction) + nodeMap = getUps(halfOpMap); + else + nodeMap = getDowns(halfOpMap); + final AliasedSet/**/ localNodes = + cadencize.convert(cell).getLocalNodes(); + final Map/**/ canonicalNodeMap = + canonizeKey(localNodes, nodeMap); + return canonicalNodeMap.get(nodeName); + } + + public static String dumpDirectiveBlock(BlockInterface bi) { + final StringBuilder buf = new StringBuilder(); + for (BlockIterator it = bi.iterator(BlockInterface.DIRECTIVE); + it.hasNext(); ) { + final DirectiveBlock dirBlock = (DirectiveBlock) it.next(); + for (Iterator entryIter = dirBlock.paramEntryIterator(); + entryIter.hasNext(); ) { + final Map.Entry entry = (Map.Entry) entryIter.next(); + buf.append(entry.getKey() + " => " + entry.getValue() + "\n"); + } + } + return buf.toString(); + } + + private static void propagateWireDirective(final CellInterface cell, + final NetProperty.Cache cache, + final String dir, + final BinaryFunction update, + final Cadencize cad) { + final Map result = NetProperty.getNodeProperties(cache, cell, cad, NetProperty.WireProperty.getFactory(new NetProperty.WireProperty.WireDirective(cad, dir, update), update)); + final DirectiveSource src = new DirectiveSource(BlockInterface.SUBCELL); + for (Iterator i = result.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final NetProperty.Property property = + (NetProperty.Property) entry.getValue(); + if (property.getValue() != null) { + src.definition(dir, DirectiveConstants.NODE_TYPE, entry.getKey(), property.getValue()); + } + } + final BlockInterface subcell = + cell.getBlockInterface().iterator(BlockInterface.SUBCELL).next(); + final DirectiveInterface old = getDirectiveBlock(subcell); + final DirectiveInterface replace = src.getDirectiveInterface(); + final DirectiveInterface nevv = old == null ? replace : + new DirectiveOverride(old, replace, dir); + final BlockIterator it = subcell.iterator(BlockInterface.DIRECTIVE); + if (it.hasNext()) { + it.next(); + it.set(new DirectiveBlock(nevv)); + } else { + it.add(new DirectiveBlock(nevv)); + } + } + public static void propagateWireDirective(final CellInterface cell, + final Cadencize cad) { + propagateWireDirective(cell, new NetProperty.Cache(), DirectiveConstants.WIREWIDTH, NetProperty.WireProperty.MAX, cad); + propagateWireDirective(cell, new NetProperty.Cache(), DirectiveConstants.WIRESPACE, NetProperty.WireProperty.MAX, cad); + propagateWireDirective(cell, new NetProperty.Cache(), DirectiveConstants.WIRELENGTH, NetProperty.WireProperty.MIN, cad); + propagateWireDirective(cell, new NetProperty.Cache(), DirectiveConstants.WIRESPAN, NetProperty.WireProperty.MIN, cad); + propagateWireDirective(cell, new NetProperty.Cache(), DirectiveConstants.RESET_NET, NetProperty.WireProperty.OR, cad); + } + + public static ChannelTimingInfo getTiming(final CellInterface cell, + final String channel) { + return getTiming(cell, channel, 1); + } + + public static ChannelTimingInfo getTiming(final CellInterface cell, + final String channel, + final int defStages) { + return getTiming(cell, BlockInterface.CSP, channel, defStages); + } + + public static ChannelTimingInfo getTiming(final CellInterface cell, + final String block, + final String channel, + final int defStages) { + // find dynamic_slack, a scalar quantity that describes the maximum + // number of tokens in a channel while still cycling at cycle_time + final Integer dynslack = (Integer) getBlockDirective(cell, block, DirectiveConstants.DYNAMIC_SLACK, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + + // find cycle_time + final Float defaultct = (Float) getBlockDirective(cell, block, DirectiveConstants.DEFAULT_CYCLE_TIME); + final Float ct = (Float) getBlockDirective(cell, block, DirectiveConstants.CYCLE_TIME, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final float cycleTime = + ct == null ? defaultct.floatValue() : ct.floatValue(); + + // find cycle_time_in + final Float cti = (Float) getBlockDirective(cell, block, DirectiveConstants.CYCLE_TIME_IN, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final float cycleTimeIn = cti == null ? cycleTime : cti.floatValue(); + + // find cycle_time_out + final Float cto = (Float) getBlockDirective(cell, block, DirectiveConstants.CYCLE_TIME_OUT, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final float cycleTimeOut = cto == null ? cycleTime : cto.floatValue(); + + // find slack + final int slack; + final Integer _slack = (Integer) getBlockDirective(cell, block, DirectiveConstants.SLACK, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final Integer _stages = (Integer) getBlockDirective(cell, block, DirectiveConstants.STAGES, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final Float sps = (Float) getBlockDirective(cell, block, DirectiveConstants.SLACK_PER_STAGE); + final int stages = _stages == null ? defStages : _stages.intValue(); + final float dynamicCycleTime; + if (_slack == null) { + if (dynslack == null) { + slack = (int) Math.ceil(stages * sps.floatValue()); + dynamicCycleTime = cycleTime; + } else { + slack = dynslack.intValue(); + // find cycle_time after dynamic_slack adjustment + dynamicCycleTime = cycleTime / dynslack.intValue(); + } + } else { + slack = _slack.intValue(); + if (_stages != null) { + System.err.println("WARNING: Both slack and stages specified for channel " + channel + " in " + cell.getFullyQualifiedType() + "; using slack directive"); + } + dynamicCycleTime = cycleTime; + if (dynslack != null) { + System.err.println("WARNING: Both slack and dynamic_slack specified for channel " + channel + " in " + cell.getFullyQualifiedType() + "; ignoring dynamic_slack directive"); + } + } + + // find forward latency + final float latency; + final Float _latency = (Float) getBlockDirective(cell, block, DirectiveConstants.LATENCY, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + if (_latency == null) { + final Float lps = (Float) getBlockDirective(cell, block, DirectiveConstants.LATENCY_PER_STAGE); + latency = lps.floatValue() * stages; + } else { + latency = _latency.floatValue(); + } + + if (slack == 0 && latency > 0) { + System.err.println("WARNING: Non-zero latency ignored on slack zero channel " + channel + " in " + cell.getFullyQualifiedType()); + } + + // find up transition and down transistion delays in DSim units + final Float _defaultUpDelay = (Float) getTopLevelDirective(cell, DirectiveConstants.DEFAULT_UP_DELAY); + final Float _defaultDnDelay = (Float) getTopLevelDirective(cell, DirectiveConstants.DEFAULT_DN_DELAY); + final float defaultUpDelay = _defaultUpDelay.floatValue() / 100; + final float defaultDnDelay = _defaultDnDelay.floatValue() / 100; + + // find scale factor for data-enable and enable-data latencies + final float fbScale = cycleTimeIn >= 10 ? 1 : cycleTimeIn / 10; + final float bfScale = cycleTimeOut >= 10 ? 1 : cycleTimeOut / 10; + + // find data-enable latency + final float fbLatency; + final Float _fbLatency = (Float) getBlockDirective(cell, block, DirectiveConstants.FB, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + if (_fbLatency == null) { + fbLatency = 3; + } else { + fbLatency = _fbLatency.floatValue(); + } + + final Float _fbNeutral = (Float) getBlockDirective(cell, block, DirectiveConstants.FB_NEUTRAL, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final float fbNeutral = + Math.max(0, _fbNeutral == null ? + fbScale * (fbLatency + defaultUpDelay - 1) + : _fbNeutral.floatValue()); + + final Float _fbValid = (Float) getBlockDirective(cell, block, DirectiveConstants.FB_VALID, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final float fbValid = + Math.max(0, _fbValid == null ? + fbScale * (fbLatency + defaultDnDelay - 1) + : _fbValid.floatValue()); + + // find enable-data latency + final Float _bfLatency = (Float) getBlockDirective(cell, block, DirectiveConstants.BF, DirectiveConstants.WIDE_CHANNEL_TYPE).get(channel); + final float bfLatency; + if (_bfLatency == null) { + bfLatency = 2 * bfScale; + } else { + bfLatency = _bfLatency.floatValue(); + } + + // find the conversion to DSim units + final int timeUnit = ((Integer) getBlockDirective(cell, block, DirectiveConstants.TIME_UNIT)).intValue(); + + return new ChannelTimingInfo() { + public int getSlack() { return slack; } + public int getLatency() { + return Math.round(latency * timeUnit); + } + public int getCycleTime() { + return Math.round(dynamicCycleTime * timeUnit); + } + public int getDataNeutralEnableLatency() { + return Math.round(fbNeutral * timeUnit); + } + public int getDataValidEnableLatency() { + return Math.round(fbValid * timeUnit); + } + public int getEnableDataLatency() { + return Math.round(bfLatency * timeUnit); + } + public int getCycleTimeIn() { + return Math.round(cycleTimeIn * timeUnit); + } + public int getCycleTimeOut() { + return Math.round(cycleTimeOut * timeUnit); + } + }; + } + + public static enum IdleState { IDLE_0, IDLE_1, IDLE_UNKNOWN } + + private static IdleState getIdleState(final int s) { + switch (s) { + case 0: return IdleState.IDLE_0; + case 1: return IdleState.IDLE_1; + case 2: return IdleState.IDLE_UNKNOWN; + default: + throw new RuntimeException("Invalid idle_state constant: " + s); + } + } + + private static void getIdleState(final HierName prefix, + final AliasedSet namespace, + final Map dir, + final Map result) { + for (Map.Entry entry : dir.entrySet()) { + final HierName canon = (HierName) + namespace.getCanonicalKey( + HierName.append(prefix, entry.getKey())); + result.put(canon, getIdleState(entry.getValue())); + } + } + + private static void getIdleState(final HierName prefix, + final CellInterface cell, + final AliasedSet namespace, + final Map result) { + final Map dir = (Map) + getTopLevelDirective(cell, DirectiveConstants.IDLE_STATE, + DirectiveConstants.NODE_TYPE); + getIdleState(prefix, namespace, dir, result); + } + + /** + * Return idle_state directives as a map from canonical name to IdleState + * enum. + **/ + public static Map getIdleState( + final CellInterface cell, + final AliasedSet namespace) { + final Map result = + new HashMap(); + + for (Iterator i = cell.getPortSubcellPairs(); i.hasNext(); ) { + final Pair p = + (Pair) i.next(); + getIdleState(p.getFirst(), p.getSecond(), namespace, result); + } + + final Map topDirs = (Map) + getTopLevelDirective(cell, DirectiveConstants.IDLE_STATE, + DirectiveConstants.NODE_TYPE); + final Map prsDirs = (Map) + getPrsDirective(cell, DirectiveConstants.IDLE_STATE, + DirectiveConstants.NODE_TYPE); + getIdleState(null, namespace, topDirs, result); + getIdleState(null, namespace, prsDirs, result); + + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveWalker.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveWalker.java new file mode 100644 index 0000000000..8cb57da741 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/DirectiveWalker.java @@ -0,0 +1,102 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cast2.util; + +import java.util.Map; +import java.util.TreeMap; +import java.util.SortedMap; +import java.util.Iterator; +import java.io.IOException; +import java.util.Comparator; + +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.util.container.Pair; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.cast2.directive.UnknownDirectiveException; + +import com.avlsi.util.debug.Debug; + + +public class DirectiveWalker { + + private final DirectiveActionInterface action; + + public DirectiveWalker(DirectiveActionInterface action) { + this.action = action; + } + + public void walk(BlockInterface cellBlock, String blockType) throws UnknownDirectiveException, IOException { + BlockIterator iter = cellBlock.iterator( blockType ); + if(iter.hasNext()) { + BlockInterface block = iter.next(); + walk(block); + } + } + + public void walk(BlockInterface block) throws UnknownDirectiveException, IOException { + walk(block, DirectiveUtils.getDirectiveBlock(block) ); + } + + private static Comparator directiveComparator = + new Comparator() { + public int compare(Object a, Object b) { + return a.toString().compareTo(b.toString()); + } + }; + + public void walk(BlockInterface block, DirectiveBlock db) throws UnknownDirectiveException, IOException { + if( db == null ) + return; + action.doBlockInterface(block); + + SortedMap noParamMap = new TreeMap(directiveComparator); + for(Iterator i=db.noparamEntryIterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + noParamMap.put(entry.getKey(),entry.getValue()); + } + for(Iterator i=noParamMap.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + Object value = entry.getValue(); + String type = (String) DirectiveTable.lookupDirective(block.getType(), key).getFirst(); + action.doUnParameterizedDirective(block, db, key, value, type); + } + + SortedMap paramMapMap = new TreeMap(directiveComparator); + for(Iterator i=db.paramEntryIterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + paramMapMap.put(entry.getKey(),entry.getValue()); + } + for(Iterator i=paramMapMap.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + Pair pair = (Pair) entry.getKey(); + String paramKey = (String) pair.getFirst(); + String paramType = (String) pair.getSecond(); + SortedMap paramMap = new TreeMap(directiveComparator); + paramMap.putAll((Map)entry.getValue()); + String valueType = (String) + (DirectiveTable.lookupParameterizedDirective(block.getType(), paramKey))[0].getSecond(); + action.doParameterizedDirectiveType(block, db, paramKey, paramType, valueType); + for(Iterator j=paramMap.entrySet().iterator(); j.hasNext(); ) { + Map.Entry paramEntry = (Map.Entry) j.next(); + Object param = paramEntry.getKey(); + Map valueMap = db.getValues(paramKey, paramType); + + Object value = valueMap.get(param); + action.doParameterizedDirectiveValue(block, db, paramKey, param, value, paramType, valueType); + } + } + } +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/NetProperty.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/NetProperty.java new file mode 100644 index 0000000000..2d7eda3ba0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/NetProperty.java @@ -0,0 +1,281 @@ +package com.avlsi.cast2.util; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.cast2.directive.impl.DirectiveComparator; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.BinaryFunction; + +/** + * A class to help propagate properties on nets in a hierarchical design. The + * properties on a net can be specified in any point in the hierarchy. + **/ +public class NetProperty { + public static class WireProperty implements Property { + public interface DirectiveGetter { + Object getDirective(CellInterface cell, HierName net, boolean port); + } + + public static class WireDirective implements DirectiveGetter { + private final String dir; + private final Cadencize cad; + private final BinaryFunction update; + public WireDirective(final Cadencize cad, final String dir, + final BinaryFunction update) { + this.cad = cad; + this.dir = dir; + this.update = update; + } + public Object getDirective(final CellInterface cell, + final HierName net, boolean port) { + Object result = null; + + if (port) { + final Map top = DirectiveUtils.getTopLevelDirective(cell, dir, DirectiveConstants.NODE_TYPE); + final Map canon = DirectiveUtils.canonizeKey(cad.convert(cell).getLocalNodes(), top, update); + result = canon.get(net); + } + + if (result == null) { + final Map subcell = DirectiveUtils.getSubcellDirective(cell, dir, DirectiveConstants.NODE_TYPE); + final Map canon = DirectiveUtils.canonizeKey(cad.convert(cell).getLocalNodes(), subcell, update); + result = canon.get(net); + } + + return result; + } + } + + public static class EMDirective implements DirectiveGetter { + private final String dir; + private final Cadencize cad; + private final BinaryFunction update; + public EMDirective(final Cadencize cad, final String dir, + final BinaryFunction update) { + this.cad = cad; + this.dir = dir; + this.update = update; + } + public Object getDirective(final CellInterface cell, + final HierName net, boolean port) { + Object result = null; + + if (result == null) { + final Map prs = DirectiveUtils.getPrsDirective(cell, dir, DirectiveConstants.NODE_TYPE); + final Map canon = DirectiveUtils.canonizeKey(cad.convert(cell).getLocalNodes(), prs, update); + result = canon.get(net); + } + + if (result == null) { + final Map subcell = DirectiveUtils.getSubcellDirective(cell, dir, DirectiveConstants.NODE_TYPE); + final Map canon = DirectiveUtils.canonizeKey(cad.convert(cell).getLocalNodes(), subcell, update); + result = canon.get(net); + } + + return result; + } + } + + Object value; + final boolean fixed; + final BinaryFunction update; + private WireProperty(final Object value, final BinaryFunction update, + final boolean em) { + this.value = value; + this.fixed = value != null && !em; + this.update = update; + } + + public void absorbChildProperty(final Property other) { + if (!fixed) { + final Object oval = ((WireProperty) other).value; + if (value == null) value = oval; + else if (oval != null) { + value = update.execute(oval, value); + } + } + } + + public Object getValue() { + return value; + } + + public String toString() { + return value == null ? "null" : value.toString(); + } + + public static BinaryFunction MAX = new BinaryFunction() { + public Object execute(final Object a, final Object b) { + return ((Number) a).doubleValue() > ((Number) b).doubleValue() ? + a : b; + } + }; + + public static BinaryFunction MIN = new BinaryFunction() { + public Object execute(final Object a, final Object b) { + return ((Number) a).doubleValue() < ((Number) b).doubleValue() ? + a : b; + } + }; + + public static BinaryFunction OR = new BinaryFunction() { + public Object execute(final Object a, final Object b) { + return Boolean.valueOf(((Boolean) a).booleanValue() || + ((Boolean) b).booleanValue()); + } + }; + + public static PropertyFactory getFactory(final DirectiveGetter getter, + final BinaryFunction update) { + return getFactory(getter, update, false); + } + + public static PropertyFactory getFactory(final DirectiveGetter getter, + final BinaryFunction update, + final boolean em) { + return new PropertyFactory() { + public Property makeProperty(final CellInterface cell, + final HierName net, + final boolean port) { + return new WireProperty(getter.getDirective(cell, net, port), update, em); + } + }; + } + } + + public interface Property { + void absorbChildProperty(Property other); + Object getValue(); + } + + public interface PropertyFactory { + /** + * Create a new property for the given cell. + * + * @param cell Cell to create the property for. + * @param net Canonical name of the net + * @param port Whether the property should be in a port context. + **/ + Property makeProperty(CellInterface cell, HierName net, boolean port); + } + + public static class Cache extends HashMap { + } + + private final Cadencize cad; + public NetProperty(final Cadencize cad) { + this.cad = cad; + } + + private static void update(final Map /**/ map, + final CellInterface cell, + final HierName net, + final Property property) { + assert net != null && property != null; + final Property existing = (Property) map.get(net); + if (existing == null) { + map.put(net, property); + } else { + existing.absorbChildProperty(property); + } + } + + public static Map /**/ + getNodeProperties(final Cache cache, final CellInterface cell, + final Cadencize cad, final PropertyFactory propFactory) { + final Map /**/ result = new HashMap(); + final CadenceInfo cinfo = cad.convert(cell); + final AliasedSet locals = cinfo.getLocalNodes(); + + for (Iterator i = locals.getCanonicalKeys(); i.hasNext(); ) { + final HierName local = (HierName) i.next(); + update(result, cell, local, propFactory.makeProperty(cell, local, false)); + } + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + + final CellInterface subcell = (CellInterface) p.getSecond(); + final Map subcellResult = + getPortProperties(cache, subcell, cad, propFactory); + + // Convert subcell names to canonical names in this cell + final HierName inst = (HierName) p.getFirst(); + for (Iterator j = subcellResult.entrySet().iterator(); + j.hasNext(); ) { + final Map.Entry entry = (Map.Entry) j.next(); + final HierName key = + HierName.prefixName(inst, (HierName) entry.getKey()); + final HierName local = + (HierName) locals.getCanonicalKey(key); + + assert local != null : "key = " + key; + final Property prop = (Property) entry.getValue(); + update(result, cell, local, prop); + } + } + + return result; + } + + public static Map /**/ + getPortProperties(final Cache cache, final CellInterface cell, + final Cadencize cad, final PropertyFactory propFactory) { + final Map /**/ cached = (Map) cache.get(cell.getFullyQualifiedType()); + if (cached != null) return cached; + + final Map /**/ result = new HashMap(); + final CadenceInfo cinfo = cad.convert(cell); + final AliasedMap ports = cinfo.getPortNodes(); + final AliasedSet locals = cinfo.getLocalNodes(); + + for (Iterator i = ports.getCanonicalKeys(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + update(result, cell, port, propFactory.makeProperty(cell, port, true)); + } + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + + final CellInterface subcell = (CellInterface) p.getSecond(); + final Map subcellResult = + getPortProperties(cache, subcell, cad, propFactory); + + // Convert subcell names to canonical names in this cell + final HierName inst = (HierName) p.getFirst(); + for (Iterator j = subcellResult.entrySet().iterator(); + j.hasNext(); ) { + final Map.Entry entry = (Map.Entry) j.next(); + final HierName key = + HierName.prefixName(inst, (HierName) entry.getKey()); + final HierName canon = (HierName) locals.getCanonicalKey(key); + + assert canon != null : "key = " + key; + + // If canon is not a port node of this cell, its information + // need not be propagated up any further + if (ports.contains(canon)) { + final Property prop = (Property) entry.getValue(); + update(result, cell, canon, prop); + } + } + } + + cache.put(cell.getFullyQualifiedType(), result); + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/StandardParsingOption.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/StandardParsingOption.java new file mode 100644 index 0000000000..b1b35b4ec7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/StandardParsingOption.java @@ -0,0 +1,194 @@ +package com.avlsi.cast2.util; + +import java.lang.ref.WeakReference; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.impl.CastParsingOption; +import com.avlsi.cast2.impl.CastTwoParser; +import com.avlsi.cast2.impl.CastTwoTreeParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsIterator; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.text.StringUtil; + +/** + * Handle overriding of variables via --define arguments specified on the + * commandline. + **/ +public class StandardParsingOption implements CastParsingOption { + /** + * The regular expression for the right hand-side of a valid --define + * argument. + **/ + private final static Pattern OVERRIDE = + Pattern.compile("(.*)\\.([^\\.]+):(.*)"); + + /** + * Map from fully qualified cell name to a map from variable name to + * value. + **/ + private final Map/*>*/ vars; + + /** + * A stack containing currently active maps from variable name to value. + * The top of the stack contains the map that should be used to look for + * overriden values. + **/ + private final LinkedList/*>*/ mapStack; + + /** + * A tree parser instance used to parse the value. The instance is created + * lazily, when needed. + **/ + private CastTwoTreeParser castTreeParser; + + /** + * Enable hack for compatibility for bug 3771? + **/ + private final boolean hackBug3771; + + /** + * Enable hack for compatibility for bug 7068? + **/ + private final boolean hackBug7068; + + /** + * Enable hack for compatibility for bug 16459? If set, do not require + * strict, linear subtyping. + **/ + private final boolean hackBug16459; + + /** + * Whether to check ports are connected properly between subcells. + **/ + private final boolean checkConnections; + private boolean checkE1ofN = false; + + /** + * Weak reference to a Cadencize object used to check connections between + * subcells. + **/ + private WeakReference cadRef; + + public StandardParsingOption(final CommandLineArgs args) { + vars = new HashMap(); + mapStack = new LinkedList(); + // handle variables not declared inside a cell, e.g., file scope + // variables + mapStack.add(Collections.EMPTY_MAP); + + for (CommandLineArgsIterator i = args.iterator(); i.hasNext(); ) { + final CommandLineArg arg = (CommandLineArg) i.next(); + if (arg.getName().equals("define")) { + final String val = arg.getValue(); + final Matcher m = OVERRIDE.matcher(val); + if (m.matches()) { + final String cell = m.group(1); + Map cellMap = (Map) vars.get(cell); + if (cellMap == null) { + cellMap = new HashMap(); + vars.put(cell, cellMap); + } + cellMap.put(m.group(2), m.group(3)); + } else { + System.err.println("WARNING: invalid --define argument: " + + val); + } + } + } + + hackBug3771 = args.argExists("enable-bug3771-compatibility"); + hackBug7068 = args.argExists("enable-bug7068-compatibility"); + hackBug16459 = args.argExists("enable-bug16459-compatibility"); + checkConnections = args.argExists("check-connections"); + if (checkConnections) { + final String s = args.getArgValue("check-connections", ""); + final Set types = + new HashSet(Arrays.asList(StringUtil.split(s, ','))); + checkE1ofN = types.contains("e1ofN"); + } + } + + public boolean processInline(final CellInterface cell) { + return true; + } + + public void beginCellConstruction(final CellInterface cell) { + final Map currentMap = (Map) vars.get(cell.getFullyQualifiedType()); + mapStack.addFirst(currentMap == null ? Collections.EMPTY_MAP + : currentMap); + } + + public Value getOverrideValue(final CellInterface cell, final Symbol var, + final Value init, final Environment env) { + final Map currentMap = (Map) mapStack.getFirst(); + final String val = (String) currentMap.remove(var.getString()); + if (val == null) return null; + try { + final CastTwoParser castParser = + CastTwoParser.getParser(val, 0, 0, ""); + castParser.startExpression(); + + if (castTreeParser == null) { + castTreeParser = new CastTwoTreeParser(); + } + final Value v = castTreeParser.expression(castParser.getAST(), env, + false); + + return v; + } catch (Exception e) { + System.err.println("WARNING: Cannot parse overriden value " + + cell.getFullyQualifiedType() + "." + + var.getString() + ":" + val); + return null; + } + } + + public void endCellConstruction(final CellInterface cell) { + final Map currentMap = (Map) mapStack.removeFirst(); + if (!currentMap.isEmpty()) { + System.err.print("WARNING: " + cell.getFullyQualifiedType() + + " does not define the following variables to be" + + " overridden:"); + for (Iterator i = currentMap.keySet().iterator(); i.hasNext(); ) { + System.err.print(" " + i.next()); + } + System.err.println(); + } + if (checkConnections) { + Cadencize cad = cadRef == null ? null : cadRef.get(); + if (cad == null) { + cad = new Cadencize(false); + cadRef = new WeakReference(cad); + } + CellUtils.verifySubcells(cell, cad, checkE1ofN); + } + } + + public boolean bug3771HackEnabled() { + return hackBug3771; + } + + public boolean bug7068HackEnabled() { + return hackBug7068; + } + + public boolean bug16459HackEnabled() { + return hackBug16459; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/custom.mk new file mode 100644 index 0000000000..72c034e49e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/custom.mk @@ -0,0 +1,5 @@ +CURR_RESULT_FILES := $(CURR_TARGET_DIR)/cast_file_server.sh $(CURR_RESULT_FILES) + +$(CURR_TARGET_DIR)/cast_file_server.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.cast2.util.CastFileServer/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/fileserver.package.inc b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/fileserver.package.inc new file mode 100644 index 0000000000..209922feea --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cast2/util/fileserver.package.inc @@ -0,0 +1,3 @@ +1 0 +java com.avlsi.cast2.util.CastFileServer +$arch/bin/cast_file_server.sh cast_file_server.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/AttributeInheritanceException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/AttributeInheritanceException.java new file mode 100644 index 0000000000..1c432c3b1e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/AttributeInheritanceException.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +public class AttributeInheritanceException extends Exception { + public AttributeInheritanceException + (String msg, String childType, String parentType) { + super("Error trying to <+ attribute inherit " + childType + + " from " + parentType + ": " + msg); + } + + public AttributeInheritanceException + (String msg, String childType, String parentType, + Throwable cause) { + super("Error trying to <+ attribute inherit " + childType + + " from " + parentType + ": " + msg, cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/BadCSPPortException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/BadCSPPortException.java new file mode 100644 index 0000000000..ccb14712f7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/BadCSPPortException.java @@ -0,0 +1,15 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id: //depot/sw/cad/java/main/src/com/avlsi/cell/RefinementException.java#2 $ + * $DateTime: 2002/02/23 11:33:05 $ + * $Author: chrisb $ + */ + +package com.avlsi.cell; + +public class BadCSPPortException extends Exception { + public BadCSPPortException(String cellName, String portName) { + super("Couldn't make port " + portName + + " accessible to the csp block in cell " + cellName); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellDelay.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellDelay.java new file mode 100644 index 0000000000..98e03aa54e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellDelay.java @@ -0,0 +1,227 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cell; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.util.container.AliasedSet; + +/** + * Calculate the delay associated with a half-operator. + * + * @author Harry Liu + * @version $DateTime$ $Revision$ + **/ +public final class CellDelay { + private final CellInterface cell; + private final AliasedSet localNodes; + private final float nativeUpDelay, nativeDnDelay; + private final Map upAfterDelays; + private final Map dnAfterDelays; + private final Map upDelayBias; + private final Map dnDelayBias; + private final Map upExtraDelay; + private final Map dnExtraDelay; + private final Map upAstaExtraDelay; + private final Map dnAstaExtraDelay; + private final float cellDelayBias; + + public CellDelay(final CellInterface cell, final Cadencize cadencizer) { + this(cell, cadencizer, Float.NaN); + } + + public CellDelay(final CellInterface cell, final Cadencize cadencizer, + final float cellDelayBias) { + this(cell, cadencizer.convert(cell).getLocalNodes(), + cell.getProductionRuleSet().getProductionRules(), cellDelayBias, + false); + } + + public CellDelay(final CellInterface cell, final AliasedSet localNodes, + final Iterator prsIterator) { + this(cell, localNodes, prsIterator, Float.NaN, false); + } + + public CellDelay(final CellInterface cell, final AliasedSet localNodes, + final Iterator prsIterator, final float cellDelayBias, + final boolean useAstaExtraDelay) { + this.cell = cell; + this.localNodes = localNodes; + this.cellDelayBias = cellDelayBias; + + this.nativeUpDelay = ((Float) DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.DEFAULT_UP_DELAY)).floatValue(); + this.nativeDnDelay = ((Float) DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.DEFAULT_DN_DELAY)).floatValue(); + + this.upAfterDelays = new HashMap(); + this.dnAfterDelays = new HashMap(); + + final Set badUpSet = new HashSet(); + final Set badDnSet = new HashSet(); + + while (prsIterator.hasNext()) { + final ProductionRule pr = (ProductionRule) prsIterator.next(); + final HierName target = canon(pr.getTarget()); + final int direction = pr.getDirection(); + assert direction == ProductionRule.UP || + direction == ProductionRule.DOWN; + final Map delayMap = + direction == ProductionRule.UP ? upAfterDelays : dnAfterDelays; + + final int after = pr.getAfter(); + assert after >= 0 || after == -1 : "Invalid after delay: " + pr; + + final Integer oldAfter = (Integer) delayMap.get(target); + final Set badSet = + direction == ProductionRule.UP ? badUpSet : badDnSet; + + Integer newAfter = new Integer(after); + if (oldAfter != null && oldAfter.intValue() != after) { + badSet.add(target); + if (after == -1) newAfter = null; + else if (oldAfter.intValue() != -1 && + after >= oldAfter.intValue()) newAfter = null; + } + + if (newAfter != null) delayMap.put(target, newAfter); + } + + for (Iterator i = badUpSet.iterator(); i.hasNext(); ) { + final HierName target = (HierName) i.next(); + System.err.println("Warning: half operator " + target + "+ in cell " + cell.getFullyQualifiedType() + " has inconsistent after delay, using a delay of " + upAfterDelays.get(target)); + } + + for (Iterator i = badDnSet.iterator(); i.hasNext(); ) { + final HierName target = (HierName) i.next(); + System.err.println("Warning: half operator " + target + "- in cell " + cell.getFullyQualifiedType() + " has inconsistent after delay, using a delay of " + dnAfterDelays.get(target)); + } + + final Map delayBias = DirectiveUtils.getPrsDirective(cell, DirectiveConstants.DELAYBIAS, DirectiveConstants.HALFOP_TYPE); + this.upDelayBias = DirectiveUtils.canonizeKey(localNodes, DirectiveUtils.getUps(delayBias)); + this.dnDelayBias = DirectiveUtils.canonizeKey(localNodes, DirectiveUtils.getDowns(delayBias)); + + final Map extraDelay = DirectiveUtils.getPrsDirective(cell, DirectiveConstants.EXTRA_DELAY, DirectiveConstants.HALFOP_TYPE); + this.upExtraDelay = DirectiveUtils.canonizeKey(localNodes, DirectiveUtils.getUps(extraDelay)); + this.dnExtraDelay = DirectiveUtils.canonizeKey(localNodes, DirectiveUtils.getDowns(extraDelay)); + + if (useAstaExtraDelay) { + final Map astaExtraDelay = DirectiveUtils.getPrsDirective(cell, DirectiveConstants.ASTA_EXTRA_DELAY, DirectiveConstants.HALFOP_TYPE); + this.upAstaExtraDelay = DirectiveUtils.canonizeKey(localNodes, DirectiveUtils.getUps(astaExtraDelay)); + this.dnAstaExtraDelay = DirectiveUtils.canonizeKey(localNodes, DirectiveUtils.getDowns(astaExtraDelay)); + } else { + this.upAstaExtraDelay = Collections.EMPTY_MAP; + this.dnAstaExtraDelay = Collections.EMPTY_MAP; + } + } + + private final HierName canon(final HierName name) { + return (HierName) localNodes.getCanonicalKey(name); + } + + /** + * Return the native delay associated with N or P transistors. + **/ + public float getNativeDelay(final boolean up) { + return up ? nativeUpDelay : nativeDnDelay; + } + + private final float getDelay(final HierName node, final boolean up, + final Map upMap, final Map dnMap, + final float defaultDelay) { + final Map delayMap = up ? upMap : dnMap; + final Number delay = (Number) delayMap.get(canon(node)); + return delay == null ? defaultDelay : delay.floatValue(); + } + + /** + * Return the delay specified by the after keyword in the PRS + * block. + **/ + public float getAfterDelay(final HierName node, final boolean up) { + float delay = getDelay(node, up, upAfterDelays, dnAfterDelays, 100); + if (delay<0) delay = getNativeDelay(up); // use native delay instead + return delay; + } + + /** + * Return the delay specified by the delaybias directive in + * the PRS block. + **/ + public float getDelayBias(final HierName node, final boolean up) { + return getDelay(node, up, upDelayBias, dnDelayBias, 1); + } + + /** + * Return the delay specified by the extra_delay directive + * (including the asta_extra_delay directive, if requested). + **/ + public float getExtraDelay(final HierName node, final boolean up) { + return getDelay(node, up, upExtraDelay, dnExtraDelay, 0) + + getDelay(node, up, upAstaExtraDelay, dnAstaExtraDelay, 0); + } + + /** + * Return the delay specified by the delaybias directive in + * the top level block, or the instance hierarchy propagated + * delaybias directive, if that is available. + **/ + public float getCellDelayBias() { + if (Float.isNaN(cellDelayBias)) { + return ((Float) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.DELAYBIAS)).floatValue(); + } else { + return cellDelayBias; + } + } + + /** + * Return the delay associated with a node. This is computed as: + *
    delay = [ [afterDelay or nativeDelay] + extraDelay ] * delayBias * cellDelayBias / 100.
    + **/ + public float getDelay(final HierName node, final boolean up) { + return (getAfterDelay(node, up) + getExtraDelay(node, up)) + * getDelayBias(node, up) * getCellDelayBias() / 100; + } + + /** + * Return the delay associated with a node given the unit delay. This is + * computed as multiplying the result of + * {@link getDelay(HierName, boolean) getDelay} + * by tau. + **/ + public float getDelay(final HierName node, final boolean up, + final float tau) { + return getDelay(node, up) * tau; + } + + public String toString() { + final StringBuffer buf = new StringBuffer(); + buf.append("CellDelay for " + cell.getFullyQualifiedType() + "\n"); + buf.append("nativeUpDelay: " + nativeUpDelay); + buf.append(" nativeDnDelay: " + nativeDnDelay + "\n"); + buf.append("upAfterDelays: " + upAfterDelays + "\n"); + buf.append("dnAfterDelays: " + dnAfterDelays + "\n"); + buf.append("upDelayBias: " + upDelayBias + "\n"); + buf.append("dnDelayBias: " + dnDelayBias + "\n"); + buf.append("upExtraDelay: " + upExtraDelay + "\n"); + buf.append("dnExtraDelay: " + dnExtraDelay + "\n"); + return buf.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellImpl.java new file mode 100644 index 0000000000..fd2e3a7621 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellImpl.java @@ -0,0 +1,2932 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +import java.lang.reflect.Constructor; + +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StringWriter; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.StringTokenizer; + +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.impl.CastParsingOption; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.csp.ast.CSPProgram; +import com.avlsi.csp.csp2java.CSP2Class; +import com.avlsi.csp.csp2java.runtime.CspSnoopingInterface; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.fast.AssertBlock; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.CellBlock; +import com.avlsi.fast.CspBlock; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.EnvBlock; +import com.avlsi.fast.JavaBlock; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.PrsBlock; +import com.avlsi.fast.PrsDirective; +import com.avlsi.fast.SubcellBlock; +import com.avlsi.fast.metaparameters.MetaParamDefinition; +import com.avlsi.fast.ports.ArrayType; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.fast.ports.StructureType; +import com.avlsi.file.common.HierName; +import com.avlsi.file.cdl.parser.CDLDeviceNameFilter; +import com.avlsi.file.cdl.parser.CDLNodeNameFilter; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.io.NullWriter; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.cosim.ChannelDictionary; +import com.avlsi.tools.cosim.CoSimInfo; +import com.avlsi.tools.cosim.CoSimParameters; +import com.avlsi.tools.cosim.CSPCoSimInfo; +import com.avlsi.tools.cosim.DeviceConstructionException; +import com.avlsi.tools.cosim.DeviceParameters; +import com.avlsi.tools.cosim.JavaCoSimInfo; +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.Startable; +import com.avlsi.tools.tsim.WideNode; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.BooleanUtils; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Namespace; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.StringUtil; + + +/** + * Implementation of {@link CellInterface}, implements the + * interface, as well as adding modification functionality. + **/ +public class CellImpl implements CellInterface { + + /** + * The type of node cells. + **/ + public static final String NODE_TYPE = "$NODE"; + + /** + * Constant for definitionKind, indicating a cell + * defined with define. + **/ + public static final int CELL = 0; + + /** + * Constant for definitionKind, indicating a cell + * defined not in cast, but on the fly be java code. + * Indicates a synthetic cell which isn't part of the + * whole implied-port-refinement scheme but which might have + * subcells which aren't synthetic. InstanceValue will use this + * when it assigns defaults to implied ports: if this is true, the + * InstanceValue will create nodes for any implied ports which + * aren't there. + **/ + public static final int SYNTHETIC_CELL = 1; + + /** + * Constant for definitionKind, indicating a cell + * defined with define ... attributes. + * Attributes cells cannot refine other cells, and are + * the only cells that can be used in <+ inheritance. + **/ + public static final int ATTRIBUTES_CELL = 2; + + /** + * Constant for definitionKind, indicating a cell + * defined with defchan. + **/ + public static final int CHANNEL = 3; + + /** + * Constant for definitionKind, indicating a cell + * defined with defalias. + **/ + public static final int ALIAS_CELL = 4; + + /** + * The type of the cell. + **/ + private final String type; + + /** + * The filename of the file. + **/ + private final String filename; + + /** + * One of {@link CELL}, {@link SYNTHETIC_CELL}, {@link ATTRIBUTES_CELL}, + * or {@link CHANNEL}, indicating how the cell was declared. + **/ + private final int definitionKind; + + /** + * The type of the cell furthest up the refinement hierarchy which + * is a direct ancestor of this cell and has the same port list. + * This may refer to this cell. + **/ + private String refinementAncestor; + + /** + * The CellImpl this cell was refined from, if any. This makes it + * possible to tell if one cell specializes another one (see + * eventuallyRefinesFrom()) + **/ + private CellImpl directRefinementParent; + + /** + * The module the cell was defined in. This also uniquely + * specifies the file the cell definition can be found in. + **/ + private final String moduleName; + + /** + * Map from HierName (subcell usage name) to CellInterface + * (the cell instance). + **/ + private final Map/**/ subcellMap; + + /** + * Map from HierName (subcell usage name) to a Triplet + * (CellInterface, CellInterface, boolean). The first + * CellInterface is the cell instance of the refinement parent. + * The second is the cell instance of the refinement child and + * will be moved with the name into subcellMap when the refinement + * parent is set. The third is whether the subcell should be + * inlined after being refined. + * + *

    The movement into subcellMap and the accompanying + * typechecks are "validation" of the subtype. As subtypes are + * validated by the refinement process, they are removed from this + * Map, which should be empty at the end of refinement. + * + *

    Elements in an array of subcells may be subtyped as a unit, or + * subtyped individually. + **/ + private final Map/*>*/ subtypeMap; + private final Set/**/ subtypeArray; + + /** + * Set of HierNames of cells that are port cells. + **/ + private final Set/**/ portSubcellSet; + + /** + * Set of HierNames of cells that have been inlined or flattened. + **/ + private final Set/**/ inlinedSubcellSet; + + private final Set/**/ adoptedSet; + + /** List of {@link com.avlsi.fast.metaparameters.MetaParamDefinition}s. **/ + private final List/**/ metaParamDefinitions; + + /** + * Map from names of ports (Strings) to their {@link + * com.avlsi.fast.ports.PortDefinition}s. + **/ + private final Map portDefinitions; + + /** + * A mapping from the names of implied ports in this cell to the names to + * be connected to in the parent cell. + **/ + private final Map impliedPortMapping; + + /** + * A mapping from the names of environment extra ports in this cell to the + * names to be connected to in the parent cell. + **/ + private final Map envExtraPortMapping; + + /** + * Node aliases. + * Possibly includes channel aliases. + **/ + // Made non-final for cell-refinement + private AliasedSet/**/ aliases; + + /** + * Whether the cast cell contained a prs{...} construct, even an + * empty one. This is also set true as part of refinement if a + * refinement ancestor had a prs block. + **/ + private boolean hasPrsBlock = false; + + /** + * True if the prs block is complete. Undefined if + * !hasPrsBlock. + **/ + private boolean prsBlockIsComplete = false; + + /** + * Whether the cast cell contained a subcells{...} construct, even + * an empty one. This is also set true as part of refinement if a + * refinement ancestor had a subcells block. + **/ + private boolean hasSubcellsBlock = false; + + /** + * True if the subcells block is complete. Undefined if + * !hasSubcellsBlock. + **/ + private Boolean subcellsBlockIsComplete = null; + + /** + * Whether the cast cell contained a subtypes{...} construct, even + * an empty one. Is meaningless after completing the process of + * refinement. + **/ + private boolean hasSubtypesBlock = false; + + /** + * The cosimulation info from the Java block + **/ + private final JavaCoSimInfo javaCosimInfo; + + /** + * A structure aggregating all blocks in a cell + **/ + private final CellBlock blocks; + + /** + * Whether this cell should be inlined wherever it is instantiated + **/ + public boolean autoInline = false; + + /** + * A list of cells that this cell inherited from via <+. + **/ + private final List/**/ inheritedCells; + + private final Map/**/ instancePositions; + + /** + * Whether a warning about refinement has already been emitted for this + * type. This is only used when we turned off inline processing. + **/ + private boolean refinementWarned = false; + + /** Constructor used by old cast parser **/ + public CellImpl(final String type) { + this(type, null, CELL); + } + + /** + * Constructor used by new cast parser to generate all "real" + * (read from cast) cells + **/ + private CellImpl(final String type, final String moduleName) { + this(type, moduleName, CELL); + } + + public CellImpl(final String type, + final String moduleName, + final int definitionKind) { + this(type, moduleName, definitionKind, null); + } + + public CellImpl(final String type, + final String moduleName, + final int definitionKind, + final String filename) { + this.type = type; + this.filename = filename; + // To start out with; modified if this cell is refined + this.refinementAncestor = + moduleName == null ? type : moduleName + '.' + type; + this.directRefinementParent = null; // To start out with; modified if this cell is refined + this.moduleName = moduleName; + Debug.assertTrue(definitionKind == CELL || + definitionKind == SYNTHETIC_CELL || + definitionKind == ATTRIBUTES_CELL || + definitionKind == CHANNEL || + definitionKind == ALIAS_CELL); + this.definitionKind = definitionKind; + this.subcellMap = new LinkedHashMap/**/(); + this.subtypeMap = + new HashMap/*>*/(); + this.subtypeArray = new HashSet/**/(); + this.portSubcellSet = new HashSet/**/(); + this.inlinedSubcellSet = new HashSet/**/(); + this.adoptedSet = new HashSet/**/(); + this.metaParamDefinitions = new ArrayList/**/(); + this.portDefinitions = new LinkedHashMap(); + this.impliedPortMapping = new LinkedHashMap(); + this.envExtraPortMapping = new LinkedHashMap(); + this.aliases = + new AliasedSet/**/(HierName.getComparator()); + this.javaCosimInfo = new JavaCoSimInfo(); + blocks = new CellBlock(); + blocks.iterator(BlockInterface.ASSERT).add(new AssertBlock()); + blocks.iterator(BlockInterface.ENV).add(new EnvBlock(this)); + blocks.iterator(BlockInterface.PRS).add(new PrsBlock()); + blocks.iterator(BlockInterface.NETLIST).add(new NetlistBlock(this)); + blocks.iterator(BlockInterface.SUBCELL).add(new SubcellBlock()); + blocks.iterator(BlockInterface.CSP).add(new CspBlock()); + blocks.iterator(BlockInterface.JAVA).add(new JavaBlock()); + this.inheritedCells = new ArrayList/**/(); + this.instancePositions = new LinkedHashMap/**/(); + } + + public String getType() { + return type; + } + + public String getFilename() { + return filename; + } + + public String getModuleName() { + return moduleName; + } + + public String getFullyQualifiedType() { + if (moduleName == null) + return type; + else + return moduleName + '.' + type; + } + + public boolean isSyntheticP() { + return definitionKind == SYNTHETIC_CELL; + } + + public boolean isChannel() { + return definitionKind == CHANNEL; + } + + public boolean isAttributesCell() { + return definitionKind == ATTRIBUTES_CELL; + } + + public boolean isAlias() { + return definitionKind == ALIAS_CELL; + } + + public boolean isNode() { + return type.equals(NODE_TYPE); + } + + // + // + // Subtypes (refining subcells) + // + // + + /** + * Note that the cast cell contained a subtypes{...} construct. + **/ + public void setHasSubtypesBlock() { hasSubtypesBlock = true; } + + /** + * Add information on how cellName is refined to the internal + * table. Should not be called after setRefinementParent(). + * @param inlineP Whether the subcell should be inlined after it's + * refined. Subcells can't be inlined before refinement. + * @param looseCheck Whether to strictly require that the refinement child + * descend linearly from the refinement parent. + **/ + public void addSubtype(final HierName cellName, + final CellInterface refinementParent, + final CellInterface refinementChild, + final boolean inlineP, + final boolean looseCheck) + throws RefinementException { + + if (looseCheck) { + if (!((CellImpl) refinementParent).oldSameRefinementAncestor( + refinementChild)) { + throw new RefinementException + ("subtype for " + cellName + + " has to have the same refinement ancestor and "+ + "port list as the cells they're subtyping", + refinementParent.getFullyQualifiedType(), + refinementChild.getFullyQualifiedType()); + } + } else { + if (!refinementParent.sameRefinementAncestor(refinementChild)) { + throw new RefinementException + ("subtype for " + cellName + + " must be a direct descendent of the refinement ancestor" + + " (see bug 16459)", + refinementParent.getFullyQualifiedType(), + refinementChild.getFullyQualifiedType()); + } + } + + final HierName baseName = cellName.getArrayBase(); + + if (subtypeMap.containsKey(cellName)) { + // { TYPE1 :> TYPE2 inst; TYPE1 :> TYPE2 inst; } + throw new RefinementException("subtyped " + cellName + " twice", + refinementParent.getFullyQualifiedType(), + refinementChild.getFullyQualifiedType()); + } else if (subtypeMap.containsKey(baseName)) { + // { TYPE1 :> TYPE2 inst; TYPE1 :> TYPE2 inst[0]; } + throw new RefinementException("whole array " + + cellName.getArrayBase() + + " already subtyped", + refinementParent.getFullyQualifiedType(), + refinementChild.getFullyQualifiedType()); + } else if (subtypeArray.contains(cellName)) { + // { TYPE1 :> TYPE2 inst[0]; TYPE1 :> TYPE2 inst; } + throw new RefinementException("an element of the array " + + cellName + " already subtyped", + refinementParent.getFullyQualifiedType(), + refinementChild.getFullyQualifiedType()); + } else { + if (!baseName.equals(cellName)) subtypeArray.add(baseName); + subtypeMap.put(cellName, + new Triplet(refinementParent, + refinementChild, + new Boolean(inlineP))); + } + } + + // + // + // Subcells + // + // + + /** + * Note that the cast cell contained a fragment subcells{...} construct. + **/ + public void setHasFragmentSubcellsBlock() { + hasSubcellsBlock = true; + subcellsBlockIsComplete = Boolean.FALSE; + } + + /** + * Note that the cast cell contained a non-fragment subcells{...} + * construct. + **/ + public void setHasCompleteSubcellsBlock() { + hasSubcellsBlock = true; + subcellsBlockIsComplete = Boolean.TRUE; + } + + /** + * Does the cell contain a subcells block, either explicitly or + * through refinement? + **/ + public boolean containsSubcells() { + return hasSubcellsBlock || hasSubtypesBlock; + } + + public boolean containsCompleteSubcells() { + return hasSubcellsBlock && subcellsBlockIsComplete.booleanValue(); + } + + public boolean containsFragmentSubcells() { + return hasSubcellsBlock && !subcellsBlockIsComplete.booleanValue(); + } + + /** + * Returns an unmodifiable Iterator of HierNames of the subcell names. + **/ + public Iterator getSubcellNames() { + return Collections.unmodifiableMap(subcellMap).keySet().iterator(); + } + + /** + * Get the CellInterface for a given subcell name, or null if there is + * no subcell by that name. + **/ + public CellInterface getSubcell(HierName name) { + final CellInterface cell = (CellInterface) subcellMap.get(name); + + /* + boolean found = false; + for (final Iterator i = getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName n = (HierName) p.getFirst(); + final CellInterface c = (CellInterface) p.getSecond(); + + if (n.equals(name)) { + found = true; + break; + } + } + + Debug.assertTrue(found == (cell != null)); + */ + + return cell; + } + + /** + * Returns an Iterator of Pairs of HierName and CellInterface for + * non-inlined subcells. + **/ + public Iterator getSubcellPairs() { + return new FilteringIterator(getAllSubcellPairs(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return !isInlinedSubcell((HierName) ((Pair) o).getFirst()); + }}); + } + + /** + * Returns an Iterator of Pairs of HierName and CellInterface for + * all subcells, even inlined ones. + **/ + public Iterator getAllSubcellPairs() { + return new MappingIterator( + Collections.unmodifiableMap(subcellMap).entrySet().iterator(), + new UnaryFunction() { + public Object execute(final Object o) { + final Entry entry = (Entry) o; + return new Pair(entry.getKey(), entry.getValue()); + } + }); + } + + /** + * Adds the given cell as a subcell with the specified usage name. + **/ + public void addSubcellPair(final HierName use, + final CellInterface subcell, + final boolean portP) { + addSubcellPair(use, subcell, portP, -1, -1); + } + + /** + * Adds the given cell as a subcell with the specified usage name, and + * parse location. + **/ + public void addSubcellPair(final HierName use, + final CellInterface subcell, + final boolean portP, + final int line, final int column) { + subcellMap.put(use, subcell); + + if (portP) + portSubcellSet.add(use); + + if (line >= 0 && column >= 0 && + !subcell.isNode() && !subcell.isChannel()) + instancePositions.put(use, new Position(line, column)); + } + + private static class Position implements Comparable { + private static class Point implements Comparable { + public int line, column; + public Point(int line, int column) { + this.line = line; + this.column = column; + } + public int compareTo(final Object o) { + final Point p = (Point) o; + return line == p.line ? column - p.column : line - p.line; + } + public String toString() { + return line + ":" + column; + } + } + + public List location; + + public Position(int line, int column) { + this.location = new ArrayList(1); + location.add(new Point(line, column)); + } + + public Position(Position prefix, Position suffix) { + this.location = new ArrayList(prefix.location.size() + + suffix.location.size()); + location.addAll(prefix.location); + location.addAll(suffix.location); + } + + public int compareTo(final Object o) { + final Position p = (Position) o; + int i, j; + for (i = 0, j = 0; i < location.size() && j < p.location.size(); + ++i, ++j) { + final Point pi = (Point) location.get(i); + final Point pj = (Point) p.location.get(j); + int x = pi.compareTo(pj); + if (x != 0) return x; + } + return location.size() - p.location.size(); + } + + public String toString() { + return location.toString(); + } + } + + /** + * Get an iterator over columns of instances that is an initial guess for + * floorplanning. + **/ + public Iterator getFloorplanInstances() { + final MultiMap mm = + new MultiMap(new TreeMap(), MultiMap.ARRAY_LIST_FACTORY); + for (Iterator i = instancePositions.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName instance = (HierName) entry.getKey(); + if (!isInlinedSubcell(instance)) mm.put(entry.getValue(), instance); + } + final Iterator it = mm.keySet().iterator(); + return new Iterator() { + public boolean hasNext() { + return it.hasNext(); + } + public Object next() { + return mm.get(it.next()); + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + private void addPosition(final HierName newName, + final HierName instName, + final CellInterface cell, + final HierName subName) { + if (cell instanceof CellImpl) { + final Position prefix = (Position) instancePositions.get(instName); + final Position suffix = + (Position) ((CellImpl) cell).instancePositions.get(subName); + if (suffix != null && prefix != null) + instancePositions.put(newName, new Position(prefix, suffix)); + } + } + + /** + * Returns the non-inlined port subcell pairs. + **/ + public Iterator getPortSubcellPairs() { + return new FilteringIterator(getSubcellPairs(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return isPortSubcell((HierName) ((Pair) o).getFirst()); + }}); + } + + /** + * Returns the non-inlined local subcell pairs. + **/ + public Iterator getLocalSubcellPairs() { + return new FilteringIterator(getSubcellPairs(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return !isPortSubcell((HierName) ((Pair) o).getFirst()); + }}); + } + + public Iterator getMetaParamDefinitions() { + return Collections.unmodifiableList(metaParamDefinitions).iterator(); + } + + public Iterator getPortDefinitions() { + return Collections.unmodifiableCollection(portDefinitions.values()).iterator(); + } + + public PortDefinition getPortDefinition(final String name) { + return portDefinitions.get(name); + } + + /** + * Appends a port definition to the list. + * + * @param portDefinition port definition + **/ + public void addPortDefinition(final PortDefinition portDefinition) { + portDefinitions.put(portDefinition.getName(), portDefinition); + } + + public boolean isImpliedPort(final String name) { + return impliedPortMapping.containsKey(name); + } + + /** + * Appends a metaparameter definition to the list. + * + * @param metaParamDefinition metaparameter definition + **/ + public void addMetaParamDefinition( + final MetaParamDefinition metaParamDefinition) { + metaParamDefinitions.add(metaParamDefinition); + } + + public boolean isPortSubcell(final HierName n) { + return portSubcellSet.contains(n); + } + + public boolean isInlinedSubcell(final HierName n) { + return inlinedSubcellSet.contains(n); + } + + public boolean parentIsInlinedSubcell(final HierName n) { + if (n.getNumComponents()<2) return false; + for (Iterator scit=inlinedSubcellSet.iterator(); scit.hasNext();) + if (n.isChildOf((HierName)scit.next())) return true; + return false; + } + + /** + * Imports all production rules and connections from the + * specified subcell into this cell. + * + * @throws NoSuchSubcellException if there is no subcell with the + * specified name + * @throws SubcellCreationException if the subcell contains prs so + * can't be inlined. + **/ + public void inlineSubcell(final HierName use) + throws NoSuchSubcellException, SubcellCreationException { + /* this actually doesn't work correctly. + * prs can refer to both foo.0 and foo.d[0] */ + inlineSubcell(use, false, true); + } + + /** + * Imports all production rules and connections from the + * flattened version of the specified subcell into this cell. + * + * @throws NoSuchSubcellException if there is no subcell with the + * specified name + * @throws SubcellCreationException if subcell contains netlist body so + * can't be flattened + **/ + public void flattenSubcell(final HierName use) + throws NoSuchSubcellException, SubcellCreationException { + inlineSubcell(use, true, true); + } + + /** + * Imports all production rules and connections from + * the specified subcell into this cell. + * Subcell will be flattened first if flattenP + * is true. + * + * @throws NoSuchSubcellException if there is no subcell with the + * specified name + * @throws SubcellCreationException if the subcell contains prs so + * can't be inlined. + **/ + private void inlineSubcell(final HierName use, + final boolean flattenP, + final boolean checkPrs) + throws NoSuchSubcellException, SubcellCreationException { + + final CellInterface subcell = (CellInterface) subcellMap.get(use); + + if (subcell == null) + throw new NoSuchSubcellException(use); + + if (flattenP) { + if (subcell.hasNetlistBody()) { + throw new SubcellCreationException("Subcell has netlist body, so cannot be flattened", use, getFullyQualifiedType()); + } else { + adoptCell(use, subcell.flatten()); + } + } else { + // Check to see if production rules are being inlined. + // This won't interfere with parsing of old cast, because + // the old cast parser never sets hasPrsBlock to true. + if (checkPrs && ((CellImpl) subcell).hasPrsBlock) + throw new SubcellCreationException("Subcell has production rules, so can only be flattened, not inlined", use, getFullyQualifiedType()); + + adoptCell(use, subcell); + } + } + + + public void setAutoInline(boolean autoInline) { + this.autoInline=autoInline; + } + + public boolean isAutoInline() { + return autoInline; + } + + /** + * Helper function for adoptCell(); returns a new ProductionRule + * with nodes canonicalized as specified. + **/ + private ProductionRule canonicalizeProductionRuleForAdoptCell( + final HierName subcellName, + final ProductionRule pr) { + return new ProductionRule( + prefixAndCanonicalizeBooleanExpressionHierNames( + pr.getGuard(), subcellName, this), + canonicalizeName( + HierName.prefixName(subcellName, + pr.getTarget()), + this), + canonicalizeName( + HierName.prefixName(subcellName, + pr.getPowerSupply()), + this), + pr.getDirection(), + pr.isIsochronic(), pr.isUnstable(), pr.isMetastable(), + pr.isTimed(), pr.getAfter(), pr.isAbsolute()); + } + + /** + * Import directives from a CellInterface for a specified block. + **/ + private void adoptDirective(final CellInterface model, final String block) { + final BlockIterator modelPrs = getDirectiveIterator(model, block); + + if (modelPrs.hasNext()) { + final BlockIterator prsBlock = getDirectiveIterator(this, block); + final PrsDirective newDir = + new PrsDirective(block, (DirectiveBlock) modelPrs.next()); + if (prsBlock.hasNext()) { + prsBlock.next(); + prsBlock.set(newDir); + } else { + prsBlock.add(newDir); + } + } + } + + /** + * Import directives from a CellInterface. Currently, only PRS and subcell + * directives. + **/ + private void adoptDirective(final CellInterface model) { + adoptDirective(model, BlockInterface.CELL); + adoptDirective(model, BlockInterface.PRS); + adoptDirective(model, BlockInterface.SUBCELL); + } + + /** + * Imports all production rules, connections, exclusion properties, + * and subcells from the specified cell into this cell. + **/ + private void adoptCell(final HierName subcellName, + final CellInterface cell) { + // b. for each canonical node: + // i. add node and all connected nodes with + // usage name prefixed to name + // c. (1) add that cell's production rules to this cell, + // (2) add that cell's netlist block to this cell, + // with the usage name prefixed to each node, + // *taking care to use the new canonical node name + // d. add that cell's exclhi / excllo to the this cell + // *taking care to use the new canonical node name + // e. add that cell's subcells, and update the inlined set as + // necessary. + // f. inline directives from cell + + // b. + for (final Iterator iCanonicalNode = cell.getCanonicalNodes(); + iCanonicalNode.hasNext(); ) { + final HierName canonicalNode + = (HierName) iCanonicalNode.next(); + final HierName subcellCanonicalNode + = HierName.prefixName(subcellName, canonicalNode); + + // i. + for (final Iterator iConnectedNode + = cell.getConnectedNodes(canonicalNode); + iConnectedNode.hasNext(); ) { + + final HierName connectedNode + = (HierName) iConnectedNode.next(); + final HierName subcellConnectedNode + = HierName.prefixName(subcellName, connectedNode); + + addConnection(subcellCanonicalNode, subcellConnectedNode); + } + } + + /**/ + // c. + // (1) add production rules + for (final Iterator generalPRS + = cell.getProductionRuleSet().getProductionRules(); + generalPRS.hasNext(); ) { + final ProductionRule pr = (ProductionRule) generalPRS.next(); + + // * be sure to use canonical name + + getProductionRuleSet().addProductionRule( + canonicalizeProductionRuleForAdoptCell(subcellName, pr)); + } + + for (final Iterator assertedPRS + = cell.getAssertedProductionRuleSet().getProductionRules(); + assertedPRS.hasNext(); ) { + final ProductionRule pr = (ProductionRule) assertedPRS.next(); + + // * be sure to use canonical name + + getAssertedProductionRuleSet().addProductionRule( + canonicalizeProductionRuleForAdoptCell(subcellName, pr)); + } + // (2) add netlist block + final NetlistBlock cellNetlist = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST).next(); + final Template cellTemplate = cellNetlist.getCDLTemplate(); + if (cellTemplate != null) { + final NetlistBlock myNetlist = + (NetlistBlock) blocks.iterator(BlockInterface.NETLIST).next(); + Template myTemplate = myNetlist.getCDLTemplate(); + if (myTemplate == null) { + myTemplate = new Template(Collections.EMPTY_MAP); + myNetlist.setCDLTemplate(myTemplate, Collections.EMPTY_MAP); + } + cellTemplate.execute( + new CDLDeviceNameFilter( + new CDLNodeNameFilter(myTemplate) { + protected HierName processNodeName(HierName node) { + return CellImpl.canonicalizeName( + HierName.prefixName(subcellName, node), + CellImpl.this); + } + }) { + protected HierName processDeviceName(HierName name) { + return HierName.prefixName(subcellName, name); + } + } + ); + } + + // d. + importExcl(subcellName, cell); + /**/ + + // e. + for (final Iterator iSubcellPair = cell.getAllSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair p = (Pair) iSubcellPair.next(); + final HierName asubcellName = (HierName) p.getFirst(); + final CellInterface asubcell = (CellInterface) p.getSecond(); + final HierName newSubcellName = + HierName.append(subcellName, asubcellName); + + addSubcellPair(newSubcellName, asubcell, false); + addPosition(newSubcellName, subcellName, cell, asubcellName); + if (cell.isInlinedSubcell(asubcellName)) { + inlinedSubcellSet.add(newSubcellName); + } + Debug.assertTrue(getSubcell(newSubcellName) == asubcell); + } + addSubcellPair(subcellName, cell, false); + inlinedSubcellSet.add(subcellName); + + // f. + createInlineDirectiveBlock(cell, subcellName, BlockInterface.CELL); + createInlineDirectiveBlock(cell, subcellName, BlockInterface.PRS); + createInlineDirectiveBlock(cell, subcellName, BlockInterface.SUBCELL); + + if (!cell.isNode()) { + adoptedSet.add(subcellName); + for (final Iterator i = ((CellImpl) cell).adoptedSet.iterator(); + i.hasNext(); ) { + adoptedSet.add(HierName.append(subcellName, (HierName) i.next())); + } + } + } + + private static BlockIterator getDirectiveIterator(final CellInterface cell, + final String type) { + BlockInterface block = cell.getBlockInterface(); + if (!type.equals(BlockInterface.CELL)) { + block = block.iterator(type).next(); + } + return block.iterator(BlockInterface.DIRECTIVE); + } + + private void createInlineDirectiveBlock(final CellInterface cell, + final HierName subcellName, + final String type) { + final BlockIterator origIt = getDirectiveIterator(cell, type); + if (origIt.hasNext()) { + final BlockIterator prsIt = getDirectiveIterator(this, type); + final PrsDirective prsDir; + if (prsIt.hasNext()) { + final BlockInterface bi = prsIt.next(); + prsDir = new PrsDirective(type, (DirectiveBlock) bi); + prsIt.set(prsDir); + } else { + prsDir = new PrsDirective(type); + prsIt.add(prsDir); + } + prsDir.addInstance(subcellName, (DirectiveBlock) origIt.next()); + } + } + + // + // + // Nodes / connections + // + // + + /** + * Returns an Iterator of HierNames of the canonical names in the cell. + * The canonical names are those names that are not connected to any + * other canonical names, and are lexicographically less than + * the nodes that they are connected to. + **/ + public Iterator getCanonicalNodes() { + return aliases.getCanonicalKeys(); + } + + /** + * Returns an iterator through all nodes connected to the given node. + **/ + public Iterator getConnectedNodes(HierName nodeName) { + return aliases.getAliases(nodeName); + } + + /** + * The canonical name of the given node. + **/ + public HierName getCanonicalName(HierName nodeName) { + return (HierName) aliases.getCanonicalKey(nodeName); + } + + /** + * Adds a local connection. + **/ + public void addConnection(final HierName n1, final HierName n2) { + aliases.makeEquivalent(n1, n2); + } + + /** + * Adds the specified node name to the list of known nodes. + **/ + public void addNode(final HierName nodeName) { + aliases.add(nodeName); + } + + /** + * For debugging only. + **/ + public String getNamespaceString() { + return aliases.toString(); + } + + // + // + // PRS + // + // + + /** + * Note that the cast cell contained a fragment prs{...} construct. + **/ + public void setHasFragmentPrsBlock() { + this.hasPrsBlock = true; + this.prsBlockIsComplete = false; + } + + /** + * Note that the cast cell contained a non-fragment prs{...} construct. + **/ + public void setHasCompletePrsBlock() { + this.hasPrsBlock = true; + this.prsBlockIsComplete = true; + } + + public boolean containsCompletePrs() { + return hasPrsBlock && prsBlockIsComplete; + } + + public boolean containsFragmentPrs() { + return hasPrsBlock && !prsBlockIsComplete; + } + + /** + * Return the production rule set (PRS) specified by the cell. + * This returns only the general-purpose production rules, those + * which are eventually going to be turned into silicon. The + * production rules which implement asserts (and thus are only for + * simulation) are accessed via getAssertedProductionRuleSet() + **/ + public ProductionRuleSet getProductionRuleSet() { + final PrsBlock prs = + (PrsBlock) blocks.iterator(BlockInterface.PRS).next(); + return prs.getProductionRuleSet(); + } + + /** true if production rule set is not empty **/ + private boolean hasProductionRules() { + return getProductionRuleSet(). + getProductionRules().hasNext(); + } + + /** + * Return the production rule set inferred from the production + * rule guards stated in the assert block. These should never see + * silicon. + **/ + public ProductionRuleSet getAssertedProductionRuleSet() { + final AssertBlock assertBlock = + (AssertBlock) blocks.iterator(BlockInterface.ASSERT).next(); + return assertBlock.getProductionRuleSet(); + } + + // + // + // Java block + // + // + + /** + * Return the cosimulation info from the Java block + **/ + public JavaCoSimInfo getJavaCoSimInfo() { + return javaCosimInfo; + } + + /** + * Fills in the cosimulation information of the specified + * CoSimInfo from the port list. May be called more than once + * with no adverse effect. Can be called on java or on csp. + **/ + public void setCoSimInfoFromPorts(final CoSimInfo outCosimInfo) { + // clear old channels in case we have been called before + outCosimInfo.clearPortChannels(); + + // add channels + for (final Iterator i = getPortDefinitions(); i.hasNext(); ) { + final PortDefinition portDef = (PortDefinition) i.next(); + + // add all channels specified by this port + addPortChannelsToCosimInfo(portDef.getName(), portDef.getType(), + portDef.getDirection(), outCosimInfo); + } + } + + /** + * Adds all channels specified by the port to the CoSimInfo + **/ + private void addPortChannelsToCosimInfo + (String name, final PortTypeInterface type, + final int direction, final CoSimInfo outCosimInfo) { + if (type instanceof NodeType) { + final NodeType nodeType = (NodeType) type; + if (nodeType.isArrayed()) { + for (int i = 0; i < nodeType.getWidth(); ++i) + addNodeToCoSimInfo( + StringUtil.replaceSubstring(name + '[' + i + ']', + "][", ","), + direction, outCosimInfo); + } else { + addNodeToCoSimInfo(StringUtil.replaceSubstring(name, "][", ","), + direction, outCosimInfo); + } + final String newname = + StringUtil.replaceSubstring(name, "][", ","); + outCosimInfo.addWideNode(newname); + outCosimInfo.addNodeInfo(newname, nodeType.getWidth(), + nodeType.isArrayed(), direction); + } else if (type instanceof ChannelType) { + final ChannelType channelType = (ChannelType) type; + + // Interim hack to ignore 1ofN's and _1ofN's + if (channelType.getTypeName().startsWith("standard.channel.1of") || + channelType.getTypeName().startsWith("standard.channel._1of")) + return; + + // e1ofN*M + final int N = extractN(channelType.getTypeName()); + final int M = channelType.getWidth(); + // TODO: give way to control slack + final int slack = 1; + + // Convert ][ to , + final String newname = + StringUtil.replaceSubstring(name, "][", ","); + + // add channel params; use the real name, so that timing directives + // can be looked up; for arrayed, width 1 channels, "[0]" will be + // appended inside CoSimInfo.addChannelInfo to make the name look + // identical to chanName below. + addNewChannelToCosimInfo(newname, slack, N, M, + channelType.isArrayed(), outCosimInfo); + + // Fix for Bug 2373. Add index for "wide" channels of width 1. + // Do this before converting ][ -> , to get better channel + // names. + final String chanName = M == 1 && channelType.isArrayed() ? + StringUtil.replaceSubstring(name + "[0]", "][", ",") : newname; + + // add channel name + if (direction == PortDefinition.IN) + outCosimInfo.addInputChannel(chanName); + else if (direction == PortDefinition.OUT) + outCosimInfo.addOutputChannel(chanName); + else { // INOUT or NONE + System.out.println + ("WARNING: don't know direction of channel " + + newname + " so not hooking it up for cosimulation"); + } + } else if (type instanceof ArrayType) { + final ArrayType arrayType = (ArrayType) type; + + for (int i = arrayType.getMinIndex(); + i <= arrayType.getMaxIndex(); ++i) { + addPortChannelsToCosimInfo(name + "[" + i + "]", + arrayType.getArrayedType(), direction, outCosimInfo); + } + } else if (type instanceof StructureType) { + final StructureType structType = (StructureType) type; + if (CellUtils.isDftChannel(this, structType.getTag())) { + final String newname = + StringUtil.replaceSubstring(name, "][", ","); + if (direction == PortDefinition.IN) + outCosimInfo.addInputDftChannel(newname); + else if (direction == PortDefinition.OUT) + outCosimInfo.addOutputDftChannel(newname); + else { + System.out.println + ("WARNING: don't know direction of DFT channel " + + name + " so not hooking it up for cosimulation"); + } + return; + } + + for (Iterator i = structType.iterator(); i.hasNext(); ) { + PortDefinition p = (PortDefinition) i.next(); + int subDirection = p.getDirection(); + String subName = p.getName(); + PortTypeInterface subType = p.getType(); + + if ((subDirection == PortDefinition.FORWARD + && direction == PortDefinition.IN) + || (subDirection == PortDefinition.REVERSE + && direction == PortDefinition.OUT)) + addPortChannelsToCosimInfo(name + "." + subName, + subType, PortDefinition.IN, outCosimInfo); + else if ((subDirection == PortDefinition.FORWARD + && direction == PortDefinition.OUT) + || (subDirection == PortDefinition.REVERSE + && direction == PortDefinition.IN)) + addPortChannelsToCosimInfo(name + "." + subName, + subType, PortDefinition.OUT, outCosimInfo); + else { // Channel is bidirectional or doesn't have + // direction specified + System.out.println("WARNING: don't know direction of channel " + subName + " in complex channel " + name + " so not hooking it up for cosimulation"); + } + } + } else { + throw new AssertionFailure("Unrecognized type: " + type); + } + } + + private void addNodeToCoSimInfo(final /*@ non_null @*/ String nodeName, + final int direction, + final /*@ non_null @*/ CoSimInfo + outCosimInfo) { + if (direction == PortDefinition.IN) + outCosimInfo.addInputNode(nodeName); + else if (direction == PortDefinition.OUT) + outCosimInfo.addOutputNode(nodeName); + else { // INOUT or NONE + System.out.println + ("WARNING: don't know direction of node " + + nodeName + " so not hooking it up for cosimulation"); + } + } + + public void buildJavaClass(final HierName cellName, + final ChannelDictionary cdict, + final ClassLoader aLoader, + final int arbitrationMode) + throws ClassNotFoundException, InstantiationException, + DeviceConstructionException { + + System.out.println("Getting Java class for: " + cellName); + if (javaCosimInfo.isOldStyle()) { + if (javaCosimInfo.getClassName() == null) { + throw new ClassNotFoundException("no java class set"); + } + final Class javaClass = + Class.forName(javaCosimInfo.getClassName(), true, aLoader); + buildGenericClass(cellName, cdict, javaClass, javaCosimInfo, + arbitrationMode); + } + else { + javaCosimInfo.buildClasses(cellName, cdict, aLoader, + arbitrationMode); + } + } + + public void buildCSPClass(HierName cellName, ChannelDictionary cdict, + final int arbitrationMode, boolean emitCoverageProbes) + throws ClassNotFoundException, InstantiationException { + buildCSPClass(cellName, cdict, arbitrationMode, emitCoverageProbes, 1); + } + + public void buildCSPClass(HierName cellName, ChannelDictionary cdict, + final int arbitrationMode, boolean emitCoverageProbes, + final long seed) + throws ClassNotFoundException, InstantiationException { + buildCSPClass(cellName, cdict, arbitrationMode, emitCoverageProbes, + seed, 1.0f); + } + + public void buildCSPClass(HierName cellName, ChannelDictionary cdict, + final int arbitrationMode, boolean emitCoverageProbes, + final long seed, final float digitalTau) + throws ClassNotFoundException, InstantiationException { + buildCSPClass(cellName, cdict, arbitrationMode, emitCoverageProbes, + null, seed, digitalTau); + } + + public void buildCSPClass(HierName cellName, ChannelDictionary cdict, + final int arbitrationMode, boolean emitCoverageProbes, + CspSnoopingInterface cspSnooper) + throws ClassNotFoundException, InstantiationException { + buildCSPClass(cellName, cdict, arbitrationMode, emitCoverageProbes, + cspSnooper, 1); + } + + public void buildCSPClass(HierName cellName, ChannelDictionary cdict, + final int arbitrationMode, boolean emitCoverageProbes, + CspSnoopingInterface cspSnooper, long seed) + throws ClassNotFoundException, InstantiationException { + buildCSPClass(cellName, cdict, arbitrationMode, emitCoverageProbes, + cspSnooper, seed, 1.0f); + } + + public void buildCSPClass(HierName cellName, ChannelDictionary cdict, + final int arbitrationMode, boolean emitCoverageProbes, + CspSnoopingInterface cspSnooper, long seed, float digitalTau) + throws ClassNotFoundException, InstantiationException { + try { + if (getCspBlock().getCSPClass(emitCoverageProbes) == null) { + final PrintWriter myNullPrintWriter = + new PrintWriter( NullWriter.getInstance() ); + final PrintWriter myStdOutputWriter = + new PrintWriter( new OutputStreamWriter( System.out ) ); + getCspBlock().setCSPClass( + new CSP2Class(myNullPrintWriter, myStdOutputWriter, + myNullPrintWriter, emitCoverageProbes, + cspSnooper != null) + .compile( this ), + emitCoverageProbes); + } + } catch (Exception e) { + throw (InstantiationException) + new InstantiationException (e.toString()).initCause(e); + } + buildGenericClass(cellName, cdict, + getCspBlock().getCSPClass(emitCoverageProbes), + getCSPCoSimInfo(), arbitrationMode, cspSnooper, + seed, digitalTau); + } + + private void buildGenericClass(HierName cellName, ChannelDictionary cdict, + Class cellClass, CoSimInfo cosimInfo, final int arbitrationMode) + throws ClassNotFoundException, InstantiationException { + buildGenericClass(cellName, cdict, cellClass, cosimInfo, + arbitrationMode, null); + } + + private void buildGenericClass(HierName cellName, ChannelDictionary cdict, + Class cellClass, CoSimInfo cosimInfo, final int arbitrationMode, + final CspSnoopingInterface cspSnooper) + throws ClassNotFoundException, InstantiationException { + buildGenericClass(cellName, cdict, cellClass, cosimInfo, + arbitrationMode, cspSnooper, 1); + } + + private void buildGenericClass(HierName cellName, ChannelDictionary cdict, + Class cellClass, CoSimInfo cosimInfo, final int arbitrationMode, + final CspSnoopingInterface cspSnooper, final long seed) + throws ClassNotFoundException, InstantiationException { + buildGenericClass(cellName, cdict, cellClass, cosimInfo, + arbitrationMode, cspSnooper, 1, 1.0f); + } + + // TODO kwallmar: use DeviceConstructionException as an + // appropriate generic wrapper exception + private void buildGenericClass(HierName cellName, ChannelDictionary cdict, + Class cellClass, CoSimInfo cosimInfo, final int arbitrationMode, + final CspSnoopingInterface cspSnooper, final long seed, + final float digitalTau) + throws ClassNotFoundException, InstantiationException { + String cellClassName = cellClass.getName(); + /* Build array of input channels */ + final ChannelInput[] cin = cosimInfo.getInputChannelArray(cdict); + + /* Build array of output channels */ + ChannelOutput[] cout = cosimInfo.getOutputChannelArray(cdict); + + /* Build array of nodes */ + final WideNode[] nodes = cosimInfo.getWideNodeArray(cdict); + + final DeviceParameters params = + new DeviceParameters(cellName.getAsString('.'), + false, + (MetaParamDefinition[]) + metaParamDefinitions.toArray( + new MetaParamDefinition[0]), + arbitrationMode, + seed, + digitalTau); + + final Class[] argumentClasses; + final Object[] arguments; + if (cspSnooper != null) { + argumentClasses = new Class[] { DeviceParameters.class, + cin.getClass(), cout.getClass(), + nodes.getClass(), + CspSnoopingInterface.class }; + arguments = new Object[] { params, cin, cout, nodes, cspSnooper }; + } else { + argumentClasses = new Class[] { DeviceParameters.class, + cin.getClass(), cout.getClass(), + nodes.getClass() }; + arguments = new Object[] { params, cin, cout, nodes }; + } + + final Constructor cnstr; + try { + cnstr = cellClass.getConstructor(argumentClasses); + } catch (NoSuchMethodException e) { + throw (InstantiationException) + new InstantiationException("Instantiation of java class " + + cellClassName + " failed, constructor not found") + .initCause(e); + } + + try { + ((Startable) cnstr.newInstance(arguments)).start(); + } catch (Exception e) { + e.printStackTrace(System.out); + throw (InstantiationException) + new InstantiationException ("Instantiation of java class " + + cellClassName + " failed: " + e.toString()) + .initCause(e); + } + } + + public void setJavaClass(String jclass) { + javaCosimInfo.setClassName(jclass); + System.err.println("Set java class name to " + + javaCosimInfo.getClassName()); + } + + /** Affects the java block information. **/ + public void setInputChannel(String incn) { + final String newChanName = addNewChannelToCosimInfo(incn, javaCosimInfo); + // Interim hack to ignore 1ofN's and _1ofN's + if (newChanName != null) + javaCosimInfo.addInputChannel(newChanName); + } + + /** Affects the java block information. **/ + public void setOutputChannel(String outcn) { + final String newChanName = addNewChannelToCosimInfo(outcn, javaCosimInfo); + // Interim hack to ignore 1ofN's and _1ofN's + if (newChanName != null) + javaCosimInfo.addOutputChannel(newChanName); + } + + /** Affects the java block information. **/ + public void setInternalChannel(String intcn) { + final String newChanName = addNewChannelToCosimInfo(intcn, javaCosimInfo); + // Interim hack to ignore 1ofN's and _1ofN's + if (newChanName != null) + javaCosimInfo.addInternalChannel(newChanName); + } + + /** Adds the channel and parameters specified by spec + * to outCosimInfo.chanParams and returns the name + * of the new channel. + **/ + private String addNewChannelToCosimInfo(String spec, final CoSimInfo outCosimInfo) { + ChannelTokenizer strtok = new ChannelTokenizer(spec); + final String name = strtok.nextToken(); + if (!strtok.hasMoreTokens()) { + // No spec, just name. Assume e1of2 slack 0 + addNewChannelToCosimInfo(name, 0, 2, 1, false, outCosimInfo); + return name; + } + if (!strtok.nextToken().equals("(")) { + System.out.println("Bad channel spec"); + throw new BadChannelSpec(name); + } + String buf = strtok.nextToken(); + // Interim hack to ignore 1ofN's and _1ofN's + if (buf.startsWith("standard.channel.1of") || + buf.startsWith("standard.channel._1of")) + return null; + final int N = extractN(buf); + final boolean arrayed; + buf = strtok.nextToken(); + int M; + if (buf.equals("*")) { + M = Integer.parseInt(strtok.nextToken()); + buf = strtok.nextToken(); + arrayed = true; + } else { + M = 1; + arrayed = false; + } + int slack = 0; + if (!buf.equals(")")) { + if (!buf.equals("slack")) + throw new BadChannelSpec(name); + buf = strtok.nextToken(); + slack = Integer.parseInt(buf); + if (!strtok.nextToken().equals(")")) + throw new BadChannelSpec(name); + } + if (strtok.hasMoreTokens()) { + throw new BadChannelSpec(name); + } + + addNewChannelToCosimInfo(name, slack, N, M, arrayed, outCosimInfo); + return name; + } + + /** + * Returns N from a string of the form standard.channel.e1ofN. + **/ + private int extractN(final String channelType) { + final int result = CellUtils.extractN(channelType); + if (result == -1) throw new BadChannelSpec(channelType); + else return result; + } + + private void addNewChannelToCosimInfo + (final String name, final int slack, + final int N, final int M, final boolean isArrayed, + final CoSimInfo cosimInfo) { + // System.err.println("Adding channel " + name + " with parameters " + + // "e1of" + N + " * " + M + " slack " + slack); + cosimInfo.addChannelInfo(name, slack, N, M, isArrayed); + } + + class BadChannelSpec extends RuntimeException { + public BadChannelSpec(String foo) { super(foo); } + } + + class ChannelTokenizer { + private final StringTokenizer instrtok; + private String upcomingToken; + public ChannelTokenizer(String str) { + instrtok = new StringTokenizer(str, " ()*", true); + upcomingToken = getNextToken(); + } + + private String getNextToken() { + String rv = " "; + while (instrtok.hasMoreTokens() && + (rv=instrtok.nextToken()).equals(" ")) + { } + if (rv.equals(" ")) + return null; + else + return rv; + } + + public boolean hasMoreTokens() { + return (upcomingToken != null); + } + + public String nextToken() { + final String rv = upcomingToken; + upcomingToken = getNextToken(); + return rv; + } + } + + // + // + // CSP stuff + // + // + + private CspBlock getCspBlock() { + return (CspBlock) blocks.iterator(BlockInterface.CSP).next(); + } + + /** Return the cosimulation info from the csp block. **/ + public CSPCoSimInfo getCSPCoSimInfo() { + return getCspBlock().getCSPCoSimInfo(); + } + + /** + * Returns the CSP body, or null if none. + **/ + public CSPProgram getCSPProgram() { + //System.out.println("Getting csp body " + ((csp == null) ? "null" : "not null") + " in object " + this); + return getCspBlock().getCSPProgram(); + } + + /** + * Sets the CSP body. + **/ + public void setCSPProgram(final CSPProgram csp) { + //System.out.println("Setting csp body to " + ((csp == null)? "null" : "not null") + " in object " + this); + getCspBlock().setCSPProgram(csp); + } + + /** + * Returns as much non-csp info about the cell as the csp + * processing is going to need (ports/metas information). + **/ + public CSPCellInfo getCSPInfo() { + final Collection ports; + if (getCspBlock().getCSPPorts().isEmpty()) { + ports = portDefinitions.values(); + } else { + // Construct the list of port definitions for the csp block + ports = new ArrayList/**/(); + for (final Iterator i = getCspBlock().getCSPPorts().iterator(); + i.hasNext(); ) { + final String name = (String) i.next(); + final PortDefinition port = portDefinitions.get(name); + Debug.assertTrue(port != null, "couldn't find port " + port + " anymore"); + ports.add(portDefinitions.get(name)); + } + } + // Should this be cached? + return new CSPCellInfo(getFullyQualifiedType(), metaParamDefinitions, ports); + } + + /** + * Takes the name of a port for the csp block. If this function + * is never called, this cell passes all its ports to the + * csp->java compiler. + **/ + public void addCSPPort(String portName) + throws BadCSPPortException { + if (portDefinitions.get(portName) == null) + throw new BadCSPPortException(getFullyQualifiedType(), portName); + + getCspBlock().getCSPPorts().add(portName); + } + + // + // + // Spec stuff: exclhi/excllo + // + // + + public ExclusiveNodeSets getLocalExclusiveNodeSets() { + final AssertBlock assertBlock = + (AssertBlock) blocks.iterator(BlockInterface.ASSERT).next(); + return assertBlock.getExclusiveNodeSets(); + } + + /** + * @deprecated Use getExclusiveNodeSets().addExclusiveSet(ens) + **/ +// public void addExclusiveNodeSet(final ExclusiveNodeSet ens) { +// getExclusiveNodeSets().addExclusiveNodeSet(ens); +// } + + // + // + // Flatten + // + // + + /** + * Returns a flattened version of the cell. The flattened version + * has no subcells. + *

    + * Flattening can cause globals to appear that were not previously + * there (duh). + **/ + public CellInterface flatten() { + return flatten(Integer.MAX_VALUE); + } + + /** + * Returns a flattened version of the cell. The flattened version + * has no subcells. + *

    + * Flattening can cause globals to appear that were not previously + * there (duh). + * + * @param maxPrsDepth the maximum depth from which production rules + * should be imported. Zero means only the current cell. + * Negative means none at all. + **/ + public CellInterface flatten(final int maxPrsDepth) { + return flatten(maxPrsDepth, new TreeMap()); + } + + private ProductionRule canonicalizeProductionRuleForFlatten( + final CellImpl flatCell, + final ProductionRule pr) { + return new ProductionRule( + canonicalizeBooleanExpressionHierNames( + pr.getGuard(), flatCell), + canonicalizeName(pr.getTarget(), flatCell), + canonicalizeName(pr.getPowerSupply(), flatCell), + pr.getDirection(), + pr.isIsochronic(), pr.isUnstable(), + pr.isMetastable(), pr.isTimed(), + pr.getAfter(), pr.isAbsolute()); + } + + // Suffix used to create new "flat" version of the cell. + private static String FLAT_SUFFIX = "$FLAT"; + + /** + * Use the cache, Luke! + * + * @param flattenedCellCache cache of cells that have been + * flattened + **/ + private CellInterface flatten(final int maxPrsDepth, + final Map/**/ + flattenedCellCache) { + // A node or a flat cell cannot be flattened further + if (isNode() || getType().endsWith(FLAT_SUFFIX)) return this; + + // use the cached version if we have one + final CellInterface cachedCell + = (CellInterface) flattenedCellCache.get(getFullyQualifiedType() + FLAT_SUFFIX); + if (cachedCell != null) + return cachedCell; + + final CellImpl flatCell = + new CellImpl(getType() + FLAT_SUFFIX, moduleName); + + // 1. for each canonical node in this cell: + // a. add all connected nodes + // 1.5 inherit directives + // 2. for each subcell: + // a. flatten it + // b. for each canonical node: + // i. add node and all connected nodes with + // usage name prefixed to name + // c. add that cell's production rules to the flat cell, + // with the usage name prefixed to each node, + // *taking care to use the new canonical node name + // d. add that cell's exclhi / excllo to the flattened cell + // *taking care to use the new canonical node name + // 3. Add all production rules from this cell, + // *taking care to use the canonical name for each node + // 4. import the exclhi / excllo statements from this cell + // *taking care to use the canonical name for each node + + // 1. + for (final Iterator iCanonicalNode = getCanonicalNodes(); + iCanonicalNode.hasNext(); ) { + final HierName canonicalNode = (HierName) iCanonicalNode.next(); + + // a. + for (final Iterator iConnectedNode + = getConnectedNodes(canonicalNode); + iConnectedNode.hasNext(); ) { + final HierName connectedNode + = (HierName) iConnectedNode.next(); + + flatCell.addConnection(canonicalNode, connectedNode); + } + } + + // 1.5 + flatCell.adoptDirective(this); + + // 2. + for (final Iterator iSubcellPair = getAllSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair pair = (Pair) iSubcellPair.next(); + + final HierName subcellName = (HierName) pair.getFirst(); + if (!adoptedSet.contains(subcellName)) { + // a. + final CellInterface subcell + = ((CellImpl) pair.getSecond()) + .flatten(maxPrsDepth - 1, flattenedCellCache); + + // b. c. d. + flatCell.adoptCell(subcellName, subcell); + } + } + + /**/ + // 3. + if (maxPrsDepth >= 0) { + for (final Iterator generalPRS + = getProductionRuleSet().getProductionRules(); + generalPRS.hasNext(); ) { + final ProductionRule pr = (ProductionRule) generalPRS.next(); + + // * be sure to use canonical name + + flatCell.getProductionRuleSet().addProductionRule( + canonicalizeProductionRuleForFlatten(flatCell, pr)); + } + + for (final Iterator assertedPRS + = getAssertedProductionRuleSet().getProductionRules(); + assertedPRS.hasNext(); ) { + final ProductionRule pr = (ProductionRule) assertedPRS.next(); + + // * be sure to use canonical name + + flatCell.getAssertedProductionRuleSet().addProductionRule( + canonicalizeProductionRuleForFlatten(flatCell, pr)); + } + + } + + // 4. + flatCell.importExcl(null, this); + /**/ + + // save the flattened cell in the cache + /** @bug jmr this is cachine regardless of maxPrsDepth!!! + * the wrong thing may be cached. We probably want to + * get rid of maxPrsDepth, considering we only pass 1 and + * Integer.MAX_VALUE **/ + flattenedCellCache.put(getFullyQualifiedType() + FLAT_SUFFIX, flatCell); + + return flatCell; + } + + /** + * Import the exclhi / excllo declarations of the given cell + * into this. If subcellName is + * non-null, then prefix the names of the nodes + * in the excllo / exclhi sets with it. + **/ + private void importExcl(final HierName subcellName, + final CellInterface cell) { + for (final Iterator iENS = cell.getLocalExclusiveNodeSets().getIterator(); + iENS.hasNext(); ) { + final ExclusiveNodeSet ens = (ExclusiveNodeSet) iENS.next(); + final ArrayList l = new ArrayList(); + + // canonicalize all the nodes in the exclusion set + for (final Iterator iExclNode = ens.getNodes(); + iExclNode.hasNext(); ) { + final HierName hn = (HierName) iExclNode.next(); + final HierName hn2; + if (subcellName == null) + hn2 = hn; + else + hn2 = HierName.prefixName(subcellName, hn); + l.add(canonicalizeName(hn2, this)); + } + + getLocalExclusiveNodeSets().addExclusiveNodeSet( + new ExclusiveNodeSet(ens.getHiLo(), l)); + } + } + + /** + * Recurses through the BooleanExpressionInterface, returning + * a new BooleanExpressionInterface with all HierNames prefixed by + * the specified subcellName, unless the name is a global + * name, in which case it will be passed through unchanged. + **/ + private static BooleanExpressionInterface + canonicalizeBooleanExpressionHierNames( + final BooleanExpressionInterface be, + final CellInterface cell) { + return BooleanUtils.mapBooleanExpressionHierNames(be, + new UnaryFunction() { + public Object execute(final Object o) { + return canonicalizeName((HierName) o, cell); + } + }); + + } + + /** + * Recurses through the BooleanExpressionInterface, returning + * a new BooleanExpressionInterface with all HierNames prefixed by + * the specified subcellName, unless the name is a global + * name, in which case it will be passed through unchanged. + **/ + private static BooleanExpressionInterface + prefixAndCanonicalizeBooleanExpressionHierNames( + final BooleanExpressionInterface be, + final HierName subcellName, + final CellInterface cell) { + return BooleanUtils.mapBooleanExpressionHierNames(be, + new UnaryFunction() { + public Object execute(final Object o) { + return canonicalizeName( + HierName.prefixName(subcellName, + (HierName) o), cell); + } + }); + + } + + /** + * Returns the canonical name of name in cell, + * or, if the name isn't known to cell, return name. + **/ + private static HierName canonicalizeName(final HierName name, + final CellInterface cell) { + final HierName canonName = cell.getCanonicalName(name); + if (canonName == null) + return name; + else + return canonName; + } + + // smartFlatten + // flatten could be done more intelligently, not allocating + // much new data, but providing a structure with more + // intelligent iterators + + // + // + // Env block + // + // + + /** + * Used for setting as well as getting the named environments of this cell. + **/ + public EnvBlock getEnvironments() { + return (EnvBlock) blocks.iterator(BlockInterface.ENV).next(); + } + + + // + // + // Misc + // + // + + /** + * Returns true if this cell or any of its subcells have non- + * env production rules. + **/ + public boolean hasRealProductionRule() { + // check the prs of this cell, returning true if a non-env + // pr appears + for (final Iterator iPr + = getProductionRuleSet().getProductionRules(); + iPr.hasNext(); ) { + final ProductionRule pr = (ProductionRule) iPr.next(); + return true; + } + + // if any of its subcells have a real production rule, + // then this one does, so return true. + // TODO: this could be improved by iterating over the + // types of subcells, rather than the names, and + // further improved by caching the results. + for (final Iterator iSubcellPair = getSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair pair = (Pair) iSubcellPair.next(); + final CellInterface subcell = ((CellImpl) pair.getSecond()); + + if (subcell.hasRealProductionRule()) + return true; + } + + // otherwise, return false, no real production rules + return false; + } + + public boolean hasNetlistBody() { + // Should refactor with hasRealProductionRule above + if (containsNetlist()) return true; + for (final Iterator iSubcellPair = getSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair pair = (Pair) iSubcellPair.next(); + final CellInterface subcell = ((CellImpl) pair.getSecond()); + + if (subcell.hasNetlistBody()) + return true; + } + + return false; + } + + public boolean hasVerilog() { + // Should refactor with hasRealProductionRule above + if (containsVerilog()) return true; + for (final Iterator iSubcellPair = getSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair pair = (Pair) iSubcellPair.next(); + final CellInterface subcell = ((CellImpl) pair.getSecond()); + + if (subcell.hasVerilog()) + return true; + } + + return false; + } + + public boolean hasRunnableCsp() { + // Should refactor with hasRealProductionRule above + if (containsRunnableCsp()) return true; + for (final Iterator iSubcellPair = getSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair pair = (Pair) iSubcellPair.next(); + final CellInterface subcell = ((CellImpl) pair.getSecond()); + + if (subcell.hasRunnableCsp()) + return true; + } + + return false; + } + + public BlockInterface getBlockInterface() { + return blocks; + } + + // Refinement stuff + + /** + * Helper function for setRefinementParent(). Handles the + * inheritance of subcells from the parent when there are subtypes + * to deal with. + **/ + private void refineSubcellsUsingSubtypes(CellImpl parent) + throws RefinementException { + // The subtype statements which referred to arrays can't be + // removed until all of the array elements have passed by. + // Temporary storage to remember to remove them at the end. + Set/**/ arrayedSubtypeSet = new HashSet(); + + // Need to check each cell to see if it's been subtyped. + for (Iterator parentSubcells = parent.subcellMap.keySet().iterator(); + parentSubcells.hasNext(); + ) { + final HierName cellName = (HierName) parentSubcells.next(); + final HierName baseCellName; + final Triplet subtypeInfo; + if (subtypeMap.containsKey(cellName)) { + baseCellName = null; + subtypeInfo = (Triplet) subtypeMap.get(cellName); + } else { + baseCellName = cellName.getArrayBase(); + subtypeInfo = (Triplet) subtypeMap.get(baseCellName); + } + if (subtypeInfo != null) { + // Can't subtype flattened or inlined cells + if (inlinedSubcellSet.contains(cellName)) { + throw new RefinementException("can't subtype flattened/inlined cell " + cellName + " in this revision of cast parsing", + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } + + // The specified parent type and actual parent + // type of the subtyped subcell should match. + String specifiedParentType = + ((CellImpl)subtypeInfo.getFirst()) + .getFullyQualifiedType(); + String actualParentType = + ((CellImpl)parent.subcellMap.get(cellName)) + .getFullyQualifiedType(); + + if (! actualParentType.equals(specifiedParentType)) { + throw new RefinementException("can't subtype " + cellName + " of type " + actualParentType + " as a cell of type " + specifiedParentType, + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } + + subcellMap.put(cellName, subtypeInfo.getSecond()); + // If the newly refined subcell should be inlined. + if (((Boolean) subtypeInfo.getThird()).booleanValue()) { + try { + inlineSubcell(cellName); + } catch (NoSuchSubcellException e) { + throw new RefinementException("Error inlining refined subcell: " + e.getMessage(), getFullyQualifiedType(), + parent.getFullyQualifiedType(), e); + } catch (SubcellCreationException e) { + throw new RefinementException("Error inlining refined subcell: " + e.getMessage(), getFullyQualifiedType(), + parent.getFullyQualifiedType(), e); + } + } + if (baseCellName == null) { + subtypeMap.remove(cellName); + } else { + arrayedSubtypeSet.add(baseCellName); + } + } + else { + // Implicitly subtype port subcells; port compatiblity checked + // in CastTwoTree.g + if (!isPortSubcell(cellName)) + subcellMap.put(cellName, parent.subcellMap.get(cellName)); + } + } + + // Remove the subtype statements that referenced arrays. + Iterator iter = arrayedSubtypeSet.iterator(); + while (iter.hasNext()) { + subtypeMap.remove(iter.next()); + } + } + + /** + * Copies all node subcells from the parent cell to the child cell. + **/ + public void inheritNodes(final CellImpl parent) { + final Map/**/ childMap = subcellMap; + final Map/**/ parentMap = parent.subcellMap; + final Iterator parentEntries = parentMap.entrySet().iterator(); + while (parentEntries.hasNext()) { + final Entry parentEntry = (Entry) parentEntries.next(); + final HierName n = (HierName) parentEntry.getKey(); + final CellImpl c = (CellImpl) parentEntry.getValue(); + if (c.isNode() && !childMap.containsKey(n)) + childMap.put(n, c); + } + } + + /** + * This turns this cell into a refinement of the parent cell. It + * doesn't handle comparing the new ports to the old ports; that + * needs to be handled at the UserDefinedValue or baseType level, + * when the ports are still in order. + * + *

    It changes this cell but not the parent cell. They do share + * some data storage now. + * + *

    Refinement behavior is not defined on any cell which + * produces compile warnings about deprecated features. + **/ + + public void setRefinementParent (CellImpl parent, boolean portsMatched, + CastParsingOption opt) + throws RefinementException { + doInheritanceOrRefinement(parent, true, portsMatched, opt); + } + + /** + * Handles work of <: refinement or <+ inheritance. Called by + * {@link setRefinementParent()} and + * {@link setInheritance()}. Copies blocks (prs, subcells, + * ...), directives, nodes, etc. from parent to + * this. + * + * @param parent Cell to inherit attributes from. + * @param isRefinement If true, directRefinementParent + * will be set to the fully qualified type of parent. + * @param portsMatched If true, and isRefinement is true, + * then set refinementAncestor to the + * parent's ancestor. Has no effect if + * isRefinement is false. + **/ + private void doInheritanceOrRefinement(CellImpl parent, + boolean isRefinement, + boolean portsMatched, + CastParsingOption opt) + throws RefinementException { + + // To keep track of inherited behavior without confusing it + // with specified behavior. + boolean futureHasPrsBlock = hasPrsBlock; + boolean futurePrsBlockIsComplete = prsBlockIsComplete; + boolean futureHasSubcellsBlock = hasSubcellsBlock; + + // Keep track of what cells have already been adopted + adoptedSet.addAll(parent.adoptedSet); + + // this needs to be done before blocks.refineFrom is called, + // so we can tell whether or not our cell defines its own + // production rules + if (parent.hasPrsBlock && hasPrsBlock && parent.prsBlockIsComplete + && hasProductionRules()) { + // if parent has a complete prs block, we are not + // allowed to have one. + throw new RefinementException + ("can't use prs with non-empty rule set to refine a cell with"+ + "non-fragment prs", + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } + + if (subcellsBlockIsComplete == null) + subcellsBlockIsComplete = parent.subcellsBlockIsComplete; + + // Inherit the auto-inline property of the parent cell + setAutoInline(isAutoInline() || parent.isAutoInline()); + + blocks.refineFrom(parent.blocks); + + instancePositions.putAll(parent.instancePositions); + + // Merge parent and child aliases. + Namespace.addNamespace(this.aliases,parent.aliases); + + /** @see bug 1478 **/ + if (containsNetlist() && (hasSubcellsBlock || hasSubtypesBlock)) { + throw new RefinementException + ("Cells with netlist blocks may not define a "+ + "subcell or subtypes block, or inherit from a "+ + "cell which defines one", + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } + + // Assert blocks handled by blocks + + // CSP block handled by blocks + + if (isRefinement) + this.directRefinementParent = parent; + + // Exclusive node sets are handled by assert block + + if (hasPrsBlock || hasSubcellsBlock) { + // prs blocks are additive, so copy parental inlined + // subcells + inlinedSubcellSet.addAll(parent.inlinedSubcellSet); + } else if (!hasSubcellsBlock) { + // if no prs and no subcells, copy from parent + inlinedSubcellSet.clear(); + inlinedSubcellSet.addAll(parent.inlinedSubcellSet); + } + // subcells blocks replace, so if we have a subcells block, + // leave inlined subcells as ours + + // java block overrides + javaCosimInfo.refineFrom(parent.javaCosimInfo); + + // module name can't be inherited. + + // environments are handled by blocks + + // Either the ports match up exactly, or the parent's port + // list is empty. In either case, port definitions and port + // subcells don't need to change. + + if (isRefinement && portsMatched) { + refinementAncestor = parent.refinementAncestor; + } + + // prs blocks merge + if (parent.hasPrsBlock) { + if (hasSubcellsBlock || hasSubtypesBlock) { + throw new RefinementException + ("can't use subcells to refine a cell with prs", + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } + + // actual merging handled by blocks + + // subcellMap has internal nodes + fillInMap(subcellMap, parent.subcellMap); + futureHasPrsBlock = true; + + + // else parent is fragment, child is fragment or complete, + // so child remains as is + + // no prs block, so copy completeness from parent + if (!hasPrsBlock) { + futurePrsBlockIsComplete = parent.prsBlockIsComplete; + } + } + + // subtypes will change the cell interfaces bound to + // particular names, as well as mucking with aliases. + else if (parent.hasSubcellsBlock) { + if (hasPrsBlock) { + throw new RefinementException + ("can't use prs to refine a cell with subcells", + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } else if (parent.containsCompleteSubcells() && hasSubcellsBlock) { + throw new RefinementException + ("can't use subcells to refine a cell with complete " + + "subcells", + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } else if (parent.containsFragmentSubcells() && hasSubtypesBlock) { + throw new RefinementException + ("can't use subtypes to refine a cell with fragment " + + "subcells", + getFullyQualifiedType(), + parent.getFullyQualifiedType()); + } else { + futureHasSubcellsBlock = true; + if (! hasSubtypesBlock) { + fillInMap(subcellMap, parent.subcellMap); + } + else { // Has subtypes + refineSubcellsUsingSubtypes(parent); + } + } + } + + else { // Neither prs nor subcells in the parent, but it might + // have aliases that need to be imported. + fillInMap(subcellMap, parent.subcellMap); + } + + // If inline processing has been turned off, any instances that come + // from inlining would remain in subtypeMap. Attempt to remove those + // references from subtypeMap to prevent a fatal error. + if (isRefinement && !subtypeMap.isEmpty() && opt != null) { + final Set pending = new HashSet(); + for (Iterator i = subtypeMap.keySet().iterator(); i.hasNext(); ) { + final HierName inst = (HierName) i.next(); + HierName name = inst; + while (name != null && !subcellMap.containsKey(name)) { + name = name.getParent(); + } + if (name != null) { + final CellInterface subcell = + (CellInterface) subcellMap.get(name); + if (!opt.processInline(subcell)) { + pending.add(inst); + if (!refinementWarned) { + refinementWarned = true; + System.out.println( + "WARNING: " + getFullyQualifiedType() + + " subtypes inlined subcells, but inline" + + " processing is turned off."); + } + } + } + } + for (HierName inst : pending) subtypeMap.remove(inst); + } + + // All subtypes should refer to actual subcells. + if (isRefinement && !subtypeMap.isEmpty()) { + throw new RefinementException + ("not all subtypes refer to actual subcells. "+ + "Subtypes left over: " + + getSubtypesString(subtypeMap), + getFullyQualifiedType(), parent.getFullyQualifiedType()); + } + + // type can't be inherited + + hasSubcellsBlock = futureHasSubcellsBlock; + hasPrsBlock = futureHasPrsBlock; + prsBlockIsComplete = futurePrsBlockIsComplete; + } + + /** + * Called by the tree parser to setup inheritance via <+. + * @param parent Cell to inherit attributes from. + **/ + public void setInheritance(final CellImpl parent) + throws RefinementException { + inheritedCells.add(parent); + doInheritanceOrRefinement(parent, false, false, null); + } + + private static String getSubtypesString( + final Map/*>*/ + subtypeMap) { + final StringBuffer sb = new StringBuffer(); + + sb.append('['); + boolean first = true; + for (final Iterator i = subtypeMap.entrySet().iterator(); + i.hasNext(); ) { + final Entry e = (Entry) i.next(); + final HierName subcellName = (HierName) e.getKey(); + final Triplet t = (Triplet) e.getValue(); + final CellInterface parent = (CellInterface) t.getFirst(); + final CellInterface child = (CellInterface) t.getSecond(); + + if (!first) + sb.append(", "); + first = false; + + sb.append(parent.getFullyQualifiedType()); + sb.append(" :> "); + sb.append(child.getFullyQualifiedType()); + sb.append(" "); + sb.append(subcellName.getAsString('.')); + } + sb.append(']'); + + return sb.toString(); + } + + public boolean oldSameRefinementAncestor(CellInterface c) { + return ((CellImpl) c).refinementAncestor.equals(refinementAncestor); + } + + public boolean sameRefinementAncestor(CellInterface c) { + final String ancestor = ((CellImpl) c).refinementAncestor; + while (c != null) { + if (c == this) { + return true; + } else if (ancestor.equals(c.getFullyQualifiedType())) { + return false; + } else { + c = c.getDirectRefinementParent(); + } + } + return false; + } + + /** + * Returns true if this is cell or refined from cell or refined from a + * CellInterface which is refined from cell or .... + **/ + public boolean eventuallyRefinesFrom(CellInterface cell) { + CellImpl otherCell = (CellImpl) cell; + CellImpl temp = this; + while (temp != null) { + if (temp.equals(otherCell)) return true; + temp = temp.directRefinementParent; + } + return false; + } + + /** + * accessor for directRefinementParent + */ + public CellInterface getDirectRefinementParent(){ + return (CellInterface)this.directRefinementParent; + } + + /** + * Returns true if all of this cell's port subcells refine from + * this defchan cell. Port defchan subcells are traversed until either + * nodes or a subcell that refines from chanCell is encounted. + * When chanCell is standard.e1of, this method indicates + * whether this cell communicates with its environment in a fully + * four-phase asynchronous manner (and is presumably DI). + **/ + public boolean allPortSubcellsRefineFrom(final CellInterface parentChannel) { + if (portSubcellSet.isEmpty()) return false; + for (Iterator pi=portSubcellSet.iterator(); pi.hasNext();) { + HierName portName = (HierName) pi.next(); + if (impliedPortMapping.containsKey(portName.toString())) continue; + CellInterface portType = (CellInterface)subcellMap.get(portName); + if (!portType.eventuallyRefinesFrom(parentChannel) && + !portType.allPortSubcellsRefineFrom(parentChannel)) + return false; + } + return true; + } + + /** + * Return the cosimulation info that matches the specified + * behavior. Gives precedence to java block over csp block. + **/ + public CoSimInfo getCoSimInfo(int cosimBehavior) { + if ((cosimBehavior & CoSimParameters.JAVA) != 0) + return javaCosimInfo; + else if ((cosimBehavior & CoSimParameters.CSP) != 0) + return getCSPCoSimInfo(); + Debug.assertTrue(false, "bad cosimBehavior passed in to getCoSimInfo: " + cosimBehavior); + return null; // mollify compiler + } + + /** + * Debugging function. Returns a string with all sorts of information + * about the internal data structures. Hasn't been updated to reflect + * all the information currently stored in CellImpl. + **/ + public String toString() { + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw, true); + + pw.println("Dump of cell of type: "+getFullyQualifiedType()); + pw.println("dump:"+getFullyQualifiedType()+":aliases:"); + pw.println(aliases); + pw.println("dump:"+getFullyQualifiedType()+"assertblock:"); + pw.println(blocks.iterator(BlockInterface.ASSERT).next()); + pw.println("dump:"+getFullyQualifiedType()+":csp:"); + pw.println(getCSPProgram()); + pw.println("dump:"+getFullyQualifiedType()+":csp cosim info:"); + pw.println(getCSPCoSimInfo()); + pw.println("dump:"+getFullyQualifiedType()+":cspClass:"); + pw.println(getCspBlock().getCSPClass(false)); + pw.println("dump:"+getFullyQualifiedType()+":cspClass:"); + pw.println(getCspBlock().getCSPClass(true)); + pw.println("dump:"+getFullyQualifiedType()+":directives:"); + BlockIterator iter = blocks.iterator(BlockInterface.DIRECTIVE); + if (iter.hasNext()) + pw.println(iter.next()); + else + pw.println("none"); + pw.println("dump:"+getFullyQualifiedType()+":java cosim info:"); + pw.println(javaCosimInfo); + pw.println("dump:"+getFullyQualifiedType()+":inlinedSubcellSet:"); + pw.println(inlinedSubcellSet); + pw.print ("dump:"+getFullyQualifiedType()+":module name:"); + pw.println(moduleName); + pw.println("dump:"+getFullyQualifiedType()+":namedEnvironments:"); + pw.println(getEnvironments()); + pw.println("dump:"+getFullyQualifiedType()+":portSubcellSet:"); + pw.println(portSubcellSet); + pw.println("dump:"+getFullyQualifiedType()+":prsBlock:"); + pw.println(blocks.iterator(BlockInterface.PRS).next()); + pw.println("dump:"+getFullyQualifiedType()+":subcellMap:"); + pw.println(subcellMap); + pw.println("dump:"+getFullyQualifiedType()+":adoptedSet:"); + pw.println(adoptedSet); + + return sw.toString(); + } + + /** + * Helper function for setRefinementParent(): copies the + * information from the parent map that isn't overridden by the + * child into the child, but leaves the rest alone. putAll + * overwrites everything. Useful when the child has refined + * ports, for instance. + **/ + private static void fillInMap(Map/**/ child, + final/**/ Map + parent) { + final Iterator parentKeys = parent.keySet().iterator(); + while (parentKeys.hasNext()) { + Object parentKey = parentKeys.next(); // casting isn't worth it + if (! child.containsKey(parentKey)) + child.put(parentKey, parent.get(parentKey)); + } + } + + public boolean containsJava() { + return !javaCosimInfo.isEmpty(); + } + + public boolean containsCsp() { + return getCSPProgram() != null; + } + + public boolean containsRunnableCsp() { + return getCspBlock().hasSequentialStatement(); + } + + public boolean containsNetlist() { + final NetlistBlock netlistBlock = + (NetlistBlock) blocks.iterator(BlockInterface.NETLIST).next(); + return !netlistBlock.isEmpty(); + } + + public boolean containsVerilog() { + return blocks.iterator(BlockInterface.VERILOG).hasNext(); + } + + public CellInterface getEnvironment(final String envName) + throws NoSuchEnvironmentException { + final EnvBlock eb = getEnvironments(); + assert eb != null : "Cell " + getFullyQualifiedType() + + " has no environment block"; + try { + final CellInterface result = eb.getNamedEnvironment(envName); + if (result == null) + throw new NoSuchEnvironmentException(getFullyQualifiedType(), + envName); + else + return result; + } catch (CastSemanticException e) { + throw new NoSuchEnvironmentException(getFullyQualifiedType(), + envName, e); + } + } + + // specified CellInterface + public CellInterface inlineLayoutSubcells() { + final CellImpl cell = + new CellImpl(type, moduleName, definitionKind, filename); + cell.subcellMap.putAll(subcellMap); + cell.portSubcellSet.addAll(portSubcellSet); + cell.inlinedSubcellSet.addAll(inlinedSubcellSet); + final BlockIterator bi = blocks.iterator(BlockInterface.DIRECTIVE); + if (bi.hasNext()) { + cell.blocks.iterator(BlockInterface.DIRECTIVE).add( + new DirectiveBlock((DirectiveBlock) bi.next())); + } + Namespace.addNamespace(cell.aliases, aliases); + + final PrsBlock prs = + (PrsBlock) blocks.iterator(BlockInterface.PRS).next(); + final PrsBlock newPrs = + (PrsBlock) cell.blocks.iterator(BlockInterface.PRS).next(); + + newPrs.refineFrom(prs); + + // for all non-channel subcells, inline them if inline_subcell + // is specified for that subcell or if inline_subcell is + // specified for all cells and the inlining of that cell has + // not been overridden. + + final Map m = DirectiveUtils.getSubcellDirective(this, + DirectiveConstants.INLINE_LAYOUT, + DirectiveConstants.INSTANCE_TYPE); + final boolean inlineAll + = ((Boolean) DirectiveUtils.getSubcellDirective(this, + DirectiveConstants.INLINE_LAYOUT)).booleanValue(); + + for (final Iterator i = getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final Boolean inlineSubcell = (Boolean) m.get(subcellName); + + if (!subcell.isChannel()) { + if ((inlineSubcell != null && + inlineSubcell.booleanValue()) || + (inlineAll && inlineSubcell == null)) { + try { + cell.inlineSubcell(subcellName, false, false); + } catch (NoSuchSubcellException x) { + throw new AssertionError(x); + } catch (SubcellCreationException x) { + throw new AssertionError(x); + } + } + } + } + + return cell; + } + + public Iterator getInheritedCells() { + return inheritedCells.iterator(); + } + + /** + * Add the mapping from the given implied port to its connection in the + * parent cell. + * + * @param self name of the implied port in this cell + * @param parent name of the object in the parent to connect to + **/ + public void addImpliedPortMapping(final String self, + final String parent) { + impliedPortMapping.put(self, parent); + } + + public String getParentImpliedPort(final String self) { + return impliedPortMapping.get(self); + } + + public void addEnvExtraPortMapping(final String self, + final String dut) { + envExtraPortMapping.put(self, dut); + } + + public String getEnvExtraPortMapping(final String self) { + return envExtraPortMapping.get(self); + } + + public CellInterface routedSubcells(final boolean complete) { + return routedSubcells(complete, false, new HashMap()); + } + + private CellInterface routedSubcells(final boolean complete, + final boolean addSuffix, + final Map cache) { + if (!getSubcellPairs().hasNext()) return this; + + final CellImpl cached = (CellImpl) cache.get(getFullyQualifiedType()); + if (cached != null) return cached; + + final CellImpl cell = + new CellImpl(type + (addSuffix ? "$ROUTED" : ""), moduleName, + definitionKind, filename); + cell.refinementAncestor = refinementAncestor; + cell.directRefinementParent = directRefinementParent; + cell.subcellMap.putAll(subcellMap); + cell.portSubcellSet.addAll(portSubcellSet); + cell.inlinedSubcellSet.addAll(inlinedSubcellSet); + cell.adoptedSet.addAll(adoptedSet); + cell.metaParamDefinitions.addAll(metaParamDefinitions); + cell.portDefinitions.putAll(portDefinitions); + cell.impliedPortMapping.putAll(impliedPortMapping); + cell.envExtraPortMapping.putAll(envExtraPortMapping); + cell.hasPrsBlock = hasPrsBlock; + cell.prsBlockIsComplete = prsBlockIsComplete; + cell.hasSubcellsBlock = hasSubcellsBlock; + cell.subcellsBlockIsComplete = subcellsBlockIsComplete; + cell.hasSubtypesBlock = hasSubtypesBlock; + cell.inheritedCells.addAll(inheritedCells); + cell.instancePositions.putAll(instancePositions); + final BlockIterator bi = blocks.iterator(BlockInterface.DIRECTIVE); + if (bi.hasNext()) { + cell.blocks.iterator(BlockInterface.DIRECTIVE).add( + new DirectiveBlock((DirectiveBlock) bi.next())); + } + Namespace.addNamespace(cell.aliases, aliases); + + final String[] refineable = new String[] { BlockInterface.ASSERT, + BlockInterface.ENV, + BlockInterface.PRS, + BlockInterface.NETLIST, + BlockInterface.CSP }; + for (int i = 0; i < refineable.length; ++i) { + final BlockInterface oldBlock = + blocks.iterator(refineable[i]).next(); + final BlockInterface newBlock = + cell.blocks.iterator(refineable[i]).next(); + newBlock.refineFrom(oldBlock); + } + + cell.adoptDirective(this); + + // for all non-channel subcells, inline them if inline_subcell + // is specified for that subcell or if inline_subcell is + // specified for all cells and the inlining of that cell has + // not been overridden. + + final Map m = DirectiveUtils.getSubcellDirective(this, + DirectiveConstants.ROUTED, + DirectiveConstants.INSTANCE_TYPE); + + for (final Iterator i = getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final Boolean inlineSubcell = (Boolean) m.get(subcellName); + final boolean unrouted = + !CellUtils.isRouted(subcell) || + (inlineSubcell != null && !inlineSubcell.booleanValue()); + + if (!subcell.isChannel() && !subcell.isNode()) { + if (unrouted || complete) { + final CellInterface routedSubcell; + if (subcell instanceof CellImpl) { + routedSubcell = + ((CellImpl) subcell).routedSubcells(complete, + unrouted, + cache); + } else { + routedSubcell = subcell.routedSubcells(complete); + } + cell.subcellMap.put(subcellName, routedSubcell); + if (unrouted) { + try { + cell.inlineSubcell(subcellName, false, false); + } catch (NoSuchSubcellException x) { + throw new AssertionError(x); + } catch (SubcellCreationException x) { + throw new AssertionError(x); + } + } + } + } + } + + cache.put(getFullyQualifiedType(), cell); + return cell; + } + + public CellInterface sizingEnvSubcells(CellUtils.SizingEnvCreator creator) { + return sizingEnvSubcells(creator, true, false, new HashMap()); + } + + private CellInterface sizingEnvSubcells( + final CellUtils.SizingEnvCreator creator, + final boolean topLevel, + final boolean addSuffix, + final Map cache) { + if (CellUtils.isWiring(this)) return this; + + final CellInterface cached = + (CellInterface) cache.get(getFullyQualifiedType()); + if (cached != null) return cached; + + final Map modifiedSubcells = + new HashMap(); + + // Suppose we have: + // define A()() { subcells { inline B b; } } + // define B()() { subcells { C c; } } + // define C()() { csp { ... } } + // + // If we don't convert all cells, including inlined instances, the + // result we return, A', will reference B b, and C' b.c, but B still + // references C, and both C and C' have the same cell name. This + // causes a problem with Cadencize, because it looks at all subcells, + // including inlined ones, and also stores the result in a cache, keyed + // by the name of the cell. If Cadencize processes C before C', then + // the aliases in C' won't be visible. + for (final Iterator i = getAllSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + + if (!subcell.isChannel() && !subcell.isNode()) { + final CellInterface sizeable = + ((CellImpl) subcell).sizingEnvSubcells(creator, false, + addSuffix, cache); + if (sizeable != subcell) + modifiedSubcells.put(subcellName, sizeable); + } + } + + final CellInterface result; + final boolean internalEnv = CellUtils.isInternalEnv(this); + if (modifiedSubcells.isEmpty() && !internalEnv) { + result = this; + } else { + final CellImpl cell = + new CellImpl(type + (addSuffix ? "$SIZING" : ""), moduleName, + definitionKind, filename); + cell.refinementAncestor = refinementAncestor; + cell.directRefinementParent = directRefinementParent; + cell.subcellMap.putAll(subcellMap); + cell.subcellMap.putAll(modifiedSubcells); + cell.portSubcellSet.addAll(portSubcellSet); + cell.inlinedSubcellSet.addAll(inlinedSubcellSet); + cell.adoptedSet.addAll(adoptedSet); + cell.metaParamDefinitions.addAll(metaParamDefinitions); + cell.portDefinitions.putAll(portDefinitions); + cell.impliedPortMapping.putAll(impliedPortMapping); + cell.envExtraPortMapping.putAll(envExtraPortMapping); + cell.hasPrsBlock = hasPrsBlock; + cell.prsBlockIsComplete = prsBlockIsComplete; + cell.hasSubcellsBlock = hasSubcellsBlock; + cell.subcellsBlockIsComplete = subcellsBlockIsComplete; + cell.hasSubtypesBlock = hasSubtypesBlock; + cell.inheritedCells.addAll(inheritedCells); + cell.instancePositions.putAll(instancePositions); + final BlockIterator bi = blocks.iterator(BlockInterface.DIRECTIVE); + if (bi.hasNext()) { + cell.blocks.iterator(BlockInterface.DIRECTIVE).add( + new DirectiveBlock((DirectiveBlock) bi.next())); + } + Namespace.addNamespace(cell.aliases, aliases); + + final String[] refineable = new String[] { BlockInterface.ASSERT, + BlockInterface.ENV, + BlockInterface.PRS, + BlockInterface.NETLIST, + BlockInterface.CSP }; + for (int i = 0; i < refineable.length; ++i) { + final BlockInterface oldBlock = + blocks.iterator(refineable[i]).next(); + final BlockInterface newBlock = + cell.blocks.iterator(refineable[i]).next(); + newBlock.refineFrom(oldBlock); + } + + cell.adoptDirective(this); + if (internalEnv) { + final AliasedSet/**/ sizingAliases = + new AliasedSet/**/(HierName.getComparator()); + final Map sizingSubcells = + new HashMap(); + creator.getInternalEnv(cell, sizingAliases, sizingSubcells); + if (!sizingSubcells.isEmpty()) { + cell.setHasCompleteSubcellsBlock(); + cell.subcellMap.putAll(sizingSubcells); + Namespace.addNamespace(cell.aliases, sizingAliases); + } + } + result = cell; + } + + cache.put(getFullyQualifiedType(), result); + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellInterface.java new file mode 100644 index 0000000000..0c963ae3a3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellInterface.java @@ -0,0 +1,500 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +import java.util.Iterator; + + +import com.avlsi.csp.ast.CSPProgram; +import com.avlsi.csp.csp2java.runtime.CspSnoopingInterface; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.fast.EnvBlock; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.metaparameters.MetaParamDefinition; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.common.HierName; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.cosim.CoSimInfo; +import com.avlsi.tools.cosim.ChannelDictionary; +import com.avlsi.tools.cosim.CSPCoSimInfo; +import com.avlsi.tools.cosim.DeviceConstructionException; +import com.avlsi.tools.cosim.JavaCoSimInfo; + +/** + * Data structure for instantiated cells. Contains all the information a + * CAST file does, in a form that is easy to use. (The information isn't + * all there yet. HSE and CSP haven't been formalized, so they are not + * present.) The following information is present: + *

      + *
    • The cell type + *
    • Names of subcells, and their CellInterface instance. + *
    • The list of canonical nodes for the cell. + *
    • The list of nodes that are connected to each canonical node. + *
    • The list of connections between canonical nodes and nodes + * in subcells. + *
    • The production rule set (PRS). + *
    + *

    + * The CellInterface also can be flattened. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public interface CellInterface extends HierarchyInterface { + /** + * The type of the cell ie "FULLADDER". Does not return the + * fully-qualified name ever. If the cell has metaparameters, the + * metaparameters are included in the type (i.e., "SLACK_1of4(7)") + * + **/ + String getType(); + + + /** + * Return the path of the file which defines this cell (never + * null) + **/ + String getFilename(); + + /** + * Returns the fully qualified type name of the cell, ie + * "lib.math.add.FULLADDER". + **/ + String getFullyQualifiedType(); + + /** + * Returns true if this cell was defined with a defchan rather than a + * define. + **/ + boolean isChannel(); + + /** + * Returns true if this cell type is a node. + **/ + boolean isNode(); + + /** + * Returns true if this cell type is an alias. + **/ + boolean isAlias(); + + // + // + // Subcells + // + // + + /** + * Returns an Iterator of HierNames of the subcell names. + **/ + Iterator/**/ getSubcellNames(); + + /** + * Get the CellInterface for a given subcell name. + **/ + CellInterface getSubcell(HierName name); + + /** + * Returns an Iterator of Pairs of HierName and CellInterface, + * including inlined subcells. + **/ + Iterator/*>*/ getAllSubcellPairs(); + + /** + * Returns an Iterator of Pairs of HierName and CellInterface, + * excluding inlined subcells. + **/ + Iterator/*>*/ getSubcellPairs(); + + /** + * Returns an Iterator of Pairs of HierName and CellInterface + * that are port subcells, excluding inlined subcells. + **/ + Iterator/*>*/ getPortSubcellPairs(); + + /** + * Returns an Iterator of Pairs of HierName and CellInterface + * that are local subcells, excluding inlined subcells. + **/ + Iterator/*>*/ getLocalSubcellPairs(); + + boolean isPortSubcell(final HierName n); + + boolean isInlinedSubcell(final HierName n); + + /** + * Subcell 'n' is instantiated by some other subcell that + * is inlined. + **/ + boolean parentIsInlinedSubcell(final HierName n); + + /** @see CellImpl.autoInline **/ + void setAutoInline(boolean autoInline); + + /** @see CellImpl.autoInline **/ + boolean isAutoInline(); + + /** Returns an Iterator of {@link + * com.avlsi.fast.metaparameters.MetaParamDefinition}s, representing the + * channels declared in the metaparameter list. + * + * @return iterator of metaparameter definitions, not null + **/ + Iterator/**/ getMetaParamDefinitions(); + + /** + * Returns an Iterator of {@link com.avlsi.fast.ports.PortDefinition}s, + * representing the channels declared in the port list. + * + * @return iterator of port channel definitions, not null + **/ + Iterator getPortDefinitions(); + + /** + * Returns true if the named port is an implied port; false otherwise. + **/ + boolean isImpliedPort(String name); + + // + // + // Nodes / connections + // + // + + /** + * Returns an Iterator of HierNames of the canonical names in the cell. + * The canonical names are those names that are not connected to any + * other canonical names, and are lexicographically less than + * the nodes that they are connected to. + **/ + Iterator/**/ getCanonicalNodes(); + + /** + * Returns an iterator through all nodes connected to the given node. + **/ + Iterator/**/ getConnectedNodes(HierName nodeName); + + /** + * The canonical name of the given node. + **/ + HierName/**/ getCanonicalName(HierName nodeName); + + // + // + // PRS + // + // + + /** + * Return the synthesizable production rule set (PRS) specified by + * the cell. + **/ + ProductionRuleSet getProductionRuleSet(); + + /** + * Return the production rule set specified in the prs-env block + * (old cast) or assert block (new cast). These production rules + * are used in simulation but not to produce transistors. + **/ + ProductionRuleSet getAssertedProductionRuleSet(); + + // + // + // Java block + // + // + + /** + * Return the cosimulation inforamation from the Java block + **/ + JavaCoSimInfo getJavaCoSimInfo(); + + /** + * Fills in the cosimulation information from the port list. May be + * called more than once with no adverse effect. + **/ + void setCoSimInfoFromPorts(CoSimInfo cosimInfo); + + /** + * Build the CSP class for this cell + **/ + void buildCSPClass(HierName cellName, ChannelDictionary dict, + int arbitrationMode, boolean emitCoverageProbes) + throws ClassNotFoundException, InstantiationException; + + /** + * Build the CSP class for this cell + **/ + void buildCSPClass(HierName cellName, ChannelDictionary dict, + int arbitrationMode, boolean emitCoverageProbes, long seed) + throws ClassNotFoundException, InstantiationException; + + /** + * Build the CSP class for this cell + **/ + void buildCSPClass(HierName cellName, ChannelDictionary dict, + int arbitrationMode, boolean emitCoverageProbes, long seed, + float digitalTau) + throws ClassNotFoundException, InstantiationException; + + /** + * Build the CSP class for this cell + **/ + void buildCSPClass(HierName cellName, ChannelDictionary dict, + int arbitrationMode, boolean emitCoverageProbes, + CspSnoopingInterface cspSnooper) + throws ClassNotFoundException, InstantiationException; + + /** + * Build the java class for this cell + **/ + void buildJavaClass(HierName cellName, + ChannelDictionary dict, + ClassLoader aLoader, + int arbitrationMode) + throws ClassNotFoundException, InstantiationException, + DeviceConstructionException; + + // + // + // CSP stuff + // + // + + /** Return the cosimulation info from the csp block. **/ + CSPCoSimInfo getCSPCoSimInfo(); + + /** + * Returns as much non-csp info about the cell as the csp + * processing is going to need (ports/metas information). + **/ + CSPCellInfo getCSPInfo(); + + /** + * Returns the CSP body, or null if none. + **/ + CSPProgram getCSPProgram(); + + // + // + // Spec stuff: exclhi/excllo + // + // + + /** + * Returns an Iterator of ExclusiveNodeSet telling which nodes + * can never be high (or low) at the same time. + * + * Does not contain information from any ports, subcells, etc. + * Use the cadencizer to get that information. + **/ + ExclusiveNodeSets getLocalExclusiveNodeSets(); + + // + // + // Flatten + // + // + + /** + * Returns a flattened version of the cell. The flattened version + * has no subcells. + * + * @param maxPrsDepth the maximum depth from which production rules + * should be imported. Zero means only the current cell. + * Negative means none at all. + **/ + CellInterface flatten(int maxPrsDepth); + + /** + * Returns a flattened version of the cell. The flattened version + * has no subcells. Equivalent to flatten(Integer.MAX_VALUE). + **/ + CellInterface flatten(); + + // + // + // Env block + // + // + + /** + * Returns the environment block, from which environments in + * instantiatable form may be requested by name. + **/ + EnvBlock getEnvironments(); + + // + // + // Misc + // + // + + /** + * Returns true if this cell and c have the same port list and + * share an ancestor with that port list. + **/ + boolean sameRefinementAncestor(CellInterface c); + + /** + * Returns true if this is cell or refined from cell or refined from a + * CellInterface which is refined from cell or .... + **/ + boolean eventuallyRefinesFrom(CellInterface cell); + + /** + * Returns true if all of this cell's port subcells refine from + * this defchan cell. Port defchan subcells are traversed until either + * nodes or a subcell that refines from parentChannel is encounted. + * When parentChannel is standard.e1of, this method indicates + * whether this cell communicates with its environment in a fully + * four-phase asynchronous manner (and is presumably DI). + **/ + boolean allPortSubcellsRefineFrom(final CellInterface parentChannel); + + /** + * Return the cosimulation info that matches the specified + * behavior. Gives precedence to java block over csp block. + **/ + CoSimInfo getCoSimInfo(int cosimBehavior); + + /** + * Returns true if this cell or any of its subcells have non- + * env production rules. + **/ + boolean hasRealProductionRule(); + + /** + * Returns true if this cell or any of its subcells contains a netlist + * block. + **/ + boolean hasNetlistBody(); + + /** + * Returns true if this cell or any of its subcells contains a Verilog + * block. + **/ + boolean hasVerilog(); + + /** + * Returns true if this cell or any of its subcells contains runnable CSP. + **/ + boolean hasRunnableCsp(); + + /** + * Return an BlockInterface view of this cell. + **/ + BlockInterface getBlockInterface(); + + /** + * Returns the module the cell was defined in, which uniquely + * specifies the file the cell definition can be found in. + **/ + String getModuleName(); + + /** + * Return the direct refinement parent for a give cell, we can follow + * use this to trace a cell all the way to CELL + */ + CellInterface getDirectRefinementParent(); + + /** + * Returns true if the cell has a complete (non-fragment) prs block. + **/ + boolean containsCompletePrs(); + + /** + * Returns true if the cell has a complete (non-fragment) subcells block. + **/ + boolean containsCompleteSubcells(); + + /** + * Returns true if the cell has a java block. + **/ + boolean containsJava(); + + /** + * Returns true if the cell has a csp block. + **/ + boolean containsCsp(); + + /** + * Returns true if the cell has sequential CSP statements (as opposed to + * only containing function and structure declarations). + **/ + boolean containsRunnableCsp(); + + /** + * Returns true if the cell has a subcells block. + **/ + boolean containsSubcells(); + + /** + * Returns true if the cell has a netlist block. + **/ + boolean containsNetlist(); + + /** + * Returns true if the cell has a Verilog block. + **/ + boolean containsVerilog(); + + /** + * Returns the cell for the named environment envName. + * @throws NoSuchEnvironmentException If no environment with + * that name could be found. + **/ + CellInterface getEnvironment(String envName) + throws NoSuchEnvironmentException; + + /** + * Returns a new CellInterface, but with any subcells + * inlined that have the inline_layout directive set. + * The cell only has the information needed to lvs, it is not a complete + * copy. + **/ + CellInterface inlineLayoutSubcells(); + + /** + * Returns an iterator of attribute cells that this cell inherited. The + * order of the cells returned by iterator are the same as reading the + * attribute cells from left to right in CAST. In other words, the first + * CellInterface returned is the most overriding. + **/ + Iterator/**/ getInheritedCells(); + + /** + * Returns the name that the implied port self must connect to + * in a cell that instantiates this cell. + **/ + String getParentImpliedPort(String self); + + /** + * Returns the name that the environment extra port self must + * connect to in the DUT. + **/ + String getEnvExtraPortMapping(String self); + + /** + * Returns a CellInterface that is the same as this cell, but + * inlining any subcells necessary according to the routed + * directive. The cell only has the information needed to lvs, it is not a + * complete copy. + * + * @param complete false if flattening according to routed + * directive should be processed only one level; true if all + * routed directive should be processed + **/ + CellInterface routedSubcells(boolean complete); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellUtils.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellUtils.java new file mode 100644 index 0000000000..18820e039d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/CellUtils.java @@ -0,0 +1,2010 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cell; + +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.cdl.parser.CDLFactoryAdaptor; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.ports.*; +import com.avlsi.fast.metaparameters.*; +import com.avlsi.io.FileSearchPath; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.NaturalOrderComparator; +import com.avlsi.util.container.ObjectUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.NaturalStringComparator; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.util.text.StringUtil; + +/** + * Some useful utilities that doesn't really belong in CellInterface. + **/ +public final class CellUtils { + /** + * This class should not be instantiated. + **/ + private CellUtils() { } + + public static boolean isWiring(final CellInterface cell) { + if (cell.isNode() || cell.isChannel()) return true; + + if (cell.containsNetlist() || cell.containsVerilog()) return false; + + if (cell.containsCompletePrs() || cell.containsCompleteSubcells()) { + if (cell.hasRealProductionRule()) return false; + + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (!isWiring(subcell)) return false; + } + return true; + } else { + return !cell.containsRunnableCsp(); + } + } + + public static boolean isLeaf(final CellInterface cell) { + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair pair = (Pair) i.next(); + final CellInterface subcell = (CellInterface) pair.getSecond(); + if (!isWiring(subcell)) return false; + } + return true; + } + + public static boolean isSplittable(final CellInterface cell) { + final Boolean splittable = (Boolean) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.SPLITTABLE); + return splittable.booleanValue(); + } + + public static boolean isFixed(final CellInterface cell) { + return ((Boolean) DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.FIXED_SIZE)).booleanValue(); + } + + public static boolean isFixedSize(final CellInterface cell) { + return isFixed(cell) && cell.containsNetlist(); + } + + public static Boolean isRouted(final CellInterface cell, + final Boolean def) { + final Boolean routed = (Boolean) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.ROUTED); + return routed == null ? def : routed; + } + + public static boolean isRouted(final CellInterface cell) { + final Boolean routed = isRouted(cell, null); + return routed == null ? isLeaf(cell) : routed.booleanValue(); + } + + public static boolean isAstaBlackbox(final CellInterface cell) { + Boolean bbox = (Boolean) DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.ASTA_BLACKBOX); + return bbox == null ? false : bbox; + } + + public static boolean isAstaGraybox(final CellInterface cell) { + Boolean gbox = (Boolean) DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.ASTA_GRAYBOX); + return gbox == null ? false : gbox; + } + + public static boolean isDftChannel(final String type) { + return type.equals("lib.serial.scan.ChanDft") || + type.equals("deprecated.lib.serial.scan.ChanDft") || + type.equals("lib.dft.channel.ChanDft"); + } + + public static boolean isDftChannel(final CellInterface cell, + final String type) { + return isDftChannel(type) && + !((Boolean) DirectiveUtils.getCspDirective( + cell, DirectiveConstants.DISABLE_CHANDFT_HANDLER)).booleanValue(); + } + + public static boolean isSramSerialChannel(final String type) { + return type.equals("lib.sram.6T.channel.SramSerialChannel") || + type.equals("deprecated.lib.6T.channel.SramSerialChannel"); + } + + public static final String[] OLD_DFT_NODES = + new String[] { "e", "d[0]", "d[1]", "d[2]" }; + + public static final String[] NEW_DFT_NODES = + new String[] { "C[0]", "C[1]", "C[2]", "C[3]", + "D.e", "D.d[0]", "D.d[1]" }; + + public static CellInterface loadCell(final String castPath, + final String cellName, + final String castVersion) + throws CastSyntaxException, CastSemanticException, IOException { + final CastFileParser castParser = + new CastFileParser(new FileSearchPath(castPath), castVersion); + return castParser.getFullyQualifiedCell(cellName); + } + + /** + * Checks if a cell refines directly from a cell that has the same name, up + * to the last dot, i.e., returns true if A.B.C.D refines directly from + * A.B.C. + **/ + public static boolean isSubtype(final CellInterface cell) { + final CellInterface parent = cell.getDirectRefinementParent(); + return cell.getModuleName().equals(parent.getFullyQualifiedType()); + } + + public static boolean isInternalEnv(final CellInterface cell) { + return isLeaf(cell) && !cell.containsCompletePrs() && + !cell.containsCompleteSubcells() && + !cell.containsNetlist(); + } + + + private static Integer FORWARD = new Integer(PortDefinition.FORWARD); + private static Integer REVERSE = new Integer(PortDefinition.REVERSE); + private static Integer BIDIRECTIONAL = new Integer(PortDefinition.BIDIRECTIONAL); + + /** + * Return a map of all ports in the given cell in order (as specified in + * CAST), and their directionality. The names of the ports are Strings, + * and if converted to HierNames, are compatible with names used by + * Cadencize, which must be used to find all alias information. + **/ + public static Map markPorts(final CellInterface ci) { + return markPorts(ci.getPortDefinitions()); + } + + public static Map markPorts( + final Iterator portDefinitions) { + final Map result = new LinkedHashMap(); + (new MarkPort() { + protected void mark(final NodeType nodeType, final String name, + final int direction) { + if (direction < 0) { + result.put(name, REVERSE); + } else if (direction == 0) { + result.put(name, BIDIRECTIONAL); + } else { + result.put(name, FORWARD); + } + } + }).mark(portDefinitions); + return result; + } + + public static class MarkPort { + public void mark(final CellInterface ci) { + mark(ci.getPortDefinitions()); + } + + public void mark(final Iterator portDefinitions) { + mark(portDefinitions, null); + } + + public void mark(final Iterator portDefinitions, + final String prefix) { + mark(portDefinitions, prefix, PortDefinition.FORWARD); + } + + public void mark(final Iterator portDefinitions, + final String prefix, final int direction) { + while (portDefinitions.hasNext()) { + final PortDefinition p = portDefinitions.next(); + mark(p, prefix, direction); + } + } + + protected void mark(final PortDefinition p, final String prefix, + int direction) { + assert p.getDirection() == PortDefinition.FORWARD || + p.getDirection() == PortDefinition.REVERSE || + p.getDirection() == PortDefinition.BIDIRECTIONAL || + p.getDirection() == PortDefinition.NONE; + + // XXX: Use PortDefinition.getReverseDirection() instead + if (p.getDirection() == PortDefinition.REVERSE) + direction = -direction; + else if (p.getDirection() == PortDefinition.BIDIRECTIONAL || + p.getDirection() == PortDefinition.NONE) + direction = 0; + + final String name; + if (prefix == null) + name = p.getName(); + else + name = prefix + '.' + p.getName(); + + mark(p.getType(), name, direction, false); + } + + // ChannelType ------------------------------------------------------ + protected void mark(final ChannelType channelType, final String name, + final int direction, final boolean inArray) { + final String newName = + arrayName(channelType, name, inArray, channelType.isArrayed()); + if (channelType.isArrayed()) { + final int width = channelType.getWidth(); + assert width > 0 : "Invalid width: " + width + " ChannelType = " + channelType; + mark(channelType, newName, direction, width); + } else { + mark(channelType, newName, direction); + } + } + + protected void mark(final ChannelType channelType, final String name, + final int direction) { + mark(channelType.iterator(), name, direction); + } + + protected void mark(final ChannelType channelType, final String name, + final int direction, final int width) { + for (int i = 0; i < width; ++i) { + mark(channelType, name + i + "]", direction); + } + } + + // StructureType ------------------------------------------------------ + protected void mark(final StructureType structureType, + final String name, final int direction, + final boolean inArray) { + mark(structureType, arrayName(structureType, name, inArray, false), + direction); + } + + protected void mark(final StructureType structureType, + final String name, final int direction) { + mark(structureType.iterator(), name, direction); + } + + // ArrayType ------------------------------------------------------ + protected void mark(final ArrayType arrayType, final String name, + final int direction, final boolean inArray) { + mark(arrayType, arrayName(arrayType, name, inArray), direction); + } + + protected void mark(final ArrayType arrayType, final String name, + final int direction) { + final int min = arrayType.getMinIndex(); + final int max = arrayType.getMaxIndex(); + + final PortTypeInterface arrayedType = arrayType.getArrayedType(); + for (int i = min; i <= max; ++i) { + mark(arrayedType, name + i, direction, true); + } + } + + // NodeType ------------------------------------------------------ + protected void mark(final NodeType nodeType, final String name, + final int direction, final boolean inArray) { + final String newName = + arrayName(nodeType, name, inArray, nodeType.isArrayed()); + if (nodeType.isArrayed()) { + final int width = nodeType.getWidth(); + assert width > 0 : "Invalid width: " + width + " NodeType = " + nodeType; + mark(nodeType, newName, direction, width); + } else { + mark(nodeType, newName, direction); + } + } + + protected void mark(final NodeType nodeType, final String name, + final int direction) { + /* Default does nothing */ + } + + protected void mark(final NodeType nodeType, final String name, + final int direction, final int width) { + for (int i = 0; i < width; ++i) { + mark(nodeType, name + i + "]", direction); + } + } + + protected String arrayName(final PortTypeInterface t, + final String name, + final boolean inArray, + final boolean isArrayed) { + return isArrayed ? name + (inArray ? "," : "[") + : inArray ? name + "]" : name; + } + + protected String arrayName(final ArrayType t, + final String name, + final boolean inArray) { + return name + (inArray ? "," : "["); + } + + protected void mark(final PortTypeInterface t, final String name, + final int direction, final boolean inArray) { + + if (t instanceof ChannelType) { + mark((ChannelType) t, name, direction, inArray); + } else if (t instanceof StructureType) { + mark((StructureType) t, name, direction, inArray); + } else if (t instanceof ArrayType) { + mark((ArrayType) t, name, direction, inArray); + } else if (t instanceof NodeType) { + mark((NodeType) t, name, direction, inArray); + } else { + throw new AssertionError("Unknown PortTypeInterface: " + t); + } + } + } + + /** + * Given a cell, return a new cell containing the given cell, and the + * specified environment cell, with the ports between them correctly + * connected. For example, + *

    +     * define A()(e1of1 +a; node -b) {
    +     *   ...
    +     *   env {
    +     *     digital {
    +     *       ...
    +     *     }
    +     *   }
    +     * }
    +     * 
    + * getEnvWithCell(A, "digital", "newA", "myEnv", "myA") + * would return a cell that looks something like: + *
    +     * define newA()() {
    +     *   subcells {
    +     *     myA A;
    +     *     myEnv A:digital;  // In CAST, you can't refer to the digital env
    +     *     myA.a.d = myEnv.a.d;
    +     *     myA.a.e = myEnv.a.e;
    +     *     myA.b = myEnv.b;
    +     *   }
    +     * }
    +     * 
    + * + * @param cell Cell to process + * @param envName Name of the environment + * @param newName Name of the newly constructed cell + * @param envInstance Name of the environment instance in the new cell + * @param cellInstance Name of the cell instance in the new + * cell + * + * @return a cell containing an instance of cell, and an + * instance of the environment cell with name envName. + **/ + public static CellImpl getEnvWithCell(final CellInterface cell, + final String envName, + final String newName, + final String envInstance, + final String cellInstance) + throws NoSuchEnvironmentException { + try { + return getEnvWithCell(cell, envName, newName, + HierName.makeHierName(envInstance, '.'), + HierName.makeHierName(cellInstance, '.')); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName"); + } + } + + public static CellImpl getEnvWithCell(final CellInterface cell, + final String envName, + final String newName, + final HierName envInstance, + final HierName cellInstance) + throws NoSuchEnvironmentException { + final CellInterface env = cell.getEnvironment(envName); + final CellImpl result = new CellImpl(newName, cell.getModuleName(), + CellImpl.SYNTHETIC_CELL); + result.setHasCompleteSubcellsBlock(); + result.addSubcellPair(envInstance, env, false); + result.addSubcellPair(cellInstance, cell, false); + + final Map ports = markPorts(cell); + for (Iterator i = ports.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String s = (String) entry.getKey(); + final HierName port; + try { + port = HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName: " + s); + } + result.addConnection(HierName.append(envInstance, port), + HierName.append(cellInstance, port)); + } + return result; + } + + /** + * Given a cell type, returns a type that does not contain any + * meta-parameters. + * + * @param type Cell type to process. + * @return If type has metaparameters, return the base type + * without metaparameters; otherwise return type. + **/ + public static String getBaseType(final String type) { + if (type.endsWith(")")) { + final int lparen = type.lastIndexOf('('); + if (lparen > 0) { + return type.substring(0, lparen); + } + } + return type; + } + + /** + * Calculate the hash of a string using a given digest algorithm, and + * return the hash as a hex string. + **/ + private static String hash(final String s, final String algorithm) + throws NoSuchAlgorithmException { + final MessageDigest hash = MessageDigest.getInstance(algorithm); + return NumberFormatter.toHexString(hash.digest(s.getBytes())); + } + + /** + * Return the MD5 hash of a string. + **/ + private static String md5(final String s) { + try { + return hash(s, "MD5"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + /** + * If a cell name has a meta parameter list (the string in between the + * first "(" and the last ")") that's longer than the specified number of + * characters, replace it with a MD5 sum. + **/ + public static String hashMetaParameters(final String name, + final int length) { + final int first = name.indexOf('('); + final int last = name.lastIndexOf(')'); + if (first < 0 || last < 0 || last - first < length) return name; + final String byteString = md5(name.substring(first + 1, last)); + return name.substring(0, first) + + "_" + byteString + + name.substring(last + 1); + } + + public static String hashMetaParameters(final String name) { + return hashMetaParameters(name, 128); + } + + /** + * Regular expression for extracting the transistor type from a process + * indepedent transistor name. + **/ + private final static Pattern TRANSISTOR_TYPE_PATTERN = + Pattern.compile("([NP])\\[(\\d+)\\]"); + + /** + * Given a transistor model name, attempt to extract the type. A valid + * model name matches the regular expression "[NP]\[\d+\]". + * + * @param type name of the transistor model + * @return type of the transistor, as an Integer. Or null if it is not a + * valid model name. + **/ + public static Integer extractTransistorNumber(final String type) { + final Matcher m = TRANSISTOR_TYPE_PATTERN.matcher(type); + return m.matches() ? + new Integer((m.group(1).equals("N") ? "-" : "") + m.group(2)) : + null; + } + + /** + * Given a process independent transistor model name, return a process + * dependent transistor model name. It extracts the transistor type from + * the model name, and looks up the type in the translation table defined + * by the transistor_name directive. + * + * @param cell cell where the transistor is located in + * @param model process independent model name + * @return process dependent model name if a valid translation exists, or + * model. + **/ + public static String getTransistorModelName(final CellInterface cell, + final String model) { + final Map names = DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.TRANSISTOR_NAME, + DirectiveConstants.INT_TYPE); + return getTransistorModelName(names, model); + } + + /** + * Given a process independent transistor names, and a translation table, + * return the process dependent transistor name. + * + * @param names mapping from process independent transistor type to process + * dependent name + * @param model process indepedent transistor name + * @return process dependent transistor name if a mapping exists in + * names, otherwise return model. + **/ + public static String getTransistorModelName(final Map names, + final String model) { + final Integer type = extractTransistorNumber(model); + final String name = type == null ? null : (String) names.get(type); + return name == null ? model : name; + } + + /** + * Returns N from a string of the form standard.channel.e1ofN, or + * standard.channel.e1of(N). + * + * @return the number of data rails, or -1 if the channel type does not + * begin with standard.channel.e1of. + * @throws NumberFormatException if N cannot be parsed as an integer + **/ + public static int extractN(final String channelType) { + final String e1of = "standard.channel.e1of"; + if (!channelType.startsWith(e1of)) return -1; + String remainder = channelType.substring(e1of.length()); + remainder = remainder.replace('(', ' '); + remainder = remainder.replace(')', ' '); + remainder = remainder.trim(); + + return Integer.parseInt(remainder); + } + + private static HierName toHier(final String s) { + try { + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName from " + s, e); + } + } + + private static HierName toHierOrNull(final String s) { + return s == null ? null : toHier(s); + } + + public static class Channel implements Comparable { + private final HierName instance; + private final String name; + private final PortTypeInterface type; + private final Channel parent; + private final int index; + private final int group; + private final int direction; + private final List children; + public Channel(final HierName instance, final String name, + final Channel parent, final PortTypeInterface type, + final int index, final int group, final int direction) { + this.instance = instance; + this.name = name; + this.type = type; + this.parent = parent; + if (parent != null) parent.addChildren(this); + this.index = index; + this.group = group; + this.direction = direction; + this.children = new ArrayList(); + } + public Channel(final HierName instance, final String name, + final Channel parent, final PortTypeInterface type, + final int index, final int direction) { + this(instance, name, parent, type, index, -1, direction); + } + public HierName getInstance() { + return instance; + } + public String getName() { + return name; + } + public String getFullName() { + return (instance == null ? "" : instance + ".") + name; + } + public PortTypeInterface getType() { + return type; + } + public int getDirection() { + return direction; + } + public Channel getParent() { + return parent; + } + public int getIndex() { + return index; + } + public int getGroup() { + return group; + } + private void addChildren(final Channel child) { + children.add(child); + } + public Collection getChildren() { + return Collections.unmodifiableList(children); + } + private int realDirection() { + return getInstance() == null ? -getDirection() : getDirection(); + } + public boolean isInput() { + return realDirection() < 0; + } + public boolean isOutput() { + return realDirection() > 0; + } + public boolean isBidirectional() { + return realDirection() == 0; + } + public int compareTo(final Object other) { + final Channel o = (Channel) other; + int x = ObjectUtils.compare(getInstance(), o.getInstance()); + return x == 0 ? ObjectUtils.compare(getName(), o.getName()) : x; + } + public boolean equals(final Object other) { + if (other instanceof Channel) { + final Channel o = (Channel) other; + return ObjectUtils.equals(getInstance(), o.getInstance()) && + getName().equals(o.getName()); + } else { + return false; + } + } + public int hashCode() { + return ObjectUtils.hashCode(getInstance()) + getName().hashCode(); + } + public String toString() { + return "instance: " + instance + " name: " + name + " type: " + type + " parent: [" + parent + "] index: " + index + " direction: " + direction + " group: " + group; + } + } + + public static class ChannelCreator extends MarkPort { + private static ChannelType deArray(final ChannelType t) { + return t.isArrayed() ? + new ChannelType(t.iterator(), t.getTypeName()) : t; + } + + private static NodeType deArray(final NodeType t) { + return t.isArrayed() ? new NodeType() : t; + } + + protected Channel wide, narrow, node; + private int nodeIndex; + protected final HierName instance; + private Channel result; + public ChannelCreator(final HierName instance) { + this.instance = instance; + this.wide = null; + this.narrow = null; + this.nodeIndex = -1; + this.result = null; + } + protected void mark(final ChannelType channelType, final String name, + final int direction, final boolean inArray) { + if (channelType.isArrayed()) { + wide = + new Channel(instance, + arrayName(channelType, name, inArray, false), + null, channelType, -1, direction); + setResult(wide); + } + super.mark(channelType, name, direction, inArray); + wide = null; + } + protected void mark(final ChannelType channelType, final String name, + final int direction) { + if (narrow == null) { + narrow = new Channel(instance, name, wide, + deArray(channelType), -1, direction); + setResult(narrow); + } + nodeIndex = 0; + for (Iterator i = channelType.iterator(); i.hasNext(); ++nodeIndex) + { + final PortDefinition p = (PortDefinition) i.next(); + mark(p, name, direction); + } + nodeIndex = -1; + narrow = null; + } + protected void mark(final ChannelType channelType, final String name, + final int direction, final int width) { + for (int i = 0; i < width; ++i) { + narrow = new Channel(instance, name + i + "]", wide, + deArray(channelType), i, direction); + setResult(narrow); + mark(channelType, name + i + "]", direction); + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction, final boolean inArray) { + final boolean alone = narrow == null && nodeType.isArrayed(); + if (alone) { + narrow = + new Channel(instance, + arrayName(nodeType, name, inArray, false), + null, nodeType, -1, direction); + setResult(narrow); + nodeIndex = 0; + } + super.mark(nodeType, name, direction, inArray); + if (alone) { + narrow = null; + nodeIndex = -1; + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction, final int width) { + for (int i = 0; i < width; ++i) { + mark(nodeType, name + i + "]", direction); + if (nodeIndex >= 0) ++nodeIndex; + } + if (nodeIndex >= 0) --nodeIndex; + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + final int group = narrow == null ? -1 + : name.endsWith(".e") ? 0 + : 1; + node = new Channel(instance, name, narrow, deArray(nodeType), + nodeIndex, group, direction); + setResult(node); + } + protected void setResult(final Channel c) { + if (result == null) result = c; + } + public Channel getResult() { + return result; + } + } + + private static class ChannelConnection extends MarkPort { + private static ChannelType deArray(final ChannelType t) { + return t.isArrayed() ? + new ChannelType(t.iterator(), t.getTypeName()) : t; + } + + private static NodeType deArray(final NodeType t) { + return t.isArrayed() ? new NodeType() : t; + } + + private Channel wide, narrow; + private boolean realNarrow; + private int nodeIndex; + private final MultiMap nodeChannel; + private final HierName instance; + private final AliasedSet aliases; + public ChannelConnection(final MultiMap nodeChannel, + final HierName instance, + final AliasedSet aliases) { + this.nodeChannel = nodeChannel; + this.instance = instance; + this.wide = null; + this.narrow = null; + this.realNarrow = false; + this.nodeIndex = -1; + this.aliases = aliases; + } + protected void mark(final ChannelType channelType, final String name, + final int direction, final boolean inArray) { + if (channelType.isArrayed()) + wide = + new Channel(instance, + arrayName(channelType, name, inArray, false), + null, channelType, -1, direction); + super.mark(channelType, name, direction, inArray); + wide = null; + } + protected void mark(final ChannelType channelType, final String name, + final int direction) { + if (narrow == null) + narrow = new Channel(instance, name, wide, + deArray(channelType), -1, direction); + realNarrow = true; + nodeIndex = 0; + for (Iterator i = channelType.iterator(); i.hasNext(); ++nodeIndex) + { + final PortDefinition p = (PortDefinition) i.next(); + mark(p, name, direction); + } + nodeIndex = -1; + narrow = null; + realNarrow = false; + } + protected void mark(final ChannelType channelType, final String name, + final int direction, final int width) { + for (int i = 0; i < width; ++i) { + narrow = new Channel(instance, name + i + "]", wide, + deArray(channelType), i, direction); + mark(channelType, name + i + "]", direction); + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction, final boolean inArray) { + final boolean alone = narrow == null && nodeType.isArrayed(); + if (alone) { + narrow = + new Channel(instance, + arrayName(nodeType, name, inArray, false), + null, nodeType, -1, direction); + nodeIndex = 0; + } + super.mark(nodeType, name, direction, inArray); + if (alone) { + narrow = null; + nodeIndex = -1; + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction, final int width) { + for (int i = 0; i < width; ++i) { + mark(nodeType, name + i + "]", direction); + if (nodeIndex >= 0) ++nodeIndex; + } + if (nodeIndex >= 0) --nodeIndex; + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + final int group = realNarrow ? name.endsWith(".e") ? 0 : 1 + : -1; + final Channel node = + new Channel(instance, name, narrow, deArray(nodeType), + nodeIndex, group, direction); + + final HierName hier = HierName.prefixName(instance, toHier(name)); + final HierName canon = (HierName) aliases.getCanonicalKey(hier); + assert canon != null : "Cannot find canonical name for " + hier; + nodeChannel.put(canon, node); + } + } + + private static void groupChannel( + final AliasedSet/**/ connections, + final Collection/*>*/ parts, + final AliasedSet/**/ whole, + final boolean useGroup) { + + for (Iterator i = connections.getCanonicalKeys(); i.hasNext(); ) { + final Collection input = new HashSet(); + final Collection output = new HashSet(); + final Collection inout = new HashSet(); + final Collection childInput = new ArrayList(); + final Collection childOutput = new ArrayList(); + final Collection childInout = new ArrayList(); + final Object canon = i.next(); + for (Iterator j = connections.getAliases(canon); j.hasNext(); ) { + final Channel chan = (Channel) j.next(); + (chan.isInput() ? childInput : + (chan.isOutput() ? childOutput : childInout)).add(chan); + final Channel parent = chan.getParent(); + if (isChannelType(parent)) { + (parent.isInput() ? input : + (parent.isOutput() ? output : inout)).add(parent); + } + } + + // if there are inout channels, arbitrarily choose one as the + // source, and make the rest into sinks + for (Iterator j = childInout.iterator(); j.hasNext(); ) { + final Channel chan = (Channel) j.next(); + final Collection coll; + if (childOutput.isEmpty()) { + childOutput.add(chan); + coll = output; + } else { + childInput.add(chan); + coll = input; + } + + final Channel parent = chan.getParent(); + if (isChannelType(parent) && parent.isBidirectional()) { + coll.add(parent); + } + } + + for (Iterator j = output.iterator(); j.hasNext(); ) { + final Channel out = (Channel) j.next(); + for (Iterator k = input.iterator(); k.hasNext(); ) { + final Channel in = (Channel) k.next(); + + if (whole.areEquivalent(out, in) || + out.getChildren().size() != in.getChildren().size()) { + continue; + } + + boolean connected = true; + + if (useGroup) { + final Set outChildren = + new HashSet(out.getChildren()); + for (Channel inChild : in.getChildren()) { + boolean found = false; + for (Iterator l = outChildren.iterator(); + l.hasNext(); ) { + final Channel outChild = l.next(); + if (inChild.getGroup() == outChild.getGroup() && + connections.areEquivalent(inChild, + outChild)) { + found = true; + l.remove(); + break; + } + } + if (!found) { + connected = false; + break; + } + } + } else { + final Iterator outChildren = + out.getChildren().iterator(); + final Iterator inChildren = + in.getChildren().iterator(); + + while (outChildren.hasNext() && + inChildren.hasNext() && connected) { + final Channel outChild = outChildren.next(); + final Channel inChild = inChildren.next(); + connected = + connections.areEquivalent(outChild, inChild); + } + } + + if (connected) { + whole.makeEquivalent(out, in); + } + } + } + + if (parts != null) { + for (Iterator j = childOutput.iterator(); j.hasNext(); ) { + final Channel out = (Channel) j.next(); + final Channel outParent = out.getParent(); + for (Iterator k = childInput.iterator(); k.hasNext(); ) { + final Channel in = (Channel) k.next(); + final Channel inParent = in.getParent(); + if (outParent == null || inParent == null || + !whole.areEquivalent(outParent, inParent)) { + parts.add(new Pair(out, in)); + } + } + } + } + } + } + + public static Set getPortChannels(final CellInterface cell, + final boolean flatten, + final int parentLevels) { + return getPortChannels(cell, new Cadencize(false, true), flatten, + parentLevels); + } + + public static Set getPortChannels(final CellInterface cell, + final Cadencize cad, + final boolean flatten, + final int parentLevels) { + final MultiMap nodeChannel = new MultiMap(); + final AliasedSet locals = + cad.convertChannels(cell, Collections.EMPTY_MAP); + if (flatten) { + final AliasedMap ports = cad.convert(cell).getPortNodes(); + (new ChannelConnection(nodeChannel, null, locals)) + .mark(new FilteringIterator( + flattenPortDefinitionsNodes(cell.getPortDefinitions()), + new PrsFilterNodes(ports))); + } else { + (new ChannelConnection(nodeChannel, null, locals)).mark(cell); + } + + final Set results = new HashSet(); + for (Iterator i = nodeChannel.keySet().iterator(); i.hasNext(); ) { + for (Iterator j = nodeChannel.get(i.next()).iterator(); + j.hasNext(); ) { + Channel channel = (Channel) j.next(); + int level = 0; + for (int k = 0; k < parentLevels; ++k) { + final Channel parent = channel.getParent(); + if (parent == null) break; + else channel = parent; + } + results.add(channel); + } + } + + return results; + } + + /** + * Convert a subcell representing a channel into a port definition. + **/ + private static PortDefinition convertChannel(final CellInterface cell, + final HierName instance, + final int direction) { + final PortTypeInterface portType; + + if (cell.isNode()) { + portType = new NodeType(); + } else { + final String moduleName = cell.getModuleName(); + final String typeName = cell.getType(); + // XXX: same code appears in CastTwoTree.g; should refactor + if (moduleName.equals("standard.channel") && + typeName.substring(1).startsWith("1of")) { + portType = new ChannelType(cell.getPortDefinitions(), + cell.getFullyQualifiedType()); + } else { + portType = new StructureType(cell.getPortDefinitions(), + cell.getFullyQualifiedType()); + } + } + + return new PortDefinition(instance.getAsString('.'), portType, + direction); + } + + public static void getChannelConnection(final CellInterface cell, + final Collection nodeConnections, + final Collection narrowConnections, + final Collection wideConnections, + final Set nodeConverter, + final Set narrowConverter, + final Map flattenNodes) { + getChannelConnection(cell, nodeConnections, narrowConnections, + wideConnections, + new AliasedSet(new NaturalOrderComparator()), + new AliasedSet(new NaturalOrderComparator()), + new AliasedSet(new NaturalOrderComparator()), + nodeConverter, narrowConverter, flattenNodes, + false); + } + + private static boolean isChannelType(final Channel chan) { + return chan != null && chan.getType() instanceof ChannelType; + } + + private static class PrsFilterNodes implements UnaryPredicate { + // filter out ports that are not used + private final Set seen; + private final AliasedMap ports; + public PrsFilterNodes(final AliasedMap ports) { + this.seen = new HashSet(); + this.ports = ports; + } + public boolean evaluate(final Object o) { + final PortDefinition port = (PortDefinition) o; + final HierName hport = toHier(port.getName()); + final Boolean used = (Boolean) ports.getValue(hport); + return used.booleanValue() && + seen.add(new Pair(ports.getCanonicalKey(hport), + new Integer(port.getDirection()))); + } + } + + public static AliasedSet + getChannelConnection(final CellInterface cell, + final Collection nodeConnections, + final Collection narrowConnections, + final Collection wideConnections, + final AliasedSet nodeAliases, + final AliasedSet narrowAliases, + final AliasedSet wideAliases, + final Set nodeConverter, + final Set narrowConverter, + final Map flattenNodes, + final boolean internal) { + return getChannelConnection(cell, nodeConnections, narrowConnections, + wideConnections, nodeAliases, narrowAliases, wideAliases, + nodeConverter, narrowConverter, flattenNodes, internal, false); + } + + public static AliasedSet + getChannelConnection(final CellInterface cell, + final Collection nodeConnections, + final Collection narrowConnections, + final Collection wideConnections, + final AliasedSet nodeAliases, + final AliasedSet narrowAliases, + final AliasedSet wideAliases, + final Set nodeConverter, + final Set narrowConverter, + final Map flattenNodes, + final boolean internal, + final boolean allowTwist) { + return getChannelConnection(cell, nodeConnections, narrowConnections, + wideConnections, nodeAliases, narrowAliases, wideAliases, + nodeConverter, narrowConverter, flattenNodes, internal, + allowTwist, new Cadencize(false), null); + } + + public static AliasedSet + getChannelConnection(final CellInterface cell, + final Collection nodeConnections, + final Collection narrowConnections, + final Collection wideConnections, + final AliasedSet nodeAliases, + final AliasedSet narrowAliases, + final AliasedSet wideAliases, + final Set nodeConverter, + final Set narrowConverter, + final Map flattenNodes, + final boolean internal, + final boolean allowTwist, + final Cadencize cad, + // a "verilog aware" Cadencize + Cadencize vcad) { + final MultiMap nodeChannel = new MultiMap(); + final AliasedSet locals = cad.convertChannels(cell, flattenNodes); + (new ChannelConnection(nodeChannel, null, locals)).mark(cell); + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final HierName inst = (HierName) p.getFirst(); + if (subcell.isNode() || subcell.isChannel()) { + if (internal) + (new ChannelConnection(nodeChannel, null, locals)) + .mark(Collections.singletonList( + convertChannel(subcell, inst, + PortDefinition.IN)).iterator()); + } else { + if (flattenNodes.containsKey(inst)) { + final boolean prs = flattenNodes.get(inst) == Boolean.TRUE; + if (!prs || subcell.hasRealProductionRule()) { + // if verilog behavior, use "verilog aware" cadencize + final Cadencize realcad = prs ? cad : + (vcad == null ? (vcad = new Cadencize(false, true)) + : vcad); + final AliasedMap ports = + realcad.convert(subcell).getPortNodes(); + (new ChannelConnection(nodeChannel, inst, locals)) + .mark(new FilteringIterator( + flattenPortDefinitionsNodes( + subcell.getPortDefinitions()), + new PrsFilterNodes(ports))); + } + } else { + (new ChannelConnection(nodeChannel, inst, locals)) + .mark(subcell); + } + } + } + + for (Iterator i = nodeChannel.keySet().iterator(); i.hasNext(); ) { + final Iterator j = nodeChannel.get(i.next()).iterator(); + final Object first = j.next(); + nodeAliases.add(first); + while (j.hasNext()) { + nodeAliases.makeEquivalent(first, j.next()); + } + } + + groupChannel(nodeAliases, nodeConnections, narrowAliases, allowTwist); + groupChannel(narrowAliases, narrowConnections, wideAliases, false); + groupChannel(wideAliases, wideConnections, null, false); + + if (nodeConnections != null) { + for (Iterator i = nodeConnections.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final Channel out = ((Channel) p.getFirst()).getParent(); + final Channel in = ((Channel) p.getSecond()).getParent(); + if (isChannelType(out)) nodeConverter.add(out); + if (isChannelType(in)) nodeConverter.add(in); + } + } + + if (narrowConnections != null) { + for (Iterator i = narrowConnections.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final Channel out = ((Channel) p.getFirst()).getParent(); + final Channel in = ((Channel) p.getSecond()).getParent(); + if (out != null) narrowConverter.add(out); + if (in != null) narrowConverter.add(in); + } + } + + for (Iterator i = nodeConverter.iterator(); i.hasNext(); ) { + final Channel chan = ((Channel) i.next()).getParent(); + if (chan != null) narrowConverter.add(chan); + } + + return locals; + } + + public static final int ARRAY_TYPE = 1; + public static final int STRUCTURE_TYPE = 2; + public static final int WIDE_CHANNEL_TYPE = 4; + public static final int CHANNEL_TYPE = 8; + public static final int WIDE_NODE_TYPE = 16; + public static final int NODE_TYPE = 32; + /** + * Flatten and filter ports such that the kind of ports specified in the + * level bitmap are the only kind of ports left in the result. + * + * TODO: Replace flattenPortDefinitions, and flattenPortDefinitionsNodes + * with calls to this function + **/ + public static Iterator + flattenPorts(final Iterator ports, final int level) { + return flattenPorts(ports, level, Collections.emptySet()); + } + + public static Iterator + flattenPorts(final Iterator ports, final int level, + final Set keepStruct) { + final Collection result = + new ArrayList(); + (new MarkPort() { + private ChannelType deArray(final ChannelType t) { + return t.isArrayed() ? + new ChannelType(t.iterator(), t.getTypeName()) : t; + } + private NodeType deArray(final NodeType t) { + return t.isArrayed() ? new NodeType() : t; + } + private int translate(final int direction) { + if (direction < 0) { + return PortDefinition.REVERSE; + } else if (direction == 0) { + return PortDefinition.BIDIRECTIONAL; + } else { + return PortDefinition.FORWARD; + } + } + private void finish(final String name, final PortTypeInterface t, + final int direction) { + result.add(new PortDefinition(name, t, translate(direction))); + } + protected String arrayName(final PortTypeInterface t, + final String name, + final boolean inArray, + final boolean isArrayed) { + return super.arrayName(t, name, inArray, isArrayed && + ((t instanceof ChannelType && + (level & WIDE_CHANNEL_TYPE) == 0) || + (t instanceof NodeType && + (level & WIDE_NODE_TYPE) == 0))); + } + protected void mark(final StructureType structureType, + final String name, final int direction) { + if ((level & STRUCTURE_TYPE) == 0 && + !keepStruct.contains(structureType.getTag())) { + super.mark(structureType, name, direction); + } else { + finish(name, structureType, direction); + } + } + protected void mark(final ArrayType arrayType, final String name, + final int direction) { + if ((level & ARRAY_TYPE) == 0) { + super.mark(arrayType, name, direction); + } else { + finish(name, arrayType, direction); + } + } + protected void mark(final ChannelType channelType, + final String name, final int direction) { + if ((level & CHANNEL_TYPE) == 0) { + super.mark(channelType, name, direction); + } else { + finish(name, deArray(channelType), direction); + } + } + protected void mark(final ChannelType channelType, + final String name, final int direction, + final int width) { + if ((level & WIDE_CHANNEL_TYPE) == 0) { + super.mark(channelType, name, direction, width); + } else { + finish(name, channelType, direction); + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + if ((level & NODE_TYPE) == 0) { + super.mark(nodeType, name, direction); + } else { + finish(name, deArray(nodeType), direction); + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction, final int width) { + if ((level & WIDE_NODE_TYPE) == 0) { + super.mark(nodeType, name, direction, width); + } else { + finish(name, nodeType, direction); + } + } + }).mark(ports); + return result.iterator(); + } + + public static class FlattenPortDefinitions extends MarkPort { + protected final Collection result; + public FlattenPortDefinitions(final Collection result) { + this.result = result; + } + protected int translate(final int direction) { + if (direction < 0) { + return PortDefinition.REVERSE; + } else if (direction == 0) { + return PortDefinition.BIDIRECTIONAL; + } else { + return PortDefinition.FORWARD; + } + } + protected String arrayName(final PortTypeInterface t, + final String name, + final boolean inArray, + final boolean isArrayed) { + return super.arrayName(t, name, inArray, false); + } + protected void mark(final ChannelType channelType, + final String name, final int direction) { + result.add(new PortDefinition(name, channelType, + translate(direction))); + } + protected void mark(final ChannelType channelType, + final String name, final int direction, + final int width) { + result.add(new PortDefinition(name, channelType, + translate(direction))); + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + result.add(new PortDefinition(name, nodeType, + translate(direction))); + } + protected void mark(final NodeType nodeType, final String name, + final int direction, final int width) { + result.add(new PortDefinition(name, nodeType, + translate(direction))); + } + } + + public static Iterator flattenPortDefinitionsNodes(final Iterator ports) { + final Collection result = new ArrayList(); + (new MarkPort() { + private int translate(final int direction) { + if (direction < 0) { + return PortDefinition.REVERSE; + } else if (direction == 0) { + return PortDefinition.BIDIRECTIONAL; + } else { + return PortDefinition.FORWARD; + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + result.add(new PortDefinition(name, new NodeType(), + translate(direction))); + } + }).mark(ports); + return result.iterator(); + } + + /** + * Check to see if the specified cell or if any of its refinement parents + * satisfies the predicate check. If the predicate is + * satisfied by the specified cell, return true; otherwise, + * recursively check the cell's refinement parents, and return whatever + * value is returned by the recursive call. + **/ + public static boolean matchRefinement(final CellInterface cell, + final UnaryPredicate check) { + if (cell == null) return false; + if (check.evaluate(cell)) return true; + return matchRefinement(cell.getDirectRefinementParent(), check); + } + + /** + * Check to see if any of the inheritance parents of the specified cell + * satisfies the predicate check. If the predicate is + * satisfied, return true; otherwise, return + * false. + **/ + public static boolean matchInheritance(final CellInterface cell, + final UnaryPredicate check) { + for (Iterator i = cell.getInheritedCells(); i.hasNext(); ) { + final CellInterface attrib = (CellInterface) i.next(); + if (check.evaluate(attrib)) return true; + if (matchInheritance(attrib, check)) return true; + } + return false; + } + + /** + * Return a UnaryPredicate object that when used to evaluate a + * CellInterface object will return true if the + * cell or any of its refinement or inheritance ancestors refines or + * inherits any of the cells listed in candidates, or + * false otherwise. The matching is done by type name, so + * candidates should contain String objects. If + * any parameterization of a metaparameterized cell is to be matched, then + * use just the base name of the cell, without the metaparameters. + **/ + public static UnaryPredicate getTypeMatcher(final Collection candidates) { + final UnaryPredicate refinementCheck = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final CellInterface c = (CellInterface) o; + for (Iterator i = candidates.iterator(); i.hasNext(); ) { + final String candidate = (String) i.next(); + final String type = c.getFullyQualifiedType(); + if (candidate.equals(type) || + candidate.equals(CellUtils.getBaseType(type))) { + return true; + } + } + return false; + } + }; + final UnaryPredicate inheritanceCheck = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final CellInterface c = (CellInterface) o; + return CellUtils.matchInheritance(c, refinementCheck); + } + }; + final UnaryPredicate typeCheck = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final CellInterface cell = (CellInterface) o; + return CellUtils.matchRefinement(cell, refinementCheck) || + CellUtils.matchRefinement(cell, inheritanceCheck); + } + }; + + return typeCheck; + } + + public interface SizingEnvCreator { + void getInternalEnv(final CellInterface cell, + final AliasedSet aliases, + final Map subcells); + } + + private static UnaryPredicate INHERITS_LEAF = + getTypeMatcher(Arrays.asList( + "standard.base.leaf", + "standard.process.imported_proteus_cell")); + + public static void verifySubcells(final CellInterface cell, + final Cadencize cad, + boolean checkE1ofN) { + if (!cell.containsCompleteSubcells()) return; + + final CellInterface parent = cell.getDirectRefinementParent(); + if (parent != null && parent.containsCompleteSubcells()) { + // presumably connections have already been verified in the parent + return; + } + + // don't check e1ofN connections instead a leaf cell, as fragments + // often (harmlessly) violate this rule + if (INHERITS_LEAF.evaluate(cell)) checkE1ofN = false; + + final AliasedSet aliases = + cad.convertChannels(cell, Collections.EMPTY_MAP); + + final MultiMap channels = + new MultiMap(); + + new ChannelConnection(channels, null, aliases).mark(cell); + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = + (Pair) i.next(); + final CellInterface subcell = p.getSecond(); + if (subcell.isNode() || subcell.isChannel()) continue; + new ChannelConnection(channels, p.getFirst(), aliases).mark(subcell); + } + + TreeSet errors = null; + HashSet e1ofNodes = null; + for (HierName canon : channels.keySet()) { + int in = 0, out = 0, group = 0, total = 0;; + for (Channel c : channels.get(canon)) { + if (c.isInput() || c.isBidirectional()) ++in; + if (c.isOutput() || c.isBidirectional()) ++out; + if (c.getGroup() == 0) ++group; + ++total; + } + if (in != 0 && out == 0) { + if (errors == null) + errors = new TreeSet( + NaturalStringComparator.getInstance()); + errors.add(canon.toString()); + } else if (checkE1ofN && total == group && in != 1) { + if (e1ofNodes == null) e1ofNodes = new HashSet(); + e1ofNodes.add(canon); + } + } + + TreeSet e1ofErrors = null; + if (e1ofNodes != null) { + channels.clear(); + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = + (Pair) i.next(); + final CellInterface subcell = p.getSecond(); + if (subcell.isChannel()) { + new ChannelConnection(channels, p.getFirst(), aliases) + .mark(subcell); + } + } + e1ofErrors = + new TreeSet(NaturalStringComparator.getInstance()); + for (HierName h : e1ofNodes) { + final TreeSet canon = new TreeSet(); + for (Channel c : channels.get(h)) { + if (c.getGroup() >= 0) { + canon.add(c.getParent().getFullName()); + } else { + canon.add(c.getInstance().toString()); + } + } + e1ofErrors.add(canon.first()); + } + } + + if (errors != null) { + System.err.println( + "WARNING: the following nets have sinks but no sources in " + + cell.getFullyQualifiedType() + ":"); + for (String error : errors) { + System.err.println(" " + error); + } + } + if (e1ofErrors != null) { + System.err.println( + "WARNING: the following e1ofN channels are not " + + "point-to-point in " + cell.getFullyQualifiedType() + ":"); + for (String error : e1ofErrors) { + System.err.println(" " + error); + } + } + } + + /** + * Return the name of the implied port given the name the implied port + * connects to in the instantiator, or null if such a port + * does not exist. + **/ + public static String getLocalImpliedName(final CellInterface ci, + final String parentImpliedName) { + for (Iterator i = ci.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition p = (PortDefinition) i.next(); + if (ci.isImpliedPort(p.getName())) { + final String parent = ci.getParentImpliedPort(p.getName()); + if (parent.equals(parentImpliedName)) return p.getName(); + } + } + return null; + } + + /** + * Return the name of reset, or null if none found. Reset is + * either an implied node that would connect to _RESET in the parent, or an + * implied node that would connect to _Reset in the parent. + **/ + public static String getResetName(final CellInterface ci) { + final String RESET = getLocalImpliedName(ci, "_RESET"); + final String Reset = getLocalImpliedName(ci, "_Reset"); + if (RESET != null) return RESET; + else if (Reset != null) return Reset; + else return null; + } + + /** + * Construct and return a leakage environment. The environment aliases .e + * of input e1ofN channels, and .C.0 of input ChanDft channels to reset. + * Otherwise, it aliases all input nodes to ground. If reset or ground + * cannot be found, null is returned. + **/ + public static CellInterface getLeakageEnv(final CellInterface parent) { + final CellImpl result = + new CellImpl(parent.getType() + "_leakageEnv", + parent.getModuleName(), + CellImpl.SYNTHETIC_CELL); + + result.setHasCompleteSubcellsBlock(); + + for (Iterator i = parent.getPortSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + result.addSubcellPair((HierName) p.getFirst(), + (CellInterface) p.getSecond(), + true); + } + + final HierName reset = toHierOrNull(CellUtils.getResetName(parent)); + final HierName gnd = + toHierOrNull(CellUtils.getLocalImpliedName(parent, "GND")); + + for (Iterator i = parent.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition pd = (PortDefinition) i.next(); + final String name = pd.getName(); + final int dir; + if (parent.isImpliedPort(name)) { + final String inParent = parent.getParentImpliedPort(name); + result.addImpliedPortMapping(name, inParent); + dir = pd.getDirection(); + } else { + dir = pd.getReverseDirection(); + } + result.addPortDefinition(new PortDefinition(name, + pd.getType(), + dir)); + } + + for (Iterator i = parent.getMetaParamDefinitions(); i.hasNext(); ) { + final MetaParamDefinition mpd = (MetaParamDefinition) i.next(); + result.addMetaParamDefinition(mpd); + } + + final Set resets = new HashSet(); + final Set grounds = new HashSet(); + final Set implied = new HashSet(); + (new CellUtils.MarkPort() { + private boolean isImplied = false; + private void add(Set set, final String s) { + if (isImplied) set = implied; + set.add(toHier(s)); + } + protected void mark(final PortDefinition p, final String prefix, + int direction) { + if (prefix == null && parent.isImpliedPort(p.getName())) { + isImplied = true; + } + super.mark(p, prefix, direction); + isImplied = false; + } + protected void mark(final StructureType structureType, + final String name, final int direction) { + if (CellUtils.isDftChannel(structureType.getTag()) && + direction < 0) { + add(resets, name + ".C.d[0]"); + } + super.mark(structureType, name, direction); + } + protected void mark(final ChannelType channelType, + final String name, + final int direction) { + if (direction > 0) { + add(resets, name + ".e"); + } + super.mark(channelType, name, direction); + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + if (direction < 0) { + add(grounds, name); + } + } + }).mark(parent); + + for (HierName h : resets) { + if (reset == null) return null; + result.addConnection(h, reset); + } + + for (HierName h : grounds) { + if (!resets.contains(h)) { + if (gnd == null) return null; + result.addConnection(h, gnd); + } + } + + return result; + } + + public static Iterator> filterSubcellPairs( + final CellInterface cell, + final UnaryPredicate filter) { + return new FilteringIterator>( + (Iterator>) cell.getSubcellPairs(), + new UnaryPredicate>() { + public boolean evaluate( + final Pair p) { + return filter.evaluate(p.getSecond()); + } + }); + } + + /** + * Move array indexing to the end of string, e.g., a[0]_[1]b to a_b[0][1]. + * Nested array indexing not supported. + **/ + private static String moveBrackets(final String s) { + StringBuilder nonbracket = null; + StringBuilder bracket = null; + final int len = s.length(); + int start = 0; + while (start < len) { + final int left = s.indexOf('[', start); + if (left >= 0) { + final int right = s.indexOf(']', left + 1); + if (right >= 0) { + if (nonbracket == null) nonbracket = new StringBuilder(); + nonbracket.append(s.substring(start, left)); + + if (bracket == null) bracket = new StringBuilder(); + bracket.append(s.substring(left, right + 1)); + + start = right + 1; + continue; + } + } + break; + } + + if (start == 0) { + // special case if string contains no brackets + return s; + } else { + if (start < len) { + if (nonbracket == null) nonbracket = new StringBuilder(); + nonbracket.append(s.substring(start)); + } + + return (nonbracket == null ? "" : nonbracket.toString()) + + (bracket == null ? "" : bracket.toString()); + } + } + + /** + * Transform each component of a HierName according to the given function. + **/ + private static HierName + transformHierName(final HierName h, final UnaryFunction f) { + if (h == null) { + return h; + } else { + final HierName parent = transformHierName(h.getParent(), f); + final String suffix = f.execute(h.getSuffixString()); + if (parent == h.getParent() && suffix == h.getSuffixString()) { + return h; + } else { + try { + return HierName.makeHierName(parent, suffix); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName"); + } + } + } + } + + /** + * Given a STATICIZER instance, return a pair consisting of the CAST name + * of the small inverter node, and its real "analog" name. + **/ + private static HierName SMALL_INVERTER_NODE = HierName.makeHierName("1"); + public static Pair + getSmallInverterNode(final HierName inst) { + return new Pair( + HierName.append( + transformHierName( + inst, + new UnaryFunction() { + public String execute(String x) { + return StringUtil.replaceSubstring(moveBrackets(x), + "][", ","); + } + }), + SMALL_INVERTER_NODE), + HierName.append(inst, SMALL_INVERTER_NODE)); + } + + public static Map + getOutputNodes(final CellInterface cell, + final CastFileParser cfp, + final Cadencize cad, + final AliasedSet nodes, + final Map result) { + if (!cell.containsNetlist()) return null; + + for (Iterator i = nodes.getCanonicalKeys(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + result.put(name, name); + } + + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + + nb.getCDLTemplate().execute( + new CDLFactoryAdaptor() { + public void makeCall(HierName name, String subName, + HierName[] args, Map parameters, + com.avlsi.cast.impl.Environment env) { + if (subName.startsWith("gate.STATICIZER")) { + final Pair invNode = + getSmallInverterNode(name); + if (result.containsKey(invNode.getFirst())) + throw new AssertionError(); + result.put(invNode.getFirst(), invNode.getSecond()); + } + } + }); + + /* + final ArrayList problems = new ArrayList(); + final NetGraph ng = new NetGraph(nodes, + cell.getLocalExclusiveNodeSets(), + problems, + HierName.makeHierName("Vdd"), + HierName.makeHierName("GND"), + Collections.emptySet()); + try { + ng.addCellInterface(cell, new NetGraph[0], cfp, cad); + } catch (com.avlsi.prs.UnimplementableProductionRuleException e) { + throw new RuntimeException("Can't happen"); + } + ng.prepareForLvs(); + assert problems.isEmpty(); + for (Iterator i = ng.getOutputNodes().iterator(); + i.hasNext(); ) { + final NetGraph.NetNode n = (NetGraph.NetNode) i.next(); + result.add(n.name); + } + */ + + return result; + } + + /** + * For a given node name, returns the instance path to the cell where the + * node is local, the cell type, and the node's canonical name where it is + * local. If top is true, then even if name is + * already local, still recurse. + **/ + public static Triplet + localize(final HierName name, final CadenceInfo ci, final boolean top) { + HierName path = null; + CadenceInfo type = ci; + + final AliasedSet localNodes = ci.getLocalNodes(); + HierName canon = (HierName) localNodes.getCanonicalKey(name); + boolean inSubcell = false; + if (canon == null || top) { + for (HierName h = name; h != null; h = h.tail()) { + path = HierName.append(path, h.head()); + type = ci.getSubcell(path); + if (type != null) { + final Triplet sublocal = + localize(h.tail(), type, false); + if (sublocal != null) { + type = sublocal.getSecond(); + canon = sublocal.getThird(); + if (sublocal.getFirst() == null) { + // it's possible this can now be a local aliases + if (!top) { + final HierName candidate = (HierName) + localNodes.getCanonicalKey( + HierName.append(path,canon)); + if (candidate != null) { + canon = candidate; + path = null; + } + } + } else { + path = HierName.append(path, sublocal.getFirst()); + } + } + inSubcell = true; + break; + } + } + } + + final Triplet result; + if (canon == null) { + result = null; + } else { + if (top && !inSubcell) { + // this is an implied port node; treat as if it belongs to the + // top-level cell + final Pair p = + ci.getSubcellPairIterator().next(); + path = p.getFirst(); + type = p.getSecond(); + } + result = + new Triplet(path, type, canon); + } + + return result; + } + + /** + * Returns name decomposed into two parts: name of an instance + * in cell, the remaining part of name with the + * instance name removed. If name does not start with an + * instance name, return Pair(null, name). + **/ + public static Pair + getFirstInstance(final CellInterface cell, final HierName name, + final boolean excludeInlined) { + final Iterator> i = + HierName.getSplitsIterator(name); + final Pair notfound = i.next(); + while (i.hasNext()) { + final Pair p = i.next(); + if (cell.getSubcell(p.getFirst()) != null && + (!excludeInlined || !cell.isInlinedSubcell(p.getFirst()))) { + return p; + } + } + return notfound; + } + + /** + * Returns a map from canonical port name to port direction. If aliases of + * a port include both input and output ports, then inout will be returned. + **/ + public static Map + getCanonicalDir(final Map portDirs, + final CellInterface cell, + final AliasedSet nodes) { + for (Map.Entry portDir : + CellUtils.markPorts(cell).entrySet()) { + final HierName canon = (HierName) + nodes.getCanonicalKey(toHier(portDir.getKey())); + final Integer prev = portDirs.get(canon); + final Integer curr = portDir.getValue(); + if (prev == null) { + portDirs.put(canon, curr); + } else { + final boolean in = prev == PortDefinition.IN || + prev == PortDefinition.INOUT || + curr == PortDefinition.IN || + curr == PortDefinition.INOUT; + final boolean out = prev == PortDefinition.OUT || + prev == PortDefinition.INOUT || + curr == PortDefinition.OUT || + curr == PortDefinition.INOUT; + if (in && out) { + portDirs.put(canon, PortDefinition.INOUT); + } else if (in) { + portDirs.put(canon, PortDefinition.IN); + } else if (out) { + portDirs.put(canon, PortDefinition.OUT); + } else { + portDirs.put(canon, PortDefinition.NONE); + } + } + } + return portDirs; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ChildrenFirstCellInterfaceIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ChildrenFirstCellInterfaceIterator.java new file mode 100644 index 0000000000..30ece4c634 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ChildrenFirstCellInterfaceIterator.java @@ -0,0 +1,124 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cell; + +import java.lang.String; + +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.LinkedList; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.file.common.HierName; + +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.UnaryPredicate; + + +public class ChildrenFirstCellInterfaceIterator +implements Iterator { + + private static class StackFrame { + private final Iterator mSubcellPairsIter; + private final CellInterface mCell; + + public StackFrame( final CellInterface cell , + final UnaryPredicate filter ) { + mCell = cell; + mSubcellPairsIter = + new FilteringIterator( + mCell.getSubcellPairs(), + new UnaryPredicate>() { + public boolean evaluate( + final Pair p ) { + return filter.evaluate( p.getSecond() ); + } + }); + } + + public boolean hasNextSubcell( ) { + return mSubcellPairsIter.hasNext(); + } + + public CellInterface nextSubcellMaster() { + final Pair instancePair = ( Pair ) mSubcellPairsIter.next(); + final CellInterface master = ( CellInterface ) instancePair.getSecond(); + return master; + } + + public CellInterface getCell() { + return mCell; + } + } + + private final LinkedList mStack; + + private final Set mVisitedSet; + + private CellInterface mNextCell; + + private final UnaryPredicate mFilterPredicate; + + public ChildrenFirstCellInterfaceIterator( final CellInterface root ) { + this( root, new UnaryPredicate.Constant( true ) ); + } + + public ChildrenFirstCellInterfaceIterator( + final CellInterface root, + final UnaryPredicate filter ) { + mStack = new LinkedList(); + mVisitedSet = new HashSet(); + mNextCell = null; + mFilterPredicate = filter; + mStack.addFirst( new StackFrame( root, mFilterPredicate ) ); + } + + public boolean hasNext() { + if ( mNextCell == null ) { + while ( ( mStack.size() != 0 ) && ( mNextCell == null ) ) { + final StackFrame currFrame = mStack.getFirst(); + if ( currFrame.hasNextSubcell() ) { + final CellInterface nextSubcellMaster = currFrame.nextSubcellMaster(); + final String subcellMasterName = nextSubcellMaster.getFullyQualifiedType(); + + if ( ! ( mVisitedSet.contains( subcellMasterName ) ) ) { + mStack.addFirst( new StackFrame( nextSubcellMaster, + mFilterPredicate ) ); + } + } + else { + final CellInterface currCell = currFrame.getCell(); + mNextCell = currCell; + mVisitedSet.add( mNextCell.getFullyQualifiedType()); + mStack.removeFirst(); + } + } + } + return mNextCell != null; + } + + public CellInterface next() throws NoSuchElementException { + if ( hasNext() ) { + final CellInterface ret = mNextCell; + mNextCell = null; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSet.java new file mode 100644 index 0000000000..bded1fcd7e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSet.java @@ -0,0 +1,170 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; + +/** + * Class to represent exclhi / excllo specifications. If + * hiLo == HI, then only one node in the set can be + * simultaneously high. Similiarly for LO. If + * hiLo == CC then only one node in the set can flip + * in a direction at any time. If hiLo == NOCC, then + * the nodes will not be considered as a cap-coupling aggressor. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ExclusiveNodeSet { + public static final int LO = 0; + public static final int HI = 1; + public static final int CC = 2; + public static final int NOCC = 3; + + private final int hiLo; + private final ArrayList nodes; + + public ExclusiveNodeSet(final int hiLo, + final Collection nodes) { + if (hiLo != LO && hiLo != HI && hiLo != CC && hiLo != NOCC) + throw new IllegalArgumentException("bad value for hiLo:" + hiLo); + + this.hiLo = hiLo; + + // check that everything in the collection is a HierName + for (final Iterator i = nodes.iterator(); i.hasNext(); ) { + final Object o = i.next(); + + if (!(o instanceof HierName)) + throw new IllegalArgumentException("bad type " + + o.getClass().getName() + " in nodes"); + } + + this.nodes = new ArrayList(nodes); + } + + /** + * Return an iterator of HierNames that cannot be simultaneously high + * or low. + **/ + public Iterator getNodes() { + return nodes.iterator(); + } + + public int getNumNodes() { + return nodes.size(); + } + + /** + * Returns either HI (if only one node in the set can be high + * at one time) or LO (if only one node can be low at the same time), + * CC (if only one node can flip in a direction at any time), or NOCC + * (if no nodes in the set are cap-coupling aggressors). + **/ + public int getHiLo() { + return hiLo; + } + + /** + * Returns true if two or more nodes in the collection c are + * prevented from being simultaneously high or low by one of the exclhi / + * excllo rules, or are prevented from changing to the same value + * simultaneously by one of the exclcc rules. + * + * @param c Collection of HierNames to be checked for exclusion + **/ + public boolean areExclusive(final Collection c) { + boolean found = false; + for (final Iterator i = c.iterator(); i.hasNext(); ) { + final HierName hn = (HierName) i.next(); + + if (nodes.contains(hn)) { + if (found) + return true; + else + found = true; + } + + } + return false; + } + + /** + * Returns a new ExclusiveNodeSet such that the nodes use only the + * canonical node name, as defined in aliases. If a + * name does not appear in aliases, do not add it to the + * ExclusiveNodeSet. + **/ + public ExclusiveNodeSet canonicalizeNames(final AliasedSet aliases) { + final ArrayList canonNodes = new ArrayList(nodes.size()); + + for (final Iterator i = getNodes(); i.hasNext(); ) { + final HierName n = (HierName) i.next(); + final HierName cn = (HierName) aliases.getCanonicalKey(n); + if (cn != null) + canonNodes.add(cn); + } + + return new ExclusiveNodeSet(getHiLo(), canonNodes); + } + + /** + * Returns a new ExclusiveNodeSet with the names prefixed + * by the specified subcell name. + **/ + public ExclusiveNodeSet prefixNames(final HierName subCellName) { + final ArrayList prefixedNodes = new ArrayList(nodes.size()); + + for (final Iterator i = getNodes(); i.hasNext(); ) { + final HierName n = (HierName) i.next(); + prefixedNodes.add(HierName.prefixName(subCellName, n)); + } + + return new ExclusiveNodeSet(getHiLo(), prefixedNodes); + } + + /** + * Returns a string representation of the object for debugging use + * only. + **/ + public String toString() { + final StringBuffer sb = new StringBuffer(); + + if (getHiLo() == HI) + sb.append("exclhi("); + else if (getHiLo() == LO) + sb.append("excllo("); + else if (getHiLo() == CC) + sb.append("exclcc("); + else if (getHiLo() == NOCC) + sb.append("nocc("); + else + throw new AssertionFailure("Bad hi / lo value: " + getHiLo()); + + for (final Iterator iNode = getNodes(); iNode.hasNext(); ) { + final HierName hn = (HierName) iNode.next(); + sb.append(' ').append(hn.toString()); + } + + sb.append(" )"); + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSets.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSets.java new file mode 100644 index 0000000000..966a3ebabb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/ExclusiveNodeSets.java @@ -0,0 +1,117 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +import com.avlsi.util.container.AliasedSet; + +/** + * Aggregates exclusive hi / lo information together, so that queries + * can be made. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ExclusiveNodeSets { + /** + * List of the exclusion sets (type ExclusiveNodeSet). + **/ + private final ArrayList exclusiveNodeSetList; + + public ExclusiveNodeSets() { + this.exclusiveNodeSetList = new ArrayList(); + } + + public Iterator getIterator() { + return Collections.unmodifiableList(exclusiveNodeSetList).iterator(); + } + + public void addExclusiveNodeSet(final ExclusiveNodeSet ens) { + exclusiveNodeSetList.add(ens); + } + + /** + * Returns true if two or more nodes in the collection c + * are prevented from being simultaneously low by one of the exclhi + * or excllo rules, or are prevented from switching in the same + * direction simultaneously by one of the exclcc rules, as specified by + * hiLo. + * + * @param c Collection of HierNames to be checked for exclusion + * @param hiLo ExclusiveNodeSet.HI, ExclusiveNodeSet.LO, or + * ExclusiveNodeSet.CC depending on whether exclusive hi, lo, or switching + * in the same direction, should be checked. + **/ + public boolean areExclusive(final int hiLo, final Collection c) { + for (final Iterator i = getIterator(); i.hasNext(); ) { + final ExclusiveNodeSet ens = (ExclusiveNodeSet) i.next(); + + if (ens.getHiLo() == hiLo && ens.areExclusive(c)) + return true; + } + + return false; + } + + /** + * Ensures that all nodes use only the canonical node name, as defined + * in aliases. + **/ + public ExclusiveNodeSets canonicalizeNames(final AliasedSet aliases) { + final ExclusiveNodeSets enss = new ExclusiveNodeSets(); + + for (int i = 0; i < exclusiveNodeSetList.size(); ++i) { + final ExclusiveNodeSet ens = + (ExclusiveNodeSet) exclusiveNodeSetList.get(i); + + enss.addExclusiveNodeSet(ens.canonicalizeNames(aliases)); + } + + return enss; + } + + /** + * Absorbs exclusive node sets from the refinement parent. + **/ + public void refineFrom(final ExclusiveNodeSets parent) { + merge(parent); + } + + /** + * Adds in all exclusive node sets from another ExclusiveNodeSets. + **/ + public void merge(final ExclusiveNodeSets other) { + exclusiveNodeSetList.addAll(other.exclusiveNodeSetList); + } + + /** + * Returns a string representation of the ExclusiveNodeSets for + * debugging purposes. + **/ + public String toString() { + final StringBuffer sb = new StringBuffer(); + + for (final Iterator i = getIterator(); i.hasNext(); ) { + final ExclusiveNodeSet ens = (ExclusiveNodeSet) i.next(); + + sb.append(ens.toString()).append('\n'); + } + + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/HierarchyInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/HierarchyInterface.java new file mode 100644 index 0000000000..cc2ba16477 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/HierarchyInterface.java @@ -0,0 +1,7 @@ +package com.avlsi.cell; + +import com.avlsi.file.common.HierName; + +public interface HierarchyInterface { + HierarchyInterface getSubcell(HierName name); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/InstanceTrace.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/InstanceTrace.java new file mode 100644 index 0000000000..60568b75e3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/InstanceTrace.java @@ -0,0 +1,84 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cell; + +import java.util.Iterator; +import java.util.LinkedList; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.Pair; + +/** + * A class that represents a path in the instantiation tree. It is similar to + * Java stack traces. + **/ +public final class InstanceTrace { + public final class Element { + private final String cellName, instanceName; + /** + * Construct a new element. + * + * @param cellName Name of the cell being instantiated + * @param instanceName Name of the instance + **/ + public Element(final String cellName, final String instanceName) { + this.cellName = cellName; + this.instanceName = instanceName; + } + public String getCellName() { + return cellName; + } + public String getInstanceName() { + return instanceName; + } + public String toString() { + return "\tin type " + cellName + " (instantiated as " + instanceName + ")"; + } + } + + private final LinkedList /**/ trace; + + public InstanceTrace() { + this.trace = new LinkedList /**/ (); + } + + public Element[] getInstanceTrace() { + return (Element[]) trace.toArray(new Element[0]); + } + + public void enter(final Element elem) { + trace.addFirst(elem); + } + + public void enter(final String cellName, final String instanceName) { + enter(new Element(cellName, instanceName)); + } + + public void enter(final String cellName, final HierName instanceName) { + enter(cellName, instanceName.getAsString('.')); + } + + public void enter(final Pair subcellInstance) { + final HierName instance = (HierName) subcellInstance.getFirst(); + final CellInterface cell = (CellInterface) subcellInstance.getSecond(); + enter(cell.getFullyQualifiedType(), instance); + } + + public Element leave() { + return (Element) trace.removeFirst(); + } + + public String toString() { + final StringBuffer buf = new StringBuffer(); + for (Iterator i = trace.iterator(); i.hasNext(); ) { + final Element elem = (Element) i.next(); + buf.append(elem.toString() + "\n"); + } + return buf.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchEnvironmentException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchEnvironmentException.java new file mode 100644 index 0000000000..d8740b19f3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchEnvironmentException.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.cell; + +/** + * Thrown to indicate that the specified environment could not be found + * for cell instantiation. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class NoSuchEnvironmentException extends Exception { + + private final String cellName; + private final String envName; + + /** + * Constructs a NoSuchEnvironmentException indicating + * that the specified environment could not be created. + **/ + public NoSuchEnvironmentException(final String cellName, + final String envName) { + this.cellName = cellName; + this.envName = envName; + } + + /** + * Constructs a NoSuchEnvironmentException indicating + * that the specified environment could not be created. + **/ + public NoSuchEnvironmentException(final String cellName, + final String envName, + final Throwable cause) { + super(cause); + this.cellName = cellName; + this.envName = envName; + } + + /** + * Returns the name of the environment that couldn't be found. + **/ + public String getEnvironmentName() { + return envName; + } + + /** + * Returns the name of the cell where the environment couldn't be found. + **/ + public String getCellName() { + return cellName; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchSubcellException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchSubcellException.java new file mode 100644 index 0000000000..cca2935275 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/NoSuchSubcellException.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +import com.avlsi.file.common.HierName; + +/** + * Exception throws when an operation is attempted on a subcell that + * does not exist. + * + * @see CellImpl#inlineSubcell + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class NoSuchSubcellException extends Exception { + public NoSuchSubcellException(final HierName hn) { + super(hn.getAspiceString()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/RefinementException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/RefinementException.java new file mode 100644 index 0000000000..235026d310 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/RefinementException.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +public class RefinementException extends Exception { + public RefinementException(String msg, String childType, String parentType) { + super("Error trying to refine " + childType + " from " + parentType + + ": " + msg); + } + + public RefinementException(String msg, String childType, String parentType, Throwable cause) { + super("Error trying to refine " + childType + " from " + parentType + + ": " + msg, cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/SubcellCreationException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/SubcellCreationException.java new file mode 100644 index 0000000000..454852bb20 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/SubcellCreationException.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id: $ + */ + +package com.avlsi.cell; + +import com.avlsi.file.common.HierName; + +public class SubcellCreationException extends Exception { + public SubcellCreationException(String msg, HierName subcellName, String parentType) { + super("Error trying to create the subcell " + subcellName + " in the cell " + parentType + ": " + msg); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/cell/TestExclusiveNodeSet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/TestExclusiveNodeSet.java new file mode 100644 index 0000000000..9d4ff7a6ca --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/cell/TestExclusiveNodeSet.java @@ -0,0 +1,78 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.cell; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.avlsi.file.common.HierName; +import com.avlsi.test.AbstractTestCase; + +/** + * This is a description of the class + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class TestExclusiveNodeSet extends AbstractTestCase { + public void test() throws Exception { + final HierName a = HierName.makeHierName("a"); + final HierName b = HierName.makeHierName("b"); + final HierName c = HierName.makeHierName("c"); + final HierName fooA = HierName.makeHierName("foo.a", '.'); + final HierName fooB = HierName.makeHierName("foo.b", '.'); + + final Set ab = new HashSet(); + ab.add(a); + ab.add(b); + + final Set bc = new HashSet(); + bc.add(b); + bc.add(c); + + final Set abc = new HashSet(); + abc.add(a); + abc.add(b); + abc.add(c); + + final Set fooSet = new HashSet(); + fooSet.add(fooA); + fooSet.add(fooB); + + final ExclusiveNodeSet ens1 = + new ExclusiveNodeSet(ExclusiveNodeSet.HI, ab); + assertTrue(ens1.areExclusive(ab)); + assertTrue(!ens1.areExclusive(Collections.singleton(a))); + assertTrue(!ens1.areExclusive(Collections.singleton(b))); + + final ExclusiveNodeSet ens2 = + new ExclusiveNodeSet(ExclusiveNodeSet.HI, abc); + assertTrue(ens2.areExclusive(ab)); + assertTrue(ens2.areExclusive(bc)); + assertTrue(!ens2.areExclusive(Collections.singleton(a))); + assertTrue(!ens2.areExclusive(Collections.singleton(b))); + assertTrue(!ens2.areExclusive(Collections.singleton(c))); + + final ExclusiveNodeSet ens3 = + new ExclusiveNodeSet(ExclusiveNodeSet.HI, fooSet); + assertTrue(ens3.areExclusive(fooSet)); + assertTrue(!ens3.areExclusive(Collections.singleton(fooA))); + assertTrue(!ens3.areExclusive(Collections.singleton(fooB))); + } + + public static void main(String[] args) { + AbstractTestCase.testOne(new TestExclusiveNodeSet()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractCircuit.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractCircuit.java new file mode 100644 index 0000000000..bf1753716f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractCircuit.java @@ -0,0 +1,363 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.circuit; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.util.container.AliasedMap; +import com.avlsi.file.common.HierName; +//import com.avlsi.file.common.Capacitor; +//import com.avlsi.file.aspice.Diode; +//import com.avlsi.file.aspice.Resistor; +//import com.avlsi.file.aspice.Transistor; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.debug.Debug; + +/** + * Abstract Hierarchical Circuit class. Intended to be extended + * by different circuit structures, such as {@link CircuitGraph}, + * {@link com.avlsi.file.aspice.AspiceCell}, + * {@link com.avlsi.tools.lvs.NetGraph}, + * {@link com.avlsi.tools.aspice.JaspiceCircuit}, etc., so common parsing + * code can be used to construct them. + * + * @author Mike Davies, based on AspiceFile code by Jesse Rosenstock. + * @version $Revision$ $Date$ + **/ + +public abstract class AbstractCircuit { + + // + // Data members + // + + /** + * Cell type + **/ + private final String type; + + /** + * Map from subcell instantiation name (String) to AbstractCircuit + **/ + private final Map subcellUseMap = new HashMap(); + + /** + * Set of global names used in this cell or subcells + **/ + private final Set globalsSet = new HashSet(); + + /** + * Namespace alias map. Map from set of names to null object. + * Names may be in this cell or of the form sub.name for nodes + * defined in subcells. + **/ + private static class DummyMerge + implements AliasedMap.MergeFunction, java.io.Serializable { + public Object merge(final Object a, final Object b) { + if (a == null) + return null; + else if (b == null) + return a; + else { + Debug.assertTrue(a == EXISTS); + Debug.assertTrue(b == EXISTS); + return EXISTS; + } + } + } + + protected final AliasedMap asm + = new AliasedMap(new DummyMerge(), HierName.getComparator());/*new MergeFunction() { + public Object merge(final Object a, final Object b) { + if (a == null) + return null; + else if (b == null) + return a; + else { + Debug.assertTrue(a == EXISTS); + Debug.assertTrue(b == EXISTS); + return EXISTS; + } + } + }, HierName.getComparator());*/ + + private static final SerializedObject EXISTS = new SerializedObject(); + + private static class SerializedObject extends Object + implements java.io.Serializable {} + + protected Repository repository; + // + // Constructor + // + + /** + * Constructs a circuit of the specified type. + **/ + + public AbstractCircuit(final String type) { + this.type = type; + repository = null; + } + + // + // General class methods + // + + /** + * Returns circuit's cell type. + **/ + public String getType() { + return type; + } + + // + // Subcircuit routines + // + + /** + * Adds an instantiation of a subcell. + **/ + public void addSubcell(final String subName, final AbstractCircuit defn) { + final Object o = subcellUseMap.put(subName, defn); + if (o != null) + throw new RuntimeException("Duplicate instantiation of '"+subName + +"'. Old instantiation replaced."); + } + + /** + * Returns the definition of the specified instantiated subcell. + **/ + public AbstractCircuit getSubcellDefForName(final String name) { + return (AbstractCircuit) subcellUseMap.get(name); + } + + /** + * Returns an Iterator of HierNames referencing the circuit's subcells. + **/ + public Iterator getSubcellNames() { + return subcellUseMap.keySet().iterator(); + } + + /** + * Returns a cell type name for the specified subcell, or null + * if it doesn't exist. + **/ + public String getSubcellTypeForName(final String name) { + final AbstractCircuit a = getSubcellDefForName(name); + if (a == null) + return null; + else + return a.getType(); + } + + /** + * Clears the subcell list (used after a flatten) + **/ + public void removeAllSubcells() { + subcellUseMap.clear(); + } + + // + // Device creation & access methods. + // + + /** + * Adds a diode to the circuit (to be defined by subclass). + **/ + public abstract void addDiode(final DiodeInterface diode); + + /** + * Adds a resistor to the circuit (to be defined by subclass). + **/ + public abstract void addResistor(final ResistorInterface resistor); + + /** + * Adds a capacitor to the circuit (to be defined by subclass). + **/ + public abstract void addCapacitor(final CapacitorInterface capacitor); + + /** + * Adds a transistor to the circuit (to be defined by subclass). + **/ + public abstract void addTransistor(final TransistorInterface transistor); + + public void addSource(final SourceInterface source) + throws AbstractCircuit.Exception{ + throw new AbstractCircuit.Exception("Sources from Spice Not implemented"); + } + + /** + * Returns the number of diodes in the circuit (to be defined by subclass). + **/ + public abstract int getDiodeCount(); + + /** + * Returns the number of resistors in the circuit + * (to be defined by subclass). + **/ + public abstract int getResistorCount(); + + /** + * Returns the number of capacitors in the circuit + * (to be defined by subclass). + **/ + public abstract int getCapacitorCount(); + + /** + * Returns the number of MOSFET transistors in the circuit + * (to be defined by subclass). + **/ + public abstract int getTransistorCount(); + + // + // Namespace related methods + // + + /** + * Adds a cell or node name to the circuit + **/ + public void addName(final HierName name) + { + try { + if (name.isGlobal()) + addGlobal(name); + asm.addData(name, EXISTS); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + /** + * Connects two names, adding them if they don't exist in the circuit. + **/ + public void aliasNames(final HierName name1, final HierName name2) + { + try { + if (name1.isGlobal()) + addGlobal(name1); + if (name2.isGlobal()) + addGlobal(name2); + System.out.println("Making connection: "+name1+" to "+name2); + asm.makeEquivalent(name1, name2); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + /** + * Returns an iterator over the circuit's canonical HierNames. + **/ + public Iterator getCanonicalNames() { + return asm.getCanonicalKeys(); + } + + /** + * Returns an Iterator over the HierName equivalency set of + * the specified name. The specified name is included in the list. + **/ + public Iterator getEquivalentNames(final HierName name) { + return asm.getAliases(name); + } + + /** + * Adds name to the set of global names. + **/ + protected void addGlobal(final HierName name) { + globalsSet.add(name); + } + + /** + * Returns an Iterator of HierName, the globals in this cell or + * its subcells. + **/ + public Iterator getGlobals() { + return globalsSet.iterator(); + } + + /** + * Returns the Repository containing circuits defined locally in this + * circuit. + **/ + public Repository getRepository() { + return repository; + } + + /***************************************************************** + * Subcell repository class. Defines a subcell type to definition + * map. Also defines an (abstract) AbstractCircuit generator + * method, to be used by parsing code to generate new subcells + * of the appropriate AbstractCircuit subtype. + *****************************************************************/ + + public abstract static class Repository { + + /** + * CellType (String) -> cellDefinition (AbstractCircuitGenerator) map. + **/ + private final HashMap repos = new HashMap(); + + /** + * AbstractCircuit factory abstract method. + **/ + protected abstract AbstractCircuit + newCircuitGenerator(final String cellType); + + /** + * Returns a new empty AbstractCircuit and adds it to the + * repository map. + **/ + public AbstractCircuit newCell(final String cellType) + throws AbstractCircuit.Exception { + AbstractCircuit abstractCell = newCircuitGenerator(cellType); + Object exists = repos.put(cellType,abstractCell); + if (exists != null) + throw new AbstractCircuit.Exception("Cell '"+cellType+ + "' redefined."); + return abstractCell; + } + + /** + * Returns the set of all cell types in the repository. + * @return Set of cell type Strings. + **/ + public Set getCellTypesSet() { + return repos.keySet(); + } + + /** + * Returns an iterator over all defined cell types in the repository. + * @return Iterator over a set of String cell type names. + **/ + public Iterator getCellTypesIterator() { + return repos.keySet().iterator(); + } + + /** + * Returns the definition of the specified cell from the repository. + * @return Specified cell type definition, or null undefined. + **/ + public AbstractCircuit getCell(String cellType) { + return (AbstractCircuit) repos.get(cellType); + } + } + + /***************************************************************** + * AbstractCircuit exception class + *****************************************************************/ + public static class Exception extends java.lang.Exception { + public Exception() { super(); } + public Exception(final String desc) { super(desc); } + public Exception(final Throwable cause) { super(cause); } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractNode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractNode.java new file mode 100644 index 0000000000..ad386339bb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/AbstractNode.java @@ -0,0 +1,578 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.Iterator; +import java.util.HashSet; +import java.util.ArrayList; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.util.debug.Debug; + +/********************************************************************** + * Circuit graph node abstract base class. + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public abstract class AbstractNode { + + static boolean VDN_DEBUG; + static boolean GATERC_DEBUG; + static boolean CONJUNCTIVE_PATH_DEBUG; + + /** The node name **/ + public HierName name; + + /**************************************************************** + * Note that mark state for CapEdges and MosEdges are stored in + * the Node class (so they're directed), since these devices are + * accounted for on a per-terminal basis. Resistor mark state + * is stored in the ResEdge class, since they are accounted for + * on a per-device basis. + ****************************************************************/ + + final private boolean[] mark; + + /** + * Constructor. Takes a node name and the number of marks this + * node will need. + **/ + AbstractNode(final HierName name, int numMarks) { + this.name=name; + mark = new boolean[numMarks]; + } + + // + // Abstract methods to be implemented by subclasses: + // + + /** Connects a resistor to the node. **/ + abstract void connectRes(final ResDevice r); + + /** Connects a capacitor to the node. **/ + abstract void connectCap(final CapDevice c); + + /** Connects a transistor to the node. **/ + abstract void connectMos(final MosDevice m); + + /** Connects a diode to the node. **/ + abstract void connectDiode(final DiodeDevice m); + + /** Returns an iterator over all MosDevices connected to this node. **/ + public abstract Iterator getMosDevices(); + + /** Returns an iterator over all ResDevices connected to this node. **/ + public abstract Iterator getResDevices(); + + /** Returns an iterator over all CapDevcies connected to this node. **/ + public abstract Iterator getCapDevices(); + + /** Returns an iterator over all DiodeDevices connected to this node. **/ + public abstract Iterator getDiodeDevices(); + + /** Clears all marks in attached device edges **/ + abstract void clearDeviceMarks(); + + /** Returns total wire capacitance lumped to this node **/ + public abstract float wireCap(); + + /** Returns total gate capacitance lumped to this node **/ + public abstract float gateCap(); + + /** Returns total "good" capacitance (lumped to a fixed node) **/ + public abstract float goodCap(); + + /** + * Returns total "bad" capacitance (lumped to nodes that could + * transition during this node's transition). + **/ + public abstract float badCap(); + + /** Returns number of (wire) Capacitors attached to this node **/ + public abstract int numCap(); + + /** Returns number of resistors attached to this node **/ + public abstract int numRes(); + + /** Returns number of Mosfet attached to this node via source/drain **/ + public abstract int numDrivers(); + + /** Returns number of gates attached to this node **/ + public abstract int numGates(); + + // + // Shared methods/algorithms + // + + /** Sets the specified mark **/ + void setMark(int num) { mark[num] = true; } + + /** Clears the specified mark **/ + void clearMark(int num) { mark[num] = false; } + + /** Returns state of specified mark **/ + boolean getMark(int num) { return mark[num]; } + + /** Clears all marks associated with this node **/ + void clearAllMarks(int numMarks) { + clearDeviceMarks(); + for (int i=0; imay be covered more than + * once, in cases where cycles exist in the graph. The + * marking scheme adequately handles such cases. + *

    + * Node.mark[0] is used in this algorithm. The method + * expects {@link #wireCap()}, {@link #gateCap()}, and + * {@link #numDrivers()} to return meaningful values. For + * a non-degenerate search, {@link #getResDevices()} must + * return a non-empty Iterator. + **********************************************************/ + void buildResistiveSubnet(ResistiveSubnet rsn, HashSet uncoveredNodes) + { + // + // Check if we've touched this node already, if so + // set has_cycles; if not, remove this node from the + // set of uncovered nodes + // + if (!mark[0]) { + uncoveredNodes.remove(this); + Iterator it = getResDevices(); + if (!it.hasNext()) rsn.setDegenerate(); + rsn.addNode(this); + mark[0] = true; + // + // Follow resistive connections + // + while (it.hasNext()) { + ResDevice r = (ResDevice)it.next(); + if (!r.getMark()) { + r.setMark(); + r.nextAfter(this).buildResistiveSubnet(rsn,uncoveredNodes); + } + } + } + else rsn.encounteredCycle(); + } + + /********************************************************** + * Recursive depth-first-search routine to construct this + * node's resistive subnet test circuit. For nodes in the + * subnet, {@link #getCapDevices()}, {@link #getMosDevices()}, + * {@link #getResDevices()}, and {@link #getDiodeDevices()} + * should all be meaningful. + *

    + * Uses mark[0], and requires that all nodes in the circuit + * are initially unmarked. + **********************************************************/ + void buildTestSubnet(TestSubnet subnet) + { + if (!mark[0]) { + mark[0] = true; + subnet.addSubnetNode(this); + // + // Add capacitors + // + Iterator it = getCapDevices(); + while (it.hasNext()) { + CapDevice cd = (CapDevice)it.next(); + // + // Add the capacitor to the test subnet, if the + // other terminal hasn't been added to the subnet. + // + AbstractNode n = cd.nextAfter(this); + if (!n.mark[0]) subnet.addCapacitor(cd,n); + } + // + // Add transistors (for driver nodes, this + // will cause the pull-up/pull-down network + // attached to this node to be determined). + // + it = getMosDevices(); + while (it.hasNext()) { + MosDevice md = (MosDevice)it.next(); + if (md.gateNode() == this) + subnet.addGateMos(md); + else + subnet.addDriverNode(this); + } + // + // Add diodes + // + it = getDiodeDevices(); + while (it.hasNext()) { + DiodeDevice dd = (DiodeDevice)it.next(); + subnet.addDiode(dd); + } + // + // Follow resistive edges. + // + it = getResDevices(); + while (it.hasNext()) { + ResDevice rd = (ResDevice)it.next(); + if (!rd.getMark()) { + rd.setMark(); + subnet.addResistor(rd); + if (! (rd.nextAfter(this) instanceof Node)) { + System.err.println("Error: "+ + rd.nextAfter(this).name.getAsString('.')+ + " isn't a Node."); + } + rd.nextAfter(this).buildTestSubnet(subnet); + } + } + } + else subnet.encounteredCycle(); + } + + /** Helper class for buildConjunctivePaths() **/ + static class GateSourceType { + HierName gname; + HierName sname; + int t; + boolean reached_supply; + GateSourceType(AbstractNode g, AbstractNode s, int t) { + this.gname = g.name.getResistiveSubnetName(); + this.sname = s.name.getResistiveSubnetName(); + this.t = t; + } + boolean equals(GateSourceType gst) { + return (gst != null) && gst.gname.equals(gname) && + gst.sname.equals(sname) && (gst.t == t); + } + } + + boolean buildConjunctivePaths(ConjunctivePath p, TestSubnet subnet) + { + if (CONJUNCTIVE_PATH_DEBUG) { + System.err.print(this.name.getAsString('.')+": "); + p.printToStream(System.err); + } + // + // First check path termination condition, i.e. if this + // node is GND or Vdd, or if this path ended up back at + // a subnet driver node. + // + if (isGND() || isVdd()) { + p.addTerm(this.name,ConjunctivePath.SUPPLY); + subnet.addConjunctivePath(p); + return true; + } + else if (subnet.isDriverNode(this) && p.getNumTerms() > 0 || + !isInternal() && p.getNumTerms() > 1) { + // + // NOTE: Forced to add the !isInternal() condition to + // deal with sneak paths. Since we don't know anything + // about the exclusion relationships between input + // nodes, we can't do any better than to assume that any + // named node belongs to a different (mutually exclusive) + // output subnet. + // This assumption will definitely fail for most + // pass-gates layout (since both sides typically are named), + // so for that reason the getNumTerms() > 1 condition is + // added. This works since no shared gate network will + // ever separate two output nodes by a single transistor. + // This assumption relies on the internal nodes of + // transistor pull-up/down networks being the only numbered + // nodes in the cell under analysis. + // + if (CONJUNCTIVE_PATH_DEBUG) + System.err.println("Reached driver node "+ + name.getAsString('.')); + return false; + } + // + // Add diodes for this node + // + /* + if (!subnet.isInternalDriverNode(this)) { + Iterator it = getDiodeDevices(); + System.err.print("Adding diodes to "+name.getAsString('.')+": "); + while (it.hasNext()) { + System.err.print("."); + DiodeDevice d = (DiodeDevice) it.next(); + subnet.addDiode(d); + } + System.err.println(""); + } + */ + mark[0] = true; + // + // Otherwise... + // If we haven't reached a supply rail, split the path for + // each transistor branch. + // + boolean reached_supply = false; + ArrayList driverTerms = new ArrayList(); + Iterator it = getMosDevices(); + while (it.hasNext()) { + MosDevice md = (MosDevice)it.next(); + if (md.drainNode() == this && !md.sourceNode().mark[0] || + md.sourceNode() == this && !md.drainNode().mark[0]) { + AbstractNode g = md.gateNode(); + AbstractNode s = (md.drainNode()==this) ? md.sourceNode() : + md.drainNode(); + // + // Determine if this transistor is logically + // redundant, i.e. if we've already encountered a + // transistor with the same (s,g,type). + // + GateSourceType gst = new GateSourceType(g,s,md.getType()); + Iterator jt = driverTerms.iterator(); + boolean redundant = false; + while (jt.hasNext()) { + GateSourceType gstDone = (GateSourceType)jt.next(); + if (gst.equals(gstDone)) { + redundant = true; + if (gstDone.reached_supply) + subnet.addDriverMos(md); + } + } + if (CONJUNCTIVE_PATH_DEBUG) + System.err.println("redundant = "+redundant); + // + // If it isn't redundant, continue the path down each + // transistor branch. + // + if (!redundant) { + driverTerms.add(gst); + // Branch the ConjunctivePath + ConjunctivePath pb = new ConjunctivePath(p); + // + // Only add the term if it's non-constant. + // If the gate is constant (supply or reset), and + // if it permanently turns the transistor off, + // terminate the conjunctive path here. + // + String suffix = + g.name.getResistiveSubnetName().getSuffixString(); + if (suffix.equals("GND!")) { + if (md.getType() == DeviceTypes.N_TYPE) continue; + // else Don't add the term since it's constant + } + else if (suffix.equals("Vdd!") || suffix.equals("_PReset!") + || suffix.equals("_SReset!")) { + if (md.getType() == DeviceTypes.P_TYPE) continue; + // else Don't add the term since it's constant + } + else { + pb.addTerm(g.name.getResistiveSubnetName(), + md.getType()); + } + if (s.buildConjunctivePaths(pb,subnet)) { + // This branch reached a supply rail + reached_supply = true; + gst.reached_supply = true; + } + if (gst.reached_supply) { + subnet.addDriverMos(md); + } + } + } + } + // + // Unmark on the way back up + // + mark[0] = false; + return reached_supply; + } + + + /********************************************************** + * Recursively calculates effective R and C beginning from + * all leaves with driver nodes. Nodes with !mark[0] are + * not followed. The wire cap is summed over all paths, + * the resistance is combined over all paths as if the + * driver strengths are all identical (i.e. weighted by + * the number of drivers on each path). Also calculates + * the maximum R over all driver paths, and the C along + * that path. + *

    + * mark[0..1] are used by this algorithm. The method also + * requires {@link #getResDevices()}, {@link #numDrivers()}, and + * {@link #wireCap()} to have meaningful implementations. + **********************************************************/ + ResistiveSubnet.DriverRCData calculateRCtoDrivers() + { + ResistiveSubnet.DriverRCData rcd = + new ResistiveSubnet.DriverRCData(); + Iterator it = getResDevices(); + mark[1] = true; + while (it.hasNext()) { + ResDevice rd = (ResDevice)it.next(); + if (!rd.getMark()) { + rd.setMark(); + AbstractNode n = rd.nextAfter(this); + if (n.mark[0] && !n.mark[1]) { + ResistiveSubnet.DriverRCData subrcd = + n.calculateRCtoDrivers(); + if (VDN_DEBUG) System.err.println("vdn_R - " + +n.name.getAsString('.')+" reported " + +subrcd.R+" ("+subrcd.numDrivers+")"); + rcd.R += subrcd.numDrivers*(rd.getValue() + subrcd.R); + rcd.numDrivers += subrcd.numDrivers; + if (rd.getValue() + subrcd.maxR > rcd.maxR + && subrcd.numDrivers > 0) { + rcd.maxR = rd.getValue() + subrcd.maxR; + rcd.maxC = subrcd.maxC; + } + if (subrcd.numDrivers > 0) rcd.C += subrcd.C; + } + } + } + rcd.numDrivers += this.numDrivers(); + if (rcd.numDrivers > 0) { + rcd.R /= rcd.numDrivers; + rcd.C += wireCap(); + rcd.maxC += wireCap(); + } + return rcd; + } + + /***************************************************************** + * Depth-first search to find the maximum resistive path from VDN + * to gate load, over all such paths in the resistive subnet. + * This method assumes that {@link #getResDevices()} and {@link + * #gateCap()} are meaningfully defined. mark[0] is used in the + * search. + *

    + * This algorithm requires that the resistive subnetwork be + * cycle-free. However, if the network does contain cycles, the + * maximum resistance will be overestimated, which will often be + * acceptable for conservative circuit analysis. + *****************************************************************/ + float findMaxPathRes() + { + float maxres = -1.0f; + Iterator it = getResDevices(); + mark[0] = true; + while (it.hasNext()) { + ResDevice rd = (ResDevice)it.next(); + AbstractNode n = rd.nextAfter(this); + if (!n.mark[0]) { + float res = n.findMaxPathRes(); + if (GATERC_DEBUG) System.err.println("findMaxPathRes() - " + +n.name.getAsString('.')+" reported " + +res+" ("+(res >= 0.0 ? "has":"no")+" gates)"); + if (res >= 0.0f && rd.getValue() + res > maxres) + maxres = rd.getValue() + res; + } + } + // maxres of -1.0 is returned if no gate cap exists at + // or beyond this node. + if (maxres == -1.0f && gateCap() > 0.0f) maxres = 0.0f; + return maxres; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapDevice.java new file mode 100644 index 0000000000..8359ed7159 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapDevice.java @@ -0,0 +1,100 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.Capacitor; + +/********************************************************************** + * Capacitor device class, for use as an edge in a circuit graph. + * CapDevice is identical to a {@link ResDevice}, but omits marking + * functionality. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public final class CapDevice { + + final AbstractNode n0,n1; + private final float cap; + + /** Constructs a CapDevice from two node terminals and a resistance. **/ + public CapDevice(final AbstractNode a, final AbstractNode b, float c) { + n0 = a; + n1 = b; + cap = c; + } + + /** Returns the capacitor's value. **/ + public float getValue() { return cap; } + + /** Returns the node terminal that isn't specified. **/ + public AbstractNode nextAfter(final AbstractNode a) { + if (a==n0) return n1; + else return n0; + } + + /***************************************************************** + * Returns true if the two capacitor terminals belong to the same + * resistive subnetwork. (Commonly such capacitance will not be + * included when lumping over the net.) + *****************************************************************/ + public boolean isDegenerate() { + return n0.sameResNet(n1); + } + + /***************************************************************** + * Returns true if the capacitance is considered "good", i.e. if + * it is known that one terminal is always fixed whenever the + * other switches. Conditions for capacitance being good: + *

      + *
    1. Either terminal is Vdd or GND. + *
    2. Terminal node names belong to different signals of an + * apparent 1-of-N channel. + *
    3. Terminal node names belong to the same resistive net. + *
    + * Criterion (2) unfortunately relies on consistent alias naming + * in the extract file (if "channelname.0" is used, then this + * method assumes that "channelname.1", "channelname.e", etc. + * also is used). It also must assume that nodes named + * "channelname.N" (where N is a number) and "channelname.e" + * belong to an asynchronous hanshake channel. + *****************************************************************/ + public boolean isGood() { + if (n0.isGND() || n0.isVdd() || n1.isGND() || n1.isVdd() || + n0.channelBaseName().equals(n1.channelBaseName()) || + n0.sameResNet(n1)) + return true; + else return false; + } + + /***************************************************************** + * Returns the Capacitor corresponding to this CapDevice. + *****************************************************************/ + public Capacitor getCapacitor() { + return new Capacitor(n0.name,n1.name,cap); + } + + /***************************************************************** + * Returns the Capacitor corresponding to this CapDevice, lumping + * the specified node to its resistive subnet name. If lumpedNode + * isn't actually connected to the capacitor, then the lumping + * is undefined. + *****************************************************************/ + public Capacitor getCapacitorLumpedToSubnet(AbstractNode lumpedNode) { + if (n0 == lumpedNode) + return new Capacitor(n0.name.getResistiveSubnetName(),n1.name,cap); + else + return new Capacitor(n0.name,n1.name.getResistiveSubnetName(),cap); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Capacitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Capacitor.java new file mode 100644 index 0000000000..14703e7d93 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Capacitor.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; + +/** + * Class for Capacitor to be used with building an AbstractCircuit or a + * subclass of it + * + * @author Dan Daly + * @version $Date$ + **/ + +public class Capacitor implements CapacitorInterface{ + + /** name of device (optional) **/ + protected final HierName name; + + /** Names of connecting nodes **/ + protected final HierName source, drain; + + /** Capacitance in farads **/ + protected final double capacitance; + + /** + * Constructor. + **/ + public Capacitor(HierName name, + HierName source, + HierName drain, + double capacitance) { + this.name = name; + this.source = source; + this.drain = drain; + this.capacitance = capacitance; + } + + public HierName getName() { return name; } + + public double getCapacitance() { return capacitance; } + + public HierName getSource() { return source;} + + public HierName getDrain() { return drain;} + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapacitorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapacitorInterface.java new file mode 100644 index 0000000000..670a5aa4a9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CapacitorInterface.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; + +/** + * Interface specifying required methods of a capacitor passed to + * AbstractCircuit + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface CapacitorInterface{ + + /** Source Node **/ + HierName getSource(); + + /** Drain Node **/ + HierName getDrain(); + + /** (optional) name of Capacitor, null if not specified **/ + HierName getName(); + + /** Get the Capacitance of the device, in Farads**/ + double getCapacitance(); + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CircuitGraph.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CircuitGraph.java new file mode 100644 index 0000000000..d773e5455d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/CircuitGraph.java @@ -0,0 +1,374 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.aspice.AspiceFile; + + +/********************************************************************** + * Circuit graph data structures and associated data mining algorithms. + * The top-level CircuitGraph class represents an entire (flat) cell + * of transistors, resistors, and capacitors. It can be built either + * from an existing {@link com.avlsi.file.aspice.AspiceCell}, or + * using the addDevice() + * methods from the {@link AbstractCircuit} parent class. + *

    + * Once the CircuitGraph is built, the {@link #identifyNets()} method can be + * used to partition the graph into resistive subnetworks + * ({@link ResistiveSubnet}). The ResistiveSubnet class defines various + * useful mining algorithms, such as identifyVDN() to identify the + * net's virtual driver node, and findMaxGateRC() to determine the + * maximum resistive path on that net and its associated wire and gate + * capacitance. + *

    + * Assumptions made in the code: + *

      + *
    • The drain/gate/source terminals of each Mosfet are all unique + * nodes (although could be part of the same net). This is + * imposed by the {@link MosDevice} marking scheme. + *
    • No cycles in the circuit graph. Resistance calculations will + * be inaccurate if cycles exist. Luckily, from the standpoint of + * conservative layout verification, cycles will cause the resistance + * to be overestimated. + *
    • The virtual driver node identification algorithm assumes that + * All paths from driver nodes meet at a single node, i.e. + *
      + *      Ex 1:                 Ex 2:
      + *             D1  D2                D1  D2
      + *              \  /   D3             \  /  D3
      + *               N1   /                N1   /
      + *                \  /                /  \ /
      + *                VDN                G1   N2
      + *                 |                      |
      + *               G1..GN                 G2..GN
      + *      
      + * D1..D3 are nodes attached to transistor source/drain + * regions, N1..N2 are nodes attached only to parasitic + * capacitors, and G1..GN are nodes attached to + * transistor gates. Example 1 is what the algorithm expects. + * In Example 2, the VDN node might be identified as either + * N1 or N2, but in either case the resistive + * segment between N1 and N2 will be + * overcounted. + *
    • The circuit is flat, i.e. contains no subcells. Any subcells + * will not be considered to be part of the circuit. + *
    + * Features that need to be added: + *
      + *
    • Multiple VDN nodes need to be supported. identifyVDN() + * needs to identify cases where multiple VDN nodes are necessary + * (namely when the aggregate resistance from VDN to drivers is + * above some threshold) and leave the VDN nodes unmerged. + * findMaxGateRC() needs to consider paths from all VDN + * nodes. + *
    + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public class CircuitGraph extends AbstractCircuit { + + static boolean VDN_DEBUG; + static boolean GATERC_DEBUG; + + /*********************************************** + * Enables VDN debugging output. + ***********************************************/ + public static void enableVdnDebug() { + VDN_DEBUG = true; + ResistiveSubnet.VDN_DEBUG = true; + AbstractNode.VDN_DEBUG = true; + } + + /*********************************************** + * Enables GATE_RC debugging output. + ***********************************************/ + public static void enableGateRCDebug() { + GATERC_DEBUG = true; + ResistiveSubnet.GATERC_DEBUG = true; + AbstractNode.GATERC_DEBUG = true; + } + + /*********************************************** + * The number of resistors in the circuit. + ***********************************************/ + private int numResistors; + + /*********************************************** + * The number of capacitors in the circuit. + ***********************************************/ + private int numCapacitors; + + /*********************************************** + * The number of transistors in the circuit. + ***********************************************/ + private int numTransistors; + + /*********************************************** + * HierName-to-Node map for the entire circuit. + ***********************************************/ + private HashMap nodeMap; + + /*********************************************** + * Set of all resistive subnets + ***********************************************/ + private HashSet resSubnets; + + /*********************************************** + * Uninitialized CircuitGraph constructor. + ***********************************************/ + public CircuitGraph(String cellType) { + super(cellType); + nodeMap = new HashMap(); + resSubnets = new HashSet(); + } + + /************************************************************* + * CircuitGraph constructor. Builds a circuit graph from the + * given AspiceFile, ignoring any of its subcells. + *************************************************************/ + public CircuitGraph(AspiceFile aspiceCell) throws Exception + { + super(aspiceCell.getName()); + + // + // Allocate nodeMap and resSubnet structures, + // estimating initial capacity based on the number + // of resistors and transistors in the Aspice cell. + // + nodeMap = new HashMap((int)(aspiceCell.getResistorCount()/0.75),0.75f); + resSubnets = new HashSet((int)(aspiceCell.getTransistorCount()/3/0.75), + 0.75f); + + // + // Add all resistors in circuit to CircuitGraph + // + Iterator it = aspiceCell.getResistors(); + Resistor r; + while (it.hasNext()) addResistor((Resistor)it.next()); + + // + // Add all capacitors to the CircuitGraph + // + it = aspiceCell.getCapacitors(); + Capacitor c; + while (it.hasNext()) addCapacitor((Capacitor)it.next()); + + // + // Add all transistors to the CircuitGraph + // + it = aspiceCell.getTransistors(); + Transistor t; + while (it.hasNext()) addTransistor((Transistor)it.next()); + } + + /***************************************************************** + * Add a resistor to the circuit graph + *****************************************************************/ + public void addResistor(ResistorInterface r) + { + AbstractNode n0 = (AbstractNode)nodeMap.get(r.getSource()); + if (n0 == null) { + n0 = new LumpedNode(r.getSource()); + nodeMap.put(r.getSource(),n0); + } + + AbstractNode n1 = (AbstractNode)nodeMap.get(r.getDrain()); + if (n1 == null) { + n1 = new LumpedNode(r.getDrain()); + nodeMap.put(r.getDrain(),n1); + } + + ResDevice rd = new ResDevice(n0,n1,(float)(1/r.getConductance())); + n0.connectRes(rd); + n1.connectRes(rd); + + numResistors++; + } + + /***************************************************************** + * Add a capacitor to the circuit graph + *****************************************************************/ + public void addCapacitor(CapacitorInterface c) + { + AbstractNode n0 = (AbstractNode)nodeMap.get(c.getSource()); + if (n0 == null) { + n0 = new LumpedNode(c.getSource()); + nodeMap.put(c.getSource(),n0); + } + + AbstractNode n1 = (AbstractNode)nodeMap.get(c.getDrain()); + if (n1 == null) { + n1 = new LumpedNode(c.getDrain()); + nodeMap.put(c.getDrain(),n1); + } + + CapDevice cd = new CapDevice(n0,n1,(float)c.getCapacitance()); + n0.connectCap(cd); + n1.connectCap(cd); + + numCapacitors++; + } + + /***************************************************************** + * Add a (MOSFET) transistor to the circuit graph + *****************************************************************/ + public void addTransistor(TransistorInterface t) + { + AbstractNode d = (AbstractNode)nodeMap.get(t.getDrain()); + if (d == null) { + d = new LumpedNode(t.getDrain()); + nodeMap.put(t.getDrain(),d); + } + + AbstractNode g = (AbstractNode)nodeMap.get(t.getGate()); + if (g == null) { + g = new LumpedNode(t.getGate()); + nodeMap.put(t.getGate(),g); + } + + AbstractNode s = (AbstractNode)nodeMap.get(t.getSource()); + if (s == null) { + s = new LumpedNode(t.getSource()); + nodeMap.put(t.getSource(),s); + } + + MosDevice m = new MosDevice(d,g,s,t.getType(),t.getWidth(), + t.getLength()); + d.connectMos(m); + g.connectMos(m); + s.connectMos(m); + + numTransistors++; + } + + /***************************************************************** + * Add a diode to the circuit graph (unimplemented). + *****************************************************************/ + public void addDiode(DiodeInterface d) {} + + /***************************************************************** + * Returns the number of resistors in the circuit. + *****************************************************************/ + public int getResistorCount() { return numResistors; } + + /***************************************************************** + * Returns the number of capacitors in the circuit. + *****************************************************************/ + public int getCapacitorCount() { return numCapacitors; } + + /***************************************************************** + * Returns the number of transistors in the circuit. + *****************************************************************/ + public int getTransistorCount() { return numTransistors; } + + /***************************************************************** + * Returns the number of diodes in the circuit. + *****************************************************************/ + public int getDiodeCount() { return 0; } + + /***************************************************************** + * Searches the graph for all independent resistive networks. + * For each of these, tallies total capacitance and identifies + * driver and gate nodes. + *****************************************************************/ + public void identifyNets() + { + HashSet uncoveredNodes = new HashSet(nodeMap.values()); + while (!uncoveredNodes.isEmpty()) { + Iterator it = uncoveredNodes.iterator(); + AbstractNode base = (AbstractNode)it.next(); + ResistiveSubnet rsn = new ResistiveSubnet(base); + base.buildResistiveSubnet(rsn,uncoveredNodes); + // + // Add this subnet to the resSubnets set as long as it + // isn't GND,Vdd,_SReset,_PReset, and contains at least + // one resistor. + // + if (!rsn.getCanonicalNameAsString().equals("_SReset") && + !rsn.getCanonicalNameAsString().equals("_SReset!") && + !rsn.getCanonicalNameAsString().equals("_PReset") && + !rsn.getCanonicalNameAsString().equals("_PReset!") && + !rsn.getCanonicalNameAsString().equals("GND") && + !rsn.getCanonicalNameAsString().equals("Vdd") && + !rsn.isDegenerate()) + resSubnets.add(rsn); + } + clearMarks(); + } + + /***************************************************************** + * Returns an iterator over all the resistive subnets in the + * circuit graph. For best results (i.e. non-null), should be + * called after calling {@link #identifyNets()}. + *****************************************************************/ + public Iterator getResistiveSubnets() { + return resSubnets.iterator(); + } + + /***************************************************************** + * Searches the graph for all nodes resistively connected to hn. + * Return ArrayList contains ResDevice types. + * + public ArrayList findResistiveNetwork(final HierName hn) throws Exception + { + Node n = (Node)nodeMap.get(hn); + if (n == null) throw new Exception("Node "+hn.getAsString('.') + +" doesn't exist."); + ArrayList reslist = new ArrayList(); + n.resDepthFirstSearch(reslist); + clearMarks(); + return reslist; + } + *****************************************************************/ + + /************************************************* + * Clears all node marks throughout the net graph. + *************************************************/ + public void clearMarks() + { + // Note: numMarks argument to clearAllMarks will eventually + // require careful consideration... + Iterator it = nodeMap.values().iterator(); + while (it.hasNext()) ((AbstractNode)it.next()).clearAllMarks(2); + } + + /************************************************* + * Static subcircuit repository nested subclass. + *************************************************/ + public static class Repository extends AbstractCircuit.Repository { + /** + * CircuitGraph generator method. + **/ + protected AbstractCircuit newCircuitGenerator(final String cellType) { + return new CircuitGraph(cellType); + } + } + + /***************************************************************** + * Class to represent exceptions in CircuitGraph processing. + *****************************************************************/ + public static final class Exception extends java.lang.Exception { + public Exception(final String message) { + super(message); + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ConjunctivePath.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ConjunctivePath.java new file mode 100644 index 0000000000..8ba7b18efb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ConjunctivePath.java @@ -0,0 +1,159 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Iterator; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.util.debug.Debug; + +/** + * Transistor conjunctive pull-up/pull-down path. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **/ +public final class ConjunctivePath { + + public static final int SUPPLY = -1; + + /** + * Class to represent a single transistor term in a + * conjunctive driver path. Includes gate node name + * (HierName) and the transistor type (NFET/PFET). + * Supply end node is indicated by a type of -1. + * Hopefully this doesn't ever conflict with + * DeviceTypes.N_TYPE or DeviceTypes.P_TYPE. + **/ + public static final class Term { + + public final HierName node; + public final int type; + + public Term(final HierName n, int t) { + node = n; type = t; + } + + // + // Object overrides: + // + public boolean equals(Object o) { + return o instanceof Term && equals((Term) o); + } + + public boolean equals(Term t) { + return node.equals(t.node) && type == t.type; + } + + public int hashCode() { + return (node.hashCode()<<2) + type + 1; + } + } + + private final ArrayList terms; + private boolean is_feedback; + + /** Empty constructor. **/ + public ConjunctivePath() { + terms = new ArrayList(); + } + + /** Constructor initialized to equal the passed ConjunctivePath. **/ + public ConjunctivePath(ConjunctivePath p) { + terms = new ArrayList(p.terms); + } + + /** Adds a transistor term to the conjunctive path **/ + public void addTerm(final Term t) { + terms.add(t); + } + + /** Adds a transistor term to the path, from gate name + type **/ + public void addTerm(final HierName gate, int type) { + terms.add(new Term(gate,type)); + } + + /** Returns the list of conjunctive transistor terms **/ + public ArrayList getTerms() { return terms; } + + public int getNumTerms() { return terms.size(); } + + public boolean drivesUp() { + Term t = (Term) terms.get(terms.size()-1); + return t.node.isVdd(); + } + + public boolean drivesDown() { + Term t = (Term) terms.get(terms.size()-1); + return t.node.isGND(); + } + + public void printToStream(final PrintStream pw) { + pw.println(getAsString()); + } + + public String getAsString() { + StringBuffer sb = new StringBuffer(); + Iterator it = terms.iterator(); + for (int i=terms.size()-1; i>=0; i--) { + Term t = (Term) terms.get(i); + if (t.type == DeviceTypes.N_TYPE) + sb.append(t.node.getAsString('.')); + else if (t.type == DeviceTypes.P_TYPE) + sb.append("~" + t.node.getAsString('.')); + else + sb.append(t.node.getAsString('.')); + if (i>0) sb.append(" - "); + } + if (is_feedback) sb.append(" [staticizer]"); + return sb.toString(); + } + + /** Sets the path's feedback state. (Indicates staticizer.) **/ + void setFeedback() { is_feedback = true; } + + /** Clears the path's feedback state. **/ + void clearFeedback() { is_feedback = false; } + + /** Gets the path's feedback state. (Indicates staticizer.) **/ + public boolean isFeedbackPath() { return is_feedback; } + + // + // Object overrides: + // + + /** equals method override to avoid redundancies in disjunctive set **/ + public boolean equals(Object o) { + return o instanceof ConjunctivePath && equals((ConjunctivePath) o); + } + + public boolean equals(ConjunctivePath p) { + if (p.terms.size() != terms.size()) return false; + for (int i=0; i + * Currently, parasitic capacitance is included only on the culled + * resistive subnets. The parasitic capacitance of all internal nodes + * in the subnets' pull-up/pull-down networks are not included. Also, + * the resistance of these internal nodes is discarded (all nodes + * that are resistively connected within the pull-up/pull-down networks + * are collapsed to a single node). + *

    + * The set of nets to cull for consists of HierNames as generated by + * HierName.getResistiveSubnetName(). + *

    + * Assumptions: + *

      + *
    • The extractor consistently names nodes within nets of + * interest as 'name:xxx' where 'xxx' can be any string. + *
    • Nodes within transistor pull-down/pull-up networks + * (usually unlabelled in the layout) are also named + * consistently as 'name:xxx', for any resistive internal + * subnet. + *
    + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public class CullingCircuitGraph extends AbstractCircuit { + + static boolean ADDRES_DEBUG; + + /*********************************************** + * The number of resistors in the circuit + * (only connected to culled nodes). + ***********************************************/ + private int numResistors; + + /*********************************************** + * The number of capacitors in the circuit + * (connected to culled nodes). + ***********************************************/ + private int numCapacitors; + + /*********************************************** + * The number of transistors in the circuit. + ***********************************************/ + private int numTransistors; + + /*********************************************** + * The number of diodes in the circuit + * (connected to culled nodes). + ***********************************************/ + private int numDiodes; + + /*********************************************** + * HierName-to-Node map for the entire circuit. + ***********************************************/ + private HashMap nodeMap; + + + + /*********************************************** + * Specified Set of HierNames to cull. + ***********************************************/ + private Set cullNets; + + /***************************************************************** + * Uninitialized CullingCircuitGraph constructor. + * @param cellType the AbstractCircuit cell type. + * @param culledNets a list of nets (specified by canonical + * HierName) to cull during parsing. + *****************************************************************/ + public CullingCircuitGraph(final String cellType, + final Set cullNets) { + super(cellType); + nodeMap = new HashMap(); + + this.cullNets = new HashSet(cullNets); + } + + /***************************************************************** + * Adds a resistor to the circuit graph, if one of its terminals + * belongs to the cullNets set. + *****************************************************************/ + public void addResistor(ResistorInterface r) + { + HierName subnetName0 = r.getSource().getResistiveSubnetName(); + HierName subnetName1 = r.getDrain().getResistiveSubnetName(); + if (cullNets.contains(subnetName0) || + cullNets.contains(subnetName1)) { + if (ADDRES_DEBUG) + System.err.println("Adding res: "+ + r.getSource().getAsString('.')+" "+ + r.getDrain().getAsString('.')); + + AbstractNode n0 = (AbstractNode)nodeMap.get(r.getSource()); + if (n0 == null) { + n0 = new Node(r.getSource()); + nodeMap.put(r.getSource(),n0); + } + + AbstractNode n1 = (AbstractNode)nodeMap.get(r.getDrain()); + if (n1 == null) { + n1 = new Node(r.getDrain()); + nodeMap.put(r.getDrain(),n1); + } + + ResDevice rd = new ResDevice(n0,n1,(float)(1/r.getConductance())); + n0.connectRes(rd); + n1.connectRes(rd); + + numResistors++; + } + } + + /***************************************************************** + * Adds a capacitor to the circuit graph, if one of its terminals + * belongs to the cullNets set. + *****************************************************************/ + public void addCapacitor(CapacitorInterface c) + { + boolean culls = + cullNets.contains(c.getSource().getResistiveSubnetName()); + boolean culld = + cullNets.contains(c.getDrain().getResistiveSubnetName()); + + if (culls || culld) { + + AbstractNode n0 = (AbstractNode)nodeMap.get(c.getSource()); + AbstractNode n1 = (AbstractNode)nodeMap.get(c.getDrain()); + + if (n0 == null) { + if (culls) + n0 = new Node(c.getSource()); + else + n0 = new DriverNode(c.getSource()); + nodeMap.put(c.getSource(),n0); + } + + if (n1 == null) { + if (culld) + n1 = new Node(c.getDrain()); + else + n1 = new DriverNode(c.getDrain()); + nodeMap.put(c.getDrain(),n1); + } + + CapDevice cd = new CapDevice(n0,n1,(float)c.getCapacitance()); + n0.connectCap(cd); + n1.connectCap(cd); + + numCapacitors++; + } + } + + /***************************************************************** + * Adds a (MOSFET) transistor to the circuit graph. + *****************************************************************/ + public void addTransistor(TransistorInterface t) + { + AbstractNode d,s,g; + HierName subnetName = t.getGate().getResistiveSubnetName(); + boolean cullg = false; + + if (cullNets.contains(subnetName)) { + cullg = true; + g = (AbstractNode)nodeMap.get(t.getGate()); + if (g == null) { + g = new Node(t.getGate()); + nodeMap.put(t.getGate(),g); + } + } + else { + g = (AbstractNode)nodeMap.get(subnetName); + if (g == null) { + g = new DriverNode(subnetName); + nodeMap.put(subnetName,g); + } + } + + subnetName = t.getDrain().getResistiveSubnetName(); + + if (cullNets.contains(subnetName)) { + d = (AbstractNode)nodeMap.get(t.getDrain()); + if (d == null) { + d = new Node(t.getDrain()); + nodeMap.put(t.getDrain(),d); + } + } + else { + d = (AbstractNode)nodeMap.get(subnetName); + if (d == null) { + d = new DriverNode(subnetName); + nodeMap.put(subnetName,d); + } + } + + subnetName = t.getSource().getResistiveSubnetName(); + + if (cullNets.contains(subnetName)) { + s = (AbstractNode)nodeMap.get(t.getSource()); + if (s == null) { + s = new Node(t.getSource()); + nodeMap.put(t.getSource(),s); + } + } + else { + s = (AbstractNode)nodeMap.get(subnetName); + if (s == null) { + s = new DriverNode(subnetName); + nodeMap.put(subnetName,s); + } + } + + MosDevice m = new MosDevice(d,g,s,t.getType(),t.getWidth(), + t.getLength()); + d.connectMos(m); + s.connectMos(m); + if (cullg) g.connectMos(m); + + numTransistors++; + } + + /***************************************************************** + * Adds a diode to the circuit graph. + * Assumes that one of the diode's terminals is connected to + * either Vdd or GND. + *****************************************************************/ + public void addDiode(DiodeInterface d) + { + HierName subnetName = d.getSource().getResistiveSubnetName(); + AbstractNode n; + if (cullNets.contains(subnetName)) { + n = (AbstractNode)nodeMap.get(d.getSource()); + if (n == null) { + n = new Node(d.getSource()); + nodeMap.put(d.getSource(),n); + } + } + else { + n = (AbstractNode)nodeMap.get(subnetName); + if (n == null) { + n = new DriverNode(subnetName); + nodeMap.put(subnetName,n); + } + } + if (n.isGND() || n.isVdd()) { + subnetName = d.getDrain().getResistiveSubnetName(); + if (cullNets.contains(subnetName)) { + n = (AbstractNode)nodeMap.get(d.getDrain()); + if (n == null) { + n = new Node(d.getDrain()); + nodeMap.put(d.getDrain(),n); + } + } + else { + n = (AbstractNode)nodeMap.get(subnetName); + if (n == null) { + n = new DriverNode(subnetName); + nodeMap.put(subnetName,n); + } + } + } + + DiodeDevice dd = new DiodeDevice(n,d.getType(), + (float)d.getWidth(), + (float)d.getLength(), + (float)d.getArea(), + (float)d.getPerimeter()); + n.connectDiode(dd); + numDiodes++; + } + + /***************************************************************** + * Returns the number of resistors in the circuit. + *****************************************************************/ + public int getResistorCount() { return numResistors; } + + /***************************************************************** + * Returns the number of capacitors in the circuit. + *****************************************************************/ + public int getCapacitorCount() { return numCapacitors; } + + /***************************************************************** + * Returns the number of transistors in the circuit. + *****************************************************************/ + public int getTransistorCount() { return numTransistors; } + + /***************************************************************** + * Returns the number of diodes in the circuit. + *****************************************************************/ + public int getDiodeCount() { return numDiodes; } + + /***************************************************************** + * Generates a TestSubnet for the specified culled net. + * Lumps all dangling parasitic capacitors to GND, so this is + * not appropriate for capacitive coupling tests. + * @return An initialized TestSubnet if subnetName was found + * in the circuit graph. Otherwise, null. + *****************************************************************/ + public TestSubnet getTestSubnet(final HierName subnetName) + { + TestSubnet subnet = new TestSubnet(subnetName, getType() + "." + + subnetName.getResistiveSubnetString()); + AbstractNode base = (AbstractNode)nodeMap.get(subnetName); + // + // If a node with name equal to 'subnetName', look for + // nodes with names equal to 'subnetBaseName:N', where + // 'subnetBaseName' is the resisitve subnet basename and + // N is a number between 0 and 1000. + // + String suffixBase = subnetName.getSuffixString(); + int idx = suffixBase.indexOf(':'); + if (idx != -1) suffixBase = suffixBase.substring(0,idx); + for (int i=0; i <= 1000 && base == null; i++) { + String suffix = suffixBase + ":" + String.valueOf(i); + HierName name = HierName.makeSiblingName(subnetName,suffix); + base = (AbstractNode) nodeMap.get(name); + } + if (base instanceof Node) + base.buildTestSubnet(subnet); + else subnet = null; + return subnet; + } + + /************************************************* + * Clears all node marks throughout the net graph. + *************************************************/ + public void clearMarks() + { + // Note: numMarks argument to clearAllMarks will eventually + // require careful consideration... + Iterator it = nodeMap.values().iterator(); + while (it.hasNext()) ((AbstractNode)it.next()).clearAllMarks(2); + } + + /************************************************* + * Static subcircuit repository nested subclass. + *************************************************/ + public static class Repository extends AbstractCircuit.Repository { + /** culling set **/ + private final Set cullSet; + + /** Constructor w/ cullSet initialization **/ + public Repository(final Set cullNetSet) { + super(); + cullSet = cullNetSet; + } + + /** Constructor w/out cullSet initialization **/ + public Repository() { + super(); + cullSet = new HashSet(); + } + + /** + * CircuitGraph generator method. + **/ + protected AbstractCircuit newCircuitGenerator(final String cellType) { + return new CullingCircuitGraph(cellType,cullSet); + } + } + + /***************************************************************** + * Class to represent exceptions in CircuitGraph processing. + *****************************************************************/ + public static final class Exception extends java.lang.Exception { + public Exception(final String message) { + super(message); + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Diode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Diode.java new file mode 100644 index 0000000000..8b56397962 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Diode.java @@ -0,0 +1,83 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; +/** + * Class for Diodes used by AbstractCircuit and its subclasses + * + * @author Dan Daly + * @version $Date$ + **/ + +public class Diode implements DiodeInterface{ + + /** name of device (optional) **/ + protected final HierName name; + + /** Names of connecting nodes **/ + protected final HierName source, drain; + + /** Type of the Diode **/ + protected final int type; + + /** Width of the diode **/ + protected final double width; + + /** Length of the diode **/ + protected final double length; + + /** Area of the diode **/ + protected final double area; + + /** Perimeter of the diode **/ + protected final double perimeter; + + /** + * Constructor. + **/ + public Diode(HierName name, + int type, + HierName source, + HierName drain, + double width, + double length, + double area, + double perimeter) { + this.name = name; + this.source = source; + this.drain = drain; + this.type = type; + this.width = width; + this.length = length; + this.area = area; + this.perimeter = perimeter; + } + + public HierName getName() { return name; } + + public int getType() { return type; } + + public double getWidth() { return width; } + + public double getLength() { return length; } + + public double getArea() { return area; } + + public double getPerimeter() { return perimeter; } + + public HierName getSource() { return source;} + + public HierName getDrain() { return drain;} +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeDevice.java new file mode 100644 index 0000000000..77ac860cf4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeDevice.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import com.avlsi.file.aspice.Diode; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; + +/********************************************************************** + * Diode device class, for use as an edge in a circuit graph. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public final class DiodeDevice { + + /** Node attached to the associated transistor's source/drain **/ + final AbstractNode node; + + /** Width of the associated transistor in meters. **/ + private final float width; + + /** Length of the associated transistor in meters. **/ + private final float length; + + /** Area of the diode in square meters. **/ + private final float area; + + /** Perimeter of the diode in square meters. **/ + private final float perim; + + /** Type of diode, N_TYPE or P_TYPE. **/ + private final int type; + + /** + * Constructs a DiodeDevice from two AbstractNode terminals and + * device parameters. + *
    +     * "source"               "source"
    +     *   node __|\|__ Vdd       node __|/|__ GND
    +     *          |/|  (P_TYPE)          |\|  (N_TYPE)
    +     * 
    + **/ + DiodeDevice(final AbstractNode n, int t, float w, float l, float a, float p) + { + if (t != DeviceTypes.N_TYPE && t != DeviceTypes.P_TYPE) + throw new IllegalArgumentException("Bad diode type: "+t); + + this.node = n; + this.width = w; + this.length = l; + this.area = a; + this.perim = p; + this.type = t; + } + + public Diode getDiode() { + HierName drain = (type == DeviceTypes.N_TYPE) ? + HierName.makeHierName("GND!") : + HierName.makeHierName("Vdd!"); + return new Diode(type,node.name,drain,width,length,area,perim); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeInterface.java new file mode 100644 index 0000000000..3bf60b8e7e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DiodeInterface.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; + +/** + * Class for ... + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface DiodeInterface { + /** Get Diode Type **/ + int getType(); + /** Get the width of the transistor **/ + double getWidth(); + /** Get the length of the transistor **/ + double getLength(); + /** (optional) name of Diode, null if not specified **/ + HierName getName(); + + /** Source Node **/ + HierName getSource(); + /** Drain Node **/ + HierName getDrain(); + + /** Area of Diode **/ + double getArea(); + /** Perimeter of Diode **/ + double getPerimeter(); + + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DriverNode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DriverNode.java new file mode 100644 index 0000000000..d08b939048 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/DriverNode.java @@ -0,0 +1,133 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.avlsi.file.common.HierName; + +/********************************************************************* + * Circuit graph driver node class. Includes a list of driver + * transistors attached to this node and associated diodes. + * + * @author Mike Davies + * @version $Revision$ $Date$ + *********************************************************************/ +final class DriverNode extends AbstractNode { + + private final ArrayList driverList = new ArrayList(); + private final ArrayList diodeList = new ArrayList(); + + /** + * Constructor. Takes a node name. Constructs the AbstractNode + * base class with two marks. + **/ + DriverNode(final HierName name) { + super(name,1); + } + + // + // Abstract method implementations + // + + /** + * Connect a resistor to the node. + * Unimplemented in DegenerateNode. + **/ + void connectRes(final ResDevice r) {} + + /** + * Connect a capacitor to the node. + * Unimplmented in DegenerateNode. + ***/ + void connectCap(final CapDevice c) {} + + /** + * Connect a transistor to the node. For DriverNode, only retains + * the MosDevice if it's attached to the node by its source or + * drain terminal. + ***/ + void connectMos(final MosDevice m) { + if (m.sourceNode() == this || m.drainNode() == this) + driverList.add(m); + } + + /** Connects a diode to the node. **/ + void connectDiode(final DiodeDevice d) { + diodeList.add(d); + } + + /** + * Returns iterator over all resistors connected to this node. + * Null for DriverNode. + **/ + public Iterator getResDevices() { return null; } + + /** + * Returns iterator over all MosDevices connected to this node. + * For DriverNode, includes only those MosDevices that have their + * source/drain terminals attached to the node. + **/ + public Iterator getMosDevices() { return driverList.iterator(); } + + /** Returns an iterator over all CapDevices. Null for DriverNode. **/ + public Iterator getCapDevices() { return null; } + + /** Returns an iterator over all DiodeDevices. **/ + public Iterator getDiodeDevices() { return diodeList.iterator(); } + + /** Returns an iterator over all + + /** Clear all marks in attached device edges **/ + void clearDeviceMarks() {} + + /** Returns total wire capacitance lumped to this node **/ + public float wireCap() { return 0.0f; } + + /** Returns total gate capacitance lumped to this node **/ + public float gateCap() { return 0.0f; } + + /** + * Returns total "good" capacitance (lumped to a fixed node + * relative to this one). + **/ + public float goodCap() { return 0.0f; } + + /** + * Returns total "bad" capacitance (lumped to nodes that could + * transition during this node's transition). + **/ + public float badCap() { return 0.0f; } + + /** + * Returns number of (wire) Capacitors attached to this node . + * For DriverNode, this is always 0. + **/ + public int numCap() { return 0; } + + /** Returns number of resistors attached to this node **/ + public int numRes() { return 0; } + + /** + * Returns number of Mosfet attached to this node via source/drain. + **/ + public int numDrivers() { return driverList.size(); } + + /** + * Returns number of gates attached to this node + * For DriverNode, this is always 0. + **/ + public int numGates() { return 0; } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedNode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedNode.java new file mode 100644 index 0000000000..e3ac6b7105 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedNode.java @@ -0,0 +1,154 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.avlsi.file.common.HierName; + +/********************************************************************** + * Circuit graph lumped node class. Lumps all gate and wire + * capacitance attached to the node. Keeps a count of the number of + * connected source/drain terminals. Maintains a list of resistive + * edges. This node class is intended to contain the minimal amount + * of data to allow resistive subnet evaluation and maximum resistive + * path analysis. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +final class LumpedNode extends AbstractNode { + + private final ArrayList resList = new ArrayList(); + private float wireCap; + private float goodCap; + private float gateCap; + private int numDrivers; + + /** + * Constructor. Takes a node name. Constructs the AbstractNode + * base class with two marks. + **/ + LumpedNode(final HierName name) { + super(name,2); + } + + // + // Abstract method implementations + // + + /** Connect a resistor to the node. **/ + void connectRes(final ResDevice r) { + resList.add(r); + } + + /** + * Connect a capacitor to the node. Accumulates the + * wire cap and "good" cap. + ***/ + void connectCap(final CapDevice c) { + if (!c.isDegenerate()) { + wireCap += c.getValue(); + // Note: What effect does degenerate capacitance actually + // have? Is it maybe perfect "good" cap (always switching + // in same direction)? For now, it isn't included in the + // good cap sum. + if (c.isGood()) goodCap += c.getValue(); + } + } + + /** + * Connect a transistor to the node. If this node is attached + * to the gate, accumulates the gate cap. Otherwise, increments + * the driver count as long as the transistor is non-weak. + ***/ + void connectMos(final MosDevice m) { + if (m.gateNode() == this) gateCap += m.gateCap(); + else if (!m.isWeak()) numDrivers++; + } + + /** Connects a diode to the node. Unimplemented for LumpedNode. **/ + void connectDiode(final DiodeDevice d) {} + + /** Return iterator over all resistors connected to this node **/ + public Iterator getResDevices() { + return resList.iterator(); + } + + /** + * Returns an iterator over all capacitors connected to this node. + * Null for LumpedNode. + **/ + public Iterator getCapDevices() { return null; } + + /** + * Returns an iterator over all diodes connected to this node. + * Null for LumpedNode. + **/ + public Iterator getDiodeDevices() { return null; } + + /** Return list of MosDevices devices. Null for LumpedNode. **/ + public Iterator getMosDevices() { return null; } + + /** Clear all marks in attached device edges **/ + void clearDeviceMarks() { + Iterator it = resList.iterator(); + while (it.hasNext()) { + ResDevice rd = (ResDevice)it.next(); + rd.clearMark(); + } + } + + /** Returns total wire capacitance lumped to this node **/ + public float wireCap() { return wireCap; } + + /** Returns total gate capacitance lumped to this node **/ + public float gateCap() { return gateCap; } + + /** + * Returns total "good" capacitance (lumped to a fixed node + * relative to this one). + **/ + public float goodCap() { return goodCap; } + + /** + * Returns total "bad" capacitance (lumped to nodes that could + * transition during this node's transition). + **/ + public float badCap() { return wireCap-goodCap; } + + /** + * Returns number of (wire) Capacitors attached to this node + * For LumpedNode, this is always 1 if wireCap > 0.0; 0 + * otherwise. + **/ + public int numCap() { return (wireCap > 0.0) ? 1 : 0; } + + /** Returns number of resistors attached to this node **/ + public int numRes() { return resList.size(); } + + /** + * Returns number of Mosfet attached to this node via source/drain + * For LumpedNode, the number only includes non-weak drivers, as + * defined by {@link MosDevice#isWeak()}. + **/ + public int numDrivers() { return numDrivers; } + + /** + * Returns number of gates attached to this node + * For LumpedNode, this is 1 if gateCap > 0.0; 0 otherwise. + **/ + public int numGates() { return (gateCap > 0.0) ? 1 : 0; } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedRCGraph.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedRCGraph.java new file mode 100644 index 0000000000..7ab223fc3b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/LumpedRCGraph.java @@ -0,0 +1,401 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.aspice.Resistor; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.file.aspice.Diode; +import com.avlsi.file.common.Capacitor; + +/********************************************************************** + * Lumped RC circuit graph data structures. The top-level + * LumpedRCGraph class represents an entire (flat) cell of + * transistors, resistors, and capacitors. The underlying LumpedNode + * class lumps wire cap and gate cap, and lumps all source/drain + * regions into an integer corresponding to the number of non-weak + * drivers connected to the node. + *

    + * The LumpedRCGraph can be built either from an existing + * {@link com.avlsi.file.aspice.AspiceCell}, or using the + * addDevice() methods from the + * {@link AbstractCircuit} parent class. + *

    + * Once the LumpedRCGraph is built, the + * {@link #identifyNets(com.avlsi.circuit.LumpedRCGraph.CallbackInterface)} + * method can be used to partition the graph into resistive subnetworks + * ({@link ResistiveSubnet}). The ResistiveSubnet class defines + * various useful mining algorithms, such as identifyVDN() to + * identify the net's virtual driver node, and + * findMaxGateRC() to determine the maximum resistive path on + * that net and its associated wire and gate capacitance. + *

    + * Assumptions made in the code: + *

      + *
    • The drain/gate/source terminals of each Mosfet are all unique + * nodes (although could be part of the same net). This is + * imposed by the {@link MosDevice} marking scheme. + *
    • No cycles in the circuit graph. Resistance calculations will + * be inaccurate if cycles exist. Luckily, from the standpoint of + * conservative layout verification, cycles will cause the resistance + * to be overestimated. + *
    • The virtual driver node identification algorithm assumes that + * All paths from driver nodes meet at a single node, i.e. + *
      + *      Ex 1:                 Ex 2:
      + *             D1  D2                D1  D2
      + *              \  /   D3             \  /  D3
      + *               N1   /                N1   /
      + *                \  /                /  \ /
      + *                VDN                G1   N2
      + *                 |                      |
      + *               G1..GN                 G2..GN
      + *      
      + * D1..D3 are nodes attached to transistor source/drain + * regions, N1..N2 are nodes attached only to parasitic + * capacitors, and G1..GN are nodes attached to + * transistor gates. Example 1 is what the algorithm expects. + * In Example 2, the VDN node might be identified as either + * N1 or N2, but in either case the resistive + * segment between N1 and N2 will be + * overcounted. + *
    • The circuit is flat, i.e. contains no subcells. Any subcells + * will not be considered to be part of the circuit. + *
    + * Features that need to be added: + *
      + *
    • Multiple VDN nodes need to be supported. identifyVDN() + * needs to identify cases where multiple VDN nodes are necessary + * (namely when the aggregate resistance from VDN to drivers is + * above some threshold) and leave the VDN nodes unmerged. + * findMaxGateRC() needs to consider paths from all VDN + * nodes. + *
    + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public class LumpedRCGraph extends AbstractCircuit { + + static boolean VDN_DEBUG; + static boolean GATERC_DEBUG; + + /***************************************************************** + * Update callback interface for identifyNets(), used for updating + * UI progress meter. + *****************************************************************/ + public interface CallbackInterface { + void identifyNetsUpdate(int numNets, final Set uncoveredNodes); + } + + /*********************************************** + * Enables VDN debugging output. + ***********************************************/ + public static void enableVdnDebug() { + VDN_DEBUG = true; + ResistiveSubnet.VDN_DEBUG = true; + AbstractNode.VDN_DEBUG = true; + } + + /*********************************************** + * Enables GATE_RC debugging output. + ***********************************************/ + public static void enableGateRCDebug() { + GATERC_DEBUG = true; + ResistiveSubnet.GATERC_DEBUG = true; + AbstractNode.GATERC_DEBUG = true; + } + + /*********************************************** + * The number of resistors in the circuit. + ***********************************************/ + private int numResistors; + + /*********************************************** + * The number of capacitors in the circuit. + ***********************************************/ + private int numCapacitors; + + /*********************************************** + * The number of transistors in the circuit. + ***********************************************/ + private int numTransistors; + + /*********************************************** + * HierName-to-Node map for the entire circuit. + ***********************************************/ + private HashMap nodeMap; + + /*********************************************** + * Set of all resistive subnets + ***********************************************/ + private HashSet resSubnets; + + /*********************************************** + * Uninitialized LumpedRCGraph constructor. + ***********************************************/ + public LumpedRCGraph(String cellType) { + super(cellType); + nodeMap = new HashMap(); + resSubnets = new HashSet(); + } + + /************************************************************* + * LumpedRCGraph constructor. Builds a lumped RC circuit + * graph from the given AspiceFile, ignoring any of its + * subcells. + *************************************************************/ + public LumpedRCGraph(AspiceFile aspiceCell) throws Exception + { + super(aspiceCell.getName()); + + // + // Allocate nodeMap and resSubnet structures, + // estimating initial capacity based on the number + // of resistors and transistors in the Aspice cell. + // + nodeMap = new HashMap((int)(aspiceCell.getResistorCount()/0.75),0.75f); + resSubnets = new HashSet((int)(aspiceCell.getTransistorCount()/3/0.75), + 0.75f); + + // + // Add all resistors in circuit + // + Iterator it = aspiceCell.getResistors(); + Resistor r; + while (it.hasNext()) addResistor((Resistor)it.next()); + + // + // Add all capacitors + // + it = aspiceCell.getCapacitors(); + Capacitor c; + while (it.hasNext()) addCapacitor((Capacitor)it.next()); + + // + // Add all transistors + // + it = aspiceCell.getTransistors(); + Transistor t; + while (it.hasNext()) addTransistor((Transistor)it.next()); + } + + /***************************************************************** + * Add a resistor to the circuit graph + *****************************************************************/ + public void addResistor(ResistorInterface r) + { + AbstractNode n0 = (AbstractNode)nodeMap.get(r.getSource()); + if (n0 == null) { + n0 = new LumpedNode(r.getSource()); + nodeMap.put(r.getSource(),n0); + } + + AbstractNode n1 = (AbstractNode)nodeMap.get(r.getDrain()); + if (n1 == null) { + n1 = new LumpedNode(r.getDrain()); + nodeMap.put(r.getDrain(),n1); + } + + ResDevice rd = new ResDevice(n0,n1,(float)(1/r.getConductance())); + n0.connectRes(rd); + n1.connectRes(rd); + + numResistors++; + } + + /***************************************************************** + * Add a capacitor to the circuit graph + *****************************************************************/ + public void addCapacitor(CapacitorInterface c) + { + AbstractNode n0 = (AbstractNode)nodeMap.get(c.getSource()); + if (n0 == null) { + n0 = new LumpedNode(c.getSource()); + nodeMap.put(c.getSource(),n0); + } + + AbstractNode n1 = (AbstractNode)nodeMap.get(c.getDrain()); + if (n1 == null) { + n1 = new LumpedNode(c.getDrain()); + nodeMap.put(c.getDrain(),n1); + } + + CapDevice cd = new CapDevice(n0,n1,(float)c.getCapacitance()); + n0.connectCap(cd); + n1.connectCap(cd); + + numCapacitors++; + } + + /***************************************************************** + * Add a (MOSFET) transistor to the circuit graph + *****************************************************************/ + public void addTransistor(TransistorInterface t) + { + AbstractNode d = (AbstractNode)nodeMap.get(t.getDrain()); + if (d == null) { + d = new LumpedNode(t.getDrain()); + nodeMap.put(t.getDrain(),d); + } + + AbstractNode g = (AbstractNode)nodeMap.get(t.getGate()); + if (g == null) { + g = new LumpedNode(t.getGate()); + nodeMap.put(t.getGate(),g); + } + + AbstractNode s = (AbstractNode)nodeMap.get(t.getSource()); + if (s == null) { + s = new LumpedNode(t.getSource()); + nodeMap.put(t.getSource(),s); + } + + MosDevice m = new MosDevice(d,g,s,t.getType(),t.getWidth(), + t.getLength()); + d.connectMos(m); + g.connectMos(m); + s.connectMos(m); + + numTransistors++; + } + + /***************************************************************** + * Add a diode to the circuit graph (unimplemented). + *****************************************************************/ + public void addDiode(DiodeInterface d) {} + + /***************************************************************** + * Returns the number of resistors in the circuit. + *****************************************************************/ + public int getResistorCount() { return numResistors; } + + /***************************************************************** + * Returns the number of capacitors in the circuit. + *****************************************************************/ + public int getCapacitorCount() { return numCapacitors; } + + /***************************************************************** + * Returns the number of transistors in the circuit. + *****************************************************************/ + public int getTransistorCount() { return numTransistors; } + + /***************************************************************** + * Returns the number of diodes in the circuit. + *****************************************************************/ + public int getDiodeCount() { return 0; } + + /***************************************************************** + * Returns the number of nodes in the circuit. + *****************************************************************/ + public int getNodeCount() { return nodeMap.keySet().size(); } + + /***************************************************************** + * Searches the graph for all independent resistive networks. + * For each of these, tallies total capacitance and identifies + * driver and gate nodes. + *****************************************************************/ + public void identifyNets(final CallbackInterface callback) + { + HashSet uncoveredNodes = new HashSet(nodeMap.values()); + int numNets = 0; + if (callback != null) + callback.identifyNetsUpdate(numNets,uncoveredNodes); + while (!uncoveredNodes.isEmpty()) { + Iterator it = uncoveredNodes.iterator(); + AbstractNode base = (AbstractNode)it.next(); + ResistiveSubnet rsn = new ResistiveSubnet(base); + base.buildResistiveSubnet(rsn,uncoveredNodes); + // + // Add this subnet to the resSubnets set as long as it + // isn't GND,Vdd,_SReset,_PReset, and contains at least + // one resistor. + // + if (!rsn.getCanonicalNameAsString().equals("_SReset") && + !rsn.getCanonicalNameAsString().equals("_SReset!") && + !rsn.getCanonicalNameAsString().equals("_PReset") && + !rsn.getCanonicalNameAsString().equals("_PReset!") && + !rsn.getCanonicalNameAsString().equals("GND") && + !rsn.getCanonicalNameAsString().equals("Vdd") && + !rsn.isDegenerate()) + resSubnets.add(rsn); + // + // Update net count and do callback update + // + numNets++; + if (callback != null) + callback.identifyNetsUpdate(numNets,uncoveredNodes); + } + clearMarks(); + } + + /***************************************************************** + * Returns an iterator over all the resistive subnets in the + * circuit graph. For best results (i.e. non-null), should be + * called after calling + * {@link #identifyNets(com.avlsi.circuit.LumpedRCGraph.CallbackInterface)}. + *****************************************************************/ + public Iterator getNetsIterator() { + return resSubnets.iterator(); + } + + /***************************************************************** + * Returns the set of all resistive subnets in the circuit graph. + * Must be called after + * {@link #identifyNets(com.avlsi.circuit.LumpedRCGraph.CallbackInterface)}. + *****************************************************************/ + public final Set getNets() { + return resSubnets; + } + + /************************************************* + * Clears all node marks throughout the net graph. + *************************************************/ + public void clearMarks() + { + // Note: numMarks argument to clearAllMarks will eventually + // require careful consideration... + Iterator it = nodeMap.values().iterator(); + while (it.hasNext()) ((AbstractNode)it.next()).clearAllMarks(2); + } + + /************************************************* + * Static subcircuit repository nested subclass. + *************************************************/ + public static class Repository extends AbstractCircuit.Repository { + /** + * LumpedRCGraph generator method. + **/ + protected AbstractCircuit newCircuitGenerator(final String cellType) { + return new LumpedRCGraph(cellType); + } + } + + /***************************************************************** + * Class to represent exceptions in LumpedRCGraph processing. + *****************************************************************/ + public static final class Exception extends java.lang.Exception { + public Exception(final String message) { + super(message); + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/MosDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/MosDevice.java new file mode 100644 index 0000000000..3d22614ae1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/MosDevice.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.aspice.Transistor; + +/********************************************************************** + * Three-terminal Mosfet transistor device class, for use as an edge + * in a circuit graph. Substrate terminal is not considered. Gate + * width and length parameters are stored, as well as + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public final class MosDevice { + + // + // Constants + // + + /** A W:L ratio below this value is considered to be "weak" **/ + public static final float WEAK_DRIVE_RATIO = 2.0f; + + /** NFET gate oxide capacitance per m^2(?) (TSMC 0.18um) **/ + public static final float COX_N = 8.46e-3f; + + /** PFET gate oxide capacitance per m^2(?) (TSMC 0.18um) **/ + public static final float COX_P = 8.16e-3f; + + final AbstractNode source, drain, gate; + private final float width, length; + private final byte type; + + /** Constructs a ResDevice from two node terminals and a resistance. **/ + public MosDevice(final AbstractNode d, final AbstractNode g, + final AbstractNode s, int t, double w, double l) { + gate=g; source=s; drain=d; + type=(byte)t; width=(float)w; length=(float)l; + } + + public float gateCap() { + return (type==DeviceTypes.N_TYPE ? COX_N:COX_P) * width * length; + } + + /** Returns the AbstractNode attached to the gate terminal. **/ + public AbstractNode gateNode() { return gate; } + + /** Returns the AbstractNode attached to the source terminal. **/ + public AbstractNode sourceNode() { return source; } + + /** Returns the AbstractNode attached to the drain terminal. **/ + public AbstractNode drainNode() { return drain; } + + /** Returns the device type (P_TYPE or N_TYPE) **/ + public int getType() { return type; } + + /** Returns an equivalent Transistor type **/ + public Transistor getTransistor() { + HierName bulk = (type == DeviceTypes.N_TYPE) ? + HierName.makeHierName("GND!") : + HierName.makeHierName("Vdd!"); + return new Transistor((int)type,source.name,drain.name,gate.name, + bulk,(double)width,(double)length); + } + + /** + * Returns an equivalent Transistor type, with the gate node + * set to its resistive subnet base name. + **/ + public Transistor getTransistorWithGateLumped() { + HierName bulk = (type == DeviceTypes.N_TYPE) ? + HierName.makeHierName("GND!") : + HierName.makeHierName("Vdd!"); + return new Transistor((int)type,source.name,drain.name, + gate.name.getResistiveSubnetName(), + bulk,(double)width,(double)length); + } + + /** + * True if the transistor's W:L ratio is less than + * {@link #WEAK_DRIVE_RATIO}. + **/ + public boolean isWeak() { return (width/length <= WEAK_DRIVE_RATIO); } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Node.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Node.java new file mode 100644 index 0000000000..9572db4d5b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Node.java @@ -0,0 +1,156 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.avlsi.file.common.HierName; + +/********************************************************************** + * Circuit graph node class. Implements the full functionality of + * AbstractNode, at the expense of increased memory consumption + * compared to LumpedNode or DriverNode. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +final class Node extends AbstractNode { + + private final ArrayList mosList = new ArrayList(); + private final ArrayList resList = new ArrayList(); + private final ArrayList capList = new ArrayList(); + private final ArrayList diodeList = new ArrayList(); + + /** + * Constructor. Takes a node name. Constructs the AbstractNode + * base class with two marks. + **/ + Node(final HierName name) { + super(name,2); + } + + // + // Abstract method implementations + // + + /** Connects a resistor to the node. **/ + void connectRes(final ResDevice r) { + resList.add(r); + } + + /** Connects a capacitor to the node. **/ + void connectCap(final CapDevice c) { + capList.add(c); + } + + /** Connects a transistor to the node. **/ + void connectMos(final MosDevice m) { + mosList.add(m); + } + + /** Connects a diode to the node. **/ + void connectDiode(final DiodeDevice d) { + diodeList.add(d); + } + + /** Returns an iterator over all resistors connected to this node **/ + public Iterator getResDevices() { return resList.iterator(); } + + /** Returns an iterator over all capacitors connected to this node **/ + public Iterator getCapDevices() { return capList.iterator(); } + + /** Returns an list of MosDevices connected to this node. **/ + public Iterator getMosDevices() { return mosList.iterator(); } + + /** Returns an iterator over all diodes connected to this node **/ + public Iterator getDiodeDevices() { return diodeList.iterator(); } + + /** Clears all marks in attached device edges **/ + void clearDeviceMarks() { + Iterator it = resList.iterator(); + while (it.hasNext()) { + ResDevice rd = (ResDevice)it.next(); + rd.clearMark(); + } + } + + /** Returns total wire capacitance lumped to this node **/ + public float wireCap() { + float wc = 0.0f; + Iterator it = capList.iterator(); + while (it.hasNext()) { + CapDevice cd = (CapDevice)it.next(); + wc += cd.getValue(); + } + return wc; + } + + /** Returns total gate capacitance lumped to this node **/ + public float gateCap() { + float gc = 0.0f; + Iterator it = mosList.iterator(); + while (it.hasNext()) { + MosDevice md = (MosDevice)it.next(); + if (md.gateNode() == this) gc += md.gateCap(); + } + return gc; + } + + /** + * Returns total "good" capacitance (lumped to a fixed node + * relative to this one). For now, just {@link #gateCap()}. + **/ + public float goodCap() { return gateCap(); } + + /** + * Returns total "bad" capacitance (lumped to nodes that could + * transition during this node's transition). For now, just + * {@link #wireCap()}. + **/ + public float badCap() { return wireCap(); } + + /** Returns number of (wire) Capacitors attached to this node. **/ + public int numCap() { return capList.size(); } + + /** Returns number of resistors attached to this node **/ + public int numRes() { return resList.size(); } + + /** + * Returns number of Mosfet attached to this node via source/drain + * For LumpedNode. + **/ + public int numDrivers() { + int n = 0; + Iterator it = mosList.iterator(); + while (it.hasNext()) { + MosDevice md = (MosDevice)it.next(); + if (md.sourceNode() == this || md.drainNode() == this) ++n; + } + return n; + } + + /** + * Returns number of gates attached to this node + **/ + public int numGates() { + int n = 0; + Iterator it = mosList.iterator(); + while (it.hasNext()) { + MosDevice md = (MosDevice)it.next(); + if (md.gateNode() == this) ++n; + } + return n; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResDevice.java new file mode 100644 index 0000000000..68462cb1e3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResDevice.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.aspice.Resistor; + +/********************************************************************** + * Resistor device class, for use as an edge in a circuit graph. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +final class ResDevice { + + final AbstractNode n0,n1; + private final float res; + private boolean mark; + + /** Constructs a ResDevice from two node terminals and a resistance. **/ + ResDevice(final AbstractNode a, final AbstractNode b, float r) { + n0 = a; + n1 = b; + res = r; + } + + /** Sets the resistor's mark state. **/ + void setMark() { mark = true; } + + /** Clears the resistor's mark state. **/ + void clearMark() { mark = false; } + + /** Returns the resistor's mark state. **/ + boolean getMark() { return mark; } + + /** Returns the resistor's value. **/ + float getValue() { return res; } + + /** Returns the node terminal that isn't specified. **/ + AbstractNode nextAfter(final AbstractNode a) { + if (a==n0) return n1; + else return n0; + } + + public Resistor getResistor() { + return new Resistor(n0.name,n1.name,1/res); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistiveSubnet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistiveSubnet.java new file mode 100644 index 0000000000..e0f9064025 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistiveSubnet.java @@ -0,0 +1,407 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Comparator; + +import com.avlsi.file.common.HierName; + +/********************************************************************** + * Class representing a resistive subnetwork of a CircuitGraph. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public class ResistiveSubnet { + + static boolean VDN_DEBUG; + static boolean GATERC_DEBUG; + static boolean USE_MAX_VDN_RC = true; + + /********************************************* + * Scratch data class for VDN RC calculation. + *********************************************/ + static class DriverRCData { + public float R; + public float C; + public float maxR; + public float maxC; + public int numDrivers; + } + + /** Subnet's base node */ + private AbstractNode base; + + /** Subnet's canonical node name */ + private HierName canonicalName; + + /** Cycles detected in subnet graph? */ + private boolean has_cycles; + + /** Total wire cap tally */ + private float wireCap; + + /** Total gate cap tally */ + private float gateCap; + + /** Total good cap tally */ + private float goodCap; + + /** True when base is VDN */ + private boolean base_is_vdn; + + /** Resistance from drivers to VDN */ + private float vdnRes; + + /** Wire cap from drivers to VDN */ + private float vdnCap; + + /** Max resistance from VDN to gate */ + private float maxPathRes; + + /** nodes connected to source/drains **/ + final private ArrayList driverNodes = new ArrayList(); + + /** nodes connected to gates **/ + final private ArrayList gateNodes = new ArrayList(); + + /** + * Constructor. Requires any node within the subnet + * as the initial base node. + **/ + ResistiveSubnet(AbstractNode b) { base = b; } + + /** + * Adds an AbstractNode to the subnet. + **/ + void addNode(AbstractNode n) { + // + // Accumulate wire cap + // + wireCap += n.wireCap(); + goodCap += n.goodCap(); + gateCap += n.gateCap(); + // + // Classify mosfet terminals + // + if (n.gateCap() > 0.0f) gateNodes.add(n); + if (n.numDrivers() > 0) driverNodes.add(n); + // + // Check if this node has a more canonical name + // + if (canonicalName==null || + n.name.getResistiveSubnetName().compareTo(canonicalName)<0) + canonicalName = n.name.getResistiveSubnetName(); + } + + /** + * Sets this subnet to be degenerate (contains no resistive + * segments. + **/ + void setDegenerate() { + // reusing available bits... + vdnRes = -1.0f; + } + + /** Call this when a cycle is encountered in the subnet. **/ + void encounteredCycle() { has_cycles = true; } + + /** + * Returns true if this subnet contains no resistive segments + * (i.e. it is one node.) + **/ + public boolean isDegenerate() { return vdnRes == -1.0f; } + + /** + * Returns true if one or more cycles have been detected in the + * subnet's resistive graph. + **/ + public boolean hasCycles() { return has_cycles; } + + /** Returns an Iterator over the subnet's driver AbstractNodes. **/ + public Iterator getDriverNodes() { return driverNodes.iterator(); } + + /** Returns an Iterator over the subnet's gate AbstractNodes. **/ + public Iterator getGateNodes() { return gateNodes.iterator(); } + + /** Returns the subnet's total wire capacitance. **/ + public float getWireCap() { return wireCap; } + + /** Returns the subnet's total capacitance lumped to fixed nodes. **/ + public float getGoodCap() { return goodCap; } + + /** Returns the subnet's total gate load capacitance. **/ + public float getGateCap() { return gateCap; } + + /***************************************************************** + * Returns the subnet's effective resistance from VDN to drivers. + * When {@link #USE_MAX_VDN_RC} is set, this is the max resistance + * over all paths from VDN to driver nodes. Otherwise, it is some + * funky parallel combination over all paths (assumes all driver + * conductances are equal and much greater than the wire resistance.) + * Will be 0.0 before {@link #identifyVDN()} is called. + *****************************************************************/ + public float getVdnRes() { + return (vdnRes < 0.0f) ? 0.0f : vdnRes; + } + + /***************************************************************** + * Returns the subnet's total wire capacitance from VDN to drivers, + * not including the wire cap attached to the VDN node itself. + *****************************************************************/ + public float getVdnCap() { return vdnCap; } + + /***************************************************************** + * Returns the max resistance over all paths from VDN to gate + * load nodes. Will be 0.0 before {@link #findMaxPathRes()} is + * called. Will be -1.0 if the subnet contains no gate load. + *****************************************************************/ + public float getMaxPathRes() { return maxPathRes; } + + /***************************************************************** + * Returns the maximum RC delay this net might see, namely + * maxRC = maxPathRes * (0.5 * wireCap + gateCap). + * (Assumes wire cap is distributed and all the gate cap is + * lumped at the end of the path w/ maximum resistance.) + *****************************************************************/ + public float getMaxRC() { + return maxPathRes * (0.5f * wireCap + gateCap); + } + + /***************************************************************** + * Routine to identify the subnet's virtual driver node. + * {@link #base } is set to the VDN. Nodes in the subnet + * should either be of LumpedNode or ExplicitNode type. + *

    + * NOTE: Nodes in the resistive net are left marked (mark index 0). + * Will need to clear all marks before other algorithms (such as + * {@link #findMaxPathRes()}) can be executed. + *****************************************************************/ + public void identifyVDN() + { + // + // Only proceed if there's at least two driver nodes + // and this subnet isn't degenerate + // + int driverCount = driverNodes.size(); + if (driverCount == 1) { + base = (AbstractNode)driverNodes.iterator().next(); + base_is_vdn = true; + } + if (driverCount <= 1 || vdnRes < 0.0f) return; + // + // Initialization + // + final HashMap markOwners = new HashMap(driverCount*10); + final HashSet[] activePaths = new HashSet[driverCount]; + final AbstractNode[] headNodes = new AbstractNode[driverCount]; + int[] mergeCount = new int[driverCount]; + int maxMergeCount = 0; + int i; + for (i=0; i0 && it.hasNext()) { + final AbstractNode n = (AbstractNode)it.next(); + Iterator jt = n.getResDevices(); + while (mergeCount[i]>0 && jt.hasNext()) { + ResDevice r = (ResDevice)jt.next(); + m = r.nextAfter(n); + if (VDN_DEBUG) System.err.println("vdn - "+i+": "+ + n.name.getAsString('.')+"->"+ + m.name.getAsString('.')); + if (m.getMark(0)) { + // This node has been covered: merge with + // owner if it's not me and it's still active. + int owner = ((Integer)markOwners.get(m)). + intValue(); + if (owner != i) { + // only merge if this isn't a cycle + if (mergeCount[owner] > 0) { + // only merge if the owner is still active + mergeCount[owner] += mergeCount[i]; + mergeCount[i] = 0; + if (mergeCount[owner] > maxMergeCount) + maxMergeCount = mergeCount[owner]; + activePaths[i].clear(); + } + else { + // otherwise claim this node + markOwners.put(m,new Integer(i)); + newPaths.add(m); + } + } + } + else { + // This node is new to the search: + // mark it and claim ownership. + m.setMark(0); + markOwners.put(m,new Integer(i)); + newPaths.add(m); + } + } + if (mergeCount[i]>0) it.remove(); + } + // Add all newfound paths to active + // list, unless we merged. + if (mergeCount[i]>0) activePaths[i].addAll(newPaths); + i = (i+1) % driverCount; + } + // + // Virtual driver node will be the last merged Node, m. + // + base = m; + base_is_vdn = true; + // + // Now search backwards from the VDN to determine + // the effective resistance & wire cap at the VDN. + // Subtract wire cap of base node from total since + // otherwise it will be double counted in + // findMaxPathRes(). + // + DriverRCData vdnrc = base.calculateRCtoDrivers(); + if (!USE_MAX_VDN_RC) { + vdnRes = vdnrc.R; + vdnCap = vdnrc.C - base.wireCap(); + } + else { + vdnRes = vdnrc.maxR; + vdnCap = vdnrc.maxC - base.wireCap(); + } + } + + /** + * Returns VDN node. May call {@link #identifyVDN()} if it hasn't + * yet been. + **/ + public AbstractNode getVDN() { + if (!base_is_vdn) identifyVDN(); + return base; + } + + /***************************************************************** + * Determines path from VDN to gate load node with maximum + * resistance. Resistance value can be obtained with + * {@link #getMaxPathRes()} afterwards. + *****************************************************************/ + public void findMaxPathRes() { + if (!base_is_vdn) identifyVDN(); + maxPathRes = base.findMaxPathRes() + vdnRes; + } + + /***************************************************************** + * Returns the subnet's canonical HierName. + *****************************************************************/ + public HierName getCanonicalName() { + return canonicalName; + } + + /***************************************************************** + * Returns a String containing the ResistiveSubnets's canonical + * net name, stripped of any trailing ':\w+' suffix. Hierarchy + * separation character is '.'. + *****************************************************************/ + public String getCanonicalNameAsString() { + return canonicalName.getAsString('.'); + } + + /***************************************************************** + * Comparator to sort ResistiveSubnets by max path resistance. + *****************************************************************/ + static final class ResComparator implements Comparator { + public int compare(Object o1, Object o2) { + final ResistiveSubnet rs1 = (ResistiveSubnet) o1; + final ResistiveSubnet rs2 = (ResistiveSubnet) o2; + float dr = rs1.maxPathRes - rs2.maxPathRes; + if (dr == 0.0f) return 0; + else return (dr < 0.0f) ? -1 : 1; + } + public boolean equals(final Object o) { + return getClass() == o.getClass(); + } + } + + /***************************************************************** + * Comparator to sort ResistiveSubnets by + * max RC = maxPathR * (0.5 * wireCap + gateCap) + *****************************************************************/ + static final class ResCapComparator implements Comparator { + public int compare(Object o1, Object o2) { + final ResistiveSubnet rs1 = (ResistiveSubnet) o1; + final ResistiveSubnet rs2 = (ResistiveSubnet) o2; + float drc = rs1.getMaxRC() - rs2.getMaxRC(); + if (drc == 0.0f) return 0; + else return (drc < 0.0f) ? -1 : 1; + } + public boolean equals(final Object o) { + return getClass() == o.getClass(); + } + } + + /***************************************************************** + * Comparator to sort ResistiveSubnets by + * wireCap / (wireCap + gateCap) + * (correlates with coupling susceptibility). + *****************************************************************/ + static final class CouplingComparator implements Comparator { + public int compare(Object o1, Object o2) { + final ResistiveSubnet rs1 = (ResistiveSubnet) o1; + final ResistiveSubnet rs2 = (ResistiveSubnet) o2; + float wg1 = (rs1.gateCap == 0.0f) ? 1.0f : + rs1.wireCap / (rs1.wireCap + rs1.gateCap); + float wg2 = (rs2.gateCap == 0.0f) ? 1.0f : + rs2.wireCap / (rs2.wireCap + rs2.gateCap); + float dwg = wg1 - wg2; + if (dwg == 0.0f) return 0; + else return (dwg < 0.0f) ? -1 : 1; + } + public boolean equals(final Object o) { + return getClass() == o.getClass(); + } + } + + /** ResComparator generator **/ + public static ResComparator newResComparator() { + return new ResComparator(); + } + + /** ResCapComparator generator **/ + public static ResCapComparator newResCapComparator() { + return new ResCapComparator(); + } + + /** CouplingComparator generator **/ + public static CouplingComparator newCouplingComparator() { + return new CouplingComparator(); + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Resistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Resistor.java new file mode 100644 index 0000000000..4217110506 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Resistor.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; + +/** + * Class for Resistor to be used with building an AbstractCircuit or a + * subclass of it + * + * @author Dan Daly + * @version $Date$ + **/ + +public class Resistor implements ResistorInterface{ + + /** name of device (optional) **/ + protected final HierName name; + + /** Names of connecting nodes **/ + protected final HierName source, drain; + + /** Conductance or inverse resitance of resistor in mho(inverse ohm) **/ + protected final double conductance; + + /** + * Constructor. + **/ + public Resistor(HierName name, + HierName source, + HierName drain, + double conductance) { + this.name = name; + this.source = source; + this.drain = drain; + this.conductance = conductance; + } + + public HierName getName() { return name; } + + public double getConductance() { return conductance; } + + public HierName getSource() { return source;} + + public HierName getDrain() { return drain;} + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistorInterface.java new file mode 100644 index 0000000000..c7bcd12e0f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/ResistorInterface.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; + +/** + * Interface specifying required methods of a resistor passed to + * AbstractCircuit + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface ResistorInterface { + + /** Source Node **/ + HierName getSource(); + + /** Drain Node **/ + HierName getDrain(); + + /** (optional) name of Resistor, null if not specified **/ + HierName getName(); + + /** Conductance or inverse resitance of resistor in mho, or inverse ohm **/ + double getConductance(); + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Source.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Source.java new file mode 100644 index 0000000000..d6dbd3491a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Source.java @@ -0,0 +1,59 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; + +import com.avlsi.file.common.HierName; + +/** + * Class for describing sources specified in spice + * + * @author Dan Daly + * @version $Date$ + **/ + +public class Source implements SourceInterface{ + /** Name of the source **/ + private HierName name; + /** Positive terminal node name **/ + private HierName pname; + /** Negative terminal node name **/ + private HierName nname; + /** Source type **/ + private String type; + /** Type specific arguments **/ + private String[] args; + + /** + * Constructor. + **/ + public Source(HierName name, String type, HierName pname, HierName nname, + String[] args) { + this.name = name; + this.type = type; + this.pname = pname; + this.nname = nname; + this.args = args; + } + /** Type of the source, pulse, sin, etc **/ + public String getType() { return type; } + /** (optional) Name of the Source, returns null if unassigned **/ + public HierName getName() { return name; } + /** Positive Terminal node name **/ + public HierName getPositiveTerminal(){ return pname; } + /** Negative Terminal node name **/ + public HierName getNegativeTerminal() { return nname; } + /** Type specific arguments to the source **/ + public String[] getArguments() { return args; } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/SourceInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/SourceInterface.java new file mode 100644 index 0000000000..c79ac486e1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/SourceInterface.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; + +import com.avlsi.file.common.HierName; +/** + * Class for ... + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface SourceInterface { + /** Type of the source, pulse, sin, etc **/ + String getType(); + /** (optional) Name of the Source, returns null if unassigned **/ + HierName getName(); + /** Positive Terminal node name **/ + HierName getPositiveTerminal(); + /** Negative Terminal node name **/ + HierName getNegativeTerminal(); + /** Type specific arguments to the source **/ + String[] getArguments(); +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TestSubnet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TestSubnet.java new file mode 100644 index 0000000000..c562f5424c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TestSubnet.java @@ -0,0 +1,922 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.circuit; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Comparator; +import java.io.PrintWriter; +import java.io.PrintStream; +import java.io.OutputStream; +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.Capacitor; +import com.avlsi.file.aspice.AspiceCell; +import com.avlsi.file.aspice.CastTestEnvironment; +import com.avlsi.file.aspice.Resistor; +import com.avlsi.file.aspice.Diode; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.text.NumberFormatter; + +/********************************************************************** + * Class representing a resistive subnetwork with associated + * transistors and parasitic capacitance, for slew rate and capacitive + * coupling test structure generation. + *

    + * Assumptions made: + *

      + *
    • No diode-connected transistors. They will likely cause + * duplicate transistors to be added to the AspiceCell circuit. + *
    • No degenerate moscap structures (source and drain shorted). + *
    + * + * @author Mike Davies + * @version $Revision$ $Date$ + **********************************************************************/ +public final class TestSubnet { + + public static boolean CONJUNCTIVE_PATH_DEBUG; + public static int DSIM_TIME_TAU_MAX = 1500; + public static float DTU = 5e-13f; + public static float T_RESET = 2e-9f; + + public static HierName GND = HierName.makeHierName("GND!"); + public static HierName Vdd = HierName.makeHierName("Vdd!"); + + /** This subnet's resistive subnet name **/ + private HierName name; + + /** The most canonical name of all the subnet's node names **/ + private HierName canonicalName; + + /** Cycles detected in subnet graph? **/ + private boolean has_cycles; + + /** AspiceCell to be simulated **/ + //private AspiceCell cell; + private String cell; + + /** Nodes in the resistive subnet **/ + private HashSet subnetNodes = new HashSet(); + + /** Map of coupling node names to coupling capacitance **/ + private HashMap couplingCap = new HashMap(); + + /** Subnets (as res subnet HierNames) that are driven by this net **/ + private HashMap drivenSubnets = new HashMap(); + + /** nodes connected to source/drains **/ + private HashSet driverNodes = new HashSet(); + + /** HierNames (res subnet names) of internal driver network nodes **/ + private HashSet internalDriverNodes = new HashSet(); + + /** nodes connected to gates **/ + private ArrayList gateNodes = new ArrayList(); + + /** Set of all conjunctive paths driving this node up **/ + private HashSet conjunctivePullUpPaths = new HashSet(); + + /** Set of all conjunctive paths driving this node down **/ + private HashSet conjunctivePullDownPaths = new HashSet(); + + /** Number of feedback (staticizer) pull-up paths **/ + private int numFeedbackPullUps; + + /** Number of feedback (staticizer) pull-down paths **/ + private int numFeedbackPullDowns; + + /** Set of all MosDevices in driver networks **/ + private HashSet driverMosDevices = new HashSet(); + + /** Set of input driver subnets (terms in pull-up/down paths) **/ + private HashSet inputSubnets = new HashSet(); + + /** + * Set of all subnets that are both driven by this subnet and + * drive this subnet. (Staticizer nodes.) + **/ + private HashSet feedbackSubnets = new HashSet(); + + /** + * Cast test environment file object. + **/ + private CastTestEnvironment castEnv; + + /** + * List of resistors in subnet. + **/ + private ArrayList resistorList = new ArrayList(); + + /** + * List of diodes in subnet. + **/ + private ArrayList diodeList = new ArrayList(); + + /** + * List of capacitors in subnet. + **/ + private ArrayList capacitorList = new ArrayList(); + + /** + * List of transistors in subnet. + **/ + private ArrayList transistorList = new ArrayList(); + + /** + * Name munging state + **/ + boolean encounteredBaseName; + boolean makeBaseNumberOne; + + /** + * Constructor. Requires any node within the subnet + * as the initial base node. + **/ + TestSubnet(HierName subnetName, String cellName) { + name = subnetName; + cell = cellName; + //cell = new AspiceCell(cellName); + } + + /** + * Initialize the CastTestEnvironment file object. + **/ + public void setCastTestEnvironment(final CastTestEnvironment env) { + castEnv = new CastTestEnvironment(env); + } + + /** + * Returns the AspiceCell representing the circuit to be + * simulated. + public AspiceCell getAspiceCell() { + return cell; + } + **/ + + /** Call this when a cycle is encountered in the subnet. **/ + void encounteredCycle() { has_cycles = true; } + + /** Adds a node to the resistive subnet **/ + void addSubnetNode(AbstractNode node) { + /*subnetNodes.add(node);*/ + // + // Munge the node's name such that it is guaranteed that there + // will exist some node in the subnet with the resistive + // subnet base name. + // + if (canonicalName==null || node.name.compareTo(canonicalName) < 0) + canonicalName = node.name; + // node.name = subnetNodeNameMunge(node.name); + } + + /** + * Munges the subnet node names such that it is guaranteed that + * a node name of the resistive subnet base name (no ":X" suffix) + * exists. Swaps ":1" with the base name unless the base name + * is encountered first. + *

    + * Also removes any trailing '!' in the name. + **/ + private HierName subnetNodeNameMunge(HierName x) { + HierName y = null; + if (x.getResistiveSubnetName().equals(name)) { + if (x.equals(name)) { + if (makeBaseNumberOne) + y = HierName.makeSiblingName(x,x.getSuffixString()+":1"); + else { + encounteredBaseName = true; + y = x; + } + } + else { + String suffix = x.getSuffixString(); + int i = suffix.indexOf(':'); + if (i == -1) y = x; + if (suffix.substring(i+1,suffix.length()).equals("1") && + (makeBaseNumberOne || !encounteredBaseName)) { + makeBaseNumberOne = true; + y = x.getResistiveSubnetName(); + } + else y = x; + } + } + else y = x; + Debug.assertTrue(y!=null); + if (y.isGlobal()) { + int i = y.getSuffixString().lastIndexOf('!'); + y = HierName.makeSiblingName(y,y.getSuffixString().substring(0,i)); + } + return y; + } + + /** Add a capacitor to the subnet **/ + void addCapacitor(CapDevice cd, AbstractNode remoteNode) { + HierName remoteSubnetName = remoteNode.name.getResistiveSubnetName(); + // + // First tally parasitic cap to the + // couplingCap map. + // + Double cap = (Double) couplingCap.get(remoteSubnetName); + if (cap != null) + cap = new Double(cap.doubleValue() + cd.getValue()); + else + cap = new Double(cd.getValue()); + couplingCap.put(remoteSubnetName,cap); + // + // Now generate the appropriate capacitor device in + // the AspiceCell. If this is a capacitor from one + // node within the subnet to another, add the exact + // cap. Otherwise lump the remote terminal to its + // subnet name. + // + if (remoteNode.name.getResistiveSubnetName().equals(name)) + capacitorList.add(cd.getCapacitor()); + else + capacitorList.add(cd.getCapacitorLumpedToSubnet(remoteNode)); + } + + /** Add a diode to the subnet **/ + void addDiode(DiodeDevice dd) { + // + // Add the Diode to the internal (AspiceCell-style) list + // + diodeList.add(dd.getDiode()); + /*cell.addDiode(dd.getDiode());*/ + } + + /** Adds all diodes from the AbstractNode. **/ + void addDiodesFrom(AbstractNode n) { + Iterator it = n.getDiodeDevices(); + while (it.hasNext()) + diodeList.add(((DiodeDevice)it.next()).getDiode()); + } + + /** Add a resistor to the subnet **/ + void addResistor(ResDevice rd) { + // + // Add the Resistor to the internal (AspiceCell-style) list + // + resistorList.add(rd.getResistor()); + //cell.addResistor(rd.getResistor()); + } + + /** + * Abstract test source helper class. Represents the .cast + * code necessary to produce a particular input stimulus. + **/ + abstract class TestSource { + protected HierName n; + TestSource(final HierName node) { n=node; } + abstract void addToCastEnv(); + HierName getSubnetName() { return n; } + } + + /** + * A constant-GND test source. + **/ + class GNDTestSource extends TestSource { + GNDTestSource(HierName node) { super(node); } + void addToCastEnv() { + //castEnv.addInstantiation("node "+n.getAsString('.')+"=GND;"); + castEnv.addAspLine("wire("+n.getAsString('.')+",GND);"); + } + } + + /** + * TestSource that we can rely to be a constant Vdd. + **/ + class VddTestSource extends TestSource { + VddTestSource(HierName node) { super(node); } + void addToCastEnv() { + //castEnv.addInstantiation("node "+n.getAsString('.')+"=Vdd;"); + castEnv.addAspLine("wire("+n.getAsString('.')+",Vdd);"); + } + } + + /** + * TestSource for a "neutral" source, i.e. one that we know + * nothing about its value. Set it to a fixed Vdd/2. + **/ + class NeutralTestSource extends TestSource { + NeutralTestSource(HierName node) { super(node); } + void addToCastEnv() { + String s = n.getAsString('.'); + castEnv.addAspLine("source{ (true/2-"+s+")*1e10 -> "+s+" }"); + castEnv.addAspLine("cap (GND,"+s+")(1);"); + } + } + + /** + * Undriven source (i.e. it's not a source at all, but an + * output or feedback node in the environment. + **/ + class UndrivenTestSource extends TestSource { + UndrivenTestSource(HierName node) { super(node); } + void addToCastEnv() { + //castEnv.addDeclaration("node "+n.getAsString('.')+"; "+ + // "// (undriven)"); + } + } + + /** + * A driven source. Specified as a digital sequence of values + * separated by some fixed interval. Generated with a cast + * source_node cell from "env.cast". + **/ + class DrivenTestSource extends TestSource { + private ArrayList points = new ArrayList(); + private int period = 100; + DrivenTestSource(HierName node) { super(node); } + void setPoint(int i, boolean value) { + if (i>points.size()) { + System.err.println("setPoint! node="+n.getAsString('.')); + i = points.size(); + } + else if (i==points.size()) { + points.add(i,new Boolean(value)); + } + else { + points.set(i,new Boolean(value)); + } + } + void setPeriod(int p) { period = p; } + int getPeriod() { return period; } + void setLength(int length) { + if (length > points.size()) { + Boolean last = (Boolean) points.get(points.size()-1); + for (int i=points.size(); i < length; i++) + points.add(i,last); + } + else { + for (int i=points.size()-1; i >= length; i--) + points.remove(i); + } + } + int getLength() { return points.size(); } + void addToCastEnv() { + castEnv.addImport("env.cast"); + castEnv.addDeclaration("node \""+n.getAsString('.')+"\";"); + StringBuffer sb = new StringBuffer(); + if (points.size() > 2) { + sb.append("source_node("+period+","+points.size()+",{"); + for (int i=0; i 1); + //if (p.getNumTerms + if (p.drivesUp()) + conjunctivePullUpPaths.add(p); + else + conjunctivePullDownPaths.add(p); + if (CONJUNCTIVE_PATH_DEBUG) { + System.err.print("addConjunctivePath: adding "); + p.printToStream(System.err); + } + // + // Look for subnets that appear both in ConjunctivePull{Up,Down}Paths + // terms and in the drivenSubnets set. Remove such nets + // from drivenSubnets and set the feedback flag of this + // conjunctive path. Note: In rare cases, this condition will + // hold when this subnets staticizes an input to the ConjunctivePath + // through one of the drivenSubnets. To catch this, a check for + // single feedback conjunctive pull-up/down paths is done in + // findConjunctiveDriverPaths, and if no real driver paths remain, + // the feedback paths are set to be non-feedback. + // + ArrayList terms = p.getTerms(); + for (int i=0; i 0) { + pullUps = new ConjunctivePath[numPullUps]; + Iterator it = conjunctivePullUpPaths.iterator(); + for (int i=0; i < numPullUps; i++) { + ConjunctivePath p = null; + do { + Debug.assertTrue(it.hasNext()); + p = (ConjunctivePath) it.next(); + } while (p.isFeedbackPath()); + pullUps[i] = p; + pullUpTerms.addAll(p.getTerms()); + } + } + if (numPullDns > 0) { + pullDns = new ConjunctivePath[numPullDns]; + Iterator it = conjunctivePullDownPaths.iterator(); + for (int i=0; i < numPullDns; i++) { + ConjunctivePath p = null; + do { + Debug.assertTrue(it.hasNext()); + p = (ConjunctivePath) it.next(); + } while (p.isFeedbackPath()); + pullDns[i] = p; + pullDnTerms.addAll(p.getTerms()); + } + } + + // + // Generate input sequences + // + HashMap sourceMap = new HashMap(); + Iterator it = inputSubnets.iterator(); + while (it.hasNext()) { + HierName n = (HierName) it.next(); + sourceMap.put(n,new DrivenTestSource(n)); + } + int length; + int iup = -1, idn = -1; + ConjunctivePath pup = null, pdn = null; + if (numPullDns > 0 && numPullUps > 0) { + idn = 0; pup = pullUps[0]; + iup = 0; pdn = pullDns[0]; + length = numPullUps > numPullDns ? numPullUps : numPullDns; + } + else { + // No pull-up or pull-down terms! Drive the TestSubnet directly. + // (Hope that a 'name' node within the subnet actually exists.) + sourceMap.clear(); + sourceMap.put(name,new DrivenTestSource(name)); + pdn = new ConjunctivePath(); + pdn.addTerm(name,DeviceTypes.P_TYPE); + pdn.addTerm(GND,ConjunctivePath.SUPPLY); + pup = new ConjunctivePath(); + pup.addTerm(name,DeviceTypes.N_TYPE); + pup.addTerm(Vdd,ConjunctivePath.SUPPLY); + length = 1; + } + HashSet enabledInputSet = new HashSet(); + for (int i=0; i < length; i++) { + ConjunctivePath p = null; + // + // Handle up transition + // + enabledInputSet.clear(); + if (iup != -1 && iup < numPullUps) p = pullUps[iup++]; + else p = pup; + for (int j=0; j < p.getNumTerms()-1; j++) { + ConjunctivePath.Term t = + (ConjunctivePath.Term) p.getTerms().get(j); + DrivenTestSource src = (DrivenTestSource) sourceMap.get(t.node); + src.setPoint(2*i,t.type==DeviceTypes.N_TYPE); + enabledInputSet.add(t.node); + } + // + // Disable all non-relevant pull-up & pull-down input nodes + // + it = pullUpTerms.iterator(); + for (int j=0; j<2; j++) { + while (it.hasNext()) { + ConjunctivePath.Term t = (ConjunctivePath.Term) it.next(); + if (!enabledInputSet.contains(t.node)) { + DrivenTestSource src = + (DrivenTestSource) sourceMap.get(t.node); + if (src != null) + src.setPoint(2*i,t.type==DeviceTypes.P_TYPE); + } + } + it = pullDnTerms.iterator(); + } + + // + // Handle down transition + // + enabledInputSet.clear(); + if (idn != -1 && idn < numPullDns) p = pullDns[idn++]; + else p = pdn; + for (int j=0; j < p.getNumTerms()-1; j++) { + ConjunctivePath.Term t = + (ConjunctivePath.Term) p.getTerms().get(j); + DrivenTestSource src = (DrivenTestSource) sourceMap.get(t.node); + src.setPoint(2*i+1,t.type==DeviceTypes.N_TYPE); + enabledInputSet.add(t.node); + } + // + // Disable all non-relevant pull-down & pull-up input nodes + // + it = pullDnTerms.iterator(); + for (int j=0; j<2; j++) { + while (it.hasNext()) { + ConjunctivePath.Term t = (ConjunctivePath.Term) it.next(); + if (!enabledInputSet.contains(t.node)) { + DrivenTestSource src = + (DrivenTestSource) sourceMap.get(t.node); + if (src != null) + src.setPoint(2*i+1,t.type==DeviceTypes.P_TYPE); + } + } + it = pullUpTerms.iterator(); + } + } + // + // Now send all test sources to the CastTestEnvironment + // + it = sourceMap.values().iterator(); + while (it.hasNext()) { + DrivenTestSource src = (DrivenTestSource) it.next(); + // + // Check if any input sources were missed. + // (This can happen in extremely rare cases when + // a conjunctive path is incorrectly identified as + // a feedback path, e.g. A2S_FAST_1of2._R.0,1) + // + if (src.getLength() == 0) + for (int i=0; i<2*length; i++) src.setPoint(i,false); + src.setPeriod(DSIM_TIME_TAU_MAX); + src.addToCastEnv(); + } + // + // Set the simulation run time to match the number of unique input + // vectors. + // + float timeMax = DSIM_TIME_TAU_MAX * DTU * (2 * length + 1) + T_RESET; + String timeMaxStr = NumberFormatter.format(timeMax,4); + castEnv.addAspLine(" .timemax="+timeMaxStr); + } + + /** + * Writes the cast test environment to the specified file. + **/ + public void writeCastEnvironmentFile(String envFile) + throws IOException + { + // + // Write out the identified conjunctive paths + // to the cast file, as comments to help with + // debugging. + // + castEnv.addDeclaration("// Pull-up conjunctive paths:"); + Iterator it = conjunctivePullUpPaths.iterator(); + while (it.hasNext()) { + ConjunctivePath cp = (ConjunctivePath) it.next(); + castEnv.addDeclaration("// "+cp.getAsString()); + } + castEnv.addDeclaration("// Pull-down conjunctive paths:"); + it = conjunctivePullDownPaths.iterator(); + while (it.hasNext()) { + ConjunctivePath cp = (ConjunctivePath) it.next(); + castEnv.addDeclaration("// "+cp.getAsString()); + } + // + // Generate all input prs sources, keeping track + // of which nodes have been sourced. + // + generateInputSources(); + // + // Generate all output driver network internal node sources. + // + it = drivenSubnets.values().iterator(); + while (it.hasNext()) { + TestSource ts = (TestSource) it.next(); + ts.addToCastEnv(); + } + // + // Add coupling cap nodes (those not already covered by + // input sources), shorted to GND. Don't modify _SReset, + // _PReset, Vdd, or any of the subnet nodes. + // + it = couplingCap.keySet().iterator(); + while (it.hasNext()) { + HierName remoteNet = (HierName) it.next(); + String s = remoteNet.getAsString('.'); + int i = s.indexOf('!'); + if (i != -1) s = s.substring(0,i); + if (!inputSubnets.contains(remoteNet) && + !feedbackSubnets.contains(remoteNet) && + !internalDriverNodes.contains(remoteNet) && + !remoteNet.equals(name) && !remoteNet.isVdd() && + !s.equals("_PReset") && !s.equals("_SReset")) + castEnv.addAspLine("wire("+s+","+"GND);"); + } + // + // Instantiate the subnet + // + it = capacitorList.iterator(); + while (it.hasNext()) { + Capacitor c = (Capacitor) it.next(); + castEnv.addAspLine(c.getAspiceString()); + } + it = resistorList.iterator(); + while (it.hasNext()) { + Resistor r = (Resistor) it.next(); + castEnv.addAspLine(r.getAspiceString()); + } + it = transistorList.iterator(); + while (it.hasNext()) { + Transistor t = (Transistor) it.next(); + castEnv.addAspLine(t.getAspiceString()); + } + it = diodeList.iterator(); + while (it.hasNext()) { + Diode d = (Diode) it.next(); + castEnv.addAspLine(d.getAspiceString()); + } + // + // Make sure the resistive subnet name exists in the aspice + // namespace. + // + if (!canonicalName.getAsString('.').equals(name)) + castEnv.addAspLine("wire("+canonicalName.getAsString('.')+","+ + name.getAsString('.')+");"); + // + // Print the CastTestEnvironment to the PrintStream. + // + PrintStream ps = new PrintStream(new BufferedOutputStream( + new FileOutputStream(envFile))); + castEnv.printToStream(ps); + ps.close(); + } + + /** + * Returns true if one or more cycles have been detected in the + * subnet's resistive graph. + **/ + public boolean hasCycles() { return has_cycles; } + + /** Returns an Iterator over the subnet's driver AbstractNodes. **/ + public Iterator getDriverNodes() { return driverNodes.iterator(); } + + /** Returns an Iterator over the subnet's gate AbstractNodes. **/ + public Iterator getGateNodes() { return gateNodes.iterator(); } + + /** + * Returns an Iterator over all the subnet HierNames + * driven by this subnet. + **/ + public Iterator getDrivenSubnets() { + return drivenSubnets.keySet().iterator(); + } + + /** + * Returns an iterator over all TestSources controlling + * the driven subnets of this TestSubnet. + **/ + public Iterator getDrivenSubnetSources() { + return drivenSubnets.values().iterator(); + } + + /** + * Prints total parasitic capacitance lumped to each remote + * subnet. + **/ + public void printParasiticCapToStream(final OutputStream s) { + PrintWriter pw = new PrintWriter(s); + pw.println("#"); + pw.println("# Nodes coupling to "+cell+":"); + pw.println("#"); + Iterator it = couplingCap.keySet().iterator(); + while (it.hasNext()) { + HierName remoteNet = (HierName) it.next(); + Double cap = (Double) couplingCap.get(remoteNet); + pw.println(remoteNet.getAsString('.') + ": " + cap); + } + pw.close(); + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Transistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Transistor.java new file mode 100644 index 0000000000..3822153a1c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/Transistor.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; + +/** + * Class for Transistors to be used for AbstractCircuit and its + * subclasses + * + * @author Dan Daly + * @version $Date$ + **/ + +public class Transistor implements TransistorInterface{ + + /** name of device (optional) **/ + protected final HierName name; + + /** Names of connecting nodes **/ + protected final HierName source, drain, gate, bulk; + + /** type of transistor **/ + protected final int type; + + /** Width of transistors in meters **/ + protected final double width; + + /** Length of transistors in meters **/ + protected final double length; + + /** + * Constructor. + **/ + public Transistor(HierName name, + int type, + HierName source, + HierName drain, + HierName gate, + HierName bulk, + double width, + double length) { + this.name = name; + this.source = source; + this.drain = drain; + this.gate = gate; + this.bulk = bulk; + this.width = width; + this.length = length; + this.type = type; + } + + public int getType() { return type; } + + public double getWidth() { return width; } + + public double getLength() { return length; } + + public HierName getName() { return name; } + + public HierName getSource() { return source;} + public HierName getDrain() { return drain;} + public HierName getGate() { return gate; } + public HierName getBulk() { return bulk;} +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TransistorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TransistorInterface.java new file mode 100644 index 0000000000..1491975001 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/circuit/TransistorInterface.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.circuit; +import com.avlsi.file.common.HierName; + +/** + * Interface for classes passing transistor data into an AbstractCircuit + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface TransistorInterface { + /** Get Transistor Type **/ + int getType(); + /** Get the width of the transistor **/ + double getWidth(); + /** Get the length of the transistor **/ + double getLength(); + /** (optional) name of Transistor, null if not specified **/ + HierName getName(); + + /** Source Node **/ + HierName getSource(); + /** Drain Node **/ + HierName getDrain(); + /** Gate Node **/ + HierName getGate(); + /** Bulk Node **/ + HierName getBulk(); +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNode.java new file mode 100644 index 0000000000..97053d6a63 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNode.java @@ -0,0 +1,113 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import antlr.Token; +import com.avlsi.util.debug.Debug; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.csp.grammar.ParseRange; + +/** + * This class is the abstract superclass of all objects representing + * AST nodes. The only functionality it currently provides are methods + * to retrieve and manipulate parse range data for the node. + * + * @author Frederik Eaton + * @version $Revision$ $Date$ + **/ +public abstract class AbstractASTNode + implements AbstractASTNodeInterface { + private ParseRange parseRange=ParseRange.EMPTY; + private Exception whereInstantiated=null; + + /* IMPORTANT: Change to false before submitting: */ + static final boolean debugParseRange=false; + + public AbstractASTNode() { + if(debugParseRange) { + whereInstantiated = new Exception(); + } + } + + // all the following methods are documented in + // AbstractASTNodeInterface + public void checkParseRange() { + if(debugParseRange) { + if(parseRange==ParseRange.EMPTY) { + System.err.println("In AST node "+this.getClass()+ + ": found null parseRange"); + System.err.println("Instantiated at: "); + whereInstantiated.printStackTrace(); + throw new Error("null parseRange"); + } + } + } + + public ParseRange getParseRange() { + checkParseRange(); + return parseRange; + } + + public AbstractASTNode epr(ParseRange p) { + if(parseRange == ParseRange.EMPTY) { + if(debugParseRange) + Debug.assertTrue(p!=null); + parseRange = p; + } else { + parseRange = new ParseRange(parseRange, p); + } + return this; + } + + public AbstractASTNode epr(Token t) { + if(t!=null) + epr(new ParseRange(t)); + return this; + } + + public AbstractASTNode epr(AbstractASTNodeInterface x) { + if(x!=null) { + ((AbstractASTNode)x).checkParseRange(); + epr(((AbstractASTNode)x).getParseRange()); + } + return this; + } + + public AbstractASTNode epr(AbstractASTNodeInterface x, + AbstractASTNodeInterface y) { + epr(x); + return epr(y); + } + + public AbstractASTNode epr(Token t, Token s) { + epr(t); + return epr(s); + } + + public AbstractASTNode epr(Token t, AbstractASTNodeInterface x) { + epr(t); + return epr(x); + } + + public AbstractASTNode epr(AbstractASTNodeInterface x, Token t) { + epr(x); + return epr(t); + } + +// never used: +// /* expressions of a[] should be in forward order */ +// public AbstractASTNode epr(AbstractASTNodeInterface a[]) { +// Debug.assertTrue(a.length>0, +// "epr(AbstractASTNodeInterface[]) called with zero-length array"); +// /* simple sanity check for a[] ordering */ +// Debug.assertTrue(((AbstractASTNode)a[0]).parseRange.end. +// compareTo(((AbstractASTNode)a[a.length-1]).parseRange.start)<=0); +// epr(new ParseRange(((AbstractASTNode)a[0]).parseRange, +// ((AbstractASTNode)a[a.length-1]).parseRange)); +// return this; +// } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNodeInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNodeInterface.java new file mode 100644 index 0000000000..3c232d85ad --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractASTNodeInterface.java @@ -0,0 +1,89 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import antlr.Token; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.csp.grammar.ParseRange; + +/** + * This is an interface capturing the API of AbstractASTNode, which is + * meant to be inherited by other AST node interfaces such as + * ExpressionInterface. Thus a variable of type ExpressionInterface + * need not be cast to AbstractASTNode in order to access or modify + * its parse range information. Note that in many places we assume (by + * casting to AbstractASTNode) that the only implementor of this is + * interface is AbstractASTNode, which should be a valid assumption + * since all AST types inherit from that class. + * + * @author Frederik Eaton + * @version $Revision$ $Date$ + **/ +public interface AbstractASTNodeInterface { + /** + * Prints an informative error message and throws an exception if + * parseRange is not set + **/ + void checkParseRange(); + + + /** + * Return parseRange + * @return parseRange + **/ + ParseRange getParseRange(); + + /** + * Sets parseRange to the convex closure parseRange and p. + * + * This and the following methods are called by the parser in the + * process of constructing csp ast objects. The effect is to + * extend the parse range to the smallest interval containing both + * the old parse range and the parse range corresponding to the + * passed object. The reason for the short name and many variants + * is to preserve parser legibility. + * + * "epr" stands for "extend parse range" + * + * @param p + * @return (AbstractASTNode)this + **/ + AbstractASTNode epr(ParseRange p); + + /** + * Extends parseRange to include the characters of t + * + * @param t A token + * @return (AbstractASTNode)this + **/ + AbstractASTNode epr(Token t); + + /** + * Extends parseRange to include the parseRange of x + * + * @param x Any object representing an AST node + * @return this + **/ + AbstractASTNode epr(AbstractASTNodeInterface x); + + /** same as epr(x).epr(y) + @see #epr(AbstractASTNodeInterface) **/ + AbstractASTNode epr(AbstractASTNodeInterface x, + AbstractASTNodeInterface y); + + /** same as epr(t).epr(s) + @see #epr(Token) **/ + AbstractASTNode epr(Token t, Token s); + + /** same as epr(t).epr(x) + @see #epr(Token) @see #epr(AbstractASTNodeInterface) **/ + AbstractASTNode epr(Token t, AbstractASTNodeInterface x); + + /** same as epr(x).epr(t) + @see #epr(Token) @see #epr(AbstractASTNodeInterface) **/ + AbstractASTNode epr(AbstractASTNodeInterface x, Token t); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractBinaryExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractBinaryExpression.java new file mode 100644 index 0000000000..9dfccc4325 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractBinaryExpression.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for binary expressions. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public abstract class AbstractBinaryExpression + extends AbstractASTNode implements ExpressionInterface { + /** Left child expression. May not be null. **/ + private final ExpressionInterface left; + /** Right child expression. May not be null. **/ + private final ExpressionInterface right; + + /** + * Class constructor. + * + * @param left Left child expression, not null. + * @param right Rigth child expression, not null. + **/ + public AbstractBinaryExpression(final ExpressionInterface left, + final ExpressionInterface right) { + this.left = left; + this.right = right; + } + + /** + * Returns the left child expression. + * + * @return left child expression, may not be null. + **/ + public ExpressionInterface getLeft() { + return left; + } + + /** + * Returns the left child expression. + * + * @return right child expression, may not be null. + **/ + public ExpressionInterface getRight() { + return right; + } + + /** + * Returns the operator. + * + * @return the operator as it would have been written in CSP. + **/ + public String getOperator() { return "binary operator"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelExpression.java new file mode 100644 index 0000000000..cf38234a65 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelExpression.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for channel expressions. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public abstract class AbstractChannelExpression + extends AbstractASTNode implements ExpressionInterface { + /** Channel expression. May not be null. **/ + protected final ExpressionInterface channelExpr; + + /** + * Class constructor. + * + * @param channelExpr channel expression, not null. + **/ + public AbstractChannelExpression(final ExpressionInterface channelExpr) { + this.channelExpr = channelExpr; + } + + /** + * Returns channel to be operated on. + * + * @return expression for channel to be operated on, not null + **/ + public ExpressionInterface getChannelExpression() { + return channelExpr; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelStatement.java new file mode 100644 index 0000000000..460cb6f4d1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractChannelStatement.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for channel related operations. + * X!x, X?x + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public abstract class AbstractChannelStatement + extends AbstractASTNode + implements StatementInterface { + + /** + * The expression for the channel to send or receive on. + * May not be null. + **/ + protected final ExpressionInterface channelExpr; + + /** + * The expression for the right hand side of the operation: + * the value to send, or the variable to receive into. + * May be null for receive expressions. + **/ + protected final ExpressionInterface rhsExpr; + + /** + * Class constructor. + * + * @param channelExpr expression for channel on which to operate, + * not null + * @param rhsExpr expression for right hand side of operation, + * may be null for recieve statements + **/ + public AbstractChannelStatement(final ExpressionInterface channelExpr, + final ExpressionInterface rhsExpr) { + this.channelExpr = channelExpr; + this.rhsExpr = rhsExpr; + } + + /** + * Returns channel expression for send or recieve. + * + * @return Channel expression to send or recieve on, may not be null. + **/ + public ExpressionInterface getChannelExpression() { + return channelExpr; + } + + /** + * Returns right hand side expression: value to send, or variable + * to receive into. May be null for receive statements. + * + * @return Expression from right hand side, ie x + * from X?x or X!x. + **/ + public ExpressionInterface getRightHandSide() { + return rhsExpr; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractCompositeStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractCompositeStatement.java new file mode 100644 index 0000000000..b7a5b840e8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractCompositeStatement.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Abstract base class for sequential and parallel statements. + * Keeps a list of statements. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public abstract class AbstractCompositeStatement + extends AbstractASTNode + implements StatementInterface { + + /** List of {@link StatementInterface}s. May not be null. **/ + private final List statements; + + /** + * Class constructor. Creates a composite statement without + * any statements in its statement list. + **/ + public AbstractCompositeStatement() { + statements = new ArrayList(); + } + + /** + * Adds a statement to the tail of the statement list. + * + * @param stmt statement to add to the tail of the list, + * may not be null + **/ + public void addStatement(final StatementInterface stmt) { + statements.add(stmt); + } + + /** + * Returns an iterator through the statements in the statement list. + * Will not return null. + * + * @return Iterator of {@link StatementInterface}s, not null + **/ + public Iterator getStatements() { + return statements.iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractGuardedStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractGuardedStatement.java new file mode 100644 index 0000000000..c385fad2fd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractGuardedStatement.java @@ -0,0 +1,92 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Abstract base class for deterministic and non-deterministic selection + * and repetition statements. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public abstract class AbstractGuardedStatement + extends AbstractASTNode + implements StatementInterface { + + /** + * List of {@link GuardedCommandInterface}s, for the guard and action. + * May not be null. + **/ + private final List guardedCommands; + + /** + * Statement for else case. May be null if there is no + * else. + **/ + private StatementInterface elseStatement; + + /** + * Class constructor. Constructs a guarded statement with + * an empty guarded command list and no else statement. + **/ + public AbstractGuardedStatement() { + guardedCommands = new ArrayList(); + elseStatement = null; + } + + /** + * Returns an Iterator over guard expressions and action statements. + * + * @return Iterator of {@link GuardedCommandInterface}s, not null + **/ + public Iterator getGuardedCommands() { + return guardedCommands.iterator(); + } + + /** + * Appends a guard and action to the list. + * + * @param guardedCommand guarded command to append to list, + * may not be null + **/ + public void addGuardedCommand( + final GuardedCommandInterface guardedCommand) { + guardedCommands.add(guardedCommand); + } + + /** + * Returns statement corresponding to else guard. + * + * @return action statement for else guard or null if there + * is none + **/ + public StatementInterface getElseStatement() { + return elseStatement; + } + + /** + * Sets else statement to elseStatement, + * replacing any existing elseStatement. + * + * @param elseStatement action statement for else guard, + * not null. + **/ + public void addElseStatement(final StatementInterface elseStatement) { + this.elseStatement = elseStatement; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractLoop.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractLoop.java new file mode 100644 index 0000000000..4a6a896801 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractLoop.java @@ -0,0 +1,88 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for loop expressions or statements, + * < sep i : M..N : expr_or_stmt >. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class AbstractLoop + extends AbstractASTNode { + /** Loop index variable. May not be null. **/ + private final IdentifierExpression indexVar; + + /** Range of variable for loop execution. May not be null. **/ + private final Range range; + + /** + * Indicates operator that is used to combine loop bodies. + * Only given meaning by {@link LoopStatement} or + * {@link LoopExpression}. + **/ + private final int separator; + + /** + * Class constructor. + * + * @param indexVar loop index variable, not null + * @param range minimum and maximum of range for loop index, not null + * @param separator separator code + **/ + public AbstractLoop(final String indexVar, final Range range, + final int separator) { + this.indexVar = new IdentifierExpression(indexVar); + this.range = range; + this.separator = separator; + } + + /** + * Returns the loop index variable as a string. + * + * @return loop index variable, not null + **/ + public String getIndexVar() { + return indexVar.getIdentifier(); + } + + /** + * Returns the loop index variable as an IdentifierExpression. + * + * @return loop index variable, not null + **/ + public IdentifierExpression getIndexVarExpression() { + return indexVar; + } + + /** + * Returns the range for the loop index. + * + * @return range for loop index, not null + **/ + public Range getRange() { + return range; + } + + /** + * Returns the separator for loop bodies. Only given meaning by + * {@link LoopStatement} or {@link LoopExpression}. + * + * @return separator code + **/ + public int getSeparator() { + return separator; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractRepetitionStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractRepetitionStatement.java new file mode 100644 index 0000000000..56577696b2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractRepetitionStatement.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for deterministic and non-deterministic repetition + * statements. Ie *[e1 -> s1 [] e2 -> s2 [] ...] + * and *[e1 -> s1 : e2 -> s2 : ...]. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public abstract class AbstractRepetitionStatement + extends AbstractGuardedStatement { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractSelectionStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractSelectionStatement.java new file mode 100644 index 0000000000..d6c54fef13 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractSelectionStatement.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Abstract base class for deterministic and non-deterministic selection + * statements. Ie [e1 -> s1 [] e2 -> s2 [] ...] + * and [e1 -> s1 : e2 -> s2 : ...]. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public abstract class AbstractSelectionStatement + extends AbstractGuardedStatement { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractUnaryExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractUnaryExpression.java new file mode 100644 index 0000000000..ccad212620 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AbstractUnaryExpression.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for unary expressions. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public abstract class AbstractUnaryExpression + extends AbstractASTNode + implements ExpressionInterface { + private final ExpressionInterface expr; + + /** + * Class constructor. + * + * @param expr child expression, may not be null + **/ + public AbstractUnaryExpression(final ExpressionInterface expr) { + this.expr = expr; + } + + /** + * Returns the child expression. + * + * @return child expression, may not be null + **/ + public ExpressionInterface getExpression() { + return expr; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AddExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AddExpression.java new file mode 100644 index 0000000000..d31b5e0cf0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AddExpression.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Addition expression. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class AddExpression extends AbstractBinaryExpression { + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public AddExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitAddExpression(this); + } + + public String getOperator() { return "+"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AndExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AndExpression.java new file mode 100644 index 0000000000..272600b0c3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AndExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Bitwise and expression, represents a & b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class AndExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public AndExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitAndExpression(this); + } + public String getOperator() { return "&"; } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayAccessExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayAccessExpression.java new file mode 100644 index 0000000000..c061d6b2ff --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayAccessExpression.java @@ -0,0 +1,69 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Array expression, represents a[i] . + * Todo: add support slicing a[x..y]. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ArrayAccessExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** Expression to be accessed. May not be null. **/ + private final ExpressionInterface arrayExpr; + + /** Index expression. May not be null. **/ + private final ExpressionInterface indexExpr; + + /** + * Class constructor. + * + * @param arrayExpr expression to be access, not null + * @param indexExpr index of arrayExpression to return, not null + **/ + public ArrayAccessExpression(final ExpressionInterface arrayExpr, + final ExpressionInterface indexExpr) { + this.arrayExpr = arrayExpr; + this.indexExpr = indexExpr; + } + + /** + * Returns the array expression. + * + * @return array expression to be accessed, not null + **/ + public ExpressionInterface getArrayExpression() { + return arrayExpr; + } + + /** + * Returns the index expression. + * + * @return index of array expression to access, not null + **/ + public ExpressionInterface getIndexExpression() { + return indexExpr; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitArrayAccessExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayType.java new file mode 100644 index 0000000000..4721fd781a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ArrayType.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Class for CSP Array types + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class ArrayType extends Type{ + private final Range range; + private Type elementType; + + public ArrayType (final Range range, final Type elementType) { + this.range = range; + this.elementType = elementType; + } + + public int dimension() { + return elementType.dimension() + 1; + } + + public Range getRange () { + return range; + } + + public Type getElementType () { + return elementType; + } + + public void setElementType (final Type elementType) { + this.elementType = elementType; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitArrayType(this); + } + + public String toString() { + final String r; + final ExpressionInterface min = range.getMinExpression(); + final ExpressionInterface max = range.getMaxExpression(); + if (min instanceof IntegerExpression && + max instanceof IntegerExpression) { + r = min.toString() + ".." + max.toString(); + } else { + r = ""; + } + return elementType.toString() + "[" + r + "]"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AssignmentStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AssignmentStatement.java new file mode 100644 index 0000000000..08fff20ca3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/AssignmentStatement.java @@ -0,0 +1,131 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Assignment statement, represents lhs := rhs . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class AssignmentStatement + extends AbstractASTNode + implements StatementInterface { + + public static final char EQUAL = '='; + public static final char ADD = '+'; + public static final char SUBTRACT = '-'; + public static final char MULTIPLY = '*'; + public static final char DIVIDE = '/'; + public static final char REMAINDER = '%'; + public static final char AND = '&'; + public static final char OR = '|'; + public static final char XOR = '^'; + public static final char LEFTSHIFT = '<'; + public static final char RIGHTSHIFT = '>'; + + /** + * Left hand side of assignment. Expression to which to assign. + * May not be null. + **/ + private final ExpressionInterface lhs; + + /** + * Right hand side of assignment. Expression from which to assign. + * May not be null. + **/ + private final ExpressionInterface rhs; + + /** + * Kind of assignment statement (i.e., plain assignment statement, or += + * assignment operator). + **/ + private final char kind; + + /** + * Class constructor. + * + * @param lhs left hand side expression, to be assigned to. Not null. + * @param lhs right hand side expression, to be assigned from. Not null. + **/ + public AssignmentStatement(final ExpressionInterface lhs, + final ExpressionInterface rhs) { + this(lhs, rhs, EQUAL); + } + + /** + * Class constructor. + * + * @param lhs left hand side expression, to be assigned to. Not null. + * @param lhs right hand side expression, to be assigned from. Not null. + * @param kind the kind of assignment statement. + **/ + public AssignmentStatement(final ExpressionInterface lhs, + final ExpressionInterface rhs, final char kind) { + this.lhs = lhs; + this.rhs = rhs; + this.kind = kind; + } + + /** + * Returns left hand side expression, to be assigned to. + * + * @return left hand side expression, not null + **/ + public ExpressionInterface getLeftHandSide() { + return lhs; + } + + /** + * Returns right hand side expression, to be assigned from. + * + * @return right hand side expression, not null + **/ + public ExpressionInterface getRightHandSide() { + return rhs; + } + + /** + * Return the kind of the assignment statement. + **/ + public char getKind() { + return kind; + } + + /** + * Return the kind of the assignment statement, as a string. + **/ + public String getKindString() { + switch (getKind()) { + case ADD: return "add"; + case SUBTRACT: return "subtract"; + case MULTIPLY: return "multiply"; + case DIVIDE: return "divide"; + case REMAINDER: return "remainder"; + case AND: return "and"; + case OR: return "or"; + case XOR: return "xor"; + case LEFTSHIFT: return "leftshift"; + case RIGHTSHIFT: return "rightshift"; + default: throw new AssertionError(); + } + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitAssignmentStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BitRangeExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BitRangeExpression.java new file mode 100644 index 0000000000..dc623cd2d0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BitRangeExpression.java @@ -0,0 +1,153 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Bit range expression, represents a[n:m] . The range represents + * the bits m <= i && i <= n. Modified from + * class Range, and modeled after ArrayAccessExpression. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class BitRangeExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** Expression that we are extracting from. May not be null. **/ + private final ExpressionInterface bitsExpr; + + /** Expression for minimum value of range. May be null. **/ + private final ExpressionInterface minExpr; + + /** Expression for maximum value of range. May not be null. **/ + private final ExpressionInterface maxExpr; + + /** + * Class constructor. + * + * @param bitsExpr expression to be extracted from, not null + * @param minExpr expression for minimum value of range, may be null + * @param maxExpr expression for maximum value of range, not null + **/ + public BitRangeExpression(final ExpressionInterface bitsExpr, + final ExpressionInterface minExpr, + final ExpressionInterface maxExpr) { + this.bitsExpr = bitsExpr; + this.minExpr = minExpr; + this.maxExpr = maxExpr; + } + + /** + * Returns the expression to be extracted from. + * + * @return expression to be extracted from, not null + **/ + public ExpressionInterface getBitsExpression() { + return bitsExpr; + } + + /** + * Returns expression for minimum value of range. + * + * @return expression for minimum value of range, may be null + **/ + public ExpressionInterface getMinExpression() { + return minExpr; + } + + /** + * Returns expression for maximum value of range. + * + * @return expression for maximum value of range, not null + **/ + public ExpressionInterface getMaxExpression() { + return maxExpr; + } + + /** + * Returns an expression representing the current value of the specified + * bits. This can only be used as an rvalue. + * + * @return expression for the current value of the bits, not null. + * @throws IllegalStateException if the returned expression would evaluate + * the index expression more than once + **/ + public ExpressionInterface getValueExpression() { + // Translate: + // x[n:m] --> ((x & ((1 << (n + 1)) - 1)) >> m) + + if (minExpr == null) throw new IllegalStateException(); + + ExpressionInterface one = new IntegerExpression ("1", 10); + ExpressionInterface result = + (ExpressionInterface) new RightShiftExpression ( + (ExpressionInterface) new AndExpression ( + bitsExpr, + (ExpressionInterface) new SubtractExpression ( + (ExpressionInterface) new LeftShiftExpression ( + one, + (ExpressionInterface) new AddExpression ( + maxExpr, one)), + one)), + minExpr); + + return result; + } + + /** + * Returns an expression representing the ultimate assigned value in the + * statement x[n:m] := expr. This can only be used as an + * rvalue. + * + * @param expr right-hand-side of assignment under consideration + * @return expression representing the assigned value + * @throws IllegalStateException if the returned expression would evaluate + * the index expression more than once + **/ + public ExpressionInterface getAssignedExpression(ExpressionInterface expr){ + // Translate: + // x[n:m] := expr + // --> ((x & ~((1 << (n + 1)) - (1 << m))) + // | ((expr << m) & ((1 << (n + 1)) - (1 << m)))) + if (minExpr == null) throw new IllegalStateException(); + + ExpressionInterface one = new IntegerExpression ("1", 10); + ExpressionInterface mask = new SubtractExpression ( + (ExpressionInterface) new LeftShiftExpression ( + one, + (ExpressionInterface) new AddExpression ( + maxExpr, one)), + (ExpressionInterface) new LeftShiftExpression ( + one, minExpr)); + ExpressionInterface result = + (ExpressionInterface) new OrExpression ( + (ExpressionInterface) new AndExpression ( + bitsExpr, + (ExpressionInterface) new NotExpression (mask)), + (ExpressionInterface) new AndExpression ( + (ExpressionInterface) new LeftShiftExpression ( + expr, + minExpr), + mask)); + return result; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitBitRangeExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanExpression.java new file mode 100644 index 0000000000..feac1fdd4a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanExpression.java @@ -0,0 +1,12 @@ +package com.avlsi.csp.ast; + +public class BooleanExpression extends IntegerExpression { + private final boolean val; + public BooleanExpression(final boolean val) { + super(val ? "-1" : "0", 10); + this.val = val; + } + public boolean booleanValue() { + return val; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanType.java new file mode 100644 index 0000000000..9ba71c03dd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/BooleanType.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id: //depot/sw/cad/java/main/src/com/avlsi/csp/ast/BooleanType.java#7 $ + */ + +package com.avlsi.csp.ast; + +/** + * Class for CSP Boolean type + * + * @author David Hilvert + * @version $Revision: #7 $ $Date: 2002/01/29 $ + **/ +public class BooleanType extends Type { + private final boolean is_const; + public BooleanType () { + this(false); + } + + public BooleanType (boolean is_const) { + this.is_const = is_const; + } + + /** + * Indicates dimension of the type. Scalars have dimension 0, arrays + * N, where N > 0. + **/ + public int dimension() { + // a boolean is a scalar CSP type, so its dimension is 0. + return 0; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitBooleanType(this); + } + + public boolean isConst() { + return is_const; + } + + public String toString() { + return "bool"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/CSPProgram.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/CSPProgram.java new file mode 100644 index 0000000000..30e9878a71 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/CSPProgram.java @@ -0,0 +1,221 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.HashSet; + +/** + * Class representing a csp program body and function definitions. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class CSPProgram + extends AbstractASTNode { + + /** + * List of {@link FunctionDeclaration}s, not null. + **/ + private final List functionDeclList; + + /** + * Map from structure name to {@link StructureDeclaration}s, not null. + **/ + private final Map structureDeclMap; + + /** + * List of {@link CSPProgram}s, not null. + **/ + private final List refinementParents; + + /** + * Set of {@link CSPProgram}s that CSP statements (as opposed to + * declarations) should not be inherited from + **/ + private final Set declarationParents; + + /** + * Initializer statement. May be null. + **/ + private SequentialStatement initStmt; + + /** + * Body statement. May be null. + **/ + private StatementInterface stmt; + + /** + * Class constructor. Creates a CSP program with an empty list of + * function declarations, and no body statement. + * + **/ + public CSPProgram() { + this.functionDeclList = new ArrayList(); + this.structureDeclMap = new LinkedHashMap(); + this.refinementParents = new ArrayList(); + this.declarationParents = new HashSet(); + this.initStmt = null; + this.stmt = null; + } + + /** + * Returns the initializer statement. + * + * @return initializer statement, may be null + **/ + public SequentialStatement getInitializerStatement() { + return initStmt; + } + + /** + * Sets the initializer statement. + * + * @param stmt initializer statement, not null + **/ + public void setInitializerStatement(final SequentialStatement initStmt) { + this.initStmt = initStmt; + } + + /** + * Returns the body statement. + * + * @return body statement, may be null + **/ + public StatementInterface getStatement() { + return stmt; + } + + /** + * Sets the body statement. + * + * @param stmt body statement, not null + **/ + public void setStatement(final StatementInterface stmt) { + this.stmt = stmt; + } + + /** + * Append a function declaration to the list of function declarations. + * + * @param funcDecl function declaration to append, not null + **/ + public void addFunctionDeclaration(final FunctionDeclaration funcDecl) { + functionDeclList.add(funcDecl); + } + + /** + * Returns an iterator of the declared functions + * + * @return an Iterator of {@link FunctionDeclaration}s over the + * function declarations that have been added. Will not return + * null. + **/ + public Iterator getFunctionDeclarations() { + return functionDeclList.iterator(); + } + + /** + * Append a structure declaration to the list of structure declarations. + * + * @param structDecl structure declaration to append, not null + **/ + public void addStructureDeclaration(final StructureDeclaration structDecl) { + structureDeclMap.put(structDecl.getName(), structDecl); + } + + /** + * Returns an iterator of the declared structures. + * + * @return an Iterator of {@link StructureDeclaration}s over the + * structure declarations that have been added. Will not return + * null. + **/ + public Iterator getStructureIterator() { + return structureDeclMap.values().iterator(); + } + + /** + * Returns a map of structure names to structure declarations. + * + * @return a map from String to {@link StructureDeclaration}s + **/ + public Map getStructureDeclarations() { + return Collections.unmodifiableMap(structureDeclMap); + } + + /** + * Return the structure declaration corresponding to a name. + * + * @return a {@link StructureDeclaration} associated with the name, or + * null if there is no such declaration. + **/ + public StructureDeclaration getStructureDeclaration(final String name) { + return (StructureDeclaration) structureDeclMap.get(name); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitCSPProgram(this); + } + + /** + * Record the ancestry for possible declaration and statement inheritence + * later. + **/ + public void refineFrom(final CSPProgram parent) { + if (parent == null) return; + refinementParents.add(parent); + } + + /** + * Like refineFrom, except only function and structure + * declarations are inherited from the parent, not the statements. + **/ + public void refineDeclarationsFrom(final CSPProgram parent) { + if (parent == null) return; + refineFrom(parent); + declarationParents.add(parent); + } + + /** + * Should only the declaration but not the statement body of the specified + * program be inherited? + **/ + public boolean inheritDeclarationOnly(final CSPProgram p) { + return declarationParents.contains(p); + } + + /** + * Return a list of {@link CSPProgram}s that are ancestors. + **/ + public List getRefinementParents() { + return Collections.unmodifiableList(refinementParents); + } + + /** For debugging purposes. **/ + public String toString() { + return "functions: " + functionDeclList + " structures: " + + structureDeclMap + " statement: " + stmt; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelStructureType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelStructureType.java new file mode 100644 index 0000000000..0e7f6a534f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelStructureType.java @@ -0,0 +1,74 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Class for CSP structure types of channels + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ChannelStructureType extends Type { + /** + * Name of the structure. + **/ + private String name; + + private final Map/**/ members; + + public ChannelStructureType (final String name) { + this.name = name; + this.members = new HashMap/**/(); + } + + public int dimension() { + return 0; + } + + /** + * Get the name of the structure. + * + * @return name of the structure + **/ + public String getName() { + return name; + } + + public void addMember(final /*@ non_null @*/ String name, + final /*@ non_null @*/ Type type) { + members.put(name, type); + } + + public Type getMemberType(final /*@ non_null @*/ String name) { + return (Type) members.get(name); + } + + /** + * Returns an unmodifiable map of the members and their types. + * + * @return members of the structure + **/ + public Map/**/ getMembers() { + return Collections.unmodifiableMap(members); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitChannelStructureType(this); + } + + public String toString() { + return "defchan " + name; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelType.java new file mode 100644 index 0000000000..226375c532 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ChannelType.java @@ -0,0 +1,71 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +import java.math.BigInteger; + +/** + * Class for CSP channel type. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ChannelType extends Type { + + /** + * The number of different values the channel can carry, + * from 0 to numValues - 1. + **/ + private final /*@ non_null @*/ BigInteger numValues; + + /** + * The direction of the channel. + **/ + private final /*@ non_null @*/ PortDirection direction; + + /** + * Class constructor + * + * @param numValues + * The number of different values the channel can carry, + * from 0 to numValues - 1. + **/ + public ChannelType(final /*@ non_null @*/ BigInteger numValues, + final /*@ non_null @*/ PortDirection direction) { + this.numValues = numValues; + this.direction = direction; + } + + /** + * Returns the number of values respresentable by the channel, + * or -1 for unbounded. + **/ + public /*@ non_null @*/ BigInteger getNumValues() { + return numValues; + } + + /** + * Returns the direction of the channel, input or output. + **/ + public /*@ non_null @*/ PortDirection getDirection() { + return direction; + } + + public void accept(VisitorInterface v) throws VisitorException { + v.visitChannelType(this); + } + + public int dimension() { + // A channel is a scalar CSP type, so its dimension is 0. + return 0; + } + + public String toString() { + return "e1of" + numValues.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalAndExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalAndExpression.java new file mode 100644 index 0000000000..85ed3a7a05 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalAndExpression.java @@ -0,0 +1,37 @@ +/* + * Copyright 2006 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * Conditional and expression, represents a && b . + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class ConditionalAndExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public ConditionalAndExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitConditionalAndExpression(this); + } + + public String getOperator() { return "&&"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalOrExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalOrExpression.java new file mode 100644 index 0000000000..73fea2fa77 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ConditionalOrExpression.java @@ -0,0 +1,37 @@ +/* + * Copyright 2006 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * Conditional OR expression, represents a || b . + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class ConditionalOrExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public ConditionalOrExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitConditionalOrExpression(this); + } + + public String getOperator() { return "||"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declaration.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declaration.java new file mode 100644 index 0000000000..690cef1746 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declaration.java @@ -0,0 +1,107 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * Class for variable declarations. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class Declaration + extends AbstractASTNode { + private final DeclaratorList declaratorList; + + public Declaration (final IdentifierList identifierList, + final Type type) { + this.declaratorList = new DeclaratorList(); + for (Iterator i = identifierList.getIdentifiers(); i.hasNext(); ) { + IdentifierExpression ident = (IdentifierExpression) i.next(); + declaratorList.addDeclarator(new Declarator(ident, type, null)); + } + } + + public Declaration (final DeclaratorList declaratorList, + final Type type) { + this.declaratorList = declaratorList; + for (Iterator i = declaratorList.getDeclarators(); i.hasNext(); ) { + Declarator d = (Declarator) i.next(); + ArrayType at = (ArrayType) d.getTypeFragment(); + + /* Complete the type fragment */ + + // VariableAnalyzer requires each Type instance corresponds to only + // one variable, so we clone the type to make each declarator have + // an unique instance + final Type cloned; + try { + cloned = (Type) type.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError("Cannot clone: " + type); + } + if (at == null) { + d.setTypeFragment(cloned); + } else { + while (at.getElementType() != null) { + at = (ArrayType) at.getElementType(); + } + at.setElementType(cloned); + } + } + } + + public Declaration (final DeclaratorList declaratorList) { + this.declaratorList = declaratorList; + } + + public DeclaratorList getDeclaratorList () { + return declaratorList; + } + + /** + * Convenience routine to return the set of declared identifiers. Each + * element is an object of type java.lang.String. + **/ + public Set getIdentifierSet() { + Set result = new HashSet(); + for (Iterator i = declaratorList.getDeclarators(); i.hasNext(); ) { + Declarator declarator = (Declarator) i.next(); + result.add (declarator.getIdentifier().getIdentifier()); + } + + return result; + } + + /** + * Convenience routine to return a mapping of identifiers to types. Each + * identifier is an object of type java.lang.String. Types are + * subclasses of ast.Type. + **/ + public Map getMap() { + Map result = new HashMap(); + for (Iterator i = declaratorList.getDeclarators(); i.hasNext(); ) { + Declarator declarator = (Declarator) i.next(); + result.put (declarator.getIdentifier().getIdentifier(), + declarator.getTypeFragment()); + } + + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclarationList.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclarationList.java new file mode 100644 index 0000000000..f09855ea48 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclarationList.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Class to store lists of declarations. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class DeclarationList extends AbstractASTNode { + private final List declarations; + + public DeclarationList() { + declarations = new ArrayList(); + } + + public void addDeclaration(final Declaration d) { + declarations.add (d); + } + + public Iterator getDeclarations() { + return declarations.iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declarator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declarator.java new file mode 100644 index 0000000000..ecbbfc7531 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Declarator.java @@ -0,0 +1,122 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Declarator, modified from IdentifierExpression + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class Declarator extends AbstractASTNode { + /** No direction specified **/ + public static final int NONE = 0; + + /** Input direction, i.e., "-" **/ + public static final int IN = 1; + + /** Output direction, i.e., "+" **/ + public static final int OUT = 2; + + /** Bidirectional, i.e., "+-" or "-+" **/ + public static final int INOUT = 3; + + /** Declarator name, not null **/ + private final IdentifierExpression ident; + + /** Declarator type fragment **/ + private Type typeFragment; + + /** Initializer **/ + private ExpressionInterface init; + + /** + * Directionality of an argument. Undefined for declarators not in a + * formal parameter list. + **/ + private final int direction; + + public Declarator(final IdentifierExpression ident, final Type typeFragment, + final ExpressionInterface init) { + this(ident, typeFragment, init, NONE); + } + + /** + * Class constructor. + * + * @param ident Identifier of declarator + * @param typeFragment Type fragment associated with declarator + **/ + public Declarator(final IdentifierExpression ident, final Type typeFragment, + final ExpressionInterface init, final int direction){ + this.ident = ident; + this.typeFragment = typeFragment; + this.init = init; + this.direction = direction; + } + + /** + * Returns identifier + * + * @return identifier, not null + **/ + public IdentifierExpression getIdentifier() { + return ident; + } + + /** + * Returns type fragment + * + * @return type fragment, may be null + **/ + public Type getTypeFragment() { + return typeFragment; + } + + /** + * Sets type fragment + * + * @param typeFragment Type fragment to associate with declarator + **/ + public void setTypeFragment(final Type typeFragment) { + this.typeFragment = typeFragment; + } + + /** + * Returns initializer + * + * @return initializer, may be null + **/ + public ExpressionInterface getInitializer() { + return init; + } + + /** + * Sets initializer + * + * @param init Initializer expression + **/ + public void setInitializer(ExpressionInterface init) { + this.init = init; + } + + /** + * Returns directionality + * + * @return directionality + **/ + public int getDirection() { + return direction; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclaratorList.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclaratorList.java new file mode 100644 index 0000000000..d38020b30c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeclaratorList.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Class to store lists of declarators. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class DeclaratorList extends AbstractASTNode { + private final List declarators; + + public DeclaratorList() { + declarators = new ArrayList(); + } + + public void addDeclarator(final Declarator i) { + declarators.add (i); + } + + public Iterator getDeclarators() { + return declarators.iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicRepetitionStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicRepetitionStatement.java new file mode 100644 index 0000000000..9318cb0cec --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicRepetitionStatement.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Deterministic repetition statements. + * Ie *[e1 -> s1 [] e2 -> s2 [] ...] . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class DeterministicRepetitionStatement + extends AbstractRepetitionStatement { + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitDeterministicRepetitionStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicSelectionStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicSelectionStatement.java new file mode 100644 index 0000000000..01e1daadf8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DeterministicSelectionStatement.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Deterministic selection statements. + * Ie [e1 -> s1 [] e2 -> s2 [] ...] . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class DeterministicSelectionStatement + extends AbstractSelectionStatement { + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitDeterministicSelectionStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DivideExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DivideExpression.java new file mode 100644 index 0000000000..f04f583555 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/DivideExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Divide expression, represents a / b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class DivideExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public DivideExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitDivideExpression(this); + } + + public String getOperator() { return "/"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/EqualityExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/EqualityExpression.java new file mode 100644 index 0000000000..fa510ab212 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/EqualityExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Equality expression, represents a == b. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class EqualityExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public EqualityExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitEqualityExpression(this); + } + + public String getOperator() { return "=="; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ErrorStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ErrorStatement.java new file mode 100644 index 0000000000..ae91765cac --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ErrorStatement.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * Error statement. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ErrorStatement + extends AbstractASTNode + implements StatementInterface { + + /** File in which the error occurred. **/ + private final String filename; + /** Line number on which the error occurred. **/ + private final int line; + /** Column number at which the error occurred. **/ + private final int column; + + /** + * Class constructor. + * + * @param filename file in which the error occurred + * @param line line number on which the error occurred + * @param column column number at which the error occurred + **/ + public ErrorStatement(final String filename, + final int line, + final int column) { + this.filename = filename; + this.line = line; + this.column = column; + } + + /** + * Returns file in which the error occurred. + * + * @return file in which the error occurred + **/ + public String getFilename() { + return filename; + } + + /** + * Returns line number on which the error occurred. + * + * @return line number on which the error occurred + **/ + public int getLine() { + return line; + } + + /** + * Returns column number at which the error occurred. + * + * @return column number at which the error occurred + **/ + public int getColumn() { + return column; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitErrorStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExponentialExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExponentialExpression.java new file mode 100644 index 0000000000..115f0ff92e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExponentialExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Exponentail expression, represents a ** b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ExponentialExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public ExponentialExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitExponentialExpression(this); + } + + public String getOperator() { return "**"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionInterface.java new file mode 100644 index 0000000000..6f6d4bdfb7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionInterface.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Interface that CSP expressions implement. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface ExpressionInterface extends AbstractASTNodeInterface { + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + void accept(VisitorInterface v) throws VisitorException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionStatement.java new file mode 100644 index 0000000000..b720981158 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ExpressionStatement.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * A class that turns an expression into a statement. It is useful for + * evaluating an expression for side effect only. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class ExpressionStatement + extends AbstractASTNode + implements StatementInterface { + + /** + * The expression to evaluate. May not be null. + **/ + protected final ExpressionInterface expr; + + /** + * Class constructor. + * + * @param expr expression to evaluate for side effect, may not be null + **/ + public ExpressionStatement(final ExpressionInterface expr) { + this.expr = expr; + } + + /** + * Returns expression to be evaluated for side effect + * + * @return expression to be evaluated, may not be null. + **/ + public ExpressionInterface getExpression() { + return expr; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitExpressionStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionCallExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionCallExpression.java new file mode 100644 index 0000000000..2f58905358 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionCallExpression.java @@ -0,0 +1,89 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Function call expression, represents f(x, y) . + * + *

    This class is flexible enough to handle arrays of functions, or + * functions returning functions, but none of those are allowed + * by the CSP language at this point.

    + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class FunctionCallExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** + * Expression for function to call. May not be null. + **/ + private final ExpressionInterface functionExpr; + + /** + * List of {@link ExpressionInterface}s for actual parameters to + * function. May not be null. + **/ + private final List actuals; + + /** + * Class constructor. Actual parameter list starts empty. + * + * @param functionExpr expression for function to call, not null + **/ + public FunctionCallExpression(final ExpressionInterface functionExpr) { + this.functionExpr = functionExpr; + this.actuals = new ArrayList(); + } + + /** + * Returns the function expression. + * + * @return expression for function to call, not null + **/ + public ExpressionInterface getFunctionExpression() { + return functionExpr; + } + + /** + * Returns an iterator over the acutal parameters + * + * @return Iterator of {@link ExpressionInterface}s over the + * actual parameters. May not be null. + **/ + public Iterator getActuals() { + return actuals.iterator(); + } + + /** + * Adds an actual parameter to the list. + * + * @param expr expression for actual parameter, not null + **/ + public void addActual(final ExpressionInterface expr) { + actuals.add(expr); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitFunctionCallExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionDeclaration.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionDeclaration.java new file mode 100644 index 0000000000..895f82b05a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/FunctionDeclaration.java @@ -0,0 +1,97 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Class describing a function declaration. Ie, + * function sum(x, y: int):int = sum := x + y;. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class FunctionDeclaration extends AbstractASTNode { + + /** Name of the function. May not be null. **/ + private final IdentifierExpression funcName; + + /** List of types and names of formal parameters. May not be null. **/ + private final DeclarationList formals; + + /** + * Return type of the function, or null if the function doesn't + * return a value. + **/ + private final Type returnType; + + /** Function body. May not be null. **/ + private final StatementInterface body; + + /** + * Class constructor. + * + * @param funcName name of declared function, not null + * @param formals list of formal parameters, not null + * @param returnType return type of function, or null if no return type + * @param body body of function, not null + **/ + public FunctionDeclaration(final String funcName, + final DeclarationList formals, + final Type returnType, + final StatementInterface body) { + this.funcName = new IdentifierExpression(funcName); + this.formals = formals; + this.returnType = returnType; + this.body = body; + } + + /** + * Returns the name of the declared function. + * + * @return name of declared function, not null + **/ + public String getName() { + return funcName.getIdentifier(); + } + + public IdentifierExpression getNameIdentifier() { + return funcName; + } + + /** + * Returns list of formal parameters. + * + * @return formal parameter list, not null + **/ + public DeclarationList getFormals() { + return formals; + } + + /** + * Returns return type of function. + * + * @return return type of function, or null for none + **/ + public Type getReturnType() { + return returnType; + } + + /** + * Returns body of function. + * + * @return body statement of function, not null + **/ + public StatementInterface getBodyStatement() { + return body; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterEqualExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterEqualExpression.java new file mode 100644 index 0000000000..298054d131 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterEqualExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Greather than or equal to expression, represents a >= b. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class GreaterEqualExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public GreaterEqualExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitGreaterEqualExpression(this); + } + + public String getOperator() { return ">="; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterThanExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterThanExpression.java new file mode 100644 index 0000000000..b8a415cbcc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GreaterThanExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Greater than expression, represents a > b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class GreaterThanExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public GreaterThanExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitGreaterThanExpression(this); + } + + public String getOperator() { return ">"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommand.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommand.java new file mode 100644 index 0000000000..ccd290d0d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommand.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * A type-safe pair of guard and command. + * Represents expr -> stmt portion of repetition or + * selection statement. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class GuardedCommand + extends AbstractASTNode + implements GuardedCommandInterface { + + /** Guard expression, not null. **/ + private final ExpressionInterface guard; + + /** Node linkage terms for linked arbitration. May be null. **/ + private final LinkageTerms linkageTerms; + + /** Command statement, not null. **/ + private final StatementInterface command; + + /** + * Class constructor. + * + * @param guard Guard expression, not null + * @param linkageTerms Linkage terms for linked arbitration, + * may be null + * @param command Action command, not null + **/ + public GuardedCommand(final ExpressionInterface guard, + final LinkageTerms linkageTerms, + final StatementInterface command) { + this.guard = guard; + this.linkageTerms = linkageTerms; + this.command = command; + } + + /** + * Class constructor. + * + * @param guard Guard expression, not null + * @param command Action command, not null + **/ + public GuardedCommand(final ExpressionInterface guard, + final StatementInterface command) { + this(guard, null, command); + } + + /** + * Returns guard expression. + * + * @return guard expression, not null + **/ + public ExpressionInterface getGuard() { + return guard; + } + + /** + * Returns node linkage terms for linked arbitration. + * + * @return node linkage terms, may be null + **/ + public LinkageTerms getLinkageTerms() { + return linkageTerms; + } + + /** + * Returns action statement to be exectued if guard expression is + * true. + * + * @return action statement, not null + **/ + public StatementInterface getCommand() { + return command; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandInterface.java new file mode 100644 index 0000000000..e906172292 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandInterface.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Tagging interface for guarded commands. May want to add visitor + * capability. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface GuardedCommandInterface + extends AbstractASTNodeInterface { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandWithStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandWithStatement.java new file mode 100644 index 0000000000..4720f66069 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/GuardedCommandWithStatement.java @@ -0,0 +1,55 @@ +/* + * Copyright 2008 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * A type-safe pair of guard and command with additional statements that are + * needed to evaluate guard. The guard is an expression, but to simplify + * translation, we may want to pull out function calls, assign function return + * values to temporary variables, then use the temporary variables in place of + * the original function calls. This rewriting procedure would generate + * VarStatements as well as AssignmentStatements, + * which are not expressions. + * + * This class is not instantiated by the parser because there is no + * corresponding CSP construct. It exists to help + * FunctionPreprocessor and VerilogEmitter. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public final class GuardedCommandWithStatement extends GuardedCommand { + /** Additional statement needed to evaluate guard. **/ + private final StatementInterface guardStatement; + + /** + * Class constructor. + * + * @param guard Guard expression, not null + * @param linkageTerms Linkage terms for linked arbitration, may be null + * @param command Action command, not null + * @param guardStmt Additional statement needed to evaluate guard, + * not null + **/ + public GuardedCommandWithStatement(final ExpressionInterface guard, + final LinkageTerms linkageTerms, + final StatementInterface command, + final StatementInterface guardStmt) { + super(guard, linkageTerms, command); + this.guardStatement = guardStmt; + } + + /** + * Returns statement needed to evaluate guard. + * + * @return statement needed to evaluate guard, not null + **/ + public StatementInterface getGuardStatement() { + return guardStatement; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierExpression.java new file mode 100644 index 0000000000..1cd487a7f9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierExpression.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Identifier expression, represents ident . + *

    Todo: maybe a string pool for the idents?

    + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class IdentifierExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** Identifier name, not null **/ + private final String ident; + + /** + * Class constructor. + * + * @param ident Name of identifier, not null + **/ + public IdentifierExpression(final String ident) { + this.ident = ident; + } + + /** + * Returns identifier name + * + * @return identifier name, not null + **/ + public String getIdentifier() { + return ident; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitIdentifierExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierList.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierList.java new file mode 100644 index 0000000000..b14acc30ae --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IdentifierList.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Class to store lists of identifiers. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class IdentifierList extends AbstractASTNode { + private final List identifiers; + + public IdentifierList() { + identifiers = new ArrayList(); + } + + public void addIdentifier(final IdentifierExpression i) { + identifiers.add (i); + } + + public Iterator getIdentifiers() { + return identifiers.iterator(); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitIdentifierList(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IncDecStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IncDecStatement.java new file mode 100644 index 0000000000..809445fcf8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IncDecStatement.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Increment or decrement statement. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class IncDecStatement + extends AbstractASTNode + implements StatementInterface { + + /** + * Expression to increment or decrement. May not be null. + **/ + private final ExpressionInterface expr; + + /** + * true if increment, false if decrement. + **/ + private final boolean inc; + + /** + * Class constructor. + * + * @param expr expression to increment or decrement. Not null. + * @param inc true if increment, false if + * decrement. + **/ + public IncDecStatement(final ExpressionInterface expr, final boolean inc) { + this.expr = expr; + this.inc = inc; + } + + /** + * Returns the expression to increment or decrement. + * + * @return expression to modify, not null + **/ + public ExpressionInterface getExpression() { + return expr; + } + + /** + * Return true if increment, false if decrement. + **/ + public boolean isIncrement() { + return inc; + } + + /** + * Represent the increment and decrement as an assignment statement. + **/ + public AssignmentStatement getAssignmentStatement() { + return (AssignmentStatement) + new AssignmentStatement(expr, new IntegerExpression(1), + inc ? AssignmentStatement.ADD + : AssignmentStatement.SUBTRACT).epr(this); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitIncDecStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/InequalityExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/InequalityExpression.java new file mode 100644 index 0000000000..b57f216926 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/InequalityExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Inequality expression, represends a != b. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class InequalityExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public InequalityExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitInequalityExpression(this); + } + + public String getOperator() { return "!="; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerExpression.java new file mode 100644 index 0000000000..923f20c367 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerExpression.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Integer literals. Ie 10, 0xFF, + * or 8_77. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class IntegerExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** String representation of integer. Not null. **/ + private final String val; + + /** + * Base used to interpret value string. Must be + * 2 <= radix && radix <= 36. + **/ + private final int radix; + + /** + * Class constructor. + * + * @param val String representation of number starting with + * optional minus sign. May not be null. + * @param radix Base for string between 2 and 36 inclusive. + **/ + public IntegerExpression(final String val, final int radix) { + this.val = val; + this.radix = radix; + } + + /** + * Class constructor. + * + * @param val int representation of number + **/ + public IntegerExpression(final int val) { + this.val = String.valueOf(val); + this.radix = 10; + } + + /** + * Returns string representation of integer. + * + * @return string representation, not null + **/ + public String getValue() { + return val; + } + + /** + * Returns radix for interpretation of value string. + * + * @return radix used to interpret value string + **/ + public int getRadix() { + return radix; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitIntegerExpression(this); + } + + public String toString() { + switch (radix) { + case 2: return "0b" + val; + case 10: return val; + case 16: return "0x" + val; + default: return radix + "_" + val; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerType.java new file mode 100644 index 0000000000..cd839d98c4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/IntegerType.java @@ -0,0 +1,138 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.math.BigInteger; + +import com.avlsi.csp.util.CspUtils; +import com.avlsi.csp.util.Interval; + +/** + * Class for CSP Integer type + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class IntegerType extends Type { + /** + * Is this type constant? + **/ + private boolean is_const; + + /** + * Is this type constant? + **/ + private boolean is_signed; + + /** + * User declared bit width. + **/ + private final ExpressionInterface declaredWidth; + + /** + * Interval containing all possible values of this type. + **/ + private Interval interval; + + public IntegerType () { + this(false); + } + + public IntegerType (boolean is_const) { + this(is_const, true, null); + } + + public IntegerType (boolean is_const, ExpressionInterface declaredWidth) { + this(is_const, false, declaredWidth); + } + + public IntegerType (boolean is_const, boolean is_signed, + ExpressionInterface declaredWidth) { + this.is_const = is_const; + this.is_signed = is_signed; + this.declaredWidth = declaredWidth; + final BigInteger bw = CspUtils.getIntegerConstant(declaredWidth); + if (bw == null) { + this.interval = null; + } else { + if (bw.signum() != 1 || bw.bitLength() > 31) { + final String loc = declaredWidth.getParseRange() == null ? + "" : " at " + declaredWidth.getParseRange().fullString(); + throw new IllegalArgumentException( + "Integer bit width invalid or too big: " + bw + loc); + } else { + this.interval = new Interval(is_signed, bw.intValue()); + } + } + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitIntegerType(this); + } + + /** + * Indicates dimension of the type. Scalars have dimension 0, arrays + * N, where N > 0. + **/ + public int dimension() { + + // An Integer is a scalar CSP type, so its dimension is 0. + + return 0; + } + + /** + * Indicates whether this integer type is a constant integer type. + **/ + public boolean isConst() { + return is_const; + } + + /** + * Indicates whether this integer type is signed. + **/ + public boolean isSigned() { + return is_signed; + } + + public String toString() { + return "int"; + } + + /** + * Returns the declared bit width. + **/ + public ExpressionInterface getDeclaredWidth() { + return declaredWidth; + } + + /** + * Sets the interval containing all possible values of this type. The + * interval can only be set if this type does not have a declared bit + * width. + **/ + public void setInterval(final Interval interval) { + if (declaredWidth == null) this.interval = interval; + } + + /** + * Returns the interval containing all possible values of this type. + **/ + public Interval getInterval() { + return interval; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LeftShiftExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LeftShiftExpression.java new file mode 100644 index 0000000000..662fe843ae --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LeftShiftExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Left shift expression, represents a << . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LeftShiftExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public LeftShiftExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLeftShiftExpression(this); + } + + public String getOperator() { return "<<"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessEqualExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessEqualExpression.java new file mode 100644 index 0000000000..e050ce4cea --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessEqualExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Less than or equal to expression, represents a <= b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LessEqualExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public LessEqualExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLessEqualExpression(this); + } + + public String getOperator() { return "<="; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessThanExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessThanExpression.java new file mode 100644 index 0000000000..36cf37abb9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LessThanExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Less than expression, represents a < b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LessThanExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public LessThanExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLessThanExpression(this); + } + + public String getOperator() { return "<"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageArrayAccessExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageArrayAccessExpression.java new file mode 100644 index 0000000000..29de3c25e7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageArrayAccessExpression.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LinkageArrayAccessExpression + extends AbstractASTNode + implements LinkageExpressionInterface { + + private final LinkageExpressionInterface arrayExpr; + + private final ExpressionInterface indexExpr; + + public LinkageArrayAccessExpression( + final LinkageExpressionInterface arrayExpr, + final ExpressionInterface indexExpr) { + this.arrayExpr = arrayExpr; + this.indexExpr = indexExpr; + } + + public LinkageExpressionInterface getArrayExpression() { + return arrayExpr; + } + + public ExpressionInterface getIndexExpression() { + return indexExpr; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLinkageArrayAccessExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionInterface.java new file mode 100644 index 0000000000..6f9c4ce1a5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionInterface.java @@ -0,0 +1,19 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface LinkageExpressionInterface + extends AbstractASTNodeInterface { + void accept(VisitorInterface v) throws VisitorException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionTerm.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionTerm.java new file mode 100644 index 0000000000..8da8fa9bb7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageExpressionTerm.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LinkageExpressionTerm + extends AbstractASTNode + implements LinkageTermInterface { + + private final LinkageExpressionInterface expr; + + private final boolean isInverted; + + public LinkageExpressionTerm(final LinkageExpressionInterface expr, + final boolean isInverted) { + this.expr = expr; + this.isInverted = isInverted; + } + + public LinkageExpressionInterface getExpression() { + return expr; + } + + public boolean isInverted() { + return isInverted; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLinkageExpressionTerm(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageIdentifierExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageIdentifierExpression.java new file mode 100644 index 0000000000..079551bf54 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageIdentifierExpression.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LinkageIdentifierExpression + extends AbstractASTNode + implements LinkageExpressionInterface { + + private final String ident; + + public LinkageIdentifierExpression(final String ident) { + this.ident = ident; + } + + public String getIdentifier() { + return ident; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLinkageIdentifierExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageLoopTerm.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageLoopTerm.java new file mode 100644 index 0000000000..b961c147f7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageLoopTerm.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +import com.avlsi.util.exception.AssertionFailure; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LinkageLoopTerm extends AbstractLoop + implements LinkageTermInterface { + + private final LinkageTermInterface term; + + public LinkageLoopTerm(final String indexVar, + final Range range, + final LinkageTermInterface term) { + // pass -1 as loop type, it doesn't matter + super(indexVar, range, -1); + this.term = term; + } + + public LinkageTermInterface getTerm() { + return term; + } + + public int getSeparator() { + throw new AssertionFailure(); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLinkageLoopTerm(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageStructureAccessExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageStructureAccessExpression.java new file mode 100644 index 0000000000..4290991f6b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageStructureAccessExpression.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LinkageStructureAccessExpression + extends AbstractASTNode + implements LinkageExpressionInterface { + + private final LinkageExpressionInterface structExpr; + + private final String fieldName; + + public LinkageStructureAccessExpression( + final LinkageExpressionInterface structExpr, + final String fieldName) { + this.structExpr = structExpr; + this.fieldName = fieldName; + } + + public LinkageExpressionInterface getStructureExpression() { + return structExpr; + } + + public String getFieldName() { + return fieldName; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLinkageStructureAccessExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTermInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTermInterface.java new file mode 100644 index 0000000000..1a6608c69b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTermInterface.java @@ -0,0 +1,19 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface LinkageTermInterface + extends AbstractASTNodeInterface { + void accept(VisitorInterface v) throws VisitorException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTerms.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTerms.java new file mode 100644 index 0000000000..4d36731fd4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LinkageTerms.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class LinkageTerms extends AbstractASTNode { + private final List terms; + + public LinkageTerms() { + terms = new ArrayList(); + } + + public void addTerm(final LinkageTermInterface term) { + terms.add(term); + } + + public Iterator getTerms() { + return Collections.unmodifiableList(terms).iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopExpression.java new file mode 100644 index 0000000000..b912ff924c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopExpression.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * Loop expressions, < op i : M..N : expr >. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LoopExpression extends AbstractLoop + implements ExpressionInterface { + + /** Bitwise and separator constant. **/ + public static final int AND = 0; + + /** Bitwise or separator constant. **/ + public static final int OR = 1; + + /** Multiplication separator constant. **/ + public static final int TIMES = 2; + + /** Addition separator constant. **/ + public static final int PLUS = 3; + + /** Bitwise xor separator constant. **/ + public static final int XOR = 4; + + /** Loop body expression, not null. **/ + private final ExpressionInterface expr; + + /** + * Class constructor. + * + * @param indexVar loop index variable, not null + * @param range minimum and maximum of range for loop index, not null + * @param separator separator code, one of {@see #AND}, {@see #OR}, + * {@see #TIMES}, {@see #PLUS} + * @param expr loop body expression + **/ + public LoopExpression(final String indexVar, + final Range range, + final int separator, + final ExpressionInterface expr) { + super(indexVar, range, separator); + this.expr = expr; + } + + /** + * Returns body expression. + * + * @return body expression, not null + **/ + public ExpressionInterface getExpression() { + return expr; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLoopExpression(this); + } + + public String getSeparatorString() { + final int sep = getSeparator(); + switch(sep) { + case AND: return "&"; + case OR: return "|"; + case XOR: return "^"; + case TIMES: return "*"; + case PLUS: return "+"; + } + throw new AssertionError("Unknown separator: " + sep); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopGuard.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopGuard.java new file mode 100644 index 0000000000..a1ef5fa50d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopGuard.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Loop guards, < sep i : M..N : stmt >. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class LoopGuard extends AbstractLoop + implements GuardedCommandInterface { + + /** Guards are in a deterministic construct. **/ + public static final int BOX = 0; + + /** Guards are in a non-deterministic construct. **/ + public static final int COLON = 1; + + /** List of guard commands, not null. **/ + private final List /**/ guards; + + /** + * Class constructor. + * + * @param indexVar loop index variable, not null + * @param range minimum and maximum of range for loop index, not null + * @param separator separator code, one of {@see #BOX}, + * {@see #COLON} + **/ + public LoopGuard(final String indexVar, + final Range range, + final int separator) { + super(indexVar, range, separator); + this.guards = new ArrayList(); + } + + /** + * Add a guard. + * + * @param guard guard to be added + **/ + public void addGuard(final GuardedCommandInterface guard) { + guards.add(guard); + } + + /** + * Returns a list of guards. + * + * @return a list of {@link GuardedCommandInterface}, not null + **/ + public List getGuards() { + return Collections.unmodifiableList(guards); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLoopGuard(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopStatement.java new file mode 100644 index 0000000000..3d371a8403 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/LoopStatement.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.csp.ast; + +/** + * Loop statements, < sep i : M..N : stmt >. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class LoopStatement extends AbstractLoop + implements StatementInterface { + + /** Sequential composition of loop bodies constant. **/ + public static final int SEQUENTIAL = 0; + + /** Parallel composition of loop bodies constant. **/ + public static final int PARALLEL = 1; + + /** Loop body statement, not null. **/ + private final StatementInterface stmt; + + /** + * Class constructor. + * + * @param indexVar loop index variable, not null + * @param range minimum and maximum of range for loop index, not null + * @param separator separator code, one of {@see #SEQUENTIAL}, + * {@see #PARALLEL} + * @param stmt loop body statement + **/ + public LoopStatement(final String indexVar, + final Range range, + final int separator, + final StatementInterface stmt) { + super(indexVar, range, separator); + this.stmt = stmt; + } + + /** + * Returns body statement. + * + * @return body statement, not null + **/ + public StatementInterface getStatement() { + return stmt; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitLoopStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MemberAccessExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MemberAccessExpression.java new file mode 100644 index 0000000000..529f107459 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MemberAccessExpression.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Member access expression, represents a::f . + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class MemberAccessExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** Expression whose field is to be accessed, not null. **/ + private final ExpressionInterface structExpr; + + /** Name of member to be accessed, not null. **/ + private final String memberName; + + /** + * Class constructor. + * + * @param structExpr Expression whose field is to be accessed, not null. + * @param memberName Name of member to be accessed, not null. + **/ + public MemberAccessExpression(final ExpressionInterface structExpr, + final String memberName) { + this.structExpr = structExpr; + this.memberName = memberName; + } + + /** + * Returns expression whose member is to be accessed. + * + * @return expression whose member is to be accessed, not null + **/ + public ExpressionInterface getStructureExpression() { + return structExpr; + } + + /** + * Returns name of member to be accessed. + * + * @return name of member to be accessed, not null + **/ + public String getMemberName() { + return memberName; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitMemberAccessExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MultiplyExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MultiplyExpression.java new file mode 100644 index 0000000000..3f15d8a223 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/MultiplyExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Multiply expression, represents a * b + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class MultiplyExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public MultiplyExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitMultiplyExpression(this); + } + + public String getOperator() { return "*"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NegateExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NegateExpression.java new file mode 100644 index 0000000000..a0b658fda8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NegateExpression.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Negate expression, represents - x . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class NegateExpression extends AbstractUnaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public NegateExpression(final ExpressionInterface expr) { + super(expr); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitNegateExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NodeType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NodeType.java new file mode 100644 index 0000000000..a2da02288d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NodeType.java @@ -0,0 +1,64 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * Class for CSP node type + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class NodeType extends Type { + /** + * Number of bits of information the possibly wide node can carry. + **/ + private final int width; + + /** + * The direction of the node. + **/ + private final PortDirection direction; + + /** + * Whether this is a "wide" node. Used to distinguish node from node[1]. + **/ + private final boolean arrayed; + + public NodeType(final int width, final PortDirection direction, + final boolean arrayed) { + assert width > 0 : "Illegal node width: " + width; + assert width == 1 || arrayed : "Wide node must be arrayed: " + width; + this.direction = direction; + this.width = width; + this.arrayed = arrayed; + } + + public NodeType(final PortDirection direction) { + this(1, direction, false); + } + + public void accept(VisitorInterface v) throws VisitorException { + v.visitNodeType(this); + } + + public int getWidth() { + return width; + } + + public int dimension() { + return 0; + } + + public boolean isArrayed() { + return arrayed; + } + + public String toString() { + return arrayed ? "node[" + width + "]" : "node"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicRepetitionStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicRepetitionStatement.java new file mode 100644 index 0000000000..66cda75676 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicRepetitionStatement.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Non-deterministic repetition statements. + * Ie, *[e1 -> s1 : e2 -> s2 : ...]. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class NonDeterministicRepetitionStatement + extends AbstractRepetitionStatement { + + private LinkageTerms neutralState; + + public void setNeutralState(final LinkageTerms neutralState) { + this.neutralState = neutralState; + } + + public LinkageTerms getNeutralState() { + return neutralState; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitNonDeterministicRepetitionStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicSelectionStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicSelectionStatement.java new file mode 100644 index 0000000000..c9d9068b1e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NonDeterministicSelectionStatement.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Non-deterministic selection statements. + * Ie, [e1 -> s1 : e2 -> s2 : ...]. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class NonDeterministicSelectionStatement + extends AbstractSelectionStatement { + + private LinkageTerms neutralState; + + public void setNeutralState(final LinkageTerms neutralState) { + this.neutralState = neutralState; + } + + public LinkageTerms getNeutralState() { + return neutralState; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitNonDeterministicSelectionStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NotExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NotExpression.java new file mode 100644 index 0000000000..5d6f37e5b0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/NotExpression.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Not expression, represents ~x . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class NotExpression extends AbstractUnaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public NotExpression(final ExpressionInterface expr) { + super(expr); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitNotExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/OrExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/OrExpression.java new file mode 100644 index 0000000000..2ccfa53817 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/OrExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Bitwise OR expression, represents a | b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class OrExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public OrExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitOrExpression(this); + } + + public String getOperator() { return "|"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ParallelStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ParallelStatement.java new file mode 100644 index 0000000000..c214460213 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ParallelStatement.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Parallel statements. Represents s1 || s2 or + * s1, s2. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ParallelStatement extends AbstractCompositeStatement { + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitParallelStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PeekExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PeekExpression.java new file mode 100644 index 0000000000..901650d9ad --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PeekExpression.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Peek expression, represents #X? . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class PeekExpression extends AbstractChannelExpression { + /** + * Class constructor. + * + * @param channelExpr expression for channel to peek, not null + **/ + public PeekExpression(final ExpressionInterface channelExpr) { + super(channelExpr); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitPeekExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PortDirection.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PortDirection.java new file mode 100644 index 0000000000..383f9f02a6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/PortDirection.java @@ -0,0 +1,51 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +import com.avlsi.fast.ports.PortDefinition; + +/** + * Class for CSP port directions. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class PortDirection { + public static final PortDirection IN = new PortDirection("input"); + public static final PortDirection OUT = new PortDirection("output"); + public static final PortDirection INOUT = new PortDirection("inout"); + + private final String message; + + private PortDirection(final String s) { + message = s; + } + + public String toString() { + return message; + } + + /** + * Maps directions encoded as ints (used by PortDefinition + * constants) to PortDirections. + **/ + public static /*@ non_null @*/ PortDirection mapDirection( + final int direction) { + switch (direction) { + case PortDefinition.IN: + return PortDirection.IN; + case PortDefinition.OUT: + return PortDirection.OUT; + case PortDefinition.INOUT: + case PortDefinition.NONE: + return PortDirection.INOUT; + } + + throw new AssertionError("Unknown port direction"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ProbeExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ProbeExpression.java new file mode 100644 index 0000000000..56e2fc249f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ProbeExpression.java @@ -0,0 +1,39 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Probe expression, represents #X . + * Todo: add support for #X, Y, Z: expr. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ProbeExpression extends AbstractChannelExpression { + /** + * Class constructor. + * + * @param channelExpr expression for channel to probe, not null + **/ + public ProbeExpression(final ExpressionInterface channelExpr) { + super(channelExpr); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitProbeExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Range.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Range.java new file mode 100644 index 0000000000..3ab5bdb968 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Range.java @@ -0,0 +1,60 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Range class, represents A..B . The range represents + * the sequence of integers A <= i && i <= B. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class Range extends AbstractASTNode { + + /** Expression for minimum value of range. May not be null. **/ + private final ExpressionInterface minExpr; + + /** Expression for maximum value of range. May not be null. **/ + private final ExpressionInterface maxExpr; + + /** + * Class constructor. + * + * @param minExpr expression for minimum value of range + * @param maxExpr expression for maximum value of range + **/ + public Range(final ExpressionInterface minExpr, + final ExpressionInterface maxExpr) { + this.minExpr = minExpr; + this.maxExpr = maxExpr; + } + + /** + * Returns expression for minimum value of range. + * + * @return expression for minimum value of range, not null + **/ + public ExpressionInterface getMinExpression() { + return minExpr; + } + + /** + * Returns expression for maximum value of range. + * + * @return expression for maximum value of range, not null + **/ + public ExpressionInterface getMaxExpression() { + return maxExpr; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveExpression.java new file mode 100644 index 0000000000..5ddf09c289 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveExpression.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Receive expression, represents X? . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ReceiveExpression extends AbstractChannelExpression { + /** + * Class constructor. + * + * @param channelExpr expression for channel to receive on, not null + **/ + public ReceiveExpression(final ExpressionInterface channelExpr) { + super(channelExpr); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitReceiveExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveStatement.java new file mode 100644 index 0000000000..c387a1cd73 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/ReceiveStatement.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Recieve statement, X ? x . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class ReceiveStatement extends AbstractChannelStatement { + + /** + * Class constructor. + * + * @param channelExpr expression for channel to receive from, + * not null + * @param rhs expression for variable to receive into. + * May be null. + **/ + public ReceiveStatement(final ExpressionInterface channelExpr, + final ExpressionInterface rhs) { + super(channelExpr, rhs); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitReceiveStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RemainderExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RemainderExpression.java new file mode 100644 index 0000000000..f447a42a11 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RemainderExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Remainder expression, represents a % b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class RemainderExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public RemainderExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitRemainderExpression(this); + } + + public String getOperator() { return "%"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RightShiftExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RightShiftExpression.java new file mode 100644 index 0000000000..1b6cde31a3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/RightShiftExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Right shift expression, represents a >> b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class RightShiftExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public RightShiftExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitRightShiftExpression(this); + } + + public String getOperator() { return ">>"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SendStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SendStatement.java new file mode 100644 index 0000000000..88f358514e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SendStatement.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Send statement, X ! x . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SendStatement extends AbstractChannelStatement { + + /** + * Class constructor. + * + * @param channelExpr expression for channel to send on, not null + * @param rhs expression to send, not null + **/ + public SendStatement(final ExpressionInterface channelExpr, + final ExpressionInterface rhs) { + super(channelExpr, rhs); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitSendStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SequentialStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SequentialStatement.java new file mode 100644 index 0000000000..78bf820942 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SequentialStatement.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Sequential statements. Represents s1 ; s2 . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SequentialStatement extends AbstractCompositeStatement { + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitSequentialStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SkipStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SkipStatement.java new file mode 100644 index 0000000000..67ce121020 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SkipStatement.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Skip statement. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SkipStatement + extends AbstractASTNode + implements StatementInterface { + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitSkipStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StatementInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StatementInterface.java new file mode 100644 index 0000000000..a97654101c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StatementInterface.java @@ -0,0 +1,24 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Interface that CSP statements implement. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface StatementInterface extends AbstractASTNodeInterface { + void accept(VisitorInterface v) throws VisitorException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringExpression.java new file mode 100644 index 0000000000..953206492d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringExpression.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * String literals. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class StringExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** The string. Not null. **/ + private final String val; + + /** + * Class constructor. + * + * @param val The string. May not be null. + **/ + public StringExpression(final String val) { + this.val = val; + } + + /** + * Returns the string. + * + * @return string, not null + **/ + public String getValue() { + return val; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitStringExpression(this); + } + + public String toString() { + return val; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringType.java new file mode 100644 index 0000000000..bb758e23fe --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StringType.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Class for CSP string type + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class StringType extends Type { + boolean is_const = false; + + public StringType () { + } + + public StringType (boolean is_const) { + this.is_const = is_const; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitStringType(this); + } + + /** + * Indicates dimension of the type. Scalars have dimension 0, arrays + * N, where N > 0. + **/ + public int dimension() { + // A string is a scalar CSP type, so its dimension is 0. + return 0; + } + + /** + * Indicates whether this string type is a constant integer type. + **/ + public boolean isConst() { + return is_const; + } + + public String toString() { + return "string"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureAccessExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureAccessExpression.java new file mode 100644 index 0000000000..95ff048849 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureAccessExpression.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Structure expression, represents a.f . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class StructureAccessExpression + extends AbstractASTNode + implements ExpressionInterface { + + /** Expression whose field is to be accessed, not null. **/ + private final ExpressionInterface structExpr; + + /** Name of field to be accessed, not null. **/ + private final String fieldName; + + /** + * Class constructor. + * + * @param structExpr Expression whose field is to be accessed, not null. + * @param fieldName Name of field to be accessed, not null. + **/ + public StructureAccessExpression(final ExpressionInterface structExpr, + final String fieldName) { + this.structExpr = structExpr; + this.fieldName = fieldName; + } + + /** + * Returns expression whose field is to be accessed. + * + * @return expression whose field is to be accessed, not null + **/ + public ExpressionInterface getStructureExpression() { + return structExpr; + } + + /** + * Returns name of field to be accessed. + * + * @return name of field to be accessed, not null + **/ + public String getFieldName() { + return fieldName; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitStructureAccessExpression(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureDeclaration.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureDeclaration.java new file mode 100644 index 0000000000..4c61c3e846 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureDeclaration.java @@ -0,0 +1,84 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +/** + * Class for CSP structure definitions + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class StructureDeclaration extends AbstractASTNode { + /** + * Name of the structure + **/ + private final String name; + + /** + * Members declared in the structure + **/ + private final DeclarationList declarations; + + /** + * Class constructor. + * + * @param name name of the structure + * @param declarations members declared in the structure + **/ + public StructureDeclaration(final String name, + final DeclarationList declarations) { + this.name = name; + this.declarations = declarations; + } + + /** + * Get name of the structure + * + * @return name of the structure + **/ + public String getName() { + return name; + } + + /** + * Get members declared in the structure + * + * @return members in the structure + **/ + public DeclarationList getDeclarations() { + return declarations; + } + + /** + * Get a map from members to their types. Note that if a member is + * declared multiple times in the structure, there is no guarantee which + * type from the declarations is returned. + * + * @return map from String to Type + **/ + public Map getMap() { + final Map result = new HashMap(); + for (Iterator i = declarations.getDeclarations(); i.hasNext(); ) { + final Declaration decl = (Declaration) i.next(); + result.putAll(decl.getMap()); + } + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureType.java new file mode 100644 index 0000000000..e03f7fa832 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/StructureType.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Class for CSP structure types + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class StructureType extends Type { + /** + * Name of the structure. + **/ + private String name; + + /** + * Is the structure a constant? + **/ + private final boolean is_const; + + public StructureType (final boolean is_const, final String name) { + this.is_const = is_const; + this.name = name; + } + + public int dimension() { + return 0; + } + + /** + * Get the name of the structure. + * + * @return name of the structure + **/ + public String getName() { + return name; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitStructureType(this); + } + + /** + * Indicates whether this structure type is a constant structure type. + **/ + public boolean isConst() { + return is_const; + } + + public String toString() { + return "structure " + name; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SubtractExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SubtractExpression.java new file mode 100644 index 0000000000..0f1d68e702 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/SubtractExpression.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Subtract expression, represents a - b . + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SubtractExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public SubtractExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitSubtractExpression(this); + } + + public String getOperator() { return "-"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/TemporaryIntegerType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/TemporaryIntegerType.java new file mode 100644 index 0000000000..a3e0329a80 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/TemporaryIntegerType.java @@ -0,0 +1,7 @@ +package com.avlsi.csp.ast; + +public class TemporaryIntegerType extends IntegerType { + public TemporaryIntegerType() { + super(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Type.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Type.java new file mode 100644 index 0000000000..d0976708dd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/Type.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for CSP types + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public abstract class Type + extends AbstractASTNode implements Cloneable { + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public abstract void accept(VisitorInterface v) throws VisitorException; + + /** + * Indicates dimension of the type. Scalars have dimension 0, arrays + * N, where N > 0. + **/ + public abstract int dimension(); + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public static Type clone(final Type t) { + try { + return (Type) t.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError("Cannot clone " + t); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VarStatement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VarStatement.java new file mode 100644 index 0000000000..605c628376 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VarStatement.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Class for variable declaration block statements. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class VarStatement + extends AbstractASTNode + implements StatementInterface { + private final DeclarationList declarationList; + private final StatementInterface statement; + + public VarStatement (final DeclarationList declarationList, + StatementInterface statement) { + this.declarationList = declarationList; + this.statement = statement; + } + + /** + * Support for new-style variable declarations, which occur as part of + * a sequential statement. + **/ + public VarStatement (final Declaration declaration) { + this.declarationList = new DeclarationList(); + this.declarationList.addDeclaration (declaration); + this.statement = null; + } + + public DeclarationList getDeclarationList () { + return declarationList; + } + + public StatementInterface getStatement () { + return statement; + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitVarStatement(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorException.java new file mode 100644 index 0000000000..72fb9a3ca8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorException.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Abstract base class for Exceptions thrown by visitors. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class VisitorException extends Exception { + public VisitorException(final String message) { + super(message); + } + public VisitorException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorInterface.java new file mode 100644 index 0000000000..9f564662a8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/VisitorInterface.java @@ -0,0 +1,130 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.ast; + +/** + * Visitor pattern for CSP AST. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface VisitorInterface { + void visitCSPProgram(CSPProgram p) throws VisitorException; + + void visitAddExpression(AddExpression e) throws VisitorException; + void visitAndExpression(AndExpression e) throws VisitorException; + void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException; + void visitBitRangeExpression(BitRangeExpression e) throws VisitorException; + void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException; + void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException; + void visitDivideExpression(DivideExpression e) throws VisitorException; + void visitEqualityExpression(EqualityExpression e) + throws VisitorException; + void visitExponentialExpression(ExponentialExpression e) + throws VisitorException; + void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException; + void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException; + void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException; + void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException; + void visitIncDecStatement(IncDecStatement s) throws VisitorException; + void visitInequalityExpression(InequalityExpression e) + throws VisitorException; + void visitIntegerExpression(IntegerExpression e) throws VisitorException; + void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException; + void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException; + void visitLessThanExpression(LessThanExpression e) + throws VisitorException; + void visitLoopExpression(LoopExpression e) throws VisitorException; + void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException; + void visitNegateExpression(NegateExpression e) throws VisitorException; + void visitNotExpression(NotExpression e) throws VisitorException; + void visitOrExpression(OrExpression e) throws VisitorException; + void visitPeekExpression(PeekExpression e) throws VisitorException; + void visitProbeExpression(ProbeExpression e) throws VisitorException; + void visitReceiveExpression(ReceiveExpression e) throws VisitorException; + void visitRemainderExpression(RemainderExpression e) + throws VisitorException; + void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException; + void visitStringExpression(StringExpression e) + throws VisitorException; + void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException; + void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException; + void visitSubtractExpression(SubtractExpression e) + throws VisitorException; + void visitXorExpression(XorExpression e) throws VisitorException; + + void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException; + void visitDeterministicRepetitionStatement( + DeterministicRepetitionStatement s) + throws VisitorException; + void visitDeterministicSelectionStatement( + DeterministicSelectionStatement s) + throws VisitorException; + void visitErrorStatement(ErrorStatement s) throws VisitorException; + void visitExpressionStatement(ExpressionStatement s) + throws VisitorException; + void visitLoopStatement(LoopStatement s) + throws VisitorException; + void visitNonDeterministicRepetitionStatement( + NonDeterministicRepetitionStatement s) + throws VisitorException; + void visitNonDeterministicSelectionStatement( + NonDeterministicSelectionStatement s) + throws VisitorException; + void visitParallelStatement(ParallelStatement s) + throws VisitorException; + void visitReceiveStatement(ReceiveStatement s) + throws VisitorException; + void visitSendStatement(SendStatement s) throws VisitorException; + void visitSequentialStatement(SequentialStatement s) + throws VisitorException; + void visitSkipStatement(SkipStatement s) throws VisitorException; + void visitVarStatement(VarStatement s) throws VisitorException; + void visitArrayType(ArrayType t) throws VisitorException; + void visitChannelType(ChannelType t) throws VisitorException; + void visitChannelStructureType(ChannelStructureType t) + throws VisitorException; + void visitIntegerType(IntegerType t) throws VisitorException; + void visitBooleanType(BooleanType t) throws VisitorException; + void visitNodeType(NodeType t) throws VisitorException; + void visitStringType(StringType t) throws VisitorException; + void visitStructureType(StructureType t) throws VisitorException; + void visitIdentifierList(IdentifierList il) throws VisitorException; + + void visitLinkageLoopTerm(LinkageLoopTerm term) throws VisitorException; + void visitLinkageExpressionTerm(LinkageExpressionTerm term) + throws VisitorException; + + void visitLinkageArrayAccessExpression(LinkageArrayAccessExpression e) + throws VisitorException; + void visitLinkageIdentifierExpression(LinkageIdentifierExpression e) + throws VisitorException; + void visitLinkageStructureAccessExpression( + LinkageStructureAccessExpression e) throws VisitorException; + void visitLoopGuard(LoopGuard s) throws VisitorException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/XorExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/XorExpression.java new file mode 100644 index 0000000000..71d01290eb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/ast/XorExpression.java @@ -0,0 +1,37 @@ +/* + * Copyright 2011 Intel Corporation. All Rights Reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.ast; + +/** + * Bitwise XOR expression, represents a ^ b . + * + * @author Kevin Duncklee + * @version $Revision$ $Date$ + **/ +public class XorExpression extends AbstractBinaryExpression { + + /** + * Class constructor. + * + * @param left left child expression, not null + * @param right right child expression, not null + **/ + public XorExpression(final ExpressionInterface left, + final ExpressionInterface right) { + super(left, right); + } + + /** + * Accepts a visitor, calling the appropriate visit method on it. + **/ + public void accept(VisitorInterface v) throws VisitorException { + v.visitXorExpression(this); + } + + public String getOperator() { return "^"; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/coverage/Monitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/coverage/Monitor.java new file mode 100644 index 0000000000..93bada1561 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/coverage/Monitor.java @@ -0,0 +1,343 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.coverage; + +import com.avlsi.util.debug.Debug; + +import java.util.*; +import java.io.*; +import java.util.zip.*; + +/** + * Store a list of code coverage probe locations, as well as a table + * indicating whether or not each probe has been reached by test + * cases. + * + * By "probes" we mean statements which have been inserted into + * generated code, to see if certain locations are reached. Not to be + * confused with CSP probes. We call the act of inserting these probes + * in a body of code "instrumenting" that code. + * + * The important parts of this class are probeTable and hitTable. When + * a section of code is instrumented, the instrumenter (usually + * JavaEmitter) will call register() with a list of probe locations + * and types. Usually, register() will extend probeTable and hitTable + * with new block of indices, one for each element in this list. It + * then returns the offset of the whole block, which can be used by + * the caller to quickly register a hit (e.g. the fifth probe would + * say Monitor.getDefault().hitTable[offset+5]=1). + * + * In order to support gathering data over multiple runs of the + * program, we also keep a table of types which have been registered. + * This way, if register() is called a second time for the same type + * name, the original offset is returned. We also check the + * modification date of the file to make sure that the file hasn't + * been modified between runs. + * + * TODO: Support for combining data from separate files (so that we + * can speed up testing by running multiple sessions on different + * computers). Note that this is one reason why not all methods and + * data members in this class should be static. + * + * @author Frederik Eaton + * @version $Revision$ $Date$ + **/ +public class Monitor { + public volatile int[] hitTable; + ProbeInfo[] probeTable; + HashMap registeredTypes; // map of String -> RegisteredType + int totalEntries; + private int allocEntries; + + public static final String defaultPath="coverage-data.zip"; + String path=defaultPath; + + /** The default global Monitor instance. This has been made a + * public data member for efficiency **/ + public static Monitor global=new Monitor(); + + private static final boolean debug=false; + + public Monitor() { + initTables(); + } + + private void initTables() { + totalEntries = 0; + allocEntries = 128; + hitTable = new int[allocEntries]; + probeTable = new ProbeInfo[allocEntries]; + registeredTypes = new HashMap(); + } + + /** Holds information for each type which has been registered by + * Monitor.register(). This includes the offset into the hitTable, + * which was returned by register() the first time it was called + * with this type **/ + private static class RegisteredType { + long lastModified; + int numProbes; + + // this isn't stored in probes file, it is set when the parser + // calls register() + int hitTableOffset; + + public RegisteredType(long lastModified, int numProbes, int hitTableOffset) { + this.lastModified = lastModified; + this.numProbes = numProbes; + this.hitTableOffset = hitTableOffset; + } + + public RegisteredType(String s) + throws ParseException { + // parse s into a registered type object and a name + String words[]=s.split(" "); + if(words.length!=3) throw new ParseException("Expected three numbers"); + String curr=null; + try { + curr=words[0]; + lastModified = new Long(curr).longValue(); + curr=words[1]; + hitTableOffset = new Integer(curr).intValue(); + curr=words[2]; + numProbes = new Integer(curr).intValue(); + } catch(NumberFormatException e) { + throw new ParseException("Expected an integer, found "+curr); + } + } + + public String toString() { + return lastModified+" "+hitTableOffset+" "+numProbes; + } + } + + private void checkInit() { + if(hitTable == null) { + Debug.assertTrue(totalEntries==0); + initTables(); + } + } + + /** Register a set of probes for a given cell type. + * @param type The fully qualified name of the type + * @param info An array giving information about each probe + * @param lastModified The modification time of the file defining + * that cell type + * @return An offset into Monitor.hitTable (or to be passed to + * Monitor.setHit(int)) + **/ + public int register(String type, ProbeInfo[] info, long lastModified) { + if(debug) System.err.println("Monitor.register("+type+", "+info.length+", "+lastModified+")"); + checkInit(); + if(registeredTypes.containsKey(type)) { + RegisteredType rt = (RegisteredType)registeredTypes.get(type); + if(rt.lastModified!=lastModified) { + System.err.println("Warning: source file has changed since last coverage"+ + " run, registering probes anyway"); + } + Debug.assertTrue(rt.numProbes == info.length); + if(debug) System.err.println("Monitor.register: previously registered type, returning "+rt.hitTableOffset); + return rt.hitTableOffset; + } else { + int offset=extendTable(info.length); + registeredTypes.put(type, new RegisteredType(lastModified, info.length, offset)); + for(int i=0; i0); + do { + allocEntries *= 2; + } while(allocEntries0 ? " ("+ + (totalEntries-count)*100/totalEntries+"% covered)" : + "")); + return count; + } + + /** Print out a list of probes which haven't been covered yet **/ + public void listCounts(PrintStream w) { + for(int i=0; i*/ tokens; + + /** + * The token that will have value 1 when the statement + * being processed should begin executing. + **/ + private String precondition = null; + + private VariableAnalyzer.Results analysisResults; + + private RefinementResolver resolver = + new RefinementResolver(RefinementResolver.NAME); + + public GmaEmitter(final CSPCellInfo cellInfo, + final PrintWriter out, + final PrintWriter warningWriter, + final PrintWriter errorWriter, + final PrintWriter debugWriter) { + this.cellInfo = cellInfo; + this.out = out; + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.tokens = new ArrayList/**/(); + this.analysisResults = null; + } + + /** + * Returns a pair of (data nodes, enable nodes) that we control + * and so need to be initialized. + **/ + private Pair/*,List>*/ emitPortList() { + // TODO: when we strip out things from the implied port list, + // we will need to handle _RESET manually here. + // do reset + // out.print("_RESET"); + + final List/**/ dataNodes = new ArrayList/**/(); + final List/**/ enableNodes = new ArrayList/**/(); + + // and the real ports + boolean first = true; + for (Iterator i = cellInfo.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition portDefinition = (PortDefinition) i.next(); + final PortTypeInterface portType = portDefinition.getType(); + final String name = portDefinition.getName(); + + if (!first) + out.print(", "); + first = false; + + if (portType instanceof com.avlsi.fast.ports.ArrayType) { + throw new AssertionError("Array ports not yet supported."); + } else if (portType instanceof com.avlsi.fast.ports.ChannelType) { + final String data = name + ".d"; + final String enable = name + ".e"; + if (portDefinition.getDirection() == PortDefinition.OUT) + dataNodes.add(data); + else { + assert portDefinition.getDirection() == PortDefinition.IN; + enableNodes.add(enable); + } + out.print(data + ", " + enable); + } else if (portType instanceof com.avlsi.fast.ports.NodeType) { + // XXX: what to do about initial value? + out.print(name); + } else if (portType instanceof + com.avlsi.fast.ports.StructureType) { + throw new AssertionError( + "Structure ports not yet supported."); + } + } + + return new Pair/*,List*/(dataNodes, enableNodes); + } + + private void processUnary(final AbstractUnaryExpression expr, + final String op) throws VisitorException { + out.print('(' + op); + expr.getExpression().accept(this); + out.print(')'); + } + + private void processBinary(final AbstractBinaryExpression expr, + final String op) + throws VisitorException { + out.print('('); + expr.getLeft().accept(this); + out.print(' ' + op + ' '); + expr.getRight().accept(this); + out.print(')'); + } + + private void processCompare(final AbstractBinaryExpression expr, + final String op) + throws VisitorException { + // convert truth values of 0 and 1 to 0 and -1 + out.print("(-"); + processBinary(expr, op); + out.print(')'); + } + + /** + * Inspect the sets of uninitialized variables returned by variable + * analysis. + * XXX: duplicates code with JavaEmitter.processResults(). + **/ + private Set/**/ processResults(VariableAnalyzer.Results r) { + if (r.getUnusedSet().size() != 0) { + for (final Iterator i = r.getUnusedSet().iterator(); + i.hasNext(); ) { + errorWriter.println ("CSP undeclared variable " + + ((String) i.next()) + + " is set, but not used."); + } + errorWriter.flush(); + warningWriter.flush(); + // throw new Error ("CSP undeclared variable is set, but not used."); + } + if (r.getUninitializedSet().size() != 0) { + for (final Iterator i = r.getUninitializedSet().iterator(); + i.hasNext(); ) { + errorWriter.println ("CSP undeclared variable " + + ((String) i.next()) + + " is uninitialized."); + } + errorWriter.flush(); + warningWriter.flush(); + throw new Error ("Uninitialized variables in " + + cellInfo.getType() + '.'); + } + + final Set/**/ undeclaredVars = new HashSet/**/(); + Map m = r.getUndeclaredTypes(); + for (final Iterator i = m.keySet().iterator(); i.hasNext(); ) { + String name = (String) i.next(); + Type type = (Type) m.get(name); + + if (type == null + || type instanceof IntegerType + || type instanceof BooleanType) + undeclaredVars.add(name); + else { + errorWriter.flush(); + warningWriter.flush(); + throw new Error ("Undeclared variable has unsupported type."); + } + } + + return undeclaredVars; + } + + private void emitChannelGroup( + final /*@ non_null @*/ List/**/ nodes, + final /*@ non_null @*/ String groupName) { + if (!nodes.isEmpty()) { + out.print("group " + groupName + '('); + boolean first = true; + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + final String node = (String) i.next(); + if (!first) + out.print(", "); + first = false; + out.print(node); + } + out.println(");"); + } + } + + + public void visitCSPProgram(CSPProgram e) throws VisitorException { + // determine correspondence between function calls and function + // declarations, and structure types and structure declarations + resolver.resolve(e); + e = resolver.getCSPProgram(); + + // quote the type name in case of ()'s from meta params + out.print("define \"" + cellInfo.getType() + "\"("); + final Pair/*,List>*/ p = emitPortList(); + out.println(") {"); + + // set all enables to 0 and data rails to -1 + final List/**/ dataNodes = (List) p.getFirst(); + final List/**/ enableNodes = (List) p.getSecond(); + emitChannelGroup(dataNodes, "$channel_data"); + emitChannelGroup(enableNodes, "$channel_enables"); + + // XXX: function declarations + + // emit a group of the undeclared variables + final boolean haveUndeclaredVars; + try { + analysisResults = + new VariableAnalyzer(cellInfo).getResults(e, resolver); + final Set/**/ undeclaredVars = + processResults(analysisResults); + + // Groups of size 0 are not allowed. + haveUndeclaredVars = !undeclaredVars.isEmpty(); + if (haveUndeclaredVars) { + out.print("group $undeclared_vars("); + boolean first = true; + for (Iterator i = undeclaredVars.iterator(); i.hasNext(); ) { + final String undeclaredVar = (String) i.next(); + if (!first) + out.print(','); + first = false; + out.print(undeclaredVar); + } + out.println(");"); + } + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage()); + } + + // start gma block + out.println("gma {"); + + // handle reset + out.println("_RESET == 0 ->"); + // set variables to zero + out.println(" instant $tokens = 0,"); + if (haveUndeclaredVars) + out.println(" instant $undeclared_vars = 0,"); + if (!dataNodes.isEmpty()) + out.println(" instant $channel_data = -1,"); + if (!enableNodes.isEmpty()) + out.println(" instant $channel_enables = 0,"); + out.println(" $tok_start = 1"); + + // Because of the way things are set up elsewhere, we might end up + // wiring a token to the starting token. Wiring anything to + // $tok_start is not good. Add in another token to prevent this. + out.println("_RESET == 1 && $tok_start ->"); + // disable self + out.println(" instant $tok_start = 0,"); + // pass on token + precondition = genToken(); + out.println(" " + precondition + " = 1"); + + // handle initializer statement to deal with top-level constants + // TODO: Share top-level constants, as this wastes memory + if (e.getInitializerStatement() != null) + e.getInitializerStatement().accept(this); + + // csp body + e.getStatement().accept(this); + + // end gma block + out.println('}'); + + // declare token group + out.print("group $tokens("); + for (int i = 0; i < tokens.size(); ++i) { + final String token = (String) tokens.get(i); + if (i != 0) + out.print(','); + out.print(token); + } + out.println(");"); + + // end cell definition + out.println('}'); + + // again, quote the type name + out.println('"' + cellInfo.getType() + "\" x;"); + } + + /** + * Return a new autogenerated variable number. + **/ + private int genVarNum() { + return varNum++; + } + + private String genToken() { + final String token = "$tok_" + tokenNum++; + tokens.add(token); + return token; + } + + public void visitAddExpression(AddExpression e) + throws VisitorException { + processBinary(e, "+"); + } + + public void visitAndExpression(AndExpression e) + throws VisitorException { + processBinary(e, "&"); + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + out.print("EXT("); + e.getBitsExpression().accept(this); + out.print(','); + e.getMinExpression().accept(this); + out.print(','); + e.getMaxExpression().accept(this); + out.print(')'); + } + + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + final ExpressionInterface func = e.getFunctionExpression(); + if (func instanceof IdentifierExpression && + ((IdentifierExpression) func).getIdentifier().equals("print")) { + final Iterator actuals = e.getActuals(); + if (actuals.hasNext()) { + final ExpressionInterface arg = + (ExpressionInterface) actuals.next(); + if (!actuals.hasNext()) { + new AssignmentStatement(new IdentifierExpression("stdout"), + arg).accept(this); + return; + } + } + } + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + processBinary(e, "/"); + } + + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + processBinary(e, "**"); + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + processCompare(e, "=="); + } + + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + processCompare(e, ">="); + } + + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + processCompare(e, ">"); + } + + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + processCompare(e, "!="); + } + + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + processCompare(e, "<="); + } + + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + processCompare(e, "<"); + } + + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + if (e.getRadix() == 10) + out.print(e.getValue()); + else if (e.getRadix() == 16) + out.print("0x" + e.getValue()); + else { + // write other bases in hex for no particular reason + out.print("0x" + new BigInteger(e.getValue(), e.getRadix()) + .toString(16)); + } + } + + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + processBinary(e, "<<"); + } + + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + processBinary(e, ">>"); + } + + public void visitIdentifierExpression(IdentifierExpression e) { + out.print(e.getIdentifier()); + } + + public void visitLoopExpression(LoopExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + processBinary(e, "*"); + } + + public void visitNegateExpression(NegateExpression e) + throws VisitorException { + processUnary(e, "-"); + } + + public void visitNotExpression(NotExpression e) + throws VisitorException { + processUnary(e, "~"); + } + + public void visitOrExpression(OrExpression e) + throws VisitorException { + processBinary(e, "|"); + } + + public void visitXorExpression(XorExpression e) + throws VisitorException { + processBinary(e, "^"); + } + + public void visitPeekExpression(PeekExpression e) + throws VisitorException { + // inside guard: #L? == L.d + // outside guard: #L? == ( [ L.d >= 0 ] ; L.d ) + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitProbeExpression(ProbeExpression e) + throws VisitorException { + // #L == (L.d >= 0) + // #R == R.e + + final ExpressionInterface chanExpr = e.getChannelExpression(); + // The type checking pass should have ensured that this is indeed + // a channel type. + final ChannelType type = + (ChannelType) analysisResults.getType(chanExpr); + if (chanExpr instanceof IdentifierExpression) { + final IdentifierExpression identExpr = + (IdentifierExpression) chanExpr; + final String channel = identExpr.getIdentifier(); + if (type.getDirection() == PortDirection.IN) { + // Add - to compensate for difference in gma and csp + // comparison semantics. + out.println("(-(" + channel + ".d >= 0))"); + } else { + assert type.getDirection() == PortDirection.OUT; + out.println('-' + channel + ".e"); + } + } else { + assert chanExpr instanceof ArrayAccessExpression; + throw new AssertionError("Arrays not yet supported."); + } + } + + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + processBinary(e, "%"); + } + + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + processBinary(e, "-"); + } + + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + // our precondition + out.println("_RESET == 1 && " + precondition + " ->"); + // disable self + out.println(" instant " + precondition + " = 0,"); + // pass on token + precondition = genToken(); + out.println(" " + precondition + " = 1,"); + // do the assignment + // XXX: support array and structure access + out.print(" instant "); + if (s.getLeftHandSide() instanceof BitRangeExpression) { + final BitRangeExpression bitRangeExpression = + (BitRangeExpression) s.getLeftHandSide(); + out.print("INS("); + bitRangeExpression.getBitsExpression().accept(this); + out.print(','); + s.getRightHandSide().accept(this); + out.print(','); + bitRangeExpression.getMinExpression().accept(this); + out.print(','); + bitRangeExpression.getMaxExpression().accept(this); + out.println(')'); + } else { + s.getLeftHandSide().accept(this); + out.print(" = "); + s.getRightHandSide().accept(this); + out.println(); + } + } + + private void emitWire(final String node1, final String node2) { + // End and restart the gma block because wires need to be outside + out.println('}'); + out.println("wire(" + node1 + ", " + node2 + ");"); + out.println("gma {"); + } + + public void processDeterministicSelectionOrRepetition( + final AbstractGuardedStatement s, + final boolean isRepetition) + throws VisitorException { + // XXX: does not detect multiple true guards + // TODO: This implementation has needless token transitions, + // optimize them away. + final String loopPrecondition = precondition; + final String loopPostcondition = genToken(); + // The statement to go to after an alternative has been executed. + // This will be the beginning of the loop for a repetition, or + // the statement after the loop for a selection. + final String afterStatement = + isRepetition ? loopPrecondition : loopPostcondition; + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommand gc = (GuardedCommand) i.next(); + // handle guard + out.print("_RESET == 1 && " + loopPrecondition + " && "); + gc.getGuard().accept(this); + out.println(" ->"); + // disable self + out.println(" instant " + loopPrecondition + " = 0,"); + // pass on token + precondition = genToken(); + out.println(" " + precondition + " = 1"); + + // handle body + gc.getCommand().accept(this); + + // go back to beginning of loop or after loop + emitWire(afterStatement, precondition); + } + + if (isRepetition || s.getElseStatement() != null) { + // handle loop exit + // if all guards are false ... + out.print("_RESET == 1 && " + loopPrecondition); + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommand gc = (GuardedCommand) i.next(); + // handle guard + out.print(" && ~"); + gc.getGuard().accept(this); + } + out.println(" ->"); + // disable self + out.println(" instant " + loopPrecondition + " = 0,"); + + if (s.getElseStatement() != null) { + // pass on token + precondition = genToken(); + out.println(" " + precondition + " = 1"); + + // else statement, loop can not exit + + // handle else + s.getElseStatement().accept(this); + + // and go back to beginning of loop or after the loop + emitWire(afterStatement, precondition); + } else { + // no else statement, loop can exit + + // pass on token + out.println(" " + loopPostcondition + " = 1"); + } + } + + precondition = loopPostcondition; + } + + public void visitDeterministicRepetitionStatement( + DeterministicRepetitionStatement s) + throws VisitorException { + processDeterministicSelectionOrRepetition(s, true); + } + + public void visitDeterministicSelectionStatement( + DeterministicSelectionStatement s) + throws VisitorException { + processDeterministicSelectionOrRepetition(s, false); + } + + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + final ExpressionInterface expr = s.getExpression(); + if (expr instanceof FunctionCallExpression) { + expr.accept(this); + return; + } + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitLoopStatement(LoopStatement s) throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitNonDeterministicRepetitionStatement( + NonDeterministicRepetitionStatement s) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitNonDeterministicSelectionStatement( + NonDeterministicSelectionStatement s) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitLinkageLoopTerm(final LinkageLoopTerm term) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitLinkageExpressionTerm(final LinkageExpressionTerm term) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitLinkageArrayAccessExpression( + final LinkageArrayAccessExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitLinkageIdentifierExpression( + final LinkageIdentifierExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitLinkageStructureAccessExpression( + final LinkageStructureAccessExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + // TODO: factor out parallel assignments to all be done at once + final String parallelPrecondition = precondition; + final ArrayList/**/ preconditions = + new ArrayList/**/(); + final ArrayList/**/ postconditions = + new ArrayList/**/(); + + for (Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + + // This token will be activated by the fork, which we emit + // below. + precondition = genToken(); + preconditions.add(precondition); + + // emit the parallel code + stmt.accept(this); + + // keep track of all post-conditions so we can do the join + postconditions.add(precondition); + } + + // Emit the join after the parallel statements. A bit awkward, + // but better than storing all the statements to get them + // in the "right" order. + + // fork + out.println("_RESET == 1 && " + parallelPrecondition + " ->"); + // enable children + for (int i = 0; i < preconditions.size(); ++i) { + final String precondition = (String) preconditions.get(i); + out.println(" " + precondition + " = 1,"); + } + // disable self + out.println(" instant " + parallelPrecondition + " = 0"); + + // join + out.print("_RESET == 1"); + for (int i = 0; i < postconditions.size(); ++i) { + final String postcondition = (String) postconditions.get(i); + out.print(" && " + postcondition); + } + out.println(" ->"); + // disable all children + for (int i = 0; i < postconditions.size(); ++i) { + final String postcondition = (String) postconditions.get(i); + out.println(" instant " + postcondition + " = 0,"); + } + // enable next statement + precondition = genToken(); + out.println(" " + precondition + " = 1"); + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + // L?x == ( L.e = 1 ; [ L.d >= 0 ] ; x = L.d + // ; L.e = 0 ; [ L.d < 0 ] ) + // == $pre0 -> L.e = 1, $pre0 = 0, $pre1 = 1 + // $pre1 && L.d >= 0 -> x = L.d, $pre1 = 0, $pre2 = 1 + // $pre2 -> L.e = 0, $pre2 = 0, $pre3 = 1 + // $pre3 && L.d < 0 -> $pre3 = 0, $pre4 = 1 + // Good test cases include: + // 1. L[getTime() % N]?x + // 2. L[x]?x + // These will ensure channel is evaluated only once + + // Using 2-phase handshaking, this becomes: + // L?x == ( [ L.e != L.v ] ; x = L.d ; L.e = !L.e ) + // == $pre0 && L.e != L.v -> x = L.d, $pre0 = 0, $pre1 = 1 + // == $pre1 -> L.e = !L.e, $pre1 = 0, $pre2 = 1 + // R!x == ( [ R.e == R.v ] ; R.d = x ; R.v = !R.v ) + // == $pre0 && R.e == R.v -> R.d = x, $pre0 = 0, $pre1 = 1 + // == $pre1 -> R.v = !R.v, $pre1 = 0, $pre2 = 1 + // #L == ( L.e != L.v ) + // #R == ( R.e == R.v ) + + final ExpressionInterface chanExpr = s.getChannelExpression(); + final String data; + final String enable; + if (chanExpr instanceof IdentifierExpression) { + final IdentifierExpression identExpr = + (IdentifierExpression) chanExpr; + final String channel = identExpr.getIdentifier(); + data = channel + ".d"; + enable = channel + ".e"; + } else { + assert chanExpr instanceof ArrayAccessExpression; + throw new AssertionError("Arrays not yet supported."); + } + + // now process the expanded version + // TODO: this probably won't work too well for the array version + // TODO: currently, this is a bit inefficient because there are: + // * extra -'s from the comparisons + // * extra wire() statements + // * extra skip statements + final IdentifierExpression dataExpr = new IdentifierExpression(data); + final IdentifierExpression enableExpr = + new IdentifierExpression(enable); + final IntegerExpression zero = new IntegerExpression("0", 10); + // L.e = 1 + new AssignmentStatement(enableExpr, + new IntegerExpression("1", 10)).accept(this); + // [ L.d >= 0 -> x = L.d ] + final DeterministicSelectionStatement waitValid = + new DeterministicSelectionStatement(); + waitValid.addGuardedCommand(new GuardedCommand( + new GreaterEqualExpression(dataExpr, zero), + s.getRightHandSide() != null + ? (StatementInterface) new AssignmentStatement( + s.getRightHandSide(), dataExpr) + : (StatementInterface) new SkipStatement())); + waitValid.accept(this); + // L.e = 0 + new AssignmentStatement(enableExpr, zero).accept(this); + // [ L.d < 0 ] + final DeterministicSelectionStatement waitNeutral = + new DeterministicSelectionStatement(); + waitNeutral.addGuardedCommand(new GuardedCommand( + new LessThanExpression(dataExpr, zero), + new SkipStatement())); + waitNeutral.accept(this); + } + + public void visitSendStatement(SendStatement s) + throws VisitorException { + // R!x == ( [ R.e ] ; R.d = POSMOD(x, numValues) + // ; [ !R.e ] ; R.d = -1 ) + // == $pre0 && R.e -> R.d = POSMOD(x, numValues), + // $pre0 = 0, $pre1 = 1 + // $pre1 && !R.e -> R.d = -1, $pre1 = 0, $pre2 = 1 + // Good test cases include: + // 1. R[getTime() % N]!x + // This will ensure channel is evaluated only once + + final ExpressionInterface chanExpr = s.getChannelExpression(); + final String data; + final String enable; + if (chanExpr instanceof IdentifierExpression) { + final IdentifierExpression identExpr = + (IdentifierExpression) chanExpr; + final String channel = identExpr.getIdentifier(); + data = channel + ".d"; + enable = channel + ".e"; + } else { + assert chanExpr instanceof ArrayAccessExpression; + throw new AssertionError("Arrays not yet supported."); + } + + // The type checking pass should have ensured that this is indeed + // a channel type and that the direction is appropriate + final ChannelType type = + (ChannelType) analysisResults.getType(chanExpr); + assert type.getDirection() == PortDirection.OUT; + final BigInteger numValues = type.getNumValues(); + assert numValues.signum() == 1; + + // [ R.e -> R.d = POSMOD(x, numValues) ] + out.println("_RESET == 1 && " + precondition + + " && " + enable + " ->"); + // disable self + out.println(" instant " + precondition + " = 0,"); + // assign data + out.print(" instant " + data + " = "); + out.print("POSMOD("); + s.getRightHandSide().accept(this); + // Channel widths will generally be more understandable in hex + out.println(", 0x" + numValues.toString(16) + "),"); + // enable next + precondition = genToken(); + out.println(" " + precondition + " = 1"); + + // [ !R.e -> R.d = -1 ] + out.println("_RESET == 1 && " + precondition + + " && !" + enable + " ->"); + // disable self + out.println(" instant " + precondition + " = 0,"); + // assign data + out.println(" instant " + data + " = -1,"); + // enable next + precondition = genToken(); + out.println(" " + precondition + " = 1"); + } + + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + for (final Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + stmt.accept(this); + } + } + + public void visitErrorStatement(ErrorStatement s) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitSkipStatement(SkipStatement s) + throws VisitorException { + // TODO: optimize this token transition away. + // if we do, we need to make sure *[skip] works + out.println("_RESET == 1 && " + precondition + " ->"); + // disable self + out.println(" instant " + precondition + " = 0,"); + // enable next + precondition = genToken(); + out.println(" " + precondition + " = 1"); + } + + public void visitVarStatement(VarStatement s) + throws VisitorException { + for (Iterator i = s.getDeclarationList().getDeclarations(); + i.hasNext(); ) { + final Declaration declaration = (Declaration) i.next(); + + for (Iterator j = + declaration.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator declarator = (Declarator) j.next(); + + // XXX: support only integer declarations + assert declarator.getTypeFragment() instanceof IntegerType; + + // add the variable to the set of declared variables + // XXX: we currently do not support variables with the + // same name in parallel scopes. + // declaredVariables.add(declarator.getIdentifier() + // .getIdentifier()); + + // emit an assignment of the variable to its initial value + new AssignmentStatement(declarator.getIdentifier(), + declarator.getInitializer() != null + ? declarator.getInitializer() + : new IntegerExpression("0", 10)) + .accept(this); + } + } + + // only support new style declarations + assert s.getStatement() == null; + } + + + public void visitArrayType(ArrayType t) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitChannelType(ChannelType t) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitIntegerType(IntegerType t) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitBooleanType(BooleanType t) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitNodeType(NodeType t) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitStringType(StringType t) throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitStructureType(StructureType t) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitIdentifierList(IdentifierList il) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } + + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + throw new AssertionError("CSP construct not yet supported"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/.empty b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/.empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/ArbiterVisitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/ArbiterVisitor.java new file mode 100644 index 0000000000..8af2c82bf5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/ArbiterVisitor.java @@ -0,0 +1,820 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2java; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.avlsi.csp.ast.*; +import com.avlsi.csp.util.UniqueLabel; +import com.avlsi.util.container.Pair; +import com.avlsi.util.text.StringUtil; + +/** + * Visitor to find all nodes involved in linked arbitration and create + * Arbiter.Linkages for them. + * + * The sequence of the statements that gets visited must be identical to the + * sequence used by JavaEmitter, otherwise the linkage objects won't match up + * properly. See bug 12054. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +class ArbiterVisitor implements VisitorInterface { + + /** + * List of ArbiterLinkages that + **/ + private final ArrayList arbiters = + new ArrayList(); + + /** + * List of Term[]s for the guards of the arbiter + * that is currently being built up. + **/ + private ArrayList guards = null; + + /** + * List of Terms for the nodes in an arbitration condition + * that is currently being built up. + **/ + private ArrayList terms = null; + + /** + * The linked node that is currently being built up. + **/ + private TermInterface term = null; + + /** + * The JavaEmitter used to generate code for index expressions in a linkage + * term. + **/ + private JavaEmitter javaEmitter; + + /** + * Maps from neutral linkage terms to ints to label linkage objects. + **/ + private UniqueLabel linkageLabel; + + /** + * The old and current PrintWriters that javaEmitter is using. + **/ + private PrintWriter oldWriter, currWriter; + + /** + * Destination of captured output from javaEmitter. + **/ + private StringWriter stringWriter; + + ArbiterVisitor(final JavaEmitter javaEmitter, + final UniqueLabel linkageLabel) { + this.javaEmitter = javaEmitter; + this.linkageLabel = linkageLabel; + } + + void declareLinkages(final PrintWriter out) { + for (ArbiterLinkage link : arbiters) { + out.println("private final Linkage " + link.getName() + ";"); + } + } + + void initLinkages(final PrintWriter out) throws VisitorException { + for (ArbiterLinkage link : arbiters) { + out.print(link.getName() + " = " + + "deviceParams.getArbitrationMode() == " + + "Arbiter.NON_LINKED ? null : "); + link.emitInitializer(out); + } + } + + void destroyLinkages(final PrintWriter out) { + for (ArbiterLinkage link : arbiters) { + final String l = link.getName(); + out.println("if (" + l + " != null) " + l + ".destroy();"); + } + } + + private static final class ArbiterLinkage { + private final TermInterface[][] guardTerms; + private final TermInterface[] neutralState; + private final int id; + + private ArbiterLinkage(final TermInterface[][] guardTerms, + final TermInterface[] neutralState, + final int id) { + this.guardTerms = guardTerms; + this.neutralState = neutralState; + this.id = id; + } + + private void emitInitializer(final PrintWriter out) + throws VisitorException { + out.println("new Linkage("); + emitGuards(guardTerms, out); + out.println(','); + out.print("flattenTerms("); + emitTerms(neutralState, out); + out.println("), deviceParams.getArbitrationMode()"); + out.println(");"); + } + + private static void emitGuards(final TermInterface[][] guardTerms, + final PrintWriter out) + throws VisitorException { + out.println("flattenTerms(new Term[][][]{"); + for (int i = 0; i < guardTerms.length; ++i) { + emitGuardTerms(guardTerms[i], out); + if (i < guardTerms.length - 1) out.print(", "); + } + out.println("})"); + } + + private static void emitGuardTerms(final TermInterface[] terms, + final PrintWriter out) + throws VisitorException { + if (terms[0] instanceof GuardTerm) { + assert terms.length == 1; + out.println(terms[0].getCode()); + } else { + emitTerms(terms, out); + } + } + + private static void emitTerms(final TermInterface[] terms, + final PrintWriter out) + throws VisitorException { + out.print("new Term[][] {"); + out.print("flattenTerms(new Term[][] {"); + for (int i = 0; i < terms.length; ++i) { + out.print(terms[i].getCode()); + if (i < terms.length - 1) out.print(", "); + } + out.print("})"); + out.print(" }"); + } + + public String getName() { + return "linkage" + id; + } + } + + /** + * Start capturing output from the JavaEmitter. + **/ + private void startCapture() { + oldWriter = javaEmitter.getOutputWriter(); + stringWriter = new StringWriter(); + currWriter = new PrintWriter(stringWriter); + javaEmitter.setOutputWriter(currWriter); + } + + /** + * Stop capturing output from the JavaEmitter, and returned the string + * captured so far. + **/ + private String endCapture() { + currWriter.close(); + javaEmitter.setOutputWriter(oldWriter); + return stringWriter.toString(); + } + + private interface TermInterface { + /** + * Returns an Java expression that generates the appropriate code to + * reprsent the term. + **/ + String getCode() throws VisitorException; + } + + private final class GuardTerm implements TermInterface { + private final Collection terms; + private final Range range; + private final IdentifierExpression var; + private GuardTerm(final Collection terms, final Range range, + final IdentifierExpression var) { + this.terms = terms; + this.range = range; + this.var = var; + } + + /** + * Generates code that when evaluated has type Term[]. This flattens + * the terms associated with one guard: + * @(<,i:2: (x[i])>, y[0]) becomes @(x[0], x[1], y[0]) + **/ + private void emitSimpleGuard(final TermInterface[] terms, + final StringBuffer buf) + throws VisitorException { + buf.append("flattenTerms(new Term[][] { "); + boolean first = true; + for (TermInterface term : terms) { + if (first) first = false; + else buf.append(", "); + buf.append(term.getCode()); + } + buf.append(" })"); + } + + /** + * Generates code that when evaluated has type Term[][]. The first + * dimension is the guard. + **/ + public String getCode() throws VisitorException { + final StringBuffer buf = new StringBuffer(); + buf.append("(new LinkageHelper.GuardUnroller() {\n"); + buf.append("public Term[][] evaluate(final CspInteger "); + startCapture(); + var.accept(javaEmitter); + buf.append(endCapture()); + buf.append(") throws InterruptedException {\n"); + buf.append("return flattenTerms(new Term[][][] { "); + boolean first = true; + for (Iterator i = terms.iterator(); i.hasNext(); ) { + if (first) first = false; + else buf.append(", "); + final Object o = (Object) i.next(); + if (o instanceof GuardTerm) { + buf.append(((GuardTerm) o).getCode()); + } else { + buf.append("new Term[][] { "); + emitSimpleGuard((TermInterface[]) o, buf); + buf.append(" }"); + } + } + buf.append("});\n"); + buf.append('}'); + buf.append("}.unroll("); + startCapture(); + range.getMinExpression().accept(javaEmitter); + buf.append(endCapture()); + buf.append(", "); + startCapture(); + range.getMaxExpression().accept(javaEmitter); + buf.append(endCapture()); + buf.append("))"); + return buf.toString(); + } + } + + private final class LoopTerm implements TermInterface { + private final TermInterface term; + private final Range range; + private final IdentifierExpression var; + private LoopTerm(final TermInterface term, final Range range, + final IdentifierExpression var) { + this.term = term; + this.range = range; + this.var = var; + } + + /** + * Generates code that when evaluated has type Term[]. + **/ + public String getCode() throws VisitorException { + final StringBuffer buf = new StringBuffer(); + buf.append("(new LinkageHelper.NeutralityUnroller() {\n"); + buf.append("public Term[] evaluate(final CspInteger "); + startCapture(); + var.accept(javaEmitter); + buf.append(endCapture()); + buf.append(") throws InterruptedException {\n"); + buf.append("return "); + buf.append(term.getCode()); + buf.append(';'); + buf.append('}'); + + buf.append("}.unroll("); + startCapture(); + range.getMinExpression().accept(javaEmitter); + buf.append(endCapture()); + buf.append(", "); + startCapture(); + range.getMaxExpression().accept(javaEmitter); + buf.append(endCapture()); + buf.append("))"); + return buf.toString(); + } + } + + private static final class Term implements TermInterface { + private static final class Part { + public final boolean type; + public final StringBuffer text; + public Part(final String text, final boolean type) { + this.text = new StringBuffer(text); + this.type = type; + } + } + + private final List parts; + private final boolean isNegated; + private Part last; + + private Term(final boolean isNegated) { + this.parts = new ArrayList(); + this.isNegated = isNegated; + this.last = null; + } + + private void add(final String part, final boolean type) { + if (last != null && last.type == type) { + last.text.append(part); + return; + } + last = new Part(part, type); + parts.add(last); + } + + public Term append(final char literal) { + return append(String.valueOf(literal)); + } + + public Term append(final String literal) { + add(literal, true); + return this; + } + + public Term addCode(final String code) { + add(code, false); + return this; + } + + /** + * Generates code that when evaluated has type Term[]. + **/ + public String getCode() throws VisitorException { + final StringBuffer buf = new StringBuffer(); + buf.append("getTerm(deviceParams.getName(), "); + for (Iterator i = parts.iterator(); i.hasNext(); ) { + final Part part = (Part) i.next(); + if (part.type) { + buf.append('"'); + buf.append( + StringUtil.replaceSubstring(part.text, "][", ",")); + buf.append('"'); + } else { + buf.append('('); + buf.append(part.text); + buf.append(')'); + buf.append(".toString()"); + } + if (i.hasNext()) buf.append(" + "); + } + buf.append(", "); + buf.append(isNegated); + buf.append(')'); + return buf.toString(); + } + } + + private void unsupported(AbstractASTNodeInterface node) + throws VisitorException { + throw new VisitorException("Unsupported syntax in arbiter " + + "linkage at " + node.getParseRange()); + } + + public void visitCSPProgram(CSPProgram p) throws VisitorException { + // there may be linkage nodes in the function definitions + for (final Iterator i = p.getFunctionDeclarations(); i.hasNext(); ) { + final FunctionDeclaration funcDecl = + (FunctionDeclaration) i.next(); + funcDecl.getBodyStatement().accept(this); + } + + // body + final StatementInterface stmt = p.getStatement(); + if (stmt != null) stmt.accept(this); + } + + public void visitAddExpression(AddExpression e) throws VisitorException { + unsupported(e); + } + + public void visitAndExpression(AndExpression e) throws VisitorException { + unsupported(e); + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + unsupported(e); + // e.getArrayExpression().accept(this); + // term.append('['); + // e.getIndexExpression().accept(this); + // term.append(']'); + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + unsupported(e); + // term.append(e.getIdentifier()); + } + + public void visitIncDecStatement(IncDecStatement e) + throws VisitorException { + // empty + } + + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + ((Term) term).append(new BigInteger(e.getValue(), e.getRadix()).toString()); + } + + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitLoopExpression(LoopExpression e) throws VisitorException { + unsupported(e); + } + + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitNegateExpression(NegateExpression e) throws VisitorException { + unsupported(e); + } + + public void visitNotExpression(NotExpression e) throws VisitorException { + unsupported(e); + } + + public void visitOrExpression(OrExpression e) throws VisitorException { + unsupported(e); + } + + public void visitXorExpression(XorExpression e) throws VisitorException { + unsupported(e); + } + + public void visitPeekExpression(PeekExpression e) throws VisitorException { + unsupported(e); + } + + public void visitProbeExpression(ProbeExpression e) throws VisitorException { + unsupported(e); + } + + public void visitReceiveExpression(ReceiveExpression e) throws VisitorException { + unsupported(e); + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + } + + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + unsupported(e); + // e.getStructureExpression().accept(this); + // term.append('.').append(e.getFieldName()); + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + unsupported(e); + } + + + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + // empty + } + + public void visitDeterministicRepetitionStatement( + DeterministicRepetitionStatement s) + throws VisitorException { + processGuardedStatement(s, null); + } + + private void recurseGuards(Iterator g) throws VisitorException { + for (final Iterator i = g; i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + if (gci instanceof LoopGuard) { + final LoopGuard lg = (LoopGuard) gci; + recurseGuards(lg.getGuards().iterator()); + } else { + final GuardedCommand guardedCommand = (GuardedCommand) gci; + guardedCommand.getCommand().accept(this); + } + } + } + + private TermInterface getLinkageTerms(final LoopGuard loop) + throws VisitorException { + final List result = new ArrayList(); + for (Iterator i = loop.getGuards().iterator(); i.hasNext(); ) { + final Object guard = i.next(); + if (guard instanceof LoopGuard) { + result.add(getLinkageTerms((LoopGuard) guard)); + } else { + final GuardedCommand gc = (GuardedCommand) guard; + result.add(processLinkageTerms(gc.getLinkageTerms())); + } + } + return new GuardTerm(result, loop.getRange(), + loop.getIndexVarExpression()); + } + + private void processGuardedStatement( + final AbstractGuardedStatement s, + final LinkageTerms neutralState) throws VisitorException { + assert guards == null; + + // construct the arbiter at this level first + if (neutralState != null) { + guards = new ArrayList(); + + for (final Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + if (gci instanceof LoopGuard) { + guards.add(new TermInterface[] { + getLinkageTerms((LoopGuard) gci) } ); + } else { + final GuardedCommand gc = (GuardedCommand) gci; + guards.add(processLinkageTerms(gc.getLinkageTerms())); + } + } + + arbiters.add + (new ArbiterLinkage + ((TermInterface[][]) guards.toArray( + new TermInterface[guards.size()][]), + processLinkageTerms(neutralState), + linkageLabel.getLabel(neutralState))); + guards = null; + } + + if (s.getElseStatement() != null) + s.getElseStatement().accept(this); + + // then find any lower ones + recurseGuards(s.getGuardedCommands()); + } + + public void visitDeterministicSelectionStatement( + DeterministicSelectionStatement s) + throws VisitorException { + processGuardedStatement(s, null); + } + + public void visitErrorStatement(ErrorStatement s) throws VisitorException { + // empty + } + + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + // empty + } + + public void visitLoopStatement(LoopStatement s) + throws VisitorException { + // empty + // XXX: Doing nothing isn't quite right. We could have linked + // arbiters inside the body, but we'll assume this is not the case. + } + + public void visitNonDeterministicRepetitionStatement( + NonDeterministicRepetitionStatement s) + throws VisitorException { + assert s.getNeutralState() == null; + processGuardedStatement(s, null); + } + + public void visitNonDeterministicSelectionStatement( + NonDeterministicSelectionStatement s) + throws VisitorException { + processGuardedStatement(s, s.getNeutralState()); + } + + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + processCompositeStatement(s); + } + + private void processCompositeStatement(AbstractCompositeStatement s) + throws VisitorException { + for (final Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface subStmt = + (StatementInterface) i.next(); + subStmt.accept(this); + } + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + // empty + } + + public void visitSendStatement(SendStatement s) throws VisitorException { + // empty + } + + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + processCompositeStatement(s); + } + + public void visitSkipStatement(SkipStatement s) throws VisitorException { + // empty + } + + public void visitVarStatement(VarStatement s) throws VisitorException { + // empty + } + + public void visitArrayType(ArrayType t) throws VisitorException { + assert false; + } + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + assert false; + } + public void visitChannelType(ChannelType t) throws VisitorException { + assert false; + } + + public void visitIntegerType(IntegerType t) throws VisitorException { + assert false; + } + + public void visitNodeType(NodeType t) throws VisitorException { + assert false; + } + + public void visitBooleanType(BooleanType t) throws VisitorException { + assert false; + } + + public void visitStringType(StringType t) throws VisitorException { + assert false; + } + + public void visitStructureType(StructureType t) throws VisitorException { + assert false; + } + + public void visitIdentifierList(IdentifierList il) + throws VisitorException { + assert false; + } + + public void visitLinkageLoopTerm(LinkageLoopTerm loopTerm) + throws VisitorException { + loopTerm.getTerm().accept(this); + term = new LoopTerm(term, loopTerm.getRange(), + loopTerm.getIndexVarExpression()); + } + + public void visitLinkageExpressionTerm(LinkageExpressionTerm t) + throws VisitorException { + assert term == null; + term = new Term(t.isInverted()); + + t.getExpression().accept(this); + } + + public void visitLinkageArrayAccessExpression( + LinkageArrayAccessExpression e) + throws VisitorException { + final Term t = (Term) term; + e.getArrayExpression().accept(this); + t.append('['); + + startCapture(); + e.getIndexExpression().accept(javaEmitter); + + t.addCode("("); + t.addCode(endCapture()); + t.addCode(").toString()"); + t.append(']'); + } + + public void visitLinkageIdentifierExpression( + LinkageIdentifierExpression e) + throws VisitorException { + ((Term) term).append(e.getIdentifier()); + } + + public void visitLinkageStructureAccessExpression( + LinkageStructureAccessExpression e) throws VisitorException { + e.getStructureExpression().accept(this); + ((Term) term).append('.').append(e.getFieldName()); + } + + private TermInterface[] processLinkageTerms(final LinkageTerms linkageTerms) + throws VisitorException { + assert terms == null; + terms = new ArrayList(); + + for (final Iterator i = linkageTerms.getTerms(); i.hasNext(); ) { + final LinkageTermInterface linkageTerm = + (LinkageTermInterface) i.next(); + linkageTerm.accept(this); + if (term != null) { + terms.add(term); + term = null; + } + } + + final TermInterface[] ts = + (TermInterface[]) terms.toArray(new TermInterface[terms.size()]); + terms = null; + return ts; + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + // currently, we don't support arbiter linking in loops + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Class.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Class.java new file mode 100644 index 0000000000..51653942ac --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Class.java @@ -0,0 +1,450 @@ +/* + * Copyright 2001 Asynchronous Digital Design. + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2java; + +import com.avlsi.csp.csp2java.CSP2Java; +import com.avlsi.csp.csp2java.SemanticException; +import com.avlsi.cell.CellInterface; +import com.avlsi.util.ext.Exec; +import com.avlsi.util.text.StringUtil; +import com.avlsi.util.debug.Debug; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.IOException; +import java.io.Writer; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import com.avlsi.io.StringBuilderWriter; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import static javax.tools.JavaFileObject.Kind.CLASS; +import static javax.tools.JavaFileObject.Kind.SOURCE; + +/** + * Compiles CSP into a java Class object. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class CSP2Class { + + PrintWriter warningWriter; + PrintWriter errorWriter; + PrintWriter debugWriter; + boolean emitCoverageProbes; + boolean emitSnoopStatements; + + public CSP2Class(PrintWriter warningWriter, PrintWriter errorWriter, + PrintWriter debugWriter, boolean emitCoverageProbes) { + this(warningWriter, errorWriter, debugWriter, emitCoverageProbes, + false); + } + + public CSP2Class(PrintWriter warningWriter, PrintWriter errorWriter, + PrintWriter debugWriter, boolean emitCoverageProbes, + boolean emitSnoopStatements) { + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.emitCoverageProbes = emitCoverageProbes; + this.emitSnoopStatements = emitSnoopStatements; + } + + /* Establish CSP2Class temporary filename conventions. */ + + private static int uniqId = 0; + private static File commPfx = new File(getTemporaryDirectory()); + private static String javaSfx = ".java"; + private static final int INITIAL_CLASS_SIZE = 16 * 1024; + private static final int INITIAL_SOURCE_SIZE = 32 * 1024; + + private static String getTemporaryDirectory() { + final String prop = + System.getProperty("com.avlsi.csp.csp2java.CSP2Class.temp"); + return prop == null ? "/scratch" : prop; + } + + /** + * Class loader used to load classes from a filename according to + * CSP2Class temporary filename conventions. Use + * + * FileClassLoader.defineClass(className); + **/ + + private static class FileClassLoader extends URLClassLoader { + private static FileClassLoader singleton = null; + + public static Class defineClass + (String className, PrintWriter debugWriter ) + throws IOException { + + /* make a singleton for accessing ClassLoader non-static + * methods */ + + try { + if (singleton == null) + singleton = new FileClassLoader(commPfx); + + debugWriter.println("Defining class: " + className); + + return singleton.loadClass (className); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } catch (MalformedURLException e) { + throw new AssertionError(e); + } + } + + private FileClassLoader(File path) throws MalformedURLException { + // First convert to URI because that escapes any characters + // that are illegal in an URL + super(new URL[]{path.toURI().toURL()}); + } + } + + private static URI toURI(final String n, final JavaFileObject.Kind k) { + return URI.create("string:///" + n.replace('.', '/') + k.extension); + } + + private static class ByteStream extends ByteArrayOutputStream { + public ByteStream() { + super(); + } + public ByteStream(int size) { + super(size); + } + public byte[] getBuffer() { + return buf; + } + public int getSize() { + return count; + } + } + + private static class MemoryFileManager extends ForwardingJavaFileManager { + private final Map classes; + + private class ByteArrayFile extends SimpleJavaFileObject { + private final String name; + private ByteArrayOutputStream out; + public ByteArrayFile(String name) { + super(toURI(name, CLASS), CLASS); + this.name = name; + } + + public OutputStream openOutputStream() throws IOException { + final ByteStream out = new ByteStream(INITIAL_CLASS_SIZE); + classes.put(name, out); + return out; + } + } + + public MemoryFileManager(JavaFileManager m) { + super(m); + classes = new HashMap(); + } + + public JavaFileObject getJavaFileForOutput(Location location, + String className, + JavaFileObject.Kind kind, + FileObject sibling) + throws IOException + { + return new ByteArrayFile(className); + } + + public ByteStream getClass(String className) { + return classes.get(className); + } + } + + private static class MemoryClassLoader extends ClassLoader { + private final MemoryFileManager manager; + public MemoryClassLoader(final MemoryFileManager manager) { + this.manager = manager; + } + + protected Class findClass(String name) throws ClassNotFoundException { + final ByteStream code = manager.getClass(name); + if (code == null) { + throw new ClassNotFoundException(name); + } else { + return defineClass(name, code.getBuffer(), 0, code.getSize()); + } + } + } + + private Class memoryCompile(CellInterface cell) + throws IOException, SemanticException { + Class result = null; + + final String className = + "CSP2ClassTemp_" + (uniqId++) + "_" + + escapeType(cell.getFullyQualifiedType()); + + final StringBuilderWriter srcCode = + new StringBuilderWriter(INITIAL_SOURCE_SIZE); + new CSP2Java(warningWriter, errorWriter, debugWriter, + emitCoverageProbes, emitSnoopStatements). + convert(cell, className, srcCode); + + final DiagnosticCollector diagnostics = + new DiagnosticCollector(); + + final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + final StandardJavaFileManager stdManager = + compiler.getStandardFileManager(diagnostics, null, null); + final MemoryFileManager fileManager = new MemoryFileManager(stdManager); + + final JavaFileObject inputFile = + new SimpleJavaFileObject(toURI(className, SOURCE), SOURCE) { + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return srcCode.getBuffer(); + } + }; + + final String classpath = System.getProperty("java.class.path", "."); + final String[] opts = new String[] { "-g", "-classpath", classpath }; + + final JavaCompiler.CompilationTask task = + compiler.getTask(null, fileManager, diagnostics, Arrays.asList(opts), + null, Collections.singletonList(inputFile)); + + boolean okay = false; + Exception except = null; + try { + okay = task.call().booleanValue(); + } catch (RuntimeException e) { + except = e; + } + + if (!okay) { + final FileWriter fw = new FileWriter (className + ".err"); + writeErrorHeader(fw); + for (Diagnostic d : diagnostics.getDiagnostics()) { + fw.write(" * " + d.getKind().toString() + ": " + + d.getMessage(null) + "\n"); + } + if (except != null) { + fw.write(" * " + except.getMessage() + "\n"); + } + fw.write(" *" + "/\n"); + fw.write(srcCode.toString()); + fw.close(); + throw new SemanticException ("Error compiling java source."); + } + + try { + return new MemoryClassLoader(fileManager).loadClass(className); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } + } + + public Class compile(CellInterface cell) + throws IOException, SemanticException { + final String diskProp = + System.getProperty("com.avlsi.csp.csp2java.disk"); + if (diskProp == null) + return memoryCompile(cell); + else + return diskCompile(cell); + } + + /** + * Compiles CSP into a java Class object. + **/ + public Class diskCompile( CellInterface cell ) + throws IOException, SemanticException { + Class result = null; + + // Construct a unique class name + + final File javaFile = File.createTempFile("CSP2ClassTemp_" + + escapeType(cell.getFullyQualifiedType()), + javaSfx, commPfx); + javaFile.deleteOnExit(); + + final String className = javaFile.getName().substring(0, + javaFile.getName().length() - javaSfx.length()); + + // Perform conversion to java source text. + + new CSP2Java(warningWriter, errorWriter, debugWriter, + emitCoverageProbes, emitSnoopStatements). + convert (cell, className, new FileWriter(javaFile)); + + // Perform compilation + + Runtime runtime = Runtime.getRuntime(); + String classpath = System.getProperty("java.class.path", "."); + + // Save standard error of the compilation to a temporary file instead + // of in memory, in case it is very long + final File javacErrFile = File.createTempFile("CSP2ClassTemp_" + + escapeType(cell.getFullyQualifiedType()), + ".javac", commPfx); + javacErrFile.deleteOnExit(); + + final int exitValue; + final PrintStream oldErr = System.err; + try { + final PrintStream err = + new PrintStream(new FileOutputStream(javacErrFile)); + final String forkProp = + System.getProperty("com.avlsi.csp.csp2java.fork"); + if (forkProp == null) { + System.setErr(err); + exitValue = com.sun.tools.javac.Main.compile( + new String[] { "-g", "-classpath", classpath, + javaFile.getPath() }); + } else { + // Wait for compilation to complete, and obtain an exit value + exitValue = Exec.exec ("javac -g -classpath " + classpath + " " + + javaFile.getPath(), null, err); + } + err.close(); + } catch (InterruptedException e) { + throw new AssertionError(e); + } finally { + System.setErr(oldErr); + } + + if (exitValue != 0) { + + // Handle compilation failure + + handleCompilationError (javacErrFile, className, javaFile); + + } else { + + // Read in the main compiled class + + result = FileClassLoader.defineClass (className, debugWriter); + + } + + // Delete files on exit + + runtime.addShutdownHook(new Thread(new Runnable() { + public void run() { + final File[] files = commPfx.listFiles( + new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.startsWith(className); + } + }); + for (int i = 0; i < files.length; i++) + files[i].delete(); + } + })); + + + return result; + } + + private void writeErrorHeader(Writer fw) throws IOException { + fw.write("/* CSP2Class CSP compiler error file.\n"); + fw.write(" * \n"); + fw.write(" * An error occurred while compiling the java output\n"); + fw.write(" * of CSP2Java. The text of the compiler error\n"); + fw.write(" * is contained at the end of this comment. The comment\n"); + fw.write(" * is followed by the text of the program.\n"); + fw.write(" * \n"); + } + + /** + * Handle an error in compilation. + **/ + private void handleCompilationError (File javacErrFile, String className, + File javaFile) throws SemanticException, IOException { + // An error occurred in compilation, so produce an error file + + FileWriter fw = new FileWriter (className + ".err"); + BufferedReader br = new BufferedReader(new FileReader(javacErrFile)); + FileReader fr = new FileReader (javaFile); + int c; + + // Write a header + writeErrorHeader(fw); + + // Write the error message + + String line; + while((line = br.readLine()) != null) { + fw.write(" * " + line + "\n"); + } + br.close(); + fw.write(" */\n"); + + // Write the java file + + while ((c = fr.read()) != -1) { + fw.write(c); + } + + // Close the files + + fw.close(); + fr.close(); + + // Throw an exception + + throw new SemanticException ("Error compiling java source."); + } + + private String escapeType(final String typeName) { + final StringBuffer sb = new StringBuffer(typeName.length()); + + for (int i = 0; i < typeName.length(); ++i) { + final char ch = typeName.charAt(i); + + if (('0' <= ch && ch <= '9') || + ('a' <= ch && ch <= 'z') || + ('A' <= ch && ch <= 'Z')) { + sb.append(ch); + } else if (ch == '_') + sb.append("__"); + else + sb.append("_" + ((int) ch) + "_"); + } + + final int maxLength = 100; + return sb.substring(0, Math.min(sb.length(), maxLength)); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Java.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Java.java new file mode 100644 index 0000000000..4d5560699c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/CSP2Java.java @@ -0,0 +1,236 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.csp.csp2java; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Writer; + +import java.util.ListIterator; + +import com.avlsi.io.FileSearchPath; + +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; + +import com.avlsi.csp.ast.VisitorException; +import com.avlsi.csp.ast.CSPProgram; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.csp.util.ConstantEvaluator; +import com.avlsi.cell.CellInterface; +import com.avlsi.tools.cosim.CoSimInfo; + +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +/** + * Generates cosim Java code from a cell's CSP block. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class CSP2Java { + PrintWriter warningWriter; + PrintWriter errorWriter; + PrintWriter debugWriter; + boolean emitCoverageProbes; + boolean emitSnoopStatements; + + public CSP2Java(PrintWriter warningWriter, + PrintWriter errorWriter, + PrintWriter debugWriter, + boolean emitCoverageProbes, + boolean emitSnoopStatements) { + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.emitCoverageProbes = emitCoverageProbes; + this.emitSnoopStatements = emitSnoopStatements; + } + + + /** + * Generates java code from csp. + * + * @param p parsed CSP program + * @param packageName package name for the generated Java class. + * May be null for the empty package. + * @param className class name for the generated Java class. + * @param cellInfo Contains information on the cell's ports and metaparameters. + * @param pw PrintWriter to which to write the generated class. + * @param strictVars error on undeclared variable (bug 6085) + **/ + private void genCode(final CSPProgram p, + final String packageName, + final String className, + final CSPCellInfo cellInfo, + final PrintWriter pw, + final boolean strictVars, + final boolean disableDftHandler, + final boolean synthesizable) + throws SemanticException { + try { + p.accept(new JavaEmitter(packageName, className, cellInfo, pw, + warningWriter, errorWriter, debugWriter, + emitCoverageProbes, + emitSnoopStatements, strictVars, + disableDftHandler, synthesizable)); + } catch (VisitorException e) { + throw new SemanticException(e); + } + } + + /** + * Generates java code from csp. + * + * @param cell CAST cell from which channel declarations are fetched + * @param packageName package name for the generated Java class. + * May be null for the empty package. + * @param writer Writer to which java code should be written + * @param className class name for the generated Java class. + **/ + public void convert(final CellInterface cell, + final String className, + final Writer w) + throws IOException, SemanticException { + // begin debugging + int j = 0; + for (final java.util.Iterator i = cell.getPortDefinitions(); + i.hasNext(); ) { + final com.avlsi.fast.ports.PortDefinition portDef = + (com.avlsi.fast.ports.PortDefinition) i.next(); + debugWriter.println("port " + j++ + " " + portDef); + } + // end debugging + final PrintWriter out = new PrintWriter(new BufferedWriter(w)); + CSPProgram p = cell.getCSPProgram(); + if (p == null) { + throw new NoCSPBlockException(); + } + /* + try { + p = com.avlsi.csp.util.ConstantEvaluator.evaluate(p); + } catch (VisitorException e) { + throw new SemanticException(e); + } + */ + boolean strictVars = + ((Boolean)DirectiveUtils.getCspDirective + (cell, DirectiveConstants.STRICT_VARS)).booleanValue(); + boolean disableDftHandler = + ((Boolean)DirectiveUtils.getCspDirective + (cell, DirectiveConstants.DISABLE_CHANDFT_HANDLER)).booleanValue(); + boolean synthesizable = + ((Boolean)DirectiveUtils.getCspDirective + (cell, DirectiveConstants.SYNTHESIZABLE)).booleanValue(); + genCode(p, null, className, cell.getCSPInfo(), out, strictVars, + disableDftHandler, synthesizable); + out.close(); + } + + /** + * Prints usage message and exits. + **/ + private static void usage() { + System.out.println("Usage: " + + "csp2java [--cast-path=castpath] [--cast-file=file] CAST_CELL java_class\n" + + " If CAST_CELL is a fully qualified cell name, then the value of cast-file is ignored.\n" + + " If CAST_CELL is not a fully qualified cell name, then the specified cast file is searched\n" + + " for the specified cell." ); + System.exit(1); + } + + /** + * Converts CSP to java. Java is written to Foo.java. + * + * @param args Arguments. + * args[0] is the cast file name. + * args[1] is the cast cell name. + * [Hacked to accept an instance name also. --dhilvert] + * args[2] is the output java class name. + **/ + public static void main(String[] args) throws Exception { + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + + final boolean emitCoverageProbes = theArgs.argExists( "emit-coverage-probes" ); + final boolean emitSnoopStatements = + theArgs.argExists( "emit-snoop-statements" ); + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + CSP2Java.class)); + } + + final FileSearchPath castFSP = new FileSearchPath( theArgs.getArgValue( "cast-path", "." ) ); + + final String castFileName = theArgs.getArgValue("cast-file" , null); + String castCellName = null; + String javaClassName = null; + + StringContainerIterator strIter = theArgs.nonParsedArgumentsIterator(); + + if ( strIter.hasNext() ) { + castCellName = strIter.next(); + if ( strIter.hasNext() ) { + javaClassName = strIter.next(); + } + else { + usage(); + } + } + else { + usage(); + } + + final CastFileParser cfp = + new CastFileParser(castFSP, "2"); + + CellInterface cell = null; + + if ( castCellName.lastIndexOf( '.' ) != -1 ) { + cell = cfp.getFullyQualifiedCell( castCellName ); + } + else { + final CastFile cf = cfp.parse(castFileName); + cell = cf.getCell(castCellName); + } + + final PrintWriter systemOutWriter = new PrintWriter( new OutputStreamWriter( System.out ) ); + + new CSP2Java(systemOutWriter, + systemOutWriter, + systemOutWriter, + emitCoverageProbes, + emitSnoopStatements).convert(cell, javaClassName, new FileWriter(javaClassName + ".java")); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/JavaEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/JavaEmitter.java new file mode 100644 index 0000000000..c36685e35e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/JavaEmitter.java @@ -0,0 +1,3172 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java; + +import java.math.BigInteger; + +import java.io.PrintWriter; +import java.io.File; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.IdentityHashMap; +import java.util.LinkedList; +import java.util.Set; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; + +import com.avlsi.cell.CellUtils; +import com.avlsi.csp.ast.*; +import com.avlsi.csp.coverage.ProbeInfo; + +import com.avlsi.tools.cosim.CoSimInfo; + +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.fast.ports.PortDefinition; +/* import com.avlsi.fast.ports.ArrayType; */ + +import com.avlsi.fast.metaparameters.ArrayMetaParam; +import com.avlsi.fast.metaparameters.BooleanMetaParam; +import com.avlsi.fast.metaparameters.FloatMetaParam; +import com.avlsi.fast.metaparameters.IntegerMetaParam; +import com.avlsi.fast.metaparameters.MetaParamDefinition; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; + +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.csp.util.CspUtils; +import com.avlsi.csp.util.DeclarationProcessor; +import com.avlsi.csp.util.Problem; +import com.avlsi.csp.util.ProblemFilter; +import com.avlsi.csp.util.RefinementResolver; +import com.avlsi.csp.util.RemoveScalars; +import com.avlsi.csp.util.UniqueLabel; +import com.avlsi.csp.util.VariableAnalysisException; +import com.avlsi.csp.util.VariableAnalyzer; +import com.avlsi.csp.util.VisitorExceptionWithLocation; + +// yeah, this ought to be factored out of dsim +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; + +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.NullaryAction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.math.BigIntegerUtil; +import com.avlsi.util.text.StringUtil; +import com.avlsi.io.Printable; +import com.avlsi.io.WrapPrintWriter; + +/** + * Visitor pattern to emit java from csp. + * + * We maintain the convention that all expressions must print something + * that is parenthesized when visited. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class JavaEmitter implements VisitorInterface { + private final String packageName; + private final String className; + private final CSPCellInfo cellInfo; + // State needed for traversal + PrintWriter out; + + private final PrintWriter debugWriter; + + private final PrintWriter warningWriter; + + private final PrintWriter errorWriter; + + private final boolean strictVars; // forbids undeclared vars (bug 6085) + + private final boolean disableDftHandler; + + /** Autogenerated variable number. **/ + private int varNum = 0; + /** True if we are processing the program body. **/ + private boolean bodyP = false; + /** True if we are processing the body of a function. **/ + private boolean funcP = false; + /** Results of variable and expression analysis **/ + protected VariableAnalyzer.Results analysisResults = null; + + private UniqueLabel linkageLabel = new UniqueLabel(); + + private int probeCount = 0; + + /** Used to generate unique Element classes for non-channel arrays. **/ + private int arrayElementCount = 0; + + private boolean emitCoverageProbes=false; + private boolean emitSnoopStatements; + private final boolean synthesizable; + + private ArrayList probes = new ArrayList(); // array of ProbeInfo + + /** + * Only used if emitSnoopStatements. + **/ + private boolean foundLoop = false; + + private RefinementResolver resolver = + new RefinementResolver(RefinementResolver.NAME); + + private UniqueLabel labels = new UniqueLabel(); + + /** See recurseDeterministicGuards and recurseDeterministicBodies */ + private Map loopVarHash = new IdentityHashMap(); + + /** A suffix to the structure type definitions */ + private Map structureTypeHash = new IdentityHashMap(); + + /** Special character escape sequences to use in string literals */ + private static Map ESCAPE_MAP = CollectionUtils.mapify( + new Object[] { + new Character('\b'), "\\b", + new Character('\t'), "\\t", + new Character('\n'), "\\n", + new Character('\f'), "\\f", + new Character('\r'), "\\r" + }); + + /** + * Is the current ArrayAccessExpression part of an expression that will + * access a channel in the port list? + **/ + private boolean isPortArray = false; + + /** Used by ensureNewline() to see if it's already printed a newline. */ + private boolean didNewline = false; + + /** + * A set of all identifers that have been referenced. Any constant + * initializers that do not initialize a variable in this set will be + * eliminated. Correctness is not affected if this set happens to contain + * identifiers that weren't used. + **/ + private final Set identUsed = new HashSet(); + + private final ProblemFilter probFilter; + + public JavaEmitter(final String packageName, + final String className, + final CSPCellInfo cellInfo, + final PrintWriter out, + final PrintWriter warningWriter, + final PrintWriter errorWriter, + final PrintWriter debugWriter, + final boolean emitCoverageProbes, + final boolean emitSnoopStatements, + final boolean strictVars, + final boolean disableDftHandler, + final boolean synthesizable) { + this.packageName = packageName; + this.className = className; + this.cellInfo = cellInfo; + this.out = out; + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.emitCoverageProbes = emitCoverageProbes; + this.emitSnoopStatements = emitSnoopStatements; + final Printable prntble = new com.avlsi.io.WrapPrintWriter(errorWriter); + this.probFilter = new ProblemFilter( + ProblemFilter.getClassifier( + new HashSet(Arrays.asList( + new Object[] { "type.checker.undeclared.set.unused", + "type.checker.invalid.guard" }))), + new BinaryFunction() { + public Object execute(final Object o1, final Object o2) { + JavaEmitter.this.ensureNewline(); + return prntble; + } + }); + this.strictVars = strictVars; + this.disableDftHandler = disableDftHandler; + this.synthesizable = synthesizable; + } + + + private String getTypeString(final PortDefinition p) { + String result = (String) structureTypeHash.get(p); + if (result == null) { + result = "type_" + p.getName() + "_" + structureTypeHash.size(); + structureTypeHash.put(p, result); + } + return result; + } + + /** + * Outputs body of a class definition for an arrayed port type. Note that + * 1-dimensional arrays of channels are handled by a runtime type. If this + * member is called with a 1-dimensional array of channels, a + * VisitorException will be thrown. + * + * @param name Name of class to define + * @param type Array port type + * @param direction Direction modifier for the port: + *
      + *
    • > 0 is forward + *
    • = 0 is bidirectional + *
    • < 0 is reverse + *
    + **/ + private void outputArrayPortClass (String name, + com.avlsi.fast.ports.ArrayType type, int direction) + throws VisitorException { + + PortTypeInterface elementType = type.getArrayedType(); + int minIndex = type.getMinIndex(); + int maxIndex = type.getMaxIndex(); + int diffIndex = maxIndex - minIndex + 1; + String runtimeElementType = ""; + String runtimeElementConstructor = ""; + String runtimeOffsetUpdate = ""; + + if (diffIndex <= 0) + throw new VisitorException ("Invalid Array Size"); + + if (!(elementType instanceof com.avlsi.fast.ports.StructureType + || elementType instanceof com.avlsi.fast.ports.ArrayType)) + throw new VisitorException ("Bad element type."); + + /* Special case of elements which are 1-dimensional arrays. */ + + if (elementType instanceof com.avlsi.fast.ports.ArrayType + && ((com.avlsi.fast.ports.ArrayType) elementType).getArrayedType() + instanceof ChannelType) { + com.avlsi.fast.ports.ArrayType at = + (com.avlsi.fast.ports.ArrayType) elementType; + ChannelType ct = (ChannelType) at.getArrayedType(); + String dirString = ""; + int diffIndex2 = at.getMaxIndex() - at.getMinIndex() + 1; + + if (direction < 0) { + // IN + runtimeElementType = "CspChannelInArray1"; + dirString = "in"; + } else if (direction > 0) { + // OUT + runtimeElementType = "CspChannelOutArray1"; + dirString = "out"; + } else { + throw new VisitorException ("Invalid direction."); + } + runtimeElementConstructor = runtimeElementType + + "(" + + at.getMinIndex() + ", " + + at.getMaxIndex() + ", \"" + + ct.getTypeName() + "\", " + + dirString + ", " + + dirString + "putOffset)"; + runtimeOffsetUpdate = dirString + "putOffset += " + + diffIndex2 + ";"; + } else if (elementType instanceof com.avlsi.fast.ports.ArrayType + && ((com.avlsi.fast.ports.ArrayType) elementType).getArrayedType() + instanceof NodeType) { + com.avlsi.fast.ports.ArrayType at = + (com.avlsi.fast.ports.ArrayType) elementType; + int diffIndex2 = at.getMaxIndex() - at.getMinIndex() + 1; + runtimeElementType = "CspNodeArray1"; + runtimeElementConstructor = runtimeElementType + + "(" + + at.getMinIndex() + ", " + + at.getMaxIndex() + ", " + + "wideNodes, nodeOffset)"; + runtimeOffsetUpdate = "nodeOffset += " + diffIndex2 + ";"; + } else { + runtimeElementType = "Element_" + (arrayElementCount++); + outputPortClass (runtimeElementType, elementType, direction); + runtimeElementConstructor = runtimeElementType + "()"; + runtimeOffsetUpdate = ""; + } + + /* Array storage */ + + out.println ("private " + runtimeElementType + "[] elements;"); + + /* Constructor */ + + out.println ("public " + name + " () {"); + out.println ("\telements = new " + runtimeElementType + + "[" + diffIndex + "];"); + out.println ("\tfor (int i = 0; i < " + diffIndex + "; i++) {"); + out.println ("\t\telements[i] = new " + runtimeElementConstructor +";"); + out.println ("\t\t" + runtimeOffsetUpdate); + out.println ("\t}"); + out.println ("}"); + + /* get function */ + + out.println ("public " + runtimeElementType + + " get (final CspInteger index, String filename, int line, int column)"); + out.println ("\tthrows CspArrayBoundsException {"); + out.println ("\tint intIndex = index.intValue();"); + out.println ("\ttry {"); + out.println ("\t\treturn elements[intIndex - " + minIndex + "];"); + out.println ("\t} catch (ArrayIndexOutOfBoundsException e) {"); + out.println ("\t\tthrow (CspArrayBoundsException) new CspArrayBoundsException(index, " + minIndex + ", " + maxIndex + ", filename, line, column).initCause(e);"); + out.println ("\t}"); + out.println ("}"); + + /* There is no assignment to channels at this time. */ + + out.println ("/* set() does not exist for this class */"); + } + + /** + * Outputs body of a class definition for a structured port type. + * + * @param name Name of class to define + * @param type Structured port type + * @param direction Direction modifier for the port: + *
      + *
    • > 0 is forward + *
    • = 0 is bidirectional + *
    • < 0 is reverse + *
    + **/ + private void outputStructuredPortClass (String name, + com.avlsi.fast.ports.StructureType type, + int direction) throws VisitorException { + + /* Declare members */ + + for (Iterator i = type.iterator(); i.hasNext(); ) { + PortDefinition p = (PortDefinition) i.next(); + outputPortDecl (p, direction); + } + + /* Constructor */ + + out.println ("public " + name + " () {"); + + for (Iterator i = type.iterator(); i.hasNext(); ) { + PortDefinition p = (PortDefinition) i.next(); + outputPortInit (p, direction); + } + + out.println ("} /* end constructor for " + name + " */"); + } + + /** + * Outputs a class definition for a port type. + * + * @param name Name of class to define + * @param type Port type + * @param direction Direction modifier for the port: + * > 0 is forward + * = 0 is bidirectional + * < 0 is reverse + **/ + private void outputPortClass (String name, PortTypeInterface type, + int direction) throws VisitorException { + + out.println ("public class " + name + "{"); + + if (type instanceof com.avlsi.fast.ports.ArrayType) { + outputArrayPortClass (name, (com.avlsi.fast.ports.ArrayType) type, + direction); + } else if (type instanceof com.avlsi.fast.ports.StructureType) { + outputStructuredPortClass (name, (com.avlsi.fast.ports.StructureType) type, direction); + } else { + throw new VisitorException ("Can't output class for type: " + type); + } + + out.println ("} /* End of class definition for " + name + " */"); + } + + /** + * Outputs code to declare a port. Use the method with a direction + * parameter for sub-channels. + * + * @param p Definition of a port + **/ + private void outputPortDecl (PortDefinition p) + throws VisitorException { + outputPortDecl (p, 1); /* Forward direction modifier */ + } + + private PortTypeInterface getBaseType(PortTypeInterface t) { + while (t instanceof com.avlsi.fast.ports.ArrayType) { + t = ((com.avlsi.fast.ports.ArrayType) t).getArrayedType(); + } + return t; + } + + /** + * Outputs code to declare a port. Operates recursively on structured + * and arrayed channels. + * + * @param p Definition of a port + * @param direction Direction modifier for the port: + *
      + *
    • > 0 is forward + *
    • = 0 is bidirectional + *
    • < 0 is reverse + *
    + **/ + private void outputPortDecl (PortDefinition p, int direction) + throws VisitorException { + PortTypeInterface t = p.getType(); + String dirString = ""; + + /* Combine the direction argument and the port direction. */ + + if (p.getDirection() == PortDefinition.FORWARD) { + direction = direction * +1; + } else if (p.getDirection() == PortDefinition.REVERSE) { + direction = direction * -1; + } else { + throw new VisitorException ("Invalid direction."); + } + + /* Set dirString based on the new direction. */ + + if (direction < 0) { + /* IN, by convention */ + dirString = "In"; + } else if (direction > 0) { + /* OUT, by convention */ + dirString = "Out"; + } else { + throw new VisitorException ("Invalid direction."); + } + + /* Handle channels and 1-dimensional arrays of channels as special + * cases. Handle other cases recursively. */ + + if (t instanceof ChannelType) { + + /* channel */ + out.println("public final Channel" + + dirString + "put _" + p.getName() + ";"); + + } else if (t instanceof com.avlsi.fast.ports.ArrayType + && ((com.avlsi.fast.ports.ArrayType) t).getArrayedType() + instanceof ChannelType) { + + /* 1-dimensional array of channels */ + out.println ("public final CspChannel" + dirString + "Array1" + + " _" + p.getName() + ";"); + + } else if (t instanceof com.avlsi.fast.ports.ArrayType + && ((com.avlsi.fast.ports.ArrayType) t).getArrayedType() + instanceof NodeType) { + out.println ("public final CspNodeArray1" + " _" + p.getName() + + ";"); + } else if (t instanceof NodeType) { + out.println("public final CspNode _" + p.getName() + ";"); + } else { + + /* structured or array type which is not a special case */ + + // DFT channels are handled specially + if (isDftType(getBaseType(t))) + return; + + final String type = getTypeString(p); + outputPortClass (type, t, direction); + out.println ("public final " + type + " _" + p.getName() + ";"); + + } + } + + // DFT channels are handled specially + private boolean isDftType(PortTypeInterface t) { + return !disableDftHandler && + t instanceof com.avlsi.fast.ports.StructureType && + CellUtils.isDftChannel(((com.avlsi.fast.ports.StructureType) t).getTag()); + } + + private void declareChannelVars() throws VisitorException { + debugWriter.println("\ndeclareChannelVars()"); + debugWriter.println("cell: " + cellInfo.getType()); + for (Iterator i = cellInfo.getPortDefinitions(); i.hasNext(); ) { + PortDefinition p = (PortDefinition) i.next(); + debugWriter.println("in declareChannelVars: " + p); + outputPortDecl (p); + } + } + + /** + * Outputs code to initialize a port. Use the method with a direction + * parameter for sub-channels. + * + * @param p Definition of a port + **/ + private void outputPortInit (PortDefinition p) + throws VisitorException { + outputPortInit (p, 1); /* Forward direction modifier */ + } + + /** + * Outputs code to initialize a port. Operates recursively on + * structured channels. + * + * @param p Definition of a port + * @param direction Direction modifier for the port: + *
      + *
    • > 0 is forward + *
    • = 0 is bidirectional + *
    • < 0 is reverse + *
    + **/ + private void outputPortInit (PortDefinition p, int direction) + throws VisitorException { + PortTypeInterface t = p.getType(); + String dirString = ""; + String dirStringLC = ""; /* dirString.toLowerCase() */ + + /* Combine the direction argument and the port direction. */ + + if (p.getDirection() == PortDefinition.FORWARD) { + direction = direction * +1; + } else if (p.getDirection() == PortDefinition.REVERSE) { + direction = direction * -1; + } else { + throw new VisitorException ("Invalid direction."); + } + + /* Set dirString based on the new direction. */ + + if (direction < 0) { + /* IN, by convention */ + dirString = "In"; + } else if (direction > 0) { + /* OUT, by convention */ + dirString = "Out"; + } else { + throw new VisitorException ("Invalid direction."); + } + dirStringLC = dirString.toLowerCase(); + + if (t instanceof ChannelType) { + + /* + * Initialize a channel + */ + out.println ("this._" + p.getName() + " = " + + dirStringLC + "[" + dirStringLC + "putOffset++];"); + + } else if (t instanceof com.avlsi.fast.ports.ArrayType + && ((com.avlsi.fast.ports.ArrayType) t).getArrayedType() + instanceof ChannelType) { + + /* + * Special handling for 1-dimensional Arrays + */ + + com.avlsi.fast.ports.ArrayType at = + (com.avlsi.fast.ports.ArrayType) t; + ChannelType c = (ChannelType) at.getArrayedType(); + + out.println ("this._" + p.getName() + " = " + + "new CspChannel" + dirString + "Array1(" + + at.getMinIndex() + ", " + + at.getMaxIndex() + ", " + + "\"" + c.getTypeName() + "\"" + ", " + + dirStringLC + ", " + + dirStringLC + "putOffset);"); + out.println (dirStringLC + "putOffset += " + + (at.getMaxIndex() - at.getMinIndex() + 1) + ";"); + + } else if (t instanceof com.avlsi.fast.ports.ArrayType + && ((com.avlsi.fast.ports.ArrayType) t).getArrayedType() + instanceof NodeType) { + com.avlsi.fast.ports.ArrayType at = + (com.avlsi.fast.ports.ArrayType) t; + NodeType c = (NodeType) at.getArrayedType(); + + out.println ("this._" + p.getName() + " = " + + "new CspNodeArray1(" + + at.getMinIndex() + ", " + + at.getMaxIndex() + ", " + + "wideNodes, nodeOffset);"); + out.println ("nodeOffset += " + + (at.getMaxIndex() - at.getMinIndex() + 1) + ";"); + + } else if (t instanceof NodeType) { + + out.println ("this._" + p.getName() + + " = new CspNode(wideNodes[nodeOffset++]);"); + + } else { + + /* + * Initialize an Array or Structure which is not a special case + */ + + // DFT channels are handled specially + if (isDftType(getBaseType(t))) + return; + + final String type = getTypeString(p); + out.println("this._" + p.getName() + " = " + + "this.new " + type + "();"); + } + } + + private void assignChannelVars() + throws VisitorException { + for (Iterator i = cellInfo.getPortDefinitions(); i.hasNext(); ) { + PortDefinition p = (PortDefinition) i.next(); + outputPortInit (p); + } + } + + private void processFuncDecl(final FunctionDeclaration funcDecl, + final SequentialStatement initStmt) + throws VisitorException { + // Functions used to be static. I'm making them non-static, + // we'll see if this causes a problem. --jmr 2002.12.09 + final VariableAnalyzer.Results funcResult; + try { + VariableAnalyzer va = new VariableAnalyzer(cellInfo); + funcResult = va.getResults (funcDecl, initStmt, resolver); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + + probFilter.process(funcResult.getErrors(strictVars)); + if (probFilter.hasError()) return; + + final String funcName = + funcDecl.getName() + "_" + labels.getLabel(funcDecl); + + // emit the real function + out.print("public "); + if (funcDecl.getReturnType() != null) + funcDecl.getReturnType().accept(this); + else + out.print("void"); + out.print(' '); + processIdentifier(funcName + "_real"); + out.print('('); + // handle formal parameters + processDeclarationList(funcDecl.getFormals(), true); + // now that channels can be used inside functions, + // may throw InterruptedException -- aml 2002.12.12 + out.println(") throws InterruptedException {"); + if (funcDecl.getReturnType() != null) { + // Declare variable for function return value. + // By some miracle, you can have a variable with the same + // name as a function and everything works as expected. + final DeclaratorList drl = + new DeclaratorList(); + drl.addDeclarator( + new Declarator( + new IdentifierExpression(funcDecl.getName()), + funcDecl.getReturnType(), + null)); + + final Declaration decl = new Declaration(drl); + // REVIEW: Previously, Why could we visit Declarations? + // It's not needed... But maybe cleaner? Ask Aaron/Chris. + // It made it harder to pass the formalP arg... + processDeclaration(decl, false); + } + + // initialize any output formal arguments + final DeclaratorList drl = new DeclaratorList(); + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + if (d.getDirection() == Declarator.OUT) { + drl.addDeclarator(d); + } + } + }).process(funcDecl.getFormals()); + processDeclaration(new Declaration(drl), false, + new DeclaratorProcessor() { + public void emitModifier(Declarator dr) + throws VisitorException { } + public void emitType(Declarator dr) + throws VisitorException { } + public String getInitPreamble() { + return ".setValue("; + } + public String getInitPostamble() { + return ");"; + } + }); + + final VariableAnalyzer.Results savedResult = analysisResults; + // generate code for implied variable set + processResults (funcResult); + declareUndeclared (funcResult); + + // generate code for body + funcP = true; + funcDecl.getBodyStatement().accept(this); + funcP = false; + + // copy-out inout finite precision integer parameters, in case they + // weren't assigned; this is needed because of possible truncation, + // see bug 20398 + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final Type varT = d.getTypeFragment(); + if (d.getDirection() == Declarator.INOUT && + varT instanceof IntegerType && + ((IntegerType) varT).getDeclaredWidth() != null) { + d.getIdentifier().accept(JavaEmitter.this); + out.print(".setValue("); + d.getIdentifier().accept(JavaEmitter.this); + out.println(");"); + } + } + }).process(funcDecl.getFormals()); + + if (funcDecl.getReturnType() != null) { + // Return the value. + out.print("return "); + processIdentifier(funcDecl.getName()); + out.println(';'); + } + analysisResults = savedResult; + out.println('}'); + + // emit a wrapper around the function, to avoid having a problem with + // "code too large for try block" + out.print("public "); + if (funcDecl.getReturnType() != null) + funcDecl.getReturnType().accept(this); + else + out.print("void"); + out.print(' '); + processIdentifier(funcName); + out.print('('); + processDeclarationList(funcDecl.getFormals(), true); + out.println(") throws InterruptedException {"); + out.println("try {"); + out.println("enterFrame(\"" + funcDecl.getName() + "\");"); + if (funcDecl.getReturnType() != null) + out.print("return "); + processIdentifier(funcName + "_real"); + out.print('('); + processDeclarationList(funcDecl.getFormals(), true, + new DeclaratorProcessor() { + public void emitModifier(Declarator dr) + throws VisitorException { } + public void emitType(Declarator dr) + throws VisitorException { } + }); + out.println(");"); + out.println("} finally { leaveFrame(); } "); + out.println('}'); + } + + private int getIntegerConstant(final ExpressionInterface e) + throws VisitorException { + if (e instanceof IntegerExpression) { + final IntegerExpression ie = (IntegerExpression) e; + return Integer.parseInt(ie.getValue(), ie.getRadix()); + } else { + throw new VisitorExceptionWithLocation( + "Compile time constant integer expression expected", e); + } + } + + private void processStructDecl(final StructureDeclaration decl) + throws VisitorException { + final String name = decl.getName() + "_" + labels.getLabel(decl); + out.print("public class "); + processIdentifier(name); + out.println(" implements CspCloneableValue, CspStructure {"); + + final DeclarationList list = decl.getDeclarations(); + processDeclarationList( + list, + false, + new DeclaratorProcessor() { + public void emitModifier(Declarator dr) + throws VisitorException { + out.print("public "); + } + public String getTerminator() { return ";\n"; } + public boolean outputInit() { return false; } + public boolean generateLoggedType() { return false; } + } + ); + out.println(); + + // default constructor + out.print("public "); + processIdentifier(name); + out.println("() {"); + out.println("this(true);"); + out.println("}"); + + out.print("public "); + processIdentifier(name); + out.println("(final boolean init) {"); + out.println("if (init) {"); + processDeclarationList( + list, + false, + new DeclaratorProcessor() { + public void emitModifier(Declarator dr) + throws VisitorException { } + public void emitType(Declarator dr) + throws VisitorException { } + public boolean generateLoggedType() { return false; } + } + ); + out.println("}"); + out.println("}"); + + // member-valued constructor + out.print("public "); + processIdentifier(name); + out.print("("); + processDeclarationList(list, true); + out.println(") {"); + out.println("this();"); + for (final Iterator i = list.getDeclarations(); i.hasNext(); ) { + final Declaration d = (Declaration) i.next(); + for (Iterator j = d.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator dr = (Declarator) j.next(); + out.print("this."); + dr.getIdentifier().accept(this); + out.print(".setValue("); + dr.getIdentifier().accept(this); + out.println(");"); + } + } + out.println("}"); + + // copy constructor + out.print("public "); + processIdentifier(name); + out.print("("); + processIdentifier(name); + out.println(" other) {"); + out.println("setValue(other);"); + out.println("}"); + + // setValue (general) + out.println("public void setValue(CspValue other) {"); + out.print("setValue(("); + processIdentifier(name); + out.print(") "); + out.println("other);"); + out.println("}"); + + // setValue (value, modifier) + out.println("public void setValue(CspValue value, " + + "Fold.BinaryFunction modifier) {"); + out.println("throw new UnsupportedOperationException();"); + out.println("}"); + + // setValue + out.print("public void setValue("); + processIdentifier(name); + out.println(" other) {"); + for (final Iterator i = list.getDeclarations(); i.hasNext(); ) { + final Declaration d = (Declaration) i.next(); + for (Iterator j = d.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator dr = (Declarator) j.next(); + out.print("this."); + dr.getIdentifier().accept(this); + out.print(".setValue(other."); + dr.getIdentifier().accept(this); + out.println(");"); + } + } + out.println("}"); + + // clone + out.println("public CspCloneableValue duplicate() {"); + processIdentifier(name); + out.println(" result = new "); + processIdentifier(name); + out.println("(false);"); + for (final Iterator i = list.getDeclarations(); i.hasNext(); ) { + final Declaration d = (Declaration) i.next(); + for (Iterator j = d.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator dr = (Declarator) j.next(); + out.print("result."); + dr.getIdentifier().accept(this); + out.print(" = ("); + dr.getTypeFragment().accept(this); + out.print(") this."); + dr.getIdentifier().accept(this); + out.println(".duplicate();"); + } + } + out.println("return result;"); + out.println("}"); + + final LinkedList reversed = new LinkedList(); + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + reversed.addFirst(d); + } + }).process(list); + + // pack + out.println("public int pack(CspInteger packed, int start) {"); + for (Declarator dr : reversed) { + final Type t = dr.getTypeFragment(); + out.print("start = ((Packable) "); + dr.getIdentifier().accept(this); + out.println(").pack(packed, start);"); + } + out.println("return start;"); + out.println("}"); + + // unpack + out.println("public int unpack(CspInteger packed, int start) {"); + for (Declarator dr : reversed) { + final Type t = dr.getTypeFragment(); + out.print("start = ((Packable) "); + dr.getIdentifier().accept(this); + out.println(").unpack(packed, start);"); + } + out.println("return start;"); + out.println("}"); + + // end of structure definition + out.println("}"); + + // A logged version of the structure + final String loggedName = "Logged" + name; + out.print("public class "); + processIdentifier(loggedName); + out.print(" extends "); + processIdentifier(name); + out.println(" {"); + // default constructor + out.print("public "); + processIdentifier(loggedName); + out.println("(final String varName) {"); + out.println("super(false);"); + processDeclarationList( + list, + false, + new DeclaratorProcessor() { + public void emitModifier(Declarator dr) + throws VisitorException { } + public void emitType(Declarator dr) + throws VisitorException { } + public boolean generateLoggedType() { return true; } + public String getPrefix() { return "(varName + \".\")"; } + } + ); + out.println("}"); + + out.print("public "); + processIdentifier(loggedName); + out.println("(final String varName, final String parsePos) {"); + out.println("this(varName);"); + out.println("topFrame().addVariable(varName, parsePos, this);"); + out.println("}"); + + + out.print("public "); + processIdentifier(loggedName); + out.print("(final String varName, "); + processIdentifier(name); + out.println(" val) {"); + out.println("this(varName);"); + out.println("setValue(val);"); + out.println("}"); + + out.print("public "); + processIdentifier(loggedName); + out.print("(final String varName, final String parsePos, "); + processIdentifier(name); + out.println(" val) {"); + out.println("this(varName, val);"); + out.println("topFrame().addVariable(varName, parsePos, this);"); + out.println("}"); + + out.println("}"); + } + + private void outputConstructor(final ArbiterVisitor arbiterVisitor) + throws VisitorException { + out.println("public " + className + + "(final DeviceParameters deviceParams," + + " final ChannelInput[] in," + + " final ChannelOutput[] out," + + " final WideNode[] nodes"); + if (emitSnoopStatements) + out.print(",\nfinal CspSnoopingInterface cspSnooper"); + out.println(") throws InterruptedException {"); + out.println("super(deviceParams.getName(), " + + "in, " + + "out, " + + "nodes, " + + "deviceParams.isOutputSuppressed(), " + + "deviceParams.getArbitrationMode());"); + out.println("_srandom(new CspInteger(" + + "new BigInteger(Long.toString(" + + "deviceParams.getSeed()))));"); + out.println("setDigitalTau(deviceParams.getDigitalTau());"); + assignChannelVars(); + arbiterVisitor.initLinkages(out); + + if(emitCoverageProbes) + out.println("registerProbes();"); + if (emitSnoopStatements) + out.println("this.cspSnooper = cspSnooper;"); + else if (synthesizable) + out.println("this.cspSnooper = getProteusSnooper();"); + + out.println("}"); + out.println(); + } + + public void visitCSPProgram(CSPProgram e) throws VisitorException { + resolver.resolve(e); + e = resolver.getCSPProgram(); + + String filename = e.getParseRange().start.filename; + + // package + if (packageName != null) + out.println("package " + packageName + ";\n"); + + // imports + out.println("import java.math.BigInteger;"); + out.println("import java.util.LinkedList;"); + out.println("import java.util.Random;"); + out.println("import com.avlsi.csp.csp2java.runtime.*;"); + out.println("import com.avlsi.tools.cosim.DeviceParameters;"); + out.println("import com.avlsi.tools.dsim.DSim;"); + out.println("import com.avlsi.tools.sigscan.LoggedLogicArray;"); + out.println("import com.avlsi.tools.sigscan.LoggedLong;"); + out.println("import com.avlsi.tools.tsim.AbstractDevice;"); + out.println("import com.avlsi.tools.tsim.Arbiter;"); + out.println("import com.avlsi.tools.tsim.Arbiter.Action;"); + out.println("import com.avlsi.tools.tsim.Arbiter.Alternative;"); + out.println("import com.avlsi.tools.tsim.Arbiter.Linkage;"); + out.println("import com.avlsi.tools.tsim.Arbiter.NullaryPredicate;"); + out.println("import com.avlsi.tools.tsim.Arbiter.Term;"); + out.println("import com.avlsi.tools.tsim.ChannelInput;"); + out.println("import com.avlsi.tools.tsim.ChannelOutput;"); + out.println("import com.avlsi.tools.tsim.EmptyWaitSetException;"); + out.println("import com.avlsi.tools.tsim.Wait;"); + out.println("import com.avlsi.tools.tsim.WaitFactory;"); + out.println("import com.avlsi.tools.tsim.Waitable;"); + out.println("import com.avlsi.tools.tsim.WideNode;"); + out.println("import com.avlsi.util.container.Pair;"); + out.println("import com.avlsi.fast.metaparameters.*;"); + if(emitCoverageProbes) + out.println("import com.avlsi.csp.coverage.*;"); + out.println("import com.avlsi.csp.grammar.*;"); + out.println(); + + // class definition + out.println("public final class " + className + + " extends CspRuntimeAbstractDevice {"); + out.println(); + + // instance variables + out.println("private int outputOffset = 0;"); + out.println("private int inputOffset = 0;"); + out.println("private int nodeOffset = 0;"); + if(emitCoverageProbes) + out.println("private static int hitTableOffset;"); + if (emitSnoopStatements || synthesizable) + out.println("private final CspSnoopingInterface cspSnooper;"); + declareChannelVars(); + + final VariableAnalyzer.Results bodyResult; + try { + VariableAnalyzer va = new VariableAnalyzer(cellInfo); + bodyResult = va.getResults (e, resolver); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + + probFilter.process(bodyResult.getErrors(strictVars)); + if (!probFilter.hasError()) processResults (bodyResult); + final SequentialStatement initStmt = e.getInitializerStatement(); + + // find nodes used in linked arbitration + ArbiterVisitor arbiterVisitor = + new ArbiterVisitor(this, linkageLabel); + arbiterVisitor.visitCSPProgram(e); + arbiterVisitor.declareLinkages(out); + + // constructors + outputConstructor(arbiterVisitor); + + out.println(); + + // function declarations + for (final Iterator i = e.getFunctionDeclarations(); + i.hasNext(); ) { + final FunctionDeclaration funcDecl = + (FunctionDeclaration) i.next(); + // XXX: This is incorrect, because each function should be + // considered with respect to the initializer statements for + // the cell in which it is defined. But even so, the current + // JavaEmitter would not handle this case correctly, since only + // the initializers for the current function are emitted. + processFuncDecl(funcDecl, initStmt); + } + + if (probFilter.hasError()) + throw new VisitorException("Fatal errors found"); + + // structure declaration + for (final Iterator i = e.getStructureIterator(); i.hasNext(); ) { + final StructureDeclaration structDecl = + (StructureDeclaration) i.next(); + processStructDecl(structDecl); + } + + final SequentialStatement reducedInit = RemoveScalars.process( + initStmt, + new UnaryPredicate() { + public boolean evaluate(Object o) { + final Declarator d = (Declarator) o; + return !identUsed.contains(d.getIdentifier() + .getIdentifier()); + } + }); + if (reducedInit != null) { + // static vars + reducedInit.accept(new ConstantDeclarationEmitter + (packageName, className, cellInfo, out, + warningWriter, errorWriter, debugWriter, + emitCoverageProbes, disableDftHandler, analysisResults)); + out.println(); + + // static initializers + ConstantInitializerEmitter constEmitter = + new ConstantInitializerEmitter + (packageName, className, cellInfo, out, + warningWriter, errorWriter, debugWriter, + emitCoverageProbes, disableDftHandler, + analysisResults); + reducedInit.accept(constEmitter); + constEmitter.done(); + out.println("static {"); + out.println(" staticInitializer();"); + out.println("}"); + out.println(); + } + + // cleanup() method + out.println("protected void cleanup() {"); + arbiterVisitor.destroyLinkages(out); + out.println("}"); + out.println(); + + // go() method + out.println("public void go() throws InterruptedException {"); + if (emitSnoopStatements || synthesizable) + out.println("cspSnooper.onStart();"); + out.println("try{"); + out.println("enterFrame(null);"); + declareUndeclared(bodyResult); + bodyP = true; + if (e.getStatement() != null) { + e.getStatement().accept(this); + } + // wait forever in case program wasn't an infinite loop + out.println("waitForever();"); + out.println("}catch(NonDeterminismException e){"); + out.println("outerr(e.toString());"); + out.println("}catch(CspNode.UnstableException e){"); + out.println("printUnstableException();"); + out.println("}catch(CspArrayBoundsException e){"); + out.println("handleBoundsException(e, " + + (emitSnoopStatements ? "cspSnooper" : "null") + + ");"); + out.println("}finally{"); + out.println("leaveFrame();"); + out.println("}"); + + if (emitSnoopStatements || synthesizable) + out.println("cspSnooper.onEnd();"); + out.println("}"); + out.println(); + + // generate resetNodes() + final Pair p = + (Pair) resolver.getResolvedFunctions() + .get(RefinementResolver.RESET_FUNCTION_CALL); + if (p != null) { + String name; + final Object decl = p.getSecond(); + if (decl instanceof FunctionDeclaration) { + name = ((FunctionDeclaration) decl).getName() + "_" + + labels.getLabel(decl); + } else { + throw new VisitorException( + "Invalid definition of special function resetNodes: " + + ((AbstractASTNode) e).getParseRange().fullString()); + } + out.println("protected void resetNodes() throws InterruptedException {"); + processIdentifier(name); + out.println("();"); + out.println("}"); + } + + if(emitCoverageProbes) { + out.println("private static void registerProbes() {"); + // spit out a call to Monitor.global.register here, listing all + // the probes that we emitted above + out.println("hitTableOffset=Monitor.global.register(\""+cellInfo.getAbbreviatedType()+"\","); + out.println(" new ProbeInfo[] {"); + for(int i=0; i 0) { + Arrays.sort(loopVars); + out.println("private BigInteger " + + StringUtil.join(loopVars, ',') + ";"); + } + + out.println("public class LoggedCspInteger extends CspInteger {"); + out.println("private final LoggedLong logged;"); + out.println("public LoggedCspInteger(String varName) {"); + out.println("this(varName, BigInteger.ZERO);"); + out.println("}"); + out.println("public LoggedCspInteger(String varName, BigInteger val) {"); + out.println("super(val);"); + out.println("CspRuntimeAbstractDevice parent = getSelf();"); + out.println("logged = parent.getSigscan() == null ? null : new LoggedLong(getLoggingScope(), varName, parent.getSigscan(), parent.getDebugOpts(), true);"); + out.println("if (logged != null) logged.set(val.longValue(), getTime());"); + out.println("}"); + out.println("public LoggedCspInteger(String varName, String parsePos, BigInteger val) {"); + out.println("this(varName, val);"); + out.println("topFrame().addVariable(varName, parsePos, this);"); + out.println("}"); + out.println("protected void setValue(final BigInteger val) {"); + out.println("super.setValue(val);"); + out.println("if (logged != null) logged.set(val.longValue(), getTime());"); + out.println("}"); + out.println("}"); + + out.println("public LoggedCspArray.ElementConstructor getElementConstructor(final int width, final boolean isSigned) {"); + out.println("return new LoggedCspArray.ElementConstructor() {"); + out.println("public CspValue create(CspRuntimeAbstractDevice parent, String varName) {"); + out.println("return new LoggedFiniteCspInteger(varName, BigInteger.ZERO, width, isSigned);"); + out.println("}"); + out.println("};"); + out.println("}"); + + out.println("public class LoggedFiniteCspInteger extends FiniteCspInteger {"); + out.println("private final LoggedLogicArray logged;"); + out.println("public LoggedFiniteCspInteger(String varName, BigInteger val, int width, boolean isSigned) {"); + out.println("super(val, width, isSigned);"); + out.println("CspRuntimeAbstractDevice parent = getSelf();"); + out.println("logged = parent.getSigscan() == null ? null : new LoggedLogicArray(getLoggingScope(), varName, 0, width - 1, parent.getSigscan(), parent.getDebugOpts(), true);"); + out.println("if (logged != null) logged.set(getLogicArray(), getTime());"); + out.println("}"); + out.println("public LoggedFiniteCspInteger(String varName, String parsePos, BigInteger val, int width, boolean isSigned) {"); + out.println("this(varName, val, width, isSigned);"); + out.println("topFrame().addVariable(varName, parsePos, this);"); + out.println("}"); + out.println("protected void setValue(final BigInteger val) {"); + out.println("super.setValue(val);"); + out.println("if (logged != null) logged.set(getLogicArray(), getTime());"); + out.println("}"); + out.println("}"); + + out.println("public class LoggedCspBoolean extends CspBoolean {"); + out.println("private final LoggedLong logged;"); + out.println("public LoggedCspBoolean(String varName) {"); + out.println("this(varName, BigInteger.ZERO);"); + out.println("}"); + out.println("public LoggedCspBoolean(String varName, BigInteger val) {"); + out.println("super(val);"); + out.println("CspRuntimeAbstractDevice parent = getSelf();"); + out.println("logged = parent.getSigscan() == null ? null : new LoggedLong(getLoggingScope(), varName, parent.getSigscan(), parent.getDebugOpts(), true);"); + out.println("if (logged != null) logged.set(val.longValue(), getTime());"); + out.println("}"); + out.println("public LoggedCspBoolean(String varName, String parsePos, BigInteger val) {"); + out.println("this(varName, val);"); + out.println("topFrame().addVariable(varName, parsePos, this);"); + out.println("}"); + out.println("protected void setValue(final BigInteger val) {"); + out.println("super.setValue(val);"); + out.println("if (logged != null) logged.set(val.longValue(), getTime());"); + out.println("}"); + out.println("}"); + + out.println("}"); + } + + /** + * Return a new autogenerated variable number. + **/ + private int genVarNum() { + return varNum++; + } + + private void processUnary(final AbstractUnaryExpression expr, + final String method) throws VisitorException { + out.print('('); + expr.getExpression().accept(this); + out.print('.' + method + "())"); + } + + private void processBinary(final AbstractBinaryExpression expr, + final String method) + throws VisitorException { + out.print('('); + expr.getLeft().accept(this); + out.print('.' + method + '('); + expr.getRight().accept(this); + out.print("))"); + } + + private void processReceiveOrPeek(final ExpressionInterface chanExpr, + final ExpressionInterface typeExpr, + String which) + throws VisitorException { + out.print("(new CspInteger(" + which + "("); + chanExpr.accept(this); + out.print(')'); + // receive() returns a Message, so we need to do getValue() + // peek() returns a BigInteger + if (which == "receive") + out.print(".getValue()"); + out.print(')'); + + + if (analysisResults.getType(typeExpr) instanceof BooleanType) { + // Handle receive into boolean + out.print(".booleanValue()" + + " ? CspInteger.TRUE" + + " : CspInteger.FALSE)"); + } else + out.print(")"); + } + + private void processShift(final AbstractBinaryExpression expr, + final String shiftMethod) + throws VisitorException { + // This is wrong if the value to shift by does not + // fit in an int. Hopefully that will never happen. + // We could write a helper function to do this. + out.print('('); + expr.getLeft().accept(this); + out.print('.' + shiftMethod + '('); + expr.getRight().accept(this); + out.print(".intValue()))"); + } + + private void processIdentifier(String ident) { + // Just prefix ident with _ for now, may use symbol table + // later, or do something special for arrays. + // XXX: channels must be looked up!, or aliases made + // in constructor. + out.print('_' + ident); + } + + private void processGuardedStatement(AbstractGuardedStatement s, + final boolean breakP) + throws VisitorException { + boolean firstP = true; + for (final Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + Object maybe_gc = i.next(); + + if (!(maybe_gc instanceof GuardedCommand)) { + AbstractASTNode blame = s; + if (maybe_gc instanceof AbstractASTNode) + blame = (AbstractASTNode) maybe_gc; + String[] clname = + StringUtil.split(maybe_gc.getClass().getName(), '.'); + throw new VisitorExceptionWithLocation("expected GuardedCommand, got " + clname[clname.length - 1] + "\n\t(are you missing a level of square brackets?)", blame); + } + + final GuardedCommand gc = (GuardedCommand) maybe_gc; + + if (firstP) + firstP = false; + else + out.print("else "); + + out.print("if ("); + gc.getGuard().accept(this); + out.println(".booleanValue()) {"); + emitOneProbe((AbstractASTNode)gc.getCommand(), + "nondeterministic repetition statement alternative"); + gc.getCommand().accept(this); + if (breakP) + out.println("break;"); + out.println("}"); + } + + // It would be nice if the else stuff could be put here too. + } + + public void visitAddExpression(AddExpression e) + throws VisitorException { + if (analysisResults.getType(e) instanceof StringType) { + final boolean lstr = + analysisResults.getType(e.getLeft()) instanceof StringType; + if (!lstr) out.print("new CspString("); + e.getLeft().accept(this); + if (!lstr) out.print(".toString())"); + + out.print(".add("); + + final boolean rstr = + analysisResults.getType(e.getRight()) instanceof StringType; + if (!rstr) out.print("new CspString("); + e.getRight().accept(this); + if (!rstr) out.print(".toString())"); + + out.print(')'); + } else { + processBinary(e, "add"); + } + } + + public void visitAndExpression(AndExpression e) + throws VisitorException { + processBinary(e, "and"); + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + + // This handles array accesses. Assignment to array elements is + // handled separately by the assignment statement. + + if (!isPortArray) { + final Type elemType = analysisResults.getType(e); + // cast to the correct type [1]; don't do anything if it is a + // channel, since the arrays used to handle channels already return + // the correct types + assert elemType != null; + final boolean nonChannelType = + !(elemType instanceof com.avlsi.csp.ast.ChannelStructureType || + elemType instanceof com.avlsi.csp.ast.ChannelType || + elemType instanceof com.avlsi.csp.ast.NodeType); + if (nonChannelType) { + out.print("(("); + elemType.accept(this); + out.print(")"); + } else { + isPortArray = true; + } + } + + final boolean oldPortArray = isPortArray; + e.getArrayExpression().accept(this); + out.print(".get("); + + isPortArray = false; + e.getIndexExpression().accept(this); + ParsePosition pp = e.getIndexExpression().getParseRange().start; + out.print(", \"" + pp.filename + "\", " + + pp.line + ", " + pp.column); + out.print(")"); + + // [1] + if (!oldPortArray) + out.print(")"); + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + // Calculate the extracted value. Assigning a value to a bit range + // expression is handled separately by the assignment statement. + + e.getBitsExpression().accept(this); + out.print(".extractBits("); + if (e.getMinExpression() != null) { + e.getMinExpression().accept(this); + out.print(","); + } + e.getMaxExpression().accept(this); + out.print(")"); + } + + public void visitConditionalAndExpression(ConditionalAndExpression expr) + throws VisitorException { + out.print("CspInteger.valueOf("); + expr.getLeft().accept(this); + out.print(".booleanValue() && "); + expr.getRight().accept(this); + out.print(".booleanValue())"); + } + + public void visitConditionalOrExpression(ConditionalOrExpression expr) + throws VisitorException { + out.print("CspInteger.valueOf("); + expr.getLeft().accept(this); + out.print(".booleanValue() || "); + expr.getRight().accept(this); + out.print(".booleanValue())"); + } + + private void processAssert(FunctionCallExpression e) + throws VisitorException { + final Iterator i = e.getActuals(); + final ExpressionInterface guard = (ExpressionInterface) i.next(); + final ExpressionInterface message = + i.hasNext() ? (ExpressionInterface) i.next() : null; + out.print("handleAssert(whereAmI, "); + guard.accept(this); + out.print(", "); + if (message == null) { + out.print("null"); + } else { + message.accept(this); + } + out.println(");"); + } + + private void processPack(FunctionCallExpression e) + throws VisitorException { + final Iterator i = e.getActuals(); + final ExpressionInterface structExpr = (ExpressionInterface) i.next(); + out.print("pack("); + structExpr.accept(this); + out.print(")"); + } + + private void processUnpack(FunctionCallExpression e) + throws VisitorException { + final Iterator i = e.getActuals(); + final ExpressionInterface structExpr = (ExpressionInterface) i.next(); + final ExpressionInterface packed = (ExpressionInterface) i.next(); + out.print("unpack("); + structExpr.accept(this); + out.print(", "); + packed.accept(this); + out.println(")"); + } + + private void processWidth(final ExpressionInterface e) + throws VisitorException { + final BigInteger bi = CspUtils.getIntegerConstant(e); + if (bi == null) { + out.print("("); + e.accept(this); + out.print(").intValue()"); + } else { + // TODO: throw error for width > Integer.MAX_VALUE + out.print(bi.intValue()); + } + } + + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + // processing: func(x, y, z) + + // func + boolean isConstructor = false; + final Pair p = (Pair) resolver.getResolvedFunctions().get(e); + final ArrayList args; + String name; + if (p == null) { + final ExpressionInterface func = e.getFunctionExpression(); + name = ((IdentifierExpression) func).getIdentifier(); + args = null; + if (name.equals("assert")) { + processAssert(e); + return; + } else if (name.equals("pack")) { + processPack(e); + return; + } else if (name.equals("unpack")) { + processUnpack(e); + return; + } + } else { + final Object decl = p.getSecond(); + if (decl instanceof FunctionDeclaration) { + final FunctionDeclaration fdecl = (FunctionDeclaration) decl; + args = new ArrayList(); + name = fdecl.getName(); + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + args.add(d); + } + }).process(fdecl.getFormals()); + } else if (decl instanceof StructureDeclaration) { + isConstructor = true; + args = null; + name = ((StructureDeclaration) decl).getName(); + } else { + throw new VisitorExceptionWithLocation("Call to unknown function", e); + } + if (!RefinementResolver.isBuiltin(decl)) + name = name + "_" + labels.getLabel(decl); + } + if (isConstructor) out.print("(new "); + processIdentifier(name); + + // "(" + out.print('('); + + // actuals: x, y, z + int count = 0; + for (final Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface actual = (ExpressionInterface) i.next(); + + // "," + if (count > 0) out.print(", "); + final Declarator arg = args == null ? null : args.get(count); + final boolean copy = + args == null ? false : arg.getDirection() == Declarator.IN; + + // actual + if (arg != null && arg.getTypeFragment() instanceof IntegerType) { + final IntegerType ty = (IntegerType) arg.getTypeFragment(); + if (copy) { + if (ty.getDeclaredWidth() == null) { + out.print("new CspInteger("); + } else { + out.print("new FiniteCspInteger("); + processWidth(ty.getDeclaredWidth()); + out.print(", " + ty.isSigned() + ", "); + } + actual.accept(this); + out.print(")"); + } else { + final boolean bit = actual instanceof BitRangeExpression; + out.print("(new ShadowCspInteger"); + if (bit) out.print(".BitRange"); + else out.print(".Simple"); + out.print("("); + if (ty.getDeclaredWidth() != null) { + processWidth(ty.getDeclaredWidth()); + out.print(", " + ty.isSigned() + ", "); + } + if (bit) { + final BitRangeExpression bre = + (BitRangeExpression) actual; + bre.getMinExpression().accept(this); + out.print(", "); + bre.getMaxExpression().accept(this); + out.print(", "); + bre.getBitsExpression().accept(this); + } else { + actual.accept(this); + } + out.print("))"); + } + } else { + if (copy) { + final Type t = analysisResults.getType(actual); + out.print("(("); + t.accept(this); + out.print(") ("); + } + actual.accept(this); + if (copy) out.print(").duplicate())"); + } + } + + // ")" + out.print(')'); + if (isConstructor) out.print(")"); + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + // may want to handle divide specially to get + // different rounding, or catch divide by 0 exception + processBinary(e, "divide"); + } + + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + // This is wrong if the value to exponentiate by does not + // fit in an int. Hopefully that will never happen. + // We could write a helper function to do this. + out.print('('); + e.getLeft().accept(this); + out.print(".pow("); + e.getRight().accept(this); + out.print(".intValue()))"); + } + + private void processCompare(AbstractBinaryExpression expr, + final String compare) throws VisitorException { + out.print('('); + processBinary(expr, "compareTo"); + out.print(compare + " 0" + + " ? CspInteger.TRUE" + + " : CspInteger.FALSE)"); + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + // could be optimized to use .equals() instead of compareTo + processCompare(e, "=="); + } + + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + processCompare(e, ">="); + } + + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + processCompare(e, ">"); + } + + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + // could be optimized to use .equals() instead of compareTo + processCompare(e, "!="); + } + + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + processCompare(e, "<="); + } + + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + processCompare(e, "<"); + } + + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + String value = e.getValue(); + int radix = e.getRadix(); + try { + /* Reduce code size by just using a bipush when possible, + * rather than putting another string in the constant table. + * (bug 3896) */ + byte b = Byte.parseByte(value, radix); + out.print("new CspInteger((byte)" + b + ')'); + } catch (NumberFormatException nf) { // Bigger than a byte + if (radix == 10) { // omit radix if possible + out.print("new CspInteger(new BigInteger(\"" + value + "\"))"); + } else { + out.print("new CspInteger(new BigInteger(\"" + value + + "\", " + radix + "))"); + } + } + } + + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + processShift(e, "shiftLeft"); + } + + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + processShift(e, "shiftRight"); + } + + public void visitIdentifierExpression(IdentifierExpression e) { + processIdentifier(e.getIdentifier()); + } + + public void visitLoopExpression(LoopExpression e) + throws VisitorException { + + final String[] units = new String[] { + "BigInteger.ZERO.not()", // AND + "BigInteger.ZERO", // OR + "BigInteger.ONE", // TIMES + "BigInteger.ZERO", // PLUS + "BigInteger.ZERO" }; // XOR + final String[] functions = new String[] { + "Fold.AND_FUNCTION", // AND + "Fold.OR_FUNCTION", // OR + "Fold.MULTIPLY_FUNCTION", // TIMES + "Fold.ADD_FUNCTION", // PLUS + "Fold.XOR_FUNCTION" }; // XOR + + final boolean stringType = + analysisResults.getType(e) instanceof StringType; + out.print("("); + if (stringType) out.print("(CspString) "); + else out.print("(CspInteger) "); + out.println("new Fold() {"); + out.print("public CspValue evaluate(final CspInteger "); + processIdentifier(e.getIndexVar()); + out.println(") throws InterruptedException {"); + out.print("return "); + e.getExpression().accept(this); + out.println(';'); + out.println('}'); + final int sep = e.getSeparator(); + + // should have caught other invalid operations on strings in + // VariableAnalyzer + assert !stringType || sep == LoopExpression.PLUS; + + out.print("}.fold(" + + (stringType ? "new CspString()" + : "new CspInteger(" + units[sep] + ")") + + ", " + functions[sep] + ", "); + e.getRange().getMinExpression().accept(this); + out.print(", "); + e.getRange().getMaxExpression().accept(this); + out.print("))"); + } + + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + processBinary(e, "multiply"); + } + + public void visitNegateExpression(NegateExpression e) + throws VisitorException { + processUnary(e, "negate"); + } + + public void visitNotExpression(NotExpression e) + throws VisitorException { + processUnary(e, "not"); + } + + public void visitOrExpression(OrExpression e) + throws VisitorException { + processBinary(e, "or"); + } + + public void visitXorExpression(XorExpression e) + throws VisitorException { + processBinary(e, "xor"); + } + + public void visitPeekExpression(PeekExpression e) + throws VisitorException { + processReceiveOrPeek(e.getChannelExpression(), e, "peek"); + } + + public void visitProbeExpression(ProbeExpression e) + throws VisitorException { + out.print("(probe("); + e.getChannelExpression().accept(this); + out.print(") ? CspInteger.TRUE" + + " : CspInteger.FALSE)"); + } + + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException { + processReceiveOrPeek(e.getChannelExpression(), e, "receive"); + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + // may want to handle divide specially to get + // different rounding, or catch divide by 0 exception + processBinary(e, "remainder"); + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + out.print("new CspString(\"" + + StringUtil.quoteASCIIString(e.getValue(), ESCAPE_MAP) + + "\")"); + } + + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + processBinary(e, "subtract"); + } + + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(this); + out.print("._"); + out.print(e.getFieldName()); + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(this); + out.print("."); + processIdentifier(e.getMemberName()); + } + + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + s.getAssignmentStatement().accept(this); + } + + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + // This assumes that the lhs expression emitter always emits + // an lvalue. This may not be true for arrays, in which + // case something will have to be done for get() / set(). + final ExpressionInterface lhs = s.getLeftHandSide(); + final ExpressionInterface rhs = s.getRightHandSide(); + + if (lhs instanceof BitRangeExpression){ + + // We are assigning to a bit field. Make a transformation so + // that no bit field is involved. + + BitRangeExpression bre = (BitRangeExpression) lhs; + + bre.getBitsExpression().accept(this); + out.print(".assignBits("); + if (bre.getMinExpression() != null) { + bre.getMinExpression().accept(this); + out.print(","); + } + bre.getMaxExpression().accept(this); + out.print(","); + rhs.accept(this); + if (s.getKind() != AssignmentStatement.EQUAL) { + out.print(", Fold." + s.getKindString().toUpperCase() + + "_FUNCTION"); + } + out.println(");"); + } else { + + // We are not assigning to a bit range + + lhs.accept(this); + final boolean str = + s.getKind() == AssignmentStatement.ADD && + (analysisResults.getType(lhs) instanceof StringType) && + !(analysisResults.getType(rhs) instanceof StringType); + out.print(".setValue("); + + if (str) out.print("new CspString("); + rhs.accept(this); + if (str) out.print(".toString())"); + + if (s.getKind() != AssignmentStatement.EQUAL) { + out.print(", Fold." + s.getKindString().toUpperCase() + + "_FUNCTION"); + } + out.println(");"); + } + } + + public void visitDeterministicRepetitionStatement( + DeterministicRepetitionStatement s) + throws VisitorException { + + final String label = "label" + genVarNum(); + out.println(label + ':'); + + out.println("for (;;) {"); + final String trueIdx = "trueIdx" + genVarNum(); + out.println("int " + trueIdx + " = -1;"); + + // evaluate guards + processDeterministicGuards(s, trueIdx); + + if ((emitSnoopStatements || synthesizable) && bodyP && !foundLoop) { + foundLoop = true; + out.println("cspSnooper.onOutermostLoopStart();"); + } + + // execute body + out.println("switch (" + trueIdx + ") {"); + // a case that never occurs but prevents the Java compiler from + // concluding later code as unreacahble + out.println("case -2:"); + out.println("break " + label + ";"); + + // handle else, if any + out.println("case -1:"); + if (s.getElseStatement() == null) { + out.println("break " + label + ";"); + } else { + emitOneProbe((AbstractASTNode)s.getElseStatement(), + "deterministic repetition statement else clause"); + s.getElseStatement().accept(this); + out.println("break;"); + } + + // handle bodies + processDeterministicBodies(s, null); + out.println('}'); + if (!emitSnoopStatements) { + // the simulation could be interrupted at yield, so we need to + // reset the annotate position to avoid confusing the user + annotatePosition(s); + out.println("yield();"); + } + + out.println('}'); + } + + private int recurseDeterministicGuards(Iterator guards, + AbstractASTNodeInterface where, + String trueIdx, int idx) + throws VisitorException { + // evaluate guards + for (final Iterator i = guards; i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + + if (gci instanceof LoopGuard) { + final LoopGuard lg = (LoopGuard) gci; + final String loopVar = "loopVar" + genVarNum(); + final String indexVar = lg.getIndexVar(); + final Range range = lg.getRange(); + loopVarHash.put(lg, loopVar); + out.println("if (" + trueIdx + " == -1) " + + loopVar + " = null;"); + + out.print("for (final CspInteger "); + processIdentifier(indexVar); + out.print(" = new CspInteger("); + range.getMinExpression().accept(this); + out.println("); "); + processIdentifier(indexVar); + out.print(".compareTo("); + range.getMaxExpression().accept(this); + out.println(") <= 0; "); + processIdentifier(indexVar); + out.print(".setValue("); + processIdentifier(indexVar); + out.println(".add(CspInteger.ONE))) {"); // [2] + + idx = recurseDeterministicGuards(lg.getGuards().iterator(), + where, trueIdx, idx); + + out.print("if (" + loopVar + " == null && " + + trueIdx + " != -1) " + loopVar + " = "); + processIdentifier(indexVar); + out.println(".toBigInteger();"); + out.println('}'); // matches [2] + } else { + final GuardedCommand gc = (GuardedCommand) gci; + + out.print("if ("); + gc.getGuard().accept(this); + out.println(".booleanValue()) {"); + // first guard doesn't need multiple true check + if (idx == 0) { + out.println(trueIdx + " = " + idx + ';'); + } else { + // Don't include idx in string keep from creating + // many strings in class. + out.println("if (" + trueIdx + " == -1)"); + out.println(trueIdx + " = " + idx + ';'); + out.println("else {"); + out.println("throw new NonDeterminismException(\"" + + "Error -- Multiple guards \" + " + trueIdx + + " + \" and \" + " + idx + + " + \" true for deterministic repetition" + + " or selection at \" + \"" + + where.getParseRange().start.filename + + ':' + where.getParseRange().toString()+ + "\");"); + out.println("}"); + } + out.println('}'); + ++idx; + } + } + + return idx; + } + + /** + * Process the guards for a deterministic repetition or selection + * statement. + * + * @param s DeterministicRepetitionStatement or + * DeterministicSelectionStatement whose guards are to be evaluated + * @param trueIdx variable name to store index of true variable + **/ + private void processDeterministicGuards(final AbstractGuardedStatement s, + final String trueIdx) throws VisitorException { + recurseDeterministicGuards(s.getGuardedCommands(), s, trueIdx, 0); + } + + protected void emitOneProbe(AbstractASTNode node, + String type) { + if(emitCoverageProbes) { + ParseRange pr=node.getParseRange(); + out.println("/* coverage probe (line "+ + pr.start.line+", column "+pr.start.column+ + " to line "+pr.end.line+", column "+pr.end.column+") */"); + out.println("Monitor.global.setHit(hitTableOffset+"+probeCount+");"); + probes.add(new ProbeInfo(pr, type, + cellInfo.getAbbreviatedType())); + probeCount++; + } + } + + private int recurseDeterministicBodies(Iterator guards, String breakLabel, + int idx, NullaryAction[] vardecl) + throws VisitorException { + for (final Iterator i = guards; i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + + if (gci instanceof LoopGuard) { + final LoopGuard lg = (LoopGuard) gci; + final String indexVar = lg.getIndexVar(); + final String loopVar = (String) loopVarHash.get(lg); + final NullaryAction[] newVardecl = + new NullaryAction[vardecl.length + 1]; + System.arraycopy(vardecl, 0, newVardecl, 0, vardecl.length); + newVardecl[vardecl.length] = new NullaryAction() { + public void execute() { + out.print("final CspInteger "); + processIdentifier(indexVar); + out.println(" = new CspInteger(" + loopVar + ");"); + } + }; + idx = recurseDeterministicBodies(lg.getGuards().iterator(), + breakLabel, idx, newVardecl); + } else { + final GuardedCommand gc = (GuardedCommand) gci; + + out.println("case " + idx + ':'); + out.println("{"); // [1] + for (int j = 0; j < vardecl.length; j++) + vardecl[j].execute(); + emitOneProbe((AbstractASTNode)gc.getCommand(), + "repetition or selection statement alternative"); + gc.getCommand().accept(this); + if (breakLabel != null) + out.println("break " + breakLabel + ';'); + else + out.println("break;"); + out.println("}"); // matches [1] + ++idx; + } + } + + return idx; + } + + /** + * Process the bodies for a deterministic repetition or selection + * statement. + * + * @param s DeterministicRepetitionStatement or + * DeterministicSelectionStatement whose statements are to be emitted + **/ + private void processDeterministicBodies( + final AbstractGuardedStatement s, + final String breakLabel) throws VisitorException { + recurseDeterministicBodies(s.getGuardedCommands(), breakLabel, 0, + new NullaryAction[0]); + } + + public void visitDeterministicSelectionStatement( + DeterministicSelectionStatement s) + throws VisitorException { + // TODO: + // Check for probes in the guard statements. If there are + // probes, we must generate a Wait inside a for loop. + // If not, ifs are fine. + + // Whether we should emit wait statements + // Always emit wait statements for now, before we resolve the question + // on what semantics functions should have. See bug 7111. + final boolean waitP = true; // bodyP; // why is this bodyP? --frederik + + out.println('{'); + + final String waitVar; + final String waitableVar; + final String pairVar; + final String label; + if (waitP) { + final int varNum = genVarNum(); + waitVar = "w" + varNum; + waitableVar = "wa" + varNum; + pairVar = "p" + varNum; + out.println("Wait " + waitVar + " = null;"); + + label = "label" + genVarNum(); + out.println(label + ':'); + out.println("for (;;) {"); + } else { + waitVar = null; + waitableVar = null; + pairVar = null; + label = null; + } + + final String trueIdx = "trueIdx" + genVarNum(); + out.println("int " + trueIdx + " = -1;"); + + // evaluate guards + processDeterministicGuards(s, trueIdx); + + // execute body + out.println("switch (" + trueIdx + ") {"); + // handle else, if any + out.println("case -1:"); + if (waitP) { + if (s.getElseStatement() == null) { + if (emitSnoopStatements || synthesizable) { + out.println( + "cspSnooper.onDeadlock(\"No guards true " + + "in deterministic selection\", whereAmI);"); + } + // Probe looks at the time, so we must update + // the time even for deterministic selection + // statements, otherwise all probes could + // return false and we would get empty + // wait set exceptions. + out.println("if (" + waitVar + " == null)"); + out.println(waitVar + + " = WaitFactory.newWait(in, out," + + " getNodesWithDifferentValue(true)," + + " getNodesWithDifferentValue(false));"); + out.println("final Pair/**/ " + + pairVar + " = select2(" + + waitVar + ");"); + out.println("updateTime(((Long)" + pairVar + + ".getSecond()).longValue());"); + out.println("final Waitable " + waitableVar + + " = (Waitable) " + pairVar + + ".getFirst();"); + out.println("Arbiter.removeFromWait(" + waitVar + + ", " + waitableVar + ");"); + out.println("break;"); + } else { + emitOneProbe((AbstractASTNode)s.getElseStatement(), + "deterministic selection statement else clause"); + s.getElseStatement().accept(this); + out.println("break " + label + ';'); + } + } else { + if (s.getElseStatement() != null) { + emitOneProbe((AbstractASTNode)s.getElseStatement(), + "deterministic selection statement else clause"); + s.getElseStatement().accept(this); + out.println("break;"); + } else { + // If we are not waiting, and no alternatives are + // true, then they never will be true, so flag an + // error. + out.println("throw new RuntimeException(\"" + + "No true guards in unwaited " + + "selection.\");"); + } + } + + // handle bodies + processDeterministicBodies(s, label); + out.println('}'); + + + if (waitP) { + out.println('}'); + // let the wait be garbage collected + out.println(waitVar + " = null;"); + } + + out.println('}'); + } + + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + s.getExpression().accept(this); + out.println(';'); + } + + public void visitLoopStatement(LoopStatement s) throws VisitorException { + // Treat parallel as sequential for now. + if (s.getSeparator() == LoopStatement.PARALLEL) { + warningWriter.println("Warning: Sequentializing parallel loop."); + out.println("/* Warning: should have been a parallel loop. */"); + } + + final String loopMax = "loopMax" + genVarNum(); + out.print("for (final CspInteger "); + processIdentifier(s.getIndexVar()); + out.print(" = new CspInteger("); + s.getRange().getMinExpression().accept(this); + out.print("), " + loopMax + " = "); + s.getRange().getMaxExpression().accept(this); + out.println("; "); + processIdentifier(s.getIndexVar()); + out.println(".compareTo(" + loopMax + ") <= 0; "); + processIdentifier(s.getIndexVar()); + out.print(".setValue("); + processIdentifier(s.getIndexVar()); + out.println(".add(CspInteger.ONE))) {"); + s.getStatement().accept(this); + out.println('}'); + } + + public void visitNonDeterministicRepetitionStatement( + NonDeterministicRepetitionStatement s) + throws VisitorException { + // Be unfair in choice for now + out.println("for (;;) {"); + processGuardedStatement(s, false); + + out.println("else {"); + if (s.getElseStatement() == null) { + out.println("break;"); + } else { + emitOneProbe((AbstractASTNode)s.getElseStatement(), + "nondeterministic repetition else statement"); + s.getElseStatement().accept(this); + } + out.println('}'); + out.println('}'); + } + + public void visitNonDeterministicSelectionStatement( + NonDeterministicSelectionStatement s) + throws VisitorException { + final String alternatives = "alternatives" + genVarNum(); + out.println("LinkedList " + alternatives + " = new LinkedList();"); + + // use arbiter maker? + + processAlternatives(s.getGuardedCommands(), alternatives); + if (emitSnoopStatements || synthesizable) { + out.println("checkAlternative(" + alternatives + ", cspSnooper);"); + } + out.println("arbitrate(new Arbiter((Alternative[])" + alternatives + + ".toArray(new Alternative[0]),"); + if (s.getNeutralState() != null) + out.println("linkage" + + linkageLabel.getLabel(s.getNeutralState()) + ","); + else + out.println("(Linkage) null,"); + // If @(linkage) was not specified, make the arbiter non-linked + // We only need to check one because the grammar ensures + // that either all or none of the linkage specifiers are there. + if (s.getNeutralState() == null) + out.print("Arbiter.NON_LINKED, "); + else + out.print("arbitrationMode, "); + out.print("in, out, "); + if (s.getNeutralState() == null) { + out.print("getNodesWithDifferentValue(true), " + + "getNodesWithDifferentValue(false), "); + } + out.println("arbiterRandom, " + className + ".this)," + + "\"" + getLocation(s) + "\");"); + } + + private void processAlternatives(Iterator guards, String alternatives) + throws VisitorException { + // stuff to construct arbiter + for (final Iterator i = guards; i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + + if (gci instanceof LoopGuard) { + final LoopGuard lg = (LoopGuard) gci; + final String loopVar = "loopVar" + genVarNum(); + final String indexVar = lg.getIndexVar(); + final Range range = lg.getRange(); + + out.print("for (final CspInteger " + loopVar); + out.print(" = new CspInteger("); + range.getMinExpression().accept(this); + out.println("); "); + out.print(loopVar + ".compareTo("); + range.getMaxExpression().accept(this); + out.println(") <= 0; "); + out.print(loopVar + ".setValue(" + loopVar); + out.println(".add(CspInteger.ONE))) {"); // [1] + + out.print("final CspInteger "); + processIdentifier(indexVar); + out.print(" = new CspInteger(" + loopVar + + ".toBigInteger());"); + processAlternatives(lg.getGuards().iterator(), alternatives); + out.println("}"); // matches [1] + } else { + final GuardedCommand gc = (GuardedCommand) gci; + + out.println(alternatives + ".add(new Alternative("); + // guard + out.println("new NullaryPredicate() {"); + out.println("public boolean evaluate()" + + " throws InterruptedException {"); + out.print("return "); + gc.getGuard().accept(this); + out.println(".booleanValue();"); + out.println("}"); + out.println("}, "); + // linkage terms are handled by Arbiter.Linkage + // action + out.println("new Action() {"); + out.println("public void execute() " + + "throws InterruptedException {"); + emitOneProbe((AbstractASTNode)gc.getCommand(), + "nondeterministic selection "+ + "statement alternative"); + gc.getCommand().accept(this); + out.println("}"); + out.println("}"); + out.println("));"); + } + } + } + + public void visitLinkageLoopTerm(final LinkageLoopTerm term) + throws VisitorException { + throw new VisitorException("should never be called"); + } + + public void visitLinkageExpressionTerm(final LinkageExpressionTerm term) + throws VisitorException { + throw new VisitorException("should never be called"); + } + + public void visitLinkageArrayAccessExpression( + final LinkageArrayAccessExpression e) + throws VisitorException { + throw new VisitorException("should never be called"); + } + + public void visitLinkageIdentifierExpression( + final LinkageIdentifierExpression e) + throws VisitorException { + throw new VisitorException("should never be called"); + } + + public void visitLinkageStructureAccessExpression( + final LinkageStructureAccessExpression e) + throws VisitorException { + throw new VisitorException("should never be called"); + } + + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + int nStmts = 0; + for (final Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + annotatePosition(stmt); + // The statements will already be terminated with a ; + stmt.accept(this); + // Check for number of statements because we may have one + // statement in parallel, in which case nothing special need + // be done. + if (nStmts >= 1) + out.println("/* ^ Should have been parallel. */"); + if (nStmts == 1) + warningWriter.println("Warning: " + + "Sequentializing parallel statements."); + + nStmts++; + } + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + final ExpressionInterface target = s.getRightHandSide(); + final ExpressionInterface source = s.getChannelExpression(); + + if (target != null) { + // This case is expressible as an assignment statement, so we + // construct this equivalent statement as the source for Java + // translation. + final ExpressionInterface recv = new ReceiveExpression(source); + final Type targetType = analysisResults.getType(target); + analysisResults.setType(recv, targetType); + if (targetType instanceof StructureType || + targetType instanceof ArrayType) { + out.print("unpack("); + target.accept(this); + out.print(", "); + recv.accept(this); + out.println(");"); + } else { + new AssignmentStatement(target, recv).accept(this); + } + } else { + // target == null, so remove a token from the channel + // Put receive statement in an if statement with an empty body + // because (receive(chan).getValue()) is not a statement. + // receive(chan).getValue() is, but it would be more work to + // control the generation of ()'s, so we just wrap it in an + // if statement. + out.print("if ("); + processReceiveOrPeek(source, target, "receive"); + out.println(" != null)"); + out.println("/* do nothing */;"); + } + } + + public void visitSendStatement(SendStatement s) + throws VisitorException { + final ExpressionInterface expr = s.getRightHandSide(); + final com.avlsi.csp.ast.ChannelType chanType = + (com.avlsi.csp.ast.ChannelType) + analysisResults.getType(s.getChannelExpression()); + out.print("send("); + if (!BigIntegerUtil.isPowerOf2(chanType.getNumValues())) { + final ParseRange pr = s.getParseRange(); + out.print("\"" + cellInfo.getAbbreviatedType() + "\", \"" + + pr.fullString() + "\", "); + } + s.getChannelExpression().accept(this); + out.print(", "); + final Type ty = analysisResults.getType(expr); + final boolean needPack = ty instanceof StructureType || + ty instanceof ArrayType; + if (needPack) out.print("pack("); + expr.accept(this); + if (needPack) out.print(")"); + out.println(".toBigInteger());"); + } + + void sequentialStatementBeginScopeHook() { + out.println("{"); // provide scope for variables + } + + void sequentialStatementEndScopeHook() { + out.println("}"); + } + + private String getLocation(AbstractASTNodeInterface node) { + final ParseRange pr = node.getParseRange(); + final String fname = pr.start.filename; + return fname + ' ' + pr.toString(); + } + + private void annotatePosition(StatementInterface stmt) { + if (bodyP || funcP) { + out.println("setWhereAmI(\"" + getLocation(stmt) + "\");"); + } + } + + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + sequentialStatementBeginScopeHook(); + for (final Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + annotatePosition(stmt); + // The statements will already be terminated with a ; + stmt.accept(this); + } + sequentialStatementEndScopeHook(); + } + + public void visitErrorStatement(ErrorStatement s) + throws VisitorException { + out.println("handleError(\"" + cellInfo.getAbbreviatedType() + + "\", \"" + + s.getFilename() + "\", " + s.getLine() + ", " + + s.getColumn() + ");"); + } + + public void visitSkipStatement(SkipStatement s) + throws VisitorException { + out.println("/* skip */"); + } + + public void visitVarStatement(VarStatement s) + throws VisitorException { + + if (s.getStatement() != null) { + // Scoped var statement + + out.println("{ /* begin block */"); + } + + // Handle variables + + processDeclarationList(s.getDeclarationList(), false, + new TopLevelDeclaratorProcessor()); + + if (s.getStatement() != null) { + // Handle code + s.getStatement().accept(this); + + out.println("} /* end block */"); + } + } + + private void processDeclarationList(DeclarationList dl, boolean formalP) + throws VisitorException { + processDeclarationList(dl, formalP, new DeclaratorProcessor()); + } + + private void processDeclarationList(DeclarationList dl, boolean formalP, + DeclaratorProcessor proc) + throws VisitorException { + + boolean firstP = true; + for (final Iterator i = dl.getDeclarations(); i.hasNext(); ) { + final Declaration d = (Declaration) i.next(); + if (formalP) { + if (firstP) + firstP = false; + else { + // comma separates formals + out.println(','); + } + } + processDeclaration(d, formalP, proc); + } + } + + void declarationModifierHook() { + // All types must be declared final due to interaction with + // inner class Fold. + + out.print("final "); + } + + boolean useLoggedType() { return true; } + + private class DeclaratorProcessor { + public void emitModifier(Declarator dr) throws VisitorException { + declarationModifierHook(); + } + public void emitType(Declarator dr) throws VisitorException { + dr.getTypeFragment().accept(JavaEmitter.this); + } + public String getInitPreamble() { + return " = "; + } + public String getInitPostamble() { + return ";"; + } + public String getTerminator() { + return ""; + } + public boolean outputInit() { + return true; + } + public boolean generateLoggedType() { + return useLoggedType(); + } + public boolean isTopLevel() { + return false; + } + public String getPrefix() { + return "\"\""; + } + } + + private class TopLevelDeclaratorProcessor extends DeclaratorProcessor { + public boolean isTopLevel() { + return true; + } + } + + private void processDeclaration(Declaration d, boolean formalP) + throws VisitorException { + processDeclaration(d, formalP, new DeclaratorProcessor()); + } + + private void processLoggedType(final Type t) throws VisitorException { + if (t instanceof IntegerType) { + final IntegerType it = (IntegerType) t; + if (it.getDeclaredWidth() != null) { + out.print("getElementConstructor("); + processWidth(it.getDeclaredWidth()); + out.print(", " + it.isSigned() + ")"); + } else { + out.print("LoggedCspInteger.class"); + } + } else { + if (t instanceof BooleanType) { + out.print("LoggedCspBoolean"); + } else if (t instanceof StructureType) { + final StructureType st = (StructureType) t; + final Pair p = (Pair) resolver.getResolvedStructures().get(st); + assert p != null; + final StructureDeclaration decl = + (StructureDeclaration) p.getSecond(); + processIdentifier("Logged" + decl.getName() + "_" + + labels.getLabel(decl)); + } else { + t.accept(this); + } + out.print(".class"); + } + } + + private Type deArray(Type t) { + while (t instanceof ArrayType) { + t = ((ArrayType) t).getElementType(); + } + return t; + } + + private void processDeclaration(Declaration d, boolean formalP, + DeclaratorProcessor proc) + throws VisitorException { + + boolean firstP = true; + for (Iterator i = d.getDeclaratorList().getDeclarators(); + i.hasNext(); ) { + + final Declarator dr = (Declarator) i.next(); + + if (formalP) { + if (firstP) + firstP = false; + else { + // comma separates formals + out.println(','); + } + } + + proc.emitModifier(dr); + + // Print java type + + proc.emitType(dr); + + // Whitespace separates type and identifier + + out.print(" "); + + // Print identifier + + dr.getIdentifier().accept(this); + + if (!formalP && proc.outputInit()) { + out.print(proc.getInitPreamble()); + + // Add appropriate initializer (ignore arrays for now) + // REVIEW: use one Type visitor for initializers, + // another for variable declarations. + + Type varT = dr.getTypeFragment(); + ExpressionInterface init = dr.getInitializer(); + + if (varT instanceof IntegerType) { + // Integer type + IntegerType integerT = (IntegerType) varT; + final ExpressionInterface width = + integerT.getDeclaredWidth(); + if (init == null && integerT.isConst()) { + // no initializer present for a const declarator + throw new VisitorException( + "Missing initializer for const variable."); + } else { + final String intType = + width != null ? "FiniteCspInteger" : "CspInteger"; + out.print("new "); + if (proc.generateLoggedType()) { + out.print("Logged" + intType + "(" + + proc.getPrefix() + " + \"" + + dr.getIdentifier().getIdentifier() + + "\", "); + if (proc.isTopLevel()) { + out.print("\"" + + getLocation(dr.getIdentifier()) + + "\", "); + } + } else { + out.print(intType + "("); + } + if (init == null) { + // no initializer present for a non-constant + // declarator + out.print("BigInteger.ZERO"); + } else { + init.accept(this); + out.print(".toBigInteger()"); + } + if (width != null) { + out.print(", ("); + width.accept(this); + out.print(").intValue(), "); + out.print(integerT.isSigned()); + } + out.print(")"); + } + } else if (varT instanceof BooleanType) { + BooleanType boolT = (BooleanType) varT; + if (init == null && boolT.isConst()) { + // no initializer present for a const declarator + throw new VisitorException( + "Missing initializer for const variable."); + } else { + out.print("new "); + if (proc.generateLoggedType()) { + out.print("LoggedCspBoolean(" + + proc.getPrefix() + " + \"" + + dr.getIdentifier().getIdentifier() + + "\", "); + if (proc.isTopLevel()) { + out.print("\"" + + getLocation(dr.getIdentifier()) + + "\", "); + } + } else { + out.print("CspBoolean("); + } + if (init == null) { + // no initializer present for a non-constant + // declarator + out.print("BigInteger.ZERO"); + } else { + init.accept(this); + out.print(".toBigInteger()"); + } + out.print(")"); + } + } else if (varT instanceof StringType) { + if (init == null) { + out.print("new CspString()"); + } else { + init.accept(this); + } + } else if (varT instanceof ArrayType) { + + // Array type + + // Arrays currently do not accept initializers + if (init != null) + throw new VisitorException( + "Array initializers are not supported at " + + init.getParseRange().fullString()); + + ArrayType at = (ArrayType) varT; + int dim = at.dimension(); + + if (proc.generateLoggedType()) out.print("Logged"); + out.print ("CspArray.makeArray("); + if (proc.generateLoggedType()) { + out.print("getSelf(), " + proc.getPrefix() + " + \"" + + dr.getIdentifier().getIdentifier() + + "\", "); + if (proc.isTopLevel()) { + out.print("\"" + + getLocation(dr.getIdentifier()) + + "\", "); + } + } + out.print ("new CspInteger[] { "); + + { + ArrayType subarray = at; + for (int j = 0; j < dim; j++) { + if (j > 0) { + subarray = (ArrayType) + subarray.getElementType(); + out.print(", "); + } + subarray.getRange().getMinExpression().accept(this); + out.print(", "); + subarray.getRange().getMaxExpression().accept(this); + } + } + + out.print(" }, "); + + final Type et = deArray(at.getElementType()); + if (proc.generateLoggedType()) processLoggedType(et); + else { + et.accept(this); + out.print(".class"); + } + + out.print (")"); + } else if (varT instanceof StructureType) { + StructureType st = (StructureType) varT; + final Pair p = + (Pair) resolver.getResolvedStructures().get(st); + assert p != null; + if (init == null && st.isConst()) { + // no initializer present for a const declarator + throw new VisitorException( + "Missing initializer for const variable."); + } else { + // a non-constant declarator + out.print("new "); + final StructureDeclaration decl = + (StructureDeclaration) p.getSecond(); + processIdentifier( + (proc.generateLoggedType() ? "Logged" : "") + + decl.getName() + "_" + labels.getLabel(decl)); + out.print("("); + if (proc.generateLoggedType()) { + out.print(proc.getPrefix() + " + \"" + + dr.getIdentifier().getIdentifier() + + "\""); + if (proc.isTopLevel()) { + out.print(", \"" + + getLocation(dr.getIdentifier()) + + "\""); + } + out.print(init == null ? "" : ", "); + } + if (init != null) init.accept(this); + out.print(")"); + } + } + + // Semicolon terminates declaration + out.print(proc.getInitPostamble()); + } + + out.print(proc.getTerminator()); + } + } + + /** Print a newline, only the first time, to get off "Applying models ." */ + private void ensureNewline() { + if (!didNewline) { + errorWriter.println(); + didNewline = true; + } + } + + /** Pretty-print an error message to errorWriter */ + private void prettyMessage(String message, ParseRange pr) { + ensureNewline(); + ExceptionPrettyPrinter.prettyMessage(message, pr.start.filename, + pr.start.line, pr.start.column+1, + errorWriter); + } + + /** + * Generate declarations for undeclared variables. + **/ + private void declareUndeclared(VariableAnalyzer.Results r) + throws VisitorException { + Map m = r.getUndeclaredTypes(); + for (final Iterator i = m.keySet().iterator(); i.hasNext(); ) { + String name = (String) i.next(); + Type type = (Type) m.get(name); + + if (type == null + || type instanceof IntegerType + || type instanceof BooleanType) { + final DeclaratorList dlist = new DeclaratorList(); + dlist.addDeclarator( + new Declarator(new IdentifierExpression(name), type, null)); + processDeclaration(new Declaration(dlist), false, + new TopLevelDeclaratorProcessor()); + } else { + errorWriter.flush(); + warningWriter.flush(); + throw new VisitorException + ("Undeclared variable has unsupported type."); + } + } + } + + /** + * Inspect the sets of uninitialized variables returned by variable + * analysis. + **/ + private void processResults(VariableAnalyzer.Results r) + throws VisitorException { + identUsed.addAll(r.getUsedIdentifiers()); + analysisResults = r; + } + + public void visitChannelType(com.avlsi.csp.ast.ChannelType t) + throws VisitorException { + throw new AssertionError("Declarations of channels not supported."); + } + + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + throw new AssertionError("Declarations of channels not supported."); + } + + public void visitNodeType(com.avlsi.csp.ast.NodeType t) + throws VisitorException { + out.print("CspNode"); + } + + + public void visitArrayType(ArrayType t) + throws VisitorException { + out.print("CspArray"); + } + + public void visitIntegerType(IntegerType t) + throws VisitorException { + // XXX: ignore t.isConst(), handling of constants is broken + out.print("CspInteger"); + } + + public void visitBooleanType(BooleanType t) + throws VisitorException { + // XXX: ignore t.isConst(), handling of constants is broken + out.print("CspInteger"); + } + + public void visitStringType(StringType t) throws VisitorException { + out.print("CspString"); + } + + public void visitStructureType(StructureType t) + throws VisitorException { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + assert p != null; + final StructureDeclaration decl = (StructureDeclaration) p.getSecond(); + processIdentifier(decl.getName() + "_" + labels.getLabel(decl)); + } + + public void visitIdentifierList(IdentifierList il) + throws VisitorException { + + // Note that this is not called when the identifier list is contained + // in a VarStatement DeclarationList. + + Iterator i = il.getIdentifiers(); + + if (!i.hasNext()) { + throw new VisitorException ("IdentifierList is empty."); + } + + while (i.hasNext()) { + final IdentifierExpression id = (IdentifierExpression) i.next(); + id.accept(this); + if (i.hasNext()) { + out.print(", "); + } + } + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + throw new VisitorException("should never be called"); + } + + void setOutputWriter(final PrintWriter out) { + this.out = out; + } + + PrintWriter getOutputWriter() { + return out; + } + + /** + * Emits static declarations for top-level constants. + *

    Hack hack hack. + **/ + private static class ConstantDeclarationEmitter extends JavaEmitter { + public ConstantDeclarationEmitter(final String packageName, + final String className, + final CSPCellInfo cellInfo, + final PrintWriter out, + final PrintWriter warningWriter, + final PrintWriter errorWriter, + final PrintWriter debugWriter, + final boolean emitCoverageProbes, + final boolean disableDftHandler, + final VariableAnalyzer.Results analysisResults) { + super(packageName, className, cellInfo, out, warningWriter, + errorWriter, debugWriter, emitCoverageProbes, false, false, + disableDftHandler, false); + this.analysisResults = analysisResults; + } + + void declarationModifierHook() { + out.print("static final "); + } + + void sequentialStatementBeginScopeHook() { + // do nothing + } + + void sequentialStatementEndScopeHook() { + // do nothing + } + + public void visitAssignmentStatement(AssignmentStatement s) { + // do nothing + } + + boolean useLoggedType() { return false; } + } + + /** + * Emits static initializations for top-level constants. + *

    Hack hack hack. + **/ + private static class ConstantInitializerEmitter extends JavaEmitter { + private static final int MAX_ASSIGNMENT_PER_FUNCTION = 100; + private int assignCount; + private int funcCount; + public ConstantInitializerEmitter(final String packageName, + final String className, + final CSPCellInfo cellInfo, + final PrintWriter out, + final PrintWriter warningWriter, + final PrintWriter errorWriter, + final PrintWriter debugWriter, + final boolean emitCoverageProbes, + final boolean disableDftHandler, + final VariableAnalyzer.Results analysisResults) { + super(packageName, className, cellInfo, out, warningWriter, + errorWriter, debugWriter, emitCoverageProbes, false, false, + disableDftHandler, false); + this.analysisResults = analysisResults; + this.assignCount = 0; + } + + public void visitVarStatement(VarStatement s) { + // do nothing + } + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + if (assignCount == 0) { + final String name = "StaticInitializer_" + funcCount; + out.println("private static class " + name + " {"); + out.println("public static void init() {"); + ++funcCount; + } + super.visitAssignmentStatement(s); + ++assignCount; + if (assignCount > MAX_ASSIGNMENT_PER_FUNCTION) { + out.println("}"); + out.println("}"); + assignCount = 0; + } + } + public void done() { + if (assignCount != 0) { + out.println("}"); + out.println("}"); + } + out.println("private static void staticInitializer() {"); + for (int i = 0; i < funcCount; ++i) { + out.println("StaticInitializer_" + i + ".init();"); + } + out.println("}"); + } + + void sequentialStatementBeginScopeHook() { } + + void sequentialStatementEndScopeHook() { } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/NoCSPBlockException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/NoCSPBlockException.java new file mode 100644 index 0000000000..264c9043ba --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/NoCSPBlockException.java @@ -0,0 +1,23 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id: //depot/sw/cad/java/main/src/com/avlsi/csp/csp2java/SemanticException.java#2 $ + * $DateTime: 2002/02/23 11:33:05 $ + * $Author: chrisb $ + */ + +package com.avlsi.csp.csp2java; + +/** + * Exception thrown if cell has no csp block. + * + * @author Kim Wallmark + * @version $Revision: #2 $ $Date: 2002/02/23 $ + **/ +public class NoCSPBlockException extends SemanticException { + /** + * Class constructor. + **/ + public NoCSPBlockException() { + super("No CSP block found"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SemanticException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SemanticException.java new file mode 100644 index 0000000000..6c41ed5923 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SemanticException.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java; + +/** + * Exception thrown in case of semantic error with CSP. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SemanticException extends Exception { + /** + * Class constructor. + **/ + public SemanticException(final String message) { + super(message); + } + + public SemanticException(final String message, Throwable cause) { + super(message, cause); + } + + public SemanticException(Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolRedefinedException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolRedefinedException.java new file mode 100644 index 0000000000..1a8d47f323 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolRedefinedException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java; + +/** + * Exception thrown by SymbolTable.insert if the symbol + * is not defined. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SymbolRedefinedException extends Exception { + /** + * Class constructor. + **/ + public SymbolRedefinedException(final String message) { + super(message); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolTable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolTable.java new file mode 100644 index 0000000000..d922293de6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolTable.java @@ -0,0 +1,199 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2java; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import com.avlsi.csp.ast.Type; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.UnaryFunction; + +/** + * Symbol table for csp to Java translator. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +class SymbolTable { + /** The current environment. **/ + private Environment env = new Environment(); + + /** + * Adds symbol to the current scope's environment, throwing + * SymbolRedefinedException if the symbol already + * exists in this scope. + **/ + public void insert(final String name, + final Type type, final String targetName) + throws SymbolRedefinedException { + env.insert(name, new Attribute(type, targetName)); + } + + /** + * Adds symbol to the outermost scope's environment, throwing + * SymbolRedefinedException if the symbol already + * exists in any scope. + **/ + public void insertInRootEnvironment(final String name, + final Type type, final String targetName) + throws SymbolRedefinedException { + getRootEnvironment().insert(name, new Attribute(type, targetName)); + } + + /** + * Looks up name in the symbol table. + **/ + public Attribute lookup(final String name) + throws SymbolUndefinedException { + return env.lookup(name); + } + + /** + * Begin a scope, pushing a new environment linked to the old one. + **/ + public void beginScope() { + env = new Environment(env); + } + + /** + * Pop outermost ennvironment. + **/ + public void endScope() { + env = env.getParent(); + } + + /** + * Returns an iterator of Strings of names in the current scope. + **/ + public Iterator/**/ getRootNames() { + return getRootEnvironment().getLocalNames(); + } + + /** + * Returns an iterator of Strings of names in the current scope. + **/ + public Iterator/**/ getRootAttributes() { + return getRootEnvironment().getLocalAttributes(); + } + + /** + * Returns the root environment. + **/ + private Environment getRootEnvironment() { + Environment e = env; + while (e.getParent() != null) + e = e.getParent(); + return e; + } + + /** + * Attributes of a variable: the type and its name in the + * target language. + **/ + public final class Attribute { + /** CSP type of variable. **/ + private final Type type; + /** Name for variable in target language. **/ + private final String targetName; + + public Attribute(final Type type, final String targetName) { + this.type = type; + this.targetName = targetName; + } + + /** Returns CSP type of variable. **/ + public Type getType() { + return type; + } + + /** Returns name for variable in target language. **/ + public String getTargetName() { + return targetName; + } + } + + /** + * Chained environments. + **/ + private final class Environment { + private final Environment parent; + private final Map/**/ syms; + + public Environment() { + this(null); + } + + public Environment(final Environment parent) { + this.parent = parent; + this.syms = new HashMap/**/(); + } + + public Environment getParent() { + return parent; + } + + /** + * Add name to this environment with the + * specified attributes. + **/ + public void insert(final String name, final Attribute attr) + throws SymbolRedefinedException { + if (syms.get(name) != null) + throw new SymbolRedefinedException("Symbol redefined: " + + name); + + syms.put(name, attr); + } + + /** + * Looks up name in the chained environments. + **/ + public Attribute lookup(final String name) + throws SymbolUndefinedException { + final Attribute attr = (Attribute) syms.get(name); + + if (attr != null) + return attr; + else if (parent == null) + throw new SymbolUndefinedException("Symbol undefined: " + + name); + else + return parent.lookup(name); + } + + /** + * Returns an unmodifiable iterator of Strings of names in this scope + * only. + **/ + public Iterator/**/ getLocalNames() { + return Collections.unmodifiableMap(syms).keySet().iterator(); + } + + /** + * Returns an unmodifiable iterator of Pairs of Strings of names + * from this scope and their attributes. + **/ + public Iterator/*>*/ getLocalAttributes() { + return new + MappingIterator/*, + Pair>*/ + (Collections.unmodifiableMap(syms) + .entrySet().iterator(), + new UnaryFunction/*>*/() { + public Object execute(final Object o) { + return Pair.fromMapEntry((Entry) o); + } + }); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolUndefinedException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolUndefinedException.java new file mode 100644 index 0000000000..4089cc1e21 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/SymbolUndefinedException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java; + +/** + * Exception thrown by SymbolTable.lookup if the symbol + * is not defined. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SymbolUndefinedException extends Exception { + /** + * Class constructor. + **/ + public SymbolUndefinedException(final String message) { + super(message); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.html b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.html new file mode 100644 index 0000000000..82380d6899 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.html @@ -0,0 +1,98 @@ + + CSP2Java + +

    CSP2Java: A CSP to Java translator

    + +

    Introduction

    + +

    CSP2Java generates Java cosim modules from cell behavioral + models written in CSP.

    + +

    For an introduction to CSP, see link (XXX: ref). +

    + +

    Example Usage

    + +

    Using the FULLADDER cell as an example, + let's look at the CAST:

    + +
    +define FULLADDER()(e1of2 -a,-b,-c,+s,+d) {
    +    csp {
    +        var xa, xb, xc: int;
    +        in *[a?xa,b?xb,c?xc; s!(xa+xb+xc)%2,d!(xa+xb+xc>1)] 
    +    }
    +}
    +            
    + +

    Run dsim.

    + +

    Limitations / Warts

    + +
      +
    1. Currently, CSP2Java is strictly a macro preprocessor, + having no understanding of the code being converted. + It catches syntax errors, but any type checking errors + will not be caught until the generated Java is compiled. + This may change in the future.
    2. + +
    3. The only first class objects are ints, + and arrays. Channels are not first class objects.
    4. + +
    5. ints are passed by value, + arrays by reference.
    6. + +
    7. All operations are bitwise, ie there is no + && operator. + +
    8. There is no boolean data type.
    9. + +
    10. Comments are not nestable, but should be.
    11. + +
    12. true = ~false = ~0 = -1 + +
    13. Metaparameters are unsupported until cosim supports + them.
    14. + +
    15. Macros are unsupported.
    16. + +
    17. Ability to specify wide channels in the port list as + e1of4[16] a. Currently, wide channels + must be specifed in the java block as + a(e1of4*16).
    18. +
    + +

    Requested Features

    + +
      +
    1. Array slicing, ie a[x..y].
    2. + +
    3. Produce a runtime error if more than one guard of + a deterministic selection or repetition statement is true. +
    4. + +
    5. Ability to link non-deterministic selection or + repetition statements to production rules via + LinkedArbiter class.
    6. + +
    + +

    Recently Added Features

    + +
      +
    1. Bit extraction from integers. x[n:m] + (or some other syntax) as a synonym for + (x & ((1 << (n + 1) - 1)) >> m. +
    2. + +
    3. Support for arrays of channels.
    4. + +
    5. Channels no longer must be declared in the + java block. They can be inferred from the CAST + cell port list.
    6. + +
    + + + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.package b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.package new file mode 100644 index 0000000000..08c40f97cb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/csp2java.package @@ -0,0 +1,10 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.csp.csp2java.CSP2Java +include ../resources/resources.package.inc ../resources +share/java/csp2java.jar csp2java.jar 664 +$arch/bin/csp2java.sh csp2java.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/custom.mk new file mode 100644 index 0000000000..e7db4c96e3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/custom.mk @@ -0,0 +1,6 @@ + +CURR_RESULT_FILES := $(CURR_TARGET_DIR)/csp2java.sh $(CURR_RESULT_FILES) + +$(CURR_TARGET_DIR)/csp2java.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.csp.csp2java.CSP2Java/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArray.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArray.java new file mode 100644 index 0000000000..6c6046d0f9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArray.java @@ -0,0 +1,188 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import com.avlsi.csp.csp2java.runtime.Fold.BinaryFunction; + +/** + * A class for runtime array support of any number of dimensions. The object + * being stored inside the array must have a default constructor. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class CspArray implements CspCloneableValue, Packable { + /** + * Storage for the elements in the array. + **/ + final CspValue[] ca; + + /** + * The range of the array. + **/ + final int min, max; + + /** + * Class constructor. + * + * @param min lower bound of the array + * @param max upper bound of the array + * @param elem class of the element to store inside the array + **/ + public CspArray (final CspInteger min, final CspInteger max, + final Class elem) { + + // XXX: this should throw an exception if the narrowing is invalid. + + this.min = min.intValue(); + this.max = max.intValue(); + + ca = new CspValue[this.max - this.min + 1]; + + try { + for (int i = 0; i < ca.length; ++i) + ca[i] = (CspValue) elem.newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + /** + * Get the object stored at the given index. + * + * @param index index of the element to retrieve + * @return object stored at index + **/ + public CspValue get (final CspInteger index) { + + // XXX: this should throw an exception if the narrowing is invalid. + + return ca[index.intValue() - min]; + } + + /** + * Get the object stored at the given index. If it is out of bounds, + * print a pretty error message and exit. + * + * @param index index of the element to retrieve + * @param filename source file that the error occurred in + * @param line source line number that the error occurred on + * @param column source column number that the error occurred at + * @return object stored at index + **/ + public CspValue get (final CspInteger index, String filename, + int line, int column) { + + // XXX: this should throw an exception if the narrowing is invalid. + try { + return ca[index.intValue() - min]; + } catch (ArrayIndexOutOfBoundsException e) { + throw (CspArrayBoundsException) + new CspArrayBoundsException(index, min, max, filename, line, + column).initCause(e); + } + } + + public void setValue(final CspValue v) { + final CspArray array = (CspArray) v; + for (int i = 0; i < ca.length; ++i) { + ca[i].setValue(array.ca[i]); + } + } + + public void setValue(CspValue v, BinaryFunction modifier) { + throw new UnsupportedOperationException(); + } + + public CspCloneableValue duplicate() { + final CspValue[] dup = new CspValue[ca.length]; + for (int i = 0; i < ca.length; ++i) + dup[i] = ((CspCloneableValue) ca[i]).duplicate(); + return new CspArray(min, max, dup); + } + + public int getMinIndex() { + return min; + } + + public int getMaxIndex() { + return max; + } + + /** + * Construct an array initialized with ca. ca is + * stored as a reference, and its content is not copied. Care + * should be taken to avoid modifying it. + **/ + CspArray (final int min, final int max, final CspValue[] ca) { + assert max - min + 1 == ca.length; + this.min = min; + this.max = max; + this.ca = ca; + } + + private static CspArray makeArray(final CspInteger[] limits, + int start, final Class elem) { + if (limits.length - start == 2) { + return new CspArray(limits[start], limits[start + 1], elem); + } else { + final int min = limits[start].intValue(); + final int max = limits[start + 1].intValue(); + final int len = max - min + 1; + final CspValue[] content = new CspValue[len]; + for (int i = 0; i < len; ++i) { + content[i] = makeArray(limits, start + 2, elem); + } + return new CspArray(min, max, content); + } + } + + /** + * Construct a possibly multi-dimensional array. If the array is + * multidimensional, the result is a CspArray that contains + * CspArrays of one less dimension. + * + * @param limits bounds of the dimensions of the array; + * limits[0] and limits[1] are the lower and + * upper bound of the first dimension respectively, limits[2] + * and limits[3] are the lower and upper bound of the second + * dimension, and so on. Therefore the length of limits must be + * even. + * @param elem class of the element to store inside the array + * + * @return a CspArray with the specified dimensions, with all elements + * initialized using the default constructor of elem + **/ + public static CspArray makeArray(final CspInteger[] limits, + final Class elem) { + // assert limits.length % 2 == 0; + return makeArray(limits, 0, elem); + } + + public int pack(final CspInteger packed, int start) { + for (CspValue val : ca) { + start = ((Packable) val).pack(packed, start); + } + return start; + } + + public int unpack(final CspInteger unpacked, int start) { + for (CspValue val : ca) { + start = ((Packable) val).unpack(unpacked, start); + } + return start; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArrayBoundsException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArrayBoundsException.java new file mode 100644 index 0000000000..4195e263e9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspArrayBoundsException.java @@ -0,0 +1,17 @@ +package com.avlsi.csp.csp2java.runtime; + +public class CspArrayBoundsException extends RuntimeException { + final String filename; + final int line, column; + public CspArrayBoundsException(final CspInteger index, + final int min, + final int max, + final String filename, + final int line, + final int column) { + super("index " + index + " out of bounds " + min + ".." + max); + this.filename = filename; + this.line = line; + this.column = column; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspBoolean.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspBoolean.java new file mode 100644 index 0000000000..c00bf8ba14 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspBoolean.java @@ -0,0 +1,23 @@ +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; + +public class CspBoolean extends CspInteger implements Packable { + public CspBoolean(BigInteger val) { + super(val); + } + public int pack(CspInteger packed, int start) { + packed.assignBits(start, start, booleanValue() ? CspInteger.ONE + : CspInteger.ZERO); + return start + 1; + } + public int unpack(CspInteger packed, int start) { + CspInteger parts = packed.extractBits(start, start); + setValue(parts.equals(CspInteger.ONE) ? CspInteger.TRUE + : CspInteger.FALSE); + return start + 1; + } + public CspCloneableValue duplicate() { + return new CspBoolean(getValue()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray1.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray1.java new file mode 100644 index 0000000000..393abf5f3f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray1.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; +import com.avlsi.tools.tsim.ChannelInput; + +/* A class for runtime array support. */ + +public class CspChannelInArray1 { + final ChannelInput[] cia; + final int min, max; + final String elementTypeName; + public CspChannelInArray1 (int min, int max, + String elementTypeName, ChannelInput[] cia, int offset) { + + this.min = min; + this.max = max; + this.elementTypeName = elementTypeName; + + this.cia = new ChannelInput[this.max - this.min + 1]; + + System.arraycopy(cia, offset, this.cia, 0, this.cia.length); + } + + public CspChannelInArray1 (CspInteger min, CspInteger max, + String elementTypeName, ChannelInput[] cia, int offset) { + + // XXX: this should throw an exception if the narrowing is invalid. + + this.min = min.intValue(); + this.max = max.intValue(); + this.elementTypeName = elementTypeName; + + this.cia = new ChannelInput[this.max - this.min + 1]; + + System.arraycopy(cia, offset, this.cia, 0, this.cia.length); + } + + public ChannelInput get (final CspInteger index) { + return cia[index.intValue() - min]; + } + + public ChannelInput get (final CspInteger index, String filename, int line, + int column) { + + // XXX: this should throw an exception if the narrowing is invalid. + try { + return cia[index.intValue() - min]; + } catch (ArrayIndexOutOfBoundsException e) { + throw (CspArrayBoundsException) + new CspArrayBoundsException(index, min, max, filename, line, + column).initCause(e); + } + } + + public int getMinIndex() { + return min; + } + + public int getMaxIndex() { + return max; + } + + public String getElementTypeName() { + return elementTypeName; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray2.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray2.java new file mode 100644 index 0000000000..87f142bb0a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelInArray2.java @@ -0,0 +1,70 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import com.avlsi.tools.tsim.ChannelInput; + +/* A class for runtime array support. */ + +public class CspChannelInArray2 { + final CspChannelInArray1[] cia; + final int min, max; + public CspChannelInArray2 (int min1, int max1, int min2, int max2, + String elementTypeName, ChannelInput[] cia, int offset) { + + // XXX: this should throw an exception if the narrowing is invalid. + + int subarray_min = min2; + int subarray_max = max2; + + this.min = min1; + this.max = max1; + + this.cia = new CspChannelInArray1[this.max - this.min + 1]; + + for (int i = 0; i < this.cia.length; i++) { + this.cia[i] = new CspChannelInArray1(min2, max2, elementTypeName, + cia, offset + i * (subarray_max - subarray_min + 1)); + } + } + + public CspChannelInArray2 (final CspInteger min1, final CspInteger max1, + final CspInteger min2, final CspInteger max2, + String elementTypeName, + ChannelInput[] cia, int offset) { + + // XXX: this should throw an exception if the narrowing is invalid. + + int subarray_min = min2.intValue(); + int subarray_max = max2.intValue(); + + this.min = min1.intValue(); + this.max = max1.intValue(); + + this.cia = new CspChannelInArray1[this.max - this.min + 1]; + + for (int i = 0; i < this.cia.length; i++) { + this.cia[i] = new CspChannelInArray1(min2, max2, elementTypeName, + cia, offset + i * (subarray_max - subarray_min + 1)); + } + } + + public CspChannelInArray1 get (final CspInteger index) { + + // XXX: this should throw an exception if the narrowing is invalid. + + return cia[index.intValue() - min]; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray1.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray1.java new file mode 100644 index 0000000000..34e24b86fc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray1.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import com.avlsi.tools.tsim.ChannelOutput; + +/* A class for runtime array support. */ + +public class CspChannelOutArray1 { + final ChannelOutput[] cia; + final int min, max; + final String elementTypeName; + public CspChannelOutArray1 (int min, int max, String elementTypeName, + ChannelOutput[] cia, int offset) { + + this.min = min; + this.max = max; + this.elementTypeName = elementTypeName; + + this.cia = new ChannelOutput[this.max - this.min + 1]; + + System.arraycopy(cia, offset, this.cia, 0, this.cia.length); + } + + public CspChannelOutArray1 (final CspInteger min, final CspInteger max, + String elementTypeName, + ChannelOutput[] cia, int offset) { + + // XXX: this should throw an exception if the narrowing is invalid. + + this.min = min.intValue(); + this.max = max.intValue(); + this.elementTypeName = elementTypeName; + + this.cia = new ChannelOutput[this.max - this.min + 1]; + + System.arraycopy(cia, offset, this.cia, 0, this.cia.length); + } + + public ChannelOutput get (final CspInteger index) { + return cia[index.intValue() - min]; + } + + public ChannelOutput get (final CspInteger index, String filename, + int line, int column) { + + // XXX: this should throw an exception if the narrowing is invalid. + + try { + return cia[index.intValue() - min]; + } catch (ArrayIndexOutOfBoundsException e) { + throw (CspArrayBoundsException) + new CspArrayBoundsException(index, min, max, filename, line, + column).initCause(e); + } + } + + public int getMinIndex() { + return min; + } + + public int getMaxIndex() { + return max; + } + + public String getElementTypeName() { + return elementTypeName; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray2.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray2.java new file mode 100644 index 0000000000..0c781018d7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspChannelOutArray2.java @@ -0,0 +1,70 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import com.avlsi.tools.tsim.ChannelOutput; + +/* A class for runtime array support. */ + +public class CspChannelOutArray2 { + final CspChannelOutArray1[] cia; + final int min, max; + public CspChannelOutArray2 (int min1, int max1, int min2, int max2, + String elementTypeName, ChannelOutput[] cia, int offset) { + + // XXX: this should throw an exception if the narrowing is invalid. + + int subarray_min = min2; + int subarray_max = max2; + + this.min = min1; + this.max = max1; + + this.cia = new CspChannelOutArray1[this.max - this.min + 1]; + + for (int i = 0; i < this.cia.length; i++) { + this.cia[i] = new CspChannelOutArray1(min2, max2, elementTypeName, + cia, offset + i * (subarray_max - subarray_min + 1)); + } + } + + public CspChannelOutArray2 (final CspInteger min1, final CspInteger max1, + final CspInteger min2, final CspInteger max2, + String elementTypeName, + ChannelOutput[] cia, int offset) { + + // XXX: this should throw an exception if the narrowing is invalid. + + int subarray_min = min2.intValue(); + int subarray_max = max2.intValue(); + + this.min = min1.intValue(); + this.max = max1.intValue(); + + this.cia = new CspChannelOutArray1[this.max - this.min + 1]; + + for (int i = 0; i < this.cia.length; i++) { + this.cia[i] = new CspChannelOutArray1(min2, max2, elementTypeName, + cia, offset + i * (subarray_max - subarray_min + 1)); + } + } + + public CspChannelOutArray1 get (final CspInteger index) { + + // XXX: this should throw an exception if the narrowing is invalid. + + return cia[index.intValue() - min]; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspCloneableValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspCloneableValue.java new file mode 100644 index 0000000000..9c672f0859 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspCloneableValue.java @@ -0,0 +1,7 @@ +package com.avlsi.csp.csp2java.runtime; + +import com.avlsi.csp.csp2java.runtime.Fold.BinaryFunction; + +public interface CspCloneableValue extends CspValue { + CspCloneableValue duplicate(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspInteger.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspInteger.java new file mode 100644 index 0000000000..70a237db7e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspInteger.java @@ -0,0 +1,301 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; +import com.avlsi.csp.csp2java.runtime.Fold.BinaryFunction; +import com.avlsi.util.math.BigIntegerUtil; + +/** + * Class to represent an integer in csp. This just contains a reference to + * a BigInteger. + * + *

    I think it would be better to store the csp variables as + * BigInteger[1] and use BigInteger everywhere else, but + * this will do for now.

    + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class CspInteger implements CspCloneableValue { + /** + * A constant version that will throw an AssertionError on + * attempts to modify it. To be efficient, JavaEmitter emits + * code that use some common constants instead of constructing new + * CspInteger objects. However, if, for some reason, a CSP variable is + * assigned one of these constants, and later the variable is modified, + * then the value of these constants will also change, which is + * undesirable. This makes sure that does not happen without notice. + **/ + private static class Constant extends CspInteger { + public Constant(final BigInteger val) { + super(val); + } + protected void setValue(final BigInteger val) { + throw new AssertionError("Trying to modify CspInteger constant: " + + getValue()); + } + } + + public static final CspInteger ZERO = new Constant(BigInteger.ZERO); + public static final CspInteger ONE = new Constant(BigInteger.ONE); + public static final CspInteger FALSE = ZERO; + public static final CspInteger TRUE = new Constant(new BigInteger("-1")); + + private BigInteger val; + + public CspInteger() { + this(BigInteger.ZERO); + } + + public CspInteger(final CspInteger v) { + this(v.getValue()); + } + + public CspInteger(final BigInteger val) { + this.val = val; + } + + public CspInteger(final byte v) { + this(byteConsts[v - (int) Byte.MIN_VALUE]); + } + + public void setValue(final CspValue v) { + setValue((CspInteger) v); + } + + public void setValue(final CspInteger v) { + setValue(v.getValue()); + } + + public void setValue(CspValue v, BinaryFunction modifier) { + setValue((CspInteger) modifier.evaluate(this, v)); + } + + protected void setValue(final BigInteger val) { + this.val = val; + } + + protected BigInteger getValue() { + return val; + } + + public CspInteger add(final CspInteger v) { + return new CspInteger(getValue().add(v.getValue())); + } + + public CspInteger subtract(final CspInteger v) { + return new CspInteger(getValue().subtract(v.getValue())); + } + + public CspInteger multiply(final CspInteger v) { + return new CspInteger(getValue().multiply(v.getValue())); + } + + public CspInteger divide(final CspInteger v) { + // x / 0 == 0 + final BigInteger vval = v.getValue(); + if (vval.equals(BigInteger.ZERO)) + return new CspInteger(BigInteger.ZERO); + else + return new CspInteger(getValue().divide(vval)); + } + + public CspInteger remainder(final CspInteger v) { + // x % 0 == x + final BigInteger myVal = getValue(); + final BigInteger yourVal = v.getValue(); + if (yourVal.equals(BigInteger.ZERO)) + return new CspInteger(myVal); + else + return new CspInteger(myVal.remainder(yourVal)); + } + + public CspInteger negate() { + return new CspInteger(getValue().negate()); + } + + public CspInteger and(final CspInteger v) { + return new CspInteger(getValue().and(v.getValue())); + } + + public CspInteger or(final CspInteger v) { + return new CspInteger(getValue().or(v.getValue())); + } + + public CspInteger xor(final CspInteger v) { + return new CspInteger(getValue().xor(v.getValue())); + } + + public CspInteger not() { + return new CspInteger(getValue().not()); + } + + public CspInteger shiftLeft(final int shiftAmount) { + return new CspInteger(getValue().shiftLeft(shiftAmount)); + } + + public CspInteger shiftLeft(final CspInteger shiftAmount) { + return shiftLeft(shiftAmount.intValue()); + } + + public CspInteger shiftRight(final int shiftAmount) { + return new CspInteger(getValue().shiftRight(shiftAmount)); + } + + public CspInteger shiftRight(final CspInteger shiftAmount) { + return shiftRight(shiftAmount.intValue()); + } + + public CspInteger pow(final int exponent) { + if (exponent >= 0) + return new CspInteger(getValue().pow(exponent)); + else if (getValue().equals(BigInteger.ZERO)) + return new CspInteger(BigInteger.ZERO); + else + return new CspInteger(BigInteger.ONE.divide(getValue().pow(-exponent))); + } + + public CspInteger extractBits(final CspInteger min) { + // x[n:m] --> ((x & ((1 << (n + 1)) - 1)) >> m) where m <= n + return extractBits(min, min); + } + + public CspInteger extractBits(final CspInteger min, final CspInteger max) { + return extractBits(min.intValue(), max.intValue()); + } + + public CspInteger extractBits(final int min, final int max) { + // x[n:m] --> ((x & ((1 << (n + 1)) - 1)) >> m) where m <= n + return this.and(ONE.shiftLeft(max + 1).subtract(ONE)) + .shiftRight(min); + } + + public void assignBits(final CspInteger min, final CspInteger expr) { + assignBits(min, min, expr); + } + + public void assignBits(final CspInteger min, final CspInteger expr, + final BinaryFunction modifier) { + assignBits(min, min, expr, modifier); + } + + public void assignBits(final CspInteger min, final CspInteger max, + final CspInteger expr) { + assignBits(min.intValue(), max.intValue(), expr); + } + + public void assignBits(final int min, final int max, + final CspInteger expr) { + // x[n:m] := expr + // --> ((x & ~((1 << (n + 1)) - (1 << m))) + // | ((expr << m) & ((1 << (n + 1)) - (1 << m)))) + // where m <= n + assert (max < Integer.MAX_VALUE); + final CspInteger mask = ONE.shiftLeft(max + 1) + .subtract(ONE.shiftLeft(min)); + setValue(this.and(mask.not()) + .or(expr.shiftLeft(min).and(mask))); + } + + public void assignBits(final CspInteger min, final CspInteger max, + final CspInteger expr, + final BinaryFunction modifier) { + // x[n:m] := expr + // --> ((x & ~((1 << (n + 1)) - (1 << m))) + // | ((expr << m) & ((1 << (n + 1)) - (1 << m)))) + // where m <= n + final int minValue = min.intValue(); + final CspInteger mask = ONE.shiftLeft(max.add(ONE).intValue()) + .subtract(ONE.shiftLeft(minValue)); + final CspInteger curr = extractBits(min, max); + final CspInteger eval = (CspInteger) modifier.evaluate(curr, expr); + setValue(this.and(mask.not()) + .or(eval.shiftLeft(minValue).and(mask))); + } + + public CspInteger log2() { + return CspInteger.valueOf(BigIntegerUtil.log2(getValue())); + } + + public CspInteger log4() { + return CspInteger.valueOf(BigIntegerUtil.log4(getValue())); + } + + public int compareTo(final CspInteger v) { + return getValue().compareTo(v.getValue()); + } + + public int intValue() { + return getValue().intValue(); + } + + public long longValue() { + return getValue().longValue(); + } + + public BigInteger toBigInteger() { + return getValue(); + } + + public static CspInteger valueOf(final long val) { + return new CspInteger(BigInteger.valueOf(val)); + } + + public String toString() { + return getValue().toString(); + } + + public String toString(final int radix) { + return getValue().toString(radix); + } + + public boolean equals(final Object o) { + return o instanceof CspInteger && equals((CspInteger) o); + } + + public boolean equals(final CspInteger v) { + return v != null && getValue().equals(v.getValue()); + } + + public int bitLength() { + return getValue().bitLength(); + } + + public boolean booleanValue() { + return !this.equals(FALSE); + } + + public static CspInteger valueOf(final boolean val) { + return val ? TRUE : FALSE; + } + + public CspCloneableValue duplicate() { + return new CspInteger(getValue()); + } + + private static final BigInteger[] byteConsts; + + static { + byteConsts = new BigInteger[256]; + byte[] tmp = new byte[1]; + for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) { + BigInteger bi; + if (i == 0) { + bi = BigInteger.ZERO; + } else if (i == 1) { + bi = BigInteger.ONE; + } else { + tmp[0] = (byte) i; + bi = new BigInteger(tmp); + } + assert bi.intValue() == i; + byteConsts[i - Byte.MIN_VALUE] = bi; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspMetaParamArray1.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspMetaParamArray1.java new file mode 100644 index 0000000000..4414260114 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspMetaParamArray1.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; +import com.avlsi.fast.metaparameters.ArrayMetaParam; +import com.avlsi.fast.metaparameters.BooleanMetaParam; +import com.avlsi.fast.metaparameters.IntegerMetaParam; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; + +/* A class for runtime array support. */ + +public class CspMetaParamArray1{ + ArrayMetaParam a; + + public CspMetaParamArray1( ArrayMetaParam a ){ + this.a = a; + } + + public CspInteger get( final CspInteger index ){ + MetaParamTypeInterface m = a.get( index.intValue() ); + + if( m instanceof IntegerMetaParam ){ + return new CspInteger(((IntegerMetaParam) m).toBigInteger()); + }else if( m instanceof BooleanMetaParam ){ + boolean b = ((BooleanMetaParam) m).toBoolean(); + return (b ? new CspInteger(BigInteger.ONE) + : new CspInteger(BigInteger.ZERO)); + }else{ + throw new /* Assertion */ Error( "Invalid Meta-parameter type." ); + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNode.java new file mode 100644 index 0000000000..e3d2656d19 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNode.java @@ -0,0 +1,42 @@ +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; +import com.avlsi.tools.tsim.WideNode; + +public class CspNode extends CspInteger { + public static class UnstableException extends RuntimeException { } + + private final WideNode node; + + private CspNode(BigInteger value) { + super(value); + this.node = null; + } + + public CspNode(WideNode node) { + this.node = node; + } + + protected void setValue(final BigInteger v) { + if (node == null) super.setValue(v); + else node.setValue(v); + } + + protected BigInteger getValue() { + if (node == null) { + return super.getValue(); + } else { + final BigInteger result = node.getValue(); + if (result == null) throw new UnstableException(); + return node.isArrayed() ? result : result.negate(); + } + } + + public boolean stable() { + return node == null ? true : node.stable(); + } + + public CspCloneableValue duplicate() { + return new CspNode(getValue()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNodeArray1.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNodeArray1.java new file mode 100644 index 0000000000..394fbd7a8f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspNodeArray1.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; +import com.avlsi.csp.csp2java.runtime.Fold.BinaryFunction; +import com.avlsi.tools.tsim.WideNode; + +/* A class for runtime array support. */ +public class CspNodeArray1 implements CspValue { + private final CspArray array; + public CspNodeArray1 (CspInteger min, CspInteger max, WideNode[] nodes, + int offset) { + this(min.intValue(), max.intValue(), nodes, offset); + } + public CspNodeArray1 (int min, int max, WideNode[] nodes, int offset) { + final CspValue[] cspNodes = new CspValue[max - min + 1]; + for (int i = 0; i < cspNodes.length; ++i) { + cspNodes[i] = new CspNode(nodes[offset + i]); + } + this.array = new CspArray(min, max, cspNodes); + } + public CspNode get (final CspInteger index) { + return (CspNode) array.get(index); + } + public CspNode get (final CspInteger index, String filename, int line, + int column) { + return (CspNode) array.get(index, filename, line, column); + } + public void setValue(final CspValue v) { + array.setValue(v); + } + public void setValue(CspValue v, BinaryFunction modifier) { + throw new UnsupportedOperationException(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspRuntimeAbstractDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspRuntimeAbstractDevice.java new file mode 100644 index 0000000000..6fe1c2a6f7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspRuntimeAbstractDevice.java @@ -0,0 +1,823 @@ +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; +import java.io.File; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.TreeMap; + +import com.avlsi.tools.dsim.DSim; +import com.avlsi.tools.dsim.DSimUtil; +import com.avlsi.tools.dsim.DigitalScheduler; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.tools.dsim.Node; +import com.avlsi.tools.dsim.WakeAt; +import com.avlsi.tools.sigscan.LoggedString; +import com.avlsi.tools.sigscan.Sigscan; +import com.avlsi.tools.tsim.Arbiter; +import com.avlsi.tools.tsim.Arbiter.Alternative; +import com.avlsi.tools.tsim.Arbiter.Term; +import com.avlsi.tools.tsim.AbstractDevice; +import com.avlsi.tools.tsim.BufferedNodeChannel; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.NodeReadChannel; +import com.avlsi.tools.tsim.NodeWriteChannel; +import com.avlsi.tools.tsim.EmptyWaitSetException; +import com.avlsi.tools.tsim.Message; +import com.avlsi.tools.tsim.Statusable; +import com.avlsi.tools.tsim.Wait; +import com.avlsi.tools.tsim.Waitable; +import com.avlsi.tools.tsim.WideNode; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.math.BigIntegerUtil; +import com.avlsi.util.text.NaturalStringComparator; + +/** + * Subclass of AbstractDevice which handles arrays of channels in the + * csp2java runtime. + * + * @author David Hilvert + * @version $Name: $ $Date$ + **/ + +public abstract class CspRuntimeAbstractDevice extends AbstractDevice { + + /** Array of input channels **/ + protected final ChannelInput[] in; + + /** Array of output channels **/ + protected final ChannelOutput[] out; + + /** Array of wide nodes */ + protected final WideNode[] wideNodes; + + /** Nodes to monitor for change when waiting for an event */ + protected final Node[] nodes; + + /** The arbitration mode to use for Arbiters. **/ + protected final int arbitrationMode; + + /** Map<String, Arbiter> from arbiter name to + * Arbiter, used by nondeterministic selection statement + * code. + **/ + protected final HashMap arbiters = + new HashMap(); + + /** Handy random number generator. */ + private Random rand = new Random(1); + + /** Random number generator for use by arbiters. */ + protected final Random arbiterRandom = new Random(1); + + /** String indicating current location, for debugging */ + public volatile String whereAmI; + + /** Used to log whereAmI to SST **/ + protected LoggedString loggedWhereAmI; + + /** String indicating current channel operation, if any, for debugging */ + public volatile String currChanOp; + + /** Node transition responsible for waking me up **/ + private Node enablingNode; + + /** Number of times yield() has been called **/ + private volatile int yieldCount = 0; + + /** Maximum supported base conversion */ + private static final CspInteger MAX_BASE = + new CspInteger(new BigInteger("36")); + + /** A scale factor to apply to digital delays **/ + private float digitalTau = 1.0f; + + /** Accumulated energy in fJ **/ + private CspInteger energy = CspInteger.ZERO; + + /** + * A synchronized List of + * CspRuntimeAbstractDevice created since the last reset. + **/ + private static final List cspDevices = + Collections.synchronizedList( + new ArrayList()); + + /** + * The stack of the CSP program + **/ + private final LinkedList frames = new LinkedList(); + + /** + * Used to detect if a channel is sent or received on multiple times in one + * loop. + **/ + private MultiMap usedChannels = null; + + + /** + * Class constructor. + **/ + protected CspRuntimeAbstractDevice(String name, + ChannelInput[] in, + ChannelOutput[] out, + WideNode[] wideNodes, + boolean suppressOutput, + int arbitrationMode) { + super(name, suppressOutput); + this.in = in; + this.out = out; + this.wideNodes = wideNodes; + final HashSet/**/ uniqNodes = new HashSet/**/(); + for (int i = 0; i < wideNodes.length; ++i) { + final Node[] components = wideNodes[i].getNodes(); + for (int j = 0; j < components.length; ++j) { + uniqNodes.add(components[j]); + } + } + this.nodes = (Node[]) uniqNodes.toArray(new Node[0]); + this.arbitrationMode = arbitrationMode; + + for (int i = 0; i < in.length; ++i) setOwner(in[i]); + for (int i = 0; i < out.length; ++i) setOwner(out[i]); + + cspDevices.add(this); + } + + private void setOwner(final ChannelInput in) { + if (in instanceof NodeReadChannel) { + final ChannelInput wrapped = ((NodeReadChannel) in).unwrap(); + if (wrapped instanceof BufferedNodeChannel) { + ((BufferedNodeChannel) wrapped).setOwner(this); + } + } + } + + private void setOwner(final ChannelOutput out) { + if (out instanceof NodeWriteChannel) { + final ChannelOutput wrapped = ((NodeWriteChannel) out).unwrap(); + if (wrapped instanceof BufferedNodeChannel) { + ((BufferedNodeChannel) wrapped).setOwner(this); + } + } + } + + private void setChanOp(final Statusable chan, final String op) { + currChanOp = chan.getName() + op; + } + + private void resetChanOp() { + currChanOp = null; + } + + protected Term[] getTerm(final String deviceName, final String term, + final boolean isNegated) { + return getTerms(deviceName, new String[] { term }, isNegated); + } + + protected Term[] getTerms(final String deviceName, final String[] terms, + final boolean isNegated) { + final Term[] result = new Term[terms.length]; + final DSim dsim = DSim.get(); + for (int i = 0; i < terms.length; ++i) { + result[i] = + new Term(dsim.findOrAddNode(deviceName + "." + terms[i]), + isNegated); + } + return result; + } + + protected Term[][] flattenTerms(final Term[][][] terms) { + final Collection result = new ArrayList(); + for (int i = 0; i < terms.length; ++i) { + for (int j = 0; j < terms[i].length; ++j) { + result.add(terms[i][j]); + } + } + final Term[][] array = (Term[][]) result.toArray(new Term[0][0]); + return array; + } + + protected Term[] flattenTerms(final Term[][] terms) { + final Collection result = new ArrayList(); + for (int i = 0; i < terms.length; ++i) { + for (int j = 0; j < terms[i].length; ++j) { + result.add(terms[i][j]); + } + } + final Term[] array = (Term[]) result.toArray(new Term[0]); + return array; + } + + /** + * Display a BigInteger message to stdout. + * + * @param message Message (of type BigInteger) to send. + * @return CSP boolean true. + **/ + protected CspInteger _print(CspInteger message) { + System.out.println(getTime() + ": " + getFullname() + + ": 0x" + message.toString(16)); + return CspInteger.valueOf(-1); + } + + /** + * Display a string message to stdout. + * + * @param message Message (of type String) to send. + * @return CSP boolean true. + **/ + protected CspInteger _print(CspString message) { + System.out.println(getTime() + ": " + getFullname() + ": " + message); + return CspInteger.valueOf(-1); + } + + /** + * Display a tagged BigInteger message to stdout. + * + * @param tag Tag (of type BigInteger) associated with the message. + * @param message Message (of type BigInteger) to send. + * @return CSP boolean true. + **/ + protected CspInteger _print(CspInteger tag, CspInteger message) { + System.out.println(getTime() + ": " + getFullname() + + ": 0x" + message.toString(16) + + " (tag=0x" + tag.toString(16) + ")"); + return CspInteger.valueOf(-1); + } + + /** + * Display a tagged String message to stdout. + * + * @param tag Tag (of type BigInteger) associated with the message. + * @param message Message (of type String) to send. + * @return CSP boolean true. + **/ + protected CspInteger _print(CspInteger tag, CspString message) { + System.out.println(getTime() + ": " + getFullname() + ": " + message + + " (tag=0x" + tag.toString(16) + ")"); + return CspInteger.valueOf(-1); + } + + /** + * Waits forever, will never return normally, only by throwing + * InterruptedException. + **/ + protected static void waitForever() throws InterruptedException { + DigitalScheduler.get().waitForever(); + } + + /** + * Waits until the event queue is empty. + **/ + protected CspInteger _eventQueueIsEmpty() throws InterruptedException { + DigitalScheduler.get().waitForEmptyEventQueue(); + updateTime(DigitalScheduler.get().getTime()); + return CspInteger.valueOf(-1); + } + + /** + * Sets the DSim warn and error state. Useful for test environments. + **/ + protected void _enableDSimErrors(CspInteger enableErrors) + throws InterruptedException { + DSim.get().setWarn(enableErrors.booleanValue()); + DSim.get().setError(enableErrors.booleanValue()); + } + + /** + * Returns a random CspInteger with numBits + **/ + protected CspInteger _random(CspInteger numBits) { + return new CspInteger(new BigInteger(numBits.intValue(),rand)); + } + + /** + * Seed the random number generator. + **/ + protected CspInteger _srandom(CspInteger seed) { + rand.setSeed(seed.longValue()); + arbiterRandom.setSeed(rand.nextLong()); + return CspInteger.valueOf(-1); + } + + /** + * Picks one of two integers based on a boolean, just like + * C and Java's ?: operator. (Except without the short-circuit + * behavior. + */ + protected CspInteger _choose(CspInteger b, CspInteger t, CspInteger f) + throws InterruptedException { + return b.booleanValue() ? t : f; + } + + protected CspInteger _log2(CspInteger a) { + return a.log2(); + } + + protected CspInteger _log4(CspInteger a) { + return a.log4(); + } + + protected CspString _string(CspInteger num, CspInteger baseNum) { + final int base; + if (baseNum.compareTo(CspInteger.ONE) <= 0 || + baseNum.compareTo(MAX_BASE) > 0) { + outerr("Invalid base " + baseNum + " at " + whereAmI + ".\n"); + base = 10; + } else { + base = baseNum.intValue(); + } + return new CspString(num.toString(base)); + } + + /** Convert a CspInteger into ASCII string **/ + protected CspString _string(CspInteger num) { + return new CspString(new String(num.toBigInteger().toByteArray(), + Charset.forName("ISO-8859-1"))); + } + + /** + * Returns true if all receives can complete on all channels in the + * array in. + **/ + protected boolean probe(final CspChannelInArray1 in) { + for (int i = in.getMaxIndex(); i >= in.getMinIndex(); i--) { + final ChannelInput channel = in.get(CspInteger.valueOf(i)); + if (!probeReceive(channel)) + return false; + } + + return true; + } + + /** + * Returns true if all sends can complete on all channels in the + * array in. + **/ + protected boolean probe(final CspChannelOutArray1 out) { + for (int i = out.getMaxIndex(); i >= out.getMinIndex(); i--) { + final ChannelOutput channel = out.get(CspInteger.valueOf(i)); + if (!probeSend(channel)) + return false; + } + + return true; + } + + protected boolean probe(final ChannelInput in) { + // AbstractDevice.probeReceive(ChannelInput) passes the current + // device time to ChannelInput.probeReceive(time) + return probeReceive(in); + } + + protected boolean probe(final ChannelOutput out) { + // AbstractDevice.probeSend(ChannelOutput) passes the current + // device time to ChannelOutput.probeSend(time) + return probeSend(out); + } + + protected void send(final String cellName, final String location, + final ChannelOutput out, final BigInteger message) + throws InterruptedException { + final BigInteger numValues = out.getNumPossibleValues(); + if (message.compareTo(BigInteger.ZERO) < 0 || + message.compareTo(numValues) >= 0) { + outerr("Warning: implicit non-power-of-2 posmod is deprecated: " + + message + " outside [0.." + + (numValues.subtract(BigInteger.ONE)) + "] at " + location); + } + send(out, message); + } + + protected void send(final ChannelOutput out, BigInteger message) + throws InterruptedException { + final boolean isStatusable = out instanceof Statusable; + if (isStatusable) { + final Statusable status = (Statusable) out; + setChanOp(status, "!" + message); + if (usedChannels !=null) usedChannels.put(status, whereAmI); + } + super.send(out, message); + if (isStatusable) resetChanOp(); + } + + protected Message receive(ChannelInput in) throws InterruptedException { + final boolean isStatusable = in instanceof Statusable; + if (isStatusable) { + final Statusable status = (Statusable) in; + setChanOp(status, "?"); + if (usedChannels !=null) usedChannels.put(status, whereAmI); + } + final Message m = super.receive(in); + if (isStatusable) resetChanOp(); + return m; + } + + protected BigInteger peek(final ChannelInput in) + throws InterruptedException { + if (in instanceof Statusable) setChanOp((Statusable) in, "#?"); + in.waitForMessage(); + if (in instanceof Statusable) resetChanOp(); + // AbstractDevice.probeValue(ChannelInput) takes care of updating the time + return probeValue(in).getValue(); + } + + /** + * Uses {@link com.avlsi.tools.tsim.Wait#select()} to wait, + * but logs any EmptyWaitSetExceptions with outerr(). + **/ + public /*@ non_null @*/ Pair/**/ select2( + final /*@ non_null @*/ Wait wait) + throws InterruptedException { + try { + return wait.select2(); + } catch (EmptyWaitSetException e) { + outerr("Empty wait set -- You have a [] whose guards never " + + "become true"); + throw e; + } + } + + protected void cleanup() { + for (int i = 0; i < in.length; ++i) { + in[i].destroy(); + in[i]=null; + } + for (int i = 0; i < out.length; ++i) { + out[i].destroy(); + out[i]=null; + } + for (Arbiter arb : arbiters.values()) { + arb.destroy(); + } + arbiters.clear(); + } + + /** + * Wait for the specified number of digital cycles. + **/ + protected void _wait(final CspInteger delay) throws InterruptedException { + wait(Math.round(delay.intValue() * digitalTau)); + } + + protected void yield() throws InterruptedException { + ++yieldCount; + wait(0); + } + + public int getYieldCount() { + return yieldCount; + } + + public void resetYieldCount() { + yieldCount = 0; + } + + public synchronized Node getEnablingNode() { + return enablingNode; + } + + public synchronized void setEnablingNode(final Node node) { + enablingNode = node; + } + + protected Node[] getNodesWithDifferentValue(boolean on) { + final Collection result = new ArrayList(); + for (int i = 0; i < nodes.length; ++i) { + if (nodes[i].getValue() != (on ? Node.VALUE_1 : Node.VALUE_0)) + result.add(nodes[i]); + } + return (Node[]) result.toArray(new Node[0]); + } + + protected CspInteger _stable(CspNode node) throws InterruptedException { + return CspInteger.valueOf(node.stable() ? -1 : 0); + } + + /** + * Return the current device time. + **/ + protected CspInteger _time() throws InterruptedException { + return CspInteger.valueOf(getTime()); + } + + /** + * Accumulate energy. + * + * @param val energy in fJ + **/ + protected void _energy(CspInteger val) { + energy = energy.add(val); + } + + /** + * Reset energy accumulator. + **/ + public void resetEnergy() { + energy = CspInteger.ZERO; + } + + /** + * Return energy in J. + **/ + public double getEnergy() { + return energy.toBigInteger().doubleValue() * 1e-15; + } + + /** + * A function to be run while ~_RESET. By default it does nothing. It + * will be overriden if there is a CSP function called resetNodes(). + **/ + protected void resetNodes() throws InterruptedException { } + + protected void waitForReset() throws InterruptedException { + Node resetNode = DSimUtil.getResetNode(); + if (resetNode == null) { + synchronized(warnLock) { + if (!outWarn) { + System.err.println("Warning: No reset node was found."); + outWarn = true; + } + } + return; + } + + Wait wait; + + wait = new Wait(null, null, null, new Node[]{resetNode}); + wait.select(); + + try { + resetNodes(); + } catch (CspNode.UnstableException e) { + printUnstableException(); + } + + wait = new Wait(null, null, new Node[]{resetNode}, null); + wait.select(); + new WakeAt(DSim.get().getTime() + 00, this).sleepTil(); + + return; + } + + protected void printUnstableException() { + outerr("Reading from an unstable node at " + whereAmI + ".\n" + + "Use [ stable(node) ] to ensure a node is stable before " + + "reading from it."); + } + + public static List getAllCspDevices() { + return Collections.unmodifiableList(cspDevices); + } + + public static void clearAllCspDevices() { + cspDevices.clear(); + } + + public Collection getInputChannels() { + return Collections.unmodifiableList(Arrays.asList(in)); + } + + public Collection getOutputChannels() { + return Collections.unmodifiableList(Arrays.asList(out)); + } + + protected void handleError(final String cellName, final String filename, + final int line, final int column) { + outerr("Runtime error detected in " + cellName + " at " + + filename + ":" + line + ":" + column); + if (DSim.get().haltOnError) { + DSim.get().interrupt(); + } + } + + protected void handleAssert(final String whereAmI, final CspInteger expr, + final CspString mesg) { + if (!expr.booleanValue()) { + outerr("Assertion failed at " + whereAmI + + (mesg == null ? "" : ": " + mesg.toString())); + if (DSim.get().haltOnError) { + DSim.get().interrupt(); + } + } + } + + protected void setDigitalTau(final float digitalTau) { + this.digitalTau = digitalTau; + } + + protected CspRuntimeAbstractDevice getSelf() { + return this; + } + + protected String getLoggingScope() { + StringBuilder buf = new StringBuilder(); + buf.append(getFullname()); + for (StackFrame frame : + CollectionUtils.iterable(frames.descendingIterator())) { + String funcName = frame.getFunctionName(); + if (funcName != null) { + buf.append('.'); + buf.append(funcName); + } + } + return buf.toString(); + } + + protected void enterFrame(final String funcName) { + frames.addFirst(new StackFrame(funcName, whereAmI)); + } + + protected void leaveFrame() { + frames.removeFirst(); + } + + public Collection getFrames() { + return Collections.unmodifiableList(frames); + } + + /** + * Returns the top frame in the stack, or null if the stack is + * empty. The stack may be empty if the device has not started the go() + * method, or if it exited the go() method due to an exception. + **/ + public StackFrame topFrame() { + return frames.isEmpty() ? null : frames.getFirst(); + } + + protected CspInteger pack(final Packable structure) { + final CspInteger packed = new CspInteger(); + structure.pack(packed, 0); + return packed; + } + + protected void unpack(final Packable structure, final CspInteger packed) { + structure.unpack(packed, 0); + } + + public void setSigscan(final Sigscan sigscan) { + final Sigscan oldSigscan = getSigscan(); + super.setSigscan(sigscan); + final Sigscan newSigscan = getSigscan(); + if (oldSigscan != newSigscan && newSigscan != null) { + initWhereAmI(); + } + } + + protected void initWhereAmI() { + loggedWhereAmI = new LoggedString(getFullname(), "whereAmI", + getSigscan(), getDebugOpts(), true); + } + + protected void setWhereAmI(String whereAmI) { + this.whereAmI = whereAmI; + if (loggedWhereAmI != null) loggedWhereAmI.set(whereAmI, time); + } + + protected void checkAlternative(final List alts, + final CspSnoopingInterface snoop) + throws InterruptedException { + int numTrue = 0; + for (Iterator i = alts.iterator(); i.hasNext(); ) { + final Alternative alt = (Alternative) i.next(); + if (alt.getPredicate().evaluate()) numTrue++; + } + if (numTrue == 0) { + snoop.onDeadlock("No guards true in non-deterministic selection", + whereAmI); + } else if (numTrue > 1) { + snoop.onArbitrate( + "Multiple guards true in non-deterministic selection", + whereAmI); + } + } + + protected void handleBoundsException(final CspArrayBoundsException e, + final CspSnoopingInterface snoop) + throws InterruptedException { + if (snoop == null) { + final String msg = + "device " + getFullname() + ": " + e.getMessage(); + ExceptionPrettyPrinter.prettyMessage(msg, e.filename, e.line, + e.column + 1, System.err); + DSim.get().interrupt(); + waitForever(); + } else { + snoop.onOutOfBoundsAccess( + e.getMessage(), + new File(e.filename).getName() + ' ' + e.line + ':' + e.column); + } + } + + protected void arbitrate(final Arbiter arb, final String location) + throws InterruptedException { + try { + arb.arbitrate(); + } catch (EmptyWaitSetException e) { + final String context = e.getMessage(); + outerr("Empty wait set: waiting for condition " + + (context == null ? "" : "(" + context + ") ") + + "that can never become true at " + location); + DSim.get().interrupt(); + waitForever(); + } + } + + protected CspSnoopingInterface getProteusSnooper() { + return new ProteusSnooper(); + } + + private class ProteusSnooper implements CspSnoopingInterface { + private boolean firstLoop = true; + + public void onStart() { + usedChannels = new MultiMap( + new TreeMap>( + new Comparator() { + public int compare(Statusable s1, Statusable s2) { + return NaturalStringComparator.compareString( + s1.getName(), s2.getName()); + } + }), + MultiMap.arrayListFactory()); + } + + public void onOutermostLoopStart() { + if (!usedChannels.keySet().isEmpty()) { + final String err = getErrorString(firstLoop); + if (firstLoop) { + if (err.length() > 0) { + outerr("warning (synthesis): channel communication " + + "before main loop: " + err); + } + } else { + if (err.length() > 0) { + outerr("warning (synthesis): at most 1 send or " + + "receive operation allowed per channel per " + + "main loop iteration: " + err); + } + } + usedChannels.clear(); + } + firstLoop = false; + } + + public void onEnd() {} + + public void onDeadlock(String message, String whereAmI) { + outerr("warning (synthesis): deadlock detected at " + whereAmI + + ": " + message); + } + + public void onArbitrate(String message, String whereAmI) { + outerr("warning (synthesis): arbitration detected at " + whereAmI + + ": " + message); + } + + public void onOutOfBoundsAccess(String message, String whereAmI) {} + + private String getErrorString(boolean initial) { + final StringBuilder sb = new StringBuilder(); + for (Statusable s : usedChannels.keySet()) { + final Collection locs = usedChannels.get(s); + if ((initial && locs.size() > 0) || locs.size() > 1) { + sb.append(s.getName()); + sb.append(s instanceof ChannelInput ? '?' : '!'); + sb.append(" ("); + boolean first = true; + for (String loc : locs) { + if (first) { + first = false; + } else { + sb.append(", "); + } + sb.append(loc); + } + sb.append(") "); + } + } + return sb.toString(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspSnoopingInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspSnoopingInterface.java new file mode 100644 index 0000000000..6a65b2fae2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspSnoopingInterface.java @@ -0,0 +1,48 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +/** + * Programs generated with csp2java can call these methods to + * notify something else (ie csp2tt) of their progress. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface CspSnoopingInterface { + + /** + * Called when the go method starts. + **/ + void onStart(); + + /** + * Called immediately before executing the first statement in the + * outermost loop every time it is reached. + **/ + void onOutermostLoopStart(); + + /** + * Called immediately before the go method returns. + **/ + void onEnd(); + + /** + * Called when a deadlock would have occurred. + **/ + void onDeadlock(String message, String whereAmI); + + /** + * Called when arbitration would have been required. + **/ + void onArbitrate(String message, String whereAmI); + + /** + * Called on out of bounds array access. + **/ + void onOutOfBoundsAccess(String message, String whereAmI); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspString.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspString.java new file mode 100644 index 0000000000..61b312c25d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspString.java @@ -0,0 +1,52 @@ +package com.avlsi.csp.csp2java.runtime; + +import com.avlsi.csp.csp2java.runtime.Fold.BinaryFunction; + +public class CspString implements CspCloneableValue { + private String val; + + public CspString() { + this(""); + } + + public CspString(final String val) { + assert val != null; + this.val = val; + } + + public void setValue(CspValue v) { + setValue((CspString) v); + } + + public void setValue(CspString v) { + this.val = v.val; + } + + public void setValue(CspValue v, BinaryFunction modifier) { + setValue((CspString) modifier.evaluate(this, v)); + } + + public CspString add(final CspString s) { + return new CspString(val + s.val); + } + + public String toString() { + return val; + } + + public boolean equals(final CspString s) { + return val.equals(s.val); + } + + public boolean equals(final Object o) { + return o instanceof CspString && equals((CspString) o); + } + + public int hashCode() { + return val.hashCode(); + } + + public CspCloneableValue duplicate() { + return new CspString(val); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspStructure.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspStructure.java new file mode 100644 index 0000000000..bce09501d2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspStructure.java @@ -0,0 +1,6 @@ +package com.avlsi.csp.csp2java.runtime; + +/** + * A tagging interface used to identify user defined CSP structures. + **/ +public interface CspStructure extends Packable {} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspValue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspValue.java new file mode 100644 index 0000000000..72cef45011 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/CspValue.java @@ -0,0 +1,8 @@ +package com.avlsi.csp.csp2java.runtime; + +import com.avlsi.csp.csp2java.runtime.Fold.BinaryFunction; + +public interface CspValue { + void setValue(CspValue value); + void setValue(CspValue value, BinaryFunction modifier); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/FiniteCspInteger.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/FiniteCspInteger.java new file mode 100644 index 0000000000..e7992b295d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/FiniteCspInteger.java @@ -0,0 +1,46 @@ +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; + +import com.avlsi.tools.sigscan.Sigscan; +import com.avlsi.util.math.BigIntegerUtil; + +public class FiniteCspInteger extends CspInteger implements Packable { + private final int width; + private final boolean isSigned; + public FiniteCspInteger(int width, boolean isSigned) { + this(BigInteger.ZERO, width, isSigned); + } + public FiniteCspInteger(BigInteger val, int width, boolean isSigned) { + super(BigIntegerUtil.truncate(val, width, isSigned)); + this.width = width; + this.isSigned = isSigned; + } + public FiniteCspInteger(int width, boolean isSigned, CspInteger val) { + this(val.toBigInteger(), width, isSigned); + } + public int pack(CspInteger packed, int start) { + packed.assignBits(start, start + width - 1, + new CspInteger(BigIntegerUtil.truncate(toBigInteger(), width))); + return start + width; + } + public int unpack(CspInteger packed, int start) { + setValue(packed.extractBits(start, start + width - 1)); + return start + width; + } + public CspCloneableValue duplicate() { + return new FiniteCspInteger(getValue(), width, isSigned); + } + protected void setValue(final BigInteger val) { + super.setValue(BigIntegerUtil.truncate(val, width, isSigned)); + } + public byte[] getLogicArray() { + final byte[] result = new byte[width]; + final BigInteger val = getValue(); + for (int i = 0, j = width - 1; i < width; ++i, --j) { + result[j] = (byte) (val.testBit(i) ? Sigscan.LOGIC1 + : Sigscan.LOGIC0); + } + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Fold.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Fold.java new file mode 100644 index 0000000000..acdc3f019d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Fold.java @@ -0,0 +1,139 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; + +public abstract class Fold { + public static final BinaryFunction ADD_FUNCTION = + new AddFunction(); + public static final BinaryFunction SUBTRACT_FUNCTION = + new SubtractFunction(); + public static final BinaryFunction AND_FUNCTION = + new AndFunction(); + public static final BinaryFunction OR_FUNCTION = + new OrFunction(); + public static final BinaryFunction XOR_FUNCTION = + new XorFunction(); + public static final BinaryFunction MULTIPLY_FUNCTION = + new MultiplyFunction(); + public static final BinaryFunction DIVIDE_FUNCTION = + new DivideFunction(); + public static final BinaryFunction REMAINDER_FUNCTION = + new RemainderFunction(); + public static final BinaryFunction LEFTSHIFT_FUNCTION = + new LeftShiftFunction(); + public static final BinaryFunction RIGHTSHIFT_FUNCTION = + new RightShiftFunction(); + + public interface BinaryFunction { + CspValue evaluate(CspValue a1, CspValue a2); + } + + private static class AddFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + if (a1 instanceof CspString && a2 instanceof CspString) { + return ((CspString) a1).add((CspString) a2); + } else { + return ((CspInteger) a1).add((CspInteger) a2); + } + } + } + private static class SubtractFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).subtract((CspInteger) a2); + } + } + private static class AndFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).and((CspInteger) a2); + } + } + private static class OrFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).or((CspInteger) a2); + } + } + private static class XorFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).xor((CspInteger) a2); + } + } + private static class MultiplyFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).multiply((CspInteger) a2); + } + } + private static class DivideFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).divide((CspInteger) a2); + } + } + private static class RemainderFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).remainder((CspInteger) a2); + } + } + private static class LeftShiftFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).shiftLeft((CspInteger) a2); + } + } + private static class RightShiftFunction implements BinaryFunction { + public CspValue evaluate(CspValue a1, CspValue a2) { + return ((CspInteger) a1).shiftRight((CspInteger) a2); + } + } + + public abstract CspValue evaluate(CspInteger i) + throws InterruptedException; + + public CspValue fold(CspValue unit, BinaryFunction f, + CspInteger min, CspInteger max) + throws InterruptedException { + CspValue v = unit; + for (CspInteger i = min; i.compareTo(max) <= 0; + i = i.add(new CspInteger(BigInteger.ONE))) { + v = f.evaluate(v, evaluate(i)); + } + return v; + } + + public static void main(String[] args) throws InterruptedException { + System.err.println( + new Fold() { + public CspValue evaluate(final CspInteger i0) + throws InterruptedException { + return new Fold() { + public CspValue evaluate(final CspInteger i1) + throws InterruptedException { + // System.err.println("multiplying " + i0 + " * " + i1); + return i0.multiply(i1); + } + }.fold(new CspInteger(BigInteger.ZERO), ADD_FUNCTION, + new CspInteger(BigInteger.ZERO), + new CspInteger(new BigInteger("10"))); + } + }.fold(new CspInteger(BigInteger.ZERO), ADD_FUNCTION, + new CspInteger(BigInteger.ZERO), + new CspInteger(new BigInteger("5"))) + ); + + int n = 0; + for (int i = 0; i <= 5; ++i) + for (int j = 0; j <= 10; ++j) + n += i * j; + System.err.println(n); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LinkageHelper.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LinkageHelper.java new file mode 100644 index 0000000000..dd24fa87b3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LinkageHelper.java @@ -0,0 +1,36 @@ +package com.avlsi.csp.csp2java.runtime; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collection; + +import com.avlsi.tools.tsim.Arbiter.Term; + +public class LinkageHelper { + public static abstract class NeutralityUnroller { + public abstract Term[] evaluate(final CspInteger i) + throws InterruptedException; + public Term[] unroll(final CspInteger min, final CspInteger max) + throws InterruptedException { + final Collection result = new ArrayList(); + for (CspInteger i = min; i.compareTo(max) <= 0; + i = i.add(CspInteger.ONE)) { + result.addAll(Arrays.asList(evaluate(i))); + } + return (Term[]) result.toArray(new Term[0]); + } + } + public static abstract class GuardUnroller { + public abstract Term[][] evaluate(final CspInteger i) + throws InterruptedException; + public Term[][] unroll(final CspInteger min, final CspInteger max) + throws InterruptedException { + final Collection result = new ArrayList(); + for (CspInteger i = min; i.compareTo(max) <= 0; + i = i.add(CspInteger.ONE)) { + result.addAll(Arrays.asList(evaluate(i))); + } + return (Term[][]) result.toArray(new Term[0][0]); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LoggedCspArray.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LoggedCspArray.java new file mode 100644 index 0000000000..66917ca385 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/LoggedCspArray.java @@ -0,0 +1,153 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2java.runtime; + +import java.lang.reflect.Constructor; + +/** + * A class for runtime logged array support of any number of dimensions. The + * object being stored inside the array should be another logged data type. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class LoggedCspArray extends CspArray { + public interface ElementConstructor { + CspValue create(CspRuntimeAbstractDevice parent, String varName); + } + + private static class ReflectionConstructor implements ElementConstructor { + private final Class elem; + public ReflectionConstructor(final Class elem) { + this.elem = elem; + } + public CspValue create(CspRuntimeAbstractDevice parent, + String varName) { + try { + final Constructor ctor = + elem.getConstructor( + new Class[] { parent.getClass(), + String.class } ); + return (CspValue) ctor.newInstance( + new Object[] { parent, varName }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + /** + * Class constructor. + * + * @param varName name of the array + * @param min lower bound of the array + * @param max upper bound of the array + * @param ec an ElementConstructor used to construct elements stored inside + * the array + **/ + public LoggedCspArray (final CspRuntimeAbstractDevice parent, + final String varName, final CspInteger min, + final CspInteger max, final ElementConstructor ec) { + super(min.intValue(), max.intValue(), + getArray(parent, varName, min.intValue(), max.intValue(), ec)); + } + + private static CspValue[] getArray(final CspRuntimeAbstractDevice parent, + final String varName, + final int min, + final int max, + final ElementConstructor ec) { + final CspValue[] ca = new CspValue[max - min + 1]; + for (int i = 0; i < ca.length; ++i) + ca[i] = ec.create(parent, varName + "[" + (i + min) + "]" ); + return ca; + } + + private static CspArray makeArray(final CspRuntimeAbstractDevice parent, + final String varName, + final CspInteger[] limits, + final int start, + final ElementConstructor ec) { + if (limits.length - start == 2) { + return new LoggedCspArray(parent, varName, limits[start], + limits[start + 1], ec); + } else { + final int min = limits[start].intValue(); + final int max = limits[start + 1].intValue(); + final int len = max - min + 1; + final CspValue[] content = new CspValue[len]; + for (int i = 0; i < len; ++i) { + content[i] = makeArray(parent, varName + "[" + (i + min) + "]", + limits, start + 2, ec); + } + return new CspArray(min, max, content); + } + } + + /** + * Construct a possibly multi-dimensional array. If the array is + * multidimensional, the result is a CspArray that contains + * CspArrays of one less dimension. + * + * @param parent the csp device that contains this array + * + * @param varName name of the array + * + * @param limits bounds of the dimensions of the array; + * limits[0] and limits[1] are the lower and + * upper bound of the first dimension respectively, limits[2] + * and limits[3] are the lower and upper bound of the second + * dimension, and so on. Therefore the length of limits must be + * even. + * @param ec an ElementConstructor used to construct elements stored inside + * the array + * + * @return a CspArray with the specified dimensions, with all elements + * initialized using the default constructor of elem + **/ + public static CspArray makeArray(final CspRuntimeAbstractDevice parent, + final String varName, + final CspInteger[] limits, + final ElementConstructor ec) { + // assert limits.length % 2 == 0; + return makeArray(parent, varName, limits, 0, ec); + } + + public static CspArray makeArray(final CspRuntimeAbstractDevice parent, + final String varName, + final CspInteger[] limits, + final Class elem) { + return makeArray(parent, varName, limits, + new ReflectionConstructor(elem)); + } + + public static CspArray makeArray(final CspRuntimeAbstractDevice parent, + final String varName, + final String parsePos, + final CspInteger[] limits, + final Class elem) { + return makeArray(parent, varName, parsePos, limits, + new ReflectionConstructor(elem)); + } + + public static CspArray makeArray(final CspRuntimeAbstractDevice parent, + final String varName, + final String parsePos, + final CspInteger[] limits, + final ElementConstructor ec) { + final CspArray result = makeArray(parent, varName, limits, ec); + parent.topFrame().addVariable(varName, parsePos, result); + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/NonDeterminismException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/NonDeterminismException.java new file mode 100644 index 0000000000..4cae822239 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/NonDeterminismException.java @@ -0,0 +1,17 @@ +package com.avlsi.csp.csp2java.runtime; + +/** + * Exception thrown by CSP runtime if non-determinism occurs in a deterministic + * statement. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class NonDeterminismException extends RuntimeException { + /** + * Class constructor. + **/ + public NonDeterminismException(final String message) { + super(message); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Packable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Packable.java new file mode 100644 index 0000000000..12544f8c08 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/Packable.java @@ -0,0 +1,6 @@ +package com.avlsi.csp.csp2java.runtime; + +public interface Packable { + int pack(CspInteger packed, int start); + int unpack(CspInteger packed, int start); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/ShadowCspInteger.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/ShadowCspInteger.java new file mode 100644 index 0000000000..5cfdcbff63 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/ShadowCspInteger.java @@ -0,0 +1,59 @@ +package com.avlsi.csp.csp2java.runtime; + +import java.math.BigInteger; + +public class ShadowCspInteger { + public static class Simple extends CspInteger { + private final CspInteger formal; + private final CspInteger actual; + public Simple(final CspInteger actual) { + this(new CspInteger(), actual); + } + public Simple(final int width, final boolean isSigned, + final CspInteger actual) { + this(new FiniteCspInteger(width, isSigned), actual); + } + public Simple(final CspInteger formal, final CspInteger actual) { + this.formal = formal; + this.actual = actual; + formal.setValue(actual.getValue()); + } + protected void setValue(final BigInteger val) { + formal.setValue(val); + actual.setValue(formal); + } + protected BigInteger getValue() { + return formal.getValue(); + } + } + + public static class BitRange extends CspInteger { + private final CspInteger min, max; + private final CspInteger formal; + private final CspInteger actual; + public BitRange(final CspInteger min, final CspInteger max, + final CspInteger actual) { + this(new CspInteger(), min, max, actual); + } + public BitRange(final int width, final boolean isSigned, + final CspInteger min, final CspInteger max, + final CspInteger actual) { + this(new FiniteCspInteger(width, isSigned), min, max, actual); + } + private BitRange(final CspInteger formal, final CspInteger min, + final CspInteger max, final CspInteger actual) { + this.formal = formal; + this.actual = actual; + this.min = min; + this.max = max; + formal.setValue(actual.extractBits(min, max)); + } + protected void setValue(final BigInteger val) { + formal.setValue(val); + actual.assignBits(min, max, formal); + } + protected BigInteger getValue() { + return formal.getValue(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/StackFrame.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/StackFrame.java new file mode 100644 index 0000000000..933f38b66a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/StackFrame.java @@ -0,0 +1,32 @@ +package com.avlsi.csp.csp2java.runtime; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.util.container.Pair; + +public class StackFrame { + private final String funcName; + private final String callLocation; + private final Map> variables; + public StackFrame(final String funcName, final String callLocation) { + this.funcName = funcName; + this.callLocation = callLocation; + this.variables = + new HashMap>(); + } + public void addVariable(final String name, final String ppos, + final CspValue val) { + variables.put(name, new Pair(ppos, val)); + } + public String getCallLocation() { + return callLocation; + } + public String getFunctionName() { + return funcName; + } + public Map> getVariables() { + return Collections.unmodifiableMap(variables); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/cspruntime.package.inc b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/cspruntime.package.inc new file mode 100644 index 0000000000..b7d5fac68e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2java/runtime/cspruntime.package.inc @@ -0,0 +1,27 @@ +2 0 +java com.avlsi.csp.csp2java.runtime.CspArray +java com.avlsi.csp.csp2java.runtime.CspArrayBoundsException +java com.avlsi.csp.csp2java.runtime.CspBoolean +java com.avlsi.csp.csp2java.runtime.CspChannelInArray1 +java com.avlsi.csp.csp2java.runtime.CspChannelInArray2 +java com.avlsi.csp.csp2java.runtime.CspChannelOutArray1 +java com.avlsi.csp.csp2java.runtime.CspChannelOutArray2 +java com.avlsi.csp.csp2java.runtime.CspCloneableValue +java com.avlsi.csp.csp2java.runtime.CspInteger +java com.avlsi.csp.csp2java.runtime.CspMetaParamArray1 +java com.avlsi.csp.csp2java.runtime.CspNode +java com.avlsi.csp.csp2java.runtime.CspNodeArray1 +java com.avlsi.csp.csp2java.runtime.CspRuntimeAbstractDevice +java com.avlsi.csp.csp2java.runtime.CspSnoopingInterface +java com.avlsi.csp.csp2java.runtime.CspString +java com.avlsi.csp.csp2java.runtime.CspStructure +java com.avlsi.csp.csp2java.runtime.CspValue +java com.avlsi.csp.csp2java.runtime.FiniteCspInteger +java com.avlsi.csp.csp2java.runtime.Fold +java com.avlsi.csp.csp2java.runtime.LoggedCspArray +java com.avlsi.csp.csp2java.runtime.NonDeterminismException +java com.avlsi.csp.csp2java.runtime.Packable +java com.avlsi.csp.csp2java.runtime.LinkageHelper +java com.avlsi.csp.csp2java.runtime.StackFrame +java com.avlsi.csp.csp2java.runtime.ShadowCspInteger +include ../../../tools/sigscan/sigscan.package.inc ../../../tools/sigscan diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/Csp2TT.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/Csp2TT.java new file mode 100644 index 0000000000..05cf3857ad --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/Csp2TT.java @@ -0,0 +1,448 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2tt; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cell.CellInterface; +import com.avlsi.csp.ast.CSPProgram; +import com.avlsi.csp.csp2java.runtime.CspSnoopingInterface; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.common.HierName; +import com.avlsi.io.CopyingOutputStream; +import com.avlsi.io.FileSearchPath; +import com.avlsi.tools.cosim.ChannelDictionary; +import com.avlsi.tools.cosim.ChannelFactoryInterface; +import com.avlsi.tools.cosim.ChannelTimingInfo; +import com.avlsi.tools.cosim.NodeFactoryInterface; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.tools.dsim.Node; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.WideNode; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.text.StringUtil; + +/** + * Generates truth table from csp program. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class Csp2TT { + + private final CellInterface cell; + + private final PrintWriter out; + + /** + * Class constructor. + * + *
    
    +     *   public normal_behavior
    +     *     requires cell != null;
    +     *     requires out != null;
    +     * 
    + **/ + public Csp2TT(CellInterface cell, PrintWriter out) { + this.cell = cell; + this.out = out; + } + + public void generateTruthTable() throws IOException { + final SnoopingChannelFactory chanFactory = + new SnoopingChannelFactory(); + final DeathNodeFactory nodeFactory = new DeathNodeFactory(); + final ChannelDictionary channelDict = + cell.getCSPCoSimInfo().createChannels(null, cell, chanFactory, + nodeFactory); + + final CSPSnooper cspSnooper = + new CSPSnooper(chanFactory.getInputChannels(), + chanFactory.getOutputChannels()); + + try { + cell.buildCSPClass(HierName.makeHierName("x"), channelDict, -1, + false, cspSnooper); + } catch (Exception e) { + System.err.println("trouble building class"); + e.printStackTrace(); + System.exit(2); + } + } + + private final class CSPSnooper implements CspSnoopingInterface { + private final List/**/ inputChannels; + private final List/**/ outputChannels; + private BigInteger index = null; + private BigInteger numInputValues = null; + private final HashSet/*>*/ warnings = + new HashSet/*>*/(); + + private CSPSnooper(final List/**/ + inputChannels, + final List/**/ + outputChannels) { + this.inputChannels = inputChannels; + this.outputChannels = outputChannels; + } + + /** + *
    
    +         *   private normal_behavior
    +         *     requires channelName != null;
    +         * 
    + **/ + private String mungeChannelName(final String channelName) { + // replace ][ with , + return StringUtil.replaceSubstring(channelName, "][", ","); + } + + /** + *
    
    +         *   private normal_behavior
    +         *     requires channelName != null;
    +         *     requires radix >= 2;
    +         *     requires width >= 1;
    +         * 
    + **/ + private void printChannelHeader(final String channelName, + final int radix, + final int width) { + if (width > 1) { + for (int i = 0; i < width; ++i) + out.print(mungeChannelName(channelName + + '[' + i + ']') + + ':' + radix + ' '); + } else { + out.print(channelName + ':' + radix + ' '); + } + } + + /** + *
    
    +         *   private normal_behavior
    +         *     requires radix >= 2;
    +         *     requires width >= 1;
    +         * 
    + **/ + private void printChannelValue(final BigInteger value, + final int radix, + final int width, + final String suffix) { + if (value == null) { + for (int i = 0; i < width; ++i) + out.print("- "); + } else { + BigInteger v = value; + final BigInteger r = BigInteger.valueOf(radix); + for (int i = 0; i < width; ++i) { + out.print(v.mod(r).toString() + suffix + ' '); + v = v.divide(r); + } + } + } + + /** + * Prints a warning that num ops were done on name, but only + * if it hasn't already printed this warning before. + * @param name the name of the channel + * @param op "send" or "receive" + * @param num number of sends or receives + */ + private void printWarning(String name, String op, int num) { + Triplet/**/ warning = + new Triplet/**/(name, op, + new Integer(num)); + if (!warnings.contains(warning)) { + warnings.add(warning); + System.err.println("warning: " + num + " " + + op + "s on " + name); + } + } + + public void onStart() { + numInputValues = BigInteger.ONE; + index = BigInteger.valueOf(-1); + + // input channels + for (Iterator i = inputChannels.iterator(); i.hasNext(); ) { + final PlayingChannelInput chan = + (PlayingChannelInput) i.next(); + final BigInteger numValues = chan.getNumPossibleValues(); + + // ouput channel name(s) for header + printChannelHeader(chan.getName(), chan.getRadix(), + chan.getWidth()); + + // update possible values + numInputValues = numInputValues.multiply(numValues); + chan.startNewCycle(BigInteger.ZERO); + } + + // input / output separator + out.print("=> "); + + // output channels + for (Iterator i = outputChannels.iterator(); i.hasNext(); ) { + final RecordingChannelOutput chan = + (RecordingChannelOutput) i.next(); + + printChannelHeader(chan.getName(), chan.getRadix(), + chan.getWidth()); + } + + out.println(); + out.flush(); + } + + public void onOutermostLoopStart() { + if (index.equals(BigInteger.valueOf(-1))) { + // check that channels have not been read or written + for (Iterator i = inputChannels.iterator(); i.hasNext(); ) { + final PlayingChannelInput chan = + (PlayingChannelInput) i.next(); + if (chan.getNumReceives() != 0) + System.err.println("warning: " + chan.getName() + + " read before main loop"); + } + for (Iterator i = outputChannels.iterator(); i.hasNext(); ) { + final RecordingChannelOutput chan = + (RecordingChannelOutput) i.next(); + if (chan.getNumSends() != 0) { + System.err.println("warning: " + chan.getName() + + " written before main loop"); + chan.startNewCycle(); + } + } + } else { + // input channels + for (Iterator i = inputChannels.iterator(); i.hasNext(); ) { + final PlayingChannelInput chan = + (PlayingChannelInput) i.next(); + + // check that there was at most one receive + int numReceives = chan.getNumReceives(); + if (numReceives > 1) + printWarning(chan.getName(), "receive", numReceives); + + printChannelValue(chan.getValue(), chan.getRadix(), + chan.getWidth(), + (numReceives == 0 ? "n" : "")); + } + + out.print("=> "); + + // output channels + for (Iterator i = outputChannels.iterator(); i.hasNext(); ) { + final RecordingChannelOutput chan = + (RecordingChannelOutput) i.next(); + + // check that there was at most one send + int numSends = chan.getNumSends(); + if (numSends > 1) + printWarning(chan.getName(), "send", numSends); + + printChannelValue(chan.getValue(), chan.getRadix(), + chan.getWidth(), ""); + + chan.startNewCycle(); + } + + out.println(); + } + + index = index.add(BigInteger.ONE); + BigInteger tempVal = index; + + if (index.equals(numInputValues)) { + // we are done + out.flush(); + System.exit(0); + } else { + // input channels + for (Iterator i = inputChannels.iterator(); i.hasNext(); ) { + final PlayingChannelInput chan = + (PlayingChannelInput) i.next(); + final BigInteger numValues = chan.getNumPossibleValues(); + + // set new channel value + chan.startNewCycle(tempVal.mod(numValues)); + tempVal = tempVal.divide(numValues); + } + } + + out.flush(); + } + + public void onEnd() { + // This shouldn't happen + System.err.println("onEnd"); + out.flush(); + } + + public void onDeadlock(String message, String whereAmI) { + System.err.println("error: Deadlock detected at " + whereAmI + + ": " + message); + out.flush(); + System.exit(3); + } + + public void onArbitrate(String message, String whereAmI) { + System.err.println("error: Arbitration detected at " + whereAmI + + ": " + message); + out.flush(); + System.exit(3); + } + + public void onOutOfBoundsAccess(String message, String whereAmI) { + System.err.println("error: Array out of bounds access at " + + whereAmI + ": " + message); + out.flush(); + System.exit(3); + } + } + + private static final class SnoopingChannelFactory + implements ChannelFactoryInterface { + + private final List/**/ inputChannels = + new ArrayList/**/(); + private final List/**/ outputChannels = + new ArrayList/**/(); + + public ChannelInput makeInputChannel(final String name, + final int radix, + final int width, + final ChannelTimingInfo cti) { + final ChannelInput chan = + new PlayingChannelInput(name, radix, width); + inputChannels.add(chan); + return chan; + } + + public ChannelOutput makeOutputChannel(final String name, + final int radix, + final int width, + final ChannelTimingInfo cti) { + final ChannelOutput chan = + new RecordingChannelOutput(name, radix, width); + outputChannels.add(chan); + return chan; + } + + private List/**/ getInputChannels() { + return inputChannels; + } + + private List/**/ getOutputChannels() { + return outputChannels; + } + } + + private static final class DeathNodeFactory + implements NodeFactoryInterface { + public WideNode makeWideNode(final String name, int width, + int direction, boolean isArrayed, + boolean readOnly) { + return new WideNode() { + private void die() { + System.err.println("trouble building class"); + System.err.println( + "error: cannot handle node-level operations " + + "found on node " + name + ". Did you really " + + "want to process CSP with node-level " + + "operations? See bug 6928."); + System.exit(2); + } + public BigInteger getValue() { die(); return null; } + public Node[] getNodes() { return new Node[0]; } + public boolean stable() { die(); return false; } + public void setValue(final int[] indices, + final byte[] values) { die(); } + public void setValue(final int begin, + final int end, + final BigInteger val) { die(); } + public void setValue(final BigInteger val) { die(); } + public boolean isArrayed() { die(); return false; } + }; + } + } + + private static void usage(int exitStatus) { + System.out.println("Usage: csp2tt --cast-path=cast_path" + + " [--cell=cell_name]" + + " [--version]"); + System.exit(exitStatus); + } + + public static void main(String[] args) throws Exception { + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs(argsWithConfigs); + final CommandLineArgs theArgs = cachedArgs; + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + Csp2TT.class)); + } + + final FileSearchPath castFSP = + new FileSearchPath(theArgs.getArgValue("cast-path", ".")); + + final String castCellName = theArgs.getArgValue("cell", null); + + if (castCellName == null || + theArgs.nonParsedArgumentsIterator().hasNext()) + usage(1); + + final CastFileParser cfp = new CastFileParser(castFSP, "2"); + CellInterface cell = null; + try { + cell = cfp.getFullyQualifiedCell(castCellName); + } catch (CastSemanticException e) { + ExceptionPrettyPrinter.printException(e, System.err); + System.exit(99); + } + + final PrintWriter systemOutWriter = + new PrintWriter(new OutputStreamWriter(System.out)); + + /* Now that we've captured the real stdout in systemOutWriter, + * redirect any other use of System.out (such as CSP print + * statements) so that they don't contaminate the truth + * table output. (Fixes bug 4487.) */ + + OutputStream[] none = new OutputStream[0]; + System.setOut(new PrintStream(new CopyingOutputStream(none))); + + new Csp2TT(cell, systemOutWriter).generateTruthTable(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/PlayingChannelInput.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/PlayingChannelInput.java new file mode 100644 index 0000000000..15ad835962 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/PlayingChannelInput.java @@ -0,0 +1,146 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2tt; + +import java.math.BigInteger; + +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.Message; +import com.avlsi.tools.tsim.WaiterInterface; + +/** + * ChannelInput implementation that provides a fixed value. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class PlayingChannelInput implements ChannelInput { + private BigInteger value; + private int numReceives; + private final int radix; + private final int width; + private final BigInteger numPossibleValues; + private String name; + + /** + * Class constructor. + * + *
    
    +     *   public normal_behavior
    +     *     requires radix >= 2;
    +     *     requires width >= 1;
    +     * 
    + **/ + public PlayingChannelInput(String name, int radix, int width) { + this.value = null; + this.numReceives = 0; + this.radix = radix; + this.width = width; + this.numPossibleValues = BigInteger.valueOf(radix).pow(width); + this.name = name; + } + + public long getReceiveTime() { + return 0; + } + + public long getCycleTime() { + return 0; + } + + public BigInteger getNumPossibleValues() { + return numPossibleValues; + } + + public Message receive(long deviceTime) { + numReceives++; + return new Message(value); + } + + public Message receive() { + numReceives++; + return new Message(value); + } + + /** + * Sets this.value to value mod + * numPossibleValues and clears numReceives. + **/ + public void startNewCycle(final BigInteger value) { + this.value = value.mod(numPossibleValues); + this.numReceives = 0; + } + + public BigInteger getValue() { + return value; + } + + /** + * Returns the number of calls to {@link #receive} since + * {@link #startNewCycle} was called. + * + *
    
    +     *   public normal_behavior
    +     *     ensures \result >= 0;
    +     * 
    + **/ + public int getNumReceives() { + return numReceives; + } + + public boolean probeReceive(long time) { + return true; + } + + public boolean probeReceive() { + return true; + } + + public Message probeValue() { + return new Message(value); + } + + public boolean checklessProbeReceive(long time) { + return true; + } + + public boolean checklessProbeReceive() { + return true; + } + + public void waitForMessage() { + // do nothing + } + + public void setReadWaiter(WaiterInterface waiter) { + // do nothing + } + + public void clearReadWaiter() { + // do nothing + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void destroy() { + // do nothing + } + + public int getRadix() { + return radix; + } + + public int getWidth() { + return width; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/RecordingChannelOutput.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/RecordingChannelOutput.java new file mode 100644 index 0000000000..772a0b0048 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2tt/RecordingChannelOutput.java @@ -0,0 +1,137 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.csp2tt; + +import java.math.BigInteger; + +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.Message; +import com.avlsi.tools.tsim.WaiterInterface; + +/** + * ChannelOutput implementation that records + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class RecordingChannelOutput implements ChannelOutput { + private BigInteger value; + private int numSends; + private final int radix; + private final int width; + private final BigInteger numPossibleValues; + private String name; + + /** + * Class constructor. + * + *
    
    +     *   public normal_behavior
    +     *     requires radix >= 2;
    +     *     requires width >= 1;
    +     * 
    + **/ + public RecordingChannelOutput(String name, int radix, int width) { + this.value = null; + this.numSends = 0; + this.radix = radix; + this.width = width; + this.numPossibleValues = BigInteger.valueOf(radix).pow(width); + this.name = name; + } + + public long getSendTime() { + return 0; + } + + public long getCycleTime() { + return 0; + } + + public BigInteger getNumPossibleValues() { + return numPossibleValues; + } + + public long send(Message m, long deviceTime) { + value = m.getValue(); + numSends++; + return 0; + } + + /** + * Clears value and numSends. + **/ + public void startNewCycle() { + value = null; + numSends = 0; + } + + /** + * Returns the last value sent since {@link #startNewCycle()} was + * called, or null if none. + **/ + public BigInteger getValue() { + return value != null ? value.mod(numPossibleValues) : null; + } + + /** + * Returns the number of calls to {@link #send} since + * {@link #startNewCycle()} was called. + * + *
    
    +     *   public normal_behavior
    +     *     ensures \result >= 0;
    +     * 
    + **/ + public int getNumSends() { + return numSends; + } + + public boolean probeSend(long time) { + return true; + } + + public boolean probeSend() { + return true; + } + + public boolean checklessProbeSend(long time) { + return true; + } + + public boolean checklessProbeSend() { + return true; + } + + public void setWriteWaiter(WaiterInterface waiter) { + // do nothing + } + + public void clearWriteWaiter() { + // do nothing + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void destroy() { + // do nothing + } + + public int getRadix() { + return radix; + } + + public int getWidth() { + return width; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/CommonEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/CommonEmitter.java new file mode 100644 index 0000000000..5090831330 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/CommonEmitter.java @@ -0,0 +1,237 @@ +package com.avlsi.csp.csp2verilog; + +import java.math.BigInteger; +import java.io.PrintWriter; +import java.io.Writer; + +import com.avlsi.csp.ast.*; +import com.avlsi.csp.util.CspUtils; +import com.avlsi.io.IndentPrintWriter; + +abstract class CommonEmitter implements VisitorInterface { + final LengthAwareWriter out; + + /** + * Number of bits to use for variables with unspecified length + **/ + final int registerBitWidth; + + /** + * The type of register to use for variables. + **/ + final String registerType; + + CommonEmitter(final PrintWriter out, final int registerBitWidth) { + this.out = new LengthAwareWriter(1000, out); + this.registerBitWidth = registerBitWidth; + this.registerType = "bit signed [" + (registerBitWidth - 1) + ":0]"; + } + + protected String getRegisterType(final IntegerType t) + throws VisitorException { + final boolean signed; + final int width; + if (t.getDeclaredWidth() == null) { + if (t instanceof TemporaryIntegerType && t.getInterval() != null) { + width = CspUtils.getWidth(t.getInterval(), registerBitWidth); + signed = true; + } else { + return registerType; + } + } else { + width = getIntegerConstant(t.getDeclaredWidth()); + signed = t.isSigned(); + } + return "bit " + (signed ? "signed " : "") + "[" + (width - 1) + ":0]"; + } + + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + if (e instanceof BooleanExpression) { + if (((BooleanExpression) e).booleanValue()) { + out.print("1'b1"); + } else { + out.print("1'b0"); + } + } else { + processBigInteger(new BigInteger(e.getValue(), e.getRadix()), + e.getRadix()); + } + } + + /** + * Output an integer constant as a signed expression. If radix is 2, 8, or + * 10, use the "b", "o" and "d" base specifiers respectively. Otherwise, + * output in hexdecimal. + * + * @param bi integer to output + * @param radix radix to use + **/ + void processBigInteger(BigInteger bi, final int radix) { + // all constants must be signed, because "if any operand is unsigned, + // the result is unsigned, regardless of the operator" (4.5.1) + if (bi.signum() == -1) { + // if the number is negative, prepend a negative sign, and process + // it's absolute value + bi = bi.negate(); + out.print('-'); + } + + final int width = bi.bitLength() + 1; // plus 1 for the sign bit + + out.print(width); + out.print("'s"); + if (radix == 2) + out.print("b" + bi.toString(2)); + else if (radix == 8) + out.print("o" + bi.toString(8)); + else if (radix == 10) + out.print("d" + bi.toString(10)); + else { + // write other bases in hex for no particular reason + out.print("h" + bi.toString(16)); + } + } + + // Determine if this is a simple bit range, which can be translated to + // Verilog directly + boolean needBitRangeFunction(final BitRangeExpression e) { + // If both min and max are constants, and if we are not part-selecting + // on an array element[1], then we can use Verilog's constant + // part-select. + // [1] Seems to be a ncverilog restriction, as part-selecting an array + // element is legal per the Verilog 2001 spec 4.2.2 (p. 55). + final ExpressionInterface be = e.getBitsExpression(); + if (be instanceof IdentifierExpression || + be instanceof ArrayAccessExpression || + be instanceof MemberAccessExpression) { + if (e.getMinExpression() == null) { + // bit select + return false; + } else if (e.getMaxExpression() instanceof IntegerExpression && + e.getMinExpression() instanceof IntegerExpression) { + // part select when bounds are constants + return false; + } + } + return true; + } + + // A simple bit range is one that can be translated to Verilog directly + void processSimpleBitRange(BitRangeExpression e, boolean rhs) + throws VisitorException { + if (!rhs) out.print("($signed({1'd0, "); + + final ExpressionInterface maxExpr = e.getMaxExpression(); + final ExpressionInterface minExpr = e.getMinExpression(); + e.getBitsExpression().accept(this); + out.print('['); maxExpr.accept(this); + if (minExpr != null) { + out.print(':'); minExpr.accept(this); + } + out.print(']'); + + if (!rhs) out.print("}))"); + } + + int getIntegerConstant(final ExpressionInterface e) + throws VisitorException { + if (e instanceof IntegerExpression) { + final IntegerExpression ie = (IntegerExpression) e; + return Integer.parseInt(ie.getValue(), ie.getRadix()); + } else { + throw new VisitorException( + "Compile time constant integer expression expected: " + + e.getParseRange().fullString()); + } + } + + static class LengthAwareWriter extends IndentPrintWriter { + private final int limit; + private int length = 0; + public LengthAwareWriter(final int limit, Writer out) { + super(out); + this.limit = limit; + } + public void println() { + super.println(); + length = 0; + } + public void ws() { + if (length > limit) println(); + else print(' '); + } + public void write(int c) { + super.write(c); + ++length; + } + public void write(char buf[], int off, int len) { + super.write(buf, off, len); + length += len; + } + public void write(String s, int off, int len) { + super.write(s, off, len); + length += len; + } + public void nextLevel(int x) { + for (int i = 0; i < x; ++i) nextLevel(); + } + public void prevLevel(int x) { + for (int i = 0; i < x; ++i) prevLevel(); + } + } + + void processBinary(final AbstractBinaryExpression expr, final String op) + throws VisitorException { + out.print('('); + expr.getLeft().accept(this); + out.ws(); out.print(op); out.ws(); + expr.getRight().accept(this); + out.print(')'); + } + + void processCompare(final AbstractBinaryExpression expr, final String op) + throws VisitorException { + processBinary(expr, op); + } + + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + processCompare(e, "&&"); + } + + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + processCompare(e, "||"); + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + processCompare(e, "=="); + } + + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + processCompare(e, ">="); + } + + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + processCompare(e, ">"); + } + + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + processCompare(e, "!="); + } + + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + processCompare(e, "<="); + } + + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + processCompare(e, "<"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/Csp2Verilog.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/Csp2Verilog.java new file mode 100644 index 0000000000..be5fedd8f4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/Csp2Verilog.java @@ -0,0 +1,279 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2verilog; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.OutputStreamWriter; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.regex.Pattern; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.csp.ast.*; +import com.avlsi.csp.csp2java.NoCSPBlockException; +import com.avlsi.csp.csp2java.SemanticException; +import com.avlsi.csp.csp2xml.XmlTourist; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.csp.util.ConstantEvaluator; +import com.avlsi.csp.util.DeclarationProcessor; +import com.avlsi.csp.util.FunctionPreprocessor; +import com.avlsi.csp.util.Problem; +import com.avlsi.csp.util.ProblemFilter; +import com.avlsi.csp.util.RefinementResolver; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.Printable; +import com.avlsi.io.WrapPrintWriter; +import com.avlsi.tools.cosim.CoSimInfo; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.functions.UnaryPredicate; + +/** + * Generates gma from a cell's CSP block. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class Csp2Verilog { + private final PrintWriter warningWriter; + private final PrintWriter errorWriter; + private final PrintWriter debugWriter; + private final String resetNodeName; + private final int registerBitWidth; + private final ProblemFilter probFilter; + private final boolean debugTransformation; + private final boolean enableSystemVerilog; + + public Csp2Verilog(PrintWriter warningWriter, + PrintWriter errorWriter, + PrintWriter debugWriter, + String resetNodeName, + int registerBitWidth, + ProblemFilter probFilter, + boolean enableSystemVerilog) { + this(warningWriter, errorWriter, debugWriter, resetNodeName, + registerBitWidth, probFilter, enableSystemVerilog, false); + } + + public Csp2Verilog(PrintWriter warningWriter, + PrintWriter errorWriter, + PrintWriter debugWriter, + String resetNodeName, + int registerBitWidth, + ProblemFilter probFilter, + boolean enableSystemVerilog, + boolean debugTransformation) { + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.resetNodeName = resetNodeName; + this.registerBitWidth = registerBitWidth; + this.probFilter = probFilter; + this.enableSystemVerilog = enableSystemVerilog; + this.debugTransformation = debugTransformation; + } + + /** + * Generates Verilog from csp. + * + * @param p parsed CSP program + * @param cellInfo Contains information on the cell's ports and metaparameters. + * @param pw PrintWriter to which to write the generated class. + **/ + private void genCode(final CSPProgram p, + final CSPCellInfo cellInfo, + final Collection/**/ inputPorts, + final boolean strictVars, + final boolean implicitInit, + final PrintWriter pw) + throws SemanticException { + + try { + final VisitorInterface visitor; + if (enableSystemVerilog) { + visitor = new SystemVerilogEmitter( + cellInfo, pw, warningWriter, errorWriter, debugWriter, + resetNodeName, registerBitWidth, strictVars, probFilter); + } else { + visitor = new VerilogEmitter(cellInfo, inputPorts, + pw, warningWriter, errorWriter, debugWriter, + resetNodeName, registerBitWidth, strictVars, + implicitInit, probFilter); + } + p.accept(visitor); + } catch (VisitorException e) { + throw new SemanticException(e); + } + } + + private void dumpProgram(final CSPProgram prog, final String mesg) { + if (debugTransformation) { + try { + debugWriter.println(mesg); + prog.accept(new XmlTourist(debugWriter)); + debugWriter.flush(); + } catch (VisitorException e) { + debugWriter.println("Exception while dumping program: " + e); + } + } + } + + /** + * Generates Verilog from csp. + * + * @param cell + * CAST cell from which channel declarations and CSP program + * are fetched + * @param out + * PrintWriter to which the verilog should be written. + **/ + public void convert(final CellInterface cell, + final Collection/**/ inputPorts, + final PrintWriter out) + throws SemanticException { + final CSPProgram p = cell.getCSPProgram(); + if (p == null) { + throw new NoCSPBlockException(); + } + final CSPProgram unrolled; + try { + dumpProgram(p, "Original program"); + + final CSPProgram noConst = ConstantEvaluator.evaluate(p); + + dumpProgram(noConst, "After constant removal"); + + final FunctionPreprocessor fp = + new FunctionPreprocessor(cell.getCSPInfo(), null); + fp.visitCSPProgram(noConst); + probFilter.process(fp.getProblems()); + + unrolled = (CSPProgram) fp.getResult(); + + dumpProgram(unrolled, "After function preprocessing"); + } catch (VisitorException e) { + throw new SemanticException(e); + } + final boolean strictVars = + ((Boolean) DirectiveUtils.getCspDirective( + cell, + DirectiveConstants.STRICT_VARS)).booleanValue(); + final boolean implicitInit = + ((Boolean) DirectiveUtils.getCspDirective( + cell, + DirectiveConstants.IMPLICIT_INIT)).booleanValue(); + genCode(unrolled, cell.getCSPInfo(), inputPorts, strictVars, + implicitInit, out); + } + + /** + * Prints usage message and exits. + **/ + private static void usage() { + System.out.println("Usage: " + + "csp2verilog [--cast-path=castpath] --cell=f.q.c.n" + + " [--output-file=file_name] [--debug-transformation]" + + " [--enable-system-verilog]"); + System.exit(1); + } + + /** + * Converts CSP to Verilog. By default, Verilog is written to cell_name.v. + * + * @param args Arguments. + **/ + public static void main(String[] args) throws Exception { + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl(args); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + final CommandLineArgs theArgs = + new CachingCommandLineArgs(argsWithConfigs); + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + Csp2Verilog.class)); + } + + final String castCellName = theArgs.getArgValue("cell", null); + if (castCellName == null) + usage(); + + final FileSearchPath castFSP = + new FileSearchPath(theArgs.getArgValue("cast-path", ".")); + final CellInterface cell = + new CastFileParser(castFSP, "2") + .getFullyQualifiedCell(castCellName); + final PrintWriter systemErrWriter = + new PrintWriter(new OutputStreamWriter(System.err)); + + final String outputFileName = + theArgs.getArgValue("output-file", castCellName + ".v"); + final PrintWriter out = + new PrintWriter( + new BufferedWriter( + new FileWriter(new File(outputFileName)))); + + final boolean debugTransformation = + theArgs.argExists("debug-transformation"); + + final boolean enableSystemVerilog = + theArgs.argExists("enable-system-verilog"); + + final String resetNodeName = "\\$Reset"; + + final int registerBitWidth = 128; + + new Csp2Verilog(systemErrWriter, systemErrWriter, systemErrWriter, + resetNodeName, registerBitWidth, + getProblemFilter(systemErrWriter), enableSystemVerilog, + debugTransformation) + .convert(cell, Collections.EMPTY_LIST, out); + out.close(); + } + public static ProblemFilter getProblemFilter(final PrintWriter pw) { + final Pattern temp = Pattern.compile("^temp\\$[0-9]+$"); + final Printable prntble = new WrapPrintWriter(pw); + final UnaryFunction classifier = ProblemFilter.getClassifier( + new HashSet(Arrays.asList("type.checker.undeclared.set.unused", + "preprocessor.assign.to.input", + "type.checker.invalid.guard"))); + final BinaryFunction filter = new BinaryFunction() { + public Object execute(final Object o1, final Object o2) { + final String type = (String) o1; + final Problem prob = (Problem) o2; + if (prob.getCode() + .equals("type.checker.undeclared.set.unused")) { + final Object[] args = prob.getArguments(); + final String var = (String) args[0]; + if (temp.matcher(var).matches()) { + return null; + } + } + return prntble; + } + }; + return new ProblemFilter(classifier, filter); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/SystemVerilogEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/SystemVerilogEmitter.java new file mode 100644 index 0000000000..404eebafa5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/SystemVerilogEmitter.java @@ -0,0 +1,2157 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2verilog; + +import java.io.PrintWriter; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import com.avlsi.cell.CellUtils; +import com.avlsi.csp.ast.*; +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.csp.util.DeclarationProcessor; +import com.avlsi.csp.util.RefinementResolver; +import com.avlsi.csp.util.ProblemFilter; +import com.avlsi.csp.util.UniqueLabel; +import com.avlsi.csp.util.VariableAnalysisException; +import com.avlsi.csp.util.VariableAnalyzer; +import com.avlsi.fast.metaparameters.ArrayMetaParam; +import com.avlsi.fast.metaparameters.BooleanMetaParam; +import com.avlsi.fast.metaparameters.IntegerMetaParam; +import com.avlsi.fast.metaparameters.MetaParamDefinition; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.tools.prs2verilog.verilog.VerilogUtil; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.HashCounter; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.text.StringUtil; + +/** + * Visitor pattern to emit Verilog from csp. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class SystemVerilogEmitter implements VisitorInterface { + private final CSPCellInfo cellInfo; + + // State needed for traversal + final PrintWriter out; + + private final PrintWriter debugWriter; + + private final PrintWriter warningWriter; + + private final PrintWriter errorWriter; + + /** + * Number of bits to use for variables; + **/ + private final int registerBitWidth; + + /** + * The type of register to use for variables. + **/ + private final String registerType; + + /** + * The name of reset signal + **/ + private final String resetNodeName; + + /** + * Autogenerated variable number. + **/ + private int varNum = 0; + + private int blockNum = 0; + + private final VariableAnalyzer analyzer; + + private VariableAnalyzer.Results analysisResults; + + private RefinementResolver resolver = + new RefinementResolver(RefinementResolver.NAME); + + private ComplexAccess complexAccess = null; + + private boolean arrayDeclRange = false; + + private final UniqueLabel labels = new UniqueLabel(new HashMap()); + + /** + * true if we are processing the body of a program or a + * function; false if we are processing initializers. + **/ + private boolean processingBody = false; + + /** Special character escape sequences to use in string literals */ + private static Map ESCAPE_MAP = CollectionUtils.mapify( + new Object[] { + new Character('\n'), "\\n", + new Character('\t'), "\\t" + }); + + private final LinkedList/*, + String>>*/ pendingFunctions = + new LinkedList/*, + String>>*/(); + private final List/*, + String>>*/ pendingConstructors = + new ArrayList/*, + String>>*/(); + + private final List/*>*/ arbiters = + new ArrayList/*>*/(); + + private final boolean strictVars; + + private final ProblemFilter problems; + + private interface Index { + void write() throws VisitorException; + } + private class ComplexAccess { + private class FixedIndex implements Index { + private final String var; + public FixedIndex(final String var) { + this.var = var; + } + public void write() throws VisitorException { + out.print(var); + } + } + private class ExpressionIndex implements Index { + private final ExpressionInterface expr; + public ExpressionIndex(final ExpressionInterface expr) { + this.expr = expr; + } + public void write() throws VisitorException { + expr.accept(SystemVerilogEmitter.this); + } + } + + private final LinkedList/**/ array; + private final LinkedList/**/ structure; + private Object base; + public ComplexAccess() { + this.array = new LinkedList/**/(); + this.structure = new LinkedList/**/(); + } + public ComplexAccess(final ComplexAccess other) { + this.array = new LinkedList/**/(other.array); + this.structure = new LinkedList/**/(other.structure); + this.base = other.base; + } + private void accessArray(final Index idx, final boolean forward) { + if (forward) array.addLast(idx); + else array.addFirst(idx); + } + public void accessArray(final String var) { + accessArray(new FixedIndex(var), true); + } + public void accessArray(final ExpressionInterface expr) { + accessArray(new ExpressionIndex(expr), false); + } + public void accessStructure(final String fieldName) { + accessStructure(fieldName, true); + } + public void accessStructure(final String fieldName, + final boolean forward) { + if (forward) structure.addLast(fieldName); + else structure.addFirst(fieldName); + } + public Object getBase() { + return base; + } + public void setBase(final Object token) { + base = token; + } + private void emit(final String hierarchy, + final String channelPart) throws VisitorException { + final StringBuffer buf = new StringBuffer(); + buf.append(hierarchy); + buf.append("\\"); + buf.append((String) tokenVerilogNameMap.get(base)); + for (Iterator i = structure.iterator(); i.hasNext(); ) { + buf.append('.'); + buf.append((String) i.next()); + } + buf.append(channelPart); + out.print(buf.toString()); + out.print(' '); + for (Iterator i = array.iterator(); i.hasNext(); ) { + out.print("["); + ((Index) i.next()).write(); + out.print("]"); + } + } + public void write(final String channelPart) throws VisitorException { + final ComplexAccess mapped = mapComplexArgument(this); + String hierarchy = mapped.getHierarchy(); + if (hierarchy != null && getHierarchy() == hierarchy) + hierarchy = null; + mapped.emit(hierarchy == null ? "" : escape(hierarchy) + ".", + channelPart); + } + public void write() throws VisitorException { + write(""); + } + public Collection getIndices() { + return array; + } + public ComplexAccess map(final ComplexAccess previous) { + if (previous == null) return this; + + final ComplexAccess result = new ComplexAccess(); + result.array.addAll(previous.array); + result.array.addAll(array); + result.structure.addAll(previous.structure); + result.structure.addAll(structure); + result.base = previous.base; + return result; + } + public void copyStructure(final ComplexAccess other) { + structure.clear(); + structure.addAll(other.structure); + } + public String getHierarchy() { + return (String) hierarchyNameMap.get(base); + } + } + + private class ComplexDeclaration { + private final List/**/ array; + private final List/**/ structure; + private Type type; + public ComplexDeclaration() { + this.array = new ArrayList/**/(); + this.structure = new ArrayList/**/(); + } + public ComplexDeclaration(final ComplexDeclaration c) { + this.array = new ArrayList/**/(c.array); + this.structure = new ArrayList/**/(c.structure); + this.type = c.type; + } + public void declareArray(final Range expr) { + array.add(expr); + } + public void declareStructure(final String fieldName) { + structure.add(fieldName); + } + public void setType(final Type type) { + this.type = type; + } + private String getStructurePart(final String base) { + final StringBuffer buf = new StringBuffer(); + buf.append(base); + for (Iterator i = structure.iterator(); i.hasNext(); ) { + buf.append('.'); + buf.append((String) i.next()); + } + return escape(buf.toString()); + } + public void declare(final String base) throws VisitorException { + if (type instanceof StringType) { + out.print("`CSP_STRING "); + } else { + out.print(registerType + ' '); + } + out.print(getStructurePart(base)); + for (Iterator i = array.iterator(); i.hasNext(); ) { + final Range r = (Range) i.next(); + out.print('['); + r.getMinExpression().accept(SystemVerilogEmitter.this); + out.print(':'); + r.getMaxExpression().accept(SystemVerilogEmitter.this); + out.print(']'); + } + } + private String getIndices() throws VisitorException { + final StringBuffer buf = new StringBuffer(); + int idx = 0; + for (Iterator i = array.iterator(); i.hasNext(); ++idx) { + buf.append("[loop$[" + idx + "]]"); + } + return buf.toString(); + } + } + + private void emitForLoop(final String var, final Range r) + throws VisitorException { + out.print("for (" + var + " = "); + r.getMinExpression().accept(this); + out.print("; " + var + " <= "); + r.getMaxExpression().accept(this); + out.print("; " + var + " = " + var + " + 1)"); + } + + private void emitChannelPart(final ExpressionInterface chanExpr, + final String part) throws VisitorException { + complexAccess = new ComplexAccess(); + chanExpr.accept(this); + final ComplexAccess old = complexAccess; + complexAccess = null; + old.write(part); + } + + private void emitChannelEnable(final ExpressionInterface chanExpr) + throws VisitorException { + emitChannelPart(chanExpr, "$enable"); + } + + private void emitChannelData(final ExpressionInterface chanExpr) + throws VisitorException { + emitChannelPart(chanExpr, "$data"); + } + + public SystemVerilogEmitter(final CSPCellInfo cellInfo, + final PrintWriter out, + final PrintWriter warningWriter, + final PrintWriter errorWriter, + final PrintWriter debugWriter, + final String resetNodeName, + final int registerBitWidth, + final boolean strictVars, + final ProblemFilter problems) { + this.cellInfo = cellInfo; + this.out = out; + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.analyzer = new VariableAnalyzer(cellInfo); + this.analysisResults = null; + this.registerBitWidth = registerBitWidth; + this.registerType = "reg signed [" + (registerBitWidth - 1) + ":0]"; + this.resetNodeName = resetNodeName; + this.strictVars = strictVars; + this.problems = problems; + } + + private void processUnary(final AbstractUnaryExpression expr, + final String op) throws VisitorException { + out.print('(' + op); + expr.getExpression().accept(this); + out.print(')'); + } + + private void processBinary(final AbstractBinaryExpression expr, + final String op) + throws VisitorException { + out.print('('); + expr.getLeft().accept(this); + out.print(' ' + op + ' '); + expr.getRight().accept(this); + out.print(')'); + } + + private void processCompare(final AbstractBinaryExpression expr, + final String op) + throws VisitorException { + // convert truth values of 0 and 1 to 0 and -1 + out.print("(-"); + processBinary(expr, op); + out.print(')'); + } + + private void processSpecialBinary(final AbstractBinaryExpression expr, + final String func) + throws VisitorException { + // REVIEW: What is the overhead of functions? Should we + // do this inline with a temporary variable? + out.print(func + '('); + expr.getLeft().accept(this); + out.print(", "); + expr.getRight().accept(this); + out.print(')'); + } + + private void prettyMessage(String message, ParseRange pr) { + ExceptionPrettyPrinter.prettyMessage(message, pr.start.filename, + pr.start.line, pr.start.column+1, + errorWriter); + } + + /** + * Inspect the sets of uninitialized variables returned by variable + * analysis. + **/ + private Set/**/ processResults(VariableAnalyzer.Results r) { + final Set/**/ undeclaredVars = new HashSet/**/(); + Map m = r.getUndeclaredTypes(); + for (final Iterator i = m.keySet().iterator(); i.hasNext(); ) { + String name = (String) i.next(); + Type type = (Type) m.get(name); + + if (type == null + || type instanceof IntegerType + || type instanceof BooleanType) + undeclaredVars.add(name); + else { + errorWriter.flush(); + warningWriter.flush(); + throw new Error ("Undeclared variable has unsupported type."); + } + } + + return undeclaredVars; + } + + private void outputMetaArray(final String name, final Collection indices) { + out.print(name); + for (Iterator i = indices.iterator(); i.hasNext(); ) { + out.print("[" + i.next() + "]"); + } + out.print(" = "); + } + + private void processMetaParameter(final String name, + final MetaParamTypeInterface type, + final Collection indices) { + if (type instanceof ArrayMetaParam) { + final ArrayMetaParam amp = (ArrayMetaParam) type; + final List newidx = new ArrayList(indices); + newidx.add(null); + for (int i = amp.getMinIndex(); i <= amp.getMaxIndex(); ++i) { + newidx.set(newidx.size() - 1, new Integer(i)); + processMetaParameter(name, amp.get(i), newidx); + } + } else if (type instanceof BooleanMetaParam) { + if (!indices.isEmpty()) { + outputMetaArray(name, indices); + if (((BooleanMetaParam) type).toBoolean()) { + out.println("-1;"); + } else { + out.println("0;"); + } + } + } else if (type instanceof IntegerMetaParam) { + if (!indices.isEmpty()) { + outputMetaArray(name, indices); + processBigInteger(((IntegerMetaParam) type).toBigInteger(), 10); + out.println(";"); + } + } else if (!indices.isEmpty()) { + throw new AssertionError("Cannot handle type: " + type); + } + } + + private void processMetaParameters() { + for (Iterator i = cellInfo.getMetaParamDefinitions(); i.hasNext(); ) { + MetaParamDefinition mp = (MetaParamDefinition) i.next(); + processMetaParameter(mp.getName(), mp.getType(), + Collections.EMPTY_LIST); + } + } + + private void outputProgramBody(CSPProgram e) throws VisitorException { + declareVariables(); + + // call resetNodes() if it is defined + final Pair/**/ resetDecl = + (Pair) resolver.getResolvedFunctions() + .get(RefinementResolver.RESET_FUNCTION_CALL); + if (resetDecl != null) { + if (resetDecl.getSecond() instanceof FunctionDeclaration) { + out.println("always @(" + resetNodeName + " )"); + out.println("if (" + resetNodeName + " == 0) " + + "begin : reset_nodes"); + final String funcName = + getFullName((FunctionDeclaration) resetDecl.getSecond(), + Collections.EMPTY_LIST); + out.println(funcName + " ;"); + out.println("end"); + } else { + warningWriter.println( + "Invalid definition of special function resetNodes: " + + ((AbstractASTNode) e).getParseRange().fullString()); + + } + } + + // start main block on posedge of _RESET + out.println("always @(posedge " + resetNodeName + " )"); + out.println("begin : main "); + + processMetaParameters(); + + final Set/**/ undeclaredVars = processResults(analysisResults); + // assign to 0 + for (Iterator i = undeclaredVars.iterator(); i.hasNext(); ) { + final String var = escape((String) i.next()); + out.println(var + " = 0;"); + } + out.println(); + + // handle initializer statement to deal with top-level constants + // TODO: Share top-level constants, as this wastes memory + if (e.getInitializerStatement() != null) + e.getInitializerStatement().accept(this); + + // csp body + processingBody = true; + e.getStatement().accept(this); + processingBody = false; + + // end initial block + out.println("end"); + out.println(); + } + + public void visitCSPProgram(CSPProgram e) throws VisitorException { + + resolver.resolve(e); + e = resolver.getCSPProgram(); + + // declare and initialize the undeclared variables + try { + analysisResults = analyzer.getResults(e, resolver); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage()); + } + problems.process(analysisResults.getErrors(strictVars)); + + for (Iterator i = e.getFunctionDeclarations(); i.hasNext(); ) { + final FunctionDeclaration decl = (FunctionDeclaration) i.next(); + try { + getAnalyzerResults(decl, e.getInitializerStatement()); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + } + + if (!problems.hasError()) { + updateTokenVerilogMap(null); + outputProgramBody(e); + outputFunctions(e.getInitializerStatement()); + outputConstructors(); + outputArbiters(); + } + } + + /** + * Return a new autogenerated variable number. + **/ + private int genVarNum() { + return varNum++; + } + + private String genBlock() { + return "\\$block" + blockNum++ + ' '; + } + + public void visitAddExpression(AddExpression e) + throws VisitorException { + if (analysisResults.getType(e) instanceof StringType) { + out.print("csp_string.concat("); + final boolean lstr = + analysisResults.getType(e.getLeft()) instanceof StringType; + if (!lstr) out.print("util.csp_string("); + e.getLeft().accept(this); + if (!lstr) out.print(", 10)"); + + out.print(", "); + + final boolean rstr = + analysisResults.getType(e.getRight()) instanceof StringType; + if (!rstr) out.print("util.csp_string("); + e.getRight().accept(this); + if (!rstr) out.print(", 10)"); + + out.print(')'); + } else { + processBinary(e, "+"); + } + } + + public void visitAndExpression(AndExpression e) + throws VisitorException { + processBinary(e, "&"); + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + boolean writeNow = false; + if (complexAccess == null) { + complexAccess = new ComplexAccess(); + writeNow = true; + } + complexAccess.accessArray(e.getIndexExpression()); + e.getArrayExpression().accept(this); + if (writeNow) { + final ComplexAccess old = complexAccess; + complexAccess = null; + old.write(); + } + } + + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + // don't have to do anything to the operands, because -1 is also true + processCompare(e, "&&"); + } + + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + // don't have to do anything to the operands, because -1 is also true + processCompare(e, "||"); + } + + private void processConstantBitRange(BitRangeExpression e, boolean rhs) + throws VisitorException { + final IntegerExpression maxExpr = + (IntegerExpression) e.getMaxExpression(); + final IntegerExpression minExpr = + (IntegerExpression) e.getMinExpression(); + final BigInteger maxBit = + new BigInteger(maxExpr.getValue(), maxExpr.getRadix()); + final BigInteger minBit = minExpr == null ? + null + : new BigInteger(minExpr.getValue(), minExpr.getRadix()); + if (!rhs) out.print("($signed({1'd0, "); + e.getBitsExpression().accept(this); + out.print('[' + maxBit.toString(10)); + if (minBit != null && !maxBit.equals(minBit)) + out.print(':' + minBit.toString(10)); + out.print(']'); + if (!rhs) out.print("}))"); + } + + private boolean needBitRangeFunction(final BitRangeExpression e) { + // If both min and max are constants, and if we are not part-selecting + // on an array element[1], then we can use Verilog's constant + // part-select. + // [1] Seems to be a ncverilog restriction, as part-selecting an array + // element is legal per the Verilog 2001 spec 4.2.2 (p. 55). + if (e.getMaxExpression() instanceof IntegerExpression) { + if (e.getMinExpression() == null) return false; + else if (e.getMinExpression() instanceof IntegerExpression) { + final IntegerExpression maxExpr = + (IntegerExpression) e.getMaxExpression(); + final IntegerExpression minExpr = + (IntegerExpression) e.getMinExpression(); + final BigInteger maxBit = + new BigInteger(maxExpr.getValue(), maxExpr.getRadix()); + final BigInteger minBit = + new BigInteger(minExpr.getValue(), minExpr.getRadix()); + return !(e.getBitsExpression() instanceof IdentifierExpression) + && !maxBit.equals(minBit); + } + } + return true; + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + // The csp grammar only allows bit extraction from arrays, + // structures and simple variables. + assert e.getBitsExpression() instanceof IdentifierExpression || + e.getBitsExpression() instanceof ArrayAccessExpression || + e.getBitsExpression() instanceof MemberAccessExpression: + "Invalid bit range expression found at: " + e.getParseRange().fullString(); + + if (needBitRangeFunction(e)) { + // can't use constant part-select, use special function + out.print("util.bit_extract" + + (e.getMinExpression() == null ? "2" : "3") + + "("); + e.getBitsExpression().accept(this); + out.print(", "); + e.getMaxExpression().accept(this); + if (e.getMinExpression() != null) { + out.print(", "); + e.getMinExpression().accept(this); + } + out.print(')'); + } else { + processConstantBitRange(e, false); + } + } + + /* Process built in functions - all others are turned into assignmented + by processFunctionCalls */ + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + final ExpressionInterface func = e.getFunctionExpression(); + final String funcName = + func instanceof IdentifierExpression ? + ((IdentifierExpression) func).getIdentifier() : null; + + if ("print".equals(funcName)) { + out.println("`ifdef ENABLE_CSP_PRINT"); + out.println("$write(\"%t:%m: \", $time);"); + final List args = new ArrayList(); + CollectionUtils.addAll(args, e.getActuals()); + args.add(args.remove(0)); + for (int i = 0; i < args.size(); ++i) { + final ExpressionInterface arg = + (ExpressionInterface) args.get(i); + if (analysisResults.getType(arg) instanceof StringType) { + out.print("csp_string.write("); + } else { + out.print("util.display_hex("); + } + arg.accept(this); + out.println(");"); + if (i < args.size() - 1) { + out.print("$write(\" "); + if (i == args.size() - 2) out.print("(tag="); + out.println("\");"); + } + } + if (args.size() < 2) out.println("$display;"); + else out.println("$display(\")\");"); + out.println("`endif"); + return; + } else if ("choose".equals(funcName)) { + Iterator i = e.getActuals(); + // XXX: Add null exception handling + ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + out.print(" ? "); + arg = (ExpressionInterface) i.next(); + arg.accept(this); + out.print(" : "); + arg = (ExpressionInterface) i.next(); + arg.accept(this); + return; + } else if ("random".equals(funcName) || + "log2".equals(funcName) || + "log4".equals(funcName)) { + Iterator i = e.getActuals(); + out.print("util." + funcName + "("); + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + out.println(")"); + return; + } else if ("wait".equals(funcName)) { + final Iterator i = e.getActuals(); + out.print("#(("); + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + // divide by 100 to change from DSim units to transitions + out.println(") * `PRS2VERILOG_TAU / 100);"); + return; + } else if ("string".equals(funcName)) { + out.print("util.csp_string("); + for (Iterator i = e.getActuals(); i.hasNext(); ) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + if (i.hasNext()) out.print(" , "); + } + out.println(")"); + return; + } + throw new VisitorException("Unsupported function calls found: " + e.getParseRange().fullString()); + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + // Handle divide by 0 + processSpecialBinary(e, "util.divide"); + } + + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + // XXX: handle 0**x, for x <= 0 + // According to the verilog spec exponentiation involving + // signed values should give a real result. Reals are + // rounded to nearest, except ties are rounded away from zero. + // Thus, we should have 2**-1 == 1, but it seems that 2**-1 == 0. + // Perhaps file a bug with cadence. + processSpecialBinary(e, "util.pow"); + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + processCompare(e, "=="); + } + + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + processCompare(e, ">="); + } + + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + processCompare(e, ">"); + } + + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + processCompare(e, "!="); + } + + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + processCompare(e, "<="); + } + + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + processCompare(e, "<"); + } + + /** + * Output an integer constant as a signed expression. If radix is 2, 8, or + * 10, use the "b", "o" and "d" base specifiers respectively. Otherwise, + * output in hexdecimal. + * + * @param bi integer to output + * @param radix radix to use + **/ + private void processBigInteger(BigInteger bi, final int radix) { + // all constants must be signed, because "if any operand is unsigned, + // the result is unsigned, regardless of the operator" (4.5.1) + if (!arrayDeclRange) out.print("$signed("); + + if (bi.signum() == -1) { + // if the number is negative, prepend a negative sign, and process + // it's absolute value + bi = bi.negate(); + out.print('-'); + } + + final int width = bi.bitLength() + 1; // plus 1 for the sign bit + + if (!arrayDeclRange) out.print(width); + out.print('\''); + if (radix == 2) + out.print("b" + bi.toString(2)); + else if (radix == 8) + out.print("o" + bi.toString(8)); + else if (radix == 10) + out.print("d" + bi.toString(10)); + else { + // write other bases in hex for no particular reason + out.print("h" + bi.toString(16)); + } + if (!arrayDeclRange) out.print(")"); + } + + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + processBigInteger(new BigInteger(e.getValue(), e.getRadix()), + e.getRadix()); + } + + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + // handles negative shift amounts + processSpecialBinary(e, "util.shift_left"); + } + + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + // handles negative shift amounts + processSpecialBinary(e, "util.shift_right"); + } + + private String escape(final String s) { + return VerilogUtil.escapeIfNeeded(s); + } + + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + if (complexAccess == null) { + complexAccess = new ComplexAccess(); + complexAccess.setBase(analysisResults.getIdentToken(e)); + complexAccess.write(); + complexAccess = null; + } else complexAccess.setBase(analysisResults.getIdentToken(e)); + } + + public void visitLoopExpression(LoopExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + processBinary(e, "*"); + } + + public void visitNegateExpression(NegateExpression e) + throws VisitorException { + processUnary(e, "-"); + } + + public void visitNotExpression(NotExpression e) + throws VisitorException { + processUnary(e, "~"); + } + + public void visitOrExpression(OrExpression e) + throws VisitorException { + processBinary(e, "|"); + } + + public void visitXorExpression(XorExpression e) + throws VisitorException { + processBinary(e, "^"); + } + + public void visitPeekExpression(PeekExpression e) + throws VisitorException { + // inside guard: #L? == L.d + // outside guard: #L? == ( [ L.d >= 0 ] ; L.d ) + // FunctionPreprocessor converts peeks outside of guards + // to assignment statements that are handled specially + // in this file by visitAssignmentStatement + // It converts peeks within guards by pre-pending AND of + // probes to the expression. + // Thus, here, we just need to spit L.d + emitChannelData(e.getChannelExpression()); + } + + public void visitProbeExpression(ProbeExpression e) + throws VisitorException { + // #L == (L.d >= 0) + // #R == R.e + + final ExpressionInterface chanExpr = e.getChannelExpression(); + // The type checking pass should have ensured that this is indeed + // a channel type. + final ChannelType type = + (ChannelType) analysisResults.getType(chanExpr); + // Add - to compensate for difference in verilog and csp + // comparison semantics. + if (type.getDirection() == PortDirection.IN) { + out.print("(-("); + emitChannelData(chanExpr); + out.println(" >= 0))"); + } else { + assert type.getDirection() == PortDirection.OUT; + out.print('-'); + emitChannelEnable(chanExpr); + out.println(); + } + } + + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + // handle x % 0 + processSpecialBinary(e, "util.remainder"); + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + final String esc = + '"' + StringUtil.quoteASCIIString(e.getValue(), ESCAPE_MAP) + '"'; + out.print("csp_string.init($bits(" + esc + "), " + esc + ")"); + } + + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + processBinary(e, "-"); + } + + private void processStructureAccess(final String field, + final ExpressionInterface e) + throws VisitorException { + boolean writeNow = false; + if (complexAccess == null) { + complexAccess = new ComplexAccess(); + writeNow = true; + } + complexAccess.accessStructure(field, false); + e.accept(this); + if (writeNow) { + final ComplexAccess old = complexAccess; + complexAccess = null; + old.write(); + } + } + + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + processStructureAccess(e.getFieldName(), e.getStructureExpression()); + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + processStructureAccess(e.getMemberName(), e.getStructureExpression()); + } + + private void processBooleanChannel(ExpressionInterface chanExpr, + ExpressionInterface rhs) + throws VisitorException { + if (chanExpr == null) rhs.accept(this); + else { + final boolean bool = + analysisResults.getType(rhs) instanceof BooleanType; + if (bool) out.print("(-("); + emitChannelData(chanExpr); + if (bool) out.print("!= 0))"); + } + } + + /** + * Emit code to assign between two variables of the same type. + * + * @param lhs Left hand expression + * @param rhs Right hand expression + * @param t type of the expressions + **/ + private void emitAssignment(final ComplexAccess lhs, + final ComplexAccess rhs, final Type t) + throws VisitorException { + emitAssignment(lhs, rhs, t, 0); + } + + private void emitAssignment(final ComplexAccess lhs, + final ComplexAccess rhs, final Type t, + final int indices) throws VisitorException { + if (t instanceof IntegerType || t instanceof BooleanType || + t instanceof StringType) { + lhs.write(); + out.print(" = "); + rhs.write(); + out.println(";"); + } else if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + out.println("begin : " + genBlock()); + final String var = "loop$" + indices; + out.println(registerType + " " + var + ";"); + emitForLoop(var, at.getRange()); + out.println(" begin"); + lhs.accessArray(var); + rhs.accessArray(var); + emitAssignment(lhs, rhs, at.getElementType(), indices + 1); + out.println("end"); + out.println("end"); + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nlhs = new ComplexAccess(lhs); + final ComplexAccess nrhs = new ComplexAccess(rhs); + final String id = d.getIdentifier().getIdentifier(); + nlhs.accessStructure(id); + nrhs.accessStructure(id); + emitAssignment(nlhs, nrhs, d.getTypeFragment(), indices); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Cannot assign between: " + t); + } + } + + /** + * Process an assignment statement. + * + * @param lhs left hand side of the assignment statement + * @param rhs right hand side of the assignment statement; + * null if the right hand side is the value from a channel + * @param chanExpr null if the right hand side is not the + * value from a channel; otherwise, it contains the channel expression to + * read from. + **/ + private void processAssignmentStatement(ExpressionInterface lhs, + ExpressionInterface rhs, + ExpressionInterface chanExpr, + AssignmentStatement stmt) + throws VisitorException { + final boolean op = + stmt != null && stmt.getKind() != AssignmentStatement.EQUAL; + if (lhs instanceof BitRangeExpression && + needBitRangeFunction((BitRangeExpression) lhs)) { + final BitRangeExpression bitRangeExpression = + (BitRangeExpression) lhs; + out.print("util.bit_insert_" + + (op ? stmt.getKindString() : "") + + (bitRangeExpression.getMinExpression() == null ? + "3" : "4") + + "("); + bitRangeExpression.getBitsExpression().accept(this); + out.print(", "); + processBooleanChannel(chanExpr, rhs); + out.print(", "); + bitRangeExpression.getMaxExpression().accept(this); + if (bitRangeExpression.getMinExpression() != null) { + out.print(", "); + bitRangeExpression.getMinExpression().accept(this); + } + out.println(");"); + } else if (analysisResults.getType(lhs) instanceof StructureType || + analysisResults.getType(lhs) instanceof ArrayType) { + // This can only be an assignment between two structure or array + // variables + complexAccess = new ComplexAccess(); + lhs.accept(this); + final ComplexAccess lca = complexAccess; + + complexAccess = new ComplexAccess(); + rhs.accept(this); + final ComplexAccess rca = complexAccess; + complexAccess = null; + + final Type t = (Type) analysisResults.getType(lhs); + emitAssignment(lca, rca, t); + } else { + final boolean lstr = + stmt != null && stmt.getKind() == AssignmentStatement.ADD && + (analysisResults.getType(lhs) instanceof StringType); + final boolean lbool = + (analysisResults.getType(lhs) instanceof BooleanType); + final boolean rstr = + lstr && !(analysisResults.getType(rhs) instanceof StringType); + + if (op) out.print("util.assign_" + + (lstr ? "concat" : stmt.getKindString()) + "("); + if (lhs instanceof BitRangeExpression) { + processConstantBitRange((BitRangeExpression) lhs, true); + } else { + lhs.accept(this); + } + if (op) out.print(" , "); + else { + out.print(" = "); + if (lbool) out.print("$signed("); + } + if (rstr) out.print("util.csp_string("); + processBooleanChannel(chanExpr, rhs); + if (rstr) out.print(", 10)"); + if (op) out.print(" )"); + else if (lbool) out.print(')'); + out.println(';'); + + if (false) { + // debugging display + out.print("$display(\""); + lhs.accept(this); + out.print(": %d\\n\", "); + lhs.accept(this); + out.println(");"); + } + } + } + + private static final Map/**/ BUILTIN_FUNCTIONS = + CollectionUtils.mapify( + new String[] { "print", "util.display_hex", + "eventQueueIsEmpty", null, + "random", "random", + "srandom", "srandom", + "choose", "choose", + "log2", "log2", + "log4", "log4", + "wait", "wait", + // without function in guards, this isn't very useful + "stable", null, + "string", "string", + "enableDSimErrors", null}); + + private String getFullName( + final FunctionDeclaration decl, + final List/**/ arrayArg) throws VisitorException { + final Pair/*>*/ p = + new Pair/*>*/(decl, arrayArg); + final String result = decl.getName() + "$" + labels.getLabel(p); + pendingFunctions.addFirst(new Triplet/*, + String>*/(decl, arrayArg, result)); + + return result; + } + + private String getFullName( + final StructureDeclaration decl, + final List/**/ arrayArg) throws VisitorException { + final Pair/*>*/ p = + new Pair/*>*/(decl, arrayArg); + final String result = decl.getName() + "$" + labels.getLabel(p); + pendingConstructors.add(new Triplet/*, + String>*/(decl, arrayArg, result)); + + return result; + } + + private final Map/**/ + functionAnalyzerCache = + new HashMap/**/(); + + private VariableAnalyzer.Results + getAnalyzerResults(final FunctionDeclaration decl, + final SequentialStatement initStmt) + throws VariableAnalysisException { + VariableAnalyzer.Results results = + (VariableAnalyzer.Results) functionAnalyzerCache.get(decl); + if (results == null) { + results = analyzer.getResults(decl, initStmt, resolver); + problems.process(results.getErrors(strictVars)); + functionAnalyzerCache.put(decl, results); + } + return results; + } + + private final Map/**/ arrayMapping = + new HashMap/**/(); + + private ComplexAccess mapComplexArgument(final ComplexAccess access) { + final ComplexAccess mapped = + (ComplexAccess) arrayMapping.get(access.getBase()); + return access.map(mapped); + } + + private void outputFormalParameter(final IdentifierExpression ident, + final Type t, + final Iterator/**/ args, + final UniqueLabel label, + final String inout, + final boolean[] comma) + throws VisitorException { + if (t instanceof ArrayType || t instanceof StructureType) { + final ComplexAccess access = (ComplexAccess) args.next(); + final int num = label.getLabel(access); + final ComplexAccess fixed = new ComplexAccess(); + fixed.copyStructure(access); + fixed.setBase(access.getBase()); + final int indices = access.getIndices().size(); + if (indices > 0 && comma[0]) out.println(","); + for (int i = 0; i < indices; ++i) { + comma[0] = true; + final String var = "i$" + num + "$" + i; + declareVariable("input ", var, new IntegerType(), ","); + if (i < indices - 1) out.println(","); + fixed.accessArray(var); + } + arrayMapping.put(t, fixed); + } else { + if (comma[0]) out.println(","); + declareVariable(inout, ident.getIdentifier(), t, ","); + comma[0] = true; + } + } + + private void outputConstructor(final StructureDeclaration decl, + final List/**/ arrayArg, + final String name) throws VisitorException { + final Iterator argIter = arrayArg.iterator(); + final UniqueLabel label = new UniqueLabel(); + final boolean[] comma = new boolean[] { false }; + out.println("task " + escape(name) + " ("); + (new DeclarationProcessor() { + public void process(final Declarator d) throws VisitorException { + final IdentifierExpression ident = d.getIdentifier(); + final Type t = d.getTypeFragment(); + tokenVerilogNameMap.put(t, ident.getIdentifier()); + hierarchyNameMap.put(t, name); + outputFormalParameter(ident, t, argIter, label, "input ", + comma); + } + }).process(decl.getDeclarations()); + final IdentifierExpression rident = new IdentifierExpression("ret$"); + final StructureType rtype = new StructureType(false, decl.getName()); + tokenVerilogNameMap.put(rtype, rident.getIdentifier()); + hierarchyNameMap.put(rtype, name); + outputFormalParameter(rident, rtype, argIter, label, "output ", comma); + out.println(");"); + out.println(); + + out.println("begin : main"); + final ComplexAccess lhs = new ComplexAccess(); + lhs.setBase(rtype); + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nlhs = new ComplexAccess(lhs); + final String id = d.getIdentifier().getIdentifier(); + nlhs.accessStructure(id); + + final ComplexAccess nrhs = new ComplexAccess(); + nrhs.setBase(d.getTypeFragment()); + emitAssignment(nlhs, nrhs, d.getTypeFragment(), 0); + } + }).process(decl.getDeclarations()); + out.println("end"); + out.println("endtask"); + } + + private void outputFunction(final FunctionDeclaration decl, + final SequentialStatement initStmt, + final List/**/ arrayArg, + final String name) throws VisitorException { + final VariableAnalyzer.Results old = analysisResults; + try { + analysisResults = getAnalyzerResults(decl, initStmt); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + + updateTokenVerilogMap(name); + + arrayMapping.clear(); + out.println("task " + escape(name) + " ("); + final Iterator argIter = arrayArg.iterator(); + final UniqueLabel label = new UniqueLabel(); + final boolean[] comma = new boolean[] { false }; + for (Iterator i = decl.getFormals().getDeclarations(); i.hasNext(); ) { + final DeclaratorList d = + ((Declaration) i.next()).getDeclaratorList(); + for (Iterator j = d.getDeclarators(); j.hasNext(); ) { + final Declarator dor = (Declarator) j.next(); + final IdentifierExpression ident = dor.getIdentifier(); + final Type t = (Type) analysisResults.getIdentToken(ident); + lastVerilogTokenMap.remove(t); + outputFormalParameter(ident, t, argIter, label, "inout ", + comma); + } + } + // return value + final Type rtype = decl.getReturnType(); + if (rtype != null) { + outputFormalParameter(decl.getNameIdentifier(), rtype, + argIter, label, "output ", comma); + } + out.println(");"); + out.println(); + if (rtype != null) + lastVerilogTokenMap.remove(analysisResults.getIdentToken(decl.getNameIdentifier())); + + declareVariables(); + + // start initial block + out.println("begin : main"); + + // declare and initialize the undeclared variables + final Set/**/ undeclaredVars = processResults(analysisResults); + + // assign to 0 - undeclared variables + for (Iterator i = undeclaredVars.iterator(); i.hasNext(); ) { + final String var = escape((String) i.next()); + out.println(var + " = 0;"); + } + // assign to 0 - return value + if (decl.getReturnType() != null) + initVar(decl.getReturnType(), decl.getNameIdentifier(), 0, null); + // assign to 0 - output parameters + for (Iterator i = decl.getFormals().getDeclarations(); i.hasNext(); ) { + final DeclaratorList d = + ((Declaration) i.next()).getDeclaratorList(); + for (Iterator j = d.getDeclarators(); j.hasNext(); ) { + final Declarator dor = (Declarator) j.next(); + if (dor.getDirection() == Declarator.OUT) { + final IdentifierExpression ident = dor.getIdentifier(); + final Type t = (Type) analysisResults.getIdentToken(ident); + initVar(t, ident, 0, null); + } + } + } + out.println(); + + // csp body + processingBody = true; + decl.getBodyStatement().accept(this); + processingBody = false; + + // end initial block + out.println("end"); + out.println(); + + // end module + out.println("endtask"); + analysisResults = old; + } + + private void outputFunctions(final SequentialStatement initStmt) + throws VisitorException { + final HashSet/*, + String>>*/ seen = + new HashSet/*,String>>*/(); + while (!pendingFunctions.isEmpty()) { + final Triplet/*,String>>*/ t = + (Triplet) pendingFunctions.remove(0); + if (!seen.add(t)) continue; + final FunctionDeclaration decl = (FunctionDeclaration) t.getFirst(); + final List/**/ arrayArg = (List) t.getSecond(); + final String name = (String) t.getThird(); + outputFunction(decl, initStmt, arrayArg, name); + } + } + + private void outputConstructors() throws VisitorException { + final HashSet/*, + String>>*/ seen = + new HashSet/*,String>>*/(); + while (!pendingConstructors.isEmpty()) { + final Triplet/*,String>>*/ t = + (Triplet) pendingConstructors.remove(0); + if (!seen.add(t)) continue; + final StructureDeclaration decl = + (StructureDeclaration) t.getFirst(); + final List/**/ arrayArg = (List) t.getSecond(); + final String name = (String) t.getThird(); + outputConstructor(decl, arrayArg, name); + } + } + + private void outputArbiters() { + for (Iterator i = arbiters.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final String inst = (String) p.getFirst(); + final Integer guards = (Integer) p.getSecond(); + out.println("`CAST2VERILOG_ARBITER #(" + guards + ") " + + inst + "(" + resetNodeName + " );"); + } + } + + private void processFunctionArgument( + final ExpressionInterface arg, + final Collection/**/ realArgs, + final Collection/**/ arrayArgs) + throws VisitorException { + final Type type = analysisResults.getType(arg); + if (type instanceof ArrayType || type instanceof StructureType) { + complexAccess = new ComplexAccess(); + arg.accept(this); + final ComplexAccess mapped = mapComplexArgument(complexAccess); + complexAccess = null; + arrayArgs.add(mapped); + realArgs.addAll(mapped.getIndices()); + } else { + realArgs.add(arg); + } + } + + private void processFunctionCall(final FunctionCallExpression e, + final ExpressionInterface lhs) + throws VisitorException { + final Pair/**/ p = + (Pair) resolver.getResolvedFunctions().get(e); + final Object decl = p == null ? null : p.getSecond(); + String name = null; + if (p == null || RefinementResolver.isBuiltin(decl)) { + final ExpressionInterface func = e.getFunctionExpression(); + if (func instanceof IdentifierExpression) { + name = ((IdentifierExpression) func).getIdentifier(); + name = (String) BUILTIN_FUNCTIONS.get(name); + if (name == null) { + throw new VisitorException( + "Unsupported builtin function at " + + e.getParseRange().fullString()); + } else if (name == "util.display_hex" || name == "wait") { + visitFunctionCallExpression(e); // process builtin funcs + } else if (name == "srandom") { + System.out.println("N.B. srandom() function being skipped"); + } else if (name == "choose" || name == "random" || + name == "string" || name == "log2" || + name == "log4") { + lhs.accept(this); + out.print(" = "); + visitFunctionCallExpression(e); // process builtin funcs + out.println(" ; "); + } + } else { + throw new VisitorException("Call to unknown function at " + + e.getParseRange().fullString()); + } + return; + } + + final Collection realArgs = new ArrayList/**/(); + if (decl instanceof FunctionDeclaration || + decl instanceof StructureDeclaration) { + final List/**/ arrayArg = new ArrayList/**/(); + for (Iterator i = e.getActuals(); i.hasNext(); ) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + processFunctionArgument(arg, realArgs, arrayArg); + } + if (lhs != null) processFunctionArgument(lhs, realArgs, arrayArg); + + if (decl instanceof FunctionDeclaration) { + name = getFullName((FunctionDeclaration) decl, arrayArg); + } else { + name = getFullName((StructureDeclaration) decl, arrayArg); + } + } else { + throw new VisitorException("Call to unknown function at " + + e.getParseRange().fullString()); + } + + out.print(name); + if (!realArgs.isEmpty()) { + out.print("("); + for (Iterator i = realArgs.iterator(); i.hasNext(); ) { + final Object o = i.next(); + if (o instanceof ExpressionInterface) { + ((ExpressionInterface) o).accept(this); + } else { + ((Index) o).write(); + } + if (i.hasNext()) out.print(", "); + } + out.print(")"); + } + out.println(";"); + } + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + final ExpressionInterface rhs = s.getRightHandSide(); + // Here we handle peeks outside of guards as a special case of the rhs of assignments + // because the FunctionPreprocessor transforms peeks outside of guards as + // x = #X? + 0 into temp = #X?; x = temp + 0 + // Peeks inside guards are handled in visitPeekExpressions + if (rhs instanceof PeekExpression) { + // outside guard: #L? == ( [ L.d >= 0 ] ; L.d ) + final ExpressionInterface chanExpr = + ((PeekExpression) rhs).getChannelExpression(); + out.print("wait("); + emitChannelData(chanExpr); + out.println(" >= 0);"); + processAssignmentStatement(s.getLeftHandSide(), rhs, + chanExpr, null); + } else if (rhs instanceof FunctionCallExpression) { + processFunctionCall((FunctionCallExpression) rhs, + s.getLeftHandSide()); + } else { + processAssignmentStatement(s.getLeftHandSide(), rhs, null, s); + } + } + + /** + * Returns true if the guarded statement has one guard + * and no else clause. + **/ + private static boolean hasOneGuard(AbstractGuardedStatement s) { + final Iterator i = s.getGuardedCommands(); + assert i.hasNext(); + i.next(); + return !i.hasNext() && s.getElseStatement() == null; + } + + /** + * Returns number of guards in guarded statement + **/ + private static int numGuards(AbstractGuardedStatement s) { + final Iterator i = s.getGuardedCommands(); + int numGuards = 0; + assert i.hasNext(); + while (i.hasNext()) { + numGuards++; + i.next(); + } + return(numGuards); + } + + public void processSelectionOrRepetition( + final AbstractGuardedStatement s, + final boolean isRepetition, + final boolean isDeterministic) + throws VisitorException { + if (isRepetition && hasOneGuard(s)) { + // Special case the 1 guard case into a simple while loop + final GuardedCommand gc = + (GuardedCommand) s.getGuardedCommands().next(); + out.print("while ("); + gc.getGuard().accept(this); + out.println(") begin"); + gc.getCommand().accept(this); + out.println("end"); + } else { + out.println("begin : " + genBlock()); + final String chosenGuard = "chosen_guard$" + genVarNum(); + out.println("integer " + chosenGuard + ';'); + final String numTrueGuards = "num_true_guards$" + genVarNum(); + out.println("integer " + numTrueGuards + ';'); + + // for non-determistic case declare an array of true guard nums + final int numGuards = numGuards(s); + final String arbiterInst, trueGuards; + if (isDeterministic) { + arbiterInst = null; + trueGuards = "true_guards$" + genVarNum(); + out.println("integer " + trueGuards + + "[0:" + numGuards + " - 1];"); + } else { + arbiterInst = "arbiter$" + genVarNum(); + trueGuards = arbiterInst + ".true_guards"; + arbiters.add(new Pair(arbiterInst, new Integer(numGuards))); + } + + if (!isRepetition || s.getElseStatement() == null) { + // hack around lack of do ... while loop by setting + // chosenGuard to 0 initially + out.println(chosenGuard + " = 0;"); + out.println("while (" + chosenGuard + " != -1) begin"); + } else + out.println("while (1) begin"); + + out.println(chosenGuard + " = -1;"); + out.println(numTrueGuards + " = 0;"); + + + // handle guards + int guardNum = 0; + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommand gc = (GuardedCommand) i.next(); + + out.print("if ("); + gc.getGuard().accept(this); + out.println(')'); + + out.println("begin"); + if (isDeterministic) // remember true guard + out.println(chosenGuard + " = " + guardNum + ';'); + + // trueGuards[numTrueGuards] = guardNum; + out.println(trueGuards + "[" + numTrueGuards + "] = " + + guardNum + ";"); + + out.println(numTrueGuards + " = " + numTrueGuards + "+ 1;"); + out.println("end"); + + ++guardNum; + } + + // emit error checking code for more than 1 guard being true + // in deterministic case + if (isDeterministic) { + out.println("// error checking code"); + out.println("if (" + numTrueGuards + " > 1) begin"); + out.println("`CAST2VERILOG_MULTIPLE_GUARDS_TRUE_ERROR2(\"" + + s.getParseRange().fullString() + "\", " + + numTrueGuards + ", " + trueGuards + ")"); + out.println("end // error checking code"); + } + + // pick guard randomly among true guards + if (!isDeterministic) { + out.println("if (" + numTrueGuards + "> 0)"); + out.println(chosenGuard + " = " + arbiterInst + ".select(" + + numTrueGuards + ");"); + } + + // handle bodies + out.println("case (" + chosenGuard + ')'); + // handle else or do nothing case + out.println("-1 : begin"); + if (s.getElseStatement() != null) { + s.getElseStatement().accept(this); + } else if (!isRepetition) { + // handle case that no guards are true + // REVIEW: This might not be the best way to handle waiting + out.print("wait("); + boolean first = true; + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommand gc = (GuardedCommand) i.next(); + if (!first) + out.print(" || "); + first = false; + gc.getGuard().accept(this); + } + out.println(");"); + + // HACK: stay in loop by setting chosenGuard to 0 + out.println(chosenGuard + " = 0;"); + } + out.println("end"); + // handle other bodies + guardNum = 0; + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommand gc = (GuardedCommand) i.next(); + out.println(guardNum + " : begin"); + gc.getCommand().accept(this); + if (!isRepetition) { + // HACK: end loop by setting chosenGuard to -1 + out.println(chosenGuard + " = -1;"); + } + out.println("end"); + + ++guardNum; + } + out.println("endcase"); + + out.println("end"); + out.println("end"); + } + } + + + public void visitDeterministicRepetitionStatement( + DeterministicRepetitionStatement s) + throws VisitorException { + processSelectionOrRepetition(s, true, true); + } + + + public void visitDeterministicSelectionStatement( + DeterministicSelectionStatement s) + throws VisitorException { + processSelectionOrRepetition(s, false, true); + } + + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + final ExpressionInterface expr = s.getExpression(); + if (expr instanceof FunctionCallExpression) { + processFunctionCall((FunctionCallExpression) expr, null); + return; + } + unsupported(s); + } + + public void visitLoopStatement(LoopStatement s) throws VisitorException { + // Only sequential loops are translated directly; parallel loops is + // only handled via loop unrolling + if (s.getSeparator() == LoopStatement.SEQUENTIAL) { + out.println("begin : " + genBlock()); + final String loopMax = "loopMax$" + genVarNum(); + out.println(registerType + " " + loopMax + ";"); + out.print(loopMax + " = "); + s.getRange().getMaxExpression().accept(this); + out.println(" ;"); + + out.print("for ("); + s.getIndexVarExpression().accept(this); + out.print("="); + s.getRange().getMinExpression().accept(this); + out.print(" ; "); + s.getIndexVarExpression().accept(this); + out.print(" <= " + loopMax + " ; "); + s.getIndexVarExpression().accept(this); + out.print("="); + s.getIndexVarExpression().accept(this); + out.println(" + 1) begin "); + s.getStatement().accept(this); + out.println("end"); + out.println("end"); + } else { + throw new VisitorException("Range not compile time constants in loop at " + s.getParseRange().fullString()); + } + } + + public void visitNonDeterministicRepetitionStatement( + NonDeterministicRepetitionStatement s) + throws VisitorException { + unsupported(s); + } + + + public void visitNonDeterministicSelectionStatement( + NonDeterministicSelectionStatement s) + throws VisitorException { + /* Through exception on else. Currently this also causes a grammer exception */ + if (s.getElseStatement() != null) { + throw new AssertionError("Else in non-deterministic selection not supported"); + } + processSelectionOrRepetition(s, false, false); + } + + public void visitLinkageLoopTerm(final LinkageLoopTerm term) + throws VisitorException { + unsupported(term); + } + + public void visitLinkageExpressionTerm(final LinkageExpressionTerm term) + throws VisitorException { + unsupported(term); + } + + public void visitLinkageArrayAccessExpression( + final LinkageArrayAccessExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitLinkageIdentifierExpression( + final LinkageIdentifierExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitLinkageStructureAccessExpression( + final LinkageStructureAccessExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + out.println("fork"); + + for (Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + + out.println("begin"); + + // emit the parallel code + stmt.accept(this); + + out.println("end"); + } + + out.println("join"); + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + // This expansion requires slack of at least 1 to get probe + // sends to behave properly. + // L?x == ( [ L.d >= 0 ] ; x = L.d ; L.e = 0 + // ; [ L.d < 0 ] ; L.e = 1 ) + // Good test cases include: + // 1. L[getTime() % N]?x + // 2. L[x]?x + // These will ensure channel is evaluated only once + + final ExpressionInterface chanExpr = s.getChannelExpression(); + + out.print("wait("); + emitChannelData(chanExpr); + out.println(" >= 0);"); + + if (s.getRightHandSide() != null) + processAssignmentStatement(s.getRightHandSide(), + s.getRightHandSide(), chanExpr, + null); + + emitChannelEnable(chanExpr); + out.println(" = 0;"); + + out.print("wait("); + emitChannelData(chanExpr); + out.println(" < 0);"); + + emitChannelEnable(chanExpr); + out.println(" = 1;"); + } + + public void visitSendStatement(SendStatement s) + throws VisitorException { + // R!x == ( [ R.e ] ; R.d = POSMOD(x, numValues) + // ; [ !R.e ] ; R.d = -1 ) + // Good test cases include: + // 1. R[getTime() % N]!x + // This will ensure channel is evaluated only once + + final ExpressionInterface chanExpr = s.getChannelExpression(); + + // The type checking pass should have ensured that this is indeed + // a channel type and that the direction is appropriate + final ChannelType type = + (ChannelType) analysisResults.getType(chanExpr); + assert type.getDirection() == PortDirection.OUT; + final BigInteger numValues = type.getNumValues(); + assert numValues.signum() == 1; + + out.print("wait("); + emitChannelEnable(chanExpr); + out.println(");"); + + emitChannelData(chanExpr); + out.print(" = util.posmod("); + s.getRightHandSide().accept(this); + out.println(", "); + processBigInteger(numValues, 16); + out.println(");"); + + out.print("wait(!"); + emitChannelEnable(chanExpr); + out.println(");"); + + emitChannelData(chanExpr); + out.println(" = -1;"); + } + + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + for (final Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + stmt.accept(this); + if (processingBody) { + out.println("`ifdef CAST2VERILOG_DEBUG_DELAY"); + out.println("#(`CAST2VERILOG_DEBUG_DELAY);"); + out.println("`endif"); + } + } + } + + public void visitErrorStatement(ErrorStatement s) + throws VisitorException { + out.println("`CAST2VERILOG_CSP_ERROR(\"" + + s.getParseRange().fullString() + "\")"); + } + + public void visitSkipStatement(SkipStatement s) + throws VisitorException { + // do nothing + } + + private void declareType(final Type t, + final ComplexDeclaration decl, + final Collection/**/ results) + throws VisitorException { + if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + decl.declareArray(at.getRange()); + declareType(at.getElementType(), decl, results); + } else if (t instanceof IntegerType || t instanceof BooleanType || + t instanceof StringType) { + decl.setType(t); + results.add(decl); + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + // VariableAnalyzer should have made sure all structures are valid + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexDeclaration cdecl = + new ComplexDeclaration(decl); + cdecl.declareStructure(d.getIdentifier().getIdentifier()); + declareType(d.getTypeFragment(), cdecl, results); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Unsupported type: " + t); + } + } + + private void declareVariable(final String id, final Type t) + throws VisitorException { + declareVariable("", id, t, ";"); + out.println(";"); + } + + private void declareVariable(final String inout, final String id, + final Type t, final String delim) + throws VisitorException { + final Collection/**/ results = + new ArrayList/**/(); + final ComplexDeclaration decl = new ComplexDeclaration(); + declareType(t, decl, results); + + arrayDeclRange = true; + // just emit declaration + for (Iterator i = results.iterator(); i.hasNext(); ) { + final ComplexDeclaration cdecl = (ComplexDeclaration) i.next(); + out.print(inout); + cdecl.declare(id); + if (i.hasNext()) out.println(delim); + } + arrayDeclRange = false; + } + + private Map/**/ tokenVerilogNameMap = + new HashMap/**/(); + private Map/**/ lastVerilogTokenMap = + new HashMap/**/(); + private Map/**/ hierarchyNameMap = + new HashMap/**/(); + private void updateTokenVerilogMap(final String hierarchy) { + lastVerilogTokenMap.clear(); + final Map/**/ tokenIdentMap = + analysisResults.getTokenIdentMap(); + final Set/**/ initializerTokens = + analysisResults.getInitializerTokens(); + final HashCounter counter = new HashCounter(); + for (Iterator i = tokenIdentMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry/**/ entry = (Map.Entry) i.next(); + final Type type = (Type) entry.getKey(); + final String id = (String) entry.getValue(); + final int count = counter.getCount(id); + counter.add(id); + final String realId = id + (count == 0 ? "" : "$$" + count); + tokenVerilogNameMap.put(type, realId); + // ChannelTypes and ChannelStructureTypes cannot be passed to + // functions as arguments, and therefore can only be accessed if + // they are in the cell's port list. The cell ports translate to + // module ports, which are visible to tasks defined in the module, + // so we do not need to do anything to them. + Type baseType = type; + while (baseType instanceof ArrayType) + baseType = ((ArrayType) baseType).getElementType(); + if ((baseType instanceof IntegerType || + baseType instanceof BooleanType || + baseType instanceof StringType || + baseType instanceof StructureType) && + !initializerTokens.contains(type)) + lastVerilogTokenMap.put(type, realId); + hierarchyNameMap.put(type, hierarchy); + } + } + + private void declareVariables() throws VisitorException { + for (Iterator i = lastVerilogTokenMap.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry/**/ entry = (Map.Entry) i.next(); + declareVariable((String) entry.getValue(), (Type) entry.getKey()); + } + } + + private void initVar(final Type t, final IdentifierExpression ident, + final int dims, final ExpressionInterface init) + throws VisitorException { + complexAccess = new ComplexAccess(); + ident.accept(this); + final ComplexAccess access = complexAccess; + complexAccess = null; + initVar(t, access, dims, init); + } + + private void initVar(final Type t, final ComplexAccess ident, + final int dims, final ExpressionInterface init) + throws VisitorException { + if (t instanceof IntegerType || t instanceof BooleanType) { + ident.write(); + out.print(" = "); + if (init == null) out.print('0'); + else init.accept(this); + out.println(";"); + } else if (t instanceof StringType) { + ident.write(); + out.print(" = "); + if (init == null) out.print("csp_string.init($bits(\"\"),\"\")"); + else init.accept(this); + out.println(";"); + } else if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + out.println("begin : " + genBlock()); + final String var = "loop$" + dims; + out.println(registerType + " " + var + ";"); + emitForLoop(var, at.getRange()); + out.println(" begin"); + ident.accessArray(var); + initVar(at.getElementType(), ident, dims + 1, init); + out.println("end"); + out.println("end"); + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nident = new ComplexAccess(ident); + nident.accessStructure(d.getIdentifier().getIdentifier()); + initVar(d.getTypeFragment(), nident, dims + 1, + d.getInitializer()); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Cannot initialize type: " + t); + } + } + + public void visitVarStatement(VarStatement s) + throws VisitorException { + for (Iterator i = s.getDeclarationList().getDeclarations(); + i.hasNext(); ) { + final Declaration declaration = (Declaration) i.next(); + + for (Iterator j = + declaration.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator declarator = (Declarator) j.next(); + final Type t = declarator.getTypeFragment(); + + // declaration has been emitted at top of block by + // declareVariables(), just assign here + initVar(t, declarator.getIdentifier(), 0, + declarator.getInitializer()); + } + } + + // only support new style declarations + assert s.getStatement() == null; + } + + public void visitArrayType(ArrayType t) + throws VisitorException { + unsupported(t); + } + + public void visitChannelType(ChannelType t) + throws VisitorException { + unsupported(t); + } + + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + unsupported(t); + } + + public void visitIntegerType(IntegerType t) + throws VisitorException { + unsupported(t); + } + + public void visitBooleanType(BooleanType t) + throws VisitorException { + unsupported(t); + } + + public void visitNodeType(NodeType t) + throws VisitorException { + unsupported(t); + } + + public void visitStringType(StringType t) throws VisitorException { + unsupported(t); + } + + public void visitStructureType(StructureType t) + throws VisitorException { + unsupported(t); + } + + public void visitIdentifierList(IdentifierList il) + throws VisitorException { + unsupported(il); + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + unsupported(s); + } + + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + unsupported(s); + } + + private void unsupported(AbstractASTNode n) throws VisitorException { + throw new VisitorException("CSP construct not yet supported at " + + n.getParseRange().fullString()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/VerilogEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/VerilogEmitter.java new file mode 100644 index 0000000000..93dff1cfff --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2verilog/VerilogEmitter.java @@ -0,0 +1,2281 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.csp2verilog; + +import java.io.PrintWriter; +import java.io.Writer; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import com.avlsi.cell.CellUtils; +import com.avlsi.csp.ast.*; +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.csp.util.DeclarationProcessor; +import com.avlsi.csp.util.FilterInitializers; +import com.avlsi.csp.util.RefinementResolver; +import com.avlsi.csp.util.ProblemFilter; +import com.avlsi.csp.util.UniqueLabel; +import com.avlsi.csp.util.VariableAnalysisException; +import com.avlsi.csp.util.VariableAnalyzer; +import com.avlsi.fast.metaparameters.ArrayMetaParam; +import com.avlsi.fast.metaparameters.BooleanMetaParam; +import com.avlsi.fast.metaparameters.IntegerMetaParam; +import com.avlsi.fast.metaparameters.MetaParamDefinition; +import com.avlsi.fast.metaparameters.MetaParamTypeInterface; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.tools.prs2verilog.verilog.VerilogUtil; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.HashCounter; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.math.BigIntegerUtil; +import com.avlsi.util.text.StringUtil; + +/** + * Visitor pattern to emit Verilog from csp. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class VerilogEmitter extends CommonEmitter { + private final CSPCellInfo cellInfo; + + private final Collection/**/ inputPorts; + + // State needed for traversal + private final PrintWriter debugWriter; + + private final PrintWriter warningWriter; + + private final PrintWriter errorWriter; + + /** + * The type of register to use for boolean variables. + **/ + private final String boolType; + + /** + * The name of reset signal + **/ + private final String resetNodeName; + + /** + * Autogenerated variable number. + **/ + private int varNum = 0; + + private int blockNum = 0; + + private final VariableAnalyzer analyzer; + + private VariableAnalyzer.Results analysisResults; + + private RefinementResolver resolver = + new RefinementResolver(RefinementResolver.NAME); + + private ComplexAccess complexAccess = null; + + private final UniqueLabel labels = new UniqueLabel(new HashMap()); + + /** + * true if we are processing the body of a program or a + * function; false if we are processing initializers. + **/ + private boolean processingBody = false; + + /** Special character escape sequences to use in string literals */ + private static Map ESCAPE_MAP = CollectionUtils.mapify( + new Object[] { + new Character('\n'), "\\n", + new Character('\t'), "\\t" + }); + + private final LinkedList/*, + String>>*/ pendingFunctions = + new LinkedList/*, + String>>*/(); + private final List/*, + String>>*/ pendingConstructors = + new ArrayList/*, + String>>*/(); + + private final List/*>*/ arbiters = + new ArrayList/*>*/(); + + private final Set lvalues = + new HashSet(); + + private final boolean strictVars; + + private final boolean implicitInit; + + private int scope = 0; + + private final ProblemFilter problems; + + private interface Index { + void write() throws VisitorException; + } + private class ComplexAccess { + private class FixedIndex implements Index { + private final String var; + public FixedIndex(final String var) { + this.var = var; + } + public void write() throws VisitorException { + out.print(var); + } + } + private class ExpressionIndex implements Index { + private final ExpressionInterface expr; + public ExpressionIndex(final ExpressionInterface expr) { + this.expr = expr; + } + public void write() throws VisitorException { + expr.accept(VerilogEmitter.this); + } + } + + private final LinkedList/**/ array; + private final LinkedList/**/ structure; + private final Type ty; + private Object base; + public ComplexAccess() { + this((Type) null); + } + public ComplexAccess(final ExpressionInterface expr) { + this(lvalues.contains(expr) ? (Type) null + : analysisResults.getType(expr)); + } + public ComplexAccess(final Type ty) { + this.array = new LinkedList/**/(); + this.structure = new LinkedList/**/(); + this.ty = ty; + } + public ComplexAccess(final ComplexAccess other) { + this.array = new LinkedList/**/(other.array); + this.structure = new LinkedList/**/(other.structure); + this.base = other.base; + this.ty = other.ty; + } + private void accessArray(final Index idx, final boolean forward) { + if (forward) array.addLast(idx); + else array.addFirst(idx); + } + public void accessArray(final String var) { + accessArray(new FixedIndex(var), true); + } + public void accessArray(final ExpressionInterface expr) { + accessArray(new ExpressionIndex(expr), false); + } + public void accessStructure(final String fieldName) { + accessStructure(fieldName, true); + } + public void accessStructure(final String fieldName, + final boolean forward) { + if (forward) structure.addLast(fieldName); + else structure.addFirst(fieldName); + } + public Object getBase() { + return base; + } + public void setBase(final Object token) { + base = token; + } + private void emit(final String hierarchy, + final String channelPart, + final Type ty) throws VisitorException { + final StringBuffer buf = new StringBuffer(); + String concat = null; + if (ty instanceof IntegerType) { + final IntegerType it = (IntegerType) ty; + if (it.getDeclaredWidth() != null) { + final int width = getIntegerConstant(it.getDeclaredWidth()); + if (it.isSigned()) { + buf.append("(util.sign_extend("); + concat = "))"; + } else { + buf.append("($signed({ "); + buf.append(Math.max(1, registerBitWidth - width)); + buf.append("'b0, "); + concat = " }))"; + } + } + } else if (ty instanceof NodeType) { + final NodeType nt = (NodeType) ty; + if (nt.isArrayed()) { + buf.append("($signed({ "); + buf.append(Math.max(1, registerBitWidth - nt.getWidth())); + buf.append("'b0, "); + concat = " }))"; + } + } + + buf.append(hierarchy); + buf.append("\\"); + buf.append((String) tokenVerilogNameMap.get(base)); + for (Iterator i = structure.iterator(); i.hasNext(); ) { + buf.append('.'); + buf.append((String) i.next()); + } + buf.append(channelPart); + out.print(buf.toString()); + out.print(' '); + for (Iterator i = array.iterator(); i.hasNext(); ) { + out.print("["); + ((Index) i.next()).write(); + out.print("]"); + } + if (concat != null) { + out.print(concat); + } + } + public void write(final String channelPart) throws VisitorException { + final ComplexAccess mapped = mapComplexArgument(this); + String hierarchy = mapped.getHierarchy(); + if (hierarchy != null && getHierarchy() == hierarchy) + hierarchy = null; + mapped.emit(hierarchy == null ? "" : escape(hierarchy) + ".", + channelPart, ty); + } + public void write() throws VisitorException { + write(""); + } + public Collection getIndices() { + return array; + } + public ComplexAccess map(final ComplexAccess previous) { + if (previous == null) return this; + + final ComplexAccess result = new ComplexAccess(previous.ty); + result.array.addAll(previous.array); + result.array.addAll(array); + result.structure.addAll(previous.structure); + result.structure.addAll(structure); + result.base = previous.base; + return result; + } + public void copyStructure(final ComplexAccess other) { + structure.clear(); + structure.addAll(other.structure); + } + public String getHierarchy() { + return (String) hierarchyNameMap.get(base); + } + } + + private class ComplexDeclaration { + private final List/**/ array; + private final List/**/ structure; + private Type type; + public ComplexDeclaration() { + this.array = new ArrayList/**/(); + this.structure = new ArrayList/**/(); + } + public ComplexDeclaration(final ComplexDeclaration c) { + this.array = new ArrayList/**/(c.array); + this.structure = new ArrayList/**/(c.structure); + this.type = c.type; + } + public void declareArray(final Range expr) { + array.add(expr); + } + public void declareStructure(final String fieldName) { + structure.add(fieldName); + } + public void setType(final Type type) { + this.type = type; + } + private String getStructurePart(final String base) { + final StringBuffer buf = new StringBuffer(); + buf.append(base); + for (Iterator i = structure.iterator(); i.hasNext(); ) { + buf.append('.'); + buf.append((String) i.next()); + } + return escape(buf.toString()); + } + public void declare(final String base) throws VisitorException { + if (type instanceof StringType) { + out.print("`CSP_STRING "); + } else if (type instanceof BooleanType) { + out.print(boolType); out.ws(); + } else { + out.print(getRegisterType((IntegerType) type)); out.ws(); + } + out.print(getStructurePart(base)); + for (Iterator i = array.iterator(); i.hasNext(); ) { + final Range r = (Range) i.next(); + out.print('['); + r.getMinExpression().accept(VerilogEmitter.this); + out.print(':'); + r.getMaxExpression().accept(VerilogEmitter.this); + out.print(']'); + } + } + private String getIndices() throws VisitorException { + final StringBuffer buf = new StringBuffer(); + int idx = 0; + for (Iterator i = array.iterator(); i.hasNext(); ++idx) { + buf.append("[loop$[" + idx + "]]"); + } + return buf.toString(); + } + } + + private String getLoopVarType(final Range r) { + final ExpressionInterface minExpr = r.getMinExpression(); + final ExpressionInterface maxExpr = r.getMaxExpression(); + if (minExpr instanceof IntegerExpression && + maxExpr instanceof IntegerExpression) { + BigInteger min = new BigInteger( + ((IntegerExpression) minExpr).getValue(), + ((IntegerExpression) minExpr).getRadix()); + BigInteger max = new BigInteger( + ((IntegerExpression) maxExpr).getValue(), + ((IntegerExpression) maxExpr).getRadix()); + max = max.add(BigInteger.ONE); + if (min.signum() == -1) min = min.negate(); + if (max.signum() == -1) max = max.negate(); + int lindex = Math.max(min.bitLength(), max.bitLength()); + return "bit signed [" + lindex + ":0]"; + } else { + return registerType; + } + } + + private void emitForLoop(final String var, final Range r) + throws VisitorException { + out.print("for (" + var + " = "); + r.getMinExpression().accept(this); + out.print(';'); out.ws(); out.print(var + " <= "); + r.getMaxExpression().accept(this); + out.print(';'); out.ws(); out.print(var + " = " + var + " + 1)"); + } + + private void emitChannelPart(final ExpressionInterface chanExpr, + final String part) throws VisitorException { + complexAccess = new ComplexAccess(); + chanExpr.accept(this); + final ComplexAccess old = complexAccess; + complexAccess = null; + old.write(part); + } + + private void emitChannelEnable(final ExpressionInterface chanExpr) + throws VisitorException { + emitChannelPart(chanExpr, "$enable"); + } + + private void emitChannelData(final ExpressionInterface chanExpr) + throws VisitorException { + emitChannelPart(chanExpr, "$data"); + } + + public VerilogEmitter(final CSPCellInfo cellInfo, + final Collection/**/ inputPorts, + final PrintWriter out, + final PrintWriter warningWriter, + final PrintWriter errorWriter, + final PrintWriter debugWriter, + final String resetNodeName, + final int registerBitWidth, + final boolean strictVars, + final boolean implicitInit, + final ProblemFilter problems) { + super(out, registerBitWidth); + this.cellInfo = cellInfo; + this.inputPorts = inputPorts; + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.analyzer = new VariableAnalyzer(cellInfo); + this.analysisResults = null; + this.boolType = "bit"; + this.resetNodeName = resetNodeName; + this.strictVars = strictVars; + this.implicitInit = implicitInit; + this.problems = problems; + } + + private void processUnary(final AbstractUnaryExpression expr, + final String op) throws VisitorException { + out.print('(' + op); + expr.getExpression().accept(this); + out.print(')'); + } + + private void processSpecialBinary(final AbstractBinaryExpression expr, + final String func) + throws VisitorException { + // REVIEW: What is the overhead of functions? Should we + // do this inline with a temporary variable? + out.print(func + '('); + lvalues.add(expr.getLeft()); + expr.getLeft().accept(this); + out.print(','); out.ws(); + lvalues.add(expr.getRight()); + expr.getRight().accept(this); + out.print(')'); + } + + private void prettyMessage(String message, ParseRange pr) { + ExceptionPrettyPrinter.prettyMessage(message, pr.start.filename, + pr.start.line, pr.start.column+1, + errorWriter); + } + + /** + * Inspect the sets of uninitialized variables returned by variable + * analysis. + **/ + private Set/**/ processResults(VariableAnalyzer.Results r) { + final Set/**/ undeclaredVars = new HashSet/**/(); + Map m = r.getUndeclaredTypes(); + for (final Iterator i = m.keySet().iterator(); i.hasNext(); ) { + String name = (String) i.next(); + Type type = (Type) m.get(name); + + if (type == null + || type instanceof IntegerType + || type instanceof BooleanType) + undeclaredVars.add(name); + else { + errorWriter.flush(); + warningWriter.flush(); + throw new Error ("Undeclared variable has unsupported type."); + } + } + + return undeclaredVars; + } + + private void outputProgramBody(CSPProgram e) throws VisitorException { + declareVariables(); + + // call resetNodes() if it is defined + final Pair/**/ resetDecl = + (Pair) resolver.getResolvedFunctions() + .get(RefinementResolver.RESET_FUNCTION_CALL); + if (resetDecl != null) { + if (resetDecl.getSecond() instanceof FunctionDeclaration) { + out.println("always @(" + resetNodeName + " )"); + out.println("if (" + resetNodeName + " == 0) " + + "begin : reset_nodes"); + final String funcName = + getFullName((FunctionDeclaration) resetDecl.getSecond(), + Collections.EMPTY_LIST); + out.println(funcName + " ;"); + out.println("end"); + } else { + warningWriter.println( + "Invalid definition of special function resetNodes: " + + ((AbstractASTNode) e).getParseRange().fullString()); + + } + } + + // start main block on posedge of _RESET + out.println("always @(posedge " + resetNodeName + " )"); + out.println("begin : main "); + + final Set/**/ undeclaredVars = processResults(analysisResults); + // assign to 0 + if (implicitInit) { + for (Iterator i = undeclaredVars.iterator(); i.hasNext(); ) { + final String var = escape((String) i.next()); + out.println(var + " = 0;"); + } + out.println(); + } + + // handle initializer statement to deal with top-level constants + // TODO: Share top-level constants, as this wastes memory + if (e.getInitializerStatement() != null) { + final FilterInitializers filter = + new FilterInitializers(analysisResults, allUsedTokens); + filter.filter(e.getInitializerStatement()).accept(this); + } + + // csp body + processingBody = true; + e.getStatement().accept(this); + processingBody = false; + + // end initial block + out.println("end"); + out.println(); + } + + public void visitCSPProgram(CSPProgram e) throws VisitorException { + + resolver.resolve(e); + e = resolver.getCSPProgram(); + + // declare and initialize the undeclared variables + try { + analysisResults = analyzer.getResults(e, resolver); + allUsedTokens.addAll(analysisResults.getUsedTokens()); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage()); + } + problems.process(analysisResults.getErrors(strictVars)); + + for (Iterator i = e.getFunctionDeclarations(); i.hasNext(); ) { + final FunctionDeclaration decl = (FunctionDeclaration) i.next(); + try { + getAnalyzerResults(decl, e.getInitializerStatement()); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + } + + if (!problems.hasError()) { + updateTokenVerilogMap(null); + outputProgramBody(e); + outputFunctions(e.getInitializerStatement()); + outputConstructors(); + outputArbiters(); + } + + out.flush(); + } + + /** + * Return a new autogenerated variable number. + **/ + private int genVarNum() { + return varNum++; + } + + private String genBlock() { + return "\\$block" + blockNum++ + ' '; + } + + public void visitAddExpression(AddExpression e) + throws VisitorException { + if (analysisResults.getType(e) instanceof StringType) { + out.print("csp_string.concat("); + final boolean lstr = + analysisResults.getType(e.getLeft()) instanceof StringType; + if (!lstr) out.print("util.csp_string("); + e.getLeft().accept(this); + if (!lstr) out.print(", 10)"); + + out.print(", "); + + final boolean rstr = + analysisResults.getType(e.getRight()) instanceof StringType; + if (!rstr) out.print("util.csp_string("); + e.getRight().accept(this); + if (!rstr) out.print(", 10)"); + + out.print(')'); + } else { + processBinary(e, "+"); + } + } + + public void visitAndExpression(AndExpression e) + throws VisitorException { + processBinary(e, "&"); + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + boolean writeNow = false; + if (complexAccess == null) { + complexAccess = new ComplexAccess(e); + writeNow = true; + } + complexAccess.accessArray(e.getIndexExpression()); + e.getArrayExpression().accept(this); + if (writeNow) { + final ComplexAccess old = complexAccess; + complexAccess = null; + old.write(); + } + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + // The csp grammar only allows bit extraction from arrays, + // structures and simple variables. + assert e.getBitsExpression() instanceof IdentifierExpression || + e.getBitsExpression() instanceof ArrayAccessExpression || + e.getBitsExpression() instanceof MemberAccessExpression: + "Invalid bit range expression found at: " + e.getParseRange().fullString(); + + lvalues.add(e.getBitsExpression()); + if (needBitRangeFunction(e)) { + // can't use constant part-select, use special function + out.print("util.bit_extract" + + (e.getMinExpression() == null ? "2" : "3") + + "("); + e.getBitsExpression().accept(this); + out.print(','); out.ws(); + lvalues.add(e.getMaxExpression()); + e.getMaxExpression().accept(this); + if (e.getMinExpression() != null) { + out.print(','); out.ws(); + lvalues.add(e.getMinExpression()); + e.getMinExpression().accept(this); + } + out.print(')'); + } else { + processSimpleBitRange(e, false); + } + } + + private void printArg(final ExpressionInterface arg) + throws VisitorException { + lvalues.add(arg); + if (analysisResults.getType(arg) instanceof StringType) { + arg.accept(this); + } else { + out.print("util.hex_string("); + arg.accept(this); + out.print(")"); + } + } + + /* Process built in functions - all others are turned into assignmented + by processFunctionCalls */ + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + final ExpressionInterface func = e.getFunctionExpression(); + final String funcName = + func instanceof IdentifierExpression ? + ((IdentifierExpression) func).getIdentifier() : null; + + if ("print".equals(funcName)) { + final Iterator args = e.getActuals(); + final ExpressionInterface arg1 = args.next(); + final ExpressionInterface arg2 = + args.hasNext() ? args.next() : null; + + if (arg2 == null) { + out.print("`CAST2VERILOG_CSP_PRINT("); + printArg(arg1); + } else { + out.print("`CAST2VERILOG_CSP_PRINT2("); + printArg(arg1); + out.print(", "); + printArg(arg2); + } + out.println(")"); + return; + } else if ("assert".equals(funcName)) { + final Iterator args = e.getActuals(); + final ExpressionInterface guard = (ExpressionInterface) args.next(); + lvalues.add(guard); + final ExpressionInterface message = + args.hasNext() ? (ExpressionInterface) args.next() + : null; + if (message != null) lvalues.add(message); + + out.print("`CAST2VERILOG_CSP_ASSERT" + + (message == null ? "" : "2") + "(\"" + + e.getParseRange().fullString() + "\", "); + guard.accept(this); + if (message != null) { + out.print(','); out.ws(); + message.accept(this); + } + out.println(")"); + return; + } else if ("choose".equals(funcName)) { + Iterator i = e.getActuals(); + // XXX: Add null exception handling + ExpressionInterface arg = (ExpressionInterface) i.next(); + lvalues.add(arg); + arg.accept(this); + out.ws(); out.print('?'); out.ws(); + arg = (ExpressionInterface) i.next(); + lvalues.add(arg); + arg.accept(this); + out.ws(); out.print(':'); out.ws(); + arg = (ExpressionInterface) i.next(); + lvalues.add(arg); + arg.accept(this); + return; + } else if ("random".equals(funcName) || + "log2".equals(funcName) || + "log4".equals(funcName)) { + Iterator i = e.getActuals(); + out.print("util." + funcName + "("); + final ExpressionInterface arg = (ExpressionInterface) i.next(); + lvalues.add(arg); + arg.accept(this); + out.println(")"); + return; + } else if ("wait".equals(funcName)) { + final Iterator i = e.getActuals(); + out.print("#(("); + final ExpressionInterface arg = (ExpressionInterface) i.next(); + lvalues.add(arg); + arg.accept(this); + // divide by 100 to change from DSim units to transitions + out.println(") * `PRS2VERILOG_TAU / 100);"); + return; + } else if ("string".equals(funcName)) { + out.print("util.csp_string("); + for (Iterator i = e.getActuals(); i.hasNext(); ) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + lvalues.add(arg); + arg.accept(this); + if (i.hasNext()) { out.ws(); out.print(','); out.ws(); } + } + out.println(")"); + return; + } else if ("time".equals(funcName)) { + out.println("`CAST2VERILOG_TIME"); + return; + } + throw new VisitorException("Unsupported function calls found: " + e.getParseRange().fullString()); + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + // Handle divide by 0 + processSpecialBinary(e, "util.divide"); + } + + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + // XXX: handle 0**x, for x <= 0 + // According to the verilog spec exponentiation involving + // signed values should give a real result. Reals are + // rounded to nearest, except ties are rounded away from zero. + // Thus, we should have 2**-1 == 1, but it seems that 2**-1 == 0. + // Perhaps file a bug with cadence. + processSpecialBinary(e, "util.pow"); + } + + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + // handles negative shift amounts + processSpecialBinary(e, "util.shift_left"); + } + + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + // handles negative shift amounts + processSpecialBinary(e, "util.shift_right"); + } + + private String escape(final String s) { + return VerilogUtil.escapeIfNeeded(s); + } + + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + if (complexAccess == null) { + complexAccess = new ComplexAccess(e); + complexAccess.setBase(analysisResults.getIdentToken(e)); + complexAccess.write(); + complexAccess = null; + } else complexAccess.setBase(analysisResults.getIdentToken(e)); + } + + public void visitLoopExpression(LoopExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + processBinary(e, "*"); + } + + public void visitNegateExpression(NegateExpression e) + throws VisitorException { + processUnary(e, "-"); + } + + public void visitNotExpression(NotExpression e) + throws VisitorException { + processUnary(e, "~"); + } + + public void visitOrExpression(OrExpression e) + throws VisitorException { + processBinary(e, "|"); + } + + public void visitXorExpression(XorExpression e) + throws VisitorException { + processBinary(e, "^"); + } + + public void visitPeekExpression(PeekExpression e) + throws VisitorException { + // inside guard: #L? == L.d + // outside guard: #L? == ( [ L.d >= 0 ] ; L.d ) + // FunctionPreprocessor converts peeks outside of guards + // to assignment statements that are handled specially + // in this file by visitAssignmentStatement + // It converts peeks within guards by pre-pending AND of + // probes to the expression. + // Thus, here, we just need to spit L.d + emitChannelData(e.getChannelExpression()); + } + + public void visitProbeExpression(ProbeExpression e) + throws VisitorException { + // #L == (L.d >= 0) + // #R == R.e + + final ExpressionInterface chanExpr = e.getChannelExpression(); + // The type checking pass should have ensured that this is indeed + // a channel type. + final ChannelType type = + (ChannelType) analysisResults.getType(chanExpr); + // Add - to compensate for difference in verilog and csp + // comparison semantics. + if (type.getDirection() == PortDirection.IN) { + out.print("("); + emitChannelData(chanExpr); + out.println(" >= 0)"); + } else { + assert type.getDirection() == PortDirection.OUT; + emitChannelEnable(chanExpr); + } + } + + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + // handle x % 0 + processSpecialBinary(e, "util.remainder"); + } + + private void processString(String s) { + final String esc = + '"' + StringUtil.quoteASCIIString(s, ESCAPE_MAP) + '"'; + out.print("csp_string.init($bits(" + esc + "),"); out.ws(); + out.print(esc + ")"); + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + processString(e.getValue()); + } + + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + processBinary(e, "-"); + } + + private void processStructureAccess(final String field, + final ExpressionInterface structExpr, + final ExpressionInterface accessExpr) + throws VisitorException { + boolean writeNow = false; + if (complexAccess == null) { + complexAccess = new ComplexAccess(accessExpr); + writeNow = true; + } + complexAccess.accessStructure(field, false); + structExpr.accept(this); + if (writeNow) { + final ComplexAccess old = complexAccess; + complexAccess = null; + old.write(); + } + } + + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + processStructureAccess(e.getFieldName(), e.getStructureExpression(), e); + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + processStructureAccess(e.getMemberName(), e.getStructureExpression(), + e); + } + + private void processBooleanChannel(ExpressionInterface chanExpr, + ExpressionInterface rhs) + throws VisitorException { + if (chanExpr == null) rhs.accept(this); + else { + final boolean bool = + analysisResults.getType(rhs) instanceof BooleanType; + if (bool) out.print("("); + emitChannelData(chanExpr); + if (bool) out.print("!= 0)"); + } + } + + /** + * Emit code to assign between two variables of the same type. + * + * @param lhs Left hand expression + * @param rhs Right hand expression + * @param t type of the expressions + **/ + private void emitAssignment(final ComplexAccess lhs, + final ComplexAccess rhs, final Type t) + throws VisitorException { + emitAssignment(lhs, rhs, t, 0); + } + + private void emitAssignment(final ComplexAccess lhs, + final ComplexAccess rhs, final Type t, + final int indices) throws VisitorException { + if (t instanceof IntegerType || t instanceof BooleanType || + t instanceof StringType) { + lhs.write(); + out.ws(); out.print('='); out.ws(); + rhs.write(); + out.println(";"); + } else if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + out.println("begin : " + genBlock()); + final String var = "loop$" + indices; + out.println(getLoopVarType(at.getRange()) + " " + var + ";"); + emitForLoop(var, at.getRange()); + out.println(" begin"); + lhs.accessArray(var); + rhs.accessArray(var); + emitAssignment(lhs, rhs, at.getElementType(), indices + 1); + out.println("end"); + out.println("end"); + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nlhs = new ComplexAccess(lhs); + final ComplexAccess nrhs = new ComplexAccess(rhs); + final String id = d.getIdentifier().getIdentifier(); + nlhs.accessStructure(id); + nrhs.accessStructure(id); + emitAssignment(nlhs, nrhs, d.getTypeFragment(), indices); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Cannot assign between: " + t); + } + } + + private void emitPack(final ComplexAccess expr, final Type t) + throws VisitorException { + if (t instanceof BooleanType) { + expr.write(); + } else if (t instanceof IntegerType) { + final IntegerType it = (IntegerType) t; + final int width = getIntegerConstant(it.getDeclaredWidth()) - 1; + expr.write(); + out.print("[" + width + ":0]"); + } else if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + final Range r = at.getRange(); + final int min = getIntegerConstant(r.getMinExpression()); + final int max = getIntegerConstant(r.getMaxExpression()); + boolean first = true; + for (int i = max; i >= min; --i) { + if (first) first = false; + else { out.print(','); out.ws(); } + final ComplexAccess nexpr = new ComplexAccess(expr); + nexpr.accessArray(Integer.toString(i)); + emitPack(nexpr, at.getElementType()); + } + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final boolean[] first = new boolean[] { true }; + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nexpr = new ComplexAccess(expr); + final String id = d.getIdentifier().getIdentifier(); + nexpr.accessStructure(id); + if (first[0]) first[0] = false; + else { out.print(','); out.ws(); } + emitPack(nexpr, d.getTypeFragment()); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Cannot pack: " + t); + } + } + + private ComplexAccess getComplexAccess(final ExpressionInterface expr) + throws VisitorException { + complexAccess = new ComplexAccess(expr); + expr.accept(this); + final ComplexAccess result = complexAccess; + complexAccess = null; + return result; + } + + private void emitPack(final ExpressionInterface structure) + throws VisitorException { + emitPack(getComplexAccess(structure), + (Type) analysisResults.getType(structure)); + } + + // Fix up booleans, specifically, true is unpacked as 1, but needs to be + // turned to -1 + private void emitUnpack(final ComplexAccess expr, final Type t) + throws VisitorException { + if (t instanceof BooleanType) { + } else if (t instanceof IntegerType) { + } else if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + final Range r = at.getRange(); + final int min = getIntegerConstant(r.getMinExpression()); + final int max = getIntegerConstant(r.getMaxExpression()); + for (int i = max; i >= min; --i) { + final ComplexAccess nexpr = new ComplexAccess(expr); + nexpr.accessArray(Integer.toString(i)); + emitUnpack(nexpr, at.getElementType()); + } + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nexpr = new ComplexAccess(expr); + final String id = d.getIdentifier().getIdentifier(); + nexpr.accessStructure(id); + emitUnpack(nexpr, d.getTypeFragment()); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Cannot unpack: " + t); + } + } + + private void emitUnpack(final ExpressionInterface structure) + throws VisitorException { + emitUnpack(getComplexAccess(structure), + (Type) analysisResults.getType(structure)); + } + + /** + * Process an assignment statement. + * + * @param lhs left hand side of the assignment statement + * @param rhs right hand side of the assignment statement; + * null if the right hand side is the value from a channel + * @param chanExpr null if the right hand side is not the + * value from a channel; otherwise, it contains the channel expression to + * read from. + **/ + private void processAssignmentStatement(ExpressionInterface lhs, + ExpressionInterface rhs, + ExpressionInterface chanExpr, + AssignmentStatement stmt) + throws VisitorException { + lvalues.add(lhs); + final boolean op = + stmt != null && stmt.getKind() != AssignmentStatement.EQUAL; + if (lhs instanceof BitRangeExpression && + needBitRangeFunction((BitRangeExpression) lhs)) { + final BitRangeExpression bitRangeExpression = + (BitRangeExpression) lhs; + out.print("util.bit_insert_" + + (op ? stmt.getKindString() : "") + + (bitRangeExpression.getMinExpression() == null ? + "3" : "4") + + "("); + lvalues.add(bitRangeExpression.getBitsExpression()); + bitRangeExpression.getBitsExpression().accept(this); + out.print(','); out.ws(); + lvalues.add(rhs); + processBooleanChannel(chanExpr, rhs); + out.print(','); out.ws(); + lvalues.add(bitRangeExpression.getMaxExpression()); + bitRangeExpression.getMaxExpression().accept(this); + if (bitRangeExpression.getMinExpression() != null) { + out.print(','); out.ws(); + lvalues.add(bitRangeExpression.getMinExpression()); + bitRangeExpression.getMinExpression().accept(this); + } + out.println(");"); + } else if (analysisResults.getType(lhs) instanceof StructureType || + analysisResults.getType(lhs) instanceof ArrayType) { + // This can only be an assignment between two structure or array + // variables + complexAccess = new ComplexAccess(); + lhs.accept(this); + final ComplexAccess lca = complexAccess; + + complexAccess = new ComplexAccess(); + rhs.accept(this); + final ComplexAccess rca = complexAccess; + complexAccess = null; + + final Type t = (Type) analysisResults.getType(lhs); + emitAssignment(lca, rca, t); + } else { + final boolean lstr = + stmt != null && stmt.getKind() == AssignmentStatement.ADD && + (analysisResults.getType(lhs) instanceof StringType); + final boolean rstr = + lstr && !(analysisResults.getType(rhs) instanceof StringType); + + if (op) out.print("util.assign_" + + (lstr ? "concat" : stmt.getKindString()) + "("); + if (lhs instanceof BitRangeExpression) { + final BitRangeExpression bre = (BitRangeExpression) lhs; + lvalues.add(bre.getBitsExpression()); + processSimpleBitRange(bre, true); + } else { + lhs.accept(this); + } + if (op) { out.ws(); out.print(','); out.ws(); } + else { + out.print(" = "); + } + if (rstr) out.print("util.csp_string("); + lvalues.add(rhs); + processBooleanChannel(chanExpr, rhs); + if (rstr) out.print(", 10)"); + if (op) out.print(" )"); + out.println(';'); + + if (false) { + // debugging display + out.print("$display(\""); + lhs.accept(this); + out.print(": %d\\n\", "); + lhs.accept(this); + out.println(");"); + } + } + } + + private static final Map/**/ BUILTIN_FUNCTIONS = + CollectionUtils.mapify( + new String[] { "print", "util.display_hex", + "assert", "assert", + "eventQueueIsEmpty", null, + "random", "random", + "srandom", "srandom", + "choose", "choose", + "log2", "log2", + "log4", "log4", + "wait", "wait", + // without function in guards, this isn't very useful + "stable", null, + "string", "string", + "enableDSimErrors", null, + "time", "time", + "pack", "pack", + "unpack", "unpack", + "energy", "energy" }); + + private String getFullName( + final FunctionDeclaration decl, + final List/**/ arrayArg) throws VisitorException { + final Pair/*>*/ p = + new Pair/*>*/(decl, arrayArg); + final String result = decl.getName() + "$" + labels.getLabel(p); + pendingFunctions.addFirst(new Triplet/*, + String>*/(decl, arrayArg, result)); + + return result; + } + + private String getFullName( + final StructureDeclaration decl, + final List/**/ arrayArg) throws VisitorException { + final Pair/*>*/ p = + new Pair/*>*/(decl, arrayArg); + final String result = decl.getName() + "$" + labels.getLabel(p); + pendingConstructors.add(new Triplet/*, + String>*/(decl, arrayArg, result)); + + return result; + } + + private final Map/**/ + functionAnalyzerCache = + new HashMap/**/(); + + private VariableAnalyzer.Results + getAnalyzerResults(final FunctionDeclaration decl, + final SequentialStatement initStmt) + throws VariableAnalysisException { + VariableAnalyzer.Results results = + (VariableAnalyzer.Results) functionAnalyzerCache.get(decl); + if (results == null) { + results = analyzer.getResults(decl, initStmt, resolver); + allUsedTokens.addAll(results.getUsedTokens()); + problems.process(results.getErrors(strictVars)); + functionAnalyzerCache.put(decl, results); + } + return results; + } + + private final Map/**/ arrayMapping = + new HashMap/**/(); + + private ComplexAccess mapComplexArgument(final ComplexAccess access) { + final ComplexAccess mapped = + (ComplexAccess) arrayMapping.get(access.getBase()); + return access.map(mapped); + } + + private void outputFormalParameter(final IdentifierExpression ident, + final Type t, + final Iterator/**/ args, + final UniqueLabel label, + final String inout, + final boolean[] comma) + throws VisitorException { + if (t instanceof ArrayType || t instanceof StructureType) { + final ComplexAccess access = (ComplexAccess) args.next(); + final int num = label.getLabel(access); + final ComplexAccess fixed = new ComplexAccess(); + fixed.copyStructure(access); + fixed.setBase(access.getBase()); + final int indices = access.getIndices().size(); + if (indices > 0 && comma[0]) out.println(","); + for (int i = 0; i < indices; ++i) { + comma[0] = true; + final String var = "i$" + num + "$" + i; + declareVariable("input ", var, new IntegerType(), ","); + if (i < indices - 1) out.println(","); + fixed.accessArray(var); + } + arrayMapping.put(t, fixed); + } else { + if (comma[0]) out.println(","); + declareVariable(inout, ident.getIdentifier(), t, ","); + comma[0] = true; + } + } + + private void outputConstructor(final StructureDeclaration decl, + final List/**/ arrayArg, + final String name) throws VisitorException { + final Iterator argIter = arrayArg.iterator(); + final UniqueLabel label = new UniqueLabel(); + final boolean[] comma = new boolean[] { false }; + out.println("task " + escape(name) + " ("); + (new DeclarationProcessor() { + public void process(final Declarator d) throws VisitorException { + final IdentifierExpression ident = d.getIdentifier(); + final Type t = d.getTypeFragment(); + tokenVerilogNameMap.put(t, ident.getIdentifier()); + hierarchyNameMap.put(t, name); + outputFormalParameter(ident, t, argIter, label, "input ", + comma); + } + }).process(decl.getDeclarations()); + final IdentifierExpression rident = new IdentifierExpression("ret$"); + final StructureType rtype = new StructureType(false, decl.getName()); + tokenVerilogNameMap.put(rtype, rident.getIdentifier()); + hierarchyNameMap.put(rtype, name); + outputFormalParameter(rident, rtype, argIter, label, "output ", comma); + out.println(");"); + out.println(); + + out.println("begin : main"); + final ComplexAccess lhs = new ComplexAccess(); + lhs.setBase(rtype); + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nlhs = new ComplexAccess(lhs); + final String id = d.getIdentifier().getIdentifier(); + nlhs.accessStructure(id); + + final ComplexAccess nrhs = new ComplexAccess(); + nrhs.setBase(d.getTypeFragment()); + emitAssignment(nlhs, nrhs, d.getTypeFragment(), 0); + } + }).process(decl.getDeclarations()); + out.println("end"); + out.println("endtask"); + } + + private void outputFunction(final FunctionDeclaration decl, + final SequentialStatement initStmt, + final List/**/ arrayArg, + final String name) throws VisitorException { + final VariableAnalyzer.Results old = analysisResults; + try { + analysisResults = getAnalyzerResults(decl, initStmt); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + + updateTokenVerilogMap(name); + + arrayMapping.clear(); + out.println("task " + escape(name) + " ("); + final Iterator argIter = arrayArg.iterator(); + final UniqueLabel label = new UniqueLabel(); + final boolean[] comma = new boolean[] { false }; + for (Iterator i = decl.getFormals().getDeclarations(); i.hasNext(); ) { + final DeclaratorList d = + ((Declaration) i.next()).getDeclaratorList(); + for (Iterator j = d.getDeclarators(); j.hasNext(); ) { + final Declarator dor = (Declarator) j.next(); + final IdentifierExpression ident = dor.getIdentifier(); + final Type t = (Type) analysisResults.getIdentToken(ident); + lastVerilogTokenMap.remove(t); + outputFormalParameter(ident, t, argIter, label, + dor.getDirection() == Declarator.IN ? "input " + : "inout ", + comma); + } + } + // return value + final Type rtype = decl.getReturnType(); + if (rtype != null) { + outputFormalParameter(decl.getNameIdentifier(), rtype, + argIter, label, "output ", comma); + } + out.println(");"); + out.println(); + if (rtype != null) + lastVerilogTokenMap.remove(analysisResults.getIdentToken(decl.getNameIdentifier())); + + declareVariables(); + + // start initial block + out.println("begin : main"); + + // declare and initialize the undeclared variables + final Set/**/ undeclaredVars = processResults(analysisResults); + + // assign to 0 - undeclared variables + for (Iterator i = undeclaredVars.iterator(); i.hasNext(); ) { + final String var = escape((String) i.next()); + out.println(var + " = 0;"); + } + // assign to 0 - return value + if (decl.getReturnType() != null) + initVar(decl.getReturnType(), decl.getNameIdentifier(), 0, null); + // assign to 0 - output parameters + for (Iterator i = decl.getFormals().getDeclarations(); i.hasNext(); ) { + final DeclaratorList d = + ((Declaration) i.next()).getDeclaratorList(); + for (Iterator j = d.getDeclarators(); j.hasNext(); ) { + final Declarator dor = (Declarator) j.next(); + if (dor.getDirection() == Declarator.OUT) { + final IdentifierExpression ident = dor.getIdentifier(); + final Type t = (Type) analysisResults.getIdentToken(ident); + initVar(t, ident, 0, null); + } + } + } + out.println(); + + // csp body + processingBody = true; + decl.getBodyStatement().accept(this); + processingBody = false; + + // end initial block + out.println("end"); + out.println(); + + // end module + out.println("endtask"); + analysisResults = old; + } + + private void outputFunctions(final SequentialStatement initStmt) + throws VisitorException { + final HashSet/*, + String>>*/ seen = + new HashSet/*,String>>*/(); + while (!pendingFunctions.isEmpty()) { + final Triplet/*,String>>*/ t = + (Triplet) pendingFunctions.remove(0); + if (!seen.add(t)) continue; + final FunctionDeclaration decl = (FunctionDeclaration) t.getFirst(); + final List/**/ arrayArg = (List) t.getSecond(); + final String name = (String) t.getThird(); + outputFunction(decl, initStmt, arrayArg, name); + } + } + + private void outputConstructors() throws VisitorException { + final HashSet/*, + String>>*/ seen = + new HashSet/*,String>>*/(); + while (!pendingConstructors.isEmpty()) { + final Triplet/*,String>>*/ t = + (Triplet) pendingConstructors.remove(0); + if (!seen.add(t)) continue; + final StructureDeclaration decl = + (StructureDeclaration) t.getFirst(); + final List/**/ arrayArg = (List) t.getSecond(); + final String name = (String) t.getThird(); + outputConstructor(decl, arrayArg, name); + } + } + + private void outputArbiters() { + for (Iterator i = arbiters.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final String inst = (String) p.getFirst(); + final Integer guards = (Integer) p.getSecond(); + out.println("`CAST2VERILOG_ARBITER #(" + guards + ") " + + inst + "(" + resetNodeName + " );"); + } + } + + private void processFunctionArgument( + final ExpressionInterface arg, + final Collection/**/ realArgs, + final Collection/**/ arrayArgs) + throws VisitorException { + final Type type = analysisResults.getType(arg); + if (type instanceof ArrayType || type instanceof StructureType) { + complexAccess = new ComplexAccess(); + arg.accept(this); + final ComplexAccess mapped = mapComplexArgument(complexAccess); + complexAccess = null; + arrayArgs.add(mapped); + realArgs.addAll(mapped.getIndices()); + } else { + realArgs.add(arg); + } + } + + private void processFunctionCall(final FunctionCallExpression e, + final ExpressionInterface lhs) + throws VisitorException { + for (Iterator arg = e.getActuals(); arg.hasNext(); ) { + lvalues.add((ExpressionInterface) arg.next()); + } + if (lhs != null) lvalues.add(lhs); + + final Pair/**/ p = + (Pair) resolver.getResolvedFunctions().get(e); + final Object decl = p == null ? null : p.getSecond(); + String name = null; + if (p == null || RefinementResolver.isBuiltin(decl)) { + final ExpressionInterface func = e.getFunctionExpression(); + if (func instanceof IdentifierExpression) { + name = ((IdentifierExpression) func).getIdentifier(); + name = (String) BUILTIN_FUNCTIONS.get(name); + if (name == null) { + throw new VisitorException( + "Unsupported builtin function at " + + e.getParseRange().fullString()); + } else if (name == "util.display_hex" || name == "wait" || + name == "assert") { + visitFunctionCallExpression(e); // process builtin funcs + } else if (name == "srandom") { + System.out.println("N.B. srandom() function being skipped"); + } else if (name == "choose" || name == "random" || + name == "string" || name == "log2" || + name == "log4" || name == "time") { + lhs.accept(this); + out.print(" = "); + visitFunctionCallExpression(e); // process builtin funcs + out.println(" ; "); + } else if (name == "pack") { + lhs.accept(this); + out.print(" = { "); + final Iterator i = e.getActuals(); + emitPack((ExpressionInterface) i.next()); + out.println(" }; "); + } else if (name == "unpack") { + out.print("{ "); + final Iterator i = e.getActuals(); + final ExpressionInterface structure = + (ExpressionInterface) i.next(); + emitPack(structure); + out.print(" } = "); + ((ExpressionInterface) i.next()).accept(this); + out.println(" ;"); + emitUnpack(structure); + } else if (name == "energy") { + // do nothing + } + } else { + throw new VisitorException("Call to unknown function at " + + e.getParseRange().fullString()); + } + return; + } + + final Collection realArgs = new ArrayList/**/(); + if (decl instanceof FunctionDeclaration || + decl instanceof StructureDeclaration) { + final List/**/ arrayArg = new ArrayList/**/(); + for (Iterator i = e.getActuals(); i.hasNext(); ) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + processFunctionArgument(arg, realArgs, arrayArg); + } + if (lhs != null) processFunctionArgument(lhs, realArgs, arrayArg); + + if (decl instanceof FunctionDeclaration) { + name = getFullName((FunctionDeclaration) decl, arrayArg); + } else { + name = getFullName((StructureDeclaration) decl, arrayArg); + } + } else { + throw new VisitorException("Call to unknown function at " + + e.getParseRange().fullString()); + } + + out.print(name); + if (!realArgs.isEmpty()) { + out.print("("); + for (Iterator i = realArgs.iterator(); i.hasNext(); ) { + final Object o = i.next(); + if (o instanceof ExpressionInterface) { + ((ExpressionInterface) o).accept(this); + } else { + ((Index) o).write(); + } + if (i.hasNext()) { out.print(','); out.ws(); } + } + out.print(")"); + } + out.println(";"); + } + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + final ExpressionInterface rhs = s.getRightHandSide(); + // Here we handle peeks outside of guards as a special case of the rhs of assignments + // because the FunctionPreprocessor transforms peeks outside of guards as + // x = #X? + 0 into temp = #X?; x = temp + 0 + // Peeks inside guards are handled in visitPeekExpressions + if (rhs instanceof PeekExpression) { + // outside guard: #L? == ( [ L.d >= 0 ] ; L.d ) + final ExpressionInterface chanExpr = + ((PeekExpression) rhs).getChannelExpression(); + out.print("wait("); + emitChannelData(chanExpr); + out.println(" >= 0);"); + processAssignmentStatement(s.getLeftHandSide(), rhs, + chanExpr, null); + } else if (rhs instanceof FunctionCallExpression) { + processFunctionCall((FunctionCallExpression) rhs, + s.getLeftHandSide()); + } else { + processAssignmentStatement(s.getLeftHandSide(), rhs, null, s); + } + } + + /** + * Returns true if the guarded statement has one guard + * and no else clause. + **/ + private static boolean hasOneGuard(AbstractGuardedStatement s) { + final Iterator i = s.getGuardedCommands(); + assert i.hasNext(); + i.next(); + return !i.hasNext() && s.getElseStatement() == null; + } + + /** + * Returns number of guards in guarded statement + **/ + private static int numGuards(AbstractGuardedStatement s) { + final Iterator i = s.getGuardedCommands(); + int numGuards = 0; + assert i.hasNext(); + while (i.hasNext()) { + numGuards++; + i.next(); + } + return(numGuards); + } + + public void processSelectionOrRepetition( + final AbstractGuardedStatement s, + final boolean isRepetition, + final boolean isDeterministic) + throws VisitorException { + if (isRepetition && hasOneGuard(s)) { + // Special case the 1 guard case into a simple while loop + final GuardedCommand gc = + (GuardedCommand) s.getGuardedCommands().next(); + final StatementInterface guardStmt; + if (gc instanceof GuardedCommandWithStatement) { + guardStmt = + ((GuardedCommandWithStatement) gc).getGuardStatement(); + } else { + guardStmt = null; + } + if (guardStmt != null) { + guardStmt.accept(this); + } + out.print("while ("); + gc.getGuard().accept(this); + out.println(") begin"); + gc.getCommand().accept(this); + if (guardStmt != null) { + guardStmt.accept(this); + } + out.println("end"); + } else { + out.println("begin : " + genBlock()); + final String chosenGuard = "chosen_guard$" + genVarNum(); + out.println("integer " + chosenGuard + ';'); + final String numTrueGuards = "num_true_guards$" + genVarNum(); + out.println("integer " + numTrueGuards + ';'); + + // for non-determistic case declare an array of true guard nums + final int numGuards = numGuards(s); + final String arbiterInst, trueGuards; + if (isDeterministic) { + arbiterInst = null; + trueGuards = "true_guards$" + genVarNum(); + out.println("integer " + trueGuards + + "[0:" + numGuards + " - 1];"); + } else { + arbiterInst = "arbiter$" + genVarNum(); + trueGuards = arbiterInst + ".true_guards"; + arbiters.add(new Pair(arbiterInst, new Integer(numGuards))); + } + + if (!isRepetition || s.getElseStatement() == null) { + // hack around lack of do ... while loop by setting + // chosenGuard to 0 initially + out.println(chosenGuard + " = 0;"); + out.println("while (" + chosenGuard + " != -1) begin"); + } else + out.println("while (1) begin"); + + out.println(chosenGuard + " = -1;"); + out.println(numTrueGuards + " = 0;"); + + + // handle guards + int guardNum = 0; + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommand gc = (GuardedCommand) i.next(); + + if (gc instanceof GuardedCommandWithStatement) { + final GuardedCommandWithStatement gcws = + (GuardedCommandWithStatement) gc; + gcws.getGuardStatement().accept(this); + } + + out.print("if ("); + gc.getGuard().accept(this); + out.println(')'); + + out.println("begin"); + if (isDeterministic) // remember true guard + out.println(chosenGuard + " = " + guardNum + ';'); + + // trueGuards[numTrueGuards] = guardNum; + out.println(trueGuards + "[" + numTrueGuards + "] = " + + guardNum + ";"); + + out.println(numTrueGuards + " = " + numTrueGuards + "+ 1;"); + out.println("end"); + + ++guardNum; + } + + // emit error checking code for more than 1 guard being true + // in deterministic case + if (isDeterministic) { + out.println("// error checking code"); + out.println("if (" + numTrueGuards + " > 1) begin"); + out.println("`CAST2VERILOG_MULTIPLE_GUARDS_TRUE_ERROR2(\"" + + s.getParseRange().fullString() + "\", " + + numTrueGuards + ", " + trueGuards + ")"); + out.println("end // error checking code"); + } + + // pick guard randomly among true guards + if (!isDeterministic) { + out.println("if (" + numTrueGuards + "> 0)"); + out.println(chosenGuard + " = " + arbiterInst + ".select(" + + numTrueGuards + ");"); + } + + // handle bodies + out.println("case (" + chosenGuard + ')'); + // handle else or do nothing case + out.println("-1 : begin"); + if (s.getElseStatement() != null) { + s.getElseStatement().accept(this); + } else if (!isRepetition) { + // handle case that no guards are true + // REVIEW: This might not be the best way to handle waiting + out.print("@("); + boolean first = true; + for (Iterator i = inputPorts.iterator(); i.hasNext(); ) { + final String inputPort = (String) i.next(); + if (!first) { + out.ws(); out.print("or"); out.ws(); + } + first = false; + out.print(inputPort + " "); + } + if (first) { + // if there are no inputs at all to the cell, deadlock by + // waiting for the chosenGuard variable to change, which + // cannot happen + out.print(chosenGuard + " "); + } + out.println(");"); + + // HACK: stay in loop by setting chosenGuard to 0 + out.println(chosenGuard + " = 0;"); + } + out.println("end"); + // handle other bodies + guardNum = 0; + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommand gc = (GuardedCommand) i.next(); + out.println(guardNum + " : begin"); + gc.getCommand().accept(this); + if (!isRepetition) { + // HACK: end loop by setting chosenGuard to -1 + out.println(chosenGuard + " = -1;"); + } + out.println("end"); + + ++guardNum; + } + out.println("endcase"); + + out.println("end"); + out.println("end"); + } + } + + + public void visitDeterministicRepetitionStatement( + DeterministicRepetitionStatement s) + throws VisitorException { + processSelectionOrRepetition(s, true, true); + } + + + public void visitDeterministicSelectionStatement( + DeterministicSelectionStatement s) + throws VisitorException { + processSelectionOrRepetition(s, false, true); + } + + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + final ExpressionInterface expr = s.getExpression(); + if (expr instanceof FunctionCallExpression) { + processFunctionCall((FunctionCallExpression) expr, null); + return; + } + unsupported(s); + } + + public void visitLoopStatement(LoopStatement s) throws VisitorException { + // Only sequential loops are translated directly; parallel loops is + // only handled via loop unrolling + if (s.getSeparator() == LoopStatement.SEQUENTIAL) { + out.println("begin : " + genBlock()); + final String loopMax = "loopMax$" + genVarNum(); + out.println(registerType + " " + loopMax + ";"); + out.print(loopMax + " = "); + s.getRange().getMaxExpression().accept(this); + out.println(" ;"); + + out.print("for ("); + s.getIndexVarExpression().accept(this); + out.print("="); + s.getRange().getMinExpression().accept(this); + out.print(" ; "); + s.getIndexVarExpression().accept(this); + out.print(" <= " + loopMax + " ; "); + s.getIndexVarExpression().accept(this); + out.print("="); + s.getIndexVarExpression().accept(this); + out.println(" + 1) begin "); + s.getStatement().accept(this); + out.println("end"); + out.println("end"); + } else { + throw new VisitorException("Range not compile time constants in loop at " + s.getParseRange().fullString()); + } + } + + public void visitNonDeterministicRepetitionStatement( + NonDeterministicRepetitionStatement s) + throws VisitorException { + unsupported(s); + } + + + public void visitNonDeterministicSelectionStatement( + NonDeterministicSelectionStatement s) + throws VisitorException { + /* Through exception on else. Currently this also causes a grammer exception */ + if (s.getElseStatement() != null) { + throw new AssertionError("Else in non-deterministic selection not supported"); + } + processSelectionOrRepetition(s, false, false); + } + + public void visitLinkageLoopTerm(final LinkageLoopTerm term) + throws VisitorException { + unsupported(term); + } + + public void visitLinkageExpressionTerm(final LinkageExpressionTerm term) + throws VisitorException { + unsupported(term); + } + + public void visitLinkageArrayAccessExpression( + final LinkageArrayAccessExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitLinkageIdentifierExpression( + final LinkageIdentifierExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitLinkageStructureAccessExpression( + final LinkageStructureAccessExpression e) + throws VisitorException { + unsupported(e); + } + + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + out.println("fork"); + + for (Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + + out.println("begin"); + + // emit the parallel code + stmt.accept(this); + + out.println("end"); + } + + out.println("join"); + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + // This expansion requires slack of at least 1 to get probe + // sends to behave properly. + // L?x == ( [ L.d >= 0 ] ; x = L.d ; L.e = 0 + // ; [ L.d < 0 ] ; L.e = 1 ) + // Good test cases include: + // 1. L[getTime() % N]?x + // 2. L[x]?x + // These will ensure channel is evaluated only once + + final ExpressionInterface chanExpr = s.getChannelExpression(); + + out.print("wait("); + emitChannelData(chanExpr); + out.println(" >= 0);"); + + if (s.getRightHandSide() != null) + processAssignmentStatement(s.getRightHandSide(), + s.getRightHandSide(), chanExpr, + null); + + emitChannelEnable(chanExpr); + out.println(" = 0;"); + + out.print("wait("); + emitChannelData(chanExpr); + out.println(" < 0);"); + + emitChannelEnable(chanExpr); + out.println(" = 1;"); + } + + private void processConcat(final String var, final String literal) { + out.print(var + " = csp_string.concat(" + var + ", "); + processString(literal); + out.println(");"); + } + + public void visitSendStatement(SendStatement s) + throws VisitorException { + // R!x == ( [ R.e ] ; R.d = POSMOD(x, numValues) + // ; [ !R.e ] ; R.d = -1 ) + // Good test cases include: + // 1. R[getTime() % N]!x + // This will ensure channel is evaluated only once + + final ExpressionInterface chanExpr = s.getChannelExpression(); + + // The type checking pass should have ensured that this is indeed + // a channel type and that the direction is appropriate + final ChannelType type = + (ChannelType) analysisResults.getType(chanExpr); + assert type.getDirection() == PortDirection.OUT; + final BigInteger numValues = type.getNumValues(); + assert numValues.signum() == 1; + + out.print("wait("); + emitChannelEnable(chanExpr); + out.println(");"); + + lvalues.add(s.getRightHandSide()); + + final boolean pow2 = BigIntegerUtil.isPowerOf2(numValues); + + if (!pow2) { + out.print("if (("); + // it's okay to evaluate the rhs multiple times because rhs is + // guaranteed to be a simple variable + s.getRightHandSide().accept(this); + out.print(" < 1'sb0) || ("); + s.getRightHandSide().accept(this); + out.print(" >= "); + processBigInteger(numValues, 10); + out.println("))"); + out.print("`CAST2VERILOG_CSP_WARNING(\"" + + s.getParseRange().fullString() + "\", " + + "util.posmod_warning("); + s.getRightHandSide().accept(this); + out.print(", "); + processBigInteger(numValues.subtract(BigInteger.ONE), 10); + out.println("))"); + } + + emitChannelData(chanExpr); + out.print(" = "); + if (numValues.equals(BigInteger.ONE)) { + out.print("0"); + } else { + if (pow2) { + processBigInteger(numValues.subtract(BigInteger.ONE), 16); + out.print(" & ("); + } else { + out.print("util.posmod("); + } + s.getRightHandSide().accept(this); + if (!pow2) { + out.println(", "); + processBigInteger(numValues, 16); + } + out.print(")"); + } + out.println(';'); + + out.print("wait(!"); + emitChannelEnable(chanExpr); + out.println(");"); + + emitChannelData(chanExpr); + out.println(" = -1;"); + } + + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + ++scope; + for (final Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + stmt.accept(this); + } + --scope; + } + + public void visitErrorStatement(ErrorStatement s) + throws VisitorException { + out.println("`CAST2VERILOG_CSP_ERROR(\"" + + s.getParseRange().fullString() + "\")"); + } + + public void visitSkipStatement(SkipStatement s) + throws VisitorException { + // do nothing + } + + private void declareType(final Type t, + final ComplexDeclaration decl, + final Collection/**/ results) + throws VisitorException { + if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + decl.declareArray(at.getRange()); + declareType(at.getElementType(), decl, results); + } else if (t instanceof IntegerType || t instanceof BooleanType || + t instanceof StringType) { + decl.setType(t); + results.add(decl); + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + // VariableAnalyzer should have made sure all structures are valid + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexDeclaration cdecl = + new ComplexDeclaration(decl); + cdecl.declareStructure(d.getIdentifier().getIdentifier()); + declareType(d.getTypeFragment(), cdecl, results); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Unsupported type: " + t); + } + } + + private void declareVariable(final String id, final Type t) + throws VisitorException { + declareVariable("", id, t, ";"); + out.println(";"); + } + + private void declareVariable(final String inout, final String id, + final Type t, final String delim) + throws VisitorException { + final Collection/**/ results = + new ArrayList/**/(); + final ComplexDeclaration decl = new ComplexDeclaration(); + declareType(t, decl, results); + + // just emit declaration + for (Iterator i = results.iterator(); i.hasNext(); ) { + final ComplexDeclaration cdecl = (ComplexDeclaration) i.next(); + out.print(inout); + cdecl.declare(id); + if (i.hasNext()) out.println(delim); + } + } + + private Map/**/ tokenVerilogNameMap = + new HashMap/**/(); + private Map/**/ lastVerilogTokenMap = + new LinkedHashMap/**/(); + private Map/**/ hierarchyNameMap = + new HashMap/**/(); + private Set allUsedTokens = new HashSet(); + private void updateTokenVerilogMap(final String hierarchy) { + lastVerilogTokenMap.clear(); + final Map/**/ tokenIdentMap = + analysisResults.getTokenIdentMap(); + final Set initializerTokens = + analysisResults.getInitializerTokens(); + final HashCounter counter = new HashCounter(); + for (Iterator i = tokenIdentMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry/**/ entry = (Map.Entry) i.next(); + final Type type = (Type) entry.getKey(); + final String id = (String) entry.getValue(); + final int count = counter.getCount(id); + counter.add(id); + final String realId = id + (count == 0 ? "" : "$$" + count); + tokenVerilogNameMap.put(type, realId); + // ChannelTypes and ChannelStructureTypes cannot be passed to + // functions as arguments, and therefore can only be accessed if + // they are in the cell's port list. The cell ports translate to + // module ports, which are visible to tasks defined in the module, + // so we do not need to do anything to them. + Type baseType = type; + while (baseType instanceof ArrayType) + baseType = ((ArrayType) baseType).getElementType(); + if ((baseType instanceof IntegerType || + baseType instanceof BooleanType || + baseType instanceof StringType || + baseType instanceof StructureType) && + !initializerTokens.contains(type) && + allUsedTokens.contains(type)) + lastVerilogTokenMap.put(type, realId); + hierarchyNameMap.put(type, hierarchy); + } + } + + private void declareVariables() throws VisitorException { + for (Iterator i = lastVerilogTokenMap.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry/**/ entry = (Map.Entry) i.next(); + declareVariable((String) entry.getValue(), (Type) entry.getKey()); + } + } + + private void initVar(final Type t, final IdentifierExpression ident, + final int dims, final ExpressionInterface init) + throws VisitorException { + complexAccess = new ComplexAccess(); + ident.accept(this); + final ComplexAccess access = complexAccess; + complexAccess = null; + initVar(t, access, dims, init); + } + + private void initVar(final Type t, final ComplexAccess ident, + final int dims, final ExpressionInterface init) + throws VisitorException { + if (t instanceof IntegerType || t instanceof BooleanType) { + ident.write(); + out.print(" = "); + if (init == null) out.print('0'); + else init.accept(this); + out.println(";"); + } else if (t instanceof StringType) { + ident.write(); + out.print(" = "); + if (init == null) out.print("csp_string.init($bits(\"\"),\"\")"); + else init.accept(this); + out.println(";"); + } else if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + out.println("begin : " + genBlock()); + final String var = "loop$" + dims; + out.println(getLoopVarType(at.getRange()) + " " + var + ";"); + emitForLoop(var, at.getRange()); + out.println(" begin"); + ident.accessArray(var); + initVar(at.getElementType(), ident, dims + 1, init); + out.println("end"); + out.println("end"); + } else if (t instanceof StructureType) { + final Pair p = (Pair) resolver.getResolvedStructures().get(t); + final StructureDeclaration sdecl = + (StructureDeclaration) p.getSecond(); + final DeclarationProcessor proc = new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final ComplexAccess nident = new ComplexAccess(ident); + nident.accessStructure(d.getIdentifier().getIdentifier()); + initVar(d.getTypeFragment(), nident, dims + 1, + d.getInitializer()); + } + }; + proc.process(sdecl.getDeclarations()); + } else { + throw new AssertionError("Cannot initialize type: " + t); + } + } + + public void visitVarStatement(VarStatement s) + throws VisitorException { + for (Iterator i = s.getDeclarationList().getDeclarations(); + i.hasNext(); ) { + final Declaration declaration = (Declaration) i.next(); + + for (Iterator j = + declaration.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator declarator = (Declarator) j.next(); + final Type t = declarator.getTypeFragment(); + + // declaration has been emitted at top of block by + // declareVariables(), just assign here + final ExpressionInterface init = declarator.getInitializer(); + if (implicitInit || init != null || scope > 1) { + initVar(t, declarator.getIdentifier(), 0, init); + } + } + } + + // only support new style declarations + assert s.getStatement() == null; + } + + public void visitArrayType(ArrayType t) + throws VisitorException { + unsupported(t); + } + + public void visitChannelType(ChannelType t) + throws VisitorException { + unsupported(t); + } + + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + unsupported(t); + } + + public void visitIntegerType(IntegerType t) + throws VisitorException { + unsupported(t); + } + + public void visitBooleanType(BooleanType t) + throws VisitorException { + unsupported(t); + } + + public void visitNodeType(NodeType t) + throws VisitorException { + unsupported(t); + } + + public void visitStringType(StringType t) throws VisitorException { + unsupported(t); + } + + public void visitStructureType(StructureType t) + throws VisitorException { + unsupported(t); + } + + public void visitIdentifierList(IdentifierList il) + throws VisitorException { + unsupported(il); + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + unsupported(s); + } + + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + unsupported(s); + } + + private void unsupported(AbstractASTNode n) throws VisitorException { + throw new VisitorException("CSP construct not yet supported at " + + n.getParseRange().fullString()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/Csp2Xml.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/Csp2Xml.java new file mode 100644 index 0000000000..ba41a69676 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/Csp2Xml.java @@ -0,0 +1,157 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.csp.csp2xml; + +import com.avlsi.fast.ports.ArrayType; +import com.avlsi.csp.ast.CSPProgram; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.io.FileSearchPath; +import java.io.IOException; +import java.util.Iterator; +import com.avlsi.fast.ports.NodeType; +import java.io.OutputStreamWriter; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import java.io.PrintWriter; +import com.avlsi.fast.ports.StructureType; +import com.avlsi.csp.ast.VisitorException; + +public class Csp2Xml { + private static void printPort(XmlTourist x, PortDefinition port) { + int dir = port.getDirection(); + String dirStr = "unknown"; + switch (dir) { + case PortDefinition.NONE: + dirStr = "none"; + break; + case PortDefinition.IN: + dirStr = "in"; + break; + case PortDefinition.OUT: + dirStr = "out"; + break; + case PortDefinition.INOUT: + dirStr = "inout"; + break; + } + x.beginTag("Port name=\"" + port.getName() + "\" dir=\"" + + dirStr + "\""); + printType(x, port.getType()); + x.endTag("Port"); + } + + private static void printType(XmlTourist x, PortTypeInterface t) { + if (t instanceof ChannelType) { + ChannelType c = (ChannelType) t; + StringBuffer buf = new StringBuffer(""); + x.print(buf.toString()); + } else if (t instanceof NodeType) { + NodeType n = (NodeType) t; + StringBuffer buf = new StringBuffer(""); + x.print(buf.toString()); + } else if (t instanceof ArrayType) { + ArrayType a = (ArrayType) t; + x.beginTag("ArrayType"); + x.beginTag("min"); + x.print(""); + x.endTag("min"); + x.beginTag("max"); + x.print(""); + x.endTag("max"); + x.beginTag("elementType"); + printType(x, a.getArrayedType()); + x.endTag("elementType"); + x.endTag("ArrayType"); + } else if (t instanceof StructureType) { + StructureType s = (StructureType) t; + StringBuffer buf = new StringBuffer("StructureType"); + if (s.getTag() != null) { + buf.append(" type=\""); + buf.append(s.getTag()); + buf.append('\"'); + } + x.beginTag(buf.toString()); + for (Iterator it = s.iterator(); it.hasNext(); ) { + PortDefinition port = (PortDefinition) it.next(); + printPort(x, port); + } + x.endTag("StructureType"); + } else { + throw new RuntimeException("unknown port type " + + t.getClass().getName()); + } + } + + private static void usage(int exitStatus) { + System.out.println("Usage: csp2xml --cast-path=cast_path" + + " [--cell=cell_name]" + + " [--version]"); + System.exit(exitStatus); + } + + public static void main(String[] args) + throws CastSemanticException, CastSyntaxException, + IOException, VisitorException { + // Command-line handling code stolen from Csp2TT + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs(argsWithConfigs); + final CommandLineArgs theArgs = cachedArgs; + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + Csp2Xml.class)); + } + + final FileSearchPath castFSP = + new FileSearchPath(theArgs.getArgValue("cast-path", ".")); + + final String castCellName = theArgs.getArgValue("cell", null); + + if (castCellName == null || + theArgs.nonParsedArgumentsIterator().hasNext()) + usage(1); + + final CastFileParser cfp = new CastFileParser(castFSP, "2"); + final CellInterface cell = cfp.getFullyQualifiedCell(castCellName); + + CSPCellInfo cspInfo = cell.getCSPInfo(); + CSPProgram cspProg = cell.getCSPProgram(); + + PrintWriter p = new PrintWriter(new OutputStreamWriter(System.out)); + XmlTourist x = new XmlTourist(p); + x.beginTag("csp type=\"" + cspInfo.getType() + "\""); + x.beginTag("PortDefinitions"); + for (Iterator it = cspInfo.getPortDefinitions(); it.hasNext(); ) { + PortDefinition port = (PortDefinition) it.next(); + printPort(x, port); + } + x.endTag("PortDefinitions"); + cspProg.accept(x); + x.endTag("csp"); + p.flush(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/XmlTourist.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/XmlTourist.java new file mode 100644 index 0000000000..0fb171cd99 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/csp2xml/XmlTourist.java @@ -0,0 +1,767 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.csp.csp2xml; + +import com.avlsi.csp.ast.AbstractASTNodeInterface; +import com.avlsi.csp.ast.AbstractBinaryExpression; +import com.avlsi.csp.ast.AbstractChannelStatement; +import com.avlsi.csp.ast.AbstractCompositeStatement; +import com.avlsi.csp.ast.AbstractGuardedStatement; +import com.avlsi.csp.ast.AbstractLoop; +import com.avlsi.csp.ast.AbstractUnaryExpression; +import com.avlsi.csp.ast.AddExpression; +import com.avlsi.csp.ast.AndExpression; +import com.avlsi.csp.ast.ArrayAccessExpression; +import com.avlsi.csp.ast.ArrayType; +import com.avlsi.csp.ast.AssignmentStatement; +import java.math.BigInteger; +import com.avlsi.csp.ast.BitRangeExpression; +import com.avlsi.csp.ast.BooleanType; +import com.avlsi.csp.ast.ChannelType; +import com.avlsi.csp.ast.ChannelStructureType; +import com.avlsi.csp.ast.CSPProgram; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.csp.ast.ConditionalAndExpression; +import com.avlsi.csp.ast.ConditionalOrExpression; +import com.avlsi.util.debug.Debug; +import com.avlsi.csp.ast.Declaration; +import com.avlsi.csp.ast.DeclarationList; +import com.avlsi.csp.ast.Declarator; +import com.avlsi.csp.ast.DeterministicRepetitionStatement; +import com.avlsi.csp.ast.DeterministicSelectionStatement; +import com.avlsi.csp.ast.DivideExpression; +import com.avlsi.csp.ast.EqualityExpression; +import com.avlsi.csp.ast.ErrorStatement; +import com.avlsi.csp.ast.ExponentialExpression; +import com.avlsi.csp.ast.ExpressionInterface; +import com.avlsi.csp.ast.ExpressionStatement; +import com.avlsi.csp.ast.FunctionCallExpression; +import com.avlsi.csp.ast.FunctionDeclaration; +import com.avlsi.csp.ast.GreaterEqualExpression; +import com.avlsi.csp.ast.GreaterThanExpression; +import com.avlsi.csp.ast.GuardedCommand; +import com.avlsi.csp.ast.GuardedCommandWithStatement; +import com.avlsi.csp.ast.IdentifierExpression; +import com.avlsi.csp.ast.IdentifierList; +import com.avlsi.csp.ast.IncDecStatement; +import com.avlsi.csp.ast.InequalityExpression; +import com.avlsi.csp.ast.IntegerExpression; +import com.avlsi.csp.ast.IntegerType; +import com.avlsi.csp.ast.XorExpression; + +import java.util.Iterator; +import com.avlsi.csp.ast.LeftShiftExpression; +import com.avlsi.csp.ast.LessEqualExpression; +import com.avlsi.csp.ast.LessThanExpression; +import com.avlsi.csp.ast.LinkageArrayAccessExpression; +import com.avlsi.csp.ast.LinkageExpressionTerm; +import com.avlsi.csp.ast.LinkageIdentifierExpression; +import com.avlsi.csp.ast.LinkageLoopTerm; +import com.avlsi.csp.ast.LinkageStructureAccessExpression; +import java.util.LinkedList; +import com.avlsi.csp.ast.LoopGuard; +import com.avlsi.csp.ast.LoopExpression; +import com.avlsi.csp.ast.LoopStatement; +import com.avlsi.csp.ast.MemberAccessExpression; +import com.avlsi.csp.ast.MultiplyExpression; +import com.avlsi.csp.ast.NegateExpression; +import com.avlsi.csp.ast.NodeType; +import com.avlsi.csp.ast.NonDeterministicRepetitionStatement; +import com.avlsi.csp.ast.NonDeterministicSelectionStatement; +import com.avlsi.csp.ast.NotExpression; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.csp.ast.OrExpression; +import com.avlsi.csp.ast.ParallelStatement; +import com.avlsi.csp.ast.PeekExpression; +import java.io.PrintWriter; +import com.avlsi.csp.ast.ProbeExpression; +import com.avlsi.csp.ast.ReceiveExpression; +import com.avlsi.csp.ast.ReceiveStatement; +import com.avlsi.csp.ast.RemainderExpression; +import com.avlsi.csp.ast.RightShiftExpression; +import com.avlsi.csp.ast.SendStatement; +import com.avlsi.csp.ast.SequentialStatement; +import com.avlsi.csp.ast.SkipStatement; +import com.avlsi.csp.ast.StatementInterface; +import com.avlsi.csp.ast.StringExpression; +import com.avlsi.csp.ast.StringType; +import com.avlsi.util.text.StringUtil; +import com.avlsi.csp.ast.StructureAccessExpression; +import com.avlsi.csp.ast.StructureType; +import com.avlsi.csp.ast.SubtractExpression; +import com.avlsi.csp.ast.Type; +import com.avlsi.csp.ast.VarStatement; +import com.avlsi.csp.ast.VisitorException; +import com.avlsi.csp.ast.VisitorInterface; + +public class XmlTourist implements VisitorInterface { + private final PrintWriter pw; + private int indent = 0; + + public XmlTourist(PrintWriter pw) { + this.pw = pw; + } + + private String hexify(String val, int base) { + byte[] b = new BigInteger(val, base).toByteArray(); + StringBuffer s = new StringBuffer(); + for (int i = 0; i < b.length; i++) + s.append(NumberFormatter.toHexString(0xff & (int)b[i], 2)); + return s.toString(); + } + + public void print(String s) { + pw.println(StringUtil.repeatString(" ", indent) + s); + } + + public void beginTag(String s) { + print("<" + s + ">"); + indent++; + } + + public void endTag(String s) { + indent--; + print(""); + } + + private String pos(AbstractASTNodeInterface n) { + String range = n.getParseRange().toString(); + if (range.equals("0:0-0:0")) + return ""; + return "pos=\"" + range + "\""; + } + + private void beginTag(AbstractASTNodeInterface n) { + beginTag(n, ""); + } + + private void beginTag(AbstractASTNodeInterface n, String extra) { + String s = n.getClass().getName(); + s = s.substring(s.lastIndexOf('.') + 1); + print("<" + s + " " + extra + pos(n) + ">"); + indent++; + } + + private void endTag(AbstractASTNodeInterface n) { + indent--; + String s = n.getClass().getName(); + s = s.substring(s.lastIndexOf('.') + 1); + print(""); + } + + private void binary(AbstractBinaryExpression e) throws VisitorException { + String s = e.getClass().getName(); + s = s.substring(s.lastIndexOf('.') + 1, s.length() - 10); + s = s.substring(0,1).toLowerCase() + s.substring(1); + print(""); + indent++; + beginTag("left"); + e.getLeft().accept(this); + endTag("left"); + beginTag("right"); + e.getRight().accept(this); + endTag("right"); + endTag("BinaryExpression"); + } + + private void unary(AbstractUnaryExpression e) throws VisitorException { + String s = e.getClass().getName(); + s = s.substring(s.lastIndexOf('.') + 1, s.length() - 10); + s = s.substring(0,1).toLowerCase() + s.substring(1); + print(""); + indent++; + e.getExpression().accept(this); + endTag("UnaryExpression"); + } + + private void beginChannel(AbstractASTNodeInterface n) + throws VisitorException { + String s = n.getClass().getName(); + s = s.substring(s.lastIndexOf('.') + 1, s.length() - 10); + s = s.substring(0,1).toLowerCase() + s.substring(1); + print(""); + indent++; + } + + private void endChannel(AbstractASTNodeInterface n) + throws VisitorException { + endTag("ChannelExpression"); + } + + private void guarded(AbstractGuardedStatement s) throws VisitorException { + String str = s.getClass().getName(); + str = str.substring(str.lastIndexOf('.') + 1, str.length() - 9); + str = str.substring(0,1).toLowerCase() + str.substring(1); + print(""); + indent++; + for (Iterator it = s.getGuardedCommands(); it.hasNext(); ) { + GuardedCommand g = (GuardedCommand) it.next(); + if (g instanceof GuardedCommandWithStatement) { + beginTag("GuardedCommandWithStatement"); + beginTag("guard"); + beginTag("statement"); + ((GuardedCommandWithStatement) g).getGuardStatement() + .accept(this); + endTag("statement"); + beginTag("expression"); + g.getGuard().accept(this); + endTag("expression"); + endTag("guard"); + beginTag("command"); + g.getCommand().accept(this); + endTag("command"); + endTag("GuardedCommandWithStatement"); + } else { + beginTag("GuardedCommand"); + beginTag("guard"); + g.getGuard().accept(this); + endTag("guard"); + beginTag("command"); + g.getCommand().accept(this); + endTag("command"); + endTag("GuardedCommand"); + } + } + if (s.getElseStatement() != null) { + beginTag("else"); + s.getElseStatement().accept(this); + endTag("else"); + } + endTag("GuardedStatement"); + } + + private void composite(AbstractCompositeStatement s) + throws VisitorException { + int len = + CollectionUtils.addAll(new LinkedList(), s.getStatements()).size(); + switch (len) { + case 0: + /* Not sure if this will ever happen, but if it does, an + * empty composite statement is equivalent to a skip statement */ + print(""); + break; + case 1: + /* If there is only one statement, don't wrap it in a + * composite statement, since that would just be silly. */ + ((StatementInterface)s.getStatements().next()).accept(this); + break; + default: + String str = s.getClass().getName(); + str = str.substring(str.lastIndexOf('.') + 1, str.length() - 9); + str = str.substring(0,1).toLowerCase() + str.substring(1); + print(""); + indent++; + for (Iterator it = s.getStatements(); it.hasNext(); ) { + StatementInterface si = (StatementInterface) it.next(); + si.accept(this); + } + endTag("CompositeStatement"); + break; + } + } + + private void channel(AbstractChannelStatement s) throws VisitorException { + String str = s.getClass().getName(); + str = str.substring(str.lastIndexOf('.') + 1, str.length() - 9); + str = str.substring(0,1).toLowerCase() + str.substring(1); + print(""); + indent++; + beginTag("channel"); + s.getChannelExpression().accept(this); + endTag("channel"); + if (s.getRightHandSide() != null) { + beginTag("rhs"); + s.getRightHandSide().accept(this); + endTag("rhs"); + } + endTag("ChannelStatement"); + } + + private void loop(AbstractLoop l, String op, AbstractASTNodeInterface n) + throws VisitorException { + beginTag(l, "op=\"" + op + "\" var=\"" + l.getIndexVar() + "\" "); + beginTag("min"); + l.getRange().getMinExpression().accept(this); + endTag("min"); + beginTag("max"); + l.getRange().getMaxExpression().accept(this); + endTag("max"); + beginTag("loopBody"); + if (n instanceof ExpressionInterface) { + ((ExpressionInterface)n).accept(this); + } else { + ((StatementInterface)n).accept(this); + } + endTag("loopBody"); + endTag(l); + } + + public void visitCSPProgram(CSPProgram p) throws VisitorException { + beginTag(p, "filename=\"" + p.getParseRange().start.filename + "\" "); + beginTag("initializer"); + if (p.getInitializerStatement() != null) + p.getInitializerStatement().accept(this); + endTag("initializer"); + beginTag("functions"); + for (Iterator it = p.getFunctionDeclarations(); it.hasNext(); ) { + FunctionDeclaration f = (FunctionDeclaration) it.next(); + beginTag("function name=\"" + f.getName() + "\""); + beginTag("parameters"); + printDeclarationList(f.getFormals()); + endTag("parameters"); + if (f.getReturnType() != null) { + beginTag("returnType"); + f.getReturnType().accept(this); + endTag("returnType"); + } + beginTag("body"); + f.getBodyStatement().accept(this); + endTag("body"); + endTag("function"); + } + endTag("functions"); + if (p.getStatement() != null) { + beginTag("body"); + p.getStatement().accept(this); + endTag("body"); + } + endTag(p); + } + + + public void visitAddExpression(AddExpression e) throws VisitorException { + binary(e); + } + + public void visitAndExpression(AndExpression e) throws VisitorException { + binary(e); + } + + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + binary(e); + } + + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + binary(e); + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + beginTag(e); + beginTag("array"); + e.getArrayExpression().accept(this); + endTag("array"); + beginTag("index"); + e.getIndexExpression().accept(this); + endTag("index"); + endTag(e); + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + beginTag(e); + beginTag("bits"); + e.getBitsExpression().accept(this); + endTag("bits"); + if (e.getMinExpression() != null) { + beginTag("min"); + e.getMinExpression().accept(this); + endTag("min"); + } + beginTag("max"); + e.getMaxExpression().accept(this); + endTag("max"); + endTag(e); + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + binary(e); + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + binary(e); + } + + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + binary(e); + } + + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + beginTag(e); + beginTag("function"); + e.getFunctionExpression().accept(this); + endTag("function"); + beginTag("parameters"); + for (Iterator it = e.getActuals(); it.hasNext(); ) { + ExpressionInterface p = (ExpressionInterface) it.next(); + p.accept(this); + } + endTag("parameters"); + endTag(e); + } + + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + binary(e); + } + + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + binary(e); + } + + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + final String type = s.isIncrement() ? "increment" : "decrement"; + beginTag(type); + beginTag("expr"); + s.getExpression().accept(this); + endTag("expr"); + endTag(type); + } + + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + print(""); + } + + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + binary(e); + } + + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + print(""); + } + + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + binary(e); + } + + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + binary(e); + } + + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + binary(e); + } + + public void visitLoopExpression(LoopExpression e) throws VisitorException { + String op = "unknown"; + switch (e.getSeparator()) { + case LoopExpression.AND: + op = "and"; + break; + case LoopExpression.OR: + op = "or"; + break; + case LoopExpression.XOR: + op = "xor"; + break; + case LoopExpression.TIMES: + op = "multiply"; // for consistency with MultiplyExpression + break; + case LoopExpression.PLUS: + op = "add"; // for consistency with AddExpression + break; + } + loop(e, op, e.getExpression()); + } + + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + binary(e); + } + + public void visitNegateExpression(NegateExpression e) + throws VisitorException { + unary(e); + } + + public void visitNotExpression(NotExpression e) throws VisitorException { + unary(e); + } + + public void visitOrExpression(OrExpression e) throws VisitorException { + binary(e); + } + + public void visitXorExpression(XorExpression e) throws VisitorException { + binary(e); + } + + public void visitPeekExpression(PeekExpression e) throws VisitorException { + beginChannel(e); + e.getChannelExpression().accept(this); + endChannel(e); + } + + public void visitProbeExpression(ProbeExpression e) + throws VisitorException { + beginChannel(e); + e.getChannelExpression().accept(this); + endChannel(e); + } + + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException { + beginChannel(e); + e.getChannelExpression().accept(this); + endChannel(e); + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + binary(e); + } + + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + binary(e); + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + // XXX: encode special characters + print(""); + } + + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + beginTag(e, "field=\"" + e.getFieldName() + "\" "); + e.getStructureExpression().accept(this); + endTag(e); + } + + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + binary(e); + } + + + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + beginTag(s); + beginTag("lhs"); + s.getLeftHandSide().accept(this); + endTag("lhs"); + beginTag("rhs"); + s.getRightHandSide().accept(this); + endTag("rhs"); + endTag(s); + } + + public void visitDeterministicRepetitionStatement(DeterministicRepetitionStatement s) + throws VisitorException { + guarded(s); + } + + public void visitDeterministicSelectionStatement(DeterministicSelectionStatement s) + throws VisitorException { + guarded(s); + } + + public void visitErrorStatement(ErrorStatement s) throws VisitorException { + print(""); + } + + public void visitLoopStatement(LoopStatement s) + throws VisitorException { + String op = "unknown"; + switch (s.getSeparator()) { + case LoopStatement.SEQUENTIAL: + op = "sequential"; + break; + case LoopStatement.PARALLEL: + op = "parallel"; + break; + } + loop(s, op, s.getStatement()); + } + + public void visitNonDeterministicRepetitionStatement(NonDeterministicRepetitionStatement s) + throws VisitorException { + guarded(s); + } + + public void visitNonDeterministicSelectionStatement(NonDeterministicSelectionStatement s) + throws VisitorException { + guarded(s); + } + + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + composite(s); + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + channel(s); + } + + public void visitSendStatement(SendStatement s) throws VisitorException { + channel(s); + } + + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + composite(s); + } + + public void visitSkipStatement(SkipStatement s) throws VisitorException { + print(""); + } + + private void printDeclarationList(DeclarationList l) + throws VisitorException { + for (Iterator it = l.getDeclarations(); it.hasNext(); ) { + Declaration d = (Declaration) it.next(); + + for (Iterator it2 = d.getDeclaratorList().getDeclarators() ; + it2.hasNext(); ) { + Declarator d2 = (Declarator) it2.next(); + + beginTag("Declarator"); + d2.getIdentifier().accept(this); + d2.getTypeFragment().accept(this); + if (d2.getInitializer() != null) { + beginTag("initializer"); + d2.getInitializer().accept(this); + endTag("initializer"); + } + endTag("Declarator"); + } + } + } + + public void visitVarStatement(VarStatement s) throws VisitorException { + beginTag(s); + printDeclarationList(s.getDeclarationList()); + + // ???: When will this not be null? + if (s.getStatement() != null) + throw new VisitorException("s.getStatement() is not null!"); + endTag(s); + } + + public void visitChannelType(ChannelType t) throws VisitorException { + throw new AssertionError("Declarations of channels not supported."); + } + + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + throw new AssertionError("Declarations of structures of " + + "channels not supported."); + } + + public void visitArrayType(ArrayType t) throws VisitorException { + beginTag(t); + beginTag("min"); + t.getRange().getMinExpression().accept(this); + endTag("min"); + beginTag("max"); + t.getRange().getMaxExpression().accept(this); + endTag("max"); + beginTag("elementType"); + t.getElementType().accept(this); + endTag("elementType"); + endTag(t); + } + + public void visitIntegerType(IntegerType t) throws VisitorException { + print(""); + } + + public void visitBooleanType(BooleanType t) throws VisitorException { + print(""); + } + + public void visitNodeType(NodeType t) throws VisitorException { + throw new AssertionError("Declarations of nodes not supported."); + } + + public void visitIdentifierList(IdentifierList il) + throws VisitorException { + Debug.unimplemented(); + } + + + public void visitLinkageLoopTerm(LinkageLoopTerm term) + throws VisitorException { + Debug.unimplemented(); + } + + public void visitLinkageExpressionTerm(LinkageExpressionTerm term) + throws VisitorException { + Debug.unimplemented(); + } + + + public void visitLinkageArrayAccessExpression(LinkageArrayAccessExpression e) + throws VisitorException { + Debug.unimplemented(); + } + + public void visitLinkageIdentifierExpression(LinkageIdentifierExpression e) + throws VisitorException { + Debug.unimplemented(); + } + + public void visitLinkageStructureAccessExpression(LinkageStructureAccessExpression e) throws VisitorException { + Debug.unimplemented(); + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + Debug.unimplemented(); + } + + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + beginTag(s); + s.getExpression().accept(this); + endTag(s); + } + + public void visitStringType(StringType t) throws VisitorException { + print(""); + } + + public void visitStructureType(StructureType t) throws VisitorException { + print(""); + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + beginTag(e, "field=\"" + e.getMemberName() + "\" "); + e.getStructureExpression().accept(this); + endTag(e); + } + public static String print(ExpressionInterface ei) { + if (ei == null) return "null"; + final java.io.StringWriter sw = new java.io.StringWriter(); + final PrintWriter pw = new PrintWriter(sw); + final XmlTourist tour = new XmlTourist(pw); + String result = "visit exception"; + try { + ei.accept(tour); + pw.flush(); + result = sw.toString(); + } catch (VisitorException e) { } + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/Csp.g b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/Csp.g new file mode 100644 index 0000000000..cfc6acd40f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/Csp.g @@ -0,0 +1,835 @@ +// +// Copyright 2001 Asynchronous Digital Design. All rights reserved. +// +// $Id$ +// + +// authors: Jesse Rosenstock, Tim Crowder +// version: $Revision$ $Date$ + +header { + package com.avlsi.csp.grammar; + + import java.math.BigInteger; + + import com.avlsi.util.container.Pair; + import com.avlsi.cast2.impl.CastTwoUtil; + import com.avlsi.csp.ast.*; +} + +class CspParser extends Parser; +options { + buildAST = false; + k = 3; + defaultErrorHandler = false; +} +{ + private antlr.TokenStreamSelector selector = null; + + public void setSelector(final antlr.TokenStreamSelector selector) { + this.selector = selector; + } + + private IntegerExpression decodeInt(final String s) { + // XXX: catch exceptions, mapping to something or other + if (s.startsWith("0x")) + return new IntegerExpression(s.substring(2), 16); + else if (s.startsWith("0b")) + return new IntegerExpression(s.substring(2), 2); + else { + final int underIdx = s.indexOf('_'); + if (underIdx == -1) + return new IntegerExpression(s, 10); + else { + final String radixString = s.substring(0, underIdx); + final int radix = Integer.parseInt(radixString); + final String valString = s.substring(underIdx + 1); + + return new IntegerExpression(valString, radix); + } + } + } + private IntegerExpression trueExpression() { + return new BooleanExpression(true); + } + private IntegerExpression falseExpression() { + return new BooleanExpression(false); + } + private StatementInterface waitStatement(final ExpressionInterface e) { + final DeterministicSelectionStatement stmt = + new DeterministicSelectionStatement(); + final SkipStatement skip = + new SkipStatement(); + stmt.epr(e); + skip.epr(e); + stmt.addGuardedCommand(new GuardedCommand(e, skip)); + return stmt; + } + private StatementInterface infiniteLoop(final StatementInterface s) { + final DeterministicRepetitionStatement stmt = + new DeterministicRepetitionStatement(); + final IntegerExpression true_exp = trueExpression(); + stmt.epr(s); + true_exp.epr(s); + stmt.addGuardedCommand(new GuardedCommand(true_exp, s)); + return stmt; + } +} +// ANTLR only expects EOFs after "start rules", which are rules +// that are not referred to by any in the grammar. If we don't +// have this rule, EOF will break us! +program returns [Pair pair = null] + { FunctionDeclaration funcDecl; StatementInterface s; + StructureDeclaration structDecl; + CSPProgram prog = new CSPProgram(); } + : ( funcDecl=function_decl {prog.addFunctionDeclaration(funcDecl); + prog.epr(funcDecl);} + | structDecl=structure_decl {prog.addStructureDeclaration(structDecl); + prog.epr(structDecl);} + )* + ( s=sequential_statement {prog.setStatement(s); + prog.epr(s);} )? + ( DIRECTIVES l:LCURLY {l.setText(CastTwoUtil.getDumbBlockString(selector, + this));})? + EOF + { pair = new Pair(prog, l); } + ; +function_decl returns [FunctionDeclaration funcDecl = null] + { DeclarationList decList = null; Type t = null; StatementInterface s; } + : func:FUNCTION id:IDENT paren:LPAREN + ( decList=declaration_list[true] + | /*empty*/ {decList = new DeclarationList(); + decList.epr(paren);} + ) RPAREN ( COLON t=type )? ASSIGN s=statement semi:SEMI + { funcDecl = new FunctionDeclaration(id.getText(), decList, t, s); + funcDecl.epr(func, semi); } + ; +var_statement returns [VarStatement varStmt = null] + { StatementInterface stmt = null; + DeclarationList decList = null; + Declaration dec = null; } + : dec=declaration[false] + { varStmt = new VarStatement (dec); + varStmt.epr(dec); } + ; +loop_statement returns [StatementInterface stmt = null] + { Range r; StatementInterface s; int sep = -1; Token t=null; } +/* XXX: not sure this will work --frederik */ + : (la0:LANGL {sep = LoopStatement.SEQUENTIAL; t=la0; } + |la1:SLOOP {sep = LoopStatement.SEQUENTIAL; t=la1; } + |la2:BLOOP {sep = LoopStatement.PARALLEL; t=la2; } + |la3:CLOOP {sep = LoopStatement.PARALLEL; t=la3; }) + id:IDENT COLON r=range COLON LPAREN s=sequential_statement RPAREN ra:RANGL + { stmt = new LoopStatement(id.getText(), r, sep, s); + stmt.epr(t,ra); } + ; +sequential_part returns [StatementInterface stmt] + : ( var_statement ) => stmt=var_statement + | stmt=parallel_statement + ; +sequential_statement returns [SequentialStatement seqStmt] + { seqStmt = new SequentialStatement(); + StatementInterface stmt; } + // Interspersed var statements and parallel statements. We used to require + // that every var statement must be followed by a parallel statement, and + // at least one parallel statement must occur. + : stmt=sequential_part {seqStmt.addStatement(stmt); seqStmt.epr(stmt);} + ( options { warnWhenFollowAmbig = false; } : + SEMI stmt=sequential_part {seqStmt.addStatement(stmt); + seqStmt.epr(stmt);} + )* + ( SEMI )? + ; +parallel_statement returns [StatementInterface stmt] + { ParallelStatement parStmt = null; } + : stmt=statement + (COMMA + { if (parStmt == null) { + parStmt = new ParallelStatement(); + parStmt.addStatement(stmt); + parStmt.epr(stmt); + } + } + stmt=statement { parStmt.addStatement(stmt); + parStmt.epr(stmt); } + )* + { if (parStmt != null) + stmt = parStmt; + } + ; +statement returns [StatementInterface stmt = null] + { ExpressionInterface e; } + : lp:LPAREN stmt=sequential_statement rp:RPAREN + { stmt.epr(lp,rp); } + | (LBRACK | ( HASH LBRACK ) ) => stmt=selection_statement + | stmt=repetition_statement + | (lvalue + ( ASSIGN | PASSIGN | MASSIGN | TASSIGN | XASSIGN | + DASSIGN | RASSIGN | AASSIGN | OASSIGN | LSASSIGN | RSASSIGN ) + ) => stmt=assignment_statement + | (lvalue ( INC | DEC ) ) => stmt=incdec_statement + | (HASH | ( lvalue ( QUEST | BANG ) ) ) => stmt=communication_statement + | (lvalue ( PLUS | MINUS ) ) => stmt=bool_assignment_statement + | e=lvalue { stmt=new ExpressionStatement(e); stmt.epr(e); } + | stmt=loop_statement + | err:ERROR {stmt = new ErrorStatement(getFilename(), err.getLine(), + err.getColumn()); + stmt.epr(err); } + | sk:SKIP {stmt = new SkipStatement(); + stmt.epr(sk); } + ; +selection_statement returns [StatementInterface stmt = null] + { ExpressionInterface e; AbstractGuardedStatement g = null; } + : lb:LBRACK ( ( (expression (AT | ARROW)) | CLLOOP | BOXLOOP ) + => stmt=guard_commands[false] + | e=expression {stmt = waitStatement(e);} + ) rb:RBRACK {stmt.epr(lb,rb);} + | ha:HASH LBRACK {g=new DeterministicSelectionStatement();} + det_guard_noelse_commands[g] rb1:RBRACK + {g.addElseStatement((StatementInterface) new SkipStatement().epr(ha)); + stmt = g; stmt.epr(ha,rb1);} + ; +repetition_statement returns [StatementInterface stmt = null] + { StatementInterface s; } + : lo:LOOP + ( ( (expression ARROW) | CLLOOP | BOXLOOP ) => stmt=guard_commands[true] + | s=sequential_statement {stmt = infiniteLoop(s);}) + rb:RBRACK {stmt.epr(lo,rb);} + ; +assignment_statement returns [StatementInterface stmt = null] + { ExpressionInterface e1, e2; char kind = AssignmentStatement.EQUAL; } + : e1=lvalue + ( ASSIGN { kind = AssignmentStatement.EQUAL; } + | PASSIGN { kind = AssignmentStatement.ADD; } + | MASSIGN { kind = AssignmentStatement.SUBTRACT; } + | TASSIGN { kind = AssignmentStatement.MULTIPLY; } + | DASSIGN { kind = AssignmentStatement.DIVIDE; } + | RASSIGN { kind = AssignmentStatement.REMAINDER; } + | AASSIGN { kind = AssignmentStatement.AND; } + | OASSIGN { kind = AssignmentStatement.OR; } + | XASSIGN { kind = AssignmentStatement.XOR; } + | LSASSIGN { kind = AssignmentStatement.LEFTSHIFT; } + | RSASSIGN { kind = AssignmentStatement.RIGHTSHIFT; } + ) + e2=expression + {stmt = new AssignmentStatement(e1, e2, kind); stmt.epr(e1,e2);} + ; +incdec_statement returns [StatementInterface stmt = null] + { ExpressionInterface e1; boolean inc = false; } + : e1=lvalue ( i:INC { inc = true; e1.epr(i); } + | d:DEC { inc = false; e1.epr(d); } ) + {stmt = new IncDecStatement(e1, inc); stmt.epr(e1); } + ; +bool_assignment_statement returns [StatementInterface stmt = null] + { ExpressionInterface e1, e2 = null; } + : e1=lvalue ( p:PLUS { e2 = trueExpression(); e2.epr(p); } + | m:MINUS { e2 = falseExpression(); e2.epr(m); }) + {stmt = new AssignmentStatement(e1, e2); stmt.epr(e1, e2);} + ; +communication_statement returns [StatementInterface stmt = null] + { ExpressionInterface e1, e2=null; + boolean peekP = false;} + : ha:HASH e1=lvalue QUEST e2=lvalue + {stmt = new AssignmentStatement(e2, + (PeekExpression)new PeekExpression(e1).epr(e1)); + stmt.epr(ha,e2);} + | e1=lvalue + // note that e2 may be null for recv + ( q:QUEST (e2=lvalue)? {stmt = new ReceiveStatement(e1, e2); + stmt.epr(e1,q); stmt.epr(e2);} + | b:BANG (e2=expression)? { + stmt = new SendStatement(e1, + e2 != null ? e2 + : (IntegerExpression)falseExpression().epr(b)); + stmt.epr(e1,b); stmt.epr(e2); } + ) + ; +guard_commands[boolean repetitionP] returns [StatementInterface stmt = null] + : ( CLLOOP + | expression ( AT | ARROW sequential_statement COLON ) ) => + stmt=non_det_guard_commands[repetitionP] + | stmt=det_guard_commands[repetitionP] + ; +det_guard_commands[boolean repetitionP] +returns [AbstractGuardedStatement stmt] + { StatementInterface s; + stmt = repetitionP + ? (AbstractGuardedStatement) + new DeterministicRepetitionStatement() + : (AbstractGuardedStatement) + new DeterministicSelectionStatement(); } + : det_guard_noelse_commands[stmt] + (BOX s=guard_else_command {stmt.addElseStatement(s); + stmt.epr(s);})? + ; +det_guard_noelse_commands[AbstractGuardedStatement stmt] + { GuardedCommandInterface g; } + : g=det_guard_command {stmt.addGuardedCommand(g); stmt.epr(g);} + (BOX g=det_guard_command {stmt.addGuardedCommand(g); stmt.epr(g);})* + ; +non_det_guard_linked[boolean repetitionP, AbstractGuardedStatement stmt] + { GuardedCommandInterface g; LinkageTerms neutralTerms = null; } + : g=linked_guard_command {stmt.addGuardedCommand(g); + stmt.epr(g);} + (COLON g=linked_guard_command {stmt.addGuardedCommand(g); + stmt.epr(g);})* + COLON neutralTerms=linkage_specifier + { if (repetitionP) + ((NonDeterministicRepetitionStatement) stmt) + .setNeutralState(neutralTerms); + else + ((NonDeterministicSelectionStatement) stmt) + .setNeutralState(neutralTerms); + stmt.epr(neutralTerms); + } + ; +non_det_guard_simple[boolean repetitionP, AbstractGuardedStatement stmt] + { GuardedCommandInterface g; } + : g=non_det_guard_command {stmt.addGuardedCommand(g); stmt.epr(g);} + (COLON g=non_det_guard_command {stmt.addGuardedCommand(g); stmt.epr(g);})* + ; +non_det_guard_commands[boolean repetitionP] +returns [AbstractGuardedStatement stmt] + { stmt = repetitionP + ? (AbstractGuardedStatement) + new NonDeterministicRepetitionStatement() + : (AbstractGuardedStatement) + new NonDeterministicSelectionStatement(); } + : ( non_det_guard_simple[repetitionP, stmt] ) => + non_det_guard_simple[repetitionP, stmt] + | non_det_guard_linked[repetitionP, stmt] + ; +guard_command_simple returns [GuardedCommandInterface guardedCommand = null] + { ExpressionInterface expr; + SequentialStatement seqStmt; } + : expr=expression ARROW seqStmt=sequential_statement + { guardedCommand = new GuardedCommand(expr, seqStmt); + guardedCommand.epr(expr); + guardedCommand.epr(seqStmt);} + ; +det_guard_command returns [GuardedCommandInterface guardedCommand = null] + { GuardedCommandInterface g; + LoopGuard loop = null; + Range r; } + : guardedCommand=guard_command_simple + | la:BOXLOOP bid:IDENT COLON r=range COLON LPAREN + {loop = new LoopGuard(bid.getText(), r, LoopGuard.BOX);} + g=det_guard_command {loop.addGuard(g);} + (BOX g=det_guard_command {loop.addGuard(g);})* + RPAREN ra:RANGL + { guardedCommand = loop; guardedCommand.epr(la,ra); } + ; +non_det_guard_command returns [GuardedCommandInterface guardedCommand = null] + { GuardedCommandInterface g; + LoopGuard loop = null; + Range r; } + : guardedCommand=guard_command_simple + | lb:CLLOOP cid:IDENT COLON r=range COLON LPAREN + {loop = new LoopGuard(cid.getText(), r, LoopGuard.COLON);} + g=non_det_guard_command {loop.addGuard(g);} + (COLON g=non_det_guard_command {loop.addGuard(g);})* + RPAREN rb:RANGL + { guardedCommand = loop; guardedCommand.epr(lb,rb); } + ; +linked_guard_command returns [GuardedCommandInterface guardedCommand = null] + { ExpressionInterface guardExpr; + LinkageTerms linkTerms; + SequentialStatement seqStmt; + GuardedCommandInterface g; + LoopGuard loop = null; + Range r; } + : guardExpr=expression linkTerms=linkage_specifier + ARROW seqStmt=sequential_statement + { guardedCommand = new GuardedCommand(guardExpr, linkTerms, seqStmt); + guardedCommand.epr(guardExpr,seqStmt); } + | lb:CLLOOP cid:IDENT COLON r=range COLON LPAREN + {loop = new LoopGuard(cid.getText(), r, LoopGuard.COLON);} + g=linked_guard_command {loop.addGuard(g);} + (COLON g=linked_guard_command {loop.addGuard(g);})* + RPAREN rb:RANGL + { guardedCommand = loop; guardedCommand.epr(lb,rb); } + ; +linkage_specifier returns [LinkageTerms terms] + : at:AT LPAREN terms=linkage_terms rp:RPAREN + { terms.epr(at,rp); } + ; +guard_else_command returns [SequentialStatement stmt] + : el:ELSE ARROW stmt=sequential_statement + { stmt.epr(el,stmt); } + ; +linkage_terms returns [LinkageTerms terms = new LinkageTerms()] + { LinkageTermInterface term; } + : term=linkage_term {terms.addTerm(term); + terms.epr(term); } + ( COMMA term=linkage_term {terms.addTerm(term); + terms.epr(term); } )* + ; +linkage_term returns [LinkageTermInterface term = null] + { boolean isInverted = false; + LinkageExpressionInterface expr = null; + ExpressionInterface e; + Range r; } + : ( ti:TILDE { isInverted = true; } )? + id1:IDENT { expr = new LinkageIdentifierExpression(id1.getText()); + expr.epr(ti,id1); } + ( DOT id2:IDENT + { expr = (LinkageExpressionInterface) + (new LinkageStructureAccessExpression(expr, id2.getText())) + .epr(expr,id2); } + | DOT id4:INTEGER + { expr = (LinkageExpressionInterface) + (new LinkageStructureAccessExpression(expr, id4.getText())) + .epr(expr,id4); } + | LBRACK e=expression + { expr = (LinkageExpressionInterface) + (new LinkageArrayAccessExpression(expr, e)) + .epr(expr,e); } + ( COMMA e=expression + { expr = (LinkageExpressionInterface) + (new LinkageArrayAccessExpression(expr, e)) + .epr(expr,e); } )* + rb:RBRACK {expr.epr(rb);} + )* + { term = new LinkageExpressionTerm(expr, isInverted); + term.epr(expr); } + | cl:CLOOP id3:IDENT COLON + r=range COLON + ( term=linkage_term | LPAREN term=linkage_term RPAREN ) ra:RANGL + { term = new LinkageLoopTerm(id3.getText(), r, term); + term.epr(cl,ra); } + ; +expression returns [ExpressionInterface expr] + : expr=conditional_or_expression + ; +loop_expression returns [ExpressionInterface expr = null] + { Range r; ExpressionInterface e; int sep = -1; Token t=null; } + : (lo0:PLOOP {sep = LoopExpression.PLUS; t=lo0; } + |lo1:MLOOP {sep = LoopExpression.TIMES; t=lo1; } + |lo2:ALOOP {sep = LoopExpression.AND; t=lo2; } + |lo3:OLOOP {sep = LoopExpression.OR; t=lo3; } + |lo4:XLOOP {sep = LoopExpression.XOR; t=lo4; }) + id:IDENT COLON r=range COLON LPAREN e=expression RPAREN ra:RANGL + { expr = new LoopExpression(id.getText(), r, sep, e); + expr.epr(t,ra); } + ; +conditional_or_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=conditional_and_expression + (PIPE2 e2=conditional_and_expression + {expr = (ExpressionInterface) + new ConditionalOrExpression(expr, e2).epr(expr,e2);})* + ; +conditional_and_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=or_expression + (AMP2 e2=or_expression + {expr = (ExpressionInterface) + new ConditionalAndExpression(expr, e2).epr(expr,e2);})* + ; +or_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=xor_expression + (PIPE e2=xor_expression + {expr = (ExpressionInterface) + new OrExpression(expr, e2).epr(expr,e2);})* + ; +xor_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=and_expression + (CARET e2=and_expression + {expr = (ExpressionInterface) + new XorExpression(expr, e2).epr(expr,e2);})* + ; +and_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=equal_expression + (AMP e2=equal_expression + {expr = (ExpressionInterface) + new AndExpression(expr, e2).epr(expr,e2);})* + ; +equal_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=rel_expression + (NEQ e2=rel_expression + {expr = (ExpressionInterface) + new InequalityExpression(expr, e2).epr(expr,e2); } + |EQUAL e2=rel_expression + {expr = (ExpressionInterface) + new EqualityExpression(expr, e2).epr(expr,e2); } + )* + ; +rel_expression returns [ExpressionInterface expr] + // the RANGL causes nondeterminism, which way is it resolved? + { ExpressionInterface e2; } + : expr=shift_expression + (LEQ e2=shift_expression + {expr = (ExpressionInterface) + new LessEqualExpression(expr, e2).epr(expr,e2);} + |GEQ e2=shift_expression + {expr = (ExpressionInterface) + new GreaterEqualExpression(expr, e2).epr(expr,e2);} + |LANGL e2=shift_expression + {expr = (ExpressionInterface) + new LessThanExpression(expr, e2).epr(expr,e2);} + |RANGL e2=shift_expression + {expr = (ExpressionInterface) + new GreaterThanExpression(expr, e2).epr(expr,e2);} + )* + ; +shift_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=add_expression + (LSHIFT e2=add_expression + {expr = (ExpressionInterface) + new LeftShiftExpression(expr, e2).epr(expr,e2); } + |RSHIFT e2=add_expression + {expr = (ExpressionInterface) + new RightShiftExpression(expr, e2).epr(expr,e2); } + )* + ; +add_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=mult_expression + (PLUS e2=mult_expression + {expr = (ExpressionInterface) + new AddExpression(expr, e2).epr(expr,e2);} + |MINUS e2=mult_expression + {expr = (ExpressionInterface) + new SubtractExpression(expr, e2).epr(expr,e2);} + )* + ; +mult_expression returns [ExpressionInterface expr] + { ExpressionInterface e2; } + : expr=unary_expression + (STAR e2=unary_expression + {expr = (ExpressionInterface) + new MultiplyExpression(expr, e2).epr(expr,e2);} + |SLASH e2=unary_expression + {expr = (ExpressionInterface) + new DivideExpression(expr, e2).epr(expr,e2);} + |CENT e2=unary_expression + {expr = (ExpressionInterface) + new RemainderExpression(expr, e2).epr(expr,e2);} + )* + ; +unary_expression returns [ExpressionInterface expr] + : TILDE expr=unary_expression + {expr = (ExpressionInterface) + new NotExpression(expr).epr(expr);} + | MINUS expr=unary_expression + {expr = (ExpressionInterface) + new NegateExpression(expr).epr(expr);} + | expr=exponential_expression + ; +exponential_expression returns [ExpressionInterface expr] + { ExpressionInterface e; } + : expr=primary_expression + ( EXP e=unary_expression + {expr = (ExpressionInterface) + new ExponentialExpression(expr, e).epr(expr,e);} )? + ; +primary_expression returns [ExpressionInterface expr = null] + : i:INTEGER {expr = decodeInt(i.getText()); expr.epr(i);} + | tr:TRUE {expr = trueExpression(); expr.epr(tr);} + | fa:FALSE {expr = falseExpression(); expr.epr(fa);} + | s:STRING_LITERAL {expr = new StringExpression(s.getText()); expr.epr(s);} + | LPAREN expr=expression RPAREN + | (lvalue QUEST) => expr=communication_expression + | expr=lvalue + | expr=probe_expression + | expr=loop_expression + ; +probe_expression returns [ExpressionInterface expr] + : ha:HASH expr=lvalue + (q:QUEST {expr = (ExpressionInterface) + new PeekExpression(expr).epr(ha,q);} + |/*empty*/ {expr = (ExpressionInterface) + new ProbeExpression(expr).epr(ha,expr);} + ) + // | HASH lvalue ((COMMA lvalue)* COLON expression)? + ; +communication_expression returns [ExpressionInterface expr] + : expr=lvalue qu:QUEST + {expr = (ExpressionInterface) + new ReceiveExpression(expr).epr(expr,qu);} + ; +range returns [Range r = null] + { ExpressionInterface minExpr, maxExpr; } + : minExpr=expression + ( DOTDOT maxExpr=expression + {r = new Range(minExpr, maxExpr); r.epr(minExpr,maxExpr);} + | /*empty*/ { IntegerExpression i0=new IntegerExpression("0", 10); + IntegerExpression i1=new IntegerExpression("1", 10); + SubtractExpression s0=new SubtractExpression(minExpr,i1); + i0.epr(minExpr); i1.epr(i0); s0.epr(i0); + r = new Range(i0,s0); r.epr(minExpr);} + ) + ; +identifier returns [IdentifierExpression ident = null] + : id:IDENT {ident = new IdentifierExpression(id.getText()); + ident.epr(id);} + ; +lvalue returns [ExpressionInterface expr = null] + { ExpressionInterface e1, e2 = null; + FunctionCallExpression funcCall = null; } + : ( expr=identifier + | st:STRING { expr=new IdentifierExpression(st.getText()); + expr.epr(st); + } + ) + ( + // Array slicing has been removed until it is demanded. + ( LBRACK // ((expression DOTDOT) => range + // | expression + // ) + e2=expression {expr = (ExpressionInterface) + new ArrayAccessExpression(expr, e2).epr(expr,e2);} + ( COMMA e2=expression + {expr = (ExpressionInterface) + new ArrayAccessExpression(expr, e2).epr(expr,e2);} + )* + rb:RBRACK {expr.epr(rb);} + ) + | LCURLY e1=expression ( COLON e2=expression | /*empty*/ {e2=null;} ) + rc:RCURLY {expr = (ExpressionInterface) + new BitRangeExpression(expr, e2, e1).epr(expr,rc);} + | LPAREN {funcCall = new FunctionCallExpression(expr);} + ( e2=expression {funcCall.addActual(e2);} + ( COMMA e2=expression {funcCall.addActual(e2);} )* )? + rp:RPAREN {expr = (ExpressionInterface)funcCall.epr(expr,rp);} + | DOT id:IDENT + {expr = (ExpressionInterface) + new StructureAccessExpression(expr, id.getText()).epr(expr,id);} + | DOT ie:INTEGER + {expr = (ExpressionInterface) + new StructureAccessExpression(expr, ie.getText()).epr(expr,ie);} + | COLON2 mbr:IDENT + {expr = (ExpressionInterface) + new MemberAccessExpression(expr, mbr.getText()).epr(expr,mbr);} + )* + ; +declaration_list[boolean formalP] returns [DeclarationList declList] + { declList = new DeclarationList (); + Declaration decl = null; } + : decl=declaration[formalP] {declList.addDeclaration(decl); + declList.epr(decl);} + ( SEMI decl=declaration[formalP] {declList.addDeclaration(decl); + declList.epr(decl);} )* + ( SEMI )? + ; +declaration[boolean formalP] returns [Declaration decl = null] + { IdentifierList idList; + DeclaratorList decList; + Type t; } +// : idList=identifier_list COLON t=type +// { decl = new Declaration(idList, t); } + : t=type decList=declarator_list[formalP] + { decl = new Declaration(decList, t); + decl.epr(t,decList); } + ; +declarator_list[boolean formalP] returns [DeclaratorList decList] + { decList = new DeclaratorList(); + Declarator dec = null; } + : dec=declarator[formalP] {decList.addDeclarator(dec); + decList.epr(dec);} + ( COMMA dec=declarator[formalP] {decList.addDeclarator(dec); + decList.epr(dec);} )* + ; + +declarator[boolean formalP] returns [Declarator dec] + { IdentifierExpression ident = null; + ExpressionInterface init = null; + ArrayType s, t = null; + Range rng; + int dir = Declarator.NONE; + Token pm = null; + dec = null; } + : ( {formalP}? ( p:PLUS {dir=Declarator.OUT; pm = p;} + ( MINUS {dir=Declarator.INOUT;} )? + | m:MINUS {dir=Declarator.IN; pm = m;} + ( PLUS {dir=Declarator.INOUT;} )? ) )? + ident=identifier + {dec = new Declarator(ident, null, null, dir); dec.epr(ident); + if (pm != null) dec.epr(pm);} + ( lb:LBRACK rng=range rb:RBRACK + { s=new ArrayType(rng, null); s.epr(lb,rb); + if (t == null) { + dec.setTypeFragment(s); + dec.epr(s); + } else { + t.setElementType(s); + t.epr(s); + } + t = s; + } + )* + ( ASSIGN init=expression {dec.setInitializer(init); + dec.epr(init);} )? + ; +identifier_list returns [IdentifierList idList] + { idList = new IdentifierList(); + IdentifierExpression ident = null; } + : ident=identifier + {idList.addIdentifier(ident); idList.epr(ident);} + ( COMMA ident=identifier + {idList.addIdentifier(ident); idList.epr(ident);} )* + ; +type returns [Type t] + { boolean constantP = false; + ExpressionInterface bits = null; + t = null; } + : (co:CONST {constantP = true;})? + ( to0:INT ( LPAREN bits=expression RPAREN )? + {t = (Type)new IntegerType(constantP, bits).epr(co,to0);} + | to4:SINT LPAREN bits=expression RPAREN + {t = (Type)new IntegerType(constantP, true, bits).epr(co,to0);} + | to1:BOOLEAN {t = (Type)new BooleanType(constantP).epr(co,to1);} + | to2:BOOL {t = (Type)new BooleanType(constantP).epr(co,to2);} + | to3:STRING {t = (Type)new StringType(constantP).epr(co,to3);} + | id:IDENT {t = (Type)new StructureType(constantP, id.getText()).epr(co,id);} ) + ; +structure_decl returns [StructureDeclaration sd] + { DeclarationList decl = null; + sd = null; } + : st:STRUCTURE id:IDENT ASSIGN LPAREN decl=declaration_list[false] RPAREN + semi:SEMI + { sd = new StructureDeclaration(id.getText(), decl); sd.epr(st, semi); } + ; +class CspLexer extends Lexer; +options { + k = 3; + charVocabulary = '\3' .. '\377'; // needed for ~ to make sense + testLiterals = false; +} +tokens { + TRUE="true"; + FALSE="false"; + ERROR="error"; + SKIP="skip"; + ELSE="else"; + BOOLEAN="boolean"; + BOOL="bool"; + INT="int"; + SINT="sint"; + CONST="const"; + FUNCTION="function"; + DIRECTIVES="directives"; + STRUCTURE="structure"; + STRING="string"; +} + +{ + public Token makeToken(final int t) { + final Token tok = super.makeToken(t); + ((com.avlsi.cast.impl.TokenWithInfo) tok).setFilename(getFilename()); + return tok; + } +} + +WS : (' ' | '\t' | '\n' { newline(); } | '\r') { _ttype = Token.SKIP; } ; +protected ALPHA : (('a'..'z') | ('A'..'Z') | '_') ; +protected DIGIT : ('0'..'9') ; +protected HEX_DIGIT : DIGIT | 'a'..'f' | 'A'..'F' ; +protected BIN_DIGIT : '0' | '1'; +IDENT + options { testLiterals = true; } + : ALPHA (ALPHA | DIGIT)* ; +INTEGER + : (DIGIT)+ ( '_' (('a'..'z') | ('A'..'Z') | DIGIT)+ )? + | "0x" ('_'!)? (HEX_DIGIT)+ ('_'! (HEX_DIGIT)+)* + | "0b" ('_'!)? (BIN_DIGIT)+ ('_'! (BIN_DIGIT)+)* + ; +LPAREN: '(' ; RPAREN: ')' ; +LBRACK: '[' ; RBRACK: ']' ; +LCURLY: '{' ; RCURLY: '}' ; +BOX :"[]" ; +LOOP :"*[" ; +PLOOP :"<+" ; MLOOP :"<*" ; ALOOP :"<&" ; OLOOP :"<|" ; +SLOOP :"<;" ; BLOOP :"<||"; CLOOP :"<," ; XLOOP :"<^" ; +BOXLOOP :"<[]"; CLLOOP: "<:"; +LANGL : '<' ; RANGL : '>' ; +LSHIFT:"<<" ; RSHIFT:">>" ; +LEQ :"<=" ; GEQ :">=" ; +ARROW : "->"; +EQUAL : "==" ; +NEQ :"!=" ; +ASSIGN: '=' ; PASSIGN:"+="; MASSIGN:"-="; TASSIGN:"*="; +DASSIGN:"/="; RASSIGN:"%="; AASSIGN:"&="; OASSIGN:"|="; +LSASSIGN:"<<="; RSASSIGN:">>="; XASSIGN:"^="; +INC : "++"; DEC : "--"; +TILDE : '~' ; +STAR : '*' ; SLASH : '/' ; +CENT : '%' ; +PLUS : '+' ; MINUS : '-' ; +EXP : "**" ; +DOT : '.' ; COMMA : ',' ; +SEMI : ';' ; COLON : ':' ; +COLON2: "::"; +DOTDOT: ".."; +QUEST : '?' ; +BANG : '!' ; +PIPE : '|' ; +PIPE2 : "||"; +AMP : '&' ; +AMP2 : "&&"; +CARET : "^" ; +HASH : '#' ; +AT : '@' ; +//PEEK : "#?" ; + +COMMENT_1 + : "/*" + ( options { generateAmbigWarnings=false; } + : { LA(2) != '/' }? '*' + | '\n' { newline(); } + | ~('*' | '\n' | '\r') + )* + "*/" + { $setType(Token.SKIP); } + ; + +COMMENT_2 + : "//" (~ '\n' )* '\n' { $setType(Token.SKIP); newline(); } + ; + +STRING_LITERAL + : '"'! (ESC|'\n' { newline(); } | ~('"'|'\\'|'\n'))* '"'! + ; + +protected +ESC + : '\\' + ( 'n' { $setText("\n"); } + | 'r' { $setText("\r"); } + | 't' { $setText("\t"); } + | 'b' { $setText("\b"); } + | 'f' { $setText("\f"); } + | '"' { $setText("\""); } + | '\'' { $setText("'"); } + | '\\' { $setText("\\"); } + | 'x' HEX_DIGIT HEX_DIGIT { + String esc = $getText; + char c[] = { (char) Integer.parseInt(esc.substring(2), 16) }; + String s = new String(c); + $setText(s); + } + | ('0'..'3') + ( + options { + warnWhenFollowAmbig = false; + } + : ('0'..'7') + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + )? + )? { + String esc = $getText; + char c[] = { (char) Integer.parseInt(esc.substring(1), 8) }; + String s = new String(c); + $setText(s); + } + ) + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParsePosition.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParsePosition.java new file mode 100644 index 0000000000..68d88a5b70 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParsePosition.java @@ -0,0 +1,111 @@ +package com.avlsi.csp.grammar; + +import com.avlsi.util.debug.Debug; +import antlr.Token; +import com.avlsi.cast.impl.TokenWithInfo; + +// XXX: use a different class, or put this class in a different place +import com.avlsi.csp.coverage.ParseException; + +/** + * Class representing a position in a file, used for reporting parse + * errors and such. @see ParseRange + * + * @author Frederik Eaton + * @version $Revision$ $Date$ + **/ +public class ParsePosition implements Cloneable { + public int line; + public int column; + public String filename; + + private static final String emptyFilename="empty_parse_position"; + + /** create an empty ParsePosition for use as a placeholder **/ + public ParsePosition() { + line=0; column=0; filename=emptyFilename; + } + + public ParsePosition(int line, int column, String filename) { + this.line = line; this.column = column; + this.filename = filename.intern(); + } + /** Create a ParsePosition pointing to the first character of a + * token **/ + public ParsePosition(Token t) { + this.line = t.getLine(); + this.column = t.getColumn()-1; + this.filename = ((TokenWithInfo)t).getFilename().intern(); + } + /** Assuming that the string s directly follows this + * ParsePosition, return a ParsePosition pointing to the character + * after s. **/ + public ParsePosition addString(String s) { + /* XXX: could scan string for newlines and increment line + number accordingly, although probably not necessary since + no tokens have newlines in them */ + ParsePosition p=null; + try { + p=(ParsePosition)this.clone(); + } catch(CloneNotSupportedException e) { + Debug.assertTrue(false); + } + p.column += s.length(); + return p; + } + public int compareTo(ParsePosition pp) { + if(line!=pp.line) + return line-pp.line; + else + return column-pp.column; + } + public boolean equals(Object o) { + if (o instanceof ParsePosition) { + ParsePosition p = (ParsePosition) o; + return line == p.line && column == p.column && + filename == p.filename; + } else { + return false; + } + } + public int hashCode() { + return filename.hashCode() + line + column; + } + public static void checkFiles(ParsePosition a, ParsePosition b) { + Debug.assertTrue(a.filename == b.filename + || a.filename == emptyFilename + || b.filename == emptyFilename); + } + public static ParsePosition max(ParsePosition a, + ParsePosition b) { + checkFiles(a,b); + if(a.compareTo(b)<0) return b; + else return a; + } + public static ParsePosition min(ParsePosition a, + ParsePosition b) { + checkFiles(a,b); + if(a.compareTo(b)<0) return a; + else return b; + } + + private static final String separator=":"; + /** Create a ParsePosition from a string of the form AA:BB, and a + * file name **/ + public ParsePosition(String s, String filename) + throws ParseException { + String substrs[]=s.split(separator,2); + if(substrs.length!=2) throw new ParseException("Expected "+separator); + try { + line = new Integer(substrs[0]).intValue(); + column = new Integer(substrs[1]).intValue(); + } catch(NumberFormatException e) { + throw new ParseException("Expected an integer"); + } + this.filename = filename.intern(); + } + /** Return a string of the form AA:BB **/ + public String toString() { + return line+separator+column; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParseRange.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParseRange.java new file mode 100644 index 0000000000..dc19ab3ac7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/ParseRange.java @@ -0,0 +1,83 @@ +package com.avlsi.csp.grammar; + +import com.avlsi.util.debug.Debug; +import com.avlsi.csp.coverage.ParseException; +import antlr.Token; + +/** + * Class representing a start and end position in a file, used for + * reporting parse errors and such. + * + * @author Frederik Eaton + * @version $Revision$ $Date$ + **/ +public class ParseRange { + public final ParsePosition start; + public final ParsePosition end; + public final static ParseRange EMPTY = new ParseRange(); + + /** Generate an empty parse range when one can't be found **/ + private ParseRange() { + start = new ParsePosition(); + end = new ParsePosition(); + } + /** Create a new ParseRange, specifying start and end positions **/ + public ParseRange(ParsePosition start, + ParsePosition end) { + this.start = start; this.end = end; + Debug.assertTrue(start.compareTo(end)<=0, + "ParseRange instantiated with invalid range"); + // XXX: eventually it might be better to allow statements + // across files (e.g. if there is a preprocessor) + Debug.assertTrue(start.filename==end.filename); + } + /** Create a new ParseRange with starting and ending line and + * column numbers and a file name **/ + public ParseRange(int sl, int sc, int el, int ec, String filename) { + this.start = new ParsePosition(sl,sc,filename); + this.end = new ParsePosition(el,ec,filename); + } + /** Create a new ParseRange which is the convex closure of two + * ParseRange's **/ + public ParseRange(ParseRange a, ParseRange b) { + this.start = ParsePosition.min(a.start,b.start); + this.end = ParsePosition.max(a.end,b.end); + } + /** Create a new ParseRange representing the span of characters in + * a token **/ + public ParseRange(Token t) { + this.start = new ParsePosition(t); + this.end = (new ParsePosition(t)).addString(t.getText()); + } + /** Separator character for printing and parsing **/ + private static final String separator="-"; + /** Create a new ParseRange from an expression of the form + * AA:BB-CC:DD and a file name **/ + public ParseRange(String s, String filename) throws ParseException { + // parse a range expression of the form AA:BB-CC:DD + String substrs[]=s.split(separator,2); + if(substrs.length!=2) throw new ParseException("Expected "+separator); + start = new ParsePosition(substrs[0], filename); + end = new ParsePosition(substrs[1], filename); + } + /** Return a string representing the range in form AA:BB-CC:DD**/ + public String toString() { + return start.toString()+separator+end.toString(); + } + /** Same as toString, but prepend filename+":". Use this for most + * error messages. **/ + public String fullString() { + return start.filename+":"+this; + } + public boolean equals(Object o) { + if (o instanceof ParseRange) { + ParseRange p = (ParseRange) o; + return start.equals(p.start) && end.equals(p.end); + } else { + return false; + } + } + public int hashCode() { + return start.hashCode() + end.hashCode(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/custom.mk new file mode 100644 index 0000000000..b3bf6234bd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/custom.mk @@ -0,0 +1,7 @@ + +MAKE_ANTLR_RULES_G_FILE_NAME := Csp.g +MAKE_ANTLR_RULES_LEXER_NAME := CspLexer +MAKE_ANTLR_RULES_PARSER_NAME := CspParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := CspParser + +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/assign.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/assign.csp new file mode 100644 index 0000000000..fc6ef23574 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/assign.csp @@ -0,0 +1 @@ +x := y diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select.csp new file mode 100644 index 0000000000..62ee4084c6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select.csp @@ -0,0 +1,3 @@ +[ false -> skip +[] true -> skip +] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select_else.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select_else.csp new file mode 100644 index 0000000000..14e28a4ff8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/det_select_else.csp @@ -0,0 +1,4 @@ +[ false -> skip +[] true -> skip +[] else -> skip +] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_bar_stmt.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_bar_stmt.csp new file mode 100644 index 0000000000..a62f4a00de --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_bar_stmt.csp @@ -0,0 +1 @@ +<|| i : 15 : ( skip ) > diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_comma_stmt.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_comma_stmt.csp new file mode 100644 index 0000000000..2d2d3820b3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_comma_stmt.csp @@ -0,0 +1 @@ +<, i : 15 : ( skip ) > diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_seq_stmt.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_seq_stmt.csp new file mode 100644 index 0000000000..42199fbc36 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_seq_stmt.csp @@ -0,0 +1 @@ +<; i : 15 : ( skip ) > diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_stmt.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_stmt.csp new file mode 100644 index 0000000000..20346d0615 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/loop_stmt.csp @@ -0,0 +1 @@ +< i : 15 : ( skip ) > diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select.csp new file mode 100644 index 0000000000..0f947876a4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select.csp @@ -0,0 +1,3 @@ +[ true -> skip +: true -> skip +] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select_else.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select_else.csp new file mode 100644 index 0000000000..0354fd2468 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/nd_select_else.csp @@ -0,0 +1,5 @@ +[ false -> skip +: true -> skip +: true -> skip +: else -> skip +] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_bars.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_bars.csp new file mode 100644 index 0000000000..47e40bf091 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_bars.csp @@ -0,0 +1 @@ +skip || skip diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_comma.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_comma.csp new file mode 100644 index 0000000000..0245331155 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/par_comma.csp @@ -0,0 +1 @@ +skip , skip diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/paren_proc.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/paren_proc.csp new file mode 100644 index 0000000000..51854ff7ae --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/paren_proc.csp @@ -0,0 +1 @@ +( skip ) diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/peek.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/peek.csp new file mode 100644 index 0000000000..270f88fa25 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/peek.csp @@ -0,0 +1 @@ +#X ? x diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv.csp new file mode 100644 index 0000000000..08f8265c78 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv.csp @@ -0,0 +1 @@ +X ? diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv_var.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv_var.csp new file mode 100644 index 0000000000..3851f8d984 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/recv_var.csp @@ -0,0 +1 @@ +X ? x diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat.csp new file mode 100644 index 0000000000..e0949e16f0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat.csp @@ -0,0 +1 @@ +*[ false -> skip ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det.csp new file mode 100644 index 0000000000..b33dc321ec --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det.csp @@ -0,0 +1 @@ +*[ true -> skip [] false -> skip ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det_else.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det_else.csp new file mode 100644 index 0000000000..dd627b0f9a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_det_else.csp @@ -0,0 +1 @@ +*[ true -> skip [] false -> skip [] else -> skip ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd.csp new file mode 100644 index 0000000000..a5519ac693 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd.csp @@ -0,0 +1 @@ +*[ true -> skip : true -> skip ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd_else.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd_else.csp new file mode 100644 index 0000000000..31e9c8a762 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_nd_else.csp @@ -0,0 +1 @@ +*[ true -> skip : true -> skip : else -> skip ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_true.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_true.csp new file mode 100644 index 0000000000..e41ff6871a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/repeat_true.csp @@ -0,0 +1 @@ +*[ skip ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_add.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_add.csp new file mode 100644 index 0000000000..228b70dd9b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_add.csp @@ -0,0 +1 @@ +[ 0 + 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_and.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_and.csp new file mode 100644 index 0000000000..732ff559d3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_and.csp @@ -0,0 +1 @@ +[ true & false ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array.csp new file mode 100644 index 0000000000..fe34a176af --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array.csp @@ -0,0 +1 @@ +[ a[b] ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array_2d.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array_2d.csp new file mode 100644 index 0000000000..3143577a3b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_array_2d.csp @@ -0,0 +1 @@ +[ a[b][c] ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_div.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_div.csp new file mode 100644 index 0000000000..6a2697a325 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_div.csp @@ -0,0 +1 @@ +[ 1 / 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_eq.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_eq.csp new file mode 100644 index 0000000000..e25155edc7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_eq.csp @@ -0,0 +1 @@ +[ true = false ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_geq.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_geq.csp new file mode 100644 index 0000000000..f20de7b692 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_geq.csp @@ -0,0 +1 @@ +[ 0 >= 1] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_gt.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_gt.csp new file mode 100644 index 0000000000..1d57409285 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_gt.csp @@ -0,0 +1 @@ +[ 1 > 0 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_hex.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_hex.csp new file mode 100644 index 0000000000..9dcb87dad4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_hex.csp @@ -0,0 +1 @@ +[ 0x1F ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_leq.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_leq.csp new file mode 100644 index 0000000000..5b552410e0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_leq.csp @@ -0,0 +1 @@ +[ 0 <= 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_add.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_add.csp new file mode 100644 index 0000000000..bd6e5f0328 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_add.csp @@ -0,0 +1 @@ +[ <+ i : 16 : ( 1 ) > ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_and.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_and.csp new file mode 100644 index 0000000000..50a127129f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_and.csp @@ -0,0 +1 @@ +[ <& i : 16 : ( true ) > ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_mul.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_mul.csp new file mode 100644 index 0000000000..c102561fae --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_mul.csp @@ -0,0 +1 @@ +[ <* i : 16 : ( 1 ) > ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_or.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_or.csp new file mode 100644 index 0000000000..c8841a7b88 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_loop_or.csp @@ -0,0 +1 @@ +[ <| i : 16 : ( true ) > ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_lt.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_lt.csp new file mode 100644 index 0000000000..1642fb90d0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_lt.csp @@ -0,0 +1 @@ +[ 0 < 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mod.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mod.csp new file mode 100644 index 0000000000..b8640b89d1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mod.csp @@ -0,0 +1 @@ +[ 1 % 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mul.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mul.csp new file mode 100644 index 0000000000..70b0875318 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_mul.csp @@ -0,0 +1 @@ +[ 1 * 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neg.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neg.csp new file mode 100644 index 0000000000..66c119b3dc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neg.csp @@ -0,0 +1 @@ +[ - 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neq.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neq.csp new file mode 100644 index 0000000000..4329efedf6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_neq.csp @@ -0,0 +1 @@ +[ true != false ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_not.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_not.csp new file mode 100644 index 0000000000..202b799624 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_not.csp @@ -0,0 +1 @@ +[ ~ 0 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_octal.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_octal.csp new file mode 100644 index 0000000000..dc961923d6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_octal.csp @@ -0,0 +1 @@ +[ 8_777 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_or.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_or.csp new file mode 100644 index 0000000000..db7c677d41 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_or.csp @@ -0,0 +1 @@ +[ true | false ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_paren.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_paren.csp new file mode 100644 index 0000000000..6b9d6f2fe9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_paren.csp @@ -0,0 +1 @@ +[ ( 1 ) ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_peek.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_peek.csp new file mode 100644 index 0000000000..edd35bb17c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_peek.csp @@ -0,0 +1 @@ +[ #X? ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_probe.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_probe.csp new file mode 100644 index 0000000000..b66a8a1925 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_probe.csp @@ -0,0 +1 @@ +[ #X ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_recv.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_recv.csp new file mode 100644 index 0000000000..9e45829dae --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_recv.csp @@ -0,0 +1 @@ +[ X ? ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shl.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shl.csp new file mode 100644 index 0000000000..7be1b7a237 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shl.csp @@ -0,0 +1 @@ +[ 0 << 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shr.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shr.csp new file mode 100644 index 0000000000..575abf49a2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_shr.csp @@ -0,0 +1 @@ +[ 0 >> 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_sub.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_sub.csp new file mode 100644 index 0000000000..f1f8b29451 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/sel_expr_sub.csp @@ -0,0 +1 @@ +[ 0 - 1 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_id.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_id.csp new file mode 100644 index 0000000000..1c23d5a563 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_id.csp @@ -0,0 +1 @@ +[ x ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true.csp new file mode 100644 index 0000000000..5dc225e9db --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true.csp @@ -0,0 +1 @@ +[ true ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true_skip.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true_skip.csp new file mode 100644 index 0000000000..a62c29ba95 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/select_wait_true_skip.csp @@ -0,0 +1 @@ +[ true -> skip ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send.csp new file mode 100644 index 0000000000..296c502227 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send.csp @@ -0,0 +1 @@ +X ! diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_expr.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_expr.csp new file mode 100644 index 0000000000..5a920f761b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_expr.csp @@ -0,0 +1 @@ +X ! ( x ) diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_var.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_var.csp new file mode 100644 index 0000000000..f699a08866 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/send_var.csp @@ -0,0 +1 @@ +X ! x diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/seq.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/seq.csp new file mode 100644 index 0000000000..87329f0647 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/seq.csp @@ -0,0 +1 @@ +skip ; skip diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/skip.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/skip.csp new file mode 100644 index 0000000000..e32e76dd5f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_0/skip.csp @@ -0,0 +1 @@ +skip diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/alt.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/alt.csp new file mode 100644 index 0000000000..7bac73b50f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/alt.csp @@ -0,0 +1,7 @@ +is_infinite := true; +repeats := 20; + +x := 1; +[ is_infinite -> *[ x := 1 - x ; X ! x] +[] else -> i := 0; *[ i < repeats -> x := 1 - x ; X ! x ] +] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_bucket.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_bucket.csp new file mode 100644 index 0000000000..386496c132 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_bucket.csp @@ -0,0 +1 @@ +*[ X? ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_gen.csp b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_gen.csp new file mode 100644 index 0000000000..33162c0ab5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/grammar/test/level_1/bit_gen.csp @@ -0,0 +1 @@ +*[ X!0 ] diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/csp2rtl.properties b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/csp2rtl.properties new file mode 100644 index 0000000000..0594fbecf1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/csp2rtl.properties @@ -0,0 +1,14 @@ +csp2rtl.function.not.synthesizable=\ +built-in function {0} is not synthesizable + +csp2rtl.construct.not.synthesizable=\ +{0} is not synthesizable + +csp2rtl.construct.not.supported=\ +{0} not yet supported + +csp2rtl.incomplete.selection=\ +selection could block without "else"; interpreting the last guard as "else" + +csp2rtl.internal.error=\ +internal error; please file a bug diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/preprocessor.properties b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/preprocessor.properties new file mode 100644 index 0000000000..a80a6b381e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/preprocessor.properties @@ -0,0 +1,2 @@ +preprocessor.assign.to.input=\ +assigning to input argument {0} in function {1} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/resources.package.inc b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/resources.package.inc new file mode 100644 index 0000000000..9209bfffb4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/resources.package.inc @@ -0,0 +1,4 @@ +1 0 +resource typechecker.properties com/avlsi/csp/resources/typechecker.properties +resource csp2rtl.properties com/avlsi/csp/resources/csp2rtl.properties +resource preprocessor.properties com/avlsi/csp/resources/preprocessor.properties diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/typechecker.properties b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/typechecker.properties new file mode 100644 index 0000000000..b84fbb4a8f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/resources/typechecker.properties @@ -0,0 +1,113 @@ +type.checker.incompatible.assignment=\ +cannot assign a {1} to a {0} + +type.checker.incompatible.parameter.passing=\ +cannot pass a {1} as a {0} in call to {2} + +type.checker.array.width.mismatch=\ +passing an {1} array as an {0} array with differing integer widths not supported + +type.checker.output.bitrange.unsupported=\ +passing bit range expression for non-input parameter {0} not supported + +type.checker.invalid.array=\ +array required, found {0} + +type.checker.invalid.string.concat=\ +string, int or bool required for string concatenation, found {0} + +type.checker.invalid.add.operands=\ +cannot add a {0} to a {1} + +type.checker.unknown.function=\ +function {0} not defined + +type.checker.invalid.function=\ +invalid function expression + +type.checker.too.many.arguments=\ +too many arguments calling {0} + +type.checker.too.few.arguments=\ +too few arguments calling {0} + +type.checker.invalid.print.tag=\ +int expected for tag argument to print, found {0} + +type.checker.invalid.print.message=\ +int, bool, string expected for message argument to print, found {0} + +type.checker.invalid.string.argument1=\ +int, bool expected for first argument to string, found {0} + +type.checker.invalid.string.argument2=\ +int expected for second argument to string, found {0} + +type.checker.invalid.assert.argument1=\ +bool expected for first argument to assert, found {0} + +type.checker.invalid.assert.argument2=\ +string expected for second argument to assert, found {0} + +type.checker.invalid.unpack.argument=\ +int, bool expected for second argument to unpack, found {0} + +type.checker.nonstring.plus=\ +string expressions cannot be combined with {0} + +type.checker.invalid.field=\ +no field {0} in user defined channel {1} + +type.checker.not.a.defchan=\ +not a user defined channel + +type.checker.undefined.structure=\ +structure {0} not defined + +type.checker.invalid.member=\ +no member {0} in structure {1} + +type.checker.not.a.structure=\ +not a structure + +type.checker.not.a.packed.structure=\ +structure {0} is not packed + +type.checker.not.a.packed.array=\ +array is not packed + +type.checker.incompatible.structure.init=\ +cannot initialize field {2} of type {0} with a {1} + +type.checker.invalid.bitwise.operand=\ +operands of a bitwise operator must both be bools or ints, found {0} and {1} + +type.checker.invalid.comparison=\ +operands of a comparison must both be bools or ints, found {0} and {1} + +type.checker.int.expected=\ +int expected, found {0} + +type.checker.int.bool.packed.expected=\ +int, bool, packed structure or packed array expected, found {0} + +type.checker.packed.expected=\ +packed structure or packed array expected, found {0} + +type.checker.channel.wrong.direction=\ +{1} channel expected, found {0} channel + +type.checker.channel.expected=\ +channel expected, found {0} + +type.checker.undeclared.set.unused=\ +undeclared variable {0} set but not used + +type.checker.undeclared.uninit=\ +undeclared variable {0} used but not set + +type.checker.undeclared.var=\ +found undeclared variable {0} + +type.checker.invalid.guard=\ +guard must evaluate to bool, found {0} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ArithmeticOperator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ArithmeticOperator.java new file mode 100644 index 0000000000..e1581c61ff --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ArithmeticOperator.java @@ -0,0 +1,61 @@ +package com.avlsi.csp.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.avlsi.csp.ast.*; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.util.container.Pair; + +public class ArithmeticOperator implements Comparable { + private static final Pattern OPERATOR = + Pattern.compile(".*\\.([^.]+)Expression"); + private final ExpressionInterface e; + private final IntegerType ty; + public ArithmeticOperator(final ExpressionInterface e, + final IntegerType ty) { + this.e = e; + this.ty = ty; + } + public int getWidth(final int defWidth) { + return CspUtils.getWidth(ty.getInterval(), defWidth); + } + public String getOp() { + if (e instanceof AbstractBinaryExpression) { + return ((AbstractBinaryExpression) e).getOperator(); + } else { + final Matcher m = OPERATOR.matcher(e.getClass().getName()); + if (m.matches()) { + return m.group(1).toLowerCase(); + } + } + return "unknown operator"; + + } + public ParseRange getParseRange() { + return e.getParseRange(); + } + public boolean equals(Object x) { + if (x instanceof ArithmeticOperator) + return compareTo((ArithmeticOperator) x) == 0; + else + return false; + } + public int hashCode() { + return e.hashCode() + ty.hashCode(); + } + public int compareTo(final ArithmeticOperator other) { + // compare based on start parse position + int result; + final ParsePosition astart = e.getParseRange().start; + final ParsePosition bstart = other.e.getParseRange().start; + + result = astart.filename.compareTo(bstart.filename); + if (result != 0) return result; + + result = astart.compareTo(bstart); + if (result != 0) return result; + else return getOp().compareTo(other.getOp()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CSPCellInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CSPCellInfo.java new file mode 100644 index 0000000000..39133d9586 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CSPCellInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.util; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +import com.avlsi.fast.metaparameters.MetaParamDefinition; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.cell.CellUtils; + +/** + * Contains information about the cell that the csp->java process + * needs for creation and compilation of the java. Includes all ports + * which the csp connects to, but not necessarily all ports of the + * total cell. + * + * Immutable. + **/ +public class CSPCellInfo { + /** + * The fully qualified type of the cell. + **/ + private final String type; + + /** Contains {@link com.avlsi.fast.metaparameters.MetaParamDefinition}s. **/ + private final Collection/**/ metaParamDefinitions; + + /** Contains {@link com.avlsi.fast.ports.PortDefinition}s. **/ + private final Collection portDefinitions; + + public CSPCellInfo(final String type, + final Collection/**/ + metaParamDefinitions, + final Collection + portDefinitions) { + this.type = type; + this.metaParamDefinitions = metaParamDefinitions; + this.portDefinitions = portDefinitions; + } + + public String getType() { + return type; + } + + public String getAbbreviatedType() { + return CellUtils.hashMetaParameters(getType(), 10000); + } + + public Iterator/**/ getMetaParamDefinitions() { + return Collections.unmodifiableCollection(metaParamDefinitions).iterator(); + } + + public Iterator getPortDefinitions() { + return Collections.unmodifiableCollection(portDefinitions).iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ConstantEvaluator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ConstantEvaluator.java new file mode 100644 index 0000000000..187ae279c6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ConstantEvaluator.java @@ -0,0 +1,1517 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.util; + +import java.lang.reflect.Constructor; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.csp.ast.*; +import com.avlsi.csp.csp2java.runtime.CspInteger; +import com.avlsi.csp.csp2java.runtime.CspValue; +import com.avlsi.csp.csp2java.runtime.Fold; +import com.avlsi.util.container.IterableIterator; + +/** + * A class to eliminate constant variables from a CSP program, and unrolls + * iterators. + **/ +public class ConstantEvaluator implements VisitorInterface { + private AbstractASTNodeInterface result; + private final SymbolTable table; + private boolean inLoop = false; + private boolean inInitializers = false; + + public interface Value { + Type getType(); + Object getValue(); + } + + /** + * Returns a new {@link CSPProgram} that is the same as the given program, + * except with all constant variables removed, and iterators with constant + * bounds unrolled. + * + * @param p program to process + * @return unrolled program with no constant variables + **/ + public static CSPProgram evaluate(final CSPProgram p) + throws VisitorException { + final ConstantEvaluator e = new ConstantEvaluator(); + e.visitCSPProgram(p); + return (CSPProgram) e.result; + } + + private ConstantEvaluator() { + this.table = new SymbolTable(); + } + + private static CspInteger toCspInteger(final IntegerExpression e) { + return new CspInteger(new BigInteger(e.getValue(), e.getRadix())); + } + + private static IntegerExpression fromCspInteger(final CspInteger i) { + return new IntegerExpression(i.toString(10), 10); + } + + private static IntegerExpression fromValue(final Value v) { + final CspInteger i = (CspInteger) v.getValue(); + if (v.getType() instanceof BooleanType) { + return new BooleanExpression(i.booleanValue()); + } else { + return fromCspInteger(i); + } + } + + private static String constArrayExpr(final IdentifierExpression id, + final IntegerExpression e) { + return id.getIdentifier() + "[" + e.getValue() + "]"; + } + + private static final Fold.BinaryFunction ADD = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).add((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction AND = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).and((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction DIVIDE = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).divide((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction POW = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).pow(((CspInteger) b).intValue()); + } + }; + + private static final Fold.BinaryFunction MULTIPLY = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).multiply((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction OR = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).or((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction XOR = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).xor((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction REMAINDER = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).remainder((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction SUBTRACT = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).subtract((CspInteger) b); + } + }; + + private static final Fold.BinaryFunction LEFTSHIFT = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).shiftLeft(((CspInteger) b).intValue()); + } + }; + + private static final Fold.BinaryFunction RIGHTSHIFT = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return ((CspInteger) a).shiftRight(((CspInteger) b).intValue()); + } + }; + + private static final Fold.BinaryFunction AND2 = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return CspInteger.valueOf(((CspInteger) a).booleanValue() && + ((CspInteger) b).booleanValue()); + } + }; + + private static final Fold.BinaryFunction OR2 = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return CspInteger.valueOf(((CspInteger) a).booleanValue() || + ((CspInteger) b).booleanValue()); + } + }; + + private AbstractASTNodeInterface newBinaryExpression( + final Class c, + final ExpressionInterface left, + final ExpressionInterface right) { + try { + final Constructor ctor = + c.getConstructor(new Class[] { ExpressionInterface.class, + ExpressionInterface.class }); + return (AbstractASTNodeInterface) + ctor.newInstance(new Object[] { left, right }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private boolean isRealInteger(final AbstractASTNodeInterface n) { + return n instanceof IntegerExpression && + !(n instanceof BooleanExpression); + } + + private void processBinaryExpression(final AbstractBinaryExpression e, + final Fold.BinaryFunction op) + throws VisitorException { + e.getLeft().accept(this); + final AbstractASTNodeInterface left = result; + e.getRight().accept(this); + + if (left instanceof BooleanExpression && + result instanceof BooleanExpression) { + result = + new BooleanExpression( + ((CspInteger) + op.evaluate(toCspInteger((IntegerExpression) left), + toCspInteger((IntegerExpression) result))) + .booleanValue()); + } else if (isRealInteger(left) && isRealInteger(result)) { + result = + fromCspInteger( + (CspInteger) + op.evaluate( + toCspInteger((IntegerExpression) left), + toCspInteger((IntegerExpression) result))); + } else if (e.getLeft() == left && e.getRight() == result) { + result = e; + } else { + result = newBinaryExpression(e.getClass(), + (ExpressionInterface) left, + (ExpressionInterface) result); + } + result.epr(e); + } + + /* Arithmetic binary operators -------------------------------------- */ + public void visitAddExpression(AddExpression e) throws VisitorException + { + processBinaryExpression(e, ADD); + } + public void visitAndExpression(AndExpression e) throws VisitorException + { + processBinaryExpression(e, AND); + } + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + processBinaryExpression(e, AND2); + } + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + processBinaryExpression(e, OR2); + } + public void visitDivideExpression(DivideExpression e) + throws VisitorException + { + processBinaryExpression(e, DIVIDE); + } + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException + { + processBinaryExpression(e, POW); + } + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException + { + processBinaryExpression(e, MULTIPLY); + } + public void visitOrExpression(OrExpression e) throws VisitorException + { + processBinaryExpression(e, OR); + } + public void visitXorExpression(XorExpression e) throws VisitorException + { + processBinaryExpression(e, XOR); + } + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException + { + processBinaryExpression(e, REMAINDER); + } + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException + { + processBinaryExpression(e, SUBTRACT); + } + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException + { + processBinaryExpression(e, LEFTSHIFT); + } + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException + { + processBinaryExpression(e, RIGHTSHIFT); + } + + /* Arithmetic unary operators --------------------------------------- */ + private interface UnaryFunction { + CspInteger evaluate(CspInteger a); + } + private static final UnaryFunction NEGATE = + new UnaryFunction() { + public CspInteger evaluate(final CspInteger a) { + return a.negate(); + } + }; + private static final UnaryFunction NOT = + new UnaryFunction() { + public CspInteger evaluate(final CspInteger a) { + return a.not(); + } + }; + + private AbstractASTNodeInterface newUnaryExpression( + final Class c, + final ExpressionInterface operand) { + try { + final Constructor ctor = + c.getConstructor(new Class[] { ExpressionInterface.class }); + return (AbstractASTNodeInterface) + ctor.newInstance(new Object[] { operand }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void processUnaryExpression(final AbstractUnaryExpression e, + final UnaryFunction op) + throws VisitorException { + e.getExpression().accept(this); + + if (result instanceof BooleanExpression) { + result = + new BooleanExpression( + ((CspInteger) + op.evaluate(toCspInteger((IntegerExpression) result))) + .booleanValue()); + } else if (isRealInteger(result)) { + result = + fromCspInteger( + op.evaluate( + toCspInteger((IntegerExpression) result))); + } else if (e.getExpression() == result) { + result = e; + } else { + result = newUnaryExpression(e.getClass(), + (ExpressionInterface) result); + } + result.epr(e); + } + public void visitNegateExpression(NegateExpression e) + throws VisitorException + { + processUnaryExpression(e, NEGATE); + } + public void visitNotExpression(NotExpression e) throws VisitorException + { + processUnaryExpression(e, NOT); + } + + /* Relational operators --------------------------------------------- */ + private static int intCompare(final CspValue a, final CspValue b) { + return ((CspInteger) a).compareTo((CspInteger) b); + } + + private static final Fold.BinaryFunction EQ = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return intCompare(a, b) == 0 ? CspInteger.ZERO.not() + : CspInteger.ZERO; + } + }; + + private static final Fold.BinaryFunction NE = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return intCompare(a, b) != 0 ? CspInteger.ZERO.not() + : CspInteger.ZERO; + } + }; + + private static final Fold.BinaryFunction LE = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return intCompare(a, b) <= 0 ? CspInteger.ZERO.not() + : CspInteger.ZERO; + } + }; + + private static final Fold.BinaryFunction LT = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return intCompare(a, b) < 0 ? CspInteger.ZERO.not() + : CspInteger.ZERO; + } + }; + + private static final Fold.BinaryFunction GT = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return intCompare(a, b) > 0 ? CspInteger.ZERO.not() + : CspInteger.ZERO; + } + }; + + private static final Fold.BinaryFunction GE = + new Fold.BinaryFunction() { + public CspValue evaluate(final CspValue a, final CspValue b) { + return intCompare(a, b) >= 0 ? CspInteger.ZERO.not() + : CspInteger.ZERO; + } + }; + + private void processBinaryComparison(final AbstractBinaryExpression e, + final Fold.BinaryFunction op) + throws VisitorException { + processBinaryExpression(e, op); + if (isRealInteger(result)) { + result = + new BooleanExpression(toCspInteger((IntegerExpression) result) + .booleanValue()); + } + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException + { + processBinaryComparison(e, EQ); + } + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException + { + processBinaryComparison(e, NE); + } + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException + { + processBinaryComparison(e, GE); + } + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException + { + processBinaryComparison(e, GT); + } + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException + { + processBinaryComparison(e, LE); + } + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException + { + processBinaryComparison(e, LT); + } + + /* Primary expressions ---------------------------------------------- */ + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException + { + e.getArrayExpression().accept(this); + final ExpressionInterface arrayExpr = (ExpressionInterface) result; + e.getIndexExpression().accept(this); + + // might be an access to a const array + if (arrayExpr instanceof IdentifierExpression && + result instanceof IntegerExpression) { + final IdentifierExpression id = (IdentifierExpression) arrayExpr; + final Value v = + table.lookup(constArrayExpr((IdentifierExpression) arrayExpr, + (IntegerExpression) result)); + if (v != null && v.getValue() != null) { + result = fromValue(v); + result.epr(e); + return; + } + } + + if (e.getArrayExpression() == arrayExpr && + e.getIndexExpression() == result) { + result = e; + } else { + result = new ArrayAccessExpression(arrayExpr, + (ExpressionInterface) result); + result.epr(e); + } + } + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException + { + e.getStructureExpression().accept(this); + if (e.getStructureExpression() == result) { + result = e; + } else { + result = new StructureAccessExpression((ExpressionInterface) result, + e.getFieldName()); + result.epr(e); + } + } + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException + { + e.getStructureExpression().accept(this); + if (e.getStructureExpression() == result) { + result = e; + } else { + result = new MemberAccessExpression((ExpressionInterface) result, + e.getMemberName()); + result.epr(e); + } + } + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException + { + e.getBitsExpression().accept(this); + final ExpressionInterface bitsExpr = (ExpressionInterface) result; + if (e.getMinExpression() == null) result = null; + else e.getMinExpression().accept(this); + final ExpressionInterface minExpr = (ExpressionInterface) result; + e.getMaxExpression().accept(this); + + if (e.getBitsExpression() == bitsExpr && + e.getMinExpression() == minExpr && + e.getMaxExpression() == result) { + result = e; + } else { + final ExpressionInterface maxExpr = (ExpressionInterface) result; + result = new BitRangeExpression(bitsExpr, minExpr, maxExpr); + if (bitsExpr instanceof IntegerExpression && + minExpr instanceof IntegerExpression && + maxExpr instanceof IntegerExpression) { + ((BitRangeExpression) result).getValueExpression().accept(this); + assert result instanceof IntegerExpression; + } + result.epr(e); + } + } + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + e.getFunctionExpression().accept(this); + final ExpressionInterface functionExpr = (ExpressionInterface) result; + + boolean same = e.getFunctionExpression() == functionExpr; + + final FunctionCallExpression ne = + new FunctionCallExpression(functionExpr); + int count = 0; + for (Iterator i = e.getActuals(); i.hasNext(); count++) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + ne.addActual((ExpressionInterface) result); + same &= arg == result; + } + + result = same ? e : ne; + + // XXX: Hardcode support for log2, log4 and choose. This should call + // RefinementResolver to determine if a function is built-in or not, + // and then use a more general mechanism to evaluate the result. + if (functionExpr instanceof IdentifierExpression && count >= 1 && + ne.getActuals().next() instanceof IntegerExpression) { + final String id = + ((IdentifierExpression) functionExpr).getIdentifier(); + final Iterator args = ne.getActuals(); + final CspInteger val = + toCspInteger((IntegerExpression) args.next()); + if ("log2".equals(id) && count == 1) { + result = fromCspInteger(val.log2()); + } else if ("log4".equals(id) && count == 1) { + result = fromCspInteger(val.log4()); + } else if ("choose".equals(id) && count == 3) { + final ExpressionInterface trueExpr = + (ExpressionInterface) args.next(); + final ExpressionInterface falseExpr = + (ExpressionInterface) args.next(); + result = val.booleanValue() ? trueExpr : falseExpr; + } + } + + result.epr(e); + } + + private void processIdentifierExpression(IdentifierExpression e) { + result = inLoop ? new IdentifierExpression(e.getIdentifier()).epr(e) + : e; + } + + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException + { + final Value v = table.lookup(e.getIdentifier()); + if (v == null || v.getValue() == null) { + processIdentifierExpression(e); + } else { + result = fromValue(v); + result.epr(e); + } + } + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException + { + result = e; + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + result = e; + } + + private interface BinaryExpressionFactory { + AbstractBinaryExpression makeExpression(ExpressionInterface left, + ExpressionInterface right); + } + private static final BinaryExpressionFactory AND_MAKER = + new BinaryExpressionFactory() { + public AbstractBinaryExpression makeExpression( + ExpressionInterface left, + ExpressionInterface right) { + return new AndExpression(left, right); + } + }; + private static final BinaryExpressionFactory OR_MAKER = + new BinaryExpressionFactory() { + public AbstractBinaryExpression makeExpression( + ExpressionInterface left, + ExpressionInterface right) { + return new OrExpression(left, right); + } + }; + private static final BinaryExpressionFactory XOR_MAKER = + new BinaryExpressionFactory() { + public AbstractBinaryExpression makeExpression( + ExpressionInterface left, + ExpressionInterface right) { + return new XorExpression(left, right); + } + }; + private static final BinaryExpressionFactory ADD_MAKER = + new BinaryExpressionFactory() { + public AbstractBinaryExpression makeExpression( + ExpressionInterface left, + ExpressionInterface right) { + return new AddExpression(left, right); + } + }; + private static final BinaryExpressionFactory MULTIPLY_MAKER = + new BinaryExpressionFactory() { + public AbstractBinaryExpression makeExpression( + ExpressionInterface left, + ExpressionInterface right) { + return new MultiplyExpression(left, right); + } + }; + + private Range processRange(final Range range) throws VisitorException { + range.getMinExpression().accept(this); + final ExpressionInterface min = (ExpressionInterface) result; + range.getMaxExpression().accept(this); + + if (range.getMinExpression() == min && + range.getMaxExpression() == result) { + return range; + } else { + return (Range) + new Range(min, (ExpressionInterface) result).epr(range); + } + } + + private interface Looper { + void begin() throws VisitorException; + void loop() throws VisitorException; + void end() throws VisitorException; + } + + private void processAbstractLoop(final IntegerExpression min, + final IntegerExpression max, + final String indexVar, + final Looper looper) + throws VisitorException { + final CspInteger minVal = toCspInteger((IntegerExpression) min); + final CspInteger maxVal = toCspInteger((IntegerExpression) max); + final boolean oldInLoop = inLoop; + inLoop = true; + looper.begin(); + for (CspInteger i = minVal; i.compareTo(maxVal) <= 0; + i = i.add(CspInteger.ONE)) { + final CspInteger loopVar = i; + table.enterScope(); + table.bind(indexVar, + new Value() { + public Type getType() { + return new IntegerType(); + } + public Object getValue() { + return loopVar; + } + }); + looper.loop(); + table.leaveScope(); + } + looper.end(); + inLoop = oldInLoop; + } + + public void visitLoopExpression(final LoopExpression e) + throws VisitorException + { + final BinaryExpressionFactory factory; + switch (e.getSeparator()) { + case LoopExpression.AND: factory = AND_MAKER; + break; + case LoopExpression.OR: factory = OR_MAKER; + break; + case LoopExpression.XOR: factory = XOR_MAKER; + break; + case LoopExpression.TIMES: factory = MULTIPLY_MAKER; + break; + case LoopExpression.PLUS: factory = ADD_MAKER; + break; + default: + throw new AssertionError(e); + } + + // resolve constants in the loop expression + e.getExpression().accept(this); + final ExpressionInterface expr = (ExpressionInterface) result; + + final Range range = processRange(e.getRange()); + final ExpressionInterface min = range.getMinExpression(); + final ExpressionInterface max = range.getMaxExpression(); + + if (min instanceof IntegerExpression && + max instanceof IntegerExpression) { + processAbstractLoop((IntegerExpression) min, + (IntegerExpression) max, e.getIndexVar(), + new Looper() { + ExpressionInterface unit = null; + public void begin() throws VisitorException { } + public void loop() throws VisitorException { + expr.accept(ConstantEvaluator.this); + if (unit == null) { + unit = (ExpressionInterface) result; + } else { + unit = factory.makeExpression( + unit, (ExpressionInterface) result); + } + } + public void end() throws VisitorException { + unit.accept(ConstantEvaluator.this); + } + }); + } else if (e.getRange() == range && e.getExpression() == expr) { + result = e; + } else { + result = new LoopExpression(e.getIndexVar(), range, + e.getSeparator(), expr); + } + result.epr(e); + } + + /* Channel expressions ---------------------------------------------- */ + private void processChannelExpression(final AbstractChannelExpression e) + throws VisitorException { + e.getChannelExpression().accept(this); + + if (e.getChannelExpression() == result) { + result = e; + } else { + result = newUnaryExpression(e.getClass(), + (ExpressionInterface) result); + result.epr(e); + } + } + public void visitPeekExpression(PeekExpression e) throws VisitorException + { + processChannelExpression(e); + } + public void visitProbeExpression(ProbeExpression e) + throws VisitorException + { + processChannelExpression(e); + } + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException + { + processChannelExpression(e); + } + + /* Simple statements ------------------------------------------------ */ + public void visitErrorStatement(ErrorStatement s) throws VisitorException + { + result = s; + } + public void visitSkipStatement(SkipStatement s) throws VisitorException + { + result = s; + } + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException + { + s.getExpression().accept(this); + + if (s.getExpression() == result) { + result = s; + } else { + result = new ExpressionStatement((ExpressionInterface) result); + result.epr(s); + } + } + + /* Channel statements ----------------------------------------------- */ + private void processChannelStatement(final AbstractChannelStatement s) + throws VisitorException { + s.getChannelExpression().accept(this); + final ExpressionInterface chanExpr = (ExpressionInterface) result; + if (s.getRightHandSide() == null) { + result = null; + } else { + s.getRightHandSide().accept(this); + } + result = newBinaryExpression(s.getClass(), chanExpr, + (ExpressionInterface) result); + result.epr(s); + } + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException + { + processChannelStatement(s); + } + public void visitSendStatement(SendStatement s) throws VisitorException + { + processChannelStatement(s); + } + + /* Compound statements ---------------------------------------------- */ + private void processCompositeStatement(final AbstractCompositeStatement s, + final AbstractCompositeStatement x) + throws VisitorException { + for (Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface si = (StatementInterface) i.next(); + si.accept(this); + x.addStatement((StatementInterface) result); + } + result = x; + result.epr(s); + } + public void visitParallelStatement(ParallelStatement s) + throws VisitorException + { + processCompositeStatement(s, new ParallelStatement()); + } + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException + { + table.enterScope(); + processCompositeStatement(s, new SequentialStatement()); + table.leaveScope(); + } + + /* Guarded statements ----------------------------------------------- */ + private Object processGuardedCommand(final GuardedCommandInterface g) + throws VisitorException { + if (g instanceof GuardedCommand) { + final GuardedCommand gc = (GuardedCommand) g; + gc.getGuard().accept(this); + final ExpressionInterface guard = (ExpressionInterface) result; + gc.getCommand().accept(this); + final StatementInterface command = (StatementInterface) result; + processLinkageTerms(gc.getLinkageTerms()); + + if (gc.getGuard() == guard && gc.getCommand() == command && + gc.getLinkageTerms() == result) { + result = g; + } else { + result = new GuardedCommand(guard, (LinkageTerms) result, + command); + result.epr(g); + } + return result; + } else if (g instanceof LoopGuard) { + return processLoopGuard((LoopGuard) g); + } else { + throw new AssertionError(); + } + } + private void processAbstractGuardedStatement( + final AbstractGuardedStatement s, + final AbstractGuardedStatement x) throws VisitorException { + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommandInterface g = + (GuardedCommandInterface) i.next(); + final Object o = processGuardedCommand(g); + if (o instanceof Collection) { + for (Iterator j = ((Collection) o).iterator(); j.hasNext(); ) { + x.addGuardedCommand((GuardedCommandInterface) j.next()); + } + } else { + x.addGuardedCommand((GuardedCommandInterface) o); + } + } + final StatementInterface els = s.getElseStatement(); + if (els != null) { + els.accept(this); + x.addElseStatement((StatementInterface) result); + } + result = x; + result.epr(s); + } + public void + visitDeterministicRepetitionStatement + (DeterministicRepetitionStatement s) throws VisitorException + { + processAbstractGuardedStatement( + s, new DeterministicRepetitionStatement()); + } + /** + * Returns true if all guard commands are simple guarded commands, with the + * guards are constant false; false otherwise. + **/ + private boolean allGuardsFalse(final AbstractGuardedStatement s) { + for (GuardedCommandInterface g : + new IterableIterator( + s.getGuardedCommands())) { + if (g instanceof GuardedCommand) { + final GuardedCommand gc = (GuardedCommand) g; + if (gc.getGuard() instanceof IntegerExpression) { + final CspInteger expr = + toCspInteger((IntegerExpression) gc.getGuard()); + if (!expr.booleanValue()) { + continue; + } + } + } + return false; + } + return true; + } + public void + visitDeterministicSelectionStatement + (DeterministicSelectionStatement s) throws VisitorException + { + final DeterministicSelectionStatement x = + new DeterministicSelectionStatement(); + processAbstractGuardedStatement(s, x); + + // match: [ false -> .. [] false -> .. [] ... [] else -> skip ] + // replace with: skip + if (x.getElseStatement() instanceof SkipStatement && + allGuardsFalse(x)) { + result = new SkipStatement(); + result.epr(s); + } + } + public void + visitNonDeterministicRepetitionStatement + (NonDeterministicRepetitionStatement s) throws VisitorException + { + processAbstractGuardedStatement( + s, new NonDeterministicRepetitionStatement()); + } + public void + visitNonDeterministicSelectionStatement + (NonDeterministicSelectionStatement s) throws VisitorException + { + processAbstractGuardedStatement( + s, new NonDeterministicSelectionStatement()); + } + public void visitLoopGuard(LoopGuard s) throws VisitorException + { + throw new AssertionError(); + } + private List processLoopGuard(final LoopGuard s) throws VisitorException + { + final Range range = processRange(s.getRange()); + final ExpressionInterface min = range.getMinExpression(); + final ExpressionInterface max = range.getMaxExpression(); + + final List l = new ArrayList(); + if (min instanceof IntegerExpression && + max instanceof IntegerExpression) { + processAbstractLoop((IntegerExpression) min, + (IntegerExpression) max, s.getIndexVar(), + new Looper() { + ExpressionInterface unit = null; + public void begin() throws VisitorException { } + public void loop() throws VisitorException { + for (Iterator i = s.getGuards().iterator(); i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + final Object o = processGuardedCommand(gci); + if (o instanceof Collection) { + for (Iterator j = ((Collection) o).iterator(); + j.hasNext(); ) { + l.add(j.next()); + } + } else { + l.add(o); + } + } + } + public void end() throws VisitorException { } + }); + } else { + final LoopGuard ret = + new LoopGuard(s.getIndexVar(), range, s.getSeparator()); + for (Iterator i = s.getGuards().iterator(); i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + final Object o = processGuardedCommand(gci); + if (o instanceof Collection) { + for (Iterator j = ((Collection) o).iterator(); + j.hasNext(); ) { + ret.addGuard((GuardedCommandInterface) j.next()); + } + } else { + ret.addGuard((GuardedCommandInterface) o); + } + } + l.add(ret); + } + return l; + } + private interface DeclaratorProcessor { + Declarator execute(final Declarator d) throws VisitorException; + } + private void processDeclarationList(final DeclarationList dlst, + final DeclaratorProcessor doer) + throws VisitorException { + final DeclarationList ndlst = new DeclarationList(); + boolean sameDlst = true; + for (Iterator i = dlst.getDeclarations(); i.hasNext(); ) { + final Declaration decl = (Declaration) i.next(); + final DeclaratorList dclr = decl.getDeclaratorList(); + final DeclaratorList ndclr = new DeclaratorList(); + boolean sameDclr = true; // can we reuse the original declaration? + boolean oneDclr = false; // at least one declarator left? + for (Iterator j = dclr.getDeclarators(); j.hasNext(); ) { + final Declarator d = (Declarator) j.next(); + final Declarator newd = doer.execute(d); + // newd is null if the declarator should be removed + + if (newd == null) { + sameDclr = false; + } else { + ndclr.addDeclarator(newd); + oneDclr = true; + if (newd != d) { + newd.epr(d); + sameDclr = false; + } + } + } + sameDlst &= sameDclr; + if (oneDclr) { + if (sameDclr) { + ndlst.addDeclaration(decl); + } else { + ndlst.addDeclaration( + (Declaration) new Declaration(ndclr).epr(decl)); + } + } + } + result = sameDlst ? dlst : (DeclarationList) ndlst.epr(dlst); + } + private final DeclaratorProcessor PROCESS_DECLARATOR = + new DeclaratorProcessor() { + public Declarator execute(final Declarator d) + throws VisitorException { + d.getTypeFragment().accept(ConstantEvaluator.this); + final Type frag = (Type) result; + if (d.getInitializer() == null) result = null; + else d.getInitializer().accept(ConstantEvaluator.this); + if (d.getTypeFragment() == frag && + d.getInitializer() == result) { + return d; + } else { + return new Declarator(d.getIdentifier(), frag, + (ExpressionInterface) result, + d.getDirection()); + } + } + }; + private void processFunctionDeclaration(final FunctionDeclaration decl) + throws VisitorException { + processDeclarationList(decl.getFormals(), PROCESS_DECLARATOR); + final DeclarationList formals = (DeclarationList) result; + final Type retType; + if (decl.getReturnType() == null) { + retType = null; + } else { + decl.getReturnType().accept(this); + retType = (Type) result; + } + decl.getBodyStatement().accept(this); + if (formals == decl.getFormals() && retType == decl.getReturnType() && + result == decl.getBodyStatement()) { + result = decl; + } else { + result = new FunctionDeclaration(decl.getName(), formals, retType, + (StatementInterface) result); + result.epr(decl); + } + } + + private void processStructureDeclaration(final StructureDeclaration decl) + throws VisitorException { + processDeclarationList(decl.getDeclarations(), PROCESS_DECLARATOR); + final DeclarationList members = (DeclarationList) result; + if (members == decl.getDeclarations()) { + result = decl; + } else { + result = new StructureDeclaration(decl.getName(), members); + result.epr(decl); + } + } + + private static SequentialStatement resolveInitializerStatement( + final CSPProgram p) { + SequentialStatement s = p.getInitializerStatement(); + for (Iterator i = p.getRefinementParents().iterator(); + s == null && i.hasNext(); ) { + final CSPProgram parent = (CSPProgram) i.next(); + if (!p.inheritDeclarationOnly(parent)) + s = resolveInitializerStatement(parent); + } + return s; + } + + public void visitCSPProgram(CSPProgram p) throws VisitorException { + final CSPProgram ncsp = new CSPProgram(); + + final SequentialStatement initializers = resolveInitializerStatement(p); + + table.enterScope(); + if (initializers != null) { + inInitializers = true; + for (Iterator i = initializers.getStatements(); i.hasNext(); ) { + ((StatementInterface) i.next()).accept(this); + } + inInitializers = false; + } + ncsp.setInitializerStatement(p.getInitializerStatement()); + if (p.getStatement() != null) { + p.getStatement().accept(this); + ncsp.setStatement((StatementInterface) result); + } + for (Iterator i = p.getFunctionDeclarations(); i.hasNext(); ) { + final FunctionDeclaration funDecl = (FunctionDeclaration) i.next(); + processFunctionDeclaration(funDecl); + ncsp.addFunctionDeclaration((FunctionDeclaration) result); + } + for (Iterator i = p.getStructureIterator(); i.hasNext(); ) { + processStructureDeclaration((StructureDeclaration) i.next()); + ncsp.addStructureDeclaration((StructureDeclaration) result); + } + for (Iterator i = p.getRefinementParents().iterator(); i.hasNext(); ) { + final CSPProgram parent = (CSPProgram) i.next(); + ncsp.refineFrom(ConstantEvaluator.evaluate(parent)); + } + table.leaveScope(); + ncsp.epr(p); + result = ncsp; + } + + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException + { + s.getLeftHandSide().accept(this); + final ExpressionInterface lhs = (ExpressionInterface) result; + s.getRightHandSide().accept(this); + + if (inInitializers && lhs instanceof ArrayAccessExpression && + result instanceof IntegerExpression) { + final ArrayAccessExpression access = (ArrayAccessExpression) lhs; + final ExpressionInterface arrayExpr = access.getArrayExpression(); + final ExpressionInterface indexExpr = access.getIndexExpression(); + if (arrayExpr instanceof IdentifierExpression && + indexExpr instanceof IntegerExpression) { + final CspInteger var = toCspInteger((IntegerExpression) result); + final IdentifierExpression id = (IdentifierExpression) arrayExpr; + final String varName = + constArrayExpr(id, (IntegerExpression) indexExpr); + final Value v = table.lookup(id.getIdentifier()); + final boolean boolArray; + if (v != null && v.getValue() == null) { + final Type et = ((ArrayType) v.getType()).getElementType(); + boolArray = et instanceof BooleanType; + } else { + boolArray = false; + } + + final boolean firstDecl = + table.bind(varName, + new Value() { + public Type getType() { + return boolArray ? new BooleanType() + : new IntegerType(); + } + public Object getValue() { + return var; + } + }); + if (!firstDecl) { + System.err.println("Warning: element in const array " + varName + " redefined at " + s.getParseRange().fullString()); + } + } + } else if (s.getLeftHandSide() == lhs && + s.getRightHandSide() == result) { + result = s; + } else if (lhs instanceof IntegerExpression) { + throw new VisitorException("Left hand side of the assignment statement is a constant expression at " + s.getParseRange().fullString()); + } else { + result = new AssignmentStatement(lhs, (ExpressionInterface) result, + s.getKind()); + result.epr(s); + } + } + public void visitIncDecStatement(final IncDecStatement s) + throws VisitorException + { + s.getExpression().accept(this); + if (s.getExpression() == result) { + result = s; + } else { + result = new IncDecStatement((ExpressionInterface) result, + s.isIncrement()).epr(s); + } + } + public void visitLoopStatement(final LoopStatement s) + throws VisitorException + { + s.getStatement().accept(this); + final StatementInterface stmt = (StatementInterface) result; + final Range range = processRange(s.getRange()); + + final int sep = s.getSeparator(); + if (sep == LoopStatement.PARALLEL) { + final AbstractCompositeStatement acs = + sep == LoopStatement.SEQUENTIAL ? + (AbstractCompositeStatement) new SequentialStatement() : + (AbstractCompositeStatement) new ParallelStatement(); + final ExpressionInterface min = range.getMinExpression(); + final ExpressionInterface max = range.getMaxExpression(); + + if (min instanceof IntegerExpression && + max instanceof IntegerExpression) { + processAbstractLoop((IntegerExpression) min, + (IntegerExpression) max, + s.getIndexVar(), new Looper() { + public void begin() throws VisitorException { acs.epr(s); } + public void loop() throws VisitorException { + stmt.accept(ConstantEvaluator.this); + acs.addStatement((StatementInterface) result); + } + public void end() throws VisitorException { + result = acs; + } + }); + return; + } + } + + if (s.getRange() == range && s.getStatement() == stmt) { + result = s; + } else { + result = new LoopStatement(s.getIndexVar(), range, sep, stmt); + result.epr(s); + } + } + public void visitVarStatement(VarStatement s) throws VisitorException + { + StatementInterface si = s.getStatement(); + if (si != null) { + si.accept(this); + si = (StatementInterface) result; + } + processDeclarationList( + s.getDeclarationList(), + new DeclaratorProcessor() { + public Declarator execute(final Declarator d) + throws VisitorException { + d.getTypeFragment().accept(ConstantEvaluator.this); + final Type ty = (Type) result; + // Do not visit id because if it was defined as a constant, + // it would be turned into an IntegerExpression; but we + // must still take care to return a new object if we are + // inside a loop + processIdentifierExpression(d.getIdentifier()); + final IdentifierExpression id = + (IdentifierExpression) result; + if (inInitializers && ty instanceof ArrayType) { + // Store types of arrays, so that when we bind array + // elements, we correctly choose BooleanExpression or + // IntegerExpression + table.bind(id.getIdentifier(), + new Value() { + public Type getType() { + return Type.clone(ty); + } + public Object getValue() { + return null; + } + }); + } + final ExpressionInterface init = d.getInitializer(); + if (init == null) result = null; + else init.accept(ConstantEvaluator.this); + final boolean constInt = (ty instanceof IntegerType) && + ((IntegerType) ty).isConst(); + final boolean constBool = (ty instanceof BooleanType) && + ((BooleanType) ty).isConst(); + if ((constInt || constBool) && + result instanceof IntegerExpression) { + final CspInteger var = + toCspInteger((IntegerExpression) result); + final boolean firstDecl = + table.bind(id.getIdentifier(), + new Value() { + public Type getType() { + return constInt ? + new IntegerType() + : new BooleanType(); + } + public Object getValue() { + return var; + } + }); + if (!firstDecl) { + System.err.println("Warning: const int/bool " + + id.getIdentifier() + " redeclared at " + + id.getParseRange().fullString()); + } + return null; + } else if (d.getInitializer() != result || + d.getIdentifier() != id || + d.getTypeFragment() != ty) { + return new Declarator(id, ty, + (ExpressionInterface) result, + d.getDirection()); + } else { + return d; + } + } + }); + if (result == s.getDeclarationList() && si == s.getStatement()) { + result = s; + } else { + result = + new VarStatement((DeclarationList) result, s.getStatement()); + result.epr(s); + } + } + private void processType(Type t) throws VisitorException { + result = inLoop ? Type.clone(t) : t; + } + public void visitArrayType(ArrayType t) throws VisitorException + { + final Range r = processRange(t.getRange()); + t.getElementType().accept(this); + if (r == t.getRange() && result == t.getElementType()) { + result = t; + } else { + result = new ArrayType(r, (Type) result); + result.epr(t); + } + } + public void visitIntegerType(IntegerType t) throws VisitorException { + final ExpressionInterface width = t.getDeclaredWidth(); + if (width == null) result = null; + else width.accept(this); + if (result != width) { + result = new IntegerType(t.isConst(), t.isSigned(), + (ExpressionInterface) result); + result.epr(t); + processType((IntegerType) result); + } else { + processType(t); + } + } + public void visitBooleanType(BooleanType t) throws VisitorException { + processType(t); + } + public void visitStringType(StringType t) throws VisitorException { + processType(t); + } + public void visitStructureType(StructureType t) throws VisitorException { + processType(t); + } + public void visitChannelType(ChannelType t) throws VisitorException { + processType(t); + } + public void visitNodeType(NodeType t) throws VisitorException { + processType(t); + } + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + final ChannelStructureType newt = new ChannelStructureType(t.getName()); + boolean same = true; + for (Iterator i = t.getMembers().entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + ((Type) entry.getValue()).accept(this); + newt.addMember((String) entry.getKey(), (Type) result); + same &= result == entry.getValue(); + } + result = same ? t : newt; + } + public void visitIdentifierList(IdentifierList il) throws VisitorException + { + throw new AssertionError(); + } + + private void processLinkageTerms(final LinkageTerms terms) + throws VisitorException { + boolean same = true; + final LinkageTerms newTerms = new LinkageTerms(); + if (terms != null) { + for (Iterator i = terms.getTerms(); i.hasNext(); ) { + final LinkageTermInterface lti = + (LinkageTermInterface) i.next(); + lti.accept(this); + // unrolling a loop may cause a LinkageTermInterface to become + // a LinkageTerms + if (result instanceof LinkageTerms) { + processLinkageTerms((LinkageTerms) result); + for (Iterator j = ((LinkageTerms) result).getTerms(); + j.hasNext(); ) { + newTerms.addTerm((LinkageTermInterface) j.next()); + } + same = false; + } else { + newTerms.addTerm((LinkageTermInterface) result); + same &= lti == result; + } + } + } + result = same ? terms : newTerms; + } + public void visitLinkageLoopTerm(final LinkageLoopTerm term) throws + VisitorException + { + term.getTerm().accept(this); + final LinkageTermInterface lterm = (LinkageTermInterface) result; + + final Range range = processRange(term.getRange()); + final ExpressionInterface min = range.getMinExpression(); + final ExpressionInterface max = range.getMaxExpression(); + + if (min instanceof IntegerExpression && + max instanceof IntegerExpression) { + processAbstractLoop((IntegerExpression) min, + (IntegerExpression) max, + term.getIndexVar(), new Looper() { + LinkageTerms lt = new LinkageTerms(); + public void begin() throws VisitorException { lt.epr(term); } + public void loop() throws VisitorException { + lterm.accept(ConstantEvaluator.this); + lt.addTerm((LinkageTermInterface) result); + } + public void end() throws VisitorException { + result = lt; + } + }); + return; + } + if (term.getRange() == range && term.getTerm() == lterm) { + result = term; + } else { + result = new LinkageLoopTerm(term.getIndexVar(), range, lterm); + result.epr(term); + } + } + public void visitLinkageExpressionTerm(LinkageExpressionTerm term) + throws VisitorException + { + term.getExpression().accept(this); + if (term.getExpression() == result) { + result = term; + } else { + result = + new LinkageExpressionTerm((LinkageExpressionInterface) result, + term.isInverted()); + result.epr(term); + } + } + + public void visitLinkageArrayAccessExpression(LinkageArrayAccessExpression + e) throws VisitorException + { + e.getArrayExpression().accept(this); + final LinkageExpressionInterface arrayExpr = + (LinkageExpressionInterface) result; + e.getIndexExpression().accept(this); + + if (e.getArrayExpression() == arrayExpr && + e.getIndexExpression() == result) { + result = e; + } else { + result = + new LinkageArrayAccessExpression(arrayExpr, + (ExpressionInterface) result); + result.epr(e); + } + } + public void visitLinkageIdentifierExpression(LinkageIdentifierExpression + e) throws VisitorException + { + result = e; + } + public void + visitLinkageStructureAccessExpression(LinkageStructureAccessExpression + e) throws VisitorException + { + e.getStructureExpression().accept(this); + final LinkageExpressionInterface structExpr = + (LinkageExpressionInterface) result; + if (e.getStructureExpression() == structExpr) { + result = e; + } else { + result = new LinkageStructureAccessExpression(structExpr, + e.getFieldName()); + result.epr(e); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspCallback.java new file mode 100644 index 0000000000..b9cc22793d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspCallback.java @@ -0,0 +1,173 @@ +package com.avlsi.csp.util; + +import antlr.RecognitionException; +import antlr.TokenStreamSelector; +import antlr.TokenStreamException; +import antlr.collections.AST; + +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cast.impl.ArrayValue; +import com.avlsi.cast.impl.DenseSubscriptSpec; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.InstanceValue; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.Range; +import com.avlsi.cast.impl.SubscriptSpecInterface; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.impl.CastTwoParser; +import com.avlsi.cast2.impl.CastTwoTreeParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.tools.cosim.CoSimChannelNames; +import com.avlsi.util.container.Pair; + +public class CspCallback implements DirectiveCallback { + private static CspCallback singleton = null; + + private boolean isChannel(final Value v) { + if (v instanceof InstanceValue) { + final CellInterface c = ((InstanceValue) v).getCell(); + try { + return CellUtils.extractN(c.getFullyQualifiedType()) != -1; + } catch (NumberFormatException e) { } + } + return false; + } + + private AST getAST(final String value) { + final CastTwoParser castParser = + CastTwoParser.getParser(value, 0, 0, ""); + + try { + castParser.startPrsNodeExpression(); + } catch (RecognitionException e) { + return null; + } catch (TokenStreamException e) { + return null; + } + + return castParser.getAST(); + } + + private String accessArray(final ArrayValue av, + final SubscriptSpecInterface spec) { + return accessArray(av, spec, av.isWideChannel()); + } + + private String accessArray(final ArrayValue av, + final SubscriptSpecInterface spec, + final boolean ignoreLastDimension) { + try { + final Value v = av.accessArray(spec); + if (isChannel(v)) { + final CoSimChannelNames names = + spec.getCoSimChannelNames(av.getInstanceName() + .getAsString('.'), + ignoreLastDimension); + return names.getFirstElement(); + } + } catch (InvalidOperationException e) { } + return null; + } + + /** + * Return the name of the channel as a string. This is complicated by the + * fact that wide channels are processed as having an extra dimension. + * + * @param value a string that represents a channel + * @param env environment in which to interpret value + * @param partialOkay whether it is okay to select a particular narrow + * channel from a wide channel + * @return name of the channel, or null if value + * does not specify a valid channel. + **/ + private String getNames(final String value, final Environment env, + final boolean partialOkay) { + final AST ast = getAST(value); + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + + // Parse as an array expression first + Pair p; + try { + p = treeParser.arrayAccessExpr(ast, env); + } catch (RecognitionException e) { + p = null; + } + + if (p == null) { + // value is not an array expression; it is either a plain channel + // (e.g., e1of4 x) or a wide channel that is not arrayed (e.g., + // e1of4[2] x). + Value v; + try { + v = treeParser.expr(ast, env, false); + } catch (RecognitionException e) { + v = null; + } + if (isChannel(v)) { + return v.getInstanceName().getAsString('.'); + } else if (v instanceof ArrayValue) { + final ArrayValue av = (ArrayValue) v; + if (av.isWideChannel()) { + final Range[] r = new Range[] { new Range(0, 0) }; + return accessArray(av, new DenseSubscriptSpec(r)); + } + } + } else if (p.getFirst() instanceof ArrayValue) { + final ArrayValue av = (ArrayValue) p.getFirst(); + SubscriptSpecInterface spec = + (SubscriptSpecInterface) p.getSecond(); + if (spec.getNumElements() != 1) return null; + String result = accessArray(av, spec, false); + if (av.isWideChannel()) { + if (result == null) { + // if an array is a wide channel (e.g., e1of4[2] x[3]), + // then the last dimension, i.e., the channel width + // dimension, must not be specified. Since channel width + // must be greater than 0, there is always a 0th element in + // the channel width dimension. So add [0] to the end of + // subscript spec, and test if the expression is a valid + // channel. + final int[] idx = spec.indexOf(0); + assert idx.length == spec.getNumDimensions(); + final Range[] r = new Range[idx.length + 1]; + for (int i = 0; i < idx.length; ++i) { + r[i] = new Range(idx[i], idx[i]); + } + r[idx.length] = new Range(0, 0); + spec = new DenseSubscriptSpec(r); + result = accessArray(av, spec); + } else if (!partialOkay) { + result = null; + } + } + return result; + } + return null; + } + + private CspCallback() { } + + /** + * A channel for the purpose of a csp block is either a channel, or a wide + * channel (i.e., an array of channels). Suppose we have: + *
    e1of4 x; e1of4 y[0..2]; e1of4[2] z[0..2];
    + * then x, y[1], z[1] are considered + * channels, but y and z[1,1] are not. + **/ + public Object resolve(String type, String value, Environment env) { + if (type.equals(DirectiveConstants.WIDE_CHANNEL_TYPE)) { + return getNames(value, env, false); + } else if (type.equals(DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE)) { + return getNames(value, env, true); + } else { + return null; + } + } + + public static CspCallback getInstance() { + if (singleton == null) singleton = new CspCallback(); + return singleton; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspUtils.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspUtils.java new file mode 100644 index 0000000000..4b19d41613 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/CspUtils.java @@ -0,0 +1,33 @@ +package com.avlsi.csp.util; + +import java.math.BigInteger; + +import com.avlsi.csp.ast.*; + +public class CspUtils { + public static BigInteger getIntegerConstant(final ExpressionInterface e) { + if (e instanceof IntegerExpression) { + final IntegerExpression ie = (IntegerExpression) e; + return new BigInteger(ie.getValue(), ie.getRadix()); + } else { + return null; + } + } + + public static int getWidth(final Interval x, final int def) { + if (x == null || x == Interval.EXCEPTION) return def; + else { + final int lwidth = x.getLeftBound().bitLength(); + final int rwidth = x.getRightBound().bitLength(); + return Math.min(def, Math.max(lwidth, rwidth) + 1); + } + + } + + public static Type getBaseType(Type ty) { + while (ty instanceof ArrayType) { + ty = ((ArrayType) ty).getElementType(); + } + return ty; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/DeclarationProcessor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/DeclarationProcessor.java new file mode 100644 index 0000000000..9602b3f868 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/DeclarationProcessor.java @@ -0,0 +1,27 @@ +package com.avlsi.csp.util; + +import java.util.Iterator; + +import com.avlsi.csp.ast.*; + +public class DeclarationProcessor { + public void process(final DeclarationList list) throws VisitorException { + for (Iterator i = list.getDeclarations(); i.hasNext(); ) { + final Declaration d = (Declaration) i.next(); + process(d); + } + } + + public void process(final Declaration decl) throws VisitorException { + process(decl.getDeclaratorList()); + } + + public void process(final DeclaratorList list) throws VisitorException { + for (Iterator i = list.getDeclarators(); i.hasNext(); ) { + final Declarator d = (Declarator) i.next(); + process(d); + } + } + + public void process(final Declarator d) throws VisitorException { } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FilterInitializers.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FilterInitializers.java new file mode 100644 index 0000000000..5408e91ecb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FilterInitializers.java @@ -0,0 +1,43 @@ +package com.avlsi.csp.util; + +import java.util.Iterator; +import java.util.Set; + +import com.avlsi.csp.ast.*; + +public class FilterInitializers extends VisitorByCategory { + private final VariableAnalyzer.Results analyzerResult; + private final Set usedTokens; + private final SequentialStatement result; + private boolean keep; + private boolean isTop; + public FilterInitializers(final VariableAnalyzer.Results analyzerResult, + final Set usedTokens) { + this.analyzerResult = analyzerResult; + this.usedTokens = usedTokens; + this.result = new SequentialStatement(); + } + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + boolean oldTop = isTop; + isTop = false; + for (Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + if (oldTop) keep = false; + stmt.accept(getVisitor()); + if (oldTop && keep) result.addStatement(stmt); + } + isTop = oldTop; + } + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + final Type ty = analyzerResult.getType(e); + if (usedTokens.contains(ty)) keep = true; + } + public SequentialStatement filter(SequentialStatement s) + throws VisitorException { + isTop = true; + s.accept(this); + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FunctionPreprocessor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FunctionPreprocessor.java new file mode 100644 index 0000000000..6f9bbf135c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/FunctionPreprocessor.java @@ -0,0 +1,1396 @@ +package com.avlsi.csp.util; + +import java.lang.reflect.Constructor; +import java.math.BigInteger; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Set; + +import com.avlsi.csp.ast.*; +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.util.container.Pair; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.csp.util.RefinementResolver; +import com.avlsi.csp.util.VariableAnalyzer; +import com.avlsi.csp.util.VariableAnalysisException; +import com.avlsi.util.math.BigIntegerUtil; + +public class FunctionPreprocessor extends VisitorByCategory { + private class Usage { + private final Declarator decl; + private final List write; + private final List read; + public Usage(final Declarator decl) { + this.decl = decl; + this.write = new ArrayList(); + this.read = new ArrayList(); + } + public void addWrite(final AbstractASTNode node) { + write.add(node); + } + public void addRead(final AbstractASTNode node) { + read.add(node); + } + public List getWrites() { + return write; + } + public boolean isAssigned() { + return !write.isEmpty(); + } + } + + private AbstractASTNodeInterface result; + private SymbolTable table; + + private int tempVars = 0; + private LinkedList/**/ preamble; + private LinkedList/*>*/ preambleStack; + private List/**/ initializers; + private boolean simpleAssign; + private boolean inGuard = false; + private boolean formalParamList = false; + private boolean isLvalue = false; + private CSPProgram ncsp; + private CSPProgram currentProgram; + private final VariableAnalyzer analyzer; + private VariableAnalyzer.Results analysisResults; + private Map> copiesNeeded; + + private static final ResourceBundle INVALID = new NullResourceBundle(); + private static ResourceBundle resourceBundle = null; + private final Collection problems; + + /** + * A list of arithmetic operators for reporting purposes. It's also + * overloaded to mean that processing is in the context of Cast2RTL. + **/ + private final Collection arithOps; + + public static ResourceBundle getResourceBundle() { + if (resourceBundle == null) { + try { + resourceBundle = ResourceBundle.getBundle( + "com.avlsi.csp.resources.preprocessor"); + } catch (MissingResourceException e) { + System.err.println( + "Cannot load function preprocessor error messages."); + resourceBundle = INVALID; + } + } + return resourceBundle; + } + + private static class AssignToInput extends SimpleProblem { + public AssignToInput(final AbstractASTNode node, final String func, + final Declarator param) { + super("preprocessor.assign.to.input", node.getParseRange(), + new Object[] { param.getIdentifier().getIdentifier(), func }); + } + public String getMessage() { + final ResourceBundle rb = getResourceBundle(); + if (rb != INVALID) { + try { + return MessageFormat.format(rb.getString(getCode()), args); + } catch (MissingResourceException e) { } + } + + return errorCode; + } + } + + public FunctionPreprocessor( + final CSPCellInfo cellInfo, + final Collection arithOps) { + this(new VariableAnalyzer(cellInfo), new ArrayList(), + arithOps); + copiesNeeded = new HashMap>(); + } + + private FunctionPreprocessor( + final VariableAnalyzer analyzer, + final Collection problems, + final Collection arithOps) { + this.analyzer = analyzer; + this.problems = problems; + this.arithOps = arithOps; + preamble = new LinkedList/**/(); + preambleStack = new LinkedList/*>*/(); + initializers = new ArrayList(); + } + + private FunctionPreprocessor( + final RefinementResolver resolver, + final VariableAnalyzer analyzer, + final int tempVars, + final Map> copiesNeeded, + final Collection problems, + final Collection arithOps) { + this(analyzer, problems, arithOps); + this.resolver = resolver; + this.tempVars = tempVars; + this.copiesNeeded = copiesNeeded; + } + + protected void setResult(AbstractASTNodeInterface node) { + result = node; + } + + public AbstractASTNodeInterface getResult() { + return result; + } + + public Collection getProblems() { + return problems; + } + + private RefinementResolver resolver = null; + + private IdentifierExpression gensym() { + return new IdentifierExpression("temp$" + tempVars++); + } + + private void clearPreamble() { + preamble.clear(); + // care must be taken in reusing temporary variables, because of + // parallel statements + //tempVars = 0; + } + + private void pushPreamble() { + preambleStack.addFirst(preamble); + preamble = new LinkedList/**/(); + } + + private void popPreamble() { + preamble = (LinkedList) preambleStack.removeFirst(); + } + + protected VisitorInterface getVisitor() { + return this; + } + + protected void + processDeclarator(Declarator d) throws VisitorException { + if (table != null) { + table.bind(d.getIdentifier().getIdentifier(), + formalParamList ? new Usage(d) : null); + } + + final ExpressionInterface init = d.getInitializer(); + if (init == null) { + setResult(d); + } else { + init.accept(getVisitor()); + final ExpressionInterface newInit; + if (getResult() instanceof IntegerExpression) { + newInit = (ExpressionInterface) getResult(); + } else { + newInit = null; + for (Iterator i = preamble.iterator(); i.hasNext(); ) { + final StatementInterface s = (StatementInterface) i.next(); + if (!(s instanceof VarStatement)) { + i.remove(); + initializers.add(s); + } + } + initializers.add( + new AssignmentStatement(d.getIdentifier(), + (ExpressionInterface) getResult()) + .epr(d)); + } + setResult(new Declarator(d.getIdentifier(), + d.getTypeFragment(), + newInit, + d.getDirection())); + } + } + + protected void + processDeclaratorList(final DeclaratorList dclr) throws VisitorException { + final DeclaratorList ndclr = new DeclaratorList(); + boolean same = true; + for (Iterator j = dclr.getDeclarators(); j.hasNext(); ) { + final Declarator d = (Declarator) j.next(); + processDeclarator(d); + same &= d == getResult(); + ndclr.addDeclarator((Declarator) getResult()); + } + setResult(same ? dclr : ndclr); + } + + protected void + processDeclarationList(DeclarationList l) throws VisitorException { + final DeclarationList nl = new DeclarationList(); + boolean same = true; + for (Iterator i = l.getDeclarations(); i.hasNext(); ) { + final Declaration decl = (Declaration) i.next(); + processDeclaratorList(decl.getDeclaratorList()); + if (decl.getDeclaratorList() == getResult()) { + nl.addDeclaration(decl); + } else { + same = false; + nl.addDeclaration( + new Declaration((DeclaratorList) getResult())); + } + } + setResult(same ? l : nl); + } + + protected void + processFunctionDeclaration(FunctionDeclaration decl) + throws VisitorException { + final SymbolTable usages = new SymbolTable(); + table = usages; + formalParamList = true; + processDeclarationList(decl.getFormals()); + formalParamList = false; + final Type rtype = decl.getReturnType(); + if (rtype != null) rtype.accept(getVisitor()); + decl.getBodyStatement().accept(getVisitor()); + setResult(new FunctionDeclaration(decl.getName(), + decl.getFormals(), + rtype, + (StatementInterface) getResult()) + .epr(decl)); + final List copyNeeded = new ArrayList(); + (new DeclarationProcessor() { + public void process(final Declarator d) throws VisitorException { + copyNeeded.add( + usages.lookup(d.getIdentifier().getIdentifier())); + } + }).process(decl.getFormals()); + copiesNeeded.put(decl, copyNeeded); + table = null; + } + protected void + processStructureDeclaration(StructureDeclaration decl) + throws VisitorException { + //processDeclarationList(decl.getDeclarations()); + setResult(decl); + } + protected void + processRefinementParent(CSPProgram p) throws VisitorException { + final FunctionPreprocessor prep = + new FunctionPreprocessor(resolver, analyzer, tempVars, + copiesNeeded, problems, arithOps); + prep.visitCSPProgram(p); + setResult(prep.getResult()); + tempVars = prep.tempVars; + } + private class SortFunctions extends VisitorByCategory { + private final Set seen; + public SortFunctions(final Set seen) { + this.seen = seen; + } + public void processFunctionDeclaration(FunctionDeclaration decl) + throws VisitorException { + if (!seen.contains(decl)/* && !copiesNeeded.containsKey(decl)*/) { + super.processFunctionDeclaration(decl); + seen.add(decl); + } + } + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + final Pair p = (Pair) resolver.getResolvedFunctions().get(e); + + final DeclarationList list; + final String name; + final Object resolved = p == null ? null : p.getSecond(); + + if (resolved instanceof FunctionDeclaration) { + processFunctionDeclaration((FunctionDeclaration) resolved); + } + + super.visitFunctionCallExpression(e); + } + } + public void visitCSPProgram(CSPProgram p) throws VisitorException + { + if (resolver == null) { + resolver = new RefinementResolver(RefinementResolver.NAME); + resolver.resolve(p); + } + + currentProgram = p; + ncsp = new CSPProgram(); + for (Iterator i = p.getRefinementParents().iterator(); i.hasNext(); ) { + processRefinementParent((CSPProgram) i.next()); + ncsp.refineFrom((CSPProgram) getResult()); + } + + final CSPProgram resolvedProgram = resolver.getCSPProgram(); + final SequentialStatement initStmt = p.getInitializerStatement(); + + final LinkedHashSet seen = + new LinkedHashSet(); + final SortFunctions sorter = new SortFunctions(seen); + for (Iterator i = p.getFunctionDeclarations(); i.hasNext(); ) { + final FunctionDeclaration decl = (FunctionDeclaration) i.next(); + if (resolver.isUsed(decl)) { + sorter.processFunctionDeclaration(decl); + } + } + + for (FunctionDeclaration decl : seen) { + if (resolver.isUsed(decl)) { + try { + analysisResults = + analyzer.getResults(decl, initStmt, resolver); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + processFunctionDeclaration(decl); + } else { + setResult(decl); + } + ncsp.addFunctionDeclaration((FunctionDeclaration) getResult()); + } + + for (Iterator i = p.getStructureIterator(); i.hasNext(); ) { + processStructureDeclaration((StructureDeclaration) i.next()); + ncsp.addStructureDeclaration((StructureDeclaration) getResult()); + } + + try { + analysisResults = analyzer.getResults(p, resolver); + } catch (VariableAnalysisException x) { + throw new VisitorException(x.getMessage(), x); + } + + if (initStmt != null) { + if (initStmt == resolvedProgram.getInitializerStatement()) { + initStmt.accept(getVisitor()); + } else { + setResult(initStmt); + } + ncsp.setInitializerStatement((SequentialStatement) getResult()); + } + + final StatementInterface stmt = p.getStatement(); + if (stmt != null) { + if (stmt == resolvedProgram.getStatement()) { + stmt.accept(getVisitor()); + } else { + setResult(stmt); + } + ncsp.setStatement((StatementInterface) getResult()); + } + setResult(ncsp); + } + + private static AbstractASTNodeInterface + constructNode(final AbstractASTNodeInterface node) { + try { + final AbstractASTNodeInterface ast = + (AbstractASTNodeInterface) node.getClass().newInstance(); + return ast.epr(node); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static AbstractASTNodeInterface + constructNode(final AbstractASTNodeInterface node, + final ExpressionInterface[] args) { + try { + final Class c = node.getClass(); + final Class[] argType = new Class[args.length]; + for (int i = 0; i < args.length; ++i) + argType[i] = ExpressionInterface.class; + final Constructor ctor = c.getConstructor(argType); + return + ((AbstractASTNodeInterface) + ctor.newInstance((Object[]) args)).epr(node); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static AbstractASTNodeInterface + constructNode(final AbstractASTNodeInterface node, + final ExpressionInterface e) { + return constructNode(node, new ExpressionInterface[] { e }); + } + + private static AbstractASTNodeInterface + constructNode(final AbstractASTNodeInterface node, + final ExpressionInterface e1, + final ExpressionInterface e2) { + return constructNode(node, new ExpressionInterface[] { e1, e2 }); + } + + private void addArithmeticOp(final ExpressionInterface e, + final IntegerType ty) { + if (!(e instanceof AbstractBinaryExpression)) return; + + final AbstractBinaryExpression abe = (AbstractBinaryExpression) e; + final BigInteger lhs = CspUtils.getIntegerConstant(abe.getLeft()); + final BigInteger rhs = CspUtils.getIntegerConstant(abe.getRight()); + + if (e instanceof MultiplyExpression) { + if ((lhs == null || !BigIntegerUtil.isPowerOf2(lhs)) && + (rhs == null || !BigIntegerUtil.isPowerOf2(rhs))) { + arithOps.add(new ArithmeticOperator(e, ty)); + } + } else if (e instanceof DivideExpression || + e instanceof RemainderExpression) { + if (rhs == null || !BigIntegerUtil.isPowerOf2(rhs)) { + arithOps.add(new ArithmeticOperator(e, ty)); + } + } else if (e instanceof LeftShiftExpression || + e instanceof RightShiftExpression) { + if (rhs == null) arithOps.add(new ArithmeticOperator(e, ty)); + } + } + + // if the expression type is integer, assign the previous result to a + // temporary variable, and make that temporary variable the new result + private void createTempInt(final ExpressionInterface e) + throws VisitorException { + if (analysisResults.getType(e) instanceof IntegerType && + !(e instanceof IdentifierExpression)) { + final ExpressionInterface temp = gensym(); + final VarStatement stmt = + createVarStatement(temp, new TemporaryIntegerType()); + preamble.add(stmt); + preamble.add( + new AssignmentStatement(temp, + (ExpressionInterface) getResult()) + .epr(e)); + temp.epr(e); + setResult(temp); + if (arithOps != null) { + final IntegerType[] ty = new IntegerType[1]; + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + ty[0] = (IntegerType) d.getTypeFragment(); + } + }).process(stmt.getDeclarationList()); + addArithmeticOp(e, ty[0]); + } + } + } + + protected void + processAbstractBinaryExpression(final AbstractBinaryExpression e) + throws VisitorException { + e.getLeft().accept(getVisitor()); + final AbstractASTNodeInterface left = getResult(); + e.getRight().accept(getVisitor()); + if (e.getLeft() == left && e.getRight() == getResult()) { + setResult(e); + } else { + setResult(constructNode(e, (ExpressionInterface) left, + (ExpressionInterface) getResult()) + .epr(e)); + } + + if (arithOps != null) createTempInt(e); + } + + // This function makes sure the two operands of the expression are both + // identifiers. Division and remainder require this, because Cast2RTL will + // translate, for example, a % b as b == 0 ? a : a % b, and we do not want + // to evaluate "b" twice. Since the ternary operator is short-circuiting, + // we must also evaluate "a", otherwise, it would be incorrect to translate + // a / b as b == 0 ? 0 : a / b, since a might not be evaluated. + private void makeTempOperands(final AbstractBinaryExpression e) + throws VisitorException { + e.getLeft().accept(getVisitor()); + createTempInt((ExpressionInterface) getResult()); + ExpressionInterface lhs = (ExpressionInterface) getResult(); + + e.getRight().accept(getVisitor()); + createTempInt((ExpressionInterface) getResult()); + ExpressionInterface rhs = (ExpressionInterface) getResult(); + + if (lhs == e.getLeft() && rhs == e.getRight()) { + setResult(e); + } else { + setResult(constructNode(e, lhs, rhs)); + } + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + if (arithOps == null) { + super.visitDivideExpression(e); + } else { + makeTempOperands(e); + createTempInt(e); + } + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + if (arithOps == null) { + super.visitRemainderExpression(e); + } else { + makeTempOperands(e); + createTempInt(e); + } + } + + private void processConditionalExpression(AbstractBinaryExpression e, + boolean and) + throws VisitorException { + final ExpressionInterface val = gensym(); + preamble.add(createVarStatement(val, new BooleanType())); + + pushPreamble(); + e.getLeft().accept(getVisitor()); + ExpressionInterface guardExpr = (ExpressionInterface) getResult(); + if (!and) guardExpr = new NotExpression(guardExpr); + final Collection guardPreamble = preamble; + popPreamble(); + final SequentialStatement guardStmt = packagePreamble(guardPreamble); + + pushPreamble(); + e.getRight().accept(getVisitor()); + final Collection actionPreamble = preamble; + popPreamble(); + final StatementInterface actionStmt = + packagePreamble( + actionPreamble, + new AssignmentStatement(val, + (ExpressionInterface) getResult())); + actionStmt.epr(e.getRight()); + + final GuardedCommand gc; + if (guardStmt == null) { + gc = new GuardedCommand(guardExpr, null, actionStmt); + } else { + guardStmt.epr(e.getLeft()); + gc = new GuardedCommandWithStatement(guardExpr, null, actionStmt, + guardStmt); + } + gc.epr(e.getLeft()); + gc.epr(e.getRight()); + + final StatementInterface elseStmt = + new AssignmentStatement(val, new BooleanExpression(!and)); + + final AbstractGuardedStatement select = + new DeterministicSelectionStatement(); + select.addGuardedCommand(gc); + select.addElseStatement(elseStmt); + select.epr(e); + preamble.add(select); + + setResult(val); + } + + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + processConditionalExpression(e, true); + } + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + processConditionalExpression(e, false); + } + + protected void + processAbstractChannelExpression(final AbstractChannelExpression e) + throws VisitorException { + e.getChannelExpression().accept(getVisitor()); + if (inGuard) { + if (getResult() == e.getChannelExpression()) setResult(e); + else setResult(constructNode(e, (ExpressionInterface) getResult())); + } else { + final ExpressionInterface temp = gensym(); + if (e instanceof ProbeExpression) + preamble.add(createVarStatement(temp, new BooleanType())); + preamble.add(new AssignmentStatement(temp, + (AbstractChannelExpression) + constructNode(e, (ExpressionInterface) getResult())).epr(e)); + setResult(temp); + } + } + + public void visitReceiveExpression(final ReceiveExpression e) + throws VisitorException { + if (inGuard) { + throw new VisitorException("Receive expressions not supported in guard expression at " + e.getParseRange().fullString()); + } + + e.getChannelExpression().accept(getVisitor()); + final ExpressionInterface temp = gensym(); + preamble.add(createVarStatement(temp, new IntegerType())); + preamble.add(new ReceiveStatement((ExpressionInterface) getResult(), + temp).epr(e)); + setResult(temp); + } + + /** + * Package the given statement with any preambles necessary into a + * sequential statement and return it. Any preamble is cleared. If there + * is no preamble, return the argument with no modification. + **/ + private SequentialStatement packagePreamble() { + if (preamble.isEmpty()) { + return null; + } else { + final SequentialStatement seq = new SequentialStatement(); + for (Iterator i = preamble.iterator(); i.hasNext(); ) { + seq.addStatement((StatementInterface) i.next()); + } + clearPreamble(); + return seq; + } + } + + private StatementInterface packagePreamble(final StatementInterface s) + { + final SequentialStatement seq = packagePreamble(); + if (seq == null) { + return s; + } else { + seq.addStatement(s); + seq.epr(s); + return seq; + } + } + + private SequentialStatement packagePreamble(final Collection somePreamble) { + if (somePreamble.isEmpty()) { + return null; + } else { + final SequentialStatement seq = new SequentialStatement(); + for (Iterator i = somePreamble.iterator(); i.hasNext(); ) { + final StatementInterface stmt = (StatementInterface) i.next(); + if (stmt instanceof VarStatement) { + preamble.add(stmt); + } else { + seq.addStatement(stmt); + } + } + return seq; + } + } + + private StatementInterface packagePreamble(final Collection somePreamble, + final StatementInterface s) { + final SequentialStatement seq = packagePreamble(somePreamble); + if (seq == null) { + return s; + } else { + seq.addStatement(s); + seq.epr(s); + return seq; + } + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + s.getChannelExpression().accept(getVisitor()); + final ExpressionInterface chanExpr = (ExpressionInterface) getResult(); + ExpressionInterface rhs = s.getRightHandSide(); + final StatementInterface last; + if (rhs == null) { + last = (AbstractChannelStatement) constructNode(s, chanExpr, null); + } else { + final Type ty = analysisResults.getType(rhs); + if (ty instanceof StructureType || ty instanceof ArrayType) { + final ExpressionInterface temp = gensym(); + preamble.add(createVarStatement(temp, new IntegerType())); + preamble.add(new ReceiveStatement(chanExpr, temp).epr(s)); + final FunctionCallExpression funcall = + new FunctionCallExpression( + new IdentifierExpression("unpack")); + funcall.addActual(rhs); + funcall.addActual(temp); + funcall.epr(s); + funcall.accept(getVisitor()); + last = (StatementInterface) + new ExpressionStatement( + (ExpressionInterface) getResult()).epr(s); + } else { + isLvalue = true; + rhs.accept(getVisitor()); + isLvalue = false; + last = (AbstractChannelStatement) + constructNode(s, chanExpr, + (ExpressionInterface) getResult()); + } + } + setResult(packagePreamble(last)); + } + + public void visitSendStatement(SendStatement s) throws VisitorException { + s.getChannelExpression().accept(getVisitor()); + final ExpressionInterface chanExpr = (ExpressionInterface) getResult(); + ExpressionInterface rhs = s.getRightHandSide(); + if (rhs == null) { + setResult(null); + } else { + final Type ty = analysisResults.getType(rhs); + if (ty instanceof StructureType || ty instanceof ArrayType) { + final FunctionCallExpression funcall = + new FunctionCallExpression( + new IdentifierExpression("pack")); + funcall.addActual(rhs); + funcall.epr(rhs); + rhs = funcall; + } + rhs.accept(getVisitor()); + // the emitters depend on the RHS being a simple identifier, + // because it might be evaluated multiple times + if (!(getResult() instanceof IdentifierExpression)) { + final ExpressionInterface temp = gensym(); + preamble.add(createVarStatement(temp, + ty instanceof BooleanType ? new BooleanType() + : new TemporaryIntegerType())); + preamble.add( + new AssignmentStatement(temp, + (ExpressionInterface) getResult()) + .epr(rhs)); + setResult(temp); + } + } + setResult( + packagePreamble( + (AbstractChannelStatement) + constructNode(s, chanExpr, (ExpressionInterface) getResult()))); + } + + private void addInitializers(final AbstractCompositeStatement ns) { + for (Iterator i = preamble.iterator(); i.hasNext(); ) { + final StatementInterface s = (StatementInterface) i.next(); + ns.addStatement(s); + } + clearPreamble(); + for (Iterator i = initializers.iterator(); i.hasNext(); ) { + ns.addStatement((StatementInterface) i.next()); + } + initializers.clear(); + } + + protected void + processAbstractCompositeStatement(final AbstractCompositeStatement s) + throws VisitorException { + final AbstractCompositeStatement ns = + (AbstractCompositeStatement) constructNode(s); + for (Iterator i = s.getStatements(); i.hasNext(); ) { + final StatementInterface ss = (StatementInterface) i.next(); + if (!(ss instanceof VarStatement)) addInitializers(ns); + ss.accept(getVisitor()); + ns.addStatement((StatementInterface) getResult()); + } + addInitializers(ns); + setResult(ns); + } + + public void visitSequentialStatement(final SequentialStatement s) + throws VisitorException { + if (table != null) table.enterScope(); + processAbstractCompositeStatement(s); + if (table != null) table.leaveScope(); + } + + protected void + processAbstractUnaryExpression(final AbstractUnaryExpression e) + throws VisitorException { + e.getExpression().accept(getVisitor()); + if (e.getExpression() == getResult()) { + setResult(e); + } else { + setResult((AbstractUnaryExpression) + constructNode(e, (ExpressionInterface) getResult())); + } + + if (arithOps != null) createTempInt(e); + } + + /* Primary expressions */ + protected void processPrimaryExpression(ExpressionInterface e) + throws VisitorException { + setResult(e); + } + + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + final Usage u = table == null ? null + : table.lookup(e.getIdentifier()); + if (isLvalue) { + if (u != null) u.addWrite(e); + isLvalue = false; + } else { + if (u != null) u.addRead(e); + } + processPrimaryExpression(e); + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + e.getArrayExpression().accept(getVisitor()); + final ExpressionInterface arrayExpr = (ExpressionInterface) getResult(); + e.getIndexExpression().accept(getVisitor()); + if (!(getResult() instanceof IntegerExpression)) + createTempInt((ExpressionInterface) getResult()); + if (e.getArrayExpression() == arrayExpr && + e.getIndexExpression() == getResult()) { + setResult(e); + } else { + setResult(new ArrayAccessExpression(arrayExpr, (ExpressionInterface) + getResult()) + .epr(e)); + } + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + e.getBitsExpression().accept(getVisitor()); + final ExpressionInterface bitsExpr = (ExpressionInterface) getResult(); + if (e.getMinExpression() == null) setResult(null); + else { + e.getMinExpression().accept(getVisitor()); + if (!(getResult() instanceof IntegerExpression)) + createTempInt((ExpressionInterface) getResult()); + } + final ExpressionInterface minExpr = (ExpressionInterface) getResult(); + e.getMaxExpression().accept(getVisitor()); + if (!(getResult() instanceof IntegerExpression)) + createTempInt((ExpressionInterface) getResult()); + if (e.getBitsExpression() == bitsExpr && + e.getMinExpression() == minExpr && + e.getMaxExpression() == getResult()) { + setResult(e); + } else { + setResult(new BitRangeExpression(bitsExpr, minExpr, + (ExpressionInterface) getResult()) + .epr(e)); + } + } + + private boolean isAssignable(final AbstractASTNodeInterface n) { + return n instanceof IdentifierExpression || + n instanceof ArrayAccessExpression || + n instanceof StructureAccessExpression || + n instanceof MemberAccessExpression; + } + + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + // Find function call declaration using refinement resolver + // to determine types of arguments and return value + final Pair p = (Pair) resolver.getResolvedFunctions().get(e); + + final DeclarationList list; + final String name; + final List copyNeeded; + final Object resolved = p == null ? null : p.getSecond(); + + e.getFunctionExpression().accept(getVisitor()); + final FunctionCallExpression funcall = + new FunctionCallExpression((ExpressionInterface) getResult()); + funcall.epr(e); + + boolean specialNoCopy = false; + if (resolved instanceof FunctionDeclaration) { + final FunctionDeclaration decl = (FunctionDeclaration) resolved; + list = decl.getFormals(); + name = decl.getName(); + copyNeeded = copiesNeeded.get(decl); + } else if (resolved instanceof StructureDeclaration) { + final StructureDeclaration decl = (StructureDeclaration) resolved; + list = decl.getDeclarations(); + name = decl.getName(); + copyNeeded = null; + } else { + list = null; + final ExpressionInterface funExpr = funcall.getFunctionExpression(); + if (funExpr instanceof IdentifierExpression) { + name = ((IdentifierExpression) funExpr).getIdentifier(); + specialNoCopy = name.equals("print") || name.equals("pack") || + name.equals("string"); + } else { + name = null; + } + copyNeeded = null; + } + + final Iterator types; + if (list == null) { + types = null; + } else { + final Collection c = new ArrayList(); + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + c.add(d); + } + }).process(list); + types = c.iterator(); + } + + int count = 0; + for (Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + final Type currType = analysisResults.getType(arg); + final Declarator d; + final int dir; + if (types == null) { + d = null; + dir = Declarator.NONE; + } else { + if (types.hasNext()) { + d = (Declarator) types.next(); + dir = d.getDirection(); + } else throw new VisitorExceptionWithLocation( + "More arguments to function " + name + + " than expected (expecting " + count + ")", + arg); + } + + final Usage u = copyNeeded == null ? null : copyNeeded.get(count); + final boolean needCopy = + (u == null ? true : (dir == Declarator.IN && u.isAssigned())); + if (needCopy && u != null) { + for (AbstractASTNode node : u.getWrites()) { + problems.add(new AssignToInput(node, name, d)); + } + } + + final boolean larg = dir != Declarator.IN && !specialNoCopy && + isAssignable(arg); + if (larg) isLvalue = true; + arg.accept(getVisitor()); + if (larg) isLvalue = false; + + final ExpressionInterface actual; + if ((dir != Declarator.IN || !needCopy) && + isAssignable(getResult())) { + actual = (ExpressionInterface) getResult(); + } else { + actual = gensym(); // temp var for actual + // create var statement for actual for resolved + // functions + if (currType != null) { + preamble.add(createVarStatement(actual, currType)); + } + actual.epr(arg); + preamble.add( + new AssignmentStatement(actual, + (ExpressionInterface) getResult()) + .epr(arg)); + } + funcall.addActual(actual); + } + if (types != null && types.hasNext()) { + throw new VisitorExceptionWithLocation( + "Fewer actual arguments to function " + name + + " than expected (found " + count + ")", funcall); + } + + // Create return variable + final ExpressionInterface temp = gensym(); + // And process its type + if (resolved instanceof StructureDeclaration) { + setResult(funcall); + } else { + boolean noReturn = false; + if (resolved instanceof FunctionDeclaration) { + final FunctionDeclaration decl2 = + (FunctionDeclaration) p.getSecond(); + // Find return type of function + final Type type = decl2.getReturnType(); + // Then create var statement and add it to program + if (type == null) noReturn = true; + else preamble.add(createVarStatement(temp, type)); + } else if (name.equals("string")) { + preamble.add(createVarStatement(temp, new StringType())); + } else if (name.equals("print") || name.equals("assert") || + name.equals("unpack")) { + noReturn = true; + } else if (name.equals("pack")) { + preamble.add(createVarStatement(temp, + new TemporaryIntegerType())); + } + + if (noReturn) { + setResult(funcall); + } else { + preamble.add(new AssignmentStatement(temp, funcall).epr(e)); + setResult(temp); + } + } + } + + // Create var statement from id + private VarStatement createVarStatement(ExpressionInterface temp, + Type type) { + final IdentifierList idlist = new IdentifierList(); + idlist.addIdentifier((IdentifierExpression) temp); + final Type cloned = Type.clone(type); + return(new VarStatement(new Declaration(idlist, cloned))); + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(getVisitor()); + if (e.getStructureExpression() == getResult()) { + setResult(e); + } else { + setResult(new MemberAccessExpression( + (ExpressionInterface) getResult(), e.getMemberName()) + .epr(e)); + } + } + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(getVisitor()); + if (e.getStructureExpression() == getResult()) { + setResult(e); + } else { + setResult(new StructureAccessExpression( + (ExpressionInterface) getResult(), e.getFieldName()) + .epr(e)); + } + } + + /* Loop */ + public void visitLinkageLoopTerm(LinkageLoopTerm term) + throws VisitorException { + processRange(term.getRange()); + final Range r = (Range) getResult(); + + if (table != null) { + table.enterScope(); + table.bind(term.getIndexVar(), null); + } + term.getTerm().accept(getVisitor()); + if (table != null) table.leaveScope(); + + if (term.getRange() == r && term.getTerm() == getResult()) { + setResult(term); + } else { + setResult(new LinkageLoopTerm(term.getIndexVar(), r, + (LinkageTermInterface) getResult()) + .epr(term)); + + } + } + + public void visitLoopExpression(LoopExpression e) throws VisitorException { + processRange(e.getRange()); + final Range r = (Range) getResult(); + + if (table != null) { + table.enterScope(); + table.bind(e.getIndexVar(), null); + } + e.getExpression().accept(getVisitor()); + if (table != null) table.leaveScope(); + + if (e.getRange() == r && e.getExpression() == getResult()) { + setResult(e); + } else { + setResult(new LoopExpression(e.getIndexVar(), r, + e.getSeparator(), + (ExpressionInterface) getResult()) + .epr(e)); + + } + } + + public void visitLoopStatement(LoopStatement s) throws VisitorException { + processRange(s.getRange()); + final Range r = (Range) getResult(); + + pushPreamble(); + if (table != null) { + table.enterScope(); + table.bind(s.getIndexVar(), null); + } + s.getStatement().accept(getVisitor()); + if (table != null) table.leaveScope(); + popPreamble(); + + if (s.getRange() == r && s.getStatement() == getResult()) { + setResult(s); + } else { + final LoopStatement ls = (LoopStatement) + new LoopStatement(s.getIndexVar(), r, s.getSeparator(), + (StatementInterface) getResult()).epr(s); + setResult(packagePreamble(ls)); + } + } + + protected void processGuardedCommandInterface(GuardedCommandInterface gci) + throws VisitorException { + if (gci instanceof GuardedCommand) { + final GuardedCommand gc = (GuardedCommand) gci; + inGuard = true; + pushPreamble(); + gc.getGuard().accept(getVisitor()); + ExpressionInterface ng = (ExpressionInterface) getResult(); + inGuard = false; + final Collection guardPreamble = preamble; + popPreamble(); + + final SequentialStatement guardStmt; + if (guardPreamble.isEmpty()) { + guardStmt = null; + } else { + guardStmt = new SequentialStatement(); + for (Iterator i = guardPreamble.iterator(); i.hasNext(); ) { + final StatementInterface stmt = + (StatementInterface) i.next(); + if (stmt instanceof VarStatement) { + preamble.add(stmt); + } else { + guardStmt.addStatement(stmt); + } + } + } + + pushPreamble(); + gc.getCommand().accept(getVisitor()); + final StatementInterface cmd = + packagePreamble((StatementInterface) getResult()); + popPreamble(); + if ((gc.getCommand() != cmd) || (gc.getGuard() != ng)) { + if (guardStmt == null) { + setResult(new GuardedCommand(ng, + gc.getLinkageTerms(), + cmd) + .epr(gci)); + } else { + guardStmt.epr(ng); + setResult(new GuardedCommandWithStatement( + ng, gc.getLinkageTerms(), cmd, guardStmt) + .epr(gci)); + } + return; + } + } + setResult(gci); + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + // should have been unrolled by ConstantEvaluator + setResult(s); + } + + /* Assignment and variable declaration statements */ + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + isLvalue = true; + s.getLeftHandSide().accept(getVisitor()); + isLvalue = false; + final ExpressionInterface lhs = (ExpressionInterface) getResult(); + s.getRightHandSide().accept(getVisitor()); + final ExpressionInterface rhs = (ExpressionInterface) getResult(); + + if (s.getLeftHandSide() == lhs && s.getRightHandSide() == rhs) { + setResult(s); + } else { + final AssignmentStatement as = (AssignmentStatement) + new AssignmentStatement(lhs, rhs, s.getKind()).epr(s); + setResult(packagePreamble(as)); + } + } + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + new AssignmentStatement( + s.getExpression(), new IntegerExpression(1), + s.isIncrement() ? AssignmentStatement.ADD + : AssignmentStatement.SUBTRACT) + .accept(getVisitor()); + } + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + s.getExpression().accept(getVisitor()); + final StatementInterface si; + if (getResult() instanceof IdentifierExpression) { + si = (StatementInterface) new SkipStatement().epr(s); + } else { + si = (StatementInterface) new ExpressionStatement( + (ExpressionInterface) getResult()).epr(s.getExpression()); + } + setResult(packagePreamble(si).epr(s)); + } + public void visitVarStatement(VarStatement s) throws VisitorException { + processDeclarationList(s.getDeclarationList()); + final DeclarationList dlst = (DeclarationList) getResult(); + + final StatementInterface stmt = s.getStatement(); + if (stmt == null) { + setResult(null); + } else { + stmt.accept(getVisitor()); + } + setResult(new VarStatement(dlst, + (StatementInterface) getResult()).epr(s)); + } + + // XXX: Figure out what boolean same var is used for. Completely unclear + // at first glance. + protected void + processAbstractGuardedStatement(AbstractGuardedStatement s) + throws VisitorException { + final AbstractGuardedStatement ags = + (AbstractGuardedStatement) constructNode(s); + boolean same = true; + final StatementInterface els = s.getElseStatement(); + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + processGuardedCommandInterface(gci); + ags.addGuardedCommand((GuardedCommandInterface) getResult()); + same &= gci == getResult(); + } + if (els != null) { + pushPreamble(); + els.accept(getVisitor()); + ags.addElseStatement( + packagePreamble((StatementInterface) getResult())); + popPreamble(); + same &= els == getResult(); + } + if (same) setResult(s); + else setResult(ags.epr(s)); + } + + protected void + processAbstractSelectionStatement(AbstractSelectionStatement s) + throws VisitorException { + processAbstractGuardedStatement(s); + } + + protected void + processAbstractRepetitionStatement(AbstractRepetitionStatement s) + throws VisitorException { + processAbstractGuardedStatement(s); + } + + public void + visitNonDeterministicRepetitionStatement + (NonDeterministicRepetitionStatement s) throws VisitorException + { + pushPreamble(); + processAbstractRepetitionStatement(s); + if (getResult() != s) { + final NonDeterministicRepetitionStatement ndrs = + (NonDeterministicRepetitionStatement) getResult(); + ndrs.setNeutralState(s.getNeutralState()); + } + setResult(packagePreamble((StatementInterface) getResult())); + popPreamble(); + } + + public void + visitNonDeterministicSelectionStatement + (NonDeterministicSelectionStatement s) throws VisitorException { + pushPreamble(); + processAbstractSelectionStatement(s); + if (getResult() != s) { + final NonDeterministicSelectionStatement ndrs = + (NonDeterministicSelectionStatement) getResult(); + ndrs.setNeutralState(s.getNeutralState()); + } + setResult(packagePreamble((StatementInterface) getResult())); + popPreamble(); + } + + public void + visitDeterministicRepetitionStatement + (DeterministicRepetitionStatement s) throws VisitorException + { + pushPreamble(); + processAbstractRepetitionStatement(s); + setResult(packagePreamble((StatementInterface) getResult())); + popPreamble(); + } + + public void + visitDeterministicSelectionStatement + (DeterministicSelectionStatement s) throws VisitorException + { + pushPreamble(); + processAbstractSelectionStatement(s); + setResult(packagePreamble((StatementInterface) getResult())); + popPreamble(); + } + + + /* LinkageExpressionInterface */ + protected void + processLinkageExpressionInterface(LinkageExpressionInterface e) + throws VisitorException { + setResult(e); + } + public void + visitLinkageArrayAccessExpression(LinkageArrayAccessExpression e) + throws VisitorException { + processLinkageExpressionInterface(e); + } + public void visitLinkageExpressionTerm(LinkageExpressionTerm term) + throws VisitorException { + term.getExpression().accept(getVisitor()); + if (term.getExpression() == getResult()) { + setResult(term); + } else { + setResult(new LinkageExpressionTerm( + (LinkageExpressionInterface) getResult(), + term.isInverted()) + .epr(term)); + } + } + public void visitLinkageIdentifierExpression(LinkageIdentifierExpression e) + throws VisitorException { + processLinkageExpressionInterface(e); + } + public void + visitLinkageStructureAccessExpression(LinkageStructureAccessExpression e) + throws VisitorException { + processLinkageExpressionInterface(e); + } + + /* Range */ + protected void processRange(final Range r) throws VisitorException { + r.getMinExpression().accept(getVisitor()); + final ExpressionInterface minExpr = (ExpressionInterface) getResult(); + r.getMaxExpression().accept(getVisitor()); + if (r.getMinExpression() == minExpr && + r.getMaxExpression() == getResult()) { + setResult(r); + } else { + setResult(new Range(minExpr, (ExpressionInterface) getResult()) + .epr(r)); + } + } + + protected void processLinkageTerms(final LinkageTerms terms) + throws VisitorException { + for (Iterator i = terms.getTerms(); i.hasNext(); ) { + ((LinkageTermInterface) i.next()).accept(getVisitor()); + } + } + + /* Trivial statements */ + public void visitErrorStatement(ErrorStatement s) throws VisitorException { + setResult(s); + } + + public void visitSkipStatement(SkipStatement s) throws VisitorException { + setResult(s); + } + + /* Currently unused */ + public void visitIdentifierList(IdentifierList il) throws VisitorException { + setResult(il); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Interval.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Interval.java new file mode 100644 index 0000000000..6adbfce006 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Interval.java @@ -0,0 +1,670 @@ +package com.avlsi.csp.util; + +import java.lang.Math; +import java.math.BigInteger; + +/** + * Class implementing interval analysis on simple arithmetic and bitwise + * operations with CSP integer semantics. Sadly, not all operations will + * return the tightest interval. + **/ +public class Interval { + /** + * Largest int as a BigInteger. Useful for + * comparison purposes before calling intValue(). + **/ + private static final BigInteger MAX_INT = + BigInteger.valueOf(Integer.MAX_VALUE); + + /** + * Smallest int as a BigInteger. Useful for + * comparison purposes before calling intValue(). + **/ + private static final BigInteger MIN_INT = + BigInteger.valueOf(Integer.MIN_VALUE); + + /** + * Interval [0..0]. + **/ + public static final Interval ZERO = new Interval(BigInteger.ZERO); + + /** + * Interval [1..1]. + **/ + public static final Interval ONE = new Interval(BigInteger.ONE); + + /** + * Returned if a computation is out of range. For example, if the shift + * amount or the exponent is greater than 32-bits. + **/ + public static final Interval EXCEPTION = new Interval(); + + /** + * Left bound, inclusive. + **/ + private final BigInteger from; + + /** + * Right bound, inclusive. + **/ + private final BigInteger to; + + /** + * Private constructor only used to create EXCEPTION. Use + * null for the bounds to detect if EXCEPTION is + * ever used incorrectly in a computation. + **/ + private Interval() { + this.from = null; + this.to = null; + } + + private static BigInteger bitsInt(final int bits, final boolean neg) { + final BigInteger pow2 = BigInteger.ONE.shiftLeft(bits); + return neg ? pow2.negate() : pow2.subtract(BigInteger.ONE); + } + + /** + * Construct an interval [0..2^bits-1]. + * + * @param bits number of bits in the interval + **/ + public Interval(final int bits) { + this(false, bits); + } + + /** + * Construct an interval for a possibly signed integer expressed in 2's + * complement that is bits wide (including the sign bit, if + * any). If signed, the interval is [-2^(bits-1)..2^(bits-1)-1]; if + * unsigned, the interval is [0..2^bits-1]. + * + * @param signed whether this is a signed integer + * @param bits number of bits in the integer + **/ + public Interval(final boolean signed, final int bits) { + this(signed ? bitsInt(bits - 1, true) : BigInteger.ZERO, + signed ? bitsInt(bits - 1, false) : bitsInt(bits, false)); + } + + /** + * Construct an interval [from..to]. + * + * @param from left bound of the interval, inclusive + * @param to right bound of the interval, inclusive + **/ + public Interval(final BigInteger from, final BigInteger to) { + if (from.compareTo(to) < 0) { + this.from = from; + this.to = to; + } else { + this.from = to; + this.to = from; + } + } + + /** + * Construct an interval [val..val]. + * + * @param val the single integer contained in the interval + **/ + public Interval(final BigInteger val) { + this(val, val); + } + + /** + * Returns the left bound. + * + * @return left bound of the interval + **/ + public BigInteger getLeftBound() { + return from; + } + + /** + * Returns the right bound. + * + * @return right bound of the interval + **/ + public BigInteger getRightBound() { + return to; + } + + // Returns the minimum BigInteger + private BigInteger min(final BigInteger... vals) { + BigInteger result = null; + for (BigInteger val : vals) { + result = result == null ? val : result.min(val); + } + return result; + } + + // Returns the maximum BigInteger + private BigInteger max(final BigInteger... vals) { + BigInteger result = null; + for (BigInteger val : vals) { + result = result == null ? val : result.max(val); + } + return result; + } + + // Returns the union of intervals; a null interval is skipped + private Interval union(final Interval... vals) { + Interval result = null; + for (Interval val : vals) { + if (val != null) { + if (result == null) result = val; + else result = result.union(val); + } + } + return result; + } + + // Returns if any of the intervals are EXCEPTION + private boolean checkException(final Interval... vals) { + for (Interval v : vals) { + if (v == EXCEPTION) return true; + } + return false; + } + + /** + * Returns the union of this interval and interval r. + * + * @param r interval to be unioned with this interval + * @return the union interval or EXCEPTION if either interval + * is EXCEPTION + **/ + public Interval union(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + return new Interval(min(from, r.from), max(to, r.to)); + } + + public boolean equals(final Interval other) { + return from.equals(other.from) && to.equals(other.to); + } + + /** + * Returns the interval containing the sum of an integer in this interval + * addded to an integer in interval r. + * + * @param r interval containing integer to be added + * @return the interval containing the sum or EXCEPTION if + * either addend interval is EXCEPTION + **/ + public Interval add(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + return new Interval(from.add(r.from), to.add(r.to)); + } + + // Partition this interval into 3 intervals: interval less than 0, interval + // of 0, and interval greater than 0. + private Interval[] partitionBySign() { + final Interval[] result = new Interval[3]; + if (from.signum() == to.signum()) { + result[from.signum() + 1] = this; + } else { + result[1] = Interval.ZERO; + if (from.signum() == -1) { + result[0] = new Interval(from, BigInteger.valueOf(-1)); + } + if (to.signum() == 1) { + result[2] = new Interval(BigInteger.ONE, to); + } + } + return result; + } + + // Perform an interval divide; the divisor interval must not contain 0 + private Interval simpleDivide(final Interval r) { + final BigInteger q1 = from.divide(r.from); + final BigInteger q2 = from.divide(r.to); + final BigInteger q3 = to.divide(r.from); + final BigInteger q4 = to.divide(r.to); + return new Interval(min(q1, q2, q3, q4), max(q1, q2, q3, q4)); + } + + /** + * Returns the interval containing the quotient of an integer in this + * interval divided by an integer in interval r. Note that + * division by 0 is defined to be 0. + * + * @param r interval containing the divisor + * @return the interval containing the quotient or EXCEPTION + * if either the dividend or the divisor interval is EXCEPTION + **/ + public Interval divide(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + final Interval[] divisor = r.partitionBySign(); + final Interval[] q = new Interval[3]; + if (divisor[0] != null) { + q[0] = simpleDivide(divisor[0]); + } + if (divisor[1] != null) { + q[1] = Interval.ZERO; + } + if (divisor[2] != null) { + q[2] = simpleDivide(divisor[2]); + } + + return union(q); + } + + /** + * Returns the interval containing the product of an integer in this + * interval multiplied by an integer in interval r. + * + * @param r interval containing the term to be multiplied + * @return the interval containing the product or EXCEPTION + * if either term interval is EXCEPTION + **/ + public Interval multiply(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + final BigInteger p1 = from.multiply(r.from); + final BigInteger p2 = from.multiply(r.to); + final BigInteger p3 = to.multiply(r.from); + final BigInteger p4 = to.multiply(r.to); + return new Interval(min(p1, p2, p3, p4), max(p1, p2, p3, p4)); + } + + /** + * Returns the interval containing the remainder of an integer in this + * interval divided by an integer in interval r. Note that + * the remainder equals the dividend if the divisor is 0. + * + * @param r interval containing the divisor + * @return the interval containing the remainder or EXCEPTION + * if either the dividend or the divisor interval is EXCEPTION + **/ + public Interval remainder(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + final Interval[] dividend = partitionBySign(); + final Interval[] divisor = r.partitionBySign(); + final Interval[] rem = new Interval[6]; + if (dividend[0] != null) { + if (divisor[0] != null) rem[0] = divisor[0].add(ONE); + if (divisor[2] != null) rem[1] = divisor[2].negate().add(ONE); + } + if (dividend[2] != null) { + if (divisor[0] != null) rem[2] = divisor[0].negate().subtract(ONE); + if (divisor[2] != null) rem[3] = divisor[2].subtract(ONE); + } + if (dividend[1] != null) rem[4] = ZERO; + if (divisor[1] != null) rem[5] = this; + return union(rem); + } + + /** + * Returns the interval containing the result of an integer in this + * interval shifted left by an integer in interval r. A + * negative left shift is defined as a right shift. + * + * @param r interval containing the shift amount + * @return the interval containing the result of the left shift or + * EXCEPTION if either interval is EXCEPTION or + * if the shift amount could be less than -2^31 or greater than 2^31-1. + **/ + public Interval shiftLeft(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + if (r.from.compareTo(MIN_INT) < 0 || r.to.compareTo(MAX_INT) > 0) { + return EXCEPTION; + } + + final BigInteger s1 = from.shiftLeft(r.from.intValue()); + final BigInteger s2 = from.shiftLeft(r.to.intValue()); + final BigInteger s3 = to.shiftLeft(r.from.intValue()); + final BigInteger s4 = to.shiftLeft(r.to.intValue()); + return new Interval(min(s1, s2, s3, s4), max(s1, s2, s3, s4)); + } + + /** + * Returns the interval containing the result of an integer in this + * interval shifted right by an integer in interval r. A + * negative right shift is defined as a left shift. + * + * @param r interval containing the shift amount + * @return the interval containing the result of the right shift or + * EXCEPTION if either interval is EXCEPTION or + * if the shift amount could be less than -2^31 or greater than 2^31-1. + **/ + public Interval shiftRight(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + if (r.from.compareTo(MIN_INT) < 0 || r.to.compareTo(MAX_INT) > 0) { + return EXCEPTION; + } + + final BigInteger s1 = from.shiftRight(r.from.intValue()); + final BigInteger s2 = from.shiftRight(r.to.intValue()); + final BigInteger s3 = to.shiftRight(r.from.intValue()); + final BigInteger s4 = to.shiftRight(r.to.intValue()); + return new Interval(min(s1, s2, s3, s4), max(s1, s2, s3, s4)); + } + + /** + * Returns the interval containing the difference of an integer in this + * interval minus an integer in interval r. + * + * @param r interval containing the integer to be subtracted + * @return the interval containing the difference or EXCEPTION + * if either interval is EXCEPTION + **/ + public Interval subtract(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + return new Interval(from.subtract(r.to), to.subtract(r.from)); + } + + /** + * Returns the interval containing the negative of an integer in this + * interval. + * + * @return the interval containing the negation or EXCEPTION + * if this interval is EXCEPTION + **/ + public Interval negate() { + if (checkException(this)) return EXCEPTION; + return new Interval(to.negate(), from.negate()); + } + + private boolean strictlyPositive() { + return to.signum() == 1 && from.signum() == 1; + } + + private boolean zeroOrPositive() { + return to.signum() >= 0 && from.signum() >= 0; + } + + private boolean strictlyNegative() { + return to.signum() == -1 && from.signum() == -1; + } + + private boolean zeroOrNegative() { + return to.signum() <= 0 && from.signum() <= 0; + } + + /** + * Returns the interval containing the bitwise AND of an integer in this + * interval with an integer in interval r. + * + * @param r interval containing the integer to be AND'ed + * @return the interval containing the AND result or EXCEPTION + * if either interval is EXCEPTION + **/ + public Interval and(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + final Interval lparts[] = partitionBySign(); + final Interval rparts[] = r.partitionBySign(); + final Interval result[] = new Interval[7]; + int k = 0; + + if (lparts[0] != null) { + // only a negative number AND'ed with a negative number returns a + // negative number, because negative numbers can be thought as + // having an infinite number of sign bits + if (rparts[0] != null) { + result[k++] = + (new Interval(maxLength(lparts[0].from, rparts[0].from))) + .negate(); + } + if (rparts[1] != null) { + result[k++] = ZERO; + } + if (rparts[2] != null) { + result[k++] = + new Interval(maxLength(lparts[0].from, rparts[2].to)); + } + } + if (lparts[1] != null) { + result[k++] = ZERO; + } + if (lparts[2] != null) { + if (rparts[0] != null) { + result[k++] = + new Interval(maxLength(lparts[2].to, rparts[0].from)); + } + if (rparts[1] != null) { + result[k++] = ZERO; + } + if (rparts[2] != null) { + result[k++] = + new Interval(maxLength(lparts[2].to, rparts[2].to)); + } + } + + return union(result); + } + + /** + * Returns the interval containing the bitwise NOT of an integer in this + * interval. + * + * @return the interval containing the bitwise not or + * EXCEPTION if this interval is EXCEPTION + **/ + public Interval not() { + if (checkException(this)) return EXCEPTION; + return new Interval(to.not(), from.not()); + } + + // Returns the maximum bit length of BigIntegers + private int maxLength(final BigInteger... vals) { + int result = 0; + for (BigInteger val : vals) { + result = Math.max(result, val.bitLength()); + } + return result; + } + + /** + * Returns the interval containing the bitwise OR of an integer in this + * interval with an integer in interval r. + * + * @param r interval containing the integer to be OR'ed + * @return the interval containing the OR result or EXCEPTION + * if either interval is EXCEPTION + **/ + public Interval or(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + final Interval lparts[] = partitionBySign(); + final Interval rparts[] = r.partitionBySign(); + final Interval result[] = new Interval[7]; + int k = 0; + + if (lparts[0] != null) { + if (rparts[0] != null) { + result[k++] = + (new Interval(maxLength(lparts[0].from, rparts[0].from))) + .negate(); + } + if (rparts[1] != null) { + result[k++] = lparts[0]; + } + if (rparts[2] != null) { + result[k++] = + (new Interval(maxLength(lparts[0].from, rparts[2].to))) + .negate(); + } + } + if (lparts[1] != null) { + result[k++] = r; + } + if (lparts[2] != null) { + if (rparts[0] != null) { + result[k++] = + (new Interval(maxLength(lparts[2].to, rparts[0].from))) + .negate(); + } + if (rparts[1] != null) { + result[k++] = lparts[2]; + } + // only a positive number AND'ed with a positive number returns a + // positive number, because negative numbers can be thought as + // having an infinite number of sign bits + if (rparts[2] != null) { + result[k++] = + new Interval(maxLength(lparts[2].to, rparts[2].to)); + } + } + + return union(result); + } + + /** + * Returns the interval containing the bitwise XOR of an integer in this + * interval with an integer in interval r. + * + * @param r interval containing the integer to be XOR'ed + * @return the interval containing the XOR result or EXCEPTION + * if either interval is EXCEPTION + **/ + public Interval xor(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + int max = maxLength(from, to, r.from, r.to); + boolean negative = strictlyNegative() & r.strictlyPositive() | r.strictlyNegative() & strictlyPositive(); + boolean positive = zeroOrPositive() & r.zeroOrPositive() | strictlyNegative() & r.strictlyNegative(); + + if (negative) return new Interval(bitsInt(max,true), BigInteger.valueOf(-1)); + if (positive) return new Interval(max); + return new Interval(true, max+1); + } + + // Returns true if the interval contains odd numbers + private boolean hasOdd() { + final BigInteger two = BigInteger.valueOf(2); + for (BigInteger i = from; i.compareTo(to) <= 0; + i = i.add(BigInteger.ONE)) { + if (i.mod(two).signum() != 0) return true; + } + return false; + } + + // Returns true if the interval contains even numbers + private boolean hasEven() { + final BigInteger two = BigInteger.valueOf(2); + for (BigInteger i = from; i.compareTo(to) <= 0; + i = i.add(BigInteger.ONE)) { + if (i.mod(two).signum() == 0) return true; + } + return false; + } + + // Return base**exp, where base and exp are positive + private Interval simplePow(final Interval base, final Interval exp) { + assert exp.from.signum() == 1 && exp.to.signum() == 1 && + base.from.signum() == 1 && base.to.signum() == 1; + if (exp.from.compareTo(MAX_INT) > 0 || exp.to.compareTo(MAX_INT) > 0) { + return EXCEPTION; + } + final BigInteger p1 = base.to.pow(exp.to.intValue()); + final BigInteger p2 = base.from.pow(exp.from.intValue()); + return new Interval(min(p1, p2), max(p1, p2)); + } + + /** + * Returns the interval containing an integer in this interval to the power + * of an integer in interval r. + * + * @param r interval containing the exponent + * @return the interval containing the result or EXCEPTION if + * either interval is EXCEPTION + **/ + public Interval pow(final Interval r) { + if (checkException(this, r)) return EXCEPTION; + final Interval[] base = partitionBySign(); + final Interval[] exp = r.partitionBySign(); + final Interval[] result = new Interval[11]; + int k = 0; + if (exp[0] != null) { + if (base[0] != null) { + // a < 0, b < 0, a**b = 1/(a**(-b)) + if (base[0].to.equals(BigInteger.ONE.negate())) { + // if a = -1, a**b = 1 if b is even + // = -1 if b is odd + if (exp[0].hasOdd()) result[k++] = ONE.negate(); + if (exp[0].hasEven()) result[k++] = ONE; + } + if (!base[0].from.equals(BigInteger.ONE.negate())) { + // if a < -1, a**b = 0 + result[k++] = ZERO; + } + } + + // b < 0, 0**b = 1/(0**(-b)) = 1/0 = 0 + if (base[1] != null) result[k++] = ZERO; + + if (base[2] != null) { + // a = 1, b < 0, a**b = 1 + if (base[2].from.equals(BigInteger.ONE)) { + result[k++] = ONE; + } + // a > 1, b < 0, a**b = 0 + if (!base[2].to.equals(BigInteger.ONE)) { + result[k++] = ZERO; + } + } + } + if (exp[1] != null) { + // a**0 = 1 for all a + result[k++] = ONE; + } + if (exp[2] != null) { + if (base[0] != null) { + // a < 0, b > 0, calculate (-a)**b, then calculate the sign + // depending on odd/even power + final Interval x = simplePow(base[0].negate(), exp[2]); + if (exp[2].hasOdd()) result[k++] = x.negate(); + if (exp[2].hasEven()) result[k++] = x; + } + // b > 0, 0**b = 0 + if (base[1] != null) result[k++] = ZERO; + // a > 0, b > 0 + if (base[2] != null) { + result[k++] = simplePow(base[2], exp[2]); + } + } + return union(result); + } + + /** + * Returns an interval containing the value of the bits extracted from an + * integer in this interval starting at a bit position from interval + * min and ending at a bit position from interval + * max. + * + * @param min interval containing the starting bit position + * @param max interval containing the ending bit position + * @return the interval containing the extracted bits or + * EXCEPTION if any input interval is EXCEPTION + **/ + public Interval bitExtract(final Interval min, final Interval max) { + if (checkException(this, min, max)) return EXCEPTION; + + // determine the maximum number of bits that can be extracted, and + // assuming the result can be any integer representable in that bit + // width + final Interval diff = max.subtract(min).add(ONE); + if (diff.to.compareTo(MAX_INT) > 0) { + return EXCEPTION; + } + + return new Interval(Math.max(1, diff.to.intValue())); + } + + private String toString(BigInteger x) { + final int width = x.bitLength(); + final String result; + if (width > 32) { + result = (x.signum() == -1 ? "-" : "") + "2**" + width; + } else { + result = x.toString(); + } + return result; + } + + public String toString() { + if (this == EXCEPTION) { + return "[EXCEPTION]"; + } else { + return "[" + toString(from) + ".." + toString(to) + "]"; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/NullResourceBundle.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/NullResourceBundle.java new file mode 100644 index 0000000000..30bd8987d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/NullResourceBundle.java @@ -0,0 +1,9 @@ +package com.avlsi.csp.util; + +import java.util.ResourceBundle; +import java.util.Enumeration; + +public class NullResourceBundle extends ResourceBundle { + public Enumeration getKeys() { return null; } + protected Object handleGetObject(String key) { return null; } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Problem.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Problem.java new file mode 100644 index 0000000000..e86e1192ad --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/Problem.java @@ -0,0 +1,12 @@ +package com.avlsi.csp.util; + +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.io.Printable; + +public interface Problem { + ParseRange getParseRange(); + String getCode(); + String getMessage(); + void printMessage(Printable pw); + Object[] getArguments(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ProblemFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ProblemFilter.java new file mode 100644 index 0000000000..8ab1b1a155 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/ProblemFilter.java @@ -0,0 +1,90 @@ +package com.avlsi.csp.util; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.io.Printable; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.UnaryFunction; + +// XXX: Eventually switch to using the standard logging interface. +public class ProblemFilter { + public static final String ERROR = "error"; + public static final String WARNING = "warning"; + + /** + * Compares a problem by filename, line number, column number, and error + * code. + **/ + private static final Comparator POSITION_COMPARATOR = + new Comparator() { + public int compare(Object o1, Object o2) { + final Problem p1 = (Problem) o1; + final Problem p2 = (Problem) o2; + final ParsePosition pp1 = p1.getParseRange().start; + final ParsePosition pp2 = p2.getParseRange().start; + int x; + x = pp1.filename.compareTo(pp2.filename); + if (x != 0) return x; + x = pp1.compareTo(pp2); + if (x != 0) return x; + return p1.getCode().compareTo(p2.getCode()); + } + public boolean equals(Object o) { + return o == this; + } + }; + + private final Map store; + private final UnaryFunction classify; + private final BinaryFunction filter; + public ProblemFilter(final UnaryFunction classify, + final BinaryFunction filter) { + this.store = new TreeMap(POSITION_COMPARATOR); + this.classify = classify; + this.filter = filter; + } + public void process(final Collection problems) { + final Map temp = new TreeMap(POSITION_COMPARATOR); + for (Iterator i = problems.iterator(); i.hasNext(); ) { + final Problem prob = (Problem) i.next(); + if (!store.containsKey(prob)) { + final String type = (String) classify.execute(prob); + temp.put(prob, type); + } + } + for (Iterator i = temp.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Problem prob = (Problem) entry.getKey(); + final String type = (String) entry.getValue(); + final Printable p = (Printable) filter.execute(type, prob); + if (p != null) { + p.print(type + ": "); + prob.printMessage(p); + p.flush(); + } + } + store.putAll(temp); + } + public boolean hasError() { + return store.values().contains(ERROR); + } + + public static UnaryFunction getClassifier(final Set warnings) { + return new UnaryFunction() { + public Object execute(final Object o) { + final Problem p = (Problem) o; + if (warnings.contains(p.getCode())) { + return ProblemFilter.WARNING; + } else { + return ProblemFilter.ERROR; + } + } + }; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RefinementResolver.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RefinementResolver.java new file mode 100644 index 0000000000..5ba8a1bccc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RefinementResolver.java @@ -0,0 +1,453 @@ +package com.avlsi.csp.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Set; + +import com.avlsi.csp.ast.*; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.Pair; + +public class RefinementResolver extends VisitorByCategory { + public interface BuiltIn { + String EVENTQUEUEISEMPTY = "eventQueueIsEmpty"; + String ENABLEDSIMERRORS = "enableDSimErrors"; + String STABLE = "stable"; + String WAIT = "wait"; + String LOG4 = "log4"; + String LOG2 = "log2"; + String CHOOSE = "choose"; + String SRANDOM = "srandom"; + String RANDOM = "random"; + String TIME = "time"; + String ENERGY = "energy"; + } + + // Define built-in functions + private static Declaration getDeclaration(final String name, + final Type type, + final int dir) { + final Declarator dcltor = + new Declarator(new IdentifierExpression(name), type, null, dir); + final DeclaratorList dcltors = new DeclaratorList(); + dcltors.addDeclarator(dcltor); + return new Declaration(dcltors); + } + + private static Declaration getDeclaration(final String name, + final Type type) { + return getDeclaration(name, type, Declarator.IN); + } + + private static Declaration getDeclaration(final String name) { + return getDeclaration(name, new IntegerType()); + } + + private static DeclarationList getDeclarations(final Declaration[] dcls) { + final DeclarationList result = new DeclarationList(); + for (int i = 0; i < dcls.length; ++i) result.addDeclaration(dcls[i]); + return result; + } + + private static DeclarationList getDeclarations(final Declaration dcl) { + return getDeclarations(new Declaration[] { dcl }); + } + + private static final Map builtinFunctions = + CollectionUtils.mapify( + new Object[] { + BuiltIn.EVENTQUEUEISEMPTY, + new FunctionDeclaration(BuiltIn.EVENTQUEUEISEMPTY, + new DeclarationList(), + new BooleanType(), + new SequentialStatement()), + + BuiltIn.RANDOM, + new FunctionDeclaration(BuiltIn.RANDOM, + getDeclarations(getDeclaration("bits")), + new IntegerType(), + new SequentialStatement()), + + BuiltIn.SRANDOM, + new FunctionDeclaration(BuiltIn.SRANDOM, + getDeclarations(getDeclaration("bits")), + new IntegerType(), + new SequentialStatement()), + + BuiltIn.CHOOSE, + new FunctionDeclaration(BuiltIn.CHOOSE, + getDeclarations(new Declaration[] { + getDeclaration("condition", + new BooleanType()), + getDeclaration("true_value"), + getDeclaration("false_value") + }), + new IntegerType(), + new SequentialStatement()), + + BuiltIn.LOG2, + new FunctionDeclaration(BuiltIn.LOG2, + getDeclarations(getDeclaration("val")), + new IntegerType(), + new SequentialStatement()), + + BuiltIn.LOG4, + new FunctionDeclaration(BuiltIn.LOG4, + getDeclarations(getDeclaration("val")), + new IntegerType(), + new SequentialStatement()), + + BuiltIn.WAIT, + new FunctionDeclaration(BuiltIn.WAIT, + getDeclarations(getDeclaration("delay")), + null, + new SequentialStatement()), + + BuiltIn.STABLE, + new FunctionDeclaration(BuiltIn.STABLE, + getDeclarations( + getDeclaration( + "node", + new NodeType(PortDirection.IN), + Declarator.INOUT)), + new IntegerType(), + new SequentialStatement()), + + BuiltIn.ENABLEDSIMERRORS, + new FunctionDeclaration(BuiltIn.ENABLEDSIMERRORS, + getDeclarations(getDeclaration("val")), + null, + new SequentialStatement()), + + BuiltIn.TIME, + new FunctionDeclaration(BuiltIn.TIME, + new DeclarationList(), + new IntegerType(), + new SequentialStatement()), + BuiltIn.ENERGY, + new FunctionDeclaration(BuiltIn.ENERGY, + getDeclarations(getDeclaration("val")), + null, + new SequentialStatement()) + }); + + public static final String RESET_FUNCTION_NAME = "resetNodes"; + public static final FunctionCallExpression RESET_FUNCTION_CALL = + new FunctionCallExpression( + new IdentifierExpression(RESET_FUNCTION_NAME)); + + public static boolean isBuiltin(final Object decl) { + return builtinFunctions.values().contains(decl); + } + + public interface Policy { + /** + * Determine whether a function declaration is the function to invoke + * in a function call expression. + * + * @param p program where decl is defined + * @param decl function declaration + * @param expr function call expression + * @return true if the function declaration is compatible + * with the function call; false otherwise + **/ + boolean isMatch(CSPProgram p, FunctionDeclaration decl, + FunctionCallExpression expr); + /** + * Determine whether a function declaration is a constructor call for + * the given structure. + **/ + boolean isMatch(CSPProgram p, StructureDeclaration decl, + FunctionCallExpression expr); + + /** + * Determine whether the structure type refers to the given structure + * declaration. + **/ + boolean isMatch(CSPProgram p, StructureDeclaration decl, + StructureType t); + } + + /** + * A policy that determines function and structure compatibility by + * examining only the name. + **/ + public static Policy NAME = new Policy() { + private boolean isMatch(final FunctionCallExpression expr, + final String name) { + final ExpressionInterface func = expr.getFunctionExpression(); + return func instanceof IdentifierExpression && + ((IdentifierExpression) func).getIdentifier().equals(name); + } + public boolean isMatch(CSPProgram p, + FunctionDeclaration decl, + FunctionCallExpression expr) { + return isMatch(expr, decl.getName()); + } + public boolean isMatch(CSPProgram p, StructureDeclaration decl, + FunctionCallExpression expr) { + return isMatch(expr, decl.getName()); + } + public boolean isMatch(CSPProgram p, StructureDeclaration decl, + StructureType t) { + return decl.getName().equals(t.getName()); + } + }; + + private final Policy policy; + private CSPProgram currentProgram; + private StatementInterface stmt; + private SequentialStatement initStmt; + private FunctionDeclaration currentFunc; + private StructureDeclaration currentStruct; + private Map/*>*/ functionMap; + private Map/*>*/ structureMap; + private Set/**/ usedFunctions; + private Set/**/ usedStructures; + + public RefinementResolver(final Policy policy) { + this.policy = policy; + } + + public void resolve(final CSPProgram p) throws VisitorException { + currentProgram = p; + currentFunc = null; + currentStruct = null; + functionMap = + new IdentityHashMap/*>*/(); + structureMap = + new IdentityHashMap/*>*/(); + usedFunctions = new LinkedHashSet/**/(); + usedStructures = new LinkedHashSet/**/(); + final Pair stmts = resolveStatement(p); + initStmt = (SequentialStatement) stmts.getFirst(); + if (initStmt != null) initStmt.accept(getVisitor()); + stmt = (StatementInterface) stmts.getSecond(); + if (stmt != null) { + resolveFunction(currentProgram, RESET_FUNCTION_CALL); + stmt.accept(getVisitor()); + } + } + + public CSPProgram getCSPProgram() { + final CSPProgram result = new CSPProgram(); + result.epr(currentProgram); + + for (Iterator i = usedFunctions.iterator(); i.hasNext(); ) { + result.addFunctionDeclaration((FunctionDeclaration) i.next()); + } + for (Iterator i = usedStructures.iterator(); i.hasNext(); ) { + result.addStructureDeclaration((StructureDeclaration) i.next()); + } + if (stmt != null) result.setStatement(stmt); + if (initStmt != null) result.setInitializerStatement(initStmt); + return result; + } + + public StatementInterface getStatement() { + return stmt; + } + + public Map/*>*/ + getResolvedFunctions() { + return functionMap; + } + + public Map/*>*/ + getResolvedStructures() { + return structureMap; + } + + public boolean isUsed(final FunctionDeclaration decl) { + return usedFunctions.contains(decl); + } + + public boolean isUsed(final StructureDeclaration decl) { + return usedStructures.contains(decl); + } + + public static Pair resolveStatement(final CSPProgram p) { + Pair result = new Pair(p.getInitializerStatement(), p.getStatement()); + for (Iterator i = p.getRefinementParents().iterator(); + result.getSecond() == null && i.hasNext(); ) { + final CSPProgram parent = (CSPProgram) i.next(); + if (!p.inheritDeclarationOnly(parent)) + result = resolveStatement(parent); + } + return result; + } + + private Pair/**/ findBuiltin( + final FunctionCallExpression e) { + for (Iterator i = builtinFunctions.values().iterator(); i.hasNext(); ) { + final FunctionDeclaration decl = (FunctionDeclaration) i.next(); + if (policy.isMatch(null, decl, e)) { + return new Pair/**/(null, decl); + } + } + return null; + } + + private Pair/**/ findLocal( + final CSPProgram p, + final FunctionCallExpression e) { + for (Iterator i = p.getFunctionDeclarations(); i.hasNext(); ) { + final FunctionDeclaration decl = (FunctionDeclaration) i.next(); + if (decl == currentFunc) + break; + else if (policy.isMatch(p, decl, e)) + return new Pair/**/(p, decl); + } + for (Iterator i = p.getStructureIterator(); i.hasNext(); ) { + final StructureDeclaration decl = (StructureDeclaration) i.next(); + if (decl == currentStruct) + break; + else if (policy.isMatch(p, decl, e)) + return new Pair/**/(p, decl); + } + return null; + } + + private Pair/**/ findLocal( + final CSPProgram p, + final StructureType t) { + for (Iterator i = p.getStructureIterator(); i.hasNext(); ) { + final StructureDeclaration decl = (StructureDeclaration) i.next(); + if (decl == currentStruct) + break; + else if (policy.isMatch(p, decl, t)) + return new Pair/**/(p, decl); + } + return null; + } + + private Pair/**/ findFunction( + final CSPProgram p, + final FunctionCallExpression e) + throws VisitorException { + Pair/**/ result = findLocal(p, e); + for (Iterator i = p.getRefinementParents().iterator(); + i.hasNext() && result == null; ) { + final CSPProgram parent = (CSPProgram) i.next(); + result = findFunction(parent, e); + } + if (result != null) { + final Object func = result.getSecond(); + if (func instanceof FunctionDeclaration) { + final CSPProgram oldProg = currentProgram; + final FunctionDeclaration oldFunc = currentFunc; + currentProgram = (CSPProgram) result.getFirst(); + currentFunc = (FunctionDeclaration) func; + processFunctionDeclaration(currentFunc); + currentProgram = oldProg; + currentFunc = oldFunc; + } + } + return result; + } + + private Pair/**/ findStructure( + final CSPProgram p, + final StructureType t) + throws VisitorException { + Pair/**/ result = findLocal(p, t); + for (Iterator i = p.getRefinementParents().iterator(); + i.hasNext() && result == null; ) { + final CSPProgram parent = (CSPProgram) i.next(); + result = findStructure(parent, t); + } + if (result != null) { + final CSPProgram oldProg = currentProgram; + final StructureDeclaration oldStruct = currentStruct; + currentProgram = (CSPProgram) result.getFirst(); + currentStruct = (StructureDeclaration) result.getSecond(); + processStructureDeclaration(currentStruct); + currentProgram = oldProg; + currentStruct = oldStruct; + } + return result; + } + + private void resolveFunction(final CSPProgram p, + final FunctionCallExpression e) + throws VisitorException { + final boolean isBuiltin; + Pair/**/ decl = findBuiltin(e); + if (decl == null) { + isBuiltin = false; + decl = findFunction(p, e); + } else { + isBuiltin = true; + } + functionMap.put(e, decl); + if (decl != null && !isBuiltin) { + final Object o = decl.getSecond(); + if (o instanceof FunctionDeclaration) { + usedFunctions.add(o); + } else { + assert o instanceof StructureDeclaration; + usedStructures.add(o); + } + } + } + + private void resolveStructure(final CSPProgram p, + final StructureType t) + throws VisitorException { + Pair/**/ decl = findStructure(p, t); + structureMap.put(t, decl); + if (decl != null) usedStructures.add(decl.getSecond()); + } + + protected void processGuardedCommandInterface(GuardedCommandInterface gci) + throws VisitorException { + if (gci instanceof GuardedCommand) { + final GuardedCommand g = (GuardedCommand) gci; + if (g instanceof GuardedCommandWithStatement) { + final GuardedCommandWithStatement gcws = + (GuardedCommandWithStatement) g; + gcws.getGuardStatement().accept(getVisitor()); + } + g.getGuard().accept(getVisitor()); + if (g.getLinkageTerms() != null) + processLinkageTerms(g.getLinkageTerms()); + g.getCommand().accept(getVisitor()); + } else if (gci instanceof LoopGuard) { + final LoopGuard g = (LoopGuard) gci; + for (Iterator i = g.getGuards().iterator(); i.hasNext(); ) { + final GuardedCommandInterface one = + (GuardedCommandInterface) i.next(); + processGuardedCommandInterface(one); + } + } + } + + public void visitFunctionCallExpression(final FunctionCallExpression e) + throws VisitorException { + resolveFunction(currentProgram, e); + super.visitFunctionCallExpression(e); + } + + public void visitArrayType(final ArrayType t) throws VisitorException { + t.getElementType().accept(getVisitor()); + } + + public void visitStructureType(final StructureType t) + throws VisitorException { + resolveStructure(currentProgram, t); + } + + public void visitIntegerType(IntegerType t) throws VisitorException { + final ExpressionInterface width = t.getDeclaredWidth(); + if (width != null) width.accept(getVisitor()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RemoveScalars.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RemoveScalars.java new file mode 100644 index 0000000000..e8ad47d6c3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/RemoveScalars.java @@ -0,0 +1,67 @@ +package com.avlsi.csp.util; + +import java.util.Iterator; + +import com.avlsi.csp.ast.Declaration; +import com.avlsi.csp.ast.Declarator; +import com.avlsi.csp.ast.DeclaratorList; +import com.avlsi.csp.ast.IntegerType; +import com.avlsi.csp.ast.SequentialStatement; +import com.avlsi.csp.ast.StatementInterface; +import com.avlsi.csp.ast.Type; +import com.avlsi.csp.ast.VarStatement; +import com.avlsi.csp.ast.VisitorException; +import com.avlsi.util.functions.UnaryPredicate; + +/** + * A class to remove scalar declarations from the initializers. + **/ +public class RemoveScalars extends DeclarationProcessor { + /** + * A unary predicate that evaluates to true for declarators that should be + * filtered away. + **/ + private final UnaryPredicate filter; + private DeclaratorList declList = null; + + public RemoveScalars(final UnaryPredicate filter) { + this.filter = filter; + } + + public void process(final Declarator d) throws VisitorException { + // only attempt to filter away integer constants, because it's more + // complicated to remove constant arrays + if (!(d.getTypeFragment() instanceof IntegerType) || + !filter.evaluate(d)) { + if (declList == null) declList = new DeclaratorList(); + declList.addDeclarator(d); + } + } + + public static SequentialStatement process( + final SequentialStatement initStmt, + final UnaryPredicate filter) { + if (initStmt == null) return null; + + SequentialStatement result = new SequentialStatement(); + for (Iterator i = initStmt.getStatements(); i.hasNext(); ) { + StatementInterface stmt = (StatementInterface) i.next(); + if (stmt instanceof VarStatement) { + final VarStatement var = (VarStatement) stmt; + RemoveScalars rs = new RemoveScalars(filter); + try { + rs.process(var.getDeclarationList()); + } catch (VisitorException e) { + throw new AssertionError("Should never happen: " + e); + } + stmt = rs.declList == null ? + null + : new VarStatement(new Declaration(rs.declList)); + } + if (stmt != null) { + result.addStatement(stmt); + } + } + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SimpleProblem.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SimpleProblem.java new file mode 100644 index 0000000000..9467203906 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SimpleProblem.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.util; + +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.io.Printable; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; + +public abstract class SimpleProblem implements Problem { + protected final String errorCode; + protected final ParseRange pr; + protected final Object[] args; + public SimpleProblem(final String errorCode, final ParseRange pr, + final Object[] args) { + this.errorCode = errorCode; + this.pr = pr; + this.args = args; + } + public ParseRange getParseRange() { + return pr; + } + public String getCode() { + return errorCode; + } + public Object[] getArguments() { + return args; + } + public abstract String getMessage(); + public void printMessage(Printable out) { + ExceptionPrettyPrinter.prettyMessage(getMessage().trim(), + pr.start.filename, + pr.start.line, + pr.start.column + 1, + out); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SymbolTable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SymbolTable.java new file mode 100644 index 0000000000..350d368249 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/SymbolTable.java @@ -0,0 +1,57 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.csp.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +public class SymbolTable { + private final Map> table; + private final LinkedList> history; + private Set scope; + + public SymbolTable() { + table = new HashMap>(); + history = new LinkedList>(); + scope = new HashSet(); + } + + public void enterScope() { + history.addFirst(scope); + scope = new HashSet(); + } + + public void leaveScope() { + for (String s : scope) table.get(s).removeFirst(); + scope = history.removeFirst(); + } + + public V lookup(final String s) { + final LinkedList l = table.get(s); + return l == null || l.isEmpty() ? null : l.getFirst(); + } + + public V lookupCurrent(final String s) { + return scope.contains(s) ? lookup(s) : null; + } + + public boolean bind(final String s, final V v) { + if (!scope.add(s)) return false; + + LinkedList l = table.get(s); + if (l == null) { + l = new LinkedList(); + table.put(s, l); + } + l.addFirst(v); + return true; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/UniqueLabel.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/UniqueLabel.java new file mode 100644 index 0000000000..3c208fea99 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/UniqueLabel.java @@ -0,0 +1,22 @@ +package com.avlsi.csp.util; + +import java.util.IdentityHashMap; +import java.util.Map; + +public class UniqueLabel { + private final Map map; + public UniqueLabel() { + this(new IdentityHashMap()); + } + public UniqueLabel(final Map map) { + this.map = map; + } + public int getLabel(final Object o) { + Integer i = (Integer) map.get(o); + if (i == null) { + i = new Integer(map.size()); + map.put(o, i); + } + return i.intValue(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalysisException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalysisException.java new file mode 100644 index 0000000000..fb54737f4a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalysisException.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.util; + +/** + * Class for exceptions thrown by {@link VariableAnalyzer#getResults}. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class VariableAnalysisException extends Exception { + VariableAnalysisException(String s) { + super(s); + } + VariableAnalysisException(String s, Throwable cause) { + super(s, cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalyzer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalyzer.java new file mode 100644 index 0000000000..f94e691712 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VariableAnalyzer.java @@ -0,0 +1,2196 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.csp.util; + +import com.avlsi.cell.CellUtils; +import com.avlsi.csp.ast.*; +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.csp.util.CSPCellInfo; + +import com.avlsi.fast.metaparameters.*; + +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.fast.ports.PortDefinition; + +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; + +import java.math.BigInteger; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.TreeMap; +import java.util.Vector; + +import java.util.Enumeration; +import java.io.FileInputStream; +import java.io.IOException; +import com.avlsi.io.Printable; + +/** + * Class to analyze the use of variables. Determines the implied set + * (of undeclared variables). Also performs some type-checking. + * Associates types with channels and undeclared variables when these types + * can be determined. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public class VariableAnalyzer { + /** + * Special void type. + **/ + private static final Type VOID = new Type() { + public void accept(VisitorInterface v) throws VisitorException { } + public int dimension() { return 0; } + public String toString() { return "void"; } + }; + + /** + * Special don't-care type. + **/ + private static final Type ANY = new Type() { + public void accept(VisitorInterface v) throws VisitorException { } + public int dimension() { return 0; } + public String toString() { return "unknown"; } + }; + + private static final ResourceBundle INVALID = new NullResourceBundle(); + private static ResourceBundle resourceBundle = null; + public static ResourceBundle getResourceBundle() { + if (resourceBundle == null) { + try { + resourceBundle = ResourceBundle.getBundle( + "com.avlsi.csp.resources.typechecker"); + } catch (MissingResourceException e) { + System.err.println("Cannot load type checker error messages."); + resourceBundle = INVALID; + } + } + return resourceBundle; + } + + private static class TypeError extends SimpleProblem { + public TypeError(final String errorCode, final ParseRange pr, + final Object[] args) { + super(errorCode, pr, args); + } + public String getMessage() { + final ResourceBundle rb = getResourceBundle(); + if (rb != INVALID) { + try { + return MessageFormat.format(rb.getString(getCode()), args); + } catch (MissingResourceException e) { } + } + + return errorCode; + } + } + + /** + * Metaparameter and ports information. Use null to avoid + * type checking channel expressions. + **/ + CSPCellInfo cellInfo; + + public VariableAnalyzer(CSPCellInfo cellInfo) { + this.cellInfo = cellInfo; + } + + /** + * A nested class used for reporting results. Sets contain objects of type + * java.lang.String. + **/ + public static class Results { + private Map undeclaredReads; + private Map undeclaredWrites; + private Map undeclaredTypes; + private Map/**/ expressionTypes; + private Map/**/ identUse; + private Set identRef; + private Set identRefTypes; + private Set initializerTokens; + private boolean inFunctionInitializer; + private boolean inInitializer; + final RefinementResolver resolver; + private Set declarationWarned = new HashSet(); + private Collection/**/ errors; + + public Results(final RefinementResolver resolver) { + this(resolver, Collections.EMPTY_MAP); + } + + public Results(final RefinementResolver resolver, final Map identUse) { + undeclaredReads = new HashMap(); + undeclaredWrites = new HashMap(); + undeclaredTypes = new HashMap(); + expressionTypes = new HashMap/**/(); + // XXX: We really want to used IdentityLinkedHashMap here + this.identUse = + new LinkedHashMap/**/(identUse); + this.identRef = new HashSet(); + this.identRefTypes = new HashSet(); + this.initializerTokens = new HashSet(); + this.inFunctionInitializer = false; + this.inInitializer = false; + this.resolver = resolver; + this.errors = new ArrayList(); + } + + public void useIdent(final IdentifierExpression ident, + final Type type) { + identUse.put(ident, type); + if (inFunctionInitializer) initializerTokens.add(type); + if (!inInitializer) { + identRef.add(ident.getIdentifier()); + identRefTypes.add(type); + } + } + + /** + * Returns the set intersection(undeclaredReads, undeclaredWrites). + * + * @return Set of String variable names + **/ + public Set getImpliedSet() { + Set results = + new HashSet(undeclaredWrites.keySet()); + results.retainAll (undeclaredReads.keySet()); + return results; + } + + /** + * Returns the set undeclaredWrites \ undeclaredReads + * + * @return Set of String variable names + **/ + public Set getUnusedSet() { + Set results = + new HashSet(undeclaredWrites.keySet()); + results.removeAll (undeclaredReads.keySet()); + return results; + } + + /** + * Returns the set undeclaredReads \ undeclaredWrites + * + * @return Set of String variable names + **/ + public Set getUninitializedSet() { + Set results = + new HashSet(undeclaredReads.keySet()); + results.removeAll (undeclaredWrites.keySet()); + return results; + } + + /** + * Returns the map intersection(undeclaredReads, undeclaredWrites). + * + * @return Map of String variable names + **/ + public Map getImpliedMap() { + Map results = + new TreeMap(undeclaredWrites); + results.keySet().retainAll (undeclaredReads.keySet()); + return results; + } + + /** + * Returns the map undeclaredWrites \ undeclaredReads + * + * @return Map of String variable names + **/ + public Map getUnusedMap() { + Map results = + new TreeMap(undeclaredWrites); + results.keySet().removeAll (undeclaredReads.keySet()); + return results; + } + + /** + * Returns the map undeclaredReads \ undeclaredWrites + * + * @return Map of String variable names + **/ + public Map getUninitializedMap() { + Map results = + new TreeMap(undeclaredReads); + results.keySet().removeAll (undeclaredWrites.keySet()); + return results; + } + + /** + * Returns the map union(undeclaredReads, undeclaredWrites). + * + * @return Map of String variable names + **/ + public Map getUndeclaredMap() { + Map results = + new TreeMap(undeclaredReads); + results.putAll (undeclaredWrites); + return results; + } + + /** + * Returns a map from the names of undeclared variables to the types of + * undeclared variables, or maps to null if the type is unknown. + * + * @return Map from String to Type. + **/ + public Map getUndeclaredTypes() { + return undeclaredTypes; + } + + public Type getUndeclaredType(final String s) { + return undeclaredTypes.get(s); + } + + public void setUndeclaredType(final String s, final Type t) { + undeclaredTypes.put(s, t); + } + + /** + * Returns a map from expressions to the types of expressions, or maps + * to null if the type is unknown. + * + * @return Map from ExpressionInterface to Type. + **/ + public Map/**/ getExpressionTypes() { + Map/**/ results = + new HashMap/**/(expressionTypes); + return results; + } + + /** + * Return the map of undeclared reads. Only used internally. + **/ + private Map getUndeclaredWrites() { + return undeclaredWrites; + } + + /** + * Return the map of undeclared writes. Only used internally. + **/ + private Map getUndeclaredReads() { + return undeclaredReads; + } + + /** Adds an object to the specified undeclared map **/ + public void addUndeclared(Map undeclaredMap, + String o, ParseRange r) { + if (!undeclaredMap.containsKey(o)) undeclaredMap.put(o,r); + } + + /** Sets the type of an expression **/ + public void setType(ExpressionInterface e, Type t) { + if (!(getType(e) instanceof NodeType)) + expressionTypes.put(e, t); + } + + /** Gets the type of an expression **/ + public Type getType(ExpressionInterface e) { + return (Type) expressionTypes.get(e); + } + + // For this system of variable lifting to work, we require that + // different variables must be represented by different instances of + // IdentifierExpression (it is permissible to have different instances + // of IdentifierExpression for the same variable) and each variable + // must have different an unique instances of Type associated with it. + // Reference equality (i.e., ==) is used, so care must be taken when + // constructing or copying objects. + + public Object getIdentToken(final IdentifierExpression id) { + assert identUse.containsKey(id); + Object result = identUse.get(id); + if (result == null) { + result = getUndeclaredTypes().get(id.getIdentifier()); + } + return result; + } + + public Map/**/ getTokenIdentMap() { + // XXX: We really want to used IdentityLinkedHashMap here + final LinkedHashMap/**/ result = + new LinkedHashMap/**/(); + for (Iterator i = identUse.keySet().iterator(); i.hasNext(); ) { + final IdentifierExpression id = (IdentifierExpression) i.next(); + final Object token = getIdentToken(id); + if (result.containsKey(token)) { + assert result.get(token).equals(id.getIdentifier()); + } else { + result.put(token, id.getIdentifier()); + } + } + return result; + } + + public Set getInitializerTokens() { + return initializerTokens; + } + + /** + * Returns a set of identifiers (represented as Strings) referenced. + **/ + public Set getUsedIdentifiers() { + return Collections.unmodifiableSet(identRef); + } + + /** + * Returns a set of types associated with identifiers referenced. + **/ + public Set getUsedTokens() { + return Collections.unmodifiableSet(identRefTypes); + } + + public Collection getUndeclaredErrors(final boolean strictVars) { + final Collection result = new ArrayList(); + if (strictVars) { + Map undeclaredMap = getUndeclaredMap(); + for (final Iterator i = undeclaredMap.entrySet().iterator(); + i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + result.add( + new TypeError("type.checker.undeclared.var", + (ParseRange) entry.getValue(), + new Object[] { entry.getKey() })); + } + } else { + final Map unusedMap = getUnusedMap(); + for (final Iterator i = unusedMap.entrySet().iterator(); + i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + result.add( + new TypeError("type.checker.undeclared.set.unused", + (ParseRange) entry.getValue(), + new Object[] { entry.getKey() })); + } + + final Map uninitializedMap = getUninitializedMap(); + for (final Iterator i = uninitializedMap.entrySet().iterator(); + i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + result.add( + new TypeError("type.checker.undeclared.uninit", + (ParseRange) entry.getValue(), + new Object[] { entry.getKey() })); + } + } + return result; + } + + public Collection getErrors(final boolean strictVars) { + final Collection result = new ArrayList(); + result.addAll(errors); + result.addAll(getUndeclaredErrors(strictVars)); + return result; + } + } + + /** + * Returns the results of analyzing the main body of a CSP program. + * + * @param p Program to analyze + * @return Set of identifiers (as java.lang.String) + **/ + public Results getResults (CSPProgram p, RefinementResolver resolver) + throws VariableAnalysisException { + Results results = new Results(resolver); + Map predeclared = new HashMap(); + + // Get metaparameters. + + predeclared.putAll(getMetaParamMap()); + + // Get ports. + + predeclared.putAll(getPortMap()); + + // Walk the syntax tree of the main program, if defined. Otherwise, + // return an empty set. + + SequentialStatement initSI = p.getInitializerStatement(); + StatementInterface si = p.getStatement(); + if (initSI != null || si != null) + computeTypes (initSI, si, predeclared, Collections.EMPTY_MAP, + resolver, results, false); + + // return the results + + return results; + } + + /** + * Returns the results of analyzing the body of a function. + * + * @param f Function to analyze + * @param initStmt initializer statement, containing declarations of + * and assignments to top level constants + * @return Set of identifiers (as java.lang.String) + **/ + public Results getResults (FunctionDeclaration f, + SequentialStatement initStmt, + RefinementResolver resolver) + throws VariableAnalysisException { + Map predeclared = new HashMap(); + // Get the set of metaparameters. + + predeclared.putAll (getMetaParamMap()); + + // Get the set of ports. + + predeclared.putAll (getPortMap()); + + // Get the set of formal arguments + + Map funcParams = new HashMap(); + + // XXX: We really want to used IdentityLinkedHashMap here + final LinkedHashMap identUse = new LinkedHashMap(); + for (Iterator i = f.getFormals().getDeclarations(); i.hasNext(); ) { + final Declaration decl = (Declaration) i.next(); + funcParams.putAll (decl.getMap()); + for (Iterator j = decl.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator declarator = (Declarator) j.next(); + identUse.put(declarator.getIdentifier(), + declarator.getTypeFragment()); + } + } + + // Add the function name to the list of funcParams variables + + if (f.getReturnType() != null) { + funcParams.put (f.getName(), f.getReturnType()); + identUse.put(f.getNameIdentifier(), f.getReturnType()); + } + + // Walk the syntax tree of the function body + + final Results results = new Results(resolver, identUse); + + computeTypes(initStmt, f.getBodyStatement(), predeclared, funcParams, + resolver, results, true); + + // return the implied set + + return results; + } + + private void computeTypes(SequentialStatement initStmt, + StatementInterface s, + Map declared, + Map funcParams, + RefinementResolver resolver, + Results results, + boolean isFunction) + throws VariableAnalysisException { + try { + final HashMap withInit = + new HashMap(declared); + final VisitorImplementation visitorInit = + new VisitorImplementation (withInit, results); + + if (initStmt != null) { + // do not use initStmt.accept(visitorInit), because then any + // variable declaration in initStmt will be created in a + // local scope, and won't be visible to the actual + // statements + results.inFunctionInitializer = isFunction; + results.inInitializer = true; + for (final Iterator i = initStmt.getStatements(); + i.hasNext(); ) + ((StatementInterface) i.next()).accept(visitorInit); + results.inFunctionInitializer = false; + results.inInitializer = false; + } + + final Map withFuncParams = + new HashMap(withInit); + withFuncParams.putAll(funcParams); + final VisitorImplementation visitor = + new VisitorImplementation (withFuncParams, results); + + if (s != null) s.accept(visitor); + + // validate the types of predeclared variables + for (Type ty : declared.values()) ty.accept(visitor); + + // validate the types of function parameter and return value types + for (Type ty : funcParams.values()) ty.accept(visitor); + + } catch (VisitorException e) { + throw new VariableAnalysisException + (s.getParseRange().fullString() + + ": Error in variable analysis. " + e.getMessage(), e); + } + } + + /** + * Traverses an AST until known type information stabilizes. Returns + * results of final traversal. (The traversal method should guarantee that + * known type information is monotonically increasing. Since there are a + * finite number of expressions with unknown type, the method will + * eventually return.) + * + * XXX: This method is dependent on the behavior of VisitorImplementation. + * In particular, VisitorImplementation currently updates the undeclared + * variable type information at the same time that the expression + * information is updated. + * + * @param initStmt statements containing CAST constants + * @param s Statement to traverse + * @param declared Map of predeclared variable names to types + * @param Results of traversal + **/ + private void walkUntilStabilized(SequentialStatement initStmt, + StatementInterface s, + Map/**/ declared, + RefinementResolver resolver, + Results results, + boolean isFunction) + throws VariableAnalysisException { + int N = 0; // N == number of currently known types + int M = -1; // M == number of previously known types + + try { + while (N != M) { + M = N; + N = 0; + HashMap/**/ declaredIn = + new HashMap/**/(declared); + final VisitorImplementation visitor = + new VisitorImplementation (declaredIn, results); + + if (initStmt != null) { + // do not use initStmt.accept(visitor), because then any + // variable declaration in initStmt will be created in a + // local scope, and won't be visible to the actual + // statements + results.inFunctionInitializer = isFunction; + results.inInitializer = true; + for (final Iterator i = initStmt.getStatements(); + i.hasNext(); ) + ((StatementInterface) i.next()).accept(visitor); + results.inFunctionInitializer = false; + results.inInitializer = false; + } + + if (s != null) s.accept(visitor); + Map/**/ types = + results.getExpressionTypes(); + for (Iterator i = types.keySet().iterator(); i.hasNext(); ) { + if (types.get(i.next()) != null) + N++; + } + if (N == M) { // do this only once on the last iteration + // validate the types of predeclared variables + for (Iterator i = declared.values().iterator(); + i.hasNext(); ) { + Type ty = (Type) i.next(); + ty.accept(visitor); + } + } + } + } catch (VisitorException e) { + throw new VariableAnalysisException + (s.getParseRange().fullString() + + ": Error in variable analysis. " + e.getMessage(), e); + } + } + + /** Get a Map of the ports of the current cell. **/ + private /*@ non_null @*/ Map getPortMap() { + Map results = new HashMap(); + for (Iterator i = cellInfo.getPortDefinitions(); i.hasNext(); ) { + PortDefinition d = (PortDefinition) i.next(); + // TODO: We probably want to ignore Vdd, GND, and _RESET, + // but eventually we will not want to ignore other nodes. + results.put(d.getName(), + port2AST(d.getType(), + PortDefinition.updateDirection( + d.getDirection(), + PortDefinition.FORWARD))); + } + return results; + } + + /** + * Maps a {@link PortTypeInterface} to a csp ast {@link Type}. + **/ + private /*@ non_null @*/ Type port2AST( + final /*@ non_null @*/ PortTypeInterface t, + final int direction) { + if (t instanceof com.avlsi.fast.ports.ArrayType) { + final com.avlsi.fast.ports.ArrayType at = + (com.avlsi.fast.ports.ArrayType) t; + // XXX: what to do for parseRange of the nodes we create + // here? + return new ArrayType + (new Range(new IntegerExpression(at.getMinIndex()), + new IntegerExpression(at.getMaxIndex())), + port2AST(at.getArrayedType(), direction)); + } else if (t instanceof com.avlsi.fast.ports.ChannelType) { + final com.avlsi.fast.ports.ChannelType ct = + (com.avlsi.fast.ports.ChannelType) t; + return new ChannelType(computeChannelWidth(ct.getTypeName(), + ct.getWidth()), + PortDirection.mapDirection(direction)); + } else if (t instanceof com.avlsi.fast.ports.NodeType) { + final com.avlsi.fast.ports.NodeType nt = + (com.avlsi.fast.ports.NodeType) t; + return new NodeType(nt.getWidth(), + PortDirection.mapDirection(direction), + nt.isArrayed()); + } else { + assert t instanceof com.avlsi.fast.ports.StructureType; + final com.avlsi.fast.ports.StructureType st = + (com.avlsi.fast.ports.StructureType) t; + final ChannelStructureType cst = + new ChannelStructureType(st.getTag()); + for (Iterator i = st.iterator(); i.hasNext(); ) { + final PortDefinition portDef = (PortDefinition) i.next(); + cst.addMember(portDef.getName(), + port2AST(portDef.getType(), + PortDefinition.updateDirection( + direction, + portDef.getDirection()))); + } + return cst; + } + } + + /** + * Returns the base width of the channel, ie how many values + * the unbundled channel can carry. + **/ + private static int getChannelBase(final /*@ non_null @*/ String + channelTypeName) { + final int result = CellUtils.extractN(channelTypeName); + assert result != -1; + return result; + } + + /** + * Returns how many values a wide channel can carry. + **/ + private static /*@ non_null @*/ BigInteger computeChannelWidth( + final /*@ non_null @*/ String channelTypeName, + final int width) { + return BigInteger.valueOf(getChannelBase(channelTypeName)) + .pow(width); + } + + /** Get a Map of the metaparameters of the current cell. **/ + private Map getMetaParamMap() { + Map results = new HashMap(); + for (Iterator i = cellInfo.getMetaParamDefinitions(); i.hasNext(); ) { + MetaParamDefinition mp = (MetaParamDefinition) i.next(); + results.put (mp.getName(), meta2AST (mp.getType())); + } + return results; + } + + /** Convert a metaparameter type into an AST type **/ + private Type meta2AST(MetaParamTypeInterface t) { + if (t instanceof IntegerMetaParam) { + return new IntegerType(true); + } else if (t instanceof BooleanMetaParam) { + return new BooleanType(true); + } else if (t instanceof FloatMetaParam) { + throw new AssertionError + ((Object) "Float metaparameters unsupported."); + } else if (t instanceof ArrayMetaParam) { + ArrayMetaParam at = (ArrayMetaParam) t; + // XXX: what to do for parseRange of the nodes we create + // here? + return new ArrayType + (new Range(new IntegerExpression(at.getMinIndex()), + new IntegerExpression(at.getMaxIndex())), + meta2AST(at.getArrayedType())); + } else { + throw new AssertionError((Object) "Unknown metaparameter type."); + } + } + + private static boolean isBoolean(Type e) { + return (e instanceof BooleanType) || + (e instanceof NodeType && !((NodeType) e).isArrayed()) || + e == ANY; + } + + private static boolean isInteger(Type e) { + return (e instanceof IntegerType) || + (e instanceof NodeType && ((NodeType) e).isArrayed()) || + e == ANY; + } + + private static boolean isString(Type e) { + return e instanceof StringType || e == ANY; + } + + private static boolean isScalar(Type e) { + return isBoolean(e) || isInteger(e) || isString(e); + } + + /** + * Nested class used to walk the syntax tree. Updates the results + * structure and declared set. Also performs some typechecking. + **/ + private static class VisitorImplementation implements VisitorInterface { + /** Declared variables in the current scope. **/ + Map/**/ declared; + /** Results accumulated by walking the syntax tree. **/ + Results results; + + /** Default interval used for integer with unspecified width. **/ + private static final int LARGE_WIDTH = 1024; + private static final BigInteger LARGE_UPPER_BOUND = + BigInteger.ONE.shiftLeft(LARGE_WIDTH).subtract(BigInteger.ONE); + private static final BigInteger LARGE_LOWER_BOUND = + LARGE_UPPER_BOUND.negate(); + private static final Interval LARGE_INTERVAL = + new Interval(LARGE_LOWER_BOUND, LARGE_UPPER_BOUND); + + /** Both 'declared' and 'results' may be modified. **/ + public VisitorImplementation (Map/**/ declared, + Results results) { + this.declared = declared; + this.results = results; + } + + public void visitCSPProgram(CSPProgram p) throws VisitorException{ + throw new AssertionError((Object) "Can't get here."); + } + + public void visitAddExpression(AddExpression e) + throws VisitorException { + processBinary(e); + + final Type lty = getType(e.getLeft()); + final Type rty = getType(e.getRight()); + if (isString(lty)) { + if (!isScalar(rty)) report("invalid.string.concat", e, rty); + setString(e); + } else if (isString(rty)) { + if (!isScalar(lty)) report("invalid.string.concat", e, lty); + setString(e); + } else if (isInteger(lty) && isInteger(rty)) { + setInteger(e); + setInterval(getInterval(lty).add(getInterval(rty)), e); + } else { + report("invalid.add.operands", e, lty, rty); + setInteger(e); + } + } + + public void visitAndExpression(AndExpression e) + throws VisitorException { + processBitwiseBinary (e); + + final Type lty = getType(e.getLeft()); + final Type rty = getType(e.getRight()); + if (isInteger(lty) && isInteger(rty)) { + setInterval(getInterval(lty).and(getInterval(rty)), e); + } + } + + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + e.getArrayExpression().accept(this); + e.getIndexExpression().accept(this); + expectInteger(e.getIndexExpression()); + + Type t = getType(e.getArrayExpression()); + if (t instanceof ArrayType) { + ArrayType at = (ArrayType) t; + setType(e, at.getElementType()); + } else { + e.checkParseRange(); + report("invalid.array", e, t); + setInteger(e); + } + } + + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + e.getBitsExpression().accept(this); + expectInteger(e.getBitsExpression()); + + if (e.getMinExpression() != null) { + e.getMinExpression().accept(this); + expectInteger(e.getMinExpression()); + } + + e.getMaxExpression().accept(this); + expectInteger(e.getMaxExpression()); + + setInteger(e); + if (e.getMinExpression() == null) { + setInterval(new Interval(1), e); + } else { + setInterval( + getInterval(e.getBitsExpression()) + .bitExtract(getInterval(e.getMinExpression()), + getInterval(e.getMaxExpression())), e); + } + } + + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + processBitwiseBinary(e); + setBoolean(e); + } + + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + processBitwiseBinary(e); + setBoolean(e); + } + + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + processArithmeticBinary(e); + setInterval( + getInterval(e.getLeft()).divide(getInterval(e.getRight())), + e); + } + + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + processBitwiseComparison(e); + } + + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + processArithmeticBinary(e); + setInterval( + getInterval(e.getLeft()).pow(getInterval(e.getRight())), + e); + } + + private void processBuiltinString(final FunctionCallExpression e) + throws VisitorException { + int count = 0; + for (Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + final Type ty = getType(arg); + if (count == 0) { + if (!isInteger(ty) && !isBoolean(ty)) { + report("invalid.string.argument1", e, ty); + } + } else if (count == 1) { + if (!isInteger(ty)) + report("invalid.string.argument2", e, ty); + } else if (count == 2) { + report("too.many.arguments", e, "string"); + } + } + if (count == 0) { + report("too.few.arguments", e, "string"); + } + setString(e); + } + + private void processBuiltinPrint(final FunctionCallExpression e) + throws VisitorException { + int count = 0; + for (Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + final Type ty = getType(arg); + if (count == 0) { + if (i.hasNext()) { + if (!isInteger(ty)) { + report("invalid.print.tag", arg, ty); + } + } else { + if (!isScalar(ty)) { + report("invalid.print.message", arg, ty); + } + } + } else if (count == 1) { + if (!isScalar(ty)) { + report("invalid.print.message", arg, ty); + } + } else if (count == 2) { + report("too.many.arguments", arg, "print"); + } + } + if (count == 0) { + report("too.few.arguments", e, "print"); + } + setVoid(e); + } + + private void processBuiltinAssert(final FunctionCallExpression e) + throws VisitorException { + int count = 0; + for (Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + final Type ty = getType(arg); + if (count == 0) { + if (!isBoolean(ty)) { + report("invalid.assert.argument1", arg, ty); + } + } else if (count == 1) { + if (!isString(ty)) { + report("invalid.assert.argument2", arg, ty); + } + } else if (count == 2) { + report("too.many.arguments", arg, "assert"); + } + } + if (count == 0) { + report("too.few.arguments", e, "assert"); + } + setVoid(e); + } + + /** + * Returns true if the argument is a packed structure. A packed + * structure is a structure that has a finite, declared width. It + * cannot contain strings. + **/ + private boolean isPacked(final Type t) throws VisitorException { + if (t instanceof BooleanType) { + return true; + } else if (t instanceof IntegerType) { + final IntegerType it = (IntegerType) t; + return it.getDeclaredWidth() != null; + } else if (t instanceof ArrayType) { + return isPacked(((ArrayType) t).getElementType()); + } else if (t instanceof StructureType) { + final StructureDeclaration decl = getStructureDecl(null, t); + if (decl == null) { + return false; + } else { + return isPacked(decl); + } + } else { + return false; + } + } + + private boolean isPacked(final StructureDeclaration decl) + throws VisitorException { + final boolean[] result = new boolean[] { true }; + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + final Type t = d.getTypeFragment(); + result[0] &= isPacked(t); + } + }).process(decl.getDeclarations()); + return result[0]; + } + + private int getPackSize(final StructureDeclaration decl) + throws VisitorException { + final int[] result = new int[] { 0 }; + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + if (result[0] != -1) { + final int w = getPackSize(d.getTypeFragment()); + if (w == -1) result[0] = -1; + else result[0] += w; + } + } + }).process(decl.getDeclarations()); + return result[0]; + } + + private int getPackSize(final Type t) throws VisitorException { + int s = -1; + if (t instanceof BooleanType) { + s = 1; + } else if (t instanceof IntegerType) { + final IntegerType it = (IntegerType) t; + final BigInteger w = + CspUtils.getIntegerConstant(it.getDeclaredWidth()); + s = w == null ? -1 : w.intValue(); + } else if (t instanceof ArrayType) { + final ArrayType at = (ArrayType) t; + final Range r = at.getRange(); + final BigInteger min = + CspUtils.getIntegerConstant(r.getMinExpression()); + final BigInteger max = + CspUtils.getIntegerConstant(r.getMaxExpression()); + if (min != null && max != null) { + final int w = getPackSize(at.getElementType()); + if (w != -1) { + BigInteger num = max.subtract(min).add(BigInteger.ONE); + s = num.intValue() * w; + } + } + } else if (t instanceof StructureType) { + final StructureDeclaration decl = getStructureDecl(null, t); + if (decl != null) { + s = getPackSize(decl); + } + } + return s; + } + + private StructureDeclaration getStructureDecl( + final AbstractASTNodeInterface e, + final Type t) { + StructureDeclaration decl = null; + if (t instanceof StructureType) { + StructureType st = (StructureType) t; + final Pair p = (Pair) + results.resolver.getResolvedStructures().get(st); + if (p == null) { + if (e != null) { + e.checkParseRange(); + report("undefined.structure", e, st.getName()); + } + } else { + decl = (StructureDeclaration) p.getSecond(); + } + } else { + if (e != null) { + e.checkParseRange(); + report("not.a.structure", e); + } + } + return decl; + } + + private void processBuiltinPack(final FunctionCallExpression e) + throws VisitorException { + int count = 0; + int size = -1; + for (Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + final Type ty = getType(arg); + if (count == 0) { + processPacked(arg, ty, "packed.expected"); + size = getPackSize(ty); + } else if (count == 1) { + report("too.many.arguments", arg, "pack"); + } + } + if (count == 0) { + report("too.few.arguments", e, "pack"); + } + setInteger(e); + if (size > 0) { + setInterval(new Interval(size), e); + } + } + + private void processBuiltinUnpack(final FunctionCallExpression e) + throws VisitorException { + int count = 0; + for (Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + final Type ty = getType(arg); + if (count == 0) { + processPacked(arg, ty, "packed.expected"); + } else if (count == 1) { + if (!isInteger(ty) && !isBoolean(ty)) { + report("invalid.unpack.argument", arg, ty); + } + } else if (count == 2) { + report("too.many.arguments", arg, "unpack"); + } + } + if (count < 2) { + report("too.few.arguments", e, "unpack"); + } + setVoid(e); + } + + private String getName(final FunctionCallExpression e) { + final ExpressionInterface func = e.getFunctionExpression(); + if (func instanceof IdentifierExpression) { + return ((IdentifierExpression) func).getIdentifier(); + } else { + return null; + } + } + + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + // Find function call declaration using refinement resolver + // to determine types of arguments and return value + final Pair p = (Pair) results.resolver.getResolvedFunctions() + .get(e); + + final String name; + final Object resolved = p == null ? null : p.getSecond(); + if (p == null) { + name = getName(e); + if ("print".equals(name)) { + processBuiltinPrint(e); + } else if ("string".equals(name)) { + processBuiltinString(e); + } else if ("assert".equals(name)) { + processBuiltinAssert(e); + } else if ("pack".equals(name)) { + processBuiltinPack(e); + } else if ("unpack".equals(name)) { + processBuiltinUnpack(e); + } else if (name != null) { + report("unknown.function", e, name); + setAny(e); + } else { + report("invalid.function", e); + setAny(e); + } + return; + } + + final DeclarationList list; + final Type rtype; + if (resolved instanceof FunctionDeclaration) { + final FunctionDeclaration decl = (FunctionDeclaration) resolved; + list = decl.getFormals(); + name = decl.getName(); + rtype = decl.getReturnType() == null ? VOID + : decl.getReturnType(); + } else { + final StructureDeclaration decl = + (StructureDeclaration) resolved; + list = decl.getDeclarations(); + name = decl.getName(); + rtype = new StructureType(false, name); + } + setType(e, rtype); + + final Collection c = new ArrayList(); + (new DeclarationProcessor() { + public void process(final Declarator d) + throws VisitorException { + c.add(d); + } + }).process(list); + final Iterator decls = c.iterator(); + + boolean argsNumWarned = false; + int count = 0; + for (Iterator i = e.getActuals(); i.hasNext(); ++count) { + final ExpressionInterface arg = (ExpressionInterface) i.next(); + arg.accept(this); + + final Declarator decl; + if (decls.hasNext()) { + decl = decls.next(); + } else { + if (!argsNumWarned) report("too.many.arguments", e, name); + argsNumWarned = true; + decl = null; + } + + if (decl != null) { + final Type actualType = getType(arg); + final Type formalType = decl.getTypeFragment(); + final int direction = decl.getDirection(); + + if (!isAssignable(formalType, actualType)) { + report("incompatible.parameter.passing", arg, + formalType, actualType, name); + } else if (direction != Declarator.IN && + arg instanceof BitRangeExpression) { + report("output.bitrange.unsupported", arg, + decl.getIdentifier().getIdentifier()); + } + + if (actualType instanceof ArrayType) { + final Type actBase = CspUtils.getBaseType(actualType); + final Type forBase = CspUtils.getBaseType(formalType); + if (actBase instanceof IntegerType) { + final String wa = getWidthString(actBase); + final String wf = getWidthString(forBase); + if (!wa.equals(wf)) { + report("array.width.mismatch", arg, wf, wa); + } + } + } + } + } + + if (decls.hasNext()) { + report("too.few.arguments", e, name); + } + } + + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + processArithmeticComparison (e); + } + + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + processArithmeticComparison(e); + } + + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + + // This method handles reading of variables. Writing is handled + // explicitly in: + // visitAssignmentStatement() + // visitReceiveStatement() + + processRead(e); + } + + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + processBitwiseComparison(e); + } + + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + if (e instanceof BooleanExpression) { + setBoolean(e); + } else { + setInteger(e); + final IntegerType ity = (IntegerType) getType(e); + ity.setInterval( + new Interval(new BigInteger(e.getValue(), e.getRadix()))); + } + } + + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + processArithmeticBinary(e); + setInterval( + getInterval(e.getLeft()).shiftLeft(getInterval(e.getRight())), + e); + } + + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + processArithmeticComparison(e); + } + + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + processArithmeticComparison(e); + } + + public void visitLoopExpression(LoopExpression e) + throws VisitorException { + + // Visit the min/max expression with the current scope + + e.getRange().getMinExpression().accept(this); + expectInteger(e.getRange().getMinExpression()); + + e.getRange().getMaxExpression().accept(this); + expectInteger(e.getRange().getMaxExpression()); + + // Visit the expression being looped with an augmented + // scope which includes the index variable. + + Map/**/ loopDeclared = + new HashMap/**/(declared); + loopDeclared.put (e.getIndexVar(), new IntegerType()); + e.getExpression().accept( + new VisitorImplementation (loopDeclared, results)); + final Type ty = getType(e.getExpression()); + if (ty instanceof StringType && + e.getSeparator() != LoopExpression.PLUS) { + report("nonstring.plus", e, e.getSeparatorString()); + } + setType(e, ty); + } + + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + processArithmeticBinary(e); + setInterval( + getInterval(e.getLeft()).multiply(getInterval(e.getRight())), + e); + } + + public void visitNegateExpression(NegateExpression e) + throws VisitorException { + processUnary(e); + + final Type ty = getType(e.getExpression()); + if (isInteger(ty)) { + setInterval(getInterval(ty).negate(), e); + } + } + + public void visitNotExpression(NotExpression e) + throws VisitorException { + processUnary(e); + final Type ty = getType(e.getExpression()); + if (isInteger(ty)) { + setInterval(getInterval(ty).not(), e); + } + } + + public void visitOrExpression(OrExpression e) + throws VisitorException { + processBitwiseBinary(e); + + final Type lty = getType(e.getLeft()); + final Type rty = getType(e.getRight()); + if (isInteger(lty) && isInteger(rty)) { + setInterval(getInterval(lty).or(getInterval(rty)), e); + } + } + + public void visitXorExpression(XorExpression e) + throws VisitorException { + processBitwiseBinary(e); + + final Type lty = getType(e.getLeft()); + final Type rty = getType(e.getRight()); + if (isInteger(lty) && isInteger(rty)) { + setInterval(getInterval(lty).xor(getInterval(rty)), e); + } + } + + public void visitPeekExpression(PeekExpression e) + throws VisitorException { + e.getChannelExpression().accept(this); + expectChannel(e.getChannelExpression(), PortDirection.IN); + setInteger(e); + setInterval(getInterval(e.getChannelExpression()), e); + } + + public void visitProbeExpression(ProbeExpression e) + throws VisitorException { + e.getChannelExpression().accept(this); + expectChannel(e.getChannelExpression(), null); + setBoolean(e); + } + + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException { + e.getChannelExpression().accept(this); + expectChannel(e.getChannelExpression(), PortDirection.IN); + setInteger(e); + setInterval(getInterval(e.getChannelExpression()), e); + } + + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + processArithmeticBinary(e); + setInterval( + getInterval(e.getLeft()).remainder(getInterval(e.getRight())), + e); + } + + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + processArithmeticBinary(e); + setInterval( + getInterval(e.getLeft()).shiftRight(getInterval(e.getRight())), + e); + } + + public void visitStringExpression(StringExpression e) + throws VisitorException { + setString(e); + } + + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(this); + final Type t = getType(e.getStructureExpression()); + if (t instanceof ChannelStructureType) { + final ChannelStructureType cst = (ChannelStructureType) t; + final Type memberType = cst.getMemberType(e.getFieldName()); + if (memberType == null) { + report("invalid.field", e, e.getFieldName(), cst.getName()); + setAny(e); + } else { + setType(e, memberType); + } + } else { + e.checkParseRange(); + report("not.a.defchan", e); + setAny(e); + } + } + + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(this); + final Type t = getType(e.getStructureExpression()); + final StructureDeclaration sd = getStructureDecl(e, t); + if (sd == null) { + setAny(e); + } else { + final Map/**/ m = sd.getMap(); + final Type mt = (Type) m.get(e.getMemberName()); + if (mt == null) { + e.checkParseRange(); + report("invalid.member", e, e.getMemberName(), + sd.getName()); + setAny(e); + } else { + setType(e, mt); + } + } + } + + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + processArithmeticBinary(e); + setInterval( + getInterval(e.getLeft()).subtract(getInterval(e.getRight())), + e); + } + + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + s.getRightHandSide().accept(this); + processLvalue(s.getLeftHandSide()); + final Type lty = getType(s.getLeftHandSide()); + final Type rty = getType(s.getRightHandSide()); + switch (s.getKind()) { + case AssignmentStatement.EQUAL: + if (!isAssignable(lty, rty)) { + report("incompatible.assignment", s, lty, rty); + } + if (lty instanceof TemporaryIntegerType) { + setInterval(getInterval(rty), lty); + } + break; + case AssignmentStatement.ADD: + if (isString(lty)) { + if (!isScalar(rty)) report("invalid.string.concat", s, rty); + } else if (!(isInteger(lty) && isInteger(rty))) { + report("invalid.add.operands", s, lty, rty); + } + break; + case AssignmentStatement.SUBTRACT: + case AssignmentStatement.MULTIPLY: + case AssignmentStatement.DIVIDE: + case AssignmentStatement.REMAINDER: + case AssignmentStatement.LEFTSHIFT: + case AssignmentStatement.RIGHTSHIFT: + expectInteger(s.getLeftHandSide()); + expectInteger(s.getRightHandSide()); + break; + case AssignmentStatement.AND: + case AssignmentStatement.OR: + case AssignmentStatement.XOR: + if (!(isBoolean(lty) && isBoolean(rty)) && + !(isInteger(lty) && isInteger(rty))) { + report("invalid.bitwise.operand", s, lty, rty); + } + break; + default: + throw new AssertionError("Unknown assignment kind: " + + s.getKind()); + } + } + + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + s.getExpression().accept(this); + expectInteger(s.getExpression()); + } + + public void visitDeterministicRepetitionStatement( + DeterministicRepetitionStatement s) + throws VisitorException { + processGuardedStatement(s); + } + + public void visitDeterministicSelectionStatement( + DeterministicSelectionStatement s) + throws VisitorException { + processGuardedStatement(s); + } + + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + s.getExpression().accept(this); + } + + public void visitLoopStatement(LoopStatement s) + throws VisitorException { + // Visit the min/max expression with the current scope + s.getRange().getMinExpression().accept(this); + expectInteger(s.getRange().getMinExpression()); + + s.getRange().getMaxExpression().accept(this); + expectInteger(s.getRange().getMaxExpression()); + + // Visit the statement being looped with an augmented + // scope which includes the index variable. + + Map/**/ loopDeclared = + new HashMap/**/(declared); + final IntegerType t = new IntegerType(); + final Interval min = getInterval(s.getRange().getMinExpression()); + final Interval max = getInterval(s.getRange().getMaxExpression()); + if (min != null && max != null) t.setInterval(min.union(max)); + + loopDeclared.put (s.getIndexVar(), t); + results.useIdent(s.getIndexVarExpression(), t); + s.getStatement().accept( + new VisitorImplementation (loopDeclared, results)); + } + + public void visitNonDeterministicRepetitionStatement( + NonDeterministicRepetitionStatement s) + throws VisitorException { + processGuardedStatement(s); + processLinkageTerms(s.getNeutralState()); + } + + public void visitNonDeterministicSelectionStatement( + NonDeterministicSelectionStatement s) + throws VisitorException { + processGuardedStatement(s); + processLinkageTerms(s.getNeutralState()); + } + + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + for (final Iterator i = s.getStatements(); i.hasNext(); ) + ((StatementInterface) i.next()).accept(this); + } + + private void processPacked(final AbstractASTNodeInterface rhs, + final Type ty, + final String err) + throws VisitorException { + if (ty instanceof StructureType) { + final StructureDeclaration sd = getStructureDecl(rhs, ty); + if (sd != null && !isPacked(sd)) { + report("not.a.packed.structure", rhs, sd.getName()); + } + } else if (ty instanceof ArrayType) { + if (!isPacked(ty)) { + report("not.a.packed.array", rhs); + } + } else { + report(err, rhs, ty); + } + } + + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + s.getChannelExpression().accept(this); + expectChannel(s.getChannelExpression(), PortDirection.IN); + if (s.getRightHandSide() != null) { + processLvalue(s.getRightHandSide()); + final Type ty = getType(s.getRightHandSide()); + if (!isInteger(ty) && !isBoolean(ty)) { + processPacked(s.getRightHandSide(), ty, + "int.bool.packed.expected"); + } + } + } + + public void visitSendStatement(SendStatement s) + throws VisitorException { + s.getChannelExpression().accept(this); + expectChannel(s.getChannelExpression(), PortDirection.OUT); + s.getRightHandSide().accept(this); + final Type ty = getType(s.getRightHandSide()); + if (!isInteger(ty) && !isBoolean(ty)) { + processPacked(s.getRightHandSide(), ty, + "int.bool.packed.expected"); + } + } + + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException{ + + // A sequential statement is the only place in which a variable + // declaration should occur, and any variable declaration is + // limited to the scope of the sequential statement which is its + // immediate parent. Hence, we make a new scope here. + + Map/**/ seqDeclared = + new HashMap/**/(declared); + VisitorImplementation vi = + new VisitorImplementation (seqDeclared, results); + + for (final Iterator i = s.getStatements(); i.hasNext(); ) + ((StatementInterface) i.next()).accept(vi); + } + + public void visitErrorStatement(ErrorStatement s) + throws VisitorException { /* Do nothing. */ } + + public void visitSkipStatement(SkipStatement s) + throws VisitorException { /* Do nothing. */ } + + public void visitVarStatement(VarStatement s) throws VisitorException { + if (s.getStatement() != null) + throw new VisitorException ("Old-style CSP unsupported."); + + // For each declarator, visit the initializer and type specifier, + // and add the identifier to the list of variables declared in the + // current scope. + + for (final Iterator i = s.getDeclarationList().getDeclarations(); + i.hasNext(); ) { + final Declaration d = (Declaration) i.next(); + for (final Iterator j = d.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator dr = (Declarator) j.next(); + dr.getTypeFragment().accept(this); + declared.put(dr.getIdentifier().getIdentifier(), + dr.getTypeFragment()); + setType(dr.getIdentifier(), dr.getTypeFragment()); + results.useIdent(dr.getIdentifier(), dr.getTypeFragment()); + // Handle initializer as if it had been an assignment + // statement. This should be less bug-prone than the + // old way of handling the initializer explicity. + if (dr.getInitializer() != null) { + final AssignmentStatement fake = + new AssignmentStatement(dr.getIdentifier(), + dr.getInitializer()); + fake.epr(dr); + fake.accept(this); + } + } + } + } + + public void visitArrayType(ArrayType t) throws VisitorException{ + if (t.getElementType() != null) + t.getElementType().accept(this); + + t.getRange().getMinExpression().accept(this); + expectInteger(t.getRange().getMinExpression()); + + t.getRange().getMaxExpression().accept(this); + expectInteger(t.getRange().getMaxExpression()); + } + + public void visitChannelType(com.avlsi.csp.ast.ChannelType t) + throws VisitorException { /* Do nothing. */ } + + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { /* Do nothing. */ } + + public void visitIntegerType(IntegerType t) + throws VisitorException { + if (t.getDeclaredWidth() != null) { + t.getDeclaredWidth().accept(this); + } + } + + public void visitBooleanType(BooleanType t) + throws VisitorException { /* Do nothing. */ } + + public void visitNodeType(NodeType t) + throws VisitorException { /* Do nothing. */ } + + private void processStructureDeclaration(final StructureDeclaration sd) + throws VisitorException { + // visit each member's type and initializer if any + for (final Iterator i = sd.getDeclarations().getDeclarations(); + i.hasNext(); ) { + final Declaration d = (Declaration) i.next(); + for (final Iterator j = d.getDeclaratorList().getDeclarators(); + j.hasNext(); ) { + final Declarator dr = (Declarator) j.next(); + dr.getTypeFragment().accept(this); + if (dr.getInitializer() != null) { + processLvalue(dr.getInitializer()); + final Type lty = dr.getTypeFragment(); + final Type rty = getType(dr.getInitializer()); + if (!isAssignable(lty, rty)) { + report("incompatibe.structure.init", dr, + lty, rty, dr.getIdentifier() + .getIdentifier()); + } + } + } + } + } + + public void visitStringType(StringType t) throws VisitorException {} + + public void visitStructureType(StructureType t) + throws VisitorException { + final Pair p = (Pair) + results.resolver.getResolvedStructures().get(t); + if (p == null) { + t.checkParseRange(); + report("undefined.structure", t, t.getName()); + } else { + final StructureDeclaration sd = + (StructureDeclaration) p.getSecond(); + if (results.declarationWarned.add(sd)) { + processStructureDeclaration(sd); + } + } + } + + public void visitIdentifierList(IdentifierList il) { + throw new AssertionError((Object) "Can't get here"); + } + + public void visitLinkageLoopTerm(LinkageLoopTerm term) + throws VisitorException { + // Visit the min/max expression with the current scope + term.getRange().getMinExpression().accept(this); + expectInteger(term.getRange().getMinExpression()); + + term.getRange().getMaxExpression().accept(this); + expectInteger(term.getRange().getMaxExpression()); + + // Visit the linkage term being looped with an augmented + // scope which includes the index variable. + + Map/**/ loopDeclared = + new HashMap/**/(declared); + loopDeclared.put (term.getIndexVar(), new IntegerType()); + Map/**/ oldDeclared = declared; + declared = loopDeclared; + term.getTerm().accept(this); + declared = oldDeclared; + } + public void visitLinkageExpressionTerm(LinkageExpressionTerm term) + throws VisitorException { + term.getExpression().accept(this); + } + public void visitLinkageArrayAccessExpression( + LinkageArrayAccessExpression e) throws VisitorException { + e.getArrayExpression().accept(this); + e.getIndexExpression().accept(this); + } + public void visitLinkageIdentifierExpression( + LinkageIdentifierExpression e) { + } + public void visitLinkageStructureAccessExpression( + LinkageStructureAccessExpression e) { + } + + public void visitLoopGuard(LoopGuard s) throws VisitorException { + throw new AssertionError((Object) "Can't get here"); + } + + private void processUnary(final AbstractUnaryExpression e) + throws VisitorException { + e.getExpression().accept(this); + setType(e, getType(e.getExpression())); + } + + private void processBinary(final AbstractBinaryExpression e) + throws VisitorException { + e.getLeft().accept(this); + e.getRight().accept(this); + } + + private void processBitwiseBinary(final AbstractBinaryExpression e) + throws VisitorException { + processBinary(e); + final Type lty = getType(e.getLeft()); + final Type rty = getType(e.getRight()); + if (isBoolean(lty) && isBoolean(rty)) setBoolean(e); + else if (isInteger(lty) && isInteger(rty)) setInteger(e); + else { + setAny(e); + report("invalid.bitwise.operand", e, lty, rty); + } + } + + private void processArithmeticBinary(final AbstractBinaryExpression e) + throws VisitorException { + processBinary(e); + expectInteger(e.getLeft()); + expectInteger(e.getRight()); + setInteger(e); + } + + private void processArithmeticComparison( + final AbstractBinaryExpression e) throws VisitorException { + processBinary(e); + expectInteger(e.getLeft()); + expectInteger(e.getRight()); + setBoolean(e); + } + + private void processBitwiseComparison(final AbstractBinaryExpression e) + throws VisitorException { + processBinary(e); + + final Type lty = getType(e.getLeft()); + final Type rty = getType(e.getRight()); + + if (!(isInteger(lty) && isInteger(rty)) && + !(isBoolean(lty) && isBoolean(rty))) { + report("invalid.comparison", e, lty, rty); + } + + setBoolean(e); + } + + private void processLinkageTerms(final LinkageTerms terms) + throws VisitorException { + if (terms != null) + for (Iterator i = terms.getTerms(); i.hasNext(); ) { + LinkageTermInterface term = (LinkageTermInterface) i.next(); + term.accept(this); + } + } + + private void processGuards(Iterator guards) throws VisitorException { + for (final Iterator i = guards; i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + + if (gci instanceof LoopGuard) { + final LoopGuard lg = (LoopGuard) gci; + // Visit the min/max expression with the current scope + + lg.getRange().getMinExpression().accept(this); + expectInteger(lg.getRange().getMinExpression()); + + lg.getRange().getMaxExpression().accept(this); + expectInteger(lg.getRange().getMaxExpression()); + + // Visit the statement being looped with an augmented + // scope which includes the index variable. + + Map/**/ loopDeclared = + new HashMap/**/(declared); + loopDeclared.put (lg.getIndexVar(), new IntegerType()); + Map/**/ oldDeclared = declared; + declared = loopDeclared; + processGuards(lg.getGuards().iterator()); + declared = oldDeclared; + } else { + final GuardedCommand gc = (GuardedCommand) gci; + if (gc instanceof GuardedCommandWithStatement) { + final GuardedCommandWithStatement gcws = + (GuardedCommandWithStatement) gc; + gcws.getGuardStatement().accept(this); + } + gc.getGuard().accept(this); + final Type gty = getType(gc.getGuard()); + if (!isBoolean(gty)) { + report("invalid.guard", gc.getGuard(), gty); + } + gc.getCommand().accept(this); + processLinkageTerms(gc.getLinkageTerms()); + } + } + } + private void processGuardedStatement(final AbstractGuardedStatement s) + throws VisitorException { + if (s.getElseStatement() != null) + s.getElseStatement().accept(this); + processGuards(s.getGuardedCommands()); + } + private void processLvalue(final ExpressionInterface e) + throws VisitorException { + + // If the lhs is an identifier, or an identifier qualified by a + // bitfield specifier, then consider this identifier a candidate + // for addition to the UndeclaredWrite set, and any bitfield + // specifiers for additions to the UndeclaredRead set. Otherwise, + // consider the entire expression for additions to the + // UndeclaredRead set. + + // XXX: note that this will not handle the following expression + // properly: + // + // x[15:0][3:2] = 5; + // + // This could be fixed by treating each bitrange expression in + // turn. Ignore this for now, since it will probably occur + // rarely, and should produce obvious error messages if it does + // present a problem. + + if (e instanceof BitRangeExpression) { + BitRangeExpression bre = (BitRangeExpression) e; + ExpressionInterface bits = bre.getBitsExpression(); + if (bits instanceof IdentifierExpression) { + IdentifierExpression id = (IdentifierExpression) bits; + processWrite (id); + } + visitBitRangeExpression(bre); + } else if (e instanceof IdentifierExpression) { + IdentifierExpression id = (IdentifierExpression) e; + processWrite (id); + } else if (e != null) { + e.accept(this); + } + } + + private void processIdent(Map undeclared, + IdentifierExpression expr) + throws VisitorException { + final String id = expr.getIdentifier(); + Type ty; + if (!declared.containsKey(id)) { + results.addUndeclared(undeclared, id, expr.getParseRange()); + ty = results.getUndeclaredType(id); + if (ty == null) { + ty = new IntegerType(); + results.setUndeclaredType(id, ty); + } + } else { + ty = (Type) declared.get(id); + } + setType (expr, ty); + results.useIdent(expr, ty); + } + private void processWrite(IdentifierExpression expr) + throws VisitorException { + processIdent(results.getUndeclaredWrites(), expr); + } + private void processRead(IdentifierExpression expr) + throws VisitorException { + processIdent(results.getUndeclaredReads(), expr); + } + + private void setVoid(ExpressionInterface e) { + setType(e, VOID); + } + private void setAny(ExpressionInterface e) { + setType(e, ANY); + } + private void setInteger(ExpressionInterface e) { + setType(e, new IntegerType()); + } + private void setBoolean(ExpressionInterface e) { + setType(e, new BooleanType()); + } + private void setString(ExpressionInterface e) { + setType(e, new StringType()); + } + private void setType(ExpressionInterface e, Type t) { + assert e != null && t != null; + + // If t already has a parse range (for example, if it is the + // type of a member in a structure), it makes no sense to + // extend it. + if (t.getParseRange() == ParseRange.EMPTY) t.epr(e); + t.checkParseRange(); + results.setType(e, t); + } + private Type getType(ExpressionInterface e) { + return results.getType(e); + } + private void sameType(ExpressionInterface e, + ExpressionInterface f) + throws VisitorException { + setType(e, getType(f)); + setType(f, getType(e)); + } + private void expectInteger(ExpressionInterface e) + throws VisitorException { + final Type ty = getType(e); + if (!isInteger(ty)) report("int.expected", e, ty); + } + private void expectChannel(ExpressionInterface e, + PortDirection dir) + throws VisitorException { + final Type t = getType(e); + if (t instanceof ChannelType) { + if (dir != null) { + final ChannelType ct = (ChannelType) t; + if (ct.getDirection() != dir) { + report("channel.wrong.direction", e, ct.getDirection(), + dir); + } + } + } else { + report("channel.expected", e, t); + } + } + // Because there could be multiple structures with the same name, for + // any StructureType, add additional information on the declaration + // location, if available + private Object clarify(Object o) { + if (o instanceof StructureType) { + final StructureDeclaration decl = + getStructureDecl(null, (StructureType) o); + o = o.toString() + " (" + + (decl == null ? "undeclared" + : decl.getParseRange().fullString()) + + ")"; + } + return o; + } + private void report(final String s, final AbstractASTNodeInterface a) { + report(s, a, null); + } + private void report(final String s, final AbstractASTNodeInterface a, + final Object o1) { + report(s, a, o1, null); + } + private void report(final String s, final AbstractASTNodeInterface a, + final Object o1, final Object o2) { + report(s, a, o1, o2, null); + } + private void report(final String s, final AbstractASTNodeInterface a, + final Object o1, final Object o2, final Object o3) { + results.errors.add(new TypeError("type.checker." + s, + a.getParseRange(), + new Object[] { clarify(o1), + clarify(o2), + clarify(o3) })); + } + + private Interval getInterval(final Type ty) { + final Interval result; + if (ty instanceof IntegerType) { + final IntegerType ity = (IntegerType) ty; + result = ity.getInterval() == null ? LARGE_INTERVAL + : ity.getInterval(); + } else if (ty instanceof NodeType) { + final NodeType nty = (NodeType) ty; + result = new Interval(nty.getWidth()); + } else if (ty instanceof ChannelType) { + final ChannelType cty = (ChannelType) ty; + final BigInteger biggest = + cty.getNumValues().subtract(BigInteger.ONE); + if (biggest.signum() == -1) { + result = LARGE_INTERVAL; + } else { + result = new Interval(BigInteger.ZERO, biggest); + } + } else { + result = LARGE_INTERVAL; + } + return result; + } + + private Interval getInterval(final ExpressionInterface ei) { + final Interval result = getInterval(getType(ei)); + return result; + } + + private void setInterval(Interval interval, final Type ty) { + // Saturate to LARGE_INTERVAL so that intervals that became too big + // due to operations on infinite integers don't propagate + if (interval == Interval.EXCEPTION) { + interval = LARGE_INTERVAL; + } else if (interval != null) { + interval = new Interval( + LARGE_LOWER_BOUND.max(interval.getLeftBound()), + LARGE_UPPER_BOUND.min(interval.getRightBound())); + } + + if (ty instanceof IntegerType) { + final IntegerType ity = (IntegerType) ty; + ity.setInterval(interval); + } + } + + private void setInterval(final Interval interval, + final ExpressionInterface ei) { + setInterval(interval, getType(ei)); + } + + /** Assert that two types are compatible. **/ + private void assertCompatible(Type s, Type t) + throws VariableAnalyzerVisitorException { + if(!isCompatible(s,t)) { + s.checkParseRange(); + t.checkParseRange(); + final ParseRange spr = s.getParseRange(); + final ParseRange tpr = t.getParseRange(); + throw new VariableAnalyzerVisitorException(spr.fullString() + ", " + + (spr.start.filename == tpr.start.filename ? tpr.toString() + : tpr.fullString()) + + ": CSP type error: expected "+ s + ", found " + t, t); + } + } + + private boolean sameType(StructureType s, StructureType t) { + final StructureDeclaration sd = getStructureDecl(null, s); + final StructureDeclaration td = getStructureDecl(null, t); + if (sd != null && td != null) { + return sd.getParseRange().equals(td.getParseRange()); + } else { + return sd == td; + } + } + + /** Return a value indicating whether two types are compatible + * (called by assertCompatible) **/ + private boolean isCompatible(Type s, Type t) { + if (t != null && s != null) { + if ((t instanceof BooleanType && !isBoolean(s)) + || (t instanceof IntegerType && !isInteger(s)) + || (t instanceof StructureType && !(s instanceof StructureType)) + || (t instanceof ArrayType && !(s instanceof ArrayType))) + return false; + if (t instanceof ArrayType && s instanceof ArrayType) + return isCompatible(((ArrayType) s).getElementType(), + ((ArrayType) t).getElementType()); + if (t instanceof StructureType && s instanceof StructureType) { + return sameType((StructureType) t, (StructureType) s); + } + + } + return true; + } + + /** + * Return true if rhs is a type that can be + * assigned to lhs, and false otherwise. + **/ + private boolean isAssignable(Type lhs, Type rhs) { + if ((isBoolean(lhs) && isBoolean(rhs)) || + (isInteger(lhs) && isInteger(rhs)) || + (isString(lhs) && isString(rhs)) || + (lhs == ANY) || + (rhs == ANY)) { + return true; + } + if (lhs instanceof StructureType && rhs instanceof StructureType) { + return sameType((StructureType) lhs, (StructureType) rhs); + } + if (lhs instanceof ArrayType && rhs instanceof ArrayType) { + return isAssignable(((ArrayType) lhs).getElementType(), + ((ArrayType) rhs).getElementType()); + } + return false; + } + } + + private static final class VariableAnalyzerVisitorException + extends VisitorExceptionWithLocation { + private VariableAnalyzerVisitorException(String s, + AbstractASTNodeInterface a) { + super(s, a); + } + } + + private static String getWidthString(final Type ty) { + final IntegerType it = (IntegerType) ty; + final BigInteger w = CspUtils.getIntegerConstant(it.getDeclaredWidth()); + return w == null ? "int" : ("int(" + w + ")"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorByCategory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorByCategory.java new file mode 100644 index 0000000000..ec9b70baf0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorByCategory.java @@ -0,0 +1,432 @@ +package com.avlsi.csp.util; + +import java.util.Iterator; +import java.util.Map; + +import com.avlsi.csp.ast.*; + +public class VisitorByCategory implements VisitorInterface { + protected VisitorInterface getVisitor() { + return this; + } + + protected void + processDeclarator(Declarator d) throws VisitorException { + d.getIdentifier().accept(getVisitor()); + final Type t = d.getTypeFragment(); + if (t != null) t.accept(getVisitor()); + final ExpressionInterface init = d.getInitializer(); + if (init != null) init.accept(getVisitor()); + } + + protected void + processDeclarationList(DeclarationList l) throws VisitorException { + for (Iterator i = l.getDeclarations(); i.hasNext(); ) { + final Declaration decl = (Declaration) i.next(); + final DeclaratorList dclr = decl.getDeclaratorList(); + for (Iterator j = dclr.getDeclarators(); j.hasNext(); ) { + final Declarator d = (Declarator) j.next(); + processDeclarator(d); + } + } + } + protected void + processFunctionDeclaration(FunctionDeclaration decl) + throws VisitorException { + processDeclarationList(decl.getFormals()); + final Type rtype = decl.getReturnType(); + if (rtype != null) rtype.accept(getVisitor()); + decl.getBodyStatement().accept(getVisitor()); + } + protected void + processStructureDeclaration(StructureDeclaration decl) + throws VisitorException { + processDeclarationList(decl.getDeclarations()); + } + protected void + processRefinementParent(CSPProgram p) throws VisitorException { } + public void visitCSPProgram(CSPProgram p) throws VisitorException + { + for (Iterator i = p.getRefinementParents().iterator(); i.hasNext(); ) { + processRefinementParent((CSPProgram) i.next()); + } + for (Iterator i = p.getFunctionDeclarations(); i.hasNext(); ) { + processFunctionDeclaration((FunctionDeclaration) i.next()); + } + for (Iterator i = p.getStructureIterator(); i.hasNext(); ) { + processStructureDeclaration((StructureDeclaration) i.next()); + } + p.getInitializerStatement().accept(getVisitor()); + p.getStatement().accept(getVisitor()); + } + + /* AbstractBinaryExpression */ + protected void + processAbstractBinaryExpression(final AbstractBinaryExpression e) + throws VisitorException { + e.getLeft().accept(getVisitor()); + e.getRight().accept(getVisitor()); + } + protected void + processArithmeticBinaryExpression(final AbstractBinaryExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitAddExpression(AddExpression e) throws VisitorException { + processArithmeticBinaryExpression(e); + } + public void visitAndExpression(AndExpression e) throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitConditionalAndExpression(ConditionalAndExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitConditionalOrExpression(ConditionalOrExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitDivideExpression(DivideExpression e) + throws VisitorException { + processArithmeticBinaryExpression(e); + } + public void visitEqualityExpression(EqualityExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitExponentialExpression(ExponentialExpression e) + throws VisitorException { + processArithmeticBinaryExpression(e); + } + public void visitGreaterEqualExpression(GreaterEqualExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitGreaterThanExpression(GreaterThanExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitInequalityExpression(InequalityExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitLeftShiftExpression(LeftShiftExpression e) + throws VisitorException { + processArithmeticBinaryExpression(e); + } + public void visitLessEqualExpression(LessEqualExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitLessThanExpression(LessThanExpression e) + throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitMultiplyExpression(MultiplyExpression e) + throws VisitorException { + processArithmeticBinaryExpression(e); + } + public void visitOrExpression(OrExpression e) throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitXorExpression(XorExpression e) throws VisitorException { + processAbstractBinaryExpression(e); + } + public void visitRemainderExpression(RemainderExpression e) + throws VisitorException { + processArithmeticBinaryExpression(e); + } + public void visitRightShiftExpression(RightShiftExpression e) + throws VisitorException { + processArithmeticBinaryExpression(e); + } + public void visitSubtractExpression(SubtractExpression e) + throws VisitorException { + processArithmeticBinaryExpression(e); + } + + /* AbstractChannelExpression */ + protected void + processAbstractChannelExpression(final AbstractChannelExpression e) + throws VisitorException { + e.getChannelExpression().accept(getVisitor()); + } + public void visitPeekExpression(PeekExpression e) throws VisitorException { + processAbstractChannelExpression(e); + } + public void visitProbeExpression(ProbeExpression e) + throws VisitorException { + processAbstractChannelExpression(e); + } + public void visitReceiveExpression(ReceiveExpression e) + throws VisitorException { + processAbstractChannelExpression(e); + } + + /* AbstractChannelStatement */ + protected void + processAbstractChannelStatement(final AbstractChannelStatement s) + throws VisitorException { + s.getChannelExpression().accept(getVisitor()); + final ExpressionInterface rhs = s.getRightHandSide(); + if (rhs != null) rhs.accept(getVisitor()); + } + public void visitReceiveStatement(ReceiveStatement s) + throws VisitorException { + processAbstractChannelStatement(s); + } + public void visitSendStatement(SendStatement s) throws VisitorException { + processAbstractChannelStatement(s); + } + + /* AbstractCompositeStatement */ + protected void + processAbstractCompositeStatement(final AbstractCompositeStatement s) + throws VisitorException { + for (Iterator i = s.getStatements(); i.hasNext(); ) { + ((StatementInterface) i.next()).accept(getVisitor()); + } + } + public void visitParallelStatement(ParallelStatement s) + throws VisitorException { + processAbstractCompositeStatement(s); + } + public void visitSequentialStatement(SequentialStatement s) + throws VisitorException { + processAbstractCompositeStatement(s); + } + + /* AbstractUnaryExpression */ + protected void + processAbstractUnaryExpression(final AbstractUnaryExpression e) + throws VisitorException { + e.getExpression().accept(getVisitor()); + } + public void visitNegateExpression(NegateExpression e) + throws VisitorException { + processAbstractUnaryExpression(e); + } + public void visitNotExpression(NotExpression e) throws VisitorException { + processAbstractUnaryExpression(e); + } + + /* Type */ + protected void processType(final Type t) throws VisitorException { } + public void visitArrayType(ArrayType t) throws VisitorException { + processType(t); + } + public void visitBooleanType(BooleanType t) throws VisitorException { + processType(t); + } + public void visitChannelType(ChannelType t) throws VisitorException { + processType(t); + } + public void visitChannelStructureType(ChannelStructureType t) + throws VisitorException { + processType(t); + } + public void visitIntegerType(IntegerType t) throws VisitorException { + processType(t); + } + public void visitNodeType(NodeType t) throws VisitorException { + processType(t); + } + public void visitStringType(StringType t) throws VisitorException {} + public void visitStructureType(StructureType t) throws VisitorException { + processType(t); + } + + /* Primary expressions */ + protected void processPrimaryExpression(ExpressionInterface e) + throws VisitorException { } + public void visitArrayAccessExpression(ArrayAccessExpression e) + throws VisitorException { + e.getArrayExpression().accept(getVisitor()); + e.getIndexExpression().accept(getVisitor()); + } + public void visitBitRangeExpression(BitRangeExpression e) + throws VisitorException { + e.getBitsExpression().accept(getVisitor()); + if (e.getMinExpression() != null) + e.getMinExpression().accept(getVisitor()); + e.getMaxExpression().accept(getVisitor()); + } + public void visitFunctionCallExpression(FunctionCallExpression e) + throws VisitorException { + e.getFunctionExpression().accept(getVisitor()); + for (Iterator i = e.getActuals(); i.hasNext(); ) { + ((ExpressionInterface) i.next()).accept(getVisitor()); + } + } + public void visitIdentifierExpression(IdentifierExpression e) + throws VisitorException { + processPrimaryExpression(e); + } + public void visitIntegerExpression(IntegerExpression e) + throws VisitorException { + processPrimaryExpression(e); + } + public void visitMemberAccessExpression(MemberAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(getVisitor()); + } + public void visitStringExpression(StringExpression e) + throws VisitorException { + processPrimaryExpression(e); + } + public void visitStructureAccessExpression(StructureAccessExpression e) + throws VisitorException { + e.getStructureExpression().accept(getVisitor()); + } + + /* Loop */ + protected void processAbstractLoop(final AbstractLoop l) + throws VisitorException { + processRange(l.getRange()); + } + public void visitLinkageLoopTerm(LinkageLoopTerm term) + throws VisitorException { + processAbstractLoop(term); + term.getTerm().accept(getVisitor()); + } + public void visitLoopExpression(LoopExpression e) throws VisitorException { + processAbstractLoop(e); + e.getExpression().accept(getVisitor()); + } + public void visitLoopStatement(LoopStatement s) throws VisitorException { + processAbstractLoop(s); + s.getStatement().accept(getVisitor()); + } + + protected void processGuardedCommandInterface(GuardedCommandInterface gci) + throws VisitorException { + } + public void visitLoopGuard(LoopGuard s) throws VisitorException { + processAbstractLoop(s); + for (Iterator i = s.getGuards().iterator(); i.hasNext(); ) { + processGuardedCommandInterface((GuardedCommandInterface) i.next()); + } + } + + /* Assignment and variable declaration statements */ + public void visitAssignmentStatement(AssignmentStatement s) + throws VisitorException { + s.getLeftHandSide().accept(getVisitor()); + s.getRightHandSide().accept(getVisitor()); + } + public void visitIncDecStatement(IncDecStatement s) + throws VisitorException { + s.getExpression().accept(getVisitor()); + } + public void visitExpressionStatement(ExpressionStatement s) + throws VisitorException { + s.getExpression().accept(getVisitor()); + } + public void visitVarStatement(VarStatement s) throws VisitorException { + processDeclarationList(s.getDeclarationList()); + final StatementInterface stmt = s.getStatement(); + if (stmt != null) stmt.accept(getVisitor()); + } + + /* Abstract guarded statement */ + protected void + processAbstractGuardedStatement(AbstractGuardedStatement s) + throws VisitorException { + for (Iterator i = s.getGuardedCommands(); i.hasNext(); ) { + final GuardedCommandInterface gci = + (GuardedCommandInterface) i.next(); + processGuardedCommandInterface(gci); + } + final StatementInterface els = s.getElseStatement(); + if (els != null) els.accept(getVisitor()); + } + + /* Abstract reptition statement */ + protected void + processAbstractRepetitionStatement(AbstractRepetitionStatement s) + throws VisitorException { + processAbstractGuardedStatement(s); + } + /* Deterministic repetition and selection */ + public void + visitDeterministicRepetitionStatement + (DeterministicRepetitionStatement s) throws VisitorException + { + processAbstractRepetitionStatement(s); + } + public void + visitNonDeterministicRepetitionStatement + (NonDeterministicRepetitionStatement s) throws VisitorException + { + processAbstractRepetitionStatement(s); + final LinkageTerms terms = s.getNeutralState(); + if (terms != null) processLinkageTerms(terms); + } + + /* Abstract selection statement */ + protected void + processAbstractSelectionStatement(AbstractSelectionStatement s) + throws VisitorException { + processAbstractGuardedStatement(s); + } + public void + visitDeterministicSelectionStatement + (DeterministicSelectionStatement s) throws VisitorException + { + processAbstractSelectionStatement(s); + } + public void + visitNonDeterministicSelectionStatement + (NonDeterministicSelectionStatement s) throws VisitorException + { + processAbstractSelectionStatement(s); + final LinkageTerms terms = s.getNeutralState(); + if (terms != null) processLinkageTerms(terms); + } + + /* Trivial statements */ + public void visitErrorStatement(ErrorStatement s) throws VisitorException { + } + public void visitSkipStatement(SkipStatement s) throws VisitorException { + } + + /* LinkageExpressionInterface */ + protected void + processLinkageExpressionInterface(LinkageExpressionInterface e) + throws VisitorException { } + public void + visitLinkageArrayAccessExpression(LinkageArrayAccessExpression e) + throws VisitorException { + processLinkageExpressionInterface(e); + } + public void visitLinkageExpressionTerm(LinkageExpressionTerm term) + throws VisitorException { + term.getExpression().accept(getVisitor()); + } + public void visitLinkageIdentifierExpression(LinkageIdentifierExpression e) + throws VisitorException { + processLinkageExpressionInterface(e); + } + public void + visitLinkageStructureAccessExpression(LinkageStructureAccessExpression e) + throws VisitorException { + processLinkageExpressionInterface(e); + } + + /* Range */ + protected void processRange(final Range r) throws VisitorException { + r.getMinExpression().accept(getVisitor()); + r.getMaxExpression().accept(getVisitor()); + } + + protected void processLinkageTerms(final LinkageTerms terms) + throws VisitorException { + for (Iterator i = terms.getTerms(); i.hasNext(); ) { + ((LinkageTermInterface) i.next()).accept(getVisitor()); + } + } + + /* Currently unused */ + public void visitIdentifierList(IdentifierList il) throws VisitorException { + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorExceptionWithLocation.java b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorExceptionWithLocation.java new file mode 100644 index 0000000000..5037249cf9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/csp/util/VisitorExceptionWithLocation.java @@ -0,0 +1,47 @@ +/* + * Copyright 2006 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.csp.util; + +import com.avlsi.csp.ast.AbstractASTNodeInterface; +import com.avlsi.csp.ast.VisitorException; +import com.avlsi.csp.grammar.ParsePosition; +import com.avlsi.csp.grammar.ParseRange; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import java.io.PrintStream; + +public class VisitorExceptionWithLocation extends VisitorException { + private final ParseRange pr; + + public VisitorExceptionWithLocation(final String message, ParseRange pr) { + super(message); + this.pr = pr; + } + + public VisitorExceptionWithLocation(final String message, + AbstractASTNodeInterface node) { + this(message, node.getParseRange()); + } + + public ParseRange getParseRange() { + return pr; + } + + public void printSelf(PrintStream out) { + ExceptionPrettyPrinter.prettyMessage(super.getMessage().trim(), + pr.start.filename, + pr.start.line, pr.start.column+1, + out); + } + + public String getMessage() { + String msg = super.getMessage(); + if (msg.endsWith("\n")) { + return pr.fullString() + ":\n" + msg; + } else { + return msg + " at " + pr.fullString(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/AnonymousInstanceException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/AnonymousInstanceException.java new file mode 100644 index 0000000000..478b185682 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/AnonymousInstanceException.java @@ -0,0 +1,16 @@ +package com.avlsi.fast; + +import java.util.Collection; + +public class AnonymousInstanceException extends RuntimeException { + /** + * A collection of names of cell types that contain anonymous instances. + **/ + private Collection cells; + public AnonymousInstanceException(final Collection cells) { + this.cells = cells; + } + public Collection getCells() { + return cells; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/AssertBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/AssertBlock.java new file mode 100644 index 0000000000..1f30fe8c9b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/AssertBlock.java @@ -0,0 +1,78 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.util.debug.Debug; + +/** + * Represents all the data stored in the assert block of castv2. Note + * that to get _all_ the production rules of a cell you need to query + * this block as well as the prs block. This only stores the + * simulator-only production rules; the prs block only stores the + * general-purpose production rules. + **/ + +public class AssertBlock extends BlockCommon { + /** + * The production rules created by the prs assertions. All of + * them should be "environmental" (simulator only). + **/ + private final ProductionRuleSet productionRuleSet; + + private final ExclusiveNodeSets exclNodeSets; + + public AssertBlock() { + this.productionRuleSet = new ProductionRuleSet(); + this.exclNodeSets = new ExclusiveNodeSets(); + } + + public String getType() { + return BlockInterface.ASSERT; + } + + /** + * Absorbs the production rules and exclusive node sets from its + * refinement parent into itself. + **/ + public void refineFrom(final BlockInterface o) { + super.refineFrom(o); + + final AssertBlock parent = (AssertBlock) o; + productionRuleSet.refineFrom(parent.productionRuleSet); + exclNodeSets.refineFrom(parent.exclNodeSets); + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "AssertBlock doesn't support all BlockInterface functionality"); + return null; + } + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "AssertBlock doesn't support all BlockInterface functionality"); + return null; + } + + public ProductionRuleSet getProductionRuleSet() { + return productionRuleSet; + } + + public ExclusiveNodeSets getExclusiveNodeSets() { + return exclNodeSets; + } + + public String toString() { + return "AssertBlock(" + productionRuleSet + exclNodeSets + ")"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockCommon.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockCommon.java new file mode 100644 index 0000000000..ee5c20c959 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockCommon.java @@ -0,0 +1,127 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +abstract class BlockCommon implements BlockInterface { + // Map from String to List of blocks + protected Map blockMap = new HashMap(); + + public abstract String getType(); + public abstract BlockInterface merge(BlockInterface o); + public abstract BlockInterface replace(BlockInterface o); + + /** + * Replaces this' blockMap with o's. + **/ + public void copyInternals(final BlockInterface o) { + final BlockCommon parent = (BlockCommon) o; + this.blockMap = parent.blockMap; + } + + /** + * Compares the blockMaps. Inherits all of the subblocks which + * have no equivalent in this block; refines the others. + **/ + public void refineFrom(final BlockInterface o) { + final BlockCommon parent = (BlockCommon) o; + for (final Iterator i = parent.blockMap.entrySet().iterator(); + i.hasNext(); + ) { + final Map.Entry parentBlock = (Map.Entry) i.next(); + final List blockList = (List) blockMap.get(parentBlock.getKey()); + if (blockList != null && !blockList.isEmpty()) { + final BlockInterface block = (BlockInterface) blockList.get(0); + if (block != null) { + final List parentList = (List) parentBlock.getValue(); + if (!parentList.isEmpty()) { + block.refineFrom((BlockInterface) parentList.get(0)); + } + continue; + } + } + + // Block from parent doesn't exist in this BlockCommon. + final BlockIterator bi = iterator((String) parentBlock.getKey()); + final List parentList = (List) parentBlock.getValue(); + for (final Iterator j = parentList.iterator(); j.hasNext(); ) { + final BlockInterface block = (BlockInterface) j.next(); + if (block instanceof Cloneable) { + try { + bi.add((BlockInterface) block.clone()); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); + } + } else { + bi.add(block); + } + } + } + } + + public BlockIterator iterator(String type) { + List list = (List) blockMap.get(type); + if (list == null) { + list = new ArrayList(); + blockMap.put(type, list); + } + final ListIterator iterator = list.listIterator(); + return new BlockIterator() { + public void add(BlockInterface block) { + iterator.add(block); + } + public boolean hasNext() { + return iterator.hasNext(); + } + public boolean hasPrevious() { + return iterator.hasPrevious(); + } + /** @throws NoSuchElementException */ + public BlockInterface next() { + return (BlockInterface) iterator.next(); + } + /** @throws NoSuchElementException */ + public BlockInterface previous() { + return (BlockInterface) iterator.previous(); + } + public void remove() { + iterator.remove(); + } + public void set(BlockInterface block) { + iterator.set(block); + } + public void merge(BlockInterface block) { + if (hasNext()) { + BlockInterface merge = next(); + set(merge.merge(block)); + } else { + add(block); + } + } + }; + } + + public String toString() { + return blockMap.toString(); + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockInterface.java new file mode 100644 index 0000000000..c8978ac8cb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockInterface.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import com.avlsi.fast.BlockIterator; + +/** + * Interface representing f/cast bodies. + * Example of f/cast bodies are: prs block, decomposition + * block, csp block, etc. + * + * These classes should be immutable, unless you really, *really* know + * what you are doing. refineFrom() modifies them, but should only be + * called during creation of a CellImpl (specifically, during the + * function setRefinementParent()). Specifically, refineFrom() should + * only be called before the cell is used for anything, even as a + * refinement parent of another cell. + * + * @author Aaron Denney + * @version $Date$ + **/ + +public interface BlockInterface { + String ENV = "env"; + String DIRECTIVE = "directive"; + String CELL = "cell"; + String PRS = "prs"; + String NETLIST = "netlist"; + String ASSERT = "assert"; + String SUBCELL = "subcell"; + String VERILOG = "verilog"; + String CSP = "csp"; + String JAVA = "java"; + + /** + * Returns the type of this block. + **/ + String getType(); + + /** + * Returns a new block that is the merging of this block and the specified + * block. The semantics of a merge operation is block specific. + **/ + BlockInterface merge(BlockInterface o); + + /** + * Returns a new block that is the replacement of the specified block over + * this block. The semantics of a replace operation is block specific. + **/ + BlockInterface replace(BlockInterface o); + + /** + * Takes the given block as the refinement parent of this block, + * and modifies this block accordingly. Changes this + * block. See class notes for restrictions on use. + **/ + void refineFrom(BlockInterface parent); + + /** + * Returns a BlockIterator of all attached blocks of a specific type. + **/ + BlockIterator iterator(String type); + + /** + * Returns a clone of this block. + **/ + Object clone() throws CloneNotSupportedException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockIterator.java new file mode 100644 index 0000000000..76db04c700 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/BlockIterator.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.NoSuchElementException; + +/** + * Interface representing an iterator over BlockInterface. + **/ + +public interface BlockIterator { + void add(BlockInterface block); + boolean hasNext(); + boolean hasPrevious(); + + /** + * @throws NoSuchElementException + **/ + BlockInterface next(); + + /** + * @throws NoSuchElementException + **/ + BlockInterface previous(); + + void remove(); + void set(BlockInterface block); + void merge(BlockInterface block); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CastDesign.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CastDesign.java new file mode 100644 index 0000000000..a93e00f410 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CastDesign.java @@ -0,0 +1,1478 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; + +import com.avlsi.tools.jauto.TransistorSizingTool; +import com.avlsi.tools.jauto.NetSource; +import com.avlsi.tools.jauto.NetSink; +import com.avlsi.tools.jauto.NetType; +import com.avlsi.tools.jauto.DebugOption; +import com.avlsi.tools.jauto.TechnologyData; +import com.avlsi.tools.jauto.JautoMessageCenter; + +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.cdl.CDLFileFormatException; +import com.avlsi.file.cdl.parser.AspiceCellAdapter; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.io.SearchPath; +import com.avlsi.io.SearchPathFile; + +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.dsim.InstanceData; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.text.StringUtil; + +/** + * Class to represent a cast design. + * + * @author Aaron Denney + * @version $Date$ + **/ + +public final class CastDesign { + private final Map/**/ allCells = new TreeMap/**/(); + + /** flags for each cell. Has estimated positions and sizes. **/ + public static final int FLOORPLAN = 1; + /** flags for each cell. Has transistors. **/ + public static final int TRANSISTORS = 2; + /** flags for each cell. Has transistors, and their size has been specified. **/ + public static final int TRANSISTORS_SIZED = 4; + /** flags for each cell. Has transistors in place. Routed? **/ + public static final int TRANSISTORS_PLACED_SIZED = 8; + + /** set of all celltypes in the design **/ + public Set/**/ allCellTypes = + new TreeSet/**/(CellType.getNameComparator()); + + final TechnologyData techData; + + public JautoMessageCenter messageCenter; + + /** Names for Vdd, GND, and _RESET */ + private final HierName Vdd, GND, _RESET; + + /** Cadencize to use */ + private final Cadencize cad; + + /** + * Cast parser to store for later use by + * GlobalNet.getDelayFunction. + **/ + private final CastFileParser castFileParser; + + private final float tau; + + /** + * A special delaybias that applies only to fixed size cells. + **/ + private final float fixedDelayBias; + + /** + * A special delaybias that applies only to sizable cells. + **/ + private final float sizableDelayBias; + + private final boolean keepCsp; + + /** + * A collection of cell types that contains anonymous instances that aren't + * wiring cells. + **/ + private final Set anonymousInstances = new TreeSet(); + + /** + * A collection of cell types that have been synthesized as part of the + * sizing environment. + **/ + private final Set synthCells; + + /** + * The real top level cell to be sized, if an external sizing environment + * was synthesized. + **/ + private final CellInterface realTop; + + /** + * Whether to use Steiner trees for wirelength and wirespan estimation. + **/ + private final boolean useSteinerTree; + + //Constructs a cast design from a cell interface. + public CastDesign(final CellInterface theCell, final HierName Vdd, + final HierName GND, final HierName _RESET, + final float tau, final TechnologyData techData, + final CastFileParser cfp) { + this(theCell, Vdd, GND, _RESET, tau, techData, new Cadencize(true), + cfp, 1, Collections.emptySet(), new HashSet(), false, + false); + } + + private static CellInterface createFakeEnv(final CellInterface cell) { + final CellImpl fakeEnv = new CellImpl( "" ); + final HierName fakeInstName = HierName.makeHierName( "top" ); + fakeEnv.addSubcellPair( fakeInstName, cell, false ); + return fakeEnv; + } + + public CastDesign(final CellInterface theCell, final HierName Vdd, + final HierName GND, final HierName _RESET, + final float tau, final TechnologyData techData, + final Cadencize cad, final CastFileParser cfp, + final boolean useAstaExtraDelay) { + this(theCell, Vdd, GND, _RESET, tau, techData, cad, cfp, 1, + Collections.emptySet(), new HashSet(), false, + useAstaExtraDelay); + } + + public CastDesign(final CellInterface theCell, final HierName Vdd, + final HierName GND, final HierName _RESET, + final float tau, final TechnologyData techData, + final Cadencize cad, final CastFileParser cfp, + final float fixedDelayBias, + final Set synthCells, + final Set skipCells, + final boolean keepCsp, + final boolean useAstaExtraDelay) { + this(Vdd, GND, _RESET, tau, techData, cad, cfp, createFakeEnv(theCell), + null, fixedDelayBias, 1, synthCells, skipCells, keepCsp, + useAstaExtraDelay, false); + } + + public CastDesign(final CellInterface theCell, final HierName Vdd, + final HierName GND, final HierName _RESET, + final float tau, final TechnologyData techData, + final Cadencize cad, final CastFileParser cfp, + final float fixedDelayBias, + final float sizableDelayBias, + final Set synthCells, + final Set skipCells, + final boolean keepCsp, + final boolean useAstaExtraDelay) { + this(Vdd, GND, _RESET, tau, techData, cad, cfp, createFakeEnv(theCell), + null, fixedDelayBias, sizableDelayBias, synthCells, skipCells, + keepCsp, useAstaExtraDelay, false); + } + + public CastDesign(final HierName Vdd, final HierName GND, + final HierName _RESET, final float tau, + final TechnologyData techData, final Cadencize cad, + final CastFileParser cfp, final CellInterface top, + final CellInterface realTop, + final float fixedDelayBias, + final float sizableDelayBias, + final Set synthCells, + final Set skipCells, + final boolean keepCsp, + final boolean useAstaExtraDelay, + final boolean useSteinerTree){ + this.Vdd = Vdd; + this.GND = GND; + this._RESET = _RESET; + this.tau = tau; + this.techData = techData; + this.cad = cad; + this.castFileParser = cfp; + this.fixedDelayBias = fixedDelayBias; + this.sizableDelayBias = sizableDelayBias; + this.keepCsp = keepCsp; + this.synthCells = synthCells; + this.realTop = realTop; + this.useSteinerTree = useSteinerTree; + convertSubcellsFromCast(cad, top, skipCells, useAstaExtraDelay); + } + + /** + * Find the minimum delaybias for each cell type. The minimum delaybias + * gives the most conservative delay budget. + **/ + private void updateDelayBias(final CellInterface cell, + final InstanceData instData, + final Map result) { + if (cell.isNode()) return; + + final String type = cell.getFullyQualifiedType(); + final float curr = instData.getDelayBias(null); + final Float bias = (Float) result.get(type); + if (bias == null) result.put(type, new Float(curr)); + else if (curr < bias.floatValue()) result.put(type, new Float(curr)); + else return; + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName inst = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + updateDelayBias(subcell, + instData.translate(cell, subcell, inst, cad), + result); + } + } + + public final JautoMessageCenter setMessageCenter(JautoMessageCenter mc) + { + messageCenter = mc; + + return messageCenter; + } + + public final JautoMessageCenter getMessageCenter() + { + return messageCenter; + } + + public CellType getCell(String name) { + return (CellType)allCells.get(name); + } + + public CellType getTopLevelCell() { + return getCell(""); + } + + public CellType getRealTopCell() { + return realTop == null ? null + : getCell(realTop.getFullyQualifiedType()); + } + + + public TechnologyData getTechnologyData(){ + return techData; + } + + public /*@ non_null @*/ Cadencize getCadencize() { + return cad; + } + + public CastFileParser getCastFileParser() { + return castFileParser; + } + + public /*@ non_null @*/ CellInterface getCellForGate( + final NetGraph.GateInstance gate) { + try { + return castFileParser.getFullyQualifiedCell(gate.getType()); + } catch (CastSemanticException e) { + // We can't get an exception here because the file has + // already been parsed, and has been cached, so it can't + // have any errors. + throw new AssertionError(e); + } + } + + // FIXME: Should this be moved to the CellType constructor? + /** + * Converts cells from CellInterface to CellType, storing + * result in allCells. + **/ + private void convertSubcellsFromCast(final Cadencize c, + final CellInterface start, + final Set skipCells, + final boolean useAstaExtraDelay) { + if (start.isNode()) { + return; + } + // if (!start.hasRealProductionRule()) { + // return; + // } + String type = start.getFullyQualifiedType(); + if (allCells.containsKey(type)) { + return; + } + + CadenceInfo ci = c.convert(start); + + if (type.equals("$env")) { type = ""; }; + + final boolean isInternalEnv = synthCells.contains(type); + if (!isInternalEnv && !type.equals("")) { + for (Iterator i = start.getAllSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName n = (HierName) p.getFirst(); + final CellInterface sc = (CellInterface) p.getSecond(); + if (n.isAnonymous() && !CellUtils.isWiring(sc)) { + anonymousInstances.add(start.getFullyQualifiedType()); + break; + } + } + } + + for (Iterator i = start.getSubcellPairs(); i.hasNext(); ) { + Pair p = (Pair) i.next(); + HierName n = (HierName) p.getFirst(); + CellInterface sc = (CellInterface) p.getSecond(); + convertSubcellsFromCast(c, sc, skipCells, useAstaExtraDelay); + // FIXME: Preserve connectivity, create subcell connections, etc. + } + + CellType ct = + new CellType(this, c, start, Vdd, GND, _RESET, isInternalEnv, + useAstaExtraDelay); + allCells.put(type, ct); + for (Iterator i = start.getSubcellPairs(); i.hasNext(); ) { + Pair p = (Pair) i.next(); + HierName n = (HierName) p.getFirst(); + CellInterface sc = (CellInterface) p.getSecond(); + final boolean hasCsp = keepCsp && sc.hasRunnableCsp(); + if (sc.isNode() || skipCells.contains(sc.getFullyQualifiedType())) { + continue; + } + CellType sct = this.getCell(sc.getFullyQualifiedType()); + + // if a wiring cell has no directives, then it cannot affect the + // sizing process at all, so discard it here + if (sct.isWiringCell && + DirectiveUtils.getDirectiveBlock(sc.getBlockInterface()) + == null && + !hasCsp) { + continue; + } + + ConnectionInfo conn = new ConnectionInfo(ct, sct, n, c); + if (!sct.isWiringCell || hasCsp) { + ct.subcellconnections.put(n, conn); + sct.parentcellconnections.add(conn); + } + for (ConnectionInfo.NameIterator j = conn.parentIterator(); j.hasNext(); ) { + HierName s = j.next(); + ct.subcellports.put(s, conn); + ct.getNet(s).changeToSubcellconnection(s, sct.isWiringCell); + } + } + + } + + public Collection getAnonymousInstances() { + return Collections.unmodifiableSet(anonymousInstances); + } + + /** + * Instance and connect the global nets, assuming c is a top-level cell. + **/ + public void addGlobalNets(CellType c) { + // FIXME: + } + + public static NetGraph getGateNetGraph(CastFileParser cfp, + String cellName, HierName Vdd, HierName GND, Cadencize cad) + throws CastSemanticException,UnimplementableProductionRuleException { + + final NetGraph netgraph = + new NetGraph(null,null,null, Vdd, GND, Collections.EMPTY_SET); + final CellInterface ci; + ci = cfp.getFullyQualifiedCell(cellName); + netgraph.addCellInterface(ci, new NetGraph[0], cfp, cad); + netgraph.gateType = cellName; + final boolean stack = ((Boolean) DirectiveUtils.getTopLevelDirective(ci, DirectiveConstants.STACK_GATE)).booleanValue(); + if (!stack) netgraph.prepareForLvs(); + return netgraph; + } + + public void print() + { + System.out.println("-----------------------------------------------------------"); + System.out.println("List of all cell types in this design:"); + for (Iterator ita = allCellTypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + System.out.println(sta.toString()); + } + System.out.println("-----------------------------------------------------------"); + } + + + public String toString() + { + String s = "-------------------------------------------------------\n"; + s += "List of all cell types in this design:\n"; + + for (Iterator ita = allCellTypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + s += sta.toString(); + } + s += "-----------------------------------------------------------\n"; + + return s; + } + + + /** + * Function to generate HalfOperator data structures for cells. + **/ + public void generateHalfOperators(Set/**/ cellTypes) + { + if(DebugOption.printLevel <= 2){ + System.out.println("-----------------------------------------------------------"); + System.out.println("Generating half-operators"); + } + + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + generateHalfOperator(sta); + } + + if(DebugOption.printAll){ + System.out.println("-----------------------------------------------------------"); + } + } + + /** + * Generate HalfOperator data structures for the given cell. + **/ + public void generateHalfOperator(final CellType sta) { + final double cellDelayBias = sta.getDelay().getCellDelayBias(); + + if(DebugOption.printLevel <= 2){ + System.out.println("************* Processing Cell: " + sta.typeName); + } + + if(sta.transistors.getEdges().size() == 0){ // there is no transistor in this cell + if(DebugOption.printAll){ + System.out.println("This is a cell with no transistors"); + System.out.println("*************\n"); + } + return; + } + + + final float celltau = tau; + + // reset sizes of all transistors to -infinity, depth to -1 + // Anything less than the minumum possible size or depth is fine. + // TODO: Maybe should set transistor length too? + Collection transistors = (Collection) sta.transistors.getNodes(); + for (Iterator itb = transistors.iterator(); itb.hasNext(); ) { + NetGraph.NetNode nna = (NetGraph.NetNode)itb.next(); + + for (Iterator itc = nna.edges.iterator(); itc.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)itc.next(); + nea.size = Double.NEGATIVE_INFINITY; + nea.depth = -1; + } + } + + // create the set of all output nodes + // not including the output node of the first inverter in the staticizer + Set/**/ normalOutputNodes = + new TreeSet/**/(); + for (Iterator itb = transistors.iterator(); itb.hasNext(); ) { + NetGraph.NetNode nna = (NetGraph.NetNode)itb.next(); + if(DebugOption.printAll){ + System.out.print("Node: \"" + nna.name.getCadenceString() + "\" is "); + } + + if(nna.isOutput()){ + if(nna.isStaticizerInverter()){ + if(DebugOption.printAll){ + System.out.println("staticizer output node"); + } + } + else{ + normalOutputNodes.add(nna); + if(DebugOption.printAll){ + System.out.println("normal output node"); + } + } + + } + else{ + if(DebugOption.printAll){ + System.out.println("not output node."); + } + } + } + if(DebugOption.printAll){ + System.out.println("Number of output nodes: " + + normalOutputNodes.size()); + System.out.println("*************\n"); + } + + + // generate all half-operators + List/**/ halfOperators = + sta.getListHalfOperators(); + + boolean nonDefaultLength = false; + + for (Iterator itb = normalOutputNodes.iterator(); + itb.hasNext(); ) { + NetGraph.NetNode nna = (NetGraph.NetNode)itb.next(); + HierName nodename = nna.name; + + // find paths, check if operator is combinational or a library gate + nna.findPaths(); + boolean isCombinational = nna.isCombinational(); + boolean isLibraryGate = (nna.getGate() != null); + + // debugging + if (DebugOption.printAll) { + System.out.println("*************************"); + System.out.println("Created 2 new half-operators"); + System.out.println("node=" + nna.name + + " combinational=" + isCombinational + + " libraryGate=" + isLibraryGate); + } + + // delaybias from non-CAST source + final double externalDelayBias = + sta.isFixedSize() ? sta.design.fixedDelayBias + : sta.design.sizableDelayBias; + + // create pull-down half-operator + HalfOperator dnHalfOp = new HalfOperator(); + dnHalfOp.driveDirection = HalfOperator.DriveDirection.PULL_DOWN; + dnHalfOp.outputNode = nna; + dnHalfOp.setDelayBias(sta.getDelay().getDelay(nna.name, false, celltau) * externalDelayBias / tau); + dnHalfOp.subType = sta; + dnHalfOp.setSymmetrizationFactor(getDownSymmetrizationFactor(nna, sta)); + dnHalfOp.isCombinational = isCombinational; + dnHalfOp.isLibraryGate = isLibraryGate; + + // create pull-up half-operator + HalfOperator upHalfOp = new HalfOperator(); + upHalfOp.driveDirection = HalfOperator.DriveDirection.PULL_UP; + upHalfOp.outputNode = nna; + upHalfOp.setDelayBias(sta.getDelay().getDelay(nna.name, true, celltau) * externalDelayBias / tau); + upHalfOp.subType = sta; + upHalfOp.setSymmetrizationFactor(getUpSymmetrizationFactor(nna, sta)); + upHalfOp.isCombinational = isCombinational; + upHalfOp.isLibraryGate = isLibraryGate; + + boolean found = false; + for (Iterator ite = sta.getAllNets().iterator(); ite.hasNext(); ) { + CellNet cna = (CellNet)ite.next(); + if (cna.canonicalName.equals(nna.name)) { + found = true; + + dnHalfOp.outputNet = cna; + dnHalfOp.minDelay = cellDelayBias * cna.getDownMinDelay(); + dnHalfOp.setStrengthBias(cna.getDownStrengthBias()); + if (dnHalfOp.getStrengthBias() > 1.0) { + System.err.println("NOTE: Got strength bias: " + dnHalfOp.getStrengthBias() + + " on " + sta.typeName + "/" + + cna.canonicalName + "-"); + } + upHalfOp.outputNet = cna; + upHalfOp.minDelay = cellDelayBias * cna.getUpMinDelay(); + upHalfOp.setStrengthBias(cna.getUpStrengthBias()); + if (upHalfOp.getStrengthBias() > 1.0) { + System.err.println("NOTE: Got strength bias: " + upHalfOp.getStrengthBias() + + " on " + sta.typeName + "/" + + cna.canonicalName + "+"); + } + break; + } + } + + assert found + : "Output netnode doesn't have corresponding cellnet\n" + + sta.toString() + "\n" + + "-----> Name of the netnode: " + + nna.name.getCadenceString(); + + Float effectiveResistanceUp = null; + Float effectiveResistanceDown = null; + if (techData.getUseIntrinsicCap()) { + final NetGraph.GateInstance gate = nna.getGate(); + if (gate != null) { + final HierName portName = + gate.getPortName(nna.getName()); + final CellInterface gateCell = getCellForGate(gate); + effectiveResistanceUp = + (Float) DirectiveUtils + .getHalfOpDirectiveValue(gateCell, + DirectiveConstants.EFFECTIVE_RESISTANCE, + portName, true, cad); + effectiveResistanceDown = + (Float) DirectiveUtils + .getHalfOpDirectiveValue(gateCell, + DirectiveConstants.EFFECTIVE_RESISTANCE, + portName, false, cad); + } + } + + // Do a first pass through the paths to compute the maxDepth + int maxDepthDown = 0; + int maxDepthUp = 0; + for (Iterator iPath = nna.getPaths().iterator(); + iPath.hasNext(); ) { + NetGraph.NetPath netPath = + (NetGraph.NetPath) iPath.next(); + // Replicate control of next loop + if (!netPath.isFeedBack()) { + final int numEdges = netPath.getEdges().size(); + if (netPath.getType() == DeviceTypes.N_TYPE) { + maxDepthDown = Math.max(maxDepthDown, numEdges); + } else { + assert netPath.getType() == DeviceTypes.P_TYPE; + maxDepthUp = Math.max(maxDepthUp, numEdges); + } + } + } + + // calculate relative size of the transistors with corresponding half-operator + for (Iterator itc = nna.getPaths().iterator(); itc.hasNext(); ) { + NetGraph.NetPath npa = (NetGraph.NetPath)itc.next(); + + if(DebugOption.printLevel <= 1){ + System.out.println("**********************************************"); + System.out.println(npa.toString()); + System.out.println("**********************************************"); + } + + int pathType = npa.getType(); // type of the path + if(!npa.isFeedBack()){ + if(DebugOption.printLevel <= 1){ + System.out.println("**********************************************"); + System.out.println(npa.toString()); + System.out.println("**********************************************"); + } + + List/**/ edges = npa.getEdges(); + int numEdges = edges.size(); + + boolean floating = true; + for (Iterator ei = edges.iterator(); ei.hasNext(); ) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) ei.next(); + floating = floating && edge.floating; + } + + double symmetrizeFactor = 1.0; + + if (pathType == DeviceTypes.N_TYPE) { + dnHalfOp.addDepths(numEdges, floating); + symmetrizeFactor = + dnHalfOp.getSymmetrizationFactor(); + } else { + assert pathType == DeviceTypes.P_TYPE; + upHalfOp.addDepths(numEdges, floating); + symmetrizeFactor = + upHalfOp.getSymmetrizationFactor(); + } + + if(!(npa.getEndNode().isGND() || npa.getEndNode().isVdd())){ + if(DebugOption.printLevel <= 3) { + System.out.println("NOTE: Transistor sharing between half-operators found, not processed."); + } + } + + // assign relative sizes to the transistors on this path + for (Iterator itd = edges.iterator(); itd.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)itd.next(); + + final double resistanceRatio; + if (pathType == DeviceTypes.N_TYPE) { // PULL_DOWN + final double[] erf = + techData.getEffectiveResistanceFactorN(nea.getTransistorType()); + if (effectiveResistanceDown != null) { + resistanceRatio = + (effectiveResistanceDown + .floatValue() / erf[0]) * + (erf[numEdges - 1] / + erf[maxDepthDown - 1]); + } else { + final int limitedDepth = + Math.min(numEdges, + techData.stackLimitN); + resistanceRatio = + erf[limitedDepth - 1] / erf[0]; + } + } else { // PULL_UP + assert pathType == DeviceTypes.P_TYPE; + final double[] erf = + techData.getEffectiveResistanceFactorP(nea.getTransistorType()); + if (effectiveResistanceUp != null) { + resistanceRatio = + (effectiveResistanceUp + .floatValue() / erf[0]) * + (erf[numEdges - 1] / + erf[maxDepthUp - 1]); + } else { + final int limitedDepth = + Math.min(numEdges, + techData.stackLimitP); + resistanceRatio = + erf[limitedDepth - 1] / erf[0]; + } + } + + double effectiveWidth = resistanceRatio * numEdges * + (nea.length / techData.getDefaultGateLength()); + + if(symmetrizeFactor > 1.0){ + if(DebugOption.printLevel <= 2){ + System.out.println("Note: symmetrized transistor found"); + } + effectiveWidth = effectiveWidth / symmetrizeFactor; + } + + // compute max size and depth + if (nea.size < effectiveWidth) + nea.size = effectiveWidth; + if (nea.depth < numEdges) + nea.depth = numEdges; + + if (pathType == DeviceTypes.N_TYPE) { // PULL_DOWN + if(DebugOption.printAll){ + System.out.println("Added PULL_DOWN transistor: " + + nea.gate.name + " Size: " + nea.size); + } + if (dnHalfOp.transistors.contains(nea)) { + if(DebugOption.printLevel <= 2){ + System.out.println("Note: Transistor sharing found within same half-operator"); + } + } + else{ + dnHalfOp.transistors.add(nea); + } + } else { // PULL_UP + assert pathType == DeviceTypes.P_TYPE; + if(DebugOption.printAll){ + System.out.println("Added PULL_UP transistor: " + + nea.gate.name + " Size: " + nea.size); + } + if (upHalfOp.transistors.contains(nea)) { + if(DebugOption.printLevel <= 2){ + System.out.println("Note: Transistor sharing found within same half-operator"); + } + } + else{ + upHalfOp.transistors.add(nea); + } + } + } + if(DebugOption.printAll){ + System.out.println("***************"); + } + } + } + if(DebugOption.printAll){ + System.out.println("*************************"); + } + + // Find the total up and down sizes attached to output node + // this will be used to compute the diffusion cap. + double downSize = 0.0; + double upSize = 0.0; + for (Iterator iEdge = nna.getEdges(); iEdge.hasNext(); ) { + final NetGraph.NetEdge edge = + (NetGraph.NetEdge) iEdge.next(); + assert edge.source == nna || edge.drain == nna; + // The size will be NEGATIVE_INFINITY if the transistor + // is not part of a half-operator + if (edge.size != Double.NEGATIVE_INFINITY) { + if (edge.type == DeviceTypes.N_TYPE) + downSize += edge.size; + else + upSize += edge.size; + } + } + dnHalfOp.setOutputDiffusionLength(downSize); + upHalfOp.setOutputDiffusionLength(upSize); + + if (dnHalfOp.transistors.size() != 0) { + halfOperators.add(dnHalfOp); + nonDefaultLength |= checkTransistorLength(dnHalfOp); + } + else{ + if(DebugOption.printAll){ + System.out.println("Warning: this half-operator does not have transistors"); + System.out.println("Will not be added to the list"); + System.out.println(dnHalfOp.toString()); + } + } + + if (upHalfOp.transistors.size() != 0) { + halfOperators.add(upHalfOp); + nonDefaultLength |= checkTransistorLength(upHalfOp); + } + else{ + if(DebugOption.printAll){ + System.out.println("Warning: this half-operator does not have transistors"); + System.out.println("Will not be added to the list"); + System.out.println(upHalfOp.toString()); + } + } + } + + if (nonDefaultLength) { + System.err.println("WARNING: cell " + sta.typeName + + " contains transistors with non-default length."); + } + + if(DebugOption.printLevel <= 3){ + System.out.println("----------------------------------------------------------------"); + System.out.println("Halfoperator coverage check for cell: " + sta.typeName); + String stra = sta.checkHalfOperatorCoverage(); + System.out.println("Result: " + stra); + System.out.println("----------------------------------------------------------------"); + } + } + + private boolean checkTransistorLength(final HalfOperator op) { + final double l = + op.subType.design.getTechnologyData().getDefaultGateLength(); + boolean nonDefaultLength = false; + for (NetGraph.NetEdge nea : op.transistors) { + if (nea.length != l) nonDefaultLength = true; + } + if (nonDefaultLength) { + final String dir = + op.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? "-" : "+"; + System.out.println( + "INFO: half-operator " + op.subType.typeName + "/" + + op.outputNode.name + dir + + " contains transistors with non-default length."); + } + return nonDefaultLength; + } + + private double getUpSymmetrizationFactor(final NetGraph.NetNode netNode, + final CellType cellType) { + return getSymmetrizationFactor(netNode, netNode.getPaths(), + DeviceTypes.P_TYPE, cellType, this); + } + + private double getDownSymmetrizationFactor(final NetGraph.NetNode netNode, + final CellType cellType) { + return getSymmetrizationFactor(netNode, netNode.getPaths(), + DeviceTypes.N_TYPE, cellType, this); + } + + /** + * Get the symmetrization factor for a half-operator. Pass-gates + * are ignored unless the half-operator consists entirely of + * pass-gates, in which case the symmetrization factor is assumed + * to be 1. + **/ + public static double getSymmetrizationFactor + (final NetGraph.NetNode netNode, + final Collection netPaths, + final int pathType, + final CellType cellType, + final CastDesign design) { + assert (pathType==DeviceTypes.N_TYPE)||(pathType==DeviceTypes.P_TYPE) + : "NetPath.type should be either N_TYPE or P_TYPE"; + + // set to zero to signal that the symmetrization factor is unknown + double symmetrizationFactor = 0; + boolean allPathsPass = true; + for (Iterator iPath = netPaths.iterator(); iPath.hasNext(); ) { + NetGraph.NetPath netPath = (NetGraph.NetPath) iPath.next(); + + if (netPath.getType() != pathType) + continue; + if (netPath.isFeedBack()) + continue; + // ignore pass gates + if (!netPath.getEndNode().isRail()) { + // Give warning for more than one transistor in pass gate + if (netPath.getEdges().size() > 1) + design.messageCenter.createMessage(1, 20, "WARNING", + "Found pass gate with more than one transistor\n", + "Found " + netPath.getEdges().size() + + " transistors in pass gate " + netPath + + " in cell " + cellType.typeName + "\n"); + continue; + } + allPathsPass = false; + + // get folding factor for NetPath + double M = netPath.getFoldingFactor(netPaths); + if (symmetrizationFactor == 0) { + symmetrizationFactor = M; + } else if (symmetrizationFactor != M) { + // TODO: turn this into an assertion if we only care + // about processing netlists generated by jauto. + design.messageCenter.createMessage(1, 19, "WARNING", + "Symmetrization factors do not agree for paths in a half-op.", + "cell type: " + cellType.typeName + + "\nnode name: " + netNode.name + + "\npath type: " + pathType + + "\nold symmetrization factor: " + symmetrizationFactor + + "\nnew symmetrization factor: " + M + "\n"); + } + } + + if (allPathsPass) { + assert symmetrizationFactor == 0; + return 1; + } else { + assert symmetrizationFactor > 0; + return symmetrizationFactor; + } + } + + + /** + * Function to put I/O direction properties on all port nets. + **/ + public static void addPortDirection(Set/**/ cellTypes) + { + if(DebugOption.printAll){ + System.out.println("*************************************************************************"); + System.out.println("Assigning I/O directions to port nets"); + System.out.println("*************************************************************************"); + } + + // Create a sorted list for all celltypes, from low to high + // (leaf to high level) + ArrayList/**/ lsta = new ArrayList/**/(); + + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + sortedInsert(lsta, sta); + } + + // Annotate all the port cellnets + for (Iterator ita = lsta.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + Map markPorts = new HashMap(); + for (Map.Entry portDir : + CellUtils.markPorts(sta.cast_cell).entrySet()) { + try { + HierName hport = + HierName.makeHierName(portDir.getKey(), '.'); + markPorts.put( + (HierName) sta.namespace.getCanonicalKey(hport), + portDir.getValue()); + } catch (InvalidHierNameException e) { + throw new RuntimeException( + "Cannot create HierName: " + portDir.getKey(), e); + } + } + + if(DebugOption.printAll){ + System.out.println(sta.toString()); + } + + for (Iterator itb = sta.getAllNets().iterator(); + itb.hasNext(); ) { + CellNet neta = (CellNet)itb.next(); + if(neta.isPortNet()){ // only process port nets + neta.visited = false; // reset the "visited" flag + HierName hna = neta.canonicalName; + + if (!sta.transistors.isEmpty()) { + // there are transistors in the netgraph + + for (Iterator itc = sta.transistors.getNodes().iterator(); itc.hasNext(); ) { + NetGraph.NetNode nna = (NetGraph.NetNode)itc.next(); + + if (hna.equals(nna.name)) { // the cellnet exists in netgraph + if(nna.isOutput()){ // should be at least output port + + // see if it also drives a gate + boolean found = false; + nodeLoop: + for (Iterator itd = sta.transistors.getNodes().iterator(); itd.hasNext(); ) { + NetGraph.NetNode nnb = (NetGraph.NetNode)itd.next(); + + for (Iterator ite = nnb.edges.iterator(); ite.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)ite.next(); + if(nea.source.isStaticizerInverter() || nea.drain.isStaticizerInverter()){ + if(DebugOption.printAll){ + } + } + else{ + if(nea.gate == nna){ + found = true; + break nodeLoop; + } + } + } + } + + + if(found){ // this is a IN/OUT net + if(DebugOption.printAll){ + System.out.println("1. This is a I/O port in the netgraph"); + System.out.println("Name of the netnode: " + nna.name); + } + neta.portDirection = + CellNet.INPUTOUTPUT; + neta.visited = true; + } + else{ + if(neta.visited){ + if (neta.portDirection == CellNet.INPUT) { + // already marked as input + neta.portDirection = + CellNet.INPUTOUTPUT; + if(DebugOption.printAll){ + System.out.println("2. This is a I/O port in the netgraph"); + System.out.println("Name of the netnode: " + nna.name); + } + } + } + else{ + neta.portDirection = CellNet.OUTPUT; + neta.visited = true; + } + } + } + else{ + if(neta.visited){ + if (neta.portDirection == CellNet.OUTPUT) { + // already marked as output + neta.portDirection = + CellNet.INPUTOUTPUT; + if(DebugOption.printAll){ + System.out.println("3. This is a I/O port in the netgraph"); + System.out.println("Name of the netnode: " + nna.name); + } + } + } + else{ + neta.portDirection = CellNet.INPUT; + neta.visited = true; + } + } + } + } + } + + // FIXME: possible cell/transistor mix in the future, don't use getLevel + if((sta.getLevel() == 0) && (!neta.visited)){ + String msa = "WARNING"; + String msb = "Port net is not in the netgraph of the leaf cell.\n"; + String msc = "CellName: " + sta.typeName + "\n" + + "NetName: " + neta.canonicalName.getCadenceString() + "\n"; + + sta.design.getMessageCenter().createMessage(1, 99, msa, msb, msc); + } + + + // check cells next + for (Iterator itc = neta.getSetSubcellNets().iterator(); itc.hasNext(); ) { + CellNet netb = (CellNet)itc.next(); + + if (netb.portDirection == CellNet.INPUT) { + if(neta.visited){ + if (neta.portDirection == CellNet.OUTPUT) { + // already marked as output + neta.portDirection = CellNet.INPUTOUTPUT; + } else if (neta.portDirection == CellNet.UNKNOWN) { + // already marked as unknown + neta.portDirection = CellNet.INPUT; + } + } + else{ + neta.portDirection = CellNet.INPUT; + } + } else if (netb.portDirection == CellNet.OUTPUT) { + if(neta.visited){ + if (neta.portDirection == CellNet.INPUT) { + // already marked as input + neta.portDirection = CellNet.INPUTOUTPUT; + } else if (neta.portDirection == CellNet.UNKNOWN) { + // already marked as unknown + neta.portDirection = CellNet.OUTPUT; + } + } + else{ + neta.portDirection = CellNet.OUTPUT; + } + } else if (netb.portDirection == CellNet.INPUTOUTPUT) { + neta.portDirection = CellNet.INPUTOUTPUT; + } else if (netb.portDirection == CellNet.UNKNOWN) { + String msa = "WARNING"; + String msb = "Found port with UNKNOWN direction.\n"; + String msc = "CellName: " + netb.container.typeName + "\n" + + "NetName: " + netb.canonicalName.getCadenceString() + "\n"; + + netb.container.design.getMessageCenter().createMessage(1, 98, msa, msb, msc); + } + + neta.visited = true; + } + + if (sta.isInternalEnv()) { + final Integer portDir = + markPorts.get(neta.canonicalName); + if (portDir != null) { + switch (portDir.intValue()) { + case PortDefinition.IN: + neta.portDirection = CellNet.INPUT; + break; + case PortDefinition.OUT: + neta.portDirection = CellNet.OUTPUT; + break; + case PortDefinition.INOUT: + neta.portDirection = CellNet.INPUTOUTPUT; + break; + } + } + } + } + } + } + } + + + /** + * Generate the source/sink lists for all the cellnets in the design. + * Used for GlobalNet generation. + **/ + public void generateSourceSinkLists(Set/**/ cellTypes) + { + if(DebugOption.printSSG){ + System.out.println("*******************************************************"); + System.out.println("Generating the lists of sources and sinks for all cell nets"); + System.out.println("*******************************************************"); + } + + + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + if(DebugOption.printSSG){ + System.out.println("******************************"); + } + + CellType sta = (CellType)ita.next(); + List/**/ halfOperators = + sta.getListHalfOperators(); + + if(DebugOption.printSSG){ + System.out.println(sta.toString()); + } + + for (Iterator itb = sta.getAllNets().iterator(); itb.hasNext(); ) { + if(DebugOption.printSSG){ + System.out.println("--------------------------------------------------------------"); + } + CellNet cna = (CellNet)itb.next(); + cna.listSources.clear(); + cna.listSinks.clear(); + HierName hna = cna.canonicalName; + + // look for user-defined load capacitance, add it as a sink + double loadCap = cna.getLoadCapacitance(); + if(DebugOption.printLevel <= 1){ + System.out.println("Obtained loadcap: " + loadCap + " for net: " + cna.canonicalName.getCadenceString()); + } + + if(loadCap > 0.0){ + NetSink nska = new NetSink(NetType.CAPACITIVE_LOAD); + nska.loadCapacitance = loadCap; + cna.listSinks.add(nska); + + if(DebugOption.printLevel <= 1){ + System.out.println("Load capacitance sink " + loadCap + " added to net: " + cna.canonicalName.getCadenceString()); + } + } + + + if(DebugOption.printSSG){ + System.out.println(cna.toString()); + } + + // work through all the instances the net connects to + for (Iterator itc = cna.getListInstanceInfo().iterator(); itc.hasNext(); ) { + CellNet.InstanceInfo insta = (CellNet.InstanceInfo)itc.next(); + if (insta.inst.child.isJautoIgnore()) + continue; + Set/**/ subcellNets = insta.setSubcellNets; + + CellType childCellType = null; + + // Check port directions for childCellType, to decide whether + // to add as a source, or a sink, or both + int direction = -1; + for (Iterator itd = subcellNets.iterator(); itd.hasNext(); ) { + CellNet cnc = (CellNet)itd.next(); + // container should be the same for all cellnets + assert childCellType == null || childCellType == cnc.container; + childCellType = cnc.container; + + if (direction == -1 || direction == CellNet.UNKNOWN) + direction = cnc.portDirection; + else if (direction == CellNet.INPUT) { + if (cnc.portDirection == CellNet.OUTPUT || + cnc.portDirection == CellNet.INPUTOUTPUT) + direction = CellNet.INPUTOUTPUT; + } else if (direction == CellNet.OUTPUT) { + if (cnc.portDirection == CellNet.INPUT || + cnc.portDirection == CellNet.INPUTOUTPUT) + direction = CellNet.INPUTOUTPUT; + } + } + + + // Add source/sink list + if (direction == CellNet.INPUT || + direction == CellNet.INPUTOUTPUT) { + // INPUT, INPUTOUTPUT -> NetSink + NetSink nska = new NetSink(NetType.CELL); + nska.cellSink = childCellType; + nska.setSubcellNets = subcellNets; + nska.coordinateX = insta.coordinateX; + nska.coordinateY = insta.coordinateY; + nska.orientation = insta.orientation; + nska.prefixInstanceName(insta.inst.nameInParent); + cna.listSinks.add(nska); + + if(DebugOption.printSSG){ + System.out.println("Created a sink"); + System.out.println(nska.toString()); + } + + } + + if (direction == CellNet.OUTPUT || + direction == CellNet.INPUTOUTPUT) { + // OUTPUT, INPUTOUTPUT -> NetSource + NetSource nsra = new NetSource(NetType.CELL); + nsra.cellSource = childCellType; + nsra.setSubcellNets = subcellNets; + nsra.coordinateX = insta.coordinateX; + nsra.coordinateY = insta.coordinateY; + nsra.orientation = insta.orientation; + nsra.prefixInstanceName(insta.inst.nameInParent); + cna.listSources.add(nsra); + + if(DebugOption.printSSG){ + System.out.println("Created a source"); + System.out.println(nsra.toString()); + } + + } + + // REVIEW: Why can't this be an assertion? + // It does happen. Why? + // UNKNOWN -> can't be! + if (direction == CellNet.UNKNOWN) { + System.out.println("NOTE: net with unknown direction"); + //System.out.println(cna.toString()); + } + + } + + + // add default sinks to primary I/O ports + // TODO: not adding sources, no method to deal with it yet, may need later + if(cna.isPortNet() && (sta == getTopLevelCell())){ // primary input/output + /* + if (cna.portDirection == CellNet.INPUT || + cna.portDirection == CellNet.INPUTOUTPUT) { + nsra = new NetSource(CellType.CAPACITIVE_LOAD); + cna.listSources.add(nsra); + } + */ + + if (cna.portDirection == CellNet.OUTPUT || + cna.portDirection == CellNet.INPUTOUTPUT) { + NetSink nska = new NetSink(NetType.CAPACITIVE_LOAD); + cna.listSinks.add(nska); + } + + assert cna.portDirection != CellNet.UNKNOWN + : "Port net with unknown direction at top-level: " + + cna; + } + + + // Generate half-operator and transistor type sources and + // sinks. + for (Iterator itc = sta.transistors.getNodes().iterator(); itc.hasNext(); ) { + NetGraph.NetNode nna = (NetGraph.NetNode)itc.next(); + + if (hna.equals(nna.name)) { // the cellnet exists in the netgraph + if(nna.isOutput()){ // look for sources for output nodes + for (Iterator itd = halfOperators.iterator(); itd.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itd.next(); + assert hoa.outputNode != null + : "Null pointer to netnode"; + if(DebugOption.printSSG){ + System.out.println("-----------------------"); + System.out.println("\t\t" + hoa.outputNode.toString()); + System.out.println("-----------------------"); + } + if(hoa.outputNode == nna){ + NetSource nsra = new NetSource(NetType.HALF_OPERATOR_TRANSISTOR); + nsra.source = hoa; + cna.listSources.add(nsra); + + if(DebugOption.printSSG){ + System.out.println("\t\tAdded one half-operator to the list of sources"); + System.out.println("\t\t" + nna.toString()); + } + + } + } + } + + // look for sinks for all nodes + Set/**/ seenEdges = + new HashSet/**/(); + for (Iterator itd = sta.transistors.getNodes().iterator(); itd.hasNext(); ) { + NetGraph.NetNode nnb = (NetGraph.NetNode)itd.next(); + + for (Iterator ite = nnb.edges.iterator(); ite.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)ite.next(); + + if(nea.gate == nna){ // found the netnode as the gate of a transistor + if (!seenEdges.contains(nea)) { + int count = 0; + for (Iterator itf = halfOperators.iterator(); itf.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itf.next(); + if(hoa.transistors.contains(nea)){ + if(DebugOption.printSSG){ + System.out.println("Added a sink to the sink list"); + System.out.println("Name of the net: " + nna.name); + } + + NetSink nska = + new NetSink(NetType.HALF_OPERATOR_TRANSISTOR); + nska.sink = hoa; + nska.transistor = nea; + cna.listSinks.add(nska); + + count++; + } + } + + nea.shareCount = Math.max(1, count); + + seenEdges.add(nea); + } + } + } + } + } + } + if(DebugOption.printSSG){ + System.out.println("--------------------------------------------------------------"); + } + + } + + if(DebugOption.printSSG){ + System.out.println("******************************"); + } + } + } + + + /** + * Sorted insert of a celltype to list, by cell level number, from low to high. + **/ + public static void sortedInsert(ArrayList/**/ lst1, CellType st1) + { + int k = st1.getLevel(); // get the level number of the sub-type + int j = lst1.size(); + for(int i=0;i k){ + lst1.add(i, st1); // insert this sub-type at index i + return; + } + } + + lst1.add(st1); // add this sub-type to the end of the list + } + + + + /** + * Mark non-observable ports. + **/ + public static void markNonObservablePorts(Set/**/ cellTypes) + { + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + Boolean blb = (Boolean)DirectiveUtils.getTopLevelDirective(cella.cast_cell, DirectiveConstants.CELLNONOBSERVABLE); + + // "fragment" directive makes all port nets non-observable + boolean isFragment = blb.booleanValue(); + + cella.setIsFragment(isFragment); + + if(isFragment){ + + if(DebugOption.printLevel <= 3){ + System.out.println("Fragment cell found:"); + System.out.println(cella.toString()); + } + + for (Iterator itb = cella.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + + if(cna.isPortNet()){ // only mark port net non-observable + cna.setIsObservable(false); + } + } + + + } + } + + + // "cutpath" directive makes any net observable + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + for (Iterator itb = cella.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + + if(cna.isCutPath()){ + cna.setIsObservable(true); + } + } + } + } + + public boolean useSteinerTree() { + return useSteinerTree; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellBlock.java new file mode 100644 index 0000000000..a79416d425 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellBlock.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import com.avlsi.cell.CellImpl; +import com.avlsi.fast.BlockInterface; +import com.avlsi.util.debug.Debug; + +public class CellBlock extends BlockCommon { + public String getType() { + return BlockInterface.CELL; + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "CellBlock does not support merge"); + return null; + } + + // The inherited refineFrom() is fine + + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "CellBlock does not support replace"); + return null; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellNet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellNet.java new file mode 100644 index 0000000000..e933611047 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellNet.java @@ -0,0 +1,1143 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.fast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.TreeSet; + +import java.io.*; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.impl.SimpleAbstractDeviceIterator; +import com.avlsi.tools.jauto.GlobalNet; +import com.avlsi.tools.jauto.NetSource; +import com.avlsi.tools.jauto.NetSink; +import com.avlsi.tools.jauto.NetType; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.ObjectUtils; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.Functional; +import com.avlsi.util.functions.BinaryFunction; + +/** + * Class for representing a net in a cell. Used by CellType. In + * contrast to GlobalNet, which represents a net spanning several + * levels of hierarchy, a CellNet only includes nodes which are + * defined within a single cell. + * + * A "net" is a set of nodes which are either the same or are + * connected by wires; something like a vertex in a circuit graph. + * Nodes in a CellNet must be all defined in the same cell, and so + * must be related to each other by an alias expression "a=b". + * + * @author Aaron Denney + * @version $Date$ + **/ + +public class CellNet { + + static final HierName Reset = HierName.makeHierName("Reset"); + static final HierName _Reset = HierName.makeHierName("_Reset"); + + public interface Geometry { + /** Map a name that is part of a subcircuit call. */ + HierName mapName(final CellNet port, final HierName alias); + + /** Map a name that is internal to a leaf cell. */ + HierName mapName(final CellNet net, final boolean gate); + Pair[] getRC(final HierName alias1, final HierName alias2); + AbstractDeviceIterator getDeviceIterator(); + } + + private static Comparator nameComparator = null; + public static Comparator getComparator() { + if (nameComparator == null) { + nameComparator = new Comparator() { + public int compare(Object o1, Object o2) { + final CellNet cn1 = (CellNet) o1; + final CellNet cn2 = (CellNet) o2; + int x = ObjectUtils.compare(cn1.container.typeName, + cn2.container.typeName); + if (x != 0) return x; + return ObjectUtils.compare(cn1.canonicalName, + cn2.canonicalName); + } + public boolean equals(Object o) { + return this == o; + } + }; + } + return nameComparator; + } + + public final CellType container; + public final Set/**/ internalNames; + public final Set/**/ portNames; + public final Set/**/ subcellconnectionNames; + private Set/**/ wiringConnectionNames; + public final HierName canonicalName; + private Geometry geometry; + + public static final int INPUT = 0; + public static final int OUTPUT = 1; + public static final int INPUTOUTPUT = 2; + public static final int UNKNOWN = 3; + + // I/O direction for port net + // 0 = INPUT + // 1 = OUTPUT + // 2 = INPUT/OUTPUT + // 3 = UNKNOWN + public int portDirection = UNKNOWN; + public boolean visited = false; + + public final List/**/ listSources = + new ArrayList/**/(); + public final List/**/ listSinks = + new ArrayList/**/(); + + public List globalNets = new ArrayList(); + + boolean isObservable = true; + boolean cutpath = false; + + private double upSize = -1, downSize = -1; + private final HierName Vdd, GND, _RESET; + + /** + * Constructor from no-layout information. + **/ + CellNet(CellType container, + Set/**/ internalNames, + Set/**/ portNames, + Set/**/ subcellconnectionNames, + HierName canonicalName, + HierName Vdd, HierName GND, HierName _RESET) { + this.container = container; + this.internalNames = internalNames; + this.portNames = portNames; + this.subcellconnectionNames = subcellconnectionNames; + this.wiringConnectionNames = Collections.EMPTY_SET; + this.geometry = null; + this.Vdd = Vdd; + this.GND = GND; + this._RESET = _RESET; + this.canonicalName = canonicalName; + } + + /** + * Constructor from layout-information, inheriting from other net. + **/ + CellNet(CellNet prototype, CellType container) { + Debug.assertTrue(container.prototype == prototype.container); + this.container = container; + this.internalNames = prototype.internalNames; + this.portNames = prototype.portNames; + this.subcellconnectionNames = prototype.subcellconnectionNames; + this.wiringConnectionNames = prototype.wiringConnectionNames; + this.canonicalName = prototype.canonicalName; + this.geometry = null; //FIXME + this.Vdd = prototype.Vdd; + this.GND = prototype.GND; + this._RESET = prototype._RESET; + } + + public Geometry getGeometry() { + return geometry; + } + + public void setGeometry(Geometry geometry) { + this.geometry = geometry; + } + + /** + * hack to approximate lexicographic ordering. + * + * The size of the various arrays corresponds to the index of the highest value of that type. + * + * Hmm. Totally wrong. need to get smallest element of each set. + **/ + public int compareTo(CellNet o) { + if (o == this) return 0; + assert o.container == container + : "Can't compare nets in different cells!"; + if (o.internalNames.size() < internalNames.size()) return -1; + else if (o.internalNames.size() > internalNames.size()) return 1; + else if (o.portNames.size() < portNames.size()) return -1; + else if (o.portNames.size() > portNames.size()) return 1; + else if (o.subcellconnectionNames.size() < subcellconnectionNames.size()) return -1; + else if (o.subcellconnectionNames.size() > subcellconnectionNames.size()) return 1; + else return 0; + } + + public int compareTo(Object o) { + return compareTo((CellNet) o); + } + + public boolean isPortNet() { + return this.portNames.size() > 0; + } + + public boolean isReset() + { + return (portNames.contains(_RESET) || portNames.contains(Reset) || portNames.contains(_Reset)); + } + + public boolean isVdd() + { + return portNames.contains(Vdd); + } + + public boolean isGND() + { + return portNames.contains(GND); + } + + public boolean connectedToSubcells() { + return this.subcellconnectionNames.size() > 0; + } + + public boolean isInternalNet() { + return !isPortNet(); + } + + private LinkedHashMap/*>*/ + getConnectionInfoMap() { + LinkedHashMap/*>*/ map = + new LinkedHashMap/*>*/(); + for (Iterator i = subcellconnectionNames.iterator(); i.hasNext(); ) { + HierName j = (HierName) i.next(); + ConnectionInfo ci = (ConnectionInfo) container.subcellports.get(j); + HierName child = ci.getChildName(j); + CellNet sub = ci.child.getNet(child); + Set/**/ s = (Set) map.get(ci); + if (s == null) { + s = new LinkedHashSet/**/(); + map.put(ci,s); + } + s.add(sub); + } + return map; + } + + /** + * Nets in subcells this connects to. + * List>CellNet<. + * + * For cells that are connected to multiple times, we want one net for each cell instance. + **/ + public List/**/ getSubcellNets() { + LinkedHashMap/*>*/ map = + getConnectionInfoMap(); + List/**/ rv = + new ArrayList/**/(map.size()); + for (Iterator i = map.values().iterator(); i.hasNext(); ) { + rv.addAll((Set)i.next()); + } + return rv; + } + + + /** + * Return at most one cellnet for each net we can be connected to via any + * instance of a subcell. + **/ + public Set getSetSubcellNets(boolean includeWiringSubcells) { + Set rv = new LinkedHashSet(); + for (Iterator i = subcellconnectionNames.iterator(); i.hasNext(); ) { + + HierName j = (HierName) i.next(); + CellNet sub = container.getSubcellNetConnectedTo(j); + rv.add(sub); + } + if (includeWiringSubcells) { + for (Iterator i = wiringConnectionNames.iterator(); i.hasNext(); ) { + + HierName j = (HierName) i.next(); + CellNet sub = container.getSubcellNetConnectedTo(j); + rv.add(sub); + } + } + return rv; + } + + public Set getSetSubcellNets() { + return getSetSubcellNets(false); + } + + /** + * return a list of list of cellnets we are connected to in subcells, + * organized by instance. + **/ + public List/*>*/ getListListSubcellNets() { + LinkedHashMap/*ConnectionInfo,Set>*/ map = + getConnectionInfoMap(); + List/*>*/ rv = + new ArrayList/*>*/(map.size()); + for (Iterator i = map.values().iterator(); i.hasNext(); ) { + Set s = (Set) i.next(); + rv.add(new ArrayList(s)); + } + return rv; + } + + // REVIEW: Do these fields need to be copied, or can we just + // keep a reference to the ConnectionInfo to save memory? + // How much memory do we use for InstanceInfos? + public static final class InstanceInfo { + final ConnectionInfo inst; + final Set/**/ setSubcellNets; + final double coordinateX; + final double coordinateY; + final int orientation; + + private InstanceInfo(ConnectionInfo ci, + Set/**/ subcellNets) + { + inst = ci; + setSubcellNets = new LinkedHashSet/**/(subcellNets); + coordinateX = ci.xOffset; + coordinateY = ci.yOffset; + + orientation = ci.orientation; + } + } + + /** + * return a list of connection information for all the instances connectted to this net + * includes cellnets in instances and x-y coordinates of the instances + **/ + public List/**/ getListInstanceInfo() + { + LinkedHashMap/*>*/ map = + getConnectionInfoMap(); + ArrayList/**/ rv = + new ArrayList/**/(map.size()); + for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) { + Map.Entry/*>*/ entry = + (Map.Entry) i.next(); + ConnectionInfo ci = (ConnectionInfo) entry.getKey(); + Set s = (Set) entry.getValue(); + + rv.add(new InstanceInfo(ci, s)); + } + + return rv; + + } + + + + /** + * Make us part of GlobalNet g. + **/ + public void addGlobalNet(GlobalNet g) { + globalNets.add(g); + } + + /** + * What global nets are we part of? + **/ + public List getGlobalNets() { + return globalNets; + } + + /** + * Get the list of sources + **/ + public List/**/ getListSources(){ + return listSources; + } + + /** + * Get the list of sinks + **/ + public List/**/ getListSinks(){ + return listSinks; + } + + public void print( final PrintWriter p ) { + p.print( toString() ); + } + + /** + * Dump out information for debug + @deprecated Library code should not be using System.out directly. + **/ + public void print() + { + final PrintWriter p = new PrintWriter( System.out ); + } + + + public static String portDirectionString(int dir) { + switch(dir){ + case INPUT: return "INPUT"; + case OUTPUT: return "OUTPUT"; + case INPUTOUTPUT: return "IN/OUT"; + case UNKNOWN: return "UNKNOWN"; + default: throw new AssertionError("Unknown port direction " + + dir); + } + } + + public String toString() + { + String s = ""; + + if(portNames.size() != 0){ + s += portDirectionString(portDirection); + s += "\tport net" + "\n"; + } + else{ + s += "\tinternal net" + "\n"; + } + + + s += "\tnumber of internal names: " + internalNames.size() + "\n"; + for (Iterator itc = internalNames.iterator(); itc.hasNext(); ) { + HierName hna = (HierName)itc.next(); + s += "\t\t" + hna.getCadenceString() + "\n"; + } + + s += "\tnumber of port names: " + portNames.size() + "\n"; + for (Iterator itc = portNames.iterator(); itc.hasNext(); ) { + HierName hna = (HierName)itc.next(); + s += "\t\t" + hna.getCadenceString() + "\n"; + } + + s += "\tnumber of subcellconnection names: " + subcellconnectionNames.size() + "\n"; + for (Iterator itc = subcellconnectionNames.iterator(); itc.hasNext(); ) { + HierName hna = (HierName)itc.next(); + s += "\t\t" + hna.getCadenceString() + "\n"; + } + + + s += "\tnumber of subcell nets: " + getSetSubcellNets().size() + "\n"; + + + s += "\tnumber of sources: " + listSources.size() + "\n"; + for (Iterator itc = listSources.iterator(); itc.hasNext(); ) { + NetSource nsra = (NetSource)itc.next(); + s += "\t\ttype: " + nsra.getType() + "\n"; + } + + s += "\tnumber of sinks: " + listSinks.size() + "\n"; + for (Iterator itc = listSinks.iterator(); itc.hasNext(); ) { + NetSink nska = (NetSink)itc.next(); + s += "\t\ttype: " + nska.getType() + "\n"; + } + + s += "\tnumber of global nets: " + globalNets.size() + "\n"; + + + s += "\n"; + + return s; + } + + + + public void dumpInfo(BufferedWriter bw1, String s1) + { + try{ + bw1.write(s1 + "CELL_NET " + canonicalName.getCadenceString() + " {\n"); + bw1.write(s1 + "\tis_staticized = " + isStaticized() + ";\n"); + bw1.write(s1 + "\tis_port = " + isPortNet() + ";\n"); + if(isPortNet()){ + bw1.write(s1 + "\tport_direction = " + portDirection + ";\n"); + } + else{ + bw1.write(s1 + "\tgate_cap = " + getGateCap() + ";\n"); + bw1.write(s1 + "\twire_cap = " + getWireCap() + ";\n"); + bw1.write(s1 + "\twire_res = " + getWireRes() + ";\n"); + } + bw1.write(s1 + "\tn_sources = " + listSources.size() + ";\n"); + bw1.write(s1 + "\tn_sinks = " + listSinks.size() + ";\n"); + + + + bw1.write(s1 + "\n"); + + for (Iterator ita = globalNets.iterator(); ita.hasNext(); ) { + GlobalNet gna = (GlobalNet)ita.next(); + gna.dumpInfo(bw1, s1 + "\t"); + } + + bw1.write(s1 + "}\n"); + } + catch(IOException e){ + System.out.println("IO exception thrown: " + e); + } + } + + + public double getGateCap() + { + assert getGlobalNets().size() == 1 + : "Port net should not call this function."; + + GlobalNet gna = (GlobalNet) getGlobalNets().get(0); + + double gateCap = 0.0; + + for (Iterator ita = gna.getListSinks().iterator(); ita.hasNext(); ) { + NetSink nska = (NetSink)ita.next(); + if(nska.type == NetType.HALF_OPERATOR_TRANSISTOR){ + NetGraph.NetEdge nea = nska.transistor; + gateCap += nea.width / nea.shareCount; + } + assert nska.type != NetType.CELL + : "Netsink of type CELL should be cleared at this stage"; + if(nska.type == NetType.CAPACITIVE_LOAD){ + // System.out.println("Warning: Netsink of type CAPACITIVE_LOAD should not exist in testbenchs"); + } + + } + + return gateCap; + } + + + public double getWireCap() + { + assert getGlobalNets().size() == 1 + : "Port net should not call this function."; + + return ((GlobalNet) getGlobalNets().get(0)).getWireCapacitance(); + } + + + public double getWireRes() + { + assert getGlobalNets().size() == 1 + : "Port net should not call this function."; + + return ((GlobalNet) getGlobalNets().get(0)).getWireResistance(); + } + + + + // Used by cast design to correct names that aren't local names or + // wiring cell names. + void changeToSubcellconnection(HierName h, boolean wiring) { + if (wiring) { + if (wiringConnectionNames == Collections.EMPTY_SET) { + wiringConnectionNames = new TreeSet(); + } + wiringConnectionNames.add(h); + } else if (internalNames.contains(h)) { + internalNames.remove(h); + subcellconnectionNames.add(h); + } + } + + // We want the same notion of most canonical as the NetGraph uses. + // While it may be prettier to have names in the port list have + // priority, it breaks things. + private HierName getMostCanonical() { + Set/**/ allNames = new TreeSet/**/(); + allNames.addAll(internalNames); + allNames.addAll(portNames); + return (HierName) findCannon(allNames); + } + + private HierName findCannon(Set names) { + Iterator i = names.iterator(); + HierName best = null; + if (i.hasNext()) { + best = (HierName) i.next(); + } + while (i.hasNext()) { + HierName next = (HierName) i.next(); + if (next.compareTo(best) < 0) { + best = next; + } + } + return best; + } + + /** + * returns constant capacitance value assigned by load directives + **/ + public double getAssignedLoad() + { + return 0.0; + } + + + + public boolean hasOnlyCellTypeSources() + { + if(listSources.size() == 0){ + return false; + } + + for (Iterator ita = listSources.iterator(); ita.hasNext(); ) { + NetSource nsra = (NetSource)ita.next(); + if(nsra.getType() != NetType.CELL){ + return false; + } + } + + return true; + } + + + + public Set/**/ getHalfOperatorSinks() + { + Set/**/ seta = new LinkedHashSet/**/(); + + for (Iterator ita = listSinks.iterator(); ita.hasNext(); ) { + NetSink nska = (NetSink)ita.next(); + if(nska.getType() == NetType.HALF_OPERATOR_TRANSISTOR){ + seta.add(nska); + } + } + + return seta; + + } + + + public boolean hasSinkAs(HalfOperator ho1) + { + for (Iterator ita = listSinks.iterator(); ita.hasNext(); ) { + NetSink nska = (NetSink)ita.next(); + if(nska.getType() == NetType.HALF_OPERATOR_TRANSISTOR){ + if(nska.sink == ho1){ + return true; + } + } + } + + return false; + } + + + + /** + Gets all the ConnectionInfo objects the connect the encapsulated net to a net in a subcell. + @see com.avlsi.fast.ConnectionInfo + @return A set containing ConnectionInfo instances for all the subcell instances + that the encapsulated net connects to. + */ + public Set getSubcellsConnectedTo( ) { + return container.getSubcellsConnectedTo( canonicalName ); + } + + + public final boolean isObservable() + { + return isObservable; + } + + + public final boolean setIsObservable(boolean b1) + { + isObservable = b1; + + return isObservable; + } + + + public final boolean isStaticized() + { + LinkedHashSet/**/ seta = + new LinkedHashSet/**/(); + + for (Iterator ita = getGlobalNets().iterator(); ita.hasNext(); ) { + GlobalNet gna = (GlobalNet)ita.next(); + + for (Iterator itb = gna.getListSources().iterator(); itb.hasNext(); ) { + NetSource nsra = (NetSource)itb.next(); + + if(nsra.getType() == NetType.HALF_OPERATOR_TRANSISTOR){ //half-operator-type net source + seta.add(nsra.source); + } + } + } + + for (Iterator ita = seta.iterator(); ita.hasNext(); ) { + HalfOperator hoa = (HalfOperator)ita.next(); + NetGraph.NetNode nna = hoa.outputNode; + + if(nna.isStaticized()){ + return true; + } + } + + return false; + } + + public final boolean isCutPath() { + return cutpath; + } + + public final boolean setCutPath(boolean v) { + cutpath = v; + return cutpath; + } + + private final Double getLocalNodeDirective(final String dir) { + final Map m = DirectiveUtils.getSubcellDirective(container.cast_cell, dir, DirectiveConstants.NODE_TYPE); + for (Iterator i = internalNames.iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + final Float f = (Float) m.get(name); + if (f != null) { + return new Double(f.doubleValue()); + } + } + return null; + } + + private final Float findMatchingName(final Map prsDirs, + final Map subcellDirs, + final Map topDirs, + final Set/**/ names, + Float val, + final BinaryFunction combine) { + for (Iterator i = names.iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + + // Jauto does not model a wire as segments, each of which may have + // different wiring attributes, as is partially expressible by + // directives; instead, we use the most conservative wiring + // attributes, and ignore where the directives are specified. + final Float prsVal = (Float) prsDirs.get(name); + if (prsVal != null) + val = val == null ? prsVal + : (Float) combine.execute(prsVal, val); + + final Float subcellVal = (Float) subcellDirs.get(name); + if (subcellVal != null) + val = val == null ? subcellVal + : (Float) combine.execute(subcellVal, val); + + final Float topVal = (Float) topDirs.get(name); + if (topVal != null) + val = val == null ? topVal + : (Float) combine.execute(topVal, val); + } + return val; + } + + private final double getWireAttr(final String dir, + final Float def, + final BinaryFunction combine) { + // Each of the wire attributes may be defined in the top-level cell, + // the subcells block, and the prs block. + final Map prs = + DirectiveUtils.containsDirective(container.cast_cell, + BlockInterface.PRS, dir, + DirectiveConstants.NODE_TYPE) ? + DirectiveUtils.getPrsDirective(container.cast_cell, dir, + DirectiveConstants.NODE_TYPE) + : Collections.EMPTY_MAP; + + final Map subcell = + DirectiveUtils.containsDirective(container.cast_cell, + BlockInterface.SUBCELL, dir, + DirectiveConstants.NODE_TYPE) ? + DirectiveUtils.getSubcellDirective(container.cast_cell, dir, + DirectiveConstants.NODE_TYPE) + : Collections.EMPTY_MAP; + + final Map top = + DirectiveUtils.containsDirective(container.cast_cell, + BlockInterface.CELL, dir, + DirectiveConstants.NODE_TYPE) ? + DirectiveUtils.getTopLevelDirective(container.cast_cell, dir, + DirectiveConstants.NODE_TYPE) + : Collections.EMPTY_MAP; + + Float result = null; + + /* XXX: The directives at the top-level can only parameterize on + * port nodes. However, what names go into internalNames, and what + * go into portNames is confusing. For example, if e1of4 -L is in + * the port list, then L.d[1] is in portNames, but L.1 is in + * internalNames. Thus, we need to check both sets. */ + result = findMatchingName(prs, subcell, top, internalNames, result, + combine); + result = findMatchingName(prs, subcell, top, portNames, result, + combine); + result = findMatchingName(prs, subcell, top, subcellconnectionNames, + result, combine); + + if (result == null) result = def; + + return result == null ? -1 : result.doubleValue(); + } + + private final double getWireAttr(final String dir, + final BinaryFunction combine) { + return getWireAttr(dir, null, combine); + } + + // Cached wire attributes associated with this net + private double assignedMinWireLength = Double.NaN; + private double assignedMinWireSpan = Double.NaN; + private double assignedWireLength = Double.NaN; + private double assignedWireSpan = Double.NaN; + private double internalWireLength = Double.NaN; + private double assignedWireWidth = Double.NaN; + private double assignedWireSpace = Double.NaN; + private double assignedLoadCap = Double.NaN; + private double resistanceScale = Double.NaN; + + public final double getAssignedMinWireLength(){ + if (Double.isNaN(assignedMinWireLength)) + assignedMinWireLength = + getWireAttr(DirectiveConstants.MIN_WIRELENGTH, + DirectiveUtils.MAX); + assert !Double.isNaN(assignedMinWireLength); + return assignedMinWireLength; + } + + public final double getAssignedMinWireSpan(){ + if (Double.isNaN(assignedMinWireSpan)) + assignedMinWireSpan = + getWireAttr(DirectiveConstants.MIN_WIRESPAN, + DirectiveUtils.MAX); + assert !Double.isNaN(assignedMinWireSpan); + return assignedMinWireSpan; + } + + public final double getAssignedWireLength(){ + if (Double.isNaN(assignedWireLength)) + assignedWireLength = getWireAttr(DirectiveConstants.WIRELENGTH, + DirectiveUtils.MAX); + assert !Double.isNaN(assignedWireLength); + return assignedWireLength; + } + + public final double getAssignedWireSpan(){ + if (Double.isNaN(assignedWireSpan)) + assignedWireSpan = getWireAttr(DirectiveConstants.WIRESPAN, + DirectiveUtils.MAX); + assert !Double.isNaN(assignedWireSpan); + return assignedWireSpan; + } + + public final double getInternalWireLength() { + if (Double.isNaN(internalWireLength)) { + double internal = -1; + double external = -1; + if (isPortNet() && !isGND() && !isVdd()) { + if (container.isInternalEnv()) { + final Float defValue = (Float) + DirectiveUtils.getTopLevelDirective( + container.cast_cell, + DirectiveConstants.INTERNAL_WIRELENGTH); + internal = + getWireAttr(DirectiveConstants.INTERNAL_WIRELENGTH, + defValue, DirectiveUtils.MAX); + } + if (container.design.getRealTopCell() == container) { + final Float defValue = (Float) + DirectiveUtils.getTopLevelDirective( + container.cast_cell, + DirectiveConstants.EXTERNAL_WIRELENGTH); + external = + getWireAttr(DirectiveConstants.EXTERNAL_WIRELENGTH, + defValue, DirectiveUtils.MAX); + } + } + internalWireLength = Math.max(internal, external); + } + assert !Double.isNaN(internalWireLength); + return internalWireLength; + } + + public final double getAssignedWireWidth(){ + if (Double.isNaN(assignedWireWidth)) + assignedWireWidth = getWireAttr(DirectiveConstants.WIREWIDTH, + DirectiveUtils.MIN); + assert !Double.isNaN(assignedWireWidth); + return assignedWireWidth; + } + + public final double getAssignedWireSpace(){ + if (Double.isNaN(assignedWireSpace)) + assignedWireSpace = getWireAttr(DirectiveConstants.WIRESPACE, + DirectiveUtils.MIN); + assert !Double.isNaN(assignedWireSpace); + return assignedWireSpace; + } + + public final double getLoadCapacitance(){ + if (Double.isNaN(assignedLoadCap)) { + assignedLoadCap = getWireAttr(DirectiveConstants.LOADCAP, + DirectiveUtils.MAX); + if (assignedLoadCap < 0 && isPortNet() && !isGND() && !isVdd()) { + String dir = null; + if (container.isInternalEnv() && + (portDirection == INPUT || portDirection == INPUTOUTPUT)) { + dir = DirectiveConstants.INTERNAL_LOADCAP; + } + if (container.design.getRealTopCell() == container && + (portDirection == OUTPUT || portDirection == INPUTOUTPUT)) { + dir = DirectiveConstants.EXTERNAL_LOADCAP; + } + if (dir != null) { + final Float defValue = (Float) + DirectiveUtils.getTopLevelDirective( + container.cast_cell, dir); + assignedLoadCap = + getWireAttr(dir, defValue, DirectiveUtils.MAX); + } + } + } + assert !Double.isNaN(assignedLoadCap); + return assignedLoadCap; + } + + public final double getResistanceScale() { + if (Double.isNaN(resistanceScale)) { + final Double val = + getLocalNodeDirective(DirectiveConstants.RESISTANCE_SCALE); + resistanceScale = val == null ? 1.0 : val.doubleValue(); + } + assert !Double.isNaN(resistanceScale); + return resistanceScale; + } + + public final void setUpSize(final double upSize) { + Debug.assertTrue(upSize >= 0, "Invalid upSize " + upSize); + this.upSize = upSize; + } + + public double getUpSize() { + return upSize; + } + + public final void setDownSize(final double downSize) { + Debug.assertTrue(downSize >= 0, "Invalid downSize " + downSize); + this.downSize = downSize; + } + + public double getDownSize() { + return downSize; + } + + public double getUpMinDelay() { + Map mindelay = DirectiveUtils.getPrsDirective(container.cast_cell, DirectiveConstants.MINDELAY, DirectiveConstants.HALFOP_TYPE); + Map ups = DirectiveUtils.getUps(mindelay); + Map canon = DirectiveUtils.canonizeKey(container.namespace, ups); + final Float val = (Float) canon.get(canonicalName); + return val == null ? -1 : val.doubleValue(); + } + + public double getDownMinDelay() { + Map mindelay = DirectiveUtils.getPrsDirective(container.cast_cell, DirectiveConstants.MINDELAY, DirectiveConstants.HALFOP_TYPE); + Map downs = DirectiveUtils.getDowns(mindelay); + Map canon = DirectiveUtils.canonizeKey(container.namespace, downs); + final Float val = (Float) canon.get(canonicalName); + return val == null ? -1 : val.doubleValue(); + } + + /** + * Returns the value of the strengthbias directive for + * the up half-operator for this node, or 1.0 if no + * directive was specified. + * + * @return The strenthbias for the up half-operator for this node. + **/ + public double getUpStrengthBias() { + Map strengthbias = DirectiveUtils.getPrsDirective(container.cast_cell, DirectiveConstants.STRENGTHBIAS, DirectiveConstants.HALFOP_TYPE); + Map ups = DirectiveUtils.getUps(strengthbias); + Map canon = DirectiveUtils.canonizeKey(container.namespace, ups); + final Float val = (Float) canon.get(canonicalName); + return val == null ? 1.0 : val.doubleValue(); + } + + /** + * Returns the value of the strengthbias directive for + * the down half-operator for this node, or 1.0 if no + * directive was specified. + * + * @return The strenthbias for the down half-operator for this node. + **/ + public double getDownStrengthBias() { + Map strengthbias = DirectiveUtils.getPrsDirective(container.cast_cell, DirectiveConstants.STRENGTHBIAS, DirectiveConstants.HALFOP_TYPE); + Map downs = DirectiveUtils.getDowns(strengthbias); + Map canon = DirectiveUtils.canonizeKey(container.namespace, downs); + final Float val = (Float) canon.get(canonicalName); + return val == null ? 1.0 : val.doubleValue(); + } + + private double upExtraDelay = Double.NaN; + private double dnExtraDelay = Double.NaN; + + private void initializeExtraDelay() { + if (CellUtils.isLeaf(container.cast_cell)) { + // Do not retrieve extra delay for leaf cell, as that is already + // taken into account by CellDelay + upExtraDelay = 0; + dnExtraDelay = 0; + } else { + final Map xdelay = + DirectiveUtils.getSubcellDirective(container.cast_cell, + DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE); + Map canon; + Float val; + + canon = DirectiveUtils.canonizeKey(container.namespace, + DirectiveUtils.getUps(xdelay)); + val = (Float) canon.get(canonicalName); + upExtraDelay = val == null ? 0 : val.doubleValue(); + + canon = DirectiveUtils.canonizeKey(container.namespace, + DirectiveUtils.getDowns(xdelay)); + val = (Float) canon.get(canonicalName); + dnExtraDelay = val == null ? 0 : val.doubleValue(); + } + } + + public double getUpExtraDelay() { + if (Double.isNaN(upExtraDelay)) initializeExtraDelay(); + assert !Double.isNaN(upExtraDelay); + return upExtraDelay; + } + + public double getDownExtraDelay() { + if (Double.isNaN(dnExtraDelay)) initializeExtraDelay(); + assert !Double.isNaN(dnExtraDelay); + return dnExtraDelay; + } + + public double getUpDelay() + { + List/**/ lsta = getGlobalNets(); + if(lsta.size() > 1){ // This function is only valid for internal nets or primary outputs + return -1.0; + } + + return ((GlobalNet) lsta.get(0)).getUpDelay(); + } + + + public double getDownDelay() + { + List/**/ lsta = getGlobalNets(); + if(lsta.size() > 1){ // This function is only valid for internal nets or primary outputs + return -1.0; + } + + return ((GlobalNet) lsta.get(0)).getDownDelay(); + } + + public HierName getInternalCanonical() { + if (internalNames.size() > 0) { + return findCannon(internalNames); + } else { + // A cell was declared without a port list + final Set/**/ names = new HashSet/**/(); + for (Iterator i = subcellconnectionNames.iterator(); i.hasNext(); ) + { + final HierName port = (HierName) i.next(); + final ConnectionInfo ci = + (ConnectionInfo) container.subcellports.get(port); + final HierName child = ci.getChildName(port); + if (ci.child.getNet(child).portNames.contains(child)) { + names.add(port); + } + } + return findCannon(names); + } + } + + + /** + * Get the strength ratios. Used to generate a warning message. + **/ + public Pair/**/ getStrengthRatios() + { + List/**/ lsta = new ArrayList/**/(); + + for (Iterator ita = getListSources().iterator(); ita.hasNext(); ) { + NetSource nsra = (NetSource)ita.next(); + if(nsra.getType() == NetType.HALF_OPERATOR_TRANSISTOR){ + lsta.add(nsra); + } + } + + if(lsta.size() < 2){ + Double negOne = new Double(-1.0); + return new Pair/**/(negOne, negOne); + } + + double maxStrengthP = Double.NEGATIVE_INFINITY; + double minStrengthP = Double.POSITIVE_INFINITY; + double maxStrengthN = Double.NEGATIVE_INFINITY; + double minStrengthN = Double.POSITIVE_INFINITY; + + for (Iterator ita = lsta.iterator(); ita.hasNext(); ) { + NetSource nsra = (NetSource)ita.next(); + + HalfOperator hoa = nsra.source; + // getStrength() actually returns the "effective resistance", + // so we should inverse it to get the "real" strength + double strength = 1.0 / hoa.getStrength(); + + if (hoa.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + if (strength > maxStrengthN) + maxStrengthN = strength; + + if (strength < minStrengthN) + minStrengthN = strength; + } + else{ + if (strength > maxStrengthP) + maxStrengthP = strength; + + if (strength < minStrengthP) + minStrengthP = strength; + } + } + + Double ratioPN; + if (maxStrengthP == Double.NEGATIVE_INFINITY || + minStrengthN == Double.POSITIVE_INFINITY) { + ratioPN = new Double(-1.0); + } + else{ + ratioPN = new Double(maxStrengthP / minStrengthN); + } + + Double ratioNP; + if (maxStrengthN == Double.NEGATIVE_INFINITY || + minStrengthP == Double.POSITIVE_INFINITY) { + ratioNP = new Double(-1.0); + } + else{ + ratioNP = new Double(maxStrengthN / minStrengthP); + } + + return new Pair/**/(ratioPN, ratioNP); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellType.java new file mode 100644 index 0000000000..10d668b203 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellType.java @@ -0,0 +1,1928 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.NoSuchElementException; +import java.io.*; + +import com.avlsi.io.FileSearchPath; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveSource; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellDelay; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.ObjectUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.geometry.BoundingBox; + +import com.avlsi.tools.jauto.*; +import com.avlsi.tools.jauto.AutoThreshold; +/** + * Class to represent a node in the cast cell refinement hierarchy. + * + * Need not be a "cell", just a holder for information common to many + * cells, such as technology constants, or leaf cell parameters. + * + * May also be a subtype of cell, or a subtype of a subtype. + * + * This is also a node in the instantiation hierarchy, which is a DAG. + * + * @author Aaron Denney + * @version $Date$ + **/ + +public final class CellType { + /** + * Encapsulates a port. A port is direction, and a CellNet. + **/ + public static final class PortInfo { + private final CellNet m_Net; + + public static int INPUT = 0; + public static int OUTPUT = 1; + public static int INPUT_OUTPUT = 2; + public static int UNKNOWN = 3; + + private final int m_PortType; + + public BoundingBox bBox; + + public PortInfo( final CellNet net, int portType ) { + m_Net = net; + m_PortType = portType; + Debug.assertTrue( ( portType == INPUT ) || + ( portType == OUTPUT ) || + ( portType == INPUT_OUTPUT ) || + ( portType == UNKNOWN ) ); + } + + public int getType() { + return m_PortType; + } + + public CellNet getNet() { + return m_Net; + } + + } + + public interface PortInfoIterator { + boolean hasNext(); + /** @throws NoSuchElementException **/ + PortInfo next(); + } + + /** flags for creating a new type from an existing type. **/ + private static final int REFINEMENT=0, SIBLING=1; + + /** the design we are part of. **/ + public final CastDesign design; + + /** Temporary. Will be removed with new parser. **/ + public final CellInterface cast_cell; + + // Refinement hierarchy. + + /** the CellType we refine. **/ + public final CellType prototype; + + /** the CellType that are refinements of us. **/ + public final List/**/ refinements; + + /** + * how many refinements have been created. + * Also index for next anonymous derived cell. + **/ + int subtypeCount = 0; + + /** + * name of this cell type. Anonymous derived cells have the form + * <prototype's name>:<count> + **/ + public final String typeName; + + /** manually created, or automatic. **/ + public final boolean manual; + + /** which subtype is this? **/ + public final int subtypenumber; + + // Actual data! + + /** The available blocks. **/ + protected final Map/**/ _blocks = + new HashMap/**/(); + public final Map/**/ blocks = + Collections.unmodifiableMap(_blocks); + + // The blocks with explicit typing information. + + // Instantiation DAG. + + /** + * connections to subcells. Instantiation DAG. "Name" -> + * "subcellconnection" + **/ + final Map subcellconnections; + + /** + * names of subcellports -> connectioninfo. Follow to traverse nets. + **/ + final Map/**/ subcellports; + + /** + * connections to parent instances. Backpointers for Instantiation DAG. + **/ + final List/**/ parentcellconnections; + + // Node and name information. + + /** production rules for this cell type. **/ + + public final ProductionRuleSet prs; + + /** which names are aliased together? **/ + public final AliasedSet/**/ namespace; + + /** names of nodes ... map hier names -> nodes structure. **/ + public final Map/**/ nets; + + /** Maps CellNet to PortInfo.*/ + private final Map/**/ ports; + + /** all nets. **/ + public final Set/**/ allNets; + + // Subtype-specific information. + + public NetGraph transistors; + + // list of all the halfoperators in this cell + public ArrayList listHalfOperators; + + // set of sizing paths belong to this cell + public Set/**/ sizingPaths; + + // set of concatenated paths belong to this cell + public Set/**/ catPaths; + + // set of reduced (simplified) concatenated paths belong to this cell + public Set/**/ reducedCatPaths; + + // list of all the halfoperators in the concatenated paths of this cell + public Set/**/ setSizingHalfOperators; + + // strength_group directive + private final AliasedSet strengthGroup; + + /** is this cell "fragment"? **/ + boolean isFragment = false; + + /** size of cell. **/ + public float xSize = 0, ySize = 0; + + /** cell level cached here. **/ + private int level = -1; + + /** + * Are we a "wiring cell"? That is, no transistors, and non in subcells. + * Used strictly to collect wires and names for wires. e1ofN, TWIST, BGZ, + * etc. + **/ + public final boolean isWiringCell; + + /** + * ExclusiveNodeSets, from CellInterface, via Cadencize. + **/ + public final ExclusiveNodeSets exclusives; + + /** Names of Vdd, GND, and _RESET */ + private final HierName Vdd, GND, _RESET; + + /** Cadencize to use */ + private final Cadencize cad; + + /** Information relayed to delays. Include delaybias, cell delaybias, + * extra_delay. + **/ + private final CellDelay delay; + + /** + * Is this cell a synthesized internal environment + **/ + private final boolean isInternalEnv; + + private static Map/**/ makePortMap( + final Set/**/ netSet) { + //Iterate over all the nets and put ones that are ports into + //this map. + final Map/**/ ports = + new HashMap/**/(); + + for (final Iterator netIter = netSet.iterator(); netIter.hasNext(); ) { + final CellNet currNet = ( CellNet ) netIter.next(); + + int portType; + + switch( currNet.portDirection ) { + case CellNet.INPUT: + portType = PortInfo.INPUT; + break; + + case CellNet.OUTPUT: + portType = PortInfo.OUTPUT; + break; + + case CellNet.INPUTOUTPUT: + portType = PortInfo.INPUT_OUTPUT; + break; + + case CellNet.UNKNOWN: + portType = PortInfo.UNKNOWN; + break; + + default: + throw new AssertionError("Unknown port direction " + + currNet.portDirection); + } + + ports.put( currNet, new PortInfo( currNet, portType ) ); + } + + return ports; + + } + + /** + * Constructor based on Cast Parser. + * + * package visibility, as it should only be invoked via CastDesign. + **/ + CellType(CastDesign d, Cadencize c, CellInterface cell, HierName Vdd, HierName GND, HierName _RESET, boolean isInternalEnv, boolean useAstaExtraDelay) { + this.Vdd = Vdd; + this.GND = GND; + this._RESET = _RESET; + this.isInternalEnv = isInternalEnv; + // Cast V1 has no refinements. + this.prototype = null; + this.design = d; + this.prs = cell.getProductionRuleSet(); + this.typeName = cell.getFullyQualifiedType(); + this.isWiringCell = CellUtils.isWiring(cell); + this.cad = c; + CadenceInfo ci = c.convert(cell); + this.namespace = ci.getLocalNodes(); + this.nets = nodeFactory(ci, cell); + if (cell.containsNetlist()) { + final Template templ = ((NetlistBlock) cell.getBlockInterface().iterator(BlockInterface.NETLIST).next()).getCanonicalTemplate(c); + nodeNetlistFactory(this.nets, templ); + } + // Useful, because its the only list of all the nets without duplicates. + this.allNets = new TreeSet/**/(CellNet.getComparator()); + this.allNets.addAll(this.nets.values()); + // Work to get rid of this. + this.cast_cell = cell; + this.refinements = new ArrayList(); + this.subtypenumber = this.subtypeCount = 0; + this.transistors = null; + this.exclusives = new ExclusiveNodeSets(); + this.exclusives.merge(ci.getPortExclusiveNodeSets()); + this.exclusives.merge(ci.getLocalExclusiveNodeSets()); + + this.ports = makePortMap( allNets ); + + // FIXME: these are bogus. + + this.subcellports = new HashMap/**/(); + this.subcellconnections = new TreeMap(); + this.parentcellconnections = new ArrayList/**/(); + this.manual = false; + + this.listHalfOperators = new ArrayList(); + this.setSizingHalfOperators = new HashSet/**/(); + this.sizingPaths = new LinkedHashSet/**/(); + this.catPaths = new LinkedHashSet/**/(); + this.reducedCatPaths = new LinkedHashSet/**/(); + this.delay = + new CellDelay(cast_cell, + cad.convert(cast_cell).getLocalNodes(), + cast_cell.getProductionRuleSet().getProductionRules(), + Float.NaN, useAstaExtraDelay); + this.strengthGroup = initializeStrengthGroup(cast_cell); + + addCutPaths(); + } + + /** + * Constructor duplicating existing type. Private as it should only be + * invoked from functions here. + **/ + private CellType(CellType o, int how, Set overrides) { + this.Vdd = o.Vdd; + this.GND = o.GND; + this._RESET = o._RESET; + this.isInternalEnv = o.isInternalEnv; + this.parentcellconnections = new ArrayList/**/(); + this.refinements = new ArrayList(); + + this.subcellports = new HashMap/**/(); + this.isWiringCell = o.isWiringCell; + this.cad = o.cad; + this.exclusives = o.exclusives; + switch (how) { + case REFINEMENT: + this.prototype = o; + // FIXME: need to be equivalent refinements. + this.subcellconnections = o.subcellconnections; + this.nets = o.nets; + this.namespace = o.namespace; + break; + case SIBLING: + this.prototype = o.prototype; + // FIXME: need to make subcells point to me. + this.subcellconnections = o.subcellconnections; + // FIXME: need to make subcells point to me. + this.nets = o.nets; + this.namespace = o.namespace; + break; + default: + throw new AssertionError("invalid flag in duplicating constructor"); + } + this.prs = o.prs; + this.subtypenumber = this.prototype.subtypeCount++; + this.typeName = this.prototype.typeName + ":" + this.subtypenumber; + this.manual = true; + this.design = o.design; + this.cast_cell = null; + this.transistors = null; + this.allNets = new HashSet/**/( nets.values() ); + + this.ports = makePortMap( allNets ); + + this.listHalfOperators = o.listHalfOperators; + this.setSizingHalfOperators = o.setSizingHalfOperators; + this.sizingPaths = o.sizingPaths; + this.catPaths = o.catPaths; + this.reducedCatPaths = o.reducedCatPaths; + this.delay = o.delay; + this.strengthGroup = o.strengthGroup; + + addCutPaths(); + } + + public PortInfoIterator getPorts() { + return new PortInfoIterator() { + + private final Iterator portIter = ports.values().iterator(); + + public boolean hasNext() { + return portIter.hasNext(); + } + + public PortInfo next() { + return ( PortInfo ) portIter.next(); + } + }; + } + + private void initializeStrengthGroupHelper( + final MultiMap> grouped, + final Map directives, + final Integer pull) { + for (Map.Entry entry : directives.entrySet()) { + final Integer group = entry.getValue(); + if (group >= 0) { + grouped.put(group, + new Pair(getNet(entry.getKey()), + pull)); + } + } + } + + // Convert strength_group directives into an aliased set. Equivalent + // members in the aliased set are in the same group. Each member is a pair + // of CellNet and drive direction. + private AliasedSet initializeStrengthGroup(final CellInterface ci) { + final Map dir = DirectiveUtils.getPrsDirective(ci, + DirectiveConstants.STRENGTH_GROUP, + DirectiveConstants.HALFOP_TYPE); + final Map ups = (Map) + DirectiveUtils.canonizeKey(namespace, DirectiveUtils.getUps(dir)); + final Map dns = (Map) + DirectiveUtils.canonizeKey(namespace, DirectiveUtils.getDowns(dir)); + + final MultiMap> grouped = + new MultiMap>(); + initializeStrengthGroupHelper(grouped, ups, + HalfOperator.DriveDirection.PULL_UP); + initializeStrengthGroupHelper(grouped, dns, + HalfOperator.DriveDirection.PULL_DOWN); + + final AliasedSet result = new AliasedSet( + new Comparator>() { + public int compare(final Pair p1, + final Pair p2) { + int result = ObjectUtils.compare(p1.getSecond(), + p2.getSecond()); + if (result == 0) { + result = CellNet.getComparator().compare(p1.getFirst(), + p2.getFirst()); + } + + return result; + } + }); + for (Integer key : grouped.keySet()) { + final Collection> values = grouped.get(key); + Pair first = null; + for (Pair value : values) { + if (first == null) { + first = value; + result.add(first); + } else { + result.makeEquivalent(first, value); + } + } + } + + return result; + } + + /** + * Returns true if a half-operator driving net1 in the direction pull1 is + * in the same strength group as a half-operator driving net2 in the + * direction pull2. + **/ + boolean hasSameStrengthGroup(final CellNet net1, final int pull1, + final CellNet net2, final int pull2) { + return strengthGroup.areEquivalent( + new Pair(net1, pull1), + new Pair(net2, pull2)); + } + + public PortInfo getPortInfoForCellNet(CellNet n) { + return (PortInfo) ports.get(n); + } + + public PortInfo getPortInfoForPinNamed(HierName h) { + CellNet net = getNet(h); + return getPortInfoForCellNet(net); + } + + public PortInfo getPortInfoForPinNamed(String s) { + CellNet net = getNet(s); + return getPortInfoForCellNet(net); + } + + /** + * create all associated CellNets and stick them in parent. + **/ + private Map/**/ nodeFactory(CadenceInfo ci, CellInterface cell) { + HashMap/**/ nodes = new HashMap/**/(); + // What's described below should no long be necessary. But for + // historical purposes: + // + // This only gets the ones declared in the Cast, not globals. + // We don't use cadencize because it considers aliases of ports + // to be ports. Appropriate for its original purpose, but not + // for what we want. + // + // To get the other ones we + // *UGLY HACK WARNING* + // see if the name is global and only has one level, if so, it + // must be in the portlist. + Set/**/ cellPorts = collectPortNames(cell); + AliasedSet/**/ l = ci.getLocalNodes(); + for (Iterator i = l.getCanonicalKeys(); i.hasNext();) { + Set/**/ locals = new TreeSet/**/(); + Set/**/ ports = new TreeSet/**/(); + final HierName canon = (HierName) i.next(); + for (Iterator j = l.getAliases(canon); j.hasNext();) { + HierName name = (HierName)j.next(); + if (cellPorts.contains(name)) { + ports.add(name); + } else { + locals.add(name); + } + } + addCellNets(nodes, locals, ports, canon); + } + return nodes; + } + + /** + * Create all CellNets internal to a netlist block + **/ + private void nodeNetlistFactory(final Map/**/ nodes, final Template cell) { + cell.execute(Collections.EMPTY_MAP, new CDLSimpleInterface() { + private void addName(final HierName name) { + if (!name.isGenerated() && + !name.isNumeric() && + !nodes.containsKey(name)) { + final Set/**/ locals = + new TreeSet/**/(); + locals.add(name); + final HierName canon = + (HierName) namespace.getCanonicalKey(name); + addCellNets(nodes, locals, Collections.EMPTY_SET, + canon == null ? name : canon); + } + } + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + addName(n1); addName(n2); + } + public void makeCapacitor(HierName name, HierName npos, + HierName nneg, double val) { + addName(npos); addName(nneg); + } + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + addName(ns); addName(nd); addName(ng); addName(nb); + } + public void makeDiode(HierName name, int type, HierName npos, + HierName nneg, double w, double l, double a, + double p) { + addName(npos); addName(nneg); + } + public void makeInductor(HierName name, HierName npos, + HierName nneg, double val) { + addName(npos); addName(nneg); + } + public void makeBipolar(HierName name, int type, HierName nc, + HierName nb, HierName ne, double a) { + addName(nc); addName(nb); addName(ne); + } + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { + for (int i = 0; i < args.length; ++i) addName(args[i]); + } + public void beginSubcircuit(String subName, String[] in, + String[] out) { } + public void endSubcircuit(String subName) { } + }); + } + + private Set/**/ collectPortNames(CellInterface c) { + Set/**/ rv = new TreeSet/**/(); + collectPortNamesRecurse(null, c, rv); + return rv; + } + + private void collectPortNamesRecurse(HierName prefix, + CellInterface port, + Set/**/ ports) { + if (port.isNode()) { + HierName local = prefix; + ports.add(local); + } else { + for (Iterator i = port.getPortSubcellPairs(); i.hasNext();) { + Pair p = (Pair) i.next(); + HierName newh = (HierName) p.getFirst(); + CellInterface c = (CellInterface) p.getSecond(); + HierName local = HierName.append(prefix, newh); + collectPortNamesRecurse(local, c, ports); + } + } + } + + private void addCellNets(Map/**/ nodes, + Set/**/ l, + Set/**/ p, + HierName canon) { + CellNet n = new CellNet(CellType.this, l, p, + new TreeSet/**/(), canon, + Vdd, GND, _RESET); + for (Iterator j = l.iterator(); j.hasNext();) { + HierName h = (HierName) j.next(); + nodes.put(h, n); + } + for (Iterator j = p.iterator(); j.hasNext();) { + HierName h = (HierName) j.next(); + nodes.put(h, n); + } + } + + /** + * Gets (or creates) the default subtype for this cell. + * + * This will have sizing information if there are transistors to + * be sized. + **/ + CellType getDefaultSubType() { + if (refinements.isEmpty()) { + createDefaultSubType(); + } + return (CellType) refinements.get(0); + } + + /** + * creates a new automatic subtype. + * + * Calling context: after new completed. + **/ + private void createDefaultSubType() { + CellType st = new CellType(this, REFINEMENT, null); + st.ensureSizingBlock(); + refinements.add(st); + } + + // Block retrieval. + public BlockInterface getBlock(String name) { + return (BlockInterface) _blocks.get(name); + } + + // Technology block. + + /** + * Technology constants. + **/ + public float getUnitCapacitance() { + return 0; + } + + /** + * Technology constants. + **/ + public float getUnitResistance() { + return 0; + } + + // containment hierarchy manipulation. + /** + * create a new subtype that is a sibling to this one, with all + * values starting the same. + * + * @return a new cell that is a sibling of this one. + **/ + public CellType cloneAsSibling() { + return new CellType(this, SIBLING, null); + } + + /** + * removes this cell from instance hierarchy, replacing it with the + * other. + **/ + public void replaceWith(CellType other) { + // for all instances, paste other in instead. + // (instances, parents, but not prototypes, or what we instance.) + } + + /** + * ensure that we have sizing information. + **/ + private void ensureSizingBlock() { + } + + /** + * Get the net corresponding to a name s. + **/ + public CellNet getNet(String s) { + try { + return (CellNet) nets.get(HierName.makeHierName(s, '.')); + } catch (InvalidHierNameException e) { + throw new RuntimeException("makeHierName failed. Cannot happen!"); + } + } + + public CellNet getNet(HierName local) { + return (CellNet) nets.get(local); + } + + /** + * Translate a name to a string. + * + * @param local The name local to this cell. + * @return The name represented as a string. + **/ + public String getNameAsString(HierName h) { + return h.getAspiceString(); + } + + /** + * Walks the instance space, but visits each celltype at most once. + **/ + public void walkOnce(CellTypeProcessor p) { + HashSet/**/ s = new HashSet/**/(); + walkOnce(p, s); + } + + public void walkOnce(CellTypeProcessor p, Set/**/ s) { + if (s.contains(this)) return; + + if(DebugOption.printLevel <= 1){ + System.out.println("Note: walkOnce processing: " + this.typeName); + } + + s.add(this); + p.processCellType(this); + for (Iterator i = subcellconnections.values().iterator(); i.hasNext(); ) { + CellType c = ((ConnectionInfo) i.next()).child; + c.walkOnce(p, s); + } + } + + /** + * Walks the instance space, possibly visiting a given celltype multiple times. + **/ + public interface InstanceProcessor { + void processInstance(final CellType type, final HierName instance, + final Collection path); + } + + private void walkMany(InstanceProcessor p, HierName instance, + LinkedList path) { + p.processInstance(this, instance, path); + for (Iterator i = subcellconnections.values().iterator(); + i.hasNext(); ) { + final ConnectionInfo ci = (ConnectionInfo) i.next(); + path.addLast(ci); + ci.child.walkMany(p, HierName.append(instance, ci.nameInParent), + path); + path.removeLast(); + } + } + + public void walkMany(InstanceProcessor p) { + walkMany(p, null, new LinkedList()); + } + + /** + * @return the number of logically different places this celltype is instanced. + **/ + public int getLogicalInstanceCount() { + return parentcellconnections.size(); + } + + /** + * @return the number of physically different places this celltype is ever instanced. + **/ + public int getPhysicalInstanceCount() { + int count = parentcellconnections.size(); + if (count == 0) { + return 1; // assume top level cell. + } + count = 0; + for (Iterator i = parentcellconnections.iterator(); i.hasNext(); ) { + ConnectionInfo c = (ConnectionInfo) i.next(); + count += c.parent.getPhysicalInstanceCount(); + } + return count; + } + + /** + * Returns the list of pointers to all the half-operators in this cell + **/ + public ArrayList getListHalfOperators() { + return listHalfOperators; + } + + /** + * Returns the list of pointers to all the half-operators in the concatenated paths of this cell + **/ + public Set/**/ getSetHalfOperatorsInCatPaths() + { + return setSizingHalfOperators; + } + + /** + * For all the variables in the cell, set their "FIXED" properties + **/ + public void fixVariables() { + fixOrUnfixVariables(true); + } + + /** + * For all the variables in the cell, unset their "FIXED" properties + **/ + public void unfixVariables() { + fixOrUnfixVariables(false); + } + + private void fixOrUnfixVariables(boolean fix) { + // FIXME: possible cell/transistor mix in the future, don't use getLevel + if(getLevel() == 0){ + + for (Iterator ita = sizingPaths.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + if(!spa.isFragment()){ + for (Iterator itb = spa.getPath().iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + if (fix) + hoa.fixVariable(); + else + hoa.unfixVariable(); + } + } + } + } + else{ + + for (Iterator ita = reducedCatPaths.iterator(); ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + + if(!cpa.isFragment()){ + for (Iterator itb = cpa.getCatPath().iterator(); itb.hasNext(); ) { + SizingPath spa = (SizingPath)itb.next(); + + for (Iterator itc = spa.getPath().iterator(); itc.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itc.next(); + if (fix) + hoa.fixVariable(); + else + hoa.unfixVariable(); + } + } + } + } + } + } + + /** + * Check if the sizes of all transisors in the cell are converged + * Absolute differences + **/ + public boolean sizeConvergedAbs(double threshold) { + for (HalfOperator hoa : listHalfOperators) { + double delta = Math.abs(hoa.getCurrentSize() - hoa.getPreviousSize()); + if (delta > threshold) { + if(DebugOption.printLevel <= 1){ + System.out.println(toString()); + System.out.println("Current size: " + hoa.getCurrentSize()); + System.out.println("Previous size: " + hoa.getPreviousSize()); + } + return false; + } + } + + + return true; + } + + /** + * Check if the sizes of all transisors in the cell are converged + * Relative differences + **/ + public boolean sizeConvergedRel(double threshold) { + for (HalfOperator hoa : listHalfOperators) { + double delta = Math.abs(hoa.getCurrentSize() / hoa.getPreviousSize() - 1.0); + if (delta > threshold) { + if(DebugOption.printLevel <= 3){ + System.out.println("NOTE: Cell: " + + typeName + + " did not converge on: " + + hoa.outputNet.canonicalName.getCadenceString()); + System.out.println("Current size: " + hoa.getCurrentSize()); + System.out.println("Previous size: " + hoa.getPreviousSize()); + } + return false; + } + } + + + return true; + } + + /** + * Do we have a subcell named name? If so return it, else return null; + * + * @param name the name of the subcell. + * @return The ConnectionInfo corresponding to this instance of the cell. + **/ + public ConnectionInfo getSubcellNamed(HierName h) { + return (ConnectionInfo) subcellconnections.get(h); + } + + /** + * What are the subcells connected to the net named name? + * + * @param name the name of the net + * @return a set of ConnectionInfo that connect to this net. + **/ + public Set getSubcellsConnectedTo(HierName h) { + CellNet n = (CellNet) nets.get(h); + if (n == null) return null; + Set rv = new HashSet(); + for (Iterator i = n.subcellconnectionNames.iterator(); i.hasNext(); ) { + HierName j = (HierName) i.next(); + ConnectionInfo ci = (ConnectionInfo) subcellports.get(j); + if (ci != null) rv.add(ci); + } + return rv; + } + + /** + * What (if any) is the net in the subcell connected + * to this particular alias. + * + * @param name the name in the parent. + * @return the CellNet in the child, null if none. + **/ + public CellNet getSubcellNetConnectedTo(HierName h) { + ConnectionInfo ci = (ConnectionInfo) subcellports.get(h); + if (ci == null) return null; + HierName child = ci.getChildName(h); + if (child == null) return null; + return (CellNet) ci.child.getNet(child); + } + + public ConnectionInfo getSubcellConnectedTo(HierName h) { + return (ConnectionInfo) subcellports.get(h); + } + + /** + * Collection of all CellNets. + **/ + public Set/**/ getAllNets() { + return allNets; + } + + /** + * Collection of all SubcellConnections (ConnectionInfo) + **/ + public Collection getAllSubcellConnections() { + return subcellconnections.values(); + } + + + public Set/**/ getAllInstances() + { + return new HashSet/**/(getAllSubcellConnections()); + } + + /** + * all subcells. Usually not useful, as we generally want to know how they are connected. + **/ + public Set/**/ getAllSubcells() { + Collection/**/ c = getAllSubcellConnections(); + Set/**/ s = new HashSet/**/(c.size()); + for (Iterator i = c.iterator(); i.hasNext(); ) { + ConnectionInfo ci = (ConnectionInfo) i.next(); + s.add(ci.child); + } + return s; + } + + /** + * retrieve the "level" of this cell. + * + * The cell's level is one higher than the highest level of the subcells it contains. + * A leaf cell has level 0. + * + * @return The level of the cell. + **/ + public int getLevel() { + if (level < 0) { + calculateLevel(); + } + return level; + } + + /** + * Calculate the level of the cell. + **/ + private void calculateLevel() { + int max = -1; + for (Iterator i = getAllSubcells().iterator(); i.hasNext(); ) { + CellType c = (CellType) i.next(); + if (c.getLevel() > max) max = c.getLevel(); + } + level = max + 1; + } + + /** + * returns the set of (NetGraph.NetEdge) driven by (i.e. gated by) net n. + * + * FIXME: does not actually work yet. + **/ + public Set/**/ getTransistorsDrivenBy(CellNet n) { + throw new AssertionError(); + // Set/**/ s = new HashSet/**/(); + // // HierName h = n.getName(); + // HierName h = null; + // h = (HierName) namespace.getCanonicalKey(h); + // for (Iterator i = transistors.getEdges().iterator(); i.hasNext(); ) { + // NetGraph.NetEdge prospective = (NetGraph.NetEdge) i.next(); + // if (prospective.gate.name.equals(n)) { + // s.add(prospective); + // } + // } + // return s; + } + + public String toString() { + int numNonFragmentCatPaths = 0; + + for (Iterator ita = catPaths.iterator(); ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + if(!cpa.isFragment()){ + ++numNonFragmentCatPaths; + } + } + + return "Cell name: " + typeName + "\n" + + "Subtype index: " + subtypenumber + "\n" + + "Hier level: " + getLevel() + "\n" + + "Number of Half-operators: " + listHalfOperators.size() + "\n" + + "Number of sizing paths: " + sizingPaths.size() + "\n" + + "Number of concatenated paths: " + catPaths.size() + "\n" + + "Number of non-fragment concatenated paths: " + numNonFragmentCatPaths + "\n" + + "Number of reduced concatenated paths: " + reducedCatPaths.size() + "\n"; + +// return typeName + ":" + subtypenumber; + } + + + public void dumpInfo(BufferedWriter bw1, String prefix) + { + try{ + bw1.write(prefix + "CELL " + typeName + " {\n"); + bw1.write(prefix + "\tsubtype_index = " + subtypenumber + ";\n"); + bw1.write(prefix + "\thier_level = " + getLevel() + ";\n"); + bw1.write(prefix + "\tn_half_operators = " + listHalfOperators.size() + ";\n"); + + // FIXME: possible cell/transistor mix in the future, don't use getLevel + if(getLevel() == 0){ + bw1.write(prefix + "\tn_sizing_paths = " + sizingPaths.size() + ";\n"); + } + else{ + bw1.write(prefix + "\tn_cat_paths = " + catPaths.size() + ";\n"); + bw1.write(prefix + "\tn_non_fragment_cat_paths = " + catPaths.size() + ";\n"); + bw1.write(prefix + "\tn_reduced_cat_paths = " + reducedCatPaths.size() + ";\n"); + } + + bw1.write(prefix + "\n"); + + for (Iterator ita = allNets.iterator(); ita.hasNext(); ) { + CellNet cna = (CellNet)ita.next(); + cna.dumpInfo(bw1, prefix + "\t"); + } + + bw1.write(prefix + "\n"); + + // FIXME: possible cell/transistor mix in the future, don't use getLevel + if(getLevel() == 0){ + for (Iterator ita = sizingPaths.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + spa.dumpInfo(bw1, prefix + "\t"); + } + + bw1.write(prefix + "\n"); + } + + else{ + // ita = catPaths.iterator(); + for (Iterator ita = reducedCatPaths.iterator(); ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + cpa.dumpInfo(bw1, prefix + "\t"); + } + + bw1.write(prefix + "\n"); + } + + bw1.write(prefix + "}\n"); + } + catch(IOException e){ + System.out.println("IO exception thrown: " + e); + } + } + + + + + public void print() + { + System.out.println("Cell name: " + typeName); + System.out.println("Subtype index: " + subtypenumber); + System.out.println("Hier level: " + getLevel()); + // for (Iterator i = allNets.iterator(); i.hasNext(); ) { + // CellNet n = (CellNet) i.next(); + // n.print(); + // } + System.out.println(); + + } + + /** + * Creates a new instance graph with each cell being a refinement of the + * corresponding cell in the original graph. + * + * At most one refinement per cell. + * + * @param flags What things the new instance hierarchy should have. + * @return the subtype of the top-level cell. + **/ + public CellType instanceMinimalSubTypes(int flags, + String staticizer, + String weakInverter, + String smallInverter, + String[] gates, + CastFileParser cfp, + UnaryPredicate netlistFromPrs) { + return instanceMinimalSubTypes(flags, staticizer, weakInverter, + smallInverter, gates, cfp, + netlistFromPrs, null); + } + + public CellType instanceMinimalSubTypes( + int flags, + String staticizer, + String weakInverter, + String smallInverter, + String[] gates, + CastFileParser cfp, + UnaryPredicate netlistFromPrs, + Map autoThresholdOptions) { + + minimalInstancer m = + new minimalInstancer(staticizer, weakInverter, smallInverter, + gates, Vdd, GND, cfp, cad, netlistFromPrs, + autoThresholdOptions); + walkOnce(m, design.allCellTypes); + + // generate half-operators for all the cells + design.generateHalfOperators(design.allCellTypes); + + // Annotate all port cellnets with I/O directions + CastDesign.addPortDirection(design.allCellTypes); + + // Generate source/sink lists for cellnets + design.generateSourceSinkLists(design.allCellTypes); + + // Mark non-observable port nets + CastDesign.markNonObservablePorts(design.allCellTypes); + + + return m.newt; + } + + public CellType instanceMinimalSubTypes(int flags, + String staticizer, + String weakInverter, + String smallInverter, + String[] gates, + CastFileParser cfp) { + return instanceMinimalSubTypes(flags, staticizer, weakInverter, smallInverter, + gates, cfp, new UnaryPredicate.Constant(false)); + } + + private static class minimalInstancer implements CellTypeProcessor { + CellType newt; + final HierName Vdd, GND; + NetGraph staticizer; + NetGraph weakInverter; + NetGraph smallInverter; + NetGraph[] gates; + final CastFileParser cfp; + final Cadencize cad; + final UnaryPredicate netlistFromPrs; + final Map autoThresholdOptions; + + /** + * Constructor + * + */ + public minimalInstancer( + String staticizer, String weakInverter, + String smallInverter, + String[] gates, HierName Vdd, HierName GND, + CastFileParser cfp, Cadencize cad , + UnaryPredicate netlistFromPrs, + Map autoThresholdOptions) { + if (staticizer==null) this.staticizer=null; + else try { + this.staticizer = CastDesign.getGateNetGraph(cfp, staticizer, Vdd, GND, cad); + } catch (Exception e) { + this.staticizer = null; + System.err.println("WARNING: Cannot load staticizer " + staticizer); + } + if (weakInverter==null) this.weakInverter=null; + else try { + this.weakInverter = CastDesign.getGateNetGraph(cfp, weakInverter, Vdd, GND, cad); + } catch (Exception e) { + this.weakInverter = null; + System.err.println("WARNING: Cannot load weak-inverter " + weakInverter); + } + if (smallInverter==null) this.smallInverter=null; + else try { + this.smallInverter = CastDesign.getGateNetGraph(cfp, smallInverter, Vdd, GND, cad); + } catch (Exception e) { + this.smallInverter = null; + System.err.println("WARNING: Cannot load small inverter " + smallInverter); + } + List gs = new ArrayList(); + for (int i = 0; i < gates.length; i++) { + try { + NetGraph g = CastDesign.getGateNetGraph(cfp, gates[i], Vdd, GND, cad); + gs.add(g); + } catch (Exception e) { + System.err.println("WARNING: Cannot load gate " + gates[i]); + } + } + this.gates = new NetGraph[gs.size()]; + for (int i=0; i,Integer> getTransistorTypes( + final String typeName, + final int tt, + final int ftt, + final int stt, + final Map ttup, + final Map ttdn, + final Map is, + final NetGraph transistors, + final List halfops, + final Map options) { + final Map,Integer> result = + AutoThreshold.getTransistorTypesMap(typeName,is, + transistors,stt,tt,ftt,ttup,ttdn,halfops,options); + System.out.println("Result Map:" + +result); + + return result; + } + + // Compute additional transistor_type directives + private void updateTransistorTypes(final CellType c) { + // default transistor type + final Integer tt = (Integer) + DirectiveUtils.getTopLevelDirective(c.cast_cell, + DirectiveConstants.TRANSISTOR_TYPE); + + // fast transistor type + final Integer ftt = (Integer) + DirectiveUtils.getTopLevelDirective(c.cast_cell, + DirectiveConstants.FAST_TRANSISTOR_TYPE); + + // slow transistor type + final Integer stt = (Integer) + DirectiveUtils.getTopLevelDirective(c.cast_cell, + DirectiveConstants.SLOW_TRANSISTOR_TYPE); + + // nothing to do if all transistor types are identical + if (tt.intValue() == ftt.intValue() && + tt.intValue() == stt.intValue()) return; + + // existing transistor_type directives + final Map ttype = DirectiveUtils.getPrsDirective(c.cast_cell, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.HALFOP_TYPE); + final Map ttup = DirectiveUtils.canonizeKey(c.namespace, + DirectiveUtils.getUps(ttype)); + final Map ttdn = DirectiveUtils.canonizeKey(c.namespace, + DirectiveUtils.getDowns(ttype)); + + // idle_state directives + final Map is = + DirectiveUtils.getIdleState(c.cast_cell, c.namespace); + + // create half-operators to determine transistor sharing + c.design.generateHalfOperator(c); + + // from idle_state directives, assign slow or fast transistor type + // to each half-operator, existing transistor_type directives from + // the user overrides + final Map,Integer> results = + getTransistorTypes(c.typeName,tt, ftt, stt, (Map) ttup, + (Map) ttdn, is, + c.transistors, c.getListHalfOperators(), + autoThresholdOptions); + + c.getListHalfOperators().clear(); + + // merge in transistor_type directive + final DirectiveSource src = + new DirectiveSource(BlockInterface.PRS); + for (Map.Entry,Integer> r : + results.entrySet()) { + src.definition(DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.HALFOP_TYPE, + r.getKey(), r.getValue()); + } + + c.cast_cell.getBlockInterface() + .iterator(BlockInterface.PRS).next() + .iterator(BlockInterface.DIRECTIVE) + .merge(new DirectiveBlock(src.getDirectiveInterface())); + } + + public void processCellType(CellType c) { + final boolean unimpl = ((Boolean) DirectiveUtils.getTopLevelDirective(c.cast_cell, DirectiveConstants.UNIMPL)).booleanValue(); + if (unimpl) { + System.out.println("Note: Attempting to size " + c.typeName + ", which has directive unimplementable = true"); + } + + Map nostats = DirectiveUtils.getPrsDirective( + c.cast_cell, DirectiveConstants.NO_STAT, + DirectiveConstants.NODE_TYPE); + Set nostatnodes = DirectiveUtils.canonize(c.namespace, + DirectiveUtils.getExplicitTrues(nostats)); + if (newt == null) newt = c; + c.transistors = new NetGraph(c.namespace, + c.exclusives, new ArrayList(), + Vdd, GND, + c.design.getTechnologyData().getMinimumTransistorWidth(), + c.design.getTechnologyData().getDefaultGateLength(), + nostatnodes); + + if (c.isJautoIgnore()) return; + + final boolean wantPrs = netlistFromPrs.evaluate(c); + final CellInterface parent = + c.cast_cell.getDirectRefinementParent(); + final boolean regenNetlist = wantPrs && !parent.containsNetlist(); + if (wantPrs && !regenNetlist) { + System.err.println( + "WARNING: " + parent.getFullyQualifiedType() + + " contains netlist block; not regenerating " + + c.typeName + " from prs"); + } + + // Production rule insertion, gate matching and logic minimization + try { + if (autoThresholdOptions != null && + regenNetlist && + c.cast_cell.containsNetlist() && + c.cast_cell.containsCompletePrs()) { + c.transistors.addCellInterface(c.cast_cell, gates, cfp, + cad); + c.transistors.prepareForLvs(); + updateTransistorTypes(c); + c.transistors = + new NetGraph(c.namespace, + c.exclusives, new ArrayList(), + Vdd, GND, + c.design.getTechnologyData().getMinimumTransistorWidth(), + c.design.getTechnologyData().getDefaultGateLength(), + nostatnodes); + } + + if ((staticizer != null || weakInverter != null || smallInverter != null) && + !regenNetlist) { + c.transistors.addCellInterface(c.cast_cell, gates, cfp, cad); + } else { + // In this case, we want to ignore staticizers that are in the + // netlist block, so we don't look at the netlist block. + // This is used by Prs2Verilog --minimize-tri-reg option. + c.transistors.addCellInterfacePrs(c.cast_cell, gates, cfp, cad); + } + + if (!c.isFixedSize() && (regenNetlist || + !c.cast_cell.containsNetlist())) { + final double l = + c.design.getTechnologyData().getDefaultGateLength(); + // set default gate length after netgraph generation + for (Iterator i = c.transistors.getEdges().iterator(); + i.hasNext(); ) { + final NetGraph.NetEdge e = (NetGraph.NetEdge) i.next(); + e.length = l; + } + } + } catch (UnimplementableProductionRuleException e) { + System.err.println(e); + System.exit(1); + } + c.transistors.prepareForLvs(); + + // Assume transistors in a netlist block has already been properly + // staticized and needs no further processing + if (c.cast_cell.containsNetlist() && + !netlistFromPrs.evaluate(c)) return; + + // Insert staticizers + if (staticizer != null || weakInverter != null || smallInverter != null) { + c.transistors.addStaticizers(gates, staticizer, weakInverter, + smallInverter, true, + c.cast_cell, cfp, cad); + } + + // needs to be called before isStaticizerInverter() works. + c.transistors.prepareForLvs(); + } + } + + /** + * Creates a new instance graph with each cell being a refinement of the + * corresponding cell in the original graph. + * + * FIXME: does not work. + * + * One refinement in each "context": name in parent. + * + * @param flags What things the new instance hierarchy should have. + * @return the subtype of the top-level cell. + **/ + public CellType instanceStandardSubTypes(int flags) { + return null; + // this.transistors = new NetGraph(null, null, new ArrayList(), null, null, this); + } + + + + public Set/**/ getSizingPaths() + { + return sizingPaths; + } + + + + public Set/**/ getCatPaths() + { + return catPaths; + } + + + public Set/**/ getReducedCatPaths() + { + return reducedCatPaths; + } + + + public String checkPathCoverage() + { + HashSet/**/ sizingPathHalfOps = + new HashSet/**/(); + for (Iterator ita = sizingPaths.iterator(); ita.hasNext(); ){ + SizingPath spa = (SizingPath)ita.next(); + sizingPathHalfOps.addAll(spa.getPath()); + } + + HashSet cellTypeHalfOps = + new HashSet(listHalfOperators); + + if (sizingPathHalfOps.equals(cellTypeHalfOps)) { + return "PASS"; + } + else{ + if(DebugOption.printLevel <= 3){ + System.out.println("---------------------------------------------------"); + System.out.println("HalfOperator number in SizingPath: " + + sizingPathHalfOps.size()); + System.out.println("HalfOperator number in CellType: " + + cellTypeHalfOps.size()); + + printHalfOperatorSetDifference(sizingPathHalfOps, "SizingPath", + cellTypeHalfOps, "CellType"); + printHalfOperatorSetDifference(cellTypeHalfOps, "CellType", + sizingPathHalfOps, "SizingPath"); + + System.out.println("---------------------------------------------------"); + + System.out.println(transistors.cdlString()); + + + } + return "FAIL"; + } + } + + private void printHalfOperatorSetDifference(Set/**/ set1, + String setName1, + Set/**/ set2, + String setName2) { + HashSet/**/ difference = + new HashSet/**/(set1); + difference.removeAll(set2); + System.out.println("HalfOperators in " + setName1 + + ", not in " + setName2 + ":"); + for (Iterator ita = difference.iterator(); + ita.hasNext(); ) { + HalfOperator hoa = (HalfOperator) ita.next(); + System.out.println( + "output net: " + + hoa.outputNet.canonicalName + .getCadenceString() + + ", direction: " + + hoa.driveDirection + ); + + for (Iterator itb = hoa.transistors.iterator(); + itb.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge) itb.next(); + + System.out.println( + "gate: " + + nea.gate.getName().getCadenceString() + + ", drain: " + + nea.drain.getName().getCadenceString() + + ", source: " + + nea.source.getName().getCadenceString() + ); + } + } + } + + + public String checkHalfOperatorCoverage() + { + HashSet/**/ netgraphTransistors = + new HashSet/**/(); + for (Iterator ita = transistors.getEdges().iterator(); ita.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)ita.next(); + + if(nea.gate.isStaticizerInverter()){ + continue; + } + + if(nea.source.isStaticizerInverter() || nea.drain.isStaticizerInverter()){ + continue; + } + + netgraphTransistors.add(nea); + } + + + HashSet/**/ halfOpTransistors = + new HashSet/**/(); + for (HalfOperator hoa : listHalfOperators) { + halfOpTransistors.addAll(hoa.transistors); + } + + if (netgraphTransistors.equals(halfOpTransistors)) { + return "PASS"; + } + else{ + System.out.println("---------------------------------------------------"); + System.out.println("Transistor number in NetGraph: " + + netgraphTransistors.size()); + System.out.println("Transistor number in HalfOperator: " + + halfOpTransistors.size()); + + printTransistorSetDifference(netgraphTransistors, "NetGraph", + halfOpTransistors, "HalfOperator"); + printTransistorSetDifference(halfOpTransistors, "HalfOperator", + netgraphTransistors, "NetGraph"); + + System.out.println("---------------------------------------------------"); + + + return "FAIL"; + } + + } + + private void printTransistorSetDifference(Set/**/ set1, + String setName1, + Set/**/ set2, + String setName2) { + HashSet/**/ difference = + new HashSet/**/(set1); + difference.removeAll(set2); + System.out.println("Transistors in " + setName1 + + ", not in " + setName2 + ":"); + for (Iterator ita = difference.iterator(); ita.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)ita.next(); + System.out.println( + "gate: " + + nea.gate.getName().getCadenceString() + + ", drain: " + + nea.drain.getName().getCadenceString() + + ", source: " + + nea.source.getName().getCadenceString() + ); + } + } + + + public boolean hasPaths() + { + // FIXME: possible cell/transistor mix in the future, don't use getLevel + if(getLevel() == 0){ + if(DebugOption.printLevel <= 3){ + System.out.println("Number of sizing paths: " + sizingPaths.size()); + } + + for (Iterator ita = sizingPaths.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + if(!spa.isFragment()){ + return true; + } + } + } + else{ + if(DebugOption.printLevel <= 3){ + System.out.println("Number of sizing paths: " + sizingPaths.size()); + System.out.println("Number of concatenated paths: " + catPaths.size()); + } + + for (Iterator ita = catPaths.iterator(); ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + if(!cpa.isFragment()){ + return true; + } + } + } + + return false; + } + + + public int getNumPaths() + { + int numPaths = 0; + + // FIXME: possible cell/transistor mix in the future, don't use getLevel + if(getLevel() == 0){ + if(DebugOption.printLevel <= 3){ + System.out.println("Number of sizing paths: " + sizingPaths.size()); + } + + for (Iterator ita = sizingPaths.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + if(!spa.isFragment()){ + ++numPaths; + } + } + } + else{ + if(DebugOption.printLevel <= 3){ + System.out.println("Number of sizing paths: " + sizingPaths.size()); + System.out.println("Number of concatenated paths: " + catPaths.size()); + } + + for (Iterator ita = catPaths.iterator(); ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + if(!cpa.isFragment()){ + ++numPaths; + } + } + } + + return numPaths; + } + + + + public void generateSizingHalfOperators() + { + // FIXME: possible cell/transistor mix in the future, don't use getLevel + if (getLevel() == 0) { // Leaf cell + for (Iterator ita = sizingPaths.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + if(!spa.isFragment()){ + setSizingHalfOperators.addAll(spa.getPath()); + } + } + } + else{ // Non-leaf cell + for (Iterator ita = reducedCatPaths.iterator(); ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + + if(!cpa.isFragment()){ + for (Iterator itb = cpa.getCatPath().iterator(); itb.hasNext(); ) { + SizingPath spa = (SizingPath)itb.next(); + + setSizingHalfOperators.addAll(spa.getPath()); + } + } + } + } + + } + + + + + public boolean isSharingSizingHalfOperatorsWith(CellType ct1) + { + HashSet/**/ seta = + new HashSet/**/(setSizingHalfOperators); + + seta.retainAll(ct1.setSizingHalfOperators); + + return !seta.isEmpty(); + } + + /** Is this the top-level Jauto sizing cell? **/ + public boolean isTopLevel() + { + return (typeName.equals("")); + } + + public boolean isFloorplanned() + { + if (isTopLevel()) return false; + return ((Boolean) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.FLOORPLAN)).booleanValue(); + } + + + public boolean isFragment() + { + return isFragment; + } + + + public boolean setIsFragment(boolean b1) + { + isFragment = b1; + + return isFragment; + } + + + public boolean hasNonObservablePorts() + { + for (Iterator ita = getAllNets().iterator(); ita.hasNext(); ) { + CellNet cna = (CellNet)ita.next(); + + if((cna.isPortNet()) && (!cna.isObservable())){ + return true; + } + } + + return false; + } + + + /** Returns true if a cell with a netlist block has the fixed size + * directive set to true. */ + public final boolean isFixedSize() + { + return CellUtils.isFixedSize(cast_cell); + } + + public final double getAssignedWireWidth() { + final Float width = (Float) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.WIREWIDTH); + return width.doubleValue(); + } + + public final double getAssignedWireSpace() { + final Float width = (Float) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.WIRESPACE); + return width.doubleValue(); + } + + public final double getAssignedWireLength() { + final Float length = (Float) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.WIRELENGTH); + return length.doubleValue(); + } + + public final double getAssignedWireSpan() { + final Float span = (Float) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.WIRESPAN); + return span.doubleValue(); + } + + public final double getAssignedMinWireLength() { + final Float minlen = (Float) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.MIN_WIRELENGTH); + return minlen.doubleValue(); + } + + public final double getAssignedMinWireSpan() { + final Float minspan = (Float) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.MIN_WIRESPAN); + return minspan.doubleValue(); + } + + private void addCutPaths(final Map m) { + final Set cutpaths = DirectiveUtils.getExplicitTrues(m); + for (Iterator i = cutpaths.iterator(); i.hasNext(); ) { + final HierName h = (HierName) i.next(); + final CellNet n = getNet(h); + n.setCutPath(true); + } + } + + private void addCutPaths() { + /* Strictly speaking, only one of these should ever apply to a cell, + since the subcell block is mutually exclusive with the prs block, but + it's harmless to try both. */ + final Map prsCutpath = DirectiveUtils.getPrsDirective(cast_cell, DirectiveConstants.CUTPATH, DirectiveConstants.NODE_TYPE); + final Map subcellCutpath = DirectiveUtils.getSubcellDirective(cast_cell, DirectiveConstants.CUTPATH, DirectiveConstants.NODE_TYPE); + addCutPaths(prsCutpath); + addCutPaths(subcellCutpath); + final Set/**/ nocutpaths = new HashSet/**/(); + nocutpaths.addAll(DirectiveUtils.canonize(namespace, DirectiveUtils.getExplicitFalses(prsCutpath))); + nocutpaths.addAll(DirectiveUtils.canonize(namespace, DirectiveUtils.getExplicitFalses(subcellCutpath))); + /* If a subcell has been inlined, preserve implied cutpath on its port + * nodes, if the subcell is not non-observable, and if a port is not + * explicitly declared as cutpath=false. A possible fix for BUG 1289. + */ + for (Iterator i = cast_cell.getAllSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName instance = (HierName) p.getFirst(); + final CellInterface ci = (CellInterface) p.getSecond(); + final boolean nonobs = ((Boolean) DirectiveUtils.getTopLevelDirective(ci, DirectiveConstants.CELLNONOBSERVABLE)).booleanValue(); + if (cast_cell.isInlinedSubcell(instance) && !nonobs) { + final CadenceInfo cinfo = cad.convert(ci); + final AliasedMap map = cinfo.getPortNodes(); + for (Iterator j = map.getCanonicalKeys(); j.hasNext(); ) { + final HierName port = (HierName) j.next(); + final HierName full = (HierName) namespace.getCanonicalKey(HierName.append(instance, port)); + Debug.assertTrue(full != null, "Cannot find canonical name for " + instance + "." + port + " in " + typeName); + if (nocutpaths.contains(full)) continue; + final CellNet n = getNet(full); + Debug.assertTrue(n != null, "Cannot find inlined net " + port + " in inlined cell " + ci.getFullyQualifiedType() + " in " + typeName); + n.setCutPath(true); + } + } + } + } + + public CellDelay getDelay() { + return delay; + } + + public float getTau() { + return -1; + } + + public boolean isJautoIgnore() { + return ((Boolean) DirectiveUtils.getTopLevelDirective(cast_cell, DirectiveConstants.JAUTO_IGNORE)).booleanValue(); + } + + public boolean isInternalEnv() { + return isInternalEnv; + } + + private static final class NameComparator implements Comparator { + private static NameComparator singleton = null; + private NameComparator() { } + public static NameComparator getInstance() { + if (singleton == null) singleton = new NameComparator(); + return singleton; + } + public int compare(Object o1, Object o2) { + return ObjectUtils.compare(((CellType) o1).typeName, + ((CellType) o2).typeName); + } + public boolean equals(Object o) { + return o == this; + } + } + + public static Comparator getNameComparator() { + return NameComparator.getInstance(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellTypeProcessor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellTypeProcessor.java new file mode 100644 index 0000000000..9caffe6080 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CellTypeProcessor.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +/** + * Interface representing + * + * @author Aaron Denney + * @version $Date$ + **/ + +public interface CellTypeProcessor { + void processCellType(CellType c); +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ChannelNet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ChannelNet.java new file mode 100644 index 0000000000..df40f88803 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ChannelNet.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Asynchronous Digital Design. All rights reserved. + * + * $Id: $ + */ + +package com.avlsi.fast; + + +import java.util.Iterator; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.Alias; + +/** + * Class to represent one of the nets inside a channel. Does not + * represent complete connectivity of said net, only its connectivity + * inside that channel. In the cast of the cast fragment "e1of2 L; + * node foo = L.e; L.0 = L.e;", the net for L.0 would only have the + * two names "0" and "d[0]", not "e" or "foo". + * + * Immutable. + **/ + +public class ChannelNet { + /** + * List of alternate names (as HierNames without parents), in a + * useful form for parent classes. + **/ + private final Alias names; + + /** Only constructor, used by ChannelTemplate.execute(). **/ + public ChannelNet(final Alias names) { + this.names = names; + } + + /** + * Returns the canonical name of this net, based only on the + * information known by this channel (see example in class-level + * comment) + **/ + public HierName getCanonicalName() { + return (HierName) names.getRootAlias().getKey(); + } + + /** Returns an iterator of all the HierNames stored in this ChannelNet **/ + public Iterator getNames() { + return names.getAliasedKeys(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ConnectionInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ConnectionInfo.java new file mode 100644 index 0000000000..b97df953c2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ConnectionInfo.java @@ -0,0 +1,423 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import com.avlsi.file.common.HierName; +import com.avlsi.cell.CellInterface; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.TreeMap; + +import com.avlsi.util.container.ObjectUtils; + +/** + * Class to represent linkages in the instantiation hierarchy. + * + * Encapsulates an instantiation of a cell in another cell. + * Can map the name of a net in the parent cell to the name + * of the net in the instantiated cell that it is connected to. + * Can map the name of a net in the instantiated cell to the name of + * of the net in the instantiating cell that it is connected to. + * + * + * Part of the subcells block. + * + * Combines the role of the original connection info in the jauto + * datastructure design document, and that of the "location info", + * though the location information may be non-existent. + * + * Edges on the instantiation DAG. + * + * + * + * @author Aaron Denney + * @version $Date$ + **/ + +public class ConnectionInfo { + /** Type of parent. **/ + public final CellType parent; + /** Type of child. **/ + public final CellType child; + /** Name of child cell in parent. **/ + public final HierName nameInParent; + /** + * Offset in parent. These are valid iff the parent and the child have + * location information. It is an error for only one to. + * (floorplanned cells must be contained in floorplanned cells, + * sized cells in sized cells, and layed out cells in layed out cells.) + **/ + public float xOffset, yOffset; + // It is always the case that, + // \forall(x \in childToParent.keySet(); + // childToParent.get(parentToChild.get(x)) == x) + // and + // \forall(x \in parentToChild.keySet(); + // parentToChild.get(childToParent.get(x)) == x) + // ie, the maps are inverses of each other + /** name map. **/ + private final Map/**/ childToParent; + /** name map. **/ + private final Map/**/ parentToChild; + + private static Comparator comparator = null; + + /** Possible orientation values, the same as in Cadence. All rotations are + * counterclockwise. */ + public static final int R0 = 0; /* No rotation */ + public static final int R90 = 1; /* Rotate 90 degrees */ + public static final int R180 = 2; /* Rotate 180 degrees */ + public static final int R270 = 3; /* Rotate 270 degrees */ + public static final int MY = 4; /* Mirror about y */ + public static final int MYR90 = 5; /* Mirror about y, rotate 90 degrees */ + public static final int MX = 6; /* Mirror about x */ + public static final int MXR90 = 7; /* Mirror about x, rotate 90 degrees */ + + /** Compose two orientations, and return the result orientation. */ + public static int composeOrientation(int first, int second) { + switch (first) { + case R0: + return second; + + case R90: + switch (second) { + case R0: return R90; + case R90: return R180; + case R180: return R270; + case R270: return R0; + case MY: return MYR90; + case MYR90: return MX; + case MX: return MXR90; + case MXR90: return MY; + default: + throw new AssertionError("Unknown orientation " + second); + } + + case R180: + switch (second) { + case R0: return R180; + case R90: return R270; + case R180: return R0; + case R270: return R90; + case MY: return MX; + case MYR90: return MXR90; + case MX: return MY; + case MXR90: return MYR90; + default: + throw new AssertionError("Unknown orientation " + second); + } + + case R270: + switch (second) { + case R0: return R270; + case R90: return R0; + case R180: return R90; + case R270: return R180; + case MY: return MXR90; + case MYR90: return MY; + case MX: return MYR90; + case MXR90: return MX; + default: + throw new AssertionError("Unknown orientation " + second); + } + + case MY: + switch (second) { + case R0: return MY; + case R90: return MXR90; + case R180: return MX; + case R270: return MYR90; + case MY: return R0; + case MYR90: return R270; + case MX: return R180; + case MXR90: return R90; + default: + throw new AssertionError("Unknown orientation " + second); + } + + case MYR90: + switch (second) { + case R0: return MYR90; + case R90: return MY; + case R180: return MXR90; + case R270: return MX; + case MY: return R90; + case MYR90: return R0; + case MX: return R270; + case MXR90: return R180; + default: + throw new AssertionError("Unknown orientation " + second); + } + + case MX: + switch (second) { + case R0: return MX; + case R90: return MYR90; + case R180: return MY; + case R270: return MXR90; + case MY: return R180; + case MYR90: return R90; + case MX: return R0; + case MXR90: return R270; + default: + throw new AssertionError("Unknown orientation " + second); + } + + case MXR90: + switch (second) { + case R0: return MXR90; + case R90: return MX; + case R180: return MYR90; + case R270: return MY; + case MY: return R270; + case MYR90: return R180; + case MX: return R90; + case MXR90: return R0; + default: + throw new AssertionError("Unknown orientation " + second); + } + + default: + throw new AssertionError("Unknown orientation " + first); + } + } + + /** Orientation of the instance */ + public int orientation = R0; + + /** Base index of independent variable relative to the parent. **/ + private int baseIndex = 0; + + /** + * Constructor. + **/ + ConnectionInfo(CellType parent, CellType child, HierName name, Cadencize c) { + this.parent = parent; + this.child = child; + this.nameInParent = name; + xOffset = 0; yOffset = 0; + NameHelper h = new NameHelper(c); + childToParent = h.createChildToParent(); + parentToChild = h.createParentToChild(); + orientation = R0; + } + + ConnectionInfo factory() { + return null; + } + + /** + * Given the name of a net in the instantiated cell returns + * the name of a net in the instantiating cell connected to it. + * @param c the name of a node in the child's portlist. + * @return the name of child's node c in the parent. + **/ + public HierName getParentName(HierName c) { + return (HierName) childToParent.get(c); + } + + /** + * Given a net in the instantiated cell returns + * the name of a net in the instantiating cell connected to it. + * @param cNet A net in the child's portlist. + * @return the name of child's node c in the parent. + **/ + public HierName getParentName( CellNet cNet ) { + Debug.assertTrue( child == cNet.container ); + return getParentName( cNet.canonicalName ); + } + + /** + * Given the name of a net in the instantiating cell returns + * the name of a net in the instantiated cell connected to it. + * @param p the name of a node in the parent that is connected + * to this child. + * @return the name of parent's node p in the child. + **/ + public HierName getChildName(HierName p) { + return (HierName) parentToChild.get(p); + } + + /** + Given a net in the instantiating cell returns + the name of a net in the instantiated cell connected to it. + * @param p A net in the parent that is connected + * to this child. + * @return the name of parent's node p in the child. + **/ + public HierName getChildName( CellNet pNet ) { + Debug.assertTrue( parent == pNet.container ); + return getChildName( pNet.canonicalName ); + } + + /** + * resolves names to build name <-> name mapping. + * + * Should perhaps be using cadencizer? + **/ + private class NameHelper { + Cadencize c; + TreeMap/**/ parentNames = new TreeMap/**/(); + TreeMap/**/ childNames = new TreeMap/**/(); + + NameHelper(Cadencize c) { + this.c = c; + final HierName prefix = nameInParent; + // cadencize not only unifies nodes, but it also converts globals used in cell or subcell to ports. + final CadenceInfo ci = c.convert(child.cast_cell); + final AliasedMap portNodes = ci.getPortNodes(); + for (Iterator i = portNodes.getKeys(); i.hasNext(); ) { + HierName h = (HierName) i.next(); + // Only add the nodes that are to be included in the port list + if (((Boolean) portNodes.getValue(h)).booleanValue() || + child.isWiringCell || + child.isInternalEnv()) { + HierName parentLocal = HierName.append(prefix, h); + parentNames.put(parentLocal, h); + childNames.put(h, parentLocal); + } + } + } + + Map/**/ createParentToChild() { + return parentNames; + } + + Map/**/ createChildToParent() { + return childNames; + } + } + + /** + Generates a string representation of the ConnectionInfo. + @return A string representing the ConnectionInfo. + */ + public String toString() { + StringBuffer temp = new StringBuffer("Parent = "); + temp.append(parent); + temp.append(", child = "); + temp.append(child); + temp.append(" named "); + temp.append(nameInParent); + for (Iterator i = parentToChild.entrySet().iterator(); i.hasNext(); ) { + Map.Entry e = (Map.Entry) i.next(); + HierName parent = (HierName) e.getKey(); + HierName child = (HierName) e.getValue(); + temp.append("\n"); + temp.append(parent).append(" = ").append(child); + } + return temp.toString(); + } + + public static final class NameIterator { + private Iterator i; + private NameIterator(Map m) { + this.i = m.keySet().iterator(); + } + + public boolean hasNext() { + return i.hasNext(); + } + + /** @throws NoSuchElementException **/ + public HierName next() { + return (HierName) i.next(); + } + } + + /** + Constructs an iterator that will iterate over all the net names + that reference nets in the instantiating cell that are connected to + nets in the instantiated cell. + @return An iterator that will iterate over all the net names + that reference nets in the instantiating cell that are connected to + nets in the instantiated cell. + */ + public NameIterator parentIterator() { + return new NameIterator(parentToChild); + } + + /** + Constructs an iterator that will iterate over all the net names + that reference nets in the instantiated cell that are connected to + nets in the instantiating cell. + @return An iterator that will iterate over all the net names + that reference nets in the instantiated cell that are connected to + nets in the instantiating cell. + */ + public NameIterator childIterator() { + return new NameIterator(childToParent); + } + + + public final Set/**/ getParentNet(CellNet cn1) + { + HashSet/**/ seta = new HashSet/**/(); + + for (Iterator ita = cn1.portNames.iterator(); ita.hasNext(); ){ + HierName hna = (HierName)ita.next(); + + seta.add(parent.getNet(getParentName(hna))); + } + + + return seta; + } + + public static Comparator getComparator() { + if (comparator == null) { + comparator = + new Comparator() { + public int compare(Object o1, Object o2) { + final ConnectionInfo ci1 = (ConnectionInfo) o1; + final ConnectionInfo ci2 = (ConnectionInfo) o2; + int x; + x = ObjectUtils.compare(ci1.child.typeName, + ci2.child.typeName); + if (x != 0) return x; + x = ObjectUtils.compare(ci1.parent.typeName, + ci2.parent.typeName); + if (x != 0) return x; + x = ObjectUtils.compare(ci1.nameInParent, + ci2.nameInParent); + return x; + } + public boolean equals(Object o) { + return this == o; + } + }; + } + return comparator; + } + + public int getIndex() { + return baseIndex; + } + + public void setIndex(int index) { + baseIndex = index; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CspBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CspBlock.java new file mode 100644 index 0000000000..ec61f872c5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/CspBlock.java @@ -0,0 +1,133 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.ArrayList; +import java.util.List; + +import com.avlsi.fast.BlockCommon; +import com.avlsi.tools.cosim.CSPCoSimInfo; +import com.avlsi.csp.ast.CSPProgram; + +/** + * Interface to a CSP block. + **/ +public class CspBlock extends BlockCommon { + /** + * The cosimulation info from the csp block + **/ + private final CSPCoSimInfo cspCosimInfo; + + /** + * The names (Strings) of the ports for the csp block. If all + * ports are to be passed in to the csp, is empty. + **/ + private final List cspPorts; + + /** + * CSP parse tree. + **/ + private CSPProgram csp; + + /** + * The compiled class for CSP without coverage probes; + **/ + private Class cspClass; + + /** + * The compiled class for CSP with coverage probes; + **/ + private Class cspClassWithProbes; + + /** + * Does any refinement parents have sequential CSP statements? + **/ + private boolean hasSequential; + + public CspBlock() { + this.cspCosimInfo = new CSPCoSimInfo(); + this.cspPorts = new ArrayList(); + this.csp = null; + this.cspClass = null; + this.cspClassWithProbes = null; + this.hasSequential = false; + } + + public String getType() { + return BlockInterface.CSP; + } + + /* CSP cosim information is derived and, due to the restrictions on + * port-changing by the refinement process, will always be derived + * properly. Statement overrides, functions add. + */ + public void refineFrom(final BlockInterface o) { + super.refineFrom(o); + + final CspBlock parent = (CspBlock) o; + this.hasSequential |= parent.hasSequentialStatement(); + + final CSPProgram parentCSP = parent.getCSPProgram(); + if (parentCSP != null) { + if (getCSPProgram() == null) { + setCSPProgram(new CSPProgram()); + } + getCSPProgram().refineFrom(parentCSP); + } + } + + public BlockInterface merge(BlockInterface o) { + throw new AssertionError( + "CspBlock doesn't support all BlockInterface functionality"); + } + + public BlockInterface replace(BlockInterface o) { + throw new AssertionError( + "CspBlock doesn't support all BlockInterface functionality"); + } + + public CSPCoSimInfo getCSPCoSimInfo() { + return cspCosimInfo; + } + + public List getCSPPorts() { + return cspPorts; + } + + public Class getCSPClass(boolean probes) { + return probes ? cspClassWithProbes : cspClass; + } + + public void setCSPClass(final Class cspClass, boolean probes) { + if (probes) { + this.cspClassWithProbes = cspClass; + } else { + this.cspClass = cspClass; + } + } + + public CSPProgram getCSPProgram() { + return csp; + } + + public void setCSPProgram(final CSPProgram csp) { + this.csp = csp; + } + + public boolean hasSequentialStatement() { + return hasSequential || (csp != null && csp.getStatement() != null); + } + + public String toString() { + return "CspBlock cspCosimInfo=" + cspCosimInfo + + " cspPorts=" + cspPorts + + " cspClass=" + cspClass + + " cspClassWithProbes=" + cspClassWithProbes + + " csp=" + csp; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/DirectiveBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/DirectiveBlock.java new file mode 100644 index 0000000000..adbeaae1ed --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/DirectiveBlock.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.HashMap; +import java.util.Map; +import java.util.Iterator; + +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cell.CellInterface; +import com.avlsi.util.debug.Debug; + +/** + * Interface to an directives block. + **/ + +public class DirectiveBlock extends BlockCommon implements DirectiveInterface, + Cloneable { + DirectiveInterface directives; + + public DirectiveBlock(DirectiveInterface directives) { + assert directives != null; + this.directives = directives; + } + + public String getType() { + return BlockInterface.DIRECTIVE; + } + + public void refineFrom(final BlockInterface o) { + super.refineFrom(o); + + final DirectiveBlock parent = (DirectiveBlock) o; + directives = new MergeDirective(parent, this.directives); + } + + public BlockInterface merge(BlockInterface o) { + if (o instanceof DirectiveBlock) { + return new MergeDirective(this, (DirectiveBlock) o); + } + Debug.assertTrue(false, "DirectiveBlock does not support merge"); + return null; + } + + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "DirectiveBlock does not support replace"); + return null; + } + + + public Object getDefaultValue(String key, String memberType) throws UnknownDirectiveException { + return directives.getDefaultValue(key, memberType); + } + + public Map getValues(String key, String memberType) throws UnknownDirectiveException { + return directives.getValues(key, memberType); + } + + public Object lookup(String key) throws UnknownDirectiveException { + return directives.lookup(key); + } + + public boolean containsDirective(String key) throws UnknownDirectiveException { + return directives.containsDirective(key); + } + + public Object lookup(String key, String memberType, Object parameter) throws UnknownDirectiveException { + return directives.lookup(key, memberType, parameter); + } + + public boolean isKey(String key) { + return directives.isKey(key); + } + + public boolean isKey(String key, String memberType) { + return directives.isKey(key, memberType); + } + + public String toString() { + return directives + super.toString(); + } + + public Iterator noparamEntryIterator() { + return directives.noparamEntryIterator(); + } + + public Iterator paramEntryIterator() { + return directives.paramEntryIterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/EnvBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/EnvBlock.java new file mode 100644 index 0000000000..19e89482e5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/EnvBlock.java @@ -0,0 +1,162 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.CastParserEnvironment; +import com.avlsi.cast.impl.ChainEnvironment; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentEntry; +import com.avlsi.cast.impl.EnvironmentEntryIterator; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast.impl.SemanticWrapperException; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.UserDefinedValue; +import com.avlsi.cast.impl.Value; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.util.debug.Debug; +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; + +/** + * Interface to an env block. Currently only useful for getting + * the named environments from the env block. + **/ + +public class EnvBlock extends BlockCommon { + /** + * An environment containing definitions of environment cells as well as + * any bindings before that point. It is set when the environment block of + * a cell is parsed. + * + * @see com.avlsi.cast.impl.UserDefinedValue + **/ + private Environment env; + + /** + * An environment containing definitions inside the environment block. It + * is set when the environment block of a cell is parsed. + * + * @see com.avlsi.cast.impl.UserDefinedValue + **/ + private Environment blockEnv; + + /** + * The current parser environment associated with this environment block. + * This is necessary so we can use the correct CastParsingOptions when we + * actually tree parse the AST associated with an environment block. + * Keeping a reference to it shouldn't create any problems with GC. + **/ + private CastParserEnvironment parserEnv; + + /** + * The cell containing this EnvBlock. + **/ + private final CellInterface parent; + + public EnvBlock(final CellInterface parent) { + env = NullEnvironment.getInstance(); + blockEnv = NullEnvironment.getInstance(); + this.parent = parent; + } + + public void setEnvironment(final Environment env, + final Environment blockEnv, + final CastParserEnvironment parserEnv) { + this.env = env; + this.blockEnv = blockEnv; + this.parserEnv = parserEnv; + } + + public Environment getEnvironment() { + return env; + } + + /** + * Returns an iterator over the names of all environments that do not have + * metaparameters. Automated testing programs use this function to iterate + * over environments to test. Environments with metaparameters are not + * tested, because metaparameters cannot be choosen automatically. + **/ + public Iterator/**/ getNames() { + final List/**/ result = new ArrayList(); + for (EnvironmentEntryIterator i = blockEnv.entryIterator(); + i.hasNext(); ) { + final EnvironmentEntry entry = i.next(); + final Value val = entry.getValue(); + if (val instanceof UserDefinedValue && + !((UserDefinedValue) val).hasMetaParams()) { + result.add(entry.getName().getString()); + } + } + return result.iterator(); + } + + /** + * Returns an environment by that name, or null if it cannot be + * instantiated. name may contain metaparameters. + **/ + public CellInterface getNamedEnvironment(final String name) + throws CastSemanticException { + CellInterface result = null; + + // check to make sure name is an environment defined locally + if (parserEnv != null && + blockEnv.contains(Symbol.create(CellUtils.getBaseType(name)))) { + try { + result = parserEnv.getCell(env, name, null, null, parent); + } catch (SemanticWrapperException e) { + throw new CastSemanticException(e.getCause(), e.getFilename(), + e.getLine(), e.getColumn()); + } + } else { + // automatically generated environments + if (name.equals("leakage")) { + result = CellUtils.getLeakageEnv(parent); + } + } + return result; + } + + /** + * Environments add, except that in name clashes the refined one + * is used. + **/ + public void refineFrom(final BlockInterface o) { + super.refineFrom(o); + final EnvBlock parent = (EnvBlock) o; + this.env = new ChainEnvironment(parent.env, this.env); + this.blockEnv = new ChainEnvironment(parent.blockEnv, this.blockEnv); + if (this.parserEnv == null) this.parserEnv = parent.parserEnv; + } + + public String getType() { + return BlockInterface.ENV; + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "EnvBlock doesn't support all BlockInterface functionality"); + return null; + } + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "EnvBlock doesn't support all BlockInterface functionality"); + return null; + } + + public String toString() { + return "EnvBlock " + env; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/HalfOperator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/HalfOperator.java new file mode 100644 index 0000000000..cde36a27dd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/HalfOperator.java @@ -0,0 +1,677 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Collections; +import java.util.List; +import java.util.LinkedHashSet; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.Iterator; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.prs.ProductionRule; + +import com.avlsi.tools.jauto.*; +import com.avlsi.util.container.ObjectUtils; +import com.avlsi.util.debug.Debug; + + +/** + * Class representing half-operators. + * + * Just references a gate network + an output. + * + * @author Aaron Denney + * @author Qing Wu + * @version $Date$ + **/ + +public class HalfOperator { + public static final class DriveDirection { + private DriveDirection() { throw new AssertionError(); } + public static final int PULL_DOWN = 0; + public static final int PULL_UP = 1; + public static final int PASS_GATE = 2; + } + + private double delayBias = 1.0; + private double strengthBias = 1.0; + public double minDelay = -1.0; + + /** + * Cell containing the half-operator. + **/ + public CellType subType; + + + public NetGraph.NetNode outputNode; + public CellNet outputNet; + public Set transistors; + + // Set of depths of the transistor stack + public SortedSet/**/ depths; + //@invariant depth.containsAll(nofloating); + private SortedSet/**/ nofloating; + + // drive direction: DriveDirection.PULL_DOWN or DriveDirection.PULL_UP + public int driveDirection; + + // current effective width of the halfoperator, in Meter + private double currentSize; + + // previous effective width of the halfoperator, in Meter + private double previousSize; + + /** + * The length per meter "effective" size of diffusion of transistors + * in this half-operator attached to the outputNode. Must be multiplied + * by currentSize to get a length in meters. + **/ + private double outputDiffusionLength; + + // isFixed == true -> use value (currentSize), otherwise use variable (variableName) + private boolean isFixed; + + // name of the variable associated with this halfoperator + // must be unique in the scope of the whole cast design + private String variableName; + + /** + * Factor by which this half operator is symmetrized. + **/ + private double symmetrizationFactor; + + // is this part of a combinational or dynamic gate? + public boolean isCombinational; + + // did this match part of a gate from the library? + public boolean isLibraryGate; + + // Set of NetNodes that have been precharged + private Set prechargeNodes = null; + + private int transistorType = TechnologyData.NO_TRANSISTOR_TYPE; + + private static Comparator comparator = null; + + private static double EPSILON = 1e-12; + + public HalfOperator(){ + // FIXME: removed hardcoded constant + currentSize = 0.3E-6; + previousSize = 0.0; + outputDiffusionLength = Double.NaN; + isFixed = true; + variableName = ""; + isCombinational = true; + isLibraryGate = false; + + outputNode = null; + outputNet = null; + transistors = new LinkedHashSet(); + depths = new TreeSet/**/(); + nofloating = new TreeSet/**/(); + + driveDirection = DriveDirection.PULL_DOWN; + } + + + /** + * Lock size. + **/ + public boolean fixVariable() { + isFixed = true; + + return isFixed; + } + + /** + * Unlock size, unless this half-operator is from a fixed size cell. + **/ + public boolean unfixVariable() { + if(!subType.isFixedSize()){ + isFixed = false; + } + + return isFixed; + } + + + /** + * Returns whether the size variable related to the half-operator is fixed or not + **/ + public boolean isVariableFixed() { + return isFixed; + } + + /** + * Set the symmetrization factor for this half-operator. + **/ + public void setSymmetrizationFactor(final double symmetrizationFactor) { + assert symmetrizationFactor > 0; + this.symmetrizationFactor = symmetrizationFactor; + } + + /** + * Returns the symmetrization factor for this half-operator. + **/ + public double getSymmetrizationFactor() { + return symmetrizationFactor; + } + + + /** + * Initialize size for fixed-size cells + **/ + public final double initializeSize(){ + boolean consistent = true; + boolean first = true; + + currentSize = Double.POSITIVE_INFINITY; + + // find the minimum half-operator size implied by the transistors + for (NetGraph.NetEdge nea : transistors) { + final double hsize = nea.width / nea.size; + if (first) { + currentSize = hsize; + first = false; + } else { + if (Math.abs(hsize - currentSize) > EPSILON) { + currentSize = Math.min(hsize, currentSize); + consistent = false; + } + } + } + + if (!consistent && ! JautoUI.quiet) { + System.out.println("Warning: Size inconsistency found in " + + "fixed-sized cell, using most conservative " + + "half-operator size: " + currentSize); + System.out.println(toString()); + } + + previousSize = currentSize; + + return currentSize; + } + + /** + * Initialize the width of the transistors in this half-operator to + * -Infinity. + **/ + public void resetWidth() { + if (!subType.isFixedSize()) { + for (NetGraph.NetEdge nea : transistors) { + nea.width = Double.NEGATIVE_INFINITY; + } + } + } + + /** + * Update the current and previous values of the half-operator, and the + * width and length values for transistors. + * Sets previousSize to the currentSize and + * the currentSize to the newSize parameter. + **/ + public double updateSize(double newSize) { + if (!subType.isFixedSize()) { + previousSize = currentSize; + currentSize = newSize; + + for (NetGraph.NetEdge nea : transistors) { + nea.width = Math.max(nea.width, currentSize * nea.size); + } + } + + return currentSize; + } + + /** + * Returns the current "effective" size of the half-operator + **/ + public double getCurrentSize() { + return currentSize; + } + + /** + * Returns the previous "effective" size of the half-operator + **/ + public double getPreviousSize() { + return previousSize; + } + + /** + * Returns the length per meter "effective" size of diffusion of + * transistors in this half-operator attached to the outputNode. + **/ + public double getOutputDiffusionLength() { + assert !Double.isNaN(outputDiffusionLength); + return outputDiffusionLength; + } + + /** + * Sets the length per meter "effective" size of diffusion of + * transistors in this half-operator attached to the outputNode. + **/ + void setOutputDiffusionLength(final double outputDiffusionLength) { + assert !Double.isNaN(outputDiffusionLength); + this.outputDiffusionLength = outputDiffusionLength; + } + + /** + * Returns the name of the variable associated with this half-operator + **/ + public String getVariableName() { + return variableName; + } + + /** + * Set the name of the variable associated with this half-operator + **/ + public String setVariableName(String s){ + assert s.length() <= 10 + : "variable name must contain no more than 10 characters"; + + variableName = s; + + return variableName; + } + + + /** + * Returns the list of pointers to all the fanout global nets of this half-operator + **/ + public List getListGlobalNets() { + return outputNet.getGlobalNets(); + } + + + /** + * Returns the setting of delay bias for this halfoperator + **/ + public double getDelayBias() { + return delayBias; + } + + + public double setDelayBias(double f) + { + assert f >= 0.0 : "f = " + f; + + delayBias = f; + + return delayBias; + } + + + public double getStrengthBias() + { + return strengthBias; + } + + + public double setStrengthBias(double f) + { + assert f > 0.0; + + strengthBias = f; + + return strengthBias; + } + + + public String toString() + { + return "Name of output node: " + outputNode.name + "\n" + + "Name of output net: " + outputNet.canonicalName.getCadenceString() + "\n" + + "Number of transistors: " + transistors.size() + "\n" + + "Drive direction: " + driveDirection + "\n"; + } + + + public boolean isSharingWith(HalfOperator ho1) + { + HashSet seta = new HashSet(); + + seta.addAll(transistors); + seta.retainAll(ho1.transistors); + + return !seta.isEmpty(); + } + + public boolean isSameStrengthGroup(HalfOperator ho1) + { + return subType.hasSameStrengthGroup(outputNet, driveDirection, + ho1.outputNet, ho1.driveDirection); + } + + /* Add a depth to the list of depths. Set floating to true if this depth + * is not to be emitted. */ + public void addDepths(int depth, boolean floating) { + final Integer i = new Integer(depth); + depths.add(i); + if (!floating) nofloating.add(i); + } + + /* Return a sorted array of stack depths to be emitted */ + public int[] getDepths() { + final int[] result = new int[nofloating.size()]; + int j = 0; + for (Iterator i = nofloating.iterator(); i.hasNext(); ++j) { + Integer val = (Integer) i.next(); + result[j] = val.intValue(); + } + return result; + } + + public int getMaxDepth() { + Debug.assertTrue(!depths.isEmpty(), "Depths set empty! Cannot get maximum depth!"); + return ((Integer) depths.last()).intValue(); + } + + public int getMinDepth() { + Debug.assertTrue(!depths.isEmpty(), "Depths set empty! Cannot get minimum depth!"); + return ((Integer) depths.first()).intValue(); + } + + + private double getEffectiveResistanceFactor() { + final TechnologyData tech = subType.design.getTechnologyData(); + + return driveDirection == DriveDirection.PULL_DOWN ? + tech.getEffectiveResistanceFactorN(getTransistorType(), 0) : + tech.getEffectiveResistanceFactorP(getTransistorType(), 0); + } + + public double getStrength() { + final TechnologyData tech = subType.design.getTechnologyData(); + return getEffectiveResistanceFactor() * tech.defaultGateLength / + getCurrentSize(); + } + + + // REVIEW: This function seems dodgy. + public double getWidth(int depth) { + final TechnologyData tech = subType.design.getTechnologyData(); + + if (tech.getUseIntrinsicCap()) { + final NetGraph.GateInstance gate = outputNode.getGate(); + + // Did we match a gate? + if (gate != null) { + final HierName portName = + gate.getPortName(outputNode.getName()); + + final CastDesign castDesign = outputNet.container.design; + final CellInterface gateCell = + castDesign.getCellForGate(gate); + final Float effectiveResistance = (Float) + DirectiveUtils.getHalfOpDirectiveValue(gateCell, + DirectiveConstants.EFFECTIVE_RESISTANCE, + portName, + driveDirection == DriveDirection.PULL_UP, + castDesign.getCadencize()); + + // Was the effective resistance specified for the gate? + if (effectiveResistance != null) { + final double[] effectiveResistances = + driveDirection == DriveDirection.PULL_DOWN ? + tech.getEffectiveResistanceFactorN(getTransistorType()) : + tech.getEffectiveResistanceFactorP(getTransistorType()); + return getCurrentSize() * depth + * (effectiveResistance.floatValue() / + effectiveResistances[0]) + * (effectiveResistances[depth - 1] / + effectiveResistances[getMaxDepth() - 1]); + } + } + } + + JautoMessageCenter messageCenter = subType.design.messageCenter; + + // TODO: move stack limit checks elsewhere + + double resistanceFactorRatio; + if (driveDirection == DriveDirection.PULL_DOWN) { + if(depth > tech.stackWarnLimitN){ + String msa = "WARNING"; + String msb = "N-type transistor stack depth out of bound. The maximum allowable is " + + tech.stackWarnLimitN + ".\n"; + String msc = "CellName: " + subType.typeName + "\n" + + "NetName: " + outputNet.canonicalName.getCadenceString() + "\n"; + if (! JautoUI.quiet) + messageCenter.createMessage(1, 15, msa, msb, msc); + } + else{ + // Max depth OK if matched to a gate or straight-chain. + if(depth == tech.stackWarnLimitN){ + // If we do this check when generating the netlist, + // we could delete the symmetrizationFactor member. + if (outputNode.getGate() == null && + transistors.size() > depth * symmetrizationFactor) { + String msa = "WARNING"; + String msb = "N-type transistor stack depth at maximum=" + + tech.stackWarnLimitN + "\n and not a gate or straight-chain.\n"; + String msc = "CellName: " + subType.typeName + "\n" + + "NetName: " + outputNet.canonicalName.getCadenceString() + "\n"; + if (! JautoUI.quiet) + messageCenter.createMessage(1, 16, msa, msb, msc); + } + } + } + + resistanceFactorRatio = tech.getEffectiveResistanceFactorN(getTransistorType(), depth-1) + / tech.getEffectiveResistanceFactorN(getTransistorType(), 0); + } + else{ // PULL_UP + if(depth > tech.stackWarnLimitP){ + String msa = "WARNING"; + String msb = "P-type transistor stack depth out of bound. The maximum allowable is " + + tech.stackWarnLimitP + ".\n"; + String msc = "CellName: " + subType.typeName + "\n" + + "NetName: " + outputNet.canonicalName.getCadenceString() + "\n"; + if (! JautoUI.quiet) + messageCenter.createMessage(1, 17, msa, msb, msc); + } + else{ + // Max depth OK if matched to a gate or straight-chain. + if(depth == tech.stackWarnLimitP){ + if(outputNode.getGate() == null && + transistors.size() > depth * symmetrizationFactor){ + String msa = "WARNING"; + String msb = "P-type transistor stack depth at maximum=" + + tech.stackWarnLimitP + "\n and not a gate or straight-chain.\n"; + String msc = "CellName: " + subType.typeName + "\n" + + "NetName: " + outputNet.canonicalName.getCadenceString() + "\n"; + if (! JautoUI.quiet) + messageCenter.createMessage(1, 18, msa, msb, msc); + } + } + } + + resistanceFactorRatio = tech.getEffectiveResistanceFactorP(getTransistorType(),depth-1) + / tech.getEffectiveResistanceFactorP(getTransistorType(), 0); + } + + return getCurrentSize() * depth * resistanceFactorRatio + / getSymmetrizationFactor(); // width per fold + } + + + public HalfOperator getOpposingHalfOperator() { + HalfOperator foundHalfOp = null; + + for (Iterator i = outputNet.getListSources().iterator(); + i.hasNext(); ) { + final NetSource source = (NetSource) i.next(); + if (source.getType() == NetType.HALF_OPERATOR_TRANSISTOR) { + final HalfOperator halfOp = source.getSource(); + assert halfOp.outputNet == outputNet; + assert halfOp.subType == subType; + if (halfOp.driveDirection != driveDirection) { + // TODO: When this assertion is verified, just + // return here. + assert foundHalfOp == null; + foundHalfOp = halfOp; + } + } + } + + return foundHalfOp; + } + + public Set getPrechargeNodes() { + if (prechargeNodes == null) { + prechargeNodes = new HashSet(); + for (NetGraph.NetEdge edge : transistors) { + + final NetGraph.GateInstance g1 = edge.source.getGate(); + if (g1 != null && g1.isPrechargePrimitive()) + prechargeNodes.add(edge.source); + + final NetGraph.GateInstance g2 = edge.drain.getGate(); + if (g2 != null && g2.isPrechargePrimitive()) + prechargeNodes.add(edge.drain); + } + if (prechargeNodes.isEmpty()) + prechargeNodes = Collections.EMPTY_SET; + } + return prechargeNodes; + } + + public static Comparator getComparator() { + if (comparator == null) { + comparator = new Comparator() { + public int compare(Object o1, Object o2) { + final HalfOperator h1 = (HalfOperator) o1; + final HalfOperator h2 = (HalfOperator) o2; + int x = h1.driveDirection - h2.driveDirection; + if (x != 0) return x; + x = ObjectUtils.compare(h1.subType.typeName, + h2.subType.typeName); + if (x != 0) return x; + x = ObjectUtils.compare(h1.outputNode, + h2.outputNode); + if (x != 0) return x; + x = ObjectUtils.compare(h1.outputNet.canonicalName, + h2.outputNet.canonicalName); + return x; + } + public boolean equals(Object o) { + return this == o; + } + }; + } + return comparator; + } + + public int getTransistorType() { + if (transistorType == TechnologyData.NO_TRANSISTOR_TYPE) { + boolean warned = false; + for (NetGraph.NetEdge edge : transistors) { + if (transistorType == TechnologyData.NO_TRANSISTOR_TYPE) { + transistorType = edge.getTransistorType(); + } else if (transistorType != edge.getTransistorType()) { + if (!warned) { + warned = true; + final String msa = "WARNING"; + final String msb = "Multiple transistor types found " + + "in a single half-operator.\n"; + final String msc = + "CellName: " + subType.typeName + "\n" + + "NetName: " + + outputNet.canonicalName.getCadenceString() + "\n"; + if (! JautoUI.quiet) + subType.design.messageCenter + .createMessage(1, 19, msa, msb, msc); + } + transistorType = + Math.max(transistorType, edge.getTransistorType()); + } + } + } + return transistorType; + } + + /** + * size = conductance * getConductanceToSizeFactor() + **/ + private double getConductanceToSizeFactor() { + final TechnologyData tech = subType.design.getTechnologyData(); + return getEffectiveResistanceFactor() / getStrengthBias() * + tech.defaultGateLength; + } + + /** + * Returns the conductance for a given size + **/ + public double getConductanceForSize(final double size) { + return size / getConductanceToSizeFactor(); + } + + /** + * Returns the size for a given conductance + **/ + public double getSizeForConductance(final double g) { + return g * getConductanceToSizeFactor(); + } + + public FunctionTerm getResistanceTerm() { + + final FunctionTerm result; + if (isVariableFixed()) { + final double f = getConductanceToSizeFactor(); + result = new FunctionTerm(f / getCurrentSize()); + } else { + result = new FunctionTerm(FunctionTerm.Type.ONE_OVER_VAR, + getVariableName(), 1.0); + } + + return result; + } + + public AdditiveTerms getDiffusionCapacitanceTerm() { + final TechnologyData tech = subType.design.getTechnologyData(); + final double unitDiffusionCapacitance = + driveDirection == DriveDirection.PULL_DOWN ? + tech.getUnitNmosDiffusionCapacitance(getTransistorType()) : + tech.getUnitPmosDiffusionCapacitance(getTransistorType()); + final double f = + getOutputDiffusionLength() * unitDiffusionCapacitance; + + final AdditiveTerms result; + if (isVariableFixed()) { + result = new AdditiveTerms(new FunctionTerm(f * getCurrentSize())); + } else { + result = new AdditiveTerms( + new FunctionTerm(FunctionTerm.Type.VAR, + getVariableName(), + f * getSizeForConductance(1.0) * + tech.getWidthRoundingSlope()), + new FunctionTerm(f * tech.getWidthRoundingOffset() * + getSymmetrizationFactor())); + } + + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/JavaBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/JavaBlock.java new file mode 100644 index 0000000000..74dd094ce3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/JavaBlock.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import com.avlsi.util.debug.Debug; + +public class JavaBlock extends BlockCommon { + public JavaBlock() { } + + public String getType() { + return BlockInterface.JAVA; + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "JavaBlock does not support merge"); + return null; + } + + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "JavaBlock does not support replace"); + return null; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/MergeDirective.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/MergeDirective.java new file mode 100644 index 0000000000..7020695d36 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/MergeDirective.java @@ -0,0 +1,138 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Iterator; + +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cell.CellInterface; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; + +/** + * DirectiveBlock that represents the merging of 2 DirectiveBlocks. + * Essentially, requests will be forwarded to one DirectiveBlock, and if + * unsuccessful, to the other DirectiveBlock. + **/ + +public class MergeDirective extends DirectiveBlock { + private DirectiveInterface child; + private Map valueCache; + + /** + * Constructs a MergeDirective from 2 DirectiveBlocks. + * @param parent Containing "fall-through" directives, consulted second. + * @param child Containing overriding directives, consulted first. + **/ + public MergeDirective(DirectiveInterface parent, DirectiveInterface child) { + super(parent); + this.child = child; + this.valueCache = null; + } + + public Object getDefaultValue(String key, String memberType) throws UnknownDirectiveException { + try { + return child.getDefaultValue(key, memberType); + } catch (UnknownDirectiveException e) { + return directives.getDefaultValue(key, memberType); + } + } + + public Map getValues(String key, String memberType) throws UnknownDirectiveException { + Map p = null; + try { + p = directives.getValues(key, memberType); + } catch (UnknownDirectiveException e) { + return child.getValues(key, memberType); + } + + Map c = null; + try { + c = child.getValues(key, memberType); + } catch (UnknownDirectiveException e) { + return p; + } + + if (valueCache == null) valueCache = new HashMap(); + + final Pair k = new Pair(key, memberType); + Map result = (Map) valueCache.get(k); + if (result == null) { + result = new LinkedHashMap(); + result.putAll(p); + result.putAll(c); + valueCache.put(k, result); + } + return result; + } + + public Object lookup(String key) throws UnknownDirectiveException { + try { + if (child.containsDirective(key)) return child.lookup(key); + } catch (UnknownDirectiveException e) { } + return directives.lookup(key); + } + + public boolean containsDirective(String key) throws UnknownDirectiveException { + return child.containsDirective(key) || directives.containsDirective(key); + } + + public Object lookup(String key, String memberType, Object parameter) throws UnknownDirectiveException { + try { + Object o = child.lookup(key, memberType, parameter); + if (o != child.getDefaultValue(key, memberType)) return o; + } catch (UnknownDirectiveException e) { } + return directives.lookup(key, memberType, parameter); + } + + public boolean isKey(String key) { + return child.isKey(key) || directives.isKey(key); + } + + public boolean isKey(String key, String memberType) { + return child.isKey(key, memberType) || directives.isKey(key, memberType); + } + + public Iterator noparamEntryIterator() { + HashMap mergeMap = new HashMap(); + for(Iterator i=super.noparamEntryIterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + mergeMap.put( entry.getKey(), entry.getValue() ); + } + for(Iterator i=child.noparamEntryIterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + mergeMap.put( entry.getKey(), entry.getValue() ); + } + + return mergeMap.entrySet().iterator(); + } + + public Iterator paramEntryIterator() { + HashMap mergeMap = new HashMap(); + for(Iterator i = super.paramEntryIterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + mergeMap.put(entry.getKey(), new HashMap((Map) entry.getValue())); + } + for(Iterator i = child.paramEntryIterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + Object key = entry.getKey(); + Map m = (Map) mergeMap.get(key); + if (m == null) { + m = new HashMap(); + mergeMap.put(key, m); + } + m.putAll((Map) entry.getValue()); + } + + return mergeMap.entrySet().iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NamedEnvironmentRedeclaredException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NamedEnvironmentRedeclaredException.java new file mode 100644 index 0000000000..f01c804b0e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NamedEnvironmentRedeclaredException.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +/** + * Exception thrown by {@link EnvBlock} for duplicated named environments. + **/ +public final class NamedEnvironmentRedeclaredException extends Exception { + public NamedEnvironmentRedeclaredException(final String detail) { + super(detail); + } + + public String toString() { + return "NamedEnvironmentRedeclaredException: " + + getMessage(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistAdapter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistAdapter.java new file mode 100644 index 0000000000..8606912eeb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistAdapter.java @@ -0,0 +1,996 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.TreeMap; +import java.util.Set; +import java.util.SortedSet; +import java.util.HashSet; +import java.util.TreeSet; + +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellTypeProcessor; +import com.avlsi.fast.HalfOperator; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.cdl.parser.NetlistBlockFactory; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.ConcatAbstractDeviceIterator; +import com.avlsi.netlist.impl.SimpleAbstractDeviceIterator; +import com.avlsi.netlist.impl.SimpleAbstractNetlistIterator; +import com.avlsi.netlist.impl.SimpleAbstractNodeIterator; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryPredicate; + +/** + This class is an adapter to CellType that makes it look like a netlist. + */ + +public class NetlistAdapter implements AbstractNetlist { + private int stackId = 0; + private class Stack implements AbstractDevice { + private final NetGraph.NetNode start; + private final NetGraph.NetNode end; + private final List gates; + private final int type; + private final int transistorType; + private final Map params; + private int id; + private String pn() { + return (type == DeviceTypes.N_TYPE ? "N" : "P"); + } + public Stack(final NetGraph.NetNode start, + final NetGraph.NetNode end, + final List gates, + final int type) { + this.gates = new ArrayList(gates); + this.type = type; + this.params = new TreeMap(); + final NetGraph.NetEdge zero = (NetGraph.NetEdge) gates.get(0); + params.put(pn() + "W" + gates.size(), + new Double(roundMinWidth(zero.width))); + params.put(pn() + "L", new Double(zero.length)); + this.start = start; + this.end = end; + this.id = -1; + this.transistorType = zero.getTransistorType(); + } + public void accept(final Visitor visitor) { + final Map map = new TreeMap(); + if (id < 0) id = stackId++; + map.put("S", start); + map.put("D", end); + for (int i = 0; i < gates.size(); ++i) { + map.put("G[" + i + "]", ((NetGraph.NetEdge) gates.get(i)).gate); + } + if (type == DeviceTypes.N_TYPE) { + map.put("GND", graph.findNetNode(GND)); + } else { + map.put("Vdd", graph.findNetNode(Vdd)); + } + + final AbstractNodeIterator nodes = new SimpleAbstractNodeIterator(map.entrySet().iterator()) { + public AbstractNode next() { + final Map.Entry entry = (Map.Entry) iterator.next(); + final NetGraph.NetNode to = (NetGraph.NetNode) entry.getValue(); + return new Node(to, to != start && + to != end && + !to.isRail()); + } + }; + + final NetGraph gate = (NetGraph) stackMap.get(new Pair(new Integer(gates.size()), new Integer(type))); + + if ( gate == null ) { + + final String errorStr = + "Cannot find appropriate gate for " + + pn() + + "-type chains of size " + + gates.size() + + ".\n For chain starting with \"" + + start.name.toString() + + "\" and ending with \"" + + end.name.toString() + + "\" in \"" + + cell.typeName + + "\"."; + + throw new RuntimeException( errorStr ); + + + } + + final String baseType = CellUtils.getBaseType(gate.gateType); + final String realName = baseType.equals(gate.gateType) ? + baseType : baseType + "(" + transistorType + ")"; + visitor.subcircuitCall(HierName.makeHierName("chain_" + id), new GateAdapter(gate, realName), nodes, params); + } + public String toString() { + return "==> Start: " + start + "\n==> End: " + end + "\n==> Gates: " + gates; + } + public boolean equals(Object o) { + return (o instanceof Stack) && gates.equals(((Stack) o).gates); + } + public int hashCode() { + return gates.hashCode(); + } + } + + private void stackize(final NetGraph.NetPath path, final Set stacks) { + final int type = path.getType(); + final List edges = path.getEdges(); + NetGraph.NetNode start = path.getStartNode(); + final NetGraph.NetNode end = path.getEndNode(); + List stack = new ArrayList(); + NetGraph.NetNode last = start; + for (Iterator i = edges.iterator(); i.hasNext(); ) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) i.next(); + final boolean excluded = edge.library && !edge.floating; + final NetGraph.NetNode next = + edge.source == last ? edge.drain : edge.source; + if (stack.isEmpty()) { + if (!excluded) { + stack.add(edge); + start = last; + } + } else { + final NetGraph.NetEdge zero = (NetGraph.NetEdge) stack.get(0); + if (zero.length != edge.length || zero.width != edge.width || + zero.getTransistorType() != edge.getTransistorType() || + excluded) { + stacks.add(new Stack(start, last, stack, type)); + stack.clear(); + start = last; + } + if (!excluded) stack.add(edge); + } + if (!stack.isEmpty() && next.needsContact()) { + stacks.add(new Stack(start, next, stack, type)); + stack.clear(); + } + last = next; + } + if (!stack.isEmpty()) stacks.add(new Stack(start, end, stack, type)); + } + + private Collection getStacks(final NetGraph g) { + final Set result = new LinkedHashSet(); + for (Iterator i = g.getNodes().iterator(); i.hasNext(); ) { + final NetGraph.NetNode n = (NetGraph.NetNode) i.next(); + for (Iterator j = n.getPaths().iterator(); j.hasNext(); ) { + final NetGraph.NetPath p = (NetGraph.NetPath) j.next(); + final NetGraph.NetNode start = p.getStartNode(); + final NetGraph.NetNode end = p.getEndNode(); + if (!start.isRail() && !end.isRail() && start.compareTo(end) > 0) continue; + final int type = p.getType(); + if (type == DeviceTypes.P_TYPE || type == DeviceTypes.N_TYPE) + stackize(p, result); + } + } + return result; + } + + /** Obtain the port list in a consistent way using Cadencize. */ + public static SortedSet getParameterList(final CellInterface ci) { + return getParameterList(ci, new Cadencize(true)); + } + + public static SortedSet getParameterList(final CellInterface ci, + final Cadencize c) { + /* Cadencize to find the port list. */ + final CadenceInfo cinfo = c.convert(ci); + TreeSet port = new TreeSet(); + AliasedMap portNodes = cinfo.getPortNodes(); + for (Iterator i = portNodes.getCanonicalKeys(); i.hasNext(); ) { + final HierName h = (HierName) i.next(); + if (((Boolean) portNodes.getValue(h)).booleanValue()) port.add(h); + } + return port; + } + + /** + This class is an adapter to turn a NetGraph representation of a gate + into a Netlist. The gate is read in from a CDL file, and is very + simple. In particular, this means no subcircuit calls. + */ + public static class GateAdapter implements AbstractNetlist { + private int transistorID = 0; + private class Node implements AbstractNode { + private final NetGraph.NetNode node; + + public Node(final NetGraph.NetNode node) { + this.node = node; + } + + public HierName getCanonicalName() { + return node.name; + } + + public Iterator getAliases() { + /* There is no aliasing in CDL files except through parameter + * passing */ + return Collections.EMPTY_LIST.iterator(); + } + + public AbstractDeviceIterator getDevices() { + return new SimpleAbstractDeviceIterator(node.edges.iterator()) { + public AbstractDevice next() { + final NetGraph.NetEdge edge = + (NetGraph.NetEdge) iterator.next(); + return new Transistor(edge); + } + }; + } + } + private class Transistor implements AbstractDevice { + private final NetGraph.NetEdge edge; + private final NetGraph.NetNode bulk; + private String type; + private final HierName name; + + public Transistor(final NetGraph.NetEdge edge) { + this.edge = edge; + if (edge.type == DeviceTypes.N_TYPE) { + bulk = graph.GND; + type = "N"; + } else { + bulk = graph.Vdd; + type = "P"; + } + type = type + "[" + edge.getTransistorType() + "]"; + name = makeHierName(Integer.toString(transistorID++)); + } + + public void accept(final Visitor visitor) { + visitor.genericTransistor( + name, + new Node(edge.drain), new Node(edge.gate), + new Node(edge.source), new Node(bulk), + edge.length, edge.width, + type, Collections.EMPTY_MAP + ); + } + } + private final NetGraph graph; + private final String name; + public GateAdapter(NetGraph gateGraph) { + this(gateGraph, gateGraph.gateType); + } + public GateAdapter(NetGraph gateGraph, String name) { + this.graph = gateGraph; + this.name = name; + } + /* There is no way to tell if a node is a input or an output from + * NetGraph, so assume all nodes are output nodes. */ + public AbstractNodeIterator getInputNodes() { + return new + SimpleAbstractNodeIterator(Collections.EMPTY_LIST.iterator()); + } + public AbstractNodeIterator getOutputNodes() { + final UnaryPredicate isOutput = new UnaryPredicate() { + public boolean evaluate(Object a) { + NetGraph.NetNode node = (NetGraph.NetNode) a; + return node.isOutput() && node.isNamed(); + } + }; + final FilteringIterator filter = + new FilteringIterator(graph.getNodes().iterator(), isOutput); + return new SimpleAbstractNodeIterator(filter) { + public AbstractNode next() { + final NetGraph.NetNode node = + (NetGraph.NetNode) iterator.next(); + return new Node(node); + } + }; + } + public HierName getName() { + return makeHierName(name); + } + public AbstractNodeIterator getNodes() { + return new + SimpleAbstractNodeIterator(graph.getNodes().iterator()) { + public AbstractNode next() { + final NetGraph.NetNode node = + (NetGraph.NetNode) iterator.next(); + return new Node(node); + } + }; + } + public AbstractDeviceIterator getDevices() { + return new + SimpleAbstractDeviceIterator(graph.getEdges().iterator()) { + public AbstractDevice next() { + final NetGraph.NetEdge edge = + (NetGraph.NetEdge) iterator.next(); + return new Transistor(edge); + } + }; + } + public AbstractNetlistIterator getSubcircuits() { + return new + SimpleAbstractNetlistIterator(Collections.EMPTY_LIST.iterator()); + } + } + + private final CellType cell; + private final NetGraph graph; + private int transistorID = 0; + private final Map portMap; + private final boolean outputRC; + private final Map stackMap; + private final HierName GND, Vdd; + + /** + * Float.isNaN(top) means old SPICE style; top < 0 indicate non-top + * level cell; otherwise top is the capacitance to attach to the port + * nodes. + **/ + private final float top; + + /** + * Minimum width of a transistor for a stack or a gate. This limit does + * not apply to staticizers. + **/ + private final float minWidth; + private double roundMinWidth(final double val) { + if (Float.isNaN(minWidth)) return val; + else return Math.max(val, minWidth); + } + + private static HierName makeSource(final HierName name) { + return name.appendString(":source"); + } + + private static HierName makeSink(final HierName name) { + return name; + } + + private static final UnaryPredicate notLibraryEdge = new UnaryPredicate() { + public boolean evaluate(Object a) { + /* NetEdge.library is true if the edge is part of a matched gate. + * We want to filter these out. But we also want to keep the + * "floating" transistors in. */ + final NetGraph.NetEdge edge = (NetGraph.NetEdge) a; + return !edge.library || edge.floating; + } + }; + + // XXX: Jcast does not handle definition within a definition + private boolean subcircuits; + + private static HierName makeHierName(final String s) { + HierName n = null; + try { + n = HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + Debug.assertTrue(false, "Cannot makeHierName"); + } + return n; + } + + private class Node implements AbstractNode { + private final NetGraph.NetNode node; + + /** Is the node used as a gate node in a transistor? If so, it is + * treated as a sink, otherwise, it is treated as a source. */ + private final boolean gate; + + public Node(final NetGraph.NetNode node, final boolean gate) { + this.node = node; + this.gate = gate; + } + + public HierName getCanonicalName() { + final CellNet net; + if (outputRC && (net = cell.getNet(node.name)) != null) { + final CellNet.Geometry geometry = net.getGeometry(); + if (geometry != null) return geometry.mapName(net, gate); + else if (!Float.isNaN(top)) { + if (net.isInternalNet()) { + return gate ? node.name : makeSource(node.name); + } else if (top < 0) { + return gate ? makeSink(node.name) : + makeSource(node.name); + } else { + return node.name; + } + } + } + return node.name; + } + + public Iterator getAliases() { + return Collections.EMPTY_LIST.iterator(); + } + + public AbstractDeviceIterator getDevices() { + final Iterator i = + new FilteringIterator(node.edges.iterator(), notLibraryEdge); + return new SimpleAbstractDeviceIterator(i) { + public AbstractDevice next() { + NetGraph.NetEdge edge = (NetGraph.NetEdge) iterator.next(); + return new Transistor(edge); + } + }; + } + } + + private class PortNode implements AbstractNode { + private final CellType cell; + private final HierName name; + + public PortNode(final CellType cell, final HierName name) { + this.cell = cell; + this.name = name; + } + + public HierName getCanonicalName() { + return name; + } + + public Iterator getAliases() { + // XXX + return null; + } + + public AbstractDeviceIterator getDevices() { + // XXX + return null; + } + } + + private class Transistor implements AbstractDevice { + private final NetGraph.NetEdge edge; + private final NetGraph.NetNode bulk; + private String type; + private final HierName name; + + public Transistor(final NetGraph.NetEdge edge) { + this.edge = edge; + if (edge.type == DeviceTypes.N_TYPE) { + bulk = graph.GND; + type = "N"; + } else { + bulk = graph.Vdd; + type = "P"; + } + type = type + "[" + edge.getTransistorType() + "]"; + name = makeHierName(Integer.toString(transistorID++)); + } + + public void accept(final Visitor visitor) { + visitor.genericTransistor( + name, + new Node(edge.drain, false), + new Node(edge.gate, true), + new Node(edge.source, false), + new Node(bulk, false), + edge.length, + edge.width, + type, + Collections.EMPTY_MAP + ); + } + } + + private class Capacitor implements AbstractDevice { + private final HierName name; + private final AbstractNode pos; + private final AbstractNode neg; + private final double cap; + public Capacitor(final HierName name, final AbstractNode pos, + final AbstractNode neg, final double cap) { + this.name = name; + this.pos = pos; + this.neg = neg; + this.cap = cap; + } + public void accept(final Visitor visitor) { + visitor.genericCapacitor(name, pos, neg, cap, + Collections.EMPTY_MAP); + } + } + + private class Call implements AbstractDevice { + private AbstractNodeIterator nodes; + private HierName name; + private ConnectionInfo ci; + + public Call(final ConnectionInfo ci) { + this.ci = ci; + this.name = ci.nameInParent; + + if (!portMap.containsKey(ci.child)) { + new PortIterator(ci); + } + final Set formal = (Set) portMap.get(ci.child); + final List list = new ArrayList(); + for (Iterator i = formal.iterator(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + final HierName parentPort = ci.getParentName(port); + final CellNet net = ci.parent.getNet(parentPort); + final CellNet.Geometry geometry = net.getGeometry(); + if (Float.isNaN(top)) { + if (outputRC && geometry != null) { + final CellNet childNet = ci.child.getNet(port); + list.add(geometry.mapName(childNet, parentPort)); + } else { + list.add(net.canonicalName); + } + } else { + if (net.isInternalNet()) { + list.add(makeSource(net.canonicalName)); + list.add(net.canonicalName); + } else if (top < 0) { + list.add(makeSource(net.canonicalName)); + list.add(makeSink(net.canonicalName)); + } else { + list.add(net.canonicalName); + list.add(net.canonicalName); + } + } + } + + this.nodes = new SimpleAbstractNodeIterator(list.iterator()) { + public AbstractNode next() { + return new PortNode(ci.parent, (HierName) iterator.next()); + } + }; + } + + public void accept(final Visitor visitor) { + visitor.subcircuitCall(name, new NetlistAdapter(ci.child, false, outputRC, stackMap, GND, Vdd, Float.isNaN(top) ? Float.NaN : -1, minWidth), nodes, Collections.EMPTY_MAP); + } + } + + private static class UnusedGateOutputException extends Exception { + } + + private HalfOperator[] findHalfOperator(NetGraph.NetNode node) + throws UnusedGateOutputException { + List halfops = cell.getListHalfOperators(); + HalfOperator[] ops = new HalfOperator[2]; + int count = 0; + /* Expecting a pull-down and a pull-up for a node. Exit early if both + * found. Currently, this is a linear search, as the number of half + * operators in a leaf cell is expected to be small. */ + for (Iterator i = halfops.iterator(); i.hasNext() && count < 2;) { + HalfOperator op = (HalfOperator) i.next(); + if (node.equals(op.outputNode)) { + ops[count++] = op; + } + } + if (count != 2) { + throw new UnusedGateOutputException(); + } + return ops; + } + + /* gateDirection is a cache of whether a node in a gate NetGraph is ever + * used as a gate node in a transistor. */ + private static final Map gateDirection = new HashMap(); + private class Gate implements AbstractDevice { + private final NetGraph.GateInstance gate; + private final HierName name; + private final AbstractNodeIterator nodes; + private final Map params; + + private boolean isGateNode(HierName node) { + final NetGraph g = gate.getNetGraph(); + Set gateSet = (Set) gateDirection.get(g); + if (gateSet == null) { + gateSet = new HashSet(); + for (Iterator i = g.getEdges().iterator(); i.hasNext(); ) { + NetGraph.NetEdge edge = (NetGraph.NetEdge) i.next(); + gateSet.add(edge.gate.name); + } + gateDirection.put(g, gateSet); + } + return gateSet.contains(node); + } + + private void addWidth(final HalfOperator op, final Map params) { + String np = null; + switch (op.driveDirection) { + case 0: np = "NW"; break; + case 1: np = "PW"; break; + default: Debug.assertTrue(false, "Don't know how to handle driveDirection " + op.driveDirection); + } + /* Originally, this only outputs ports that are used, so any stack + * depths only used by floating transistors are not included here. + * But, there is some difficulty not emitting these unused ports + * when emitting from a netlist block, which causes difficulty when + * using aspice, since it expects parameters to match exactly. + * This problem is resolved by adding the usued port to the gate + * definitions (BUG 1273). But, this fix causes aspice to complain + * about the netlist generated directly from PRS. So, just emit + * all the ports, even ones unused, since that appears to be + * harmless (BUG 1625). */ + /* + int[] depths = op.getDepths(); + Debug.assertTrue(depths.length != 0, "Half operator has 0 depth!"); + for (int i = 0; i < depths.length; i++) { + params.put(np + depths[i], new Double(op.getWidth(depths[i]))); + } + */ + final Collection depths = op.depths; + assert depths.size() > 0 : "Half operator has 0 depth!"; + for (Iterator i = depths.iterator(); i.hasNext(); ) { + final int depth = ((Integer) i.next()).intValue(); + params.put(np + depth, + new Double(roundMinWidth(op.getWidth(depth)))); + } + } + + private void nonStaticizerGate(final HalfOperator[] ops) { + Debug.assertTrue(ops.length == 2, "Invalid ops.length = " + ops.length); + Debug.assertTrue(ops[0].driveDirection != ops[1].driveDirection, "Found half operators that are the same direction!"); + addWidth(ops[0], params); + addWidth(ops[1], params); + } + + private void prechargeGate(final NetGraph.NetNode node) { + for (Iterator i = node.getEdges(); i.hasNext(); ) { + final NetGraph.NetEdge e = (NetGraph.NetEdge) i.next(); + if (e.precharge) { + final String t = e.type == DeviceTypes.N_TYPE ? "N" : "P"; + params.put(t + "W1", new Double(e.width)); + params.put(t + "L", new Double(e.length)); + } + } + assert false : "Precharge primitive attached on " + node + + " but no precharge transistor found"; + } + + private void staticizerGate(final NetGraph.NetNode node) { + Debug.assertTrue(node.isStaticized(), "isStaticized returned false for " + node + ", but a STATICIZER gate is attached to it."); + double nlength = -1, nwidth = -1; + double plength = -1, pwidth = -1; + Iterator i; + i = node.getFeedbackEdges().iterator(); + while (i.hasNext()) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) i.next(); + switch (edge.type) { + case DeviceTypes.N_TYPE: + Debug.assertTrue(nlength == -1, "More than one staticizer for node " + node + "?"); + nlength = edge.length; + nwidth = edge.width; + break; + case DeviceTypes.P_TYPE: + Debug.assertTrue(plength == -1, "More than one staticizer for node " + node + "?"); + plength = edge.length; + pwidth = edge.width; + break; + default: Debug.assertTrue(false, "Don't know how to handle edge type " + edge.type); + } + } + Debug.assertTrue(nlength > 0 && nwidth > 0 && plength > 0 && pwidth > 0); + params.put("NW", new Double(nwidth)); + params.put("PW", new Double(pwidth)); + params.put("NL", new Double(nlength)); + params.put("PL", new Double(plength)); + } + + private void feedbackWidth(final NetGraph.NetNode node) { + final SortedSet nws = new TreeSet(); + final SortedSet pws = new TreeSet(); + for (Iterator i = node.getFeedbackEdges().iterator(); + i.hasNext(); ) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) i.next(); + if (edge.isFeedbackOnly() && edge.library) { + if (edge.type == DeviceTypes.N_TYPE) { + nws.add(edge.width); + } else { + pws.add(edge.width); + } + } + } + if (!nws.isEmpty()) { + params.put("NWS", nws.last()); + assert nws.size() == 1 : "Too many NWS: " + nws + " at " + + cell.typeName + "/" + node; + } + if (!pws.isEmpty()) { + params.put("PWS", pws.last()); + assert pws.size() == 1 : "Too many PWS: " + pws + " at " + + cell.typeName + "/" + node; + } + } + + public Gate(final NetGraph.GateInstance gate, + final NetGraph.NetNode n, final boolean isStaticizer) + throws UnusedGateOutputException { + this.gate = gate; + final Map map = gate.getUnmodifiableMap(); + this.nodes = new SimpleAbstractNodeIterator(map.entrySet().iterator()) { + public AbstractNode next() { + final Map.Entry entry = (Map.Entry) iterator.next(); + final HierName from = (HierName) entry.getKey(); + final HierName to = (HierName) entry.getValue(); + final NetGraph.NetNode node = graph.findNetNode(to); + return isStaticizer ? new Node(node, false) : new Node(node, isGateNode(from)); + } + }; + this.params = new TreeMap(); + if (n.isStaticizerInverter()) { + this.name = n.name; + // no width parameters for small inverters for now + } else if (isStaticizer) { + this.name = n.name.appendString("_stat"); + staticizerGate(n); + } else if (gate.isPrechargePrimitive()) { + this.name = n.name.appendString("_precharge"); + prechargeGate(n); + } else { + this.name = n.name; + final HalfOperator ops[] = findHalfOperator(n); + nonStaticizerGate(ops); + feedbackWidth(n); + } + } + public void accept(final Visitor visitor) { + visitor.subcircuitCall(name, + new GateAdapter(gate.getNetGraph(), gate.getType()), + nodes, params); + } + } + + public NetlistAdapter(final CellType cell, final boolean outputRC) { + this(cell, outputRC, null, null, null, Float.NaN, Float.NaN); + } + + public NetlistAdapter(final CellType cell, final boolean outputRC, + final Map stackMap, final HierName GND, + final HierName Vdd, final float minWidth) { + this(cell, true, outputRC, stackMap, GND, Vdd, Float.NaN, minWidth); + } + + /** + * Construct a new NetlistAdapter. + * @param cell Cell to make an AbstractNetlist from. + * @param outputRC Output resistors and capacitors suitable for SPICE + * @param stackMap Map from a pair of depth and type + * Pair<Integer, Integer (DeviceTypes.N_TYPE | DeviceTypes.P_TYPE)> to + * NetGraph. + **/ + public NetlistAdapter(final CellType cell, final boolean outputRC, + final Map stackMap, final HierName GND, + final HierName Vdd, final float top, + final float minWidth) { + this(cell, true, outputRC, stackMap, GND, Vdd, top, minWidth); + } + + private NetlistAdapter(final CellType cell, boolean subcircuits, + boolean outputRC, final Map stackMap, + final HierName GND, final HierName Vdd, + final float top, final float minWidth) { + this.cell = cell; + graph = cell.transistors; + this.subcircuits = subcircuits; + this.outputRC = outputRC; + portMap = new HashMap(); + this.stackMap = stackMap; + this.GND = GND; + this.Vdd = Vdd; + this.top = top; + this.minWidth = minWidth; + } + + public AbstractDeviceIterator getDevices() { + /* We do not want to output transistors that are a part of the gate + * library, since they are already output as subcircuit calls to + * gates. */ + final Iterator edge = + new FilteringIterator(graph.getEdges().iterator(), notLibraryEdge); + final ArrayList calls = new ArrayList(); + if (!cell.isInternalEnv()) { + for (Iterator iter = cell.getAllSubcellConnections().iterator(); + iter.hasNext(); ) { + ConnectionInfo ci = (ConnectionInfo) iter.next(); + if (!ci.child.isWiringCell) calls.add(ci); + } + } + + final ArrayList devices = new ArrayList(); + + if (stackMap == null) { + devices.add(new SimpleAbstractDeviceIterator(edge) { + public AbstractDevice next() { + return new Transistor((NetGraph.NetEdge) iterator.next()); + } + }); + } else { + final Collection stacks = getStacks(graph); + devices.add(new SimpleAbstractDeviceIterator(stacks.iterator())); + } + + devices.add(new SimpleAbstractDeviceIterator(calls.iterator()) { + public AbstractDevice next() { + return new Call((ConnectionInfo) iterator.next()); + } + }); + + if (outputRC) { + for (Iterator i = cell.getAllNets().iterator(); i.hasNext(); ) { + final CellNet net = (CellNet) i.next(); + final CellNet.Geometry geometry = net.getGeometry(); + if (geometry==null) continue; + if (net.isInternalNet() || // include small inverters created in netlist + net.getListSources().size() > 0 || net.getListSinks().size() > 0) + devices.add(geometry.getDeviceIterator()); + } + } + + // top > 0 ==> !Float.isNaN(top) + if (top > 0) { + assert !Float.isNaN(top); + final ArrayList portCaps = new ArrayList(); + for (AbstractNodeIterator i = getOutputNodes(); i.hasNext(); ) { + final AbstractNode port = i.next(); + final HierName canon = port.getCanonicalName(); + if (canon.equals(GND) || canon.equals(Vdd)) continue; + portCaps.add(new Capacitor(canon, new PortNode(cell, GND), + port, top)); + } + devices.add(new SimpleAbstractDeviceIterator(portCaps.iterator())); + } + + final ArrayList gates = new ArrayList(); + for (Iterator iter = graph.getNodes().iterator(); iter.hasNext();) { + final NetGraph.NetNode node = (NetGraph.NetNode) iter.next(); + final NetGraph.GateInstance gate = node.getGate(); + if (gate != null) { + try { + gates.add(new Gate(gate, node, false)); + } catch (UnusedGateOutputException e) { + if (cell.isFixedSize()) { + System.err.println("Warning: in fixed sized cell " + + cell.typeName + ", " + node.name + + " is the output of a matched gate, but does" + + " not drive anything."); + } else { + System.err.println( + "Error: in cell " + cell.typeName + ", " + + node.name + " is the output of a matched gate, " + + "but does not drive anything. Please remove the " + + "unnecessary production rules to reduce " + + "transistor count."); + } + } + } + final NetGraph.GateInstance staticizer = node.getStaticizer(); + if (staticizer != null) { + try { + gates.add(new Gate(staticizer, node, true)); + } catch (UnusedGateOutputException e) { + throw new AssertionError( + "Staticizer gate treated like non-staticizer gate: " + + cell.typeName + "/" + node.name); + } + } + } + devices.add(new SimpleAbstractDeviceIterator(gates.iterator())); + + return new ConcatAbstractDeviceIterator(devices); + } + + // XXX: For now, assume all nodes are output nodes + public AbstractNodeIterator getInputNodes() { + return new SimpleAbstractNodeIterator(Collections.EMPTY_LIST.iterator()); + } + + private class PortIterator implements AbstractNodeIterator { + private final ConnectionInfo ci; + private final Iterator iterator; + + public PortIterator(final ConnectionInfo ci) { + this.ci = ci; + Set set = (Set) portMap.get(ci.child); + if (set == null) { + final Map map = new HashMap(); + for (ConnectionInfo.NameIterator it = ci.childIterator(); + it.hasNext(); ) { + HierName port = (HierName) it.next(); + CellNet net = ci.child.getNet(port); + HierName old = (HierName) map.get(net); + if (old != null && old.compareTo(port) <= 0) + continue; + map.put(net, port); + } + set = new TreeSet(map.values()); + portMap.put(ci.child, set); + } + final ArrayList ports = new ArrayList(); + for (Iterator i = set.iterator(); i.hasNext(); ) { + final HierName hn = (HierName) i.next(); + final HierName cn = ci.child.getNet(hn).canonicalName; + // top < 0 ==> !Float.isNaN(top) + if (top < 0) { + assert !Float.isNaN(top); + ports.add(makeSource(cn)); + ports.add(makeSink(cn)); + } else { + ports.add(cn); + } + } + iterator = ports.iterator(); + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public AbstractNode next() { + HierName port = (HierName) iterator.next(); + return new PortNode(ci.child, port); + } + } + + public AbstractNodeIterator getOutputNodes() { + if (cell.parentcellconnections.size() > 0) { + final ConnectionInfo ci = (ConnectionInfo) cell.parentcellconnections.get(0); + return new PortIterator(ci); + } else { + return new SimpleAbstractNodeIterator(Collections.EMPTY_LIST.iterator()); + } + } + + public AbstractNodeIterator getNodes() { + final Iterator i = graph.getNodes().iterator(); + return new SimpleAbstractNodeIterator(i); + } + + public AbstractNetlistIterator getSubcircuits() { + final ArrayList subckt = new ArrayList(); + if (subcircuits) { + cell.walkOnce(new CellTypeProcessor() { + public void processCellType(CellType c) { + if (cell != c && !c.isWiringCell) subckt.add(c); + } + }); + } + + final Iterator i = subckt.iterator(); + + return new SimpleAbstractNetlistIterator(i) { + public AbstractNetlist next() { + return new NetlistAdapter((CellType) iterator.next(), false, outputRC, stackMap, GND, Vdd, Float.isNaN(top) ? Float.NaN : -1, minWidth); + } + }; + } + + public HierName getName() { + return makeHierName(cell.typeName); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistBlock.java new file mode 100644 index 0000000000..9d8878e90a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/NetlistBlock.java @@ -0,0 +1,113 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.Collections; +import java.util.Map; + +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockCommon; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.NetlistBlockFactory; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.CanonicalizeCDL; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; + +/** + * Interface to a netlist block. + **/ +public class NetlistBlock extends BlockCommon { + private AbstractNetlist netlist; + private CellInterface parent; + private Template templ = null; + private Map params = Collections.EMPTY_MAP; + private boolean empty; + + public NetlistBlock(final CellInterface parent) { + this(null, parent); + empty = true; + } + + public NetlistBlock(final AbstractNetlist netlist, + final CellInterface parent) { + setNetlist(netlist); + this.parent = parent; + } + + public String getType() { + return BlockInterface.NETLIST; + } + + /** Netlist block overrides. **/ + public void refineFrom(final BlockInterface o) { + if (empty) { + super.copyInternals(o); + final NetlistBlock parent = (NetlistBlock) o; + this.netlist = parent.netlist; + this.templ = parent.templ; + this.params = parent.params; + this.empty = parent.empty; + } + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "NetlistBlock doesn't support all BlockInterface functionality"); + return null; + } + + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "NetlistBlock doesn't support all BlockInterface functionality"); + return null; + } + + public void setCDLTemplate(final Template templ, final Map params) { + this.empty = false; + this.templ = templ; + this.params = params; + } + + public void setNetlist(final AbstractNetlist netlist) { + this.empty = false; + this.netlist = netlist; + } + + public AbstractNetlist getNetlist() { + if (netlist == null && templ != null) { + /* If the template exist, then create the netlist from that, using + * the default parameters, and cache it. */ + netlist = new NetlistBlockFactory(); + templ.execute(Collections.EMPTY_MAP, (CDLSimpleInterface) netlist); + } + return netlist; + } + + public boolean isEmpty() { + return empty; + } + + public Template getCDLTemplate() { + return templ; + } + + public Template getCanonicalTemplate(final Cadencize c) { + final CadenceInfo ci = c.convert(parent); + final AliasedMap ports = ci.getPortNodes(); + final Template canonTempl = new Template(Collections.EMPTY_MAP); + templ.execute(new CanonicalizeCDL(canonTempl, new AliasedSet(ports))); + return canonTempl; + } + + public Map getParams() { + return params; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ParamTypeInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ParamTypeInterface.java new file mode 100644 index 0000000000..6c05eb8354 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ParamTypeInterface.java @@ -0,0 +1,24 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +/** + * Tagging interface for types of parameters. (Copied and modified from + * ports/PortTypeInterface.java) + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public interface ParamTypeInterface { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsBlock.java new file mode 100644 index 0000000000..b7ab592612 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsBlock.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import com.avlsi.fast.BlockCommon; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.util.debug.Debug; + +/** + * Interface to a PRS block. + **/ +public class PrsBlock extends BlockCommon { + private ProductionRuleSet productionRuleSet; + + public PrsBlock() { + this.productionRuleSet = new ProductionRuleSet(); + } + + public String getType() { + return BlockInterface.PRS; + } + + /** + * Absorbs the production rules from its refinement parent into + * itself. + **/ + public void refineFrom(final BlockInterface o) { + super.refineFrom(o); + + final PrsBlock parent = (PrsBlock) o; + productionRuleSet.refineFrom(parent.productionRuleSet); + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "PrsBlock doesn't support all BlockInterface functionality"); + return null; + } + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "PrsBlock doesn't support all BlockInterface functionality"); + return null; + } + + public ProductionRuleSet getProductionRuleSet() { + return productionRuleSet; + } + + public String toString() { + return "PrsBlock " + productionRuleSet; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsDirective.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsDirective.java new file mode 100644 index 0000000000..f277447bb6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/PrsDirective.java @@ -0,0 +1,438 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import com.avlsi.cast.impl.AlintFaninValue; +import com.avlsi.cast.impl.TupleValue; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.cast.impl.Value; +import static com.avlsi.cast2.directive.DirectiveConstants.ALINT_SCENARIO_TYPE; +import static com.avlsi.cast2.directive.DirectiveConstants.NODE_TYPE; +import static com.avlsi.cast2.directive.DirectiveConstants.HALFOP_TYPE; +import static com.avlsi.cast2.directive.DirectiveConstants.DEEP_HALFOP_TYPE; +import static com.avlsi.cast2.directive.DirectiveConstants.WIDE_CHANNEL_TYPE; +import static com.avlsi.cast2.directive.DirectiveConstants.POSSIBLY_WIDE_CHANNEL_TYPE; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.directive.impl.DirectiveImpl; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.debug.Debug; + +/** + * Class used to bring up directives from a inlined or flattened cell. When a + * cell is flattened in the PRS block, all its directives must be propagated + * upwards, with the name of the flattened instance prepended to all nodes and + * half operators used in the directive block inside the flattened cell. + **/ + +public class PrsDirective extends DirectiveBlock { + /** + * Constructs a PrsDirective based on an empty DirectiveInterface. + **/ + public PrsDirective(final String type) { + this(type, (new DirectiveImpl(type, new LocalEnvironment())).getDirectiveInterface()); + } + + /** + * Constructs a PrsDirective from the DirectiveInterface to the current + * cell. + * @param me Containing directives for the current cell. + **/ + public PrsDirective(final String type, final DirectiveInterface me) { + super(new PrefixDirective(type, me)); + } + + /** + * Add the directives of an inlined cell. + **/ + public void addInstance(final HierName instance, + final DirectiveInterface directives) { + ((PrefixDirective) this.directives).addInstance(instance, directives); + } + + private static class PrefixDirective implements DirectiveInterface { + /** + * A map from instance name prefixes to the corresponding directives + * blocks of inlined cells. + **/ + private final Map blocks; + + /** + * The block type + **/ + private final String type; + + /** + * The base directive interface. + **/ + private final DirectiveInterface base; + + private Map,Map> valuesCache = null; + + public PrefixDirective(final String type, + final DirectiveInterface base) { + this.type = type; + this.base = base; + this.blocks = new HashMap(); + } + + /** + * The block type + **/ + public void addInstance(final HierName instance, + final DirectiveInterface directives) { + blocks.put(instance, directives); + } + + public Object getDefaultValue(String key, String memberType) + throws UnknownDirectiveException { + return base.getDefaultValue(key, memberType); + } + + private abstract static class Prefix { + protected HierName prefix; + + public abstract Object process(final Object o); + + public void setPrefix(final HierName prefix) { + this.prefix = prefix; + } + } + + private static class PrefixNode extends Prefix { + public Object process(final Object o) { + return HierName.prefixName(prefix, (HierName) o); + } + } + + private static class PrefixHalfop extends Prefix { + public Object process(final Object o) { + final Pair p = (Pair) o; + final HierName node = (HierName) p.getFirst(); + return new Pair(HierName.prefixName(prefix, node), p.getSecond()); + } + } + + private static class PrefixChannel extends Prefix { + public Object process(final Object o) { + return prefix.getAsString('.') + '.' + (String) o; + } + } + + private static class PrefixAlintScenario extends Prefix { + public Object process(final Object o) { + if (o == null) return o; + + final TupleValue tv = (TupleValue) o; + final Collection result = new ArrayList(); + for (Iterator i = tv.getIterator(); i.hasNext(); ) { + final AlintFaninValue afv = (AlintFaninValue) i.next(); + result.add( + afv.newInstanceName( + HierName.prefixName(prefix, afv.getNode()))); + } + return new TupleValue(result.toArray(new Value[0])); + } + } + + private static class PrefixArray extends Prefix { + private final Prefix element; + public PrefixArray(final Prefix element) { + this.element = element; + } + public void setPrefix(final HierName prefix) { + element.setPrefix(prefix); + } + public Object process(final Object o) { + if (o == null) return o; + + final Collection c = (Collection) o; + final ArrayList result = new ArrayList(); + for (Iterator i = c.iterator(); i.hasNext(); ) { + result.add(element.process(i.next())); + } + return Collections.unmodifiableList(result); + } + } + + private interface Extract { + Pair getParts(final Object o, final Set prefixes); + } + + private static Pair getParts(final HierName n, final Set prefixes) { + final HierName head = n.head(); + final HierName tail = n.tail(); + return tail != null && prefixes.contains(head) ? + new Pair(head, tail) : null; + } + + private static class ExtractNode implements Extract { + public Pair getParts(final Object o, final Set prefixes) { + return PrefixDirective.getParts((HierName) o, prefixes); + } + } + + private static class ExtractHalfop implements Extract { + public Pair getParts(final Object o, final Set prefixes) { + final Pair p = (Pair) o; + final Pair r = PrefixDirective.getParts(((HierName) p.getFirst()), prefixes); + return r == null ? null : + new Pair(r.getFirst(), new Pair(r.getSecond(), p.getSecond())); + } + } + + private static class ExtractChannel implements Extract { + public Pair getParts(final Object o, final Set prefixes) { + final HierName h; + try { + h = HierName.makeHierName((String) o, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot make HierName:" + o, e); + } + return PrefixDirective.getParts(h, prefixes); + } + } + + /** + * How to inline the given type? + **/ + private Prefix howPrefix(final String type) { + if (DirectiveTable.isArray(type)) { + final Prefix element = howPrefix(DirectiveTable.deArray(type)); + if (element == null) { + return null; + } else { + return new PrefixArray(element); + } + } + + if (type.equals(NODE_TYPE)) { + return new PrefixNode(); + } else if (type.equals(HALFOP_TYPE) || + type.equals(DEEP_HALFOP_TYPE)) { + return new PrefixHalfop(); + } else if (type.equals(POSSIBLY_WIDE_CHANNEL_TYPE) || + type.equals(WIDE_CHANNEL_TYPE)) { + return new PrefixChannel(); + } else if (type.equals(ALINT_SCENARIO_TYPE)) { + return new PrefixAlintScenario(); + } else { + return null; + } + } + + /** + * How to extract the prefix and suffix for a given type? + **/ + private Extract howExtract(final String type) { + if (type.equals(NODE_TYPE)) { + return new ExtractNode(); + } else if (type.equals(HALFOP_TYPE)) { + return new ExtractHalfop(); + } else if (type.equals(POSSIBLY_WIDE_CHANNEL_TYPE) || + type.equals(WIDE_CHANNEL_TYPE)) { + return new ExtractChannel(); + } else { + return null; + } + } + + private Triplet how(String key, String memberType) throws UnknownDirectiveException { + final Triplet[] triplet = + DirectiveTable.lookupParameterizedDirective(type, key); + if (triplet == null) { + throw new UnknownDirectiveException(key + ":" + memberType); + } + Triplet spec = null; + for (int i = 0; i < triplet.length; ++i) { + if (triplet[i].getFirst().equals(memberType)) { + spec = triplet[i]; + break; + } + } + if (spec == null) { + throw new UnknownDirectiveException(key + ":" + memberType); + } + + return new Triplet(howPrefix((String) spec.getFirst()), + howPrefix((String) spec.getSecond()), + howExtract((String) spec.getFirst())); + } + + private Object augment(final Prefix prefix, final Object o) { + if (prefix != null) { + return prefix.process(o); + } else { + return o; + } + } + + /** + * Augment the result map with key value pairs from an inlined cell, + * prefixing things as necessary. + **/ + private void augment(final Map result, final Map directive, + final Prefix member, final Prefix value) { + + if (member != null || value != null) { + final Set entries = directive.entrySet(); + for (Iterator i = entries.iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Object key = augment(member, entry.getKey()); + final Object val = augment(value, entry.getValue()); + result.put(key, val); + } + } else { + result.putAll(directive); + } + } + + public Map getValues(String key, String memberType) throws UnknownDirectiveException { + Map result = null; + if (valuesCache == null) { + valuesCache = new HashMap,Map>(); + } + final Pair keyType = + new Pair(key, memberType); + result = valuesCache.get(keyType); + + if (result != null) return result; + + final Triplet t = how(key, memberType); + final Prefix member = (Prefix) t.getFirst(); + final Prefix value = (Prefix) t.getSecond(); + + result = new HashMap(base.getValues(key, memberType)); + valuesCache.put(keyType, result); + + for (Map.Entry entry : + blocks.entrySet()) { + final HierName instance = entry.getKey(); + final DirectiveInterface dir = entry.getValue(); + if (member != null) member.setPrefix(instance); + if (value != null) value.setPrefix(instance); + augment(result, dir.getValues(key, memberType), member, value); + } + + return result; + } + + public Object lookup(String key) throws UnknownDirectiveException { + return base.lookup(key); + } + + public boolean containsDirective(String key) throws UnknownDirectiveException { + return base.containsDirective(key); + } + + public Object lookup(String key, String memberType, Object parameter) + throws UnknownDirectiveException { + Object o = base.lookup(key, memberType, parameter); + if (o != base.getDefaultValue(key, memberType)) return o; + + final Triplet t = how(key, memberType); + final Prefix value = (Prefix) t.getSecond(); + final Extract extract = (Extract) t.getThird(); + HierName prefix = null; + if (extract != null) { + final Pair parts = extract.getParts(parameter, blocks.keySet()); + if (parts != null) { + prefix = (HierName) parts.getFirst(); + final DirectiveInterface dir = blocks.get(prefix); + o = dir.lookup(key, memberType, parts.getSecond()); + } + } else { + for (Map.Entry entry : + blocks.entrySet()) { + final DirectiveInterface dir = entry.getValue(); + o = dir.lookup(key, memberType, parameter); + if (o != dir.getDefaultValue(key, memberType)) { + prefix = entry.getKey(); + break; + } + } + } + + if (value != null && prefix != null) { + value.setPrefix(prefix); + return augment(value, o); + } else { + return o; + } + } + + public boolean isKey(String key) { + return base.isKey(key); + } + + public boolean isKey(String key, String memberType) { + return base.isKey(key, memberType); + } + + public Iterator paramEntryIterator() { + final HashMap result = new HashMap(); + + for (Iterator i = base.paramEntryIterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + result.put(entry.getKey(), new HashMap((Map) entry.getValue())); + } + + for (Map.Entry entry : + blocks.entrySet()) { + final HierName instance = entry.getKey(); + final DirectiveInterface dir = entry.getValue(); + for (Iterator j = dir.paramEntryIterator(); j.hasNext(); ) { + final Map.Entry sentry = (Map.Entry) j.next(); + final Pair keytype = (Pair) sentry.getKey(); + + final Triplet t; + try { + t = how((String) keytype.getFirst(), + (String) keytype.getSecond()); + } catch (UnknownDirectiveException e) { + throw new RuntimeException(e); + } + final Prefix member = (Prefix) t.getFirst(); + final Prefix value = (Prefix) t.getSecond(); + + if (member != null) member.setPrefix(instance); + if (value != null) value.setPrefix(instance); + + Map sresult = (Map) result.get(keytype); + if (sresult == null) { + sresult = new HashMap(); + result.put(keytype, sresult); + } + + final Map values = (Map) sentry.getValue(); + augment(sresult, values, member, value); + } + } + + return result.entrySet().iterator(); + } + + public Iterator noparamEntryIterator() { + return base.noparamEntryIterator(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/SubcellBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/SubcellBlock.java new file mode 100644 index 0000000000..7bdc3d7439 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/SubcellBlock.java @@ -0,0 +1,49 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast; + +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.util.debug.Debug; + +/** + * Represents all the data stored in the subcell block of castv2. Right now, + * this is just a place holder to attach a directives block. + **/ + +public class SubcellBlock extends BlockCommon { + public SubcellBlock() { + } + + public String getType() { + return BlockInterface.SUBCELL; + } + + public void refineFrom(final BlockInterface o) { + super.refineFrom(o); + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "SubcellBlock doesn't support all BlockInterface functionality"); + return null; + } + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "SubcellBlock doesn't support all BlockInterface functionality"); + return null; + } + + public String toString() { + return "SubcellBlock()"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/VerilogBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/VerilogBlock.java new file mode 100644 index 0000000000..00f1c5118c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/VerilogBlock.java @@ -0,0 +1,312 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import com.avlsi.cell.CellImpl; +import com.avlsi.fast.BlockInterface; +import com.avlsi.util.container.FlatteningIterator; +import com.avlsi.util.debug.Debug; + +/** + * A class to represent named verilog blocks in a cell. For example: + *
    + * define TEST()(node +a, -b) {
    + *   verilog {
    + *     rtl {
    + *       TEST_RTL (a, b) : 'test_rtl.v';
    + *     }
    + *     gate {
    + *       TEST_GATE (.a(a), .b(b)) : 'test_gate.v';
    + *     }
    + *   }
    + * }
    + * 
    + * Each VerilogBlock contains any number of + * NamedBlocks, each of which contains any number of + * Instances. See the CASTv2 spec for more information. + **/ +public class VerilogBlock extends BlockCommon { + /** + * Represent an instantiation of a verilog module. There are 2 ways to + * make the connections between CAST and Verilog: by implicit ordering of + * the ports (the TEST_RTL example) or by explicit naming of ports (the + * TEST_GATE example). + **/ + public static class Instance { + private final String module; + private final List parameters; + private final List files; + private final List impliedPorts; + private final Map explicitPorts; + public Instance(final String module, final List parameters, + final List impliedPorts, final Map explicitPorts, + final List files) { + this.module = module; + this.parameters = parameters; + this.impliedPorts = impliedPorts; + this.explicitPorts = explicitPorts; + this.files = files; + assert (impliedPorts == null) != (explicitPorts == null); + } + + /** + * Get the name of the verilog module being instantiated. + * + * @return Name of the verilog module. + **/ + public String getModule() { + return module; + } + + /** + * Return parameters of the instantiation. + **/ + public Iterator getParameters() { + return parameters.iterator(); + } + + /** + * Get a list of files this is depended on by the verilog module. + * + * @return An iterator of Strings. + **/ + public Iterator getFiles() { + return files.iterator(); + } + + /** + * Get a list of ports that are used to instantiate the verilog module. + * The order of the ports as specified by the iterator is the order + * that they were specified in CAST. + * + * @return An iterator of Strings, or null if + * port connections is specified explicitly. + **/ + public Iterator getPortsByOrder() { + return impliedPorts == null ? null : impliedPorts.iterator(); + } + + /** + * Get a list of ports that are used to instantiate the verilog module. + * The result is an iterator over a Map. The key is the + * name of the port in Verilog, and the value is the value of the CAST + * expression to pass in to that port. + * + * @return An iterator of Map.Entrys (String + * to Value), or null if port connections is + * specified implicitly. + **/ + public Iterator getPortsByName() { + return explicitPorts == null ? null : explicitPorts.entrySet().iterator(); + } + } + + public static abstract class NamedBlock extends BlockCommon { + @Override + public String getType() { + return BlockInterface.VERILOG; + } + + @Override + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "VerilogBlock does not support merge"); + return null; + } + + @Override + public void refineFrom(final BlockInterface nb) { + super.refineFrom(nb); + } + + @Override + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "VerilogBlock does not support replace"); + return null; + } + + /** + * Add a verilog module instantiate to this verilog block. + * + * @param inst the instance to add + **/ + public abstract void addInstance(final Instance inst); + + /** + * Get an iterator over all verilog module instantiations in this + * verilog block. + * + * @return an iterator of Instances. + **/ + public abstract Iterator getInstances(); + + /** + * Add a list of files depended on by this verilog block. + * + * @param a list of Strings + **/ + public abstract void addFiles(final List files); + + /** + * Get a list of files depended on by this verilog block. + * + * @return an iterator of Strings. + **/ + public abstract Iterator getFiles(); + + /** + * Get the name of this verilog block. + * + * @return name of the verilog block. + **/ + public abstract String getName(); + } + + public static class SimpleNamedBlock extends NamedBlock { + private final List instances; + private final LinkedList files; + private final String name; + + public SimpleNamedBlock(final String name) { + this.name = name; + this.instances = new ArrayList(); + this.files = new LinkedList(); + } + + @Override + public void addInstance(final Instance inst) { + instances.add(inst); + } + + @Override + public Iterator getInstances() { + return instances.iterator(); + } + + @Override + public void addFiles(final List files) { + this.files.addAll(files); + } + + @Override + public Iterator getFiles() { + return files.iterator(); + } + + @Override + public String getName() { + return name; + } + } + + private static class MergedNameBlock extends NamedBlock { + private final NamedBlock parent; + private final NamedBlock child; + + public MergedNameBlock(final NamedBlock parent, + final NamedBlock child) { + this.parent = parent; + this.child = child; + refineFrom(parent); + refineFrom(child); + } + + @Override + public void addInstance(final Instance inst) { + throw new AssertionError("addInstance shouldn't be called"); + } + + @Override + public Iterator getInstances() { + final Iterator i = child.getInstances(); + return i.hasNext() ? i : parent.getInstances(); + } + + @Override + public void addFiles(final List files) { + throw new AssertionError("addFiles shouldn't be called"); + } + + @Override + public Iterator getFiles() { + return new FlatteningIterator( + Arrays.asList(parent.getFiles(), + child.getFiles()).iterator()); + } + + @Override + public String getName() { + return parent.getName(); + } + } + + + private Map namedBlocks; + + public VerilogBlock() { + this.namedBlocks = new HashMap(); + } + + public String getType() { + return BlockInterface.VERILOG; + } + + public void addNamedBlock(final NamedBlock block) { + namedBlocks.put(block.getName(), block); + } + + /** + * Get the verilog block associated with a particular name. + * + * @param name Which verilog block to return + * @return A NamedBlock associated with name or + * null if there is no block by that name. + **/ + public NamedBlock getNamedBlock(final String name) { + return (NamedBlock) namedBlocks.get(name); + } + + /** + * Get an iterator over all named verilog blocks. + * + * @return An iterator of Strings. + **/ + public Iterator getNamesIterator() { + return namedBlocks.keySet().iterator(); + } + + public BlockInterface merge(BlockInterface o) { + Debug.assertTrue(false, "VerilogBlock does not support merge"); + return null; + } + + public void refineFrom(BlockInterface o) { + super.refineFrom(o); + final VerilogBlock vb = (VerilogBlock) o; + for (Iterator i = vb.getNamesIterator(); i.hasNext(); ) { + final String name = (String) i.next(); + final NamedBlock onb = vb.getNamedBlock(name); + final NamedBlock nb = getNamedBlock(name); + addNamedBlock(nb == null ? onb + : new MergedNameBlock(onb, nb)); + } + } + + public BlockInterface replace(BlockInterface o) { + Debug.assertTrue(false, "VerilogBlock does not support replace"); + return null; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/ArrayMetaParam.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/ArrayMetaParam.java new file mode 100644 index 0000000000..62c086936a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/ArrayMetaParam.java @@ -0,0 +1,97 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.metaparameters; + +import com.avlsi.util.exception.AssertionFailure; + +/** + * Class representing arrayed types in metaparameter list. (Modified from + * com.avlsi.fast.ports.ArrayType) + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public final class ArrayMetaParam implements MetaParamTypeInterface { + /** Array of elements **/ + private final MetaParamTypeInterface[] elements; + + /** Minimum index for array. **/ + private final int min; + + /** Maximum index for array. **/ + private final int max; + + /** + * Class constructor. + * + * @param elements Array of element values + * @param min minimum index for array + * @param max maximum index for array + **/ + public ArrayMetaParam( final MetaParamTypeInterface[] elements, + final int min, final int max ){ + this.elements = elements; + this.min = min; + this.max = max; + + if( max - min + 1 != elements.length ) + throw new AssertionFailure( + "Array initializer has wrong length" ); + } + + /** + * Returns arrayed type. + * + * @return arrayed type, not null + **/ + public MetaParamTypeInterface getArrayedType() { + if( max < min ) + throw new AssertionFailure( "Array has nonpositive size." ); + + return elements[0]; + } + + /** + * Returns an array element. + * + * @param index The index of the MetaParamTypeInterface array element + * to return. + * @return The array element with the specified index. + **/ + public MetaParamTypeInterface get( int i ){ + return elements[i - min]; + } + + /** + * Returns minimum index for array. + * + * @return minimum index for array + **/ + public int getMinIndex(){ + return min; + } + + /** + * Returns maximum index for array. + * + * @return maximum index for array + **/ + public int getMaxIndex(){ + return max; + } + + public String toString(){ + return getArrayedType().toString() + '[' + min + ".." + max + ']'; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/BooleanMetaParam.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/BooleanMetaParam.java new file mode 100644 index 0000000000..fab8851311 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/BooleanMetaParam.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.metaparameters; +import java.math.BigInteger; + +/** + * Interface representing boolean metaparameter types. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public interface BooleanMetaParam extends MetaParamTypeInterface { + String toString(); + boolean toBoolean(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/FloatMetaParam.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/FloatMetaParam.java new file mode 100644 index 0000000000..9dedd2adba --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/FloatMetaParam.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.metaparameters; + +/** + * Interface representing floating point metaparameter types. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public interface FloatMetaParam extends MetaParamTypeInterface { + String toString(); + float toFloat(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/IntegerMetaParam.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/IntegerMetaParam.java new file mode 100644 index 0000000000..6b938deb39 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/IntegerMetaParam.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.metaparameters; + +import java.math.BigInteger; + +/** + * Interface representing integer metaparameter types. + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public interface IntegerMetaParam extends MetaParamTypeInterface { + String toString(); + BigInteger toBigInteger(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamDefinition.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamDefinition.java new file mode 100644 index 0000000000..7e0daf003c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamDefinition.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.metaparameters; + +/** + * A metaparameter variable definition, consisting of its type and name. + * (Modified from com.avlsi.fast.ports.PortDefinition.) + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public final class MetaParamDefinition { + + /** Meta-parameter name, not null. **/ + private final String name; + + /** Meta-parameter type, not null. **/ + private final MetaParamTypeInterface type; + + /** + * Class constructor + * + * @param name metaparameter name, not null + * @param type metaparameter type, not null + **/ + public MetaParamDefinition(final String name, + final MetaParamTypeInterface type) { + this.name = name; + this.type = type; + } + + /** + * Returns the metaparameter variable name. + * + * @return param name, not null + **/ + public String getName() { + return name; + } + + /** + * Returns the metaparameter type. + * + * @return param type, not null + **/ + public MetaParamTypeInterface getType() { + return type; + } + + public String toString() { + return name + ": " + ' ' + type.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamTypeInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamTypeInterface.java new file mode 100644 index 0000000000..7f1f2dd4af --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/metaparameters/MetaParamTypeInterface.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.metaparameters; + +import com.avlsi.fast.ParamTypeInterface; + +/** + * Tagging interface for types of metaparameters. (Copied and modified from + * com.avlsi.fast.ports.PortTypeInterface.) + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public interface MetaParamTypeInterface extends ParamTypeInterface { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ArrayType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ArrayType.java new file mode 100644 index 0000000000..d365dc56bc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ArrayType.java @@ -0,0 +1,77 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.ports; + +/** + * Class representing arrayed types in port list. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class ArrayType implements PortTypeInterface { + + /** Type being arrayed, not null. **/ + private final PortTypeInterface arrayedType; + + /** Minimum index for array. **/ + private final int min; + + /** Maximum index for array. **/ + private final int max; + + /** + * Class constructor. + * + * @param arrayedType type being arrayed + * @param min minimum index for array + * @param max maximum index for array + **/ + public ArrayType(final PortTypeInterface arrayedType, + final int min, final int max) { + this.arrayedType = arrayedType; + this.min = min; + this.max = max; + } + + /** + * Returns arrayed type. + * + * @return arrayed type, not null + **/ + public PortTypeInterface getArrayedType() { + return arrayedType; + } + + /** + * Returns minimum index for array. + * + * @return minimum index for array + **/ + public int getMinIndex() { + return min; + } + + /** + * Returns maximum index for array. + * + * @return maximum index for array + **/ + public int getMaxIndex() { + return max; + } + + public String toString() { + return arrayedType.toString() + '[' + min + ".." + max + ']'; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ChannelType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ChannelType.java new file mode 100644 index 0000000000..92a9ee2863 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/ChannelType.java @@ -0,0 +1,120 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.ports; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +/** + * Class representing a simple channel type (a channel which contains + * only nodes, and can be represented by a ChannelInput or + * ChannelOutput. These are e1ofNs and e1ofN[M]s.) + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class ChannelType implements PortTypeInterface { + + /** CAST Type name for the channel, not null. **/ + private final String typeName; + + /** + * Width of channel, the number of typeName's comprising + * channel. width > 0 + **/ + private final int width; + + /** + * Tells if this is an arrayed ChannelType. This is used by SubtypeOutput + * to differentiate e1of4[1] from e1of4 which both have width of 1, but are + * incompatible for refinement. + **/ + private final boolean arrayed; + + /** + * Describes ports for this channel. + **/ + private final Collection/**/ subPortsList; + + /** + * Class constructor. + * + * @param typeName CAST type name, not null + **/ + public ChannelType(final Iterator/**/ ports, + final String typeName) { + this(ports, typeName, 1, false); + } + + /** + * Class constructor. Use this constructor to represent a type that would + * require a bracket in CAST, e.g., e1of4[1]. + * + * @param typeName CAST type name, not null + * @param width number of typeName's comprising channel, + * width > 0. + **/ + public ChannelType(final Iterator/**/ ports, + final String typeName, + final int width) { + this(ports, typeName, width, true); + } + + private ChannelType(final Iterator/**/ ports, + final String typeName, + final int width, final boolean arrayed) { + assert ports != null && typeName != null && width > 0; + this.typeName = typeName; + this.width = width; + this.arrayed = arrayed; + this.subPortsList = new ArrayList/**/(); + while (ports.hasNext()) add((PortDefinition) ports.next()); + } + + /** + * Returns the CAST type name. + * + * @return channel's CAST type name, not null + **/ + public String getTypeName() { + return typeName; + } + + /** + * Returns the channel's width, ie number of typeName's + * comprising the channel. + * + * @return channel's width + **/ + public int getWidth() { + return width; + } + + public boolean isArrayed() { + return arrayed; + } + + public String toString() { + return typeName + (width > 1 ? "*" + width : ""); + } + + private void add(PortDefinition p) { + subPortsList.add(p); + } + + public Iterator/**/ iterator() { + return subPortsList.iterator(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/NodeType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/NodeType.java new file mode 100644 index 0000000000..94303d699a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/NodeType.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.ports; + +/** + * Class representing node types. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class NodeType implements PortTypeInterface { + private final int width; + private final boolean arrayed; + + public NodeType() { + this.width = 1; + this.arrayed = false; + } + + public NodeType(final int width) { + this.width = width; + this.arrayed = true; + } + + /** + * Returns the channel's width, ie number of typeName's + * comprising the channel. + * + * @return channel's width + **/ + public int getWidth() { + return width; + } + + public boolean isArrayed() { + return arrayed; + } + + public String toString() { + return "node of width " + width; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortDefinition.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortDefinition.java new file mode 100644 index 0000000000..a444e19286 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortDefinition.java @@ -0,0 +1,184 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.ports; + +/** + * A port variable definition, consisting of its name, type, and direction. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class PortDefinition { + + /** + * Direction specifier used for nodes or channels whose direction is + * unspecified. + * **/ + public static final int NONE = -1; + + /** Direction specifier used for IN nodes or channels. **/ + public static final int IN = 0; + public static final String INSTRING = "-"; + + /** Direction specifier used for OUT nodes or channels. **/ + public static final int OUT = 1; + public static final String OUTSTRING = "+"; + + /** Direction specifier used for INOUT nodes or channels. **/ + public static final int INOUT = 2; + public static final String INOUTSTRING = ""; + + /** + * Synonyms for IN/OUT/INOUT which may be more intuitive when sub-channels + * are involved. + **/ + + /** Direction specifier used for REVERSE sub-nodes or sub-channels. **/ + public static final int REVERSE = IN; + + /** Direction specifier used for FORWARD sub-nodes or sub-channels. **/ + public static final int FORWARD = OUT; + + /** Direction specifier used for BIDIRECTIONAL sub-nodes or sub-channels.**/ + public static final int BIDIRECTIONAL = INOUT; + + /** Port name, not null. **/ + private final String name; + + /** Port type, not null. **/ + private final PortTypeInterface type; + + /** Port direction, either IN, OUT, or INOUT. **/ + private final int direction; + + /** + * Class constructor + * + * @param name port name, not null + * @param type port type, not null + * @param direction port direction, IN, OUT, or INOUT + **/ + public PortDefinition(final String name, + final PortTypeInterface type, + final int direction) { + this.name = name; + this.type = type; + this.direction = direction; + } + + /** + * Returns the port variable name. + * + * @return port name, not null + **/ + public String getName() { + return name; + } + + /** + * Returns the port type. + * + * @return port type, not null + **/ + public PortTypeInterface getType() { + return type; + } + + /** + * Returns the port direciton, either IN, OUT, or INOUT. + * + * @return port direction + **/ + public int getDirection() { + return direction; + } + + /** + * Returns the reverse of the port direction, either IN, OUT, or INOUT. + * + * @return reverse of the port direction + **/ + public int getReverseDirection() { + switch (direction) { + case IN: + return OUT; + case OUT: + return IN; + case INOUT: + return INOUT; + default: + return NONE; + } + } + + + private String directionString() { + switch (direction) { + case IN: + return "in"; + case OUT: + return "out"; + case INOUT: + return "inout"; + default: + return ""; + } + } + + private String subPortDirectionString() { + switch (direction) { + case REVERSE: + return "reverse"; + case FORWARD: + return "forward"; + case BIDIRECTIONAL: + return "bidirectional"; + default: + return ""; + } + } + + + /** + * Updates the port direction (in, out, etc) with the specified + * direction modifier (forward, reverse, bidirectional). + **/ + public static int updateDirection(final int originalDirection, + final int directionModifier) { + switch (directionModifier) { + case PortDefinition.FORWARD: + return originalDirection; + + case PortDefinition.REVERSE: + switch (originalDirection) { + case PortDefinition.IN: + return PortDefinition.OUT; + case PortDefinition.OUT: + return PortDefinition.IN; + case PortDefinition.INOUT: + case PortDefinition.NONE: + return PortDefinition.INOUT; + } + throw new AssertionError("Unknown port direction"); + + case PortDefinition.BIDIRECTIONAL: + return PortDefinition.INOUT; + } + + throw new AssertionError("Unknown port direction"); + } + + + public String toString() { + return name + ": " + directionString() + ' ' + type.toString(); + } + + public String toSubPortString() { + return name + ": " + directionString() + ' ' + type.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortTypeInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortTypeInterface.java new file mode 100644 index 0000000000..73f1cc94e6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/PortTypeInterface.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.ports; + +import com.avlsi.fast.ParamTypeInterface; + +/** + * Tagging interface for types of ports. Provides minimal functionality. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface PortTypeInterface extends ParamTypeInterface { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/StructureType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/StructureType.java new file mode 100644 index 0000000000..8f02ac2142 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/ports/StructureType.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.fast.ports; + +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; + +/** + * Class representing structured types in port list (a channel which + * contains other channels and therefore can't be represented by a + * ChannelInput or a ChannelOutput). + * + * @author David Hilvert + * @version $Revision$ $Date$ + **/ +public final class StructureType implements PortTypeInterface { + private List subPortsList; + /** + * Fully qualified name of this structured type; maybe null. + **/ + private String tag; + + public StructureType () { + subPortsList = new ArrayList(); + tag = null; + } + + public StructureType (Iterator i) { + this(i, null); + } + + public StructureType (Iterator i, String tag) { + subPortsList = new ArrayList(); + while (i.hasNext()) { + PortDefinition p = (PortDefinition) i.next(); + subPortsList.add (p); + } + this.tag = tag; + } + + public void add (PortDefinition p) { + subPortsList.add (p); + } + + public Iterator iterator () { + return subPortsList.iterator(); + } + + /** + * Returns the fully qualified name of this structured type, or + * null if it doesn't have a name. + **/ + public String getTag() { + return tag; + } + + public String toString() { + String result = "{"; + for (Iterator i = iterator(); i.hasNext(); ) { + PortDefinition p = i.next(); + result = result + p.toSubPortString() + ';'; + } + result = result + "}"; + + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ArgumentMismatchException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ArgumentMismatchException.java new file mode 100644 index 0000000000..4c614c4bc3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ArgumentMismatchException.java @@ -0,0 +1,17 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + + +public class ArgumentMismatchException extends Exception { + public ArgumentMismatchException(final String name, + int expected, + int found) { + super("ShapeFunction " + name + " expects " + expected + " arguments, found " + found + " arguments."); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Point.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Point.java new file mode 100644 index 0000000000..67c140ea54 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Point.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.fast.shapes; + +import com.avlsi.util.mathexpression.MathExpression; + +/** + Interface to a point used in the shapes block code. + @see com.avlsi.fast.shapes.Shape + @see com.avlsi.fast.shapes.ShapesBlock + */ +public interface Point { + /** + Gets the expression for the x-coordinate of the point. + @return A MathExpression for the x-coordinate of the point. + */ + MathExpression getX( ); + /** + Gets the expression for the y-coordinate of the point. + @return A MathExpression for the y-coordinate of the point. + */ + MathExpression getY( ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Polygon.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Polygon.java new file mode 100644 index 0000000000..8f0540b5bd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Polygon.java @@ -0,0 +1,24 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +/** + Interface to a polygon. + */ +public interface Polygon { + /** + @return An iterator that will iterate over all the points in the + polygon. + */ + PolygonIterator iterator(); + + /** + @return Returns the number of points in the polygon. + */ + int size(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/PolygonIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/PolygonIterator.java new file mode 100644 index 0000000000..5c3084bdab --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/PolygonIterator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.Point; + +import java.util.NoSuchElementException; + +/** + Iterator iterface used to iterate over all the points in a polygon. + */ +public interface PolygonIterator { + /** + Gets the next point in the polygon. Throws + NoSuchElementException if there are no more points + in the polygon. + @return The next point in the polygon. + */ + Point next(); + /** + Determines if there are any more points in the polygon. + @return true if there are one or more points remaining in the iterator. + */ + boolean hasNext(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Shape.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Shape.java new file mode 100644 index 0000000000..bc94ef7b5f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/Shape.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.ShapeIterator; +import com.avlsi.fast.shapes.Point; + + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +import com.avlsi.util.mathexpression.MathExpression; + +/** + Interface to a shape. + */ +public interface Shape { + /** + @return A string expression for the name of the layer the shape + is to be drawn on. + */ + StringExpression getLayerName( ); + + /** + @return A string expression which evaluates to the name + of the net the shape should be attached to or null if the + shape should not be attached to any net. + */ + StringExpression getNetName( ); + + /** + @return An iterator that will iterate over all the polygons + in the shape. + */ + ShapeIterator iterator(); + + /** + @return The location of the shape's origin + in the refering cell. + */ + Point getOrigin(); + + /** + @return null if the shape is not repeated along the x-axis, + otherwise an expression that evaluates to the distance + along the x-axis between repitions of a repeated shape. + When this method does not return null, then the x-coordinate + of the point returned from getOrigin should be ignored. + The left most repition should put the x-coordinate of its origin + at the left edge of the shape on the repeat boundary layer. + The last repition should be entirely entirely enclosed by the + shape on the boundary layer. + */ + MathExpression getXRepeat(); + /** + @return null if the shape is not repeated along the y-axis, + otherwise an expression that evaluates to the distance + along the y-axis between repitions of a repeated shape. + When this method does not return null, then the y-coordinate + of the point returned from getOrigin should be ignored. + The bottom most repition should put the y-coordinate of its origin + at the bottom edge of the shape on the repeat boundary layer. + The last repition should be entirely entirely enclosed by the + shape on the boundary layer. + */ + MathExpression getYRepeat(); + + /** + @return A string expression that evaluates to the name + of the repeat boundary layer. + */ + StringExpression getRepeatBoundaryLayer(); + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollection.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollection.java new file mode 100644 index 0000000000..4e49af7de1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollection.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.ShapeCollectionIterator; + +/** + Iterface to a collection of shapes. + @see com.avlsi.fast.shapes.Shape + */ +public interface ShapeCollection { + /** + @return An interator that will iterate through all the shapes + in the collection. + */ + ShapeCollectionIterator iterator(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollectionIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollectionIterator.java new file mode 100644 index 0000000000..7824aba42e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeCollectionIterator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.Shape; + +import java.util.NoSuchElementException; + +/** + Iterface to an iterator that enumerates all the shapes + in a collection of shapes. + @see com.avlsi.fast.shapes.ShapeCollection + */ +public interface ShapeCollectionIterator { + + /** + @return The next shape in the shape collection being iterated. + */ + Shape next(); + + /** + @return true if the shape collection has more shapes. + */ + boolean hasNext(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFactory.java new file mode 100644 index 0000000000..b590cc2bde --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + + +import java.util.Collection; + +import com.avlsi.fast.shapes.ShapeFunction; +import com.avlsi.fast.shapes.Point; +import com.avlsi.fast.shapes.Polygon; +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.util.mathexpression.MathExpression; + +public interface ShapeFactory { + ShapeFunction makeShapeFunction(final String name, + final StringExpression layer, + final StringExpression net, + boolean repeatx, boolean repeaty, + final StringExpression boundary, + final Point origin, + String[] mathParams, + String[] stringParams); + + Point makePoint(final MathExpression xExp, + final MathExpression yExp); + + Polygon makePolygon(final Collection c); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunction.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunction.java new file mode 100644 index 0000000000..6809dcf7d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunction.java @@ -0,0 +1,69 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import java.util.Set; + +import com.avlsi.fast.shapes.ShapeCollection; +import com.avlsi.fast.shapes.ShapeFunctionTable; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.util.mathexpression.ExpressionCollection; + +/** + Interface to a compiled ShapeFunction. A ShapeFunction contains a list of + statements. A statement is either a list of points, or a call to another + ShapeFunction. + */ +public interface ShapeFunction { + /** + Gets the name of the function. + @return Name of the function. + */ + String getName(); + + /** + Recursively evaluates this function so that all calls to other shape + functions are removed. + @param table A map from String to ShapeFunction, used to look up + function calls. + @param seen A Set of function names that should not be called again, to + avoid recursion (since there is no control statements in the Shapes + language). + @return All the shapes that this ShapeFunction generated in a + ShapeCollection. + */ + ShapeCollection resolve(final ShapeFunctionTable table, + final Set seen, + final ExpressionCollection mathArgs, + final StringExpressionCollection stringArgs); + + /** + Recursively evaluates the anonymous function returned by the parser. + @param table A map from String to ShapeFunction, used to look up + function calls. + @return All the shapes that this ShapeFunction generated in a + ShapeCollection. + */ + ShapeCollection resolve(final ShapeFunctionTable table); + + /** + Add a function call to the body of this function. + @param name Name of the function to call. + @param mathArgs Arguments to be bound to MathExpressions. + @param stringArgs Arguments to be bound to StringExpressions. + */ + void addFunctionCall(final String name, + final ExpressionCollection mathArgs, + final StringExpressionCollection stringArgs); + + /** + Add a polygon to the body of this function. + @param poly Polygon to add. + */ + void addPolygon(final Polygon poly); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionRedefinedException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionRedefinedException.java new file mode 100644 index 0000000000..cdb9c56a8a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionRedefinedException.java @@ -0,0 +1,15 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + + +public class ShapeFunctionRedefinedException extends Exception { + public ShapeFunctionRedefinedException(final String func) { + super("ShapeFunction " + func + " redefined."); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionTable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionTable.java new file mode 100644 index 0000000000..591e21aa73 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionTable.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + + +import com.avlsi.fast.shapes.ShapeFunction; +import com.avlsi.fast.shapes.ShapeFunctionUndefinedException; + +/** + Interface to a symbol table of ShapeFunctions. + */ +public interface ShapeFunctionTable { + /** + Finds the ShapeFunction associated with a name. + @param name Name of the function to lookup. + @return The ShapeFunction associated with the specified name. + @throws ShapeFunctionUndefinedException if the name was not found. + */ + ShapeFunction lookup(final String name) + throws ShapeFunctionUndefinedException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionUndefinedException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionUndefinedException.java new file mode 100644 index 0000000000..d124b973d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeFunctionUndefinedException.java @@ -0,0 +1,15 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + + +public class ShapeFunctionUndefinedException extends Exception { + public ShapeFunctionUndefinedException(final String func) { + super("ShapeFunction " + func + " undefined."); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeIterator.java new file mode 100644 index 0000000000..1abee52e62 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapeIterator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.Polygon; + +import java.util.NoSuchElementException; + +/** + Iterator interface used to iterate through + all the polygons in a shape. + @see com.avlsi.fast.shapes.Point + */ +public interface ShapeIterator { + /** + Returns the next polygon in the shape being iterated. + @return the next polygon in the shape being iterated. + */ + Polygon next(); + /** + Returns true if the shape has more polygons. + @return true if the shape has more polygons. + */ + boolean hasNext(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlock.java new file mode 100644 index 0000000000..82ab97397b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlock.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.ShapesBlockIterator; +import com.avlsi.fast.shapes.Shape; + +/** + Interface used by clients of JCast or JFast to interact + with shapes blocks. + @author Christopher A. Brichford ( chrisb@avlsi.com ) + @see com.avlsi.fast.shapes.ShapesBlockIterator + @see com.avlsi.fast.shapes.Shape + */ +public interface ShapesBlock { + ShapeCollection getShapes(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlockIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlockIterator.java new file mode 100644 index 0000000000..6d56d9b07c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/ShapesBlockIterator.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.Shape; + +import java.util.NoSuchElementException; +/** + Iterator interface used by the ShapesBlock interface. + Pretty generic iterator interface. + */ +public interface ShapesBlockIterator { + /** + Returns the next shape in the shapes block being iterated. + @return the next shape in the shapes block being iterated. + */ + Shape next(); + /** + Returns true if the shapes block has more shapes. + @return true if there are more shapes in the shapes block. + */ + boolean hasNext(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteablePoint.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteablePoint.java new file mode 100644 index 0000000000..f54067e664 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteablePoint.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.util.mathexpression.MathExpression; +/** + Interface to a point used in the shapes block code. + */ +public interface WriteablePoint extends Point { + /** + Sets the expression for the x-coordinate of the point. + @param Exp The expression for the x-coordinate of the point. + */ + void setX( MathExpression Exp ); + /** + Sets the expression for the x-coordinate of the point. + @param Exp The expression for the x-coordinate of the point. + */ + void setY( MathExpression Exp ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShape.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShape.java new file mode 100644 index 0000000000..82bad39b0c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShape.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.ShapeIterator; +import com.avlsi.fast.shapes.Point; + + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +import com.avlsi.util.mathexpression.MathExpression; + +/** + Interface to a writeable shape. + */ +public interface WriteableShape extends Shape { + /** + Add a polygon to this shape. + */ + void addPolygon(Polygon poly); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollection.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollection.java new file mode 100644 index 0000000000..b6760072c5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollection.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + + +import com.avlsi.fast.shapes.ShapeCollection; +import com.avlsi.fast.shapes.Shape; +import com.avlsi.fast.shapes.WriteableShapeCollectionIterator; + +/** + Iterface to a collection of shapes. + */ +public interface WriteableShapeCollection extends ShapeCollection { + /** + Add a shape to the collection of shapes. + @param newShape Shape to add to the collection + */ + void addShape( Shape newShape ); + + /** + @return An iterator that will enumerate all the shapes in the + collection. + */ + WriteableShapeCollectionIterator getWriteableIterator(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollectionIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollectionIterator.java new file mode 100644 index 0000000000..23e7b73a4c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeCollectionIterator.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.Shape; + +import java.util.NoSuchElementException; + +/** + Iterface to an iterator that enumerates all the shapes + in a collection of shapes. + @see com.avlsi.fast.shapes.ShapeCollection + */ +public interface WriteableShapeCollectionIterator { + + /** + @return The next shape in the shape collection being iterated. + */ + Shape next(); + + /** + @return true if the shape collection has more shapes. + */ + boolean hasNext(); + + /** + Remove the current shape from the collection. + Depending on the implementation of the collection, + this iterator may or not be valid after calling + this method. + */ + void remove(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeFunctionTable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeFunctionTable.java new file mode 100644 index 0000000000..5d1eacd7c2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapeFunctionTable.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + + +import com.avlsi.fast.shapes.ShapeFunction; +import com.avlsi.fast.shapes.ShapeFunctionRedefinedException; + +/** + Interface to a symbol table of ShapeFunctions. + */ +public interface WriteableShapeFunctionTable extends ShapeFunctionTable { + /** + Associate a ShapeFunction with a name. + @param name Name to bind to. + @param func ShapeFunction to be bound. + @throws ShapeFunctionRedefinedException if the name was already bound. + */ + void define(final String name, final ShapeFunction func) + throws ShapeFunctionRedefinedException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapesBlock.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapesBlock.java new file mode 100644 index 0000000000..f451ec732d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/WriteableShapesBlock.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes; + +import com.avlsi.fast.shapes.WriteableShapeCollection; +import com.avlsi.fast.shapes.ShapeCollection; + +/** + Interface used by clients of JCast or JFast to interact + with shapes blocks. This interface allows the user to modify + the contents of shapes block. + @author Christopher A. Brichford ( chrisb@avlsi.com ) + + */ +public interface WriteableShapesBlock extends ShapesBlock{ + /** + Addes the shapes in the specified collection to the block. + @param NewShapes Collection of shapes to add. + */ + void addShapes( ShapeCollection NewShapes ); + + /** + @return The collection of shapes stored in the block. + If a shape is removed from the collection then the shape will + be removed from the block. If a shape is added to the + collection than the shape will also be added to the block. + */ + WriteableShapeCollection getWriteableShapes(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/PolygonImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/PolygonImpl.java new file mode 100644 index 0000000000..5aac0b94a6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/PolygonImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + +import com.avlsi.fast.shapes.Point; +import com.avlsi.fast.shapes.Polygon; +import com.avlsi.fast.shapes.PolygonIterator; + +import java.util.Collection; +import java.util.NoSuchElementException; + +/** + Default implementation for Polygon. Points are stored in an array to make + this class relatively cheap. There is no way to modify the polygon after + it's been constructed. + */ +public class PolygonImpl implements Polygon { + /** + Storage for points. + */ + protected Point[] points; + + /** + Construct a polygon from an array of Points. + @see com.avlsi.fast.shapes.Point + @param points Array of Points to construct the polygon from. + */ + public PolygonImpl(final Point[] points) { + this.points = new Point[points.length]; + System.arraycopy(points, 0, this.points, 0, points.length); + } + + /** + Construct a polygon from a Collection of Points. + @see com.avlsi.fast.shapes.Point + @param c Collection of Points to construct the polygon from. + */ + public PolygonImpl(final Collection c) { + points = (Point[]) c.toArray(new Point[0]); + } + + public PolygonIterator iterator() { + return new PolygonIterator() { + private int index = 0; + + public Point next() { + if (index < points.length) { + return points[index++]; + } else { + throw(new NoSuchElementException()); + } + } + + public boolean hasNext() { + return index < points.length; + } + }; + } + + public int size() { + return points.length; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFactoryImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFactoryImpl.java new file mode 100644 index 0000000000..6d96f657f1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFactoryImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + + +import java.util.Collection; + +import com.avlsi.fast.shapes.ShapeFactory; +import com.avlsi.fast.shapes.ShapeFunction; +import com.avlsi.fast.shapes.Point; +import com.avlsi.fast.shapes.Polygon; +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.impl.ShapeFunctionImpl; +import com.avlsi.fast.shapes.impl.WriteablePointImpl; +import com.avlsi.fast.shapes.impl.PolygonImpl; + +import com.avlsi.util.mathexpression.MathExpression; + +public class ShapeFactoryImpl implements ShapeFactory { + public ShapeFunction makeShapeFunction(final String name, + final StringExpression layer, + final StringExpression net, + boolean repeatx, boolean repeaty, + final StringExpression boundary, + final Point origin, + String[] mathParams, + String[] stringParams) { + return new ShapeFunctionImpl(name, layer, net, repeatx, repeaty, + boundary, origin, mathParams, + stringParams); + } + + public Point makePoint(final MathExpression xExp, + final MathExpression yExp) { + return new WriteablePointImpl(xExp, yExp); + } + + public Polygon makePolygon(final Collection c) { + return new PolygonImpl(c); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFunctionImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFunctionImpl.java new file mode 100644 index 0000000000..6d5a519ebe --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/ShapeFunctionImpl.java @@ -0,0 +1,310 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.HashSet; + +import com.avlsi.fast.shapes.ArgumentMismatchException; +import com.avlsi.fast.shapes.ShapeFunctionUndefinedException; +import com.avlsi.fast.shapes.Shape; +import com.avlsi.fast.shapes.ShapeCollection; +import com.avlsi.fast.shapes.ShapeFunction; +import com.avlsi.fast.shapes.ShapeFunctionTable; +import com.avlsi.fast.shapes.Polygon; +import com.avlsi.fast.shapes.PolygonIterator; +import com.avlsi.fast.shapes.Point; +import com.avlsi.fast.shapes.WriteableShape; +import com.avlsi.fast.shapes.WriteableShapesBlock; +import com.avlsi.fast.shapes.impl.PolygonImpl; +import com.avlsi.fast.shapes.impl.WriteablePointImpl; +import com.avlsi.fast.shapes.impl.WriteableShapeImpl; +import com.avlsi.fast.shapes.impl.WriteableShapeCollectionImpl; +import com.avlsi.fast.shapes.impl.WriteableShapesBlockImpl; + +import com.avlsi.util.mathexpression.MathExpression; +import com.avlsi.util.mathexpression.ExpressionCollection; +import com.avlsi.util.mathexpression.ExpressionCollectionIterator; +import com.avlsi.util.mathexpression.impl.WriteableExpressionCollectionImpl; +import com.avlsi.util.mathexpression.variable.VariableDictionary; +import com.avlsi.util.mathexpression.variable.impl.WriteableVariableDictionaryImpl; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.impl.WriteableStringExpressionCollectionImpl; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollectionIterator; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.variable.impl.WriteableStringVariableDictionaryImpl; + +public class ShapeFunctionImpl implements ShapeFunction { + private String name; + private StringExpression layer, net, boundary; + private Point origin; + private boolean repeatx, repeaty; + private List polygons, calls; + private String[] mathParams; + private String[] stringParams; + + protected class FunctionCall { + private String name; + private ExpressionCollection mathArgs; + private StringExpressionCollection stringArgs; + + /** + Construct a representation of a function call given the name of the + function, the math arguments, and the string arguments. + @param name Name of the function + @param mathArgs Mathematical arguments + @param stringArgs String arguments + */ + public FunctionCall(final String name, + final ExpressionCollection mathArgs, + final StringExpressionCollection stringArgs) { + this.name = name; + this.mathArgs = mathArgs; + this.stringArgs = stringArgs; + } + + /** + Gets the name of the function. + @return Name of the function + */ + public String getName() { + return name; + } + + /** + Evaluate function call arguments given a dictionary. + @param dict Dictionary to lookup variables in + @return Evaluated arguments in a ExpressionCollection + */ + public ExpressionCollection resolve(VariableDictionary dict) { + WriteableExpressionCollectionImpl coll = + new WriteableExpressionCollectionImpl(mathArgs.size()); + ExpressionCollectionIterator iter = mathArgs.getIterator(); + while (iter.hasNext()) { + coll.addExpression(iter.next().evaluate(dict)); + } + return coll; + } + + /** + Evaluate function call arguments given a dictionary. + @param dict Dictionary to lookup variables in + @return Evaluated arguments in a StringExpressionCollection + */ + public StringExpressionCollection resolve(StringVariableDictionary dict) + { + WriteableStringExpressionCollectionImpl coll = + new WriteableStringExpressionCollectionImpl(stringArgs.size()); + StringExpressionCollectionIterator iter = stringArgs.getIterator(); + while (iter.hasNext()) { + coll.addExpression(iter.next().evaluate(dict)); + } + return coll; + } + } + + public ShapeFunctionImpl(final String name, final StringExpression layer, + final StringExpression net, + boolean repeatx, boolean repeaty, + final StringExpression boundary, + final Point origin, String[] mathParams, + String[] stringParams) { + polygons = new ArrayList(); + calls = new ArrayList(); + this.name = name; + this.layer = layer; + this.net = net; + this.repeatx = repeatx; + this.repeaty = repeaty; + this.boundary = boundary; + this.origin = origin; + this.mathParams = mathParams; + this.stringParams = stringParams; + } + + /** + Bind arguments to parameters and return a dictionary with the bindings. + @param args Arguments. + @return VariableDictionary with the bindings. + @throws ArgumentMismatchException if the number of arguments and number + of parameters do not match. + */ + protected VariableDictionary bind(ExpressionCollection args) + throws ArgumentMismatchException { + if (mathParams.length != args.size()) { + throw new ArgumentMismatchException(name, mathParams.length, + args.size()); + } + WriteableVariableDictionaryImpl dict = + new WriteableVariableDictionaryImpl(); + ExpressionCollectionIterator iter = args.getIterator(); + for (int i = 0; i < mathParams.length; i++) { + dict.bindVariable(mathParams[i], iter.next()); + } + return dict; + } + + /** + Bind arguments to parameters and return a dictionary with the bindings. + @param args Arguments. + @return StringVariableDictionary with the bindings. + @throws ArgumentMismatchException if the number of arguments and number + of parameters do not match. + */ + protected StringVariableDictionary bind(StringExpressionCollection args) + throws ArgumentMismatchException { + if (stringParams.length != args.size()) { + throw new ArgumentMismatchException(name, stringParams.length, + args.size()); + } + WriteableStringVariableDictionaryImpl dict = + new WriteableStringVariableDictionaryImpl(); + StringExpressionCollectionIterator iter = args.getIterator(); + for (int i = 0; i < stringParams.length; i++) { + dict.bindVariable(stringParams[i], iter.next()); + } + return dict; + } + + /** + Evaluate a Point with a specified VariableDictionary. + @param point Point to evaluate + @param dict Dictionary to lookup bindings + @return A new Point with its coordinates evaluated. + */ + protected Point resolve(final Point point, final VariableDictionary dict) { + return new WriteablePointImpl(point.getX().evaluate(dict), + point.getY().evaluate(dict)); + } + + /** + Evaluate a Polygon with a specified VariableDictionary. + @param poly Polygon to evaluate + @param dict Dictionary to lookup bindings + @return A new Polygon with its coordinates evaluated. + */ + protected Polygon resolve(final Polygon poly, + final VariableDictionary dict) { + int size = poly.size(); + Point[] points = new Point[size]; + PolygonIterator iter = poly.iterator(); + for (int i = 0; i < size; i++) { + points[i] = resolve(iter.next(), dict); + } + return new PolygonImpl(points); + } + + public ShapeCollection resolve(final ShapeFunctionTable table, + final Set seen, + final ExpressionCollection mathArgs, + final StringExpressionCollection stringArgs) + { + VariableDictionary mathDict; + StringVariableDictionary stringDict; + try { + mathDict = bind(mathArgs); + stringDict = bind(stringArgs); + } catch (ArgumentMismatchException e) { + System.err.println(e.getMessage()); + return new WriteableShapeCollectionImpl(1); + } + WriteableShapesBlockImpl block = + new WriteableShapesBlockImpl(); + WriteableShapeCollectionImpl coll = + new WriteableShapeCollectionImpl(); + + if (!polygons.isEmpty()) { + Point eo = resolve(origin, mathDict); + MathExpression xrep = null; + MathExpression yrep = null; + if (repeatx) xrep = eo.getX(); + if (repeaty) yrep = eo.getY(); + WriteableShape shape = + new WriteableShapeImpl(layer.evaluate(stringDict), + net == null ? + null : net.evaluate(stringDict), + eo, + xrep, yrep, + boundary); + Iterator iter = polygons.iterator(); + while (iter.hasNext()) { + shape.addPolygon(resolve((Polygon) iter.next(), mathDict)); + } + coll.addShape(shape); + block.addShapes(coll); + } + + resolve(table, seen, mathDict, stringDict, block); + return block.getShapes(); + } + + public ShapeCollection resolve(final ShapeFunctionTable table) { + VariableDictionary mathDict = new WriteableVariableDictionaryImpl(); + StringVariableDictionary stringDict = + new WriteableStringVariableDictionaryImpl(); + WriteableShapesBlockImpl block = + new WriteableShapesBlockImpl(); + + resolve(table, new HashSet(), mathDict, stringDict, block); + return block.getShapes(); + } + + /** + Evaluate function calls. + */ + protected void resolve(final ShapeFunctionTable table, + final Set seen, + final VariableDictionary mathDict, + final StringVariableDictionary stringDict, + final WriteableShapesBlock block) + { + Iterator iter = calls.iterator(); + while (iter.hasNext()) { + FunctionCall call = (FunctionCall) iter.next(); + String funName = call.getName(); + if (seen.contains(funName)) { + System.err.println("Recursion of ShapeFun " + funName + " detected!"); + continue; + } else { + seen.add(funName); + } + try { + ShapeFunction func = table.lookup(funName); + block.addShapes(func.resolve(table, + seen, + call.resolve(mathDict), + call.resolve(stringDict))); + } catch (ShapeFunctionUndefinedException e) { + System.err.println(e.getMessage()); + } finally { + seen.remove(funName); + } + } + } + + public void addPolygon(final Polygon poly) { + polygons.add(poly); + } + + public void addFunctionCall(final String name, + final ExpressionCollection mathArgs, + final StringExpressionCollection stringArgs) { + calls.add(new FunctionCall(name, mathArgs, stringArgs)); + } + + public String getName() { + return name; + } +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/SkillExporter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/SkillExporter.java new file mode 100644 index 0000000000..eda60281c0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/SkillExporter.java @@ -0,0 +1,151 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + +import java.io.Writer; +import java.io.PrintWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +import com.avlsi.fast.shapes.Shape; +import com.avlsi.fast.shapes.ShapeIterator; +import com.avlsi.fast.shapes.Point; +import com.avlsi.fast.shapes.Polygon; +import com.avlsi.fast.shapes.PolygonIterator; +import com.avlsi.fast.shapes.ShapeCollection; +import com.avlsi.fast.shapes.ShapeCollectionIterator; +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringVisitor; +import com.avlsi.fast.shapes.stringexpression.impl.SkillStringVisitor; + +import com.avlsi.util.mathexpression.MathExpression; +import com.avlsi.util.mathexpression.Visitor; +import com.avlsi.util.mathexpression.impl.SkillVisitor; + +public class SkillExporter { + protected PrintWriter out; + protected StringVisitor sv; + protected Visitor v; + protected int count; + + protected String gensym() { + return "poly" + Integer.toString(count++); + } + + public SkillExporter(final Writer out) { + this.out = new PrintWriter(out); + sv = new SkillStringVisitor(out) { + public void variable(final String varName) { + write("stringEnv[\"" + varName + "\"]"); + } + }; + v = new SkillVisitor(out) { + public void variable(final String varName) { + write("mathEnv[\"" + varName + "\"]"); + } + }; + count = 0; + } + + protected void point(Point p) { + out.print("(list (quote "); + p.getX().accept(v); + out.print(") (quote "); + p.getY().accept(v); + out.print("))"); + } + + protected void polygon(Polygon p) { + PolygonIterator iter = p.iterator(); + out.print("(list "); + while (iter.hasNext()) { + point(iter.next()); + out.print(" "); + } + out.print(")"); + } + + protected void shape(Shape s) { + out.println("(lambda (doShape) "); + out.println("(doShape"); + + out.print("?layerName (quote "); + s.getLayerName().accept(sv); + out.println(")"); + + out.print("?netName "); + if (s.getNetName() == null) { + out.print("nil"); + } else { + out.print("(quote "); + s.getNetName().accept(sv); + out.print(")"); + } + out.println(); + + Point o = s.getOrigin(); + out.print("?xOrigin (quote"); + o.getX().accept(v); + out.println(")"); + + out.print("?yOrigin (quote"); + o.getY().accept(v); + out.println(")"); + + final MathExpression xrep = s.getXRepeat(); + out.print("?xRepeat "); + if (xrep == null) out.print("nil"); + else { + out.print("(quote "); + xrep.accept(v); + out.print(")"); + } + out.println(); + + final MathExpression yrep = s.getYRepeat(); + out.print("?yRepeat "); + if (yrep == null) out.print("nil"); + else { + out.print("(quote "); + yrep.accept(v); + out.print(")"); + } + out.println(); + + final StringExpression bound = s.getRepeatBoundaryLayer(); + out.print("?boundaryLayer "); + if (bound == null) out.print("nil"); + else { + out.print("(quote "); + bound.accept(sv); + out.print(")"); + } + out.println(); + + ShapeIterator iter = s.iterator(); + out.println("?polygon (list "); + while (iter.hasNext()) { + polygon(iter.next()); + out.println(); + } + out.print(")"); + out.println(")"); // doShape + + out.println(")"); // lambda + } + + public void export(ShapeCollection coll, final String funName) { + ShapeCollectionIterator iter = coll.iterator(); + while (iter.hasNext()) { + out.println("(setq poly (cons"); + shape(iter.next()); + out.println("poly))"); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteablePointImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteablePointImpl.java new file mode 100644 index 0000000000..7bdf5021fc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteablePointImpl.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + +import com.avlsi.fast.shapes.Point; +import com.avlsi.fast.shapes.WriteablePoint; + +import com.avlsi.util.mathexpression.MathExpression; + +/** + Default implementation of WriteablePoint + */ +public class WriteablePointImpl implements WriteablePoint { + /** + Coordinates of this point. + */ + protected MathExpression x, y; + + /** + Constructs a point from coordinates. + @param xExp x-coordinate of the point + @param yExp y-coordinate of the point + */ + public WriteablePointImpl(final MathExpression xExp, + final MathExpression yExp) { + x = xExp; + y = yExp; + } + + /** + Constructs a point from another point. + @param point The point to copy. + */ + public WriteablePointImpl(final Point point) { + this(point.getX(), point.getY()); + } + + public MathExpression getX() { + return x; + } + + public MathExpression getY() { + return y; + } + + public void setX(final MathExpression Exp) { + x = Exp; + } + + public void setY(final MathExpression Exp) { + y = Exp; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeCollectionImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeCollectionImpl.java new file mode 100644 index 0000000000..e63a19cc7f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeCollectionImpl.java @@ -0,0 +1,92 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import com.avlsi.fast.shapes.Shape; +import com.avlsi.fast.shapes.ShapeCollection; +import com.avlsi.fast.shapes.ShapeCollectionIterator; +import com.avlsi.fast.shapes.WriteableShapeCollection; +import com.avlsi.fast.shapes.WriteableShapeCollectionIterator; + +/** + Default implementation of WriteableShapeCollection. Shapes are stored in an + ArrayList. + */ +public class WriteableShapeCollectionImpl implements WriteableShapeCollection { + /** + Storage for shapes in the collection. + */ + protected List shapes; + + /** + Constructs a collection with an initial size of 4. + */ + public WriteableShapeCollectionImpl() { + this(4); + } + + /** + Constructs a collection with the given initial size. + @param size Initial size of the collection. + */ + public WriteableShapeCollectionImpl(final int size) { + shapes = new ArrayList(size); + } + + /** + Constructs a collection from another collection. + @param c A ShapeCollection to copy from. + */ + public WriteableShapeCollectionImpl(final ShapeCollection c) { + ShapeCollectionIterator iter = c.iterator(); + while (iter.hasNext()) { + shapes.add(iter.next()); + } + } + + public void addShape(final Shape newShape) { + shapes.add(newShape); + } + + public ShapeCollectionIterator iterator() { + return new ShapeCollectionIterator() { + private Iterator iterator = shapes.iterator(); + + public Shape next() { + return (Shape) iterator.next(); + } + + public boolean hasNext() { + return iterator.hasNext(); + } + }; + } + + public WriteableShapeCollectionIterator getWriteableIterator() { + return new WriteableShapeCollectionIterator() { + private Iterator iterator = shapes.iterator(); + + public Shape next() { + return (Shape) iterator.next(); + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public void remove() { + iterator.remove(); + } + }; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeFunctionTableImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeFunctionTableImpl.java new file mode 100644 index 0000000000..a0de71f03b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeFunctionTableImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + + +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.fast.shapes.ShapeFunction; +import com.avlsi.fast.shapes.WriteableShapeFunctionTable; +import com.avlsi.fast.shapes.ShapeFunctionRedefinedException; +import com.avlsi.fast.shapes.ShapeFunctionUndefinedException; + +/** + Default implementation of WriteableShapeFunctionTable. The mapping is + stored in a HashMap. + */ +public class WriteableShapeFunctionTableImpl +implements WriteableShapeFunctionTable { + protected Map storage; + + public WriteableShapeFunctionTableImpl() { + storage = new HashMap(); + } + + public ShapeFunction lookup(final String name) + throws ShapeFunctionUndefinedException { + ShapeFunction func = (ShapeFunction) storage.get(name); + if (func == null) { + throw new ShapeFunctionUndefinedException(name); + } + return func; + } + + public void define(final String name, final ShapeFunction func) + throws ShapeFunctionRedefinedException { + if (storage.containsKey(name)) { + throw new ShapeFunctionRedefinedException(name); + } + storage.put(name, func); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeImpl.java new file mode 100644 index 0000000000..62eec4a4de --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapeImpl.java @@ -0,0 +1,118 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import com.avlsi.fast.shapes.Point; +import com.avlsi.fast.shapes.Polygon; +import com.avlsi.fast.shapes.ShapeIterator; +import com.avlsi.fast.shapes.WriteableShape; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +import com.avlsi.util.mathexpression.MathExpression; + +/** + Default implementation for Shapes. + */ +public class WriteableShapeImpl implements WriteableShape { + /** + Names of the layer and the net of this shape. + */ + protected StringExpression layerName, netName; + + /** + Origin of the shape. + */ + protected Point origin; + + /** + Distances between repetitions along the x and y axes. + */ + protected MathExpression xRepeat, yRepeat; + + /** + Name of the repeat boundary layer. + */ + protected StringExpression boundaryLayer; + + /** + Storage for the polygons in the shape. + */ + protected List polygon; + + /** + Constructs a Shape on the specified layer with the specified net and + origin. The shape has no polygons initially. + @param layerName Name of the layer of the shape. + @param netName Name of the net of the shape. + @param origin Origin of the shape. + */ + public WriteableShapeImpl(final StringExpression layerName, + final StringExpression netName, + final Point origin, + final MathExpression xrep, + final MathExpression yrep, + final StringExpression boundary) { + this.layerName = layerName; + this.netName = netName; + this.origin = origin; + this.polygon = new ArrayList(); + this.xRepeat = xrep; + this.yRepeat = yrep; + this.boundaryLayer = boundary; + } + + public StringExpression getLayerName() { + return layerName; + } + + public StringExpression getNetName() { + return netName; + } + + public Point getOrigin() { + return origin; + } + + public MathExpression getXRepeat() { + return xRepeat; + } + + public MathExpression getYRepeat() { + return yRepeat; + } + + public StringExpression getRepeatBoundaryLayer() { + return boundaryLayer; + } + + public ShapeIterator iterator() { + return new ShapeIterator() { + private Iterator iterator = polygon.iterator(); + + public Polygon next() { + return (Polygon) iterator.next(); + } + + public boolean hasNext() { + return iterator.hasNext(); + } + }; + } + + public void addPolygon(Polygon poly) { + polygon.add(poly); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapesBlockImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapesBlockImpl.java new file mode 100644 index 0000000000..46dc1bf636 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/WriteableShapesBlockImpl.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.impl; + +import com.avlsi.fast.shapes.impl.WriteableShapeCollectionImpl; +import com.avlsi.fast.shapes.Shape; +import com.avlsi.fast.shapes.ShapeCollection; +import com.avlsi.fast.shapes.ShapeCollectionIterator; +import com.avlsi.fast.shapes.WriteableShapeCollection; +import com.avlsi.fast.shapes.WriteableShapeCollectionIterator; +import com.avlsi.fast.shapes.WriteableShapesBlock; + +/** + Default implementation of WriteableShapesBlock. + */ +public class WriteableShapesBlockImpl implements WriteableShapesBlock { + /** + Storage for shapes in the collection. + */ + protected WriteableShapeCollection collection; + + /** + Constructs an empty block containing a collection with an initial size + of 4. + */ + public WriteableShapesBlockImpl() { + this(4); + } + + /** + Constructs an empty block containing a collection with the given initial + size. + @param size Initial size of the block. + */ + public WriteableShapesBlockImpl(final int size) { + collection = new WriteableShapeCollectionImpl(size); + } + + /** + Constructs a block containing the specified collection. + @param c A collection to construct a block from. + */ + public WriteableShapesBlockImpl(final ShapeCollection c) { + this(); + addShapes(c); + } + + public ShapeCollection getShapes() { + return collection; + } + + public void addShapes(ShapeCollection NewShapes) { + ShapeCollectionIterator iter = NewShapes.iterator(); + while (iter.hasNext()) { + collection.addShape(iter.next()); + } + } + + public WriteableShapeCollection getWriteableShapes() { + return collection; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/Shape.g b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/Shape.g new file mode 100644 index 0000000000..9c676e5853 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/Shape.g @@ -0,0 +1,712 @@ +/* Grammar: + +goal ::= "shape" LCURLY shapeBlock* RCURLY +shapeBlock ::= shapeFuncDecl | shapeFuncCall +shapeFuncDecl ::= "shapefun" ident + "(" shapeParamList ")" + ("{" shapeParamList "}")? + stringExpression ("/" stringExpression)? + "repeat"? mathExpression + "repeat"? mathExpression + ("bound" stringExpression)? + "{" (shapeFuncStatement ";")* "}" +shapeFuncStatement ::= pointList | shapeFuncCall +shapeParamList ::= (ident ("," ident)*)? +shapeFuncCall ::= ident "(" mathArgList ")" ("{" stringArgList "}")? +mathArgList ::= (mathExpression ("," mathExpression)*)? +stringArgList ::= (stringExpression ("," stringExpression)*)? +pointList ::= "[" mathExpression+ "]" + +*/ + +header { + package com.avlsi.fast.shapes.impl.parser; +} + +class ShapeLexer extends Lexer; + +options { + charVocabulary = '\0'..'\377'; + filter = false; + testLiterals = true; +// importVocab = Common; +// exportVocab = ShapeLexer; + k = 2; +} + +tokens { + SHAPEFUN = "shapefun"; + SHAPE = "shape"; + REPEAT = "repeat"; + BOUND = "bound"; +} + +LBRACKET : '['; +RBRACKET : ']'; +LCURLY : '{'; +RCURLY : '}'; +LPAREN : '('; +RPAREN : ')'; +COMMA : ','; +SEMI : ';'; +PLUS : '+' ; +MINUS : '-' ; +TIMES : '*' ; +SLASH : '/'; +QUOTE : '"'; +BACKSLASH : '\\'; +WS : ( ' ' | '\t' | '\f' | ( '\n' { newline(); } ) ) + { $setType(Token.SKIP); } + ; + + +IDENT + : ( LETTER | '_' ) ( LETTER | '_' | DIGIT )* + ; + +protected +LETTER + : 'a'..'z' | 'A'..'Z' + ; + +protected +DIGIT + : '0'..'9' + ; + +protected +INTEGER + : ( DIGIT )+ + ; +protected +FLOAT + : INTEGER '.' INTEGER + ; + +INT_OR_FLOAT + : ( INTEGER '.' INTEGER ) => FLOAT { $setType(FLOAT); } + | INTEGER { $setType(INTEGER); } + ; + +/* Following 3 rules copied from http://www.antlr.org/grammars/java/java.g, + with semantic actions added and other small modifications */ +STRING_LITERAL + : QUOTE (ESC|~('"'|'\\'))* QUOTE + ; + +protected +ESC + : BACKSLASH + ( 'n' { $setText("\n"); } + | 'r' { $setText("\r"); } + | 't' { $setText("\t"); } + | 'b' { $setText("\b"); } + | 'f' { $setText("\f"); } + | '"' { $setText("\""); } + | '\'' { $setText("'"); } + | '\\' { $setText("\\"); } + | 'x' HEX_DIGIT HEX_DIGIT { + String esc = $getText; + char c[] = { (char) Integer.parseInt(esc.substring(2), 16) }; + String s = new String(c); + $setText(s); + } + | ('0'..'3') + ( + options { + warnWhenFollowAmbig = false; + } + : ('0'..'7') + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + )? + )? { + String esc = $getText; + char c[] = { (char) Integer.parseInt(esc.substring(2), 8) }; + String s = new String(c); + $setText(s); + } + ) + ; + +protected +HEX_DIGIT + : ('0'..'9'|'A'..'F'|'a'..'f') + ; + +CMT : "/*" (options {greedy=false;} : ( '\n' {newline();} | ~('\n') ) )* "*/" + + {$setType(Token.SKIP);} + ; + +{ + import java.util.ArrayList; + import java.util.HashMap; + import java.util.List; + import java.util.Map; + + import com.avlsi.util.debug.Debug; + + import com.avlsi.fast.shapes.ShapeFactory; + import com.avlsi.fast.shapes.ShapeFunction; + import com.avlsi.fast.shapes.ShapeFunctionRedefinedException; + import com.avlsi.fast.shapes.Point; + import com.avlsi.fast.shapes.Shape; + import com.avlsi.fast.shapes.WriteableShapeFunctionTable; + + import com.avlsi.util.debug.Debug; + + import com.avlsi.util.mathexpression.ExpressionCollection; + import com.avlsi.util.mathexpression.MathExpression; + import com.avlsi.util.mathexpression.MathExpressionFactory; + import com.avlsi.util.mathexpression.WriteableExpressionCollection; + + import com.avlsi.fast.shapes.stringexpression.StringExpression; + import com.avlsi.fast.shapes.stringexpression.StringExpressionFactory; + import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; + import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollection; + + import antlr.CharScanner; + import antlr.TokenStreamSelector; +} + +class ShapeParser extends Parser; +options { + k = 1; + buildAST = false; +// importVocab = ShapeLexer; +} + +{ + protected WriteableShapeFunctionTable table; + + protected ShapeFactory shapeFactory; + protected MathExpressionFactory mathFactory; + protected StringExpressionFactory stringFactory; + protected TokenStreamSelector selector; + protected HashMap funmap; + + protected abstract class Function { + private int args; + + Function(int args) { + this.args = args; + } + + public void check(MathExpression[] arg) throws RuntimeException { + if (arg.length != args) { + throw new RuntimeException(); + } + } + + public abstract MathExpression make(MathExpression[] arg); + } + + private void fillFunmap(Map map) { + map.put("exp", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeExpFunction(arg[0]); + }}); + map.put("log", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeLogFunction(arg[0]); + }}); + map.put("sin", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeSinFunction(arg[0]); + }}); + map.put("cos", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeCosFunction(arg[0]); + }}); + map.put("tan", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeTanFunction(arg[0]); + }}); + map.put("asin", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeArcsinFunction(arg[0]); + }}); + map.put("acos", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeArccosFunction(arg[0]); + }}); + map.put("atan", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeArctanFunction(arg[0]); + }}); + map.put("ceil", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeCeilFunction(arg[0]); + }}); + map.put("round", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeRoundFunction(arg[0]); + }}); + map.put("floor", new Function(1) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeFloorFunction(arg[0]); + }}); + map.put("less", new Function(4) { + public MathExpression make(MathExpression[] arg) { + check(arg); + return mathFactory.makeLessThanOperator(arg[0], + arg[1], + arg[2], + arg[3]); + }}); + map.put("sum", new Function(4) { + public MathExpression make(MathExpression[] arg) { + check(arg); + final String idx = arg[0].getVariableNames()[0]; + return mathFactory.makeSumOperator(idx, + arg[1], + arg[2], + arg[3]); + }}); + } + + protected MathExpression makeFunction(final String name, + final MathExpression[] arg) { + Function fun = (Function) funmap.get(name); + Debug.assertTrue(fun != null, + "Function unknown, even though isFunction returned true."); + return fun.make(arg); + } + + protected boolean isFunction(final String name) { + return funmap.containsKey(name); + } + + public ShapeParser(TokenStreamSelector selector, + WriteableShapeFunctionTable table, + ShapeFactory shapeFactory, + MathExpressionFactory mathFactory, + StringExpressionFactory stringFactory) { + this(selector); + this.shapeFactory = shapeFactory; + this.mathFactory = mathFactory; + this.stringFactory = stringFactory; + this.selector = selector; + this.table = table; + funmap = new HashMap(); + fillFunmap(funmap); + } + + public static ShapeParser makeShapeParser(ShapeLexer lexer, + WriteableShapeFunctionTable table, + ShapeFactory shapeFactory, + MathExpressionFactory mathFactory, + StringExpressionFactory stringFactory) { + TokenStreamSelector selector = new TokenStreamSelector(); + //MathExpressionLexer mathLexer = new MathExpressionLexer(lexer.getInputState()); + selector.addInputStream(lexer, "shapeLexer"); + //selector.addInputStream(mathLexer, "mathLexer"); + selector.select("shapeLexer"); + return new ShapeParser(selector, table, shapeFactory, mathFactory, stringFactory); + } +} + +goal returns [ ShapeFunction anon ] + { + anon = null; + } + : EOF + | SHAPE LCURLY { + anon = shapeFactory.makeShapeFunction( + "anonymous", + stringFactory.makeConstant("noLayer"), + stringFactory.makeConstant("noNet"), + false, false, + stringFactory.makeConstant("noBoundaryLayer"), + shapeFactory.makePoint(mathFactory.makeConstant(0), + mathFactory.makeConstant(0)), + new String[0], + new String[0]); + } (shapeBlock[anon])* RCURLY + ; + +shapeBlock [ ShapeFunction anon ] + { + ShapeFunction func; + } + : SHAPEFUN func = shapeFuncDecl { + try { + table.define(func.getName(), func); + } catch (ShapeFunctionRedefinedException e) { + System.err.println(e.getMessage()); + } + } + | shapeFuncCall[anon] + ; + +shapeFuncDecl returns [ ShapeFunction func ] + { + boolean repeatx = false, repeaty = false; + StringExpression net = null, layer; + StringExpression bound = stringFactory.makeConstant("prBound"); + List mathParams, stringParams = null; + MathExpression xorig, yorig; + func = null; + } + : funName:IDENT + LPAREN mathParams = shapeParamList RPAREN + (LCURLY stringParams = shapeParamList RCURLY)? + layer = stringExpression + (SLASH net = stringExpression)? + (REPEAT { + repeatx = true; + })? + xorig = mathExpression + (REPEAT { + repeaty = true; + })? + yorig = mathExpression + (BOUND bound = stringExpression)? + LCURLY { + func = shapeFactory.makeShapeFunction( + funName.getText(), + layer, + net, + repeatx, + repeaty, + bound, + shapeFactory.makePoint(xorig, yorig), + (String[]) mathParams.toArray(new String[0]), + stringParams == null ? + new String[0] : + (String[]) stringParams.toArray(new String[0]) + ); + } + (shapeFuncStatement[func])* + RCURLY + ; + +shapeFuncStatement [ ShapeFunction func ] + { + } + : pointList[func] + | shapeFuncCall[func] + ; + +shapeParamList returns [ ArrayList params ] + { + params = new ArrayList(); + } + : ( + param1:IDENT { + params.add(param1.getText()); + } + ( + COMMA paramk:IDENT { + params.add(paramk.getText()); + } + )* + )? + ; + +shapeFuncCall [ ShapeFunction func ] + { + ExpressionCollection mathArgs; + StringExpressionCollection stringArgs = + stringFactory.makeExpressionCollection(); + } + : funName:IDENT + mathArgs = mathArgList + (stringArgs = stringArgList)? { + func.addFunctionCall(funName.getText(), mathArgs, stringArgs); + } + SEMI + ; + +mathArgList returns [ WriteableExpressionCollection args ] + { + args = mathFactory.makeExpressionCollection(); + MathExpression expr; + } + : { LT(2).getType() != RPAREN }? LPAREN expr = mathExpression { + args.addExpression(expr); + } + ( + COMMA expr = mathExpression { + args.addExpression(expr); + } + )* + RPAREN + | LPAREN RPAREN + ; + +stringArgList returns [ WriteableStringExpressionCollection args ] + { + args = stringFactory.makeExpressionCollection(); + StringExpression expr; + } + : { LT(2).getType() != RCURLY }? LCURLY { + expr = stringExpression(); + args.addExpression(expr); + } + ( + COMMA expr = stringExpression { + args.addExpression(expr); + } + )* + RCURLY + | LCURLY RCURLY + ; + +protected +pointList [ ShapeFunction func ] + { + MathExpression x, y, first; + ArrayList points = new ArrayList(); + int count = 0; + } + : LBRACKET x = mathExpression { + first = x; + } + ( + y = mathExpression { + count++; + if (count % 2 == 0) { + points.add(shapeFactory.makePoint(y, x)); + } else { + points.add(shapeFactory.makePoint(x, y)); + } + x = y; + } + )+ + RBRACKET { + if (count < 4) { + System.err.println("Warning: Only " + count + + " points specified."); + } + if (!first.equals(x)) { + System.err.println("Warning: Point specification may not be" + + "rectilinear"); + } + func.addPolygon(shapeFactory.makePolygon(points)); + } + SEMI + ; + +/* +mathExpression returns [ MathExpression exp ] + { + exp = null; + } + : + { + selector.push("mathLexer"); + MathExpressionParser mathParser = new MathExpressionParser(getInputState(), mathFactory); + exp = mathParser.goal(); + selector.pop(); + } + ; +*/ + +mathExpression returns [ MathExpression exp ] + { + MathExpression seed_term; + MathExpression curr_term; + boolean negate_next_term; + WriteableExpressionCollection terms=null; + exp = null; + } + : + seed_term=mathExpressionProduct + ( + ( + PLUS { + negate_next_term = false; + } + | MINUS { + negate_next_term = true; + } + ) + curr_term=mathExpressionProduct { + if ( terms == null ) { + terms = mathFactory.makeExpressionCollection(); + terms.addExpression( seed_term ); + } + + if ( negate_next_term ) { + curr_term = + mathFactory.makeNegationOperator( curr_term ); + } + terms.addExpression( curr_term ); + } + )* + + { + if ( terms == null ) { + exp = seed_term; + } + else { + exp = mathFactory.makePlusOperator( terms ); + } + } + ; + +protected +mathArgumentList returns [ MathExpression[] exp ] + { + ArrayList args = new ArrayList(); + MathExpression term; + exp = null; + } + : + term=mathExpression { + args.add(term); + } + ( + COMMA term=mathExpression { + args.add(term); + } + )* + + { + exp = (MathExpression[]) args.toArray(new MathExpression[0]); + } + ; + + +protected +mathExpressionProduct returns [ MathExpression exp ] + { + MathExpression seed_member; + MathExpression curr_member; + boolean invert_next_member; + WriteableExpressionCollection members = null; + exp = null; + } + : + seed_member=mathExpressionAtom + ( + ( + SLASH { + invert_next_member = true; + } + | TIMES { + invert_next_member = false; + } + ) + curr_member=mathExpressionAtom { + if ( members == null ) { + members = mathFactory.makeExpressionCollection(); + members.addExpression( seed_member ); + } + if ( invert_next_member ) { + curr_member = + mathFactory.makeDivideOperator( mathFactory.makeConstant(1), + curr_member ); + } + members.addExpression( curr_member ); + } + )* + { + if ( members == null ) { + exp = seed_member; + } + else { + exp = mathFactory.makeTimesOperator( members ); + } + } + ; + + +protected +mathExpressionAtom returns [ MathExpression exp ] + { + exp = null; + MathExpression[] args; + } + : {isFunction(LT(1).getText())}? + myFunc:IDENT LPAREN args=mathArgumentList RPAREN { + exp=makeFunction(myFunc.getText(), args); + } + | myIdent:IDENT { + exp = mathFactory.makeVariableReference( myIdent.getText() ); + } + | myFloat:FLOAT { + exp = mathFactory.makeConstant( Double.parseDouble( myFloat.getText() ) ); + } + | myInt:INTEGER { + exp = mathFactory.makeConstant( Double.parseDouble( myInt.getText() ) ); + } + | LPAREN exp=mathExpression RPAREN + ; + +/* +stringExpression returns [ StringExpression exp ] + { + exp = null; + } + : + { + selector.push("stringLexer"); + StringExpressionParser stringParser = new StringExpressionParser(getInputState()); + stringParser.setFactory(stringFactory); + exp = stringParser.goal(); + selector.pop(); + } + ; +*/ + +stringExpression returns [ StringExpression exp ] + { + StringExpression seed_term; + StringExpression curr_term; + WriteableStringExpressionCollection terms = null; + exp = null; + } + : + seed_term=stringExpressionAtom + ( + PLUS curr_term=stringExpressionAtom { + if ( terms == null ) { + terms = stringFactory.makeExpressionCollection(); + terms.addExpression( seed_term ); + } + terms.addExpression( curr_term ); + } + )* + + { + if ( terms == null ) { + exp = seed_term; + } + else { + exp = stringFactory.makeConcatOperator( terms ); + } + } + ; + + +protected +stringExpressionAtom returns [ StringExpression exp ] + { + exp = null; + } + : myIdent:IDENT { + exp = stringFactory.makeVariableReference( myIdent.getText() ); + } + | myString:STRING_LITERAL { + String str = myString.getText(); + exp = stringFactory.makeConstant(str.substring(1, str.length() - 1)); + } + | LPAREN exp=stringExpression RPAREN + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/custom.mk new file mode 100644 index 0000000000..4182caa12a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/impl/parser/custom.mk @@ -0,0 +1,5 @@ +MAKE_ANTLR_RULES_G_FILE_NAME := Shape.g +MAKE_ANTLR_RULES_LEXER_NAME := ShapeLexer +MAKE_ANTLR_RULES_PARSER_NAME := ShapeParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := ShapeLexer +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpression.java new file mode 100644 index 0000000000..3eb2261f34 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpression.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression; + +import com.avlsi.util.mathexpression.NotAConstantValueException; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.StringVisitor; + + +/** + Iterface to a string expression. + */ +public interface StringExpression { + + /** + Evaluates the string expression using the specified + variable bindings. + @param VarBindings Variable bindings to use when + evaluating the expression. + @return An expression equivalent to this expression, + except that all variables references that could be resolved + with the specified variable dictionary are replaced with the + variables value in the dictionary. Any variable references + in this expression not resolved by the variable dictionary + will also be in the returned expression. + */ + StringExpression evaluate( StringVariableDictionary VarBindings ); + + /** + Determines if the result of the expression is a constant. + @return true if the expressions evaluates to a constant. + */ + boolean isConstant( ); + + /** + If the expression is evaluates to a constant, this + method will return the evaluation of the expression as + a String. + @return The result of the expression if the expression + evaluates to a constant result. + @exception NotAConstantValueException Thrown when the expression + does not evaluate to a constant result. + */ + String getConstantValue() throws NotAConstantValueException; + + /** + Returns an array of strings where each string in the array + is the name of a variable referenced by this expression. + @return An array of strings where each string in the array + is the name of a variable referenced by this expression. + */ + String[] getVariableNames( ); + + /** + Calls the appropriate method in the visistor interface given + the implementation of this interface. This method will + not call accept on any referenced math expression directly, + it is up to the implementation of the visitor interface + to visit any referenced math expression. + @param v StringVisistor to call into. + */ + void accept(StringVisitor v); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollection.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollection.java new file mode 100644 index 0000000000..8cb70ac04e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollection.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression; + +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollectionIterator; + +/** + Iterface to a collection of expressions. + @see com.avlsi.fast.shapes.stringexpression.StringExpression + */ +public interface StringExpressionCollection { + /** + Gets an iterator that will enumerate all the expressions + in the collection. + @return An iterator that will enumerate all the expressions + in the collection. + */ + StringExpressionCollectionIterator getIterator(); + + /** + Determins if all the members of the collection are constant. + @return true if all the expressions in the collection + have constant values. + */ + boolean allMembersAreConstant( ); + + /** + @return The number of expressions in the collection. + */ + int size(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollectionIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollectionIterator.java new file mode 100644 index 0000000000..867701a957 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionCollectionIterator.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression; + +import java.util.NoSuchElementException; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +/** + Interface to an iterator that iterates throw the expression + stored in a StringExpressionCollection. + @see com.avlsi.fast.shapes.stringexpression.StringExpressionCollection + */ +public interface StringExpressionCollectionIterator { + + /** + Gets the next expression in the iteration. + @exception NoSuchElementException Thrown when there + is not another expression in the iteration. + @return The next expression in the iteration of the + expression collection. + + @throws NoSuchElementException + + */ + StringExpression next(); + + /** + Gets the previous expression in the iteration. + @exception NoSuchElementException Thrown when there + is not a previous expression in the iteration. + @return The previous expression in the iteration of the + expression collection. + + @throws NoSuchElementException + + */ + StringExpression previous(); + + /** + Determines if there is another expression in the iteration + of the expression collection. + @return true if there is another expression in the + iterator of the expression collection. + */ + boolean hasNext(); + + /** + Determines if there is a previous expression in the iteration + of the expression collection. + @return true if there is a previous expression in the + iterator of the expression collection. + */ + boolean hasPrevious(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionFactory.java new file mode 100644 index 0000000000..72d777ab53 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringExpressionFactory.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression; + + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollection; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + +/** + Factory interface to be implemented by all collections of implementations + of the StringExpression interface. This interface provides methods + to make all the types of operators mentioned in the visitor interface. + */ +public interface StringExpressionFactory { + + /** + Method to make an empty collection of expressions. + @return An empty collection of expressions. + */ + WriteableStringExpressionCollection makeExpressionCollection( ) ; + + /** + Makes an expression that evaluates to the specified + constant value. + @param constValue The value the returned expression will + evaluate to. + @return An expression that evaluates to the specified + constant value. The returned expression's isConstant method + should return true. + */ + StringExpression makeConstant( final String constValue ); + + /** + Makes a reference to the specified variable. + @param varName The name of the variable to reference. + @return An expression that is a reference to the specified variable. + */ + StringExpression makeVariableReference( final String varName ); + + /** + Makes an expression that is the concatenation of the expressions in the + specified collection of expressions. + @param terms The collection of string expressions to be concatened + together in the returned expression. + @return An expression that is the concatenation of all the expressions + in the specified collection of expressions. + */ + StringExpression makeConcatOperator( final StringExpressionCollection terms); + + /** + Makes an expression that is a reference to another expression. + @param subBindings A variable dictionary that defines some set + of the variables used in the subExpression in terms of other expressions. + @param subExpression The referenced expression. + @return An expression that is a reference to another expression. + */ + StringExpression makeSubExprRef( final StringVariableDictionary subBindings, + final StringExpression subExpression ); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringVisitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringVisitor.java new file mode 100644 index 0000000000..6f77c3dcd8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/StringVisitor.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression; + + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + +/** + Visitor interface used for StringExpressions. + */ +public interface StringVisitor { + void constant(final String constValue); + + void variable(final String varName); + + void concatOperator(final StringExpressionCollection terms); + + void subExpressionReference(final StringVariableDictionary subBindings, + final StringExpression subExpression); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollection.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollection.java new file mode 100644 index 0000000000..527141441b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollection.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression; + + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollectionIterator; + +/** + Iterface to a collection of expressions. + @see com.avlsi.fast.shapes.stringexpression.StringExpression + */ +public interface WriteableStringExpressionCollection extends StringExpressionCollection { + /** + Gets an iterator that will enumerate all the expressions + in the collection. The returned iterator is capable of removing and + adding expressions to the collection. + @return An iterator that will enumerate all the expressions + in the collection. + */ + WriteableStringExpressionCollectionIterator getWriteableIterator(); + + /** + Adds an expression to the collection. + @param expToAdd Expression to add. + */ + void addExpression( StringExpression expToAdd ); + + /** + Removes all the expression from the collection. + */ + void clear() ; + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollectionIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollectionIterator.java new file mode 100644 index 0000000000..c6f008ff4a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/WriteableStringExpressionCollectionIterator.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollectionIterator; + +/** + Interface to an iterator that iterates over the expression + stored in a StringExpressionCollection. + @see com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollection + */ +public interface WriteableStringExpressionCollectionIterator + extends StringExpressionCollectionIterator +{ + + /** + Inserts the specified expression into the collection. + The new expression is inserted before the implicit + cursor: a subsequent call to next would be unaffected, and + a subsequent call to previous would return the new expression. + */ + void add( StringExpression Exp ); + + /** + Removes the last expression returned from next or previous + from the collection of expressions. This call can only be made + once per call to next or previous. It can only be called if + WriteableStringExpressionCollectionIterator.add has not been called + after the last call to next or previous. + */ + void remove(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/ConcatOperator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/ConcatOperator.java new file mode 100644 index 0000000000..caf1b7f602 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/ConcatOperator.java @@ -0,0 +1,214 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + +import java.util.Collection; +import java.util.Iterator; + +import com.avlsi.util.debug.Debug; + +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollectionIterator; +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringVisitor; +import com.avlsi.util.mathexpression.NotAConstantValueException; +import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollectionIterator; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + +import com.avlsi.fast.shapes.stringexpression.impl.OperatorCommon; +import com.avlsi.fast.shapes.stringexpression.impl.WriteableStringExpressionCollectionImpl; + +/** + Default implementation of the concat operator. + Concatenates together a collection of terms. If one of the terms is a + concat operator it is removed from the collection of terms and replaced by + its terms. + If there is ever more than one constant value in the collection, all the + constant values are removed from the collection, concatenated together and a + single constant term is added to the end of the collection. + */ +public class ConcatOperator extends OperatorCommon { + + protected WriteableStringExpressionCollection m_Terms ; + + private void Construct( int PredictedNumTerms ) { + m_Terms = new WriteableStringExpressionCollectionImpl( PredictedNumTerms ) ; + } + + protected void addTerm( StringExpression NewTerm ) { + m_Terms.addExpression( NewTerm ) ; + } + + protected void flattenChildConcatOperators( ) { + WriteableStringExpressionCollectionIterator iter = + m_Terms.getWriteableIterator() ; + + while( iter.hasNext() ) { + StringExpression currExp = iter.next() ; + + if ( currExp instanceof ConcatOperator ) { + iter.remove() ; + + ConcatOperator childPlus = ( ConcatOperator ) currExp ; + + StringExpressionCollection innerTerms = childPlus.getTerms() ; + + StringExpressionCollectionIterator inner_iter = + innerTerms.getIterator() ; + + while( inner_iter.hasNext() ) { + StringExpression innerExp = inner_iter.next(); + iter.add( innerExp ) ; + } + } + } + } + + protected void combineConstants( ) { + WriteableStringExpressionCollectionIterator iter = + m_Terms.getWriteableIterator() ; + String accumulator = "" ; + + while( iter.hasNext() ) { + StringExpression currExp = iter.next() ; + + if ( currExp.isConstant() ){ + try { + accumulator += currExp.getConstantValue() ; + } + catch( NotAConstantValueException e ) { + Debug.assertTrue( false, + "Caught NotAConstantValueException " + + "even though I called isConstant first." ); + } + iter.remove() ; + } else { + if (!accumulator.equals("")) { + iter.previous(); + iter.add(makeConstantExpression(accumulator)); + accumulator = ""; + } + } + } + + if (!accumulator.equals("")) { + iter.add( makeConstantExpression( accumulator ) ) ; + } + } + + protected StringExpressionCollection getTerms(){ + return m_Terms; + } + + protected ConcatOperator( WriteableStringExpressionCollection terms ) { + m_Terms = terms; + flattenChildConcatOperators() ; + combineConstants() ; + } + + /** + Construct a concatenation of the terms in the specified collection. + Each entry in the collection must implement the StringExpression + iterface. + @see com.avlsi.fast.shapes.stringexpression.StringExpression + @param Terms Collection of terms that are to be concatenated together. + */ + public ConcatOperator( Collection Terms ) { + Iterator iter; + Construct( Terms.size() ) ; + + iter = Terms.iterator() ; + + while( iter.hasNext() ) { + StringExpression currExp = ( StringExpression ) iter.next() ; + + addTerm( currExp ) ; + + } + + flattenChildConcatOperators() ; + combineConstants() ; + } + + /** + Construct a concatenation of the terms in the specified collection. + Each entry in the collection must implement the StringExpression + iterface. + @see com.avlsi.fast.shapes.stringexpression.StringExpression + @param Terms Collection of terms that are to be concatenated together. + */ + public ConcatOperator( StringExpressionCollection terms ) { + Construct( 4 ); + StringExpressionCollectionIterator iter; + iter = terms.getIterator(); + + while( iter.hasNext() ) { + StringExpression currExp = iter.next() ; + addTerm( currExp ); + } + + flattenChildConcatOperators() ; + combineConstants(); + } + + public StringExpression evaluate( StringVariableDictionary varBindings ) { + + StringExpression ret; + if ( isConstant() ) { + ret = this; + } + else { + WriteableStringExpressionCollection newTerms = + new WriteableStringExpressionCollectionImpl( m_Terms.size() ) ; + + StringExpressionCollectionIterator iter = m_Terms.getIterator() ; + + while( iter.hasNext() ) { + StringExpression currExp = iter.next() ; + newTerms.addExpression( currExp.evaluate( varBindings ) ) ; + } + ret = new ConcatOperator( newTerms ) ; + } + if ( ret.isConstant() ) { + try { + ret = makeConstantExpression( ret.getConstantValue() ) ; + } + catch( NotAConstantValueException e ){ + Debug.assertTrue( false, + "Caught NotAConstantValueException " + + "even though I called isConstant first." ); + } + } + return ret; + } + + public boolean isConstant( ) { + return m_Terms.allMembersAreConstant() ; + } + + public String getConstantValue( ) throws NotAConstantValueException { + if ( ! ( isConstant() ) ) { + throw new NotAConstantValueException( getVariableNames() ); + } + Debug.assertTrue( m_Terms.size() == 1, + "ConcatOperator constructors should make sure" + + "that when adding constants everything gets" + + "collapsed into a single term" ); + return m_Terms.getIterator().next().getConstantValue(); + } + + public String[] getVariableNames( ) { + return getReferencedVariableNames( m_Terms ); + } + + public void accept(StringVisitor v) { + v.concatOperator(m_Terms); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/Constant.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/Constant.java new file mode 100644 index 0000000000..f07401e36d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/Constant.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringVisitor; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + + + + +/** + Default implementation of StringExpression that implements + a constant value. + */ +public class Constant implements StringExpression { + + protected String m_Val; + + /** + Construct a constant value string expression object + with the specified value. + @param val Value of the constant. The specified String object will be + referenced by the constructed object, thus changes to the specified + object will change the value of the constructed object. + */ + public Constant( final String val ) { + m_Val = val; + } + + public StringExpression evaluate( StringVariableDictionary VarBindings ) { + return this; + } + + public boolean isConstant( ) { + return true; + } + + public String getConstantValue( ) { + return m_Val; + } + + public String[] getVariableNames() { + return new String[0]; + } + + public void accept(StringVisitor v) { + v.constant(m_Val); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/OperatorCommon.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/OperatorCommon.java new file mode 100644 index 0000000000..731a36126c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/OperatorCommon.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.TreeSet; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.impl.Constant; + +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollectionIterator; + + +/** + Superclass of all the default imlementations of all the operators that + use doubles. + */ +public abstract class OperatorCommon implements StringExpression { + /** + Method called by the default implementations of the operators + to construct a constant value during simplications. + */ + protected StringExpression makeConstantExpression( final String val ) { + return new Constant( val ); + } + + protected String[] getReferencedVariableNames( StringExpressionCollection expCol) { + if ( !( isConstant() ) ) { + TreeSet varSet = new TreeSet(); + + StringExpressionCollectionIterator iter = expCol.getIterator(); + + while ( iter.hasNext() ) { + StringExpression currExp = iter.next() ; + if ( ! ( currExp.isConstant() ) ) { + varSet.addAll( Arrays.asList( currExp.getVariableNames() ) ); + } + } + return ( String[] ) varSet.toArray(new String[0]); + } + else { + return new String[0]; + } + } + + protected String[] getReferencedVariableNames( StringExpression a, + StringExpression b ) { + if ( !( isConstant() ) ) { + TreeSet varSet = new TreeSet(); + + if ( ! ( a.isConstant() ) ) { + varSet.addAll( Arrays.asList( a.getVariableNames() ) ); + } + if ( ! ( b.isConstant() ) ) { + varSet.addAll( Arrays.asList( b.getVariableNames() ) ); + } + return ( String[] ) varSet.toArray(new String[0]); + } + else { + return new String[0]; + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SkillStringVisitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SkillStringVisitor.java new file mode 100644 index 0000000000..6c16543cbd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SkillStringVisitor.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + +import java.io.Writer; +import java.io.IOException; +import java.io.PrintWriter; + +import com.avlsi.fast.shapes.stringexpression.StringVisitor; +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollectionIterator; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + +public class SkillStringVisitor implements StringVisitor { + protected PrintWriter out; + + public SkillStringVisitor(final Writer out) { + this.out = new PrintWriter(out); + } + + protected void write(final String s) { + out.print(" " + s); + } + + public void constant(final String constValue) { + write("\"" + constValue + "\""); + } + + public void variable(final String varName) { + write(varName); + } + + private void oneArg(final String name, final StringExpression x) { + write("(" + name); + x.accept(this); + write(")"); + } + + private void twoArg(final String name, + final StringExpression x, + final StringExpression y) { + write("(" + name); + x.accept(this); + y.accept(this); + write(")"); + } + + private void manyArg(final String name, final StringExpressionCollection terms) { + final StringExpressionCollectionIterator i = terms.getIterator(); + if (terms.size() == 1) { + i.next().accept(this); + } else { + write("(" + name); + while (i.hasNext()) { + i.next().accept(this); + } + write(")"); + } + } + + public void concatOperator(final StringExpressionCollection terms) { + manyArg("strcat", terms); + } + + public void subExpressionReference(final StringVariableDictionary subBindings, + final StringExpression subExpression) { + subExpression.accept(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/StringExpressionFactoryImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/StringExpressionFactoryImpl.java new file mode 100644 index 0000000000..14f4b42a8c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/StringExpressionFactoryImpl.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringExpressionFactory; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollection; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + + +import com.avlsi.fast.shapes.stringexpression.impl.Constant; +import com.avlsi.fast.shapes.stringexpression.impl.ConcatOperator; +import com.avlsi.fast.shapes.stringexpression.impl.VariableReference; +import com.avlsi.fast.shapes.stringexpression.impl.SubExpressionReference; +import com.avlsi.fast.shapes.stringexpression.impl.WriteableStringExpressionCollectionImpl; + + +public class StringExpressionFactoryImpl implements StringExpressionFactory { + + + public WriteableStringExpressionCollection makeExpressionCollection( ) { + return new WriteableStringExpressionCollectionImpl(); + } + + public StringExpression makeConstant( final String constValue ) { + return new Constant( constValue ); + } + + public StringExpression makeVariableReference( final String varName ) { + return new VariableReference( varName ); + } + + public StringExpression makeConcatOperator( final StringExpressionCollection terms ) { + return new ConcatOperator( terms ); + } + + public StringExpression makeSubExprRef( final StringVariableDictionary subBindings, + final StringExpression subExpression ) { + return new SubExpressionReference( subExpression, subBindings ); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SubExpressionReference.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SubExpressionReference.java new file mode 100644 index 0000000000..9813cbdd6f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/SubExpressionReference.java @@ -0,0 +1,152 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + +import java.util.Arrays; +import java.util.TreeSet; + +import com.avlsi.util.debug.Debug; + +import com.avlsi.util.mathexpression.NotAConstantValueException; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringVisitor; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariable; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionaryIterator; +import com.avlsi.fast.shapes.stringexpression.variable.WriteableStringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableUtil; + +import com.avlsi.fast.shapes.stringexpression.impl.OperatorCommon; + +import com.avlsi.fast.shapes.stringexpression.variable.impl.WriteableStringVariableDictionaryImpl; + +/** + Default implmentation of a sub expression reference. + */ +public class SubExpressionReference extends OperatorCommon { + + protected StringExpression m_SubExpression; + protected StringVariableDictionary m_Bindings; + + /** + Construct a sub expression reference. + + */ + public SubExpressionReference( StringExpression subExpression, + StringVariableDictionary bindings ) { + m_SubExpression = subExpression; + m_Bindings = bindings; + } + + public StringExpression evaluate( StringVariableDictionary varBindings ) { + StringExpression ret; + if ( isConstant() ) { + ret = this; + } + else { + WriteableStringVariableDictionary newSubDict = + new WriteableStringVariableDictionaryImpl(); + + StringVariableUtil.evaluateVariableValues( m_Bindings, + varBindings, + newSubDict ); + + WriteableStringVariableDictionary dictCopy = + new WriteableStringVariableDictionaryImpl( varBindings ); + + StringVariableDictionaryIterator iter = newSubDict.getIterator(); + + while ( iter.hasNext() ) { + StringVariable curr = iter.next() ; + dictCopy.unBindVariable( curr.getName() ); + } + + ret = + new SubExpressionReference( m_SubExpression.evaluate( dictCopy ), + newSubDict ); + } + if ( ret.isConstant() ) { + try { + ret = makeConstantExpression( ret.getConstantValue() ); + } + catch( NotAConstantValueException e ){ + Debug.assertTrue( false, + "Caught NotAConstantValueException " + + "even though I called isConstant first." ); + } + } + return ret; + } + + public boolean isConstant() { + String[] var_names_in_sub_expr = m_SubExpression.getVariableNames(); + + int num_var_names_in_sub_expr = var_names_in_sub_expr.length; + + int i = 0; + + boolean ret = true; + + while ( ( i < num_var_names_in_sub_expr ) && ( ret ) ) { + + StringExpression val = + m_Bindings.getVariableValue( var_names_in_sub_expr[i] ); + + if ( val == null ) { + ret = false; + } + else { + ret = val.isConstant(); + } + + ++i; + + } + + return ret; + + } + + public String getConstantValue() throws NotAConstantValueException { + return m_SubExpression.evaluate( m_Bindings ).getConstantValue(); + } + + public String[] getVariableNames() { + if ( ! ( isConstant() ) ) { + TreeSet varSet = new TreeSet(); + + String[] var_names_in_sub_expr = m_SubExpression.getVariableNames(); + + int num_var_names_in_sub_expr = var_names_in_sub_expr.length; + + int i ; + + for ( i = 0 ; i < num_var_names_in_sub_expr ; ++i ) { + StringExpression val = + m_Bindings.getVariableValue( var_names_in_sub_expr[i] ); + + if ( val == null ) { + varSet.add( var_names_in_sub_expr[i] ); + } + else { + varSet.addAll( Arrays.asList( val.getVariableNames() ) ); + } + } + return ( String[] ) varSet.toArray(); + + } + else { + return new String[0]; + } + } + + public void accept(StringVisitor v) { + v.subExpressionReference(m_Bindings, m_SubExpression); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/VariableReference.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/VariableReference.java new file mode 100644 index 0000000000..ab1d3c1ab6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/VariableReference.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.StringVisitor; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + +import com.avlsi.util.mathexpression.NotAConstantValueException; + + +/** + Default implementation of a variable reference. + */ +public class VariableReference implements StringExpression { + + protected final String m_VarName; + + /** + Consturcts a reference to a variable with the specified name. + @param varName Name of the variable to reference. + */ + public VariableReference( String varName ) { + m_VarName = varName ; + } + + public StringExpression evaluate( StringVariableDictionary VarBindings ) { + StringExpression ret = VarBindings.getVariableValue( m_VarName ); + if ( ret == null ) { + ret = this; + } + return ret; + } + + public boolean isConstant( ) { + return false; + } + + public String getConstantValue( ) throws NotAConstantValueException { + throw new NotAConstantValueException( getVariableNames() ); + } + + public String[] getVariableNames( ) { + String[] ret = new String[1]; + ret[0] = m_VarName; + return ret; + } + + public void accept(StringVisitor v) { + v.variable(m_VarName); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/WriteableStringExpressionCollectionImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/WriteableStringExpressionCollectionImpl.java new file mode 100644 index 0000000000..e9f4307b6c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/WriteableStringExpressionCollectionImpl.java @@ -0,0 +1,171 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.impl; + +import java.util.List; +import java.util.ArrayList; +import java.util.ListIterator; + +import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollection; +import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollectionIterator; +import com.avlsi.fast.shapes.stringexpression.StringExpressionCollectionIterator; +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +/** + Default implementation of WriteableStringExpressionCollection. + */ +public class WriteableStringExpressionCollectionImpl + implements WriteableStringExpressionCollection { + + ///The list of expressions in the collection. + protected List m_Storage; + + protected boolean m_IsCachedIsConstantDirty; + protected boolean m_CachedIsConstant; + + /** + Utility private method to create the list used to store + the collection. + @param PredictedNumItems A guess as to how many expressions + will end up in the collection. + */ + private void Construct( final int PredictedNumItems ) { + m_Storage = new ArrayList( PredictedNumItems ); + m_IsCachedIsConstantDirty = false; + m_CachedIsConstant = true; + } + + protected final void updateCachedIsConstant( ) { + if ( isCachedIsConstantDirty() ) { + StringExpressionCollectionIterator iter = getIterator(); + m_CachedIsConstant = true; + while ( ( m_CachedIsConstant ) && ( iter.hasNext() ) ) { + StringExpression currExp = iter.next(); + m_CachedIsConstant = currExp.isConstant() ; + } + m_IsCachedIsConstantDirty = false; + } + } + + protected final void cachedIsConstantIsDirty() { + m_IsCachedIsConstantDirty = true; + } + + protected final boolean isCachedIsConstantDirty() { + return m_IsCachedIsConstantDirty; + } + + protected final void notConstant() { + m_CachedIsConstant = false; + } + + /** + Default constructor. Allocates space for four expressions. + */ + public WriteableStringExpressionCollectionImpl( ) { + Construct( 4 ); + } + + /** + Constructor that allows the caller to communicate their best guess + as to how many expression will end up in the collection. + @param PredictedNumExpression A guess as to how many expressions + will end up in the collection. + */ + public WriteableStringExpressionCollectionImpl( final int PredictedNumExpressions ) { + Construct( PredictedNumExpressions ); + } + + + public StringExpressionCollectionIterator getIterator() { + return new StringExpressionCollectionIterator() { + private ListIterator m_Iter = m_Storage.listIterator(); + + + public StringExpression next() { + return ( StringExpression ) m_Iter.next() ; + } + + public StringExpression previous() { + return ( StringExpression ) m_Iter.previous() ; + } + + public boolean hasNext() { + return m_Iter.hasNext() ; + } + + public boolean hasPrevious() { + return m_Iter.hasPrevious(); + } + }; + } + + public boolean allMembersAreConstant() { + updateCachedIsConstant( ); + return m_CachedIsConstant; + } + + public int size() { + return m_Storage.size(); + } + + public WriteableStringExpressionCollectionIterator getWriteableIterator() { + return new WriteableStringExpressionCollectionIterator() { + private ListIterator m_Iter = m_Storage.listIterator(); + + public StringExpression next() { + return ( StringExpression ) m_Iter.next() ; + } + + public StringExpression previous() { + return ( StringExpression ) m_Iter.previous() ; + } + + public boolean hasNext() { + return m_Iter.hasNext() ; + } + + public boolean hasPrevious() { + return m_Iter.hasPrevious(); + } + + public void add( StringExpression exp ) { + m_Iter.add( exp ) ; + if ( ! ( isCachedIsConstantDirty() ) ) { + if ( allMembersAreConstant() ) { + if ( ! ( exp.isConstant() ) ) { + notConstant(); + } + } + } + } + + public void remove( ) { + cachedIsConstantIsDirty(); + m_Iter.remove(); + } + }; + } + + public void addExpression( StringExpression expToAdd ) { + m_Storage.add( expToAdd ); + if ( ! ( isCachedIsConstantDirty() ) ) { + if ( allMembersAreConstant() ) { + if ( ! ( expToAdd.isConstant() ) ) { + notConstant(); + } + } + } + } + + public void clear() { + m_Storage.clear(); + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpression.g b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpression.g new file mode 100644 index 0000000000..6ac279febc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/StringExpression.g @@ -0,0 +1,185 @@ +header { + package com.avlsi.fast.shapes.stringexpression.impl.parser; +} + +{ + + import com.avlsi.util.debug.Debug; + + import com.avlsi.fast.shapes.stringexpression.StringExpression; + import com.avlsi.fast.shapes.stringexpression.StringExpressionFactory; + import com.avlsi.fast.shapes.stringexpression.WriteableStringExpressionCollection; +} + + +class StringExpressionParser extends Parser ; +options { + k = 2; + buildAST = false; +} + +{ + protected StringExpressionFactory m_Factory; + //protected WriteableVariableDictionary m_VarDict; + public StringExpressionParser( TokenStream lexer, + StringExpressionFactory stringExpressionFactory + /*WriteableVariableDictionary varDict */ ) { + + this( lexer ); + + m_Factory = stringExpressionFactory; + } +} + +goal returns [ StringExpression exp ] + { + exp = null; + } + : + EOF + | exp=stringExpression + ; + +stringExpression returns [ StringExpression exp ] + { + StringExpression seed_term; + StringExpression curr_term; + WriteableStringExpressionCollection terms = null; + exp = null; + } + : + seed_term=stringExpressionAtom + ( + PLUS curr_term=stringExpressionAtom { + if ( terms == null ) { + terms = m_Factory.makeExpressionCollection(); + terms.addExpression( seed_term ); + } + terms.addExpression( curr_term ); + } + )* + + { + if ( terms == null ) { + exp = seed_term; + } + else { + exp = m_Factory.makeConcatOperator( terms ); + } + } + ; + + +protected +stringExpressionAtom returns [ StringExpression exp ] + { + exp = null; + } + : myIdent:IDENT { + exp = m_Factory.makeVariableReference( myIdent.getText() ); + } + | myString:STRING_LITERAL { + String str = myString.getText(); + exp = m_Factory.makeConstant(str.substring(1, str.length() - 1)); + } + | OPENPAREN exp=stringExpression CLOSEPAREN + ; + +class StringExpressionLexer extends Lexer; + +options { + charVocabulary = '\0'..'\377'; + k = 3; + caseSensitive = true ; + } + +{ + private boolean singleQuote = false; + + public StringExpressionLexer(final Reader in, boolean singleQuote) { + this(in); + this.singleQuote = singleQuote; + } + + public StringExpressionLexer(final InputStream in, boolean singleQuote) { + this(in); + this.singleQuote = singleQuote; + } +} + +PLUS : '+' ; + +/* Following 3 rules copied from http://www.antlr.org/grammars/java/java.g, + with semantic actions added and other small modifications */ +STRING_LITERAL + : { singleQuote }? '\'' (ESC|~('\''|'\\'))* '\'' + | { !singleQuote }? '"' (ESC|~('"'|'\\'))* '"' + ; + +protected +ESC + : '\\' + ( 'n' { $setText("\n"); } + | 'r' { $setText("\r"); } + | 't' { $setText("\t"); } + | 'b' { $setText("\b"); } + | 'f' { $setText("\f"); } + | '"' { $setText("\""); } + | '\'' { $setText("'"); } + | '\\' { $setText("\\"); } + | 'x' HEX_DIGIT HEX_DIGIT { + String esc = $getText; + char c[] = { (char) Integer.parseInt(esc.substring(2), 16) }; + String s = new String(c); + $setText(s); + } + | ('0'..'3') + ( + options { + warnWhenFollowAmbig = false; + } + : ('0'..'7') + ( + options { + warnWhenFollowAmbig = false; + } + : '0'..'7' + )? + )? { + String esc = $getText; + char c[] = { (char) Integer.parseInt(esc.substring(1), 8) }; + String s = new String(c); + $setText(s); + } + ) + ; + +protected +HEX_DIGIT + : ('0'..'9'|'A'..'F'|'a'..'f') + ; + +WS + : ( ' ' | '\t' | '\f' | ( '\n' { newline(); } ) ) + { $setType(Token.SKIP); } + ; + +CMT : "/*" (options {greedy=false;} : ( '\n' {newline();} | ~('\n') ) )* "*/" + + {$setType(Token.SKIP);} + ; + +IDENT + options {testLiterals=true;} + : ( LETTER | '_' ) ( LETTER | '_' | DIGIT )* + ; + +protected +LETTER + : 'a'..'z' | 'A'..'Z' + ; + +protected +DIGIT + : '0'..'9' + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/custom.mk new file mode 100644 index 0000000000..22d567f8f7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/impl/parser/custom.mk @@ -0,0 +1,5 @@ +MAKE_ANTLR_RULES_G_FILE_NAME := StringExpression.g +MAKE_ANTLR_RULES_LEXER_NAME := StringExpressionLexer +MAKE_ANTLR_RULES_PARSER_NAME := StringExpressionParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := StringExpressionParser +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariable.java new file mode 100644 index 0000000000..2aeac0d435 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariable.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + + + +/** + Interface to a string variable. + */ +public interface StringVariable { + /** + Retrieves the name of the variable. + @return The name of the variable. + */ + String getName( ); + /** + Retrieves the value of the variable. + @return A string which is the value of the variable. + */ + StringExpression getValue( ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionary.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionary.java new file mode 100644 index 0000000000..d9c3d401d2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionary.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionaryIterator; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + + +/** + Interface to a dictionary of string variable values. + */ +public interface StringVariableDictionary { + + /** + Returns the value of a string variable with the specified name. + Variable names are case sunsitive. + @param VariableName Name of the string variable you want the value of. + @return The value of the string variable if the variable exists in the + dictionary, null otherwise. The returned StringExpression can + contain references to other StringExpressions. + */ + StringExpression getVariableValue( final String VariableName ); + + /** + Returns an iterator that will iterate through all the string variables in + the dictionary. + @return An iterator that can be used to enumerate all the string + variables in the dictionary. + */ + StringVariableDictionaryIterator getIterator(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionaryIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionaryIterator.java new file mode 100644 index 0000000000..8fc4d03f53 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableDictionaryIterator.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariable; + +import java.util.NoSuchElementException; + +/** + Iterator interface for iterating over variable bindings + in a StringVariableDictionary. + @see StringVariableDictionary + */ +public interface StringVariableDictionaryIterator { + /** + Returns the next string variable in the dictionary if + there is one. + @exception NoSuchElementException Thrown when there is not + another string variable in the dictionary. + @return The next string variable in the StringVariableDictionary that + created the iterator. + + @throws NoSuchElementException + + */ + StringVariable next(); + /** + Determines if there is another string variable in the dictionary. + @return true if thare is another string variable in the dictionary + */ + boolean hasNext(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableUtil.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableUtil.java new file mode 100644 index 0000000000..d06fe65bf9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/StringVariableUtil.java @@ -0,0 +1,70 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionaryIterator; +import com.avlsi.fast.shapes.stringexpression.variable.WriteableStringVariableDictionary; + +public class StringVariableUtil { + /** + * This class should not be instantiated. + **/ + private StringVariableUtil() { } + + /** + Determines if all the values of the variables defined in the specified + dictionary have constant values. + @param d The variable dictionary. + @return true if all the values of the variables defined in the dictionary + have constant values. + */ + public static boolean allVariablesAreConstants( final StringVariableDictionary d ) { + StringVariableDictionaryIterator iter = d.getIterator() ; + boolean ret = true; + + while ( ( iter.hasNext() ) && ( ret ) ) { + StringVariable curr = iter.next() ; + ret = curr.getValue().isConstant(); + } + return ret; + } + + + /** + Evaluates the StringExpression that are the values of the variables + defined in src_dict, using the bindings in src_bindings. Stores + the resulting values in dest_dict. + @param src_dict The dictionary with the variables whose + values are to be evaluated using src_bindings. + @param src_bindings The bindings that are to be used to evaluate + the values of variables in src_dict. + @param dest_dict The dictionary into which the resulting + variable values are written into. + @exception IllegalArgumentException when src_dict and src_bindings + are the same dictionary. + */ + public static + void evaluateVariableValues( final StringVariableDictionary src_dict, + final StringVariableDictionary src_bindings, + WriteableStringVariableDictionary dest_dict ) { + + if ( src_dict == src_bindings ) { + throw new IllegalArgumentException() ; + } + + StringVariableDictionaryIterator iter = src_dict.getIterator(); + + while ( iter.hasNext() ) { + StringVariable curr = iter.next() ; + dest_dict.unBindVariable( curr.getName() ); + dest_dict.bindVariable( curr.getName(), + curr.getValue().evaluate( src_dict ) ); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariable.java new file mode 100644 index 0000000000..dc0aad885a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariable.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariable; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +/** + Interface to a string variable. + */ +public interface WriteableStringVariable extends StringVariable { + + /** + Sets the value of the string variable to the specified string. + @param NewValue The new value of the variable. + */ + void setValue( StringExpression NewValue ); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionary.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionary.java new file mode 100644 index 0000000000..603411a886 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionary.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable; + +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; + +import com.avlsi.fast.shapes.stringexpression.variable.WriteableStringVariableDictionaryIterator; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; + +/** + Interface to a variable dictionary that can be changed. + */ +public interface WriteableStringVariableDictionary + extends StringVariableDictionary { + /** + Binds a StringExpression to a string variable with the specified name. + @param VariableName The name of the string variable to bind the specified + expression to. + @param Value The new value of the string variable. + @return false when there was already a string variable with the same + name. + */ + boolean bindVariable( final String VariableName, + final StringExpression Value ); + + /** + Unbinds a string variable with the specified name. + @param VariableName The name of the string variable to unbind. + */ + void unBindVariable( final String VariableName ); + + /** + Returns an iterator that will iterate through all the string variables in + the dictionary. + @return An iterator that can be used to enumerate all the string variables + in the dictionary. + */ + WriteableStringVariableDictionaryIterator getWriteableIterator(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionaryIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionaryIterator.java new file mode 100644 index 0000000000..18d1a37f2b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/WriteableStringVariableDictionaryIterator.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable; + +import com.avlsi.fast.shapes.stringexpression.variable.WriteableStringVariable; + +import java.util.NoSuchElementException; + +/** + Iterator interface for iterating over string variable bindings + in a WriteableStringVariableDictionary. + @see WriteableStringVariableDictionary + */ +public interface WriteableStringVariableDictionaryIterator { + /** + Returns the next string variable in the dictionary if there is one. + @exception NoSuchElementException Thrown when there is not + another string variable in the dictionary. + @return The next string variable in the VariableDictionary that + created the iterator. + @throws NoSuchElementException + */ + WriteableStringVariable next( ); + /** + Determines if there is another string variable in the dictionary. + @return true if thare is another string variable in the dictionary + */ + boolean hasNext( ); + + /** + Removes the last string variable returned by the iterator from + the dictionary. + */ + void remove( ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/impl/WriteableStringVariableDictionaryImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/impl/WriteableStringVariableDictionaryImpl.java new file mode 100644 index 0000000000..a7ee916544 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/fast/shapes/stringexpression/variable/impl/WriteableStringVariableDictionaryImpl.java @@ -0,0 +1,156 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.fast.shapes.stringexpression.variable.impl; + +import java.util.Iterator; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.fast.shapes.stringexpression.StringExpression; +import com.avlsi.fast.shapes.stringexpression.variable.WriteableStringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionaryIterator; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariableDictionary; +import com.avlsi.fast.shapes.stringexpression.variable.WriteableStringVariableDictionaryIterator; +import com.avlsi.fast.shapes.stringexpression.variable.StringVariable; +import com.avlsi.fast.shapes.stringexpression.variable.WriteableStringVariable; + +/** + Default implementation of WriteableStringVariableDictionary interface. + */ +public class WriteableStringVariableDictionaryImpl + implements WriteableStringVariableDictionary { + + protected Map storage; + + public final StringExpression putVariable( final String varName, + final StringExpression val ) { + return ( StringExpression ) storage.put( varName, val ); + } + + /** + Default constructor. Uses a HashMap for storage. + */ + public WriteableStringVariableDictionaryImpl( ) { + storage = new HashMap( ); + } + + public WriteableStringVariableDictionaryImpl( StringVariableDictionary vDict ) { + this(); + + StringVariableDictionaryIterator iter = vDict.getIterator(); + + while ( iter.hasNext() ) { + StringVariable currVar = iter.next() ; + putVariable( currVar.getName(), currVar.getValue() ); + } + } + + + /** + Dictionary will use specified map for storage. + @param MapToUseForStorage Object implementing java.util.Map that the + dictionary should use for storage. You should not reference + this map after using this constructor. + */ + public WriteableStringVariableDictionaryImpl( Map MapToUseForStorage ) { + storage = MapToUseForStorage; + } + + public StringExpression getVariableValue( final String StringVariableName ) { + return ( StringExpression ) storage.get( StringVariableName ) ; + } + + public StringVariableDictionaryIterator getIterator() { + return new StringVariableDictionaryIterator() { + private Iterator m_Iter = storage.entrySet().iterator(); + + /** @throws NoSuchElementException **/ + public StringVariable next() { + Map.Entry CurrEntry = (Map.Entry) m_Iter.next(); + String VarName = + ( String ) CurrEntry.getKey(); + StringExpression VarVal = + ( StringExpression ) CurrEntry.getValue(); + + return new WriteableStringVariableImpl( VarName ); + + } + + public boolean hasNext() { + return m_Iter.hasNext() ; + } + + }; + } + + public boolean bindVariable( final String StringVariableName, + final StringExpression Exp ) { + StringExpression PrevValue = putVariable( StringVariableName, Exp ); + if ( PrevValue != null ) { + putVariable( StringVariableName, PrevValue ) ; + } + return PrevValue == null ; + } + + public WriteableStringVariableDictionaryIterator getWriteableIterator() { + return new WriteableStringVariableDictionaryIterator() { + private Iterator m_Iter = storage.entrySet().iterator(); + + /** @throws NoSuchElementException **/ + public WriteableStringVariable next( ) { + Map.Entry CurrEntry = (Map.Entry) m_Iter.next(); + String varName = + ( String ) CurrEntry.getKey(); + StringExpression VarVal = + ( StringExpression ) CurrEntry.getValue(); + + return new WriteableStringVariableImpl( varName ); + + } + + public boolean hasNext( ) { + return m_Iter.hasNext(); + } + + public void remove( ) { + m_Iter.remove(); + } + }; + } + + public void unBindVariable( final String variableName ) { + storage.remove( variableName ); + } + + /** + Default implementation of WriteableStringVariable. + */ + private class WriteableStringVariableImpl implements WriteableStringVariable { + + protected final String m_Name; + + /** + @param Name The name of the variable. + */ + public WriteableStringVariableImpl( final String name ) { + m_Name = name; + } + + public String getName( ) { + return m_Name; + } + + public StringExpression getValue( ) { + return getVariableValue( m_Name ); + } + + public void setValue( StringExpression exp ) { + putVariable( m_Name, exp ); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AbstractDeviceTest.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AbstractDeviceTest.java new file mode 100644 index 0000000000..3897c585ae --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AbstractDeviceTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +/** + * Class that tests devices + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +abstract class AbstractDeviceTest { + // Device + protected final DeviceInterface device; + + // Voltage value ranges for test graphs + protected final double low = 0.0; + protected final double high = 2.0; + + // Number of iterations (data points to gather) + protected long numIter = 100; + + // Minus one because we test both endpoints + protected final double step = (high-low) / (numIter-1); + + protected AbstractDeviceTest(DeviceInterface device) { + this.device = device; + } + + // Technically stated there should be API function calls that + // set step/low/high and numIter is automatically recalculated + // from that, but it's much easier to make the variables constant + // instead. How often do you really want to change that information + // during run-time? + + /** + * Test the device + * @param voltageRange Boundary point voltages to test + * @param numIter Number of iterations to test + **/ + public void test() + { + try { + final int numPorts = device.getNumPorts(); + double[][] voltageRange = getVoltageRange(); + GraphPortData[] graphers = makeGraphers(); + + // You need at least 2 data points for a graph + if (numIter < 2) + numIter = 2; + + // Compute starting voltages and voltage step between iterations + // Allocate Port Data object + double [] voltage = new double [numPorts]; + double [] step = new double [numPorts]; + PortData[] data = new PortData[numPorts]; + + for (int i = 0; i < numPorts; i++) { + voltage[i] = voltageRange[i][0]; + step[i] = (voltageRange[i][1] - voltageRange[i][0]) / + (numIter - 1); + data[i] = new PortData(numPorts); + } + + long startTime = System.currentTimeMillis(); + + for (long i = 0; i < numIter; i++) { + device.evalVoltage(data, voltage); + + for (int j = 0; j < graphers.length; j++) + graphers[j].writeCoordinate(data); + + for (int j = 0; j < numPorts; j++) + voltage[j] += step[j]; + } + + long endTime = System.currentTimeMillis(); + double diff = (endTime - startTime) / 1000.0; + System.out.println(numIter + " " + device.getClass().getName() + + " tests took " + diff + " seconds."); + System.out.println(" That's " + (numIter / diff) + + " evaluations per second"); + + for (int i = 0; i < graphers.length; i++) + graphers[i].close(); + } catch (IOException e) { + System.out.println(e); + } catch (NoModelException e) { + System.out.println("Couldn't find a model for tested device."); + } + } + + protected abstract double[][] getVoltageRange(); + protected abstract GraphPortData[] makeGraphers() + throws IOException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceCell.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceCell.java new file mode 100644 index 0000000000..3b02525193 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceCell.java @@ -0,0 +1,585 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +//import com.avlsi.file.common.Capacitor; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Namespace; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.UnaryFunction; + +import com.avlsi.circuit.AbstractCircuit; +import com.avlsi.circuit.ResistorInterface; +import com.avlsi.circuit.DiodeInterface; +import com.avlsi.circuit.TransistorInterface; +import com.avlsi.circuit.CapacitorInterface; + +/** + * Class to represent a parsed .aspice file. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class AspiceCell extends AbstractCircuit { + + /** + * List of Diodes. + **/ + private final List diodeList = new ArrayList(); + + /** + * List of Resistors + **/ + private final List resistorList = new ArrayList(); + + /** + * List of Transistors. + **/ + private final List transistorList = new ArrayList(); + + /** + * List of capacitors. + **/ + private final List capacitorList = new ArrayList(); + + /** + * Map from subcell use name (String) to AspiceCell + **/ + private final Map subcellUseMap = new TreeMap(); + + + /** + * Namespace info. Map from set of names to null object. + * Names may be in this sell or of the form sub.name for + * captured names from subcells. + **/ + private final AliasedMap asm + = new AliasedMap(new AliasedMap.MergeFunction() { + public Object merge(final Object a, final Object b) { + if (a == null) + return b; + else if (b == null) + return a; + else { + Debug.assertTrue(a == EXISTS); + Debug.assertTrue(b == EXISTS); + return EXISTS; + } + } + }, HierName.getComparator()); + + private static final Object EXISTS = new Object(); + + /************************************************* + * Static nested subcircuit repository subclass. + *************************************************/ + public static class Repository extends AbstractCircuit.Repository { + /** + * AspiceCell generator method. + **/ + protected AbstractCircuit newCircuitGenerator(final String cellType) { + return new AspiceCell(cellType); + } + } + + // + // class constructor + // + + /** + * Class constructor. Use mutators to build up an AspiceCell. + **/ + public AspiceCell(final String type) { + super(type); + } + + + // + // subcellUseMap related methods + // + + /** + * Returns an Iterator of Strings representing subcell names. + **/ + public Iterator getSubcellNames() { + return subcellUseMap.keySet().iterator(); + } + + /** + * Adds a definition defn for subName, replacing any existing definition. + **/ + public void addSubcell(final String subName, final AspiceCell defn) { + final Object o = subcellUseMap.put(subName, defn); + + if (o != null) + throw new RuntimeException("duplicate defn for " + subName + + " old defn replaced"); + } + + /** + * returns the type of the subcell based on its name, or null + * if there is no subcell of that name. + **/ + public String getSubcellTypeForName(final String name) { + final AbstractCircuit a = getSubcellDefForName(name); + + if (a == null) + return null; + else + return a.getType(); + } + + // + // diodeList related methods + // + + /** + * Returns an Iterator of the defined Diodes. + **/ + public Iterator getDiodes() { + return diodeList.iterator(); + } + + /** + * Adds a diode to the list of diodes. + **/ + public void addDiode(final DiodeInterface diode) { + addName(diode.getSource()); + addName(diode.getDrain()); + diodeList.add(new Diode(diode.getType(),diode.getSource(), + diode.getDrain(), + diode.getWidth(), diode.getLength(), + diode.getArea(), diode.getPerimeter())); + } + + // + // resistorList related methods + // + + /** + * Returns an Iterator of the defined Resistors. + **/ + public Iterator getResistors() { + return resistorList.iterator(); + } + + /** + * Adds a resistor to the list of resistors. + **/ + public void addResistor(final ResistorInterface r) { + addName(r.getSource()); + addName(r.getDrain()); + resistorList.add(new Resistor(r.getSource(), + r.getDrain(), + r.getConductance())); + } + + /** + * Returns the number of resistors in the file. + * (Not including resistors in subcells.) + **/ + public int getResistorCount() { + return resistorList.size(); + } + + // + // transistorList related methods + // + + /** + * Returns an Iterator of the defined Transistors + **/ + public Iterator getTransistors() { + return transistorList.iterator(); + } + + /** + * Adds a transistor to the list of transistors. + **/ + public void addTransistor(final TransistorInterface t) { + addName(t.getSource()); + addName(t.getDrain()); + addName(t.getGate()); + addName(t.getBulk()); + transistorList.add(new Transistor( t.getType(), t.getSource(), + t.getDrain(),t.getGate(), + t.getBulk(), + t.getWidth(), t.getLength())); + } + + /** + * Returns the number of transistors in the file. + * (Not including transistors in subcells.) + **/ + public int getTransistorCount() { + return transistorList.size(); + } + + + /** + * Returns the number of transistors in the file. + * (Not including transistors in subcells.) + **/ + public int getDiodeCount() { + return diodeList.size(); + } + + + // + // capacitorList related methods + // + + /** + * Returns an Iterator of the defined Capacitors + **/ + public Iterator getCapacitors() { + return capacitorList.iterator(); + } + + /** + * Adds a capacitor to the list of capacitors. + **/ + public void addCapacitor(final CapacitorInterface capacitor) { + addName(capacitor.getSource()); + addName(capacitor.getDrain()); + capacitorList.add(new Capacitor(capacitor.getSource(), + capacitor.getDrain(), + capacitor.getCapacitance())); + } + + /** + * Returns the number of capacitors in the file. + * (Not including capacitors in subcells.) + **/ + public int getCapacitorCount() { + return capacitorList.size(); + } + + + // + // namespace related methods + // + + /** + * Returns an iterator of HierNames representing the canonical names. + **/ + public Iterator getCanonicalNames() { + return asm.getCanonicalKeys(); + } + + /** + * returns the canonical name for a node + **/ + public HierName getCanonicalName(final HierName nodeName) { + return (HierName) asm.getCanonicalKey(nodeName); + } + + /** + * Adds a name. + **/ + public void addName(final HierName nodeName) + { + try { + if (nodeName.isGlobal()) + addGlobal(nodeName); + asm.addData(nodeName, EXISTS); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + /** + * Connects the two names, adding them if they don't both + * exist. + **/ + public void connectNames(final HierName name1, final HierName name2) + { + try { + if (name1.isGlobal()) + addGlobal(name1); + if (name2.isGlobal()) + addGlobal(name2); + asm.makeEquivalent(name1, name2); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + /** + * Returns an Iterator of HierName of the equivalent names to + * the node. Includes name in the list. + **/ + public Iterator getEquivalentNames(final HierName name) { + return asm.getAliases(name); + } + + /** + * String representation of namespace for debugging. + **/ + public String getNamespaceString() { + return asm.toString(); + } + + // + // misc + // + + /** + * Returns true if this cell or any of its subcells as a fet. + **/ + public boolean hasTransistors() { + if (transistorList.size() > 0) + return true; + + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String subcellName = (String) i.next(); + + if (((AspiceCell)getSubcellDefForName(subcellName)).hasTransistors()) + return true; + } + + return false; + } + + + // + // output methods + // + + public void printToStream(final OutputStream out, final AspiceCell.Repository repos) { + final PrintWriter pw = new PrintWriter(out); + printToWriter(pw, 0, repos); + pw.close(); + } + + private void printToWriter(final PrintWriter pw, int nestingLevel, + final AspiceCell.Repository repos) { + + // print subcell definitions, if at top level + if (nestingLevel == 0) { + // find the set of reachable types + final List typeList = new ArrayList(); + foldSubcells(new BinaryFunction() { + public Object execute(final Object a, final Object b) { + final AspiceCell af = (AspiceCell) a; + + // add my type to the set if it is not already there, + // except for type of root + if (!af.getType().equals(getType()) + && !typeList.contains(af.getType())) + typeList.add(af.getType()); + + return null; + } + }, null); + + // print the definitions for the types we have found + // @review jmr XXX they will not be printed in any specific + // order, maybe this is a problem + for (final Iterator i = typeList.iterator(); i.hasNext(); ) { + final String type = (String) i.next(); + final AspiceCell af + = (AspiceCell) repos.getCell(type); + + af.printToWriter(pw, nestingLevel + 1, repos); + } + } + + pw.println("define " + getType()); + pw.println("{"); + + // print subcell instantiations + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String name = (String) i.next(); + final String type = getSubcellTypeForName(name); + + pw.println(type + " " + name + ";"); + } + + // print wires + for (final Iterator i = getCanonicalNames(); i.hasNext(); ) { + final HierName canonicalName = (HierName) i.next(); + final Wire wire = new Wire(); + + // get all the aliases for this name + for (final Iterator iAlias = asm.getAliases(canonicalName); + iAlias.hasNext(); ) { + final String s = ((HierName) iAlias.next()).getAspiceString(); + wire.addNode(s); + } + + // if the wire actually connects something + if (wire.getNumNodes() > 1) + pw.println(wire.getAspiceString()); + } + + // print caps + for (final Iterator i = getCapacitors(); i.hasNext(); ) { + final Capacitor cap = (Capacitor) i.next(); + + Debug.assertTrue(!asm.equivalent(cap.getSource(), cap.getDrain())); + + pw.println(cap.getAspiceString()); + } + + // print diodes + for (final Iterator i = getDiodes(); i.hasNext(); ) { + final Diode d = (Diode) i.next(); + + pw.println(d.getAspiceString()); + } + + // print resistors + for (final Iterator i = getResistors(); i.hasNext(); ) { + final Resistor r = (Resistor) i.next(); + + pw.println(r.getAspiceString()); + } + + // print transistors + for (final Iterator i = getTransistors(); i.hasNext(); ) { + final Transistor t = (Transistor) i.next(); + + pw.println(t.getAspiceString()); + } + + pw.println("}\n"); + + // if at top level, print globals + if (nestingLevel == 0) { + for (final Iterator i = getGlobals(); i.hasNext(); ) { + final HierName global = (HierName) i.next(); + + pw.println(".global " + global.getAspiceString() + ";"); + } + } + } + + /** + * If cell has children c1, c2, c3, ..., cN, computes + * f(this, f(c1, f(c2, ..., f(cN, unit)...))). The first argument of + * f is type AspiceCell, the second is type Object, and represents + * the state of the traversal. The traversal order of subcells is + * not defined. + **/ + public Object foldSubcells(final BinaryFunction f, Object unit) { + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String subcellName = (String) i.next(); + + unit = ((AspiceCell)getSubcellDefForName(subcellName)).foldSubcells(f, unit); + } + + return f.execute(this, unit); + } + + /** + * Imports the contents of another aspice file, prefixing + * all node names with prefix. + **/ + private void importCell(final String prefix, final AspiceCell af) { + + throw new AssertionFailure("FIXME XXX"); + /* + // import diodes + for (final Iterator i = af.getDiodes(); i.hasNext(); ) { + final Diode d = (Diode) i.next(); + + addDiode(new Diode(d.getType(), + prefix + d.getSource(), prefix + d.getDrain(), + d.getWidth(), d.getLength(), + d.getArea(), d.getPerimeter())); + } + + // import transistors + for (final Iterator i = af.getTransistors(); i.hasNext(); ) { + final Transistor t = (Transistor) i.next(); + + addTransistor(new Transistor(t.getType(), + prefix + t.getSource(), prefix + t.getDrain(), + prefix + t.getGate(), prefix + t.getBulk(), + t.getWidth(), t.getLength())); + } + + // import caps + for (final Iterator i = af.getCapacitors(); i.hasNext(); ) { + final Capacitor c = (Capacitor) i.next(); + + addCapacitor(new Capacitor(prefix + c.getSource(), + prefix + c.getDrain(), c.getCap())); + } + + // XXX import resistors + + // import globals + for (final Iterator i = af.getGlobals(); i.hasNext(); ) { + final String g = (String) i.next(); + + addGlobal(prefix + g); + } + + // import namespace + try { + asm.adopt(prefix, new UnaryFunction() { + public Object execute(final Object a) { + Debug.assertTrue(a == null); + return null; + } + }, af.asm); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure("How can merge fail when" + + " it doesn't do anything?"); + } + */ + } + + /** + * Flattens the AspiceCell and all its subcells into a flat + * representation, with no subcells. Returns a new AspiceCell, + * and does not modify any existing ones. Does not modify the + * subcellNameToDefnMap. + **/ + public AspiceCell flatten() { + // @todo jmr XXX abstract out this recursion + + final AspiceCell af = new AspiceCell(getType()); + + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String subcellName = (String) i.next(); + final AspiceCell flat + = ((AspiceCell)getSubcellDefForName(subcellName)).flatten(); + + af.importCell(subcellName + ".", flat); + } + + af.importCell("", this); + + return af; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceFile.java new file mode 100644 index 0000000000..de05c46740 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/AspiceFile.java @@ -0,0 +1,646 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.avlsi.file.common.Capacitor; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Namespace; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.UnaryFunction; + +/** + * Class to represent a parsed .aspice file. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class AspiceFile { + /** + * Name of the cell. + **/ + private final String name; + + /** + * Ports of cell. + **/ + private final List portList = new ArrayList(); + + /** + * List of Diodes. + **/ + private final List diodeList = new ArrayList(); + + /** + * List of Resistors + **/ + private final List resistorList = new ArrayList(); + + /** + * List of Transistors. + **/ + private final List transistorList = new ArrayList(); + + /** + * List of capacitors. + **/ + private final List capacitorList = new ArrayList(); + + /** + * Global repository for subcell definitions. Passed + * to constructor. + **/ + private final Map subcellNameToDefnMap; + + /** + * Map from subcell use name (String) to AspiceFile + **/ + private final Map subcellUseMap = new TreeMap(); + + /** + * Set of global names mentioned at in this cell or in subcells. + **/ + private final Set globalsSet = new TreeSet(); + + /** + * Namespace info. Map from set of names to null object. + * Names may be in this sell or of the form sub.name for + * captured names from subcells. + **/ + private final AliasedMap asm + = new AliasedMap(new AliasedMap.MergeFunction() { + public Object merge(final Object a, final Object b) { + if (a == null) + return b; + else if (b == null) + return a; + else { + Debug.assertTrue(a == EXISTS); + Debug.assertTrue(b == EXISTS); + return EXISTS; + } + } + }, HierName.getComparator()); + + private static final Object EXISTS = new Object(); + + + // + // class constructor + // + + /** + * Class constructor. Use mutators to build up an AspiceFile. + **/ + public AspiceFile(final String name, final Map subcellNameToDefnMap) { + this.name = name; + this.subcellNameToDefnMap = subcellNameToDefnMap; + } + + // + // name related methods + // + + public String getName() { + return name; + } + + // + // subcellUseMap related methods + // + + /** + * Returns an Iterator of Strings representing subcell names. + **/ + public Iterator getSubcellNames() { + return subcellUseMap.keySet().iterator(); + } + + /** + * Adds a definition defn for subName, replacing any existing definition. + **/ + public void addSubcell(final String subName, final AspiceFile defn) { + final Object o = subcellUseMap.put(subName, defn); + + if (o != null) + throw new RuntimeException("duplicate defn for " + subName + + " old defn replaced"); + } + + /** + * returns the definition of the subcell based on its name + **/ + public AspiceFile getSubcellDefForName(final String name) { + return (AspiceFile) subcellUseMap.get(name); + } + + /** + * returns the type of the subcell based on its name, or null + * if there is no subcell of that name. + **/ + public String getSubcellTypeForName(final String name) { + final AspiceFile a = getSubcellDefForName(name); + + if (a == null) + return null; + else + return a.getName(); + } + + // + // diodeList related methods + // + + /** + * Returns an Iterator of the defined Diodes. + **/ + public Iterator getDiodes() { + return diodeList.iterator(); + } + + /** + * Adds a diode to the list of diodes. + **/ + public void addDiode(final Diode diode) { + addName(diode.getSource()); + addName(diode.getDrain()); + diodeList.add(diode); + } + + // + // resistorList related methods + // + + /** + * Returns an Iterator of the defined Resistors. + **/ + public Iterator getResistors() { + return resistorList.iterator(); + } + + /** + * Adds a resistor to the list of resistors. + **/ + public void addResistor(final Resistor resistor) { + addName(resistor.getSource()); + addName(resistor.getDrain()); + resistorList.add(resistor); + } + + /** + * Returns the number of resistors in the file. + * (Not including resistors in subcells.) + **/ + public int getResistorCount() { + return resistorList.size(); + } + + // + // transistorList related methods + // + + /** + * Returns an Iterator of the defined Transistors + **/ + public Iterator getTransistors() { + return transistorList.iterator(); + } + + /** + * Adds a transistor to the list of transistors. + **/ + public void addTransistor(final Transistor transistor) { + addName(transistor.getSource()); + addName(transistor.getDrain()); + addName(transistor.getGate()); + addName(transistor.getBulk()); + transistorList.add(transistor); + } + + /** + * Returns the number of transistors in the file. + * (Not including transistors in subcells.) + **/ + public int getTransistorCount() { + return transistorList.size(); + } + + + // + // capacitorList related methods + // + + /** + * Returns an Iterator of the defined Capacitors + **/ + public Iterator getCapacitors() { + return capacitorList.iterator(); + } + + /** + * Adds a capacitor to the list of capacitors. + **/ + public void addCapacitor(final Capacitor capacitor) { + addName(capacitor.getSource()); + addName(capacitor.getDrain()); + capacitorList.add(capacitor); + } + + /** + * Returns the number of capacitors in the file. + * (Not including capacitors in subcells.) + **/ + public int getCapacitorCount() { + return capacitorList.size(); + } + + + // + // namespace related methods + // + + /** + * Returns an iterator of HierNames representing the canonical names. + **/ + public Iterator getCanonicalNames() { + return asm.getCanonicalKeys(); + } + + /** + * returns the canonical name for a node + **/ + public HierName getCanonicalName(final HierName nodeName) { + return (HierName) asm.getCanonicalKey(nodeName); + } + + /** + * Adds a name. + **/ + public void addName(final HierName nodeName) { + try { + if (nodeName.isGlobal()) + addGlobal(nodeName); + asm.addData(nodeName, EXISTS); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + /** + * Adds a name and adds to port list. + **/ + public void addPort(final HierName nodeName) { + addName(nodeName); + portList.add(nodeName); + } + + /** + * Returns portList. + **/ + public List getPortList() { + return (List) portList; + } + + /** + * Connects the two names, adding them if they don't both + * exist. + **/ + public void connectNames(final HierName name1, final HierName name2) { + try { + if (name1.isGlobal()) + addGlobal(name1); + if (name2.isGlobal()) + addGlobal(name2); + asm.makeEquivalent(name1, name2); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + /** + * Returns an Iterator of HierName of the equivalent names to + * the node. Includes name in the list. + **/ + public Iterator getEquivalentNames(final HierName name) { + return asm.getAliases(name); + } + + /** + * String representation of namespace for debugging. + **/ + public String getNamespaceString() { + return asm.toString(); + } + + // + // globals + // + + /** + * Adds name to the set of global names. A name should be added if + * and only if it is a global name mentioned in this cell, + * or a subcell of this cell. The path separator is '.'. + **/ + private void addGlobal(final HierName name) { + globalsSet.add(name); + } + + /** + * Returns an Iterator of HierName, the globals in this cell or + * its subcells. + **/ + public Iterator getGlobals() { + return globalsSet.iterator(); + } + + + // + // misc + // + + /** + * Returns true if this cell or any of its subcells has a transistor. + **/ + public boolean hasTransistors() { + if (transistorList.size() > 0) + return true; + + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String subcellName = (String) i.next(); + + if (getSubcellDefForName(subcellName).hasTransistors()) + return true; + } + + return false; + } + + /** + * Returns true if this cell or any of its subcells has a + * particular set of devices. + **/ + public boolean hasDevices(boolean doTransistors, + boolean doDiodes, + boolean doResistors, + boolean doCapacitors) { + if (doTransistors && (transistorList.size() > 0)) + return true; + if (doDiodes && (diodeList.size() > 0)) + return true; + if (doResistors && (resistorList.size() > 0)) + return true; + if (doCapacitors && (capacitorList.size() > 0)) + return true; + + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String subcellName = (String) i.next(); + + if (getSubcellDefForName(subcellName).hasDevices(doTransistors, + doDiodes, + doResistors, + doCapacitors)) + return true; + } + + return false; + } + + // + // output methods + // + + public void printToStream(final OutputStream out) { + final PrintWriter pw = new PrintWriter(out); + printToWriter(pw, 0); + pw.close(); + } + + private void printToWriter(final PrintWriter pw, int nestingLevel) { + + // print subcell definitions, if at top level + if (nestingLevel == 0) { + // find the set of reachable types + final List typeList = new ArrayList(); + foldSubcells(new BinaryFunction() { + public Object execute(final Object a, final Object b) { + final AspiceFile af = (AspiceFile) a; + + // add my type to the set if it is not already there, + // except for type of root + if (!af.getName().equals(getName()) + && !typeList.contains(af.getName())) + typeList.add(af.getName()); + + return null; + } + }, null); + + // print the definitions for the types we have found + // @review jmr XXX they will not be printed in any specific + // order, maybe this is a problem + for (final Iterator i = typeList.iterator(); i.hasNext(); ) { + final String type = (String) i.next(); + final AspiceFile af + = (AspiceFile) subcellNameToDefnMap.get(type); + + af.printToWriter(pw, nestingLevel + 1); + } + } + + pw.println("define " + getName()); + pw.println("{"); + + // print subcell instantiations + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String name = (String) i.next(); + final String type = getSubcellTypeForName(name); + + pw.println(type + " " + name + ";"); + } + + // print wires + for (final Iterator i = getCanonicalNames(); i.hasNext(); ) { + final HierName canonicalName = (HierName) i.next(); + final Wire wire = new Wire(); + + // get all the aliases for this name + for (final Iterator iAlias = asm.getAliases(canonicalName); + iAlias.hasNext(); ) { + final String s = ((HierName) iAlias.next()).getAspiceString(); + wire.addNode(s); + } + + // if the wire actually connects something + if (wire.getNumNodes() > 1) + pw.println(wire.getAspiceString()); + } + + // print caps + for (final Iterator i = getCapacitors(); i.hasNext(); ) { + final Capacitor cap = (Capacitor) i.next(); + + Debug.assertTrue(!asm.equivalent(cap.getSource(), cap.getDrain())); + + pw.println(cap.getAspiceString()); + } + + // print diodes + for (final Iterator i = getDiodes(); i.hasNext(); ) { + final Diode d = (Diode) i.next(); + + pw.println(d.getAspiceString()); + } + + // print resistors + for (final Iterator i = getResistors(); i.hasNext(); ) { + final Resistor r = (Resistor) i.next(); + + pw.println(r.getAspiceString()); + } + + // print transistors + for (final Iterator i = getTransistors(); i.hasNext(); ) { + final Transistor t = (Transistor) i.next(); + + pw.println(t.getAspiceString()); + } + + pw.println("}\n"); + + // if at top level, print globals + if (nestingLevel == 0) { + for (final Iterator i = getGlobals(); i.hasNext(); ) { + final HierName global = (HierName) i.next(); + + pw.println(".global " + global.getAspiceString() + ";"); + } + } + } + + /** + * If cell has children c1, c2, c3, ..., cN, computes + * f(this, f(c1, f(c2, ..., f(cN, unit)...))). The first argument of + * f is type AspiceFile, the second is type Object, and represents + * the state of the traversal. The traversal order of subcells is + * not defined. + **/ + public Object foldSubcells(final BinaryFunction f, Object unit) { + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String subcellName = (String) i.next(); + + unit = getSubcellDefForName(subcellName).foldSubcells(f, unit); + } + + return f.execute(this, unit); + } + + /** + * Imports the contents of another aspice file, prefixing + * all node names with prefix. + **/ + private void importCell(final String prefix, final AspiceFile af) { + + throw new AssertionFailure("FIXME XXX"); + /* + // import diodes + for (final Iterator i = af.getDiodes(); i.hasNext(); ) { + final Diode d = (Diode) i.next(); + + addDiode(new Diode(d.getType(), + prefix + d.getSource(), prefix + d.getDrain(), + d.getWidth(), d.getLength(), + d.getArea(), d.getPerimeter())); + } + + // import transistors + for (final Iterator i = af.getTransistors(); i.hasNext(); ) { + final Transistor t = (Transistor) i.next(); + + addTransistor(new Transistor(t.getType(), + prefix + t.getSource(), prefix + t.getDrain(), + prefix + t.getGate(), prefix + t.getBulk(), + t.getWidth(), t.getLength())); + } + + // import caps + for (final Iterator i = af.getCapacitors(); i.hasNext(); ) { + final Capacitor c = (Capacitor) i.next(); + + addCapacitor(new Capacitor(prefix + c.getSource(), + prefix + c.getDrain(), c.getCap())); + } + + // XXX import resistors + + // import globals + for (final Iterator i = af.getGlobals(); i.hasNext(); ) { + final String g = (String) i.next(); + + addGlobal(prefix + g); + } + + // import namespace + try { + asm.adopt(prefix, new UnaryFunction() { + public Object execute(final Object a) { + Debug.assertTrue(a == null); + return null; + } + }, af.asm); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure("How can merge fail when" + + " it doesn't do anything?"); + } + */ + } + + /** + * Flattens the AspiceFile and all its subcells into a flat + * representation, with no subcells. Returns a new AspiceFile, + * and does not modify any existing ones. Does not modify the + * subcellNameToDefnMap. + **/ + public AspiceFile flatten() { + // @todo jmr XXX abstract out this recursion + + final AspiceFile af = new AspiceFile(getName(), new TreeMap()); + + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String subcellName = (String) i.next(); + final AspiceFile flat + = getSubcellDefForName(subcellName).flatten(); + + af.importCell(subcellName + ".", flat); + } + + af.importCell("", this); + + return af; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/BSim3Model.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/BSim3Model.java new file mode 100644 index 0000000000..5b7f263372 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/BSim3Model.java @@ -0,0 +1,1623 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StreamTokenizer; +import java.util.Iterator; +import java.util.ArrayList; + +import com.avlsi.file.common.DeviceTypes; + +/** + * Read in BSIM3 files and create java Model objects from them + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public class BSim3Model { + protected static ArrayList models = new ArrayList(); + + private static final int NMOS = 1; + private static final int PMOS = -1; + + public static void readFile(String fileName, double temperature) + { + FileInputStream file = null; + try { + file = new FileInputStream(fileName); + StreamTokenizer st = new StreamTokenizer( + new BufferedReader( + new InputStreamReader(file) + ) + ); + // For some reason, the steam tokenizer defaults number + // processing mode on and has no way of automatically turning + // it off-- hence this code. + st.resetSyntax(); + st.wordChars(0, 255); + + st.whitespaceChars(' ', ' '); + st.whitespaceChars('\t', '\t'); + st.whitespaceChars('\n', '\n'); + st.whitespaceChars('\r', '\r'); + st.whitespaceChars('=', '='); + + st.lowerCaseMode(true); + st.commentChar('*'); + + // Set of data states describing which state machine state + // we're in (ie. what data we're waiting for) + + final int BSIM_ERROR = 0; // Found error-- abort + final int BSIM_IDLE = 1; // Start state or Found ) + final int BSIM_MODEL = 2; // Found .MODEL + final int BSIM_NAME = 3; // Found CMOSN, CMOSP, etc. + final int BSIM_TYPE = 4; // Found NMOS, PMOS, etc. + final int BSIM_DATA = 5; // Found ( or field value + final int BSIM_FIELD = 6; // Found Field name + int state = BSIM_IDLE; + + // The for loop below encodes a simple state machine on + // These states. They link as follows: + // Name -> Type -> Data ---> Field + // ^ | ^ | + // | v | | + // -- Model <- Idle ------------ + // + // Idle is the start state. If we reach EOF outside of idle, + // the file is invalid. + + // Ref to the current model + BSim3Model model = new BSim3Model(temperature); + + String field = ""; + + while (state != BSIM_ERROR && + st.nextToken() != StreamTokenizer.TT_EOF) { + if (st.ttype != StreamTokenizer.TT_WORD) + continue; + + switch (state) { + case BSIM_IDLE: + if (st.sval.equals(".model")) + state = BSIM_MODEL; + break; + + // Find model name + case BSIM_MODEL: + // Model name is in st.sval but we don't care + models.add(model); + + state = BSIM_NAME; + break; + + // Find model type + case BSIM_NAME: + if (st.sval.equals("nmos")) { + model.type = NMOS; + } else if (st.sval.equals("pmos")) { + model.type = PMOS; + } else { + System.out.println("Invalid Model type: "+st.sval); + state = BSIM_ERROR; + break; + } + + state = BSIM_TYPE; + break; + + // Find data open '(' + case BSIM_TYPE: + if (st.sval.equals("(")) + state = BSIM_DATA; + else { + System.out.println("Found " + st.sval + " instead " + + "of expected '('"); + state = BSIM_ERROR; + } + break; + + // Find field name or ')' + case BSIM_DATA: + if (st.sval.equals(")")) { + // Cleanup old model + model.setDefaults(); + model.computeTemperatureData(); + + // Get to work on the new one + model = new BSim3Model(temperature); + state = BSIM_IDLE; + } else { + if (st.sval.startsWith("+")) { + field = st.sval.substring(1); + } else { + field = st.sval; + } + state = BSIM_FIELD; + } + + break; + + // Find field number value + case BSIM_FIELD: + model.set(field, st.sval); + state = BSIM_DATA; + break; + + // Error out just in case + default: + System.out.println("State machine in unknown state " + + state); + state = BSIM_ERROR; + case BSIM_ERROR: + break; + } + } + } catch (IOException e) { + System.out.println(e); + } finally { + try { + if (file != null) + file.close(); + } catch (IOException e) { + ; + } + } + } + + public BSim3Model(int type, double temperature) { + this.type = type; + this.temp = temperature + CONSTCtoK; + } + + public BSim3Model(double temperature) { + this.temp = temperature + CONSTCtoK; + } + + /** + * Finds a model given a type, width, and length + * @param type Type of model (NMOS or PMOS) + * @param width in meters + * @param length in meters + * @return BSim3Model if found, or null otherwise + **/ + public static BSim3Model findModel(int type, double W, double L) { + // Convert between normal typing and BSim's type multiplier-- + // -1 for PMOS where everything is inverted. + if (type == DeviceTypes.N_TYPE) { + type = NMOS; + } else if (type == DeviceTypes.P_TYPE) { + type = PMOS; + } + + for (Iterator i = models.iterator(); i.hasNext(); ) { + final BSim3Model m = (BSim3Model) i.next(); + if (type == m.type && L >= m.Lmin && L < m.Lmax + && W >= m.Wmin && W < m.Wmax) + return m; + } + + return null; + } + + public static final double EPSOX = 3.453133e-11; + public static final double EPSSI = 1.03594e-10; + public static final double CONSTCtoK = 273.15; + public static final double Charge_q = 1.60219e-19; + public static final double CONSTroot2 = 1.41421356237309504880; + public static final double CONSTboltz = 1.3806226e-23; + public static final double CONSTvt0 = CONSTboltz * (27 + CONSTCtoK ) / Charge_q; + public static final double KboQ = 8.617087e-5; /* Kb / q where q = 1.60219e-19 */ + +//GGG These may or may not be Double.MAX_VALUE and 1/Double.MAX_VALUE... + public static final double MAX_EXP = 5.834617425e14; + public static final double MIN_EXP = 1.713908431e-15; + public static final double EXP_THRESHOLD = 34.0; + + public static final double DELTA_1 = 0.02; + public static final double DELTA_2 = 0.02; + public static final double DELTA_3 = 0.02; + public static final double DELTA_4 = 0.02; + + public boolean given(double d) { return !Double.isNaN(d); } + public boolean given(int i) { return i != Integer.MIN_VALUE; } + public boolean given(String s) { return !s.equals(""); } + + public double temp = Double.NaN; + public double xl = Double.NaN; + public double xw = Double.NaN; + public double hdif = Double.NaN; + public double ldif = Double.NaN; + public double rs = Double.NaN; + public double rd = Double.NaN; + public int acm = Integer.MIN_VALUE; + public double cta = Double.NaN; + public double ctp = Double.NaN; + public double pta = Double.NaN; + public double ptp = Double.NaN; + public double n = Double.NaN; + public int nlev = Integer.MIN_VALUE; + public double tlev = Double.NaN; + public double tlevc = Double.NaN; + public double em = Double.NaN; + public double ef = Double.NaN; + public double af = Double.NaN; + public double kf = Double.NaN; + public int nqsMod = Integer.MIN_VALUE; + public int type = Integer.MIN_VALUE; + public int level = Integer.MIN_VALUE; + public int capMod = Integer.MIN_VALUE; + public int mobMod = Integer.MIN_VALUE; + public int noiMod = Integer.MIN_VALUE; + public int paramChk = Integer.MIN_VALUE; + public int binUnit = Integer.MIN_VALUE; + public String version = ""; + public double tox = Double.NaN; + public double toxm = Double.NaN; + public double cdsc = Double.NaN; + public double cdscb = Double.NaN; + public double cdscd = Double.NaN; + public double cit = Double.NaN; + public double nfactor = Double.NaN; + public double xj = Double.NaN; + public double vsat = Double.NaN; + public double at = Double.NaN; + public double a0 = Double.NaN; + public double ags = Double.NaN; + public double a1 = Double.NaN; + public double a2 = Double.NaN; + public double keta = Double.NaN; + public double nsub = Double.NaN; + public double npeak = Double.NaN; + public double ngate = Double.NaN; + public double gamma1 = Double.NaN; + public double gamma2 = Double.NaN; + public double vbx = Double.NaN; + public double vbm = Double.NaN; + public double xt = Double.NaN; + public double k1 = Double.NaN; + public double kt1 = Double.NaN; + public double kt1l = Double.NaN; + public double kt2 = Double.NaN; + public double k2 = Double.NaN; + public double k3 = Double.NaN; + public double k3b = Double.NaN; + public double w0 = Double.NaN; + public double nlx = Double.NaN; + public double dvt0 = Double.NaN; + public double dvt1 = Double.NaN; + public double dvt2 = Double.NaN; + public double dvt0w = Double.NaN; + public double dvt1w = Double.NaN; + public double dvt2w = Double.NaN; + public double drout = Double.NaN; + public double dsub = Double.NaN; + public double vth0 = Double.NaN; + public double ua = Double.NaN; + public double ua1 = Double.NaN; + public double ub = Double.NaN; + public double ub1 = Double.NaN; + public double uc = Double.NaN; + public double uc1 = Double.NaN; + public double u0 = Double.NaN; + public double ute = Double.NaN; + public double voff = Double.NaN; + public double delta = Double.NaN; + public double rdsw = Double.NaN; + public double prwg = Double.NaN; + public double prwb = Double.NaN; + public double prt = Double.NaN; + public double eta0 = Double.NaN; + public double etab = Double.NaN; + public double pclm = Double.NaN; + public double pdibl1 = Double.NaN; + public double pdibl2 = Double.NaN; + public double pdiblb = Double.NaN; + public double pscbe1 = Double.NaN; + public double pscbe2 = Double.NaN; + public double pvag = Double.NaN; + public double wr = Double.NaN; + public double dwg = Double.NaN; + public double dwb = Double.NaN; + public double b0 = Double.NaN; + public double b1 = Double.NaN; + public double alpha0 = Double.NaN; + public double alpha1 = Double.NaN; + public double beta0 = Double.NaN; + public double ijth = Double.NaN; + public double vfb = Double.NaN; + public double elm = Double.NaN; + public double cgsl = Double.NaN; + public double cgdl = Double.NaN; + public double ckappa = Double.NaN; + public double cf = Double.NaN; + public double vfbcv = Double.NaN; + public double clc = Double.NaN; + public double cle = Double.NaN; + public double dwc = Double.NaN; + public double dlc = Double.NaN; + public double noff = Double.NaN; + public double voffcv = Double.NaN; + public double acde = Double.NaN; + public double moin = Double.NaN; + public double tcj = Double.NaN; + public double tcjsw = Double.NaN; + public double tcjswg = Double.NaN; + public double tpb = Double.NaN; + public double tpbsw = Double.NaN; + public double tpbswg = Double.NaN; + public double tnom = Double.NaN; + public double cgso = Double.NaN; + public double cgdo = Double.NaN; + public double cgbo = Double.NaN; + public double xpart = Double.NaN; + public double sheetResistance = Double.NaN; + public double jctSatCurDensity = Double.NaN; + public double jctSidewallSatCurDensity = Double.NaN; + public double bulkJctPotential = Double.NaN; + public double bulkJctBotGradingCoeff = Double.NaN; + public double bulkJctSideGradingCoeff = Double.NaN; + public double bulkJctGateSideGradingCoeff = Double.NaN; + public double sidewallJctPotential = Double.NaN; + public double GatesidewallJctPotential = Double.NaN; + public double unitAreaJctCap = Double.NaN; + public double unitLengthSidewallJctCap = Double.NaN; + public double unitLengthGateSidewallJctCap = Double.NaN; + public double jctEmissionCoeff = Double.NaN; + public double jctTempExponent = Double.NaN; + public double Lint = Double.NaN; + public double Ll = Double.NaN; + public double Llc = Double.NaN; + public double Lln = Double.NaN; + public double Lw = Double.NaN; + public double Lwc = Double.NaN; + public double Lwn = Double.NaN; + public double Lwl = Double.NaN; + public double Lwlc = Double.NaN; + public double Lmin = Double.NaN; + public double Lmax = Double.NaN; + public double Wint = Double.NaN; + public double Wl = Double.NaN; + public double Wlc = Double.NaN; + public double Wln = Double.NaN; + public double Ww = Double.NaN; + public double Wwc = Double.NaN; + public double Wwn = Double.NaN; + public double Wwl = Double.NaN; + public double Wwlc = Double.NaN; + public double Wmin = Double.NaN; + public double Wmax = Double.NaN; + public double vtm = Double.NaN; + public double cox = Double.NaN; + public double cof1 = Double.NaN; + public double cof2 = Double.NaN; + public double cof3 = Double.NaN; + public double cof4 = Double.NaN; + public double vcrit = Double.NaN; + public double factor1 = Double.NaN; + public double PhiB = Double.NaN; + public double PhiBSW = Double.NaN; + public double PhiBSWG = Double.NaN; + public double jctTempSatCurDensity = Double.NaN; + public double jctSidewallTempSatCurDensity = Double.NaN; + public double oxideTrapDensityA = Double.NaN; + public double oxideTrapDensityB = Double.NaN; + public double oxideTrapDensityC = Double.NaN; + public double lcdsc = Double.NaN; + public double lcdscb = Double.NaN; + public double lcdscd = Double.NaN; + public double lcit = Double.NaN; + public double lnfactor = Double.NaN; + public double lxj = Double.NaN; + public double lvsat = Double.NaN; + public double lat = Double.NaN; + public double la0 = Double.NaN; + public double lags = Double.NaN; + public double la1 = Double.NaN; + public double la2 = Double.NaN; + public double lketa = Double.NaN; + public double lnsub = Double.NaN; + public double lnpeak = Double.NaN; + public double lngate = Double.NaN; + public double lgamma1 = Double.NaN; + public double lgamma2 = Double.NaN; + public double lvbx = Double.NaN; + public double lvbm = Double.NaN; + public double lxt = Double.NaN; + public double lk1 = Double.NaN; + public double lkt1 = Double.NaN; + public double lkt1l = Double.NaN; + public double lkt2 = Double.NaN; + public double lk2 = Double.NaN; + public double lk3 = Double.NaN; + public double lk3b = Double.NaN; + public double lw0 = Double.NaN; + public double lnlx = Double.NaN; + public double ldvt0 = Double.NaN; + public double ldvt1 = Double.NaN; + public double ldvt2 = Double.NaN; + public double ldvt0w = Double.NaN; + public double ldvt1w = Double.NaN; + public double ldvt2w = Double.NaN; + public double ldrout = Double.NaN; + public double ldsub = Double.NaN; + public double lvth0 = Double.NaN; + public double lua = Double.NaN; + public double lua1 = Double.NaN; + public double lub = Double.NaN; + public double lub1 = Double.NaN; + public double luc = Double.NaN; + public double luc1 = Double.NaN; + public double lu0 = Double.NaN; + public double lute = Double.NaN; + public double lvoff = Double.NaN; + public double ldelta = Double.NaN; + public double lrdsw = Double.NaN; + public double lprwg = Double.NaN; + public double lprwb = Double.NaN; + public double lprt = Double.NaN; + public double leta0 = Double.NaN; + public double letab = Double.NaN; + public double lpclm = Double.NaN; + public double lpdibl1 = Double.NaN; + public double lpdibl2 = Double.NaN; + public double lpdiblb = Double.NaN; + public double lpscbe1 = Double.NaN; + public double lpscbe2 = Double.NaN; + public double lpvag = Double.NaN; + public double lwr = Double.NaN; + public double ldwg = Double.NaN; + public double ldwb = Double.NaN; + public double lb0 = Double.NaN; + public double lb1 = Double.NaN; + public double lalpha0 = Double.NaN; + public double lalpha1 = Double.NaN; + public double lbeta0 = Double.NaN; + public double lvfb = Double.NaN; + public double lelm = Double.NaN; + public double lcgsl = Double.NaN; + public double lcgdl = Double.NaN; + public double lckappa = Double.NaN; + public double lcf = Double.NaN; + public double lclc = Double.NaN; + public double lcle = Double.NaN; + public double lvfbcv = Double.NaN; + public double lnoff = Double.NaN; + public double lvoffcv = Double.NaN; + public double lacde = Double.NaN; + public double lmoin = Double.NaN; + public double wcdsc = Double.NaN; + public double wcdscb = Double.NaN; + public double wcdscd = Double.NaN; + public double wcit = Double.NaN; + public double wnfactor = Double.NaN; + public double wxj = Double.NaN; + public double wvsat = Double.NaN; + public double wat = Double.NaN; + public double wa0 = Double.NaN; + public double wags = Double.NaN; + public double wa1 = Double.NaN; + public double wa2 = Double.NaN; + public double wketa = Double.NaN; + public double wnsub = Double.NaN; + public double wnpeak = Double.NaN; + public double wngate = Double.NaN; + public double wgamma1 = Double.NaN; + public double wgamma2 = Double.NaN; + public double wvbx = Double.NaN; + public double wvbm = Double.NaN; + public double wxt = Double.NaN; + public double wk1 = Double.NaN; + public double wkt1 = Double.NaN; + public double wkt1l = Double.NaN; + public double wkt2 = Double.NaN; + public double wk2 = Double.NaN; + public double wk3 = Double.NaN; + public double wk3b = Double.NaN; + public double ww0 = Double.NaN; + public double wnlx = Double.NaN; + public double wdvt0 = Double.NaN; + public double wdvt1 = Double.NaN; + public double wdvt2 = Double.NaN; + public double wdvt0w = Double.NaN; + public double wdvt1w = Double.NaN; + public double wdvt2w = Double.NaN; + public double wdrout = Double.NaN; + public double wdsub = Double.NaN; + public double wvth0 = Double.NaN; + public double wua = Double.NaN; + public double wua1 = Double.NaN; + public double wub = Double.NaN; + public double wub1 = Double.NaN; + public double wuc = Double.NaN; + public double wuc1 = Double.NaN; + public double wu0 = Double.NaN; + public double wute = Double.NaN; + public double wvoff = Double.NaN; + public double wdelta = Double.NaN; + public double wrdsw = Double.NaN; + public double wprwg = Double.NaN; + public double wprwb = Double.NaN; + public double wprt = Double.NaN; + public double weta0 = Double.NaN; + public double wetab = Double.NaN; + public double wpclm = Double.NaN; + public double wpdibl1 = Double.NaN; + public double wpdibl2 = Double.NaN; + public double wpdiblb = Double.NaN; + public double wpscbe1 = Double.NaN; + public double wpscbe2 = Double.NaN; + public double wpvag = Double.NaN; + public double wwr = Double.NaN; + public double wdwg = Double.NaN; + public double wdwb = Double.NaN; + public double wb0 = Double.NaN; + public double wb1 = Double.NaN; + public double walpha0 = Double.NaN; + public double walpha1 = Double.NaN; + public double wbeta0 = Double.NaN; + public double wvfb = Double.NaN; + public double welm = Double.NaN; + public double wcgsl = Double.NaN; + public double wcgdl = Double.NaN; + public double wckappa = Double.NaN; + public double wcf = Double.NaN; + public double wclc = Double.NaN; + public double wcle = Double.NaN; + public double wvfbcv = Double.NaN; + public double wnoff = Double.NaN; + public double wvoffcv = Double.NaN; + public double wacde = Double.NaN; + public double wmoin = Double.NaN; + public double pcdsc = Double.NaN; + public double pcdscb = Double.NaN; + public double pcdscd = Double.NaN; + public double pcit = Double.NaN; + public double pnfactor = Double.NaN; + public double pxj = Double.NaN; + public double pvsat = Double.NaN; + public double pat = Double.NaN; + public double pa0 = Double.NaN; + public double pags = Double.NaN; + public double pa1 = Double.NaN; + public double pa2 = Double.NaN; + public double pketa = Double.NaN; + public double pnsub = Double.NaN; + public double pnpeak = Double.NaN; + public double pngate = Double.NaN; + public double pgamma1 = Double.NaN; + public double pgamma2 = Double.NaN; + public double pvbx = Double.NaN; + public double pvbm = Double.NaN; + public double pxt = Double.NaN; + public double pk1 = Double.NaN; + public double pkt1 = Double.NaN; + public double pkt1l = Double.NaN; + public double pkt2 = Double.NaN; + public double pk2 = Double.NaN; + public double pk3 = Double.NaN; + public double pk3b = Double.NaN; + public double pw0 = Double.NaN; + public double pnlx = Double.NaN; + public double pdvt0 = Double.NaN; + public double pdvt1 = Double.NaN; + public double pdvt2 = Double.NaN; + public double pdvt0w = Double.NaN; + public double pdvt1w = Double.NaN; + public double pdvt2w = Double.NaN; + public double pdrout = Double.NaN; + public double pdsub = Double.NaN; + public double pvth0 = Double.NaN; + public double pua = Double.NaN; + public double pua1 = Double.NaN; + public double pub = Double.NaN; + public double pub1 = Double.NaN; + public double puc = Double.NaN; + public double puc1 = Double.NaN; + public double pu0 = Double.NaN; + public double pute = Double.NaN; + public double pvoff = Double.NaN; + public double pdelta = Double.NaN; + public double prdsw = Double.NaN; + public double pprwg = Double.NaN; + public double pprwb = Double.NaN; + public double pprt = Double.NaN; + public double peta0 = Double.NaN; + public double petab = Double.NaN; + public double ppclm = Double.NaN; + public double ppdibl1 = Double.NaN; + public double ppdibl2 = Double.NaN; + public double ppdiblb = Double.NaN; + public double ppscbe1 = Double.NaN; + public double ppscbe2 = Double.NaN; + public double ppvag = Double.NaN; + public double pwr = Double.NaN; + public double pdwg = Double.NaN; + public double pdwb = Double.NaN; + public double pb0 = Double.NaN; + public double pb1 = Double.NaN; + public double palpha0 = Double.NaN; + public double palpha1 = Double.NaN; + public double pbeta0 = Double.NaN; + public double pvfb = Double.NaN; + public double pelm = Double.NaN; + public double pcgsl = Double.NaN; + public double pcgdl = Double.NaN; + public double pckappa = Double.NaN; + public double pcf = Double.NaN; + public double pclc = Double.NaN; + public double pcle = Double.NaN; + public double pvfbcv = Double.NaN; + public double pnoff = Double.NaN; + public double pvoffcv = Double.NaN; + public double pacde = Double.NaN; + public double pmoin = Double.NaN; + +//GGG It's cleaner to use a hash table corrolating file identifier with +// class variable name which delimits only differences. We would use +// the reflection api to set values and we'd only have 50-75 lines of +// exceptions. I don't think it's worth rewriting the code though. + public void set(String field, String value) { + try { + if (field.equals("xl")) xl = Double.parseDouble(value); + else if (field.equals("xw")) xw = Double.parseDouble(value); + else if (field.equals("hdif")) hdif = Double.parseDouble(value); + else if (field.equals("ldif")) ldif = Double.parseDouble(value); + else if (field.equals("rs")) rs = Double.parseDouble(value); + else if (field.equals("rd")) rd = Double.parseDouble(value); + else if (field.equals("acm")) acm = Integer.parseInt(value); + else if (field.equals("cta")) cta = Double.parseDouble(value); + else if (field.equals("ctp")) ctp = Double.parseDouble(value); + else if (field.equals("pta")) pta = Double.parseDouble(value); + else if (field.equals("ptp")) ptp = Double.parseDouble(value); + else if (field.equals("n")) n = Double.parseDouble(value); + else if (field.equals("nlev")) nlev = Integer.parseInt(value); + else if (field.equals("tlev")) tlev = Double.parseDouble(value); + else if (field.equals("tlevc")) tlevc = Double.parseDouble(value); + else if (field.equals("em")) em = Double.parseDouble(value); + else if (field.equals("ef")) ef = Double.parseDouble(value); + else if (field.equals("af")) af = Double.parseDouble(value); + else if (field.equals("kf")) kf = Double.parseDouble(value); + else if (field.equals("nqsmod")) nqsMod = Integer.parseInt(value); + else if (field.equals("level")) level = Integer.parseInt(value); + else if (field.equals("capmod")) capMod = Integer.parseInt(value); + else if (field.equals("mobmod")) mobMod = Integer.parseInt(value); + else if (field.equals("noimod")) noiMod = Integer.parseInt(value); + else if (field.equals("paramchk")) paramChk = Integer.parseInt(value); + else if (field.equals("binunit")) binUnit = Integer.parseInt(value); + else if (field.equals("version")) version = value; + else if (field.equals("tox")) tox = Double.parseDouble(value); + else if (field.equals("toxm")) toxm = Double.parseDouble(value); + else if (field.equals("cdsc")) cdsc = Double.parseDouble(value); + else if (field.equals("cdscb")) cdscb = Double.parseDouble(value); + else if (field.equals("cdscd")) cdscd = Double.parseDouble(value); + else if (field.equals("cit")) cit = Double.parseDouble(value); + else if (field.equals("nfactor")) nfactor = Double.parseDouble(value); + else if (field.equals("xj")) xj = Double.parseDouble(value); + else if (field.equals("vsat")) vsat = Double.parseDouble(value); + else if (field.equals("at")) at = Double.parseDouble(value); + else if (field.equals("a0")) a0 = Double.parseDouble(value); + else if (field.equals("ags")) ags = Double.parseDouble(value); + else if (field.equals("a1")) a1 = Double.parseDouble(value); + else if (field.equals("a2")) a2 = Double.parseDouble(value); + else if (field.equals("keta")) keta = Double.parseDouble(value); + else if (field.equals("nsub")) nsub = Double.parseDouble(value); + else if (field.equals("nch")) npeak = Double.parseDouble(value); + else if (field.equals("ngate")) ngate = Double.parseDouble(value); + else if (field.equals("gamma1")) gamma1 = Double.parseDouble(value); + else if (field.equals("gamma2")) gamma2 = Double.parseDouble(value); + else if (field.equals("vbx")) vbx = Double.parseDouble(value); + else if (field.equals("vbm")) vbm = Double.parseDouble(value); + else if (field.equals("xt")) xt = Double.parseDouble(value); + else if (field.equals("k1")) k1 = Double.parseDouble(value); + else if (field.equals("kt1")) kt1 = Double.parseDouble(value); + else if (field.equals("kt1l")) kt1l = Double.parseDouble(value); + else if (field.equals("kt2")) kt2 = Double.parseDouble(value); + else if (field.equals("k2")) k2 = Double.parseDouble(value); + else if (field.equals("k3")) k3 = Double.parseDouble(value); + else if (field.equals("k3b")) k3b = Double.parseDouble(value); + else if (field.equals("w0")) w0 = Double.parseDouble(value); + else if (field.equals("nlx")) nlx = Double.parseDouble(value); + else if (field.equals("dvt0")) dvt0 = Double.parseDouble(value); + else if (field.equals("dvt1")) dvt1 = Double.parseDouble(value); + else if (field.equals("dvt2")) dvt2 = Double.parseDouble(value); + else if (field.equals("dvt0w")) dvt0w = Double.parseDouble(value); + else if (field.equals("dvt1w")) dvt1w = Double.parseDouble(value); + else if (field.equals("dvt2w")) dvt2w = Double.parseDouble(value); + else if (field.equals("drout")) drout = Double.parseDouble(value); + else if (field.equals("dsub")) dsub = Double.parseDouble(value); + else if (field.equals("vth0")) vth0 = Double.parseDouble(value); + else if (field.equals("ua")) ua = Double.parseDouble(value); + else if (field.equals("ua1")) ua1 = Double.parseDouble(value); + else if (field.equals("ub")) ub = Double.parseDouble(value); + else if (field.equals("ub1")) ub1 = Double.parseDouble(value); + else if (field.equals("uc")) uc = Double.parseDouble(value); + else if (field.equals("uc1")) uc1 = Double.parseDouble(value); + else if (field.equals("u0")) u0 = Double.parseDouble(value); + else if (field.equals("ute")) ute = Double.parseDouble(value); + else if (field.equals("voff")) voff = Double.parseDouble(value); + else if (field.equals("delta")) delta = Double.parseDouble(value); + else if (field.equals("rdsw")) rdsw = Double.parseDouble(value); + else if (field.equals("prwg")) prwg = Double.parseDouble(value); + else if (field.equals("prwb")) prwb = Double.parseDouble(value); + else if (field.equals("prt")) prt = Double.parseDouble(value); + else if (field.equals("eta0")) eta0 = Double.parseDouble(value); + else if (field.equals("etab")) etab = Double.parseDouble(value); + else if (field.equals("pclm")) pclm = Double.parseDouble(value); + else if (field.equals("pdiblc1")) pdibl1 = Double.parseDouble(value); + else if (field.equals("pdiblc2")) pdibl2 = Double.parseDouble(value); + else if (field.equals("pdiblcb")) pdiblb = Double.parseDouble(value); + else if (field.equals("pscbe1")) pscbe1 = Double.parseDouble(value); + else if (field.equals("pscbe2")) pscbe2 = Double.parseDouble(value); + else if (field.equals("pvag")) pvag = Double.parseDouble(value); + else if (field.equals("wr")) wr = Double.parseDouble(value); + else if (field.equals("dwg")) dwg = Double.parseDouble(value); + else if (field.equals("dwb")) dwb = Double.parseDouble(value); + else if (field.equals("b0")) b0 = Double.parseDouble(value); + else if (field.equals("b1")) b1 = Double.parseDouble(value); + else if (field.equals("alpha0")) alpha0 = Double.parseDouble(value); + else if (field.equals("alpha1")) alpha1 = Double.parseDouble(value); + else if (field.equals("beta0")) beta0 = Double.parseDouble(value); + else if (field.equals("ijth")) ijth = Double.parseDouble(value); + else if (field.equals("vfb")) vfb = Double.parseDouble(value); + else if (field.equals("elm")) elm = Double.parseDouble(value); + else if (field.equals("cgsl")) cgsl = Double.parseDouble(value); + else if (field.equals("cgdl")) cgdl = Double.parseDouble(value); + else if (field.equals("ckappa")) ckappa = Double.parseDouble(value); + else if (field.equals("cf")) cf = Double.parseDouble(value); + else if (field.equals("vfbcv")) vfbcv = Double.parseDouble(value); + else if (field.equals("clc")) clc = Double.parseDouble(value); + else if (field.equals("cle")) cle = Double.parseDouble(value); + else if (field.equals("dwc")) dwc = Double.parseDouble(value); + else if (field.equals("dlc")) dlc = Double.parseDouble(value); + else if (field.equals("noff")) noff = Double.parseDouble(value); + else if (field.equals("voffcv")) voffcv = Double.parseDouble(value); + else if (field.equals("acde")) acde = Double.parseDouble(value); + else if (field.equals("moin")) moin = Double.parseDouble(value); + else if (field.equals("tcj")) tcj = Double.parseDouble(value); + else if (field.equals("tcjsw")) tcjsw = Double.parseDouble(value); + else if (field.equals("tcjswg")) tcjswg = Double.parseDouble(value); + else if (field.equals("tpb")) tpb = Double.parseDouble(value); + else if (field.equals("tpbsw")) tpbsw = Double.parseDouble(value); + else if (field.equals("tpbswg")) tpbswg = Double.parseDouble(value); + else if (field.equals("tnom")) tnom = Double.parseDouble(value); + else if (field.equals("cgso")) cgso = Double.parseDouble(value); + else if (field.equals("cgdo")) cgdo = Double.parseDouble(value); + else if (field.equals("cgbo")) cgbo = Double.parseDouble(value); + else if (field.equals("xpart")) xpart = Double.parseDouble(value); + else if (field.equals("rsh")) sheetResistance = Double.parseDouble(value); + else if (field.equals("js")) jctSatCurDensity = Double.parseDouble(value); + else if (field.equals("jsw")) jctSidewallSatCurDensity = Double.parseDouble(value); + else if (field.equals("pb")) bulkJctPotential = Double.parseDouble(value); + else if (field.equals("mj")) bulkJctBotGradingCoeff = Double.parseDouble(value); + else if (field.equals("mjsw")) bulkJctSideGradingCoeff = Double.parseDouble(value); + else if (field.equals("mjswg")) bulkJctGateSideGradingCoeff = Double.parseDouble(value); + else if (field.equals("pbsw")) sidewallJctPotential = Double.parseDouble(value); + else if (field.equals("pbswg")) GatesidewallJctPotential = Double.parseDouble(value); + else if (field.equals("cj")) unitAreaJctCap = Double.parseDouble(value); + else if (field.equals("cjsw")) unitLengthSidewallJctCap = Double.parseDouble(value); + else if (field.equals("cjswg")) unitLengthGateSidewallJctCap = Double.parseDouble(value); + else if (field.equals("nj")) jctEmissionCoeff = Double.parseDouble(value); + else if (field.equals("xti")) jctTempExponent = Double.parseDouble(value); + else if (field.equals("lint")) Lint = Double.parseDouble(value); + else if (field.equals("ll")) Ll = Double.parseDouble(value); + else if (field.equals("llc")) Llc = Double.parseDouble(value); + else if (field.equals("lln")) Lln = Double.parseDouble(value); + else if (field.equals("lw")) Lw = Double.parseDouble(value); + else if (field.equals("lwc")) Lwc = Double.parseDouble(value); + else if (field.equals("lwn")) Lwn = Double.parseDouble(value); + else if (field.equals("lwl")) Lwl = Double.parseDouble(value); + else if (field.equals("lwlc")) Lwlc = Double.parseDouble(value); + else if (field.equals("lmin")) Lmin = Double.parseDouble(value); + else if (field.equals("lmax")) Lmax = Double.parseDouble(value); + else if (field.equals("wint")) Wint = Double.parseDouble(value); + else if (field.equals("wl")) Wl = Double.parseDouble(value); + else if (field.equals("wlc")) Wlc = Double.parseDouble(value); + else if (field.equals("wln")) Wln = Double.parseDouble(value); + else if (field.equals("ww")) Ww = Double.parseDouble(value); + else if (field.equals("wwc")) Wwc = Double.parseDouble(value); + else if (field.equals("wwn")) Wwn = Double.parseDouble(value); + else if (field.equals("wwl")) Wwl = Double.parseDouble(value); + else if (field.equals("wwlc")) Wwlc = Double.parseDouble(value); + else if (field.equals("wmin")) Wmin = Double.parseDouble(value); + else if (field.equals("wmax")) Wmax = Double.parseDouble(value); + else if (field.equals("lcdsc")) lcdsc = Double.parseDouble(value); + else if (field.equals("lcdscb")) lcdscb = Double.parseDouble(value); + else if (field.equals("lcdscd")) lcdscd = Double.parseDouble(value); + else if (field.equals("lcit")) lcit = Double.parseDouble(value); + else if (field.equals("lnfactor")) lnfactor = Double.parseDouble(value); + else if (field.equals("lxj")) lxj = Double.parseDouble(value); + else if (field.equals("lvsat")) lvsat = Double.parseDouble(value); + else if (field.equals("lat")) lat = Double.parseDouble(value); + else if (field.equals("la0")) la0 = Double.parseDouble(value); + else if (field.equals("lags")) lags = Double.parseDouble(value); + else if (field.equals("la1")) la1 = Double.parseDouble(value); + else if (field.equals("la2")) la2 = Double.parseDouble(value); + else if (field.equals("lketa")) lketa = Double.parseDouble(value); + else if (field.equals("lnsub")) lnsub = Double.parseDouble(value); + else if (field.equals("lnch")) lnpeak = Double.parseDouble(value); + else if (field.equals("lngate")) lngate = Double.parseDouble(value); + else if (field.equals("lgamma1")) lgamma1 = Double.parseDouble(value); + else if (field.equals("lgamma2")) lgamma2 = Double.parseDouble(value); + else if (field.equals("lvbx")) lvbx = Double.parseDouble(value); + else if (field.equals("lvbm")) lvbm = Double.parseDouble(value); + else if (field.equals("lxt")) lxt = Double.parseDouble(value); + else if (field.equals("lk1")) lk1 = Double.parseDouble(value); + else if (field.equals("lkt1")) lkt1 = Double.parseDouble(value); + else if (field.equals("lkt1l")) lkt1l = Double.parseDouble(value); + else if (field.equals("lkt2")) lkt2 = Double.parseDouble(value); + else if (field.equals("lk2")) lk2 = Double.parseDouble(value); + else if (field.equals("lk3")) lk3 = Double.parseDouble(value); + else if (field.equals("lk3b")) lk3b = Double.parseDouble(value); + else if (field.equals("lw0")) lw0 = Double.parseDouble(value); + else if (field.equals("lnlx")) lnlx = Double.parseDouble(value); + else if (field.equals("ldvt0")) ldvt0 = Double.parseDouble(value); + else if (field.equals("ldvt1")) ldvt1 = Double.parseDouble(value); + else if (field.equals("ldvt2")) ldvt2 = Double.parseDouble(value); + else if (field.equals("ldvt0w")) ldvt0w = Double.parseDouble(value); + else if (field.equals("ldvt1w")) ldvt1w = Double.parseDouble(value); + else if (field.equals("ldvt2w")) ldvt2w = Double.parseDouble(value); + else if (field.equals("ldrout")) ldrout = Double.parseDouble(value); + else if (field.equals("ldsub")) ldsub = Double.parseDouble(value); + else if (field.equals("lvth0")) lvth0 = Double.parseDouble(value); + else if (field.equals("lua")) lua = Double.parseDouble(value); + else if (field.equals("lua1")) lua1 = Double.parseDouble(value); + else if (field.equals("lub")) lub = Double.parseDouble(value); + else if (field.equals("lub1")) lub1 = Double.parseDouble(value); + else if (field.equals("luc")) luc = Double.parseDouble(value); + else if (field.equals("luc1")) luc1 = Double.parseDouble(value); + else if (field.equals("lu0")) lu0 = Double.parseDouble(value); + else if (field.equals("lute")) lute = Double.parseDouble(value); + else if (field.equals("lvoff")) lvoff = Double.parseDouble(value); + else if (field.equals("ldelta")) ldelta = Double.parseDouble(value); + else if (field.equals("lrdsw")) lrdsw = Double.parseDouble(value); + else if (field.equals("lprwg")) lprwg = Double.parseDouble(value); + else if (field.equals("lprwb")) lprwb = Double.parseDouble(value); + else if (field.equals("lprt")) lprt = Double.parseDouble(value); + else if (field.equals("leta0")) leta0 = Double.parseDouble(value); + else if (field.equals("letab")) letab = Double.parseDouble(value); + else if (field.equals("lpclm")) lpclm = Double.parseDouble(value); + else if (field.equals("lpdiblc1")) lpdibl1 = Double.parseDouble(value); + else if (field.equals("lpdiblc2")) lpdibl2 = Double.parseDouble(value); + else if (field.equals("lpdiblcb")) lpdiblb = Double.parseDouble(value); + else if (field.equals("lpscbe1")) lpscbe1 = Double.parseDouble(value); + else if (field.equals("lpscbe2")) lpscbe2 = Double.parseDouble(value); + else if (field.equals("lpvag")) lpvag = Double.parseDouble(value); + else if (field.equals("lwr")) lwr = Double.parseDouble(value); + else if (field.equals("ldwg")) ldwg = Double.parseDouble(value); + else if (field.equals("ldwb")) ldwb = Double.parseDouble(value); + else if (field.equals("lb0")) lb0 = Double.parseDouble(value); + else if (field.equals("lb1")) lb1 = Double.parseDouble(value); + else if (field.equals("lalpha0")) lalpha0 = Double.parseDouble(value); + else if (field.equals("lalpha1")) lalpha1 = Double.parseDouble(value); + else if (field.equals("lbeta0")) lbeta0 = Double.parseDouble(value); + else if (field.equals("lvfb")) lvfb = Double.parseDouble(value); + else if (field.equals("lelm")) lelm = Double.parseDouble(value); + else if (field.equals("lcgsl")) lcgsl = Double.parseDouble(value); + else if (field.equals("lcgdl")) lcgdl = Double.parseDouble(value); + else if (field.equals("lckappa")) lckappa = Double.parseDouble(value); + else if (field.equals("lcg")) lcf = Double.parseDouble(value); + else if (field.equals("lclc")) lclc = Double.parseDouble(value); + else if (field.equals("lcle")) lcle = Double.parseDouble(value); + else if (field.equals("lvfbcv")) lvfbcv = Double.parseDouble(value); + else if (field.equals("lnoff")) lnoff = Double.parseDouble(value); + else if (field.equals("lvoffcv")) lvoffcv = Double.parseDouble(value); + else if (field.equals("lacde")) lacde = Double.parseDouble(value); + else if (field.equals("lmoin")) lmoin = Double.parseDouble(value); + else if (field.equals("wcdsc")) wcdsc = Double.parseDouble(value); + else if (field.equals("wcdscb")) wcdscb = Double.parseDouble(value); + else if (field.equals("wcdscd")) wcdscd = Double.parseDouble(value); + else if (field.equals("wcit")) wcit = Double.parseDouble(value); + else if (field.equals("wnfactor")) wnfactor = Double.parseDouble(value); + else if (field.equals("wxj")) wxj = Double.parseDouble(value); + else if (field.equals("wvsat")) wvsat = Double.parseDouble(value); + else if (field.equals("wat")) wat = Double.parseDouble(value); + else if (field.equals("wa0")) wa0 = Double.parseDouble(value); + else if (field.equals("wags")) wags = Double.parseDouble(value); + else if (field.equals("wa1")) wa1 = Double.parseDouble(value); + else if (field.equals("wa2")) wa2 = Double.parseDouble(value); + else if (field.equals("wketa")) wketa = Double.parseDouble(value); + else if (field.equals("wnsub")) wnsub = Double.parseDouble(value); + else if (field.equals("wnch")) wnpeak = Double.parseDouble(value); + else if (field.equals("wngate")) wngate = Double.parseDouble(value); + else if (field.equals("wgamma1")) wgamma1 = Double.parseDouble(value); + else if (field.equals("wgamma2")) wgamma2 = Double.parseDouble(value); + else if (field.equals("wvbx")) wvbx = Double.parseDouble(value); + else if (field.equals("wvbm")) wvbm = Double.parseDouble(value); + else if (field.equals("wxt")) wxt = Double.parseDouble(value); + else if (field.equals("wk1")) wk1 = Double.parseDouble(value); + else if (field.equals("wkt1")) wkt1 = Double.parseDouble(value); + else if (field.equals("wkt1l")) wkt1l = Double.parseDouble(value); + else if (field.equals("wkt2")) wkt2 = Double.parseDouble(value); + else if (field.equals("wk2")) wk2 = Double.parseDouble(value); + else if (field.equals("wk3")) wk3 = Double.parseDouble(value); + else if (field.equals("wk3b")) wk3b = Double.parseDouble(value); + else if (field.equals("ww0")) ww0 = Double.parseDouble(value); + else if (field.equals("wnlx")) wnlx = Double.parseDouble(value); + else if (field.equals("wdvt0")) wdvt0 = Double.parseDouble(value); + else if (field.equals("wdvt1")) wdvt1 = Double.parseDouble(value); + else if (field.equals("wdvt2")) wdvt2 = Double.parseDouble(value); + else if (field.equals("wdvt0w")) wdvt0w = Double.parseDouble(value); + else if (field.equals("wdvt1w")) wdvt1w = Double.parseDouble(value); + else if (field.equals("wdvt2w")) wdvt2w = Double.parseDouble(value); + else if (field.equals("wdrout")) wdrout = Double.parseDouble(value); + else if (field.equals("wdsub")) wdsub = Double.parseDouble(value); + else if (field.equals("wvth0")) wvth0 = Double.parseDouble(value); + else if (field.equals("wua")) wua = Double.parseDouble(value); + else if (field.equals("wua1")) wua1 = Double.parseDouble(value); + else if (field.equals("wub")) wub = Double.parseDouble(value); + else if (field.equals("wub1")) wub1 = Double.parseDouble(value); + else if (field.equals("wuc")) wuc = Double.parseDouble(value); + else if (field.equals("wuc1")) wuc1 = Double.parseDouble(value); + else if (field.equals("wu0")) wu0 = Double.parseDouble(value); + else if (field.equals("wute")) wute = Double.parseDouble(value); + else if (field.equals("wvoff")) wvoff = Double.parseDouble(value); + else if (field.equals("wdelta")) wdelta = Double.parseDouble(value); + else if (field.equals("wrdsw")) wrdsw = Double.parseDouble(value); + else if (field.equals("wprwg")) wprwg = Double.parseDouble(value); + else if (field.equals("wprwb")) wprwb = Double.parseDouble(value); + else if (field.equals("wprt")) wprt = Double.parseDouble(value); + else if (field.equals("weta0")) weta0 = Double.parseDouble(value); + else if (field.equals("wetab")) wetab = Double.parseDouble(value); + else if (field.equals("wpclm")) wpclm = Double.parseDouble(value); + else if (field.equals("wpdiblc1")) wpdibl1 = Double.parseDouble(value); + else if (field.equals("wpdiblc2")) wpdibl2 = Double.parseDouble(value); + else if (field.equals("wpdiblcb")) wpdiblb = Double.parseDouble(value); + else if (field.equals("wpscbe1")) wpscbe1 = Double.parseDouble(value); + else if (field.equals("wpscbe2")) wpscbe2 = Double.parseDouble(value); + else if (field.equals("wpvag")) wpvag = Double.parseDouble(value); + else if (field.equals("wwr")) wwr = Double.parseDouble(value); + else if (field.equals("wdwg")) wdwg = Double.parseDouble(value); + else if (field.equals("wdwb")) wdwb = Double.parseDouble(value); + else if (field.equals("wb0")) wb0 = Double.parseDouble(value); + else if (field.equals("wb1")) wb1 = Double.parseDouble(value); + else if (field.equals("walpha0")) walpha0 = Double.parseDouble(value); + else if (field.equals("walpha1")) walpha1 = Double.parseDouble(value); + else if (field.equals("wbeta0")) wbeta0 = Double.parseDouble(value); + else if (field.equals("wvfb")) wvfb = Double.parseDouble(value); + else if (field.equals("welm")) welm = Double.parseDouble(value); + else if (field.equals("wcgsl")) wcgsl = Double.parseDouble(value); + else if (field.equals("wcgdl")) wcgdl = Double.parseDouble(value); + else if (field.equals("wckappa")) wckappa = Double.parseDouble(value); + else if (field.equals("wcg")) wcf = Double.parseDouble(value); + else if (field.equals("wclc")) wclc = Double.parseDouble(value); + else if (field.equals("wcle")) wcle = Double.parseDouble(value); + else if (field.equals("wvfbcv")) wvfbcv = Double.parseDouble(value); + else if (field.equals("wnoff")) wnoff = Double.parseDouble(value); + else if (field.equals("wvoffcv")) wvoffcv = Double.parseDouble(value); + else if (field.equals("wacde")) wacde = Double.parseDouble(value); + else if (field.equals("wmoin")) wmoin = Double.parseDouble(value); + else if (field.equals("pcdsc")) pcdsc = Double.parseDouble(value); + else if (field.equals("pcdscb")) pcdscb = Double.parseDouble(value); + else if (field.equals("pcdscd")) pcdscd = Double.parseDouble(value); + else if (field.equals("pcit")) pcit = Double.parseDouble(value); + else if (field.equals("pnfactor")) pnfactor = Double.parseDouble(value); + else if (field.equals("pxj")) pxj = Double.parseDouble(value); + else if (field.equals("pvsat")) pvsat = Double.parseDouble(value); + else if (field.equals("pat")) pat = Double.parseDouble(value); + else if (field.equals("pa0")) pa0 = Double.parseDouble(value); + else if (field.equals("pags")) pags = Double.parseDouble(value); + else if (field.equals("pa1")) pa1 = Double.parseDouble(value); + else if (field.equals("pa2")) pa2 = Double.parseDouble(value); + else if (field.equals("pketa")) pketa = Double.parseDouble(value); + else if (field.equals("pnsub")) pnsub = Double.parseDouble(value); + else if (field.equals("pnch")) pnpeak = Double.parseDouble(value); + else if (field.equals("pngate")) pngate = Double.parseDouble(value); + else if (field.equals("pgamma1")) pgamma1 = Double.parseDouble(value); + else if (field.equals("pgamma2")) pgamma2 = Double.parseDouble(value); + else if (field.equals("pvbx")) pvbx = Double.parseDouble(value); + else if (field.equals("pvbm")) pvbm = Double.parseDouble(value); + else if (field.equals("pxt")) pxt = Double.parseDouble(value); + else if (field.equals("pk1")) pk1 = Double.parseDouble(value); + else if (field.equals("pkt1")) pkt1 = Double.parseDouble(value); + else if (field.equals("pkt1l")) pkt1l = Double.parseDouble(value); + else if (field.equals("pkt2")) pkt2 = Double.parseDouble(value); + else if (field.equals("pk2")) pk2 = Double.parseDouble(value); + else if (field.equals("pk3")) pk3 = Double.parseDouble(value); + else if (field.equals("pk3b")) pk3b = Double.parseDouble(value); + else if (field.equals("pw0")) pw0 = Double.parseDouble(value); + else if (field.equals("pnlx")) pnlx = Double.parseDouble(value); + else if (field.equals("pdvt0")) pdvt0 = Double.parseDouble(value); + else if (field.equals("pdvt1")) pdvt1 = Double.parseDouble(value); + else if (field.equals("pdvt2")) pdvt2 = Double.parseDouble(value); + else if (field.equals("pdvt0w")) pdvt0w = Double.parseDouble(value); + else if (field.equals("pdvt1w")) pdvt1w = Double.parseDouble(value); + else if (field.equals("pdvt2w")) pdvt2w = Double.parseDouble(value); + else if (field.equals("pdrout")) pdrout = Double.parseDouble(value); + else if (field.equals("pdsub")) pdsub = Double.parseDouble(value); + else if (field.equals("pvth0")) pvth0 = Double.parseDouble(value); + else if (field.equals("pua")) pua = Double.parseDouble(value); + else if (field.equals("pua1")) pua1 = Double.parseDouble(value); + else if (field.equals("pub")) pub = Double.parseDouble(value); + else if (field.equals("pub1")) pub1 = Double.parseDouble(value); + else if (field.equals("puc")) puc = Double.parseDouble(value); + else if (field.equals("puc1")) puc1 = Double.parseDouble(value); + else if (field.equals("pu0")) pu0 = Double.parseDouble(value); + else if (field.equals("pute")) pute = Double.parseDouble(value); + else if (field.equals("pvoff")) pvoff = Double.parseDouble(value); + else if (field.equals("pdelta")) pdelta = Double.parseDouble(value); + else if (field.equals("prdsw")) prdsw = Double.parseDouble(value); + else if (field.equals("pprwg")) pprwg = Double.parseDouble(value); + else if (field.equals("pprwb")) pprwb = Double.parseDouble(value); + else if (field.equals("pprt")) pprt = Double.parseDouble(value); + else if (field.equals("peta0")) peta0 = Double.parseDouble(value); + else if (field.equals("petab")) petab = Double.parseDouble(value); + else if (field.equals("ppclm")) ppclm = Double.parseDouble(value); + else if (field.equals("ppdiblc1")) ppdibl1 = Double.parseDouble(value); + else if (field.equals("ppdiblc2")) ppdibl2 = Double.parseDouble(value); + else if (field.equals("ppdiblcb")) ppdiblb = Double.parseDouble(value); + else if (field.equals("ppscbe1")) ppscbe1 = Double.parseDouble(value); + else if (field.equals("ppscbe2")) ppscbe2 = Double.parseDouble(value); + else if (field.equals("ppvag")) ppvag = Double.parseDouble(value); + else if (field.equals("pwr")) pwr = Double.parseDouble(value); + else if (field.equals("pdwg")) pdwg = Double.parseDouble(value); + else if (field.equals("pdwb")) pdwb = Double.parseDouble(value); + else if (field.equals("pb0")) pb0 = Double.parseDouble(value); + else if (field.equals("pb1")) pb1 = Double.parseDouble(value); + else if (field.equals("palpha0")) palpha0 = Double.parseDouble(value); + else if (field.equals("palpha1")) palpha1 = Double.parseDouble(value); + else if (field.equals("pbeta0")) pbeta0 = Double.parseDouble(value); + else if (field.equals("pvfb")) pvfb = Double.parseDouble(value); + else if (field.equals("pelm")) pelm = Double.parseDouble(value); + else if (field.equals("pcgsl")) pcgsl = Double.parseDouble(value); + else if (field.equals("pcgdl")) pcgdl = Double.parseDouble(value); + else if (field.equals("pckappa")) pckappa = Double.parseDouble(value); + else if (field.equals("pcg")) pcf = Double.parseDouble(value); + else if (field.equals("pclc")) pclc = Double.parseDouble(value); + else if (field.equals("pcle")) pcle = Double.parseDouble(value); + else if (field.equals("pvfbcv")) pvfbcv = Double.parseDouble(value); + else if (field.equals("pnoff")) pnoff = Double.parseDouble(value); + else if (field.equals("pvoffcv")) pvoffcv = Double.parseDouble(value); + else if (field.equals("pacde")) pacde = Double.parseDouble(value); + else if (field.equals("pmoin")) pmoin = Double.parseDouble(value); + } catch (NumberFormatException e) { + System.out.println(value + " is not a number"); + } + } + + void setDefaults() { + if (!given(type)) type = NMOS; + if (!given(mobMod)) mobMod = 1; + if (!given(binUnit)) binUnit = 1; + if (!given(paramChk)) paramChk = 0; + if (!given(capMod)) capMod = 3; + if (!given(noiMod)) noiMod = 1; + if (!given(nqsMod)) nqsMod = 0; + if (!given(version)) version = "3.2.2"; + if (!given(tox)) tox = 150.0e-10; + cox = 3.453133e-11 / tox; + if (!given(toxm)) toxm = tox; + + if (!given(cdsc)) cdsc = 2.4e-4; /* unit Q/V/m^2 */ + if (!given(cdscb)) cdscb = 0.0; /* unit Q/V/m^2 */ + if (!given(cdscd)) cdscd = 0.0; /* unit Q/V/m^2 */ + if (!given(cit)) cit = 0.0; /* unit Q/V/m^2 */ + if (!given(nfactor)) nfactor = 1; + if (!given(xj)) xj = .15e-6; + if (!given(vsat)) vsat = 8.0e4; /* unit m/s */ + if (!given(at)) at = 3.3e4; /* unit m/s */ + if (!given(a0)) a0 = 1.0; + if (!given(ags)) ags = 0.0; + if (!given(a1)) a1 = 0.0; + if (!given(a2)) a2 = 1.0; + if (!given(keta)) keta = -0.047; /* unit / V */ + if (!given(nsub) && !given(k1) && !given(k2)) nsub = 6.0e16; /* unit 1/cm3 */ + if (!given(npeak)) npeak = 1.7e17; /* unit 1/cm3 */ + if (!given(ngate)) ngate = 0; /* unit 1/cm3 */ + if (!given(vbm)) vbm = -3.0; + if (!given(xt) && !given(k1) && !given(k2)) xt = 1.55e-7; + if (!given(kt1)) kt1 = -0.11; /* unit V */ + if (!given(kt1l)) kt1l = 0.0; /* unit V*m */ + if (!given(kt2)) kt2 = 0.022; /* No unit */ + if (!given(k3)) k3 = 80.0; + if (!given(k3b)) k3b = 0.0; + if (!given(w0)) w0 = 2.5e-6; + if (!given(nlx)) nlx = 1.74e-7; + if (!given(dvt0)) dvt0 = 2.2; + if (!given(dvt1)) dvt1 = 0.53; + if (!given(dvt2)) dvt2 = -0.032; /* unit 1 / V */ + + if (!given(dvt0w)) dvt0w = 0.0; + if (!given(dvt1w)) dvt1w = 5.3e6; + if (!given(dvt2w)) dvt2w = -0.032; + + if (!given(drout)) drout = 0.56; + if (!given(dsub)) dsub = drout; + if (!given(vth0)) vth0 = (type == NMOS) ? 0.7 : -0.7; + if (!given(ua)) ua = 2.25e-9; /* unit m/V */ + if (!given(ua1)) ua1 = 4.31e-9; /* unit m/V */ + if (!given(ub)) ub = 5.87e-19; /* unit (m/V)**2 */ + if (!given(ub1)) ub1 = -7.61e-18; /* unit (m/V)**2 */ + if (!given(uc)) uc = (mobMod == 3) ? -0.0465 : -0.0465e-9; + if (!given(uc1)) uc1 = (mobMod == 3) ? -0.056 : -0.056e-9; + if (!given(u0)) u0 = (type == NMOS) ? 0.067 : 0.025; + if (!given(ute)) ute = -1.5; + if (!given(voff)) voff = -0.08; + if (!given(delta)) delta = 0.01; + if (!given(rdsw)) rdsw = 0; + if (!given(prwg)) prwg = 0.0; /* unit 1/V */ + if (!given(prwb)) prwb = 0.0; + if (!given(prt)) prt = 0.0; + if (!given(eta0)) eta0 = 0.08; /* no unit */ + if (!given(etab)) etab = -0.07; /* unit 1/V */ + if (!given(pclm)) pclm = 1.3; /* no unit */ + if (!given(pdibl1)) pdibl1 = .39; /* no unit */ + if (!given(pdibl2)) pdibl2 = 0.0086; /* no unit */ + if (!given(pdiblb)) pdiblb = 0.0; /* 1/V */ + if (!given(pscbe1)) pscbe1 = 4.24e8; + if (!given(pscbe2)) pscbe2 = 1.0e-5; + if (!given(pvag)) pvag = 0.0; + if (!given(wr)) wr = 1.0; + if (!given(dwg)) dwg = 0.0; + if (!given(dwb)) dwb = 0.0; + if (!given(b0)) b0 = 0.0; + if (!given(b1)) b1 = 0.0; + if (!given(alpha0)) alpha0 = 0.0; + if (!given(alpha1)) alpha1 = 0.0; + if (!given(beta0)) beta0 = 30.0; + if (!given(ijth)) ijth = 0.1; /* unit A */ + + if (!given(elm)) elm = 5.0; + if (!given(cgsl)) cgsl = 0.0; + if (!given(cgdl)) cgdl = 0.0; + if (!given(ckappa)) ckappa = 0.6; + if (!given(clc)) clc = 0.1e-6; + if (!given(cle)) cle = 0.6; + if (!given(vfbcv)) vfbcv = -1.0; + if (!given(acde)) acde = 1.0; + if (!given(moin)) moin = 15.0; + if (!given(noff)) noff = 1.0; + if (!given(voffcv)) voffcv = 0.0; + if (!given(tcj)) tcj = 0.0; + if (!given(tpb)) tpb = 0.0; + if (!given(tcjsw)) tcjsw = 0.0; + if (!given(tpbsw)) tpbsw = 0.0; + if (!given(tcjswg)) tcjswg = 0.0; + if (!given(tpbswg)) tpbswg = 0.0; + + /* Length dependence */ + if (!given(lcdsc)) lcdsc = 0.0; + if (!given(lcdscb)) lcdscb = 0.0; + if (!given(lcdscd)) lcdscd = 0.0; + if (!given(lcit)) lcit = 0.0; + if (!given(lnfactor)) lnfactor = 0.0; + if (!given(lxj)) lxj = 0.0; + if (!given(lvsat)) lvsat = 0.0; + if (!given(lat)) lat = 0.0; + if (!given(la0)) la0 = 0.0; + if (!given(lags)) lags = 0.0; + if (!given(la1)) la1 = 0.0; + if (!given(la2)) la2 = 0.0; + if (!given(lketa)) lketa = 0.0; + if (!given(lnsub)) lnsub = 0.0; + if (!given(lnpeak)) lnpeak = 0.0; + if (!given(lngate)) lngate = 0.0; + if (!given(lvbm)) lvbm = 0.0; + if (!given(lxt)) lxt = 0.0; + if (!given(lkt1)) lkt1 = 0.0; + if (!given(lkt1l)) lkt1l = 0.0; + if (!given(lkt2)) lkt2 = 0.0; + if (!given(lk3)) lk3 = 0.0; + if (!given(lk3b)) lk3b = 0.0; + if (!given(lw0)) lw0 = 0.0; + if (!given(lnlx)) lnlx = 0.0; + if (!given(ldvt0)) ldvt0 = 0.0; + if (!given(ldvt1)) ldvt1 = 0.0; + if (!given(ldvt2)) ldvt2 = 0.0; + if (!given(ldvt0w)) ldvt0w = 0.0; + if (!given(ldvt1w)) ldvt1w = 0.0; + if (!given(ldvt2w)) ldvt2w = 0.0; + if (!given(ldrout)) ldrout = 0.0; + if (!given(ldsub)) ldsub = 0.0; + if (!given(lvth0)) lvth0 = 0.0; + if (!given(lua)) lua = 0.0; + if (!given(lua1)) lua1 = 0.0; + if (!given(lub)) lub = 0.0; + if (!given(lub1)) lub1 = 0.0; + if (!given(luc)) luc = 0.0; + if (!given(luc1)) luc1 = 0.0; + if (!given(lu0)) lu0 = 0.0; + if (!given(lute)) lute = 0.0; + if (!given(lvoff)) lvoff = 0.0; + if (!given(ldelta)) ldelta = 0.0; + if (!given(lrdsw)) lrdsw = 0.0; + if (!given(lprwb)) lprwb = 0.0; + if (!given(lprwg)) lprwg = 0.0; + if (!given(lprt)) lprt = 0.0; + if (!given(leta0)) leta0 = 0.0; + if (!given(letab)) letab = -0.0; + if (!given(lpclm)) lpclm = 0.0; + if (!given(lpdibl1)) lpdibl1 = 0.0; + if (!given(lpdibl2)) lpdibl2 = 0.0; + if (!given(lpdiblb)) lpdiblb = 0.0; + if (!given(lpscbe1)) lpscbe1 = 0.0; + if (!given(lpscbe2)) lpscbe2 = 0.0; + if (!given(lpvag)) lpvag = 0.0; + if (!given(lwr)) lwr = 0.0; + if (!given(ldwg)) ldwg = 0.0; + if (!given(ldwb)) ldwb = 0.0; + if (!given(lb0)) lb0 = 0.0; + if (!given(lb1)) lb1 = 0.0; + if (!given(lalpha0)) lalpha0 = 0.0; + if (!given(lalpha1)) lalpha1 = 0.0; + if (!given(lbeta0)) lbeta0 = 0.0; + if (!given(lvfb)) lvfb = 0.0; + + if (!given(lelm)) lelm = 0.0; + if (!given(lcgsl)) lcgsl = 0.0; + if (!given(lcgdl)) lcgdl = 0.0; + if (!given(lckappa)) lckappa = 0.0; + if (!given(lclc)) lclc = 0.0; + if (!given(lcle)) lcle = 0.0; + if (!given(lcf)) lcf = 0.0; + if (!given(lvfbcv)) lvfbcv = 0.0; + if (!given(lacde)) lacde = 0.0; + if (!given(lmoin)) lmoin = 0.0; + if (!given(lnoff)) lnoff = 0.0; + if (!given(lvoffcv)) lvoffcv = 0.0; + + /* Width dependence */ + if (!given(wcdsc)) wcdsc = 0.0; + if (!given(wcdscb)) wcdscb = 0.0; + if (!given(wcdscd)) wcdscd = 0.0; + if (!given(wcit)) wcit = 0.0; + if (!given(wnfactor)) wnfactor = 0.0; + if (!given(wxj)) wxj = 0.0; + if (!given(wvsat)) wvsat = 0.0; + if (!given(wat)) wat = 0.0; + if (!given(wa0)) wa0 = 0.0; + if (!given(wags)) wags = 0.0; + if (!given(wa1)) wa1 = 0.0; + if (!given(wa2)) wa2 = 0.0; + if (!given(wketa)) wketa = 0.0; + if (!given(wnsub)) wnsub = 0.0; + if (!given(wnpeak)) wnpeak = 0.0; + if (!given(wngate)) wngate = 0.0; + if (!given(wvbm)) wvbm = 0.0; + if (!given(wxt)) wxt = 0.0; + if (!given(wkt1)) wkt1 = 0.0; + if (!given(wkt1l)) wkt1l = 0.0; + if (!given(wkt2)) wkt2 = 0.0; + if (!given(wk3)) wk3 = 0.0; + if (!given(wk3b)) wk3b = 0.0; + if (!given(ww0)) ww0 = 0.0; + if (!given(wnlx)) wnlx = 0.0; + if (!given(wdvt0)) wdvt0 = 0.0; + if (!given(wdvt1)) wdvt1 = 0.0; + if (!given(wdvt2)) wdvt2 = 0.0; + if (!given(wdvt0w)) wdvt0w = 0.0; + if (!given(wdvt1w)) wdvt1w = 0.0; + if (!given(wdvt2w)) wdvt2w = 0.0; + if (!given(wdrout)) wdrout = 0.0; + if (!given(wdsub)) wdsub = 0.0; + if (!given(wvth0)) wvth0 = 0.0; + if (!given(wua)) wua = 0.0; + if (!given(wua1)) wua1 = 0.0; + if (!given(wub)) wub = 0.0; + if (!given(wub1)) wub1 = 0.0; + if (!given(wuc)) wuc = 0.0; + if (!given(wuc1)) wuc1 = 0.0; + if (!given(wu0)) wu0 = 0.0; + if (!given(wute)) wute = 0.0; + if (!given(wvoff)) wvoff = 0.0; + if (!given(wdelta)) wdelta = 0.0; + if (!given(wrdsw)) wrdsw = 0.0; + if (!given(wprwb)) wprwb = 0.0; + if (!given(wprwg)) wprwg = 0.0; + if (!given(wprt)) wprt = 0.0; + if (!given(weta0)) weta0 = 0.0; + if (!given(wetab)) wetab = 0.0; + if (!given(wpclm)) wpclm = 0.0; + if (!given(wpdibl1)) wpdibl1 = 0.0; + if (!given(wpdibl2)) wpdibl2 = 0.0; + if (!given(wpdiblb)) wpdiblb = 0.0; + if (!given(wpscbe1)) wpscbe1 = 0.0; + if (!given(wpscbe2)) wpscbe2 = 0.0; + if (!given(wpvag)) wpvag = 0.0; + if (!given(wwr)) wwr = 0.0; + if (!given(wdwg)) wdwg = 0.0; + if (!given(wdwb)) wdwb = 0.0; + if (!given(wb0)) wb0 = 0.0; + if (!given(wb1)) wb1 = 0.0; + if (!given(walpha0)) walpha0 = 0.0; + if (!given(walpha1)) walpha1 = 0.0; + if (!given(wbeta0)) wbeta0 = 0.0; + if (!given(wvfb)) wvfb = 0.0; + + if (!given(welm)) welm = 0.0; + if (!given(wcgsl)) wcgsl = 0.0; + if (!given(wcgdl)) wcgdl = 0.0; + if (!given(wckappa)) wckappa = 0.0; + if (!given(wcf)) wcf = 0.0; + if (!given(wclc)) wclc = 0.0; + if (!given(wcle)) wcle = 0.0; + if (!given(wvfbcv)) wvfbcv = 0.0; + if (!given(wacde)) wacde = 0.0; + if (!given(wmoin)) wmoin = 0.0; + if (!given(wnoff)) wnoff = 0.0; + if (!given(wvoffcv)) wvoffcv = 0.0; + + /* Cross-term dependence */ + if (!given(pcdsc)) pcdsc = 0.0; + if (!given(pcdscb)) pcdscb = 0.0; + if (!given(pcdscd)) pcdscd = 0.0; + if (!given(pcit)) pcit = 0.0; + if (!given(pnfactor)) pnfactor = 0.0; + if (!given(pxj)) pxj = 0.0; + if (!given(pvsat)) pvsat = 0.0; + if (!given(pat)) pat = 0.0; + if (!given(pa0)) pa0 = 0.0; + + if (!given(pags)) pags = 0.0; + if (!given(pa1)) pa1 = 0.0; + if (!given(pa2)) pa2 = 0.0; + if (!given(pketa)) pketa = 0.0; + if (!given(pnsub)) pnsub = 0.0; + if (!given(pnpeak)) pnpeak = 0.0; + if (!given(pngate)) pngate = 0.0; + if (!given(pvbm)) pvbm = 0.0; + if (!given(pxt)) pxt = 0.0; + if (!given(pkt1)) pkt1 = 0.0; + if (!given(pkt1l)) pkt1l = 0.0; + if (!given(pkt2)) pkt2 = 0.0; + if (!given(pk3)) pk3 = 0.0; + if (!given(pk3b)) pk3b = 0.0; + if (!given(pw0)) pw0 = 0.0; + if (!given(pnlx)) pnlx = 0.0; + if (!given(pdvt0)) pdvt0 = 0.0; + if (!given(pdvt1)) pdvt1 = 0.0; + if (!given(pdvt2)) pdvt2 = 0.0; + if (!given(pdvt0w)) pdvt0w = 0.0; + if (!given(pdvt1w)) pdvt1w = 0.0; + if (!given(pdvt2w)) pdvt2w = 0.0; + if (!given(pdrout)) pdrout = 0.0; + if (!given(pdsub)) pdsub = 0.0; + if (!given(pvth0)) pvth0 = 0.0; + if (!given(pua)) pua = 0.0; + if (!given(pua1)) pua1 = 0.0; + if (!given(pub)) pub = 0.0; + if (!given(pub1)) pub1 = 0.0; + if (!given(puc)) puc = 0.0; + if (!given(puc1)) puc1 = 0.0; + if (!given(pu0)) pu0 = 0.0; + if (!given(pute)) pute = 0.0; + if (!given(pvoff)) pvoff = 0.0; + if (!given(pdelta)) pdelta = 0.0; + if (!given(prdsw)) prdsw = 0.0; + if (!given(pprwb)) pprwb = 0.0; + if (!given(pprwg)) pprwg = 0.0; + if (!given(pprt)) pprt = 0.0; + if (!given(peta0)) peta0 = 0.0; + if (!given(petab)) petab = 0.0; + if (!given(ppclm)) ppclm = 0.0; + if (!given(ppdibl1)) ppdibl1 = 0.0; + if (!given(ppdibl2)) ppdibl2 = 0.0; + if (!given(ppdiblb)) ppdiblb = 0.0; + if (!given(ppscbe1)) ppscbe1 = 0.0; + if (!given(ppscbe2)) ppscbe2 = 0.0; + if (!given(ppvag)) ppvag = 0.0; + if (!given(pwr)) pwr = 0.0; + if (!given(pdwg)) pdwg = 0.0; + if (!given(pdwb)) pdwb = 0.0; + if (!given(pb0)) pb0 = 0.0; + if (!given(pb1)) pb1 = 0.0; + if (!given(palpha0)) palpha0 = 0.0; + if (!given(palpha1)) palpha1 = 0.0; + if (!given(pbeta0)) pbeta0 = 0.0; + if (!given(pvfb)) pvfb = 0.0; + + if (!given(pelm)) pelm = 0.0; + if (!given(pcgsl)) pcgsl = 0.0; + if (!given(pcgdl)) pcgdl = 0.0; + if (!given(pckappa)) pckappa = 0.0; + if (!given(pcf)) pcf = 0.0; + if (!given(pclc)) pclc = 0.0; + if (!given(pcle)) pcle = 0.0; + if (!given(pvfbcv)) pvfbcv = 0.0; + if (!given(pacde)) pacde = 0.0; + if (!given(pmoin)) pmoin = 0.0; + if (!given(pnoff)) pnoff = 0.0; + if (!given(pvoffcv)) pvoffcv = 0.0; + + /* unit degree celcius */ + if (!given(tnom)) tnom = 27; + tnom += CONSTCtoK; + + if (!given(Lint)) Lint = 0.0; + if (!given(Ll)) Ll = 0.0; + if (!given(Llc)) Llc = Ll; + if (!given(Lln)) Lln = 1.0; + if (!given(Lw)) Lw = 0.0; + if (!given(Lwc)) Lwc = Lw; + if (!given(Lwn)) Lwn = 1.0; + if (!given(Lwl)) Lwl = 0.0; + if (!given(Lwlc)) Lwlc = Lwl; + if (!given(Lmin)) Lmin = 0.0; + if (!given(Lmax)) Lmax = 1.0; + if (!given(Wint)) Wint = 0.0; + if (!given(Wl)) Wl = 0.0; + if (!given(Wlc)) Wlc = Wl; + if (!given(Wln)) Wln = 1.0; + if (!given(Ww)) Ww = 0.0; + if (!given(Wwc)) Wwc = Ww; + if (!given(Wwn)) Wwn = 1.0; + if (!given(Wwl)) Wwl = 0.0; + if (!given(Wwlc)) Wwlc = Wwl; + if (!given(Wmin)) Wmin = 0.0; + if (!given(Wmax)) Wmax = 1.0; + if (!given(dwc)) dwc = Wint; + if (!given(dlc)) dlc = Lint; + if (!given(cf)) cf = 2.0 * EPSOX / Math.PI * Math.log(1.0 + 0.4e-6 / tox); + if (!given(cgdo)) { + if (given(dlc) && (dlc > 0.0)) + cgdo = dlc * cox - cgdl; + else + cgdo = 0.6 * xj * cox; + } + if (!given(cgso)) { + if (given(dlc) && (dlc > 0.0)) + cgso = dlc * cox - cgsl; + else + cgso = 0.6 * xj * cox; + } + + if (!given(cgbo)) cgbo = 2.0 * dwc * cox; + if (!given(xpart)) xpart = 0.0; + if (!given(sheetResistance)) sheetResistance = 0.0; + if (!given(unitAreaJctCap)) unitAreaJctCap = 5.0E-4; + if (!given(unitLengthSidewallJctCap)) unitLengthSidewallJctCap = 5.0E-10; + if (!given(unitLengthGateSidewallJctCap)) unitLengthGateSidewallJctCap = unitLengthSidewallJctCap; + if (!given(jctSatCurDensity)) jctSatCurDensity = 1.0E-4; + if (!given(jctSidewallSatCurDensity)) jctSidewallSatCurDensity = 0.0; + if (!given(bulkJctPotential)) bulkJctPotential = 1.0; + if (!given(sidewallJctPotential)) sidewallJctPotential = 1.0; + if (!given(GatesidewallJctPotential)) GatesidewallJctPotential = sidewallJctPotential; + if (!given(bulkJctBotGradingCoeff)) bulkJctBotGradingCoeff = 0.5; + if (!given(bulkJctSideGradingCoeff)) bulkJctSideGradingCoeff = 0.33; + if (!given(bulkJctGateSideGradingCoeff)) bulkJctGateSideGradingCoeff = bulkJctSideGradingCoeff; + if (!given(jctEmissionCoeff)) jctEmissionCoeff = 1.0; + if (!given(jctTempExponent)) jctTempExponent = 3.0; + if (!given(oxideTrapDensityA)) { + if (type == NMOS) + oxideTrapDensityA = 1e20; + else + oxideTrapDensityA=9.9e18; + } + if (!given(oxideTrapDensityB)) { + if (type == NMOS) + oxideTrapDensityB = 5e4; + else + oxideTrapDensityB = 2.4e3; + } + if (!given(oxideTrapDensityC)) { + if (type == NMOS) + oxideTrapDensityC = -1.4e-12; + else + oxideTrapDensityC = 1.4e-12; + } + + if (!given(em)) em = 4.1e7; /* V/m */ + if (!given(ef)) ef = 1.0; + if (!given(af)) af = 1.0; + if (!given(kf)) kf = 0.0; + +//GGG These lines were added by me (tedv) because I think +// the original bsim3 code had a bug where it didn't check them. + if (!given(lk2)) lk2 = 0.0; + if (!given(wk2)) wk2 = 0.0; + if (!given(pk2)) pk2 = 0.0; + } + + public void computeTemperatureData() { + double Temp,Tnom,TRatio,Vtm0,Eg0,ni,Eg,T0,T1,delTemp; + + if (bulkJctPotential < 0.1) + { + bulkJctPotential = 0.1; + System.out.println("Given pb is less than 0.1. Pb is set to 0.1."); + } + if (sidewallJctPotential < 0.1) + { + sidewallJctPotential = 0.1; + System.out.println("Given pbsw is less than 0.1. Pbsw is set to 0.1."); + } + if (GatesidewallJctPotential < 0.1) + { + GatesidewallJctPotential = 0.1; + System.out.println("Given pbswg is less than 0.1. Pbswg is set to 0.1."); + } + + Temp = temp; + Tnom = tnom; + TRatio = Temp / Tnom; + + vcrit = CONSTvt0 * Math.log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); + factor1 = Math.sqrt(EPSSI / EPSOX * tox); + + Vtm0 = KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + ni = 1.45e10 * (Tnom / 300.15) * Math.sqrt(Tnom / 300.15) + * Math.exp(21.5565981 - Eg0 / (2.0 * Vtm0)); + + vtm = KboQ * Temp; + Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); + if (Temp != Tnom) + { + T0 = Eg0 / Vtm0 - Eg / vtm + jctTempExponent * Math.log(Temp / Tnom); + T1 = Math.exp(T0 / jctEmissionCoeff); + jctTempSatCurDensity = jctSatCurDensity * T1; + jctSidewallTempSatCurDensity = jctSidewallSatCurDensity * T1; + } + else + { + jctTempSatCurDensity = jctSatCurDensity; + jctSidewallTempSatCurDensity = jctSidewallSatCurDensity; + } + + if (jctTempSatCurDensity < 0.0) + jctTempSatCurDensity = 0.0; + if (jctSidewallTempSatCurDensity < 0.0) + jctSidewallTempSatCurDensity = 0.0; + + /* Temperature dependence of D/B and S/B diode capacitance begins */ + delTemp = Temp - tnom; + T0 = tcj * delTemp; + if (T0 >= -1.0) + unitAreaJctCap *= 1.0 + T0; + else if (unitAreaJctCap > 0.0) + { + unitAreaJctCap = 0.0; + System.out.println("Temperature effect has caused cj to be negative. Cj is clamped to zero."); + } + T0 = tcjsw * delTemp; + if (T0 >= -1.0) + unitLengthSidewallJctCap *= 1.0 + T0; + else if (unitLengthSidewallJctCap > 0.0) + { + unitLengthSidewallJctCap = 0.0; + System.out.println("Temperature effect has caused cjsw to be negative. Cjsw is clamped to zero."); + } + T0 = tcjswg * delTemp; + if (T0 >= -1.0) + unitLengthGateSidewallJctCap *= 1.0 + T0; + else if (unitLengthGateSidewallJctCap > 0.0) + { + unitLengthGateSidewallJctCap = 0.0; + System.out.println("Temperature effect has caused cjswg to be negative. Cjswg is clamped to zero."); + } + + PhiB = bulkJctPotential - tpb * delTemp; + if (PhiB < 0.01) + { + PhiB = 0.01; + System.out.println("Temperature effect has caused pb to be less than 0.01. Pb is clamped to 0.01."); + } + PhiBSW = sidewallJctPotential- tpbsw * delTemp; + if (PhiBSW <= 0.01) + { + PhiBSW = 0.01; + System.out.println("Temperature effect has caused pbsw to be less than 0.01. Pbsw is clamped to 0.01."); + } + PhiBSWG = GatesidewallJctPotential - tpbswg * delTemp; + if (PhiBSWG <= 0.01) + { + PhiBSWG = 0.01; + System.out.println("Temperature effect has caused pbswg to be less than 0.01. Pbswg is clamped to 0.01."); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Capacitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Capacitor.java new file mode 100644 index 0000000000..3d77e3ee62 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Capacitor.java @@ -0,0 +1,157 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.circuit.CapacitorInterface; + +/** + * Class to represent resistors in .aspice files. + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public final class Capacitor implements DeviceInterface,CapacitorInterface { + /** Number of Ports */ + private static final int NUM_PORTS = 2; + + /** Capacitance of capacitor in */ + private double capacitance; + + /** Name of source node */ + private final HierName source; + + /** Name of drain node */ + private final HierName drain; + + /** + * Class constructor. + * @param source name of source node + * @param drain name of drain node + * @param capacitance of capacitor + **/ + public Capacitor(final HierName source, + final HierName drain, + final double capacitance) + { + // ensure that source <= drain, lexicographically + if (source.compareTo(drain) <= 0) { + this.source = source; + this.drain = drain; + } else { + this.source = drain; + this.drain = source; + } + + this.capacitance = capacitance; + } + + /** Not implemented, returns null **/ + public HierName getName() { return null;} + + /** + * Get number of ports + * @return name of source node + **/ + public int getNumPorts() { + return NUM_PORTS; + } + + /** + * Get name of source node. + * @return name of source node + **/ + public HierName getSource() { + return source; + } + + /** + * Get name of drain node. + * @return name of drain node + **/ + public HierName getDrain() { + return drain; + } + + /** + * Get capacitance of capacitor. + * @return capacitance of capacitor + **/ + public double getCapacitance() { + return capacitance; + } + + /** + * Set capacitance of capacitor. + **/ + public void setCapacitance(double capacitance) { + this.capacitance = capacitance; + } + + /** + * return string suitable for inclusion in an aspice file. + **/ + public String getAspiceString() { + return "cap (" + + getSource().getAspiceString() + "," + + getDrain().getAspiceString() + ") (" + + NumberFormatter.format(getCapacitance()) + ");"; + } + + /** + * + **/ + public String toString() { + return getClass().getName() + " (" + + getSource().toString() + "," + + getDrain().toString() + ") (" + + getCapacitance() + ");"; + } + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device for a given set of input voltages. + * @param data array of port data objects to use for return values + * @param voltage array of voltages connected to device + * @throws IllegalArgumentException + * @return array of current/charge/etc. data for each port, + * indexed by input voltage + **/ + public PortData[] evalVoltage(PortData[] data, double[] voltage) { + if (data.length != NUM_PORTS || voltage.length != NUM_PORTS) + throw new IllegalArgumentException("Expected " + NUM_PORTS + + " ports"); + + double charge = (voltage[1] - voltage[0]) * capacitance; + + data[0].setVoltage(voltage[0]); + data[0].setCurrent(0); + data[0].setCurrentDerivative(0, 0); + data[0].setCurrentDerivative(1, 0); + data[0].setCharge(charge); + data[0].setChargeDerivative(0, capacitance); + data[0].setChargeDerivative(1, -capacitance); + + data[1].setVoltage(voltage[1]); + data[1].setCurrent(0); + data[1].setCurrentDerivative(0, 0); + data[1].setCurrentDerivative(1, 0); + data[1].setCharge(-charge); + data[1].setChargeDerivative(0, -capacitance); + data[1].setChargeDerivative(1, capacitance); + + return data; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CapacitorTest.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CapacitorTest.java new file mode 100644 index 0000000000..33db5983f4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CapacitorTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +import com.avlsi.file.common.HierName; + +/** + * Class that tests capacitors + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public class CapacitorTest extends AbstractDeviceTest { + public CapacitorTest(String source, String drain, double capacitance) { + super(new Capacitor(HierName.makeHierName(source), + HierName.makeHierName(drain), + capacitance)); + } + + public double[][] getVoltageRange() { + // voltageRange[i] is range info for port i + // voltageRange[i][0] is start voltage, and [i][1] is end voltage + return new double[][] { + new double[] { low, low }, // Fix Source voltage + new double[] { low, high } // Scan Drain voltage + }; + } + + public GraphPortData[] makeGraphers() + throws IOException + { + // Compare current on source with voltage on drain + final int chargePort = 0; + final int voltagePort = 1; + final String devName = device.getClass().getName(); + + final GraphPortData[] gpds = new GraphPortData[2]; + + try { + gpds[0] = new GraphCharge(devName, voltagePort, chargePort); + gpds[1] = new GraphChargeDerivative(devName, voltagePort, + chargePort, chargePort); + return gpds; + } catch (IOException e) { + for (int i = 0; i < gpds.length; i++) + if (gpds[i] != null) + gpds[i].close(); + + throw e; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CastTestEnvironment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CastTestEnvironment.java new file mode 100644 index 0000000000..65799ef241 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/CastTestEnvironment.java @@ -0,0 +1,144 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.io.File; +import java.io.FileReader; +import java.io.PrintStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * Class representing the cast file test environment for the + * C version of aspice. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **/ +public final class CastTestEnvironment { + + /** List of imports (Strings) **/ + private final HashSet importSection = new HashSet(); + + /** Node/channel declarations **/ + private final ArrayList declarationSection = new ArrayList(); + + /** Instantiations **/ + private final ArrayList instantiationSection = new ArrayList(); + + /** asp{} section **/ + private final ArrayList aspSection = new ArrayList(); + + /** Copy constructor **/ + public CastTestEnvironment(final CastTestEnvironment src) { + importSection.addAll(src.importSection); + declarationSection.addAll(src.declarationSection); + instantiationSection.addAll(src.instantiationSection); + aspSection.addAll(src.aspSection); + } + + /** Constructor from initialization file **/ + public CastTestEnvironment(final String initFile) { + File f = new File(initFile); + if (!f.canRead()) return; + try { + FileReader fr = new FileReader(f); + int ch, lineNum = 1; + String line = ""; + while ((ch = fr.read()) != -1) { + if (ch != '\n') { + line += (char)ch; + lineNum++; + } + else { + // + // Complete line. Parse into + // "SECTION: str" fields. + // + int i = line.indexOf(':'); + if (i == -1) { + // Default to instantiation section + // (for no particular reason) + instantiationSection.add(line); + } + else { + String section = line.substring(0,i); + String x = line.substring(i+1); + if (section.equals("IMPORT")) + importSection.add(x); + else if (section.equals("DECLARATION")) + declarationSection.add(x); + else if (section.equals("INSTANTIATION")) + instantiationSection.add(x); + else if (section.equals("ASP")) + aspSection.add(x); + else { + System.err.println("CastTestEnvironment: Ignoring "+ + "unknown section '"+x+"' at line "+ + lineNum+" in "+initFile+"."); + } + } + line = ""; + } + } + fr.close(); + } + catch (FileNotFoundException e) { + System.err.println("Couldn't find file "+initFile+"."); + return; + } + catch (IOException e) { + System.err.println("Error reading "+initFile+":"); + System.err.println(e+": "+e.getMessage()); + } + } + + /** Add a line to the import section. **/ + public void addImport(final String line) { + importSection.add(line); + } + + /** Add a line to the type declaration section. **/ + public void addDeclaration(final String line) { + declarationSection.add(line); + } + + /** Add a line to the instantiation section. **/ + public void addInstantiation(final String line) { + instantiationSection.add(line); + } + + /** Add a line to the asp section. **/ + public void addAspLine(final String line) { + aspSection.add(line); + } + + /** Print the entire cast test environment file to the PrintStream. **/ + public void printToStream(PrintStream os) { + Iterator it = importSection.iterator(); + while (it.hasNext()) + os.println("import \""+(String)it.next()+"\";"); + int i; + for (i=0; i < declarationSection.size(); i++) + os.println(declarationSection.get(i)); + for (i=0; i < instantiationSection.size(); i++) + os.println(instantiationSection.get(i)); + os.println("asp {"); + for (i=0; i < aspSection.size(); i++) + os.println(aspSection.get(i)); + os.println("}"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DeviceInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DeviceInterface.java new file mode 100644 index 0000000000..696bdc1304 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DeviceInterface.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +/** + * Interface for devices + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +interface DeviceInterface { + /** Gets the number of ports on the device. **/ + int getNumPorts(); + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device for a given set of input voltages. + * @param data array of port data objects to use for return values + * @param voltage array of voltages connected to device + * @throws IllegalArgumentException + * @throws NoModelException + * @return array of current/charge/etc. data for each port, + * indexed by input voltage + **/ + PortData[] evalVoltage(PortData[] data, final double[] voltage) + throws NoModelException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Diode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Diode.java new file mode 100644 index 0000000000..83f05f4c23 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Diode.java @@ -0,0 +1,333 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.circuit.DiodeInterface; + +/** + * Class to represent diodes in .aspice files. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Diode implements DeviceInterface,DiodeInterface { + /** type of diode, N_TYPE or P_TYPE. */ + private final int type; + + /** Name of source node. **/ + private final HierName source; + + /** Name of drain node. **/ + private final HierName drain; + + /** Width of diode in meters. **/ + private final double width; + + /** Length of diode in meters. **/ + private final double length; + + /** Area of diode in square meters. **/ + private final double area; + + /** Perimeter of diode in meters. **/ + private final double perimeter; + + /** Number of Ports **/ + private static final int NUM_PORTS = 2; + + /** BSIM3 Device model data **/ + private final BSim3Model m; + + /** BSim3 convergence correction hack-- 0 turns it off. **/ + private static final double gmin = 0; + + /** + * Class constructor. + * @param source name of source node + * @param drain name of drain node + * @param width of diode in meters + * @param length of diode in meters + * @param area of diode in square meters + * @param perimeter of diode in meters + * @throws IllegalArgumentException + **/ + public Diode(final int type, + final HierName source, + final HierName drain, + final double width, + final double length, + final double area, + final double perimeter) { + if (type != DeviceTypes.N_TYPE && type != DeviceTypes.P_TYPE) + throw new IllegalArgumentException("Bad diode type: " + type); + + this.type = type; + + this.source = source; + this.drain = drain; + + this.width = width; + this.length = length; + this.area = area; + this.perimeter = perimeter; + + m = BSim3Model.findModel(type, width, length); + } + + /** Not implemented, returns null **/ + public HierName getName() { return null;} + + /** + * Get number of ports + * @return number of ports + **/ + public int getNumPorts() { + return NUM_PORTS; + } + + /** + * Get the type of the diode, either N_TYPE, or P_TYPE. + * @return the type of the diode + **/ + public int getType() { + return type; + } + + /** + * Get name of source node. + * @return name of source node + **/ + public HierName getSource() { + return source; + } + + /** + * Get name of drain node. + * @return name of drain node + **/ + public HierName getDrain() { + return drain; + } + + /** + * Get width of diode + * @return width of diode in meters + **/ + public double getWidth() { + return width; + } + + /** + * Get length of diode + * @return length of diode in meters + **/ + public double getLength() { + return length; + } + + /** + * Get area of diode + * @return area of diode in square meters + **/ + public double getArea() { + return area; + } + + /** + * Get perimeter + * @return get diode perimeter in meters + **/ + public double getPerimeter() { + return perimeter; + } + + /** + * return string suitable for inclusion in an aspice file. + **/ + public String getAspiceString() { + return (type == DeviceTypes.N_TYPE ? "n_diode (" : "p_diode (") + + getSource().getAspiceString() + "," + + getDrain().getAspiceString() + ") (" + + NumberFormatter.format(getWidth()) + "," + + NumberFormatter.format(getLength()) + "," + + NumberFormatter.format(getArea()) + "," + + NumberFormatter.format(getPerimeter()) + ");"; + + } + + public String toString() { + return getAspiceString(); + } + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device for a given set of input voltages. + * @param data array of port data objects to use for return values + * @param voltage array of voltages connected to device + * @throws IllegalArgumentException + * @return array of current/charge/etc. data for each port, + * indexed by input voltage + **/ + public PortData[] evalVoltage(PortData[] data, double[] voltage) + throws NoModelException { + if (data.length != NUM_PORTS || voltage.length != NUM_PORTS) + throw new IllegalArgumentException("Expected " + NUM_PORTS + + " ports"); + + if (m == null) + throw new NoModelException(); + + double Vs = voltage[0]; + double Vb = voltage[1]; + + double vbs,gbs,cbs,qbs,capbs; + double Nvtm, Inv_Nvtm; + double SatCurrent,evbs,vjsm,IsEvjsm,czbs,czbssw,czbsswg; + double MJ,MJSW,MJSWG; + double T0,T1,arg,sarg; + + /* precompute some diode expressions */ + vbs = m.type * (Vb - Vs); + Nvtm = m.vtm * m.jctEmissionCoeff; + Inv_Nvtm = 1.0 / Nvtm; + MJ = m.bulkJctBotGradingCoeff; + MJSW = m.bulkJctSideGradingCoeff; + MJSWG = m.bulkJctGateSideGradingCoeff; + + /* I and G */ + if ((area <= 0.0) && (perimeter <= 0.0)) + SatCurrent = 1.0e-14; + else + SatCurrent = area * m.jctTempSatCurDensity + + perimeter * m.jctSidewallTempSatCurDensity; + if (SatCurrent <= 0.0) + { + gbs = gmin; + cbs = gbs * vbs; + } + else + { + if (m.ijth == 0.0) + { + evbs = Math.exp(vbs * Inv_Nvtm); + gbs = SatCurrent * evbs * Inv_Nvtm + gmin; + cbs = SatCurrent * (evbs - 1.0) + gmin * vbs; + } + else + { + vjsm = Nvtm * Math.log(m.ijth / SatCurrent + 1.0); + IsEvjsm = SatCurrent * Math.exp(vjsm * Inv_Nvtm); + if (vbs < vjsm) + { + evbs = Math.exp(vbs * Inv_Nvtm); + gbs = SatCurrent * evbs * Inv_Nvtm + gmin; + cbs = SatCurrent * (evbs - 1.0) + gmin * vbs; + } + else + { + T0 = IsEvjsm * Inv_Nvtm; + gbs = T0 + gmin; + cbs = IsEvjsm - SatCurrent + T0 * (vbs - vjsm) + gmin * vbs; + } + } + } + + /* Q and C */ + czbs = m.unitAreaJctCap * area; + if (perimeter < width) + { + czbssw = 0; + czbsswg = m.unitLengthGateSidewallJctCap * perimeter; + } + else + { + czbssw = m.unitLengthSidewallJctCap * (perimeter - width); + czbsswg = m.unitLengthGateSidewallJctCap * width; + } + + if (vbs == 0.0) + { + qbs = 0.0; + capbs = czbs + czbssw + czbsswg; + } + else if (vbs < 0.0) + { + if (czbs > 0.0) + { + arg = 1.0 - vbs / m.PhiB; + if (MJ == 0.5) + sarg = 1.0 / Math.sqrt(arg); + else + sarg = Math.exp(-MJ * Math.log(arg)); + qbs = m.PhiB * czbs * (1.0 - arg * sarg) / (1.0 - MJ); + capbs = czbs * sarg; + } + else + { + qbs = 0.0; + capbs = 0.0; + } + if (czbssw > 0.0) + { + arg = 1.0 - vbs / m.PhiBSW; + if (MJSW == 0.5) + sarg = 1.0 / Math.sqrt(arg); + else + sarg = Math.exp(-MJSW * Math.log(arg)); + qbs += m.PhiBSW * czbssw * (1.0 - arg * sarg) / (1.0 - MJSW); + capbs += czbssw * sarg; + } + if (czbsswg > 0.0) + { + arg = 1.0 - vbs / m.PhiBSWG; + if (MJSWG == 0.5) + sarg = 1.0 / Math.sqrt(arg); + else + sarg = Math.exp(-MJSWG * Math.log(arg)); + qbs += m.PhiBSWG * czbsswg * (1.0 - arg * sarg) / (1.0 - MJSWG); + capbs += czbsswg * sarg; + } + } + else + { + T0 = czbs + czbssw + czbsswg; + T1 = vbs * (czbs * MJ / m.PhiB + czbssw * MJSW + / m.PhiBSW + czbsswg * MJSWG / m.PhiBSWG); + qbs = vbs * (T0 + 0.5 * T1); + capbs = T0 + T1; + } + + data[0].setVoltage(voltage[0]); + data[0].setCurrent(m.type * cbs); + data[0].setCurrentDerivative(0, capbs); + data[0].setCurrentDerivative(1, -capbs); + data[0].setCharge(-m.type * qbs); + data[0].setChargeDerivative(0, -gbs); + data[0].setChargeDerivative(1, gbs); + + data[1].setVoltage(voltage[1]); + data[1].setCurrent(-m.type * cbs); + data[1].setCurrentDerivative(0, -capbs); + data[1].setCurrentDerivative(1, capbs); + data[1].setCharge(m.type * qbs); + data[1].setChargeDerivative(0, gbs); + data[1].setChargeDerivative(1, -gbs); + + return data; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DiodeTest.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DiodeTest.java new file mode 100644 index 0000000000..70b09cb28b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/DiodeTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +import com.avlsi.file.common.HierName; + +/** + * Class that tests diodes + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public class DiodeTest extends AbstractDeviceTest { + public DiodeTest(int type, + String source, String drain, + double width, double length, + double area, double perimeter) + { + super(new Diode(type, + HierName.makeHierName(source), + HierName.makeHierName(drain), + width, length, area, perimeter)); + } + + public double[][] getVoltageRange() { + // voltageRange[i] is range info for port i + // voltageRange[i][0] is start voltage, and [i][1] is end voltage + return new double[][] { + new double[] { 0, 0 }, // Fix Source voltage + new double[] { 0, 2 }, // Scan Drain voltage + }; + } + + public GraphPortData[] makeGraphers() + throws IOException + { + final int source = 0; + final int drain = 1; + + final int voltagePort = drain; + final String devName = device.getClass().getName(); + + final GraphPortData[] gpds = new GraphPortData[4]; + + try { + gpds[0] = new GraphCurrent(devName, voltagePort, source); + gpds[1] = new GraphCurrentDerivative(devName, voltagePort, source, + source); + gpds[2] = new GraphCurrent(devName, voltagePort, drain); + gpds[3] = new GraphCurrentDerivative(devName, voltagePort, drain, + source); + return gpds; + } catch (IOException e) { + for (int i = 0; i < gpds.length; i++) + if (gpds[i] != null) + gpds[i].close(); + + throw e; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCharge.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCharge.java new file mode 100644 index 0000000000..51b8b58974 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCharge.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +/** + * Interface for graphing current + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public class GraphCharge extends GraphPortData { + + private final int chargePort; + + public GraphCharge(String fileName, int voltagePort, int chargePort) + throws IOException + { + super(fileName + "_Q" + chargePort, voltagePort); + + this.chargePort = chargePort; + } + + public double getY(PortData[] data) { + return data[chargePort].getCharge(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphChargeDerivative.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphChargeDerivative.java new file mode 100644 index 0000000000..9712862912 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphChargeDerivative.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +/** + * Interface for graphing current + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public class GraphChargeDerivative extends GraphPortData { + + private final int chargePort; + private final int voltageDerivativePort; + + public GraphChargeDerivative(String fileName, int voltagePort, + int chargePort) + throws IOException + { + this(fileName, voltagePort, chargePort, voltagePort); + } + + public GraphChargeDerivative(String fileName, int voltagePort, + int chargePort, int voltageDerivativePort) + throws IOException + { + super(fileName + "_dQ" + chargePort + "_dV" + voltageDerivativePort, + voltagePort); + + this.chargePort = chargePort; + this.voltageDerivativePort = voltageDerivativePort; + } + + public double getY(PortData[] data) { + //GGG Wow is that a great example of too much description making + // something hard to understand... + return data[chargePort].getChargeDerivative(voltageDerivativePort); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrent.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrent.java new file mode 100644 index 0000000000..0befc73015 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrent.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +/** + * Interface for graphing current + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public class GraphCurrent extends GraphPortData { + + private final int currentPort; + + public GraphCurrent(String fileName, int voltagePort, int currentPort) + throws IOException + { + super(fileName + "_I" + currentPort, voltagePort); + + this.currentPort = currentPort; + } + + public double getY(PortData[] data) { + return data[currentPort].getCurrent(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrentDerivative.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrentDerivative.java new file mode 100644 index 0000000000..2e7ea35c5b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphCurrentDerivative.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +/** + * Interface for graphing current + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public class GraphCurrentDerivative extends GraphPortData { + + private final int currentPort; + private final int voltageDerivativePort; + + public GraphCurrentDerivative(String fileName, int voltagePort, + int currentPort) + throws IOException + { + this(fileName, voltagePort, currentPort, voltagePort); + } + + public GraphCurrentDerivative(String fileName, int voltagePort, + int currentPort, int voltageDerivativePort) + throws IOException + { + super(fileName + "_dI" + currentPort + "_dV" + voltageDerivativePort, + voltagePort); + + this.currentPort = currentPort; + this.voltageDerivativePort = voltageDerivativePort; + } + + public double getY(PortData[] data) { + //GGG Wow is that a great example of too much description making + // something hard to understand... + return data[currentPort].getCurrentDerivative(voltageDerivativePort); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphPortData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphPortData.java new file mode 100644 index 0000000000..51d5208319 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/GraphPortData.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.Writer; +import java.io.PrintWriter; +import java.io.BufferedWriter; +import java.io.FileWriter; + +import java.io.IOException; + +/** + * Interface for graphing port data + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +abstract class GraphPortData { + + private PrintWriter file; + + private final int voltagePort; + + protected GraphPortData(Writer w, int voltagePort) { + this.file = new PrintWriter(w); + this.voltagePort = voltagePort; + } + + protected GraphPortData(String fileName, int voltagePort) + throws IOException + { + this(new BufferedWriter(new FileWriter(fileName+".gplot")), + voltagePort); + } + + public void close() + throws IOException + { + file.close(); + } + + public void writeCoordinate(PortData[] data) { + writeCoordinate(getX(data), getY(data)); + } + + public void writeCoordinate(double x, double y) { + file.println(x + " " + y); + } + + public double getX(PortData[] data) { + return data[voltagePort].getVoltage(); + } + + public abstract double getY(PortData[] data); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/NoModelException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/NoModelException.java new file mode 100644 index 0000000000..416698c9ba --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/NoModelException.java @@ -0,0 +1,23 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +/** + * Exception generated when a model-less device tries to access a model + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public final class NoModelException extends Exception { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/PortData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/PortData.java new file mode 100644 index 0000000000..912bae259a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/PortData.java @@ -0,0 +1,151 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +/** + * Class for port data evaluated by device. + * + * This class wraps all of the data values associated with + * a single port (node) out of a device. It contains + * current, voltage, and charge values as doubles. It also + * has an array of partial derivatives for both current and + * charge with respect to voltages on each device node. + * So dI/dV[0] is the derivative of current on this node + * with respect to the 0th node of the device (usually source). + * + **/ +class PortData { + private double V; + private double I; + private double Q; + private double dI[]; + private double dQ[]; + + public PortData(int numPorts) { + this.V = this.I = this.Q = 0; + this.dI = new double[numPorts]; + this.dQ = new double[numPorts]; + + for (int i = 0; i < numPorts; i++) + dI[i] = dQ[i] = 0; + } + + public PortData(double V, double I, double Q, + double dI[], double dQ[]) { + this.V = V; + this.I = I; + this.Q = Q; + this.dI = dI; + this.dQ = dQ; + } + + /** + * Get voltage + * @return voltage + **/ + public double getVoltage() { + return V; + } + + /** + * Set voltage + * @param voltage + **/ + public void setVoltage(double V) { + this.V = V; + } + + /** + * Get current + * @return current + **/ + public double getCurrent() { + return I; + } + + /** + * Set current + * @param current + **/ + public void setCurrent(double I) { + this.I = I; + } + + /** + * Get charge + * @return charge + **/ + public double getCharge() { + return Q; + } + + /** + * Set charge + * @param charge + **/ + public void setCharge(double Q) { + this.Q = Q; + } + + /** + * Get derivative vector of current + * @return current derivative array + **/ + public double[] getCurrentDerivative() { + return dI; + } + + /** + * Get derivative of current + * @return current derivative + **/ + public double getCurrentDerivative(int i) { + return dI[i]; + } + + /** + * Set derivative of current + * @param voltage with respect to which voltage + * @param current derivative value + **/ + public void setCurrentDerivative(int voltage, double current) { + dI[voltage] = current; + } + + /** + * Get derivative vector of charge + * @return charge derivative array + **/ + public double[] getChargeDerivative() { + return dQ; + } + + /** + * Get derivative of charge + * @return charge derivative + **/ + public double getChargeDerivative(int i) { + return dQ[i]; + } + + /** + * Set derivative of charge + * @param voltage with respect to which voltage + * @param charge derivative value + **/ + public void setChargeDerivative(int voltage, double charge) { + dQ[voltage] = charge; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Resistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Resistor.java new file mode 100644 index 0000000000..6e15951158 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Resistor.java @@ -0,0 +1,152 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.circuit.ResistorInterface; + +/** + * Class to represent resistors in .aspice files. + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public final class Resistor implements DeviceInterface,ResistorInterface { + /** Number of Ports */ + private static final int NUM_PORTS = 2; + + /** Conductance of resistor in 1/ohms */ + private double conductance; + + /** Name of source node */ + private final HierName source; + + /** Name of drain node */ + private final HierName drain; + + /** + * Class constructor. + * @param source name of source node + * @param drain name of drain node + * @param conductance of resistor + **/ + public Resistor(final HierName source, + final HierName drain, + final double conductance) + { + // ensure that source <= drain, lexicographically + if (source.compareTo(drain) <= 0) { + this.source = source; + this.drain = drain; + } else { + this.source = drain; + this.drain = source; + } + + this.conductance = conductance; + } + /** Not implemented, returns null **/ + public HierName getName() { return null;} + + /** + * Get number of ports + * @return number of ports + **/ + public int getNumPorts() { + return NUM_PORTS; + } + + /** + * Get name of source node. + * @return name of source node + **/ + public HierName getSource() { + return source; + } + + /** + * Get name of drain node. + * @return name of drain node + **/ + public HierName getDrain() { + return drain; + } + + /** + * Get conductance of resistor. + * @return conductance of resistor + **/ + public double getConductance() { + return conductance; + } + + /** + * Set conductance of resistor. + **/ + public void setConductance(double conductance) { + this.conductance = conductance; + } + + /** + * return string suitable for inclusion in an aspice file. + **/ + public String getAspiceString() { + return "res (" + + getSource().getAspiceString() + "," + + getDrain().getAspiceString() + ") (" + + NumberFormatter.format(1/getConductance()) + ");"; + } + + public String toString() { + return getAspiceString(); + } + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device for a given set of input voltages. + * @param data array of port data objects to use for return values + * @param voltage array of voltages connected to device + * @throws IllegalArgumentException + * @return array of current/charge/etc. data for each port, + * indexed by input voltage + **/ + + public PortData[] evalVoltage(PortData[] data, double[] voltage) { + if (data.length != NUM_PORTS || voltage.length != NUM_PORTS) + throw new IllegalArgumentException("Expected " + NUM_PORTS + + " ports"); + + double current = (voltage[1] - voltage[0]) * conductance; + + data[0].setVoltage(voltage[0]); + data[0].setCurrent(current); + data[0].setCurrentDerivative(0, conductance); + data[0].setCurrentDerivative(1, -conductance); + data[0].setCharge(0); + data[0].setChargeDerivative(0, 0); + data[0].setChargeDerivative(1, 0); + + data[1].setVoltage(voltage[1]); + data[1].setCurrent(-current); + data[1].setCurrentDerivative(0, -conductance); + data[1].setCurrentDerivative(1, conductance); + data[1].setCharge(0); + data[1].setChargeDerivative(0, 0); + data[1].setChargeDerivative(1, 0); + + return data; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/ResistorTest.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/ResistorTest.java new file mode 100644 index 0000000000..9429071b95 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/ResistorTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +import com.avlsi.file.common.HierName; + +/** + * Class that tests resistors + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public final class ResistorTest extends AbstractDeviceTest { + public ResistorTest(String source, String drain, double conductance) { + super(new Resistor(HierName.makeHierName(source), + HierName.makeHierName(drain), + conductance)); + + } + + public double[][] getVoltageRange() { + // voltageRange[i] is range info for port i + // voltageRange[i][0] is start voltage, and [i][1] is end voltage + return new double[][] { + new double[] { low, low }, // Fix Source voltage + new double[] { low, high } // Scan Drain voltage + }; + } + + public GraphPortData[] makeGraphers() + throws IOException + { + // Compare current on source with voltage on drain + final int currentPort = 0; + final int voltagePort = 1; + final String devName = device.getClass().getName(); + + final GraphPortData[] gpds = new GraphPortData[2]; + + try { + gpds[0] = new GraphCurrent(devName, voltagePort, currentPort); + gpds[1] = new GraphCurrentDerivative(devName, voltagePort, + currentPort, currentPort); + return gpds; + } catch (IOException e) { + for (int i = 0; i < gpds.length; i++) + if (gpds[i] != null) + gpds[i].close(); + + throw e; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/SizedModel.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/SizedModel.java new file mode 100644 index 0000000000..d11b667c65 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/SizedModel.java @@ -0,0 +1,731 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + + +import com.avlsi.file.common.DeviceTypes; + +public class SizedModel { + public double Width; + public double Length; + + /* W,L adjusted parameters */ + public double cdsc; + public double cdscb; + public double cdscd; + public double cit; + public double nfactor; + public double xj; + public double vsat; + public double at; + public double a0; + public double ags; + public double a1; + public double a2; + public double keta; + public double nsub; + public double npeak; + public double ngate; + public double gamma1; + public double gamma2; + public double vbx; + public double vbi; + public double vbm; + public double vbsc; + public double xt; + public double phi; + public double litl; + public double k1; + public double kt1; + public double kt1l; + public double kt2; + public double k2; + public double k3; + public double k3b; + public double w0; + public double nlx; + public double dvt0; + public double dvt1; + public double dvt2; + public double dvt0w; + public double dvt1w; + public double dvt2w; + public double drout; + public double dsub; + public double vth0; + public double ua; + public double ua1; + public double ub; + public double ub1; + public double uc; + public double uc1; + public double u0; + public double ute; + public double voff; + public double vfb; + public double delta; + public double rdsw; + public double rds0; + public double prwg; + public double prwb; + public double prt; + public double eta0; + public double etab; + public double pclm; + public double pdibl1; + public double pdibl2; + public double pdiblb; + public double pscbe1; + public double pscbe2; + public double pvag; + public double wr; + public double dwg; + public double dwb; + public double b0; + public double b1; + public double alpha0; + public double alpha1; + public double beta0; + + /* CV model */ + public double elm; + public double cgsl; + public double cgdl; + public double ckappa; + public double cf; + public double clc; + public double cle; + public double vfbcv; + public double noff; + public double voffcv; + public double acde; + public double moin; + + /* Pre-calculated constants */ + public double dw; + public double dl; + public double leff; + public double weff; + + public double dwc; + public double dlc; + public double leffCV; + public double weffCV; + public double abulkCVfactor; + public double cgso; + public double cgdo; + public double cgbo; + public double tconst; + + public double u0temp; + public double vsattemp; + public double sqrtPhi; + public double phis3; + public double Xdep0; + public double sqrtXdep0; + public double theta0vb0; + public double thetaRout; + + public double cof1; + public double cof2; + public double cof3; + public double cof4; + public double cdep0; + public double vfbzb; + public double ldeb; + public double k1ox; + public double k2ox; + + private static SizedModel cachedSizedModel = null; + private static double lastWidth = Double.NaN; + private static double lastLength = Double.NaN; + private static BSim3Model lastModel = null; + + public static SizedModel newSizedModel(BSim3Model m, double W, double L) { + if (m != lastModel || W != lastWidth || L != lastLength || + cachedSizedModel == null) + { + lastModel = m; + lastWidth = W; + lastLength = L; + cachedSizedModel = new SizedModel(m, W, L); + } + + return cachedSizedModel; + } + + /** @throws IllegalArgumentException **/ + public SizedModel(BSim3Model m, double W, double L) { + + double Ldrn, Wdrn, T0, T1, T2, T3, T4, T5, Inv_L, Inv_W, Inv_LW; + double Tnom, TRatio, Vtm0, ni, Eg0; + double tmp, tmp1, tmp2, tmp3; + + /*** adjust W,L ***/ + W += m.xw; + L += m.xl; + + /*** temperature, width, length dependent calculations ***/ + Tnom = m.tnom; + TRatio = m.temp / Tnom; + + Vtm0 = BSim3Model.KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + ni = 1.45e10 * (Tnom / 300.15) * Math.sqrt(Tnom / 300.15) + * Math.exp(21.5565981 - Eg0 / (2.0 * Vtm0)); + + Ldrn = L; + Wdrn = W; + Length = Ldrn; + Width = Wdrn; + + T0 = Math.pow(Ldrn, m.Lln); + T1 = Math.pow(Wdrn, m.Lwn); + tmp1 = m.Ll / T0 + m.Lw / T1 + m.Lwl / (T0 * T1); + dl = m.Lint + tmp1; + tmp2 = m.Llc / T0 + m.Lwc / T1 + m.Lwlc / (T0 * T1); + dlc = m.dlc + tmp2; + + T2 = Math.pow(Ldrn, m.Wln); + T3 = Math.pow(Wdrn, m.Wwn); + tmp1 = m.Wl / T2 + m.Ww / T3 + m.Wwl / (T2 * T3); + dw = m.Wint + tmp1; + tmp2 = m.Wlc / T2 + m.Wwc / T3 + m.Wwlc / (T2 * T3); + dwc = m.dwc + tmp2; + + leff = L - 2.0 * dl; + weff = W - 2.0 * dw; + leffCV = L - 2.0 * dlc; + weffCV = W - 2.0 * dwc; + + if (leff <= 0.0) + throw new IllegalArgumentException("Effective channel length <= 0"); + if (weff <= 0.0) + throw new IllegalArgumentException("Effective channel width <= 0"); + if (leffCV <= 0.0) + throw new IllegalArgumentException("Effective channel length for C-V <= 0"); + if (weffCV <= 0.0) + throw new IllegalArgumentException("Effective channel width for C-V <= 0"); + + if (m.binUnit == 1) + { + Inv_L = 1.0e-6 / leff; + Inv_W = 1.0e-6 / weff; + Inv_LW = 1.0e-12 / (leff * weff); + } + else + { + Inv_L = 1.0 / leff; + Inv_W = 1.0 / weff; + Inv_LW = 1.0 / (leff * weff); + } + + cdsc = m.cdsc + + m.lcdsc * Inv_L + + m.wcdsc * Inv_W + + m.pcdsc * Inv_LW; + cdscb = m.cdscb + + m.lcdscb * Inv_L + + m.wcdscb * Inv_W + + m.pcdscb * Inv_LW; + + cdscd = m.cdscd + + m.lcdscd * Inv_L + + m.wcdscd * Inv_W + + m.pcdscd * Inv_LW; + + cit = m.cit + + m.lcit * Inv_L + + m.wcit * Inv_W + + m.pcit * Inv_LW; + nfactor = m.nfactor + + m.lnfactor * Inv_L + + m.wnfactor * Inv_W + + m.pnfactor * Inv_LW; + xj = m.xj + + m.lxj * Inv_L + + m.wxj * Inv_W + + m.pxj * Inv_LW; + vsat = m.vsat + + m.lvsat * Inv_L + + m.wvsat * Inv_W + + m.pvsat * Inv_LW; + at = m.at + + m.lat * Inv_L + + m.wat * Inv_W + + m.pat * Inv_LW; + a0 = m.a0 + + m.la0 * Inv_L + + m.wa0 * Inv_W + + m.pa0 * Inv_LW; + + ags = m.ags + + m.lags * Inv_L + + m.wags * Inv_W + + m.pags * Inv_LW; + + a1 = m.a1 + + m.la1 * Inv_L + + m.wa1 * Inv_W + + m.pa1 * Inv_LW; + a2 = m.a2 + + m.la2 * Inv_L + + m.wa2 * Inv_W + + m.pa2 * Inv_LW; + keta = m.keta + + m.lketa * Inv_L + + m.wketa * Inv_W + + m.pketa * Inv_LW; + nsub = m.nsub + + m.lnsub * Inv_L + + m.wnsub * Inv_W + + m.pnsub * Inv_LW; + npeak = m.npeak + + m.lnpeak * Inv_L + + m.wnpeak * Inv_W + + m.pnpeak * Inv_LW; + ngate = m.ngate + + m.lngate * Inv_L + + m.wngate * Inv_W + + m.pngate * Inv_LW; + gamma1 = m.gamma1 + + m.lgamma1 * Inv_L + + m.wgamma1 * Inv_W + + m.pgamma1 * Inv_LW; + gamma2 = m.gamma2 + + m.lgamma2 * Inv_L + + m.wgamma2 * Inv_W + + m.pgamma2 * Inv_LW; + vbx = m.vbx + + m.lvbx * Inv_L + + m.wvbx * Inv_W + + m.pvbx * Inv_LW; + vbm = m.vbm + + m.lvbm * Inv_L + + m.wvbm * Inv_W + + m.pvbm * Inv_LW; + xt = m.xt + + m.lxt * Inv_L + + m.wxt * Inv_W + + m.pxt * Inv_LW; + vfb = m.vfb + + m.lvfb * Inv_L + + m.wvfb * Inv_W + + m.pvfb * Inv_LW; + k1 = m.k1 + + m.lk1 * Inv_L + + m.wk1 * Inv_W + + m.pk1 * Inv_LW; + kt1 = m.kt1 + + m.lkt1 * Inv_L + + m.wkt1 * Inv_W + + m.pkt1 * Inv_LW; + kt1l = m.kt1l + + m.lkt1l * Inv_L + + m.wkt1l * Inv_W + + m.pkt1l * Inv_LW; + k2 = m.k2 + + m.lk2 * Inv_L + + m.wk2 * Inv_W + + m.pk2 * Inv_LW; + kt2 = m.kt2 + + m.lkt2 * Inv_L + + m.wkt2 * Inv_W + + m.pkt2 * Inv_LW; + k3 = m.k3 + + m.lk3 * Inv_L + + m.wk3 * Inv_W + + m.pk3 * Inv_LW; + k3b = m.k3b + + m.lk3b * Inv_L + + m.wk3b * Inv_W + + m.pk3b * Inv_LW; + w0 = m.w0 + + m.lw0 * Inv_L + + m.ww0 * Inv_W + + m.pw0 * Inv_LW; + nlx = m.nlx + + m.lnlx * Inv_L + + m.wnlx * Inv_W + + m.pnlx * Inv_LW; + dvt0 = m.dvt0 + + m.ldvt0 * Inv_L + + m.wdvt0 * Inv_W + + m.pdvt0 * Inv_LW; + dvt1 = m.dvt1 + + m.ldvt1 * Inv_L + + m.wdvt1 * Inv_W + + m.pdvt1 * Inv_LW; + dvt2 = m.dvt2 + + m.ldvt2 * Inv_L + + m.wdvt2 * Inv_W + + m.pdvt2 * Inv_LW; + dvt0w = m.dvt0w + + m.ldvt0w * Inv_L + + m.wdvt0w * Inv_W + + m.pdvt0w * Inv_LW; + dvt1w = m.dvt1w + + m.ldvt1w * Inv_L + + m.wdvt1w * Inv_W + + m.pdvt1w * Inv_LW; + dvt2w = m.dvt2w + + m.ldvt2w * Inv_L + + m.wdvt2w * Inv_W + + m.pdvt2w * Inv_LW; + drout = m.drout + + m.ldrout * Inv_L + + m.wdrout * Inv_W + + m.pdrout * Inv_LW; + dsub = m.dsub + + m.ldsub * Inv_L + + m.wdsub * Inv_W + + m.pdsub * Inv_LW; + vth0 = m.vth0 + + m.lvth0 * Inv_L + + m.wvth0 * Inv_W + + m.pvth0 * Inv_LW; + ua = m.ua + + m.lua * Inv_L + + m.wua * Inv_W + + m.pua * Inv_LW; + ua1 = m.ua1 + + m.lua1 * Inv_L + + m.wua1 * Inv_W + + m.pua1 * Inv_LW; + ub = m.ub + + m.lub * Inv_L + + m.wub * Inv_W + + m.pub * Inv_LW; + ub1 = m.ub1 + + m.lub1 * Inv_L + + m.wub1 * Inv_W + + m.pub1 * Inv_LW; + uc = m.uc + + m.luc * Inv_L + + m.wuc * Inv_W + + m.puc * Inv_LW; + uc1 = m.uc1 + + m.luc1 * Inv_L + + m.wuc1 * Inv_W + + m.puc1 * Inv_LW; + u0 = m.u0 + + m.lu0 * Inv_L + + m.wu0 * Inv_W + + m.pu0 * Inv_LW; + ute = m.ute + + m.lute * Inv_L + + m.wute * Inv_W + + m.pute * Inv_LW; + voff = m.voff + + m.lvoff * Inv_L + + m.wvoff * Inv_W + + m.pvoff * Inv_LW; + delta = m.delta + + m.ldelta * Inv_L + + m.wdelta * Inv_W + + m.pdelta * Inv_LW; + rdsw = m.rdsw + + m.lrdsw * Inv_L + + m.wrdsw * Inv_W + + m.prdsw * Inv_LW; + prwg = m.prwg + + m.lprwg * Inv_L + + m.wprwg * Inv_W + + m.pprwg * Inv_LW; + prwb = m.prwb + + m.lprwb * Inv_L + + m.wprwb * Inv_W + + m.pprwb * Inv_LW; + prt = m.prt + + m.lprt * Inv_L + + m.wprt * Inv_W + + m.pprt * Inv_LW; + eta0 = m.eta0 + + m.leta0 * Inv_L + + m.weta0 * Inv_W + + m.peta0 * Inv_LW; + etab = m.etab + + m.letab * Inv_L + + m.wetab * Inv_W + + m.petab * Inv_LW; + pclm = m.pclm + + m.lpclm * Inv_L + + m.wpclm * Inv_W + + m.ppclm * Inv_LW; + pdibl1 = m.pdibl1 + + m.lpdibl1 * Inv_L + + m.wpdibl1 * Inv_W + + m.ppdibl1 * Inv_LW; + pdibl2 = m.pdibl2 + + m.lpdibl2 * Inv_L + + m.wpdibl2 * Inv_W + + m.ppdibl2 * Inv_LW; + pdiblb = m.pdiblb + + m.lpdiblb * Inv_L + + m.wpdiblb * Inv_W + + m.ppdiblb * Inv_LW; + pscbe1 = m.pscbe1 + + m.lpscbe1 * Inv_L + + m.wpscbe1 * Inv_W + + m.ppscbe1 * Inv_LW; + pscbe2 = m.pscbe2 + + m.lpscbe2 * Inv_L + + m.wpscbe2 * Inv_W + + m.ppscbe2 * Inv_LW; + pvag = m.pvag + + m.lpvag * Inv_L + + m.wpvag * Inv_W + + m.ppvag * Inv_LW; + wr = m.wr + + m.lwr * Inv_L + + m.wwr * Inv_W + + m.pwr * Inv_LW; + dwg = m.dwg + + m.ldwg * Inv_L + + m.wdwg * Inv_W + + m.pdwg * Inv_LW; + dwb = m.dwb + + m.ldwb * Inv_L + + m.wdwb * Inv_W + + m.pdwb * Inv_LW; + b0 = m.b0 + + m.lb0 * Inv_L + + m.wb0 * Inv_W + + m.pb0 * Inv_LW; + b1 = m.b1 + + m.lb1 * Inv_L + + m.wb1 * Inv_W + + m.pb1 * Inv_LW; + alpha0 = m.alpha0 + + m.lalpha0 * Inv_L + + m.walpha0 * Inv_W + + m.palpha0 * Inv_LW; + alpha1 = m.alpha1 + + m.lalpha1 * Inv_L + + m.walpha1 * Inv_W + + m.palpha1 * Inv_LW; + beta0 = m.beta0 + + m.lbeta0 * Inv_L + + m.wbeta0 * Inv_W + + m.pbeta0 * Inv_LW; + /* CV model */ + elm = m.elm + + m.lelm * Inv_L + + m.welm * Inv_W + + m.pelm * Inv_LW; + cgsl = m.cgsl + + m.lcgsl * Inv_L + + m.wcgsl * Inv_W + + m.pcgsl * Inv_LW; + cgdl = m.cgdl + + m.lcgdl * Inv_L + + m.wcgdl * Inv_W + + m.pcgdl * Inv_LW; + ckappa = m.ckappa + + m.lckappa * Inv_L + + m.wckappa * Inv_W + + m.pckappa * Inv_LW; + cf = m.cf + + m.lcf * Inv_L + + m.wcf * Inv_W + + m.pcf * Inv_LW; + clc = m.clc + + m.lclc * Inv_L + + m.wclc * Inv_W + + m.pclc * Inv_LW; + cle = m.cle + + m.lcle * Inv_L + + m.wcle * Inv_W + + m.pcle * Inv_LW; + vfbcv = m.vfbcv + + m.lvfbcv * Inv_L + + m.wvfbcv * Inv_W + + m.pvfbcv * Inv_LW; + acde = m.acde + + m.lacde * Inv_L + + m.wacde * Inv_W + + m.pacde * Inv_LW; + moin = m.moin + + m.lmoin * Inv_L + + m.wmoin * Inv_W + + m.pmoin * Inv_LW; + noff = m.noff + + m.lnoff * Inv_L + + m.wnoff * Inv_W + + m.pnoff * Inv_LW; + voffcv = m.voffcv + + m.lvoffcv * Inv_L + + m.wvoffcv * Inv_W + + m.pvoffcv * Inv_LW; + + abulkCVfactor = 1.0 + Math.pow((clc / leffCV), cle); + + T0 = (TRatio - 1.0); + ua = ua + ua1 * T0; + ub = ub + ub1 * T0; + uc = uc + uc1 * T0; + if (u0 > 1.0) u0 = u0 / 1.0e4; + + u0temp = u0 * Math.pow(TRatio, ute); + vsattemp = vsat - at * T0; + rds0 = (rdsw + prt * T0) / Math.pow(weff * 1E6, wr); + + cgdo = (m.cgdo + cf) * weffCV; + cgso = (m.cgso + cf) * weffCV; + cgbo = m.cgbo * leffCV; + + T0 = leffCV * leffCV; + tconst = u0temp * elm / (m.cox * weffCV * leffCV * T0); + + if (!m.given(m.npeak) && m.given(m.gamma1)) + { + T0 = gamma1 * m.cox; + npeak = 3.021E22 * T0 * T0; + } + + phi = 2.0 * Vtm0 * Math.log(npeak / ni); + + sqrtPhi = Math.sqrt(phi); + phis3 = sqrtPhi * phi; + + Xdep0 = Math.sqrt(2.0 * BSim3Model.EPSSI / (BSim3Model.Charge_q * npeak * 1.0e6)) * sqrtPhi; + sqrtXdep0 = Math.sqrt(Xdep0); + litl = Math.sqrt(3.0 * xj * m.tox); + vbi = Vtm0 * Math.log(1.0e20 * npeak / (ni * ni)); + cdep0 = Math.sqrt(BSim3Model.Charge_q * BSim3Model.EPSSI * npeak * 1.0e6 / 2.0 / phi); + + ldeb = Math.sqrt(BSim3Model.EPSSI * Vtm0 / (BSim3Model.Charge_q * npeak * 1.0e6)) / 3.0; + acde *= Math.pow((npeak / 2.0e16), -0.25); + + if (m.given(m.k1) || m.given(m.k2)) + { + if (!m.given(m.k1)) + { + System.out.println("Warning: k1 should be specified with k2."); + k1 = 0.53; + } + if (!m.given(m.k2)) + { + System.out.println("Warning: k2 should be specified with k1."); + k2 = -0.0186; + } + if (m.given(m.nsub)) + System.out.println("Warning: nsub is ignored because k1 or k2 is given."); + if (m.given(m.xt)) + System.out.println("Warning: xt is ignored because k1 or k2 is given."); + if (m.given(m.vbx)) + System.out.println("Warning: vbx is ignored because k1 or k2 is given."); + if (m.given(m.gamma1)) + System.out.println("Warning: gamma1 is ignored because k1 or k2 is given."); + if (m.given(m.gamma2)) + System.out.println("Warning: gamma2 is ignored because k1 or k2 is given."); + } + else + { + if (!m.given(m.vbx)) + vbx = phi - 7.7348e-4 * npeak * xt * xt; + if (vbx > 0.0) + vbx = -vbx; + if (vbm > 0.0) + vbm = -vbm; + + if (!m.given(m.gamma1)) + gamma1 = 5.753e-12 * Math.sqrt(npeak) / m.cox; + if (!m.given(m.gamma2)) + gamma2 = 5.753e-12 * Math.sqrt(nsub) / m.cox; + + T0 = gamma1 - gamma2; + T1 = Math.sqrt(phi - vbx) - sqrtPhi; + T2 = Math.sqrt(phi * (phi - vbm)) - phi; + k2 = T0 * T1 / (2.0 * T2 + vbm); + k1 = gamma2 - 2.0 * k2 * Math.sqrt(phi - vbm); + } + + if (k2 < 0.0) + { + T0 = 0.5 * k1 / k2; + vbsc = 0.9 * (phi - T0 * T0); + if (vbsc > -3.0) + vbsc = -3.0; + else if (vbsc < -30.0) + vbsc = -30.0; + } + else + vbsc = -30.0; + + if (vbsc > vbm) + vbsc = vbm; + + if (!m.given(m.vfb)) + { + if (m.given(m.vth0)) + vfb = m.type * vth0 - phi - k1 * sqrtPhi; + else + vfb = -1.0; + } + + if (!m.given(m.vth0)) + vth0 = m.type * (vfb + phi + k1 * sqrtPhi); + + k1ox = k1 * m.tox / m.toxm; + k2ox = k2 * m.tox / m.toxm; + + T1 = Math.sqrt(BSim3Model.EPSSI / BSim3Model.EPSOX * m.tox * Xdep0); + T0 = Math.exp(-0.5 * dsub * leff / T1); + theta0vb0 = (T0 + 2.0 * T0 * T0); + + T0 = Math.exp(-0.5 * drout * leff / T1); + T2 = (T0 + 2.0 * T0 * T0); + thetaRout = pdibl1 * T2 + pdibl2; + + tmp = Math.sqrt(Xdep0); + tmp1 = vbi - phi; + tmp2 = m.factor1 * tmp; + + T0 = -0.5 * dvt1w * weff * leff / tmp2; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = BSim3Model.MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + } + T0 = dvt0w * T2; + T2 = T0 * tmp1; + + T0 = -0.5 * dvt1 * leff / tmp2; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + T3 = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = BSim3Model.MIN_EXP; + T3 = T1 * (1.0 + 2.0 * T1); + } + T3 = dvt0 * T3 * tmp1; + + T4 = m.tox * phi / (weff + w0); + + T0 = Math.sqrt(1.0 + nlx / leff); + T5 = k1ox * (T0 - 1.0) * sqrtPhi + (kt1 + kt1l / leff) * (TRatio - 1.0); + + tmp3 = m.type * vth0 - T2 - T3 + k3 * T4 + T5; + vfbzb = tmp3 - phi - k1 * sqrtPhi; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Tester.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Tester.java new file mode 100644 index 0000000000..26cdb8ce1d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Tester.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import com.avlsi.file.common.DeviceTypes; + +/** + * Class that runs device tests + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +//GGG I heard that this should extend something... +public class Tester { + public static void main (String[] args) { + System.out.println("Reading model file"); + BSim3Model.readFile("/usr/local/cad/lib/bsim3/tsmc18.bsim3", 27); + + System.out.println("Starting Device tests"); + + new ResistorTest("Source", "Drain", 1).test(); + new CapacitorTest("Source", "Drain", 1).test(); + + double length = 1.8e-6; + double width = 5 * length; + new TransistorTest(DeviceTypes.N_TYPE, + "Source", "Drain", "Gate", "Bulk", + width, length).test(); + + new DiodeTest(DeviceTypes.N_TYPE, + "Source", "Drain", + width, length, width*length, 2*(width+length)).test(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Transistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Transistor.java new file mode 100644 index 0000000000..910d344ae3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Transistor.java @@ -0,0 +1,2209 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.circuit.TransistorInterface; +/** + * Class to represent a transistor in a .aspice file. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Transistor implements DeviceInterface,TransistorInterface { + /** type of transistor (N_TYPE or P_TYPE). **/ + private final int type; + + /** Name of source node. **/ + private final HierName source; + + /** Name of drain node. **/ + private final HierName drain; + + /** Name of gate node. **/ + private final HierName gate; + + /** Name of bulk node. **/ + private final HierName bulk; + + /** Width of transistor in meters. **/ + private final double width; + + /** Length of transistor in meters. **/ + private final double length; + + /** Number of Ports */ + private static final int NUM_PORTS = 4; + + /** + * BSIM3 Device model data. + * This value will be null if no model was found. + * If so, some class methods such as evaluate() will + * generate exceptions if called. + **/ + private final BSim3Model m; + + /** + * Class constructor. Canonicalizes the source and drain node names + * by ensuring that source is lexicographically less than drain. + * @param type type of transistor, N_TYPE or P_TYPE. + * @param source name of source node + * @param drain name of drain node + * @param gate name of gate node + * @param bulk name of bulk node + * @param width of gate in meters + * @param length of gate in meters + * + * @throws IllegalArgumentException If type is bad. + **/ + + public Transistor(final int type, + final HierName source, + final HierName drain, + final HierName gate, + final HierName bulk, + final double width, + final double length) { + if (type != DeviceTypes.N_TYPE && type != DeviceTypes.P_TYPE) + throw new IllegalArgumentException("Bad fet type: " + type); + + this.type = type; + + // ensure that source <= drain, lexicographically + if (source.compareTo(drain) <= 0) { + this.source = source; + this.drain = drain; + } else { + this.source = drain; + this.drain = source; + } + + this.gate = gate; + this.bulk = bulk; + this.width = width; + this.length = length;; + + m = BSim3Model.findModel(type, width, length); + } + + /** Not implemented, returns null **/ + public HierName getName() { return null;} + + /** + * Get number of ports + * @return number of ports + **/ + public int getNumPorts() { + return NUM_PORTS; + } + + /** + * Get the type of the transistor, either N_TYPE, or P_TYPE. + * @return the type of the transistor + **/ + public int getType() { + return type; + } + + /** + * Get name of source node. + * @return name of source node + **/ + public HierName getSource() { + return source; + } + + /** + * Get name of drain node. + * @return name of drain node + **/ + public HierName getDrain() { + return drain; + } + + /** + * Get name of gate node. + * @return name of gate node + **/ + public HierName getGate() { + return gate; + } + + /** + * Get name of bulk node. + * @return name of bulk node + **/ + public HierName getBulk() { + return bulk; + } + + /** + * Get width of transistor + * @return width of transistor in meters + **/ + public double getWidth() { + return width; + } + + /** + * Get length of transistor + * @return length of transistor in meters + **/ + public double getLength() { + return length; + } + + /** + * return string suitable for inclusion in an aspice file. + **/ + public String getAspiceString() { + return (type == DeviceTypes.N_TYPE ? "nmos (" : "pmos (") + + getSource().getAspiceString() + "," + + getGate().getAspiceString() + "," + + getDrain().getAspiceString() + "," + + getBulk().getAspiceString() + ") (" + + NumberFormatter.format(getWidth()) + "," + + NumberFormatter.format(getLength()) + ");"; + } + + public String toString() { + return getAspiceString(); + } + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device for a given set of input voltages. + * @param data array of port data objects to use for return values + * @param voltage array of voltages connected to device + * @throws IllegalArgumentException If + * data.length != NUM_PORTS or + * voltage.length != NUM_PORTS. + * @return array of current/charge/etc. data for each port, + * indexed by input voltage + **/ + public PortData[] evalVoltage(PortData[] data, double[] voltage) + throws NoModelException + { + if (data.length != NUM_PORTS || voltage.length != NUM_PORTS) + throw new IllegalArgumentException("Expected " + NUM_PORTS + + " ports"); + + if (m == null) + throw new NoModelException(); + + double Vs = voltage[0]; + double Vd = voltage[1]; + double Vg = voltage[2]; + double Vb = voltage[3]; + + double qgd, qgs, qgb, VgstNVt, ExpVgst; + double Vfbeff, dVfbeff_dVg, dVfbeff_dVb, V3, V4; + double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb, gcgdb, gcggb, gcgsb, gcsdb; + double gcsgb, gcssb; + double qgate, qbulk, qdrn, qsrc, qinoi; + double Vds, Vgs, Vbs; + double Vgs_eff, Vfb; + double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd; + double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Vtm; + double n, dn_dVb, dn_dVd, voffcv, noff, dnoff_dVd, dnoff_dVb; + double ExpArg, V0, CoxWLcen, QovCox, LINK; + double DeltaPhi, dDeltaPhi_dVg, dDeltaPhi_dVd, dDeltaPhi_dVb; + double Cox, Tox, Tcen, dTcen_dVg, dTcen_dVd, dTcen_dVb; + double Ccen, Coxeff, dCoxeff_dVg, dCoxeff_dVd, dCoxeff_dVb; + double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb; + double ueff, dueff_dVg, dueff_dVd, dueff_dVb; + double Esat, Vdsat; + double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb; + double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, Vasat, dAlphaz_dVg, dAlphaz_dVb; + double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, dVa_dVd, dVa_dVg, dVa_dVb; + double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; + double Arg1, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; + double T0, dT0_dVg, dT0_dVd, dT0_dVb; + double T1, dT1_dVg, dT1_dVd, dT1_dVb; + double T2, dT2_dVg, dT2_dVd, dT2_dVb; + double T3, dT3_dVg, dT3_dVd, dT3_dVb; + double T4, T5, T6, T7, T8, T9, T10, T11, T12; + double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; + double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb; + double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb; + double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb, Delt_vth, dDelt_vth_dVb; + double Theta0, dTheta0_dVb; + double TempRatio, tmp1, tmp2, tmp3, tmp4; + double DIBL_Sft, dDIBL_Sft_dVd, Lambda, dLambda_dVg; + double a1; + + double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb; + double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; + double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; + double diffVds, dAbulk_dVg; + double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb; + double gche, dgche_dVg, dgche_dVd, dgche_dVb; + double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb; + double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb; + double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb; + double Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb; + double Ids, Gm, Gds, Gmb; + double Isub, Gbd, Gbg, Gbb; + double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb; + double CoxWovL; + double Rds, dRds_dVg, dRds_dVb, WVCox, WVCoxRds; + double Vgst2Vtm, VdsatCV, dVdsatCV_dVg, dVdsatCV_dVb; + double Leff, Weff, dWeff_dVg, dWeff_dVb; + double AbulkCV, dAbulkCV_dVb; + double qgdo, qgso, cgdo, cgso; + + double Cgg, Cgd, Cgb; + double Csg, Csd, Csb, Cbg, Cbd, Cbb; + double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0; + double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; + + double thetavth; + + double cggb, cgsb, cgdb, cdgb, cdsb, cddb, cbgb, cbsb, cbdb; + double qinv; + double vgd, vgs, vgb; + + int Tmode, nS, nD; + + + final SizedModel s = SizedModel.newSizedModel(m, width, length); + + /* convert voltages to NMOS conventions */ + Vs *= m.type; + Vd *= m.type; + Vg *= m.type; + Vb *= m.type; + + /* unadulterated voltage differences */ + vgd = Vg - Vd; + vgs = Vg - Vs; + vgb = Vg - Vb; + + /* swap s/d so Vds >=0 */ + if (Vd >= Vs) + { + Tmode = 1; + Vds = Vd - Vs; + Vgs = Vg - Vs; + Vbs = Vb - Vs; + nS = 0; + nD = 1; + } + else + { + Tmode = -1; + Vds = Vs - Vd; + Vgs = Vg - Vd; + Vbs = Vb - Vd; + nS = 1; + nD = 0; + } + + /* compute Vbseff */ + T0 = Vbs - s.vbsc - 0.001; + T1 = Math.sqrt(T0 * T0 - 0.004 * s.vbsc); + Vbseff = s.vbsc + 0.5 * (T0 + T1); + dVbseff_dVb = 0.5 * (1.0 + T0 / T1); + if (Vbseff < Vbs) + Vbseff = Vbs; + + if (Vbseff > 0.0) + { + T0 = s.phi / (s.phi + Vbseff); + Phis = s.phi * T0; + dPhis_dVb = -T0 * T0; + sqrtPhis = s.phis3 / (s.phi + 0.5 * Vbseff); + dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / s.phis3; + } + else + { + Phis = s.phi - Vbseff; + dPhis_dVb = -1.0; + sqrtPhis = Math.sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + } + + /* compute Xdep */ + Xdep = s.Xdep0 * sqrtPhis / s.sqrtPhi; + dXdep_dVb = (s.Xdep0 / s.sqrtPhi) * dsqrtPhis_dVb; + + /* grab Leff and Vtm */ + Leff = s.leff; + Vtm = m.vtm; + + /* Vth Calculation */ + T3 = Math.sqrt(Xdep); + V0 = s.vbi - s.phi; + + T0 = s.dvt2 * Vbseff; + if (T0 >= - 0.5) + { + T1 = 1.0 + T0; + T2 = s.dvt2; + } + else + { + /* Added to avoid any discontinuity problems caused by dvt2 */ + T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = s.dvt2 * T4 * T4; + } + lt1 = m.factor1 * T3 * T1; + dlt1_dVb = m.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = s.dvt2w * Vbseff; + if (T0 >= - 0.5) + { + T1 = 1.0 + T0; + T2 = s.dvt2w; + } + else + { + /* Added to avoid any discontinuity problems caused by dvt2w */ + T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = s.dvt2w * T4 * T4; + } + ltw = m.factor1 * T3 * T1; + dltw_dVb = m.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = -0.5 * s.dvt1 * Leff / lt1; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + Theta0 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { + T1 = BSim3Model.MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + + thetavth = s.dvt0 * Theta0; + Delt_vth = thetavth * V0; + dDelt_vth_dVb = s.dvt0 * dTheta0_dVb * V0; + + T0 = -0.5 * s.dvt1w * s.weff * Leff / ltw; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { + T1 = BSim3Model.MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + + T0 = s.dvt0w * T2; + T2 = T0 * V0; + dT2_dVb = s.dvt0w * dT2_dVb * V0; + + TempRatio = m.temp / m.tnom - 1.0; + T0 = Math.sqrt(1.0 + s.nlx / Leff); + T1 = s.k1ox * (T0 - 1.0) * s.sqrtPhi + + (s.kt1 + s.kt1l / Leff + s.kt2 * Vbseff) * TempRatio; + tmp2 = m.tox * s.phi / (s.weff + s.w0); + + T3 = s.eta0 + s.etab * Vbseff; + if (T3 < 1.0e-4) + { + /* avoid discontinuity problems caused by etab */ + T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9; + } + else + T4 = 1.0; + dDIBL_Sft_dVd = T3 * s.theta0vb0; + DIBL_Sft = dDIBL_Sft_dVd * Vds; + + Vth = m.type * s.vth0 - s.k1 * s.sqrtPhi + s.k1ox * sqrtPhis + - s.k2ox * Vbseff - Delt_vth - T2 + + (s.k3 + s.k3b * Vbseff) * tmp2 + T1 - DIBL_Sft; + + dVth_dVb = s.k1ox * dsqrtPhis_dVb - s.k2ox + - dDelt_vth_dVb - dT2_dVb + s.k3b * tmp2 + - s.etab * Vds * s.theta0vb0 * T4 + s.kt2 * TempRatio; + dVth_dVd = -dDIBL_Sft_dVd; + + /* Calculate n */ + tmp2 = s.nfactor * BSim3Model.EPSSI / Xdep; + tmp3 = s.cdsc + s.cdscb * Vbseff + s.cdscd * Vds; + tmp4 = (tmp2 + tmp3 * Theta0 + s.cit) / m.cox; + if (tmp4 >= -0.5) + { + n = 1.0 + tmp4; + dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + s.cdscb * Theta0) / m.cox; + dn_dVd = s.cdscd * Theta0 / m.cox; + } + else + { + /* avoid discontinuity problems caused by tmp4 */ + T0 = 1.0 / (3.0 + 8.0 * tmp4); + n = (1.0 + 3.0 * tmp4) * T0; + T0 *= T0; + dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + + s.cdscb * Theta0) / m.cox * T0; + dn_dVd = s.cdscd * Theta0 / m.cox * T0; + } + + /* Poly Gate Si Depletion Effect */ + T0 = s.vfb + s.phi; + if ((s.ngate > 1.e18) && (s.ngate < 1.e25) && (Vgs > T0)) + { + /* added to avoid the problem caused by ngate */ + T1 = 1.0e6 * BSim3Model.Charge_q * BSim3Model.EPSSI * s.ngate / (m.cox * m.cox); + T4 = Math.sqrt(1.0 + 2.0 * (Vgs - T0) / T1); + T2 = T1 * (T4 - 1.0); + T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */ + T7 = 1.12 - T3 - 0.05; + T6 = Math.sqrt(T7 * T7 + 0.224); + T5 = 1.12 - 0.5 * (T7 + T6); + Vgs_eff = Vgs - T5; + dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); + } + else + { + Vgs_eff = Vgs; + dVgs_eff_dVg = 1.0; + } + Vgst = Vgs_eff - Vth; + + /* Effective Vgst (Vgsteff) Calculation */ + T10 = 2.0 * n * Vtm; + VgstNVt = Vgst / T10; + ExpArg = (2.0 * s.voff - Vgst) / T10; + + /* MCJ: Very small Vgst */ + if (VgstNVt > BSim3Model.EXP_THRESHOLD) + { + Vgsteff = Vgst; + dVgsteff_dVg = dVgs_eff_dVg; + dVgsteff_dVd = -dVth_dVd; + dVgsteff_dVb = -dVth_dVb; + } + else if (ExpArg > BSim3Model.EXP_THRESHOLD) + { + T0 = (Vgst - s.voff) / (n * Vtm); + ExpVgst = Math.exp(T0); + Vgsteff = Vtm * s.cdep0 / m.cox * ExpVgst; + dVgsteff_dVg = Vgsteff / (n * Vtm); + dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * Vtm * dn_dVd); + dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * Vtm * dn_dVb); + dVgsteff_dVg *= dVgs_eff_dVg; + } + else + { + ExpVgst = Math.exp(VgstNVt); + T1 = T10 * Math.log(1.0 + ExpVgst); + dT1_dVg = ExpVgst / (1.0 + ExpVgst); + dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb; + dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd; + + dT2_dVg = -m.cox / (Vtm * s.cdep0) * Math.exp(ExpArg); + T2 = 1.0 - T10 * dT2_dVg; + dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd) + + (T2 - 1.0) / n * dn_dVd; + dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb) + + (T2 - 1.0) / n * dn_dVb; + + Vgsteff = T1 / T2; + T3 = T2 * T2; + dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg; + dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3; + dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; + } + + /* Calculate Effective Channel Geometry */ + T9 = sqrtPhis - s.sqrtPhi; + Weff = s.weff - 2.0 * (s.dwg * Vgsteff + s.dwb * T9); + dWeff_dVg = -2.0 * s.dwg; + dWeff_dVb = -2.0 * s.dwb * dsqrtPhis_dVb; + + if (Weff < 2.0e-8) + { + /* to avoid the discontinuity problem due to Weff*/ + T0 = 1.0 / (6.0e-8 - 2.0 * Weff); + Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; + T0 *= T0 * 4.0e-16; + dWeff_dVg *= T0; + dWeff_dVb *= T0; + } + + T0 = s.prwg * Vgsteff + s.prwb * T9; + if (T0 >= -0.9) + { + Rds = s.rds0 * (1.0 + T0); + dRds_dVg = s.rds0 * s.prwg; + dRds_dVb = s.rds0 * s.prwb * dsqrtPhis_dVb; + } + else + { + /* to avoid the discontinuity problem due to prwg and prwb*/ + T1 = 1.0 / (17.0 + 20.0 * T0); + Rds = s.rds0 * (0.8 + T0) * T1; + T1 *= T1; + dRds_dVg = s.rds0 * s.prwg * T1; + dRds_dVb = s.rds0 * s.prwb * dsqrtPhis_dVb * T1; + } + + /* Calculate Abulk */ + T1 = 0.5 * s.k1ox / sqrtPhis; + dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb; + + T9 = Math.sqrt(s.xj * Xdep); + tmp1 = Leff + 2.0 * T9; + T5 = Leff / tmp1; + tmp2 = s.a0 * T5; + tmp3 = s.weff + s.b1; + tmp4 = s.b0 / tmp3; + T2 = tmp2 + tmp4; + dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb; + T6 = T5 * T5; + T7 = T5 * T6; + + Abulk0 = 1.0 + T1 * T2; + dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb; + + T8 = s.ags * s.a0 * T7; + dAbulk_dVg = -T1 * T8; + Abulk = Abulk0 + dAbulk_dVg * Vgsteff; + dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb + 3.0 * T1 * dT2_dVb); + + if (Abulk0 < 0.1) + { + /* added to avoid the problems caused by Abulk0 */ + T9 = 1.0 / (3.0 - 20.0 * Abulk0); + Abulk0 = (0.2 - Abulk0) * T9; + dAbulk0_dVb *= T9 * T9; + } + + if (Abulk < 0.1) + { + /* added to avoid the problems caused by Abulk */ + T9 = 1.0 / (3.0 - 20.0 * Abulk); + Abulk = (0.2 - Abulk) * T9; + T10 = T9 * T9; + dAbulk_dVb *= T10; + dAbulk_dVg *= T10; + } + + T2 = s.keta * Vbseff; + if (T2 >= -0.9) + { + T0 = 1.0 / (1.0 + T2); + dT0_dVb = -s.keta * T0 * T0; + } + else + { + /* added to avoid the problems caused by Keta */ + T1 = 1.0 / (0.8 + T2); + T0 = (17.0 + 20.0 * T2) * T1; + dT0_dVb = -s.keta * T1 * T1; + } + dAbulk_dVg *= T0; + dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; + dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; + Abulk *= T0; + Abulk0 *= T0; + + + /* Mobility calculation */ + if (m.mobMod == 1) + { + T0 = Vgsteff + Vth + Vth; + T2 = s.ua + s.uc * Vbseff; + T3 = T0 / m.tox; + T5 = T3 * (T2 + s.ub * T3); + dDenomi_dVg = (T2 + 2.0 * s.ub * T3) / m.tox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + s.uc * T3; + } + else if (m.mobMod == 2) + { + T5 = Vgsteff / m.tox * (s.ua + s.uc * Vbseff + s.ub * Vgsteff / m.tox); + dDenomi_dVg = (s.ua + s.uc * Vbseff + 2.0 * s.ub * Vgsteff / m.tox) / m.tox; + dDenomi_dVd = 0.0; + dDenomi_dVb = Vgsteff * s.uc / m.tox; + } + else + { + T0 = Vgsteff + Vth + Vth; + T2 = 1.0 + s.uc * Vbseff; + T3 = T0 / m.tox; + T4 = T3 * (s.ua + s.ub * T3); + T5 = T4 * T2; + dDenomi_dVg = (s.ua + 2.0 * s.ub * T3) * T2 / m.tox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + s.uc * T4; + } + + if (T5 >= -0.8) + Denomi = 1.0 + T5; + else + { + /* Added to avoid the discontinuity problem caused by ua and ub*/ + T9 = 1.0 / (7.0 + 10.0 * T5); + Denomi = (0.6 + T5) * T9; + T9 *= T9; + dDenomi_dVg *= T9; + dDenomi_dVd *= T9; + dDenomi_dVb *= T9; + } + + ueff = s.u0temp / Denomi; + T9 = -ueff / Denomi; + dueff_dVg = T9 * dDenomi_dVg; + dueff_dVd = T9 * dDenomi_dVd; + dueff_dVb = T9 * dDenomi_dVb; + + /* Saturation Drain Voltage Vdsat */ + WVCox = Weff * s.vsattemp * m.cox; + WVCoxRds = WVCox * Rds; + + Esat = 2.0 * s.vsattemp / ueff; + EsatL = Esat * Leff; + T0 = -EsatL /ueff; + dEsatL_dVg = T0 * dueff_dVg; + dEsatL_dVd = T0 * dueff_dVd; + dEsatL_dVb = T0 * dueff_dVb; + + /* Sqrt() */ + a1 = s.a1; + if (a1 == 0.0) + { + Lambda = s.a2; + dLambda_dVg = 0.0; + } + else if (a1 > 0.0) + { + /* Added to avoid the discontinuity problem caused by a1 and a2 (Lambda) */ + T0 = 1.0 - s.a2; + T1 = T0 - s.a1 * Vgsteff - 0.0001; + T2 = Math.sqrt(T1 * T1 + 0.0004 * T0); + Lambda = s.a2 + T0 - 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * s.a1 * (1.0 + T1 / T2); + } + else + { + T1 = s.a2 + s.a1 * Vgsteff - 0.0001; + T2 = Math.sqrt(T1 * T1 + 0.0004 * s.a2); + Lambda = 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * s.a1 * (1.0 + T1 / T2); + } + + Vgst2Vtm = Vgsteff + 2.0 * Vtm; + if (Rds > 0) + { + tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; + tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; + } + else + { + tmp2 = dWeff_dVg / Weff; + tmp3 = dWeff_dVb / Weff; + } + if ((Rds == 0.0) && (Lambda == 1.0)) + { + T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm); + tmp1 = 0.0; + T1 = T0 * T0; + T2 = Vgst2Vtm * T0; + T3 = EsatL * Vgst2Vtm; + Vdsat = T3 * T0; + + dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1; + dT0_dVd = -(Abulk * dEsatL_dVd) * T1; + dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1; + + dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; + dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; + dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; + } + else + { + tmp1 = dLambda_dVg / (Lambda * Lambda); + T9 = Abulk * WVCoxRds; + T8 = Abulk * T9; + T7 = Vgst2Vtm * T9; + T6 = Vgst2Vtm * WVCoxRds; + T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda); + dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1 + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg); + + dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3) + + (1.0 / Lambda - 1.0) * dAbulk_dVb); + dT0_dVd = 0.0; + T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7; + + dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 + * (T9 + T7 * tmp2 + T6 * dAbulk_dVg); + dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb + + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3); + dT1_dVd = Abulk * dEsatL_dVd; + + T2 = Vgst2Vtm * (EsatL + 2.0 * T6); + dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); + dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); + dT2_dVd = Vgst2Vtm * dEsatL_dVd; + + T3 = Math.sqrt(T1 * T1 - 2.0 * T0 * T2); + Vdsat = (T1 - T3) / T0; + + dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg)) / T3; + dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd)) / T3; + dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb)) / T3; + + dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 + - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; + dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 + - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; + dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; + } + + /* Effective Vds (Vdseff) Calculation */ + T1 = Vdsat - Vds - s.delta; + dT1_dVg = dVdsat_dVg; + dT1_dVd = dVdsat_dVd - 1.0; + dT1_dVb = dVdsat_dVb; + + T2 = Math.sqrt(T1 * T1 + 4.0 * s.delta * Vdsat); + T0 = T1 / T2; + T3 = 2.0 * s.delta / T2; + dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; + dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; + dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; + + Vdseff = Vdsat - 0.5 * (T1 + T2); + dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); + dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); + dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); + if (Vds == 0.0) + { + /* Added to eliminate non-zero Vdseff at Vds=0.0 */ + Vdseff = 0.0; + dVdseff_dVg = 0.0; + dVdseff_dVb = 0.0; + } + + /* Calculate VAsat */ + tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; + T9 = WVCoxRds * Vgsteff; + T8 = T9 / Vgst2Vtm; + T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; + + T7 = 2.0 * WVCoxRds * tmp4; + dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff) + - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm + Vdsat * dAbulk_dVg); + + dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff + - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); + dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd; + + T9 = WVCoxRds * Abulk; + T1 = 2.0 / Lambda - 1.0 + T9; + dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg); + dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3; + + Vasat = T0 / T1; + dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; + dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; + dVasat_dVd = dT0_dVd / T1; + + if (Vdseff > Vds) + Vdseff = Vds; + diffVds = Vds - Vdseff; + + /* Calculate VACLM */ + if ((s.pclm > 0.0) && (diffVds > 1.0e-10)) + { + T0 = 1.0 / (s.pclm * Abulk * s.litl); + dT0_dVb = -T0 / Abulk * dAbulk_dVb; + dT0_dVg = -T0 / Abulk * dAbulk_dVg; + + T2 = Vgsteff / EsatL; + T1 = Leff * (Abulk + T2); + dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg); + dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL); + dT1_dVd = -T2 * dEsatL_dVd / Esat; + + T9 = T0 * T1; + VACLM = T9 * diffVds; + dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + T1 * diffVds * dT0_dVg; + dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds - T9 * dVdseff_dVb; + dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); + } + else + { + VACLM = BSim3Model.MAX_EXP; + dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0; + } + + /* Calculate VADIBL */ + if (s.thetaRout > 0.0) + { + T8 = Abulk * Vdsat; + T0 = Vgst2Vtm * T8; + dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8 + Vgst2Vtm * Vdsat * dAbulk_dVg; + dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); + dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd; + + T1 = Vgst2Vtm + T8; + dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg; + dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat; + dT1_dVd = Abulk * dVdsat_dVd; + + T9 = T1 * T1; + T2 = s.thetaRout; + VADIBL = (Vgst2Vtm - T0 / T1) / T2; + dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; + dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; + dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; + + T7 = s.pdiblb * Vbseff; + if (T7 >= -0.9) + { + T3 = 1.0 / (1.0 + T7); + VADIBL *= T3; + dVADIBL_dVg *= T3; + dVADIBL_dVb = (dVADIBL_dVb - VADIBL * s.pdiblb) * T3; + dVADIBL_dVd *= T3; + } + else + { + /* Added to avoid the discontinuity problem caused by pdiblcb */ + T4 = 1.0 / (0.8 + T7); + T3 = (17.0 + 20.0 * T7) * T4; + dVADIBL_dVg *= T3; + dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * s.pdiblb * T4 * T4; + dVADIBL_dVd *= T3; + VADIBL *= T3; + } + } + else + { + VADIBL = BSim3Model.MAX_EXP; + dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0; + } + + /* Calculate VA */ + T8 = s.pvag / EsatL; + T9 = T8 * Vgsteff; + if (T9 > -0.9) + { + T0 = 1.0 + T9; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL); + dT0_dVb = -T9 * dEsatL_dVb / EsatL; + dT0_dVd = -T9 * dEsatL_dVd / EsatL; + } + else + { + /* Added to avoid the discontinuity problems caused by pvag */ + T1 = 1.0 / (17.0 + 20.0 * T9); + T0 = (0.8 + T9) * T1; + T1 *= T1; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1; + + T9 *= T1 / EsatL; + dT0_dVb = -T9 * dEsatL_dVb; + dT0_dVd = -T9 * dEsatL_dVd; + } + + tmp1 = VACLM * VACLM; + tmp2 = VADIBL * VADIBL; + tmp3 = VACLM + VADIBL; + + T1 = VACLM * VADIBL / tmp3; + tmp3 *= tmp3; + dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; + dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; + dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; + + Va = Vasat + T0 * T1; + dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; + dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; + dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; + + /* Calculate VASCBE */ + if (s.pscbe2 > 0.0) + { + if (diffVds > s.pscbe1 * s.litl / BSim3Model.EXP_THRESHOLD) + { + T0 = s.pscbe1 * s.litl / diffVds; + VASCBE = Leff * Math.exp(T0) / s.pscbe2; + T1 = T0 * VASCBE / diffVds; + dVASCBE_dVg = T1 * dVdseff_dVg; + dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd); + dVASCBE_dVb = T1 * dVdseff_dVb; + } + else + { + VASCBE = BSim3Model.MAX_EXP * Leff/s.pscbe2; + dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; + } + } + else + { + VASCBE = BSim3Model.MAX_EXP; + dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; + } + + /* Calculate Ids */ + CoxWovL = m.cox * Weff / Leff; + beta = ueff * CoxWovL; + dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; + dbeta_dVd = CoxWovL * dueff_dVd; + dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; + + T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm; + dT0_dVg = -0.5 * (Abulk * dVdseff_dVg + - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm; + dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm; + dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff) / Vgst2Vtm; + + fgche1 = Vgsteff * T0; + dfgche1_dVg = Vgsteff * dT0_dVg + T0; + dfgche1_dVd = Vgsteff * dT0_dVd; + dfgche1_dVb = Vgsteff * dT0_dVb; + + T9 = Vdseff / EsatL; + fgche2 = 1.0 + T9; + dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; + dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; + dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; + + gche = beta * fgche1 / fgche2; + dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg + - gche * dfgche2_dVg) / fgche2; + dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd + - gche * dfgche2_dVd) / fgche2; + dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb + - gche * dfgche2_dVb) / fgche2; + + T0 = 1.0 + gche * Rds; + T9 = Vdseff / T0; + Idl = gche * T9; + + dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 + - Idl * gche / T0 * dRds_dVg ; + + dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; + dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb - Idl * dRds_dVb * gche) / T0; + + T9 = diffVds / Va; + T0 = 1.0 + T9; + Idsa = Idl * T0; + dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; + dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd - T9 * dVa_dVd) / Va; + dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; + + T9 = diffVds / VASCBE; + T0 = 1.0 + T9; + Ids = Idsa * T0; + + Gm = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE; + Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd - T9 * dVASCBE_dVd) / VASCBE; + Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb + T9 * dVASCBE_dVb) / VASCBE; + + Gds += Gm * dVgsteff_dVd; + Gmb += Gm * dVgsteff_dVb; + Gm *= dVgsteff_dVg; + Gmb *= dVbseff_dVb; + + /* Substrate current begins */ + tmp = s.alpha0 + s.alpha1 * Leff; + if ((tmp <= 0.0) || (s.beta0 <= 0.0)) + Isub = Gbd = Gbb = Gbg = 0.0; + else + { + T2 = tmp / Leff; + if (diffVds > s.beta0 / BSim3Model.EXP_THRESHOLD) + { + T0 = -s.beta0 / diffVds; + T1 = T2 * diffVds * Math.exp(T0); + T3 = T1 / diffVds * (T0 - 1.0); + dT1_dVg = T3 * dVdseff_dVg; + dT1_dVd = T3 * (dVdseff_dVd - 1.0); + dT1_dVb = T3 * dVdseff_dVb; + } + else + { + T3 = T2 * BSim3Model.MIN_EXP; + T1 = T3 * diffVds; + dT1_dVg = -T3 * dVdseff_dVg; + dT1_dVd = T3 * (1.0 - dVdseff_dVd); + dT1_dVb = -T3 * dVdseff_dVb; + } + Isub = T1 * Idsa; + Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg; + Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd; + Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb; + + Gbd += Gbg * dVgsteff_dVd; + Gbb += Gbg * dVgsteff_dVb; + Gbg *= dVgsteff_dVg; + Gbb *= dVbseff_dVb; /* bug fixing */ + } + + /* Charge/Capacitance computation begins */ + qgate = qdrn = qsrc = qbulk = 0.0; + cggb = cgsb = cgdb = 0.0; + cdgb = cdsb = cddb = 0.0; + cbgb = cbsb = cbdb = 0.0; + if (m.xpart >= 0 && m.capMod == 0) + { + if (Vbseff < 0.0) + { + Vbseff = Vbs; + dVbseff_dVb = 1.0; + } + else + { + Vbseff = s.phi - Phis; + dVbseff_dVb = -dPhis_dVb; + } + + Vfb = s.vfbcv; + Vth = Vfb + s.phi + s.k1ox * sqrtPhis; + Vgst = Vgs_eff - Vth; + dVth_dVb = s.k1ox * dsqrtPhis_dVb; + dVgst_dVb = -dVth_dVb; + dVgst_dVg = dVgs_eff_dVg; + + CoxWL = m.cox * s.weffCV * s.leffCV; + Arg1 = Vgs_eff - Vbseff - Vfb; + + if (Arg1 <= 0.0) + { + qgate = CoxWL * Arg1; + qbulk = -qgate; + qdrn = 0.0; + + cggb = CoxWL * dVgs_eff_dVg; + cgdb = 0.0; + cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg); + + cdgb = 0.0; + cddb = 0.0; + cdsb = 0.0; + + cbgb = -CoxWL * dVgs_eff_dVg; + cbdb = 0.0; + cbsb = -cgsb; + qinv = 0.0; + } + else if (Vgst <= 0.0) + { + T1 = 0.5 * s.k1ox; + T2 = Math.sqrt(T1 * T1 + Arg1); + qgate = CoxWL * s.k1ox * (T2 - T1); + qbulk = -qgate; + qdrn = 0.0; + + T0 = CoxWL * T1 / T2; + cggb = T0 * dVgs_eff_dVg; + cgdb = 0.0; + cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg); + + cdgb = 0.0; + cddb = 0.0; + cdsb = 0.0; + + cbgb = -cggb; + cbdb = 0.0; + cbsb = -cgsb; + qinv = 0.0; + } + else + { + One_Third_CoxWL = CoxWL / 3.0; + Two_Third_CoxWL = 2.0 * One_Third_CoxWL; + + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + Vdsat = Vgst / AbulkCV; + dVdsat_dVg = dVgs_eff_dVg / AbulkCV; + dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV; + + if (m.xpart > 0.5) + { + /* 0/100 Charge partition model */ + if (Vdsat <= Vds) + { + /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.0; + + cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + cgsb = -(cggb + T2); + cgdb = 0.0; + + cdgb = 0.0; + cddb = 0.0; + cdsb = 0.0; + + cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + cbsb = -(cbgb + T3); + cbdb = 0.0; + qinv = -(qgate + qbulk); + } + else + { + /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + T7 = 2.0 * Vds - T1 - 3.0 * T3; + T8 = T3 - T1 - 2.0 * Vds; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - 0.5 * (Vds - T3)); + T10 = T4 * T8; + qdrn = T4 * T7; + qbulk = -(qgate + qdrn + T10); + + T5 = T3 / T1; + cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; + T11 = -CoxWL * T5 * dVdsat_dVb; + cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); + cgsb = -(cggb + T11 + cgdb); + T6 = 1.0 / Vdsat; + dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); + dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); + T7 = T9 * T7; + T8 = T9 * T8; + T9 = 2.0 * T4 * (1.0 - 3.0 * T5); + cdgb = (T7 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; + T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb; + cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5); + cdsb = -(cdgb + T12 + cddb); + + T9 = 2.0 * T4 * (1.0 + T5); + T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; + T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb; + T12 = T4 * (2.0 * T2 + T5 - 1.0); + T0 = -(T10 + T11 + T12); + + cbgb = -(cggb + cdgb + T10); + cbdb = -(cgdb + cddb + T12); + cbsb = -(cgsb + cdsb + T0); + qinv = -(qgate + qbulk); + } + } + else if (m.xpart < 0.5) + { + /* 40/60 Charge partition model */ + if (Vds >= Vdsat) + { + /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb + - s.phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.4 * T2; + + cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + cgsb = -(cggb + T2); + cgdb = 0.0; + + T3 = 0.4 * Two_Third_CoxWL; + cdgb = -T3 * dVgs_eff_dVg; + cddb = 0.0; + T4 = T3 * dVth_dVb; + cdsb = -(T4 + cdgb); + + cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + cbsb = -(cbgb + T3); + cbdb = 0.0; + qinv = -(qgate + qbulk); + } + else + { + /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - 0.5 * (Vds - T3)); + + T5 = T3 / T1; + cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; + tmp = -CoxWL * T5 * dVdsat_dVb; + cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); + cgsb = -(cggb + cgdb + tmp); + + T6 = 1.0 / Vdsat; + dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); + dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); + + T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds + 1.2 * Vds * Vds; + T8 = T2 / T1; + T7 = Vds - T1 - T8 * T6; + qdrn = T4 * T7; + T7 *= T9; + tmp = T8 / T1; + tmp1 = T4 * (2.0 - 4.0 * tmp * T6 + T8 * (16.0 * Vdsat - 6.0 * Vds)); + + cdgb = (T7 * dAlphaz_dVg - tmp1 * dVdsat_dVg) * dVgs_eff_dVg; + T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb; + cddb = T4 * (2.0 - (1.0 / (3.0 * T1 * T1) + 2.0 * tmp) * T6 + T8 + * (6.0 * Vdsat - 2.4 * Vds)); + cdsb = -(cdgb + T10 + cddb); + + T7 = 2.0 * (T1 + T3); + qbulk = -(qgate - T4 * T7); + T7 *= T9; + T0 = 4.0 * T4 * (1.0 - T5); + T12 = (-T7 * dAlphaz_dVg - cdgb - T0 * dVdsat_dVg) * dVgs_eff_dVg; + T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb; + T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5) - cddb; + tmp = -(T10 + T11 + T12); + + cbgb = -(cggb + cdgb + T12); + cbdb = -(cgdb + cddb + T11); + cbsb = -(cgsb + cdsb + tmp); + qinv = -(qgate + qbulk); + } + } + else + { + /* 50/50 partitioning */ + if (Vds >= Vdsat) + { + /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.5 * T2; + + cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + cgsb = -(cggb + T2); + cgdb = 0.0; + + cdgb = -One_Third_CoxWL * dVgs_eff_dVg; + cddb = 0.0; + T4 = One_Third_CoxWL * dVth_dVb; + cdsb = -(T4 + cdgb); + + cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + cbsb = -(cbgb + T3); + cbdb = 0.0; + qinv = -(qgate + qbulk); + } + else + { + /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - 0.5 * (Vds - T3)); + + T5 = T3 / T1; + cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; + tmp = -CoxWL * T5 * dVdsat_dVb; + cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); + cgsb = -(cggb + cgdb + tmp); + + T6 = 1.0 / Vdsat; + dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); + dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); + + T7 = T1 + T3; + qdrn = -T4 * T7; + qbulk = - (qgate + qdrn + qdrn); + T7 *= T9; + T0 = T4 * (2.0 * T5 - 2.0); + + cdgb = (T0 * dVdsat_dVg - T7 * dAlphaz_dVg) * dVgs_eff_dVg; + T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb; + cddb = T4 * (1.0 - 2.0 * T2 - T5); + cdsb = -(cdgb + T12 + cddb); + + cbgb = -(cggb + 2.0 * cdgb); + cbdb = -(cgdb + 2.0 * cddb); + cbsb = -(cgsb + 2.0 * cdsb); + qinv = -(qgate + qbulk); + } + } + } + } + else if (m.xpart >= 0) + { + if (Vbseff < 0.0) + { + VbseffCV = Vbseff; + dVbseffCV_dVb = 1.0; + } + else + { + VbseffCV = s.phi - Phis; + dVbseffCV_dVb = -dPhis_dVb; + } + + CoxWL = m.cox * s.weffCV * s.leffCV; + + /* Seperate VgsteffCV with noff and voffcv */ + noff = n * s.noff; + dnoff_dVd = s.noff * dn_dVd; + dnoff_dVb = s.noff * dn_dVb; + T0 = Vtm * noff; + voffcv = s.voffcv; + VgstNVt = (Vgst - voffcv) / T0; + + if (VgstNVt > BSim3Model.EXP_THRESHOLD) + { + Vgsteff = Vgst - voffcv; + dVgsteff_dVg = dVgs_eff_dVg; + dVgsteff_dVd = -dVth_dVd; + dVgsteff_dVb = -dVth_dVb; + } + else if (VgstNVt < -BSim3Model.EXP_THRESHOLD) + { + Vgsteff = T0 * Math.log(1.0 + BSim3Model.MIN_EXP); + dVgsteff_dVg = 0.0; + dVgsteff_dVd = Vgsteff / noff; + dVgsteff_dVb = dVgsteff_dVd * dnoff_dVb; + dVgsteff_dVd *= dnoff_dVd; + } + else + { + ExpVgst = Math.exp(VgstNVt); + Vgsteff = T0 * Math.log(1.0 + ExpVgst); + dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst); + dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgst - voffcv) + / noff * dnoff_dVd) + Vgsteff / noff * dnoff_dVd; + dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgst - voffcv) + / noff * dnoff_dVb) + Vgsteff / noff * dnoff_dVb; + dVgsteff_dVg *= dVgs_eff_dVg; + } /* End of VgsteffCV */ + + if (m.capMod == 1) + { + Vfb = s.vfbzb; + Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff; + + if (Arg1 <= 0.0) + { + qgate = CoxWL * Arg1; + Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg); + Cgd = -CoxWL * dVgsteff_dVd; + Cgb = -CoxWL * (dVbseffCV_dVb + dVgsteff_dVb); + } + else + { + T0 = 0.5 * s.k1ox; + T1 = Math.sqrt(T0 * T0 + Arg1); + T2 = CoxWL * T0 / T1; + + qgate = CoxWL * s.k1ox * (T1 - T0); + + Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg); + Cgd = -T2 * dVgsteff_dVd; + Cgb = -T2 * (dVbseffCV_dVb + dVgsteff_dVb); + } + qbulk = -qgate; + Cbg = -Cgg; + Cbd = -Cgd; + Cbb = -Cgb; + + One_Third_CoxWL = CoxWL / 3.0; + Two_Third_CoxWL = 2.0 * One_Third_CoxWL; + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + VdsatCV = Vgsteff / AbulkCV; + if (VdsatCV < Vds) + { + dVdsatCV_dVg = 1.0 / AbulkCV; + dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; + T0 = Vgsteff - VdsatCV / 3.0; + dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0; + dT0_dVb = -dVdsatCV_dVb / 3.0; + qgate += CoxWL * T0; + Cgg1 = CoxWL * dT0_dVg; + Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb; + Cgd1 = Cgg1 * dVgsteff_dVd; + Cgg1 *= dVgsteff_dVg; + Cgg += Cgg1; + Cgb += Cgb1; + Cgd += Cgd1; + + T0 = VdsatCV - Vgsteff; + dT0_dVg = dVdsatCV_dVg - 1.0; + dT0_dVb = dVdsatCV_dVb; + qbulk += One_Third_CoxWL * T0; + Cbg1 = One_Third_CoxWL * dT0_dVg; + Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb; + Cbd1 = Cbg1 * dVgsteff_dVd; + Cbg1 *= dVgsteff_dVg; + Cbg += Cbg1; + Cbb += Cbb1; + Cbd += Cbd1; + + if (m.xpart > 0.5) + T0 = -Two_Third_CoxWL; + else if (m.xpart < 0.5) + T0 = -0.4 * CoxWL; + else + T0 = -One_Third_CoxWL; + + qsrc = T0 * Vgsteff; + Csg = T0 * dVgsteff_dVg; + Csb = T0 * dVgsteff_dVb; + Csd = T0 * dVgsteff_dVd; + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + } + else + { + T0 = AbulkCV * Vds; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20); + T2 = Vds / T1; + T3 = T0 * T2; + dT3_dVg = -12.0 * T2 * T2 * AbulkCV; + dT3_dVd = 6.0 * T0 * (4.0 * Vgsteff - T0) / T1 / T1 - 0.5; + dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff; + + qgate += CoxWL * (Vgsteff - 0.5 * Vds + T3); + Cgg1 = CoxWL * (1.0 + dT3_dVg); + Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb; + Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd; + Cgg1 *= dVgsteff_dVg; + Cgg += Cgg1; + Cgb += Cgb1; + Cgd += Cgd1; + + qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * Vds - T3); + Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg); + Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb + (0.5 * Vds - T3) * dAbulkCV_dVb) + + Cbg1 * dVgsteff_dVb; + Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd + Cbg1 * dVgsteff_dVd; + Cbg1 *= dVgsteff_dVg; + Cbg += Cbg1; + Cbb += Cbb1; + Cbd += Cbd1; + + if (m.xpart > 0.5) + { + /* 0/100 Charge petition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); + Csg = -CoxWL * (0.5 + 24.0 * T0 * Vds / T1 / T1 * AbulkCV); + Csb = -CoxWL * (0.25 * Vds * dAbulkCV_dVb + - 12.0 * T0 * Vds / T1 / T1 * (4.0 * Vgsteff - T0) + * dAbulkCV_dVb) + Csg * dVgsteff_dVb; + Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0 + / T1 / T1 * (4.0 * Vgsteff - T0)) + Csg * dVgsteff_dVd; + Csg *= dVgsteff_dVg; + } + else if (m.xpart < 0.5) + { + /* 40/60 Charge petition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + 0.4 * T0 * T0; + Csg = -2.0 * qsrc / T1 - T2 + * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); + Csb = (qsrc / T1 * Vds + T2 * T4 * Vds) * dAbulkCV_dVb + + Csg * dVgsteff_dVb; + Csd = (qsrc / T1 + T2 * T4) * AbulkCV + Csg * dVgsteff_dVd; + Csg *= dVgsteff_dVg; + } + else + { + /* 50/50 Charge petition model */ + qsrc = -0.5 * (qgate + qbulk); + Csg = -0.5 * (Cgg1 + Cbg1); + Csb = -0.5 * (Cgb1 + Cbb1); + Csd = -0.5 * (Cgd1 + Cbd1); + } + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + } + qdrn = -(qgate + qbulk + qsrc); + cggb = Cgg; + cgsb = -(Cgg + Cgd + Cgb); + cgdb = Cgd; + cdgb = -(Cgg + Cbg + Csg); + cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); + cddb = -(Cgd + Cbd + Csd); + cbgb = Cbg; + cbsb = -(Cbg + Cbd + Cbb); + cbdb = Cbd; + qinv = -(qgate + qbulk); + } + + else if (m.capMod == 2) + { + Vfb = s.vfbzb; + V3 = Vfb - Vgs_eff + VbseffCV - BSim3Model.DELTA_3; + if (Vfb <= 0.0) + { + T0 = Math.sqrt(V3 * V3 - 4.0 * BSim3Model.DELTA_3 * Vfb); + T2 = -BSim3Model.DELTA_3 / T0; + } + else + { + T0 = Math.sqrt(V3 * V3 + 4.0 * BSim3Model.DELTA_3 * Vfb); + T2 = BSim3Model.DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1 * dVbseffCV_dVb; + Qac0 = CoxWL * (Vfbeff - Vfb); + dQac0_dVg = CoxWL * dVfbeff_dVg; + dQac0_dVb = CoxWL * dVfbeff_dVb; + + T0 = 0.5 * s.k1ox; + T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; + if (s.k1ox == 0.0) + { + T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { + T1 = T0 + T3 / s.k1ox; + T2 = CoxWL; + } + else + { + T1 = Math.sqrt(T0 * T0 + T3); + T2 = CoxWL * T0 / T1; + } + + Qsub0 = CoxWL * s.k1ox * (T1 - T0); + + dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg); + dQsub0_dVd = -T2 * dVgsteff_dVd; + dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb); + + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + VdsatCV = Vgsteff / AbulkCV; + + V4 = VdsatCV - Vds - BSim3Model.DELTA_4; + T0 = Math.sqrt(V4 * V4 + 4.0 * BSim3Model.DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = BSim3Model.DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + dVdseffCV_dVg = T3; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + if (Vds == 0.0) + { + /* Added to eliminate non-zero VdseffCV at Vds=0.0 */ + VdseffCV = 0.0; + dVdseffCV_dVg = 0.0; + dVdseffCV_dVb = 0.0; + } + + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + qinoi = -CoxWL * (Vgsteff - 0.5 * T0 + AbulkCV * T3); + qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd; + Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cgg1 * dVgsteff_dVb; + Cgg1 *= dVgsteff_dVg; + + T7 = 1.0 - AbulkCV; + qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3); + T4 = -T7 * (T4 - 1.0); + T5 = -T7 * T5; + T6 = -(T7 * T6 + (0.5 * VdseffCV - T3)); + Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd; + Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cbg1 * dVgsteff_dVb; + Cbg1 *= dVgsteff_dVg; + + if (m.xpart > 0.5) + { + /* 0/100 Charge petition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); + T7 = (4.0 * Vgsteff - T0) / (T1 * T1); + T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); + T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); + T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); + Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; + Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; + Csg *= dVgsteff_dVg; + } + else if (m.xpart < 0.5) + { + /* 40/60 Charge petition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + 0.4 * T0 * T0; + T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T5 = (qsrc / T1 + T2 * T7) * AbulkCV; + T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); + Csg = (T4 + T5 * dVdseffCV_dVg); + Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; + Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; + Csg *= dVgsteff_dVg; + } + else + { + /* 50/50 Charge petition model */ + qsrc = -0.5 * (qgate + qbulk); + Csg = -0.5 * (Cgg1 + Cbg1); + Csb = -0.5 * (Cgb1 + Cbb1); + Csd = -0.5 * (Cgd1 + Cbd1); + } + + qgate += Qac0 + Qsub0; + qbulk -= (Qac0 + Qsub0); + qdrn = -(qgate + qbulk + qsrc); + + Cgg = dQac0_dVg + dQsub0_dVg + Cgg1; + Cgd = dQsub0_dVd + Cgd1; + Cgb = dQac0_dVb + dQsub0_dVb + Cgb1; + + Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; + Cbd = Cbd1 - dQsub0_dVd; + Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; + + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + + cggb = Cgg; + cgsb = -(Cgg + Cgd + Cgb); + cgdb = Cgd; + cdgb = -(Cgg + Cbg + Csg); + cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); + cddb = -(Cgd + Cbd + Csd); + cbgb = Cbg; + cbsb = -(Cbg + Cbd + Cbb); + cbdb = Cbd; + qinv = qinoi; + } + + /* New Charge-Thickness capMod (CTM) begins */ + else if (m.capMod == 3) + { + V3 = s.vfbzb - Vgs_eff + VbseffCV - BSim3Model.DELTA_3; + if (s.vfbzb <= 0.0) + { + T0 = Math.sqrt(V3 * V3 - 4.0 * BSim3Model.DELTA_3 * s.vfbzb); + T2 = -BSim3Model.DELTA_3 / T0; + } + else + { + T0 = Math.sqrt(V3 * V3 + 4.0 * BSim3Model.DELTA_3 * s.vfbzb); + T2 = BSim3Model.DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = s.vfbzb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1 * dVbseffCV_dVb; + + Cox = m.cox; + Tox = 1.0e8 * m.tox; + T0 = (Vgs_eff - VbseffCV - s.vfbzb) / Tox; + dT0_dVg = dVgs_eff_dVg / Tox; + dT0_dVb = -dVbseffCV_dVb / Tox; + + tmp = T0 * s.acde; + if ((-BSim3Model.EXP_THRESHOLD < tmp) && (tmp < BSim3Model.EXP_THRESHOLD)) + { + Tcen = s.ldeb * Math.exp(tmp); + dTcen_dVg = s.acde * Tcen; + dTcen_dVb = dTcen_dVg * dT0_dVb; + dTcen_dVg *= dT0_dVg; + } + else if (tmp <= -BSim3Model.EXP_THRESHOLD) + { + Tcen = s.ldeb * BSim3Model.MIN_EXP; + dTcen_dVg = dTcen_dVb = 0.0; + } + else + { + Tcen = s.ldeb * BSim3Model.MAX_EXP; + dTcen_dVg = dTcen_dVb = 0.0; + } + + LINK = 1.0e-3 * m.tox; + V3 = s.ldeb - Tcen - LINK; + V4 = Math.sqrt(V3 * V3 + 4.0 * LINK * s.ldeb); + Tcen = s.ldeb - 0.5 * (V3 + V4); + T1 = 0.5 * (1.0 + V3 / V4); + dTcen_dVg *= T1; + dTcen_dVb *= T1; + + Ccen = BSim3Model.EPSSI / Tcen; + T2 = Cox / (Cox + Ccen); + Coxeff = T2 * Ccen; + T3 = -Ccen / Tcen; + dCoxeff_dVg = T2 * T2 * T3; + dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; + dCoxeff_dVg *= dTcen_dVg; + CoxWLcen = CoxWL * Coxeff / Cox; + + Qac0 = CoxWLcen * (Vfbeff - s.vfbzb); + QovCox = Qac0 / Coxeff; + dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg; + dQac0_dVb = CoxWLcen * dVfbeff_dVb + QovCox * dCoxeff_dVb; + + T0 = 0.5 * s.k1ox; + T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; + if (s.k1ox == 0.0) + { + T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { + T1 = T0 + T3 / s.k1ox; + T2 = CoxWLcen; + } + else + { + T1 = Math.sqrt(T0 * T0 + T3); + T2 = CoxWLcen * T0 / T1; + } + + Qsub0 = CoxWLcen * s.k1ox * (T1 - T0); + QovCox = Qsub0 / Coxeff; + dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg) + + QovCox * dCoxeff_dVg; + dQsub0_dVd = -T2 * dVgsteff_dVd; + dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb) + + QovCox * dCoxeff_dVb; + + /* Gate-bias dependent delta Phis begins */ + if (s.k1ox <= 0.0) + { + Denomi = 0.25 * s.moin * Vtm; + T0 = 0.5 * s.sqrtPhi; + } + else + { + Denomi = s.moin * Vtm + * s.k1ox * s.k1ox; + T0 = s.k1ox * s.sqrtPhi; + } + T1 = 2.0 * T0 + Vgsteff; + + DeltaPhi = Vtm * Math.log(1.0 + T1 * Vgsteff / Denomi); + dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff); + dDeltaPhi_dVd = dDeltaPhi_dVg * dVgsteff_dVd; + dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb; + /* End of delta Phis */ + + T3 = 4.0 * (Vth - s.vfbzb - s.phi); + Tox += Tox; + if (T3 >= 0.0) + { + T0 = (Vgsteff + T3) / Tox; + dT0_dVd = (dVgsteff_dVd + 4.0 * dVth_dVd) / Tox; + dT0_dVb = (dVgsteff_dVb + 4.0 * dVth_dVb) / Tox; + } + else + { + T0 = (Vgsteff + 1.0e-20) / Tox; + dT0_dVd = dVgsteff_dVd / Tox; + dT0_dVb = dVgsteff_dVb / Tox; + } + tmp = Math.exp(0.7 * Math.log(T0)); + T1 = 1.0 + tmp; + T2 = 0.7 * tmp / (T0 * Tox); + Tcen = 1.9e-9 / T1; + dTcen_dVg = -1.9e-9 * T2 / T1 /T1; + dTcen_dVd = Tox * dTcen_dVg; + dTcen_dVb = dTcen_dVd * dT0_dVb; + dTcen_dVd *= dT0_dVd; + dTcen_dVg *= dVgsteff_dVg; + + Ccen = BSim3Model.EPSSI / Tcen; + T0 = Cox / (Cox + Ccen); + Coxeff = T0 * Ccen; + T1 = -Ccen / Tcen; + dCoxeff_dVg = T0 * T0 * T1; + dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd; + dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; + dCoxeff_dVg *= dTcen_dVg; + CoxWLcen = CoxWL * Coxeff / Cox; + + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + VdsatCV = (Vgsteff - DeltaPhi) / AbulkCV; + V4 = VdsatCV - Vds - BSim3Model.DELTA_4; + T0 = Math.sqrt(V4 * V4 + 4.0 * BSim3Model.DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = BSim3Model.DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + T4 = T3 * ( 1.0 - dDeltaPhi_dVg); + dVdseffCV_dVg = T4; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + if (Vds == 0.0) + { + /* Added to eliminate non-zero VdseffCV at Vds=0.0 */ + VdseffCV = 0.0; + dVdseffCV_dVg = 0.0; + dVdseffCV_dVb = 0.0; + } + + T0 = AbulkCV * VdseffCV; + T1 = Vgsteff - DeltaPhi; + T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20); + T3 = T0 / T2; + T4 = 1.0 - 12.0 * T3 * T3; + T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5); + T6 = T5 * VdseffCV / AbulkCV; + + qgate = qinoi = CoxWLcen * (T1 - T0 * (0.5 - T3)); + QovCox = qgate / Coxeff; + Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) + T5 * dVdseffCV_dVg); + Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1 + * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + + T7 = 1.0 - AbulkCV; + T8 = T2 * T2; + T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV); + T10 = T9 * (1.0 - dDeltaPhi_dVg); + T11 = -T7 * T5 / AbulkCV; + T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2)); + + qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2); + QovCox = qbulk / Coxeff; + Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg); + Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb) + + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + + if (m.xpart > 0.5) + { + /* 0/100 partition */ + qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 - 0.5 * T0 * T0 / T2); + QovCox = qsrc / Coxeff; + T2 += T2; + T3 = T2 * T2; + T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3); + T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg); + T5 = T7 * AbulkCV; + T6 = T7 * VdseffCV; + + Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg); + Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + } + else if (m.xpart < 0.5) + { + /* 40/60 partition */ + T2 = T2 / 12.0; + T3 = 0.5 * CoxWLcen / (T2 * T2); + T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T3 * T4; + QovCox = qsrc / Coxeff; + T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0; + T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T6 = AbulkCV * (qsrc / T2 + T3 * T8); + T7 = T6 * VdseffCV / AbulkCV; + + Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg; + Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd + QovCox * dCoxeff_dVd; + Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb + + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + } + else + { + /* 50/50 partition */ + qsrc = -0.5 * qgate; + Csg = -0.5 * Cgg1; + Csd = -0.5 * Cgd1; + Csb = -0.5 * Cgb1; + } + + qgate += Qac0 + Qsub0 - qbulk; + qbulk -= (Qac0 + Qsub0); + qdrn = -(qgate + qbulk + qsrc); + + Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; + Cbd = Cbd1 - dQsub0_dVd; + Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; + + Cgg = Cgg1 - Cbg; + Cgd = Cgd1 - Cbd; + Cgb = Cgb1 - Cbb; + + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + + cggb = Cgg; + cgsb = -(Cgg + Cgd + Cgb); + cgdb = Cgd; + cdgb = -(Cgg + Cbg + Csg); + cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); + cddb = -(Cgd + Cbd + Csd); + cbgb = Cbg; + cbsb = -(Cbg + Cbd + Cbb); + cbdb = Cbd; + qinv = -qinoi; + } /* End of CTM */ + } + + /* bulk and channel charge plus overlaps */ + if (m.capMod == 0) + { + if (vgd < 0.0) + { + cgdo = s.cgdo; + qgdo = s.cgdo * vgd; + } + else + { + cgdo = s.cgdo; + qgdo = s.cgdo * vgd; + } + + if (vgs < 0.0) + { + cgso = s.cgso; + qgso = s.cgso * vgs; + } + else + { + cgso = s.cgso; + qgso = s.cgso * vgs; + } + } + else if (m.capMod == 1) + { + if (vgd < 0.0) + { + T1 = Math.sqrt(1.0 - 4.0 * vgd / s.ckappa); + cgdo = s.cgdo + s.weffCV * s.cgdl / T1; + qgdo = s.cgdo * vgd - s.weffCV * 0.5 * s.cgdl * s.ckappa * (T1 - 1.0); + } + else + { + cgdo = s.cgdo + s.weffCV * s.cgdl; + qgdo = (s.weffCV * s.cgdl + s.cgdo) * vgd; + } + + if (vgs < 0.0) + { + T1 = Math.sqrt(1.0 - 4.0 * vgs / s.ckappa); + cgso = s.cgso + s.weffCV * s.cgsl / T1; + qgso = s.cgso * vgs - s.weffCV * 0.5 * s.cgsl * s.ckappa * (T1 - 1.0); + } + else + { + cgso = s.cgso + s.weffCV * s.cgsl; + qgso = (s.weffCV * s.cgsl + s.cgso) * vgs; + } + } + else + { + T0 = vgd + BSim3Model.DELTA_1; + T1 = Math.sqrt(T0 * T0 + 4.0 * BSim3Model.DELTA_1); + T2 = 0.5 * (T0 - T1); + + T3 = s.weffCV * s.cgdl; + T4 = Math.sqrt(1.0 - 4.0 * T2 / s.ckappa); + cgdo = s.cgdo + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1); + qgdo = (s.cgdo + T3) * vgd - T3 * (T2 + 0.5 * s.ckappa * (T4 - 1.0)); + + T0 = vgs + BSim3Model.DELTA_1; + T1 = Math.sqrt(T0 * T0 + 4.0 * BSim3Model.DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = s.weffCV * s.cgsl; + T4 = Math.sqrt(1.0 - 4.0 * T2 / s.ckappa); + cgso = s.cgso + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1); + qgso = (s.cgso + T3) * vgs - T3 * (T2 + 0.5 * s.ckappa * (T4 - 1.0)); + } + + /*** add up capacitances and charges ***/ + if (Tmode > 0) + { + gcggb = cggb + cgdo + cgso + s.cgbo; + gcgdb = cgdb - cgdo; + gcgsb = cgsb - cgso; + + gcdgb = cdgb - cgdo; + gcddb = cddb + cgdo; + gcdsb = cdsb; + + gcsgb = -(cggb + cbgb + cdgb + cgso); + gcsdb = -(cgdb + cbdb + cddb); + gcssb = cgso - (cgsb + cbsb + cdsb); + + gcbgb = cbgb - s.cgbo; + gcbdb = cbdb; + gcbsb = cbsb; + + qgd = qgdo; + qgs = qgso; + qgb = s.cgbo * vgb; + qgate += qgd + qgs + qgb; + qbulk -= qgb; + qdrn -= qgd; + qsrc = -(qgate + qbulk + qdrn); + } + else + { + gcggb = cggb + cgdo + cgso + s.cgbo; + gcgdb = cgsb - cgdo; + gcgsb = cgdb - cgso; + + gcdgb = -(cggb + cbgb + cdgb + cgdo); + gcddb = cgdo - (cgsb + cbsb + cdsb); + gcdsb = -(cgdb + cbdb + cddb); + + gcsgb = cdgb - cgso; + gcsdb = cdsb; + gcssb = cddb + cgso; + + gcbgb = cbgb - s.cgbo; + gcbdb = cbsb; + gcbsb = cbdb; + + qgd = qgdo; + qgs = qgso; + qgb = s.cgbo * vgb; + qgate += qgd + qgs + qgb; + qbulk -= qgb; + qsrc = qdrn - qgs; + qdrn = -(qgate + qbulk + qsrc); + } + + /* Note that we need to unswap source and drain for I and dI, + but not for Q and dQ */ + + data[0].setVoltage(voltage[0]); + + data[0].setCurrent(m.type * Ids); + data[0].setCurrentDerivative(nS, -Gds - Gm - Gmb); + data[0].setCurrentDerivative(nD, Gds); + data[0].setCurrentDerivative(2, Gm); + data[0].setCurrentDerivative(3, Gmb); + + data[0].setCharge(m.type * qsrc); + data[0].setChargeDerivative(0, gcssb); + data[0].setChargeDerivative(1, gcsdb); + data[0].setChargeDerivative(2, gcsgb); + data[0].setChargeDerivative(3, -gcssb - gcsdb - gcsgb); + + + data[1].setVoltage(voltage[1]); + + data[1].setCurrent(-m.type * (Ids + Isub)); + data[1].setCurrentDerivative(nS, Gds + Gm + Gmb + Gbd + Gbg + Gbb); + data[1].setCurrentDerivative(nD, -Gds - Gbd); + data[1].setCurrentDerivative(2, -Gm - Gbg); + data[1].setCurrentDerivative(3, -Gmb - Gbb); + + data[1].setCharge(m.type * qdrn); + data[1].setChargeDerivative(0, gcdsb); + data[1].setChargeDerivative(1, gcddb); + data[1].setChargeDerivative(2, gcdgb); + + + data[2].setVoltage(voltage[2]); + + data[2].setCurrent(0); + data[2].setCurrentDerivative(0, 0); + data[2].setCurrentDerivative(1, 0); + data[2].setCurrentDerivative(2, 0); + data[2].setCurrentDerivative(3, 0); + + data[2].setCharge(m.type * qgate); + data[2].setChargeDerivative(0, gcgsb); + data[2].setChargeDerivative(1, gcgdb); + data[2].setChargeDerivative(2, gcggb); + data[2].setChargeDerivative(3, -gcgsb - gcgdb - gcggb); + + + data[3].setVoltage(voltage[3]); + + data[3].setCurrent(m.type * Isub); + data[3].setCurrentDerivative(0, -Gbd - Gbg - Gbb); + data[3].setCurrentDerivative(1, Gbd); + data[3].setCurrentDerivative(2, Gbg); + data[3].setCurrentDerivative(3, Gbb); + + data[3].setCharge(m.type * qbulk); + data[3].setChargeDerivative(0, gcbsb); + data[3].setChargeDerivative(1, gcbdb); + data[3].setChargeDerivative(2, gcbgb); + data[3].setChargeDerivative(3, -gcbsb - gcbdb - gcbgb); + + + return data; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/TransistorTest.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/TransistorTest.java new file mode 100644 index 0000000000..3e908dd4b3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/TransistorTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.io.IOException; + +import com.avlsi.file.common.HierName; + +/** + * Class that tests resistors + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ + +public class TransistorTest extends AbstractDeviceTest { + public TransistorTest(int type, + String source, String drain, + String gate, String bulk, + double width, double length) + { + super(new Transistor(type, + HierName.makeHierName(source), + HierName.makeHierName(drain), + HierName.makeHierName(gate), + HierName.makeHierName(bulk), + width, length)); + } + + public double[][] getVoltageRange() { + // voltageRange[i] is range info for port i + // voltageRange[i][0] is start voltage, and [i][1] is end voltage + return new double[][] { + new double[] { 0, 0 }, // Fix Source voltage + new double[] { 2, 2 }, // Fix Drain voltage + new double[] { 0, 2 }, // Scan Gate Voltage + new double[] { 0, 0 }, // Fix Bulk Voltage + }; + } + + public GraphPortData[] makeGraphers() + throws IOException + { + final int source = 0; + final int drain = 1; + final int gate = 2; + final int bulk = 3; + + final int voltagePort = gate; + final String devName = device.getClass().getName(); + + final GraphPortData[] gpds = new GraphPortData[4]; + + try { + gpds[0] = new GraphCurrent(devName, voltagePort, source); + gpds[1] = new GraphCurrentDerivative(devName, voltagePort, source, + source); + gpds[2] = new GraphCurrent(devName, voltagePort, drain); + gpds[3] = new GraphCurrentDerivative(devName, voltagePort, drain, + source); + return gpds; + } catch (IOException e) { + for (int i = 0; i < gpds.length; i++) + if (gpds[i] != null) + gpds[i].close(); + + throw e; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Wire.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Wire.java new file mode 100644 index 0000000000..24d0de15b5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/aspice/Wire.java @@ -0,0 +1,89 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.aspice; + +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + +/** + * Class to represent a wire in an .aspice files. + * @design jmr XXX this class is stupid, remove it pronto. + * Namespace should be tracked using AliasedStringMap. Duh! + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Wire { + /** + * Name of nodes being connected. + **/ + private final Set nodeNames = new TreeSet(); + + /** + * Class constructor. Makes a wire connecting an empty set of nodes. + **/ + public Wire() + { + } + + /** + * Adds the wire to the set of equivalent wires. + **/ + public void addNode(final String nodeName) { + nodeNames.add(nodeName); + } + + /** + * returns an Iterator of the connected node names. + **/ + public Iterator getNodeNames() { + return nodeNames.iterator(); + } + + /** + * Returns the number of connected nodes. + **/ + public int getNumNodes() { + return nodeNames.size(); + } + + /** + * return string suitable for inclusion in an aspice file. + **/ + public String getAspiceString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("wire ("); + + int n = 0; + for (final Iterator i = nodeNames.iterator(); i.hasNext(); ++n) { + final String nodeName = (String) i.next(); + + if (n > 0) + sb.append(','); + + sb.append(nodeName); + } + + sb.append(");"); + + return sb.toString(); + } + + public String toString() { + return getAspiceString(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLFileFormatException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLFileFormatException.java new file mode 100644 index 0000000000..c06ea432ff --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLFileFormatException.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.cdl; + +/** + * Class to represent exceptions in parsing of .cdl files. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CDLFileFormatException extends Exception { + public CDLFileFormatException(final String message) { + super(message); + } + + public CDLFileFormatException(String message, Throwable cause) { + super(message, cause); + } + + public CDLFileFormatException(Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLParser.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLParser.java new file mode 100644 index 0000000000..f9d1919a72 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/CDLParser.java @@ -0,0 +1,844 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.file.cdl; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.StringTokenizer; + +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.aspice.Diode; +import com.avlsi.file.aspice.Resistor; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.file.common.Capacitor; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.ext.parse.ExtParser; +import com.avlsi.io.PositionStackReader; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.text.StringUtil; + +/** + * Parses cadence .cdl files into {@link AspiceFile} class. + * + * @see AspiceFile + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CDLParser { + private String line = null; + private PositionStackReader reader = null; + private final Map aspiceCellRepos = new HashMap(); + private final Map resistorMap; + private final char subcellConnectionSeparatorChar; + private boolean assura_rcx_extract; + + private int lineNum = 1; + + /** + * Class constructor. + * + * @param subcellConnectionSeparatorChar the character that + * should be used to separate the node name from the + * cell name in arguments to 'X' lines. + * @param resistorMap (may be null) a Map from resistor type + * (String) to rho (Double). When a subcircuit is encountered, + * the rho for the type is looked up in resistorMap, + * and a resistor is created with resistance rho * l / w. + **/ + public CDLParser(final char subcellConnectionSeparatorChar, + final Map resistorMap) { + this.subcellConnectionSeparatorChar = + subcellConnectionSeparatorChar; + this.resistorMap = resistorMap; + } + + /** + * Class constructor. + * + * @param subcellConnectionSeparatorChar the character that + * should be used to separate the node name from the + * cell name in arguments to 'X' lines. + **/ + public CDLParser(final char subcellConnectionSeparatorChar) { + this(subcellConnectionSeparatorChar, null); + } + + /** + * Class constructor. Uses '/' for subcell connection separator. + **/ + public CDLParser() { + this('/', null); + } + + /** + * Map from cell name String to String[] + * representing names of ports. If a use has been seen, but no + * definition, then the value will be an array of String with the + * correct length seen in the uses, but nulls for the entries. If + * a definition has been seen, then the values will also be filled in. + **/ + private final Map cellPortMap = new TreeMap(); + + private CDLFileFormatException cdlFileFormatException( + final String message) { + return new CDLFileFormatException(message); + } + + /** + * Call this to enable Assura RCX parsing compatibility. Node + * names of the form 'Xblah/' are converted to 'blah.'. + **/ + public void setAssuraRCXParsing() { + assura_rcx_extract = true; + } + + public void parseFile(final String fileName) + throws CDLFileFormatException, IOException { + parseStream(new FileInputStream(fileName)); + } + + public void parseStream(final InputStream in) + throws CDLFileFormatException, IOException { + reader = new PositionStackReader(new InputStreamReader(in)); + + reader.savePosition(); + while ((line = nextLine()) != null) { + // skip empty lines + if (line.length() == 0) { + reader.discardPosition(); + reader.savePosition(); + continue; + } + + // skip comment lines + if (line.charAt(0) == '*') { + reader.discardPosition(); + reader.savePosition(); + continue; + } + + final String[] words = split(line); + + if (".SUBCKT".equalsIgnoreCase(words[0])) { + reader.restorePosition(); + parseSubckt(); + reader.savePosition(); + } else if (".PARAM".equalsIgnoreCase(words[0]) || + ".GLOBAL".equalsIgnoreCase(words[0])) { + // ignore .PARAM & .GLOBAL + reader.discardPosition(); + reader.savePosition(); + } else { + throw cdlFileFormatException("Unknown directive " + + words[0] + " on line " + lineNum + + "; line is: " + line); + } + } + } + + /** + * Parses a .SUBCKT / .ENDS section into an AspiceFile, adding + * the parsed AspiceFile to the map of cells. It is an error if + * a cell of the same name as already been parsed. The stream + * position must be before the .SUBCKT. + **/ + private void parseSubckt() + throws CDLFileFormatException, IOException { + line = nextLine(); + String[] words = split(line); + // .SUBCKT subname output_node ... / input_node ... + // We treat input and output nodes the same + + Debug.assertTrue(".SUBCKT".equalsIgnoreCase(words[0])); + + // array[2] of Map from Pair of (source:HierName, drain:HierName) + // to double[4], representing + // diode info: {area, perim, width, length} + final Map[] diodeInfoMap = + new HashMap[]{new HashMap(), new HashMap()}; + + // the name will look like lib-BUF_1of2, this will not + // match the cast name which is just BUF_1of2, but in + // the future should change to lib/BUF_1of2 + final String cellType = unmangleType(words[1]); + + // ignore out any "/" to merge the input and output ports + String [] nodes = new String[words.length]; + int numDefPorts = 0; + int numSlashes = 0; + for (int i = 2; i < words.length; ++i) { + if ("/".equals(words[i])) numSlashes++; + else nodes[numDefPorts++] = words[i]; + } + if (numSlashes>1) + throw cdlFileFormatException("More than one / in port list."); + + + // the rest of the params are the exported nest + String[] defPorts = (String[]) cellPortMap.get(cellType); + + if (defPorts != null) { + throw cdlFileFormatException("Multiple definition of " + + cellType); + /* + * Don't allow use before definition because it complicates + * uses that occur before definition. + // check that the ports are compatable + if (numDefPorts != defPorts.length) + throw cdlFileFormatException("Found .SUBCKT " + cellType + + " with " + numDefPorts + " ports, but earlier use " + + "had " + ports.length + " ports."); + + for (int i = 0; i < ports.length; ++i) + Debug.assertTrue(ports[i] == null); + */ + } else { + Debug.assertTrue(getCell(cellType) == null); + // add the port list + defPorts = new String[numDefPorts]; + cellPortMap.put(cellType, defPorts); + } + + // fill in the right values for the port names + System.arraycopy(nodes, 0, defPorts, 0, numDefPorts); + + final AspiceFile aspiceCell = + new AspiceFile(cellType, aspiceCellRepos); + + // add names, also handling globals + for (int i = 0; i < numDefPorts; ++i) + aspiceCell.addPort(parseNodeName(defPorts[i])); + + while ((line = nextLine()) != null) { + words = split(line); + if (Character.toUpperCase(words[0].charAt(0)) == 'M') { + // mosfet + // Mxxx drain gate source bulk mname W=width L=length + // [ M=mag + // | as=source_area ps=source_perim + // ad=drain_area pd=draim_perim ] + // {a,p}{s,d} are floating point numbers x.yye-zz + if (words.length != 8 && words.length != 9 && words.length != 12) { + for (int i=0; i 5) + throw cdlFileFormatException("Wrong # of non-params " + + "for mosfet."); + + double width = -1.0; + double length = -1.0; + double[] area = new double[2]; + double[] perim = new double[2]; + area[0] = -1.0; + area[1] = -1.0; + perim[0] = -1.0; + perim[1] = -1.0; + + for (int i=6; i 4 && words[4].startsWith("M=") && + !"M=1".equalsIgnoreCase(words[4])) + throw cdlFileFormatException("Can only support M=1, " + + " got " + words[4]); + + aspiceCell.addCapacitor(new Capacitor(npositive, + nminus, cap)); + } + else { + System.err.println("Warning: Ignoring 'Inf' capacitance."); + } + } else if (Character.toUpperCase(words[0].charAt(0)) == 'D') { + // diode + // Dxxx npositive nminus mname {area} {M=multiplier} + // {periphery} {$SUB=substrate} + // + // Mname must contain exactly one of 'N' or 'P'. + // Area and periphery are optional in .cdl, but required here. + // Multiplier must be 1. + // Substrate is ignored here. + + // XXX: note that these diodes will not be combined with + // those created via as=, ... on 'M' lines. + + if (words.length < 7) { + throw cdlFileFormatException("Too few fields for " + + "diode. Expected 7, got " + words.length); + } + final HierName npositive = parseNodeName(words[1]); + final HierName nminus = parseNodeName(words[2]); + final boolean isNType = (words[3].indexOf('N') >= 0); + final boolean isPType = (words[3].indexOf('P') >= 0); + final double area = parseDouble(words[4], "area"); + final String multiplier = words[5]; + final double periphery = parseDouble(words[6], "periphery"); + int type; + + if (isNType == isPType) { + throw cdlFileFormatException("Mname argument for diode " + + "must contain exactly one of 'N' or 'P'. Got " + + words[3]); + } + + type = isNType ? DeviceTypes.N_TYPE : DeviceTypes.P_TYPE; + + if (!"M=1".equalsIgnoreCase(multiplier)) + throw cdlFileFormatException("Can only support M=1, " + + " got " + multiplier); + + final double width = (periphery + + java.lang.Math.sqrt(periphery * periphery + - 4 * area)) / 2; + final double length = area / width; + + aspiceCell.addDiode(new Diode(type, npositive, nminus, + width, length, area, periphery)); + } else if (Character.toUpperCase(words[0].charAt(0)) == 'R') { + // resistor + // Rxxx term1 term2 {res / r=res} {$SUB=substrate} {M=multiplier} + // {$[mname] / $.MODEL=mname} {w=width} {l=length} + // + // Res is optional in .cdl, but required here. + // All arguments after res are ignored here. + + if (words.length < 4) { + throw cdlFileFormatException("Too few fields for " + + "resistor. Expected 4, got " + words.length); + } + final HierName term1 = parseNodeName(words[1]); + final HierName term2 = parseNodeName(words[2]); + double res = 0; + for (int i=3; i 0 && s.charAt(0) == '+') { + reader.discardPosition(); + reader.savePosition(); + savedLineNum = lineNum; + // append a space instead of the + + sb.append(' ').append(s.substring(1)); + } else { + lineNum = savedLineNum; + reader.restorePosition(); + break; + } + } + + if (s == null) + reader.discardPosition(); + + return sb.toString(); + } + + /** + * Returns the next line, handling both continuation and comment lines. + * Ignores empty lines. + **/ + private String nextLine() throws IOException { + String s; + + while ((s = readContinuedLine()) != null) { + if (s.length() == 0) + continue; + else if (s.charAt(0) == '*') + continue; + else + break; + } + + return s; + } + + private int findLastNonParm(final String[] words) { + for (int i = words.length - 1; i >= 0; --i) { + if (words[i].indexOf('=') == -1) + return i; + } + + return -1; + } + + private int parseType(final String mname) throws CDLFileFormatException { + final boolean isNType = mname.toLowerCase().indexOf('n') != -1; + final boolean isPType = mname.toLowerCase().indexOf('p') != -1; + + if (isNType == isPType) { + throw cdlFileFormatException("Bad modelname " + mname + + " must contain exactly one 'n' or 'p'. Got " + mname); + } else + return isNType ? DeviceTypes.N_TYPE : DeviceTypes.P_TYPE; + } + + private double parseParam(final String param, final String startsWith, + final String message) throws CDLFileFormatException { + if (!param.toUpperCase().startsWith(startsWith.toUpperCase())) + throw cdlFileFormatException("Bad " + message + ": " + param + + " didn't start with " + startsWith); + + String d = param.substring(startsWith.length()).toUpperCase(); + if (d.endsWith("M")) d = d.substring(0,d.length()-1) + "E-3"; + else if (d.endsWith("U")) d = d.substring(0,d.length()-1) + "E-6"; + else if (d.endsWith("N")) d = d.substring(0,d.length()-1) + "E-9"; + else if (d.endsWith("P")) d = d.substring(0,d.length()-1) + "E-12"; + else if (d.endsWith("F")) d = d.substring(0,d.length()-1) + "E-15"; + + return parseDouble(d, message); + } + + private double parseDouble(final String d, final String message) + throws CDLFileFormatException { + + try { + return Double.parseDouble(d); + } catch (NumberFormatException e) { + throw (CDLFileFormatException) + cdlFileFormatException("Bad double format " + d + + " for " + message).initCause(e); + } + } + + private boolean isInteger(final String s) { + for (int i = 0; i < s.length(); ++i) { + if (s.charAt(i) < '0' || s.charAt(i) > '9') { + return false; + } + } + + return true; + } + + private HierName parseNodeName(String s) { + + // convert arrays back + s = StringUtil.replaceSubstring(s, "][", ","); + + // Convert 'Xblah/' to 'blah.' if this is an Assura RCX extract + if (assura_rcx_extract) { + StringTokenizer st = new StringTokenizer(s,"/"); + StringBuffer sb = new StringBuffer(); + while (st.hasMoreTokens()) { + String x = st.nextToken(); + if (st.hasMoreTokens()) sb.append(x.substring(1)+"."); + else sb.append(x); + } + s = sb.toString(); + } + + + try { + if (s.startsWith("av")) { + // spice uses av[A-Z][0-9]+(_[0-9]+)? + // XXX: what if there is a real node called this? + if (s.length() > 3 && + s.charAt(2) >= 'A' && s.charAt(2) <= 'Z') { + final String t = s.substring(3); + if (isInteger(t)) + s += '#'; + else { + final int underIdx = t.indexOf('_'); + if (underIdx != -1 && + isInteger(t.substring(0, underIdx)) && + isInteger(t.substring(underIdx + 1))) { + s += '#'; + } + } + } + } else { + // cdl uses integers for anonymous nodes: [0-9]+ + + // add a hash on to the end if the name is an integer + if (isInteger(s)) + s += '#'; + } + + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw (AssertionFailure) + new AssertionFailure("Invalid HierName -- can't happen!") + .initCause(e); + } + } + + private void go(String file) throws Throwable { + reader = new PositionStackReader(new InputStreamReader(new + FileInputStream(file))); + String s; + + while ((s = nextLine()) != null) { + System.err.println(">" + s + "<"); + } + } + + public AspiceFile getCell(final String cellType) { + return (AspiceFile) aspiceCellRepos.get(cellType); + } + + public Iterator getCellTypes() { + return aspiceCellRepos.keySet().iterator(); + } + + private String unmangleType(final String typeName) + throws CDLFileFormatException { + final StringBuffer sb = new StringBuffer(); + + // 1. convert any occurences of #xx to the appropriate character + // x must be a hex digit + // 2. map the first - to / + + boolean firstDash = true; + for (int i = 0; i < typeName.length(); ++i) { + final char ch = typeName.charAt(i); + + if (ch == '#') { + try { + if (typeName.charAt(i + 1) != '#') + throw cdlFileFormatException("Single hash in " + + typeName); + + final String hexDigits = "0123456789ABCDEF"; + final int i1 = hexDigits.indexOf( + Character.toUpperCase(typeName.charAt(i + 2))); + final int i2 = hexDigits.indexOf( + Character.toUpperCase(typeName.charAt(i + 3))); + + if (i1 == -1 || i2 == -1) + throw cdlFileFormatException("Bad hex escape in " + + typeName); + + sb.append((char) (16 * i1 + i2)); + + i += 3; + } catch (IndexOutOfBoundsException e) { + throw (CDLFileFormatException) + cdlFileFormatException("Bad hex escape in " + + typeName).initCause(e); + } + } else if (ch == '-' && firstDash) { + sb.append('/'); + firstDash = false; + } else + sb.append(ch); + } + + return sb.toString(); + } + + private static String[] split(final String line) { + StringTokenizer st = new StringTokenizer(line); + final String[] s = new String[st.countTokens()]; + + for (int i = 0; i < s.length; ++i) + s[i] = st.nextToken(); + + return s; + } + + public static void main(String[] args) throws Throwable { + // new CDLParser().go(args[0]); + new CDLParser().parseFile(args[0]); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/AspiceCellAdapter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/AspiceCellAdapter.java new file mode 100644 index 0000000000..db50ad8364 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/AspiceCellAdapter.java @@ -0,0 +1,228 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.StringTokenizer; + +import antlr.collections.AST; +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.aspice.Diode; +import com.avlsi.file.aspice.Resistor; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.file.cdl.CDLFileFormatException; +import com.avlsi.file.cdl.parser.CDLInterfaceSimplifier; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLParser; +import com.avlsi.file.cdl.parser.CDLWalker; +import com.avlsi.file.common.Capacitor; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.text.StringUtil; + +public class AspiceCellAdapter extends CDLInterfaceSimplifier { + private final Map aspiceCellRepos = new HashMap(); + private final Map portLists = new HashMap(); + private final char subcellConnectionSeparatorChar; + private boolean assura_rcx_extract = false; + private AspiceFile aspiceCell = null; + + public AspiceCellAdapter() { + this('/'); + } + + public AspiceCellAdapter(final char subcellConnectionSeparatorChar) { + this.subcellConnectionSeparatorChar = subcellConnectionSeparatorChar; + } + + public void setAssuraRCXParsing() { + assura_rcx_extract = true; + } + + private HierName parseNodeName(HierName s) { + return parseNodeName(s.getCadenceString()); + } + + /* Copied from com.avlsi.file.common.cdl.CDLParser */ + private boolean isInteger(final String s) { + for (int i = 0; i < s.length(); ++i) { + if (s.charAt(i) < '0' || s.charAt(i) > '9') { + return false; + } + } + + return true; + } + + /* Copied from com.avlsi.file.common.cdl.CDLParser */ + private HierName parseNodeName(String s) { + // convert arrays back + s = StringUtil.replaceSubstring(s, "][", ","); + + // Convert 'Xblah/' to 'blah.' if this is an Assura RCX extract + if (assura_rcx_extract) { + StringTokenizer st = new StringTokenizer(s,"/"); + StringBuffer sb = new StringBuffer(); + while (st.hasMoreTokens()) { + String x = st.nextToken(); + if (st.hasMoreTokens()) sb.append(x.substring(1)+"."); + else sb.append(x); + } + s = sb.toString(); + } + try { + if (s.startsWith("av")) { + // spice uses av[A-Z][0-9]+(_[0-9]+)? + // XXX: what if there is a real node called this? + if (s.length() > 3 && + s.charAt(2) >= 'A' && s.charAt(2) <= 'Z') { + final String t = s.substring(3); + if (isInteger(t)) + s += '#'; + else { + final int underIdx = t.indexOf('_'); + if (underIdx != -1 && + isInteger(t.substring(0, underIdx)) && + isInteger(t.substring(underIdx + 1))) { + s += '#'; + } + } + } + } else { + // cdl uses integers for anonymous nodes: [0-9]+ + + // add a hash on to the end if the name is an integer + if (isInteger(s)) + s += '#'; + } + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionFailure(e); + } + } + + public HierName [] getPorts(final String cellType) { + return (HierName []) portLists.get(cellType); + } + + public AspiceFile getCell(final String cellType) { + return (AspiceFile) aspiceCellRepos.get(cellType); + } + + public Iterator getCellTypes() { + return aspiceCellRepos.keySet().iterator(); + } + + public void parseFile(final String fileName) throws CDLFileFormatException, IOException { + parseStream(new FileInputStream(fileName)); + } + + public void parseStream(final InputStream in) throws CDLFileFormatException { + final CDLLexer lexer = new CDLLexer(new InputStreamReader(in), false); + final CDLParser parser = new CDLParser(lexer); + parser.setASTNodeClass(CDLParser.ASTWithToken.class.getName()); + try { + parser.goal(); + final AST ast = parser.getAST(); + final CDLWalker walker = new CDLWalker(); + walker.goal(ast, new LocalEnvironment(), this); + } catch (RecognitionException e) { + throw new CDLFileFormatException("Error parsing CDL file: " + + e.getMessage(), e); + } catch (TokenStreamException e) { + throw new CDLFileFormatException("Error parsing CDL file: " + + e.getMessage(), e); + } + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + aspiceCell.addResistor(new Resistor(parseNodeName(n1), parseNodeName(n2), val)); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { + aspiceCell.addCapacitor(new Capacitor(parseNodeName(npos), parseNodeName(nneg), val)); + } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + aspiceCell.addTransistor(new Transistor(type, parseNodeName(ns), parseNodeName(nd), parseNodeName(ng), parseNodeName(nb), w, l)); + } + + public void makeDiode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p) { + aspiceCell.addDiode(new Diode(type, parseNodeName(npos), parseNodeName(nneg), w, l, a, p)); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { + throw new RuntimeException("AspiceCell does not support inductors."); + } + + public void makeBipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a) { + throw new RuntimeException("AspiceCell does not support bipolar devices."); + } + + public void makeCall(HierName name, String subName, HierName[] args, Map parameters) { + HierName[] ports = (HierName []) portLists.get(subName); + if (ports == null) { + throw new RuntimeException("Subcircuit " + subName + " undefined!"); + } + if (ports.length != args.length) { + throw new RuntimeException("Subcircuit " + subName + " defined with " + ports.length + " ports, but used with " + args.length + " ports!"); + } + aspiceCell.addSubcell(name.getAsString('.'), getCell(subName)); + for (int i = 0; i < ports.length; i++) { + HierName hn = null; + try { + hn = HierName.makeHierName(name.getAsString('.') + + subcellConnectionSeparatorChar + + ports[i].getAsString('.'), '.'); + } catch (InvalidHierNameException e) { + throw new AssertionFailure(e); + } + aspiceCell.connectNames(args[i], hn); + } + } + + public void beginSubcircuit(String subName, String[] in, String[] out) { + if (portLists.containsKey(subName)) { + throw new RuntimeException("Subcircuit " + subName + " redefined!"); + } + int index = 0; + HierName[] all = new HierName[in.length + out.length]; + aspiceCell = new AspiceFile(subName, aspiceCellRepos); + for (int i = 0; i < in.length; i++, index++) { + all[index] = parseNodeName(in[i]); + aspiceCell.addPort(all[index]); + } + for (int i = 0; i < out.length; i++, index++) { + all[index] = parseNodeName(out[i]); + aspiceCell.addPort(all[index]); + } + portLists.put(subName, all); + } + + public void endSubcircuit(String subName) { + aspiceCellRepos.put(subName, aspiceCell); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDL.g b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDL.g new file mode 100644 index 0000000000..24ca6eeca2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDL.g @@ -0,0 +1,1291 @@ +/* Requires antlr 2.7.1 or newer, because lexer uses column information. */ +/* Does not handle forward references */ + +header { + package com.avlsi.file.cdl.parser; +} + +{ + import java.util.ArrayList; + import java.util.Iterator; + import java.util.List; + + import antlr.RecognitionException; + import antlr.TokenStreamSelector; + import antlr.TokenStreamException; + import antlr.collections.AST; + + import com.avlsi.cast.impl.ASTWithInfo; + import com.avlsi.cast.impl.AmbiguousLookupException; + import com.avlsi.cast.impl.BoolValue; + import com.avlsi.cast.impl.Environment; + import com.avlsi.cast.impl.FloatValue; + import com.avlsi.cast.impl.InvalidOperationException; + import com.avlsi.cast.impl.Symbol; + import com.avlsi.cast.impl.TokenWithInfo; + import com.avlsi.cast.impl.TupleValue; + import com.avlsi.cast.impl.Range; + import com.avlsi.cast.impl.UserDefinedValue; + import com.avlsi.cast.impl.Value; + import com.avlsi.cast2.impl.CastTwoLexer; + import com.avlsi.cast2.impl.CastTwoParser; + import com.avlsi.cast2.impl.CastTwoTreeParser; + import com.avlsi.util.container.Pair; + import com.avlsi.util.container.Triplet; +} + +class CDLLexer extends Lexer; +options { + charVocabulary = '\0'..'\377'; + k = 2; + caseSensitive = false; +} + +{ + private boolean extension = false; + private boolean nl = false; + + public CDLLexer(Reader in, boolean extension) { + this(in); + this.extension = extension; + setTokenObjectClass(TokenWithInfo.class.getName()); + } + + public void consume() throws CharStreamException { + char c = LA(1); + if (c == '\n') nl = true; + else if (!Character.isWhitespace(c)) nl = false; + super.consume(); + } + + public static abstract class InfoToken extends TokenWithInfo { + protected InfoToken(int t, String s) { + super(t, s); + } + protected InfoToken(int t, Token o) { + this(t, o.getText()); + setFilename(o.getFilename()); + setColumn(o.getColumn()); + setLine(o.getLine()); + } + public abstract String getText(Environment env); + public abstract Double getValue(Environment env); + public String getSpiceString(Environment env) { + return getText(env); + } + public String getFqcn(Environment env) { + return getText(env); + } + } + + public static class SimpleToken extends InfoToken { + private final Double val; + private final String text; + public SimpleToken(final Double val) { + this(val, val.toString()); + } + public SimpleToken(final Double val, final String text) { + super(0, text); + this.val = val; + this.text = text; + } + public String getText(Environment env) { + return text; + } + public Double getValue(Environment env) { + return val; + } + } + + private interface ParserAction { + void execute(CastTwoParser parser) throws RecognitionException, + TokenStreamException; + } + + static AST evaluate(String expr, ParserAction act) { + final CastTwoParser castParser = + CastTwoParser.getParser(expr, 0, 0, ""); + try { + act.execute(castParser); + } catch (RecognitionException e) { +System.err.println("evaluate: " + e); + return null; + } catch (TokenStreamException e) { +System.err.println("evaluate: " + e); + return null; + } + return castParser.getAST(); + } + + /** Use the expression rule in the CAST parser to parse the expression into + * an AST. + **/ + static AST evaluate(String expr) { + return evaluate(expr, + new ParserAction() { + public void execute(CastTwoParser parser) + throws RecognitionException, TokenStreamException { + parser.startExpression(); + } + }); + } + + // Parse an expression list using the CAST parser and return the AST. + static AST evaluateList(String expr) { + return evaluate(expr, + new ParserAction() { + public void execute(CastTwoParser parser) + throws RecognitionException, TokenStreamException { + parser.startExpressionList(); + } + }); + } + + private interface TreeParserAction { + Value execute(CastTwoTreeParser parser) throws RecognitionException; + } + + static Value evaluate(AST ast, TreeParserAction act) { + if (ast == null) return null; + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + try { + return act.execute(treeParser); + } catch (RecognitionException e) { +//System.err.println("evaluate: " + e); + return null; + } + } + + // Parse an expression list using the CAST parser and return the AST. + static Value evaluateList(final AST ast, final Environment env) { + return evaluate(ast, + new TreeParserAction() { + public Value execute(CastTwoTreeParser parser) + throws RecognitionException { + return parser.expressionList(ast, env, false); + } + }); + } + + /** Use the expression rule in the CAST tree parser to evaluate an + * expression given an AST of the expression and an environment. + **/ + static Value evaluate(final AST ast, final Environment env) { + return evaluate(ast, + new TreeParserAction() { + public Value execute(CastTwoTreeParser parser) + throws RecognitionException { + return parser.expression(ast, env, false); + } + }); + } + + /** + * Evaluate a string represented as an expression in a given environment. + **/ + static Value evaluate(String expr, Environment env) { + return evaluate(evaluate(expr), env); + } + + static Boolean evaluateBoolean(String expr, Environment env) { + Value v = evaluate(expr, env); + if (v == null) return null; + else { + try { + return new Boolean(BoolValue.valueOf(v).getValue()); + } catch (InvalidOperationException e) { + return null; + } + } + } + + static Double evaluateDouble(AST ast, Environment env) { + Value v = evaluate(ast, env); + if (v == null) return null; + else { + try { + return new Double(FloatValue.valueOf(v).getValue()); + } catch (InvalidOperationException e) { + return null; + } + } + } + + static Double evaluateDouble(String expr, Environment env) { + return evaluateDouble(evaluate(expr), env); + } + + static Double toDouble(final Value v) { + if (v == null) return null; + else { + try { + return new Double(FloatValue.valueOf(v).getValue()); + } catch (InvalidOperationException e) { + return null; + } + } + } + + static Range evaluateRange(String expr, Environment env) { + // XXX: Keep track of line and column numbers, and filename + final CastTwoParser castParser = + CastTwoParser.getParser(expr, 0, 0, ""); + + try { + castParser.startRange(); + } catch (RecognitionException e) { + return null; + } catch (TokenStreamException e) { + return null; + } + + final AST node = castParser.getAST(); + + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + try { + return treeParser.range(node, env, true); + } catch (RecognitionException e) { + return null; + } + } + + /** + * Class representing a token that "looks" like an double. The problem is + * the lexer cannot tell whether this token should be interpreted as a + * double, or as a node name, since SPICE allows almost anything to be a + * node name. This class keeps track of the string and the double value, + * so the parser can decide later. Array indexing might require parameter + * substitution. + **/ + class NameToken extends InfoToken { + private List name; + private Double val; + + public NameToken(final List name) { + super(NODE, (Token) name.get(0)); + this.name = name; + this.val = null; + } + + public NameToken(final Token token, Double val) { + super(NODE, token); + name = new ArrayList(); + name.add(token); + this.val = val; + } + + private String getIndexText(final Environment env, final List indices) { + StringBuffer buf = new StringBuffer(); + for (Iterator i = indices.iterator(); i.hasNext(); ) { + final List l = (List) i.next(); + buf.append(getText(env, l)); + if (i.hasNext()) buf.append(","); + } + return buf.toString(); + } + + private String getText(final Environment env, final List name) { + StringBuffer buf = new StringBuffer(); + for (Iterator i = name.iterator(); i.hasNext(); ) { + final Object o = i.next(); + if (o instanceof Triplet) { + final Triplet p = (Triplet) o; + List l = (List) p.getSecond(); + buf.append((String) p.getFirst()); + String indexText = getIndexText(env, l); + if (l.size() > 1 || !extension) { + buf.append(indexText); + } else { + Double element = evaluateDouble(indexText, env); + if (element == null) buf.append(indexText); + else buf.append(element.intValue()); + } + buf.append((String) p.getThird()); + } else { + Token t = (Token) o; + buf.append(t.getText()); + } + } + return buf.toString(); + } + + public String getText(Environment env) { + return getText(env, name); + } + + public Double getValue(Environment env) { + if (val != null) return val; + if (name.size() == 1) { + final Token t = (Token) name.get(0); + final String key = t.getText(); + try { + final Value v = env.lookup(Symbol.create(key)); + if (v == null) + return null; + return new Double(FloatValue.valueOf(v).getValue()); + } catch (AmbiguousLookupException e) { + return null; + } catch (InvalidOperationException e) { + return null; + } + } + return null; + } + + public String getFqcn(final Environment env) { + StringBuffer buf = new StringBuffer(); + for (Iterator i = name.iterator(); i.hasNext(); ) { + final Object o = i.next(); + if (o instanceof Triplet) { + final Triplet p = (Triplet) o; + List l = (List) p.getSecond(); + final String lbracket = (String) p.getFirst(); + String indexText = getIndexText(env, l); + + final TupleValue v; + if (extension && lbracket.equals("(")) { + v = (TupleValue) evaluateList(evaluateList(indexText), + env); + } else { + v = null; + } + + if (v == null) { + buf.append(lbracket); + buf.append(indexText); + buf.append((String) p.getThird()); + } else { + buf.append(UserDefinedValue.getTypeName("", v)); + } + } else { + Token t = (Token) o; + buf.append(t.getText()); + } + } + return buf.toString(); + } + } + + class MathExprToken extends InfoToken { + private AST parsedAST; + public MathExprToken(final Token token) { + super(NODE, token); + parsedAST = evaluate(super.getText()); + } + + public String getText(Environment env) { + return super.getText(); + } + + public Double getValue(Environment env) { + return evaluateDouble(parsedAST, env); + } + + public String getSpiceString(Environment env) { + return "'" + getText(env) + "'"; + } + } + + class LoopToken extends Token { + private Token ident, range; + + public LoopToken(Token ident, Token range) { + super(LOOP_BEGIN, ident.getText()); + this.ident = ident; + this.range = range; + } + + public String getIdent() { + return ident.getText(); + } + + public Range getRange(Environment env) { + return evaluateRange(range.getText(), env); + } + } + + public Token makeToken(final int t) { + final Token tok = super.makeToken(t); + tok.setFilename(getFilename()); + return tok; + } +} + +EQUAL : '='; + +WS : ( ' ' + | '\t' + | '\f' + | '\r' + | ( ( '\n' { newline(); } ) ( '+' )? ) + ) + { $setType(Token.SKIP); } + ; + +TOKEN + : { getColumn() == 1 || (nl && extension) }? + ( + ".subckt" { + $setType(SUBCKT); + } + | ".ends" { + $setType(ENDS); + } + | ".param" { + $setType(PARAM); + } + | device:DEVICE { + $setToken(device); + $setType(device.getType()); + } + | CMT { + $setType(Token.SKIP); + } + | { extension }? '<' var:IDENT ':' range:RANGE_CHARS ':' { + LoopToken t = new LoopToken(var, range); + $setToken(t); + } + | { extension }? '>' { + $setType(LOOP_END); + } + | { extension }? '['! ( options { greedy = false; }: ~('\n') )* "->"! { + $setType(IF_BEGIN); + } + | { extension }? ']' { + $setType(IF_END); + } + ) + | node:NODE { + $setToken(node); + $setType(NODE); + } + ; + +protected +RANGE_CHARS + : ( ~( '\n' | ':' ) )+ + ; + +protected +CMT + : '*' ( ~('\n') )* { $setType(Token.SKIP); } + ; + +protected +NODE + { + double val = 0; + List names; + } + : ( SIGNED_NUMBER ( ' ' | '\t' | '\n' ) )=> + val = number:SIGNED_NUMBER { + NameToken t = new NameToken(number, new Double(val)); + $setToken(t); + } + | ( MATH_EXPR )=> + expr:MATH_EXPR { + MathExprToken t = new MathExprToken(expr); + $setToken(t); + } + | names = NODE_NAME { + NameToken t = new NameToken(names); + $setToken(t); + } + ; + +protected +DEVICE + { + List names; + Token t; + int type = 0; + } + : ( + 'r'! { type = RESISTOR; } + | 'c'! { type = CAPACITOR; } + | 'm'! { type = TRANSISTOR; } + | 'x'! { type = SUBCELL; } + | 'd'! { type = DIODE; } + | 'l'! { type = INDUCTOR; } + | 'q'! { type = BIPOLAR; } + ) + names = NODE_NAME { + t = new NameToken(names); + t.setType(type); + $setToken(t); + } + ; + +protected +SIGNED_NUMBER returns [ double number ] + { + boolean neg = false; + } + : ( '-' { neg = true; } )? number = NUMBER { + if (neg) number = -number; + } + ; + +protected +NUMBER returns [ double number ] + { + StringBuffer value = new StringBuffer(); + double scale = 1; + double exponent = 1; + number = 0; + } + : ( DIGITS ( '.' | 'e' )? )=> + digit:DIGITS { + value.append(digit.getText()); + } + ( + '.' { + value.append('.'); + } + (decimal:DIGIT { + value.append(decimal.getText()); + })* + (exponent = EXPONENT)? + | exponent = EXPONENT + )? + (scale = SUFFIX CHARS)? { + try { + number = Double.parseDouble(value.toString()); + } catch (NumberFormatException e) { + System.err.println("Invalid number " + value + "!"); + } + number *= scale * exponent; + } + | '.' integer:DIGITS (exponent = EXPONENT)? (scale = SUFFIX CHARS)? { + try { + number = Integer.parseInt(integer.getText()); + } catch (NumberFormatException e) { + System.err.println("Invalid number " + number + "!"); + } + number *= scale * exponent; + } + ; + +protected +EXPONENT returns [ double exponent ] + { + boolean neg = false; + exponent = 1; + } + : ( 'e' ) ( '+' | '-' { neg = true; } )? + exp:DIGITS { + try { + exponent = Long.parseLong(exp.getText(), 10); + } catch (NumberFormatException e) { + System.err.println("Exponent " + exp.getText() + " too large!"); + } + if (neg) exponent = -exponent; + exponent = Math.pow(10, exponent); + } + ; + +protected +SUFFIX returns [ double scale ] + { + scale = 1.0; + } + : 'm' { scale = 1e-3; } + | 'u' { scale = 1e-6; } + | 'n' { scale = 1e-9; } + | 'p' { scale = 1e-12; } + | 'f' { scale = 1e-15; } + | 'k' { scale = 1e3; } + ; + +protected +DIGIT + : '0'..'9' + ; + +protected +DIGITS + : (DIGIT)+ + ; + +protected +CHARS + : ( '!'..'<' | '>'..'~' )* + ; + +protected +MATH_EXPR + : '\''! ( ~( '\'' | '\n' ) )* '\''! + ; + +protected +LETTER + : 'a'..'z' + ; + +protected +IDENT + : ( LETTER | '_' ) ( LETTER | DIGIT | '_' )* + ; + +/* Printable characters excluding ' ', ',', '=', '(', ')', '[', ']', '{', '}' */ +protected +NODE_CHARS + : ( '!' | '#'..'\'' | '*'..'+' | '-'..'<' | '>'..'@' | '\\' | '^'..'z' | '~' | '|' )+ + ; + +protected +NODE_NAME_BASE [ List name ] + : base:NODE_CHARS { + name.add(base); + } + ; + +protected +NODE_NAME_LIST [ List name ] + { + List indices; + Triplet triple; + } + : triple = BRACKET_BLOCK { + name.add(triple); + } + ( selector:NODE_CHARS { + name.add(selector); + } )? + ; + +protected +NODE_NAME returns [ List name ] + { + name = new ArrayList(); + } + : NODE_NAME_BASE[ name ] + ( + NODE_NAME_LIST[ name ] + )* + ; + +protected +NODE_NAME_OPT returns [ List name ] + { + name = new ArrayList(); + } + : ( NODE_NAME_BASE[ name ] )? + ( + NODE_NAME_LIST[ name ] + )* + ; + +protected +INDEX returns [ List indices ] + { + indices = new ArrayList(); + List index; + } + : index = NODE_NAME_OPT { indices.add(index); } + ( ',' index = NODE_NAME_OPT { indices.add(index); } )* + ; + +protected +BRACKET_BLOCK returns [ Triplet bracket ] + { + bracket = null; + List indices; + } + : '[' indices = INDEX ']' { bracket = new Triplet("[", indices, "]"); } + | '{' indices = INDEX '}' { bracket = new Triplet("{", indices, "}"); } + | '(' indices = INDEX ')' { bracket = new Triplet("(", indices, ")"); } + ; + +{ + import antlr.CommonAST; +} + +class CDLParser extends Parser; +options { + k = 2; + buildAST = true; + ASTLabelType = "ASTWithToken"; + defaultErrorHandler = false; +} + +tokens { + LOOP_BEGIN; + LOOP_END; + IF_BEGIN; + IF_END; +} + +{ + public static class ASTWithToken extends CommonAST { + private Token token = null; + + public void initialize(Token tok) { + super.initialize(tok); + this.token = tok; + } + + public void initialize(final AST ast) { + super.initialize(ast); + setToken(((ASTWithToken) ast).getToken()); + } + + public void setToken(Token tok) { + token = tok; + } + + public Token getToken() { + return token; + } + } +} + +goal + : deviceList EOF! + ; + +param + : PARAM^ parameterList + ; + +subcircuit + : subcircuitStart deviceList subcircuitEnd + ; + +parameterList + : ( parameter )+ + { #parameterList = #( [PARAMETERS], #parameterList ); } + ; + +parameter + : NODE { #parameter = #( [NOEQUAL], #parameter ); } + | NODE EQUAL^ NODE + ; + + +device + : RESISTOR^ NODE NODE parameterList + | CAPACITOR^ NODE NODE parameterList + | TRANSISTOR^ NODE NODE NODE NODE NODE parameterList + | DIODE^ NODE NODE NODE parameterList + | INDUCTOR^ NODE NODE parameterList + | BIPOLAR^ NODE NODE NODE NODE parameterList + | SUBCELL^ parameterList + | LOOP_BEGIN^ deviceList LOOP_END! + | IF_BEGIN^ deviceList IF_END! + | subcircuit + | param + ; + +startDeviceList + : deviceList EOF! + ; + +deviceList + : ( device )* + { #deviceList = #( [DEVICES], #deviceList ); } + ; + +expr + : RESISTOR^ NODE NODE parameterList + | CAPACITOR^ NODE NODE parameterList + | TRANSISTOR^ NODE NODE NODE NODE NODE parameterList + | DIODE^ NODE NODE NODE parameterList + | INDUCTOR^ NODE NODE parameterList + | BIPOLAR^ NODE NODE NODE NODE parameterList + | SUBCELL^ parameterList + | subcircuitStart + | subcircuitEnd + | EOF! + ; + +subcircuitStart + : SUBCKT^ parameterList + ; + +subcircuitEnd + : ENDS^ ( NODE! )* + ; + +{ + import java.util.ArrayList; + import java.util.LinkedHashMap; + import java.util.Iterator; + import java.util.List; + import java.util.Map; + import java.util.Stack; + + import com.avlsi.file.cdl.parser.CDLFactoryInterface; + import com.avlsi.file.common.HierName; + import com.avlsi.file.common.InvalidHierNameException; + import com.avlsi.cast.impl.ArrayValue; + import com.avlsi.cast.impl.BlockEnvironment; + import com.avlsi.cast.impl.BoolValue; + import com.avlsi.cast.impl.Environment; + import com.avlsi.cast.impl.EnvironmentEntry; + import com.avlsi.cast.impl.EnvironmentEntryIterator; + import com.avlsi.cast.impl.FloatValue; + import com.avlsi.cast.impl.IntValue; + import com.avlsi.cast.impl.LocalEnvironment; + import com.avlsi.cast.impl.LoopEnvironment; + import com.avlsi.cast.impl.Range; + import com.avlsi.cast.impl.Symbol; + import com.avlsi.cast.impl.SymbolRedeclaredException; + import com.avlsi.cast.impl.UserDefinedValue; + import com.avlsi.cast.impl.Value; + import com.avlsi.util.debug.Debug; +} + +class CDLWalker extends TreeParser; + +options { + ASTLabelType = "CDLParser.ASTWithToken"; +} + +{ + private Stack subNameStack = new Stack(); + + private HierName makeHierName(final String s, char sep) { + HierName name = null; + try { + name = HierName.makeHierName(s, sep); + } catch (InvalidHierNameException e) { + Debug.assertTrue(false, "Cannot makeHierName"); + } + return name; + } + + private String toStr(final Token t, Environment env) { + return ((CDLLexer.InfoToken) t).getText(env); + } + + private HierName toHier(final Token t, Environment env) { + return makeHierName(toStr(t, env), '.'); + } + + private Double toDouble(final Environment env, final Object token) + throws RecognitionException { + final Double ret = ((CDLLexer.InfoToken) token).getValue(env); + if (ret == null) { + throw new RecognitionException("Expecting an numerical value, found " + token + "!"); + } + return ret; + } + + private Double bind(final Environment env, final Double val, + final Map binding, final String key) + throws RecognitionException { + if (val == null && binding.containsKey(key)) { + return toDouble(env, binding.get(key)); + } else { + return val; + } + } + + private int findList(final List l, final String text) { + int index = 0; + for (Iterator i = l.iterator(); i.hasNext(); index++) { + Token t = (Token) i.next(); + if (t.getText().equals(text)) return index; + } + return -1; + } + + private void bindParams(final Map binding, final Environment env) throws RecognitionException { + for (Iterator i = binding.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Symbol key = Symbol.create((String) entry.getKey()); + final Double val = toDouble(env, entry.getValue()); + if (val == null) { + throw new RecognitionException("Invalid value specified for parameter " + key.getString() + "!"); + } + try { + env.bind(key, new FloatValue(val.doubleValue())); + } catch (SymbolRedeclaredException e) { + throw (RecognitionException) new RecognitionException("Cannot assign to parameter " + key.getString() + " more than once!").initCause(e); + } + } + } + + private static boolean isSimpleValue(final Value v) { + if (v instanceof ArrayValue) { + // an array is simple if its elements are simple + final Value ev = ((ArrayValue) v).getIterator().next(); + return isSimpleValue(ev); + } else { + return v instanceof BoolValue || + v instanceof FloatValue || + v instanceof IntValue; + } + } + + /** + * Copy simple values (floats, integers, booleans, arrays) from the given + * environment and return it as a new environment. The values are shallow + * copied (i.e., not duplicated). The purpose is to remove + * pointers to UserDefinedValues, which hold cell information, + * in the environment, so that they may be garbage collected. This is + * necessary because devices in Template keeps a copy of the + * environment. That requirement should be re-thought.

    + **/ + public static Environment sanitizeEnvironment(final Environment env) { + final Environment clean = new LocalEnvironment(); + for (EnvironmentEntryIterator i = env.entryIterator(); i.hasNext(); ) { + final EnvironmentEntry entry = i.next(); + final Value v = entry.getValue(); + if (isSimpleValue(v)) { + final Symbol name = entry.getName(); + if (!clean.contains(name)) { + try { + clean.bind(entry.getName(), v); + } catch (SymbolRedeclaredException e) { + Debug.assertTrue(false, "Cannot happen!"); + } + } + } + } + return clean; + } +} + + +expr[ Environment env, CDLFactoryInterface factory ] + : resistor[env,factory] + | capacitor[env,factory] + | transistor[env,factory] + | inductor[env,factory] + | diode[env,factory] + | bipolar[env,factory] + | subcell[env,factory] + | param[ env ] + | subcircuitStart[ env, factory ] + | subcircuitEnd[ env, factory ] + ; + +goal [ Environment env, CDLFactoryInterface factory ] + : deviceList[ env, factory ] + ; + +param [ Environment env ] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( PARAM parameterList[ env, param, binding ] { + bindParams(binding, env); + }) + ; + +subcircuit [ Environment env, CDLFactoryInterface factory ] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + Environment localEnv = new BlockEnvironment(env); + } + : subcircuitStart[ localEnv, factory ] + deviceList[ localEnv, factory ] + subcircuitEnd[ env, factory ] + ; + +subcircuitStart[ Environment env, CDLFactoryInterface factory ] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( SUBCKT parameterList[ env, param, binding ] ) { + List input = new ArrayList(), output = new ArrayList(); + String subName = null; + if (param.size() >= 1) { + Iterator i = param.iterator(); + subName = ((CDLLexer.InfoToken) i.next()).getText(env); + List current = input; + while (i.hasNext()) { + CDLLexer.InfoToken t = (CDLLexer.InfoToken) i.next(); + String ttext = t.getText(env); + if (ttext.equals("/")) { + if (current == input) { + current = output; + continue; + } else { + throw new RecognitionException("Too many slashes in prototype of subcircuit " + subName + "!"); + } + } + current.add(ttext); + } + } else { + throw new RecognitionException("Subcircuit definition missing name!"); + } + bindParams(binding, env); + subNameStack.push(subName); + factory.beginSubcircuit(subName, + (String[]) input.toArray(new String[0]), + (String[]) output.toArray(new String[0]), + binding, + env); + } + ; + +subcircuitEnd[ Environment env, CDLFactoryInterface factory ] + : ENDS + { + String subName = (String)subNameStack.pop(); + factory.endSubcircuit(subName, env); + } + ; + + +parameterList [ Environment env, List param, Map binding ] + : #( PARAMETERS ( parameter[ env, param, binding ] )+ ) + ; + +deviceList [ Environment env, CDLFactoryInterface factory ] + : #( DEVICES ( device[ env, factory ] )* ) + ; + +parameter[ Environment env, List param, Map binding ] + : #( NOEQUAL node:NODE ) { + param.add(node.getToken()); + } + | #( EQUAL key:NODE val:NODE ) { + binding.put(key.getToken().getText(), val.getToken()); + } + ; + +device[ Environment env, CDLFactoryInterface factory ] + : resistor[env,factory] + | capacitor[env,factory] + | transistor[env,factory] + | inductor[env,factory] + | diode[env,factory] + | bipolar[env,factory] + | subcell[env,factory] + | #( loop:LOOP_BEGIN loopdev:DEVICES ) { + // XXX: Should refactor with loopStatement in CastTwoTree.g + final CDLLexer.LoopToken token = (CDLLexer.LoopToken) loop.getToken(); + final Symbol var = Symbol.create(token.getIdent()); + final Range range = token.getRange(env); + if (range == null) { + System.err.println("Loop range uninitialized."); + } else { + for (Range.Iterator ri = range.iterator(); ri.hasNext(); ) { + final int i = ri.next(); + final Environment loopEnv = + new LoopEnvironment(env, var, IntValue.valueOf(i)); + deviceList(loopdev, loopEnv, factory); + } + } + } + | #( cond:IF_BEGIN ifdev:DEVICES ) { + // XXX: Should refactor with ifStatement in CastTwoTree.g + final Boolean guard = CDLLexer.evaluateBoolean(cond.getToken().getText(), env); + if (guard == null) { + System.err.println("If guard uninitialized."); + } else { + if (guard.booleanValue()) { + deviceList(ifdev, env, factory); + } + } + } + | subcircuit[ env, factory ] + | param[ env ] + ; + +resistor[Environment env, CDLFactoryInterface factory] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( r:RESISTOR n1:NODE n2:NODE parameterList[ env, param, binding ] ) { + // Rxxxxxxx n1 n2 ( resistance | R=resistance ) + Object res = null; + int currParam = 0; + if (binding.containsKey("r")) res = binding.remove("r"); + else if (binding.containsKey("R")) res = binding.remove("R"); + else if (param.size() > currParam) res = param.get(currParam++); + if (param.size() > currParam ) { + CDLLexer.NameToken token = (CDLLexer.NameToken)param.get(currParam); + binding.put("$.MODEL", token); + } + if (res == null) { + throw new RecognitionException("No resistance specified for resistor " + r.getText() + "!"); + } else { + factory.makeResistor(toHier(#r.getToken(), env), + toHier(#n1.getToken(), env), + toHier(#n2.getToken(), env), + (CDLLexer.InfoToken) res, + binding, env); + } + } + ; + +capacitor[Environment env, CDLFactoryInterface factory] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( c:CAPACITOR npos:NODE nneg:NODE + parameterList[ env, param, binding ] ) { + // Cxxxxxx n+ n- capacitance + Object cap = null; + if (param.size() >= 1) { + cap = param.get(0); + } + if (cap == null) { + throw new RecognitionException("No capacitance specified for capacitor " + c.getText() + "!"); + } else { + factory.makeCapacitor(toHier(#c.getToken(), env), + toHier(#npos.getToken(), env), + toHier(#nneg.getToken(), env), + (CDLLexer.InfoToken) cap, binding, + env); + } + } + ; + +transistor[Environment env, CDLFactoryInterface factory] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( t:TRANSISTOR nd:NODE ng:NODE ns:NODE nb:NODE mname:NODE + parameterList[ env, param, binding ] ) { + Object w = null, l = null; + + if (binding.containsKey("W")) w = binding.remove("W"); + else if (binding.containsKey("w")) w = binding.remove("w"); + + if (binding.containsKey("L")) l = binding.remove("L"); + else if (binding.containsKey("l")) l = binding.remove("l"); + + if (w == null || l == null) { + throw new RecognitionException("No length or width specified for transistor " + t.getText() + "!"); + } else { + factory.makeTransistor(toHier(#t.getToken(), env), + toStr(#mname.getToken(), env), + toHier(#ns.getToken(), env), + toHier(#nd.getToken(), env), + toHier(#ng.getToken(), env), + toHier(#nb.getToken(), env), + (CDLLexer.InfoToken) w, + (CDLLexer.InfoToken) l, + binding, env); + } + } + ; + +inductor[Environment env, CDLFactoryInterface factory] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( l0:INDUCTOR lpos:NODE lneg:NODE + parameterList[ env, param, binding ] ) { + // Lxxxxxx n+ n- inductance + Object ind = null; + if (param.size() >= 1) { + ind = param.get(0); + } + if (ind == null) { + throw new RecognitionException("No inductance specified for inductor " + l0.getText() + "!"); + } else { + factory.makeInductor(toHier(#l0.getToken(), env), + toHier(#lpos.getToken(), env), + toHier(#lneg.getToken(), env), + (CDLLexer.InfoToken) ind, + binding, env); + } + } + ; + +diode[Environment env, CDLFactoryInterface factory] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( d:DIODE dpos:NODE dneg:NODE dtype:NODE + parameterList[ env, param, binding ] ) { + // Dxxxxxxx type n1 n2 ( area | area=area ) + Object area = null; + if (binding.containsKey("area")) area = binding.remove("area"); + else if (binding.containsKey("AREA")) area = binding.remove("AREA"); + else if (param.size() >= 1) area = param.get(0); + if (area == null) { + throw new RecognitionException("No area specified for diode " + d.getText() + "!"); + } else { + factory.makeDiode(toHier(#d.getToken(), env), + dtype.getText(), + toHier(#dpos.getToken(), env), + toHier(#dneg.getToken(), env), + (CDLLexer.InfoToken) area, + binding, env); + } + } + ; + +bipolar[Environment env, CDLFactoryInterface factory] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( q:BIPOLAR nc:NODE nb:NODE ne:NODE mname:NODE + parameterList[ env, param, binding ] ) { + // Qxxxxxxx nc nb ne type ( area | area=area ) + Object area = null; + if (binding.containsKey("area")) area = binding.remove("area"); + else if (binding.containsKey("AREA")) area = binding.remove("AREA"); + else if (param.size() >= 1) area = param.get(0); + if (area == null) { + throw new RecognitionException("No area specified for BJT " + q.getText() + "!"); + } else { + factory.makeBipolar(toHier(#q.getToken(), env), + mname.getText(), + toHier(#nc.getToken(), env), + toHier(#nb.getToken(), env), + toHier(#ne.getToken(), env), + (CDLLexer.InfoToken) area, + binding, env); + } + } + ; + +subcell[Environment env, CDLFactoryInterface factory] + { + List param = new ArrayList(); + Map binding = new LinkedHashMap(); + } + : #( call:SUBCELL parameterList[ env, param, binding ] ) { + final int slash = findList(param, "/"); + + final int numSubCircuitArgs; + //findList should always return >= -1 + assert ( slash >= -1 ); + + final CDLLexer.InfoToken subToken; + //If there is a slash, it must only be followed by exactly one token. + if ( slash > -1 ) { + if ( ( slash + 2 ) != param.size() ) { + throw new RecognitionException("Improper subcell specification in call " + call); + } + else { + subToken = (CDLLexer.InfoToken) param.get(slash + 1); + numSubCircuitArgs = slash; + } + } + else { + final int indexOfLast = param.size() - 1; + //There was no slash so subname is last element of param list. + subToken = (CDLLexer.InfoToken) param.get(indexOfLast); + numSubCircuitArgs = indexOfLast; + } + + final String subName = subToken.getFqcn(env); + + final HierName args[] = new HierName[numSubCircuitArgs]; + for (int i = 0; i < numSubCircuitArgs; i++) { + args[i] = toHier((Token) param.get(i), env); + } + + factory.makeCall(toHier(#call.getToken(), env), subName, args, + binding, env); + } + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLAliases.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLAliases.java new file mode 100644 index 0000000000..18214096c2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLAliases.java @@ -0,0 +1,419 @@ +package com.avlsi.file.cdl.parser; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.util.rename.CDLRenameFactory; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; +import com.avlsi.file.cdl.util.rename.TrivialCDLNameInterfaceFactory; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgFormatException; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsUtil; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.functions.UnaryPredicate; + +public class CDLAliases extends CDLFactoryAdaptor { + private static String h2s(final HierName n) { + return n.getAsString('.'); + } + + private static HierName s2h(final String n) { + try { + return HierName.makeHierName(n, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException(e); + } + } + + private static final HierName DEMOTER_HIERNAME = + HierName.makeHierName("$\000\000\000\000\000"); + + private static HierName demote(final HierName h) { + return HierName.append(DEMOTER_HIERNAME, h); + } + + private static HierName undemote(final HierName h) { + HierName result = null; + HierName left = h; + while (left != null) { + final HierName parent = left.getParent(); + final HierName current = + HierName.makeHierName(left.getSuffixString()); + if (!DEMOTER_HIERNAME.equals(current)) { + result = result == null ? current + : HierName.append(current, result); + } + left = parent; + } + return result; + } + + private static class MultiMap { + private final Map map; + public MultiMap() { + map = new HashMap(); + } + public void put(final Object key, final Object val) { + Collection coll = (Collection) map.get(key); + if (coll == null) { + coll = new ArrayList(); + map.put(key, coll); + } + coll.add(val); + } + public void put(final Object key) { + if (!map.containsKey(key)) { + map.put(key, new ArrayList()); + } + } + public Collection get(final Object key) { + return (Collection) map.get(key); + } + public Set keySet() { + return map.keySet(); + } + } + + private class Cell { + private class Instance { + final String subName; + final String instance; + public Instance(final String subName, final String instance) { + this.subName = subName; + this.instance = instance; + } + public String getType() { + return subName; + } + public String getInstance() { + return instance; + } + } + + private class Port { + final String subName; + final String instance; + final int position; + public Port(final String subName, final String instance, + final int position) { + this.subName = subName; + this.instance = instance; + this.position = position; + } + public String getType() { + return subName; + } + public String getInstance() { + return instance; + } + public int getPosition() { + return position; + } + } + + private final String name; + private final String[] ports; + private final Set portSet; + private final Collection instances; + private final MultiMap aliases; + + public Cell(final String name, final String[] in, final String[] out) { + this.name = name; + this.ports = new String[in.length + out.length]; + System.arraycopy(in, 0, ports, 0, in.length); + System.arraycopy(out, 0, ports, in.length, out.length); + this.portSet = (Set) CollectionUtils.addAll(new HashSet(), ports); + this.instances = new ArrayList(); + this.aliases = new MultiMap(); + } + + public void addInstance(final String subName, final HierName inst) { + instances.add(new Instance(subName, h2s(inst))); + } + + public String getName() { + return name; + } + + public String getPort(int position) { + return ports[position]; + } + + public boolean isPort(final String name) { + return portSet.contains(name); + } + + public void addAlias(final HierName port, final String subName, + final HierName inst, final int position) { + aliases.put(h2s(port), new Port(subName, h2s(inst), position)); + } + + public void addAlias(final HierName name) { + aliases.put(h2s(name)); + } + + public Collection getAliases(final String name) { + final Collection results = new HashSet(); + final Collection names = aliases.get(name); + if (names == null) return Collections.EMPTY_LIST; + results.add(name); + for (Iterator i = names.iterator(); i.hasNext(); ) { + final Port port = (Port) i.next(); + final Cell subcell = (Cell) cells.get(port.getType()); + if (subcell == null) { + throw new IllegalStateException( + "Subcircuit " + port.getType() + " undefined."); + } + final String subport = subcell.getPort(port.getPosition()); + results.add(append(port.getInstance(), subport)); + if (!routed.evaluate(subcell.getName())) { + for (Iterator j = subcell.getAliases(subport).iterator(); + j.hasNext(); ) { + results.add(append(port.getInstance(), (String) j.next())); + } + } + } + return results; + } + + private void printList(final Iterator iter, final String seperator) { + while (iter.hasNext()) { + System.out.print(undemote((HierName) iter.next())); + if (iter.hasNext()) System.out.print(seperator); + } + } + + public void printAlias(final String prefix, final String name, + final Collection names) { + final Set sorted = new TreeSet(); + for (Iterator i = names.iterator(); i.hasNext(); ) { + sorted.add(s2h(append(prefix, (String) i.next()))); + } + sorted.add(s2h(append(prefix, name))); + printList(sorted.iterator(), "="); + } + + public void printAliases(final String prefix, final boolean internal) { + for (Iterator i = aliases.keySet().iterator(); i.hasNext(); ) { + final String port = (String) i.next(); + if (internal && isPort(port)) continue; + printAlias(prefix, port, getAliases(port)); + System.out.println(); + } + for (Iterator i = instances.iterator(); i.hasNext(); ) { + final Instance inst = (Instance) i.next(); + final Cell subcell = (Cell) cells.get(inst.getType()); + if (subcell == null) { + throw new IllegalStateException( + "Subcircuit " + inst.getType() + " undefined."); + } + if (!routed.evaluate(subcell.getName())) { + subcell.printAliases(append(prefix, inst.getInstance()), + true); + } + } + } + } + + private String append(final String a, final String b) { + return a == null ? b : a + hierarchyDelimiter + b; + } + + private final String hierarchyDelimiter; + private final Map/**/ cells; + private Cell currentCell; + + /** + * A predicate that evaluates a cell name, and returns true if + * the cell is routed, and false otherwise. + **/ + private final UnaryPredicate routed; + + /** + * A predicate that evaluates a cell name, and returns true if + * the cell is a gate, and false otherwise. + **/ + private final UnaryPredicate gate; + + public CDLAliases(final UnaryPredicate routed, final UnaryPredicate gate) { + this.hierarchyDelimiter = "."; + this.cells = new TreeMap(); + this.currentCell = null; + this.routed = routed; + this.gate = gate; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + currentCell.addAlias(n1); + currentCell.addAlias(n2); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + currentCell.addAlias(npos); + currentCell.addAlias(nneg); + } + + public void makeDiode(HierName name, String type, HierName npos, + HierName nneg, CDLLexer.InfoToken val, + Map parameters, Environment env) { + currentCell.addAlias(npos); + currentCell.addAlias(nneg); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + currentCell.addAlias(npos); + currentCell.addAlias(nneg); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + currentCell.addAlias(ns); + currentCell.addAlias(nd); + currentCell.addAlias(ng); + currentCell.addAlias(nb); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + final HierName instName; + if (gate.evaluate(subName)) { + instName = demote(name); + } else { + instName = name; + currentCell.addInstance(subName, name); + } + for (int i = 0; i < args.length; ++i) { + currentCell.addAlias(args[i], subName, instName, i); + } + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + if (currentCell != null) { + throw new IllegalStateException( + "Found nested subcircuit definition of " + subName + + " while processing " + currentCell.getName()); + } + + if (cells.containsKey(subName)) { + throw new IllegalStateException( + "Found redefinition of subcircuit " + subName); + } + + currentCell = new Cell(subName, in, out); + cells.put(subName, currentCell); + } + + public void endSubcircuit(String subName, Environment env) { + if (currentCell == null) { + throw new IllegalStateException("Found unmatched .ENDS"); + } + + currentCell = null; + } + + public void printAliases(final String type) { + final Cell cell = type == null ? null : (Cell) cells.get(type); + if (cell == null) { + for (Iterator i = cells.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + System.out.println("cell = " + entry.getKey()); + ((Cell) entry.getValue()).printAliases(null, false); + } + } else { + System.out.println(cell.getName()); + cell.printAliases(null, false); + } + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + final String grayboxList = theArgs.getArgValue("graybox-list", null); + final String cell = theArgs.getArgValue("cell", null); + final String gatesRegex = theArgs.getArgValue("gates-regex", null); + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + System.err.print( pedanticArgs.pedanticString() ); + System.exit(1); + } + final Pattern gatesPattern = + gatesRegex == null ? null : Pattern.compile(gatesRegex); + final UnaryPredicate gatePredicate = new UnaryPredicate() { + public boolean evaluate(final Object o) { + return gatesPattern != null && + gatesPattern.matcher((String) o).matches(); + } + }; + + final UnaryPredicate grayboxPredicate; + if (grayboxList == null) { + grayboxPredicate = new UnaryPredicate() { + public boolean evaluate(final Object o) { + return false; + } + }; + } else { + final BufferedReader br = + new BufferedReader(new FileReader(grayboxList)); + final Set grayboxSet = new HashSet(); + String line; + while ((line = br.readLine()) != null) { + grayboxSet.add(line.trim()); + } + br.close(); + grayboxPredicate = new UnaryPredicate() { + public boolean evaluate(final Object o) { + return grayboxSet.contains(o); + } + }; + } + final CDLAliases ca = new CDLAliases(grayboxPredicate, gatePredicate); + // input CDL is expected to be using Cadence names + ReadCDLIntoFactory.readCDL( + new InputStreamReader(System.in), + new CDLRenameFactory(ca, + new TrivialCDLNameInterfaceFactory( + new CadenceReverseNameInterface()))); + ca.printAliases(cell); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLDeviceNameFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLDeviceNameFilter.java new file mode 100644 index 0000000000..2908fa7b7b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLDeviceNameFilter.java @@ -0,0 +1,88 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +/** + * Allows transformation of device names by overriding the + * processDeviceName method. By the default, the method is the identity + * transformation. + **/ +public class CDLDeviceNameFilter implements CDLFactoryInterface { + protected CDLFactoryInterface inner; + + public CDLDeviceNameFilter(final CDLFactoryInterface inner) { + this.inner = inner; + } + + protected HierName processDeviceName(final HierName name) { + return name; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeResistor(processDeviceName(name), n1, n2, val, parameters, + env); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeCapacitor(processDeviceName(name), npos, nneg, val, + parameters, env); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + inner.makeTransistor(processDeviceName(name), type, ns, nd, ng, nb, + w, l, parameters, env); + } + + + public void makeDiode(HierName name, String type, HierName npos, + HierName nneg, CDLLexer.InfoToken val, + Map parameters, Environment env) { + inner.makeDiode(processDeviceName(name), type, npos, nneg, val, + parameters, env); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeInductor(processDeviceName(name), npos, nneg, val, + parameters, env); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + inner.makeBipolar(processDeviceName(name), type, nc, nb, ne, val, + parameters, env); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + inner.makeCall(processDeviceName(name), subName, args, parameters, env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + inner.beginSubcircuit(subName, in, out, parameters, env); + } + + public void endSubcircuit(String subName, Environment env) { + inner.endSubcircuit(subName, env); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryAdaptor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryAdaptor.java new file mode 100644 index 0000000000..89a8d91e3e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryAdaptor.java @@ -0,0 +1,58 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + +public class CDLFactoryAdaptor implements CDLFactoryInterface { + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, Environment env) { + } + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + + } + + public void makeTransistor(HierName name, String type, HierName ns, HierName nd, + HierName ng, HierName nb, CDLLexer.InfoToken w, + CDLLexer.InfoToken l, Map parameters, Environment env) { + } + + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + } + + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + } + + + public void endSubcircuit(String subName, Environment env) { + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryEmitter.java new file mode 100644 index 0000000000..ebef29792e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryEmitter.java @@ -0,0 +1,382 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.PrintWriter; +import java.io.Writer; + +import java.util.Iterator; +import java.util.Map; + +import antlr.Token; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; + +public class CDLFactoryEmitter implements CDLFactoryInterface, CDLSimpleInterface { + private final PrintWriter w; + + /** + * The maximum line size. + **/ + private final int maxLineSize; + + /** + * Length of the current line is. + **/ + private int linesize; + + /** + * Filter out 0 width or length transistors, and 0 farad + * capacitors? Never skip 0 ohm resistors, since they are wires + * and must be emitted! + **/ + private final boolean filter0; + + /** + * Surround expressions with single quotes? + **/ + private final boolean quoteExpression; + + private final boolean evaluateTokens; + + /** + * Delimiter to use between ports of an instantiation and the name of the + * subcircuit to be instantiated. + **/ + private final String callDelimiter; + + public CDLFactoryEmitter(final Writer w) { + this(w, true); + } + + public CDLFactoryEmitter(final Writer w, boolean filter0) { + this(w, filter0, 999); + } + + public CDLFactoryEmitter(final Writer w, boolean filter0, int maxLineSize) { + this(w, filter0, maxLineSize, true); + } + + public CDLFactoryEmitter(final Writer w, boolean filter0, int maxLineSize, + final boolean quoteExpression) { + this(w, filter0, maxLineSize, quoteExpression, false); + } + + public CDLFactoryEmitter(final Writer w, boolean filter0, int maxLineSize, + final boolean quoteExpression, + final boolean evaluateTokens) { + this(w, filter0, maxLineSize, quoteExpression, evaluateTokens, "" /*"/"*/); + } + + public CDLFactoryEmitter(final Writer w, boolean filter0, int maxLineSize, + final boolean quoteExpression, + final boolean evaluateTokens, + final String callDelimiter) { + this.w = new PrintWriter(w); + this.linesize = 0; + this.filter0 = filter0; + this.maxLineSize = maxLineSize; + this.quoteExpression = quoteExpression; + this.evaluateTokens = evaluateTokens; + this.callDelimiter = callDelimiter; + } + + + private String stringNode(HierName node) { + return node.getCadenceString(); + } + + private String stringToken(final Token token) { + if (token instanceof CDLLexer.MathExprToken) { + return "'" + token.getText() + "'"; + } else { + return token.getText(); + } + } + + /* Print the string as is */ + protected void print(String s) { + linesize += s.length(); + w.print(s); + } + + /* Create whitespace, then print the string */ + protected void printws(String s) { + int l = s.length(); + if (linesize + l + 1 > maxLineSize) { + println(); + w.print("+"); + } else { + w.print(" "); + } + w.print(s); + linesize += 1 + l; + } + + /* Go to a newline */ + protected void println() { + linesize = 0; + w.println(); + } + + private boolean skip(CDLLexer.InfoToken token, Environment env) { + if (filter0) { + Double d = token.getValue(env); + if (d != null && d.doubleValue() == 0) return true; + } + return false; + } + + private boolean skip(double val) { + return filter0 && val == 0; + } + + private void keypair(Map parameters, Environment env) { + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + Token val = (Token) entry.getValue(); + printws(key + "=" + getTokenVal(val, env)); + } + } + + private String getTokenVal(Token token, Environment env) { + if(evaluateTokens && token instanceof CDLLexer.InfoToken) { + Double eval = ((CDLLexer.InfoToken)token).getValue(env); + if(eval == null ) + return stringToken(token); + else + return "" + eval.floatValue(); + } + else + return stringToken(token); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + if (skip(w, env) || skip(l, env)) return; + print("M" + name.getCadenceString()); + printws(stringNode(nd)); + printws(stringNode(ng)); + printws(stringNode(ns)); + printws(stringNode(nb)); + printws(type); + printws("w=" + getTokenVal(w, env)); + printws("l=" + getTokenVal(l, env)); + keypair(parameters, env); + println(); + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + if (skip(val, env)) return; + print("D" + name.getCadenceString()); + printws(stringNode(npos)); + printws(stringNode(nneg)); + printws(type); + printws(getTokenVal(val, env)); + keypair(parameters, env); + println(); + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + // don't skip 0 ohm resistors! + print("R" + name.getCadenceString()); + printws(stringNode(n1)); + printws(stringNode(n2)); + printws(getTokenVal(val, env)); + keypair(parameters, env); + println(); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + if (skip(val, env)) return; + print("C" + name.getCadenceString()); + printws(stringNode(npos)); + printws(stringNode(nneg)); + printws(getTokenVal(val, env)); + keypair(parameters, env); + println(); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + if (skip(val, env)) return; + print("L" + name.getCadenceString()); + printws(stringNode(npos)); + printws(stringNode(nneg)); + printws(getTokenVal(val, env)); + keypair(parameters, env); + println(); + } + + public void makeBipolar(HierName name, String type, + HierName nc, HierName nb, HierName ne, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + if (skip(val, env)) return; + print("Q" + name.getCadenceString()); + printws(stringNode(nc)); + printws(stringNode(nb)); + printws(stringNode(ne)); + printws(type); + printws("area=" + getTokenVal(val, env)); + keypair(parameters, env); + println(); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + print("X" + name.getCadenceString()); + + for (int i = 0; i < args.length; i++) { + printws(stringNode(args[i])); + } + + if (!callDelimiter.equals("")) printws(callDelimiter); + printws(subName); + keypair(parameters, env); + println(); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + print(".SUBCKT"); + printws(subName); + + for (int i = 0; i < in.length; i++) { + printws(in[i]); + } + + if (out.length > 0) { + // printws("/"); + for (int i = 0; i < out.length; i++) { + printws(out[i]); + } + } + + keypair(parameters, env); + println(); + } + + public void endSubcircuit(String subName, Environment env) { + print(".ENDS"); + println(); + } + + // Implementatin of CDLSimpleInterface + private void keypairSimple(Map parameters) { + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + Double val = (Double) entry.getValue(); + printws(key + "=" + val); + } + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + // don't skip 0 ohm resistors! + print("R" + name.getCadenceString()); + printws(stringNode(n1)); + printws(stringNode(n2)); + printws(Double.toString(val)); + println(); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { + if (skip(val)) return; + print("C" + name.getCadenceString()); + printws(stringNode(npos)); + printws(stringNode(nneg)); + printws(Double.toString(val)); + println(); + + } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + if (skip(w) || skip(l)) return; + print("M" + name.getCadenceString()); + printws(stringNode(nd)); + printws(stringNode(ng)); + printws(stringNode(ns)); + printws(stringNode(nb)); + printws(type == DeviceTypes.N_TYPE ? "n" : "p"); + printws("w=" + w); + printws("l=" + l); + println(); + } + + public void makeDiode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p) { + if (skip(a)) return; + print("D" + name.getCadenceString()); + printws(stringNode(npos)); + printws(stringNode(nneg)); + printws(type == DeviceTypes.N_TYPE ? "dw" : "dp"); + printws(Double.toString(a)); + println(); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { + if (skip(val)) return; + print("L" + name.getCadenceString()); + printws(stringNode(npos)); + printws(stringNode(nneg)); + printws(Double.toString(val)); + println(); + } + + public void makeBipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a) { + if (skip(a)) return; + print("Q" + name.getCadenceString()); + printws(stringNode(nc)); + printws(stringNode(nb)); + printws(stringNode(ne)); + printws(type == DeviceTypes.N_TYPE ? "npn" : "pnp"); + printws("area=" + Double.toString(a)); + println(); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { + print("X" + name.getCadenceString()); + + for (int i = 0; i < args.length; i++) { + printws(stringNode(args[i])); + } + + if (!callDelimiter.equals("")) printws(callDelimiter); + printws(subName); + keypairSimple(parameters); + println(); + } + + public void beginSubcircuit(String subName, String[] in, String[] out) { + throw new RuntimeException(); + } + + public void endSubcircuit(String subName) { + throw new RuntimeException(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryFilter.java new file mode 100644 index 0000000000..a080185fdb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryFilter.java @@ -0,0 +1,79 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +/** + * An implementation of CDLFactoryInterface that is a transparent + * filter that relays all incoming calls to an underlying + * CDLFactoryInterface. This is meant to make it more convenient + * to implement filters that override only a few of the methods in + * CDLFactoryInterface. + **/ +public class CDLFactoryFilter implements CDLFactoryInterface { + protected CDLFactoryInterface inner; + + public CDLFactoryFilter(final CDLFactoryInterface inner) { + this.inner = inner; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeResistor(name, n1, n2, val, parameters, env); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeCapacitor(name, npos, nneg, val, parameters, env); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + inner.makeTransistor(name, type, ns, nd, ng, nb, w, l, parameters, env); + } + + public void makeDiode(HierName name, String type, HierName npos, + HierName nneg, CDLLexer.InfoToken val, + Map parameters, Environment env) { + inner.makeDiode(name, type, npos, nneg, val, parameters, env); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeInductor(name, npos, nneg, val, parameters, env); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + inner.makeBipolar(name, type, nc, nb, ne, val, parameters, env); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + inner.makeCall(name, subName, args, parameters, env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + inner.beginSubcircuit(subName, in, out, parameters, env); + } + + public void endSubcircuit(String subName, Environment env) { + inner.endSubcircuit(subName, env); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryInterface.java new file mode 100644 index 0000000000..252d1631ee --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLFactoryInterface.java @@ -0,0 +1,130 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +/** + * Factory interface used by the CDL parser to create devices. + **/ +public interface CDLFactoryInterface { + /** + * Called by the parser to make a resistor. + * @param name Name of the resistor + * @param n1 First terminal + * @param n2 Second terminal + * @param val Resistance in ohm + * @param parameters Parameters specified for this resistor + * @param env Current environment + **/ + void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, Environment env); + + /** + * Called by the parser to make a capacitor. + * @param name Name of the capacitor + * @param npos Positive terminal + * @param nneg Negative terminal + * @param val Capacitance in farads + * @param parameters Parameters specified for this capacitor + * @param env Current environment + **/ + void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env); + + /** + * Called by the parser to make a transistor. + * @param name Name of the transistor + * @param type Type of the transistor + * @param ns Source + * @param nd Drain + * @param ng Gate + * @param nb Bulk + * @param w Width of the transistor in meters + * @param l Length of the transistor in meters + * @param parameters Parameters specified for this transistor + * @param env Current environment + **/ + void makeTransistor(HierName name, String type, HierName ns, HierName nd, + HierName ng, HierName nb, CDLLexer.InfoToken w, + CDLLexer.InfoToken l, Map parameters, Environment env); + + /** + * Called by the parser to make a diode. + * @param name Name of the diode + * @param type Type of the diode + * @param npos Positive terminal + * @param nneg Negative terminal + * @param area Area of the diode in square meters + * @param parameters Parameters specified for this diode + * @param env Current environment + **/ + void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken area, Map parameters, Environment env); + + /** + * Called by the parser to make an inductor. + * @param name Name of the inductor + * @param npos Positive terminal + * @param nneg Negative terminal + * @param val Inductance in henrys + * @param parameters Parameters specified for this inductor + * @param env Current environment + **/ + void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env); + + /** + * Called by the parser to make a BJT. + * @param name Name of the diode + * @param type Type of the diode + * @param nc Collector terminal + * @param nb Base terminal + * @param ne Emitter terminal + * @param area Area of the diode in square meters + * @param parameters Parameters specified for this diode + * @param env Current environment + **/ + void makeBipolar(HierName name, String type, HierName nc, HierName nb, + HierName ne, CDLLexer.InfoToken area, Map parameters, + Environment env); + + + /** + * Called by the parser to make a call. + * @param name Name of the instantiation + * @param subName Name of the subcircuit + * @param args Arguments to the subcircuit + * @param parameters Overriding parameters specified for this call + * @param env Current environment + **/ + void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env); + + /** + * Called by the parser before processing a subcircuit. + * @param subName Name of the subcircuit + * @param in Input nodes + * @param out Output nodes + * @param parameters Default parameters for this subcircuit + * @param env Current environment + **/ + void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env); + + /** + * Called by the parser after processing a subcircuit. + * @param subName Name of the subcircuit + * @param env Current environment + **/ + void endSubcircuit(String subName, Environment env); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInlineFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInlineFactory.java new file mode 100644 index 0000000000..d968aa8635 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInlineFactory.java @@ -0,0 +1,348 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.Reader; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.file.cdl.CDLFileFormatException; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.container.Pair; + + +/** + * Inlines cells in a CDL file. + **/ +public class CDLInlineFactory implements CDLFactoryInterface { + private class Inliner implements CDLFactoryInterface { + /** Mapping from formal to actual parameters */ + private final Map param; + /** What to prefix to internal nodes */ + private final HierName prefix; + public Inliner(Map param, HierName prefix) { + this.param = param; + this.prefix = prefix; + } + + /* This function depends on how HierName determines a name is + * generated. Currently, this is determined by if there exist a '#' in + * the name. */ + private HierName markAsGenerated(final HierName n) { + return n.appendString("#"); + } + + private HierName prefix(HierName name) { + return HierName.append(prefix, name); + } + private HierName subst(HierName name) { + if (param.containsKey(name)) return (HierName) param.get(name); + else { + if (markGenerated && name.isNumeric()) { + name = markAsGenerated(name); + } + return prefix(name); + } + } + private HierName[] subst(HierName[] names) { + HierName[] translated = new HierName[names.length]; + for (int i = 0; i < names.length; i++) { + translated[i] = subst(names[i]); + } + return translated; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + proxy.makeResistor(prefix(name), subst(n1), subst(n2), val, parameters, env); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + proxy.makeCapacitor(prefix(name), subst(npos), subst(nneg), val, parameters, env); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + proxy.makeTransistor(prefix(name), type, subst(ns), subst(nd), + subst(ng), subst(nb), w, l, parameters, env); + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + proxy.makeDiode(prefix(name), type, subst(npos), subst(nneg), val, parameters, env); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + proxy.makeInductor(prefix(name), subst(npos), subst(nneg), val, parameters, env); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + proxy.makeBipolar(prefix(name), type, subst(nc), subst(nb), + subst(ne), val, parameters, env); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + callProxy.makeCall(prefix(name), subName, subst(args), parameters, env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + proxy.beginSubcircuit(subName, in, out, parameters, env); + } + + public void endSubcircuit(String subName, Environment env) { + proxy.endSubcircuit(subName, env); + } + } + + /** + * An interface for getting a template from the name of the subcircuit. + **/ + public interface Retriever { + Template getTemplate(final String name); + } + + /** + * Return a template for a given name by reading the cell from CAST. + **/ + public static class RetrieveFromCast implements Retriever { + private final CastFileParser cfp; + public RetrieveFromCast(final CastFileParser cfp) { + this.cfp = cfp; + } + public Template getTemplate(final String subName) { + final CellInterface cell; + try { + cell = cfp.getFullyQualifiedCell(subName); + } catch (Exception e) { + throw new RuntimeException("Cannot load gate " + subName + "!"); + } + final Set ports = NetlistAdapter.getParameterList(cell); + final String[] out = new String[ports.size()]; + int j = 0; + for (Iterator i = ports.iterator(); i.hasNext(); ++j) { + out[j] = ((HierName) i.next()).getCadenceString(); + } + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + return Template.setInOut(nb.getCDLTemplate(), new String[0], + out); + } + } + + private final Map templates; + private CDLFactoryInterface proxy; + private CDLFactoryInterface callProxy; + private final boolean markGenerated; + private final Retriever retriever; + private boolean bFlatten; + + public CDLInlineFactory() { + this(false); + } + + public CDLInlineFactory(final boolean markGenerated) { + this(markGenerated, null); + } + + /** + * CDLInlineFactory constructor. + * @param markGenerated Use true if names that look like internally + * generated nodes in cells to be inlined are marked as such (by appending + * a '#') in the output. + * @param retriever A Retriever that returns an Template when given a + * subcircuit name. If the function is not to be inlined, the function + * returns null. + **/ + public CDLInlineFactory(final boolean markGenerated, final Retriever retriever) { + this(markGenerated, retriever, false); + } + + public CDLInlineFactory(final boolean markGenerated, final Retriever retriever, boolean flatten) { + templates = new HashMap(); + this.markGenerated = markGenerated; + this.retriever = retriever; + this.bFlatten = flatten; + if(this.bFlatten) + this.callProxy = this; + } + + /** + * Add specified cells found in a reader to the set of cells to be + * flattened. + **/ + public void addTarget(Reader r, String[] cells) { + final Map m = Template.getTemplates(r); + for (int i = 0; i < cells.length; i++) { + if (m.containsKey(cells[i])) { + templates.put(cells[i], m.get(cells[i])); + } + } + } + /** + * Add all cells found in a reader to the set of cells to be flattened. + **/ + public void addTarget(Reader r) { + final Map m = Template.getTemplates(r); + templates.putAll(m); + } + + /** + * Add the specified cell to be flattened. + **/ + public void addTarget(final String cell, final Template templ) { + templates.put(cell, templ); + } + + /** + * Add the specified cells to be flattened. + **/ + public void addTargets(final Map cells) { + templates.putAll(cells); + } + + /** + * Set the CDLFactoryInterface to write to. + **/ + public void setProxy(final CDLFactoryInterface proxy) { + this.proxy = proxy; + if(!bFlatten) + callProxy = proxy; + } + + /** + * Inline all cells specified as a target in all cells found in a reader. + **/ + public void process(Reader r, CDLFactoryInterface proxy) throws CDLFileFormatException { + setProxy(proxy); + try { + ReadCDLIntoFactory.readCDL(r, this); + } catch (Exception e) { + e.printStackTrace(); + throw new CDLFileFormatException(e); + } + } + + /** + * Return the templates associated with a subcircuit. If the templates + * does not already exist in the cache of templates, try to obtain it from + * the template retriever. + * @param subName Name of the template to get. + **/ + private Template getTemplate(final String subName) { + if (!templates.containsKey(subName) && retriever != null) { + final Template t = retriever.getTemplate(subName); + if (t != null) templates.put(subName, t); + } + return (Template) templates.get(subName); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + final Template t = getTemplate(subName); + if (t == null) { + callProxy.makeCall(name, subName, args, parameters, env); + } else { + final Pair p = t.getArguments(); + final String[] in = (String []) p.getFirst(); + final String[] out = (String []) p.getSecond(); + if (in.length + out.length != args.length) { + System.err.println("Mismatched parameters in call " + name + " to " + subName + " expecting " + in.length + " input parameters and " + out.length + " output parameters, found " + args.length + "."); + return; + } + final Map m = new HashMap(); + int index = 0; + try { + for (int i = 0; i < in.length; i++, index++) { + m.put(HierName.makeHierName(in[i], '.'), args[index]); + } + for (int i = 0; i < out.length; i++, index++) { + m.put(HierName.makeHierName(out[i], '.'), args[index]); + } + } catch (InvalidHierNameException e) { + System.err.println("InvalidHierNameException cannot happen!"); + } + final Inliner inliner = new Inliner(m, name); + t.execute(inliner, parameters, NullEnvironment.getInstance(), null); + } + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + proxy.makeResistor(name, n1, n2, val, parameters, env); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + proxy.makeCapacitor(name, npos, nneg, val, parameters, env ); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + proxy.makeTransistor(name, type, ns, nd, ng, nb, w, l, parameters, env); + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + proxy.makeDiode(name, type, npos, nneg, val, parameters, env); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + proxy.makeInductor(name, npos, nneg, val, parameters, env); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + proxy.makeBipolar(name, type, nc, nb, ne, val, parameters, env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + proxy.beginSubcircuit(subName, in, out, parameters, env); + } + + public void endSubcircuit(String subName, Environment env) { + proxy.endSubcircuit(subName, env); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInterfaceSimplifier.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInterfaceSimplifier.java new file mode 100644 index 0000000000..7b5b28adcc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLInterfaceSimplifier.java @@ -0,0 +1,152 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; + +public abstract class CDLInterfaceSimplifier implements CDLFactoryInterface, CDLSimpleInterface { + /* These methods from CDLSimpleInterface must be implemented by any + * subclass. */ + public abstract void makeResistor(HierName name, HierName n1, + HierName n2, double val); + public abstract void makeCapacitor(HierName name, HierName npos, + HierName nneg, double val); + public abstract void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l); + public abstract void makeDiode(HierName name, int type, HierName npos, + HierName nneg, double w, double l, double a, double p ); + public abstract void makeInductor(HierName name, HierName npos, + HierName nneg, double val); + public abstract void makeBipolar(HierName name, int type, HierName nc, + HierName nb, HierName ne, double a); + public abstract void makeCall(HierName name, String subName, + HierName[] args, Map parameters); + public abstract void beginSubcircuit(String subName, String[] in, + String[] out); + public abstract void endSubcircuit(String subName); + + private Environment currentEnv; + + public CDLInterfaceSimplifier() { + currentEnv = new LocalEnvironment(); + } + + /* These methods are from CDLFactoryInterface. They simply invoke the + * simpler methods defined in CDLSimpleInterface. */ + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + final double res = getValue(val, env); + makeResistor(name, n1, n2, 1 / res); + } + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + final double cap = getValue(val, env); + makeCapacitor(name, npos, nneg, cap); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + final double wid = getValue(w, env); + final double len = getValue(l, env); + + int typ; + if (type.startsWith("p") || type.startsWith("P")) { + typ = DeviceTypes.P_TYPE; + } else { + typ = DeviceTypes.N_TYPE; + } + + makeTransistor(name, typ, ns, nd, ng, nb, wid, len); + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + final double a = getValue(val, env); + final double w = Math.sqrt(a); + final double l = w; + final double p = 2*w + 2*l; + + int typ; + if (type.equals("DW") || type.equals("dw")) { + typ = DeviceTypes.N_TYPE; + } else { + typ = DeviceTypes.P_TYPE; + } + + + makeDiode(name, typ, npos, nneg, w,l,a,p); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + final double ind = getValue(val, env); + makeCapacitor(name, npos, nneg, ind); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + int typ; + if (type.startsWith("p") || type.startsWith("P")) { + typ = DeviceTypes.P_TYPE; + } else { + typ = DeviceTypes.N_TYPE; + } + makeBipolar(name, typ, nc, nb, ne, getValue(val, env)); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + makeCall(name, subName, args, resolveCallParameter(parameters, env)); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + beginSubcircuit(subName, in, out); + } + + public void endSubcircuit(String subName, Environment env) { + endSubcircuit(subName); + } + + public static Map resolveCallParameter(Map parameters, Environment env) { + Map result = new HashMap(); + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final CDLLexer.InfoToken val = (CDLLexer.InfoToken) entry.getValue(); + result.put(entry.getKey(), val.getValue(env)); + } + return result; + } + + public static double getValue(final CDLLexer.InfoToken val, + final Environment env) { + final Double result = val.getValue(env); + if (result == null) { + throw new RuntimeException("Cannot evaluate floating point expression: " + val); + } + return result.doubleValue(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLNodeNameFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLNodeNameFilter.java new file mode 100644 index 0000000000..5752908412 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLNodeNameFilter.java @@ -0,0 +1,95 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +/** + * Allows transformation of node names by overriding the + * processNodeName method. By the default, the method is the identity + * transformation. + **/ +public class CDLNodeNameFilter implements CDLFactoryInterface { + protected CDLFactoryInterface inner; + + public CDLNodeNameFilter(final CDLFactoryInterface inner) { + this.inner = inner; + } + + protected HierName processNodeName(final HierName node) { + return node; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeResistor(name, processNodeName(n1), processNodeName(n2), val, + parameters, env); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeCapacitor(name, processNodeName(npos), processNodeName(nneg), + val, parameters, env); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + inner.makeTransistor(name, type, + processNodeName(ns), processNodeName(nd), + processNodeName(ng), processNodeName(nb), + w, l, parameters, env); + } + + + public void makeDiode(HierName name, String type, HierName npos, + HierName nneg, CDLLexer.InfoToken val, + Map parameters, Environment env) { + inner.makeDiode(name, type, + processNodeName(npos), processNodeName(nneg), val, + parameters, env); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + inner.makeInductor(name, processNodeName(npos), processNodeName(nneg), + val, parameters, env); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + inner.makeBipolar(name, type, processNodeName(nc), processNodeName(nb), + processNodeName(ne), val, parameters, env); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + final HierName[] processed = new HierName[args.length]; + for (int i = 0; i < args.length; ++i) { + processed[i] = processNodeName(args[i]); + } + inner.makeCall(name, subName, processed, parameters, env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + inner.beginSubcircuit(subName, in, out, parameters, env); + } + + public void endSubcircuit(String subName, Environment env) { + inner.endSubcircuit(subName, env); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScaleBali.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScaleBali.java new file mode 100644 index 0000000000..a403ac2337 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScaleBali.java @@ -0,0 +1,265 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.lang.Double; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringReader; +import java.util.Map; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.IndentWriter; +import com.avlsi.io.NullWriter; +import com.avlsi.util.cmdlineargs.*; +import com.avlsi.util.cmdlineargs.defimpl.*; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.text.PrintfFormat; + +public final class CDLScaleBali extends CDLFactoryFilter { + private final double mMosWidthScaleFactor; + private final double mMosLengthScaleFactor; + private static final Pattern GATE_REGEX = + Pattern.compile("(.*)\\.\\d(\\(.*\\))?"); + private static final double GRID = 0.005e-6; + + private final static class ScalingToken extends CDLLexer.InfoToken { + private final CDLLexer.InfoToken mWrapped; + private final double mScale; + private final boolean isWidth; + + public ScalingToken( final CDLLexer.InfoToken wrapped, double scale ) { + this(wrapped, scale, false); + } + + public ScalingToken( final CDLLexer.InfoToken wrapped, double scale, + boolean width) { + super( 0, wrapped.getText() ); + mWrapped = wrapped; + mScale = scale; + isWidth = width; + } + + public String getText( Environment env ) { + final Double value = getValue( env ); + + if ( value != null ) { + setText(value.toString()); + return value.toString(); + } + else { + //return Double.toString( mScale ) + "( " + mWrapped.getText( env ) + " )"; + setText("'" + Double.toString(mScale) + "* (" + mWrapped.getText() + ")'"); + return "'" + Double.toString(mScale) + "* (" + mWrapped.getText() + ")'"; + } + } + + public Double getValue( Environment env ) { + final Double wrappedValue = mWrapped.getValue( env ); + if ( wrappedValue != null ) { + if (getText().indexOf("W") == -1 && + getText().indexOf("w") == -1 && + getText().indexOf("L") == -1 && + getText().indexOf("l") == -1 ) { + if (isWidth) { + double x = 0.6 * wrappedValue.doubleValue(); + if (x < 0.12e-6) x = 0.12e-6; + setText((new Double(x)).toString()); + } else { + if (Math.abs(wrappedValue.doubleValue() - 0.13e-6) < 0.1e-8) { + setText("0.06u"); + } else { + setText((new Double(0.6 * wrappedValue.doubleValue() - 0.018e-6)).toString()); + } + } + } + return new Double( 0.6 * wrappedValue.doubleValue() ); + } + else { + return null; + } + } + + } + + public CDLScaleBali(final double mosWidthScaleFactor, + final double mosLengthScaleFactor, + final CDLFactoryInterface chained ) { + super(chained); + mMosWidthScaleFactor = mosWidthScaleFactor; + mMosLengthScaleFactor = mosLengthScaleFactor; + + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + inner.makeTransistor( name, + type, + ns, + nd, + ng, + nb, + new ScalingToken( w, mMosWidthScaleFactor, true ), + new ScalingToken( l, mMosLengthScaleFactor, false ), + parameters, + env ); + } + + private double scaleParam(String cell, String param, double val) { + if ((param.equals("NL") || param.equals("PL")) && + val == 0.13e-6) { + return 0.06e-6; + } else { + val = val * 0.6; + if (param.indexOf("W") != -1 || param.indexOf("w") != -1) { + if (val < 0.12e-6) val = 0.12e-6; + } else if (param.indexOf("L") != -1 || param.indexOf("l") != -1) { + val = val - 0.018e-6; + } + return val; + } + } + + private static final PrintfFormat FORMAT = new PrintfFormat("%.3fu"); + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + final Map resolved = + CDLInterfaceSimplifier.resolveCallParameter(parameters, env); + for (Iterator i = resolved.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String key = (String) entry.getKey(); + final Double val = (Double) entry.getValue(); + final double scaled = scaleParam(subName, key, val.doubleValue()); + entry.setValue( + new CDLLexer.SimpleToken( + new Double(scaled), + FORMAT.sprintf(Math.round(scaled/GRID)*GRID*1e6))); + } + final Matcher m = GATE_REGEX.matcher(subName); + if (m.matches()) { + final String baseName = m.group(1); + subName = baseName + ".0(" + + (baseName.startsWith("stack") ? "1" : "1,1") + + ")"; + } + inner.makeCall( name, subName, args, resolved, env ); + } + + private static void writeSpec(final File outputDir, + final CellInterface cell) + throws IOException, RecognitionException, TokenStreamException { + final String type = cell.getFullyQualifiedType(); + final String castFile = type.replace('.', File.separatorChar) + ".cast"; + final File outCast = new File(outputDir, castFile); + outCast.getParentFile().mkdirs(); + final IndentWriter iw = + new IndentWriter(new BufferedWriter(new FileWriter(outCast))); + final String module = cell.getModuleName(); + final String subtype = cell.getType(); + iw.write("module " + module + ";\n"); + iw.write("define \"" + subtype + + "\"() <+ standard.process.scaled_layout_cell" + + " <: " + module + " {\n"); + iw.nextLevel(); + iw.write("netlist {\n"); + iw.nextLevel(); + final CDLScaleBali factory = + new CDLScaleBali(0.6, 0.6, new CDLFactoryEmitter(iw)); + final NetlistBlock block = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST).next(); + block.getCDLTemplate().execute(factory); + iw.prevLevel(); + iw.write("}\n"); + iw.write("directives {\n"); + iw.nextLevel(); + iw.write("fixed_size = true;\n"); + iw.prevLevel(); + iw.write("}\n"); + iw.prevLevel(); + iw.write("}\n"); + iw.close(); + } + + private static void usage() { + System.out.print( + "Usage: scalebali --cast-path= (130 nm CAST path)\n" + + " --output-dir= (65 nm spec directory)\n" + + " [--verbose (print stack traces)\n]" + + " cell [cell ...]\n"); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl(args); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs(argsWithConfigs); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs(cachedArgs); + + final CommandLineArgs theArgs = pedanticArgs; + + final String castPath = theArgs.getArgValue("cast-path", null); + final String outputPath = theArgs.getArgValue("output-dir", null); + final boolean verbose = theArgs.argExists("verbose"); + int errors = 0; + if (castPath == null) { + System.err.println("--cast-path must be specified."); + ++errors; + } + if (outputPath == null) { + System.err.println("--output-dir must be specified."); + ++errors; + } + if (errors > 0) { + usage(); + System.exit(1); + } + final CastFileParser cfp = + new CastFileParser(new FileSearchPath(castPath), "2"); + final File outputDir = new File(outputPath); + for (StringContainerIterator i = theArgs.nonParsedArgumentsIterator(); + i.hasNext(); ) { + final String name = i.next(); + try { + final CellInterface cell = cfp.getFullyQualifiedCell(name); + writeSpec(outputDir, cell); + } catch (Exception e) { + System.err.println("Error processing " + name + + ": " + e.getMessage() + "; skipping"); + if (verbose) { + e.printStackTrace(); + } + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScalingFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScalingFactory.java new file mode 100644 index 0000000000..1e9e850a19 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLScalingFactory.java @@ -0,0 +1,187 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.lang.Double; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.common.HierName; + + + +public final class CDLScalingFactory implements CDLFactoryInterface { + private final double mMosWidthScaleFactor; + private final double mMosLengthScaleFactor; + private final double mResistanceScaleFactor; + private final double mCapacitanceScaleFactor; + private final double mDiodeAreaScaleFactor; + private final double mInductanceScaleFactor; + private final double mBipolarAreaScaleFactor; + + private final CDLFactoryInterface mChained; + + private final static class ScalingToken extends CDLLexer.InfoToken { + private final CDLLexer.InfoToken mWrapped; + private final double mScale; + + public ScalingToken( final CDLLexer.InfoToken wrapped, double scale ) { + super( 0, "" ); + mWrapped = wrapped; + mScale = scale; + } + + public String getText( Environment env ) { + final Double value = getValue( env ); + + if ( value != null ) { + return value.toString(); + } + else { + return Double.toString( mScale ) + "( " + mWrapped.getText( env ) + " )"; + } + } + + public Double getValue( Environment env ) { + final Double wrappedValue = mWrapped.getValue( env ); + if ( wrappedValue != null ) { + return new Double( mScale * wrappedValue.doubleValue() ); + } + else { + return null; + } + } + + } + + public CDLScalingFactory( final double mosWidthScaleFactor, + final double mosLengthScaleFactor, + final double resistanceScaleFactor, + final double capacitanceScaleFactor, + final double diodeAreaScaleFactor, + final double inductanceScaleFactor, + final CDLFactoryInterface chained ) { + this(mosWidthScaleFactor, mosLengthScaleFactor, resistanceScaleFactor, + capacitanceScaleFactor, diodeAreaScaleFactor, + inductanceScaleFactor, 1, chained); + } + + public CDLScalingFactory( final double mosWidthScaleFactor, + final double mosLengthScaleFactor, + final double resistanceScaleFactor, + final double capacitanceScaleFactor, + final double diodeAreaScaleFactor, + final double inductanceScaleFactor, + final double bipolarAreaScaleFactor, + final CDLFactoryInterface chained ) { + mMosWidthScaleFactor = mosWidthScaleFactor; + mMosLengthScaleFactor = mosLengthScaleFactor; + mResistanceScaleFactor = resistanceScaleFactor; + mCapacitanceScaleFactor = capacitanceScaleFactor; + mDiodeAreaScaleFactor = diodeAreaScaleFactor; + mInductanceScaleFactor = inductanceScaleFactor; + mBipolarAreaScaleFactor = bipolarAreaScaleFactor; + mChained = chained; + + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, Environment env) { + mChained.makeResistor( name, + n1, + n2, + new ScalingToken( val, mResistanceScaleFactor ), + parameters, + env ); + } + + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + mChained.makeCapacitor( name, + npos, + nneg, + new ScalingToken( val, mCapacitanceScaleFactor ), + parameters, + env ); + } + + + public void makeTransistor(HierName name, String type, HierName ns, HierName nd, + HierName ng, HierName nb, CDLLexer.InfoToken w, + CDLLexer.InfoToken l, Map parameters, Environment env) { + mChained.makeTransistor( name, + type, + ns, + nd, + ng, + nb, + new ScalingToken( w, mMosWidthScaleFactor ), + new ScalingToken( l, mMosLengthScaleFactor ), + parameters, + env ); + } + + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken area, Map parameters, Environment env) { + mChained.makeDiode( name, + type, + npos, + nneg, + new ScalingToken( area, mDiodeAreaScaleFactor ), + parameters, + env ); + + } + + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + mChained.makeInductor( name, + npos, + nneg, + new ScalingToken( val, mInductanceScaleFactor ), + parameters, + env ); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken area, + Map parameters, Environment env) { + mChained.makeBipolar( name, + type, + nc, + nb, + ne, + new ScalingToken( area, mBipolarAreaScaleFactor ), + parameters, + env ); + + } + + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + mChained.makeCall( name, subName, args, parameters, env ); + } + + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + mChained.beginSubcircuit( subName, in, out, parameters, env ); + } + + + public void endSubcircuit(String subName, Environment env) { + mChained.endSubcircuit( subName, env ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleFilter.java new file mode 100644 index 0000000000..c7132ed9d7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleFilter.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.file.common.HierName; + +/** + * A simple implementation of CDLSimpleInterface, which can be easily extended + * by classes that wish to override a few methods. + **/ +public class CDLSimpleFilter implements CDLSimpleInterface { + protected CDLSimpleInterface output = null; + + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + output.makeResistor(name, n1, n2, val); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { + output.makeCapacitor(name, npos, nneg, val); + } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + output.makeTransistor(name, type, ns, nd, ng, nb, w, l); + } + + public void makeDiode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p) { + output.makeDiode(name, type, npos, nneg, w, l, a, p); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { + output.makeInductor(name, npos, nneg, val); + } + + public void makeBipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a) { + output.makeBipolar(name, type, nc, nb, ne, a); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { + output.makeCall(name, subName, args, parameters); + } + + public void beginSubcircuit(String subName, String[] in, String[] out) { + output.beginSubcircuit(subName, in, out); + } + + public void endSubcircuit(String subName) { + output.endSubcircuit(subName); + } + + public void setOutput(final CDLSimpleInterface output) { + this.output = output; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleImpl.java new file mode 100644 index 0000000000..9b92564b4f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleImpl.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.file.common.HierName; + +/** + * A simple implementation of CDLSimpleInterface, which can be easily extended + * by classes that wish to override a few methods. + **/ +public class CDLSimpleImpl implements CDLSimpleInterface { + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { } + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { } + + public void makeDiode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p) { } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { } + + public void makeBipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a) { } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { } + + public void beginSubcircuit(String subName, String[] in, String[] out) { } + + public void endSubcircuit(String subName) { } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleInterface.java new file mode 100644 index 0000000000..f22c90c762 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLSimpleInterface.java @@ -0,0 +1,107 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.file.common.HierName; + +/** + * A simplied factory interface which makes the CDL parser easier to use. + **/ +public interface CDLSimpleInterface { + /** + * Called by the parser to make a resistor. + * @param name Name of the resistor + * @param n1 First terminal + * @param n2 Second terminal + * @param val Conductance in mho + **/ + void makeResistor(HierName name, HierName n1, HierName n2, double val); + + /** + * Called by the parser to make a capacitor. + * @param name Name of the capacitor + * @param npos Positive terminal + * @param nneg Negative terminal + * @param val Capacitance in farads + **/ + void makeCapacitor(HierName name, HierName npos, HierName nneg, double val); + + /** + * Called by the parser to make a transistor. + * @param name Name of the transistor + * @param type Type of the transistor + * @param ns Source + * @param nd Drain + * @param ng Gate + * @param nb Bulk + * @param w Width of the transistor in meters + * @param l Length of the transistor in meters + **/ + void makeTransistor(HierName name, int type, HierName ns, HierName nd, + HierName ng, HierName nb, double w, double l); + + /** + * Called by the parser to make a diode. + * @param name Name of the diode + * @param type Type of the diode + * @param npos Positive terminal + * @param nneg Negative terminal + * @param w Width of the diode in meters + * @param l Length of the diode in meters + * @param a Area of the diode in square meters + * @param p Perimeter of the diode in meters + **/ + void makeDiode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p); + + /** + * Called by the parser to make an inductor. + * @param name Name of the inductor + * @param npos Positive terminal + * @param nneg Negative terminal + * @param val Inductance in henrys + **/ + void makeInductor(HierName name, HierName npos, HierName nneg, double val); + + /** + * Called by the parser to make a BJT. + * @param name Name of the diode + * @param type Type of the diode + * @param nc Collection terminal + * @param nb Base terminal + * @param ne Emitter terminal + * @param a Area of the diode in square meters + **/ + void makeBipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a); + + /** + * Called by the parser to make a call. + * @param name Name of the instantiation + * @param subName Name of the subcircuit + * @param args Arguments to the subcircuit + * @param parameters Parameters defined on the call (String to Double) + **/ + void makeCall(HierName name, String subName, HierName[] args, Map parameters); + + /** + * Called by the parser before processing a subcircuit. + * @param subName Name of the subcircuit + * @param in Input nodes + * @param out Output nodes + **/ + void beginSubcircuit(String subName, String[] in, String[] out); + + /** + * Called by the parser after processing a subcircuit. + * @param subName Name of the subcircuit + **/ + void endSubcircuit(String subName); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLstat.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLstat.java new file mode 100644 index 0000000000..b72a0a9d83 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CDLstat.java @@ -0,0 +1,634 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.Iterator; +import java.util.Map; +import java.util.Stack; + +import com.avlsi.util.container.Counter; +import com.avlsi.util.container.HashCounter; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.tools.jauto.TechnologyData; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.text.StringUtil; +import com.avlsi.util.text.NumberFormatter; + +public class CDLstat implements CDLSimpleInterface { + /** Contains statistics for all the instanciations of a cell, + NOT for all the instances in that cell. */ + private static class InstStat { + /** Number of instances */ + public int instances = 0; + + /** Map of nets to connection count*/ + public HashCounter netCounter = new HashCounter(); + /** Map of ports */ + public HashSet portSet = new HashSet(); + /** Total number of transistors */ + public int totalTransistors = 0; + /** Total area of all instances */ + public double totalArea = 0; + /** Total area (with overhead) of all instances */ + public double totalAreaWithOverhead = 0; + /** Total width of transistors in all instances */ + public double totalWidth = 0; + /** Total length of transistors in all instances */ + public double totalLength = 0; + + /** Total number of resistors */ + public double totalResistors = 0; + /** Total resistance */ + public double totalResistance = 0; + + /** Total number of capacitors */ + public double totalCapacitors = 0; + /** Total capacitance */ + public double totalCapacitance = 0; + + /** The area of the largest instance */ + public double maxArea = -Double.MAX_VALUE; + /** The area of the smallest instance */ + public double minArea = Double.MAX_VALUE; + } + + public static class EstimatedSize { + public double width; + public double height; + public final double availableArea; + /** Density factor computed from available area. */ + public final double reportDensityFactor; + + /** + * Choose width or height to satisfy: + * (width - cellWidthOverhead) * (height - cellHeightOverhead) + * >= transistorArea * densityFactor + **/ + public EstimatedSize(final double cellWidth, + final double cellHeight, + final double densityFactor, + final double cellWidthOverhead, + final double cellHeightOverhead, + final double cellWidthIncrement, + final double cellHeightIncrement, + final double cellWidthMinimum, + final double cellHeightMinimum, + final double transistorArea) { + double a = densityFactor * transistorArea; + if (cellHeight > 0 && cellWidth > 0) { + height = cellHeight; + width = cellWidth; + } else if (cellHeight > 0) { + height = cellHeight; + width = a / (height - cellHeightOverhead) + cellWidthOverhead; + width = round(width,cellWidthIncrement); + width = Math.max(width,cellWidthMinimum); + } else if (cellWidth > 0) { + width = cellWidth; + height = a / (width - cellWidthOverhead) + cellHeightOverhead; + height = round(height,cellHeightIncrement); + height = Math.max(height,cellHeightMinimum); + } else { + throw new IllegalArgumentException( + "Must specify at least height or width"); + } + availableArea = (width - cellWidthOverhead) * + (height - cellHeightOverhead); + reportDensityFactor = availableArea / transistorArea; + } + + private double round(final double value, final double incr) { + return incr == 0 ? value : incr * Math.ceil(value / incr); + } + + public String toString() { + return String.format("EstimatedSize: width=%g height=%g " + + "availableArea=%g reportDensityFactor=%g", + width, height, availableArea, + reportDensityFactor); + } + } + + /** Contains statistics for a cell */ + public static class CellStat { + + public int getNumNets() { + return netCounter.size(); + } + + public int getNumLocalNets() { + return netCounter.size() - portSet.size(); + } + + public int getNumPorts() { + return portSet.size(); + } + + public int getNumConnections() { + return netCounter.getTotalCount(); + } + + /** Map of nets to connection count*/ + public Counter netCounter = new HashCounter(); + /** Set of ports */ + public Set portSet = new HashSet(); + + /** Number of instances */ + public int instances = 0; + /** Number of transistors */ + public int transistors = 0; + /** Gate area of transistors */ + public double area = 0; + /** Area of transistors (including overhead) **/ + public double areaWithOverhead = 0; + /** Total width of transistors */ + public double width = 0; + /** Total length of transistors */ + public double length = 0; + + /** Total resistance */ + public double resistance = 0; + /** Number of resistors */ + public int resistors = 0; + + /** Total capacitance */ + public double capacitance = 0; + /** Number of capacitors */ + public int capacitors = 0; + + public String toString() { + return String.format("CellStat: instances=%d transistors=%d " + + "area=%g areaWithOverhead=%g width=%g " + + "length=%g resistance=%g resistors=%d " + + "capacitance=%g capacitors=%d numNets=%d " + + "numLocalNets=%d numPorts=%d " + + "numConnections=%d", + instances, transistors, + area, areaWithOverhead, width, + length, resistance, resistors, + capacitance, capacitors, getNumNets(), + getNumLocalNets(), getNumPorts(), + getNumConnections()); + } + } + + private Exception mError; + + private final Map instStatMap; + private final Map cellStatMap; + private final Map cellTemplateMap; + private final Stack stack; + private final double transistorWidthOverhead; + private final double transistorLengthOverhead; + + private CDLstat( final Map instStatMap, + final Map cellStatMap, + final Map cellTemplateMap, + final double transistorWidthOverhead, + final double transistorLengthOverhead + ) { + this.instStatMap = instStatMap; + this.cellStatMap = cellStatMap; + this.cellTemplateMap = cellTemplateMap; + this.transistorWidthOverhead = transistorWidthOverhead; + this.transistorLengthOverhead = transistorLengthOverhead; + this.stack = new Stack(); + this.stack.push( new CellStat() ); + this.mError = null; + } + + public Exception getError() { + return mError; + } + + private CellStat current() { + if ( stack.empty() ) { + return null; + } + else { + return ( CellStat ) stack.peek(); + } + } + + public void makeResistor( HierName name, + HierName n1, + HierName n2, + double val) { + if ( mError == null ) { + final CellStat stat = current(); + stat.resistors++; + // val is mho, convert to ohm + stat .resistance += 1 / val; + stat.netCounter.add(n1); + stat.netCounter.add(n2); + } + } + + public void makeCapacitor( HierName name, + HierName npos, + HierName nneg, + double val ) { + if ( mError == null ) { + final CellStat stat = current(); + stat.capacitors++; + stat.capacitance += val; + stat.netCounter.add(npos); + stat.netCounter.add(nneg); + } + } + + public void makeTransistor( HierName name, + int type, + HierName ns, + HierName nd, + HierName ng, + HierName nb, + double w, + double l ) { + if ( mError == null ) { + final CellStat stat = current(); + stat.netCounter.add(ns); + stat.netCounter.add(nd); + stat.netCounter.add(ng); + stat.netCounter.add(nb); + stat.transistors++; + stat.area += w * l; + stat.areaWithOverhead += (w + transistorWidthOverhead) * + (l + transistorLengthOverhead); + stat.width += w; + stat.length += l; + } + } + + public void makeDiode( HierName name, + int type, + HierName npos, + HierName nneg, + double w, + double l, + double a, + double p ) { + if ( mError == null ) { + final CellStat stat = current(); + stat.netCounter.add(npos); + stat.netCounter.add(nneg); + } + } + + public void makeInductor( HierName name, + HierName npos, + HierName nneg, + double val ) { + if ( mError == null ) { + final CellStat stat = current(); + stat.netCounter.add(npos); + stat.netCounter.add(nneg); + } + } + + public void makeBipolar(HierName name, + int type, + HierName nc, + HierName nb, + HierName ne, + double a) { + if ( mError == null ) { + final CellStat stat = current(); + stat.netCounter.add(nc); + stat.netCounter.add(nb); + stat.netCounter.add(ne); + } + } + + + private void updateInstStat( String subName, CellStat stat ) { + if (!instStatMap.containsKey(subName)) { + instStatMap.put(subName, new InstStat()); + } + + InstStat s = (InstStat) instStatMap.get(subName); + s.instances++; + + s.netCounter.addAll(stat.netCounter); + s.portSet.addAll(stat.portSet); + + s.instances += stat.instances; + s.totalTransistors += stat.transistors; + s.totalArea += stat.area; + s.totalAreaWithOverhead += stat.areaWithOverhead; + s.totalWidth += stat.width; + s.totalLength += stat.length; + if (stat.area > s.maxArea) { + s.maxArea = stat.area; + } + if (stat.area < s.minArea) { + s.minArea = stat.area; + } + + s.totalResistors += stat.resistors; + s.totalResistance += stat.resistance; + + s.totalCapacitors += stat.capacitors; + s.totalCapacitance += stat.capacitance; + } + + public void makeCall( final HierName name, + final String subName, + final HierName[] args, + final Map parameters) { + + if ( mError == null ) { + + final CellStat stat = current(); + + for(int i=0; i width) return text.substring(0, width); + else return StringUtil.repeatString(" ", width - len) + text; + } + + private static String leftJustify(String text, int width) { + final int len = text.length(); + if (len == width) return text; + else if (len > width) return text.substring(0, width); + else return text + StringUtil.repeatString(" ", width - len); + } + + private static String centerJustify(String text, int width) { + final int len = text.length(); + if (len == width) return text; + else if (len > width) return text.substring(0, width); + else { + int half = (width - len) / 2; + return StringUtil.repeatString(" ", half) + text + StringUtil.repeatString(" ", width - len - half); + } + } + + private static String format(double val) { + if (val == 0) return "0"; + else return NumberFormatter.format(val); + } + + private static String format(double val, int prec) { + return NumberFormatter.format(val, prec); + } + + private static void formatStat1(String type, InstStat s) { + /* Ugh. I NEED PRINTF! */ + System.out.print(leftJustify(type, 27) + " "); + System.out.print(rightJustify(format(s.instances), 6) + " "); + System.out.print(rightJustify(format(s.totalTransistors), 10) + " "); + System.out.print(leftJustify(format(s.totalArea, 4), 11)); + System.out.print(leftJustify(format(s.minArea, 4), 11)); + System.out.println(leftJustify(format(s.maxArea, 4), 11)); + } + private static void formatStat2(String type, InstStat s) { + System.out.print(leftJustify(type, 27) + " "); + System.out.print(rightJustify(format(s.totalResistors), 6) + " "); + System.out.print(leftJustify(format(s.totalResistance, 4), 9) + " "); + System.out.print(rightJustify(format(s.totalCapacitors), 6) + " "); + System.out.print(leftJustify(format(s.totalCapacitance, 4), 11) + " "); + System.out.println(leftJustify(format(s.totalWidth, 4), 10)); + System.out.println(leftJustify(format(s.totalLength, 4), 10)); + } + + private static void usage() { + final String className = CDLstat.class.getName(); + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className + "\n" + + "[--verbose] --cell= ..." ); + } + + + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + final String cell = theArgs.getArgValue("cell", null); + final boolean verbose = theArgs.argExists("verbose"); + if (cell == null) { + System.err.println("You must specify a cell name."); + usage(); + System.exit(1); + } + final Map cellTemplates = new HashMap(); + + Template.getTemplates( theArgs.nonParsedArgumentsIterator(), + cellTemplates ); + + final CellStat result; + + if (verbose) { + final Map cellStatMap = new HashMap(); + final Map instStatMap = new HashMap(); + result = getCellStat( cell, cellTemplates, cellStatMap, instStatMap, 0, 0 ); + + System.out.print(leftJustify("Type", 28)); + System.out.print(centerJustify("Uses", 7)); + System.out.print(centerJustify("Transistors", 11)); + System.out.print(centerJustify("Area", 11)); + System.out.print(centerJustify("Min Area", 11)); + System.out.println(centerJustify("Max Area", 11)); + for ( Iterator i = instStatMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String type = (String) entry.getKey(); + final InstStat s = (InstStat) entry.getValue(); + formatStat1(type, s); + } + System.out.print(leftJustify("Type", 28)); + System.out.print(centerJustify("R", 7)); + System.out.print(centerJustify("ohm", 10)); + System.out.print(centerJustify("C", 7)); + System.out.print(centerJustify("farad", 12)); + System.out.println(centerJustify("Width", 10)); + for (Iterator i = instStatMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String type = (String) entry.getKey(); + final InstStat s = (InstStat) entry.getValue(); + formatStat2(type, s); + } + } + else { + result = getCellStat( cell, cellTemplates ); + } + + + System.out.println("Total Nets = " + result.getNumNets()); + System.out.println("Total Ports = " + result.getNumPorts()); + System.out.println("Total Local Nets = " + result.getNumLocalNets()); + System.out.println("Total Internal Connections at top level = " + result.getNumConnections()); + System.out.println("Total transistors = " + result.transistors); + System.out.println("Total area = " + result.area); + System.out.println("Average area = " + result.area / result.transistors); + System.out.println("Total width = " + result.width); + System.out.println("Total length = " + result.length); + System.out.println("Average width = " + result.width / result.transistors); + System.out.println("Total resistors = " + result.resistors); + System.out.println("Total resistance = " + result.resistance); + System.out.println("Average resistance = " + result.resistance / result.resistors); + System.out.println("Total capacitors = " + result.capacitors); + System.out.println("Total capacitance = " + result.capacitance); + System.out.println("Average capacitance = " + result.capacitance / result.capacitors); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CanonicalizeCDL.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CanonicalizeCDL.java new file mode 100644 index 0000000000..ddfe332bf8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CanonicalizeCDL.java @@ -0,0 +1,89 @@ +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.AliasedSet; + +/** + * Canonicalizes nodes in a CDL according to an AliasedSet. Any nodes not + * found in the AliasedSet are left unchanged. This class works as a filter. + **/ +public class CanonicalizeCDL implements CDLFactoryInterface { + /** Which CDLFactoryInterface to write output to */ + private final CDLFactoryInterface out; + + /** AliasedSet containing information on which nodes are aliases */ + private final AliasedSet alias; + + public CanonicalizeCDL(final CDLFactoryInterface out, + final AliasedSet alias) { + this.out = out; + this.alias = alias; + } + + private HierName canon(final HierName name) { + final Object result = (HierName) alias.getCanonicalKey(name); + return result == null ? name : (HierName) result; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + out.makeResistor(name, canon(n1), canon(n2), val, parameters, env); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + out.makeCapacitor(name, canon(npos), canon(nneg), val, parameters, env); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + out.makeTransistor(name, type, canon(ns), canon(nd), canon(ng), + canon(nb), w, l, parameters, env); + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + out.makeDiode(name, type, canon(npos), canon(nneg), val, parameters,env); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + out.makeInductor(name, canon(npos), canon(nneg), val, parameters, env); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + out.makeBipolar(name, type, canon(nc), canon(nb), canon(ne), val, + parameters,env); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + HierName[] canonArgs = new HierName[args.length]; + for (int i = 0; i < args.length; i++) { + canonArgs[i] = canon(args[i]); + } + out.makeCall(name, subName, canonArgs, parameters, env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + this.out.beginSubcircuit(subName, in, out, parameters, env); + } + + public void endSubcircuit(String subName, Environment env) { + out.endSubcircuit(subName, env); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CellSetFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CellSetFactory.java new file mode 100644 index 0000000000..2539c7c9fa --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/CellSetFactory.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.parser; + +import java.util.Set; +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.CDLFactoryAdaptor; + +public final class CellSetFactory extends CDLFactoryAdaptor { + private final Set mCellSet; + + public CellSetFactory( final Set targetSet ){ + mCellSet = targetSet; + } + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + mCellSet.add( subName ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ChildrenFirstTemplateIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ChildrenFirstTemplateIterator.java new file mode 100644 index 0000000000..3beafe2bdc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ChildrenFirstTemplateIterator.java @@ -0,0 +1,268 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.parser; + + +import java.util.NoSuchElementException; + +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.HashSet; +import java.util.NoSuchElementException; +import java.util.Iterator; + +import com.avlsi.file.common.HierName; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.TemplateIterator; + +public class ChildrenFirstTemplateIterator implements TemplateIterator { + + private static class CallIterator { + + public static class Call { + private final String mName; + private final String mMasterName; + + public Call( final String name, + final String masterName ) { + mName = name; + mMasterName = masterName; + } + + public final String getName() { + return mName; + } + + public final String getMasterName() { + return mMasterName; + } + } + + private final Template.StatementIterator mIter; + private Call mCurrCall; + + public CallIterator( Template.StatementIterator iter ) { + mIter = iter; + mCurrCall = null; + } + + public boolean hasNext() { + while ( ( mCurrCall == null ) && ( mIter.hasNext() ) ) { + mIter.next( new Template.Visitor() { + public void resistorStatement( final HierName name, + final HierName n1, + final HierName n2, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) {} + public void capacitorStatement( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) {} + + public void transistorStatement( final HierName name, + final String type, + final HierName ns, + final HierName nd, + final HierName ng, + final HierName nb, + final CDLLexer.InfoToken w, + final CDLLexer.InfoToken l, + final Map parameters, + final Environment env ) {} + + public void inductorStatement( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) {} + + public void diodeStatement( final HierName name, + final String type, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) {} + public void bipolarStatement( final HierName name, + final String type, + final HierName nc, + final HierName nb, + final HierName ne, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) {} + public void callStatement( final HierName name, + final String subName, + final HierName[] args, + final Map parameters, + final Environment env ) { + mCurrCall = new Call( name.toString(), + subName ); + } + } ); + } + return mCurrCall != null; + } + + public Call next() { + if ( hasNext() ) { + final Call ret = mCurrCall; + mCurrCall = null; + return ret; + } + else { + throw new NoSuchElementException( ); + } + } + } + + private static class StackFrame { + private final String mTemplateName; + private final Template mTemplate; + private final CallIterator mIter; + + public StackFrame( final Template template, + final String templateName ) { + mTemplate = template; + mIter = new CallIterator( template.getStatements() ); + mTemplateName = templateName; + } + + public CallIterator getIter() { + return mIter; + } + + public Template getTemplate() { + return mTemplate; + } + + public String getTemplateName() { + return mTemplateName; + } + } + + + private final Set mVisitedTemplateNames; + private final Stack mStack; + private final Iterator mMapIter; + private final Map mTemplateMap; + + private Template mNextTemplate; + + private void push( final String templateName, + final Template template ) { + final StackFrame newFrame = new StackFrame( template, templateName ); + mStack.push( newFrame ); + } + + private void push( final String templateName ) { + final Template template = ( Template ) mTemplateMap.get( templateName ); + if ( template != null ) { + push( templateName, template ); + } + else { + throw new RuntimeException( "Encountered reference to undefined cell \"" + + templateName + "\"." ); + } + } + + private CallIterator getTopIterator() { + final StackFrame topFrame = ( StackFrame ) mStack.peek(); + return topFrame.getIter(); + } + + private Template getTopTemplate() { + final StackFrame topFrame = ( StackFrame ) mStack.peek(); + return topFrame.getTemplate(); + } + + private String getTopTemplateName() { + final StackFrame topFrame = ( StackFrame ) mStack.peek(); + return topFrame.getTemplateName(); + } + + private boolean wasVisited( final String templateName ) { + return mVisitedTemplateNames.contains( templateName ); + } + + private void markAsVisited( final String templateName ) { + mVisitedTemplateNames.add( templateName ); + } + + public ChildrenFirstTemplateIterator( final Map templateMap ) { + mTemplateMap = templateMap; + mMapIter = templateMap.entrySet().iterator(); + mStack = new Stack(); + mVisitedTemplateNames = new HashSet(); + mNextTemplate = null; + } + + public boolean hasNext() { + while ( ( mNextTemplate == null ) && + ( ( mMapIter.hasNext() ) || + ( ! ( mStack.empty() ) ) ) ) { + if ( mStack.empty() ) { + final Map.Entry nextTemplateMapEntry = + ( Map.Entry ) mMapIter.next(); + final String templateName = + ( String ) nextTemplateMapEntry.getKey(); + final Template template = + ( Template ) nextTemplateMapEntry.getValue(); + push( templateName, template ); + } + while ( ( mNextTemplate == null ) && + ( ! ( mStack.empty() ) ) ) { + final CallIterator currCallIter = getTopIterator(); + + String currCallMasterName = null; + + if ( currCallIter.hasNext() ) { + do { + final CallIterator.Call call = + currCallIter.next(); + currCallMasterName = call.getMasterName(); + } while ( ( currCallIter.hasNext() ) && + ( wasVisited( currCallMasterName ) ) ); + } + if ( ( currCallMasterName != null ) && + ( ! wasVisited( currCallMasterName ) ) ) { + push( currCallMasterName ); + } + else { + final String topTemplateName = getTopTemplateName(); + mNextTemplate = getTopTemplate(); + mStack.pop(); + markAsVisited( topTemplateName ); + } + } + } + return mNextTemplate != null; + } + + public Template next() { + if ( hasNext() ) { + final Template ret = mNextTemplate; + mNextTemplate = null; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inline.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inline.java new file mode 100644 index 0000000000..f3f7bd6b29 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inline.java @@ -0,0 +1,328 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.Reader; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.file.cdl.CDLFileFormatException; +import com.avlsi.file.cdl.parser.CDLInterfaceSimplifier; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.container.Pair; +import com.avlsi.util.exception.AssertionFailure; + + +/** + * Inlines cells in a CDL file. + **/ +public class Inline extends CDLInterfaceSimplifier { + private class Inliner extends CDLInterfaceSimplifier { + /** Mapping from formal to actual parameters */ + private final Map param; + /** What to prefix to internal nodes */ + private final HierName prefix; + public Inliner(Map param, HierName prefix) { + this.param = param; + this.prefix = prefix; + } + + /* This function depends on how HierName determines a name is + * generated. Currently, this is determined by if there exist a '#' in + * the name. */ + private HierName markAsGenerated(final HierName n) { + return n.appendString("#"); + } + + private HierName prefix(HierName name) { + return HierName.append(prefix, name); + } + private HierName subst(HierName name) { + if (param.containsKey(name)) return (HierName) param.get(name); + else { + if (markGenerated && name.isNumeric()) { + name = markAsGenerated(name); + } + return prefix(name); + } + } + private HierName[] subst(HierName[] names) { + HierName[] translated = new HierName[names.length]; + for (int i = 0; i < names.length; i++) { + translated[i] = subst(names[i]); + } + return translated; + } + /* Forward calls to proxy, with appropriate name substitutions */ + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { + callProxy.makeCall(prefix(name), subName, subst(args), parameters); + } + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + proxy.makeResistor(prefix(name), subst(n1), subst(n2), val); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { + proxy.makeCapacitor(prefix(name), subst(npos), subst(nneg), val); + } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + proxy.makeTransistor(prefix(name), type, subst(ns), subst(nd), + subst(ng), subst(nb), w, l); + } + + public void makeDiode(HierName name, int type, HierName npos, + HierName nneg, double w, double l, double a, + double p) { + proxy.makeDiode(prefix(name), type, subst(npos), subst(nneg), w, l, + a, p); + } + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { + proxy.makeInductor(prefix(name), subst(npos), subst(nneg), val); + } + public void makeBipolar(HierName name, int type, HierName nc, + HierName nb, HierName ne, double a) { + proxy.makeBipolar(prefix(name), type, subst(nc), subst(nb), + subst(ne), a); + } + public void beginSubcircuit(String subName, String[] in, String[] out) { + throw new AssertionFailure("Should not happen!"); + } + public void endSubcircuit(String subName) { + throw new AssertionFailure("Should not happen!"); + } + } + + /** + * An interface for getting a template from the name of the subcircuit. + **/ + public interface Retriever { + Template getTemplate(final String name); + } + + /** + * Return a template for a given name by reading the cell from CAST. + **/ + public static class RetrieveFromCast implements Retriever { + protected final CastFileParser cfp; + public RetrieveFromCast(final CastFileParser cfp) { + this.cfp = cfp; + } + protected CellInterface loadCell(final String subName) { + try { + return cfp.getFullyQualifiedCell(subName); + } catch (Exception e) { + throw new RuntimeException("Cannot load cell " + subName + "!"); + } + } + protected Template makeTemplate(final CellInterface cell) { + final Set ports = NetlistAdapter.getParameterList(cell); + final String[] out = new String[ports.size()]; + int j = 0; + for (Iterator i = ports.iterator(); i.hasNext(); ++j) { + out[j] = ((HierName) i.next()).getCadenceString(); + } + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + return Template.setInOut(nb.getCDLTemplate(), new String[0], out); + } + public Template getTemplate(final String subName) { + final CellInterface cell = loadCell(subName); + return makeTemplate(cell); + } + } + + private final Map templates; + private CDLSimpleInterface proxy; + private CDLSimpleInterface callProxy; + private final boolean markGenerated; + private final boolean bFlatten; + private final Retriever retriever; + + public Inline() { + this(false); + } + + public Inline(final boolean markGenerated) { + this(markGenerated, null); + } + + public Inline(final boolean markGenerated, final Retriever retriever) { + this(markGenerated, retriever, false); + } + /** + * Inline constructor. + * @param markGenerated Use true if names that look like internally + * generated nodes in cells to be inlined are marked as such (by appending + * a '#') in the output. + * @param retriever A Retriever that returns an Template when given a + * subcircuit name. If the function is not to be inlined, the function + * returns null. + **/ + public Inline(final boolean markGenerated, final Retriever retriever, boolean flatten) { + templates = new HashMap(); + this.markGenerated = markGenerated; + this.retriever = retriever; + this.bFlatten = flatten; + if(this.bFlatten) + this.callProxy = this; + } + + /** + * Add specified cells found in a reader to the set of cells to be + * flattened. + **/ + public void addTarget(Reader r, String[] cells) { + final Map m = Template.getTemplates(r); + for (int i = 0; i < cells.length; i++) { + if (m.containsKey(cells[i])) { + templates.put(cells[i], m.get(cells[i])); + } + } + } + /** + * Add all cells found in a reader to the set of cells to be flattened. + **/ + public void addTarget(Reader r) { + final Map m = Template.getTemplates(r); + templates.putAll(m); + } + + /** + * Add the specified cell to be flattened. + **/ + public void addTarget(final String cell, final Template templ) { + templates.put(cell, templ); + } + + /** + * Add the specified cells to be flattened. + **/ + public void addTargets(final Map cells) { + templates.putAll(cells); + } + + /** + * Set the CDLSimpleInterface to write to. + **/ + public void setProxy(final CDLSimpleInterface proxy) { + this.proxy = proxy; + if(!bFlatten) + callProxy = proxy; + } + + /** + * Inline all cells specified as a target in all cells found in a reader. + **/ + public void process(Reader r, CDLSimpleInterface proxy) throws CDLFileFormatException { + setProxy(proxy); + try { + ReadCDLIntoFactory.readCDL(r, this); + } catch (Exception e) { + e.printStackTrace(); + throw new CDLFileFormatException(e); + } + } + + /** + * Return the templates associated with a subcircuit. If the templates + * does not already exist in the cache of templates, try to obtain it from + * the template retriever. + * @param subName Name of the template to get. + **/ + private Template getTemplate(final String subName) { + if (!templates.containsKey(subName) && retriever != null) { + final Template t = retriever.getTemplate(subName); + if (t != null) templates.put(subName, t); + } + return (Template) templates.get(subName); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { + final Template t = getTemplate(subName); + if (t == null) { + callProxy.makeCall(name, subName, args, parameters); + } else { + final Pair p = t.getArguments(); + final String[] in = (String []) p.getFirst(); + final String[] out = (String []) p.getSecond(); + if (in.length + out.length != args.length) { + System.err.println("Mismatched parameters in call " + name + " to " + subName + " expecting " + in.length + " input parameters and " + out.length + " output parameters, found " + args.length + "."); + return; + } + final Map m = new HashMap(); + int index = 0; + try { + for (int i = 0; i < in.length; i++, index++) { + m.put(HierName.makeHierName(in[i], '.'), args[index]); + } + for (int i = 0; i < out.length; i++, index++) { + m.put(HierName.makeHierName(out[i], '.'), args[index]); + } + } catch (InvalidHierNameException e) { + System.err.println("InvalidHierNameException cannot happen!"); + } + final Inliner inliner = new Inliner(m, name); + t.execute(parameters, inliner); + } + } + /* The rest just forwards the call to proxy */ + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + proxy.makeResistor(name, n1, n2, val); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { + proxy.makeCapacitor(name, npos, nneg, val); + } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + proxy.makeTransistor(name, type, ns, nd, ng, nb, w, l); + } + + public void makeDiode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p) { + proxy.makeDiode(name, type, npos, nneg, w, l, a, p); + } + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { + proxy.makeInductor(name, npos, nneg, val); + } + public void makeBipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a) { + proxy.makeBipolar(name, type, nc, nb, ne, a); + } + public void beginSubcircuit(String subName, String[] in, String[] out) { + proxy.beginSubcircuit(subName, in, out); + } + public void endSubcircuit(String subName) { + proxy.endSubcircuit(subName); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inliner.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inliner.java new file mode 100644 index 0000000000..6e7e602f1a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Inliner.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.FileReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Reader; +import java.util.Map; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.text.StringUtil; + +public class Inliner { + private static void usage() { + System.err.print( +"Usage: java com.avlsi.file.cdl.parser.Inliner\n" + +" --cdl= (File to be inlined)\n" + +" --library= (Cells to inline)\n" + +" [ --cells= ] (Only inline listed cells)\n" + ); + System.exit(1); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + final String cdlFile = theArgs.getArgValue("cdl", null); + final String cdlLibrary = theArgs.getArgValue("library", null); + if (cdlFile == null || cdlLibrary == null) usage(); + + final CDLInlineFactory iline = new CDLInlineFactory(true); + final Reader libraryReader = new FileReader(cdlLibrary); + final String cells = theArgs.getArgValue("cells", null); + if (cells == null) { + iline.addTarget(libraryReader); + } else { + final String[] targets = StringUtil.split(cells, ':'); + iline.addTarget(libraryReader, targets); + } + + final PrintWriter w = + new PrintWriter(new OutputStreamWriter(System.out)); + final CDLFactoryInterface emitter = + new CDLFactoryEmitter(w, true, 79, true, true); + + iline.process(new FileReader(cdlFile), emitter); + w.close(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/InternalNodeFilterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/InternalNodeFilterFactory.java new file mode 100644 index 0000000000..8f864b572a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/InternalNodeFilterFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + +public class InternalNodeFilterFactory extends CDLFactoryAdaptor { + private final CDLFactoryInterface out; + + public InternalNodeFilterFactory(final CDLFactoryInterface out) { + this.out = out; + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + this.out.makeCall(name, subName, new HierName[] {}, parameters, env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + this.out.beginSubcircuit(subName, in, out, parameters, env); + } + + public void endSubcircuit(String subName, Environment env) { + this.out.endSubcircuit(subName, env); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesCDLFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesCDLFactory.java new file mode 100644 index 0000000000..0a95fcd191 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesCDLFactory.java @@ -0,0 +1,270 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.lang.String; +import java.lang.System; + +import java.util.Set; +import java.util.SortedSet; +import java.util.Map; +import java.util.Iterator; +import java.util.HashSet; +import java.util.List; + +import com.avlsi.util.container.Pair; + +import com.avlsi.cast.impl.Environment; + +import com.avlsi.cast2.directive.DirectiveConstants; + +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.LVSNodesHandler; + +import com.avlsi.layout.LVSNodes; + +/** + * CDLFactory that adds LVSNodes to cells + * - adds LVS nodes to the port lists of cells + * - adds LVS node connections to the instantiations of subcells + * - checks to see that the LVS nodes are used in the cell, and + * throws if this is not the case + * - forwards to LVSNodesHandler: + * startCell - called on beginSubCircuit + * lvsNodesForInstance - called on makeCall + * endCell - called on endSubCircuit if there were LVS nodes + * abortCell - called on endSubCircuit if there weren't LVS nodes + **/ + +public class LVSNodesCDLFactory implements CDLFactoryInterface { + private final LVSNodes mLVSNodes; + private final CDLFactoryInterface mTarget; + private final LVSNodesHandler mHandler; + private Set mCurrNodes; + private LVSNodes.Info mCurrCellLVSNodesInfo; + + + public LVSNodesCDLFactory( final LVSNodes lvsNodes, + final CDLFactoryInterface target, + final LVSNodesHandler handler ) { + mLVSNodes = lvsNodes; + mTarget = target; + mHandler = handler; + mCurrNodes = null; + mCurrCellLVSNodesInfo = null; + } + public void makeTransistor( HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + assert mCurrNodes != null; + mTarget.makeTransistor( name, type, ns, nd, ng, nb, w, l, parameters, env ); + mCurrNodes.add( ns ); + mCurrNodes.add( nd ); + mCurrNodes.add( ng ); + mCurrNodes.add( nb ); + } + public void makeDiode(HierName name, String type, HierName npos, + HierName nneg, CDLLexer.InfoToken val, + Map parameters, Environment env) { + assert mCurrNodes != null; + mTarget.makeDiode( name, type, npos, nneg, val, parameters, env ); + mCurrNodes.add( npos ); + mCurrNodes.add( nneg ); + } + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + assert mCurrNodes != null; + mTarget.makeResistor( name, n1, n2, val, parameters, env ); + mCurrNodes.add( n1 ); + mCurrNodes.add( n2 ); + } + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + assert mCurrNodes != null; + mTarget.makeCapacitor( name, npos, nneg, val, parameters, env ); + mCurrNodes.add( npos ); + + mCurrNodes.add( nneg ); + } + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + assert mCurrNodes != null; + mTarget.makeInductor( name, npos, nneg, val, parameters, env ); + mCurrNodes.add( npos ); + mCurrNodes.add( nneg ); + } + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + assert mCurrNodes != null; + mTarget.makeBipolar( name, type, nc, nb, ne, val, parameters, env ); + mCurrNodes.add( nc ); + mCurrNodes.add( nb ); + mCurrNodes.add( ne ); + } + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + + assert mCurrNodes != null; + + final List lvsNodesConnections = + mCurrCellLVSNodesInfo.getInstanceLVSNodesConnections( name ); + + if ( ( lvsNodesConnections != null ) && + ( lvsNodesConnections.size() > 0 ) ) { + + final HierName[] newArgs = + new HierName[ args.length + lvsNodesConnections.size() ]; + + int destIndex = 0; + + for ( int i = 0 ; i < args.length ; ++i ) { + newArgs[destIndex] = args[i]; + ++destIndex; + mCurrNodes.add( args[i].getCadenceString() ); + } + final Iterator lvsNodesConnectionsIter = + lvsNodesConnections.iterator(); + + while ( lvsNodesConnectionsIter.hasNext() ) { + final Pair lvsNodeConnection = + ( Pair ) lvsNodesConnectionsIter.next(); + final HierName lvsNode = ( HierName ) lvsNodeConnection.getFirst(); + newArgs[destIndex] = lvsNode; + ++destIndex; + } + mHandler.lvsNodesForInstance( name, lvsNodesConnections ); + mTarget.makeCall( name, subName, newArgs, parameters, env ); + } + else { + mTarget.makeCall( name, subName, args, parameters, env ); + } + for ( int i = 0 ; i < args.length ; ++i ) { + mCurrNodes.add( args[i] ); + } + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + mCurrNodes = new HashSet(); + + try { + + mCurrCellLVSNodesInfo = mLVSNodes.getLVSNodesSetsForCell( subName ); + //The startCell method of the handler must be called before + //the beginSubcircuit method of the target factory. + //Handler implementations are allowed to rely on this fact. + mHandler.startCell( subName ); + + final SortedSet lvsNodes = mCurrCellLVSNodesInfo.getLVSNodes(); + + //The LVS nodes appear as inputs to the cell + //iff there are not outputs + final boolean addLVSNodesToInputs = out.length == 0; + + final String[] newInputs; + final String[] newOutputs; + final String[] arrayToAddLVSNodesTo; + int destIndex; + + if ( addLVSNodesToInputs ) { + newInputs = new String[ lvsNodes.size() + in.length ]; + System.arraycopy( in, 0, newInputs, 0, in.length ); + arrayToAddLVSNodesTo = newInputs; + destIndex = in.length; + newOutputs = out; + } + else { + newOutputs = new String[ lvsNodes.size() + out.length ]; + System.arraycopy( out, 0, newOutputs, 0, out.length ); + arrayToAddLVSNodesTo = newOutputs; + destIndex = out.length; + newInputs = in; + } + + final Iterator lvsNodesIter = lvsNodes.iterator(); + + + while ( lvsNodesIter.hasNext() ) { + final HierName lvsNode = ( HierName ) lvsNodesIter.next(); + arrayToAddLVSNodesTo[destIndex] = lvsNode.getCadenceString(); + ++destIndex; + } + + mTarget.beginSubcircuit( subName, + newInputs, + newOutputs, + parameters, + env ); + } + catch ( LVSNodes.LVSNodesException e ) { + throw new RuntimeException( "Unable to get LVSNodes.Info for \"" + + subName + + "\".", + e ); + } + + + } + public void endSubcircuit(String subName, Environment endEnv ) { + assert mCurrCellLVSNodesInfo != null; + assert mCurrNodes != null; + + + final SortedSet topLevelLVSNodes = + mCurrCellLVSNodesInfo.getTopLevelLVSNodes(); + + assert topLevelLVSNodes != null; + + if ( topLevelLVSNodes.size() > 0 ) { + + final Iterator topLevelLVSNodesIter = topLevelLVSNodes.iterator(); + + while ( topLevelLVSNodesIter.hasNext() ) { + final HierName lvsNode = ( HierName ) topLevelLVSNodesIter.next(); + + if ( ! ( mCurrNodes.contains( lvsNode ) ) ) { + throw new RuntimeException( "\"" + + lvsNode.getCadenceString() + + "\" is not a node in \"" + + subName + + "\", so it can not be in the " + + DirectiveConstants.LVS_NODES + + " directive." ); + } + + } + } + + mTarget.endSubcircuit( subName, endEnv ); + + final SortedSet lvsNodes = mCurrCellLVSNodesInfo.getLVSNodes(); + + /* It is critical that we call the abort or endCell method + of the handler AFTER we have executed all the statements of the + accumulated template. Handler implementations are allowed to + assume that abort or endCell is called after the call to + endSubcircuit. */ + if ( lvsNodes.size() == 0 ) { + mHandler.abortCell( subName ); + } + else { + mHandler.endCell( subName, lvsNodes ); + } + + mCurrNodes = null; + mCurrCellLVSNodesInfo = null; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesHandler.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesHandler.java new file mode 100644 index 0000000000..1bf6e564bd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesHandler.java @@ -0,0 +1,28 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.lang.String; +import java.util.Set; +import java.util.List; + +import com.avlsi.file.common.HierName; + +/** + * Get's calls forwarded from an LVSNodeCDLFactory + **/ +public interface LVSNodesHandler { + + void startCell( final String cellName ); + + void lvsNodesForInstance( final HierName instnaceName, + final List lvsNodeConnectionPairs ); + + void endCell( final String cellName, final Set cellLVSNodes ); + void abortCell( final String cellName ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesNullHandler.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesNullHandler.java new file mode 100644 index 0000000000..9a2f1bb56b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/LVSNodesNullHandler.java @@ -0,0 +1,31 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.lang.String; +import java.util.Set; +import java.util.List; + +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.LVSNodesHandler; + +public class LVSNodesNullHandler implements LVSNodesHandler { + + public LVSNodesNullHandler() { } + + public void startCell( final String cellName ) {} + + public void lvsNodesForInstance( final HierName instnaceName, + final List lvsNodeConnectionPairs ) {} + + public void endCell( final String cellName, final Set cellLVSNodes ) {} + + public void abortCell( final String cellName ) {} + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/NetlistBlockFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/NetlistBlockFactory.java new file mode 100644 index 0000000000..d781a2cd7f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/NetlistBlockFactory.java @@ -0,0 +1,355 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.SimpleAbstractDeviceIterator; +import com.avlsi.netlist.impl.SimpleAbstractNetlistIterator; +import com.avlsi.netlist.impl.SimpleAbstractNodeIterator; +import com.avlsi.util.container.AliasedMap; + +/** + * A factory intended to be used when parsing a netlist block in CASTv2. Only + * resistor, transistor, inductor circuit elements are allowed. Specifically, + * subcircuit definitions, and subcircuit calls are NOT allowed.

    + * When viewed as an AbstractNetlist, it is a circuit that does not have any + * input or output nodes, and has a default name of <netlist block>. It + * is the responsibility of the user (e.g., + * {@link com.avlsi.fast.NetlistAdapter NetlistAdapter}) + * to stitch in the netlist, so that it has the proper input and output nodes, + * and the proper name. + **/ +public class NetlistBlockFactory extends CDLInterfaceSimplifier implements AbstractNetlist { + /** The list of all circuit elements. */ + private List requests = new ArrayList(); + + /** + * The data stored in the AliasedMap is a 2-element array. The first + * element is a Set of all devices connected to the key. The + * second element contains the canonical name, which maybe different from + * the canonical name returned by AliasedMap, and is expected to be set + * after the CDL has been parsed. When we merge, we union the + * Set of all devices, and set the canonical name to null. + **/ + private class MergeSet implements AliasedMap.MergeFunction { + public Object merge(Object oldValue, Object newValue) { + final Set s1 = (Set) ((Object[]) oldValue)[0]; + final Set s2 = (Set) ((Object[]) newValue)[0]; + final Set s3 = new HashSet(); + s3.addAll(s1); s3.addAll(s2); + final Object[] o = new Object[2]; + o[0] = s3; o[1] = null; + return o; + } + } + + /** All nodes in the netlist. */ + private AliasedMap nodes = + new AliasedMap(new MergeSet(), HierName.getComparator()); + + public AliasedMap getAliasedMap() { + return nodes; + } + + /* Return a HierName that is marked as generated, if it consists only of + * digits */ + private HierName mark(HierName n) { + if (n.isNumeric()) return n.appendString("#"); + else return n; + } + + /** + * Associate a node with a device, to allow enumeration of all devices + * connected to a node. + * + * @param name Name of the node. + * @param device AbstractDevice to associate the node with. + **/ + private void newName(HierName name, AbstractDevice device) { + final Object[] o = new Object[2]; + final Set s = new HashSet(); + s.add(device); + o[0] = s; o[1] = null; + try { + nodes.addData(name, o); + } catch (AliasedMap.MergeFailedException e) { + System.err.println("MergeFailed: " + e); + } + } + + private class Node implements AbstractNode { + private final HierName name; + public Node(final HierName name) { + this.name = name; + } + public HierName getCanonicalName() { + final Object[] o = (Object[]) nodes.getValue(name); + if (o[1] == null) { + return (HierName) nodes.getCanonicalKey(name); + } else { + return (HierName) o[1]; + } + } + public Iterator getAliases() { + return nodes.getAliases(name); + } + public AbstractDeviceIterator getDevices() { + final Set s = (Set) ((Object[]) nodes.getValue(name))[0]; + return new SimpleAbstractDeviceIterator(s.iterator()); + } + } + + private Node toNode(HierName name) { + return new Node(name); + } + + private final class Resistor implements AbstractDevice { + private final HierName name, n1, n2; + private final double val; + public Resistor(HierName name, HierName n1, HierName n2, double val) { + this.name = name; + this.n1 = mark(n1); + this.n2 = mark(n2); + this.val = val; + newName(this.n1, this); newName(this.n2, this); + } + + public void accept(final Visitor visitor) { + visitor.genericResistor(name, toNode(n1), toNode(n2), 1 / val, + new HashMap()); + } + } + + private final class Capacitor implements AbstractDevice { + private final HierName name, npos, nneg; + private final double val; + public Capacitor(HierName name, HierName npos, HierName nneg, + double val) { + this.name = name; + this.npos = mark(npos); + this.nneg = mark(nneg); + this.val = val; + newName(this.npos, this); newName(this.nneg, this); + } + + public void accept(final Visitor visitor) { + visitor.genericCapacitor(name, toNode(npos), toNode(nneg), + val, new HashMap()); + } + } + + private final class Transistor implements AbstractDevice { + private final HierName name, ns, nd, ng, nb; + private final int type; + private final double w, l; + public Transistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + this.name = name; + this.type = type; + this.ns = mark(ns); + this.nd = mark(nd); + this.ng = mark(ng); + this.nb = mark(nb); + this.w = w; + this.l = l; + newName(this.ns, this); newName(this.nd, this); + newName(this.ng, this); newName(this.nb, this); + } + + public void accept(final Visitor visitor) { + visitor.genericTransistor(name, toNode(nd), toNode(ng), + toNode(ns), toNode(nb), l, w, + type == DeviceTypes.P_TYPE ? "p" : "n", + new HashMap()); + } + } + + private final class Inductor implements AbstractDevice { + private final HierName name, npos, nneg; + private final double val; + public Inductor(HierName name, HierName npos, HierName nneg, + double val) { + this.name = name; + this.npos = mark(npos); + this.nneg = mark(nneg); + this.val = val; + newName(this.npos, this); newName(this.nneg, this); + } + + public void accept(final Visitor visitor) { + visitor.genericInductor(name, toNode(npos), toNode(nneg), + val, new HashMap()); + } + } + + private final class Diode implements AbstractDevice { + private final HierName name, npos, nneg; + private final double l,w,p,a; + private final int type; + public Diode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p) { + this.name = name; + this.npos = mark(npos); + this.nneg = mark(nneg); + this.l = l; + this.w = w; + this.p = p; + this.a = a; + this.type = type; + newName(this.npos, this); newName(this.nneg, this); + } + + public void accept(final Visitor visitor) { + visitor.genericDiode(name, toNode(npos), toNode(nneg), + l,w,p,a, + type == DeviceTypes.N_TYPE ? "dw" : "dp", + new HashMap()); + } + } + + private final class Bipolar implements AbstractDevice { + private final HierName name, nc, nb, ne; + private final double a; + private final int type; + public Bipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a) { + this.name = name; + this.nc = mark(nc); + this.nb = mark(nb); + this.ne = mark(ne); + this.a = a; + this.type = type; + newName(this.nc, this); + newName(this.nb, this); + newName(this.ne, this); + } + + public void accept(final Visitor visitor) { + throw new AssertionError("Bipolar devices not implemented"); + } + } + + private final class Call implements AbstractDevice { + private final HierName name; + private final String subName; + private final HierName[] args; + private final Map parameters; + public Call(HierName name, String subName, HierName[] args, + Map parameters) { + this.name = name; + this.subName = subName; + this.args = args; + this.parameters = parameters; + } + public void accept(final Visitor visitor) { + } + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + if (val <= 0) { + throw new RuntimeException("Resistor " + name + + " has invalid resistance " + val + "!"); + } + requests.add(new Resistor(name, n1, n2, val)); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { + requests.add(new Capacitor(name, npos, nneg, val)); + } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + requests.add(new Transistor(name, type, ns, nd, ng, nb, w, l)); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { + if (val <= 0) { + throw new RuntimeException("Inductor " + name + + " has invalid inductance " + val + "!"); + } + requests.add(new Inductor(name, npos, nneg, val)); + } + + public void makeDiode(HierName name, int type, HierName npos, HierName nneg, + double w, double l, double a, double p) { + requests.add(new Diode(name, type, npos, nneg, w, l, p, a) ); + } + + public void makeBipolar(HierName name, int type, HierName nc, HierName nb, + HierName ne, double a) { + requests.add(new Bipolar(name, type, nc, nb, ne, a) ); + } + + /* The following devices are not allowed in a netlist block */ + public void makeCall(HierName name, String subName, HierName[] args, Map parameters) { + // throw new RuntimeException("Cannot instantiate subcell " + subName + " as " + name + " from within a netlist block!"); + } + + public void beginSubcircuit(String subName, String[] in, String[] out) { + throw new RuntimeException("Cannot define subcell " + subName + " from within a netlist block!"); + } + + public void endSubcircuit(String subName) { + throw new RuntimeException("Cannot define subcell " + subName + " from within a netlist block!"); + } + + public AbstractNodeIterator getInputNodes() { + return new SimpleAbstractNodeIterator(Collections.EMPTY_LIST.iterator()); + } + + public AbstractNodeIterator getOutputNodes() { + return new SimpleAbstractNodeIterator(Collections.EMPTY_LIST.iterator()); + } + + public HierName getName() { + return HierName.makeHierName(""); + } + + public AbstractNodeIterator getNodes() { + final Iterator keys = nodes.getKeys(); + return new AbstractNodeIterator() { + public boolean hasNext() { + return keys.hasNext(); + } + + public AbstractNode next() { + return toNode((HierName) keys.next()); + } + }; + } + + public AbstractDeviceIterator getDevices() { + return new SimpleAbstractDeviceIterator(requests.iterator()); + } + + public AbstractNetlistIterator getSubcircuits() { + return new SimpleAbstractNetlistIterator(Collections.EMPTY_LIST.iterator()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ReadCDLIntoFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ReadCDLIntoFactory.java new file mode 100644 index 0000000000..bde46df669 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/ReadCDLIntoFactory.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.Reader; + +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.Token; +import antlr.collections.AST; + +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLParser; +import com.avlsi.file.cdl.parser.CDLWalker; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + + +public final class ReadCDLIntoFactory { + /** + * This class should not be instantiated. + **/ + private ReadCDLIntoFactory() { } + + public static void readCDL( final Reader r, + final CDLFactoryInterface f ) + throws RecognitionException, TokenStreamException + + { + final CDLLexer lexer = new CDLLexer( r, false ); + final CDLParser parser = new CDLParser( lexer ); + parser.setASTNodeClass( CDLParser.ASTWithToken.class.getName() ); + + parser.goal(); + final AST ast = parser.getAST(); + final CDLWalker walker = new CDLWalker(); + + walker.goal( ast, new LocalEnvironment(), f ); + } + + public static void readCDLSimple( final Reader r, + final CDLFactoryInterface f) + throws RecognitionException, TokenStreamException + { + final CDLLexer lexer = new CDLLexer( r, false ); + final CDLParser parser = new CDLParser( lexer ); + final CDLWalker walker = new CDLWalker(); + + parser.setASTNodeClass( CDLParser.ASTWithToken.class.getName() ); + + boolean eof; + do { + parser.expr(); + final AST ast = parser.getAST(); + eof = ( ast == null || ast.getType() == Token.EOF_TYPE ); + if(!eof) walker.expr(ast, new LocalEnvironment(), f ); + } while(!eof); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RemoveLVSNodesCDLFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RemoveLVSNodesCDLFactory.java new file mode 100644 index 0000000000..be39ff131e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RemoveLVSNodesCDLFactory.java @@ -0,0 +1,394 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.parser; + +import java.lang.String; +import java.lang.System; +import java.lang.RuntimeException; + +import java.util.Map; +import java.util.List; +import java.util.ListIterator; +import java.util.SortedSet; +import java.util.HashMap; +import java.util.LinkedList; + +import com.avlsi.util.container.Pair; + +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + +import com.avlsi.cast.impl.Environment; + + +import com.avlsi.layout.LVSNodes; + +public class RemoveLVSNodesCDLFactory implements CDLFactoryInterface { + + private final LVSNodes mLVSNodes; + private final CDLFactoryInterface mTarget; + private final Map mLVSNodesPorts; + private String mCurrCellName; + private LVSNodes.Info mCurrCellLVSNodesInfo; + + public static class RemoveException extends RuntimeException { + public RemoveException( final String str ) { + super( str ); + } + + public RemoveException( final String str, + final Exception e ) { + super( str, e ); + } + + public RemoveException( final Exception e ) { + super( e ); + } + } + + public RemoveLVSNodesCDLFactory( final LVSNodes lvsNodes, + final CDLFactoryInterface target ) { + mLVSNodes = lvsNodes; + mTarget = target; + mLVSNodesPorts = new HashMap(); + mCurrCellName = null; + mCurrCellLVSNodesInfo = null; + } + + + public void makeTransistor( HierName name, + String type, + HierName ns, + HierName nd, + HierName ng, + HierName nb, + CDLLexer.InfoToken w, + CDLLexer.InfoToken l, + Map parameters, + Environment env ) { + mTarget.makeTransistor( name, type, ns, nd, ng, nb, w, l, parameters, env ); + } + public void makeDiode( HierName name, + String type, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + mTarget.makeDiode( name, type, npos, nneg, val, parameters, env ); + } + public void makeResistor( HierName name, + HierName n1, + HierName n2, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + mTarget.makeResistor( name, n1, n2, val, parameters, env ); + } + public void makeCapacitor( HierName name, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + mTarget.makeCapacitor( name, npos, nneg, val, parameters, env ); + } + public void makeInductor( HierName name, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env ) { + mTarget.makeInductor( name, npos, nneg, val, parameters, env ); + } + public void makeBipolar( HierName name, + String type, + HierName nc, + HierName nb, + HierName ne, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + mTarget.makeBipolar( name, type, nc, nb, ne, val, parameters, env ); + } + public void makeCall( HierName name, + String subName, + HierName[] args, + Map parameters, + Environment env ) { + + final List lvsNodesConnections = mCurrCellLVSNodesInfo.getInstanceLVSNodesConnections( name ); + + if ( ( lvsNodesConnections != null ) && + ( lvsNodesConnections.size() > 0 ) ) { + + final HierName[] lvsNodesPortsFromMasterDef = + ( HierName [] ) mLVSNodesPorts.get( subName ); + + if ( lvsNodesPortsFromMasterDef != null ) { + + final int numLVSNodes = lvsNodesConnections.size(); + + assert args.length > numLVSNodes; + + final int numRealArgs = args.length - numLVSNodes; + + final ListIterator lvsNodesConnectionsIter = + lvsNodesConnections.listIterator( numLVSNodes ); + int argIndex = ( args.length - 1 ); + int masterLVSPortIndex = lvsNodesPortsFromMasterDef.length - 1; + boolean foundProblem = false; + + while ( ( argIndex >= numRealArgs ) && + ( lvsNodesConnectionsIter.hasPrevious() ) && + ( masterLVSPortIndex >= 0 ) && + ( ! foundProblem ) ) { + final Pair lvsNodeConnectionPair = + ( Pair ) lvsNodesConnectionsIter.previous(); + + final HierName castNodeName = + ( HierName ) lvsNodeConnectionPair.getFirst(); + + final HierName castNodeNameInSubcell = + ( HierName ) lvsNodeConnectionPair.getSecond(); + + foundProblem = + ( ( ! castNodeName.equals( args[ argIndex ] ) ) || + ( ! castNodeNameInSubcell.equals( lvsNodesPortsFromMasterDef[ masterLVSPortIndex ] ) ) ); + + --argIndex; + --masterLVSPortIndex; + + } + + if ( foundProblem ) { + ++argIndex; + ++masterLVSPortIndex; + final Pair lvsNodeConnectionPair = + ( Pair ) lvsNodesConnectionsIter.next(); + final HierName castNodeName = + ( HierName ) lvsNodeConnectionPair.getFirst(); + + final HierName castNodeNameInSubcell = + ( HierName ) lvsNodeConnectionPair.getSecond(); + + final String errorStr; + assert mCurrCellName != null; + if ( ! castNodeName.equals( args[ argIndex ] ) ) { + errorStr = + "In \"" + + mCurrCellName + + "\", on instance \"" + + name.getCadenceString() + + "\", the node \"" + + args[argIndex].getCadenceString() + + "\" should be \"" + + castNodeName.getCadenceString() + + "\" which should then be connected to \"" + + castNodeNameInSubcell.getCadenceString() + + "\" in the instantiated sub-cell."; + } + else if ( ! castNodeNameInSubcell.equals( lvsNodesPortsFromMasterDef[ masterLVSPortIndex ] ) ) { + errorStr = + "In \"" + + mCurrCellName + + "\", on instance \"" + + name.getCadenceString() + + "\", the node \"" + + args[argIndex].getCadenceString() + + "\" is connected to \"" + + lvsNodesPortsFromMasterDef[ masterLVSPortIndex].getCadenceString() + + "\" in the instantiated subcell, but it should connect to \"" + + castNodeNameInSubcell.getCadenceString() + + "\" instead."; + } + else { + errorStr = "Unknown LVSNode problem."; + } + + throw new RemoveException( errorStr ); + } + + final HierName[] newArgs = new HierName[ numRealArgs ]; + + System.arraycopy( args, 0, newArgs, 0, numRealArgs ); + + mTarget.makeCall( name, subName, newArgs, parameters, env ); + + } + else { + throw new RemoveException( "No LVSNode ports for \"" + + subName + + "\" which is instantiated as \"" + + name.getCadenceString() + + "\" in \"" + + mCurrCellName + + "\"." ); + } + + } + else { + mTarget.makeCall( name, subName, args, parameters, env ); + } + } + + public void beginSubcircuit( String subName, + String[] in, + String[] out, + Map parameters, + Environment env ) { + + mCurrCellName = subName; + try { + + mCurrCellLVSNodesInfo = mLVSNodes.getLVSNodesSetsForCell( subName ); + + final SortedSet lvsNodes = mCurrCellLVSNodesInfo.getLVSNodes(); + + final ListIterator lvsNodesIter = new LinkedList( lvsNodes ).listIterator( lvsNodes.size() ); + + int i = out.length - 1; + + boolean foundProblem = false; + + String lvsNodeString = null; + + while ( ( ! foundProblem ) && + ( i >= 0 ) && + ( lvsNodesIter.hasPrevious() ) ) { + final HierName lvsNode = ( HierName ) lvsNodesIter.previous(); + + lvsNodeString = lvsNode.getCadenceString(); + + foundProblem = ( ! lvsNodeString.equals( out[i] ) ); + --i; + } + + if ( foundProblem ) { + ++i; + assert ( ! lvsNodeString.equals( out[i] ) ); + + final String errorStr = + "In the port list of \"" + + subName + + "\", \"" + + out[i] + + "\" should be \"" + + lvsNodeString + + "\"."; + throw new RemoveException( errorStr ); + } + + final int outputLen = i + 1; + + i = in.length - 1; + while ( ( ! foundProblem ) && + ( i >= 0 ) && + ( lvsNodesIter.hasPrevious() ) ) { + final HierName lvsNode = ( HierName ) lvsNodesIter.previous(); + + lvsNodeString = lvsNode.getCadenceString(); + + foundProblem = ( ! lvsNodeString.equals( in[i] ) ); + --i; + } + + foundProblem = foundProblem || + lvsNodesIter.hasPrevious() || + ( i < 0 ); + + if ( foundProblem ) { + final String errorStr; + if ( i < 0 ) { + errorStr = + "\"" + + subName + + "\" only had lvs nodes in its port list."; + } + else if ( lvsNodesIter.hasPrevious() ) { + final HierName lvsNode = ( HierName ) lvsNodesIter.previous(); + errorStr = + "\"" + + lvsNode.getCadenceString() + + "\" should be in the port list of \"" + + subName + + "\"."; + } else if ( ! lvsNodeString.equals( in[ i + 1 ] ) ) { + errorStr = + "In the port list of \"" + + subName + + "\", \"" + + in[ i + 1 ] + + "\" should be \"" + + lvsNodeString + + "\"."; + } + else { + errorStr = "Unknown LVSNode problem."; + } + throw new RemoveException( errorStr ); + } + + final int inputLen = i + 1; + + final String[] newInput; + + assert inputLen <= in.length; + + if ( inputLen == in.length ) { + newInput = in; + } + else { + newInput = new String[ inputLen ]; + System.arraycopy( in, 0, newInput, 0, inputLen ); + } + + assert outputLen <= out.length; + + final String[] newOutput; + if ( outputLen == out.length ) { + newOutput = out; + } + else { + newOutput = new String[ outputLen ]; + System.arraycopy( out, 0, newOutput, 0, outputLen ); + } + + + final HierName[] lvsNodesArray = ( HierName[] ) lvsNodes.toArray( new HierName[0] ); + mLVSNodesPorts.put( subName, lvsNodesArray ); + + mTarget.beginSubcircuit( subName, + newInput, + newOutput, + parameters, + env ); + } + catch ( LVSNodes.LVSNodesException e ) { + throw new RuntimeException( "Unable to get LVSNodes.Info for \"" + + subName + + "\".", + e ); + } + + + } + public void endSubcircuit( String subName, Environment endEnv ) { + assert mCurrCellLVSNodesInfo != null; + assert mCurrCellName != null; + + mTarget.endSubcircuit( subName, endEnv ); + + mCurrCellName = null; + mCurrCellLVSNodesInfo = null; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RenumberFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RenumberFactory.java new file mode 100644 index 0000000000..d06e92f0a5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/RenumberFactory.java @@ -0,0 +1,313 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.PrintWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import antlr.collections.AST; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLParser; +import com.avlsi.file.cdl.parser.CDLWalker; +import com.avlsi.file.common.HierName; + +/** + * An CDLFactoryInterface that can be used to rename nodes and names of circuit + * components to another format + **/ +public class RenumberFactory implements CDLFactoryInterface { + private static int MAX_LENGTH = 256; + + private interface TranslateInterface { + /** Translates the name of a component */ + String translateName(String name, int tries); + /** Translates the name of a node */ + String translateNode(String name, int tries); + /** Translates the name of a subcircuit */ + String translateCircuit(String name, int tries); + } + + private static class NullTranslation implements TranslateInterface { + public String translateName(String name, int tries) { + return name; + } + + public String translateNode(String name, int tries) { + return name; + } + + public String translateCircuit(String name, int tries) { + return name; + } + } + + private static class SpiceTranslation implements TranslateInterface { + public String translateName(String name, int tries) { + return translate(name, tries); + } + + public String translateNode(String name, int tries) { + return translate(name, tries); + } + + public String translateCircuit(String name, int tries) { + return translate(name, tries); + } + + private String translate(String s, int tries) { + String ss = translate(s); + if (tries > 0) { + return ss + tries; + } else { + return ss; + } + } + + private String translate(String s) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (Character.isLetterOrDigit(c)) { + sb.append(c); + continue; + } + switch (c) { + case '.': sb.append("_D_"); break; + case ',': sb.append("_C_"); break; + case '[': sb.append("_l_"); break; + case ']': sb.append("_r_"); break; + case '(': sb.append("_L_"); break; + case ')': sb.append("_R_"); break; + case '-': sb.append("_M_"); break; + case '_': sb.append("_U_"); break; + default: sb.append("_"); sb.append((int) c); sb.append("_"); + } + } + return sb.toString(); + } + } + + private Map nameMap, nodeMap, circuitMap; + private PrintWriter w; + private TranslateInterface trans; + + private static void usage() { + System.err.println("Usage: java com.avlsi.file.cdl.parser.RenumberFactory [ null | spice ] < old_cdlfile > new_cdlfile"); + } + + public static void main(String[] args) throws Exception { + if (args.length != 1) { + usage(); + System.exit(1); + } + final CDLLexer lexer = new CDLLexer(new InputStreamReader(System.in), false); + final CDLParser parser = new CDLParser(lexer); + parser.setASTNodeClass(CDLParser.ASTWithToken.class.getName()); + parser.goal(); + final AST ast = parser.getAST(); + final CDLWalker walker = new CDLWalker(); + final Writer w = new OutputStreamWriter(System.out); + final TranslateInterface ti; + if (args[0].equals("spice")) ti = new SpiceTranslation(); + else ti = new NullTranslation(); + final RenumberFactory factory = new RenumberFactory(w, ti); + walker.goal(ast, new LocalEnvironment(), factory); + w.flush(); + } + + public RenumberFactory(Writer w, TranslateInterface trans) { + this.w = new PrintWriter(w); + this.nameMap = new HashMap(); + this.nodeMap = new HashMap(); + this.circuitMap = new HashMap(); + this.trans = trans; + } + + private void checkSize(String old, String s) { + if (s.length() > MAX_LENGTH) { + System.err.println("New name too long: \"" + old + "\" -> \"" + s + "\""); + } + } + + private String newName(String old) { + int tries = 0; + String s = trans.translateName(old, tries++); + while (nameMap.containsValue(s)) { + s = trans.translateName(old, tries++); + } + checkSize(old, s); + return s; + } + + private String newNode(String old) { + int tries = 0; + String s = trans.translateNode(old, tries++); + while (nodeMap.containsValue(s)) { + s = trans.translateNode(old, tries++); + } + checkSize(old, s); + return s; + } + + private String newCircuit(String old) { + int tries = 0; + String s = trans.translateCircuit(old, tries++); + while (circuitMap.containsValue(s)) { + s = trans.translateCircuit(old, tries++); + } + checkSize(old, s); + return s; + } + + private String lookupName(String name) { + if (!nameMap.containsKey(name)) nameMap.put(name, newName(name)); + return (String) nameMap.get(name); + } + + private String lookupNode(String name) { + if (!nodeMap.containsKey(name)) nodeMap.put(name, newNode(name)); + return (String) nodeMap.get(name); + } + + private String lookupCircuit(String name) { + if (!circuitMap.containsKey(name)) circuitMap.put(name, newCircuit(name)); + return (String) circuitMap.get(name); + } + + private String lookupName(HierName name) { + return lookupName(name.getCadenceString()); + } + + private String lookupNode(HierName name) { + return lookupNode(name.getCadenceString()); + } + + private void outputParameters(Map parameters, Environment env) { + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String key = (String) entry.getKey(); + final String val = ((CDLLexer.InfoToken) entry.getValue()).getText(env); + w.print(" " + key + "=" + val); + } + } + + public void makeResistor(HierName name, + HierName n1, + HierName n2, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + w.print("R" + lookupName(name) + " " + lookupNode(n1) + " " + lookupNode(n2) + " " + val.getText(env)); + outputParameters(parameters, env); + w.println(); + } + + public void makeCapacitor(HierName name, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + w.print("C" + lookupName(name) + " " + lookupNode(npos) + " " + lookupNode(nneg) + " " + val.getText(env)); + outputParameters(parameters, env); + w.println(); + } + + public void makeTransistor(HierName name, + String type, + HierName ns, + HierName nd, + HierName ng, + HierName nb, + CDLLexer.InfoToken width, + CDLLexer.InfoToken length, + Map parameters, + Environment env) { + w.print("M" + lookupName(name) + " " + lookupNode(nd) + " " + lookupNode(ng) + " " + lookupNode(ns) + " " + lookupNode(nb) + " " + type + " W=" + width.getText(env) + " L=" + length.getText(env)); + outputParameters(parameters, env); + w.println(); + } + + public void makeDiode(HierName name, + String type, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + w.print("D" + lookupName(name) + " " + lookupNode(npos) + " " + lookupNode(nneg) + " " + val.getText(env)); + outputParameters(parameters, env); + w.println(); + } + + public void makeInductor(HierName name, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + w.print("L" + lookupName(name) + " " + lookupNode(npos) + " " + lookupNode(nneg) + " " + val.getText(env)); + outputParameters(parameters, env); + w.println(); + } + + public void makeBipolar(HierName name, + String type, + HierName nc, + HierName nb, + HierName ne, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + w.print("Q" + lookupName(name) + " " + lookupNode(nc) + " " + lookupNode(nb) + " " + lookupNode(ne) + " " + type + " area=" + val.getText(env)); + outputParameters(parameters, env); + w.println(); + } + + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + w.print("X" + lookupName(name)); + for (int i = 0; i < args.length; i++) { + w.print(" " + lookupNode(args[i])); + } + w.print(" / " + lookupCircuit(subName)); + outputParameters(parameters, env); + w.println(); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + w.print(".SUBCKT " + lookupCircuit(subName)); + for (int i = 0; i < in.length; i++) { + w.print(" " + lookupNode(in[i])); + } + for (int i = 0; i < out.length; i++) { + w.print(" " + lookupNode(out[i])); + } + outputParameters(parameters, env); + w.println(); + } + + /** + * Called by the parser after processing a subcircuit. + * @param subName Name of the subcircuit + **/ + public void endSubcircuit(String subName, Environment env) { + w.println(".ENDS"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/SplittingFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/SplittingFactory.java new file mode 100644 index 0000000000..4addde3aac --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/SplittingFactory.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.util.Map; + + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + +public final class SplittingFactory implements CDLFactoryInterface { + + private CDLFactoryInterface mFirst; + private CDLFactoryInterface mSecond; + + + public SplittingFactory( CDLFactoryInterface first, CDLFactoryInterface second ) { + mFirst = first; + mSecond = second; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, Environment env) { + mFirst.makeResistor( name, n1, n2, val, parameters, env ); + mSecond.makeResistor( name, n1, n2, val, parameters, env ); + } + + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + mFirst.makeCapacitor( name, npos, nneg, val, parameters, env ); + mSecond.makeCapacitor( name, npos, nneg, val, parameters, env ); + } + + + public void makeTransistor(HierName name, String type, HierName ns, HierName nd, + HierName ng, HierName nb, CDLLexer.InfoToken w, + CDLLexer.InfoToken l, Map parameters, Environment env) { + mFirst.makeTransistor( name, type, ns, nd, ng, nb, w, l, parameters, env ); + mSecond.makeTransistor( name, type, ns, nd, ng, nb, w, l, parameters, env ); + } + + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + mFirst.makeDiode( name, type, npos, nneg, val, parameters, env ); + mSecond.makeDiode( name, type, npos, nneg, val, parameters, env ); + } + + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, Environment env) { + mFirst.makeInductor( name, npos, nneg, val, parameters, env ); + mSecond.makeInductor( name, npos, nneg, val, parameters, env ); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + mFirst.makeBipolar( name, type, nc, nb, ne, val, parameters, env ); + mSecond.makeBipolar( name, type, nc, nb, ne, val, parameters, env ); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + mFirst.makeCall( name, subName, args, parameters, env ); + mSecond.makeCall( name, subName, args, parameters, env ); + } + + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + mFirst.beginSubcircuit( subName, in, out, parameters, env ); + mSecond.beginSubcircuit( subName, in, out, parameters, env ); + } + + + public void endSubcircuit(String subName, Environment env) { + mFirst.endSubcircuit( subName, env ); + mSecond.endSubcircuit( subName, env ); + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Template.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Template.java new file mode 100644 index 0000000000..9fb5beb193 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/Template.java @@ -0,0 +1,894 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.parser; + +import java.io.File; +import java.io.InputStream; +import java.io.Reader; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.NoSuchElementException; +import java.lang.Comparable; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.cast.impl.ChainEnvironment; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.SymbolRedeclaredException; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLInterfaceSimplifier; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; + +public class Template implements CDLFactoryInterface { + private Map templates; + private List statements; + private String[] in, out; + private String mStreamName; + private Map subcktParam; + + public static class CellRedefinitionException extends Exception { + + private final String mCellName; + private final String mFirstLocation; + private final String mSecondLocation; + + public CellRedefinitionException( final String cellName, + final String firstLocation, + final String secondLocation ) { + super( cellName + " was defined more than once." ); + mCellName = cellName; + mFirstLocation = firstLocation; + mSecondLocation = secondLocation; + } + + public final String getCellName() { + return mCellName; + } + + public final String getFirstLocation( ) { + return mFirstLocation; + } + + public final String getSecondLocation( ) { + return mSecondLocation; + } + } + + public interface Visitor { + void resistorStatement( final HierName name, + final HierName n1, + final HierName n2, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ); + void capacitorStatement( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ); + + void transistorStatement( final HierName name, + final String type, + final HierName ns, + final HierName nd, + final HierName ng, + final HierName nb, + final CDLLexer.InfoToken w, + final CDLLexer.InfoToken l, + final Map parameters, + final Environment env ); + void inductorStatement( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ); + void diodeStatement( final HierName name, + final String type, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ); + void callStatement( final HierName name, + final String subName, + final HierName[] args, + final Map parameters, + final Environment env ); + void bipolarStatement( final HierName name, + final String type, + final HierName nc, + final HierName nb, + final HierName ne, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ); + + } + + private interface DeviceInterface extends Comparable { + void execute(final Environment inner, final CDLSimpleInterface visitor); + void execute(final CDLFactoryInterface factory); + void execute(final CDLFactoryInterface factory, final Environment inner); + void accept( final Visitor v ); + + } + + private abstract static class Device implements DeviceInterface { + abstract int compareToSame(Object o); + public int compareTo(Object that) { + int ret = this.getClass().getName().compareTo(that.getClass().getName()); + if(ret != 0) + return ret; + else + return compareToSame(that); + } + } + + private static class Resistor extends Device { + public HierName name, n1, n2; + public CDLLexer.InfoToken val; + public Map parameters; + public Environment env; + public Resistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + this.name = name; + this.n1 = n1; + this.n2 = n2; + this.val = val; + this.parameters = parameters; + this.env = env; + } + public void execute(final Environment inner, + final CDLSimpleInterface visitor) { + Environment env = new ChainEnvironment(this.env, inner); + final double res = CDLInterfaceSimplifier.getValue(val, env); + visitor.makeResistor(name, n1, n2, 1 / res); + } + + public void execute(final CDLFactoryInterface factory) { + factory.makeResistor(name, n1, n2, val, parameters, env); + } + + public void execute(final CDLFactoryInterface factory, + final Environment inner + ) { + Environment env = new ChainEnvironment(this.env, inner); + factory.makeResistor(name, n1, n2, val, parameters, env); + } + + public void accept( final Visitor v ) { + v.resistorStatement( name, + n1, + n2, + val, + parameters, + env ); + } + + public int compareToSame(Object o) { + return compareToSame((Resistor)o); + } + + public int compareToSame(Resistor that) { + return this.name.compareTo(that.name); + } + } + + private static class Capacitor extends Device { + public HierName name, npos, nneg; + public CDLLexer.InfoToken val; + public Map parameters; + public Environment env; + public Capacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + this.name = name; + this.npos = npos; + this.nneg = nneg; + this.val = val; + this.parameters = parameters; + this.env = env; + } + public void execute(final Environment inner, + final CDLSimpleInterface visitor) { + Environment env = new ChainEnvironment(this.env, inner); + final double cap = CDLInterfaceSimplifier.getValue(val, env); + visitor.makeCapacitor(name, npos, nneg, cap); + } + + public void execute(final CDLFactoryInterface factory) { + factory.makeCapacitor(name, npos, nneg, val, parameters, env); + } + + public void execute(final CDLFactoryInterface factory, + final Environment inner + ) { + Environment env = new ChainEnvironment(this.env, inner); + factory.makeCapacitor(name, npos, nneg, val, parameters, env); + } + + public void accept( final Visitor v ) { + v.capacitorStatement( name, + npos, + nneg, + val, + parameters, + env ); + } + public int compareToSame(Object o) { + return compareToSame((Capacitor)o); + } + + public int compareToSame(Capacitor that) { + return this.name.compareTo(that.name); + } + } + + private static class Transistor extends Device { + public HierName name; + public String type; + public HierName ns, nd, ng, nb; + public CDLLexer.InfoToken w, l; + public Map parameters; + public Environment env; + public Transistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + this.name = name; + this.type = type; + this.ns = ns; + this.nd = nd; + this.ng = ng; + this.nb = nb; + this.w = w; + this.l = l; + this.parameters = parameters; + this.env = env; + } + public void execute(final Environment inner, + final CDLSimpleInterface visitor) { + Environment env = new ChainEnvironment(this.env, inner); + final double wid = CDLInterfaceSimplifier.getValue(w, env); + final double len = CDLInterfaceSimplifier.getValue(l, env); + + int typ; + if (type.startsWith("p") || type.startsWith("P")) { + typ = DeviceTypes.P_TYPE; + } else { + typ = DeviceTypes.N_TYPE; + } + + visitor.makeTransistor(name, typ, ns, nd, ng, nb, wid, len); + } + public void execute(final CDLFactoryInterface factory) { + factory.makeTransistor(name, type, ns, nd, ng, nb, w, l, parameters, env); + } + + public void execute(final CDLFactoryInterface factory, + final Environment inner + ) { + Environment env = new ChainEnvironment(this.env, inner); + factory.makeTransistor(name, type, ns, nd, ng, nb, w, l, parameters, env); + } + + public void accept( final Visitor v ) { + v.transistorStatement( name, + type, + ns, + nd, + ng, + nb, + w, + l, + parameters, + env ); + } + + public int compareToSame(Object o) { + return compareToSame((Transistor)o); + } + + public int compareToSame(Transistor that) { + return this.name.compareTo(that.name); + } + } + + private static class Inductor extends Device { + public HierName name, npos, nneg; + public CDLLexer.InfoToken val; + public Map parameters; + public Environment env; + public Inductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + this.name = name; + this.npos = npos; + this.nneg = nneg; + this.val = val; + this.parameters = parameters; + this.env = env; + } + + public void execute(final Environment inner, + final CDLSimpleInterface visitor) { + Environment env = new ChainEnvironment(this.env, inner); + final double ind = CDLInterfaceSimplifier.getValue(val, env); + visitor.makeInductor(name, npos, nneg, ind); + } + + public void execute(final CDLFactoryInterface factory) { + factory.makeInductor(name, npos, nneg, val, parameters, env); + } + + public void execute(final CDLFactoryInterface factory, + final Environment inner + ) { + Environment env = new ChainEnvironment(this.env, inner); + factory.makeInductor(name, npos, nneg, val, parameters, env); + } + + public void accept( final Visitor v ) { + v.inductorStatement( name, + npos, + nneg, + val, + parameters, + env ); + } + + public int compareToSame(Object o) { + return compareToSame((Inductor)o); + } + + public int compareToSame(Inductor that) { + return this.name.compareTo(that.name); + } + } + + private static class Diode extends Device { + public HierName name, npos, nneg; + public CDLLexer.InfoToken val; + public Map parameters; + public Environment env; + public String type; + public Diode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + this.name = name; + this.type = type; + this.npos = npos; + this.nneg = nneg; + this.val = val; + this.parameters = parameters; + this.env = env; + } + + public void execute(final Environment inner, + final CDLSimpleInterface visitor) { + Environment env = new ChainEnvironment(this.env, inner); + final double a = CDLInterfaceSimplifier.getValue(val, env); + final double w = Math.sqrt(a); + final double l = w; + final double p = 2*w + 2*l; + + int typ; + if (type.equals("DW") || type.equals("dw")) { + typ = DeviceTypes.N_TYPE; + } else { + typ = DeviceTypes.P_TYPE; + } + + visitor.makeDiode(name, typ, npos, nneg, w,l,a,p); + } + + public void execute(final CDLFactoryInterface factory) { + factory.makeDiode(name, type, npos, nneg, val, parameters, env); + } + + public void execute(final CDLFactoryInterface factory, + final Environment inner + ) { + Environment env = new ChainEnvironment(this.env, inner); + factory.makeDiode(name, type, npos, nneg, val, parameters, env); + } + + public void accept( final Visitor v ) { + v.diodeStatement( name, + type, + npos, + nneg, + val, + parameters, + env ); + } + + public int compareToSame(Object o) { + return compareToSame((Diode)o); + } + + public int compareToSame(Diode that) { + return this.name.compareTo(that.name); + } + } + + private static class Bipolar extends Device { + public HierName name, nc, nb, ne; + public CDLLexer.InfoToken val; + public Map parameters; + public Environment env; + public String type; + public Bipolar(HierName name, String type, HierName nc, HierName nb, + HierName ne, CDLLexer.InfoToken val, Map parameters, + Environment env) { + this.name = name; + this.type = type; + this.nc = nc; + this.nb = nb; + this.ne = ne; + this.val = val; + this.parameters = parameters; + this.env = env; + } + + public void execute(final Environment inner, + final CDLSimpleInterface visitor) { + Environment env = new ChainEnvironment(this.env, inner); + final double a = CDLInterfaceSimplifier.getValue(val, env); + + int typ; + if (type.startsWith("p") || type.startsWith("P")) { + typ = DeviceTypes.P_TYPE; + } else { + typ = DeviceTypes.N_TYPE; + } + + visitor.makeBipolar(name, typ, nc, nb, ne, a); + } + + public void execute(final CDLFactoryInterface factory) { + factory.makeBipolar(name, type, nc, nb, ne, val, parameters, env); + } + + public void execute(final CDLFactoryInterface factory, + final Environment inner + ) { + Environment env = new ChainEnvironment(this.env, inner); + factory.makeBipolar(name, type, nc, nb, ne, val, parameters, env); + } + + public void accept( final Visitor v ) { + v.bipolarStatement( name, + type, + nc, + nb, + ne, + val, + parameters, + env ); + } + + public int compareToSame(Object o) { + return compareToSame((Bipolar)o); + } + + public int compareToSame(Bipolar that) { + return this.name.compareTo(that.name); + } + } + + private static class Call extends Device { + public HierName name; + public String subName; + public HierName[] args; + public Map parameters; + public Environment env; + + public Call(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + assert env != null; + this.name = name; + this.subName = subName; + this.args = args; + this.parameters = parameters; + this.env = env; + } + public void execute(final Environment inner, + final CDLSimpleInterface visitor) { + Environment env = new ChainEnvironment(this.env, inner); + visitor.makeCall(name, subName, args, CDLInterfaceSimplifier.resolveCallParameter(parameters, env)); + } + + public void execute(final CDLFactoryInterface factory) { + factory.makeCall(name, subName, args, parameters, env); + } + + public void execute(final CDLFactoryInterface factory, + final Environment inner + ) { + Environment env = new ChainEnvironment(this.env, inner); + factory.makeCall(name, subName, args, parameters, env); + } + + public void accept( final Visitor v ) { + v.callStatement( name, + subName, + args, + parameters, + env ); + } + + public int compareToSame(Object o) { + return compareToSame((Call)o); + } + + public int compareToSame(Call that) { + return this.name.compareTo(that.name); + } + } + + public static class StatementIterator { + private final Iterator innerIter; + + public StatementIterator( final Iterator iter ) { + innerIter = iter; + } + + public boolean hasNext() { + return innerIter.hasNext(); + } + + /** @throws NoSuchElementException **/ + public void next( Visitor v ) { + final DeviceInterface curr = + ( DeviceInterface ) innerIter.next(); + + curr.accept( v ); + } + } + + + + public Template( final Map templates) { + this( templates, null ); + } + + public Template( final Map templates, + final String streamName ) { + this( templates, + new ArrayList(), + new String[0], + new String[0], + Collections.EMPTY_MAP, + streamName ); + } + + private Template( final Map templates, + final List statements, + final String[] in, + final String[] out, + final Map subcktParam, + final String streamName ) + { + this.templates = templates; + this.statements = statements; + this.in = in; + this.out = out; + this.subcktParam = subcktParam; + mStreamName = streamName; + } + + public void sortStatements() { + Collections.sort(statements); + } + + public String getStreamName() { + return mStreamName; + } + + public StatementIterator getStatements( ) { + return new StatementIterator( statements.iterator() ); + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + statements.add(new Resistor(name, n1, n2, val, parameters, env)); + } + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + statements.add(new Capacitor(name, npos, nneg, val, parameters, env)); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + statements.add(new Transistor(name, type, ns, nd, ng, nb, w, l, parameters, env)); + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + statements.add(new Diode(name, type, npos, nneg, val, parameters, env)); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + statements.add(new Inductor(name, npos, nneg, val, parameters, env)); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, CDLLexer.InfoToken val, + Map parameters, Environment env) { + statements.add(new Bipolar(name, type, nc, nb, ne, val, parameters, env)); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + statements.add(new Call(name, subName, args, parameters, env)); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + statements = new ArrayList(); + this.in = new String[in.length]; + System.arraycopy(in, 0, this.in, 0, in.length); + this.out = new String[out.length]; + System.arraycopy(out, 0, this.out, 0, out.length); + this.subcktParam = parameters; + } + + public void endSubcircuit(String subName, Environment env) { + templates.put(subName, new Template(templates, statements, in, out, subcktParam, mStreamName )); + } + + public Pair getArguments() { + return new Pair(in, out); + } + + public Map getParameters() { + return subcktParam; + } + + private Environment params2env(Map parameters) { + Environment env = new LocalEnvironment(); + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String key = (String) entry.getKey(); + final Double val = (Double) entry.getValue(); + if (val != null) { + try { + env.bind(Symbol.create(key), + FloatValue.valueOf(val.doubleValue())); + } catch (SymbolRedeclaredException e) { + System.err.println("Cannot happen!"); + } + } + } + return env; + } + + private Environment params2env(Map parameters, Environment inner) { + Environment env = new LocalEnvironment(); + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String key = entry.getKey().toString(); + final CDLLexer.InfoToken tok = (CDLLexer.InfoToken) entry.getValue(); + if (tok != null) { + try { + final Double val = tok.getValue(inner); + if (val == null) { + throw new RuntimeException( + "Cannot evaluate: " + tok.getText() + " at " + + tok.getFilename() + ":" + tok.getLine() + ":" + + tok.getColumn()); + } else { + env.bind(Symbol.create(key), + FloatValue.valueOf(val.doubleValue())); + } + } catch (SymbolRedeclaredException e) { + System.err.println("Cannot happen!"); + } + } + } + return env; + } + + /** Execute this template with the given parameter mapping using visitor. */ + public void execute(Map params, CDLSimpleInterface visitor) { + execute(params, visitor, null); + } + + public void execute(Map params, CDLSimpleInterface visitor, + String cellName) { + execute(params2env(params), visitor, cellName); + } + + public void execute(Environment env, CDLSimpleInterface visitor) { + execute(env, visitor, null); + } + + /** + * Execute this template with the given environment using visitor. + * @param env The environment to evaluate expressions with + * @param visitor The visitor to call + * @param cellName Call beginSubckt and endSubckt with cellName. If + * cellName is null then the calls are not made. + **/ + public void execute(Environment env, + CDLSimpleInterface visitor, + String cellName) { + if (cellName != null) { + visitor.beginSubcircuit(cellName, in, out); + } + for (Iterator i = statements.iterator(); i.hasNext(); ) { + final DeviceInterface device = (DeviceInterface) i.next(); + device.execute(env, visitor); + } + if (cellName != null) { + visitor.endSubcircuit(cellName); + } + } + + public void execute(CDLFactoryInterface factory, + Environment env, + String cellName) { + execute(factory, subcktParam, env, cellName); + } + + public void execute(CDLFactoryInterface factory, + Map params, + Environment env, + String cellName) { + Environment paramEnv = new ChainEnvironment(env, + params2env(params, env) ); + if (cellName != null) { + factory.beginSubcircuit(cellName, in, out, params, paramEnv); + } + for (Iterator i = statements.iterator(); i.hasNext(); ) { + final DeviceInterface device = (DeviceInterface) i.next(); + + device.execute(factory, paramEnv); + } + if (cellName != null) { + factory.endSubcircuit(cellName, paramEnv); + } + } + + public void execute(CDLFactoryInterface factory) { + for (Iterator i = statements.iterator(); i.hasNext(); ) { + final DeviceInterface device = (DeviceInterface) i.next(); + device.execute(factory); + } + } + + public static void getTemplatesAllowingRedefinition( final StringContainerIterator filesIter, + final Map templatesMap, + final List redefinitionExceptions ) { + + while ( filesIter.hasNext() ) { + final String currFileName = filesIter.next(); + final File currFile = new File( currFileName ); + try { + final InputStream currInputStream = new FileInputStream( currFile ); + final Reader currReader = new BufferedReader( new InputStreamReader( currInputStream, + "UTF-8" ) ); + final Map currMap = new HashMap(); + ReadCDLIntoFactory.readCDL( currReader, + new Template( currMap, currFileName ) ); + + final Iterator templateIter = currMap.entrySet().iterator(); + + while ( templateIter.hasNext() ) { + final Map.Entry currTemplateEntry = ( Map.Entry ) templateIter.next(); + final String currTemplateName = ( String ) currTemplateEntry.getKey(); + final Template currTemplate = ( Template ) currTemplateEntry.getValue(); + + final Template existingTemplate = ( Template ) templatesMap.put( currTemplateName, + currTemplate ); + + if ( existingTemplate != null ) { + + final Exception redefException = + new CellRedefinitionException( currTemplateName, + existingTemplate.getStreamName(), + currFileName ); + redefinitionExceptions.add( redefException ); + } + } + } + catch ( IOException e ) { + throw new RuntimeException( e ); + } + catch ( RecognitionException e ) { + throw new RuntimeException( e ); + } + catch ( TokenStreamException e ) { + throw new RuntimeException( e ); + } + } + } + + public static void getTemplates( final StringContainerIterator filesIter, + final Map templatesMap ) throws CellRedefinitionException { + final List redefinitions = new LinkedList(); + getTemplatesAllowingRedefinition( filesIter, + templatesMap, + redefinitions ) ; + if ( redefinitions.size() > 0 ) { + final CellRedefinitionException redefinition = + ( CellRedefinitionException ) redefinitions.get( 0 ); + throw redefinition; + } + + } + + + public void removeTemplate(final String name ) { + templates.remove(name); + } + + public boolean containsTemplate(final String name ) { + return templates.containsKey(name); + } + + /** Fill map with entries from cell name (String) to Template */ + public static void getTemplates(final Reader file, final Map cells) { + try { + ReadCDLIntoFactory.readCDL(file, new Template(cells)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** Returns a map from cell name (String) to Template */ + public static Map getTemplates(final Reader file) { + final Map cells = new HashMap(); + getTemplates(file, cells); + return cells; + } + + public Template getTemplate(String name) { + return (Template)templates.get(name); + } + + public Map getTemplates() { + return templates; + } + + public static Template setInOut(final Template templ, final String[] in, + final String[] out) { + return new Template(null, templ.statements, in, out, templ.subcktParam, + templ.mStreamName); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateIterator.java new file mode 100644 index 0000000000..7c829f415f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateIterator.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.parser; + + +import java.util.NoSuchElementException; + +import com.avlsi.file.cdl.parser.Template; + +public interface TemplateIterator { + + boolean hasNext(); + + Template next() throws NoSuchElementException; + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateSplitterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateSplitterFactory.java new file mode 100644 index 0000000000..df526f1be4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/TemplateSplitterFactory.java @@ -0,0 +1,153 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.parser; + +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; + +import com.avlsi.util.container.Counter; +import com.avlsi.util.container.HashCounter; +import com.avlsi.util.container.Pair; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLInterfaceSimplifier; +import com.avlsi.file.common.HierName; + + +/** + * Factory that splits templates of differently parameterized instantiations + * into new templates, one for each parameterization. So for + * .SUBCKT subcell + * .PARAM foo=default + * M0 bla ... w=foo + * .ENDS + * .SUBCKT cell + * X1 / subcell w=bar + * X2 / subcell w=baz + * .ENDS + * originally we have 2 templates, one for cell and one for subcell. + * after running through this puppy, we have the same templtes for cell, + * but now there are 2 templates from the subcell .SUBCKT: + * subcell__w_E_bar and subcell__w_E_baz that have the environment from + * the parameteriztion built in. + * The first template will always have the original name, in case + * something else wants to use it(AspiceCellAdaptor in CDL2Cast). + **/ + +public class TemplateSplitterFactory implements CDLFactoryInterface { + + Map templateMap = new HashMap(); + Map envMap = new HashMap(); + + private Template target; + public TemplateSplitterFactory(Template template) { + this.target = template; + } + + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + target.makeResistor(name, n1, n2, val, parameters, env); + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + target.makeCapacitor(name, npos, nneg, val, parameters, env); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + target.makeTransistor(name, type, ns, nd, ng, nb, w, l, parameters, env); + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + target.makeDiode(name,type,npos,nneg,val,parameters,env); + } + + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + target.makeInductor(name,npos,nneg,val,parameters,env); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, + CDLLexer.InfoToken val, + Map parameters, Environment env) { + target.makeBipolar(name,type,nc,nb,ne,val,parameters,env); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + // Here is a key assumption... + // that we can get a template if we're making a call + Template template = (Template)templateMap.get(subName); + + final int count = newCellCounter.getCount(subName); + if(count == 0) template.removeTemplate(subName); + final String newName = + getParameterizedCellName(subName,parameters,env); + if(!target.containsTemplate(newName)) { + template.execute(new Template(target.getTemplates()), + parameters, + (Environment)envMap.get(subName), + newName); + } + target.makeCall(name,newName,args,parameters,env); + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + target.beginSubcircuit(subName,in,out,parameters,env); + } + + public void endSubcircuit(String subName, Environment env) { + target.endSubcircuit(subName,env); + // add the default template to the map + // and it's environment so parameterized templates + // can use it + envMap.put(subName, env); + Template newTemplate = target.getTemplate(subName); + templateMap.put(subName, newTemplate ); + } + + private final Map newCellNames = new HashMap(); + private final Counter newCellCounter = new HashCounter(); + + /** + * Get a new name for a parameterized template + * For the first parameterization we call this with, + * we'll just get bck the original name. + **/ + private String getParameterizedCellName(String subName, + Map parameters, + Environment env) { + if(parameters.isEmpty()) return subName; + final int count = newCellCounter.getCount(subName); + final String newCellName = + (count == 0) ? subName : subName + count; + final Pair key = new Pair(subName,parameters.toString()); + if(newCellNames.containsKey(key)) { + return (String) newCellNames.get(key); + } + else { + newCellNames.put(key,newCellName); + newCellCounter.add(subName); + return newCellName; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/custom.mk new file mode 100644 index 0000000000..836c874770 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/custom.mk @@ -0,0 +1,16 @@ +MAKE_ANTLR_RULES_G_FILE_NAME := CDL.g +MAKE_ANTLR_RULES_LEXER_NAME := CDLLexer +MAKE_ANTLR_RULES_PARSER_NAME := CDLParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := CDLLexer +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk + + +CURR_INTERMEDIATE_FILES := $(CURR_TARGET_DIR)/CDLWalker.java $(CURR_TARGET_DIR)/cdlstat.sh $(CURR_TARGET_DIR)/cdlaliases.sh $(CURR_INTERMEDIATE_FILES) + +$(CURR_TARGET_DIR)/cdlstat.sh: \ + $(CURR_PROJECT_DIR)/../../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.file.cdl.parser.CDLstat/" >$@ + +$(CURR_TARGET_DIR)/cdlaliases.sh: \ + $(CURR_PROJECT_DIR)/../../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.file.cdl.parser.CDLAliases/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/javafiles-custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/javafiles-custom.mk new file mode 100644 index 0000000000..a9167634ba --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/parser/javafiles-custom.mk @@ -0,0 +1,5 @@ +CURR_RESULTS_FILES := $(CURR_RESULT_FILES) $(CURR_TARGET_DIR)/RenumberFactory.sh + +$(CURR_TARGET_DIR)/RenumberFactory.sh: \ + $(CURR_PROJECT_DIR)/../../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.file.cdl.parser.RenumberFactory/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/CDLWriter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/CDLWriter.java new file mode 100644 index 0000000000..2156ed2196 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/CDLWriter.java @@ -0,0 +1,156 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id: //depot/sw/cad/java/main/src/com/avlsi/file/cdl/parser/CDLFactoryEmitter +.java#4 $ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util; + +import java.io.IOException; +import java.io.Writer; + +public class CDLWriter { + public class Exception extends RuntimeException { + public Exception(String message, Throwable cause) { + super(message, cause); + } + public Exception(String message) { + super(message); + } + } + + protected Writer w; + protected int linesize, maxLineSize; + + public CDLWriter(final Writer w, final int maxLineSize) { + this.w = w; + this.linesize = 0; + this.maxLineSize = maxLineSize; + } + + private void write(final String s) { + try { + w.write(s); + } catch (IOException e) { + throw new Exception("I/O problems while writing", e); + } + } + + /* Print the string as is */ + protected void print(final String s) { + linesize += s.length(); + write(s); + } + + /* Create whitespace, then print the string */ + protected void printws(final String s) { + int l = s.length(); + if (linesize + l + 1 > maxLineSize) { + println(); + write("+"); + } else { + write(" "); + } + write(s); + linesize += 1 + l; + } + + protected void printws(final String[] s) { + for (int i = 0; i < s.length; ++i) printws(s[i]); + } + + /* Go to a newline */ + protected void println() { + linesize = 0; + write("\n"); + } + + public void comment(String comment) { + print("*" + comment); + println(); + } + + public void subckt(String name, String[] in, String[] out, + String[] parameters) { + print(".SUBCKT"); + printws(name); + + printws(in); + printws(out); + printws(parameters); + println(); + } + + public void ends(String name) { + print(".ENDS"); + println(); + } + + public void C(String name, String n1, String n2, String mname, + String capacitance, String[] parameters) { + print("C" + name); + printws(n1); + printws(n2); + if (mname != null) printws(mname); + if (capacitance != null) printws(capacitance); + printws(parameters); + println(); + } + + public void E(String name, String np, String nn, String keyword, + String[] parameters) { + print("E" + name); + printws(np); + printws(nn); + printws(keyword); + printws(parameters); + println(); + } + + public void G(String name, String np, String nn, String keyword, + String[] parameters) { + print("G" + name); + printws(np); + printws(nn); + printws(keyword); + printws(parameters); + println(); + } + + public void M(String name, String nd, String ng, String ns, String nb, + String mname, String length, String width, + String[] parameters) { + print("M" + name); + printws(nd); + printws(ng); + printws(ns); + if (nb != null) printws(nb); + printws(mname); + printws("L=" + length); + printws("W=" + width); + printws(parameters); + println(); + } + + public void R(String name, String n1, String n2, String mname, + String resistance, String[] parameters) { + print("R" + name); + printws(n1); + printws(n2); + if (mname != null) printws(mname); + printws(resistance); + printws(parameters); + println(); + } + + public void X(String name, String[] args, String subname, + String[] parameters) { + print("X" + name); + printws(args); + printws(subname); + printws(parameters); + println(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/BindRulNameInterfaceFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/BindRulNameInterfaceFactory.java new file mode 100644 index 0000000000..50ef72c7d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/BindRulNameInterfaceFactory.java @@ -0,0 +1,387 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.util.rename; + + +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.io.IOException; +import java.io.Reader; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + + +public class BindRulNameInterfaceFactory implements CDLNameInterfaceFactory { + + private class CellMappings { + private final String mOldCellName; + private final String mNewCellName; + private final Map mNodeMap; + private final Map mInstanceMap; + + + public CellMappings( final String oldCellName, + final String newCellName ) { + mOldCellName = oldCellName; + mNewCellName = newCellName; + + mNodeMap = new HashMap(); + mInstanceMap = new HashMap(); + } + + public final String getOldCellName() { + return mOldCellName; + } + + public final String getNewCellName() { + return mNewCellName; + } + + public final String getNewNodeNameForOldNodeName( final String oldNodeName ) { + return ( String ) mNodeMap.get( oldNodeName ); + } + + public final String getNewInstanceNameForOldInstanceName( final String oldInstanceName ) { + return ( String ) mInstanceMap.get( oldInstanceName ); + } + + public final void addNodeMapping( final String oldNodeName, + final String newNodeName ) { + mNodeMap.put( oldNodeName, newNodeName ); + } + + public final void addInstanceMapping( final String oldInstanceName, + final String newInstanceName ) { + mInstanceMap.put( oldInstanceName, + newInstanceName ); + } + + public final Set getNewNodeNames( ) { + final Iterator entryIter = mNodeMap.entrySet().iterator(); + + final Set ret = new HashSet(); + + while ( entryIter.hasNext() ) { + final Map.Entry currEntry = ( Map.Entry ) entryIter.next(); + final String currNewName = ( String ) currEntry.getValue(); + ret.add( currNewName ); + } + return ret; + } + + public final Set getNewInstanceNames( ) { + final Iterator entryIter = mInstanceMap.entrySet().iterator(); + + final Set ret = new HashSet(); + + while ( entryIter.hasNext() ) { + final Map.Entry currEntry = ( Map.Entry ) entryIter.next(); + final String currNewName = ( String ) currEntry.getValue(); + ret.add( currNewName ); + } + return ret; + } + } + + + public class BindRulParser { + private Map mTargetCellMaps; + private CellMappings mCurrMap; + + private boolean mEOF; + + private Reader mSrcReader ; + + private final String readLine( ) + throws IOException + { + if ( ! mEOF ) { + final StringBuffer ret = new StringBuffer(); + int readRet = 0; + while ( ( readRet >= 0 ) && ( readRet != '\n' ) ) { + readRet = mSrcReader.read(); + if ( ( readRet >= 0 ) && ( readRet != '\n' ) ) { + ret.append( ( char ) readRet ); + } + } + if ( readRet < 0 ) { + mEOF = true; + } + return ret.toString(); + } + else { + return ""; + } + } + + private void addCellNameMapping( final String originalCellName, + final String newCellName ) { + mCurrMap = ( CellMappings ) mTargetCellMaps.get( originalCellName ); + if ( mCurrMap == null ) { + mCurrMap = new CellMappings( originalCellName, newCellName ); + mTargetCellMaps.put( originalCellName, mCurrMap ); + } + } + + private void addNodeNameMapping( final String originalNodeName, + final String newNodeName ) { + mCurrMap.addNodeMapping( originalNodeName, + newNodeName ); + } + + private void addInstanceNameMapping( final String originalInstanceName, + final String newInstanceName ) { + mCurrMap.addInstanceMapping( originalInstanceName, + newInstanceName ); + } + + private List splitLine( final String currLine ) { + int i; + final int length = currLine.length(); + + boolean inQuotes=false; + + final List ret = new ArrayList(); + + final StringBuffer accum = new StringBuffer(); + + for ( i = 0 ; i < length ; ++i ) { + final char c = currLine.charAt( i ); + if ( Character.isWhitespace( c ) ) { + if ( inQuotes ) { + accum.append( c ); + } + else { + ret.add( accum.toString() ); + accum.delete( 0, accum.length() ); + } + + } + else if ( c == '"' ) { + inQuotes = inQuotes ^ true; + } + else { + accum.append( c ); + } + } + if ( accum.length() > 0 ) { + ret.add( accum.toString() ); + } + return ret; + + } + + private String getFirstWord( final String str ) { + return str.split( "\\p{Space}+" )[0]; + } + + private void parse( ) + throws IOException + { + while ( ! mEOF ) { + final String currLine = readLine(); + + if ( currLine.length() > 0 ) { + + final String[] tokens = ( String[] ) splitLine( currLine ).toArray( new String[0] ); + + if ( tokens.length >= 2 ) { + char statementType = tokens[0].charAt( 0 ); + switch ( statementType ) { + case 'C': + case 'c': + addCellNameMapping( getFirstWord( tokens[1] ) , + getFirstWord( tokens[2] ) ); + break; + case 'N': + case 'n': + addNodeNameMapping( tokens[1], tokens[2] ); + break; + case 'I': + case 'i': + addInstanceNameMapping( tokens[1], tokens[2] ); + break; + } + } + } + } + } + public BindRulParser( final Reader srcReader, + final Map targetCellMaps ) + throws IOException + { + mTargetCellMaps = targetCellMaps; + mCurrMap = null; + mEOF = false; + mSrcReader = srcReader; + parse(); + } + } + + private final class NameInterface implements CDLNameInterface { + + private final CDLNameInterface mChained; + + private final Map mCellsMappings; + + private final CellMappings mCellMappings; + + public NameInterface( final CDLNameInterface chained, + final String cellName, + final Map cellsMappings ) { + mChained = chained; + mCellsMappings = cellsMappings; + mCellMappings = ( CellMappings ) cellsMappings.get( cellName ); + + } + + public String renameCell( final String oldCellName ) throws CDLRenameException { + final CellMappings cellMappings = ( CellMappings ) mCellsMappings.get( oldCellName ); + if ( cellMappings != null ) { + return cellMappings.getNewCellName(); + } + else { + return mChained.renameCell( oldCellName ); + } + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + if ( mCellMappings != null ) { + final String newNodeName = + mCellMappings.getNewNodeNameForOldNodeName( oldNodeName ); + if ( newNodeName != null ) { + return newNodeName; + } + else { + return mChained.renameNode( oldNodeName ); + } + } + else { + return mChained.renameNode( oldNodeName ); + } + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + if ( mCellMappings != null ) { + final String newDeviceName = + mCellMappings.getNewInstanceNameForOldInstanceName( oldDeviceName ); + if ( newDeviceName != null ) { + return newDeviceName; + } + else { + return mChained.renameDevice( oldDeviceName ); + } + } + else { + return mChained.renameDevice( oldDeviceName ); + } + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + if ( mCellMappings != null ) { + final String newInstanceName = + mCellMappings.getNewInstanceNameForOldInstanceName( oldInstanceName ); + if ( newInstanceName != null ) { + return newInstanceName; + } + else { + return mChained.renameDevice( oldInstanceName ); + } + } + else { + return mChained.renameDevice( oldInstanceName ); + } + } + + public String renameTransistorModel( final String oldTransistorModel ) + throws CDLRenameException + { + + final CellMappings cellMappings = ( CellMappings ) mCellsMappings.get( oldTransistorModel ); + if ( cellMappings != null ) { + return cellMappings.getNewCellName(); + } + else { + return mChained.renameTransistorModel( oldTransistorModel ); + } + } + } + + final Map mCellsMaps; + final CDLNameInterfaceFactory mNameInterfaceFactory; + + public BindRulNameInterfaceFactory( final Reader srcReader, + final CDLNameInterfaceFactory nameInterfaceFactory ) + throws IOException + { + mCellsMaps = new HashMap(); + new BindRulParser( srcReader, mCellsMaps ); + mNameInterfaceFactory = nameInterfaceFactory; + } + + + public CDLNameInterface getNameInterface( final String cellName ) + throws CDLRenameException + { + final CDLNameInterface chained = mNameInterfaceFactory.getNameInterface( cellName ); + + return new NameInterface( chained, cellName, mCellsMaps ); + } + + public Set getNewCellNames( ) { + final Iterator entryIter = mCellsMaps.entrySet().iterator(); + + final Set ret = new HashSet(); + + while ( entryIter.hasNext() ) { + final Map.Entry currEntry = ( Map.Entry ) entryIter.next(); + final CellMappings currCellMappings = ( CellMappings ) currEntry.getValue(); + ret.add( currCellMappings.getNewCellName() ); + } + return ret; + } + + public Set getNewNodeNamesForOldCellName( final String oldCellName ) { + final CellMappings cellMappings = ( CellMappings ) mCellsMaps.get( oldCellName ); + if ( cellMappings != null ) { + return cellMappings.getNewNodeNames(); + } + else { + return Collections.EMPTY_SET; + } + } + + public Set getNewInstanceNamesForOldCellName( final String oldCellName ) { + final CellMappings cellMappings = ( CellMappings ) mCellsMaps.get( oldCellName ); + if ( cellMappings != null ) { + return cellMappings.getNewInstanceNames(); + } + else { + return Collections.EMPTY_SET; + } + } + + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.java new file mode 100644 index 0000000000..3fd6248cc2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public interface CDLNameInterface { + + String renameCell( final String oldCellName ) + throws CDLRenameException; + + String renameNode( final String oldNodeName ) + throws CDLRenameException; + + String renameDevice( final String oldDeviceName ) + throws CDLRenameException; + + String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException; + + String renameTransistorModel( final String oldTransistorModel ) + throws CDLRenameException; + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.py new file mode 100644 index 0000000000..99efcf17e1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterface.py @@ -0,0 +1,17 @@ +CDLRenameException = "CDL Rename error" + +class CDLNameInterface: + def renameCell(self, name): + 0 + + def renameNode(self, name): + 0 + + def renameDevice(self, name): + 0 + + def renameSubCellInstance(self, name): + 0 + + def renameTransistorModel(self, name): + 0 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterfaceFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterfaceFactory.java new file mode 100644 index 0000000000..66f1ed9931 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLNameInterfaceFactory.java @@ -0,0 +1,20 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; + +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public interface CDLNameInterfaceFactory { + + CDLNameInterface getNameInterface( final String cellName ) throws CDLRenameException ; + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameException.java new file mode 100644 index 0000000000..8c279295e5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameException.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.common.HierName; + +public class CDLRenameException extends Exception { + + public CDLRenameException( final HierName from, final HierName to ) { + this( from.toString(), to.toString(), null ); + } + + public CDLRenameException( final String from, final String to, + final Throwable cause ) { + this( "Could not rename \"" + + from + "\" to \"" + to + "\".", cause ); + } + + public CDLRenameException( final String errorMessage ) { + super( errorMessage ); + } + + public CDLRenameException( final String errorMessage, + final Throwable cause ) { + super( errorMessage, cause ); + } + + public CDLRenameException( final Throwable cause ) { + super( cause ); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameFactory.java new file mode 100644 index 0000000000..e9b3c7d2b9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenameFactory.java @@ -0,0 +1,201 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import java.util.Map; + +import com.avlsi.cast.impl.Environment; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; + +/** + * An CDLFactoryInterface that can be used to rename nodes and names of circuit + * components to another format + **/ +public final class CDLRenameFactory implements CDLFactoryInterface { + private final CDLFactoryInterface out; + private CDLNameInterface ni; + private final CDLNameInterfaceFactory nif; + private String subckt; + + public static class RenameException extends RuntimeException { + RenameException(final String message, final String cell, + final CDLRenameException e) { + super(message + (cell == null ? "" : " in cell " + cell)); + initCause(e); + } + } + + public CDLRenameFactory(final CDLFactoryInterface out, + final CDLNameInterfaceFactory nif) { + this.out = out; + this.nif = nif; + this.ni = null; + } + + private String _(final HierName name) { + return name.getAsString('.'); + } + + private HierName _(final String name) { + try { + return HierName.makeHierName(name, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException(e.getMessage()); + } + } + + private HierName renameNode(final HierName node) { + return _(renameNode(_(node))); + } + + private String renameNode(final String node) { + try { + return ni.renameNode(node); + } catch (CDLRenameException e) { + throw new RenameException("Cannot rename node: " + node, subckt, e); + } + } + + private HierName renameDevice(final HierName device) { + try { + return _(ni.renameDevice(_(device))); + } catch (CDLRenameException e) { + throw new RenameException( + "Cannot rename device: " + device, subckt, e); + } + } + + private HierName renameSubCellInstance(final HierName instance) { + try { + return _(ni.renameSubCellInstance(_(instance))); + } catch (CDLRenameException e) { + throw new RenameException( + "Cannot rename instance: " + instance, subckt, e); + } + } + + private String renameTransistorModel(final String model) { + try { + return ni.renameTransistorModel(model); + } catch (CDLRenameException e) { + throw new RenameException( + "Cannot rename transistor model: " + model, subckt, e); + } + } + + private String renameCell(final String cell) { + try { + return ni.renameCell(cell); + } catch (CDLRenameException e) { + throw new RenameException("Cannot rename cell: " + cell, subckt, e); + } + } + + public void makeResistor(final HierName name, final HierName n1, + final HierName n2, final CDLLexer.InfoToken val, + final Map parameters, final Environment env) { + out.makeResistor(renameDevice(name), renameNode(n1), renameNode(n2), + val, parameters, env); + } + + public void makeCapacitor(final HierName name, final HierName npos, + final HierName nneg, final CDLLexer.InfoToken val, + final Map parameters, final Environment env) { + out.makeCapacitor(renameDevice(name), renameNode(npos), + renameNode(nneg), val, parameters, env); + } + + public void makeTransistor(final HierName name, final String type, + final HierName ns, final HierName nd, + final HierName ng, final HierName nb, + final CDLLexer.InfoToken width, + final CDLLexer.InfoToken length, + final Map parameters, final Environment env) { + out.makeTransistor(renameDevice(name), renameTransistorModel(type), + renameNode(ns), renameNode(nd), renameNode(ng), + renameNode(nb), width, length, parameters, env); + } + + public void makeDiode(final HierName name, final String type, + final HierName npos, final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, final Environment env) { + out.makeDiode(renameDevice(name), type, renameNode(npos), + renameNode(nneg), val, parameters, env); + } + + public void makeInductor(final HierName name, final HierName npos, + final HierName nneg, final CDLLexer.InfoToken val, + final Map parameters, final Environment env) { + out.makeInductor(renameDevice(name), renameNode(npos), renameNode(nneg), + val, parameters, env); + } + + public void makeBipolar(final HierName name, final String type, + final HierName nc, final HierName nb, + final HierName ne, final CDLLexer.InfoToken val, + final Map parameters, final Environment env) { + out.makeBipolar(renameDevice(name), type, renameNode(nc), + renameNode(nb), renameNode(ne), val, parameters, env); + } + + public void makeCall(final HierName name, final String subName, + final HierName[] args, final Map parameters, + final Environment env) { + final HierName[] newargs = new HierName[args.length]; + for (int i = 0; i < args.length; ++i) { + newargs[i] = renameNode(args[i]); + } + out.makeCall(renameSubCellInstance(name), renameCell(subName), + newargs, parameters, env); + } + + public void beginSubcircuit(final String subName, final String[] in, + final String[] out, final Map parameters, + final Environment env) { + + subckt = subName; + + try { + ni = nif.getNameInterface( subName ); + } + catch ( CDLRenameException e ) { + throw new RenameException( + "Cannot get name interface for cell: " + subName, null, e); + } + + final String[] newin = new String[in.length]; + for (int i = 0; i < in.length; ++i) { + newin[i] = renameNode(in[i]); + } + + final String[] newout = new String[out.length]; + for (int i = 0; i < out.length; ++i) { + newout[i] = renameNode(out[i]); + } + + this.out.beginSubcircuit(renameCell(subName), newin, newout, parameters, + env); + } + + public void endSubcircuit(final String subName, final Environment env) { + out.endSubcircuit(renameCell(subName), env); + ni = null; + subckt = null; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamer.java new file mode 100644 index 0000000000..13f5ed89f9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamer.java @@ -0,0 +1,343 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.file.cdl.util.rename; + + +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +import java.io.Writer; +import java.io.Reader; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.InputStreamReader; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + + +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; + +import com.avlsi.file.cdl.util.rename.CDLRenamerFactory; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.ReloadableNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.PMCHackNameInterface; + +import com.avlsi.io.NullWriter; + +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; + +/** + * An CDLFactoryInterface that can be used to rename nodes and names of circuit + * components to another format + **/ +public class CDLRenamer { + public interface StartObserver { + void renameStart() throws CDLRenameException; + } + public interface EndObserver { + void renameEnd() throws CDLRenameException; + } + private static class CompositeInterface extends CompositeCDLNameInterface + implements StartObserver, EndObserver { + public CompositeInterface(final CDLNameInterface f, + final CDLNameInterface g) { + super(f, g); + } + public void renameStart() throws CDLRenameException { + if (f instanceof StartObserver) { + ((StartObserver) f).renameStart(); + } + if (g instanceof StartObserver) { + ((StartObserver) g).renameStart(); + } + } + public void renameEnd() throws CDLRenameException { + if (f instanceof EndObserver) { + ((EndObserver) f).renameEnd(); + } + if (g instanceof EndObserver) { + ((EndObserver) g).renameEnd(); + } + } + } + + private static void usage( String m ) { + + System.err.println( "Usage: cdl_renamer\n" + + " --source-cdl-file=file\n" + + " --name-in=cast|gds2|cadence|pmc_hack|rcx_hack\n" + + " --name-out=cast|gds2|cadence|pmc_hack|rcx_hack\n" + + " --translated-cdl=file\n" + + " [--rcx-cell-map=file]\n" + + " [--rcx-pipo-map=file]\n" + + " [--translated-nmap=file]\n" + + " (only understands conditionals and loops if nmap specified)\n" ); + if (m != null && m.length() > 0) + System.err.print( m ); + System.exit(1); + } + + private static void usage() { + usage( null ); + } + + private static void usagej() { + + final String className = CDLRenamer.class.getName(); + + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className + "\n" + + " --source-cdl-file=file\n" + + " --name-in=cast|gds2|cadence|pmc_hack|rcx_hack\n" + + " --name-out=cast|gds2|cadence|pmc_hack|rcx_hack\n" + + " --translated-cdl=file\n" + + " [--rcx-cell-map=file]\n" + + " [--rcx-pipo-map=file]\n" + + " [--translated-nmap=file]\n" + + " (only understands conditionals and loops if nmap specified)\n" ); + } + + public static Writer openOutputFile( final String fileName ) + throws IOException + { + final Writer ret; + + final OutputStream outputStream = + new FileOutputStream( fileName ); + + ret = new BufferedWriter( new OutputStreamWriter( outputStream ) ); + + return ret; + } + + public static void main(String[] args) + throws Exception + { + final CommandLineArgs parsedArgs = + new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + final CommandLineArgs theArgs = pedanticArgs; + + final String nameIn = + theArgs.getArgValue( "name-in", null ); + + final String nameOut = + theArgs.getArgValue( "name-out", null ); + + final String translatedCDLFileName = + theArgs.getArgValue( "translated-cdl", null ); + + final String nameMapFileName = + theArgs.getArgValue( "translated-nmap", null ); + + final String sourceCDLFileName = + theArgs.getArgValue( "source-cdl-file", null ); + + pedanticArgs.argTag("rcx-cell-map"); + pedanticArgs.argTag("rcx-pipo-map"); + + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + usage( pedanticArgs.pedanticString() ); + } + + final List outputFileNames = new ArrayList( 2 ); + + if ( ( sourceCDLFileName != null ) && + ( translatedCDLFileName != null ) && + ( nameIn != null ) && + ( nameOut != null ) ) { + final File sourceCDLFile = new File( sourceCDLFileName ); + + if ( ( sourceCDLFile.isFile() ) && ( sourceCDLFile.canRead() ) ) { + + final InputStream sourceCDLInputStream = + new FileInputStream( sourceCDLFile ); + + final Reader sourceCDLReader = + new BufferedReader( + new InputStreamReader( sourceCDLInputStream ) ); + + final CDLRenamerFactory cdlFactory = + new CDLRenamerFactory( ); + + + outputFileNames.add( translatedCDLFileName ); + + final Writer cdlWriter = + openOutputFile( translatedCDLFileName ); + + CDLNameInterface ni; + + if( nameIn.equals(nameOut) ) { + ni = new IdentityNameInterface(); + } + else { + final CDLNameInterface f,g; + + if( nameIn.equals( "cast" ) || + nameOut.equals( "pmc_hack" ) ) { + f = new IdentityNameInterface(); + } + else if( nameIn.equals( "cadence" ) ) { + f = new CadenceReverseNameInterface(); + } + else if ( nameIn.equals( "gds2" ) ) { + f = new GDS2ReverseNameInterface(); + } + else if ( nameIn.equals( "pmc_hack" ) ) { + f = PMCHackNameInterface.getReverseNamer(); + } + else if ( nameIn.equals( "rcx_hack" ) ) { + final String cellMapFile = + theArgs.getArgValue("rcx-cell-map", null); + if (cellMapFile == null) { + throw new CDLRenameException( + "rcx_hack naming requires valid " + + "--rcx-cell-map cell name mapping file" ); + } + final Reader r = new FileReader(cellMapFile); + f = RCXHackNameInterface.getReverseNamer(r); + } + else + throw new CDLRenameException("Invalid translation: " + + nameIn + " -> " + nameOut ); + + if( nameOut.equals( "cast" ) || + nameIn.equals( "pmc_hack" ) ) { + g = new IdentityNameInterface(); + } + else if( nameOut.equals( "cadence" ) ) { + g = new CadenceNameInterface(); + } + else if( nameOut.equals( "gds2" ) ) { + g = new GDS2NameInterface(); + } + else if( nameOut.equals( "pmc_hack" ) ) { + g = PMCHackNameInterface.getForwardNamer(); + } + else if ( nameOut.equals( "rcx_hack" ) ) { + final String cellMapFile = + theArgs.getArgValue("rcx-cell-map", null); + final String pipoMapFile = + theArgs.getArgValue("rcx-pipo-map", null); + if (cellMapFile == null) { + throw new CDLRenameException( + "rcx_hack naming requires valid " + + "--rcx-cell-map cell name mapping file" ); + } + final Writer cellWriter = new FileWriter(cellMapFile); + final Writer pipoWriter = pipoMapFile == null ? + (Writer) NullWriter.getInstance() : + (Writer) new FileWriter(pipoMapFile); + g = RCXHackNameInterface.getForwardNamer( + 60, cellWriter, pipoWriter); + } + else + throw new CDLRenameException("Invalid translation: " + + nameIn + " -> " + nameOut ); + ni = new CompositeInterface(f,g); + } + final CDLNameInterface nameInterface = ni; + try { + if (nameInterface instanceof StartObserver) { + ((StartObserver) nameInterface).renameStart(); + } + if( nameMapFileName != null ) { + final ReloadableNameInterface reloadableNameInterface = + new ReloadableNameInterface( nameInterface ); + + cdlFactory.addNameInterface( cdlWriter, + reloadableNameInterface, + 76 ); + + ReadCDLIntoFactory.readCDL( sourceCDLReader, + cdlFactory ); + + outputFileNames.add(nameMapFileName); + + final Writer nameMapWriter = + openOutputFile( nameMapFileName ); + + reloadableNameInterface.save( nameMapWriter ); + + nameMapWriter.close(); + } + else { + cdlFactory.addNameInterface( cdlWriter, + nameInterface, + 76 ); + ReadCDLIntoFactory.readCDLSimple( sourceCDLReader, + cdlFactory ); + } + if (nameInterface instanceof EndObserver) { + ((EndObserver) nameInterface).renameEnd(); + } + cdlFactory.closeOutputs(); + if ( cdlFactory.haveError() ){ + throw cdlFactory.getError(); + } + } + catch ( Exception e ) { + final Iterator outputFileNameIter = outputFileNames.iterator(); + + cdlFactory.closeOutputs(); + + while ( outputFileNameIter.hasNext() ) { + + final String currOutputFileName = ( String ) outputFileNameIter.next(); + + final File currOutputFile = new File( currOutputFileName ); + + System.out.println( "deleting " + currOutputFileName + "." ); + + if ( currOutputFile.isFile() ) { + currOutputFile.delete(); + } + } + throw e; + } + } + else { + System.out.println( "\"" + + sourceCDLFileName + + "\" is not a readable file." ); + } + } + else { + if ( sourceCDLFileName == null ) { + System.out.println( "You must specify a source cdl file." ); + } + usage(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamerFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamerFactory.java new file mode 100644 index 0000000000..b3808c8300 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CDLRenamerFactory.java @@ -0,0 +1,491 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import java.io.Writer; +import java.io.IOException; + +import java.util.Iterator; +import java.util.Map; +import java.util.Collection; +import java.util.LinkedList; + +import com.avlsi.cast.impl.Environment; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; + +/** + * An CDLFactoryInterface that can be used to rename nodes and names of circuit + * components to another format + **/ +public class CDLRenamerFactory implements CDLFactoryInterface { + + + private static final class OutputInfo { + private final Writer m_CDLOutput; + + private final int m_MaxLineSize; + private int m_CurrLineSize; + + private final CDLNameInterface m_RenameInterface; + + public OutputInfo( final Writer cdlOutput, + final CDLNameInterface renameInterface, + final int maxLineSize ) { + m_CDLOutput = cdlOutput; + m_RenameInterface = renameInterface; + m_CurrLineSize = 0; + m_MaxLineSize = maxLineSize; + } + + public void print( final StringBuffer s ) throws IOException { + print( s.toString() ); + } + + public void print( final String s ) throws IOException { + m_CDLOutput.write( s ); + m_CurrLineSize += s.length(); + } + + public void printws( final StringBuffer s ) throws IOException { + printws( s.toString() ); + } + + public void printws( final String s ) throws IOException { + if ( ( m_CurrLineSize + 1 + s.length() ) > m_MaxLineSize ) { + println(); + print( "+" ); + } + else { + m_CDLOutput.write( ' ' ); + } + m_CDLOutput.write( s ); + m_CurrLineSize += s.length() + 1; + } + + public void println( ) throws IOException { + m_CurrLineSize = 0; + m_CDLOutput.write( '\n' ); + } + + public void flush() throws IOException { + m_CDLOutput.flush(); + } + + public Writer getWriter( ) { + return m_CDLOutput; + } + + public CDLNameInterface getNameInterface() { + return m_RenameInterface; + } + + public String renameCell( final String oldCellName ) + throws CDLRenameException + { + return getNameInterface().renameCell( oldCellName ); + } + + public String renameNode( final HierName oldNodeName ) + throws CDLRenameException + { + return getNameInterface().renameNode(oldNodeName.getAsString('.')); + } + + public String renameDevice( final HierName oldDeviceName ) + throws CDLRenameException + { + return getNameInterface().renameDevice( oldDeviceName.getAsString('.') ); + } + + public String renameSubCellInstance( final HierName oldInstanceName ) + throws CDLRenameException + { + return getNameInterface().renameSubCellInstance( oldInstanceName.getAsString('.') ); + } + + public String renameTransistorModel( final String oldModelName ) + throws CDLRenameException + { + return getNameInterface().renameTransistorModel( oldModelName ); + } + + public void close() throws IOException { + m_CDLOutput.close(); + } + } + + final Collection m_OutputInfos; + Exception m_Error; + + + public CDLRenamerFactory( ) { + m_OutputInfos = new LinkedList(); + m_Error = null; + + } + + + + public void addNameInterface( final Writer cdlOutput, + final CDLNameInterface nameInterface, + final int maxLineSize ) { + final OutputInfo newInfo = new OutputInfo( cdlOutput, + nameInterface, + maxLineSize ); + m_OutputInfos.add( newInfo ); + } + + + + private void writeParameters( final Map parameters, + final Environment env, + final OutputInfo output ) throws IOException { + final StringBuffer accumulator = new StringBuffer(); + final Iterator i = parameters.entrySet().iterator(); + while ( i.hasNext() ) { + + final Map.Entry entry = ( Map.Entry ) i.next(); + final String key = ( String ) entry.getKey(); + final CDLLexer.InfoToken val = ( CDLLexer.InfoToken ) entry.getValue(); + final String valStr = val.getSpiceString( env ); + + output.printws( key + "=" + valStr ); + + } + } + + + + public void makeResistor( HierName name, + HierName n1, + HierName n2, + CDLLexer.InfoToken val, + Map parameters, + Environment env ) { + + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.print( "R" + currInfo.renameDevice( name ) ); + currInfo.printws( currInfo.renameNode( n1 ) ); + currInfo.printws( currInfo.renameNode( n2 ) ); + currInfo.printws( val.getText( env ) ); + writeParameters( parameters, env, currInfo ); + currInfo.println(); + } + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + public void makeCapacitor(HierName name, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + + currInfo.print( "C" + currInfo.renameDevice( name ) ); + currInfo.printws( currInfo.renameNode( npos ) ); + currInfo.printws( currInfo.renameNode( nneg ) ); + currInfo.printws( val.getText( env ) ); + writeParameters( parameters, env, currInfo ); + currInfo.println(); + + } + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + public void makeTransistor(HierName name, + String type, + HierName ns, + HierName nd, + HierName ng, + HierName nb, + CDLLexer.InfoToken width, + CDLLexer.InfoToken length, + Map parameters, + Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + + currInfo.print( "M" + currInfo.renameDevice( name ) ); + currInfo.printws( currInfo.renameNode( nd ) ); + currInfo.printws( currInfo.renameNode( ng ) ); + currInfo.printws( currInfo.renameNode( ns ) ); + currInfo.printws( currInfo.renameNode( nb ) ); + currInfo.printws( currInfo.renameTransistorModel( type ) ); + currInfo.printws( "w=" + width.getText( env ) ); + currInfo.printws( "l=" + length.getText( env ) ); + writeParameters( parameters, env, currInfo ); + currInfo.println(); + + } + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + public void makeDiode(HierName name, + String type, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.print( "D" + currInfo.renameDevice( name ) ); + currInfo.printws( currInfo.renameNode( npos ) ); + currInfo.printws( currInfo.renameNode( nneg ) ); + currInfo.printws( type ); + currInfo.printws( val.getText( env ) ); + writeParameters( parameters, env, currInfo ); + currInfo.println(); + } + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + public void makeInductor(HierName name, + HierName npos, + HierName nneg, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.print( "L" + currInfo.renameDevice( name ) ); + currInfo.printws( currInfo.renameNode( npos ) ); + currInfo.printws( currInfo.renameNode( nneg ) ); + currInfo.printws( val.getText( env ) ); + writeParameters( parameters, env, currInfo ); + currInfo.println(); + + } + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + public void makeBipolar(HierName name, + String type, + HierName nc, + HierName nb, + HierName ne, + CDLLexer.InfoToken val, + Map parameters, + Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.print( "Q" + currInfo.renameDevice( name ) ); + currInfo.printws( currInfo.renameNode( nc ) ); + currInfo.printws( currInfo.renameNode( nb ) ); + currInfo.printws( currInfo.renameNode( ne ) ); + currInfo.printws( type ); + currInfo.printws( "area=" + val.getText( env ) ); + writeParameters( parameters, env, currInfo ); + currInfo.println(); + } + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.print( "X" + currInfo.renameSubCellInstance( name ) ); + + for ( int i = 0 ; i < args.length ; ++i ) { + currInfo.printws( currInfo.renameNode( args[i] ) ); + } + currInfo.printws( "/" ); + currInfo.printws( currInfo.renameCell( subName ) ); + writeParameters( parameters, env, currInfo ); + currInfo.println(); + + } + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.print( ".SUBCKT " + currInfo.renameCell( subName ) ); + + for ( int i = 0; i < in.length; ++i ) { + final HierName currHierName = + HierName.makeHierName( in[i], '.' ); + currInfo.printws( currInfo.renameNode( currHierName ) ); + } + + for ( int i = 0; i < out.length; ++i ) { + final HierName currHierName = + HierName.makeHierName( out[i], '.' ); + currInfo.printws( currInfo.renameNode( currHierName ) ); + + } + writeParameters( parameters, env, currInfo ); + currInfo.println(); + } + } + catch( InvalidHierNameException e ) { + m_Error = e; + } + catch( IOException e ) { + m_Error = e; + } + catch( CDLRenameException e ) { + m_Error = e; + } + } + } + + /** + * Called by the parser after processing a subcircuit. + * @param subName Name of the subcircuit + **/ + public void endSubcircuit(String subName, Environment env) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.print( ".ENDS" ); + currInfo.println(); + currInfo.flush(); + } + } + catch( IOException e ) { + m_Error = e; + } + } + } + + public void closeOutputs( ) { + if ( m_Error == null ) { + try { + final Iterator outputInfoIter = + m_OutputInfos.iterator(); + while ( outputInfoIter.hasNext() ) { + final OutputInfo currInfo = ( OutputInfo ) outputInfoIter.next(); + + currInfo.close(); + } + } + catch( IOException e ) { + m_Error = e; + } + } + + } + + public boolean haveError() { + return m_Error != null; + } + + public Exception getError() { + return m_Error; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CachingNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CachingNameInterface.java new file mode 100644 index 0000000000..96b8c31098 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CachingNameInterface.java @@ -0,0 +1,159 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import java.util.Map; +import java.util.HashMap; +import java.util.Set; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; + +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class CachingNameInterface implements CDLNameInterface { + + private final Map m_CellNameMap; + private final Map m_NodeNameMap; + private final Map m_DeviceNameMap; + private final Map m_SubCellInstanceNameMap; + private final Map m_TransistorModelNameMap; + + final CDLNameInterface m_RenameInterface; + + public CachingNameInterface( final CDLNameInterface renameInterface ) { + m_RenameInterface = renameInterface; + + m_CellNameMap = new HashMap(); + m_NodeNameMap = new HashMap(); + m_DeviceNameMap = new HashMap(); + m_SubCellInstanceNameMap = new HashMap(); + m_TransistorModelNameMap = new HashMap(); + } + + protected Set getCellNameMappings( ) { + return m_CellNameMap.entrySet(); + } + + protected Set getNodeNameMappings( ) { + return m_NodeNameMap.entrySet(); + } + + protected Set getDeviceNameMappings() { + return m_DeviceNameMap.entrySet(); + } + + protected Set getSubCellInstanceNameMappings() { + return m_SubCellInstanceNameMap.entrySet(); + } + + protected Set getTransistorModelNameMappings() { + return m_TransistorModelNameMap.entrySet(); + } + + protected void addCellNameMapping( final String oldCellName, + final String newCellName ) { + m_CellNameMap.put( oldCellName, newCellName ); + } + + protected void addNodeNameMapping( final String oldNodeName, + final String newNodeName ) { + m_NodeNameMap.put( oldNodeName, newNodeName ); + } + + protected void addDeviceNameMapping( final String oldDeviceName, + final String newDeviceName ) { + m_DeviceNameMap.put( oldDeviceName, newDeviceName ); + } + + protected void addSubCellInstanceNameMapping( final String oldInstanceName, + final String newInstanceName ) { + m_SubCellInstanceNameMap.put( oldInstanceName, newInstanceName ); + } + + protected void addTransistorModelNameMapping( final String oldModelName, + final String newModelName ) { + m_TransistorModelNameMap.put( oldModelName, newModelName ); + } + + public String renameCell( final String oldCellName ) + throws CDLRenameException + { + final String cachedName = ( String ) m_CellNameMap.get( oldCellName ); + final String ret; + if ( cachedName == null ) { + ret = m_RenameInterface.renameCell( oldCellName ); + addCellNameMapping( oldCellName, ret ); + } + else { + ret = cachedName; + } + return ret; + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + final String cachedName = ( String ) m_NodeNameMap.get( oldNodeName ); + final String ret; + if ( cachedName == null ) { + ret = m_RenameInterface.renameNode( oldNodeName ); + addNodeNameMapping( oldNodeName, ret ); + } + else { + ret = cachedName; + } + return ret; + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + final String cachedName = ( String ) m_DeviceNameMap.get( oldDeviceName ); + final String ret; + if ( cachedName == null ) { + ret = m_RenameInterface.renameDevice( oldDeviceName ); + addDeviceNameMapping( oldDeviceName, ret ); + } + else { + ret = cachedName; + } + return ret; + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + final String cachedName = + ( String ) m_SubCellInstanceNameMap.get( oldInstanceName ); + final String ret; + if ( cachedName == null ) { + ret = m_RenameInterface.renameSubCellInstance( oldInstanceName ); + addSubCellInstanceNameMapping( oldInstanceName, ret ); + } + else { + ret = cachedName; + } + return ret; + } + + public String renameTransistorModel( final String oldModelName ) throws CDLRenameException { + final String cachedName = + ( String ) m_TransistorModelNameMap.get( oldModelName ); + final String ret; + if ( cachedName == null ) { + ret = m_RenameInterface.renameTransistorModel( oldModelName ); + addTransistorModelNameMapping( oldModelName, ret ); + } + else { + ret = cachedName; + } + return ret; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNameInterface.java new file mode 100644 index 0000000000..db7846e970 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNameInterface.java @@ -0,0 +1,248 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; +import java.util.HashSet; +import java.util.Set; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + + +public class CadenceNameInterface implements CDLNameInterface { + private final Set transformTransistorModel; + //If true '$' will be translated to '-D', otherwise throw + //when we are asked to translate a name containing a '$'. + private final boolean mTranslateDollar; + + public CadenceNameInterface() { + mTranslateDollar=false; + transformTransistorModel = new HashSet(); + transformTransistorModel.add("p"); + transformTransistorModel.add("P"); + transformTransistorModel.add("n"); + transformTransistorModel.add("N"); + } + + public CadenceNameInterface( final boolean translateDollar ) { + mTranslateDollar = translateDollar; + transformTransistorModel = new HashSet(); + transformTransistorModel.add("p"); + transformTransistorModel.add("P"); + transformTransistorModel.add("n"); + transformTransistorModel.add("N"); + } + + public CadenceNameInterface(final Set transformTransistorModel) { + this.transformTransistorModel = transformTransistorModel; + mTranslateDollar=false; + } + + public CadenceNameInterface(final Set transformTransistorModel, + final boolean translateDollar ) { + mTranslateDollar = translateDollar; + this.transformTransistorModel = transformTransistorModel; + } + + public String renameCell(String name ) + throws CDLRenameException + { + boolean badName = false; + final StringBuffer sb = new StringBuffer(); + boolean inParens = false; + int curlyCount = 0; + + final int nameLength = name.length(); + + int i = 0; + while ( ( i < nameLength ) && + ( ! badName ) ) { + final char c = name.charAt(i); + + switch (c) { + case '.': + badName = inParens; + sb.append('.'); + break; + case ',': + badName = !inParens; + sb.append("_"); + break; + case '(': + inParens = true; + sb.append("-L"); + break; + case ')': + badName = !inParens; + inParens = false; + sb.append("-R"); + break; + case '{': + badName = !inParens; + ++curlyCount; + sb.append("-L"); + break; + case '}': + badName = ! ( inParens && ( curlyCount > 0 ) ); + --curlyCount; + sb.append("-R"); + break; + case '-': + sb.append('-'); + badName = ( ( ! inParens ) || + ( i >= ( nameLength - 1 ) ) || + ( ! ( Character.isDigit( name.charAt( i + 1 ) ) ) ) ); + break; + case '_': + sb.append('_'); + break; + default: + if (Character.isLetterOrDigit(c)) { + sb.append(c); + } + else { + if ( ( mTranslateDollar ) && ( c =='$' ) ) { + sb.append("-D"); + } + else { + final String errorMessage = + "Unable to translate '" + + Character.toString(c) + + "' (0x" + + Integer.toString( ( int ) c, 16 ) + + ")"; + throw new CDLRenameException( errorMessage ); + } + } + } + ++i; + } + badName = badName || inParens || ( curlyCount != 0 ) ; + if ( badName ) { + final String errorMessage = + "\"" + name + "\" is an invalid cell name."; + throw new CDLRenameException( errorMessage ); + } + return sb.toString(); + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + return translate( oldNodeName ); + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + return translate( oldDeviceName ); + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + return translate( oldInstanceName ); + } + + public String renameTransistorModel( final String oldTransistorModel ) + { + return oldTransistorModel; + } + + private String translate( final String s ) + throws CDLRenameException + { + + + boolean badName = false; + final StringBuffer sb = new StringBuffer(); + boolean inParens = false; + boolean inBrackets = false; + + final int stringLength = s.length(); + + int i = 0; + while ( ( i < stringLength ) && + ( ! badName ) ) { + final char c = s.charAt(i); + + switch (c) { + case '!': + sb.append('!'); + break; + case '.': + sb.append('.'); + break; + case ',': + badName = ( ! inBrackets ) || inParens ; + sb.append("]["); + break; + case '[': + badName = inBrackets | inParens ; + inBrackets = true; + sb.append('['); + break; + case ']': + badName = ( ! inBrackets ) || inParens ; + inBrackets = false; + sb.append(']'); + break; + /* case '(': + badName = inBrackets || inParens ; + inParens = true; + sb.append('('); + break; + case ')': + badName = inBrackets || ( ! inParens ) ; + inParens = false; + sb.append(')'); + break; */ + case '-': + badName = ! ( inBrackets || inParens ); + sb.append('-'); + break; + case '_': + sb.append('_'); + break; + case '#': + badName = inBrackets || inParens ; + sb.append("-H"); + break; + case '+': + sb.append( '+' ); + break; + default: + if (Character.isLetterOrDigit(c)) { + sb.append(c); + } + else { + if ( ( mTranslateDollar ) && ( c =='$' ) ) { + sb.append("-D"); + } + else { + final String errorMessage = + "Unable to translate '" + + Character.toString(c) + + "' (0x" + + Integer.toString( ( int ) c, 16 ) + + ")"; + throw new CDLRenameException( errorMessage ); + } + } + } + ++i; + } + badName = badName || inParens || inBrackets ; + if ( badName ) { + final String errorMessage = + "\"" + s + "\" is an invalid instance or net name."; + throw new CDLRenameException( errorMessage ); + } + return sb.toString(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNames2CastNames.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNames2CastNames.py new file mode 100644 index 0000000000..1df857b2d4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceNames2CastNames.py @@ -0,0 +1,117 @@ +import string + +from com.avlsi.file.cdl.util.rename.CDLNameInterface import * + +class CadenceNames2CastNames( CDLNameInterface ): + "Converts cadence names to cast names." + + def __init__(self): + self.curlyCount = 0 + + def left(self): + if ( self.curlyCount == 0 ): + result = u'(' + else: + result = u'{' + self.curlyCount = self.curlyCount + 1 + return result + + def right(self): + if (self.curlyCount <= 0): + raise CDLRenameException, "Unmatched parenthesis!" + elif (self.curlyCount == 1): + result = u')' + else: + result = u'}' + self.curlyCount = self.curlyCount - 1 + return result + + def renameCell(self, name): + badName = 0 + sb = "" + self.curlyCount = 0 + + nameLength = len( name ) + + i = 0 + while ( ( i < nameLength ) and + ( not badName ) ): + c = name[i] + if ( c == u'.' ): + badName = self.curlyCount != 0 + sb = sb + u'.' + elif ( c == u'-' ): + if (i + 1 < nameLength): + d = name[i+1] + if (d == u'L'): + i = i + 1 + sb = sb + self.left() + elif (d == u'R'): + i = i + 1 + sb = sb + self.right() + else: + sb = sb + u'-' + else: + sb = sb + '-' + elif ( c == u'_' ): + if (self.curlyCount > 0): + sb = sb + u',' + else: + sb = sb + u'_' + else: + if ( string.find( string.digits + string.ascii_letters, c ) != -1 ): + sb = sb + c + else: + errorMessage = "Unable to translate: " + c + raise CDLRenameException, errorMessage + i = i + 1 + + if ( badName or self.curlyCount != 0 ): + errorMessage = "\"" + name + "\" is an invalid cell name." + raise CDLRenameException, errorMessage + return sb + + def renameNode(self, name): + return self.translate(name) + + def renameDevice(self, name): + return self.translate(name) + + def renameSubCellInstance(self, name): + return self.translate(name) + + def renameTransistorModel(self, name): + if ( name[0] in ( "n", "N" ) ): + return u"n" + else: + return u"p" + + def translate(self, s): + sb = "" + nameLength = len(s) + i = 0 + while ( i < nameLength ): + c = s[i] + if ( c in ( u'!' u'.' u'[' u'(' u')' u'_' ) ): + sb = sb + c + elif ( c == u']' ): + if (i + 1 < len(s) and s[i+1] == u'['): + sb = sb + u',' + i = i + 1 + else: + sb = sb + u']' + elif ( c == u'-' ): + if (i + 1 < nameLength and s[i+1] == u'H'): + sb = sb + u'#' + i = i + 1 + else: + sb = sb + u'-' + else: + if ( string.find( string.digits + string.ascii_letters, c ) != -1 ): + sb = sb + c + else: + errorMessage = "Unable to translate: " + c + raise CDLRenameException, errorMessage + i = i + 1 + return sb + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceReverseNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceReverseNameInterface.java new file mode 100644 index 0000000000..5b835bccc7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CadenceReverseNameInterface.java @@ -0,0 +1,200 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +/** + * Implements the reverse of CadenceNameInterface. However, due to the way + * CadenceNameInterface is defined, it is impossible to completely reverse the + * translation. However, restrictions on CAST will not allow (hopefully) those + * inconsistencies to be triggered. + **/ +public class CadenceReverseNameInterface implements CDLNameInterface { + + int curlyCount = 0; + + public CadenceReverseNameInterface() { + } + + private char left() { + char result; + if (curlyCount == 0) { + result = '('; + } else { + result = '{'; + } + ++curlyCount; + return result; + } + + private char right() throws CDLRenameException { + char result; + if (curlyCount <= 0) { + throw new CDLRenameException( "Unmatched parenthesis!" ); + } else if (curlyCount == 1) { + result = ')'; + } else { + result = '}'; + } + --curlyCount; + return result; + } + + public String renameCell(String name ) + throws CDLRenameException + { + boolean badName = false; + final StringBuffer sb = new StringBuffer(); + curlyCount = 0; + + final int nameLength = name.length(); + + int i = 0; + while ( ( i < nameLength ) && + ( ! badName ) ) { + final char c = name.charAt(i); + + switch (c) { + case '$': + sb.append('$'); + break; + case '.': + badName = curlyCount != 0; + sb.append('.'); + break; + case '-': + if (i + 1 < nameLength) { + char d = name.charAt(i + 1); + if (d == 'L') { + ++i; + sb.append(left()); + } else if (d == 'R') { + ++i; + sb.append(right()); + } else { + sb.append('-'); + } + } else { + sb.append('-'); + } + break; + case '_': + if (curlyCount > 0) { + sb.append(','); + } else { + sb.append('_'); + } + break; + default: + if (Character.isLetterOrDigit(c)) { + sb.append(c); + } + else { + final String errorMessage = + "Unable to translate '" + + Character.toString(c) + + "' (0x" + + Integer.toString( ( int ) c, 16 ) + + ")"; + throw new CDLRenameException( errorMessage ); + } + } + ++i; + } + if ( badName || curlyCount != 0 ) { + final String errorMessage = + "\"" + name + "\" is an invalid cell name."; + throw new CDLRenameException( errorMessage ); + } + return sb.toString(); + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + return translate( oldNodeName ); + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + return translate( oldDeviceName ); + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + return translate( oldInstanceName ); + } + + public String renameTransistorModel( final String oldTransistorModel ) + { + return oldTransistorModel; + } + + private String translate( final String s ) + throws CDLRenameException + { + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + switch (c) { + case '!': + sb.append('!'); + break; + case '.': + sb.append('.'); + break; + case '[': + sb.append('['); + break; + case ']': + if (i + 1 < s.length() && s.charAt(i + 1) == '[') { + sb.append(','); + i++; + } else { + sb.append(']'); + } + break; + case '(': + sb.append('('); + break; + case ')': + sb.append(')'); + break; + case '-': + if (i + 1 < s.length() && s.charAt(i + 1) == 'H') { + sb.append('#'); + i++; + } else { + sb.append('-'); + } + break; + case '_': + sb.append('_'); + break; + default: + if (Character.isLetterOrDigit(c)) { + sb.append(c); + } + else { + final String errorMessage = + "Unable to translate '" + + Character.toString(c) + + "' (0x" + + Integer.toString( ( int ) c, 16 ) + + ")"; + throw new CDLRenameException( errorMessage ); + } + } + } + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2CadenceNames.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2CadenceNames.py new file mode 100644 index 0000000000..c3dbfecd8b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2CadenceNames.py @@ -0,0 +1,116 @@ +# $Id$ +# $DateTime$ +# $Author$ + +import string +from com.avlsi.file.cdl.util.rename.CDLNameInterface import * + +class CastNames2CadenceNames( CDLNameInterface ): + "Converts cast names to cadence names." + + def renameCell( self, name ): + badName = 0 + inParens = 0 + curlyCount = 0 + + result=u"" + + nameLength = len( name ) + i = 0 + while ( ( i < nameLength ) & + ( not badName ) ): + char = name[i] + if ( char == u"." ): + badName = inParens + result = result + u"." + elif ( char == u"," ): + badName = not inParens + result = result + u"_" + elif ( char == u"(" ): + badName = inParens + inParens = 1 + result = result + u"-L" + elif ( char == u")" ): + badName = not inParens + inParens = 0 + result = result + u"-R" + elif ( char == u"{" ): + badName = not inParens + curlyCount = curlyCount + 1 + result = result + u"-L" + elif ( char == u"}" ): + badName = not ( inParens & ( curlyCount > 0 ) ) + curlyCount = curlyCount - 1 + result = result + u"-R" + elif ( char == u"-" ): + badName = ( ( not inParens ) | + ( i >= ( nameLength - 1 ) ) | + ( string.find(string.digits, name[ i + 1 ] ) == -1 ) ) + result = result + u"-" + elif ( char == u"_" ): + result = result + u"_" + elif ( string.find( string.digits + string.ascii_letters, char ) != -1 ): + result = result + char + else: + raise ValueError, "'%s' in \"%s\" can not be translated" % ( char, name ) + i = i + 1 + if ( badName ): + raise ValueError, "\"%s\" can not be translated into a cadence name." % name + return result + + def renameNode( self, name ): + return self.translate( name ) + + def renameDevice( self, name ): + return self.translate( name ) + + def renameSubCellInstance( self, name ): + return self.translate( name ) + + def renameTransistorModel( self, oldModelName ): + return oldModelName + + def translate( self, name ): + badName = 0 + inParens = 0 + inBrackets = 0 + + nameLength = len( name ) + i = 0 + + result = u"" + + while ( ( i < nameLength ) & + ( not badName ) ): + char = name[i] + if ( char == u"!" ): + result = result + u"!" + elif ( char == u"." ): + result = result + u"." + elif ( char == u"," ): + badName = ( not inBrackets ) | inParens + result = result + u"]["; + elif ( char == u"[" ): + badName = inBrackets | inParens; + inBrackets = 1 + result = result + u"[" + elif ( char == u"]" ): + badName = ( not inBrackets ) | inParens + inBrackets = 0 + result = result + u"]" + elif ( char == u"-" ): + badName = not ( inBrackets | inParens ) + result = result + u"-" + elif ( char == u"_" ): + result = result + u"_" + elif ( char == u"#" ): + badName = inBrackets | inParens + result = result + u"#" + elif ( string.find(string.digits + string.ascii_letters, char ) != -1 ): + result = result + char + else: + raise ValueError, "'%s' in \"%s\" can not be translated" % ( char, name ) + i = i + 1 + if ( badName ): + raise ValueError, "\"%s\" can not be translated into a cadence name." % name + return result diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2GDSIINames.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2GDSIINames.py new file mode 100644 index 0000000000..8ecef1bb80 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CastNames2GDSIINames.py @@ -0,0 +1,50 @@ +# $Id$ +# $DateTime$ +# $Author$ + +import string +from com.avlsi.file.cdl.util.rename.CDLNameInterface import * + +class CastNames2GDSIINames( CDLNameInterface ): + "Converts cast names to gds II names." + def translate( self, name ): + result = u"" + for char in name: + if ( char == u"." ): + result = result + u"_D_" + elif ( char == u"," ): + result = result + u"_C_" + elif ( char == u"[" ): + result = result + u"_l_" + elif ( char == u"]" ): + result = result + u"_r_" + elif ( char == u"(" ): + result = result + u"_L_" + elif ( char == u")" ): + result = result + u"_R_" + elif ( char == u"-" ): + result = result + u"_M_" + elif ( char == u"_" ): + result = result + u"_U_" + elif ( char == u"#" ): + result = result + u"_H_" + elif ( string.find(string.digits + string.ascii_letters, char ) != -1 ): + result = result + char; + else: + hexstring = u"%00x" % ord( char ); + if ( len( hexstring ) == 2 ): + result = result + u"_" + hexstring + u"_" + else: + raise ValueError, "The code point of %s is greater than 255." % char + return result + + def renameCell( self, name ): + return self.translate( name ) + def renameNode( self, name ): + return self.translate( name ) + def renameDevice( self, name ): + return self.translate( name ) + def renameSubCellInstance( self, name ): + return self.translate( name ) + def renameTransistorModel( self, oldModelName ): + return oldModelName diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterface.java new file mode 100644 index 0000000000..b5c2f70962 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterface.java @@ -0,0 +1,47 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class CompositeCDLNameInterface implements CDLNameInterface { + + final protected CDLNameInterface f,g; + + public CompositeCDLNameInterface(final CDLNameInterface f, final CDLNameInterface g) { + this.f = f; + this.g = g; + } + + public String renameCell( final String oldCellName ) + throws CDLRenameException { + return g.renameCell( f.renameCell(oldCellName) ); + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException { + return g.renameNode( f.renameNode(oldNodeName) ); + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException { + return g.renameDevice( f.renameDevice(oldDeviceName) ); + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException { + return g.renameSubCellInstance( f.renameSubCellInstance(oldInstanceName) ); + } + + public String renameTransistorModel( final String oldTransistorModel ) + throws CDLRenameException { + return g.renameTransistorModel( f.renameTransistorModel(oldTransistorModel) ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterfaceFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterfaceFactory.java new file mode 100644 index 0000000000..9228c068e0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeCDLNameInterfaceFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.file.cdl.util.rename; + + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.file.cdl.util.rename.CompositeCDLNameInterface; + +public class CompositeCDLNameInterfaceFactory implements CDLNameInterfaceFactory { + + private final CDLNameInterfaceFactory mF; + private final CDLNameInterfaceFactory mG; + + public CompositeCDLNameInterfaceFactory( final CDLNameInterfaceFactory f, + final CDLNameInterfaceFactory g ) { + mF = f; + mG = g; + } + + public CDLNameInterface getNameInterface( final String cellName ) throws CDLRenameException { + final CDLNameInterface niF = mF.getNameInterface( cellName ); + final CDLNameInterface niG = mG.getNameInterface( cellName ); + + return new CompositeCDLNameInterface( niF, niG ); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeNames.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeNames.py new file mode 100644 index 0000000000..478e3ce0a7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/CompositeNames.py @@ -0,0 +1,22 @@ +from com.avlsi.file.cdl.util.rename.CDLNameInterface import * + +class CompositeNames( CDLNameInterface ): + + def __init__(self,a,b): + self.names1 = a + self.names2 = b + + def renameCell(self, name): + return self.names2.renameCell( self.names1.renameCell(name) ) + + def renameNode(self, name): + return self.names2.renameNode( self.names1.renameNode(name) ) + + def renameDevice(self, name): + return self.names2.renameDevice( self.names1.renameDevice(name) ) + + def renameSubCellInstance(self, name): + return self.names2.renameSubCellInstance( self.names1.renameSubCellInstance(name) ) + + def renameTransistorModel(self, name): + return self.names2.renameTransistorModel( self.names1.renameTransistorModel(name) ) diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2NameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2NameInterface.java new file mode 100644 index 0000000000..8550006a32 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2NameInterface.java @@ -0,0 +1,114 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class GDS2NameInterface implements CDLNameInterface { + + public GDS2NameInterface() { + } + + public String renameCell(String name ) + throws CDLRenameException + { + return translate( name ); + + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + return translate( oldNodeName ); + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + return translate( oldDeviceName ); + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + return translate( oldInstanceName ); + } + + public String renameTransistorModel( final String oldTransistorModel ) + { + return oldTransistorModel; + } + + private String translate( final String s ) + throws CDLRenameException + { + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + switch (c) { + case '.': + sb.append("_D_"); + break; + case ',': + sb.append("_C_"); + break; + case '[': + sb.append("_l_"); + break; + case ']': + sb.append("_r_"); + break; + case '(': + sb.append("_L_"); + break; + case ')': + sb.append("_R_"); + break; + case '-': + sb.append("_M_"); + break; + case '_': + sb.append("_U_"); + break; + case '#': + sb.append("_H_"); + break; + default: + if (Character.isLetterOrDigit(c)) { + sb.append(c); + } + else { + sb.append("_"); + final String intStr = Integer.toHexString( c ); + switch ( intStr.length() ) { + case 1: + sb.append( "0" ); + break; + case 2: + break; + default: + final String errorMessage = + "Unable to translate '" + + Character.toString( c ) + + "' (0x" + + intStr + + ")"; + throw new CDLRenameException( errorMessage ); + } + sb.append( intStr ); + sb.append("_"); + } + } + } + return sb.toString(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2ReverseNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2ReverseNameInterface.java new file mode 100644 index 0000000000..488d15ee23 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDS2ReverseNameInterface.java @@ -0,0 +1,137 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +/** + * Implements the reverse of GDS2NameInterface. However, due to the way + * GDS2NameInterface is defined, it is impossible to completely reverse the + * translation. However, restrictions on CAST will not allow (hopefully) those + * inconsistencies to be triggered. + **/ +public class GDS2ReverseNameInterface implements CDLNameInterface { + + //If on, then foo_1 -> foo_1 instead of failing + //and _XXX_ -> _XXX_ if it fails other translations + private final boolean bLenient; + + public GDS2ReverseNameInterface() { + this(true); + } + + public GDS2ReverseNameInterface(final boolean bLenient) { + this.bLenient = bLenient; + } + + public String renameCell(String name ) + throws CDLRenameException + { + return translate( name ); + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + return translate( oldNodeName ); + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + return translate( oldDeviceName ); + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + return translate( oldInstanceName ); + } + + public String renameTransistorModel( final String oldTransistorModel ) + { + return oldTransistorModel; + } + + private char translateEscaped( final String str ) + throws CDLRenameException, NumberFormatException { + switch ( str.length() ) { + case 1: + final char c = str.charAt(0); + switch( c ) { + case 'D': + return '.'; + case 'C': + return ','; + case 'l': + return '['; + case 'r': + return ']'; + case 'L': + return '('; + case 'R': + return ')'; + case 'M': + return '-'; + case 'U': + return '_'; + case 'H': + return '#'; + default: + throw new CDLRenameException( "_" + c + "_ is and invalid escape construct" ); + } + default: + int charValue = Integer.parseInt( str, 16 ); + return (char) charValue; + } + } + + + private String translate( final String s ) + throws CDLRenameException + { + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + if(c == '_' ) { + final StringBuffer usb = new StringBuffer(); + boolean closed = false; + while( ++i < s.length()) { + final char uc; + uc = s.charAt(i); + if( uc == '_' ) { + closed = true; + break; + } + usb.append(uc); + } + if(closed || !bLenient ) { + final String untranslated = new String(usb); + try { + final char translated = translateEscaped( untranslated ); + sb.append( translated ); + } + catch(CDLRenameException e ) { + if(!bLenient) { throw e; } else { sb.append( "_" + untranslated ); i--; }; + } + catch(NumberFormatException e ) { + if(!bLenient) { throw e; } else { sb.append( "_" + untranslated ); i--; }; + } + } + else { + sb.append('_'); + sb.append(usb); + } + } + else + sb.append(c); + } + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDSIINames2CastNames.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDSIINames2CastNames.py new file mode 100644 index 0000000000..0d58cef11d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/GDSIINames2CastNames.py @@ -0,0 +1,80 @@ +import string + +from com.avlsi.file.cdl.util.rename.CDLNameInterface import * + +class GDSIINames2CastNames( CDLNameInterface ): + "Converts gds2 names to cast names." + + def renameCell(self, name): + return self.translate(name) + + def renameNode(self, name): + return self.translate(name) + + def renameDevice(self, name): + return self.translate(name) + + def renameSubCellInstance(self, name): + return self.translate(name) + + def renameTransistorModel(self, name): + if ( name[0] in ( "n", "N" ) ): + return "n" + else: + return "p" + + def translate(self, s): + sb = "" + nameLength = len(s) + i = 0 + while ( i < nameLength ): + c = s[i] + if ( c == u'_' ): + usb = "" + while ( i + 1 < nameLength ): + i = i + 1 + uc = s[i]; + if ( uc == u'_' ): + break + usb = usb + uc + sb = sb + self.translateEscaped(usb) + else: + sb = sb + c + i = i + 1 + return sb + + def translateEscaped(self, str): + if(len(str) == 1 ): + c = str[0] + if ( c == u'D' ): + return u'.' + elif ( c == u'C' ): + return u',' + elif ( c == u'l' ): + return u'[' + elif ( c == u'r' ): + return u']' + elif ( c == u'L' ): + return u'(' + elif ( c == u'R' ): + return u')' + elif ( c == u'M' ): + return u'-' + elif ( c == u'U' ): + return u'_' + elif ( c == u'H' ): + return u'#' + else: + errorMessage = "_" + str + "_ is and invalid escape construct" + raise CDLRenameException, errorMessage + elif(len(str) == 0 ): + errorMessage = "_" + str + "_ is and invalid escape construct" + raise CDLRenameException, errorMessage + else: + charVal = int(str, 16) + if (charVal < 256 ): + return chr(charVal) + else: + errorMessage = "_" + str + "_ is and invalid escape construct" + raise CDLRenameException, errorMessage + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNameInterface.java new file mode 100644 index 0000000000..c6a786f208 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNameInterface.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class IdentityNameInterface implements CDLNameInterface { + + public String renameCell( final String oldCellName ) + throws CDLRenameException { + return oldCellName ; + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException { + return oldNodeName ; + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException { + return oldDeviceName ; + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException { + return oldInstanceName ; + } + + public String renameTransistorModel( final String oldTransistorModel ) + throws CDLRenameException { + return oldTransistorModel ; + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNames.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNames.py new file mode 100644 index 0000000000..b470bfc9dd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/IdentityNames.py @@ -0,0 +1,17 @@ +from com.avlsi.file.cdl.util.rename.CDLNameInterface import * + +class IdentityNames( CDLNameInterface ): + def renameCell(self, name): + return name + + def renameNode(self, name): + return name + + def renameDevice(self, name): + return name + + def renameSubCellInstance(self, name): + return name + + def renameTransistorModel(self, name): + return name diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/PMCHackNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/PMCHackNameInterface.java new file mode 100644 index 0000000000..906e05661d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/PMCHackNameInterface.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; + +/** + * A name interface to hack around an LVS issue with biased GDS2 at PMC. This + * appends a constant string at the end of a cell name, which makes them look + * different than the cell names in GDS2, thus forcing LVS to flatten the + * entire hierarchy. + **/ +public class PMCHackNameInterface { + private static Impl forward, reverse; + + public static class Impl extends IdentityNameInterface { + private static final String SUFFIX = "_PMC_"; + // direction of the mapping + private boolean forward; + public Impl(final boolean forward) { + this.forward = forward; + } + + public String renameCell(final String oldCellName) + throws CDLRenameException { + if (forward) { + return oldCellName + SUFFIX; + } else { + if (oldCellName.endsWith(SUFFIX)) { + final int l = oldCellName.length(); + return oldCellName.substring(0, l - SUFFIX.length()); + } else { + throw new CDLRenameException("Cell name: " + oldCellName + + " does not end in " + SUFFIX); + } + } + } + } + + /** + * This class cannot be constructed. Use {@link getForwardNamer} and + * {@link getReverseNamer} to get an instance that does the forward and + * reverse mapping respectively. + **/ + private PMCHackNameInterface() { } + + public static CDLNameInterface getForwardNamer() { + if (forward == null) forward = new Impl(true); + return forward; + } + + public static CDLNameInterface getReverseNamer() { + if (reverse == null) reverse = new Impl(false); + return reverse; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/RCXHackNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/RCXHackNameInterface.java new file mode 100644 index 0000000000..0899f95c56 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/RCXHackNameInterface.java @@ -0,0 +1,206 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + +import java.io.IOException; +import java.io.BufferedReader; +import java.io.Reader; +import java.io.Writer; +import java.util.HashMap; +import java.util.Map; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; +import com.avlsi.csp.util.UniqueLabel; + +/** + * The same as CadenceNameInterface, except cell names are + * translated to unique names less than 40 characters long to work around an + * RCX issue that occurs for cell names longer than 80 characters. Optionally + * generates a cell mapping file appropriate for passing to pipo. + * The reverse naming is not implemented, but instead depends on + * ReloadableNameInterface to load back a previous encoding. + **/ +public class RCXHackNameInterface { + public static class Primitive extends CadenceNameInterface { + private static Pattern METAPARAM = Pattern.compile("(.*)\\(.*\\).*"); + + /** + * The maximum number of characters before a numeric sequence number is + * added. Thus this should probably be conservative. + **/ + private final int lengthLimit; + + private final UniqueLabel labels; + + /** + * A mapping of cell names from the CAST name space to this name + * space. + **/ + protected final Map/**/ cellNameMap; + + public Primitive(final int lengthLimit) { + this.lengthLimit = lengthLimit; + this.labels = new UniqueLabel(new HashMap()); + this.cellNameMap = new HashMap(); + } + public String renameCell(final String castName) { + // if a name has been translated already, use the previous + // translation + String result = (String) cellNameMap.get(castName); + if (result == null) result = castName; + else return result; + + // if the name exceeds the length limit, remove any metaparameters + if (result.length() > lengthLimit) { + final Matcher m = METAPARAM.matcher(result); + if (m.matches()) { + result = m.group(1); + } + } + + // if the name exceeds the length limit without metaparameters + // divide the name into . delimited components and use as many + // components as possible starting from the right end + if (result.length() > lengthLimit) { + final int len = result.length(); + int last = len; + int dot; + while (last > 0 && + (dot = result.lastIndexOf('.', last - 1)) != -1) { + if (len - dot - 1 > lengthLimit && + len - last - 1 < lengthLimit) { + break; + } + last = dot; + } + if (last != len) { + result = result.substring(last + 1); + } + } + + // truncate to the length limit if name is still too long + if (result.length() > lengthLimit) { + result = result.substring(0, lengthLimit); + } + + // replace non-alphanumeric characters with _ + final StringBuffer buf = new StringBuffer(result); + for (int i = 0; i < buf.length(); ++i) { + if (!Character.isLetterOrDigit(buf.charAt(i))) + buf.setCharAt(i, '_'); + } + result = buf.toString(); + + // add a numeric suffix + result = result + "_" + labels.getLabel(castName); + cellNameMap.put(castName, result); + + return result; + } + } + + public static class Forward extends Primitive + implements CDLRenamer.EndObserver { + private final Writer castMappingWriter, cadenceMappingWriter; + public Forward(final int lengthLimit, final Writer castMappingWriter, + final Writer cadenceMappingWriter) { + super(lengthLimit); + this.castMappingWriter = castMappingWriter; + this.cadenceMappingWriter = cadenceMappingWriter; + } + public void renameEnd() throws CDLRenameException { + final CadenceNameInterface cadenceRenamer = + new CadenceNameInterface(); + try { + for (Iterator i = cellNameMap.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + + final String key = (String) entry.getKey(); + assert !key.matches("\\s") : "White space in " + key; + + final String val = (String) entry.getValue(); + assert !val.matches("\\s") : "White space in " + val; + + castMappingWriter.write(key + " " + val + "\n"); + final String cadenceKey = cadenceRenamer.renameCell(key); + cadenceMappingWriter.write(cadenceKey + " " + val + "\n"); + } + castMappingWriter.flush(); + cadenceMappingWriter.flush(); + } catch (IOException e) { + throw new CDLRenameException(e); + } + } + } + + public static class Reverse extends CadenceReverseNameInterface + implements CDLRenamer.StartObserver { + private final Reader cellMapReader; + private final Map cellNameMap; + private final static Pattern MAP_PATTERN = + Pattern.compile("^\\s*(\\S+)\\s*(\\S+)\\s*$"); + public Reverse(final Reader cellMapReader) { + this.cellMapReader = cellMapReader; + this.cellNameMap = new HashMap(); + } + public void renameStart() throws CDLRenameException { + try { + final BufferedReader br = new BufferedReader(cellMapReader); + String line; + while ((line = br.readLine()) != null) { + final Matcher m = MAP_PATTERN.matcher(line); + if (m.matches()) { + final String castName = m.group(1); + final String rcxName = m.group(2); + assert !cellNameMap.containsKey(rcxName) : + "Cell map not one-to-one"; + cellNameMap.put(rcxName, castName); + } else { + throw new CDLRenameException("Invalid cell name " + + "mapping: " + line); + } + } + } catch (IOException e) { + throw new CDLRenameException(e); + } + } + public String renameCell(final String rcxName) + throws CDLRenameException { + final String result = (String) cellNameMap.get(rcxName); + if (result == null) { + throw new CDLRenameException(rcxName + " not defined in the " + + "cell mapping file"); + } else { + return result; + } + } + } + + /** + * This class cannot be constructed. Use {@link getForwardNamer} and + * {@link getReverseNamer} to get an instance that does the forward and + * reverse mapping respectively. + **/ + private RCXHackNameInterface() { } + + public static CDLNameInterface getForwardNamer(final int lengthLimit, + final Writer castMappingWriter, final Writer cadenceMappingWriter) { + return new Forward(lengthLimit, castMappingWriter, + cadenceMappingWriter); + } + + public static CDLNameInterface getReverseNamer(final Reader cellMapReader) { + return new Reverse(cellMapReader); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/ReloadableNameInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/ReloadableNameInterface.java new file mode 100644 index 0000000000..8d19504aa8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/ReloadableNameInterface.java @@ -0,0 +1,185 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.util.rename; + + +import java.util.Set; +import java.util.Iterator; +import java.util.Map; + +import java.io.Writer; +import java.io.Reader; +import java.io.LineNumberReader; +import java.io.IOException; + +import com.avlsi.util.text.StringUtil; + +import com.avlsi.file.cdl.util.rename.CachingNameInterface; + +public class ReloadableNameInterface extends CachingNameInterface { + + public class FileFormatException extends Exception { + FileFormatException( final String errorStr ) { + super( errorStr ); + } + } + + public ReloadableNameInterface( final CDLNameInterface renameInterface ) { + super( renameInterface ); + } + + private void throwFileFormatException( final String line, + final LineNumberReader r ) + throws FileFormatException + { + final String errorStr = + "Invalid mapping \"" + + line + + "\" on line " + + Integer.toString( r.getLineNumber() ) + + "."; + throw new FileFormatException( errorStr ); + } + + public void load( Reader r ) + throws IOException, FileFormatException + { + final LineNumberReader myReader = new LineNumberReader( r ); + + String currLine; + + do { + currLine = myReader.readLine(); + + if ( currLine != null ) { + + final String[] lineComponents = StringUtil.tokenize( currLine ); + + if ( lineComponents.length > 0 ) { + if ( lineComponents[0].charAt( 0 ) != '#' ) { + if ( lineComponents.length == 3 ) { + final String mappingType = + lineComponents[0]; + final String fromName = lineComponents[1]; + final String toName = lineComponents[2]; + + if ( mappingType.equals( "cell" ) ) { + addCellNameMapping( fromName, + toName ); + } + else{ + if ( mappingType.equals( "node" ) ) { + + addNodeNameMapping( fromName, + toName ); + } + else if ( mappingType.equals( "device" ) ) { + addDeviceNameMapping( fromName, + toName ); + } + else if ( mappingType.equals( "instance" ) ) { + addSubCellInstanceNameMapping( fromName, + toName ); + } + else if ( mappingType.equals( "transistor" ) ) { + addTransistorModelNameMapping( fromName, + toName ); + } + else { + throwFileFormatException( currLine, myReader ); + } + } + } + else { + throwFileFormatException( currLine, myReader ); + } + } + } + } + } while ( currLine != null ); + } + + public void save( Writer w ) + throws IOException + { + + final Set cellNameMappings = getCellNameMappings(); + final Iterator cellNameIter = cellNameMappings.iterator(); + + while ( cellNameIter.hasNext() ) { + final Map.Entry currMapping = ( Map.Entry ) cellNameIter.next(); + final String fromName = ( String ) currMapping.getKey(); + final String toName = ( String ) currMapping.getValue(); + if ( ! ( fromName.equals( toName ) ) ) { + final String outputStr = + "cell " + + fromName + + ' ' + + toName + + '\n'; + w.write( outputStr ); + } + } + + final Set nodeNameMappings = getNodeNameMappings(); + final Iterator nodeNameIter = nodeNameMappings.iterator(); + + while ( nodeNameIter.hasNext() ) { + final Map.Entry currMapping = ( Map.Entry ) nodeNameIter.next(); + final String fromName = ( String ) currMapping.getKey(); + final String toName = ( String ) currMapping.getValue(); + if ( ! ( fromName.toString().equals( toName ) ) ) { + final String outputStr = + "node " + + fromName.toString() + + ' ' + + toName.toString() + + '\n'; + w.write( outputStr ); + } + } + + final Set deviceNameMappings = getDeviceNameMappings(); + final Iterator deviceNameIter = deviceNameMappings.iterator(); + + while ( deviceNameIter.hasNext() ) { + final Map.Entry currMapping = ( Map.Entry ) deviceNameIter.next(); + final String fromName = ( String ) currMapping.getKey(); + final String toName = ( String ) currMapping.getValue(); + if ( ! ( fromName.toString().equals( toName ) ) ) { + final String outputStr = + "device " + + fromName.toString() + + ' ' + + toName + + '\n'; + w.write( outputStr ); + } + } + + final Set subCellInstanceNameMappings = getSubCellInstanceNameMappings(); + final Iterator subCellInstanceNameIter = subCellInstanceNameMappings.iterator(); + + while ( subCellInstanceNameIter.hasNext() ) { + final Map.Entry currMapping = ( Map.Entry ) subCellInstanceNameIter.next(); + final String fromName = ( String ) currMapping.getKey(); + final String toName = ( String ) currMapping.getValue(); + if ( ! ( fromName.toString().equals( toName ) ) ) { + final String outputStr = + "instance " + + fromName.toString() + + ' ' + + toName + + '\n'; + w.write( outputStr ); + } + } + w.flush(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/Rename.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/Rename.java new file mode 100644 index 0000000000..b03667dc06 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/Rename.java @@ -0,0 +1,415 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.cdl.util.rename; + + +import java.io.PrintStream; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +import java.util.Collection; +import java.util.StringTokenizer; + +import com.avlsi.tools.jauto.PartialExtract; +import com.avlsi.util.container.Triplet; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.GDS2ReverseNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; +import com.avlsi.file.cdl.util.rename.CompositeCDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; + +/** + * A java version of rename. Translates lines from stdin using the CDLRenameInterfaces. + **/ + +public class Rename { + + public static void usagej() { + final String className = CDLRenamer.class.getName(); + + System.err.print( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className + "\n" + + "--type=[cell|node|instance|model|all]\n" + + "--from=[cast,cadence,gds2]\n" + + "--to=[cast,cadence,gds2]\n" ); + } + + public static void usage( String m ) { + + System.err.print( "Usage: rename\n" + + " --type=[cell|node|instance|model|all]\n" + + " --from=[cast,cadence,gds2]\n" + + " --to=[cast,cadence,gds2]\n" ); + if (m != null && m.length() > 0) + System.err.print( m ); + } + + public static void usage() { + usage( null ); + } + + private interface RenameAction { + String act(String in) throws CDLRenameException; + } + + public static void main(String[] args) + throws Exception + { + final CommandLineArgs parsedArgs = + new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + final CommandLineArgs theArgs = pedanticArgs; + + final String from = + theArgs.getArgValue( "from", null ); + + final String to = + theArgs.getArgValue( "to", null ); + + final String type = + theArgs.getArgValue( "type", null ); + + pedanticArgs.argTag( "from" ); + pedanticArgs.argTag( "to" ); + pedanticArgs.argTag( "type" ); + pedanticArgs.argTag( "partial" ); + pedanticArgs.argTag( "partial-subtype" ); + + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + usage(); + throw new CDLRenameException( pedanticArgs.pedanticString() ); + } + + if (type != null && type.equals("all")) { + + final CDLNameInterface nicast2cadence = new CadenceNameInterface(); + final CDLNameInterface nicast2gds2 = new GDS2NameInterface(); + final CDLNameInterface nicadence2cast = new CadenceReverseNameInterface(); + final CDLNameInterface nicadence2gds2 = new CompositeCDLNameInterface(new CadenceReverseNameInterface(), + new GDS2NameInterface()); + final CDLNameInterface nigds22cast = new GDS2ReverseNameInterface(); + final CDLNameInterface nigds22cadence = new CompositeCDLNameInterface(new GDS2ReverseNameInterface(), + new CadenceNameInterface()); + final RenameAction actsame = new RenameAction() { + public String act(String in) throws CDLRenameException { + return in;}}; + final RenameAction actcast2cadence4cell = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2cadence.renameCell(in);}}; + final RenameAction actcast2cadence4node = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2cadence.renameNode(in);}}; + final RenameAction actcast2cadence4instance = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2cadence.renameSubCellInstance(in);}}; + final RenameAction actcast2cadence4model = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2cadence.renameTransistorModel(in);}}; + final RenameAction actcast2gds24cell = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2gds2.renameCell(in);}}; + final RenameAction actcast2gds24node = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2gds2.renameNode(in);}}; + final RenameAction actcast2gds24instance = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2gds2.renameSubCellInstance(in);}}; + final RenameAction actcast2gds24model = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicast2gds2.renameTransistorModel(in);}}; + final RenameAction actcadence2cast4cell = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2cast.renameCell(in);}}; + final RenameAction actcadence2cast4node = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2cast.renameNode(in);}}; + final RenameAction actcadence2cast4instance = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2cast.renameSubCellInstance(in);}}; + final RenameAction actcadence2cast4model = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2cast.renameTransistorModel(in);}}; + final RenameAction actcadence2gds24cell = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2gds2.renameCell(in);}}; + final RenameAction actcadence2gds24node = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2gds2.renameNode(in);}}; + final RenameAction actcadence2gds24instance = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2gds2.renameSubCellInstance(in);}}; + final RenameAction actcadence2gds24model = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nicadence2gds2.renameTransistorModel(in);}}; + final RenameAction actgds22cast4cell = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cast.renameCell(in);}}; + final RenameAction actgds22cast4node = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cast.renameNode(in);}}; + final RenameAction actgds22cast4instance = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cast.renameSubCellInstance(in);}}; + final RenameAction actgds22cast4model = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cast.renameTransistorModel(in);}}; + final RenameAction actgds22cadence4cell = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cadence.renameCell(in);}}; + final RenameAction actgds22cadence4node = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cadence.renameNode(in);}}; + final RenameAction actgds22cadence4instance = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cadence.renameSubCellInstance(in);}}; + final RenameAction actgds22cadence4model = new RenameAction() { + public String act(String in) throws CDLRenameException { + return nigds22cadence.renameTransistorModel(in);}}; + + final PrintStream out = System.out; + final BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); + + String line; + StringTokenizer tk = null; + String ltype = "cell"; + String lfrom = "cast"; + String lto = "cast"; + String lname = ""; + String lx = ""; + RenameAction theAct; + int cnt; + while((line = in.readLine()) != null) { + tk = new StringTokenizer( line, " "); + cnt = 0; + if (tk.hasMoreTokens()) { lx = tk.nextToken(); cnt++; } + if (tk.hasMoreTokens()) { lfrom = tk.nextToken(); cnt++; } + if (tk.hasMoreTokens()) { lto = tk.nextToken(); cnt++; } + if (tk.hasMoreTokens()) { lname = tk.nextToken(); cnt++; } + if (cnt == 1) lname = lx; + if (cnt > 1) ltype = lx; + if (cnt == 1 || cnt == 4) { + theAct = actsame; + if (ltype.equals("cell")) { + if (lfrom.equals("cast")) { + if (lto.equals("cadence")) { + theAct = actcast2cadence4cell; + } + else if (lto.equals("gds2")) { + theAct = actcast2gds24cell; + } + } + else if (lfrom.equals("cadence")) { + if (lto.equals("cast")) { + theAct = actcadence2cast4cell; + } + else if (lto.equals("gds2")) { + theAct = actcadence2gds24cell; + } + } + else if (lfrom.equals("gds2")) { + if (lto.equals("cast")) { + theAct = actgds22cast4cell; + } + else if (lto.equals("cadence")) { + theAct = actgds22cadence4cell; + } + } + } + else if (ltype.equals("node")) { + if (lfrom.equals("cast")) { + if (lto.equals("cadence")) { + theAct = actcast2cadence4node; + } + else if (lto.equals("gds2")) { + theAct = actcast2gds24node; + } + } + else if (lfrom.equals("cadence")) { + if (lto.equals("cast")) { + theAct = actcadence2cast4node; + } + else if (lto.equals("gds2")) { + theAct = actcadence2gds24node; + } + } + else if (lfrom.equals("gds2")) { + if (lto.equals("cast")) { + theAct = actgds22cast4node; + } + else if (lto.equals("cadence")) { + theAct = actgds22cadence4node; + } + } + } + else if (ltype.equals("instance")) { + if (lfrom.equals("cast")) { + if (lto.equals("cadence")) { + theAct = actcast2cadence4instance; + } + else if (lto.equals("gds2")) { + theAct = actcast2gds24instance; + } + } + else if (lfrom.equals("cadence")) { + if (lto.equals("cast")) { + theAct = actcadence2cast4instance; + } + else if (lto.equals("gds2")) { + theAct = actcadence2gds24instance; + } + } + else if (lfrom.equals("gds2")) { + if (lto.equals("cast")) { + theAct = actgds22cast4instance; + } + else if (lto.equals("cadence")) { + theAct = actgds22cadence4instance; + } + } + } + else if (ltype.equals("model")) { + if (lfrom.equals("cast")) { + if (lto.equals("cadence")) { + theAct = actcast2cadence4model; + } + else if (lto.equals("gds2")) { + theAct = actcast2gds24model; + } + } + else if (lfrom.equals("cadence")) { + if (lto.equals("cast")) { + theAct = actcadence2cast4model; + } + else if (lto.equals("gds2")) { + theAct = actcadence2gds24model; + } + } + else if (lfrom.equals("gds2")) { + if (lto.equals("cast")) { + theAct = actgds22cast4model; + } + else if (lto.equals("cadence")) { + theAct = actgds22cadence4model; + } + } + } + out.println( theAct.act( lname )); + } + } + } + else { + CDLNameInterface ni = null; + + if(from == null || to == null || type == null) { + usage(); + throw new CDLRenameException("Must specify a valid from,to name-system and type"); + } + + if(from.equals("cast")) { + if(to.equals("cast")) + ni = new IdentityNameInterface(); + else if(to.equals("cadence")) + ni = new CadenceNameInterface(); + else if(to.equals("gds2")) + ni = new GDS2NameInterface(); + } + else if(from.equals("cadence")) { + if(to.equals("cast")) + ni = new CadenceReverseNameInterface(); + else if(to.equals("cadence")) + ni = new IdentityNameInterface(); + else if(to.equals("gds2")) + ni = new CompositeCDLNameInterface(new CadenceReverseNameInterface(), + new GDS2NameInterface()); + } + else if(from.equals("gds2")) { + if(to.equals("cast")) + ni = new GDS2ReverseNameInterface(); + else if(to.equals("cadence")) + ni = new CompositeCDLNameInterface(new GDS2ReverseNameInterface(), + new CadenceNameInterface()); + else if(to.equals("gds2")) + ni = new IdentityNameInterface(); + } + if(ni == null) { + usage(); + throw new CDLRenameException("Must specify a valid from,to name-system"); + } + + final CDLNameInterface theNI; + if(theArgs.argExists( "partial" ) || + theArgs.argExists( "partial-subtype" )) { + final CDLNameInterface partialNI = new IdentityNameInterface() { + public String renameCell(String in) { + final Triplet triplet = PartialExtract.parseCellPlusMinus(in); + String ret = (String) triplet.getFirst(); + if(theArgs.argExists( "partial-subtype") && + !((Collection)triplet.getThird()).isEmpty() ) { + ret += ".0"; + } + return ret; + } + }; + theNI = new CompositeCDLNameInterface(partialNI, ni); + } + else { + theNI = ni; + } + + final PrintStream out = System.out; + final BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); + RenameAction act = null; + + if(type.equals("cell")) + act = new RenameAction() { public String act(String in) + throws CDLRenameException { return theNI.renameCell(in); } }; + else if(type.equals("node")) + act = new RenameAction() { public String act(String in) + throws CDLRenameException { return theNI.renameNode(in); } }; + else if(type.equals("instance")) + act = new RenameAction() { public String act(String in) + throws CDLRenameException { return theNI.renameSubCellInstance(in); } }; + else if(type.equals("model")) + act = new RenameAction() { public String act(String in) + throws CDLRenameException { return theNI.renameTransistorModel(in); } }; + if(act == null) { + usage(); + throw new CDLRenameException("Must specify a valid type"); + } + + final RenameAction theAct = act; + + String line; + while((line = in.readLine()) != null) { + out.println( theAct.act(line.trim())); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/TrivialCDLNameInterfaceFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/TrivialCDLNameInterfaceFactory.java new file mode 100644 index 0000000000..58994d8ccc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/TrivialCDLNameInterfaceFactory.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.file.cdl.util.rename; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class TrivialCDLNameInterfaceFactory implements CDLNameInterfaceFactory { + + private final CDLNameInterface mTheInterface; + + public TrivialCDLNameInterfaceFactory( final CDLNameInterface theInterface ) { + mTheInterface = theInterface; + } + + public CDLNameInterface getNameInterface( final String cellName ) throws CDLRenameException { + return mTheInterface; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/__init__.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/cdlrenamer.package b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/cdlrenamer.package new file mode 100644 index 0000000000..2de96d4c06 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/cdlrenamer.package @@ -0,0 +1,9 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.file.cdl.util.rename.CDLRenamer com.avlsi.file.cdl.util.rename.Rename +$arch/bin/cdl_renamer.sh cdl_renamer.sh 775 +$arch/bin/rename.sh rename.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/custom.mk new file mode 100644 index 0000000000..8fbeb44de5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/custom.mk @@ -0,0 +1,12 @@ + +CURR_RESULT_FILES := $(CURR_RESULT_FILES) \ + $(CURR_TARGET_DIR)/cdl_renamer.sh \ + $(CURR_TARGET_DIR)/rename.sh + +$(CURR_TARGET_DIR)/cdl_renamer.sh: \ + $(CURR_PROJECT_DIR)/../../../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.file.cdl.util.rename.CDLRenamer/" >$@ + +$(CURR_TARGET_DIR)/rename.sh: \ + $(CURR_PROJECT_DIR)/../../../../../../../scripts/fulcrum-rename.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.file.cdl.util.rename.Rename/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.py b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.py new file mode 100644 index 0000000000..7c1894f356 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.py @@ -0,0 +1,94 @@ +#!/usr/bin/python +import sys +import getopt + +from com.avlsi.file.cdl.util.rename.IdentityNames import * +from com.avlsi.file.cdl.util.rename.CompositeNames import * +from com.avlsi.file.cdl.util.rename.CastNames2CadenceNames import * +from com.avlsi.file.cdl.util.rename.CastNames2GDSIINames import * +from com.avlsi.file.cdl.util.rename.CadenceNames2CastNames import * +from com.avlsi.file.cdl.util.rename.GDSIINames2CastNames import * +from com.avlsi.file.cdl.util.rename.CDLNameInterface import CDLRenameException + +import string + +ArgError = "Error parsing arguments" + +def usage(): + print "Usage: " + sys.argv[0] + print ' --type=[cell|node|instance|model]' + print ' --from=[cast,cadence,gds2]' + print ' --to=[cast,cadence,gds2]' + + +NamesDict = { "cast" : + { "cast" : IdentityNames(), + "cadence" : CastNames2CadenceNames(), + "gds2" : CastNames2GDSIINames() }, + "cadence" : + { "cast" : CadenceNames2CastNames(), + "cadence" : IdentityNames(), + "gds2" : CompositeNames( CadenceNames2CastNames(), CastNames2GDSIINames() ) }, + "gds2" : + { "cast" : GDSIINames2CastNames(), + "cadence" : CompositeNames( GDSIINames2CastNames(), CastNames2CadenceNames() ), + "gds2" : IdentityNames() } + } + +def main(argv): + try: + opts, args = getopt.getopt(argv, "", ["type=", "from=", "to=" ]) + except getopt.GetoptError: + usage() + sys.exit(2) + + renameType = "" + fromCode = "" + toCode = "" + try: + for key, val in opts: + if (key == "--type"): + renameType = val + elif (key == "--from"): + fromCode = val + elif (key == "--to"): + toCode = val + else: + raise ArgError, key + if ( not ( renameType in ("cell", "node", "instance" "device" "model" ) ) or + not ( fromCode in ("cast", "gds2", "cadence" ) ) or + not ( toCode in ("cast", "gds2", "cadence" ) ) ): + raise ArgError, "missing parameter" + except ArgError, message: + print ArgError + ": " + message + usage() + sys.exit(2) + + + Names = NamesDict[fromCode][toCode] + + if( renameType == "cell" ): + renameFunc = Names.renameCell + elif( renameType == "node" ): + renameFunc = Names.renameNode + elif( renameType == "instance" ): + renameFunc = Names.renameSubCellInstance + elif( renameType == "device" ): + renameFunc = Names.renameDevice + elif( renameType == "model" ): + renameFunc = Names.renameTransistorModel + + while 1: + try: + line = raw_input() + except EOFError: + break + names = string.splitfields( line, " " ) + newnames = map( renameFunc, names ) + newline = string.joinfields( newnames, " " ) + print newline + +if __name__ == "__main__": + main(sys.argv[1:]) + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.sh b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.sh new file mode 100755 index 0000000000..14146f8c99 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/cdl/util/rename/rename.sh @@ -0,0 +1,4 @@ +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} +python=`which python` +[[ ( $? == 0 ) && ( -d $package_root ) ]] && PYTHONPATH="$package_root/share/script/python" $python -O "$package_root/share/script/python/com/avlsi/file/cdl/util/rename/rename.pyo" $@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/Capacitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/Capacitor.java new file mode 100644 index 0000000000..0998254e23 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/Capacitor.java @@ -0,0 +1,116 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.common; + +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.circuit.CapacitorInterface; +/** + * Class to represent a capacitor in an aspice or ext file. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Capacitor implements CapacitorInterface{ + /** + * Name of source node. + **/ + private final HierName source; + + /** + * Name of drain node. + **/ + private final HierName drain; + + /** + * Capacitance in farads + **/ + private final double cap; + + /** + * Class constructor. Ensures that source is lexicographically + * less than or equal to drain, in order to canonicalize. + * @param source name of source node + * @param drain name of drain node + * @param cap capacitance in farads + **/ + public Capacitor(final HierName source, + final HierName drain, + final double cap) + { + // ensure that source <= drain, lexicographically + if (source.compareTo(drain) <= 0) { + this.source = source; + this.drain = drain; + } else { + this.source = drain; + this.drain = source; + } + + this.cap = cap; + } + + /** Not used, returns null **/ + public HierName getName() { + return null; + } + + /** + * Get name of source node. + * @return name of source node + **/ + public HierName getSource() { + return source; + } + + /** + * Get name of drain node. + * @return name of drain node + **/ + public HierName getDrain() { + return drain; + } + + /** + * Get the capacitance + * @return capacitance in farads. + **/ + public double getCap() { + return cap; + } + + /** Duplicate yes, but for compatibility we'll deal **/ + public double getCapacitance() { + return cap; + } + + /** + * return string suitable for inclusion in an aspice file. + **/ + public String getAspiceString() { + return "cap (" + + getSource().getAspiceString() + "," + + getDrain().getAspiceString() + ") (" + + NumberFormatter.format(getCap()) + ");"; + } + + /** + * + **/ + public String toString() { + return getClass().getName() + " (" + + getSource().toString() + "," + + getDrain().toString() + ") (" + + getCap() + ");"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/DeviceTypes.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/DeviceTypes.java new file mode 100644 index 0000000000..55ee23be07 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/DeviceTypes.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.common; + +/** + * Class holding constants for device types. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class DeviceTypes { + /** + * Constant for NFETs / N diodes + **/ + public static final int N_TYPE = 0; + + /** + * Constant for PFETs / P diodes + **/ + public static final int P_TYPE = 1; + + /** + * Number of device types. + **/ + public static final int NUM_TYPES = 2; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/HierName.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/HierName.java new file mode 100644 index 0000000000..6f95d683b3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/HierName.java @@ -0,0 +1,1040 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.common; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.HashMap; +import java.util.Iterator; + +import com.avlsi.util.debug.Debug; +import com.avlsi.util.container.Pair; +import com.avlsi.util.text.ByteArrayString; +import com.avlsi.util.text.StringUtil; +import com.avlsi.util.text.UnrepresentableCharException; + +/** + * Node name class. The same object is always returned by makeHierName + * for the same String input. + *

    The names are stored with common prefixes shared, also + * for space efficiency. For example, if the names "a/b/c" and "a/b/d" + * were both created, the tree would look like this: + *

    + *         a
    + *         ^
    + *         |
    + *         |
    + *         b
    + *        ^ ^
    + *       /   \
    + *      /     \
    + *     c       d
    + * 
    + * ("a" and "a/b" are automatically created by creating "a/b/c".) + * + * @todo jmr make this use weak references + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + * @review kiniry - Reviewed 16-23 July 2002. + * + * @bug kiniry 23 July 2002 - HierName is the primary culprit in memory and + * performance issues for many tools (e.g., PrsToNet). For example, a moderate + * run of PrsToNet generates over 30M HierName objects (10s to 100s MB of memory + * used at a time and 100s MB memory garbage collected throughout the run) and + * accounts for over 1/3rd of the run-time of the tool. Many of these calls are + * via Alias$AliasComparator.compare(). + * @see Bug#1173 + **/ +public final class HierName implements Comparable { + private final static byte ORDER_CLASS_MASK = 7; + private final static byte IS_ANONYMOUS = 4; + private final static byte IS_GENERATED = 8; + private final static byte IS_POINTER = 16; + private final static byte IS_GLOBAL = 32; + private final static byte IS_PORT = 64; + + private final int flags; + /** + * cache mapping the string representation of HierNames to + * An interned HierName object. + **/ + // private static final Map cache = new HashMap(); + + /** + * Pointer to parent HierName, or null if this one has no parent. + **/ + private final HierName prefix; + + /** + * The string representing the name, stored as a byte array. + **/ + private final byte[] name; + + /** + * Constructor. Only to be used by append. Only copies reference + * to name. + **/ + private HierName(final HierName prefix, final byte[] name) { + this.prefix = prefix; + this.name = name; + this.flags = initializeFlags(); + } + + /** + * Constructor. Only to be used by makeHierName. + **/ + private HierName(final HierName prefix, final String hierNameString) + throws InvalidHierNameException + { + try { + this.prefix = prefix; + this.name = ByteArrayString.fromString(hierNameString); + this.flags = initializeFlags(); + } catch (UnrepresentableCharException e) { + throw new InvalidHierNameException + ("Invalid char in name: " + e.getUnrepresentableChar(), e); + } + } + + /** + * Constructor. Only to be used by makeHierName. + * + *
    
    +     *   private normal_behavior
    +     *     requires prefix != null;
    +     *     requires suffix != null;
    +     *     requires suffix.prefix != null;
    +     * 
    + **/ + private HierName(final HierName prefix, final HierName suffix) { + this(prefix, suffix.name); + } + + private HierName(final HierName clone) { + this.prefix = clone.prefix; + this.name = clone.name; + this.flags = clone.flags | IS_PORT; + } + + private int initializeFlags() { + final boolean global = + ByteArrayString.lastIndexOf(name, (byte) '!') != -1; + final boolean pointer = + ByteArrayString.lastIndexOf(name, (byte) '#') == name.length - 1; + final boolean generated = + ByteArrayString.indexOf(name, (byte) '#') != -1; + final boolean anonymous = + ByteArrayString.indexOf(name, (byte) '$') == 0 || + (prefix != null && prefix.isAnonymous()); + return computeOrderClass(global, generated, anonymous) | + (global ? IS_GLOBAL : 0) | + (pointer ? IS_POINTER : 0) | + (generated ? IS_GENERATED : 0); + } + + /** + * Determine whether the name is of the format of a global name, + * ie it contains '!'. + **/ + public boolean isGlobal() { + return (flags & IS_GLOBAL) != 0; + } + + /** + * Returns whether this name is marked as a port. This designation only + * makes sense in the context of a cell, so use with caution. + **/ + private boolean isPort() { + return (flags & IS_PORT) != 0; + } + + /** + * Determine whether the name is of the format of a node pointer, + * ie it ends in '#'. + **/ + public boolean isPointer() { + return (flags & IS_POINTER) != 0; + } + + /** + * Determine whether the name is a local name, ie if its prefix is null. + **/ + public boolean isLocal() { + return prefix == null; + } + + /** + * Determine whether the name is of the format of a generated name, + * ie it contains '#'. + **/ + public boolean isGenerated() { + return (flags & IS_GENERATED) != 0; + } + + /** + * Determine whether any component of this name is the autogenerated name + * of an anonymous variable, i.e., if any components start with "$" and + * does not contain "!". + **/ + public boolean isAnonymous() { + return (flags & IS_ANONYMOUS) != 0; + } + + /** + * Determine whether the name is all digits. This might indicate a + * generated name. + **/ + public boolean isNumeric() { + final String s = getCadenceString(); + for (int i = 0; i < s.length(); i++) { + if (!Character.isDigit(s.charAt(i))) return false; + } + return true; + } + + // do we want isGnd, isVdd methods? I think so (-mid) + + /** + * Returns true if the suffix string is "GND" or "GND!". + **/ + public boolean isGND() { + int i = ByteArrayString.lastIndexOf(name, (byte) '!'); + if (i == -1) + return ByteArrayString.getString(name).equals("GND"); + else + return ByteArrayString.getString(name).substring(0,i).equals("GND"); + } + + /** + * Returns true if the suffix string is "Vdd" or "Vdd!". + **/ + public boolean isVdd() { + int i = ByteArrayString.lastIndexOf(name, (byte) '!'); + if (i == -1) + return ByteArrayString.getString(name).equals("Vdd"); + else + return ByteArrayString.getString(name).substring(0,i).equals("Vdd"); + } + + public boolean isResetNode() { + int i = ByteArrayString.lastIndexOf(name, (byte) '!'); + if (i == -1) + return ByteArrayString.getString(name).equals("_RESET") || + ByteArrayString.getString(name).equals("_Reset") || + ByteArrayString.getString(name).equals("Reset") || + ByteArrayString.getString(name).equals("Reset_"); + else + return ByteArrayString.getString(name).substring(0,i).equals("_RESET") || + ByteArrayString.getString(name).equals("_Reset") || + ByteArrayString.getString(name).equals("Reset") || + ByteArrayString.getString(name).equals("Reset_"); + } + + /** + * Returns the number of components in the name. Ie "a/b/c" has 3. + **/ + public int getNumComponents() { + int n = 0; + for (HierName hn = this; hn != null; hn = hn.prefix) + ++n; + return n; + } + + /** + * Returns a string representation of the name. Components are + * separated by separator. + * + * @bug kiniry 23 July 2002 - Hot spot for optimization. + * @see Bug#1173 + * + * @see String getAsString(String) + * @see StringBuffer getAsStringBuffer(StringBuffer, char) + * @see StringBuffer getAsStringBuffer(StringBuffer, String) + **/ + public String getAsString(final char separator) { + return getAsStringBuffer(new StringBuffer(), separator).toString(); + } + + public String getAsString( final String seperator ) { + return getAsStringBuffer( new StringBuffer(), seperator ).toString(); + } + + /** + * Returns a string representation of the suffix. + **/ + public String getSuffixString() { + return ByteArrayString.getString(name); + } + + public String getSuffixTrimmed() { + if (name.length <= 1) return getSuffixString(); + return ByteArrayString.getString( + ByteArrayString.substring(name, 0, name.length-1) + ); + } + + /** + * Returns a string representation of the name as a string buffer. + **/ + private StringBuffer getAsStringBuffer(final StringBuffer sb, + final char separator) { + if (prefix != null) + prefix.getAsStringBuffer(sb, separator).append(separator); + + return sb.append(ByteArrayString.getString(name)); + } + + private StringBuffer getAsStringBuffer(final StringBuffer sb, + final String separator) { + if (prefix != null) + prefix.getAsStringBuffer(sb, separator).append(separator); + + return sb.append(ByteArrayString.getString(name)); + } + + /** + * Returns the string that aspice wants to see. This means that + * a global a.b.c.foo!ext is output as foo. Otherwise, + * return the dot separated name. + **/ + public String getAspiceString() { + if (isGlobal()) { + final int bangIdx + = ByteArrayString.lastIndexOf(name, (byte) '!'); + + Debug.assertTrue(bangIdx != -1); + + return ByteArrayString.getString( + ByteArrayString.substring(name, + 0, bangIdx)); + } else { + return getAsString('.'); + } + } + + /** + * If this HierName corresponds to an array element, return the + * base name of the array. Otherwise, return this HierName. Only + * looks at the current level, not at the parent HierName. + **/ + public HierName getArrayBase() { + final int braceIdx + = ByteArrayString.lastIndexOf(name, (byte) '['); + if (braceIdx == -1) return this; + return makeSiblingName(this, ByteArrayString.getString(ByteArrayString.substring(name, 0, braceIdx))); + } + + /** + * Returns the string that cadence wants to see. This means that + * a global a.b.c.foo!ext is output as a.b.c.foo!ext. + **/ + public String getCadenceString() { + return getAsString('.'); + } + + /** + * Returns the string with the resistive subnet identifier suffix + * stripped off, i.e. a.b.c.foo:bar is output as a.b.c.foo. + **/ + public String getResistiveSubnetString() { + String s = getAsString('.'); + int i = s.indexOf(':'); + if (i == -1) + return s; + else + return s.substring(0,i); + } + + /** + * Returns the resistive subnet base HierName. + **/ + public HierName getResistiveSubnetName() { + final int colonIdx = ByteArrayString.lastIndexOf(name, (byte) ':'); + if (colonIdx == -1) return this; + else + return intern(new HierName(prefix, + ByteArrayString.substring(name,0,colonIdx))); + } + + /** + * Used only for debugging + **/ + public String toString() { + return getAsString('.'); + } + + /** + * Makes a HierName. The String must not contain any .'s or + * or non-ascii chars or an IllegalArgumentException will be thrown. + **/ + public static HierName makeHierName(final String s) { + final char sep = '.'; + if (s.indexOf(sep) != -1) + throw new IllegalArgumentException(s + " contains '.'"); + + try { + return HierName.makeHierName(s, sep); + } catch (InvalidHierNameException e) { + throw (IllegalArgumentException) + new IllegalArgumentException("Bad HierName " + s) + .initCause(e); + } + } + + /** + * Factory to make a HierName for the given hierNameString. + * The same HierName will always be returned for the + * same string + **/ + public static HierName makeHierName(final String hierNameString, + final char separator) + throws InvalidHierNameException + { + final String[] a = StringUtil.split(hierNameString, separator); + HierName p = null; + + // @review jmr + // this is somewhat inefficent for "a/b/c" and "a/b/d", + // an attempt will be made to add "a" and "a/b" twice. + // pehaps going from back to front could fix this. + for (int i = 0; i < a.length; ++i) + p = makeHierName(p, a[i]); + + return p; + } + + /** + * Given a HierName prefix and suffix, return the canonical HierName + * for this pair of (prefix, name). If + * p1.equals(p2) && n1.equals(n2) + * then makeHierName(p1,n1) == makeHierName(p2,n2); + * prefix is assumed + * to be in the cache. The HierName is added to + * the cache if it is not already there. + **/ + public static HierName makeHierName(final HierName prefix, + final String name) + throws InvalidHierNameException + { + // Debug.assertTrue(cache.get(prefix) == prefix); + + return intern(new HierName(prefix, name)); + } + + /** + * Returns a HierName with the specified prefix and suffix. + * The suffix must not have a parent, or an IllegalArgumentException + * will be thrown. + **/ + public static HierName makeHierName(final HierName prefix, + final HierName suffix) { + // Debug.assertTrue(cache.get(prefix) == prefix); + // Debug.assertTrue(cache.get(suffix) == suffix); + + return intern(new HierName(prefix, suffix)); + } + + /** + * Returns a HierName that is a clone of an existing HierName, except + * marked as a port, if so identified. + **/ + public static HierName makePortName(final HierName clone, + final boolean port) { + return !port || clone.isPort() ? clone : new HierName(clone); + } + + /** + * Returns a HierName that is the concatenation of the two names. + **/ + public static HierName append(final HierName hn1, final HierName hn2) { + if (hn2.prefix == null) + return new HierName(hn1, hn2.name); + else + return new HierName(append(hn1, hn2.prefix), hn2.name); + } + + /** + * Returns the HierName with the specified suffix appended. For example: + * makeHierName("a.b.c", '.').appendString("d") returns + * "a.b.cd". + **/ + public HierName appendString(final String suffix) { + return makeSiblingName(this, this.getSuffixString()+suffix); + } + + /** + * Memorizes the given name if it is not already memorized. + **/ + private static HierName intern(final HierName hn) { + // cache.get compares using equals, so this will be sort of slow + /* + final HierName hnOld = (HierName) cache.get(hn); + if (hnOld != null) + return hnOld; + else { + cache.put(hn, hn); + return hn; + } + */ + return hn; + } + + /** + * Returns a name with the same prefix as name, + * but a different suffix. Ie makeSiblingName("a.b.c", "d") == + * "a.b.d". If newSuffix contains invalid characters, + * IllegalArgumentException is thrown. + **/ + public static HierName makeSiblingName(final HierName name, + final String newSuffix) { + try { + return makeHierName(name.prefix, newSuffix); + } catch (InvalidHierNameException e) { + throw (IllegalArgumentException) + new IllegalArgumentException("bad hiername: " + + e.getMessage()).initCause(e); + } + } + + /** + * Returns a name with the same prefix as name but with a + * suffix one character shorter than before. Ie trim("a.b.c#") == "a.b.c" + ***/ + public static HierName trim(final HierName name) { + try { + return makeHierName(name.prefix, name.getSuffixTrimmed()); + } catch (InvalidHierNameException e) { + throw (IllegalArgumentException) + new IllegalArgumentException("bad hiername: " + + e.getMessage()).initCause(e); + } + } + + public int hashCode() { + int h = 0; + if (prefix != null && !isGlobal()) + h = prefix.hashCode(); + + for (int i = 0; i < name.length; ++i) + h = 31 * h + name[i]; + + return h; + } + + /** + * Returns true if the other object is a HierName, and they are equal. + * Two HierNames are equal if + **/ + public boolean equals(final Object o) { + return o instanceof HierName && equals((HierName) o); + } + + /** + * Two HierNames are equal if all components of their names are equal, + * and they have the same number of components. This computes equality + * by actually testing the prefix and local name, so should + * only be used within this file. + * + * @bug kiniry 23 July 2002 - Hot spot for optimization. + * @see Bug#1173 + * + * @see boolean equals(Object) + **/ + public boolean equals(final HierName hn) { + if (hn == null) + return false; + else if (!ByteArrayString.equals(name, hn.name)) + return false; + else if (prefix == null) + return hn.prefix == null; + else + return prefix.equals(hn.prefix); + } + + /** + * Returns the class number of the node. Smaller class numbers + * are less for the purposes of compareTo. + * global < local < generated + * + * @bug kiniry 23 July 2002 - Hot spot for optimization. + * @see Bug#1173 + **/ + private int getOrderClass() { + return flags & ORDER_CLASS_MASK; + } + + /** + * Used by initializeFlags() to initialize the + * order class to be returned by getOrderClass(). + **/ + private int computeOrderClass(final boolean global, + final boolean generated, + final boolean anonymous) { + if (global) + return 0; + else + return (anonymous ? IS_ANONYMOUS : 0) + (generated ? 2 : 1); + } + + /** + * Returns true if the first component of the HierName is + * hn. hn must have exactly one + * component. + * + * @todo jmr An iterative implemenation could make this more efficient. + **/ + public boolean prefixIs(final HierName hn) { + Debug.assertTrue(hn.getNumComponents() == 1); + HierName n = this; + + while (n.prefix != null) + n = n.prefix; + + return ByteArrayString.equals(n.name, hn.name); + } + + /** + * Returns this HierName, but without the first component, or + * null if there is only one component. + **/ + public HierName tail() { + if (prefix == null) + return null; + else + return new HierName(prefix.tail(), name); + } + + /** + * Return this HierName, but with the first n components + * removed, or null if n is larger than the + * number of components. + **/ + public HierName tail(final int n) { + HierName name = this; + for (int i = 0; i < n && name != null; ++i) { + name = name.tail(); + } + return name; + } + + /** + * Returns true if this successively matches all components of hn + **/ + public boolean isChildOf(HierName hn) { + if( hn == null ) + return true; + else { + if( this.head().equals(hn.head() ) ) { + final HierName t = tail(); + return t != null && t.isChildOf(hn.tail()); + } else + return false; + } + } + + /** + * Same as isChildOf, but avoids creating new HierName in the process. + **/ + public boolean isChildOf2(HierName hn) { + if (hn == null) return true; + + final int hnSize = hn.getNumComponents(); + final int mySize = getNumComponents(); + final int diff = mySize - hnSize; + if (diff <= 0) return false; + + HierName trimmed = this; + for (int i = 0; i < diff; ++i) trimmed = trimmed.prefix; + + return trimmed.equals(hn); + } + + /** + * Returns the first component of this HierName + **/ + public HierName head() { + if( prefix == null ) + return this; + else + return prefix.head(); + } + + /** + * Returns the components of this HierName as a collection. + **/ + public Collection getComponents(Collection result) { + if (prefix != null) prefix.getComponents(result); + result.add(ByteArrayString.getString(name)); + return result; + } + + /** + * Returns true if this HierName ends with hn + **/ + public boolean endsWith(HierName hn) { + boolean same = ByteArrayString.equals(name, hn.name); + if (same) { + if (hn.prefix == null) { + return true; + } else if (prefix == null) { + return false; + } else { + return prefix.endsWith(hn.prefix); + } + } else { + return false; + } + } + + // + // implements Comparable + // + + /** + * @exception ClassCastException if o is not a HierName + **/ + public int compareTo(final Object o) { + return compareTo((HierName) o); + } + + /** + * Compares two HierNames lexicographically. + * First, the class of the name is compared. All global names + * are less than all local names are less than all generated names + * If they are the same class, the one with fewer path components + * is smaller. If they have the same number of components, + * the one that comes earlier in the alphabet is smaller. + * + * @bug kiniry 23 July 2002 - Hot spot for optimization. + * @see Bug#1173 + **/ + public int compareTo(final HierName that) { + // first check the class + final int c1 = this.getOrderClass(); + final int c2 = that.getOrderClass(); + if (c1 != c2) + return c1 - c2; + + // both are in the same class + // check the number of components, then alpha order + + return lexicographicCompareTo(that); + } + + private static int lexicographicCompareByteArrayStrings( final byte[] a, final byte[] b ) { + if ( ( a.length != 0 ) && ( b.length != 0 ) ) { + final int dollarChar = ( int ) '$'; + final int aFirstChar = a[0]; + final int bFirstChar = b[0]; + if ( aFirstChar == bFirstChar ) { + return ByteArrayString.compare( a, b ); + } + else { + if ( aFirstChar == dollarChar ) { + return 1; + } + else if ( bFirstChar == dollarChar ) { + return -1; + } + else { + return ByteArrayString.compare( a, b ); + } + } + } + else { + return ByteArrayString.compare( a, b ); + } + } + + /** + * If the two names have a different number of components, + * the one with fewer is smaller. + * If the two names have the same number of components, + * compare component by component from parent to child; + * the first one with a component lexiographically + * smaller than the other is smaller. + **/ + private int lexicographicCompareTo(final HierName that) { + if (this == that) + return 0; + + if ( prefix == null ) { + if (that.prefix == null) + return lexicographicCompareByteArrayStrings(name, that.name); + else + return -1; + } + else if (that.prefix == null) { + return 1; + } + else { + // neither at end + final int c = prefix.lexicographicCompareTo(that.prefix); + if (c != 0) + return c; + else + return lexicographicCompareByteArrayStrings(name, that.name); + } + } + + /** + * return the comparator that compares HierNames with their natural + * ordering. + **/ + public static Comparator getComparator() { + return new HierNameComparator(); + } + + /** + * Comparator using HierName's natural order + **/ + private static final class HierNameComparator implements Comparator { + public int compare(Object o1, Object o2) { + final HierName hn1 = (HierName) o1; + final HierName hn2 = (HierName) o2; + + return hn1.compareTo(hn2); + } + + public boolean equals(final Object o) { + return getClass() == o.getClass(); + } + } + + /** + * return the comparator that compares HierNames with their natural + * ordering, giving higher priority to names designated as ports + **/ + public static Comparator getPortComparator() { + return PortNameComparator.getInstance(); + } + + private static final class PortNameComparator + implements Comparator { + private static PortNameComparator singleton = null; + + private PortNameComparator() { } + + public int compare(final HierName n1, final HierName n2) { + final boolean port1 = n1.isPort(); + final boolean port2 = n2.isPort(); + if (port1 == port2) { + return n1.compareTo(n2); + } else { + return port1 ? -1 : 1; + } + } + + public boolean equals(final Object o) { + return this == o; + } + + public int hashCode() { + return 0; + } + + public static PortNameComparator getInstance() { + if (singleton == null) singleton = new PortNameComparator(); + return singleton; + } + } + + /** + * If name is a global name, return it, otherwise, + * return it prefixed by subcellName. + **/ + public static HierName prefixName(final HierName subcellName, + final HierName name) { + if (name.isGlobal()) + return name; + else + return HierName.append(subcellName, name); + } + + /** + * returns name of parent. + **/ + public HierName getParent() { + return prefix; + } + + /** + * Iterate over all prefix-suffix pairs. For example, for + * a.b.c.d, the iterator would iterate over + * [null, a.b.c.d], + * [a, b.c.d], + * [a.b, c.d], + * [a.b.c, d], and + * [a.b.c.d, null]. + **/ + public static Iterator> + getSplitsIterator(final HierName name) { + return new Iterator>() { + HierName prefix = null; + HierName suffix = name; + public boolean hasNext() { + return prefix != null || suffix != null; + } + public Pair next() { + if (!hasNext()) throw new NoSuchElementException(); + final Pair result = + new Pair(prefix, suffix); + if (suffix == null) { + prefix = null; // signal termination + } else { + prefix = HierName.append(prefix, suffix.head()); + suffix = suffix.tail(); + } + return result; + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + /** + * Splits a string with 1 glob into 4 sets of strings: + * a.b.c*d.e.f -> a,b c d e,f, for use in comparing globs + * to HierNames. + **/ + public static class Glob1 { + private final byte [] prefixes[], suffixes[]; + private final byte [] globPrefix, globSuffix; + + public Glob1(String glob) throws UnrepresentableCharException { + int star = glob.indexOf('*'); + String head = glob.substring(0, star); + String tail = glob.substring(star+1); + String [] heads = StringUtil.split(head,'.'); + String [] tails = StringUtil.split(tail,'.'); + if (heads.length == 0) { + prefixes = new byte [0][]; + globPrefix = new byte [0]; + } else { + prefixes = new byte [heads.length - 1][]; + for (int i = 0; i < heads.length - 1; i++) { + prefixes[i] = ByteArrayString.fromString(heads[i]); + } + globPrefix = + ByteArrayString.fromString(heads[heads.length - 1]); + } + + if (tails.length == 0) { + suffixes = new byte [0][]; + globSuffix = new byte [0]; + } else { + suffixes = new byte [tails.length - 1][]; + for (int i = 1; i < tails.length; i++) { + suffixes[i-1] = ByteArrayString.fromString(tails[i]); + } + globSuffix = + ByteArrayString.fromString(tails[0]); + } + } + + public boolean matches(HierName h) { + int numComponents = h.getNumComponents(); + if (numComponents < prefixes.length + suffixes.length + 1) { + return false; + } + + byte [][] components = getComponents(h); + if (!suffixesMatch(components)) { + return false; + } + if (!prefixesMatch(components)) { + return false; + } + int first = prefixes.length; + int last = components.length - suffixes.length - 1; + if (!bigEnough(components, first, last)) { + return false; + } + if (!prefixMatch(components[first])) { + return false; + } + if (!suffixMatch(components[last])) { + return false; + } + return true; + } + + private boolean suffixesMatch(byte [][] components) { + int sl = suffixes.length; + int offset = components.length - sl; + for (int i = 0; i < sl; i++) { + if (!ByteArrayString.equals(suffixes[i], + components[i+offset])) { + return false; + } + } + return true; + } + + private boolean prefixesMatch(byte [][] components) { + for (int i = 0; i < prefixes.length; i++) { + if (!ByteArrayString.equals(prefixes[i], components[i])) { + return false; + } + } + return true; + } + + private boolean prefixMatch(byte [] string) { + if (globPrefix.length > string.length) { + return false; + } + for (int i = 0; i < globPrefix.length; i++) { + if (globPrefix[i] != string[i]) { + return false; + } + } + return true; + } + + private boolean suffixMatch(byte [] string) { + if (globSuffix.length > string.length) { + return false; + } + int offset = string.length - globSuffix.length; + for (int i = 0; i < globSuffix.length; i++) { + if (globSuffix[i] != string[i+offset]) { + return false; + } + } + return true; + } + + private boolean bigEnough(byte[][] components, int first, int last) { + if (first == last) { + if (components[first].length < + globSuffix.length + globPrefix.length) { + return false; + } + } else if (components[first].length < globPrefix.length) { + return false; + } else if (components[last].length < globSuffix.length) { + return false; + } + return true; + } + + private byte [][] getComponents(HierName h) { + byte [][] comps = new byte[h.getNumComponents()][]; + for (int i = comps.length - 1; i >= 0; i--) { + comps[i] = h.name; + h = h.prefix; + } + return comps; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/InvalidHierNameException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/InvalidHierNameException.java new file mode 100644 index 0000000000..5e88b1d8cf --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/InvalidHierNameException.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.common; + +/** + * Exception throws for invalied HierNames. + * + * @see HierName + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class InvalidHierNameException extends Exception { + InvalidHierNameException() { + super(); + } + + InvalidHierNameException(final String detail) { + super(detail); + } + + InvalidHierNameException(final String detail, final Throwable cause) { + super(detail, cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/TestHierName.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/TestHierName.java new file mode 100644 index 0000000000..8fbaa9c19c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/common/TestHierName.java @@ -0,0 +1,56 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.common; + +import com.avlsi.test.AbstractTestCase; + +/** + * Test case for HierName. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class TestHierName extends AbstractTestCase { + + public void testAppend(final String n1, final String n2, final char sep) + throws Throwable { + final String expectedResult = n1 + sep + n2; + + final HierName hn1 = HierName.makeHierName(n1, sep); + final HierName hn2 = HierName.makeHierName(n2, sep); + final HierName hnRes = HierName.append(hn1, hn2); + + assertTrue(expectedResult.equals(hnRes.getAsString(sep))); + } + + public void testAppend() throws Throwable { + testAppend("a", "d", '.'); + testAppend("a.b", "d", '.'); + testAppend("a.b.c", "d", '.'); + + testAppend("a", "d", '.'); + testAppend("a", "d.e", '.'); + testAppend("a", "d.e.f", '.'); + + testAppend("a.b.c", "d.e.f", '.'); + } + + public void test() throws Throwable { + testAppend(); + } + + public static void main(String[] args) { + AbstractTestCase.testOne(new TestHierName()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Environment.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Environment.java new file mode 100644 index 0000000000..b1f30a6911 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Environment.java @@ -0,0 +1,105 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.ext; + +import java.util.Date; + +/** + * Immutable wrapper class encapsulating environment information from the + * .ext file such as: + *
      + *
    • The name of the technology + *
    • The time the cell was last modified + *
    • The version of the ext format + *
    • The style that the cell has been extracted with + *
    • The resistance per square for each of the resistance classes + * defined in the tech file. + *
    + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Environment { + private final String technology; + private final Date timestamp; + private final String version; + private final String style; + private double[] resistanceClasses; + + public Environment(final String technology, + final Date timestamp, + final String version, + final String style, + final double[] resistanceClasses) + { + this.technology = technology; + this.timestamp = timestamp; + this.version = version; + this.style = style; + this.resistanceClasses = resistanceClasses; + } + + public String getTechnology() { + return technology; + } + + public Date getTimestamp() { + return timestamp; + } + + public String getVersion() { + return version; + } + + public String getStyle() { + return style; + } + + /** + * Returns the reistance per square (in milliohms) for the specified + * resistance class. + * @param n the number of the resistance class + * @return resistance per square (in milliohms) for resistance class n + * + * @throws ResistanceClassOutOfBoundsException + **/ + public double getResistanceForClass(int n) { + try { + return resistanceClasses[n]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new ResistanceClassOutOfBoundsException(n, + getNumResistClasses(), e); + } + } + + public int getNumResistClasses() { + return resistanceClasses.length; + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + sb.append("Environment {"); + sb.append("\n Technology: " + technology); + sb.append("\n, Timestamp: " + timestamp); + sb.append("\n, Version: " + version); + sb.append("\n, Style: " + version); + sb.append("\n, Resistance Classes:"); + for (int i = 0; i < resistanceClasses.length; ++i) + sb.append(" " + resistanceClasses[i]); + sb.append("\n}"); + + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ExtCell.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ExtCell.java new file mode 100644 index 0000000000..8f31a57e2a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ExtCell.java @@ -0,0 +1,419 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.ext; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.avlsi.file.common.Capacitor; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.BinaryAction; +import com.avlsi.util.functions.UnaryPredicate; + +/** + * This class represents information from a .ext file. Rather than + * simply present an abstract syntax tree of a .ext file, try to + * present the information in "useful" data structures. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ExtCell { + private final String name; + private Environment environment = null; + private final List fetList = new ArrayList(); + private final List capList = new ArrayList(); + + /** + * Global repository for subcell definitions. Passed in + * from ExtParser. + **/ + private final Map subcellNameToDefnMap; + + /** + * Map from subcell use name (String) to ExtCell + **/ + private final Map subcellUseMap = new TreeMap(); + + /** + * Namespace info. Map from set of names to node. Names + * may be in this cell or of the form sub/name for captured + * nodes from subcells. + **/ + private final AliasedMap asm + = new AliasedMap( + new Node.NodeMergeFunction(), HierName.getComparator()); + + /** + * Constructs an ExtCell with the given name. + **/ + public ExtCell(final String name, final Map subcellNameToDefnMap) { + this.name = name; + this.subcellNameToDefnMap = subcellNameToDefnMap; + } + + /** + * Return the name of the cell. + **/ + public String getName() { + return name; + } + + // + // environment related methods + // + + /** + * set the environment + **/ + public void setEnvironment(final Environment environment) { + this.environment = environment; + } + + /** + * get the environment + **/ + public Environment getEnvironment() { + return environment; + } + + // + // fet related methods + // + + /** + * Adds a fet. + **/ + public void addFET(final FET fet) { + // add to namespace + addName(fet.getSubstrateNode()); + addName(fet.getGate().getConnectingNode()); + addName(fet.getSource().getConnectingNode()); + addName(fet.getDrain().getConnectingNode()); + + fetList.add(fet); + } + + /** + * Returns an iterator of FETs. + **/ + public Iterator getFETs() { + return fetList.iterator(); + } + + // + // cap related methods + // + + /** + * Adds a capacitor. Adds its source and drain to the namespace. + **/ + public void addCapacitor(final Capacitor capacitor) { + // add to namespace + addName(capacitor.getSource()); + addName(capacitor.getDrain()); + + capList.add(capacitor); + } + + /** + * Returns an iterator of Capacitors. + **/ + public Iterator getCapacitors() { + return capList.iterator(); + } + + // + // namespace related methods + // + + /** + * return an Iterator of Nodes. + **/ + public Iterator getNodes() { + return new FilteringIterator(asm.getValues(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return ((Node) o) != null; + } + }); + } + + /** + * returns the canonical name for a node, + * or null if that nodename is not known. + **/ + public HierName getCanonicalName(final HierName nodeName) { + return (HierName) asm.getCanonicalKey(nodeName); + } + + /** + * Returns the node with the given name. + **/ + public Node getNodeByName(HierName name) { + return (Node) asm.getValue(name); + } + + /** + * Adds the node using the given name. If the node already + * exists, merge the contents with Node.NodeMergeFunction. + * + * @param nodeName (WHERE nodeName != null) the name of the node + * @param node (WHERE node != null || node == null) the node data, + * pass null to indicate no data. + **/ + public void addData(final HierName nodeName, final Node node) + throws AliasedMap.MergeFailedException + { + Debug.assertTrue(nodeName != null); + asm.addData(nodeName, node); + } + + /** + * Adds a name, with no data. + **/ + public void addName(final HierName nodeName) + { + try { + addData(nodeName, null); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + /** + * Connects the two names, adding them if they don't both + * exist. + **/ + public void connectNames(final HierName name1, final HierName name2) + throws AliasedMap.MergeFailedException + { + Debug.assertTrue(name1 != null); + Debug.assertTrue(name2 != null); + asm.makeEquivalent(name1, name2); + } + + /** + * Returns an Iterator of HierName of the equivalent names to + * the node. Includes name in the list. + **/ + public Iterator getEquivalentNames(final HierName name) { + return asm.getAliases(name); + } + + /** + * Returns whether two names are equivalent. + **/ + public boolean areEquivalent(final HierName hn1, final HierName hn2) { + return asm.areEquivalent(hn1, hn2); + } + + + // + // subcell related methods + // + + /** + * Adds a subcell. + **/ + public void addSubcell(final String useName, final ExtCell subExt) { + final Object o = subcellUseMap.put(useName, subExt); + + if (o != null) + throw new RuntimeException("multiple use of " + useName + + " old defn replaced."); + } + + /** + * returns an Iterator of Strings of the subcell use names. + **/ + public Iterator getSubcellNames() { + return subcellUseMap.keySet().iterator(); + } + + /** + * returns the definition of the subcell based on its usage name + **/ + public ExtCell getSubcellDefForName(final String name) { + return (ExtCell) subcellUseMap.get(name); + } + + /** + * returns the type of the subcell based on its name + **/ + public String getSubcellTypeForName(final String name) { + return getSubcellDefForName(name).getName(); + } + + + // + // Subcell traversal methods + // + + /** + * Recursively applies visitSubcells on all subcells of + * this cell, then calls f on this cell itself. + * The first argument to f.execute is a String representing + * the path of cells above in the hierarchy. The second + * argument is the ExtCell itself. + * + * @param prefix path indicating cells above in hierarchy + * @param f the BinaryAction to be applied to all cells + **/ + private void visitSubcells(final String prefix, final BinaryAction f) { + for (final Iterator i = getSubcellNames(); i.hasNext(); ) { + final String n = (String) i.next(); + + // this would be nicer if local names started with / + final String newPrefix + = prefix.length() == 0 ? n : prefix + "/" + n; + getSubcellDefForName(n).visitSubcells(newPrefix, f); + } + + f.execute(prefix, this); + } + + /** + * Recursively applies visitSubcells on all subcells of + * this cell, then calls f on this cell itself. + * The first argument to f.execute is a String representing + * the path of cells above in the hierarchy. The second + * argument is the ExtCell itself. + **/ + public void visitSubcells(final BinaryAction f) { + visitSubcells("", f); + } + + /** + * Applies a function to all the capacitors in the tree. + * The first argument to f.execute is a String representing + * the path of cells above in the hierarchy. The second + * argument is the Capacitor itself. + **/ + public void visitCapacitors(final BinaryAction f) { + visitSubcells(new BinaryAction() { + public void execute(final Object a, final Object b) { + final String prefix = (String) a; + final ExtCell e = (ExtCell) b; + + for (final Iterator i = e.getCapacitors(); i.hasNext(); ) { + final Capacitor c = (Capacitor) i.next(); + f.execute(prefix, c); + } + } + }); + } + + /** + * Applies a function to all the resistors in the tree. + * The first argument to f.execute is a String representing + * the path of cells above in the hierarchy. The second + * argument is the Resistor itself. + **/ + /* + public void visitResistors(final BinaryAction f) { + visitSubcells(new BinaryAction() { + public void execute(final Object a, final Object b) { + final String prefix = (String) a; + final ExtCell e = (ExtCell) b; + + for (final Iterator i = e.getCapacitors(); i.hasNext(); ) { + final Resistor r = (Capacitor) i.next(); + f.execute(prefix, r); + } + } + }); + } + */ + + /** + * Applies a function to all the nodes in the tree. + * The first argument to f.execute is a String representing + * the path of cells above in the hierarchy. The second + * argument is the Resistor itself. + **/ + public void visitNodes(final BinaryAction f) { + visitSubcells(new BinaryAction() { + public void execute(final Object a, final Object b) { + final String prefix = (String) a; + final ExtCell e = (ExtCell) b; + + for (final Iterator i = e.getNodes(); i.hasNext(); ) { + final Node n = (Node) i.next(); + f.execute(prefix, n); + } + } + }); + } + + /** + * Applies a function to all the FETs in the tree. + * The first argument to f.execute is a String representing + * the path of cells above in the hierarchy. The second + * argument is the FET itself. + **/ + public void visitFETs(final BinaryAction f) { + visitSubcells(new BinaryAction() { + public void execute(final Object a, final Object b) { + final String prefix = (String) a; + final ExtCell e = (ExtCell) b; + + for (final Iterator i = e.getFETs(); i.hasNext(); ) { + final FET fet = (FET) i.next(); + f.execute(prefix, fet); + } + } + }); + } + + // + // toString + // + + public String toString() { + final StringWriter sw = new StringWriter(); + final Writer w = new PrintWriter(sw); + + /* + private final FET[] fets; + private final Subcell[] subcells; + private final Map pairToResistanceMap; + private final Map pairToCapacitanceMap; + private final Namespace namespace; + */ + + /* + w.println("ExtCell {"); + w.println(environment); + w.println(namespace); + */ + + // xxx + + return w.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/FET.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/FET.java new file mode 100644 index 0000000000..20b3eb2d36 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/FET.java @@ -0,0 +1,100 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.ext; + +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; + +/** + * + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class FET { + + private final int type; + private final double area; + private final double perimeter; + private final HierName substrateNode; + private final Terminal gate; + private final Terminal source; + private final Terminal drain; + + /** + * Class constructor. Canonicalizes the source and drain node + * names by ensuring that source is lexicographically less than + * drain. This will ensure we have a canonical form for + * FETs. + **/ + public FET(final int type, + final double area, + final double perimeter, + final HierName substrateNode, + final Terminal gate, + final Terminal source, + final Terminal drain) + { + if (type != DeviceTypes.N_TYPE && type != DeviceTypes.P_TYPE) + throw new IllegalArgumentException("Bad fet type: " + type); + + this.type = type; + this.area = area; + this.perimeter = perimeter; + this.substrateNode = substrateNode; + this.gate = gate; + + // ensure that source <= drain, lexicographically + if (source.getConnectingNode().compareTo( + drain.getConnectingNode()) <= 0) { + this.source = source; + this.drain = drain; + } else { + this.source = drain; + this.drain = source; + } + } + + public int getType() { + return type; + } + + // area of the gate region in square centimicrons + public double getArea() { + return area; + } + + // perimeter of the gate region in centimicrons + public double getPerimeter() { + return perimeter; + } + + // the node to which the substrate of the transistor is connected + public HierName getSubstrateNode() { + return substrateNode; + } + + public Terminal getGate() { + return gate; + } + + public Terminal getSource() { + return source; + } + + public Terminal getDrain() { + return drain; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Node.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Node.java new file mode 100644 index 0000000000..ad5a066790 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Node.java @@ -0,0 +1,132 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.ext; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; + +/** + * Class to represent an electrical node in a .ext file. + * Lumped resistance has been ignored, as it is useless. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Node { + private final HierName name; + private final double capacitanceToGround; + private final double[] resistClassPerims; + private final double[] resistClassAreas; + + public Node(final HierName name, + final double capacitanceToGround, + final double[] resistClassPerims, + final double[] resistClassAreas) + { + this.name = name; + this.capacitanceToGround = capacitanceToGround; + this.resistClassPerims = resistClassPerims; + this.resistClassAreas = resistClassAreas; + + Debug.assertTrue(name != null); + Debug.assertTrue(resistClassPerims != null); + Debug.assertTrue(resistClassAreas != null); + } + + /** + * @review XXX should this always return a fresh object? + **/ + public static final class NodeMergeFunction + implements AliasedMap.MergeFunction { + public Object merge(final Object o1, final Object o2) + throws AliasedMap.MergeFailedException + { + if (o1 == null) + return o2; + else if (o2 == null) + return o1; + else { + final Node n1 = (Node) o1; + final Node n2 = (Node) o2; + + // if names do not agree (merge of label-connected nodes) + // then pick the more canonical name + // even better: make the name non-intrinsic + + // cap + final double c = n1.getCapacitanceToGround() + + n2.getCapacitanceToGround(); + + // perims + final double[] rcp1s = n1.getResistClassPerims(); + final double[] rcp2s = n2.getResistClassPerims(); + + if (rcp1s.length != rcp2s.length) + throw new AliasedMap.MergeFailedException( + "Num resist class perims differ"); + + final double[] rcps = new double[rcp1s.length]; + + for (int i = 0; i < rcps.length; ++i) + rcps[i] = rcp1s[i] + rcp2s[i]; + + // areas + final double[] rca1s = n1.getResistClassAreas(); + final double[] rca2s = n2.getResistClassAreas(); + + if (rca1s.length != rca2s.length) + throw new AliasedMap.MergeFailedException( + "Num resist class areas differ"); + + final double[] rcas = new double[rca1s.length]; + + for (int i = 0; i < rcas.length; ++i) + rcas[i] = rca1s[i] + rca2s[i]; + + return new Node(n1.getName(), c, rcps, rcas); + } + } + } + + /** + * returns the name of the node + **/ + public HierName getName() { + return name; + } + + // total capacitance to ground in attofarads + public double getCapacitanceToGround() { + return capacitanceToGround; + } + + public double[] getResistClassPerims() { + return resistClassPerims; + } + public double[] getResistClassAreas() { + return resistClassAreas; + } + public double getAreaForResistClass(int i) { + return resistClassAreas[i]; + } + public double getPerimForResistClass(int i) { + return resistClassPerims[i]; + } + + public String toString() { + return "Node[" + getName().toString() + "]"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ResistanceClassOutOfBoundsException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ResistanceClassOutOfBoundsException.java new file mode 100644 index 0000000000..a75d738cc3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/ResistanceClassOutOfBoundsException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.ext; + +/** + * This is a description of the class + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ResistanceClassOutOfBoundsException + extends IndexOutOfBoundsException +{ + public ResistanceClassOutOfBoundsException() { + super(); + } + + public ResistanceClassOutOfBoundsException(final int resistanceClass, + final int numResistanceClasses) + { + this(resistanceClass, numResistanceClasses, null); + } + + public ResistanceClassOutOfBoundsException(final int resistanceClass, + final int numResistanceClasses, + final Throwable cause) + { + super("resistance class out of range: " + resistanceClass + + "; number of valid classes: " + numResistanceClasses); + initCause(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Terminal.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Terminal.java new file mode 100644 index 0000000000..c955461aa0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/Terminal.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.ext; + +import com.avlsi.file.common.HierName; + +/** + * + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Terminal { + private final HierName connectingNode; + private final double length; + + public Terminal(final HierName connectingNode, + final double length) + { + this.connectingNode = connectingNode; + this.length = length; + } + + public HierName getConnectingNode() { + return connectingNode; + } + + // the terminal length in centimicrons; the length of that segment of + // the channel perimeter connecting to adjacent material, such as + // polysilicon for the gate or diffusion for a source or drain + public double getLength() { + return length; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ArraySpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ArraySpec.java new file mode 100644 index 0000000000..4afacb6c4f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ArraySpec.java @@ -0,0 +1,178 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.ext.parse; + +import com.avlsi.util.functions.UnaryAction; + +/** + * This class represents the array specification abbreviation syntax + * in .ext files. This occurs in two places + *
      + *
    • use lines: use[xlo,xhi,xsep_centimicron][ylo,yhi,ysep_centimicron] + *
    • merge lines: cell[xlo:xhi,ylo:yhi]/node + *
    + * + * The class contains the following information: + *
      + *
    • before: the string before the array spec opening bracket + *
    • after: the string before the array spec closing bracket + *
    • xlo: the min x index + *
    • xhi: the max x index + *
    • ylo: the min y index + *
    • yhi: the max y index + *
    + * The constructor is passed all these data, and accessors are provided for + * them. There is one additional method: {@link #genName} + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ArraySpec { + private final String before; + private final String after; + private final int xlo, xhi, ylo, yhi; + + /** + * True if the given coord should be treated as an array. + **/ + private final boolean xIsArray, yIsArray; + + /** + * Class constructor. + * + * @throws IllegalArgumentException + **/ + public ArraySpec(final String before, + final String after, + int xlo, int xhi, final boolean xIsArray, + int ylo, int yhi, final boolean yIsArray) { + if (xlo > xhi) { + // swap them + int t = xhi; + xhi = xlo; + xlo = t; + } + + if (ylo > yhi) { + // swap them + int t = yhi; + yhi = ylo; + ylo = t; + } + + if (!xIsArray && (xlo != xhi)) + throw new IllegalArgumentException( + "You said x wasn't arrayed, but it is."); + + if (!yIsArray && (ylo != yhi)) + throw new IllegalArgumentException( + "You said y wasn't arrayed, but it is."); + + this.before = before; + this.after = after; + this.xlo = xlo; + this.xhi = xhi; + this.xIsArray = xIsArray; + this.ylo = ylo; + this.yhi = yhi; + this.yIsArray = yIsArray; + } + + /** + * Generates the (x,y)-th name. Examples: + * new ArraySpec("foo", "bar", 1, 7, 3, 5).genName(2, 4) + * => foo[4][2]bar + * new ArraySpec("foo", "bar", 1, 7, 3, 3).genName(2, 3) + * => foo[2]bar + * new ArraySpec("foo", "bar", 1, 1, 3, 5).genName(1, 4) + * => foo[4]bar + * new ArraySpec("foo", "bar", 1, 1, 3, 3).genName(1, 3) + * => foobar + * new ArraySpec("foo", "bar", 1, 1, 3, 5).genName(1, -1) + * => throws IllegalArgumentException + * + * @throws IllegalArgumentException + **/ + public String genName(final int x, final int y) { + if (x < xlo) + throw new IllegalArgumentException("x < xlo: " + x + "<" + xlo); + else if (x > xhi) + throw new IllegalArgumentException("x > xhi: " + x + ">" + xhi); + else if (y < ylo) + throw new IllegalArgumentException("y < ylo: " + y + "<" + ylo); + else if (y > yhi) + throw new IllegalArgumentException("y > yhi: " + y + ">" + yhi); + + final String xs = !xIsArray ? "" : "[" + x + "]"; + final String ys = !yIsArray ? "" : "[" + y + "]"; + + return before + ys + xs + after; + } + + public void mapNames(final UnaryAction f) { + for (int ix = xlo; ix <= xhi; ++ix) + for (int iy = ylo; iy <= yhi; ++iy) + f.execute(genName(ix, iy)); + } + + public String getBeforeString() { + return before; + } + + public String getAfterString() { + return after; + } + + public boolean getXIsArray() { + return xIsArray; + } + + public int getXLo() { + return xlo; + } + + public int getXHi() { + return xhi; + } + + public int getXSize() { + return xhi - xlo + 1; + } + + public boolean getYIsArray() { + return yIsArray; + } + + public int getYLo() { + return ylo; + } + + public int getYHi() { + return yhi; + } + + public int getYSize() { + return yhi - ylo + 1; + } + + /** + * Return a string representation for debugging only. + **/ + public String toString() { + return before + "[" + + xlo + ":" + xhi + ":" + xIsArray + "," + + ylo + ":" + yhi + ":" + yIsArray + "]" + + after; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtFileFormatException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtFileFormatException.java new file mode 100644 index 0000000000..df4bf13267 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtFileFormatException.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.ext.parse; + +public class ExtFileFormatException extends Exception { + private final String fileName; + private final int lineNumber; + private final String line; + + public ExtFileFormatException(final String detail, + final String fileName, + final int lineNumber, + final String line, + final Throwable cause) + { + super("File: " + fileName + "; line: " + lineNumber + ": " + detail, + cause); + this.fileName = fileName; + this.lineNumber = lineNumber; + this.line = line; + } + + public ExtFileFormatException(final String detail, + final String fileName, + final int lineNumber, + final String line) + { + this(detail, fileName, lineNumber, line, null); + } + + public String getFileName() { + return fileName; + } + + public int getLineNumber() { + return lineNumber; + } + + public String getLine() { + return line; + } + + public String toString() { + return getMessage() + "; line was: " + getLine(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtParser.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtParser.java new file mode 100644 index 0000000000..4f63dd7070 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/ext/parse/ExtParser.java @@ -0,0 +1,1109 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.file.ext.parse; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import com.avlsi.file.common.Capacitor; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.ext.Environment; +import com.avlsi.file.ext.ExtCell; +import com.avlsi.file.ext.FET; +import com.avlsi.file.ext.Node; +import com.avlsi.file.ext.Terminal; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryAction; +import com.avlsi.util.text.StringUtil; + +/** + * ExtParser parses .ext files into {@link ExtCell}s. + * + * @see ExtCell + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class ExtParser { + // Conversions from .ext units to SI units + private static final double attoFarads = 1e-18; + private static final double milliOhms = 1e-3; + private static final double centiMicrons = 1e-2 * 1e-6; + private static final double squareCentiMicrons + = centiMicrons * centiMicrons; + + /** + * The number of resistance classes that are important to us. + * We only care about the first two, for ndiff and pdiff. + **/ + private static final int NUM_IMPORTANT_RESIST_CLASSES = 2; + + private static final char PATH_SEPARATOR = '/'; + + // environmental information + String technology = null; + Date timestamp = null; + String version = null; + String style = null; + double rscale = 1.0, cscale = 1.0, lscale = 1.0; + boolean scalesSet = false; + double[] resistanceClasses = new double[0]; + int numResistClasses = -1; // the number of resistance classes + // specified in the .ext file + // this will not equal + // resistanceClasses.length because + // resistanceClasses.length == + // NUM_IMPORTANT_RESIST_CLASSES, + // the number we care to remember + + // parse structures + final ExtCell ext; + + /** + * The global repository for subcell definitions. + **/ + final Map subcellNameToDefnMap; + + /** + * search path to use to find .ext files. + **/ + final FileSearchPath extPath; + + // parse state + private boolean env = true; + private int lineNumber = 0; + private String line = null; + + private boolean m_RecurseOnUseStatements; + + /** + * Class constructor. Constructs a parser with a new + * subcellNameToDefnMap + **/ + public ExtParser(final String name, + final FileSearchPath extPath, + boolean RecurseOnUseStatements ) { + this(name, extPath, new HashMap(), RecurseOnUseStatements ); + } + + /** + * Class constructor. Constructs a parser with the given + * subcellNameToDefnMap + * @todo jmr XXX check that subcells are parsed with the same + * tech file (and other appropriate env info) as parent. + **/ + public ExtParser(final String name, + final FileSearchPath extPath, + final Map subcellNameToDefnMap, + boolean RecurseOnUseStatements ) { + // System.err.print("name in constructor:" ); + // System.err.println( name ); + ext = new ExtCell(name, subcellNameToDefnMap); + this.extPath = extPath; + this.subcellNameToDefnMap = subcellNameToDefnMap; + m_RecurseOnUseStatements = RecurseOnUseStatements ; + } + + /** + * Constructs an ExtFileFormatException with the appropriate parameters. + * When the constructor of ExtFileFormatException changes its mind + * about what it wants, only this method needs to change. + **/ + private ExtFileFormatException extFileFormatException( + final String message) + { + return (ExtFileFormatException) new ExtFileFormatException(message, + ext.getName(), lineNumber, line); + } + + /** + * Constructs an ExtFileFormatException with the appropriate parameters. + * When the constructor of ExtFileFormatException changes its mind + * about what it wants, only this method needs to change. + **/ + private ExtFileFormatException extFileFormatException( + final String message, final Exception cause) + { + return new ExtFileFormatException + (message, ext.getName(), lineNumber, line, cause); + } + + /** + * Ensures that the words array has n words, throws an exception if this + * is not the case. + **/ + private void ensureNumWords(final String[] words, + final int n) + throws ExtFileFormatException + { + if (words.length != n) + throw extFileFormatException("Bad token count, " + n + + " tokens expected " + words.length + " found"); + } + + /** + * Ensures that we are parsing the environment section of the .ext file, + * throws an exception if this is not the case. Should be called + * whenever parsing an environmental directive. + **/ + private void ensureEnv() + throws ExtFileFormatException + { + if (!env) + throw extFileFormatException("Environment directive found" + + " after non-environment directive"); + } + + /** + * Ensures that the environment directives have been specified. + * Should be called whenever parsing a non-environment directive. + **/ + private void ensureEnvSpecified(final String technology, + final Date timestamp, + final String version, + final String style, + final double[] resistanceClasses) + throws ExtFileFormatException + { + if (technology == null) + throw extFileFormatException("Technology not specified"); + else if (timestamp == null) + throw extFileFormatException("Timestamp not specified"); + else if (version == null) + throw extFileFormatException("Version not specified"); + else if (style == null) + throw extFileFormatException("Style not specified"); + else if (resistanceClasses.length == 0) + throw extFileFormatException("Resistclass not specified"); + } + + // Generic datatype parsing //////////////////////////////////////////// + + /** + * Parses a string into a double. + **/ + private double parseDouble(final String s, + final String message) + throws ExtFileFormatException + { + try { + return Double.parseDouble(s); + } catch (NumberFormatException e) { + throw extFileFormatException(message, e); + } + } + + /** + * Parses a string into an int. + **/ + private int parseInt(final String s, + final String message) + throws ExtFileFormatException + { + try { + return Integer.parseInt(s); + } catch (NumberFormatException e) { + throw extFileFormatException(message, e); + } + } + + /** + * Parses a string into an Integer. + **/ + private Integer parseInteger(final String s, + final String message) + throws ExtFileFormatException + { + try { + return Integer.valueOf(s); + } catch (NumberFormatException e) { + throw extFileFormatException(message, e); + } + } + + /** + * Parses n alternate doubles from the words array, starting at index + * startField. + **/ + private double[] parseAltDoubles(final String[] words, + final int n, + final int startField, + final double multiplier, + final String errorMsg) + throws ExtFileFormatException + { + // check for num fields + if (words.length < startField + 2 * (n - 1)) + throw extFileFormatException("Not enough fields"); + + final double[] ds = new double[n]; + + for (int i = 0; i < n; ++i) { + final int j = startField + 2 * i; + ds[i] = parseDouble(words[j], "Field " + j + ": " + errorMsg) + * multiplier; + } + + return ds; + } + + // Unit Parsing //////////////////////////////////////////////////////// + + // Capacitance + + /** + * Parses a string with a capacitance in attofarads into a capacitance + * in farads. + **/ + private double parseCapacitance(final String s, final String message) + throws ExtFileFormatException + { + try { + return parseDouble(s, message) * attoFarads * cscale; + } catch (NumberFormatException e) { + throw extFileFormatException(message, e); + } + } + + /** + * Parses a string with a capacitance in attofarads into a capacitance + * in farads. + **/ + private double parseCapacitance(final String s) + throws ExtFileFormatException + { + return parseCapacitance(s, "Bad capacitance: " + s); + } + + // Resistance + + /** + * Parses a string with a resistance in milliohms into a resistance + * in ohms. + **/ + private double parseResistance(final String s, final String message) + throws ExtFileFormatException + { + try { + return parseDouble(s, message) * milliOhms * rscale; + } catch (NumberFormatException e) { + throw extFileFormatException(message, e); + } + } + + /** + * Parses a string with a resistance in milliohms into a resistance + * in ohms. + **/ + private double parseResistance(final String s) + throws ExtFileFormatException + { + return parseResistance(s, "Bad resistance: " + s); + } + + // Length + + /** + * Parses a string with a length in centimicrons into a length in + * meters. + **/ + private double parseLength(final String s, final String message) + throws ExtFileFormatException + { + try { + return parseDouble(s, message) * centiMicrons * lscale; + } catch (NumberFormatException e) { + throw extFileFormatException(message, e); + } + } + + /** + * Parses a string with a length in centimicrons into a length in + * meters. + **/ + private double parseLength(final String s) + throws ExtFileFormatException + { + return parseLength(s, "Bad length: " + s); + } + + private double[] parseAltLengths(final String[] words, + final int n, + final int startField, + final String errorMsg) + throws ExtFileFormatException + { + return parseAltDoubles(words, n, startField, centiMicrons * lscale, + errorMsg); + } + + // Area + + /** + * Parses a string with an area in square centimicrons into an area + * in square meters. + **/ + private double parseArea(final String s, final String message) + throws ExtFileFormatException + { + try { + return parseDouble(s, message) * squareCentiMicrons + * lscale * lscale; + } catch (NumberFormatException e) { + throw extFileFormatException(message, e); + } + } + + /** + * Parses a string with an area in square centimicrons into an area + * in square meters. + **/ + private double parseArea(final String s) + throws ExtFileFormatException + { + return parseArea(s, "Bad area: " + s); + } + + private double[] parseAltAreas(final String[] words, + final int n, + final int startField, + final String errorMsg) + throws ExtFileFormatException + { + return parseAltDoubles(words, n, startField, + squareCentiMicrons * lscale * lscale, errorMsg); + } + + /** + * Strips quotes from the beginning and end of a name, throwing an + * exception if they are not there. Ie maps "foo" -> foo. + **/ + private String parseQuoted(final String s) + throws ExtFileFormatException + { + if (s.length() < 3) + throw extFileFormatException("name too short: " + s); + else if (s.charAt(0) != '"') + throw extFileFormatException("name does not start with \": "+ s); + else if (s.charAt(s.length() - 1) != '"') + throw extFileFormatException("name does not end with \": " + s); + else // strip quotes + return s.substring(1, s.length() - 1); + } + + private HierName makeHierName(String name) + throws ExtFileFormatException + { + try { + // don't map / to . + // name = StringUtil.replaceChars(name, PATH_SEPARATOR, '.'); + return HierName.makeHierName(name, '.'); + } catch (InvalidHierNameException e) { + throw extFileFormatException("Invalid name: " + + e.getMessage(), e); + } + } + + /** + * Strips quotes from the beginning and end of a name, throwing an + * exception if they are not there. Ie maps "foo" -> foo. + * @todo jmr XXX rename to to parseNodeName + **/ + private HierName parseName(final String s) + throws ExtFileFormatException + { + // strip quotes + final String name = parseQuoted(s); + + // @design jmr move this into ExtCell, perhaps? + return makeHierName(name); + } + + /** + * Parses a range specification for a use line of the form lo:hi:sep . + **/ + private int[] parseUseRange(final String s) + throws ExtFileFormatException + { + int[] a = new int[2]; + + final int colon1Idx = s.indexOf(':'); + final int colon2Idx = s.indexOf(':', colon1Idx + 1); + + if (colon1Idx == -1 || colon2Idx == -1) + throw extFileFormatException("Bad range spec: " + s); + + try { + a[0] = Integer.parseInt(s.substring(0, colon1Idx)); + a[1] = Integer.parseInt(s.substring(colon1Idx + 1, colon2Idx)); + Integer.parseInt(s.substring(colon2Idx + 1)); + } catch (final NumberFormatException e) { + throw extFileFormatException("Bad range spec, number format: " + + s, e); + } + + return a; + } + + /** + * Parses the useID in a use line, returning an {@link ArraySpec}. + * useID may be of the form use or use[xlo:xhi:xsep][ylo:yhi:ysep]. + * Yes, lo:hi:sep, contrary to the lo,hi,sep indicated in ext(5). + **/ + private ArraySpec parseUseSpec(final String useID) + throws ExtFileFormatException + { + // find first [ + final int xOpen = useID.indexOf('['); + + if (xOpen == -1) { + // there is no array + return new ArraySpec(useID, "", 1, 1, false, 1, 1, false); + } else { + // find ] + final int xClose = useID.indexOf(']', xOpen); + + try { + // substring will throw IndexOutOfBoundsException + // if an indexOf returns -1 + + final int[] xRange + = parseUseRange(useID.substring(xOpen + 1, xClose)); + + if (useID.charAt(xClose + 1) != '[' + || useID.charAt(useID.length() - 1) != ']') + throw extFileFormatException("Bad useID: " + useID); + + final int[] yRange = parseUseRange( + useID.substring(xClose + 2, useID.length() - 1)); + + return new ArraySpec(useID.substring(0, xOpen), "", + xRange[0], xRange[1], xRange[0] != xRange[1], + yRange[0], yRange[1], yRange[0] != yRange[1]); + } catch (final IndexOutOfBoundsException e) { + throw extFileFormatException("Bad useID: " + useID, e); + } + } + } + + /** + * Parses the subcell array specifier component of a merge line, + * returning an {@link ArraySpec}. + * mergePath may be in one of the four forms: + *
      + *
    • "" (the empty string), if it is a node in the cell + *
    • sub + *
    • sub[lo:hi] + *
    • sub[xlo:xhi,ylo:yhi] + *
    + **/ + private ArraySpec parseMergeSpec(final String mergePath) + throws ExtFileFormatException + { + final int openBracket = mergePath.indexOf('['); + + if (openBracket == -1) { + // no open bracket, make sure there is no close bracket + if (mergePath.indexOf(']') != -1) + throw extFileFormatException("Bad merge path: " + + mergePath); + return new ArraySpec(mergePath, "", 1, 1, false, 1, 1, false); + } else { + // find ] + final int closeBracket = mergePath.indexOf(']'); + + // make sure ] is at end of string + if (closeBracket != mergePath.length() - 1) + throw extFileFormatException("Bad merge path: " + mergePath); + + try { + // substring will throw IndexOutOfBoundsException + // if an indexOf returns -1 + + final String spec + = mergePath.substring(openBracket + 1, closeBracket); + + final int commaIdx = spec.indexOf(','); + + final boolean xIsArray; + final int[] xRange; + final int[] yRange; + if (commaIdx == -1) { + // there is no comma, it is a 1-d spec + xIsArray = false; + xRange = new int[]{1, 1}; + yRange = parseMergeRange(spec); + } else { + // there is a comma, it is a 2-d spec + xIsArray = true; + xRange = parseMergeRange(spec.substring(0, commaIdx)); + yRange = parseMergeRange(spec.substring(commaIdx + 1)); + } + + final String pre = mergePath.substring(0, openBracket); + + return new ArraySpec(pre, "", + xRange[0], xRange[1], xIsArray, + yRange[0], yRange[1], true); + } catch (final IndexOutOfBoundsException e) { + throw extFileFormatException("Bad merge path: " + mergePath, e); + } + } + } + + /** + * Parses ranges for array specifications. The format is + *
    +     *   range ::= number | number:number
    +     * 
    + **/ + private int[] parseMergeRange(final String s) + throws ExtFileFormatException + { + // do we have a : ? + final int colonIndex = s.indexOf(':'); + + if (colonIndex == -1) { + final int n = parseInt(s, "Bad single range: " + s); + return new int[]{n,n}; + } else { + final String startString = s.substring(0, colonIndex); + final String endString = s.substring(colonIndex + 1); + + final int start = parseInt(startString, + "Bad range start: " + startString); + final int end = parseInt(endString, "Bad range end: " + + endString); + + return new int[]{start, end}; + } + } + + /** + * Splits a path from a merge line into subcell and node path. + * Splits a path of the form a/b/c/d into {a, /b/c/d}. + * Splits a path of the form a into {"", a} + **/ + public String[] splitMergePath(final String s) { + final int slashIdx = s.indexOf('/'); + + if (slashIdx == -1) + return new String[]{"", s}; + else + return new String[]{ + s.substring(0, slashIdx), + s.substring(slashIdx)}; + } + + /** + * Parses a terminal for a fet line. + **/ + private Terminal parseTerminal(final String[] words, + final int startIndex, + final String terminalName) + throws ExtFileFormatException + { + final HierName name = parseName(words[startIndex]); + final double length = parseLength(words[startIndex + 1], + "bad gate length " + words[startIndex + 1] + " for " + + terminalName); + final String attributes = words[startIndex + 2]; + + if (!"0".equals(attributes)) + throw extFileFormatException("Attributes unsupported: " + + words[startIndex + 2] + ", in " + terminalName); + + return new Terminal(name, length); + } + + /** + * Converts sparse array names and comma separated array names. + * @review jmr XXX is this right? what do we need to do for + * node names vs. subcell names? + **/ + public static String convertArrays(final String s) { + + // this name has array elements expanded into + // foo[x][y]. We want this to be transformed + // into foo[x,y]. We also may have a sparse + // array like foo(v)(w)[x,y]. This should + // be transformed to foo[v,w,x,y] + // So, we perform + // two steps: + // 1: change ( to [ and ) to ] + // 2: change ][ to , + + // @bug jmr XXX If we have parens in a non-sparse + // array meaning, they will be mapped, too. + // Is this ok? + + // step 1 + final StringBuffer noParens + = StringUtil.replaceChars(new StringBuffer(s), "()", "[]"); + + // step 2 + final String fixedUse + = StringUtil.replaceSubstring(noParens, "][", ",").toString(); + + return fixedUse; + } + + /** + * parses an ExtCell from the given file. Searches using the extPath + * search path. + **/ + public void parseFile(final String fileName) + throws ExtFileFormatException, IOException + { + // System.out.print( "File name in parseFile:" ); + // System.out.println( fileName ); + parseStream(extPath.openFileAsStream(fileName)); + } + + /** + * Parses a .ext file. + **/ + public void parseStream(final InputStream in) + throws ExtFileFormatException, IOException + { + final BufferedReader + br = new BufferedReader(new InputStreamReader(in)); + + while ((line = br.readLine()) != null) { + ++lineNumber; + final String[] words = StringUtil.split(line, ' '); + + if (words.length == 0) + throw extFileFormatException("Found empty line"); + + if ("tech".equals(words[0])) { + // tech techname + ensureEnv(); + ensureNumWords(words, 2); + + technology = words[0]; + } else if ("timestamp".equals(words[0])) { + // timestamp time + ensureEnv(); + ensureNumWords(words, 2); + + if (timestamp != null) + throw extFileFormatException("Duplicate timestamp"); + + // value in file is seconds since 1970, Date constructor + // takes milliseconds + timestamp = new Date(Long.parseLong(words[1]) * 1000); + } else if ("version".equals(words[0])) { + // version version + ensureEnv(); + ensureNumWords(words, 2); + + if (version != null) + throw extFileFormatException("Duplicate versions"); + + version = words[1]; + } else if ("style".equals(words[0])) { + // style style + ensureEnv(); + ensureNumWords(words, 2); + + if (style != null) + throw extFileFormatException("Duplicate styles"); + + style = words[1]; + } else if ("scale".equals(words[0])) { + // scale rscale cscale lscale + ensureEnv(); + ensureNumWords(words, 4); + + if (scalesSet) + throw extFileFormatException("Duplicate scales"); + + scalesSet = true; + rscale = parseInt(words[1], "Bad rscale: " + words[1]); + cscale = parseInt(words[2], "Bad cscale: " + words[2]); + lscale = parseInt(words[3], "Bad lscale: " + words[3]); + } else if ("resistclasses".equals(words[0])) { + // resistclasses r1 r2 ... + // however, we only care about the first two: + // ndiff and pdiff + ensureEnv(); + + if (resistanceClasses.length != 0) + throw extFileFormatException("Duplicate resistclass"); + + numResistClasses = words.length - 1; + + // there must be at least one resistclass + if (numResistClasses < 1) + throw extFileFormatException( + "No resistance classes specified"); + + resistanceClasses = new double[NUM_IMPORTANT_RESIST_CLASSES]; + + for (int i = 0; i < resistanceClasses.length; ++i) { + resistanceClasses[i] = parseResistance(words[i + 1]); + } + } else if ("node".equals(words[0])) { + // node name R C x y type a1 p1 a2 p2 ... aN pN + // 0 1 2 3 4 5 6 7 + env = false; + + ensureNumWords(words, 7 + 2 * numResistClasses); + + final HierName name = parseName(words[1]); + // lumped resistance is ignored, as it is useless + final double r = parseResistance(words[2], + "Bad resistance: " + words[2]); + final double c = parseCapacitance(words[3], + "Bad capacitance: " + words[3]); + final double x = parseLength(words[4], + "Bad x: " + words[4]); + final double y = parseLength(words[5], + "Bad y: " + words[5]); + /* @todo jmr XXX replace this with a flag or something */ + final String type = words[6]; + + final double[] rcas = parseAltAreas(words, + NUM_IMPORTANT_RESIST_CLASSES, 7, + "Bad resistance class area"); + final double[] rcps = parseAltLengths(words, + NUM_IMPORTANT_RESIST_CLASSES, 8, + "Bad resistance class perimeter"); + + final Node protoNode = new Node(name, c, rcps, rcas); + + + try { + ext.addData(name, protoNode); + } catch (AliasedMap.MergeFailedException e) { + throw extFileFormatException("Internal error: " + + e.getMessage(), e); + } + + } else if ("attr".equals(words[0])) { + // attr name xl yl xh yh type text + env = false; + ensureNumWords(words, 8); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + throw extFileFormatException("attr unsupported"); + } else if ("equiv".equals(words[0])) { + // equiv node1 node2 + env = false; + ensureNumWords(words, 3); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + final HierName node1 = parseName(words[1]); + final HierName node2 = parseName(words[2]); + + try { + ext.connectNames(node1, node2); + } catch (AliasedMap.MergeFailedException e) { + throw extFileFormatException("Internal error: " + + e.getMessage(), e); + } + } else if ("fet".equals(words[0])) { + // fet type xl yl xh yh area perim sub GATE T1 T2 + // 0 1 2 3 4 5 6 7 8 9-11 12-14 15-17 + // or + // fet type xl yl xh yh area perim sub GATE T1 + // 0 1 2 3 4 5 6 7 8 9-11 12-14 + env = false; + + // fet lines will have 15 or 18 words, depending on whether + // or not it is degenerate. + // If it is degenerate, make source = drain. + if (words.length != 15 && words.length != 18) + throw extFileFormatException( + "Bad token count, expected 15 or 18, got " + + words.length); + + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + final int type; + if ("pfet".equals(words[1])) + type = DeviceTypes.P_TYPE; + else if ("nfet".equals(words[1])) + type = DeviceTypes.N_TYPE; + else + throw extFileFormatException("Bad fet type: " + + words[1]); + + // ignore xl, yl, xh, yh + + final double area = parseArea(words[6], "bad area: " + + words[6]); + final double perim = parseLength(words[7], "bad perim: " + + words[7]); + final HierName sub = parseName(words[8]); + + final Terminal gate = parseTerminal(words, 9, "gate"); + final Terminal source = parseTerminal(words, 12, "source"); + final Terminal drain; + + // for degenerate fets, make drain = source + // otherwise, parse drain + if (words.length == 15) + drain = source; + else + drain = parseTerminal(words, 15, "drain"); + + final FET fet = new FET(type, + area, perim, sub, gate, source, drain); + + ext.addFET(fet); + } else if ("killnode".equals(words[0])) { + // killnode node + env = false; + ensureNumWords(words, 2); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + // XXX support soon + throw extFileFormatException("killnode unsupported"); + } else if ("resist".equals(words[0])) { + // resist node1 node2 R + env = false; + ensureNumWords(words, 4); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + final String node1 = words[1]; + final String node2 = words[2]; + final double r = parseResistance(words[3], + "Bad resistance: " + words[3]); + + Debug.assertTrue(false); + + /** @bug XXX **/ + + // pairToResistanceMap.put(new AliasPair(node1, node2), + // new Double(r)); + } else if ("distance".equals(words[0])) { + // distance name1 name2 dmin dmax + env = false; + ensureNumWords(words, 5); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + throw extFileFormatException("distance unsupported"); + } else if ("use".equals(words[0])) { + // use def use-id ta tb tc td te tf + // 0 1 2 3 4 5 6 7 8 + env = false; + ensureNumWords(words, 9); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + final String def = words[1]; + final String useID = words[2]; + + // parse the useID, which may be of the form use or + // use[xlo,xhi,xsep_centimicron][ylo,yhi,ysep_centimicron] + final ArraySpec arraySpec = parseUseSpec(useID); + + if ( m_RecurseOnUseStatements ) { + // if not parsed, parse the subcell definition + ExtCell subExt = (ExtCell) subcellNameToDefnMap.get(def); + + if (subExt == null) { + final ExtParser p + = new ExtParser(def, extPath, subcellNameToDefnMap, true); + p.parseFile(def + ".ext"); + subExt = p.getExtCell(); + // parsing will add it to subcellNameToDefnMap + } + + final ExtCell e = subExt; + arraySpec.mapNames(new UnaryAction() { + public void execute(final Object o) { + final String use = convertArrays((String) o); + + // add the cell to the list of used cells + ext.addSubcell(use, e); + } + }); + } + + } else if ("merge".equals(words[0])) { + // merge path1 path2 C a1 p1 a2 p2 ... aN pN + // 0 1 2 3 + // or + // merge path1 path2 + // 0 1 2 + env = false; + + if (words.length != 3 + && words.length != (4 + 2 * numResistClasses)) + throw extFileFormatException("Bad token count for merge"); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + // @bug jmr XXX need to handle global ! + final String path1 = parseQuoted(words[1]); + final String path2 = parseQuoted(words[2]); + + final double c; + final double[] rcas; + final double[] rcps; + + if (words.length == 3) { + // If there are no merge info given, make all 0's + + c = 0.0; + + // share the same array + rcas = new double[resistanceClasses.length]; + rcps = rcas; + + for (int i = 0; i < rcas.length; ++i) + rcas[i] = 0.0; + } else { + c = parseCapacitance(words[3], "Bad capacitance: " + + words[3]); + + rcas = parseAltAreas(words, + NUM_IMPORTANT_RESIST_CLASSES, 4, + "Bad merge area"); + rcps = parseAltLengths(words, + NUM_IMPORTANT_RESIST_CLASSES, 5, + "Bad merge perimeter"); + } + + // split paths into subcellSpec and path + final String[] p1 = splitMergePath(path1); + final String[] p2 = splitMergePath(path2); + + final ArraySpec path1Spec = parseMergeSpec(p1[0]); + final ArraySpec path2Spec = parseMergeSpec(p2[0]); + + // verify that the arrays are of compatible sizes + // this may not correctly handle merge of a 1-d array + // and a 2-d array. What is the spec for that? + final int nx1 = path1Spec.getXSize(); + final int nx2 = path2Spec.getXSize(); + final int ny1 = path1Spec.getYSize(); + final int ny2 = path2Spec.getYSize(); + + if (nx1 != nx2 || ny1 != ny2) { + throw extFileFormatException( + "Array sizes do not agree"); + } + + // make a node for the merged nodes, give the node + // two names for the connected labels, regardless + // of whether they are sub/a b or sub1/a sub2/b + + for (int ix = 0; ix < nx1; ++ix) + for (int iy = 0; iy < ny1; ++iy) { + final HierName name1 = makeHierName( + convertArrays(path1Spec.genName( + path1Spec.getXLo() + ix, + path1Spec.getYLo() + iy)) + p1[1]); + final HierName name2 = makeHierName( + convertArrays(path2Spec.genName( + path2Spec.getXLo() + ix, + path2Spec.getYLo() + iy)) + p2[1]); + + final Node node = new Node(name1, c, rcps, rcas); + + try { + /* + if (c != 0.0 + || rcps[0] != 0.0 || rcps[1] != 0.0 + || rcas[0] != 0.0 || rcas[1] != 0.0) + */ + ext.addData(name1, node); + ext.connectNames(name1, name2); + } catch (AliasedMap.MergeFailedException e) { + throw extFileFormatException( + "Internal error: " + e.getMessage(), e); + } + } + + } else if ("cap".equals(words[0])) { + // cap node1 node2 C + env = false; + ensureNumWords(words, 4); + ensureEnvSpecified(technology, timestamp, version, style, + resistanceClasses); + + final HierName node1 = parseName(words[1]); + final HierName node2 = parseName(words[2]); + final double c = parseCapacitance(words[3], + "Bad capacitance: " + words[3]); + + ext.addCapacitor(new Capacitor(node1, node2, c)); + } else { + throw extFileFormatException("Unrecognized directive: " + + words[0]); + } + + } + + // XXX: check to make sure that hierarchical names referenced + // are valid, ie that any subcells are actually there + + // XXX: many more validity checks + + // now that the file is parsed, add it to the global repository + subcellNameToDefnMap.put(ext.getName(), ext); + + } + + /** + * Retrieve the parsed ExtCell. + **/ + public ExtCell getExtCell() { + return ext; + } + + /** + * Parses the file cellName.ext into an ExtCell. + **/ + public static ExtCell parse(final String cellName, + final FileSearchPath extPath, + boolean RecurseOnUseStatements ) + throws ExtFileFormatException, IOException + { + final ExtParser p = new ExtParser(cellName, extPath, RecurseOnUseStatements); + System.out.print( "Cell name in parse:" ); + System.out.println( cellName ); + p.parseFile(cellName + ".ext"); + return p.getExtCell(); + } + + public static ExtCell parse( final String cellName, + final String extFileName, + final FileSearchPath extPath, + boolean RecurseOnUseStatements ) + throws ExtFileFormatException, IOException + { + final ExtParser p = new ExtParser( cellName, extPath, RecurseOnUseStatements ); + p.parseFile( extFileName ); + return p.getExtCell(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SimulatorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SimulatorInterface.java new file mode 100644 index 0000000000..001bca3e75 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SimulatorInterface.java @@ -0,0 +1,33 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.spice; + +/** + * Class for passing parsed commands from the spice parser to a general 'simulator' + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface SimulatorInterface { + void printStatement(String type, String[] args) + throws SpiceFileFormatException; +// void voltageSourceStatement(String name, String plusnode, +// String minusnode, String args[]) throws SpiceFileFormatException; + //void currentSourceStatement(String name, String plusnode, + //String minusnode, String args[]); + void setStatement(String key, String value) + throws SpiceFileFormatException; +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceFileFormatException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceFileFormatException.java new file mode 100644 index 0000000000..b5fc85fc2e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceFileFormatException.java @@ -0,0 +1,33 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.spice; + +/** + * Class to represent exceptions in parsing of .cdl files. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class SpiceFileFormatException extends Exception { + public SpiceFileFormatException(final String message) { + super(message); + } + public SpiceFileFormatException(final String message, + final Throwable cause) { + super(message, cause); + } + public SpiceFileFormatException(final Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceParser.java b/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceParser.java new file mode 100644 index 0000000000..964b263137 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/file/spice/SpiceParser.java @@ -0,0 +1,1016 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.file.spice; + +import java.io.FileReader; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.StringTokenizer; + +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.circuit.Diode; +import com.avlsi.circuit.Resistor; +import com.avlsi.circuit.Transistor; +import com.avlsi.circuit.Capacitor; +import com.avlsi.circuit.Source; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.ext.parse.ExtParser; +import com.avlsi.io.PositionStackReader; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.text.StringUtil; + +import com.avlsi.circuit.AbstractCircuit; + + +/** + * Parses spice extract files into an {@link com.avlsi.file.aspice.AspiceCell} + * repository. + * + * @see com.avlsi.file.aspice.AspiceCell + * + * @author Abe Ankumah/Jesse Rossenstock + * @version $Revision$ $Date$ + * + **/ +public final class SpiceParser { + + /** + * parsing update callback class. update() will be called for + * every line processed. + **/ + public interface ParsingCallback { + void update(int lineNum); + } + + private char sepChar = '.'; + private String line = null; + private PositionStackReader reader = null; + + private AbstractCircuit.Repository repository; + private final Map resistorMap; + private final char subcellConnectionSeparatorChar; + private boolean assura_rcx_extract; + private boolean quiet; + private final ParsingCallback callback; + private final SimulatorInterface simulator; + + private int lineNum = 1; + + /** + * Class constructor. + * + * @param subcellConnectionSeparatorChar the character that + * should be used to separate the node name from the + * cell name in arguments to 'X' lines. + * @param resistorMap (may be null) a Map from resistor type + * (String) to rho (Double). When a subcircuit is encountered, + * the rho for the type is looked up in resistorMap, + * and a resistor is created with resistance rho * l / w. + * @param callback (may be null) a ParsingCallback class + * whose update() method will be called for every line + * processed. + * @param SimulatorInterface (may be null) an interface for passing + * simulator info inside the spice file to the simulator + **/ + public SpiceParser(final char subcellConnectionSeparatorChar, + final Map resistorMap, + final ParsingCallback callback, + final SimulatorInterface sim) { + this.subcellConnectionSeparatorChar = + subcellConnectionSeparatorChar; + this.resistorMap = resistorMap; + this.callback = callback; + this.simulator = sim; + } + + /** + * Class constructor. + * + * @param subcellConnectionSeparatorChar the character that + * should be used to separate the node name from the + * cell name in arguments to 'X' lines. + * @param resistorMap (may be null) a Map from resistor type + * (String) to rho (Double). When a subcircuit is encountered, + * the rho for the type is looked up in resistorMap, + * and a resistor is created with resistance rho * l / w. + * @param callback (may be null) a ParsingCallback class + * whose update() method will be called for every line + * processed. + **/ + public SpiceParser(final char subcellConnectionSeparatorChar, + final Map resistorMap, + final ParsingCallback callback) { + this.subcellConnectionSeparatorChar = + subcellConnectionSeparatorChar; + this.resistorMap = resistorMap; + this.callback = callback; + this.simulator = null; + } + /** + * Class constructor. + * + * @param subcellConnectionSeparatorChar the character that + * should be used to separate the node name from the + * cell name in arguments to 'X' lines. + * @param callback (may be null) a ParsingCallback class + * whose update() method will be called for every line + * processed. + **/ + public SpiceParser(final char subcellConnectionSeparatorChar, + final ParsingCallback callback) { + this(subcellConnectionSeparatorChar, null, callback,null); + } + + /** + * Class constructor. Uses '/' for subcell connection separator. + **/ + public SpiceParser() { + this('/', null, null,null); + } + + /** + * Map from cell name String to String[] + * representing names of ports. If a use has been seen, but no + * definition, then the value will be an array of String with the + * correct length seen in the uses, but nulls for the entries. If + * a definition has been seen, then the values will also be filled in. + **/ + private final Map cellPortMap = new TreeMap(); + + private SpiceFileFormatException fileFormatException(final String message) { + return new SpiceFileFormatException(message); + } + + private SpiceFileFormatException fileFormatException( + final String message, final Exception cause) { + return new SpiceFileFormatException(message, cause); + } + + /** + * Call this to enable Assura RCX parsing compatibility. Node + * names of the form 'Xblah/' are converted to 'blah.'. + **/ + public void setAssuraRCXParsing() { + assura_rcx_extract = true; + sepChar = '/'; + } + + /** + * Tells the parser to suppress warning output + * during parsing. + **/ + public void beQuiet() { quiet = true; } + + /** + * Tells the parser to print warning output + * during parsing. + **/ + public void beVerbose() { quiet = false; } + + /** + * Returns the number of lines parsed to date. + **/ + public int getLineCount() { return lineNum; } + + public void parseFile(final String fileName, + AbstractCircuit.Repository repos) + throws SpiceFileFormatException, IOException + { + this.repository = repos; + reader = new PositionStackReader(new BufferedReader( + new FileReader(fileName))); + + reader.savePosition(); + while ((line = nextLine()) != null) { + // skip empty lines + if (line.length() == 0) { + reader.discardPosition(); + reader.savePosition(); + continue; + } + + // skip comment lines + if (line.charAt(0) == '*') { + reader.discardPosition(); + reader.savePosition(); + continue; + } + + final String[] words = split(line); + + if (words[0].startsWith(".")) { + + if (".SUBCKT".equalsIgnoreCase(words[0])) { + reader.restorePosition(); + parseSubckt(); + reader.savePosition(); + } else if (".PARAM".equalsIgnoreCase(words[0]) || + ".GLOBAL".equalsIgnoreCase(words[0])) { + // ignore .PARAM & .GLOBAL + if (!quiet) + System.out.println("Ignoring "+words[0]); + reader.discardPosition(); + reader.savePosition(); + } else if (words[0].toUpperCase().startsWith(".OPTION")) { + //Example of this command: + // .OPTION TNOM=27 NOPAGE TIMEMAX=1e-9 + // it should ignore case, default value is one + // + for(int i = 1;i + //Example: .PRINT TRAN Vin Vout + if (words.length < 3) { + if (!quiet) + System.out.println("Not enough parameters for .PRINT, ignoring"); + } else if (simulator != null) { + String args[] = new String[words.length-2]; + System.arraycopy(words,2,args,0,args.length); + simulator.printStatement(words[1],args); + } + } */else { + + throw fileFormatException("Unknown directive " + + words[0] + " on line " + lineNum + + "; line is: " + line); + } + } + } + } + + /** + * Parses a .SUBCKT / .ENDS section into an AspiceFile, adding + * the parsed AspiceFile to the map of cells. It is an error if + * a cell of the same name as already been parsed. The stream + * position must be before the .PARAM. + **/ + private void parseSubckt() + throws SpiceFileFormatException, IOException { + + AbstractCircuit genericCell; + line = nextLine(); + String[] words = split(line); + // .SUBCKT subname output_node ... / input_node ... + // We treat input and output nodes the same + + Debug.assertTrue(".SUBCKT".equalsIgnoreCase(words[0])); + + // array[2] of Map from Pair of (source:HierName, drain:HierName) + // to double[4], representing + // diode info: {area, perim, width, length} + final Map[] diodeInfoMap = + new HashMap[]{new HashMap(), new HashMap()}; + + // the name will look like lib-BUF_1of2, this will not + // match the cast name which is just BUF_1of2, but in + // the future should change to lib/BUF_1of2 + final String cellType = unmangleType(words[1]); + + // ignore out any "/" to merge the input and output ports + String [] nodes = new String[words.length]; + int numDefPorts = 0; + int numSlashes = 0; + for (int i = 2; i < words.length; ++i) { + if ("/".equals(words[i])) numSlashes++; + else nodes[numDefPorts++] = words[i]; + } + if (numSlashes>1) + throw fileFormatException("More than one / in port list."); + + + // the rest of the params are the exported nest + String[] defPorts = (String[]) cellPortMap.get(cellType); + + if (defPorts != null) { + throw fileFormatException("Multiple definition of " + + cellType); + /* + * Don't allow use before definition because it complicates + * uses that occur before definition. + // check that the ports are compatable + if (numDefPorts != defPorts.length) + throw fileFormatException("Found .SUBCKT " + cellType + + " with " + numDefPorts + " ports, but earlier use " + + "had " + ports.length + " ports."); + + for (int i = 0; i < ports.length; ++i) + Debug.assertTrue(ports[i] == null); + */ + } else { + Debug.assertTrue(repository.getCell(cellType) == null); + // add the port list + defPorts = new String[numDefPorts]; + cellPortMap.put(cellType, defPorts); + } + + // fill in the right values for the port names + System.arraycopy(nodes, 0, defPorts, 0, numDefPorts); + + try { + genericCell = repository.newCell(cellType); + } + catch(AbstractCircuit.Exception e){ + throw fileFormatException("Cell is already defined", e); + } + + // add names, also handling globals + for (int i = 0; i < numDefPorts; ++i) + genericCell.addName(parseNodeName(defPorts[i])); + + while ((line = nextLine()) != null) { + words = split(line); + if (Character.toUpperCase(words[0].charAt(0)) == 'M') { + // mosfet + // Mxxx drain gate source bulk mname W=width L=length + // [ M=mag + // | as=source_area ps=source_perim + // ad=drain_area pd=draim_perim ] + // {a,p}{s,d} are floating point numbers x.yye-zz + + final HierName name = parseNodeName(words[0]); + final HierName drain = parseNodeName(words[1]); + final HierName gate = parseNodeName(words[2]); + final HierName source = parseNodeName(words[3]); + final HierName bulk = parseNodeName(words[4]); + final int type = parseType(words[5]); + + if (findLastNonParm(words) > 5) + throw fileFormatException("Wrong # of non-params " + + "for mosfet."); + + double width = -1.0; + double length = -1.0; + double[] area = new double[2]; + double[] perim = new double[2]; + area[0] = -1.0; + area[1] = -1.0; + perim[0] = -1.0; + perim[1] = -1.0; + + for (int i=6; i 4 && words[4].startsWith("M=") && + !"M=1".equalsIgnoreCase(words[4])) + throw fileFormatException("Can only support M=1, " + +" got " + words[4]); + + genericCell.addCapacitor(new Capacitor(name, npositive, + nminus, cap)); + } + else if (!quiet) + System.err.println("Warning: Ignoring 'Inf' capacitance."); + + } else if (Character.toUpperCase(words[0].charAt(0)) == 'D') { + // diode + // Dxxx npositive nminus mname {area} {M=multiplier} + // {periphery} {$SUB=substrate} + // + // Mname must contain exactly one of 'N' or 'P'. + // Area and periphery are optional in spice, but required here. + // Multiplier must be 1. + // Substrate is ignored here. + + // XXX: note that these diodes will not be combined with + // those created via as=, ... on 'M' lines. + + if (words.length < 7) { + throw fileFormatException("Too few fields for " + + "diode. Expected 7, got " + words.length); + } + final HierName name = parseNodeName(words[0]); + final HierName npositive = parseNodeName(words[1]); + final HierName nminus = parseNodeName(words[2]); + final boolean isNType = (words[3].indexOf('N') >= 0); + final boolean isPType = (words[3].indexOf('P') >= 0); + final double area = parseDouble(words[4], "area"); + final String multiplier = words[5]; + final double periphery = parseDouble(words[6], "periphery"); + int type; + + if (isNType == isPType) { + throw fileFormatException("Mname argument for diode " + + "must contain exactly one of 'N' or 'P'. Got " + + words[3]); + } + + type = isNType ? DeviceTypes.N_TYPE : DeviceTypes.P_TYPE; + + if (!"M=1".equalsIgnoreCase(multiplier)) + throw fileFormatException("Can only support M=1, " + + " got " + multiplier); + + final double width = (periphery + + java.lang.Math.sqrt(periphery * periphery + - 4 * area)) / 2; + final double length = area / width; + + genericCell.addDiode(new Diode(name,type, npositive, nminus, + width, length, area, periphery)); + } else if (Character.toUpperCase(words[0].charAt(0)) == 'R') { + // resistor + // Rxxx term1 term2 {res} {$SUB=substrate} {M=multiplier} + // {$[mname] / $.MODEL=mname} {$W=width} {$L=length} + // + // Res is optional in .spice, but required here. + // All arguments after res are ignored here. + + if (words.length < 4) { + throw fileFormatException("Too few fields for " + + "resistor. Expected 4, got " + words.length); + } + final HierName name = parseNodeName(words[0]); + final HierName term1 = parseNodeName(words[1]); + final HierName term2 = parseNodeName(words[2]); + final double res = parseDouble(words[3], "resistance"); + + genericCell.addResistor(new Resistor(name,term1, term2, 1/res)); + } else if (Character.toUpperCase(words[0].charAt(0)) == 'V') { + // Voltage Source call + // Vxxx type n+ n- args1 args2 ... argsN + // Number of args checked by source call to AbstractCircuit + if (words.length < 4) { + throw fileFormatException("Too few fields for " + +"V source. Expected 4 or more, got "+words.length); + } + final HierName name = parseNodeName(words[0]); + final HierName pterm = parseNodeName(words[1]); + final HierName nterm = parseNodeName(words[2]); + String[] args = null; + if (words.length != 4) { + args = new String[words.length-4]; + System.arraycopy(words,4,args,0,args.length); + } + try { + genericCell.addSource(new Source(name, words[3], + pterm,nterm, + args)); + } catch (AbstractCircuit.Exception e) { + System.out.println(e.getMessage()); + } + } else if (Character.toUpperCase(words[0].charAt(0)) == 'X') { + // subcircuit call + // cdl: Xyyy node1 ... / subname + // spice: Xyyy node1 node2 ... nodeN subname + // parm1=v2 parm2=v2 ... + if (words.length < 2) + throw fileFormatException("Too few arguments for " + + "subcircuit call " + words[0]); + + final String instanceNameString = + ExtParser.convertArrays(words[0].substring(1)); + final HierName instanceName; + try { + instanceName = + HierName.makeHierName(instanceNameString, sepChar); + } catch (InvalidHierNameException e) { + throw new AssertionFailure(e); + } + final String slash = words[words.length - 2]; + final boolean isCDL = "/".equals(slash); + final int typeIdx = findLastNonParm(words); + final String subcellType = unmangleType(words[typeIdx]); + + // param names are in words[1..typeIdx-2] if there is + // a /, or words[1..typeIdx-1] if there is not + final int numUsePorts = + isCDL ? typeIdx - 2 : typeIdx - 1; + final Double rho = resistorMap == null ? + null : (Double) resistorMap.get(subcellType); + if (rho != null) { + // resistor type + if (numUsePorts != 2) { + throw fileFormatException("Found " + + numUsePorts + " for resistor, not 2:" + + line); + } + + if (typeIdx != words.length - 3) { + throw fileFormatException("Found " + numUsePorts + + " params for resistor, not 2." + line); + } + + Debug.assertTrue(typeIdx == 3); + + final HierName name = parseNodeName(words[0]/*.substring(1)*/); + final HierName t1 = parseNodeName(words[1]); + final HierName t2 = parseNodeName(words[2]); + final double width = + parseParam(words[typeIdx + 1], "w=", + "resistor width"); + final double length = + parseParam(words[typeIdx + 2], "l=", + "resistor length"); + final double res = rho.doubleValue() * (length / width); + + genericCell.addResistor(new Resistor(name,t1, t2, 1/res)); + } else { + // normal type + String[] ports = (String[]) cellPortMap.get(subcellType); + + if (ports != null) { + // check that number of ports is right + if (numUsePorts != ports.length) + throw fileFormatException("Subcell use " + + words[0] + " with " + numUsePorts + + " ports, but definition had " + + ports.length + " ports."); + } else { + throw fileFormatException("Subcell use " + + words[0] + " of type " + subcellType + + " without preceding .SUBCKT"); + /* + * Don't bother with this, how would we know + * what to connect to? + // add dummy port list to record number of ports + cellPortMap.put(subcellType, ports); + */ + } + + // add subcell + genericCell.addSubcell(instanceNameString, + repository.getCell(subcellType)); + + // process connections to ports + for (int i = 0; i < numUsePorts; ++i) { + final HierName port = parseNodeName(ports[i]); + final HierName param = parseNodeName(words[i + 1]); + + try { + // use / or . as separator + // THIS NEEDS TO BE FIXED TO USE sepChar! -mid + genericCell.aliasNames(param, + HierName.makeHierName( + instanceName.getAsString('.') + + subcellConnectionSeparatorChar + + port.getAsString('.'), '.')); + } catch (InvalidHierNameException e) { + throw new AssertionFailure(e); + } + } + } + + } else if (".ENDS".equalsIgnoreCase(words[0])) { + // now add the diodes that were collected from 'M' lines + for (int itype = 0; itype < 2; ++itype) { + for (final Iterator iEntry = + diodeInfoMap[itype].entrySet().iterator(); + iEntry.hasNext(); ) { + final Entry e = (Entry) iEntry.next(); + final Pair p = (Pair) e.getKey(); + final double[] diodeInfo = (double[]) e.getValue(); + final HierName source = (HierName) p.getFirst(); + final HierName drain = (HierName) p.getSecond(); + final double width = diodeInfo[2]; + final double length = diodeInfo[3]; + final double area = diodeInfo[0]; + final double perim = diodeInfo[1]; + genericCell.addDiode(new Diode(null,itype, source, drain, + width, length, area, perim)); + } + } + + //aspiceCellRepos.put(cellType, aspiceCell); + return; + } else { + throw fileFormatException("Unknown line type: " + line); + } + } + + // we should not reach eof in a subcircuit + throw fileFormatException("reached EOF in .SUBCKT"); + } + + /** + * Reads a line, returning it, or null if end of stream has been reached. + * The final '\n' is not returned. + **/ + private String readLine() throws IOException { + final StringBuffer sb = new StringBuffer(); + int ch; + + while ((ch = reader.read()) != -1) { + if (ch == '\n') { + lineNum++; + break; + } + + sb.append((char) ch); + } + + if (ch == -1 && sb.length() == 0) + return null; + else + return sb.toString(); + } + + /** + * Reads a line, handling line concatenation via '+'. Final '\n' is + * not returned. + **/ + private String readContinuedLine() throws IOException { + String s = readLine(); + if (callback != null) callback.update(lineNum); + + if (s == null) + return null; + + final StringBuffer sb = new StringBuffer(s); + int savedLineNum = lineNum; + reader.savePosition(); + while ((s = readLine()) != null) { + if (s.length() > 0 && s.charAt(0) == '+') { + if (callback != null) callback.update(lineNum); + reader.discardPosition(); + reader.savePosition(); + savedLineNum = lineNum; + // append a space instead of the + + sb.append(' ').append(s.substring(1)); + } else { + lineNum = savedLineNum; + reader.restorePosition(); + break; + } + } + + if (s == null) + reader.discardPosition(); + + return sb.toString(); + } + + /** + * Returns the next line, handling both continuation and comment lines. + * Ignores empty lines. + **/ + private String nextLine() throws IOException { + String s; + + while ((s = readContinuedLine()) != null) { + if (s.length() == 0) + continue; + else if (s.charAt(0) == '*') + continue; + else + break; + } + + return s; + } + + private int findLastNonParm(final String[] words) { + for (int i = words.length - 1; i >= 0; --i) { + if (words[i].indexOf('=') == -1) + return i; + } + + return -1; + } + + private int parseType(final String mname) throws SpiceFileFormatException { + final boolean isNType = mname.toLowerCase().indexOf('n') != -1; + final boolean isPType = mname.toLowerCase().indexOf('p') != -1; + + if (isNType == isPType) { + throw fileFormatException("Bad modelname " + mname + + " must contain exactly one 'n' or 'p'. Got " + mname); + } else + return isNType ? DeviceTypes.N_TYPE : DeviceTypes.P_TYPE; + } + + private double parseParam(final String param, final String startsWith, + final String message) throws SpiceFileFormatException { + if (!param.toUpperCase().startsWith(startsWith.toUpperCase())) + throw fileFormatException("Bad " + message + ": " + param + + " didn't start with " + startsWith); + + String d = param.substring(startsWith.length()).toUpperCase(); + if (d.endsWith("M")) d = d.substring(0,d.length()-1) + "E-3"; + else if (d.endsWith("U")) d = d.substring(0,d.length()-1) + "E-6"; + else if (d.endsWith("N")) d = d.substring(0,d.length()-1) + "E-9"; + else if (d.endsWith("P")) d = d.substring(0,d.length()-1) + "E-12"; + else if (d.endsWith("F")) d = d.substring(0,d.length()-1) + "E-15"; + + return parseDouble(d, message); + } + + private double parseDouble(final String d, final String message) + throws SpiceFileFormatException { + + try { + return Double.parseDouble(d); + } catch (NumberFormatException e) { + throw fileFormatException("Bad double format " + d + + " for " + message, e); + } + } + + private boolean isInteger(final String s) { + for (int i = 0; i < s.length(); ++i) { + if (s.charAt(i) < '0' || s.charAt(i) > '9') { + return false; + } + } + + return true; + } + + private HierName parseNodeName(String s) { + + // convert arrays back + s = StringUtil.replaceSubstring(s, "][", ","); + + // Convert 'Xblah/' to 'blah/' if this is an Assura RCX extract, + // and use '/' as the hierarchy separation character. + if (assura_rcx_extract) { + StringTokenizer st = new StringTokenizer(s,"/"); + StringBuffer sb = new StringBuffer(); + while (st.hasMoreTokens()) { + String x = st.nextToken(); + if (st.hasMoreTokens()) sb.append(x.substring(1)+"/"); + else sb.append(x); + } + s = sb.toString(); + } + + try { + if (s.startsWith("av")) { + // spice uses av[A-Z][0-9]+(_[0-9]+)? + // XXX: what if there is a real node called this? + if (s.length() > 3 && + s.charAt(2) >= 'A' && s.charAt(2) <= 'Z') { + final String t = s.substring(3); + if (isInteger(t)) + s += '#'; + else { + final int underIdx = t.indexOf('_'); + if (underIdx != -1 && + isInteger(t.substring(0, underIdx)) && + isInteger(t.substring(underIdx + 1))) { + s += '#'; + } + } + } + } else { + // spice uses integers for anonymous nodes: [0-9]+ + + // add a hash on to the end if the name is an integer + /* Disabled by mid. (Why do this?) + if (isInteger(s)) + s += '#'; + */ + } + + return HierName.makeHierName(s, sepChar); + } catch (InvalidHierNameException e) { + throw (AssertionFailure) + new AssertionFailure("Invalid HierName -- can't happen!") + .initCause(e); + } + } + + private void go(String file) throws Throwable { + reader = new PositionStackReader(new InputStreamReader(new + FileInputStream(file))); + String s; + + while ((s = nextLine()) != null) { + System.err.println(">" + s + "<"); + } + } + + private String unmangleType(final String typeName) + throws SpiceFileFormatException { + final StringBuffer sb = new StringBuffer(); + + // 1. convert any occurences of #xx to the appropriate character + // x must be a hex digit + // 2. map the first - to / + + boolean firstDash = true; + for (int i = 0; i < typeName.length(); ++i) { + final char ch = typeName.charAt(i); + + if (ch == '#') { + try { + if (typeName.charAt(i + 1) != '#') + throw fileFormatException("Single hash in " + + typeName); + + final String hexDigits = "0123456789ABCDEF"; + final int i1 = hexDigits.indexOf( + Character.toUpperCase(typeName.charAt(i + 2))); + final int i2 = hexDigits.indexOf( + Character.toUpperCase(typeName.charAt(i + 3))); + + if (i1 == -1 || i2 == -1) + throw fileFormatException("Bad hex escape in " + + typeName); + + sb.append((char) (16 * i1 + i2)); + + i += 3; + } catch (IndexOutOfBoundsException e) { + throw fileFormatException("Bad hex escape in " + + typeName, e); + } + } else if (ch == '-' && firstDash) { + sb.append('/'); + firstDash = false; + } else + sb.append(ch); + } + + return sb.toString(); + } + + private static String[] split(final String line) { + StringTokenizer st = new StringTokenizer(line); + final String[] s = new String[st.countTokens()]; + + for (int i = 0; i < s.length; ++i) + s[i] = st.nextToken(); + + return s; + } + + private static int findEquals(final String line) { + for (int i=0;i + name_of_variable LBRACK expression COLON expression RBRACK | + ( name_of_variable LBRACK ) => + name_of_variable LBRACK expression RBRACK | + name_of_variable + ; + +module_item : + // ambiguity between net_declaration and continuous_assign, + // but parser gets it right: keyword chosen over IDENTIFIER. + parameter_declaration | + input_declaration | + output_declaration | + inout_declaration | + net_declaration | + reg_declaration | + time_declaration | + integer_declaration | + real_declaration | + event_declaration | + gate_declaration | + instantiation | + parameter_override | + continuous_assign | + specify_block | + initial_statement | + always_statement | + task | + function | + directive + ; + +instantiation: + (module_instantiation) => module_instantiation | + udp_instantiation + ; + +//---------------------------------------------------------------------------- +// UDP specs +//---------------------------------------------------------------------------- + +udp : + "primitive" name_of_UDP + LPAREN name_of_variable ( COMMA name_of_variable )* RPAREN SEMI + (udp_declaration)+ + (udp_initial_statement)? + table_definition + "endprimitive" + ; + +udp_port_list : + udp_name_of_port ( COMMA udp_name_of_port )* + ; + +udp_declaration : + output_declaration | + input_declaration | + reg_declaration + ; + +udp_initial_statement : + "initial" output_terminal_name ASSIGN init_val SEMI + ; + + // Use a semantic predicate to determine whether a matched NUMBER + // is a valid special value in the given context. + // This kludge avoids having the special values in the Literals table, + // thus avoiding a lexical conflict. +init_val : + "1'b0" | + "1'b1" | + "1'bx" | + n:NUMBER + { n.getText().equals("0") || n.getText().equals("1") }? + ; + +table_definition : + "table" table_entries "endtable" + ; + + // Don't try to parse table entries; just collect them. + // There are ambiguities between edge_symbol and level_symbol, + // and textbook Verilog examples don't seem to follow rules + // completely. For example, + // "0 00 : 0;" + // doesn't match grammar because of "00", but is frequently used. +table_entries : + //(sequential_entry) => (sequential_entry)+ | + //(combinational_entry)+ + (( ~(SEMI | "endtable") )+ SEMI)* + ; + + +/******** + ******** Start of commented out rules related to table entries. + ******** + +combinational_entry : + level_input_list COLON output_symbol SEMI + ; + +sequential_entry : + input_list COLON state COLON next_state SEMI + ; + +input_list : + (level_input_list) => level_input_list | + edge_input_list + ; + +level_input_list : + (level_symbol)+ + ; + +edge_input_list : + (level_symbol)* edge (level_symbol)* + ; + +edge : + LPAREN level_symbol level_symbol RPAREN | + edge_symbol + ; + +state : + level_symbol + ; + +next_state : + output_symbol | + MINUS + ; + + // Next 3 rules use semantic predicates to determine whether a matched + // NUMBER or IDENTIFIER is a valid special value in the given context. + // This kludge avoids having the special values in the Literals table, + // thus avoiding a lexical conflict. +output_symbol: + n:NUMBER + { n.getText().equals("0") || n.getText().equals("1") }? + | + i:IDENTIFIER + { i.getText().equals("x") || i.getText().equals("X") }? + ; + +level_symbol: + QUESTION + | + n:NUMBER + { n.getText().equals("0") || n.getText().equals("1") }? + | + i:IDENTIFIER + { i.getText().equals("x") || i.getText().equals("X") || + i.getText().equals("b") || i.getText().equals("B") }? + ; + +edge_symbol: + STAR + | + i:IDENTIFIER + { i.getText().equals("r") || i.getText().equals("R") || + i.getText().equals("f") || i.getText().equals("F") || + i.getText().equals("p") || i.getText().equals("P") || + i.getText().equals("n") || i.getText().equals("N") }? + ; + + ******** + ******** End of commented out rules related to table entries. + ********/ + + +task : + "task" name_of_task SEMI + (tf_declaration)* + statement_or_null + "endtask" + ; + +function : + "function" (range_or_type)? name_of_function SEMI + (tf_declaration)+ + statement + "endfunction" + ; + +range_or_type : + range | + "integer" | + "real" + ; + +tf_declaration : + parameter_declaration | + output_declaration | + input_declaration | + inout_declaration | + reg_declaration | + time_declaration | + integer_declaration | + real_declaration | + event_declaration + ; + + +//---------------------------------------------------------------------------- +// Declarations +//---------------------------------------------------------------------------- + +parameter_declaration : + "parameter" (range)? list_of_param_assignments SEMI + ; + +list_of_param_assignments : + param_assignment ( COMMA param_assignment )* + ; + +param_assignment : + identifier ASSIGN expression + ; + +input_declaration : + "input" (range)? list_of_variables SEMI + ; + +output_declaration : + "output" (range)? list_of_variables SEMI + ; + +inout_declaration : + "inout" (range)? list_of_variables SEMI + ; + +net_declaration : + ( net_type (expandrange)? ) => + net_type (expandrange)? (delay)? + list_of_assigned_variables SEMI | + "trireg" (charge_strength)? (expandrange)? (delay)? + list_of_variables SEMI + ; + +net_type : + "wire" | + "tri" | + "tri1" | + "supply0" | + "wand" | + "triand" | + "tri0" | + "supply1" | + "wor" | + "trior" | + "trireg" + ; + +expandrange : + "scalared" range | + "vectored" range | + range + ; + +reg_declaration : + "reg" (range)? list_of_register_variables SEMI + ; + +time_declaration : + "time" list_of_register_variables SEMI + ; + +integer_declaration : + "integer" list_of_register_variables SEMI + ; + +real_declaration : + "real" list_of_variables SEMI + ; + +event_declaration : + "event" name_of_event ( COMMA name_of_event )* SEMI + ; + +continuous_assign : + "assign" (drive_strength)? (delay)? list_of_assignments SEMI | + net_type (drive_strength)? (expandrange)? (delay)? + list_of_assignments SEMI + ; + +parameter_override : + "defparam" list_of_param_assignments SEMI + ; + +list_of_variables : + name_of_variable ( COMMA name_of_variable )* + ; + +list_of_assigned_variables : + name_of_variable ( ASSIGN expression )? + ( COMMA name_of_variable ( ASSIGN expression )? )* + ; + +list_of_register_variables : + register_variable ( COMMA register_variable )* + ; + +register_variable : + name_of_register | + name_of_memory LBRACK expression COLON expression RBRACK + ; + +charge_strength : + LPAREN "small" RPAREN | + LPAREN "medium" RPAREN | + LPAREN "large" RPAREN + ; + +drive_strength : + LPAREN strength0 COMMA strength1 RPAREN | + LPAREN strength1 COMMA strength0 RPAREN + ; + +strength0 : + "supply0" | + "strong0" | + "pull0" | + "weak0" | + "highz0" + ; + +strength1 : + "supply1" | + "strong1" | + "pull1" | + "weak1" | + "highz1" + ; + +range : + (LBRACK expression COLON) => + LBRACK expression COLON expression RBRACK | + LBRACK expression RBRACK + ; + +list_of_assignments : + assignment ( COMMA assignment )* + ; + + +//---------------------------------------------------------------------------- +// Primitive Instances +//---------------------------------------------------------------------------- + +gate_declaration : + gate_type (drive_strength)? (delay)? + gate_instance ( COMMA gate_instance )* SEMI + ; + +gate_type : + "and" | + "nand" | + "or" | + "nor" | + "xor" | + "xnor" | + "buf" | + "bufif0" | + "bufif1" | + "not" | + "notif0" | + "notif1" | + "pulldown" | + "pullup" | + "nmos" | + "rnmos" | + "pmos" | + "rpmos" | + "cmos" | + "rcmos" | + "tran" | + "rtran" | + "tranif0" | + "rtranif0" | + "tranif1" | + "rtranif1" + ; + +delay : + POUND NUMBER | + POUND identifier | + POUND LPAREN mintypmax_expression + ( COMMA mintypmax_expression + ( COMMA mintypmax_expression )? + )? + RPAREN + ; + +gate_instance : + (name_of_gate_instance)? + LPAREN terminal ( COMMA terminal )* RPAREN + ; + +udp_instantiation : + name_of_UDP (drive_strength)? (delay)? + udp_instance ( COMMA udp_instance )* SEMI + ; + +udp_instance : + (name_of_UDP_instance)? + LPAREN terminal ( COMMA terminal )* RPAREN + ; + +terminal : + expression + // | IDENTIFIER + ; + +//---------------------------------------------------------------------------- +// Module Instantiations +//---------------------------------------------------------------------------- + +module_instantiation : + name_of_module (parameter_value_assignment)? + module_instance ( COMMA module_instance )* SEMI + ; + +parameter_value_assignment : + POUND LPAREN expression ( COMMA expression )* RPAREN + ; + +module_instance : + name_of_instance LPAREN list_of_module_connections RPAREN + ; + +list_of_module_connections : + module_port_connection ( COMMA module_port_connection )* | + named_port_connection ( COMMA named_port_connection )* + ; + +module_port_connection : + expression | + // NULL + ; + + // expression below isn't optional according to Palnitkar, but + // several examples generated by Cadence use this syntax. +named_port_connection : + DOT IDENTIFIER LPAREN (expression)? RPAREN + ; + +//---------------------------------------------------------------------------- +// Behavioral Statements +//---------------------------------------------------------------------------- + +initial_statement : + "initial" statement + ; + +always_statement : + "always" statement + ; + +statement_or_null : + (statement) => statement | + SEMI + ; + +statement : + (lvalue ASSIGN) => blocking_assignment SEMI | + (lvalue LE) => non_blocking_assignment SEMI | + conditional_statement | + case_statement | + loop_statement | + procedural_timing_control_statement | + wait_statement | + event_trigger | + seq_block | + par_block | + task_enable | + system_task_enable | + disable_statement | + procedural_continuous_assignment + ; + +assignment : + lvalue ASSIGN expression + ; + +blocking_assignment : + lvalue ASSIGN ( delay_or_event_control )? expression + ; + +non_blocking_assignment : + lvalue LE ( delay_or_event_control )? expression + ; + + // "else" clause is inherently ambiguous; ANTLR gets it right, + // so suppress warning. +conditional_statement : + "if" LPAREN expression RPAREN statement_or_null + ( options { warnWhenFollowAmbig = false; } : + "else" statement_or_null + )? + ; + +case_statement : + case_keyword LPAREN expression RPAREN (case_item)+ "endcase" + ; + +case_keyword : + "case" | "casez" | "casex" + ; + +case_item : + expression ( COMMA expression )* COLON statement_or_null | + "default" (COLON)? statement_or_null + ; + +loop_statement : + "forever" statement | + "repeat" LPAREN expression RPAREN statement | + "while" LPAREN expression RPAREN statement | + "for" LPAREN assignment SEMI expression SEMI assignment RPAREN statement + ; + +procedural_timing_control_statement : + delay_or_event_control statement_or_null + ; + +wait_statement : + "wait" LPAREN expression RPAREN statement_or_null + ; + +event_trigger : + TRIGGER name_of_event SEMI + ; + +disable_statement : + "disable" IDENTIFIER SEMI + ; + +seq_block : + "begin" + ( COLON name_of_block (block_declaration)* )? + (statement)* + "end" + ; + +par_block : + "fork" + ( COLON name_of_block (block_declaration)* )? + (statement)* + "join" + ; + +block_declaration : + parameter_declaration | + reg_declaration | + integer_declaration | + real_declaration | + time_declaration | + event_declaration + ; + +task_enable : + name_of_task ( LPAREN expression (COMMA (expression)?)* RPAREN )? + SEMI + ; + +system_task_enable : + SYSTEM_TASK_NAME ( LPAREN expression (COMMA (expression)?)* RPAREN )? + SEMI + ; + +procedural_continuous_assignment : + "assign" assignment SEMI | + "deassign" lvalue SEMI | + "force" assignment SEMI | + "release" lvalue SEMI + ; + +delay_or_event_control : + delay_control | + event_control + ; + +//---------------------------------------------------------------------------- +// Specify Section +//---------------------------------------------------------------------------- + +specify_block : + "specify" (specify_item)* "endspecify" + ; + +specify_item : + spec_param_declaration | + (path_declaration) => path_declaration | + system_timing_check + | sdpd + ; + +spec_param_declaration : + "specparam" list_of_specparam_assignments SEMI + ; + +list_of_specparam_assignments : + specparam_assignment ( COMMA specparam_assignment )* + ; + +specparam_assignment : + identifier ASSIGN expression + ; + +path_declaration : + (simple_path_declaration) => + simple_path_declaration SEMI | + (level_sensitive_path_declaration) => + level_sensitive_path_declaration SEMI | + edge_sensitive_path_declaration SEMI + ; + +simple_path_declaration : + (parallel_path_description) => + parallel_path_description ASSIGN path_delay_value | + full_path_descriptor ASSIGN path_delay_value + ; + +parallel_path_description : + LPAREN specify_terminal_descriptor PPATH specify_terminal_descriptor RPAREN + ; + +full_path_descriptor : + LPAREN list_of_path_terminals FPATH list_of_path_terminals RPAREN + ; + +list_of_path_terminals : + specify_terminal_descriptor ( COMMA specify_terminal_descriptor )* + ; + +specify_terminal_descriptor : + (identifier LBRACK expression COLON) => + identifier LBRACK expression COLON expression RBRACK | + (identifier LBRACK) => + identifier LBRACK expression RBRACK | + identifier + ; + +path_delay_value : + (path_delay_expression) => path_delay_expression | + LPAREN list_of_path_delay_expressions RPAREN + ; + +list_of_path_delay_expressions : + path_delay_expression COMMA path_delay_expression + ( COMMA path_delay_expression + ( COMMA path_delay_expression COMMA + path_delay_expression COMMA path_delay_expression )? )? + ; + +path_delay_expression : + mintypmax_expression + ; + +system_timing_check : + "$setup" LPAREN timing_check_event COMMA timing_check_event COMMA + timing_check_limit ( COMMA notify_register )? RPAREN SEMI | + "$hold" LPAREN timing_check_event COMMA timing_check_event COMMA + timing_check_limit ( COMMA notify_register )? RPAREN SEMI | + "$period" LPAREN controlled_timing_check_event COMMA + timing_check_limit ( COMMA notify_register )? RPAREN SEMI | + "$width" LPAREN controlled_timing_check_event COMMA + timing_check_limit ( COMMA expression COMMA notify_register )? + RPAREN SEMI | + "$skew" LPAREN timing_check_event COMMA timing_check_event COMMA + timing_check_limit ( COMMA notify_register )? RPAREN SEMI | + "$recovery" LPAREN controlled_timing_check_event COMMA + timing_check_event COMMA timing_check_limit + ( COMMA notify_register )? RPAREN SEMI | + "$setuphold" LPAREN timing_check_event COMMA timing_check_event COMMA + timing_check_limit COMMA timing_check_limit + ( COMMA notify_register )? RPAREN SEMI + ; + +timing_check_event : + (timing_check_event_control)? specify_terminal_descriptor + ( "&&&" timing_check_condition )? + ; + +controlled_timing_check_event : + timing_check_event_control specify_terminal_descriptor + ( "&&&" timing_check_condition )? + ; + +timing_check_event_control : + "posedge" | + "negedge" | + edge_control_specifier + ; + +edge_control_specifier : + "edge" LBRACK edge_descriptor ( COMMA edge_descriptor )* RBRACK + ; + + // Use semantic predicates to determine whether a matched + // NUMBER or IDENTIFIER is a valid special value in the given context. + // This kludge avoids having the special values in the Literals table, + // thus avoiding a lexical conflict. +edge_descriptor : + "0x" | "1x" + | + n:NUMBER + { n.getText().equals("01") || n.getText().equals("10") }? + | + i:IDENTIFIER + { i.getText().equals("x1") || i.getText().equals("x0") }? + ; + +timing_check_condition : + scalar_timing_check_condition + ; +scalar_timing_check_condition : + expression + ; + +timing_check_limit : + expression + ; + +notify_register : + name_of_register + ; + +level_sensitive_path_declaration : + (parallel_level_sensitive_path_description) => + parallel_level_sensitive_path_description + ASSIGN path_delay_value SEMI + | + full_level_sensitive_path_description + ASSIGN path_delay_value SEMI + ; + +parallel_level_sensitive_path_description : + "if" LPAREN expression RPAREN + LPAREN specify_terminal_descriptor (polarity_operator)? + PPATH specify_terminal_descriptor RPAREN + ; + +full_level_sensitive_path_description : + "if" LPAREN expression RPAREN + LPAREN list_of_path_terminals (polarity_operator)? + FPATH list_of_path_terminals RPAREN + ; + +polarity_operator : + PLUS | + MINUS + ; + +edge_sensitive_path_declaration : + ( "if" LPAREN expression RPAREN )? + LPAREN (edge_identifier)? specify_terminal_descriptor + ( PPATH | FPATH ) + LPAREN ( (list_of_path_terminals) => list_of_path_terminals | + specify_terminal_descriptor ) + (polarity_operator)? COLON data_source_expression + RPAREN + RPAREN + ASSIGN path_delay_value SEMI + ; + +data_source_expression : + expression + ; + +edge_identifier : + "posedge" | + "negedge" + ; + +sdpd : + "if" LPAREN expression RPAREN + simple_path_declaration + SEMI + ; + +//---------------------------------------------------------------------------- +// Expressions +//---------------------------------------------------------------------------- + +lvalue : + (identifier range) => + identifier range | + identifier | + concatenation + ; + +concatenation : + (LCURLY expression LCURLY) => + LCURLY expression + LCURLY expression ( COMMA expression )* RCURLY RCURLY | + LCURLY expression ( COMMA expression )* RCURLY + ; + +mintypmax_expression : + expression ( COLON expression COLON expression )? + ; + +exp11 : + STRING | + NUMBER | + (function_call) => function_call | + lvalue + ; + +exp10 : + exp11 | LPAREN expression RPAREN + ; + +exp9 : + exp10 | unary_operator exp9 + ; + +exp8 : + exp9 ( binary_operator exp9 )* + ; + +exp7 : + exp8 ( QUESTION exp7 COLON exp7 )? + ; + +exp0 : + exp7 + ; + +expression : + exp0 + ; + +function_call : + name_of_function LPAREN expression_list RPAREN | + SYSTEM_TASK_NAME ( LPAREN expression_list RPAREN )? + ; + +expression_list : + expression ( COMMA expression )* + ; + +unary_operator : + PLUS | + MINUS | + LNOT | + BNOT | + BAND | + RNAND | + BOR | + RNOR | + BXOR | + RXNOR + ; + +binary_operator : + PLUS | + MINUS | + STAR | + DIV | + MOD | + EQUAL | + NOT_EQ | + EQ_CASE | + NOT_EQ_CASE | + LAND | + LOR | + LT_ | + LE | + GT | + GE | + BAND | + BOR | + BXOR | + BXNOR | + SR | + SL + ; + +//---------------------------------------------------------------------------- +// Identifiers +//---------------------------------------------------------------------------- + +name_of_module : local_identifier ; +name_of_port : local_identifier ; +name_of_variable : local_identifier ; +name_of_UDP : local_identifier ; +name_of_UDP_instance : local_identifier ; +name_of_event : local_identifier ; +name_of_task : identifier ; +real_identifier : identifier ; +name_of_memory : local_identifier ; +net_identifier : identifier ; +name_of_function : local_identifier ; +specparam_identifier : identifier ; +udp_name_of_port : identifier ; +name_of_register : local_identifier ; +name_of_gate_instance : local_identifier ; +name_of_instance : local_identifier ; +name_of_block : local_identifier ; +output_terminal_name : local_identifier ; + + +//---------------------------------------------------------------------------- +// General +//---------------------------------------------------------------------------- + +identifier : + identifier_path + ; + +identifier_path : + local_identifier ( DOT local_identifier )* + ; + +local_identifier : + IDENTIFIER | + ESCAPED_IDENTIFIER | + DEFINE + ; + +delay_control : + POUND NUMBER | + POUND identifier | + POUND LPAREN mintypmax_expression RPAREN + ; + +event_control : + AT identifier | + AT LPAREN event_expression RPAREN + ; + +event_expression : + sub_event_expression ( "or" sub_event_expression )* + ; + +sub_event_expression : + expression | + "posedge" expression | + "negedge" expression + ; + +//---------------------------------------------------------------------------- +// Compiler directives +//---------------------------------------------------------------------------- + +directive: + define_directive | + include_directive + ; + +define_directive : + "`define" IDENTIFIER expression + ; + +include_directive : + "`include" ( identifier | STRING ) + ; + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// The Verilog scanner +//---------------------------------------------------------------------------- + +class VerilogLexer extends Lexer; + +options { + exportVocab = Verilog; // call the vocabulary "Verilog" + testLiterals = false; // don't automatically test for literals + k = 3; // 3 characters of lookahead +} + + // Operators +AT : "@" ; +COLON : ":" ; +COMMA : "," ; +DOT : "." ; +ASSIGN : "=" ; +MINUS : "-" ; +LBRACK : "[" ; +RBRACK : "]" ; +LCURLY : "{" ; +RCURLY : "}" ; +LPAREN : "(" ; +RPAREN : ")" ; +POUND : "#" ; +QUESTION : "?" ; +SEMI : ";" ; +PLUS : "+" ; +LNOT : "!" ; +BNOT : "~" ; +BAND : "&" ; +RNAND : "~&" ; +BOR : "|" ; +RNOR : "~|" ; +BXOR : "^" ; +RXNOR : "~^" | "^~" ; +STAR : "*" ; +DIV : "/" ; +MOD : "%" ; +EQUAL : "==" ; +NOT_EQ : "!=" ; +NOT_EQ_CASE : "!==" ; +EQ_CASE : "===" ; +LAND : "&&" ; +LOR : "||" ; +LT_ : "<" ; +LE : "<=" ; +GT : ">" ; +GE : ">=" ; +SR : ">>" ; +SL : "<<" ; +TRIGGER : "->" ; +PPATH : "=>" ; +FPATH : "*>" ; + + // an identifier. Note that testLiterals is set to true! This means + // that after we match the rule, we look in the Literals table to see + // if it's a literal or really an identifer. +IDENTIFIER + options {testLiterals=true;} + : + ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'$'|'0'..'9')* + ; + +ESCAPED_IDENTIFIER : + '\\'! (~ '\040')+ ('\040'|'\t'|'\n')! + ; + +SYSTEM_TASK_NAME : + '$' IDENTIFIER + ; + + // string literals +STRING : + '"' (~('"'|'\n'))* '"' + ; + + // "compiler" define/macro. +DEFINE + options {testLiterals=true;} + : + '`' IDENTIFIER + ; + + // a dummy rule to force vocabulary to be all characters (except special + // ones that ANTLR uses internally (0 to 2) +protected +VOCAB : + '\3'..'\177' + ; + + // a numeric literal +NUMBER : + ( (SIZE)? BASE SIZED_DIGIT ) => SIZED_NUMBER | + UNSIZED_NUMBER + ; + +protected +SIZED_NUMBER : + (SIZE)? BASE SIZED_DIGIT (SIZED_DIGIT | '_')* + ; + +protected +SIZE : + (DIGIT)+ + ; + +protected +BASE : + '\'' ( 'd' | 'D' | 'h' | 'H' | 'o' | 'O' | 'b' | 'B' ) + ; + +protected +SIZED_DIGIT : + DIGIT | HEXDIGIT | 'x' | 'X' | 'z' | 'Z' | '?' + ; + +protected +UNSIZED_NUMBER : + DIGIT (DIGIT | '_')* ( '.' (DIGIT | '_')* )? (EXPONENT)? + ; + +protected +DIGIT : + ('0'..'9') + ; + +protected +HEXDIGIT : + ('A'..'F'|'a'..'f') + ; + +protected +EXPONENT : + ('e'|'E') ('+'|'-')? ('0'..'9')+ + ; + + // Whitespace -- ignored +WS_ : + ( ' ' + | '\t' + | '\f' + // handle newlines + | ( "\r\n" // Evil DOS + | '\r' // Macintosh + | '\n' // Unix (the right way) + ) + { newline(); } + ) + { $setType(Token.SKIP); } + ; + + // Single-line comments +SL_COMMENT : + "//" (~'\n')* '\n' + { $setType(Token.SKIP); newline(); } + ; + + // multiple-line comments +ML_COMMENT + : "/*" + ( { LA(2)!='/' }? '*' + | '\n' { newline(); } + | ~('*'|'\n') + )* + "*/" + { $setType(Token.SKIP); } + ; + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/CellListFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/CellListFile.java new file mode 100644 index 0000000000..7c27aa2ef4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/CellListFile.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.floorplanning; + + +import java.util.Set; +import java.util.HashSet; + + +import java.io.File; +import java.io.InputStream; +import java.io.Reader; +import java.io.LineNumberReader; +import java.io.FileInputStream; +import java.io.InputStreamReader; + +import java.io.FileNotFoundException; +import java.io.IOException; + + +import com.avlsi.util.debug.Debug; + +final class CellListFile { + + private final Set m_CellSet; + + private void readFromReader( final Reader r ) + throws IOException + { + final LineNumberReader lR = new LineNumberReader( r ); + + String currLine; + + do { + currLine = lR.readLine(); + if ( currLine != null ) { + m_CellSet.add( currLine ); + } + } while ( currLine != null ); + } + + private void readFromStream( final InputStream i ) + throws IOException + { + + readFromReader( new InputStreamReader( i, "UTF-8" ) ); + } + + private void readFromFile( final File f ) + throws IOException, FileNotFoundException + { + if ( ( f.isFile() ) && ( f.canRead() ) ) { + try { + readFromStream( new FileInputStream( f ) ); + } + catch( FileNotFoundException e ) { + Debug.assertTrue( false ); + } + } + else { + throw new IllegalArgumentException(); + } + + } + + private void readFromFile( final String fn ) + throws IOException + { + final File f = new File( fn ); + readFromFile( f ); + } + + + private CellListFile( ) { + m_CellSet = new HashSet(); + } + + public CellListFile( final File f ) throws IOException { + this(); + readFromFile( f ); + } + + public CellListFile( final String fn ) throws IOException { + this(); + readFromFile( fn ); + } + + public Set getCellList() { + return m_CellSet; + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/GenerateFloorPlanningData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/GenerateFloorPlanningData.java new file mode 100644 index 0000000000..1ff7cb49c9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/GenerateFloorPlanningData.java @@ -0,0 +1,1322 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.floorplanning; + + +import java.util.Collections; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; +import java.util.Iterator; + +import java.util.Date; +import java.util.Calendar; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.io.OutputStreamWriter; + +import java.io.FileInputStream; +import java.io.FileOutputStream; + +import java.io.InputStreamReader; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import java.text.MessageFormat; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.util.debug.Debug; + +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.SearchPath; + +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.NullEnvironment; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractNodeIterator; + +import com.avlsi.netlist.impl.SimpleAbstractNetlistIterator; +import com.avlsi.netlist.impl.simple.SimpleNetlistFactory; + +import com.avlsi.netlist.util.ChildrenFirstNetlistIterator; +import com.avlsi.netlist.util.SubcellIterator; +import com.avlsi.netlist.util.FETIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +import com.avlsi.floorplanning.PCellTypesInfo; +import com.avlsi.floorplanning.PCellTypesInfoImpl; +import com.avlsi.floorplanning.TransistorTypeInfo; + +public class GenerateFloorPlanningData { + + static final String openSchematicFormatStr = + "( defvar\n" + + " {0}\n" + + " (let (\n" + + " ( SchematicDDObj ( ddGetObj\n" + + " {1}\n" + + " {2}\n" + + " {3}\n" + + " \"pc.db\"\n" + + " nil\n" + + " \"r\"" + + " )\n" + + " )\n" + + " )\n" + + " (when ( or\n" + + " ( null SchematicDDObj )\n" + + " ( ddIsObjWritable SchematicDDObj )\n" + + " )\n" + + " ( dbOpenCellViewByType\n" + + " {1}\n" + + " {2}\n" + + " {3}\n" + + " \"schematic\"\n" + + " \"w\"\n" + + " )\n" + + " )\n" + + " )\n" + + " )\n" + + "(if {0}\n" + + " ( printf \"%s %s %s\\n\" {1} {2} {3} )\n" + + " ( printf \"Skipping %s %s %s\\n\" {1} {2} {3} )\n" + + " )\n"; + + static final String saveAndCloseSchematicFormatStr = + "(when {0}\n" + + " ( DistributeInstances {0} 0 0 5 )\n" + + " ( dbReplaceProp\n" + + " {0}\n" + + " \"lastSchematicExtraction\"\n" + + " \"time\"\n" + + " \"{1,time,MMM dd HH:mm:ss yyyy}\"\n" + + " )\n" + + " ( dbSave {0} )\n" + + " ( dbPurge {0} )\n" + + " )\n"; + + /* + TransistorTable + ModelName + LibName + CellName + ViewName + */ + static final String openPCellFormatStr = + "( setarray\n" + + " {0}\n" + + " {1}\n" + + " ( dbOpenCellViewByType\n" + + " {2}\n" + + " {3}\n" + + " {4}\n" + + " nil\n" + + " \"r\"\n" + + " )\n" + + " )\n"; + + static final String createTerminalFormatStr = + "( when {0}\n" + + " ( dbCreateTerm\n" + + " ( dbMakeNet {0} {1} )" + + " {1}" + + " \"inputOutput\"\n" + + " )\n" + + " )\n"; + /* + 0 CurrCellView + 1 TransitorName + 2 W + 3 L + 4 GateNetName + 5 SourceNetName + 6 DrainNetName + 7 BulkNetName + 8 TransistorView + 9 WParamName + 10 WParamType + 11 LParamName + 12 LParamType + 13 GateTermName + 14 SourceTermName + 15 DrainTermName + 16 BulkTermName + */ + static final String createTransistorFormatStr = + "(when {0}\n" + + " (let (\n" + + " ( TransistorInstance ( dbCreateParamInst\n" + + " {0}\n" + + " {8}\n" + + " {1}\n" + + " ( list 0 0 )\n" + + " \"R0\"\n" + + " 1\n" + + " ( list\n" + + " ( list\n" + + " {9}\n" + + " {10}\n" + + " {2}\n" + + " )\n" + + " ( list\n" + + " {11}\n" + + " {12}\n" + + " {3}\n" + + " )\n" + + " )\n" + + " )\n" + + " )\n" + + " )\n" + + " (when TransistorInstance\n" + + " ( dbCreateConnByName\n" + + " ( dbMakeNet {0} {4} )\n" + + " TransistorInstance\n" + + " {13}\n" + + " )\n" + + " ( dbCreateConnByName\n" + + " ( dbMakeNet {0} {5} )\n" + + " TransistorInstance\n" + + " {14}\n" + + " )\n" + + " ( dbCreateConnByName\n" + + " ( dbMakeNet {0} {6} )\n" + + " TransistorInstance\n" + + " {15}\n" + + " )\n" + + " ( dbCreateConnByName\n" + + " ( dbMakeNet {0} {7} )\n" + + " TransistorInstance\n" + + " {16}\n" + + " )\n" + + " )\n" + + " )\n" + + " )\n"; + + static final String createInstFormatStr = + "(when {0}\n" + + " (let (\n" + + " ( InstanceMaster ( dbOpenCellViewByType\n" + + " {2}\n" + + " {3}\n" + + " {4}\n" + + " \"schematic\"\n" + + " \"r\"\n" + + " )\n" + + " )\n" + + " )\n" + + " (when InstanceMaster\n" + + " ( defvar\n" + + " {1}\n" + + " ( dbCreateInst {0} InstanceMaster {5} ( list 0 0 ) \"R0\" )\n" + + " )\n" + + " )\n" + + " )\n" + + " )\n"; + + /* + CurrCellView + Instance + ConnectedNet + TerminalName + */ + static final String createConnectionFormatStr = + "(when {0}\n" + + " (let (\n" + + " ( ConnectedNet ( dbMakeNet {0} {2} ) )\n" + + " )\n" + + " ( dbCreateConnByName ConnectedNet {1} {3} )\n" + + " )\n" + + " )\n"; + + + + private interface NetlistNameParser { + String getCellName( final HierName netlistName ); + String getLibName( final HierName netlistName ); + } + + public static class FloorPlanningException extends Exception { + public FloorPlanningException( final String error ) { + super( error ); + } + } + + private static String quoteString( final String src ) { + return "\"" + src + "\""; + } + + private static Set getGateNetlists( final PCellTypesInfo pcellInfos, + final SimpleNetlistFactory f ) + { + + final Iterator gatePCellTypeInfos = pcellInfos.getNonTransistorPCellTypeInfos(); + + final String[] emptyStrArray = new String[0]; + + final Environment emptyEnv = NullEnvironment.getInstance(); + + while ( gatePCellTypeInfos.hasNext() ) { + PCellTypeInfo currInfo = ( PCellTypeInfo ) gatePCellTypeInfos.next(); + f.beginSubcircuit( currInfo.getCellName(), + emptyStrArray, + emptyStrArray, + Collections.EMPTY_MAP, + emptyEnv ); + f.endSubcircuit( currInfo.getCellName(), + emptyEnv ); + } + + final Set ret = new HashSet( ); + + final AbstractNetlistIterator netlistIter = f.getAllNetlists(); + + while ( netlistIter.hasNext() ) { + final AbstractNetlist netlist = netlistIter.next(); + ret.add( netlist ); + } + + return ret; + + } + + + private static List getNetlistsInOrder( final File cdlFile, + final SimpleNetlistFactory f, + final Set gateNetlists ) + throws FloorPlanningException, IOException, FileNotFoundException, + RecognitionException, TokenStreamException + { + + final InputStream cdlInputStream = + new FileInputStream( cdlFile ); + final Reader cdlReader = + new InputStreamReader( cdlInputStream, "UTF-8" ); + + ReadCDLIntoFactory.readCDL( cdlReader, f ); + + final AbstractNetlistIterator netlistIter = f.getAllNetlists(); + final Set cellsWeHaveAlreadySeen = new HashSet(); + + final List ret = new LinkedList(); + + while ( netlistIter.hasNext() ) { + final AbstractNetlist curr = netlistIter.next(); + final String currName = curr.getName().toString(); + if ( ! ( cellsWeHaveAlreadySeen.contains( currName ) ) ) { + final ChildrenFirstNetlistIterator innerNetlistIter = + new ChildrenFirstNetlistIterator( curr ); + while ( innerNetlistIter.hasNext() ) { + final AbstractNetlist innerCurr = innerNetlistIter.next(); + final String innerCurrName = innerCurr.getName().toString(); + if ( ! ( cellsWeHaveAlreadySeen.contains( innerCurrName ) ) ) { + cellsWeHaveAlreadySeen.add( innerCurrName ); + if ( ! ( gateNetlists.contains( innerCurr ) ) ) { + ret.add( innerCurr ); + } + } + } + } + } + + return ret; + } + + private static boolean isEmptyCell( final AbstractNetlist netlist ) { + return ! netlist.getDevices().hasNext(); + } + + private static boolean isMidLevelCellNetlist( final AbstractNetlist netlist, + final Set gateNetlists ) { + boolean isMidLevel = false; + final SubcellIterator subCellIter = + new SubcellIterator( netlist.getDevices() ); + + if ( subCellIter.hasNext() ) { + final SubcellIterator.SubcellInstance instance = + subCellIter.next(); + isMidLevel = + ! ( gateNetlists.contains( instance.getInstantiatedNetlist() ) ) ; + } + + return isMidLevel; + } + + private static boolean isLeafCellNetlist( final AbstractNetlist netlist, + final Set gateNetlists ) { + + boolean isLeaf = false; + final SubcellIterator subCellIter = + new SubcellIterator( netlist.getDevices() ); + + if ( subCellIter.hasNext() ) { + final SubcellIterator.SubcellInstance instance = + subCellIter.next(); + isLeaf = gateNetlists.contains( instance.getInstantiatedNetlist() ); + } + else { + isLeaf = netlist.getDevices().hasNext(); + } + + return isLeaf; + + } + + private static void emitTerminals( final Writer w, + final AbstractNodeIterator terminalNodes, + final String cellViewExpression, + final MessageFormat formatter ) + throws IOException { + final StringBuffer accumulator = new StringBuffer(); + while ( terminalNodes.hasNext() ) { + final AbstractNode currNode = terminalNodes.next(); + + final Object[] createTerminalArgs = { + cellViewExpression, + quoteString( currNode.getCanonicalName().toString() ) + }; + + formatter.format( createTerminalArgs, + accumulator, + null ); + w.write( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + } + } + + private static + void emitConnections( final Writer w, + final AbstractNodeIterator connectedNodes, + final AbstractNodeIterator masterNodes, + final String cellViewExpression, + final String currInstanceExpression, + final MessageFormat formatter) + throws IOException + + { + + final StringBuffer accumulator = new StringBuffer(); + while ( masterNodes.hasNext() ) { + final AbstractNode currMasterNode = masterNodes.next(); + final AbstractNode currConnectedNode = connectedNodes.next(); + + final Object[] createConnectionArgs = { + cellViewExpression, + currInstanceExpression, + quoteString( currConnectedNode.getCanonicalName().toString() ), + quoteString( currMasterNode.getCanonicalName().toString() ) + }; + + formatter.format( createConnectionArgs, + accumulator, + null ); + + w.write( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + } + } + + private static + void openTransistors( final Writer writer, + final String transistorTableName, + final PCellTypesInfo pCellsInfo ) + throws IOException + { + final StringBuffer accum = new StringBuffer(); + final StringContainerIterator modelIter = + pCellsInfo.getTransistorModels(); + + if ( modelIter.hasNext() ) { + + final MessageFormat openPCellFormatter = + new MessageFormat( openPCellFormatStr ); + + writer.write( "( defvar " + + transistorTableName + + " ( makeTable \"foo\" nil ) )\n" ); + while( modelIter.hasNext() ) { + final String currModelName = modelIter.next(); + final TransistorTypeInfo currTransistorType = + pCellsInfo.getTransistorInfo( currModelName ); + + final String libName = currTransistorType.getLibName(); + final String cellName = currTransistorType.getCellName(); + final String viewName = + currTransistorType.getSchematicViewName(); + + if ( ( libName != null ) && + ( cellName != null ) && + ( viewName != null ) ) { + + final Object[] openTransistorArgs = { + transistorTableName, + quoteString( currModelName ), + quoteString( libName ), + quoteString( cellName), + quoteString( viewName ) + }; + openPCellFormatter.format( openTransistorArgs, + accum, + null ); + } + } + writer.write( accum.toString() ); + } + + } + + private static + void openGates( final Writer writer, + final String gateTableName, + final PCellTypesInfo pCellsInfo, + final Set gateNetlists ) + throws IOException + { + + final StringBuffer accum = new StringBuffer(); + final Iterator gateIter = gateNetlists.iterator(); + + if ( gateIter.hasNext() ) { + + final MessageFormat openPCellFormatter = + new MessageFormat( openPCellFormatStr ); + + writer.write( "( defvar " + + gateTableName + + " ( makeTable \"bar\" nil ) )\n" ); + while( gateIter.hasNext() ) { + final AbstractNetlist currGate = ( AbstractNetlist ) gateIter.next(); + final String currGateName = currGate.getName().toString(); + final PCellTypeInfo currPCellType = + pCellsInfo.getPCellTypeInfo( currGateName ); + if ( currPCellType != null ) { + final String libName = currPCellType.getLibName(); + final String cellName = currPCellType.getCellName(); + final String viewName = + currPCellType.getSchematicViewName(); + if ( ( libName != null ) && + ( cellName != null ) && + ( viewName != null ) ) { + + final Object[] openGateArgs = { + gateTableName, + quoteString( currGateName ), + quoteString( libName ), + quoteString( cellName), + quoteString( viewName ) + }; + openPCellFormatter.format( openGateArgs, + accum, + null ); + } + } + else { + System.out.println( "Unable to find pcell info for \"" + currGateName + "\"." ); + } + } + writer.write( accum.toString() ); + } + } + + private static + void emitTransistors( final Writer writer, + final AbstractNetlist netlist, + final String currCellViewExpression, + final String transistorTableName, + final PCellTypesInfo pCellsInfo, + final MessageFormat createTransistorFormatter ) + throws IOException + { + final StringBuffer accumulator = new StringBuffer(); + + final FETIterator fetIter = + new FETIterator( netlist.getDevices() ); + + while ( fetIter.hasNext() ) { + final FETIterator.FET currFET = fetIter.next(); + + final TransistorTypeInfo currTransistorInfo = + pCellsInfo.getTransistorInfo( currFET.getType() ); + + if ( currTransistorInfo != null ) { + + final String wParamType = + currTransistorInfo.getParamType( "W" ); + final String lParamType = + currTransistorInfo.getParamType( "L" ); + + final String gateTerminalName = + currTransistorInfo.getGateTerminalName(); + + final String sourceTerminalName = + currTransistorInfo.getSourceTerminalName(); + + final String drainTerminalName = + currTransistorInfo.getDrainTerminalName(); + + final String bulkTerminalName = + currTransistorInfo.getBulkTerminalName(); + + if ( ( wParamType != null ) && + ( lParamType !=null ) && + ( gateTerminalName != null ) && + ( sourceTerminalName != null ) && + ( drainTerminalName != null ) && + ( bulkTerminalName != null ) ) { + + final String transistorViewExpression = + "( arrayref " + + transistorTableName + + " " + + quoteString( currFET.getType() ) + + " )"; + + final double w = currFET.getWidth(); + final String wStr = Double.toString( w ); + + final double l = currFET.getLength(); + final String lStr = Double.toString( l ); + + final AbstractNode drainNode = currFET.getDrain(); + final String drainNodeName = + drainNode.getCanonicalName().toString(); + + final AbstractNode gateNode = currFET.getGate(); + final String gateNodeName = + gateNode.getCanonicalName().toString(); + + final AbstractNode sourceNode = currFET.getSource(); + final String sourceNodeName = + sourceNode.getCanonicalName().toString(); + + final AbstractNode bulkNode = currFET.getBulk(); + final String bulkNodeName = + bulkNode.getCanonicalName().toString(); + + final Object[] createTransistorArgs = + { + currCellViewExpression, + quoteString( currFET.getName().toString() ), + wStr, + lStr, + quoteString( gateNodeName ), + quoteString( sourceNodeName ), + quoteString( drainNodeName ), + quoteString( bulkNodeName ), + transistorViewExpression, + "\"w\"", + quoteString( wParamType ), + "\"l\"", + quoteString( lParamType ), + quoteString( gateTerminalName ), + quoteString( sourceTerminalName ), + quoteString( drainTerminalName ), + quoteString( bulkTerminalName ) + }; + + createTransistorFormatter.format( createTransistorArgs, + accumulator, + null ); + + } + } + } + writer.write( accumulator.toString() ); + } + + private static + void emitGates( final Writer writer, + final AbstractNetlist netlist, + final String currCellViewExpression, + final String gateTableName, + final PCellTypesInfo pCellsInfo, + final MessageFormat createConnectionFormatter ) + throws FloorPlanningException, IOException { + final String currInstanceVarName = "CurrInstance"; + final StringBuffer accumulator = new StringBuffer(); + + final SubcellIterator subCellsIter = + new SubcellIterator( netlist.getDevices() ); + + while( subCellsIter.hasNext() ) { + final SubcellIterator.SubcellInstance currInstance = + subCellsIter.next(); + + final AbstractNetlist instanceMaster = + currInstance.getInstantiatedNetlist(); + + final String instanceMasterName = instanceMaster.getName().toString(); + + final String instanceName = currInstance.getName().toString(); + + final PCellTypeInfo currGateInfo = + pCellsInfo.getPCellTypeInfo( instanceMasterName ); + + + if ( currGateInfo != null ) { + final Map instanceParamMap = currInstance.getParams(); + + final Set instanceParams = instanceParamMap.entrySet(); + + final Iterator instanceParamsIter = instanceParams.iterator(); + + writer.write( "( when " + + currCellViewExpression + + "\n" + + " (let (\n" + + " ( ParamValueList\n" + + " ( list\n" ); + + while ( instanceParamsIter.hasNext() ) { + final Map.Entry currParam = ( Map.Entry ) instanceParamsIter.next(); + + final String currParamName = ( String ) currParam.getKey(); + + final String currParamType = currGateInfo.getParamType( currParamName ); + + if ( currParamType != null ) { + final Double currParamValue = ( Double ) currParam.getValue(); + writer.write( " ( list \"" + + currParamName + + "\" \"" + + currParamType + + "\" " + + currParamValue.toString() + + " )\n" ); + } + } + writer.write( " )\n" ); + writer.write( " )\n" ); + writer.write( " )\n" ); + writer.write( " ( defvar\n" + + " " + + currInstanceVarName + + "\n" + + " ( dbCreateParamInst\n" + + " " + + currCellViewExpression + + "\n" + + " ( arrayref " + + gateTableName + + " " + + quoteString( instanceMasterName ) + + " )\n" + + " " + + quoteString( instanceName ) + + "\n" + + " ( list 0 0 )\n" + + " \"R0\"\n" + + " 1\n" + + " ParamValueList\n" + + " )\n" + + " )\n" + + " )\n" + + " )\n" ); + + final AbstractNodeIterator connectedNodeIter = + currInstance.getConnectedNodes(); + + final AbstractNodeIterator instanceInputNodeIter = + instanceMaster.getInputNodes(); + + final AbstractNodeIterator instanceOutputNodeIter = + instanceMaster.getOutputNodes(); + + emitConnections( writer, + connectedNodeIter, + instanceInputNodeIter, + currCellViewExpression, + currInstanceVarName, + createConnectionFormatter ); + + emitConnections( writer, + connectedNodeIter, + instanceOutputNodeIter, + currCellViewExpression, + currInstanceVarName, + createConnectionFormatter ); + } + else { + throw new FloorPlanningException( "Unable to get pcell info for \"" + + instanceMasterName + + "\"."); + } + + } + } + + + private static + void emitSubCells( final Writer writer, + final AbstractNetlist netlist, + final NetlistNameParser nParser, + final String currCellViewExpression, + final String viewNameExpression, + final MessageFormat createInstFormatter, + final MessageFormat createConnectionFormatter ) + throws IOException + { + + final String currInstanceVarName = "CurrInstance"; + final StringBuffer accumulator = new StringBuffer(); + + final SubcellIterator subCellsIter = + new SubcellIterator( netlist.getDevices() ); + + while ( subCellsIter.hasNext() ) { + final SubcellIterator.SubcellInstance currInstance = + subCellsIter.next(); + + final AbstractNetlist instanceMaster = + currInstance.getInstantiatedNetlist(); + + final Object[] createInstArgs = { + currCellViewExpression, + currInstanceVarName, + quoteString( nParser.getLibName( instanceMaster.getName() ) ), + quoteString( nParser.getCellName( instanceMaster.getName() ) ), + viewNameExpression, + quoteString( currInstance.getName().toString() ) + }; + + createInstFormatter.format( createInstArgs, + accumulator, + null ); + + writer.write( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + + final AbstractNodeIterator connectedNodeIter = + currInstance.getConnectedNodes(); + + final AbstractNodeIterator instanceInputNodeIter = + instanceMaster.getInputNodes(); + + final AbstractNodeIterator instanceOutputNodeIter = + instanceMaster.getOutputNodes(); + + emitConnections( writer, + connectedNodeIter, + instanceInputNodeIter, + currCellViewExpression, + currInstanceVarName, + createConnectionFormatter ); + + emitConnections( writer, + connectedNodeIter, + instanceOutputNodeIter, + currCellViewExpression, + currInstanceVarName, + createConnectionFormatter ); + + } + } + + private static + void openCellForWriting( final AbstractNetlist netlist, + final Writer writer, + final NetlistNameParser nParser, + final String viewNameExpression, + final String cellViewVarName, + final MessageFormat openSchematicFormatter ) + throws IOException + { + final Object[] openSchematicArgs = { + cellViewVarName, + quoteString( nParser.getLibName( netlist.getName() ) ), + quoteString( nParser.getCellName( netlist.getName() ) ), + viewNameExpression + }; + + final StringBuffer accum = new StringBuffer(); + + + openSchematicFormatter.format( openSchematicArgs, + accum, + null ); + writer.write( accum.toString() ); + + } + + private static void saveAndPurgeCell( final AbstractNetlist netlist, + final Writer writer, + final String currCellViewVarName, + final MessageFormat formatter ) + throws IOException + { + final Calendar myCalendar = Calendar.getInstance(); + + myCalendar.add( Calendar.YEAR, 20 ); + + final Date myDate = myCalendar.getTime(); + + final Object[] saveAndPurgeArgs = { + currCellViewVarName, + myDate + }; + + final StringBuffer accumulator = new StringBuffer(); + + + + formatter.format( saveAndPurgeArgs, accumulator, null ); + + + writer.write( accumulator.toString() ); + } + + + private static + void emitLeafCell( final AbstractNetlist netlist, + final Writer writer, + final String currCellViewExpression, + final String transistorTableName, + final String gateTableName, + final PCellTypesInfo pCellsInfo, + final MessageFormat createTerminalFormatter, + final MessageFormat createTransistorFormatter, + final MessageFormat createConnectionFormatter ) + throws FloorPlanningException, IOException + { + + final AbstractNodeIterator inputNodesIter = netlist.getInputNodes(); + final AbstractNodeIterator outputNodesIter = netlist.getOutputNodes(); + + emitTerminals( writer, + inputNodesIter, + currCellViewExpression, + createTerminalFormatter ); + + emitTerminals( writer, + outputNodesIter, + currCellViewExpression, + createTerminalFormatter ); + + emitTransistors( writer, + netlist, + currCellViewExpression, + transistorTableName, + pCellsInfo, + createTransistorFormatter ); + emitGates( writer, + netlist, + currCellViewExpression, + gateTableName, + pCellsInfo, + createConnectionFormatter ); + } + + + private static + void emitMidLevelCell( final AbstractNetlist netlist, + final Writer writer, + final String currCellViewExpression, + final NetlistNameParser nParser, + final String viewNameExpression, + final MessageFormat createTerminalFormatter, + final MessageFormat createTransistorFormatter, + final MessageFormat createInstFormatter, + final MessageFormat createConnectionFormatter ) + throws IOException + { + + final AbstractNodeIterator inputNodesIter = netlist.getInputNodes(); + final AbstractNodeIterator outputNodesIter = netlist.getOutputNodes(); + + emitTerminals( writer, + inputNodesIter, + currCellViewExpression, + createTerminalFormatter ); + + emitTerminals( writer, + outputNodesIter, + currCellViewExpression, + createTerminalFormatter ); + + emitSubCells( writer, + netlist, + nParser, + currCellViewExpression, + viewNameExpression, + createInstFormatter, + createConnectionFormatter ); + } + + public static Set getLibNames( final List cells, + final NetlistNameParser nParser ) { + final Set ret = new HashSet(); + final SimpleAbstractNetlistIterator cellIter = + new SimpleAbstractNetlistIterator( cells.iterator() ); + + while ( cellIter.hasNext() ) { + final AbstractNetlist currCell = cellIter.next(); + ret.add( nParser.getLibName( currCell.getName() ) ); + } + + return ret; + } + + public static Writer openOutputFile( final String fileName ) + throws FloorPlanningException, IOException + { + final Writer ret; + try { + final OutputStream outputStream = + new FileOutputStream( fileName ); + + ret = new OutputStreamWriter( outputStream ); + } + catch( FileNotFoundException e ) { + final String message = + "Unable to create file \"" + + fileName + "\""; + throw new FloorPlanningException(message); + } + return ret; + } + + public static void emitCells( final List cells, + final Writer skillOutputWriter, + final Writer cellListWriter, + final NetlistNameParser nParser, + final Set gateNetlists, + final PCellTypesInfo pCellsInfo ) + throws FloorPlanningException, IOException + { + + final MessageFormat openSchematicFormatter = + new MessageFormat( openSchematicFormatStr ); + + final MessageFormat saveAndCloseSchematicFormatter = + new MessageFormat( saveAndCloseSchematicFormatStr ); + + final MessageFormat createTerminalFormatter = + new MessageFormat( createTerminalFormatStr ); + + final MessageFormat createTransistorFormatter = + new MessageFormat( createTransistorFormatStr ); + + final MessageFormat createInstFormatter = + new MessageFormat( createInstFormatStr ); + + final MessageFormat createConnectionFormatter = + new MessageFormat( createConnectionFormatStr ); + + final SimpleAbstractNetlistIterator cellIter = + new SimpleAbstractNetlistIterator( cells.iterator() ); + + final String viewNameExpression = "\"netlist\""; + final String currCellViewVarName = "CurrCellView" ; + + final String transistorTableName = "TransistorTable"; + final String gateTableName = "GateTable"; + + if ( cellIter.hasNext() ) { + openTransistors( skillOutputWriter, + transistorTableName, + pCellsInfo ); + openGates( skillOutputWriter, + gateTableName, + pCellsInfo, + gateNetlists); + } + + while ( cellIter.hasNext() ) { + final AbstractNetlist currNetlist = cellIter.next(); + + if ( ! isEmptyCell( currNetlist ) ) { + final String currCellName = + currNetlist.getName().toString() + "\n"; + cellListWriter.write( currCellName ); + + openCellForWriting( currNetlist, + skillOutputWriter, + nParser, + viewNameExpression, + currCellViewVarName, + openSchematicFormatter ); + + if ( isMidLevelCellNetlist( currNetlist, + gateNetlists ) ) { + emitMidLevelCell( currNetlist, + skillOutputWriter, + currCellViewVarName, + nParser, + viewNameExpression, + createTerminalFormatter, + createTransistorFormatter, + createInstFormatter, + createConnectionFormatter ); + } + else { + emitLeafCell( currNetlist, + skillOutputWriter, + currCellViewVarName, + transistorTableName, + gateTableName, + pCellsInfo, + createTerminalFormatter, + createTransistorFormatter, + createConnectionFormatter ); + } + saveAndPurgeCell( currNetlist, + skillOutputWriter, + currCellViewVarName, + saveAndCloseSchematicFormatter ); + skillOutputWriter.flush(); + } + + + } + } + + public static void emitLibs( final List cells, + final NetlistNameParser nParser, + final Writer libListWriter ) + throws IOException + { + final Set libNames = getLibNames( cells, nParser ); + + final Iterator libNamesIter = libNames.iterator(); + + while ( libNamesIter.hasNext() ) { + final String currLibName = ( String ) libNamesIter.next(); + libListWriter.write( currLibName + "\n" ); + } + } + + + + public static void emit( final List cells, + final String skillFileName, + final String outputCellListFileName, + final String libListFileName, + final Set gateNetlists, + final PCellTypesInfo pCellsInfo ) + throws FloorPlanningException, IOException + { + final Writer skillOutputWriter = + openOutputFile( skillFileName ); + + final Writer cellListWriter = + openOutputFile( outputCellListFileName ); + + final Writer libListWriter = + openOutputFile( libListFileName ); + + + final NetlistNameParser myNameParser = + new NetlistNameParser() { + public String getCellName( final HierName netlistName ) { + return netlistName.toString(); + } + public String getLibName( final HierName netlistName ) { + return netlistName.getParent().getParent().toString(); + } + }; + + emitLibs( cells, myNameParser, libListWriter ); + + emitCells( cells, + skillOutputWriter, + cellListWriter, + myNameParser, + gateNetlists, + pCellsInfo ); + + skillOutputWriter.flush(); + skillOutputWriter.close(); + cellListWriter.flush(); + cellListWriter.close(); + libListWriter.flush(); + libListWriter.close(); + } + + + + private static void usage( ) { + + final String className = GenerateFloorPlanningData.class.getName(); + + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className + "\n" + + " --cast-path=path\n" + + " --cdl-file=file\n" + + " --cell=cell\n" + + " --skill-output=file\n" + + " --cell-list-output=file\n" + + " --lib-list-output=file\n" + + " --pcell-libs-output=file\n" + + " --pcell-info-path=path\n" ); + } + + public static void main( String args[] ) throws Exception { + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + final SearchPath castPath = + new FileSearchPath( theArgs.getArgValue( "cast-path", "." ) ); + + final String cdlFileName = theArgs.getArgValue( "cdl-file", null ); + + final String outputSkillFileName = + theArgs.getArgValue( "skill-output", null ); + + final String outputCellListFileName = + theArgs.getArgValue( "cell-list-output", null ); + + final String outputLibListFileName = + theArgs.getArgValue( "lib-list-output", null ); + + final String pcellLibListFileName = + theArgs.getArgValue( "pcell-libs-output", null ); + + final String pcellInfoPathStr = + theArgs.getArgValue( "pcell-info-path", null ); + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + GenerateFloorPlanningData.class)); + } + + if ( ( cdlFileName != null ) && + ( outputSkillFileName != null ) && + ( outputCellListFileName != null ) && + ( outputLibListFileName != null ) && + ( pcellLibListFileName != null ) && + ( pcellInfoPathStr != null ) ){ + + final File cdlFile = new File( cdlFileName ); + + final FileSearchPath pcellInfoPath = + new FileSearchPath( pcellInfoPathStr ); + + final PCellTypesInfo pCellsInfo = + new PCellTypesInfoImpl( pcellInfoPath.getSearchPath() ); + + if ( cdlFile.isFile() && + cdlFile.canRead() ) { + final SimpleNetlistFactory netlistFactory = + new SimpleNetlistFactory(); + final Set gateNetlists = + getGateNetlists( pCellsInfo , netlistFactory ); + try { + final List cells = + getNetlistsInOrder( cdlFile, + netlistFactory, + gateNetlists ); + + emit( cells, + outputSkillFileName, + outputCellListFileName, + outputLibListFileName, + gateNetlists, + pCellsInfo ); + + final Writer pcellLibListWriter = + openOutputFile( pcellLibListFileName ); + + final Set pcellLibList = new HashSet(); + + final Iterator pcellsInfosIter = pCellsInfo.getAllPCellTypeInfos(); + + while ( pcellsInfosIter.hasNext() ) { + final PCellTypeInfo currInfo = + ( PCellTypeInfo ) pcellsInfosIter.next(); + + pcellLibList.add( currInfo.getLibName() ); + } + + final Iterator pcellLibNamesIter = pcellLibList.iterator(); + + while ( pcellLibNamesIter.hasNext() ) { + final String currLibName = ( String ) pcellLibNamesIter.next(); + pcellLibListWriter.write( currLibName + "\n" ); + } + pcellLibListWriter.close(); + + } + catch ( FloorPlanningException e ) { + System.out.println( e.getMessage() ); + } + + + } + } + else { + if ( cdlFileName == null ) { + System.out.println( "The name of the cdl file to read" + + " must be specified." ); + } + if ( outputSkillFileName == null ) { + System.out.println( "The name of the skill file to generate" + + " must be specified." ); + } + if ( outputCellListFileName == null ) { + System.out.println( "The name of the cell list file" + + " to generate" + + " must be specified." ); + } + if ( outputLibListFileName == null ) { + System.out.println( "The name of the library list file" + + " to generate must be specified." ); + } + if ( pcellLibListFileName == null ) { + System.out.println( "The name of the pcell library list file" + + " to generate must be specified." ); + } + if ( pcellInfoPathStr == null ) { + System.out.println( "You must specify a path in which to" + + " search for pcell information." ); + } + usage(); + } + + + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypeInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypeInfo.java new file mode 100644 index 0000000000..ae9409f85c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypeInfo.java @@ -0,0 +1,19 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.floorplanning; + + +interface PCellTypeInfo { + + String getLibName( ); + String getCellName( ); + String getLayoutViewName( ); + String getSchematicViewName(); + + String getParamType( final String name ); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfo.java new file mode 100644 index 0000000000..47afefb8be --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfo.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.floorplanning; + +import java.util.Iterator; + +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.floorplanning.PCellTypeInfo; +import com.avlsi.floorplanning.TransistorTypeInfo; + + +interface PCellTypesInfo { + + PCellTypeInfo getPCellTypeInfo( final String cellName ); + + TransistorTypeInfo getTransistorInfo( final String modelName ); + + StringContainerIterator getTransistorModels(); + + Iterator getAllPCellTypeInfos(); + + Iterator getNonTransistorPCellTypeInfos(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfoImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfoImpl.java new file mode 100644 index 0000000000..f4060e9c9c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PCellTypesInfoImpl.java @@ -0,0 +1,146 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.floorplanning; + +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import java.io.File; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.FileNotFoundException; + +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.container.Iterator2StringContainerIteratorAdapter; + +import com.avlsi.floorplanning.PCellTypesInfo; +import com.avlsi.floorplanning.PCellTypeInfo; +import com.avlsi.floorplanning.TransistorTypeInfo; +import com.avlsi.floorplanning.PropertyFilePCellTypeInfo; +import com.avlsi.floorplanning.PropertyFileTransistorTypeInfo; + +public class PCellTypesInfoImpl implements PCellTypesInfo { + + private final Map m_PCellTypesInfo; + private final Map m_TransistorTypesInfo; + + public PCellTypesInfoImpl( final StringContainerIterator dirNames ) { + m_PCellTypesInfo = new HashMap(); + m_TransistorTypesInfo = new HashMap(); + + while ( dirNames.hasNext() ) { + final String currDirName = dirNames.next(); + + final File currDir = new File( currDirName ); + + if ( currDir.isDirectory() && currDir.canRead() ) { + final File[] infoFiles = currDir.listFiles(); + + int i; + for ( i = 0 ; i < infoFiles.length ; ++i ) { + if ( infoFiles[i].isFile() && infoFiles[i].canRead() ) { + try { + final InputStream infoFileStream = + new FileInputStream( infoFiles[i] ); + final Properties info = + new Properties(); + info.load( infoFileStream ); + + final boolean isTransistorInfo = + PropertyFileTransistorTypeInfo.isTransistorInfo( info ); + if ( isTransistorInfo ) { + final PropertyFileTransistorTypeInfo tInfo = + new PropertyFileTransistorTypeInfo( info ) ; + m_TransistorTypesInfo.put( tInfo.getModelName(), + tInfo ); + } + else { + final PropertyFilePCellTypeInfo pInfo = + new PropertyFilePCellTypeInfo( info ) ; + m_PCellTypesInfo.put( pInfo.getCellName(), + pInfo ); + } + } + catch( FileNotFoundException e ) { + } + catch( IOException e ) { + } + + } + } + + } + } + + } + + public PCellTypeInfo getPCellTypeInfo( final String cellName ) { + return ( PCellTypeInfo ) m_PCellTypesInfo.get( cellName ); + } + + public TransistorTypeInfo getTransistorInfo( final String modelName ) { + return ( TransistorTypeInfo ) m_TransistorTypesInfo.get( modelName ); + } + + public StringContainerIterator getTransistorModels() { + + final Iterator keyIter = + m_TransistorTypesInfo.keySet().iterator(); + + final StringContainerIterator ret = + new Iterator2StringContainerIteratorAdapter( keyIter ); + + return ret; + } + + public Iterator getAllPCellTypeInfos() { + return new Iterator() { + final private Iterator firstIter = m_TransistorTypesInfo.entrySet().iterator(); + final private Iterator secondIter = m_PCellTypesInfo.entrySet().iterator(); + + public boolean hasNext() { + return ( firstIter.hasNext() || secondIter.hasNext() ); + } + + public Object next() { + if ( firstIter.hasNext() ) { + return ( ( Map.Entry ) firstIter.next()).getValue(); + } + else { + return ( ( Map.Entry ) secondIter.next()).getValue(); + } + } + public void remove() { + + } + }; + } + + public Iterator getNonTransistorPCellTypeInfos() { + return new Iterator() { + final private Iterator entryIter = m_PCellTypesInfo.entrySet().iterator(); + public boolean hasNext() { + return entryIter.hasNext(); + } + + public Object next() { + final Map.Entry currEntry = ( Map.Entry ) entryIter.next(); + return currEntry.getValue(); + } + + public void remove() { + entryIter.remove(); + } + }; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFilePCellTypeInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFilePCellTypeInfo.java new file mode 100644 index 0000000000..f1bf2c4a15 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFilePCellTypeInfo.java @@ -0,0 +1,56 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.floorplanning; + +import com.avlsi.floorplanning.PCellTypeInfo; + +import java.io.InputStream; +import java.io.IOException; + +import java.util.Properties; + +class PropertyFilePCellTypeInfo implements PCellTypeInfo { + + private final Properties info; + + public PropertyFilePCellTypeInfo( final Properties p ) { + info = p; + } + + public PropertyFilePCellTypeInfo( final InputStream input ) + throws IOException + { + info = new Properties(); + info.load( input ); + } + + protected final String get( final String key ) { + return info.getProperty( key ); + } + + public String getLibName( ) { + return get( "library" ); + } + + public String getCellName( ) { + return get( "cell" ); + } + + public String getLayoutViewName( ) { + return get( "layout" ); + } + + public String getSchematicViewName( ) { + return get( "schematic" ); + } + + public String getParamType( final String name ) { + return get( name ); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFileTransistorTypeInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFileTransistorTypeInfo.java new file mode 100644 index 0000000000..765f63e6e3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/PropertyFileTransistorTypeInfo.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.floorplanning; + + +import com.avlsi.floorplanning.PCellTypeInfo; + +import java.io.InputStream; +import java.io.IOException; + +import java.util.Properties; + +class PropertyFileTransistorTypeInfo extends PropertyFilePCellTypeInfo + implements TransistorTypeInfo + +{ + + + public PropertyFileTransistorTypeInfo( final Properties p ) { + super( p ); + } + + public PropertyFileTransistorTypeInfo( final InputStream input ) + throws IOException + { + super( input ); + } + + public String getModelName() { + return get( "model" ); + } + + public String getGateTerminalName() { + return get( "gate" ); + } + + public String getSourceTerminalName() { + return get( "source" ); + } + + public String getDrainTerminalName() { + return get( "drain" ); + } + + public String getBulkTerminalName() { + return get( "bulk" ); + } + + public static boolean isTransistorInfo( Properties info ) { + return info.getProperty( "model" ) != null; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/TransistorTypeInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/TransistorTypeInfo.java new file mode 100644 index 0000000000..fb8a8a5b6c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/floorplanning/TransistorTypeInfo.java @@ -0,0 +1,21 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.floorplanning; + +import com.avlsi.floorplanning.PCellTypeInfo; + + +interface TransistorTypeInfo extends PCellTypeInfo { + + String getModelName(); + String getGateTerminalName(); + String getSourceTerminalName(); + String getDrainTerminalName(); + String getBulkTerminalName(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/BoundingBox.java b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/BoundingBox.java new file mode 100644 index 0000000000..8a0cb37e85 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/BoundingBox.java @@ -0,0 +1,180 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.geometry; + +/** + * This class represents the bounding box of an object in 2D space. + * Coordinates are doubles. The class is immutable. + * The lower left and upper right corners satify the constraints: + * + * BoundingBox bb; + * bb.getLowerLeft().getX() <= bb.getUpperRight().getX() + * && bb.getLowerLeft().getY() <= bb.getUpperRight().getY() + * + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class BoundingBox { + /** + * The lower left corner of the bounding box. + **/ + private final Point lowerLeft; + + /** + * The upper right corner of the bounding box. + **/ + private final Point upperRight; + + /** + * Class constructor. If the corner arguments do not satisfy + * the constraints, the x and y values will be swapped so that the + * constraints are satisfied. + * + * @param lowerLeft lower left corner + * @param upperRight upper right corner + **/ + public BoundingBox(final Point lowerLeft, final Point upperRight) + { + if (lowerLeft.getX() <= upperRight.getX() + && lowerLeft.getY() <= upperRight.getY()) { + this.lowerLeft = lowerLeft; + this.upperRight = upperRight; + } + else { + // normalize the coords so that the box is proper + final double llx, urx; + + if (lowerLeft.getX() < upperRight.getX()) { + llx = lowerLeft.getX(); + urx = upperRight.getX(); + } else { + llx = upperRight.getX(); + urx = lowerLeft.getX(); + } + + final double lly, ury; + + if (lowerLeft.getY() < upperRight.getY()) { + lly = lowerLeft.getY(); + ury = upperRight.getY(); + } else { + lly = upperRight.getY(); + ury = lowerLeft.getY(); + } + + this.lowerLeft = new Point(llx, lly); + this.upperRight = new Point(urx, ury); + } + } + + /** + * Class constructor. If the corner arguments do not satisfy + * the constraints, the x and y values will be swapped so that the + * constraints are satisfied. + * + * @param lowerLeftX x coord of lower left corner + * @param lowerLeftY y coord of lower left corner + * @param upperRightX x coord of upper right corner + * @param upperRightY y coord of upper right corner + **/ + public BoundingBox(final double lowerLeftX, + final double lowerLeftY, + final double upperRightX, + final double upperRightY) + { + // normalize the coords so that the box is proper + final double llx, urx; + + if (lowerLeftX < upperRightX) { + llx = lowerLeftX; + urx = upperRightX; + } else { + llx = upperRightX; + urx = lowerLeftX; + } + + final double lly, ury; + + if (lowerLeftY < upperRightY) { + lly = lowerLeftY; + ury = upperRightY; + } else { + lly = upperRightY; + ury = lowerLeftY; + } + + lowerLeft = new Point(llx, lly); + upperRight = new Point(urx, ury); + } + + /** + * Returns the lower left corner. + * @return the lower left corner + **/ + public Point getLowerLeft() { + return lowerLeft; + } + + /** + * Returns the upper right corner. + * @return the upper right corner + **/ + public Point getUpperRight() { + return upperRight; + } + + /** + * Returns the x span of the bounding box. + **/ + public double getWidth() { + return getUpperRight().getX() - getLowerLeft().getX(); + } + + /** + * Returns the y span of the bounding box. + **/ + public double getHeight() { + return getUpperRight().getY() - getLowerLeft().getY(); + } + + /** + * Returns the 1/2 Perimeter of the bounding box. + **/ + public double getHalfPerimeter() { + return getWidth() + getHeight(); + } + + /** + * Returns the center of the bounding box. + **/ + public Point getCenter() { + return new Point( lowerLeft.getX() + 0.5 * getWidth(), + lowerLeft.getY() + 0.5 * getHeight() ); + } + + public boolean equals(Object o) { + if (o instanceof BoundingBox) { + final BoundingBox b = (BoundingBox) o; + return lowerLeft.equals(b.lowerLeft) && + upperRight.equals(b.upperRight); + } else { + return false; + } + } + + public String toString() { + return "[" + lowerLeft + " " + upperRight + "]"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Point.java b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Point.java new file mode 100644 index 0000000000..2fc1a503bf --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Point.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.geometry; + +/** + * This class represents a point with double coordinates in 2D space. + * Points are treated as column vectors. + * The class is immutable. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class Point { + private final double x; + private final double y; + + public Point (final double x, final double y) + { + this.x = x; + this.y = y; + } + + /** + * Returns the x coordinate of the point + * @return the x coordinate of the point + **/ + public double getX() { return x; } + + /** + * Returns the y coordinate of the point + * @return the y coordinate of the point + **/ + public double getY() { return y; } + + public boolean equals(Object o) { + if (o instanceof Point) { + final Point p = (Point) o; + return p.x == x && p.y == y; + } else { + return false; + } + } + + public String toString() { + return "(" + x + ", " + y + ")"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/SteinnerTree.java b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/SteinnerTree.java new file mode 100644 index 0000000000..e1a29ef279 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/SteinnerTree.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.geometry; + +/** + * Class to represent steinner trees. + * + * @author Aaron Denney + * @version $Date$ + **/ + +public abstract class SteinnerTree { + /** + * constructor surrogate. + * + * The two arrays should be of the same size represent the x and + * y coördinates of the points to be joined in a Steinner tree. + * + * Should be static, but ... + **/ + public abstract SteinnerTree factory(float x[], float y[]); + /** + * @return the sum of the lengths of all segments of the tree. + * @throws ArrayIndexOutOfBoundsException on differing array sizes. + **/ + public abstract float getTotalLength(); + /** + * @return the sum of the lengths of the segments of the path connecting the two + * points. + * + * @throws ArrayIndexOutOfBoundsException on + **/ + public abstract float getLength(int index1, int index2); + /** + * @return number of points we are supposed to cover. + **/ + public abstract int getInitialPointCount(); + /** + * @return number of points added to reduce total length. + **/ + public abstract int getAddedPointCount(); + /** + * @return x coördinate of point number index + * @throws ArrayIndexOutOfBoundsException on index >= getInitialPointCount() + getAddedPointCount();. + */ + public abstract float getX(int index); + /** + * @return y coördinate of point number index + * @throws ArrayIndexOutOfBoundsException on index >= getInitialPointCount() + getAddedPointCount();. + */ + public abstract float getY(int index); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Transform.java b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Transform.java new file mode 100644 index 0000000000..39e0d702f5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/geometry/Transform.java @@ -0,0 +1,107 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.geometry; + +/** + * Transformation class to transform {@link Point}s, and + * {@link BoundingBox}es. The transformation is a matrix that + * premultiplies points, which are column vectors. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class Transform { + private final double[][] forward; + private final double[][] inverse; + + /** + * Class constructor. The matrix of the transform will be: + * + * a b c
    + * d e f
    + * 0 0 1 + *
    + **/ + public Transform(final double a, final double b, final double c, + final double d, final double e, final double f) + { + forward = new double[][] { + { a, b, c }, + { d, e, f }, + { 0, 0, 1 }, }; + + final double det = a * e - b * d; + inverse = new double[][] { + { e / det , -b / det , (b * f - c * e) / det }, + { -d / det , a / det , (c * d - a * f) / det }, + { 0 , 0 , 1 }, }; + } + + /** + * Transform a point. + * @param p point to be transformed + * @return the transformed point + **/ + public Point transform(final Point p) { + return transform(forward, p); + } + + /** + * Transform a point, using the inverse transformation. + * @param p point to be transformed + * @return the transformed point + **/ + public Point inverseTransform(final Point p) { + return transform(inverse, p); + } + + /** + * Transform a point, using the specified transformation matrix. + * @param t the transformation matrix + * @param p point to be transformed + * @return the transformed point + **/ + private Point transform(final double[][] t, final Point p) { + final double px = p.getX(); + final double py = p.getY(); + + final double x = t[0][0] * px + t[0][1] * py + t[0][2]; + final double y = t[1][0] * px + t[1][1] * py + t[1][2]; + final double w = t[2][0] * px + t[2][1] * py + t[2][2]; + + return new Point(x / w, y / w); + } + + /** + * Transform a bounding box. + * @param bb bounding box to be transformed + * @return the transformed bounding box + **/ + public BoundingBox transform(final BoundingBox bb) { + return new BoundingBox( + transform(bb.getLowerLeft()), + transform(bb.getUpperRight())); + } + + /** + * Transform a bounding box, using the inverse transformation. + * @param bb bounding box to be transformed + * @return the transformed bounding box + **/ + public BoundingBox inverseTransform(final BoundingBox bb) { + return new BoundingBox( + inverseTransform(bb.getLowerLeft()), + inverseTransform(bb.getUpperRight())); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/CopyingOutputStream.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/CopyingOutputStream.java new file mode 100644 index 0000000000..488063a9ab --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/CopyingOutputStream.java @@ -0,0 +1,51 @@ +/* + * Copyright 2005 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.io; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Copy one OutputStream to multiple OutputStreams. + */ +public class CopyingOutputStream extends OutputStream { + private final OutputStream[] streams; + + /** + * Specifies the output streams you want to copy to. + * This can be any number of streams, including 1 (which is + * kind of pointless) or 0 (which gives you the effect of + * /dev/null). + */ + public CopyingOutputStream(OutputStream[] streams) { + this.streams = streams; + } + + public void close() throws IOException { + for (int i = 0; i < streams.length; i++) + streams[i].close(); + } + + public void flush() throws IOException { + for (int i = 0; i < streams.length; i++) + streams[i].flush(); + } + + public void write(byte[] b) throws IOException { + for (int i = 0; i < streams.length; i++) + streams[i].write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + for (int i = 0; i < streams.length; i++) + streams[i].write(b, off, len); + } + + public void write(int b) throws IOException { + for (int i = 0; i < streams.length; i++) + streams[i].write(b); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/EmptyPositionStackException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/EmptyPositionStackException.java new file mode 100644 index 0000000000..fd14565c2c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/EmptyPositionStackException.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Throws by methods in PositionStackReader class to indicate + * that the position stack is empty. + * + * @see PositionStackReader + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class EmptyPositionStackException extends RuntimeException { + /** + * Constructs a new EmptyPositionStackException with + * null as its error message string. + **/ + public EmptyPositionStackException() { + } + + public EmptyPositionStackException(Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/FileSearchPath.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/FileSearchPath.java new file mode 100644 index 0000000000..2d041ec293 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/FileSearchPath.java @@ -0,0 +1,550 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.io; + +import java.io.File; + +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; +import java.util.NoSuchElementException; + + +import com.avlsi.util.text.StringUtil; + +import com.avlsi.io.SearchPath; +import com.avlsi.io.SearchPathFile; +import com.avlsi.io.SearchPathFileFilter; +import com.avlsi.io.TrivialSearchPathFile; + + +import com.avlsi.util.container.StringContainerIterator; + + +/** + * This class represents a search path for files. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class FileSearchPath implements SearchPath { + + public interface SearchPathFileFactory { + SearchPathFile getSearchPathFile(File file); + SearchPathFile getSearchPathFile(File file, boolean isCanon); + } + + public static final class DefaultSearchPathFileFactory + implements SearchPathFileFactory { + public SearchPathFile getSearchPathFile(File file) { + return new TrivialSearchPathFile(file); + } + public SearchPathFile getSearchPathFile(File file, boolean isCanon) { + return new TrivialSearchPathFile(file, isCanon); + } + } + + public static final class TrackingSearchPathFileFactory + implements SearchPathFileFactory { + + private final Collection history; + private static final class TrackingSearchPathFile + extends TrivialSearchPathFile { + + private final Collection history; + public TrackingSearchPathFile(File file, Collection history) { + super(file); + this.history = history; + } + public TrackingSearchPathFile(File file, boolean isCanon, Collection history) { + super(file,isCanon); + this.history = history; + } + public InputStream getStream() + throws java.io.FileNotFoundException { + history.add(getName()); + return super.getStream(); + } + } + + public SearchPathFile getSearchPathFile(File file) { + return new TrackingSearchPathFile(file,history); + } + public SearchPathFile getSearchPathFile(File file, boolean isCanon) { + return new TrackingSearchPathFile(file,isCanon,history); + } + public TrackingSearchPathFileFactory(final Collection history) { + this.history = history; + } + } + + private static final class FileSearchPathDirectory implements SearchPathDirectory { + private final File m_File ; + private final File[] m_SubDirs; + private final File[] m_Files; + private final SearchPathFileFactory m_Factory; + + public FileSearchPathDirectory( final File theFile , + final SearchPathFileFactory factory) { + m_File = theFile; + m_Factory = factory; + + final File[] entries = theFile.listFiles(); + + if ( entries != null ) { + + int readPos; + int numDirs = 0; + int numFiles = 0; + + for ( readPos = 0 ; readPos < entries.length ; ++readPos ) { + if ( entries[readPos].canRead() ) { + if ( entries[readPos].isDirectory() ) { + ++numDirs; + } + else { + ++numFiles; + } + } + } + + m_SubDirs = new File[numDirs]; + m_Files = new File[numFiles]; + + int dirWritePos = 0; + int fileWritePos = 0; + + for ( readPos = 0 ; readPos < entries.length ; ++readPos ) { + + if ( entries[readPos].canRead() ) { + if ( entries[readPos].isDirectory() ) { + + m_SubDirs[dirWritePos] = entries[readPos]; + ++dirWritePos; + } + else { + m_Files[ fileWritePos] = entries[readPos]; + ++fileWritePos; + } + } + } + } + else { + m_SubDirs = null; + m_Files = null; + } + } + + public String getName() { + return m_File.getAbsolutePath(); + } + + public SearchPathDirectoryIterator getSubDirectories() { + return new SearchPathDirectoryIterator() { + + private final File[] dirs = m_SubDirs; + + private int currIndex = 0; + + public final boolean hasNext() { + return ( dirs != null ) && ( currIndex < dirs.length ); + } + + public final SearchPathDirectory next() { + + if ( hasNext() ) { + final SearchPathDirectory ret = new FileSearchPathDirectory( dirs[ currIndex ], m_Factory ); + ++currIndex; + return ret; + } + else { + throw new NoSuchElementException(); + } + + } + + + }; + + + + } + + public SearchPathFileIterator getFiles() { + return new SearchPathFileIterator() { + private final File[] files = m_Files; + private int currIndex; + + public final boolean hasNext() { + return ( files != null ) && ( currIndex < files.length ); + } + + public final SearchPathFile next() { + + if ( hasNext() ) { + final SearchPathFile ret = m_Factory.getSearchPathFile( files[ currIndex ] ); + ++currIndex; + return ret; + } + else { + throw new NoSuchElementException(); + } + + } + }; + } + + public SearchPathFileIterator getFiles( final SearchPathFileFilter f ) { + return new SearchPathFileIterator() { + private final SearchPathFileIterator m_InnerIter = getFiles(); + + private final SearchPathFileFilter m_Filter = f; + + SearchPathFile m_NextFile = null; + + private void updateNextFile( ) { + while ( ( m_NextFile == null ) && ( m_InnerIter.hasNext() ) ){ + final SearchPathFile currFile = ( SearchPathFile ) m_InnerIter.next(); + + if ( f.accept( currFile ) ) { + m_NextFile = currFile; + } + } + } + + public final boolean hasNext() { + updateNextFile(); + return m_NextFile != null; + } + + public final SearchPathFile next() { + + if ( hasNext() ) { + final SearchPathFile ret = m_NextFile; + m_NextFile = null; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + + }; + } + + } + + /** + * Array of directory names to be searched. + * + * TODO: convert to a Vector. + **/ + private String[] dirs; + private final SearchPathFileFactory spfFactory; + + /** + * Used to create SearchPathFiles. + **/ + + public FileSearchPath(final String path) { + this(path, new DefaultSearchPathFileFactory()); + } + + /** + * Constructs a new search path from the given colon separated path. + **/ + public FileSearchPath(final String path, + final SearchPathFileFactory spfFactory) { + this(path, System.getProperty( "user.home" ), spfFactory ); + } + + public FileSearchPath(final String path, final String homeDir) { + this(path, homeDir, new DefaultSearchPathFileFactory()); + } + + public FileSearchPath(final String path, final String homeDir, + final SearchPathFileFactory spfFactory) { + this(path, homeDir, System.getProperty( "user.name" ), spfFactory); + } + + /** + * Constructs a new search path from the given colon separated path. + * Occurences of ~ are replaced with homeDir. + **/ + public FileSearchPath(final String path, final String homeDir, + final String userName, + final SearchPathFileFactory spfFactory) { + this.spfFactory = spfFactory; + + final String seperatorChar = System.getProperty("path.separator", ":"); + + final StringTokenizer st = new StringTokenizer(path, seperatorChar); + final List dirList = new ArrayList(); + + while (st.hasMoreTokens()) { + String dir = (String) st.nextToken(); + + if (homeDir != null) { + if (dir.equals("~")) + dir = homeDir; + else if (dir.startsWith("~/")) + dir = homeDir + '/' + StringUtil.chompStart(dir, "~/"); + else { + final String start = '~' + userName + '/'; + if (dir.startsWith(start)) + dir = homeDir + '/' + StringUtil.chompStart(dir, start); + } + } + + if (dir.length() > 0) + dirList.add(dir); + } + + dirs = (String[]) dirList.toArray(new String[0]); + } + + public FileSearchPath(final String[] dirs) { + this(dirs, new DefaultSearchPathFileFactory()); + } + + /** + * Constructs a search path from the specified array of paths + **/ + public FileSearchPath(final String[] dirs, + final SearchPathFileFactory spfFactory) { + this.spfFactory = spfFactory; + this.dirs = new String[dirs.length]; + System.arraycopy(dirs, 0, this.dirs, 0, dirs.length); + } + + /** + * Returns the first file of name fileName found in the search path. + * If the fileName is an an absolute path, return it. + * + * @exception FileNotFoundException if the file could not be found + * in the search path + **/ + public InputStream openFileAsStream(final String fileName) + throws FileNotFoundException + { + final SearchPathFile theFile = findFile( fileName ); + return theFile.getStream(); + } + + private String generateErrorMessage( final String fileName ) { + final StringBuffer errorMessage = new StringBuffer( fileName ); + + final StringContainerIterator iter = getSearchPath(); + + errorMessage.append( " not found in:" ); + + boolean hasTilde = false; + + while ( iter.hasNext() ) { + errorMessage.append( "\n " ); + final String next = iter.next(); + if ( next.startsWith( "~" ) ) hasTilde = true; + errorMessage.append( next ); + } + errorMessage.append( '\n' ); + + // an additional hint on ~ expansion limitations + if ( hasTilde ) { + errorMessage.append( + "note: expansion of ~anotherUser in path is not supported\n" ); + } + + return errorMessage.toString(); + } + + private String generateErrorMessage(final String[] fileNames) { + final StringBuffer files = new StringBuffer(); + + for (int i = 0; i < fileNames.length; ++i) + files.append(fileNames[i]).append(' '); + + return generateErrorMessage(files.toString()); + } + + public SearchPathFile findFile( final String fileName ) throws FileNotFoundException { + final File absFileObj = new File( fileName ); + + File currFileObj = null; + + if ( absFileObj.isAbsolute() ) { + try { + currFileObj = absFileObj.getCanonicalFile(); + } + catch ( IOException e ) { + throw (FileNotFoundException) + new FileNotFoundException( generateErrorMessage( fileName ) ) + .initCause(e); + } + } + else { + for (int i = 0; i < dirs.length && currFileObj == null; ++i) { + final File candidate = getFile(i, fileName); + if (candidate.canRead() && candidate.isFile()) { + try { + currFileObj = candidate.getCanonicalFile(); + } catch (IOException e) { + currFileObj = null; + } + } + } + } + + if ( ( currFileObj != null ) && ( currFileObj.canRead() ) ) { + return spfFactory.getSearchPathFile( currFileObj, true ); + } + else { + + throw new FileNotFoundException( generateErrorMessage( fileName ) ); + } + } + + public SearchPathFile findFirstFileOf(final String[] fileNames) + throws FileNotFoundException { + + if (fileNames.length == 0) + throw new IllegalArgumentException("No file names specified."); + + + for (int i = 0; i < dirs.length; ++i) { + for (int j = 0; j < fileNames.length; ++j) { + final File candidate = getFile(i, fileNames[j]); + if (candidate.canRead()) { + try { + return spfFactory.getSearchPathFile(candidate.getCanonicalFile(), true); + } catch (IOException e) { + // do nothing + } + } + } + } + + throw new FileNotFoundException(generateErrorMessage(fileNames)); + } + + public SearchPathDirectory findDirectory( final String dirName ) throws FileNotFoundException { + final File absFileObj = new File( dirName ); + File currFileObj = null; + + if ( absFileObj.isAbsolute() ) { + try { + currFileObj = absFileObj.getCanonicalFile(); + } + catch ( IOException e ) { + throw (FileNotFoundException) + new FileNotFoundException( generateErrorMessage( dirName ) ) + .initCause(e); + } + } + else { + for (int i = 0; i < dirs.length && currFileObj == null; ++i) { + final File candidate = getFile(i, dirName); + if (candidate.canRead() && candidate.isDirectory()) { + try { + currFileObj = candidate.getCanonicalFile(); + } catch (IOException e) { + currFileObj = null; + } + } + } + } + + if ( ( currFileObj != null ) && ( currFileObj.canRead() ) ) { + + return new FileSearchPathDirectory( currFileObj, spfFactory ); + + } + else { + throw new FileNotFoundException( generateErrorMessage( dirName ) ); + } + } + + + /** + * Returns the components of the search path as an unmodifiable + * Iterator. + **/ + public StringContainerIterator getSearchPath() { + return new StringContainerIterator() { + private final String[] myEntries = dirs; + private int currIndex = 0; + + public final boolean hasNext() { + return currIndex < myEntries.length; + } + + public final String next() { + if ( hasNext() ) { + final String ret = myEntries[currIndex]; + ++currIndex; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + + }; + } + + /** + * Returns true if the specified directory is part of this path. + * (Note that being a subdirectory of part of this path isn't good + * enough.) This is used for verifying module names. dirName is + * assumed to end with a '/'. + **/ + public boolean containsDirectory(String dirName) { + for (int i=0; ifile. If file is a directory, delete + * the hierarchy under it. If file is not, just delete + * it. + * + * @return true if and only if the entire hierarchy was + * successfully deleted; false otherwise. + * + * @param file + * The file or directory to be deleted. + **/ + public static boolean recursiveDelete(final /*@ non_null @*/ File file) { + boolean allRemoved = true; + final File[] files = file.listFiles(); + if (files != null) + for (int i = 0; i < files.length; ++i) + allRemoved &= recursiveDelete(files[i]); + + allRemoved &= file.delete(); + + return allRemoved; + } + + public static List getLines(final File file) throws IOException { + final List lines = new LinkedList(); + final InputStream is = new FileInputStream( file ); + final Reader r = new InputStreamReader( is, "UTF-8" ); + final BufferedReader br = new BufferedReader( r ); + String line; + while((line = br.readLine()) != null) { + lines.add(line); + } + return lines; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentPrintWriter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentPrintWriter.java new file mode 100644 index 0000000000..81ae2f1c2e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentPrintWriter.java @@ -0,0 +1,107 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.io; + +import java.io.PrintWriter; +import java.io.Writer; + +/** + * Class that provides a general way to indent output. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public class IndentPrintWriter extends PrintWriter { + /** Current level of indenting. */ + private int level; + + /** The "tab" string. */ + private final String tab; + + /** Is the last character written a newline? */ + private boolean nl; + + /** + * Constructs a new IndentWriter object. The indent string is set to 2 + * spaces. + * @param out a Writer object to provide the underlying stream. + **/ + public IndentPrintWriter(Writer out) { + this(out, " "); + } + + /** + * Constructs a new IndentWriter object. + * @param out a Writer object to provide the underlying stream. + * @param tab a String to print for each indent level. + **/ + public IndentPrintWriter(Writer out, String tab) { + super(out); + this.level = 0; + this.tab = tab; + this.nl = false; + } + + public void println() { + nl = true; + super.println(); + } + + private void indent() { + if (nl) { + for (int i = 0; i < level; ++i) super.write(tab, 0, tab.length()); + nl = false; + } + } + + public void write(int c) { + indent(); + super.write(c); + } + + public void write(char buf[], int off, int len) { + indent(); + super.write(buf, off, len); + } + + public void write(String s, int off, int len) { + indent(); + super.write(s, off, len); + } + + /** + * Sets the current indenting level. Clamp the level to 0. + * @param level New level of indenting. + **/ + public void setLevel(int level) { + if (level < 0) level = 0; + this.level = level; + } + + /** + * Returns the current indenting level. + * @return Current level of indenting. + **/ + public int getLevel() { + return level; + } + + /** + * Increment the indenting level. + **/ + public void nextLevel() { + setLevel(getLevel() + 1); + } + + /** + * Decrement the indenting level. + **/ + public void prevLevel() { + setLevel(getLevel() - 1); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentWriter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentWriter.java new file mode 100644 index 0000000000..e1716bf001 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/IndentWriter.java @@ -0,0 +1,102 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.io; + +import java.io.FilterWriter; +import java.io.IOException; +import java.io.Writer; + +/** + * Class that provides a general way to indent output. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public final class IndentWriter extends FilterWriter { + /** Current level of indenting. */ + private int level; + + /** The "tab" string. */ + private final String tab; + + /** Is the last character written a newline? */ + private boolean nl; + + /** + * Constructs a new IndentWriter object. The indent string is set to 2 + * spaces. + * @param out a Writer object to provide the underlying stream. + **/ + public IndentWriter(Writer out) { + this(out, " "); + } + + /** + * Constructs a new IndentWriter object. + * @param out a Writer object to provide the underlying stream. + * @param tab a String to print for each indent level. + **/ + public IndentWriter(Writer out, String tab) { + super(out); + this.level = 0; + this.tab = tab; + this.nl = false; + } + + public void write(char[] cbuf, int off, int len) throws IOException { + for (int i = 0; i < len; ++i, ++off) write(cbuf[off]); + } + + public void write(String str, int off, int len) throws IOException { + for (int i = 0; i < len; ++i, ++off) write(str.charAt(off)); + } + + public void write(int c) throws IOException { + if (c == '\n') { + nl = true; + } else { + if (nl) { + for (int i = 0; i < level; ++i) + out.write(tab, 0, tab.length()); + nl = false; + } + } + out.write(c); + } + + /** + * Sets the current indenting level. Clamp the level to 0. + * @param level New level of indenting. + **/ + public void setLevel(int level) { + if (level < 0) level = 0; + this.level = level; + } + + /** + * Returns the current indenting level. + * @return Current level of indenting. + **/ + public int getLevel() { + return level; + } + + /** + * Increment the indenting level. + **/ + public void nextLevel() { + setLevel(getLevel() + 1); + } + + /** + * Decrement the indenting level. + **/ + public void prevLevel() { + setLevel(getLevel() - 1); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/LineContinuationStream.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/LineContinuationStream.java new file mode 100644 index 0000000000..d217febfc0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/LineContinuationStream.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.io; + +import java.io.FilterInputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.PushbackInputStream; + +public class LineContinuationStream extends FilterInputStream { + private int continueChar; + private InputStream real; + private boolean atEOF; + + public LineContinuationStream(InputStream real, int continueChar) { + super(new PushbackInputStream(real)); + this.real = real; + this.continueChar = continueChar; + atEOF = false; + } + + /* + public int available() throws IOException { + int avail = real.available(); + return (in.available() - avail) + avail / 2; + } + */ + + public int read() throws IOException { + if (atEOF) return -1; + + int a = 0, b = 0; + if ((a = in.read()) == '\n') { + if ((b = in.read()) == continueChar) { + a = ' '; + } else if (b < 0) { + atEOF = true; + } else { + ((PushbackInputStream) in).unread(b); + } + } + return a; + } + + public long skip(long n) throws IOException { + long count = 0; + while (n > 0) { + if (read() == -1) break; + n--; + count++; + } + return count; + } + + public int read(byte[] b, int off, int len) throws IOException { + int count = 0, c = 0; + while (len > 0) { + if ((c = read()) < 0) break; + b[off] = (byte) c; + off++; + len--; + count++; + } + if (count == 0 && c < 0) return -1; + else return count; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/NullWriter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/NullWriter.java new file mode 100644 index 0000000000..457f46eb00 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/NullWriter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.io; + +import java.io.Writer; + +/** + A writer that doesn't actually write. Sort of like /dev/null. + */ +public final class NullWriter extends Writer { + + private static NullWriter singleton = null; + + private NullWriter() { + } + + public void close() { + } + + public void flush() { + } + + public void write(char[] cbuf, int off, int len){ + } + + public static NullWriter getInstance() { + if (singleton == null) singleton = new NullWriter(); + return singleton; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/OutputPumper.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/OutputPumper.java new file mode 100644 index 0000000000..2a0ba99ea5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/OutputPumper.java @@ -0,0 +1,33 @@ +/* + * Copyright 2003-2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.io; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * A thread which copies an InputStream to an OutputStream + */ +public class OutputPumper extends Thread { + private final OutputStream os; + private final InputStream is; + + public OutputPumper(InputStream is, OutputStream os) { + this.is = is; + this.os = os; + } + + public void run() { + try { + int c; + while ((c = is.read()) >= 0) { + os.write(c); + os.flush(); + } + } catch (Exception e) { + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/PositionStackReader.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/PositionStackReader.java new file mode 100644 index 0000000000..8d36f461f9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/PositionStackReader.java @@ -0,0 +1,404 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.util.EmptyStackException; +import java.util.Stack; + +import com.avlsi.util.debug.Debug; + +/** + * A character-stream reader that allows saving and restoring of positions + * on a stack. + * + * @design jmr This could be implemented with a single StringBuffer, + * keeping track of indices. That would be a little more complicated, + * but no characters would be stored twice as they are now when + * chars are copied from head to the top StringBuffer. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class PositionStackReader extends FilterReader { + + /** + * Stack of StringBuffers storing characters saved for later recall + * in case of a {@link #restorePosition} or {@link #discardPosition} + * call. + * If the stream looked like this:
    +     * a b c d e f g h i 
    +     *  ^ ^   ^   ^
    +     *  p p   p   cur
    +     *  u u   u   p
    +     *  s s   s   o
    +     *  h h   h   s
    +     * 
    , then the stack would look like: + *
    +     * e f
    +     * c d
    +     * b
    +     * 
    + **/ + private final Stack saveStack = new Stack(); + + /** + * The string from which characters should be fetched, + * if headPos < head.length. If headPos == head.length, + * characters should come from the wrapped reader. + **/ + private char[] head = new char[0]; + + /** + * The position in head from which the next character should come, + * if headPos == head.length, then the next character should come + * from the wrapped reader. + **/ + private int headPos = head.length; + + /** + * Flag indicating whether the reader has been closed. + * @see #ensureOpen + **/ + private boolean closedP = false; + + /** + * Create a new postion stack reader. + **/ + public PositionStackReader(final Reader in) { + super(in); + } + + /** + * Check to make sure that the stream has not been closed, + * throw IOException if it has. + * + * @throws IOException if the stream has been closed + **/ + private void ensureOpen() throws IOException { + if (closedP) + throw new IOException("Stream closed"); + } + + + // + // extends FilterReader + // + + /** + * Read a single character. + *

    + * If !saveStack.empty(), we are currently saving characters, + * and so must add the character to the StringBuffer on top of the + * stack. + * + * @return The character read, or -1 if the end of the stream has + * been reached + * + * @exception IOException If an I/O error occurs + **/ + public int read() throws IOException { + synchronized (lock) { + ensureOpen(); + final int ch; + if (headPos < head.length) + ch = head[headPos++]; + else + ch = super.read(); + + // update StringBuffer on top of stack. + if (!saveStack.empty() && ch != -1) { + Debug.assertTrue(ch == (char) ch); + saveChar((char) ch); + } + + return ch; + } + } + + /** + * Read characters into a portion of an array. + * + * @param cbuf Destination buffer + * @param off Offset at which to start writing characters + * @param len Maximum number of characters to read + * + * @return The number of characters read, or -1 if the end of the + * stream has been reached + * + * @exception IOException If an I/O error occurs + */ + public int read(char cbuf[], int off, int len) throws IOException { + synchronized (lock) { + ensureOpen(); + if (len < 0) + throw new IndexOutOfBoundsException(); + else if (len == 0) { + if ((off < 0) || (off > cbuf.length)) + throw new IndexOutOfBoundsException(); + else + return 0; + } else { + // the number of characters we have in head + int avail = head.length - headPos; + + // first, get rid of the chars we have + if (avail > 0) { + if (avail > len) + avail = len; + System.arraycopy(head, headPos, cbuf, off, avail); + + // update StringBuffer on top of stack + if (!saveStack.empty()) + saveChars(cbuf, off, avail); + + headPos += avail; + off += avail; + len -= avail; + } + + // if they want more chars, get rid of chars from underlying + // reader + if (len > 0) { + len = super.read(cbuf, off, len); + + // update StringBuffer on top of stack + if (!saveStack.empty() && len > 0) + saveChars(cbuf, off, len); + + if (len == -1) + return (avail == 0) ? -1 : avail; + return avail + len; + } + + return avail; + } + } + } + + /** + * Skips over and discards n characters of data from this + * input stream. The skip method may, for a variety of + * reasons, end up skipping over some smaller number of characters, + * possibly zero. If n is negative, no characters are + * skipped. + * + *

    The skip method of PositionStackReader + * first skips over the characters in the pushback buffer, if any. It + * then calls the skip method of the underlying reader if + * more characters need to be skipped. The actual number of characters + * skipped is returned. + * + * @param n the number of characters to be skipped. + * @return the actual number of characters skipped. + * @exception IOException If an I/O error occurs + **/ + public long skip(long n) throws IOException { + synchronized (lock) { + ensureOpen(); + + if (n <= 0) + return 0; + + if (saveStack.empty()) { + // we're not remembering, so just skip + + final int avail = head.length - headPos; + final long skipped; + + if (n < avail) { + skipped = n; + headPos += n; + n = 0; + } else { + skipped = avail; + headPos = head.length; + n -= avail; + } + + return skipped + super.skip(n); + } else { + // we are remembering, so we need to memorize + // the chars + + if (n > Integer.MAX_VALUE) + n = Integer.MAX_VALUE; + + final int nn = (int) n; + + // read will take care of remembering + final int cnt = read(new char[nn], 0, nn); + + return cnt == -1 ? 0 : cnt; + } + } + } + + /** + * Tell whether this stream is ready to be read. + * + * @exception IOException If an I/O error occurs + **/ + public boolean ready() throws IOException { + synchronized (lock) { + ensureOpen(); + return headPos < head.length || super.ready(); + } + } + + /** + * Tell whether this stream supports the mark() operation, which it does + * not. + **/ + public boolean markSupported() { + return false; + } + + /** + * Mark the present position in the stream. The mark + * for class PushbackReader always throws an exception. + * + * @exception IOException Always, since mark is not supported + **/ + public void mark(int readAheadLimit) throws IOException { + throw new IOException("mark/reset not supported"); + } + + /** + * Reset the stream. The reset method of + * PushbackReader always throws an exception. + * + * @exception IOException Always, since reset is not supported + **/ + public void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + /** + * Close the stream. + * + * @exception IOException If an I/O error occurs + **/ + public void close() throws IOException { + super.close(); + closedP = true; + } + + + + // + // push / pop functionality + // + + /** + * Saves the current position onto the stack. + *

    + * Characters read after a call to pushPosition will be appended to + * the StringBuffer on top of the stack. + * + * @throws IOException if the stream has been closed + **/ + public void savePosition() + throws IOException + { + synchronized(lock) { + ensureOpen(); + saveStack.push(new StringBuffer()); + } + } + + /** + * Pops position off stack, discarding it. The current position will + * be unchanged. The ability to restore to the discarded position + * will be lost, but the characters that were read after the position + * will not be lost. + * + * @throws EmptyPositionStackException if there are no saved positions + * @throws IOException if the stream has been closed + **/ + public void discardPosition() + throws IOException + { + synchronized(lock) { + ensureOpen(); + try { + final StringBuffer sb = (StringBuffer) saveStack.pop(); + + // append characters stored after the discarded position + // to the position before + if (!saveStack.empty()) { + final StringBuffer sb2 + = (StringBuffer) saveStack.peek(); + + sb2.append(sb.toString()); + } + } catch (EmptyStackException e) { + throw new EmptyPositionStackException(e); + } + } + } + + /** + * Pops position off stack, restoring it. Any characters + * read hereafter will be those that were read after the push. + * + * @throws EmptyPositionStackException if there are no saved positions + * @throws IOException if the stream has been closed + **/ + public void restorePosition() + throws IOException + { + synchronized(lock) { + ensureOpen(); + try { + final StringBuffer sb = (StringBuffer) saveStack.pop(); + sb.append(head, headPos, head.length - headPos); + head = sb.toString().toCharArray(); + headPos = 0; + } catch (EmptyStackException e) { + throw new EmptyPositionStackException(e); + } + } + } + + /** + * Saves one char to the StringBuffer on the top of the stack. + * + * @param ch the character to save + **/ + private void saveChar(final char ch) { + final StringBuffer sb = (StringBuffer) saveStack.peek(); + sb.append(ch); + } + + /** + * Saves multiple chars to the StringBuffer on top of the stack. + * + * @param stf Source buffer + * @param off Offset at which to start reading characters + * @param len Number of characters to read + * + * @exception NullPointerException If str is + * null + * @exception IndexOutOfBoundsException If offset is + * negative, or count is negative, or + * offset+count is larger than data.length + **/ + private void saveChars(final char[] str, final int off, final int len) { + final StringBuffer sb = (StringBuffer) saveStack.peek(); + sb.append(str, off, len); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/Printable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/Printable.java new file mode 100644 index 0000000000..27c6498fc6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/Printable.java @@ -0,0 +1,87 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.io; + +/** + * It's always galled me that PrintStream and PrintWriter don't share + * a common interface. The "correct" thing to use is usually a PrintWriter, + * but since System.err and System.out are PrintStreams, it's important + * to be able to support both. So, I'd like to be able to just call + * println() on something without caring which it is. + * + * So, this interface just contains all the methods that PrintStream and + * PrintWriter have in common. + * + * See WrapPrintStream and WrapPrintWriter. + */ + +public interface Printable { + /** Flush the stream if it's not closed and check its error state. */ + boolean checkError(); + + /** Close the stream. */ + void close(); + + /** Flush the stream. */ + void flush(); + + /** Print a boolean value. */ + void print(boolean b); + + /** Print a character. */ + void print(char c); + + /** Print an array of characters. */ + void print(char[] s); + + /** Print a double-precision floating-point number. */ + void print(double d); + + /** Print a floating-point number. */ + void print(float f); + + /** Print an integer. */ + void print(int i); + + /** Print a long integer. */ + void print(long l); + + /** Print an object. */ + void print(Object obj); + + /** Print a string. */ + void print(String s); + + /** Terminate the current line by writing the line separator string. */ + void println(); + + /** Print a boolean value and then terminate the line. */ + void println(boolean x); + + /** Print a character and then terminate the line. */ + void println(char x); + + /** Print an array of characters and then terminate the line. */ + void println(char[] x); + + /** Print a double-precision floating-point number and then terminate the line. */ + void println(double x); + + /** Print a floating-point number and then terminate the line. */ + void println(float x); + + /** Print an integer and then terminate the line. */ + void println(int x); + + /** Print a long integer and then terminate the line. */ + void println(long x); + + /** Print an Object and then terminate the line. */ + void println(Object x); + + /** Print a String and then terminate the line. */ + void println(String x); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPath.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPath.java new file mode 100644 index 0000000000..0e74fb0469 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.io; + +import java.io.InputStream; + +import java.io.FileNotFoundException; + +import com.avlsi.io.SearchPathFile; +import com.avlsi.io.SearchPathDirectory; + +import com.avlsi.util.container.StringContainerIterator; + + +/** + Interface to a search path. + */ +public interface SearchPath { + + /** + @param fileName The name of the file to open relative to the entries in the SearchPath. Can also + be an absolute file name. + @return The first InputStream that could be opened for a file whose name was a search path + entry with the specified file name appended. + */ + InputStream openFileAsStream(final String fileName) throws FileNotFoundException; + + /** + @param fileName The name of the file to find relative to the entries in the SearchPath. Can also + be an absolute file name. + @return A SearchPathFile that encapsulates a reference to the file within the search path. + If there are multiple files in the search path that would match the file name, a reference to + to first one that can be read will be returned. + */ + SearchPathFile findFile( final String fileName ) throws FileNotFoundException; + + /** + * Searches for each element of fileNames in successive + * directories of the search path. All of the fileNames + * are attempted in one search path entry before moving to the next + * search path entry. The first matching file is returned. + * + * @param fileNames The file names to find relative to the + * entries in the SearchPath. Can also contain absolute file names. + * + * @return A SearchPathFile that encapsulates a reference to the file + * within the search path. If there are multiple files in the search + * path that would match the file name, a reference to to first one + * that can be read will be returned. + * + * @throws FileNotFoundException If no matching file could be found. + * @throws IllegalArgumentException If fileNames does + * not contain at least entry. + */ + SearchPathFile findFirstFileOf(String[] fileNames) + throws FileNotFoundException; + + /** + @param dirName The name of the directory to find relative to the entries in the SearchPath. Can also + be an absolute directory name. + @return A SearchPathFile that encapsulates a reference to the directory within the search path. + If there are multiple directories in the search path that would match the directory name, a reference to + to first one that can be read will be returned. + */ + SearchPathDirectory findDirectory( final String dirName ) throws FileNotFoundException; + + /** + Returns the search path as a string. The components of the path are seperated by File.pathSeparatorChar + @return The search path as a string. + **/ + String getSearchPathString(); + + /** + @return An iterator that iterates over the entries in the SearchPath + */ + StringContainerIterator getSearchPath(); + + /** + * Returns true if the specified directory is part of this path. + * (Note that being a subdirectory of part of this path isn't good + * enough.) This is used for verifying module names. + **/ + boolean containsDirectory(String dirName); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectory.java new file mode 100644 index 0000000000..04559ad9a9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectory.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.io; +import com.avlsi.io.SearchPathDirectoryIterator; + +import java.io.FileFilter; + +/** + An iterface that encapsulates a directory in a SearchPath. + @see com.avlsi.io.SearchPath + */ +public interface SearchPathDirectory { + + /** + Gets the absolute name of the directory in the search path. + If the directory was found in some sort of archive in the SearchPath the implementation should + try to do something reasonable. The returned string must uniquely identify the directory + referenced by this interface. If two instances of an implementation of this interface + reference the same directory then the strings returned by this method MUST be the same. + @return The absolute name of the directory in the SearchPath. + */ + String getName(); + + + /** + @return An iterator that iterates over all the sub directories in the encapsulated directory. + */ + SearchPathDirectoryIterator getSubDirectories(); + + /** + @return An iterator that iterates over all the files in the encapsulated directory. + */ + SearchPathFileIterator getFiles(); + + /** + Gets an iterator that iterates over all the files in the encapsulated directory that satisfy the filter. + @param filter The filter through which file must return before it is returned by the iterator. + @return An iterator that iterates over all the files in the encapsulated directory that satisfy the filter. + */ + SearchPathFileIterator getFiles( SearchPathFileFilter filter ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectoryIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectoryIterator.java new file mode 100644 index 0000000000..b8d8d78c86 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathDirectoryIterator.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.io; + +import java.util.NoSuchElementException; + +import com.avlsi.io.SearchPathDirectory; + +public interface SearchPathDirectoryIterator { + + /** + @return true if there is another subdirectory of the directory being iterated, false otherwise. + */ + boolean hasNext(); + + /** + @return The next directory in the directory being iterated. + @throws NoSuchElementException + */ + SearchPathDirectory next(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFile.java new file mode 100644 index 0000000000..0909fd4c56 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFile.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.io; +import java.io.InputStream; +import java.io.FileNotFoundException; + + +/** + Interface for objects that reference files found in a SearchPath. + */ +public interface SearchPathFile { + + /** + Gets the absolute name of the file in the search path. + If the file was found in some sort of archive in the SearchPath the implementation should + try to do something reasonable. The returned string must uniquely identify the file + referenced by this interface. If two instances of an implementation of this interface + reference the same file then the strings returned by this method MUST be the same. + @return The absolute name of the file in the SearchPath. + */ + String getName( ); + + /** + Opens an InputStream that reads the contents of the file. + @return An InputStream that reads the contents of the file referenced by an instance of the implementation of + this interface. + */ + InputStream getStream( ) throws FileNotFoundException; + + /** + Tests whether the encapsulated file can be read. + @return true if the encapsulated file can be read. + */ + boolean canRead( ); + + /** + Tests whether the encapsulated file exists. + @return true if the encapsulated file can be written. + */ + boolean exists( ); + + /** + @return The time encapsulated file was last modified in milliseconds since the epoch ( 00:00:00 GMT, 1/1/1970 ) or + -1 if the last modification time is not available. + */ + long lastModified( ); + + /** + @return The number of bytes that could be read for the InputStream returned by getStream, or + -1 if that number cannot be computed. + */ + long length( ); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileFilter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileFilter.java new file mode 100644 index 0000000000..17904c548e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileFilter.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.io; + +import com.avlsi.io.SearchPathFile; + +/** + A version of the FileFilter interface for search path's. + */ +public interface SearchPathFileFilter { + + /** + @return true if the filter is allow the file f to pass through or false if the file f should be filtered. + */ + boolean accept( SearchPathFile f ); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileIterator.java new file mode 100644 index 0000000000..b4e93a0307 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/SearchPathFileIterator.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.io; +import java.util.NoSuchElementException; + +import com.avlsi.io.SearchPathFile; + + +public interface SearchPathFileIterator { + + /** + @return true if there is another file in the directory being iterated. false otherwise. + */ + boolean hasNext(); + + /** + * @return The next file in the directory being iterated. + * @throws NoSuchElementException + */ + SearchPathFile next(); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/StreamLexer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/StreamLexer.java new file mode 100644 index 0000000000..cd09b45a8e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/StreamLexer.java @@ -0,0 +1,1282 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +import java.io.IOException; +import java.io.Reader; +import java.util.Stack; + +import com.avlsi.util.debug.Debug; + +/** + * XXX write docs + * The implementation is unsynchronized. + * + * @design jmr The line and column number functionality could be factored + * out into another reader, perhaps an extension of + * PositionStackReader. + * @design jmr Comment stripping could also be factored out. + * + * @todo jmr Add support for simultaneous multiple comment styles + * ie //, --, ;, #, and % all at once like svasm + * + * @todo jmr Way to make eol significant, to do line oriented parsing + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class StreamLexer { + + /** + * Wrapped reader to be tokenized, wrapped by a PositionStackReader + * to support pushing and popping of positions. Null to indicate + * that the StreamLexer has been closed. + **/ + private PositionStackReader psr; + + /** + * stack to keep track of line and column number for + * {@link #restorePosition}. + **/ + private final Stack lineColStack = new Stack(); + + /** + * The current line number. + **/ + private int lineNumber = 1; + + /** + * The current column number. + **/ + private int columnNumber = 0; + + /** + * Determines if eol's are just whitespace, or are a token. + **/ + // private boolean eolIsSignificantP = false; + + // + // character types + // + + /** + * Characters in this string are considered whitespace. + **/ + private String whitespaceChars; + + /** + * Characters in this string begin and end quoted strings. + **/ + private String quoteChars; + + // + // single line comments + // + + /** + * Whether single line comments should be recognized. + **/ + private boolean singleLineCommentsP; + + /** + * String that starts a single-line comment. + **/ + private String singleLineCommentsBegin; + + /** + * Whether a number is allowed to start an identifier + **/ + private boolean digitStartsIdentifierP; + + + + // + // multi line comments + // + + /** + * Whether multi line comments should be recognized. + **/ + private boolean multiLineCommentsP; + + /** + * whether multi-line comments are nested + **/ + private boolean multiLineCommentsNestedP; + + /** + * String that starts a multi-line comment. + **/ + private String beginMultiLineComment; + + /** + * String that ends a multi-line comment. + **/ + private String endMultiLinesComment; + + + // + // Constructor + // + + /** + * Create a lexer that operates on the given character stream. + * + * @exception NullPointerException if r is null + **/ + public StreamLexer(final Reader r) { + this(); + + if (r == null) + throw new NullPointerException(); + + psr = new PositionStackReader(r); + } + + /** + * Private constructor that initializes everything except the reader. + **/ + private StreamLexer() { + // whitespace + final StringBuffer sb = new StringBuffer(); + for (char ch = '\0'; ch <= ' '; ++ch) + sb.append(ch); + setWhitespaceChars(sb.toString()); + + // quote chars + quoteChars = "\""; + + // multi line comments + multiLineCommentsP = false; + beginMultiLineComment = null; + endMultiLinesComment = null; + multiLineCommentsNestedP = false; + + // single line comments + singleLineCommentsP = false; + singleLineCommentsBegin = null; + + // numbers cannot start identifiers + digitStartsIdentifierP = false; + } + + + /** + * Check to make sure that the stream has not been closed, + * throw IOException if it has. + * + * @throws IOException if the stream has been closed + **/ + private void ensureOpen() throws IOException { + if (psr == null) + throw new IOException("Stream closed"); + } + + + // + // Behavior control methods. + // + + /** + * Specifies that any character appearing in the string + * whitespaceChars is a white space character. + **/ + public void setWhitespaceChars(final String whitespaceChars) { + this.whitespaceChars = whitespaceChars; + } + + /** + * Specifies the beginning and ending strings for multi-line + * comments, and whether or not they are nested. A C style + * comment would be specified by + * lex.setMultiLineComments("/*", "*/", false); + **/ + public void setMultiLineComments(final String begin, + final String end, + final boolean nested) { + multiLineCommentsP = true; + beginMultiLineComment = begin; + endMultiLinesComment = end; + multiLineCommentsNestedP = nested; + } + + /** + * Specifies the beginning string for single-line + * comments. A C++ style * comment would be specified by + * lex.setSingleLineComments("//"); + **/ + public void setSingleLineComments(final String begin) { + singleLineCommentsBegin = begin; + } + + /** + * Specifies that matching pairs of this character delimit string + * constants. + **/ + public void addQuoteChar(char ch) { + quoteChars += ch; + } + + /** + * Specifies whether a number is allowed to start an identifier. + **/ + public void setDigitStartsIdentifier( + final boolean digitStartsIdentifierP) { + this.digitStartsIdentifierP = digitStartsIdentifierP; + } + + // + // private character type checking methods + // + + /** + * Returns whether a character is considered whitespace. + **/ + private boolean charIsWhitespace(final int ch) { + return whitespaceChars.indexOf(ch) != -1; + } + + /** + * Returns whether a character is considered a digit. + * @todo jmr, extend this for other arbitrary radix. + **/ + private boolean charIsDigit(final int ch) { + return '0' <= ch && ch <= '9'; + } + + /** + * Returns whether a character is considered a quote character. + **/ + private boolean charIsQuote(final int ch) { + return quoteChars.indexOf(ch) != -1; + } + + /** + * Returns whether a character is considered an alphabetic character. + **/ + private boolean charIsAlpha(final int ch) { + return ch == '_' + || ('a' <= ch && ch <= 'z') + || ('A' <= ch && ch <= 'Z'); + } + + + // + // + // private parsing methods + // + // + + // + // char parsing: readChar, peekChar + // + + /** + * Returns the next character on the stream, and advances the + * the current position. Adjusts lineNumber and columnNumber. + * + * @return The character read, or -1 if the end of the stream has + * been reached. + * + * @exception IOException If an I/O error occurs + **/ + private int readChar() throws IOException { + final int ch = psr.read(); + + // XXX handle EOF line / col no + // XXX do we want to handle \n\r? + // XXX: this handling isn't quite right for EOL chars + if (ch == '\n' || ch == '\r') { + ++lineNumber; + columnNumber = 0; + } else + ++columnNumber; + + return ch; + } + + /** + * Returns the next character on the stream, without changing + * the current position. + * + * @return The character read, or -1 if the end of the stream has + * been reached. + * + * @exception IOException If an I/O error occurs + **/ + private int peekChar() throws IOException { + savePosition(); + + try { + return readChar(); + } finally { + restorePosition(); + } + } + + // we DO need separate do and read methods: + // do: just read it + // read: first skip whitespace, then read + // actually: read, then read whitespace + // or something, see above + // or something to that effect. + + + // + // whitespace parsing: + // readWhitespace, peekWhitespace, isWhitespace, readIfWhitespace + // + + + /** + * If the string at the head of the stream is whitespace, + * return a string of the maximum amount of whitespace possible + * and advance the position to after the whitespace, + * otherwise throw TokenNotWhitespaceException and leave the + * position unchanged. + * Comments are also considered whitespace. + * + * @exception TokenNotWhitespaceException If there is no + * whitespace at the head of the stream + * @exception IOException If an I/O error occurs + **/ + private String readWhitespace() + throws TokenNotWhitespaceException, IOException + { + savePosition(); + boolean success = false; + + try { + final StringBuffer sb = new StringBuffer(); + + for (;;) { + if (charIsWhitespace(peekChar())) + sb.append((char) readChar()); + else if (multiLineCommentsP + && isLiteral(beginMultiLineComment)) { + // multi line comment + sb.append(readLiteral(beginMultiLineComment)); + while (!isLiteral(endMultiLinesComment)) { + final int ch = readChar(); + + if (ch == -1) + throw new TokenNotWhitespaceException( + "EOF in comment"); + + sb.append((char) ch); + } + sb.append(readLiteral(endMultiLinesComment)); + } else if (singleLineCommentsP + && isLiteral(singleLineCommentsBegin)) { + // single line comment + + // read comment chars + sb.append(readLiteral(singleLineCommentsBegin)); + + // read until end of line + + for (;;) { + int ch = readChar(); + + if (ch == -1) + throw new TokenNotWhitespaceException( + "single line comment at end of file," + + " no trailing newline"); + + sb.append((char) ch); + + if (ch == '\n' || ch == '\r') + break; + } + + // XXX handle '\n\r'? + } + else + break; + + } + + if (sb.length() == 0) + throw new TokenNotWhitespaceException(); + + final String s = sb.toString(); + success = true; + return s; + } finally { + if (success) + discardPosition(); + else + restorePosition(); + } + } + + /** + * If the string at the head of the stream is whitespace, + * return a string of the maximum amount of whitespace possible, + * otherwise throw TokenNotWhitespaceException. Leave the + * position unchanged. + * Comments are also considered whitespace. + * + * @exception TokenNotWhitespaceException If there is no + * whitespace at the head of the stream + * @exception IOException If an I/O error occurs + **/ + private String peekWhitespace() + throws TokenNotWhitespaceException, IOException + { + savePosition(); + + try { + return readWhitespace(); + } finally { + restorePosition(); + } + } + + /** + * Returns whether a call to readWhitespace or peekWhitespace would + * succeed. + * + * @exception IOException If an I/O error occurs + **/ + private boolean isWhitespace() throws IOException { + try { + peekWhitespace(); + return true; + } catch (TokenNotWhitespaceException e) { + return false; + } + } + + /** + * If {@link #isWhitespace} would return true, return + * what {@link #readWhitespace} would return, otherwise return null. + * + * @exception IOException If an I/O error occurs + **/ + private String readIfWhitespace() throws IOException { + try { + return readWhitespace(); + } catch (TokenNotWhitespaceException e) { + return null; + } + } + + // + // literal parsing: + // readLiteral, peekLiteral, isLiteral, readIfLiteral + // + + /** + * Returns the literal and advances position if it is at the head of + * the stream. If not, throws TokenNotLiteralException and + * position will be unchanged. + * Does not read any whitespace first, thus it can be used + * to check for comment beginning and ending. + * + * @exception TokenNotLiteralException if the literal was not + * at the head of the stream + * @exception IOException If an I/O error occurs + **/ + private String readLiteral(final String lit) + throws TokenNotLiteralException, IOException + { + savePosition(); + boolean success = false; + + try { + readIfWhitespace(); + + for (int i = 0; i < lit.length(); ++i) + if (readChar() != lit.charAt(i)) + throw new TokenNotLiteralException(); + + success = true; + return lit; + } finally { + if (success) + discardPosition(); + else + restorePosition(); + } + } + + /** + * Returns the literal if it is at the head of + * the stream. If not, throw TokenNotLiteralException. + * Position will be unchanged. + * Does not read any whitespace first, thus it can be used + * to check for comment beginning and ending. + * + * @exception TokenNotLiteralException if the literal was not + * at the head of the stream + * @exception IOException If an I/O error occurs + **/ + private String peekLiteral(final String lit) + throws TokenNotLiteralException, IOException + { + savePosition(); + + try { + return readLiteral(lit); + } finally { + restorePosition(); + } + } + + /** + * Returns whether a call to readLiteral or peekLiteral would + * succeed. + * + * @exception IOException If an I/O error occurs + **/ + private boolean isLiteral(final String lit) throws IOException { + try { + peekLiteral(lit); + return true; + } catch (TokenNotLiteralException e) { + return false; + } + } + + /** + * If {@link #isLiteral} would return true, return + * what {@link #readLiteral} would return, otherwise return null. + * + * @exception IOException If an I/O error occurs + **/ + private String readIfLiteral(final String lit) throws IOException { + try { + return readLiteral(lit); + } catch (TokenNotLiteralException e) { + return null; + } + } + + + + // + // + // public parsing methods + // + // + + // + // int parsing: + // readInt, peekInt, isInt, readIfInt + // + + /** + * First reads whitespace, if any, then returns the next token + * if it is an integer, advancing the position to after the integer. + * If the token after optional whitespace is not an integer, + * throws TokenNotIntException and leaves position unchanged. + * + * @return the integer represented by the next token + * + * @exception TokenNotIntException if the token is not an integer + * @exception IOException If an I/O error occurs + **/ + public int readInt() throws TokenNotIntException, IOException { + savePosition(); + boolean success = false; + + try { + readIfWhitespace(); + + final StringBuffer sb = new StringBuffer(); + + if (peekChar() == '+') // parseInt can't handle + + readChar(); + else if (peekChar() == '-') + sb.append((char) readChar()); + + if (charIsDigit(peekChar())) { + do { + sb.append((char) readChar()); + } while (charIsDigit(peekChar())); + } else + throw new TokenNotIntException("no digits"); + + final int i = Integer.parseInt(sb.toString()); + success = true; + return i; + } catch (NumberFormatException e) { + throw new TokenNotIntException(e); + } finally { + if (success) + discardPosition(); + else + restorePosition(); + } + + } + + /** + * First reads whitespace, if any, then returns the next token + * if it is an integer. If the token after optional whitespace is + * not an integer, throws TokenNotIntException. + * Always leaves position unchanged. + * + * @return the integer represented by the next token + * + * @exception TokenNotIntException if the token is not an integer + * @exception IOException If an I/O error occurs + **/ + public int peekInt() throws TokenNotIntException, IOException { + savePosition(); + + try { + return readInt(); + } finally { + restorePosition(); + } + } + + /** + * Returns whether a call to readInt or peekInt would + * succeed. + * + * @exception IOException If an I/O error occurs + **/ + public boolean isInt() throws IOException { + try { + peekInt(); + return true; + } catch (TokenNotIntException e) { + return false; + } + } + + /** + * If {@link #isInt} would return true, return a java.lang.Integer + * representing what {@link #readInt} would return, + * otherwise return null. + * + * @exception IOException If an I/O error occurs + **/ + public Integer readIfInt() throws IOException { + try { + return new Integer(readInt()); + } catch (TokenNotIntException e) { + return null; + } + } + + // + // double: + // readDouble, peekDouble, isDouble, readIfDouble + // + + /** + * First reads whitespace, if any, then returns the next token + * if it is a double, advancing the position to after the double. + * If the token after optional whitespace is not an double, + * throws TokenNotDoubletException and leaves position unchanged. + * + * @return the double represented by the next token + * + * @exception TokenNotDoubletException if the token is not a double + * @exception IOException If an I/O error occurs + **/ + public double readDouble() throws TokenNotDoubleException, IOException { + savePosition(); + boolean success = false; + + try { + readIfWhitespace(); + + // formats parsed are + // double ::= + // [ sign ] digits . [ digits ] [ exponent ] + // [ sign ] . digits [ exponent ] + // [ sign ] digits [ exponent ] + // exponent ::= + // ( e | E ) signed_integer + // signed_integer ::= + // [ sign ] digits + // sign ::= + // + | - + + final StringBuffer sb = new StringBuffer(); + + // we depend on Double.parseDouble to find errors + + // sign + if (peekChar() == '+' || peekChar() == '-') + sb.append((char) readChar()); + + // pre-decimal digits + while (charIsDigit(peekChar())) + sb.append((char) readChar()); + + // decimal + if (peekChar() == '.') + sb.append((char) readChar()); + + // post-decimal digits + while (charIsDigit(peekChar())) + sb.append((char) readChar()); + + // exponent indicator + if (peekChar() == 'E' || peekChar() == 'e') + sb.append((char) readChar()); + + // exponent sign + if (peekChar() == '+' || peekChar() == '-') + sb.append((char) readChar()); + + // exponent digits + while (charIsDigit(peekChar())) + sb.append((char) readChar()); + + final double d = Double.parseDouble(sb.toString()); + + // we were successful + success = true; + return d; + } catch (NumberFormatException e) { + throw new TokenNotDoubleException(e); + } finally { + if (success) + discardPosition(); + else + restorePosition(); + } + } + + /** + * First reads whitespace, if any, then returns the next token + * if it is a double. If the token after optional whitespace is + * not a double, throws TokenNotDoubleException. + * Always leaves position unchanged. + * + * @return the integer represented by the next token + * + * @exception TokenNotDoubleException if the token is not an integer + * @exception IOException If an I/O error occurs + **/ + public double peekDouble() + throws TokenNotDoubleException, IOException + { + savePosition(); + + try { + return readDouble(); + } finally { + restorePosition(); + } + } + + /** + * Returns whether a call to readDouble or peekDouble would + * succeed. + * + * @exception IOException If an I/O error occurs + **/ + public boolean isDouble() throws IOException { + try { + peekDouble(); + return true; + } catch (TokenNotDoubleException e) { + return false; + } + } + + /** + * If {@link #isDouble} would return true, return a java.lang.Double + * representing what {@link #readDouble} would return, + * otherwise return null. + * + * @exception IOException If an I/O error occurs + **/ + public Double readIfDouble() throws IOException { + try { + return new Double(readDouble()); + } catch (TokenNotDoubleException e) { + return null; + } + } + + + // + // identifier parsing: + // readIdentifier, peekIdentifier, isIdentifier, readIfIdentifier + // + + /** + * First reads whitespace, if any, then returns the next token + * if it is an identifier, advancing the position to after the + * identifier. + * If the token after optional whitespace is not an identifier, + * throws TokenNotIdentifierException and leaves position unchanged. + * An identifier is a word character (or a number character if + * setDigitStartsIdentifier(true) was called) + * followed by one or more + * word or number characters. + * + * @return the identifier represented by the next token + * + * @exception TokenNotIdentifierException if the token is not an + * identifier + * @exception IOException If an I/O error occurs + **/ + public String readIdentifier() + throws TokenNotIdentifierException, IOException + { + savePosition(); + boolean success = false; + + // ident ::= alpha [ alpha | digit ]* + + try { + readIfWhitespace(); + + final StringBuffer sb = new StringBuffer(); + + if (charIsAlpha(peekChar()) + || (digitStartsIdentifierP && charIsDigit(peekChar()))) { + sb.append((char) readChar()); + + while (charIsAlpha(peekChar()) || charIsDigit(peekChar())) + sb.append((char) readChar()); + } else + throw new TokenNotIdentifierException( + "must start with alpha"); + + // we were successful + final String s = sb.toString(); + success = true; + return s; + } finally { + if (success) + discardPosition(); + else + restorePosition(); + } + } + + /** + * If readIdentifier would successfully return, then return its value. + * If readIdentifier would throw an exception, throw that same exception. + * Always leaves position unchanged. + * + * @return the identifier represented by the next token + * + * @exception TokenNotIdentifierException if the token is not an integer + * @exception IOException If an I/O error occurs + **/ + public String peekIdentifier() + throws TokenNotIdentifierException, IOException + { + savePosition(); + + try { + return readIdentifier(); + } finally { + restorePosition(); + } + } + + /** + * Returns whether a call to readIdentifier or peekIdentifier would + * succeed. + * + * @exception IOException If an I/O error occurs + **/ + public boolean isIdentifier() throws IOException { + try { + peekIdentifier(); + return true; + } catch (TokenNotIdentifierException e) { + return false; + } + } + + /** + * If {@link #isIdentifier} would return true, return + * what {@link #readIdentifier} would return, + * otherwise return null. + * + * @exception IOException If an I/O error occurs + **/ + public String readIfIdentifier() throws IOException { + try { + return readIdentifier(); + } catch (TokenNotIdentifierException e) { + return null; + } + } + + + // + // quoted string parsing: + // readQuotedString, peekQuotedString, isQuotedString, readIfQuotedString + // + // + + /** + * First read optional whitespace. Then, read one of quote + * characters, and return string between quotes until matching + * close quote, including comments and newlines. On success, + * position will advance, on failure, it will be unchanged. + * + * XXX: Escapes for octal, escaped quote chars, and c style + * escapes are not implemented yet. + * + * @exception TokenNotQuotedStringException if the next token + * is not a quoted string. + * + **/ + public String readQuotedString() + throws TokenNotQuotedStringException, IOException + { + savePosition(); + boolean success = false; + + try { + readIfWhitespace(); + + final int openQuote = readChar(); + + if (!charIsQuote(openQuote)) + throw new TokenNotQuotedStringException(); + + final StringBuffer sb = new StringBuffer(); + + while (peekChar() != openQuote && peekChar() != -1) + sb.append((char) readChar()); + + final int closeQuote = readChar(); + + if (closeQuote != openQuote) // EOF, etc + throw new TokenNotQuotedStringException(); + + final String s = sb.toString(); + success = true; + return s; + } finally { + if (success) + discardPosition(); + else + restorePosition(); + } + } + + /** + * If readQuotedString would successfully return, then return its value. + * If readQuotedString would throw an exception, throw that same exception. + * Always leaves position unchanged. + * + * @return the quoted string represented by the next token + * + * @exception TokenNotQuotedStringException if the token is not an integer + * @exception IOException If an I/O error occurs + **/ + public String peekQuotedString() + throws TokenNotQuotedStringException, IOException + { + savePosition(); + + try { + return readQuotedString(); + } finally { + restorePosition(); + } + } + + /** + * Returns whether a call to readQuotedString or peekQuotedString would + * succeed. + * + * @exception IOException If an I/O error occurs + **/ + public boolean isQuotedString() throws IOException { + try { + peekQuotedString(); + return true; + } catch (TokenNotQuotedStringException e) { + return false; + } + } + + /** + * If {@link #isQuotedString} would return true, return + * what {@link #readQuotedString} would return, + * otherwise return null. + * + * @exception IOException If an I/O error occurs + **/ + public String readIfQuotedString() throws IOException { + try { + return readQuotedString(); + } catch (TokenNotQuotedStringException e) { + return null; + } + } + + + // + // symbol parsing: + // readSymbol, peekSymbol, isSymbol, readIfSymbol + // + // + + /** + * First reads whitespace, if any, then returns the next token + * if it is the specified symbol, advancing the position to after the + * symbol. If the token after optional whitespace is not the specified + * symbol, throws TokenNotSymbolException and leaves position unchanged. + * + * @return the symbol represented by the next token + * + * @exception TokenNotSymbolException if the token is not an integer + **/ + public String readSymbol(final String sym) + throws TokenNotSymbolException, IOException + { + try { + return readLiteral(sym); + } catch (TokenNotLiteralException e) { + throw new TokenNotSymbolException(e); + } + } + + /** + * If readSymbol would successfully return, then return its value. + * If readSymbol would throw an exception, throw that same exception. + * Always leaves position unchanged. + * + * @return the symbol represented by the next token + * + * @exception TokenNotSymbolException if the token is not an integer + * @exception IOException If an I/O error occurs + **/ + public String peekSymbol(final String sym) + throws TokenNotSymbolException, IOException + { + savePosition(); + + try { + return readSymbol(sym); + } finally { + restorePosition(); + } + } + + /** + * Returns whether a call to readSymbol or peekSymbol would + * succeed. + * + * @exception IOException If an I/O error occurs + **/ + public boolean isSymbol(final String sym) throws IOException { + try { + peekSymbol(sym); + return true; + } catch (TokenNotSymbolException e) { + return false; + } + } + + /** + * If {@link #isSymbol} would return true, return sym + * (to save memory) otherwise return null. + * + * @exception IOException If an I/O error occurs + **/ + public String readIfSymbol(final String sym) throws IOException { + try { + final String s = readSymbol(sym); + Debug.assertTrue(s.equals(sym)); + return sym; + } catch (TokenNotSymbolException e) { + return null; + } + } + + // + // EOF + // + + /** + * First reads whitespace, if any, then returns if the next + * character is EOF, leaving positino at eof. + * If not, throw TokenNotEOFException, and leave position unchanged. + * + * @exception TokenNotEOFException if the token is not EOF + * @exception IOException If an I/O error occurs + **/ + public void readEOF() throws TokenNotEOFException, IOException { + savePosition(); + boolean success = false; + + try { + readIfWhitespace(); + + if (readChar() == -1) + success = true; + else + throw new TokenNotEOFException(); + + } finally { + if (success) + discardPosition(); + else + restorePosition(); + } + } + + /** + * First reads whitespace, if any, then returns if the next + * character is EOF. If not, throw TokenNotEOFException. Always + * leaves position unchanged. + * + * @exception TokenNotEOFException if the token is not EOF + * @exception IOException If an I/O error occurs + **/ + public void peekEOF() throws TokenNotEOFException, IOException { + savePosition(); + + try { + readEOF(); + } finally { + restorePosition(); + } + } + + + /** + * Returns whether a call to readEOF or peekEOF would succeed. + * + * @exception IOException If an I/O error occurs + **/ + public boolean isEOF() throws IOException { + try { + peekEOF(); + return true; + } catch (TokenNotEOFException e) { + return false; + } + } + + /** + * If {@link #isEOF} would return true, then call {@link #readEOF}. + * If {@link #isEOF} would return false, then return false. + * + * @exception IOException If an I/O error occurs + **/ + public boolean readIfEOF() throws IOException { + try { + readEOF(); + return true; + } catch (TokenNotEOFException e) { + return false; + } + } + + + // + // close + // + + /** + * Close the stream. + * + * @exception IOException If an I/O error occurs + **/ + public void close() throws IOException { + if (psr != null) { + psr.close(); + psr = null; + } + } + + + // + // stack ops + // + + /** + * Pushes current position onto position stack. + * + * @throws IOException if the stream has been closed + **/ + public void savePosition() throws IOException { + ensureOpen(); + psr.savePosition(); + + // save line and column + lineColStack.push(new int[]{getLineNumber(), getColumnNumber()}); + } + + /** + * Pops position off stack, and moves to that position. + * + * @throws EmptyPositionStackException if there are no saved positions + * @throws IOException if the stream has been closed + **/ + public void restorePosition() + throws EmptyPositionStackException, IOException + { + ensureOpen(); + psr.restorePosition(); + + // restore line and column + final int[] lineCol = (int[]) lineColStack.pop(); + lineNumber = lineCol[0]; + columnNumber = lineCol[1]; + } + + /** + * Pops position off stack, discarding it. + * + * @throws EmptyPositionStackException if there are no saved positions + * @throws IOException if the stream has been closed + **/ + public void discardPosition() + throws EmptyPositionStackException, IOException + { + ensureOpen(); + psr.discardPosition(); + + // discard line and column + lineColStack.pop(); + } + + + // + // info methods + // + + /** + * Return the current line number. + * + * @return the current line number of this stream lexer. + */ + public int getLineNumber() { + return lineNumber; + } + + /** + * Return the current column number within the line. + * + * @return the current column number of this stream lexer. + */ + public int getColumnNumber() { + return columnNumber; + } + + // toString +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/StringBuilderWriter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/StringBuilderWriter.java new file mode 100644 index 0000000000..97ef6cf36d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/StringBuilderWriter.java @@ -0,0 +1,68 @@ +package com.avlsi.io; + +import java.io.IOException; +import java.io.Writer; + +/** + * Like StringWriter, except uses a StringBuilder instead of a StringBuffer to + * hold the data written. This class is also unsynchronized. + **/ +public final class StringBuilderWriter extends Writer { + private final StringBuilder builder; + + public StringBuilderWriter() { + builder = new StringBuilder(); + } + + public StringBuilderWriter(final int capacity) { + builder = new StringBuilder(capacity); + } + + public void write(int c) { + builder.append((char) c); + } + + public void write(char cbuf[]) { + builder.append(cbuf); + } + + public void write(char cbuf[], int off, int len) { + builder.append(cbuf, off, len); + } + + public void write(String str) { + if (str == null) throw new NullPointerException(); + else builder.append(str); + } + + public void write(String str, int off, int len) { + builder.append(str, off, off + len); + } + + public StringBuilderWriter append(CharSequence csq) { + builder.append(csq); + return this; + } + + public StringBuilderWriter append(CharSequence csq, int start, int end) { + builder.append(csq, start, end); + return this; + } + + public StringBuilderWriter append(char c) { + builder.append(c); + return this; + } + + public void flush() { } + + public void close() { } + + public StringBuilder getBuffer() { + return builder; + } + + public String toString() { + return builder.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TestPositionStackReader.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TestPositionStackReader.java new file mode 100644 index 0000000000..f3d2f1915f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TestPositionStackReader.java @@ -0,0 +1,246 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +import java.io.Reader; +import java.io.StringReader; + +import com.avlsi.test.AbstractTestCase; + +/** + * Tests of the PositionStackReader class + * + * @see PositionStackReader + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class TestPositionStackReader extends AbstractTestCase { + + public void test() throws Throwable { + final StringBuffer sb = new StringBuffer(); + + for (char ch = 'a'; ch <= 'z'; ++ch) + sb.append(ch); + for (char ch = 'A'; ch <= 'Z'; ++ch) + sb.append(ch); + for (char ch = '0'; ch <= '9'; ++ch) + sb.append(ch); + + final String s = sb.toString(); + final PositionStackReader psr + = new PositionStackReader(new StringReader(s)); + + assertTrue(psr.read() == 'a'); + assertTrue(psr.read() == 'b'); + assertTrue(psr.read() == 'c'); + + psr.savePosition(); + + assertTrue(psr.read() == 'd'); + assertTrue(psr.read() == 'e'); + + psr.restorePosition(); + + assertTrue(psr.read() == 'd'); + assertTrue(psr.read() == 'e'); + assertTrue(psr.read() == 'f'); + + psr.savePosition(); + + assertTrue(psr.read() == 'g'); + + psr.savePosition(); + + assertTrue(psr.read() == 'h'); + + psr.discardPosition(); + + assertTrue(psr.read() == 'i'); + + psr.restorePosition(); + + assertTrue(psr.read() == 'g'); + assertTrue(psr.read() == 'h'); + assertTrue(psr.read() == 'i'); + assertTrue(psr.read() == 'j'); + + psr.savePosition(); + psr.savePosition(); + + assertTrue(psr.read() == 'k'); + + psr.restorePosition(); + + assertTrue(psr.read() == 'k'); + + psr.restorePosition(); + + assertTrue(psr.read() == 'k'); + assertTrue(psr.read() == 'l'); + + psr.savePosition(); + + assertTrue(psr.read() == 'm'); + + psr.savePosition(); + + assertTrue(psr.read() == 'n'); + + psr.savePosition(); + + assertTrue(psr.read() == 'o'); + + psr.discardPosition(); + psr.discardPosition(); + psr.discardPosition(); + + assertTrue(psr.read() == 'p'); + + psr.savePosition(); + + assertTrue(psr.read() == 'q'); + + psr.savePosition(); + + assertTrue(psr.read() == 'r'); + + psr.savePosition(); + + assertTrue(psr.read() == 's'); + + psr.restorePosition(); + psr.restorePosition(); + + assertTrue(psr.read() == 'r'); + assertTrue(psr.read() == 's'); + assertTrue(psr.read() == 't'); + + psr.restorePosition(); + + assertTrue(psr.read() == 'q'); + + psr.savePosition(); + psr.savePosition(); + psr.discardPosition(); + psr.discardPosition(); + + assertTrue(psr.read() == 'r'); + + psr.savePosition(); + psr.savePosition(); + psr.restorePosition(); + psr.restorePosition(); + + assertTrue(psr.read() == 's'); + + psr.skip(3); + + // skip t, u, v from stream + + assertTrue(psr.read() == 'w'); + assertTrue(psr.read() == 'x'); + + psr.savePosition(); + + assertTrue(psr.read() == 'y'); + assertTrue(psr.read() == 'z'); + assertTrue(psr.read() == 'A'); + + psr.restorePosition(); + psr.savePosition(); + + assertTrue(psr.read() == 'y'); + + psr.restorePosition(); + + assertTrue(psr.read() == 'y'); + assertTrue(psr.read() == 'z'); + + // save position before A for a while + + psr.savePosition(); + + assertTrue(psr.read() == 'A'); + + char[] chs = null; + int n = -1; + + // test array read from stream + chs = new char[3]; + n = psr.read(chs, 0, chs.length); + + assertTrue(n == 3); + assertTrue(chs[0] == 'B'); + assertTrue(chs[1] == 'C'); + assertTrue(chs[2] == 'D'); + + // keep A stored + psr.restorePosition(); + psr.savePosition(); + + // test read from buf / stream + + chs = new char[6]; + n = psr.read(chs, 0, chs.length); + + assertTrue(n == 6); + assertTrue(chs[0] == 'A'); + assertTrue(chs[1] == 'B'); + assertTrue(chs[2] == 'C'); + assertTrue(chs[3] == 'D'); + assertTrue(chs[4] == 'E'); + assertTrue(chs[5] == 'F'); + + // keep A stored + psr.restorePosition(); + psr.savePosition(); + + // skip from buf + psr.skip(3); + + assertTrue(psr.read() == 'D'); + + // keep A stored + psr.restorePosition(); + psr.savePosition(); + + assertTrue(psr.read() == 'A'); + + // keep A stored + psr.restorePosition(); + psr.savePosition(); + + chs = new char[64]; + n = psr.read(chs, 0, chs.length); + + assertTrue(n == 36); + for (char ch = 'A'; ch <= 'Z'; ++ch) + assertTrue(chs[ch - 'A'] == ch); + + for (char ch = '0'; ch <= '9'; ++ch) + assertTrue(chs[ch - '0' + 26] == ch); + + assertTrue(psr.read() == -1); + assertTrue(psr.read() == -1); + + assertTrue(psr.read(chs, 0, chs.length) == -1); + + } + + public static void main(String[] args) throws Throwable { + new TestPositionStackReader().test(); + System.err.println("SUCCESS"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TestStreamLexer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TestStreamLexer.java new file mode 100644 index 0000000000..6ddfd0a35f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TestStreamLexer.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +import java.io.StringReader; + +import com.avlsi.test.AbstractTestCase; + +/** + * This is a description of the class + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TestStreamLexer extends AbstractTestCase { + + public void test() throws Throwable { + final String s = "1e1 2. .3 0.0 3.14 1e-9 1e137 " + + " abc1 3def->boo "; + final double[] ds + = new double[]{1e1, 2., .3, 0.0, 3.14, 1e-9, 1e137}; + + final StreamLexer lex = new StreamLexer(new StringReader(s)); + + for (int i = 0; i < ds.length; ++i) + assertTrue(lex.readDouble() == ds[i]); + + assertTrue(lex.readIdentifier().equals("abc1")); + assertTrue(lex.readInt() == 3); + assertTrue(lex.readIdentifier().equals("def")); + assertTrue(lex.readSymbol("->").equals("->")); + assertTrue(lex.readIdentifier().equals("boo")); + } + + public static void main(String[] args) throws Throwable { + new TestStreamLexer().test(); + System.out.println("PASSED"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenException.java new file mode 100644 index 0000000000..69bd098cdf --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Abstract base class for all classes thrown to indicate that an attempt to + * parse a token. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public abstract class TokenException extends RuntimeException { + public TokenException() { + super(); + } + + public TokenException(final String detail) { + super(detail); + } + + public TokenException(final String detail, final Throwable cause) { + super(detail, cause); + } + + public TokenException(final Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotDoubleException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotDoubleException.java new file mode 100644 index 0000000000..0ac5eaa34d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotDoubleException.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse a double token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TokenNotDoubleException extends TokenException { + public TokenNotDoubleException() { + super(); + } + + public TokenNotDoubleException(final String detail) { + super(detail); + } + + public TokenNotDoubleException(final Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotEOFException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotEOFException.java new file mode 100644 index 0000000000..0bf612ff17 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotEOFException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse a EOF token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +class TokenNotEOFException extends TokenException { + public TokenNotEOFException() { + super(); + } + + public TokenNotEOFException(final String detail) { + super(detail); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIdentifierException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIdentifierException.java new file mode 100644 index 0000000000..bad5a97982 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIdentifierException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse a identifier token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TokenNotIdentifierException extends TokenException { + public TokenNotIdentifierException() { + super(); + } + + public TokenNotIdentifierException(final String detail) { + super(detail); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIntException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIntException.java new file mode 100644 index 0000000000..39629884dd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotIntException.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse an int token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TokenNotIntException extends TokenException { + public TokenNotIntException() { + super(); + } + + public TokenNotIntException(final String detail) { + super(detail); + } + + public TokenNotIntException(final Throwable cause) { + super(cause); + } + + public TokenNotIntException( + final String message, + final Throwable cause) { + super(message, cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotLiteralException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotLiteralException.java new file mode 100644 index 0000000000..d71ee3e4f3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotLiteralException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse a literal token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +class TokenNotLiteralException extends TokenException { + public TokenNotLiteralException() { + super(); + } + + public TokenNotLiteralException(final String detail) { + super(detail); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotQuotedStringException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotQuotedStringException.java new file mode 100644 index 0000000000..8a1382d873 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotQuotedStringException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse a quoted string token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TokenNotQuotedStringException extends TokenException { + public TokenNotQuotedStringException() { + super(); + } + + public TokenNotQuotedStringException(final String detail) { + super(detail); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotSymbolException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotSymbolException.java new file mode 100644 index 0000000000..8156423e29 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotSymbolException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse a symbol token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TokenNotSymbolException extends TokenException { + public TokenNotSymbolException() { + super(); + } + + public TokenNotSymbolException(final String detail) { + super(detail); + } + + public TokenNotSymbolException(final String detail, + final Throwable cause) { + super(detail, cause); + } + + public TokenNotSymbolException(final Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotWhitespaceException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotWhitespaceException.java new file mode 100644 index 0000000000..205f7180f2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TokenNotWhitespaceException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.io; + +/** + * Thrown to indicate that an attempt to parse a whitespace token failed. + * + * @see StreamLexer + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +class TokenNotWhitespaceException extends TokenException { + public TokenNotWhitespaceException() { + super(); + } + + public TokenNotWhitespaceException(final String detail) { + super(detail); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/TrivialSearchPathFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TrivialSearchPathFile.java new file mode 100644 index 0000000000..1c0d31eb0e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/TrivialSearchPathFile.java @@ -0,0 +1,121 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.io; + +import java.io.FileNotFoundException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.FileInputStream; +import com.avlsi.io.SearchPathFile; + +import com.avlsi.util.debug.Debug; + +public class TrivialSearchPathFile implements SearchPathFile { + + private File m_File; + + /** + * Return the canonical file of theFile if possible, or + * theFile if not (due to an IOException being + * thrown). + **/ + private static File canonizeIfPossible(final File theFile) { + try { + return theFile.getCanonicalFile(); + } catch (IOException e) { + return theFile; + } + } + + /** + * Returns true if theFile is canonical, i.e., its name equals + * to the name of the File returned by + * theFile.getCanonicalPath(). If an IOException + * is thrown, return false. + **/ + private static boolean isCanonical(final File theFile) { + final String canon; + try { + canon = theFile.getCanonicalPath(); + } catch (IOException e) { + return false; + } + return canon.equals(theFile.getPath()); + } + + public TrivialSearchPathFile( final File theFile ) { + this(theFile, false); + } + + /** + * Construct a new TrivialSearchPathFile. + * + * @param isCanon If true, then theFile is assumed to be + * canonical (in the sense it's an object returned by File's + * getCanonicalFile method). + **/ + public TrivialSearchPathFile( final File theFile, boolean isCanon ) { + assert theFile.isFile(); + + // XXX: We would like to check that if the caller claims theFile is + // canonical, that it actually is. But, there is no good way to check + // this, since the filesystem might have changed between when this + // constructor is called and now, so that theFile might have been + // canonical in the caller, but is no longer. On the other hand, + // applications that is expected to be robust to such changes should + // not be using this class anyway. + assert !isCanon || isCanonical(theFile); + + m_File = isCanon ? theFile : canonizeIfPossible(theFile); + } + + public TrivialSearchPathFile( final String fileName ) { + + this( new File( fileName ) ); + } + + + public String getName() { + return m_File.getAbsolutePath(); + } + + public InputStream getStream() throws FileNotFoundException { + if ( m_File.isFile() ) { + return new FileInputStream( m_File ); + } + else { + throw new FileNotFoundException(); + } + } + + public File getFile() { + return m_File; + } + + public boolean canRead() { + return m_File.canRead(); + } + + public boolean exists() { + return m_File.exists(); + } + + public long lastModified() { + final long ret = m_File.lastModified(); + if ( ret == 0 ) { + return -1L; + } + else { + return ret; + } + } + + public long length() { + return m_File.length(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintStream.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintStream.java new file mode 100644 index 0000000000..6397406bb7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintStream.java @@ -0,0 +1,82 @@ +/* + * Copyright 2006 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.io; + +import java.io.PrintStream; + +public class WrapPrintStream implements Printable { + private final PrintStream w; + + public WrapPrintStream(PrintStream w) { + this.w = w; + } + + /** Flush the stream if it's not closed and check its error state. */ + public boolean checkError() { return w.checkError(); } + + /** Close the stream. */ + public void close() { w.close(); } + + /** Flush the stream. */ + public void flush() { w.flush(); } + + /** Print a boolean value. */ + public void print(boolean b) { w.print(b); } + + /** Print a character. */ + public void print(char c) { w.print(c); } + + /** Print an array of characters. */ + public void print(char[] s) { w.print(s); } + + /** Print a double-precision floating-point number. */ + public void print(double d) { w.print(d); } + + /** Print a floating-point number. */ + public void print(float f) { w.print(f); } + + /** Print an integer. */ + public void print(int i) { w.print(i); } + + /** Print a long integer. */ + public void print(long l) { w.print(l); } + + /** Print an object. */ + public void print(Object obj) { w.print(obj); } + + /** Print a string. */ + public void print(String s) { w.print(s); } + + /** Terminate the current line by writing the line separator string. */ + public void println() { w.println(); } + + /** Print a boolean value and then terminate the line. */ + public void println(boolean x) { w.println(x); } + + /** Print a character and then terminate the line. */ + public void println(char x) { w.println(x); } + + /** Print an array of characters and then terminate the line. */ + public void println(char[] x) { w.println(x); } + + /** Print a double-precision floating-point number and then terminate the line. */ + public void println(double x) { w.println(x); } + + /** Print a floating-point number and then terminate the line. */ + public void println(float x) { w.println(x); } + + /** Print an integer and then terminate the line. */ + public void println(int x) { w.println(x); } + + /** Print a long integer and then terminate the line. */ + public void println(long x) { w.println(x); } + + /** Print an Object and then terminate the line. */ + public void println(Object x) { w.println(x); } + + /** Print a String and then terminate the line. */ + public void println(String x) { w.println(x); } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintWriter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintWriter.java new file mode 100644 index 0000000000..c62040a6dd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/io/WrapPrintWriter.java @@ -0,0 +1,82 @@ +/* + * Copyright 2006 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.io; + +import java.io.PrintWriter; + +public class WrapPrintWriter implements Printable { + private final PrintWriter w; + + public WrapPrintWriter(PrintWriter w) { + this.w = w; + } + + /** Flush the stream if it's not closed and check its error state. */ + public boolean checkError() { return w.checkError(); } + + /** Close the stream. */ + public void close() { w.close(); } + + /** Flush the stream. */ + public void flush() { w.flush(); } + + /** Print a boolean value. */ + public void print(boolean b) { w.print(b); } + + /** Print a character. */ + public void print(char c) { w.print(c); } + + /** Print an array of characters. */ + public void print(char[] s) { w.print(s); } + + /** Print a double-precision floating-point number. */ + public void print(double d) { w.print(d); } + + /** Print a floating-point number. */ + public void print(float f) { w.print(f); } + + /** Print an integer. */ + public void print(int i) { w.print(i); } + + /** Print a long integer. */ + public void print(long l) { w.print(l); } + + /** Print an object. */ + public void print(Object obj) { w.print(obj); } + + /** Print a string. */ + public void print(String s) { w.print(s); } + + /** Terminate the current line by writing the line separator string. */ + public void println() { w.println(); } + + /** Print a boolean value and then terminate the line. */ + public void println(boolean x) { w.println(x); } + + /** Print a character and then terminate the line. */ + public void println(char x) { w.println(x); } + + /** Print an array of characters and then terminate the line. */ + public void println(char[] x) { w.println(x); } + + /** Print a double-precision floating-point number and then terminate the line. */ + public void println(double x) { w.println(x); } + + /** Print a floating-point number and then terminate the line. */ + public void println(float x) { w.println(x); } + + /** Print an integer and then terminate the line. */ + public void println(int x) { w.println(x); } + + /** Print a long integer and then terminate the line. */ + public void println(long x) { w.println(x); } + + /** Print an Object and then terminate the line. */ + public void println(Object x) { w.println(x); } + + /** Print a String and then terminate the line. */ + public void println(String x) { w.println(x); } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/AP1ofNDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/AP1ofNDef.java new file mode 100644 index 0000000000..8b7511b26f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/AP1ofNDef.java @@ -0,0 +1,194 @@ +package com.avlsi.layout; +import java.text.MessageFormat; +import java.util.LinkedList; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Collection; + +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +/** + * Definition of a 1ofN channel extending {@link APPortDef }. Implements toSkillString() and allows flattening + */ + +public class AP1ofNDef extends APChannelDef implements Comparable { + + private APPitchedNodeDef enablePort; + private List dataPorts; + private int pitchSpacing; + private int type; + public static final int OUTPUT_CHILDREN = 0; + public static final int OUTPUT_PARENT = 1; + + public AP1ofNDef( final HierName portName, + final String portType, + final APPitchedNodeDef enablePort, + final List dataPorts, + final List allPorts, + final int direction, + final boolean bunched ) { + super(portName, portType, allPorts, direction, bunched); + this.enablePort = enablePort; + this.dataPorts = dataPorts; + this.type = OUTPUT_CHILDREN; + } + + public void setOutputType( final int type ) { + if(type == OUTPUT_CHILDREN) + this.type = OUTPUT_CHILDREN; + else + this.type = OUTPUT_PARENT; + } + + /** + * Gets a Collection of the sub {@link APNodeDef}s of this channel + */ + + public Collection getNodes() { + ArrayList allPorts = new ArrayList(dataPorts); + if ( enablePort != null ) + allPorts.add( size()/2, enablePort ); + return allPorts; + } + + public int compareTo( final Object o ) throws ClassCastException { + return compareTo((AP1ofNDef) o); + } + + public int compareTo( final AP1ofNDef o ) { + return getN() - o.getN(); + } + + public int getEnablePitch() { + return enablePort.getPitch(); + } + + public void setEnablePitch( final int enablePitch ) { + enablePort.setPitch(enablePitch); + } + + public void setDataPitches( final List dataPitches ) { + Iterator i=dataPitches.iterator(); + Iterator j=dataPorts.iterator(); + for(; i.hasNext(); ) { + int pitch = ((Integer)i.next()).intValue(); + APPitchedNodeDef node = (APPitchedNodeDef)j.next(); + node.setPitch(pitch); + } + } + + public Iterator getDataPitches() { + return new MappingIterator(dataPorts.iterator(), new UnaryFunction() { + public Object execute(Object arg) { + APPitchedNodeDef node = (APPitchedNodeDef)arg; + return new Integer( node.getPitch() ); + } + } ); + } + + public HierName getEnableNetName() { + return enablePort.getNetName(); + } + + public HierName getEnablePortName() { + return enablePort.getPortName(); + } + + public int getPitchSpacing() { + return pitchSpacing; + } + + public void setPitchSpacing( final int pitchSpacing ) { + this.pitchSpacing = pitchSpacing; + } + + public Iterator getDataNetNames() { + return new MappingIterator(dataPorts.iterator(), new UnaryFunction() { + public Object execute(Object arg) { + APNodeDef node = (APNodeDef)arg; + return node.getNetName(); + } + } ); + } + + public Iterator getDataPortNames() { + return new MappingIterator(dataPorts.iterator(), new UnaryFunction() { + public Object execute(Object arg) { + APNodeDef node = (APNodeDef)arg; + return node.getPortName(); + } + } ); + } + + public int getN() { + return dataPorts.size(); + } + + public int size() { + return dataPorts.size() + ( enablePort == null ? 0 : 1 ); + } + + static final MessageFormat formNumList = new MessageFormat( "( list {0} )" ); + static final MessageFormat formNet = new MessageFormat( "\"{0}\" " ); + static final MessageFormat formLeft = new MessageFormat( "( PinPlaceLeft1ofN \"{0}\" ( list {1} ) {2} {3} {4} {5} )\n" ); + static final MessageFormat formRight = new MessageFormat( "( PinPlaceRight1ofN \"{0}\" ( list {1} ) {2} {3} {4} {5} )\n" ); + static final MessageFormat formLeftRight = new MessageFormat( "( PinPlaceLeftRight1ofN \"{0}\" ( list {1} ) {2} {3} {4} {5} )\n" ); + + public String toSkillString( final PinGlobal global ) throws CDLRenameException { + if( size() >= 1 ) { + if(type == OUTPUT_CHILDREN) + return super.toSkillString(global); + + //get data net names + String strData = ""; + for(Iterator i=getDataNetNames(); i.hasNext(); ) { + HierName dataNetName = (HierName) i.next(); + strData += formNet.format( new Object[] { getCadenceNetName(dataNetName.toString()) } ); + } + + //get width and spacings + String strWidth = ""; + String strSpacing = ""; + boolean mustWriteWidth=false; + for(Iterator i=getNodes().iterator(); i.hasNext(); ) { + APPitchedNodeDef node = (APPitchedNodeDef) i.next(); + strWidth += node.getWidth() + " "; + strSpacing += node.getSpacing() + " "; + if( node.getWidth() != global.width ) + mustWriteWidth = true; + } + strWidth = ( mustWriteWidth ? formNumList.format( new Object[] { strWidth } ) : "" ) ; + strSpacing = ( mustWriteWidth ? formNumList.format( new Object[] { strSpacing } ) : "" ); + + + Object[] args = { getCadenceNetName(getEnableNetName().toString()), strData, new Integer(getEnablePitch()), new Integer(pitchSpacing), strWidth, strSpacing }; + + switch( direction ) { + case PortDefinition.IN: + return formLeft.format(args); + case PortDefinition.OUT: + return formRight.format(args); + case PortDefinition.INOUT: + return formLeftRight.format(args); + default: + return ""; + } + } + else + return ""; + } + + public boolean isNode() { + return false; + } + + public boolean isLeaf() { + return true; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APChannelDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APChannelDef.java new file mode 100644 index 0000000000..7f2b3e57a2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APChannelDef.java @@ -0,0 +1,85 @@ +package com.avlsi.layout; + +import java.util.List; +import java.util.LinkedList; +import java.util.Iterator; +import java.text.MessageFormat; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +/** + * Definition of a Channel extending {@link APPortDef }. + */ + +public class APChannelDef extends APPortDef { + + boolean bunched; + String portType; + List subPorts; + + public APChannelDef( final HierName portName, + final String portType, + final List subPorts, + final int direction, + final boolean bunched ) { + super(null, portName, direction); + this.portType = portType; + this.subPorts = subPorts; + this.bunched = bunched; + } + + public List getSubPorts() { + return subPorts; + } + + public boolean isBunched() { + return bunched; + } + + public boolean isFlattened() { + boolean flattened=true; + for(Iterator i=getSubPorts().iterator(); i.hasNext(); ) { + final APPortDef port = (APPortDef) i.next(); + if( !port.isLeaf() ) { + flattened = false; + break; + } + } + return flattened; + } + + public String toSkillString( final PinGlobal global ) throws CDLRenameException { + String str=""; + for(Iterator i=getSubPorts().iterator(); i.hasNext(); ) { + APPortDef port = (APPortDef) i.next(); + str += port.toSkillString(global); + } + + return str; + } + + public boolean isNode() { + return false; + } + + public boolean isLeaf() { + return isBunched(); + } + + public List getLeafPorts() { + List leafPorts = new LinkedList(); + for(Iterator i=getSubPorts().iterator(); i.hasNext(); ) { + APPortDef port = (APPortDef) i.next(); + if( port.isLeaf() ) + leafPorts.add( port ); + else if( port instanceof APChannelDef ) + leafPorts.addAll( ((APChannelDef)port).getLeafPorts() ); + } + return leafPorts; + } + + public APPortDef getInPlacePortDef() { + return new APInPlaceChannelDef(portName, portType, subPorts, bunched); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APDefaultPortDefFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APDefaultPortDefFactory.java new file mode 100644 index 0000000000..4cf79f1ce5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APDefaultPortDefFactory.java @@ -0,0 +1,68 @@ +package com.avlsi.layout; +import com.avlsi.file.common.HierName; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.LinkedList; +import java.util.Iterator; + +public class APDefaultPortDefFactory extends APPortDefFactory { + public APPortDef makePowerGridDef( final HierName netName, + final HierName portName, + final float width, + final float spacing ) { + return new APPowerGridDef(netName, portName, width, spacing); + } + + public APPortDef makeNodeDef( final HierName netName, + final HierName portName, + final int direction, + final float width, + final float spacing ) { + // System.out.println( netName + " " + portName + " " + direction ); + return new APPitchedNodeDef(netName, portName, direction, width, spacing); + } + + public APPortDef makeHorizontalStrutDef( final HierName netName, + final HierName portName, + final float width, + final float spacing ) { + return new APHorizontalStrutDef(netName, portName, width, spacing); + } + + public APPortDef makeChannelDef( final HierName portName, + final String portType, + final List subPorts, + final int direction, + boolean bunched ) { + boolean pitchedPorts = true; + for(Iterator i = subPorts.iterator(); i.hasNext(); ) { + if( !( i.next() instanceof APPitchedNodeDef ) ) + pitchedPorts = false; + } + if( pitchedPorts && portType.matches( ".*1of[0-9]*.*" ) ) { + APPitchedNodeDef enablePort = null; + List dataPorts = new LinkedList(); + for(Iterator i = subPorts.iterator(); i.hasNext(); ) { + APPitchedNodeDef node = (APPitchedNodeDef) i.next(); + if( node.getPortName().getSuffixString().matches( ".*[ae]" ) ) { + enablePort = node; + } + else { + dataPorts.add( node ); + } + } + + if(enablePort == null && dataPorts.size() != 0) { + enablePort = (APPitchedNodeDef) dataPorts.remove( dataPorts.size() / 2 ); + } + + return new AP1ofNDef(portName, portType, enablePort, dataPorts, subPorts, direction, bunched); + } + else { + return new APChannelDef(portName, portType, subPorts, direction, bunched); + } + } +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APHorizontalStrutDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APHorizontalStrutDef.java new file mode 100644 index 0000000000..7ba34f1af9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APHorizontalStrutDef.java @@ -0,0 +1,27 @@ +package com.avlsi.layout; +import java.text.MessageFormat; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class APHorizontalStrutDef extends APPitchedNodeDef { + + public APHorizontalStrutDef(HierName netName, HierName portName, float width, float spacing) { + super(netName, portName, PortDefinition.INOUT, width, spacing); + } + + static final MessageFormat form = new MessageFormat( "( PinPlaceHorizontalStrut \"{0}\" {1} {2} {3} )\n" ); + + public String toSkillString(PinGlobal global) throws CDLRenameException { + final Object[] args; + if( width != global.width ) + if( spacing != global.spacing ) + args = new Object[] { getCadenceNetName(netName.toString()), new Integer(pitch), ""+width, ""+spacing }; + else + args = new Object[] { getCadenceNetName(netName.toString()), new Integer(pitch), ""+width, "" }; + else + args = new Object[] { getCadenceNetName(netName.toString()), new Integer(pitch), "", ""}; + + return form.format(args); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceChannelDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceChannelDef.java new file mode 100644 index 0000000000..daa0eb1579 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceChannelDef.java @@ -0,0 +1,36 @@ +package com.avlsi.layout; + +import java.util.List; +import java.util.LinkedList; +import java.util.Iterator; + +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; + +public class APInPlaceChannelDef extends APChannelDef { + + public APInPlaceChannelDef( final HierName portName, + final String portType, + final List subPorts, + final boolean bunched ) { + super(portName, portType, subPorts, PortDefinition.NONE, bunched); + } + + public List getSubPorts() { + final List inplacePorts = new LinkedList(); + Iterator i = new MappingIterator(super.getSubPorts().iterator(), new UnaryFunction() { + public Object execute(Object arg) { + APPortDef port = (APPortDef) arg; + return port.getInPlacePortDef(); + } + } ); + + for(;i.hasNext(); ) { + inplacePorts.add( i.next() ); + } + + return inplacePorts; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceNodeDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceNodeDef.java new file mode 100644 index 0000000000..bbd3a397cb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlaceNodeDef.java @@ -0,0 +1,28 @@ +package com.avlsi.layout; +import java.text.MessageFormat; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +/** + * Definition of an InPlace Node - a Node that is adopted from a subcell + */ + +public class APInPlaceNodeDef extends APNodeDef { + public APInPlaceNodeDef(HierName netName, HierName portName) { + super(netName, portName, PortDefinition.NONE); + } + + static final MessageFormat form = new MessageFormat( "( PinPlaceInPlace \"{0}\" )\n" ); + + public String toSkillString(PinGlobal global) throws CDLRenameException { + Object[] args = { getCadenceNetName( netName.toString() ) }; + return form.format(args); + } + + public APPortDef getInPlacePortDef() { + return this; + } +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlacePortDefFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlacePortDefFactory.java new file mode 100644 index 0000000000..692789d285 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APInPlacePortDefFactory.java @@ -0,0 +1,43 @@ +package com.avlsi.layout; +import com.avlsi.file.common.HierName; +import java.util.List; +import java.util.LinkedList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Collections; + +public class APInPlacePortDefFactory extends APPortDefFactory { + + static final APDefaultPortDefFactory baseFactory = new APDefaultPortDefFactory(); + + public APPortDef makePowerGridDef( final HierName netName, + final HierName portName, + final float width, + final float spacing ) { + return baseFactory.makePowerGridDef(netName, portName, width, spacing).getInPlacePortDef(); + } + + public APPortDef makeNodeDef( final HierName netName, + final HierName portName, + final int direction, + final float width, + final float spacing ) { + return baseFactory.makeNodeDef(netName, portName, direction, width, spacing).getInPlacePortDef(); + } + + public APPortDef makeHorizontalStrutDef( final HierName netName, + final HierName portName, + final float width, + final float spacing ) { + return baseFactory.makeHorizontalStrutDef(netName, portName, width, spacing).getInPlacePortDef(); + } + + public APPortDef makeChannelDef( final HierName portName, + final String portType, + final List subPorts, + final int direction, + final boolean bunched ) { + return baseFactory.makeChannelDef(portName, portType, subPorts, direction, bunched).getInPlacePortDef(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APLocale.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APLocale.java new file mode 100644 index 0000000000..0aae2e34e7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APLocale.java @@ -0,0 +1,504 @@ + +package com.avlsi.layout; + +import java.util.LinkedList; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Enumeration; +import java.util.List; +import java.util.LinkedList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.ports.PortDefinition; + +/** + * Class representing a line of wire pitches in a cell. e.g. left or right edges. + * This class places {@link APPortDef}s. Should be called PinPlacer + **/ + +public class APLocale { + final private int locale; + final private ArrayList reservedPitchList = new ArrayList(); + final private List globalTakenPitchList = new LinkedList(); + final private int pitches; + final private float wirePitch; + + public APLocale( final int pitches, final float wirePitch, final int locale) { + this.pitches = pitches; + this.wirePitch = wirePitch; + this.locale = locale; + } + + private int getNodePitches( final APPitchedNodeDef node) { + int ret = (int) Math.ceil( ( node.getWidth() + node.getSpacing() ) / wirePitch ); + return ret; + } + + /** + * Places an {@link APPowerGridDef} with the following offset and spacing + * Reserves space for the grid, and returns the number of struts reserved + **/ + private void placePowerGrid( final APPowerGridDef pg, final int pgOffset, final int pgSpacing ) { + int gridPitch = pgOffset; + + pg.setGridOffset(pgOffset); + pg.setGridSpacing(pgSpacing); + + while( gridPitch + getNodePitches(pg) <= pitches) { + reservePitch(gridPitch, getNodePitches(pg)); + gridPitch += pgSpacing; + } + } + + /** + * Inserts the given Integer value in a sorted list at the corrected location + **/ + private void insertInList(final ArrayList list, final int value ) { + Integer obj = new Integer(value); + int k = Collections.binarySearch( list, obj ); + if(k<0) { + k = -k - 1; + list.add( k, obj ); + } + } + + /** + * Tests if the given pitch is occupied + **/ + private boolean isOccupied( final int pitch, final int width, final List takenPitchList ) { + for(int i = 0; i < width; i++) { + if( Collections.binarySearch( takenPitchList, new Integer(pitch+i) ) >= 0 ) + return true; + } + return false; + } + + /** + * Takes the given relative pitch + * Return true if not already taken, false if already taken + **/ + private void takePitch( final int pitch, final int width, final ArrayList takenPitchList ) { + for(int i=0; i= 0 ) { + maxEmptyAbs++; + } + k = -k-1; + int maxEmptyRel = maxEmptyAbs - k; + int minEmptyAbs = trial; + while( (k=Collections.binarySearch( reservedPitchList, new Integer(minEmptyAbs) ) ) >= 0 ) { + minEmptyAbs--; + } + k = -k-1; + int minEmptyRel = minEmptyAbs - k; + + /* + System.out.println( "" + min + " " + max + " " + pitch + " " + k); + try { + System.in.read( new byte[1] ); + } + catch( Exception e) { } + */ + + //trial not in reserved list + + if( maxEmptyRel < pitch ) + return getAbsolutePitchImpl(maxEmptyAbs, max, pitch); + else if( minEmptyRel > pitch ) + return getAbsolutePitchImpl(min, minEmptyAbs, pitch); + else if (maxEmptyRel == pitch) + return maxEmptyAbs; + else + return minEmptyAbs; + } + + /** + * Tests if the given {@link APPortDef} is associated with this locale + **/ + private boolean isPort( final APPortDef def ) { + if( def.getDirection() == locale || def.getDirection() == PortDefinition.INOUT ) + return true; + else + return false; + } + + + /** + * Places each {@link APPortDef} in the Vector of ports that came from the given cell. + * The power grid is reserved according to pgOffset and pgSpacing + **/ + public void placePorts( final CellInterface cell, + final List ports, + final int pgOffset, + final int pgSpacing, + final String pgGNDnet, + final String pgVddnet ) + throws PinPlaceException { + + LinkedList listPG = new LinkedList(); + LinkedList listSub = new LinkedList(); + LinkedList listInOut = new LinkedList(); + int pgWidth = -1; + + //split up the ports + for(Iterator i=ports.iterator(); i.hasNext(); ) { + APPortDef def = (APPortDef) i.next(); + if( isPort( def ) ) { + if(def.getDirection() == PortDefinition.INOUT && + def instanceof APPitchedNodeDef ) { + if( def instanceof APPowerGridDef ) + listPG.add(def); + else + listInOut.add(def); + } + else + listSub.add( def ); + } + } + + //setup pitch reservations(bound the viable pitches) + reservePitch(-1, 1); + reservePitch(pitches, 1); + + //power grid reserve + for(Iterator i=listPG.iterator(); i.hasNext(); ) { + APPowerGridDef pg = (APPowerGridDef) i.next(); + if( pg.getPortName().toString().equals(pgGNDnet) ) { + placePowerGrid(pg, pgOffset, pgSpacing); + pgWidth = getNodePitches( pg ); + } + else if( pg.getPortName().toString().equals(pgVddnet) ) { + placePowerGrid(pg, pgOffset + pgSpacing/2, pgSpacing); + pgWidth = getNodePitches( pg ); + } + } + + //in-out nodes + //in the middle + for(Iterator i=listInOut.iterator(); i.hasNext(); ) { + APPitchedNodeDef node = (APPitchedNodeDef) i.next(); + final int relPitch = (pitches - reservedPitchList.size()) / 2 ; + final int absPitch = getAbsolutePitch(relPitch); + reservePitch(absPitch, getNodePitches(node)); + node.setPitch(absPitch); + } + + if(pgSpacing <= pgWidth) { + throw new PinPlaceException("Power grid spacing " + pgSpacing + " not sufficient"); + } + if(pgWidth < 1 ) { + throw new PinPlaceException("Power grid width " + pgWidth + " invalid"); + } + + //attempt to force interleave + boolean success = + placeSubPorts(listSub, 0, reservedPitchList.size()-1, pgSpacing, pgWidth, globalTakenPitchList, true); + //if not, allow flattening + if(!success) + success = + placeSubPorts(listSub, 0, reservedPitchList.size()-1, pgSpacing, pgWidth, globalTakenPitchList, false); + + if(!success) + throw new PinPlaceException("Can't fit pins"); + } + + + boolean place1ofN( final AP1ofNDef def, + final int enablePitch, + final int pinSpacing, + final int minPitch, + final int maxPitch, + final ArrayList takenPitchList ) { + //System.out.println( "1ofn: " + enablePitch + ", " + pinSpacing + ", " + minPitch + ", " + maxPitch); + boolean bFit = true; + + List nodes = new LinkedList( def.getNodes() ); + for(int j = 0; j maxPitch || + isOccupied(pitch, width, takenPitchList ) ) + bFit = false; + } + if( bFit ) { + LinkedList pitchList = new LinkedList(); + for(int j = 0; j 0) { + int numUsedPitches = topUsedPitch + 1; + int numAvailableSpaces = maxPitch - numUsedPitches; + int numSpacesBetweenGrid = pgSpacing/2 - pgWidth; + enablePitch = topUsedPitch + (numAvailableSpaces - list1ofNSpread.size()) / 2; + int maxSize = ((AP1ofNDef)list1ofNSpread.get(0)).size(); + int pitchesToEnable = enablePitch - numUsedPitches; + + int maxPinSpacing; + if ( maxSize < 2 ) { + maxPinSpacing = 0; + } + else{ + maxPinSpacing = pitchesToEnable / ( maxSize / 2); + } + int basePinSpacing = ( maxPinSpacing / numSpacesBetweenGrid) * numSpacesBetweenGrid; + if( basePinSpacing < list1ofNSpread.size() ) + basePinSpacing = maxPinSpacing; + + if ( ( basePinSpacing < 1 ) && ( maxSize > 1 ) ) + return false; + + for(Iterator i=list1ofNSpread.iterator(); i.hasNext(); ) { + AP1ofNDef def = (AP1ofNDef) i.next(); + + while( enablePitch <= maxPitch) { + int pinSpacing; + if ( def.size() < 2 ) { + pinSpacing = 0; + } + else { + pinSpacing = pitchesToEnable / ( def.size() / 2 ); + } + if ( basePinSpacing != 0 ) { + pinSpacing = ( pinSpacing / basePinSpacing ) * basePinSpacing; + } + else { + pinSpacing = 0; + } + boolean success = + place1ofN(def, enablePitch, pinSpacing, minPitch, maxPitch, trialTakenPitchList); + // System.out.println( "" + basePinSpacing + " " + pinSpacing + " " + enablePitch ); + enablePitch++; + if(success) + break; + } + //if can't fit, then place them like flattened nodes, and use children output + if(enablePitch > maxPitch ) { + if( forceInterleave ) + return false; + else { + def.setOutputType(AP1ofNDef.OUTPUT_CHILDREN); + listNodes.addAll ( def.getNodes() ); + } + } + } + } + + //nodes + int currPitch = minPitch; + int numPitches = maxPitch - minPitch + 1; + for(Iterator i = listNodes.iterator(); i.hasNext(); ) { + APPitchedNodeDef node = (APPitchedNodeDef) i.next(); + boolean bFit = false; + for(int j=0; j < numPitches; j++) { + int pitch = currPitch + j; + if(pitch >= maxPitch ) + pitch -= numPitches - 1; + if( !isOccupied(pitch, getNodePitches(node), trialTakenPitchList) ) { + takePitch(pitch, getNodePitches(node), trialTakenPitchList); + node.setPitch(getAbsolutePitch(pitch)); + currPitch += 2; + if(currPitch >= maxPitch) currPitch -= numPitches - 1; + bFit = true; + break; + } + } + if( !bFit ) + return false; + } + + //sucess - commit changes and return true + parentTakenPitchList.removeAll(trialTakenPitchList); + parentTakenPitchList.addAll(trialTakenPitchList); + return true; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APNodeDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APNodeDef.java new file mode 100644 index 0000000000..045f418713 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APNodeDef.java @@ -0,0 +1,23 @@ +package com.avlsi.layout; +import java.text.MessageFormat; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; + +/** + * Definition of a Node extending {@link APPortDef }. Implements toSkillString() + */ + +public abstract class APNodeDef extends APPortDef { + + public APNodeDef(HierName netName, HierName portName, int direction) { + super(netName, portName, direction); + } + + public boolean isNode() { + return true; + } + + public boolean isLeaf() { + return true; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPitchedNodeDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPitchedNodeDef.java new file mode 100644 index 0000000000..ce592f0c2b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPitchedNodeDef.java @@ -0,0 +1,79 @@ + +package com.avlsi.layout; +import java.text.MessageFormat; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +/** + * Definition of a Node with a pitch extending {@link APNodeDef }. Implements toSkillString() + */ + +public class APPitchedNodeDef extends APNodeDef { + + public APPitchedNodeDef(HierName netName, HierName portName, int direction, float width, float spacing) { + super(netName, portName, direction); + this.width = width; + this.spacing = spacing; + } + + /** + * The pitch index of the port + **/ + + public static final int NONE = -1; + + protected int pitch = NONE; + + public void setPitch(int pitch) { + this.pitch = pitch; + } + + public int getPitch() { + return pitch; + } + + protected float width; + protected float spacing; + + public float getWidth() { + return width; + } + + public float getSpacing() { + return spacing; + } + + + static final MessageFormat formLeft = new MessageFormat( "( PinPlaceLeft \"{0}\" {1} {2} {3} )\n" ); + static final MessageFormat formRight = new MessageFormat( "( PinPlaceRight \"{0}\" {1} {2} {3} )\n" ); + static final MessageFormat formLeftRight = new MessageFormat( "( PinPlaceLeftRightPin \"{0}\" {1} {2} {3} )\n" ); + + public String toSkillString(PinGlobal global) throws CDLRenameException { + final Object[] args; + if( width != global.width ) + if( spacing != global.spacing ) + args = new Object[] { getCadenceNetName(netName.toString()), new Integer(pitch), ""+width, ""+spacing }; + else + args = new Object[] { getCadenceNetName(netName.toString()), new Integer(pitch), ""+width, "" }; + else + args = new Object[] { getCadenceNetName(netName.toString()), new Integer(pitch), "", ""}; + + + switch( direction ) { + case PortDefinition.IN: + return formLeft.format(args); + case PortDefinition.OUT: + return formRight.format(args); + case PortDefinition.INOUT: + return formLeftRight.format(args); + default: + return ""; + } + } + + public APPortDef getInPlacePortDef() { + return new APInPlaceNodeDef(netName, portName); + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDef.java new file mode 100644 index 0000000000..9a93b16516 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDef.java @@ -0,0 +1,61 @@ +/** + * Definition of a Port for a pin placer. + */ + + +package com.avlsi.layout; +import java.text.MessageFormat; +import com.avlsi.file.common.HierName; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; + +public abstract class APPortDef { + /** + * The canonical name of the net attached + **/ + protected HierName netName; + + /** + * The full name of the port + */ + protected HierName portName; + + /** + * The direction (locale) of the port + */ + protected int direction; + + public int getDirection() { + return direction; + } + + public HierName getNetName() { + return netName; + } + + public HierName getPortName() { + return portName; + } + + public APPortDef(HierName netName, HierName portName, int direction) { + this.netName = netName; + this.portName = portName; + this.direction = direction; + } + + private static CadenceNameInterface cni = new CadenceNameInterface(); + + public static String getCadenceNetName(String netName) throws CDLRenameException { + return cni.renameNode( netName ); + } + + /** + * Converts the Port to a SkillString - the code to create the port + */ + public abstract String toSkillString(PinGlobal global) throws CDLRenameException ; + public abstract boolean isNode(); + public abstract boolean isLeaf(); + public abstract APPortDef getInPlacePortDef(); +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDefFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDefFactory.java new file mode 100644 index 0000000000..7c7ba777a4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPortDefFactory.java @@ -0,0 +1,28 @@ +package com.avlsi.layout; +import com.avlsi.file.common.HierName; +import java.util.Collection; +import java.util.List; + +/** + * Factory to create Collections of APPortDef's from CellInterface info + **/ +public abstract class APPortDefFactory { + public abstract APPortDef makePowerGridDef( final HierName netName, + final HierName portName, + final float width, + final float spacing ); + public abstract APPortDef makeNodeDef( final HierName netName, + final HierName portName, + final int direction, + final float width, + final float spacing ); + public abstract APPortDef makeChannelDef( final HierName portName, + final String portType, + final List subPorts, + final int direction, + final boolean bunched ); + public abstract APPortDef makeHorizontalStrutDef( final HierName netName, + final HierName portName, + final float width, + final float spacing ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPowerGridDef.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPowerGridDef.java new file mode 100644 index 0000000000..71af9aa754 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/APPowerGridDef.java @@ -0,0 +1,75 @@ +package com.avlsi.layout; +import java.text.MessageFormat; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class APPowerGridDef extends APPitchedNodeDef { + + + private int gridOffset; + private int gridSpacing; + + public int getGridOffset() { + return gridOffset; + } + + public int getGridSpacing() { + return gridSpacing; + } + + public void setGridSpacing(int gridSpacing) { + this.gridSpacing = gridSpacing; + } + + public void setGridOffset(int gridOffset) { + this.gridOffset = gridOffset; + } + + + public APPowerGridDef(HierName netName, HierName portName, float width, float spacing) { + super(netName, portName, PortDefinition.INOUT, width, spacing); + } + + static final MessageFormat form = new MessageFormat( "( PinPlacePowerGrid \"{0}\" {1} {2} {3} {4})\n" ); + + public String toSkillString(PinGlobal global) throws CDLRenameException { + + final Object[] args; + if( width != global.width ) { + if( spacing != global.spacing ) + args = new Object[] { getCadenceNetName(portName.toString()), + new Integer(gridOffset), + new Integer(gridSpacing), + ""+width, + ""+spacing }; + else + args = new Object[] { getCadenceNetName(portName.toString()), + new Integer(gridOffset), + new Integer(gridSpacing), + ""+width, "" }; + } + else + args = new Object[] { getCadenceNetName(portName.toString()), + new Integer(gridOffset), + new Integer(gridSpacing), "", ""}; + + + + + + return form.format(args); + } + + public boolean isNode() { + return false; + } + + public boolean isLeaf() { + return true; + } + + public APPortDef getInPlacePortDef() { + return this; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/AutoPins.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/AutoPins.java new file mode 100644 index 0000000000..0f7e5f0d0c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/AutoPins.java @@ -0,0 +1,252 @@ +package com.avlsi.layout; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; +import java.util.HashMap; +import java.util.HashSet; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.BufferedWriter; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.container.Pair; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.cadencize.CadenceActionInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.util.debug.Debug; + +/** + * Class to automatically place Pins in a {@link CellInterface}. + **/ + +public class AutoPins extends CellProcessor { + + final protected int pgOffset; + final protected int pgSpacing; + final protected float pgWidth; + final protected String pgGNDnet; + final protected String pgVddnet; + final protected float wirePitch; + protected float cellHeight; + protected String pinType; + final protected Pair pinLayer; + + + public AutoPins(CellInterface cell, Cadencize cad) + throws PinPlaceException { + this(cell, cad, null, -1); + } + + public AutoPins(CellInterface cell, Cadencize cad, String pinType, + float height) + throws PinPlaceException { + super(cell, cad); + + //get cell directives + + //power grid GND net + pgGNDnet = (String) getDirective(cell, DirectiveConstants.POWERGRID_GNDNET); + + //power grid Vdd net + pgVddnet = (String) getDirective(cell, DirectiveConstants.POWERGRID_VDDNET); + + //cell-height + final float cellHeightInBitPitches = + ((Float) getDirective(cell, DirectiveConstants.HEIGHT)).floatValue(); + final float cellBitPitch = + ((Float) getDirective(cell, DirectiveConstants.BITPITCH)).floatValue(); + if(cellBitPitch < 0 ) + cellHeight = -1; + else + cellHeight = cellHeightInBitPitches * cellBitPitch; + + //wire-pitch + pinLayer = (Pair) getDirective(cell, DirectiveConstants.PINLAYER); + final Map layerWirePitchMap = + getDirective(cell, + DirectiveConstants.LAYER_WIREPITCH, + DirectiveConstants.LAYER_TYPE); + final Float wirePitchObj = (Float) layerWirePitchMap.get(pinLayer); + if(wirePitchObj == null) + wirePitch = -1; + else + wirePitch = wirePitchObj.floatValue(); + + final Map layerPGOffsetMap = + getDirective(cell, + DirectiveConstants.LAYER_POWERGRID_OFFSET, + DirectiveConstants.LAYER_TYPE); + pgOffset = ((Integer)layerPGOffsetMap.get(pinLayer)).intValue(); + + final Map layerPGSpacingMap = + getDirective(cell, + DirectiveConstants.LAYER_POWERGRID_SPACING, + DirectiveConstants.LAYER_TYPE); + pgSpacing = ((Integer)layerPGSpacingMap.get(pinLayer)).intValue(); + + final Map layerPGWidthMap = + getDirective(cell, + DirectiveConstants.LAYER_POWERGRID_WIREWIDTH, + DirectiveConstants.LAYER_TYPE); + + pgWidth = ((Float)layerPGWidthMap.get(pinLayer)).floatValue(); + + //pintype + // unless one was explicitly specified, try to figure out the + // proper pintype + if (pinType == null || + (!pinType.equals(DirectiveConstants.PINTYPE_INPLACE) && + !pinType.equals(DirectiveConstants.PINTYPE_PITCHED))) { + //force in-place if no height + if(cellHeight < 0 || wirePitch < 0) + pinType = DirectiveConstants.PINTYPE_INPLACE; + //otherwise get the command line if there + else if(cell.containsCompletePrs() ) { + pinType = DirectiveConstants.PINTYPE_PITCHED; + } + //otherwise rely on directive + else { + pinType = (String) getDirective(cell, DirectiveConstants.PINTYPE); + } + } + + if(pinType != null ) + this.pinType = pinType; + if(height > 0 ) + this.cellHeight = height; + + } + + public static Map getDirective(final CellInterface cell, + final String type, + final String param) + throws PinPlaceException { + final Map d = DirectiveUtils.getTopLevelDirective(cell, type, param); + if(d==null) { throw new PinPlaceException("Directive " + type + " could not be found!"); } + else return d; + } + + public static Object getDirective(final CellInterface cell, + final String type) + throws PinPlaceException { + final Object d = DirectiveUtils.getTopLevelDirective(cell, type); + if(d==null) { throw new PinPlaceException("Directive " + type + " could not be found!"); } + else return d; + } + + /** + * Places the pins from the given cell according to power grid parameters: pgOffset, pgSpacing + * Writes the Skill Code to file + **/ + public void process(Writer writer) + throws PinPlaceException, IOException { + APPortDefFactory portFactory; + + Debug.assertTrue( pinType.equals( DirectiveConstants.PINTYPE_PITCHED ) || + pinType.equals( DirectiveConstants.PINTYPE_INPLACE ) ); + + if( pinType.equals( DirectiveConstants.PINTYPE_PITCHED ) ) { + if( pgGNDnet == null) + throw new PinPlaceException("No powergrid_gndnet directive or command line argument"); + if( pgVddnet == null) + throw new PinPlaceException("No powergrid_vddnet directive or command line argument"); + if( pgWidth < 0 ) + throw new PinPlaceException("No powergrid_width directive or command line argument"); + if( pgSpacing < 0 ) + throw new PinPlaceException("No powergrid_spacing directive or command line argument"); + } + + int totalPitches = (int) (cellHeight / wirePitch); + + if( pinType.equals( DirectiveConstants.PINTYPE_PITCHED ) ) { + portFactory = new APDefaultPortDefFactory(); + } + else if( pinType.equals( DirectiveConstants.PINTYPE_INPLACE ) ) { + portFactory = new APInPlacePortDefFactory(); + } + else + throw new PinPlaceException("Invalid pintype directive or command line argument"); + + PinGlobal global = new PinGlobal( getLayerFloatDirective(cell, pinLayer, DirectiveConstants.LAYER_WIREPITCH ), + getLayerFloatDirective(cell, pinLayer, DirectiveConstants.LAYER_WIREWIDTH ), + getLayerFloatDirective(cell, pinLayer, DirectiveConstants.LAYER_WIRESPACING ) ); + + CellInterfacePortCollector collector = + new CellInterfacePortCollector(portFactory, + pinLayer, + pgGNDnet+"|"+pgVddnet, + "_?[Rr][Ee][Ss][Ee][Tt]", + pgWidth, + false, + false, + true); + + List ports = getPorts(null, collector); + List pitchedPorts = new LinkedList(); + CollectionUtils.addAll(pitchedPorts, + new FilteringIterator(ports.iterator(), new UnaryPredicate() { + public boolean evaluate(Object o) { + return ( ! ( o instanceof APInPlaceNodeDef || o instanceof APInPlaceChannelDef ) ); + } + } ) + ); + + APLocale[] locales = new APLocale[2]; + for(int i=0; i"); + + try { + castParser.startPrsNodeExpression(); + } catch (RecognitionException e) { + System.out.println(e); + return null; + } catch (TokenStreamException e) { + System.out.println(e); + return null; + } + + final AST port = castParser.getAST(); + + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + + Value v = null; + + try { + v = treeParser.expr(port, env, false); + } catch (RecognitionException e) {} + + return v; + } + + private Pair getInstance(String value, Environment env) { + final Value v = getValue(value, env); + if (v instanceof InstanceValue) { + return new Pair(((InstanceValue) v).getCell(), + ((InstanceValue) v).getInstanceName()); + } else { + return null; + } + } + + private HierName resolveInstance(String value, Environment env) { + Pair pair = getInstance(value,env); + if(pair == null) + return null; + CellInterface cell = (CellInterface) pair.getFirst(); + HierName instanceName = (HierName) pair.getSecond(); + return instanceName; + } + + private HierName resolveInstances(String value, Environment env) { + final Value v = getValue(value, env); + if (v instanceof ArrayValue) { + final ArrayValue av = (ArrayValue) v; + for (Iterator i = av.getIterator(); i.hasNext(); ) { + if (i.next() instanceof InstanceValue) + return v.getInstanceName(); + else + return null; + } + } + return null; + } + + private HierName resolveChannel(String value, Environment env) { + Pair pair = getInstance(value,env); + if(pair == null) + return null; + CellInterface cell = (CellInterface) pair.getFirst(); + HierName instanceName = (HierName) pair.getSecond(); + if(cell.isChannel()) + return instanceName; + else + return null; + } + + private InstanceCallback() { + } + + public Object resolve(String type, String value, Environment env) { + Object ret = null; + if (type.equals(DirectiveConstants.CHANNEL_TYPE)) { + ret = resolveChannel(value, env); + } + else if(type.equals(DirectiveConstants.INSTANCE_TYPE)) { + ret = resolveInstance(value, env); + } + else if(type.equals(DirectiveConstants.ARRAYED_INSTANCE_TYPE)) { + ret = resolveInstances(value, env); + } + return ret; + } + + public static InstanceCallback getInstance() { + if (singleton == null) singleton = new InstanceCallback(); + return singleton; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodes.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodes.java new file mode 100644 index 0000000000..94a5bc890f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodes.java @@ -0,0 +1,51 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.layout; + +import java.lang.String; +import java.lang.Exception; + +import java.util.SortedSet; +import java.util.List; + +import com.avlsi.file.common.HierName; + + +/** + Interface used to get sets of lvs nodes for cells. + */ +public interface LVSNodes { + + class LVSNodesException extends Exception { + public LVSNodesException( final Exception e ) { + super( e ); + } + + public LVSNodesException( final String str ) { + super( str ); + } + + public LVSNodesException( final String str, + final Exception e ) { + super( str, e ); + } + } + + interface Info { + SortedSet getLVSNodes(); + SortedSet getTopLevelLVSNodes(); + List getInstanceLVSNodesConnections( final HierName instanceName ); + } + + Info getLVSNodesSetsForCell( final String fullyQualifiedCellName ) throws LVSNodesException; + + SortedSet getLVSNodesForCell( final String fullyQualifiedCellName ) throws LVSNodesException; + + SortedSet getTopLevelLVSNodesForCell( final String fullyQualifiedCellName ) throws LVSNodesException; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForExtract.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForExtract.java new file mode 100644 index 0000000000..93f14bddb0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForExtract.java @@ -0,0 +1,322 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.layout; + +import java.lang.String; +import java.lang.Exception; + +import java.util.Map; +import java.util.SortedSet; +import java.util.HashMap; +import java.util.TreeSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Collections; +import java.util.ArrayList; +import java.util.List; + +import com.avlsi.util.container.Pair; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; + +import com.avlsi.layout.LVSNodes; + +/** + Class used to get sets of lvs nodes for cells. + */ +public class LVSNodesForExtract implements LVSNodes { + + /** + Implements a stack frame for the stack + used in getLVSNodesSetsForCell. + + */ + private static class Frame { + private final String mCellName; + private final HierName mInstanceName; + private final CadenceInfo mCellInfo; + private final Iterator mSubCellIter; + private final SortedSet mLVSNodes; + private final Map mInstanceLVSNodesConnections; + + public Frame( final String cellName, + final HierName instanceName, + final CadenceInfo cellInfo ) { + mCellName = cellName; + mInstanceName = instanceName; + mCellInfo = cellInfo; + mSubCellIter = cellInfo.getSubcellPairIterator(); + mLVSNodes = new TreeSet(); + mInstanceLVSNodesConnections = new HashMap(); + } + + public String getCellName() { + return mCellName; + } + + public CadenceInfo getCellInfo() { + return mCellInfo; + } + + public Iterator getSubcellPairIterator() { + return mSubCellIter; + } + + public SortedSet getLVSNodes() { + return mLVSNodes; + } + + public HierName getInstanceName() { + return mInstanceName; + } + + public Map getInstanceLVSNodesConnections() { + return mInstanceLVSNodesConnections; + } + + } + + private static class InfoImpl implements LVSNodes.Info { + private final SortedSet mLVSNodes; + private final SortedSet mTopLevelLVSNodes; + private final Map mInstanceLVSNodesConnections; + + public InfoImpl( final SortedSet lvsNodes, + final SortedSet topLevelLVSNodes, + final Map instanceLVSNodesConnections ) { + mLVSNodes = lvsNodes; + mTopLevelLVSNodes = topLevelLVSNodes; + mInstanceLVSNodesConnections = instanceLVSNodesConnections; + } + + public SortedSet getLVSNodes() { + return mLVSNodes; + } + + public SortedSet getTopLevelLVSNodes() { + return mTopLevelLVSNodes; + } + + public List getInstanceLVSNodesConnections( final HierName instanceName ) { + return ( List ) mInstanceLVSNodesConnections.get( instanceName ); + } + + } + + + private final Map mLVSNodesMap; + private final CastFileParser mCastParser; + private final Cadencize mCadencizer; + + private final SortedSet mEmptySortedSet; + private final Info mEmptyInfo; + + + public LVSNodesForExtract( final CastFileParser castParser, + final Cadencize cadencizer ) { + mCastParser = castParser; + mCadencizer = cadencizer; + mLVSNodesMap = new HashMap(); + mEmptySortedSet = new TreeSet(); + mEmptyInfo = new InfoImpl( mEmptySortedSet, mEmptySortedSet, Collections.EMPTY_MAP ); + } + + public Info getLVSNodesSetsForCell( final String fullyQualifiedCellName ) + throws LVSNodes.LVSNodesException { + final Info existingLVSNodesInfo = + ( Info ) mLVSNodesMap.get( fullyQualifiedCellName ); + + if ( existingLVSNodesInfo == null ) { + + try { + + final CellInterface cell = + mCastParser.getFullyQualifiedCell( fullyQualifiedCellName ); + final CadenceInfo cellInfo = mCadencizer.convert( cell ); + final LinkedList stack = new LinkedList(); + final Frame topFrame = new Frame( fullyQualifiedCellName, + null, + cellInfo ); + stack.addFirst( topFrame ); + + while ( stack.size() > 0 ) { + final Frame currFrame = ( Frame ) stack.getFirst(); + final CadenceInfo currInfo = currFrame.getCellInfo(); + final Iterator subcellPairIter = currFrame.getSubcellPairIterator(); + final SortedSet lvsNodes = currFrame.getLVSNodes(); + final Map instanceLVSNodesConnections = + currFrame.getInstanceLVSNodesConnections(); + + if ( subcellPairIter.hasNext() ) { + final Pair subcellPair = ( Pair ) subcellPairIter.next(); + final HierName instanceName = ( HierName ) subcellPair.getFirst(); + final CadenceInfo masterInfo = ( CadenceInfo ) subcellPair.getSecond(); + + final String masterCellName = masterInfo.getType(); + + final Info existingLVSNodesInfoForMaster = + ( Info ) mLVSNodesMap.get( masterCellName ); + + + + if ( existingLVSNodesInfoForMaster == null ) { + final Frame newFrame = new Frame( masterCellName, + instanceName, + masterInfo ); + stack.addFirst( newFrame ); + } + else { + final SortedSet lvsNodesForMaster = + existingLVSNodesInfoForMaster.getLVSNodes(); + if ( lvsNodesForMaster.size() > 0 ) { + final Iterator subCellLVSNodes = lvsNodesForMaster.iterator(); + final List lvsNodesConnectionPairs = + new ArrayList( lvsNodesForMaster.size() ); + while ( subCellLVSNodes.hasNext() ) { + final HierName subCellLVSNode = + ( HierName ) subCellLVSNodes.next(); + final HierName lvsNode = + HierName.append( instanceName, subCellLVSNode ); + lvsNodes.add( lvsNode ); + final Pair lvsNodeConnectionPair = + new Pair( lvsNode, subCellLVSNode ); + lvsNodesConnectionPairs.add( lvsNodeConnectionPair ); + } + instanceLVSNodesConnections.put( instanceName, + lvsNodesConnectionPairs ); + } + } + } + else { + final String currCellName = + currFrame.getCellName(); + final CellInterface currCell = + mCastParser.getFullyQualifiedCell( currCellName ); + final List lvsNodesFromDirective = ( List ) + DirectiveUtils.getTopLevelDirective( currCell, + DirectiveConstants.LVS_NODES ); + + final SortedSet topLevelLVSNodes; + if ( lvsNodesFromDirective != null ) { + topLevelLVSNodes = new TreeSet(); + for ( int i = 0 ; i < lvsNodesFromDirective.size() ; ++i ) { + final String lvsNodeString = + ( String ) lvsNodesFromDirective.get(i); + + final HierName lvsNode = + HierName.makeHierName( lvsNodeString, '.' ); + + final Boolean isInPortList = + ( Boolean ) currInfo.getPortNodes().getValue( lvsNode ); + + if ( isInPortList == null ) { + topLevelLVSNodes.add( lvsNode ); + lvsNodes.add( lvsNode ); + } + else { + final String errorString = "\"" + + lvsNodeString + + "\" is in the port list of \"" + + currCellName + + "\", thus it can not be in the \"" + + DirectiveConstants.LVS_NODES + + "\" directive."; + throw new LVSNodes.LVSNodesException( errorString ); + } + + } + } + else { + topLevelLVSNodes = mEmptySortedSet; + } + if ( lvsNodes.size() == 0 ) { + mLVSNodesMap.put( currCellName, mEmptyInfo ); + } + else { + final Info newInfo; + if ( instanceLVSNodesConnections.size() > 0 ) { + newInfo = + new InfoImpl( lvsNodes, + topLevelLVSNodes, + instanceLVSNodesConnections ); + + } + else { + newInfo = + new InfoImpl( lvsNodes, + topLevelLVSNodes, + Collections.EMPTY_MAP ); + } + mLVSNodesMap.put( currCellName, + newInfo ); + } + + final HierName currInstanceName = currFrame.getInstanceName(); + stack.removeFirst(); + + if ( stack.size() > 0 ) { + + final Frame newCurrFrame = ( Frame ) stack.getFirst(); + + final SortedSet newCurrFrameLVSNodes = newCurrFrame.getLVSNodes(); + + final Iterator lvsNodesIter = lvsNodes.iterator(); + + while ( lvsNodesIter.hasNext() ) { + final HierName lvsNode = ( HierName ) lvsNodesIter.next(); + + final HierName newLVSNode = HierName.append( currInstanceName, + lvsNode ); + + newCurrFrameLVSNodes.add( newLVSNode ); + + } + } + } + } + final Info ret = ( Info ) mLVSNodesMap.get( fullyQualifiedCellName ); + assert ret != null; + return ret; + } + catch ( InvalidHierNameException e ) { + throw new LVSNodes.LVSNodesException( e ); + } + catch ( CastSemanticException e ) { + throw new LVSNodes.LVSNodesException( e ); + } + } + else { + return existingLVSNodesInfo; + } + } + + public SortedSet getLVSNodesForCell( final String fullyQualifiedCellName ) + throws LVSNodes.LVSNodesException { + return ( SortedSet ) getLVSNodesSetsForCell( fullyQualifiedCellName ).getLVSNodes(); + } + + public SortedSet getTopLevelLVSNodesForCell( final String fullyQualifiedCellName ) + throws LVSNodes.LVSNodesException { + return ( SortedSet ) getLVSNodesSetsForCell( fullyQualifiedCellName ).getTopLevelLVSNodes(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForHierarchy.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForHierarchy.java new file mode 100644 index 0000000000..fee34faa16 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LVSNodesForHierarchy.java @@ -0,0 +1,312 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.layout; + +import java.lang.String; +import java.lang.Exception; + +import java.util.Map; +import java.util.SortedSet; +import java.util.HashMap; +import java.util.TreeSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Collections; +import java.util.ArrayList; +import java.util.List; + +import com.avlsi.util.container.Pair; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; + +import com.avlsi.layout.LVSNodes; + + +/** + Class used to get sets of lvs nodes for cells. + */ +public class LVSNodesForHierarchy implements LVSNodes { + + /** + Implements a stack frame for the stack + used in getLVSNodesSetsForCell. + + */ + private static class Frame { + private final String mCellName; + private final HierName mInstanceName; + private final CadenceInfo mCellInfo; + private final Iterator mSubCellIter; + private final SortedSet mLVSNodes; + private final Map mInstanceLVSNodesConnections; + + public Frame( final String cellName, + final HierName instanceName, + final CadenceInfo cellInfo ) { + mCellName = cellName; + mInstanceName = instanceName; + mCellInfo = cellInfo; + mSubCellIter = cellInfo.getSubcellPairIterator(); + mLVSNodes = new TreeSet(); + mInstanceLVSNodesConnections = new HashMap(); + } + + public String getCellName() { + return mCellName; + } + + public CadenceInfo getCellInfo() { + return mCellInfo; + } + + public Iterator getSubcellPairIterator() { + return mSubCellIter; + } + + public SortedSet getLVSNodes() { + return mLVSNodes; + } + + public HierName getInstanceName() { + return mInstanceName; + } + + public Map getInstanceLVSNodesConnections() { + return mInstanceLVSNodesConnections; + } + + } + + private static class InfoImpl implements LVSNodes.Info { + private final SortedSet mLVSNodes; + private final SortedSet mTopLevelLVSNodes; + private final Map mInstanceLVSNodesConnections; + + public InfoImpl( final SortedSet lvsNodes, + final SortedSet topLevelLVSNodes, + final Map instanceLVSNodesConnections ) { + mLVSNodes = lvsNodes; + mTopLevelLVSNodes = topLevelLVSNodes; + mInstanceLVSNodesConnections = instanceLVSNodesConnections; + } + + public SortedSet getLVSNodes() { + return mLVSNodes; + } + + public SortedSet getTopLevelLVSNodes() { + return mTopLevelLVSNodes; + } + + public List getInstanceLVSNodesConnections( final HierName instanceName ) { + return ( List ) mInstanceLVSNodesConnections.get( instanceName ); + } + + } + + + private final Map mLVSNodesMap; + private final CastFileParser mCastParser; + private final Cadencize mCadencizer; + + private final SortedSet mEmptySortedSet; + private final Info mEmptyInfo; + + + public LVSNodesForHierarchy( final CastFileParser castParser, + final Cadencize cadencizer ) { + mCastParser = castParser; + mCadencizer = cadencizer; + mLVSNodesMap = new HashMap(); + mEmptySortedSet = new TreeSet(); + mEmptyInfo = new InfoImpl( mEmptySortedSet, mEmptySortedSet, Collections.EMPTY_MAP ); + } + + public Info getLVSNodesSetsForCell( final String fullyQualifiedCellName ) + throws LVSNodes.LVSNodesException { + final Info existingLVSNodesInfo = + ( Info ) mLVSNodesMap.get( fullyQualifiedCellName ); + + if ( existingLVSNodesInfo == null ) { + + try { + + final CellInterface cell = + mCastParser.getFullyQualifiedCell( fullyQualifiedCellName ); + final CadenceInfo cellInfo = mCadencizer.convert( cell ); + final LinkedList stack = new LinkedList(); + final Frame topFrame = new Frame( fullyQualifiedCellName, + null, + cellInfo ); + stack.addFirst( topFrame ); + + while ( stack.size() > 0 ) { + final Frame currFrame = ( Frame ) stack.getFirst(); + final CadenceInfo currInfo = currFrame.getCellInfo(); + final Iterator subcellPairIter = currFrame.getSubcellPairIterator(); + final SortedSet lvsNodes = currFrame.getLVSNodes(); + final Map instanceLVSNodesConnections = + currFrame.getInstanceLVSNodesConnections(); + + if ( subcellPairIter.hasNext() ) { + final Pair subcellPair = ( Pair ) subcellPairIter.next(); + final HierName instanceName = ( HierName ) subcellPair.getFirst(); + final CadenceInfo masterInfo = ( CadenceInfo ) subcellPair.getSecond(); + + final String masterCellName = masterInfo.getType(); + + final Info existingLVSNodesInfoForMaster = + ( Info ) mLVSNodesMap.get( masterCellName ); + + + + if ( existingLVSNodesInfoForMaster == null ) { + final Frame newFrame = new Frame( masterCellName, + instanceName, + masterInfo ); + stack.addFirst( newFrame ); + } + else { + final SortedSet lvsNodesForMaster = + existingLVSNodesInfoForMaster.getLVSNodes(); + if ( lvsNodesForMaster.size() > 0 ) { + final Iterator subCellLVSNodes = lvsNodesForMaster.iterator(); + final List lvsNodesConnectionPairs = + new ArrayList( lvsNodesForMaster.size() ); + while ( subCellLVSNodes.hasNext() ) { + final HierName subCellLVSNode = + ( HierName ) subCellLVSNodes.next(); + final HierName lvsNode = + HierName.append( instanceName, subCellLVSNode ); + final Pair lvsNodeConnectionPair = + new Pair( lvsNode, subCellLVSNode ); + lvsNodesConnectionPairs.add( lvsNodeConnectionPair ); + } + instanceLVSNodesConnections.put( instanceName, + lvsNodesConnectionPairs ); + } + } + } + else { + final String currCellName = + currFrame.getCellName(); + final CellInterface currCell = + mCastParser.getFullyQualifiedCell( currCellName ); + final List lvsNodesFromDirective = ( List ) + DirectiveUtils.getTopLevelDirective( currCell, + DirectiveConstants.LVS_NODES ); + + final SortedSet topLevelLVSNodes; + if ( lvsNodesFromDirective != null ) { + topLevelLVSNodes = new TreeSet(); + for ( int i = 0 ; i < lvsNodesFromDirective.size() ; ++i ) { + final String lvsNodeString = + ( String ) lvsNodesFromDirective.get(i); + + final HierName lvsNode = + HierName.makeHierName( lvsNodeString, '.' ); + + final Boolean isInPortList = + ( Boolean ) currInfo.getPortNodes().getValue( lvsNode ); + + if ( isInPortList == null ) { + topLevelLVSNodes.add( lvsNode ); + lvsNodes.add( lvsNode ); + } + else { + final String errorString = "\"" + + lvsNodeString + + "\" is in the port list of \"" + + currCellName + + "\", thus it can not be in the \"" + + DirectiveConstants.LVS_NODES + + "\" directive."; + throw new LVSNodes.LVSNodesException( errorString ); + } + + } + } + else { + topLevelLVSNodes = mEmptySortedSet; + } + if ( ( lvsNodes.size() == 0 ) && + ( instanceLVSNodesConnections.size() == 0 ) ) { + mLVSNodesMap.put( currCellName, mEmptyInfo ); + } + else { + final SortedSet myLVSNodes; + if ( lvsNodes.size() == 0 ) { + myLVSNodes = mEmptySortedSet; + } + else { + myLVSNodes = lvsNodes; + } + + final Info newInfo; + if ( instanceLVSNodesConnections.size() > 0 ) { + newInfo = + new InfoImpl( myLVSNodes, + topLevelLVSNodes, + instanceLVSNodesConnections ); + + } + else { + newInfo = + new InfoImpl( myLVSNodes, + topLevelLVSNodes, + Collections.EMPTY_MAP ); + } + mLVSNodesMap.put( currCellName, + newInfo ); + } + + final HierName currInstanceName = currFrame.getInstanceName(); + stack.removeFirst(); + + } + } + final Info ret = ( Info ) mLVSNodesMap.get( fullyQualifiedCellName ); + assert ret != null; + return ret; + } + catch ( InvalidHierNameException e ) { + throw new LVSNodes.LVSNodesException( e ); + } + catch ( CastSemanticException e ) { + throw new LVSNodes.LVSNodesException( e ); + } + } + else { + return existingLVSNodesInfo; + } + } + + public SortedSet getLVSNodesForCell( final String fullyQualifiedCellName ) + throws LVSNodes.LVSNodesException { + return ( SortedSet ) getLVSNodesSetsForCell( fullyQualifiedCellName ).getLVSNodes(); + } + + public SortedSet getTopLevelLVSNodesForCell( final String fullyQualifiedCellName ) + throws LVSNodes.LVSNodesException { + return ( SortedSet ) getLVSNodesSetsForCell( fullyQualifiedCellName ).getTopLevelLVSNodes(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LayerCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LayerCallback.java new file mode 100644 index 0000000000..d0cb4005d9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/LayerCallback.java @@ -0,0 +1,67 @@ +package com.avlsi.layout; + +import java.io.StringReader; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.util.container.Pair; +import com.avlsi.cast.impl.Environment; + +import java.util.StringTokenizer; +import java.util.NoSuchElementException; + + +public class LayerCallback implements DirectiveCallback { + + private class LayerParseException extends Exception { + public LayerParseException() { + super("Error parsing Layer" ); + } + } + + private static LayerCallback singleton = null; + + //not worth a .g file - must be of form " ( 'layer' 'purpose' ) " + private Pair resolveLayer(String value, Environment env) { + final String str1; + final String str2; + + StringTokenizer st = new StringTokenizer(value, " \n\t'" ); + try { + if ( st.nextToken().equals("(") ) { + str1 = st.nextToken(); + str2 = st.nextToken(); + if( !st.nextToken().equals(")") ) + throw new LayerParseException(); + } + else + throw new LayerParseException(); + } + catch( LayerParseException e) { + System.out.println(e); + return null; + } + catch( NoSuchElementException e) { + System.out.println(e); + return null; + } + + return new Pair(str1, str2); + } + + private LayerCallback() { + } + + public Object resolve(String type, String value, Environment env) { + Object ret = null; + if (type.equals(DirectiveConstants.LAYER_TYPE)) { + ret = resolveLayer(value, env); + } + return ret; + } + + public static LayerCallback getInstance() { + if (singleton == null) singleton = new LayerCallback(); + return singleton; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/MapUtils.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/MapUtils.java new file mode 100644 index 0000000000..aaa26bed6d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/MapUtils.java @@ -0,0 +1,40 @@ +package com.avlsi.layout; + +import java.util.Comparator; +import java.util.Collection; +import java.util.Collections; +import java.util.TreeMap; +import java.util.SortedMap; +import java.util.Map; +import java.util.Iterator; +import java.util.LinkedList; +import com.avlsi.util.container.Pair; + +public class MapUtils { + + public static Collection getKeyValuePairs (Map map) { + LinkedList pairs = new LinkedList(); + for(Iterator i=map.keySet().iterator(); i.hasNext(); ) { + Object key = i.next(); + pairs.add( new Pair(key, map.get(key) ) ); + } + return pairs; + } + + public static SortedMap getImmutableValueSortedMap(final Map map, final Comparator comp) { + SortedMap newMap = new TreeMap(new Comparator() { + public int compare(Object a, Object b) { + //never equals - put every one + int diff = comp.compare( map.get(a), map.get(b) ); + if(diff == 0) + return 1; + else + return diff; + } + } ); + + newMap.putAll(map); + return Collections.unmodifiableSortedMap( newMap ); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinGlobal.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinGlobal.java new file mode 100644 index 0000000000..daae7d9e15 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinGlobal.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout; + +public class PinGlobal { + + public float pitch; + public float width; + public float spacing; + + public PinGlobal() { + } + + public PinGlobal(float pitch, float width, float spacing) { + this.pitch = pitch; + this.width = width; + this.spacing = spacing; + } + + public String toSkillString() { + return "( defvar PinGlobalWirePitch " + pitch + " )\n" + + "( defvar PinGlobalWireWidth " + width + " )\n" + + "( defvar PinGlobalWireSpacing " + spacing + " )\n"; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinPlaceException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinPlaceException.java new file mode 100644 index 0000000000..4c6fb9f7c5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/PinPlaceException.java @@ -0,0 +1,15 @@ +package com.avlsi.layout; + +import com.avlsi.layout.CellProcessorException; + +public class PinPlaceException extends CellProcessorException { + + public PinPlaceException(final String str) { + super(str); + } + + + public PinPlaceException(final Exception e) { + super(e); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillDirectiveEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillDirectiveEmitter.java new file mode 100644 index 0000000000..17be69294d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillDirectiveEmitter.java @@ -0,0 +1,200 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.text.MessageFormat; + +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveEmitter; +import com.avlsi.file.common.HierName; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +public class SkillDirectiveEmitter implements DirectiveEmitter { + + public String emit(String block,String type,Object val) { + if(val == null) return "nil"; + final boolean isArray = type.endsWith("[]"); + final String baseType = isArray ? type.replaceFirst("\\[\\]","") : type; + if(isArray) { + final Object[] array; + if(val instanceof Object[]) { + array = (Object[]) val; + } else if(val instanceof List) { + array = ((List)val).toArray(); + } else { + throw new RuntimeException("directive value + " + val.toString() + " of type " + type + " is not a list or array" ); + } + final StringBuffer ret = new StringBuffer(); + ret.append( "( list " ); + + for ( int i = 0; i < array.length ; ++i ) { + final String elementString = emit(block,baseType,array[i]); + ret.append( elementString + " " ); + } + ret.append( ")" ); + + return ret.toString(); + } + else { + SkillStringInterface SSI = + (SkillStringInterface) ssiMap.get(baseType); + if(SSI == null) { + SSI = stringSkillStringInterface; + } + return SSI.getString(val); + } + } + + private static MessageFormat pairForm = new MessageFormat("( list {0} {1} )" ); + private static MessageFormat stringForm = new MessageFormat("\"{0}\"" ); + private static CDLNameInterface renamer = new CadenceNameInterface(true); + + + public static SkillStringInterface defaultSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + return o.toString(); + } + }; + + public static SkillStringInterface booleanSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + Boolean b = (Boolean)o; + if( b.booleanValue() ) + return "t"; + else + return "nil"; + } + }; + + public static SkillStringInterface stringSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + final String s = o.toString(); + final StringBuffer buf = new StringBuffer(); + for (int i = 0; i < s.length(); ++i) { + final char c = s.charAt(i); + switch(c) { + case '\n': buf.append("\\n"); break; + case '\t': buf.append("\\t"); break; + case '\b': buf.append("\\b"); break; + case '\r': buf.append("\\r"); break; + case '\f': buf.append("\\f"); break; + case '\\': buf.append("\\\\"); break; + case '"' : buf.append("\\\""); break; + default: + if (c > '\177') { + throw new RuntimeException("Cannot translate 0x" + + Integer.toString(c, 16) + " to SKILL"); + } else if (c >= ' ' && c <= '~') { + buf.append(c); + } else { + buf.append('\\'); + if (c < '\010') buf.append('0'); + if (c < '\100') buf.append('0'); + buf.append(Integer.toOctalString(c)); + } + break; + } + } + return stringForm.format( new Object[] { buf.toString() } ); + } + }; + + public static SkillStringInterface nodeSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + final String name = ((HierName)o).getCadenceString(); + String cadenceName; + try { + cadenceName = renamer.renameNode(name); + } catch (CDLRenameException e) { + throw new RuntimeException(e); + } + + return stringForm.format( new Object[] { cadenceName } ); + } + }; + + public static SkillStringInterface wideChannelSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + final String name = (String) o; + String cadenceName; + try { + cadenceName = renamer.renameNode(name); + } catch (CDLRenameException e) { + throw new RuntimeException(e); + } + + return stringForm.format( new Object[] { cadenceName } ); + } + }; + + public static SkillStringInterface instanceSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + final String name = ((HierName)o).getCadenceString(); + String cadenceName; + try { + cadenceName = renamer.renameSubCellInstance(name); + } catch (CDLRenameException e) { + throw new RuntimeException(e); + } + return stringForm.format( new Object[] { cadenceName } ); + } + }; + + public static SkillStringInterface halfOpSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + Pair pair = (Pair)o; + final String direction; + final HierName name = (HierName)pair.getFirst(); + + if( pair.getSecond() == null ) + direction = "+-"; + else if( ((Boolean)pair.getSecond()).booleanValue() ) + direction = "+"; + else + direction = "-"; + + return pairForm.format( new Object[] { stringForm.format( new Object[] { name.getCadenceString() } ), + stringForm.format( new Object[] { direction } ) } ); + } + }; + + public static SkillStringInterface layerSkillStringInterface = new SkillStringInterface() { + public String getString(Object o) { + Pair pair = (Pair)o; + return pairForm.format( new Object[] { stringForm.format( new Object[] { pair.getFirst().toString() } ), + stringForm.format( new Object[] { pair.getSecond().toString() } ) } ); + } + }; + + + public static Map ssiMap = + new HashMap( CollectionUtils.mapify(new Object[] { + DirectiveConstants.INT_TYPE, defaultSkillStringInterface, + DirectiveConstants.FLOAT_TYPE, defaultSkillStringInterface, + DirectiveConstants.DOUBLE_TYPE, defaultSkillStringInterface, + DirectiveConstants.BOOLEAN_TYPE, booleanSkillStringInterface, + DirectiveConstants.STRING_TYPE, stringSkillStringInterface, + DirectiveConstants.NODE_TYPE, nodeSkillStringInterface, + DirectiveConstants.UNCHECKED_NODE_TYPE, nodeSkillStringInterface, + DirectiveConstants.DEEP_NODE_TYPE, nodeSkillStringInterface, + DirectiveConstants.HALFOP_TYPE, halfOpSkillStringInterface, + DirectiveConstants.UNCHECKED_HALFOP_TYPE, halfOpSkillStringInterface, + DirectiveConstants.DEEP_HALFOP_TYPE, halfOpSkillStringInterface, + DirectiveConstants.CHANNEL_TYPE, nodeSkillStringInterface, + DirectiveConstants.WIDE_CHANNEL_TYPE, wideChannelSkillStringInterface, + DirectiveConstants.INSTANCE_TYPE, instanceSkillStringInterface, + DirectiveConstants.LAYER_TYPE, layerSkillStringInterface } ) ); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillStringInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillStringInterface.java new file mode 100644 index 0000000000..96fc055227 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/SkillStringInterface.java @@ -0,0 +1,11 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.layout; + +public interface SkillStringInterface { + String getString(Object o); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/AssuraBindRulTableEmitterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/AssuraBindRulTableEmitterFactory.java new file mode 100644 index 0000000000..62270b696d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/AssuraBindRulTableEmitterFactory.java @@ -0,0 +1,226 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + + +import java.text.MessageFormat; + +import java.io.Reader; +import java.io.Writer; +import java.io.OutputStreamWriter; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.File; +import java.io.Reader; +import java.io.InputStreamReader; +import java.io.FileInputStream; + +import java.util.Set; +import java.util.HashSet; + +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; +import com.avlsi.layout.gdsII.CachingTableEmitter; + +public class AssuraBindRulTableEmitterFactory implements TableEmitterFactoryInterface { + + + + + private static class Emitter implements TableEmitterInterface { + + private static final String cellMappingChar = "C"; + private static final String nodeMappingChar = "N"; + private static final String instanceMappingChar = "I"; + + private static final String mappingOutputFormatStr = + "{0} {1} {2}\n"; + + private final Writer mWriter; + private final StringBuffer mAccum; + private final MessageFormat mMappingOutputFormatter; + + private final Set mTranslatedNodeNames; + private final boolean mBindAllNodes; + + public Emitter( final Writer writer, final boolean bindAllNodes ) { + mWriter = writer; + mAccum = new StringBuffer(); + mMappingOutputFormatter = new MessageFormat( mappingOutputFormatStr ); + + mTranslatedNodeNames = new HashSet(); + mBindAllNodes = bindAllNodes ; + } + + private void emitName( final String mappingType, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + emitName( mappingType, cadenceName, gdsIIName, false ); + } + + private void emitName( final String mappingType, + final String cadenceName, + final String gdsIIName, + final boolean bindAll ) + throws TableEmitterException { + if ( bindAll || ! cadenceName.equals( gdsIIName ) ) { + final Object[] mappingOutputParams = { + mappingType, + cadenceName, + gdsIIName }; + + mMappingOutputFormatter.format( mappingOutputParams, + mAccum, + null ); + try { + mWriter.write( mAccum.toString() ); + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to emit mapping: " + + cadenceName + "=" + gdsIIName + ".", + e ); + } + mAccum.delete( 0, mAccum.length() ); + } + } + + public boolean haveCellName( final String castName ) { + return false; + } + + public void realEmitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + emitName( cellMappingChar, cadenceName, gdsIIName ); + } + + public void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) { + } + + public boolean haveNodeName( final String castName ) { + return mTranslatedNodeNames.contains( castName ); + } + + public void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + if ( ! ( haveNodeName( castName ) ) ) { + emitName( nodeMappingChar, cadenceName, gdsIIName, + mBindAllNodes ); + mTranslatedNodeNames.add( castName ); + } + } + + public boolean haveInstanceName( final String castName ) { + return false; + } + + public void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + emitName( instanceMappingChar, cadenceName, gdsIIName ); + } + + public void close() throws TableEmitterException { + try { + mWriter.write( '\n' ); + mWriter.flush(); + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to flush the file.", e ); + } + } + + } + + + private final boolean mBindAllNodes; + private final Writer mWriter; + + public AssuraBindRulTableEmitterFactory( final File outputFile, + final File header ) + throws TableEmitterException { + this( outputFile, header, false ); + } + + public AssuraBindRulTableEmitterFactory( final File outputFile, + final File header, + final boolean bindAllNodes ) + throws TableEmitterException { + mBindAllNodes = bindAllNodes; + try { + final FileInputStream inputStream = new FileInputStream( header ); + final Reader reader = new InputStreamReader ( inputStream, "UTF-8" ); + + try { + final OutputStream outputStream = new FileOutputStream( outputFile ); + final Writer writer = new OutputStreamWriter( outputStream ); + + try { + int currCharInt ; + do { + currCharInt = reader.read(); + if ( currCharInt > 0 ) { + writer.write( ( char ) currCharInt ); + } + } while ( currCharInt >= 0 ) ; + writer.write( '\n' ); + writer.write( '\n' ); + + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to copy header.", e ); + } + mWriter = writer; + + } + catch ( FileNotFoundException e ) { + throw new TableEmitterException( "Unable to open " + + outputFile.toString() + + ".", + e ); + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to open " + + outputFile.toString() + + ".", + e ); + } + } + catch ( FileNotFoundException e ) { + throw new TableEmitterException( "Unable to open " + + header.toString() + + ".", + e ); + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to open " + + header.toString() + + ".", + e ); + } + } + + + public TableEmitterInterface getTableEmitter( final String castCellName, + final String cadenceCellName, + final String gdsIICellName ) + throws TableEmitterException { + final Emitter emitter = new Emitter( mWriter, mBindAllNodes ); + + emitter.realEmitCellName( castCellName, cadenceCellName, gdsIICellName ); + return emitter; + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/CachingTableEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/CachingTableEmitter.java new file mode 100644 index 0000000000..db37aba00c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/CachingTableEmitter.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + + +import java.util.Set; +import java.util.HashSet; + +import com.avlsi.layout.gdsII.TableEmitterInterface ; + + + +public class CachingTableEmitter implements TableEmitterInterface { + + private final Set m_EmittedNodeNames; + private final Set m_EmittedCellNames; + private final Set m_EmittedInstanceNames; + + private final TableEmitterInterface m_Chained; + + public CachingTableEmitter( TableEmitterInterface chained ) { + m_Chained = chained; + m_EmittedNodeNames = new HashSet(); + m_EmittedCellNames = new HashSet(); + m_EmittedInstanceNames = new HashSet(); + } + + public boolean haveCellName( final String castName ) { + return m_EmittedCellNames.contains( castName ); + } + + public void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + if ( m_EmittedCellNames.add( castName ) ) { + m_Chained.emitCellName( castName, cadenceName, gdsIIName ); + } + } + + public boolean haveNodeName( final String castName ) { + return m_EmittedNodeNames.contains( castName ); + } + + public void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + if ( m_EmittedNodeNames.add( castName ) ) { + m_Chained.emitNodeName( castName, cadenceName, gdsIIName ); + } + } + + public boolean haveInstanceName( final String castName ) { + return m_EmittedInstanceNames.contains( castName ); + } + + public void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + if ( m_EmittedInstanceNames.add( castName ) ) { + m_Chained.emitInstanceName( castName, cadenceName, gdsIIName ); + } + } + + public void close() throws TableEmitterException { + m_Chained.close(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/FilterInternalNodesTableEmitterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/FilterInternalNodesTableEmitterFactory.java new file mode 100644 index 0000000000..f52a84cf24 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/FilterInternalNodesTableEmitterFactory.java @@ -0,0 +1,119 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + +import java.lang.String; +import java.lang.Boolean; + +import java.util.Set; +import java.util.HashSet; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; + +public final class FilterInternalNodesTableEmitterFactory implements TableEmitterFactoryInterface { + + private static final class Emitter implements TableEmitterInterface { + private final CadenceInfo mCadenceInfo; + private final TableEmitterInterface mRealEmitter; + + private final Set mInternalNodes; + + public Emitter( final CadenceInfo cadenceInfo, + final TableEmitterInterface realEmitter ) { + mCadenceInfo = cadenceInfo; + mRealEmitter = realEmitter; + mInternalNodes = new HashSet(); + } + + public boolean haveCellName( final String castName ) { + return mRealEmitter.haveCellName( castName ); + } + + public void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + mRealEmitter.emitCellName( castName, cadenceName, gdsIIName ); + } + + public boolean haveNodeName( final String castName ) { + return mInternalNodes.contains( castName ) || mRealEmitter.haveNodeName( castName ); + } + public void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + assert mCadenceInfo != null; + if ( ! haveNodeName( castName ) ) { + try { + final Boolean inPortList = + ( Boolean ) mCadenceInfo.getPortNodes().getValue( HierName.makeHierName( castName, '.' ) ); + + if ( ( inPortList != null ) && + ( inPortList.booleanValue() ) ) { + mRealEmitter.emitNodeName( castName, cadenceName, gdsIIName ); + } + else { + mInternalNodes.add( castName ); + } + } + catch ( InvalidHierNameException e ) { + throw new TableEmitterException( "Unable to get HierName for \"" + castName + "\".", e ); + } + } + } + public boolean haveInstanceName( final String castName ) { + return mRealEmitter.haveInstanceName( castName ); + } + public void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + mRealEmitter.emitInstanceName( castName, cadenceName, gdsIIName ); + } + + public void close() throws TableEmitterException { + mRealEmitter.close(); + } + + + } + + private final Cadencize mCadencizer; + private final TableEmitterFactoryInterface mRealEmitterFactory; + + public FilterInternalNodesTableEmitterFactory( final Cadencize cadencizer, + final TableEmitterFactoryInterface realEmitterFactory ) { + mCadencizer = cadencizer; + mRealEmitterFactory = realEmitterFactory; + + } + + public TableEmitterInterface getTableEmitter( final String castCellName, + final String cadenceCellName, + final String gdsIICellName ) + throws TableEmitterException { + + final CadenceInfo cadenceInfo; + assert mCadencizer != null; + cadenceInfo = mCadencizer.getExistingCadenceInfo( castCellName ); + assert cadenceInfo != null; + + final TableEmitterInterface realEmitter = mRealEmitterFactory.getTableEmitter( castCellName, + cadenceCellName, + gdsIICellName ); + final TableEmitterInterface emitter = new Emitter( cadenceInfo, + realEmitter ); + return emitter; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GDSIILVSNodesHandler.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GDSIILVSNodesHandler.java new file mode 100644 index 0000000000..16ed56d505 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GDSIILVSNodesHandler.java @@ -0,0 +1,325 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + +import java.lang.String; +import java.lang.StringBuffer; + +import java.util.Set; +import java.util.Iterator; +import java.util.List; + +import java.text.MessageFormat; + +import java.io.IOException; +import java.io.Writer; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.FileOutputStream; +import java.io.File; + +import com.avlsi.util.container.Pair; + +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; + +import com.avlsi.file.cdl.parser.LVSNodesHandler; + +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; + +/** + * Writes SKILL table files for LVS nodes + * open's a file for each cell and writes + * SKILL API calls for cell LVS nodes, and instance LVS nodes + * see SKILL: + * sw/cad/external-tools-integration/cadence/virtuoso/skill/schematic/lvsnodes.il + **/ +public class GDSIILVSNodesHandler implements LVSNodesHandler { + + //0=TableVarName + //1=CellName + private static final String lvsNodesHeaderFormatStr = + "( setq {0} ( LVSNodesMakeEmptyLVSNodesTable \"{1}\" ) )\n"; + + private final MessageFormat mLVSNodesHeaderFormatter; + + //0=TableVarName + //1=lvsNodeGDSIIName + private static final String cellLVSNodeOutputFormatStr = + "( LVSNodesAddLVSNode {0} \"{1}\" )\n"; + private final MessageFormat mCellLVSNodeOutputFormatter; + + //0=TableVarName + //1=InstanceVarName + //2=instance name + private static final String lvsNodesInstanceOutputFormatStr = + "( setq \n" + + " {1}\n" + + " ( LVSNodesMakeLVSNodesInstance {0} \"{2}\" ) )\n"; + private final MessageFormat mLVSNodesInstanceOutputFormatter; + + //0=InstanceVarName + //1=Node + //2=NodeInInstance + private static final String lvsNodesInstanceConnectionPairOutputFormatStr = + "( LVSNodesMakeLVSNodesInstanceConnection\n" + + " {0}\n" + + " \"{1}\"\n" + + " \"{2}\" )\n"; + private final MessageFormat mLVSNodesInstanceConnnectionPairOutputFormatter; + + static final private class Emitter { + + private static final String currLVSNodesInstanceVarName = "GDSIILVSNodesCurrInstance"; + private final TableEmitterInterface mTableEmitter; + private final CDLNameInterface mCadenceNamesNI; + private final CDLNameInterface mGDSIINamesNI; + private final Writer mWriter; + private final MessageFormat mCellLVSNodeOutputFormatter; + private final MessageFormat mLVSNodesInstanceOutputFormatter; + private final MessageFormat mLVSNodesInstanceConnnectionPairOutputFormatter; + + private final String mTableVarName; + + private final StringBuffer mAccum; + + private final File mOutputFile; + + private void writeAccum() { + try { + mWriter.write( mAccum.toString() ); + mAccum.delete( 0, mAccum.length() ); + } + catch ( IOException e ) { + throw new RuntimeException( e ); + } + } + + public Emitter( final File outputFile, + final TableEmitterInterface tableEmitter, + final CDLNameInterface cadenceNamesNI, + final CDLNameInterface gdsIINamesNI, + final MessageFormat lvsNodesHeaderFormatter, + final MessageFormat cellLVSNodeOutputFormatter, + final MessageFormat lvsNodesInstanceOutputFormatter, + final MessageFormat lvsNodesInstanceConnnectionPairOutputFormatter, + final String tableVarName, + final String cellName ) { + try { + mOutputFile = outputFile; + mTableEmitter = tableEmitter; + final OutputStream outputStream = new FileOutputStream( mOutputFile ); + mWriter = new OutputStreamWriter( outputStream, "UTF-8" ); + mCadenceNamesNI = cadenceNamesNI; + mGDSIINamesNI = gdsIINamesNI; + mCellLVSNodeOutputFormatter = cellLVSNodeOutputFormatter; + mLVSNodesInstanceOutputFormatter = lvsNodesInstanceOutputFormatter; + mLVSNodesInstanceConnnectionPairOutputFormatter = lvsNodesInstanceConnnectionPairOutputFormatter; + mTableVarName = tableVarName; + + mAccum = new StringBuffer(); + + final Object[] headerArgs = { tableVarName, gdsIINamesNI.renameCell( cellName ) }; + + lvsNodesHeaderFormatter.format( headerArgs, mAccum, null ); + writeAccum(); + + } + catch ( CDLRenameException e ) { + throw new RuntimeException( e ); + } + catch ( IOException e ) { + throw new RuntimeException( e ); + } + + } + + public void lvsNodesForInstance( final HierName instanceName, + final List lvsNodeConnectionPairs ) { + try { + final Object[] instanceArgs = { mTableVarName, + currLVSNodesInstanceVarName, + mGDSIINamesNI.renameSubCellInstance( instanceName.getCadenceString() ) }; + + mLVSNodesInstanceOutputFormatter.format( instanceArgs, mAccum, null ); + writeAccum(); + + final Iterator connectionIter = lvsNodeConnectionPairs.iterator(); + + Object[] connectionArgs = new Object[3]; + + while ( connectionIter.hasNext() ) { + final Pair connection = ( Pair ) connectionIter.next(); + final HierName node = ( HierName ) connection.getFirst(); + final HierName nodeInInstance = ( HierName ) connection.getSecond(); + + connectionArgs[0] = currLVSNodesInstanceVarName; + connectionArgs[1] = mGDSIINamesNI.renameNode( node.getCadenceString() ); + connectionArgs[2] = mGDSIINamesNI.renameNode( nodeInInstance.getCadenceString() ); + + mLVSNodesInstanceConnnectionPairOutputFormatter.format( connectionArgs, mAccum, null ); + writeAccum(); + } + + + } + catch ( CDLRenameException e ) { + throw new RuntimeException( e ); + } + } + + public void end( final Set cellLVSNodes ) { + try { + final Iterator nodeIter = cellLVSNodes.iterator(); + + Object[] nodeArgs = new Object[2]; + + while ( nodeIter.hasNext() ) { + final HierName node = ( HierName ) nodeIter.next(); + + final String castNodeName = node.getCadenceString(); + final String cadenceNodeName = mCadenceNamesNI.renameNode( castNodeName ); + final String gdsIINodeName = mGDSIINamesNI.renameNode( castNodeName ); + + nodeArgs[0] = mTableVarName; + nodeArgs[1] = gdsIINodeName; + + mCellLVSNodeOutputFormatter.format( nodeArgs, mAccum, null ); + writeAccum(); + + mTableEmitter.emitNodeName( castNodeName, + cadenceNodeName, + gdsIINodeName + ); + + } + mWriter.close(); + mTableEmitter.close(); + } + catch ( CDLRenameException e ) { + throw new RuntimeException( e ); + } + catch ( IOException e ) { + throw new RuntimeException( e ); + } + catch ( TableEmitterException e ) { + throw new RuntimeException( e ); + } + } + public void abort( ) { + try { + mWriter.close(); + mOutputFile.delete(); + mTableEmitter.close(); + } + catch ( IOException e ) { + throw new RuntimeException( e ); + } + catch ( TableEmitterException e ) { + throw new RuntimeException( e ); + } + } + + } + + + private static final String tableVarName = "GDSIILVSNodesTable"; + + private final TableEmitterFactoryInterface mTableEmitterFactory; + private final CDLNameInterfaceFactory mCadenceNames; + private final CDLNameInterfaceFactory mGDSIINames; + private final File mOutputDir; + + private Emitter mCurrEmitter; + + public GDSIILVSNodesHandler( final TableEmitterFactoryInterface tableEmitterFactory, + final CDLNameInterfaceFactory cadenceNames, + final CDLNameInterfaceFactory gdsIINames, + final File outputDir ) { + mTableEmitterFactory = tableEmitterFactory; + mCadenceNames = cadenceNames; + mGDSIINames = gdsIINames; + mOutputDir = outputDir; + + mCurrEmitter = null; + + mLVSNodesHeaderFormatter = + new MessageFormat( lvsNodesHeaderFormatStr ); + mCellLVSNodeOutputFormatter = + new MessageFormat( cellLVSNodeOutputFormatStr ); + mLVSNodesInstanceOutputFormatter = + new MessageFormat( lvsNodesInstanceOutputFormatStr ); + mLVSNodesInstanceConnnectionPairOutputFormatter = + new MessageFormat( lvsNodesInstanceConnectionPairOutputFormatStr ); + + } + + public void startCell( final String cellName ) { + assert mCurrEmitter == null; + + try { + final CDLNameInterface gdsIINI = mGDSIINames.getNameInterface( cellName ); + final CDLNameInterface cadenceNI = mCadenceNames.getNameInterface( cellName ); + + final String cadenceCellName = cadenceNI.renameCell( cellName ); + final String gdsIICellName = gdsIINI.renameCell( cellName ); + + final TableEmitterInterface tableEmitter = mTableEmitterFactory.getTableEmitter( cellName, + cadenceCellName, + gdsIICellName ); + + + final File outputFile = new File( mOutputDir, + cadenceNI.renameCell( cellName ) + + ".lvsNodes.il" ); + + mCurrEmitter = new Emitter( outputFile, + tableEmitter, + cadenceNI, + gdsIINI, + mLVSNodesHeaderFormatter, + mCellLVSNodeOutputFormatter, + mLVSNodesInstanceOutputFormatter, + mLVSNodesInstanceConnnectionPairOutputFormatter, + tableVarName, + cellName ); + + + + } + catch ( CDLRenameException e ) { + throw new RuntimeException( e ); + } + catch ( TableEmitterException e ) { + throw new RuntimeException( e ); + } + + } + + public void lvsNodesForInstance( final HierName instanceName, + final List lvsNodeConnectionPairs ) { + assert mCurrEmitter != null; + mCurrEmitter.lvsNodesForInstance( instanceName, lvsNodeConnectionPairs ); + } + + public void endCell( final String cellName, final Set cellLVSNodes ) { + mCurrEmitter.end( cellLVSNodes ); + mCurrEmitter = null; + } + + public void abortCell( final String cellName ) { + mCurrEmitter.abort(); + mCurrEmitter = null; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIData.java new file mode 100644 index 0000000000..3f1671168b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIData.java @@ -0,0 +1,480 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.layout.gdsII; + + + +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; + +import java.io.File; +import java.io.OutputStream; +import java.io.Writer; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.BufferedWriter; +import java.io.IOException; + +import java.text.MessageFormat; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; + +import com.avlsi.io.FileSearchPath; + +import com.avlsi.file.common.HierName; + +import com.avlsi.cast.CastFileParser; + +import com.avlsi.cast.impl.Environment; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.SplittingFactory; +import com.avlsi.file.cdl.parser.InternalNodeFilterFactory; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.LVSNodesCDLFactory; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.TrivialCDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; + +import com.avlsi.tools.jauto.Cast2Cdl; +import com.avlsi.tools.jauto.PartialExtract; + +import com.avlsi.layout.LVSNodes; +import com.avlsi.layout.LVSNodesForExtract; + +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.GDSIILVSNodesHandler; +import com.avlsi.layout.gdsII.FilterInternalNodesTableEmitterFactory; +import com.avlsi.layout.gdsII.SkillTableEmitterFactory; +import com.avlsi.layout.gdsII.AssuraBindRulTableEmitterFactory; +import com.avlsi.layout.gdsII.SharedTableEmitterFactory; + +public class GenerateGDSIIData { + + private static void usage( String m ) { + final String className = GenerateGDSIIData.class.getName(); + + System.err.println( "Usage: generate_gdsII_data"); + System.err.println(" --cast-path= (defaults to .)"); + System.err.println(" --cast-version= (defaults to 2)"); + System.err.println(" --cell= (name of cell to process)"); + System.err.println(" --bind-rul= ( bind.rul file for LVS)"); + System.err.println(" --bind-all-nodes (include all nodes in output bind.rul)"); + System.err.println(" --output-root-cell-name=(defaults to fully-qualified cast name)"); + System.err.println(" --output-dir=\n"); + if (m != null && m.length() > 0) + System.err.print( m ); + System.exit(1); + } + + private static void usage() { + usage( null ); + } + + private static final class PartialExtractResultHandler implements PartialExtract.CellResultHandler { + private static final String partialExtractTableVarName = "PartialExtractTable"; + + private static final String partialExtractInstanceFormatStr = + "( setarray ( arrayref {0} \"{1}\" ) \"{2}\" \"{3}\" )\n"; + + private static final String partialExtractSubTypeFormatStr = + "( setarray {0} \"{1}\" ( makeTable \"partialExtractInstanceTable\" nil ) )\n"; + + private static final String partialExtractHeaderFormatStr = + "( defvar {0} ( makeTable \"partialExtractTable\" nil ) )\n"; + private final MessageFormat mPartialExtractInstanceFormatter; + private final MessageFormat mPartialExtractSubTypeFormatter; + private final MessageFormat mPartialExtractHeaderFormatter; + + final StringBuffer accumulator; + + final File mOutputDir; + + Writer mCurrOutputWriter; + + private final Map mOldCellNameMap = new HashMap(); + private String mCurrCellName; + + Exception mError; + + final CDLNameInterface mGDSIINameInterface; + final CDLNameInterface mCadenceNameInterface; + + public Exception getError() { + return mError; + } + + + public void finish() + throws IOException{ + if ( mCurrOutputWriter != null ) { + mCurrOutputWriter.close(); + } + } + + public PartialExtractResultHandler( final File outputDir ) { + + mPartialExtractInstanceFormatter = + new MessageFormat( partialExtractInstanceFormatStr ); + mPartialExtractSubTypeFormatter = + new MessageFormat( partialExtractSubTypeFormatStr ); + mPartialExtractHeaderFormatter = + new MessageFormat( partialExtractHeaderFormatStr ); + accumulator = new StringBuffer(); + + mOutputDir = outputDir; + mError = null; + mCurrOutputWriter = null; + mGDSIINameInterface = new GDS2NameInterface(); + mCadenceNameInterface = new CadenceNameInterface(); + } + + public void setCellName( final String cellName ) { + if ( mError == null ) { + try { + if ( mCurrOutputWriter != null ) { + mCurrOutputWriter.close(); + } + + mCurrCellName = cellName; + + final String cadenceCellName = mCadenceNameInterface.renameCell( cellName ); + + final File fileForCell = new File( mOutputDir, cadenceCellName + ".partial.il" ); + final OutputStream streamForCell = new FileOutputStream( fileForCell ); + final Writer writerForCell = new BufferedWriter( new OutputStreamWriter( streamForCell, "UTF-8" ) ); + mCurrOutputWriter = writerForCell; + + final Object[] partialExtractHeaderParams = { + partialExtractTableVarName + }; + + mPartialExtractHeaderFormatter.format( partialExtractHeaderParams, + accumulator, + null ); + mCurrOutputWriter.write( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + + } + catch ( CDLRenameException e ) { + mError = e; + } + catch( IOException e ) { + mError = e; + } + } + } + + public void handleSubtype( final String subTypeName, + final Map instances ) { + if ( mError == null ) { + try { + assert mCurrOutputWriter != null; + assert mCurrCellName != null; + + mOldCellNameMap.put(subTypeName,mCurrCellName); + + final Object[] partialExtractSubTypeParams = { + partialExtractTableVarName, + mGDSIINameInterface.renameCell( subTypeName ) }; + mPartialExtractSubTypeFormatter.format( partialExtractSubTypeParams, accumulator, null ); + mCurrOutputWriter.write( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + + final Iterator instancesEntryIter = instances.entrySet().iterator(); + + while ( instancesEntryIter.hasNext() ) { + Map.Entry instanceEntry = ( Map.Entry ) instancesEntryIter.next(); + final HierName instanceName = ( HierName ) instanceEntry.getKey(); + final String instanceMasterName = ( String ) instanceEntry.getValue(); + + final Object[] partialExtractInstanceParams = { + partialExtractTableVarName, + mGDSIINameInterface.renameCell( subTypeName ), + mGDSIINameInterface.renameSubCellInstance( instanceName.toString() ), + mGDSIINameInterface.renameCell( instanceMasterName ) }; + + mPartialExtractInstanceFormatter.format( partialExtractInstanceParams, accumulator, null ); + mCurrOutputWriter.write( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + } + + } + catch ( CDLRenameException e ) { + mError = e; + } + catch( IOException e ) { + mError = e; + } + } + } + + public Map getOriginalNames(final String subTypeName ) { + return mOldCellNameMap; + } + } + + public static void writePartialExtractInfo( final PartialExtract peInfo, + final File outputDir ) + throws Exception { + + final PartialExtractResultHandler handler = + new PartialExtractResultHandler( outputDir ); + peInfo.traverseResult( handler ); + handler.finish(); + Exception e = handler.getError(); + if(e != null) { + throw e; + } + } + + public static void main( String args[] ) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CachingCommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String givenCellName = theArgs.getArgValue("cell", null); + final String outputRootCellName = theArgs.getArgValue("output-root-cell-name", null); + final String cellName; + cellName = givenCellName; + + final File bindRulFile = new File( theArgs.getArgValue( "bind-rul", "/dev/null" )); + + final String outputDirName = theArgs.getArgValue( "output-dir", null ); + + pedanticArgs.argTag( "bind-all-nodes" ); + + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + usage( pedanticArgs.pedanticString() ); + } + + final File outputDir; + + if ( outputDirName != null ) { + outputDir = new File ( outputDirName ); + } + else { + outputDir = null ; + } + + if ( ( outputDir != null ) && + ( ! ( outputDir.exists() ) ) ) { + outputDir.mkdirs(); + } + + if ( ( cellName != null ) && + ( bindRulFile != null ) && + ( bindRulFile.canRead() ) && + ( outputDir != null ) && + ( outputDir.isDirectory() ) ) { + + final CastFileParser castParser = + new CastFileParser( new FileSearchPath(castRoot), castVersion ); + + final Cadencize cadencizer = new Cadencize(false); + + final PartialExtract.CellPlusMinus cellNameSpec = + new PartialExtract.CellPlusMinusKeyword( cellName, + PartialExtract.Info.INCLUDE, + castParser, cadencizer); + + final CellInterface ci = castParser.getFullyQualifiedCell( cellNameSpec.getTop() ); + + cadencizer.convert( ci ); + + final CadenceNameInterface cadenceNameInterface = + new CadenceNameInterface(); + final CDLNameInterface renameTopCellGDSIINameInterface = + new GDS2NameInterface() { + public String renameCell(String oldCellName) + throws CDLRenameException { + if(outputRootCellName != null && + !outputRootCellName.equals("") && + oldCellName.equals(cellName)) { + return outputRootCellName; + } + else { + return super.renameCell(oldCellName); + } + } + }; + + final TrivialCDLNameInterfaceFactory cadenceNameInterfaceFactory = + new TrivialCDLNameInterfaceFactory( cadenceNameInterface ); + + final TrivialCDLNameInterfaceFactory gdsIINameInterfaceFactory = + new TrivialCDLNameInterfaceFactory( renameTopCellGDSIINameInterface); + + + // assura bind.rul table + final File outputBindRul = new File( outputDir, "bind.rul" ); + final boolean bindAllNodes = theArgs.argExists("bind-all-nodes"); + final TableEmitterFactoryInterface bindRulEmitterFactory = + new AssuraBindRulTableEmitterFactory( outputBindRul, + bindRulFile, + bindAllNodes ); + + // names.il table + final TableEmitterFactoryInterface skillEmitterFactory = + new SkillTableEmitterFactory( outputDir, + "CadenceNodeToGDSIINodeTable", + "CadenceCellToGDSIICellTable", + "CadenceInstanceToGDSIIInstanceTable" ); + + final TableEmitterFactoryInterface emitterFactory; + + /** + * We will emit both names.il and bind.rul now only if + * this is not a partial extraction. The reason is that the + * names.il tables should have original names, while the bind.rul + * should have the partial extract names + **/ + + if ( ! cellNameSpec.isEmpty() ) { + emitterFactory = skillEmitterFactory; + } + else { + emitterFactory = + ( new SplittingTableEmitterFactory + (bindRulEmitterFactory, + skillEmitterFactory) ); + } + + final TableEmitterFactoryInterface sharedEmitterFactory = + new SharedTableEmitterFactory( emitterFactory ); + + final TableEmitterFactoryInterface filteredEmitterFactory = + new FilterInternalNodesTableEmitterFactory + ( cadencizer, + sharedEmitterFactory ); + + final GenerateGDSIIDataFactory gdsIIDataFactory = + new GenerateGDSIIDataFactory + ( filteredEmitterFactory, + cadenceNameInterfaceFactory, + gdsIINameInterfaceFactory ); + + final CDLFactoryInterface originalCDLFactory; + final CDLFactoryInterface partialExtractCDLFactory; + final Map circuitTemplatesMap; + + /** If it's a partial extract, then want to execute the partial + * extract netlist on the bind.rul emitter, and of course, create + * the templates for partial extract. Otherwise, we just + * write the names.il and bind.rul emitters + **/ + if ( ! cellNameSpec.isEmpty() ) { + circuitTemplatesMap = new HashMap(); + final Template templates = + new Template( circuitTemplatesMap ); + originalCDLFactory = + new SplittingFactory( templates, + gdsIIDataFactory); + partialExtractCDLFactory = + new InternalNodeFilterFactory + ( new GenerateGDSIIDataFactory + ( bindRulEmitterFactory, + cadenceNameInterfaceFactory, + gdsIINameInterfaceFactory ) ); + } + else { + circuitTemplatesMap = null; + originalCDLFactory = gdsIIDataFactory; + partialExtractCDLFactory = null; + } + + final GDSIILVSNodesHandler lvsNodesHandler = + new GDSIILVSNodesHandler( sharedEmitterFactory, + cadenceNameInterfaceFactory, + gdsIINameInterfaceFactory, + outputDir ) ; + + final LVSNodes lvsNodesInfo = new LVSNodesForExtract( castParser, + cadencizer ); + final CDLFactoryInterface lvsNodesEmitter = + new LVSNodesCDLFactory( lvsNodesInfo, + originalCDLFactory, + lvsNodesHandler ); + + Cast2Cdl.outputCDL( ci, + castParser, + lvsNodesEmitter, + cadencizer, + false, + false ); + + if ( ! cellNameSpec.isEmpty() ) { + final PartialExtract pe = + new PartialExtract( circuitTemplatesMap, + ci.getFullyQualifiedType(), + cellNameSpec ); + pe.execute( partialExtractCDLFactory ); + writePartialExtractInfo( pe, outputDir ); + } + + final File fileForCell = + new File( outputDir, "name.txt" ); + final OutputStream streamForCell = + new FileOutputStream( fileForCell ); + final Writer writerForCell = + new BufferedWriter( new OutputStreamWriter( streamForCell, "UTF-8" ) ); + writerForCell.write( cadenceNameInterface.renameCell( ci.getFullyQualifiedType() ) ); + writerForCell.write( "\n" ); + writerForCell.close(); + + } + else { + if ( cellName == null ) { + System.out.println( "You must specify a cast cell name." ); + } + if ( bindRulFile == null ) { + System.out.println( "You must specify the location of the bind.rul file." ); + } + else if ( ! ( ( bindRulFile.isFile() ) && + ( bindRulFile.canRead() ) ) ) { + System.out.println( "\"" + bindRulFile + "\" is not a readable file." ); + } + if ( outputDir == null ) { + System.out.println( "You must specify an output directory." ); + } + else if ( ! ( outputDir.isDirectory() ) ) { + System.out.println( "\"" + outputDir + "\" is not a directory." ); + } + usage(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIDataFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIDataFactory.java new file mode 100644 index 0000000000..198ed65495 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/GenerateGDSIIDataFactory.java @@ -0,0 +1,240 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + + + +import java.util.Map; +import java.util.HashSet; + +import com.avlsi.file.common.HierName; + +import com.avlsi.cast.impl.Environment; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; + +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; + +public class GenerateGDSIIDataFactory implements CDLFactoryInterface { + + private final CDLNameInterfaceFactory m_fromFactory; + private final CDLNameInterfaceFactory m_toFactory; + + private Exception m_Error; + + private final TableEmitterFactoryInterface m_EmitterFactory; + + private String m_CurrCellName; + private TableEmitterInterface m_CurrEmitter; + + public GenerateGDSIIDataFactory( TableEmitterFactoryInterface emitterFactory, + CDLNameInterfaceFactory from, + CDLNameInterfaceFactory to + ) { + m_EmitterFactory = emitterFactory; + m_CurrCellName = null; + m_CurrEmitter = null ; + m_fromFactory = from; + m_toFactory = to; + + m_Error = null; + } + + + + public void emitNodeName(final HierName name ) { + emitNodeName( name.toString() ); + } + + public void emitNodeName( final String nameString ) { + if ( m_Error == null ) { + try { + if ( ! m_CurrEmitter.haveNodeName( nameString ) || + ! m_CurrEmitter.haveCellName( m_CurrCellName ) ) { + + CDLNameInterface from = m_fromFactory.getNameInterface(m_CurrCellName); + CDLNameInterface to = m_toFactory.getNameInterface(m_CurrCellName); + + final String cadenceName = from.renameNode( nameString ); + final String gdsIIName = to.renameNode( nameString ); + m_CurrEmitter.emitNodeName( nameString, cadenceName, gdsIIName ); + } + } + catch ( CDLRenameException e ) { + m_Error = e; + } + catch ( TableEmitterException e ) { + m_Error = e ; + } + } + } + + public void emitCellName( final HierName name ) { + emitCellName( name.toString() ); + } + + public void emitCellName( final String nameString ) { + if ( m_Error == null ) { + try { + if ( ! m_CurrEmitter.haveCellName( nameString ) ) { + + CDLNameInterface from = m_fromFactory.getNameInterface(nameString); + CDLNameInterface to = m_toFactory.getNameInterface(nameString); + + final String cadenceName = from.renameCell( nameString ); + final String gdsIIName = to.renameCell( nameString ); + m_CurrEmitter.emitCellName( nameString, cadenceName, gdsIIName ); + } + } + catch ( CDLRenameException e ) { + m_Error = e; + } + catch ( TableEmitterException e ) { + m_Error = e ; + } + } + } + + + + public void emitInstanceName( final HierName name ) { + if ( m_Error == null ) { + try { + final String nameString = name.toString(); + if ( ! m_CurrEmitter.haveInstanceName( nameString ) || + ! m_CurrEmitter.haveCellName( m_CurrCellName ) ) { + + CDLNameInterface from = m_fromFactory.getNameInterface(m_CurrCellName); + CDLNameInterface to = m_toFactory.getNameInterface(m_CurrCellName); + + final String cadenceName = from.renameSubCellInstance( nameString ); + final String gdsIIName = to.renameSubCellInstance( nameString ); + m_CurrEmitter.emitInstanceName( nameString, cadenceName, gdsIIName ); + } + } + catch ( CDLRenameException e ) { + m_Error = e; + } + catch ( TableEmitterException e ) { + m_Error = e ; + } + } + } + + public void makeTransistor( HierName name, + String type, + HierName ns, + HierName nd, + HierName ng, + HierName nb, + CDLLexer.InfoToken w, + CDLLexer.InfoToken l, + Map parameters, + Environment env) { + + if ( m_Error == null ) { + emitNodeName( ns ); + emitNodeName( nd ); + emitNodeName( ng ); + emitNodeName( nb ); + } + + } + + public void makeDiode(HierName name, String type, HierName npos, HierName nneg, + CDLLexer.InfoToken val, + Map parameters, Environment env) { } + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { } + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { } + public void makeInductor(HierName name, HierName npos, HierName nneg, + CDLLexer.InfoToken val, Map parameters, + Environment env) { } + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, + CDLLexer.InfoToken val, + Map parameters, Environment env) { } + + public void makeCall( HierName name, + String subName, + HierName[] args, + Map parameters, + Environment env ) { + if ( m_Error == null ) { + for ( int i = 0 ; i < args.length ; ++i ) { + emitNodeName( args[i] ); + } + emitCellName( subName ); + emitInstanceName( name ); + } + } + + public void beginSubcircuit( String subName, + String[] in, + String[] out, + Map parameters, + Environment env ) { + if ( m_Error == null ) { + try { + m_CurrCellName = subName; + + CDLNameInterface from = m_fromFactory.getNameInterface(m_CurrCellName); + CDLNameInterface to = m_toFactory.getNameInterface(m_CurrCellName); + + final String fromName = from.renameCell( subName ); + final String toName = to.renameCell( subName ); + + m_CurrEmitter = m_EmitterFactory.getTableEmitter( subName, + fromName, + toName ); + emitCellName( subName ); + + int i; + for ( i = 0 ; i < in.length ; ++i ) { + emitNodeName( in[i] ); + } + for ( i = 0 ; i < out.length ; ++i ) { + emitNodeName( out[i] ); + } + } + + catch ( CDLRenameException e ) { + m_Error = e; + } + catch ( TableEmitterException e ) { + m_Error = e; + } + } + } + + public void endSubcircuit( String subName, Environment env ) { + if ( m_Error == null ) { + try { + m_CurrCellName = null; + m_CurrEmitter.close(); + } + catch ( TableEmitterException e ) { + m_Error = e ; + } + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SharedTableEmitterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SharedTableEmitterFactory.java new file mode 100644 index 0000000000..4c97badc7c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SharedTableEmitterFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + +import java.util.Map; +import java.util.HashMap; + + +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; + +public class SharedTableEmitterFactory implements TableEmitterFactoryInterface { + + private class Emitter implements TableEmitterInterface { + + private final String mCastCellName; + private int refCount; + + private final TableEmitterInterface mRealEmitter; + + public Emitter( final TableEmitterInterface realEmitter, + final String castCellName ) { + mCastCellName = castCellName; + mRealEmitter = realEmitter; + refCount = 0; + } + + public boolean haveCellName( final String castName ) { + return mRealEmitter.haveCellName( castName ); + } + public void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + mRealEmitter.emitCellName( castName, cadenceName, gdsIIName ); + } + public boolean haveNodeName( final String castName ) { + return mRealEmitter.haveNodeName( castName ); + } + public void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + mRealEmitter.emitNodeName( castName, cadenceName, gdsIIName ); + } + public boolean haveInstanceName( final String castName ) { + return mRealEmitter.haveInstanceName( castName ); + } + public void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + mRealEmitter.emitInstanceName( castName, + cadenceName, + gdsIIName ); + } + + public void close() throws TableEmitterException { + assert refCount > 0; + --refCount; + if ( refCount == 0 ) { + mRealEmitter.close(); + purge( mCastCellName ); + } + } + + public void addRef( ) { + ++refCount; + } + } + + private Map mEmitterMap; + private TableEmitterFactoryInterface mRealEmitterFactory; + + public SharedTableEmitterFactory( final TableEmitterFactoryInterface realEmitterFactory ) { + mRealEmitterFactory = realEmitterFactory; + mEmitterMap = new HashMap(); + } + + public TableEmitterInterface getTableEmitter( final String castCellName, + final String cadenceCellName, + final String gdsIICellName ) + throws TableEmitterException { + + final Emitter existingEmitter = + ( Emitter ) mEmitterMap.get( castCellName ); + + final Emitter sharedEmitter; + + if ( existingEmitter == null ) { + final TableEmitterInterface realEmitter = + mRealEmitterFactory.getTableEmitter( castCellName, + cadenceCellName, + gdsIICellName ); + sharedEmitter = new Emitter( realEmitter, + castCellName ); + mEmitterMap.put( castCellName, sharedEmitter ); + } + else { + sharedEmitter = existingEmitter; + } + sharedEmitter.addRef(); + return sharedEmitter; + + } + + private void purge( final String castCellName ) { + mEmitterMap.remove( castCellName ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SkillTableEmitterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SkillTableEmitterFactory.java new file mode 100644 index 0000000000..ebec041b68 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SkillTableEmitterFactory.java @@ -0,0 +1,207 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + + +import java.io.Writer; +import java.io.OutputStreamWriter; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.File; + +import java.util.Set; +import java.util.HashSet; + +import java.text.MessageFormat; + +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; + +public final class SkillTableEmitterFactory implements TableEmitterFactoryInterface { + + + private static final String mappingOutputFormatStr = + "( setarray {0} \"{1}\" \"{2}\" )\n"; + private final MessageFormat mMappingOutputFormatter; + + private static final String mappingHeaderFormatStr = + "( defvar {0} ( makeTable \"foo\" nil ) )\n" + + "( defvar {1} ( makeTable \"bar\" nil ) )\n" + + "( defvar {2} ( makeTable \"baz\" nil ) )\n"; + private final MessageFormat mMappingHeaderFormatter; + + private static final class Emitter implements TableEmitterInterface { + private final Writer mWriter; + private final String mNodeNameMappingTableVarName; + private final String mCellNameMappingTableVarName; + private final String mInstanceNameMappingTableVarName; + private final MessageFormat mMappingOutputFormatter; + private final StringBuffer mAccum; + private final Set mTranslatedCellNames; + private final Set mTranslatedNodeNames; + + public Emitter( final Writer writer, + final String nodeNameMappingTableVarName, + final String cellNameMappingTableVarName, + final String instanceNameMappingTableVarName, + final MessageFormat mappingOutputFormatter ) { + mWriter = writer; + mNodeNameMappingTableVarName = nodeNameMappingTableVarName; + mCellNameMappingTableVarName = cellNameMappingTableVarName; + mInstanceNameMappingTableVarName = instanceNameMappingTableVarName; + mMappingOutputFormatter = mappingOutputFormatter; + mAccum = new StringBuffer(); + mTranslatedCellNames = new HashSet(); + mTranslatedNodeNames = new HashSet(); + } + + private void emitName( final String tableName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + final Object[] mappingOutputParams = { + tableName, + cadenceName, + gdsIIName }; + + mMappingOutputFormatter.format( mappingOutputParams, + mAccum, + null ); + try { + mWriter.write( mAccum.toString() ); + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to emit mapping: " + + cadenceName + "=" + gdsIIName + ".", + e ); + } + mAccum.delete( 0, mAccum.length() ); + + } + + public boolean haveCellName( final String castName ) { + return mTranslatedCellNames.contains( castName ); + } + + public void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + if ( ! ( haveCellName( castName ) ) ) { + emitName( mCellNameMappingTableVarName, cadenceName, gdsIIName ); + mTranslatedCellNames.add( castName ); + } + } + + public boolean haveNodeName( final String castName ) { + return mTranslatedNodeNames.contains( castName ); + } + + public void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + if ( ( ! ( haveNodeName( castName ) ) ) ) { + emitName( mNodeNameMappingTableVarName, cadenceName, gdsIIName ); + mTranslatedNodeNames.add( castName ); + } + + } + + public boolean haveInstanceName( final String castName ) { + return false; + } + + public void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + emitName( mInstanceNameMappingTableVarName, cadenceName, gdsIIName ); + } + + public void close() throws TableEmitterException { + try { + mWriter.close(); + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to close the file.", e ); + } + + } + + } + + private final File mOutputDir; + private final String mNodeNameMappingTableVarName; + private final String mCellNameMappingTableVarName; + private final String mInstanceNameMappingTableVarName; + + public SkillTableEmitterFactory( final File outputDir, + final String nodeNameMappingTableVarName, + final String cellNameMappingTableVarName, + final String instanceNameMappingTableVarName ) { + mOutputDir = outputDir; + mNodeNameMappingTableVarName = nodeNameMappingTableVarName; + mCellNameMappingTableVarName = cellNameMappingTableVarName; + mInstanceNameMappingTableVarName = instanceNameMappingTableVarName; + + mMappingOutputFormatter = new MessageFormat( mappingOutputFormatStr ); + + mMappingHeaderFormatter = new MessageFormat( mappingHeaderFormatStr ); + + } + + public TableEmitterInterface getTableEmitter( final String castCellName, + final String cadenceCellName, + final String gdsIICellName ) + throws TableEmitterException { + + final File outputFile = new File( mOutputDir, cadenceCellName + ".names.il" ); + try { + final OutputStream outputStream = new FileOutputStream( outputFile ); + final Writer writer = new OutputStreamWriter( outputStream, "UTF-8" ); + + final StringBuffer accum = new StringBuffer(); + + final Object[] headerParams = { mNodeNameMappingTableVarName, + mCellNameMappingTableVarName, + mInstanceNameMappingTableVarName }; + + mMappingHeaderFormatter.format( headerParams, accum, null ); + try { + writer.write( accum.toString() ); + + final TableEmitterInterface skillEmitter = + new Emitter( writer, + mNodeNameMappingTableVarName, + mCellNameMappingTableVarName, + mInstanceNameMappingTableVarName, + mMappingOutputFormatter ); + + return skillEmitter; + } + catch( IOException e ) { + throw new TableEmitterException( "Unable to write header.", + e ); + } + } + catch ( FileNotFoundException e ) { + throw new TableEmitterException( "Unable to open " + + outputFile.toString() + + ".", + e ); + } + catch ( IOException e ) { + throw new TableEmitterException( "Unable to open " + + outputFile.toString() + + ".", + e ); + } + + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SplittingTableEmitterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SplittingTableEmitterFactory.java new file mode 100644 index 0000000000..b4e8b280eb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/SplittingTableEmitterFactory.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.layout.gdsII; + + +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; + +import com.avlsi.layout.gdsII.CachingTableEmitter; + +public class SplittingTableEmitterFactory implements TableEmitterFactoryInterface { + + private final TableEmitterFactoryInterface m_Left; + private final TableEmitterFactoryInterface m_Right; + + private static final class SplittingTableEmitter implements TableEmitterInterface { + private final TableEmitterInterface m_Left; + private final TableEmitterInterface m_Right; + + public boolean haveCellName( final String castName ) { + return ( ( m_Left.haveCellName( castName ) ) && + ( m_Right.haveCellName( castName ) ) ); + } + + public void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + m_Left.emitCellName( castName, cadenceName, gdsIIName ); + m_Right.emitCellName( castName, cadenceName, gdsIIName ); + } + + public boolean haveNodeName( final String castName ) { + return ( ( m_Left.haveNodeName( castName ) ) && + ( m_Right.haveNodeName( castName ) ) ); + } + + public void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + m_Left.emitNodeName( castName, cadenceName, gdsIIName ); + m_Right.emitNodeName( castName, cadenceName, gdsIIName ); + } + + public boolean haveInstanceName( final String castName ) { + return ( ( m_Left.haveInstanceName( castName ) ) && + ( m_Right.haveInstanceName( castName ) ) ); + } + + public void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException { + m_Left.emitInstanceName( castName, cadenceName, gdsIIName ); + m_Right.emitInstanceName( castName, cadenceName, gdsIIName ); + } + + public void close() throws TableEmitterException { + m_Left.close(); + m_Right.close(); + } + + public SplittingTableEmitter( final TableEmitterInterface left, + final TableEmitterInterface right ) { + m_Left = left; + m_Right = right; + } + } + + public SplittingTableEmitterFactory( final TableEmitterFactoryInterface left, + final TableEmitterFactoryInterface right ) { + m_Left = left; + m_Right = right; + } + + public TableEmitterInterface getTableEmitter( final String castCellName, + final String cadenceCellName, + final String gdsIICellName ) + throws TableEmitterException { + + TableEmitterInterface left = m_Left.getTableEmitter( castCellName, + cadenceCellName, + gdsIICellName ); + + TableEmitterInterface right = m_Right.getTableEmitter( castCellName, + cadenceCellName, + gdsIICellName ); + + return new CachingTableEmitter( new SplittingTableEmitter( left, right ) ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterException.java new file mode 100644 index 0000000000..20369abcce --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterException.java @@ -0,0 +1,15 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.layout.gdsII; + + +public class TableEmitterException extends Exception { + public TableEmitterException( final String errorStr, final Exception cause ) { + super( errorStr, cause ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterFactoryInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterFactoryInterface.java new file mode 100644 index 0000000000..6d1d12d34b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterFactoryInterface.java @@ -0,0 +1,20 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.layout.gdsII; + + +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; + +public interface TableEmitterFactoryInterface { + TableEmitterInterface getTableEmitter( final String castCellName, + final String cadenceCellName, + final String gdsIICellName ) + throws TableEmitterException ; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterInterface.java new file mode 100644 index 0000000000..928eb17880 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/TableEmitterInterface.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.layout.gdsII; + + +import com.avlsi.layout.gdsII.TableEmitterException; + +public interface TableEmitterInterface { + + boolean haveCellName( final String castName ); + void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException ; + boolean haveNodeName( final String castName ); + void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException ; + boolean haveInstanceName( final String castName ); + void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) throws TableEmitterException ; + + void close() throws TableEmitterException ; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/custom.mk new file mode 100644 index 0000000000..47cf26019b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/gdsII/custom.mk @@ -0,0 +1,3 @@ +$(CURR_TARGET_DIR)/generate_gdsII_data.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.layout.gdsII.GenerateGDSIIData/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/layout/javafiles-custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/javafiles-custom.mk new file mode 100644 index 0000000000..fa760ad989 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/layout/javafiles-custom.mk @@ -0,0 +1 @@ +JAVAFILES_PARSERS_USED := $(JAVAFILES_PARSERS_USED) $(call CONONICALIZE_PATH, $(CURR_TARGET_DIR)/../tools/jauto/CellHierarchyDumpParser ) diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDevice.java new file mode 100644 index 0000000000..a711d92425 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDevice.java @@ -0,0 +1,22 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist; + +import com.avlsi.netlist.Visitor; + +/** + Interface to a device. + */ +public interface AbstractDevice { + /** + Calls the appropriate method in the specified implementation of the + Visitor interface. + @param visitor An implementation of Visitor. + */ + void accept(final Visitor visitor); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDeviceIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDeviceIterator.java new file mode 100644 index 0000000000..3149b9da1d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractDeviceIterator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist; + +import java.util.NoSuchElementException; + +import com.avlsi.netlist.AbstractDevice; + +/** + Interface to a device iterator, for type safety. + */ + +public interface AbstractDeviceIterator { + /** + Returns true if the iteration has more elements. + @return true if iterator has more elements + */ + boolean hasNext(); + + /** + Returns the next AbstractDevice in the iteration. + @return the next AbstractDevice + @throws NoSuchElementException iteration has no more elements + */ + AbstractDevice next(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlist.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlist.java new file mode 100644 index 0000000000..db1c17b504 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlist.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist; + +import java.util.Iterator; +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.AbstractDeviceIterator; + +/** + Interface to a netlist. A netlist contains a set of nets, which are called + nodes, and a set of devices, such as transistors, resistors and capacitors + that are connected by the nets. A netlist is hierachical, with possibly + nesting subcircuits. + */ +public interface AbstractNetlist { + /** + Gets an iterator that iterates over all input nodes. + @return an AbstractNodeIterator over input nodes + */ + AbstractNodeIterator getInputNodes(); + + /** + Gets an iterator that iterates over all output nodes. + @return an AbstractNodeIterator over output nodes + */ + AbstractNodeIterator getOutputNodes(); + + /** + Gets the name of this subcircuit. + @return name of this subcircuit + */ + HierName getName(); + + /** + Gets an iterator that iterates over all nodes in the netlist. + @return an AbstractNodeIterator over all nodes + */ + AbstractNodeIterator getNodes(); + + /** + Gets an iterator that iterates over all devices in the netlist. + @return an AbstractDeviceIterator over all devices + */ + AbstractDeviceIterator getDevices(); + + /** + Gets an iterator that iterates over all subcircuits defined in the + netlist. + @return an AbstractNetlistIterator over all subcircuits + */ + AbstractNetlistIterator getSubcircuits(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlistIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlistIterator.java new file mode 100644 index 0000000000..e929d0007d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNetlistIterator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist; + +import java.util.NoSuchElementException; + +import com.avlsi.netlist.AbstractNetlist; + +/** + Interface to a netlist iterator, for type safety. + */ + +public interface AbstractNetlistIterator { + /** + Returns true if the iteration has more elements. + @return true if iterator has more elements + */ + boolean hasNext(); + + /** + Returns the next AbstractNetlist in the iteration. + @return the next AbstractNetlist + @throws NoSuchElementException iteration has no more elements + */ + AbstractNetlist next(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNode.java new file mode 100644 index 0000000000..79f5de3587 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNode.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist; + +import java.util.Iterator; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDeviceIterator; + +/** + Interface to a node. A node represents an electrical net. It has a + canonical name, and aliases. + */ + +public interface AbstractNode { + /** + Gets the canonical name of the node + @return Name of the node + */ + HierName getCanonicalName(); + + /** + Gets an iterator that iterates over aliases of the node + @return An iterator containing HierNames + */ + Iterator getAliases(); + + /** + Gets an iterator that iterates over devices connected to this node + @return An iteration over connected devices. + */ + AbstractDeviceIterator getDevices(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNodeIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNodeIterator.java new file mode 100644 index 0000000000..72c6ad3591 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/AbstractNodeIterator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist; + +import java.util.NoSuchElementException; + +import com.avlsi.netlist.AbstractNode; + +/** + Interface to a node iterator, for type safety. + */ + +public interface AbstractNodeIterator { + /** + Returns true if the iteration has more elements. + @return true if iterator has more elements + */ + boolean hasNext(); + + /** + Returns the next AbstractNode in the interation. + @return the next AbstractNode + @throws NoSuchElementException iteration has no more elements + */ + AbstractNode next(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/Visitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/Visitor.java new file mode 100644 index 0000000000..7a24e277b4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/Visitor.java @@ -0,0 +1,144 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist; + +import java.util.Collection; +import java.util.Map; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractNetlist; + +/** + Visitor interface used by AbstractDevice. + */ +public interface Visitor { + /** + Called by implementations of AbstractDevice that implement a transistor. + Parameters is a table of key-value pairs containing additional + parameters. The name of the transistor must be unique for every + instance within a subcircuit. + @param name Name of the transistor + @param drain Drain node + @param gate Gate node + @param source Source node + @param bulk Substrate node + @param length Length in meters + @param width Width in meters + @param type Type of transistor + @param parameters A Map from String to Double that captures additional + parameters + */ + void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters); + + /** + Called by implementations of AbstractDevice that implement a diode. + Parameters is a table of key-value pairs containing additional + parameters. The name of the transistor must be unique for every + instance within a subcircuit. + @param name Name of the diode + @param positive The positive terminal + @param negative The negative terminal + @param length Length in meters + @param width Width in meters + @param perimeter Perimeter in meters + @param area Area in square meters + @param type Type of diode + @param parameters A Map from String to Double that captures additional + parameters + */ + void genericDiode(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double length, + final double width, + final double perimeter, + final double area, + final String type, + final Map parameters); + + /** + Called by implementations of AbstractDevice that implement a resistor. + Parameters is a table of key-value pairs containing additional + parameters. The name of the transistor must be unique for every + instance within a subcircuit. + @param name Name of the resistor + @param node1 First terminal + @param node2 Second terminal + @param conductance Conductance in mho + @param parameters A Map from String to Double that captures additional + parameters + */ + void genericResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double conductance, + final Map parameters); + + /** + Called by implementations of AbstractDevice that implement a capacitor. + Parameters is a table of key-value pairs containing additional + parameters. The name of the transistor must be unique for every + instance within a subcircuit. + @param name Name of the capacitor + @param positive The positive terminal + @param negative The negative terminal + @param capacitance Capacitance in farads + @param parameters A Map from String to Double that captures additional + parameters + */ + void genericCapacitor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double capacitance, + final Map parameters); + + /** + Called by implementations of AbstractDevice that implement an inductor. + Parameters is a table of key-value pairs containing additional + parameters. The name of the inductor must be unique for every + instance within a subcircuit. + @param name Name of the inductor + @param positive The positive terminal + @param negative The negative terminal + @param inductance Inductance in henrys + @param parameters A Map from String to Double that captures additional + parameters + */ + void genericInductor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double inductance, + final Map parameters); + + /** + Called by implementations of AbstractDevice that implement a subcircuit + call. + @param name Name of the instantiated cell. + @param circuit Circuit description + @param nodes Input nodes in the same order as circuit.getInputNodes + would return, followed by output nodes in the same order as + circuit.getOutputNodes would return. + @param parameters A Map from String to Double that captures additional + parameters + + */ + void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/CDLEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/CDLEmitter.java new file mode 100644 index 0000000000..cd51d51876 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/CDLEmitter.java @@ -0,0 +1,256 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.io.PrintWriter; +import java.io.Writer; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.NetlistFormatter; +import com.avlsi.util.text.NumberFormatter; + +public class CDLEmitter extends NetlistFormatter implements Visitor { + private static final Map suffixMap = new HashMap(); + private static final Set needSuffix = new HashSet(); + private final PrintWriter w; + private final double deviceScale; + private final String suffix; + private final int precision; + private final int maxLineSize; + private int linesize; + + static { + suffixMap.put(new Character('m'), new Double(1e3)); + suffixMap.put(new Character('u'), new Double(1e6)); + suffixMap.put(new Character('n'), new Double(1e9)); + suffixMap.put(new Character('p'), new Double(1e12)); + suffixMap.put(new Character('f'), new Double(1e15)); + + needSuffix.add("nw"); /* n-stack width for gates */ + needSuffix.add("pw"); /* p-stack width for gates */ + needSuffix.add("nl"); /* n-stack length for staticizers */ + needSuffix.add("pl"); /* p-stack length for staticizers */ + } + + public CDLEmitter( final Writer w ) { + this( w, "" ); + } + + public CDLEmitter(final Writer w, final String suffix) { + this(w, suffix, -1); + } + public CDLEmitter(final Writer w, final String suffix, int precision) { + this(w, suffix, precision, 999); + } + public CDLEmitter(final Writer w, final String suffix, int precision, + int maxLineSize) { + this.w = new PrintWriter(w); + double scale = 1; + if (!suffix.equals("")) { + /* CDL interprets the first letter in the suffix as the scale + * factor */ + final Double x = (Double) suffixMap.get(new Character(Character.toLowerCase(suffix.charAt(0)))); + if (x != null) { + scale = x.doubleValue(); + } + } + this.deviceScale = scale; + this.suffix = suffix; + this.precision = precision; + this.linesize = 0; + this.maxLineSize = maxLineSize; + } + + private String stringNode(AbstractNode node) { + return node.getCanonicalName().getCadenceString(); + } + + private String d2s(double num) { + if (precision > 0) { + return NumberFormatter.format(num, precision); + } else { + return Double.toString(num); + } + } + + private String lengthSuffix(double length) { + return d2s(length * deviceScale) + suffix; + } + + /* Print the string as is */ + protected void print(String s) { + linesize += s.length(); + w.print(s); + } + + /* Create whitespace, then print the string */ + protected void printws(String s) { + int l = s.length(); + if (linesize + l + 1 > maxLineSize) { + println(); + w.print("+"); + } else { + w.print(" "); + } + w.print(s); + linesize += 1 + l; + } + + /* Go to a newline */ + protected void println() { + linesize = 0; + w.println(); + } + + private void keypair(Map parameters, Set needSuffix) { + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + Double val = (Double) entry.getValue(); + final String sval; + + boolean found = false; + for (Iterator j = needSuffix.iterator(); j.hasNext(); ) { + final String prefix = (String) j.next(); + if (key.toLowerCase().startsWith(prefix)) { + found = true; + break; + } + } + if (found) { + sval = lengthSuffix(val.doubleValue()); + } else { + sval = d2s(val.doubleValue()); + } + printws(key + "=" + sval); + } + } + + private void keypair(Map parameters) { + keypair(parameters, Collections.EMPTY_SET); + } + + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + + print("M" + name.getCadenceString()); + printws(stringNode(drain)); + printws(stringNode(gate)); + printws(stringNode(source)); + printws(stringNode(bulk)); + printws(type); + printws("W=" + lengthSuffix(width)); + printws("L=" + lengthSuffix(length)); + keypair(parameters); + println(); + } + + public void genericDiode(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double length, + final double width, + final double perimeter, + final double area, + final String type, + final Map parameters) { } + + public void genericResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double conductance, + final Map parameters) { + print("R" + name.getCadenceString()); + printws(stringNode(node1)); + printws(stringNode(node2)); + printws(d2s(1 / conductance)); + keypair(parameters); + println(); + } + + public void genericCapacitor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double capacitance, + final Map parameters) { + print("C" + name.getCadenceString()); + printws(stringNode(positive)); + printws(stringNode(negative)); + printws(d2s(capacitance)); + keypair(parameters); + println(); + } + + public void genericInductor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double inductance, + final Map parameters) { } + + public void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters) { + print("X" + name.getCadenceString()); + + while (nodes.hasNext()) { + printws(stringNode(nodes.next())); + } + + printws("/"); + printws(circuit.getName().getCadenceString()); + keypair(parameters, needSuffix); + println(); + } + + public void subcktBegin(final AbstractNetlist netlist) { + print(".SUBCKT"); + printws(netlist.getName().getCadenceString()); + + AbstractNodeIterator i; + i = netlist.getOutputNodes(); + while (i.hasNext()) { + printws(stringNode(i.next())); + } + + i = netlist.getInputNodes(); + if (i.hasNext()) { + printws("/"); + while (i.hasNext()) { + printws(stringNode(i.next())); + } + } + + println(); + } + + public void subcktEnd(final AbstractNetlist netlist) { + print(".ENDS"); + println(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/ConcatAbstractDeviceIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/ConcatAbstractDeviceIterator.java new file mode 100644 index 0000000000..b7be918805 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/ConcatAbstractDeviceIterator.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; + + +/** + Utility class to concantenate any number of AbstractDeviceIterators into + a single AbstractDeviceIterator. + */ +public class ConcatAbstractDeviceIterator implements AbstractDeviceIterator { + protected final AbstractDeviceIterator[] iterators; + protected int current; + + /** + Construct a AbstractDeviceIterator that is the concatentation of a + collection of AbstractDeviceIterators. + @param iterators Collection of AbstractDeviceIterator instances to + concatenate into a single AbstractDeviceIterator. The iterators in the + collection should not be modified after this constructor is called. + */ + public ConcatAbstractDeviceIterator( final Collection iterators) { + + this( ( AbstractDeviceIterator[] ) iterators.toArray(new AbstractDeviceIterator[0]) ); + } + /** + Construct a AbstractDeviceIterator that is the concatentation of an array + AbstractDeviceIterators. + @param iterators Array of AbstractDeviceIterator instances to concatenate + into a single AbstractDeviceIterator. The iterators in the array should + not be modified after this constructor is called. + */ + public ConcatAbstractDeviceIterator( final AbstractDeviceIterator[] iterators ) { + this.iterators = iterators; + current = 0; + } + + /** + Utility constructor to concatenate 2 AbstractDeviceIterators. + The specified iterators should not be modified after this constructor is + called. + @param i1 The first iterator. + @param i2 The second iterator. + */ + public ConcatAbstractDeviceIterator( final AbstractDeviceIterator i1, + final AbstractDeviceIterator i2 ) { + this(new AbstractDeviceIterator[] { i1, i2 }); + + } + + /** + Utility constructor to concatenate 3 AbstractDeviceIterators. + The specified iterators should not be modified after this constructor is + called. + @param i1 The first iterator. + @param i2 The second iterator. + @param i3 The third iterator. + */ + public ConcatAbstractDeviceIterator( final AbstractDeviceIterator i1, + final AbstractDeviceIterator i2, + final AbstractDeviceIterator i3 ) { + this(new AbstractDeviceIterator[] { i1, i2, i3 }); + } + + public boolean hasNext() { + while (current < iterators.length) { + if (iterators[current].hasNext()) { + return true; + } else { + current++; + } + } + return false; + } + + public AbstractDevice next() { + if (hasNext()) { + return (AbstractDevice) iterators[current].next(); + } else { + throw new NoSuchElementException(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessor.java new file mode 100644 index 0000000000..57e0d103d1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessor.java @@ -0,0 +1,226 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.NoSuchElementException; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.DeviceProcessorInterface; + +/** + * Processes devices in a netlist in a simple way. This class is ideal for + * device transformations that is one-to-one and stateless. If the + * transformation of a device is dependent on other devices, deletes devices or + * adds devices, then this class should not be used. + */ +public class DeviceProcessor implements AbstractNetlist, Visitor { + protected AbstractNetlist netlist; + protected final LinkedList processors; + private AbstractDevice result; + + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + DeviceProcessorInterface.Transistor device = + new DeviceProcessorInterface.Transistor(name, drain, gate, + source, bulk, length, + width, type, parameters); + for (Iterator i = processors.iterator(); i.hasNext(); ) { + DeviceProcessorInterface dpi = (DeviceProcessorInterface) i.next(); + device = dpi.processTransistor(device); + } + final DeviceProcessorInterface.Transistor d = device; + result = new AbstractDevice() { + public void accept(Visitor v) { + v.genericTransistor(d.name, d.drain, d.gate, d.source, d.bulk, + d.length, d.width, d.type, d.parameters); + } + }; + } + + public void genericDiode(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double length, + final double width, + final double perimeter, + final double area, + final String type, + final Map parameters) { + DeviceProcessorInterface.Diode device = + new DeviceProcessorInterface.Diode(name, positive, negative, + length, width, perimeter, + area, type, parameters); + for (Iterator i = processors.iterator(); i.hasNext(); ) { + DeviceProcessorInterface dpi = (DeviceProcessorInterface) i.next(); + device = dpi.processDiode(device); + } + final DeviceProcessorInterface.Diode d = device; + result = new AbstractDevice() { + public void accept(Visitor v) { + v.genericDiode(d.name, d.positive, d.negative, d.length, + d.width, d.perimeter, d.area, d.type, + d.parameters); + } + }; + } + + public void genericResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double conductance, + final Map parameters) { + DeviceProcessorInterface.Resistor device = + new DeviceProcessorInterface.Resistor(name, node1, node2, + conductance, parameters); + for (Iterator i = processors.iterator(); i.hasNext(); ) { + DeviceProcessorInterface dpi = (DeviceProcessorInterface) i.next(); + device = dpi.processResistor(device); + } + final DeviceProcessorInterface.Resistor d = device; + result = new AbstractDevice() { + public void accept(Visitor v) { + v.genericResistor(d.name, d.node1, d.node2, d.conductance, + d.parameters); + } + }; + } + + public void genericCapacitor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double capacitance, + final Map parameters) { + DeviceProcessorInterface.Capacitor device = + new DeviceProcessorInterface.Capacitor(name, positive, negative, + capacitance, parameters); + for (Iterator i = processors.iterator(); i.hasNext(); ) { + DeviceProcessorInterface dpi = (DeviceProcessorInterface) i.next(); + device = dpi.processCapacitor(device); + } + final DeviceProcessorInterface.Capacitor d = device; + result = new AbstractDevice() { + public void accept(Visitor v) { + v.genericCapacitor(d.name, d.positive, d.negative, + d.capacitance, d.parameters); + } + }; + } + + public void genericInductor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double inductance, + final Map parameters) { + DeviceProcessorInterface.Inductor device = + new DeviceProcessorInterface.Inductor(name, positive, negative, + inductance, parameters); + for (Iterator i = processors.iterator(); i.hasNext(); ) { + DeviceProcessorInterface dpi = (DeviceProcessorInterface) i.next(); + device = dpi.processInductor(device); + } + final DeviceProcessorInterface.Inductor d = device; + result = new AbstractDevice() { + public void accept(Visitor v) { + v.genericInductor(d.name, d.positive, d.negative, d.inductance, + d.parameters); + } + }; + } + + public void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters) { + DeviceProcessorInterface.Call device = + new DeviceProcessorInterface.Call(name, circuit, + nodes, parameters); + for (Iterator i = processors.iterator(); i.hasNext(); ) { + DeviceProcessorInterface dpi = (DeviceProcessorInterface) i.next(); + device = dpi.processCall(device); + } + final DeviceProcessorInterface.Call d = device; + result = new AbstractDevice() { + public void accept(Visitor v) { + v.subcircuitCall(d.name, d.circuit, d.nodes, d.parameters); + } + }; + } + + public DeviceProcessor(final AbstractNetlist netlist) { + this.netlist = netlist; + this.processors = new LinkedList(); + } + + public void appendProcessor(final DeviceProcessorInterface dpi) { + processors.addLast(dpi); + } + + public void prependProcessor(final DeviceProcessorInterface dpi) { + processors.addFirst(dpi); + } + + public void setNetlist(final AbstractNetlist netlist) { + this.netlist = netlist; + for (Iterator i = processors.iterator(); i.hasNext(); ) { + DeviceProcessorInterface dpi = (DeviceProcessorInterface) i.next(); + dpi.processCell(getName()); + } + } + + public AbstractNodeIterator getInputNodes() { + return netlist.getInputNodes(); + } + + public AbstractNodeIterator getOutputNodes() { + return netlist.getOutputNodes(); + } + + public HierName getName() { + return netlist.getName(); + } + + public AbstractNodeIterator getNodes() { + return netlist.getNodes(); + } + + public AbstractDeviceIterator getDevices() { + final AbstractDeviceIterator devices = netlist.getDevices(); + return new AbstractDeviceIterator() { + public boolean hasNext() { + return devices.hasNext(); + } + public AbstractDevice next() { + final AbstractDevice d = devices.next(); + d.accept(DeviceProcessor.this); + return result; + } + }; + } + + public AbstractNetlistIterator getSubcircuits() { + return netlist.getSubcircuits(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessorInterface.java new file mode 100644 index 0000000000..6496f03e94 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/DeviceProcessorInterface.java @@ -0,0 +1,160 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.Collection; +import java.util.Map; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; + +/** + * Extend this class by override one or more of the process functions. This is + * meant to be used in conjunction with DeviceProcessor. + */ +public class DeviceProcessorInterface { + public static class Transistor { + public HierName name; + public AbstractNode drain, gate, source, bulk; + public double length, width; + public String type; + public Map parameters; + public Transistor(final HierName name, final AbstractNode drain, + final AbstractNode gate, final AbstractNode source, + final AbstractNode bulk, final double length, + final double width, final String type, + final Map parameters) { + this.name = name; + this.drain = drain; + this.gate = gate; + this.source = source; + this.bulk = bulk; + this.length = length; + this.width = width; + this.type = type; + this.parameters = parameters; + } + } + + public Transistor processTransistor(final Transistor device) { + return device; + } + + public static class Diode { + public HierName name; + public AbstractNode positive, negative; + public double length, width; + public double perimeter, area; + public String type; + public Map parameters; + public Diode(final HierName name, final AbstractNode positive, + final AbstractNode negative, final double length, + final double width, final double perimeter, + final double area, final String type, + final Map parameters) { + this.name = name; + this.positive = positive; + this.negative = negative; + this.length = length; + this.width = width; + this.perimeter = this.perimeter; + this.area = area; + this.type = type; + this.parameters = parameters; + } + } + + public Diode processDiode(final Diode device) { + return device; + } + + public static class Resistor { + public HierName name; + public AbstractNode node1, node2; + public double conductance; + public Map parameters; + public Resistor(final HierName name, final AbstractNode node1, + final AbstractNode node2, final double conductance, + final Map parameters) { + this.name = name; + this.node1 = node1; + this.node2 = node2; + this.conductance = conductance; + this.parameters = parameters; + } + } + + public Resistor processResistor(final Resistor device) { + return device; + } + + public static class Capacitor { + public HierName name; + public AbstractNode positive, negative; + public double capacitance; + public Map parameters; + public Capacitor(final HierName name, final AbstractNode positive, + final AbstractNode negative, final double capacitance, + final Map parameters) { + this.name = name; + this.positive = positive; + this.negative = negative; + this.capacitance = capacitance; + this.parameters = parameters; + } + } + + public Capacitor processCapacitor(final Capacitor device) { + return device; + } + + public static class Inductor { + public HierName name; + public AbstractNode positive, negative; + public double inductance; + public Map parameters; + public Inductor(final HierName name, final AbstractNode positive, + final AbstractNode negative, final double inductance, + final Map parameters) { + this.name = name; + this.positive = positive; + this.negative = negative; + this.inductance = inductance; + this.parameters = parameters; + } + } + + public Inductor processInductor(final Inductor device) { + return device; + } + + public static class Call { + public HierName name; + public AbstractNetlist circuit; + public AbstractNodeIterator nodes; + public Map parameters; + public Call(final HierName name, final AbstractNetlist circuit, + final AbstractNodeIterator nodes, final Map parameters) { + this.name = name; + this.circuit = circuit; + this.nodes = nodes; + this.parameters = parameters; + } + } + + public Call processCall(final Call device) { + return device; + } + + public void processCell(final HierName cell) { + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FactoryEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FactoryEmitter.java new file mode 100644 index 0000000000..45b58e90e9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FactoryEmitter.java @@ -0,0 +1,163 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.io.PrintWriter; +import java.io.Writer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.NetlistFormatter; +import com.avlsi.util.text.PrintfFormat; + +public class FactoryEmitter extends NetlistFormatter implements Visitor { + private final CDLFactoryInterface out; + private final PrintfFormat fmt; + + public FactoryEmitter(final CDLFactoryInterface out) { + this(out, null); + } + + public FactoryEmitter(final CDLFactoryInterface out, + final PrintfFormat fmt) { + this.out = out; + this.fmt = fmt; + } + + private HierName node(final AbstractNode n) { + return n.getCanonicalName(); + } + + private HierName[] node(final AbstractNodeIterator nodes) { + final Collection result = new ArrayList(); + while (nodes.hasNext()) { + result.add(node(nodes.next())); + } + return (HierName[]) result.toArray(new HierName[0]); + } + + private String[] stringNode(final AbstractNodeIterator nodes) { + final Collection result = new ArrayList(); + while (nodes.hasNext()) { + result.add(node(nodes.next()).getCadenceString()); + } + return (String[]) result.toArray(new String[0]); + } + + private CDLLexer.InfoToken toToken(final double val) { + return new CDLLexer.SimpleToken(new Double(val)); + } + + private CDLLexer.InfoToken toToken(final Double val) { + return new CDLLexer.SimpleToken(val, fmt == null ? val.toString() : + fmt.sprintf(val)); + } + + private Map keypair(Map parameters) { + final Map result = new LinkedHashMap(); + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + Double val = (Double) entry.getValue(); + result.put(key, toToken(val)); + } + return result; + } + + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + out.makeTransistor(name, type, node(source), node(drain), + node(gate), node(bulk), + toToken(width), toToken(length), + keypair(parameters), NullEnvironment.getInstance()); + + } + + public void genericDiode(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double length, + final double width, + final double perimeter, + final double area, + final String type, + final Map parameters) { } + + public void genericResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double conductance, + final Map parameters) { + out.makeResistor(name, node(node1), node(node2), + toToken(1 / conductance), keypair(parameters), + NullEnvironment.getInstance()); + } + + public void genericCapacitor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double capacitance, + final Map parameters) { + out.makeCapacitor(name, node(positive), node(negative), + toToken(capacitance), keypair(parameters), + NullEnvironment.getInstance()); + } + + public void genericInductor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double inductance, + final Map parameters) { } + + public void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters) { + out.makeCall(name, circuit.getName().getCadenceString(), + node(nodes), keypair(parameters), + NullEnvironment.getInstance()); + } + + public void subcktBegin(final AbstractNetlist netlist) { + out.beginSubcircuit(netlist.getName().getCadenceString(), + stringNode(netlist.getInputNodes()), + stringNode(netlist.getOutputNodes()), + Collections.EMPTY_MAP, + NullEnvironment.getInstance()); + } + + public void subcktEnd(final AbstractNetlist netlist) { + out.endSubcircuit(netlist.getName().getCadenceString(), + NullEnvironment.getInstance()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FoldTransistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FoldTransistor.java new file mode 100644 index 0000000000..ae574f0769 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/FoldTransistor.java @@ -0,0 +1,161 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.VisitorImpl; + +public class FoldTransistor implements AbstractNetlist { + private final AbstractNetlist netlist; + private final double cutoff, minsize; + + public FoldTransistor(final AbstractNetlist netlist, final double cutoff, + final double minsize) { + this.netlist = netlist; + this.cutoff = cutoff; + this.minsize = minsize; + } + +/* + public static void main(String file) { + FileReader cdlFile = new FileReader(file); + final CDLLexer lexer = new CDLLexer(cdlFile); + final CDLParser parser = new CDLParser(lexer); + parser.setASTNodeClass(CDLParser.ASTWithToken.class.getName()); + try { + parser.goal(); + } catch (TokenStreamException e) { + throw new SemanticException("Error parsing netlist block" + e); + } + final AST ast = parser.getAST(); + final CDLWalker walker = new CDLWalker(); + final NetlistBlockFactory factory = new NetlistBlockFactory(); + walker.goal(ast, env, factory); + } +*/ + + private class FoldVisitor extends VisitorImpl { + private final List more; + public FoldVisitor(final List more) { + this.more = more; + } + private AbstractDevice transistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + return new AbstractDevice() { + public void accept(final Visitor visitor) { + visitor.genericTransistor(name, drain, gate, source, bulk, + length, width, type, parameters); + } + }; + } + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + if (width <= 0) { + System.err.println("Zero width transistor: " + name + " w=" + width + " l=" + length); + return; + } + String n = name.getCadenceString(); + double w = width; + int k = 0; + while (w > cutoff) { + final HierName newName = + HierName.makeHierName(n + "[" + k + "]"); + double size = cutoff; + if (w < cutoff + minsize) { + size = w / 2; + } + w -= size; + more.add(transistor(newName, drain, gate, source, bulk, + length, size, type, parameters)); + k++; + } + + if (w > 0) { + if (w < minsize && k > 0) { + System.err.println("Cannot meet maximum and minimum cutoff size requirements: w=" + width + " max=" + cutoff + " min=" + minsize); + } + final HierName newName = HierName.makeHierName(n + "[" + k + "]"); + more.add(transistor(newName, drain, gate, source, bulk, + length, w, type, parameters)); + } + } + } + + public AbstractNodeIterator getInputNodes() { + return netlist.getInputNodes(); + } + public AbstractNodeIterator getOutputNodes() { + return netlist.getOutputNodes(); + } + public HierName getName() { + return netlist.getName(); + } + public AbstractNodeIterator getNodes() { + return netlist.getNodes(); + } + public AbstractDeviceIterator getDevices() { + final AbstractDeviceIterator devices = netlist.getDevices(); + return new AbstractDeviceIterator() { + ArrayList more = new ArrayList(); + AbstractDevice nextDevice = null; + public boolean hasNext() { + if (!more.isEmpty()) { + return true; + } else if (devices.hasNext()) { + nextDevice = devices.next(); + more.clear(); + nextDevice.accept(new FoldVisitor(more)); + if (!more.isEmpty()) nextDevice = null; + return true; + } else { + return false; + } + } + public AbstractDevice next() { + if (!more.isEmpty()) { + return (AbstractDevice) more.remove(0); + } else if (nextDevice != null) { + final AbstractDevice tmp = nextDevice; + nextDevice = null; + return tmp; + } else { + throw new NoSuchElementException(); + } + } + }; + } + public AbstractNetlistIterator getSubcircuits() { + return netlist.getSubcircuits(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NetlistFormatter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NetlistFormatter.java new file mode 100644 index 0000000000..b6fef1459e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NetlistFormatter.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.Visitor; + +public class NetlistFormatter { + public void subcktBegin(final AbstractNetlist circuit) {} + public void subcktEnd(final AbstractNetlist circuit) {} + + public void deviceBegin(final AbstractDevice device) {} + public void deviceEnd(final AbstractDevice device) {} + + public void devicesBegin() {} + public void devicesEnd() {} + + public void format(final AbstractNetlist netlist, final Visitor visitor, + final boolean recursive) { + subcktBegin(netlist); + + if (recursive) { + for (AbstractNetlistIterator i = netlist.getSubcircuits(); + i.hasNext();) { + AbstractNetlist subckt = i.next(); + format(subckt, visitor); + } + } + + devicesBegin(); + for (AbstractDeviceIterator i = netlist.getDevices(); i.hasNext();) { + AbstractDevice device = i.next(); + deviceBegin(device); + device.accept(visitor); + deviceEnd(device); + } + devicesEnd(); + subcktEnd(netlist); + } + + public void format(final AbstractNetlist netlist, final Visitor visitor) { + format(netlist, visitor, true); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NumberedNodeNetlist.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NumberedNodeNetlist.java new file mode 100644 index 0000000000..09b3996d7c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/NumberedNodeNetlist.java @@ -0,0 +1,320 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; + +import java.util.Map; +import java.util.HashMap; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class NumberedNodeNetlist implements AbstractNetlist { + + private final Map m_nameToNumber; + + private final AbstractNetlist m_Wrapped; + + private final class Device implements AbstractDevice { + private final class DeviceVisitor implements Visitor { + + private final Map m_nameToNumber; + private final Visitor m_Visitor; + + public DeviceVisitor( final Map nameToNumber, final Visitor visitor ) { + + m_nameToNumber = nameToNumber; + m_Visitor = visitor; + + } + + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + m_Visitor.genericTransistor( name, + new Node( m_nameToNumber, drain ), + new Node( m_nameToNumber, gate ), + new Node( m_nameToNumber, source ), + new Node( m_nameToNumber, bulk ), + length, + width, + type, + parameters ); + + } + + + public void genericDiode(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double length, + final double width, + final double perimeter, + final double area, + final String type, + final Map parameters) { + m_Visitor.genericDiode( name, + new Node( m_nameToNumber, positive ), + new Node( m_nameToNumber, negative ), + length, + width, + perimeter, + area, + type, + parameters ); + } + + + public void genericResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double conductance, + final Map parameters) { + m_Visitor.genericResistor( name, + new Node( m_nameToNumber, node1 ), + new Node( m_nameToNumber, node2 ), + conductance, + parameters ); + } + + + public void genericCapacitor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double capacitance, + final Map parameters) { + m_Visitor.genericCapacitor( name, + new Node( m_nameToNumber, positive ), + new Node( m_nameToNumber, negative ), + capacitance, + parameters ); + } + + + public void genericInductor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double inductance, + final Map parameters) { + m_Visitor.genericInductor( name, + new Node( m_nameToNumber, positive ), + new Node( m_nameToNumber, negative ), + inductance, + parameters ); + } + + + public void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters) { + final AbstractNodeIterator portIter = new NodeIterator( m_nameToNumber, nodes ); + m_Visitor.subcircuitCall( name, + circuit, + portIter, + parameters ); + } + } + + private final Map m_NameToNumber; + private final AbstractDevice m_InnerDevice; + + public Device( final Map nameToNumber, AbstractDevice innerDevice ) { + m_NameToNumber = nameToNumber; + m_InnerDevice = innerDevice; + } + + public void accept(final Visitor visitor) { + m_InnerDevice.accept( new DeviceVisitor( m_NameToNumber, visitor ) ); + } + } + + private final class Node implements AbstractNode { + + private final int m_NodeNumber; + private final AbstractNode m_Wrapped; + private final Map m_NameToNumber; + + + public Node( Map nameToNumber, AbstractNode wrapped ) { + m_Wrapped = wrapped; + + m_NameToNumber = nameToNumber; + + final Integer nodeNumber = ( Integer ) nameToNumber.get( wrapped.getCanonicalName() ); + + m_NodeNumber = nodeNumber.intValue(); + + + + } + + + public HierName getCanonicalName() { + return HierName.makeHierName( String.valueOf( m_NodeNumber ) ); + } + + public Iterator getAliases() { + return new Iterator() { + + final Iterator m_innerIter = m_Wrapped.getAliases(); + + boolean m_didNumberAlias = false; + + final HierName m_NumberAlias = getCanonicalName(); + + public boolean hasNext() { + return ( ( ! m_didNumberAlias ) || ( m_innerIter.hasNext() ) ); + } + + public Object next() { + if ( m_didNumberAlias ) { + return m_innerIter.next(); + } + else { + m_didNumberAlias = true; + return m_NumberAlias; + } + } + + public void remove() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + + }; + } + + public AbstractDeviceIterator getDevices() { + return new AbstractDeviceIterator() { + private final AbstractDeviceIterator m_InnerIter = m_Wrapped.getDevices(); + private final Map nameToNumber = m_NameToNumber; + + public final boolean hasNext() { + return m_InnerIter.hasNext(); + } + + public AbstractDevice next() { + return new Device( nameToNumber, m_InnerIter.next() ); + } + + }; + } + + } + + private final class NodeIterator implements AbstractNodeIterator { + + private final AbstractNodeIterator m_Wrapped; + private final Map m_NameMap; + + public NodeIterator( Map nameMap, AbstractNodeIterator wrapped ) { + m_Wrapped = wrapped; + m_NameMap = nameMap; + } + + public boolean hasNext() { + return m_Wrapped.hasNext(); + } + + public AbstractNode next() { + return new Node( m_NameMap, m_Wrapped.next() ); + } + + + + } + + public NumberedNodeNetlist( AbstractNetlist wrapped ) { + + m_Wrapped = wrapped; + + m_nameToNumber = new HashMap(); + + final AbstractNodeIterator nodeIter = m_Wrapped.getNodes(); + + int counter = 0; + + while ( nodeIter.hasNext() ) { + + final AbstractNode currNode = nodeIter.next(); + + final HierName currNodeName = currNode.getCanonicalName(); + + m_nameToNumber.put( currNodeName, new Integer( counter ) ); + ++counter; + + } + + } + + public AbstractNodeIterator getInputNodes() { + return new NodeIterator( m_nameToNumber, m_Wrapped.getInputNodes() ); + } + + + public AbstractNodeIterator getOutputNodes() { + return new NodeIterator( m_nameToNumber, m_Wrapped.getOutputNodes() ); + } + + + public HierName getName() { + return m_Wrapped.getName(); + } + + + public AbstractNodeIterator getNodes() { + return new NodeIterator( m_nameToNumber, m_Wrapped.getNodes() ); + } + + + public AbstractDeviceIterator getDevices() { + return new AbstractDeviceIterator() { + private final Map nameToNumber = m_nameToNumber; + private final AbstractDeviceIterator m_InnerIter = m_Wrapped.getDevices(); + + public boolean hasNext() { + return m_InnerIter.hasNext(); + } + + public AbstractDevice next() { + return new Device( m_nameToNumber, m_InnerIter.next() ); + } + + }; + } + + public AbstractNetlistIterator getSubcircuits() { + return new AbstractNetlistIterator() { + private AbstractNetlistIterator m_InnerIter = m_Wrapped.getSubcircuits(); + + public boolean hasNext() { + return m_InnerIter.hasNext(); + } + + public AbstractNetlist next() { + return new NumberedNodeNetlist( m_InnerIter.next() ); + } + + }; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractDeviceIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractDeviceIterator.java new file mode 100644 index 0000000000..a22ab868f9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractDeviceIterator.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.Iterator; + +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; + +public class SimpleAbstractDeviceIterator implements AbstractDeviceIterator { + protected final Iterator iterator; + + public SimpleAbstractDeviceIterator(Iterator iterator) { + this.iterator = iterator; + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public AbstractDevice next() { + return (AbstractDevice) iterator.next(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNetlistIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNetlistIterator.java new file mode 100644 index 0000000000..ea09261838 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNetlistIterator.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.Iterator; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; + +public class SimpleAbstractNetlistIterator implements AbstractNetlistIterator { + protected final Iterator iterator; + + public SimpleAbstractNetlistIterator(Iterator iterator) { + this.iterator = iterator; + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public AbstractNetlist next() { + return (AbstractNetlist) iterator.next(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNodeIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNodeIterator.java new file mode 100644 index 0000000000..63e7e38a65 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SimpleAbstractNodeIterator.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.Iterator; + +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; + +public class SimpleAbstractNodeIterator implements AbstractNodeIterator { + protected final Iterator iterator; + + public SimpleAbstractNodeIterator(Iterator iterator) { + this.iterator = iterator; + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public AbstractNode next() { + return (AbstractNode) iterator.next(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SkillEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SkillEmitter.java new file mode 100644 index 0000000000..c6c88a1d0e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/SkillEmitter.java @@ -0,0 +1,161 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.io.PrintWriter; +import java.io.Writer; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.NetlistFormatter; + +public class SkillEmitter extends NetlistFormatter implements Visitor { + private PrintWriter w; + + public SkillEmitter(Writer w) { + this.w = new PrintWriter(w); + } + + private String stringNode(AbstractNode node) { + return "\"" + node.getCanonicalName().getCadenceString() + "\""; + } + + private void keypair(Map parameters) { + Iterator i = parameters.entrySet().iterator(); + + while (i.hasNext()) { + Map.Entry entry = (Map.Entry) i.next(); + String key = (String) entry.getKey(); + Double val = (Double) entry.getValue(); + w.print(" beginlist " + key + " " + val + " endlist"); + } + } + + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + w.print("beginlist transistor " + + "M" + name.getCadenceString() + " " + + stringNode(drain) + " " + + stringNode(gate) + " " + + stringNode(source) + " " + + stringNode(bulk) + " " + + type + " beginlist " + + "beginlist width " + width + " endlist " + + "beginlist length " + length + " endlist" + ); + + keypair(parameters); + + w.println(" endlist endlist"); + } + + public void genericDiode(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double length, + final double width, + final double perimeter, + final double area, + final String type, + final Map parameters) { } + + public void genericResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double conductance, + final Map parameters) { } + + public void genericCapacitor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double capacitance, + final Map parameters) { } + + public void genericInductor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double inductance, + final Map parameters) { } + + public void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters) { + w.print("beginlist subcell " + name.getCadenceString()); + + for (AbstractNodeIterator formal = circuit.getInputNodes(); + formal.hasNext() && nodes.hasNext();) { + w.print(" beginlist"); + w.print(" " + stringNode(nodes.next())); + w.print(" " + stringNode(formal.next())); + w.print(" endlist"); + } + + for (AbstractNodeIterator formal = circuit.getOutputNodes(); + formal.hasNext() && nodes.hasNext();) { + w.print(" beginlist"); + w.print(" " + stringNode(nodes.next())); + w.print(" " + stringNode(formal.next())); + w.print(" endlist"); + } + + keypair(parameters); + + w.println(" endlist"); + } + + public void devicesBegin() { + w.println("beginlist"); + } + + public void devicesEnd() { + w.println("endlist"); + } + + /* + public void subcktBegin(final AbstractNetlist netlist) { + + w.print(".SUBCKT " + netlist.getName().getCadenceString()); + + AbstractNodeIterator i; + i = netlist.getOutputNodes(); + while (i.hasNext()) { + w.print(" " + stringNode(i.next())); + } + + i = netlist.getInputNodes(); + if (i.hasNext()) { + w.print(" /"); + while (i.hasNext()) { + w.print(" " + stringNode(i.next())); + } + } + + w.println(); + } + + public void subcktEnd(final AbstractNetlist netlist) { + w.println(".ENDS"); + } + */ +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/VisitorImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/VisitorImpl.java new file mode 100644 index 0000000000..5df2df7549 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/VisitorImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl; + +import java.util.Collection; +import java.util.Map; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; + +/** + * Simple visitor implementation that can be inherited to easily override a + * couple of methods. All methods are empty. + */ +public class VisitorImpl implements Visitor { + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { } + + public void genericDiode(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double length, + final double width, + final double perimeter, + final double area, + final String type, + final Map parameters) { } + + public void genericResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double conductance, + final Map parameters) { } + + public void genericCapacitor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double capacitance, + final Map parameters) { } + + public void genericInductor(final HierName name, + final AbstractNode positive, + final AbstractNode negative, + final double inductance, + final Map parameters) { } + + public void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters) { } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/CDLReaderToNetlist.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/CDLReaderToNetlist.java new file mode 100644 index 0000000000..904248c38a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/CDLReaderToNetlist.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.netlist.impl.simple; + + +import java.io.Reader; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; + +import com.avlsi.netlist.AbstractNetlist; + +import com.avlsi.netlist.impl.simple.SimpleNetlistFactory; + + + +import antlr.collections.AST; + +public class CDLReaderToNetlist { + + public static SimpleNetlistFactory readCDL( final Reader r ) + throws RecognitionException, TokenStreamException + { + final SimpleNetlistFactory factory = new SimpleNetlistFactory(); + ReadCDLIntoFactory.readCDL( r, factory ); + return factory; + } + + + public static AbstractNetlist readCDL( final Reader r, + final String rootCellName ) + throws RecognitionException, TokenStreamException + { + + final SimpleNetlistFactory factory = readCDL( r ); + + final AbstractNetlist ret = factory.getNetlist( rootCellName ); + + return ret; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Device.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Device.java new file mode 100644 index 0000000000..5283128244 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Device.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl.simple; + +import com.avlsi.file.common.HierName; + +import com.avlsi.netlist.AbstractDevice; + +import com.avlsi.netlist.impl.simple.Net; + +abstract class Device implements AbstractDevice { + + private final HierName m_Name; + + Device( final HierName name ) { + m_Name = name; + } + + public HierName getName() { + return m_Name; + } + + public abstract void replaceNet( final Net oldNet, final Net newNet ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/FET.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/FET.java new file mode 100644 index 0000000000..f91d7c3561 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/FET.java @@ -0,0 +1,110 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.netlist.impl.simple; + +import java.util.HashMap; +import java.util.Map; +import java.util.Collections; + +import com.avlsi.util.debug.Debug; + +import com.avlsi.file.common.HierName; + +import com.avlsi.netlist.Visitor; + +import com.avlsi.netlist.impl.simple.Device; +import com.avlsi.netlist.impl.simple.Net; + +class FET extends Device { + + private Net m_Drain; + private Net m_Gate; + private Net m_Source; + private Net m_Bulk; + + private final double m_Length; + private final double m_Width; + private final String m_Type; + + private final Map m_Parameters; + + public FET( final HierName name, + final Net drain, + final Net gate, + final Net source, + final Net bulk, + final double length, + final double width, + final String type, + final Map params ) { + super( name ); + + m_Drain = drain; + m_Gate = gate; + m_Source = source; + m_Bulk = bulk; + + m_Length = length; + m_Width = width; + m_Type = type; + m_Parameters = params; + + m_Drain.addDevice( this ); + m_Gate.addDevice( this ); + m_Source.addDevice( this ); + m_Bulk.addDevice( this ); + } + + public final void replaceNet( final Net oldNet, final Net newNet ) { + boolean foundNet = false; + if ( m_Drain == oldNet ) { + m_Drain = newNet; + foundNet = true; + } + if ( m_Gate == oldNet ) { + m_Gate = newNet; + foundNet = true; + } + if ( m_Source == oldNet ) { + m_Source = newNet; + foundNet = true; + } + if ( m_Bulk == oldNet ) { + m_Bulk = newNet; + foundNet = true; + } + Debug.assertTrue( foundNet ); + oldNet.removeDevice( this ); + newNet.addDevice( this ); + } + + public final void accept(final Visitor visitor) { + final Map myParams; + + if ( m_Parameters == null ) { + myParams = Collections.EMPTY_MAP; + } + else { + myParams = new HashMap( m_Parameters ); + } + + visitor.genericTransistor( getName(), + m_Drain, + m_Gate, + m_Source, + m_Bulk, + m_Length, + m_Width, + m_Type, + myParams ); + } + + + + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Net.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Net.java new file mode 100644 index 0000000000..2c2f10447a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/Net.java @@ -0,0 +1,89 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.netlist.impl.simple; + +import java.util.List; +import java.util.Map; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Collections; + +import com.avlsi.file.common.HierName; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractDeviceIterator; + +import com.avlsi.netlist.impl.SimpleAbstractDeviceIterator; + +import com.avlsi.netlist.impl.simple.Device; + + +class Net implements AbstractNode { + + private List m_Names; + private Map m_Devices; + + public Net( final HierName name ) { + m_Names = new ArrayList(); + m_Devices = null; + m_Names.add( name ); + } + + public boolean isAlias( final HierName name ) { + return ( m_Names.indexOf( name ) != -1 ); + } + + public void addAlias( final HierName name ) { + if ( ! ( isAlias( name ) ) ) { + m_Names.add( name ); + } + } + + public void addDevice( final Device newDevice ) { + if ( m_Devices == null ) { + m_Devices = new HashMap(); + } + m_Devices.put( newDevice.getName(), newDevice ); + } + + public void removeDevice( final Device devToRemove ) { + if ( m_Devices != null ) { + m_Devices.remove( devToRemove.getName() ); + } + } + + public void setCanonicalName( final HierName name ) { + final int existingIndex = m_Names.indexOf( name ); + if ( existingIndex != -1 ) { + m_Names.remove( existingIndex ); + } + m_Names.add( 0, name ); + } + + public HierName getCanonicalName() { + return ( HierName )m_Names.get( 0 ); + } + + public Iterator getAliases() { + return m_Names.iterator(); + } + + public AbstractDeviceIterator getDevices() { + final Iterator i; + if ( m_Devices != null ) { + i = m_Devices.values().iterator(); + } + else { + i = Collections.EMPTY_SET.iterator(); + } + return new SimpleAbstractDeviceIterator( i ); + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlist.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlist.java new file mode 100644 index 0000000000..c394ef269e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlist.java @@ -0,0 +1,125 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.netlist.impl.simple; + + +import java.util.Map; +import java.util.List; +import java.util.Iterator; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Collections; + +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.common.HierName; + +import com.avlsi.netlist.AbstractNetlist; + +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNetlistIterator; + +import com.avlsi.netlist.impl.SimpleAbstractNodeIterator; +import com.avlsi.netlist.impl.SimpleAbstractDeviceIterator; +import com.avlsi.netlist.impl.SimpleAbstractNetlistIterator; + +import com.avlsi.netlist.impl.simple.Net; + +public final class SimpleNetlist implements AbstractNetlist{ + + private final HierName m_Name; + + private final Map m_DeviceMap; + private final Map m_NetMap; + + private final List m_Inputs; + private final List m_Outputs; + + public SimpleNetlist( final HierName name, final String[] inputs, final String[] outputs ) { + m_Name = name; + m_DeviceMap = new HashMap(); + m_NetMap = new HashMap(); + + m_Inputs = new ArrayList( inputs.length ); + m_Outputs = new ArrayList( outputs.length ); + + int i; + try { + for ( i = 0 ; i < inputs.length ; ++i ) { + final Net currNode = + makeNode( HierName.makeHierName( inputs[i], '.' ) ); + m_Inputs.add( currNode ); + } + + for ( i = 0 ; i < outputs.length ; ++i ) { + final Net currNode = + makeNode( HierName.makeHierName( outputs[i], '.' ) ); + m_Outputs.add( currNode ); + } + } + catch ( InvalidHierNameException e ) { + throw (IllegalArgumentException) + new IllegalArgumentException().initCause(e); + } + + } + + public Net makeNode( HierName name ) { + Net ret = ( Net ) m_NetMap.get( name ); + if ( ret == null ) { + ret = new Net( name ); + m_NetMap.put( name, ret ); + } + return ret; + } + + public void addDevice( Device newDevice ) { + m_DeviceMap.put( newDevice.getName(), newDevice ); + } + + public int hashCode( ) { + return getName().hashCode(); + } + + public boolean equals( final Object other ) { + if ( other instanceof SimpleNetlist ) { + final SimpleNetlist otherNetlist = ( SimpleNetlist ) other; + return getName().equals( otherNetlist.getName() ); + } + else { + return false; + } + } + + public AbstractNodeIterator getInputNodes() { + return new SimpleAbstractNodeIterator( m_Inputs.iterator() ); + } + + public AbstractNodeIterator getOutputNodes() { + return new SimpleAbstractNodeIterator( m_Outputs.iterator() ); + } + + public HierName getName() { + return m_Name; + } + + public AbstractNodeIterator getNodes() { + return new SimpleAbstractNodeIterator( m_NetMap.values().iterator() ); + } + + public AbstractDeviceIterator getDevices() { + return new SimpleAbstractDeviceIterator( m_DeviceMap.values().iterator() ); + } + + public AbstractNetlistIterator getSubcircuits() { + return new SimpleAbstractNetlistIterator( Collections.EMPTY_SET.iterator() ); + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlistFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlistFactory.java new file mode 100644 index 0000000000..39ac0295a1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SimpleNetlistFactory.java @@ -0,0 +1,205 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.netlist.impl.simple; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Collection; + +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.common.HierName; + +import com.avlsi.cast.impl.Environment; + +import com.avlsi.file.cdl.parser.CDLLexer; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; + +import com.avlsi.netlist.impl.SimpleAbstractNetlistIterator; + +import com.avlsi.netlist.impl.simple.FET; +import com.avlsi.netlist.impl.simple.SubCircuit; + +public class SimpleNetlistFactory implements CDLFactoryInterface { + + private Map m_CircuitMap; + + public SimpleNetlist m_CurrNetlist; + + public SimpleNetlistFactory() { + m_CircuitMap = new HashMap(); + m_CurrNetlist = null; + } + + + private Map convertParameterMap( final Map parameters, + final Environment env ) { + final Map ret = new HashMap(); + final Iterator i = parameters.entrySet().iterator(); + while ( i.hasNext() ) { + final Map.Entry currEntry = ( Map.Entry ) i.next(); + final String key = ( String ) currEntry.getKey(); + final Double val = + ( ( CDLLexer.InfoToken ) currEntry.getValue() ).getValue( env ); + if ( val != null ) { + ret.put( key, val ); + } + } + return ret; + } + + public AbstractNetlist getNetlist( final String rootCellName ) { + return ( AbstractNetlist ) + m_CircuitMap.get( rootCellName ); + + } + + public AbstractNetlistIterator getAllNetlists( ) { + final Collection circuits = m_CircuitMap.values(); + return new SimpleAbstractNetlistIterator( circuits.iterator()); + } + + public void makeResistor( final HierName name, + final HierName n1, + final HierName n2, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + throw new RuntimeException(); + } + + + public void makeCapacitor( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + throw new RuntimeException(); + } + + + public void makeTransistor( final HierName name, + final String type, + final HierName ns, + final HierName nd, + final HierName ng, + final HierName nb, + final CDLLexer.InfoToken w, + final CDLLexer.InfoToken l, + final Map parameters, + final Environment env ) { + if ( m_CurrNetlist != null ) { + final Double wVal = w.getValue( env ); + final Double lVal = l.getValue( env ); + if ( ( wVal != null ) && ( lVal != null ) ) { + final FET f = new FET( name, + m_CurrNetlist.makeNode( nd ), + m_CurrNetlist.makeNode( ng ), + m_CurrNetlist.makeNode( ns ), + m_CurrNetlist.makeNode( nb ), + lVal.doubleValue(), + wVal.doubleValue(), + type, + convertParameterMap( parameters, env ) ); + m_CurrNetlist.addDevice( f ); + } + } + } + + + public void makeDiode( final HierName name, + final String type, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + throw new RuntimeException(); + } + + + public void makeInductor( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + throw new RuntimeException(); + } + + + public void makeBipolar( final HierName name, + final String type, + final HierName nc, + final HierName nb, + final HierName ne, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + throw new RuntimeException(); + } + + + public void makeCall( final HierName name, + final String subName, + final HierName[] args, + final Map parameters, + final Environment env ) { + if ( m_CurrNetlist != null ) { + final SimpleNetlist subCircuit = + ( SimpleNetlist ) m_CircuitMap.get( subName ); + if ( subCircuit != null ) { + final List nodes = new ArrayList( args.length ); + int i = 0; + for ( i = 0 ; i < args.length ; ++i ) { + nodes.add( m_CurrNetlist.makeNode( args[i] ) ); + } + final SubCircuit s = + new SubCircuit( name, + subCircuit, + nodes, + convertParameterMap( parameters, env ) ); + m_CurrNetlist.addDevice( s ); + } + } + } + + + public void beginSubcircuit( final String subName, + final String[] in, + final String[] out, + final Map parameters, + final Environment env ) { + try { + m_CurrNetlist = + new SimpleNetlist( HierName.makeHierName( subName, '.' ), + in, + out ); + } + catch( InvalidHierNameException e ) { + throw (IllegalArgumentException) + new IllegalArgumentException().initCause(e); + } + + + } + + + public void endSubcircuit( final String subName, + final Environment env ) { + m_CircuitMap.put( m_CurrNetlist.getName().toString(), m_CurrNetlist ); + m_CurrNetlist = null; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SubCircuit.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SubCircuit.java new file mode 100644 index 0000000000..ba7bce6751 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/impl/simple/SubCircuit.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.impl.simple; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; +import java.util.ListIterator; + +import com.avlsi.util.debug.Debug; + +import com.avlsi.file.common.HierName; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; + +import com.avlsi.netlist.impl.SimpleAbstractNodeIterator; + +import com.avlsi.netlist.impl.simple.SimpleNetlist; +import com.avlsi.netlist.impl.simple.Device; +import com.avlsi.netlist.impl.simple.Net; + +class SubCircuit extends Device { + private final SimpleNetlist m_Circuit; + private final List m_Nodes; + private Map m_Params; + + public SubCircuit( final HierName name, + final SimpleNetlist circuit, + final List nodes ) { + super( name ); + m_Circuit = circuit; + m_Nodes = nodes; + m_Params = null; + + final ListIterator i = m_Nodes.listIterator(); + + while ( i.hasNext() ) { + final Net currNet = ( Net ) i.next() ; + currNet.addDevice( this ); + } + } + + public SubCircuit( final HierName name, + final SimpleNetlist circuit, + final List nodes, + final Map params ) { + this( name, circuit, nodes ); + m_Params = params; + } + + public final void accept(final Visitor visitor) { + final Map myParams; + + if ( m_Params == null ) { + myParams = Collections.EMPTY_MAP; + } + else { + myParams = new HashMap( m_Params ); + } + + visitor.subcircuitCall( getName(), + m_Circuit, + new SimpleAbstractNodeIterator(m_Nodes.iterator() ), + myParams ); + } + + public final void replaceNet( final Net oldNet, final Net newNet ) { + boolean foundNet = false; + final ListIterator nodeIter = m_Nodes.listIterator(); + + while ( nodeIter.hasNext() ) { + final Net currNet = ( Net ) nodeIter.next(); + if ( currNet == oldNet ) { + nodeIter.set( newNet ); + foundNet = true; + } + } + Debug.assertTrue( foundNet ); + oldNet.removeDevice( this ); + newNet.addDevice( this ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/ChildrenFirstNetlistIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/ChildrenFirstNetlistIterator.java new file mode 100644 index 0000000000..b9461f2beb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/ChildrenFirstNetlistIterator.java @@ -0,0 +1,142 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.util; + +import java.util.Stack; +import java.util.Set; +import java.util.HashSet; +import java.util.NoSuchElementException; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNetlistIterator; +import com.avlsi.netlist.AbstractDeviceIterator; + +import com.avlsi.netlist.util.SubcellIterator; + +/** + Iterator to iterate over all the abstract netlists + in a circuit hierarchy. Starting from a root circuit + all the instantiated sub circuits are enumerated such that + a sub circuit is enumerated after all the sub circuits it + instantiates are enumerated. + */ +public final class ChildrenFirstNetlistIterator + implements AbstractNetlistIterator { + + private static class StackFrame { + + private final AbstractNetlist m_Netlist; + private final SubcellIterator m_Iter; + + public StackFrame( final AbstractNetlist netlist ) { + m_Netlist = netlist; + m_Iter = new SubcellIterator( netlist.getDevices() ); + } + + public SubcellIterator getIter() { + return m_Iter; + } + + public AbstractNetlist getNetlist() { + return m_Netlist; + } + } + + private final Set m_VisitedSet; + private final Stack m_Stack; + + private AbstractNetlist m_NextNetlist; + + private void push( final AbstractNetlist netlist ) { + final StackFrame newFrame = new StackFrame( netlist ); + m_Stack.push( newFrame ); + } + + private SubcellIterator getTopIterator() { + final StackFrame topFrame = ( StackFrame ) m_Stack.peek(); + return topFrame.getIter(); + } + + private AbstractNetlist getTopNetlist() { + final StackFrame topFrame = ( StackFrame ) m_Stack.peek(); + return topFrame.getNetlist(); + } + + private boolean wasVisited( final AbstractNetlist netlist ) { + return m_VisitedSet.contains( netlist.getName() ); + } + + private void markAsVisited( final AbstractNetlist netlist ) { + m_VisitedSet.add( netlist.getName() ); + } + + /** + Constructs the iterator such that it will enumerate all the + circuits instantiated in the circuit hierarchy defined in + the specified netlist. + @param top The root netlist under which to enumerate all netlists. + */ + public ChildrenFirstNetlistIterator( final AbstractNetlist top ) { + m_VisitedSet = new HashSet(); + m_Stack = new Stack(); + push( top ); + m_NextNetlist = null; + } + + /** + Determines if there is another circuit in the enumeration. + @return true if there is another circuit in the enumeration. + false otherwise. + */ + public boolean hasNext() { + while ( ( m_NextNetlist == null ) && ( ! ( m_Stack.empty() ) ) ) { + final SubcellIterator currIter = getTopIterator(); + + AbstractNetlist instanceMaster = null; + + if ( currIter.hasNext() ) { + do { + final SubcellIterator.SubcellInstance instance = + currIter.next(); + instanceMaster = + instance.getInstantiatedNetlist(); + + } while ( ( currIter.hasNext() ) && + ( wasVisited( instanceMaster ) ) ); + } + if ( ( instanceMaster != null ) && + ( ! wasVisited( instanceMaster ) ) ) { + push( instanceMaster ); + } + else { + m_NextNetlist = getTopNetlist(); + m_Stack.pop(); + markAsVisited( m_NextNetlist ); + } + } + return m_NextNetlist != null; + } + + /** + Retrieves the next circuit from the enumeration. + @return The next circuit in the enumeration. + */ + public AbstractNetlist next() { + if ( hasNext() ) { + final AbstractNetlist ret = m_NextNetlist; + m_NextNetlist = null; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/CombiningNodeIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/CombiningNodeIterator.java new file mode 100644 index 0000000000..35c085c7aa --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/CombiningNodeIterator.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.netlist.util; + +import java.util.NoSuchElementException; + +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.AbstractNode; + +public class CombiningNodeIterator implements AbstractNodeIterator { + + + private final AbstractNodeIterator mFirst; + private final AbstractNodeIterator mSecond; + + public CombiningNodeIterator( AbstractNodeIterator first, + AbstractNodeIterator second ) { + mFirst = first; + mSecond = second; + } + + public boolean hasNext() { + return ( ( mSecond.hasNext() ) || ( mFirst.hasNext() ) ); + } + /** + @throws NoSuchElementException + */ + public AbstractNode next() { + if ( mFirst.hasNext() ) { + return mFirst.next(); + } + else { + return mSecond.next(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FETIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FETIterator.java new file mode 100644 index 0000000000..e2f78c4d02 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FETIterator.java @@ -0,0 +1,181 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +/** + An iterator to iterate over all subcell instances + in an iteration of AbstractDevices. + */ + +package com.avlsi.netlist.util; + +import java.util.Collections; +import java.util.Map; +import java.util.NoSuchElementException; + +import com.avlsi.file.common.HierName; + +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.Visitor; + +import com.avlsi.netlist.impl.VisitorImpl; + +public class FETIterator { + /** + A nice interface to an instantiation of a subcell. + */ + public static final class FET implements AbstractDevice { + private final HierName m_Name; + private final AbstractNode m_Drain; + private final AbstractNode m_Gate; + private final AbstractNode m_Source; + private final AbstractNode m_Bulk; + private final double m_Length; + private final double m_Width; + private final String m_Type; + private final Map m_Params; + + FET( final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters ) { + m_Name = name; + + m_Drain = drain; + m_Gate = gate; + m_Source = source; + m_Bulk = bulk; + + m_Length = length; + m_Width = width; + m_Type = type; + + m_Params = parameters; + + } + + /** + Retrieves the name of the instance. + @return The name of the instance. + */ + public HierName getName() { + return m_Name; + } + + public AbstractNode getDrain() { + return m_Drain; + } + + public AbstractNode getGate() { + return m_Gate; + } + + public AbstractNode getSource() { + return m_Source; + } + + public AbstractNode getBulk() { + return m_Bulk; + } + + public double getLength() { + return m_Length; + } + + public double getWidth() { + return m_Width; + } + + public String getType() { + return m_Type; + } + + /** + @return A map from String to Double that captures additional + parameters of the instantiation. + */ + public Map getParams() { + return Collections.unmodifiableMap( m_Params ); + } + + public void accept( final Visitor v ) { + + v.genericTransistor( m_Name, + m_Drain, + m_Gate, + m_Source, + m_Bulk, + m_Length, + m_Width, + m_Type, + m_Params ); + + } + } + + private FET m_CurrFET; + + private final AbstractDeviceIterator m_Iter; + + /** + Construcst a SubcellIterator that will iterate over + all the subcell instances that the specified + AbstractDeviceIterator returns. + @param iter Iterator to get AbstractDevices from. + */ + public FETIterator( final AbstractDeviceIterator iter ) { + m_Iter = iter; + m_CurrFET = null; + } + + public boolean hasNext() { + while ( ( m_CurrFET == null ) && ( m_Iter.hasNext() ) ) { + final AbstractDevice currDevice = m_Iter.next(); + + currDevice.accept( new VisitorImpl() { + public void genericTransistor(final HierName name, + final AbstractNode drain, + final AbstractNode gate, + final AbstractNode source, + final AbstractNode bulk, + final double length, + final double width, + final String type, + final Map parameters) { + m_CurrFET = new FET( name, + drain, + gate, + source, + bulk, + length, + width, + type, + parameters ); + } + } ); + + } + return m_CurrFET != null; + } + + public FET next() { + if ( hasNext() ) { + final FET ret = m_CurrFET; + m_CurrFET = null; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FlatteningIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FlatteningIterator.java new file mode 100644 index 0000000000..75e6b677d0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/FlatteningIterator.java @@ -0,0 +1,305 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.netlist.util; + +import com.avlsi.util.debug.Debug; + +import java.util.List; +import java.util.LinkedList; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.util.SubcellIterator; +import com.avlsi.netlist.util.CombiningNodeIterator; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.AbstractNode; + + + +public final class FlatteningIterator { + + + + public static final class FlatInstance { + private final List mPathToInstance; + private final AbstractNetlist mMasterNetlist; + + private FlatInstance( final List pathToInstance, + final AbstractNetlist masterNetlist ) { + mPathToInstance = pathToInstance; + mMasterNetlist = masterNetlist; + } + + public final List getPathToInstance( ) { + return mPathToInstance; + } + + public final AbstractNetlist getInstanceMasterNetlist( ) { + return mMasterNetlist; + } + + public static String pathToString( final List path, final String seperator ) { + final Iterator iter = path.iterator(); + final StringBuffer ret = new StringBuffer(); + boolean first = true; + + while ( iter.hasNext() ) { + final String currComponent = ( String ) iter.next(); + if ( ! first ) { + ret.append( seperator ); + } + first = false; + ret.append( currComponent ); + } + return ret.toString(); + } + + /*public final String getPathToInstanceAsString( final String seperator ) { + return pathToString( getPathToInstance(), seperator ); + } + + public final String getPathToInstanceAsString( ) { + return getPathToInstanceAsString( "." ); + }*/ + + public final String getCanonicalNodeName( final String nodeName, + final String hierarchySeperator ) { + final Iterator componentIter = mPathToInstance.iterator(); + + String ret = nodeName; + boolean done = false; + + if ( componentIter.hasNext() ) { + + PathComponent currComponent = null; + while ( ( componentIter.hasNext() ) && ( !done ) ) { + currComponent = ( PathComponent ) componentIter.next(); + + final AbstractNetlist currNetlist = currComponent.getComponentNetlist(); + + final AbstractNodeIterator portIter = + new CombiningNodeIterator( currNetlist.getInputNodes(), + currNetlist.getOutputNodes() ); + int nodeIndexInPortList = 0; + boolean nodeFoundInPortList = false; + + while ( ( portIter.hasNext() ) && ( !nodeFoundInPortList ) ) { + final AbstractNode currPortNode = portIter.next(); + final String currPortNodeName = + currPortNode.getCanonicalName().toString(); + if ( currPortNodeName.equals( ret ) ) { + nodeFoundInPortList = true; + } + else { + ++nodeIndexInPortList; + } + } + + if ( nodeFoundInPortList ) { + if ( componentIter.hasNext() ) { + final AbstractNodeIterator connectedNodes = + currComponent.getConnectedNodes(); + + int i; + + for ( i = 0 ; i < nodeIndexInPortList ; ++i ) { + connectedNodes.next(); + } + + final AbstractNode connectedNode = connectedNodes.next(); + + ret = connectedNode.getCanonicalName().toString(); + + } + else { + done = true; + } + } + else { + done = true; + } + + } + { + final String currComponentName = currComponent.getComponentName(); + if ( currComponentName != null ) { + ret = currComponentName + hierarchySeperator + ret; + } + } + + while ( componentIter.hasNext() ) { + final PathComponent curr = ( PathComponent ) componentIter.next(); + final String currComponentName = curr.getComponentName(); + if ( currComponentName != null ) { + ret = currComponentName + hierarchySeperator + ret; + } + else { + Debug.assertTrue( ! ( componentIter.hasNext() ) ) ; + } + } + } + return ret; + } + + } + + public interface PathComponent { + + String getComponentName(); + + AbstractNetlist getComponentNetlist(); + + AbstractNodeIterator getConnectedNodes(); + } + + private interface StackFrame extends PathComponent { + SubcellIterator getIter(); + } + + private static class RootFrame implements StackFrame { + + private final AbstractNetlist mRootNetlist; + private final SubcellIterator mIter; + + private RootFrame( final AbstractNetlist rootNetlist ) { + mRootNetlist = rootNetlist; + mIter = new SubcellIterator( getComponentNetlist().getDevices() ); + } + + public AbstractNetlist getComponentNetlist() { + return mRootNetlist; + } + + public String getComponentName() { + return null; + } + + public AbstractNodeIterator getConnectedNodes() { + return new AbstractNodeIterator() { + public boolean hasNext() { + return false; + } + + public AbstractNode next() { + throw new NoSuchElementException(); + } + }; + } + + public SubcellIterator getIter() { + return mIter; + } + } + + private static class StackFrameImpl implements StackFrame { + + private final SubcellIterator mIter; + + private final SubcellIterator.SubcellInstance mComponentInstance; + + + public String getComponentName() { + return mComponentInstance.getName().toString(); + } + + public AbstractNetlist getComponentNetlist() { + return mComponentInstance.getInstantiatedNetlist(); + } + + public AbstractNodeIterator getConnectedNodes() { + return mComponentInstance.getConnectedNodes(); + } + + public StackFrameImpl( final SubcellIterator.SubcellInstance componentInstance ) { + mComponentInstance = componentInstance; + mIter = new SubcellIterator( getComponentNetlist().getDevices() ); + } + + public SubcellIterator getIter() { + return mIter; + } + } + + private final LinkedList mStack; + + private AbstractNetlist mNextNetlist; + + private void push( final SubcellIterator.SubcellInstance componentInstance ) { + final StackFrame newFrame = new StackFrameImpl( componentInstance ); + push( newFrame ); + } + + private void push( final StackFrame frameToPush ) { + mStack.addFirst( frameToPush ); + } + + private SubcellIterator getTopIterator() { + final StackFrame topFrame = ( StackFrame ) mStack.getFirst(); + return topFrame.getIter(); + } + + private AbstractNetlist getTopNetlist() { + final StackFrame topFrame = ( StackFrame ) mStack.getFirst(); + return topFrame.getComponentNetlist(); + } + + private String getTopFrameName() { + final StackFrame topFrame = ( StackFrame ) mStack.getFirst(); + return topFrame.getComponentName(); + } + + + public FlatteningIterator( final AbstractNetlist top ) { + mStack = new LinkedList(); + push( new RootFrame( top ) ); + mNextNetlist = null; + } + + + public boolean hasNext() { + while ( ( mNextNetlist == null ) && ( ! ( mStack.isEmpty() ) ) ) { + final SubcellIterator currIter = getTopIterator(); + + if ( currIter.hasNext() ) { + final SubcellIterator.SubcellInstance instance = + currIter.next(); + push( instance ); + } + else { + mNextNetlist = getTopNetlist(); + } + } + return mNextNetlist != null; + } + + public FlatInstance next() { + if ( hasNext() ) { + final FlatInstance ret = new FlatInstance( getCurrPath(), + mNextNetlist ); + mNextNetlist = null; + mStack.removeFirst(); + return ret; + } + else { + throw new NoSuchElementException(); + } + } + + private List getCurrPath() { + final LinkedList ret = new LinkedList(); + final Iterator iter = mStack.iterator(); + while ( iter.hasNext() ) { + final StackFrame currFrame = ( StackFrame ) iter.next(); + ret.addLast( currFrame ); + } + return ret; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/SubcellIterator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/SubcellIterator.java new file mode 100644 index 0000000000..2f4ab988f1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/netlist/util/SubcellIterator.java @@ -0,0 +1,150 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.netlist.util; + +import java.util.Collections; +import java.util.Map; +import java.util.List; +import java.util.LinkedList; +import java.util.NoSuchElementException; + +import com.avlsi.file.common.HierName; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; + +import com.avlsi.netlist.impl.SimpleAbstractNodeIterator; +import com.avlsi.netlist.impl.VisitorImpl; + + +/** + An iterator to iterate over all subcell instances + in an iteration of AbstractDevices. + */ +public class SubcellIterator { + /** + A nice interface to an instantiation of a subcell. + */ + public static final class SubcellInstance implements AbstractDevice { + private final HierName m_Name; + private final AbstractNetlist m_Netlist; + private final List m_ConnectedNets; + private final Map m_Params; + + SubcellInstance( final HierName name, + final AbstractNetlist netlist, + final AbstractNodeIterator connectedNodes, + final Map params ) { + m_Name = name; + m_Netlist = netlist; + m_Params = params; + m_ConnectedNets = new LinkedList(); + + while( connectedNodes.hasNext() ) { + final AbstractNode currNode = connectedNodes.next(); + m_ConnectedNets.add( currNode ); + } + } + + /** + Retrieves the name of the instance. + @return The name of the instance. + */ + public HierName getName() { + return m_Name; + } + + /** + Retrieves the nodes connected to the instantiated netlist. + @return An iterator that will iterate over all the nodes connected + to input nodes of the instantiated netlist in the same order as + getInstantiatedNetlist().getInputNodes() would + return, followed by all the nodes connected to output + nodes of the instantiated netlist in the same order as + getInstantiatedNetlist().getOutputNodes() + would return. + */ + public AbstractNodeIterator getConnectedNodes() { + return new SimpleAbstractNodeIterator( m_ConnectedNets.iterator() ); + } + + /** + Retrieves the netlist of the instantiated cell. + @return The netlist of the instantiated cell. + */ + public AbstractNetlist getInstantiatedNetlist() { + return m_Netlist; + } + + /** + @return A map from String to Double that captures additional + parameters of the instantiation. + */ + public Map getParams() { + return Collections.unmodifiableMap( m_Params ); + } + + public void accept( final Visitor v ) { + v.subcircuitCall( m_Name, + m_Netlist, + getConnectedNodes(), + m_Params ); + } + } + + private SubcellInstance m_CurrInstance; + + private final AbstractDeviceIterator m_Iter; + + /** + Construcst a SubcellIterator that will iterate over + all the subcell instances that the specified + AbstractDeviceIterator returns. + @param iter Iterator to get AbstractDevices from. + */ + public SubcellIterator( final AbstractDeviceIterator iter ) { + m_Iter = iter; + m_CurrInstance = null; + } + + public boolean hasNext() { + while ( ( m_CurrInstance == null ) && ( m_Iter.hasNext() ) ) { + final AbstractDevice currDevice = m_Iter.next(); + + currDevice.accept( new VisitorImpl() { + public void subcircuitCall(final HierName name, + final AbstractNetlist circuit, + final AbstractNodeIterator nodes, + final Map parameters) { + m_CurrInstance = new SubcellInstance( name, + circuit, + nodes, + parameters ); + } + } ); + + } + return m_CurrInstance != null; + } + + public SubcellInstance next() { + if ( hasNext() ) { + final SubcellInstance ret = m_CurrInstance; + m_CurrInstance = null; + return ret; + } + else { + throw new NoSuchElementException(); + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRule.java b/async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRule.java new file mode 100644 index 0000000000..9ed66b05b8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRule.java @@ -0,0 +1,547 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.prs; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.bool.AbstractAtomicBooleanExpression; +import com.avlsi.util.bool.AbstractBooleanExpression; +import com.avlsi.util.bool.AndBooleanExpression; +import com.avlsi.util.bool.AndBooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionVisitorInterface; +import com.avlsi.util.bool.BooleanUtils; +import com.avlsi.util.bool.HierNameAtomicBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpressionInterface; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.UnaryAction; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.test.AbstractTestCase; + +/** + * Class to represent a production rule. Production rules have + * four components: + *

      + *
    1. A left-hand side, a condition. + *
    2. A right-hand side, a node that fires when the left-hand side + * condition is met. + *
    3. A direction, either up or down, + *
    4. A number of time steps after which the rule will fire + * see {@link #getAfter} + *
    5. A boolean flag indicating whether or not the production + * rule is an "environmental" production rule, ie whether it + * was declared in an env block. This is no + * longer relevant. A ProductionRule in a PrsBlock is not + * "environmental", a ProductionRule derived from a statement in an + * AssertBlock is. + *
    + *

    + * There are three options for a production rule: + *

      + *
    • unstable see {@link #isUnstable} + *
    • timed see {@link #isTimed} + *
    • isochronic see {@link #isIsochronic} and Bug#1643 + *
    + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ProductionRule { + /** + * The guard condition. + **/ + private final BooleanExpressionInterface guard; + + /** + * The target node. + **/ + private final HierName target; + + /** + * The power supply node. + **/ + private final HierName powerSupply; + + /** + * The direction (UP or DOWN) the target will fire when the guard condition + * is true. + **/ + private final int direction; + + /** + * see {@link #isIsochronic} + **/ + private final boolean isIsochronic; + + /** + * see {@link #isUnstable} + **/ + private final boolean isUnstableP; + + /** + * see {@link #isMetastable} + **/ + private final boolean isMetastableP; + + /** + * see {@link #isTimed} + **/ + private final boolean isTimedP; + + /** + * see {@link #getAfter} + **/ + private final int after; + + /** + * see {@link #isAbsolute} + **/ + private final boolean absolute; + + /** + * Direction constant indicating that the right-hand side goes down when + * the left-hand side condition is true. + **/ + public static final int DOWN = 0; + + /** + * Direction constant indicating that the right-hand side goes up when + * the left-hand side condition is true. + **/ + public static final int UP = 1; + + /** + * Class constructor. + **/ + public ProductionRule(final BooleanExpressionInterface guard, + final HierName target, + final HierName powerSupply, + final int direction, + final boolean isIsochronic, + final boolean isUnstableP, + final boolean isMetastableP, + final boolean isTimedP, + final int after, + final boolean absolute) { + assert !(isUnstableP && isMetastableP) : "A rule cannot be unstable and metastable: " + guard + " -> " + target; + assert direction == UP || direction == DOWN : "Unknown direction: " + direction; + if (direction != DOWN && direction != UP) + throw new IllegalArgumentException("bad direction:" + direction); + + this.guard = guard; + this.target = target; + this.powerSupply = powerSupply; + this.direction = direction; + this.isIsochronic = isIsochronic; + this.isUnstableP = isUnstableP; + this.isMetastableP = isMetastableP; + this.isTimedP = isTimedP; + this.after = after; + this.absolute = absolute; + } + + /** + * Returns the left-hand side condition. + **/ + public BooleanExpressionInterface getGuard() { + return guard; + } + + /** + * Returns the right-hand side node. + **/ + public HierName getTarget() { + return target; + } + + /** + * Returns the power supply node. + **/ + public HierName getPowerSupply() { + return powerSupply; + } + + /** + * Returns the direction the right hand side will transition + * when the left hand side condition is true. + **/ + public int getDirection() { + return direction; + } + + /** + * Flag for special "isochronic" handling of this rule by DSim. + **/ + public boolean isIsochronic() { + return isIsochronic; + } + + /** + * Whether the node on the right hand side of the rule is guaranteed + * not to be changed by another rule between the time this rule's + * left hand side becomes true, and the right hand side is changed. + **/ + public boolean isUnstable() { + return isUnstableP; + } + + /** + * Whether the node on the right hand side of the rule should have a "lazy" + * threshold for analog to digital conversation. + * See bug 2949 + * for more details. + **/ + public boolean isMetastable() { + return isMetastableP; + } + + /** + * Means something to dsim, not sure what. + **/ + public boolean isTimed() { + return isTimedP; + } + + /** + * Whether the after delay is in terms of DSim units, or in + * terms of absolute time. + * See bug 3026 + * for more details. + **/ + public boolean isAbsolute() { + return absolute; + } + + /** + * @deprecated Return the number of time steps between the left + * hand side becoming true and the right hand side transitioning. + * This access method replaces -1 (that is, unspecified) with 100 + * for compatibility with older tools. We should eventually + * migrate most tools to CellDelay instead. -- AML + **/ + public int getAfterTimeSteps() { + return (after >=0 ) ? after : 100; + } + + /** + * New way of getting after rule. Returns -1 if after was not + * explictly specified. -- AML + **/ + public int getAfter() { + return after; + } + + /** + * Returns production rule with transformed left hand side, opposite + * direction, and otherwise the same. The CNF of the left hand side + * must consist only of literals and negated literals. The new left + * hand side expression will be the same, but with the opposite sense + * for each literal. + *

    Ie. a & b & ~c -> d+ yields ~a & ~b & c -> d- + **/ + public ProductionRule cElementComplement(final HierName newPowerSupply) { + return new ProductionRule( + cElementComplement(getGuard(), true), + getTarget(), newPowerSupply, + oppositeDirection(getDirection()), + isIsochronic(), isUnstable(), isMetastable(), + isTimed(), getAfter(), isAbsolute()); + } + + /** + * + **/ + private static BooleanExpressionInterface cElementComplement( + final BooleanExpressionInterface be, + final boolean nonNegatedP) { + /** @review denney This is kinda nasty due to design of + * boolean stuff. How should we improve it? **/ + + if (be instanceof AbstractAtomicBooleanExpression) { + // handle variable + return be.negated(); + } else { + final boolean sense; + final Collection terms; + if (be instanceof AndBooleanExpressionInterface) { + final AndBooleanExpressionInterface abe + = (AndBooleanExpressionInterface) be; + sense = abe.getSense(); + terms = abe.getConjuncts(); + } else if (be instanceof OrBooleanExpressionInterface) { + final OrBooleanExpressionInterface obe + = (OrBooleanExpressionInterface) be; + sense = obe.getSense(); + terms = obe.getDisjuncts(); + } else { + throw new AssertionFailure("unknown boolean expression" + + " type: " + be.getClass().getName()); + } + + // handle true/false + if (terms.size() == 0) + return be.negated(); + + final Collection newTerms = new ArrayList(); + for (final Iterator iTerm = terms.iterator(); iTerm.hasNext();) { + final BooleanExpressionInterface subBe + = (BooleanExpressionInterface) iTerm.next(); + + newTerms.add(cElementComplement(subBe, nonNegatedP == sense)); + } + + if (nonNegatedP == sense) + return new AndBooleanExpression(sense, newTerms); + else + return new OrBooleanExpression(sense, newTerms); + } + } + + /** + * Returns production rule with negated left hand side, opposite + * direction, and otherwise the same. + *

    Ie. a & (b | c) -> d+ yields ~(a & (b | c)) -> d- + **/ + public ProductionRule combinationalComplement( + final HierName newPowerSupply) { + return new ProductionRule(getGuard().negated(), + getTarget(), newPowerSupply, + oppositeDirection(getDirection()), + isIsochronic(), isUnstable(), isMetastable(), isTimed(), + getAfter(), isAbsolute()); + } + + /** + * Returns a new ProductionRule with the HierNames on both + * sides transformed by f. + **/ + public ProductionRule mapNames(final UnaryFunction f) { + return new ProductionRule( + BooleanUtils.mapBooleanExpressionHierNames( + getGuard(), f), + (HierName) f.execute(getTarget()), + (HierName) f.execute(getPowerSupply()), + getDirection(), isIsochronic(), isUnstable(), isMetastable(), + isTimed(), getAfter(), isAbsolute()); + } + + /** + * Returns a new ProductionRule with the HierNames on both + * sides transformed replaced with the canonical name + * according to aliases. f + * must not return null. + **/ + public ProductionRule canonicalizeNames(final AliasedSet aliases) { + return mapNames( + new UnaryFunction() { + public Object execute(final Object o) { + final HierName n = (HierName) o; + final HierName cn = + (HierName) aliases.getCanonicalKey(n); + Debug.assertTrue(cn != null); + return cn; + }}); + } + + /** + * Executes f on each HierName mentioned in the production rule. + **/ + public void foreachHierName(final UnaryAction f) { + f.execute(getTarget()); + f.execute(getPowerSupply()); + BooleanUtils.foreachHierName(getGuard(), f); + } + + /** + * Verifies the inverse monotonicity property. + * + * Our prs expressions are only synthesizable if they are "inverse + * monotonic". This just means that any input from a rule going from + * high to low can only leave the target alone or make the target go + * from low to high, and that any input going from low to high can + * only leave the target alone, or make it go from high to low. + * + * @return whether this production rule satisfies the inverse monotonicity constraint. + **/ + public boolean isInverseMonotonic() { + MonotonicityChecker visitor = new MonotonicityChecker(); + guard.visitWith(visitor); + return visitor.ok; + } + + /** report rule boolean flags as a string suitable for csim/aspice output */ + public String flagsString() { + return + (isTimed() ? "timed " : "") + + (isIsochronic() ? "isochronic " : "") + + (isUnstable() ? "unstab " : "") + + (isMetastable() ? "metastab " : ""); + } + + /** print a PRS in a readable and parseable format */ + public String toString() { + return flagsString() + + (getAfter()>=0 ? (isAbsolute() ? "after_ps " : "after ") + getAfter() + " " : "") + + getGuard() + " -> \"" + getTarget() +"\"" + + (getDirection() == UP ? "+" : "-"); + } + + /** + * Returns DOWN if passed UP, and vice versa. + * + * @throws IllegalArgumentException If direction is not either + * UP or DOWN. + **/ + public int oppositeDirection(final int direction) { + if (direction == UP) + return DOWN; + else if (direction == DOWN) + return UP; + else + throw new IllegalArgumentException("bad direction: " + direction); + } + + private class MonotonicityChecker implements BooleanExpressionVisitorInterface { + /** are all atomic terms processed so far acceptable? Also used for shortcutting. **/ + public boolean ok = true; + /** current sense we are checking against. **/ + private boolean up = direction == UP; + /** + * Handle and expression. + **/ + public void visit(AndBooleanExpressionInterface ae) { + final boolean nonnegated=ae.getSense(); + // if this is a negated clause, treat all subclauses as if up is opposite. + up ^= (!nonnegated); + Collection c = ae.getConjuncts(); + for (Iterator i = c.iterator(); ok && i.hasNext(); ) { + BooleanExpressionInterface b = (BooleanExpressionInterface)i.next(); + b.visitWith(this); + } + // restore for parent. + up ^= (!nonnegated); + } + /** + * Handle or expression. + **/ + public void visit(OrBooleanExpressionInterface oe) { + boolean nonnegated=oe.getSense(); + // if this is a negated clause, treat all subclauses as if up is opposite. + up ^= (!nonnegated); + Collection c = oe.getDisjuncts(); + for (Iterator i = c.iterator(); ok && i.hasNext(); ) { + BooleanExpressionInterface b = (BooleanExpressionInterface)i.next(); + b.visitWith(this); + } + // restore for parent. + up ^= (!nonnegated); + } + /** + * Handle atomic expression. + **/ + public void visit(HierNameAtomicBooleanExpression te) { + boolean nonnegated=te.getSense(); + if (!up ^ nonnegated) { + ok = false; + } + } + } + + /** + * Tests {@link + * ProductionRule#cElementComplement(BooleanExpressionInterface,boolean)} + **/ + public static final class TestCElementComplement + extends AbstractTestCase { + + /** + * Test cElementComplement, making sure that the + * string representation of the complement + * matches what is expected. Obviously, this is suboptimal, + * and a better boolean epression comparison method is needed. + **/ + private void test(final BooleanExpressionInterface be, + final String expected) { + final String got + = cElementComplement(be, true).toUserVisibleString(); + + assertTrue(got.equals(expected)); + } + + /** + * Test cElementComplement. The expected string + * will have to be changed if the algorithm changes, + * or the formatting changes. This sucks, but at least + * we have automated tests. + **/ + public void test() throws Throwable { + final BooleanUtils u = new BooleanUtils(); + + final BooleanExpressionInterface a = u.literal("a"); + final BooleanExpressionInterface b = u.literal("b"); + final BooleanExpressionInterface c = u.literal("c"); + final BooleanExpressionInterface d = u.literal("d"); + + // test true, expect false + test(u.t(), "~true"); + + // test false, expect true + test(u.f(), "~false"); + + // test ~true, expect true + test(u.not(u.t()), "true"); + + // test ~false, expect false + test(u.not(u.f()), "false"); + + // test a, expect ~a + test(a, "~\"a\""); + + // test ~a, expect a + test(u.not(a), "\"a\""); + + // test a & b, expect ~a & ~b + test(u.and(a, b), "(~\"a\"&~\"b\")"); + + // test a | b, expect ~a & ~b + test(u.or(a, b), "(~\"a\"&~\"b\")"); + + // test ~(a & b), expect ~(~a | ~b) + test(u.not(u.and(a, b)), "~(~\"a\"|~\"b\")"); + + // test ~(a | b), expect ~(~a | ~b) + test(u.not(u.or(a, b)), "~(~\"a\"|~\"b\")"); + + // test ~(~a & b), expect ~(~~a | ~b) + test(u.not(u.and(u.not(a), b)), "~(\"a\"|~\"b\")"); + + // test ~(~a | b), expect ~(~~a | ~b) + test(u.not(u.or(u.not(a), b)), "~(\"a\"|~\"b\")"); + + // test (a & b) | (c & d), expect ~a & ~b & ~c & ~d + test(u.or(u.and(a, b), u.and(c, d)), + "((~\"a\"&~\"b\")&(~\"c\"&~\"d\"))"); + + // test ~(~(~a & b) | (~c & d)), + // expect ~(~(~~"a"&~"b")|~~"c"|~"d") + test(u.not(u.or(u.not(u.and(u.not(a), b)), u.and(u.not(c), d))), + "~(~(\"a\"&~\"b\")|(\"c\"|~\"d\"))"); + } + + public static void main(String[] args) { + AbstractTestCase.testOne(new TestCElementComplement()); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRuleSet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRuleSet.java new file mode 100644 index 0000000000..696382748f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/prs/ProductionRuleSet.java @@ -0,0 +1,88 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.prs; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; + +import com.avlsi.util.container.AliasedSet; + +/** + * Class to represent the set of production rules for a Cell. + * + * @see com.avlsi.cell.CellInterface + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ProductionRuleSet { + /** + * List of the production rules. + **/ + private ArrayList productionRuleList = new ArrayList(); + + /** + * Returns an unmodifiable iterator through the production rules, + * in the order they were added. + **/ + public Iterator getProductionRules() { + return Collections.unmodifiableList(productionRuleList).iterator(); + } + + /** + * Adds a reference to the production rule to the end of the list. + * Any changes to the production rule passed in will be change + * the stored production rule. + **/ + public void addProductionRule(final ProductionRule pr) { + productionRuleList.add(pr); + } + + /** + * Ensures that all nodes use only the canonical node name, as defined + * in aliases. + **/ + public void canonicalizeNames(final AliasedSet aliases) { + for (int i = 0; i < productionRuleList.size(); ++i) { + final ProductionRule pr = + (ProductionRule) productionRuleList.get(i); + + productionRuleList.set(i, pr.canonicalizeNames(aliases)); + } + } + + /** + * Absorbs production rules from the refinement parent. + **/ + public void refineFrom(final ProductionRuleSet parent) { + productionRuleList.addAll(parent.productionRuleList); + } + + /** + * String representation for debugging only. + **/ + public String toString() { + final StringBuffer sb = new StringBuffer(); + for (final Iterator iPr = getProductionRules(); iPr.hasNext(); ) { + final ProductionRule pr = (ProductionRule) iPr.next(); + sb.append(pr.toString()).append('\n'); + } + return sb.toString(); + } + + public int size() { + return productionRuleList.size(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/prs/UnimplementableProductionRuleException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/prs/UnimplementableProductionRuleException.java new file mode 100644 index 0000000000..3ab9e10ea9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/prs/UnimplementableProductionRuleException.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.prs; + +import com.avlsi.cell.CellInterface; + +/** + * Exception thrown when the production rule cannot be synthesized. + * + * @author Aaron Denney + * @version $Date$ + **/ +public final class UnimplementableProductionRuleException extends Exception { + /** + * The production rule that cannot be implemented. + **/ + public final ProductionRule rule; + /** + * The cell the production rule is in. Helps to find the problem. + **/ + public final CellInterface cell; + /** + * Constructor. + * @param p The production rule that cannot be implemented. May not be null. + * @param c The cell the production rule is located in. May be null. + **/ + public UnimplementableProductionRuleException(ProductionRule p, CellInterface c) { + super("Production rule " + p + (c==null ? "" : " in cell " + c.getFullyQualifiedType()) + " is not implementable."); + rule = p; + cell = c; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/sync/Semaphore.java b/async-toolkit/jtools/cad/java/src/com/avlsi/sync/Semaphore.java new file mode 100644 index 0000000000..d6bba051b7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/sync/Semaphore.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.sync; + +/** + * Semaphore is a straightforward implementation of the well-known + * synchronization primitive. Its counter can be initialized to any + * nonnegative value -- by default, it is zero. + **/ +public class Semaphore { + private int counter; + + public Semaphore() { + this(0); + } + + public Semaphore(int i) { + if (i < 0) throw new IllegalArgumentException(i + " < 0"); + counter = i; + } + + /** + * Increments internal counter, possibly awakening a thread + * wait()ing in acquire(). + **/ + public synchronized void release() { + if (counter == 0) { + this.notify(); + } + counter++; + } + + /** + * Decrements internal counter, blocking if the counter is already + * zero. + * + * If the exception happens, it was not acquired. + * + * @exception InterruptedException passed from this.wait(). + **/ + public synchronized void acquire() throws InterruptedException { + while (counter == 0) { + this.wait(); + } + counter--; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/test/AbstractTestCase.java b/async-toolkit/jtools/cad/java/src/com/avlsi/test/AbstractTestCase.java new file mode 100644 index 0000000000..099b352f41 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/test/AbstractTestCase.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.test; + +/** + * Base class for test cases. All test cases should extend this class. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public abstract class AbstractTestCase { + + /** + * Asserts a condition, throwing TestFailedError if it is not true. + * + * @throws TestFailedError If !cond. + **/ + protected void assertTrue(final boolean cond) { + if (!cond) + throw new TestFailedError(); + } + + /** + * Asserts a condition, throwing TestFailedError if it is not true. + * + * @throws TestFailedError If !cond. + **/ + protected void assertTrue(final boolean cond, final String message) { + if (!cond) + throw new TestFailedError(message); + } + + /** + * Run the test case. + * + * @throws TestFailedError If the test fails. + * @throws Throwable Who knows what could go wrong. + **/ + public abstract void test() throws Throwable; + + /** + * Runs one test case, printing useful info. + **/ + public static void testOne(final AbstractTestCase tc) { + try { + tc.test(); + System.err.println("PASS"); + } catch (TestFailedError t) { + System.err.println("FAIL: " + t); + t.printStackTrace(); + } catch (Throwable t) { + System.err.println("Uncaught throwable: " + t); + t.printStackTrace(); + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/test/TestEverything.java b/async-toolkit/jtools/cad/java/src/com/avlsi/test/TestEverything.java new file mode 100644 index 0000000000..7ea0c1851c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/test/TestEverything.java @@ -0,0 +1,82 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.test; + +/** + * Run all of our test cases. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class TestEverything { + + public static void main(String[] args) { + + final AbstractTestCase[] tests = new AbstractTestCase[] { + new com.avlsi.cast.impl.TestDenseSubscriptSpec(), + new com.avlsi.cell.TestExclusiveNodeSet(), + new com.avlsi.file.common.TestHierName(), + new com.avlsi.io.TestPositionStackReader(), + new com.avlsi.io.TestStreamLexer(), + new com.avlsi.prs.ProductionRule.TestCElementComplement(), + new com.avlsi.util.bool.TestBooleans.TestAtomic(), + new com.avlsi.util.bool.TestBooleans.TestDNFCNF(), + new com.avlsi.util.bool.TestBooleans.Test3CNF(), + new com.avlsi.util.bool.TestBooleans.TestDeep(), + new com.avlsi.util.bool.TestBooleans.TestOrder(), + new com.avlsi.util.container.TestAlias(), + new com.avlsi.util.container.TestAliasedMap(), + new com.avlsi.util.container.TestAliasedSet(), + new com.avlsi.util.container.TestCollectionUtils(), + new com.avlsi.util.container.TestMultiSet(), + new com.avlsi.util.container.TestPriorityQueue(), + new com.avlsi.util.recalc.TestRecalc(), + new com.avlsi.tools.tsim.TestChannelBundle(), + new com.avlsi.tools.tsim.TestChannelOutputBundle() + }; + + int nFail = 0; // # test failures + int nError = 0; // # uncaught throwables + int nPass = 0; // # passed tests + + final int nTests = tests.length; + + for (int i = 0; i < tests.length; ++i) { + try { + tests[i].test(); + ++nPass; + } catch (TestFailedError e) { + System.out.println("FAILED: " + tests[i]); + System.out.println(e); + e.printStackTrace(); + ++nFail; + } catch (Throwable t) { + System.out.println("ERROR: " + tests[i]); + System.out.println(t); + t.printStackTrace(); + ++nError; + } + } + + if (nPass == nTests) { + System.out.println("All " + nTests + " tests passed!"); + } else { + System.out.println(); + System.out.println(nTests + " tests"); + System.out.println(nPass + " passed"); + System.out.println(nFail + " failed"); + System.out.println(nError + " uncaught throwables"); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/test/TestFailedError.java b/async-toolkit/jtools/cad/java/src/com/avlsi/test/TestFailedError.java new file mode 100644 index 0000000000..c8b5471af7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/test/TestFailedError.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.test; + +/** + * Throws by {@link AbstractTestCase#assertTrue} when an assertion fails. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class TestFailedError extends Error { + public TestFailedError() { + super(); + } + + public TestFailedError(final String message) { + super(message); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AbstractDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AbstractDevice.java new file mode 100644 index 0000000000..fb1c99552a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AbstractDevice.java @@ -0,0 +1,108 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.file.common.HierName; + +/** + * Base class for devices + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public abstract class AbstractDevice implements Cloneable{ + + public static final int I1 = 1; + public static final int I2 = 2; + public static final int I3 = 3; + public static final int I4 = 4; + + public static final String[] names = { "ERROR", "I1","I2","I3","I4"}; + /** + * List of nodes connected to this device. + * Classes extending this class understand the ordering. + **/ + protected Node[] nodes; + + /** Name of the Device **/ + protected HierName name; + + /** + * Construct device + **/ + public AbstractDevice(Node[] nodes) { + this.nodes = nodes; + + for (int i = 0; i < nodes.length; i++) + nodes[i].addNeighborNodes(nodes); + } + + /** + * Get nodes connected to this device + * @return list of nodes this device connects + **/ + public Node[] getNodes() { + return nodes; + } + + public HierName getName() { + return name; + } + + public void setName(HierName n) { name = n; } + + public double getCurrent(int type) { return -1; } + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device and then informs its nodes of these values. + * @param chargeScale scalar for charge calculation + * @param currentScale scalar for current calculation + * @param derivChargeScale scalar for charge derivative calculation + * @param derivCurrentScale scalar for current derivative calculation + * @param time Current time of the simulation (for sources) + **/ + public abstract void evalVoltage( + double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale,double time); + + /** Should return the SPICE prefic code (like M, D, C, etc) **/ + public abstract String getCode(); + public AbstractDevice copy(HierName name, Node[] nodes) + throws AbstractDeviceException { + try { + AbstractDevice ad = (AbstractDevice) this.clone(); + ad.name = name; + ad.nodes = nodes; + for (int i = 0; i < nodes.length; i++) + ad.nodes[i].addNeighborNodes(ad.nodes); + return ad; + } catch(CloneNotSupportedException e) { + throw new AbstractDeviceException("Could not clone: "+ + e.getMessage(), e); + } + } + + /***************************************************************** + * AbstractCircuit exception class + *****************************************************************/ + public static class AbstractDeviceException extends java.lang.Exception { + public AbstractDeviceException() { super(); } + public AbstractDeviceException(final String desc) { super(desc); } + public AbstractDeviceException(final String desc, Throwable cause) { + super(desc, cause); + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogTraceInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogTraceInterface.java new file mode 100644 index 0000000000..e1f90aae24 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogTraceInterface.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; +import java.util.Iterator; +/** + * Interface for tracing analog nodes
    + * An analog trace records all traced elements' values for all timesteps, + * giving it a very simple interface. + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface AnalogTraceInterface { + /** Adds an element to the tracefile, given an iterator of strings **/ + void addAliasedElement(Iterator names) throws TraceFileException; + /** Adds a new element to the list **/ + void addElement(String name) throws TraceFileException; + /** Sends a new record to the tracefile. The order of the floats + * should be the same as the order of the addElements. If the number + * of floats is not the same as the number of elements, the tracefile + * may become corrupted **/ + void record(double time, double[] data) throws TraceFileException; + /** Closes the tracefile **/ + void close() throws TraceFileException; +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogWatcher.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogWatcher.java new file mode 100644 index 0000000000..b2e6ca51e6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/AnalogWatcher.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +/** + * Class for AnalogWatcher + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface AnalogWatcher{ + void voltageChanged(double voltage); +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/BSim3Model.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/BSim3Model.java new file mode 100644 index 0000000000..6a9e11e940 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/BSim3Model.java @@ -0,0 +1,1692 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StreamTokenizer; +import java.util.Iterator; +import java.util.ArrayList; + +import com.avlsi.file.common.DeviceTypes; + +/** + * Read in BSIM3 files and create java Model objects from them. Will + * load the files natively or in java, depending on the parameters set. + * + * @author Ted Vessenes, some JNI stuff from Dan Daly + * @version $Name: $ $Date$ + **/ +public class BSim3Model { + protected static ArrayList models = new ArrayList(); + + private static final int NMOS = 1; + private static final int PMOS = -1; + + /** Loads the model natively (models reside on the C side **/ + private static native void loadModel(String filename, double temperature); + + /** Retrieves the pointer to the model on the C side **/ + public static native int findNativeModel(int type, double width, + double length); + + /** Was the native load successful? **/ + private static boolean nativeLoaded = false; + /** For debugging the native **/ + public static boolean both = false; + + // + //Instance Vars for Native Implementation + // + // + /** For native models, the handle to the native model **/ + private int nativeModelHandle; + + public static boolean isNativeLoaded() { return nativeLoaded; } + + public int getHandle() { return nativeModelHandle; } + + public static void readFile(String filename, double temperature, + boolean useNative) { + if (!nativeLoaded && (useNative || both)) { + try { + System.loadLibrary("Aspice"); + loadModel(filename,temperature); + nativeLoaded = true; + System.out.println("Native Model Libraries Loaded from "+ + filename+" @ "+temperature+" deg C"); + } catch (UnsatisfiedLinkError e) { + System.out.println("Exception while loading native model library"+ + ", UnsatisfiedLinkError:"+e.getMessage()+ + "Java Models will be used instead."); + nativeLoaded = false; + } catch ( Exception e) { + System.out.println("Exception while loading native model library :"+ + "\t"+e+"\n"+ + "\t"+e.getMessage()+ + "Java Models will be used instead."); + nativeLoaded = false; + } + } + if (!BSim3Model.isNativeLoaded() || BSim3Model.both) { + readFile(filename, temperature); + } + } + + public static void readFile(String fileName, double temperature) { + FileInputStream file = null; + try { + file = new FileInputStream(fileName); + StreamTokenizer st = new StreamTokenizer( + new BufferedReader( + new InputStreamReader(file) + ) + ); + // For some reason, the steam tokenizer defaults number + // processing mode on and has no way of automatically turning + // it off-- hence this code. + st.resetSyntax(); + st.wordChars(0, 255); + + st.whitespaceChars(' ', ' '); + st.whitespaceChars('\t', '\t'); + st.whitespaceChars('\n', '\n'); + st.whitespaceChars('\r', '\r'); + st.whitespaceChars('=', '='); + + st.lowerCaseMode(true); + st.commentChar('*'); + + // Set of data states describing which state machine state + // we're in (ie. what data we're waiting for) + + final int BSIM_ERROR = 0; // Found error-- abort + final int BSIM_IDLE = 1; // Start state or Found ) + final int BSIM_MODEL = 2; // Found .MODEL + final int BSIM_NAME = 3; // Found CMOSN, CMOSP, etc. + final int BSIM_TYPE = 4; // Found NMOS, PMOS, etc. + final int BSIM_DATA = 5; // Found ( or field value + final int BSIM_FIELD = 6; // Found Field name + int state = BSIM_IDLE; + + // The for loop below encodes a simple state machine on + // These states. They link as follows: + // Name -> Type -> Data ---> Field + // ^ | ^ | + // | v | | + // -- Model <- Idle ------------ + // + // Idle is the start state. If we reach EOF outside of idle, + // the file is invalid. + + // Ref to the current model + BSim3Model model = new BSim3Model(temperature); + + String field = ""; + + while (state != BSIM_ERROR && st.nextToken() != st.TT_EOF) { + if (st.ttype != st.TT_WORD) + continue; + + switch (state) { + case BSIM_IDLE: + if (st.sval.equals(".model")) + state = BSIM_MODEL; + break; + + // Find model name + case BSIM_MODEL: + // Model name is in st.sval but we don't care + models.add(model); + + state = BSIM_NAME; + break; + + // Find model type + case BSIM_NAME: + if (st.sval.equals("nmos")) { + model.type = NMOS; + } else if (st.sval.equals("pmos")) { + model.type = PMOS; + } else { + System.out.println("Invalid Model type: "+st.sval); + state = BSIM_ERROR; + break; + } + + state = BSIM_TYPE; + break; + + // Find data open '(' + case BSIM_TYPE: + if (st.sval.equals("(")) + state = BSIM_DATA; + else { + System.out.println("Found " + st.sval + " instead " + + "of expected '('"); + state = BSIM_ERROR; + } + break; + + // Find field name or ')' + case BSIM_DATA: + if (st.sval.equals(")")) { + // Cleanup old model + model.setDefaults(); + model.computeTemperatureData(); + + // Get to work on the new one + model = new BSim3Model(temperature); + state = BSIM_IDLE; + } else { + if (st.sval.startsWith("+")) { + field = st.sval.substring(1); + } else { + field = st.sval; + } + state = BSIM_FIELD; + } + + break; + + // Find field number value + case BSIM_FIELD: + model.set(field, st.sval); + state = BSIM_DATA; + break; + + // Error out just in case + default: + System.out.println("State machine in unknown state " + + state); + state = BSIM_ERROR; + case BSIM_ERROR: + break; + } + } + } catch (IOException e) { + System.out.println(e); + } finally { + try { + if (file != null) + file.close(); + } catch (IOException e) { + ; + } + } + } + + public BSim3Model(int type, double temperature) { + this.type = type; + this.temp = temperature + CONSTCtoK; + } + + public BSim3Model(double temperature) { + this.temp = temperature + CONSTCtoK; + } + + private BSim3Model(int type, int handle) { + this.type = type; + this.nativeModelHandle = handle; + } + /** + * Finds a model given a type, width, and length + * @param type Type of model (NMOS or PMOS) + * @param width in meters + * @param length in meters + * @throws IllegalArgumentException + * @return BSim3Model if found, or null otherwise + **/ + public static BSim3Model findModel(int type, final double W, final double L) + { + // Convert between normal typing and BSim's type multiplier-- + // -1 for PMOS where everything is inverted. + if (type == DeviceTypes.N_TYPE) { + type = NMOS; + } else if (type == DeviceTypes.P_TYPE) { + type = PMOS; + } + + if (isNativeLoaded() && !both) { + int h = findNativeModel(type, W, L); + //System.out.println("Native model loaded at "+h+" with type= "+type+ + // " width= "+W+" length= "+L); + return new BSim3Model(type, h); + } + + for (Iterator i = models.iterator(); i.hasNext(); ) { + final BSim3Model m = (BSim3Model) i.next(); + if (type == m.type && L >= m.Lmin && L < m.Lmax + && W >= m.Wmin && W < m.Wmax) { + //System.out.println("model = "+m.type+" lmin= "+m.Lmin+" lmax= "+ + // m.Lmax+" Wmin= "+m.Wmin+" Wmax= "+m.Wmax); + if (isNativeLoaded() && both) { + int h = findNativeModel(type, W, L); + //System.out.println("Native model loaded at "+h+ + // " with type= "+type+ + // " width= "+W+" length= "+L); + m.nativeModelHandle = h; + } + return m; + } + } + + throw new IllegalArgumentException("Could not find model for type " + + type + ", width " + W + ", and " + + "length " + L + "."); + } + + public static final double EPSOX = 3.453133e-11; + public static final double EPSSI = 1.03594e-10; + public static final double CONSTCtoK = 273.15; + public static final double Charge_q = 1.60219e-19; + public static final double CONSTroot2 = 1.41421356237309504880; + public static final double CONSTboltz = 1.3806226e-23; + public static final double CONSTvt0 = CONSTboltz * (27 + CONSTCtoK ) / Charge_q; + public static final double KboQ = 8.617087e-5; /* Kb / q where q = 1.60219e-19 */ + + public static final double MAX_EXP = 5.834617425e14; + public static final double MIN_EXP = 1.713908431e-15; + public static final double EXP_THRESHOLD = 34.0; + + public static final double DELTA_1 = 0.02; + public static final double DELTA_2 = 0.02; + public static final double DELTA_3 = 0.02; + public static final double DELTA_4 = 0.02; + + public boolean given(double d) { return !Double.isNaN(d); } + public boolean given(int i) { return i != Integer.MIN_VALUE; } + public boolean given(String s) { return !s.equals(""); } + + public double temp = Double.NaN; + public double xl = Double.NaN; + public double xw = Double.NaN; + public double hdif = Double.NaN; + public double ldif = Double.NaN; + public double rs = Double.NaN; + public double rd = Double.NaN; + public int acm = Integer.MIN_VALUE; + public double cta = Double.NaN; + public double ctp = Double.NaN; + public double pta = Double.NaN; + public double ptp = Double.NaN; + public double n = Double.NaN; + public int nlev = Integer.MIN_VALUE; + public double tlev = Double.NaN; + public double tlevc = Double.NaN; + public double em = Double.NaN; + public double ef = Double.NaN; + public double af = Double.NaN; + public double kf = Double.NaN; + public int nqsMod = Integer.MIN_VALUE; + public int type = Integer.MIN_VALUE; + public int level = Integer.MIN_VALUE; + public int capMod = Integer.MIN_VALUE; + public int mobMod = Integer.MIN_VALUE; + public int noiMod = Integer.MIN_VALUE; + public int paramChk = Integer.MIN_VALUE; + public int binUnit = Integer.MIN_VALUE; + public String version = ""; + public double tox = Double.NaN; + public double toxm = Double.NaN; + public double cdsc = Double.NaN; + public double cdscb = Double.NaN; + public double cdscd = Double.NaN; + public double cit = Double.NaN; + public double nfactor = Double.NaN; + public double xj = Double.NaN; + public double vsat = Double.NaN; + public double at = Double.NaN; + public double a0 = Double.NaN; + public double ags = Double.NaN; + public double a1 = Double.NaN; + public double a2 = Double.NaN; + public double keta = Double.NaN; + public double nsub = Double.NaN; + public double npeak = Double.NaN; + public double ngate = Double.NaN; + public double gamma1 = Double.NaN; + public double gamma2 = Double.NaN; + public double vbx = Double.NaN; + public double vbm = Double.NaN; + public double xt = Double.NaN; + public double k1 = Double.NaN; + public double kt1 = Double.NaN; + public double kt1l = Double.NaN; + public double kt2 = Double.NaN; + public double k2 = Double.NaN; + public double k3 = Double.NaN; + public double k3b = Double.NaN; + public double w0 = Double.NaN; + public double nlx = Double.NaN; + public double dvt0 = Double.NaN; + public double dvt1 = Double.NaN; + public double dvt2 = Double.NaN; + public double dvt0w = Double.NaN; + public double dvt1w = Double.NaN; + public double dvt2w = Double.NaN; + public double drout = Double.NaN; + public double dsub = Double.NaN; + public double vth0 = Double.NaN; + public double ua = Double.NaN; + public double ua1 = Double.NaN; + public double ub = Double.NaN; + public double ub1 = Double.NaN; + public double uc = Double.NaN; + public double uc1 = Double.NaN; + public double u0 = Double.NaN; + public double ute = Double.NaN; + public double voff = Double.NaN; + public double delta = Double.NaN; + public double rdsw = Double.NaN; + public double prwg = Double.NaN; + public double prwb = Double.NaN; + public double prt = Double.NaN; + public double eta0 = Double.NaN; + public double etab = Double.NaN; + public double pclm = Double.NaN; + public double pdibl1 = Double.NaN; + public double pdibl2 = Double.NaN; + public double pdiblb = Double.NaN; + public double pscbe1 = Double.NaN; + public double pscbe2 = Double.NaN; + public double pvag = Double.NaN; + public double wr = Double.NaN; + public double dwg = Double.NaN; + public double dwb = Double.NaN; + public double b0 = Double.NaN; + public double b1 = Double.NaN; + public double alpha0 = Double.NaN; + public double alpha1 = Double.NaN; + public double beta0 = Double.NaN; + public double ijth = Double.NaN; + public double vfb = Double.NaN; + public double elm = Double.NaN; + public double cgsl = Double.NaN; + public double cgdl = Double.NaN; + public double ckappa = Double.NaN; + public double cf = Double.NaN; + public double vfbcv = Double.NaN; + public double clc = Double.NaN; + public double cle = Double.NaN; + public double dwc = Double.NaN; + public double dlc = Double.NaN; + public double noff = Double.NaN; + public double voffcv = Double.NaN; + public double acde = Double.NaN; + public double moin = Double.NaN; + public double tcj = Double.NaN; + public double tcjsw = Double.NaN; + public double tcjswg = Double.NaN; + public double tpb = Double.NaN; + public double tpbsw = Double.NaN; + public double tpbswg = Double.NaN; + public double tnom = Double.NaN; + public double cgso = Double.NaN; + public double cgdo = Double.NaN; + public double cgbo = Double.NaN; + public double xpart = Double.NaN; + public double sheetResistance = Double.NaN; + public double jctSatCurDensity = Double.NaN; + public double jctSidewallSatCurDensity = Double.NaN; + public double bulkJctPotential = Double.NaN; + public double bulkJctBotGradingCoeff = Double.NaN; + public double bulkJctSideGradingCoeff = Double.NaN; + public double bulkJctGateSideGradingCoeff = Double.NaN; + public double sidewallJctPotential = Double.NaN; + public double GatesidewallJctPotential = Double.NaN; + public double unitAreaJctCap = Double.NaN; + public double unitLengthSidewallJctCap = Double.NaN; + public double unitLengthGateSidewallJctCap = Double.NaN; + public double jctEmissionCoeff = Double.NaN; + public double jctTempExponent = Double.NaN; + public double Lint = Double.NaN; + public double Ll = Double.NaN; + public double Llc = Double.NaN; + public double Lln = Double.NaN; + public double Lw = Double.NaN; + public double Lwc = Double.NaN; + public double Lwn = Double.NaN; + public double Lwl = Double.NaN; + public double Lwlc = Double.NaN; + public double Lmin = Double.NaN; + public double Lmax = Double.NaN; + public double Wint = Double.NaN; + public double Wl = Double.NaN; + public double Wlc = Double.NaN; + public double Wln = Double.NaN; + public double Ww = Double.NaN; + public double Wwc = Double.NaN; + public double Wwn = Double.NaN; + public double Wwl = Double.NaN; + public double Wwlc = Double.NaN; + public double Wmin = Double.NaN; + public double Wmax = Double.NaN; + public double vtm = Double.NaN; + public double cox = Double.NaN; + public double cof1 = Double.NaN; + public double cof2 = Double.NaN; + public double cof3 = Double.NaN; + public double cof4 = Double.NaN; + public double vcrit = Double.NaN; + public double factor1 = Double.NaN; + public double PhiB = Double.NaN; + public double PhiBSW = Double.NaN; + public double PhiBSWG = Double.NaN; + public double jctTempSatCurDensity = Double.NaN; + public double jctSidewallTempSatCurDensity = Double.NaN; + public double oxideTrapDensityA = Double.NaN; + public double oxideTrapDensityB = Double.NaN; + public double oxideTrapDensityC = Double.NaN; + public double lcdsc = Double.NaN; + public double lcdscb = Double.NaN; + public double lcdscd = Double.NaN; + public double lcit = Double.NaN; + public double lnfactor = Double.NaN; + public double lxj = Double.NaN; + public double lvsat = Double.NaN; + public double lat = Double.NaN; + public double la0 = Double.NaN; + public double lags = Double.NaN; + public double la1 = Double.NaN; + public double la2 = Double.NaN; + public double lketa = Double.NaN; + public double lnsub = Double.NaN; + public double lnpeak = Double.NaN; + public double lngate = Double.NaN; + public double lgamma1 = Double.NaN; + public double lgamma2 = Double.NaN; + public double lvbx = Double.NaN; + public double lvbm = Double.NaN; + public double lxt = Double.NaN; + public double lk1 = Double.NaN; + public double lkt1 = Double.NaN; + public double lkt1l = Double.NaN; + public double lkt2 = Double.NaN; + public double lk2 = Double.NaN; + public double lk3 = Double.NaN; + public double lk3b = Double.NaN; + public double lw0 = Double.NaN; + public double lnlx = Double.NaN; + public double ldvt0 = Double.NaN; + public double ldvt1 = Double.NaN; + public double ldvt2 = Double.NaN; + public double ldvt0w = Double.NaN; + public double ldvt1w = Double.NaN; + public double ldvt2w = Double.NaN; + public double ldrout = Double.NaN; + public double ldsub = Double.NaN; + public double lvth0 = Double.NaN; + public double lua = Double.NaN; + public double lua1 = Double.NaN; + public double lub = Double.NaN; + public double lub1 = Double.NaN; + public double luc = Double.NaN; + public double luc1 = Double.NaN; + public double lu0 = Double.NaN; + public double lute = Double.NaN; + public double lvoff = Double.NaN; + public double ldelta = Double.NaN; + public double lrdsw = Double.NaN; + public double lprwg = Double.NaN; + public double lprwb = Double.NaN; + public double lprt = Double.NaN; + public double leta0 = Double.NaN; + public double letab = Double.NaN; + public double lpclm = Double.NaN; + public double lpdibl1 = Double.NaN; + public double lpdibl2 = Double.NaN; + public double lpdiblb = Double.NaN; + public double lpscbe1 = Double.NaN; + public double lpscbe2 = Double.NaN; + public double lpvag = Double.NaN; + public double lwr = Double.NaN; + public double ldwg = Double.NaN; + public double ldwb = Double.NaN; + public double lb0 = Double.NaN; + public double lb1 = Double.NaN; + public double lalpha0 = Double.NaN; + public double lalpha1 = Double.NaN; + public double lbeta0 = Double.NaN; + public double lvfb = Double.NaN; + public double lelm = Double.NaN; + public double lcgsl = Double.NaN; + public double lcgdl = Double.NaN; + public double lckappa = Double.NaN; + public double lcf = Double.NaN; + public double lclc = Double.NaN; + public double lcle = Double.NaN; + public double lvfbcv = Double.NaN; + public double lnoff = Double.NaN; + public double lvoffcv = Double.NaN; + public double lacde = Double.NaN; + public double lmoin = Double.NaN; + public double wcdsc = Double.NaN; + public double wcdscb = Double.NaN; + public double wcdscd = Double.NaN; + public double wcit = Double.NaN; + public double wnfactor = Double.NaN; + public double wxj = Double.NaN; + public double wvsat = Double.NaN; + public double wat = Double.NaN; + public double wa0 = Double.NaN; + public double wags = Double.NaN; + public double wa1 = Double.NaN; + public double wa2 = Double.NaN; + public double wketa = Double.NaN; + public double wnsub = Double.NaN; + public double wnpeak = Double.NaN; + public double wngate = Double.NaN; + public double wgamma1 = Double.NaN; + public double wgamma2 = Double.NaN; + public double wvbx = Double.NaN; + public double wvbm = Double.NaN; + public double wxt = Double.NaN; + public double wk1 = Double.NaN; + public double wkt1 = Double.NaN; + public double wkt1l = Double.NaN; + public double wkt2 = Double.NaN; + public double wk2 = Double.NaN; + public double wk3 = Double.NaN; + public double wk3b = Double.NaN; + public double ww0 = Double.NaN; + public double wnlx = Double.NaN; + public double wdvt0 = Double.NaN; + public double wdvt1 = Double.NaN; + public double wdvt2 = Double.NaN; + public double wdvt0w = Double.NaN; + public double wdvt1w = Double.NaN; + public double wdvt2w = Double.NaN; + public double wdrout = Double.NaN; + public double wdsub = Double.NaN; + public double wvth0 = Double.NaN; + public double wua = Double.NaN; + public double wua1 = Double.NaN; + public double wub = Double.NaN; + public double wub1 = Double.NaN; + public double wuc = Double.NaN; + public double wuc1 = Double.NaN; + public double wu0 = Double.NaN; + public double wute = Double.NaN; + public double wvoff = Double.NaN; + public double wdelta = Double.NaN; + public double wrdsw = Double.NaN; + public double wprwg = Double.NaN; + public double wprwb = Double.NaN; + public double wprt = Double.NaN; + public double weta0 = Double.NaN; + public double wetab = Double.NaN; + public double wpclm = Double.NaN; + public double wpdibl1 = Double.NaN; + public double wpdibl2 = Double.NaN; + public double wpdiblb = Double.NaN; + public double wpscbe1 = Double.NaN; + public double wpscbe2 = Double.NaN; + public double wpvag = Double.NaN; + public double wwr = Double.NaN; + public double wdwg = Double.NaN; + public double wdwb = Double.NaN; + public double wb0 = Double.NaN; + public double wb1 = Double.NaN; + public double walpha0 = Double.NaN; + public double walpha1 = Double.NaN; + public double wbeta0 = Double.NaN; + public double wvfb = Double.NaN; + public double welm = Double.NaN; + public double wcgsl = Double.NaN; + public double wcgdl = Double.NaN; + public double wckappa = Double.NaN; + public double wcf = Double.NaN; + public double wclc = Double.NaN; + public double wcle = Double.NaN; + public double wvfbcv = Double.NaN; + public double wnoff = Double.NaN; + public double wvoffcv = Double.NaN; + public double wacde = Double.NaN; + public double wmoin = Double.NaN; + public double pcdsc = Double.NaN; + public double pcdscb = Double.NaN; + public double pcdscd = Double.NaN; + public double pcit = Double.NaN; + public double pnfactor = Double.NaN; + public double pxj = Double.NaN; + public double pvsat = Double.NaN; + public double pat = Double.NaN; + public double pa0 = Double.NaN; + public double pags = Double.NaN; + public double pa1 = Double.NaN; + public double pa2 = Double.NaN; + public double pketa = Double.NaN; + public double pnsub = Double.NaN; + public double pnpeak = Double.NaN; + public double pngate = Double.NaN; + public double pgamma1 = Double.NaN; + public double pgamma2 = Double.NaN; + public double pvbx = Double.NaN; + public double pvbm = Double.NaN; + public double pxt = Double.NaN; + public double pk1 = Double.NaN; + public double pkt1 = Double.NaN; + public double pkt1l = Double.NaN; + public double pkt2 = Double.NaN; + public double pk2 = Double.NaN; + public double pk3 = Double.NaN; + public double pk3b = Double.NaN; + public double pw0 = Double.NaN; + public double pnlx = Double.NaN; + public double pdvt0 = Double.NaN; + public double pdvt1 = Double.NaN; + public double pdvt2 = Double.NaN; + public double pdvt0w = Double.NaN; + public double pdvt1w = Double.NaN; + public double pdvt2w = Double.NaN; + public double pdrout = Double.NaN; + public double pdsub = Double.NaN; + public double pvth0 = Double.NaN; + public double pua = Double.NaN; + public double pua1 = Double.NaN; + public double pub = Double.NaN; + public double pub1 = Double.NaN; + public double puc = Double.NaN; + public double puc1 = Double.NaN; + public double pu0 = Double.NaN; + public double pute = Double.NaN; + public double pvoff = Double.NaN; + public double pdelta = Double.NaN; + public double prdsw = Double.NaN; + public double pprwg = Double.NaN; + public double pprwb = Double.NaN; + public double pprt = Double.NaN; + public double peta0 = Double.NaN; + public double petab = Double.NaN; + public double ppclm = Double.NaN; + public double ppdibl1 = Double.NaN; + public double ppdibl2 = Double.NaN; + public double ppdiblb = Double.NaN; + public double ppscbe1 = Double.NaN; + public double ppscbe2 = Double.NaN; + public double ppvag = Double.NaN; + public double pwr = Double.NaN; + public double pdwg = Double.NaN; + public double pdwb = Double.NaN; + public double pb0 = Double.NaN; + public double pb1 = Double.NaN; + public double palpha0 = Double.NaN; + public double palpha1 = Double.NaN; + public double pbeta0 = Double.NaN; + public double pvfb = Double.NaN; + public double pelm = Double.NaN; + public double pcgsl = Double.NaN; + public double pcgdl = Double.NaN; + public double pckappa = Double.NaN; + public double pcf = Double.NaN; + public double pclc = Double.NaN; + public double pcle = Double.NaN; + public double pvfbcv = Double.NaN; + public double pnoff = Double.NaN; + public double pvoffcv = Double.NaN; + public double pacde = Double.NaN; + public double pmoin = Double.NaN; + + public void set(String field, String value) { + try { + if (field.equals("xl")) xl = Double.parseDouble(value); + else if (field.equals("xw")) xw = Double.parseDouble(value); + else if (field.equals("hdif")) hdif = Double.parseDouble(value); + else if (field.equals("ldif")) ldif = Double.parseDouble(value); + else if (field.equals("rs")) rs = Double.parseDouble(value); + else if (field.equals("rd")) rd = Double.parseDouble(value); + else if (field.equals("acm")) acm = Integer.parseInt(value); + else if (field.equals("cta")) cta = Double.parseDouble(value); + else if (field.equals("ctp")) ctp = Double.parseDouble(value); + else if (field.equals("pta")) pta = Double.parseDouble(value); + else if (field.equals("ptp")) ptp = Double.parseDouble(value); + else if (field.equals("n")) n = Double.parseDouble(value); + else if (field.equals("nlev")) nlev = Integer.parseInt(value); + else if (field.equals("tlev")) tlev = Double.parseDouble(value); + else if (field.equals("tlevc")) tlevc = Double.parseDouble(value); + else if (field.equals("em")) em = Double.parseDouble(value); + else if (field.equals("ef")) ef = Double.parseDouble(value); + else if (field.equals("af")) af = Double.parseDouble(value); + else if (field.equals("kf")) kf = Double.parseDouble(value); + else if (field.equals("nqsmod")) nqsMod = Integer.parseInt(value); + else if (field.equals("level")) level = Integer.parseInt(value); + else if (field.equals("capmod")) capMod = Integer.parseInt(value); + else if (field.equals("mobmod")) mobMod = Integer.parseInt(value); + else if (field.equals("noimod")) noiMod = Integer.parseInt(value); + else if (field.equals("paramchk")) paramChk = Integer.parseInt(value); + else if (field.equals("binunit")) binUnit = Integer.parseInt(value); + else if (field.equals("version")) version = value; + else if (field.equals("tox")) tox = Double.parseDouble(value); + else if (field.equals("toxm")) toxm = Double.parseDouble(value); + else if (field.equals("cdsc")) cdsc = Double.parseDouble(value); + else if (field.equals("cdscb")) cdscb = Double.parseDouble(value); + else if (field.equals("cdscd")) cdscd = Double.parseDouble(value); + else if (field.equals("cit")) cit = Double.parseDouble(value); + else if (field.equals("nfactor")) nfactor = Double.parseDouble(value); + else if (field.equals("xj")) xj = Double.parseDouble(value); + else if (field.equals("vsat")) vsat = Double.parseDouble(value); + else if (field.equals("at")) at = Double.parseDouble(value); + else if (field.equals("a0")) a0 = Double.parseDouble(value); + else if (field.equals("ags")) ags = Double.parseDouble(value); + else if (field.equals("a1")) a1 = Double.parseDouble(value); + else if (field.equals("a2")) a2 = Double.parseDouble(value); + else if (field.equals("keta")) keta = Double.parseDouble(value); + else if (field.equals("nsub")) nsub = Double.parseDouble(value); + else if (field.equals("nch")) npeak = Double.parseDouble(value); + else if (field.equals("ngate")) ngate = Double.parseDouble(value); + else if (field.equals("gamma1")) gamma1 = Double.parseDouble(value); + else if (field.equals("gamma2")) gamma2 = Double.parseDouble(value); + else if (field.equals("vbx")) vbx = Double.parseDouble(value); + else if (field.equals("vbm")) vbm = Double.parseDouble(value); + else if (field.equals("xt")) xt = Double.parseDouble(value); + else if (field.equals("k1")) k1 = Double.parseDouble(value); + else if (field.equals("kt1")) kt1 = Double.parseDouble(value); + else if (field.equals("kt1l")) kt1l = Double.parseDouble(value); + else if (field.equals("kt2")) kt2 = Double.parseDouble(value); + else if (field.equals("k2")) k2 = Double.parseDouble(value); + else if (field.equals("k3")) k3 = Double.parseDouble(value); + else if (field.equals("k3b")) k3b = Double.parseDouble(value); + else if (field.equals("w0")) w0 = Double.parseDouble(value); + else if (field.equals("nlx")) nlx = Double.parseDouble(value); + else if (field.equals("dvt0")) dvt0 = Double.parseDouble(value); + else if (field.equals("dvt1")) dvt1 = Double.parseDouble(value); + else if (field.equals("dvt2")) dvt2 = Double.parseDouble(value); + else if (field.equals("dvt0w")) dvt0w = Double.parseDouble(value); + else if (field.equals("dvt1w")) dvt1w = Double.parseDouble(value); + else if (field.equals("dvt2w")) dvt2w = Double.parseDouble(value); + else if (field.equals("drout")) drout = Double.parseDouble(value); + else if (field.equals("dsub")) dsub = Double.parseDouble(value); + else if (field.equals("vth0")) vth0 = Double.parseDouble(value); + else if (field.equals("ua")) ua = Double.parseDouble(value); + else if (field.equals("ua1")) ua1 = Double.parseDouble(value); + else if (field.equals("ub")) ub = Double.parseDouble(value); + else if (field.equals("ub1")) ub1 = Double.parseDouble(value); + else if (field.equals("uc")) uc = Double.parseDouble(value); + else if (field.equals("uc1")) uc1 = Double.parseDouble(value); + else if (field.equals("u0")) u0 = Double.parseDouble(value); + else if (field.equals("ute")) ute = Double.parseDouble(value); + else if (field.equals("voff")) voff = Double.parseDouble(value); + else if (field.equals("delta")) delta = Double.parseDouble(value); + else if (field.equals("rdsw")) rdsw = Double.parseDouble(value); + else if (field.equals("prwg")) prwg = Double.parseDouble(value); + else if (field.equals("prwb")) prwb = Double.parseDouble(value); + else if (field.equals("prt")) prt = Double.parseDouble(value); + else if (field.equals("eta0")) eta0 = Double.parseDouble(value); + else if (field.equals("etab")) etab = Double.parseDouble(value); + else if (field.equals("pclm")) pclm = Double.parseDouble(value); + else if (field.equals("pdiblc1")) pdibl1 = Double.parseDouble(value); + else if (field.equals("pdiblc2")) pdibl2 = Double.parseDouble(value); + else if (field.equals("pdiblcb")) pdiblb = Double.parseDouble(value); + else if (field.equals("pscbe1")) pscbe1 = Double.parseDouble(value); + else if (field.equals("pscbe2")) pscbe2 = Double.parseDouble(value); + else if (field.equals("pvag")) pvag = Double.parseDouble(value); + else if (field.equals("wr")) wr = Double.parseDouble(value); + else if (field.equals("dwg")) dwg = Double.parseDouble(value); + else if (field.equals("dwb")) dwb = Double.parseDouble(value); + else if (field.equals("b0")) b0 = Double.parseDouble(value); + else if (field.equals("b1")) b1 = Double.parseDouble(value); + else if (field.equals("alpha0")) alpha0 = Double.parseDouble(value); + else if (field.equals("alpha1")) alpha1 = Double.parseDouble(value); + else if (field.equals("beta0")) beta0 = Double.parseDouble(value); + else if (field.equals("ijth")) ijth = Double.parseDouble(value); + else if (field.equals("vfb")) vfb = Double.parseDouble(value); + else if (field.equals("elm")) elm = Double.parseDouble(value); + else if (field.equals("cgsl")) cgsl = Double.parseDouble(value); + else if (field.equals("cgdl")) cgdl = Double.parseDouble(value); + else if (field.equals("ckappa")) ckappa = Double.parseDouble(value); + else if (field.equals("cf")) cf = Double.parseDouble(value); + else if (field.equals("vfbcv")) vfbcv = Double.parseDouble(value); + else if (field.equals("clc")) clc = Double.parseDouble(value); + else if (field.equals("cle")) cle = Double.parseDouble(value); + else if (field.equals("dwc")) dwc = Double.parseDouble(value); + else if (field.equals("dlc")) dlc = Double.parseDouble(value); + else if (field.equals("noff")) noff = Double.parseDouble(value); + else if (field.equals("voffcv")) voffcv = Double.parseDouble(value); + else if (field.equals("acde")) acde = Double.parseDouble(value); + else if (field.equals("moin")) moin = Double.parseDouble(value); + else if (field.equals("tcj")) tcj = Double.parseDouble(value); + else if (field.equals("tcjsw")) tcjsw = Double.parseDouble(value); + else if (field.equals("tcjswg")) tcjswg = Double.parseDouble(value); + else if (field.equals("tpb")) tpb = Double.parseDouble(value); + else if (field.equals("tpbsw")) tpbsw = Double.parseDouble(value); + else if (field.equals("tpbswg")) tpbswg = Double.parseDouble(value); + else if (field.equals("tnom")) tnom = Double.parseDouble(value); + else if (field.equals("cgso")) cgso = Double.parseDouble(value); + else if (field.equals("cgdo")) cgdo = Double.parseDouble(value); + else if (field.equals("cgbo")) cgbo = Double.parseDouble(value); + else if (field.equals("xpart")) xpart = Double.parseDouble(value); + else if (field.equals("rsh")) sheetResistance = Double.parseDouble(value); + else if (field.equals("js")) jctSatCurDensity = Double.parseDouble(value); + else if (field.equals("jsw")) jctSidewallSatCurDensity = Double.parseDouble(value); + else if (field.equals("pb")) bulkJctPotential = Double.parseDouble(value); + else if (field.equals("mj")) bulkJctBotGradingCoeff = Double.parseDouble(value); + else if (field.equals("mjsw")) bulkJctSideGradingCoeff = Double.parseDouble(value); + else if (field.equals("mjswg")) bulkJctGateSideGradingCoeff = Double.parseDouble(value); + else if (field.equals("pbsw")) sidewallJctPotential = Double.parseDouble(value); + else if (field.equals("pbswg")) GatesidewallJctPotential = Double.parseDouble(value); + else if (field.equals("cj")) unitAreaJctCap = Double.parseDouble(value); + else if (field.equals("cjsw")) unitLengthSidewallJctCap = Double.parseDouble(value); + else if (field.equals("cjswg")) unitLengthGateSidewallJctCap = Double.parseDouble(value); + else if (field.equals("nj")) jctEmissionCoeff = Double.parseDouble(value); + else if (field.equals("xti")) jctTempExponent = Double.parseDouble(value); + else if (field.equals("lint")) Lint = Double.parseDouble(value); + else if (field.equals("ll")) Ll = Double.parseDouble(value); + else if (field.equals("llc")) Llc = Double.parseDouble(value); + else if (field.equals("lln")) Lln = Double.parseDouble(value); + else if (field.equals("lw")) Lw = Double.parseDouble(value); + else if (field.equals("lwc")) Lwc = Double.parseDouble(value); + else if (field.equals("lwn")) Lwn = Double.parseDouble(value); + else if (field.equals("lwl")) Lwl = Double.parseDouble(value); + else if (field.equals("lwlc")) Lwlc = Double.parseDouble(value); + else if (field.equals("lmin")) Lmin = Double.parseDouble(value); + else if (field.equals("lmax")) Lmax = Double.parseDouble(value); + else if (field.equals("wint")) Wint = Double.parseDouble(value); + else if (field.equals("wl")) Wl = Double.parseDouble(value); + else if (field.equals("wlc")) Wlc = Double.parseDouble(value); + else if (field.equals("wln")) Wln = Double.parseDouble(value); + else if (field.equals("ww")) Ww = Double.parseDouble(value); + else if (field.equals("wwc")) Wwc = Double.parseDouble(value); + else if (field.equals("wwn")) Wwn = Double.parseDouble(value); + else if (field.equals("wwl")) Wwl = Double.parseDouble(value); + else if (field.equals("wwlc")) Wwlc = Double.parseDouble(value); + else if (field.equals("wmin")) Wmin = Double.parseDouble(value); + else if (field.equals("wmax")) Wmax = Double.parseDouble(value); + else if (field.equals("lcdsc")) lcdsc = Double.parseDouble(value); + else if (field.equals("lcdscb")) lcdscb = Double.parseDouble(value); + else if (field.equals("lcdscd")) lcdscd = Double.parseDouble(value); + else if (field.equals("lcit")) lcit = Double.parseDouble(value); + else if (field.equals("lnfactor")) lnfactor = Double.parseDouble(value); + else if (field.equals("lxj")) lxj = Double.parseDouble(value); + else if (field.equals("lvsat")) lvsat = Double.parseDouble(value); + else if (field.equals("lat")) lat = Double.parseDouble(value); + else if (field.equals("la0")) la0 = Double.parseDouble(value); + else if (field.equals("lags")) lags = Double.parseDouble(value); + else if (field.equals("la1")) la1 = Double.parseDouble(value); + else if (field.equals("la2")) la2 = Double.parseDouble(value); + else if (field.equals("lketa")) lketa = Double.parseDouble(value); + else if (field.equals("lnsub")) lnsub = Double.parseDouble(value); + else if (field.equals("lnch")) lnpeak = Double.parseDouble(value); + else if (field.equals("lngate")) lngate = Double.parseDouble(value); + else if (field.equals("lgamma1")) lgamma1 = Double.parseDouble(value); + else if (field.equals("lgamma2")) lgamma2 = Double.parseDouble(value); + else if (field.equals("lvbx")) lvbx = Double.parseDouble(value); + else if (field.equals("lvbm")) lvbm = Double.parseDouble(value); + else if (field.equals("lxt")) lxt = Double.parseDouble(value); + else if (field.equals("lk1")) lk1 = Double.parseDouble(value); + else if (field.equals("lkt1")) lkt1 = Double.parseDouble(value); + else if (field.equals("lkt1l")) lkt1l = Double.parseDouble(value); + else if (field.equals("lkt2")) lkt2 = Double.parseDouble(value); + else if (field.equals("lk2")) lk2 = Double.parseDouble(value); + else if (field.equals("lk3")) lk3 = Double.parseDouble(value); + else if (field.equals("lk3b")) lk3b = Double.parseDouble(value); + else if (field.equals("lw0")) lw0 = Double.parseDouble(value); + else if (field.equals("lnlx")) lnlx = Double.parseDouble(value); + else if (field.equals("ldvt0")) ldvt0 = Double.parseDouble(value); + else if (field.equals("ldvt1")) ldvt1 = Double.parseDouble(value); + else if (field.equals("ldvt2")) ldvt2 = Double.parseDouble(value); + else if (field.equals("ldvt0w")) ldvt0w = Double.parseDouble(value); + else if (field.equals("ldvt1w")) ldvt1w = Double.parseDouble(value); + else if (field.equals("ldvt2w")) ldvt2w = Double.parseDouble(value); + else if (field.equals("ldrout")) ldrout = Double.parseDouble(value); + else if (field.equals("ldsub")) ldsub = Double.parseDouble(value); + else if (field.equals("lvth0")) lvth0 = Double.parseDouble(value); + else if (field.equals("lua")) lua = Double.parseDouble(value); + else if (field.equals("lua1")) lua1 = Double.parseDouble(value); + else if (field.equals("lub")) lub = Double.parseDouble(value); + else if (field.equals("lub1")) lub1 = Double.parseDouble(value); + else if (field.equals("luc")) luc = Double.parseDouble(value); + else if (field.equals("luc1")) luc1 = Double.parseDouble(value); + else if (field.equals("lu0")) lu0 = Double.parseDouble(value); + else if (field.equals("lute")) lute = Double.parseDouble(value); + else if (field.equals("lvoff")) lvoff = Double.parseDouble(value); + else if (field.equals("ldelta")) ldelta = Double.parseDouble(value); + else if (field.equals("lrdsw")) lrdsw = Double.parseDouble(value); + else if (field.equals("lprwg")) lprwg = Double.parseDouble(value); + else if (field.equals("lprwb")) lprwb = Double.parseDouble(value); + else if (field.equals("lprt")) lprt = Double.parseDouble(value); + else if (field.equals("leta0")) leta0 = Double.parseDouble(value); + else if (field.equals("letab")) letab = Double.parseDouble(value); + else if (field.equals("lpclm")) lpclm = Double.parseDouble(value); + else if (field.equals("lpdiblc1")) lpdibl1 = Double.parseDouble(value); + else if (field.equals("lpdiblc2")) lpdibl2 = Double.parseDouble(value); + else if (field.equals("lpdiblcb")) lpdiblb = Double.parseDouble(value); + else if (field.equals("lpscbe1")) lpscbe1 = Double.parseDouble(value); + else if (field.equals("lpscbe2")) lpscbe2 = Double.parseDouble(value); + else if (field.equals("lpvag")) lpvag = Double.parseDouble(value); + else if (field.equals("lwr")) lwr = Double.parseDouble(value); + else if (field.equals("ldwg")) ldwg = Double.parseDouble(value); + else if (field.equals("ldwb")) ldwb = Double.parseDouble(value); + else if (field.equals("lb0")) lb0 = Double.parseDouble(value); + else if (field.equals("lb1")) lb1 = Double.parseDouble(value); + else if (field.equals("lalpha0")) lalpha0 = Double.parseDouble(value); + else if (field.equals("lalpha1")) lalpha1 = Double.parseDouble(value); + else if (field.equals("lbeta0")) lbeta0 = Double.parseDouble(value); + else if (field.equals("lvfb")) lvfb = Double.parseDouble(value); + else if (field.equals("lelm")) lelm = Double.parseDouble(value); + else if (field.equals("lcgsl")) lcgsl = Double.parseDouble(value); + else if (field.equals("lcgdl")) lcgdl = Double.parseDouble(value); + else if (field.equals("lckappa")) lckappa = Double.parseDouble(value); + else if (field.equals("lcg")) lcf = Double.parseDouble(value); + else if (field.equals("lclc")) lclc = Double.parseDouble(value); + else if (field.equals("lcle")) lcle = Double.parseDouble(value); + else if (field.equals("lvfbcv")) lvfbcv = Double.parseDouble(value); + else if (field.equals("lnoff")) lnoff = Double.parseDouble(value); + else if (field.equals("lvoffcv")) lvoffcv = Double.parseDouble(value); + else if (field.equals("lacde")) lacde = Double.parseDouble(value); + else if (field.equals("lmoin")) lmoin = Double.parseDouble(value); + else if (field.equals("wcdsc")) wcdsc = Double.parseDouble(value); + else if (field.equals("wcdscb")) wcdscb = Double.parseDouble(value); + else if (field.equals("wcdscd")) wcdscd = Double.parseDouble(value); + else if (field.equals("wcit")) wcit = Double.parseDouble(value); + else if (field.equals("wnfactor")) wnfactor = Double.parseDouble(value); + else if (field.equals("wxj")) wxj = Double.parseDouble(value); + else if (field.equals("wvsat")) wvsat = Double.parseDouble(value); + else if (field.equals("wat")) wat = Double.parseDouble(value); + else if (field.equals("wa0")) wa0 = Double.parseDouble(value); + else if (field.equals("wags")) wags = Double.parseDouble(value); + else if (field.equals("wa1")) wa1 = Double.parseDouble(value); + else if (field.equals("wa2")) wa2 = Double.parseDouble(value); + else if (field.equals("wketa")) wketa = Double.parseDouble(value); + else if (field.equals("wnsub")) wnsub = Double.parseDouble(value); + else if (field.equals("wnch")) wnpeak = Double.parseDouble(value); + else if (field.equals("wngate")) wngate = Double.parseDouble(value); + else if (field.equals("wgamma1")) wgamma1 = Double.parseDouble(value); + else if (field.equals("wgamma2")) wgamma2 = Double.parseDouble(value); + else if (field.equals("wvbx")) wvbx = Double.parseDouble(value); + else if (field.equals("wvbm")) wvbm = Double.parseDouble(value); + else if (field.equals("wxt")) wxt = Double.parseDouble(value); + else if (field.equals("wk1")) wk1 = Double.parseDouble(value); + else if (field.equals("wkt1")) wkt1 = Double.parseDouble(value); + else if (field.equals("wkt1l")) wkt1l = Double.parseDouble(value); + else if (field.equals("wkt2")) wkt2 = Double.parseDouble(value); + else if (field.equals("wk2")) wk2 = Double.parseDouble(value); + else if (field.equals("wk3")) wk3 = Double.parseDouble(value); + else if (field.equals("wk3b")) wk3b = Double.parseDouble(value); + else if (field.equals("ww0")) ww0 = Double.parseDouble(value); + else if (field.equals("wnlx")) wnlx = Double.parseDouble(value); + else if (field.equals("wdvt0")) wdvt0 = Double.parseDouble(value); + else if (field.equals("wdvt1")) wdvt1 = Double.parseDouble(value); + else if (field.equals("wdvt2")) wdvt2 = Double.parseDouble(value); + else if (field.equals("wdvt0w")) wdvt0w = Double.parseDouble(value); + else if (field.equals("wdvt1w")) wdvt1w = Double.parseDouble(value); + else if (field.equals("wdvt2w")) wdvt2w = Double.parseDouble(value); + else if (field.equals("wdrout")) wdrout = Double.parseDouble(value); + else if (field.equals("wdsub")) wdsub = Double.parseDouble(value); + else if (field.equals("wvth0")) wvth0 = Double.parseDouble(value); + else if (field.equals("wua")) wua = Double.parseDouble(value); + else if (field.equals("wua1")) wua1 = Double.parseDouble(value); + else if (field.equals("wub")) wub = Double.parseDouble(value); + else if (field.equals("wub1")) wub1 = Double.parseDouble(value); + else if (field.equals("wuc")) wuc = Double.parseDouble(value); + else if (field.equals("wuc1")) wuc1 = Double.parseDouble(value); + else if (field.equals("wu0")) wu0 = Double.parseDouble(value); + else if (field.equals("wute")) wute = Double.parseDouble(value); + else if (field.equals("wvoff")) wvoff = Double.parseDouble(value); + else if (field.equals("wdelta")) wdelta = Double.parseDouble(value); + else if (field.equals("wrdsw")) wrdsw = Double.parseDouble(value); + else if (field.equals("wprwg")) wprwg = Double.parseDouble(value); + else if (field.equals("wprwb")) wprwb = Double.parseDouble(value); + else if (field.equals("wprt")) wprt = Double.parseDouble(value); + else if (field.equals("weta0")) weta0 = Double.parseDouble(value); + else if (field.equals("wetab")) wetab = Double.parseDouble(value); + else if (field.equals("wpclm")) wpclm = Double.parseDouble(value); + else if (field.equals("wpdiblc1")) wpdibl1 = Double.parseDouble(value); + else if (field.equals("wpdiblc2")) wpdibl2 = Double.parseDouble(value); + else if (field.equals("wpdiblcb")) wpdiblb = Double.parseDouble(value); + else if (field.equals("wpscbe1")) wpscbe1 = Double.parseDouble(value); + else if (field.equals("wpscbe2")) wpscbe2 = Double.parseDouble(value); + else if (field.equals("wpvag")) wpvag = Double.parseDouble(value); + else if (field.equals("wwr")) wwr = Double.parseDouble(value); + else if (field.equals("wdwg")) wdwg = Double.parseDouble(value); + else if (field.equals("wdwb")) wdwb = Double.parseDouble(value); + else if (field.equals("wb0")) wb0 = Double.parseDouble(value); + else if (field.equals("wb1")) wb1 = Double.parseDouble(value); + else if (field.equals("walpha0")) walpha0 = Double.parseDouble(value); + else if (field.equals("walpha1")) walpha1 = Double.parseDouble(value); + else if (field.equals("wbeta0")) wbeta0 = Double.parseDouble(value); + else if (field.equals("wvfb")) wvfb = Double.parseDouble(value); + else if (field.equals("welm")) welm = Double.parseDouble(value); + else if (field.equals("wcgsl")) wcgsl = Double.parseDouble(value); + else if (field.equals("wcgdl")) wcgdl = Double.parseDouble(value); + else if (field.equals("wckappa")) wckappa = Double.parseDouble(value); + else if (field.equals("wcg")) wcf = Double.parseDouble(value); + else if (field.equals("wclc")) wclc = Double.parseDouble(value); + else if (field.equals("wcle")) wcle = Double.parseDouble(value); + else if (field.equals("wvfbcv")) wvfbcv = Double.parseDouble(value); + else if (field.equals("wnoff")) wnoff = Double.parseDouble(value); + else if (field.equals("wvoffcv")) wvoffcv = Double.parseDouble(value); + else if (field.equals("wacde")) wacde = Double.parseDouble(value); + else if (field.equals("wmoin")) wmoin = Double.parseDouble(value); + else if (field.equals("pcdsc")) pcdsc = Double.parseDouble(value); + else if (field.equals("pcdscb")) pcdscb = Double.parseDouble(value); + else if (field.equals("pcdscd")) pcdscd = Double.parseDouble(value); + else if (field.equals("pcit")) pcit = Double.parseDouble(value); + else if (field.equals("pnfactor")) pnfactor = Double.parseDouble(value); + else if (field.equals("pxj")) pxj = Double.parseDouble(value); + else if (field.equals("pvsat")) pvsat = Double.parseDouble(value); + else if (field.equals("pat")) pat = Double.parseDouble(value); + else if (field.equals("pa0")) pa0 = Double.parseDouble(value); + else if (field.equals("pags")) pags = Double.parseDouble(value); + else if (field.equals("pa1")) pa1 = Double.parseDouble(value); + else if (field.equals("pa2")) pa2 = Double.parseDouble(value); + else if (field.equals("pketa")) pketa = Double.parseDouble(value); + else if (field.equals("pnsub")) pnsub = Double.parseDouble(value); + else if (field.equals("pnch")) pnpeak = Double.parseDouble(value); + else if (field.equals("pngate")) pngate = Double.parseDouble(value); + else if (field.equals("pgamma1")) pgamma1 = Double.parseDouble(value); + else if (field.equals("pgamma2")) pgamma2 = Double.parseDouble(value); + else if (field.equals("pvbx")) pvbx = Double.parseDouble(value); + else if (field.equals("pvbm")) pvbm = Double.parseDouble(value); + else if (field.equals("pxt")) pxt = Double.parseDouble(value); + else if (field.equals("pk1")) pk1 = Double.parseDouble(value); + else if (field.equals("pkt1")) pkt1 = Double.parseDouble(value); + else if (field.equals("pkt1l")) pkt1l = Double.parseDouble(value); + else if (field.equals("pkt2")) pkt2 = Double.parseDouble(value); + else if (field.equals("pk2")) pk2 = Double.parseDouble(value); + else if (field.equals("pk3")) pk3 = Double.parseDouble(value); + else if (field.equals("pk3b")) pk3b = Double.parseDouble(value); + else if (field.equals("pw0")) pw0 = Double.parseDouble(value); + else if (field.equals("pnlx")) pnlx = Double.parseDouble(value); + else if (field.equals("pdvt0")) pdvt0 = Double.parseDouble(value); + else if (field.equals("pdvt1")) pdvt1 = Double.parseDouble(value); + else if (field.equals("pdvt2")) pdvt2 = Double.parseDouble(value); + else if (field.equals("pdvt0w")) pdvt0w = Double.parseDouble(value); + else if (field.equals("pdvt1w")) pdvt1w = Double.parseDouble(value); + else if (field.equals("pdvt2w")) pdvt2w = Double.parseDouble(value); + else if (field.equals("pdrout")) pdrout = Double.parseDouble(value); + else if (field.equals("pdsub")) pdsub = Double.parseDouble(value); + else if (field.equals("pvth0")) pvth0 = Double.parseDouble(value); + else if (field.equals("pua")) pua = Double.parseDouble(value); + else if (field.equals("pua1")) pua1 = Double.parseDouble(value); + else if (field.equals("pub")) pub = Double.parseDouble(value); + else if (field.equals("pub1")) pub1 = Double.parseDouble(value); + else if (field.equals("puc")) puc = Double.parseDouble(value); + else if (field.equals("puc1")) puc1 = Double.parseDouble(value); + else if (field.equals("pu0")) pu0 = Double.parseDouble(value); + else if (field.equals("pute")) pute = Double.parseDouble(value); + else if (field.equals("pvoff")) pvoff = Double.parseDouble(value); + else if (field.equals("pdelta")) pdelta = Double.parseDouble(value); + else if (field.equals("prdsw")) prdsw = Double.parseDouble(value); + else if (field.equals("pprwg")) pprwg = Double.parseDouble(value); + else if (field.equals("pprwb")) pprwb = Double.parseDouble(value); + else if (field.equals("pprt")) pprt = Double.parseDouble(value); + else if (field.equals("peta0")) peta0 = Double.parseDouble(value); + else if (field.equals("petab")) petab = Double.parseDouble(value); + else if (field.equals("ppclm")) ppclm = Double.parseDouble(value); + else if (field.equals("ppdiblc1")) ppdibl1 = Double.parseDouble(value); + else if (field.equals("ppdiblc2")) ppdibl2 = Double.parseDouble(value); + else if (field.equals("ppdiblcb")) ppdiblb = Double.parseDouble(value); + else if (field.equals("ppscbe1")) ppscbe1 = Double.parseDouble(value); + else if (field.equals("ppscbe2")) ppscbe2 = Double.parseDouble(value); + else if (field.equals("ppvag")) ppvag = Double.parseDouble(value); + else if (field.equals("pwr")) pwr = Double.parseDouble(value); + else if (field.equals("pdwg")) pdwg = Double.parseDouble(value); + else if (field.equals("pdwb")) pdwb = Double.parseDouble(value); + else if (field.equals("pb0")) pb0 = Double.parseDouble(value); + else if (field.equals("pb1")) pb1 = Double.parseDouble(value); + else if (field.equals("palpha0")) palpha0 = Double.parseDouble(value); + else if (field.equals("palpha1")) palpha1 = Double.parseDouble(value); + else if (field.equals("pbeta0")) pbeta0 = Double.parseDouble(value); + else if (field.equals("pvfb")) pvfb = Double.parseDouble(value); + else if (field.equals("pelm")) pelm = Double.parseDouble(value); + else if (field.equals("pcgsl")) pcgsl = Double.parseDouble(value); + else if (field.equals("pcgdl")) pcgdl = Double.parseDouble(value); + else if (field.equals("pckappa")) pckappa = Double.parseDouble(value); + else if (field.equals("pcg")) pcf = Double.parseDouble(value); + else if (field.equals("pclc")) pclc = Double.parseDouble(value); + else if (field.equals("pcle")) pcle = Double.parseDouble(value); + else if (field.equals("pvfbcv")) pvfbcv = Double.parseDouble(value); + else if (field.equals("pnoff")) pnoff = Double.parseDouble(value); + else if (field.equals("pvoffcv")) pvoffcv = Double.parseDouble(value); + else if (field.equals("pacde")) pacde = Double.parseDouble(value); + else if (field.equals("pmoin")) pmoin = Double.parseDouble(value); + } catch (NumberFormatException e) { + System.out.println(value + " is not a number"); + } + } + + void setDefaults() { + if (!given(type)) type = NMOS; + if (!given(mobMod)) mobMod = 1; + if (!given(binUnit)) binUnit = 1; + if (!given(paramChk)) paramChk = 0; + if (!given(capMod)) capMod = 3; + if (!given(noiMod)) noiMod = 1; + if (!given(nqsMod)) nqsMod = 0; + if (!given(version)) version = "3.2.2"; + if (!given(tox)) tox = 150.0e-10; + cox = 3.453133e-11 / tox; + if (!given(toxm)) toxm = tox; + + if (!given(cdsc)) cdsc = 2.4e-4; /* unit Q/V/m^2 */ + if (!given(cdscb)) cdscb = 0.0; /* unit Q/V/m^2 */ + if (!given(cdscd)) cdscd = 0.0; /* unit Q/V/m^2 */ + if (!given(cit)) cit = 0.0; /* unit Q/V/m^2 */ + if (!given(nfactor)) nfactor = 1; + if (!given(xj)) xj = .15e-6; + if (!given(vsat)) vsat = 8.0e4; /* unit m/s */ + if (!given(at)) at = 3.3e4; /* unit m/s */ + if (!given(a0)) a0 = 1.0; + if (!given(ags)) ags = 0.0; + if (!given(a1)) a1 = 0.0; + if (!given(a2)) a2 = 1.0; + if (!given(keta)) keta = -0.047; /* unit / V */ + if (!given(nsub) && !given(k1) && !given(k2)) nsub = 6.0e16; /* unit 1/cm3 */ + if (!given(npeak)) npeak = 1.7e17; /* unit 1/cm3 */ + if (!given(ngate)) ngate = 0; /* unit 1/cm3 */ + if (!given(vbm)) vbm = -3.0; + if (!given(xt) && !given(k1) && !given(k2)) xt = 1.55e-7; + if (!given(kt1)) kt1 = -0.11; /* unit V */ + if (!given(kt1l)) kt1l = 0.0; /* unit V*m */ + if (!given(kt2)) kt2 = 0.022; /* No unit */ + if (!given(k3)) k3 = 80.0; + if (!given(k3b)) k3b = 0.0; + if (!given(w0)) w0 = 2.5e-6; + if (!given(nlx)) nlx = 1.74e-7; + if (!given(dvt0)) dvt0 = 2.2; + if (!given(dvt1)) dvt1 = 0.53; + if (!given(dvt2)) dvt2 = -0.032; /* unit 1 / V */ + + if (!given(dvt0w)) dvt0w = 0.0; + if (!given(dvt1w)) dvt1w = 5.3e6; + if (!given(dvt2w)) dvt2w = -0.032; + + if (!given(drout)) drout = 0.56; + if (!given(dsub)) dsub = drout; + if (!given(vth0)) vth0 = (type == NMOS) ? 0.7 : -0.7; + if (!given(ua)) ua = 2.25e-9; /* unit m/V */ + if (!given(ua1)) ua1 = 4.31e-9; /* unit m/V */ + if (!given(ub)) ub = 5.87e-19; /* unit (m/V)**2 */ + if (!given(ub1)) ub1 = -7.61e-18; /* unit (m/V)**2 */ + if (!given(uc)) uc = (mobMod == 3) ? -0.0465 : -0.0465e-9; + if (!given(uc1)) uc1 = (mobMod == 3) ? -0.056 : -0.056e-9; + if (!given(u0)) u0 = (type == NMOS) ? 0.067 : 0.025; + if (!given(ute)) ute = -1.5; + if (!given(voff)) voff = -0.08; + if (!given(delta)) delta = 0.01; + if (!given(rdsw)) rdsw = 0; + if (!given(prwg)) prwg = 0.0; /* unit 1/V */ + if (!given(prwb)) prwb = 0.0; + if (!given(prt)) prt = 0.0; + if (!given(eta0)) eta0 = 0.08; /* no unit */ + if (!given(etab)) etab = -0.07; /* unit 1/V */ + if (!given(pclm)) pclm = 1.3; /* no unit */ + if (!given(pdibl1)) pdibl1 = .39; /* no unit */ + if (!given(pdibl2)) pdibl2 = 0.0086; /* no unit */ + if (!given(pdiblb)) pdiblb = 0.0; /* 1/V */ + if (!given(pscbe1)) pscbe1 = 4.24e8; + if (!given(pscbe2)) pscbe2 = 1.0e-5; + if (!given(pvag)) pvag = 0.0; + if (!given(wr)) wr = 1.0; + if (!given(dwg)) dwg = 0.0; + if (!given(dwb)) dwb = 0.0; + if (!given(b0)) b0 = 0.0; + if (!given(b1)) b1 = 0.0; + if (!given(alpha0)) alpha0 = 0.0; + if (!given(alpha1)) alpha1 = 0.0; + if (!given(beta0)) beta0 = 30.0; + if (!given(ijth)) ijth = 0.1; /* unit A */ + + if (!given(elm)) elm = 5.0; + if (!given(cgsl)) cgsl = 0.0; + if (!given(cgdl)) cgdl = 0.0; + if (!given(ckappa)) ckappa = 0.6; + if (!given(clc)) clc = 0.1e-6; + if (!given(cle)) cle = 0.6; + if (!given(vfbcv)) vfbcv = -1.0; + if (!given(acde)) acde = 1.0; + if (!given(moin)) moin = 15.0; + if (!given(noff)) noff = 1.0; + if (!given(voffcv)) voffcv = 0.0; + if (!given(tcj)) tcj = 0.0; + if (!given(tpb)) tpb = 0.0; + if (!given(tcjsw)) tcjsw = 0.0; + if (!given(tpbsw)) tpbsw = 0.0; + if (!given(tcjswg)) tcjswg = 0.0; + if (!given(tpbswg)) tpbswg = 0.0; + + /* Length dependence */ + if (!given(lcdsc)) lcdsc = 0.0; + if (!given(lcdscb)) lcdscb = 0.0; + if (!given(lcdscd)) lcdscd = 0.0; + if (!given(lcit)) lcit = 0.0; + if (!given(lnfactor)) lnfactor = 0.0; + if (!given(lxj)) lxj = 0.0; + if (!given(lvsat)) lvsat = 0.0; + if (!given(lat)) lat = 0.0; + if (!given(la0)) la0 = 0.0; + if (!given(lags)) lags = 0.0; + if (!given(la1)) la1 = 0.0; + if (!given(la2)) la2 = 0.0; + if (!given(lketa)) lketa = 0.0; + if (!given(lnsub)) lnsub = 0.0; + if (!given(lnpeak)) lnpeak = 0.0; + if (!given(lngate)) lngate = 0.0; + if (!given(lvbm)) lvbm = 0.0; + if (!given(lxt)) lxt = 0.0; + if (!given(lkt1)) lkt1 = 0.0; + if (!given(lkt1l)) lkt1l = 0.0; + if (!given(lkt2)) lkt2 = 0.0; + if (!given(lk3)) lk3 = 0.0; + if (!given(lk3b)) lk3b = 0.0; + if (!given(lw0)) lw0 = 0.0; + if (!given(lnlx)) lnlx = 0.0; + if (!given(ldvt0)) ldvt0 = 0.0; + if (!given(ldvt1)) ldvt1 = 0.0; + if (!given(ldvt2)) ldvt2 = 0.0; + if (!given(ldvt0w)) ldvt0w = 0.0; + if (!given(ldvt1w)) ldvt1w = 0.0; + if (!given(ldvt2w)) ldvt2w = 0.0; + if (!given(ldrout)) ldrout = 0.0; + if (!given(ldsub)) ldsub = 0.0; + if (!given(lvth0)) lvth0 = 0.0; + if (!given(lua)) lua = 0.0; + if (!given(lua1)) lua1 = 0.0; + if (!given(lub)) lub = 0.0; + if (!given(lub1)) lub1 = 0.0; + if (!given(luc)) luc = 0.0; + if (!given(luc1)) luc1 = 0.0; + if (!given(lu0)) lu0 = 0.0; + if (!given(lute)) lute = 0.0; + if (!given(lvoff)) lvoff = 0.0; + if (!given(ldelta)) ldelta = 0.0; + if (!given(lrdsw)) lrdsw = 0.0; + if (!given(lprwb)) lprwb = 0.0; + if (!given(lprwg)) lprwg = 0.0; + if (!given(lprt)) lprt = 0.0; + if (!given(leta0)) leta0 = 0.0; + if (!given(letab)) letab = -0.0; + if (!given(lpclm)) lpclm = 0.0; + if (!given(lpdibl1)) lpdibl1 = 0.0; + if (!given(lpdibl2)) lpdibl2 = 0.0; + if (!given(lpdiblb)) lpdiblb = 0.0; + if (!given(lpscbe1)) lpscbe1 = 0.0; + if (!given(lpscbe2)) lpscbe2 = 0.0; + if (!given(lpvag)) lpvag = 0.0; + if (!given(lwr)) lwr = 0.0; + if (!given(ldwg)) ldwg = 0.0; + if (!given(ldwb)) ldwb = 0.0; + if (!given(lb0)) lb0 = 0.0; + if (!given(lb1)) lb1 = 0.0; + if (!given(lalpha0)) lalpha0 = 0.0; + if (!given(lalpha1)) lalpha1 = 0.0; + if (!given(lbeta0)) lbeta0 = 0.0; + if (!given(lvfb)) lvfb = 0.0; + + if (!given(lelm)) lelm = 0.0; + if (!given(lcgsl)) lcgsl = 0.0; + if (!given(lcgdl)) lcgdl = 0.0; + if (!given(lckappa)) lckappa = 0.0; + if (!given(lclc)) lclc = 0.0; + if (!given(lcle)) lcle = 0.0; + if (!given(lcf)) lcf = 0.0; + if (!given(lvfbcv)) lvfbcv = 0.0; + if (!given(lacde)) lacde = 0.0; + if (!given(lmoin)) lmoin = 0.0; + if (!given(lnoff)) lnoff = 0.0; + if (!given(lvoffcv)) lvoffcv = 0.0; + + /* Width dependence */ + if (!given(wcdsc)) wcdsc = 0.0; + if (!given(wcdscb)) wcdscb = 0.0; + if (!given(wcdscd)) wcdscd = 0.0; + if (!given(wcit)) wcit = 0.0; + if (!given(wnfactor)) wnfactor = 0.0; + if (!given(wxj)) wxj = 0.0; + if (!given(wvsat)) wvsat = 0.0; + if (!given(wat)) wat = 0.0; + if (!given(wa0)) wa0 = 0.0; + if (!given(wags)) wags = 0.0; + if (!given(wa1)) wa1 = 0.0; + if (!given(wa2)) wa2 = 0.0; + if (!given(wketa)) wketa = 0.0; + if (!given(wnsub)) wnsub = 0.0; + if (!given(wnpeak)) wnpeak = 0.0; + if (!given(wngate)) wngate = 0.0; + if (!given(wvbm)) wvbm = 0.0; + if (!given(wxt)) wxt = 0.0; + if (!given(wkt1)) wkt1 = 0.0; + if (!given(wkt1l)) wkt1l = 0.0; + if (!given(wkt2)) wkt2 = 0.0; + if (!given(wk3)) wk3 = 0.0; + if (!given(wk3b)) wk3b = 0.0; + if (!given(ww0)) ww0 = 0.0; + if (!given(wnlx)) wnlx = 0.0; + if (!given(wdvt0)) wdvt0 = 0.0; + if (!given(wdvt1)) wdvt1 = 0.0; + if (!given(wdvt2)) wdvt2 = 0.0; + if (!given(wdvt0w)) wdvt0w = 0.0; + if (!given(wdvt1w)) wdvt1w = 0.0; + if (!given(wdvt2w)) wdvt2w = 0.0; + if (!given(wdrout)) wdrout = 0.0; + if (!given(wdsub)) wdsub = 0.0; + if (!given(wvth0)) wvth0 = 0.0; + if (!given(wua)) wua = 0.0; + if (!given(wua1)) wua1 = 0.0; + if (!given(wub)) wub = 0.0; + if (!given(wub1)) wub1 = 0.0; + if (!given(wuc)) wuc = 0.0; + if (!given(wuc1)) wuc1 = 0.0; + if (!given(wu0)) wu0 = 0.0; + if (!given(wute)) wute = 0.0; + if (!given(wvoff)) wvoff = 0.0; + if (!given(wdelta)) wdelta = 0.0; + if (!given(wrdsw)) wrdsw = 0.0; + if (!given(wprwb)) wprwb = 0.0; + if (!given(wprwg)) wprwg = 0.0; + if (!given(wprt)) wprt = 0.0; + if (!given(weta0)) weta0 = 0.0; + if (!given(wetab)) wetab = 0.0; + if (!given(wpclm)) wpclm = 0.0; + if (!given(wpdibl1)) wpdibl1 = 0.0; + if (!given(wpdibl2)) wpdibl2 = 0.0; + if (!given(wpdiblb)) wpdiblb = 0.0; + if (!given(wpscbe1)) wpscbe1 = 0.0; + if (!given(wpscbe2)) wpscbe2 = 0.0; + if (!given(wpvag)) wpvag = 0.0; + if (!given(wwr)) wwr = 0.0; + if (!given(wdwg)) wdwg = 0.0; + if (!given(wdwb)) wdwb = 0.0; + if (!given(wb0)) wb0 = 0.0; + if (!given(wb1)) wb1 = 0.0; + if (!given(walpha0)) walpha0 = 0.0; + if (!given(walpha1)) walpha1 = 0.0; + if (!given(wbeta0)) wbeta0 = 0.0; + if (!given(wvfb)) wvfb = 0.0; + + if (!given(welm)) welm = 0.0; + if (!given(wcgsl)) wcgsl = 0.0; + if (!given(wcgdl)) wcgdl = 0.0; + if (!given(wckappa)) wckappa = 0.0; + if (!given(wcf)) wcf = 0.0; + if (!given(wclc)) wclc = 0.0; + if (!given(wcle)) wcle = 0.0; + if (!given(wvfbcv)) wvfbcv = 0.0; + if (!given(wacde)) wacde = 0.0; + if (!given(wmoin)) wmoin = 0.0; + if (!given(wnoff)) wnoff = 0.0; + if (!given(wvoffcv)) wvoffcv = 0.0; + + /* Cross-term dependence */ + if (!given(pcdsc)) pcdsc = 0.0; + if (!given(pcdscb)) pcdscb = 0.0; + if (!given(pcdscd)) pcdscd = 0.0; + if (!given(pcit)) pcit = 0.0; + if (!given(pnfactor)) pnfactor = 0.0; + if (!given(pxj)) pxj = 0.0; + if (!given(pvsat)) pvsat = 0.0; + if (!given(pat)) pat = 0.0; + if (!given(pa0)) pa0 = 0.0; + + if (!given(pags)) pags = 0.0; + if (!given(pa1)) pa1 = 0.0; + if (!given(pa2)) pa2 = 0.0; + if (!given(pketa)) pketa = 0.0; + if (!given(pnsub)) pnsub = 0.0; + if (!given(pnpeak)) pnpeak = 0.0; + if (!given(pngate)) pngate = 0.0; + if (!given(pvbm)) pvbm = 0.0; + if (!given(pxt)) pxt = 0.0; + if (!given(pkt1)) pkt1 = 0.0; + if (!given(pkt1l)) pkt1l = 0.0; + if (!given(pkt2)) pkt2 = 0.0; + if (!given(pk3)) pk3 = 0.0; + if (!given(pk3b)) pk3b = 0.0; + if (!given(pw0)) pw0 = 0.0; + if (!given(pnlx)) pnlx = 0.0; + if (!given(pdvt0)) pdvt0 = 0.0; + if (!given(pdvt1)) pdvt1 = 0.0; + if (!given(pdvt2)) pdvt2 = 0.0; + if (!given(pdvt0w)) pdvt0w = 0.0; + if (!given(pdvt1w)) pdvt1w = 0.0; + if (!given(pdvt2w)) pdvt2w = 0.0; + if (!given(pdrout)) pdrout = 0.0; + if (!given(pdsub)) pdsub = 0.0; + if (!given(pvth0)) pvth0 = 0.0; + if (!given(pua)) pua = 0.0; + if (!given(pua1)) pua1 = 0.0; + if (!given(pub)) pub = 0.0; + if (!given(pub1)) pub1 = 0.0; + if (!given(puc)) puc = 0.0; + if (!given(puc1)) puc1 = 0.0; + if (!given(pu0)) pu0 = 0.0; + if (!given(pute)) pute = 0.0; + if (!given(pvoff)) pvoff = 0.0; + if (!given(pdelta)) pdelta = 0.0; + if (!given(prdsw)) prdsw = 0.0; + if (!given(pprwb)) pprwb = 0.0; + if (!given(pprwg)) pprwg = 0.0; + if (!given(pprt)) pprt = 0.0; + if (!given(peta0)) peta0 = 0.0; + if (!given(petab)) petab = 0.0; + if (!given(ppclm)) ppclm = 0.0; + if (!given(ppdibl1)) ppdibl1 = 0.0; + if (!given(ppdibl2)) ppdibl2 = 0.0; + if (!given(ppdiblb)) ppdiblb = 0.0; + if (!given(ppscbe1)) ppscbe1 = 0.0; + if (!given(ppscbe2)) ppscbe2 = 0.0; + if (!given(ppvag)) ppvag = 0.0; + if (!given(pwr)) pwr = 0.0; + if (!given(pdwg)) pdwg = 0.0; + if (!given(pdwb)) pdwb = 0.0; + if (!given(pb0)) pb0 = 0.0; + if (!given(pb1)) pb1 = 0.0; + if (!given(palpha0)) palpha0 = 0.0; + if (!given(palpha1)) palpha1 = 0.0; + if (!given(pbeta0)) pbeta0 = 0.0; + if (!given(pvfb)) pvfb = 0.0; + + if (!given(pelm)) pelm = 0.0; + if (!given(pcgsl)) pcgsl = 0.0; + if (!given(pcgdl)) pcgdl = 0.0; + if (!given(pckappa)) pckappa = 0.0; + if (!given(pcf)) pcf = 0.0; + if (!given(pclc)) pclc = 0.0; + if (!given(pcle)) pcle = 0.0; + if (!given(pvfbcv)) pvfbcv = 0.0; + if (!given(pacde)) pacde = 0.0; + if (!given(pmoin)) pmoin = 0.0; + if (!given(pnoff)) pnoff = 0.0; + if (!given(pvoffcv)) pvoffcv = 0.0; + + /* unit degree celcius */ + if (!given(tnom)) tnom = 27; + tnom += CONSTCtoK; + + if (!given(Lint)) Lint = 0.0; + if (!given(Ll)) Ll = 0.0; + if (!given(Llc)) Llc = Ll; + if (!given(Lln)) Lln = 1.0; + if (!given(Lw)) Lw = 0.0; + if (!given(Lwc)) Lwc = Lw; + if (!given(Lwn)) Lwn = 1.0; + if (!given(Lwl)) Lwl = 0.0; + if (!given(Lwlc)) Lwlc = Lwl; + if (!given(Lmin)) Lmin = 0.0; + if (!given(Lmax)) Lmax = 1.0; + if (!given(Wint)) Wint = 0.0; + if (!given(Wl)) Wl = 0.0; + if (!given(Wlc)) Wlc = Wl; + if (!given(Wln)) Wln = 1.0; + if (!given(Ww)) Ww = 0.0; + if (!given(Wwc)) Wwc = Ww; + if (!given(Wwn)) Wwn = 1.0; + if (!given(Wwl)) Wwl = 0.0; + if (!given(Wwlc)) Wwlc = Wwl; + if (!given(Wmin)) Wmin = 0.0; + if (!given(Wmax)) Wmax = 1.0; + if (!given(dwc)) dwc = Wint; + if (!given(dlc)) dlc = Lint; + if (!given(cf)) cf = 2.0 * EPSOX / Math.PI * Math.log(1.0 + 0.4e-6 / tox); + if (!given(cgdo)) { + if (given(dlc) && (dlc > 0.0)) + cgdo = dlc * cox - cgdl; + else + cgdo = 0.6 * xj * cox; + } + if (!given(cgso)) { + if (given(dlc) && (dlc > 0.0)) + cgso = dlc * cox - cgsl; + else + cgso = 0.6 * xj * cox; + } + + if (!given(cgbo)) cgbo = 2.0 * dwc * cox; + if (!given(xpart)) xpart = 0.0; + if (!given(sheetResistance)) sheetResistance = 0.0; + if (!given(unitAreaJctCap)) unitAreaJctCap = 5.0E-4; + if (!given(unitLengthSidewallJctCap)) unitLengthSidewallJctCap = 5.0E-10; + if (!given(unitLengthGateSidewallJctCap)) unitLengthGateSidewallJctCap = unitLengthSidewallJctCap; + if (!given(jctSatCurDensity)) jctSatCurDensity = 1.0E-4; + if (!given(jctSidewallSatCurDensity)) jctSidewallSatCurDensity = 0.0; + if (!given(bulkJctPotential)) bulkJctPotential = 1.0; + if (!given(sidewallJctPotential)) sidewallJctPotential = 1.0; + if (!given(GatesidewallJctPotential)) GatesidewallJctPotential = sidewallJctPotential; + if (!given(bulkJctBotGradingCoeff)) bulkJctBotGradingCoeff = 0.5; + if (!given(bulkJctSideGradingCoeff)) bulkJctSideGradingCoeff = 0.33; + if (!given(bulkJctGateSideGradingCoeff)) bulkJctGateSideGradingCoeff = bulkJctSideGradingCoeff; + if (!given(jctEmissionCoeff)) jctEmissionCoeff = 1.0; + if (!given(jctTempExponent)) jctTempExponent = 3.0; + if (!given(oxideTrapDensityA)) { + if (type == NMOS) + oxideTrapDensityA = 1e20; + else + oxideTrapDensityA=9.9e18; + } + if (!given(oxideTrapDensityB)) { + if (type == NMOS) + oxideTrapDensityB = 5e4; + else + oxideTrapDensityB = 2.4e3; + } + if (!given(oxideTrapDensityC)) { + if (type == NMOS) + oxideTrapDensityC = -1.4e-12; + else + oxideTrapDensityC = 1.4e-12; + } + + if (!given(em)) em = 4.1e7; /* V/m */ + if (!given(ef)) ef = 1.0; + if (!given(af)) af = 1.0; + if (!given(kf)) kf = 0.0; + +// These lines were added by me (tedv) because I think +// the original bsim3 code had a bug where it didn't check them. + if (!given(lk2)) lk2 = 0.0; + if (!given(wk2)) wk2 = 0.0; + if (!given(pk2)) pk2 = 0.0; + } + + public void computeTemperatureData() { + double Temp,Tnom,TRatio,Vtm0,Eg0,ni,Eg,T0,T1,delTemp; + + if (bulkJctPotential < 0.1) + { + bulkJctPotential = 0.1; + System.out.println("Given pb is less than 0.1. Pb is set to 0.1."); + } + if (sidewallJctPotential < 0.1) + { + sidewallJctPotential = 0.1; + System.out.println("Given pbsw is less than 0.1. Pbsw is set to 0.1."); + } + if (GatesidewallJctPotential < 0.1) + { + GatesidewallJctPotential = 0.1; + System.out.println("Given pbswg is less than 0.1. Pbswg is set to 0.1."); + } + + Temp = temp; + Tnom = tnom; + TRatio = Temp / Tnom; + + vcrit = CONSTvt0 * Math.log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); + factor1 = Math.sqrt(EPSSI / EPSOX * tox); + + Vtm0 = KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + ni = 1.45e10 * (Tnom / 300.15) * Math.sqrt(Tnom / 300.15) + * Math.exp(21.5565981 - Eg0 / (2.0 * Vtm0)); + + vtm = KboQ * Temp; + Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); + if (Temp != Tnom) + { + T0 = Eg0 / Vtm0 - Eg / vtm + jctTempExponent * Math.log(Temp / Tnom); + T1 = Math.exp(T0 / jctEmissionCoeff); + jctTempSatCurDensity = jctSatCurDensity * T1; + jctSidewallTempSatCurDensity = jctSidewallSatCurDensity * T1; + } + else + { + jctTempSatCurDensity = jctSatCurDensity; + jctSidewallTempSatCurDensity = jctSidewallSatCurDensity; + } + + if (jctTempSatCurDensity < 0.0) + jctTempSatCurDensity = 0.0; + if (jctSidewallTempSatCurDensity < 0.0) + jctSidewallTempSatCurDensity = 0.0; + + /* Temperature dependence of D/B and S/B diode capacitance begins */ + delTemp = Temp - tnom; + T0 = tcj * delTemp; + if (T0 >= -1.0) + unitAreaJctCap *= 1.0 + T0; + else if (unitAreaJctCap > 0.0) + { + unitAreaJctCap = 0.0; + System.out.println("Temperature effect has caused cj to be negative. Cj is clamped to zero."); + } + T0 = tcjsw * delTemp; + if (T0 >= -1.0) + unitLengthSidewallJctCap *= 1.0 + T0; + else if (unitLengthSidewallJctCap > 0.0) + { + unitLengthSidewallJctCap = 0.0; + System.out.println("Temperature effect has caused cjsw to be negative. Cjsw is clamped to zero."); + } + T0 = tcjswg * delTemp; + if (T0 >= -1.0) + unitLengthGateSidewallJctCap *= 1.0 + T0; + else if (unitLengthGateSidewallJctCap > 0.0) + { + unitLengthGateSidewallJctCap = 0.0; + System.out.println("Temperature effect has caused cjswg to be negative. Cjswg is clamped to zero."); + } + + PhiB = bulkJctPotential - tpb * delTemp; + if (PhiB < 0.01) + { + PhiB = 0.01; + System.out.println("Temperature effect has caused pb to be less than 0.01. Pb is clamped to 0.01."); + } + PhiBSW = sidewallJctPotential- tpbsw * delTemp; + if (PhiBSW <= 0.01) + { + PhiBSW = 0.01; + System.out.println("Temperature effect has caused pbsw to be less than 0.01. Pbsw is clamped to 0.01."); + } + PhiBSWG = GatesidewallJctPotential - tpbswg * delTemp; + if (PhiBSWG <= 0.01) + { + PhiBSWG = 0.01; + System.out.println("Temperature effect has caused pbswg to be less than 0.01. Pbswg is clamped to 0.01."); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Capacitor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Capacitor.java new file mode 100644 index 0000000000..5ef94e544f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Capacitor.java @@ -0,0 +1,132 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.file.common.HierName; +/** + * Class to represent resistors in .aspice files. + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public final class Capacitor extends AbstractDevice { + /** Capacitance of capacitor in */ + private double capacitance; + + /** Device currents **/ + + /** Drain node **/ + private double drainI; + /** Source node **/ + private double sourceI; + + /** + * Class constructor. + * @param name HierName of device + * @param source node + * @param drain node + * @param capacitance of capacitor + **/ + public Capacitor(final HierName name, + final Node source, + final Node drain, + final double capacitance) + { + super(new Node[] { source, drain }); + this.capacitance = capacitance; + this.name = name; + } + + public Capacitor(final Node source, + final Node drain, + final double capacitance) { + this(null, source, drain, capacitance); + } + /** + * Get source node. + * @return source node + **/ + public Node getSource() { + return nodes[0]; + } + + /** + * Get drain node. + * @return drain node + **/ + public Node getDrain() { + return nodes[1]; + } + + /** + * Get capacitance of capacitor. + * @return capacitance of capacitor + **/ + public double getCapacitance() { + return capacitance; + } + + /** + * Set capacitance of capacitor. + **/ + public void setCapacitance(double capacitance) { + this.capacitance = capacitance; + } + + /** returns the device current **/ + public double getCurrent(int type) { + switch (type) { + case AbstractDevice.I1: return drainI; + case AbstractDevice.I2: return sourceI; + } + return -1; + } + + + public String getCode() { return "C";} + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device and then informs its nodes of these values. + * @param chargeScale scalar for charge calculation + * @param currentScale scalar for current calculation + * @param derivChargeScale scalar for charge derivative calculation + * @param derivCurrentScale scalar for current derivative calculation + **/ + public void evalVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) + { + Node source = getSource(); + Node drain = getDrain(); + + double charge = (drain.getVoltage() - source.getVoltage()) + * capacitance; + + drainI = capacitance * (drain.getVoltageChange() - source.getVoltage()); + sourceI = -drainI; + + source.setResult(chargeScale, charge, currentScale, 0); + drain.setResult(chargeScale, -charge, currentScale, 0); + + source.setMatrix(source, + derivChargeScale, capacitance, derivCurrentScale, 0); + source.setMatrix(drain, + derivChargeScale, -capacitance, derivCurrentScale, 0); + drain.setMatrix(source, + derivChargeScale, -capacitance, derivCurrentScale, 0); + drain.setMatrix(drain, + derivChargeScale, capacitance, derivCurrentScale, 0); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Circuit.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Circuit.java new file mode 100644 index 0000000000..bd3eb1523c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Circuit.java @@ -0,0 +1,221 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.TreeMap; + +/** + * This class simulates a circuit + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public class Circuit { + /** List of AbstractDevice objects in the circuit. **/ + private ArrayList devices = new ArrayList(); + + /** List of Node objects in the circuit. **/ + private TreeMap nodes = new TreeMap(); + + /** Weighting constant for charge data. **/ + private double chargeScale; + + /** Weighting constant for current data. **/ + private double currentScale; + + /** Weighting constant for charge derivative data. **/ + private double derivChargeScale; + + /** Weighting constant for current derivative data. **/ + private double derivCurrentScale; + + /** Threshold for relaxation voltage change. **/ + private static final double relaxationThreshold = 1e-6; + + /** Amount of time lapsed in one timestep. **/ + private double timestep; + + /** Current simulation time. **/ + private double time; + + /** + * Construct default circuit + **/ + public Circuit() { + this(1e-12); + } +//GGG Create constructor based on cell object. + + /** + * Construct blank circuit. + * @param timestep for simulation increments + **/ + public Circuit(double timestep) { + this.timestep = timestep; + this.time = 0; + + this.chargeScale = 0; + this.currentScale = timestep; + this.derivChargeScale = 1; + this.derivCurrentScale = -timestep/2; + } + + /** + * Add device to circuit. + * @param device to add + **/ + public void addDevice(AbstractDevice device) { + devices.add(device); + + Node[] deviceNodes = device.getNodes(); + for (int i = 0; i < deviceNodes.length; i++) + addNode(deviceNodes[i]); + } + + /** + * Add node to circuit. + * Note that addDevice uses this function to implicitly add that + * device's nodes. + * @param node to add + **/ + public void addNode(Node node) { + Integer nodeId = node.getId(); + if (!nodes.containsKey(nodeId)) + nodes.put(nodeId, node); + } + + /** + * Initialize circuit for simulation + **/ + public void initializeSimulation() { + time = 0; + + for (final Iterator i = nodes.values().iterator(); i.hasNext(); ) { + Node node = (Node) i.next(); + node.setVoltage(0); + } + } + + /** + * Default simulation of circuit. + **/ + public void simulate() { + initializeSimulation(); + jump(50e-9); + } + + /** + * Take multiple simulation steps + * @param timeChange number of seconds to step forward + **/ + public void jump(double timeChange) { + double stopTime = time + timeChange; + + while (time < stopTime) + step(); + } + + /** + * Take multiple simulation steps + * @param steps number of steps to take + **/ + public void jump(int steps) { + // JVM hangs here because 0 < steps => false for for all step values! + //while (0 < steps--) + while (steps-- > 0) + step(); + } + + /** + * Take one simulation timestep. + **/ + public void step() { + // Clear out data values + for (final Iterator i = nodes.values().iterator(); i.hasNext(); ) + ((Node) i.next()).initialize(); + + analogStep(); +//GGG Add in digital Step sometime. Add it before or after analog? + + time += timestep; + } + + /** + * Take one simulation step for analog devices. + **/ + private void analogStep() { + // Evaluate voltages, charges and currents on all devices + for (final Iterator i = devices.iterator(); i.hasNext(); ) { + AbstractDevice device = (AbstractDevice) i.next(); + device.evalVoltage(chargeScale, currentScale, + derivChargeScale, derivCurrentScale,time); + } + + for (final Iterator i = nodes.values().iterator(); i.hasNext(); ) + ((Node) i.next()).normalize(); + +//GGG Is it really good to directly access neighborMap or not? + // Use relaxation to solve for new voltage changes + double maxDelta; + do { + // Greatest change in X, where X is estimated change in voltage + maxDelta = 0; + + // Relax each individual node + // In theory, we want A*X = B + // We can write this as Bi - Sum(all j but i){Aij*Xj} - Aii*Xi = 0 + // So Xi = (Bi - Sum(all j but i){Aij*Xj})/Aii + for (final Iterator i = nodes.values().iterator(); i.hasNext(); ) { + Node node = (Node) i.next(); + Integer id = node.getId(); + TreeMap neighborMap = node.getNeighborMap(); + + // Iterate over all neighboring nodes + double change = node.getResult(); + for (final Iterator j = neighborMap.keySet().iterator(); + j.hasNext(); ) + { + Integer nodeId = (Integer) j.next(); + if (nodeId.intValue() == id.intValue()) + continue; + + double[] matrixValue = (double[]) neighborMap.get(nodeId); + Node neighbor = (Node) nodes.get(nodeId); + + change -= matrixValue[0] * neighbor.getVoltageChange(); + } + + double changeDelta = Math.abs(change - node.getVoltageChange()); + node.setVoltageChange(change); + + if (changeDelta > maxDelta) + maxDelta = changeDelta; + } + } while (maxDelta > relaxationThreshold); + + // Save node change values + for (final Iterator i = nodes.values().iterator(); i.hasNext(); ) + ((Node) i.next()).changeVoltage(); + } + + /** + * Get current simulation time + * @return simulation time in seconds + **/ + public double getTime() { + return time; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/CurrentSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/CurrentSource.java new file mode 100644 index 0000000000..3e58aeb4ce --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/CurrentSource.java @@ -0,0 +1,118 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import java.util.HashMap; +import java.util.Iterator; + +import com.avlsi.file.common.HierName; + +import com.avlsi.util.recalc.ExpressionInterface; +import com.avlsi.util.recalc.IndependantVariable; + +/** + * Class to represent current sources + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public final class CurrentSource extends AbstractDevice { + /** Node that receives the current. **/ + private Node source; + + /** Expression to evaluate current for source. **/ + private ExpressionInterface currentFormula; + + /** + * Map whose values are independant variables used by currentFormula + * and keys are nodes that influence those variables. + **/ + private HashMap voltageMap; + + /** + * Class constructor. + * @param source node to output current + * @param currentFormula Recalc expression describing current output + * @param voltageMap Maps independant variables in currentFormula with + * nodes. See class variable voltageMap for more information + **/ + public CurrentSource(HierName name, Node source, + ExpressionInterface currentFormula, + HashMap voltageMap) + { + super(new Node[] { source }); + this.currentFormula = currentFormula; + this.voltageMap = voltageMap; + this.name = name; + } + + public CurrentSource(Node source, + ExpressionInterface currentFormula, + HashMap voltageMap) { + this(null, source, currentFormula, voltageMap); + } + + /** + * Get source node. + * @return source node + **/ + public Node getSource() { + return nodes[0]; + } + + public String getCode() { return "I";} + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device and then informs its nodes of these values. + * @param chargeScale scalar for charge calculation + * @param currentScale scalar for current calculation + * @param derivChargeScale scalar for charge derivative calculation + * @param derivCurrentScale scalar for current derivative calculation + **/ + public void evalVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) + { + Node source = getSource(); + + // Initialize formula variables with voltages from influencing nodes + for (final Iterator i = voltageMap.keySet().iterator(); i.hasNext(); ) { + Node node = (Node) i.next(); + IndependantVariable var = + (IndependantVariable) voltageMap.get(node); + var.set(node.getVoltage()); + } + + double current = currentFormula.eval(); + source.setResult(chargeScale, 0, currentScale, current); + + // Compute partial derivatives + final double delta = 1e-9; + for (final Iterator i = voltageMap.keySet().iterator(); i.hasNext(); ) { + Node node = (Node) i.next(); + IndependantVariable var = + (IndependantVariable) voltageMap.get(node); + + final double oldVoltage = var.get(); + var.set(oldVoltage + delta); + double dIdV = (currentFormula.eval() - current) / delta; + + source.setMatrix(node, derivChargeScale, 0, + derivCurrentScale, dIdV); + + var.set(oldVoltage); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DefaultCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DefaultCallback.java new file mode 100644 index 0000000000..807d1fb9b7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DefaultCallback.java @@ -0,0 +1,286 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.Collection; +/*************************************************************** + * Default callback that writes to a tracefile with name tracename.trace + ***************************************************************/ +public class DefaultCallback implements JaspiceCallbackInterface { + private TraceFile tracer; + private double timemax, poststep,timestep; + private String tracename; + private boolean traceon; + + /** Used to keep track of the poststep **/ + private double elapsed_time = 0; + + /** List of nodes to trace **/ + private TraceList tracelist = null; + + /** Parses a string into the correct int (for tracing) **/ + public static int getType(String str) { + int type = -1; + if (str.equals("V")) + type = Node.VOLTAGE; + else if (str.equals("I1")) + type = AbstractDevice.I1; + else if (str.equals("I2")) + type = AbstractDevice.I2; + else if (str.equals("I3")) + type = AbstractDevice.I3; + else if (str.equals("I4")) + type = AbstractDevice.I4; + return type; + } + + /** Constructor, nothing is actually done until the init method **/ + public DefaultCallback() { + timemax = 0; + poststep = 0; + timestep = 0; + tracename = "a"; + boolean traceon = true; + tracelist = null; + } + + /** JaspiceCallbackInterface method. Builds the tracefile, and adds all node and + * device names to the tracefile .names **/ + public void init() throws JaspiceException{ + Jaspice ja = Jaspice.get(); + try { + traceon = ja.getBooleanProperty("trace"); + } catch (Jaspice.PropertyException e) { + System.out.println("Trace toggle not found."); + } + if (!traceon) { + tracer = null; + return; //trace disabled + } + try { + timemax = ja.getDoubleProperty("timemax"); + poststep = ja.getDoubleProperty("poststep"); + timestep = ja.getDoubleProperty("timestep"); + tracename = ja.getStringProperty("tracename"); + } catch (Jaspice.PropertyException e) { + throw new JaspiceException("In Callback: "+e.getMessage(), e); + } + try { + tracer = new TraceFile(tracename); + tracer.startNewTrace(); + for (Iterator list = getTraceList().iterator(); + list.hasNext();) { + TraceElement te = (TraceElement) list.next(); + //If a node then get all aliases as well + if (te.getObject() instanceof Node) + tracer.addNodeNames( + ja.getAliases((Node) te.getObject())); + else + tracer.addNodeName(te.getName()); + } + + tracer.closeOutNodes(); + } catch( TraceFile.TraceFileException te) { + throw new JaspiceException("TraceFileException: "+ + te.getMessage()); + } + } + + /** Returns an iterator of strings that contains the print strings + * of the elements in the trace list **/ + public Iterator printElements() { + return printElements(-1); + } + + /** Returns an iterator of strings that contains the print strings of the + * elements of the trace list whose trace type is equal to type + * **/ + public Iterator printElements(int type) { + ArrayList strings = new ArrayList(); + if (tracelist == null) { + strings.add("Trace List uninitialized, all nodes will be added to"+ + " trace at runtime."); + } else { + for (Iterator i = tracelist.iterator();i.hasNext();) { + TraceElement te = (TraceElement) i.next(); + if ((type == -1) || (te.getType() == type)) + strings.add(te.printElement()); + } + } + return strings.iterator(); + } + + /** Gets the current trace list **/ + private Collection getTraceList() { + checkTrace(); + return tracelist; + } + + /** Installs the default behavior before any trace functions can be used **/ + private void checkTrace() { + if (tracelist == null) { + tracelist = new TraceList(); + //default behavior + addAllNodesToTrace(); + } + } + + /** Removes all nodes in this circuit from the trace list **/ + public void removeAllNodesFromTrace() { + if (tracelist == null) tracelist = new TraceList(); + else tracelist.removeAll(Node.VOLTAGE,Node.VOLTAGE); + } + + /** Removes all devices in this circuit from the trace list **/ + public void removeAllDevicesFromTrace() { + if (tracelist == null) tracelist = new TraceList(); + else tracelist.removeAll(AbstractDevice.I1, + AbstractDevice.I4); + } + + /** Clears entire trace list **/ + public void clearTraceList() { + if (tracelist == null) tracelist = new TraceList(); + else tracelist.clear(); + } + + /** Adds all of the nodes in this circuit to the node list **/ + public void addAllNodesToTrace() { + if (tracelist == null) tracelist = new TraceList(); + else tracelist.clear(); + System.out.println("adding all nodes to trace"); + Jaspice ja = Jaspice.get(); + Collection c = ja.getNodes(); + if (c != null) + tracelist.addAll(c, Node.VOLTAGE); + } + + /** Trace a single node or object (depending on the type).**/ + public void trace(Object tracer, int type) { + if (tracelist == null) tracelist = new TraceList(); + //Does not check for repeated nodes + tracelist.add(new TraceElement(type,tracer)); + } + + /** Untrace a single trace type from node or device untracer. **/ + public void untrace(Object untracer,int type) { + if (tracelist== null) tracelist = new TraceList(); + else tracelist.remove(untracer,type); + } + + /** Removes all elements that trace the node or device untracer **/ + public void untrace(Object untracer) { + if (tracelist== null) tracelist = new TraceList(); + else tracelist.removeAll(untracer); + } + + /** Get all of the nodes being traced in the order they were printed + * to the .names file **/ + private float[] traceNodes() { + Collection c = getTraceList(); + float[] data = new float[c.size()];//all traced nodes, not inc time + int index = 0; + for(Iterator i = c.iterator();i.hasNext();) { + TraceElement te = (TraceElement) i.next(); + //Node node = + // (Node) i.next(); + data[index++] = (float) te.getData();//node.getVoltage(); + } + return data; + } + + /** JaspiceCallbackInterface method. Outputs all node voltages and device + * currents chosen in the init step in float form to the tracefile **/ + public void update() throws JaspiceException{ + if ((tracer==null) || (!traceon)) return; + Jaspice ja = Jaspice.get(); + //JaspiceCircuit circuit = ja.getCircuit(); + /** Loop to check if poststep has elapased, under the assumption + * that poststep is larger than timestep**/ + if (elapsed_time <= timestep*1e-6 /*zero*/) { + try { + tracer.writeFloat((float)ja.getTime()); + tracer.writeRecord( traceNodes()); + } catch (TraceFile.TraceFileException e) { + throw new JaspiceException("TraceFileException: "+ + e.getMessage()); + } + elapsed_time = poststep; + } + elapsed_time -= timestep; + } + + /** JaspiceCallbackInterface method, closes the tracefile **/ + public void finish() throws JaspiceException { + try { + if (tracer != null) tracer.close(); + } catch (TraceFile.TraceFileException e) { + throw new JaspiceException("TraceFileException: "+ + e.getMessage()); + } + } + + /** Swanky arraylist that handles trace elements **/ + private class TraceList extends ArrayList { + + public void addAll(Collection src, int type) { + for (Iterator i = src.iterator();i.hasNext();) { + TraceElement te = new TraceElement(type,i.next()); + add(te); + } + } + + /** Remove the element o that has the trace type type **/ + public boolean remove(Object o,int type) { + for( Iterator i = this.iterator();i.hasNext();) { + TraceElement te = (TraceElement) i.next(); + if (te.getObject().equals(o) && + (te.getType() == type)) { + tracelist.remove(te); + return true; + } + } + return false; + } + + /** Removes all elements whose object is the same as o.**/ + public boolean removeAll(Object o) { + boolean found = false; + for( Iterator i = this.iterator();i.hasNext();) { + TraceElement te = (TraceElement) i.next(); + if (te.getObject().equals(o)) { + tracelist.remove(te); + found = true; + } + } + return found; + } + /** Removes all elements whose types fall between a certain range **/ + public boolean removeAll(int type1, int type2) { + boolean found = false; + for( Iterator i = this.iterator();i.hasNext();) { + TraceElement te = (TraceElement) i.next(); + int type = te.getType(); + if ((type >= type1) && (type <= type2)) { + i.remove(); + found = true; + } + } + return found; + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DevTester.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DevTester.java new file mode 100644 index 0000000000..0c1762003f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DevTester.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.util.recalc.IndependantVariable; +import com.avlsi.util.recalc.MinusOp; +import com.avlsi.util.recalc.DivOp; +import com.avlsi.util.recalc.MultOp; +import com.avlsi.util.recalc.Literal; +import java.util.HashMap; + +/** + * Class for ... + * + * @author Dan Daly + * @version $Date$ + **/ + +public class DevTester { + /** + * Constructor. + **/ + DevTester() { + + } + + public static void main(String[] args) { + //TraceFile tracer = new TraceFile("devtest"); + //tracer.startNewTrace(); + BSim3Model.readFile("/usr/local/cad/lib/bsim3/tsmc18.bsim3",27); + Circuit circuit = new Circuit(1e-13d); + GroundNode gnd = new GroundNode(HierName.makeHierName("GND!")); + Node volt = new Node(HierName.makeHierName("volt")); + Diode d = new Diode(DeviceTypes.N_TYPE, + volt, + gnd, + 0.9e-06d, 0.18e-06d, //width, length + 0.432e-12d, 2.76e-06d //area source, area perim + ); + circuit.addDevice(d); + IndependantVariable x = new IndependantVariable(0); + HashMap voltageMap = new HashMap(); + voltageMap.put(volt, x); + circuit.addDevice( + new com.avlsi.tools.aspice.CurrentSource(volt, + x, voltageMap)); + double time = circuit.getTime(); + while ( time < 1e-9) { + circuit.jump(1e-12); + time = circuit.getTime(); + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DigitalDriver.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DigitalDriver.java new file mode 100644 index 0000000000..baa57bc74a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/DigitalDriver.java @@ -0,0 +1,86 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; +import java.util.ArrayList; +import com.avlsi.tools.dsim.NodeWatcher; +import com.avlsi.tools.dsim.DSim; +/** + * Class for Driving a node with the activity of a node + * + * @author Dan Daly + * @version $Date$ + **/ + +public class DigitalDriver implements Node.NodeDriver,NodeWatcher { + + private ArrayList inputs; + private double currV; + private double prstau; + /** + * Constructor. + **/ + public DigitalDriver(double prstau) { + inputs = new ArrayList(); + currV = 0; + this.prstau = prstau; + } + + public void nodeChanged(com.avlsi.tools.dsim.Node node, long time) { + double newtime = (time*5e-9d)/10000d; + char val = node.toString().charAt(node.toString().length()-1); + int num = 2; + switch (val) { + case '1': num = 1; + break; + case '0': num = 0; + break; + } + inputs.add(new Event(newtime,num)); + System.out.println("Got new event: "+newtime+" "+node+" len= "+inputs.size()); + } + + public double getDrivenVoltage(double time) { + if (inputs.isEmpty()) return currV; + double toptime = ((Event)inputs.get(0)).time; + if (toptime <= time) { + switch(((Event) inputs.remove(0)).num ) { + case 0: + currV = 0.0; + break; + case 1: + currV = 1.8; + break; + default: + System.out.println("Error in D to A"); + } + //System.out.println("Driving "+currV+" V at "+time); + } + return currV; + } + + public double getDrivenTau() { + return prstau; + } + + private class Event { + public double time; + public int num; + + public Event(double t, int num) { + this.time = t; + this.num = num; + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Diode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Diode.java new file mode 100644 index 0000000000..3f2ad9055d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Diode.java @@ -0,0 +1,414 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; + +/** + * Class to represent diodes in .aspice files. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Diode extends AbstractDevice { + /** type of diode, N_TYPE or P_TYPE. */ + private final int type; + + /** Width of diode in meters. **/ + private final double width; + + /** Length of diode in meters. **/ + private final double length; + + /** Area of diode in square meters. **/ + private final double area; + + /** Perimeter of diode in meters. **/ + private final double perimeter; + + /** BSIM3 Device model data. **/ + private final BSim3Model m; + + /** BSim3 convergence correction hack-- 0 turns it off. **/ + private final double gmin = 0; + + /** Device currents **/ + + /** Drain node **/ + private double drainI; + /** Source node **/ + private double sourceI; + + public native void nativeEval(int modelHandle, int type, + double Vsource, double Vdrain, + double area, double perimeter, + double width, double gmin, + double[] charge, + double[] current, + double[] charge_partials, + double[] current_partials); + + /** + * Class constructor. + * @param name Name of the device + * @param source name of source node + * @param drain name of drain node + * @param width of diode in meters + * @param length of diode in meters + * @param area of diode in square meters + * @param perimeter of diode in meters + * @throws IllegalArgumentException + **/ + public Diode(final HierName name, + final int type, + final Node source, + final Node drain, + final double width, + final double length, + final double area, + final double perimeter) { + super(new Node[] { source, drain }); + + if (type != DeviceTypes.N_TYPE && type != DeviceTypes.P_TYPE) + throw new IllegalArgumentException("Bad diode type: " + type); + + this.type = type; + + this.width = width; + this.length = length; + this.area = area; + this.perimeter = perimeter; + this.name = name; + + // + //Loads native or java model depending on native parameter + // + m = BSim3Model.findModel(type, width, length); + } + + /** @throws IllegalArgumentException **/ + public Diode(final int type, + final Node source, + final Node drain, + final double width, + final double length, + final double area, + final double perimeter) { + this(null, type, source,drain, width,length, area,perimeter); + } + + /** + * Get the type of the diode, either N_TYPE, or P_TYPE. + * @return the type of the diode + **/ + public int getType() { + return type; + } + + /** + * Get source node. + * @return source node + **/ + public Node getSource() { + return nodes[0]; + } + + /** + * Get drain node. + * @return drain node + **/ + public Node getDrain() { + return nodes[1]; + } + + /** + * Get width of diode + * @return width of diode in meters + **/ + public double getWidth() { + return width; + } + + /** + * Get length of diode + * @return length of diode in meters + **/ + public double getLength() { + return length; + } + + /** + * Get area of diode + * @return area of diode in square meters + **/ + public double getArea() { + return area; + } + + /** + * Get perimeter + * @return get diode perimeter in meters + **/ + public double getPerimeter() { + return perimeter; + } + + /** returns the device current **/ + public double getCurrent(int type) { + switch (type) { + case AbstractDevice.I1: return drainI; + case AbstractDevice.I2: return sourceI; + } + return -1; + } + + public String getCode() { return "D";} + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device and then informs its nodes of these values. + * @param chargeScale scalar for charge calculation + * @param currentScale scalar for current calculation + * @param derivChargeScale scalar for charge derivative calculation + * @param derivCurrentScale scalar for current derivative calculation + **/ + public void evalVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) { + if (BSim3Model.isNativeLoaded()) { + evalNativeVoltage(chargeScale,currentScale,derivChargeScale, + derivCurrentScale,time); + } + if (!BSim3Model.isNativeLoaded() || BSim3Model.both) { + evalJavaVoltage(chargeScale,currentScale,derivChargeScale, + derivCurrentScale,time); + } + } + + // + //doubles[] pooled so these don't have to be created every evaluation + // + double[] Q = new double[2]; + double[] I = new double[2]; + double[] dQ= new double[4]; + double[] dI= new double[4]; + public void evalNativeVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) { + + + Node source = getSource(); + Node drain = getDrain(); + + nativeEval(m.getHandle(), m.type, + source.getVoltage(), drain.getVoltage(), + area, perimeter, width, 0, Q,I,dQ,dI); + + if (BSim3Model.both) return; //just observe + drainI = I[1];//-m.type*cbs; + sourceI = I[0];//m.type*cbs; + + source.setResult(chargeScale, Q[0],//-m.type*qbs, + currentScale, sourceI /*m.type*cbs*/); + drain.setResult (chargeScale, Q[1],//m.type*qbs, + currentScale, drainI /*-m.type*cbs*/); + source.setMatrix(source, + derivChargeScale, dQ[0], //capbs, + derivCurrentScale, dI[0]);//-gbs); + source.setMatrix(drain, + derivChargeScale, dQ[2], //-capbs, + derivCurrentScale, dI[2]);//gbs); + drain.setMatrix(source, + derivChargeScale, dQ[1],//-capbs, + derivCurrentScale, dI[1]);//gbs); + drain.setMatrix(drain, + derivChargeScale, dQ[3],//capbs, + derivCurrentScale, dI[3]);//-gbs); + } + + public void evalJavaVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) + { + Node source = getSource(); + Node drain = getDrain(); + + double Vs = source.getVoltage(); + double Vb = drain.getVoltage(); + + double vbs,gbs,cbs,qbs,capbs; + double Nvtm, Inv_Nvtm; + double SatCurrent,evbs,vjsm,IsEvjsm,czbs,czbssw,czbsswg; + double MJ,MJSW,MJSWG; + double T0,T1,arg,sarg; + + /* precompute some diode expressions */ + vbs = m.type * (Vb - Vs); + Nvtm = m.vtm * m.jctEmissionCoeff; + Inv_Nvtm = 1.0 / Nvtm; + MJ = m.bulkJctBotGradingCoeff; + MJSW = m.bulkJctSideGradingCoeff; + MJSWG = m.bulkJctGateSideGradingCoeff; + + /* I and G */ + if ((area <= 0.0) && (perimeter <= 0.0)) + SatCurrent = 1.0e-14; + else + SatCurrent = area * m.jctTempSatCurDensity + + perimeter * m.jctSidewallTempSatCurDensity; + if (SatCurrent <= 0.0) + { + gbs = gmin; + cbs = gbs * vbs; + } + else + { + if (m.ijth == 0.0) + { + evbs = Math.exp(vbs * Inv_Nvtm); + gbs = SatCurrent * evbs * Inv_Nvtm + gmin; + cbs = SatCurrent * (evbs - 1.0) + gmin * vbs; + } + else + { + vjsm = Nvtm * Math.log(m.ijth / SatCurrent + 1.0); + IsEvjsm = SatCurrent * Math.exp(vjsm * Inv_Nvtm); + if (vbs < vjsm) + { + evbs = Math.exp(vbs * Inv_Nvtm); + gbs = SatCurrent * evbs * Inv_Nvtm + gmin; + cbs = SatCurrent * (evbs - 1.0) + gmin * vbs; + } + else + { + T0 = IsEvjsm * Inv_Nvtm; + gbs = T0 + gmin; + cbs = IsEvjsm - SatCurrent + T0 * (vbs - vjsm) + gmin * vbs; + } + } + } + + /* Q and C */ + czbs = m.unitAreaJctCap * area; + if (perimeter < width) + { + czbssw = 0; + czbsswg = m.unitLengthGateSidewallJctCap * perimeter; + } + else + { + czbssw = m.unitLengthSidewallJctCap * (perimeter - width); + czbsswg = m.unitLengthGateSidewallJctCap * width; + } + + if (vbs == 0.0) + { + qbs = 0.0; + capbs = czbs + czbssw + czbsswg; + } + else if (vbs < 0.0) + { + if (czbs > 0.0) + { + arg = 1.0 - vbs / m.PhiB; + if (MJ == 0.5) + sarg = 1.0 / Math.sqrt(arg); + else + sarg = Math.exp(-MJ * Math.log(arg)); + qbs = m.PhiB * czbs * (1.0 - arg * sarg) / (1.0 - MJ); + capbs = czbs * sarg; + } + else + { + qbs = 0.0; + capbs = 0.0; + } + if (czbssw > 0.0) + { + arg = 1.0 - vbs / m.PhiBSW; + if (MJSW == 0.5) + sarg = 1.0 / Math.sqrt(arg); + else + sarg = Math.exp(-MJSW * Math.log(arg)); + qbs += m.PhiBSW * czbssw * (1.0 - arg * sarg) / (1.0 - MJSW); + capbs += czbssw * sarg; + } + if (czbsswg > 0.0) + { + arg = 1.0 - vbs / m.PhiBSWG; + if (MJSWG == 0.5) + sarg = 1.0 / Math.sqrt(arg); + else + sarg = Math.exp(-MJSWG * Math.log(arg)); + qbs += m.PhiBSWG * czbsswg * (1.0 - arg * sarg) / (1.0 - MJSWG); + capbs += czbsswg * sarg; + } + } + else + { + T0 = czbs + czbssw + czbsswg; + T1 = vbs * (czbs * MJ / m.PhiB + czbssw * MJSW + / m.PhiBSW + czbsswg * MJSWG / m.PhiBSWG); + qbs = vbs * (T0 + 0.5 * T1); + capbs = T0 + T1; + } + + sourceI = m.type*cbs; + drainI = -m.type*cbs; + + source.setResult(chargeScale, -m.type*qbs, + currentScale, sourceI/*m.type*cbs*/); + drain.setResult (chargeScale, m.type*qbs, + currentScale, drainI /*-m.type*cbs*/); + + source.setMatrix(source, + derivChargeScale, capbs, derivCurrentScale, -gbs); + source.setMatrix(drain, + derivChargeScale, -capbs, derivCurrentScale, gbs); + drain.setMatrix(source, + derivChargeScale, -capbs, derivCurrentScale, gbs); + drain.setMatrix(drain, + derivChargeScale, capbs, derivCurrentScale, -gbs); + if (BSim3Model.both && BSim3Model.isNativeLoaded()) { + /* + System.out.println("JQ= "+(-m.type*qbs)+","+(m.type*qbs)+ + " NQ= "+Q[0]+","+Q[1]); + System.out.println("JI= "+(sourceI)+","+(drainI)+ + " NI= "+I[0]+","+I[1]); + System.out.println("J0= "+(capbs)+","+(-gbs)+ + " N0= "+dQ[0]+","+dI[0]); + System.out.println("J2= "+(-capbs)+","+(gbs)+ + " N2= "+dQ[2]+","+dI[2]); + System.out.println("J1= "+(-capbs)+","+(gbs)+ + " N1= "+dQ[1]+","+dI[1]); + System.out.println("J3= "+(capbs)+","+(-gbs)+ + " N3= "+dQ[3]+","+dI[3]); + */ + System.out.println(time+"\t"+(-m.type*qbs)+"\t"+(m.type*qbs)+"\t"+ + sourceI+"\t"+drainI+"\t"+ + capbs+"\t"+gbs+"\t"+ + //Q[0] = 8th + Q[0]+"\t"+Q[1]+"\t"+I[0]+"\t"+I[1]+"\t"+ + dQ[0]+"\t"+dI[0]+"\t"+ + dQ[1]+"\t"+dI[1]+"\t"+ + dQ[2]+"\t"+dI[2]+"\t"+ + dQ[3]+"\t"+dI[3]+"\t"+ + getName()); + } + + } +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/ExpVoltageSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/ExpVoltageSource.java new file mode 100644 index 0000000000..07e6bf2a75 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/ExpVoltageSource.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; +import com.avlsi.file.common.HierName; +/** + * Class for Sinusoidal Voltage Source + * + * @author Dan Daly + * @version $Date$ + **/ + +public class ExpVoltageSource extends VoltageSource{ + +// +//Voltage Imp variables +// + /** Initial value of voltage or current in volts or amps. **/ + private double v1; + + /** Pulsed value of voltage or current in volts or amps. **/ + private double v2; + + /** Rise delay time in seconds. **/ + private double td1; + /** Fall delay time in seconds. **/ + private double td2; + /** Rise time constant in seconds. **/ + private double tau1; + /** Fall time constant in seconds. **/ + private double tau2; + + + /** Builds a exponential voltage source device + * + * @param name HierName of the device + * @param nplus positive terminal node + * @param nminus negative terminal node + * @param v1 Initial value of voltage in volts. + * @param v2 Pulsed value of voltage in volts. + * @param td1 Rise delay time in seconds. + * @param tau1 Rise time constant in seconds. + * @param td2 Fall delay time in seconds. + * @param tau2 Fall time constant in seconds. + * **/ + public ExpVoltageSource(final HierName name, + final Node nplus, + final Node nminus, + final double v1, + final double v2, + final double td1, + final double tau1, + final double td2, + final double tau2) { + super(name, nplus, nminus); + this.v1 = v1; + this.v2 = v2; + this.td1 = td1; + this.td2 = td2; + this.tau1 = tau1; + this.tau2 = tau2; + } + + public double getDrivenVoltage(double time,double timestep) { + if (time <= td1) return v1; + if (time <= td2) return v1 + (v2-v1)*(1-Math.exp(-(time-td1)/tau1) ); + return v1 + (v2-v1) * (1-Math.exp(-(td2-td1)/tau1)) + * (Math.exp(-(time-td2)/tau2)); + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/GroundNode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/GroundNode.java new file mode 100644 index 0000000000..20f1b8d3f3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/GroundNode.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.file.common.HierName; +/** + * This class simulates the ground node + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public class GroundNode extends Node { +//GGG I feel bad implementing this class by "pasting over" 4 functions +// with nothing functions. But I don't think devices should know or +// care if they talk to a ground node... so the ground node needs to +// support some sort of null API for consistancy with other nodes. +// Is this the best way of writing things? Remember that we need a +// coherent node numbering scheme, so we can't use an interface. +// +// Actually, if we never need to lookup the ground node in a tree, +// we wouldn't need the node ID to also track ground, so that could +// enable us to use an interface... + /** Named GroundNode + ***/ + public GroundNode() { + super(); + } + + public GroundNode(HierName name) { + super(name); + //System.out.println("(Ground)"); + } + + /** + * Track neighbor nodes. + * The ground node does not care which nodes use it because its + * voltage is always zero. + * @param nodes list + **/ + protected void addNeighborNodes(Node[] nodes) { + } + + /** + * Set Voltage. + * Since this is the ground node, its voltage doesn't change + * @param voltage to set (for consistancy) + **/ + public void setVoltage(double voltage) { + } + + /** + * Compute and set result value. + * We don't need to do any voltage calculation for the ground node + * @param chargeScale scalar for charge + * @param charge on node + * @param currentScale scalar for current + * @param current on node + **/ + public void setResult(double chargeScale, double charge, + double currentScale, double current) + { + } + + /** + * Compute and set matrix entry. + * We don't need to do any voltage calculation for the ground node + * @param node if charge derivative is dI0/dV1, node is 0 (and "this" is 1) + * @param chargeScale scalar for charge + * @param charge derivative on node + * @param currentScale scalar for current + * @param current derivative on node + **/ + public void setMatrix(Node node, + double chargeScale, double charge, + double currentScale, double current) + { + } + + /** + * Ground nodes don't need normalization + **/ + public void normalize() { + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Jaspice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Jaspice.java new file mode 100644 index 0000000000..4b895d8a47 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Jaspice.java @@ -0,0 +1,584 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.file.spice.SpiceParser; +import com.avlsi.file.spice.SimulatorInterface; +import com.avlsi.file.spice.SpiceFileFormatException; +import java.util.Properties; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Collection; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.tools.dsim.DSim; +import com.avlsi.tools.dsim.DSimSynchronizer; +/** + * Class for Jaspice + * + * @author Dan Daly + * @version $Date$ + **/ + +public class Jaspice implements SimulatorInterface,DSimSynchronizer.Runnable{ + + private static Jaspice singleton = null; + + // + //States of the Simulator + // + + /** Required before starting **/ + private static boolean modelLoaded = false; + /** Once running cannot change static properties, use reset() to + * set back to false + **/ + private boolean running; + + /** Repository for all of the cell definitions **/ + private final JaspiceCircuit.Repository repo; + /** Parser **/ + private final SpiceParser parser; + /** Analog system's circuit **/ + private JaspiceCircuit circuit=null; + /** For Output **/ + private JaspiceCallbackInterface callback; + + /** Parameters loaded into the simulator through the spice or the cmdline **/ + private static HashMap params; + + /** Current Time (sec)**/ + private double time; + + /***************************************************************** + * Sets the default values to the global parameters + *****************************************************************/ + public static void setDefaults() { + params = new HashMap(); + try { + addProperty("timestep", new JaspiceProp(new Double("1e-12"), + "seconds (run)","time of each integration step")); + addProperty("poststep", new JaspiceProp(new Double("10e-12"), + "seconds (run)","time elapsed between each update (ie trace)")); + addProperty("trace",new JaspiceProp(new Boolean(true), + "toggle on/off (run)","turns trace on or off")); + addProperty("tracename", new JaspiceProp("javatrace", + "string (run)", + "base name of tracefile (suffix added by simulator)")); + addProperty("modelfile",new JaspiceProp( + "/usr/local/cad/lib/bsim3/tsmc18.bsim3", + "string (build)","BSIM3 model filename")); + addProperty("vdd",new JaspiceProp( + "Vdd!", + "string (build)","Positive terminal name of default"+ + " power supply")); + addProperty("gnd",new JaspiceProp( + "GND!", + "string (build)","Negative terminal name of default"+ + " power supply")); + addProperty("temperature", new JaspiceProp(new Double("27"), + "Celsius (build)","temparture of simulation")); + addProperty("native", new JaspiceProp(new Boolean(true), + "on/off (build)", "turns native models on or off")); + addProperty("high", new JaspiceProp(new Double("1.8"), + "Volts (build)","target Vdd voltage")); + addProperty("low", new JaspiceProp(new Double("0"), + "Volts (build)","target GND voltage")); + addProperty("timemax", new JaspiceProp(new Double("1e-9"), + "seconds (run)", + "runtime when run is called with no parameters")); + addProperty("dsimstep",new JaspiceProp(new Integer("0"), + "dsim cycles (run)", + "number of dsim cycles to take with each timestep")); + addProperty("prstau", new JaspiceProp(new Double("25e-12"), + "seconds (run)", + "paramter for digital to analog conversion")); + addProperty("maxerr", new JaspiceProp(new Double("1e-6"), + " (run)", + "relaxation parameter")); + addProperty("transconductance", new JaspiceProp(new Double("1"), + "mhos (build (build))", + "Voltage Source Parameter")); + } catch (PropertyException e) {} + } + + /** return the current simulation time **/ + public double getTime() { return time;} + + /** Load the model vars for the simulatio, uses properties modelfile + * and temperature + **/ + private void loadModel() + throws PropertyException { + String modelfile = getStringProperty("modelfile"); + double temp = getDoubleProperty("temperature"); + boolean useNative = getBooleanProperty("native"); + BSim3Model.readFile(modelfile,temp,useNative); + modelLoaded = true; + } + + /** Returns the Jaspice object **/ + public static Jaspice get() { + if ((singleton==null) || + (!modelLoaded)){ + singleton = new Jaspice(); + } + return singleton; + } + + /** + * Secret Constructor. + **/ + private Jaspice() { + circuit = new JaspiceCircuit(""); + params = new HashMap(); + setDefaults(); + parser = new SpiceParser('.', null, null, this); + repo = new JaspiceCircuit.Repository(); + callback = null; + running = false; + time = 0f; + Runtime.getRuntime().addShutdownHook( + new Thread( + new Runnable() { + public void run() { + cleanup(); + } + })); + } + + /** Sets the callback to call update on foreach timestep **/ + public void setCallback(JaspiceCallbackInterface callback) { + this.callback = callback; + } + + /** Returns the node with name name**/ + public Node findNode(String name) { + if (circuit != null) return circuit.findNode(name); + return null; + } + + /** returns the device in the circuit **/ + public AbstractDevice findDevice(String name) { + if (circuit != null) return circuit.findDevice(name); + return null; + } + + /** Gets all nodes in the circuit + * @return A collection of Nodes**/ + public Collection getNodes() { + if (getCircuit() == null) return null; + return getCircuit().getNodes(); + } + + /** Gets all devices in the circuit + * @return A collection of AbstractDevices **/ + public Collection getDevices() { + if (getCircuit() == null) return null; + return getCircuit().getDevices(); + } + + /** Build a circuit within the repository with the given parameters + * @param filename File that holds the celltype + * @param cellname Name of the cell to instantiate + * @param fullname Prefix appended to the nodenames, set to "" when + * not in use + ***/ + public void buildCircuit(final String filename, + final String cellname, + final String fullname) + throws JaspiceException { + double high=0,low=0,maxerr=0; + String vdd,gnd; + try { + high = getDoubleProperty("high"); + low = getDoubleProperty("low"); + maxerr = getDoubleProperty("maxerr"); + vdd = getStringProperty("vdd"); + gnd = getStringProperty("gnd"); + } catch (PropertyException e) { + throw new JaspiceException(e); + } + HierName hvdd=null,hgnd=null; + try { + hvdd = HierName.makeHierName(vdd,'.'); + hgnd = HierName.makeHierName(gnd,'.'); + } catch (InvalidHierNameException e) { + System.out.println(e.getMessage()); + } + JaspiceCircuit.groundName = hgnd; + /** Loads the model **/ + try { + loadModel(); + } catch (PropertyException e) { + System.out.println("Invalid Property, model not loaded: "+ + e.getMessage()); + } + /** Builds the specific instance **/ + try { + HierName hname = HierName.makeHierName(fullname); + } catch (IllegalArgumentException e) { + System.out.println("Error in hierarchical fullname: "+ + e.getMessage()); + } + /** Retrieve the cell definition **/ + JaspiceCircuit celldef = (JaspiceCircuit) repo.getCell(cellname); + if (celldef == null) { + try { + parser.parseFile(filename, repo); + } catch (SpiceFileFormatException e) { + throw new JaspiceException("Parse Error: "+e.getMessage(), e); + } catch (java.io.IOException e) { + throw new JaspiceException("Parse Error: "+e.getMessage(), e); + } + /*for (Iterator i = repo.getCellTypesIterator(); i.hasNext();) { + System.out.println((String) i.next()); + }*/ + celldef =(JaspiceCircuit) repo.getCell(cellname); + if (celldef == null) + throw new JaspiceException("Cell definition "+cellname+ + " not found in "+filename); + } + + //JaspiceCircuit jcircuit = (JaspiceCircuit) deepCopy(celldef); + /** Add the instance to the instance space **/ + //circuits.put(fullname, jcircuit); + //circuit.addSubcell(fullname, jcircuit); + //FIX ME? flattens the cells in the repo as well! + circuit.addSubcell(fullname, celldef); + circuit.flatten(); + circuit.setHigh(high); + circuit.setLow(low); + circuit.setMaxerr(maxerr); + if (!circuit.powered()) + try { + circuit.addPowerSupply(hvdd, hgnd); + System.out.println("Power Supply added across "+vdd+" and "+gnd); + } catch(JaspiceCircuit.JaspiceCircuitException e) { + System.out.println("Warning : "+e.getMessage()); + } + circuit.printStats(); + } + + /** Tests to see if the simulation has been initialized and started **/ + public boolean isRunning() { return running; } + + /** Initialize on first run **/ + private void initialize(double timestep) + throws JaspiceException { + if (callback != null) + callback.init(); + if (circuit == null) + throw new JaspiceException("No circuit built, cannot initialize."); + circuit.setTimeStep(timestep); + Jaspice.setDSimTime(DSim.get().getTime()); + } + + /** Run the simulation + * @param newDur Duration to run the simulation, a newDur of zero will + * run the simulation to timemax **/ + public void run(double newDur) + throws JaspiceException, PropertyException { + if (circuit == null) throw new JaspiceException("No circuit built."); + if (callback == null) System.out.println("WARNING: No callback used."); + double timemax = newDur; + if (newDur == 0) + timemax = getDoubleProperty("timemax"); + double timestep = getDoubleProperty("timestep"); + double poststep = getDoubleProperty("poststep"); + int dsimstep = getIntegerProperty("dsimstep"); + double prstau = getDoubleProperty("prstau"); + if (!running) { //initialize + initialize(timestep); + running = true; + } + long numsteps = Math.round((timemax - time)/timestep); + double starttime = time; + long totalsteps = numsteps; + long iterations = 0; + while (numsteps-- > 0 ) { + + iterations += circuit.step(); + JaspiceCircuit.digitalStep(dsimstep); + if (callback != null) callback.update(); + time+= timestep; + } + System.out.println("Ran from "+starttime+" to "+time+" ("+ + totalsteps+" steps, iterations/step= "+ + (iterations/totalsteps)+")"); + } + + /** Close stuff on exit **/ + private void cleanup() { + try { + if (callback != null) + callback.finish(); + } catch (JaspiceException e) { + System.out.println("Error, callback couldn't finish:\n\t"+e.getMessage()); + } + } + /** Set the dsim time internally in Jaspice. Because Jaspice is timesteped, + * and DSim only cycles when it has inputs, Jaspice needs to keep an + * internal count on the amount it needs to stroke DSim to stay synchronized + * **/ + public static void setDSimTime(long dtime) { + JaspiceCircuit.setDSimTime(dtime); + } + + /** Get a property from the Jaspice parameter list + * @return A JaspiceProp with the proper parameter (or null if not found)**/ + private JaspiceProp getProperty(String key) + throws PropertyException { + if (!params.containsKey(key)) + throw new PropertyException("Property with key "+key+ + " not found."); + return (JaspiceProp) params.get(key); + } + + /** Return a formatted string for use in printing to stdout or to + * a file **/ + + public String printProperty(String key) + throws PropertyException { + return getProperty(key).printProp(key); + } + + /** Get all of the names of the properties in the parameter list + * @return A collection of strings**/ + public Collection getPropertyKeys() { + return params.keySet(); + } + + public static void addProperty(String key, JaspiceProp jprop) + throws PropertyException { + if (params == null) params = new HashMap(); + if (params.containsKey(key)) + throw new PropertyException("Key "+key+" already exists, cannot"+ + " add again."); + params.put(key,jprop); + } + /**************************************************************** + * Methods to parse properties into different kinds of base types + ****************************************************************/ + + /** Get the property only if it is a double, throw an exception otherwise **/ + public double getDoubleProperty(String key) + throws PropertyException{ + JaspiceProp jp = (JaspiceProp) params.get(key); + if (jp == null) + throw new PropertyException("Key "+key+" not found."); + Object o = jp.getValue(); + if (!(o instanceof Double)) + throw new PropertyException(key+"'s value is not a Double"); + return ((Double) o).doubleValue(); + } + + /** Get the property only if it is an integer, throw an exception otherwise **/ + public int getIntegerProperty(String key) + throws PropertyException{ + JaspiceProp jp = (JaspiceProp) params.get(key); + if (jp == null) + throw new PropertyException("Key "+key+" not found."); + Object o = jp.getValue(); + if (!(o instanceof Integer)) + throw new PropertyException(key+"'s value is not an Integer"); + return ((Integer) o).intValue(); + } + + /** Get the property only if it is a boolean, throw an exception otherwise **/ + public boolean getBooleanProperty(String key) + throws PropertyException{ + JaspiceProp jp = (JaspiceProp) params.get(key); + if (jp == null) + throw new PropertyException("Key "+key+" not found."); + Object o = jp.getValue(); + if (!(o instanceof Boolean)) + throw new PropertyException(key+"'s value is not a Boolean"); + if (((Boolean) o).equals(Boolean.TRUE)) return true; + return false; + } + + /** Get the property only if it is a string, throw an exception otherwise **/ + public String getStringProperty(String key) + throws PropertyException{ + JaspiceProp jp = (JaspiceProp) params.get(key); + if (jp == null) + throw new PropertyException("Key "+key+" not found."); + Object o = jp.getValue(); + if (!(o instanceof String)) + throw new PropertyException(key+"'s value is not a String"); + return (String) o; + } + + /***************************************************************** + * Classes to add different types of drivers to the nodes + *****************************************************************/ + + /** Drive the simulation with a digital node + * @param aname Name of the analog node to drive + * @param dname Name of the digital node driving**/ + public void addDigitalDriver(String aname, String dname) + throws JaspiceException { + Node node = findNode(aname); + com.avlsi.tools.dsim.Node dnode = DSim.get().findNode(dname); + if (node != null) { + if (dnode != null) { + try { + double prstau = getDoubleProperty("prstau"); + DigitalDriver dd = new DigitalDriver(prstau); + node.setDriver(dd); + dnode.addWatch(dd); + } catch (PropertyException e) { + throw new JaspiceException(e); + } + System.out.println("Analog node "+node.getName()+ + " will be driven by "+ + dnode.getName()); + } else throw new JaspiceException("Cannot find digital node "+ + dname); + } else throw new JaspiceException("Node "+aname+" not found."); + } + + /** Adds a source handler to the circuit **/ + public void addSourceHandler(String key, SourceHandler sH) { + JaspiceCircuit.addSourceHandler(key,sH); + } + + /** adds a source to the circuit **/ + public void addSource(String name, String type, String pname, String nname, + String[] args) throws JaspiceException { + if (circuit == null) + throw new JaspiceException("No circuit built, cannot add source."); + try { + HierName hp = HierName.makeHierName(pname, '.'); + HierName hn = HierName.makeHierName(nname, '.'); + HierName hname = HierName.makeHierName(name, '.'); + //Use the Source just to make passing easier + circuit.addSource(new com.avlsi.circuit.Source( + hname, type, hp, hn, args)); + } catch(InvalidHierNameException e) { + throw new JaspiceException(e); + } catch (JaspiceCircuit.Exception e) { + throw new JaspiceException(e); + } + } + + /***************************************************************** + * Class to represent exceptions in Property processing. + *****************************************************************/ + public static final class PropertyException + extends java.lang.Exception { + public PropertyException(final String message) { + super(message); + } + } + + /***************************************************************** + * Set a static variable + *****************************************************************/ + public static void set(String key, String val) + throws PropertyException { + if (!params.containsKey(key)) + throw new PropertyException("Key "+key+" not found"); + JaspiceProp jp = (JaspiceProp) params.get(key); + //Supports doubles, ints and booleans, the rest go as strings + Object o = jp.getValue(); + if (o instanceof Double) { + jp.setValue(new Double(val)); + } else if (o instanceof Integer) { + jp.setValue(new Integer(val)); + } else if (o instanceof Boolean) { + if ((val.equalsIgnoreCase("on")) || + (val.equals("1"))) val = "true"; + if ((val.equalsIgnoreCase("off")) || + (val.equals("0"))) val = "false"; + jp.setValue(new Boolean(val)); + } else jp.setValue(val); + } + + /** Get the toplevel circuit modeled in Jaspice **/ + private JaspiceCircuit getCircuit() { + return circuit; + } + + /** Add alias name to node node. + * Assumes a flattened circuit**/ + public void aliasNode(Node node, String name) + throws JaspiceException { + Node node2 = findNode(name); + if (node2 != null) { + throw new JaspiceException("Node with name "+name+ + " already exists, cannot alias two nodes that"+ + " already exist."); + } + try { + circuit.aliasNames(node.getName(), + HierName.makeHierName(name,'.')); + } catch (InvalidHierNameException e) { + throw new JaspiceException("The name "+name+ + " is not a valid HierName.", e); + } + } + + /** Returns an iterator of HierNames containing all aliases. One + * alias will be a pointer (name.isPointer() == true) **/ + public Iterator getAliases(Node node) { + + return circuit.getAliases(node); + } + + // + //Simulator Interface functions + // + + //private boolean firstprint = true; + /** Not implemented currently **/ + public void printStatement(String type, String args[]) + throws SpiceFileFormatException { +/* if (!type.equals("TRAN")) + throw new SpiceFileFormatException("Only TRAN (transient) .print"+ + " functions supported."); + if (circuit == null) + throw new SpiceFileFormatException("No circuits built, .print ignored"); + if (firstprint) { + try { + clearTraceList(); + } catch (JaspiceException e) { + throw new SpiceFileFormatException("Error in simulator .PRINT"+ + " : "+e.getMessage()); + } + firstprint = false; + } + for(int i=0;iname **/ + public Node findNode(String name) { + try { + HierName hname = HierName.makeHierName(name,'.'); + return findNode(hname); + } catch (InvalidHierNameException e) { + return null; + } + } + + public Node findNode(HierName hname) { + Node node = (Node) nodeMap.get(hname); + if (node != null) return node; + //not canonical, gotta go searching + return findPointer(hname); + } + + /** Find the nodename that actually points to a real node **/ + private Node findPointer(HierName name) { + Iterator i = getEquivalentNames(name); + if (i == null) return null; + while (i.hasNext()) { + HierName curr = (HierName) i.next(); + if (curr.isPointer()) { + //Get the pointer + return (Node) nodeMap.get(HierName.trim(curr)); + } + } + System.out.println("... not found."); + return null; + } + + public AbstractDevice findDevice(String name) { + HierName hname = HierName.makeHierName(name); + return findDevice(hname); + } + + public AbstractDevice findDevice(HierName hname) { + return (AbstractDevice) devices.get(hname); + } + + public Collection getNodes() { return nodeMap.values(); } + + public Collection getDevices() { return devices.values(); } + + /** + * Take one simulation timestep, returns the number of iterations used in the + * step. + **/ + public long step() { + initialize(); + long iterations = analogStep(); + time += timestep; + return iterations; + + } + + /** Initialize all nodes in the circuit **/ + private void initialize() { + // Clear out data values + for (final Iterator i = nodeMap.values().iterator(); i.hasNext(); ) + ((Node) i.next()).initialize(); + } + + + /** Set the dsim time internally in Jaspice. Because Jaspice is timesteped, + * and DSim only cycles when it has inputs, Jaspice needs to keep an + * internal count on the amount it needs to stroke DSim to stay synchronized + * **/ + public static void setDSimTime(long dtime) { + dsimtime = dtime; + } + + /** + * Stroke the dsim so that it is in step with Jaspice, will only run + * with a positive dsimastep + **/ + public static void digitalStep(long dsimstep) { + if (dsimstep > 0) { + dsimtime += dsimstep; + DSim dsim = DSim.get(); + dsim.cycle(dsimtime - dsim.getTime()); + } + } + + /** + * Take one simulation step for analog devices. + **/ + private int analogStep() { + evaluateDevices(); + int iters = evaluateNodes(); + changeVoltage(); + return iters; + } + + private void evaluateDevices() { + // Evaluate voltages, charges and currents on all devices + for (final Iterator i = devices.values().iterator(); i.hasNext(); ) { + AbstractDevice device = (AbstractDevice) i.next(); + device.evalVoltage(chargeScale, currentScale, + derivChargeScale, derivCurrentScale,time); + } + } + + private int evaluateNodes() { + final Collection c = nodeMap.values(); + // + //Evaluate all of the drivers on the nodes, such as digital drivers + // + for (final Iterator i = c.iterator(); i.hasNext(); ) { + Node node = (Node) i.next(); + if (node.getDriver() != null) { + node.setAnalogNode(node.getDriver().getDrivenVoltage(time), + chargeScale, currentScale, + derivChargeScale, derivCurrentScale, + timestep, + node.getDriver().getDrivenTau()); + } + } + + // + //Normalize the nodes (makes AX=B simpler) + // + for (final Iterator i = c.iterator(); i.hasNext(); ) + ((Node) i.next()).normalize(); +/* + for (final Iterator i = c.iterator(); i.hasNext(); ) { + Node node = (Node) i.next(); + System.out.print(node.getName()+" v= "+node.getVoltage()+" delv= "+node.getVoltageChange()+" B="+node.getResult()+" : "); + TreeMap neighborMap = node.getNeighborMap(); + for (final Iterator j = neighborMap.keySet().iterator(); + j.hasNext(); ) { + Object nodeId = j.next(); + if (nodeId.equals(node.getHash())) + continue; + + double[] matrixValue = (double[]) neighborMap.get(nodeId); + //Node neighbor = null; + //if (changeGlobals) + // node = getNode((HierName) nodeId); + //else node = findNode((HierName) nodeId); + Node neighbor = (Node) nodeMap.get(nodeId); + System.out.print(neighbor.getName()+"("+matrixValue[0]+") "); + } + System.out.println(""); + } +*/ + + //GGG Is it really good to directly access neighborMap or not? + // Use relaxation to solve for new voltage changes + double maxDelta; + //Count the number of relaxation steps used + int curr_iterations = 0; + //Damp if needed + double alpha = 1; + do { + // Greatest change in X, where X is estimated change in voltage + maxDelta = 0; + + // Relax each individual node + // In theory, we want A*X = B + // We can write this as Bi - Sum(all j but i){Aij*Xj} - Aii*Xi = 0 + // So Xi = (Bi - Sum(all j but i){Aij*Xj})/Aii + for (final Iterator i = c.iterator(); i.hasNext(); ) { + Node node = (Node) i.next(); + Object nodeId = node.getHash(); + TreeMap neighborMap = node.getNeighborMap(); + + // Iterate over all neighboring nodes + double change = node.getResult(); + for (final Iterator j = neighborMap.keySet().iterator(); + j.hasNext(); ) + { + Object neighId = (Object) j.next(); + if (neighId.equals(nodeId)) + continue; + + double[] matrixValue = (double[]) neighborMap.get(neighId); + Node neighbor = (Node) nodeMap.get(neighId); + change -= matrixValue[0] * neighbor.getVoltageChange(); + } + + double changeDelta = Math.abs(change - node.getVoltageChange()); + node.setVoltageChange(alpha*change); //damp with alpha + //The total change needs to be communicated to the friend nodes + + if (changeDelta > maxDelta) + maxDelta = changeDelta; + } + curr_iterations++; + if (curr_iterations == 1000) { + System.out.println("WARNING: relaxation hasn't converged in 1000"+ + " iterations, maxDelta= "+maxDelta+ + " damping... "); + } + } while (maxDelta > relaxationThreshold); + if (curr_iterations >=1000) System.out.println("successful."); + return curr_iterations; + } + + public void changeVoltage() { + Collection c = nodeMap.values(); + // Save node change values + for (final Iterator i = c.iterator(); i.hasNext(); ) + ((Node) i.next()).changeVoltage(); + } + + /************************************************* + * Circuit Statistics + *************************************************/ + + public void printStats() { + System.out.println("Circuit Statistics:\n"+ + " "+getNodeCount()+" analog nodes\n"+ + " "+getTransistorCount()+" transistors"+ + ", "+getDiodeCount()+" diodes\n"+ + " "+getCapacitorCount()+" capacitors"+ + ", "+getResistorCount()+ " resistors\n"+ + " "+getISourceCount()+" current sources"+ + ", "+getVSourceCount()+" voltage sources"); + } + + /************************************************* + * Static subcircuit repository nested subclass. + *************************************************/ + public static class Repository extends AbstractCircuit.Repository { + + /** + * CircuitGraph generator method. + **/ + protected AbstractCircuit newCircuitGenerator(final String cellType) { + return new JaspiceCircuit(cellType); + } + } + + /***************************************************************** + * Class to represent exceptions in CircuitGraph processing. + *****************************************************************/ + public static final class JaspiceCircuitException extends java.lang.Exception { + public JaspiceCircuitException(final String message) { + super(message); + } + } + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceException.java new file mode 100644 index 0000000000..d08f6b4509 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +/***************************************************************** + * Class to represent exceptions in Jaspice. + *****************************************************************/ +public final class JaspiceException + extends java.lang.Exception { + public JaspiceException(final String message) { + super(message); + } + public JaspiceException(final String message, Throwable cause) { + super(message, cause); + } + public JaspiceException(Throwable cause) { + super(cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceModule.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceModule.java new file mode 100644 index 0000000000..b926e3c96a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceModule.java @@ -0,0 +1,536 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.util.cmdline.CmdLine; +import com.avlsi.util.cmdline.CmdCommand; +import com.avlsi.util.cmdline.CmdModule; +import com.avlsi.util.cmdline.Signal; +import java.util.Iterator; +import com.avlsi.tools.dsim.DSim; +import com.avlsi.tools.dsim.DSimSynchronizer; +import com.avlsi.file.common.HierName; +/** + * Class for running Jaspice throught the CmdLine interface. See + * for more details on each command. + * + * @author Dan Daly + * @version $Date$ + **/ +public class JaspiceModule extends CmdLine{ + + /** Jaspice Singleton Object **/ + private Jaspice ja = null; + /** TraceFile Callback **/ + private DefaultCallback callback; + + /** Interrupt handler. Catches Ctrl-C and tells the simulator to stop. **/ + Signal.Handler intHandler = new Signal.Handler() { + public void execute() { + DSim dsim = DSim.get(); + if (dsim!=null) { dsim.interrupt(); } + } + }; + + /** When run from the shell can also specify a setup file **/ + public void install(CmdModule parent, String args[]) { + // process any arguments from the invocation command line + if (args==null || args.length!=1) { + System.out.println("Usage: jaspice file.setup"); + return; + } + routeCommand("/source " + args[0]); + } + + /** + * Constructor + **/ + public JaspiceModule() { + super(false); + this.ja = Jaspice.get(); + callback = new DefaultCallback(); + ja.setCallback(callback); + addIntHandler(intHandler); + addCommands(commands); + } + + public String getName() { return "Jaspice"; } + public String getHelpMsg() { return "\tJaspice/\t\tanalog simulation"+ + " module"; } + CmdCommand commands[] = { + + /******************************************************************* + ** Loads the cdl or spice file into Jaspice with a specified + ** isntance name + ********************************************************************/ + + new CmdCommand("attach", "attach "+ + " [instance_hierarchical_name]", + "Builds a Jaspice circuit from with"+ + " instance name ") { + public void execute(String args[]) { + if (args != null && (args.length==2 || args.length==3)) { + try { + String hiername = ""; + if (args.length ==3) hiername = args[2]; + + ja.buildCircuit(args[0], //filename + args[1], //celltype + hiername //HierName+instName + ); + } catch (JaspiceException e) { + System.out.println("ERROR, JaspiceException: "+ + e.getMessage()); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Aliases a node name in Jaspice with a new name + *********************************************************************/ + + new CmdCommand("alias", "alias "+ + " ", + "Connects the with a new name ") { + public void execute(String args[]) { + if (args != null && args.length==2) { + if (ja.isRunning()) { + System.out.println( + "Simulation started, aliases are frozen."); + } else { + Node node = ja.findNode(args[0]); + if (node == null) { + System.out.println("Node "+args[0]+" not found."); + return; + } + try { + ja.aliasNode(node,args[1]); + } catch (JaspiceException e) { + System.out.println(e.getMessage()); + } + } + + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Sets static variables within Jaspice + *********************************************************************/ + + new CmdCommand("set", "set ", + "Set a Jaspice property with name "+ + " to ") { + public void execute(String args[]) { + if (args != null && args.length==2) { + if (ja.isRunning()) { + System.out.println( + "Simulation started, parameters are frozen."); + } else { + try { + ja.set(args[0],args[1]); + } catch (Jaspice.PropertyException e) { + System.out.println(args[0]+" not found : "+ + e.getMessage()); + } + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Lists all of the static variables in Jaspice and their values + *********************************************************************/ + + new CmdCommand("set?", "set? [param_name]", + "Print the value of Jaspice property [param_name],"+ + " or print out all propertiesand their values") { + public void execute(String args[]) { + if ((args == null) || (args.length==1)){ + if(args == null) { + for(final Iterator i = ja.getPropertyKeys().iterator(); + i.hasNext();) { + String key = (String)i.next(); + try { + System.out.println( + ja.printProperty(key)); + } catch (Jaspice.PropertyException e) {} + } + } else { + try { + System.out.println(ja.printProperty(args[0])); + } catch (Jaspice.PropertyException e) { + System.out.println("Property with key "+args[0]+ + " not found."); + } + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Watches an analog node + *********************************************************************/ +/* + new CmdCommand("watch", "watch ", + "Add node to the watch list") { + public void execute(String args[]) { + if (args != null && args.length==1) { + Node node = ja.findNode(args[0]); + if (node != null) { + TempWatcher tw = new TempWatcher(args[0]); + node.addAnalogWatcher(tw); + } else + System.out.println("Node "+args[0]+" not found."); + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + */ + /********************************************************************** + ** Unwatches an analog node + *********************************************************************/ +/* + new CmdCommand("unwatch", "unwatch ", + "Remove a node from the watch list") { + public void execute(String args[]) { + if (args != null && args.length==1) { + //Removes a node from the watch list + System.out.println("Sorry not implemented :("); + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + */ + /******************************************************************** + * Reports all nodes being traced cuurently by callback + ********************************************************************/ + + new CmdCommand("trace?", "trace? [type=V,I1,I2,I3,I4]", + "Displays the nodes and/or devices being traced,"+ + " optionally provide a type to query only that type") { + public void execute(String args[]) { + if (args == null || args.length==1) { + Iterator strings = null; + int type = -1; + if (args != null) { + type = DefaultCallback.getType(args[0]); + if (type != -1) { + strings = callback.printElements(type); + } else System.out.println("Unknown type: "+args[0]); + } else strings = callback.printElements(); + if (strings != null) { + while(strings.hasNext()) { + System.out.print((String)strings.next()); + if (strings.hasNext()) + System.out.print(", "); + } + System.out.println(""); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /******************************************************************** + * Prints out all of the nodes + ********************************************************************/ + + new CmdCommand("nodes?", "nodes?", + "Displays all of the nodes in the circuit") { + public void execute(String args[]) { + if (args == null) { + for(Iterator i = ja.getNodes().iterator(); i.hasNext();) { + Node node = (Node) i.next(); + StringBuffer buf = new StringBuffer(" aka "); + for(Iterator j = ja.getAliases(node);j.hasNext();) { + HierName hname = (HierName) j.next(); + if (hname.isPointer()) + buf.insert(0,HierName.trim(hname).toString()); + else { + buf.append(hname.toString()); + if (j.hasNext()) + buf.append(" "); + } + } + System.out.println(buf.toString()); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + /******************************************************************** + ** Traces an analog node + *********************************************************************/ + + new CmdCommand("trace", "trace [type=V(default),I1,I2,I3,I4]", + "Add node or device to the tracefile with"+ + " type [type]") { + public void execute(String args[]) { + if (args != null && args.length>=1 && args.length <=2) { + if ( (args.length == 1) || + (args[1].equals("V")) ) { + Node node = ja.findNode(args[0]); + if (node == null) + System.out.println("Node "+args[0]+ + " not found."); + else callback.trace(node,Node.VOLTAGE); + } else { + int type = DefaultCallback.getType(args[1]); + if (type != -1) { + AbstractDevice dev = ja.findDevice(args[0]); + if (dev == null) + System.out.println("Device "+args[0]+ + " not found."); + else callback.trace(dev,type); + } else System.out.println("Unknown type: "+args[1]); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Untraces an analog node + *********************************************************************/ + + new CmdCommand("untrace", "untrace "+ + " [type=V(default),I1,I2,I3,I4]", + "Remove a node or device with "+ + " and optionally [type] from the tracefile") { + public void execute(String args[]) { + if (args != null && args.length>=1 && args.length <=2) { + if ( (args.length == 1) || + (args[1].equals("V")) ) { + Node node = ja.findNode(args[0]); + if (node == null) + System.out.println("Node "+args[0]+ + " not found."); + else callback.untrace(node,Node.VOLTAGE); + } else { + int type = DefaultCallback.getType(args[1]); + if (type != -1) { + AbstractDevice dev = ja.findDevice(args[0]); + if (dev == null) + System.out.println("Device "+args[0]+ + " not found."); + else callback.untrace(dev,type); + } else System.out.println("Unknown type: "+args[1]); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + + /********************************************************************** + ** Traces all analog nodes + *********************************************************************/ + + new CmdCommand("traceall", "traceall", + "Adds all nodes to the tracefile") { + public void execute(String args[]) { + if (args == null) { + callback.addAllNodesToTrace(); + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Untraces all analog nodes + *********************************************************************/ + + new CmdCommand("untraceall", "untraceall [nodes, devices]", + "Removes all nodes from the tracefile, add the keyword"+ + " nodes to remove only nodes, add devices to remove"+ + " only devices") { + public void execute(String args[]) { + if (args == null) { + callback.clearTraceList(); + System.out.println("All nodes and devices removed"+ + " from tracelist."); + } else if (args.length == 1) { + if (args[0].equals("nodes")) { + callback.removeAllNodesFromTrace(); + System.out.println("All nodes removed from tracelist."); + } else if (args[0].equals("devices")) { + callback.removeAllDevicesFromTrace(); + System.out.println("All devices removed from tracelist."); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Displays the Current Time in seconds + *********************************************************************/ + + new CmdCommand("time", "time", + "Returns current Jaspice time") { + public void execute(String args[]) { + if (args == null) { + System.out.println("Jaspice Time = "+ja.getTime()+" seconds"); + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Synchronize Jaspice to run along-side DSim + *********************************************************************/ +/* + new CmdCommand("withDSim", "withDSim ", + "Run alongside DSim with equal to"+ + " ") { + public void execute(String args[]) { + if (args != null && args.length==2) { + int dunits = Integer.parseInt(args[0]); + double tunits = Double.parseDouble(args[1]); + DSimSynchronizer ds = new DSimSynchronizer(dunits,tunits); + ds.addDevice(Jaspice.get()); + ds.start(); + System.out.println("Running Jaspice alongside DSim with"+ + " dunits= "+dunits+" which equals "+ + tunits+" seconds"); + } else + System.out.println("Usage: "+this.getUsage()); + } + }, +*/ + /********************************************************************** + ** Runs the simulation + *********************************************************************/ + + new CmdCommand("run", "run [time_in_secs]", + "Run the analog simulation,"+ + " optionaly providing a time to stop the run"+ + " (which overrides timemax)") { + public void execute(String args[]) { + if ((args == null) || (args.length ==1)) { + try { + double newDur = 0; + if (args != null){ + try { + newDur = Double.parseDouble(args[0]); + } catch(NumberFormatException e) { + System.out.println("Time provided: "+args[0]+ + " should be a real number."); + return; + } + } + ja.run(newDur); + } catch (JaspiceException e) { + System.out.println("ERROR, JaspiceException: "+ + e.getMessage()); + } catch (Jaspice.PropertyException e) { + System.out.println("PropertyException : "+ + e.getMessage()); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + + /********************************************************************** + ** Drives an analog node with digital inout (requires DSim) + *********************************************************************/ +/* + new CmdCommand("drive", "drive ", + "Drive an analognode with a digital input"+ + " (requires DSim)") { + public void execute(String args[]) { + if (args != null && args.length==2) { + try { + ja.addDigitalDriver(args[0],args[1]); + } catch (JaspiceException e ) { + System.out.println(e.getMessage()); + } + } else + System.out.println("Usage: "+this.getUsage()); + + } + }, + */ + /********************************************************************** + * Add a voltage source + *********************************************************************/ + + new CmdCommand("vsource", "vsource name n+ n- type arg1 arg2 ... argN", + "Attach a voltage source device across two nodes") { + public void execute(String args[]) { + if (args != null && args.length>=4) { + String[] newargs = null; + if (args.length > 4) { + newargs = new String[args.length-4]; + System.arraycopy(args,4,newargs,0,newargs.length); + } + try { + ja.addSource(args[0], args[3],args[1],args[2],newargs); + } catch (JaspiceException e) { + System.out.println(e.getMessage()); + } + } else + System.out.println("Usage: "+this.getUsage()); + } + }, + }; +/* + private class TempWatcher implements AnalogWatcher { + + private byte value = -1; + private String name; + + private double high = 1.2; + private double low = .6; + + TempWatcher(String nodename) { + this.name = nodename; + DSim.get().setNodeValue("ckbar", (byte)0); + } + public void voltageChanged(double voltage) { + if (voltage < low) { + if ((value == -1) || (value == 1)) { + value = 0; + sendEvent(); + } + } else if (voltage > high) { + if (value <=0) { + value = 1; + sendEvent(); + } + } + } + + private void sendEvent() { + System.out.println("The node "+name+" has changed to "+value); + //byte ckbar = 1; + //if (value == 1) ckbar = 0; + DSim.get().setNodeValue("ckbar",value); + System.out.println("Sending "+value+" to ckbar"); + } + } + +*/ + +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceProp.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceProp.java new file mode 100644 index 0000000000..e6e662ee0b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/JaspiceProp.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice ; + +/** + * Class for ... + * + * @author Dan Daly + * @version $Date$ + **/ + +public class JaspiceProp { + + private Object value; + private final String units; + private final String info; + /** + * Constructor. + **/ + public JaspiceProp(Object value, String units,String info) { + this.value = value; + this.units = units; + this.info = info; + } + + public JaspiceProp(Object value) { + this.value = value; + this.units = ""; + this.info = ""; + } + + public Object getValue() { return value; } + + public String getUnits() { return units; } + + public void setValue(Object o) { + this.value = o; + } + + public String printProp(String key) { + return " "+key+" : "+value+" ["+units+"]\n\t"+info; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspice.java new file mode 100644 index 0000000000..e2d14e5580 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspice.java @@ -0,0 +1,162 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.aspice; + +/** + * JNI wrapper for native C aspice and dsim. + * C pointer to CIRCUIT is represented as an int. + * All devices and nodes are referred to by number. + * + * @author Andrew Lines + * @version $Date$ + **/ + +public class NativeAspice { + + /** Define transistor constants */ + public static final int NMOS = +1; + public static final int PMOS = -1; + + /** Set current bsim3 model */ + static native void setBsim3Model + (String filename, double temperature); + + /** Set simulation options */ + static native void setOptions + (double timestep, double poststep, + double maxerr, double coupling_cutoff, + double trueV, double falseV, double prs_tau); + + /** Create an empty circuit */ + static native int createCircuit(); + + /** Allocate memory for analog nodes and devices */ + static native void allocateAnalog + (int circuitHandle, int Nnodes, int Ndevices); + + /** Allocate memory for digital nodes and rules */ + static native void allocateDigital + (int circuitHandle, int Ndnodes, int Ndrules); + + /** Link analog to digital node */ + static native void linkAnalogDigitalNode + (int inode, int idnode); + + /** Free memory associated with a circuit */ + static native void freeCircuit + (int circuitHandle); + + /** Prepare a circuit for simulation */ + static native void prepareCircuit + (int circuitHandle); + + /** Summarize statistics of a circuit */ + static native void summarizeCircuit + (int circuitHandle); + + /** Simulate the circuit with current options */ + static native void simulateCircuit + (int circuitHandle, String tracefilename, double from, double to); + + /** Create a digital node */ + static native void createDigitalNode + (int circuitHandle, int idnode, String name); + + /** Create a digital production rule */ + static native void createDigitalRule + (int circuitHandle, int idrule, + int Nguards, int [] iguards, int [] sense, + int itarget, int dir, int delay); + + /** Create an analog node */ + static native void createAnalogNode + (int circuitHandle, int inode, int watch, int warn, String name); + + /** Force an analog node to given voltage */ + static native void forceAnalogNode + (int circuitHandle, int inode, double forceV); + + /** Create a capacitor */ + static native void createCapacitor + (int circuitHandle, int idev, int iA, int iB, double C); + + /** Create a resistor */ + static native void createResistor + (int circuitHandle, int idev, int iA, int iB, double R); + + /** Create a BSIM3 source/drain resistor */ + static native void createSourceResistor + (int circuitHandle, int idev, int type, int source, + int iA, int iB, double W, double L, double NRS, double RSC); + + /** Create a BSIM3 diode */ + static native void createDiode + (int circuitHandle, int idev, int type, + int iS, int iB, double W, double L, double AS, double PS); + + /** Create a BSIM3 transistor */ + static native void createTransistor + (int circuitHandle, int idev, int type, + int iS, int iD, int iG, int iB, double W, double L); + + /** constructor */ + NativeAspice() { + } + + /** self-test 3 inverter ring oscillator */ + public static void main(String [] args) { + // load c libraries + System.err.println("Loading c library..."); + System.loadLibrary("aspice"); + + // set simulation options + System.err.println("Setting simulation options..."); + setOptions(1e-12,10e-12,1e-6,0.3,1.2,0,25e-12); + + // set default BSIM3 model + System.err.println("Setting default BSIM3 model..."); + setBsim3Model("tsmc18.bsim3",25); + + // create circuit + System.err.println("Creating circuit..."); + int circuit = createCircuit(); + allocateAnalog(circuit,5,6); + + // create nodes + System.err.println("Creating nodes..."); + int GND=0, Vdd=1; + int [] x = {2,3,4}; + createAnalogNode(circuit,0,1,0,"GND"); + createAnalogNode(circuit,1,1,0,"Vdd"); + createAnalogNode(circuit,2,1,0,"x[0]"); + createAnalogNode(circuit,3,1,0,"x[1]"); + createAnalogNode(circuit,4,1,0,"x[2]"); + + // create devices + System.err.println("Creating devices..."); + for (int i=0; i<3; i++) { + createTransistor(circuit,2*i+0,NMOS,GND,x[(i+1)%3],x[i],GND,0.6e-6,0.18e-6); + createTransistor(circuit,2*i+1,PMOS,Vdd,x[(i+1)%3],x[i],Vdd,0.9e-6,0.18e-6); + } + + // prepare the circuit + System.err.println("Prepare and summarize circuit..."); + prepareCircuit(circuit); + summarizeCircuit(circuit); + + // simulate + System.err.println("Simulating circuit..."); + forceAnalogNode(circuit,0,0); + forceAnalogNode(circuit,1,1.8); + simulateCircuit(circuit,"ring.trace",0,10e-9); + + // finish + System.err.println("Done."); + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceCircuit.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceCircuit.java new file mode 100644 index 0000000000..27baf6ca76 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceCircuit.java @@ -0,0 +1,180 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.HashMap; +import java.util.TreeMap; +import java.util.HashSet; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.util.container.MultiSet; + +import com.avlsi.util.recalc.IndependantVariable; +import com.avlsi.util.recalc.MinusOp; +import com.avlsi.util.recalc.PlusOp; +import com.avlsi.util.recalc.DivOp; +import com.avlsi.util.recalc.MultOp; +import com.avlsi.util.recalc.Literal; + +import com.avlsi.circuit.AbstractCircuit; +import com.avlsi.circuit.ResistorInterface; +import com.avlsi.circuit.DiodeInterface; +import com.avlsi.circuit.TransistorInterface; +import com.avlsi.circuit.CapacitorInterface; +import com.avlsi.circuit.SourceInterface; + +import com.avlsi.tools.dsim.DSim; + +/** NativeAspice Circuit needed for parsing */ +public class NativeAspiceCircuit extends AbstractCircuit { + + /** control verbosity */ + private boolean verbose = false; + + /** Which pass are we on? */ + private boolean firstpass = false; + + /** HierName-to-Node map for the entire circuit. */ + private MultiSet nodes; + + /** Which adsim to create stuff in */ + private NativeAspiceUtil adsim = null; + + /** counts of various devices */ + private int numVSources=0; + private int numISources=0; + private int numResistors=0; + private int numCapacitors=0; + private int numTransistors=0; + private int numDiodes=0; + + /** methods to return count of various devices */ + public int getResistorCount() { return numResistors; } + public int getCapacitorCount() { return numCapacitors; } + public int getTransistorCount() { return numTransistors; } + public int getDiodeCount() { return numDiodes; } + public int getNodeCount() { return nodes.size(); } + public int getVSourceCount() { return numVSources; } + public int getISourceCount() { return numISources; } + + /** methods to instantiate things */ + public void addResistor(ResistorInterface r) { + if (firstpass) { + if (verbose) + System.err.println("add resistor drain=" + r.getDrain() + + " source=" + r.getSource() + + " G=" + r.getConductance()); + nodes.addIfUnique(r.getDrain()); + nodes.addIfUnique(r.getSource()); + } else { + adsim.createResistor(r.getSource(),r.getDrain(), + r.getConductance()); + } + numResistors++; + } + public void addCapacitor(CapacitorInterface c) { + if (firstpass) { + if (verbose) + System.err.println("add capacitor drain=" + c.getDrain() + + " source=" + c.getSource() + + " C=" + c.getCapacitance()); + nodes.addIfUnique(c.getDrain()); + nodes.addIfUnique(c.getSource()); + } else { + adsim.createCapacitor(c.getSource(),c.getDrain(), + c.getCapacitance()); + } + numCapacitors++; + } + public void addTransistor(TransistorInterface t) { + if (firstpass) { + if (verbose) + System.err.println("add transistor source=" + t.getSource() + + " drain=" + t.getDrain() + + " gate=" + t.getGate() + + " bulk=" + t.getBulk() + + " W=" + t.getWidth() + + " L=" + t.getLength() + + " type=" + t.getType()); + nodes.addIfUnique(t.getDrain()); + nodes.addIfUnique(t.getSource()); + nodes.addIfUnique(t.getBulk()); + nodes.addIfUnique(t.getGate()); + } else { + adsim.createTransistor(t.getType(), + t.getSource(),t.getDrain(),t.getGate(),t.getBulk(), + t.getWidth(),t.getLength()); + } + numTransistors++; + } + public void addDiode(DiodeInterface diode) { + if (firstpass) { + if (verbose) + System.err.println("add diode source=" + diode.getSource() + + " drain=" + diode.getDrain() + + " area=" + diode.getArea() + + " width=" + diode.getWidth() + + " length=" + diode.getLength() + + " perim=" + diode.getPerimeter() + + " type=" + diode.getType()); + nodes.addIfUnique(diode.getDrain()); + nodes.addIfUnique(diode.getSource()); + } else { + adsim.createDiode(diode.getType(), + diode.getSource(),diode.getDrain(), + diode.getWidth(),diode.getLength(), + diode.getArea(),diode.getPerimeter()); + } + numDiodes++; + } + public void addSource(SourceInterface source) { + System.err.println("Sources not supported"); + } + + /** first pass constructor */ + public NativeAspiceCircuit(String cellType, NativeAspiceUtil adsim) { + super(cellType); + if (adsim==null) { + firstpass = true; + nodes = new MultiSet(); + this.adsim = null; + } + else { + firstpass = false; + nodes = adsim.AnalogNodeNames; + this.adsim = adsim; + } + } + + /** return nodes */ + public MultiSet getNodes() { + nodes.sort(); + return nodes; + } + + /** Static subcircuit repository nested subclass. */ + public static class Repository extends AbstractCircuit.Repository { + public NativeAspiceUtil adsim = null; // null on first pass + + /** CircuitGraph generator method. */ + protected AbstractCircuit newCircuitGenerator(final String cellType) { + return new NativeAspiceCircuit(cellType,adsim); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceUtil.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceUtil.java new file mode 100644 index 0000000000..789352e8d7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/NativeAspiceUtil.java @@ -0,0 +1,264 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.aspice; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Iterator; +import java.io.BufferedWriter; +import java.io.FileWriter; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.MultiSet; +import com.avlsi.file.spice.SpiceParser; +import com.avlsi.circuit.AbstractCircuit; +import com.avlsi.file.spice.SpiceFileFormatException; + +/** + * Extends NativeAspice to provide namespace management + * and maintain other state variables that live on the java side. + * Also performs multi-step functions. + * This is the correct way to access NativeAspice features. + * + * @author Andrew Lines + * @version $Date$ + **/ + +public class NativeAspiceUtil extends NativeAspice { + /** keep trace of currently created circuit handle */ + private int circuitHandle = 0; + + /** has circuit been prepped for simulation? */ + private boolean prepared = false; + + /** basename for files */ + private String basename = null; + + /** current analog time */ + private double analog_time = 0; + + /** analog namespace */ + public MultiSet AnalogNodeNames = null; + + /** options to pass to aspice */ + double timestep = 1e-12; + double poststep = 10e-12; + double maxerr = 1e-6; + double coupling_cutoff = 0.3; + double trueV = 1.2; + double falseV = 0; + double prs_tau = 25e-12; + + /** number of analog devices */ + int Ndevices = 0; + + /** constructor given name of a tracefile */ + public NativeAspiceUtil() { + System.loadLibrary("aspice"); + circuitHandle = createCircuit(); + } + + /** clear everything in the circuit */ + public void clear() { + System.err.println("clear circuit"); + freeCircuit(circuitHandle); + circuitHandle = createCircuit(); + Ndevices = 0; + prepared = false; + basename = null; + analog_time = 0; + } + + /** pass all the options to aspice */ + public void setOptions() { + setOptions(timestep,poststep,maxerr,coupling_cutoff,trueV,falseV,prs_tau); + } + + /** simulate circuit for given amount of time */ + public void simulate(double delay) { + System.err.println("simulate from=" + analog_time + " to=" + (analog_time+delay)); + setOptions(); + if (!prepared) { + prepareCircuit(circuitHandle); + summarizeCircuit(circuitHandle); + // write names file + try { + BufferedWriter namesfile = + new BufferedWriter(new FileWriter(basename + ".names")); + Iterator i = AnalogNodeNames.iterator(); + namesfile.write("time\n"); + while (i.hasNext()) namesfile.write((HierName) i.next() + "\n"); + namesfile.close(); + } catch (IOException e) { + System.err.println("can't write to names file."); + return; + } + prepared = true; + } + simulateCircuit(circuitHandle,basename + ".trace", + analog_time,analog_time+delay); + analog_time += delay; + } + + /** force an analog node to a given voltage */ + public void forceAnalogNode(HierName name, double voltage) { + forceAnalogNode(circuitHandle,AnalogNodeToNumber(name),voltage); + } + + /** handle userinterrupt has occured */ + public void interrupt() { + System.err.println("interrupted"); + } + + /** select BSIM3 model and temperature to use */ + public void selectModel(String filename, double temperature) { + setBsim3Model(filename,temperature); + } + + /** instantiate analog circuit (HACK) */ + public void instantiateSpice(String filename, String cellname) { + setOptions(); + if (filename.endsWith(".cdl")) + basename = filename.substring(0,filename.length()-4); + else if (filename.endsWith(".spice")) + basename = filename.substring(0,filename.length()-6); + else basename = filename; + prepared = false; + + // first pass of construction -- count devices and create namespace + SpiceParser parser = new SpiceParser(); + NativeAspiceCircuit.Repository repository = new NativeAspiceCircuit.Repository(); + try { + parser.parseFile(filename,repository); + } catch (FileNotFoundException e) { + System.err.println("can't find " + filename); + return; + } catch (IOException e) { + System.err.println("file trouble " + e); + return; + } catch (SpiceFileFormatException e) { + System.err.println("syntax error " + e); + return; + } + NativeAspiceCircuit circuit = (NativeAspiceCircuit) repository.getCell(cellname); + AnalogNodeNames = circuit.getNodes(); + + // allocate memory for analog nodes and devices + allocateAnalog(circuitHandle,AnalogNodeNames.size(), + circuit.getTransistorCount() + circuit.getDiodeCount() + + circuit.getResistorCount() + circuit.getCapacitorCount()); + + // create analog nodes + int num = 0; + Iterator i = AnalogNodeNames.iterator(); + while (i.hasNext()) { + HierName name = (HierName) i.next(); + createAnalogNode(circuitHandle,num++,1,0,name.toString()); + } + + // second pass of construction -- create devices + parser = new SpiceParser(); + repository = new NativeAspiceCircuit.Repository(); + repository.adsim = this; // enable second pass + try { + parser.parseFile(filename,repository); + } catch (FileNotFoundException e) { + System.err.println("can't find " + filename); + return; + } catch (IOException e) { + System.err.println("file trouble " + e); + return; + } catch (SpiceFileFormatException e) { + System.err.println("syntax error " + e); + return; + } + } + + /** instantiate prs circuit */ + public void instantiatePrs() { + System.err.println("instantiate digital"); + } + + /** set various options */ + public void setOption(String type, double value) { + if (type.equals("timestep")) timestep = value; + else if (type.equals("poststep")) poststep = value; + else if (type.equals("maxerr")) maxerr = value; + else if (type.equals("coupling_cutoff")) coupling_cutoff = value; + else if (type.equals("trueV")) trueV = value; + else if (type.equals("falseV")) falseV = value; + else if (type.equals("prs_tau")) prs_tau = value; + else System.err.println("unknown option"); + } + + /** get various options */ + public double getOption(String type) { + if (type.equals("timestep")) return timestep; + else if (type.equals("poststep")) return poststep; + else if (type.equals("maxerr")) return maxerr; + else if (type.equals("coupling_cutoff")) return coupling_cutoff; + else if (type.equals("trueV")) return trueV; + else if (type.equals("falseV")) return falseV; + else if (type.equals("prs_tau")) return prs_tau; + System.err.println("unknown option"); + return 0; + } + + /** print value of all options */ + public void printOptions() { + System.out.println("timestep=" + timestep); + System.out.println("poststep=" + poststep); + System.out.println("maxerr=" + maxerr); + System.out.println("coupling_cutoff=" + coupling_cutoff); + System.out.println("trueV=" + trueV); + System.out.println("falseV=" + falseV); + System.out.println("prs_tau=" + prs_tau); + } + + /** convert analog node name to node number */ + public int AnalogNodeToNumber(HierName name) { + if (AnalogNodeNames == null) return -1; + return AnalogNodeNames.findIndex(name); + } + + /** convert digital node name to node number */ + public int DigitalNodeToNumber(HierName name) { + return -1; + } + + /** create a transistor from node names */ + public void createTransistor(int type, + HierName S, HierName D, HierName G, HierName B, + double W, double L) { + createTransistor(circuitHandle,Ndevices++,(type==1 ? PMOS : NMOS), + AnalogNodeToNumber(S), AnalogNodeToNumber(D), + AnalogNodeToNumber(G), AnalogNodeToNumber(B), + W,L); + } + + /** create a diode from node names */ + public void createDiode(int type, + HierName S, HierName B, + double W, double L, double A, double P) { + if (W>0.0001) W=0.0001; // HACK + createDiode(circuitHandle,Ndevices++,(type==1 ? PMOS : NMOS), + AnalogNodeToNumber(S), AnalogNodeToNumber(B), + W,L,A,P); + } + + /** create a resistor from node names */ + public void createResistor(HierName S, HierName D, double G) { + createResistor(circuitHandle,Ndevices++, + AnalogNodeToNumber(S), AnalogNodeToNumber(D), 1/G); + } + + /** create a capacitor from node names */ + public void createCapacitor(HierName S, HierName D, double C) { + createCapacitor(circuitHandle,Ndevices++, + AnalogNodeToNumber(S), AnalogNodeToNumber(D), C); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Node.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Node.java new file mode 100644 index 0000000000..fc057e4b0a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Node.java @@ -0,0 +1,343 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.Collection; +import java.util.TreeMap; +import com.avlsi.file.common.HierName; + +/** + * This class simulates a circuit node + * + * @author Ted Vessenes, extended by Dan Daly + * @version $Name: $ $Date$ + * + * In theory, A*X = B where A is a matrix containing information + * about partial derivatives of current and charge (with respect + * to voltage) of all nodes in the system. neighborNodeMatrixRow + * represents a row of this sparse matrix. It is a list of all matrix + * entries based on derivatives with respect to this node's voltage. + * So if this is node 0, then neighborMap.get(node_1) contains data + * based on dI1/dV0 and dQ1/dV0. Note that X is a vector of current + * voltages, per node. This value is represented by "voltage". (The + * entire vector is distributed across all nodes.) B is a vector of + * information based on I and Q (cv. matrix row based on dI and dQ). + * Like X, B is also distributed across all nodes. Its data value is + * kept in "result". + **/ +public class Node implements java.io.Serializable{ + + public static final int VOLTAGE = 0; + + /** Id of the last created node. **/ + private static int lastId = 0; + + /** Id of this node. **/ + private Integer id; + + /** Hash Object for this Node **/ + private Object hash; + + /** Name of this node (optional) **/ + private HierName name; + /** + * A row of a sparse Matrix associated with this node. + * Based on Current and Charge derivatives (dI and dQ) with + * respect to this node's voltage. + * See class comments for more information. + **/ + private TreeMap neighborMap; + + /** + * Voltage across node. + * See class comments for more information. + **/ + private double voltage; + + /** Change in voltage since relaxation (performed by circuit). **/ + private double voltageChange; + + /** + * Result vector B of A*X=B. + * Based on Current and Charge data (I and Q) for this node. + * See class comments for more information. + **/ + private double result; + + /** Collection of watches on the node **/ + private final Collection watches = new ArrayList(1); + + /** The driver that drives the node **/ + private NodeDriver driver; + + /** + * Construct new node. + **/ + public Node() { + this(0); + name = null; + } + + /** + * Construct new node with initial voltage. + * @param voltage of node + **/ + public Node(double voltage) { + id = new Integer(++lastId); + neighborMap = new TreeMap(); + this.driver = null; + + this.voltage = voltage; + this.voltageChange = 0; + this.hash = getId(); + } + + public Node(HierName name) { + this(0); + this.name = name; + //System.out.println("New Node: "+name); + } + + public Node(HierName name,double voltage) { + this(voltage); + this.name = name; + //System.out.println("New Node: "+name); + } + + /** + * Track neighbor nodes. + * Devices using this node need to inform this node who its + * neighbors are. After all, neighbors are defined as "all nodes + * connected to this node through at most one device." + * @param nodes list + **/ + protected void addNeighborNodes(Node[] nodes) { + for (int i = 0; i < nodes.length; i++) { + Object neighborId = nodes[i].getHash(); + + if (!(nodes[i] instanceof GroundNode) && + !neighborMap.containsKey(neighborId)) + neighborMap.put(neighborId, new double[] {0}); } + } + + /** + * Add device to node. + * Note that we don't initialize the voltage because this speeds up + * relaxation convergence. + * @param device to add + **/ + protected void initialize() { + result = 0; + + for (final Iterator i = neighborMap.values().iterator(); i.hasNext(); ) + ((double[]) i.next())[0] = 0; // Set A = 0 + } + + /** + * Get Node Id. + * @return Id of this node. + **/ + public Integer getId() { + return id; + } + + /** + * Calculate hash code + * @return hash code (id of node) + **/ + public int hashcode() { + return id.intValue(); + } + + public Object getHash() { + return hash; + } + + public void setHash(Object o) { + hash = o; + } + + /** + * Get Node Name + * @return name + **/ + public HierName getName() { return name; } + /** + * Get Voltage. + * @return voltage + **/ + public double getVoltage() { + return voltage; + } + + /** Send voltage to digital node **/ + private void sendVoltage() { + for (Iterator i = watches.iterator(); i.hasNext();) { + AnalogWatcher nw = (AnalogWatcher)i.next(); + nw.voltageChanged(voltage); + } + } + + /** + * Set Voltage. + * @param voltage to set + **/ + public void setVoltage(double voltage) { + this.voltage = voltage; + sendVoltage(); + } + + /** + * Change Voltage + **/ + public void changeVoltage() { + this.voltage += voltageChange; + sendVoltage(); + + + } + + /** + * Get Voltage Change + **/ + public double getVoltageChange() { + return voltageChange; + } + + /** + * Set Voltage Change + **/ + public void setVoltageChange(double voltageChange) { + this.voltageChange = voltageChange; + } + + /** + * Get Result (B in A*X = B) + * @return result value + **/ + public double getResult() { + return result; + } + + /** + * Compute and set result value. + * @param chargeScale scalar for charge + * @param charge on node + * @param currentScale scalar for current + * @param current on node + **/ + public void setResult(double chargeScale, double charge, + double currentScale, double current) + { + result += chargeScale*charge + currentScale*current; + } + + public void forceResult(double d) { + result = d; + } + + /** + * Get map of neighbors to sparse matrix row entry + * @return node matrix row + **/ + public TreeMap getNeighborMap() { + return neighborMap; + } + + /** + * Compute and set matrix entry. + * @param node if charge derivative is dI0/dV1, node is 0 (and "this" is 1) + * @param chargeScale scalar for charge + * @param charge derivative on node + * @param currentScale scalar for current + * @param current derivative on node + **/ + public void setMatrix(Node node, + double chargeScale, double charge, + double currentScale, double current) + { + Object nodeId = node.getHash(); + double[] matrixValue = (double[]) neighborMap.get(nodeId); + if (matrixValue != null) + matrixValue[0] += chargeScale*charge + currentScale*current; + } + + /** + * Normalize Matrix row and result values for faster computation + **/ + public void normalize() { + double divisor = ((double[]) neighborMap.get(getHash()))[0]; + if (divisor == 0) + System.out.println("Warning: Attempting to normalize zero row!"); + + for (final Iterator i = neighborMap.values().iterator(); i.hasNext(); ) + ((double[]) i.next())[0] /= divisor; + + result /= divisor; + } + + /** Remove from our watcher list. **/ + public synchronized boolean removeAnalogWatcher(AnalogWatcher w) { + return watches.remove(w); + } + + /** Add to our watcher list, for change notifications. **/ + public synchronized boolean addAnalogWatcher(AnalogWatcher w) { + return watches.add(w); + } + /** Check presence in our watcher list. **/ + public synchronized boolean isAnalogWatcher(AnalogWatcher w) { + return watches.contains(w); + } + + public interface NodeDriver { + double getDrivenVoltage(double time); + double getDrivenTau(); + } + + public synchronized void setDriver(NodeDriver driver) { + this.driver = driver; + } + + public NodeDriver getDriver() { + return driver; + } + + /** set an analog node to V, ex values: mAq=1, mAi=-0.5*timestep, + * mBq=0, mBi=timestep */ + public void setAnalogNode(double V, double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double timestep,double prstau) { + double tau = prstau; + if (tau < 4*timestep) tau = 4*timestep; + //this.setResult(mBq*tau*(this.getVoltage() - V) - + // mBi*(this.getVoltage() -V)); + result = (chargeScale*tau-currentScale)*(this.getVoltage() - V); + /* Once a node becomes 'digital' or driven to the voltage V, + * it cannot be influenced by its neighboring nodes. So the + * diagonal matrix element is set to mAq*tau - mAi + * */ + for (final Iterator i= this.neighborMap.keySet().iterator(); + i.hasNext();) { + Object nodeId = i.next(); + double[] matrixValue = (double[]) neighborMap.get(nodeId); + if (nodeId.equals(getHash())) { + matrixValue[0] = derivChargeScale*tau - derivCurrentScale; + } else matrixValue[0] = 0; + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PWLVoltageSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PWLVoltageSource.java new file mode 100644 index 0000000000..091f7ca1ee --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PWLVoltageSource.java @@ -0,0 +1,246 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ +package com.avlsi.tools.aspice; +import com.avlsi.file.common.HierName; +import java.util.ArrayList; +import java.util.Iterator; +import java.io.FileReader; +import java.io.BufferedReader; +/** + * Class for Sinusoidal Voltage Source + * + * @author Dan Daly + * @version $Date$ + **/ + +public class PWLVoltageSource extends VoltageSource{ + + /** Holds all of the events **/ + private SimpleQueue queue; + + /** Delay before starting up the queue **/ + private double td; + + + /** Builds a sine voltage source device + * + * @param name HierName of the device + * @param nplus positive terminal node + * @param nminus negative terminal node + * @param vt Double array containing [ t1 v1 t2 v2 t3 v3 ... tn vn ] + * @param repeat time in units of seconds which specifies the start point + * of the waveform which is to be repeated. Set negative for no repeat. + * @param td Time delay before beginning the piece-wise linear + * variation in seconds. + * **/ + public PWLVoltageSource(final HierName name, + final Node nplus, + final Node nminus, + final double[] tv, + final double repeat, + final double td) { + super(name, nplus, nminus); + this.td = td; + this.queue = new SimpleQueue(); + int count = 0; + double lastTime = 0; + while (count < tv.length) { + double currShift = 0, currValue=0; + if (count == tv.length) { + System.out.println("Warning: PWL voltage source found voltage"+ + " value without matching time value."); + } else { + if (tv[count] < lastTime) { + System.out.println("Warning: PWL voltage source expects"+ + " monotonic increasing time values,"+ + " results may be affected."); + } + currShift= tv[count] - lastTime; + count++; + currValue = tv[count++]; + } + queue.add(new Event(currValue, currShift)); + lastTime += currShift; + } + if (repeat >= 0) + queue.setRepeat(repeat); + } + + public PWLVoltageSource(final HierName name, + final Node nplus, + final Node nminus, + final String filename, + final double repeat, + final double td) + throws java.io.FileNotFoundException,java.io.IOException { + this(name, nplus, nminus, getDoubles(filename), repeat, td); + } + + private static int splitLine(double[] parts, String line) { + if ((line == null) || (line.length()==0)) return -3; + if (line.charAt(0) == '#') return -3; + int start=-1,end=-1,count=0; + for (int loop=0;loop=0) && (end == -1)) end =loop; + } + if ((start >=0) && (end >=0)) { + if (start == -1) continue; + try { + if (count == 2) return -2; + parts[count++] = + Double.parseDouble(line.substring(start,loop+1)); + start=-1; end=-1; + } catch (NumberFormatException e) { + return -999; + } + } + } + if (count != 2) return -1; + return 1; + } + + private static final int initsize = 16; + private static double[] getDoubles(String filename) + throws java.io.FileNotFoundException,java.io.IOException { + double[] vect = new double[initsize]; + FileReader fr = new FileReader(filename); + BufferedReader br = new BufferedReader(fr); + int linenum =0, count=0; + double[] parts = new double[2]; + String line =""; + while ( (line = br.readLine()) != null) { + int result = splitLine(parts,line); + if (result == -3) continue; //Comment case + if (result ==-999) + System.out.println("PWL: Number Format Error on line "+linenum+ + "\n\t"+line+"\nignoring line"); + if (result == -2) + System.out.println("PWL: Too many arguments on line "+linenum+ + "\n\t"+line+"\nignoring line"); + else if (result == -1) + System.out.println("PWL: Too few arguments on line "+linenum+ + "\n\t"+line+"\nignoring line"); + else { + vect[count++] = parts[0]; + vect[count++] = parts[1]; + if (vect.length == count) { //Grow array + double[] temp = new double[2*vect.length]; + System.arraycopy(vect,0,temp,0,vect.length); + vect = temp; + } + } + linenum++; + } + double[] temp = new double[count]; + System.arraycopy(vect,0,temp,0,count); + return temp; + } + + public double ramp(Event curr, Event last, double time) { + double run = curr.tshift; + if (run == 0) return last.value; + double rise = curr.value - last.value; + double slope = rise/run; + double shift = time - queue.total; + return last.value + slope*(shift); + } + + public double getDrivenVoltage(double time,double timestep) { + if (time <= td) return 0; + Event curr = queue.getCurrent(); + time -= td; + if (time <= queue.total+curr.tshift) + return ramp(curr, queue.getLast(), time); + Event newCurr = queue.getNext(); + if (newCurr.equals(curr)) return newCurr.value; + return ramp(newCurr, curr,time); + } + + private class SimpleQueue extends ArrayList { + + private int index; + private int repeat; + private Event last; + private double total; + public SimpleQueue() { + this.index = 0; + this.repeat = -1; + this.last = null; + total = 0; + } + + + /** This function assumes the queue has already been built **/ + public void setRepeat(double rtime) { + Event last = null; + int count = 0; + double rtotal=0; + for(Iterator i = iterator();i.hasNext();) { + Event e = (Event) i.next(); + rtotal += e.tshift; + if (rtotal > rtime) { + //add the new event + repeat = count; + if (last != null) { + //Insert a new repeat point + Event newEvent = + new Event( ramp(e, last,rtime-(rtotal-e.tshift)), + rtime-(rtotal-e.tshift)); + add(repeat, newEvent); + e.tshift -= newEvent.tshift; + } + return; + } else { + count++; + last = e; + } + } + repeat = 0; + } + + public Event getCurrent() { + return (Event) get(index); + } + + public Event getLast() { + return last; + } + + public Event getNext() { + if (size() == 0) return null; + last = (Event) get(index); + total += last.tshift; + index++; + if (index == size()) { + if (repeat == -1) { + index--; + } else + index = repeat; + } + return (Event) get(index); + } + } + + private class Event { + public final double value; + public double tshift; + public Event(double v, double t) { value=v; tshift = t; } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PulseVoltageSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PulseVoltageSource.java new file mode 100644 index 0000000000..63ebc66792 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/PulseVoltageSource.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice ; +import java.util.Iterator; +import com.avlsi.file.common.HierName; +/** + * Class for ... + * + * @author Dan Daly + * @version $Date$ + **/ + +public class PulseVoltageSource extends VoltageSource { + + /** Initial value of the voltage or current, before the + * pulse onset (units of volts).**/ + private double v1; + /**Pulse plateau value (units of volts).**/ + private double v2; + /** Delay time in seconds from the beginning of transient interval to + * the first onset ramp. + ***/ + private double td; + /**Duration of the onset ramp in seconds, from the initial value to the pulse + * plateau value (reverse transit time). Default=timestep). + **/ + private double tr; + /**Duration of the recovery ramp in seconds, from the pulse plateau back to + * the initial value (forward transit time). Default=timestep. + **/ + private double tf; + /**Pulse width (the width of the plateau portion of the pulse) in seconds. + * Default=timestep. **/ + private double pw; + /**Pulse repetition period in seconds. Default=timestep. **/ + private double per; + + /** Builds a pulse voltage source device + * + * @param nplus positive terminal node + * @param nminus negative terminal node + * @param v1 trough voltage + * @param v2 peak voltage + * @param td delay at the beginning of the period before ramping up + * @param tr time duration of ramp (rising edge) + * @param tf time duration of falling edge + * @param pw time duration of peak (at v2) + * @param per period of pulse sequence + * **/ + public PulseVoltageSource(final HierName name, + final Node nplus, + final Node nminus, + final double v1, + final double v2, + final double td, + final double tr, + final double tf, + final double pw, + final double per) { + super(name, nplus, nminus); + //System.out.println("New PVS: v1 "+v1+" v2 "+v2+" td "+td+" tr "+tr+ + // " tf "+tf+" pw "+pw+" per "+per); + this.v1 = v1; + this.v2 = v2; + this.td = td; + this.tr = tr; + this.tf = tf; + this.pw = pw; + this.per = per; + } + + private double rampUp(double t){ return v1 + (v2-v1)*(t/ tr); } + + private double rampDown(double t){ return v1 + (v2-v1)*(1 - (t / tf)); } + + public double getDrivenVoltage(double time,double timestep) { + if (time <= td) return v1; + double gotime = (time -td) % per; //Find which part of the period we're in + if (gotime < tr) return rampUp(gotime); + if (gotime <= tr+pw) return v2; + if (gotime < tr+pw+tf) return rampDown(gotime-tr-pw); + return v1; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Resistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Resistor.java new file mode 100644 index 0000000000..5d5ef9a135 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Resistor.java @@ -0,0 +1,134 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.file.common.HierName; + +/** + * Class to represent resistors in .aspice files. + * + * @author Ted Vessenes + * @version $Name: $ $Date$ + **/ +public final class Resistor extends AbstractDevice + implements java.io.Serializable { + /** Conductance of resistor in 1/ohms */ + private double conductance; + /** Device currents **/ + + /** Drain node **/ + private double drainI; + /** Source node **/ + private double sourceI; + + /** + * Class constructor. + * @param source node + * @param drain node + * @param conductance of resistor + **/ + public Resistor(final HierName name, + final Node source, + final Node drain, + final double conductance) + { + super(new Node[] { source, drain }); + this.conductance = conductance; + this.name = name; + //System.out.println("New Resistor s="+source.getName()+ + // " d="+drain.getName()+ + // " cond= "+conductance); + } + + public Resistor(final Node source, + final Node drain, + final double conductance) { + this(null, source, drain, conductance); + } + /** + * Get source node. + * @return source node + **/ + public Node getSource() { + return nodes[0]; + } + + /** + * Get drain node. + * @return drain node + **/ + public Node getDrain() { + return nodes[1]; + } + + /** + * Get conductance of resistor. + * @return conductance of resistor + **/ + public double getConductance() { + return conductance; + } + + /** + * Set conductance of resistor. + **/ + public void setConductance(double conductance) { + this.conductance = conductance; + } + + /** returns the device current **/ + public double getCurrent(int type) { + switch (type) { + case AbstractDevice.I1: return drainI; + case AbstractDevice.I2: return sourceI; + } + return -1; + } + + public String getCode() { return "R";} + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device and then informs its nodes of these values. + * @param chargeScale scalar for charge calculation + * @param currentScale scalar for current calculation + * @param derivChargeScale scalar for charge derivative calculation + * @param derivCurrentScale scalar for current derivative calculation + **/ + public void evalVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) + { + Node source = getSource(); + Node drain = getDrain(); + + double current = (drain.getVoltage() - source.getVoltage()) + * conductance; + + drainI = -current; + sourceI = current; + + source.setResult(chargeScale, 0, currentScale, current); + drain.setResult(chargeScale, 0, currentScale, -current); + + source.setMatrix(source, + derivChargeScale, 0, derivCurrentScale, conductance); + source.setMatrix(drain, + derivChargeScale, 0, derivCurrentScale, -conductance); + drain.setMatrix(source, + derivChargeScale, 0, derivCurrentScale, -conductance); + drain.setMatrix(drain, + derivChargeScale, 0, derivCurrentScale, conductance); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SinVoltageSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SinVoltageSource.java new file mode 100644 index 0000000000..ddf0749741 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SinVoltageSource.java @@ -0,0 +1,86 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; +import com.avlsi.file.common.HierName; +/** + * Class for Sinusoidal Voltage Source + * + * @author Dan Daly + * @version $Date$ + **/ + +public class SinVoltageSource extends VoltageSource{ + +// +//Voltage Imp variables +// + /** Voltage or current offset in volts or amps. **/ + private double vo; + + /** Voltage or current RMS amplitude in volts or amps.**/ + private double va; + + /** Source frequency in Hz. **/ + private double freq; + /** Time delay before beginning the sinusoidal + * variation in seconds. Response will be 0 volts or amps + * until the delay value is reached, even with a non-zero + * DC voltage.**/ + private double td; + /** Damping factor in units of 1/seconds. **/ + private double theta; + /** Phase delay in units of degrees. **/ + private double phi; + + + /** Builds a sine voltage source device + * + * @param name HierName of the device + * @param nplus positive terminal node + * @param nminus negative terminal node + * @param vo Voltage offset in volts or amps. + * @param va Voltage RMS amplitude in volts or amps. + * @param freq Source frequency in Hz. + * @param td Time delay before beginning the sinusoidal + * variation in seconds. Response will be 0 volts or amps + * until the delay value is reached, even with a non-zero + * DC voltage. + * @param theta Damping factor in units of 1/seconds. + * @param phi Phase delay in units of degrees. + * **/ + public SinVoltageSource(final HierName name, + final Node nplus, + final Node nminus, + final double vo, + final double va, + final double freq, + final double td, + final double theta, + final double phi) { + super(name, nplus, nminus); + this.va = va; + this.vo = vo; + this.td = td; + this.freq = freq; + this.theta = theta; + this.phi = phi; + } + + public double getDrivenVoltage(double time,double timestep) { + if (time <= td) return vo+ va*Math.sin(2*Math.PI*phi/360d); + return vo+ va *Math.exp((td-time)*theta) + *Math.sin(2*Math.PI*( freq*(time -td) + phi/360d )); + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SizedModel.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SizedModel.java new file mode 100644 index 0000000000..6cb6c559bb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SizedModel.java @@ -0,0 +1,731 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + + +public class SizedModel { + public double Width; + public double Length; + + /* W,L adjusted parameters */ + public double cdsc; + public double cdscb; + public double cdscd; + public double cit; + public double nfactor; + public double xj; + public double vsat; + public double at; + public double a0; + public double ags; + public double a1; + public double a2; + public double keta; + public double nsub; + public double npeak; + public double ngate; + public double gamma1; + public double gamma2; + public double vbx; + public double vbi; + public double vbm; + public double vbsc; + public double xt; + public double phi; + public double litl; + public double k1; + public double kt1; + public double kt1l; + public double kt2; + public double k2; + public double k3; + public double k3b; + public double w0; + public double nlx; + public double dvt0; + public double dvt1; + public double dvt2; + public double dvt0w; + public double dvt1w; + public double dvt2w; + public double drout; + public double dsub; + public double vth0; + public double ua; + public double ua1; + public double ub; + public double ub1; + public double uc; + public double uc1; + public double u0; + public double ute; + public double voff; + public double vfb; + public double delta; + public double rdsw; + public double rds0; + public double prwg; + public double prwb; + public double prt; + public double eta0; + public double etab; + public double pclm; + public double pdibl1; + public double pdibl2; + public double pdiblb; + public double pscbe1; + public double pscbe2; + public double pvag; + public double wr; + public double dwg; + public double dwb; + public double b0; + public double b1; + public double alpha0; + public double alpha1; + public double beta0; + + /* CV model */ + public double elm; + public double cgsl; + public double cgdl; + public double ckappa; + public double cf; + public double clc; + public double cle; + public double vfbcv; + public double noff; + public double voffcv; + public double acde; + public double moin; + + /* Pre-calculated constants */ + public double dw; + public double dl; + public double leff; + public double weff; + + public double dwc; + public double dlc; + public double leffCV; + public double weffCV; + public double abulkCVfactor; + public double cgso; + public double cgdo; + public double cgbo; + public double tconst; + + public double u0temp; + public double vsattemp; + public double sqrtPhi; + public double phis3; + public double Xdep0; + public double sqrtXdep0; + public double theta0vb0; + public double thetaRout; + + public double cof1; + public double cof2; + public double cof3; + public double cof4; + public double cdep0; + public double vfbzb; + public double ldeb; + public double k1ox; + public double k2ox; + + private static SizedModel cachedSizedModel = null; + private static double lastWidth = Double.NaN; + private static double lastLength = Double.NaN; + private static BSim3Model lastModel = null; + + public static SizedModel newSizedModel(BSim3Model m, double W, double L) { + if (m != lastModel || W != lastWidth || L != lastLength || + cachedSizedModel == null) + { + lastModel = m; + lastWidth = W; + lastLength = L; + cachedSizedModel = new SizedModel(m, W, L); + } + + return cachedSizedModel; + } + + /** + * @throws IllegalArgumentException + **/ + public SizedModel(BSim3Model m, double W, double L) { + + double Ldrn, Wdrn, T0, T1, T2, T3, T4, T5, Inv_L, Inv_W, Inv_LW; + double Tnom, TRatio, Vtm0, ni, Eg0; + double tmp, tmp1, tmp2, tmp3; + + /*** adjust W,L ***/ + W += m.xw; + L += m.xl; + + /*** temperature, width, length dependent calculations ***/ + Tnom = m.tnom; + TRatio = m.temp / Tnom; + + Vtm0 = BSim3Model.KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + ni = 1.45e10 * (Tnom / 300.15) * Math.sqrt(Tnom / 300.15) + * Math.exp(21.5565981 - Eg0 / (2.0 * Vtm0)); + + Ldrn = L; + Wdrn = W; + Length = Ldrn; + Width = Wdrn; + + T0 = Math.pow(Ldrn, m.Lln); + T1 = Math.pow(Wdrn, m.Lwn); + tmp1 = m.Ll / T0 + m.Lw / T1 + m.Lwl / (T0 * T1); + dl = m.Lint + tmp1; + tmp2 = m.Llc / T0 + m.Lwc / T1 + m.Lwlc / (T0 * T1); + dlc = m.dlc + tmp2; + + T2 = Math.pow(Ldrn, m.Wln); + T3 = Math.pow(Wdrn, m.Wwn); + tmp1 = m.Wl / T2 + m.Ww / T3 + m.Wwl / (T2 * T3); + dw = m.Wint + tmp1; + tmp2 = m.Wlc / T2 + m.Wwc / T3 + m.Wwlc / (T2 * T3); + dwc = m.dwc + tmp2; + + leff = L - 2.0 * dl; + weff = W - 2.0 * dw; + leffCV = L - 2.0 * dlc; + weffCV = W - 2.0 * dwc; + + if (leff <= 0.0) + throw new IllegalArgumentException("Effective channel length <= 0"); + if (weff <= 0.0) + throw new IllegalArgumentException("Effective channel width <= 0"); + if (leffCV <= 0.0) + throw new IllegalArgumentException("Effective channel length for C-V <= 0"); + if (weffCV <= 0.0) + throw new IllegalArgumentException("Effective channel width for C-V <= 0"); + + if (m.binUnit == 1) + { + Inv_L = 1.0e-6 / leff; + Inv_W = 1.0e-6 / weff; + Inv_LW = 1.0e-12 / (leff * weff); + } + else + { + Inv_L = 1.0 / leff; + Inv_W = 1.0 / weff; + Inv_LW = 1.0 / (leff * weff); + } + + cdsc = m.cdsc + + m.lcdsc * Inv_L + + m.wcdsc * Inv_W + + m.pcdsc * Inv_LW; + cdscb = m.cdscb + + m.lcdscb * Inv_L + + m.wcdscb * Inv_W + + m.pcdscb * Inv_LW; + + cdscd = m.cdscd + + m.lcdscd * Inv_L + + m.wcdscd * Inv_W + + m.pcdscd * Inv_LW; + + cit = m.cit + + m.lcit * Inv_L + + m.wcit * Inv_W + + m.pcit * Inv_LW; + nfactor = m.nfactor + + m.lnfactor * Inv_L + + m.wnfactor * Inv_W + + m.pnfactor * Inv_LW; + xj = m.xj + + m.lxj * Inv_L + + m.wxj * Inv_W + + m.pxj * Inv_LW; + vsat = m.vsat + + m.lvsat * Inv_L + + m.wvsat * Inv_W + + m.pvsat * Inv_LW; + at = m.at + + m.lat * Inv_L + + m.wat * Inv_W + + m.pat * Inv_LW; + a0 = m.a0 + + m.la0 * Inv_L + + m.wa0 * Inv_W + + m.pa0 * Inv_LW; + + ags = m.ags + + m.lags * Inv_L + + m.wags * Inv_W + + m.pags * Inv_LW; + + a1 = m.a1 + + m.la1 * Inv_L + + m.wa1 * Inv_W + + m.pa1 * Inv_LW; + a2 = m.a2 + + m.la2 * Inv_L + + m.wa2 * Inv_W + + m.pa2 * Inv_LW; + keta = m.keta + + m.lketa * Inv_L + + m.wketa * Inv_W + + m.pketa * Inv_LW; + nsub = m.nsub + + m.lnsub * Inv_L + + m.wnsub * Inv_W + + m.pnsub * Inv_LW; + npeak = m.npeak + + m.lnpeak * Inv_L + + m.wnpeak * Inv_W + + m.pnpeak * Inv_LW; + ngate = m.ngate + + m.lngate * Inv_L + + m.wngate * Inv_W + + m.pngate * Inv_LW; + gamma1 = m.gamma1 + + m.lgamma1 * Inv_L + + m.wgamma1 * Inv_W + + m.pgamma1 * Inv_LW; + gamma2 = m.gamma2 + + m.lgamma2 * Inv_L + + m.wgamma2 * Inv_W + + m.pgamma2 * Inv_LW; + vbx = m.vbx + + m.lvbx * Inv_L + + m.wvbx * Inv_W + + m.pvbx * Inv_LW; + vbm = m.vbm + + m.lvbm * Inv_L + + m.wvbm * Inv_W + + m.pvbm * Inv_LW; + xt = m.xt + + m.lxt * Inv_L + + m.wxt * Inv_W + + m.pxt * Inv_LW; + vfb = m.vfb + + m.lvfb * Inv_L + + m.wvfb * Inv_W + + m.pvfb * Inv_LW; + k1 = m.k1 + + m.lk1 * Inv_L + + m.wk1 * Inv_W + + m.pk1 * Inv_LW; + kt1 = m.kt1 + + m.lkt1 * Inv_L + + m.wkt1 * Inv_W + + m.pkt1 * Inv_LW; + kt1l = m.kt1l + + m.lkt1l * Inv_L + + m.wkt1l * Inv_W + + m.pkt1l * Inv_LW; + k2 = m.k2 + + m.lk2 * Inv_L + + m.wk2 * Inv_W + + m.pk2 * Inv_LW; + kt2 = m.kt2 + + m.lkt2 * Inv_L + + m.wkt2 * Inv_W + + m.pkt2 * Inv_LW; + k3 = m.k3 + + m.lk3 * Inv_L + + m.wk3 * Inv_W + + m.pk3 * Inv_LW; + k3b = m.k3b + + m.lk3b * Inv_L + + m.wk3b * Inv_W + + m.pk3b * Inv_LW; + w0 = m.w0 + + m.lw0 * Inv_L + + m.ww0 * Inv_W + + m.pw0 * Inv_LW; + nlx = m.nlx + + m.lnlx * Inv_L + + m.wnlx * Inv_W + + m.pnlx * Inv_LW; + dvt0 = m.dvt0 + + m.ldvt0 * Inv_L + + m.wdvt0 * Inv_W + + m.pdvt0 * Inv_LW; + dvt1 = m.dvt1 + + m.ldvt1 * Inv_L + + m.wdvt1 * Inv_W + + m.pdvt1 * Inv_LW; + dvt2 = m.dvt2 + + m.ldvt2 * Inv_L + + m.wdvt2 * Inv_W + + m.pdvt2 * Inv_LW; + dvt0w = m.dvt0w + + m.ldvt0w * Inv_L + + m.wdvt0w * Inv_W + + m.pdvt0w * Inv_LW; + dvt1w = m.dvt1w + + m.ldvt1w * Inv_L + + m.wdvt1w * Inv_W + + m.pdvt1w * Inv_LW; + dvt2w = m.dvt2w + + m.ldvt2w * Inv_L + + m.wdvt2w * Inv_W + + m.pdvt2w * Inv_LW; + drout = m.drout + + m.ldrout * Inv_L + + m.wdrout * Inv_W + + m.pdrout * Inv_LW; + dsub = m.dsub + + m.ldsub * Inv_L + + m.wdsub * Inv_W + + m.pdsub * Inv_LW; + vth0 = m.vth0 + + m.lvth0 * Inv_L + + m.wvth0 * Inv_W + + m.pvth0 * Inv_LW; + ua = m.ua + + m.lua * Inv_L + + m.wua * Inv_W + + m.pua * Inv_LW; + ua1 = m.ua1 + + m.lua1 * Inv_L + + m.wua1 * Inv_W + + m.pua1 * Inv_LW; + ub = m.ub + + m.lub * Inv_L + + m.wub * Inv_W + + m.pub * Inv_LW; + ub1 = m.ub1 + + m.lub1 * Inv_L + + m.wub1 * Inv_W + + m.pub1 * Inv_LW; + uc = m.uc + + m.luc * Inv_L + + m.wuc * Inv_W + + m.puc * Inv_LW; + uc1 = m.uc1 + + m.luc1 * Inv_L + + m.wuc1 * Inv_W + + m.puc1 * Inv_LW; + u0 = m.u0 + + m.lu0 * Inv_L + + m.wu0 * Inv_W + + m.pu0 * Inv_LW; + ute = m.ute + + m.lute * Inv_L + + m.wute * Inv_W + + m.pute * Inv_LW; + voff = m.voff + + m.lvoff * Inv_L + + m.wvoff * Inv_W + + m.pvoff * Inv_LW; + delta = m.delta + + m.ldelta * Inv_L + + m.wdelta * Inv_W + + m.pdelta * Inv_LW; + rdsw = m.rdsw + + m.lrdsw * Inv_L + + m.wrdsw * Inv_W + + m.prdsw * Inv_LW; + prwg = m.prwg + + m.lprwg * Inv_L + + m.wprwg * Inv_W + + m.pprwg * Inv_LW; + prwb = m.prwb + + m.lprwb * Inv_L + + m.wprwb * Inv_W + + m.pprwb * Inv_LW; + prt = m.prt + + m.lprt * Inv_L + + m.wprt * Inv_W + + m.pprt * Inv_LW; + eta0 = m.eta0 + + m.leta0 * Inv_L + + m.weta0 * Inv_W + + m.peta0 * Inv_LW; + etab = m.etab + + m.letab * Inv_L + + m.wetab * Inv_W + + m.petab * Inv_LW; + pclm = m.pclm + + m.lpclm * Inv_L + + m.wpclm * Inv_W + + m.ppclm * Inv_LW; + pdibl1 = m.pdibl1 + + m.lpdibl1 * Inv_L + + m.wpdibl1 * Inv_W + + m.ppdibl1 * Inv_LW; + pdibl2 = m.pdibl2 + + m.lpdibl2 * Inv_L + + m.wpdibl2 * Inv_W + + m.ppdibl2 * Inv_LW; + pdiblb = m.pdiblb + + m.lpdiblb * Inv_L + + m.wpdiblb * Inv_W + + m.ppdiblb * Inv_LW; + pscbe1 = m.pscbe1 + + m.lpscbe1 * Inv_L + + m.wpscbe1 * Inv_W + + m.ppscbe1 * Inv_LW; + pscbe2 = m.pscbe2 + + m.lpscbe2 * Inv_L + + m.wpscbe2 * Inv_W + + m.ppscbe2 * Inv_LW; + pvag = m.pvag + + m.lpvag * Inv_L + + m.wpvag * Inv_W + + m.ppvag * Inv_LW; + wr = m.wr + + m.lwr * Inv_L + + m.wwr * Inv_W + + m.pwr * Inv_LW; + dwg = m.dwg + + m.ldwg * Inv_L + + m.wdwg * Inv_W + + m.pdwg * Inv_LW; + dwb = m.dwb + + m.ldwb * Inv_L + + m.wdwb * Inv_W + + m.pdwb * Inv_LW; + b0 = m.b0 + + m.lb0 * Inv_L + + m.wb0 * Inv_W + + m.pb0 * Inv_LW; + b1 = m.b1 + + m.lb1 * Inv_L + + m.wb1 * Inv_W + + m.pb1 * Inv_LW; + alpha0 = m.alpha0 + + m.lalpha0 * Inv_L + + m.walpha0 * Inv_W + + m.palpha0 * Inv_LW; + alpha1 = m.alpha1 + + m.lalpha1 * Inv_L + + m.walpha1 * Inv_W + + m.palpha1 * Inv_LW; + beta0 = m.beta0 + + m.lbeta0 * Inv_L + + m.wbeta0 * Inv_W + + m.pbeta0 * Inv_LW; + /* CV model */ + elm = m.elm + + m.lelm * Inv_L + + m.welm * Inv_W + + m.pelm * Inv_LW; + cgsl = m.cgsl + + m.lcgsl * Inv_L + + m.wcgsl * Inv_W + + m.pcgsl * Inv_LW; + cgdl = m.cgdl + + m.lcgdl * Inv_L + + m.wcgdl * Inv_W + + m.pcgdl * Inv_LW; + ckappa = m.ckappa + + m.lckappa * Inv_L + + m.wckappa * Inv_W + + m.pckappa * Inv_LW; + cf = m.cf + + m.lcf * Inv_L + + m.wcf * Inv_W + + m.pcf * Inv_LW; + clc = m.clc + + m.lclc * Inv_L + + m.wclc * Inv_W + + m.pclc * Inv_LW; + cle = m.cle + + m.lcle * Inv_L + + m.wcle * Inv_W + + m.pcle * Inv_LW; + vfbcv = m.vfbcv + + m.lvfbcv * Inv_L + + m.wvfbcv * Inv_W + + m.pvfbcv * Inv_LW; + acde = m.acde + + m.lacde * Inv_L + + m.wacde * Inv_W + + m.pacde * Inv_LW; + moin = m.moin + + m.lmoin * Inv_L + + m.wmoin * Inv_W + + m.pmoin * Inv_LW; + noff = m.noff + + m.lnoff * Inv_L + + m.wnoff * Inv_W + + m.pnoff * Inv_LW; + voffcv = m.voffcv + + m.lvoffcv * Inv_L + + m.wvoffcv * Inv_W + + m.pvoffcv * Inv_LW; + + abulkCVfactor = 1.0 + Math.pow((clc / leffCV), cle); + + T0 = (TRatio - 1.0); + ua = ua + ua1 * T0; + ub = ub + ub1 * T0; + uc = uc + uc1 * T0; + if (u0 > 1.0) u0 = u0 / 1.0e4; + + u0temp = u0 * Math.pow(TRatio, ute); + vsattemp = vsat - at * T0; + rds0 = (rdsw + prt * T0) / Math.pow(weff * 1E6, wr); + + cgdo = (m.cgdo + cf) * weffCV; + cgso = (m.cgso + cf) * weffCV; + cgbo = m.cgbo * leffCV; + + T0 = leffCV * leffCV; + tconst = u0temp * elm / (m.cox * weffCV * leffCV * T0); + + if (!m.given(m.npeak) && m.given(m.gamma1)) + { + T0 = gamma1 * m.cox; + npeak = 3.021E22 * T0 * T0; + } + + phi = 2.0 * Vtm0 * Math.log(npeak / ni); + + sqrtPhi = Math.sqrt(phi); + phis3 = sqrtPhi * phi; + + Xdep0 = Math.sqrt(2.0 * BSim3Model.EPSSI / (BSim3Model.Charge_q * npeak * 1.0e6)) * sqrtPhi; + sqrtXdep0 = Math.sqrt(Xdep0); + litl = Math.sqrt(3.0 * xj * m.tox); + vbi = Vtm0 * Math.log(1.0e20 * npeak / (ni * ni)); + cdep0 = Math.sqrt(BSim3Model.Charge_q * BSim3Model.EPSSI * npeak * 1.0e6 / 2.0 / phi); + + ldeb = Math.sqrt(BSim3Model.EPSSI * Vtm0 / (BSim3Model.Charge_q * npeak * 1.0e6)) / 3.0; + acde *= Math.pow((npeak / 2.0e16), -0.25); + + if (m.given(m.k1) || m.given(m.k2)) + { + if (!m.given(m.k1)) + { + System.out.println("Warning: k1 should be specified with k2."); + k1 = 0.53; + } + if (!m.given(m.k2)) + { + System.out.println("Warning: k2 should be specified with k1."); + k2 = -0.0186; + } + if (m.given(m.nsub)) + System.out.println("Warning: nsub is ignored because k1 or k2 is given."); + if (m.given(m.xt)) + System.out.println("Warning: xt is ignored because k1 or k2 is given."); + if (m.given(m.vbx)) + System.out.println("Warning: vbx is ignored because k1 or k2 is given."); + if (m.given(m.gamma1)) + System.out.println("Warning: gamma1 is ignored because k1 or k2 is given."); + if (m.given(m.gamma2)) + System.out.println("Warning: gamma2 is ignored because k1 or k2 is given."); + } + else + { + if (!m.given(m.vbx)) + vbx = phi - 7.7348e-4 * npeak * xt * xt; + if (vbx > 0.0) + vbx = -vbx; + if (vbm > 0.0) + vbm = -vbm; + + if (!m.given(m.gamma1)) + gamma1 = 5.753e-12 * Math.sqrt(npeak) / m.cox; + if (!m.given(m.gamma2)) + gamma2 = 5.753e-12 * Math.sqrt(nsub) / m.cox; + + T0 = gamma1 - gamma2; + T1 = Math.sqrt(phi - vbx) - sqrtPhi; + T2 = Math.sqrt(phi * (phi - vbm)) - phi; + k2 = T0 * T1 / (2.0 * T2 + vbm); + k1 = gamma2 - 2.0 * k2 * Math.sqrt(phi - vbm); + } + + if (k2 < 0.0) + { + T0 = 0.5 * k1 / k2; + vbsc = 0.9 * (phi - T0 * T0); + if (vbsc > -3.0) + vbsc = -3.0; + else if (vbsc < -30.0) + vbsc = -30.0; + } + else + vbsc = -30.0; + + if (vbsc > vbm) + vbsc = vbm; + + if (!m.given(m.vfb)) + { + if (m.given(m.vth0)) + vfb = m.type * vth0 - phi - k1 * sqrtPhi; + else + vfb = -1.0; + } + + if (!m.given(m.vth0)) + vth0 = m.type * (vfb + phi + k1 * sqrtPhi); + + k1ox = k1 * m.tox / m.toxm; + k2ox = k2 * m.tox / m.toxm; + + T1 = Math.sqrt(BSim3Model.EPSSI / BSim3Model.EPSOX * m.tox * Xdep0); + T0 = Math.exp(-0.5 * dsub * leff / T1); + theta0vb0 = (T0 + 2.0 * T0 * T0); + + T0 = Math.exp(-0.5 * drout * leff / T1); + T2 = (T0 + 2.0 * T0 * T0); + thetaRout = pdibl1 * T2 + pdibl2; + + tmp = Math.sqrt(Xdep0); + tmp1 = vbi - phi; + tmp2 = m.factor1 * tmp; + + T0 = -0.5 * dvt1w * weff * leff / tmp2; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = BSim3Model.MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + } + T0 = dvt0w * T2; + T2 = T0 * tmp1; + + T0 = -0.5 * dvt1 * leff / tmp2; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + T3 = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = BSim3Model.MIN_EXP; + T3 = T1 * (1.0 + 2.0 * T1); + } + T3 = dvt0 * T3 * tmp1; + + T4 = m.tox * phi / (weff + w0); + + T0 = Math.sqrt(1.0 + nlx / leff); + T5 = k1ox * (T0 - 1.0) * sqrtPhi + (kt1 + kt1l / leff) * (TRatio - 1.0); + + tmp3 = m.type * vth0 - T2 - T3 + k3 * T4 + T5; + vfbzb = tmp3 - phi - k1 * sqrtPhi; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SourceHandler.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SourceHandler.java new file mode 100644 index 0000000000..cceb0fac5d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/SourceHandler.java @@ -0,0 +1,236 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; +import java.util.HashMap; +import com.avlsi.file.common.HierName; + +/** + * Class for building custom sources + * + * @author Dan Daly + * @version $Date$ + **/ + +public class SourceHandler { + + /** + * Constructor. + **/ + public SourceHandler() { } + + public VoltageSource buildSource(HierName name, + Node nplus, Node nminus, String[] args) + throws SourceHandlerException { return null;} + + public static double[] parseDoubles(String[] args) + throws NumberFormatException { + double[] dargs = new double[args.length]; + for (int loop=0;loop 1e-6; + gateVolt += 10*step) + { + gate.setVoltage(gateVolt); + + for (double drainVolt = low; Math.abs(drainVolt - high) > 1e-6; + drainVolt += step) + { + drain.setVoltage(drainVolt); + + source.initialize(); + drain.initialize(); + gate.initialize(); + bulk.initialize(); + + trans.evalVoltage(0, 1, 0, 0,0); // Only track Current +//GGG We should do number compares here instead of printing to file + + if (output) + System.out.println(drainVolt + " " + source.getResult()); + } + + if (output) + System.out.println(); + } + } + + /** + * Test a simple capacitor charging circuit + * @param output true if test should print output + **/ + public void testCharging(boolean output) throws Exception { + final double timestep = 1e-10; + final double conductance = 1e-3; + final double capacitance = 1e-9; + final double endTime = 5*(capacitance / conductance); + + Circuit circuit = new Circuit(timestep); + GroundNode ground = new GroundNode(); + Node vdd = new Node(high); + Node x = new Node(); + + circuit.addDevice(new Capacitor(vdd, ground, 1)); + circuit.addDevice(new Capacitor(ground, x, capacitance)); + circuit.addDevice(new Resistor(vdd, x, conductance)); + + circuit.initializeSimulation(); + vdd.setVoltage(high); + + double voltage = x.getVoltage(); + double time = circuit.getTime(); + if (output) + System.out.println(time + " " + voltage); + + while (time < endTime) { + circuit.jump(1e-8); + + time = circuit.getTime(); + voltage = x.getVoltage(); +//GGG Compare values to expected values... + + if (output) + System.out.println(time + " " + voltage); + } + } + + /** + * Test a simple transistor oscillation ring + * @param output true if test should print output + **/ + public void testOscillatorRing(boolean output) throws Exception { + final double timestep = 1e-12; + final double endTime = 1e-9; + final int ringSize = 5; // Must be odd + + Circuit circuit = new Circuit(timestep); + GroundNode ground = new GroundNode(); + Node vdd = new Node(high); + Node firstNode = new Node(); // Save to close loop + Node linkNode = firstNode; // Update as we create new nodes + + for (int i = 0; i < ringSize; i++) { + Node sourceDrain; + if (i == ringSize - 1) + sourceDrain = firstNode; + else + sourceDrain = new Node(); + + circuit.addDevice(new Transistor(sourceDrain, ground, + linkNode, ground, + DeviceTypes.N_TYPE, + nWidth, nLength)); + circuit.addDevice(new Transistor(sourceDrain, vdd, + linkNode, vdd, + DeviceTypes.P_TYPE, + pWidth, pLength)); + + linkNode = sourceDrain; // Old source/drain feed into new linkNode + } + + // Cheat on the power supply + IndependantVariable x = new IndependantVariable(high); + DivOp exp = new DivOp(new MinusOp(new Literal(high), x), + new Literal(1e-10)); + HashMap voltageMap = new HashMap(); + voltageMap.put(vdd, x); + + circuit.addDevice(new CurrentSource(vdd, exp, voltageMap)); + + double time = circuit.getTime(); + double voltage = firstNode.getVoltage(); + if (output) + System.out.println(time + " " + voltage); + + do { + circuit.jump(1e-11); + + time = circuit.getTime(); + voltage = firstNode.getVoltage(); +//GGG Again, we should test these values, not print them to file. + + if (output) + System.out.println(time + " " + voltage); + } while (time < endTime && (low-1) <= voltage && voltage <= (high+1)); + } + + /** + * Run all circuit test cases + * @param args Command line arguments + **/ + public static void main (String[] args) { + AbstractTestCase.testOne(new TestCircuit()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceElement.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceElement.java new file mode 100644 index 0000000000..ccf6ab84db --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceElement.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +/** + * Class for tracing different parameters within the nodes + * + * @author Dan Daly + * @version $Date$ + **/ + +public class TraceElement { + + private int type; + private Object o; + /** + * Constructor for TraceElement + **/ + public TraceElement(final int type, final Object o) { + this.type = type; + this.o = o; + } + + public double getData() { + if ((type == Node.VOLTAGE) && + (o instanceof Node)) return ((Node) o).getVoltage(); + + if (!(o instanceof AbstractDevice)) return -1; + + return ((AbstractDevice) o).getCurrent(type); + } + + public Object getObject() { return o; } + + public int getType() { return type; } + + public String getName() { + if (type == Node.VOLTAGE) { + return ((Node) o).getName().toString(); + } else { + AbstractDevice ad = (AbstractDevice) o; + return ad.getName() + "_" + AbstractDevice.names[type]; + } + } + + public String printElement() { + String sname = "Unknown object type"; + String stype = "Unknown type"; + if ( getObject() instanceof Node) { + sname = ((Node) o).getName().toString(); + stype = "V";//Node.names[getType()]; + return sname; + } else if (getObject() instanceof AbstractDevice) { + sname = ((AbstractDevice) o).getName().toString(); + stype = AbstractDevice.names[getType()]; + return sname+"_"+stype; + } + return sname; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFile.java new file mode 100644 index 0000000000..57d1c25adb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFile.java @@ -0,0 +1,232 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import java.io.BufferedOutputStream; +import java.io.DataOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.File; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.util.Iterator; +import com.avlsi.file.common.HierName; +import com.avlsi.util.debug.Debug; +/** + * Class for Trace Files in Jaspice + * + * @author Dan Daly + * @version $Date$ + **/ + +public class TraceFile { + + private static final int ORDER_ORIGINAL = 0; + private static final int ORDER_REORDERED= 1; + private static final int ORDER_CHANGING = 2; + private static final int HEADER_SIZE = 3; + private static String[] suffixes = { ".names", ".trace" }; + private File namesfile,tracefile; + private boolean namesOpen = false; + private DataOutputStream dos; + private BufferedWriter nameswriter; + private int order; + private int timestamp; + private int num_nodes; + + private boolean defaultEndian = true;//Use Sun's Ordering + /** + * Constructor. + **/ + public TraceFile(String path) { + /** Check to make sure we have the base name only **/ + for (int loop=0;loop>8); + } + } + } catch (IOException e) { + throw new TraceFileException("Error writing trace"+ + " java.io.IOException: "+ + e.getMessage(), e); + } + } + + public void writeFloat(float val) + throws TraceFileException { + //Switch Bits + if (defaultEndian) { + try { + dos.writeFloat(val); + } catch (IOException e ) { + throw new TraceFileException("Error writing trace"+ + " java.io.IOException: "+ + e.getMessage(), e); + } + } else { + int ival = Float.floatToIntBits(val); + writeInt(ival); + } + } + + public void closeOutNodes() + throws TraceFileException{ + writeHeader(); + closeNamesFile(); + } + + private void closeNamesFile() + throws TraceFileException { + if (namesOpen) { + try { + nameswriter.close(); + namesOpen = false; + } catch (IOException e) { + throw new TraceFileException("Error closing names file"+ + " java.io.IOException: "+ + e.getMessage(), e); + } + } + } + + public void close() + throws TraceFileException { + + try { + dos.close(); + } catch (IOException e) { + throw new TraceFileException("Error closing trace"+ + " java.io.IOException: "+ + e.getMessage(), e); + } finally { + closeNamesFile(); + } + } + + public class TraceFileException extends Exception { + public TraceFileException(String msg) { + super("[Trace File]: "+msg); + } + public TraceFileException(String msg, Exception cause) { + super("[Trace File]: "+msg, cause); + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFileException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFileException.java new file mode 100644 index 0000000000..abd7562ef0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/TraceFileException.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +/** + * Class for Exceptions in Trace Files + * + * @author Dan Daly + * @version $Date$ + **/ + +public class TraceFileException extends Exception { + public TraceFileException(String msg) { + super(msg); + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Transistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Transistor.java new file mode 100644 index 0000000000..f1d033bcd5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/Transistor.java @@ -0,0 +1,2285 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; + +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.util.debug.Debug; + +/** + * Class to represent a transistor in a circuit + * + * @author JTed Vessenes + * @version $Name: $ $Date$ + **/ +public final class Transistor extends AbstractDevice + implements java.io.Serializable{ + + /** type of transistor (N_TYPE or P_TYPE). **/ + private final int type; + + /** Width of transistor in meters. **/ + private final double width; + + /** Length of transistor in meters. **/ + private final double length; + + /** + * BSIM3 Device model data. + * This value will be null if no model was found. + * If so, some class methods such as evaluate() will + * generate exceptions if called. + **/ + private final BSim3Model m; + + /** Device currents **/ + + /** Drain node current **/ + private double drainI; + /** Gate node current **/ + private double gateI; + /** Source node current **/ + private double sourceI; + /** Bulk node current **/ + private double bulkI; + +// public static native void loadModel(String filename, double temperature); + +// public native int findModel(int type, double width, double height); + + public native void nativeEval(int modelHandle, int type, + double Vsource, double Vdrain, + double Vgate, double Vbulk, + double width, double length, + double gmin, + double[] charge, + double[] current, + double[] charge_partials, + double[] current_partials); + /** + * Class constructor. Canonicalizes the source and drain node names + * by ensuring that source is lexicographically less than drain. + * @param name HierName name of the device + * @param type type of transistor, N_TYPE or P_TYPE. + * @param source name of source node + * @param drain name of drain node + * @param gate name of gate node + * @param bulk name of bulk node + * @param width of gate in meters + * @param length of gate in meters + * @throws IllegalArgumentException + **/ + + public Transistor(final HierName name, + final Node source, + final Node drain, + final Node gate, + final Node bulk, + final int type, + final double width, + final double length) { + super(new Node[] { source, drain, gate, bulk }); + + if (type != DeviceTypes.N_TYPE && type != DeviceTypes.P_TYPE) + throw new IllegalArgumentException("Bad fet type: " + type); + + this.type = type; + this.width = width; + this.length = length; + this.name = name; + + m = BSim3Model.findModel(type, width, length); + } + + /** @throws IllegalArgumentException **/ + public Transistor(final Node source, + final Node drain, + final Node gate, + final Node bulk, + final int type, + final double width, + final double length) { + this(null, source, drain, gate, bulk, type, width, length); + } + + /** + * Get the type of the transistor, either N_TYPE, or P_TYPE. + * @return the type of the transistor + **/ + public int getType() { + return type; + } + + /** + * Get source node. + * @return name of source node + **/ + public Node getSource() { + return nodes[0]; + } + + /** + * Get drain node. + * @return name of drain node + **/ + public Node getDrain() { + return nodes[1]; + } + + /** + * Get gate node. + * @return name of gate node + **/ + public Node getGate() { + return nodes[2]; + } + + /** + * Get bulk node. + * @return name of bulk node + **/ + public Node getBulk() { + return nodes[3]; + } + + /** + * Get width of transistor + * @return width of transistor in meters + **/ + public double getWidth() { + return width; + } + + /** + * Get length of transistor + * @return length of transistor in meters + **/ + public double getLength() { + return length; + } + + /** returns the device current **/ + public double getCurrent(int type) { + switch (type) { + case AbstractDevice.I1: return drainI; + case AbstractDevice.I2: return gateI; + case AbstractDevice.I3: return sourceI; + case AbstractDevice.I4: return bulkI; + } + return -1; + } + + public String getCode() { return "M";} + + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device and then informs its nodes of these values. + * @param chargeScale scalar for charge calculation + * @param currentScale scalar for current calculation + * @param derivChargeScale scalar for charge derivative calculation + * @param derivCurrentScale scalar for current derivative calculation + **/ + public void evalVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) { + if (BSim3Model.isNativeLoaded()) { + evalNativeVoltage(chargeScale,currentScale,derivChargeScale, + derivCurrentScale,time); + } + if (!BSim3Model.isNativeLoaded() || BSim3Model.both) { + evalJavaVoltage(chargeScale,currentScale,derivChargeScale, + derivCurrentScale,time); + } + } + + // + //Data values are pooled, so these doubles[] don't need to be created + //for every run, global for 'both' mode + // + private double[] Q = new double[4]; + private double[] I = new double[4]; + private double[] dQ= new double[16]; + private double[] dI= new double[16]; + private int nD=1,nS=0; + + /** Evaluates the voltage natively, using the BSIM3 model written + * for aspice. + **/ + public void evalNativeVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) { + + Node source = getSource(); + Node drain = getDrain(); + Node gate = getGate(); + Node bulk = getBulk(); + double Vs = source.getVoltage(); + double Vd = drain.getVoltage(); + int ntype = m.type; + nS = 0; + nD = 1; + //Native will switch source and drain to make Vds always positive +// if (ntype*Vd < ntype*Vs) { +// nD = 0; +// nS= 1; +// } + + nativeEval(m.getHandle(), ntype, + Vs, Vd, + gate.getVoltage(), bulk.getVoltage(), + width, length, 0, Q, I, dQ, dI); + + if (BSim3Model.both) return; //For both mode, just observe + sourceI = I[nS];//m.type*Ids; + drainI = I[nD];//-m.type*(Ids+Isub); + gateI = I[2];//0; + bulkI = I[3]; //m.type*Isub; + source.setResult(chargeScale, Q[0]/*m.type*qsrc*/, + currentScale,sourceI); + drain.setResult(chargeScale, Q[1]/*m.type*qdrn*/, + currentScale, drainI/*-m.type*(Ids+Isub*/); + gate.setResult(chargeScale, Q[2]/*m.type*qgate*/, + currentScale, gateI/*0*/); + bulk.setResult(chargeScale, Q[3]/*m.type*qbulk*/, + currentScale,bulkI/*m.type*Isub*/); + + source.setMatrix(source, derivChargeScale, dQ[0], //gcssb, + derivCurrentScale, dI[4*nS+nS] //-Gds - Gm - Gmb + ); + source.setMatrix(drain, derivChargeScale, dQ[4],// gcdsb, + derivCurrentScale, dI[4*nD+nS]//Gds+Gm+Gmb+Gbd+Gbg+Gbb + ); + source.setMatrix(gate, derivChargeScale, dQ[8], //gcgsb, + derivCurrentScale, dI[8] //0 + ); + source.setMatrix(bulk, derivChargeScale, dQ[12], //gcbsb, + derivCurrentScale, dI[12+nS] //-Gbd - Gbg - Gbb + ); + drain.setMatrix(source, derivChargeScale, dQ[1], //gcsdb, + derivCurrentScale, dI[4*nS+nD] //Gds + ); + drain.setMatrix(drain, derivChargeScale, dQ[5], //gcddb, + derivCurrentScale, dI[4*nD+nD] //-Gds - Gbd + ); + drain.setMatrix(gate, derivChargeScale, dQ[9], //gcgdb, + derivCurrentScale, dI[9]// = 0 //0 + ); + drain.setMatrix(bulk, derivChargeScale, dQ[13], //gcbdb, + derivCurrentScale, dI[12+nD] //Gbd + ); + gate.setMatrix(source, derivChargeScale, dQ[2], //gcsgb, + derivCurrentScale, dI[4*nS+2] //Gm + ); + gate.setMatrix(drain, derivChargeScale, dQ[6], //gcdgb, + derivCurrentScale, dI[4*nD+2] //-Gm - Gbg + ); + gate.setMatrix(gate, derivChargeScale, dQ[10], //gcggb, + derivCurrentScale, dI[10] //0 + ); + gate.setMatrix(bulk, derivChargeScale, dQ[14], //gcbgb, + derivCurrentScale, dI[14] //Gbg + ); + bulk.setMatrix(source, derivChargeScale, dQ[3], //-gcssb - gcsdb - gcsgb, + derivCurrentScale, dI[4*nS+3] //Gmb + ); + bulk.setMatrix(drain, derivChargeScale, dQ[7], //-gcdsb - gcddb - gcdgb, + derivCurrentScale, dI[4*nD+3] //-Gmb - Gbb + ); + bulk.setMatrix(gate, derivChargeScale, dQ[11], //-gcgsb - gcgdb - gcggb, + derivCurrentScale, dI[11] //0 + ); + bulk.setMatrix(bulk, derivChargeScale, dQ[15], //-gcbsb - gcbdb - gcbgb, + derivCurrentScale, dI[15] //Gbb + ); + } + + public void evalJavaVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) { + double qgd, qgs, qgb, VgstNVt, ExpVgst; + double Vfbeff, dVfbeff_dVg, dVfbeff_dVb, V3, V4; + double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb, gcgdb, gcggb, gcgsb, gcsdb; + double gcsgb, gcssb; + double qgate, qbulk, qdrn, qsrc, qinoi; + double Vds, Vgs, Vbs; + double Vgs_eff, Vfb; + double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd; + double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Vtm; + double n, dn_dVb, dn_dVd, voffcv, noff, dnoff_dVd, dnoff_dVb; + double ExpArg, V0, CoxWLcen, QovCox, LINK; + double DeltaPhi, dDeltaPhi_dVg, dDeltaPhi_dVd, dDeltaPhi_dVb; + double Cox, Tox, Tcen, dTcen_dVg, dTcen_dVd, dTcen_dVb; + double Ccen, Coxeff, dCoxeff_dVg, dCoxeff_dVd, dCoxeff_dVb; + double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb; + double ueff, dueff_dVg, dueff_dVd, dueff_dVb; + double Esat, Vdsat; + double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb; + double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, Vasat, dAlphaz_dVg, dAlphaz_dVb; + double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, dVa_dVd, dVa_dVg, dVa_dVb; + double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; + double Arg1, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; + double T0, dT0_dVg, dT0_dVd, dT0_dVb; + double T1, dT1_dVg, dT1_dVd, dT1_dVb; + double T2, dT2_dVg, dT2_dVd, dT2_dVb; + double T3, dT3_dVg, dT3_dVd, dT3_dVb; + double T4, T5, T6, T7, T8, T9, T10, T11, T12; + double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; + double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb; + double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb; + double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb, Delt_vth, dDelt_vth_dVb; + double Theta0, dTheta0_dVb; + double TempRatio, tmp1, tmp2, tmp3, tmp4; + double DIBL_Sft, dDIBL_Sft_dVd, Lambda, dLambda_dVg; + double a1; + + double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb; + double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; + double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; + double diffVds, dAbulk_dVg; + double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb; + double gche, dgche_dVg, dgche_dVd, dgche_dVb; + double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb; + double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb; + double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb; + double Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb; + double Ids, Gm, Gds, Gmb; + double Isub, Gbd, Gbg, Gbb; + double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb; + double CoxWovL; + double Rds, dRds_dVg, dRds_dVb, WVCox, WVCoxRds; + double Vgst2Vtm, VdsatCV, dVdsatCV_dVg, dVdsatCV_dVb; + double Leff, Weff, dWeff_dVg, dWeff_dVb; + double AbulkCV, dAbulkCV_dVb; + double qgdo, qgso, cgdo, cgso; + + double Cgg, Cgd, Cgb; + double Csg, Csd, Csb, Cbg, Cbd, Cbb; + double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0; + double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; + + double thetavth; + + double cggb, cgsb, cgdb, cdgb, cdsb, cddb, cbgb, cbsb, cbdb; + double qinv; + double vgd, vgs, vgb; + + final SizedModel s = SizedModel.newSizedModel(m, width, length); + + Node source = getSource(); + Node drain = getDrain(); + Node gate = getGate(); + Node bulk = getBulk(); + + if (source.getVoltage() * m.type > + drain.getVoltage() * m.type) + { + Node temp = source; + source = drain; + drain = temp; + } + + /* convert voltages to NMOS conventions */ + double Vs = m.type * source.getVoltage(); + double Vd = m.type * drain.getVoltage(); + double Vg = m.type * gate.getVoltage(); + double Vb = m.type * bulk.getVoltage(); + + /* unadulterated voltage differences */ + vgd = Vg - Vd; + vgs = Vg - Vs; + vgb = Vg - Vb; + + Vds = Vd - Vs; + Vgs = Vg - Vs; // Note that this equals vgs + Vbs = Vb - Vs; + + /* compute Vbseff */ + T0 = Vbs - s.vbsc - 0.001; + T1 = Math.sqrt(T0 * T0 - 0.004 * s.vbsc); + Vbseff = s.vbsc + 0.5 * (T0 + T1); + dVbseff_dVb = 0.5 * (1.0 + T0 / T1); + if (Vbseff < Vbs) + Vbseff = Vbs; + + if (Vbseff > 0.0) + { + T0 = s.phi / (s.phi + Vbseff); + Phis = s.phi * T0; + dPhis_dVb = -T0 * T0; + sqrtPhis = s.phis3 / (s.phi + 0.5 * Vbseff); + dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / s.phis3; + } + else + { + Phis = s.phi - Vbseff; + dPhis_dVb = -1.0; + sqrtPhis = Math.sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + } + + /* compute Xdep */ + Xdep = s.Xdep0 * sqrtPhis / s.sqrtPhi; + dXdep_dVb = (s.Xdep0 / s.sqrtPhi) * dsqrtPhis_dVb; + + /* grab Leff and Vtm */ + Leff = s.leff; + Vtm = m.vtm; + + /* Vth Calculation */ + T3 = Math.sqrt(Xdep); + V0 = s.vbi - s.phi; + + T0 = s.dvt2 * Vbseff; + if (T0 >= - 0.5) + { + T1 = 1.0 + T0; + T2 = s.dvt2; + } + else + { + /* Added to avoid any discontinuity problems caused by dvt2 */ + T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = s.dvt2 * T4 * T4; + } + lt1 = m.factor1 * T3 * T1; + dlt1_dVb = m.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = s.dvt2w * Vbseff; + if (T0 >= - 0.5) + { + T1 = 1.0 + T0; + T2 = s.dvt2w; + } + else + { + /* Added to avoid any discontinuity problems caused by dvt2w */ + T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = s.dvt2w * T4 * T4; + } + ltw = m.factor1 * T3 * T1; + dltw_dVb = m.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = -0.5 * s.dvt1 * Leff / lt1; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + Theta0 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { + T1 = BSim3Model.MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + + thetavth = s.dvt0 * Theta0; + Delt_vth = thetavth * V0; + dDelt_vth_dVb = s.dvt0 * dTheta0_dVb * V0; + + T0 = -0.5 * s.dvt1w * s.weff * Leff / ltw; + if (T0 > -BSim3Model.EXP_THRESHOLD) + { + T1 = Math.exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { + T1 = BSim3Model.MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + + T0 = s.dvt0w * T2; + T2 = T0 * V0; + dT2_dVb = s.dvt0w * dT2_dVb * V0; + + TempRatio = m.temp / m.tnom - 1.0; + T0 = Math.sqrt(1.0 + s.nlx / Leff); + T1 = s.k1ox * (T0 - 1.0) * s.sqrtPhi + + (s.kt1 + s.kt1l / Leff + s.kt2 * Vbseff) * TempRatio; + tmp2 = m.tox * s.phi / (s.weff + s.w0); + + T3 = s.eta0 + s.etab * Vbseff; + if (T3 < 1.0e-4) + { + /* avoid discontinuity problems caused by etab */ + T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9; + } + else + T4 = 1.0; + dDIBL_Sft_dVd = T3 * s.theta0vb0; + DIBL_Sft = dDIBL_Sft_dVd * Vds; + + Vth = m.type * s.vth0 - s.k1 * s.sqrtPhi + s.k1ox * sqrtPhis + - s.k2ox * Vbseff - Delt_vth - T2 + + (s.k3 + s.k3b * Vbseff) * tmp2 + T1 - DIBL_Sft; + + dVth_dVb = s.k1ox * dsqrtPhis_dVb - s.k2ox + - dDelt_vth_dVb - dT2_dVb + s.k3b * tmp2 + - s.etab * Vds * s.theta0vb0 * T4 + s.kt2 * TempRatio; + dVth_dVd = -dDIBL_Sft_dVd; + + /* Calculate n */ + tmp2 = s.nfactor * BSim3Model.EPSSI / Xdep; + tmp3 = s.cdsc + s.cdscb * Vbseff + s.cdscd * Vds; + tmp4 = (tmp2 + tmp3 * Theta0 + s.cit) / m.cox; + if (tmp4 >= -0.5) + { + n = 1.0 + tmp4; + dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + s.cdscb * Theta0) / m.cox; + dn_dVd = s.cdscd * Theta0 / m.cox; + } + else + { + /* avoid discontinuity problems caused by tmp4 */ + T0 = 1.0 / (3.0 + 8.0 * tmp4); + n = (1.0 + 3.0 * tmp4) * T0; + T0 *= T0; + dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + + s.cdscb * Theta0) / m.cox * T0; + dn_dVd = s.cdscd * Theta0 / m.cox * T0; + } + + /* Poly Gate Si Depletion Effect */ + T0 = s.vfb + s.phi; + if ((s.ngate > 1.e18) && (s.ngate < 1.e25) && (Vgs > T0)) + { + /* added to avoid the problem caused by ngate */ + T1 = 1.0e6 * BSim3Model.Charge_q * BSim3Model.EPSSI * s.ngate / (m.cox * m.cox); + T4 = Math.sqrt(1.0 + 2.0 * (Vgs - T0) / T1); + T2 = T1 * (T4 - 1.0); + T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */ + T7 = 1.12 - T3 - 0.05; + T6 = Math.sqrt(T7 * T7 + 0.224); + T5 = 1.12 - 0.5 * (T7 + T6); + Vgs_eff = Vgs - T5; + dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); + } + else + { + Vgs_eff = Vgs; + dVgs_eff_dVg = 1.0; + } + Vgst = Vgs_eff - Vth; + + /* Effective Vgst (Vgsteff) Calculation */ + T10 = 2.0 * n * Vtm; + VgstNVt = Vgst / T10; + ExpArg = (2.0 * s.voff - Vgst) / T10; + + /* MCJ: Very small Vgst */ + if (VgstNVt > BSim3Model.EXP_THRESHOLD) + { + Vgsteff = Vgst; + dVgsteff_dVg = dVgs_eff_dVg; + dVgsteff_dVd = -dVth_dVd; + dVgsteff_dVb = -dVth_dVb; + } + else if (ExpArg > BSim3Model.EXP_THRESHOLD) + { + T0 = (Vgst - s.voff) / (n * Vtm); + ExpVgst = Math.exp(T0); + Vgsteff = Vtm * s.cdep0 / m.cox * ExpVgst; + dVgsteff_dVg = Vgsteff / (n * Vtm); + dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * Vtm * dn_dVd); + dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * Vtm * dn_dVb); + dVgsteff_dVg *= dVgs_eff_dVg; + } + else + { + ExpVgst = Math.exp(VgstNVt); + T1 = T10 * Math.log(1.0 + ExpVgst); + dT1_dVg = ExpVgst / (1.0 + ExpVgst); + dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb; + dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd; + + dT2_dVg = -m.cox / (Vtm * s.cdep0) * Math.exp(ExpArg); + T2 = 1.0 - T10 * dT2_dVg; + dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd) + + (T2 - 1.0) / n * dn_dVd; + dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb) + + (T2 - 1.0) / n * dn_dVb; + + Vgsteff = T1 / T2; + T3 = T2 * T2; + dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg; + dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3; + dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; + } + + /* Calculate Effective Channel Geometry */ + T9 = sqrtPhis - s.sqrtPhi; + Weff = s.weff - 2.0 * (s.dwg * Vgsteff + s.dwb * T9); + dWeff_dVg = -2.0 * s.dwg; + dWeff_dVb = -2.0 * s.dwb * dsqrtPhis_dVb; + + if (Weff < 2.0e-8) + { + /* to avoid the discontinuity problem due to Weff*/ + T0 = 1.0 / (6.0e-8 - 2.0 * Weff); + Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; + T0 *= T0 * 4.0e-16; + dWeff_dVg *= T0; + dWeff_dVb *= T0; + } + + T0 = s.prwg * Vgsteff + s.prwb * T9; + if (T0 >= -0.9) + { + Rds = s.rds0 * (1.0 + T0); + dRds_dVg = s.rds0 * s.prwg; + dRds_dVb = s.rds0 * s.prwb * dsqrtPhis_dVb; + } + else + { + /* to avoid the discontinuity problem due to prwg and prwb*/ + T1 = 1.0 / (17.0 + 20.0 * T0); + Rds = s.rds0 * (0.8 + T0) * T1; + T1 *= T1; + dRds_dVg = s.rds0 * s.prwg * T1; + dRds_dVb = s.rds0 * s.prwb * dsqrtPhis_dVb * T1; + } + + /* Calculate Abulk */ + T1 = 0.5 * s.k1ox / sqrtPhis; + dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb; + + T9 = Math.sqrt(s.xj * Xdep); + tmp1 = Leff + 2.0 * T9; + T5 = Leff / tmp1; + tmp2 = s.a0 * T5; + tmp3 = s.weff + s.b1; + tmp4 = s.b0 / tmp3; + T2 = tmp2 + tmp4; + dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb; + T6 = T5 * T5; + T7 = T5 * T6; + + Abulk0 = 1.0 + T1 * T2; + dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb; + + T8 = s.ags * s.a0 * T7; + dAbulk_dVg = -T1 * T8; + Abulk = Abulk0 + dAbulk_dVg * Vgsteff; + dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb + 3.0 * T1 * dT2_dVb); + + if (Abulk0 < 0.1) + { + /* added to avoid the problems caused by Abulk0 */ + T9 = 1.0 / (3.0 - 20.0 * Abulk0); + Abulk0 = (0.2 - Abulk0) * T9; + dAbulk0_dVb *= T9 * T9; + } + + if (Abulk < 0.1) + { + /* added to avoid the problems caused by Abulk */ + T9 = 1.0 / (3.0 - 20.0 * Abulk); + Abulk = (0.2 - Abulk) * T9; + T10 = T9 * T9; + dAbulk_dVb *= T10; + dAbulk_dVg *= T10; + } + + T2 = s.keta * Vbseff; + if (T2 >= -0.9) + { + T0 = 1.0 / (1.0 + T2); + dT0_dVb = -s.keta * T0 * T0; + } + else + { + /* added to avoid the problems caused by Keta */ + T1 = 1.0 / (0.8 + T2); + T0 = (17.0 + 20.0 * T2) * T1; + dT0_dVb = -s.keta * T1 * T1; + } + dAbulk_dVg *= T0; + dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; + dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; + Abulk *= T0; + Abulk0 *= T0; + + + /* Mobility calculation */ + if (m.mobMod == 1) + { + T0 = Vgsteff + Vth + Vth; + T2 = s.ua + s.uc * Vbseff; + T3 = T0 / m.tox; + T5 = T3 * (T2 + s.ub * T3); + dDenomi_dVg = (T2 + 2.0 * s.ub * T3) / m.tox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + s.uc * T3; + } + else if (m.mobMod == 2) + { + T5 = Vgsteff / m.tox * (s.ua + s.uc * Vbseff + s.ub * Vgsteff / m.tox); + dDenomi_dVg = (s.ua + s.uc * Vbseff + 2.0 * s.ub * Vgsteff / m.tox) / m.tox; + dDenomi_dVd = 0.0; + dDenomi_dVb = Vgsteff * s.uc / m.tox; + } + else + { + T0 = Vgsteff + Vth + Vth; + T2 = 1.0 + s.uc * Vbseff; + T3 = T0 / m.tox; + T4 = T3 * (s.ua + s.ub * T3); + T5 = T4 * T2; + dDenomi_dVg = (s.ua + 2.0 * s.ub * T3) * T2 / m.tox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + s.uc * T4; + } + + if (T5 >= -0.8) + Denomi = 1.0 + T5; + else + { + /* Added to avoid the discontinuity problem caused by ua and ub*/ + T9 = 1.0 / (7.0 + 10.0 * T5); + Denomi = (0.6 + T5) * T9; + T9 *= T9; + dDenomi_dVg *= T9; + dDenomi_dVd *= T9; + dDenomi_dVb *= T9; + } + + ueff = s.u0temp / Denomi; + T9 = -ueff / Denomi; + dueff_dVg = T9 * dDenomi_dVg; + dueff_dVd = T9 * dDenomi_dVd; + dueff_dVb = T9 * dDenomi_dVb; + + /* Saturation Drain Voltage Vdsat */ + WVCox = Weff * s.vsattemp * m.cox; + WVCoxRds = WVCox * Rds; + + Esat = 2.0 * s.vsattemp / ueff; + EsatL = Esat * Leff; + T0 = -EsatL /ueff; + dEsatL_dVg = T0 * dueff_dVg; + dEsatL_dVd = T0 * dueff_dVd; + dEsatL_dVb = T0 * dueff_dVb; + + /* Sqrt() */ + a1 = s.a1; + if (a1 == 0.0) + { + Lambda = s.a2; + dLambda_dVg = 0.0; + } + else if (a1 > 0.0) + { + /* Added to avoid the discontinuity problem caused by a1 and a2 (Lambda) */ + T0 = 1.0 - s.a2; + T1 = T0 - s.a1 * Vgsteff - 0.0001; + T2 = Math.sqrt(T1 * T1 + 0.0004 * T0); + Lambda = s.a2 + T0 - 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * s.a1 * (1.0 + T1 / T2); + } + else + { + T1 = s.a2 + s.a1 * Vgsteff - 0.0001; + T2 = Math.sqrt(T1 * T1 + 0.0004 * s.a2); + Lambda = 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * s.a1 * (1.0 + T1 / T2); + } + + Vgst2Vtm = Vgsteff + 2.0 * Vtm; + if (Rds > 0) + { + tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; + tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; + } + else + { + tmp2 = dWeff_dVg / Weff; + tmp3 = dWeff_dVb / Weff; + } + if ((Rds == 0.0) && (Lambda == 1.0)) + { + T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm); + tmp1 = 0.0; + T1 = T0 * T0; + T2 = Vgst2Vtm * T0; + T3 = EsatL * Vgst2Vtm; + Vdsat = T3 * T0; + + dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1; + dT0_dVd = -(Abulk * dEsatL_dVd) * T1; + dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1; + + dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; + dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; + dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; + } + else + { + tmp1 = dLambda_dVg / (Lambda * Lambda); + T9 = Abulk * WVCoxRds; + T8 = Abulk * T9; + T7 = Vgst2Vtm * T9; + T6 = Vgst2Vtm * WVCoxRds; + T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda); + dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1 + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg); + + dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3) + + (1.0 / Lambda - 1.0) * dAbulk_dVb); + dT0_dVd = 0.0; + T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7; + + dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 + * (T9 + T7 * tmp2 + T6 * dAbulk_dVg); + dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb + + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3); + dT1_dVd = Abulk * dEsatL_dVd; + + T2 = Vgst2Vtm * (EsatL + 2.0 * T6); + dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); + dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); + dT2_dVd = Vgst2Vtm * dEsatL_dVd; + + T3 = Math.sqrt(T1 * T1 - 2.0 * T0 * T2); + Vdsat = (T1 - T3) / T0; + + dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg)) / T3; + dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd)) / T3; + dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb)) / T3; + + dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 + - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; + dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 + - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; + dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; + } + + /* Effective Vds (Vdseff) Calculation */ + T1 = Vdsat - Vds - s.delta; + dT1_dVg = dVdsat_dVg; + dT1_dVd = dVdsat_dVd - 1.0; + dT1_dVb = dVdsat_dVb; + + T2 = Math.sqrt(T1 * T1 + 4.0 * s.delta * Vdsat); + T0 = T1 / T2; + T3 = 2.0 * s.delta / T2; + dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; + dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; + dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; + + Vdseff = Vdsat - 0.5 * (T1 + T2); + dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); + dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); + dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); + if (Vds == 0.0) + { + /* Added to eliminate non-zero Vdseff at Vds=0.0 */ + Vdseff = 0.0; + dVdseff_dVg = 0.0; + dVdseff_dVb = 0.0; + } + + /* Calculate VAsat */ + tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; + T9 = WVCoxRds * Vgsteff; + T8 = T9 / Vgst2Vtm; + T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; + + T7 = 2.0 * WVCoxRds * tmp4; + dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff) + - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm + Vdsat * dAbulk_dVg); + + dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff + - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); + dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd; + + T9 = WVCoxRds * Abulk; + T1 = 2.0 / Lambda - 1.0 + T9; + dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg); + dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3; + + Vasat = T0 / T1; + dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; + dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; + dVasat_dVd = dT0_dVd / T1; + + if (Vdseff > Vds) + Vdseff = Vds; + diffVds = Vds - Vdseff; + + /* Calculate VACLM */ + if ((s.pclm > 0.0) && (diffVds > 1.0e-10)) + { + T0 = 1.0 / (s.pclm * Abulk * s.litl); + dT0_dVb = -T0 / Abulk * dAbulk_dVb; + dT0_dVg = -T0 / Abulk * dAbulk_dVg; + + T2 = Vgsteff / EsatL; + T1 = Leff * (Abulk + T2); + dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg); + dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL); + dT1_dVd = -T2 * dEsatL_dVd / Esat; + + T9 = T0 * T1; + VACLM = T9 * diffVds; + dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + T1 * diffVds * dT0_dVg; + dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds - T9 * dVdseff_dVb; + dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); + } + else + { + VACLM = BSim3Model.MAX_EXP; + dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0; + } + + /* Calculate VADIBL */ + if (s.thetaRout > 0.0) + { + T8 = Abulk * Vdsat; + T0 = Vgst2Vtm * T8; + dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8 + Vgst2Vtm * Vdsat * dAbulk_dVg; + dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); + dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd; + + T1 = Vgst2Vtm + T8; + dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg; + dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat; + dT1_dVd = Abulk * dVdsat_dVd; + + T9 = T1 * T1; + T2 = s.thetaRout; + VADIBL = (Vgst2Vtm - T0 / T1) / T2; + dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; + dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; + dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; + + T7 = s.pdiblb * Vbseff; + if (T7 >= -0.9) + { + T3 = 1.0 / (1.0 + T7); + VADIBL *= T3; + dVADIBL_dVg *= T3; + dVADIBL_dVb = (dVADIBL_dVb - VADIBL * s.pdiblb) * T3; + dVADIBL_dVd *= T3; + } + else + { + /* Added to avoid the discontinuity problem caused by pdiblcb */ + T4 = 1.0 / (0.8 + T7); + T3 = (17.0 + 20.0 * T7) * T4; + dVADIBL_dVg *= T3; + dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * s.pdiblb * T4 * T4; + dVADIBL_dVd *= T3; + VADIBL *= T3; + } + } + else + { + VADIBL = BSim3Model.MAX_EXP; + dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0; + } + + /* Calculate VA */ + T8 = s.pvag / EsatL; + T9 = T8 * Vgsteff; + if (T9 > -0.9) + { + T0 = 1.0 + T9; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL); + dT0_dVb = -T9 * dEsatL_dVb / EsatL; + dT0_dVd = -T9 * dEsatL_dVd / EsatL; + } + else + { + /* Added to avoid the discontinuity problems caused by pvag */ + T1 = 1.0 / (17.0 + 20.0 * T9); + T0 = (0.8 + T9) * T1; + T1 *= T1; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1; + + T9 *= T1 / EsatL; + dT0_dVb = -T9 * dEsatL_dVb; + dT0_dVd = -T9 * dEsatL_dVd; + } + + tmp1 = VACLM * VACLM; + tmp2 = VADIBL * VADIBL; + tmp3 = VACLM + VADIBL; + + T1 = VACLM * VADIBL / tmp3; + tmp3 *= tmp3; + dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; + dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; + dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; + + Va = Vasat + T0 * T1; + dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; + dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; + dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; + + /* Calculate VASCBE */ + if (s.pscbe2 > 0.0) + { + if (diffVds > s.pscbe1 * s.litl / BSim3Model.EXP_THRESHOLD) + { + T0 = s.pscbe1 * s.litl / diffVds; + VASCBE = Leff * Math.exp(T0) / s.pscbe2; + T1 = T0 * VASCBE / diffVds; + dVASCBE_dVg = T1 * dVdseff_dVg; + dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd); + dVASCBE_dVb = T1 * dVdseff_dVb; + } + else + { + VASCBE = BSim3Model.MAX_EXP * Leff/s.pscbe2; + dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; + } + } + else + { + VASCBE = BSim3Model.MAX_EXP; + dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; + } + + /* Calculate Ids */ + CoxWovL = m.cox * Weff / Leff; + beta = ueff * CoxWovL; + dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; + dbeta_dVd = CoxWovL * dueff_dVd; + dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; + + T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm; + dT0_dVg = -0.5 * (Abulk * dVdseff_dVg + - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm; + dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm; + dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff) / Vgst2Vtm; + + fgche1 = Vgsteff * T0; + dfgche1_dVg = Vgsteff * dT0_dVg + T0; + dfgche1_dVd = Vgsteff * dT0_dVd; + dfgche1_dVb = Vgsteff * dT0_dVb; + + T9 = Vdseff / EsatL; + fgche2 = 1.0 + T9; + dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; + dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; + dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; + + gche = beta * fgche1 / fgche2; + dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg + - gche * dfgche2_dVg) / fgche2; + dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd + - gche * dfgche2_dVd) / fgche2; + dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb + - gche * dfgche2_dVb) / fgche2; + + T0 = 1.0 + gche * Rds; + T9 = Vdseff / T0; + Idl = gche * T9; + + dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 + - Idl * gche / T0 * dRds_dVg ; + + dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; + dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb - Idl * dRds_dVb * gche) / T0; + + T9 = diffVds / Va; + T0 = 1.0 + T9; + Idsa = Idl * T0; + dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; + dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd - T9 * dVa_dVd) / Va; + dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; + + T9 = diffVds / VASCBE; + T0 = 1.0 + T9; + Ids = Idsa * T0; + + Gm = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE; + Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd - T9 * dVASCBE_dVd) / VASCBE; + Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb + T9 * dVASCBE_dVb) / VASCBE; + + Gds += Gm * dVgsteff_dVd; + Gmb += Gm * dVgsteff_dVb; + Gm *= dVgsteff_dVg; + Gmb *= dVbseff_dVb; + + /* Substrate current begins */ + tmp = s.alpha0 + s.alpha1 * Leff; + if ((tmp <= 0.0) || (s.beta0 <= 0.0)) + Isub = Gbd = Gbb = Gbg = 0.0; + else + { + T2 = tmp / Leff; + if (diffVds > s.beta0 / BSim3Model.EXP_THRESHOLD) + { + T0 = -s.beta0 / diffVds; + T1 = T2 * diffVds * Math.exp(T0); + T3 = T1 / diffVds * (T0 - 1.0); + dT1_dVg = T3 * dVdseff_dVg; + dT1_dVd = T3 * (dVdseff_dVd - 1.0); + dT1_dVb = T3 * dVdseff_dVb; + } + else + { + T3 = T2 * BSim3Model.MIN_EXP; + T1 = T3 * diffVds; + dT1_dVg = -T3 * dVdseff_dVg; + dT1_dVd = T3 * (1.0 - dVdseff_dVd); + dT1_dVb = -T3 * dVdseff_dVb; + } + Isub = T1 * Idsa; + Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg; + Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd; + Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb; + + Gbd += Gbg * dVgsteff_dVd; + Gbb += Gbg * dVgsteff_dVb; + Gbg *= dVgsteff_dVg; + Gbb *= dVbseff_dVb; /* bug fixing */ + } + + /* Charge/Capacitance computation begins */ + qgate = qdrn = qsrc = qbulk = 0.0; + cggb = cgsb = cgdb = 0.0; + cdgb = cdsb = cddb = 0.0; + cbgb = cbsb = cbdb = 0.0; + if (m.xpart >= 0 && m.capMod == 0) + { + if (Vbseff < 0.0) + { + Vbseff = Vbs; + dVbseff_dVb = 1.0; + } + else + { + Vbseff = s.phi - Phis; + dVbseff_dVb = -dPhis_dVb; + } + + Vfb = s.vfbcv; + Vth = Vfb + s.phi + s.k1ox * sqrtPhis; + Vgst = Vgs_eff - Vth; + dVth_dVb = s.k1ox * dsqrtPhis_dVb; + dVgst_dVb = -dVth_dVb; + dVgst_dVg = dVgs_eff_dVg; + + CoxWL = m.cox * s.weffCV * s.leffCV; + Arg1 = Vgs_eff - Vbseff - Vfb; + + if (Arg1 <= 0.0) + { + qgate = CoxWL * Arg1; + qbulk = -qgate; + qdrn = 0.0; + + cggb = CoxWL * dVgs_eff_dVg; + cgdb = 0.0; + cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg); + + cdgb = 0.0; + cddb = 0.0; + cdsb = 0.0; + + cbgb = -CoxWL * dVgs_eff_dVg; + cbdb = 0.0; + cbsb = -cgsb; + qinv = 0.0; + } + else if (Vgst <= 0.0) + { + T1 = 0.5 * s.k1ox; + T2 = Math.sqrt(T1 * T1 + Arg1); + qgate = CoxWL * s.k1ox * (T2 - T1); + qbulk = -qgate; + qdrn = 0.0; + + T0 = CoxWL * T1 / T2; + cggb = T0 * dVgs_eff_dVg; + cgdb = 0.0; + cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg); + + cdgb = 0.0; + cddb = 0.0; + cdsb = 0.0; + + cbgb = -cggb; + cbdb = 0.0; + cbsb = -cgsb; + qinv = 0.0; + } + else + { + One_Third_CoxWL = CoxWL / 3.0; + Two_Third_CoxWL = 2.0 * One_Third_CoxWL; + + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + Vdsat = Vgst / AbulkCV; + dVdsat_dVg = dVgs_eff_dVg / AbulkCV; + dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV; + + if (m.xpart > 0.5) + { + /* 0/100 Charge partition model */ + if (Vdsat <= Vds) + { + /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.0; + + cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + cgsb = -(cggb + T2); + cgdb = 0.0; + + cdgb = 0.0; + cddb = 0.0; + cdsb = 0.0; + + cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + cbsb = -(cbgb + T3); + cbdb = 0.0; + qinv = -(qgate + qbulk); + } + else + { + /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + T7 = 2.0 * Vds - T1 - 3.0 * T3; + T8 = T3 - T1 - 2.0 * Vds; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - 0.5 * (Vds - T3)); + T10 = T4 * T8; + qdrn = T4 * T7; + qbulk = -(qgate + qdrn + T10); + + T5 = T3 / T1; + cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; + T11 = -CoxWL * T5 * dVdsat_dVb; + cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); + cgsb = -(cggb + T11 + cgdb); + T6 = 1.0 / Vdsat; + dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); + dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); + T7 = T9 * T7; + T8 = T9 * T8; + T9 = 2.0 * T4 * (1.0 - 3.0 * T5); + cdgb = (T7 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; + T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb; + cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5); + cdsb = -(cdgb + T12 + cddb); + + T9 = 2.0 * T4 * (1.0 + T5); + T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg; + T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb; + T12 = T4 * (2.0 * T2 + T5 - 1.0); + T0 = -(T10 + T11 + T12); + + cbgb = -(cggb + cdgb + T10); + cbdb = -(cgdb + cddb + T12); + cbsb = -(cgsb + cdsb + T0); + qinv = -(qgate + qbulk); + } + } + else if (m.xpart < 0.5) + { + /* 40/60 Charge partition model */ + if (Vds >= Vdsat) + { + /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb + - s.phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.4 * T2; + + cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + cgsb = -(cggb + T2); + cgdb = 0.0; + + T3 = 0.4 * Two_Third_CoxWL; + cdgb = -T3 * dVgs_eff_dVg; + cddb = 0.0; + T4 = T3 * dVth_dVb; + cdsb = -(T4 + cdgb); + + cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + cbsb = -(cbgb + T3); + cbdb = 0.0; + qinv = -(qgate + qbulk); + } + else + { + /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - 0.5 * (Vds - T3)); + + T5 = T3 / T1; + cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; + tmp = -CoxWL * T5 * dVdsat_dVb; + cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); + cgsb = -(cggb + cgdb + tmp); + + T6 = 1.0 / Vdsat; + dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); + dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); + + T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds + 1.2 * Vds * Vds; + T8 = T2 / T1; + T7 = Vds - T1 - T8 * T6; + qdrn = T4 * T7; + T7 *= T9; + tmp = T8 / T1; + tmp1 = T4 * (2.0 - 4.0 * tmp * T6 + T8 * (16.0 * Vdsat - 6.0 * Vds)); + + cdgb = (T7 * dAlphaz_dVg - tmp1 * dVdsat_dVg) * dVgs_eff_dVg; + T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb; + cddb = T4 * (2.0 - (1.0 / (3.0 * T1 * T1) + 2.0 * tmp) * T6 + T8 + * (6.0 * Vdsat - 2.4 * Vds)); + cdsb = -(cdgb + T10 + cddb); + + T7 = 2.0 * (T1 + T3); + qbulk = -(qgate - T4 * T7); + T7 *= T9; + T0 = 4.0 * T4 * (1.0 - T5); + T12 = (-T7 * dAlphaz_dVg - cdgb - T0 * dVdsat_dVg) * dVgs_eff_dVg; + T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb; + T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5) - cddb; + tmp = -(T10 + T11 + T12); + + cbgb = -(cggb + cdgb + T12); + cbdb = -(cgdb + cddb + T11); + cbsb = -(cgsb + cdsb + tmp); + qinv = -(qgate + qbulk); + } + } + else + { + /* 50/50 partitioning */ + if (Vds >= Vdsat) + { + /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.5 * T2; + + cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + cgsb = -(cggb + T2); + cgdb = 0.0; + + cdgb = -One_Third_CoxWL * dVgs_eff_dVg; + cddb = 0.0; + T4 = One_Third_CoxWL * dVth_dVb; + cdsb = -(T4 + cdgb); + + cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + cbsb = -(cbgb + T3); + cbdb = 0.0; + qinv = -(qgate + qbulk); + } + else + { + /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + qgate = CoxWL * (Vgs_eff - Vfb - s.phi - 0.5 * (Vds - T3)); + + T5 = T3 / T1; + cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg; + tmp = -CoxWL * T5 * dVdsat_dVb; + cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); + cgsb = -(cggb + cgdb + tmp); + + T6 = 1.0 / Vdsat; + dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); + dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); + + T7 = T1 + T3; + qdrn = -T4 * T7; + qbulk = - (qgate + qdrn + qdrn); + T7 *= T9; + T0 = T4 * (2.0 * T5 - 2.0); + + cdgb = (T0 * dVdsat_dVg - T7 * dAlphaz_dVg) * dVgs_eff_dVg; + T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb; + cddb = T4 * (1.0 - 2.0 * T2 - T5); + cdsb = -(cdgb + T12 + cddb); + + cbgb = -(cggb + 2.0 * cdgb); + cbdb = -(cgdb + 2.0 * cddb); + cbsb = -(cgsb + 2.0 * cdsb); + qinv = -(qgate + qbulk); + } + } + } + } + else if (m.xpart >= 0) + { + if (Vbseff < 0.0) + { + VbseffCV = Vbseff; + dVbseffCV_dVb = 1.0; + } + else + { + VbseffCV = s.phi - Phis; + dVbseffCV_dVb = -dPhis_dVb; + } + + CoxWL = m.cox * s.weffCV * s.leffCV; + + /* Seperate VgsteffCV with noff and voffcv */ + noff = n * s.noff; + dnoff_dVd = s.noff * dn_dVd; + dnoff_dVb = s.noff * dn_dVb; + T0 = Vtm * noff; + voffcv = s.voffcv; + VgstNVt = (Vgst - voffcv) / T0; + + if (VgstNVt > BSim3Model.EXP_THRESHOLD) + { + Vgsteff = Vgst - voffcv; + dVgsteff_dVg = dVgs_eff_dVg; + dVgsteff_dVd = -dVth_dVd; + dVgsteff_dVb = -dVth_dVb; + } + else if (VgstNVt < -BSim3Model.EXP_THRESHOLD) + { + Vgsteff = T0 * Math.log(1.0 + BSim3Model.MIN_EXP); + dVgsteff_dVg = 0.0; + dVgsteff_dVd = Vgsteff / noff; + dVgsteff_dVb = dVgsteff_dVd * dnoff_dVb; + dVgsteff_dVd *= dnoff_dVd; + } + else + { + ExpVgst = Math.exp(VgstNVt); + Vgsteff = T0 * Math.log(1.0 + ExpVgst); + dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst); + dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgst - voffcv) + / noff * dnoff_dVd) + Vgsteff / noff * dnoff_dVd; + dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgst - voffcv) + / noff * dnoff_dVb) + Vgsteff / noff * dnoff_dVb; + dVgsteff_dVg *= dVgs_eff_dVg; + } /* End of VgsteffCV */ + + if (m.capMod == 1) + { + Vfb = s.vfbzb; + Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff; + + if (Arg1 <= 0.0) + { + qgate = CoxWL * Arg1; + Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg); + Cgd = -CoxWL * dVgsteff_dVd; + Cgb = -CoxWL * (dVbseffCV_dVb + dVgsteff_dVb); + } + else + { + T0 = 0.5 * s.k1ox; + T1 = Math.sqrt(T0 * T0 + Arg1); + T2 = CoxWL * T0 / T1; + + qgate = CoxWL * s.k1ox * (T1 - T0); + + Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg); + Cgd = -T2 * dVgsteff_dVd; + Cgb = -T2 * (dVbseffCV_dVb + dVgsteff_dVb); + } + qbulk = -qgate; + Cbg = -Cgg; + Cbd = -Cgd; + Cbb = -Cgb; + + One_Third_CoxWL = CoxWL / 3.0; + Two_Third_CoxWL = 2.0 * One_Third_CoxWL; + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + VdsatCV = Vgsteff / AbulkCV; + if (VdsatCV < Vds) + { + dVdsatCV_dVg = 1.0 / AbulkCV; + dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; + T0 = Vgsteff - VdsatCV / 3.0; + dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0; + dT0_dVb = -dVdsatCV_dVb / 3.0; + qgate += CoxWL * T0; + Cgg1 = CoxWL * dT0_dVg; + Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb; + Cgd1 = Cgg1 * dVgsteff_dVd; + Cgg1 *= dVgsteff_dVg; + Cgg += Cgg1; + Cgb += Cgb1; + Cgd += Cgd1; + + T0 = VdsatCV - Vgsteff; + dT0_dVg = dVdsatCV_dVg - 1.0; + dT0_dVb = dVdsatCV_dVb; + qbulk += One_Third_CoxWL * T0; + Cbg1 = One_Third_CoxWL * dT0_dVg; + Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb; + Cbd1 = Cbg1 * dVgsteff_dVd; + Cbg1 *= dVgsteff_dVg; + Cbg += Cbg1; + Cbb += Cbb1; + Cbd += Cbd1; + + if (m.xpart > 0.5) + T0 = -Two_Third_CoxWL; + else if (m.xpart < 0.5) + T0 = -0.4 * CoxWL; + else + T0 = -One_Third_CoxWL; + + qsrc = T0 * Vgsteff; + Csg = T0 * dVgsteff_dVg; + Csb = T0 * dVgsteff_dVb; + Csd = T0 * dVgsteff_dVd; + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + } + else + { + T0 = AbulkCV * Vds; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20); + T2 = Vds / T1; + T3 = T0 * T2; + dT3_dVg = -12.0 * T2 * T2 * AbulkCV; + dT3_dVd = 6.0 * T0 * (4.0 * Vgsteff - T0) / T1 / T1 - 0.5; + dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff; + + qgate += CoxWL * (Vgsteff - 0.5 * Vds + T3); + Cgg1 = CoxWL * (1.0 + dT3_dVg); + Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb; + Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd; + Cgg1 *= dVgsteff_dVg; + Cgg += Cgg1; + Cgb += Cgb1; + Cgd += Cgd1; + + qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * Vds - T3); + Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg); + Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb + (0.5 * Vds - T3) * dAbulkCV_dVb) + + Cbg1 * dVgsteff_dVb; + Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd + Cbg1 * dVgsteff_dVd; + Cbg1 *= dVgsteff_dVg; + Cbg += Cbg1; + Cbb += Cbb1; + Cbd += Cbd1; + + if (m.xpart > 0.5) + { + /* 0/100 Charge petition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); + Csg = -CoxWL * (0.5 + 24.0 * T0 * Vds / T1 / T1 * AbulkCV); + Csb = -CoxWL * (0.25 * Vds * dAbulkCV_dVb + - 12.0 * T0 * Vds / T1 / T1 * (4.0 * Vgsteff - T0) + * dAbulkCV_dVb) + Csg * dVgsteff_dVb; + Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0 + / T1 / T1 * (4.0 * Vgsteff - T0)) + Csg * dVgsteff_dVd; + Csg *= dVgsteff_dVg; + } + else if (m.xpart < 0.5) + { + /* 40/60 Charge petition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + 0.4 * T0 * T0; + Csg = -2.0 * qsrc / T1 - T2 + * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); + Csb = (qsrc / T1 * Vds + T2 * T4 * Vds) * dAbulkCV_dVb + + Csg * dVgsteff_dVb; + Csd = (qsrc / T1 + T2 * T4) * AbulkCV + Csg * dVgsteff_dVd; + Csg *= dVgsteff_dVg; + } + else + { + /* 50/50 Charge petition model */ + qsrc = -0.5 * (qgate + qbulk); + Csg = -0.5 * (Cgg1 + Cbg1); + Csb = -0.5 * (Cgb1 + Cbb1); + Csd = -0.5 * (Cgd1 + Cbd1); + } + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + } + qdrn = -(qgate + qbulk + qsrc); + cggb = Cgg; + cgsb = -(Cgg + Cgd + Cgb); + cgdb = Cgd; + cdgb = -(Cgg + Cbg + Csg); + cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); + cddb = -(Cgd + Cbd + Csd); + cbgb = Cbg; + cbsb = -(Cbg + Cbd + Cbb); + cbdb = Cbd; + qinv = -(qgate + qbulk); + } + + else if (m.capMod == 2) + { + Vfb = s.vfbzb; + V3 = Vfb - Vgs_eff + VbseffCV - BSim3Model.DELTA_3; + if (Vfb <= 0.0) + { + T0 = Math.sqrt(V3 * V3 - 4.0 * BSim3Model.DELTA_3 * Vfb); + T2 = -BSim3Model.DELTA_3 / T0; + } + else + { + T0 = Math.sqrt(V3 * V3 + 4.0 * BSim3Model.DELTA_3 * Vfb); + T2 = BSim3Model.DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1 * dVbseffCV_dVb; + Qac0 = CoxWL * (Vfbeff - Vfb); + dQac0_dVg = CoxWL * dVfbeff_dVg; + dQac0_dVb = CoxWL * dVfbeff_dVb; + + T0 = 0.5 * s.k1ox; + T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; + if (s.k1ox == 0.0) + { + T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { + T1 = T0 + T3 / s.k1ox; + T2 = CoxWL; + } + else + { + T1 = Math.sqrt(T0 * T0 + T3); + T2 = CoxWL * T0 / T1; + } + + Qsub0 = CoxWL * s.k1ox * (T1 - T0); + + dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg); + dQsub0_dVd = -T2 * dVgsteff_dVd; + dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb); + + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + VdsatCV = Vgsteff / AbulkCV; + + V4 = VdsatCV - Vds - BSim3Model.DELTA_4; + T0 = Math.sqrt(V4 * V4 + 4.0 * BSim3Model.DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = BSim3Model.DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + dVdseffCV_dVg = T3; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + if (Vds == 0.0) + { + /* Added to eliminate non-zero VdseffCV at Vds=0.0 */ + VdseffCV = 0.0; + dVdseffCV_dVg = 0.0; + dVdseffCV_dVb = 0.0; + } + + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + qinoi = -CoxWL * (Vgsteff - 0.5 * T0 + AbulkCV * T3); + qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd; + Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cgg1 * dVgsteff_dVb; + Cgg1 *= dVgsteff_dVg; + + T7 = 1.0 - AbulkCV; + qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3); + T4 = -T7 * (T4 - 1.0); + T5 = -T7 * T5; + T6 = -(T7 * T6 + (0.5 * VdseffCV - T3)); + Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd; + Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Cbg1 * dVgsteff_dVb; + Cbg1 *= dVgsteff_dVg; + + if (m.xpart > 0.5) + { + /* 0/100 Charge petition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1); + T7 = (4.0 * Vgsteff - T0) / (T1 * T1); + T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); + T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); + T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); + Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; + Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; + Csg *= dVgsteff_dVg; + } + else if (m.xpart < 0.5) + { + /* 40/60 Charge petition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + 0.4 * T0 * T0; + T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 * Vgsteff - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T5 = (qsrc / T1 + T2 * T7) * AbulkCV; + T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); + Csg = (T4 + T5 * dVdseffCV_dVg); + Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; + Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + Csg * dVgsteff_dVb; + Csg *= dVgsteff_dVg; + } + else + { + /* 50/50 Charge petition model */ + qsrc = -0.5 * (qgate + qbulk); + Csg = -0.5 * (Cgg1 + Cbg1); + Csb = -0.5 * (Cgb1 + Cbb1); + Csd = -0.5 * (Cgd1 + Cbd1); + } + + qgate += Qac0 + Qsub0; + qbulk -= (Qac0 + Qsub0); + qdrn = -(qgate + qbulk + qsrc); + + Cgg = dQac0_dVg + dQsub0_dVg + Cgg1; + Cgd = dQsub0_dVd + Cgd1; + Cgb = dQac0_dVb + dQsub0_dVb + Cgb1; + + Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; + Cbd = Cbd1 - dQsub0_dVd; + Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; + + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + + cggb = Cgg; + cgsb = -(Cgg + Cgd + Cgb); + cgdb = Cgd; + cdgb = -(Cgg + Cbg + Csg); + cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); + cddb = -(Cgd + Cbd + Csd); + cbgb = Cbg; + cbsb = -(Cbg + Cbd + Cbb); + cbdb = Cbd; + qinv = qinoi; + } + + /* New Charge-Thickness capMod (CTM) begins */ + else if (m.capMod == 3) + { + V3 = s.vfbzb - Vgs_eff + VbseffCV - BSim3Model.DELTA_3; + if (s.vfbzb <= 0.0) + { + T0 = Math.sqrt(V3 * V3 - 4.0 * BSim3Model.DELTA_3 * s.vfbzb); + T2 = -BSim3Model.DELTA_3 / T0; + } + else + { + T0 = Math.sqrt(V3 * V3 + 4.0 * BSim3Model.DELTA_3 * s.vfbzb); + T2 = BSim3Model.DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = s.vfbzb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1 * dVbseffCV_dVb; + + Cox = m.cox; + Tox = 1.0e8 * m.tox; + T0 = (Vgs_eff - VbseffCV - s.vfbzb) / Tox; + dT0_dVg = dVgs_eff_dVg / Tox; + dT0_dVb = -dVbseffCV_dVb / Tox; + + tmp = T0 * s.acde; + if ((-BSim3Model.EXP_THRESHOLD < tmp) && (tmp < BSim3Model.EXP_THRESHOLD)) + { + Tcen = s.ldeb * Math.exp(tmp); + dTcen_dVg = s.acde * Tcen; + dTcen_dVb = dTcen_dVg * dT0_dVb; + dTcen_dVg *= dT0_dVg; + } + else if (tmp <= -BSim3Model.EXP_THRESHOLD) + { + Tcen = s.ldeb * BSim3Model.MIN_EXP; + dTcen_dVg = dTcen_dVb = 0.0; + } + else + { + Tcen = s.ldeb * BSim3Model.MAX_EXP; + dTcen_dVg = dTcen_dVb = 0.0; + } + + LINK = 1.0e-3 * m.tox; + V3 = s.ldeb - Tcen - LINK; + V4 = Math.sqrt(V3 * V3 + 4.0 * LINK * s.ldeb); + Tcen = s.ldeb - 0.5 * (V3 + V4); + T1 = 0.5 * (1.0 + V3 / V4); + dTcen_dVg *= T1; + dTcen_dVb *= T1; + + Ccen = BSim3Model.EPSSI / Tcen; + T2 = Cox / (Cox + Ccen); + Coxeff = T2 * Ccen; + T3 = -Ccen / Tcen; + dCoxeff_dVg = T2 * T2 * T3; + dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; + dCoxeff_dVg *= dTcen_dVg; + CoxWLcen = CoxWL * Coxeff / Cox; + + Qac0 = CoxWLcen * (Vfbeff - s.vfbzb); + QovCox = Qac0 / Coxeff; + dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg; + dQac0_dVb = CoxWLcen * dVfbeff_dVb + QovCox * dCoxeff_dVb; + + T0 = 0.5 * s.k1ox; + T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; + if (s.k1ox == 0.0) + { + T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { + T1 = T0 + T3 / s.k1ox; + T2 = CoxWLcen; + } + else + { + T1 = Math.sqrt(T0 * T0 + T3); + T2 = CoxWLcen * T0 / T1; + } + + Qsub0 = CoxWLcen * s.k1ox * (T1 - T0); + QovCox = Qsub0 / Coxeff; + dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg) + + QovCox * dCoxeff_dVg; + dQsub0_dVd = -T2 * dVgsteff_dVd; + dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb) + + QovCox * dCoxeff_dVb; + + /* Gate-bias dependent delta Phis begins */ + if (s.k1ox <= 0.0) + { + Denomi = 0.25 * s.moin * Vtm; + T0 = 0.5 * s.sqrtPhi; + } + else + { + Denomi = s.moin * Vtm + * s.k1ox * s.k1ox; + T0 = s.k1ox * s.sqrtPhi; + } + T1 = 2.0 * T0 + Vgsteff; + + DeltaPhi = Vtm * Math.log(1.0 + T1 * Vgsteff / Denomi); + dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff); + dDeltaPhi_dVd = dDeltaPhi_dVg * dVgsteff_dVd; + dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb; + /* End of delta Phis */ + + T3 = 4.0 * (Vth - s.vfbzb - s.phi); + Tox += Tox; + if (T3 >= 0.0) + { + T0 = (Vgsteff + T3) / Tox; + dT0_dVd = (dVgsteff_dVd + 4.0 * dVth_dVd) / Tox; + dT0_dVb = (dVgsteff_dVb + 4.0 * dVth_dVb) / Tox; + } + else + { + T0 = (Vgsteff + 1.0e-20) / Tox; + dT0_dVd = dVgsteff_dVd / Tox; + dT0_dVb = dVgsteff_dVb / Tox; + } + tmp = Math.exp(0.7 * Math.log(T0)); + T1 = 1.0 + tmp; + T2 = 0.7 * tmp / (T0 * Tox); + Tcen = 1.9e-9 / T1; + dTcen_dVg = -1.9e-9 * T2 / T1 /T1; + dTcen_dVd = Tox * dTcen_dVg; + dTcen_dVb = dTcen_dVd * dT0_dVb; + dTcen_dVd *= dT0_dVd; + dTcen_dVg *= dVgsteff_dVg; + + Ccen = BSim3Model.EPSSI / Tcen; + T0 = Cox / (Cox + Ccen); + Coxeff = T0 * Ccen; + T1 = -Ccen / Tcen; + dCoxeff_dVg = T0 * T0 * T1; + dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd; + dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; + dCoxeff_dVg *= dTcen_dVg; + CoxWLcen = CoxWL * Coxeff / Cox; + + AbulkCV = Abulk0 * s.abulkCVfactor; + dAbulkCV_dVb = s.abulkCVfactor * dAbulk0_dVb; + VdsatCV = (Vgsteff - DeltaPhi) / AbulkCV; + V4 = VdsatCV - Vds - BSim3Model.DELTA_4; + T0 = Math.sqrt(V4 * V4 + 4.0 * BSim3Model.DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = BSim3Model.DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + T4 = T3 * ( 1.0 - dDeltaPhi_dVg); + dVdseffCV_dVg = T4; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + if (Vds == 0.0) + { + /* Added to eliminate non-zero VdseffCV at Vds=0.0 */ + VdseffCV = 0.0; + dVdseffCV_dVg = 0.0; + dVdseffCV_dVb = 0.0; + } + + T0 = AbulkCV * VdseffCV; + T1 = Vgsteff - DeltaPhi; + T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20); + T3 = T0 / T2; + T4 = 1.0 - 12.0 * T3 * T3; + T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5); + T6 = T5 * VdseffCV / AbulkCV; + + qgate = qinoi = CoxWLcen * (T1 - T0 * (0.5 - T3)); + QovCox = qgate / Coxeff; + Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) + T5 * dVdseffCV_dVg); + Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1 + * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + + T7 = 1.0 - AbulkCV; + T8 = T2 * T2; + T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV); + T10 = T9 * (1.0 - dDeltaPhi_dVg); + T11 = -T7 * T5 / AbulkCV; + T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2)); + + qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2); + QovCox = qbulk / Coxeff; + Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg); + Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb) + + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + + if (m.xpart > 0.5) + { + /* 0/100 partition */ + qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 - 0.5 * T0 * T0 / T2); + QovCox = qsrc / Coxeff; + T2 += T2; + T3 = T2 * T2; + T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3); + T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg); + T5 = T7 * AbulkCV; + T6 = T7 * VdseffCV; + + Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg); + Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + } + else if (m.xpart < 0.5) + { + /* 40/60 partition */ + T2 = T2 / 12.0; + T3 = 0.5 * CoxWLcen / (T2 * T2); + T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T3 * T4; + QovCox = qsrc / Coxeff; + T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0; + T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T6 = AbulkCV * (qsrc / T2 + T3 * T8); + T7 = T6 * VdseffCV / AbulkCV; + + Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg; + Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd + QovCox * dCoxeff_dVd; + Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb + + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + } + else + { + /* 50/50 partition */ + qsrc = -0.5 * qgate; + Csg = -0.5 * Cgg1; + Csd = -0.5 * Cgd1; + Csb = -0.5 * Cgb1; + } + + qgate += Qac0 + Qsub0 - qbulk; + qbulk -= (Qac0 + Qsub0); + qdrn = -(qgate + qbulk + qsrc); + + Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; + Cbd = Cbd1 - dQsub0_dVd; + Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; + + Cgg = Cgg1 - Cbg; + Cgd = Cgd1 - Cbd; + Cgb = Cgb1 - Cbb; + + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + + cggb = Cgg; + cgsb = -(Cgg + Cgd + Cgb); + cgdb = Cgd; + cdgb = -(Cgg + Cbg + Csg); + cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb); + cddb = -(Cgd + Cbd + Csd); + cbgb = Cbg; + cbsb = -(Cbg + Cbd + Cbb); + cbdb = Cbd; + qinv = -qinoi; + } /* End of CTM */ + } + + /* bulk and channel charge plus overlaps */ + if (m.capMod == 0) + { + if (vgd < 0.0) + { + cgdo = s.cgdo; + qgdo = s.cgdo * vgd; + } + else + { + cgdo = s.cgdo; + qgdo = s.cgdo * vgd; + } + + if (vgs < 0.0) + { + cgso = s.cgso; + qgso = s.cgso * vgs; + } + else + { + cgso = s.cgso; + qgso = s.cgso * vgs; + } + } + else if (m.capMod == 1) + { + if (vgd < 0.0) + { + T1 = Math.sqrt(1.0 - 4.0 * vgd / s.ckappa); + cgdo = s.cgdo + s.weffCV * s.cgdl / T1; + qgdo = s.cgdo * vgd - s.weffCV * 0.5 * s.cgdl * s.ckappa * (T1 - 1.0); + } + else + { + cgdo = s.cgdo + s.weffCV * s.cgdl; + qgdo = (s.weffCV * s.cgdl + s.cgdo) * vgd; + } + + if (vgs < 0.0) + { + T1 = Math.sqrt(1.0 - 4.0 * vgs / s.ckappa); + cgso = s.cgso + s.weffCV * s.cgsl / T1; + qgso = s.cgso * vgs - s.weffCV * 0.5 * s.cgsl * s.ckappa * (T1 - 1.0); + } + else + { + cgso = s.cgso + s.weffCV * s.cgsl; + qgso = (s.weffCV * s.cgsl + s.cgso) * vgs; + } + } + else + { + T0 = vgd + BSim3Model.DELTA_1; + T1 = Math.sqrt(T0 * T0 + 4.0 * BSim3Model.DELTA_1); + T2 = 0.5 * (T0 - T1); + + T3 = s.weffCV * s.cgdl; + T4 = Math.sqrt(1.0 - 4.0 * T2 / s.ckappa); + cgdo = s.cgdo + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1); + qgdo = (s.cgdo + T3) * vgd - T3 * (T2 + 0.5 * s.ckappa * (T4 - 1.0)); + + T0 = vgs + BSim3Model.DELTA_1; + T1 = Math.sqrt(T0 * T0 + 4.0 * BSim3Model.DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = s.weffCV * s.cgsl; + T4 = Math.sqrt(1.0 - 4.0 * T2 / s.ckappa); + cgso = s.cgso + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1); + qgso = (s.cgso + T3) * vgs - T3 * (T2 + 0.5 * s.ckappa * (T4 - 1.0)); + } + + /*** add up capacitances and charges ***/ + gcggb = cggb + cgdo + cgso + s.cgbo; + gcgdb = cgdb - cgdo; + gcgsb = cgsb - cgso; + + gcdgb = cdgb - cgdo; + gcddb = cddb + cgdo; + gcdsb = cdsb; + + gcsgb = -(cggb + cbgb + cdgb + cgso); + gcsdb = -(cgdb + cbdb + cddb); + gcssb = cgso - (cgsb + cbsb + cdsb); + + gcbgb = cbgb - s.cgbo; + gcbdb = cbdb; + gcbsb = cbsb; + + qgd = qgdo; + qgs = qgso; + qgb = s.cgbo * vgb; + qgate += qgd + qgs + qgb; + qbulk -= qgb; + qdrn -= qgd; + qsrc = -(qgate + qbulk + qdrn); + + drainI = -m.type*(Ids+Isub); + gateI = 0; + sourceI = m.type*Ids; + bulkI = m.type*Isub; + source.setResult(chargeScale, m.type*qsrc, currentScale, sourceI); + drain.setResult(chargeScale, m.type*qdrn, + currentScale, drainI); + gate.setResult(chargeScale, m.type*qgate, currentScale, gateI); + bulk.setResult(chargeScale, m.type*qbulk, currentScale, bulkI); + + source.setMatrix(source, derivChargeScale, gcssb, + derivCurrentScale, -Gds - Gm - Gmb); + source.setMatrix(drain, derivChargeScale, gcdsb, + derivCurrentScale, Gds+Gm+Gmb+Gbd+Gbg+Gbb); + source.setMatrix(gate, derivChargeScale, gcgsb, + derivCurrentScale, 0); + source.setMatrix(bulk, derivChargeScale, gcbsb, + derivCurrentScale, -Gbd - Gbg - Gbb); + + drain.setMatrix(source, derivChargeScale, gcsdb, + derivCurrentScale, Gds); + drain.setMatrix(drain, derivChargeScale, gcddb, + derivCurrentScale, -Gds - Gbd); + drain.setMatrix(gate, derivChargeScale, gcgdb, + derivCurrentScale, 0); + drain.setMatrix(bulk, derivChargeScale, gcbdb, + derivCurrentScale, Gbd); + + gate.setMatrix(source, derivChargeScale, gcsgb, + derivCurrentScale, Gm); + gate.setMatrix(drain, derivChargeScale, gcdgb, + derivCurrentScale, -Gm - Gbg); + gate.setMatrix(gate, derivChargeScale, gcggb, + derivCurrentScale, 0); + gate.setMatrix(bulk, derivChargeScale, gcbgb, + derivCurrentScale, Gbg); + + bulk.setMatrix(source, derivChargeScale, -gcssb - gcsdb - gcsgb, + derivCurrentScale, Gmb); + bulk.setMatrix(drain, derivChargeScale, -gcdsb - gcddb - gcdgb, + derivCurrentScale, -Gmb - Gbb); + bulk.setMatrix(gate, derivChargeScale, -gcgsb - gcgdb - gcggb, + derivCurrentScale, 0); + bulk.setMatrix(bulk, derivChargeScale, -gcbsb - gcbdb - gcbgb, + derivCurrentScale, Gbb); + //Used to debug native models vs java handcoded models + if (BSim3Model.both && BSim3Model.isNativeLoaded()) { + System.out.println(time+"\t"+(m.type*qsrc)+"\t"+(m.type*qdrn)+"\t"+ + (m.type*qgate)+"\t"+(m.type*qbulk)+"\t"+ + sourceI+"\t"+drainI+"\t"+ + gateI+"\t"+bulkI+"\t"+ + gcssb+"\t"+(-Gds - Gm - Gmb)+"\t"+ + gcsdb+"\t"+(Gds)+"\t"+ + gcsgb+"\t"+(Gm)+"\t"+ + (-gcssb - gcsdb - gcsgb)+"\t"+(Gmb)+"\t"+ + (gcdsb)+"\t"+(Gds+Gm+Gmb+Gbd+Gbg+Gbb)+"\t"+ + (gcddb)+"\t"+(-Gds - Gbd)+"\t"+ + (gcdgb)+"\t"+(-Gm - Gbg)+"\t"+ + (-gcdsb - gcddb - gcdgb)+"\t"+(-gcdsb - gcddb - gcdgb)+"\t"+ + + //Q[0] = 26th + Q[0]+"\t"+Q[1]+"\t"+Q[2]+"\t"+Q[3]+"\t"+ + I[nS]+"\t"+I[nD]+"\t"+I[2]+"\t"+I[3]+"\t"+ + dQ[0]+"\t"+dI[4*nS+nS]+"\t"+ + dQ[1]+"\t"+dI[4*nS+nD]+"\t"+ + dQ[2]+"\t"+dI[4*nS+2]+"\t"+ + dQ[3]+"\t"+dI[4*nS+3]+"\t"+ + dQ[4]+"\t"+dI[4*nD+nS]+"\t"+ + dQ[5]+"\t"+dI[4*nD+nD]+"\t"+ + dQ[6]+"\t"+dI[4*nD+2]+"\t"+ + dQ[7]+"\t"+dI[4*nD+3]+"\t"+ + //dQ[3]+"\t"+dI[3]+"\t"+ + //s/d = 50 + nS+"\t"+nD+"\t"+ + getName()); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/VoltageSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/VoltageSource.java new file mode 100644 index 0000000000..ded8b2af92 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/aspice/VoltageSource.java @@ -0,0 +1,149 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.aspice; +import com.avlsi.file.common.HierName; +import java.util.Iterator; + +/** + * Abstract Class to represent a generic voltage sources + * + * @author Dan Daly + * @version $Name: $ $Date$ + **/ +public abstract class VoltageSource extends AbstractDevice { + +// +//Parameters used to calculate the timestep +// + /** The time last timestep **/ + private double oldtime; + /** The current time **/ + private double time; + +// +//Device currents +// + /** Drain node **/ + private double drainI; + /** Source node **/ + private double sourceI; + + /** Builds a generic voltage source device + * + * @param name HierName of the device + * @param nplus positive terminal node + * @param nminus negative terminal node + ***/ + public VoltageSource(final HierName name, + final Node nplus, + final Node nminus) { + super( new Node[] {nplus, nminus}); + this.name = name; + this.oldtime = -1e-12; // Provides a timstep of 1e-12 at t=0 + } + + /** returns a tau = to 4*timestep **/ + public double getDrivenTau() { + return 4*(time-oldtime); //amount of curvature + } + + /** + * Get the positive terminal node. + * @return positive terminal node + **/ + public Node getPositiveTerminal() { + return nodes[0]; + } + + /** + * Get negative terminal node. + * @return negative terminal node + **/ + public Node getNegativeTerminal() { + return nodes[1]; + } + + /** returns the device current **/ + public double getCurrent(int type) { + switch (type) { + case AbstractDevice.I1: return drainI; + case AbstractDevice.I2: return sourceI; + } + return -1; + } + + public String getCode() { return "V";} + + private double setAnalogNode(Node node, double X, + double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale) { + double I = ((derivChargeScale*getDrivenTau() + - derivCurrentScale)*X)/currentScale; + //node.setResult( + // (chargeScale*getDrivenTau()-currentScale) + // *(node.getVoltage() - V)); + //node.setResult(chargeScale, getDrivenTau()*(node.getVoltage() - V), + // currentScale, I); + node.forceResult((derivChargeScale*getDrivenTau() + - derivCurrentScale)*X); + + /* Once a node becomes driven to the voltage V, + * it cannot be influenced by its neighboring nodes. So the + * diagonal matrix element is set to mAq*tau - mAi + * */ + for (final Iterator i= node.getNeighborMap().keySet().iterator(); + i.hasNext();) { + Object nodeId = i.next(); + double[] matrixValue = (double[]) node.getNeighborMap().get(nodeId); + if (nodeId.equals(node.getHash())) { + matrixValue[0] = derivChargeScale*getDrivenTau() + - derivCurrentScale; + } else matrixValue[0] = 0; + } + return I; + } + + private double V=0,lastV=0; + + /** + * Evaluates current, charge, and their derivatives for all ports + * on a device and then informs its nodes of these values. + * @param chargeScale scalar for charge calculation + * @param currentScale scalar for current calculation + * @param derivChargeScale scalar for charge derivative calculation + * @param derivCurrentScale scalar for current derivative calculation + * @param time Current time of the simulation + **/ + public void evalVoltage(double chargeScale, double currentScale, + double derivChargeScale, double derivCurrentScale, + double time) { + this.time = time; + this.lastV = V; + double timestep = time-oldtime; + this.V = getDrivenVoltage(time,timestep); + drainI = setAnalogNode(getPositiveTerminal(),V-lastV, + chargeScale,currentScale, + derivChargeScale, derivCurrentScale); + sourceI = setAnalogNode(getNegativeTerminal(),lastV-V, + chargeScale,currentScale, + derivChargeScale, derivCurrentScale); + oldtime = time; + } + + /** The function to override to provide specific behavior **/ + public abstract double getDrivenVoltage(double time, double timestep); + + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cadalyze.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cadalyze.java new file mode 100644 index 0000000000..7f1f346526 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cadalyze.java @@ -0,0 +1,797 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadalyze; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TreeSet; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.htmlWriter.HtmlWriter; + +import com.avlsi.tools.cadalyze.Cell.Category; +import com.avlsi.tools.cadalyze.NetGraphAnalyzer.NodeType; + + +/** + * CAST Design Analyzer + * + * Gathers and reports interesting information about a CAST design. Supports + * both asynchronous and synchronous circuits. + * + * @author Mike Davies + * @version $Revision$ $Date$ + **/ +public final class Cadalyze { + + /***************************** INNER CLASSES *****************************/ + + static class AreaCategory { + + String description = ""; + LeafStats leafStats = new LeafStats(); + NodeProps nodeProps = new NodeProps(); + Collection cellCategorySet; // null for all categories + AreaCategory parentAreaCategory = null; + int indent = 0; + + AreaCategory(String description) { + this.description = description; + cellCategorySet = null; + } + + AreaCategory(String description, Collection categories) { + this.description = description; + cellCategorySet = categories; + } + + AreaCategory(String description, Category category) { + this.description = description; + cellCategorySet = new ArrayList(); + cellCategorySet.add(category); + } + + AreaCategory(String description, Category[] categories, + AreaCategory parentAreaCategory, int indent) { + this.description = description; + this.parentAreaCategory = parentAreaCategory; + this.indent = indent; + cellCategorySet = new ArrayList(); + for (int i=0; i 0) { + cols.add(Boolean.TRUE); + // Make this variably indent sometime later... + cols.add("    "+description); + } + else { + cols.add(Boolean.FALSE); + cols.add(description); + } + return cols; + } + + String htmlFileName() { + return description.replace(' ','_').replace('/','_') + .toLowerCase() + ".html"; + } + } + + + /***************************** DATA MEMBERS ******************************/ + + /** Print lots of debugging information? Used by debugPrintln() **/ + private boolean debug; + + /** The top-level cast cell to analyze **/ + private final CellInterface ci; + + /** Cast File Parser to use to parse new cells **/ + private final CastFileParser cfp; + + /** List of gates, in case we need to generate NetGraphs from prs blocks **/ + private final List gateList; + + /** FQCN-to-Cell map of all cells in the design **/ + private Map fqcnToCellMap = null; + + /** Top-level Cell **/ + private Cell topCell = null; + + /** Set of all leaf cells (impled from fqcnToCellMap + Cell lookups) **/ + private Set leafSet = null; + + /** Number of non-fragment leaf cells in the design **/ + private int nonFragLeafCnt = 0; + + /** Number of fragment leaf cells in the design **/ + private int fragLeafCnt = 0; + + /** Design style type (-1: unknown, 0: async, 1: sync, 2: mixed) **/ + private int style = -1; + + private static final int UNKNOWN = -1; + private static final int ASYNCHRONOUS = 0; + private static final int SYNCHRONOUS = 1; + private static final int MIXED = 2; + + /** List of all area categories (AreaCategory) **/ + private List areaCategories = null; + + /** Stats accumulated over all leaf cells (index 0 of areaCategories) **/ + //private LeafStats totalStats = null; + private AreaCategory allCategories = null; + + /** Directory to which all output report files are written **/ + private String outputDir; + + /** Report generation start time **/ + private Date startDate; + + /** Median transistor length in the design **/ + private float medGateLength; + + /** Layout information **/ + private final LayoutInfo layoutInfo; + + /***************************** CLASS METHODS *****************************/ + + /** Constructor **/ + public Cadalyze(final CellInterface ci, + final CastFileParser cfp, + final List gateList, + final List layoutInfoFiles, + final String outputDir, + boolean debug) { + this.ci = ci; + this.cfp = cfp; + this.gateList = gateList; + this.outputDir = outputDir + "/" + ci.getFullyQualifiedType(); + this.debug = debug; + Cell.debug = debug; + startDate = new Date(); + + // Read layout info files + layoutInfo = new LayoutInfo(layoutInfoFiles); + + // Create results output directory if it doesn't exist + File outputDirFile = new File(this.outputDir); + if (!outputDirFile.exists()) outputDirFile.mkdir(); + } + + /** Analyze the design **/ + public void analyze(boolean verbose) throws Exception { + if (verbose) System.out.println("Processing hierarchy..."); + fqcnToCellMap = Cell.processHierarchy(ci,cfp,verbose); + topCell = (Cell)fqcnToCellMap.get(ci.getFullyQualifiedType()); + assert topCell != null; + leafSet = lookupLeafCells(); + + // Analyze all leaf cell netlists, tally results across entire design + if (verbose) System.out.println("Analyzing leaf cell NetGraphs..."); + for (Iterator cit=fqcnToCellMap.values().iterator(); cit.hasNext();) { + Cell cell = (Cell) cit.next(); + if (cell.isLeaf()) cell.analyzeNetGraph(cfp,layoutInfo); + } + + /* + for (Iterator lcit=leafSet.iterator(); lcit.hasNext();) { + Cell leaf = (Cell)lcit.next(); + leaf.buildNetGraph(cfp); + leaf.analyzeNetGraph(); + } + */ + + // Perform bottom-up propagation of node properties + if (verbose) System.out.println("Accumulating node properties..."); + topCell.setNodeProperties(); + + tallyLeafStatistics(); + } + + /** + * Returns all leaf cells (set of Cell types) + * As a side effect, calculates fragLeafCnt/nonFragLeafCnt and sets style. + **/ + private Set lookupLeafCells() { + HashSet leafSet = new HashSet(); + for (Iterator cit=fqcnToCellMap.values().iterator(); cit.hasNext();) { + Cell cell = (Cell) cit.next(); + if (cell.isLeaf()) { + leafSet.add(cell); + if (cell.isFragment()) fragLeafCnt++; + else nonFragLeafCnt++; + } + + // Set high-level design style + if (style == -1) { + if (!cell.isSynchronous()) style = 0; + else style = 1; + } + else if (style == 0 && cell.isSynchronous() || + style == 1 && !cell.isSynchronous()) + style = 2; + } + return leafSet; + } + + /** Tallies leaf cell statistics over all leaf cells in the design **/ + private void tallyLeafStatistics() { + assert leafSet != null; + + // Set up area categories + areaCategories = new ArrayList(); + AreaCategory areaCat = new AreaCategory("All"); + allCategories = areaCat; // maintain reference + areaCategories.add(areaCat); + if (style == ASYNCHRONOUS) + addAreaCategoryHierarchy(areaCategories, + Cell.Category.getMajorAsyncCategories(), ""); + else if (style == SYNCHRONOUS) + addAreaCategoryHierarchy(areaCategories, + Cell.Category.getMajorSyncCategories(), ""); + else if (style == MIXED) { + addAreaCategoryHierarchy(areaCategories, + Cell.Category.getMajorAsyncCategories(), "Async "); + addAreaCategoryHierarchy(areaCategories, + Cell.Category.getMajorSyncCategories(), "Sync "); + } + addAreaCategoryHierarchy(areaCategories, + Cell.Category.getOtherCategories(),""); + + // Tally leaf and node statistics in each area category + for (Iterator cit=fqcnToCellMap.values().iterator(); cit.hasNext();) { + Cell cell = (Cell) cit.next(); + for (Iterator ai=areaCategories.iterator(); ai.hasNext();) { + areaCat = (AreaCategory) ai.next(); + if (cell.isLeaf()) areaCat.addLeafStats(cell); + if (!cell.isDpuFragment()) areaCat.addNodeProps(cell); + } + } + + // Determine median transistor length + medGateLength = allCategories.leafStats.getMedianTransistorLength(); + } + + private void addAreaCategoryHierarchy(final List areaCategories, + final List categoryList, + final String descPrefix) { + for (Iterator ci=categoryList.iterator(); ci.hasNext();) { + Pair p = (Pair) ci.next(); + String desc = descPrefix + (String) p.getFirst(); + Category subCats[] = (Category[]) p.getSecond(); + AreaCategory parentAreaCat = + new AreaCategory(desc,subCats,allCategories,0); + areaCategories.add(parentAreaCat); + if (subCats.length > 1) { + for (int i=0; i 0.05) { + String logicEffStr = + formFloat.format(stats.getLogicEfficiency()); + + aveWidthFile.println(formFloat.format( + stats.getAverageTransistorWidth()*1e6) + + " " + logicEffStr); + + inputRailsFile.println( + String.valueOf(stats.getNodeTypeCount( + new NodeType(NodeType.INPUT_DATA_RAIL))) + + " " + logicEffStr); + + outputRailsFile.println( + String.valueOf(stats.getNodeTypeCount( + new NodeType(NodeType.OUTPUT_DATA_RAIL))) + + " " + logicEffStr); + + inputEnablesFile.println( + String.valueOf(stats.getNodeTypeCount( + new NodeType(NodeType.INPUT_ENABLE))) + + " " + logicEffStr); + + outputEnablesFile.println( + String.valueOf(stats.getNodeTypeCount( + new NodeType(NodeType.OUTPUT_ENABLE))) + + " " + logicEffStr); + } + } + aveWidthFile.close(); + inputRailsFile.close(); + outputRailsFile.close(); + inputEnablesFile.close(); + outputEnablesFile.close(); + } + catch (Exception e) { + System.err.println("Warning! Couldn't write leaf cell data files."); + System.err.println(e); + } + } + + /** + * Generates an HTML report for the design. + * To be called after analyze(). + **/ + public void printReport(boolean verbose) { + HtmlPage page; + try { + page = new HtmlPage(ci.getFullyQualifiedType(), + outputDir,"index.html", + "Cadalyze Netlist Report"); + } + catch (IOException e) { + System.err.println("Couldn't create HTML report "+ + outputDir+"/index.html"); + System.err.println(e); + return; + } + + // Design info summary + printDesignInfo(page); + + // High-level area breakdown + page.section("Top-Level Area Breakdown"); + printCategoryBreakdown(page); + + // High-level node analysis + page.section("Top-Level Node Statistics"); + printNodeStats(page); + + // Leaf cell statistics + page.section("Leaf Cell Analyses"); + ArrayList lnklist = new ArrayList(); + printLeafCells(); + lnklist.add(new Pair("leafcells.html","Leaf Cell Categorizations")); + for (Iterator ai=areaCategories.iterator(); ai.hasNext();) { + // Generate and link to sub-report page + AreaCategory areaCat = (AreaCategory) ai.next(); + if (areaCat.leafStats.getTransistorCount() > 0) { + areaCat.leafStats.printHtmlStatsReport( + ci.getFullyQualifiedType(), + outputDir, areaCat.htmlFileName(), + areaCat.description+" Leaf Cells"); + lnklist.add(new Pair(areaCat.htmlFileName(), + areaCat.description + " leaf cells")); + } + } + page.listOfLinks(lnklist,false); + + // End page + page.close(); + } + + public void printDesignInfo(final HtmlPage page) { + + // Median length intermediate + String medLenStr = formFloat.format(medGateLength*1e6); + + page.section("Design Information"); + + page.summaryTable(); + String styleString; + switch (style) { + case 0: styleString = "Asynchronous"; break; + case 1: styleString = "Synchronous"; break; + case 2: styleString = "Mixed"; break; + default: styleString = "Unknown"; + } + page.summaryTableLine("Design style:",styleString); + page.summaryTableLine("Number of transistors (folded):", + String.valueOf(allCategories.leafStats + .getUnfoldedTransistorCount()) + " (" + + String.valueOf(allCategories.leafStats + .getTransistorCount()) + ")"); + page.summaryTableLine("Number of unique leaf cells (fragments):", + String.valueOf(fragLeafCnt+nonFragLeafCnt)+" ("+ + String.valueOf(fragLeafCnt)+")"); + page.summaryTableLine("Average transistor width:", + formFloat.format(allCategories.leafStats + .getAverageTransistorWidth()*1e6)+" um"); + page.summaryTableLine("Average non-staticizer transistor width:", + formFloat.format(allCategories.leafStats.getAverageTransistorWidth( + NetGraphAnalyzer.EdgeType.getNonStaticizerTypes())*1e6)+" um"); + page.summaryTableLine("Median transistor length:",medLenStr+" um"); + page.summaryTableLine("Total transistor area:", + formFloat.format(allCategories.leafStats + .getTransistorArea()*1e12)+" um^2"); + page.summaryTableLine("Average drive strength per node:", + formFloat.format(allCategories.nodeProps + .getAverageDriveStrength())); + page.summaryTableLine("Average leaf cell connections per mid-level node:", + formFloat.format(allCategories.nodeProps + .getAverageConnections())); + page.summaryTableLine("Average transistor fanout per node:", + formFloat.format(allCategories.nodeProps + .getAverageTransistorFanout())); + page.summaryTableLine("Average gate load per node (per "+medLenStr+ + " um length):", + formFloat.format(allCategories.nodeProps + .getGateLoadPerLength(medGateLength)*1e6)+" um"); + + page.summaryTableEnd(); + } + + public void printCategoryBreakdown(final HtmlPage page) { + // Start report table + List cols = new ArrayList(); + cols.add(new Pair("Category",Boolean.FALSE)); + cols.add(new Pair("Average Transistor Width",Boolean.TRUE)); + cols.add(new Pair("Transistor Count",Boolean.TRUE)); + cols.add(new Pair("Transistor Area",Boolean.TRUE)); + page.reportTableIndented(cols); + + // List each area category + Iterator ai=areaCategories.iterator(); + if (ai.hasNext()) { + AreaCategory allCat = (AreaCategory) ai.next(); + assert allCat.description.equals("All"); + while (ai.hasNext()) { + AreaCategory areaCat = (AreaCategory) ai.next(); + if (areaCat.leafStats.getTransistorCount() == 0) continue; + //cols = new ArrayList(); + //cols.add(areaCat.description); + cols = areaCat.reportTableLineStart(); + cols.add(formFloat.format((float)areaCat.leafStats + .getAverageTransistorWidth()*1e6)+" um"); + cols.add(formPercent.format( + (float)areaCat.leafStats.getTransistorCount()/ + areaCat.parentAreaCategory + .leafStats.getTransistorCount())); + cols.add(formPercent.format( + areaCat.leafStats.getTransistorArea()/ + areaCat.parentAreaCategory + .leafStats.getTransistorArea())); + page.reportTableLine(cols); + } + } + page.reportTableEnd(); + } + + public void printNodeStats(final HtmlPage page) { + // Start report table + List cols = new ArrayList(); + cols.add(new Pair("Category",Boolean.FALSE)); + cols.add(new Pair("Average Drive Strength",Boolean.TRUE)); + cols.add(new Pair("Average Transistor Fanout",Boolean.TRUE)); + cols.add(new Pair("Average Gate Load",Boolean.TRUE)); + page.reportTableIndented(cols); + + // List each area category + AreaCategory allCat = null; + Iterator ai=areaCategories.iterator(); + if (ai.hasNext()) { + allCat = (AreaCategory) ai.next(); + assert allCat.description.equals("All"); + while (ai.hasNext()) { + AreaCategory areaCat = (AreaCategory) ai.next(); + if (areaCat.leafStats.getTransistorCount() == 0) continue; + cols = areaCat.reportTableLineStart(); + //cols = new ArrayList(); + //cols.add(areaCat.description); + cols.add(formFloat.format((float)areaCat.nodeProps + .getAverageDriveStrength())); + cols.add(formFloat.format(areaCat.nodeProps + .getAverageTransistorFanout())); + cols.add(formFloat.format((float)areaCat.nodeProps + .getGateLoadPerLength(medGateLength)*1e6)+" um"); + page.reportTableLine(cols); + } + } + page.reportTableEnd(); + allCat.nodeProps.printHtmlDistributions(page,medGateLength); + } + + /** Prints a list of all leaf cells in the design **/ + public void printLeafCells() { + HtmlPage page = null; + try { + page = new HtmlPage(ci.getFullyQualifiedType(), + outputDir,"leafcells.html", + "Leaf Cell Categorizations"); + } + catch (IOException e) { + System.err.println("Couldn't write "+outputDir+"/leafcells.html"); + System.err.println(e); + } + ArrayList cols = new ArrayList(); + cols.add(new Pair("Cell",Boolean.FALSE)); + cols.add(new Pair("Category",Boolean.TRUE)); + cols.add(new Pair("Style",Boolean.TRUE)); + cols.add(new Pair("Instance Count",Boolean.TRUE)); + cols.add(new Pair("Ave Width (um)",Boolean.TRUE)); + cols.add(new Pair("Area Contribution (um^2)",Boolean.TRUE)); + page.reportTable(cols); + for (Iterator ct = getSortedLeafSet().iterator(); ct.hasNext();) { + Cell cell = (Cell) ct.next(); + cols = new ArrayList(); + cols.add(""+ + cell.getName()+""); + cols.add(cell.getCategory().toString()); + cols.add((cell.isSynchronous() ? "S" : "A") + + (cell.isFragment() ? "*" : "")); + cols.add(String.valueOf(cell.getInstanceCount())); + cols.add(formFloat.format(cell.getLeafStats() + .getAverageTransistorWidth()*1e6)); + cols.add(formFloat.format(cell.getInstanceCount() * + cell.getLeafStats().getTransistorArea() * 1e12)); + page.reportTableLine(cols); + } + page.reportTableEnd(); + page.writer.p(); + page.writer.println("* Fragment cell (Asynchronous only)"); + page.close(); + } + + /** Returns a list of all leaf cells, sorted by area contribution **/ + public SortedSet getSortedLeafSet() { + class LeafCompare implements Comparator { + public int compare(Object o1, Object o2) { + Cell c1 = (Cell) o1, c2 = (Cell) o2; + if (c1 == c2) return 0; + if (c2.getInstanceCount() * + c2.getLeafStats().getTransistorArea() * 1e12 - + c1.getInstanceCount() * + c1.getLeafStats().getTransistorArea() * 1e12 > 0.0) + return 1; + else return -1; + } + } + TreeSet set = new TreeSet(new LeafCompare()); + set.addAll(leafSet); + assert set.size() == leafSet.size(); + return set; + } + + /** For debug **/ + private void printSubcellLists(final PrintStream ps) { + for (Iterator cit = fqcnToCellMap.values().iterator(); cit.hasNext();) { + Cell cell = (Cell) cit.next(); + if (!cell.getSubcellSet().isEmpty()) { + ps.println("Subcells of "+cell.getName()+ + (cell.isSynchronous() ? "[s]" : "")); + for (Iterator scit=cell.getSubcellSet().iterator(); + scit.hasNext();) { + Cell subCell = (Cell) scit.next(); + ps.print(" "+subCell.getName()+ + (cell.isLeaf() ? "[L]" : "") + "("+ + cell.getSubcellInstanceCount(subCell)+"/"+ + subCell.getInstanceCount()+")"); + } + ps.println(""); + } + } + } + + private void debugPrintln(final String s) { + if (debug) System.err.println(s); + } + + private void debugPrint(final String s) { + if (debug) System.err.print(s); + } + + /***************************** STATIC METHODS *****************************/ + + private static DecimalFormat formPercent = + (DecimalFormat)DecimalFormat.getInstance(); + + private static DecimalFormat formFloat = + (DecimalFormat)DecimalFormat.getInstance(); + + static { + formPercent.applyPattern("#0.0%"); + formFloat.applyPattern("#0.00"); + } + + /** Very common HTML snippet **/ + private static void printTableReportLine(HtmlWriter page, + String desc, String val) { + page.tr(); page.td(); + page.println(desc); + page.tdEnd(); page.td(); + page.println(val); + page.tdEnd(); page.trEnd(); + } + + private static void printTableReportLine(HtmlWriter page, + String desc, int val) { + printTableReportLine(page,desc,String.valueOf(val)); + } + + private static void printPageHeader(HtmlWriter page, String title) { + page.html(); page.head(); page.title(); + page.println(title); + page.titleEnd(); + page.headEnd(); page.body(); + } + + private static final String usageString = +"Usage: java "+Cadalyze.class.getName()+"\n" + +" [--debug=0|1] Enable debug output (0)\n" + +" [--verbose=0|1] Enable verbose output (0)\n" + +" [--output-dir=

    ] Directory to which all output files are\n"+ +" written (.)\n"+ +" [--cast-path=] Standard cast path (.)\n" + +" fqcn Cell to analyze\n\n"; + + /** Command-line usage **/ + private static void usage_exit(final int exitStatus) { + System.err.println(usageString); + System.exit(exitStatus); + } + + /** Main **/ + public static void main(String[] args) { + try { + boolean verbose = false; + boolean debug = false; + + final CommandLineArgs parsedArgs = + new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + final CommandLineArgs theArgs = cachedArgs; + + if (theArgs.argExists("version")) { + System.out.println( com.avlsi.util.debug.VersionInfo + .getVersionString(Cadalyze.class)); + } + + if (theArgs.getArgValue("verbose","").equals("1")) { + verbose = true; + } + + if (theArgs.getArgValue("debug","").equals("1")) { + debug = true; + } + + String outputDir = theArgs.getArgValue("output-dir","."); + + final FileSearchPath castPath = + new FileSearchPath( theArgs.getArgValue( "cast-path", "." ) ); + + final String gateString = theArgs.getArgValue("gates", null); + List gateList = null; + if (gateString != null) + gateList = Arrays.asList(gateString.split(":")); + + final String lfilesString = theArgs.getArgValue("layout-info",null); + List layoutInfoFiles = null; + if (lfilesString != null) + layoutInfoFiles = Arrays.asList(lfilesString.split(":")); + + final StringContainerIterator strIter = + theArgs.nonParsedArgumentsIterator(); + if (!strIter.hasNext()) usage_exit(1); + final String castCellName = strIter.next(); + if (strIter.hasNext()) usage_exit(1); + + final CastFileParser cfp = new CastFileParser(castPath,"2"); + + if (verbose) System.err.println("Parsing "+castCellName+"..."); + final CellInterface cell = + cfp.getFullyQualifiedCell(castCellName); + + final Cadalyze design = new Cadalyze(cell,cfp,gateList, + layoutInfoFiles, + outputDir,debug); + + design.analyze(verbose); + if (debug) { + System.out.println("Subcell listing:"); + design.printSubcellLists(System.out); + } + if (verbose) System.err.println("Generating HTML reports..."); + design.printCellReports(); + design.printReport(verbose); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cell.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cell.java new file mode 100644 index 0000000000..004ec73758 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/Cell.java @@ -0,0 +1,943 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadalyze; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TreeSet; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.tools.cadalyze.NetGraphAnalyzer.CellType; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.lvs.NetGraph.NetNode; +import com.avlsi.tools.lvs.NetGraph.NetEdge; +import com.avlsi.tools.lvs.NetGraph.NetPath; +import com.avlsi.tools.lvs.PrsToNet; + + +/** + * Class to contain Cadalyze cell statistics & other data. + * @author Mike Davies + * @version $Revision$ $Date$ + **/ +public final class Cell { + + /*************************** STATIC DATA MEMBERS **************************/ + + /** Print lots of debugging information? Used by debugPrintln() **/ + public static boolean debug = false; + + private static String stdAsyncChannelType = + "standard.channel.asynchronous_channel"; + + private static String dpuFragmentTypes[] = { + "standard.base.DPU_DYB", "standard.base.DPU_BIT", + "standard.base.DPU_CTRL" + }; + + /** Cached standard.e1of CellInterface **/ + private static CellInterface stdAsyncChannel = null; + + /** Cached standard.base.DPU_DYB etc. CellInterfaces **/ + private static CellInterface[] dpuFragmentCells = null; + + /****************************** DATA MEMBERS ******************************/ + + /** Constants to identify cell design style type **/ + public static final int UNKNOWN = -1; + public static final int ASYNCHRONOUS = 0; + public static final int SYNCHRONOUS = 1; + public static final int OTHER = 2; + + /** Helper class to encapsulate cell category type constants **/ + public static class Category { + public static final int UNKNOWN = -1; + + /** Asynchronous cell types **/ + public static final int ASYNC = 0; // (unspecified/logic) + public static final int BUFFER = 1; + public static final int SMRBUF = 2; + public static final int SLACK = 3; + public static final int RESET = 4; + public static final int ACK = 5; + public static final int SRAM10E = 6; + public static final int SRAM10B = 7; + public static final int SRAM6E = 8; + public static final int SRAM6B = 9; + public static final int SRAM = 10; + public static final int XBAR = 11; + public static final int CSR = 12; + public static final int DFT = 13; + public static final int SERIAL = 14; // (non-CSR, non-DFT) + + /** Synchronous cell types **/ + public static final int SYNC = 20; // (unspecified/logic) + public static final int SYNCBUF = 21; + public static final int DFF = 22; + public static final int LATCH = 23; + + private static final int syncOffset = SYNC; + + /** Other, whatever that may be **/ + public static final int OTHER = 30; + + /** Cell type **/ + int index; + + static final int highLevelFragmentTypes[] = { RESET }; + static final String asyncCategoryDescriptions[] = { + "Logic", "Buffer", "S/M/R Buffer", "Slack", "Reset", + "Ack", "SRAM 10T", "SRAM 10T Bit", + "SRAM 6T", "SRAM 6T Bit", "SRAM (Other)", "Crossbar", + "CSR", "DFT", "Serial (Other)" + }; + static final String syncCategoryDescriptions[] = { + "Logic", "Buffer", "Flip-Flop", "Latch" + }; + + /** Uninitialized constructor only for use within class **/ + Category() { index = UNKNOWN; } + + /** General use constructor **/ + public Category(int c) { index = c; } + + public boolean isAsynchronous() { + return index != UNKNOWN && index != OTHER && index < syncOffset; + } + public boolean isSynchronous() { + return index != UNKNOWN && index != OTHER && index >= syncOffset; + } + public boolean isHighLevelFragment() { + for (int i=0; i) **/ + public static List getMajorAsyncCategories() { + List catList = new ArrayList(); + + catList.add(new Pair("Logic", new Category[] { + new Category(ASYNC) })); + + catList.add(new Pair("Buffering", new Category[] { + new Category(BUFFER), + new Category(SMRBUF), + new Category(SLACK) })); + + catList.add(new Pair("SRAM", new Category[] { + new Category(SRAM10E), + new Category(SRAM10B), + new Category(SRAM6E), + new Category(SRAM6B), + new Category(SRAM) })); + + catList.add(new Pair("Crossbar", new Category[] { + new Category(XBAR) })); + + catList.add(new Pair("Serial", new Category[] { + new Category(CSR), + new Category(DFT), + new Category(SERIAL) })); + + catList.add(new Pair("Other", new Category[] { + new Category(ACK), + new Category(RESET) })); + + return catList; + } + + public static List getMajorSyncCategories() { + List catList = new ArrayList(); + + catList.add(new Pair("Logic", new Category[] { + new Category(SYNC) })); + + catList.add(new Pair("Buffering", new Category[] { + new Category(SYNCBUF) })); + + catList.add(new Pair("Registers", new Category[] { + new Category(DFF), + new Category(LATCH) })); + + return catList; + } + + public static List getOtherCategories() { + List catList = new ArrayList(); + catList.add(new Pair("Other", new Category[] { + new Category(OTHER) })); + return catList; + } + + /** Buffer, slack, etc. categories **/ + public static Collection getSyncBufferCategories() { + ArrayList list = new ArrayList(); + list.add(new Category(SYNCBUF)); + return list; + } + + /** Non-logic and non-buffer categories **/ + public static Collection getFlopCategories() { + ArrayList list = new ArrayList(); + list.add(new Category(DFF)); + list.add(new Category(LATCH)); + return list; + } + + public static Collection getSyncLogicCategories() { + ArrayList list = new ArrayList(); + list.add(new Category(SYNC)); + return list; + } + + public int hashCode() { return index; } + public boolean equals(Object c) { + return c instanceof Category && + index == ((Category)c).index; + } + public String toString() { + if (isAsynchronous()) return asyncCategoryDescriptions[index]; + if (isSynchronous()) + return syncCategoryDescriptions[index-syncOffset]; + if (index == OTHER) return "Other"; + return "Unknown"; + } + + public String styleString() { + if (isAsynchronous()) return "Asynchronous"; + if (isSynchronous()) return "Synchronous"; + if (index == OTHER) return "Other"; + return "Unknown"; + } + } + + /** Cell type **/ + private Category category; + + /** CellInterface for this cell **/ + private final CellInterface ci; + + /** CadenceInfo for this cell **/ + private final CadenceInfo cinfo; + + /** + * Map of parent cell category to instance count. This is + * maintained as a map since, for example, buffers instantiated + * within slack cells or srams need to be accounted for differently + * from isolated buffers. + **/ + private Map instCountByCategory = null; + + /** + * Is this cell a leaf? For purposes of Cadalyze, a leaf is defined + * as follows: + * If asynchronous: All port nodes belong to channel defchans AND + * the cell contains no subcells whose port nodes all belong to + * channel defchans; OR has bare nodes or nodes belonging to + * non-channel defchans in its port list AND has no subcells. + * In the latter case, isFragment will be true. + * + * If synchronous: The cell has no subcells. + **/ + private boolean leaf; + + /** Is this cell a fragment? (See leaf for definition) **/ + private boolean fragment; + + /** Is this cell a datapath unit cell constituent (e.g. DPU_DYB) **/ + private boolean dpuFragment = false; + + /** + * Is this an inlined cell? The same cell that is instantiated in + * the design in both inlined and non-inlined forms will have two + * distinct Cell objects. + **/ + private boolean inlined; + + /** This cell's LeafStats, obtained from NetGraphAnalyzer **/ + private LeafStats leafStats = null; + + /** This cell's CellType, as reported by NetGraphAnalyzer **/ + private CellType cellType = null; + + /** This cell's local node count **/ + private int localNodeCount; + + /** Subcell Cell-to-Set instance map **/ + private final Map subcellInstNameMap; + + /** Subcell instance HierName-to-Cell map (subcellInstNameMap^-1) **/ + private final Map instNameToCellMap; + + /** HierName-to-NodeProps map **/ + private Map nodePropsMap = null; + + /** Accumulated local node properties of this cell **/ + private NodeProps localNodeProps = null; + + /***************************** CLASS METHODS *****************************/ + + /** Constructor **/ + public Cell(final CellInterface ci, final CadenceInfo cinfo, + final Map subcellInstNameMap, + final Map instNameToCellMap) { + this.ci = ci; + this.cinfo = cinfo; + this.subcellInstNameMap = subcellInstNameMap; + this.instNameToCellMap = instNameToCellMap; + this.instCountByCategory = new HashMap(); + setProperties(); + } + + /** + * Constructor helper; Sets the cell's design style type, fragment & + * dpuFragment properties, and category type. + **/ + private void setProperties() { + + String fqcn = ci.getFullyQualifiedType(); + + // Asynchronous or synchronous? (rely on synchronous directive) + int designStyleType = ASYNCHRONOUS; + if (((Boolean)DirectiveUtils.getTopLevelDirective(ci, + DirectiveConstants.SYNCHRONOUS)).booleanValue()) + designStyleType = SYNCHRONOUS; + if (fqcn.startsWith("vendor.") && designStyleType != SYNCHRONOUS) + designStyleType = OTHER; + + // Are all port types asynchronous e1ofN channels? + fragment = (designStyleType == ASYNCHRONOUS ? + !ci.allPortSubcellsRefineFrom(stdAsyncChannel) : false); + + // Set dpuFragment (check if the cell refines from + // DPU_DYB, DPU_BIT, or DPU_CTRL) + for (int i=0; i B (type2) -> C + * -> C + * D -> B (type2) -> C + * + * (A instantiates a B which instantiates a C, and D instnatiates a + * B which instantiates a C), "C" will be counted twice under type1 + * and only once under type2. (In the first instantiation of C, the + * type1 of A overrides the type2 classification of B.) + **/ + public int getInstanceCountInCategory(final Category cat) { + Integer cnt = ((Integer)instCountByCategory.get(cat)); + return cnt == null ? 0 : cnt.intValue(); + } + + /** catSet==null causes total instance count to be returned **/ + public int getInstanceCountInCategories(final Collection catSet) { + int sum = 0; + for (Iterator ci=instCountByCategory.keySet().iterator(); + ci.hasNext();) { + Category c = (Category)ci.next(); + if (catSet == null || catSet.contains(c)) + sum += ((Integer)instCountByCategory.get(c)).intValue(); + } + return sum; + } + + /** Returns leaf cell statistics, if they exist **/ + public LeafStats getLeafStats() { + return leafStats; + //if (netgraphAnalyzer != null) return netgraphAnalyzer.getLeafStats(); + //else return null; + } + + /** Checks if this is a high-level fragment type (e.g. RAMP_RESET) **/ + public boolean isHighLevelFragment() { + return fragment && category.isHighLevelFragment(); + } + + /** For debug **/ + public Iterator getSubcellPairs() { return ci.getSubcellPairs(); } + + /** Returns the set of all of this cell's subcells **/ + public final Set getSubcellSet() { return subcellInstNameMap.keySet(); } + + /** Returns local instance count of specified subcell **/ + public int getSubcellInstanceCount(final Cell cell) { + Set instNameSet = (Set)subcellInstNameMap.get(cell); + return instNameSet == null ? 0 : instNameSet.size(); + } + + /** + * Construct the cell's netgraph (if possible), study it with + * NetGraphAnalyzer, extract relevant info, and then free + * the associated memory. + **/ + public void analyzeNetGraph(final CastFileParser cfp, final LayoutInfo li) { + // Construct NetGraph + NetGraph netgraph = null; + if (leaf && ci.hasNetlistBody()) { + try { + netgraph = PrsToNet.getNetGraph(ci,cfp,null,null,null,null); + } + catch (Exception e) { + System.err.println("Warning: Couldn't build NetGraph "+ + "for cell "+getName()); + System.err.println(e); + netgraph = null; + } + } + if (netgraph == null) return; + + // Set input CellType to include what information we have + cellType = new CellType(); + if (category.isAsynchronous()) { + if (fragment) { + if (category.index == Category.RESET) + cellType.setType(CellType.RESET); + else if (category.index == Category.ACK) + cellType.setType(CellType.ACK); + else { + // XBAR, SRAM, etc. + cellType.setType(CellType.OTHER); + } + } + } + else cellType.setType(CellType.OTHER); + + // Have NetGraphAnalyzer take a look + NetGraphAnalyzer netgraphAnalyzer = + new NetGraphAnalyzer(ci,netgraph,cellType); + nodePropsMap = netgraphAnalyzer.analyzeCell(); + leafStats = netgraphAnalyzer.getLeafStats(); + leafStats.setLayoutProperties(li,getName().toString()); + cellType = netgraphAnalyzer.getCellType(); + } + + /** + * Sets node properties of all local nodes of all cells in the + * hierarchy, including this one. This cell's port nodes are treated + * specially; they are set to be non-local if they only connect to + * a single leaf cell or if they are either undriven or unloaded. + * (All other nodes in a particular subcell type are set to be local + * iff the node is not connected to any parent node in any instantiation + * of that cell.) + **/ + public void setNodeProperties() { + // Set nodePropsMap in all subcells + setNodePropsRecursively(); + + // For the top level cell ONLY, explicitly make single-connection + // nodes non-local. + for (Iterator ni=nodePropsMap.entrySet().iterator(); ni.hasNext();) { + Entry entry = (Entry) ni.next(); + HierName name = (HierName) entry.getKey(); + NodeProps props = (NodeProps) entry.getValue(); + debugPrintln("Port node "+name+": "+props.getNumConnections()+ + " connections"); + if (((AliasedMap) cinfo.getPortNodes()).contains(name) && + (props.getNumConnections() <= 1 || + !props.isDriven() || !props.isLoaded())) { + props.setNonLocal(); + } + } + } + + /** Private recursive workhorse function for setNodeProps() **/ + private void setNodePropsRecursively() { + if (nodePropsMap != null) return; + + debugPrintln("Setting node properties of "+getName()); + nodePropsMap = new HashMap(); + + // Descend down to subcells -- build nodePropsMap bottom-up + for (Iterator sci=subcellInstNameMap.keySet().iterator(); + sci.hasNext();) { + + // Set the subcell's NodeProps + Cell subcell = (Cell) sci.next(); + subcell.setNodePropsRecursively(); + + // Get all instance names of this subcell type + Set instNameSet = (Set) subcellInstNameMap.get(subcell); + + // Connect all ports of this subcell type + AliasedMap ports = subcell.cinfo.getPortNodes(); + for (Iterator pi=ports.getCanonicalKeys(); pi.hasNext();) { + HierName portName = (HierName) pi.next(); + // Skip if port not used by the subcell + if (Boolean.FALSE.equals(ports.getValue(portName))) continue; + + // Look up the NodeProps of this port of the subcell + NodeProps portProps = + (NodeProps) subcell.nodePropsMap.get(portName); + if (portProps == null) continue; // Vdd, GND + + // Connect this port of all instances of this subcell type + for (Iterator ni=instNameSet.iterator(); ni.hasNext();) { + HierName instName = (HierName) ni.next(); + HierName nodeName = HierName.append(instName,portName); + HierName cnodeName= (HierName) + cinfo.getLocalNodes().getCanonicalKey(nodeName); + if (cnodeName == null) { + debugPrintln(" Couldn't find canonical alias of "+portName+" of "+ + "instance "+instName+" ("+nodeName+") "+ + "in type "+subcell.getName()+")"); + continue; + } + NodeProps nodeProps = + (NodeProps) nodePropsMap.get(cnodeName); + if (nodeProps == null) { + nodeProps = new NodeProps(); + nodePropsMap.put(cnodeName,nodeProps); + } + nodeProps.connectNode(portProps); + //debugPrintln(getName()+": Connecting "+cnodeName+" to "+ + // nodeName+" ("+portName+") of cell type "+ + // subcell.getName()); + } + } + } + } + + /** + * To be called after setNodeProps has ben called on the top-level cell. + * (Warning: will call setNodeProps() if it hasn't already been called.) + * This method tallies properties of the cell's local nodes. + **/ + public NodeProps getLocalNodeProps() { + if (nodePropsMap == null) setNodeProperties(); + if (localNodeProps != null) return localNodeProps; + + localNodeProps = new NodeProps(); + + for (Iterator npi=nodePropsMap.entrySet().iterator(); npi.hasNext();) { + Entry entry = (Entry) npi.next(); + NodeProps node = (NodeProps) entry.getValue(); + if (node.isLocal()) localNodeProps.accumulateNode(node); + else debugPrintln(" Not local: "+(HierName)entry.getKey()); + } + debugPrintln("Cell "+getName()+": "+localNodeProps.getNumNodes()+ + " local nodes accumulated."); + debugPrintln(" aveDriveStrength="+localNodeProps.getAverageDriveStrength()); + debugPrintln(" numConnections="+localNodeProps.getNumConnections()+ + " ("+localNodeProps.numLocalLeafNodes+" local nodes)"); + return localNodeProps; + } + + + /** Generates an HTML leaf cell report page for this cell **/ + public void printHtmlReport(String designName, String outputDir, + float medGateLength) { + HtmlPage page; + try { + page = new HtmlPage(designName,outputDir,getName()+".html", + getName()); + } + catch (IOException e) { + System.err.println("Couldn't create HTML page "+outputDir+"/"+ + getName()); + System.err.println(e); + return; + } + // General info table + page.summaryTable(); + page.summaryTableLine("Design style:",category.styleString()); + page.summaryTableLine("Cell category:",category.toString()); + page.summaryTableLine("Instance count:",getInstanceCount()); + page.summaryTableLine("Fragment:", fragment ? "Yes" : "No"); + if (cellType != null) cellType.toHtml(page); + page.summaryTableEnd(); + + // Standard LeafStats info + if (leafStats != null) leafStats.printHtmlStats(page); + + // Output any cell anomalies + if (cellType != null) { + page.section("Analysis Warnings"); + cellType.printHtmlAnomalyList(page); + } + + if (localNodeProps != null) { + page.section("Local Node Statistics"); + localNodeProps.printHtmlStats(page,medGateLength); + } + + // Print subcell list + if (subcellInstNameMap.keySet().size() > 0) { + page.section("Subcells"); + List cols = new ArrayList(); + cols.add(new Pair("Subcell Type",Boolean.FALSE)); + cols.add(new Pair("Instance count",Boolean.TRUE)); + page.reportTable(cols); + for (Iterator pi=getSortedSubcellSet().iterator(); pi.hasNext();) { + Pair p = (Pair) pi.next(); + Cell subcell = (Cell) p.getFirst(); + int subcellInstCnt = ((Integer) p.getSecond()).intValue(); + cols = new ArrayList(); + cols.add(""+ + subcell.getName()+""); + cols.add(((Integer) p.getSecond()).toString()); + page.reportTableLine(cols); + } + page.reportTableEnd(); + } + + page.close(); + } + + /** + * Returns a list of subcells w/ instance counts (Pair), + * sorted by instance count + **/ + public SortedSet getSortedSubcellSet() { + class SubcellCompare implements Comparator { + public int compare(Object o1, Object o2) { + Pair p1 = (Pair) o1, p2 = (Pair) o2; + if (p1.getFirst() == p2.getFirst()) return 0; + if (((Integer)p2.getSecond()).intValue() > + ((Integer)p1.getSecond()).intValue()) + return 1; + else return -1; + } + } + TreeSet set = new TreeSet(new SubcellCompare()); + for (Iterator ei=subcellInstNameMap.entrySet().iterator(); + ei.hasNext();) { + Entry entry = (Entry) ei.next(); + set.add(new Pair(entry.getKey(), + new Integer(((Set) entry.getValue()).size()))); + } + return set; + } + + + + /***************************** STATIC METHODS *****************************/ + + private static void debugPrintln(final String s) { + if (debug) System.err.println(s); + } + + private static void debugPrint(final String s) { + if (debug) System.err.print(s); + } + + /** + * Adds this cell and its entire subcell tree to fqcnToCellMap. + * Guaranteed to not return null. If parentIsInlined, then + * this cell won't be added + **/ + private static Cell addCellToMap(final Cadencize cadencize, + final CellInterface ci, + final Map fqcnToCellMap) { + + String fqcn = ci.getFullyQualifiedType(); + debugPrintln("Adding "+fqcn); + + HashMap subcellInstNameMap = new HashMap(); + HashMap instNameToCellMap = new HashMap(); + + Cell cell = new Cell(ci,cadencize.convert(ci),subcellInstNameMap, + instNameToCellMap); + + debugPrintln(" category="+cell.getCategory()+" fragment="+ + cell.isFragment()); + + boolean containsSubcells = false; + boolean containsAllDpuFragmentSubcells = true; + + List dpuFragmentCells = new ArrayList(); + if (!ci.containsCompletePrs()) { + for (Iterator scit=ci.getAllSubcellPairs(); scit.hasNext();) { + Pair subcellPair = (Pair)scit.next(); + HierName name = (HierName) subcellPair.getFirst(); + CellInterface subci = (CellInterface) subcellPair.getSecond(); + + // Look up inline info + boolean subIsInlined = ci.isInlinedSubcell(name); + boolean subFromInlinedParent = ci.parentIsInlinedSubcell(name); + + // Skip non-prs cells and any inlined subcells + if (!subci.hasRealProductionRule() && !subci.hasNetlistBody() + || subIsInlined) continue; + + // Look up/create this subcell's Cell; this will probably + // be thrown out if it's inlined (or if this cell was inlined) + String subFqcn = subci.getFullyQualifiedType(); + Cell subCell = (Cell)fqcnToCellMap.get(subFqcn); + if (subCell == null) { + subCell = addCellToMap(cadencize, subci, fqcnToCellMap); + } + + containsSubcells = true; + containsAllDpuFragmentSubcells &= subCell.dpuFragment; + if (subCell.dpuFragment) dpuFragmentCells.add(subCell); + + // Update subcell instance count map + Set instNameSet = (Set) subcellInstNameMap.get(subCell); + if (instNameSet == null) { + instNameSet = new HashSet(); + instNameSet.add(name); + subcellInstNameMap.put(subCell,instNameSet); + } + else if (instNameSet != null) { + instNameSet.add(name); + } + instNameToCellMap.put(name,subCell); + } + } + cell.setLeaf(!cell.dpuFragment && + (!containsSubcells || + containsSubcells && containsAllDpuFragmentSubcells)); + + if (containsSubcells && !containsAllDpuFragmentSubcells && + dpuFragmentCells.size() > 0) { + // Corner case: a DPU fragment cell was used in a non-DPU + // environment (e.g. lib.sram.6T.ENV_4x4) + for (Iterator sci=dpuFragmentCells.iterator(); sci.hasNext();) { + ((Cell)sci.next()).setLeaf(true); + } + } + + debugPrintln(" leaf="+cell.isLeaf()); + + // Add the cell to fqcnToCell map + /*if (!skipAddToMap)*/fqcnToCellMap.put(fqcn,cell); + return cell; + } + + /** + * Recursively tallies instance counts of 'cell' and all of its subcells. + * The Category is "sticky" in the sense that as soon as it becomes + * non-"UNSPEC" it never changes again. Thus the highest level cell with + * an assigned Category overrides the categorization of any of its + * subcells. + **/ + private static void tallyInstanceCounts(final Cell cell, int cnt, + Category cat) { + if (cat.isUncategorized()) cat = cell.category; + cell.addToInstCount(cat,cnt); + for (Iterator scit=cell.subcellInstNameMap.entrySet().iterator(); + scit.hasNext();) { + Entry subcellEntry = (Entry) scit.next(); + tallyInstanceCounts((Cell)subcellEntry.getKey(), + cnt * ((Set)subcellEntry.getValue()).size(), cat); + } + } + + /** + * Recursively processes this cell and all of its subcells + * Returns a FQCN-to-Cell Map of all cells in + * the design. + **/ + public static Map processHierarchy(final CellInterface ci, + final CastFileParser cfp, + boolean verbose) + throws Exception { + Cadencize cadencize = new Cadencize(false); + HashMap fqcnToCellMap = new HashMap(); + if (verbose) System.err.println("Building cell hierarchy..."); + lookupBaseCells(cfp); + Cell cell = addCellToMap(cadencize,ci,fqcnToCellMap); + tallyInstanceCounts(cell,1,new Category()); + return fqcnToCellMap; + } + + /** + * Look up CellInterfaces of standard base cells that are needed + * during cell processing. + **/ + private static void lookupBaseCells(final CastFileParser cfp) + throws Exception { + if (stdAsyncChannel == null) + stdAsyncChannel = cfp.getFullyQualifiedCell(stdAsyncChannelType); + if (dpuFragmentCells == null) { + dpuFragmentCells = new CellInterface[dpuFragmentTypes.length]; + for (int i=0; i numBins) bin = numBins+1; + else bin = (int)binVal + 1; + count[bin]++; + total[bin] += value; + } + + void addDistribution(int cnt, final DoubleDistribution dist) { + assert min == dist.min && max == dist.max && numBins == dist.numBins; + for (int i=0; i"+formFloat.format(scale*max)); + page.writer.tdEnd(); + page.writer.trEnd(); + page.writer.tr(); + for (int i=0; i 0 ? t : 1; + g.setColor(barColor); + for (int i=0; i0) { + g.setColor(annotateColor); + g.drawString("("+formFloat.format(scale*(total[i]/count[i]))+ + ")", x + 4, 1+b-ph-4); + g.setColor(barColor); + } + x += dx; + } + // Vertical average value marker + g.setColor(annotateColor); + x = 1 + dx + (int) (numBins*dx * (getAverage()-min)/(max-min)); + if (x < 2) x = 2; + if (x > 1+dx+numBins*dx) x = (numBins+2)*dx; + g.drawLine(x,2,x,1+b); + + /** Write the image **/ + Iterator writers = ImageIO.getImageWritersBySuffix("png"); + try { + ImageWriter iw = (ImageWriter) writers.next(); + ImageOutputStream ios = + ImageIO.createImageOutputStream(new File(baseFileName+".png")); + iw.setOutput(ios); + iw.write(img); + iw.dispose(); + ios.close(); + img.flush(); + } + catch (Exception e) { + System.err.println("Could not write image "+baseFileName+".png:"); + System.err.println(e); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/HtmlPage.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/HtmlPage.java new file mode 100644 index 0000000000..e3d0b575ba --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/HtmlPage.java @@ -0,0 +1,218 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadalyze; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.avlsi.util.container.Pair; +import com.avlsi.util.htmlWriter.HtmlWriter; + + +/** + * HTML Page Generation Utility Class + * (builds on com.avlsi.util.htmlWriter.HtmlWriter) + * + * @author Mike Davies + * @version $Revision$ $Date$ + **/ +public final class HtmlPage { + + /***************************** INNER CLASSES *****************************/ + + + /***************************** DATA MEMBERS ******************************/ + + private static final String indexPage = "index.html"; + private static final String pageHeaderBgColor = "#dddddd"; + private static final String reportHeaderBgColor = "#eeeedd"; + private static final String reportIndentedRowColor = "#eeeeee"; + + /** Low-level HTML tag interface **/ + HtmlWriter writer = null; + + /** Top-level design name **/ + private String designName; + + /** HTML base directory **/ + private String baseDir; + + /** HTML page filename (under baseDir) **/ + private String pageName; + + /** Directory to which all output report files are written **/ + private String outputDir; + + /** Array of boolean values specifying whether to center each columnn **/ + boolean centerReportColumns[] = null; + + /***************************** CLASS METHODS *****************************/ + + /** Opens the page and writes the header **/ + public HtmlPage(String designName, String baseDir, String pageName, + String pageTitle) + throws IOException { + this.designName = designName; + this.baseDir = baseDir; + this.pageName = pageName; + writer = new HtmlWriter(baseDir + "/" + pageName, null); + pageHeader(pageTitle); + } + + /** For a file "path/name.html", returns "path/name" **/ + public String getPagePath() { + String pagePath = baseDir + "/" + pageName; + if (pagePath.endsWith(".html")) + pagePath = pagePath.substring(0,pagePath.length()-5); + return pagePath; + } + + private void pageHeader(String title) { + writer.html(); writer.head(); writer.title(); + writer.println(title); + writer.titleEnd(); + writer.headEnd(); writer.body(); + writer.table(0,"25%",4,0); + writer.tr(); + writer.print(""); + writer.bold(); + writer.print("Design: "+designName); + writer.boldEnd(); + writer.tdEnd(); writer.trEnd(); + writer.tableEnd(); + writer.h1(); writer.println(title); writer.h1End(); + } + + public void close() { + writer.hr(); + if (!pageName.equals(indexPage)) { + writer.print("["); + writer.aHref("index.html"); + writer.print("Main Report Page"); + writer.aEnd(); + writer.println("]"); + } + else { + writer.println("Report generated on "+new Date()); + } + writer.bodyEnd(); + writer.htmlEnd(); + writer.close(); + } + + public void section(String title) { + writer.h2(); writer.println(title); writer.h2End(); + } + + /** + * Begins a simple report table. headColumns is a list of + * Pair types; first element is the column string, + * second specifies whether the column text should be centered. + **/ + public void reportTable(final List headColumns) { + writer.table(1,"100%",2,2); + writer.tr(); + centerReportColumns = new boolean[headColumns.size()]; + int col=0; + for (Iterator hpi=headColumns.iterator(); hpi.hasNext(); col++) { + writer.print(""); + writer.bold(); + writer.println(text); + writer.boldEnd(); + writer.tdEnd(); + } + writer.trEnd(); + indentedTable = false; + } + + public void reportTableIndented(final List headColumns) { + reportTable(headColumns); + indentedTable = true; + } + + /** Are we in an indented report table? **/ + private boolean indentedTable; + + public void reportTableEnd() { writer.tableEnd(); } + + /** Prints a line of a report table. **/ + public void reportTableLine(final List columns) { + assert columns.size() == (centerReportColumns.length + + (indentedTable ? 1 : 0)); + Iterator ci = columns.iterator(); + if (indentedTable) { + if (((Boolean) ci.next()).equals(Boolean.TRUE)) + writer.print(""); + else + writer.tr(); + } + else { + writer.tr(); + } + for (int col=0; ci.hasNext() && col 0) System.err.println(" (Line "+lineNum+")"); + else System.err.println("."); + System.err.println(" Some or all layout info will be"+ + "missing."); + System.err.println(e); + } + catch (CDLRenameException e) { + System.err.println("Warning: Garbled cell name encountered in "+ + "file "+filename+" (Line "+lineNum+")"); + System.err.println(" Some or all layout info will be"+ + "missing."); + } + } + + /** + * Returns layout area, or -1.0 if no layout information exists for this + * cell. + **/ + public float getLayoutArea(String cell) { + float area = -1.0F; + LeafInfo linfo = (LeafInfo) leafMap.get(cell); + if (linfo != null) area = linfo.getBoundingBoxArea(); + else { + MidInfo minfo = (MidInfo) midMap.get(cell); + if (minfo != null) area = minfo.getMergedLeafArea(); + } + return area; + } + + /** + * Returns the cell's transistor density factor (top level area + * divided by the cell's given total transistor area). If the + * specified cell is a leaf cell, compares the calculated density + * factor to the one provided by 'density'. Warns (to System.err) + * if the values differ by more than 1%. If no cell information + * exists for the specified cell, -1.0 is returned. + **/ + public float getTransistorDensityFactor(String cell, float transistorArea) { + float dfactor = -1.0F; + LeafInfo linfo = (LeafInfo) leafMap.get(cell); + if (linfo != null) { + dfactor = linfo.getBoundingBoxArea() / transistorArea; + if (Math.abs(dfactor - linfo.getReportedDensityFactor()) > 0.01) { + System.err.println("Density factor mismatch in cell "+ + cell+":"); + System.err.println(" Calculated "+dfactor+ + ", 'density' reported "+ + linfo.getReportedDensityFactor()); + } + } + else { + MidInfo minfo = (MidInfo) midMap.get(cell); + if (minfo != null) + dfactor = minfo.getMergedLeafArea() / transistorArea; + } + return dfactor; + } + + /** + * Returns the cell's total area divided by the leaf cell prBound + * covering area. A value of 1.0 indicates perfect packing; larger + * values corresponding to less efficient box packing. If no cell + * information exists for the specified cell, -1.0 is returned. + **/ + public float getLeafPackingFactor(String cell) { + float pfactor = -1.0F; + MidInfo minfo = (MidInfo) midMap.get(cell); + if (minfo != null) + pfactor = minfo.getMergedLeafArea() / minfo.getLeafArea(); + else { + LeafInfo linfo = (LeafInfo) leafMap.get(cell); + if (linfo != null) pfactor = 1.0F; + } + return pfactor; + } + + /** Debug only **/ + private void printAllDensities() { + for (Iterator li=leafMap.entrySet().iterator(); li.hasNext();) { + Entry entry = (Entry) li.next(); + String cell = (String) entry.getKey(); + LeafInfo linfo = (LeafInfo) entry.getValue(); + System.out.println("LEAF: "+cell+" "+ + linfo.getReportedDensityFactor()); + } + for (Iterator mi=midMap.entrySet().iterator(); mi.hasNext();) { + Entry entry = (Entry) mi.next(); + String cell = (String) entry.getKey(); + //MidInfo minfo = (MidInfo) entry.getValue(); + System.out.println("MID: "+cell+" "+ getLeafPackingFactor(cell)); + } + } + + /***************************** STATIC METHODS ****************************/ + + public static void main(String[] args) { + LayoutInfo layoutInfo = new LayoutInfo(Arrays.asList(args)); + layoutInfo.printAllDensities(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/LeafStats.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/LeafStats.java new file mode 100644 index 0000000000..9001184e5b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/LeafStats.java @@ -0,0 +1,658 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadalyze; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.SortedMap; +import java.util.StringTokenizer; +import java.util.TreeMap; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.htmlWriter.HtmlWriter; + +import com.avlsi.tools.cadalyze.NetGraphAnalyzer.EdgeType; +import com.avlsi.tools.cadalyze.NetGraphAnalyzer.NodeType; +import com.avlsi.tools.lvs.NetGraph; + +public final class LeafStats { + + int numNMOS; // Number of NMOS transistors not in gates + int numPMOS; // Number of PMOS transistors not in gates + int numGateNMOS; // Number of NMOS transistors in gates + int numGatePMOS; // Number of PMOS transistors in gates + int numGates; // Number of gates in the cell + int numStaticizers; // Number of staticizers in the cell + int numUnfoldedEdges; // Transistor count adjusted for folding + + float areaNMOS; // Gate area of NMOS transistors not in gates + float areaPMOS; // Gate area of PMOS transistors not in gates + float areaGateNMOS; // Gate area of NMOS transistors in gates + float areaGatePMOS; // Gate area of PMOS transistors in gates + + Map nodeTypeCounts; + Map edgeTypeCounts; + Map edgeTypeCountsUnfolded; + Map edgeTypeAreas; + Map edgeTypeWidths; + + SortedMap lengthCounts; // transistor length [nm] -> count map + + float unclassifiedFraction; + + float logicEfficiency; // Set by printHtmlStats (should be elsewhere) + + /** !=1 only when the LeafStats represents a leaf cell group **/ + private int numCells; + + /** Layout bounding box area **/ + double layoutArea = -1.0F; + + /** Layout density factor **/ + float densityFactor = -1.0F; + + /** Accumulated transistor area of cells with layout info **/ + double layoutTransistorArea = 0.0; + + /** Number of cells with layout info **/ + int cellsWithLayoutInfo = 0; + + /** True if this LeafStats represents an aggregation of cell statistics **/ + private boolean aggegatedStats; + + /** Returns the total number of transistors in this leaf cell **/ + public int getTransistorCount() { + return numNMOS + numPMOS + numGateNMOS + numGatePMOS; + } + + /** Returns the total number of transistors, adjusted for folding **/ + public int getUnfoldedTransistorCount() { return numUnfoldedEdges; } + + /** Returns the total transistor area in this leaf cell **/ + public float getTransistorArea() { + return areaNMOS + areaPMOS + areaGateNMOS + areaGatePMOS; + } + + public int getNumNMOS() { return numNMOS+numGateNMOS; } + public int getNumPMOS() { return numPMOS+numGatePMOS; } + public int getNumStaticizers() { return numStaticizers; } + public float getAreaNMOS() { return areaNMOS+areaGateNMOS; } + public float getAreaPMOS() { return areaPMOS+areaGatePMOS; } + + /** Returns total node count **/ + public int getNodeCount() { + int total = 0; + for (Iterator ci=nodeTypeCounts.values().iterator(); ci.hasNext();) { + Integer cnt = (Integer)ci.next(); + total += (cnt==null ? 0 : cnt.intValue()); + } + return total; + } + + /** Returns node count of the given NodeType **/ + public int getNodeTypeCount(final NodeType type) { + Integer cnt = (Integer)nodeTypeCounts.get(type); + return cnt==null ? 0 : cnt.intValue(); + } + + /** Returns edge count of the given EdgeType **/ + public int getEdgeTypeCount(final EdgeType type) { + Integer cnt = (Integer)edgeTypeCounts.get(type); + return cnt==null ? 0 : cnt.intValue(); + } + + /** Returns unfolded edge count of the given EdgeType **/ + public int getEdgeTypeCountUnfolded(final EdgeType type) { + Double cnt = (Double)edgeTypeCountsUnfolded.get(type); + return cnt==null ? 0 : cnt.intValue(); + } + + /** Returns total area of the given EdgeType **/ + public float getEdgeTypeArea(final EdgeType type) { + Double area = (Double)edgeTypeAreas.get(type); + return area==null ? 0 : area.floatValue(); + } + + /** Returns total transistor width of the given EdgeType **/ + public float getEdgeTypeWidth(final EdgeType type) { + Double width = (Double)edgeTypeWidths.get(type); + return width==null ? 0 : width.floatValue(); + } + + /** Returns the average (unfolded) transistor width of all edges **/ + public float getAverageTransistorWidth() { + double totalWidth = 0.0; + for (Iterator wi=edgeTypeWidths.values().iterator(); wi.hasNext();) { + totalWidth += ((Double)wi.next()).doubleValue(); + } + return (float)totalWidth/getUnfoldedTransistorCount(); + } + + /** + * Returns the average (unfolded) transistor width of edges belonging + * to any of the types in 'edgeTypes'. + **/ + public float getAverageTransistorWidth(final Collection edgeTypes) { + double totalWidth = 0.0; + double totalCnt = 0.0; + for (Iterator ti=edgeTypes.iterator(); ti.hasNext();) { + EdgeType type = (EdgeType) ti.next(); + Double cnt = (Double) edgeTypeCountsUnfolded.get(type); + if (cnt != null) { + totalCnt += cnt.doubleValue(); + totalWidth += ((Double)edgeTypeWidths.get(type)).doubleValue(); + } + } + return totalCnt == 0.0 ? 0.0F : (float)(totalWidth / totalCnt); + } + + /** Returns the fraction of nodes that couldn't be classified **/ + public float getUnclassifiedNodeFraction() { + Integer cnt = + (Integer)nodeTypeCounts.get(new NodeType(NodeType.UNCLASSIFIED)); + if (cnt != null && (cnt.intValue() > 0) + || unclassifiedFraction == -1.0F) { + int total = getNodeCount(); + unclassifiedFraction = + cnt==null || total==0 ? 0.0F : cnt.floatValue() / total; + } + return unclassifiedFraction; + } + + /** Returns the median transistor legnth, in meters. **/ + public float getMedianTransistorLength() { + int medianCount = getTransistorCount() / 2; + for (Iterator li=lengthCounts.entrySet().iterator(); li.hasNext();) { + Entry entry = (Entry) li.next(); + medianCount -= ((Integer) entry.getValue()).intValue(); + if (medianCount <= 0) + return ((Integer) entry.getKey()).floatValue() * 1e-9F; + } + // Should never get this case! (Unless no transistors) + return -1.0e-6F; + } + + /** Reclassify unclassified node and edge counts to "OTHER" **/ + public void convertUnclassifiedToOther() { + recategorizeCountsOfType(new NodeType(NodeType.UNCLASSIFIED), + new NodeType(NodeType.OTHER), + nodeTypeCounts); + recategorizeCountsOfType(new EdgeType(EdgeType.UNCLASSIFIED), + new EdgeType(EdgeType.OTHER), + edgeTypeCounts); + recategorizeDoublesOfType(new EdgeType(EdgeType.UNCLASSIFIED), + new EdgeType(EdgeType.OTHER), + edgeTypeCountsUnfolded); + recategorizeDoublesOfType(new EdgeType(EdgeType.UNCLASSIFIED), + new EdgeType(EdgeType.OTHER), + edgeTypeAreas); + recategorizeDoublesOfType(new EdgeType(EdgeType.UNCLASSIFIED), + new EdgeType(EdgeType.OTHER), + edgeTypeWidths); + } + + /** Number of cells this LeafStats represents **/ + public int getNumCells() { return numCells; } + + /** Average transistor area per cell **/ + public float getAverageTransistorAreaPerCell() { + return (float) getTransistorArea() / numCells; + } + + /** Average transistor count per cell **/ + public float getAverageTransistorCountPerCell(boolean folded) { + if (folded) + return (float) getTransistorCount() / numCells; + else + return (float) getUnfoldedTransistorCount() / numCells; + } + + /** Average number of specified node type per cell **/ + public float getAverageNodeCountPerCell(final NodeType type) { + Integer cnt = (Integer) nodeTypeCounts.get(type); + return cnt == null ? 0.0F : cnt.floatValue()/numCells; + } + + /** Set layout area and density factor **/ + public void setLayoutProperties(final LayoutInfo li, + final String cellName) { + layoutArea = li.getLayoutArea(cellName); + layoutTransistorArea = getTransistorArea(); + densityFactor = li.getTransistorDensityFactor(cellName, (float) + layoutTransistorArea); + cellsWithLayoutInfo = 1; + } + + /** + * Initializes all counts to 0. Call tallyMarks() to calculate + * statistics + **/ + LeafStats() { + nodeTypeCounts = new HashMap(); + edgeTypeCounts = new HashMap(); + edgeTypeCountsUnfolded = new HashMap(); + edgeTypeAreas = new HashMap(); + edgeTypeWidths = new HashMap(); + lengthCounts = new TreeMap(); + layoutArea = 0.0; + layoutTransistorArea = 0.0; + cellsWithLayoutInfo = 0; + numCells = 0; + aggegatedStats = false; + } + + /** + * Calculates basic statistics from the NetGraph, sets + * node type and edge type maps from those passed. + **/ + LeafStats(final NetGraph netgraph, + final Map nodeTypeCounts, + final Map edgeTypeCounts, + final Map edgeTypeCountsUnfolded, + final Map edgeTypeAreas, + final Map edgeTypeWidths) { + lengthCounts = new TreeMap(); + countDevices(netgraph); + this.nodeTypeCounts = new HashMap(nodeTypeCounts); + this.edgeTypeCounts = new HashMap(edgeTypeCounts); + this.edgeTypeCountsUnfolded = new HashMap(edgeTypeCountsUnfolded); + this.edgeTypeAreas = new HashMap(edgeTypeAreas); + this.edgeTypeWidths = new HashMap(edgeTypeWidths); + numCells = 1; + aggegatedStats = false; + } + + /** + * Adds statistics from the passed LeafStats, weighted by + * instance count + **/ + void addStatistics(int instCount, final LeafStats stats) { + numNMOS += instCount * stats.numNMOS; + numPMOS += instCount * stats.numPMOS; + numGateNMOS += instCount * stats.numGateNMOS; + numGatePMOS += instCount * stats.numGatePMOS; + numGates += instCount * stats.numGates; + numStaticizers += instCount * stats.numStaticizers; + areaNMOS += instCount * stats.areaNMOS; + areaPMOS += instCount * stats.areaPMOS; + areaGateNMOS += instCount * stats.areaGateNMOS; + areaGatePMOS += instCount * stats.areaGatePMOS; + numUnfoldedEdges += instCount * stats.numUnfoldedEdges; + + addWeightedIntegersByType(instCount,stats.nodeTypeCounts, + nodeTypeCounts); + addWeightedIntegersByType(instCount,stats.edgeTypeCounts, + edgeTypeCounts); + addWeightedDoublesByType(instCount,stats.edgeTypeCountsUnfolded, + edgeTypeCountsUnfolded); + addWeightedDoublesByType(instCount,stats.edgeTypeAreas,edgeTypeAreas); + addWeightedDoublesByType(instCount,stats.edgeTypeWidths,edgeTypeWidths); + + // Add transistor length counts + for (Iterator li=stats.lengthCounts.entrySet().iterator(); + li.hasNext();) { + Entry entry = (Entry) li.next(); + int len = ((Integer) entry.getKey()).intValue(); + int cnt = ((Integer) entry.getValue()).intValue(); + addGateLength(instCount*cnt,len); + } + + numCells += instCount * stats.numCells; + if (stats.cellsWithLayoutInfo > 0) { + layoutArea += instCount * stats.layoutArea; + layoutTransistorArea += instCount * stats.layoutTransistorArea; + cellsWithLayoutInfo += instCount * stats.cellsWithLayoutInfo; + } + aggegatedStats = true; + } + + /** Preliminary statistics that are tallied upfront **/ + private void countDevices(final NetGraph netgraph) { + for (Iterator t=netgraph.getEdges().iterator(); t.hasNext();) { + NetGraph.NetEdge e = (NetGraph.NetEdge) t.next(); + if (e.type == DeviceTypes.N_TYPE) { + if (e.library && !e.floating) { + numGateNMOS++; + areaGateNMOS += e.width * e.length; + } + else { + numNMOS++; + areaNMOS += e.width * e.length; + } + } + else if (e.type == DeviceTypes.P_TYPE) { + if (e.library && !e.floating) { + numGatePMOS++; + areaGatePMOS += e.width * e.length; + } + else { + numPMOS++; + areaPMOS += e.width * e.length; + } + } + addGateLength(1,(int)(e.length*1e9)); + } + for (Iterator t = netgraph.getNodes().iterator(); t.hasNext();) { + NetGraph.NetNode n = (NetGraph.NetNode) t.next(); + if (n.getGate() != null) numGates++; + if (n.getStaticizer() != null) numStaticizers++; + } + numUnfoldedEdges = netgraph.getUnfoldedTransistorCount(); + } + + /** Adds 'cnt' transistors of length 'nanometerLength' (in nm obviously) **/ + private void addGateLength(int cnt, int nanometerLength) { + Integer intLen = new Integer(nanometerLength); + Integer intCnt = (Integer) lengthCounts.get(intLen); + if (intCnt == null) lengthCounts.put(intLen,new Integer(cnt)); + else lengthCounts.put(intLen,new Integer(intCnt.intValue()+cnt)); + } + + private static void recategorizeCountsOfType(final Object fromType, + final Object toType, + final Map map) { + Integer fromCntInt = (Integer)map.get(fromType); + Integer toCntInt = (Integer)map.get(toType); + int fromCnt = (fromCntInt == null ? 0 : fromCntInt.intValue()); + int toCnt = (toCntInt == null ? 0 : toCntInt.intValue()); + map.put(toType,new Integer(fromCnt + toCnt)); + map.remove(fromType); + } + + private static void recategorizeDoublesOfType(final Object fromType, + final Object toType, + final Map map) { + Double fromValDouble = (Double)map.get(fromType); + Double toValDouble = (Double)map.get(toType); + double fromCnt = (fromValDouble == null ? 0 : + fromValDouble.doubleValue()); + double toCnt = (toValDouble == null ? 0 : + toValDouble.doubleValue()); + map.put(toType,new Double(fromCnt + toCnt)); + map.remove(fromType); + } + + private static void addWeightedIntegersByType(int weight, + final Map from, + final Map to) { + for (Iterator ki=from.entrySet().iterator(); ki.hasNext();) { + Entry entry = (Entry) ki.next(); + int inc = weight * ((Integer)entry.getValue()).intValue(); + Integer toVal = (Integer) to.get(entry.getKey()); + if (toVal == null) to.put(entry.getKey(),new Integer(inc)); + else to.put(entry.getKey(),new Integer(inc+toVal.intValue())); + } + } + + private static void addWeightedFloatsByType(int weight, + final Map from, + final Map to) { + for (Iterator ki=from.entrySet().iterator(); ki.hasNext();) { + Entry entry = (Entry) ki.next(); + float inc = weight * ((Float)entry.getValue()).floatValue(); + Float toVal = (Float) to.get(entry.getKey()); + if (toVal == null) to.put(entry.getKey(),new Float(inc)); + else to.put(entry.getKey(),new Float(inc+toVal.floatValue())); + } + } + + private static void addWeightedDoublesByType(int weight, + final Map from, + final Map to) { + for (Iterator ki=from.entrySet().iterator(); ki.hasNext();) { + Entry entry = (Entry) ki.next(); + double inc = weight * ((Double)entry.getValue()).doubleValue(); + Double toVal = (Double) to.get(entry.getKey()); + if (toVal == null) to.put(entry.getKey(),new Double(inc)); + else to.put(entry.getKey(),new Double(inc+toVal.doubleValue())); + } + } + + /** Statistics Report Summary **/ + void printSummary(boolean verbose) { + // Set up numeric formats + DecimalFormat formWidth = (DecimalFormat)DecimalFormat.getInstance(); + DecimalFormat formPercent = (DecimalFormat)DecimalFormat.getInstance(); + formWidth.applyPattern("0.00"); + formPercent.applyPattern("#0.00%"); + + // Report node count distribution + Iterator nt; + if (verbose) { + System.out.println("Node type distribution:"); + nt = nodeTypeCounts.keySet().iterator(); + while (nt.hasNext()) { + NodeType type = (NodeType)nt.next(); + int cnt = ((Integer)nodeTypeCounts.get(type)).intValue(); + System.out.println(" "+type.toPaddedString()+": "+cnt); + } + } + // Report edge count, ave width, and area percentage distributions + if (verbose) System.out.println( + "Edge type count distribution & total area (unfolded):"); + nt = edgeTypeCounts.keySet().iterator(); + int logicCount = 0; + float logicArea = 0.0F; + while (nt.hasNext()) { + EdgeType type = (EdgeType)nt.next(); + int cnt = ((Integer)edgeTypeCounts.get(type)).intValue(); + int ucnt = ((Double)edgeTypeCountsUnfolded.get(type)).intValue(); + float area = ((Double)edgeTypeAreas.get(type)).floatValue(); + float width = ((Double)edgeTypeWidths.get(type)).floatValue(); + if (type.isLogicType()) { + logicCount += cnt; + logicArea += area; + } + if (verbose) { + System.out.println(" " +type.toPaddedString()+": " + + cnt + "(" + ucnt + ") " + + formWidth.format(width/cnt*1e6) + "(" + + formWidth.format(width/ucnt*1e6) + ") um / " + + formPercent.format((float)cnt/getTransistorCount()) + " " + + formPercent.format(area/getTransistorArea())); + } + } + if (verbose) + System.out.println("Transistor Count and Area Summary:"); + System.out.println(" Logic Transistor Count: " + + (float)logicCount/getTransistorCount()*100 + "%"); + System.out.println(" Logic Transistor Area: " + + logicArea/getTransistorArea()*100 + "%"); + } + + void printStats(boolean verbose) { + if (verbose) { + System.out.println( + "Transistor counts:\n" + + " Gates = " + numGates + "\n" + + " Staticizers = " + numStaticizers + "\n" + + " NMOS (Floating) = " + numNMOS + "\n" + + " PMOS (Floating) = " + numPMOS + "\n" + + " NMOS (Gates) = " + numGateNMOS + "\n" + + " PMOS (Gates) = " + numGatePMOS + "\n" + + " Total = " + getTransistorCount() + "\n" + + " Total Unfolded = " + getUnfoldedTransistorCount() + "\n" + + " TotalArea = " + getTransistorArea()); + } + printSummary(verbose); + } + + /** + * Writes node, transistor, and summary sections to the specified + * HtmlPage. As a side effect, sets logicEfficiency for use by + * getLogicEfficiency(). (Should be generated more cleanly.) + **/ + void printHtmlStats(final HtmlPage page) { + + // Set up numeric formats + DecimalFormat formFloat = + (DecimalFormat)DecimalFormat.getInstance(); + DecimalFormat formPercent = + (DecimalFormat)DecimalFormat.getInstance(); + formFloat.applyPattern("#0.00"); + formPercent.applyPattern("#0.00%"); + + // Report node count distribution + page.section("Node Distribution"); + ArrayList cols = new ArrayList(); + cols.add(new Pair("Category",Boolean.FALSE)); + cols.add(new Pair("Count",Boolean.TRUE)); + cols.add(new Pair("Percentage",Boolean.TRUE)); + page.reportTable(cols); + + // Output each node type + Iterator nt; + for (nt = nodeTypeCounts.keySet().iterator(); nt.hasNext();) { + NodeType type = (NodeType)nt.next(); + int cnt = ((Integer)nodeTypeCounts.get(type)).intValue(); + if (cnt == 0) continue; + cols = new ArrayList(); + cols.add(type.toString()); + cols.add(String.valueOf(cnt)); + cols.add(formPercent.format((float)cnt/getNodeCount())); + page.reportTableLine(cols); + } + page.reportTableEnd(); + + // Report edge count, ave width, and area percentage distributions + page.section("Transistor Distribution"); + cols = new ArrayList(); + cols.add(new Pair("Category",Boolean.FALSE)); + cols.add(new Pair("Count (folded)",Boolean.TRUE)); + cols.add(new Pair("Average width (um)",Boolean.TRUE)); + cols.add(new Pair("Percentage by count",Boolean.TRUE)); + cols.add(new Pair("Percentage by area",Boolean.TRUE)); + page.reportTable(cols); + + // Output each edge type + int logicCount = 0, logicUnfoldedCount = 0; + float logicArea = 0.0F; + for (nt = edgeTypeCounts.keySet().iterator(); nt.hasNext();) { + EdgeType type = (EdgeType)nt.next(); + int cnt = ((Integer)edgeTypeCounts.get(type)).intValue(); + int ucnt = ((Double)edgeTypeCountsUnfolded.get(type)).intValue(); + if (cnt == 0 && ucnt == 0) continue; + float area = ((Double)edgeTypeAreas.get(type)).floatValue(); + float width = ((Double)edgeTypeWidths.get(type)).floatValue(); + if (type.isLogicType()) { + logicCount += cnt; + logicUnfoldedCount += ucnt; + logicArea += area; + } + cols = new ArrayList(); + cols.add(type.toString()); + cols.add(String.valueOf(ucnt)+" ("+String.valueOf(cnt)+")"); + cols.add(formFloat.format(width/ucnt*1e6)); + cols.add(formPercent.format((float)ucnt/ + getUnfoldedTransistorCount())); + cols.add(formPercent.format((float)area/getTransistorArea())); + page.reportTableLine(cols); + } + page.reportTableEnd(); + + // Summary + page.section("Summary"); + page.summaryTable(); + if (aggegatedStats) { + page.summaryTableLine("Number of cells:",numCells); + page.summaryTableLine("Average transistor count per cell (folded):", + formFloat.format(getAverageTransistorCountPerCell(false))+" ("+ + formFloat.format(getAverageTransistorCountPerCell(true))+")"); + page.summaryTableLine("Average transistor area per cell:", + formFloat.format(getAverageTransistorAreaPerCell()*1e12)); + float numInputRails = getAverageNodeCountPerCell( + new NodeType(NodeType.INPUT_DATA_RAIL)); + if (numInputRails > 0.0F) { + float numInputEnables = getAverageNodeCountPerCell( + new NodeType(NodeType.INPUT_ENABLE)); + float numOutputRails = getAverageNodeCountPerCell( + new NodeType(NodeType.OUTPUT_DATA_RAIL)); + float numOutputEnables = getAverageNodeCountPerCell( + new NodeType(NodeType.OUTPUT_ENABLE)); + page.summaryTableLine( + "Average number of input data rails per cell:", + formFloat.format(numInputRails)); + page.summaryTableLine( + "Average number of input enables per cell:", + formFloat.format(numInputEnables)); + page.summaryTableLine( + "Average number of output data rails per cell:", + formFloat.format(numOutputRails)); + page.summaryTableLine( + "Average number of output enables per cell:", + formFloat.format(numOutputEnables)); + } + } + page.summaryTableLine("Total transistor count:",getTransistorCount()); + page.summaryTableLine("Total transistor area (um^2):", + formFloat.format(getTransistorArea()*1e12)); + page.summaryTableLine("Layout area (um^2):", + layoutArea == -1.0F ? "N/A" : + formFloat.format(layoutArea)); + page.summaryTableLine("Layout density factor:", + layoutArea == -1.0F ? "N/A" : + formFloat.format(densityFactor)); + page.summaryTableLine("Logic transistor count percentage (unfolded):", + formPercent.format((float)logicUnfoldedCount/ + getUnfoldedTransistorCount())); + page.summaryTableLine("Logic transistor area percentage:", + formPercent.format(logicArea/getTransistorArea())); + + page.summaryTableEnd(); + + // Save this for future use + logicEfficiency = (float) logicArea / getTransistorArea(); + } + + public float getLogicEfficiency() { return logicEfficiency; } + + /** Generates HTML Statistics Report Page **/ + void printHtmlStatsReport(String designName, String outputDir, + String pageName, String title) { + // Start page + if (title == null) title = "Leaf Cell Statistics"; + HtmlPage page; + try { + page = new HtmlPage(designName,outputDir,pageName,title); + } + catch (IOException e) { + System.err.println("Couldn't create HTML page "+pageName); + System.err.println(e); + return; + } + printHtmlStats(page); + page.close(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NetGraphAnalyzer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NetGraphAnalyzer.java new file mode 100644 index 0000000000..7d76c7d07e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NetGraphAnalyzer.java @@ -0,0 +1,1697 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadalyze; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.StringTokenizer; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.tools.cadalyze.LeafStats; +import com.avlsi.tools.lvs.PrsToNet; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.lvs.NetGraph.NetNode; +import com.avlsi.tools.lvs.NetGraph.NetEdge; +import com.avlsi.tools.lvs.NetGraph.NetPath; + + +/** + * Gleans interesting statistics from a NetGraph + * + * @author Mike Davies + * @version $Revision$ $Date$ + **/ +public final class NetGraphAnalyzer { + /** Print lots of debugging information? Used by debugPrintln() **/ + public static boolean debug = false; + + /** The top-level cast cell to analyze **/ + private final CellInterface cell; + + /** Net graph representation of the cell **/ + private NetGraph netgraph; + + /** Map of NetEdge to EdgeType **/ + private HashMap edgeMap; + + /** Map of NedNode to NodeType **/ + private HashMap nodeMap; + + /** Set of all combinational output nodes in the cell **/ + private HashSet combinationalOutputs; + + /** Set of all unmarked nodes in the cell **/ + private HashSet unmarkedNodes; + + /** Statistics **/ + private LeafStats stats; + + private abstract static class NetGraphElementType { + + public static final int UNCLASSIFIED = 0; + + public abstract int getNumTypes(); + public abstract String[] getTypeStringArray(); + abstract List getLogicTypes(); + + public Integer type; + + /** Sub-category types **/ + public static final int PRIMARY = 0; + public static final int STATICIZER = 1; + public static final int INTERNAL = 2; + + public NetGraphElementType(int t, int subType) { + type = new Integer(t + subType * getNumTypes()); + } + public NetGraphElementType() { + type = new Integer(UNCLASSIFIED); + } + + public boolean equals(final Object t) { + return t instanceof NetGraphElementType && + (((NetGraphElementType)t).type.intValue() == type.intValue()); + } + + public int hashCode() { return type.intValue(); } + + public void setType(int t) { type = new Integer(t); } + public void setStaticizerType(int t) { + type = new Integer(t + getNumTypes()); + } + + public int getType() { return type.intValue(); } + public final Integer getInteger() { return type; } + public boolean isLogicType() { + int t = type.intValue(); + Integer baseType = new Integer(t % getNumTypes()); + return getLogicTypes().contains(baseType); + } + public boolean isStaticizerType() { + return type.intValue() >= getNumTypes() && + type.intValue() < 2 * getNumTypes(); + } + public boolean isInternal() { + return type.intValue() >= 2 * getNumTypes(); + } + + public final String toString() { + final String tstr[] = getTypeStringArray(); + int t = type.intValue(); + String s = new String(tstr[t % getNumTypes()]); + if (t >= getNumTypes() && t < 2*getNumTypes()) s += " staticizer"; + if (t >= 2*getNumTypes()) s += " internal"; + return s; + } + + public final String toPaddedString() { + int max_length = 0; + final String tstr[] = getTypeStringArray(); + for (int i=0; i max_length) + max_length = tstr[i].length(); + max_length += (new String(" staticizer")).length(); + String s = toString(); + for (int i=s.length(); i node- + * ~p1 & ~p2 & .. & ~pN -> node+ + * + * if so, returns a pair of two sets of NetNodes: + * (1) nonempty set of {p1,p2,..pN} precharge nodes + * (2) Possibly empty set of (logic terms) nodes + * + * If 'node' is not driven in the manner described above, then + * the returned pair will be null. + * Note: reset nodes are ignored (relies on proper naming). + **/ + private Pair isPrechargedLogicNode(final NetNode node) { + if (!node.isOutput() || node.isCombinational()) return null; + List paths = node.getLogicPaths(); + Iterator pt = paths.iterator(); + debugPrintln("Examining logic paths of output " + + node.getName().toString()); + Set up_terms = new HashSet(); + Set dn_terms = new HashSet(); + Set common_up_terms = new HashSet(); + Set common_dn_terms = new HashSet(); + boolean up_first = true; + boolean dn_first = true; + while (pt.hasNext()) { + NetPath p = (NetPath) pt.next(); + debugPrintln(p.toString()); + if (p.getDir()==0) + cellType.registerAnomaly("Illegal path found on output "+ + node.name); + else if (!isParallelReset(p)) { + Set tset,ctset; + boolean first = false; + if (p.getDir()==-1) { // to GND + tset = dn_terms; + ctset = common_dn_terms; + if (dn_first) first = true; + dn_first = false; + } + else { // to Vdd + tset = up_terms; + ctset = common_up_terms; + if (up_first) first = true; + up_first = false; + } + Iterator gt = p.getEdges().iterator(); + HashSet gnodes = new HashSet(); + while (gt.hasNext()) { + NetNode g = ((NetEdge)gt.next()).gate; + // Special-case Reset/_Reset: ignore them + if (!isResetNode(g)) { + tset.add(g); + if (first) { + ctset.add(g); + } + else { + gnodes.add(g); + } + } + } + if (!first) { + ctset.retainAll(gnodes); + } + } + } + if (debug) { + debugPrintln("Non-reset terms of output " + node.name + ":"); + debugPrint(" -("); + pt = dn_terms.iterator(); + while (pt.hasNext()) { + NetGraph.NetNode term = (NetGraph.NetNode)pt.next(); + debugPrint(" " + term.getName().toString()); + if (common_dn_terms.contains(term)) debugPrint("*"); + } + debugPrint(" ) +("); + pt = up_terms.iterator(); + while (pt.hasNext()) { + NetGraph.NetNode term = (NetGraph.NetNode)pt.next(); + debugPrint(" " + term.getName().toString()); + if (common_up_terms.contains(term)) debugPrint("*"); + } + debugPrint(" )\n"); + } + // Now determine if this a precharged logic node. + // Rule: If common_up_terms==up_terms and + // If common_up_terms<=common_dn_terms and + // If dn_term-common_up_terms is non-empty. + Set logic_terms = new HashSet(); + if (common_up_terms.containsAll(up_terms) && + common_dn_terms.containsAll(common_up_terms)) { + logic_terms.addAll(dn_terms); + logic_terms.removeAll(common_up_terms); + } + else { + return null; + } + return new Pair(common_up_terms,logic_terms); + } + + /** + * Identifies _R.d[i] logic nodes and associated transistor edges. + * Also identifies en/go/L.e, R.e, and L.d[i]. + **/ + private void identifyLogic() { + Iterator t = netgraph.getNodes().iterator(); + while (t.hasNext()) { + NetNode n = (NetNode) t.next(); + Pair logicPair = isPrechargedLogicNode(n); + if (logicPair != null) { + // A candidate logic node. Now Need to additionally check that + // logic_terms are all cell inputs + // and is non-empty unless precharge_terms includes + // data rail cell inputs (WCHB buffer case) + Set precharge_terms = (Set)logicPair.getFirst(); + Set logic_terms = (Set)logicPair.getSecond(); + Iterator gt = logic_terms.iterator(); + List paths = n.getLogicPaths(); + boolean all_inputs = true; + while (gt.hasNext()) { + NetNode node = (NetNode)gt.next(); + if (!node.isOutput() && node.isPort() && + isInExclusiveSet(node)) + markNode(node,NodeType.INPUT_DATA_RAIL); + else all_inputs = false; + } + debugPrintln("all_inputs = "+all_inputs); + if (all_inputs && logic_terms.size()>0) { + // This is a logic node... but may be a conditional + // output rail. + debugPrintln("Is a dynamic logic output"); + if (hasCombinationalPathToOutput(n)) { + markOutputLogicNode(n); + markEdgesByGates(paths,logic_terms, + EdgeType.DATA_DYNAMIC_LOGIC, + NodeType.LOGIC_RAIL); + // Learn what we can from the precharge_terms + gt = precharge_terms.iterator(); + boolean has_re = false; + boolean has_le = false; + boolean has_en = false; + boolean has_go = false; + boolean wchb = false; + while (gt.hasNext()) { + NetNode node = (NetNode)gt.next(); + if (node.isPort() && !node.isOutput()) { + // L.d[i] or R.e + if (isInExclusiveSet(node)) { + markNode(node,NodeType.INPUT_DATA_RAIL); + markEdgesByGate(paths,node, + EdgeType.DATA_DYNAMIC_LOGIC_PRECHARGE, + NodeType.LOGIC_RAIL); + wchb = true; + } + else { + has_re = true; + markNode(node,NodeType.OUTPUT_ENABLE); + markEdgesByGate(paths,node, + EdgeType.DATA_DYNAMIC_LOGIC_PRECHARGE, + NodeType.LOGIC_RAIL); + } + } + else if (node.isPort() && node.isOutput()) { + // L.e + markOperator(node,NodeType.INPUT_ENABLE, + EdgeType.ACK_LOGIC,false); + markEdgesByGate(paths,node, + EdgeType.DATA_DYNAMIC_LOGIC_PRECHARGE, + NodeType.LOGIC_RAIL); + has_le = true; + } + else if (!node.isPort()) { + // en or go, depending on number + if (precharge_terms.size()==1) { + has_go = true; + markNode(node,NodeType.GO); + markEdgesByGate(paths,node, + EdgeType.DATA_DYNAMIC_LOGIC_PRECHARGE, + NodeType.LOGIC_RAIL); + } + else { + has_en = true; + markOperator(node,NodeType.INTERNAL_ENABLE, + EdgeType.ACK_LOGIC,false); + markEdgesByGate(paths,node, + EdgeType.DATA_DYNAMIC_LOGIC_PRECHARGE, + NodeType.LOGIC_RAIL); + } + } + } + debugPrintln("has_re="+has_re+" "+ + "has_le="+has_le+" "+ + "has_en="+has_en+" "+ + "has_go="+has_go+" "+ + "wchb="+wchb); + // Consistency check, set template type + if ( has_le && has_re && !has_en && + !has_go && !wchb || + !has_le && has_re && has_en && + !has_go && !wchb || + !has_le && !has_re && !has_en && + has_go && !wchb) + cellType.setType(CellType.PCHB); + else if (!has_le && has_re && !has_en && + !has_go && wchb) + cellType.setType(CellType.WCHB); + else { + System.err.println("Warning: Unknown template type."); + cellType.setType(CellType.OTHER); + } + if (has_go) cellType.setGo(); + } + else { + // Conditional output logic rail + markNode(n,NodeType.CONDITIONAL_RAIL); + markEdgesByGates(paths,logic_terms, + EdgeType.CONDITIONAL_OUTPUT_LOGIC, + NodeType.CONDITIONAL_RAIL); + // Mark precharge gates & edges + gt = precharge_terms.iterator(); + while (gt.hasNext()) { + NetNode node = (NetNode)gt.next(); + markEdgesByGate(paths,node, + EdgeType.CONDITIONAL_OUTPUT_PRECHARGE, + NodeType.CONDITIONAL_RAIL); + } + // Mark staticizer + markStaticizer(n,NodeType.CONDITIONAL_RAIL, + EdgeType.CONDITIONAL_OUTPUT_PRECHARGE); + } + } + else if (logic_terms.size()==0 && + hasCombinationalPathToOutput(n) && + precharge_terms.size()==2) { + // Annoying WCHB buffer case... + gt = precharge_terms.iterator(); + NetNode node1 = (NetNode)gt.next(); + NetNode node2 = (NetNode)gt.next(); + boolean excl1 = isInExclusiveSet(node1); + boolean excl2 = isInExclusiveSet(node2); + if (node1.isPort() && !node1.isOutput() && + node2.isPort() && !node2.isOutput() && + (excl1 && !excl2 || !excl1 && excl2)) { + NetNode ldnode,renode; + if (excl1) { + ldnode = node1; renode = node2; + } + else { + ldnode = node2; renode = node1; + } + markNode(ldnode,NodeType.INPUT_DATA_RAIL); + markEdgesByGate(paths,ldnode, + EdgeType.DATA_DYNAMIC_LOGIC, + NodeType.LOGIC_RAIL); + markNode(renode,NodeType.OUTPUT_ENABLE); + markEdgesByGate(paths,renode, + EdgeType.DATA_DYNAMIC_LOGIC_PRECHARGE, + NodeType.LOGIC_RAIL); + markOutputLogicNode(n); + cellType.setType(CellType.WCHB); + debugPrintln("WCHB: node="+n.name); + } + } + } + } + } + + /** + * Call after identifyLogic if the cell has any go signals. + * This will identify the _go inverters, marking the associated + * _go nodes as "_GO" and edges as "GO". Will also mark the output + * enable node and the internal enable. + * + * After this call, all port nodes should be marked. + **/ + private void identifyGo() { + if (cellType.hasGo()) { + // First identify all go nodes + ArrayList goNodes = new ArrayList(); + Iterator nt = nodeMap.keySet().iterator(); + while (nt.hasNext()) { + NetNode go = (NetNode)nt.next(); + if (((NodeType)nodeMap.get(go)).isGo()) goNodes.add(go); + } + for (int i=0; i]\n" + + " [--cast-path=castpath]\n" ); + System.exit(exitStatus); + } + + public static void main(String[] args) { + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + if (theArgs.argExists("version")) { + System.out.println(com.avlsi.util.debug.VersionInfo + .getVersionString(NetGraphAnalyzer.class)); + } + boolean verbose = false; + if (theArgs.getArgValue("verbose","").equals("1")) { + verbose = true; + } + if (theArgs.getArgValue("debug","").equals("1")) { + debug = true; + } + + final FileSearchPath castPath = + new FileSearchPath( theArgs.getArgValue( "cast-path", "." ) ); + + // check number of arguments + if (args.length < 2) + usage(1); + + final String gateString = theArgs.getArgValue("gates", null); + final List gateList = new ArrayList(); + final StringTokenizer tok = new StringTokenizer(gateString,":"); + while (tok.hasMoreTokens()) { + gateList.add(tok.nextToken()); + } + + final StringContainerIterator strIter = + theArgs.nonParsedArgumentsIterator(); + + try { + final String castCellName = strIter.next(); + + // get the cast body + final CastFileParser cfp = new CastFileParser(castPath,"2"); + + final CellInterface cell = + cfp.getFullyQualifiedCell(castCellName); + + final NetGraph netgraph = + PrsToNet.getNetGraph(cell,cfp,null,null,null,null); + + final NetGraphAnalyzer analyzer = + new NetGraphAnalyzer(cell,netgraph,null); + //stats.printOutputDataPorts(); + + if (verbose) System.err.println("Analyzing "+castCellName); + analyzer.analyzeCell(); + analyzer.printStatistics(verbose); + } + catch (Exception e) { + e.printStackTrace(); + usage(1); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NodeProps.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NodeProps.java new file mode 100644 index 0000000000..ad7f41d14d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/NodeProps.java @@ -0,0 +1,341 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadalyze; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.StringTokenizer; + +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.util.container.Pair; + +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.lvs.NetGraph.NetNode; +import com.avlsi.tools.lvs.NetGraph.NetEdge; +import com.avlsi.tools.lvs.NetGraph.NetPath; + + +/** + * Class to contain Cadalyze node (net) properties. + * @author Mike Davies + * @version $Revision$ $Date$ + **/ +public final class NodeProps { + + /*************************** STATIC DATA MEMBERS **************************/ + + /** Print lots of debugging information? Used by debugPrintln() **/ + public static boolean debug = false; + + /****************************** DATA MEMBERS ******************************/ + + /** Number of different cells that drive this node (down/up) **/ + private int[] numDrivers = { 0, 0 }; + + /** Total of all driver cell drive strengths (down, up), in squares **/ + private double[] driveStrengthTotal = { 0.0, 0.0 }; + + /** Fan-out count to NFET(0), PFET(1), all(2) transistors **/ + private DoubleDistribution[] fanoutDistribution = { + new DoubleDistribution(0,10,20), + new DoubleDistribution(0,10,20), + new DoubleDistribution(0,20,20) + }; + private int[] fanoutCount = { 0, 0 }; + + /** Total of all gate load on this node, NFET(0) PFET(1) (area, m^2) **/ + private double[] gateLoadTotal = { 0.0, 0.0 }; + + /** Distribution of total gate load **/ + private DoubleDistribution gateLoadDistribution = + new DoubleDistribution(0.0,40e-6*0.13e-6,20); + + /** Is this a local node? **/ + private boolean local = true; + + /** Does this NodeProps come from a leaf cell NetNode? **/ + private boolean leafNode = false; + + /** Number of different leaf cells this node connects **/ + private int numConnections = 0; + + /** Number of nodes represented; greater than 1 only for tallied stats **/ + private int numNodes = 0; + + /** + * Number of nodes in this tally group that represent local (internal) + * leaf cell nodes. (Needed to adjust averageConnections calculation.) + **/ + int numLocalLeafNodes = 0; + + private HierName name = null; + + /******************************** METHODS ********************************/ + + NodeProps() {} + + NodeProps(NetNode netnode) { + if (netnode.isOutput()) { + driveStrengthTotal = netnode.getAverageDriveStrength(); + for (int i=0; i<2; i++) { + if (driveStrengthTotal[i] != 0.0) numDrivers[i] = 1; + else debugPrintln("Warning: node "+netnode.name+ + " has zero drive strength towards "+i); + } + } + fanoutCount = netnode.getTransistorFanout(); + gateLoadTotal = netnode.getTransistorLoad(); + numNodes = 1; + numConnections = 1; + leafNode = true; + name = netnode.getName(); + } + + /** + * Called by a parent cell when connecting one of its nodes to a + * subcell's port node. Mark the subcell's node as being non-local + * since it connects upward in the hierarchy. + **/ + void connectNode(NodeProps alias) { + if (alias == null) return; + for (int i=0; i<2; i++) { + numDrivers[i] += alias.numDrivers[i]; + driveStrengthTotal[i] += alias.driveStrengthTotal[i]; + fanoutCount[i] += alias.fanoutCount[i]; + gateLoadTotal[i] += alias.gateLoadTotal[i]; + } + numConnections += alias.numConnections; + numNodes = 1; + alias.local = false; + } + + /** + * Accumulate an actual node into a node statistics tally. + * Note that driveStrengthTotal now is treated as the sum of + * *average* drive strengths per node. + **/ + void accumulateNode(NodeProps node) { + if (node == null ) return; + for (int i=0; i<2; i++) { + numDrivers[i] += numDrivers[i]; + driveStrengthTotal[i] += node.numDrivers[i] == 0 ? 0.0 : + node.driveStrengthTotal[i] / node.numDrivers[i]; + fanoutCount[i] += node.fanoutCount[i]; + gateLoadTotal[i] += node.gateLoadTotal[i]; + fanoutDistribution[i].addValue(node.fanoutCount[i]); + } + fanoutDistribution[2].addValue(node.fanoutCount[0]+node.fanoutCount[1]); + gateLoadDistribution.addValue(node.gateLoadTotal[0]+ + node.gateLoadTotal[1]); + numConnections += node.numConnections; + assert node.numNodes == 1; // Must be a single node + numNodes++; + if (node.leafNode && node.local) numLocalLeafNodes++; + } + + /** + * Add a NodeProps statistics set to this one. Not for use when + * 'props' is a single node (use accumulateNode() instead). + **/ + void addNodeProps(int cnt, NodeProps props) { + if (props == null ) return; + for (int i=0; i<2; i++) { + numDrivers[i] += cnt * props.numDrivers[i]; + driveStrengthTotal[i] += cnt * props.driveStrengthTotal[i]; + fanoutCount[i] += cnt * props.fanoutCount[i]; + gateLoadTotal[i] += cnt * props.gateLoadTotal[i]; + fanoutDistribution[i]. + addDistribution(cnt,props.fanoutDistribution[i]); + } + fanoutDistribution[2]. + addDistribution(cnt,props.fanoutDistribution[2]); + gateLoadDistribution.addDistribution(cnt,props.gateLoadDistribution); + numConnections += cnt * props.numConnections; + numNodes += cnt * props.numNodes; + numLocalLeafNodes += cnt * props.numLocalLeafNodes; + } + + double getDriveStrengthUp() { + return numDrivers[1] == 0 ? 0.0 : + driveStrengthTotal[1]/numDrivers[1]; + } + double getDriveStrengthDn() { + return numDrivers[0] == 0 ? 0.0 : + driveStrengthTotal[0]/numDrivers[0]; + } + + int getTransistorFanout() { + return numNodes == 0 ? 0 : + (fanoutCount[0] + fanoutCount[1]) / numNodes; + } + int getNfetFanout() { + return numNodes == 0 ? 0 : + fanoutCount[DeviceTypes.N_TYPE] / numNodes; + } + int getPfetFanout() { + return numNodes == 0 ? 0 : + fanoutCount[DeviceTypes.P_TYPE] / numNodes; + } + + double getGateLoad() { + return numNodes == 0 ? 0.0 : + (gateLoadTotal[0] + gateLoadTotal[1]) / numNodes; + } + double getGateLoadPerLength(double length) { + return getGateLoad() / length; + } + double getGateLoadPerLength(double length, int dir) { + return gateLoadTotal[dir] / (length * numNodes); + } + double getNfetLoad() { + return numNodes == 0 ? 0.0 : + gateLoadTotal[DeviceTypes.N_TYPE] / numNodes; + } + double getPfetLoad() { + return numNodes == 0 ? 0.0 : + gateLoadTotal[DeviceTypes.P_TYPE] / numNodes; + } + + int getNumConnections() { + return leafNode ? 1 : numConnections; + } + + boolean isLocal() { return local; } + + /** Forces this node to be non-local **/ + void setNonLocal() { local=false; } + + boolean isLeafNode() { return leafNode; } + + boolean isLoaded() { return fanoutCount[0] + fanoutCount[1] > 0; } + + /** Is this cell driven? (both high and low) **/ + boolean isDriven() { return numDrivers[0] > 0 && numDrivers[1] > 0; } + + /** Specifically for statistics gathering (when numNodes > 1) **/ + float getAverageTransistorFanout() { + return numNodes == 0 ? 0.0F : (float)fanoutDistribution[2].getAverage(); + //fanoutDistribution[1].getAverage()); + } + + /** Specifically for statistics gathering (when numNodes > 1) **/ + float getAverageNfetFanout() { + return numNodes == 0 ? 0.0F : + (float)fanoutDistribution[DeviceTypes.N_TYPE].getAverage(); + } + + /** Specifically for statistics gathering (when numNodes > 1) **/ + float getAveragePfetFanout() { + return numNodes == 0 ? 0.0F : + (float)fanoutDistribution[DeviceTypes.P_TYPE].getAverage(); + } + + /** Specifically for statistics gathering (when numNodes > 1) **/ + double getAverageDriveStrength() { + return numNodes == 0 ? 0.0 : + (driveStrengthTotal[0]+driveStrengthTotal[1])/(2*numNodes); + } + + double getAverageDriveStrength(int dir) { + return numNodes == 0 ? 0.0 : driveStrengthTotal[dir]/numNodes; + } + + float getAverageConnections() { + return (float)(numConnections - numLocalLeafNodes) / + (numNodes - numLocalLeafNodes); + } + + int getNumNodes() { return numNodes; } + + /** medLen: median transistor length [m] **/ + void printHtmlStats(HtmlPage page, float medGateLength) { + DecimalFormat formFloat = (DecimalFormat)DecimalFormat.getInstance(); + formFloat.applyPattern("#0.00"); + + page.summaryTable(); + page.summaryTableLine("Number of local nodes:", getNumNodes()); + if (getAverageConnections() > 1.0F) + page.summaryTableLine("Average number of leaf cell "+ + "connections per node:", + String.valueOf(getAverageConnections())); + page.summaryTableLine("Average transistor fanout per node:", + formFloat.format(getAverageTransistorFanout())); + page.summaryTableLine("    NFET", + formFloat.format(getAverageNfetFanout())); + page.summaryTableLine("    PFET", + formFloat.format(getAveragePfetFanout())); + page.summaryTableLine("Average drive strength per node:", + formFloat.format(getAverageDriveStrength())); + page.summaryTableLine("    NFET (to GND)", + formFloat.format(getAverageDriveStrength(DeviceTypes.N_TYPE))); + page.summaryTableLine("    PFET (to Vdd)", + formFloat.format(getAverageDriveStrength(DeviceTypes.P_TYPE))); + page.summaryTableLine("Average gate load per node (per "+ + formFloat.format(medGateLength)+" um):", + formFloat.format(getGateLoadPerLength(medGateLength)*1e6)); + page.summaryTableLine("    NFET", + formFloat.format(getGateLoadPerLength(medGateLength, + DeviceTypes.N_TYPE)*1e6)); + page.summaryTableLine("    PFET", + formFloat.format(getGateLoadPerLength(medGateLength, + DeviceTypes.P_TYPE)*1e6)); + page.summaryTableEnd(); + + /* + for (int i=0; i<2; i++) { + page.writer.p(); + fanoutDistribution[i].printHtml(page,1.0); + } + */ + printHtmlDistributions(page,medGateLength); + } + + void printHtmlDistributions(HtmlPage page, float medGateLength) { + // fanout distribution + String imgName = page.getPagePath()+".fanout"; + fanoutDistribution[2].plotData(imgName,1.0); + page.writer.p(); + page.writer.println("Transistor fanout distribution:
    "); + imgName = imgName.substring(imgName.lastIndexOf('/')+1); + page.writer.println(""); + + // gate load distribution + imgName = page.getPagePath()+".load"; + gateLoadDistribution.plotData(imgName,1e6/medGateLength); + page.writer.p(); + page.writer.println("Gate load distribution:
    "); + imgName = imgName.substring(imgName.lastIndexOf('/')+1); + page.writer.println(""); + } + + /***************************** STATIC METHODS *****************************/ + + private static void debugPrintln(final String s) { + if (debug) System.err.println(s); + } + + private static void debugPrint(final String s) { + if (debug) System.err.print(s); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/cadalyze.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/cadalyze.package new file mode 100644 index 0000000000..8620b2f36b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/cadalyze.package @@ -0,0 +1,8 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.tools.cadalyze.Cadalyze +$arch/bin/cadalyze.sh cadalyze.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/custom.mk new file mode 100644 index 0000000000..3aeaa0b821 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadalyze/custom.mk @@ -0,0 +1,5 @@ +CURR_RESULT_FILES := $(CURR_RESULT_FILES) $(CURR_TARGET_DIR)/cadalyze.sh + +$(CURR_TARGET_DIR)/cadalyze.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.cadalyze.Cadalyze/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceActionInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceActionInterface.java new file mode 100644 index 0000000000..677fe6c12f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceActionInterface.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.cadencize; + +import java.util.Iterator; + +/** + * A class implementing this interface provides actions to be + * executed as a CadenceInfoInterface is traversed. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public interface CadenceActionInterface { + + /** + * Action to be executed on the name of the type of the cell. + **/ + void doType(String typeName); + + /** + * Action to be executed once for each canonical name in + * the port list. + **/ + void doPort(String portName); + + /** + * Action to be executed once for each canonical name in + * the local list. + **/ + void doNet(String portName); + + /** + * Action to be executed once for each subcell instantiation. + **/ + void doSubcell(String subcellName, String subcellType); + + /** + * Action to be executed once for each connection between a + * net and a port of this cell. + **/ + void doPortConnection(String netName, String portName); + + /** + * Action to be executed once for each connection between a + * net and a port on a subcell. + **/ + void doSubcellConnection(String netName, + String subcellName, String subcellPortName, + String subcellNetName); + + /** + * Action to be executed once for each netName. + * + * @param netName the name of the net + * @param netName an unmodifiable Iterator of Strings of the + * aliases of the net + **/ + void doAliases(String netName, Iterator aliases); + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataInterface.java new file mode 100644 index 0000000000..045c982264 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataInterface.java @@ -0,0 +1,115 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadencize; +import java.util.Map; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.Set; + +/** + Interface specification for data needed to output files for cadence. +*/ +public interface CadenceDataInterface { + /** + Gets the name of the unit in which the cell resides. + @return The name of the cell's unit. + */ + String GetCellUnitName(); + + /** + Gets the name of the cell. + @return The name of the cell. + */ + String GetCellName(); + + /** + Gets the name of the cell's subtype. + @return The name of the cell's subtype. If the cell is not subtyped, + the cell name will be returned. + */ + String GetCellSubType(); + + /** + Gets the net a given port is conencted to. + @param PortName The name of the port to lookup. + @return + The name of the net connected to the port on success. + null on failure. + */ + String GetPortNetName( String PortName ); + + + /** + Gets the set of nets that are connected to ports. + @return A Set containing all the nets that are connected to ports. + */ + SortedSet GetExportedNets( ) ; + + /** + Gets the type of a given instance as specified in the cast. + @param InstanceName The name of the instance to lookup. + @return The type of the instance as specified in the cast on success. + null on failure. + */ + String GetInstanceType( String InstanceName ); + + /** + Gets the subtype of a given instance as specified in the auto file or mag file. + The subtype of an instance is often the same as the type (ie the cell has not been + subtyped) + @param InstanceName The name of the instance to lookup. + @return The subtype of a given instance as specified in the auto file or mag file + on success. null on failure. + */ + String GetInstanceSubType( String InstanceName ); + + /** + Gets the set of nets in the subcell that connect to nets in the cell. + @param InstanceName The name of the instance to lookup. + @return The set of subcell nets that connecto to nets in this cell on success, + or null on failure. + */ + SortedSet GetSubCellNets( String InstanceName ); + + /** + Gets the name of the net that is connected to a specified net in a specified + subcell. + @param InstanceName The name of the subcell to lookup up connection to. + @param SubCellNet The name of the net in the specified subcell. + @return The name of the net the net in the subcell is connected to on success, + null on failure. + */ + String GetSubCellConnection( String InstanceName, String SubCellNet ) ; + + /** + Gets the set of all port names in the cell. + @return A set containing all the port names. + */ + Set GetPortNames( ); + + /** + Gets the set of all nets in the cell. + @return A sorted set containing all the net names in the cell. + */ + SortedSet GetNetNames(); + + + /** + Gets an iterator that will iterate over all the aliases for a given net. + @param CononicalNetName The canonical name for the net for which you want + the aliases. + */ + Iterator GetNetAliases( final String CononicalNetName ) ; + + + /** + Gets the set of all instance names in the cell. + @return A set containing the names of all the instances in the cell. + */ + Set GetInstanceNames( ); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataTreeMapImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataTreeMapImpl.java new file mode 100644 index 0000000000..f42dec4207 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceDataTreeMapImpl.java @@ -0,0 +1,208 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadencize; + +import java.util.Map; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeMap; +import java.util.SortedSet; +import java.util.TreeSet; + +import com.avlsi.tools.cadencize.CadenceDataInterface; +import com.avlsi.util.debug.Debug; + +public class CadenceDataTreeMapImpl implements CadenceDataInterface { + + public String m_CellName ; + public String m_SubTypeName ; + public String m_CellUnitName ; + /** + Maps portname to netname + */ + private TreeMap m_Ports ; + /** + Maps subcell name to subcell type name + */ + private TreeMap m_SubCellTypes ; + /** + Maps subcell name to subcell sub-type name + */ + private TreeMap m_SubCellSubTypes ; + /** + Maps subcell name to subcell connections map. + */ + private TreeMap m_SubCellConnections ; + + /** + The set all nets in the cell. + */ + private TreeSet m_Nets ; + + /** + Maps net name to iterator of aliases. + */ + private TreeMap m_NetAliases ; + + private boolean IsANet( final String NetName ) { + return m_Nets.contains( NetName ); + } + + /** + Default constructor. + */ + public CadenceDataTreeMapImpl( ) { + m_Ports = new TreeMap(); + m_SubCellTypes = new TreeMap(); + m_SubCellSubTypes = new TreeMap(); + m_SubCellConnections = new TreeMap(); + m_CellName = null ; + m_Nets = new TreeSet(); + m_NetAliases = new TreeMap(); + } + + /** + Sets the cell's unit name. + @param UnitName The new unit name of the cell. + */ + public final void SetCellUnitName( final String UnitName ) { + m_CellUnitName = UnitName; + } + + /** + Sets the cell name. + @param CellName The new cell name. + */ + public final void SetCellName( final String CellName ) { + m_CellName = CellName ; + } + + /** + Sets the cell's subtype name. + @param SubType The new subtype name. + */ + public final void SetCellSubType( final String SubTypeName ) { + m_SubTypeName = SubTypeName ; + } + + public final void AddPort( final String netName, final String portName ) { + //Debug.assertTrue( IsANet( netName ) ); + m_Ports.put( portName, netName ); + } + + public final void AddNet( final String netName ) { + m_Nets.add( netName ); + } + + public final void AddNetAliases( final String CononicalName, final Iterator aliases ) { + Debug.assertTrue( IsANet( CononicalName ) ) ; + m_NetAliases.put( CononicalName, aliases ); + } + + public final void AddSubCell( String subcellName, String subcellType, String subcellSubType ){ + m_SubCellTypes.put( subcellName, subcellType ); + m_SubCellSubTypes.put( subcellName, subcellSubType ); + } + + public final void AddSubCellConnection( String subcellName, + String subcellNetName, + String netName ){ + TreeMap PortMap; + Debug.assertTrue( IsANet( netName ) ); + PortMap = ( TreeMap ) m_SubCellConnections.get( subcellName ); + + if ( PortMap == null ) { + PortMap = new TreeMap() ; + m_SubCellConnections.put( subcellName, PortMap ) ; + } + + PortMap.put( subcellNetName, netName ) ; + } + + public String GetCellUnitName( ) { + return m_CellUnitName; + } + + public String GetCellName( ) { + return m_CellName; + } + + public String GetCellSubType( ) { + if ( m_SubTypeName != null ) { + return m_SubTypeName ; + } + else{ + return m_CellName; + } + } + + public String GetPortNetName( String PortName ) { + return ( String ) m_Ports.get( PortName ) ; + } + + public SortedSet GetExportedNets( ) { + TreeSet ret = new TreeSet(); + Iterator pCurrNetName = m_Ports.values().iterator(); + + while ( pCurrNetName.hasNext() ){ + String CurrNetName = ( String ) pCurrNetName.next(); + ret.add( CurrNetName ); + } + + return ret; + } + + public String GetInstanceType( String InstanceName ){ + return ( String ) m_SubCellTypes.get( InstanceName ); + } + + public String GetInstanceSubType( String InstanceName ) { + return ( String ) m_SubCellSubTypes.get( InstanceName ); + } + + public Map GetSubCellConnections( String InstanceName ) { + return ( Map ) m_SubCellConnections.get( InstanceName ) ; + } + + public SortedSet GetSubCellNets( String InstanceName ) { + TreeSet ret = null; + Map SubCellConnections = GetSubCellConnections( InstanceName ); + + if ( SubCellConnections != null ) { + ret = new TreeSet( SubCellConnections.keySet() ); + } + + return ret; + } + + public String GetSubCellConnection( String InstanceName, String SubCellNet ) { + String ret = null ; + Map SubCellConnections = GetSubCellConnections( InstanceName ); + if ( SubCellConnections != null ) { + ret = ( String ) SubCellConnections.get( SubCellNet ) ; + } + return ret; + } + + public Set GetPortNames( ) { + return m_Ports.keySet(); + } + + public SortedSet GetNetNames( ) { + return m_Nets; + } + + public Iterator GetNetAliases( final String CononicalNetName ) { + return ( Iterator ) m_NetAliases.get( CononicalNetName ); + } + + public Set GetInstanceNames( ) { + return m_SubCellTypes.keySet(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceInfo.java new file mode 100644 index 0000000000..cdf34e2679 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadenceInfo.java @@ -0,0 +1,335 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.cadencize; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.cell.HierarchyInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.NaturalOrderComparator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.UnmodifiableIterator; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.UnaryFunction; + +/** + * Contains information relevant to use the cell with the cadence flow. + *
      + *
    • Port list of the cell, including which ports are connected + * together. + *
    • Subcell list of the cell, including connections between + * two subcells, and subcells and ports. + *
    + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CadenceInfo implements HierarchyInterface { + public static final class BooleanMergeFunction + implements AliasedMap/**/.MergeFunction { + public Object /*Boolean*/ merge (final Object /*Boolean*/ v1, + final Object /*Boolean*/ v2) { + if (v1 == null) + return v2; + else if (v2 == null) + return v1; + else { + final boolean b1 = ((Boolean) v1).booleanValue(); + final boolean b2 = ((Boolean) v2).booleanValue(); + return b1 || b2 ? Boolean.TRUE : Boolean.FALSE; + } + } + } + + /** + * The type of the cell. + **/ + private final String cellType; + + /** + * The port list, an AliasedMap from HierNames to Boolean, signaling + * whether or not the node should appear in the layout port list. + * @see #getPortNodes() + **/ + private final AliasedMap/**/ portNodes; + + /** + * The local nodes, an AliasedSet of HierNames. @see #getLocalNodes() + **/ + private final AliasedSet/**/ localNodes; + + /** + * A map from instance name of subcell to cadence info. + **/ + private final Map subcellMap; + + /** + * Exclusive node sets for local nodes of this cell, and those for + * involving ports of subcells. + **/ + private final ExclusiveNodeSets localExcls; + + /** + * Exclusive node sets for ports of this cell. + **/ + private final ExclusiveNodeSets portExcls; + + + /** + * Class constructor. + **/ + public CadenceInfo(final String cellType, final boolean doExcls) { + this(cellType, doExcls, new NaturalOrderComparator()); + } + + /** + * Class constructor. + **/ + public CadenceInfo(final String cellType, final boolean doExcls, + final Comparator canonicalnessComparator) { + this.cellType = cellType; + this.portNodes = + new AliasedMap/**/( + new BooleanMergeFunction(), + new NaturalOrderComparator()); + this.localNodes = + new AliasedSet/**/(canonicalnessComparator, + new NaturalOrderComparator()); + this.subcellMap = new TreeMap(); + this.localExcls = doExcls ? new ExclusiveNodeSets() : null; + this.portExcls = doExcls ? new ExclusiveNodeSets() : null; + } + + + /** + * The type of the cell. + **/ + public String getType() { + return cellType; + } + + + // + // port nodes + // + + /** + * Returns a namespace of all the HierNames for nodes in the port list, as + * specified by cast. Any connections between nodes captured here as + * aliased names. The values of the map are Boolean, true if the node + * should appear in the layout port list. + * + * This connections in this namespace are a proper subset of those in + * getLocalNodes(). In particular, for any port node N, + * getLocalNodes().getCanonicalKey(N) is consistent with + * getPortNodes().getCanonicalKey(N). This implies that the canonical + * names in the result of getPortNodes() may not necessarily be port nodes. + **/ + public AliasedMap/**/ getPortNodes() { + return portNodes; + } + + public void addPortNode(final HierName portName) { + try { + portNodes.addData(portName, Boolean.FALSE); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + public void connectPortNodes(final HierName portName1, + final HierName portName2) { + try { + portNodes.makeEquivalent(portName1, portName2); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + + // + // local nodes + // + + /** + * Returns an AliasedSet consisting of all the names for all local + * nodes, including any that are in the port list of any child cells. + * + * Any globals used in a subcell are also listed as aliases of the global. + * i.e. if we have a subcell a that uses global b, we will include b! = a.b! + **/ + public AliasedSet/**/ getLocalNodes() { + return localNodes; + } + + public void addLocalNode(final HierName localName) { + localNodes.add(localName); + } + + public void connectLocalNodes(final HierName localName1, + final HierName localName2) { + localNodes.makeEquivalent(localName1, localName2); + } + + /** + * Returns an iterator through pairs of HierName and CadenceInfo, where + * the first of the pair is the instance name, and the second is + * the CadenceInfo for the cell. + **/ + public Iterator> getSubcellPairIterator() { + return new MappingIterator, + Pair> + (subcellMap.entrySet().iterator(), + new UnaryFunction, + Pair>() { + public Pair execute + (final Entry e) { + return new Pair + (e.getKey(), e.getValue()); + } + }); + } + + public CadenceInfo getSubcell(final HierName name) { + return subcellMap.get(name); + } + + public void addSubcellPair(final HierName name, final CadenceInfo ci) { + subcellMap.put(name, ci); + } + + public ExclusiveNodeSets getLocalExclusiveNodeSets() { + return localExcls; + } + + public ExclusiveNodeSets getPortExclusiveNodeSets() { + return portExcls; + } + + + /** + * Walk the cell, executing the specified actions. + **/ + public void walk(CadenceActionInterface a) { + // cell type + // System.err.println("type: " + getType()); + a.doType(getType()); + + // ports, don't print connections among ports + for (final Iterator/**/ i = + getPortNodes().getCanonicalKeys(); + i.hasNext(); ) { + final HierName n = (HierName) i.next(); + + final boolean used = + ((Boolean) getPortNodes().getValue(n)).booleanValue(); + // System.err.println("port " + n + (used ? " used" : " not used")); + if (!used) + continue; + + final String s = n.getCadenceString(); + + // XXX: this could be wrong. CDL files cannot handle a different + // name for the port net and local net, although cadence itself + // can. Consider this cast: define X()(node b) { node b = a; } + // The port name we would pick is "b", but we would pick "a" + // as the local name because it is before "b" alphabetically. + // This cannot be represented in CDL files. The most obvious fix + // is to rename the ports to be the most canonical local node + // that is connected to that port. So in this case, we would + // have .subckt X a. + final HierName netName = + (HierName) getLocalNodes().getCanonicalKey(n); + + // System.err.println("port/net: " + n + " / " + netName); + + a.doPort(s); + // port connections, net to port + a.doPortConnection(netName.getCadenceString(), s); + } + + // local nets + for (final Iterator/**/ i = + getLocalNodes().getCanonicalKeys(); + i.hasNext(); ) { + final HierName n = (HierName) i.next(); + final String s = n.getCadenceString(); + + a.doNet(s); + + // aliases of local nodes + a.doAliases(s, + new UnmodifiableIterator/**/( + new MappingIterator/**/( + getLocalNodes().getAliases(n), + new UnaryFunction/**/() { + public Object /*String*/ execute + (final Object /*HierName*/ o) { + final HierName alias = (HierName) o; + return alias.getCadenceString(); + } + }))); + } + + // subcells + for (final Iterator/*>*/ i = + getSubcellPairIterator(); i.hasNext(); ) { + final Pair/**/ p = (Pair) i.next(); + final HierName name = (HierName) p.getFirst(); + final CadenceInfo subci = (CadenceInfo) p.getSecond(); + + a.doSubcell(name.getCadenceString(), subci.getType()); + + // subcell connections, net to subcell + port & subcell + net + for (final Iterator/**/ iPort = + subci.getPortNodes().getCanonicalKeys(); + iPort.hasNext(); ) { + final HierName subcellPortName = (HierName) iPort.next(); + + final boolean used = + ((Boolean) subci.getPortNodes() + .getValue(subcellPortName)) + .booleanValue(); + // System.err.println("subcell port " + name + '/' + + // subcellPortName + (used ? " used" : " not used")); + if (!used) + continue; + + final HierName subcellNetName + = (HierName) subci.getLocalNodes() + .getCanonicalKey(subcellPortName); + + final HierName netName = + (HierName) getLocalNodes().getCanonicalKey( + HierName.append(name, subcellPortName)); + + a.doSubcellConnection(netName.getCadenceString(), + name.getCadenceString(), + subcellPortName.getCadenceString(), + subcellNetName.getCadenceString()); + } + } + + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/Cadencize.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/Cadencize.java new file mode 100644 index 0000000000..5365ad2a66 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/Cadencize.java @@ -0,0 +1,929 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.cadencize; + +import java.io.BufferedReader; +import java.io.InputStream ; +import java.io.File; +import java.io.FileReader; +import java.io.FileInputStream ; +import java.io.Writer; +import java.io.PrintWriter; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.FileOutputStream; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; + +import com.avlsi.cast.impl.ArrayValue; +import com.avlsi.cast.impl.NodeValue; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.VerilogBlock; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.file.ext.ExtCell; +import com.avlsi.file.ext.parse.ExtParser; +import com.avlsi.io.FileSearchPath; +import com.avlsi.prs.ProductionRule; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Namespace; +import com.avlsi.util.container.NaturalOrderComparator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.UnaryAction; +import com.avlsi.util.text.StringUtil; +import com.avlsi.tools.cadencize.SubCellFile; +import com.avlsi.tools.cadencize.CadencizeDataInterfaceActionHandler; +import com.avlsi.tools.cadencize.CadencizeOutputToSkill; + +import com.avlsi.tools.ext2cdl.Ext2Cdl; + +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +/** + * Extracts information relevant for cadence from a cast CellInterface. + * In the future, I expect that this functionality will be rolled into + * CellInterface. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Cadencize { + public static final int VERILOG_NONE = 0; + public static final int VERILOG_ALL = 1; + public static final int VERILOG_PARTIAL = 2; + + public interface BlockCallback { + /** + * Returns true if the block block should be considered + * when figuring out if a node in the port list is used. + **/ + boolean mark(CellInterface cell, String block); + + /** + * Returns true if the given subcell should be included in CadenceInfo. + **/ + boolean subcell(CellInterface cell, HierName subCellName, + CellInterface subCell); + + /** + * Returns true if the port should be marked as used. + **/ + boolean used(CellInterface cell, HierName portCanon, boolean wiring, + boolean used); + } + + public static class DefaultCallback implements BlockCallback { + private final int considerVerilog; + public DefaultCallback(final int considerVerilog) { + this.considerVerilog = considerVerilog; + } + public boolean mark(CellInterface cell, String block) { + final boolean impl = cell.containsCompletePrs() || + cell.containsCompleteSubcells() || + cell.containsNetlist(); + + if (block == BlockInterface.PRS) { + return cell.containsCompletePrs() && + cell.hasRealProductionRule(); + } else if (block == BlockInterface.SUBCELL) { + return cell.containsCompleteSubcells(); + } else if (block == BlockInterface.VERILOG) { + return (considerVerilog == VERILOG_ALL || + (considerVerilog == VERILOG_PARTIAL && !impl)) && + cell.containsVerilog(); + } else if (block == BlockInterface.NETLIST) { + return cell.containsNetlist(); + } else if (block == BlockInterface.CSP) { + return !impl && cell.containsRunnableCsp(); + } else { + return false; + } + } + public boolean subcell(CellInterface cell, HierName subCellName, + CellInterface subCell) { + return standardSubcellCallback(cell, subCellName, subCell); + } + public boolean used(CellInterface cell, HierName portCanon, + boolean wiring, boolean used) { + return wiring || used; + } + } + + /** + * If a netlist block exists, don't look at the subcells or prs block to + * determine if a node in the port list is used or not. Verilog block is + * not examined. + **/ + public static BlockCallback NETLIST_PRIORITY = + new DefaultCallback(VERILOG_NONE) { + public boolean mark(CellInterface cell, String block) { + if (block == BlockInterface.NETLIST) { + return cell.containsNetlist(); + } else { + return !cell.containsNetlist() && super.mark(cell, block); + } + } + }; + + public static Comparator DEFAULT_CANONICALNESS_COMPARATOR = + System.getProperty("cadencize.old_port_names") == null ? + HierName.getPortComparator() : new NaturalOrderComparator(); + + /** + * Map from string of type name to CadenceInfo. + * Cache of all types that have been converted. + * Type might be "BUF_1of4". + **/ + private final Map convertedCellMap = + new TreeMap(); + + private final boolean raiseExcls; + private final BlockCallback callback; + private final Comparator canonicalnessComparator; + + /** + * Class constructor. + * + * @param raiseExcls whether to bring exclusion properties from + * exported nets of subcells up. + **/ + public Cadencize(final boolean raiseExcls) { + this(raiseExcls, false); + } + + public Cadencize(final boolean raiseExcls, final boolean considerVerilog) { + this(raiseExcls, considerVerilog ? VERILOG_ALL : VERILOG_NONE); + } + + public Cadencize(final boolean raiseExcls, final int considerVerilog) { + this(raiseExcls, new DefaultCallback(considerVerilog)); + } + + public Cadencize(final boolean raiseExcls, final BlockCallback callback) { + this(raiseExcls, callback, DEFAULT_CANONICALNESS_COMPARATOR); + } + + public Cadencize(final boolean raiseExcls, final BlockCallback callback, + final Comparator canonicalnessComparator) { + this.raiseExcls = raiseExcls; + this.callback = callback; + this.canonicalnessComparator = canonicalnessComparator; + } + + public CadenceInfo getExistingCadenceInfo( final String fullyQualifiedCellName ) { + final CadenceInfo ci = convertedCellMap.get( fullyQualifiedCellName ); + return ci; + } + + public CadenceInfo removeCachedCadenceInfo( final String fullyQualifiedCellName ) { + return convertedCellMap.remove( fullyQualifiedCellName ); + } + + private AliasedMap prefixAliasedSet(final HierName instance, + final AliasedSet localNodes) { + return prefixAliasedSet(instance, localNodes, false); + } + + private AliasedMap prefixAliasedSet(final HierName instance, + final AliasedSet localNodes, + final boolean isPort) { + try { + return Namespace.prefixNamespace( + instance, + localNodes.toAliasedMap( + new AliasedMap.MergeFunction() { + public Object merge(Object o1, Object o2) { + return Boolean.FALSE; + } + }, + Boolean.FALSE), + isPort); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionError(e); + } + } + + public static boolean standardSubcellCallback( + CellInterface cell, HierName subCellName, CellInterface subCell) { + return !CellUtils.isWiring(subCell) && + !cell.isInlinedSubcell(subCellName); + } + + public CadenceInfo convert(CellInterface cell) { + final String type = cell.getFullyQualifiedType(); + CadenceInfo ci = getExistingCadenceInfo( type ); + + if (ci != null) + return ci; + + // System.err.println("cell is " + type); + + ci = new CadenceInfo(type, raiseExcls, canonicalnessComparator); + + if (cell.isNode()) { + convertedCellMap.put(type, ci); + return ci; + } + + // let the real handling begin + + // local and port subcells + // for all port cells, add the prefixed namespace of + // their port nodes to the port nodes of this cell. + // Ie if there is an e1of2 called "l" in the port list, + // we will add "l.0", "l.1", "l.e", "l.d[0]", "l.d[1]" to + // the port nodes of this cell. + // Note that the cast definition of this is: + // define e1of2(node "0", "1", e; node d[0..1]) { + // "0" = d[0]; "1" = d[1]; + // } + for (final Iterator/**/ iSubCell = + cell.getAllSubcellPairs(); + iSubCell.hasNext(); ) { + final Pair/**/ p = + (Pair) iSubCell.next(); + + final HierName subCellName = (HierName) p.getFirst(); + final CellInterface subCell = (CellInterface) p.getSecond(); + final boolean isPortSubcell = cell.isPortSubcell(subCellName) || + cell.isChannel(); + + // System.err.println("found subcell " + subCellName + " : " + + // subCell.getType() + " of cell " + type); + + if (subCell.isNode()) { + final HierName node = HierName.makePortName(subCellName, + isPortSubcell); + ci.addLocalNode(node); + if (isPortSubcell) + ci.addPortNode(node); + Debug.assertTrue(!subCell.hasRealProductionRule()); + } else { + final CadenceInfo subci = convert(subCell); + // if the cell is inlined, add the prefixed local nodes, + // otherwise, add the prefixed port nodes + final AliasedMap subcellPortNodes; + if (cell.isInlinedSubcell(subCellName)) { + assert !isPortSubcell; + subcellPortNodes = + prefixAliasedSet(subCellName, subci.getLocalNodes()); + } else { + subcellPortNodes = + Namespace.prefixNamespace(subCellName, + subci.getPortNodes(), + isPortSubcell); + } + + // make all the ports non-exported + for (final Iterator/**/ iSubPort = + subcellPortNodes.getCanonicalKeys(); + iSubPort.hasNext(); ) { + final HierName k = (HierName) iSubPort.next(); + subcellPortNodes.setValue(k, Boolean.FALSE); + } + + // bring the exclusion properties up if requested + if (raiseExcls) { + // get the exclusions for subcell, then check + // to see whether we export them, or + for (Iterator/**/ iExcl = + subci.getPortExclusiveNodeSets().getIterator(); + iExcl.hasNext(); ) { + final ExclusiveNodeSet excl = + (ExclusiveNodeSet) iExcl.next(); + final ExclusiveNodeSet prefixedExcl = + excl.prefixNames(subCellName); + + ci.getLocalExclusiveNodeSets() + .addExclusiveNodeSet(prefixedExcl); + } + } + + // System.err.println("doing subcell " + subCellName + " : " + + // subCell.getType() + " of cell " + type); + + // System.err.println("Sub namespace: \n" + + // Namespace.toString(subci.getPortNodes())); + // System.err.println("prefixed sub namespace: \n" + + // Namespace.toString(subcellPortNodes)); + + if (callback.subcell(cell, subCellName, subCell)) { + Debug.assertTrue(!isPortSubcell); + + ci.addSubcellPair(subCellName, subci); + } + + // Add the nodes and connections of the subcell's + // port namespace to the local namespace. + Namespace.addNamespace(ci.getLocalNodes(), + new AliasedSet/**/(subcellPortNodes)); + + // if it is a port subcell, also add to the port subcells + if (isPortSubcell) { + try { + Namespace.addNamespace(ci.getPortNodes(), + subcellPortNodes); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + + // System.err.println(type + " local ns: \n" + + // Namespace.toString(ci.getLocalNodes())); + // System.err.println(type + " port ns: \n" + + // Namespace.toString(ci.getPortNodes())); + + } + } + + if (raiseExcls) { + // add the locally defined exclusions: + for (final Iterator/**/ iLocalExcl = + cell.getLocalExclusiveNodeSets().getIterator(); + iLocalExcl.hasNext(); ) { + final ExclusiveNodeSet excl = + (ExclusiveNodeSet) iLocalExcl.next(); + + ci.getLocalExclusiveNodeSets().addExclusiveNodeSet(excl); + } + + // filter the local exclusions using port nodes to obtain the + // port exclusions + for (final Iterator/**/ iLocalExcl = + ci.getLocalExclusiveNodeSets().getIterator(); + iLocalExcl.hasNext(); ) { + final ExclusiveNodeSet localExcl = + (ExclusiveNodeSet) iLocalExcl.next(); + + final List/**/ nodes = + new ArrayList/**/(localExcl.getNumNodes()); + + for (final Iterator/**/ iExclNode = + localExcl.getNodes(); + iExclNode.hasNext(); ) { + final HierName n = (HierName) iExclNode.next(); + + if (ci.getPortNodes().getCanonicalKey(n) != null) + nodes.add(n); + } + + if (nodes.size() > 1) + ci.getPortExclusiveNodeSets().addExclusiveNodeSet( + new ExclusiveNodeSet(localExcl.getHiLo(), nodes)); + } + } + + + // System.err.println(type + " cast namespace:\n" + + // ((com.avlsi.cell.CellImpl) cell).getNamespaceString()); + + // take care of cast connections + absorbCastConnections(cell, ci); + + // 5/21/2001: I believe that this loop can be removed because + // globals are now ports on all subcells, so they should already + // be in the local nodes. This loop was a second pass to add + // in globals. + + // take care of globals & shit + // perhaps this could be ditched + for (final Iterator/**/ iCanonLocalNode = + ci.getLocalNodes().getCanonicalKeys(); + iCanonLocalNode.hasNext(); ) { + + final HierName c1 = (HierName) iCanonLocalNode.next(); + + for (final Iterator/**/ iConnLocalNode = + ci.getLocalNodes().getAliases(c1); + iConnLocalNode.hasNext(); ) { + + final HierName n1 = (HierName) iConnLocalNode.next(); + + // This line is mysterious: We need it, but I don't + // understand why. --jmr + if (ci.getPortNodes().contains(n1)) + ci.connectPortNodes(n1, c1); + } + } + + // figure out which ports are used by prs or subcells + markUsedPorts(cell, ci); + + // System.err.println(type + " final local ns: \n" + + // Namespace.toString(ci.getLocalNodes())); + // System.err.println(type + " final port ns: \n" + + // Namespace.toString(ci.getPortNodes())); + + convertedCellMap.put(type, ci); + return ci; + } + + /** + * Absorb aliases specified in CAST. + **/ + private void absorbCastConnections(final CellInterface cell, + final CadenceInfo ci) { + for (final Iterator/**/ iCanonCastNode = + cell.getCanonicalNodes(); + iCanonCastNode.hasNext(); ) { + + final HierName canon = (HierName) iCanonCastNode.next(); + HierName fndLocal = null; + HierName fndPort = null; + + for (final Iterator/**/ iConnCastNode = + cell.getConnectedNodes(canon); + iConnCastNode.hasNext(); ) { + + final HierName conn = (HierName) iConnCastNode.next(); + + // Here is an example of where a node in the cast will + // not be in the CadenceInfo: + // define X()(node a) { + // node c; + // node b = a; + // prs { a => c-; } + // ... and b is never used later + // } + // The node b is merely a convenience. Maybe there is + // an example where b is used. + // + // REVIEW: I don't know when this if statement will be false. + // Maybe this was from when globals were really globals, they're + // ports now. + if (ci.getLocalNodes().contains(conn)) { + final boolean isPort = ci.getPortNodes().contains(conn) || + cell.isChannel(); + final HierName portConn = + HierName.makePortName(conn, isPort); + + if (fndLocal == null) + fndLocal = portConn; + else + ci.connectLocalNodes(fndLocal, portConn); + + if (isPort) { + if (fndPort == null) + fndPort = portConn; + else + ci.connectPortNodes(fndPort, portConn); + } + } + } + } + } + + /** + * Do almost everything convert does, except do not fully + * examine aliases in subcells that are not channels or nodes. For those + * subcells, only examine aliases in their port subcells. Except if the + * subcell is specified in allAliases, then its aliases are + * examined in their entirety. + * + * @param cell cell for which to return alias information + * @param allAliases a map from subcell instance name + * (HierName) to whether it should be examined fully + * (Boolean.TRUE or Boolean.FALSE). + * @return all aliases in cell, including any aliases defined + * in channels, port subcells of subcells, and any cells specified in + * allAliases + **/ + public AliasedSet convertChannels(final CellInterface cell, + final Map allAliases) { + final CadenceInfo ci = + new CadenceInfo(cell.getFullyQualifiedType(), false); + + for (final Iterator/**/ iSubCell = + cell.getAllSubcellPairs(); iSubCell.hasNext(); ) { + final Pair/**/ p = (Pair) iSubCell.next(); + + final HierName subCellName = (HierName) p.getFirst(); + final CellInterface subCell = (CellInterface) p.getSecond(); + final boolean isPortSubcell = cell.isPortSubcell(subCellName); + + if (subCell.isNode()) { + ci.addLocalNode(HierName.makePortName(subCellName, + isPortSubcell)); + } else { + if (subCell.isChannel() || + allAliases.get(subCellName) == Boolean.TRUE) { + final CadenceInfo subci = convert(subCell); + Namespace.addNamespace(ci.getLocalNodes(), + new AliasedSet/**/( + prefixAliasedSet(subCellName, + subci.getLocalNodes(), + isPortSubcell))); + } else if (cell.isInlinedSubcell(subCellName)) { + assert !isPortSubcell; + final AliasedSet sublocals = + convertChannels(subCell, Collections.EMPTY_MAP); + Namespace.addNamespace(ci.getLocalNodes(), + new AliasedSet/**/( + prefixAliasedSet(subCellName, sublocals))); + } else { + for (Iterator portSubCell = subCell.getPortSubcellPairs(); + portSubCell.hasNext(); ) { + final Pair/**/ pp = + (Pair) portSubCell.next(); + + final HierName portCellName = (HierName) pp.getFirst(); + final CellInterface portCell = + (CellInterface) pp.getSecond(); + if (portCell.isNode()) { + ci.addLocalNode(HierName.append(subCellName, + portCellName)); + continue; + } + final CadenceInfo subci = convert(portCell); + + // Add the nodes and connections of the subcell's + // port namespace to the local namespace. + Namespace.addNamespace(ci.getLocalNodes(), + new AliasedSet/**/( + prefixAliasedSet( + HierName.append(subCellName, portCellName), + subci.getLocalNodes()))); + } + } + } + } + + absorbCastConnections(cell, ci); + + return ci.getLocalNodes(); + } + + /** + * Determine which ports are used by a subcell or a production rule. + * We only output ports that are used. + **/ + private void markUsedPorts(final CellInterface cell, + final CadenceInfo ci) { + final Set/**/ usedLocalCanonSet = + new HashSet/**/(); + + // System.err.println("cell is " + cell.getType()); + + // mark ports used by prs + if (callback.mark(cell, BlockInterface.PRS)) { + for (final Iterator/**/ iPR = + cell.getProductionRuleSet().getProductionRules(); + iPR.hasNext(); ) { + final ProductionRule pr = (ProductionRule) iPR.next(); + + pr.foreachHierName(new UnaryAction/**/() { + public void execute(final Object /*HierName*/ o) { + final HierName n = (HierName) o; + final HierName localCanon = + (HierName) ci.getLocalNodes().getCanonicalKey(n); + // Debug.assertTrue(localCanon != null); + // it's ok if we don't find a node. This means that + // it was from an inlined subcell. + if (localCanon != null) + usedLocalCanonSet.add(localCanon); + } + }); + } + } + + // mark ports used by subcells + if (callback.mark(cell, BlockInterface.SUBCELL)) { + for (final Iterator/*>*/ iSubCell = + ci.getSubcellPairIterator(); + iSubCell.hasNext(); ) { + final Pair/**/ p = (Pair) iSubCell.next(); + + final HierName subCellName = (HierName) p.getFirst(); + final CadenceInfo subci = (CadenceInfo) p.getSecond(); + final AliasedMap/**/ subPortNodes = + subci.getPortNodes(); + for (final Iterator/**/ iPort = + subPortNodes.getCanonicalKeys(); + iPort.hasNext(); ) { + final HierName subcellPortName = (HierName) iPort.next(); + final Boolean used = + (Boolean) subPortNodes.getValue(subcellPortName); + if (used.booleanValue()) { + final HierName localCanon = + (HierName) ci.getLocalNodes().getCanonicalKey( + HierName.append(subCellName, subcellPortName)); + + Debug.assertTrue(localCanon != null); + usedLocalCanonSet.add(localCanon); + } + } + } + } + + // mark ports used by netlist body + if (callback.mark(cell, BlockInterface.NETLIST)) { + final BlockIterator bi = + cell.getBlockInterface().iterator(BlockInterface.NETLIST); + Debug.assertTrue(bi.hasNext(), "No netlist block found in " + cell.getFullyQualifiedType()); + final NetlistBlock block = (NetlistBlock) bi.next(); + final Template templ = block.getCDLTemplate(); + final AliasedMap ports = ci.getPortNodes(); + templ.execute(Collections.EMPTY_MAP, new CDLSimpleInterface() { + private void addName(final HierName name) { + final Object key = ports.getCanonicalKey(name); + if (key != null) usedLocalCanonSet.add(key); + } + public void makeResistor(HierName name, HierName n1, + HierName n2, double val) { + addName(n1); addName(n2); + } + public void makeCapacitor(HierName name, HierName npos, + HierName nneg, double val) { + addName(npos); addName(nneg); + } + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, + HierName nb, double w, double l) { + addName(ns); addName(nd); addName(ng); addName(nb); + } + public void makeDiode(HierName name, int type, HierName npos, + HierName nneg, double w, double l, + double a, double p) { + addName(npos); addName(nneg); + } + public void makeInductor(HierName name, HierName npos, + HierName nneg, double val) { + addName(npos); addName(nneg); + } + public void makeBipolar(HierName name, int type, HierName nc, + HierName nb, HierName ne, double a) { + addName(nc); addName(nb); addName(ne); + } + public void makeCall(HierName name, String subName, + HierName[] args, Map parameters) { + for (int i = 0; i < args.length; ++i) addName(args[i]); + } + public void beginSubcircuit(String subName, String[] in, + String[] out) { } + public void endSubcircuit(String subName) { } + }); + } + + // mark ports used by verilog body or CSP body + if (callback.mark(cell, BlockInterface.VERILOG) || + callback.mark(cell, BlockInterface.CSP)) { + // It is unnecessary to eliminated unused ports in Verilog, because + // not part of the flow that generates CDL for layout should care + // about the verilog block, so mark all ports as used so that any + // ports used in the verilog block would be included in the port + // list + // Assume all ports are used by the CSP block + final AliasedMap ports = ci.getPortNodes(); + for (Iterator/**/ i = ports.getCanonicalKeys(); + i.hasNext(); ) { + usedLocalCanonSet.add(i.next()); + } + } + + final boolean isWiring = + ((Boolean)DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.WIRING)).booleanValue(); + + // for all ports, check to see if they were used, mark accordingly + // If this is a wiring cell, we can't rule out that it's used + for (final Iterator/**/ iPortCanon = + ci.getPortNodes().getCanonicalKeys(); + iPortCanon.hasNext(); ) { + final HierName portCanon = (HierName) iPortCanon.next(); + final HierName localCanon = + (HierName) ci.getLocalNodes().getCanonicalKey(portCanon); + final Boolean v = + (Boolean) ci.getPortNodes().getValue(portCanon); + // Debug.assertTrue(v.booleanValue() == FALSE); + Debug.assertTrue(v == Boolean.FALSE); + + try { + if (callback.used(cell, portCanon, isWiring, + usedLocalCanonSet.contains(localCanon))) { + // System.err.println("port " + portCanon + " used"); + ci.getPortNodes().addData(portCanon, Boolean.TRUE); + } else { + // System.err.println("port " + portCanon + " not used"); + ci.getPortNodes().addData(portCanon, Boolean.FALSE); + } + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionFailure(e); + } + } + } + + private static void usage(final int exitStatus) { + System.err.println("Usage: " + + Cadencize.class.getName() + + " [--ext-path=extractfilepath] [--cast-path=castpath]" + + " ( --file=filename --rootcell=cellname ) |" + + " ( unit cell subtype file.cast file.subcells output.il [ output.cdl [file.ext] ]) "); + System.exit(exitStatus); + } + + private static InputStream OpenInputFileStream( final String FileName ) + throws java.io.FileNotFoundException { + + File myFile = new File( FileName ) ; + return new FileInputStream( myFile ) ; + } + + private static OutputStream OpenOutputFileStream( final String FileName ) + throws java.io.FileNotFoundException { + + File myFile = new File( FileName ); + + return new FileOutputStream( myFile ); + } + + private static PrintWriter MakePrintWriter( OutputStream s ) + throws java.io.UnsupportedEncodingException { + OutputStreamWriter MyWriter = new OutputStreamWriter( s, "UTF-8" ) ; + return new PrintWriter( MyWriter, false ); + } + + private void processCell( + final CastFileParser cfp, + final String unitName, + final String cellName, + final String cellSubType, + final String castFileName, + final String subcellsFileName, + final String outputSkillFileName, + final String outputCDLFileName, + final String extractFileName, + final FileSearchPath extractFileSearchPath ) throws Exception { + OutputStream SkillOutStream = OpenOutputFileStream( outputSkillFileName ) ; + + PrintWriter SkillWriter = MakePrintWriter( SkillOutStream ); + + SubCellFile MySubCells = new SubCellFile( OpenInputFileStream( subcellsFileName ) ); + + + // parse the file + final CastFile cf = cfp.parse(castFileName); + + final CellInterface cell = cf.getCell(cellName); + + CadencizeDataInterfaceActionHandler MyActionHandler = + new CadencizeDataInterfaceActionHandler( unitName, + cellSubType, + MySubCells.GetInstanceTypeMap() ) ; + + convert(cell).walk( MyActionHandler ); + + CadenceDataInterface CadInfo = MyActionHandler.getCadenceData(); + + CadencizeOutputToSkill.WriteSkill( SkillWriter, CadInfo ); + + SkillOutStream.close(); + + if ( outputCDLFileName != null ) { + OutputStream CDLOutStream = OpenOutputFileStream( outputCDLFileName ); + PrintWriter CDLWriter = MakePrintWriter( CDLOutStream ); + + ExtCell ext = null ; + + if ( extractFileName != null ) { + ext = ExtParser.parse( cellName, extractFileName , extractFileSearchPath, false ); + } + MessageFormat FETFormat = new MessageFormat( "M{0,number,############} {1} {2} {3} {4} {5} {6} {7}" ); + + Ext2Cdl.WriteCDL( ext, CDLWriter, FETFormat, CadInfo ); + + CDLOutStream.close(); + } + } + + private void processLine(final CastFileParser cfp, + final String[] words, + final FileSearchPath extractFileSearchPath ) throws Exception { + if (!(6 <= words.length && words.length <= 8)) + usage(1); + + final String unitName = words[0]; + final String cellName = words[1]; + final String cellSubType = words[2]; + final String castFileName = words[3]; + + final String subcellsFileName = words[4]; + final String outputSkillFileName = words[5]; + final String outputCDLFileName = words.length > 6 ? words[6] : null; + final String extractFileName = words.length > 7 ? words[7] : null; + + processCell(cfp, unitName, cellName, cellSubType, castFileName, + subcellsFileName, outputSkillFileName, + outputCDLFileName, extractFileName, extractFileSearchPath ); + } + + private void processFile(final CastFileParser cfp, + final String fileName, + final String rootCell, + final FileSearchPath extractFileSearchPath ) + throws Exception { + final BufferedReader reader = + new BufferedReader(new FileReader(fileName)); + + int lineNum = 0; + String line; + while ((line = reader.readLine()) != null) { + ++lineNum; +// final String[] words = StringUtil.wordBreak(line); + final String[] words = StringUtil.split(line, ' '); + + if (lineNum == 1 && !words[1].equals(rootCell)) { + System.err.println(rootCell + + " specified as --rootCell, but not first in file"); + System.exit(2); + } + + processLine(cfp, words, extractFileSearchPath ); + } + } + + public static void main(String[] args) throws Exception { + if (!(args.length == 4 || (6 <= args.length && args.length <= 8))) + usage(1); + + + CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + CommandLineArgs theArgs = cachedArgs; + + final FileSearchPath castFileSearchPath = new FileSearchPath( theArgs.getArgValue( "cast-path", "." ), + System.getProperty( "user.home" ) ); + + final CastFileParser cfp = + new CastFileParser(castFileSearchPath); + final Cadencize cad = new Cadencize(false); + + final FileSearchPath extractFileSearchPath = new FileSearchPath( theArgs.getArgValue( "ext-path", "." ), + System.getProperty( "user.home" ) ); + + String fileName = theArgs.getArgValue( "file", null ); + String rootCell = theArgs.getArgValue( "rootcell", null ); + + if ( ( fileName == null ) ^ ( rootCell == null ) ) { + usage(1); + } + else { + if ( fileName != null ) { + cad.processFile(cfp, fileName, rootCell, extractFileSearchPath ); + } + else { + ArrayList argList = new ArrayList(); + + StringContainerIterator strIter = theArgs.nonParsedArgumentsIterator(); + + while ( strIter.hasNext() ) { + argList.add( strIter.next() ); + } + + cad.processLine(cfp, (String[]) argList.toArray(), extractFileSearchPath ); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeDataInterfaceActionHandler.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeDataInterfaceActionHandler.java new file mode 100644 index 0000000000..65c2d9db0b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeDataInterfaceActionHandler.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadencize; + +import java.util.Map; +import java.util.Iterator; + +import com.avlsi.tools.cadencize.CadenceDataInterface; +import com.avlsi.tools.cadencize.CadenceDataTreeMapImpl; +import com.avlsi.tools.cadencize.SubCellFile; + +public final class CadencizeDataInterfaceActionHandler implements CadenceActionInterface { + + CadenceDataTreeMapImpl m_CadenceData; + Map m_InstanceSubTypeMap; + + public CadencizeDataInterfaceActionHandler( final String unitName, + final String subTypeName, + Map InstanceSubTypeMap ){ + m_CadenceData = new CadenceDataTreeMapImpl(); + m_CadenceData.SetCellUnitName( unitName ) ; + m_CadenceData.SetCellSubType( subTypeName ); + m_InstanceSubTypeMap = InstanceSubTypeMap; + } + + public void doType( String typeName ){ + m_CadenceData.SetCellName( typeName ); + } + + public void doPort( String portName ){} + + public void doNet( String netName ){ + m_CadenceData.AddNet( SubCellFile.CononicalizeSubCellInstanceName(netName) ); + } + + public void doSubcell( String subcellName, String subcellType ){ + String RealSubCellName = SubCellFile.CononicalizeSubCellInstanceName( subcellName ); + String SubCellSubType = ( String ) m_InstanceSubTypeMap.get( RealSubCellName ) ; + if ( SubCellSubType != null ) { + m_CadenceData.AddSubCell( RealSubCellName, subcellType, SubCellSubType ) ; + } + else{ + System.out.print( "WARNING: Could not get subtype for \"" ); + System.out.print( RealSubCellName ); + System.out.print( "\" which is of type \"" ); + System.out.print( subcellType ); + System.out.print( "\". Assumming subtype is \"" ); + System.out.print( subcellType ); + System.out.println( "\". Your layout might use a subtype different"); + System.out.print( "from \"" ); + System.out.print( subcellType ) ; + System.out.print( ", which potentially will mean that the layout will differ from the CDL "); + System.out.println( "file generated by this program." ); + + m_CadenceData.AddSubCell( RealSubCellName, subcellType, subcellType ) ; + } + } + + public void doPortConnection( String netName, String portName ){ + m_CadenceData.AddPort( SubCellFile.CononicalizeSubCellInstanceName(netName), SubCellFile.CononicalizeSubCellInstanceName(portName) ); + } + + public void doSubcellConnection( String netName, + String subcellName, + String subcellPortName, + String subcellNetName ){ + m_CadenceData.AddSubCellConnection( SubCellFile.CononicalizeSubCellInstanceName(subcellName), + SubCellFile.CononicalizeSubCellInstanceName(subcellNetName), + SubCellFile.CononicalizeSubCellInstanceName(netName) ) ; + } + + public void doAliases(final String netName, final Iterator aliases) { + m_CadenceData.AddNetAliases( SubCellFile.CononicalizeSubCellInstanceName(netName), aliases ); + } + + public CadenceDataInterface getCadenceData( ) { + return m_CadenceData; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeOutputToSkill.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeOutputToSkill.java new file mode 100644 index 0000000000..b1810f3e03 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/CadencizeOutputToSkill.java @@ -0,0 +1,303 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadencize; + + +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.Set ; +import java.util.Iterator ; +import java.text.MessageFormat ; + +import com.avlsi.tools.cadencize.CadenceDataInterface; +/** + A class containing static methods to write out data in an object that + implements CadenceDataInterface to a skill file. +*/ + +public final class CadencizeOutputToSkill { + /** + * This class should not be instantiated. + **/ + private CadencizeOutputToSkill() { } + + private static String GetSubCellConnectionFunctionString( CadenceDataInterface cadData, + String SubCellName, + long CurrSubCellNum ) { + + Set SubCellNets = cadData.GetSubCellNets( SubCellName ); + long InternalFuncCount = 0; + long LineCount = 0; + + String SubCellFuncName = MakeSubCellConnectionsFuncName( CurrSubCellNum ); + StringBuffer result = new StringBuffer(); + + result.append( "( defun " ); + result.append( SubCellFuncName ); + result.append( " ( )\n" ); + if ( SubCellNets != null ) { + + result.append( "( append\n( list\n" ); + + Iterator i; + + i = SubCellNets.iterator(); + + while ( i.hasNext() ) { + if ( LineCount == 500 ) { + StringBuffer NewFuncName = new StringBuffer( MakeSubCellConnectionsFuncName( CurrSubCellNum ) ); + NewFuncName.append( "_" ); + NewFuncName.append( InternalFuncCount ); + ++InternalFuncCount; + LineCount = 0; + + result.append( " ) \n ( " ); + result.append( NewFuncName ) ; + result.append( " )\n )\n )\n" ); + + result.append( "( defun " ); + result.append( NewFuncName ); + result.append( " ( )\n" ); + result.append( "( append\n( list\n" ); + } + + + + + String CurrSubCellNet = ( String ) i.next() ; + result.append( " ( list \"" ); + result.append( CurrSubCellNet ); + result.append( "\" \"" ); + result.append( cadData.GetSubCellConnection( SubCellName, + CurrSubCellNet ) ) ; + result.append( "\" )\n" ); + ++LineCount; + } + result.append( " )\n nil )\n" ); + + + } + else { + + result.append( "nil\n" ); + } + result.append( ")\n" ); + return result.toString() ; + } + + + private static String GetNetAliasessString( CadenceDataInterface cadData, + String NetName, + long CurrNetNum ) { + + Iterator i = cadData.GetNetAliases( NetName ); + long InternalFuncCount = 0; + long LineCount = 0; + + String NetAliasesFuncName = MakeNetAliasesFuncName( CurrNetNum ); + StringBuffer result = new StringBuffer(); + + result.append( "( defun " ); + result.append( NetAliasesFuncName ); + result.append( " ( )\n" ); + if ( i.hasNext() ) { + + result.append( "( append\n( list\n" ); + + while ( i.hasNext() ) { + if ( LineCount == 500 ) { + StringBuffer NewFuncName = new StringBuffer( MakeNetAliasesFuncName( CurrNetNum ) ); + NewFuncName.append( "_" ); + NewFuncName.append( InternalFuncCount ); + ++InternalFuncCount; + LineCount = 0; + + result.append( " ) \n ( " ); + result.append( NewFuncName ) ; + result.append( " )\n )\n )\n" ); + + result.append( "( defun " ); + result.append( NewFuncName ); + result.append( " ( )\n" ); + result.append( "( append\n( list\n" ); + } + + + + + String CurrAlias = ( String ) i.next() ; + result.append( "\""); + result.append(CurrAlias); + result.append("\"\n" ); + ++LineCount; + } + result.append( " )\n nil )\n" ); + + + } + else { + + result.append( "nil\n" ); + } + result.append( ")\n" ); + return result.toString() ; + } + + + + private static String GetSubCellConnectionsString( long CurrSubCellNum ) { + StringBuffer result = new StringBuffer(); + + result.append( "( " ); + result.append( MakeSubCellConnectionsFuncName( CurrSubCellNum ) ); + result.append( " )" ); + return result.toString(); + } + + private static String MakeSubCellConnectionsFuncName( long SubCellNum ) { + + return "CastInfo_SubCellConnectionFunc" + SubCellNum ; + } + + private static String MakeNetAliasesFuncName( long SubCellNum ) { + return "CastInfo_NetAliasesFunc" + SubCellNum; + } + + public static void WriteSkill( PrintWriter out, CadenceDataInterface cadData ) { + + long CurrSubCellNum = 0; + long CurrNetNum = 0; + Iterator i = cadData.GetInstanceNames().iterator(); + + while( i.hasNext() ) { + String CurrSubCellInst = ( String ) i.next() ; + + out.println( GetSubCellConnectionFunctionString( cadData, + CurrSubCellInst, + CurrSubCellNum ) ); + ++CurrSubCellNum; + } + + + i = cadData.GetNetNames().iterator() ; + while ( i.hasNext() ) { + final String CurrNetName = ( String ) i.next() ; + + out.println( GetNetAliasessString( cadData, CurrNetName, CurrNetNum ) ) ; + ++CurrNetNum; + } + + + out.println( ";CurrSubCellInst\n( defun ImportCurrentCell ( BlockLibHandle )" ); + out.println( " ( let (" ); + + + + + i = cadData.GetInstanceNames().iterator(); + CurrSubCellNum = 0; + + out.println( " ( SubCellsConnections" ); + if ( i.hasNext() ) { + + out.println( " ( list" ); + + MessageFormat subcellfmt = new MessageFormat( " ( list \"{0}\" {1} )" ); + while( i.hasNext() ) { + String CurrSubCellInst = ( String ) i.next(); + String[] subcellstrs = { CurrSubCellInst, + GetSubCellConnectionsString( CurrSubCellNum ) }; + out.println( subcellfmt.format( subcellstrs ) ) ; + ++CurrSubCellNum; + } + + out.println( " )" ); + + } + else { + out.println( "nil" ); + } + + out.println( " )" ) ; + + i = cadData.GetExportedNets().iterator() ; + out.println( " ( ExportedNets"); + if ( i.hasNext() ) { + + out.println( " ( list" ); + + while ( i.hasNext() ) { + + String CurrPortNet ; + CurrPortNet = ( String ) i.next(); + + out.print( "\""); + out.print( CurrPortNet ); + out.println( "\"" ); + } + + + out.println( " )" ); + + } + else{ + out.println( "nil" ); + } + + out.println( " )" ) ; + + out.println( " )" ) ; + + out.println( "( list" ); + out.println( "nil" ); + out.println( "( list" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "nil" ); + out.println( "SubCellsConnections" ) ; + out.println( "ExportedNets" ); + out.println( "nil" ); + + + + /*out.println( "( list" ); + i = cadData.GetNetNames().iterator() ; + CurrNetNum = 0; + while ( i.hasNext() ) { + final String CurrNetName = ( String ) i.next() ; + out.println( " ( list" ); + out.print( " \""); + out.print( CurrNetName ); + out.println( "\"" ); + out.print( " ( "); + out.print( MakeNetAliasesFuncName( CurrNetNum ) ); + out.println(" )" ); + out.println(" )" ); + ++CurrNetNum; + } + out.println(" )" );*/ + out.println( "nil" ); + + out.println( ")" ); + out.println( ")" ); + out.println( ")" ); + + + out.println( ")" ); + out.flush(); + + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/SubCellFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/SubCellFile.java new file mode 100644 index 0000000000..3d42e8df4d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cadencize/SubCellFile.java @@ -0,0 +1,177 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cadencize; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.util.Map; +import java.util.TreeMap; + +final class SubCellFile { + private BufferedReader m_BufferedReader; + private InputStreamReader m_Reader; + private InputStream m_Stream; + private TreeMap m_InstTypes; + private boolean m_StreamDone; + + private int GetChar( ) throws java.io.IOException { + int c; + c = m_BufferedReader.read(); + if ( c == -1 ) { + m_StreamDone = true; + } + return c; + } + + private void EatWhiteSpace( ) throws java.io.IOException { + int c; + StringBuffer ret = new StringBuffer(); + + do { + m_BufferedReader.mark( 1 ); + c = GetChar(); + } while ( ( c != -1 ) && ( Character.isWhitespace( ( char ) c ) ) ) ; + + if ( c != -1 ) { + m_BufferedReader.reset() ; + } + } + + private String GetNextWord( ) throws java.io.IOException { + int c; + boolean bIsSpace; + StringBuffer ret = new StringBuffer(); + + EatWhiteSpace(); + + do { + c = GetChar(); + bIsSpace = Character.isWhitespace( (char) c); + if ( ( c != -1 ) && ( ! ( bIsSpace ) ) ) { + ret.append( ( char ) c ); + } + } while ( ( c != -1 ) && ( ! ( bIsSpace ) ) ) ; + + return ret.toString(); + } + + private static String MungeCellTypeName( String Src ) { + + int Index = 0; + StringBuffer ret = new StringBuffer(); + + while ( Index < Src.length() ) { + if ( Src.charAt( Index ) == '/' ) { + ret.append( '-' ) ; + } + else{ + ret.append( Src.charAt( Index ) ); + } + ++Index; + } + + return ret.toString(); + } + + static String CononicalizeSubCellInstanceName( String Src ) { + int Index = 0 ; + StringBuffer ret = new StringBuffer(); + + while ( Index < Src.length() ) { + while ( ( Index < Src.length() ) && + ( Src.charAt( Index ) != '[' ) && + ( Src.charAt( Index ) != '(' ) ) { + if ( ( Index < ( Src.length() - 1 ) ) || Src.charAt( Index ) != '.' ) { + ret.append( Src.charAt( Index ) ); + } + ++Index; + } + + if ( Index < Src.length() ){ + + switch ( Src.charAt( Index ) ) { + case '[': + case '(': + ret.append( '[' ); + ++Index; + break; + default: + Index = Src.length(); + break; + } + + while ( ( Index < Src.length() ) && + ( Src.charAt( Index ) != ']' ) && + ( Src.charAt( Index ) != ')' ) ) { + if ( Src.charAt( Index ) == ',' ) { + ret.append( "][" ); + } + else { + if ( ( Index < ( Src.length() - 1 ) ) || Src.charAt( Index ) != '.' ) { + ret.append( Src.charAt( Index ) ); + } + } + ++Index; + } + + if ( Index < Src.length() ) { + switch ( Src.charAt( Index ) ) { + case ']': + case ')': + ret.append( ']' ); + ++Index; + break; + default: + Index = Src.length(); + break; + } + } + } + } + return ret.toString(); + } + + + static String MungeArrayEntry( String Src ) { + + return CononicalizeSubCellInstanceName( Src ); + + } + + + public SubCellFile( InputStream Stream ) throws java.io.IOException { + m_Stream = Stream; + m_Reader = new InputStreamReader( Stream, "UTF-8" ); + m_BufferedReader = new BufferedReader( m_Reader ) ; + m_StreamDone = false; + m_InstTypes = new TreeMap(); + parse(); + } + + private void parse( ) throws java.io.IOException { + while ( ! m_StreamDone ) { + String SubType = MungeCellTypeName( GetNextWord() ) ; + String InstName = MungeArrayEntry( GetNextWord() ) ; + if ( ! ( m_StreamDone ) ) { +// System.out.print( "\"" ) ; +// System.out.print( SubType ); +// System.out.print( "\" \"" ); +// System.out.print( InstName ); +// System.out.println( "\""); + m_InstTypes.put( InstName, SubType ); + } + } + } + + Map GetInstanceTypeMap( ) { + return m_InstTypes; + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/Cast2Def.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/Cast2Def.java new file mode 100644 index 0000000000..3630d58215 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/Cast2Def.java @@ -0,0 +1,539 @@ +package com.avlsi.tools.cast2def; + +import java.io.IOException; +import java.io.FileWriter; +import java.io.Writer; +import java.text.MessageFormat; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeMap; + +import com.avlsi.file.cdl.util.rename.*; +import com.avlsi.file.common.HierName; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.Value; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.io.FileSearchPath; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cell.CellConstants; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.ObjectUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsUtil; +import com.avlsi.util.cmdlineargs.CommandLineArgFormatException; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.debug.Debug; + +public class Cast2Def { + static abstract class Formatter { + protected final Writer w; + protected final CDLNameInterface renamer; + protected final CellInterface cell; + protected final float wireLambda; + private final Cadencize cad; + private final Float widthDefault; + private final Float spaceDefault; + private final static float EPSILON = 0.00001f; + public final static int WIDTH_DEFAULT_FACTOR = 7; // W=7*wireLambda + public final static int SPACE_DEFAULT_FACTOR = 6; // S=6*wireLambda + + public Formatter(final Writer w, final CellInterface cell, + final Cadencize cad, + final float wireLambda, final Float widthDefault, + final Float spaceDefault) { + this.w = w; + this.cell = cell; + this.cad = cad; + this.renamer = new CadenceNameInterface(); + this.wireLambda = wireLambda; + this.widthDefault = widthDefault; + this.spaceDefault = spaceDefault; + } + + protected String renameCell(final String cellName) { + try { + return renamer.renameCell(cellName); + } catch (CDLRenameException e) { + throw new RuntimeException("Cannot rename cell " + cellName, e); + } + } + + protected String renameNet(final HierName net) { + try { + return renamer.renameNode(net.getAsString('.')); + } catch (CDLRenameException e) { + throw new RuntimeException("Cannot rename node " + net, e); + } + } + + private int discretize(final Float val) { + return (int) Math.ceil(val.floatValue() / wireLambda - EPSILON); + } + + private String getRule(Float width, Float space, Boolean reset) { + if (width == null) width = widthDefault; + if (space == null) space = spaceDefault; + if (reset == null) reset = Boolean.FALSE; + + int w = discretize(width); + int s = discretize(space); + + if (w < WIDTH_DEFAULT_FACTOR) w = WIDTH_DEFAULT_FACTOR; + if (s < SPACE_DEFAULT_FACTOR) s = SPACE_DEFAULT_FACTOR; + + if (reset.booleanValue()) { + // return "RESET_WIRE"; // use special nondefault W and S + } + + return w + "W" + s + "S"; + } + + private void putDirective(final CellInterface cell, + final HierName prefix, + final String dir, + final AliasedMap ports, + final Map result) { + final Map dirs = DirectiveUtils.getSubcellDirective( + cell, dir, DirectiveConstants.NODE_TYPE); + for (final Iterator i = dirs.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName local = (HierName) entry.getKey(); + if (prefix == null || !ports.contains(local)) { + result.put(HierName.append(prefix, local), + entry.getValue()); + } + } + } + + private void getRoutedDirective(final CellInterface cell, + final HierName prefix, + final Map wireWidth, + final Map wireSpace, + final Map resetNet, + final Set nodes, + final Set propagated) { + if (propagated.add(cell)) { + DirectiveUtils.propagateWireDirective(cell, cad); + } + + final AliasedSet locals = cad.convert(cell).getLocalNodes(); + final AliasedMap ports = cad.convert(cell).getPortNodes(); + for (Iterator i = locals.getCanonicalKeys(); i.hasNext(); ) { + final HierName local = (HierName) i.next(); + if (prefix == null || !ports.contains(local)) { + nodes.add(HierName.append(prefix, local)); + } + } + + putDirective(cell, prefix, DirectiveConstants.WIREWIDTH, ports, + wireWidth); + putDirective(cell, prefix, DirectiveConstants.WIRESPACE, ports, + wireSpace); + putDirective(cell, prefix, DirectiveConstants.RESET_NET, ports, + resetNet); + + final Map m = DirectiveUtils.getSubcellDirective(cell, + DirectiveConstants.ROUTED, + DirectiveConstants.INSTANCE_TYPE); + + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final Boolean inlineSubcell = (Boolean) m.get(subcellName); + final boolean unrouted = + !CellUtils.isRouted(subcell) || + (inlineSubcell != null && !inlineSubcell.booleanValue()); + + if (unrouted && !subcell.isChannel() && !subcell.isNode() && + !CellUtils.isLeaf(subcell)) { + getRoutedDirective(subcell, + HierName.append(prefix, subcellName), + wireWidth, + wireSpace, + resetNet, + nodes, + propagated); + } + } + } + + protected Map findProperty() throws IOException { + final Set propagated = new HashSet(); + final Set nodes = new HashSet(); + + final Map wireWidth = new HashMap(); + final Map wireSpace = new HashMap(); + final Map resetNet = new HashMap(); + getRoutedDirective(cell, null, wireWidth, wireSpace, resetNet, + nodes, new HashSet()); + + final Map result = new TreeMap(); + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + final HierName key = (HierName) i.next(); + final Float width = (Float) wireWidth.get(key); + final Float space = (Float) wireSpace.get(key); + final Boolean reset = (Boolean) resetNet.get(key); + final String rule = getRule(width, space, reset); + if (rule != null) result.put(key, rule); + } + + return result; + } + + protected void header() throws IOException { } + protected void footer() throws IOException { } + protected void nets() throws IOException { } + + public void output() throws IOException { + header(); + nets(); + footer(); + } + } + + static class DefFormatter extends Formatter { + private final String version; + private final String dividerChar; + private final String busBitChars; + private final String ruleDefault; + private final UnaryPredicate filter; + public DefFormatter(final String version, final String dividerChar, + final String busBitChars, final Writer w, + final CellInterface cell, final Cadencize cad, + final float wireLambda, final Float widthDefault, + final Float spaceDefault, final String ruleDefault, + final UnaryPredicate filter) { + super(w, cell, cad, wireLambda, widthDefault, spaceDefault); + this.version = version; + this.dividerChar = dividerChar; + this.busBitChars = busBitChars; + this.ruleDefault = ruleDefault; + this.filter = filter; + } + + public DefFormatter(final Writer w, final CellInterface cell, + final Cadencize cad, + final float wireLambda, + final Float widthDefault, final Float spaceDefault, + final String ruleDefault, + final UnaryPredicate filter) { + this("5.5", "|", "<>", w, cell, cad, wireLambda, + widthDefault, spaceDefault, ruleDefault, filter); + } + + private static final MessageFormat HEADER = new MessageFormat( + "VERSION {0} ;\n" + + "NAMESCASESENSITIVE ON ;\n" + + "DIVIDERCHAR \"{1}\" ;\n" + + "BUSBITCHARS \"{2}\" ;\n" + + "DESIGN {3} ;\n"); + + protected void header() throws IOException { + w.write( + HEADER.format( + new Object[] { + version, + dividerChar, + busBitChars, + renameCell(cell.getFullyQualifiedType())})); + w.write("# wire lambda = " + wireLambda + " default rule = " + + (ruleDefault == null ? "none" : ruleDefault) + "\n"); + } + + protected void footer() throws IOException { + w.write("END DESIGN\n"); + } + + private void netRule(final HierName node, final String rule) + throws IOException { + w.write(" - " + renameNet(node) + " + NONDEFAULTRULE " + rule + + " ;\n"); + } + + protected void nets() throws IOException { + final Map result = findProperty(); + int count = 0; + for (Iterator i = + new FilteringIterator(result.entrySet().iterator(), + filter); i.hasNext(); + i.next(), ++count); + w.write("NETS " + count + " ;\n"); + + for (Iterator i = + new FilteringIterator(result.entrySet().iterator(), + filter); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName node = (HierName) entry.getKey(); + final String rule = (String) entry.getValue(); + netRule(node, rule); + } + + w.write("END NETS\n"); + } + } + + static class SkillFormatter extends Formatter { + private final String ruleDefault; + private final UnaryPredicate filter; + public SkillFormatter(final Writer w, final CellInterface cell, + final Cadencize cad, + final float wireLambda, + final Float widthDefault, + final Float spaceDefault, + final String ruleDefault, + final UnaryPredicate filter) { + super(w, cell, cad, wireLambda, widthDefault, spaceDefault); + this.ruleDefault = ruleDefault; + this.filter = filter; + } + + protected void header() throws IOException { + w.write("; wire lambda = " + wireLambda + " default rule = " + + (ruleDefault == null ? "none" : ruleDefault) + "\n"); + w.write("NondefaultRoutingDirective=nil\n"); + } + + protected void nets() throws IOException { + final Map result = findProperty(); + final MultiMap inverse = new MultiMap(); + + for (Iterator i = + new FilteringIterator(result.entrySet().iterator(), + filter); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName node = (HierName) entry.getKey(); + final String rule = (String) entry.getValue(); + inverse.put(rule, node); + } + + for (Iterator i = inverse.keySet().iterator(); i.hasNext(); ) { + final String rule = (String) i.next(); + w.write("NondefaultRoutingDirective=cons("); + w.write(" list( \"" + rule + "\""); + + final Collection nets = (Collection) inverse.get(rule); + for (Iterator j = nets.iterator(); j.hasNext(); ) { + w.write(" \"" + renameNet((HierName) j.next()) + "\""); + } + + w.write(")\n"); + w.write(" NondefaultRoutingDirective)\n"); + } + } + } + + static class TxtFormatter extends Formatter { + private final UnaryPredicate filter; + public TxtFormatter(final Writer w, final CellInterface cell, + final Cadencize cad, + final float wireLambda, + final Float widthDefault, final Float spaceDefault, + final UnaryPredicate filter) { + super(w, cell, cad, wireLambda, widthDefault, spaceDefault); + this.filter = filter; + } + + protected void nets() throws IOException { + final Map result = findProperty(); + + for (Iterator i = + new FilteringIterator(result.entrySet().iterator(), + filter); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName node = (HierName) entry.getKey(); + final String rule = (String) entry.getValue(); + w.write(renameNet(node) + " " + rule + "\n"); + } + } + } + + private static void usage( String m ) { + System.err.println( +"Usage: cast2def --cast-path=\n" + +" --cell=\n" + +" --outfile= (output file)\n" + +" [--format=[def|skill|txt] (output format of the wiring rules)]\n" + +" [--cadence-name (cell name is a Cadence name)]\n" + +" [--ignore-ports (do not generate output for ports)]\n" + +" [--default-width=width (default wire width; 2*lambda)]\n" + +" [--default-space=space (default wire space; 2*lambda)]\n" + +" [--default-rule=rule (default rule name, not output; 7W6S)]\n" + +" [--lambda=lambda (wire lambda)"); + if (m != null && m.length() > 0) + System.err.println( m ); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl(args); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + if (theArgs.argExists("version")) { + System.out.println(com.avlsi.util.debug.VersionInfo.getVersionString +(Cast2Def.class)); + } + + final String castPath = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cell", null); + final String outfile = theArgs.getArgValue("outfile", null); + final String format = theArgs.getArgValue("format", "def"); + + Float defaultWidth; + Float defaultSpace; + final Float lambda; + try { + defaultWidth = + CommandLineArgsUtil.getFloatArgValue(theArgs, "default-width", + null); + defaultSpace = + CommandLineArgsUtil.getFloatArgValue(theArgs, "default-space", + null); + lambda = + CommandLineArgsUtil.getFloatArgValue(theArgs, "lambda", null); + } catch (CommandLineArgFormatException e) { + System.err.println("Invalid " + e.getArgName() + " argument."); + System.exit(2); + return; + } + + if (cellName == null || outfile == null) { + usage( "\n--cell and/or --outfile not specified" ); + System.exit(1); + } + if (!format.equals("skill") && + !format.equals("def") && + !format.equals("txt")) { + usage( "\n--format must be one of skill, def, or txt" ); + System.exit(1); + } + + final boolean cadenceName = theArgs.argExists("cadence-name"); + final String realCell = cadenceName ? + new CadenceReverseNameInterface().renameCell(cellName) + : cellName; + + final CastFileParser castParser = + new CastFileParser(new FileSearchPath(castPath), castVersion); + final Writer w = new FileWriter(outfile); + final CellInterface ci = castParser.getFullyQualifiedCell(realCell); + + final CellConstants consts = new CellConstants(castParser); + final float wlambda; + if (lambda == null) { + final Environment topConsts = + consts.getTopLevelConstants(ci.getFullyQualifiedType()); + final Value wireLambda = + topConsts.lookup(Symbol.create("WIRE_LAMBDA")); + if (!(wireLambda instanceof FloatValue)) { + System.err.println("Wire lambda not specified on the " + + "command line and undefined in CAST."); + System.exit(2); + } + wlambda = FloatValue.valueOf(wireLambda).toFloat(); + } else { + wlambda = lambda.floatValue(); + } + + if (defaultWidth == null) + defaultWidth = new Float(wlambda * Formatter.WIDTH_DEFAULT_FACTOR); + if (defaultSpace == null) + defaultSpace = new Float(wlambda * Formatter.SPACE_DEFAULT_FACTOR); + + final Cadencize cad = new Cadencize(false); + + final UnaryPredicate portFilter; + if (theArgs.argExists("ignore-ports")) { + final AliasedMap ports = cad.convert(ci).getPortNodes(); + portFilter = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final Map.Entry entry = (Map.Entry) o; + return !ports.contains(entry.getKey()); + } + }; + } else { + portFilter = new UnaryPredicate() { + public boolean evaluate(final Object o) { + return true; + } + }; + } + + final String defaultRule = theArgs.getArgValue("default-rule", "7W6S"); + + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + usage( pedanticArgs.pedanticString() ); + } + + final UnaryPredicate ruleFilter = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final Map.Entry entry = (Map.Entry) o; + return !ObjectUtils.equals(defaultRule, entry.getValue()); + } + }; + + final AliasedSet nodes = cad.convert(ci).getLocalNodes(); + final UnaryPredicate groundFilter = new UnaryPredicate() { + final HierName ground = HierName.makeHierName("GND"); + public boolean evaluate(final Object o) { + final Map.Entry entry = (Map.Entry) o; + return !nodes.areEquivalent(ground, (HierName) entry.getKey()); + } + }; + + final UnaryPredicate filter = new UnaryPredicate() { + public boolean evaluate(final Object o) { + return portFilter.evaluate(o) && groundFilter.evaluate(o) && + ruleFilter.evaluate(o); + } + }; + + final Formatter formatter; + + if (format.equals("skill")) { + formatter = new SkillFormatter(w, ci, cad, wlambda, + defaultWidth, defaultSpace, + defaultRule, filter); + } else if (format.equals("def")) { + formatter = new DefFormatter(w, ci, cad, wlambda, + defaultWidth, defaultSpace, + defaultRule, filter); + } else { + formatter = new TxtFormatter(w, ci, cad, wlambda, + defaultWidth, defaultSpace, filter); + } + + formatter.output(); + w.close(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/cast2def.package.inc b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/cast2def.package.inc new file mode 100644 index 0000000000..d065e8e3ce --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/cast2def.package.inc @@ -0,0 +1,8 @@ +0 1 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.tools.cast2def.Cast2Def +$arch/bin/cast2def.sh cast2def.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/custom.mk new file mode 100644 index 0000000000..f23f19852a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2def/custom.mk @@ -0,0 +1,5 @@ +CURR_RESULT_FILES := $(CURR_TARGET_DIR)/cast2def.sh $(CURR_RESULT_FILES) + +$(CURR_TARGET_DIR)/cast2def.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.cast2def.Cast2Def/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/Cast2Skill.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/Cast2Skill.java new file mode 100644 index 0000000000..8855e3a821 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/Cast2Skill.java @@ -0,0 +1,763 @@ +/* + * Copyright 2002-2009 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cast2skill; + + + + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.HashSet; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Collection; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import java.io.File; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.Writer; +import java.io.OutputStreamWriter; +import java.io.BufferedWriter; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.Reader; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.FileNotFoundException; + +import java.text.MessageFormat; + +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.FileUtil; + +import com.avlsi.util.container.SortingIterator; + +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; + +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.ports.PortDefinition; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; + +import com.avlsi.cast.impl.Environment; + +import com.avlsi.cast2.directive.DirectiveConstants; + +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; + +import com.avlsi.layout.CellProcessor; +import com.avlsi.layout.CellProcessorInterface; +import com.avlsi.layout.CellProcessorException; +import com.avlsi.layout.CellDirs2Skill; +import com.avlsi.layout.AutoPins; +import com.avlsi.layout.PinPlaceException; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLstat; +import com.avlsi.file.cdl.parser.SplittingFactory; +import com.avlsi.file.cdl.parser.CellSetFactory; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.CDLLexer; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameFactory; +import com.avlsi.file.cdl.util.rename.TrivialCDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; + +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; + +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; + +import com.avlsi.tools.cdl2skill.CDL2SkillFactory; + +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; + +import com.avlsi.tools.ipgen.HashMapTableEmitterFactory; +import com.avlsi.tools.ipgen.TablifyingNameInterfaceFactory; + +import com.avlsi.tools.jauto.Cast2Cdl; +import com.avlsi.tools.jauto.Floorplan; +import com.avlsi.tools.jauto.TechnologyData; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.tools.prs2verilog.GeneratePortMapping; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; + +public final class Cast2Skill { + + private interface CellProcessorFactory { + CellProcessorInterface getCellProcessor( final CellInterface ci ); + } + + + private static class RoutedCastParser { + private final CastFileParser castParser; + private final boolean routed; + private final boolean rootOnly; + private final Map cache; + public RoutedCastParser(final CastFileParser castParser, + final boolean routed, + final boolean rootOnly) { + this.castParser = castParser; + this.routed = routed; + this.rootOnly = rootOnly; + this.cache = new HashMap(); + } + public CellInterface getFullyQualifiedCell(final String name) + throws CastSemanticException { + final CellInterface candidate = + castParser.getFullyQualifiedCell(name); + if (routed) { + final String type = candidate.getFullyQualifiedType(); + CellInterface cached = cache.get(type); + if (cached == null) { + cached = candidate.routedSubcells(!rootOnly); + cache.put(type, cached); + } + return cached; + } else { + return candidate; + } + } + } + + private static void processCells( final CellProcessorFactory cellProcessorFactory, + final RoutedCastParser castParser, + final Collection castCellNameCollection, + final HashMapTableEmitterFactory castNameToCadenceNameMap, + final File outputDir, + final String fileNameSuffix ) throws Exception { + + final Iterator cellNameIter = castCellNameCollection.iterator(); + + while ( cellNameIter.hasNext() ) { + + final String currCellName = ( String ) cellNameIter.next(); + + final String cadenceCellName = castNameToCadenceNameMap.getCadenceCellNameForCastCellName( currCellName ); + assert cadenceCellName != null ; + + final File currOutputFile = new File( outputDir, cadenceCellName + fileNameSuffix ); + + final OutputStream currOutputStream = new FileOutputStream( currOutputFile ); + + final Writer currOutputWriter = + new BufferedWriter( new OutputStreamWriter( currOutputStream, "UTF-8" ) ); + + final CellInterface currCell = castParser.getFullyQualifiedCell( currCellName ); + + final CellProcessorInterface currProcessor = cellProcessorFactory.getCellProcessor( currCell ); + + System.out.println( "Generating \"" + currOutputFile.getAbsolutePath() + "\"." ); + + try { + currProcessor.process( currOutputWriter ); + } + catch( CellProcessorException e ) { + System.out.println( e ); + } + + currOutputWriter.close(); + + } + + } + + private static void usage( ) { + final String className = Cast2Skill.class.getName(); + + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className + "\n" + + " --cast-path= (defaults to .)\n" + + " --cast-version= (defaults to 2)\n" + + " --cell= (name of cell to process)\n" + + " | --cells= (containing list of cells to process)\n" + + " --output-dir=\n" + + " [ --cadence-name ]\n" + + " [ --cell-height=num ]\n" + + " [ --do-file-template=file --uu-per-meter=num ]\n" + + " [ --ignore-netlist ]\n" + + " [ --instances-dir=dir ]\n" + + " [ --library-list=file ]\n" + + " [ --pin-type=pitched|inplace ]\n" + + " [ --root-only ]\n" + + " [ --suppress-directives ]\n" + + " [ --suppress-pins ]"); + } + + public static Set filterGatesAndStacks( final Set srcCellSet, + final RoutedCastParser castParser ) + throws CastSemanticException { + + final Set ret = new HashSet(); + + final Iterator cellIter = srcCellSet.iterator(); + + while ( cellIter.hasNext() ) { + final String cellName = ( String ) cellIter.next(); + + final CellInterface cell = castParser.getFullyQualifiedCell( cellName ); + + final Boolean isNetlistPrimitive = ( Boolean ) + DirectiveUtils.getTopLevelDirective( cell, "netlist_primitive" ); + + if ( ( isNetlistPrimitive == null ) || + ( ! ( isNetlistPrimitive.booleanValue() ) ) ) { + ret.add( cellName ); + } + } + return ret; + } + + + public static void writeStringCollectionToFile( final File targetFile, + final Collection stringCollection ) + throws IOException + { + final OutputStream targetStream = new FileOutputStream( targetFile ); + final Writer targetWriter = + new BufferedWriter( new OutputStreamWriter( targetStream, "UTF-8" ) ); + + final Iterator strIter = stringCollection.iterator(); + + while( strIter.hasNext() ) { + final String str = ( String ) strIter.next(); + targetWriter.write( str + "\n" ); + } + targetWriter.close(); + } + + public static void main( final String args[] ) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + final String castPath = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final List cellsToProcess = new ArrayList(); + if(theArgs.argExists("cell") ) { + final String givenCellName = theArgs.getArgValue("cell", null); + cellsToProcess.add(givenCellName); + } else { + if(!theArgs.argExists("cells") ) { + System.err.println("Must specify --cell or --cells"); + usage(); + System.exit(1); + } + final String cellsFileName = theArgs.getArgValue("cells", null); + final File cellsFile = new File(cellsFileName); + cellsToProcess.addAll(FileUtil.getLines(cellsFile)); + } + + final TechnologyData techData; + try { + techData = TechnologyData.getTechnologyData(theArgs); + } catch (Exception e) { + System.err.println("Can't load technology data: " + + e.getMessage()); + System.exit(1); + return; + } + + final CadenceReverseNameInterface crni = + new CadenceReverseNameInterface(); + if( theArgs.argExists( "cadence-name" ) ) { + for(int i=0;i sizeError = new HashSet(); + final CDL2SkillFactory skillFactory = + new CDL2SkillFactory( skillNetlistOutputDir, + skillFunctionPrefix, + skillTableName, + libSet, + cadenceCellNameList, + cellTemplateMap, + cellStatMap, + techData ) { + protected String makeStatisticsString( + final String subckt, + final CDLstat.CellStat stat ) { + final StringBuffer sb = + new StringBuffer(super.makeStatisticsString( subckt, stat ) ); + final String castName; + try { + castName = crni.renameCell( subckt ); + } catch (Exception e) { + throw new AssertionError( + "Can't rename: " + subckt ); + } + + try { + final CDLstat.EstimatedSize estimate = + CDLstat.getEstimatedSize( + castParser.getFullyQualifiedCell( + castName ), + stat ); + sizeEstimateFormatter.format( + new Object[] { estimate.width, + estimate.height }, + sb, + null ); + } catch (Exception e) { + sizeError.add(castName + ": " + e.getMessage()); + } + + return sb.toString(); + } + }; + + final CDLNameInterface cadenceNameInterface = + new CadenceNameInterface( ); + + final CDLNameInterfaceFactory cadenceNameInterfaceFactory = + new TrivialCDLNameInterfaceFactory( cadenceNameInterface ); + + final HashMapTableEmitterFactory hashTableEmitterFactory = + new HashMapTableEmitterFactory(); + + final TablifyingNameInterfaceFactory nameInterfaceFactory = + new TablifyingNameInterfaceFactory( hashTableEmitterFactory, + cadenceNameInterfaceFactory, + cadenceNameInterfaceFactory ); + + final CDLFactoryInterface factory1 = + new SplittingFactory( templateFactory, + skillFactory ); + + final Set allCellsSet = new HashSet(); + final CDLFactoryInterface cellSetFactory = + new CellSetFactory( allCellsSet ); + + final CDLFactoryInterface renamingFactory = + new CDLRenameFactory( factory1, nameInterfaceFactory ); + + final CDLFactoryInterface factory2 = + new SplittingFactory( renamingFactory, cellSetFactory ); + + final CDLFactoryInterface trueNamesEmitter = + new Cast2Cdl.RealTransistorNames(factory2, realParser); + + //XXX - This will duplicate output of subcells + for(Iterator i=cellsToProcess.iterator();i.hasNext();) { + final String c = (String)i.next(); + final CellInterface ci = + castParser.getFullyQualifiedCell( c ); + + Cast2Cdl.outputCDL(ci, + realParser, + trueNamesEmitter, + cadencizer, + false, + false, + true, + ! ignoreNetlist, + true); + } + + if ( ! ignoreNetlist && skillFactory.getError() != null ) { + throw new RuntimeException( skillFactory.getError() ); + } + + if ( ! ignoreNetlist && ! sizeError.isEmpty() ) { + System.err.println( + "Error estimating geometry of the following cell: " ); + for ( String err : sizeError ) { + System.err.println( "\t" + err ); + } + System.exit( 1 ); + } + + final File cadenceCellNameListFile = + new File( outputDir, "cellnames.txt" ); + + writeStringCollectionToFile( cadenceCellNameListFile, + cadenceCellNameList ); + + final File cadenceLibListFile = + new File( outputDir, "libnames.txt" ); + + writeStringCollectionToFile( cadenceLibListFile, libSet ); + + final Set cellSet; + if ( rootOnly ) { + cellSet = new HashSet(); + cellSet.addAll( cellsToProcess ); + } + else { + cellSet = filterGatesAndStacks( allCellsSet, + castParser ); + } + + if ( ! ( theArgs.argExists( "suppress-directives" ) ) ) { + + final File skillDirectivesOutputDir = new File( outputDir, "ildirectives" ); + if ( ! ( skillDirectivesOutputDir.exists() ) ) { + skillDirectivesOutputDir.mkdirs(); + } + + final boolean suppress = + theArgs.argExists( "suppress-wiring-directives" ); + + final CellProcessorFactory directivesCellProcessorFactory = + new CellProcessorFactory () { + public CellProcessorInterface getCellProcessor( final CellInterface ci ) { + if (!suppress) { + //prepare cell by propagating wire directives + DirectiveUtils.propagateWireDirective( + ci, cadencizer ); + } + return new CellDirs2Skill( ci, suppress ); + } + }; + + processCells( directivesCellProcessorFactory, + castParser, + cellSet, + hashTableEmitterFactory, + skillDirectivesOutputDir, + ".directives.il" ); + } + + if ( ! ( theArgs.argExists( "suppress-pins" ) ) ) { + + final File autoPinsDir = new File( outputDir, "autopins" ); + if ( ! ( autoPinsDir.exists() ) ) { + autoPinsDir.mkdirs(); + } + + String heightString = theArgs.getArgValue( "cell-height", null ); + float height = 0; + if ( heightString != null ) { + try { + height = Float.parseFloat( heightString ); + } + catch ( NumberFormatException e ) { + System.out.println( "\"" + heightString + "\" is not a valid number." ); + heightString = null; + height = 0; + } + } + final float cellHeight = height; + final String pinType = theArgs.getArgValue( "pin-type", null ); + + final CellProcessorFactory pinsCellProcessorFactory = + new CellProcessorFactory () { + public CellProcessorInterface getCellProcessor( final CellInterface ci ) { + try { + return new AutoPins( ci, cadencizer, pinType, + cellHeight ); + } catch(PinPlaceException e) { + throw new RuntimeException(e); + } + } + }; + + processCells( pinsCellProcessorFactory, + castParser, + cellSet, + hashTableEmitterFactory, + autoPinsDir, + ".pins.il" ); + } + + final String verilogBlock = theArgs.getArgValue( "verilog-block", "rtl"); + final CDLNameInterface ni = new CadenceNameInterface(); + + for(int c=0;c seen = new HashSet(); + i = new SortingIterator(mp.keySet().iterator()); + for (; i.hasNext(); ) { + final String s = (String) i.next(); + final HierName hs; + try { + hs = HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName: " + s, e); + } + final HierName canon = (HierName) ports.getCanonicalKey(hs); + if (((Boolean) ports.getValue(hs)).booleanValue() && + seen.add(canon)) { + String c1 = ni.renameNode(canon.getCadenceString()); + for (Iterator j = nodes.getAliases(canon); j.hasNext(); ) { + final HierName aName= (HierName) j.next(); + if (!aName.equals(canon) && !aName.isAnonymous()) { + if (pincnt % pinsPerSegment == 0) { + if (pincnt != 0) { + currOutputWriter2.write(" Table ) )\n\n"); + } + numsegments++; + currOutputWriter2.write("(defun PinCanonicalTable"+numsegments+" ( )\n"); + currOutputWriter2.write(" (let (\n"); + currOutputWriter2.write(" ( Table ( makeTable `pd nil ) ) )\n"); + } + pincnt++; + currOutputWriter2.write(" ( setarray Table \""+ni.renameNode(aName.getCadenceString())+"\" "); + currOutputWriter2.write(" \""+c1+"\" "); + currOutputWriter2.write(" )\n"); + } + } + } + } + if (pincnt > 0) + currOutputWriter2.write(" Table ) )\n\n"); + currOutputWriter2.write("(defun PinCanonicalTable ( )\n"); + currOutputWriter2.write(" (let ( Key map \n"); + currOutputWriter2.write(" ( Table ( makeTable `pd nil ) ) )\n"); + for (int segment = 1; segment <= numsegments; segment++) { + currOutputWriter2.write(" map = PinCanonicalTable"+segment+"( )\n"); + currOutputWriter2.write(" foreach( Key map\n"); + currOutputWriter2.write(" ( setarray Table Key arrayref( map Key ) ) )\n"); + } + currOutputWriter2.write(" Table ) )\n\n"); + currOutputWriter2.close(); + } + } catch (CastSemanticException e) { + ExceptionPrettyPrinter.printException(e); + System.exit(1); + } + else { + if ( outputDirName == null ) { + System.out.println( "You must specify an output directory." ); + } + else if ( ! ( outputDir.isDirectory() ) ) { + System.out.println( "\"" + outputDirName + "\" is not a directory and could not be created." ); + } + usage(); + System.exit(1); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/custom.mk new file mode 100644 index 0000000000..4af57a9699 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2skill/custom.mk @@ -0,0 +1,9 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ +CURR_RESULT_FILES := $(CURR_TARGET_DIR)/cast2skill.sh $(CURR_RESULT_FILES) + +$(CURR_TARGET_DIR)/cast2skill.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.cast2skill.Cast2Skill/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/Cast2Verilog.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/Cast2Verilog.java new file mode 100644 index 0000000000..e13fd41318 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/Cast2Verilog.java @@ -0,0 +1,3325 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cast2verilog; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.Integer; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.text.MessageFormat; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.impl.CastParsingOption; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.NoSuchEnvironmentException; +import com.avlsi.csp.csp2java.SemanticException; +import com.avlsi.csp.csp2verilog.Csp2Verilog; +import com.avlsi.csp.util.CSPCellInfo; +import com.avlsi.csp.util.UniqueLabel; +import com.avlsi.csp.util.ProblemFilter; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.ports.ArrayType; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.fast.ports.StructureType; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.common.HierName; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.NullWriter; +import com.avlsi.prs.ProductionRule; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cosim.ChannelTimingInfo; +import com.avlsi.tools.cosim.CoSimParameters; +import com.avlsi.tools.cosim.CoSimHelper; +import com.avlsi.tools.cosim.JavaCoSimInfo; +import com.avlsi.tools.cosim.spec.CoSim; +import com.avlsi.tools.cosim.spec.CoSimSpec; +import com.avlsi.tools.cosim.spec.CoSimSpecList; +import com.avlsi.tools.cosim.spec.InstSpec; +import com.avlsi.tools.cosim.spec.InstSpecList; +import com.avlsi.tools.cosim.spec.Mode; +import com.avlsi.tools.cosim.spec.ModeList; +import com.avlsi.tools.cosim.spec.ModeListLevelSpec; +import com.avlsi.tools.dsim.InstanceData; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.tools.prs2verilog.Prs2Verilog; +import com.avlsi.tools.prs2verilog.ConverterConstants; +import com.avlsi.tools.prs2verilog.verilog.VerilogUtil; +import com.avlsi.tools.prs2verilog.verilog.VerilogVisitor; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.FlatteningIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.text.NaturalStringComparator; +import com.avlsi.util.text.StringUtil; + + + +/** + * Generates Verilog from Cast + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public class Cast2Verilog { + + private final PrintWriter warningWriter; + private final PrintWriter errorWriter; + private final PrintWriter debugWriter; + private final CoSimParameters params; + private Set prsBehavior; + private final Map leafDelayBias; + private final Map leafExtraDelay; + private static final String resetNodeName = "_RESET"; + private static final String delaybiasAnnotationName = + "CAST2VERILOG_ANNOTATE_DELAYBIAS"; + private static final String extraDelayAnnotationName = + "CAST2VERILOG_ANNOTATE_EXTRADELAY"; + private final Set /*>*/ usedWide2NarrowConvs = + new TreeSet (new Comparator() { + public int compare(final Object o1, final Object o2) { + final int[] i1 = (int[]) o1; + final int[] i2 = (int[]) o2; + for (int i = 0; i < 3; ++i) { + if (i1[i] != i2[i]) return i1[i] - i2[i]; + } + return 0; + } + }); + + private final Map subcellNames; + + private final Set convertedCells; + /** + * Number of bits to use for variables + **/ + private final int registerBitWidth; + + /** + * Files depended on by verilog blocks. + **/ + private final Set validVerilogFiles = new LinkedHashSet(); + + /** + * Names of cells that has been translated by Prs2Verilog. + **/ + private final Set prsDone = new HashSet(); + + private static final Logger logger = + Logger.getLogger("com.avlsi.tools.cast2verilog"); + + private ProblemFilter probFilter = null; + + /** + * Whether to emit SystemVerilog constructs + **/ + private boolean enableSystemVerilog; + + /** + * Whether to surround module definitions with ifdefs to prevent + * redefinition. + **/ + private boolean generateIfDef; + + /** + * Set to true if errors were encountered during translation. + **/ + private boolean errorExist; + + private Cadencize vcad = null; // Verilog Cadencize + private Cadencize cad = null; // non-Verilog Cadencize + + private static class IgnoreWiring extends Cadencize.DefaultCallback { + public IgnoreWiring(final int considerVerilog) { + super(considerVerilog); + } + public boolean used(CellInterface cell, HierName portCanon, + boolean wiring, boolean used) { + return used; + } + } + + private Cadencize getCadencize(boolean verilog) { + if (verilog) { + // exclusion properties required for netgraph operations in + // Prs2Verilog.emitVerilogBlock + if (vcad == null) + vcad = new Cadencize(true, + new IgnoreWiring(Cadencize.VERILOG_ALL)); + return vcad; + } else { + if (cad == null) + cad = new Cadencize(false, + new IgnoreWiring(Cadencize.VERILOG_NONE)); + return cad; + } + } + + public boolean checkError() { + return errorExist; + } + + /** + * Do not write out a Verilog for a single cell more than once. + **/ + private class NoRepeatVisitor implements Prs2Verilog.VisitorFactory { + private Prs2Verilog.SingleWriterVisitor single; + public NoRepeatVisitor(final Writer writer) { + single = new Prs2Verilog.SingleWriterVisitor(writer, true); + } + public VerilogVisitor getVisitor(final String cellName) { + return prsDone.add(cellName) ? single.getVisitor(cellName) : null; + } + public void doneVisitor(final VerilogVisitor visitor) { + single.doneVisitor(visitor); + } + } + + private static class GroupedChannel { + private final CellInterface cell; + private final Map dirs; + private final Map groups; + private final MultiMap/**/ input, output; + public GroupedChannel(final CellInterface cell, + final Map dirs) { + this.cell = cell; + this.dirs = dirs; + this.groups = new HashMap/**/(); + this.input = new MultiMap/**/( + new LinkedHashMap(), MultiMap.ARRAY_LIST_FACTORY); + this.output = new MultiMap/**/( + new LinkedHashMap(), MultiMap.ARRAY_LIST_FACTORY); + } + public String getGroupName(final String channel, final int direction) { + final String groupName = dirs.remove(channel); + if (groupName != null) { + final String group; + int idx = groupName.lastIndexOf('.'); + if (idx < 0) { + group = groupName; + logger.warning("In " + cell.getFullyQualifiedType() + ", " + + "the group directive of " + channel + " " + + "does not contain a dot."); + } else { + group = groupName.substring(0, idx); + } + ((direction == PortDefinition.IN) ? input : output) + .put(group, channel); + groups.put(channel, groupName); + return group; + } else { + return null; + } + } + public String lookupGroupName(final String channel) { + final String group = groups.get(channel); + return group == null ? null : group + "$$" + channel; + } + public boolean checkError() { + boolean hasError = false; + if (!dirs.isEmpty()) { + logger.warning(cell.getFullyQualifiedType() + " contains " + + "group directives that didn't take effect: " + + dirs); + } + for (Iterator i = input.keySet().iterator(); i.hasNext(); ) { + final String group = (String) i.next(); + final Collection bad = output.get(group); + if (bad != null) { + logger.severe("In " + cell.getFullyQualifiedType() + ", " + + "group " + group + " is associated with " + + "both input and output channels. Input " + + "channels: " + input.get(group) + "; " + + "output channels: " + bad); + hasError = true; + } + } + return hasError; + } + private String v(String group) { + return "\\" + group + "$$v "; + } + private String e(String group) { + return "\\" + group + "$$e "; + } + private String enable(String chan) { + return "\\" + chan + "$enable "; + } + private String data(String chan) { + return "\\" + chan + "$data "; + } + private void writePort(final PrintWriter out, final MultiMap map, + final String valid, final String enable, + final String delim) { + for (Iterator i = map.keySet().iterator(); i.hasNext(); ) { + final String group = (String) i.next(); + out.println(delim); + out.println(valid + " " + v(group) + delim); + out.print(enable + " " + e(group)); + } + } + public void outputPorts(final PrintWriter out) { + writePort(out, input, "input", "output reg", ","); + writePort(out, output, "output reg", "input", ","); + } + public void outputDecl(final PrintWriter out, + final List verilogPorts) { + writePort(out, input, "wire", "wire", ";"); + writePort(out, output, "wire", "wire", ";"); + out.println(';'); + for (VerilogPort port : verilogPorts) { + if (port.getDirection() == VerilogPort.OUTPUT && + port.getGroup() != null) { + out.println("wire " + + (port.getSignedness() ? "signed " : "") + + port.getVector() + + " \\" + port.getName() + " ;"); + } + } + for (Iterator i = input.keySet().iterator(); i.hasNext(); ) { + final String group = (String) i.next(); + final Collection chans = input.get(group); + out.println("`CAST2VERILOG_CELEMENT " + + "#(.width(" + chans.size() + ")) " + + "\\" + group + "$$c ("); + out.println(".out (" + v(group) + "),"); + out.print(".in ({"); + for (Iterator j = chans.iterator(); j.hasNext(); ) { + final String chan = (String) j.next(); + out.print(data(chan) + " >= 0"); + if (j.hasNext()) out.print(",\n "); + } + out.println("})"); + out.println(");"); + } + + for (Iterator i = output.keySet().iterator(); i.hasNext(); ) { + final String group = (String) i.next(); + final Collection chans = output.get(group); + out.println("`CAST2VERILOG_CELEMENT " + + "#(.width(" + chans.size() + ")) " + + "\\" + group + "$$c ("); + out.println(".out (" + e(group) + "),"); + out.print(".in ({"); + for (Iterator j = chans.iterator(); j.hasNext(); ) { + final String chan = (String) j.next(); + out.print(enable(chan)); + if (j.hasNext()) out.print(",\n "); + } + out.println("})"); + out.println(");"); + } + + for (VerilogPort port : verilogPorts) { + if (port.getGroup() != null) { + if (port.getDirection() == VerilogPort.OUTPUT) { + out.println("assign " + + data(port.getGroup().getSecond()) + + " = " + v(port.getGroup().getFirst()) + + " ? \\" + port.getName() + " : -1;"); + } else { + out.println("assign " + + enable(port.getGroup().getSecond()) + + " = " + e(port.getGroup().getFirst()) + + ";"); + } + } + } + } + private void writePort(final PrintWriter out, final MultiMap map, + final boolean output) { + for (Iterator i = map.keySet().iterator(); i.hasNext(); ) { + final String group = (String) i.next(); + for (Iterator j = map.get(group).iterator(); j.hasNext(); ) { + final String chan = (String) j.next(); + out.println(","); + out.print(".\\" + lookupGroupName(chan) + " ("); + if (output) { + out.print("\\" + lookupGroupName(chan) + " "); + } else { + out.print(data(chan)); + } + out.print(")"); + } + out.println(","); + out.println("." + v(group) + " (" + v(group) + "),"); + out.print("." + e(group) + " (" + e(group) + ")"); + } + } + public void outputInstantiation(final PrintWriter out, + final List verilogPorts) { + boolean first = true; + for (VerilogPort port : verilogPorts) { + if (port.getGroup() != null) continue; + if (first) first = false; + else out.println(","); + out.print(".\\" + port.getName() + " (\\" + port.getName() + + " )"); + } + writePort(out, input, false); + writePort(out, output, true); + } + } + + public Cast2Verilog(PrintWriter warningWriter, + PrintWriter errorWriter, + PrintWriter debugWriter, + final CoSimParameters params, + final int registerBitWidth, + final boolean enableSystemVerilog, + final boolean generateIfDef) { + this.subcellNames = new HashMap(); + this.convertedCells = new HashSet /**/ (); + this.warningWriter = warningWriter; + this.errorWriter = errorWriter; + this.debugWriter = debugWriter; + this.params = params; + this.prsBehavior = null; + this.registerBitWidth = registerBitWidth; + this.leafDelayBias = new HashMap(); + this.leafExtraDelay = new HashMap(); + this.enableSystemVerilog = enableSystemVerilog; + this.generateIfDef = generateIfDef; + this.errorExist = false; + } + + /** + * Find the largest blocks that can be processed completely by prs2verilog, + * and store the instance names in prsBehavior. + **/ + private boolean cellBehavior(final CellInterface cell, + final HierName prefix) { + if (cell.isNode() || cell.isChannel()) return true; + final String instance = prefix == null ? null : prefix.getAsString('.'); + final int beh = instance == null ? CoSimParameters.DIGITAL + : params.lookupBehavior(instance); + if (beh == CoSimParameters.DIGITAL) { + boolean prs = true; + if (cell.containsSubcells()) { // mid-level cells + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subinst = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + prs &= + cellBehavior(subcell, + HierName.append(prefix, subinst)); + } + } + if (prs) { + getSubcellName(cell.getFullyQualifiedType(), null); + prsBehavior.add(prefix); + } + return prs; + } else if (beh == CoSimParameters.VERILOG && + params.lookupVerilogLevel(instance) == null) { + throw new RuntimeException("The \"verilog\" behavior is specified for " + cell.getFullyQualifiedType() + "/" + instance + ", but it is not supported. You must specify a named block to use, e.g., \"verilog.rtl\"."); + } + return false; + } + + private void populateLeafDelaybias(final CellInterface cell, + final HierName prefix, + final InstanceData instData, + final String verilogInst, + final Cadencize cad, + boolean wrapperAdded) { + final String instance = prefix == null ? null : prefix.getAsString('.'); + final int beh = instance == null ? CoSimParameters.DIGITAL + : params.lookupBehavior(instance); + String newVerilogInst = verilogInst; + if (beh == CoSimParameters.DIGITAL) { + if (!wrapperAdded && prsBehavior.contains(prefix)) { + newVerilogInst = + (verilogInst == null ? "" : verilogInst + ".") + "_"; + wrapperAdded = true; + } + if (cell.containsSubcells()) { // mid-level cells + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (subcell.isNode() || subcell.isChannel()) continue; + + final HierName subinst = (HierName) p.getFirst(); + final InstanceData newInstData = + instData.translate(cell, subcell, subinst, cad); + populateLeafDelaybias(subcell, + HierName.append(prefix, subinst), + newInstData, + (newVerilogInst == null ? + "" : newVerilogInst + ".") + + VerilogUtil.escapeIfNeeded( + subinst.getAsString('.')), + cad, wrapperAdded); + } + } else if (cell.hasRealProductionRule()) { // leaf cell + final float total = instData.getDelayBias(null); + // we must divide by the cell level delaybias in a leaf cell + // has aleady been taken into account by CellDelay + final float cellDelay = + ((Float) DirectiveUtils.getTopLevelDirective( + cell, DirectiveConstants.DELAYBIAS)).floatValue(); + + // avoid NaNs in case delaybias = 0 in a cell + final float curr = cellDelay == 0 ? 0 : total / cellDelay; + + if (curr != 1) + leafDelayBias.put(newVerilogInst, new Float(curr)); + + final AliasedSet locals = cad.convert(cell).getLocalNodes(); + Map extraDelay = Collections.EMPTY_MAP; + for (Iterator i = cell.getProductionRuleSet() + .getProductionRules(); i.hasNext(); ) { + final ProductionRule prs = (ProductionRule) i.next(); + final HierName target = prs.getTarget(); + final HierName canon = + (HierName) locals.getCanonicalKey(target); + if (extraDelay.containsKey(canon)) continue; + + final float up = instData.getExtraDelay(true, canon); + final float dn = instData.getExtraDelay(false, canon); + if (up != 0 || dn != 0) { + if (extraDelay == Collections.EMPTY_MAP) + extraDelay = new HashMap(); + extraDelay.put(canon, new float[] { up, dn }); + } + } + if (extraDelay != Collections.EMPTY_MAP) + leafExtraDelay.put(newVerilogInst, extraDelay); + } + } + } + + /** + * Return the appropriate module name for a cell with subcells behavior. + **/ + private String getSubcellName(final String type, final Map subcells) { + UniqueLabel label = (UniqueLabel) subcellNames.get(type); + if (label == null) { + label = new UniqueLabel(new HashMap()); + subcellNames.put(type, label); + } + final int n = label.getLabel(subcells); + return type + (n == 0 ? "" : "$" + n); + } + + /** + * Return the behavior associated with an instance. + **/ + private Mode getBehavior(final HierName instance) { + final Mode m; + if (instance == null) m = Mode.SUBCELLS; + else if (prsBehavior.contains(instance)) m = Mode.PRS; + else { + final String inst = instance.getAsString('.'); + switch (params.lookupBehavior(inst)) { + case CoSimParameters.DIGITAL: m = Mode.SUBCELLS; break; + case CoSimParameters.JAVA: m = Mode.JAVA; break; + case CoSimParameters.CSP: m = Mode.CSP; break; + case CoSimParameters.VERILOG: + m = new Mode.VerilogMode(params.lookupVerilogLevel(inst)); + break; + default: + throw new RuntimeException("Csp2Verilog does not support cosimulation: " + inst + " " + params.lookupBehavior(inst)); + } + } + return m; + } + + private void logmem(final String heading) { + logger.info(heading + " memory" + + " total = " + Runtime.getRuntime().totalMemory() + + " max = " + Runtime.getRuntime().maxMemory() + + " free = " + Runtime.getRuntime().freeMemory()); + } + + private void convert(final /*@ non_null @*/ CellInterface cell, + final HierName prefix, + final /*@ non_null @*/ PrintWriter out, + final PrintWriter behOut, + final CommandLineArgs theArgs) + throws SemanticException { + prsBehavior = new HashSet(); + cellBehavior(cell, prefix); + + cad = getCadencize(false); + final InstanceData instData = new InstanceData(); + instData.updateDelayBias(cell); + logmem("cadencize before"); + final AliasedSet localNodes = cad.convert(cell).getLocalNodes(); + logmem("cadencize after"); + instData.updateExtraDelay(cell, localNodes); + if (!theArgs.argExists("ignore-asta-extra-delay")) { + instData.updateAstaExtraDelay(cell, localNodes); + } + populateLeafDelaybias(cell, prefix, instData, null, cad, false); + + final String topName = convert(cell, prefix, out, behOut, true, true, + false, theArgs); + if (probFilter != null && probFilter.hasError()) { + warningWriter.println("Fatal CSP errors found.\n"); + warningWriter.flush(); + System.exit(1); + } + + annotateDelaybias(out, topName); + annotateExtraDelay(out, topName); + } + + private void ifdef(final String name, final PrintWriter out) { + // Even with the ifdefs, in general, it is still not safe to + // concatenate the output of multiple runs of cast2verilog, because the + // name of a cell with the subcells behavior does not encode the + // behaviors of the subcells it contains. It is easy to fix this, for + // example, by adding the MD5 hash of the names of the subcells to the + // end of the name of a cell containing subcells, but the name would + // be very ugly. + if (generateIfDef) { + out.println("`ifndef " + VerilogUtil.escapeIfNeeded(name)); + out.println("`define " + VerilogUtil.escapeIfNeeded(name) + " 1"); + } + } + + private void endif(final PrintWriter out) { + if (generateIfDef) { + out.println("`endif"); + } + } + + // Convert cell to verilog and emit to file + private String convert(final /*@ non_null @*/ CellInterface cell, + final HierName prefix, + final /*@ non_null @*/ PrintWriter out, + final PrintWriter behOut, + final boolean emitSlackWrappers, + final boolean topLevel, + final boolean narrowPort, + final CommandLineArgs theArgs) + throws SemanticException { + + final String result; + final String type = cell.getFullyQualifiedType(); + final Mode beh = getBehavior(prefix); + + final String logstr = + "cell = " + type + + " prefix = " + (prefix == null ? "null" : prefix.getAsString('.')) + + " behavior = " + (beh == null ? "null" : beh.toString()); + logger.info("begin convert " + logstr); + if (beh == Mode.SUBCELLS) { + // map from instance name to converted module name + final Map subcells = + new TreeMap( + NaturalStringComparator.getInstance()); + + // map from instance name to whether its port should be narrow + final Set/**/ narrowInstances = + new HashSet/**/(); + + final boolean narrowSubcell; + if (prefix == null) { + // this is the top-level cell contain the DUT and the + // environment; if either requsted narrow ports, use narrow + // ports here as well + boolean narrowRequsted = false; + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (subcell.isNode() || subcell.isChannel()) continue; + narrowRequsted |= + params.isNarrowSubcell( + ((HierName) p.getFirst()).getAsString('.')); + } + narrowSubcell = narrowRequsted; + } else { + narrowSubcell = params.isNarrowSubcell(prefix.getAsString('.')); + } + + if (narrowPort || (narrowSubcell && topLevel)) + narrowInstances.add(null); + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair/**/ pair = (Pair) i.next(); + final CellInterface subcell = (CellInterface) pair.getSecond(); + + // ignore node and channel subcells + if (subcell.isNode() || subcell.isChannel()) continue; + + final HierName instance = (HierName) pair.getFirst(); + final HierName complete = HierName.append(prefix, instance); + + final Mode subbeh = getBehavior(complete); + + // this subcell is a wiring cell; inline aliases, and don't + // generate anything + if (subbeh == Mode.PRS && !subcell.hasRealProductionRule()) + continue; + + logger.info("found subcell " + instance + " of type " + + subcell.getFullyQualifiedType()); + + // CSP and Java behaviors always have wide ports + if (subbeh != Mode.CSP && subbeh != Mode.JAVA && narrowSubcell) + narrowInstances.add(instance); + + // get the subcell's converted module name + final String converted = + convert(subcell, complete, out, behOut, emitSlackWrappers, + false, narrowSubcell, theArgs); + + subcells.put(instance, converted); + } + + // determine if this subcell has been processed already + final String suffix = narrowPort ? "$narrow" : ""; + result = getSubcellName(type + suffix, subcells); + if (convertedCells.add(result)) { + ifdef(result, out); + emitModuleForCellWithSubcells(cell, prefix, result, subcells, + topLevel, narrowInstances, out); + endif(out); + } + } else if (beh == Mode.CSP) { + result = type + "$csp"; + behOut.println(cell.getFullyQualifiedType() + " " + prefix + + " csp"); + if (convertedCells.add(result)) { + ifdef(result, out); + emitCspLeaf(cell, result, out, emitSlackWrappers); + endif(out); + } + } else if (beh == Mode.JAVA) { + result = type + "$java"; + // write out header for module + if (convertedCells.add(result)) { + ifdef(result, out); + + final Map dirs = (Map) + DirectiveUtils.getJavaDirective( + cell, + DirectiveConstants.GROUP, + DirectiveConstants.WIDE_CHANNEL_TYPE); + final List verilogPorts = + new ArrayList(); + + final GroupedChannel groupedChannel = + new GroupedChannel(cell, new HashMap(dirs)); + + out.println("module \\" + result + "$body ("); + emitPortList(cell, null, null, null, null, null, + out, true, true, false, verilogPorts, + groupedChannel); + groupedChannel.outputPorts(out); + out.println(");"); + + errorExist |= groupedChannel.checkError(); + + final JavaCoSimInfo jcsi = cell.getJavaCoSimInfo(); + for (Iterator i = jcsi.getClassNames().iterator(); + i.hasNext(); ) { + final String name = (String) i.next(); + out.println("initial $instantiate(\"" + name + "\");"); + } + out.println("endmodule // java block"); + + out.println(); + + out.println("module \\" + result + "$wrap ("); + emitPortList(cell, null, null, null, null, null, + out, true, true, false); + out.print(")"); + groupedChannel.outputDecl(out, verilogPorts); + out.println("\\" + result + "$body body("); + groupedChannel.outputInstantiation(out, verilogPorts); + out.println(");"); + out.println("endmodule"); + out.println(); + + emitSlackWrapper(cell, result, result + "$wrap", + BlockInterface.JAVA, out); + + endif(out); + } + } else if (beh instanceof Mode.VerilogMode || beh == Mode.PRS) { + final CellImpl wrapper = getWrapperCell(cell); + result = + CellUtils.hashMetaParameters(wrapper.getFullyQualifiedType()); + behOut.println(cell.getFullyQualifiedType() + " " + prefix + + " digital"); + if (convertedCells.add(result)) { + try { + Prs2Verilog.emitVerilogBlock( + wrapper, getCadencize(true), + beh == Mode.PRS ? null + : ((Mode.VerilogMode) beh).getLevel(), + new NoRepeatVisitor(out), theArgs, validVerilogFiles); + } catch (IOException e) { + throw new SemanticException(e); + } + } + } else + throw new AssertionError("No suitable behavior found in " + + cell.getFullyQualifiedType()); + + logger.info("end convert " + logstr); + return result; + } + + /** + * Add object o into the collection c if + * c is not null. Otherwise, do nothing. + **/ + private static void addNonNull(Collection c, Object o) { + if (c != null) c.add(o); + } + + private static class VerilogPort { + public static final String INPUT = "input"; + public static final String OUTPUT = "output"; + public static final String INOUT = "inout"; + public static final String WIRE = "wire"; + public static final String REG = "reg"; + private String direction; + private boolean signedness; + private Pair group; + private String netType; + private String vector; + private String name; + public VerilogPort() { } + public void setDirection(String direction) { + this.direction = direction; + } + public void setSignedness(boolean signedness) { + this.signedness = signedness; + } + public void setGroup(Pair group) { this.group = group; } + public void setNetType(String netType) { this.netType = netType; } + public void setVector(String vector) { this.vector = vector; } + public void setName(String name) { this.name = name; } + public String getName() { return name; } + public String getVector() { return vector; } + public Pair getGroup() { return group; } + public String getDirection() { return direction; } + public boolean getSignedness() { return signedness; } + } + + /** + * Fills in (data nodes, enable nodes, arrayInputNode, arrayOutputNodes). + **/ + private void emitPortList(CellInterface cell, + List/**/ dataNodes, + List/**/ enableNodes, + List/*>*/ arrayInputNodes, + List/*>*/ + arrayOutputNodes, + List/**/ inputPorts, + PrintWriter out, + boolean isLeaf) { + emitPortList(cell, dataNodes, enableNodes, arrayInputNodes, + arrayOutputNodes, inputPorts, out, isLeaf, false, false); + } + + private void emitPortList(CellInterface cell, + List/**/ dataNodes, + List/**/ enableNodes, + List/*>*/ arrayInputNodes, + List/*>*/ + arrayOutputNodes, + List/**/ inputPorts, + PrintWriter out, + boolean isLeaf, + boolean inJava, + boolean narrowPorts) { + emitPortList(cell, dataNodes, enableNodes, arrayInputNodes, + arrayOutputNodes, inputPorts, out, isLeaf, inJava, + narrowPorts, null, null); + } + + private void emitPortList(CellInterface cell, + List/**/ dataNodes, + List/**/ enableNodes, + List/*>*/ arrayInputNodes, + List/*>*/ + arrayOutputNodes, + List/**/ inputPorts, + PrintWriter out, + boolean isLeaf, + boolean inJava, + boolean narrowPorts, + List verilogPorts, + GroupedChannel groupedChannels) { + // and the real ports + final boolean[] first = new boolean[] { true }; + final CSPCellInfo cellInfo = cell.getCSPInfo(); + for (Iterator i = cellInfo.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition portDefinition = (PortDefinition) i.next(); + emitPorts(cell, + portDefinition.getName(), + portDefinition.getType(), + portDefinition.getDirection(), + dataNodes, enableNodes, + arrayInputNodes, arrayOutputNodes, inputPorts, false, + first, out, isLeaf, inJava, narrowPorts, + verilogPorts, groupedChannels); + } + } + + + private void emitPorts(final CellInterface cell, + final String name, + final PortTypeInterface portType, + final int direction, + final List/**/ dataNodes, + final List/**/ enableNodes, + final List/*>*/ + arrayInputNodes, + final List/*>*/ + arrayOutputNodes, + final List/**/ inputPorts, + final boolean isArray, + final boolean[] first, + PrintWriter out, + boolean isLeaf, + boolean inJava, + boolean narrowPorts, + final List verilogPorts, + final GroupedChannel groupedChannels) { + if (portType instanceof com.avlsi.fast.ports.ArrayType) { + final com.avlsi.fast.ports.ArrayType arrayType = + (com.avlsi.fast.ports.ArrayType) portType; + + for (int i = arrayType.getMinIndex(); + i <= arrayType.getMaxIndex(); ++i) { + emitPorts(cell, name + '[' + i + ']', + arrayType.getArrayedType(), + direction, dataNodes, enableNodes, + arrayInputNodes, arrayOutputNodes, inputPorts, + true, first, out, isLeaf, inJava, narrowPorts, + verilogPorts, groupedChannels); + } + } else if (portType instanceof ChannelType) { + final ChannelType chanType = (ChannelType) portType; + if (chanType.isArrayed() && narrowPorts) { + for (int i = 0; i < chanType.getWidth(); ++i) { + emitPorts(cell, name + '[' + i + ']', + new ChannelType(chanType.iterator(), + chanType.getTypeName()), + direction, dataNodes, enableNodes, + arrayInputNodes, arrayOutputNodes, inputPorts, + isArray, first, out, isLeaf, inJava, narrowPorts, + verilogPorts, groupedChannels); + } + } else { + final VerilogPort vdata = new VerilogPort(); + final VerilogPort venable = new VerilogPort(); + + final String prettyName = + StringUtil.replaceSubstring(name, "][", ","); + final String data = '\\' + prettyName + "$data "; + vdata.setName(prettyName + "$data"); + final String enable = '\\' + prettyName + "$enable "; + venable.setName(prettyName + "$enable"); + + // If we are part of an array, emit the outputs as + // wires because the regs will be internal. + // If we are not a leaf cell, emit the outputs as + // wires as the regs will be declared in a lower + // level cell + final boolean outWire = + ((isArray || !isLeaf) && !inJava) || + (inJava && groupedChannels == null); + final String outputType = outWire ? "output" : "output reg"; + final String dataDirection; + final String enableDirection; + if (direction == PortDefinition.OUT) { + if (isArray) { + addNonNull(arrayInputNodes, + new Pair/**/( + enable, new Integer(1))); + addNonNull(arrayOutputNodes, + new Pair/**/( + data, new Integer(-1))); + } else { + addNonNull(dataNodes, data); + addNonNull(inputPorts, enable); + } + + dataDirection = outputType; + vdata.setDirection(VerilogPort.OUTPUT); + vdata.setNetType(outWire ? VerilogPort.WIRE + : VerilogPort.REG); + enableDirection = "input"; + venable.setDirection(VerilogPort.INPUT); + venable.setNetType(VerilogPort.WIRE); + } else { + assert direction == PortDefinition.IN; + if (isArray) { + addNonNull(arrayInputNodes, + new Pair/**/( + data, new Integer(-1))); + addNonNull(arrayOutputNodes, + new Pair/**/( + enable, new Integer(1))); + } else { + addNonNull(enableNodes, enable); + addNonNull(inputPorts, data); + } + + dataDirection = "input"; + vdata.setDirection(VerilogPort.INPUT); + vdata.setNetType(VerilogPort.WIRE); + enableDirection = outputType; + venable.setDirection(VerilogPort.OUTPUT); + venable.setNetType(outWire ? VerilogPort.WIRE + : VerilogPort.REG); + } + if (!first[0]) + out.println(','); + /* Always print out wide channels */ + final String bitWidth = + "[" + (getNumBitsWide(chanType) - 1) + ":0]"; + final String fullGroup, groupName; + if (groupedChannels == null) { + fullGroup = null; + groupName = null; + } else { + groupName = groupedChannels.getGroupName(prettyName, + direction); + fullGroup = groupedChannels.lookupGroupName(prettyName); + } + if (fullGroup == null) { + out.println(dataDirection + " signed " + bitWidth + " " + + data + ','); + out.print(enableDirection + ' ' + enable); + addNonNull(verilogPorts, vdata); + addNonNull(verilogPorts, venable); + } else { + out.print(dataDirection + " signed " + bitWidth + " " + + "\\" + fullGroup + ' '); + vdata.setName(fullGroup); + vdata.setGroup(new Pair(groupName, + prettyName)); + addNonNull(verilogPorts, vdata); + } + vdata.setSignedness(true); + vdata.setVector(bitWidth); + first[0] = false; + } + } else if (portType instanceof com.avlsi.fast.ports.NodeType) { + // XXX: what to do about initial value? + // Ignore for now + final VerilogPort vnode = new VerilogPort(); + final NodeType nodeType = (NodeType) portType; + if (!first[0]) + out.println(','); + + final String comma = StringUtil.replaceSubstring(name, "][", ","); + final String prettyName = '\\' + comma + ' '; + vnode.setName(comma); + + final String dir; + vnode.setNetType(VerilogPort.WIRE); + if (direction == PortDefinition.OUT) { + final boolean outWire = ((isArray || !isLeaf) && !inJava) || + (inJava && groupedChannels == null); + dir = outWire ? "output" : "output reg"; + vnode.setDirection(VerilogPort.OUTPUT); + if (!outWire) vnode.setNetType(VerilogPort.REG); + } else { + if (direction == PortDefinition.IN) { + dir = "input"; + vnode.setDirection(VerilogPort.INPUT); + } else { + dir = "inout"; + vnode.setDirection(VerilogPort.INOUT); + } + addNonNull(inputPorts, prettyName); + } + + if (isArray) { + final Collection which = + direction == PortDefinition.OUT ? + arrayOutputNodes + : (direction == PortDefinition.IN ? arrayInputNodes + : null); + + // if neither array input ports or array output ports are + // requested, then it makes no difference which collection to + // add the port to, so suppress the warning in that case + if (direction == PortDefinition.INOUT && + (arrayOutputNodes != null || arrayInputNodes != null)) + logger.severe("In " + cell.getFullyQualifiedType() + + ", port " + prettyName + + "may not be handled correctly, because it " + + "is declared as inout, and is part of an " + + "array."); + + addNonNull(which, + new Pair/**/(prettyName, null)); + } + + if (nodeType.isArrayed()) { + final String width = "[" + (nodeType.getWidth() - 1) + ":0]"; + vnode.setVector(width); + out.print(dir + " " + width + " " + prettyName); + } else { + out.print(dir + " " + prettyName); + } + + first[0] = false; + addNonNull(verilogPorts, vnode); + } else { + assert portType instanceof com.avlsi.fast.ports.StructureType; + final com.avlsi.fast.ports.StructureType structureType = + (com.avlsi.fast.ports.StructureType) portType; + + if (isLeaf && !inJava && + (CellUtils.isDftChannel(cell, structureType.getTag()) || + CellUtils.isSramSerialChannel(structureType.getTag()))) { + return; + } + + for (Iterator i = structureType.iterator(); i.hasNext(); ) { + final PortDefinition portDefinition = + (PortDefinition) i.next(); + + emitPorts(cell, + name + '.' + portDefinition.getName(), + portDefinition.getType(), + PortDefinition.updateDirection( + direction, + portDefinition.getDirection()), + dataNodes, enableNodes, + arrayInputNodes, arrayOutputNodes, inputPorts, + isArray, first, out, isLeaf, inJava, narrowPorts, + verilogPorts, groupedChannels); + } + } + } + + private static String getChannelConverterName(final int base, + final int len, final boolean n2w) { + return "project.cast2verilog.nw." + + (n2w ? "NarrowWide" : "WideNarrow") + + "(" + base + "," + len + ")"; + } + + /* Creates channel converter module by recursively calling Cast2Verilog + on a special cast cell checked in specifically for this purpose */ + /* + private static void emitChannelConverterModule(final CastFileParser cfp, + final PrintWriter warningWriter, + final PrintWriter errorWriter, + final PrintWriter debugWriter, + final PrintWriter out, + final int base, + final int len, + final boolean n2w, + final int registerBitWidth) + throws CastSemanticException, SemanticException { + final String name = getChannelConverterName(base, len, n2w); + final CellInterface cell = cfp.getFullyQualifiedCell(name); + final Map behaviors = new HashMap(); + behaviors.put(cell.getFullyQualifiedType(), Mode.CSP); + new Cast2Verilog(warningWriter, errorWriter, debugWriter, behaviors, + registerBitWidth) + .convert(cell, null, out, false, null); + } + */ + + private void repeatN(final String format, final int N, + final PrintWriter out) { + repeatN(new MessageFormat(format), N, out); + } + + private void repeatN(final MessageFormat format, final int N, + final PrintWriter out) { + repeatN(format, N, "\n", out); + out.println(); + } + + private void repeatN(final String format, final int N, + final String sep, final PrintWriter out) { + repeatN(new MessageFormat(format), N, sep, out); + } + private void repeatN(final MessageFormat format, final int N, + final String sep, final PrintWriter out) { + for (int i = 0; i < N; ++i) { + out.print(format.format(new Object[] { String.valueOf(i) })); + if (i < N - 1) out.print(sep); + } + } + + private void emitNarrowWideConverter(final PrintWriter out, + final int base, final int len) { + final int narrowBits = getNumBitsNarrow(base) - 1; + final int wideBits = getNumBitsWide(base, len) - 1; + + out.print("module \\" + getChannelConverterName(base, len, true)); + out.println(" ("); + + repeatN("input signed [" + narrowBits + ":0] \\NARROW[{0}]$data , output \\NARROW[{0}]$enable ,", len, out); + + out.println("output reg signed [" + wideBits + ":0] \\WIDE$data , " + + "input \\WIDE$enable );"); + + out.println("reg signed [" + wideBits + ":0] x;"); + + repeatN("assign \\NARROW[{0}]$enable = \\WIDE$enable ;", len, out); + + out.println("always @* begin"); + out.println("if ("); + repeatN("(\\NARROW[{0}]$data >= 0)", len, "&\n", out); + out.println(") begin"); + out.println("x = 0;"); + for (int i = 0; i < len; ++i) { + out.println("x = " + base + " * x + \\NARROW[" + (len - i - 1) + + "]$data ;"); + } + out.println("\\WIDE$data = x;"); + out.println("end"); + out.println("else if ("); + repeatN("(\\NARROW[{0}]$data < 0)", len, "&\n", out); + out.println(") begin"); + out.println("\\WIDE$data = -1;"); + out.println("end"); + out.println("end"); + + out.println("endmodule"); + } + + private void emitWideNarrowConverter(final PrintWriter out, + final int base, + final int len) { + final int narrowBits = getNumBitsNarrow(base) - 1; + final int wideBits = getNumBitsWide(base, len) - 1; + + out.print("module \\" + getChannelConverterName(base, len, false)); + out.println(" ("); + + repeatN("output reg signed [" + narrowBits + ":0] \\NARROW[{0}]$data , input \\NARROW[{0}]$enable ,", len, out); + + out.println("input signed [" + wideBits + ":0] \\WIDE$data , " + + "output reg \\WIDE$enable );"); + + out.println("reg signed [" + wideBits + ":0] x;"); + + out.println("always @* begin"); + out.println("if ("); + repeatN("(\\NARROW[{0}]$enable )", len, "&\n", out); + out.println(") begin"); + out.println("\\WIDE$enable = 1;"); + out.println("end"); + out.println("else if ("); + repeatN("(!\\NARROW[{0}]$enable )", len, "&\n", out); + out.println(") begin"); + out.println("\\WIDE$enable = 0;"); + out.println("end"); + out.println("end"); + + out.println("always @* begin"); + out.println("if (\\WIDE$data >= 0) begin"); + out.println("x = \\WIDE$data ;"); + repeatN("\\NARROW[{0}]$data = x % " + base + "; x = x / " + base + ";", + len, out); + out.println("end"); + out.println("else begin"); + repeatN("\\NARROW[{0}]$data = -1;", len, out); + out.println("end"); + out.println("end"); + + out.println("endmodule"); + } + + /** + * Returns a port definition with all arrays pushed down to the + * leaves and structures brought up to the top. + **/ + private PortTypeInterface mungeArrays( + final PortTypeInterface portType) { + return mungeArrays(portType, null); + } + + private PortTypeInterface mungeArrays( + final PortTypeInterface portType, + final com.avlsi.fast.ports.ArrayType arrays) { + if (portType instanceof com.avlsi.fast.ports.ArrayType) { + final com.avlsi.fast.ports.ArrayType arrayType = + (com.avlsi.fast.ports.ArrayType) portType; + + return mungeArrays(arrayType.getArrayedType(), + (com.avlsi.fast.ports.ArrayType) + substituteArray(arrays, + new com.avlsi.fast.ports.ArrayType( + null, arrayType.getMinIndex(), + arrayType.getMaxIndex()))); + } else if (portType instanceof com.avlsi.fast.ports.ChannelType) { + return substituteArray(arrays, portType); + } else if (portType instanceof com.avlsi.fast.ports.NodeType) { + return substituteArray(arrays, portType); + } else { + assert portType instanceof com.avlsi.fast.ports.StructureType; + final com.avlsi.fast.ports.StructureType structureType = + (com.avlsi.fast.ports.StructureType) portType; + final com.avlsi.fast.ports.StructureType newStructureType = + new com.avlsi.fast.ports.StructureType(); + + for (Iterator i = structureType.iterator(); i.hasNext(); ) { + final PortDefinition portDefinition = + (PortDefinition) i.next(); + newStructureType.add( + new PortDefinition( + portDefinition.getName(), + mungeArrays(portDefinition.getType(), arrays), + portDefinition.getDirection())); + } + + return newStructureType; + } + } + + /** + * Substitutes arrayType in for the blank space denoted by + * null in arrays. arrays + * is an ArrayType of ArrayTypes, + * with the innermost arrayed type as null. + **/ + private PortTypeInterface substituteArray( + final com.avlsi.fast.ports.ArrayType arrays, + final PortTypeInterface type) { + if (arrays == null) { + return type; + } else { + return new com.avlsi.fast.ports.ArrayType( + substituteArray( + (com.avlsi.fast.ports.ArrayType) + arrays.getArrayedType(), + type), + arrays.getMinIndex(), + arrays.getMaxIndex()); + } + } + + private void declareArrayRegs(CSPCellInfo cellInfo, PrintWriter out) { + for (Iterator i = cellInfo.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition portDefinition = (PortDefinition) i.next(); + declareArrayRegs(portDefinition.getName(), + mungeArrays(portDefinition.getType()), + portDefinition.getDirection(), "", out); + } + } + + private void declareArrayRegs(final String name, + final PortTypeInterface portType, + final int direction, + final String arrayPart, + PrintWriter out) { + if (portType instanceof com.avlsi.fast.ports.ArrayType) { + final com.avlsi.fast.ports.ArrayType arrayType = + (com.avlsi.fast.ports.ArrayType) portType; + declareArrayRegs(name, arrayType.getArrayedType(), direction, + arrayPart + "[" + arrayType.getMaxIndex() + ":" + + arrayType.getMinIndex() + "]", out); + } else if (portType instanceof com.avlsi.fast.ports.ChannelType) { + // We only do something if we are part of an array + if (arrayPart != "") { + final com.avlsi.fast.ports.ChannelType chanType = + (com.avlsi.fast.ports.ChannelType) portType; + final String data = '\\' + name + "$data " + arrayPart; + final String enable = '\\' + name + "$enable " + arrayPart; + final int bitWidth = getNumBitsWide(chanType); + out.println("reg signed [" + (bitWidth-1) + ":0] " + + data + ';'); + out.println("reg " + enable + ';'); + } + } else if (portType instanceof com.avlsi.fast.ports.NodeType) { + // We only do something if we are part of an array + if (arrayPart != "") { + final com.avlsi.fast.ports.NodeType nodeType = + (com.avlsi.fast.ports.NodeType) portType; + final String width = nodeType.isArrayed() ? + ("[" + (nodeType.getWidth() - 1) + ":0] ") : ""; + out.println("reg " + width + '\\' + name + ' ' + + arrayPart + ';'); + } + } else { + assert portType instanceof com.avlsi.fast.ports.StructureType; + final com.avlsi.fast.ports.StructureType structureType = + (com.avlsi.fast.ports.StructureType) portType; + + // We should not have encountered any arrays yet because + // of the call to mungeArrays(). + assert arrayPart == ""; + + for (Iterator i = structureType.iterator(); i.hasNext(); ) { + final PortDefinition portDefinition = + (PortDefinition) i.next(); + declareArrayRegs(name + '.' + portDefinition.getName(), + portDefinition.getType(), + PortDefinition.updateDirection( + direction, + portDefinition.getDirection()), + arrayPart, out); + } + } + } + + /** + * Moves all array accesses to the end of the string s. + **/ + private String mungeArray(String s) { + // Recover ]['s that were deleted earlier + s = StringUtil.replaceSubstring(s, ",", "]["); + final StringBuffer nonArrayPart = new StringBuffer(s.length()); + final StringBuffer arrayPart = new StringBuffer(s.length()); + final Pattern p = Pattern.compile("\\[\\d+\\]"); + final Matcher m = p.matcher(s); + int start = 0; + while (m.find(start)) { + nonArrayPart.append(s.substring(start, m.start())); + arrayPart.append(s.substring(m.start(), m.end())); + start = m.end(); + } + + nonArrayPart.append(s.substring(start, s.length())); + nonArrayPart.append(arrayPart); + + return nonArrayPart.toString(); + } + + private void emitHelperFunctions(PrintWriter out) { + final String size = "[" + (registerBitWidth - 1) + ":0]"; + ifdef("CAST2VERILOG_RUNTIME_UTIL", out); + out.println("module util;"); + + out.println("function signed " + size + " sign_extend("); + out.println(" input signed " + size + " val);"); + out.println("sign_extend = val;"); + out.println("endfunction"); + out.println(); + + out.println("function signed " + size + " pow("); + out.println(" input signed " + size + " x,"); + out.println(" input signed " + size + " y);"); + out.println("pow = y >= 0 ? x ** y : (x == 0 ? 0 : 1 / (x ** -y));"); + out.println("endfunction"); + out.println(); + + // a trivial implementation of log2 + out.println("function signed " + size + " log2("); + out.println(" input signed " + size + " x);"); + out.println("bit " + size + " temp;"); + out.println("integer i;"); + out.println("begin"); + out.println("if (x < 1) temp = -x;"); + out.println("else temp = x - 1;"); + out.println("log2 = 0;"); + out.println("i = 0;"); + out.println("while (temp !== 0) begin"); + out.println("i = i + 1;"); + out.println("case (temp[0])"); + out.println("1'b1: log2 = i;"); + out.println("1'bx: begin temp = 0; log2 = 1'bx; end"); + out.println("1'bz: begin temp = 0; log2 = 1'bz; end"); + out.println("endcase"); + out.println("temp = temp >> 1;"); + out.println("end"); + out.println("end"); + out.println("endfunction"); + out.println(); + + out.println("function signed " + size + " log4("); + out.println(" input signed " + size + " x);"); + out.println("begin"); + out.println("log4 = (log2(x) + 1) / 2;"); + out.println("end"); + out.println("endfunction"); + out.println(); + + out.println("function signed " + size + " divide("); + out.println(" input signed " + size + " numer,"); + out.println(" input signed " + size + " denom);"); + // Verilog divide rounds to 0, just like csp, so we don't need + // to compensate for that. + out.println("divide = denom != 0 ? numer / denom : 0;"); + out.println("endfunction"); + out.println(); + + out.println("function signed " + size + " remainder("); + out.println(" input signed " + size + " numer,"); + out.println(" input signed " + size + " denom);"); + // Verilog divide rounds to 0, just like csp, so we don't need + // to compensate for that. + out.println("remainder = denom != 0 ? numer % denom : numer;"); + out.println("endfunction"); + out.println(); + + out.println("function signed " + size + " shift_left("); + out.println(" input signed " + size + " left,"); + out.println(" input signed " + size + " right);"); + out.println("shift_left = right >= 0 ? left <<< right : left >>> -right;"); + out.println("endfunction"); + out.println(); + + out.println("function signed " + size + " shift_right("); + out.println(" input signed " + size + " left,"); + out.println(" input signed " + size + " right);"); + out.println("shift_right = right >= 0 ? left >>> right : left <<< -right;"); + out.println("endfunction"); + out.println(); + + out.println("function " + size + " posmod("); + out.println(" input signed " + size + " numer,"); + out.println(" input signed " + size + " denom);"); + out.println("posmod = $unsigned((numer % denom + denom) % denom);"); + out.println("endfunction"); + out.println(); + + // XXX: handle negatives and bad ranges + out.println("function signed " + size + " bit_extract2("); + out.println(" input signed " + size + " val,"); + out.println(" input signed " + size + " max_bit);"); + out.println("bit_extract2 = bit_extract3(val, max_bit, max_bit);"); + out.println("endfunction"); + out.println(); + + out.println("function signed " + size + " bit_extract3("); + out.println(" input signed " + size + " val,"); + out.println(" input signed " + size + " max_bit,"); + out.println(" input signed " + size + " min_bit);"); + out.println("bit_extract3 = " + + "(val & ((1 << (max_bit + 1)) - 1)) >> min_bit;"); + out.println("endfunction"); + out.println(); + + // XXX: handle negatives and bad ranges + final Collection kinds = CollectionUtils.addAll( + new HashSet(), + new String[] { "", "add", "subtract", "multiply", "divide", + "remainder", "and", "or", "xor", "leftshift", + "rightshift" } + ); + for (Iterator i = kinds.iterator(); i.hasNext(); ) { + final String kind = (String) i.next(); + final String name3 = "bit_insert_" + kind + "3"; + final String name4 = "bit_insert_" + kind + "4"; + out.println("task " + name3 + "("); + out.println(" inout signed " + size + " old_val,"); + out.println(" input signed " + size + " new_val,"); + out.println(" input signed " + size + " max_bit);"); + out.println(name4 + "(old_val, new_val, max_bit, max_bit);"); + out.println("endtask"); + out.println(); + } + + for (Iterator i = kinds.iterator(); i.hasNext(); ) { + final String kind = (String) i.next(); + final String name4 = "bit_insert_" + kind + "4"; + out.println("task " + name4 + "("); + out.println(" inout signed " + size + " old_val,"); + out.println(" input signed " + size + " new_val,"); + out.println(" input signed " + size + " max_bit,"); + out.println(" input signed " + size + " min_bit);"); + out.println("bit signed " + size + " mask;"); + out.println("bit signed " + size + " curr;"); + out.println("begin"); + if (kind.equals("")) { + out.println("curr = new_val;"); + } else { + out.println("curr = bit_extract3(old_val, max_bit, min_bit);"); + out.println("assign_" + kind + "(curr, new_val);"); + } + out.println("mask = (1 << (max_bit + 1)) - (1 << min_bit);"); + out.println("old_val = (old_val & ~mask) " + + "| ((curr << min_bit) & mask);"); + out.println("end"); + out.println("endtask"); + out.println(); + } + + + // Random number generator + // XXX: handle negatives and bad ranges + out.println("function " + size + " random("); + out.println(" input signed " + size + " num_bits);"); + out.println("integer words, i, remaining_bits, msb_bits;"); + out.println("begin"); + // set # of 32-bit words in num_bits + out.println("words = num_bits / 32;"); + // initialize entire integer to 0 + out.println("random = 0;"); + out.println("for (i = 0; i < words; i=i+1) begin"); + out.println(" random[i*32 +:32] = $random;"); + out.println("end"); + // set remaining bits: j = num_bits - 32*32bitchunks + out.println("remaining_bits = num_bits - words*32;"); + out.println("// Use shift and bitwise or to avoid verilog's"); + out.println("// restrictions on part selects"); + out.println("msb_bits = {$random} % (1< 0) begin"); + out.println(" len = len + 1;"); + out.println(" end "); + out.println(" hex_string[`CSP_STRING_LENGTH] = len;"); + out.println(" hex_string[`CSP_STRING_ASCII] = temp;"); + out.println("end"); + out.println("endfunction"); + out.println(); + + out.println("task assign_concat;"); + out.println("inout [`CSP_STRING_WHOLE] variable;"); + out.println("input [`CSP_STRING_WHOLE] val;"); + out.println("`CSP_STRING variable;"); + out.println("`CSP_STRING val;"); + out.println("variable = csp_string.concat(variable, val);"); + out.println("endtask"); + out.println(); + + out.println("task assign_add;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = variable + val;"); + out.println("endtask"); + out.println(); + + out.println("task assign_subtract;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = variable - val;"); + out.println("endtask"); + out.println(); + + out.println("task assign_multiply;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = variable * val;"); + out.println("endtask"); + out.println(); + + out.println("task assign_divide;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = divide(variable, val);"); + out.println("endtask"); + out.println(); + + out.println("task assign_remainder;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = remainder(variable, val);"); + out.println("endtask"); + out.println(); + + out.println("task assign_and;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = variable & val;"); + out.println("endtask"); + out.println(); + + out.println("task assign_or;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = variable | val;"); + out.println("endtask"); + out.println(); + + out.println("task assign_xor;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = variable ^ val;"); + out.println("endtask"); + out.println(); + + out.println("task assign_leftshift;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = shift_left(variable, val);"); + out.println("endtask"); + out.println(); + + out.println("task assign_rightshift;"); + out.println("inout signed variable;"); + out.println("input signed val;"); + out.println("bit signed " + size + " variable;"); + out.println("bit signed " + size + " val;"); + out.println("variable = shift_right(variable, val);"); + out.println("endtask"); + out.println(); + + out.println("function [`CSP_STRING_WHOLE] csp_string(" + + "input signed " + size + " value, " + + "input signed " + size + " base);"); + out.println("bit [36*8:1] digits;"); + out.println("bit signed " + size + " pos;"); + out.println("bit signed [`CSP_STRING_ASCII] temp;"); + out.println("bit [5:0] b, rem;"); + out.println("bit [7:0] neg;"); + out.println("integer len;"); + out.println("begin"); + out.println(" digits = \"zyxwvutsrqponmlkjihgfedcba9876543210\";"); + out.println(" b = base;"); + out.println(" if (base < 2 || base > 36) begin"); + out.println(" $display(\"%t:%m: Invalid base %d for string conversion\", $time, base);"); + out.println(" b = 10;"); + out.println(" end"); + out.println(" if (value < 0) begin"); + out.println(" pos = -value;"); + out.println(" neg = \"-\";"); + out.println(" end"); + out.println(" else begin"); + out.println(" pos = value;"); + out.println(" neg = \"\";"); + out.println(" end"); + out.println(" if (pos == 0) $sformat(temp, \"0\");"); + out.println(" else if (base == 2) $sformat(temp, \"%0s%0b\", neg, pos);"); + out.println(" else if (base == 8) $sformat(temp, \"%0s%0o\", neg, pos);"); + out.println(" else if (base == 10) $sformat(temp, \"%0s%0d\", neg, pos);"); + out.println(" else if (base == 16) $sformat(temp, \"%0s%0h\", neg, pos);"); + out.println(" else begin"); + out.println(" temp = 0;"); + out.println(" len = 1;"); + out.println(" while (pos > 0) begin"); + out.println(" rem = pos % b;"); + out.println(" pos = pos / b;"); + out.println(" temp[len * 8 -: 8] = digits[(rem + 1) * 8 -: 8];"); + out.println(" len = len + 1;"); + out.println(" end"); + out.println(" if (neg > 0) temp[len * 8 -: 8] = \"-\";"); + out.println(" end"); + out.println(" len = 0;"); + out.println(" while ((len + 1) <= `CSP_STRING_MAX && temp[(len + 1) * 8 -: 8] > 0) begin"); + out.println(" len = len + 1;"); + out.println(" end"); + out.println(" csp_string[`CSP_STRING_LENGTH] = len;"); + out.println(" csp_string[`CSP_STRING_ASCII] = temp;"); + out.println("end"); + out.println("endfunction"); + out.println(); + + out.println("function [`CSP_STRING_WHOLE] posmod_warning(" + + "input signed " + size + " message, " + + "input signed " + size + " maxValue);"); + out.println("begin"); + out.println("posmod_warning = csp_string.inits(\"implicit non-power-of-2 posmod is deprecated: \");"); + out.println("posmod_warning = csp_string.concat(posmod_warning, csp_string(message, 10));"); + out.println("posmod_warning = csp_string.concat(posmod_warning, csp_string.inits(\" outside [0..\"));"); + out.println("posmod_warning = csp_string.concat(posmod_warning, csp_string(maxValue, 10));"); + out.println("posmod_warning = csp_string.concat(posmod_warning, csp_string.inits(\"]\"));"); + out.println("end"); + out.println("endfunction"); + + out.println("endmodule"); + endif(out); + out.println(); + out.println(); + } + + /** + * Emits Verilog declaration of Wide2Narrow and Narrow2Wide converters + * stored in usedWide2NarrowConvs. + **/ + private void emitConverterModules(CastFileParser cfp, PrintWriter out) + throws CastSemanticException, SemanticException { + for (Iterator i = usedWide2NarrowConvs.iterator(); i.hasNext();) { + final int[] params = (int[]) i.next(); + + // Old style converters were generated from CAST + // emitChannelConverterModule(cfp, warningWriter, errorWriter, + // debugWriter, out, params[0], params[1], params[2] == 0, + // registerBitWidth); + + if (params[2] == 0) { + emitNarrowWideConverter(out, params[0], params[1]); + } else { + emitWideNarrowConverter(out, params[0], params[1]); + } + } + } + + /** + * Prints usage message and exits. + **/ + private static void usage() { + System.out.print( + "Usage: cast2verilog\n" + + " --cast-path=\n" + + " --cell=\n" + + " [--output-file=] (defaults to .v)\n" + + " [--register-width=] (defaults to 129)\n" + + " [--library=] (gate matching for PRS behavior)\n" + + " [--ignore-inline] (do not process inline keyword)\n" + + " [--enable-system-verilog] (use SystemVerilog features)\n" + + " [--ifdef] (surround module definitions with ifdef)\n" + + " [--file-list=] (Verilog block dependencies)\n" + + " [--behavior-report=] (report CSP and PRS instances)\n" + + " [--version] (print version information)\n"); + System.exit(1); + } + + /** + * Converts CSP to Verilog. By default, Verilog is written to cell_name.v. + * + * @param args Arguments. + **/ + public static void main(String[] args) throws Exception { + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl(args); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + final CommandLineArgs theArgs = + new CachingCommandLineArgs(argsWithConfigs); + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + Cast2Verilog.class)); + } + + final String logging = theArgs.getArgValue("logging", "SEVERE"); + Level loggingLevel; + try { + loggingLevel = Level.parse(logging); + } catch (IllegalArgumentException e) { + loggingLevel = Level.OFF; + System.out.println("Valid levels are OFF, SEVERE, WARNING, INFO," + + " CONFIG, FINE, FINER, FINEST, ALL\n" + + "\"" + logging + "\" is invalid"); + } + logger.setLevel(loggingLevel); + + final String castCellName = theArgs.getArgValue("cell", null); + if (castCellName == null) + usage(); + final CoSim cosim = CoSim.getCoSim(castCellName, true); + final String cellName = cosim.getCellType(); + final String envName = cosim.getEnvName(); + + final FileSearchPath castFSP = + new FileSearchPath(theArgs.getArgValue("cast-path", ".")); + final StandardParsingOption spo = new StandardParsingOption(theArgs) { + public boolean processInline(final CellInterface cell) { + return !theArgs.argExists("ignore-inline"); + } + }; + + final CastFileParser cfp = new CastFileParser(castFSP, "2", spo); + + final CellInterface resetDriver; + final String resetDriverFqcn = + theArgs.getArgValue("reset-driver", null); + final HierName resetDriverPort = HierName.makeHierName("RESET"); + if (resetDriverFqcn == null) { + resetDriver = null; + } else { + resetDriver = cfp.getFullyQualifiedCellPretty(resetDriverFqcn, 2); + final CellInterface port = resetDriver.getSubcell(resetDriverPort); + if (!resetDriver.containsJava() || port == null || !port.isNode()) { + System.err.println( + "To be a valid reset driver, " + resetDriverFqcn + + " should have a node output port called " + + resetDriverPort + ", and contains a java block"); + System.exit(1); + } + } + + final CellInterface cell = cfp.getFullyQualifiedCellPretty(cellName, 2); + + final CoSimParameters params = new CoSimParameters(); + CoSimHelper.setCoSimParams("x", cell, cosim.getCoSimSpecList(), params, + null, false); + + final HierName instanceName; + final CellInterface cellEnv; + if (envName == null) { + instanceName = HierName.makeHierName("x"); + cellEnv = cell; + } else { + try { + final CellInterface envCell = cell.getEnvironment(envName); + CoSimHelper.setCoSimParams("_env", envCell, + new CoSimSpecList( + new CoSimSpec[] { cosim.getEnvSpec() }), + params, null, false); + } catch (NoSuchEnvironmentException e) { + System.err.println("Cannot find environment " + envName + + " in " + cellName); + ExceptionPrettyPrinter.printException(e, System.err); + System.exit(2); + } + instanceName = null; + final CellImpl impl = + CellUtils.getEnvWithCell(cell, envName, + cell.getType() + "_" + envName, + "_env", "x"); + + // bring the implied ports up to the cell enclosing the original + // cell and the environment + for (Iterator i = cell.getPortSubcellPairs(); i.hasNext(); ){ + final Pair p = (Pair) i.next(); + final HierName inst = (HierName) p.getFirst(); + if (cell.isImpliedPort(inst.getAsString('.'))) { + impl.addSubcellPair(inst, (CellInterface) p.getSecond(), + true); + } + } + + // create port definitions for the implied ports, and setup + // connections + final HierName instance = HierName.makeHierName("x"); + for (Iterator i = cell.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition def = (PortDefinition) i.next(); + if (cell.isImpliedPort(def.getName())) { + impl.addPortDefinition(def); + impl.addImpliedPortMapping( + def.getName(), + cell.getParentImpliedPort(def.getName())); + final Map ports = + CellUtils.markPorts(Collections.singletonList(def) + .iterator()); + for (Iterator j = ports.entrySet().iterator(); + j.hasNext(); ) { + final Map.Entry entry = (Map.Entry) j.next(); + final String s = (String) entry.getKey(); + final HierName port; + try { + port = HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName: " + s); + } + impl.addConnection(port, HierName.append(instance, port)); + } + } + } + + // instantiate a reset driver if requested; it should be a cell + // with only an output node as port + if (resetDriver != null) { + final String resetName = getResetName(cell, null); + if (resetName != null) { + final HierName resetInst = + HierName.makeHierName("reset_driver"); + impl.addSubcellPair(resetInst, resetDriver, false); + impl.addConnection( + HierName.append(resetInst, resetDriverPort), + HierName.append(instance, + HierName.makeHierName(resetName, '.'))); + + // set the instance to the "java" behavior + CoSimHelper.setCoSimParams( + resetInst.toString(), resetDriver, + new CoSimSpecList( + new CoSimSpec[] { + new CoSimSpec( + new ModeListLevelSpec( + new ModeList( + new Mode[] { + Mode.JAVA })), + new InstSpecList( + new InstSpec[0])) }), + params, null, false); + } + } + + cellEnv = impl; + } + + final PrintWriter systemErrWriter = + new PrintWriter(new OutputStreamWriter(System.err)); + + final String outputFileName = + theArgs.getArgValue("output-file", cellEnv.getFullyQualifiedType() + ".v"); + System.err.println("output file is " + outputFileName); + final PrintWriter out = + new PrintWriter( + new BufferedWriter( + new FileWriter(new File(outputFileName)))); + out.println("// " + + com.avlsi.util.debug.VersionInfo.getVersionString( + Cast2Verilog.class)); + out.println("// " + Calendar.getInstance().getTime()); + out.println("// " + StringUtil.join(args, ' ')); + + final String behFileName = + theArgs.getArgValue("behavior-report", null); + final PrintWriter behOut = + new PrintWriter( + behFileName == null ? NullWriter.getInstance() + : new BufferedWriter( + new FileWriter(behFileName))); + + final String registerWidth = + theArgs.getArgValue("register-width", "129"); + final boolean enableSystemVerilog = + theArgs.argExists("enable-system-verilog"); + final boolean generateIfDef = theArgs.argExists("ifdef"); + final Cast2Verilog c2v = new Cast2Verilog(systemErrWriter, + systemErrWriter, systemErrWriter, params, + Integer.parseInt(registerWidth), enableSystemVerilog, + generateIfDef); + c2v.emitHelperFunctions(out); + c2v.convert(cellEnv, instanceName, out, behOut, theArgs); + c2v.emitConverterModules(cfp, out); + if (c2v.checkError()) { + System.err.println("Errors found during translation; output file " + + "may be incorrect."); + System.exit(1); + } + + final String filelist = theArgs.getArgValue("file-list", null); + if (filelist != null && !c2v.validVerilogFiles.isEmpty()) { + final FileWriter w = new FileWriter(filelist); + for (Iterator i = c2v.validVerilogFiles.iterator(); i.hasNext(); ) { + w.write((String) i.next() + "\n"); + } + w.close(); + } + + out.close(); + behOut.close(); + } + + private final CellImpl createWrapperCell(final CellInterface verilog) { + final String module = "prs2verilog." + verilog.getModuleName(); + final String type = verilog.getType(); + final CellImpl cell = + new CellImpl(type, module, CellImpl.SYNTHETIC_CELL); + + // We must choose a name that does not conflict with any ports. _ is + // the anonymous name, and translated by the CAST parser, so it must + // not cause a conflict in a synthetic cell. + final HierName instance = HierName.makeHierName("_"); + cell.addSubcellPair(instance, verilog, false); + for (Iterator i = verilog.getPortSubcellPairs(); i.hasNext(); ){ + final Pair p = (Pair) i.next(); + cell.addSubcellPair((HierName) p.getFirst(), + (CellInterface) p.getSecond(), true); + } + cell.setHasCompleteSubcellsBlock(); + + // connect ports of the new cell with the ports of the cell containing + // the verilog block + final Map ports = CellUtils.markPorts(verilog); + for (Iterator i = ports.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String s = (String) entry.getKey(); + final HierName port; + try { + port = HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName: " + s); + } + cell.addConnection(port, HierName.append(instance, port)); + } + + // copy the appropriate port definition for the new cell + for (Iterator i = verilog.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition def = (PortDefinition) i.next(); + cell.addPortDefinition(def); + if (verilog.isImpliedPort(def.getName())) { + cell.addImpliedPortMapping( + def.getName(), + verilog.getParentImpliedPort(def.getName())); + } + } + + return cell; + } + + /** + * A cache of wrapper cells. + **/ + private final Map/**/ wrapperCache = + new HashMap/**/(); + + /** + * Return the wrapper cell for the give cell. + **/ + private final CellImpl getWrapperCell(final CellInterface verilog) { + CellImpl cell = + (CellImpl) wrapperCache.get(verilog.getFullyQualifiedType()); + if (cell == null) { + cell = createWrapperCell(verilog); + wrapperCache.put(verilog.getFullyQualifiedType(), cell); + } + + return cell; + } + + private final String getActualName(final Map portLocalMap, + final CellUtils.Channel chan) { + final CellUtils.Channel local = + (CellUtils.Channel) portLocalMap.get(chan); + if (local == null) { + return null; + } else { + final CellUtils.Channel parent = local.getParent(); + if (parent != null && parent.getType() instanceof NodeType) { + return parent.getFullName() + " [" + local.getIndex() + "]"; + } else { + return local.getFullName(); + } + } + } + + private final String getFormalName(final AliasedMap ports, + final CellUtils.Channel chan) { + if (ports == null) { + return chan.getName(); + } else { + HierName h = null; + try { + h = HierName.makeHierName(chan.getName(), '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException(e); + } + if (((Boolean) ports.getValue(h)).booleanValue()) { + return ports.getCanonicalKey(h).toString(); + } else { + return null; + } + } + } + + private final void emitModuleForCellWithSubcells(CellInterface cell, + final HierName prefix, + final String moduleName, + final Map subcells, + final boolean topLevel, + final Set/**/ narrowInstances, + PrintWriter out) { + + // write out header for module + out.println("module \\" + moduleName + " ("); + emitPortList(cell, null, null, null, null, null, + out, false, false, narrowInstances.contains(null)); + out.println(");"); + + final Map flattenNodes = new HashMap(); + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (subcell.isNode() || subcell.isChannel()) continue; + + final HierName instanceName = (HierName) p.getFirst(); + final HierName complete = HierName.append(prefix, instanceName); + final Mode m = getBehavior(complete); + if (m instanceof Mode.VerilogMode || m == Mode.PRS) { + flattenNodes.put(instanceName, + m == Mode.PRS ? Boolean.TRUE : Boolean.FALSE); + } + } + + final Set nodeNarrowConverters = + new TreeSet(); + final Set narrowWideConverters = + new TreeSet(); + + // First, process all port connections, identify split src and snk + // ports, and create mapping between narrow/wide channels and local + // variables/ports. Emit declaration of new local variables as needed + final Map portToLocalMap = + processPortConnections(cell, flattenNodes, narrowInstances, + nodeNarrowConverters, narrowWideConverters, + out); + + // Unconnected wide nodes that have already been declared + final Set unconnectedWideNodes = new HashSet(); + + // Write out subcell instantiations with port lists + // These will always have wide local names according to above maps + for (Map.Entry entry : subcells.entrySet()) { + final HierName instanceName = entry.getKey(); + final String convertedName = entry.getValue(); + final CellInterface subcell = cell.getSubcell(instanceName); + + if (flattenNodes.get(instanceName) == Boolean.TRUE && + !subcell.hasRealProductionRule()) { + continue; + } + final boolean verilog = flattenNodes.containsKey(instanceName); + + final AliasedMap portAliases; + final CellInterface wrapper; + if (verilog) { + wrapper = getWrapperCell(subcell); + portAliases = getCadencize(true).convert(wrapper).getPortNodes(); + } else { + wrapper = subcell; + portAliases = null; + } + + // calculate the port connection for the subcell module + // instantiation + final HashSet aliasedPorts = new HashSet(); + final TreeSet actualPorts = new TreeSet(new Comparator() { + public int compare(Object o1, Object o2) { + final Triplet t1 = (Triplet) o1; + final Triplet t2 = (Triplet) o2; + return NaturalStringComparator.compareString( + t1.getSecond(), t2.getSecond()); + } + }); + + for (Iterator j = CellUtils.getPortChannels(wrapper, + getCadencize(true), verilog, + narrowInstances.contains(instanceName) ? 1 : 2).iterator(); + j.hasNext(); ) { + final CellUtils.Channel subchan = (CellUtils.Channel) j.next(); + final String formal = getFormalName(portAliases, subchan); + if (formal == null) continue; + + final List actuals = new ArrayList(); + final PortTypeInterface subtype = subchan.getType(); + if (portAliases == null && subtype instanceof NodeType && + ((NodeType) subtype).isArrayed()) { + for (int k = ((NodeType) subtype).getWidth() - 1; k >= 0; --k) + { + String name = subchan.getName() + "[" + k + "]"; + name = StringUtil.replaceSubstring(name, "][", ","); + final CellUtils.Channel chan = + new CellUtils.Channel(instanceName, name, + subchan.getParent(), + subchan.getType(), + subchan.getIndex(), + subchan.getDirection()); + String actual = getActualName(portToLocalMap, chan); + if (actual == null) { + // the node is unconnected; use its name as is, + // since it must be unique. + actual = subchan.getFullName() + " [" + k + "]"; + + // the node must have not been declared; do so here + emitChannelDecl( + new CellUtils.Channel( + instanceName, subchan.getName(), subchan, + subchan.getType(), k, + subchan.getDirection()), + unconnectedWideNodes, out); + } + actuals.add(actual); + } + } else { + final CellUtils.Channel chan = + new CellUtils.Channel(instanceName, subchan.getName(), + subchan.getParent(), subchan.getType(), + subchan.getIndex(), + subchan.getDirection()); + actuals.add(getActualName(portToLocalMap, chan)); + } + + // only output a connection for the first alias to a port, + // others are handled earlier in assign statements + if (portAliases != null && !aliasedPorts.add(formal)) continue; + + actualPorts.add(new Triplet(subtype, formal, actuals)); + } + + // emit the subcell module instantiation + out.println('\\' + convertedName + " \\" + instanceName + " ("); + for (Iterator j = actualPorts.iterator(); j.hasNext(); ) { + final Triplet triple = (Triplet) j.next(); + final PortTypeInterface type = + (PortTypeInterface) triple.getFirst(); + final String formal = (String) triple.getSecond(); + final List actuals = (List) triple.getThird(); + if (type instanceof NodeType) { + emitNodeConnection(cell, instanceName, formal, actuals, + out); + } else { + assert actuals.size() == 1; + emitChannelConnection(cell, instanceName, formal, + (String) actuals.get(0), out); + } + if (j.hasNext()) out.println(','); + } + out.println(");"); + } + + if (topLevel && !leafDelayBias.isEmpty()) { + out.println("`ifdef USE_CAST2VERILOG_DELAYBIAS"); + out.println(delaybiasAnnotationName + " CAST2VERILOG_DELAYBIAS();"); + out.println("`endif"); + } + + if (topLevel && !leafExtraDelay.isEmpty()) { + out.println("`ifdef USE_CAST2VERILOG_EXTRADELAY"); + out.println(extraDelayAnnotationName + + " CAST2VERILOG_EXTRADELAY();"); + out.println("`endif"); + } + + final String converterModule = narrowWideConverters.size() > 0 || + nodeNarrowConverters.size() > 0 + ? VerilogUtil.escapeIfNeeded(moduleName + "$converters") + : null; + + if (converterModule != null) { + out.println(converterModule + " cast2verilog$converters();"); + } + + out.println("endmodule // module with subcells"); + out.println(); + + // Emit converter instantiation module if needed + if (converterModule != null) { + out.println("module " + converterModule + ";"); + + // Wide to narrow converters + for (final CellUtils.Channel wide : narrowWideConverters) { + usedWide2NarrowConvs.add( + instantiateWideNarrowConverter(wide, portToLocalMap, + moduleName, out)); + } + + // Narrow to node converters + for (final CellUtils.Channel narrow : nodeNarrowConverters) { + instantiateNarrowNodeConverter(narrow, portToLocalMap, + moduleName, out); + } + out.println("endmodule // converter module"); + } + out.println(); + } + + private void addLocalName(final CellUtils.Channel source, + final CellUtils.Channel sink, + final Map portMap, + final Set alreadyDeclared, + final Map flattenNodes, + final Collection needAssign, + final PrintWriter out) { + final CellUtils.Channel local; + if (source.getInstance() == null || sink.getInstance() != null) { + local = source; + } else { + local = sink; + } + + if ((local.getInstance() != null || local.getParent() != null) && + alreadyDeclared.add(local)) { + // XXX: with the port handling below, this may cause some extrenous + // (but harmless) wires to be declared; to avoid this, declaration + // should happen after the names have been fixed + emitChannelDecl(local, alreadyDeclared, out); + } + + if (!portMap.containsKey(source)) portMap.put(source, local); + else if (local == sink) { + final CellUtils.Channel prev = + (CellUtils.Channel) portMap.get(source); + if (prev.getInstance() == null) { + needAssign.add(new Pair(prev, local)); + } else { + portMap.put(source, local); + } + } + if (portMap.containsKey(sink)) { + final CellUtils.Channel prev = + (CellUtils.Channel) portMap.get(sink); + if (!prev.equals(local)) { + final CellUtils.Channel old = + (CellUtils.Channel) simplifyMap(portMap, prev); + final CellUtils.Channel curr = + (CellUtils.Channel) simplifyMap(portMap, local); + final CellUtils.Channel from, to; + if ((old.getInstance() == null) != + (curr.getInstance() == null)) { + if (old.getInstance() == null) { + from = curr; to = old; + } else { + from = old; to = curr; + } + } else { + if (curr.compareTo(old) < 0) { + from = curr; to = old; + } else { + from = old; to = curr; + } + } + portMap.put(from, to); + } + } else { + portMap.put(sink, local); + } + } + + private void declareWire(final String name, final int width, + final PrintWriter out) { + out.println("wire" + (width > 0 ? " [" + (width - 1) + ":0] " : " ") + + VerilogUtil.escapeIfNeeded(name) + ";"); + } + + private void emitChannelDecl(final CellUtils.Channel channel, + final Set alreadyDeclared, + final PrintWriter out) { + final PortTypeInterface type = channel.getType(); + final String fullName = channel.getFullName(); + if (type instanceof NodeType) { + final CellUtils.Channel parent = channel.getParent(); + if (parent != null && parent.getType() instanceof NodeType) { + if (channel.getInstance() != null && + alreadyDeclared.add(parent)) + declareWire(parent.getFullName(), + ((NodeType) parent.getType()).getWidth(), out); + } else { + declareWire(fullName, 0, out); + } + } else { + final ChannelType chan = (ChannelType) type; + declareWire(fullName + "$data", getNumBitsWide(chan), out); + declareWire(fullName + "$enable", 0, out); + } + } + + private int[] instantiateWideNarrowConverter(final CellUtils.Channel wide, + final Map portMap, + final String hier, + final PrintWriter out) { + final ChannelType type = (ChannelType) wide.getType(); + final int base = getBase(type); + final int width = type.getWidth(); + + final String otherWide = + ((CellUtils.Channel) portMap.get(wide)).getFullName(); + + final String convType = + getChannelConverterName(base, width, wide.isInput()); + out.println("\\" + convType + " \\conv_" + otherWide + " ("); + + // output connections to the wide side of the converter + emitChannelConnection("WIDE", otherWide, hier, out); + + // output connections to the narrow side of the converter + int j = 0; + for (Iterator i = wide.getChildren().iterator(); i.hasNext(); ++j) { + if (i.hasNext()) out.println(","); + final CellUtils.Channel narrow = (CellUtils.Channel) i.next(); + final String otherNarrow = + ((CellUtils.Channel) portMap.get(narrow)).getFullName(); + emitChannelConnection("NARROW[" + j + "]", otherNarrow, hier, out); + } + + // output connection to reset + out.println(");"); + + return new int[] { base, width, wide.isInput() ? 0 : 1 }; + } + + private void instantiateNarrowNodeConverter(final CellUtils.Channel narrow, + final Map portMap, + final String hier, + final PrintWriter out) { + final ChannelType type = (ChannelType) narrow.getType(); + final int base = getBase(type); + final int width = type.getWidth(); + + final String otherNarrow = + ((CellUtils.Channel) portMap.get(narrow)).getFullName(); + out.print(narrow.isInput() ? "Nodes2ChannelConv2" + : "Channel2NodesConv2"); + out.print(" #(.base(" + base + "), "); + out.print(".numBits(" + getNumBitsNarrow(type) + ")) "); + out.println("\\conv_" + otherNarrow + " ("); + + // output connections to the narrow side of the converter + emitChannelConnection("channel", otherNarrow, hier, out); + out.println(","); + + // output connections to the node side of the converter + // the order is d[0], d[1], ... + out.print(".nodes ({"); + final Collection nodes = narrow.getChildren(); + final Iterator i = nodes.iterator(); + for (int j = 0; j < nodes.size() - 1; ++j) { + final CellUtils.Channel node = (CellUtils.Channel) i.next(); + final String otherNode = + ((CellUtils.Channel) portMap.get(node)).getFullName(); + out.print(hierRef(hier, VerilogUtil.escapeIfNeeded(otherNode))); + if (j < nodes.size() - 2) out.print(", "); + } + out.println("}),"); + + // output connection to enable + final CellUtils.Channel node = (CellUtils.Channel) i.next(); + final String otherNode = + ((CellUtils.Channel) portMap.get(node)).getFullName(); + out.println(".enable(" + + hierRef(hier, VerilogUtil.escapeIfNeeded(otherNode)) + + "));"); + } + + private void declConverterVars(final Collection converters, + final Set alreadyDeclared, + final Map flattenNodes, + final Map portMap, + final PrintWriter out) { + for (Iterator i = converters.iterator(); i.hasNext();) { + final CellUtils.Channel parent = (CellUtils.Channel) i.next(); + if (!portMap.containsKey(parent)) { + addLocalName(parent, parent, portMap, alreadyDeclared, + flattenNodes, null, out); + } + for (Iterator j = parent.getChildren().iterator(); j.hasNext(); ) { + final CellUtils.Channel child = (CellUtils.Channel) j.next(); + if (!portMap.containsKey(child)) { + addLocalName(child, child, portMap, alreadyDeclared, + flattenNodes, null, out); + } + } + } + } + + private static boolean wideNodeChild(final CellUtils.Channel channel) { + return channel.getParent() != null && + channel.getParent().getType() instanceof NodeType && + channel.getParent().getParent() == null; + } + + /** + * Return the string representation for a possibly wide node typed channel. + * The returned string will be properly escaped. + **/ + private static String nodeVerilogName(final CellUtils.Channel channel) { + assert channel.getType() instanceof NodeType; + + if (wideNodeChild(channel)) { + final CellUtils.Channel parent = channel.getParent(); + return VerilogUtil.escapeIfNeeded(parent.getFullName()) + + "[" + channel.getIndex() + "]"; + } else { + return VerilogUtil.escapeIfNeeded(channel.getFullName()); + } + } + + private Object simplifyMap(final Map portMap, final Object key) { + final Object value = portMap.get(key); + if (value == null || value == key) { + return key; + } else { + final Object last = simplifyMap(portMap, value); + portMap.put(key, last); + return last; + } + } + + private Map processPortConnections( + final CellInterface cell, + final Map flattenNodes, + final Set narrowInstances, + final Set nodeNarrowConverters, + final Set narrowWideConverters, + final PrintWriter out) { + final Map portMap = new HashMap(); + + final Collection nodeConnections = new ArrayList(); + final Collection narrowConnections = new ArrayList(); + final Collection wideConnections = new ArrayList(); + + CellUtils.getChannelConnection(cell, + nodeConnections, narrowConnections, wideConnections, + new AliasedSet(), new AliasedSet(), new AliasedSet(), + nodeNarrowConverters, narrowWideConverters, flattenNodes, + false, false, getCadencize(false), getCadencize(true)); + + // convert a wide connection to narrow connections if either the source + // or the sink instance is supposed to be narrow + for (Iterator i = wideConnections.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellUtils.Channel source = (CellUtils.Channel) p.getFirst(); + final CellUtils.Channel sink = (CellUtils.Channel) p.getSecond(); + if (narrowInstances.contains(source.getInstance()) || + narrowInstances.contains(sink.getInstance())) { + for (Iterator srcIter = source.getChildren().iterator(), + snkIter = sink.getChildren().iterator(); + srcIter.hasNext() && snkIter.hasNext(); ) { + narrowConnections.add(new Pair(srcIter.next(), + snkIter.next())); + } + + // add additional converters that might be necessary because + // one end of a connection is wide, but the other end is + // narrow. + if (!narrowInstances.contains(source.getInstance())) + narrowWideConverters.add(source); + if (!narrowInstances.contains(sink.getInstance())) + narrowWideConverters.add(sink); + + i.remove(); + } + } + + // remove narrow to wide converters for narrow instances as they are + // not necessary + for (Iterator i = narrowWideConverters.iterator(); i.hasNext(); ) { + final CellUtils.Channel chan = (CellUtils.Channel) i.next(); + if (narrowInstances.contains(chan.getInstance())) i.remove(); + } + + final Set alreadyDeclared = new HashSet(); + + // Signals that need to be connected via assign statements + final Collection needAssign = new HashSet(); + + for (Iterator i = + new FlatteningIterator( + Arrays.asList( + new Iterator[] { + nodeConnections.iterator(), + narrowConnections.iterator(), + wideConnections.iterator() }).iterator()); + i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellUtils.Channel source = (CellUtils.Channel) p.getFirst(); + final CellUtils.Channel sink = (CellUtils.Channel) p.getSecond(); + addLocalName(source, sink, portMap, alreadyDeclared, flattenNodes, + needAssign, out); + if (source.getInstance() == null && sink.getInstance() == null) + needAssign.add(p); + } + + // Make sure all variables used in instantiating converters have + // appropriate mapping in portMap + declConverterVars(narrowWideConverters, alreadyDeclared, flattenNodes, + portMap, out); + declConverterVars(nodeNarrowConverters, alreadyDeclared, flattenNodes, + portMap, out); + + // Compute the transitive closure of the name mapping to find the + // ultimate name to use + for (Iterator i = portMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + entry.setValue(simplifyMap(portMap, entry.getValue())); + } + + for (Iterator i = needAssign.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellUtils.Channel source = (CellUtils.Channel) p.getFirst(); + final CellUtils.Channel sink = (CellUtils.Channel) p.getSecond(); + if (source.getType() instanceof NodeType) { + final String sourceName = nodeVerilogName(source); + final String sinkName = nodeVerilogName(sink); + out.println("assign " + sinkName + " = " + sourceName + ";"); + } else { + out.println("assign " + + VerilogUtil.escapeIfNeeded(sink.getFullName() + + "$data") + " = " + + VerilogUtil.escapeIfNeeded(source.getFullName() + + "$data") + ";"); + out.println("assign " + + VerilogUtil.escapeIfNeeded(source.getFullName() + + "$enable") + " = " + + VerilogUtil.escapeIfNeeded(sink.getFullName() + + "$enable") + ";"); + } + } + + return portMap; + } + + private int getBase(ChannelType chanType) { + return CellUtils.extractN(chanType.getTypeName()); + } + + private int getNumBitsNarrow(PortTypeInterface portType) { + if (portType instanceof ChannelType) { + return getNumBitsNarrow((ChannelType) portType); + } else { + return(1); + } + } + + /*** + Find the number of bits we need to model each narrow channel element + of a possibly wide channel. + ***/ + private int getNumBitsNarrow(ChannelType chanType) { + return getNumBitsNarrow(CellUtils.extractN(chanType.getTypeName())); + } + + private int getNumBitsNarrow(final int rails) { + // Regardless if the channel is wide, the number of narrow bits + // only depends on the base type + final BigInteger numValues = BigInteger.valueOf(rails); + // We can carry numValues values in base type, including 0. + // numValues - 1 is the largest we can carry. + // See how many bits that takes. + final int bitWidth = numValues.subtract(BigInteger.ONE).bitLength(); + // Use bitWidth + 1 bits for the port so we can handle + // negative numbers, too. + return(bitWidth + 1); + } + + private int getNumBitsWide(PortTypeInterface portType) { + if (portType instanceof ChannelType) { + return getNumBitsWide((ChannelType) portType); + } else { + return(1); + } + } + + /*** + Find the number of bits we need model the data in possibly wide channels + **/ + private int getNumBitsWide(ChannelType chanType) { + return getNumBitsWide(CellUtils.extractN(chanType.getTypeName()), + chanType.getWidth()); + } + + private int getNumBitsWide(final int rails, final int width) { + final BigInteger numValues = BigInteger.valueOf(rails).pow(width); + // We can carry numValues values, including 0. + // numValues - 1 is the largest we can carry. + // See how many bits that takes. + final int bitWidth = numValues.subtract(BigInteger.ONE).bitLength(); + // Use bitWidth + 1 bits for the port so we can + // handle negative numbers, too. + return(bitWidth + 1); + } + + /** + * Same as emitChannelConnection(String, String, PrintWriter), except also + * log a warning if there is no connection. + **/ + private void emitChannelConnection(final CellInterface parent, + final HierName instance, + final String formal, + final String actual, + final PrintWriter out) { + if (actual == null) { + logger.warning("In " + parent.getFullyQualifiedType() + + ", port " + formal + " of instance " + + instance + " is unconnected."); + } + emitChannelConnection(formal, actual, null, out); + } + + private String hierRef(final String hier, final String local) { + return hier == null ? local + : VerilogUtil.escapeIfNeeded(hier) + "." + local; + } + + /** + * Emits argument passing of channel using Verilog dot notation, expanding + * data and enable. + **/ + private void emitChannelConnection(final String formal, final String actual, + final String hier, + final PrintWriter out) { + out.println(" .\\" + formal + "$data (" + + (actual == null ? "/*NC*/" + : hierRef(hier, "\\" + actual + "$data ")) + + "),"); + out.print(" .\\" + formal + "$enable (" + + (actual == null ? "/*NC*/" + : hierRef(hier, "\\" + actual + "$enable ")) + + ")"); + } + + private void emitNodeConnection(final CellInterface parent, + final HierName instance, + final String formal, + final List actuals, + final PrintWriter out) { + boolean unconnected = false; + + final String port = " .\\" + formal + " ("; + out.print(port); + if (actuals.size() == 1) { + final String actual = (String) actuals.get(0); + out.print((actual == null ? "/*NC*/" : "\\" + actual + " ")); + unconnected |= actual == null; + } else { + final String spaces = + ",\n" + StringUtil.repeatString(" ", port.length() + 2); + out.print("{ "); + for (Iterator i = actuals.iterator(); i.hasNext(); ) { + final String actual = (String) i.next(); + out.print(actual == null ? "1'dx" : "\\" + actual + " "); + unconnected |= actual == null; + if (i.hasNext()) out.print(spaces); + } + out.print("} "); + } + out.print(")"); + + if (unconnected) { + logger.warning("In " + parent.getFullyQualifiedType() + + ", port " + formal + " of instance " + + instance + " is unconnected."); + } + } + + /** + * Convert DSim units to number of transitions. + **/ + private float numTransitions(final float dsimUnits) { + return dsimUnits / 100f; + } + + /** + * Emit a cell to be implemented in CSP. + **/ + private void emitCspLeaf(final CellInterface cell, + final String moduleName, + final PrintWriter out, + final boolean emitSlackWrappers) + throws SemanticException { + + final String bodyName = moduleName + (emitSlackWrappers ? "$body" : ""); + out.println("module \\" + bodyName + " ("); + final List/**/ dataNodes = new ArrayList/**/(); + final List/**/ enableNodes = new ArrayList/**/(); + final List/*>*/ arrayInputNodes = + new ArrayList/*>*/(); + final List/*>*/ arrayOutputNodes = + new ArrayList/*>*/(); + final List/**/ inputPorts = new ArrayList/**/(); + /* Call emit PortList - do not flatten wide channels */ + emitPortList(cell, dataNodes, enableNodes, + arrayInputNodes, arrayOutputNodes, inputPorts, out, true); + out.println(");"); + + // declare the array regs for array inputs and outputs + declareArrayRegs(cell.getCSPInfo(), out); + + // emit the continuous assigments for array outputs + // which assign non-arrayed ports to elements of arrayed + // internals (because Verilog does not support arrayed + // ports) + for (Iterator i = arrayOutputNodes.iterator(); i.hasNext(); ) { + final Pair/**/ p = (Pair) i.next(); + final String outputNode = (String) p.getFirst(); + + out.println("assign " + outputNode + " = " + + mungeArray(outputNode) + ';'); + } + + // emit always blocks for the array inputs to set + // arrayed internals to non-arrayed ports (because + // Verilog does not support arrayed ports) + for (Iterator i = arrayInputNodes.iterator(); i.hasNext(); ) { + final Pair/**/ p = (Pair) i.next(); + final String inputNode = (String) p.getFirst(); + + final String munged = mungeArray(inputNode); + out.println("always @* " + munged + " = " + inputNode + ';'); + inputPorts.add(munged); + } + + final String resetName = getResetName(cell); + // initialize port variables + out.println("always @(negedge " + resetName + " )"); + out.println("begin : init_ports"); + out.println("disable main;"); + + // set all enables to 1 and data rails to -1 + for (Iterator i = dataNodes.iterator(); i.hasNext(); ) { + final String dataNode = (String) i.next(); + out.println(dataNode + " = $signed(-1);"); + } + + for (Iterator i = enableNodes.iterator(); i.hasNext(); ) { + final String enableNode = (String) i.next(); + out.println(enableNode + " = 1;"); + } + + // set array output data regs to -1, indicating no data + for (Iterator i = arrayOutputNodes.iterator(); i.hasNext(); ) { + final Pair/**/ p = (Pair) i.next(); + final String outputNode = (String) p.getFirst(); + final Integer value = (Integer) p.getSecond(); + + if (value != null) + out.println(mungeArray(outputNode) + " = $signed(" + + value + ");"); + } + + // don't initialize our input array enable regs, the always + // blocks will take care of it for us. + + out.println("end"); + out.println(); + + if (probFilter == null) + probFilter = Csp2Verilog.getProblemFilter(warningWriter); + + new Csp2Verilog(warningWriter, errorWriter, debugWriter, resetName, + registerBitWidth, probFilter, enableSystemVerilog) + .convert(cell, inputPorts, out); + + out.println("endmodule // CSP body "); + out.println(); + out.println(); + + if (emitSlackWrappers) + emitSlackWrapper(cell, moduleName, bodyName, BlockInterface.CSP, + out); + } + + private void emitPassThru(final PortDefinition l, final PortDefinition r, + final PrintWriter out) { + final Collection lports = + new ArrayList(); + new CellUtils.FlattenPortDefinitions(lports).mark( + Collections.singleton(l).iterator()); + + final Collection rports = + new ArrayList(); + new CellUtils.FlattenPortDefinitions(rports).mark( + Collections.singleton(r).iterator()); + + assert lports.size() == rports.size() : + "Left and right ports not compatible: " + l + " " + r; + + final Iterator liter = lports.iterator(); + final Iterator riter = rports.iterator(); + while (liter.hasNext() && riter.hasNext()) { + final PortDefinition lport = liter.next(); + final PortDefinition rport = riter.next(); + final String input, output; + if (lport.getDirection() == PortDefinition.IN) { + input = lport.getName(); + output = rport.getName(); + } else { + input = rport.getName(); + output = lport.getName(); + } + + if (lport.getType() instanceof ChannelType && + rport.getType() instanceof ChannelType) { + out.println("assign \\" + output + "$data = \\" + + input + "$data ;"); + out.println("assign \\" + input + "$enable = \\" + + output + "$enable ;"); + } else { + out.println("assign \\" + output + " = \\" + input + " ;"); + } + } + } + + /** + * Emits wrapper that includes all timing buffers. $body is surrounded + * by timing buffers, 1 per (possibly wide) channel + **/ + private void emitSlackWrapper(final CellInterface cell, + final String moduleName, + final String bodyName, + final String block, + PrintWriter out) { + + // emit module name and port list declaration + // throw away resulting lists as we should need them + out.println("module \\" + moduleName + " ("); + /* Call emit PortList - keep wide channels wide */ + emitPortList(cell, null, null, null, null, null, out, false); + out.println(");"); + + // Collect channels require special handling + final Collection inSramSerial = + new ArrayList(); + final Collection outSramSerial = + new ArrayList(); + final Collection inChanDft = + new ArrayList(); + final Collection outChanDft = + new ArrayList(); + + /* Iterate over flattened possibly wide channels */ + Iterator portDefs = cell.getCSPInfo().getPortDefinitions(); + final Collection partialFlatPorts = new ArrayList(); + (new CellUtils.FlattenPortDefinitions(partialFlatPorts) { + protected void mark(final StructureType structureType, + final String name, final int direction) { + final String tag = structureType.getTag(); + final int dir = translate(direction); + if (CellUtils.isDftChannel(cell, tag)) { + (dir == PortDefinition.IN ? inChanDft : outChanDft) + .add(new PortDefinition(name, structureType, dir)); + } else if (CellUtils.isSramSerialChannel(tag)) { + (dir == PortDefinition.IN ? inSramSerial : outSramSerial) + .add(new PortDefinition(name, structureType, dir)); + } else { + super.mark(structureType, name, direction); + } + } + }).mark(portDefs); + for (Iterator i = partialFlatPorts.iterator(); i.hasNext(); ) { + final PortDefinition port = (PortDefinition) i.next(); + + // Find direction, wideChannelInfo, and bit-widths + final int dir = port.getDirection(); + final String portName = port.getName(); + final PortTypeInterface portType = port.getType(); + + if (portType instanceof NodeType) continue; + + assert portType instanceof ChannelType : + "found non-channel type " + portType + " port after flattening"; + + final ChannelType chanType = (ChannelType) portType; + + final int bitWidth = getNumBitsWide(chanType); + + // Declare necessary new wires. + // Only one or the other is needed as the + // port list offers the other (based on direction) + if (dir == PortDefinition.IN) { + out.println("wire [" + (bitWidth-1) + ":0] \\" + portName + + "$data_snk " + ';'); + out.println("wire \\" + portName + "$enable_src " + ';'); + } else { + out.println("wire [" + (bitWidth-1) + ":0] \\" + portName + + "$data_src " + ';'); + out.println("wire \\" + portName + "$enable_snk " + ';'); + } + + // Find slack parameters; 0 stages by default + final ChannelTimingInfo cti = + DirectiveUtils.getTiming(cell, block, portName, 0); + final int slack = cti.getSlack(); + final float latency = numTransitions(cti.getLatency()); + final float cycletime = numTransitions(cti.getCycleTime()); + + // emit timing buffer instantiation + if (dir == PortDefinition.IN) { + out.print("`CAST2VERILOG_INPUT_TIMINGBUFFER"); + } else { + out.print("`CAST2VERILOG_OUTPUT_TIMINGBUFFER"); + } + if (slack == 0) out.print("_SLACK0"); + + out.print(" #(.bit_width(" + (bitWidth-1) + "), "); + out.print(".cycle_time (" + cycletime + "), "); + if (slack != 0) { + out.print(".slack (" + slack + "), "); + out.print(".forward_latency (" + latency + "), "); + out.print(".cycle_time_in (" + + numTransitions(cti.getCycleTimeIn()) + "), "); + out.print(".cycle_time_out (" + + numTransitions(cti.getCycleTimeOut()) + "), "); + } + if (dir == PortDefinition.IN) { + out.print(".fb_neutral (" + + numTransitions(cti.getDataNeutralEnableLatency()) + + "), "); + out.print(".fb_valid (" + + numTransitions(cti.getDataValidEnableLatency()) + + ")"); + } else { + out.print(".bf_latency (" + + numTransitions(cti.getEnableDataLatency()) + ")"); + } + out.println(") \\tb_" + portName + " ( "); + out.print("." + resetNodeName + " (" + getResetName(cell) + " )"); + if (dir == PortDefinition.IN) { + out.println(","); + out.println(". L$data (\\" + portName + "$data ), "); + out.println(". L$enable (\\" + portName + "$enable ),"); + out.println(". R$data (\\" + portName + "$data_snk ),"); + out.print(". R$enable (\\" + portName + "$enable_src ) "); + } else { + out.println(","); + out.println(". L$data (\\" + portName + "$data_src ),"); + out.println(". L$enable (\\" + portName + "$enable_snk ),"); + out.println(". R$data (\\" + portName + "$data ), "); + out.print(". R$enable (\\" + portName + "$enable ) "); + } + out.println(");"); + } + + // Handle special case for ChanDft + final Iterator chanDftIn = inChanDft.iterator(); + final Iterator chanDftOut = outChanDft.iterator(); + while (chanDftIn.hasNext() && chanDftOut.hasNext()) { + emitPassThru(chanDftIn.next(), chanDftOut.next(), out); + } + + if (chanDftIn.hasNext() != chanDftOut.hasNext()) { + logger.severe("In " + cell.getFullyQualifiedType() + ", " + + "ChanDft ports do not appear in pairs"); + } + + // Handle special case for SramSerialChannel + final Iterator sramSerialIn = inSramSerial.iterator(); + final Iterator sramSerialOut = outSramSerial.iterator(); + while (sramSerialIn.hasNext() && sramSerialOut.hasNext()) { + emitPassThru(sramSerialIn.next(), sramSerialOut.next(), out); + } + + if (sramSerialIn.hasNext() != sramSerialOut.hasNext()) { + logger.severe("In " + cell.getFullyQualifiedType() + ", " + + "SramSerialChannel ports do not appear in pairs"); + } + + // instance name = "body" for now + out.println('\\' + bodyName + " body("); + + // instantiate verilog cell for CSP body using dot notation + // for arguments. + portDefs = cell.getCSPInfo().getPortDefinitions(); + final Collection flatPorts = new ArrayList(); + (new CellUtils.FlattenPortDefinitions(flatPorts) { + protected void mark(final StructureType structureType, + final String name, final int direction) { + final String tag = structureType.getTag(); + if (!CellUtils.isDftChannel(cell, tag) && + !CellUtils.isSramSerialChannel(tag)) { + super.mark(structureType, name, direction); + } + } + }).mark(portDefs); + for (Iterator i = flatPorts.iterator(); i.hasNext(); ) { + final PortDefinition port = (PortDefinition) i.next(); + // Find direction, wideChannelInfo, and bit-widths + final int dir = port.getDirection(); + final String portName = port.getName(); + final PortTypeInterface portType = port.getType(); + + if (portType instanceof NodeType) { + out.print(" .\\" + portName + " (\\" + portName + " )"); + } else { + assert portType instanceof ChannelType; + final ChannelType chanType = (ChannelType) portType; + final int bitWidth = getNumBitsWide(chanType); + if (dir == PortDefinition.IN) { + out.println(" .\\" + portName + "$data (\\" + + portName + "$data_snk ),"); + out.print(" .\\" + portName + "$enable (\\" + + portName + "$enable_src )"); + } else { + assert dir == PortDefinition.OUT; + out.println(" .\\" + portName + "$data (\\" + + portName + "$data_src ),"); + out.print(" .\\" + portName + "$enable (\\" + + portName + "$enable_snk )"); + } + } + if (i.hasNext()) out.println(","); + } + out.println(");"); + + out.println("endmodule // slack wrapper"); + out.println(""); + } + + /** + * Return the reset node for a cell. The reset node is an implied node + * that connects to _RESET in the parent. Mike Davies + * promises this condition is satisfied for any cell that needs to be + * implemented in CSP. + * + * @param cell cell to process + * @return name of the reset node, escaped if necessary + **/ + private static String getResetName(final CellInterface cell) { + final String name = getResetName(cell, null); + if (name == null) { + throw new RuntimeException("Cannot find the reset node in " + + cell.getFullyQualifiedType()); + } else { + return name; + } + } + + /** + * Return the reset node for a cell. The reset node is an implied node + * that connects to _RESET in the parent. If that node does + * not exists and portMap is not null, look for a node called + * _RESET in the current cell, and if it exists, return the + * proper name associated with that node. + * + * @param cell cell to process + * @param portMap mapping from source and sinks to local names generated by + * {@link processPortConnections} + * @return name of the reset node, escaped if necessary + **/ + private static String getResetName(final CellInterface cell, + final Map portMap) { + boolean found = false; + for (Iterator i = cell.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition port = (PortDefinition) i.next(); + if (resetNodeName.equals(cell.getParentImpliedPort(port.getName()))) + { + return VerilogUtil.escapeIfNeeded(port.getName()); + } + if (resetNodeName.equals(port.getName())) found = true; + } + + if (portMap == null) { + if (found) return VerilogUtil.escapeIfNeeded(resetNodeName); + } else { + // _RESET may not be in the map directly, because the map only + // contains sources and sinks, but one of its aliases should be in + // the map, if _RESET is in fact connected correctly + final HierName hierReset = HierName.makeHierName(resetNodeName); + final Iterator i = cell.getConnectedNodes(hierReset); + if (i != null) { + while (i.hasNext()) { + final String alias = ((HierName) i.next()).getAsString('.'); + final CellUtils.Channel candidate = + new CellUtils.Channel(null, alias, null, new NodeType(), + -1, -1); + final CellUtils.Channel reset = + (CellUtils.Channel) portMap.get(candidate); + if (reset != null) + return nodeVerilogName(reset); + } + } + } + + return null; + } + + private void annotateDelaybias(final PrintWriter out, + final String topModule) { + // don't output anything if there are no instance delaybiases + if (leafDelayBias.isEmpty()) return; + + final String esc = VerilogUtil.escapeIfNeeded(topModule); + out.println("`ifdef USE_CAST2VERILOG_DELAYBIAS"); + out.println("module " + delaybiasAnnotationName + ";"); + out.println("defparam"); + for (Iterator i = leafDelayBias.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + out.println(" " + esc + "." + entry.getKey() + "." + + VerilogUtil.escapeIfNeeded( + ConverterConstants.getDelayBiasString()) + + " = " + entry.getValue() + (i.hasNext() ? "," : ";")); + } + out.println("endmodule"); + out.println("`endif"); + } + + private void annotateExtraDelay(final String prefix, + final HierName net, + final boolean up, + final float extraDelay, + final PrintWriter out, + final boolean[] first) { + if (!first[0]) out.println(","); + out.print(prefix + + VerilogUtil.escapeIfNeeded( + ConverterConstants.getExtraDelayString( + net, up)) + " = " + + numTransitions(extraDelay)); + first[0] = false; + } + + private void annotateExtraDelay(final PrintWriter out, + final String topModule) { + // don't output anything if there are no extra delays + if (leafExtraDelay.isEmpty()) return; + + final String esc = VerilogUtil.escapeIfNeeded(topModule); + out.println("`ifdef USE_CAST2VERILOG_EXTRADELAY"); + out.println("module " + extraDelayAnnotationName + ";"); + out.println("defparam"); + final boolean[] first = new boolean[] { true }; + for (Iterator i = leafExtraDelay.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String partialLhs = " " + esc + "." + entry.getKey() + "."; + for (Iterator j = ((Map) entry.getValue()).entrySet().iterator(); + j.hasNext(); ) { + final Map.Entry netValue = (Map.Entry) j.next(); + final HierName net = (HierName) netValue.getKey(); + final float[] extraDelay = (float[]) netValue.getValue(); + if (extraDelay[0] != 0) + annotateExtraDelay(partialLhs, net, true, extraDelay[0], + out, first); + if (extraDelay[1] != 0) + annotateExtraDelay(partialLhs, net, false, extraDelay[1], + out, first); + } + } + if (!first[0]) out.println(";"); + out.println("endmodule"); + out.println("`endif"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/cast2verilog.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/cast2verilog.package new file mode 100644 index 0000000000..8080e2e83a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/cast2verilog.package @@ -0,0 +1,13 @@ +0 6 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.tools.cast2verilog.Cast2Verilog +java com.avlsi.tools.cast2verilog.Cast2RTL +include ../../csp/resources/resources.package.inc ../../csp/resources +include ../../util/logging/logging.package.inc ../../util/logging +$arch/bin/cast2verilog.sh cast2verilog.sh 775 +$arch/bin/cast2rtl.sh cast2rtl.sh 775 +$arch/bin/verilog_filelist verilog_filelist.pl 775 p diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/custom.mk new file mode 100644 index 0000000000..e492600818 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/custom.mk @@ -0,0 +1,9 @@ +CURR_RESULT_FILES := $(CURR_TARGET_DIR)/cast2verilog.sh $(CURR_TARGET_DIR)/cast2rtl.sh $(CURR_RESULT_FILES) + +$(CURR_TARGET_DIR)/cast2verilog.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.cast2verilog.Cast2Verilog/" >$@ + +$(CURR_TARGET_DIR)/cast2rtl.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.cast2verilog.Cast2RTL/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/verilog_filelist.pl b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/verilog_filelist.pl new file mode 100644 index 0000000000..33d4f4e31f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cast2verilog/verilog_filelist.pl @@ -0,0 +1,38 @@ +#!/usr/intel/bin/perl +use strict; +use warnings; +use Getopt::Long; + +my ($mem, $cell); +my $path = '.'; +my $output = '/dev/stdout'; +my @defines = (); + +GetOptions("cast-path=s" => \$path, + "cell=s" => \$cell, + "define=s" => \@defines, + "max-heap-size=s" => \$mem, + "output=s" => \$output) || die "Can't parse arguments: $!"; + +if (!defined($cell)) { + print STDERR < (cell to generate filelist for) + [--cast-path= (CAST path, defaults to .)] + [--max-heap-size=] + [--define= ...] + [--output= (defaults to /dev/stdout)] +EOF + exit(2); +} + +my @cmd = ('cast2verilog', + "--cast-path=$path", + "--cell=$cell", + '--output-file=/dev/null', + "--file-list=$output", + map { "--define=$_" } @defines); +push @cmd, "--max-heap-size=$mem" if defined $mem; + +exec(@cmd); + +exit(1); # in case cast2verilog cannot be executed diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2aspice/CDL2Aspice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2aspice/CDL2Aspice.java new file mode 100644 index 0000000000..a9e468776d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2aspice/CDL2Aspice.java @@ -0,0 +1,88 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.cdl2aspice; + +import java.io.FileOutputStream; +import java.util.Map; +import java.util.TreeMap; + +import com.avlsi.file.aspice.AspiceCell; +import com.avlsi.file.spice.SpiceParser; + +/** + * Converts a .cdl file to a .aspice file. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public final class CDL2Aspice { + private static void usage(final int exitStatus) { + System.err.println("Usage: cdl2aspice " + + "( --res res_type rho )*" + + "file.cdl cell_name out_file"); + System.exit(exitStatus); + } + + public static void main(final String[] args) { + if (args.length < 3) + usage(1); + + final Map resMap = new TreeMap(); + + int i = 0; + for (i = 0; i + 3 < args.length && args[i].equals("--res"); i += 3) { + final String resType = args[i + 1]; + final String rho = args[i + 2]; + + try { + final Double d = + (Double) resMap.put(resType, new Double(rho)); + if (d != null) { + System.err.println("Duplicate rho for " + resType + + ". Old value: " + d + ", new value: " + rho); + System.exit(2); + } + } catch (NumberFormatException e) { + System.err.println("Bad double format for rho of " + + resType + ": " + rho); + System.exit(3); + } + } + + final String cdlFileName = args[i]; + final String cdlCellName = args[i + 1]; + final String outFile = args[i + 2]; + AspiceCell.Repository repos = new AspiceCell.Repository(); + + try { + SpiceParser.ParsingCallback callback = null; + final SpiceParser spiceParser = + new SpiceParser('.', resMap, callback); + spiceParser.parseFile(cdlFileName, repos); + final AspiceCell aspiceCell = + (AspiceCell) repos.getCell(cdlCellName); + + if (aspiceCell == null) { + System.err.println("Couldn't find cell " + cdlCellName); + System.exit(2); + } + + aspiceCell.printToStream(new FileOutputStream(outFile), repos); + } catch (Exception e) { + e.printStackTrace(); + System.err.println(e + ": " + e.getMessage()); + System.exit(1); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/CDL2Cast.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/CDL2Cast.java new file mode 100644 index 0000000000..f97798a185 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/CDL2Cast.java @@ -0,0 +1,1528 @@ +/* Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.tools.cdl2cast; + + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.HashSet; +import java.util.HashMap; +import java.util.TreeMap; +import java.util.Iterator; +import java.util.Collection; +import java.util.Collections; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.ListIterator; +import java.util.LinkedHashSet; +import java.util.ArrayList; + +import java.io.Writer; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.OutputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.InputStreamReader; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.io.File; +import java.io.IOException; +import java.io.FileNotFoundException; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.file.cdl.parser.CDLLexer; + +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.BindRulNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CompositeCDLNameInterface; +import com.avlsi.file.cdl.util.rename.CompositeCDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameFactory; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.TrivialCDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.layout.gdsII.GenerateGDSIIDataFactory; +import com.avlsi.layout.gdsII.SkillTableEmitterFactory; +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; + +import com.avlsi.file.cdl.parser.SplittingFactory; +import com.avlsi.file.cdl.parser.TemplateSplitterFactory; +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLFactoryAdaptor; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.CDLInterfaceSimplifier; +import com.avlsi.file.cdl.parser.CDLInlineFactory; +import com.avlsi.file.cdl.parser.CDLScalingFactory; +import com.avlsi.file.cdl.parser.Template; + +import com.avlsi.util.container.Pair; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.io.IndentWriter; + +import com.avlsi.util.exception.AssertionFailure; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +import com.avlsi.layout.gdsII.AssuraBindRulTableEmitterFactory; + +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.cdl.parser.AspiceCellAdapter; + +/** + * This class writes out a hierarchical cdl file as a tree + * of .cast files in a spec tree and digital tree, and a SKILL names.il table + * directory of mappings from existing layout names -> desired layout names which + * will be used in gds2hier.il dfII library munging. It includes prs generated + * from NetGraph. + **/ + +public class CDL2Cast { + + private static void usage( String m ) { + + final String className = CDL2Cast.class.getName(); + + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className + "\n" + + " --cdl-file=file\n" + + " --output-spec=dir\n" + + " --output-cast=dir\n" + + " [--pedantic]\n" + + " [--vdd-node=name]\n" + + " [--gnd-node=name]\n" + + " [--node-prefix=prefix]\n" + + " [--instance-prefix=prefix]\n" + + " [--lib-name=name]\n" + + " [--refinement-parent=type]\n" + + " [--name-table-dir=.]\n" + + " [--sub-type=num]\n" + + " [--meters-per-input-unit=1]\n" + + " [--layout-to-cdl-bind-rul=/dev/null]\n" + + " [--output-cdl-to-layout-bind-rul=/dev/null]\n" + + " [--bind-rul-in=/dev/null]\n" + + " [--bind-rul-template=/dev/null]\n" + + " [--skip-prs-generation]\n" + + " [--all-cells]\n" + ); + if (m != null && m.length() > 0) + System.err.println ( m ); + System.exit(1); + } + + /** + * returns a Writer to fileName + **/ + public static Writer openOutputFile( final String fileName ) + throws IOException + { + final Writer ret; + + final OutputStream outputStream = + new FileOutputStream( fileName ); + + ret = new BufferedWriter( new OutputStreamWriter( outputStream ) ); + + return ret; + } + + public static File makeDir( final String dirName ) { + File dir; + if ( dirName != null ) { + dir = new File( dirName ); + } + else { + dir = null ; + } + + if ( ( dir != null ) && + ( ! ( dir.exists() ) ) ) { + dir.mkdirs(); + } + return dir; + } + + + public static void main(String[] args) + throws Exception + { + final CommandLineArgs parsedArgs = + new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs(cachedArgs); + final CommandLineArgs theArgs = pedanticArgs; + + final Boolean allCells = theArgs.argExists( "all-cells" ); + + final String sourceCDLFileName = + theArgs.getArgValue( "cdl-file", null ); + + final String inputBindRulFileName = + theArgs.getArgValue( "bind-rul-in", "/dev/null" ); + + final String bindRulHeaderFileName = + theArgs.getArgValue( "bind-rul-header", "/dev/null" ); + + /** + * The location of the .names.il output. These files contain + * SKILL tables with naem mappings from + **/ + final String outputSkillTableDirName = + theArgs.getArgValue( "name-table-dir", "." ); + + + /** + * The location of the digital cast output. The digital cast + * will contain port definitions and a subcells block for each cell + * with a .SUBCKT in the cdl file + **/ + final String outputSpecTreeDirName = + theArgs.getArgValue( "output-spec", null ); + + /** + * The location of the digital cast output. The digital cast + * will contain port definitions and a subcells block for each cell + * with a .SUBCKT in the cdl file + **/ + final String outputCastTreeDirName = + theArgs.getArgValue( "output-cast", null ); + + /** + * The names for Vdd and GND (rename to canonical Vdd/GND). + **/ + final String Vdd = theArgs.getArgValue("vdd-node", "VDD"); + final String GND = theArgs.getArgValue("gnd-node", "VSS"); + + /** + * Prefixes to apply to node and instance names to make sure + * they aren't ambiguous. + **/ + final String nodePrefix = theArgs.getArgValue("node-prefix",""); + final String instancePrefix = theArgs.getArgValue("instance-prefix",""); + + /** + * The libname and subtype for backstop renamed cells + **/ + final String subType = theArgs.getArgValue( "sub-type", "0" ); + final String libName = theArgs.getArgValue( "lib-name", "" ); + + /** + * Sometimes, generated CDL will have non meter units + * e.g. M0 a b c d n w=1.2 l=0.13 + * will imlicitly have units of microns. + * All length units in the output CAST will be multiplied + * by this constant + **/ + final double metersPerInputUnit = + Double.parseDouble + ( theArgs.getArgValue( "meters-per-input-unit", "1" ) ); + + /** + * The refinement parent for generated digital CAST cells + **/ + final String refinementParent = + theArgs.getArgValue( "refinement-parent", "NULL" ); + + /** + * bind.rul format mappings from cdl -> existing layout + * Can be generated (.cxl) by running Assura LVS + */ + final String cdlToLayoutInputBindRulFileName = + theArgs.getArgValue( "layout-to-cdl-bind-rul", "/dev/null" ); + + /** + * bind.rul format mappings from cdl -> desired layout + */ + final String cdlToDesiredLayoutOutputBindRulFileName = + theArgs.getArgValue( "output-cdl-to-layout-bind-rul", "/dev/null" ); + + final String outputCastCellsFileName = + theArgs.getArgValue( "output-cast-cells", "/dev/null" ); + + final Writer outputCastCellsWriter = + new BufferedWriter(new FileWriter( new File(outputCastCellsFileName))); + + final boolean skipPrsGeneration = + theArgs.argExists("skip-prs-generation"); + + if (! pedanticArgs.pedanticOK(false, true)) { + usage(pedanticArgs.pedanticString()); + } + + if ( ( sourceCDLFileName != null ) && + ( inputBindRulFileName != null ) && + ( bindRulHeaderFileName != null ) && + ( outputSkillTableDirName != null ) && + ( outputSpecTreeDirName != null ) && + ( outputCastTreeDirName != null ) && + ( libName != null ) && + ( subType != null ) && + ( refinementParent != null ) && + ( cdlToLayoutInputBindRulFileName != null ) && + ( cdlToDesiredLayoutOutputBindRulFileName != null ) + ) { + + final File bindRulHeaderFile = new File(bindRulHeaderFileName); + final File sourceCDLFile = new File( sourceCDLFileName ); + final File inputBindRulFile = new File( inputBindRulFileName ); + final File cdlToLayoutInputBindRulFile = + new File( cdlToLayoutInputBindRulFileName ); + final File cdlToDesiredLayoutOutputBindRulFile = + new File( cdlToDesiredLayoutOutputBindRulFileName ); + final File outputSkillTableDir; + final File outputSpecTreeDir; + final File outputCastTreeDir; + + if ( ( sourceCDLFile.isFile() ) && + ( sourceCDLFile.canRead() ) ) { + if ( ( inputBindRulFile.canRead() ) && + ( cdlToLayoutInputBindRulFile.canRead() ) ) { + final InputStream sourceCDLInputStream = + new FileInputStream( sourceCDLFile ); + + final Reader sourceCDLReader = + new InputStreamReader( sourceCDLInputStream, "UTF-8" ); + + final InputStream inputBindRulInputStream = + new FileInputStream( inputBindRulFile ); + + final Reader inputBindRulReader = + new InputStreamReader( inputBindRulInputStream, "UTF-8" ); + + final InputStream cdlToLayoutInputBindRulStream = + new FileInputStream( cdlToLayoutInputBindRulFile ); + + + final Reader cdlToLayoutInputBindRulReader = + new InputStreamReader( cdlToLayoutInputBindRulStream, "UTF-8" ); + + outputSpecTreeDir = makeDir(outputSpecTreeDirName); + outputCastTreeDir = makeDir(outputCastTreeDirName); + outputSkillTableDir = makeDir(outputSkillTableDirName); + + /** + * The cdl is split into 2 factories, one which turns + * it into templates, one which creates a directory + * of names.il tables. + * + * The templates are renamed to CAST names, which are + * the names mapped from CDL names by the bind-rul-in file + * ( If no mapping is given, a backstop CAST-lagalizing + * renaming is enforced ) + * They are then flattened if they have both components + * and subcell instantiations, and templates with multiple + * parameterizations are split into new templates + * + * The names.il files map from the existing layout names + * to the cadence translated CAST names. The existing + * layout names are just the CDL names mapped to layout + * names with the layout-cdl-bind-rul + **/ + + /** + * The back-stop for convertng cdl names to CAST names + * Alter names so that they are CAST legal and have no + * special meaning, and so that node names don't conflict + * with instantiations + **/ + final CDLNameInterface castLegalizingNI = + new CDLNameInterface() { + private String escape( final String name ) { + final String S0 = name.replaceAll( "\\." , "_D_" ); + final String S1 = S0.replaceAll( "\\[", "_L_"); + final String S2 = S1.replaceAll( "\\]", "_R_" ); + final String S3 = S2.replaceAll( "-" , "_M_" ); + return S3; + } + + public String renameCell( final String oldCellName ) + throws CDLRenameException { + final String S0; + if( !libName.equals("") ) + S0 = libName + "." + oldCellName; + else + S0 = oldCellName; + final String S1 = S0.replaceAll( "-" , "_M_" ); + return S1 + "." + subType; + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException { + if (oldNodeName.equals(Vdd)) return "Vdd"; + else if (oldNodeName.equals(GND)) return "GND"; + return escape(nodePrefix + oldNodeName); + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException { + return escape(instancePrefix + oldDeviceName); + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException { + return escape(instancePrefix + oldInstanceName); + } + + public String renameTransistorModel( final String oldTransistorModel ) + throws CDLRenameException { + return oldTransistorModel; + } + + }; + + final CDLNameInterfaceFactory castLegalizingNIF = + new TrivialCDLNameInterfaceFactory(castLegalizingNI); + + /** + * Maps from CDL names to desired CAST names w/ subtypes + * if not in bind.rul uses guaranteed CAST legal names + **/ + final BindRulNameInterfaceFactory + cdlToCastNameInterfaceFactory = + new BindRulNameInterfaceFactory( inputBindRulReader, + castLegalizingNIF ); + + /** + * Maps from CDL names to desired layout names + * which are just cast names translated to cadence names + * This is what Cast2CDL will output, and thus + * is what we we'll LVS the layout against, so we want + * it to match + **/ + final CDLNameInterfaceFactory + cdlToDesiredLayoutNameInterfaceFactory = + new CompositeCDLNameInterfaceFactory + ( cdlToCastNameInterfaceFactory, + new TrivialCDLNameInterfaceFactory + ( new CadenceNameInterface(Collections.EMPTY_SET))); + + + final CDLNameInterfaceFactory identityNIF = + new TrivialCDLNameInterfaceFactory + ( new IdentityNameInterface() ); + + /** + * Maps from CDL names to existing layout names, with + * identity backstop. The cdlToLayoutInputBindRul will + * typically be from a .cxl file from running LVS + **/ + final CDLNameInterfaceFactory + cdlToExistingLayoutNameInterfaceFactory = + new BindRulNameInterfaceFactory + ( cdlToLayoutInputBindRulReader, + identityNIF ); + + /** + * Writes bind.rul from cdl -> layout names + **/ + final TableEmitterFactoryInterface + cdlToDesiredLayoutOutputBindRulEmitterFactory = + new AssuraBindRulTableEmitterFactory + ( cdlToDesiredLayoutOutputBindRulFile, + bindRulHeaderFile ); + + final CDLFactoryInterface bindRulFactory = + new GenerateGDSIIDataFactory + ( cdlToDesiredLayoutOutputBindRulEmitterFactory, + identityNIF, + cdlToDesiredLayoutNameInterfaceFactory ); + + /** + * Writes names.il table map from existing layout + * names to desired layout names + **/ + final TableEmitterFactoryInterface skillEmitterFactory = + new SkillTableEmitterFactory + ( outputSkillTableDir, + "CadenceNodeToGDSIINodeTable", + "CadenceCellToGDSIICellTable", + "CadenceInstanceToGDSIIInstanceTable" ); + + final CDLFactoryInterface oldToNewLayoutNameTableFactory = + new GenerateGDSIIDataFactory + ( skillEmitterFactory, + cdlToExistingLayoutNameInterfaceFactory, + cdlToDesiredLayoutNameInterfaceFactory ); + + /** + * Output names.il and bind.rul + **/ + final CDLFactoryInterface tableFactory = + new SplittingFactory( bindRulFactory, + oldToNewLayoutNameTableFactory); + /** + * Create the templates + **/ + final Map templates = new TreeMap(); + + final Template templateFactory = + new Template(templates); + + /** + * split different parameterizations of templates + * into new templates + **/ + final CDLFactoryInterface templateSplitterFactory = + new TemplateSplitterFactory(templateFactory) { + public void makeCall(HierName name, + String subName, + HierName[] args, + Map parameters, + Environment env) { + // don't specialize undefined subcircuits + if (templateFactory.containsTemplate(subName)) { + super.makeCall( + name, subName, args, parameters, env); + } else { + templateFactory.makeCall( + name, subName, args, parameters, env); + } + } + }; + + final AspiceCellAdapter aspicer; + final CDLFactoryInterface outputFactory; + if (skipPrsGeneration) { + aspicer = null; + outputFactory = templateSplitterFactory; + } else { + /** + * Also read CDL into AspiceCellAdapter -- AML + **/ + aspicer = new AspiceCellAdapter() { + public void makeCall(HierName name, + String subName, + HierName[] args, + Map parameters, + Environment env) { + if (templateFactory.containsTemplate(subName)) { + super.makeCall(name, subName, args, + parameters, env); + } + } + }; + // this is where we branch between outputs : + // aspice and templates + outputFactory = + new SplittingFactory( templateSplitterFactory, + aspicer ); + } + + final CDLFactoryInterface renamedOutputFactory = + new CDLRenameFactory(outputFactory, + cdlToCastNameInterfaceFactory); + + /** + * Make templates and tables + **/ + final CDLFactoryInterface splittingFactory = + new SplittingFactory( renamedOutputFactory, + tableFactory); + + final CDLFactoryInterface firstFactory = + new CDLScalingFactory( metersPerInputUnit, + metersPerInputUnit, + 1, + 1, + 1, + 1, + splittingFactory); + + ReadCDLIntoFactory.readCDL( sourceCDLReader, + firstFactory ); + + final CDL2Cast cdl2cast = new CDL2Cast(); + try { + cdl2cast.writeTemplates(templates, + aspicer, + outputCastCellsWriter, + outputSpecTreeDir, + outputCastTreeDir, + new String[] { refinementParent }, + allCells ); + outputCastCellsWriter.close(); + + } + catch(Exception e ) { + e.printStackTrace(); + } + } + else + System.out.println( "\"" + + inputBindRulFileName + + "\" is not a readable file." ); + } + else { + System.out.println( "\"" + + sourceCDLFileName + + "\" is not a readable file." ); + } + } + else { + usage(null); + } + } + + /** + * Get the subtype for a fqcn + * e.g. lib.buffer.half.BUF_1of4.0 -> 0 + **/ + public String getSubType(HierName fqcn) { + return fqcn.getSuffixString(); + } + + public String getCellModule(String fqcn) { + try { + final HierName hName = + HierName.makeHierName(fqcn,'.'); + return getCellModule(hName).getCadenceString(); + } catch(InvalidHierNameException e) { + throw new RuntimeException(e); + } + } + + /** + * Get the CAST name w/o subtype for a given fqcn + * e.g. lib.buffer.half.BUF_1of4.0 -> lib.buffer.half.BUF_1of4 + **/ + public HierName getCellModule(HierName fqcn) { + return fqcn.getParent(); + } + + /** + * Get the CAST library name for a given fqcn + * e.g. lib.buffer.half.BUF_1of4.0 -> lib.buffer.half + **/ + public HierName getLibName(HierName fqcn) { + return fqcn.getParent().getParent(); + } + + /** + * Get the CAST library module for a given fqcn + * e.g. lib.buffer.half.BUF_1of4 -> lib.buffer + **/ + public HierName getLibraryModule(HierName fqcn) { + return fqcn.getParent().getParent().getParent(); + } + + /** + * Write templates in cast format to spec tree and digital tree + **/ + public void writeTemplates( final Map templates, + final AspiceCellAdapter aspicer, + final Writer outputCastCellsWriter, + final File outputSpecTreeDir, + final File outputCastTreeDir, + final String[] refinementParents ) + throws Exception { + writeTemplates(templates, aspicer, outputCastCellsWriter, outputSpecTreeDir, + outputCastTreeDir, refinementParents, false); + } + + public void writeTemplates( final Map templates, + final AspiceCellAdapter aspicer, + final Writer outputCastCellsWriter, + final File outputSpecTreeDir, + final File outputCastTreeDir, + final String[] refinementParents, + final Boolean allCells ) + throws Exception { + + //determine which templates should be inlined. + //If a template contains both instantiation calls and + //components(R,C,M, etc), then all the calls in that template + //should be flattened to components so that the resulting + //cast cell has either a subcells block or a netlist block, not both. + + /** + * Set of leaf cells which have components. + **/ + final Set leafSet = new HashSet(); + + /** + * Set of cells which are instantiated somewhere. + * If a flattened cell is not instantiated, then it should not + * be output. + **/ + final Set instantiatedSet = new HashSet(); + + /** + * Set of cells that have components and subcells. + * These will be flattened, and the flattened cells + * automatically added to the templates + **/ + final Set flattenedSet = new HashSet(); + + /** + * map from cast file to writer + **/ + final Map digitalLibWriterMap = new HashMap(); + final Map emitterMap = new HashMap(); + final Set cellModuleDone = new HashSet(); + + for(Iterator i=templates.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry)i.next(); + final String fqcn = (String)entry.getKey(); + final Template template = (Template)entry.getValue(); + final TemplateContentSniffer sniffer = + new TemplateContentSniffer(template); + + outputCastCellsWriter.write(fqcn+"\n"); + final HierName hName = HierName.makeHierName(fqcn,'.'); + final HierName module = getLibraryModule(hName); + final HierName libName = getLibName(hName); + + /** + * if this is the first time we've seen this library + * open a writer to it and write the CAST Header + **/ + if(!digitalLibWriterMap.containsKey(libName) ) { + final Writer digitalLibWriter = + openFile( cellPath(outputCastTreeDir, module), + libName.getSuffixString() + ".cast" ); + digitalLibWriterMap.put(libName, digitalLibWriter); + writeCastFileHeader(digitalLibWriter); + digitalLibWriter.write("\n"); + digitalLibWriter.write("module " + + libName.getCadenceString() + ";\n"); + digitalLibWriter.write("\n"); + } + + template.execute( sniffer ); + if(sniffer.hasComponents() ) { + leafSet.add(template); + for(Iterator j = sniffer.getSubCells(); j.hasNext(); ) { + String cellName = (String)j.next(); + flattenedSet.add( templates.get( cellName ) ); + } + } + else { + for(Iterator j = sniffer.getSubCells(); j.hasNext(); ) { + String cellName = (String)j.next(); + instantiatedSet.add( templates.get( cellName ) ); + } + } + } + + CDLInlineFactory flatten = + new CDLInlineFactory(false, null, false); + flatten.addTargets(templates); + + for(Iterator i=templates.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry = (Map.Entry)i.next(); + String fqcn = (String)entry.getKey(); + Template template = (Template)entry.getValue(); + if ( ! allCells && flattenedSet.contains(template) && + !instantiatedSet.contains(template) ) + continue; + + final HierName hName = HierName.makeHierName(fqcn,'.'); + final HierName libName = getLibName(hName); + final HierName cellModule = getCellModule(hName); + final String subType = getSubType(hName); + + // get NetGraph if one exists + AspiceFile aspiceCell = + aspicer == null ? null : aspicer.getCell(fqcn); + NetGraph netgraph = null; + if (aspiceCell!=null) { + netgraph = new NetGraph(HierName.makeHierName("Vdd"), + HierName.makeHierName("GND")); + netgraph.addAspice(aspiceCell); + netgraph.prepareForLvs(); + } + + final Writer specWriter = + openFile( cellPath(outputSpecTreeDir, cellModule), + subType + ".cast" ); + final Writer digitalWriter = + (Writer) digitalLibWriterMap.get(libName); + + writeTemplateToSpecTree(hName, + template, + netgraph, + flatten, + leafSet.contains(template), + specWriter); + + specWriter.close(); + + //only add a cellModule once to digital library cast file + // and for gods sake, wait until we have prs for leaf cells + if(cellModuleDone.contains(cellModule)|| + ( leafSet.contains(template) && + aspicer != null && + aspiceCell == null ) ) continue; + cellModuleDone.add(cellModule); + + writeTemplateToCastTree(hName, + refinementParents, + template, + templates, + netgraph, + flatten, + leafSet.contains(template), + digitalWriter); + } + + /** + * Close all digital CAST library files + **/ + for(Iterator i=digitalLibWriterMap.entrySet().iterator(); + i.hasNext(); ) { + Map.Entry entry = (Map.Entry)i.next(); + Writer writer = (Writer)entry.getValue(); + writer.close(); + } + } + + /** + * When executed by a template, + * collects information about instantiations of subcells and components. + * Used to determine what ever to do with this template. e.g. if it has + * both components and calls, it will be flattened + **/ + private class TemplateContentSniffer extends CDLInterfaceSimplifier + { + private boolean bComponent = false; + private boolean bCall = false; + private Collection subCells = new HashSet(); + private final Template templ; + + TemplateContentSniffer(final Template templ) { + this.templ = templ; + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { + if (templ.containsTemplate(subName)) { + bCall = true; + subCells.add(subName); + } + } + public void makeResistor(HierName name, HierName n1, HierName n2, + double val) { + bComponent = true; + } + + public void makeCapacitor(HierName name, HierName npos, HierName nneg, + double val) { + bComponent = true; + } + + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w, double l) { + bComponent = true; + } + + public void makeDiode(HierName name, int type, HierName npos, + HierName nneg, double w, double l, double a, + double p) { + bComponent = true; + } + public void makeInductor(HierName name, HierName npos, HierName nneg, + double val) { + bComponent = true; + } + public void makeBipolar(HierName name, int type, HierName nc, + HierName nb, HierName ne, double a) { + bComponent = true; + } + public void beginSubcircuit(String subName, String[] in, String[] out) { + throw new AssertionFailure("Should not happen!"); + } + public void endSubcircuit(String subName) { + throw new AssertionFailure("Should not happen!"); + } + + public boolean hasSubCells() { return bCall; } + public Iterator getSubCells() { return subCells.iterator(); } + public boolean hasComponents() { return bComponent; } + } + + /** + * Writes all non-port nodes references in all statements in a template + * in CAST format. This will presumably be called before writing + * instantiations to the subcells block, as undefined nodes cannot be + * referenced by instantiations + **/ + private class CastLocalNodesDeclarationEmitter extends CDLInterfaceSimplifier + { + private final Collection nodes = new HashSet(); + private final Collection args = new HashSet(); + private final Writer w; + + public CastLocalNodesDeclarationEmitter(final Template template, + final Writer w) { + this.w = w; + final Pair p = template.getArguments(); + final String[] in = (String []) p.getFirst(); + final String[] out = (String []) p.getSecond(); + for(int i=0; iList if Integers in + * a bracket string + * e.g. + * [0][1] -> (0,1) + * [0,1] -> (0,1) + **/ + private final List parseBracketStr( final String bracketStr ) { + final int len = bracketStr.length(); + + final StringBuffer accum = new StringBuffer(); + + final List ret = new ArrayList(); + + boolean bracketOpen = false; + + for ( int i = 0 ; i < len ; ++i ) { + final char c = bracketStr.charAt( i ); + + switch ( c ) { + case '[': + if ( bracketOpen ) { + throw new RuntimeException( "\"" + + bracketStr + + "\" is not a valid array index string." ); + } + bracketOpen = true; + break; + case ']': + if ( ! bracketOpen ) { + throw new RuntimeException( "\"" + + bracketStr + + "\" is not a valid array index string." ); + } + bracketOpen = false; + + ret.add( new Integer( accum.toString() ) ); + accum.delete( 0, accum.length() ); + break; + case ',': + if ( ! bracketOpen ) { + throw new RuntimeException( "\"" + + bracketStr + + "\" is not a valid array index string." ); + } + ret.add( new Integer( accum.toString() ) ); + accum.delete( 0, accum.length() ); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + accum.append( c ); + break; + default: + throw new RuntimeException( "\"" + + bracketStr + + "\" is not a valid array index string." ); + } + } + return ret; + } + + /** + * Returns a Pair (stem, indices>) for a + * String + * e.g. + * a[0][1] -> (a,(0,1)) + * d -> (d,()) + **/ + private final Pair parsePortNodeName( final String portNodeName ) { + final int len = portNodeName.length(); + + final int indexOfFirstOpenBracket = portNodeName.indexOf( '[' ); + + final int indexOfLastCloseBracket = portNodeName.lastIndexOf( ']' ); + + + if ( ( ( indexOfFirstOpenBracket == -1 ) && + ( indexOfLastCloseBracket == -1 ) ) || + ( ( indexOfFirstOpenBracket > 0 ) && + ( indexOfLastCloseBracket > 0 ) && + ( indexOfLastCloseBracket == ( len - 1 ) ) && + ( ( indexOfFirstOpenBracket + 1 ) < indexOfLastCloseBracket ) ) ) { + if ( indexOfFirstOpenBracket != -1 ) { + final String stem = portNodeName.substring( 0, indexOfFirstOpenBracket ); + assert stem.length() > 0 ; + final String bracketStr = portNodeName.substring( indexOfFirstOpenBracket, indexOfLastCloseBracket + 1 ); + return new Pair( stem, parseBracketStr( bracketStr ) ); + } + else { + return new Pair( portNodeName, Collections.EMPTY_LIST ); + } + } + else { + throw new RuntimeException( "\"" + + portNodeName + + "\" is not a valid port name because a misplaced '[' or ']'." ); + } + } + + /** + * Given a List of ports, return + * a Pair of + * the Map is a Map> + * from stems to min/max ranges for each index of the array + * the Set is a Set + * of stems in order of first appearance + * So if ports = (b[0], a[0][0], a[0][1], a[1][0], a[1][1], d, DOG, b[1] ) + * returns + * ({a->((0,1),(0,1)), b->((0,1)), d->(), DOG->()}, {b,a,d,DOG}) + **/ + private Pair sniffArrays( final List ports /**/) { + final Map portMap = new HashMap(); /**/ + final Set portStems = new LinkedHashSet(); /* 0 ) { + dimensions = new ArrayList( indices.size() ); + final Iterator indexIter = indices.iterator(); + while ( indexIter.hasNext() ) { + final Integer index = ( Integer ) indexIter.next(); + final Pair minMaxPair = new Pair( index, index ); + dimensions.add( minMaxPair ); + } + } + else { + dimensions = Collections.EMPTY_LIST; + } + portMap.put( stem, dimensions ); + portStems.add( stem ); + } + else { + if ( indices.size() == existingPortDimensions.size() ) { + final Iterator indexIter = indices.iterator(); + final ListIterator dimensionIter = + existingPortDimensions.listIterator(); + while ( indexIter.hasNext() ) { + final Integer index = ( Integer ) indexIter.next(); + final Pair minMaxPair = ( Pair ) dimensionIter.next(); + + final Integer min = ( Integer ) minMaxPair.getFirst(); + final Integer max = ( Integer ) minMaxPair.getSecond(); + + assert min.intValue() <= max.intValue(); + + if ( index.intValue() < min.intValue() ) { + dimensionIter.set( new Pair( index, max ) ); + } + else if ( index.intValue() > max.intValue() ) { + dimensionIter.set( new Pair( min, index ) ); + } + } + + } + else { + throw new RuntimeException( "Can not change number of dimensions of \"" + stem + "\"." ); + } + } + } + + return new Pair( portMap, portStems ); + + } + + private static final Set IMPLIED_PORTS = + new LinkedHashSet(Arrays.asList(new Object[] { "Vdd", "GND" })); + + /** + * HACK to check for the nodes which are in the STD_CELL parent + * should really check the refinement parent + **/ + private boolean isImpliedPort(final String name) { + return IMPLIED_PORTS.contains(name); + } + + private void writeCellPorts(final Template template, + final NetGraph netgraph, + final Writer writer) + throws IOException { + writer.write("("); + final Pair p = template.getArguments(); + final String[] in = (String []) p.getFirst(); + final String[] out = (String []) p.getSecond(); + + final List ports = new ArrayList(); + for ( int i = 0 ; i < in.length ; ++i ) { + if (! isImpliedPort (in[i])) ports.add( in[i] ); + } + + for ( int i = 0 ; i < out.length ; ++i ) { + if (! isImpliedPort (out[i])) ports.add( out[i] ); + } + + final Pair portInfo = sniffArrays( ports ); + + final Map portMap = ( Map ) portInfo.getFirst(); + final Set portStems = ( Set ) portInfo.getSecond(); + + final Iterator stemIter = portStems.iterator(); + + if ( stemIter.hasNext() ) writer.write("node "); + + while ( stemIter.hasNext() ) { + final String stem = ( String ) stemIter.next(); + final List dimensions = ( List ) portMap.get( stem ); + String dir = "-+"; + if (netgraph!=null) { // infer directionality of port + NetGraph.NetNode node = + netgraph.findNetNode(HierName.makeHierName(stem)); + if ((node!=null) && node.isGate() && !node.isOutput()) dir = "-"; + if ((node!=null) && !node.isGate() && node.isOutput()) dir = "+"; + } + writer.write(dir + stem ); + if ( dimensions.size() > 0 ) { + final Iterator dimenIter = dimensions.iterator(); + writer.write( "[" ); + while ( dimenIter.hasNext() ) { + final Pair minMaxPair = ( Pair ) dimenIter.next(); + final Integer min = ( Integer ) minMaxPair.getFirst(); + final Integer max = ( Integer ) minMaxPair.getSecond(); + assert min.intValue() <= max.intValue(); + + writer.write( min.toString() + ".." + max.toString() ); + if ( dimenIter.hasNext() ) { + writer.write( ',' ); + } + } + writer.write( ']' ); + } + if ( stemIter.hasNext() ) { + writer.write( ", " ); + } + } + + writer.write(")"); + } + + /** + * writes the CAST cell declaration + * define "cell"(node b[0..1], + * node a[0..1,0..1], + * node d, + * node BAD) + * from the examples above + **/ + private void writeCellHeader(String cell, + String[] refinementParents, + Template template, + NetGraph netgraph, + Writer writer, + boolean elidePorts) + throws IOException { + writer.write("define \"" + cell + "\"()" ); + + if (!elidePorts) { + writeCellPorts(template, netgraph, writer); + } + + if (refinementParents.length > 0 ) { + writer.write(" <:"); + for(int i=0; i \n" ); + w.print(" " + subName + " " + name.getCadenceString() + ";\n" ); + } + } + + /** + * a CDLFactory executed by a template for a mid-level cell + * (with only instantiataions) to write a CAST digital definition. + * Just writes the instantiations + **/ + private class CastSubCellEmitter extends CDLFactoryAdaptor { + private PrintWriter w; + private Map templates; + private String subckt; + public CastSubCellEmitter(Map templates, Writer w ) { + this.templates = templates; + this.w = new PrintWriter(w); + this.subckt = ""; + } + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + subckt = subName; + } + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + Map implied = new HashMap(); + final List realargs; + + Template template = (Template) templates.get(subName); + if (template == null) { + System.out.println("Warning: SUBCKT " + subckt + + " instantiates unknown subcell " + + name.getAsString('.') + "/" + + subName); + realargs = Arrays.asList(args); + } else { + realargs = new ArrayList(); + final Pair p = template.getArguments(); + final String[] in = (String []) p.getFirst(); + final String[] out = (String []) p.getSecond(); + if (in.length + out.length != args.length) { + System.out.println("Warning: parameter mismatch in " + + "SUBCKT " + subckt + " instantiating " + + name.getAsString('.') + "/" + + subName); + } + + int argidx = 0; + for ( int i = 0 ; i < in.length && argidx < args.length; + ++i, ++argidx ) { + if (isImpliedPort (in[i])) { + implied.put( in[i], args[argidx] ); + } else { + realargs.add( args[argidx] ); + } + } + + for ( int i = 0 ; i < out.length && argidx < args.length; + ++i, ++argidx ) { + if (isImpliedPort (out[i])) { + implied.put( out[i], args[argidx] ); + } else { + realargs.add( args[argidx] ); + } + } + } + + String cellModule = getCellModule(subName); + w.print(cellModule + " " + name.getCadenceString() + "(" ); + for(Iterator realarg = realargs.iterator(); realarg.hasNext(); ) { + w.print(" " + ((HierName) realarg.next()).getCadenceString()); + if (realarg.hasNext()) w.print("," ); + } + w.print(")"); + + StringBuffer impliedPorts = new StringBuffer(); + boolean sameImplied = true; + for(Iterator i = IMPLIED_PORTS.iterator(); i.hasNext(); ) { + final String imp = (String) i.next(); + final HierName actual = implied.get(imp); + if (actual == null) { + impliedPorts.append(imp); + } else { + sameImplied &= imp.equals(actual.getAsString('.')); + impliedPorts.append(actual); + } + if (i.hasNext()) impliedPorts.append(","); + } + if (!sameImplied) { + w.print("(" + impliedPorts.toString() + ")"); + } + w.print(";\n"); + } + } + + + private void writeTemplateToSpecTree(final HierName fqcn, + final Template template, + final NetGraph netgraph, + final CDLInlineFactory flatten, + final boolean isLeaf, + final Writer writer) + throws IOException { + + final String subType = getSubType(fqcn); + final HierName cellModule = getCellModule(fqcn); + + final IndentWriter iw = new IndentWriter(writer); + + writeCastFileHeader(iw); + iw.write("\n"); + iw.write("module " + cellModule.getCadenceString() + ";\n"); + iw.write("\n"); + writeCellHeader(subType, + new String[] {cellModule.getCadenceString()}, + template, + netgraph, + iw, + true); + iw.write("{\n"); + iw.nextLevel(); + + if(!isLeaf) { + iw.write("subtypes {\n"); + iw.nextLevel(); + + final CDLFactoryInterface emitter = new CastSubTypeEmitter(iw); + template.execute(emitter); + + iw.prevLevel(); + iw.write("}\n"); + } + iw.prevLevel(); + iw.write("}\n"); + } + + private void writeTemplateToCastTree(final HierName fqcn, + final String[] refinementParents, + final Template template, + final Map templates, + final NetGraph netgraph, + final CDLInlineFactory flatten, + final boolean isLeaf, + final Writer writer) + throws IOException { + + final IndentWriter iw = new IndentWriter(writer); + + final HierName cellModule = getCellModule(fqcn); + + writeCellHeader(cellModule.getSuffixString(), + refinementParents, + template, + netgraph, + iw, + false); + + iw.write("{\n"); + iw.nextLevel(); + + if (!isLeaf) { + // write subcells body + iw.write("subcells {\n"); + iw.nextLevel(); + + final CDLFactoryInterface nodeEmitter = + new CastLocalNodesDeclarationEmitter(template, iw); + template.execute(nodeEmitter); + + final CDLFactoryInterface emitter = + new CastSubCellEmitter(templates, iw); + template.execute(emitter); + + iw.prevLevel(); + iw.write("}\n"); + } + else if (netgraph!=null) { + ProductionRuleSet prs = netgraph.getProductionRuleSet(); + if (prs.size()>0) { + iw.write("prs {\n"); + iw.nextLevel(); + for (Iterator i = netgraph.getNodes().iterator(); i.hasNext(); ) { + NetGraph.NetNode node = (NetGraph.NetNode) i.next(); + if (!node.isPort() && !node.isStaticizerInverter() && + (node.isGate() || node.isOutput())) + iw.write("node \"" + node.name + "\";\n"); + } + iw.write(prs.toString()); + iw.prevLevel(); + iw.write("}\n"); + } + iw.write("netlist {\n"); + iw.nextLevel(); + final CDLFactoryInterface emitter = + new CDLFactoryEmitter(iw, true, 999, true, true) { + public void makeCall(HierName name, + String subName, + HierName[] args, + Map parameters, + Environment env) { + if (template.containsTemplate(subName)) { + // flatten through + flatten.makeCall(name, subName, args, + parameters, env); + } else { + // emit reference to undefined subcircuit as is + super.makeCall(name, subName, args, + parameters, env); + } + } + }; + flatten.setProxy(emitter); + template.execute(flatten); + iw.prevLevel(); + iw.write("}\n"); + } + iw.prevLevel(); + iw.write("}\n\n"); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/cdl2cast.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/cdl2cast.package new file mode 100644 index 0000000000..d7f3d9b62e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/cdl2cast.package @@ -0,0 +1,8 @@ +2 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.tools.cdl2cast.CDL2Cast +$arch/bin/cdl2cast.sh cdl2cast.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/custom.mk new file mode 100644 index 0000000000..081f05c1b9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2cast/custom.mk @@ -0,0 +1,9 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id: //depot/sw/cad/java/main/src/com/avlsi/tools/cast2skill/custom.mk#2 $ +# $DateTime: 2003/02/18 08:19:59 $ +# $Author: chrisb $ +CURR_RESULT_FILES := $(CURR_TARGET_DIR)/cdl2cast.sh $(CURR_RESULT_FILES) + +$(CURR_TARGET_DIR)/cdl2cast.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.cdl2cast.CDL2Cast/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2Skill.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2Skill.java new file mode 100644 index 0000000000..5079c838c7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2Skill.java @@ -0,0 +1,189 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cdl2skill; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.BufferedReader; +import java.io.BufferedWriter; + + + +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; +import java.util.HashMap; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +import com.avlsi.file.cdl.parser.ReadCDLIntoFactory; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.SplittingFactory; + +import com.avlsi.tools.cdl2skill.CDL2SkillFactory; +import com.avlsi.tools.jauto.TechnologyData; + +public class CDL2Skill { + + private static void usage( ) { + + final String className = CDL2Skill.class.getName(); + + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className + "\n" + + " --cdl-file=file\n" + + " --output-dir=dir\n" + + " [ --library-list=file ]\n" + + " [ --cell-list=file ]\n" ); + } + + public static void main( String[] args ) throws Exception { + + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + final String cdlFileName = theArgs.getArgValue( "cdl-file", null ); + final String outputDirName = theArgs.getArgValue( "output-dir", null ); + final String libListFileName = theArgs.getArgValue( "library-list", null ); + final String cellListFileName = theArgs.getArgValue( "cell-list", null ); + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + CDL2Skill.class)); + } + + final TechnologyData techData; + try { + techData = TechnologyData.getTechnologyData(theArgs); + } catch (Exception e) { + System.err.println("Can't load technology data: " + e.getMessage()); + System.exit(1); + } + + + if ( ( cdlFileName != null ) && + ( outputDirName != null ) + ) { + + final File cdlFile = new File( cdlFileName ); + final File outputDir = new File( outputDirName ); + + if ( ! ( outputDir.exists() ) ) { + outputDir.mkdirs(); + } + + if ( ( cdlFile.isFile() ) && + ( cdlFile.canRead() ) && + ( outputDir.isDirectory() ) && + ( outputDir.canWrite() ) ) { + + final InputStream cdlInputStream = + new FileInputStream( cdlFile ); + final Reader cdlReader = + new BufferedReader( new InputStreamReader( cdlInputStream, "UTF-8" ) ); + + final Map cellTemplateMap = new HashMap(); + final Template templateFactory = new Template( cellTemplateMap, cdlFileName ); + + + final Map cellStatMap = new HashMap(); + final Set libSet = new HashSet(); + final List cellList = new LinkedList(); + final CDL2SkillFactory skillFactory = + new CDL2SkillFactory( outputDir, + "NetListTable", + libSet, + cellList, + cellTemplateMap, + cellStatMap, + techData ); + + final CDLFactoryInterface factory = new SplittingFactory( templateFactory, + skillFactory ); + + ReadCDLIntoFactory.readCDL( cdlReader, factory ); + + if ( skillFactory.getError() != null ) { + throw skillFactory.getError(); + } + + if ( libListFileName != null ) { + final OutputStream outStream = new FileOutputStream( libListFileName ); + final Writer outWriter = + new BufferedWriter( new OutputStreamWriter( outStream, "UTF-8" ) ); + + final Iterator i = libSet.iterator(); + while ( i.hasNext() ) { + final String currLibName = ( String ) i.next(); + outWriter.write( currLibName + "\n" ); + } + outWriter.close(); + } + + if ( cellListFileName != null ) { + final OutputStream outStream = new FileOutputStream( cellListFileName ); + final Writer outWriter = + new BufferedWriter( new OutputStreamWriter( outStream, "UTF-8" ) ); + + final Iterator i = cellList.iterator(); + while ( i.hasNext() ) { + final String currCellName = ( String ) i.next(); + outWriter.write( currCellName + "\n" ); + } + outWriter.close(); + } + + } + + } + else { + if ( cdlFileName == null ) { + System.out.println( "You must specify a cdl file to convert to skill." ); + } + if ( outputDirName == null ) { + System.out.println( "You must specify an output directory." ); + } + usage(); + } + + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillException.java new file mode 100644 index 0000000000..8deed92423 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillException.java @@ -0,0 +1,19 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cdl2skill; + + +public class CDL2SkillException extends Exception { + public CDL2SkillException( final String errorStr, final Exception cause ) { + super( errorStr, cause ); + } + + public CDL2SkillException( final String errorStr ) { + super( errorStr ); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillFactory.java new file mode 100644 index 0000000000..c17200f51d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cdl2skill/CDL2SkillFactory.java @@ -0,0 +1,745 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cdl2skill; + + +import java.util.Map; +import java.util.Set; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +import java.text.MessageFormat; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.BufferedWriter; +import java.io.Writer; +import java.io.IOException; +import java.io.FileNotFoundException; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.common.HierName; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLstat; + +import com.avlsi.tools.cdl2skill.CDL2SkillException; +import com.avlsi.tools.jauto.TechnologyData; + +public class CDL2SkillFactory implements CDLFactoryInterface { + + private final MessageFormat headerFormatter; + private final MessageFormat makeInstanceFormatter; + private final MessageFormat makeConnectionFormatter; + private final MessageFormat makeInstanceParameterFormatter; + private final MessageFormat makeNetFormatter; + private final MessageFormat makeTerminalFormatter; + private final MessageFormat makeStatisticsFormatter; + + private final StringBuffer accumulator; + + private final File mOutputDir; + + private final Set mLibSet; + private final List mCellList; + + private final Map mCellTemplateMap; + private final Map mCellStatMap; + + //Nets that have already been written. + private final Set mWrittenNets; + + //Map from cell name to list of ports. + private final Map mCellPorts; + + private Writer mCurrWriter; + + private String mCurrCellName; + + private CDL2SkillException mError; + + private final TechnologyData mTechData; + + public CDL2SkillFactory( final File outputDir, + final String skillFunctionPrefix, + final String skillTableName, + final Set libSet, + final List cellList, + final Map cellTemplateMap, + final Map cellStatMap, + final TechnologyData techData ) { + + // Cell name, Library name + final String headerFormatStr = + "( setq\n" + + " " + skillTableName + "\n" + + " ( " + skillFunctionPrefix + "CreateEmptyNetlistTable\n" + + " \"{1}\"\n" + + " \"{0}\" ) )\n" ; + + // Instance name, Cell Name of master of instance, Library Name of master of instance + final String makeInstanceFormatStr = + "( " + skillFunctionPrefix + "CreateInstanceInNetlist\n" + + " " + skillTableName + "\n" + + " \"{0}\"\n" + + " {2}\n" + + " \"{1}\" )\n"; + + // Instance Name, Terminal Name, Net Name + final String makeConnectionFormatStr = + "( " + skillFunctionPrefix + "AddConnectionToInstanceInNetlist\n" + + " " + skillTableName + "\n" + + " \"{0}\"\n" + + " \"{1}\"\n" + + " \"{2}\" )\n"; + + // Instance Name, Parameter name, Parameter value + final String makeInstanceParameterFormatStr = + "( " + skillFunctionPrefix + "AddParameterToInstanceInNetlist\n" + + " " + skillTableName + "\n" + + " \"{0}\"\n" + + " \"{1}\"\n" + + " {2} )\n"; + + // Net name + final String makeNetFormatStr = + "( " + skillFunctionPrefix + "AddNet\n" + + " " + skillTableName + "\n" + + " \"{0}\" )\n"; + + // Net name + final String makeTerminalFormatStr = + "( " + skillFunctionPrefix + "AddTerminal\n" + + " " + skillTableName + "\n" + + " \"{0}\" )\n"; + + + // Transistor Count, Area, Width, Length + final String makeStatisticsFormatStr = + "( " + skillFunctionPrefix + "SetTotalTransistorCount\n" + + " " + skillTableName + "\n" + + " {0,number,#############} )\n" + + "( " + skillFunctionPrefix + "SetTotalTransistorGateArea\n" + + " " + skillTableName + "\n" + + " {1,number,0.0000E0} )\n" + + "( " + skillFunctionPrefix + "SetTotalTransistorWidth\n" + + " " + skillTableName + "\n" + + " {2,number,0.0000E0} )\n" + + "( " + skillFunctionPrefix + "SetTotalTransistorLength\n" + + " " + skillTableName + "\n" + + " {3,number,0.0000E0} )\n"; + + headerFormatter = new MessageFormat( headerFormatStr ); + makeInstanceFormatter = new MessageFormat( makeInstanceFormatStr ); + makeConnectionFormatter = new MessageFormat( makeConnectionFormatStr ); + makeNetFormatter = new MessageFormat( makeNetFormatStr ); + makeTerminalFormatter = new MessageFormat( makeTerminalFormatStr ); + makeInstanceParameterFormatter = new MessageFormat( makeInstanceParameterFormatStr ); + makeStatisticsFormatter = new MessageFormat( makeStatisticsFormatStr ); + + accumulator = new StringBuffer(); + + mOutputDir = outputDir; + + mLibSet = libSet; + mCellList = cellList; + + mCellTemplateMap = cellTemplateMap; + mCellStatMap = cellStatMap; + + mWrittenNets = new HashSet( ); + + mCellPorts = new HashMap(); + + mCurrWriter = null; + mCurrCellName = null; + mError = null; + mTechData = techData; + } + + private String getLibNameFromCellName( final String cellName ) throws CDL2SkillException { + final int lastDot = cellName.lastIndexOf( '.' ); + if ( lastDot > 0 ) { + final int secondToLastDot = cellName.lastIndexOf( '.', lastDot - 1 ); + if ( secondToLastDot > 0 ) { + return cellName.substring( 0, secondToLastDot ); + } + } + throw new CDL2SkillException( "\"" + cellName + "\" is not a valid cell name." ); + } + + private void writeString( final String str ) { + if ( mError == null ) { + try { + mCurrWriter.write( str ); + } + catch ( IOException e ) { + mError = new CDL2SkillException( "Unable to write \"" + str + "\" to writer.", e ); + } + } + } + + private String makeHeaderStr( final String cellName ) throws CDL2SkillException { + + final String libName = getLibNameFromCellName( cellName ); + + // Cell Name, Library Name + final Object[] headerParams = { + cellName, + libName + }; + + headerFormatter.format( headerParams, accumulator, null ); + + final String ret = accumulator.toString(); + + accumulator.setLength( 0 ); + + return ret; + + } + + private void writeHeader( final String cellName ) { + try { + writeString( makeHeaderStr( cellName ) ); + } + catch ( CDL2SkillException e ) { + mError = e; + } + } + + private String makeInstanceStr( final String instanceName, + final String masterLibName, + final String masterCellName ) { + return makeInstanceStr(instanceName, + masterLibName, + masterCellName, + true); + } + + private String makeInstanceStr( final String instanceName, + final String masterLibName, + final String masterCellName, + final boolean quote) { + final Object[] instanceParams = { + instanceName, + masterCellName, + quote?"\"" + masterLibName + "\"" : masterLibName + }; + + makeInstanceFormatter.format( instanceParams, accumulator, null ); + + final String ret = accumulator.toString(); + + accumulator.setLength( 0 ); + + return ret; + + } + + private String makeInstanceStr( final String instanceName, + final String masterCellName ) throws CDL2SkillException { + final String masterLibName = getLibNameFromCellName( masterCellName ); + return makeInstanceStr( instanceName, + masterLibName, + masterCellName ); + } + + private void writeInstance( final String instanceName, + final String masterLibName, + final String masterCellName) { + writeInstance(instanceName, + masterLibName, + masterCellName, + true); + } + + private void writeInstance( final String instanceName, + final String masterLibName, + final String masterCellName, + final boolean quote) { + writeString( makeInstanceStr( instanceName, + masterLibName, + masterCellName, + quote) ); + } + + private void writeInstance( final String instanceName, + final String masterCellName ) { + try { + writeString( makeInstanceStr( instanceName, masterCellName ) ); + } + catch ( CDL2SkillException e ) { + mError = e; + } + } + + private String makeConnectionStr( final String instanceName, + final String terminalName, + final String netName ) { + final Object[] connectionParams = { + instanceName, + terminalName, + netName + }; + + makeConnectionFormatter.format( connectionParams, accumulator, null ); + + final String ret = accumulator.toString(); + + accumulator.setLength( 0 ); + + return ret; + + } + + private void writeConnection( final String instanceName, + final String terminalName, + final String netName ) { + writeString( makeConnectionStr( instanceName, terminalName, netName ) ); + } + + private String makeInstanceParameterStr( final String instanceName, + final String parameterName, + final String parameterValue ) { + final Object[] instanceParameterParams = { + instanceName, + parameterName, + parameterValue + }; + + makeInstanceParameterFormatter.format( instanceParameterParams, accumulator, null ); + + final String ret = accumulator.toString(); + + accumulator.setLength( 0 ); + + return ret; + + } + + private void writeInstanceParameter( final String instanceName, + final String parameterName, + final String parameterValue ) { + writeString( makeInstanceParameterStr( instanceName, + parameterName, + parameterValue ) ); + } + + private String makeNetStr( final String netName ) { + final Object[] netParams = { + netName + }; + + makeNetFormatter.format( netParams, accumulator, null ); + + final String ret = accumulator.toString(); + + accumulator.setLength( 0 ); + + return ret; + + } + + private void writeNet( final String netName ) { + if ( ! ( mWrittenNets.contains( netName ) ) ) { + mWrittenNets.add( netName ); + writeString( makeNetStr( netName ) ); + } + } + + private String makeTerminalStr( final String terminalName ) { + final Object[] terminalParams = { + terminalName + }; + makeTerminalFormatter.format( terminalParams, accumulator, null ); + + final String ret = accumulator.toString(); + + accumulator.setLength( 0 ); + + return ret; + + } + + private void writeTerminal( final String terminalName ) { + if ( ! ( mWrittenNets.contains( terminalName ) ) ) { + mWrittenNets.add( terminalName ); + writeString( makeTerminalStr( terminalName ) ); + } + } + + private String makeStatisticsString( final String cellName ) { + final CDLstat.CellStat stat = CDLstat.getCellStat( cellName, + mCellTemplateMap, + mCellStatMap, + null, + mTechData + ); + return makeStatisticsString( cellName, stat ); + } + + /** + * Override to provide statistical information about the cell specified by + * cellName. + **/ + protected String makeStatisticsString( final String cellName, + final CDLstat.CellStat stat ) { + final Object statParams[] = { + new Integer( stat.transistors ), + new Double( stat.area ), + new Double( stat.width ), + new Double( stat.length ) + }; + + makeStatisticsFormatter.format( statParams, accumulator, null ); + + final String ret = accumulator.toString(); + + accumulator.setLength( 0 ); + return ret; + } + + private void writeStatistics( final String cellName ) { + + writeString( makeStatisticsString( cellName ) ); + + } + + public void makeResistor( final HierName name, + final HierName n1, + final HierName n2, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + //dummy implementation...errors will occur in skill if used + if ( mError == null ) { + final String instanceName = name.toString(); + + final String ns1 = n1.toString(); + final String ns2 = n2.toString(); + + writeNet( ns1 ); + writeNet( ns2 ); + + writeInstance( instanceName, "", "" ); + + writeConnection( instanceName, "", ns1 ); + writeConnection( instanceName, "", ns2 ); + + final Double rVal = val.getValue( env ); + + writeInstanceParameter( instanceName, + "", + rVal.toString() ); + } + } + + public void makeCapacitor( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + //dummy implementation...errors will occur in skill if used + if ( mError == null ) { + final String instanceName = name.toString(); + + final String pos = npos.toString(); + final String neg = nneg.toString(); + + writeNet( pos ); + writeNet( neg ); + + writeInstance( instanceName, "", "" ); + + writeConnection( instanceName, "", pos ); + writeConnection( instanceName, "", neg ); + + final Double cVal = val.getValue( env ); + + writeInstanceParameter( instanceName, + "", + cVal.toString() ); + } + } + + public void makeTransistor( final HierName name, + final String type, + final HierName ns, + final HierName nd, + final HierName ng, + final HierName nb, + final CDLLexer.InfoToken w, + final CDLLexer.InfoToken l, + final Map parameters, + final Environment env ) { + if ( mError == null ) { + + final String instanceName = name.toString(); + + final String source = ns.toString(); + final String drain = nd.toString(); + final String gate = ng.toString(); + final String bulk = nb.toString(); + + final Double wVal = w.getValue( env ); + final Double lVal = l.getValue( env ); + + if ( ( wVal != null ) && ( lVal != null ) ) { + writeNet( source ); + writeNet( drain ); + writeNet( gate ); + writeNet( bulk ); + + writeInstance( instanceName, "TransistorLibrary", type, false ); + + writeConnection( instanceName, "S", source ); + writeConnection( instanceName, "D", drain ); + writeConnection( instanceName, "G", gate ); + writeConnection( instanceName, "B", bulk ); + + writeInstanceParameter( instanceName, + "w", + wVal.toString() ); + writeInstanceParameter( instanceName, + "l", + lVal.toString() ); + } + else { + mError = new CDL2SkillException( "\"" + + mCurrCellName + + "\": \"" + + w.getText( env ) + + "\" is not a valid transistor width." ); + } + } + } + + public void makeDiode( final HierName name, + final String type, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { + //dummy implementation...errors will occur in skill if used + if ( mError == null ) { + final String instanceName = name.toString(); + + final String pos = npos.toString(); + final String neg = nneg.toString(); + + writeNet( pos ); + writeNet( neg ); + + writeInstance( instanceName, "", "" ); + + writeConnection( instanceName, "", pos ); + writeConnection( instanceName, "", neg ); + + final Double dVal = val.getValue( env ); + + writeInstanceParameter( instanceName, + "", + dVal.toString() ); + } + } + + public void makeInductor( final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env ) { + if ( mError == null ) { + mError = new CDL2SkillException( "\"" + mCurrCellName + "\": Inductors are not supported." ); + } + } + + public void makeBipolar( final HierName name, + final String type, + final HierName nc, + final HierName nb, + final HierName ne, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { + if ( mError == null ) { + final String instanceName = name.toString(); + + final String snc = nc.toString(); + final String snb = nb.toString(); + final String sne = ne.toString(); + + writeNet( snc ); + writeNet( snb ); + writeNet( sne ); + + writeInstance( instanceName, "", "" ); + + writeConnection( instanceName, "", snc ); + writeConnection( instanceName, "", snb ); + writeConnection( instanceName, "", sne ); + + final Double dVal = val.getValue( env ); + + writeInstanceParameter( instanceName, + "", + dVal.toString() ); + } + } + + public void makeCall( final HierName name, + final String subName, + final HierName[] args, + final Map parameters, + final Environment env ) { + if ( mError == null ) { + final String instanceName = name.toString(); + final String[] terminalNames = ( String[] ) mCellPorts.get( subName ); + if ( terminalNames != null ) { + if ( terminalNames.length == args.length ) { + int i; + for ( i = 0 ; i < args.length ; ++i ) { + writeNet( args[i].toString() ); + } + + writeInstance( instanceName, + subName ); + + final Iterator paramIter = parameters.entrySet().iterator(); + + while ( paramIter.hasNext() ) { + final Map.Entry currEntry = ( Map.Entry ) paramIter.next(); + + final String currParamName = ( String ) currEntry.getKey(); + final String currParamValue = + ( ( CDLLexer.InfoToken ) currEntry.getValue() ).getText(); + writeInstanceParameter( instanceName, + currParamName, + "\"" + currParamValue + "\"" ); + } + + for ( i = 0 ; i < args.length ; ++i ) { + writeConnection( instanceName, terminalNames[i], args[i].toString() ); + } + } + } + else { + mError = new CDL2SkillException( "\"" + + mCurrCellName + + "\": Unable to find port list for \"" + + subName + + "\"." ); + } + } + } + + private void doPorts( final String cellName, + final String[] in, + final String[] out ) { + final String[] terminals = new String[ in.length + out.length ]; + int destIndex = 0; + + int i; + for ( i = 0 ; i < in.length ; ++i ) { + terminals[destIndex] = in[i]; + ++destIndex; + } + + for ( i = 0 ; i < out.length ; ++i ) { + terminals[destIndex] = out[i]; + ++destIndex; + } + + mCellPorts.put( cellName, terminals ); + + for ( i = 0 ; i < terminals.length ; ++i ) { + writeTerminal( terminals[i] ); + } + } + + private void addCellToSets( final String cellName ) { + if ( mError == null ) { + try { + final String libName = getLibNameFromCellName( cellName ); + mLibSet.add( libName ); + mCellList.add( cellName ); + } + catch ( CDL2SkillException e ) { + mError = e; + } + } + } + + public void beginSubcircuit( final String subName, + final String[] in, + final String[] out, + final Map parameters, + final Environment env ) { + + if ( mError == null ) { + + final File skillFile = new File( mOutputDir, subName + ".netlist.il" ); + try { + final OutputStream outputStream = new FileOutputStream( skillFile ); + mCurrWriter = new BufferedWriter( new OutputStreamWriter( outputStream, "UTF-8" ) ); + + mCurrCellName = subName; + + writeHeader( subName ); + doPorts( subName, in, out ); + + addCellToSets( subName ); + + } + catch ( FileNotFoundException e ) { + mError = new CDL2SkillException( "Unable to open " + + skillFile.toString() + + ".", + e ); + } + catch ( IOException e ) { + mError = new CDL2SkillException( "Unable to open " + + skillFile.toString() + + ".", + e ); + } + } + } + + public void endSubcircuit( final String subName, final Environment env) { + + if ( mError == null ) { + try { + + writeStatistics( subName ); + + mCurrWriter.close(); + mCurrWriter = null; + mCurrCellName = null; + mWrittenNets.clear(); + } + catch( IOException e ) { + mError = new CDL2SkillException( "Unable to close the writer.", e ); + } + } + } + + public CDL2SkillException getError() { + return mError; + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cell/CellConstants.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cell/CellConstants.java new file mode 100644 index 0000000000..6a5b94bed9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cell/CellConstants.java @@ -0,0 +1,105 @@ +package com.avlsi.tools.cell; + +import antlr.collections.AST; +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.impl.ASTWithInfo; +import com.avlsi.cast.impl.CastParserEnvironment; +import com.avlsi.cast.impl.CastTreeParserInterface; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.EnvironmentEntry; +import com.avlsi.cast.impl.EnvironmentEntryIterator; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast.impl.UserDefinedValue; +import com.avlsi.cast.impl.SemanticWrapperException; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.TupleValue; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.impl.CastTwoParser; +import com.avlsi.cast2.impl.CastTwoTreeParser; +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.common.HierName; + +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +/** + * A class to access cell level constants. + **/ +public class CellConstants { + private final CastParserEnvironment cpe; + + public CellConstants(final CastParserEnvironment cpe) { + this.cpe = cpe; + } + + public CellConstants(final CastFileParser cpe) { + this(cpe.getParserEnvironment()); + } + + /** + * Return the top level constants accessible in the specified cell. + * + * @param cellName cell to get constants for + * @return constants and their values represented as key value pairs + **/ + public Environment getTopLevelConstants(final String cellName) + throws RecognitionException, TokenStreamException { + final Environment env = NullEnvironment.getInstance(); + final CellInterface ci = cpe.getCell(env, cellName, null, null); + + final String type = ci.getFullyQualifiedType(); + final CastTreeParserInterface parser = cpe.getTreeParser(); + parser.setCastParserEnvironment(cpe); + // XXX: assumes CASTv2 + final UserDefinedValue udv = (UserDefinedValue) + ((CastTwoTreeParser) parser).getFullyQualifiedCellValue( + Symbol.create(CellUtils.getBaseType(type)), + env, new ASTWithInfo()); + + final CastTwoParser castParser = + CastTwoParser.getParser(cellName, 0, 0, ""); + castParser.cellType(); + final AST ast = castParser.getAST(); + final AST metas = ast.getFirstChild().getNextSibling(); + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + final TupleValue tv; + if (metas == null) { + tv = new TupleValue(new Value[0]); + } else { + tv = treeParser.expressionList(metas, env, false); + } + + return udv.getCellConstants(tv); + } + + public static void main(final String args[]) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + final String castPath = theArgs.getArgValue("cast-path", "."); + final String cellName = theArgs.getArgValue("cell", null); + final CastFileParser castParser = + new CastFileParser(new FileSearchPath(castPath), "2"); + final CellConstants consts = new CellConstants(castParser); + for (EnvironmentEntryIterator i = + consts.getTopLevelConstants(cellName).entryIterator(); + i.hasNext(); ) { + final EnvironmentEntry entry = i.next(); + System.out.println(entry.getName() + " = " + entry.getValue()); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/.empty b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/.empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CSPCoSimInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CSPCoSimInfo.java new file mode 100644 index 0000000000..2ee2855a2f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CSPCoSimInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id: //depot/sw/cad/java/main/src/com/avlsi/tools/cosim/CoSimInfo.java#5 $ + * $DateTime: 2002/02/23 11:33:05 $ + * $Author: chrisb $ + */ + +package com.avlsi.tools.cosim; + +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; + +/** + * Extends CoSimInfo to contain information specific to the csp block. + * Doesn't do much yet. + **/ +public class CSPCoSimInfo extends CoSimInfo { + private CellInterface parent = null; + + public CSPCoSimInfo() { + super(); + } + + public ChannelDictionary createChannels(final String cellName, + final CellInterface cell, + final ChannelFactoryInterface + chanFactory, + final NodeFactoryInterface + nodeFactory) { + parent = cell; + final ChannelDictionary cdict = + super.createChannels(cellName, cell, chanFactory, nodeFactory); + parent = null; + return cdict; + } + + public void addChannelInfo(final String name, final int slack, + final int latency, final int cycle_time, + final int N, final int M, + final boolean isArrayed) { + if (parent == null) { + super.addChannelInfo(name, slack, latency, cycle_time, N, M, + isArrayed); + } else { + final ChannelTimingInfo cti = + DirectiveUtils.getTiming(parent, name); + //System.err.println("CSP channel: " + parent.getFullyQualifiedType() + " " + name + " " + cti.getSlack() + " " + cti.getLatency() + " " + cti.getCycleTime()); + super.addChannelInfo(name, cti, N, M, isArrayed); + } + } + + protected boolean usePorts() { return true; } + + public String toString() { + return "CSPCoSimInfo with input channels: " + inputChannels + " and output channels: " + outputChannels; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelDictionary.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelDictionary.java new file mode 100644 index 0000000000..8148373458 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelDictionary.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +import java.util.Hashtable; +import java.util.HashMap; +import java.util.Map; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.WideNode; + + +public class ChannelDictionary { + private Hashtable inChannelTable; + private Hashtable outChannelTable; + private Map nodeMap; + + public ChannelDictionary() { + inChannelTable = new Hashtable(); + outChannelTable = new Hashtable(); + nodeMap = new HashMap(); + } + + public void addInputChan(String name, ChannelInput chan) { + inChannelTable.put(name, chan); + } + + /** Returns null if not found. **/ + public ChannelInput getInputChan(String name) { + return (ChannelInput) inChannelTable.get(name); + } + + public void addOutputChan(String name, ChannelOutput chan) { + outChannelTable.put(name, chan); + } + + /** Returns null if not found. **/ + public ChannelOutput getOutputChan(String name) { + return (ChannelOutput) outChannelTable.get(name); + } + + public void addWideNode(String name, WideNode node) { + nodeMap.put(name, node); + } + + public WideNode getWideNode(String name) { + return (WideNode) nodeMap.get(name); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelFactoryInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelFactoryInterface.java new file mode 100644 index 0000000000..d7143d2020 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelFactoryInterface.java @@ -0,0 +1,53 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.cosim; + +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.ChannelOutput; + +/** + * Factory to create input and output channels. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +public interface ChannelFactoryInterface { + + /** + * Creates an input channel. + * + *
    
    +     *   public normal_behavior
    +     *     requires radix >= 2;
    +     *     requires width >= 1;
    +     *     requires slack >= 0;
    +     *     requires latency >= 0;
    +     *     requires cycle_time >= 0;
    +     * 
    + **/ + ChannelInput makeInputChannel(String name, + int radix, + int width, + ChannelTimingInfo cti); + + /** + * Creates an output channel. + * + *
    
    +     *   public normal_behavior
    +     *     requires radix >= 2;
    +     *     requires width >= 1;
    +     *     requires slack >= 0;
    +     *     requires latency >= 0;
    +     *     requires cycle_time >= 0;
    +     * 
    + **/ + ChannelOutput makeOutputChannel(String name, + int radix, + int width, + ChannelTimingInfo cti); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelParameterDict.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelParameterDict.java new file mode 100644 index 0000000000..9e6c1f1aa0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelParameterDict.java @@ -0,0 +1,116 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +import java.util.Hashtable; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.WideNode; +import com.avlsi.tools.tsim.IllegalSlackException; +import com.avlsi.tools.tsim.NoSuchNodeException; + +final class ChannelParameterDict { + + private final class Parameter { + private final String name; + private final ChannelTimingInfo cti; + private final int N; // wires per enable (e1ofN) + private final int M; // # e1ofN bundles per channel + + public Parameter(final String name, final ChannelTimingInfo cti, + final int N, final int M) { + this.name = name; + this.cti = cti; + this.N = N; + this.M = M; + } + + /** + * @throws IllegalSlackException If slack is negative. + * @throws NoSuchNodeException If a node in the channel could not be + * found. + **/ + public ChannelInput makeInputChannel( + final String nodenm, + final ChannelFactoryInterface factory) { + return factory.makeInputChannel(nodenm, N, M, cti); + } + + /** + * @throws IllegalSlackException If slack is negative. + * @throws NoSuchNodeException If a node in the channel could not be + * found. + **/ + public ChannelOutput makeOutputChannel( + final String nodenm, + final ChannelFactoryInterface factory) { + return factory.makeOutputChannel(nodenm, N, M, cti); + } + } + + private final Hashtable channelParameters; + private final Hashtable nodeParameters; + + public ChannelParameterDict() { + channelParameters = new Hashtable(); + nodeParameters = new Hashtable(); + } + + public void addChannelParameters(final String name, + final ChannelTimingInfo cti, + final int N, final int M) { + channelParameters.put(name, new Parameter(name, cti, N, M)); + } + + public void addChannelParameters(final ChannelParameterDict params, + final String name) { + final Parameter par = + (Parameter) params.channelParameters.get(name); + channelParameters.put(name, par); + } + + public void addNodeParameters(final String name, final int M, + final boolean isArrayed, + final int direction) { + nodeParameters.put(name, new int[] { M, direction, isArrayed ? 1 : 0 }); + } + + public void clearChannels() { + channelParameters.clear(); + } + + public ChannelInput makeInputChannel + (final String chname, final String nodenm, + final ChannelFactoryInterface factory) { + final Parameter par = + (Parameter)channelParameters.get(chname); + return par.makeInputChannel(nodenm, factory); + } + + public ChannelOutput makeOutputChannel + (final String chname, final String nodenm, + final ChannelFactoryInterface factory) { + final Parameter par = + (Parameter)channelParameters.get(chname); + return par.makeOutputChannel(nodenm, factory); + } + + public WideNode makeWideNode(final String portName, final String fullName, + final boolean cosim, + final NodeFactoryInterface factory) { + final int[] params = (int[]) nodeParameters.get(portName); + return factory.makeWideNode(fullName, params[0], params[1], + params[2] == 1, cosim); + } + + /** Should only be called from CoSimInfo.refineFrom(). **/ + public void refineFrom(final ChannelParameterDict parentParams) { + this.channelParameters.putAll(parentParams.channelParameters); + this.nodeParameters.putAll(parentParams.nodeParameters); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelTimingInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelTimingInfo.java new file mode 100644 index 0000000000..0f291a856f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/ChannelTimingInfo.java @@ -0,0 +1,43 @@ +package com.avlsi.tools.cosim; + +public interface ChannelTimingInfo { + /** + * Return slack as number of full buffers. + **/ + int getSlack(); + + /** + * Return forward latency, in DSim units. + **/ + int getLatency(); + + /** + * Return data valid to enable latency, in DSim units. + **/ + int getDataValidEnableLatency(); + + /** + * Return data neutral to enable latency, in DSim units. + **/ + int getDataNeutralEnableLatency(); + + /** + * Return enable to data latency, in DSim units. + **/ + int getEnableDataLatency(); + + /** + * Return cycle time, in DSim units. + **/ + int getCycleTime(); + + /** + * Return cycle in time, in DSim units. + **/ + int getCycleTimeIn(); + + /** + * Return cycle out time, in DSim units. + **/ + int getCycleTimeOut(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelArrayInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelArrayInterface.java new file mode 100644 index 0000000000..5de628f235 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelArrayInterface.java @@ -0,0 +1,17 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +/** + * CoSimChannelArrays are (possibly multi-dimensional) arrays of + * ChannelInputs or ChannelOutputs produced by the cosim framework for + * javablock classes. People writing javablocks should always look + * for a CoSimChannelInputArray or a CoSimChannelOutputArray, for + * better typing. This interface is for the use of the framework. + **/ +interface CoSimChannelArrayInterface { } diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelInputArray.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelInputArray.java new file mode 100644 index 0000000000..2e85961ed6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimChannelInputArray.java @@ -0,0 +1,115 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +import com.avlsi.cast.impl.DenseSubscriptSpec; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.Range; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; + +/** + * Class for the cosim framework to use to pass an array of inputs to + * a javablock device. Works along the same principle as ArrayValue, + * but simpler. + **/ +public class CoSimChannelInputArray implements CoSimChannelArrayInterface { + private final DenseSubscriptSpec spec; // Java arrays are rectangular + private final ChannelInput[] chans; + private final String instanceName; + + public CoSimChannelInputArray(final DenseSubscriptSpec spec, + final ChannelInput[] chans, + final String instanceName) { + this.spec = spec; + this.chans = chans; + this.instanceName = instanceName; + } + + public DenseSubscriptSpec getSpec() { + return spec; + } + + /** + * Returns the channel resulting from subscripting. Can return + * slices. + *

    + * In order for the access to be valid, the specifications must + * both have the same number of dimensions, and all the indices of + * the accessSpec must present in the array's spec. + **/ + public CoSimChannelInputArray + accessArray(final DenseSubscriptSpec accessSpec) + throws InvalidOperationException { + + if (spec.getNumDimensions() != accessSpec.getNumDimensions()) + throw new InvalidOperationException("dims don't agree. array has " + spec.getNumDimensions() + " dimensions but accessor has " + accessSpec.getNumDimensions()); + + final ChannelInput[] newChans = + new ChannelInput[accessSpec.getNumElements()]; + + for (int i = 0; i < newChans.length; ++i) { + // spec.positionOf(idx) will throw IndexOutOfBoundsException + // if idx is not in the spec + final int[] idx = accessSpec.indexOf(i); + final int position; + + try { + position = spec.positionOf(accessSpec.indexOf(0)); + } catch (IndexOutOfBoundsException e) { + throw new InvalidOperationException("bad array access of " + + instanceName + ": index " + + DenseSubscriptSpec.idxToString(accessSpec.indexOf(0)) + + " not in spec " + spec, e); + } + + newChans[i] = chans[position]; + } + + return new CoSimChannelInputArray(accessSpec, newChans, instanceName); + } + + /** + * Access a single index. + **/ + public ChannelInput accessArray(final int[] idx) { + try { + final Range[] rs = new Range[idx.length]; + + for (int i = 0; i < rs.length; ++i) + rs[i] = new Range(idx[i], idx[i]); + + final CoSimChannelInputArray wrapper = + accessArray(new DenseSubscriptSpec(rs)); + Debug.assertTrue(wrapper.chans.length == 1); + + return wrapper.chans[0]; + } catch (InvalidOperationException e) { + throw (AssertionFailure) + new AssertionFailure("bad index? " + e).initCause(e); + } + } + + /** + * Access a range of indices. + **/ + public ChannelInput [] accessArrayRange(final int from, final int to) { + Debug.assertTrue(to>=from); + int N = to-from+1; + ChannelInput range[] = new ChannelInput[N]; + for (int i=0; i 0); + } + + public boolean hasOneElement() { + return (vals.length == 1); + } + + public String getFirstElement() { + return vals[0]; + } + + public String[] getAllElements() { + return vals; + } + + /** + * Does all the channel lookups. + * @exception DeviceConstructionException + * Thrown if it can't find one of the channels or some + * channels are inputs and some are outputs + **/ + public CoSimChannelArrayInterface + convertToChannels(final ChannelDictionary cdict) + throws DeviceConstructionException { + + // Figure out whether this is an input or an output array by + // looking at the first channel + final ChannelInput chanIn = cdict.getInputChan(vals[0]); + if (chanIn == null) + return convertToChannelOutputs(cdict); + else + return convertToChannelInputs(cdict); + } + + private CoSimChannelArrayInterface + convertToChannelInputs(final ChannelDictionary cdict) + throws DeviceConstructionException { + final ChannelInput[] chans = new ChannelInput[vals.length]; + + for (int i=0; i + * In order for the access to be valid, the specifications must + * both have the same number of dimensions, and all the indices + * of the accessSpec must present in the array's spec. + **/ + public CoSimChannelOutputArray + accessArray(final DenseSubscriptSpec accessSpec) + throws InvalidOperationException { + + if (spec.getNumDimensions() != accessSpec.getNumDimensions()) + throw new InvalidOperationException("dims don't agree. array has " + spec.getNumDimensions() + " dimensions but accessor has " + accessSpec.getNumDimensions()); + + final ChannelOutput[] newChans = + new ChannelOutput[accessSpec.getNumElements()]; + + for (int i = 0; i < newChans.length; ++i) { + // spec.positionOf(idx) will throw IndexOutOfBoundsException + // if idx is not in the spec + final int[] idx = accessSpec.indexOf(i); + final int position; + + try { + position = spec.positionOf(accessSpec.indexOf(0)); + } catch (IndexOutOfBoundsException e) { + throw new InvalidOperationException("bad array access of " + + instanceName + ": index " + + DenseSubscriptSpec.idxToString(accessSpec.indexOf(0)) + + " not in spec " + spec, e); + } + newChans[i] = chans[position]; + } + + return new CoSimChannelOutputArray(accessSpec, newChans, instanceName); + } + + /** + * Access a single index. + **/ + public ChannelOutput accessArray(final int[] idx) { + try { + final Range[] rs = new Range[idx.length]; + + for (int i = 0; i < rs.length; ++i) + rs[i] = new Range(idx[i], idx[i]); + + final CoSimChannelOutputArray wrapper = + accessArray(new DenseSubscriptSpec(rs)); + Debug.assertTrue(wrapper.chans.length == 1); + + return wrapper.chans[0]; + } catch (InvalidOperationException e) { + throw new AssertionFailure(e); + } + } + + /** + * Access a range of indices. + **/ + public ChannelOutput [] accessArrayRange(final int from, final int to) { + Debug.assertTrue(to>=from); + int N = to-from+1; + ChannelOutput range[] = new ChannelOutput[N]; + for (int i=0; icoSimParams to simulate + * instanceName in the methods specified by + * coSimSpecList. + * + *

    If verilogCellList is not null, triplets + * indicating the instance name, cell type, and verilog mode + * of any cells to be simulated in verilog will be appended to + * this list. A mode of "prs" indicates that the verilog is to + * be automatically generated from the prs if no verilog block + * named "prs" exists. + * + * @param instanceName The instance name. + * @param cell The cell type of which instanceName is an + * instance. + * @param coSimSpecList The list of methods to be cosimulated. + * @param coSimParams The cosimulation parameters to be modified. + * @param verilogCellList + * A list of triplets of (instance name, cell type, verilog mode) + * of cells that are to be simulated in verilog. May be null. + **/ + public static void setCoSimParams( + final String instanceName, + final CellInterface cell, + final CoSimSpecList coSimSpecList, + final CoSimParameters coSimParams, + final List/*>*/ verilogCellList, + final boolean verbose) + throws DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchInstanceException { + setCoSimParams(null, instanceName, cell, coSimSpecList, coSimParams, + verilogCellList, verbose); + } + + private static void setCoSimParams( + final String realInstance, + final String instanceName, + final CellInterface cell, + final CoSimSpecList coSimSpecList, + final CoSimParameters coSimParams, + final List/*>*/ verilogCellList, + final boolean verbose) + throws DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchInstanceException { + for (final Iterator i = coSimSpecList.iterator(); i.hasNext(); ) { + final CoSimSpec coSimSpec = (CoSimSpec) i.next(); + + setCoSimParams(realInstance, instanceName, cell, coSimSpec, + coSimParams, verilogCellList, verbose); + } + } + + /** + * Modifies coSimParams to simulate + * instanceName in the method specified by + * coSimSpec. This is called once for each + * member in a CoSimSpecList. The result + * of multiple calls is a CoSimParameters + * reflecting the desired cosimulation. + * + *

    If verilogCellList is not null, triplets + * indicating the instance name, cell type, and verilog mode + * of any cells to be simulated in verilog will be appended to + * this list. A mode of "prs" indicates that the verilog is to + * be automatically generated from the prs if no verilog block + * named "prs" exists. + * + * @param instanceName The instance name. + * @param cell The cell type of which instanceName is an + * instance. + * @param coSimSpec A cosimulation method. + * @param coSimParams The cosimulation parameters to be modified. + * @param verilogCellList + * A list of triplets of (instance name, cell type, verilog mode) + * of cells that are to be simulated in verilog. May be null. + **/ + public static void setCoSimParams( + final String instanceName, + final CellInterface cell, + final CoSimSpec coSimSpec, + final CoSimParameters coSimParams, + final List/*>*/ verilogCellList, + final boolean verbose) + throws DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchInstanceException { + setCoSimParams(null, instanceName, cell, coSimSpec, coSimParams, + verilogCellList, verbose); + } + + private static void setCoSimParams( + final String realInstance, + final String instanceName, + final CellInterface cell, + final CoSimSpec coSimSpec, + final CoSimParameters coSimParams, + final List/*>*/ verilogCellList, + final boolean verbose) + throws DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchInstanceException { + final LevelSpecInterface levelSpec = coSimSpec.getLevelSpec(); + final InstSpecList instSpecList = coSimSpec.getInstSpecList(); + + if (levelSpec instanceof ModeListLevelSpec) { + final ModeListLevelSpec modeListLevelSpec = + (ModeListLevelSpec) levelSpec; + + // Try the various modes + setCoSimParams(realInstance, instanceName, cell, + updateModeList(modeListLevelSpec.getModeList()), + instSpecList, + coSimParams, + verilogCellList, verbose); + } else { + final CoSimLevelSpec coSimLevelSpec = + (CoSimLevelSpec) levelSpec; + final CoSimSpecList coSimSpecList = + coSimLevelSpec.getCoSimSpecList(); + final int level = coSimLevelSpec.getLevel(); + + boolean hasSubcells = false; + if (level > 0) { + ensureRelevance(instanceName, cell, instSpecList); + // recurse to subcells, dropping irrelevant instspecs, + // keeping relevant ones, and substituting the one for + // this cell, if any + if (cell.containsCompleteSubcells()) { + for (final Iterator i = cell.getSubcellPairs(); + i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = + (HierName) p.getFirst(); + final CellInterface subcell = + (CellInterface) p.getSecond(); + final String subcellNameString = + subcellName.getAsString('.'); + + // XXX: inlined cells still a problem + // XXX: what about wiring cells? + if (!subcell.isChannel() && !subcell.isNode()) { + if (!hasSubcells) { + coSimParams.setBehavior(instanceName, + CoSimParameters.DIGITAL); + if (verbose) + System.out.println("Set behavior of " + + instanceName + " to digital"); + hasSubcells = true; + } + final String newRealInstance = + append(realInstance, subcellNameString); + setCoSimParams( + newRealInstance, + instanceName + '.' + subcellNameString, + subcell, + deepen(level, + coSimSpecList, + subcell, + newRealInstance, + instSpecList), + coSimParams, + verilogCellList, verbose); + } // if + } // for + } + } + // no longer throws HierarchyDepthException, see bug 14406 + if (!hasSubcells) { + setCoSimParams(realInstance, instanceName, cell, + addInstSpecToCoSimSpecList( + coSimSpecList, + instSpecList), + coSimParams, + verilogCellList, verbose); + } + } // else + } // setCoSimParams + + private static boolean isNarrow(final ModeList modeList) { + Mode.SubcellsMode subcell = null; + for (final Iterator i = modeList.iterator(); i.hasNext(); ) { + final Mode m = (Mode) i.next(); + if (m == Mode.PRS) return true; + else if (m == Mode.CSP) return false; + else if (m instanceof Mode.SubcellsMode) + subcell = (Mode.SubcellsMode) m; + } + return subcell.isNarrow(); + } + + private static ModeList updateModeList(final ModeList modeList) { + final List result = new ArrayList(); + for (final Iterator i = modeList.iterator(); i.hasNext(); ) { + final Mode m = (Mode) i.next(); + if (m != Mode.SUBCELLS_ROUTED && m instanceof Mode.SubcellsMode) { + final boolean narrow = isNarrow(modeList); + result.add(narrow ? Mode.SUBCELLS_NARROW : Mode.SUBCELLS); + } else { + result.add(m); + } + } + return new ModeList((Mode[]) result.toArray(new Mode[0])); + } + + /** + * Modifies coSimParams to simulate + * instanceName in the method specified by + * modeList. + * + *

    If verilogCellList is not null, triplets + * indicating the instance name, cell type, and verilog mode + * of any cells to be simulated in verilog will be appended to + * this list. A mode of "prs" indicates that the verilog is to + * be automatically generated from the prs if no verilog block + * named "prs" exists. + * + * @param instanceName The instance name. + * @param cell The cell type of which instanceName is an + * instance. + * @param modeList A list of modes to be attempted. + * @param instSpecList Instance by instance exceptions to the mode + * list. + * @param coSimParams The cosimulation parameters to be modified. + * @param verilogCellList + * A list of triplets of (instance name, cell type, verilog mode) + * of cells that are to be simulated in verilog. May be null. + **/ + private static void setCoSimParams( + final String realInstance, + final String instanceName, + final CellInterface cell, + final ModeList modeList, + final InstSpecList instSpecList, + final CoSimParameters coSimParams, + final List/*>*/ verilogCellList, + final boolean verbose) + throws DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchInstanceException { + boolean hasMode = false; + for (final Iterator i = modeList.iterator(); i.hasNext(); ) { + final Mode mode = (Mode) i.next(); + hasMode = true; + if (mode == Mode.SPICE) { + // spice level cosimulation not yet supported, treat as if + // cells do not support it + } else if (mode == Mode.PRS) { + if (cell.containsCompletePrs()) { + coSimParams.setBehavior(instanceName, + CoSimParameters.DIGITAL); + if (verbose) + System.out.println("Set behavior of " + + instanceName + " to digital"); + return; + } + } else if (mode instanceof Mode.SubcellsMode) { + if (cell.containsCompleteSubcells()) { + ensureRelevance(instanceName, cell, instSpecList); + + final Mode.SubcellsMode subMode = (Mode.SubcellsMode) mode; + coSimParams.setBehavior(instanceName, + CoSimParameters.DIGITAL, + subMode.isNarrow(), + subMode.isRouted()); + + if (verbose) + System.out.println("Set behavior of " + + instanceName + " to digital"); + + // stop when a routed hierarchy is found, but always + // recurse into the top-level subcells, even if it is + // routed + if (realInstance != null && + subMode.isRouted() && + CellUtils.isRouted(cell)) return; + + // recurse to subcells, dropping irrelevant instspecs, + // keeping relevant ones, and substituting the one for + // this cell, if any + for (final Iterator iSubcellPair = cell.getSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair p = (Pair) iSubcellPair.next(); + final HierName subcellName = + (HierName) p.getFirst(); + final CellInterface subcell = + (CellInterface) p.getSecond(); + final String subcellNameString = + subcellName.getAsString('.'); + + // XXX: inlined cells still a problem + // XXX: what about wiring cells? + if (!subcell.isChannel() && !subcell.isNode()) { + final String newRealInstance = + append(realInstance, subcellNameString); + final CoSimSpecList newCoSimSpecList = + keepRelevant(instSpecList, null, subcell, + newRealInstance); + + if (newCoSimSpecList == null) { + setCoSimParams( + newRealInstance, + instanceName + '.' + subcellNameString, + subcell, + updateModeList(modeList), + instSpecList, + coSimParams, + verilogCellList, verbose); + } else { + setCoSimParams( + newRealInstance, + instanceName + '.' + subcellNameString, + subcell, + addInstSpecToCoSimSpecList( + newCoSimSpecList, + instSpecList), + coSimParams, + verilogCellList, verbose); + } // else + } // if + } // for + + return; + } + } else if (mode == Mode.CSP) { + if (cell.containsRunnableCsp()) { + coSimParams.setBehavior(instanceName, + CoSimParameters.CSP); + if (verbose) + System.out.println("Set behavior of " + + instanceName + " to csp"); + return; + } + } else if (mode == Mode.JAVA) { + if (cell.containsJava()) { + coSimParams.setBehavior(instanceName, + CoSimParameters.JAVA); + if (verbose) + System.out.println("Set behavior of " + + instanceName + " to java"); + return; + } + } else if (mode instanceof Mode.VerilogMode) { + final Mode.VerilogMode verilogMode = (Mode.VerilogMode) mode; + final BlockIterator bi = + cell.getBlockInterface() + .iterator(BlockInterface.VERILOG); + + if (bi.hasNext()) { + // get the verilog block, making sure there is exactly 1 + final VerilogBlock verilogBlock = + (VerilogBlock) bi.next(); + assert !bi.hasNext(); + + for (Iterator iName = verilogBlock.getNamesIterator(); + iName.hasNext(); ) { + final String level = (String) iName.next(); + + if (level.equals(verilogMode.getLevel())) { + coSimParams.setBehavior(instanceName, + CoSimParameters.VERILOG, level); + if (verbose) + System.out.println("Set behavior of " + + instanceName + " to " + verilogMode); + if (verilogCellList != null) + verilogCellList.add + (new Triplet(instanceName, + cell.getFullyQualifiedType(), + level)); + return; + } + } + } + + // if we haven't found a matching named block and the + // name is null, then we will automatically generate + // the verilog using prs2verilog + if (verilogMode.getLevel() == null) { + coSimParams.setBehavior(instanceName, + CoSimParameters.VERILOG, null); + if (verbose) + System.out.println("Set behavior of " + + instanceName + " to " + verilogMode); + if (verilogCellList != null) + verilogCellList.add + (new Triplet(instanceName, + cell.getFullyQualifiedType(), + null)); + return; + } + } + } + + if (!hasMode) { + coSimParams.setBehavior(instanceName, CoSimParameters.NULL); + if (verbose) + System.out.println("Set behavior of " + instanceName + + " to null"); + return; + } + + // Error: this cell doesn't support any of the specified modes. + throw new NoBehaviorFoundException("Specified behaviors " + + modeList + instSpecList + " not " + "found in " + + instanceName + "/" + cell.getFullyQualifiedType()); + } + + /** + * Returns the cosim spec associated with an exception based on type, or + * null if no match is found. + **/ + private static CoSimSpecList typeMatches(final CellInterface cell, + final InstSpecList instSpecList) { + final CoSimSpecList[] result = new CoSimSpecList[] { null }; + final UnaryPredicate check = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final CellInterface c = (CellInterface) o; + for (Iterator i = instSpecList.iterator(); i.hasNext(); ) { + final InstSpec instSpec = (InstSpec) i.next(); + final String inst = instSpec.getInstanceName(); + final String type = c.getFullyQualifiedType(); + if (inst.equals(type) || + inst.equals(CellUtils.getBaseType(type))) { + result[0] = instSpec.getCoSimSpecList(); + break; + } + } + return result[0] != null; + } + }; + final boolean found = + CellUtils.matchRefinement(cell, check) || + CellUtils.matchRefinement(cell, new UnaryPredicate() { + public boolean evaluate(final Object o) { + final CellInterface c = (CellInterface) o; + return CellUtils.matchInheritance(c, check); + } + }); + + return result[0]; + } + + /** + * Returns the cosim spec associated with an exception based on special + * predicates, or null if no match is found. Currently, + * only the @asta_blackbox predicate is supported. + **/ + private static CoSimSpecList specialMatches(final CellInterface cell, + final InstSpecList instSpecList) + { + for (Iterator i = instSpecList.iterator(); i.hasNext(); ) { + final InstSpec instSpec = (InstSpec) i.next(); + final String inst = instSpec.getInstanceName(); + if (inst.startsWith("@")) { + if (inst.equals("@asta_blackbox")) { + if (CellUtils.isAstaBlackbox(cell)) { + return instSpec.getCoSimSpecList(); + } + } else { + // TODO: throw exception on unknown predicates + } + } + } + + return null; + } + + /** + * Returns a new relevant CoSimSpecList. The new + * CoSimSpecList contains the entry, if any, from InstSpecList that exactly + * matches subcellName, or oldCoSimSpecList if + * none matches. + **/ + private static CoSimSpecList keepRelevant( + final InstSpecList oldInstSpecList, + final CoSimSpecList oldCoSimSpecList, + final CellInterface subcell, + final String instance) { + + CoSimSpecList coSimSpecList = null; + + for (final Iterator i = oldInstSpecList.iterator(); i.hasNext(); ) { + final InstSpec instSpec = (InstSpec) i.next(); + final String instanceName = instSpec.getInstanceName(); + + // XXX: this will not catch bogus cells mentioned in the + // InstSpecList + if (instanceName.equals(instance)) { + coSimSpecList = instSpec.getCoSimSpecList(); + break; + } + } + + if (coSimSpecList == null) + coSimSpecList = typeMatches(subcell, oldInstSpecList); + + if (coSimSpecList == null) + coSimSpecList = specialMatches(subcell, oldInstSpecList); + + //if (coSimSpecList != null && verbose) + // System.out.println("substituting " + coSimSpecList + + // " for " + instanceName); + + return coSimSpecList == null ? oldCoSimSpecList : coSimSpecList; + } + + /** + * Ensures that the exceptions mentioned in instSpecList + * are not mentioned more than once. + **/ + private static void ensureRelevance( + final String instanceName, + final CellInterface cell, + final InstSpecList instSpecList) + throws DuplicateInstanceSpecException, + NoSuchInstanceException { + final Set instNames = new HashSet(); + + for (final Iterator i = instSpecList.iterator(); i.hasNext(); ) { + final InstSpec instSpec = (InstSpec) i.next(); + + final String instName = instSpec.getInstanceName(); + + // instance exception mentioned twice + if (!instNames.add(instName)) + throw new DuplicateInstanceSpecException(instanceName, + instName); + } + } + + /** + * Returns a new CoSimSpec for the specified subcell. The returned + * CoSimSpec has a CoSimLevelSpec with level one less than the level + * passed in and uses the defaultCoSimSpecList unless + * one of the exceptions from the instSpecList exactly matches + * this subcell. All exceptions in instSpecList are passed on in the new + * InstSpecList. + **/ + private static CoSimSpec deepen( + final int level, + final CoSimSpecList defaultCoSimSpecList, + final CellInterface subcell, + final String instance, + final InstSpecList instSpecList) { + + final CoSimSpecList newCoSimSpecList = + keepRelevant(instSpecList, defaultCoSimSpecList, subcell, instance); + + return new CoSimSpec( + new CoSimLevelSpec(level - 1, newCoSimSpecList), + instSpecList); + } + + /** + * Returns a new CoSimSpecList that is the same as + * coSimSpecList, but with instSpecList + * appended to the InstSpecLists of the + * component CoSimSpecs. + **/ + private static CoSimSpecList addInstSpecToCoSimSpecList( + final CoSimSpecList coSimSpecList, + final InstSpecList instSpecList) { + + final List newCoSimSpecs = new ArrayList(); + + for (final Iterator i = coSimSpecList.iterator(); i.hasNext(); ) { + final CoSimSpec coSimSpec = (CoSimSpec) i.next(); + final List newInstSpecs = new ArrayList(); + + // XXX: should we append or prepend??? + CollectionUtils.addAll(newInstSpecs, + coSimSpec.getInstSpecList().iterator()); + CollectionUtils.addAll(newInstSpecs, + instSpecList.iterator()); + + newCoSimSpecs.add(new CoSimSpec(coSimSpec.getLevelSpec(), + new InstSpecList((InstSpec[]) + newInstSpecs.toArray(new InstSpec[0])))); + } + + return new CoSimSpecList((CoSimSpec[]) + newCoSimSpecs.toArray(new CoSimSpec[0])); + } + + /** + * Fill result with a mapping from a cell type to all of its + * behaviors. + **/ + public static void getBehaviorByType(final CellInterface cell, + final CoSimParameters params, + final HierName prefix, + final MultiMap result) { + if (cell.isNode() || cell.isChannel()) return; + final String sinst = prefix.getAsString('.'); + final int beh = params.lookupBehavior(sinst); + final String type = cell.getFullyQualifiedType(); + boolean recurse = false; + if ((beh & CoSimParameters.CSP) != 0) result.put(type, Mode.CSP); + if ((beh & CoSimParameters.JAVA) != 0) result.put(type, Mode.JAVA); + if ((beh & CoSimParameters.DIGITAL) != 0) { + result.put(type, cell.containsSubcells() ? Mode.SUBCELLS + : Mode.PRS); + recurse = true; + } + if ((beh & CoSimParameters.VERILOG) != 0) + result.put(type, + new Mode.VerilogMode(params.lookupVerilogLevel(sinst))); + + if (recurse) { + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair/**/ p = (Pair) i.next(); + final HierName instance = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final HierName full = HierName.append(prefix, instance); + getBehaviorByType(subcell, params, full, result); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimInfo.java new file mode 100644 index 0000000000..55a5c65f57 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimInfo.java @@ -0,0 +1,651 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Vector; + +import com.avlsi.cast.impl.SubscriptSpecInterface; +import com.avlsi.cell.CellInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.tools.tsim.BufferedChannel; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.MergeDevice; +import com.avlsi.tools.tsim.NodeReadChannel; +import com.avlsi.tools.tsim.NodeWriteChannel; +import com.avlsi.tools.tsim.SplitDevice; +import com.avlsi.tools.tsim.Statusable; +import com.avlsi.tools.tsim.WideNode; +import com.avlsi.tools.tsim.WideNodeImpl; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.WeakHashSet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.text.StringUtil; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Set; +import java.util.TreeSet; + +/** + * Contains information needed to properly hook up channels, nodes and + * splits/merges between a behavioral-level block and its production + * rule surroundings. + **/ +public abstract class CoSimInfo { + protected final ChannelParameterDict chanParams; + /** Maps Strings to their InternalChannelInfos. **/ + protected final Map internalChannels; + /** Contains Strings. **/ + protected final Vector inputChannels; + /** Contains Strings. **/ + protected final Vector outputChannels; + /** Contains Strings. **/ + protected final Vector inputNodes; + /** Contains Strings. **/ + protected final Vector outputNodes; + /** Possibly wide node ports, any direction. */ + protected final List/**/ wideNodes; + /** Input DFT channels. **/ + protected final List/**/ inputDftChannels; + /** Output DFT channels. **/ + protected final List/**/ outputDftChannels; + + protected CoSimInfo() { + chanParams = new ChannelParameterDict(); + internalChannels = new HashMap(); + inputChannels = new Vector(); + outputChannels = new Vector(); + inputNodes = new Vector(); + outputNodes = new Vector(); + wideNodes = new ArrayList(); + inputDftChannels = new ArrayList(); + outputDftChannels = new ArrayList(); + } + + public void addInternalChannel(final String chanName) { + internalChannels.put(chanName, new InternalChannelInfo()); + } + + public void addInternalChannel(final String chanName, + int[] timingParams, + SubscriptSpecInterface spec) { + if (timingParams == null) { + internalChannels.put(chanName, new InternalChannelInfo(spec)); + } else { + Debug.assertTrue(timingParams.length == 1, + "can't handle anything other than slack yet"); + internalChannels.put(chanName, + new InternalChannelInfo(timingParams[1], + spec)); + } + } + + public void addInputChannel(final String chanName) { + inputChannels.add(chanName); + } + + public void addOutputChannel(final String chanName) { + outputChannels.add(chanName); + } + + /** Returns an iterator of Strings. **/ + public ListIterator getInputChannelNames() { + return inputChannels.listIterator(); + } + + /** Returns an iterator of Strings. **/ + public ListIterator getOutputChannelNames() { + return outputChannels.listIterator(); + } + + /** Build array of input channels. **/ + public ChannelInput[] getInputChannelArray(final ChannelDictionary dict) { + final ChannelInput[] cin = new ChannelInput[inputChannels.size()]; + for (int i = 0; i < cin.length; i++) { + cin[i] = dict.getInputChan((String) inputChannels.get(i)); + } + + return cin; + } + + /** Build array of output channels. **/ + public ChannelOutput[] getOutputChannelArray(final ChannelDictionary dict) { + final ChannelOutput[] cout = new ChannelOutput[outputChannels.size()]; + for (int i = 0; i < cout.length; i++) { + cout[i] = dict.getOutputChan((String) outputChannels.get(i)); + } + + return cout; + } + + /** Build array of wide nodes. */ + public WideNode[] getWideNodeArray(final ChannelDictionary dict) { + final WideNode[] result = new WideNode[wideNodes.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = dict.getWideNode((String) wideNodes.get(i)); + assert result[i] != null : "Cannot find WideNode for " + + wideNodes.get(i); + } + return result; + } + + /** + * Appends nodeName to list of input nodes. + **/ + public void addInputNode(final /*@ non_null @*/ String nodeName) { + inputNodes.add(nodeName); + } + + /** + * Appends nodeName to list of output nodes. + **/ + public void addOutputNode(final /*@ non_null @*/ String nodeName) { + outputNodes.add(nodeName); + } + + public void addWideNode(final String nodeName) { + wideNodes.add(nodeName); + } + + /** Returns an iterator of Strings. **/ + public /*@ non_null @*/ ListIterator getInputNodeNames() { + return inputNodes.listIterator(); + } + + /** Returns an iterator of Strings. **/ + public /*@ non_null @*/ ListIterator getOutputNodeNames() { + return outputNodes.listIterator(); + } + + /** + * Appends dftName to list of input DFT channels. + **/ + public void addInputDftChannel(final /*@ non_null @*/ String dftName) { + inputDftChannels.add(dftName); + } + + /** + * Appends dftName to list of output DFT channels. + **/ + public void addOutputDftChannel(final /*@ non_null @*/ String dftName) { + outputDftChannels.add(dftName); + } + + /** Returns an iterator of input DFT channels names. **/ + public /*@ non_null @*/ ListIterator/**/ getInputDftChannelNames() { + return inputDftChannels.listIterator(); + } + + /** Returns an iterator of output DFT channel names. **/ + public /*@ non_null @*/ ListIterator getOutputDftChannelNames() { + return outputDftChannels.listIterator(); + } + + /** + * Adds info on slack/N/M to the internal ChannelParameterDict. + **/ + public void addChannelInfo(final String name, final int slack, + final int N, final int M, + final boolean isArrayed) { + addChannelInfo(name, slack, 1, 4, N, M, isArrayed); + } + + public void addChannelInfo(final String name, final int slack, + final int latency, final int cycle_time, + final int N, final int M, + final boolean isArrayed) { + addChannelInfo(name, + new ChannelTimingInfo() { + public int getSlack() { return slack; } + public int getLatency() { return latency; } + public int getCycleTime() { return cycle_time; } + public int getDataNeutralEnableLatency() { return 0; } + public int getDataValidEnableLatency() { return 0; } + public int getEnableDataLatency() { return 0; } + public int getCycleTimeIn() { return cycle_time; } + public int getCycleTimeOut() { return cycle_time; } + }, N, M, isArrayed); + } + + public void addChannelInfo(final String name, final ChannelTimingInfo cti, + final int N, final int M, + final boolean isArrayed) { + final String realName = isArrayed && M == 1 ? + StringUtil.replaceSubstring(name + "[0]", "][", ",") : name; + chanParams.addChannelParameters(realName, cti, N, M); + } + + public void addNodeInfo(final String name, final int M, + final boolean isArrayed, final int direction) { + chanParams.addNodeParameters(name, M, isArrayed, direction); + } + + /** + * Clears all information that could have been set from + * CellImpl.setCoSimInfoFromPorts(). Internal channels are always + * explicitly specified. + **/ + public void clearPortChannels() { + inputChannels.clear(); + outputChannels.clear(); + chanParams.clearChannels(); + inputNodes.clear(); + outputNodes.clear(); + wideNodes.clear(); + inputDftChannels.clear(); + outputDftChannels.clear(); + } + + /** + * Returns true if the cosimulation information should be + * retrieved from the port list rather than the Java block. + **/ + protected abstract boolean usePorts(); + + /** + * Makes appropriate BufferedChannels and adds them to the + * dictionary. Internal channels are both inputs and outputs. + **/ + private void createInternalChannels(final ChannelDictionary dict) { + for (final Iterator i=internalChannels.entrySet().iterator(); + i.hasNext(); + ) { + Map.Entry channelDescription = (Map.Entry) i.next(); + final String name = (String) channelDescription.getKey(); + final InternalChannelInfo info = + (InternalChannelInfo) channelDescription.getValue(); + info.createInternalChannels(name, dict); + } + } + + public static class NodeChannelFactory + implements ChannelFactoryInterface { + private final float digitalTau; + + public NodeChannelFactory() { + this(1.0f); + } + + public NodeChannelFactory(final float digitalTau) { + this.digitalTau = digitalTau; + } + + protected int getSlack(final ChannelTimingInfo cti) { + return cti.getSlack(); + } + + public ChannelInput makeInputChannel(final String name, + final int radix, + final int width, + final ChannelTimingInfo cti) { + final int slack = getSlack(cti); + final int latency = cti.getLatency(); + final int ffLatency = slack == 0 ? latency : latency / slack; + final int bfLatency = cti.getEnableDataLatency(); + final int fbNeutral = cti.getDataNeutralEnableLatency(); + final int fbValid = cti.getDataValidEnableLatency(); + final int fbLatency = (fbNeutral + fbValid) / 2; + final int bbLatency = + cti.getCycleTime() - ffLatency - bfLatency - fbLatency; + return new NodeReadChannel(slack, + Math.round(ffLatency * digitalTau), + Math.round(bbLatency * digitalTau), + Math.round(fbNeutral * digitalTau), + Math.round(fbValid * digitalTau), + Math.round(bfLatency * digitalTau), + Math.round(cti.getCycleTimeIn() * + digitalTau), + Math.round(cti.getCycleTimeOut() * + digitalTau), + name, radix, width); + } + + public ChannelOutput makeOutputChannel(final String name, + final int radix, + final int width, + final ChannelTimingInfo cti) { + final int slack = getSlack(cti); + final int latency = cti.getLatency(); + final int ffLatency = slack == 0 ? latency : latency / slack; + final int bfLatency = cti.getEnableDataLatency(); + final int fbNeutral = cti.getDataNeutralEnableLatency(); + final int fbValid = cti.getDataValidEnableLatency(); + final int fbLatency = (fbNeutral + fbValid) / 2; + final int bbLatency = + cti.getCycleTime() - ffLatency - bfLatency - fbLatency; + return new NodeWriteChannel(slack, + Math.round(ffLatency * digitalTau), + Math.round(bbLatency * digitalTau), + Math.round(fbLatency * digitalTau), + Math.round(bfLatency * digitalTau), + Math.round(cti.getCycleTimeIn() * + digitalTau), + Math.round(cti.getCycleTimeOut() * + digitalTau), + name, radix, width); + } + } + + private static final class WideNodeFactory implements NodeFactoryInterface { + public WideNode makeWideNode(String name, int width, int direction, + boolean isArrayed, boolean readOnly) { + return new WideNodeImpl(name, width, direction, isArrayed, + readOnly); + } + } + + /** + * Makes appropriate NodeRead/WriteChannels and fills the + * dictionary with them. + * + * Assumes that this CoSimInfo belongs to cell. + **/ + public ChannelDictionary createNodeChannels(final HierName cellName, + final CellInterface cell, + final float digitalTau) { + return createChannels(cellName.getAsString('.'), cell, + new NodeChannelFactory(digitalTau), + new WideNodeFactory()); + } + + /** + * Makes appropriate channels using factory and fills the + * dictionary with them. + * + * Assumes that this CoSimInfo belongs to cell. + * + *

    
    +     *   public normal_behavior
    +     *     requires cell != null;
    +     *     requires chanFactory != null;
    +     *     ensures \result != null;
    +     * 
    + **/ + public ChannelDictionary createChannels(final String cellName, + final CellInterface cell, + final ChannelFactoryInterface + chanFactory, + final NodeFactoryInterface + nodeFactory) { + if (usePorts()) + cell.setCoSimInfoFromPorts(this); + + final ChannelDictionary dict = new ChannelDictionary(); + + for (final Iterator i=inputChannels.iterator(); i.hasNext(); ) { + final String chanSuffix = (String) i.next(); + final String chanName = + cellName != null ? cellName + '.' + chanSuffix + : chanSuffix; + final ChannelInput chan = + chanParams.makeInputChannel(chanSuffix, chanName, + chanFactory); + dict.addInputChan(chanSuffix, chan); + } + + for (final Iterator i=outputChannels.iterator(); i.hasNext(); ) { + final String chanSuffix = (String) i.next(); + final String chanName = + cellName != null ? cellName + '.' + chanSuffix + : chanSuffix; + final ChannelOutput chan = + chanParams.makeOutputChannel(chanSuffix, chanName, + chanFactory); + dict.addOutputChan(chanSuffix, chan); + } + + createInternalChannels(dict); + + for (final Iterator i = wideNodes.iterator(); i.hasNext(); ) { + final String nodeSuffix = (String) i.next(); + final String nodeName = + cellName != null ? cellName + '.' + nodeSuffix + : nodeSuffix; + dict.addWideNode(nodeSuffix, + chanParams.makeWideNode(nodeSuffix, nodeName, + false, nodeFactory)); + } + + return dict; + } + + /** + * Handles inputs and outputs by making appropriate NodeChannels, + * BufferedChannels, and Split/MergeDevices. The NodeChannels are + * placed in the channel dictionary. The Devices are start()ed. + * + * Assumes that this CoSimInfo belongs to cell. + * + * @param basePrefix The instance name of the cell. + * + *
    
    +     *   public normal_behavior
    +     *     requires coSimInfo != null;
    +     *     requires cell != null;
    +     *     ensures \result != null;
    +     * 
    + **/ + public static ChannelDictionary createSplitMerges( + final CoSimInfo coSimInfo, + final HierName basePrefix, + final CellInterface cell, + final int cosimSlack, + final boolean verbose) { + final HierName digPrefix = + CoSimParameters.addCoSimDigitalSuffix(basePrefix); + final ChannelDictionary dict = new ChannelDictionary(); + final NodeChannelFactory chanFactory = new NodeChannelFactory(); + final NodeChannelFactory slackFactory = new NodeChannelFactory() { + public int getSlack(ChannelTimingInfo cti) { + return 100; + } + }; + + final NodeFactoryInterface nodeFactory = new WideNodeFactory(); + + if (coSimInfo.usePorts()) + cell.setCoSimInfoFromPorts(coSimInfo); + + try { + // Inputs need to be split. + final String splitPrefix = basePrefix.getAsString('.')+".Split."; + for (final Iterator i=coSimInfo.inputChannels.iterator(); + i.hasNext(); ) { + /* Creates SplitDevice: + * >|_Java_model_| + * / + * / blmChan + * ________ baseChan / + * |_Parent_|-------->{Split} + * \ + * \ digChan + * \ _______________ + * >| Digital model | + */ + String suffix = (String) i.next(); + final ChannelInput baseChan = + coSimInfo.chanParams + .makeInputChannel(suffix, + HierName.makeHierName(basePrefix, suffix).getAsString('.'), + chanFactory); + final ChannelOutput digChan = + coSimInfo.chanParams + .makeOutputChannel(suffix, + HierName.makeHierName(digPrefix, suffix).getAsString('.'), + slackFactory); + // TODO: Move the slack into the devices + final BufferedChannel blmChan = + new BufferedChannel(cosimSlack, // slack + 1, 1, 1, 1, // latencies + 0, // debug + HierName.makeHierName(basePrefix, + suffix) + .getAsString('.'), + digChan.getNumPossibleValues()); + splitMergeChannels.add(digChan); + splitMergeChannels.add(blmChan); + assert digChan.getNumPossibleValues() + .equals(baseChan.getNumPossibleValues()); + assert digChan.getNumPossibleValues() + .equals(blmChan.getNumPossibleValues()); + new SplitDevice(splitPrefix + suffix, baseChan, + new ChannelOutput[]{digChan, blmChan}, + !verbose).start(); + dict.addInputChan(suffix, blmChan); + } + + // Outputs need to be merged. + final String mergePrefix = basePrefix.getAsString('.')+".Merge."; + for (final Iterator i=coSimInfo.outputChannels.iterator(); + i.hasNext(); ) { + /* Creates MergeDevice: + * |_Java_model_| + * / + * / blmChan + * ________ baseChan v + * |_Parent_|<--------{Merge} + * ^ + * \ digChan + * \ _______________ + * | Digital model | + */ + + String suffix = (String) i.next(); + final ChannelOutput baseChan = + coSimInfo.chanParams + .makeOutputChannel(suffix, + HierName.makeHierName(basePrefix, suffix).getAsString('.'), + chanFactory); + final ChannelInput digChan = + coSimInfo.chanParams + .makeInputChannel(suffix, + HierName.makeHierName(digPrefix, suffix).getAsString('.'), + slackFactory); + // TODO: Move the slack into the devices + final BufferedChannel blmChan = + new BufferedChannel(cosimSlack, // slack + 1, 1, 1, 1, // latencies + 0, // debug + HierName.makeHierName(basePrefix, + suffix) + .getAsString('.'), + digChan.getNumPossibleValues()); + splitMergeChannels.add(digChan); + splitMergeChannels.add(blmChan); + assert digChan.getNumPossibleValues() + .equals(baseChan.getNumPossibleValues()); + assert digChan.getNumPossibleValues() + .equals(blmChan.getNumPossibleValues()); + new MergeDevice(mergePrefix + suffix, + new ChannelInput[]{digChan, blmChan}, + baseChan, !verbose).start(); + dict.addOutputChan(suffix, blmChan); + } + + // handle nodes + for (final Iterator i = coSimInfo.wideNodes.iterator(); + i.hasNext(); ) { + final String nodeSuffix = (String) i.next(); + final String nodeName = + HierName.makeHierName(basePrefix, nodeSuffix) + .getAsString('.'); + dict.addWideNode(nodeSuffix, + coSimInfo.chanParams + .makeWideNode(nodeSuffix, nodeName, + true, nodeFactory)); + } + } catch (InvalidHierNameException e) { + // The strings stored in inputChannels and outputChannels + // should have originally been HierName suffixes, so this + // exception should be impossible to get. + Debug.assertTrue(false, "shouldn't have gotten this: " + e); + } + + coSimInfo.createInternalChannels(dict); + + return dict; + } + + public void createPortNodeLinkages + (final /*@ non_null @*/ String cellName, + final /*@ non_null @*/ CellInterface cell, + final /*@ non_null @*/ NodeLinkageInterface nodeLinker) { + + if (usePorts()) + cell.setCoSimInfoFromPorts(this); + + // input nodes + for (int i = 0; i < inputNodes.size(); ++i) { + final String nodeName = (String) inputNodes.get(i); + nodeLinker.makeInputNode(cellName + '.' + nodeName); + } + + // output nodes + for (int i = 0; i < outputNodes.size(); ++i) { + final String nodeName = (String) outputNodes.get(i); + nodeLinker.makeOutputNode(cellName + '.' + nodeName); + } + } + + /** + * Assumes that this is empty. + **/ + protected void refineFrom(final CoSimInfo parentInfo) { + // Only bother to copy anything if the parent's internals were + // explicitly set. If it cribbed from its CellImpl, it will + // do so again (and possibly more accurately). + + // This also means that information is only shared if the + // refinement child isn't going to modify it. + if (! parentInfo.usePorts()) { + this.chanParams.refineFrom(parentInfo.chanParams); + this.internalChannels.putAll(parentInfo.internalChannels); + this.inputChannels.addAll(parentInfo.inputChannels); + this.outputChannels.addAll(parentInfo.outputChannels); + this.inputNodes.addAll(parentInfo.inputNodes); + this.outputNodes.addAll(parentInfo.outputNodes); + this.wideNodes.addAll(parentInfo.wideNodes); + } + } + + public String toString() { + return "CoSimInfo with input channels: " + inputChannels + " and output channels: " + outputChannels; + } + + private static final Set splitMergeChannels = + Collections.synchronizedSet(new WeakHashSet()); + + public static void printCosimLeftovers() { + System.gc(); // eliminate zombies from WeakHashSet + TreeSet ordered = new TreeSet(new Comparator() { + public int compare(Object o1, Object o2) { + Statusable c1 = (Statusable) o1; + Statusable c2 = (Statusable) o2; + String s1 = + new StringBuffer(c1.getName()).reverse().toString(); + String s2 = + new StringBuffer(c2.getName()).reverse().toString(); + return s1.compareTo(s2); + } + }); + ordered.addAll(splitMergeChannels); + for (Iterator it = ordered.iterator(); it.hasNext(); ) { + Statusable s = (Statusable) it.next(); + s.printStatus(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimParameters.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimParameters.java new file mode 100644 index 0000000000..eb142e0e72 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/CoSimParameters.java @@ -0,0 +1,224 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +import java.util.Hashtable; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.tools.tsim.Arbiter; +import com.avlsi.util.text.StringUtil; + +public class CoSimParameters { + private Hashtable table; + + public static final int UNSPEC = 1; + public static final int DIGITAL = 2; + public static final int JAVA = 4; + public static final int CSP = 8; + public static final int VERILOG = 16; + public static final int NULL = 32; + public static final int BEH_ALL = 64; + public CoSimParameters() { table = new Hashtable(); } + + /** + * Find an existing parameter in the table with the given name. + * + * @param name name of the parameter + * @return a parameter corresponding to the name or null if a + * prameter by that name does not exist + **/ + private Parameter getParam(String name) { + if (name.charAt(0) != '.') name = "." + name; + + return (Parameter) table.get(name); + } + + /** + * Find an existing parameter in the table with the given name or if it + * does not exist, create a parameter with the given behavior and + * abitration mode and added it to the table. + * + * @param name name of the parameter + * @param behavior behavior for a newly created parameter + * @param arbitrationMode arbitration mode for a newly created parameter + * @return a parameter corresponding to the name + **/ + private Parameter getParam(String name, int behavior, int arbitrationMode) { + if (name.charAt(0) != '.') name = "." + name; + + Parameter p = (Parameter) table.get(name); + if (p == null) { + p = new Parameter(behavior, arbitrationMode); + table.put(name, p); + } + return p; + } + + private static final String COSIM_SUFFIX = "_cosim"; + + public static String stripCoSimDigitalSuffix(final HierName name) { + return StringUtil.replaceSubstring(name.getAsString('.'), "."+COSIM_SUFFIX, ""); + } + + public static HierName addCoSimDigitalSuffix(final HierName prefix) { + HierName rv = null; + try { + rv = HierName.makeHierName(prefix, COSIM_SUFFIX); + } catch (InvalidHierNameException e) { + System.out.println("Ieee! InvalidHierNameException!"); + System.exit(1); + } + return rv; + } + + /** + * Set bits of the parameter bitfield (to true). This will not set the + * UNSPEC bit. + * + * @param name Name of the instance to parameterize + * @param value Bits set to true + **/ + private Parameter setSimpleBehavior(final String name, int value) { + // do not modify the UNSPEC bit + value = value & (~UNSPEC); + + final Parameter p = getParam(name, value, 0); + value = value | p.getBehavior(); + + if ((value & CSP) != 0 && (value & JAVA) != 0) { + System.out.println("Error: cannot cosimulate CSP and JAVA." + + " Using CSP only."); + value = (value & ~JAVA); + } + + p.setBehavior(value); + + return p; + } + + public void setBehavior(final String name, final int value) { + assert value != VERILOG; + setSimpleBehavior(name, value); + } + + public void setBehavior(final String name, final int value, + final String level) { + assert level == null || value == VERILOG; + final Parameter p = setSimpleBehavior(name, value); + if (level != null) p.setVerilogLevel(level); + } + + public void setBehavior(final String name, final int value, + final boolean narrow, final boolean routed) { + assert value == DIGITAL; + final Parameter p = setSimpleBehavior(name, value); + p.setNarrowSubcell(narrow); + p.setRoutedSubcell(routed); + } + + /** + * Clear bits of the parameter bitfield (to false). This will not clear + * the UNSPEC bit if no bits have been set yet. + * + * @param name Name of the instance to parameterize + * @param value Bits set to false + **/ + public void clearBehavior(final String name, final int value) { + final Parameter p = getParam(name); + if (p != null) + p.setBehavior(~value & p.getBehavior()); + } + + public int lookupBehavior(final String name) { + final Parameter p = getParam(name); + return p == null ? UNSPEC : p.getBehavior(); + } + + public void setArbitrationMode(final String name, + final int arbitrationMode) { + getParam(name, UNSPEC, -1).setArbitrationMode(arbitrationMode); + } + + public int lookupArbitrationMode(final String name) { + final Parameter p = getParam(name); + return p == null ? Arbiter.NON_LINKED : p.getArbitrationMode(); + } + + public String lookupVerilogLevel(final String name) { + final Parameter p = getParam(name); + return p == null ? null : p.getVerilogLevel(); + } + + public boolean isNarrowSubcell(final String name) { + final Parameter p = getParam(name); + return p == null ? false : p.isNarrowSubcell(); + } + + public boolean isRoutedSubcell(final String name) { + final Parameter p = getParam(name); + return p == null ? false : p.isRoutedSubcell(); + } + + private static final class Parameter { + private int behavior; + private int arbitrationMode; + private String verilogLevel; + private boolean narrowSubcell; + private boolean routedSubcell; + + Parameter(final int behavior, final int arbitrationMode) { + this.behavior = behavior; + this.arbitrationMode = arbitrationMode; + this.verilogLevel = null; + this.narrowSubcell = false; + this.routedSubcell = false; + } + + void setBehavior(final int behavior) { + this.behavior = behavior; + } + + int getBehavior() { + return behavior; + } + + void setArbitrationMode(final int arbitrationMode) { + this.arbitrationMode = arbitrationMode; + } + + int getArbitrationMode() { + return arbitrationMode; + } + + void setVerilogLevel(final String verilogLevel) { + assert this.verilogLevel == null; + this.verilogLevel = verilogLevel; + } + + String getVerilogLevel() { + return verilogLevel; + } + + void setNarrowSubcell(final boolean narrowSubcell) { + this.narrowSubcell = narrowSubcell; + } + + boolean isNarrowSubcell() { + return narrowSubcell; + } + + void setRoutedSubcell(final boolean routedSubcell) { + this.routedSubcell = routedSubcell; + } + + boolean isRoutedSubcell() { + return routedSubcell; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceConstructionException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceConstructionException.java new file mode 100644 index 0000000000..99d4321f55 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceConstructionException.java @@ -0,0 +1,60 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.cosim; + +import java.io.PrintStream; +import java.io.PrintWriter; + +/** + * Exception to be thrown if JavaCoSimDevice has trouble constructing + * and starting the AbstractDevice it represents. Either carries a + * message in its own right or encapsulates another throwable in the + * way SemanticWrapperException and others do. + **/ + +public class DeviceConstructionException extends Exception { + private final String className; + private final String cellName; + + public DeviceConstructionException(final String message, + final Class c) { + this (message, c.getName(), "unknown cell"); + } + + public DeviceConstructionException(final String message, + final String className, + final String cellName) { + this(message, null, className, cellName); + } + + public DeviceConstructionException(final String message, + final Throwable e, + final String className, + final String cellName) { + super(message, e); + this.className = className; + this.cellName = cellName; + } + + public String getMessage() { + return toString(); + } + + public String toString() { + if (getCause() == null) + return getHeader(); + else + return getHeader() + " ( wrapping:\n" + + getCause().getMessage() + ")"; + } + + private String getHeader() { + return getClass().getName() + ": " + super.getMessage(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceParameters.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceParameters.java new file mode 100644 index 0000000000..cabff0ad75 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/DeviceParameters.java @@ -0,0 +1,233 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +import com.avlsi.fast.metaparameters.MetaParamDefinition; +import com.avlsi.tools.sigscan.DebugOpts; + +/** + * Class to wrap up all non-channel arguments to devices. Fields can + * be added to this class without breaking existing devices. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ + +public class DeviceParameters { + + /** The instance name of the device. **/ + private final String name; + + /** Debugging options controlling logging. **/ + private final DebugOpts debugOpts; + + /** Array of metaparameters. **/ + private final MetaParamDefinition[] metaParameters; + + /** + * Mode of arbitration. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + **/ + private final int arbitrationMode; + + /** + * An initial random seed. + **/ + private final long seed; + + /** + * A scale factor to apply to digital delays. + **/ + private final float digitalTau; + + /** + * Legacy class constructor. + * + * @param name instance name of device + * @param suppressOutput whether output should be suppressed + * @param metaParameters array of metaparameters + * @param arbitrationMode Mode of arbitration. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + **/ + public DeviceParameters( + final String name, + final boolean suppressOutput, + final MetaParamDefinition[] metaParameters, + final int arbitrationMode) { + this(name, suppressOutput, metaParameters, arbitrationMode, 1); + } + + /** + * Legacy class constructor. + * + * @param name instance name of device + * @param suppressOutput whether output should be suppressed + * @param metaParameters array of metaparameters + * @param arbitrationMode Mode of arbitration. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + * @param seed Initial random seed to use. + **/ + public DeviceParameters( + final String name, + final boolean suppressOutput, + final MetaParamDefinition[] metaParameters, + final int arbitrationMode, + final long seed) { + this(name, suppressOutput, metaParameters, arbitrationMode, seed, 1.0f); + } + + /** + * Legacy class constructor. + * + * @param name instance name of device + * @param suppressOutput whether output should be suppressed + * @param metaParameters array of metaparameters + * @param arbitrationMode Mode of arbitration. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + * @param seed Initial random seed to use. + * @param digitalTau Scale factor to apply to digital delays. + **/ + public DeviceParameters( + final String name, + final boolean suppressOutput, + final MetaParamDefinition[] metaParameters, + final int arbitrationMode, + final long seed, + final float digitalTau) { + this(name, new DebugOpts(!suppressOutput), metaParameters, + arbitrationMode, seed, digitalTau); + } + + /** + * Class constructor. + * + * @param name instance name of device + * @param suppressOutput whether output should be suppressed + * @param metaParameters array of metaparameters + * @param arbitrationMode Mode of arbitration. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + **/ + public DeviceParameters( + final String name, + final DebugOpts debugOpts, + final MetaParamDefinition[] metaParameters, + final int arbitrationMode) { + this(name, debugOpts, metaParameters, arbitrationMode, 1); + } + /** + * Class constructor. + * + * @param name instance name of device + * @param suppressOutput whether output should be suppressed + * @param metaParameters array of metaparameters + * @param arbitrationMode Mode of arbitration. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + * @param seed Initial random seed to use. + **/ + public DeviceParameters( + final String name, + final DebugOpts debugOpts, + final MetaParamDefinition[] metaParameters, + final int arbitrationMode, + final long seed) { + this(name, debugOpts, metaParameters, arbitrationMode, seed, 1.0f); + } + + /** + * Class constructor. + * + * @param name instance name of device + * @param suppressOutput whether output should be suppressed + * @param metaParameters array of metaparameters + * @param arbitrationMode Mode of arbitration. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + * @param seed Initial random seed to use. + * @param digitalTau Scale factor to apply to digital delays. + **/ + public DeviceParameters( + final String name, + final DebugOpts debugOpts, + final MetaParamDefinition[] metaParameters, + final int arbitrationMode, + final long seed, + final float digitalTau) { + this.name = name; + this.debugOpts = debugOpts; + this.metaParameters = metaParameters; + this.arbitrationMode = arbitrationMode; + this.seed = seed; + this.digitalTau = digitalTau; + } + + /** + * Returns the instance name of the device. + **/ + public String getName() { + return name; + } + + /** + * Returns flag indicating if output should be suppressed. + **/ + public boolean isOutputSuppressed() { + return debugOpts.loggingScreen(); + } + + /** + * Returns array of meta parameters. + **/ + public MetaParamDefinition[] getMetaParameters() { + return metaParameters; + } + + /** + * Returns the arbitration mode. One of + * com.avlsi.tools.tsim.Arbiter.NON_LINKED, + * com.avlsi.tools.tsim.Arbiter.LINKED_SLAVE, or + * com.avlsi.tools.tsim.Arbiter.LINKED_MASTER. + * See {@see com.avlsi.tools.tsim.Arbiter}. + **/ + public int getArbitrationMode() { + return arbitrationMode; + } + + /** + * Return the random seed the device should use. + **/ + public long getSeed() { + return seed; + } + + /** + * Return the scale factor applied to digital delays. + **/ + public float getDigitalTau() { + return digitalTau; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/InternalChannelInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/InternalChannelInfo.java new file mode 100644 index 0000000000..5ddd1d1fcb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/InternalChannelInfo.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim; + +import com.avlsi.cast.impl.DenseSubscriptSpec; +import com.avlsi.cast.impl.SubscriptSpecInterface; +import com.avlsi.tools.tsim.BufferedChannel; + +/** + * Class for containing parameters describing a channel internal to + * the CAST java block. Doesn't contain the name; these are indexed + * by name. Can describe an array of channels. Immutable. + **/ +final class InternalChannelInfo { + private final int slack; + /** null if this isn't an array. **/ + private final SubscriptSpecInterface arraySpec; + + private static final int defaultSlack = 1; // smallest possible + private static final SubscriptSpecInterface defaultArraySpec = null; + + public InternalChannelInfo() { + this(defaultSlack, defaultArraySpec); + } + + public InternalChannelInfo(final int slack) { + this(slack, defaultArraySpec); + } + + public InternalChannelInfo(final SubscriptSpecInterface arraySpec) { + this(defaultSlack, arraySpec); + } + + public InternalChannelInfo(final int slack, + final SubscriptSpecInterface arraySpec) { + this.slack = slack; + this.arraySpec = arraySpec; + } + + /** + * Makes appropriate BufferedChannel(s) and adds them to the + * dictionary. Internal channels are both inputs and outputs. + **/ + public void createInternalChannels(final String name, + final ChannelDictionary dict) { + if (arraySpec == null) { + final BufferedChannel chan = new BufferedChannel(slack); + dict.addInputChan(name+".in", chan); + dict.addOutputChan(name+".out", chan); + } else { + for (int i=0; i timing info mapping to m, if this channel has a + * custom slack specified. + **/ + public void getChannelTimingInfoMap(Map m) { + if(hasTimingParams()) { + Integer tp=new Integer(timingParams[0]); + if(isArray) { + String[] array=arrayNames.getAllElements(); + for(int i=0; iVector<JavaClassParameter>
    holds the parameters + * that were specified in the java block of this device. + * JavaClassParameter's are Strings + * and (possibly multi-dimensional) arrays of Strings. These have + * been through meta-parameter processing; there are no variables + * left. They might describe array elements or arrays; arrays have + * been broken down into their original channels/nodes (which are + * placed in a CoSimChannelArrayInterface). They're in the order + * they'll be passed to the AbstractDevice constructor (i.e., the + * order specified in the original CAST). Can't be null or empty. + **/ + private final Vector channelAndNodeNames; + + /** + * In the order they'll be passed to AbstractDevice.enqueue(). + * This should only contain floats/ints/bools/strings + * (BigDecimals, BigIntegers, Booleans, and Strings). Can be null. + * + *

    Not yet used for anything. + **/ + private final Vector initializers; + + /** + * See comments on the member variables for format notation on + * each of these. + **/ + public JavaCoSimDevice(final String className, + final String instanceName, + final MetaParamDefinition[] metaParameters, + final Vector channelAndNodeNames, + final Vector initializers) { + this.className = className; + this.instanceName = instanceName; + this.metaParameters = metaParameters; + this.channelAndNodeNames = channelAndNodeNames; + this.initializers = initializers; + } + + /** + * Called by JavaCoSimInfo.addClass. Adds a channel name -> timing + * info mapping to m, for each channel which has a custom slack + * specified in the java block. + **/ + public void getChannelTimingInfoMap(Map m) { + for(int i=0; i + * public normal_behavior + * requires name != null; + * + **/ + void makeInputNode(String name); + + /** + * Creates an output channel. + * + *

    
    +     *   public normal_behavior
    +     *     requires name != null;
    +     * 
    + **/ + void makeOutputNode(String name); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/AcceptorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/AcceptorInterface.java new file mode 100644 index 0000000000..d88876ef49 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/AcceptorInterface.java @@ -0,0 +1,5 @@ +package com.avlsi.tools.cosim.spec; + +public interface AcceptorInterface { + void accept(VisitorInterface visitor); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.g b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.g new file mode 100644 index 0000000000..3e958a8ae5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.g @@ -0,0 +1,305 @@ +// +// Copyright 2002 Fulcrum Microsystems. All rights reserved. +// +// $Id$ +// $DateTime$ +// $Author$ +// + +// author: Jesse Rosenstock +// version: $Revision$ $Date$ + +header { + package com.avlsi.tools.cosim.spec; +} +{ + import java.util.ArrayList; + import java.util.List; +} + +class CoSimParser extends Parser; +options { + buildAST = false; + k = 3; + defaultErrorHandler = false; +} +{ + /** + * The default mode list when one isn't supplied in envLevelSpec. + * Also used by defaultCoSimSpecList() for the default in a levelSpec. + * Default is: java, csp, subcells, prs, spice + **/ + private ModeList defaultModeList() { + return new ModeList(new Mode[] { + Mode.JAVA, Mode.CSP, Mode.SUBCELLS, Mode.PRS, Mode.SPICE + }); + } + + /** + * Returns a CoSimSpec containing one CoSimSpec specifying the + * given modes and no instance exceptions. + **/ + private CoSimSpec coSimSpecFromModeList(final ModeList modeList) { + return new CoSimSpec( + new ModeListLevelSpec(modeList), + new InstSpecList(new InstSpec[0])); + } + /** + * Returns a CoSimSpecList containing one CoSimSpec specifying the + * given modes and no instance exceptions. + **/ + private CoSimSpecList coSimSpecListFromModeList(final ModeList modeList) { + return new CoSimSpecList(new CoSimSpec[]{ + coSimSpecFromModeList(modeList) + }); + } + + /** + * The default cosimSpecList when one isn't supplied in a levelSpec. + * Default is: java,csp,subcells,prs,spice + **/ + private CoSimSpecList defaultCoSimSpecList() { + return coSimSpecListFromModeList(defaultModeList()); + } + + /** + * The default CoSimSpecList when one isn't specified at the top level. + * Default is: + * java,csp,subcells,prs,spice | prs,subcells,csp,java. + **/ + private CoSimSpecList defaultTopCoSimSpecList() { + return new CoSimSpecList(new CoSimSpec[] { + coSimSpecFromModeList(defaultModeList()), + defaultEnvCoSimSpec() + }); + } + + /** + * The default CoSimSpec when one isn't supplied as the envSpec. + * Default is: prs,subcells,csp,java. + **/ + private CoSimSpec defaultEnvCoSimSpec() { + return new CoSimSpec( + new ModeListLevelSpec( + new ModeList(new Mode[] { + Mode.PRS, Mode.SUBCELLS, Mode.CSP, Mode.JAVA + })), + new InstSpecList(new InstSpec[0])); + } + + private int intValue(final String s) { + // XXX: throws NumberFormatException if number is too large + if (s.startsWith("0x")) + return Integer.parseInt(s.substring(2), 16); + else + return Integer.parseInt(s); + } + + private CoSimSpecList topCoSimSpecList = defaultTopCoSimSpecList(); + private CoSimSpec envCoSimSpec = defaultEnvCoSimSpec(); + + public void setTopCoSimSpecList(final CoSimSpecList topCoSimSpecList) { + this.topCoSimSpecList = topCoSimSpecList; + } + public void setEnvCoSimSpec(final CoSimSpec envCoSimSpec) { + this.envCoSimSpec = envCoSimSpec; + } +} +// ANTLR only expects EOFs after "start rules", which are rules +// that are not referred to by any in the grammar. If we don't +// have this rule, EOF will break us! +cosim returns [CoSim coSim] + { String cellType, envName; + CoSimSpecList coSimSpecList = null; + CoSimSpec envSpec = null; } + // XXX + // default cosimSpecList is 0(java,csp,prs,spice)|*(prs,csp,java) + // default envSpec is *(prs,csp,java) + : cellType=type ( LCURLY coSimSpecList=cosimSpecList RCURLY )? + COLON envName=type ( LCURLY envSpec=envSpec RCURLY )? + { coSim = + new CoSim(cellType, + coSimSpecList != null ? coSimSpecList : topCoSimSpecList, + envName, + envSpec != null ? envSpec : envCoSimSpec); } + ; +cosimEnvOptional returns [CoSim coSim] + { String cellType, envName = null; + CoSimSpecList coSimSpecList = null; + CoSimSpec envSpec = null; } + // XXX + // default cosimSpecList is 0(java,csp,prs,spice)|*(prs,csp,java) + // default envSpec is *(prs,csp,java) + : cellType=type ( LCURLY coSimSpecList=cosimSpecList RCURLY )? + ( COLON envName=type ( LCURLY envSpec=envSpec RCURLY )? )? + { coSim = + new CoSim(cellType, + coSimSpecList != null ? coSimSpecList : topCoSimSpecList, + envName, + envSpec != null ? envSpec : envCoSimSpec); } + ; + +cosimSpecDirective returns [CoSimSpec coSimSpec] + : coSimSpec=cosimSpec EOF + ; + +// consider moveing LCURLY ... RCURLY inside cosimSpecList +cosimSpecList returns [CoSimSpecList coSimSpecList] + { List l = new ArrayList(); CoSimSpec coSimSpec; } + : coSimSpec=cosimSpec {l.add(coSimSpec);} + ( PIPE coSimSpec=cosimSpec {l.add(coSimSpec);} )* + { coSimSpecList = + new CoSimSpecList((CoSimSpec[]) l.toArray(new CoSimSpec[0])); } + ; +cosimSpec returns [CoSimSpec coSimSpec] + { LevelSpecInterface levelSpec; InstSpecList instSpecList; } + : levelSpec=levelSpec instSpecList=instSpecList + { coSimSpec = new CoSimSpec(levelSpec, instSpecList); } + ; +levelSpec returns [LevelSpecInterface levelSpec] + { int level; ModeList modeList; + CoSimSpecList coSimSpecList = null; } + : level=level ( LCURLY coSimSpecList=cosimSpecList RCURLY )? + { levelSpec = new CoSimLevelSpec(level, coSimSpecList != null ? + coSimSpecList : + defaultCoSimSpecList()); } + | modeList=modeList + { levelSpec = new ModeListLevelSpec(modeList); } + ; +modeList returns [ModeList modeList] + { Mode mode; List l = new ArrayList(); } + : ( mode=mode {l.add(mode);} ( COMMA mode=mode {l.add(mode);} )* )? + { modeList = new ModeList((Mode[]) l.toArray(new Mode[0])); } + ; +level returns [int level] + { String l; } + : l=integer { level = intValue(l); } + ; +mode returns [Mode mode] + { String level = null; } + : JAVA { mode = Mode.JAVA; } + | CSP { mode = Mode.CSP; } + | SUBCELLS { mode = Mode.SUBCELLS; } + | PRS { mode = Mode.PRS; } + | SPICE { mode = Mode.SPICE; } + | VERILOG ( DOT level=ident )? { mode = new Mode.VerilogMode(level); } + ; +instSpecList returns [InstSpecList instSpecList] + { InstSpec instSpec; List l = new ArrayList(); } + : ( MINUS instSpec=instSpec {l.add(instSpec);} )* + { instSpecList = + new InstSpecList((InstSpec[]) l.toArray(new InstSpec[0])); } + ; +instSpec returns [InstSpec instSpec] + { String instName; CoSimSpecList coSimSpecList; } + : instName=instance LCURLY coSimSpecList=cosimSpecList RCURLY + { instSpec = new InstSpec(instName, coSimSpecList); } + ; +envSpec returns [CoSimSpec coSimSpec] + { LevelSpecInterface levelSpec; InstSpecList instSpecList; } + : levelSpec=envLevelSpec instSpecList=envInstSpecList + { coSimSpec = new CoSimSpec(levelSpec, instSpecList); } + ; +envLevelSpec returns [LevelSpecInterface levelSpec] + { int level; ModeList modeList = null; } + : level=level ( LCURLY modeList=modeList RCURLY )? + { levelSpec = + new CoSimLevelSpec(level, + coSimSpecListFromModeList(modeList != null ? + modeList : + defaultModeList())); } + | modeList=modeList + { levelSpec = new ModeListLevelSpec(modeList); } + ; +envInstSpecList returns [InstSpecList instSpecList] + { InstSpec instSpec; List l = new ArrayList(); } + : ( MINUS instSpec=envInstSpec {l.add(instSpec);} )* + { instSpecList = + new InstSpecList((InstSpec[]) l.toArray(new InstSpec[0])); } + ; +envInstSpec returns [InstSpec instSpec] + { String instName; ModeList modeList; } + : instName=instance LCURLY modeList=modeList RCURLY + { instSpec = + new InstSpec(instName, coSimSpecListFromModeList(modeList)); } + ; +type returns [String s] + { String id; StringBuffer sb = new StringBuffer(); } + : id=ident {sb.append(id);} ( metaParamList[sb] )? + ( DOT {sb.append('.');} + id=ident {sb.append(id);} ( metaParamList[sb] )? )* + { s = sb.toString(); } + ; +metaParamList[StringBuffer sb] + : LPAREN {sb.append('(');} + metaParam[sb] ( COMMA {sb.append(',');} metaParam[sb] )* + RPAREN {sb.append(')');} + ; +metaParam[StringBuffer sb] + { String i; } + : ( MINUS {sb.append('-');} )? i=integer {sb.append(i);} + | TRUE {sb.append("true"); } + | FALSE {sb.append("false");} + | LCURLY {sb.append('{');} + metaParam[sb] ( COMMA {sb.append(',');} metaParam[sb] )* + RCURLY {sb.append('}');} + ; +// this could be tightened up since x[0][1] is not supported, only x[0,1] +instance returns [String s] + { String id; StringBuffer sb; } + : id=ident {sb = new StringBuffer(id);} ( selector[sb] )* + { s = sb.toString(); } + ; +selector[StringBuffer sb] + { String i, id; } + : DOT {sb.append('.');} + id=ident {sb.append(id);} + | LBRACK {sb.append('[');} + i=integer {sb.append(i);} + ( COMMA i=integer {sb.append(','); sb.append(i);} )* + RBRACK {sb.append(']');} + ; +ident returns [String s] + : id:IDENT { s = id.getText(); } + | i:INT { s = i.getText(); } + ; +integer returns [String i] + : t:INT { i = t.getText(); } + ; +// need to handle "0" or "spice" quoting + +class CoSimLexer extends Lexer; +options { + k = 3; + charVocabulary = '\3' .. '\377'; // needed for ~ to make sense +} +tokens { + JAVA="java"; + CSP="csp"; + SUBCELLS="subcells"; + PRS="prs"; + SPICE="spice"; + VERILOG="verilog"; + FALSE="false"; + TRUE="true"; +} + +WS : (' ' | '\t' | '\r' | '\n' { newline(); } ) { _ttype = Token.SKIP; } ; +protected ALPHA : (('a'..'z') | ('A'..'Z') | '_') ; +protected DIGIT : ('0'..'9') ; +protected HEX_DIGIT : DIGIT | 'a'..'f' | 'A'..'F' ; +protected REAL_IDENT : ALPHA (ALPHA | DIGIT)* ; +IDENT : ('@')? REAL_IDENT ; + +INT : { LA(1) == '0' && LA(2) == 'x' }? "0x" (HEX_DIGIT)+ + | (DIGIT)+ (REAL_IDENT { $setType(IDENT); })? + ; + +LBRACK : '[' ; RBRACK : ']' ; +LCURLY : '{' ; RCURLY : '}' ; +LPAREN : '(' ; RPAREN : ')' ; +COLON : ':'; +COMMA : ','; +DOT : '.'; +MINUS : '-' ; +PIPE : '|' ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.java new file mode 100644 index 0000000000..91774628d7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSim.java @@ -0,0 +1,136 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Class to represent a cosimulation. + *

    + * Represents the top level rule cosimulate rule in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CoSim { + /** + * Type of cell to be simulated. May not be null. + **/ + private final String cellType; + + /** + * Specification of the cell's simulation methods. May not be null. + **/ + private final CoSimSpecList coSimSpecList; + + /** + * Named environment in which the cell should be simulated. + * May not be null. + **/ + private final String envName; + + /** + * Specification of the environment's simulation method. May not be null. + **/ + private final CoSimSpec envSpec; + + /** + * Class constructor. + * + * @param cellType Type of cell to be simulated. May not be null. + * @param coSimSpecList Specification of the cell's simulation methods. + * May not be null. + * @param envName Named environment in which the cell should be + * simulated. May not be null. + * @param envSpec pecification of the environment's simulation method. + * May not be null. + **/ + public CoSim( + final String cellType, + final CoSimSpecList coSimSpecList, + final String envName, + final CoSimSpec envSpec) { + this.cellType = cellType; + this.coSimSpecList = coSimSpecList; + this.envName = envName; + this.envSpec = envSpec; + } + + /** + * Returns the cell type to be simulated. + * @return cell type to be simulated, not null. + **/ + public String getCellType() { + return cellType; + } + + /** + * Returns a specification of the cell's simulation methods. + * @return specification of the cell's simulation methods, not null + **/ + public CoSimSpecList getCoSimSpecList() { + return coSimSpecList; + } + + /** + * Returns the named environment in which the cell should be simulated. + * @return named environment in which the cell should be simulated, + * not null. + **/ + public String getEnvName() { + return envName; + } + + /** + * Returns a specification of the environment's simulation method. + * @return specification of the environment's simulation methods not null + **/ + public CoSimSpec getEnvSpec() { + return envSpec; + } + + public String toString() { + return cellType + coSimSpecList + + ':' + envName + '{' + envSpec + '}'; + } + + /** + * Returns a cosimulation object parsed from the given spec. + * @param spec A cosimulation specification + * @return cosimulation object corresponding to spec + * @throws IllegalArgumentException if spec cannot be parsed + **/ + public static CoSim getCoSim(final String spec) + throws IllegalArgumentException { + return getCoSim(spec, false); + } + + public static CoSim getCoSim(final String spec, final boolean envOptional) + throws IllegalArgumentException { + return getCoSim(spec, envOptional, null, null); + } + + public static CoSim getCoSim(final String spec, final boolean envOptional, + final CoSimSpecList topCoSimSpecList, + final CoSimSpec envCoSimSpec) + throws IllegalArgumentException { + final CoSimLexer lexer = new CoSimLexer(new java.io.StringReader(spec)); + final CoSimParser parser = new CoSimParser(lexer); + + if (topCoSimSpecList != null) + parser.setTopCoSimSpecList(topCoSimSpecList); + if (envCoSimSpec != null) parser.setEnvCoSimSpec(envCoSimSpec); + + try { + if (envOptional) return parser.cosimEnvOptional(); + else return parser.cosim(); + } catch (antlr.ANTLRException e) { + throw (IllegalArgumentException) + new IllegalArgumentException("Cannot parse cosimulation specification: " + spec).initCause(e); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimLevelSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimLevelSpec.java new file mode 100644 index 0000000000..da644e3449 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimLevelSpec.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Represents the level and method for the simulation of a cell. + *

    + * Represents the level ...alternative of the rule + * levelspec in the Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CoSimLevelSpec implements LevelSpecInterface, + AcceptorInterface { + /** + * Level at which the cell should be simulated. May not be negative. + **/ + private final int level; + + /** + * Method in which the cell should be simulated. May not be null. + **/ + private final CoSimSpecList coSimSpecList; + + /** + * Class constructor. + * + * @param level Level at which the cell should be simulated. May not + * be negative. + * @param coSimSpecList Method in which the cell should be simulated. + * May not be null. + * + * @throws IllegalArgumentException If level is negative. + **/ + public CoSimLevelSpec( + final int level, + final CoSimSpecList coSimSpecList) { + if (level < 0) + throw new IllegalArgumentException + ("level must be non-negative: " + level); + + this.level = level; + this.coSimSpecList = coSimSpecList; + } + + /** + * Returns the level at which the cell should be simulated. + * @return level at which the cell should be simulated, non-negative + **/ + public int getLevel() { + return level; + } + + /** + * Returns the method in which the cell should be simulated. + * @return method in which the cell should be simulated, not null + **/ + public CoSimSpecList getCoSimSpecList() { + return coSimSpecList; + } + + public String toString() { + return level + coSimSpecList.toString(); + } + + public void accept(VisitorInterface v) { + v.visitCoSimLevelSpec(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpec.java new file mode 100644 index 0000000000..788c3d3764 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpec.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Represents a levelspec and list of instance-by-instance + * exceptions to that levelspec. + *

    + * Represents the rule cosimspec + * in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class CoSimSpec implements AcceptorInterface { + /** + * Cosimulation level and method. May not be null. + **/ + private final LevelSpecInterface levelSpec; + + /** + * Instance-by-instance exceptions to the levelSpec + **/ + private final InstSpecList instSpecList; + + /** + * Class constructor. + * + * @param levelSpec Cosimulation level and method. May not be null. + * @param instSpecList Instance-by-instance exceptions to the + * levelSpec. May not be null. + **/ + public CoSimSpec( + final LevelSpecInterface levelSpec, + final InstSpecList instSpecList) { + this.levelSpec = levelSpec; + this.instSpecList = instSpecList; + } + + /** + * Returns the cosimulation level and method + * @return cosimulation level and method, not null + **/ + public LevelSpecInterface getLevelSpec() { + return levelSpec; + } + + /** + * Returns instance-by-instance exceptions to the + * levelSpec. + * @return instance-by-instance exceptions to the + * levelSpec, not null + **/ + public InstSpecList getInstSpecList() { + return instSpecList; + } + + public String toString() { + return levelSpec.toString() + instSpecList.toString(); + } + + public void accept(VisitorInterface v) { + v.visitCoSimSpec(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecCallback.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecCallback.java new file mode 100644 index 0000000000..bdf9a51d11 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecCallback.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +import java.io.StringReader; + +import antlr.ANTLRException; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast2.directive.impl.DirectiveCallback; +import com.avlsi.cast2.directive.DirectiveConstants; + +public class CoSimSpecCallback implements DirectiveCallback { + private static CoSimSpecCallback singleton = null; + private CoSimSpecCallback() { } + public static CoSimSpecCallback getInstance() { + if (singleton == null) singleton = new CoSimSpecCallback(); + return singleton; + } + public Object resolve(String type, String value, Environment env) { + assert type.equals(DirectiveConstants.COSIM_SPEC_TYPE); + final CoSimLexer lexer = new CoSimLexer(new StringReader(value)); + final CoSimParser parser = new CoSimParser(lexer); + try { + return parser.cosimSpecDirective(); + } catch (antlr.ANTLRException e) { + return null; + } catch (IllegalArgumentException e) { + return null; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecList.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecList.java new file mode 100644 index 0000000000..e755d18a60 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/CoSimSpecList.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; + +/** + * Represents the methods in which a cell should be cosimulated. + *

    + * Represents the rule cosimspec_list + * in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class CoSimSpecList implements AcceptorInterface { + /** + * Methods in which a cell should be cosimulated. May not be null. + **/ + private final CoSimSpec[] coSimSpecs; + + /** + * Class constructor. + * + * @param coSimSpecs methods in which a cell should be cosimulated. + * May not be null. + **/ + public CoSimSpecList(final CoSimSpec[] coSimSpecs) { + this.coSimSpecs = coSimSpecs; + } + + /** + * Returns an Iterator<CoSimSpec> of the + * methods to be cosimulated. + * @return an Iterator<CoSimSpec> of the + * methods to be cosimulated, not null. + **/ + public Iterator iterator() { + return Collections.unmodifiableList(Arrays.asList(coSimSpecs)) + .iterator(); + } + + public String toString() { + final StringBuffer sb = new StringBuffer("{"); + boolean firstP = true; + + for (int i = 0; i < coSimSpecs.length; ++i) { + if (firstP) + firstP = false; + else + sb.append(" | "); + + sb.append(coSimSpecs[i].toString()); + } + + sb.append('}'); + + return sb.toString(); + } + + public void accept(VisitorInterface v) { + v.visitCoSimSpecList(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/DuplicateInstanceSpecException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/DuplicateInstanceSpecException.java new file mode 100644 index 0000000000..0610e41973 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/DuplicateInstanceSpecException.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Thrown to indicate that an instance exception was specified twice in + * an InstSpecList. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class DuplicateInstanceSpecException extends Exception { + /** + * Instance in which the cosim exception is multiply specified. + * May not be null. + **/ + private final String instanceName; + + /** + * The cosim exception that is multiply specified. May not be null. + **/ + private final String subInstanceName; + + /** + * Class constructor. + **/ + public DuplicateInstanceSpecException( + final String instanceName, + final String subInstanceName) { + super("Exception " + subInstanceName + " multiply specified in " + + instanceName); + this.instanceName = instanceName; + this.subInstanceName = subInstanceName; + } + + /** + * Returns the instance in which the named subcell could not be found. + * @return the instance in which the named subcell could not be found, + * not null. + **/ + public String getInstanceName() { + return instanceName; + } + + /** + * Returns the name of the subinstance that could not be found. + * @return the name of the subinstance that could not be found, not null + **/ + public String getSubInstanceName() { + return subInstanceName; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ExtraInstanceSpecException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ExtraInstanceSpecException.java new file mode 100644 index 0000000000..7d0edfa750 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ExtraInstanceSpecException.java @@ -0,0 +1,60 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +import com.avlsi.tools.cosim.spec.InstSpecList; + +/** + * Thrown by DSim.cosimulate to indicate that a non-empty + * InstSpecList was provided where it should have been empty. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ExtraInstanceSpecException extends Exception { + /** + * Instance for which the non-empty InstSpecList + * was specified. May not be null. + **/ + private final String instanceName; + + /** + * The non-empty InstSpecList. May not be null. + **/ + private final InstSpecList instSpecList; + + /** + * Class constructor. + **/ + public ExtraInstanceSpecException( + final String instanceName, + final InstSpecList instSpecList) { + super("Erroneously non-empty instspec_list " + instSpecList + + " for " + instanceName); + this.instanceName = instanceName; + this.instSpecList = instSpecList; + } + + /** + * Returns the instance for which the non-empty InstSpecList + * was specified. + * @return the instance for which the non-empty InstSpecList + * was specified. Not null. + **/ + public String getInstanceName() { + return instanceName; + } + + /** + * Returns the non-empty InstSpecList. + * @return the non-empty InstSpecList, not null. + **/ + public InstSpecList getInstSpecList() { + return instSpecList; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/HierarchyDepthException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/HierarchyDepthException.java new file mode 100644 index 0000000000..fa55360e1b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/HierarchyDepthException.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Thrown to indicate that a cosimulation could not be carried out because + * a depth greater than the depth of the hierarchy was requested. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class HierarchyDepthException extends Exception { + + /** + * Instance name whose depth was exceeded. May not be null. + **/ + final String instanceName; + + /** + * Amount by which depth was exceeded. Must be positive. + **/ + final int excessDepth; + + /** + * Class constructor. + * + * @param instanceName Instance name whose depth was exceeded. + * May not be null. + * @param excessDepth Amount by which depth was exceeded. + * Must be positive. + **/ + public HierarchyDepthException(final String instanceName, + final int excessDepth) { + this.instanceName = instanceName; + this.excessDepth = excessDepth; + } + + /** + * Returns the instance name whose depth was exceeded. + * @return the instance name whose depth was exceeded, not null. + **/ + public String getInstanceName() { + return instanceName; + } + + /** + * Returns the amount by which the depth was exceeded. + * @return the amount by which the depth was exceeded, positive. + **/ + public int getExcessDepth() { + return excessDepth; + } + + public String toString() { + return "Depth of " + instanceName + " exceeded by " + excessDepth; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpec.java new file mode 100644 index 0000000000..6eb355729f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpec.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Represents an instance and cosimulation method for an instance-by-instance + * exception. + *

    + * Represents the rule instspec + * in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class InstSpec implements AcceptorInterface { + /** + * Instance name. May not be null. + **/ + private final String instanceName; + + /** + * Cosimulation method. May not be null. + **/ + private final CoSimSpecList coSimSpecList; + + /** + * Class constructor. + * + * @param instanceName instance name, may not be null + * @param coSimSpecList cosimulation method, may not be null + **/ + public InstSpec( + final String instanceName, + final CoSimSpecList coSimSpecList) { + this.instanceName = instanceName; + this.coSimSpecList = coSimSpecList; + } + + /** + * Returns the instance name. + * @return the instance name, not null + **/ + public String getInstanceName() { + return instanceName; + } + + /** + * Returns the cosimulation method. + * @return the cosimulation method, not null + **/ + public CoSimSpecList getCoSimSpecList() { + return coSimSpecList; + } + + public String toString() { + return " - " + instanceName + coSimSpecList; + } + + public void accept(VisitorInterface v) { + v.visitInstSpec(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpecList.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpecList.java new file mode 100644 index 0000000000..9fdf1810ff --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/InstSpecList.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; + +/** + * Represents the instance-by-instance exceptions. + *

    + * Represents the rule instspec_list + * in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class InstSpecList implements AcceptorInterface { + /** + * Instance-by-instance exceptions. May not be null. + **/ + private final InstSpec[] instSpecs; + + /** + * Class constructor. + * + * @param instSpecs Instance-by-instance exceptions. May not be null. + **/ + public InstSpecList(final InstSpec[] instSpecs) { + this.instSpecs = instSpecs; + } + + /** + * Returns an Iterator<InstSpec> of the + * instance-by-instance exceptions + * @return an Iterator<InstSpec> of the + * instance-by-instance exceptions, not null + **/ + public Iterator iterator() { + return Collections.unmodifiableList(Arrays.asList(instSpecs)) + .iterator(); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < instSpecs.length; ++i) + sb.append(instSpecs[i].toString()); + + return sb.toString(); + } + + public void accept(VisitorInterface v) { + v.visitInstSpecList(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/LevelSpecInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/LevelSpecInterface.java new file mode 100644 index 0000000000..c9b0c48a9d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/LevelSpecInterface.java @@ -0,0 +1,21 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Represents the level at which a cell should be cosimulated. + *

    + * Represents the rule levelspec + * in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public interface LevelSpecInterface extends AcceptorInterface { +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/Mode.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/Mode.java new file mode 100644 index 0000000000..9c20fa18a6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/Mode.java @@ -0,0 +1,118 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +import com.avlsi.util.container.ObjectUtils; + +/** + * Represents the mode in which a cell should be simulated. + *

    + * Represents the rule mode + * in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class Mode implements AcceptorInterface { + protected Mode() { } + + public void accept(VisitorInterface v) { + v.visitMode(this); + } + + /** + * Java mode. + **/ + public static final Mode JAVA = new JavaMode(); + + /** + * Csp mode. + **/ + public static final Mode CSP = new CspMode(); + + /** + * Subcells mode. + **/ + public static final Mode SUBCELLS = new SubcellsMode(); + public static final Mode SUBCELLS_NARROW = new SubcellsMode(true); + public static final Mode SUBCELLS_ROUTED = new SubcellsMode(false, true); + + /** + * PRS mode. + **/ + public static final Mode PRS = new PrsMode(); + + /** + * Spice mode. + **/ + public static final Mode SPICE = new SpiceMode(); + + private static final class JavaMode extends Mode { + public String toString() { return "java"; } + } + + private static final class CspMode extends Mode { + public String toString() { return "csp"; } + } + + public static final class SubcellsMode extends Mode { + private final boolean narrow; + private final boolean routed; + SubcellsMode() { + this(false); + } + SubcellsMode(final boolean narrow) { + this(narrow, false); + } + SubcellsMode(final boolean narrow, final boolean routed) { + this.narrow = narrow; + this.routed = routed; + } + public String toString() { return "subcells"; } + public boolean isNarrow() { + return narrow; + } + public boolean isRouted() { + return routed; + } + } + + private static final class PrsMode extends Mode { + public String toString() { return "prs"; } + } + + private static final class SpiceMode extends Mode { + public String toString() { return "spice"; } + } + + public static final class VerilogMode extends Mode { + private final String level; + + public VerilogMode(final String level) { + this.level = level; + } + + public String getLevel() { + return level; + } + + public boolean equals(final Object o) { + return o instanceof VerilogMode && + ObjectUtils.equals(((VerilogMode) o).level, level); + } + + public int hashCode() { + return level == null ? 0 : level.hashCode(); + } + + public String toString() { + return "verilog" + (level != null ? '.' + level : ""); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeList.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeList.java new file mode 100644 index 0000000000..c33c60c91c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeList.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * Represents a list of cosimulation modes. + *

    + * Represents rule mode_list + * in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ModeList implements AcceptorInterface { + /** + * List of modes in which to attempt simulation. May not be null. + **/ + private final Mode[] modes; + + /** + * Class constructor. + * + * @param modes Modes in which to attempt simulation. + * May not be null. + **/ + public ModeList(final Mode[] modes) { + // make sure that each mode is specified at most once + final Set modeSet = new HashSet(); + for (int i = 0; i < modes.length; ++i) { + final Mode mode = modes[i]; + if (modeSet.contains(mode)) + throw new IllegalArgumentException("Duplicate mode: " + mode); + + modeSet.add(mode); + } + + this.modes = modes; + } + + /** + * Returns an Iterator<Mode> of the + * modes in which to attempt simulation. + * @return an Iterator<Mode> of the + * methods in which to attempt simulation, not null. + **/ + public Iterator iterator() { + return Collections.unmodifiableList(Arrays.asList(modes)).iterator(); + } + + public String toString() { + final StringBuffer sb = new StringBuffer(); + boolean firstP = true; + + for (int i = 0; i < modes.length; ++i) { + if (firstP) + firstP = false; + else + sb.append(','); + sb.append(modes[i].toString()); + } + + return sb.toString(); + } + + public void accept(VisitorInterface v) { + v.visitModeList(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeListLevelSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeListLevelSpec.java new file mode 100644 index 0000000000..13dfd659c8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/ModeListLevelSpec.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Represents a list of modes at which simulation should be attempted. + *

    + * Represents the mode_listalternative of the rule + * levelspec in the + * Cosimulation UI Specification. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class ModeListLevelSpec implements LevelSpecInterface, + AcceptorInterface { + /** + * List of modes. May not be null. + **/ + private final ModeList modeList; + + /** + * Class constructor. + * + * @param modeList list of modes. May not be null + **/ + public ModeListLevelSpec(final ModeList modeList) { + this.modeList = modeList; + } + + /** + * Returns list of modes. + * @return list of modes, not null + **/ + public ModeList getModeList() { + return modeList; + } + + public String toString() { + return modeList.toString(); + } + + public void accept(VisitorInterface v) { + v.visitModeListLevelSpec(this); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/NoSuchInstanceException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/NoSuchInstanceException.java new file mode 100644 index 0000000000..a3c2f08960 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/NoSuchInstanceException.java @@ -0,0 +1,69 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.cosim.spec; + +/** + * Thrown to indicate that an instance exception was requested in + * an InstSpecList but the subcell did not exist. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class NoSuchInstanceException extends Exception { + /** + * Instance in which the named subcell could not be found. + * May not be null. + **/ + private final String instanceName; + + /** + * Type of instanceName. May not be null. + **/ + private final String cellType; + + /** + * The name of the subcell that could not be found. May not be null. + **/ + private final String subcellName; + + public NoSuchInstanceException( + final String instanceName, + final String cellType, + final String subcellName) { + super("No subcell " + subcellName + " found in " + + instanceName + "(type " + cellType + ")"); + this.instanceName = instanceName; + this.cellType = cellType; + this.subcellName = subcellName; + } + + /** + * Returns the instance in which the named subcell could not be found. + * @return the instance in which the named subcell could not be found, + * not null. + **/ + public String getInstanceName() { + return instanceName; + } + + /** + * Returns the type of instanceName. + * @return the type of instanceName, not null. + **/ + public String getCellType() { + return cellType; + } + + /** + * Returns the name of the subcell that could not be found. + * @return the name of the subcell that could not be found, not null + **/ + public String getSubcellName() { + return subcellName; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/VisitorInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/VisitorInterface.java new file mode 100644 index 0000000000..e3e3ae1eee --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/VisitorInterface.java @@ -0,0 +1,12 @@ +package com.avlsi.tools.cosim.spec; + +public interface VisitorInterface { + void visitCoSimLevelSpec(CoSimLevelSpec coSimLevelSpec); + void visitCoSimSpecList(CoSimSpecList coSimSpecList); + void visitCoSimSpec(CoSimSpec coSimSpec); + void visitInstSpecList(InstSpecList instSpecList); + void visitInstSpec(InstSpec instSpec); + void visitModeListLevelSpec(ModeListLevelSpec modeListLevelSpec); + void visitModeList(ModeList modeList); + void visitMode(Mode mode); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/custom.mk new file mode 100644 index 0000000000..cb18a4679e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/cosim/spec/custom.mk @@ -0,0 +1,6 @@ +MAKE_ANTLR_RULES_G_FILE_NAME := CoSim.g +MAKE_ANTLR_RULES_LEXER_NAME := CoSimLexer +MAKE_ANTLR_RULES_PARSER_NAME := CoSimParser +MAKE_ANTLR_RULES_TOKEN_TYPES_NAME := CoSimParser + +include $(BUILD_SYSTEM_ROOT)/filetypes/antlrfiles/mkantlrrules.mk diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayer.java new file mode 100644 index 0000000000..4f9062f342 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayer.java @@ -0,0 +1,70 @@ +package com.avlsi.tools.difflayout; + +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.util.Collection; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +public class DiffLayer { + public static BufferedImage diff(GDSIIFile a, GDSIIFile b, + int layer, int width) { + LayerInfo info = LayerInfo.get(layer); + + int minx = Math.min(a.minx, b.minx); + int miny = Math.min(a.miny, b.miny); + int maxx = Math.min(a.maxx, b.maxx); + int maxy = Math.min(a.maxy, b.maxy); + + int cellwidth = (maxx - minx); + int cellheight = (maxy - miny); + + double scale = (width / (double)cellwidth); + int height = (int)(cellheight * scale); + int imgheight = height + 50; + + BufferedImage bi = new BufferedImage(width, imgheight, + BufferedImage.TYPE_INT_RGB); + Graphics2D g = bi.createGraphics(); + g.setBackground(Color.black); + g.clearRect(0, 0, width, imgheight); + g.setColor(Color.yellow); + g.fillRect(0, 0, width, (imgheight - height)); + + Font regular = g.getFont(); + Font bigger = regular.deriveFont(Font.BOLD, (float)36); + g.setFont(bigger); + FontMetrics fm = g.getFontMetrics(); + int textX = 1 + (width - fm.stringWidth(info.name)) / 2; + int textY = (((imgheight - height) - fm.getAscent()) / 2 + + fm.getAscent()); + g.setColor(Color.black); + g.drawString(info.name, textX, textY); + + g.translate(0, imgheight - height); + g.scale(scale, -scale); + g.translate(0, -maxy); + g.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON)); + g.addRenderingHints(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON)); + + Collection agons = a.getPolygonsForLayer(layer); + Collection bgons = b.getPolygonsForLayer(layer); + Collection same = PolygonUtils.samePolygons(agons, bgons); + Collection diff = PolygonUtils.differentPolygons(agons, bgons); + + if (diff.size() == 0) + return null; + + g.setColor(info.color.darker()); + PolygonUtils.drawPolygons(same, g); + g.setColor(info.color); + PolygonUtils.drawPolygons(diff, g); + + return bi; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayers.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayers.java new file mode 100644 index 0000000000..47a2770449 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/DiffLayers.java @@ -0,0 +1,72 @@ +package com.avlsi.tools.difflayout; + +import java.util.ArrayList; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import javax.imageio.ImageIO; +import java.io.InputStream; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.awt.image.Raster; +import java.util.TreeSet; + +public class DiffLayers { + public static void main(String[] argv) throws Exception { + if (argv.length != 3) { + System.err.println("Usage: DiffLayers file1.xml file2.xml outfile.png"); + System.exit(1); + } + + InputStream file1 = new FileInputStream(argv[0]); + InputStream file2 = new FileInputStream(argv[1]); + File out = new File(argv[2]); + + GDSIIFile a = new GDSIIFile(); + a.parseXml(file1); + GDSIIFile b = new GDSIIFile(); + b.parseXml(file2); + + TreeSet layers = new TreeSet(); + layers.addAll(a.getLayers()); + layers.addAll(b.getLayers()); + + LinkedHashSet layersICareAbout = new LinkedHashSet(); + layersICareAbout.add(new Integer(37)); + layersICareAbout.add(new Integer(36)); + layersICareAbout.add(new Integer(35)); + layersICareAbout.add(new Integer(34)); + layersICareAbout.add(new Integer(33)); + layersICareAbout.add(new Integer(32)); + layersICareAbout.add(new Integer(31)); + layersICareAbout.add(new Integer(17)); + + layersICareAbout.retainAll(layers); + + ArrayList images = new ArrayList(); + int height = 0; + final int width = 800; + + for (Iterator it = layersICareAbout.iterator(); it.hasNext(); ) { + Number layer = (Number) it.next(); + BufferedImage image = DiffLayer.diff(a, b, layer.intValue(), width); + if (image != null) { + images.add(image); + height += image.getHeight(); + } + } + + BufferedImage bi = new BufferedImage(width, height, + BufferedImage.TYPE_INT_RGB); + height = 0; + for (Iterator it = images.iterator(); it.hasNext(); ) { + BufferedImage image = (BufferedImage) it.next(); + Raster r = image.getData(); + r = r.createTranslatedChild(0, height); + bi.setData(r); + height += image.getHeight(); + } + + ImageIO.write(bi, "png", out); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/GDSIIFile.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/GDSIIFile.java new file mode 100644 index 0000000000..32709be8f0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/GDSIIFile.java @@ -0,0 +1,95 @@ +package com.avlsi.tools.difflayout; + +import org.xml.sax.Attributes; +import java.io.BufferedReader; +import java.util.Collection; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.InputSource; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Iterator; +import java.util.LinkedList; +import java.io.Reader; +import java.awt.Rectangle; +import javax.xml.parsers.SAXParserFactory; +import java.util.TreeSet; +import org.xml.sax.XMLReader; + +public class GDSIIFile extends DefaultHandler { + /** + * A little utility function which feeds the given stream to this + * handler. + */ + public void parseXml(InputStream istr) + throws Exception { + XMLReader xr; + xr = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + xr.setContentHandler(this); + xr.setErrorHandler(this); + + Reader r = new BufferedReader(new InputStreamReader(istr)); + xr.parse(new InputSource(r)); + r.close(); + } + + /** Polygon currently being parsed. */ + private LayeredPolygon poly; + + /** Polygons which have been parsed. */ + private LinkedList polygons = new LinkedList(); + + /** bounding box */ + int minx = Integer.MAX_VALUE, miny = Integer.MAX_VALUE; + int maxx = Integer.MIN_VALUE, maxy = Integer.MIN_VALUE; + + /** Layers which have been seen */ + private TreeSet layers = new TreeSet(); + + public void startElement (String uri, String name, + String qName, Attributes atts) { + if (qName.equals("boundary")) { + int layer = Integer.parseInt(atts.getValue("layer")); + poly = new LayeredPolygon(layer); + layers.add(new Integer(layer)); + } else if (qName.equals("xy") && poly != null) { + int x = Integer.parseInt(atts.getValue("x")); + int y = Integer.parseInt(atts.getValue("y")); + if (x < minx) + minx = x; + if (x > maxx) + maxx = x; + if (y < miny) + miny = y; + if (y > maxy) + maxy = y; + poly.addPoint(x,y); + } + } + + public void endElement (String uri, String name, + String qName) { + if (qName.equals("boundary")) { + polygons.add(poly); + poly = null; + } + } + + public Collection getPolygonsForLayer(int layer) { + Collection c = new LinkedList(); + for (Iterator it = polygons.iterator(); it.hasNext(); ) { + LayeredPolygon p = (LayeredPolygon) it.next(); + if (p.layer == layer) + c.add(p); + } + + return c; + } + + public Collection getLayers() { + return layers; + } + + public Rectangle getBoundingBox() { + return new Rectangle(minx, miny, maxx-minx, maxy-miny); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayerInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayerInfo.java new file mode 100644 index 0000000000..c1e04e3870 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayerInfo.java @@ -0,0 +1,47 @@ +package com.avlsi.tools.difflayout; + +import java.awt.Color; + +public class LayerInfo { + public final Color color; + public final String name; + + private LayerInfo(Color color, String name) { + this.color = color; + this.name = name; + } + + public static LayerInfo get(int layer) { + switch (layer) { + case 17: return new LayerInfo(Color.red, "poly"); + case 30: return new LayerInfo(Color.gray, "contacts"); + + case 31: return new LayerInfo(Color.cyan, "metal1"); + case 32: return new LayerInfo(Color.green, "metal2"); + case 33: return new LayerInfo(Color.magenta, "metal3"); + case 34: return new LayerInfo(Color.blue, "metal4"); + case 35: return new LayerInfo(Color.orange, "metal5"); + case 36: return new LayerInfo(Color.blue.darker(), "metal6"); + case 37: return new LayerInfo(Color.orange.darker(), "metal7"); + case 38: return new LayerInfo(Color.green.darker(), "metal8"); + + case 51: return new LayerInfo(Color.cyan, "metal1-2 vias"); + case 52: return new LayerInfo(Color.green, "metal2-3 vias"); + case 53: return new LayerInfo(Color.magenta, "metal3-4 vias"); + case 54: return new LayerInfo(Color.blue, "metal4-5 vias"); + case 55: return new LayerInfo(Color.orange, "metal5-6 vias"); + case 56: return new LayerInfo(Color.blue.darker(), "metal6-7 vias"); + case 57: return new LayerInfo(Color.orange.darker(), "metal7-8 vias"); + + case 131: return new LayerInfo(Color.cyan, "metal1 pins"); + case 132: return new LayerInfo(Color.green, "metal2 pins"); + case 133: return new LayerInfo(Color.magenta, "metal3 pins"); + case 134: return new LayerInfo(Color.blue, "metal4 pins"); + case 135: return new LayerInfo(Color.orange, "metal5 pins"); + case 136: return new LayerInfo(Color.blue.darker(), "metal6 pins"); + case 137: return new LayerInfo(Color.orange.darker(), "metal7 pins"); + case 138: return new LayerInfo(Color.green.darker(), "metal8 pins"); + } + return new LayerInfo(Color.white, "unknown layer " + layer); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayeredPolygon.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayeredPolygon.java new file mode 100644 index 0000000000..da914e024d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/LayeredPolygon.java @@ -0,0 +1,44 @@ +package com.avlsi.tools.difflayout; + +import java.awt.Polygon; + +public class LayeredPolygon extends Polygon implements Comparable { + public final int layer; + + public LayeredPolygon(int layer) { + this.layer = layer; + } + + public int compareTo(Object o) { + LayeredPolygon p = (LayeredPolygon) o; + if (layer != p.layer) + return layer - p.layer; + if (npoints != p.npoints) + return npoints - p.npoints; + for (int i = 0; i < npoints; i++) { + if (xpoints[i] != p.xpoints[i]) + return xpoints[i] - p.xpoints[i]; + if (ypoints[i] != p.ypoints[i]) + return ypoints[i] - p.ypoints[i]; + } + return 0; + } + + public boolean equals(Object o) { + return (compareTo(o) == 0); + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < npoints; i++) { + if (i > 0) + buf.append(' '); + buf.append('('); + buf.append(xpoints[i]); + buf.append(", "); + buf.append(ypoints[i]); + buf.append(')'); + } + return buf.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/PolygonUtils.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/PolygonUtils.java new file mode 100644 index 0000000000..828a7ca2d3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/difflayout/PolygonUtils.java @@ -0,0 +1,34 @@ +package com.avlsi.tools.difflayout; + +import java.util.Collection; +import java.awt.Graphics2D; +import java.util.Iterator; +import java.awt.Polygon; +import java.util.TreeSet; + +public class PolygonUtils { + public static Collection samePolygons(Collection a, Collection b) { + TreeSet s = new TreeSet(); + s.addAll(a); + s.retainAll(b); + return s; + } + + public static Collection differentPolygons(Collection a, Collection b) { + TreeSet s = new TreeSet(); + s.addAll(a); + s.removeAll(b); + TreeSet t = new TreeSet(); + t.addAll(b); + t.removeAll(a); + s.addAll(t); + return s; + } + + public static void drawPolygons(Collection c, Graphics2D g) { + for (Iterator it = c.iterator(); it.hasNext(); ) { + Polygon p = (Polygon)it.next(); + g.fill(p); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/BinningQueue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/BinningQueue.java new file mode 100644 index 0000000000..c4e0b1ab90 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/BinningQueue.java @@ -0,0 +1,244 @@ +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +import java.util.NoSuchElementException; +import java.util.HashMap; + +import com.avlsi.util.debug.Debug; + +/** + *

    BinningQueue has a heap and a hashmap inside so that events + * that have the same event time take up only one node within the heap. This + * node in the heap represents the head of a linked list which strings together + * all of the events scheduled at that time. This allows us to ensure sequence + * time between the events---that is, events that have the same time will fire + * in the order in which they are added to the queue. A heap-based + * implementation would not normally have this property.

    + * + *

    The hashmap is used to match event times to bins. The hashmap maps times + * with the last node in the bin for that time. This is nice because in the + * case where the bin has already been created, the time for insertion is O(1), + * instead of O(log n).

    + * + * @author Dan Daly + * @author Joseph Kiniry + * @version $Date$ + **/ + +public class BinningQueue implements EventQueueInterface { + + // Attributes + + private static final HashMap table = new HashMap(); + + private final EventQueue queue = new EventQueue(); + + /** Number of events in the queue **/ + private int numEvents = 0; + + // Constructors + + // default constructor only + + // Public Methods + + // documented in interface + + /** + * Add an object to the queue. Will first check if any other events are + * scheduled with the same time. If so, then the event will be put at the + * end of the linked list for that event time O(1). If there are no + * existing events at that time, the event will be put into the heap O(log + * n) to head up the linked list for that event time. + **/ + public void enqueue(final Event e) { + if (e instanceof SequencedEvent) { + enqueue((SequencedEvent) e); + } else { + //Just a regular event, do not attempt to bin, + //just toss into the heap + queue.enqueue(e); + numEvents++; + } + if (DSimDebug.DEBUG) + Debug.log("Pending events after enqueue:\n" + pendingList()); + } + + public void enqueue(final SequencedEvent e) { + Long ltime = new Long(e.getTime()); + SequencedEvent simul = + (SequencedEvent) table.remove(ltime); + if (simul != null) { + //Simultaneous event exists in the table. This means + //that a bin for that event time has already been created. + //Append the new event to the linked list + simul.setNextEvent(e); + e.setIndex(simul.getIndex()); //Used to make remove work right + } else { + //We have a new event at this time + //So put it into the heap to head up the new bin + queue.enqueue(e); + } + assert(e.getIndex() >=0); + //Then put the new event into the HashMap to update + //the tail pointer of the linked list + //This is the insertion point for any new events put + //into the bin + table.put(ltime, e); + numEvents++; + if (DSimDebug.DEBUG) + Debug.log("Pending events after enqueue:\n" + pendingList()); + } + + // documented in interface + + public Event next() { + Event e = (Event) front(); + numEvents--; + if (e instanceof SequencedEvent) { + return sequencedNext((SequencedEvent) e); + } else { + return queue.next(); + } + } + + public SequencedEvent getSequencedNext() { + numEvents--; + return sequencedNext((SequencedEvent) front()); + } + + private SequencedEvent sequencedNext(SequencedEvent top) { + if (top.hasNextEvent()) { + assert(top.getIndex() != -1); + //This node has simultaneous events + //Leave the heap alone, and just pop off + //the head node from the bin + queue.copyInto(top.getIndex(), top.getNextEvent()); + top.setNextEvent(null); + top.setIndex(-1); + } else { + //Need to remove this tail event from the table + Long ltime = new Long(top.getTime()); + table.remove(ltime); + //No other simultaneous events, so remove from heap + return (SequencedEvent) queue.next(); + } + return top; + } + + // documented in interface + + /** + * @time-complexity O(1) + **/ + public int size() { + return numEvents; } + + // documented in interface + + public Event front() { return queue.front(); } + + // documented in interface + + public boolean isEmpty() { return queue.isEmpty(); } + + // documented in interface + + public void remove(Event e) { + //queue.remove() will remove the entire bin (bad), + //so massage we must do + if (e.getIndex() < 0) throw new NoSuchElementException( + "Cannot remove "+e); + if (e instanceof SequencedEvent) { + //If the event is a sequence event, we need to traverse + //the linked-list for that time and find the event. If + //the event is at the head of list, we need to update the + //event queue. + //If the event is at the end of list, we need to update the + //hash table. + Long ltime = new Long(e.getTime()); + SequencedEvent head = (SequencedEvent) queue.get(e.getIndex()); + SequencedEvent tail = (SequencedEvent) table.get(ltime); + //If the bin has only one element, just return it + //If the head of the bin is our guy, just remove it + //from the bin + if (head.equals(e)) { + SequencedEvent newhead = head.getNextEvent(); + if (newhead == null) + queue.remove(e); + else { + queue.copyInto(head.getIndex(), newhead); + head.setIndex(-1); + } + if (tail.equals(e)) { + table.remove(ltime); + } + } else { + //The EventQueue will return the head of the bin + //with the index of the event. Now its up to us to + //find this event. + SequencedEvent last = (SequencedEvent) head; + SequencedEvent se = (SequencedEvent) head.getNextEvent(); + while (!se.equals(e)) { + Debug.assertTrue(se.hasNextEvent()); + last = se; + se = se.getNextEvent(); + } + //Remove the node from our bin + last.setNextEvent(se.getNextEvent()); + se.setIndex(-1); + //Update the hash if its our last entry + if (e.equals(tail)) { + table.remove(ltime); + table.put(ltime,last); + } + } + } else { + queue.remove(e); + } + numEvents--; + } + + // documented in interface + + public String pendingList() { + return pendingList(false); + } + + public String pendingList(boolean seqEventsOnly) { + StringBuffer ret = new StringBuffer(); + for (int i=0; i violations = new TreeSet(); + circuit.foreachVertex( + new UnaryPredicate() { + @Override public boolean evaluate(Vertex v) { + ShortestPaths paths = + GraphUtil.singleSrcShortestPaths(v, tCounts + 0.5); + checkViolations((HalfOp) v, paths, tCounts, violations); + return true; + } + }); + + pw.println(violations.isEmpty() ? "PASS" : "FAIL"); + + for (Violation v : violations) { + pw.println(v); + } + } + + private void checkViolations(final HalfOp src, + final ShortestPaths paths, + final int tCounts, + final Collection violations) { + Collection reached = paths.getReached(); + HalfOp notSrc = src.not(); + for(Vertex v : reached) { + HalfOp r = (HalfOp) v; + if(r.isDuplicate()) { + continue; + } + + final int dist = (int) Math.round(paths.getDistance(r, 0)); + if (r.equals(src) || dist > tCounts) { + continue; + } + + final HalfOpEdge enableEdge = r.getEdge(notSrc); + final HalfOpEdge disableEdge = r.not().getEdge(src); + if (enableEdge != null) { + int effDist = dist + (int) Math.round(enableEdge.getWeight()); + if (effDist <= tCounts) { + violations.add(new Violation(r, notSrc, paths, effDist)); + } + } + if (disableEdge != null) { + int effDist = dist + (int) Math.round(disableEdge.getWeight()); + if (effDist <= tCounts) { + violations.add(new Violation(r, src, paths, effDist)); + } + } + } + } + + private static class Violation implements Comparable { + private final LinkedList path; + private final int transitions; + Violation(final HalfOp reached, final HalfOp end, + final ShortestPaths paths, + final int transitions) { + this.path = rotate(paths.getPath(reached)); + this.transitions = transitions; + } + + private String strip(Vertex v) { + String s = ((HalfOp) (v)).getNode().getName().toString(); + if (s.startsWith("x.")) { + s = s.substring(2); + } + return s; + } + + private LinkedList rotate(LinkedList path) { + LinkedList result = null; + + final int size = path.size(); + if (size == 0) { + result = new LinkedList(); + } else { + Vertex min = null; + for (Vertex v : path) { + if (min == null || v.compareTo(min) < 0) { + min = v; + result = new LinkedList(); + } + result.add(strip(v)); + } + int missing = size - result.size(); + + for (Iterator i = + CollectionUtils.take(path.iterator(), + size - result.size()); + i.hasNext(); ) { + result.add(strip(i.next())); + } + } + + return result; + } + + public boolean equals(Object o) { + return (o instanceof Violation) && compareTo((Violation) o) == 0; + } + + public int hashCode() { + return path.hashCode(); + } + + public int compareTo(Violation o) { + int result = transitions - o.transitions; + if (result != 0) return result; + + Iterator i = path.iterator(); + Iterator j = o.path.iterator(); + while (i.hasNext() && j.hasNext()) { + result = i.next().compareTo(j.next()); + if (result != 0) return result; + } + + if (i.hasNext()) return -1; + else if (j.hasNext()) return 1; + else return 0; + } + + public String toString() { + return "" + transitions + " " + path; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSim.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSim.java new file mode 100644 index 0000000000..3523b5375e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSim.java @@ -0,0 +1,5847 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.io.IOException; +import java.io.ByteArrayInputStream; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Writer; + +import java.text.NumberFormat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Comparator; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.NoSuchElementException; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Vector; +import java.util.regex.Pattern; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.impl.AmbiguousLookupException; +import com.avlsi.cast.impl.BoolValue; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast.impl.Value; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.impl.CastParsingOption; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; + +import com.avlsi.cell.CellDelay; +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.HierarchyInterface; +import com.avlsi.cell.NoSuchEnvironmentException; + +import com.avlsi.csp.csp2java.runtime.CspRuntimeAbstractDevice; +import com.avlsi.csp.util.VisitorExceptionWithLocation; + +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.EnvBlock; +import com.avlsi.fast.VerilogBlock; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.StructureType; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.SearchPath; + +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.cell.CellConstants; +import com.avlsi.tools.cosim.ChannelDictionary; +import com.avlsi.tools.cosim.ChannelFactoryInterface; +import com.avlsi.tools.cosim.ChannelTimingInfo; +import com.avlsi.tools.cosim.CoSimHelper; +import com.avlsi.tools.cosim.CoSimInfo; +import com.avlsi.tools.cosim.CoSimParameters; +import com.avlsi.tools.cosim.DeviceConstructionException; +import com.avlsi.tools.cosim.NodeLinkageInterface; +import com.avlsi.tools.cosim.spec.*; +import com.avlsi.tools.dsim.DigitalScheduler; +import com.avlsi.tools.dsim.Node; +import com.avlsi.tools.dsim.Rule; +import com.avlsi.tools.prs2verilog.AbstractConverter; +import com.avlsi.tools.prs2verilog.Prs2Verilog; +import com.avlsi.tools.prs2verilog.verilog.VerilogEmitter; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryImpl; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogUtil; +import com.avlsi.tools.tsim.AbstractDevice; +import com.avlsi.tools.tsim.Arbiter; +import com.avlsi.tools.tsim.ChannelInput; +import com.avlsi.tools.tsim.ChannelOutput; +import com.avlsi.tools.tsim.SharedBus; +import com.avlsi.tools.tsim.verilog.VerilogSharedBus; +import com.avlsi.tools.tsim.verilog.VpiInterface; +import com.avlsi.tools.tsim.verilog.SignalNotFoundException; +import com.avlsi.tools.tsim.Data; +import com.avlsi.tools.sigscan.DebugOpts; +import com.avlsi.tools.jflat.JFlat; +import com.avlsi.tools.sigscan.NodeLogger; +import com.avlsi.tools.sigscan.Sigscan; +import com.avlsi.tools.sigscan.SigscanException; + +import com.avlsi.util.bool.AndBooleanExpressionInterface; +import com.avlsi.util.bool.AndBooleanExpression; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.BooleanUtils; +import com.avlsi.util.bool.HierNameAtomicBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpressionInterface; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.IterableIterator; +import com.avlsi.util.container.Map2SetAdapter; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.MutableInt; +import com.avlsi.util.container.ObjectUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.SortingIterator; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.functions.NullaryAction; +import com.avlsi.util.functions.UnaryAction; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.NaturalStringComparator; +import com.avlsi.util.text.PrintfFormat; +import com.avlsi.util.text.StringUtil; +import com.avlsi.util.text.UnrepresentableCharException; + +public class DSim implements NodeWatcher { + + private static DSim singleton = null; + + + /** List of nodes in a searchable structure. **/ + //private final NodeStore nodes = new NodeStore(); + private final HashMap nodes = new HashMap(); + /** List of rules that act on the nodes. **/ + private final Vector rules = new Vector(); + /** Count of non-asserted production rules. **/ + private int nonAssertedRuleCount = 0; + /** Scheduler responsible for Event queueing and execution. **/ + private DigitalScheduler sched = DigitalScheduler.get(); + /** Has a production rule set been loaded. **/ + public boolean loaded = false; + /** Has an error occurred during instantiation? **/ + public boolean errors = false; + /** Print out warnings? **/ + private boolean warn = true; + /** Stop after any printed warnings? **/ + private boolean error = true; + /** Stop on co-simulation conflict? **/ + public boolean haltOnConflict = true; + /** Stop on CSP error statement? **/ + public boolean haltOnError = true; + /** Print lots of gratuitous details? **/ + boolean verbose = false; + /** Print gratuitous details related to STA? **/ + boolean staVerbose = false; + /** Actually only controls printout of tcounts **/ + boolean countTransitions = false; + private Random rand = new Random(1); + /** Total number of nodes created **/ + private int nodeCount=0; + /** Name of environment to use **/ + private String envName = null; + /** Name of cell that gets the environment **/ + private HierName envCell = null; + /** Name of the cell **/ + private String cellName = null; + /** The cast file that's been loaded **/ + private CastFile loadedFile = null; + /** Print exception stack traces and other such debugging crap? **/ + private boolean debug = false; + /** Slack to put between CSP devices and split/merge devices **/ + private int cosimSlack = 1000; + + /** Name of the reset port in the cell **/ + private HierName resetPortName = null; + + /** Name of the reset node in top-level **/ + private HierName resetNodeName = null; + + private SearchPath m_CastFileSearchPath; + + private CommandLineArgs m_theArgs; + + /** + * Cached CastFileParser. Changes to the files + * will not be detected! + * + *

    I tried using a {@link java.lang.ref.SoftReference}, but that was + * dropped even though there appeared to be enough memory, and + * java -client was run. + **/ + private CastFileParser cachedCastFileParser; + + /** + * True if the file cache is enabled. Changes to the files will + * not be detected! + **/ + private boolean fileCacheEnabled; + + private ClassLoader m_DeviceLoader; + + /** + * Have the ERROR node and the GND=>ERROR+ rule been added yet? + * Should only be set to back to false if the corresponding rules + * and node are removed at the same time. + **/ + private boolean ERRORHandlingDoneYet = false; + + /* controls whether we do coverage of generated CSP */ + public boolean emitCSPCoverageProbes=false; + + /** + * Map from a node's canonical name to the name that used to request + * its watch. + **/ + private final Map/**/ + canonNodeNameToWatchedNodeNameMap = + new HashMap/**/(); + + /** + * Processors of measured_delay directives. + **/ + private Collection measuredProcs = + new ArrayList(); + private Node measuredWarningContext = null; + private final NullaryAction zeroDataNotifier = new NullaryAction() { + public void execute() { + final Pair warnPair = new Pair(measuredWarningContext, "zero"); + if (warnedCells.add(warnPair)) { + System.err.println( + "\nWarning: Invalid data (bug 19653) removed for " + + measuredWarningContext.getName()); + } + } + }; + + /** + * Anomalous event helper class. + * Keeps track of the node that caused the anomaly, the rule + * which was affected, and the time the anomaly occurred. + **/ + public static class AnomalousEvent { + public Node node; + public Rule rule; + public long time; + AnomalousEvent(Node n, Rule r, long t) { + node = n; + rule = r; + time = t; + } + } + /** AnomalousEvent for an interference event **/ + private AnomalousEvent interferenceEvent = null; + /** AnomalousEvent for a glitch event **/ + private AnomalousEvent glitchEvent = null; + /** AnomalousEvent for an instability event **/ + private AnomalousEvent unstabEvent = null; + + /** + * The version of cast being used. + **/ + private String castVersion; + /** + * Whether or not to create asserted production rules as well as + * synthesizable ones when instantiating cells. + **/ + private boolean handleAsserts = true; + + /** + * Contains disjuncts of production rules that are specified in unsued_prs + * directives, indexed by the targets of the production rules. + **/ + private final Map/*>*/ + possiblyUnusedRules = + new HashMap/*>*/(); + + /** + * Contains annotation from signoff_constant directives. + **/ + private final Map/**/ constantNodes = + new HashMap/**/(); + + /** + * Set of cells for which a warning about delay bias and after has + * been issued. + **/ + private final Set warnedCells = new HashSet(); + + /** + * possibilities for randomOrder. + *

    + * NO_RANDOM, just use delay. + *

    + * UNTIMED_RANDOM -- "timed" rules fire with variable delay. Untimed rules + * fire arbitrarily in between. + *

    + * TIMED_RANDOM -- all rules have delay between delay*fastDelay and + * delay*slowDelay + * + * @see #randomOrder + **/ + public static final int NO_RANDOM = 0, UNTIMED_RANDOM = 1, TIMED_RANDOM = 2; + static final int VARIABLE_DELAY = TIMED_RANDOM; + + private static final String RESET_BODY_SUFFIX = ":body"; + private static final String RESET_ENV_SUFFIX = ":env"; + private static final float RESET_SLEW = 693; // see bug 18611 + + class MeasuredDelay { + class Data { + private double extraDelay; + private Pair[] data; + public Data(final double extraDelay, final Pair[] data) { + this.extraDelay = extraDelay; + this.data = data; + } + public boolean equals(final Object o) { + if (o instanceof Data) { + final Data d = (Data) o; + return extraDelay == d.extraDelay && + Arrays.equals(data, d.data); + } + return false; + } + public Pair[] getData() { + return data; + } + public double getExtraDelay() { + return extraDelay; + } + } + + private final HierName prefix; + private final HierName instance; + private final CellInterface cell; + private final Map,Data> measured; + private final Map portMap; + private final double delayBias; + public MeasuredDelay(final HierName prefix, + final HierName instance, + final CellInterface cell, + final double delayBias) { + this.prefix = prefix; + this.instance = instance; + this.cell = cell; + this.measured = new TreeMap,Data>( + new Comparator>() { + public int compare(Pair p1, + Pair p2) { + int x = p1.getFirst().getName().compareTo( + p2.getFirst().getName()); + if (x == 0) { + x = p1.getSecond().compareTo(p2.getSecond()); + } + return x; + } + }); + this.portMap = new HashMap(); + this.delayBias = delayBias; + } + private String printDirective(final Triplet[] values) { + if (values == null) { + return "null"; + } else { + final StringBuilder sb = new StringBuilder(); + for (Triplet value : values) { + sb.append(value.getFirst() + "/" + value.getSecond()); + sb.append(" "); + } + return sb.toString(); + } + } + public double getDelayBias() { + return delayBias; + } + public void addMeasured( + final Node node, + final HierName port, + final boolean up, + final Triplet[] values, + final Double extraDelay, + final Collection procs) { + final Pair key = new Pair(node, up); + final Data old = measured.get(key); + final Data curr = + values == null ? null + : new Data(extraDelay, + ProcessMeasuredDelay.update( + prepareData(key, values), + procs)); + measured.put(key, curr); + assert old == null || old.equals(curr) : key + " different data"; + portMap.put(node, port); + } + public Map,Data> getMeasured() { + return measured; + } + private Pair[] prepareData(final Pair key, final Triplet[] data) { + final LinkedList result = new LinkedList(); + for (Triplet t : data) { + final HierName prefix = (HierName) t.getFirst(); + final HierName trigger = (HierName) t.getSecond(); + if (trigger == null) { + result.addLast(new Pair(null, t.getThird())); + } else { + final HierName fullName = HierName.append(prefix, trigger); + Node node = findNode(fullName); + if (node == null) { + node = createNode(fullName); + } + result.addFirst(new Pair(node, t.getThird())); + } + } + return (Pair[]) result.toArray(new Pair[0]); + } + public HierName getPrefix() { + return prefix; + } + public HierName getInstance() { + return instance; + } + public CellInterface getCell() { + return cell; + } + private HierName getSuffix(final HierName name, + final HierName prefix) { + if (name.isChildOf(prefix)) { + return name.tail(prefix.getNumComponents()); + } else { + return null; + } + } + public HierName getPort(final Node node) { + return portMap.get(node); + } + public void getContext(Map contexts) { + if (instance == null) return; + final Set checkAliases = new HashSet(); + final HierName fullPrefix = HierName.append(prefix, instance); + for (Data data : measured.values()) { + if (data != null) { + final Pair[] ps = data.getData(); + for (Pair p : ps) { + final Node node = (Node) p.getFirst(); + final HierName suffix = getSuffix(node.getName(), + fullPrefix); + if (suffix != null) { + contexts.put(node, suffix); + } else { + checkAliases.add(node); + } + } + } + } + final MultiMap aliases = + generateNodeToAliases(checkAliases); + for (Node key : aliases.keySet()) { + Collection names = aliases.get(key); + boolean found = false; + for (HierName name : names) { + final HierName suffix = getSuffix(name, fullPrefix); + if (suffix != null) { + contexts.put(key, suffix); + found = true; + break; + } + } + if (!found) { + contexts.put(key, null); + } + } + } + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Prefix: " + prefix + "\n"); + sb.append("Instance: " + instance + "\n"); + sb.append("Cell: " + cell.getFullyQualifiedType() + "\n"); + sb.append("Measured: "); + sb.append(measured.keySet().toString()); + return sb.toString(); + } + } + + private Collection boundaryDelays = + new ArrayList(); + private Collection interiorOutputPorts = Collections.emptyList(); + private MultiMap routedInstancesByType = null; + + private DSim( SearchPath cFSP, ClassLoader deviceLoader ) { + this.m_CastFileSearchPath = cFSP; + this.cachedCastFileParser = null; + this.fileCacheEnabled = false; + Debug.assertTrue( deviceLoader != null ); + this.m_DeviceLoader = deviceLoader; + this.castVersion = null; + } + + /** Returns the singleton instance of the simulator. **/ + public static synchronized DSim get() { + if (singleton == null) { + singleton = new DSim(new FileSearchPath("."), + DSim.class.getClassLoader()); + } + return singleton; + } + + /** + * @throws IllegalStateException + * If the cast version has already been set. + **/ + public void setCastVersion( String castVersion ) { + if (this.castVersion == null) { + Debug.assertTrue(castVersion != null); + this.castVersion = castVersion; + System.out.println("Setting cast version to " + castVersion); + } else { + throw new + IllegalStateException("You can only set the cast version once."); + } + } + + public void setDeviceLoader(ClassLoader deviceLoader) { + m_DeviceLoader = deviceLoader; + } + + public void setCastPath(SearchPath castPath) { + m_CastFileSearchPath = castPath; + } + + public void setArgs(CommandLineArgs theArgs) { + m_theArgs = theArgs; + } + + public void setCosimSlack(final int cosimSlack) { + if (cosimSlack <= 0) { + throw new IllegalArgumentException( + "Cannot set cosim slack to non-positive number: " + cosimSlack); + } + this.cosimSlack = cosimSlack; + } + + /** + * Enables caching of parsed files, ASTs and CellImpls. + * Changes to the files will not be detected. Pretty much useful + * only for the RTE. + **/ + public void enableFileCache() { + fileCacheEnabled = true; + } + + /** + * Enables caching of parsed files, ASTs and CellImpls using + * the specified CastFileParser. Changes to the files will not be + * detected. Pretty much useful only for the RTE. + **/ + public void enableFileCache(final CastFileParser cfp) { + enableFileCache(); + cachedCastFileParser = cfp; + } + + /** + * Disables caching of parsed files, ASTs and CellImpls. + **/ + public void disableFileCache() { + fileCacheEnabled = false; + } + + /** + * If cache is enabled, flush it. + **/ + public void flushFileCache() { + cachedCastFileParser = null; + } + + /** + * Returns true if the file cache has been enabled with + * {@link #enableFileCache}, and has not been subsequently + * disabled with {@link #disableFileCache}. + **/ + public boolean isFileCacheEnabled() { + return fileCacheEnabled; + } + + private CastFileParser newFileParser() + throws CastSemanticException, + CastSyntaxException, + IOException { + final CastParsingOption opt = + m_theArgs == null ? CastParsingOption.DEFAULT + : new StandardParsingOption(m_theArgs); + return new CastFileParser(m_CastFileSearchPath, castVersion, opt); + } + + /** + * Returns the cached cast file parser if there is one, otherwise + * returns a new one. This method will store the new parser if + * caching is enabled. + **/ + private CastFileParser getCastFileParser() + throws CastSemanticException, + CastSyntaxException, + IOException { + if (fileCacheEnabled) { + if (cachedCastFileParser== null) { + cachedCastFileParser = newFileParser(); + } + return cachedCastFileParser; + } else { + return newFileParser(); + } + } + + /** Has DSim been activated? **/ + public static boolean activated() { + return singleton != null; + } + + /** + * Can be called at any time and affects all instantiations until + * the next time it's set. If assert handling is on, + * instantiating a cell digitally will create both its + * synthesizable production rules and its asserted production + * rules. If it's off, only the synthesizable rules will be + * created. + **/ + public void setAssertHandling(boolean handleAsserts) { + this.handleAsserts = handleAsserts; + } + + /** Get current state of handleAsserts. **/ + public boolean getAssertHandling() { + return handleAsserts; + } + + /** Set cell as the name of the cell under test and + ** name as the name of the environment to use. **/ + private void setEnv(String cell, String name) { + if (verbose) { + System.out.println("Setting environment for "+cell+" to "+name); + } + envName = name; + envCell = HierName.makeHierName(cell); + } + + /** Loads file name and convert it into nodes and rules **/ + public void loadFile(String name) throws CastSyntaxException, + CastSemanticException, IOException, NoSuchEnvironmentException { + // Runtime r = Runtime.getRuntime(); + CastFileParser p = getCastFileParser(); + loadedFile = p.parse(name); + CellInterface c = loadedFile.getEnvironmentCell(); + p = null; + + System.out.println("Parsed."); + System.gc(); + + instantiate(c, null); + } + + public void cosimulate( + final String cellType, + final String instanceName, + final CoSimSpecList coSimSpecList, + final String envName, + final String envInstanceName, + final CoSimSpec envCoSimSpec) + throws IOException, + CastSemanticException, + CastSyntaxException, + DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchCellException, + NoSuchEnvironmentException, + NoSuchInstanceException { + cosimulate(cellType, instanceName, coSimSpecList, envName, + envInstanceName, envCoSimSpec, new CoSimParameters()); + } + + /** + * Cosimulates the cell cellType in the presence of the + * environment envName. + * (See the + * Cosimulation UI Specification. + * for the meaning of the rules.) + * + * @param cellType The type of cell to be cosimulated. + * May not be null. + * @param instanceName The name as which the cell should be + * instantiated. May not be null. + * @param coSimSpecList Specifies how the cell is to be + * cosimulated. + * @param envName Environment in which to cosimulate the cell. + * May not be null. + * @param envInstanceName The name as which the cell's environment + * should be instantiated. May not be null. + * @param envCoSimSpec Specifies how the environment is to be + * simulated. + * + * @throws IOException If a needed cast file is not found or some + * other I/O error occurs. + * @throws CastSemanticException If there is a semantic error in a + * cast file. + * @throws CastSyntaxException If there is a syntax error in a cast + * file. + * @throws NoSuchCellException If a definition for cellType + * cannot be found. + **/ + public void cosimulate( + final String cellType, + final String instanceName, + final CoSimSpecList coSimSpecList, + final String envName, + final String envInstanceName, + final CoSimSpec envCoSimSpec, + final CoSimParameters coSimParams) + throws IOException, + CastSemanticException, + CastSyntaxException, + DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchCellException, + NoSuchEnvironmentException, + NoSuchInstanceException { + CastFileParser cfp = null; + // get the cell + final CellInterface cell; + if (cellType.indexOf('.') == -1) { + if (loadedFile == null) + throw new NoSuchCellException(cellType); + cell = loadedFile.getCell(cellType); + } else { + cfp = getCastFileParser(); + cell = cfp.getFullyQualifiedCell(cellType); + } + cellName = cellType; + + if (cell == null) + throw new NoSuchCellException(cellType); + + // XXX: need to handle fragments in some way!!! + + // TODO: flip all this around so we call + // coSimSpecList.setCoSimParams(instanceName, cell, coSimParams) + // Make cosim.spec.* implement some interface to enforce this + + // set up CoSimParameters as specified + CoSimHelper.setCoSimParams(instanceName, cell, coSimSpecList, + coSimParams, null, verbose); + + // Set the environment name + setEnv(instanceName, envName); + + // set the behavior for envInstanceName as specified + if (envName != null) { + CoSimHelper.setCoSimParams( + envInstanceName, getEnvironmentBlock(cell), envCoSimSpec, + coSimParams, null, verbose); + } + + // instantiate cell + instantiateByName(cellType, instanceName, coSimParams, cfp); + } + + public CellInterface getCell() throws CastSemanticException, + CastSyntaxException, + IOException { + return getCastFileParser().getFullyQualifiedCell(cellName); + } + + /** Make a synthetic environment cell containing 'inside' and having the + ** same ports as 'parent'. **/ + private CellInterface makeSyntheticEnv(final CellInterface inside, + final CellInterface parent, + final HierName parentName, + AliasedSet nodeAliases) { + final CellImpl outside = + new CellImpl("$Synth", null, CellImpl.SYNTHETIC_CELL); + final HierName env = HierName.makeHierName("_env"); + EnvironmentAliases envAliases = + new EnvironmentAliases(parentName, nodeAliases); + outside.addSubcellPair(env, inside, false); + outside.setHasCompleteSubcellsBlock(); + + /* For each of parent's ports, we add a port to inside. */ + final Iterator it = parent.getPortSubcellPairs(); + while (it.hasNext()) { + /* Alias parentName.name to _env.name */ + final Pair p = (Pair)it.next(); + final CellInterface ci = (CellInterface)p.getSecond(); + final HierName name = (HierName)p.getFirst(); + if (name.equals(resetPortName)) { + envAliases.aliasCell(ci, HierName.makeHierName(env, name), + resetNodeName.appendString(RESET_ENV_SUFFIX)); + } else { + envAliases.aliasCell(ci, HierName.makeHierName(env, name), + HierName.makeHierName(parentName, name)); + } + } + + return outside; + } + + class EnvironmentAliases { + final HierName instanceName; + AliasedSet nodeAliases; + + EnvironmentAliases(HierName name, AliasedSet nodeAliases) { + instanceName = name; + this.nodeAliases = nodeAliases; + } + + void makeConnection(final HierName n1, final HierName n2) { + // System.out.println("Aliasing nodes " + n1 + " and " + n2); + nodeAliases.makeEquivalent(n1, n2); + } + + void aliasCell(CellInterface c, HierName n1, HierName n2) { + Iterator it = c.getSubcellPairs(); + if (!it.hasNext()) { + if (c.isNode()) { + /* Node, add alias */ + + // Equivalent of getting the default values for the + // implied global ports, but a HACK. + if (n2.isGlobal()) { + n2 = HierName.trim(n2); + } + + makeConnection(n1, n2); + } else { + System.out.println("Non-node leaf cell in environment!"); + System.out.println(c.getFullyQualifiedType() + ": " + n1); + } + } else { + while (it.hasNext()) { + final Pair p = (Pair)it.next(); + final CellInterface ci = (CellInterface)p.getSecond(); + final HierName name = (HierName)p.getFirst(); + aliasCell(ci, HierName.makeHierName(n1, name), + HierName.makeHierName(n2, name)); + } + } + } + } + + /** clear all the TCounts for all the nodes in the simulation **/ + public void clear_tcounts() { + for (Node node : nodes.values()) { + node.clearTCount(); + } + } + + /** Return the total number of transition counts for all the nodes in the + * simulation. **/ + public long tcounts_total() { + final Set seen = new HashSet(); + long sum = 0; + for (Node node : nodes.values()) { + if (seen.add(node.getName())) sum += node.getTCount(); + } + return sum; + } + + + /* + @deprecated Need better reset scheme for devices. + */ + public void clearEventQueues() { + sched.clearEventQueues(); + } + + /** Get rid of an instantiation **/ + public void rm_instantiation(){ + /** reset class data members set during instantiation **/ + envName = null; + envCell = null; + resetPortName = null; + resetNodeName = null; + loaded = false; + loadedFile = null; + glitchEvent = null; + interferenceEvent = null; + unstabEvent = null; + // clear history buffer, but still record same amount of history + if (history != null) { + history = new HistoryStore(history.capacity()); + } + nodeCount = 0; + + /** remove all the watches associated with a given node **/ + + for(Iterator i=nodes.values().iterator(); i.hasNext(); ) { + Node node = (Node)i.next(); + node.removeAllWatchers(); + } + nodesToAliases = null; + nodes.clear(); + rules.clear(); + nonAssertedRuleCount = 0; + ERRORHandlingDoneYet = false; + sched.clear(); + warnedCells.clear(); + constantNodes.clear(); + possiblyUnusedRules.clear(); + canonNodeNameToWatchedNodeNameMap.clear(); + measuredProcs.clear(); + measuredWarningContext = null; + CspRuntimeAbstractDevice.clearAllCspDevices(); + boundaryDelays = new ArrayList(); + interiorOutputPorts = Collections.emptyList(); + routedInstancesByType = null; + astaContext = null; + savedCadenceInfo = null; + savedOptCandidate = null; + slintIgnores.clear(); + /** garbage collect here **/ + System.gc(); + } + + /** + * Sets up node ERROR (if it doesn't already exist) and rules + * driving it from GND and Vdd. This ensures that GND and Vdd, + * even if they aren't used for anything else, will be available + * for reset. + * + * XXX: This might need to be split up so that the ERROR node is + * created before the aliases are saved. + **/ + private void createERRORHandling() { + createNode(HierName.makeHierName("ERROR")); + + final HierName gndName = HierName.makeHierName("GND"); + final HierName vddName = HierName.makeHierName("Vdd"); + final HierName errorName = HierName.makeHierName("ERROR"); + final Node target = lookupNode(errorName); + + // GND => ERROR+ + createHierRule(new HierNameAtomicBooleanExpression(false, gndName), + target, ProductionRule.DOWN, 100, DIGITAL_TAU, false, + false, false, true, null, null, Float.NaN, null, true, + null); + createHierRule(new HierNameAtomicBooleanExpression(true, gndName), + target, ProductionRule.UP, 100, DIGITAL_TAU, false, + false, false, true, null, null, Float.NaN, null, true, + null); + + // Vdd => ERROR- + createHierRule(new HierNameAtomicBooleanExpression(true, vddName), + target, ProductionRule.DOWN, 100, DIGITAL_TAU, false, + false, false, true, null, null, Float.NaN, null, true, + null); + createHierRule(new HierNameAtomicBooleanExpression(false, vddName), + target, ProductionRule.UP, 100, DIGITAL_TAU, false, + false, false, true, null, null, Float.NaN, null, true, + null); + + ERRORHandlingDoneYet = true; + } + + private void createResetFork(boolean includeEnv) { + createNode(resetNodeName); + + // _RESET => _RESET:body+ + final Node body = + lookupNode(resetNodeName.appendString(RESET_BODY_SUFFIX)); + createHierRule( + new HierNameAtomicBooleanExpression(false, resetNodeName), + body, ProductionRule.DOWN, 100, DIGITAL_TAU, false, + false, false, true, null, null, RESET_SLEW, null, true, + null); + createHierRule( + new HierNameAtomicBooleanExpression(true, resetNodeName), + body, ProductionRule.UP, 100, DIGITAL_TAU, false, + false, false, true, null, null, RESET_SLEW, null, true, + null); + + if (!includeEnv) return; + + // _RESET => _RESET:env+ + final Node env = + lookupNode(resetNodeName.appendString(RESET_ENV_SUFFIX)); + createHierRule( + new HierNameAtomicBooleanExpression(false, resetNodeName), + env, ProductionRule.DOWN, 100, DIGITAL_TAU, false, + false, false, true, null, null, RESET_SLEW, null, true, + null); + createHierRule( + new HierNameAtomicBooleanExpression(true, resetNodeName), + env, ProductionRule.UP, 100, DIGITAL_TAU, false, + false, false, true, null, null, RESET_SLEW, null, true, + null); + } + + /** + * Create dummy rules to simulate behavior of the environment to check for + * short cutoff paths. On input e1ofN channels, create rules from enable + * to data; on output e1ofN channels, create rules from data to enable. + **/ + private void createCutoffRules(final CellInterface cell, + final int enableToData, + final int dataToEnable, + final HierName prefix) { + (new CellUtils.MarkPort() { + private void addRule(final Node trigger, final boolean negated, + final Node target, final int count) { + if (count > 0) { + final int dir = + (count % 2 == 0) ^ negated ? ProductionRule.DOWN + : ProductionRule.UP; + createHierRule( + new HierNameAtomicBooleanExpression( + negated, trigger.getName()), + target, dir, count * 100, DIGITAL_TAU, false, false, + false, false, null, null, RESET_SLEW, null, true, null); + } + } + protected void mark(final ChannelType channelType, + final String name, + final int direction) { + final int rails = CellUtils.extractN(channelType.getTypeName()); + final Node e = + lookupNode(HierName.append(prefix, toHier(name + ".e"))); + for (int i = 0; i < rails; ++i) { + final Node d = lookupNode( + HierName.append(prefix, toHier(name + ".d[" + i + "]"))); + if (direction < 0) { + if (enableToData > 0) { + addRule(e, false, d, enableToData); + addRule(e, true, d, enableToData); + } + } else { + if (dataToEnable > 0) { + addRule(d, false, e, dataToEnable); + addRule(d, true, e, dataToEnable); + } + } + } + } + }).mark(cell); + } + + private static HierName toHier(final String x) { + try { + return HierName.makeHierName(x, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot create HierName from: " + x); + } + } + + private void aliasExtraPorts(final CellInterface env, + final HierName envPrefix, + final HierName cutPrefix, + final AliasedSet nodeAliases) { + for (Iterator i = env.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition port = (PortDefinition) i.next(); + final String mapped = env.getEnvExtraPortMapping(port.getName()); + if (mapped != null) { + final HierName parent = + HierName.append(cutPrefix, toHier(mapped)); + (new CellUtils.MarkPort() { + protected void mark(final NodeType nodeType, + final String name, + final int direction) { + final HierName node = toHier(name); + final String part = + name.substring(port.getName().length()); + final HierName cutNode = toHier( + StringUtil.replaceSubstring(parent + part, "][", + ",")); + if (nodeAliases.contains(cutNode)) { + final HierName envNode = + HierName.append(envPrefix, node); + nodeAliases.makeEquivalent(cutNode, envNode); + } else { + System.err.println("warning: can't connect " + + "extra port " + name + " to " + cutNode); + } + } + }).mark(Collections.singletonList(port).iterator(), null, + PortDefinition.FORWARD); + } + } + } + + static Triplet localize(final HierName name) + { + return CellUtils.localize(name, get().savedCadenceInfo, true); + } + + public static HierName canonize(final HierName name, + final CadenceInfo ci) { + final AliasedSet localNodes = ci.getLocalNodes(); + HierName canon = (HierName) localNodes.getCanonicalKey(name); + if (canon == null) { + HierName head = null; + for (HierName h = name; h != null; h = h.tail()) { + head = HierName.append(head, h.head()); + final CadenceInfo subci = ci.getSubcell(head); + if (subci != null) { + final HierName subcanon = canonize(h.tail(), subci); + if (subcanon != null) { + final HierName full = HierName.append(head, subcanon); + canon = (HierName) localNodes.getCanonicalKey(full); + if (canon == null) canon = full; + } + break; + } + } + } + return canon; + } + + + /** Does the actual instantiation for loadFile and loadStream **/ + public void instantiate(CellInterface c, CoSimParameters params) + throws NoSuchEnvironmentException { + AliasedSet nodeAliases = new AliasedSet(HierName.getComparator()); + CellInterface synth = null; + CellInterface envblock = null; + final CellInterface cut = c.getSubcell(envCell); + /* One of the immediate subcells should be the CUT if an environment + * name is specified. */ + if (envName != null) { + if (cut == null) + throw new IllegalArgumentException(envCell + " not found"); + envblock = getEnvironmentBlock(cut); + synth = makeSyntheticEnv(envblock, cut, envCell, nodeAliases); + System.out.print("Collecting envblock aliases "); + new DSimCellTraverser(new AliasCreator(nodeAliases), params). + traverseCell(synth); + new PortNodesTraverser(params, nodeAliases).traverse(synth); + System.out.println("Done."); + } + System.out.print("Collecting aliases "); + new DSimCellTraverser(new AliasCreator(nodeAliases), params). + traverseCell(c); + new PortNodesTraverser(params, nodeAliases).traverse(c); + if (envblock != null) { + aliasExtraPorts(envblock, toHier("_env"), envCell, nodeAliases); + } + System.out.println(" Done."); + System.gc(); + System.out.print("Instantiating nodes..."); + saveAliases(nodeAliases); + nodeAliases = null; + System.out.println(" Done."); + System.gc(); + if (! ERRORHandlingDoneYet) createERRORHandling(); + if (resetNodeName != null) createResetFork(envName != null); + + // adding dummy production rules to model environment for cutoff + final int cutoffEnableToData = + (int) getDouble("cutoff.enableToData", -1); + final int cutoffDataToEnable = + (int) getDouble("cutoff.dataToEnable", -1); + if (cutoffEnableToData > 0 || cutoffDataToEnable > 0) { + if (verbose) { + System.out.println("Adding cutoff environment rules..."); + } + createCutoffRules(cut, cutoffEnableToData, cutoffDataToEnable, + envCell); + } + + if (useDelayMode(MEASURED_TAU)) prepareMeasured(); + System.out.print("Applying models "); + + final String candidateFqcn = getParameter("asta.candidate"); + final boolean astamizer = isAstaEnabled() && candidateFqcn != null; + + final Cadencize cadencizer = new Cadencize(false); + errors = false; + final ModelCreator creator = new ModelCreator(params, cadencizer, + astamizer ? new HashSet() : null); + errors |= creator.build(c, CoSimParameters.DIGITAL, null, false); + if (astamizer) { + interiorOutputPorts = creator.getInteriorPorts(c); + } + if (synth != null) + errors |= new ModelCreator(params, cadencizer).build(synth, + CoSimParameters.DIGITAL, null, + true); + if (astamizer) { + try { + final CellInterface candidate = getCastFileParser().getFullyQualifiedCell(candidateFqcn); + errors |= new OptimizeThresholdCreator(params, cadencizer).build(candidate, CoSimParameters.DIGITAL, envCell, true); + savedOptCandidate = SimpleCell.convert(candidate); + } catch (Exception e) { + System.err.print("Failed to parse cell specified by asta.candidate: "); + if (e instanceof CastSemanticException) { + System.err.println(); + ExceptionPrettyPrinter.printException( + (CastSemanticException) e, System.err); + } else { + System.err.println(e.getMessage()); + } + } + } + + System.out.print(" Done"); + if (errors) + System.out.print(", with errors"); + System.out.println('.'); + System.gc(); + // System.out.println("Mem free = " + r.freeMemory() + "/" + r.totalMemory()); + loaded = true; + } + + private class DSimCellTraverser { + final JFlat.CellProcessor proc; + final CoSimParameters params; + + public DSimCellTraverser(final JFlat.CellProcessor p, + final CoSimParameters params) { + proc = p; + this.params = params; + } + + public void traverseCell(final CellInterface cell) { + traverseIter(null, cell, 0); + } + + private void traverseIter(final HierName prefix, + final CellInterface cell, final int depth) { + proc.process(prefix, cell, null, depth, null); + + for (Iterator i = cell.getAllSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + HierName fullName = HierName.append(prefix, subcellName); + final int behavior = (params == null) ? CoSimParameters.DIGITAL : + params.lookupBehavior(CoSimParameters.stripCoSimDigitalSuffix(fullName)); + + if (subcell.isNode()) + continue; + + if ((behavior != CoSimParameters.UNSPEC) && + (behavior != CoSimParameters.DIGITAL)) + traversePorts(fullName, subcell, depth+1); + + if (((behavior & CoSimParameters.DIGITAL) != 0) && + (behavior != CoSimParameters.DIGITAL)) { + fullName = CoSimParameters.addCoSimDigitalSuffix(fullName); + } + + if ((behavior == CoSimParameters.UNSPEC) || + ((behavior & CoSimParameters.DIGITAL) != 0)) + traverseIter(fullName, subcell, depth+1); + } + } + + private void traversePorts(final HierName prefix, + final CellInterface cell, final int depth) { + for (Iterator i = cell.getPortSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final HierName fullName = HierName.append(prefix, subcellName); + + traverseIter(fullName, subcell, depth+1); + } + } + } + + /** Traverse cells, setting up the correct aliases for the port nodes + ** which are co-simulated. **/ + private class PortNodesTraverser { + private final CoSimParameters params; + AliasedSet aliasSet; + + PortNodesTraverser(final CoSimParameters params, AliasedSet aliasSet) { + this.params = params; + this.aliasSet = aliasSet; + } + + public void traverse(CellInterface c) { + traverseIter(null, c, 1); + } + + private void traverseIter(final HierName prefix, + final CellInterface cell, + final int currentDepth) { + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + HierName fullName = HierName.append(prefix, subcellName); + final int behavior = (params == null) ? CoSimParameters.DIGITAL : + params.lookupBehavior(CoSimParameters.stripCoSimDigitalSuffix(fullName)); + + if (subcell.isNode()) + continue; + + if (((behavior & CoSimParameters.DIGITAL) != 0) && + (behavior != CoSimParameters.DIGITAL)) { + HierName cosimName = + CoSimParameters.addCoSimDigitalSuffix(fullName); + process(fullName, cosimName, subcell); + fullName = cosimName; + } + + if ((behavior == CoSimParameters.UNSPEC) || + ((behavior & CoSimParameters.DIGITAL) != 0)) + traverseIter(fullName, subcell, currentDepth+1); + } + } + + /** Alias all port nodes between the prefix and cosimName's **/ + private void process(final HierName prefix, final HierName cosimName, + final CellInterface cell) { + (new CellUtils.MarkPort() { + private boolean flatten = false; + protected void mark(final StructureType structureType, + final String name, final int direction) { + final boolean isDft = + !flatten && + CellUtils.isDftChannel(cell, structureType.getTag()); + + if (isDft) flatten = true; + super.mark(structureType, name, direction); + if (isDft) flatten = false; + } + protected void mark(final ChannelType channelType, + final String name, final int direction, + final boolean inArray) { + boolean descend = flatten; + + if (!descend) { + try { + descend = CellUtils.extractN( + channelType.getTypeName()) < 1; + } catch (NumberFormatException e) { + descend = true; + } + } + + if (descend) { + super.mark(channelType, name, direction, inArray); + } + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + HierName nodenm; + try { + nodenm = HierName.makeHierName(name, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot create HierName from" + + name); + } + if (nodenm.isGlobal()) + nodenm = HierName.trim(nodenm); + aliasSet.makeEquivalent( + HierName.append(prefix, nodenm), + HierName.append(cosimName, nodenm)); + } + }).mark(cell); + } + } + + /** Given the CellInterface ci containing the subcell named envCell, return + ** its environment block of the name envName. **/ + private CellInterface getEnvironmentBlock(final CellInterface ci) + throws NoSuchEnvironmentException { + return ci.getEnvironment(envName); + } + + /** Instantiate a cell of the given name defined in the loaded cast file **/ + public void instantiateByName(String cellName, + String instanceName, + CoSimParameters params, + CastFileParser castParser) + throws CastSemanticException, + CastSyntaxException, + IOException, + NoSuchCellException, + NoSuchEnvironmentException { + final CellImpl fakeEnv = + new CellImpl("fake", null, CellImpl.SYNTHETIC_CELL); + CellInterface ci = null; + + final HierName instance; + try { + instance = HierName.makeHierName(instanceName, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError(e); + } + + //If the cell name is fully qualified then + //use a cast file parser to get a CellInterface. + if ( cellName.lastIndexOf( '.' ) >= 0 ) { + if (castParser == null) + castParser = getCastFileParser(); + + // do not pass in fakeEnv to avoid pollution caused by automatic + // inlining + ci = castParser.getFullyQualifiedCell(cellName, null, instance); + + EnvironmentAliases envAliases = + new EnvironmentAliases(instance, null) { + void makeConnection(final HierName n1, final HierName n2) { + fakeEnv.addConnection(n1, n2); + } + }; + + // create implied port connections from ci to fakeEnv + final Map connections = + new HashMap(); + HierName upperReset = null, lowerReset = null; + for (Iterator i = ci.getPortSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName hinst = (HierName) p.getFirst(); + final String sinst = hinst.getAsString('.'); + if (ci.isImpliedPort(sinst)) { + final HierName parent; + try { + parent = + HierName.makeHierName( + ci.getParentImpliedPort(sinst), '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError(e); + } + if (parent.equals(DSimUtil._RESET_NAME)) upperReset = hinst; + if (parent.equals(DSimUtil._Reset_NAME)) lowerReset = hinst; + connections.put(hinst, parent); + } + } + + resetPortName = + upperReset == null ? (lowerReset == null ? null : lowerReset) + : upperReset; + + if (resetPortName != null) { + resetNodeName = connections.get(resetPortName); + connections.put(resetPortName, + resetNodeName.appendString(RESET_BODY_SUFFIX)); + } + + for (Map.Entry entry : connections.entrySet()) { + final HierName hinst = entry.getKey(); + final HierName parent = entry.getValue(); + final CellInterface subci = ci.getSubcell(hinst); + fakeEnv.addSubcellPair(parent, subci, false); + envAliases.aliasCell(subci, parent, + HierName.makeHierName(instance, hinst)); + } + } else { + //If the cell name was not a fully qualified cell name + //we'll look in the loaded file for the cell. + if (loadedFile != null) + ci = loadedFile.getCell(cellName, fakeEnv, instance); + } + + if (ci == null) + throw new NoSuchCellException(cellName); + + fakeEnv.addSubcellPair( instance, ci, false ); + fakeEnv.setHasCompleteSubcellsBlock(); + + instantiate( fakeEnv, params ); + + if (verbose) { + System.out.println("envCell is " + envCell + + ". instanceName is " + instanceName + "."); + } + } + + private void createHierRule(AndBooleanExpressionInterface term, Node n, + int direction, int delay, byte delay_type, + boolean timed, boolean isochronic, + boolean absoluteDelay, boolean assertedP, + Pair[] delays, + HierName prefix, float defaultSlew, + AliasedSet localNodes, + final boolean coverage_ignore, + final Map,BitSet>, + Rule> astaGrayboxRules) { + final LinkedList measuredDelay = + delays == null ? null : new LinkedList(); + + byte coverage_requirement = (coverage_ignore ? Rule.IGNORE_COVERAGE : + Rule.MUST_BE_COVERED); + + int length = term.getConjuncts().size(); + Iterator i = term.getConjuncts().iterator(); + int j = 0; + int sense [] = new int[length]; + Node guards [] = new Node[length]; + boolean defaultDelay = false; + final Set possiblyUnused = (Set) possiblyUnusedRules.get(n.getName()); + final Collection prefixedGuards; + if (possiblyUnused == null) { + prefixedGuards = null; + } else { + prefixedGuards = new ArrayList(length); + } + while (i.hasNext()) { + HierNameAtomicBooleanExpression a; + a = (HierNameAtomicBooleanExpression) i.next(); + final HierName h = a.getName(); + + final HierName fullName = prefixName(prefix, h); + guards[j] = lookupNode(fullName); + guards[j].setSlew(defaultSlew); + sense[j] = a.getSense() ? 1 : 0; + if (prefixedGuards != null) + prefixedGuards.add(new HierNameAtomicBooleanExpression( + a.getSense(), guards[j].getName())); + + if (delays != null) { + for (int k = 0; k < delays.length; ++k) { + final Node trigger = (Node) delays[k].getFirst(); + if (trigger == null) { + if (!defaultDelay) { + measuredDelay.addLast(new Pair(null, delays[k].getSecond())); + defaultDelay = true; + } + } else if (guards[j].equals(trigger)) { + measuredDelay.addFirst(new Pair(guards[j], delays[k].getSecond())); + } + } + } + j++; + } + + // if this has been declared unused by an unused_prs directive, ignore + // it for coverage purposes + if (prefixedGuards != null) { + final AndBooleanExpression and = + new AndBooleanExpression(term.getSense(), prefixedGuards); + if (possiblyUnused.remove(and)) + coverage_requirement = Rule.MUST_NOT_BE_COVERED; + } + + final Rule newrule = + new Rule(guards, sense, n, direction, delay, delay_type, timed, + isochronic, + absoluteDelay, assertedP, + measuredDelay == null ? null : + (Pair[]) measuredDelay.toArray(new Pair[0]), + coverage_requirement, prefix); + if (isAstaEnabled() && !assertedP && astaGrayboxRules != null) { + // collapse grayboxed rules + newrule.falseConjuncts = 1; + if (n.enabler != null) { + // make sure all nodes are involved in grayboxing + boolean grayboxed = true; + for (Node guard : guards) { + if (guard.enabler == null) { + grayboxed = false; + break; + } + } + if (grayboxed) { + // guards + target + final List g = new ArrayList(guards.length + 1); + // senses of guards and target + final BitSet s = new BitSet(guards.length + 1); + + for (int k = 0; k < guards.length; ++k) { + g.add((Node) guards[k].enabler); + s.set(k, sense[k] == 1); + } + g.add((Node) n.enabler); + s.set(guards.length, direction == 1); + + // increment instance count (stored in the falseConjuncts + // field of Rule) of an existing rule, or store a new rule + final Pair,BitSet> key = + new Pair,BitSet>(g, s); + final Rule oldrule = astaGrayboxRules.get(key); + if (oldrule == null) { + astaGrayboxRules.put(key, newrule); + } else { + oldrule.falseConjuncts++; + newrule.falseConjuncts = 0; + newrule.setCanonRule(oldrule); + } + } + } + } + rules.add(newrule); + if (!assertedP) nonAssertedRuleCount++; + // System.out.println("Adding rule " + newrule.getGuardList()); + } + + private HierName prefixName(HierName prefix, HierName suff) { + return (castVersion.equals("1")) ? HierName.prefixName(prefix, suff) + : HierName.append(prefix, suff); + } + + /** Remove terminal '!'s (global signals). **/ + public HierName stripGlobals(HierName h) { + if (h.isGlobal()) + return HierName.trim(h); + else + return h; + } + + /** Looks up a node in our node map. Due to a bug in the parser, creates unfound nodes. **/ + private Node lookupNode(HierName h) { + //String name = sanitizeName(h); + //Object lookup = nodes.getDigitalNode(name); + h = stripGlobals(h); + Object lookup = nodes.get(h); + if (lookup==null) { + //throw new NoSuchElementException("No Node: "+name); + //System.err.println("Warning implicitly created node: "+name); + return createNode(h); + } + return (Node)lookup; + } + /** Looks up a node in our node map. If not present, use the passed in node. **/ + private Node addOrLookupNode(HierName h, Node n) { + h = stripGlobals(h); + Object lookup = nodes.get(h); + if (lookup==null) { + /* Add n to nodes */ + nodes.put(h, n); + nodeCount++; + return n; + } + return (Node)lookup; + } + /** Creates an alias for an already existant node in the node map. **/ + private Node aliasNode(HierName h, HierName alias) { + //String name = sanitizeName(h); + //Object lookup = nodes.getDigitalNode(name); + h = stripGlobals(h); + Object lookup = nodes.get(h); + return aliasNode((Node)lookup, alias); + } + /** Creates an alias for an already existant node in the node map. **/ + private Node aliasNode(Node node, HierName alias) { + // System.out.println("Aliasing "+node.getName()+" to "+alias); + //nodes.alias(al, node); + // System.err.println("Aliasing "+al+" to "+node.getName()); + alias = stripGlobals(alias); + if (nodes.get(alias) != null && nodes.get(alias) != node) { + System.err.println("Alias for " + alias + " to " + node + " created, but already listed as " + nodes.get(alias) + "."); + } + nodes.put(alias, node); + return node; + } + /** Creates a new node and puts it in the node map. **/ + private Node createNode(HierName h) { + //String name = sanitizeName(h); + //Node node = new Node(name); + //nodes.put(name, node); + //node.setLabel(nodes.getMixNode(name)); + HierName n = stripGlobals(h); + Node node = new Node(h); + nodes.put(h, node); + nodeCount++; + return node; + } + + /** + * Controls printing and recording of warnings. + * Whenever warning tracking is set, the anomalous event state + * interferenceEvent, glitchEvent, and unstabEvent objects are + * cleared + **/ + public void setWarn(boolean w) { + //commented out as part of fixing bug#2716, (abe) + //if (w) { + // interferenceEvent = null; + // glitchEvent = null; + // unstabEvent = null; + //} + warn=w; + } + /** Returns the warning tracking state **/ + public boolean getWarn() { return warn; } + + /** controls stoping on warnings */ + public void setError(boolean e) { error=e; } + public boolean getError() { return error; } + + /** controls printing of extra info */ + public void setVerbose(boolean v) { sched.setVerbose(verbose=v); } + public boolean getVerbose() { return verbose; } + + /** Finds and returns a node in the map, or returns null. **/ + //public Node findNode(String nodeName) { return nodes.getDigitalNode(nodeName); } + /** Prints out all of the aliases for a given node. **/ + //public void listAliases(String name) { + // String list[] = nodes.getAliases(name); + // if (list==null) { System.out.println("Aliases: Node not found."); } + // for (int i=0; iv based on node. **/ + public boolean expandNodes(String name, Collection v, boolean node, boolean nowarn) { + //TriMapIterator i = (TriMapIterator)nodes.getDigitalNodes(name); + //if (!i.hasNext()) { + // if (!nowarn) { System.err.println("WARNING: node " + name + " undefined"); } + // return false; + if (!isGlob(name)) { + HierName h; + try { + h = HierName.makeHierName(name, '.'); + } catch (InvalidHierNameException e) { + if (!nowarn) { System.err.println("WARNING: node " + name + " Invalid"); } + return false; + } + if (!nodes.containsKey(h)) { + if (!nowarn) { System.err.println("WARNING: node " + name + " undefined"); } + return false; + } + if (node) { + v.add(nodes.get(h)); + } else { + v.add(h); + } + return true; + } + // Is a glob + try { + HierName.Glob1 g = new HierName.Glob1(name); + HashSet s = new HashSet(); + boolean found = false; + for (HierName h : nodes.keySet()) { + if (!g.matches(h)) { + continue; + } + if (node) + v.add(nodes.get(h)); + else { + if (!s.contains(nodes.get(h))) { + v.add(h); + s.add(nodes.get(h)); + } + } + found = true; + } + if (!found && !nowarn) { + System.err.println("WARNING: node " + name + " undefined"); + } + return found; + } catch (UnrepresentableCharException e) { + System.err.println("WARNING: unrepresentable string '" + name + "'"); + return false; + } + } + /** Lists all of the nodes (with value) that match a single wildcard expression. **/ + /* + public void listNodeValue(String nodeName) { + Iterator i = nodes.iterator(); + if (!i.hasNext()) { + System.err.println("Get Node " + nodeName + " not found"); + } + while (i.hasNext()) { + if (node) { v.add(i.next()); } + else { v.add(i.getLabel()); i.next(); } + } + return true; + } +// // Lists all of the nodes (with value) that match a single wildcard expression. +// public void listNodeValue(String nodeName) { +// TriMapIterator i = (TriMapIterator)nodes.getDigitalNodes(nodeName); +// if (!i.hasNext()) { +// System.err.println("Get Node " + nodeName + " not found"); +// } +// while (i.hasNext()) { +// System.out.println(" "+(Node)i.next()+" ("+i.getLabel()+")"); +// } +// } + */ + /** Gets the value for a single node. **/ + public byte getNodeValue(String nodeName) { + Node n = findNode(nodeName); + if (n == null) { + System.err.println("Get Node " + nodeName + " not found"); + return -1; + } else { + return n.getValue(); + } + } + /** Sets the value for a single node. **/ + public int setNodeValue(String nodeName, byte val) { + Node node = findNode(nodeName); + if (node!=null) { + //findNode(nodeName).setValueAndEnqueueDependents(val); + node.setValueAndEnqueueDependents(val); + return 1; + } + System.out.println("Set Node: "+nodeName+" not found"); + return -1; + } + /** Tells the simulation to halt (or not) when a given node changes **/ + public int breakpointNode(Node node, boolean on) { + node.setBreakpoint(on); + return 1; + } + /** Prints a list of nodes that will halt the simulation on change. **/ + public void listBreakpointNodes() { + Vector uniqueNodes = new Vector(); + for (Node n : nodes.values()) { + if (n.getBreakpoint() && !uniqueNodes.contains(n)) { + uniqueNodes.add(n); + System.out.println(" "+n.getName()); + } + } + } + /** Tells the simulation to print out when a given node changes **/ + public void watchNode(Node node, HierName name) { + watchNode(node, name, this); + } + /** Tells the simulation to print out when a given node changes **/ + public void watchNode(Node node, HierName name, NodeWatcher w) { + if (node!=null) { + HierName oldWatchName = (HierName) + canonNodeNameToWatchedNodeNameMap.put(node.getName(), + name); + if (oldWatchName != null) { + System.out.println("Node " + node.getName() + .getAsString('.') + + " was already being watched as " + + oldWatchName.getAsString('.') + '.'); + System.out.println("Now watched as " + + name.getAsString('.') + " instead."); + } + node.addWatch(w); + } + } + /** Tells the simulation not to print out when a given node changes **/ + public void unwatchNode(Node node) { + unwatchNode(node, this); + } + /** Tells the simulation not to print out when a given node changes **/ + public void unwatchNode(Node node, NodeWatcher w) { + if (node!=null) { + canonNodeNameToWatchedNodeNameMap.remove(node.getName()); + node.removeWatch(w); + } + } + /** Prints a list of nodes that will notify on change. + Does not account for watchAll. **/ + public void listWatchNodes() { + Vector uniqueNodes = new Vector(); + for (Node n : nodes.values()) { + if (n.isWatcher(this) && !uniqueNodes.contains(n)) { + uniqueNodes.add(n); + System.out.println(" "+n.getName()); + } + } + } + /** Turns on outputing when any node changes. **/ + public void watchAllNodes(boolean watch) { Node.watchAll = watch; } + /** Are we outputting for all nodes? **/ + public boolean watchAllNodes() { return Node.watchAll; } + /** Turns on printing of node transition counts. **/ + public void showTCounts(boolean ct) { countTransitions=ct; } + /** Are we printing transition counts? **/ + public boolean showTCounts() { return countTransitions; } + /** Returns a string of rules and debugging info for a given node. **/ + public String listNodeRules(Node node) { + return node.listRules(); + } + /** Returns a list of Rules that target a given node. **/ + public List getTargetingRules(Node n) { + List ret = new ArrayList(); + for (int i=0; i getTargetingNodes(Rule r) { + Set ret = new HashSet(); + for (Node n : nodes.values()) { + // ensure no multiples from aliases + if (n.targets(r)) ret.add(n); + } + return ret; + } + + /** Prints out all nodes that are directly affected by the given node. **/ + public void listFanout(Node n, String indent, int level) { + final Set uniqueNodes = + new TreeSet(NaturalStringComparator.getInstance()); + for (Rule r : n.getTargets()) { + Node n1 = r.target; + uniqueNodes.add(n1); + } + for (Node n1 : uniqueNodes) { + System.out.println(indent + n1); + if (level > 0) { + listFanout(n1, indent + " ", level - 1); + } + } + } + + /** Prints out all nodes that directly affect the given node. **/ + public void listFanin(Node n, String indent, int level) { + final Set uniqueNodes = + new TreeSet(NaturalStringComparator.getInstance()); + for (Rule r : getTargetingRules(n)) { + for (Node n1 : getTargetingNodes(r)) { + uniqueNodes.add(n1); + } + } + for (Node n1 : uniqueNodes) { + System.out.println(indent + n1); + if (level > 0) { + listFanin(n1, indent + " ", level - 1); + } + } + } + + private static final class HistoryStore implements Iterable { + private final HistoryRecord[] data; + private int start; + private int size; + + public HistoryStore(final int capacity) { + if (capacity < 1) { + throw new IllegalArgumentException("Capacity must be >= 1"); + } + + this.data = new HistoryRecord[capacity]; + this.start = 0; + this.size = 0; + } + + public HistoryStore(final int capacity, final HistoryStore old) { + this(capacity); + if (old != null) { + size = Math.min(capacity, old.size()); + int idx = Math.max(0, old.start - size); + int len = old.start - idx; + if (len > 0) { + System.arraycopy(old.data, idx, data, size - len, len); + } + + int remain = size - len; + if (remain > 0) { + System.arraycopy(old.data, old.capacity() - remain, + data, 0, remain); + } + start = size == data.length ? 0 : size; + } + } + + public synchronized void add(final HistoryRecord record) { + data[start++] = record; + if (start == data.length) start = 0; + if (size < data.length) size++; + } + + public Iterator iterator() { + return new Iterator() { + private int remain = size; + private int pos = start; + public boolean hasNext() { + return remain > 0; + } + public HistoryRecord next() { + if (hasNext()) { + pos--; + if (pos < 0) pos += data.length; + remain--; + return data[pos]; + } else { + throw new NoSuchElementException(); + } + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public int size() { + return size; + } + + public int capacity() { + return data.length; + } + } + + /** Storage structure for node change recording. **/ + public static final class HistoryRecord { + public final Event cause; + public final Node target; + public final long time; + public final int tcount; + public final byte newVal; + public final byte delay_type; + public final float slew; + HistoryRecord(Node _target, Event _cause, long _time, int _tcount, byte _newVal, float _slew, byte _delay_type) { + target=_target; cause=_cause; time=_time; tcount=_tcount; newVal=_newVal; slew=_slew; delay_type=_delay_type; + } + + public String toString(final boolean measured, + final boolean estimated, + final boolean delay) { + if (delay) { + final int d = getDelay(); + final String fmt = measured ? " %4s" : " %6s"; + final String msg = d < 0 ? "---" : Integer.toString(d); + return " " + getNodeString(target, time, tcount, slew, + delay_type, newVal, measured, + estimated, String.format(fmt, msg)); + } else { + return toString(measured, estimated); + } + } + + public String toString(final boolean measured, + final boolean estimated) { + return " " + getNodeString(target, time, tcount, slew, delay_type, + newVal, measured, estimated); + } + + /** + * Return either the digital delay or estimated delay associated with + * the rule that triggered this transition, or -1 if there is no rule + * (for example, when transition is caused by CSP). + **/ + public int getDelay() { + final MutableInt delay = new MutableInt(-1); + if (cause instanceof Node) { + final Node enabler = (Node) cause; + enabler.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + final char dir = r.getDirection(); + if (r.target == target && + (dir == '+' && newVal == Node.VALUE_1 || + dir == '-' && newVal == Node.VALUE_0)) { + delay.set(r.getDelay()); + } + } + }); + } + return delay.get(); + } + } + /** Circular buffer of past node changes. **/ + HistoryStore history = null; + boolean historyFilterCritical = false; + /** Are we currently recording node changes? **/ + boolean recordHistory(final boolean critical) { + return history != null && (!historyFilterCritical || critical); + } + /** Allocates average storage of sz events per node. **/ + public void setHistoryPerNode(int sz) { + setHistoryPerNode(sz, false); + } + public void setHistoryPerNode(int sz, boolean filterCritical) { + setHistoryCap(sz*nodeCount); + historyFilterCritical = filterCritical; + } + /** Allocates storage for exactly cap change events. **/ + public void setHistoryCap(int cap) { + // TODO truncate history as nec + if (cap < 0) + cap = 0; + history = cap == 0 ? null : new HistoryStore(cap, history); + //System.out.println("Set history cap to :"+cap); + } + /** Put a change event into the next slot in the circular buffer. + Allocates space as nec. **/ + + public void recordEvent(Node n, Event cause, long time, int tcount, + byte newVal, float slew, byte delay_type) { + history.add(new HistoryRecord(n, cause, time, tcount, newVal, slew, + delay_type)); + } + /** Execute an action for each transition in the history for a single node, + * or each prior enabling node based on swithchNodes **/ + public void trackNode(HierName name, boolean switchNodes, + UnaryAction action) { + if (history==null || history.size()==0) { return; } + Node node = findNode(name); + if (node==null) { + System.err.println("History/Critical: Node not found: "+name); + } else { + for (HistoryRecord h : history) { + if (h.target==node) { + action.execute(h); + if (switchNodes && (h.cause instanceof Node)) + node = (Node)h.cause; + } + } + } + } + /** Prints out history for a single node, or each prior enabling node + based on swithchNodes **/ + private void trackNode(final HierName name, final boolean switchNodes, + final boolean delay, final PrintWriter pw) { + final boolean measured = useDelayMode(MEASURED_TAU); + final boolean estimated = useDelayMode(ESTIMATED_TAU); + trackNode(name, switchNodes, + new UnaryAction() { + public void execute(final HistoryRecord h) { + pw.println(h.toString(measured, estimated, delay)); + } + }); + } + /** Prints out history for a single node. **/ + public void listNodeHistory(HierName name, boolean delay, PrintWriter pw) { + trackNode(name, false, delay, pw); + } + /** Prints out history for each prior enabling node. **/ + public void listNodeEnablers(HierName name, boolean delay, PrintWriter pw) { + trackNode(name, true, delay, pw); + } + + public void findCriticalCycle(final HierName name, + final Collection cycle) { + final MutableInt most = new MutableInt(Integer.MIN_VALUE); + final LinkedHashMap,MutableInt> trans = + new LinkedHashMap,MutableInt>(); + trackNode(name, true, + new UnaryAction() { + public void execute(final HistoryRecord h) { + final Pair key = + new Pair(h.target, h.newVal); + MutableInt count = trans.get(key); + if (count == null) { + count = new MutableInt(0); + trans.put(key, count); + } + most.max(count.inc()); + } + }); + + // not enough data + if (most.get() < 3) return; + + Pair key = null; + for (Map.Entry,MutableInt> entry : trans.entrySet()) { + if (most.equals(entry.getValue())) { + key = entry.getKey(); + break; + } + } + + final Pair fkey = key; + most.set(3); + trackNode(key.getFirst().getName(), true, + new UnaryAction() { + boolean started = false; + public void execute(final HistoryRecord h) { + final boolean matched = + h.target == fkey.getFirst() && + h.newVal == fkey.getSecond().byteValue(); + if (matched) started = true; + if (started) { + if (most.get() > 0) { + cycle.add(h); + if (matched) most.dec(); + } + } + } + }); + } + + /** Returns the number of queued random events. **/ + public int randomCount() { return sched.randomCount(); } + /** Returns the number of queued timed events. **/ + public int timedCount() { return sched.timedCount(); } + /** Returns string of all pending events. Non-node events are ignored. **/ + public String pendingList() { return sched.pendingList(); } + /** Asks the scheduler to cycle. time indicates: 0 - cycle once, + positive - cycle until that time, negative - cycle until done or interrupted. **/ + public void cycle(long time) { + // break out cycle into the 3 cases... + if (sched!=null) { + if (time>0) { + //System.out.println("Cycling til: "+(time+getTime())); + sched.cycleTo(time+getTime()); + } else if (time<0) { + //System.out.println("Cycling indefinitely"); + sched.cycle(); + } else { + //System.out.println("Cycling Once"); + sched.cycleOnce(); + } + } else + System.err.println("Cycle error: no scheduler to cycle."); + } + + /** Cycles until the node "node" transitions tCount times. **/ + public void cycle(Node node, int tCount) { + sched.cycle(node, tCount); + } + /** Cycles until the node named "name" transitions tCount times. **/ + public void cycle(String name, int tCount) throws InvalidHierNameException { + Node n = findNode(name); + if (n == null) { + System.out.println("Node '"+name+"' does not exist."); + } else { + cycle(n, tCount); + } + } + + /** Stub. Returns true iff there's been an instability in the simulation */ + public boolean hasBeenInstability() { + return (_rand.nextInt() & (1 << 15)) == 0; + } + private static Random _rand = new Random(); + + /** Stub. Returns Iterator through map of all names. **/ + public Iterator getAllNames() { + return null; + } + + /** Asks the scheduler to stop after the next cycle. **/ + public void interrupt() { + interrupt(DigitalScheduler.InterruptedBy.OTHER); + } + + public void interrupt(DigitalScheduler.InterruptedBy what) { + sched.interrupt(what); + } + + /** Return whether the scheduler was interrupted. **/ + public DigitalScheduler.InterruptedBy isInterrupted() { + return sched.isInterrupted(); + } + + private static String getSlewString(final int value, final float slew, + final boolean measured) { + if (measured) { + return " " + (value == Node.VALUE_0 ? "-" : + value == Node.VALUE_1 ? "+" : " ") + + String.format("%6.2f", slew); + } else { + return ""; + } + } + + private static String getNodeString(final Node node, + final long time, + final int tcount, + final float slew, + final byte type, + final byte val, + final boolean measured, + final boolean estimated, + final String delay) { + final StringBuilder sb = new StringBuilder(); + if (time != 0) + sb.append(" @" + time); + if (tcount >= 0) + sb.append(" #" + tcount); + sb.append(getSlewString(val, slew, measured)); + sb.append(getDelayTypeString(type, measured, estimated)); + if (delay != null) sb.append(" " + delay); + sb.append(" " + node.getName() + ":" + Node.getNameForValue(val)); + return sb.toString(); + } + + private static String getNodeString(final Node node, + final long time, + final int tcount, + final float slew, + final byte type, + final byte val, + final boolean measured, + final boolean estimated) { + return getNodeString(node, time, tcount, slew, type, val, measured, + estimated, null); + } + + /** Returns a long string representation for a node. **/ + public String getNodeString(Node node, long time, int transitions, + float slew, byte type) { + return getNodeString(node, time, countTransitions ? transitions : -1, + slew, type, node.getValue(), + useDelayMode(MEASURED_TAU), + useDelayMode(ESTIMATED_TAU)); + } + /** Returns a long string representation for a node. **/ + public String getNodeString(Node node) { + return getNodeString(node, getTime(), node.getTCount(), node.getSlew(), + node.getDelayType()); + } + private static String getDelayTypeString(final byte type, + final boolean measured, + final boolean estimated) { + if (!estimated && !measured) { + return ""; + } else { + return type == DIGITAL_TAU ? " D" : + type == ESTIMATED_TAU ? " E" : " M"; + } + } + /** Notification by a watched node that it has changed. Prints details. **/ + public void nodeChanged(Node node, long time) { + HierName name = (HierName) + canonNodeNameToWatchedNodeNameMap.get(node.getName()); + // name may be null if this callback resulted from "watchall" + // and not "watch" + assert name != null || watchAllNodes(); + System.out.println(getNodeString(node, time, node.getTCount(), + node.getSlew(), node.getDelayType()) + + (name != null ? + " (" + name.getAsString('.') + ')' : + "")); + } + + /** + * Something odd happened! Unless we're ignoring errors, this'll + * halt the program. + **/ + public void eventWarning(Node lastEvent, Rule rule, String message) { + if (!warn) { return; } + //error=true; + System.err.print("WARNING: node "+rule.target+" "+message+" at time "+getTime()); + if (lastEvent != null) { System.err.println(" caused by "+lastEvent); } + if (error) { interrupt(); } + } + + /** A node began interfering **/ + public void interferenceWarning(Node lastEvent, Rule rule) { + if(warn) + interferenceEvent = new AnomalousEvent(lastEvent,rule,sched.getTime()); + eventWarning(lastEvent,rule,"interfering"); + } + + /** A node glitched **/ + public void glitchWarning(Node lastEvent, Rule rule) { + if(warn) + glitchEvent = new AnomalousEvent(lastEvent,rule,sched.getTime()); + eventWarning(lastEvent,rule,"unstable (set to 0 or 1)"); + } + + /** A node went unstable **/ + public void unstabWarning(Node lastEvent, Rule rule) { + if(warn) + unstabEvent = new AnomalousEvent(lastEvent,rule,sched.getTime()); + eventWarning(lastEvent,rule,"unstable (set to U)"); + } + + /** + * Returns the last interference AnomalousEvent, if + * one occurred. Returns null if no node when into + * interference. + **/ + public AnomalousEvent lastInterferenceEvent() { return interferenceEvent; } + + /** + * Returns the last glitch AnomalousEvent, if + * one occurred. Returns null if no node glitched. + **/ + public AnomalousEvent lastGlitchEvent() { return glitchEvent; } + + /** + * Returns the last instability AnomalousEvent, if + * one occurred. Returns null if no node when unstable. + **/ + public AnomalousEvent lastUnstabEvent() { return unstabEvent; } + + /** + * Spits out the anomalous event state to System.out. + **/ + public void printAnomalousState() { + AnomalousEvent e1 = lastInterferenceEvent(); + AnomalousEvent e2 = lastGlitchEvent(); + AnomalousEvent e3 = lastUnstabEvent(); + if (e1 != null) { + System.out.print("Node "+e1.rule.target+" went into "+ + "interference at time "+e1.time); + if (e1.node != null) + System.out.println(" caused by "+e1.node); + else System.out.println(""); + } + if (e2 != null) { + System.out.print("Node "+e2.rule.target+" glitched "+ + "at time "+e2.time); + if (e2.node != null) + System.out.println(" caused by "+e2.node); + else System.out.println(""); + } + if (e3 != null) { + System.out.print("Node "+e3.rule.target+" went unstable "+ + "at time "+e3.time); + if (e3.node != null) + System.out.println(" caused by "+e3.node); + else System.out.println(""); + } + if (e1 == null && e2 == null && e3 == null) { + System.out.println("No anomalous events."); + } + } + + /** + * Something unusual happened. If the user cares, print out, but + * don't halt anything. + **/ + public void eventNotice(Node lastEvent, Rule rule, String message) { + if (verbose && warn) { + System.err.print("WARNING: node "+rule.target+" "+message+" at time "+getTime()); + if (lastEvent != null) { System.err.println(" caused by "+lastEvent); } + } + } + /** Prints gratuitous info based on verbose flag. **/ + public void ui_out_verbose(String message) { + if (verbose) { System.out.print(message); } + } + /** Prints a message. **/ + public void ui_out(String message) { + System.out.print(message); + } + /** Returns the scheduler's current time. **/ + public long getTime() { return sched.getTime(); } + /** + * Sets the scheduler's current time. Clears all events out to + * avoid dealing with timing conflicts. Mostly for debugging. + **/ + public void setTime(long time) { sched.clearEventQueuesAtTime(time); } + + /** Compares a delay (offset from current time) to a given time. **/ + long compareDelayToTime(long delay, long time) { return (delay+getTime())-time; } + + /** Returns the simulator's interference state **/ + + + /** + * How randomness is handled. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    NO_RANDOM UNTIMED_RANDOM TIMED_RANDOMC characteristics java characteristics
    event normalspecified delay delay * range delay * rangerule->timed rule.timed
    event randomspecified delay random delay * range!rule->timed, event_time == MAX_INT!rule.timed; stuck on random queue
    event immediatefront of queue front of queue front of queueU (dis)appearing. or drule->delay=0 => event_time = -1 delay=0/-1 not handled correctly.
    + * @see Rule#delay + * @see #NO_RANDOM + * @see #TIMED_RANDOM + * @see #UNTIMED_RANDOM + **/ + int randomOrder = NO_RANDOM; + /** See randomOrder. **/ + public int getRandom() { return randomOrder; } + /** See randomOrder. **/ + public void setRandom(int r) { randomOrder = r; } + /** Sets the min and max range for random variations in timing. **/ + public void setTimedRandom(float fast, float slow) { + slowDelay=slow; fastDelay=fast; + } + /** Returns a String for min and max range for random timing var. **/ + public String getTimedRandom() { + return "("+fastDelay +"," +slowDelay +")"; + } + + /** Returns the min range for random variations in timing. **/ + public float getFastDelay() { return fastDelay; } + /** Returns the max range for random variations in timing. **/ + public float getSlowDelay() { return slowDelay; } + /** Set the random number generator seed. **/ + public void setRandomSeed(long r) { + rand.setSeed(r); + sched.setRandomSeed(rand.nextLong()); + } + + /** range delays are multiplied by fastDelay -- slowDelay. **/ + private float slowDelay=(float)(4.0/3.0), fastDelay=(float)(2.0/3.0); + + /** returns a float in [fastDelay, slowDelay). */ + protected float randomDelay() { + return fastDelay + rand.nextFloat() * (slowDelay - fastDelay); + } + + /** Schedule (or re-schedule) a node transition. */ + public void scheduleEvent(Node node, byte pending, long delay, + boolean random, Node lastEvent) { + boolean destRandom; + long time; + + /* questionable... should perhaps be outside? + * neither otherwise used in this method, but + * convenient place. */ + node.pending=pending; + node.enabler=lastEvent; + + time = delay + getTime(); + + if (verbose) + ui_out("adding "+node+" -> "+Node.getNameForValue(node.pending)+ + " to queue at time="+time+".\n"); + + destRandom = randomOrder == UNTIMED_RANDOM && random; + if (node.getIndex() >= 0 && destRandom != node.isRandom()) { + // On a queue, and it isn't the right one. + sched.removeEvent(node); + } + node.setRandom(destRandom); // force on correct queue + if (node.getIndex() >= 0 && !destRandom && + DigitalScheduler.compareTime(time,node.eventTime) > 0) { + if (warn) { + ui_out("Queuing event for node later than outstanding"+ + " event on EventQueue\n\tnode: " + node + " time= "+time+ + " node.eventTime= "+node.eventTime+"\n"); + } + } + node.eventTime = time; + sched.addEvent(node); + } + + private boolean isGlob(String s) { + int first = s.indexOf("*"); + if (first < 0) { + return false; + } + int last = s.lastIndexOf("*"); + if (last != first) { + return false; + } + return true; + } + + /** + * Used to traverse the cell hierarchy, instantiating all the nodes + * and rules. Should be much more memory efficient than flattening. + * + * Can also avoid keeping most names permanently, by using a local + * name to node map. Not yet implemented. + * + * IMPL note: keep all top-level names, no matter what. + * + * Strategy for following aliases properly: + * We traverse the cell hierarchy, using DSimCellTraverser. + * It passes in an aliased map from the node's portlists to + * nodes in the parent cell (or even higher in the hierarchy). + * Before checking in DSim's list of nodes we first check this + * port list so everything uses the canonical name. + **/ + + public class AliasCreator implements JFlat.CellProcessor { + private final AliasedSet collect; + + public AliasCreator(AliasedSet collect) { + this.collect = collect; + } + + private void process_dsim(HierName prefix, CellInterface cell, + Cadencize cadencizer) { + // System.err.println("portNodes are " + portNodes); + // System.out.println("Locals... in "+prefix); + addLocalAliases(prefix, cell); + } + + public void process(HierName prefix, CellInterface cell, AliasedSet s, + int depth, Cadencize cadencizer) { + if (depth < 2) System.out.print("."); + // supercell's port list + // addSuperPortAliases(s); + // Our locals + port + // System.err.println("Entering cell " + prefix); + // System.err.println("localNodes are " + cadencizer.convert(cell).getLocalNodes()); + + process_dsim(prefix, cell, cadencizer); + } + // Add the aliases in the map to DSim's. + /* + private void addSuperPortAliases(AliasedSet s) { + final Iterator i = s.getCanonicalKeys(); + while (i.hasNext()) { + final HierName canon = (HierName)i.next(); + // lookupNode(canon); + final Iterator j = s.getAliases(canon); + while (j.hasNext()) { + final HierName alias = (HierName)j.next(); + if (alias.equals(canon)) { + continue; + } + // System.out.println("Aliasing Port " + alias + " to " + canon); + // aliasNode(canon, alias); + collect.makeEquivalent(canon, alias); + } + } + } + */ + + /** + * Adds all the aliases available through the passed in Cadencize + * AliasedSet. + **/ + private void addLocalAliases(HierName prefix, CellInterface cell) { + // System.out.println("Adding local aliases for " + prefix); + final Iterator i = cell.getCanonicalNodes(); + while (i.hasNext()) { + final HierName local = (HierName)i.next(); + + final HierName canon = prefixName(prefix, local); + // lookupNode(canon); + final Iterator j = cell.getConnectedNodes(local); + while (j.hasNext()) { + final HierName localAlias = (HierName)j.next(); + if ( ! localAlias.equals(local) ) { + + + HierName alias = prefixName(prefix, localAlias); + if ( alias.isGlobal() ) { + alias = HierName.trim(alias); + } + collect.makeEquivalent(canon, alias); + } + } + } + } + } + + private final float[] delayTau = new float[] { 1, Float.NaN, Float.NaN }; + public final static byte DIGITAL_TAU = 0; + public final static byte ESTIMATED_TAU = 1; + public final static byte MEASURED_TAU = 2; + + private float measuredCapScale = Float.NaN; + + /** + * Enable using estimated_delay directives to calculate the delay. + **/ + public void enableDelayMode(final int mode, final float tau) { + assert tau > 0 && !Float.isNaN(tau); + delayTau[mode] = tau; + } + + public void disableDelayMode(final int mode) { + delayTau[mode] = Float.NaN; + } + + public boolean useDelayMode(final int mode) { + return !Float.isNaN(delayTau[mode]); + } + + public float getDelayTau(final int mode) { + return useDelayMode(mode) ? delayTau[mode] : 1; + } + + private int measureDataSet; + public void setMeasureDataSet(int dataSet) { + assert dataSet >= 0; + this.measureDataSet = dataSet; + } + public int getMeasureDataSet() { + return measureDataSet; + } + + public void enableMeasuredCap(final float scale) { + measuredCapScale = scale; + } + + public boolean useMeasuredCap() { + return !Float.isNaN(measuredCapScale); + } + + static class SimpleCell implements HierarchyInterface { + private final String fqcn; + private final Map subcells; + private final boolean isRouted; + private final boolean isGraybox; + private SimpleCell(final String fqcn, final boolean isRouted, + final boolean isGraybox) { + this.fqcn = fqcn; + this.isRouted = isRouted; + this.isGraybox = isGraybox; + subcells = new HashMap(); + } + private void addSubcell(final HierName inst, final SimpleCell subcell) { + subcells.put(inst, subcell); + } + public SimpleCell getSubcell(final HierName inst) { + return subcells.get(inst); + } + public boolean isRouted() { + return isRouted; + } + public boolean isGraybox() { + return isGraybox; + } + public boolean isLeaf() { + return subcells.isEmpty(); + } + public String getType() { + return fqcn; + } + private static SimpleCell convert(final CellInterface cell, + final Map cache) { + final String type = cell.getFullyQualifiedType(); + SimpleCell result = cache.get(type); + if (result == null) { + result = new SimpleCell(type, CellUtils.isRouted(cell), + CellUtils.isAstaGraybox(cell)); + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName name = (HierName) p.getFirst(); + final CellInterface ci = (CellInterface) p.getSecond(); + result.addSubcell(name, convert(ci, cache)); + } + cache.put(type, result); + } + return result; + } + public static SimpleCell convert(final CellInterface cell) { + return convert(cell, new HashMap()); + } + public String toString() { + return "[SimpleCell " + fqcn + "]"; + } + } + + private boolean astaEnabled = false; + private boolean slintEnabled = false; + private Map, + Map>,Boolean>> slintIgnores = + new HashMap,Map>,Boolean>>(); + private CadenceInfo savedCadenceInfo = null; + private SimpleCell savedOptCandidate = null; + + public void enableAsta() { + astaEnabled = true; + } + public void disableAsta() { + astaEnabled = false; + savedCadenceInfo = null; + savedOptCandidate = null; + } + public boolean isAstaEnabled() { + return astaEnabled; + } + + public void enableSlint() { slintEnabled = true; } + public void disableSlint() { slintEnabled = false; } + public boolean isSlintEnabled() { return slintEnabled; } + Collection>> + getSlintIgnoreFrom(final Node n, final int dir) { + Map>,Boolean> stored = + slintIgnores.get(new HalfOp(n, dir > 0 ? true : false)); + if (stored == null) stored = Collections.emptyMap(); + + final Collection>> result = + new ArrayList>>(); + for (Map.Entry>,Boolean> entry : + stored.entrySet()) { + if (entry.getValue()) { + final List> path = + new ArrayList>(); + for (HalfOp op : entry.getKey()) { + path.add(new Pair(op.node, op.getDir())); + } + result.add(path); + } + } + return result; + } + + /** + * Returns whether the node is a dynamic node. + **/ + static boolean isDynamic(Node n) { + return n.getBreakpoint(); + } + + /** + * Returns whether the node is a dynamic node staticized by a full + * staticizer. + **/ + static boolean hasFullStaticizer(Node n) { + return isDynamic(n) && n.isRandom(); + } + + /** + * Returns the inverse of the dynamic node used in the staticizer. This + * function can return null, if the node is staticized by a full + * staticizer but the inverse node internal to the full staticizer isn't + * represented in the simulation. + **/ + static Node getStaticizerInverse(Node n) { + return isDynamic(n) ? (Node) n.enabler : null; + } + + /** + * Special case handling for input DFT channels. During reset, lower + * enable; after reset, raise enable. + **/ + private static class DftInputHandler implements NodeWatcher { + private final Node enableNode; + public DftInputHandler(final String name) { + this(DSim.get().findNode(name + ".e")); + } + public DftInputHandler(final Node enableNode) { + this.enableNode = enableNode; + } + public void nodeChanged(Node resetNode, long time) { + final byte val = resetNode.getValue(); + if (val == Node.VALUE_0 || val == Node.VALUE_1) { + setNode(enableNode, val); + } + } + private void setNode(final Node node, final byte val) { + node.scheduleImmediate(val); + } + } + + /** + * Special case handling for output DFT channels. During reset, lower data + * rails; after reset, wait for the enable to raise, then raise the 2 rail. + **/ + private static class DftOutputHandler implements NodeWatcher { + private final Node[] dataNodes; + private final Node enable; + private boolean reset; + public DftOutputHandler(final String name) { + this(new Node[] { DSim.get().findNode(name + ".0"), + DSim.get().findNode(name + ".1"), + DSim.get().findNode(name + ".2") }, + DSim.get().findNode(name + ".e")); + } + public DftOutputHandler(final Node[] dataNodes, final Node enable) { + assert dataNodes.length == 3; + this.dataNodes = dataNodes; + this.enable = enable; + this.reset = false; + enable.addWatch(this); + } + public void nodeChanged(Node node, long time) { + final byte val = node.getValue(); + if (node == enable) { + if (!reset && val == Node.VALUE_1) { + setNode(dataNodes[dataNodes.length - 1], val); + } + } else { + // node is _RESET + if (val == Node.VALUE_0) { + for (int i = 0; i < dataNodes.length; ++i) + setNode(dataNodes[i], val); + reset = true; + } else if (val == Node.VALUE_1) { + reset = false; + } + } + } + private void setNode(final Node node, final byte val) { + node.scheduleImmediate(val); + } + } + + /** + * Special case handling for output DFT channels. During reset, lower data + * rails; after reset, raise the 0 and 3 rails. + **/ + private static class NewDftOutputHandler implements NodeWatcher { + private final Node[] dataNodes; + public NewDftOutputHandler(final String name) { + this(new Node[] { DSim.get().findNode(name + "[0]"), + DSim.get().findNode(name + "[1]"), + DSim.get().findNode(name + "[2]"), + DSim.get().findNode(name + "[3]") }); + } + public NewDftOutputHandler(final Node[] dataNodes) { + assert dataNodes.length == 4; + this.dataNodes = dataNodes; + } + public void nodeChanged(Node node, long time) { + // node is _RESET + final byte val = node.getValue(); + if (val == Node.VALUE_0) { + for (int i = 0; i < dataNodes.length; ++i) + setNode(dataNodes[i], val); + } else if (val == Node.VALUE_1) { + setNode(dataNodes[0], val); + setNode(dataNodes[3], val); + } + } + private void setNode(final Node node, final byte val) { + node.scheduleImmediate(val); + } + } + + private boolean existNodes(final String base, final String[] nodes) { + for (String node : nodes) { + if (findNode(base + node) == null) return false; + } + return true; + } + + private static final ChannelTimingInfo DEFAULT_TIMING_INFO = + new ChannelTimingInfo() { + public int getSlack() { return 1; } + public int getLatency() { return 200; } + public int getCycleTime() { return 1800; } + public int getDataNeutralEnableLatency() { return 725; } + public int getDataValidEnableLatency() { return 675; } + public int getEnableDataLatency() { return 200; } + public int getCycleTimeIn() { return 1800; } + public int getCycleTimeOut() { return 1800; } + }; + + private void handleDftChannel(final String base, final boolean in, + final Node resetNode, + final ChannelFactoryInterface factory) { + // There are two scan protocols we must support. We differentiate + // between the two by looking at the existence of certain nodes. + if (existNodes(base + ".", CellUtils.OLD_DFT_NODES)) { + ui_out_verbose("Old ChanDft handler installed on " + base + "\n"); + resetNode.addWatch(in ? new DftInputHandler(base) + : new DftOutputHandler(base)); + } else if (existNodes(base + ".", CellUtils.NEW_DFT_NODES)) { + ui_out_verbose("New ChanDft handler installed on " + base + "\n"); + if (in) { + factory.makeInputChannel(base + ".D", 2, 1, + DEFAULT_TIMING_INFO); + } else { + factory.makeOutputChannel(base + ".D", 2, 1, + DEFAULT_TIMING_INFO); + resetNode.addWatch(new NewDftOutputHandler(base + ".C")); + } + } else { + System.err.println("Warning: unsupported DFT channel (" + + base + ")"); + } + } + + /** + * Added special DFT handling for all DFT channels in the given CoSimInfo. + **/ + private void handleDftChannels(final HierName prefix, + final CoSimInfo info) { + Iterator inDfts = info.getInputDftChannelNames(); + Iterator outDfts = info.getOutputDftChannelNames(); + if (inDfts.hasNext() || outDfts.hasNext()) { + final Node resetNode = DSimUtil.getResetNode(); + if (resetNode == null) { + System.err.println("Warning: No reset node to watch " + + "(required to handle DFT channels in " + + prefix + ")"); + } else { + final ChannelFactoryInterface factory = + new CoSimInfo.NodeChannelFactory(); + final String root = + prefix == null ? "" : prefix.getAsString('.') + "."; + while (inDfts.hasNext()) + handleDftChannel(root + (String) inDfts.next(), true, + resetNode, factory); + while (outDfts.hasNext()) + handleDftChannel(root + (String) outDfts.next(), false, + resetNode, factory); + } + } + } + + private class CanonizePrs implements UnaryFunction { + final HierName prefix; + public CanonizePrs(final HierName prefix) { + this.prefix = prefix; + } + public Object execute(final Object o) { + final HierName full = prefixName(prefix, (HierName) o); + final Node node = findNode(full); + // node maybe null if the instance containing the node is simulated + // in csp, or if the node has no aliases + if (node == null) return full; + else return node.getName(); + } + } + + private static final InstanceData DUMMY_INSTANCE = new InstanceData() { + public InstanceData translate(final CellInterface cell, + final CellInterface subcell, + final HierName instance, + final Cadencize cad) { + return this; + } + + public AttributeInterface put(final String name, + final AttributeInterface attr) { + throw new UnsupportedOperationException(); + } + + public AttributeInterface get(final String name) { + return null; + } + + public void updateExtraDelay(final CellInterface cell, + final AliasedSet aliases) { + throw new UnsupportedOperationException(); + } + + public void updateAstaExtraDelay(final CellInterface cell, + final AliasedSet aliases) { + throw new UnsupportedOperationException(); + } + + public void updateEstimatedDelay(final CellInterface cell, + final AliasedSet aliases) { + throw new UnsupportedOperationException(); + } + + public void updateEstimatedDelaySignoff(final CellInterface cell, + final AliasedSet aliases) { + throw new UnsupportedOperationException(); + } + + public void updateDelayBias(final CellInterface cell) { + throw new UnsupportedOperationException(); + } + + public void updateMeasuredDelay(final HierName prefix, + final CellInterface cell, + final UnaryFunction canonizer, + final float delayScale, + final int dataSet) { + throw new UnsupportedOperationException(); + } + + public void updateEstimatedCap(final HierName prefix, + final CellInterface cell, + final UnaryFunction canonizer) { + throw new UnsupportedOperationException(); + } + + public void updateMeasuredCap(final HierName prefix, + final CellInterface cell, + final UnaryFunction canonizer) { + throw new UnsupportedOperationException(); + } + + public float getExtraDelay(final boolean up, final HierName canon) { + return 0; + } + + public float getEstimatedDelay(final boolean up, final HierName canon) { + return Float.NaN; + } + + public float getEstimatedDelaySignoff(final boolean up, + final HierName canon) { + return Float.NaN; + } + + public Triplet[] getMeasuredDelay(final boolean up, + final HierName canon) { + return null; + } + + public float getEstimatedCap(final HierName canon) { + return Float.NaN; + } + + public float getMeasuredCap(final HierName canon) { + return Float.NaN; + } + + public float getDelayBias(final HierName instance) { + return 1; + } + }; + + Collection getBoundaryMeasuredDelays() { + return Collections.unmodifiableCollection(boundaryDelays); + } + + Collection getInteriorOutputNodes() { + return Collections.unmodifiableCollection(interiorOutputPorts); + } + + String getCandidateType(final HierName name) { + final SimpleCell sc = (SimpleCell) getSubcell(savedOptCandidate, + name.tail()); + return sc.getType(); + } + + private RunStaticTiming.Context astaContext; + public void setAstaContext(RunStaticTiming.Context astaContext) { + this.astaContext = astaContext; + } + private double getAstaDelayBias() { + return astaContext == null ? 1.0 : astaContext.getDelayBias(); + } + + /** + * A half-operator. + **/ + private static class HalfOp { + public final T node; + public final boolean direction; + public HalfOp(final T node, final boolean direction) { + assert node != null; + this.node = node; + this.direction = direction; + } + public boolean equals(Object o) { + if (o instanceof HalfOp) { + final HalfOp op = (HalfOp) o; + return node.equals(op.node) && direction == op.direction; + } else { + return false; + } + } + public int hashCode() { + return node.hashCode() + (direction ? 1 : 0); + } + public String toString() { + return node.toString() + (direction ? "+" : "-"); + } + public int getDir() { + return direction ? 1 : 0; + } + } + + /** + * Setup measured_delay processors. + **/ + private void prepareMeasured() { + final double postStep = getDouble("sta.postStep", Double.NaN); + final int shape = (int) getDouble("sta.shape", 1); + final double defOldTh1, defOldTh2, defNewTh1, defNewTh2; + if (shape == 1) { + defOldTh1 = 1.0 / 3.0; + defOldTh2 = 2.0 / 3.0; + defNewTh1 = 0.0; + defNewTh2 = 1.0; + } else { + defOldTh1 = defOldTh2 = defNewTh1 = defNewTh2 = Double.NaN; + } + final double oldth1 = getDouble("sta.oldTh1", defOldTh1); + final double oldth2 = getDouble("sta.oldTh2", defOldTh2); + final double newth1 = getDouble("sta.newTh1", defNewTh1); + final double newth2 = getDouble("sta.newTh2", defNewTh2); + staVerbose = 1 == (int) getDouble("sta.verbose", 0); + + measuredProcs.add( + new ProcessMeasuredDelay.RemoveZeroData(zeroDataNotifier)); + if (!Double.isNaN(postStep) && !Double.isNaN(oldth1) && + !Double.isNaN(oldth2)) { + measuredProcs.add( + new ProcessMeasuredDelay.PostStepCorrection(postStep, + oldth1, + oldth2)); + System.out.printf("Enabled postStep correction: " + + "postStep=%.3f oldTh1=%.3f oldTh2=%.3f\n", + postStep, oldth1, oldth2); + if (staVerbose) { + measuredProcs.add( + new ProcessMeasuredDelay.PrintTable("postStep")); + } + } + + if (!Double.isNaN(oldth1) && !Double.isNaN(oldth2) && + !Double.isNaN(newth1) && !Double.isNaN(newth2)) { + measuredProcs.add( + new ProcessMeasuredDelay.ShiftThreshold(oldth1, oldth2, + newth1, newth2, + shape)); + System.out.printf("Enabled extrapolated thresholds:" + + " oldTh1=%.3f oldTh2=%.3f newTh1=%.3f newTh2=%.3f" + + " shape=%d\n", oldth1, oldth2, newth1, newth2, shape); + if (staVerbose) { + measuredProcs.add( + new ProcessMeasuredDelay.PrintTable("extrapolated")); + } + } + + measuredProcs.add( + new ProcessMeasuredDelay.ScaleDelay( + 100.0 / getDelayTau(MEASURED_TAU))); + } + + private interface HierarchyCallback { + void execute(final HierName prefix, final HierName suffix, + final HierarchyInterface cell); + } + + private static HierarchyInterface getSubcell(final HierarchyInterface cell, + final HierName instance, + final HierarchyCallback cb) { + for (Pair split : + new IterableIterator>( + HierName.getSplitsIterator(instance))) { + final HierName prefix = split.getFirst(); + if (prefix == null) continue; + + final HierName suffix = split.getSecond(); + final HierarchyInterface subcell = cell.getSubcell(prefix); + if (subcell != null) { + cb.execute(prefix, suffix, subcell); + if (suffix == null) { + return subcell; + } else { + return getSubcell(subcell, suffix, cb); + } + } + } + return null; + } + + private static HierarchyInterface getSubcell(final HierarchyInterface cell, + final HierName instance) { + final HierarchyCallback empty = + new HierarchyCallback() { + public void execute(final HierName prefix, + final HierName suffix, + final HierarchyInterface cell) { + } + }; + return getSubcell(cell, instance, empty); + } + + private static Pair + getPredicateParent(final SimpleCell cell, final HierName instance, + final UnaryPredicate predicate) { + final SimpleCell[] routed = new SimpleCell[] { null }; + final HierName[] path = new HierName[] { null }; + final HierarchyCallback cb = + new HierarchyCallback() { + public void execute(final HierName prefix, + final HierName suffix, + final HierarchyInterface cell) { + final SimpleCell curr = (SimpleCell) cell; + if (suffix != null && predicate.evaluate(curr)) { + routed[0] = curr; + path[0] = null; + } else { + path[0] = HierName.append(path[0], prefix); + } + } + }; + getSubcell(cell, instance, cb); + return new Pair(path[0], routed[0]); + } + + Iterator getPredicateInstances( + final HierName instance, final UnaryPredicate p) { + final Pair routed = + getPredicateParent(savedOptCandidate, instance, p); + final HierName suffix = routed.getFirst(); + final SimpleCell sc = routed.getSecond(); + Collection names = + sc == null ? null : routedInstancesByType.get(sc.getType()); + if (names == null) names = Collections.emptyList(); + return new MappingIterator(names.iterator(), + new UnaryFunction() { + public HierName execute(final HierName a) { + return suffix == null ? a : HierName.append(a, suffix); + } + }); + } + + Iterator getRoutedInstances(final HierName instance) { + return getPredicateInstances(instance, + new UnaryPredicate() { + public boolean evaluate(SimpleCell sc) { + return sc.isRouted(); + } + }); + } + + Iterator getGrayboxInstances(final HierName instance) { + return getPredicateInstances(instance, + new UnaryPredicate() { + public boolean evaluate(SimpleCell sc) { + return sc.isGraybox(); + } + }); + } + + /** Creates the models from the instantiation heirarchy **/ + public class ModelCreator { + private CoSimParameters params; + private final Cadencize cadencizer; + private boolean errorOccurred = false; + protected CadenceInfo cinfo; + + /** + * A map from FQCN to set of expanded timing arcs. + **/ + private Map, + HalfOp>>> astaIgnoreCache = + new HashMap,HalfOp>>>(); + private Map,BitSet>,Rule> astaGrayboxRules = + new HashMap,BitSet>,Rule>(); + private Map>> staticizerInfo = + new HashMap>>(); + private Map staticizerPrs = + new HashMap(); + private final Collection boundaryNodes; + + private final UnaryFunction canonizer = + new UnaryFunction() { + public Object execute(final Object o) { + final Node node = findNode((HierName) o); + // at this point, saveAliases() has already finished, + // and all aliases created; some Nodes may not exist, + // but they have no aliases, so the canonical name is + // just itself + return node == null ? o : node.getName(); + } + }; + + public ModelCreator(CoSimParameters params, Cadencize cadencizer) { + this(params, cadencizer, null); + } + + public ModelCreator(CoSimParameters params, Cadencize cadencizer, + Collection boundaryNodes) { + this.params = params; + this.cadencizer = cadencizer; + this.boundaryNodes = boundaryNodes; + } + + public Collection getInteriorPorts(final CellInterface cell) { + // find all leaf instances that drive boundary ports + final Set instances = new HashSet(); + foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (r.prefix != null && + boundaryNodes.contains(r.target())) { + instances.add(r.prefix); + } + } + }); + + // accumulate all port nodes used as input in boundary leaf cells + final Set inputPorts = new HashSet(); + for (final HierName instance : instances) { + final CellInterface subcell = + (CellInterface) getSubcell(cell, instance); + final AliasedMap ports = + cadencizer.convert(subcell).getPortNodes();; + final HashSet input = new HashSet(); + final HashSet output = new HashSet(); + for (Iterator i = subcell.getProductionRuleSet() + .getProductionRules(); + i.hasNext(); ) { + final ProductionRule pr = (ProductionRule) i.next(); + if (ports.contains(pr.getTarget())) { + output.add(pr.getTarget()); + } + BooleanUtils.foreachHierName(pr.getGuard(), + new UnaryAction() { + public void execute(final Object o) { + final HierName atom = (HierName) o; + if (ports.contains(atom)) { + input.add(atom); + } + } + }); + } + + // only select ports that are input only + for (HierName port : input) { + if (output.contains(port)) continue; + final HierName full = prefixName(instance, port); + final Node node = findNode(full); + inputPorts.add(node); + } + } + + // remove all input ports of boundary leaf cells actually on the + // boundary to get only the interior ports + inputPorts.removeAll(boundaryNodes); + + return inputPorts; + } + + public boolean build(CellInterface cell, int defaultBehavior, + HierName prefix, final boolean isEnv) { + // build is the external entry point, and this is the only place it + // is called pass -1 as arbitrationMode, as it won't be used + // because there should be no arbiters in the first level + cinfo = cadencizer.convert(cell); + if (isAstaEnabled()) savedCadenceInfo = cinfo; + final AliasedSet aliases = cinfo.getLocalNodes(); + final InstanceData instData = new InstanceData(); + instData.updateExtraDelay(cell, aliases); + instData.updateAstaExtraDelay(cell, aliases); + instData.updateEstimatedDelay(cell, aliases); + instData.updateEstimatedDelaySignoff(cell, aliases); + instData.updateEstimatedCap(prefix, cell, canonizer); + instData.updateMeasuredCap(prefix, cell, canonizer); + instData.updateMeasuredDelay( + prefix, cell, + canonizer, + 1, getMeasureDataSet()); + instData.updateDelayBias(cell, getAstaDelayBias()); + if (!isEnv) { + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface ci = (CellInterface) p.getSecond(); + final HierName name = + HierName.append(prefix, (HierName) p.getFirst()); + final Map markedPorts = CellUtils.markPorts(ci); + for (Iterator j = markedPorts.entrySet().iterator(); + j.hasNext(); ) + { + final Map.Entry entry = (Map.Entry) j.next(); + final String port = (String) entry.getKey(); + HierName hierPort; + try { + hierPort = HierName.makeHierName(port, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot make HierName from " + port, e); + } + warnedCells.add(lookupNode(prefixName(name, hierPort))); + } + } + } + + final Map,Set>> emptyAstaIgnore = + Collections.,Set>>emptyMap(); + + createModels(prefix, cell, defaultBehavior, -1, null, instData, + emptyAstaIgnore, null, isEnv); + process(prefix, prefix, cell, 1, defaultBehavior, false, instData, + emptyAstaIgnore, null, false, isEnv); + return errorOccurred; + } + + private HalfOp getHalfOp(final HierName prefix, + final HalfOp op) { + final Node n = lookupNode(HierName.append(prefix, op.node)); + return n == null ? null : new HalfOp(n, op.direction); + } + + private HalfOp findHalfOp(final HierName prefix, + final HalfOp op) { + final Node n = findNode(HierName.append(prefix, op.node)); + return n == null ? null : new HalfOp(n, op.direction); + } + + /** + * Determine whether the specified guard and target is subject to + * asta_ignore. + **/ + private boolean matchAstaIgnore( + final Map,Set>> map, + final HalfOp guard, final HalfOp target) { + final Set> s = map.get(guard); + return s != null && (s.contains(null) || s.contains(target)); + } + + /** + * Update the data structure with a new ignored timing arc from guard + * to target. Try to avoid creating new objects if possible. + **/ + private Map,Set>> updateAstaIgnore( + final Map,Set>> initial, + Map,Set>> modified, + final HalfOp guard, final HalfOp target) { + if (modified == initial) { + modified = new HashMap,Set>>(initial); + } + final Set> initialSet = initial.get(guard); + Set> modifiedSet = modified.get(guard); + if (modifiedSet == null || initialSet == modifiedSet) { + if (initialSet == null) { + modifiedSet = new HashSet>(); + } else { + modifiedSet = new HashSet>(initialSet); + } + modified.put(guard, modifiedSet); + } + modifiedSet.add(target); + return modified; + } + + /** + * Augment the data structure with asta_ignore directives from cell. + * Return the same map if nothing needs to be added. + **/ + private Map,Set>> updateAstaIgnore( + final Map,Set>> initial, + final CellInterface cell, + final HierName prefix) { + final Set,HalfOp>> ignores = + getAstaIgnore(cell); + Map,Set>> result = initial; + + for (Pair,HalfOp> ignore : ignores) { + final HalfOp guard = getHalfOp(prefix, ignore.getFirst()); + if (guard != null) { + if (ignore.getSecond() == null) { + if (!matchAstaIgnore(result, guard, null)) { + result = updateAstaIgnore(initial, result, guard, + null); + } + } else { + final HalfOp target = + getHalfOp(prefix, ignore.getSecond()); + if (target != null) { + if (!matchAstaIgnore(result, guard, target)) { + result = updateAstaIgnore(initial, result, + guard, target); + } + } + } + } + } + + return result; + } + + /** + * Expand node to node+, node-. + **/ + private HalfOp[] getHalfOp(final Pair op) { + final HierName h = op.getFirst(); + final Boolean b = op.getSecond(); + if (b == null) { + return new HalfOp[] { new HalfOp(h, false), + new HalfOp(h, true) }; + } else { + return new HalfOp[] { new HalfOp(h, b) }; + } + } + + /** + * Store expanding timing arcs to be ignored. + **/ + private void getAstaIgnore( + final String fqcn, + final Set,HalfOp>> result, + final String dirName, + final Map directive) { + for (Iterator i = directive.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Collection> key = + (Collection>) entry.getKey(); + if (key.isEmpty() || key.size() > 2) { + System.err.println( + "WARNING: One or two elements expected in the " + + " parameter to " + dirName + " in " + fqcn); + } else { + final Boolean val = (Boolean) entry.getValue(); + if (!val.booleanValue()) { + System.err.println( + "WARNING: Cannot set " + dirName + " to false in " + + fqcn); + } else { + final Iterator> it = + key.iterator(); + final HalfOp[] guard = getHalfOp(it.next()); + final HalfOp[] target = + it.hasNext() ? getHalfOp(it.next()) + : new HalfOp[] { null }; + for (HalfOp g : guard) { + for (HalfOp t : target) { + result.add(new Pair, + HalfOp>(g, t)); + } + } + } + } + } + } + + private void + processIgnoreDirective(final CellInterface cell, + final String directive, + final UnaryAction func) { + final String type = + DirectiveTable.arrayify(DirectiveConstants.DEEP_HALFOP_TYPE); + + // cell directive + final Map cellLevel = + DirectiveUtils.getTopLevelDirective(cell, directive, type); + func.execute(cellLevel); + + // prs or subcells directive + final BlockInterface cb = cell.getBlockInterface(); + final List db = Arrays.asList( + DirectiveUtils.getUniqueBlock(cb, BlockInterface.PRS), + DirectiveUtils.getUniqueBlock(cb, BlockInterface.SUBCELL) + ); + final Map prsSubcell = + DirectiveUtils.getMultipleBlockDirective(db, directive, type); + func.execute(prsSubcell); + } + + /** + * Merge cell level directives with prs/subcells level directives. + **/ + private void + getAstaIgnore(final CellInterface cell, + final Set,HalfOp>> result, + final String directive) { + processIgnoreDirective(cell, directive, + new UnaryAction() { + public void execute(Map m) { + getAstaIgnore(cell.getFullyQualifiedType(), result, + directive, m); + } + } + ); + } + + /** + * Merge cell level directives with prs/subcells level directives + * (possibly including slint_ignore directives); store result in a + * cache. + **/ + private Set,HalfOp>> + getAstaIgnore(final CellInterface cell) { + final String fqcn = cell.getFullyQualifiedType(); + Set,HalfOp>> result = + astaIgnoreCache.get(fqcn); + if (result == null) { + result = new HashSet, + HalfOp>>(); + getAstaIgnore(cell, result, DirectiveConstants.ASTA_IGNORE); + + if (result.isEmpty()) { + result = Collections., + HalfOp>>emptySet(); + } + astaIgnoreCache.put(fqcn, result); + } + return result; + } + + private void recordMeasureDelay(final HierName prefix, + final HierName instance, + final CellInterface subcell, + final InstanceData instData, + final CadenceInfo cinfo) { + final double delayBias = + instance == null ? instData.getDelayBias(null) + : instData.getDelayBias(instance); + + final MeasuredDelay delay = + new MeasuredDelay(prefix, instance, subcell, delayBias); + + final AliasedMap ports = cinfo.getPortNodes(); + for (Iterator i = ports.getCanonicalKeys(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + if (Boolean.FALSE.equals(ports.getValue(port))) continue; + + final HierName full = + HierName.append(prefix, HierName.append(instance, port)); + final Node target = lookupNode(full); + if (boundaryNodes != null) boundaryNodes.add(target); + assert target != null : "Cannot get node for " + full; + HierName fullCanon = canonize(target.getName(), this.cinfo); + if (fullCanon == null) fullCanon = target.getName(); + for (boolean dir : new boolean[] { true, false }) { + final Triplet[] ts = + instData.getMeasuredDelay(dir, fullCanon); + final double extraDelay = + instData.getExtraDelay(dir, fullCanon); + delay.addMeasured(target, port, dir, ts, extraDelay, + measuredProcs); + } + } + + boundaryDelays.add(delay); + } + + private Map grayboxes = new HashMap(); + + private void processSignoffConstant(final HierName prefix, + final Map signoffConstant) { + for (Iterator i = signoffConstant.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName full = + prefixName(prefix, (HierName) entry.getKey()); + final Node node = findNode(full); + // node might not exist, because the instance containing the + // node is simulated in csp + final HierName name = node == null ? full : node.getName(); + constantNodes.put(name, entry.getValue()); + } + } + + private void processUnusedPrs(final HierName prefix, + final Map unusedPrs) { + final UnaryFunction canonizeFunc = new CanonizePrs(prefix); + for (Iterator i = unusedPrs.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final ProductionRuleSet ruleSet = + (ProductionRuleSet) entry.getKey(); + final boolean unused = + ((Boolean) entry.getValue()).booleanValue(); + for (Iterator j = ruleSet.getProductionRules(); j.hasNext(); ) { + final ProductionRule rule = (ProductionRule) j.next(); + final HierName target = + (HierName) canonizeFunc.execute(rule.getTarget()); + final BooleanExpressionInterface prefixed = + BooleanUtils.mapBooleanExpressionHierNames( + rule.getGuard(), canonizeFunc); + Set s = (Set) possiblyUnusedRules.get(target); + if (s == null) { + s = new HashSet(); + possiblyUnusedRules.put(target, s); + } + s.addAll(prefixed.DNFForm().getDisjuncts()); + } + } + } + + /** + * Returns true if there exist a rule from guard -> target. + **/ + private boolean ruleExist(HalfOp guard, HalfOp target) { + for (Rule r : guard.node.getTargets(guard.getDir())) { + if (r.target == target.node && r.dir == target.getDir()) { + return true; + } + } + return false; + } + + private String + getSlintIgnoreError(final String message, + final String fqcn, + final HierName prefix, + final Collection> halfops) { + final StringBuilder sb = new StringBuilder(); + sb.append("Invalid slint_ignore directive (" + fqcn + "/" + prefix + + "): " ); + sb.append(message); + sb.append(": slint_ignore({"); + boolean first = true; + for (Pair halfop : halfops) { + if (first) first = false; + else sb.append(", "); + sb.append(halfop.getFirst()); + final Boolean up = halfop.getSecond(); + if (up != null) sb.append(up ? "+" : "-"); + } + sb.append("}"); + return sb.toString(); + } + + private void updateSlintIgnores(final String fqcn, + final HierName prefix, + final Map directives) { + for (Iterator i = directives.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Collection> halfops = + (Collection>) entry.getKey(); + if (halfops.size() < 2) { + System.err.println(getSlintIgnoreError( + "path too short", + fqcn, prefix, halfops)); + } else { + ArrayList> path = + new ArrayList>(halfops.size()); + HalfOp lastOp = null; + for (Pair p : halfops) { + final HalfOp[] expanded = getHalfOp(p); + if (expanded.length != 1) { + System.err.println(getSlintIgnoreError( + "direction required " + expanded[0].node, + fqcn, prefix, halfops)); + break; + } + + final HalfOp op = findHalfOp(prefix, expanded[0]); + if (op == null) { + System.err.println(getSlintIgnoreError( + "can't find node " + expanded[0].node, + fqcn, prefix, halfops)); + break; + } else { + if (lastOp != null && !ruleExist(lastOp, op)) { + System.err.println(getSlintIgnoreError( + "no rule " + lastOp + " -> " + op, + fqcn, prefix, halfops)); + break; + } else { + path.add(op); + } + } + lastOp = op; + } + + // if no errors processing the directive + if (path.size() == halfops.size()) { + Map>,Boolean> ignores = + slintIgnores.get(path.get(0)); + if (ignores == null) { + ignores = + new HashMap>,Boolean>(); + slintIgnores.put(path.get(0), ignores); + } + ignores.put(path, (Boolean) entry.getValue()); + } + } + } + } + + /** + * Look for instantiations of STATICIZER and WEAK_INV in the netlist + * block to determine dynamic nodes; construct fake production rules + * needed to model the small inverter in a full staticizer. + **/ + private Pair>, ProductionRuleSet> + getStaticizerInfo(final CellInterface cell) { + Map> result = + staticizerInfo.get(cell.getFullyQualifiedType()); + ProductionRuleSet resultPrs = + staticizerPrs.get(cell.getFullyQualifiedType()); + if (result == null) { + final Map> info = + new HashMap>(); + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + final ProductionRuleSet prs = new ProductionRuleSet(); + nb.getCDLTemplate().execute( + new com.avlsi.file.cdl.parser.CDLFactoryAdaptor() { + public void makeCall(HierName name, String subName, + HierName[] args, Map params, + Environment env) { + if (subName.startsWith("gate.STATICIZER.")) { + final HierName GND = args[0]; + final HierName Vdd = args[1]; + final HierName node = args[2]; + + final HierName invNode = + CellUtils.getSmallInverterNode(name) + .getFirst(); + info.put(node, + new Pair(invNode, true)); + + final HierNameAtomicBooleanExpression guard = + new HierNameAtomicBooleanExpression( + true, node); + prs.addProductionRule(new ProductionRule( + guard, + invNode, GND, ProductionRule.DOWN, + false, false, false, false, 100, false)); + prs.addProductionRule(new ProductionRule( + guard.negated(), + invNode, Vdd, ProductionRule.UP, + false, false, false, false, 100, false)); + } else if (subName.startsWith("gate.WEAK_INV.")) { + info.put(args[3], + new Pair(args[2], false)); + } + } + }); + + if (info.isEmpty()) { + result = Collections.emptyMap(); + resultPrs = null; + } else { + result = info; + resultPrs = prs; + } + staticizerInfo.put(cell.getFullyQualifiedType(), result); + staticizerPrs.put(cell.getFullyQualifiedType(), resultPrs); + } + + return new Pair>, + ProductionRuleSet>(result, resultPrs); + } + + /** + * Annotate dynamic nodes and their inverses. + **/ + private void annotateDynamicNodes( + final CellInterface cell, + final HierName prefix, + final Map> stats) { + for (Map.Entry> entry : + stats.entrySet()) { + final Node dynamicNode = + findNode(HierName.prefixName(prefix, entry.getKey())); + if (dynamicNode == null) { + System.err.println("Dynamic node not found: " + + entry.getKey() + " in " + prefix + "/" + + cell.getFullyQualifiedType()); + } else { + if (dynamicNode.getBreakpoint()) { + System.err.println( + "Dynamic node multiply staticized: " + + entry.getKey() + " in " + prefix + "/" + + cell.getFullyQualifiedType()); + } + + // mark as dynamic node + dynamicNode.setBreakpoint(true); + + // inverse of dynamic node + final Node invNode = + lookupNode(HierName.prefixName( + prefix, entry.getValue().getFirst())); + + // annotate whether it's a full staticizer + if (entry.getValue().getSecond()) { + dynamicNode.setRandom(true); + } + + // set inverse node of dynamic node + dynamicNode.enabler = invNode; + } + } + } + + private void process( + final HierName prefix, + final HierName abstractPrefix, CellInterface cell, + int depth, int defaultBehavior, + boolean slaveAbove, + final InstanceData instData, + final Map,Set>> astaIgnore, + final HierName grayboxPrefix, + final boolean inGraybox, + final boolean isEnv) { + if (depth < 2) System.out.print("."); + // process subcells in lexicographic order, to ensure the random + // seed associated with CSP processes can be reproduced + Iterator it = new SortingIterator( + cell.getSubcellPairs(), + new Comparator() { + public int compare(Object o1, Object o2) { + final Pair p1 = (Pair) o1; + final Pair p2 = (Pair) o2; + return ((HierName) p1.getFirst()).compareTo( + (HierName) p2.getFirst()); + } + }); + // System.out.println("prefix is " + prefix); + if (!it.hasNext() && !cell.isNode()) { + System.out.println(prefix + " has no subcells --" + + cell.getFullyQualifiedType() ); + } + + // process signoff_constant directives + processSignoffConstant( + prefix, + DirectiveUtils.getSubcellDirective( + cell, + DirectiveConstants.SIGNOFF_CONSTANT, + DirectiveConstants.DEEP_NODE_TYPE)); + + // process unused_prs directives + processUnusedPrs( + prefix, + DirectiveUtils.getSubcellDirective( + cell, + DirectiveConstants.UNUSED_PRS, + DirectiveConstants.DEEP_RULE_TYPE)); + + if (isAstaEnabled() && + ObjectUtils.equals(abstractPrefix, envCell)) { + if (astaContext == null) { + recordMeasureDelay(abstractPrefix, null, cell, + instData, cadencizer.convert(cell)); + } else { + final Map nodes = + new HashMap(); + for (HierName name : astaContext.getNames()) { + Node node = findNode(name); + if (node == null) { + node = lookupNode(canonize(name, this.cinfo)); + } + nodes.put(name, node); + } + astaContext.setNodes(nodes); + } + } + + while (it.hasNext()) { + final Pair p = (Pair) it.next(); + final CellInterface ci = (CellInterface)p.getSecond(); + if (ci.isNode()) continue; + final HierName instName = (HierName) p.getFirst(); + final HierName name = HierName.append(prefix, instName); + final HierName abstractName = HierName.append(abstractPrefix, + instName); + // System.out.println("name is " + name); + // System.out.println("CoSimInfo for " + name.getAsString('.') + " is"); + // System.out.println(ci.getCoSimInfo()); + final String abstractNameString = + abstractName.getAsString('.'); + assert params != null; + int behavior = + (params == null) ? + CoSimParameters.UNSPEC : + params.lookupBehavior(abstractNameString); + if (isAstaEnabled() && behavior == CoSimParameters.NULL) { + recordMeasureDelay(abstractPrefix, instName, ci, + instData, cadencizer.convert(ci)); + System.out.println("ASTA blackbox found: " + + abstractNameString + "/" + + ci.getFullyQualifiedType()); + } + + final HierName grayboxName; + boolean subGraybox = inGraybox; + if (isAstaEnabled() && CellUtils.isAstaGraybox(ci)) { + subGraybox = true; + System.out.println("ASTA graybox found: " + + abstractNameString + "/" + + ci.getFullyQualifiedType()); + HierName inst = grayboxes.get(ci.getFullyQualifiedType()); + if (inst == null) { + if (!CellUtils.isRouted(ci)) { + System.err.println( + "ERROR: ASTA graybox " + + ci.getFullyQualifiedType() + " is not routed"); + errorOccurred = true; + } + grayboxes.put(ci.getFullyQualifiedType(), name); + grayboxName = null; + } else { + grayboxName = inst; + } + } else { + if (grayboxPrefix == null) { + grayboxName = null; + } else { + grayboxName = HierName.append(grayboxPrefix, instName); + } + } + + if (subGraybox) { + final CadenceInfo cinfo = cadencizer.convert(ci); + final AliasedSet nodes = cinfo.getLocalNodes(); + final AliasedMap ports = cinfo.getPortNodes(); + for (Iterator i = nodes.getCanonicalKeys(); i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + if (ports.getCanonicalKey(canon) != null) continue; + final Node curr = + lookupNode(HierName.append(name, canon)); + // point the primary node to itself + final Node primary = grayboxName == null ? curr : + lookupNode(HierName.append(grayboxName, canon)); + assert curr.enabler == null; + curr.enabler = primary; + } + } + + behavior = behavior & ~CoSimParameters.NULL; + + // assert behavior != params.UNSPEC; + if (behavior == CoSimParameters.UNSPEC) { + // if (name.getAsString('.').equals("_env")) + // behavior = params.BEH_ALL; + // else + behavior = defaultBehavior; + } + + // use futureBehavior because we must be able to pass BEH_ALL + // to createModels, but is_cosim needs to be computed + // without the possibility of BEH_ALL + final int futureBehavior = + behavior == CoSimParameters.BEH_ALL ? + defaultBehavior : + behavior; + final boolean is_cosim = + ((futureBehavior & CoSimParameters.DIGITAL) != 0) && + (futureBehavior != CoSimParameters.DIGITAL); + + final int arbitrationMode; + // Note that we set the arbitration mode even if we + // aren't doing a java or csp simulation. This is + // harmless because nothing will look at it. + if (is_cosim) + arbitrationMode = Arbiter.LINKED_SLAVE; + else if (slaveAbove) + arbitrationMode = Arbiter.LINKED_MASTER; + else + arbitrationMode = Arbiter.NON_LINKED; + + final InstanceData newInstData = ci.isChannel() ? + DUMMY_INSTANCE + : instData.translate(cell, ci, (HierName) p.getFirst(), + cadencizer); + + final Map,Set>> newAstaIgnore = + isAstaEnabled() ? updateAstaIgnore(astaIgnore, ci, name) + : astaIgnore; + + // special slint handling for staticizers + final Pair>, + ProductionRuleSet> statsPrs; + if (isSlintEnabled() && ci.containsNetlist()) { + statsPrs = getStaticizerInfo(ci); + } else { + statsPrs = null; + } + + createModels(name, ci, behavior, arbitrationMode, + params.lookupVerilogLevel(abstractNameString), + newInstData, newAstaIgnore, + statsPrs == null ? null : statsPrs.getSecond(), + isEnv); + + if (statsPrs != null) { + annotateDynamicNodes(ci, name, statsPrs.getFirst()); + } + + behavior = futureBehavior; + + if ((behavior & CoSimParameters.JAVA) != 0 + && ! (ci.getJavaCoSimInfo().isEmpty())) + /* If a java cosimulation is desired, and we have found a + * java model for this cell, do not simulate java in + * subcells of this cell. */ + behavior = (behavior & ~CoSimParameters.JAVA); + + if ((behavior & CoSimParameters.CSP) != 0 + && ci.containsRunnableCsp()) + /* If a csp cosimulation is desired, and we have found a + * csp model for this cell, do not simulate csp in + * subcells of this cell. */ + behavior = (behavior & ~CoSimParameters.CSP); + + if ((behavior & CoSimParameters.VERILOG) != 0) + /* If a verilog cosimulation is desired, and we have + * found a verilog model for this cell, do not simulate + * verilog in subcells of this cell. */ + behavior = (behavior & ~CoSimParameters.VERILOG); + + if (is_cosim) + process(CoSimParameters.addCoSimDigitalSuffix(name), + abstractName, ci, depth+1, CoSimParameters.DIGITAL, + true, newInstData, newAstaIgnore, grayboxName, + subGraybox, isEnv); + else if (behavior == CoSimParameters.DIGITAL) + process(name, abstractName, ci, depth+1, behavior, + slaveAbove, newInstData, newAstaIgnore, grayboxName, + subGraybox, isEnv); + else if (behavior != 0) + throw new AssertionError("Cosim error: Invalid behavior"); + + } + + // process slint_ignore directives + if (isSlintEnabled()) { + final String fqcn = cell.getFullyQualifiedType(); + processIgnoreDirective(cell, DirectiveConstants.SLINT_IGNORE, + new UnaryAction() { + public void execute(Map m) { + updateSlintIgnores(fqcn, prefix, m); + } + } + ); + } + } + + protected void createModels( + final HierName prefix, + final CellInterface cell, + final int behavior, + final int arbitrationMode, + final String verilogLevel, + final InstanceData instData, + final Map,Set>> astaIgnore, + final ProductionRuleSet extraPrs, + final boolean isEnv) { + + // if (prefix == null) + // System.out.println("prefix is null!"); + // else + // System.out.println("Behavior of cell " + prefix.getAsString('.') + + // " is " + behavior); + + final long seed = rand.nextLong(); + ChannelDictionary dict = null; + + if (behavior == CoSimParameters.BEH_ALL) { /* Do everything */ + if (cell.containsCompletePrs()) + createRules(prefix, cell, instData, astaIgnore, extraPrs, + isEnv); + dict = cell.getCoSimInfo(behavior).createNodeChannels(prefix, cell, getDelayTau(DIGITAL_TAU)); + try { + if (cell.getJavaCoSimInfo().getClassName() != null) + cell.buildJavaClass(prefix, dict, m_DeviceLoader, + arbitrationMode); + if (cell.containsRunnableCsp()) { + cell.buildCSPClass(prefix, dict, arbitrationMode, + emitCSPCoverageProbes && !isEnv, + seed, getDelayTau(DIGITAL_TAU)); + // let prs handle DFT + if (!cell.containsCompletePrs()) + handleDftChannels(prefix, + cell.getCoSimInfo(behavior)); + } + } catch (ClassNotFoundException e1) { + System.out.println("Class of " + prefix.getAsString('.') + + " not found: " + e1.getMessage()); + errorOccurred = true; + } catch (InstantiationException e2) { + System.out.println(); // get off "applying models" line + if (!doSelfPrint(e2, System.out)) + System.out.println("Error instantiating class of " + + prefix.getAsString('.') + + " of type " + + cell.getFullyQualifiedType() + + " --- " + e2.getMessage()); + errorOccurred = true; + } catch (DeviceConstructionException e) { + // TODO: something better here! + Debug.assertTrue(false, e.getMessage()); + errorOccurred = true; + } + return; + } + assert behavior != CoSimParameters.UNSPEC; + if (behavior == 0) /* Do nothing */ + return; + /* Digital if not otherwise specified */ + if (behavior == CoSimParameters.UNSPEC || + behavior == CoSimParameters.DIGITAL) { + /* Digital-only */ + createRules(prefix, cell, instData, astaIgnore, extraPrs, + isEnv); + return; + } + if ((behavior & CoSimParameters.VERILOG) != 0) { + // Do not support cosimulation with verilog. + if (behavior != CoSimParameters.VERILOG) + throw new IllegalStateException + ("Cosimulation with verilog not supported."); + + final CoSimInfo coSimInfo = + cell.getCoSimInfo(CoSimParameters.CSP); + + linkVerilogPorts(prefix.getAsString('.'), cell, + verilogLevel, cadencizer); + + // TODO: make sure that the verilog has been instantiated + + return; + } + if ((behavior & CoSimParameters.DIGITAL) != 0) { + /* Cosimulation with digital. At the moment, this is the only + * kind of cosimulation supported. */ + createRules(CoSimParameters.addCoSimDigitalSuffix(prefix), cell, + instData, astaIgnore, extraPrs, isEnv); + dict = CoSimInfo.createSplitMerges + (cell.getCoSimInfo(behavior), prefix, cell, cosimSlack, + verbose); + } else { + dict = cell.getCoSimInfo(behavior).createNodeChannels(prefix, cell, getDelayTau(DIGITAL_TAU)); + } + try { + // XXX: We currently do not support cosimulation of JAVA and CSP. + // When support is added, we will have to tweak the + // arbitrationMode as follows: if the mode is master, both + // cannot be master, so make one a master and the other a slave. + // We probably want java to be the master by analogy with + // prs being master. Java is more detailed than csp, hence + // closer to prs. + if ((behavior & ~CoSimParameters.DIGITAL) == CoSimParameters.JAVA) { + /* Create Java block Java class */ + cell.buildJavaClass(prefix, dict, m_DeviceLoader, + arbitrationMode); + } else if ((behavior & ~CoSimParameters.DIGITAL) + == CoSimParameters.CSP) { + /* Create CSP Java class */ + cell.buildCSPClass(prefix, dict, arbitrationMode, + emitCSPCoverageProbes && !isEnv, + seed, getDelayTau(DIGITAL_TAU)); + // if cosimulating with prs, let prs handle DFT + if (behavior == CoSimParameters.CSP) + handleDftChannels(prefix, cell.getCoSimInfo(behavior)); + } else + throw new IllegalStateException( + "Cell has illegal cosim behavior parameter specified"); + } catch (ClassNotFoundException e1) { + System.out.println("Class of " + prefix.getAsString('.') + + " not found: " + e1.getMessage()); + errorOccurred = true; + } catch (InstantiationException e2) { + System.out.println(); // get off "applying models" line + if (!doSelfPrint(e2, System.out)) + System.out.println("Error instantiating class of " + + prefix.getAsString('.') + " of type " + + cell.getFullyQualifiedType() + + " --- " + e2.getMessage()); + errorOccurred = true; + } catch (DeviceConstructionException e) { + // TODO: something better here! + e.printStackTrace(); + Debug.assertTrue(false, e.getMessage()); + errorOccurred = true; + } + } + + private void createRules( + final HierName prefix, + final CellInterface cell, + final InstanceData instData, + final Map,Set>> astaIgnore, + final ProductionRuleSet extraPrs, + final boolean isEnv) { + // System.out.println("Creating rules for " + (prefix != null ? prefix.getAsString('.') : "(null)")); + processSignoffConstant( + prefix, + DirectiveUtils.getPrsDirective( + cell, + DirectiveConstants.SIGNOFF_CONSTANT, + DirectiveConstants.NODE_TYPE)); + processUnusedPrs( + prefix, + DirectiveUtils.getPrsDirective( + cell, + DirectiveConstants.UNUSED_PRS, + DirectiveConstants.RULE_TYPE)); + + createRulesFromSet(prefix, cell, cell.getProductionRuleSet(), + false, instData, astaIgnore, isEnv); + if (extraPrs != null) { + createRulesFromSet(prefix, cell, extraPrs, false, instData, + astaIgnore, isEnv); + } + if (handleAsserts) { + createRulesFromSet(prefix, cell, + cell.getAssertedProductionRuleSet(), true, + instData, astaIgnore, isEnv); + } + } + + private AndBooleanExpressionInterface filterAstaIgnore( + final AndBooleanExpressionInterface and, + final HierName prefix, + final HalfOp target, + final Map,Set>> astaIgnore, + final Node localVdd, + final Node localGND) { + final Collection conjuncts = and.getConjuncts(); + final Collection result = new ArrayList(); + for (Iterator i = conjuncts.iterator(); i.hasNext(); ) { + HierNameAtomicBooleanExpression a; + a = (HierNameAtomicBooleanExpression) i.next(); + final HierName h = a.getName(); + final HierName fullName = prefixName(prefix, h); + final Node guard = lookupNode(fullName); + String reason = null; + if (guard == localGND) { + reason = "GND"; + } else if (guard == localVdd) { + reason = "Vdd"; + } else if (matchAstaIgnore(astaIgnore, + new HalfOp(guard, + a.getSense()), + target)) { + reason = "directive"; + } else { + result.add(a); + } + if (reason != null) { + ui_out_verbose("ASTA ignored (" + reason + "): " + + guard.getName() + + (a.getSense() ? "+" : "-") + " -> " + + target.node.getName() + + (target.direction ? "+" : "-") + "\n"); + } + } + return new AndBooleanExpression(and.getSense(), result); + } + + /** + * helper function for createRules. Targets of asserted rule + * are assumed to be weird globals that don't need prefixing. + * (This prevents the creation of x.L.ERROR, x.R.ERROR, etc.) + **/ + private void createRulesFromSet( + final HierName prefix, + final CellInterface cell, + final ProductionRuleSet prsSet, + boolean assertedP, + final InstanceData instData, + final Map,Set>> astaIgnore, + final boolean isEnv) { + // unimplementable directives + final boolean unimplementable = + ((Boolean) DirectiveUtils.getTopLevelDirective + (cell, DirectiveConstants.UNIMPL)).booleanValue(); + + final boolean coverage_ignore = + ((Boolean) DirectiveUtils.getTopLevelDirective + (cell, DirectiveConstants.COVERAGE_IGNORE)).booleanValue(); + + final float defaultSlew = + ((Float) DirectiveUtils.getTopLevelDirective + (cell, DirectiveConstants.DEFAULT_SLEW)).floatValue(); + + final AliasedSet localNodes = + cadencizer.convert(cell).getLocalNodes(); + // REVIEW: perhaps there is a better way than using Cadencize + final CellDelay cellDelay = + new CellDelay(cell, localNodes, prsSet.getProductionRules(), + instData.getDelayBias(null), true); + + final Node localVdd, localGND; + try { + localVdd = findNode(HierName.makeHierName(prefix, "Vdd")); + localGND = findNode(HierName.makeHierName(prefix, "GND")); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName: " + prefix); + } + + // process rules in cell + for (Iterator i = prsSet.getProductionRules(); i.hasNext(); ) { + final ProductionRule pr = (ProductionRule) i.next(); + final HierName h; + if (assertedP) h = pr.getTarget(); + else h = prefixName( prefix, pr.getTarget() ); + final int d = pr.getDirection(); + final boolean updir = d == ProductionRule.UP; + + final HierName canonTarget = + (HierName) localNodes.getCanonicalKey(pr.getTarget()); + + final float extraDelay = + instData.getExtraDelay(updir, canonTarget); + final float afterDelay = + cellDelay.getDelay(pr.getTarget(), updir, 100) + extraDelay; + + // an after 0 production rule overrides estimated or measured + // delays associated the rule if it is also annotated as + // "isochronic" and "unstab" + final boolean isAfterZero = + pr.isIsochronic() && pr.isUnstable() && afterDelay == 0; + + final float estimated = + useDelayMode(ESTIMATED_TAU) ? + instData.getEstimatedDelay(updir, canonTarget) : + Float.NaN; + + float fdelay; + if (isAfterZero || Float.isNaN(estimated)) { + fdelay = afterDelay; + if (useDelayMode(DIGITAL_TAU)) { + fdelay *= getDelayTau(DIGITAL_TAU); + } + } else { + final float signoff = + instData.getEstimatedDelaySignoff(updir, canonTarget); + fdelay = 100 * + (Float.isNaN(signoff) ? estimated : signoff) / + getDelayTau(ESTIMATED_TAU); + } + + final int delay = Math.round(fdelay); + final boolean timed = pr.isTimed(); + final boolean isochronic = pr.isIsochronic(); + final Node target = lookupNode(h); + + target.setSlew(defaultSlew); + + // mark unstable nodes + if (pr.isUnstable() || pr.isMetastable()) + target.setUnstable(updir); + + final Triplet[] measuredRaw = useDelayMode(MEASURED_TAU) ? + instData.getMeasuredDelay(updir, target.getName()) : null; + + final float measuredCap = + instData.getMeasuredCap(target.getName()); + final float estimatedCap = + instData.getEstimatedCap(target.getName()); + + // Warn about 0 delay rules, and missing measure_delay + // directives unless cell is unimplementable or used in the + // environment + if (!unimplementable && !isEnv) { + if (delay == 0) { + final String type = cell.getFullyQualifiedType(); + final String node = pr.getTarget().getAsString('.'); + Pair warnPair = new Pair(type, node); + // don't warn redundantly + if (warnedCells.add(warnPair)) { + System.err.print("\nWarning: " + type + "/" + + node + (updir ? "+" : "-") + + " has zero delay"); + if (isAfterZero) { + String ignored = ""; + if (!Float.isNaN(estimated)) { + ignored = " estimated_delay"; + } + if (measuredRaw != null) { + if (!ignored.equals("")) ignored += " and"; + ignored += " measured_delay"; + } + if (!ignored.equals("")) { + System.err.print( + ";" + ignored + + " directives are ignored because" + + " of isochronic unstab rule"); + } + } + System.err.println('.'); + } + } + if (!assertedP && useDelayMode(MEASURED_TAU) && + measuredRaw == null && !isAfterZero) { + Pair warnPair = new Pair(target, updir ? Boolean.TRUE + : Boolean.FALSE); + if (!warnedCells.contains(target) && + warnedCells.add(warnPair)) { + final String type = cell.getFullyQualifiedType(); + System.err.println("\nWarning: Using " + + (Float.isNaN(estimated) ? "digital" : + "estimated") + + " delay for (" + h + "/" + type + ") " + + target.getName() + (updir ? "+" : "-")); + } + } + if (!assertedP && Float.isNaN(measuredCap) && + useMeasuredCap()) { + Pair warnPair = new Pair(target, "measured_cap"); + if (!warnedCells.contains(target) && + warnedCells.add(warnPair)) { + final String type = cell.getFullyQualifiedType(); + System.err.println("\nWarning: Using " + + (Float.isNaN(estimatedCap) ? "zero" : + "estimated") + + " cap for (" + h + "/" + type + ") " + + target.getName()); + } + } + } + + target.setCapacitance( + (Float.isNaN(measuredCapScale) ? 1 : measuredCapScale) * + (Float.isNaN(measuredCap) + ? (Float.isNaN(estimatedCap) ? 0 : estimatedCap) + : measuredCap)); + + final Pair[] measured; + if (measuredRaw == null || isAfterZero) { + measured = null; + } else { + final Pair[] raw = new Pair[measuredRaw.length]; + for (int j = 0; j < measuredRaw.length; ++j) { + final HierName prfx = + (HierName) measuredRaw[j].getFirst(); + final HierName trig = + (HierName) measuredRaw[j].getSecond(); + raw[j] = new Pair(trig == null ? null : lookupNode(HierName.append(prfx, trig)), measuredRaw[j].getThird()); + } + if (staVerbose) { + ProcessMeasuredDelay.printTable(raw, target, d, + "raw data"); + } + measuredWarningContext = target; + measured = + ProcessMeasuredDelay.update(raw, measuredProcs); + } + // create the dsim Rules + final BooleanExpressionInterface b = pr.getGuard(); + final OrBooleanExpressionInterface dnf = b.DNFForm(); + final HalfOp targetOp = new HalfOp(target, updir); + for (Iterator j = dnf.getDisjuncts().iterator(); j.hasNext(); ) + { + final AndBooleanExpressionInterface and = + (AndBooleanExpressionInterface)j.next(); + final AndBooleanExpressionInterface filtered; + if (isAstaEnabled()) { + filtered = filterAstaIgnore(and, prefix, targetOp, + astaIgnore, localVdd, + localGND); + if (filtered.getConjuncts().isEmpty()) continue; + } else { + filtered = and; + } + + createHierRule(filtered, target, d, delay, + Float.isNaN(estimated) ? DIGITAL_TAU + : ESTIMATED_TAU, + timed, isochronic, + pr.isAbsolute(), assertedP, measured, prefix, + defaultSlew, localNodes, + coverage_ignore || assertedP || isEnv, + astaGrayboxRules); + } + } + } + + protected void createHierRule( + AndBooleanExpressionInterface term, Node n, + int direction, int delay, byte delay_type, + boolean timed, boolean isochronic, + boolean absoluteDelay, boolean assertedP, + Pair[] delays, + HierName prefix, float defaultSlew, + AliasedSet localNodes, + final boolean coverage_ignore, + final Map,BitSet>,Rule> astaGrayboxRules) { + DSim.this.createHierRule(term, n, direction, delay, delay_type, + timed, isochronic, absoluteDelay, + assertedP, delays, prefix, defaultSlew, + localNodes, coverage_ignore, + astaGrayboxRules); + } + + protected boolean isAstaEnabled() { + return DSim.this.isAstaEnabled(); + } + } + + private class OptimizeThresholdCreator extends ModelCreator { + public OptimizeThresholdCreator(CoSimParameters params, + Cadencize cadencizer) { + super(params, cadencizer); + } + + protected void createModels( + final HierName prefix, + final CellInterface cell, + final int behavior, + final int arbitrationMode, + final String verilogLevel, + final InstanceData instData, + final Map,Set>> astaIgnore, + final ProductionRuleSet extraPrs, + final boolean isEnv) { + super.createModels(prefix, cell, behavior, arbitrationMode, + verilogLevel, instData, astaIgnore, extraPrs, + isEnv); + if (CellUtils.isRouted(cell) && !CellUtils.isLeaf(cell)) { + if (routedInstancesByType == null) { + routedInstancesByType = + new MultiMap( + new HashMap>(), + MultiMap. arrayListFactory()); + } + routedInstancesByType.put(cell.getFullyQualifiedType(), prefix); + } + } + + protected void createHierRule( + AndBooleanExpressionInterface term, final Node n, + final int direction, int delay, byte delay_type, + boolean timed, boolean isochronic, + boolean absoluteDelay, boolean assertedP, + Pair[] delays, + final HierName prefix, float defaultSlew, + AliasedSet localNodes, + final boolean coverage_ignore, + final Map,BitSet>,Rule> astaGrayboxRules) { + if (delays == null) return; + + // identical types have the same data, so skip it + final CadenceInfo curr = + (CadenceInfo) getSubcell(cinfo, prefix.tail()); + final CadenceInfo prev = + (CadenceInfo) getSubcell(savedCadenceInfo, prefix); + if (curr == prev) return; + + boolean defaultDelay = false; + final LinkedList measuredDelay = new LinkedList(); + final int length = term.getConjuncts().size(); + Set common = null; + for (Iterator i = term.getConjuncts().iterator(); i.hasNext(); ) { + final HierNameAtomicBooleanExpression a + = (HierNameAtomicBooleanExpression) i.next(); + final HierName h = a.getName(); + + final HierName fullName = prefixName(prefix, h); + final Node guard = lookupNode(fullName); + final Set affected = new HashSet(); + guard.foreachRule( + new Node.RuleFunc() { + public void accept(final Rule r, final int sense, + final Node dummy) { + if (r.dir == direction && r.target() == n && + r.prefix.equals(prefix)) + affected.add(r); + } + } + ); + if (common == null) { + common = affected; + } else { + common.retainAll(affected); + } + + for (int k = 0; k < delays.length; ++k) { + final Node trigger = (Node) delays[k].getFirst(); + if (trigger == null) { + if (!defaultDelay) { + measuredDelay.addLast(new Pair(null, delays[k].getSecond())); + defaultDelay = true; + } + } else if (guard.equals(trigger)) { + measuredDelay.addFirst(new Pair(guard, delays[k].getSecond())); + } + } + } + + for (Rule r : common) { + r.addMeasured((Pair[]) measuredDelay.toArray(new Pair[0]), 1); + } + } + + protected boolean isAstaEnabled() { + return false; + } + } + + /* Once an AliasedSet is saved, it is no longer safe to make new aliases + * to names referenced in the AliasedSet. */ + private void saveAliases(AliasedSet s) { + final Iterator i = s.getCanonicalKeys(); + while (i.hasNext()) { + final HierName canon = (HierName)i.next(); + lookupNode(canon); + final Iterator j = s.getAliases(canon); + while (j.hasNext()) { + final HierName alias = (HierName)j.next(); + if (alias.equals(canon)) { + continue; + } + aliasNode(canon, alias); + } + } + } + + public Iterator getDeviceNames() { + return sched.getDeviceNames(); + } + + public AbstractDevice getDevice(final String deviceName) { + return sched.getDevice(deviceName); + } + + + /** Turn debugging output on or off (i.e. exception stack trace dumping) **/ + public void setDebug(boolean state) { + debug = state; + } + + private void linkVerilogPorts + (final /*@ non_null @*/ String instanceName, + final /*@ non_null @*/ CellInterface cell, + final /*@ non_null @*/ String verilogLevel, + final /*@ non_null @*/ Cadencize cadencizer) { + + final Map markedPorts = CellUtils.markPorts(cell); + final AliasedMap portNodes = cadencizer.convert(cell).getPortNodes(); + + for (final Iterator iCanon = portNodes.getCanonicalKeys(); + iCanon.hasNext(); ) { + final HierName canonPort = (HierName) iCanon.next(); + final String nodeName = canonPort.getAsString('.'); + + for (final Iterator iConn = portNodes.getAliases(canonPort); + iConn.hasNext(); ) { + final HierName connPort = (HierName) iConn.next(); + final String connNodeName = connPort.getAsString('.'); + final Integer dir = (Integer) markedPorts.get(connNodeName); + if (dir == null) { + assert iConn.hasNext(); + // keep looking for a node connected to the canonical + // port + continue; + } + final int direction = dir.intValue(); + final String fullNodeName = instanceName + '.' + nodeName; + + final Node node = findNode(fullNodeName); + System.err.println("dsim node: " + node); + final SharedBus sharedBus = + new VerilogSharedBus + ("top." + VerilogUtil.escapeIfNeeded(instanceName), + VerilogUtil.escapeIfNeeded(nodeName), + sigscan, opts, 1); + System.err.println("Creating shared bus: " + + sharedBus.getFullname()); + if (direction == PortDefinition.IN) { + System.err.println("Creating input node for verilog: " + + fullNodeName); + sharedBus.drivenByNode(node, 0); + } else if (direction == PortDefinition.OUT) { + System.err.println("Creating output node for verilog:" + + fullNodeName); + sharedBus.driveNode(node, 0); + } else { + System.err.println("Unknown direction for " + nodeName + + " not added."); + } + // we found a node connected to the canonical port, + // stop there. + break; + } + } + } + + // + //Sigscan Support + // + + //The Signalscan Database used by DSim to put any nodes or sharedbuses + //it creates into + private Sigscan sigscan=null; + //The DebugOpts for any SharedBuses DSim creates + private DebugOpts opts=new DebugOpts(); + + private MultiMap nodesToAliases =null; + + MultiMap generateNodeToAliases(final Set filter) { + final MultiMap nodesToAliases = + new MultiMap( + new HashMap>(), + MultiMap.arrayListFactory()); + for (Map.Entry entry : nodes.entrySet()) { + final Node node = entry.getValue(); + if (filter == null || filter.contains(node)) { + nodesToAliases.put(node, entry.getKey()); + } + } + return nodesToAliases; + } + + /** + * @throws IllegalStateException + * If a sigscan database has not been opened with + * {@link #openSigscan}. + **/ + public void logSignals(String regex) { + logSignals(regex, false); + } + + public boolean logSignalsFixed(String sname) { + final HierName name; + try { + name = HierName.makeHierName(sname, '.'); + } catch (InvalidHierNameException e) { + System.err.println("Can't create HierName: " + sname); + return false; + } + + final Node node = findNode(name); + if (node == null) { + System.err.println("Can't find node: " + name); + return false; + } else { + HierName parent = name.getParent(); + String sparent = "global"; + if (parent != null) { + sparent = parent.toString(); + sname = name.getSuffixString(); + } + final NodeLogger logger = new NodeLogger(sigscan, sparent, sname); + logger.nodeChanged(node, getTime()); + node.addWatch(logger); + return true; + } + } + + public void logSignals(String regex, boolean useCanonialOnly) { + if (sigscan == null) + throw new IllegalStateException("No Sigscan database enabled"); + assert(nodes != null); + + String parsedRegex = StringUtil.getRegexForGlob(regex); + if (debug) + System.out.println( + "Searching node names with regex:\n\t"+parsedRegex); + + final Pattern pat; + try { + pat = Pattern.compile(parsedRegex); + } catch (java.util.regex.PatternSyntaxException e) { + throw new IllegalStateException("PatternSyntaxEror:\n\t"+ + e.getMessage()); + } + + int totalAliases = 0,totalNodes=0; + + if (useCanonialOnly) { + final Set seen = new HashSet(); + for (Node node : nodes.values()) { + HierName name = node.getName(); + if (seen.add(name)) { + String sname = name.toString(); + if (pat.matcher(sname).matches()) { + HierName parent = name.getParent(); + String sparent = "global"; + if (parent != null) { + sparent = parent.toString(); + sname = name.getSuffixString(); + } + final NodeLogger logger = + new NodeLogger(sigscan, sparent, sname); + logger.nodeChanged(node, getTime()); + node.addWatch(logger); + totalNodes++; + totalAliases++; + } + } + } + } else { + //First, build a mapping from nodes to aliases + if (nodesToAliases == null) { + nodesToAliases = generateNodeToAliases(null); + System.out.println("Node-to-alias map created, "+ + nodesToAliases.keySet().size()+ + " nodes, "+ + nodes.keySet().size()+ + " aliases."); + } + + for (Node node : nodesToAliases.keySet()) { + int numAliases = 0; + Collection alist = nodesToAliases.get(node); + //Here is where you would restrict the scope of the + //logging if you wanted (use arraylists instead of + //fixed arrays?) + //It may be easier to augment the AliasedLogger + //constructor to accomodate arraylists + String[] names = new String[alist.size()]; + String[] scopenames = new String[alist.size()]; + for (HierName name : alist) { + final HierName parent = name.getParent(); + final String matchString = name.toString(); + if (parent == null || pat.matcher(matchString).matches()) { + final String sparent; + final String sname; + if (parent == null) { + sparent = "global"; + sname = matchString; + } else { + sparent = parent.toString(); + sname = name.getSuffixString(); + } + + names[numAliases] = sname; + scopenames[numAliases] = sparent; + numAliases++; + totalAliases++; + //System.out.println("New alias = "+matchString); + } + } + if (numAliases > 0) { + final NodeLogger logger = + new NodeLogger(sigscan, scopenames, names, numAliases); + logger.nodeChanged(node, getTime()); + node.addWatch(logger); + totalNodes++; + } + } + + } + System.out.println(totalNodes+" nodes, "+totalAliases+ + " aliases added to database with "+ + "search string "+regex); + } + + /** + * Opens a sigscan database with the specified file name and + * a dsim to real time conversion factor of 5e-12 + * seconds per dsim time unit. + **/ + public void openSigscan(final String filename) throws SigscanException { + openSigscan(filename, 1e-9/1800d); + } + + /** The smallest unit of time in signalscan = 10^ timeScale seconds **/ + private static final int timeScale = -15; + + /** + * Opens a sigscan database with the specified file name and + * a dsim to real time conversion factor of secsPerDSim + * seconds per dsim time unit. + **/ + public void openSigscan( + final String filename, + final double secsPerDSim) + throws SigscanException { + sigscan = new Sigscan(filename,false, timeScale); + sigscan.setSigscanConversion(secsPerDSim/ + Math.pow(10, sigscan.getTimeScale())); + } + + /** + * Returns the sigscan database currently in use. + **/ + public Sigscan getSigscan() { return sigscan; } + + public DebugOpts getDebugOpts() { return opts; } + + public void setSigscan(Sigscan s) { this.sigscan = s; } + + /** + * get the value on a given channel; method will return an + * integer for the value on a given channel. The method + * can also be used to get the value on an array of channels + * + * INVALID CHANNEL (UNDEFINED) : -2 + * NEUTRAL: -1 + * UNSTALENODE IN LIST: -3 + * else { we actually have a valid value } + * + **/ + public int getChannel(String base){ + Node node = null; + int j, valid, value; + j = valid = value = 0; + while(true){ + try { + node = findNode(HierName.makeHierName(base+"."+j, '.')); + } catch(InvalidHierNameException e){ + return -2; + } + if(node == null)break; + if(node.getValue() == Node.VALUE_1) { value += j; valid++;} + else if(node.getValue() == Node.VALUE_U){valid+=2;} + j++; + } + if (valid == 1) return value; + else if (j==0) return -2; + else if (valid>0) return -3; + else return -1; + } + + + public void cleanup() { + if (sigscan != null) sigscan.close(); + } + + /** + * Returns the value of a given constant in a given cell. + */ + public Value getCellConstant(String cellName, String constName) + throws RecognitionException, TokenStreamException, + AmbiguousLookupException, CastSemanticException, + CastSyntaxException, IOException { + Environment env = new CellConstants(getCastFileParser()).getTopLevelConstants(cellName); + return env.lookup(Symbol.create(constName)); + } + + private static final Object INVERTED = Boolean.TRUE; + private static final Object NONINVERTED = Boolean.FALSE; + + /** + * Stores intermediate results from rule coverage analysis. + **/ + private class RuleCoverageData { + public final Map/*>*/ nodesByRule; + /** Set of rules that is always on. **/ + public final Set/**/ alwaysOnRules; + /** Set of rules that is always off. **/ + public final Set/**/ alwaysOffRules; + /** Set of nodes that is always on. **/ + public final Set/**/ alwaysOnNodes; + /** Set of nodes that is always off. **/ + public final Set/**/ alwaysOffNodes; + public RuleCoverageData(final Map nodesByRule, + final Set alwaysOnRules, + final Set alwaysOffRules, + final Set alwaysOnNodes, + final Set alwaysOffNodes) { + this.nodesByRule = nodesByRule; + this.alwaysOnRules = alwaysOnRules; + this.alwaysOffRules = alwaysOffRules; + this.alwaysOnNodes = alwaysOnNodes; + this.alwaysOffNodes = alwaysOffNodes; + } + } + + /** + * Stores statistics from rule coverage. + **/ + public static class RuleCoverageStatistics { + public final long totalRules; + public final long ignoredRules; + public final long constantRules; + public final long coveredRules; + public RuleCoverageStatistics(final long totalRules, + final long ignoredRules, + final long constantRules, + final long coveredRules) { + this.totalRules = totalRules; + this.ignoredRules = ignoredRules; + this.constantRules = constantRules; + this.coveredRules = coveredRules; + } + } + + /** + * Analyze production rules and propagate constants taking into account + * relevant directives. + * + * @param progress true means print progress indicator on stdout + * @return result of the analysis + */ + private RuleCoverageData computeRuleCoverage(final boolean progress) { + // this is where the real stuff begins + final Map nodesByRule = new IdentityHashMap(countNonAssertedRules()); + final Set alwaysOnRules = new Map2SetAdapter(new IdentityHashMap()); + final Set alwaysOffRules = new Map2SetAdapter(new IdentityHashMap()); + final Set alwaysOnNodes = new Map2SetAdapter(new IdentityHashMap()); + final Set alwaysOffNodes = new Map2SetAdapter(new IdentityHashMap()); + + Node.RuleFunc rf = new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (r.asserted) return; + + TreeMapWithInteger m = + (TreeMapWithInteger) nodesByRule.get(r); + if (m == null) { + m = new TreeMapWithInteger(); + nodesByRule.put(r, m); + } + m.count++; + Object sens = (sense == 0 ? INVERTED : NONINVERTED); + Object old = m.put(n.getName(), sens); + if (old != null && old != sens) { + if (progress) + System.out.print('\r'); + System.out.println("Badness: " + n.getName() + " has" + + " both senses in the same rule"); + } + } + }; + + final HierName gndName = HierName.makeHierName("GND"); + final Node gndNode = lookupNode(gndName); + final HierName vddName = HierName.makeHierName("Vdd"); + final Node vddNode = lookupNode(vddName); + + // Step 1: compute the Nodes that affect each Rule + + int i = 0, percent = -1; + int size = nodes.size(); + + Set doneThat = + new Map2SetAdapter(new IdentityHashMap(nodeCount)); + + for (Iterator it = nodes.values().iterator(); it.hasNext(); i++) { + if (progress) { + int p = (i + 1) * 100 / size; + if (p != percent) { + percent = p; + System.out.print("\rStep 1 of 4: " + percent + "%"); + System.out.flush(); + } + } + + Node n = it.next(); + if (doneThat.add(n)) + n.foreachRule(rf); + } + + // Step 2: compute the Rules that affect each Node + + final Set possiblyChangedNodes = + new Map2SetAdapter(new IdentityHashMap()); + + final Map rulesByNode = new IdentityHashMap(doneThat.size()); + doneThat = null; + + i = 0; + percent = -1; + size = rules.size(); + + for (Iterator it = rules.iterator(); it.hasNext(); i++) { + if (progress) { + int p = (i + 1) * 100 / size; + if (p != percent) { + percent = p; + System.out.print("\rStep 2 of 4: " + percent + "% "); + System.out.flush(); + } + } + + Rule r = (Rule) it.next(); + if (r.asserted) continue; + + Node n = r.target(); + Set s = (Set) rulesByNode.get(n); + if (s == null) { + s = new Map2SetAdapter(new IdentityHashMap()); + rulesByNode.put(n, s); + } + s.add(r); + + if (r.coverageRequirement == Rule.MUST_NOT_BE_COVERED) { + alwaysOffRules.add(r); + possiblyChangedNodes.add(r.target()); + } + } + + // Step 3: compute Nodes and Rules which cannot transition + + Node.RuleFunc propagateOn = null; + Node.RuleFunc propagateOff = null; + + for (int j = 0; j < 2; j++) { + final int sense2 = j; + propagateOn = propagateOff; + propagateOff = new Node.RuleFunc() { + public void accept(Rule r, int sense1, Node n) { + if (r.asserted) return; + + int sense = sense1 ^ sense2; + if (sense == 0) { + alwaysOffRules.add(r); + possiblyChangedNodes.add(r.target()); + } else { + TreeMapWithInteger m = + (TreeMapWithInteger) nodesByRule.get(r); + assert m != null : "m is null"; + m.count--; + if (m.count < 0) + throw new RuntimeException("bug 7014"); + if (m.count == 0) { + alwaysOnRules.add(r); + possiblyChangedNodes.add(r.target()); + } + } + } + }; + } + + alwaysOnNodes.add(vddNode); + alwaysOffNodes.add(gndNode); + + for (Iterator k = constantNodes.entrySet().iterator(); + k.hasNext(); ) { + final Map.Entry entry = (Map.Entry) k.next(); + final HierName name = (HierName) entry.getKey(); + final Node node = findNode(name); + if (node == null) continue; + + final int val = ((Integer) entry.getValue()).intValue(); + if (val == 0) { + alwaysOffNodes.add(node); + } else if (val == 1) { + alwaysOnNodes.add(node); + } + } + + i = 0; + + Set newAlwaysOnNodes = new Map2SetAdapter(new IdentityHashMap()); + Set newAlwaysOffNodes = new Map2SetAdapter(new IdentityHashMap()); + + newAlwaysOnNodes.addAll(alwaysOnNodes); + newAlwaysOffNodes.addAll(alwaysOffNodes); + + while (newAlwaysOnNodes.size() > 0 || + newAlwaysOffNodes.size() > 0) { + if (progress) { + System.out.print("\rStep 3 of 4: pass " + ++i); + } + + for (Iterator it = newAlwaysOnNodes.iterator(); + it.hasNext(); ) { + Node n = (Node) it.next(); + n.foreachRule(propagateOn); + } + for (Iterator it = newAlwaysOffNodes.iterator(); + it.hasNext(); ) { + Node n = (Node) it.next(); + n.foreachRule(propagateOff); + } + + newAlwaysOnNodes = new Map2SetAdapter(new IdentityHashMap()); + newAlwaysOffNodes = new Map2SetAdapter(new IdentityHashMap()); + + for (Iterator it = possiblyChangedNodes.iterator(); + it.hasNext(); ) { + Node n = (Node) it.next(); + Set s = (Set) rulesByNode.get(n); + assert (s != null); + boolean mustBeOn = false, mustBeOff = false; + boolean couldBeOn = false, couldBeOff = false; + for (Iterator it2 = s.iterator(); it2.hasNext(); ) { + Rule r = (Rule) it2.next(); + if (alwaysOnRules.contains(r)) { + if (r.getDirection() == '+') + mustBeOn = true; + else + mustBeOff = true; + } else if (!alwaysOffRules.contains(r)) { + if (r.getDirection() == '+') + couldBeOn = true; + else + couldBeOff = true; + } + } + + if (mustBeOn && mustBeOff) { + if (progress) + System.out.print('\r'); + System.out.println("Extreme badness: " + n.getName() + + " must be both on and off"); + } + + if (mustBeOn) { + if (!alwaysOnNodes.contains(n)) { + alwaysOnNodes.add(n); + newAlwaysOnNodes.add(n); + } + } else if (mustBeOff) { + if (!alwaysOffNodes.contains(n)) { + alwaysOffNodes.add(n); + newAlwaysOffNodes.add(n); + } + } else { + if (couldBeOn && !couldBeOff && + !alwaysOnNodes.contains(n)) { + alwaysOnNodes.add(n); + newAlwaysOnNodes.add(n); + } else if (couldBeOff && !couldBeOn && + !alwaysOffNodes.contains(n)) { + alwaysOffNodes.add(n); + newAlwaysOffNodes.add(n); + } else if (!couldBeOn && !couldBeOff) { + if (progress) + System.out.print('\r'); + System.out.println("Warning: " + n.getName() + + " is floating"); + } + } + } + + possiblyChangedNodes.clear(); + } + + return new RuleCoverageData(nodesByRule, alwaysOnRules, alwaysOffRules, + alwaysOnNodes, alwaysOffNodes); + } + + public interface RuleCoverageCallback { + boolean want(final Rule rule, boolean alwaysOn, boolean alwaysOff); + void rule(String r) throws IOException; + } + + public RuleCoverageStatistics reportRuleCoverage(final Writer dest, + final boolean progress, + final boolean full) + throws IOException { + final RuleCoverageCallback cb = new RuleCoverageCallback() { + public boolean want(final Rule r, final boolean alwaysOn, + final boolean alwaysOff) { + return full || (r.transitionCount == 0 && + r.coverageRequirement != Rule.IGNORE_COVERAGE && + !alwaysOn && !alwaysOff); + } + public void rule(String r) throws IOException { + dest.write(r); + dest.write('\n'); + } + }; + + return reportRuleCoverage(cb, progress, full); + } + + /** + * Creates a human-readable (or at least Perl-script-readable) textual + * report of the PRS DNF rule coverage. + * @param dest Writer to write the textual output to + * @param progress whether to print progress indicator on stdout + * @param full whether to output full report + */ + public RuleCoverageStatistics reportRuleCoverage( + final RuleCoverageCallback cb, + final boolean progress, + final boolean full) + throws IOException { + + /* We probably don't need scan_coverage_model anymore + // warn if scan_coverage_model isn't true + + boolean scan_coverage_model = false; + + try { + scan_coverage_model = ((BoolValue)getCellConstant("standard.null.NULL", "scan_coverage_model")).getValue(); + } catch (Exception e) { + // leave scan_coverage_model false + } + + if (!scan_coverage_model) { + System.out.println("Warning: Don't you want to set scan_coverage_model?"); + } + */ + + try { + final RuleCoverageData coverageData = computeRuleCoverage(progress); + + // Step 4: Write the file by iterating over all Rules + + int i = 0, percent = -1; + int size = rules.size(); + + int ignoreRules = 0, constantRules = 0, nonConstantCovered = 0; + + for (Iterator it = rules.iterator(); it.hasNext(); i++) { + if (progress) { + int p = (i + 1) * 100 / size; + if (p != percent) { + percent = p; + System.out.print("\rStep 4 of 4: " + percent + + "% "); + System.out.flush(); + } + } + + Rule r = (Rule) it.next(); + if (r.asserted) continue; + + boolean alwaysOn = coverageData.alwaysOnRules.contains(r); + boolean alwaysOff = coverageData.alwaysOffRules.contains(r); + + boolean coverageIgnore = + (r.coverageRequirement == Rule.IGNORE_COVERAGE); + + if (coverageIgnore) + ignoreRules++; + else if (alwaysOn || alwaysOff) + constantRules++; + else if (r.transitionCount != 0) + nonConstantCovered++; + + if (cb.want(r, alwaysOn, alwaysOff)) { + Map m = (Map) coverageData.nodesByRule.get(r); + assert m != null; + StringBuffer sb = new StringBuffer(); + for (Iterator it2 = m.entrySet().iterator(); + it2.hasNext(); ) { + Map.Entry e = (Map.Entry) it2.next(); + if (sb.length() > 0) + sb.append(" & "); + if (e.getValue() == INVERTED) + sb.append('~'); + sb.append(e.getKey()); + } + sb.append(" -> "); + sb.append(r.target().getName()); + sb.append(r.getDirection()); + if (full) { + sb.append(" ("); + sb.append(r.transitionCount); + sb.append(')'); + boolean space = false; + if (coverageData.alwaysOnRules.contains(r)) { + space = true; + sb.append(" *"); + } else if (coverageData.alwaysOffRules.contains(r)) { + space = true; + sb.append(" X"); + } + if (coverageIgnore) { + if (!space) + sb.append(' '); + sb.append('#'); + } + } + cb.rule(sb.toString()); + } + } + + final RuleCoverageStatistics stats = + new RuleCoverageStatistics(countNonAssertedRules(), + ignoreRules, + constantRules, + nonConstantCovered); + + // Step 5: print some interesting statistics + if (progress) { + NumberFormat fmt = NumberFormat.getPercentInstance(); + fmt.setMinimumFractionDigits(2); + fmt.setMaximumFractionDigits(2); + + size = countNonAssertedRules(); + double rules = size; + double constRules = constantRules; + double covered = nonConstantCovered; + double nonconst = size - constantRules - ignoreRules; + double ign = ignoreRules; + + String[][] pad = new String[][] + {{ Integer.toString(size), + Integer.toString(ignoreRules), + Integer.toString(constantRules), + Integer.toString(nonConstantCovered) }, + { fmt.format(ign / rules), + fmt.format(constRules / rules), + fmt.format(covered / nonconst) }, + { Integer.toString(size), + Integer.toString(size - constantRules - ignoreRules) }}; + + for (int k = 0; k < pad.length; k++) { + int max = 0; + for (int j = 0; j < pad[k].length; j++) + max = Math.max(max, pad[k][j].length()); + + for (int j = 0; j < pad[k].length; j++) + pad[k][j] = StringUtil.padLeft(pad[k][j], max, ' '); + } + + System.out.println("\rTotal rules: " + pad[0][0]); + System.out.println("Ignored rules: " + pad[0][1] + " (" + + pad[1][0] + " of " + pad[2][0] + ')'); + System.out.println("Constant rules: " + pad[0][2] + " (" + + pad[1][1] + " of " + pad[2][0] + ')'); + System.out.print("Covered rules: " + pad[0][3] + " (" + + pad[1][2] + " of " + pad[2][1] + ')'); + } + + return stats; + } finally { + if (progress) + System.out.println(); + } + } + + /** + * Return a string that is a properly escaped Verilog hierarchical + * reference for tail with respect to top. The + * main problem is to handle inlined instances correctly, because such + * instance names contains a dot which in that case is not a hierarchy + * delimiter. + **/ + private String getVerilogString(HierName tail, final CellInterface top, + final UnaryPredicate ignoreCheck) { + HierName inst = null; + if (ignoreCheck.evaluate(top)) return null; + if (CellUtils.isLeaf(top) || CellUtils.isWiring(top)) { + inst = tail; + tail = null; + } + while (tail != null) { + final HierName head = tail.head(); + tail = tail.tail(); + inst = prefixName(inst, head); + final CellInterface subcell = top.getSubcell(inst); + if (subcell != null) { + if (CellUtils.isWiring(subcell) && tail != null) { + inst = prefixName(inst, tail); + tail = null; + } + final String curr = + VerilogUtil.escapeIfNeeded(inst.getAsString('.')); + if (tail == null) { + return curr; + } else { + final String next = + getVerilogString(tail, subcell, ignoreCheck); + if (next == null) return null; + else return curr + "." + next; + } + } + } + return VerilogUtil.escapeIfNeeded(inst.getAsString('.')); + } + + public void reportCoverageConstantNodes(Writer dest, List ignoreList, + final boolean progress) + throws Exception { + try { + final CellInterface top = + getCastFileParser().getFullyQualifiedCell(cellName); + final RuleCoverageData coverageData = computeRuleCoverage(progress); + final UnaryPredicate checkIgnore = + CellUtils.getTypeMatcher(ignoreList); + + System.out.print("\rStep 4 of 4 "); + System.out.flush(); + for (final Iterator it = coverageData.alwaysOnNodes.iterator(); + it.hasNext();) { + final Node node = (Node) it.next(); + if (!node.getName().head().getAsString('.').equals("x")) + continue; + final String vnode = + getVerilogString(node.getName().tail(), top, checkIgnore); + if (vnode != null) dest.write("force " + vnode + " = 1;\n"); + } + for (final Iterator it = coverageData.alwaysOffNodes.iterator(); + it.hasNext();) { + final Node node = (Node) it.next(); + if (!node.getName().head().getAsString('.').equals("x")) + continue; + final String vnode = + getVerilogString(node.getName().tail(), top, checkIgnore); + if (vnode != null) dest.write("force " + vnode + " = 0;\n"); + } + } finally { + if (progress) + System.out.println(); + } + } + + /** + * Yes, this is an odd bird, but it's convenient in implementing + * reportRuleCoverage(). + */ + private static class TreeMapWithInteger extends TreeMap { + public int count = 0; + } + + /** + * If any of the chained exceptions in t is a VisitorExceptionWithLocation, + * make it print its own pretty message, and return true. + * If not, return false. + */ + public static boolean doSelfPrint(Throwable t, PrintStream p) { + while (t != null) { + if (t instanceof VisitorExceptionWithLocation) { + ((VisitorExceptionWithLocation)t).printSelf(p); + return true; + } + t = t.getCause(); + } + return false; + } + + public interface ProgressIndicator { + void percentCompleted(int percent); + } + + public void foreachRule(final Node.RuleFunc ruleFunc) { + foreachRule(ruleFunc, null); + } + + public void foreachRule(final Node.RuleFunc ruleFunc, + final ProgressIndicator indicator) { + final int size = nodes.size(); + boolean gen = false; + int i = 0; + int percent = -1; + for (Iterator it = nodes.values().iterator(); it.hasNext(); i++) { + if (indicator != null) { + final int p = (i + 1) * 100 / size; + if (p != percent) { + percent = p; + indicator.percentCompleted(percent); + } + } + + final Node n = it.next(); + if (i == 0) gen = n.getGeneration(); + if (n.getGeneration() == gen) { + n.foreachRule(ruleFunc); + n.setGeneration(!gen); + } + } + } + + void foreachNode(final UnaryPredicate nodeFunc) { + boolean gen = false; + boolean first = true; + for (Iterator it = nodes.values().iterator(); it.hasNext(); ) { + final Node n = it.next(); + if (first) { + first = false; + gen = n.getGeneration(); + } + if (n.getGeneration() == gen) { + if (nodeFunc.evaluate(n)) n.setGeneration(!gen); + } + } + } + + // Parameters persist across cosimulations + private final HashMap parameters = + new HashMap(); + + public void setParameter(final String key, final String val) { + if (val == null) { + parameters.remove(key); + } else { + parameters.put(key, val); + } + } + public String getParameter(final String key) { + return parameters.get(key); + } + public double getDouble(final String key, final double def) { + final String val = getParameter(key); + if (val == null) return def; + else { + try { + return Double.parseDouble(val); + } catch (NumberFormatException e) { + System.err.println( + "Warning: expected floating number for parameter " + + key + ", found " + val + "; using default value " + + def); + return def; + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimDebug.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimDebug.java new file mode 100644 index 0000000000..7ba8a72743 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimDebug.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +/** + *

    An interface for static debugging for the dsim package.

    + * + *

    Set this variable to "true" to compile in all debugging + * code.

    + * + *

    Once we determine which other primary packages dsim depends + * upon, we will augment this definition appropriately. E.g., if dsim + * depends upon the package foobar, then we will: + * + *

  • add import ....foobar.FoobarDebug to this class, and
  • + *
  • rewrite + *
    boolean DEBUG = false
    + * as + *
    boolean DEBUG = false || FoobarDebug.DEBUG
    + *
  • + *

    + * + * @author Joseph Kiniry + * @version $Revision$ $Date$ + **/ + +public interface DSimDebug { + + boolean DEBUG = false; + +} // end of interface DSimDebug + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimMain.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimMain.java new file mode 100644 index 0000000000..820f532e20 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimMain.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import com.avlsi.util.cmdline.CmdLine; + +import java.io.File; +import java.util.ArrayList; + + +public class DSimMain { + /** + * This class should not be instantiated. + **/ + private DSimMain() { } + + public static void main( String[] args ) { + final String myArgs[] = new String[args.length + 2]; + + + myArgs[0] = "--module=DSim" ; + myArgs[1] = "--history-file="+System.getProperty("user.home")+ + File.separatorChar+".jdsim_hist"; + + int i = 0; + while ( ( i < args.length ) && ( ! args[i].equals("--help") ) ) { + + myArgs[i+2] = args[i]; + + ++i; + } + + //If we exitted the above loop because we saw a --help + if ( i < args.length ) { + System.out.println( DSimMain.class.getName() + " [--cast-version=(1|2)] [--cast-path=path] [--device-path=path]" ); + } + else { + CmdLine.main( myArgs ); + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimSynchronizer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimSynchronizer.java new file mode 100644 index 0000000000..d5de9d8451 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimSynchronizer.java @@ -0,0 +1,97 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; +import com.avlsi.tools.tsim.AbstractDevice; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * Class for synchronizing timestep simulators with DSim's scheduler. Because DSim time + * ticks away in meaningless DSim time units (where 100 is the time expected for a prs transistion) + * the conversion between these units and rewal time is specified + * + * @author Dan Daly + * @version $Date$ + **/ + +public class DSimSynchronizer extends AbstractDevice { + + private int period; + private final int ck_dsim; + private final double ck_realtime; + boolean stop = false; + private ArrayList devices; + /** + * Constructor. + **/ + public DSimSynchronizer(final int ck_dsim, final double ck_realtime) { + this(ck_dsim, ck_realtime,ck_dsim/8); + } + + public DSimSynchronizer(final int ck_dsim, + final double ck_realtime, + final int period) { + this.ck_dsim = ck_dsim; + this.ck_realtime = ck_realtime; + this.period = period; + this.devices = new ArrayList(); + } + + public double DSim_to_RealTime(long dsim_time) { + return (((double)dsim_time*ck_realtime)/ck_dsim); + } + + public void go() throws InterruptedException { + while (!stopped()) { + try { + for (final Iterator i = devices.iterator();i.hasNext();) { + Runnable r = (Runnable) i.next(); + r.run(DSim_to_RealTime(DSim.get().getTime())); + //Run each instance to DSim time equiv + } + + } catch (Exception e) { + System.out.println("Exception called, stopping, :"+e.getMessage()); + stop = true; + break; + } + + new WakeAt(DSim.get().getTime()+period,this).sleepTil(); + } + //cleanup called after go quits + } + + public boolean stopped() { + return stop; + } + + public void stop() { + stop = true; + } + + public void setPeriod(int p) { + this.period = p; + } + + public int getPeriod() { return period;} + + public void addDevice(Runnable r) { + devices.add(r); + } + + public interface Runnable { + void run(double time) throws Exception; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimUtil.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimUtil.java new file mode 100644 index 0000000000..505be53727 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DSimUtil.java @@ -0,0 +1,618 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id: $ + * $DateTime: $ + * $Author: $ + */ + +package com.avlsi.tools.dsim; + +import com.avlsi.fast.ports.NodeType; +import com.avlsi.file.common.HierName; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.util.functions.BinaryPredicate; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; +import java.util.Map; +import java.util.HashMap; +import java.util.HashSet; +import java.util.TreeMap; + +/** + * Static DSim utility functions. + **/ +public class DSimUtil { + + private DSim dsim = null; + private MeasureNodeWatcher measure = null; + private CombinedNodeWatcher haltWatcher = null; + private Node GND; + private Node Vdd; + private Node _SReset; + private Node _PReset; + private Node _Reset; + private Node _RESET; + private Node ERROR; + private Node ENV_RESET; + + public static final int STANDARD_RESET = 0; + public static final int SP_RESET = 1; + + public static final HierName _RESET_NAME = + HierName.makeHierName("_RESET"); + public static final HierName _Reset_NAME = + HierName.makeHierName("_Reset"); + public static final HierName _SReset_NAME = + HierName.makeHierName("_SReset"); + public static final HierName _PReset_NAME = + HierName.makeHierName("_PReset"); + // FIXME: _env should not be hardcoded here, as it could be different + public static final HierName ENV_RESET_NAME = + HierName.append(HierName.makeHierName("_env"), _RESET_NAME); + + /** + * DSimUtil constructor. Looks up nodes in preparation for + * doing stuff. Shouldn't be called until a cell is instantiated. + **/ + public DSimUtil() { + dsim = DSim.get(); + GND = dsim.findNode("GND"); + Vdd = dsim.findNode("Vdd"); + _SReset = dsim.findNode(_SReset_NAME); + _PReset = dsim.findNode(_PReset_NAME); + _Reset = dsim.findNode(_Reset_NAME); + _RESET = dsim.findNode(_RESET_NAME); + ENV_RESET = dsim.findNode(ENV_RESET_NAME); + ERROR = dsim.findNode("ERROR"); + + /* + if (GND == null || Vdd == null || ERROR == null) { + throw new IllegalStateException( + "Node GND, Vdd, or ERROR is not defined."); + } + if (_Reset == null && (_SReset == null || _PReset == null)) { + throw new IllegalStateException("No known reset nodes defined."); + } + */ + } + + /** + * Resets DSim, either with _SReset & _PReset or with a + * single _Reset signal (set by protocol, SP_RESET and + * STANDARD_RESET respectively). Reset is performed with + * full random (untimed) transitions. Following reset, the + * timing model is restored to its prior value. + * + * @throws IllegalArgumentException + * @throws IllegalStateException + **/ + public void resetDSim(int protocol) { + // Store initial state + int random_state = dsim.getRandom(); + boolean warn_state = dsim.getWarn(); + boolean error_state = dsim.getError(); + + // Disable error checking & reporting + dsim.setWarn(false); + dsim.setError(false); + + // Enable random timing + dsim.setRandom(DSim.UNTIMED_RANDOM); + + // Initialize nodes + //dsim.clearEventQueues(); + GND.setValueAndEnqueueDependents(Node.VALUE_0); + Vdd.setValueAndEnqueueDependents(Node.VALUE_1); + + if (protocol == STANDARD_RESET) { + Node resetNode = _RESET; + if (resetNode == null) resetNode = _Reset; + if (resetNode == null) resetNode = ENV_RESET; + if (resetNode == null) { + throw new IllegalStateException( + "Neither _RESET, _Reset, nor env._RESET exist."); + } + + // Reset and cycle + //_Reset.setValueAndEnqueueDependents(Node.VALUE_0); + resetNode.scheduleImmediate(Node.VALUE_0); + dsim.cycle(-1); + + // Turn on error checking & reporting, then exit reset + Set unstabSet = dsim.getNodesWithValue(Node.VALUE_U); + if (!unstabSet.isEmpty()) { + System.out.println( + "Nodes unstable during reset:"); + printNodeSet(unstabSet); + } + dsim.setWarn(true); + dsim.setError(true); + //_Reset.setValueAndEnqueueDependents(Node.VALUE_1); + resetNode.scheduleImmediate(Node.VALUE_1); + } + else if (protocol == SP_RESET) { + if (_PReset != null && _SReset != null) { + // Reset and cycle + //_PReset.setValueAndEnqueueDependents(Node.VALUE_0); + //_SReset.setValueAndEnqueueDependents(Node.VALUE_0); + _PReset.scheduleImmediate(Node.VALUE_0); + _SReset.scheduleImmediate(Node.VALUE_0); + dsim.cycle(-1); + + // Turn on error checking & reporting, then raise _PReset + Set unstabSet = dsim.getNodesWithValue(Node.VALUE_U); + if (!unstabSet.isEmpty()) { + System.out.println( + "Nodes unstable during reset:"); + printNodeSet(unstabSet); + } + dsim.setWarn(true); + dsim.setError(true); + //_PReset.setValueAndEnqueueDependents(Node.VALUE_1); + _PReset.scheduleImmediate(Node.VALUE_1); + dsim.cycle(-1); + + // List status U nodes, then raise _SReset + unstabSet = dsim.getNodesWithValue(Node.VALUE_U); + if (!unstabSet.isEmpty()) { + System.out.println( + "Nodes unstable following _PReset+:"); + printNodeSet(unstabSet); + } + //_SReset.setValueAndEnqueueDependents(Node.VALUE_1); + _SReset.scheduleImmediate(Node.VALUE_1); + } + else { + throw new IllegalStateException("Reset nodes do not exist."); + } + } + else { + throw new IllegalArgumentException( + "Unknown reset protocol specified: "+protocol); + } + + // Restore DSim state + dsim.setWarn(warn_state); + dsim.setError(error_state); + dsim.setRandom(random_state); + } + + /** + * Returns the best of what DSim has to offer in the way of + * reset nodes. Preferentially picks _RESET, then _Reset, + * then _env._RESET, then _SReset, then _PReset, then null. + **/ + public static Node getResetNode() { + Node n = DSim.get().findNode(_RESET_NAME); + if (n == null) n = DSim.get().findNode(_Reset_NAME); + if (n == null) n = DSim.get().findNode(ENV_RESET_NAME); + if (n == null) n = DSim.get().findNode(_SReset_NAME); + if (n == null) n = DSim.get().findNode(_PReset_NAME); + return n; + } + + /** + * Performs repeated random-timing reset tests. This test is intended + * to catch timing races involving reset (such as the one that killed + * A2S_40 in F1). + * + * @param numTests Number of reset cycles to run. + * @param numCycles Number of cycles to run for between each reset. + * @param cycleNode Node to use for post-reset cycling. + * @param resetProtocol Reset protocol to use (SP_RESET or STANDARD_RESET). + * + * @throws IllegalArgumentException + * @throws IllegalStateException + * + * Returns true if run successfully (no deadlock); false otherwise + **/ + public boolean resetStressTest(int numTests, + int numCycles, + String cycleNode, + int resetProtocol) { + boolean done = true; + int cnode_tcounts; + Node cnode = dsim.findNode(cycleNode); + if (cnode == null) { + throw new IllegalStateException( + "Node '"+cycleNode+"' does not exist."); + } + if (numTests < 0) { + throw new IllegalArgumentException( + "Negative numTests to resetStressTest()."); + } + + for (int i=0; i inputPorts = new HashSet(); + (new CellUtils.MarkPort() { + protected void mark(final NodeType nodeType, + final String name, + final int newDir) { + if (newDir < 0) { + final Node n = dsim.findNode(instanceName + "." + name); + // don't add special nodes + if (n != null && n != GND && n != Vdd && n != reset) { + inputPorts.add(n); + } + } + } + }).mark(cell); + + if (!inputPorts.isEmpty()) { + reset.addWatch(new NodeWatcher() { + public final void nodeChanged(Node node, long time) { + if (node.getValue() == Node.VALUE_0) { + for (Node inputPort : inputPorts) { + inputPort.scheduleImmediate(Node.VALUE_0); + } + } + } + }); + } + } + } + + /** + * Class for measuring the times of transitions on a particular + * node. Will calculate average period and output a breakdown + * of observed periods. + **/ + static class MeasureNodeStats implements NodeWatcher { + private byte phase = Node.VALUE_U; + private int numIgnored = 0; + private long startTime; + private long totalTime = 0; + private long totalPeriods = 0; + private float[] slewStat = new float[] { Float.POSITIVE_INFINITY, + Float.NEGATIVE_INFINITY, + 0 }; + private long totalCycles = 0; + private float measuredNTPC = Float.NaN; + private TreeMap cycles; + private Node n; + private boolean longOutput; + private boolean continuousOutput; + + MeasureNodeStats(Node node, boolean verbose, boolean continuous) { + cycles = new TreeMap(); + n = node; + longOutput = verbose; + continuousOutput = continuous; + phase = n.getValue(); + } + + public final void nodeChanged(Node node, long time) { + byte state = n.getValue(); + if (state == Node.VALUE_U) { + numIgnored++; + startTime = 0; + phase = Node.VALUE_U; + } + else { + if (phase == Node.VALUE_U) { + phase = state; + startTime = time; + } + else if (state == phase) { + if (startTime == 0) startTime = time; + else { + totalTime += time - startTime; + totalPeriods++; + Long period = new Long((time - startTime + 50)/100); + startTime = time; + newCycle(period); + } + } + final float slew = n.getSlew(); + slewStat[0] = Math.min(slew, slewStat[0]); + slewStat[1] = Math.max(slew, slewStat[1]); + slewStat[2] += slew; + totalCycles++; + if (continuousOutput) printStats(); + } + } + + public void newCycle(Long period) { + Long cnt = (Long)cycles.get(period); + if (cnt == null) + cnt = new Long(1); + else + cnt = new Long(cnt.longValue()+1); + cycles.put(period,cnt); + } + + String printStats() { + boolean first = true; + String s = ""; + String long_str = "("; + Set periods = cycles.keySet(); + Iterator it = periods.iterator(); + while (it.hasNext()) { + Long period = (Long)it.next(); + Long cnt = (Long)cycles.get(period); + if (!first) long_str += " "; + else first = false; + long_str += period.toString() + "["; + if (cnt.longValue() >= 10) { + float percent = (float)(cnt.longValue() * 100) + / totalPeriods; + long_str += percent + "%"; + } + else + long_str += cnt.longValue(); + long_str += "]"; + } + if (numIgnored > 0) long_str += "U[" + numIgnored + "]"; + long_str += " [" + slewStat[0] + ":" + slewStat[1] + ":" + + slewStat[2] / totalCycles + "]"; + long_str += ")"; + float averagePeriod = (float)totalTime / totalPeriods / 100; + measuredNTPC = averagePeriod; + String str = n.getName().getAsString('.') + ": "+averagePeriod+"t"; + if (longOutput) str += " " + long_str; + if (totalPeriods != 0 && averagePeriod != 0.0) { + // + // Only print out the measurement if it's meaningful. + // (Error before cycling or full random timing can + // prevent this from being the case.) + // + System.out.println(str); + s += str; + } + return s; + } + + //return the measured NTPC + float getMeasuredNTPC(){return measuredNTPC; } + + void clearMeasuredNTPC(){measuredNTPC = Float.NaN; } + + void restart() { + phase = n.getValue(); + startTime = 0; + totalTime = 0; + totalPeriods = 0; + numIgnored = 0; + cycles = new TreeMap(); + totalCycles = 0; + slewStat = new float[] { Float.POSITIVE_INFINITY, + Float.NEGATIVE_INFINITY, + 0 }; + } + + void setVerbose(boolean verbose) { + longOutput = verbose; + } + + Node getNode() { + return n; + } + } + + static class HaltOnCycleWatcher extends MeasureNodeStats { + private final BinaryPredicate p; + private final Integer tpc; + HaltOnCycleWatcher(final Node node, final BinaryPredicate p, + final int tpc) { + super(node, false, false); + this.tpc = Integer.valueOf(tpc); + this.p = p; + } + public void newCycle(Long period) { + if (p.evaluate(period, tpc)) { + System.out.println("Last cycle on " + getNode().getName() + + " was " + period + " transitions."); + DSim.get().interrupt(); + } + } + } + + static class CombinedNodeWatcher + implements NodeWatcher, Iterable> { + private final Map map; + public CombinedNodeWatcher() { + this(new HashMap()); + } + public CombinedNodeWatcher(final Map map) { + this.map = map; + } + public T addNode(Node node, T watcher) { + node.addWatch(this); + return map.put(node, watcher); + } + public T deleteNode(Node node) { + final T stored = map.remove(node); + if (stored != null) node.removeWatch(this); + return stored; + } + public T getNode(Node node) { + return map.get(node); + } + public final void nodeChanged(Node node, long time) { + final T stored = map.get(node); + if (stored != null) { + stored.nodeChanged(node, time); + } + } + public void clear() { + for (Node node : map.keySet()) node.removeWatch(this); + map.clear(); + } + public Iterator> iterator() { + return Collections.unmodifiableMap(map).entrySet().iterator(); + } + } + + /** + * Node Watcher class which watches a list of nodes and tallies + * their transitions statistics. + **/ + static class MeasureNodeWatcher + extends CombinedNodeWatcher { + private boolean verbose; + + MeasureNodeWatcher(boolean verbose) { + this.verbose = verbose; + } + + void addNode(Node node, boolean continuous) { + addNode(node, new MeasureNodeStats(node, verbose, continuous)); + } + + void addNode(Node node) { addNode(node,false); } + + float getMeasuredNTPC(Node node) { + MeasureNodeStats mns = getNode(node); + if(mns != null){ + float ntpc_value= mns.getMeasuredNTPC(); + mns.clearMeasuredNTPC(); + return ntpc_value; + } + else { + System.out.println("Measure node "+node +" node found"); + return Float.NaN; + } + } + + public void clear() { + verbose = false; + super.clear(); + } + + void restart() { + for (Map.Entry entry : this) { + entry.getValue().restart(); + } + } + + String printStats() { + StringBuilder s = new StringBuilder(); + for (Map.Entry entry : this) { + s.append(entry.getValue().printStats()); + } + return s.toString(); + } + + void setVerbose(boolean v) { + verbose = v; + for (Map.Entry entry : this) { + entry.getValue().setVerbose(verbose); + } + } + } + + /** Adds a node to the measure list **/ + public boolean addMeasure(String node, boolean continuous) { + if (measure == null) { + measure = new MeasureNodeWatcher(false); + } + Node n = dsim.findNode(node); + if (n == null) { + System.out.println("Node '"+node+"' doesn't exist."); + return false; + } + else { + measure.addNode(n,continuous); + return true; + } + } + + public boolean addMeasure(String node) { + return addMeasure(node,false); + } + + /** Retrive NTPC for node we measured ***/ + public float getMeasure(String node) { + if (measure == null) { return Float.NaN; } + Node n = dsim.findNode(node); + if (n == null) { + System.out.println("Node '"+node+"' doesn't exist."); + return Float.NaN; + } + else { + return measure.getMeasuredNTPC(n); + } + } + + /** To be called whenever the user ^C's (ideally) **/ + public String printMeasureStats() { + return printMeasureStats(true); + } + + public String printMeasureStats(boolean resetStats) { + String s =null; + if (measure == null) return s; + s = measure.printStats(); + if (resetStats) measure.restart(); + return s; + } + + /** Restart new ntpc calculations **/ + public void restartStats () { + measure.restart(); + } + + /** Sets measure output to be verbose **/ + public void setMeasureVerbosity(boolean verbose) { + if (measure != null) measure.setVerbose(verbose); + } + + /** Clears all measures **/ + public void clearMeasures() { + //avoid throwing a null pointer exception + if(measure != null) + measure.clear(); + } + + public void haltOn(Node node, BinaryPredicate p, int tpc) { + if (haltWatcher == null) { + haltWatcher = new CombinedNodeWatcher(); + } + haltWatcher.addNode(node, new HaltOnCycleWatcher(node, p, tpc)); + } + + public void haltOff(final Node node) { + if (haltWatcher != null) haltWatcher.deleteNode(node); + } + + /** + * Prints the set of nodes to System.out in a compact manner, nicely + * formatting to an 80 column line width. + **/ + void printNodeSet(Set s) { + int col = 3; + Iterator it = s.iterator(); + System.out.print(" "); + while (it.hasNext()) { + String name = ((Node)it.next()).getName().getAsString('.'); + col += name.length() + 1; + if (col > 80) { + System.out.print("\n "); + col = 4 + name.length(); + } + System.out.print(name + " "); + } + System.out.println(""); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DigitalScheduler.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DigitalScheduler.java new file mode 100644 index 0000000000..b6d34961d6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/DigitalScheduler.java @@ -0,0 +1,760 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import EDU.oswego.cs.dl.util.concurrent.BrokenBarrierException; +import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier; + +import com.avlsi.tools.dsim.EventQueue; +import com.avlsi.tools.dsim.RandomEventQueue; +import com.avlsi.tools.dsim.Node; +import com.avlsi.tools.tsim.AbstractDevice; +import com.avlsi.tools.tsim.AbstractDeviceThread; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; + +import java.util.ConcurrentModificationException; + +//import com.avlsi.util.container.PriorityQueue; +//import com.avlsi.util.container.RandomQueue; + +/** + * This is the entity that controls an associated TSim simulator, waiting for it + * to reach stability before taking another action in DSim. + * + * @author tim + * @author Aaron Denney + * @author jlm + * @author Dan Daly + * @author Jesse Rosenstock + * @author Chris Brichford + * @author Kim Wallmar + * @author Joseph Kiniry + * + * @review kiniry 18-23 July 2002 + **/ + +public class DigitalScheduler { + + /* One instance of class. */ + private static DigitalScheduler singleton = null; + /** + * Thread synchronization lock object. The monitor for + * this not be acquired while holding tLock. + * This lock must be held while accessing tCount. + * This is not obeyed in clear. + * @see + * Bug#3635 + **/ + private Object tLock = new Object(); + /** + * Active simulation thread count. Digital simulator waits on all + * other simulation threads. + * + *

    The lock tLock must be held while accessing + * tCount. + * + *

    The DigitalScheduler will not fire any events until + * tCount has reached 0. Assuming other classes + * manipulate the thread count at appropriate times, this ensures + * that all devices will eventually block either on a channel + * communication or waiting for a node to transistion without + * performing any channel or node actions that could unblock + * another device. Similarly, the thread count must be incremented + * before the device is awakened. + * + *

    The DigitalScheduler must wait for stability because if it + * did not, the devices running in parallel with it could schedule + * events in the past, which would cause performance inaccuracies. + * The DigitalScheduler's time can never go back, so the events + * would happen later than they were intended to. + * + *

    While calling decThreadCount(), the lock for + * the object on which the thread will wait must be held in order + * to prevent the thread from being notified before it has waited. + * Following this rule will prevent dsim from falsely detecting + * deadlock, as the prototype tsim3 implementation could do. + * The lock need not be held while calling incThreadCount + * because it is always safe to have the thread count larger than it + * "really" is. + */ + private int tCount = 0; + + /** + * List of barriers used by threads waiting for the event queue to be + * empty. + **/ + private final LinkedList/**/ emptyEventQueueBarriers = + new LinkedList/*CyclicBarrier*/(); + + /** Priority queue for timed events. Synchronized on this. **/ + private EventQueueInterface pqueue = //new EventQueue(); + new BinningQueue(); + + /** Random queue for untimed events. Synchronized on this. **/ + private EventQueueInterface rqueue; + + private final Random rand; + /** The time that the last event fired. **/ + private long lastTime = 0; + + /** Whether to stall the simulation before the next event. **/ + private InterruptedBy interrupted = InterruptedBy.NONE; + + /** + * Dynamic debugging flag for extreme logging verbosity. + **/ + private boolean verbose = false; + + private boolean canAddDevices = true; + + /** + * All of the devices that need to be dealt with on clear. Maps from + * instance name to device. All access should be guarded by + * synchronizing on this. + * + *

     
    +     * private invariant deviceMap != null; 
    +     * 
    + **/ + + private final /*@ non_null @*/ Map deviceMap; + + /** + * Possible sources of interruption. Fill in additional values as needed. + **/ + public static enum InterruptedBy { + NONE, + USER, + OTHER + } + + /** + * The thread that constructed this object. Used to give asserts about + * threads that add event, but don't extend AbstractDeviceThread. + **/ + private final Thread constructorThread; + + /** + * Threads that have added to the event queue in this cycle. + **/ + private final List activeThreads = + new ArrayList(); + + // Constructors + + /** + * Create a new DigitalScheduler. + **/ + + private DigitalScheduler(long seed) { + rand = new Random(seed); + rqueue = new RandomEventQueue(rand); + deviceMap = new HashMap(); + this.constructorThread = Thread.currentThread(); + } + + // Methods + + /** + * @return a singleton instance of scheduler. + **/ + + public static synchronized DigitalScheduler get() { + if (singleton == null) + singleton = new DigitalScheduler(1); + return singleton; + } + + /** Controls printing of extra info **/ + public void setVerbose(boolean v) { verbose = v; } + + public final synchronized void addDevice(AbstractDevice newDevice, + String name) { + Debug.assertTrue(!deviceMap.containsKey(name)); + Debug.assertTrue(!deviceMap.containsValue(newDevice)); + + if (canAddDevices) { + deviceMap.put(name, newDevice); + } else { + throw new ConcurrentModificationException("Don't call addDevice " + + "while doing a DSim.clear"); + } + + incThreadCount(); + } + + public void incThreadCount(int count) { + synchronized(tLock) { + if (verbose) + System.err.println("inc: " + tCount + "->" + (tCount + count)); + tCount += count; + } + } + + /** + * Another simulation thread is active. + * + * @design This method is not synchronized because + * {@link #incThreadCount(int)} handles it. + **/ + + public void incThreadCount() { + incThreadCount(1); + } + + /** + * Another simulation thread is finished. + * + *

    Acquires tLock. + **/ + public void decThreadCount() { + // Thread.dumpStack(); + synchronized (tLock) { + if (verbose) + System.err.println("dec: " + tCount + "->" + (tCount - 1)); + tCount--; + if (tCount==0) { tLock.notifyAll(); } + // deal with under counting + else if (tCount<0) { + throw new + IllegalStateException("Digital Simulator Thread Count < 0 : " + + tCount); + } + } + } + /** Wait for all other simulation threads to stop, before cycling. **/ + private void waitForAllThreads() { + synchronized (tLock) { + while (tCount!=0) { + try { tLock.wait(); } + catch (InterruptedException ie) { + Debug.fail(); + } + } + } + addDeviceEvents(); + } + /** Checks for an active thread **/ + private boolean threadsActive() { + if (verbose) System.err.println("Checking for thread activity."); + synchronized (tLock) { + if (verbose) System.err.println("Lock aquired."); + return tCount > 0; + } + } + + /** + * Adds an event to the appropriate queue. + * + * @param e the event to add. + **/ + public void addEvent(Event e) { + final Thread currThread = Thread.currentThread(); + if (currThread instanceof AbstractDeviceThread) { + final AbstractDeviceThread th = (AbstractDeviceThread) currThread; + if (!th.getProcessed()) { + th.setProcessed(true); + synchronized (activeThreads) { + activeThreads.add(th); + } + } + th.addEvent(e); + } else { + insertEvent(e); + } + } + + /** + * Add all pending events from per thread event queues to the central event + * queue. + **/ + private void addDeviceEvents() { + // the abstract device threads synchronizes on tLock when decrementing + // the thread count; this thread synchronizes on tLock while waiting + // for tCount to become 0; thus all modifications to activeThreads must + // be visible in this thread without additional synchronization + final int size = activeThreads.size(); + if (size > 0) { + if (size > 1) { + // except at reset, most times activeCount is 1 + Collections.sort(activeThreads); + } + for (int i = 0; i < size; ++i) { + final AbstractDeviceThread th = activeThreads.get(i); + assert th.getProcessed(); + th.setProcessed(false); + + final List events = th.getEvents(); + final int length = events.size(); + for (int j = 0; j < length; ++j) { + insertEvent(events.get(j)); + } + th.clearEvents(); + } + activeThreads.clear(); + } + } + + /** + * Adds an event to the appropriate queue. + * + * @param e the event to add. + * + *

    
    +     * public normal_behavior
    +     *   requires e != null;
    +     *   requires (e instanceof SequencedEvent) ==>
    +     *            ((SequencedEvent) e).hasNextEvent() == false;
    +     * 
    + * + * @bug FIXME: check if on either queue? Or keep that responsibility in + * client? + **/ + private void insertEvent(Event e) { + // not synchronzied because this method should only be called by 1 + // thread + assert Thread.currentThread() == constructorThread; + + if (verbose) + System.err.println(e.getTime() + ": Adding " + e + + " index = " + e.getIndex()); + if ((e instanceof SequencedEvent) && ((SequencedEvent) e).hasNextEvent()) + System.err.println("Event has NEXT!!"); + + boolean isQueued = e.getIndex() >= 0; + + if (verbose) + if (e.getTime() < getTime()) + System.err.println("Queueing Up Event "+e+" which is in the past "+ + e.getTime()+"<"+getTime()); + /*if (e.isRandom()) { + if (!isQueued) { rqueue.enqueue(e); } + } else { + if (!isQueued) { pqueue.enqueue(e); } + else { pqueue.rerank(e); } + }*/ + if (e.isRandom()) { + if (!isQueued) //rqueue.remove(e); + rqueue.enqueue(e); + } else { + if (isQueued) pqueue.remove(e); + pqueue.enqueue(e); + } + + } + + /** Removes an event from the appropriate queue */ + public synchronized void removeEvent(Event e) { + if (e.getIndex()>=0) { + if (e.isRandom()) { rqueue.remove(e); } + else { pqueue.remove(e); } + } + } + /** Runs up to, but not including events at time. */ + public void cycleTo(long time) { + interrupted = InterruptedBy.NONE; + // Cannot choose next event until threads are inactive. + waitForAllThreads(); + while (interrupted == InterruptedBy.NONE && hasMoreEvents() && + isPqueueInFuture(time)) { + doOneCycle(); + // Cannot choose next event until threads are inactive. + waitForAllThreads(); + } + } + + //public int getNextEventTime() { + public long getNextEventTime() { + // Cannot look at next event until threads are inactive. + waitForAllThreads(); + long ret = 0; + synchronized(this) { + if (pqueue.isEmpty()) { + if (verbose) + System.out.println("pqueue is empty @"+getTime()); + return -1; + } + ret = pqueue.front().getTime(); + } + return ret; + } + + /** Waits until no threads are running in Tsim **/ + public synchronized void waitUntilStable() { + waitForAllThreads(); + } + + /** + * Misnomer. But we want to keep firing random queue + * if timed queue is empty. + **/ + //private boolean isPqueueInFuture(int time) { + private boolean isPqueueInFuture(long time) { + return pqueue.isEmpty() || compareTime(pqueue.front().getTime(),time) < 0; + } + + /** Runs until there are no more events in the queue (and no more threads). */ + public void cycle() { + interrupted = InterruptedBy.NONE; + waitForAllThreads(); + while (interrupted == InterruptedBy.NONE && hasMoreEvents()) { + doOneCycle(); + waitForAllThreads(); + } + } + + /** + * Runs until 'node' has the 'tCount' transitions or there are no more + * events in the queue. + * + * @param node the node to check. + * @param tCount the number of transitions to cycle until. + **/ + + public void cycle(Node node, int tCount) { + if (verbose) { + System.err.println("Cycling node for " + tCount +" counts"); + } + tCount += node.getTCount(); + interrupted = InterruptedBy.NONE; + waitForAllThreads(); + while (interrupted == InterruptedBy.NONE && hasMoreEvents() && + node.getTCount() < tCount) { + doOneCycle(); + waitForAllThreads(); + } + } + /** Processes the first event in the queues. */ + public void cycleOnce() { + interrupted = InterruptedBy.NONE; + doOneCycle(); + waitForAllThreads(); + } + /** + * Waits for any exteral simulation threads to complete and processes the + * next event. + **/ + private void doOneCycle() { + if (DSimDebug.DEBUG) + Debug.assertTrue(threadCount() == 0); + // check for interrupts + if (interrupted != InterruptedBy.NONE) { return; } + + // get our next victim...err event + Event e = getNextEvent(); + if (e==null) { + final CyclicBarrier barrier; + synchronized (this) { + barrier = emptyEventQueueBarriers.isEmpty() ? + (CyclicBarrier) null : + (CyclicBarrier) emptyEventQueueBarriers.removeFirst(); + } + if (barrier != null) { + try { + // release the waiting thread from the barrier + barrier.barrier(); + // and wait for him to increment his thread count + barrier.barrier(); + } catch (InterruptedException x) { + throw new AssertionError(x); + } catch (BrokenBarrierException x) { + barrier.restart(); + } + } + + return; + } + // process event + long newTime = e.getTime(); + // There is no monotonicity requirement on event times. + // @see Bug#1062 + // for more information. +// if (verbose) { +// System.err.println("Current timing information:\n" + +// "\tmean = " + AbstractDevice.meanTimeOfAllDevices() + +// "\tvariance = " + +// AbstractDevice.varianceOfTimeOfAllDevices()); +// } + // FIXME this may not handle time with random events correctly... + if (!e.isRandom() && compareTime(newTime, lastTime) > 0) { + if (verbose) { + System.err.println(lastTime + ": changing time to " + newTime); + } + lastTime = newTime; + } + e.fire(); + if (verbose) System.err.println(e.getTime() + " Fired " + e + + " numTimed= " + pqueue.size()); + } + /** Returns the number of queued random events. **/ + public synchronized int randomCount() { return rqueue.size(); } + /** Returns the number of queued timed events. **/ + public synchronized int timedCount() { return pqueue.size(); } + /** Returns string of all pending events. Non-node events are ignored. **/ + public synchronized String pendingList() { + return pqueue.pendingList()+"\n"+rqueue.pendingList(); + } + + /** Returns true if there are any pending events in either queue */ + public synchronized boolean hasMoreEvents() { + return pqueue.size() > 0 || + rqueue.size() > 0 || + !emptyEventQueueBarriers.isEmpty(); + } + + /** + * @return the next event, but does not remove it. + **/ + private synchronized Event getNextEvent() { + int pSz = pqueue.size(), rSz = rqueue.size(), tot = pSz+rSz; + + if (DSimDebug.DEBUG) + Debug.log("Pending events when getting next event:\n" + + pqueue.pendingList()); + + if (tot>0) { + /* + * Handle after 0 rules specially. They are enqueud with + * delay of -1, so they happen "in the past". They must + * happen in preference to random rules to avoid instabilities. + */ + if (pSz > 0 && + compareTime(pqueue.front().getTime(),lastTime) < 0) { + return pqueue.next(); + } + float pick = rand.nextInt(tot); + if (pick deviceMapCopy; + int myCount; + + synchronized (this){ + while (!pqueue.isEmpty()) { + pqueue.next(); + } + while (!rqueue.isEmpty()) { + rqueue.next(); + } + + lastTime = 0; + + deviceMapCopy = + new HashMap(deviceMap); + // tLock should probably be held here to read tCount. + // @see + // Bug#3635 + myCount = tCount; + canAddDevices = false; + } + boolean shouldExit = false; + for (AbstractDevice currDevice : deviceMapCopy.values()) { + currDevice.interrupt(); + + try { + currDevice.join(2000); + if (currDevice.isAlive()) { + Debug.assertTrue(myCount != 0); + --myCount; + System.err.println("Unable to kill a " + currDevice.getName() + + " device."); + System.err.println("The code for " + currDevice.getName() + + " executed for more than two seconds " + + "without waiting on an object."); + shouldExit = true; + } + + } + catch(InterruptedException e) { + throw (AssertionFailure) + new AssertionFailure("Someone interrupted DSIM.") + .initCause(e); + } + } + if (shouldExit) { + System.err.println("You really should exit DSim as soon as possible."); + } + synchronized (this){ + deviceMap.clear(); + canAddDevices = true; + for (Iterator i = emptyEventQueueBarriers.iterator(); + i.hasNext(); ) { + ((CyclicBarrier) i.next()).restart(); + } + emptyEventQueueBarriers.clear(); + } + // This is a hack. It might get around bug 831. + // In normal cases, the thread count should be 0. + synchronized (tLock) { + tCount = 0; + } + + synchronized (activeThreads) { + for (int i = 0; i < activeThreads.size(); ++i) { + final AbstractDeviceThread th = activeThreads.get(i); + th.setProcessed(false); + th.clearEvents(); + } + activeThreads.clear(); + } + } + + synchronized Iterator getDeviceNames() { + // make a new set with a copy of the device names, and return an + // iterator through that. Otherwise, we would have synchronization + // issues. + return new HashSet(deviceMap.keySet()).iterator(); + } + + synchronized AbstractDevice getDevice(final String deviceName) { + return deviceMap.get(deviceName); + } + + synchronized void setRandomSeed(final long seed) { + rand.setSeed(seed); + } +} // end of class DigitalScheduler + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Event.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Event.java new file mode 100644 index 0000000000..e86c82567e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Event.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +/** + * The interface that the DigitalScheduler interacts with + * + * @author tim + * @author Dan Daly + * @version $Revision$ $Date$ + **/ + +public interface Event { + + /** + * Called by scheduler when it is time for this event to act. + **/ + void fire() ; + + /** + * Courtesy storage (but required) for the DigitalScheduler. + * @param _index the index associated with this event in the queue. + * @see DigitalScheduler + **/ + void setIndex(int _index) ; + + /** + * @return the previously stored value (via setIndex). + * Defaults to -1, which indicates that the event is not currently queued. + **/ + /*@ pure @*/ int getIndex() ; + + /** + * @return the time at which the event should fire, for non-random events. + **/ + /*@ pure @*/ long getTime(); + + /** + * @return a true value indicates that the event should fire at a random + * unspecified time. + **/ + /*@ pure @*/ boolean isRandom(); + +} // end of interface Event + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueue.java new file mode 100644 index 0000000000..2208f90282 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueue.java @@ -0,0 +1,410 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import com.avlsi.util.debug.Debug; +import com.avlsi.tools.dsim.Node; + +import java.util.NoSuchElementException; +import java.util.ArrayList; + +/** + *

    A queue of Event objects. Smaller ranks are more + * important.

    + * + * @bug Will not handle duplicates well. + * + * @todo Write postconditions for reheap() and remove(). + * @todo Improve postconditions for left(), right(), parent(). + * @todo Add real class invariant. + * @todo Write public contracts. + * + * @author Aaron Denney + * @version $Revision$ $Date$ + **/ + +public class EventQueue implements EventQueueInterface { + + // Attributes + + /*@ private + @ invariant heap != null; + @ private + @ invariant elementCount >= 0; + @ private + @ invariant class_invariant(); + @*/ + + /** + * The actual data-structure that holds the queue's elements as a heap. + **/ + private ArrayList heap = new ArrayList(); + + /** + * The size of the heap, thus the queue. + **/ + private int elementCount = 0; + + // Constructors + + /** Class constructor. Creates an empty priority queue. **/ + + public EventQueue() { } + + // Public Methods + + // ================================================================= + // EventQueueInterface implementation. + + // Documented in interface. + + /** + * @time-complexity O(size()) * O(ArrayList.get()) + **/ + + public String pendingList() { + String ret = ""; + for (int i = 0; i < heap.size(); i++) { + Event cur = (Event)heap.get(i); + if (cur != null) { + if (cur instanceof Node) { + ret = ret + ((Node)cur).getEventString() + "\n"; + } else { + ret = ret + "Generic Event at "+cur.getTime(); + } + } + } + return ret; + } + + // Documented in interface. + + /** + * @time-complexity O(log size()) + **/ + + public final void enqueue(Event e) { + heap.add(e); + e.setIndex(heap.size()-1); + elementCount++; + reheap(elementCount-1); + } + + // Documented in interface. + + /** + * @throws NoSuchElementException + * If the event queue is empty. + * @time-complexity O(log size()) + **/ + + public final Event next() { + if (elementCount == 0 ) { throw new NoSuchElementException(); } + return remove(0); + } + + // Documented in interface. + + /** + * @throws NoSuchElementException + * If the event queue is empty. + * @time-complexity O(1) + **/ + + public final Event front() { + if (elementCount == 0) { throw new NoSuchElementException(); } + return (Event)heap.get(0); + } + + // Documented in interface. + + /** + * @time-complexity O(1) + **/ + + public final boolean isEmpty() { return elementCount == 0; } + + // Documented in interface. + + /** + * @time-complexity O(1) + **/ + + public final int size() { return elementCount; } + + // Documented in interface. + + /** + * @throws NoSuchElementException + * If the event is not in the queue. + * @time-complexity O(log n) + * @bug Conditional on exception should be a disjunct, not a conjunct. + **/ + + public final void remove(Event e) { + int index = e.getIndex(); //heap.indexOf(c); + if (index < 0 && heap.get(index) != e) { throw new NoSuchElementException (); } + remove(index); + } + + /** + * Rerank event 'e'. Use after changing its priority. Use with care! + * + * @param e the event ot rerank. + * @exception NoSuchElementException if the event is not in the queue. + * @time-complexity O(n) + * @review Might want to keep and ignore duplicates instead. + * @bug This method is erroneous if 'e' has a valid index but actually isn't + * in the heap. + * + *
    
    +     * public normal_behavior
    +     *   requires e != null;
    +     *   ensures size() == \old(size());
    +     * also
    +     * private exceptional_behavior
    +     *   requires (Event)heap.get(e.getIndex()) != e;
    +     *   signals (NoSuchElementException nsee);
    +     * also
    +     * public exceptional_behavior
    +     *   requires e.getIndex() < 0;
    +     *   signals (NoSuchElementException nsee);
    +     * 
    + **/ + + public final void rerank(Event e) { + int index = e.getIndex(); //heap.indexOf(e); + if (index < 0) { throw new NoSuchElementException (); } + reheap(index); + } + + // end of EventQueueInterface implementation. + // ================================================================= + + // Protected Methods + + /** + * Copies the event 'e' into index 'i' in the queue. + * + * @param i the index in which to copy the event. + * @param e the event to copy. + * + *
    
    +     * protected normal_behavior
    +     *   requires i < size();
    +     *   requires e != null;
    +     *   ensures size() == \old(size());
    +     * also
    +     * private normal_behavior
    +     *   ensures (Event)heap.get(i) == e;
    +     * 
    + **/ + + protected final void copyInto(int i, Event e) { + Debug.assertTrue(i < elementCount); + heap.set(i, e); + e.setIndex(i); + } + + /** + * @return the event at index 'i' + * @param i the index of the event to get. + * + *
    
    +     * protected normal_behavior
    +     *   requires i < size();
    +     *   ensures size() == \old(size());
    +     * 
    + **/ + + protected final /*@ pure @*/ Event get(int i) { return (Event) heap.get(i); } + + /** + * Class invariant: implementation heap is total ordered from children to + * parents. + **/ + + protected final /*@ pure @*/ boolean class_invariant() { + if (elementCount != heap.size()) + return false; + for (int i = 1; i < elementCount; i++) { + if (compare(parent(i),i) > 0) + return false; + } + return true; + } + + + // Private Methods + + /** + * @return index of left subchild of the node with index 'i'. + * +// If this method weren't static, we would do: +// *
    
    +//   * private normal_behavior
    +//   *   requires i < size();
    +//   *   ensures \result < size();
    +//   *   ensures size() == \old(size());
    +//   * 
    + **/ + + private static final /*@ pure @*/ int left(int i) { return i*2 + 1; } + + /** + * @return index of right subchild of the node with index 'i'. + * +// If this method weren't static, we would do: +// *
    
    +//   * private normal_behavior
    +//   *   requires i < size();
    +//   *   ensures \result < size();
    +//   *   ensures size() == \old(size());
    +//   * 
    + **/ + + private static final /*@ pure @*/ int right(int i) { return i*2 + 2; } + + /** + * @return index of the parent of node with index 'i'. + * +// If this method weren't static, we would do: +// *
    
    +//   * private normal_behavior
    +//   *   requires i < size();
    +//   *   ensures \result < size();
    +//   *   ensures size() == \old(size());
    +//   * 
    + **/ + + private static final /*@ pure @*/ int parent(int i) { return (i-1)/2; } + + /** + * Remove the event at index 'i'. + * + * @param i the index of the event to remove from the queue. + * + *
    
    +     * private normal_behavior
    +     *   requires i < size();
    +     *   ensures size() == \old(size()) - 1;
    +     * 
    + **/ + + private final Event remove(int i) { + int lastIndex = elementCount-1; + exchange(i, lastIndex); + Event rv = (Event) heap.remove(lastIndex); + elementCount--; + //if node was not the last node in the array, reheap that + //node to a valid spot + if (i != lastIndex) reheap(i); + rv.setIndex(-1); + return rv; + } + + /** + * Reheap the queue's implementation heap. + * + * @param i the index of the event to reheap. + * @design Exact same algorithm as digital_sim.c + * @requires Pre-condition: everything but element i is in proper place. + * i.e. (parent(i) > i) xor ((i > left(i)) | (i > right(i))), + * or some combination. + * @ensures Preserve invariant of children larger than parent. + * + *
    
    +     * private normal_behavior
    +     *   requires i < size();
    +     *   ensures size() == \old(size());
    +     * 
    + **/ + + private final void reheap(int i) { + // if smaller than parent, pull up until no longer true. + while (true) { + int p=parent(i); + if ((i>0) && compare(i,p) < 0) { + exchange(i,p); + i = p; + } else { break; } + } + + // if larger than child, pull down. Must promote smaller of two + // children, otherwise invariant violated. more complicated than + // pull-up section because must check existence. + while (true) { + int l=left(i), r=right(i); + int s; + boolean l_smaller, r_smaller; + l_smaller = (l < elementCount) && (compare(l,i) < 0); + r_smaller = (r < elementCount) && (compare(r,i) < 0); + if (!l_smaller && !r_smaller) { break; } + else if (l_smaller && !r_smaller) { s = l; } + else if (r_smaller && !l_smaller) { s = r; } + else if (compare(l, r) < 0) { s = l; } + else { s = r; } + exchange(i,s); + i = s; + } + } + + /** + * Compare two events in the heap indexed by 'i' and 'j'. + * + * @return the difference in the times of two two events; [i] - [j]. + * @param i the first index to look up and compare. + * @param j the second index to look up and compare. + * + *
    
    +     * private normal_behavior
    +     *   requires i < size();
    +     *   requires j < size();
    +     *   ensures size() == \old(size());
    +     * 
    + **/ + + private final /*@ pure @*/ long compare(int i, int j) { + return ((Event)heap.get(i)).getTime() - ((Event)heap.get(j)).getTime(); + } + + /** + * Exchange the events at indices 'i' and 'j'. + * + * @param i the index of the first event to exchange. + * @param j the index of the second event to exchange. + * + *
    
    +     * private normal_behavior
    +     *   requires i < size();
    +     *   requires j < size();
    +     *   ensures (Event)heap.get(i) == (Event)heap.get(\old(j));
    +     *   ensures (Event)heap.get(j) == (Event)heap.get(\old(i));
    +     *   ensures size() == \old(size());
    +     * 
    + **/ + + private final void exchange(int i, int j) { + Debug.assertTrue(i < elementCount); + Debug.assertTrue(j < elementCount); + Event swapi = (Event)heap.get(i); + Event swapj = (Event)heap.get(j); + heap.set(i, swapj); + heap.set(j, swapi); + swapi.setIndex(j); + swapj.setIndex(i); + } + +} // end of class EventQueue + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueueInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueueInterface.java new file mode 100644 index 0000000000..23aadf4cab --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/EventQueueInterface.java @@ -0,0 +1,120 @@ +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +import java.util.NoSuchElementException; + +/** + * A queue of events. + * + * @author Dan Daly + * @version $Date$ + **/ + +public interface EventQueueInterface { + + /** + * @return a list of pending events as a string. + **/ + + /*@ pure @*/ String pendingList(); + + /** + * Add an event 'e' to the queue. + * + * @param e the event to add. + * + *
    
    +     * public normal_behavior
    +     *   requires e != null;
    +     *   ensures size() == \old(size()) + 1;
    +     * 
    + **/ + + void enqueue(Event e); + + /** + * @return remove the object at the front of the queue, and return it. + * @exception NoSuchElementException if the queue is empty. + * + *
    
    +     * public normal_behavior
    +     *   requires size() > 0;
    +     *   ensures size() == \old(size()) - 1;
    +     * also
    +     * public exceptional_behavior
    +     *   requires size() == 0;
    +     *   signals (NoSuchElementException nsee);
    +     * 
    + **/ + + Event next(); + + /** + * @return the object at the front of the queue, without removing it. + * @exception NoSuchElementException if the queue is empty. + * + *
    
    +     * public exceptional_behavior
    +     *   requires size() == 0;
    +     *   signals (NoSuchElementException nsee);
    +     * 
    + **/ + + /*@ pure @*/ Event front(); + + /** + * @return a flag indicating whether the queue is empty or not. + **/ + + /*@ pure @*/ boolean isEmpty(); + + /** + * @return the size of the queue. + * @time-complexity O(1) + * + *
    
    +     * public normal_behavior
    +     *   ensures \result >= 0;
    +     * 
    + **/ + + /*@ pure @*/ int size(); + + /** + * Remove event 'e' from the queue. + * + * @param e the event to remove. + * + *
    
    +     * public normal_behavior
    +     *   requires e != null;
    +     *   ensures size() == \old(size()) - 1;
    +// There is no variable heap... This is an interface.
    +//   * also
    +//   * public exceptional_behavior
    +//   *   requires (Event)heap.get(e.getIndex()) != e;
    +//   *   signals (NoSuchElementException nsee);
    +     * also
    +     * public exceptional_behavior
    +     *   requires e.getIndex() < 0;
    +     *   signals (NoSuchElementException nsee);
    +     * 
    + **/ + + void remove(Event e); + +} // end of interface EventQueueInterface + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ExceptionPrettyPrinter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ExceptionPrettyPrinter.java new file mode 100644 index 0000000000..21bfa80f1a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ExceptionPrettyPrinter.java @@ -0,0 +1,218 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.dsim; + +import java.io.BufferedReader; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cell.NoSuchEnvironmentException; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import com.avlsi.io.Printable; +import antlr.RecognitionException; +import antlr.TokenStreamRecognitionException; +import com.avlsi.cast.impl.SemanticWrapperException; +import com.avlsi.util.text.StringUtil; +import com.avlsi.io.WrapPrintStream; +import com.avlsi.io.WrapPrintWriter; + +/** + * Print DSim exceptions nicely. See bug 1843. + * @author Patrick Pelletier + */ +public class ExceptionPrettyPrinter { + /** + * This class should not be instantiated. + **/ + private ExceptionPrettyPrinter() { } + + private static class ExceptionInfo { + String message; + String filename; + int line; + int column; + Throwable exception; + final Printable out; + + ExceptionInfo(Printable out) { + this.out = out; + } + } + + private static void getPositionInfo(Throwable e, ExceptionInfo ei) { + if (e instanceof CastSemanticException) { + CastSemanticException cse = (CastSemanticException) e; + ei.filename = cse.getFileName(); + ei.line = cse.getLineNumber(); + ei.column = cse.getColumnNumber(); + } else if (e instanceof RecognitionException) { + RecognitionException re = (RecognitionException) e; + ei.filename = re.getFilename(); + ei.line = re.getLine(); + ei.column = re.getColumn(); + } + } + + private static void extractExceptionInfo(Throwable e, ExceptionInfo ei) { + if (e instanceof TokenStreamRecognitionException) { + e = ((TokenStreamRecognitionException) e).recog; + } + getPositionInfo(e, ei); + if (e.getMessage() != null && + !(e instanceof ArrayIndexOutOfBoundsException /* bug 3717 */)) { + if (e instanceof SemanticWrapperException) { + ei.message = ((SemanticWrapperException)e).getMessageOnly(); + if (ei.message.startsWith("Error instantiating")) + printThisException(ei); + } else { + if (ei.exception != null && + (ei.exception.getClass().isAssignableFrom(e.getClass()) || + e.getClass().isAssignableFrom(ei.exception.getClass()))) { + // glue together exception messages if exceptions are of + // the same type or if one extends the other; this is a + // somewhat common scenario, where a function throws an + // exception, and the function that called it rethrows the + // exception, but adding additional information that's not + // available to the function throwing the original + // exception + ei.message = ei.message + ": " + e.getMessage(); + } else { + ei.message = e.getMessage(); + } + } + } + Throwable cause = e.getCause(); + ei.exception = e; + if (cause != null) + extractExceptionInfo(cause, ei); + } + + private static void printThisException(ExceptionInfo ei) { + File file = null; + + if (ei.filename != null && ei.filename.length() > 0 && + ei.filename.charAt(0) == '<') { + // this fixes bug 6146 + ei.out.println("top-level: " + ei.message); + } else { + file = (ei.filename == null ? null : new File(ei.filename)); + String shortname = ei.filename; + if (file != null && file.canRead()) + shortname = file.getPath(); + else + file = null; + ei.out.println(shortname + ": " + ei.line + ": " + ei.message); + } + + if (file != null) { + try { + BufferedReader r = new BufferedReader(new FileReader(file)); + String line = ""; + int n = ei.line; + while (n-- > 0) + line = r.readLine(); + r.close(); + ei.out.println(line); + if (ei.column > 0) { + ei.out.println(StringUtil.repeatString(" ", ei.column-1) + + "^"); + } + } catch (IOException ignore) { + } + } + } + + /** + * Similar to printException, except that you can just supply your + * own message, rather than passing a real Exception. + * @param message your error message + * @param filename source file that the error occurred in + * @param line source line number that the error occurred on + * @param column source column number that the error occurred at + * (1-based, 0 means no column) + * @param out stream to print the message to + */ + public static void prettyMessage(String message, String filename, + int line, int column, Printable out) { + ExceptionInfo ei = new ExceptionInfo(out); + ei.message = message; + ei.filename = filename; + ei.line = line; + ei.column = column; + printThisException(ei); + } + + /** Pretty-print exception to standard output */ + public static void printException(CastSemanticException e) { + printException(e, System.out); + } + + /** Pretty-print exception to specified Printable */ + public static void printException(CastSemanticException e, + Printable out) { + ExceptionInfo ei = new ExceptionInfo(out); + extractExceptionInfo(e, ei); + printThisException(ei); + } + + /** + * Convenience routine to pretty-print to standard out a + * NoSuchEnvironmentException, which may wrap a CastSemanticException. + **/ + public static void printException(NoSuchEnvironmentException e) { + printException(e, System.out); + } + + /** + * Convenience routine to pretty-print to the specified Printable a + * NoSuchEnvironmentException, which may wrap a CastSemanticException. + **/ + public static void printException(NoSuchEnvironmentException e, + Printable out) { + final Throwable ce = e.getCause(); + if (ce == null) { + out.println("Environment " + e.getEnvironmentName() + + " does not exist in " + e.getCellName()); + } else if (ce instanceof CastSemanticException) { + printException((CastSemanticException) ce, out); + } + } + + // overloaded versions to take PrintStream or PrintWriter + public static void prettyMessage(String message, String filename, + int line, int column, PrintStream out) { + prettyMessage(message, filename, line, column, + new WrapPrintStream(out)); + } + + public static void printException(CastSemanticException e, + PrintStream out) { + printException(e, new WrapPrintStream(out)); + } + + public static void printException(NoSuchEnvironmentException e, + PrintStream out) { + printException(e, new WrapPrintStream(out)); + } + + public static void prettyMessage(String message, String filename, + int line, int column, PrintWriter out) { + prettyMessage(message, filename, line, column, + new WrapPrintWriter(out)); + } + + public static void printException(CastSemanticException e, + PrintWriter out) { + printException(e, new WrapPrintWriter(out)); + } + + public static void printException(NoSuchEnvironmentException e, + PrintWriter out) { + printException(e, new WrapPrintWriter(out)); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOp.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOp.java new file mode 100644 index 0000000000..9520cefb1d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOp.java @@ -0,0 +1,211 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.graph.Edge; +import com.avlsi.util.graph.Vertex; + +class HalfOp implements Vertex { + private final Node node; + private final int dir; + private final HalfOpGraph graph; + private double slew; + private final boolean isDuplicate; + private final Map outEdges; + private final Map deletedEdges; + private final Map insertedEdges; + + public HalfOp(HalfOpGraph graph, Node node, int dir) { + this.graph = graph; + this.node = node; + this.dir = (dir == 0) ? 0 : 1; + this.slew = 0.0; + this.isDuplicate=false; + + this.outEdges = new HashMap(); + this.deletedEdges = new HashMap(); + this.insertedEdges = new HashMap(); + } + + HalfOp(HalfOp o) { + this.graph = o.graph; + this.node = o.node; + this.dir = o.dir; + this.slew = 0.0; + this.isDuplicate = true; + this.outEdges = copyEdges(o); + this.deletedEdges = new HashMap(); + this.insertedEdges = new HashMap(); + } + + private Map copyEdges(HalfOp o) { + Map result = new HashMap(); + for(HalfOpEdge e: o.outEdges.values()) { + result.put(e.getSnk(), + graph.newHalfOpEdge(this, e.getSnk(), e.getRule())); + } + return result; + } + + @Override public HalfOp duplicate() { + assert(!isDuplicate); + return graph.getDuplicatedHalfOp(node, dir); + } + + @Override public void deleteEdge(Vertex v) { + HalfOp h = (HalfOp) v; + HalfOpEdge e = outEdges.get(h); + if (e != null) { + deletedEdges.put(h,e); + } + } + + /* TODO(piyush): addEdge currently assumes that edges are only + * added to duplicatedHalfOp. + */ + @Override public void addEdge(Vertex v) { + HalfOp h = (HalfOp) v; + assert(h.isDuplicate); + HalfOp o = graph.getHalfOp(h.getNode(), h.getDir()); + HalfOpEdge oe = outEdges.get(o); + HalfOpEdge e = graph.newHalfOpEdge(this, h, oe.getRule()); + if (e != null) { + deletedEdges.put(h,e); + } + } + + @Override public void restore() { + deletedEdges.clear(); + insertedEdges.clear(); + graph.deleteDuplicatedHalfOp(node, dir); + } + + boolean isDuplicate() { + return isDuplicate; + } + + void getEdgesFromNode() { + final HalfOp src = this; + getNode().foreachRule( + new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (r.asserted || sense != getDir()) { + return; + } + final HalfOp snk = graph.getHalfOp(r.target(), r.dir); + if (!outEdges.containsKey(snk)) { + final HalfOpEdge e = graph.newHalfOpEdge(src, snk, r); + outEdges.put(snk, e); + } + } + }); + } + + public Node getNode() { + return node; + } + + public int getDir() { + return dir; + } + + public double getSlew() { + return this.slew; + } + + public void setSlew(double slew) { + this.slew = slew; + node.setSlew((float) slew); + } + + @Override public String toString() { + return getHalfOpName(getNode(), getDir()); + } + + private String uniqId() { + return (isDuplicate ? "#T#" : "#F#") + toString(); + } + + static String getHalfOpName(Node n, int dir) { + return getHalfOpName(n.getName(), dir); + } + + static String getHalfOpName(HierName n, int dir) { + return n.getAspiceString() + ((dir == 0) ? "-" : "+"); + } + + @Override public int compareTo(Vertex v) { + if (v == null) { + throw new NullPointerException(); + } + HalfOp h = (HalfOp) v; + return this.uniqId().compareTo(h.uniqId()); + } + + @Override public boolean equals(Object o) { + return (o != null) && (o instanceof HalfOp) && + this.compareTo((HalfOp) o) == 0; + } + + @Override public int hashCode() { + return uniqId().hashCode(); + } + + public HalfOp not() { + return graph.getHalfOp(node, 1-getDir()); + } + + public Collection enables() { + Set ret = outEdges.keySet(); + ret.removeAll(deletedEdges.keySet()); + ret.addAll(insertedEdges.keySet()); + return ret; + } + + public Collection disables() { + return this.not().enables(); + } + + public Pair getLocalName() { + return graph.localize(this); + } + + @Override public void foreachEdge(final UnaryPredicate func) { + foreachEdge(func, outEdges, deletedEdges); + foreachEdge(func, insertedEdges, deletedEdges); + } + + private void foreachEdge(final UnaryPredicate func, + Map edges, + Map exclEdges) { + for (Map.Entry e: edges.entrySet()) { + if(!exclEdges.containsKey(e.getKey())) { + func.evaluate(e.getValue()); + } + } + } + + HalfOpEdge getEdge(HalfOp v) { + return outEdges.get(v); + } + + int numEdges() { + return this.outEdges.keySet().size(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpEdge.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpEdge.java new file mode 100644 index 0000000000..abfea89083 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpEdge.java @@ -0,0 +1,117 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import com.avlsi.util.graph.Edge; + +class HalfOpEdge implements Edge { + private final Rule r; + private final HalfOp src; + private final HalfOp snk; + + public HalfOpEdge(HalfOp src, HalfOp snk, Rule r) { + this.r = r; + this.src = src; + this.snk = snk; + } + + @Override public HalfOp getSnk() { + return snk; + } + + @Override public HalfOp getSrc() { + return src; + } + + @Override public double getWeight() { + return getWeight(false); + } + + public double getWeight(boolean updateSlew) { + // TODO(piyush): Edges with no measured delay are ignored. + // Make this controlled by a switch. + // Warn when ignoring an edge. + return getDelay(src.getSlew(), Double.POSITIVE_INFINITY, + updateSlew); + } + + public double getDelay(double inputSlew, double fallbackDelay, + boolean updateSlew) { + return computeDelay(inputSlew, fallbackDelay, updateSlew, false); + } + + public double getMaxDelay(double inputSlew, double fallbackDelay, + boolean updateSlew) { + return computeDelay(inputSlew, fallbackDelay, updateSlew, true); + } + + private double computeDelay(double inputSlew, double fallbackDelay, + boolean updateSlew, boolean maxDelay) { + float[] delaySlew = new float[2]; + + src.setSlew(inputSlew); + delaySlew[0] = (float) fallbackDelay; + if (!r.getMeasured(src.getNode(), delaySlew)) { + delaySlew[0] = (float) fallbackDelay; + } + + if(delaySlew[0] == 0.0) { + System.err.println("WARNING: 0 delay for edge: " + toString()); + } + + if(updateSlew) { + snk.setSlew(delaySlew[1]); + } + return (maxDelay ? delaySlew[0] + toDSim(delaySlew[1]) : delaySlew[0]); + } + + @Override public double relax(double srcWeight, double currSnkWeight) { + double newSnkWeight = srcWeight + getWeight(); + if (newSnkWeight < currSnkWeight) { + getWeight(true); + } else { + newSnkWeight = -1; + } + return newSnkWeight; + } + + public double getSlew(double inputSlew, double fallbackSlew) { + float[] delaySlew = new float[2]; + + src.setSlew(inputSlew); + delaySlew[0] = r.delay; + delaySlew[1] = (float) fallbackSlew; + if (!r.getMeasured(src.getNode(), delaySlew)) { + delaySlew[1] = (float) fallbackSlew; + } + + return delaySlew[1]; + } + + public static double toPs(double dsimUnits) { + return dsimUnits / 100; + } + + public static double toDSim(double ps) { + return ps * 100; + } + + @Override public String toString() { + return src + "->" + snk; + } + + Rule getRule() { + return r; + } + + boolean hasMeasured() { + float[] measured = new float[2]; + return r.getMeasured(getSrc().getNode(), measured); + } +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpGraph.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpGraph.java new file mode 100644 index 0000000000..a28a655f3b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/HalfOpGraph.java @@ -0,0 +1,155 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import com.avlsi.file.common.HierName; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.graph.Edge; +import com.avlsi.util.graph.Graph; +import com.avlsi.util.graph.Vertex; + + +class HalfOpGraph implements Graph { + private DSim dsim; + private HashMap halfOps; + private HashMap duplicatedHalfOps; + + public HalfOpGraph(DSim dsim) { + this.dsim = dsim; + halfOps = new HashMap(); + duplicatedHalfOps = new HashMap(); + } + + Collection getExcludePaths(HalfOp h) { + Collection>> paths = + dsim.getSlintIgnoreFrom(h.getNode(), h.getDir()); + /* + * TODO(piyush): Currently only supports 1 exclusion path per node. + */ + assert(paths.size() <= 1); + + List excludePath = new LinkedList(); + HalfOp prev = null; + excludePath.clear(); + for (List> path : paths) { + for (Pair hop : path) { + HalfOp curr = getHalfOp(hop.getFirst(), hop.getSecond()); + if(prev != null) { + excludePath.add(prev.getEdge(curr)); + } + prev = curr; + } + } + return excludePath; + } + + @Override public void foreachVertex(final UnaryPredicate func) { + dsim.foreachNode( + new UnaryPredicate(){ + public boolean evaluate(Node n) { + if (n.getName().isVdd() || + n.getName().isGND() || + n.getName().isResetNode() ) { + return true; + } + for(int i = 0; i < 2; ++i) { + HalfOp h = getHalfOp(n, i); + func.evaluate(h); + } + return true; + } + }); + } + + public HalfOp getHalfOp(Node n, int dir) { + String halfOpName = HalfOp.getHalfOpName(n,dir); + HalfOp h = halfOps.get(halfOpName); + if(h == null) { + h = new HalfOp(this, n, dir); + halfOps.put(halfOpName, h); + } + return h; + } + + HalfOp getHalfOp(String name) { + return halfOps.get(name); + } + + public HalfOpEdge newHalfOpEdge(HalfOp src, HalfOp snk, Rule r) { + return new HalfOpEdge(src, snk, r); + } + + HalfOp getDuplicatedHalfOp(Node n, int dir) { + String halfOpName = HalfOp.getHalfOpName(n,dir); + HalfOp h = duplicatedHalfOps.get(halfOpName); + if(h == null) { + HalfOp original = halfOps.get(halfOpName); + if (original != null) { + h = new HalfOp(original); + duplicatedHalfOps.put(halfOpName, h); + } + } + return h; + } + + void deleteDuplicatedHalfOp(Node n, int dir) { + String halfOpName = HalfOp.getHalfOpName(n,dir); + duplicatedHalfOps.remove(halfOpName); + } + + public Pair localize(HalfOp h) { + Triplet localInfo = + dsim.localize(h.getNode().getName()); + return new Pair( + localInfo.getSecond().getType(), + HalfOp.getHalfOpName(localInfo.getThird(), h.getDir())); + } + + void init() { + dsim.foreachNode( + new UnaryPredicate(){ + public boolean evaluate(Node n) { + if (n.getName().isVdd() || + n.getName().isGND() || + n.getName().isResetNode() ) { + return true; + } + for(int i = 0; i < 2; ++i) { + HalfOp h = getHalfOp(n, i); + h.getEdgesFromNode(); + } + return true; + } + }); + } + + boolean isDynamic(HalfOp h) { + return dsim.isDynamic(h.getNode()); + } + + boolean hasFullStaticizer(HalfOp h) { + return dsim.hasFullStaticizer(h.getNode()); + } + + HalfOp getStaticizerInverse(HalfOp h) { + Node si = dsim.getStaticizerInverse(h.getNode()); + if(si != null) { + return getHalfOp(si, 1-h.getDir()); + } + return null; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InputSlewCheck.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InputSlewCheck.java new file mode 100644 index 0000000000..80599031fa --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InputSlewCheck.java @@ -0,0 +1,110 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.graph.ShortestPaths; +import com.avlsi.util.graph.Edge; +import com.avlsi.util.graph.Vertex; + +class InputSlewCheck extends SlewCheck { + private Map slowDelays; + private Map criticalInput; + + InputSlewCheck() { + slowDelays = new HashMap(); + criticalInput = new HashMap(); + } + + void evaluateSlowPaths(HalfOpGraph circuit, + final Map slews) { + slowDelays.putAll(maxInputSlew(circuit, slews)); + + } + + double getSlowDelay(Vertex v) { + Double slow = slowDelays.get(v.toString()); + if (slow == null) { + return -1; + } + return slow; + } + + private Map maxInputSlew( + final HalfOpGraph circuit, + final Map slews) { + final HashMap maxInputSlews = + new HashMap(); + circuit.foreachVertex( + new UnaryPredicate () { + @Override public boolean evaluate(Vertex v) { + v.foreachEdge( + new UnaryPredicate() { + @Override public boolean evaluate(Edge e) { + String srcKey = e.getSrc().toString(); + String snkKey = e.getSnk().toString(); + Double inputSlew = slews.get(srcKey) ; + Double victimSlew = maxInputSlews.get(snkKey); + if(inputSlew != null && + (victimSlew == null || + inputSlew > victimSlew)) { + maxInputSlews.put(snkKey, inputSlew); + criticalInput.put(snkKey.toString(), + e.getSrc().toString()); + } + return true; + } + }); + return true; + } + }); + return maxInputSlews; + } + + @Override + void checkViolations(HalfOpGraph circuit, HalfOp src, ShortestPaths paths, + double absMargin, double multMargin, + boolean checkIsochronicForks) { + Collection reached = paths.getReached(); + Collection disabledBySrc = src.disables(); + HalfOp notSrc = src.not(); + double slow = getSlowDelay(src); + if (slow < 0 ) { + return; + } + double effectiveSlow = computeEffectiveDelay(slow, absMargin, + multMargin); + for(Vertex v : reached) { + HalfOp r = (HalfOp) v; + + if(r.equals(src) || r.isDuplicate() || + paths.getDistance(r, + Double.POSITIVE_INFINITY) > effectiveSlow) { + continue; + } + + if(r.equals(notSrc)) { + //TODO(piyush): This check is "optimistic", perhaps it shoud + // check that notSrc is enabled and substract the fast + // delay through source from the cut-off path? + createViolation + (src, r, null, + circuit.getHalfOp(criticalInput.get(src.toString())), + null, paths, slow, absMargin, multMargin); + } + + // TODO(piyush): implement isochronic fork check here. + assert(!checkIsochronicForks); + } + } +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InstanceData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InstanceData.java new file mode 100644 index 0000000000..fbe2f2a579 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/InstanceData.java @@ -0,0 +1,865 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.common.HierName; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.UnaryFunction; + +/** + * A class for storing non-hierarchical net attributes. For example, the + * extra_delay directive is attached to a net by specifying it + * in the subcells block of the cell where the net becomes internal, but it + * affects all production rules that drives the net, no matter how many + * level of hierarchy away they are from where the directive is specified. + * This class aggregates all attributes that need to be handled in a + * net specific way. + **/ +public class InstanceData { + /** + * Represents an attribute. + **/ + public interface AttributeInterface { + /** + * Get the value of the attribute for the given node. + **/ + Object getAttribute(final HierName canon); + + /** + * Return a new AttributeInterface that is applicable + * to an instance of subcell with name + * instance in the cell cell. + **/ + AttributeInterface translate(final CellInterface cell, + final CellInterface subcell, + final AliasedSet cellAliases, + final AliasedSet subcellAliases, + final HierName instance); + } + + /** + * An attribute stored as a directive parameterized on nodes. + **/ + public static class NodeDirective implements AttributeInterface { + private final Map /**/ directives; + private final UnaryFunction /**/ getter; + private MultiMap/*>*/ cache; + + public NodeDirective(final CellInterface ci, + final AliasedSet aliases, + final UnaryFunction getter) { + this.directives = + DirectiveUtils.canonizeKey(aliases, + (Map) getter.execute(ci)); + this.getter = getter; + } + public NodeDirective(final CellInterface ci, + final Map /**/ directives, + final UnaryFunction getter) { + this.directives = directives; + this.getter = getter; + } + private NodeDirective(final Map directives, + final UnaryFunction getter) { + this.directives = directives; + this.getter = getter; + } + public Object getAttribute(final HierName canon) { + return directives.get(canon); + } + public AttributeInterface translate(final CellInterface cell, + final CellInterface subcell, + final AliasedSet cellAliases, + final AliasedSet subcellAliases, + final HierName instance) { + // in anticipation that translate will be called on all instances + // of cell, group attributes by instance + if (cache == null) attributeByInstance(cell, cellAliases); + final Collection cached = cache.get(instance); + final Map translated; + if (cached == null) { + translated = Collections.EMPTY_MAP; + } else { + translated = new LinkedHashMap(); + final int n = instance.getNumComponents(); + for (Iterator i = cached.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName alias = (HierName) p.getFirst(); + translated.put(alias.tail(n), p.getSecond()); + } + } + final Map newdir = + augmentMap(translated, + (Map) getter.execute(subcell), subcellAliases); + return new NodeDirective(newdir, getter); + } + private void attributeByInstance(final CellInterface cell, + final AliasedSet cellAliases) { + for (Iterator i = directives.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName key = (HierName) entry.getKey(); + final Object val = entry.getValue(); + final Iterator j = cellAliases.getAliases(key); + if (j == null) continue; + // iterate over all aliases, because otherwise aliases created + // in ancestors will not be handled correctly in children + while (j.hasNext()) { + final HierName alias = (HierName) j.next(); + HierName parent = alias.getParent(); + Pair p = null; + while (parent != null) { + if (cell.getSubcell(parent) != null) { + if (p == null) { + p = new Pair(alias, val); + } + if (cache == null) { + cache = + new MultiMap(new HashMap(), + MultiMap.ARRAY_LIST_FACTORY); + } + cache.put(parent, p); + // could break here if we don't care about inlined + // subcells + } + parent = parent.getParent(); + } + } + } + if (cache == null) cache = MultiMap.EMPTY_MULTIMAP; + } + } + + /** + * Special attribute for handling back annotated alint measured delay + * directives in DSim. + **/ + public static class MeasuredDirective implements AttributeInterface { + final Map /**/ directives; + private final UnaryFunction /**/ canonizer; + private final UnaryFunction /**/ getter; + private final HierName prefix; + + private static Map canonize(final HierName prefix, final Map map, + final UnaryFunction canonizer) { + // We assume that each target node in measured_delay directives + // appears in only one cell. The target node can be specified + // using any of its aliases, however, all usage must be consistent. + final Map canonized = new LinkedHashMap(); + for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName key = (HierName) entry.getKey(); + canonized.put(canonizer.execute(HierName.append(prefix, key)), + entry.getValue()); + } + return canonized; + } + + public MeasuredDirective(final CellInterface ci, + final UnaryFunction canonizer, + final UnaryFunction getter, + final HierName prefix) { + this(canonize(prefix, (Map) getter.execute(new Pair(prefix, ci)), + canonizer), + canonizer, getter, prefix); + } + private MeasuredDirective(final Map directives, + final UnaryFunction canonizer, + final UnaryFunction getter, + final HierName prefix) { + this.directives = directives; + this.canonizer = canonizer; + this.getter = getter; + this.prefix = prefix; + } + public Object getAttribute(final HierName canon) { + return directives.get(canon); + } + public AttributeInterface translate(final CellInterface cell, + final CellInterface subcell, + final AliasedSet cellAliases, + final AliasedSet subcellAliases, + final HierName instance) { + final HierName newPrefix = HierName.append(prefix, instance); + + // add new directives from subcells + directives.putAll( + canonize(newPrefix, + (Map) getter.execute(new Pair(newPrefix, subcell)), + canonizer)); + + // We keep 1 map for all measured_delay directives in all cells, + // thus we do not transform the map, but merely pass it in to the + // new instance + return new MeasuredDirective(directives, canonizer, getter, + newPrefix); + } + } + + /** + * Directives that are parameterized on instance names, and are + * multiplicative in nature down the instance hierarchy. + **/ + public static class MultiplicativeDirective implements AttributeInterface { + public static class Multiply implements BinaryFunction { + private final Double def; + public Multiply(final double def) { + this(new Double(def)); + } + public Multiply(final Double def) { + this.def = def; + } + public Object execute(final Object a, final Object b) { + final Number n1 = a == null ? def : (Number) a; + final Number n2 = b == null ? def : (Number) b; + return new Double(n1.doubleValue() * n2.doubleValue()); + } + } + + private final Object current; + private final Map /**/ directives; + private final UnaryFunction /**/ getter; + private final BinaryFunction /**/ product; + public MultiplicativeDirective(final Object current, + final CellInterface ci, + final UnaryFunction getter, + final BinaryFunction product) { + this(current, (Map) getter.execute(ci), getter, product); + } + private MultiplicativeDirective(final Object current, + final Map directives, + final UnaryFunction getter, + final BinaryFunction product) { + this.current = product.execute(current, directives.get(null)); + this.directives = directives; + this.getter = getter; + this.product = product; + } + public Object getAttribute(final HierName instance) { + return instance == null ? current + : product.execute(directives.get(instance), + current); + } + public AttributeInterface translate(final CellInterface cell, + final CellInterface subcell, + final AliasedSet cellAliases, + final AliasedSet subcellAliases, + final HierName instance) { + return new MultiplicativeDirective(getAttribute(instance), + (Map) getter.execute(subcell), getter, product); + } + } + + /** + * A half operator directive is just syntactic sugar for 2 node + * directives, one for the up direction, and one for the down + * direction. + **/ + public static class HalfOpDirective implements AttributeInterface { + public static class Convert implements UnaryFunction { + private final UnaryFunction getter; + private final boolean up; + public Convert(final boolean up, final UnaryFunction getter) { + this.getter = getter; + this.up = up; + } + public Object execute(final Object o) { + final Map dirs = (Map) getter.execute(o); + return up ? DirectiveUtils.getUps(dirs) : + DirectiveUtils.getDowns(dirs); + } + } + + final AttributeInterface up, down; + + public HalfOpDirective(final CellInterface ci, + final AliasedSet aliases, + final UnaryFunction getter) { + this(new NodeDirective(ci, aliases, new Convert(true, getter)), + new NodeDirective(ci, aliases, new Convert(false, getter))); + } + public HalfOpDirective(final CellInterface ci, + final Map /**/ updirs, + final Map /**/ dndirs, + final UnaryFunction getter) { + this(new NodeDirective(ci, updirs, new Convert(true, getter)), + new NodeDirective(ci, dndirs, new Convert(false, getter))); + } + public HalfOpDirective(final AttributeInterface up, + final AttributeInterface down) { + this.up = up; + this.down = down; + } + public Object getAttribute(final HierName canon) { + return new Pair(up.getAttribute(canon), + down.getAttribute(canon)); + } + public AttributeInterface translate(final CellInterface cell, + final CellInterface subcell, + final AliasedSet cellAliases, + final AliasedSet subcellAliases, + final HierName instance) { + return new HalfOpDirective( + up.translate(cell, subcell, cellAliases, subcellAliases, + instance), + down.translate(cell, subcell, cellAliases, + subcellAliases, instance)); + } + } + + public static class SubcellGetter implements UnaryFunction { + protected final String dir, type; + public SubcellGetter(final String dir, final String type) { + this.dir = dir; + this.type = type; + } + public Object execute(final Object o) { + final CellInterface cell = (CellInterface) o; + return DirectiveUtils.getSubcellDirective(cell, dir, type); + } + } + + /** + * Certain directives, e.g., cap and + * estimated_delay, are defined in both the subcells and + * the prs block. This will choose which block to get the directives + * from based on whether if a cell is a leaf cell, assuming that leaf + * cells have prs blocks, and midlevel cells have subcell blocks. + **/ + public static class SubcellPrsGetter implements UnaryFunction { + private final String dir, type; + public SubcellPrsGetter(final String dir, final String type) { + this.dir = dir; + this.type = type; + } + public Object execute(final Object o) { + final CellInterface cell = (CellInterface) o; + return CellUtils.isLeaf(cell) ? + DirectiveUtils.getPrsDirective(cell, dir, type) : + DirectiveUtils.getSubcellDirective(cell, dir, type); + } + } + + public static class MeasuredGetter implements UnaryFunction { + private final UnaryFunction getter; + private final Processor proc; + public interface Processor { + Object process(CellInterface cell, Pair target, HierName trigger, + List value); + } + public MeasuredGetter(final UnaryFunction getter, final Processor proc) + { + this.getter = getter; + this.proc = proc; + } + public Object execute(final Object o) { + final Pair p = (Pair) o; + final HierName prefix = (HierName) p.getFirst(); + final CellInterface cell = (CellInterface) p.getSecond(); + + // Rewrap the directives returned by the underlying getter into a + // more convenient form. + final Map/*[],Float[]>*/ val = + (Map) getter.execute(cell); + final Map/*,List>*/ + result = new LinkedHashMap(); + for (Iterator i = val.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final List key = (List) entry.getKey(); + + final Pair target = (Pair) key.get(0); + final HierName trigger = key.size() > 1 ? + (HierName) ((Pair) key.get(1)).getFirst() : null; + final List value = (List) entry.getValue(); + final Object measured = + proc.process(cell, target, trigger, value); + if (measured == null) continue; + + if (!result.containsKey(target)) { + result.put(target, new ArrayList()); + } + + ((List) result.get(target)).add(new Triplet(prefix, trigger, + measured)); + } + return result; + } + } + + private final Map /**/ attributes; + + public InstanceData() { + this(new HashMap()); + } + + private InstanceData(final Map attributes) { + this.attributes = attributes; + } + + private static Map augmentMap(final Map parent, final Map child, + final AliasedSet aliases) { + final Map result = DirectiveUtils.canonizeKey(aliases, parent); + final Map canon = DirectiveUtils.canonizeKey(aliases, child); + result.putAll(canon); + return result; + } + + /** + * Given a map of nodes to values, returns a new map that only + * contains entries relevent to the given subcell instance, with the + * keys translated to the namespace of the subcell. + * n, m and i are arbitrary + * HierNames, then node n is relevant to + * instance i if n and i.m are + * aliased together in aliases, and the translated name of + * n is m. + **/ + private static Map /**/ + translateMap(final AliasedSet aliases, final HierName instance, + final Map /**/ old) { + final Map /**/ result = new LinkedHashMap(); + final int n = instance.getNumComponents(); + for (Iterator i = old.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName key = (HierName) entry.getKey(); + final Iterator j = aliases.getAliases(key); + if (j == null) continue; + while (j.hasNext()) { + final HierName alias = (HierName) j.next(); + if (alias.isChildOf2(instance)) { + result.put(alias.tail(n), entry.getValue()); + // Cannot break here; otherwise aliases created in + // ancestors will not be handled correctly in children + } + } + } + return result; + } + + /** + * Returns a new InstanceData that is suitable for use when + * processing subcell. + * + * @param cell Cell associated with this InstanceData + * @param subcell Subcell to process + * @param instance Instance name of the subcell + * @param cad Where to find alias information + **/ + public InstanceData translate(final CellInterface cell, + final CellInterface subcell, + final HierName instance, + final Cadencize cad) { + final AliasedSet cellAliases = + cad.convert(cell).getLocalNodes(); + final AliasedSet subcellAliases = + cad.convert(subcell).getLocalNodes(); + + final Map newattr = new HashMap(attributes); + + for (Iterator i = newattr.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final AttributeInterface ai = (AttributeInterface) entry.getValue(); + entry.setValue(ai.translate(cell, subcell, cellAliases, + subcellAliases, instance)); + } + + return new InstanceData(newattr); + } + + public AttributeInterface put(final String name, + final AttributeInterface attr) { + return (AttributeInterface) attributes.put(name, attr); + } + + public AttributeInterface get(final String name) { + return (AttributeInterface) attributes.get(name); + } + + public void updateAstaExtraDelay(final CellInterface cell, + final AliasedSet aliases) { + put(DirectiveConstants.ASTA_EXTRA_DELAY, + new HalfOpDirective(cell, aliases, + new SubcellGetter(DirectiveConstants.ASTA_EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE))); + } + + public void updateExtraDelay(final CellInterface cell, + final AliasedSet aliases) { + put(DirectiveConstants.EXTRA_DELAY, + new HalfOpDirective(cell, aliases, + new SubcellGetter(DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE))); + } + + public void updateExtraDelay(final CellInterface cell, + final Map updirs, + final Map dndirs) { + put(DirectiveConstants.EXTRA_DELAY, + new HalfOpDirective(cell, updirs, dndirs, + new SubcellGetter(DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE))); + } + + public void updateExtraDelay(final CellInterface cell, + final AliasedSet aliases, + final UnaryFunction customize) { + put(DirectiveConstants.EXTRA_DELAY, + new HalfOpDirective(cell, aliases, + (UnaryFunction) customize.execute( + new SubcellGetter(DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE)))); + } + + public void updateEstimatedDelay(final CellInterface cell, + final AliasedSet aliases) { + put(DirectiveConstants.ESTIMATED_DELAY, + new HalfOpDirective(cell, aliases, + new SubcellPrsGetter(DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.HALFOP_TYPE))); + } + + public void updateEstimatedDelaySignoff(final CellInterface cell, + final AliasedSet aliases) { + put(DirectiveConstants.ESTIMATED_DELAY_SIGNOFF, + new HalfOpDirective(cell, aliases, + new SubcellPrsGetter(DirectiveConstants.ESTIMATED_DELAY_SIGNOFF, + DirectiveConstants.HALFOP_TYPE))); + } + + public void updateDelayBias(final CellInterface cell, final Double cur) { + final Double one = new Double(1); + put(DirectiveConstants.DELAYBIAS, new MultiplicativeDirective(cur, cell, + new SubcellGetter(DirectiveConstants.DELAYBIAS, + DirectiveConstants.INSTANCE_TYPE) { + public Object execute(final Object o) { + final Map result = new HashMap((Map) super.execute(o)); + final CellInterface cell = (CellInterface) o; + result.put(null, + DirectiveUtils.getTopLevelDirective(cell, dir)); + return result; + } + }, + new MultiplicativeDirective.Multiply(one))); + } + + public void updateDelayBias(final CellInterface cell) { + updateDelayBias(cell, 1.0); + } + + public class MeasuredProcessor implements MeasuredGetter.Processor { + private final float delayScale; + private final int dataSet; + public MeasuredProcessor(final float delayScale, final int dataSet) { + this.delayScale = delayScale; + this.dataSet = dataSet; + } + private String errorPrefix(final CellInterface cell, final Pair target, + final HierName trigger) { + final HierName node = (HierName) target.getFirst(); + final Boolean up = (Boolean) target.getSecond(); + return "In " + cell.getFullyQualifiedType() + " " + + (trigger == null ? "" : trigger.toString()) + + " -> " + node + (up.booleanValue() ? "+" : "-"); + } + private void E(final String s) { + System.err.println(s); + } + private float[] toFloatArray(final List obj) { + final float[] result = new float[obj.size()]; + for (int i = 0; i < obj.size(); ++i) { + result[i] = ((Float) obj.get(i)).floatValue(); + } + return result; + } + + private Object linearModel(final CellInterface cell, final Pair target, + final HierName trigger, final List array) + { + if (array.size() < 4 || array.size() % 2 != 0) { + E(errorPrefix(cell, target, trigger) + ": First dimension is " + + array.size() + "; it must at least be 4 and even"); + return null; + } + + final int index; + final int totalSets = (array.size() - 2) / 2; + if (dataSet >= 0 && dataSet < totalSets) { + index = dataSet; + } else { + E(errorPrefix(cell, target, trigger) + ": Selected dataset " + + dataSet + " out of valid range [0.." + (totalSets - 1) + "]"); + index = 0; + } + + final List inputSlew = (List) array.get(1); + final List delay = (List) array.get(2 + index * 2); + final List outputSlew = (List) array.get(3 + index * 2); + if (inputSlew.size() != delay.size() || + inputSlew.size() != outputSlew.size()) { + E(errorPrefix(cell, target, trigger) + ": Number of delay and output slew points are " + delay.size() + " and " + outputSlew.size() + " respectively; number of input slew points is " + inputSlew.size()); + return null; + } + + final float[] result = new float[inputSlew.size() * 3]; + for (int i = 0; i < inputSlew.size(); ++i) { + result[i * 3] = ((Float) inputSlew.get(i)).floatValue(); + result[i * 3 + 1] = + ((Float) delay.get(i)).floatValue() * delayScale; + result[i * 3 + 2] = ((Float) outputSlew.get(i)).floatValue(); + } + return result; + } + private Object polynomialModel(final CellInterface cell, + final Pair target, + final HierName trigger, + final List array) { + if (array.size() % 2 == 0) { + E(errorPrefix(cell, target, trigger) + ": First dimension is " + + array.size() + "; it must be odd"); + return null; + } + + final int index; + final int totalSets = (array.size() - 1) / 2; + if (dataSet >= 0 && dataSet < totalSets) { + index = dataSet; + } else { + E(errorPrefix(cell, target, trigger) + ": Selected dataset " + + dataSet + " out of valid range [0.." + (totalSets - 1) + "]"); + index = 0; + } + final float[] delayCoeff = + toFloatArray((List) array.get(1 + index * 2)); + for (int i = 0; i < delayCoeff.length; ++i) + delayCoeff[i] *= delayScale; + + final float[] slewCoeff = + toFloatArray((List) array.get(2 + index * 2)); + + return new Pair(delayCoeff, slewCoeff); + } + + public Object process(final CellInterface cell, final Pair target, + final HierName trigger, final List value) { + final List first = (List) value.get(0); + + Object result = null; + final int model = Math.round(((Float) first.get(0)).floatValue()); + switch (model) { + case Rule.LINEAR_MODEL: + result = linearModel(cell, target, trigger, value); + break; + case Rule.POLYNOMIAL_MODEL: + result = polynomialModel(cell, target, trigger, value); + break; + default: + E(errorPrefix(cell, target, trigger) + ": " + model + + " is not a recognized model"); + } + return result == null ? null : new Pair(new Integer(model), result); + } + } + + public void updateMeasuredDelay(final HierName prefix, + final CellInterface cell, + final UnaryFunction canonizer, + final float delayScale, + final int dataSet) { + final UnaryFunction getter = + new MeasuredGetter( + new SubcellPrsGetter( + DirectiveConstants.MEASURED_DELAY, + DirectiveConstants.UNCHECKED_HALFOP_TYPE + "[]"), + new MeasuredProcessor(delayScale, dataSet)); + + final AttributeInterface up = + new MeasuredDirective(cell, canonizer, + new HalfOpDirective.Convert(true, getter), + prefix); + final AttributeInterface dn = + new MeasuredDirective(cell, canonizer, + new HalfOpDirective.Convert(false, getter), + prefix); + + put(DirectiveConstants.MEASURED_DELAY, new HalfOpDirective(up, dn)); + } + + private void updateCap(final HierName prefix, final CellInterface cell, + final UnaryFunction canonizer, final String dir) { + final UnaryFunction baseGetter = + new SubcellPrsGetter(dir, DirectiveConstants.UNCHECKED_NODE_TYPE); + final UnaryFunction getter = + new UnaryFunction() { + public Object execute(final Object o) { + final Pair p = (Pair) o; + final HierName prefix = (HierName) p.getFirst(); + final CellInterface cell = (CellInterface) p.getSecond(); + return baseGetter.execute(cell); + } + }; + + final AttributeInterface measured = + new MeasuredDirective(cell, canonizer, getter, prefix); + put(dir, measured); + } + + public void updateEstimatedCap(final HierName prefix, + final CellInterface cell, + final UnaryFunction canonizer) { + updateCap(prefix, cell, canonizer, DirectiveConstants.ESTIMATED_CAP); + } + + public void updateMeasuredCap(final HierName prefix, + final CellInterface cell, + final UnaryFunction canonizer) { + updateCap(prefix, cell, canonizer, DirectiveConstants.MEASURED_CAP); + } + + private Object getHalfopResult(final boolean up, final HierName canon, + final String name, final Object def) { + final Pair p = (Pair) get(name).getAttribute(canon); + final Object result = up ? p.getFirst() : p.getSecond(); + return result == null ? def : result; + } + + private float getHalfopResult(final boolean up, final HierName canon, + final String name, final float def) { + final Float result = (Float) getHalfopResult(up, canon, name, null); + return result == null ? def : result.floatValue(); + } + + /** + * Returns the extra_delay directive (from a subcells + * block) associated with the given node. + * + * @param up true for up transition, false + * for down transition. + * @param canon Canonical name of the node + * @return Value of the extra_delay directive for + * canon transitioning in the up direction, + * or 0 if no such directive has been specified. + **/ + public float getExtraDelay(final boolean up, final HierName canon) { + float astaExtraDelay = 0; + if (get(DirectiveConstants.ASTA_EXTRA_DELAY) != null) { + astaExtraDelay = + getHalfopResult(up, canon, DirectiveConstants.ASTA_EXTRA_DELAY, + 0); + } + return astaExtraDelay + + getHalfopResult(up, canon, DirectiveConstants.EXTRA_DELAY, 0); + } + + public Object getExtraDelay(final boolean up, final HierName canon, + final Object def) { + Object astaExtraDelay = def; + if (get(DirectiveConstants.ASTA_EXTRA_DELAY) != null) { + astaExtraDelay = + getHalfopResult(up, canon, DirectiveConstants.ASTA_EXTRA_DELAY, + def); + } + + Object extraDelay = + getHalfopResult(up, canon, DirectiveConstants.EXTRA_DELAY, def); + + if (astaExtraDelay == def && extraDelay == def) { + return def; + } else if (astaExtraDelay == def) { + return extraDelay; + } else if (extraDelay == def) { + return astaExtraDelay; + } else { + return ((Float) extraDelay).floatValue() + + ((Float) astaExtraDelay).floatValue(); + } + } + + public float getEstimatedDelay(final boolean up, final HierName canon) { + return getHalfopResult(up, canon, DirectiveConstants.ESTIMATED_DELAY, + Float.NaN); + } + + public float getEstimatedDelaySignoff(final boolean up, + final HierName canon) { + return getHalfopResult(up, canon, + DirectiveConstants.ESTIMATED_DELAY_SIGNOFF, + Float.NaN); + } + + public Triplet[] getMeasuredDelay(final boolean up, final HierName canon) { + final Pair dir = + (Pair) get(DirectiveConstants.MEASURED_DELAY).getAttribute(canon); + final List result = (List) (up ? dir.getFirst() : dir.getSecond()); + return result == null ? null : (Triplet[]) result.toArray(new Triplet[0]); + } + + public Map getMeasuredDelay(final boolean up) { + final HalfOpDirective halfopDir = + (HalfOpDirective) get(DirectiveConstants.MEASURED_DELAY); + final MeasuredDirective dirs = up ? (MeasuredDirective) halfopDir.up + : (MeasuredDirective) halfopDir.down; + return dirs == null ? null + : Collections.unmodifiableMap(dirs.directives); + } + + /** + * Return the measured_cap directive on the specified node in F. The + * measured_cap directive is actually specified in fF. + **/ + public float getMeasuredCap(final HierName canon) { + final Float result = + (Float) get(DirectiveConstants.MEASURED_CAP).getAttribute(canon); + return result == null ? Float.NaN : (result.floatValue() * 1e-15f); + } + + public float getEstimatedCap(final HierName canon) { + final Float result = + (Float) get(DirectiveConstants.ESTIMATED_CAP).getAttribute(canon); + return result == null ? Float.NaN : (result.floatValue() * 1e-15f); + } + + public void dumpMeasuredDelay() { + final HalfOpDirective halfopDir = + (HalfOpDirective) get(DirectiveConstants.MEASURED_DELAY); + final MeasuredDirective up = (MeasuredDirective) halfopDir.up; + final MeasuredDirective dn = (MeasuredDirective) halfopDir.down; + if (up != null) { + System.err.println("up: " + up.directives); + } + if (dn != null) { + System.err.println("dn: " + dn.directives); + } + } + + public float getDelayBias(final HierName instance) { + final Number result = + (Number) get(DirectiveConstants.DELAYBIAS).getAttribute(instance); + return result.floatValue(); + } + + public String toString() { + return attributes.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoBehaviorFoundException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoBehaviorFoundException.java new file mode 100644 index 0000000000..5ded3d9b76 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoBehaviorFoundException.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +/** + * Thrown to indicate that a cosimulation could not be carried out because + * no specified behavior was found. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class NoBehaviorFoundException extends Exception { + + /** + * Constructs a NoSuchCellException indicating + * that the specified cell could not be found. + **/ + public NoBehaviorFoundException(final String message) { + super(message); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoSuchCellException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoSuchCellException.java new file mode 100644 index 0000000000..3b60b06115 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NoSuchCellException.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +/** + * Thrown to indicate that a cell type could not be found. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class NoSuchCellException extends Exception { + + private final String cellType; + + /** + * Constructs a NoSuchCellException indicating + * that the specified cell could not be found. + **/ + public NoSuchCellException(final String cellType) { + this.cellType = cellType; + } + + /** + * Returns the type of cell that couldn't be found. + **/ + public String getCellType() { + return cellType; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Node.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Node.java new file mode 100644 index 0000000000..8806322a9c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Node.java @@ -0,0 +1,778 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +import java.util.NoSuchElementException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import com.avlsi.util.debug.Debug; +import com.avlsi.tools.dsim.Event; +import com.avlsi.tools.dsim.Rule; +import com.avlsi.tools.dsim.DSim; +import com.avlsi.tools.tsim.Waitable; +import com.avlsi.util.container.TriTree; +import com.avlsi.file.common.HierName; + +/** + * DSimNode class + * + * Representation of state and state-change for a particular node. + * DNF. This class only keeps track of the disjuncts. The conjuncts + * are kept track of by the *conjunct members in the {@link Rule} + * class. + *

    + * Each node can be triggered by any one of a number of different rules + * which are just boolean AND expressions. "A and not B and C". + *

    + * Would perhaps be slightly clearer if state-change and current state were + * kept in seperate entities. + * + * @author Aaron Denney + * @version $Name: $ $Date$ + **/ +public final class Node implements Event, Waitable { + /** String constants for the possible logic values **/ + private static final String [] valueNames = { "0", "1", "U" }; + /** Numeric constants for the possible logic values **/ + public static final byte VALUE_0 = 0, VALUE_1 = 1, VALUE_U = 2; + /** If true, then every node notifies the simulation on change. **/ + static boolean watchAll = false; + /** Reference to the Singleton simulator **/ + private static DSim sim = DSim.get(); + + /** Node that allows us to access our name. **/ + //MixNode label; + private final HierName name; + + /** Trigger time */ + long eventTime; + /** Rules we activate positively and negatively */ + private final Rule[][] rules = { new Rule[4], new Rule[4] }; + + /** + * The number of rules we have added. + * + *

    
    +     *   private constraint
    +     *     (\forall int i; 0 <= i && i < 2;
    +     *              (\num_of int j; 0 <= j && j < rules[i].length;
    +     *                       rules[i][j] != null)
    +     *              == numRules[i]);
    +     * 
    + **/ + private final int[] numRules = { 0, 0 }; + + /** number of disjuncts (rules) certainly driving us up and down. + * Note: this corresponds to pending, not current values. + **/ + private final int count[] = { 0, 0 }; + /** number of disjuncts (rules) possibly driving us up and down. + * Note: this corresponds to pending, not current values. + **/ + private final int uCount[] = { 0, 0 }; + + /** + * Beware: some of the fields are used by ASTA for different purposes: + * transitionCount - stores an index into the array of independent + * variables + * flags - if set, bit RANDOM_BIT indicates arrival times are fixed + * if set, bit BREAKPT_BIT indicates this node has dependent rules + **/ + + /** number of transitions */ + int transitionCount; + + /** the capacitance associated with this node */ + float capacitance = 0; + + /** the output slew rate */ + float output_slew = Float.NaN; + + /** the source of the delay, either digital, estimated, or measured */ + byte delay_type = DSim.DIGITAL_TAU; + + /** "for critical path analysis". + * saved to history. + **/ + Event enabler; + + /** Current value */ + byte value = VALUE_U; + /** Value after next transition */ + byte pending = VALUE_U; + /** Tracing, etc. */ + // The watches can be accessed by multiple java threads at once. + // Deciding to watch, or not watch a clock raising or lowering is + // a key example. So we synchronize access to it, but not through + // a Collections.SynchronizedCollection, as we also do not + // want Iterators to fail. The synchronization is done via this, + // as nothing else uses it. + private Collection watches = null; + + /** Tracing, etc. */ + private static final byte BREAKPT_BIT = 0x1; + private static final byte UNSTAB_DN_BIT = 0x2; + private static final byte UNSTAB_UP_BIT = 0x4; + private static final byte RANDOM_BIT = 0x8; + private static final byte GENERATION_BIT = 0x10; + + private byte flags = 0; + // /** linkage with aspice ... is this nodes value controlled by */ + // private boolean hasDigitalFanin; + + /** Class constructor. Creates an empty Node **/ + public Node(HierName name) { + this.name = name; + } + /** Sets the container which represents our canonical name. + The names are stored in the tree for space and searching efficiency. **/ + //public void setLabel(MixNode t) { label=t; } + /** Returns our container object. **/ + //public MixNode getLabel() { return label; } + /** Returns the Nodes canonical name from its TriTree node **/ + //public String getName() { + // if (label==null) { return null; } + // return label.getName(); + //} + /** Returns the Nodes canonical name. **/ + public HierName getName() { + return name; + } + + /** Returns the number of possible logical values for a node. **/ + public static int getNumValues() { return valueNames.length; } + /** converts an integer logical value into a corresponding string. **/ + public static String getNameForValue(int val) { + if (val<0 || val>=getNumValues()) { return ""; } + return valueNames[val]; + } + /** Returns the value that matches name s, default is unknown.*/ + public static byte getValueForName(String s) { + if (s!=null) { + if (s.equals("0")) { return VALUE_0; } + if (s.equals("1")) { return VALUE_1; } + } + return VALUE_U; + } + /** Returns a string representation of a pending change on the node **/ + public String getEventString() { + return getName().getAspiceString()+" "+valueNames[value]+"->"+valueNames[pending]+" at "+eventTime; + } + + /** Collect minimum and maximum slew across all rules */ + private final static float slewStat[] = new float[2]; + public static void resetSlewStat() { + slewStat[0] = Float.POSITIVE_INFINITY; + slewStat[1] = Float.NEGATIVE_INFINITY; + } + private static void updateSlewStat(final Node me) { + final float slew = me.getSlew(); + slewStat[0] = Math.min(slew, slewStat[0]); + slewStat[1] = Math.max(slew, slewStat[1]); + } + public static float[] getSlewStat() { + return slewStat; + } + + /* Event interface Methods... */ + /** Triggers this node as an event. **/ + public void fire() { + transitionCount++; + setValueAndEnqueueDependents(pending); + updateSlewStat(this); + } + private int index=-1; + /** Returns current index as set by the scheduler. **/ + public int getIndex() { return index; } + /** Sets current index (by the scheduler). -1 indicates not scheduled. **/ + public void setIndex(int _index) { + index = _index; + } + /** Returns the next time that we should fire. **/ + public long getTime() { return eventTime; } + /** Returns whether we should fire at a random time. **/ + public boolean isRandom() { return (flags & RANDOM_BIT) != 0; } + /** sets whether we should fire at a random time. **/ + public void setRandom(boolean b) { + if (b) { + flags |= RANDOM_BIT; + } else { + flags &= ~RANDOM_BIT; + } + } + + public boolean getGeneration() { return (flags & GENERATION_BIT) != 0; } + public void setGeneration(boolean b) { + if (b) { + flags |= GENERATION_BIT; + } else { + flags &= ~GENERATION_BIT; + } + } + + /** + * Add another rule we might trigger. + * + *
    
    +     *   private normal_behavior
    +     *     requires drule != null && 0 <= sense && sense < 2;
    +     *     ensures numRules[sense] == \old(numRules[sense]) + 1
    +     *          && numRules[1 - sense] == \old(numRules[1 - sense])
    +     *          && rules[sense][numRules[sense] - 1] == drule
    +     *          && (\forall int i; 0 <= i && i < \old(numRules[sense]);
    +     *                      rules[sense][i] == \old(rules[sense][i]))
    +     *          && (\forall int i; 0 <= i && i < numRules[1 - sense];
    +     *                      rules[sense][i] == \old(rules[1 - sense][i]));
    +     * 
    + **/ + void addRule(Rule drule, int sense) { + // The rule's counts are adjusted in its constructor. + Debug.assertTrue(sense >= 0 && sense < 2); + final int nr = numRules[sense]; + final Rule[] rs = rules[sense]; + + if (nr == rs.length) { + final Rule[] newRules = new Rule[2 * nr]; + System.arraycopy(rs, 0, newRules, 0, nr); + rules[sense] = newRules; + + newRules[nr] = drule; + numRules[sense] = nr + 1; + } else { + rs[nr] = drule; + numRules[sense] = nr + 1; + } + } + + /** Remove from our watcher list. **/ + public synchronized boolean removeWatch(NodeWatcher w) { + if (watches == null) + return false; + else + return watches.remove(w); + } + + /** Remove all watchers associated with this node **/ + public synchronized void removeAllWatchers(){ + watches = null; + } + + /** Add to our watcher list, for change notifications. **/ + public synchronized boolean addWatch(NodeWatcher w) { + if (watches == null) + watches = new ArrayList/**/(1); + // Only add if the watcher is not already registered + return watches.contains(w) || watches.add(w); + } + /** Check presence in our watcher list. **/ + public synchronized boolean isWatcher(NodeWatcher w) { + if (watches == null) + return false; + else + return watches.contains(w); + } + + /** Do we stop the simulation on change? **/ + public boolean getBreakpoint() { return (flags & BREAKPT_BIT) != 0; } + + /** Sets whether we stop the simulation on change. **/ + public void setBreakpoint(boolean b) { + if (b) { + flags |= BREAKPT_BIT; + } else { + flags &= ~BREAKPT_BIT; + } + } + + /** Do we care if node goes unstable (per pending direction)? **/ + public boolean isUnstable(int pending) { + if (pending==VALUE_0) return (flags & UNSTAB_DN_BIT) != 0; + else if (pending==VALUE_1) return (flags & UNSTAB_UP_BIT) != 0; + else return false; + } + + /** Sets whether we care if node goes unstable (per direction). **/ + public void setUnstable(boolean updir) { + if (updir) flags |= UNSTAB_UP_BIT; + else flags |= UNSTAB_DN_BIT; + } + + /** Returns the current number of transitions this node has undergone. **/ + public int getTCount() { return transitionCount; } + + /** clears the transitionCount associated with node. **/ + public void clearTCount() { transitionCount =0; } + + /** sets the transitionCount associated with node. **/ + public void setTCount(int tcount) { transitionCount = tcount; } + + /** returns a short string representation of this Node. **/ + public String toString() { return getName().getAspiceString() + ":" + valueNames[value]; } + /** Returns a list of Rules that we affect. Used for debugging. **/ + public List getTargets() { + List ret = new ArrayList(); + for (int i=0; i<2; i++) { + ret.addAll(getTargets(i)); + } + return ret; + } + /** Returns a list of Rules that the input sense targets. **/ + public List getTargets(int sense) { + List ret = new ArrayList(); + int n = numRules[sense]; + Rule[] rs = rules[sense]; + for (int j = 0; j < n; j++) { + ret.add(rs[j]); + } + return ret; + } + /** Is the given Rule affected by us. Slow, used for debugging. **/ + public boolean targets(Rule targ) { + for (int i=0; i<2; i++) { + int n = numRules[i]; + Rule[] rs = rules[i]; + for (int j = 0; j < n; j++) { + Rule r = rs[j]; + if (r==targ) { return true; } + } + } + return false; + } + /** Returns which direction causes a given Rule to be activated. **/ + public int getSense(Rule targ) { + int n = numRules[0]; + Rule[] rs = rules[0]; + for (int i = 0; i < n; ++i) { + Rule r = rs[i]; + if (r==targ) { return 0; } + } + return 1; + } + /** List our rules. **/ + public String listRules() { + String ret = getName().getAspiceString()+" (" + +getNameForValue(value)+"->"+getNameForValue(pending)+", " + +count[0]+"-, "+count[1]+"+, " + +uCount[0]+"u-, "+uCount[1]+"u+)\n"; + for (Rule r : sim.getTargetingRules(this)) { + ret = ret + r.getGuardList() +"\n"; + } + return ret; + } + + /** + * Modify a node's value by external poking. + * Adjusts count and possibly fire rules we trigger. + * + *
    
    +     *   public normal_behavior
    +     *     requires 0 <= newValue && newValue <= 2;
    +     * 
    + **/ + public void setValueAndEnqueueDependents(byte newValue) { + int s; + Debug.assertTrue(newValue >= 0 && newValue <=2); + + if (getBreakpoint()) { sim.interrupt(); } + + if (value==newValue) { return; } + + for (s=0; s<2; s++) { + int n = numRules[s]; + Rule[] rs = rules[s]; + for (int j = 0; j < n; ++j) { + Rule drule = rs[j]; + // compute old state + drule.updateOldState(); // Why can't we just copy current state? + //if (drule.falseConjuncts>0) + // drule.oldState=Rule.RULE_OFF; + //else if (drule.unknownConjuncts>0) + // drule.oldState=Rule.RULE_U; + //else + // drule.oldState=Rule.RULE_ON; + } + } + /*** update dependent rule and node counters ***/ + for (s=0; s<2; s++) { + int n = numRules[s]; + Rule[] rs = rules[s]; + for (int j = 0; j < n; ++j) { + Rule drule = rs[j]; + + /*** reverse last transition on node ***/ + drule.reverseTransitions(); + //if (drule.falseConjuncts==0) { + // if (drule.unknownConjuncts==0) drule.target.dropCount(drule.dir); + // else drule.target.dropUCount(drule.dir); + //} + + /*** update rule conjunct counts ***/ + switch (newValue) { + case VALUE_0: + drule.falseConjuncts+=s; + break; + case VALUE_1: + drule.falseConjuncts+=(1-s); + break; + case VALUE_U: + drule.unknownConjuncts++; + break; + default: + Debug.assertTrue(false); + } + + switch (value) { + case VALUE_0: + drule.falseConjuncts-=s; + break; + case VALUE_1: + drule.falseConjuncts-=(1-s); + break; + case VALUE_U: + drule.unknownConjuncts--; + break; + default: + Debug.assertTrue(false); + } + + /*** update counts of target node ***/ + drule.updateTargetCounts(); + //if (drule.falseConjuncts==0) { + // if (drule.unknownConjuncts==0) drule.target.bumpCount(drule.dir); + // else drule.target.bumpUCount(drule.dir); + //} + } + } + + for (s=0; s<2; s++) { + int n = numRules[s]; + Rule[] rs = rules[s]; + for (int j = 0; j < n; ++j) { + Rule drule = rs[j]; + // compute drule.newState + drule.updateNewState(); + //if (drule.falseConjuncts>0) { drule.newState=Rule.RULE_OFF; } + //else if (drule.unknownConjuncts>0) { drule.newState=Rule.RULE_U; } + //else { drule.newState=Rule.RULE_ON; } + } + } + + /*** set node value ***/ + value=newValue; + + /*** debugging printouts ***/ + synchronized (this) { // Do not want a stale iterator + boolean toldDSim = false; + if (watches != null) { + for (Iterator i = watches.iterator(); i.hasNext();) { + NodeWatcher nw = (NodeWatcher)i.next(); + if (nw==sim) { toldDSim = true; } + nw.nodeChanged(this, sim.getTime()); + } + } + if (!toldDSim && watchAll) { + sim.nodeChanged(this, sim.getTime()); + } + } + + /*** fire modified rules ***/ + boolean critical = false; + for (s=0; s<2; s++) { + int n = numRules[s]; + Rule[] rs = rules[s]; + for (int j = 0; j < n; ++j) { + Rule drule = rs[j]; + if (drule.modified()) { + drule.fireRule(this); + critical = true; + } + } + } + + /*** record history ***/ + if (sim.recordHistory(critical)) { + sim.recordEvent(this, enabler, eventTime, transitionCount, newValue, getSlew(), getDelayType()); + } + } + + /** Returns our current value (vs pending value). **/ + public /*@ pure @*/ byte getValue() { return value; } + + /** Notification that a Rule affecting this Node changed its state **/ + public void ruleFired(int delay, float slew, byte type, byte oldState, + byte newState, Node lastEvent, Rule drule) { + if (getBreakpoint()) { System.out.println("Rule fired on breakpointed node: "+getName().getAspiceString()); } + /*** figure out whats happening to the node ***/ + if ((count[0]+uCount[0]>0)&& (count[1]+uCount[1]>0)) { /*** interfering ***/ + if ((oldState==Rule.RULE_OFF)&&(((index < 0)&&(value!=VALUE_U)) || + (((index >=0)&&(pending!=VALUE_U))))) { + /*** interfering ***/ + //sim.eventWarning(lastEvent,drule,"interfering"); + sim.interferenceWarning(lastEvent,drule); + sim.scheduleEvent(this,VALUE_U,-1,false,lastEvent); + } + } else if ((count[0]>0) || (count[1]>0)) /*** driven ***/ { + byte dir; + boolean random = false; + dir=(count[1]>0?(byte)1:(byte)0); + if (delay==0) { + // Magical "after 0" delay always fires instantly in + // any timing mode. This construct should be avoided + // if possible, except in env bodies or in glitching + // circuits like synchronizers. --AML + delay = -1; + } + else if (drule.isochronic && (sim.randomOrder == DSim.UNTIMED_RANDOM)) { + // isochronic rules fire "instantly" in random + // simulations intended to replace old "after 0" + // notation for timing assumptions. + delay = -1; + } + else if (sim.randomOrder != DSim.NO_RANDOM && !drule.absoluteDelay) { + if (drule.timed || sim.randomOrder == DSim.TIMED_RANDOM) { + delay *= sim.randomDelay(); + } else { + random = true; + delay = 0; + } + } + + if (index < 0) { + if (value==dir); /*** vacuous ***/ + else if (value==VALUE_U) { + /*** new event due to disappearance of interference ***/ + sim.eventNotice(lastEvent,drule,"changes from U"); + sim.scheduleEvent(this,dir,0,false,lastEvent); + } else if (newState==Rule.RULE_ON) { + /*** new event ***/ + sim.eventNotice(lastEvent,drule,"scheduled normally"); + setSlew(slew); + setDelayType(type); + sim.scheduleEvent(this,dir,delay,random,lastEvent); + } + } else { + if (pending==VALUE_U) { + /*** new event due to disappearance of interference ***/ + sim.eventNotice(lastEvent,drule,"changes from U"); + sim.scheduleEvent(this,dir,0,false,lastEvent); + } else if ((oldState==Rule.RULE_ON)&&(pending!=dir)) { + /*** instability ***/ + if (!isUnstable(pending)) { + // unstable (set to 0 or 1) + sim.glitchWarning(lastEvent,drule); + } + sim.scheduleEvent(this,dir,-1,false,lastEvent); + } else if ((newState==Rule.RULE_ON)&&(pending==dir)&& + sim.compareDelayToTime(delay, eventTime) < 0) { + /*** reschedule event ***/ + sim.eventNotice(lastEvent,drule,"rescheduled earlier"); + setSlew(slew); + setDelayType(type); + sim.scheduleEvent(this,dir,delay,random,lastEvent); + } + } + } else /*** floating ***/ { + if ((oldState==Rule.RULE_ON)&&(index >= 0)&&(pending!=VALUE_U)) { + /*** instability ***/ + if (!isUnstable(pending)) { + // unstable (set to U) + sim.unstabWarning(lastEvent,drule); + } + sim.scheduleEvent(this,VALUE_U,-1,false,lastEvent); + } else if ((newState==Rule.RULE_U)&&(((uCount[0]>0)&&(value==VALUE_1)) || + ((uCount[1]>0)&&(value==VALUE_0)))) { + /*** set to U ***/ + sim.eventWarning(lastEvent,drule,"set to U"); + sim.scheduleEvent(this,VALUE_U,-1,false,lastEvent); + } + } + } + + /** + * Cause this node to be scheduled to change as soon as possible, after + * the next running time. Does not block. + * If you want it to actually happen immediately, + * you can use setValueAndEnqueueDependents(). + **/ + public void scheduleImmediate(byte value) { + sim.scheduleEvent(this, value, -1, false, null); + } + + /** + * Cause this node to be scheduled to change at time t. + * Does not block. + **/ + public void scheduleTime(byte value, long t, Node lastEvent) { + long delay = t - sim.getTime(); + scheduleDelay(value, delay, lastEvent); + } + + /** + * Cause this node to be scheduled to change at time t. + * Does not block. + * Same as scheduleTime(value, t, null). + **/ + public void scheduleTime(byte value, long t) { + scheduleTime(value, t, null); + } + + /** + * Cause this node to be scheduled delay timesteps in the future. + * Does not block. + **/ + public void scheduleDelay(byte value, long delay, Node lastEvent) { + sim.scheduleEvent(this, value, delay, false, lastEvent); + } + + /** + * Cause this node to be scheduled delay timesteps in the future. + * Does not block. + * Same as scheduleDelay(value, delay, null). + **/ + public void scheduleDelay(byte value, long delay) { + scheduleDelay(value, delay, null); + } + + /** + * Place this transition on the random queue. + * Does not block. + **/ + public void scheduleRandom(byte value, Node lastEvent) { + sim.scheduleEvent(this, value, -1, true, lastEvent); + } + + /** + * Place this transition on the random queue. + * Does not block. + * Same as scheduleRandom(value, null). + **/ + public void scheduleRandom(byte value) { + scheduleRandom(value, null); + } + + /** + * Calls scheduleRandom(value) if DSim's random + * mode is UNTIMED_RANDOM, otherwise calls + * scheduleDelay. + * Does not block. + **/ + public void scheduleDelayOrRandom(byte value, long delay) { + if (sim.getRandom() == DSim.UNTIMED_RANDOM) + scheduleRandom(value); + else + scheduleDelay(value, delay); + } + + /** + * Calls scheduleRandom(value) if DSim's random + * mode is UNTIMED_RANDOM, otherwise calls + * scheduleTime. + * Does not block. + **/ + public void scheduleTimeOrRandom(byte value, long t, Node lastEvent) { + if (sim.getRandom() == DSim.UNTIMED_RANDOM) + scheduleRandom(value, lastEvent); + else + scheduleTime(value, t, lastEvent); + } + + /** + * Calls scheduleRandom(value) if DSim's random + * mode is UNTIMED_RANDOM, otherwise calls + * scheduleTime. + * Does not block. + * Same as scheduleTimeOrRandom(value, t, null). + **/ + public void scheduleTimeOrRandom(byte value, long t) { + scheduleTimeOrRandom(value, t, null); + } + + /** Another rule is pulling us up or down based on dir. **/ + void bumpCount(int dir) { count[dir]++; } + + /** Another rule may be (undefined) pulling us up or down based on dir. **/ + void bumpUCount(int dir) { uCount[dir]++; } + + /** Another rule stopped pulling us up or down based on dir. **/ + void dropCount(int dir) { count[dir]--; } + + /** Another (undefined) rule stopped pulling us up or down based on dir. **/ + void dropUCount(int dir) { uCount[dir]--; } + + /** + * Set the capacitance of this node. + **/ + public void setCapacitance(final float cap) { + this.capacitance = cap; + } + + /** + * Get the capacitance of this node. + **/ + public float getCapacitance() { + return capacitance; + } + + /** + * Set the output slew rate of this node. + **/ + public void setSlew(final float slew) { + this.output_slew = slew; + } + + /** + * Get the output slew rate of this node. + **/ + public float getSlew() { + return output_slew; + } + + /** + * For each Rule that depends on this Node, calls f with the + * rule, sense, and node. + */ + public void foreachRule(RuleFunc f) { + for (int sense = 0; sense < 2; sense++) + for (int i = 0; i < numRules[sense]; i++) + f.accept(rules[sense][i], sense, this); + } + + public interface RuleFunc { + /** + * User-supplied function passed to foreachRule(). + * @param r one of the Rules that depends on the Node + * @param sense 0 => inverted, 1 => noninverted + * @param n the Node (for convenience; you already know it) + */ + void accept(Rule r, int sense, Node n); + } + + /** + * Set the delay type of this node. + **/ + public void setDelayType(final byte type) { + this.delay_type = type; + } + + /** + * Get the delay type of this node. + **/ + public byte getDelayType() { + return delay_type; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NodeWatcher.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NodeWatcher.java new file mode 100644 index 0000000000..847a9ea4b4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/NodeWatcher.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ +package com.avlsi.tools.dsim; + +import java.util.EventListener; + +/** + * An interface to programatically listens for changes to DSim Nodes. + * + * Used by e.g. the cli part of {@link com.avlsi.util.cmdline.DSimModule} rather than + * embedding "spewing to stdout" in the guts of the Scheduler. + * + * @author Aaron Denney + * @version $Name: $ $Date$ + **/ + +public interface NodeWatcher extends EventListener { + /** Called when an associated node changes. **/ + void nodeChanged(Node node, long time); +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/OutputSlewCheck.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/OutputSlewCheck.java new file mode 100644 index 0000000000..fc9c6f3cd9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/OutputSlewCheck.java @@ -0,0 +1,37 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.util.graph.ShortestPaths; +import com.avlsi.util.graph.Vertex; + +class OutputSlewCheck extends SlewCheck { + private Map slowDelays; + + OutputSlewCheck() { + slowDelays = new HashMap(); + } + + void evaluateSlowPaths(HalfOpGraph circuit, + final Map slews) { + slowDelays.putAll(slews); + } + + double getSlowDelay(Vertex v) { + Double slow = slowDelays.get(v.toString()); + if (slow == null) { + return -1; + } + return slow; + } +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProcessMeasuredDelay.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProcessMeasuredDelay.java new file mode 100644 index 0000000000..816fbdfb9d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProcessMeasuredDelay.java @@ -0,0 +1,517 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +// vim:cin:sw=4:expandtab +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +import java.util.Collection; + +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.NullaryAction; +import com.avlsi.tools.dsim.Node; + +/** + * Functions to process the raw measured_delay data to make it more suitable + * for ASTA. + **/ +class ProcessMeasuredDelay { + /** + * Constrain the derivative to be less than limit. + **/ + static boolean constrainMaxDerivative(final double[] x, + final double[] delay, + final double limit) { + boolean changed = false; + for (int i = x.length - 1; i > 1; --i) { + final double dx = x[i] - x[i - 1]; + final double deriv = (delay[i] - delay[i - 1]) / dx; + if (deriv > limit) { + delay[i - 1] = delay[i] - dx * limit; + changed = true; + } + } + return changed; + } + + /** + * Constrain the derivative to be greater than limit. + **/ + static boolean constrainMinDerivative(final double[] x, + final double[] delay, + final double limit) { + boolean changed = false; + for (int i = 1; i < x.length - 1; ++i) { + final double dx = x[i + 1] - x[i]; + final double deriv = (delay[i + 1] - delay[i]) / dx; + if (deriv < limit) { + delay[i + 1] = delay[i] + dx * limit; + changed = false; + } + } + return changed; + } + + static void printTable(final Pair table, final Node target, + final int dir, final String label) { + final Pair p = (Pair) table.getSecond(); + System.err.println("T|" + ((Node) table.getFirst()).getName() + + (dir > 0 ? '-' : '+') + + " -> " + target.getName() + + (dir > 0 ? '+' : '-')); + printTable((float[]) p.getSecond(), label); + } + + static void printTable(final Pair[] tables, final Node target, + final int dir, final String label) { + for (Pair table : tables) { + printTable(table, target, dir, label); + } + } + + static void printTable(final float[] table, final String label) { + final int size = table.length / 3; + final double[] x = new double[size]; + final double[] delay1 = new double[size]; + final double[] delay2 = new double[size]; + int index = 0; + for (int i = 0; i < size; ++i) { + x[i] = table[index++]; + delay1[i] = table[index++]; + delay2[i] = delay1[i] + table[index++]; + } + printTable(x, delay1, delay2, label); + } + + static void printTable(final double[] x, final double[] delay1, + final double[] delay2, final String label) { + System.err.println("L|" + label); + System.err.printf(" |%7s %7s %6s %7s %6s\n", + "slew", "delay1", "deriv1", "delay2", "deriv2"); + for (int i = 0; i < x.length; ++i) { + double deriv1 = 0, deriv2 = 0; + if (i < x.length - 1) { + deriv1 = (delay1[i + 1] - delay1[i]) / (x[i + 1] - x[i]); + deriv2 = (delay2[i + 1] - delay2[i]) / (x[i + 1] - x[i]); + } + System.err.printf("D|%7.3f %7.3f %6.3f %7.3f %6.3f\n", x[i], + delay1[i], deriv1, delay2[i], deriv2); + } + System.err.println(); + } + + /** + * Print debug information. Does not change any data. + **/ + static class PrintTable implements TableProcessor { + private final String label; + public PrintTable(final String label) { + this.label = label; + } + public Object update(final int model, final Object trigger, + final Object old) { + if (model == Rule.LINEAR_MODEL) { + printTable((float[]) old, label + " " + trigger.toString()); + } + return old; + } + } + + /** + * Correct for discrete data sampling in alint. alint outputs the voltage + * every "post_step" time units. aplot linearly interpolates between + * observed data points. Assume input waveform is exponential to correct + * the aplot measurement. + * + * @param tau time constant + * @param postStep alint .post_step setting + * @param threshold ratio of voltage to true voltage + * @return difference between aplot measured time to reach threshold and + * actual time for input waveform to reach threshold + **/ + private static double postStepCorrection(final double tau, + final double postStep, + final double threshold) { + // find t when voltage actually reaches threshold + // V=Vdd*exp(-t/tau) + // ln(V/Vdd)=-t/tau + // t=-ln(threshold)*tau + final double t = -Math.log(threshold) * tau; + + // find bracketing sampling times + final double nth = Math.floor(t / postStep); + final double tl = postStep * nth; + final double tr = postStep * (nth + 1); + + // find t' when aplot says voltage reaches threshold + // Vl=Vdd*exp(-tl/tau) Vr=Vdd*exp(-tr/tau) + // [Vl+(Vr-Vl)*(t'-tl)/postStep]/Vdd=threshold + // exp(-tl/tau)+[exp(-tr/tau)-exp(-tl/tau)]*(t'-tl)/postStep=threshold + // t'=[threshold-exp(-tl/tau)]*postStep/[exp(-tr/tau)-exp(-tl/tau)]+tl + final double thl = Math.exp(-tl/tau); + final double thr = Math.exp(-tr/tau); + final double t_ = (threshold - thl) * postStep / (thr - thl) + tl; + + return t_ - t; + } + + interface TableProcessor { + Object update(final int model, final Object trigger, final Object old); + } + + static class LinearTableProcessor implements TableProcessor { + public Object update(final int model, final Object trigger, + final Object old) { + if (model == Rule.LINEAR_MODEL) { + final float[] table = (float[]) old; + return update(table); + } else { + return old; + } + } + protected float[] update(final float[] table) { + return table; + } + } + + static Pair[] update(final Pair[] measuredDelay, + final Collection procs) { + for (int i = 0; i < measuredDelay.length; ++i) { + final Object trigger = measuredDelay[i].getFirst(); + final Pair p = (Pair) measuredDelay[i].getSecond(); + final int model = ((Integer) p.getFirst()).intValue(); + final Object oldTable = p.getSecond(); + Object newTable = oldTable; + for (TableProcessor proc : procs) { + newTable = proc.update(model, trigger, newTable); + } + if (oldTable != newTable) { + measuredDelay[i] = + new Pair(trigger, new Pair(model, newTable)); + } + } + return measuredDelay; + } + + static class PostStepCorrection extends LinearTableProcessor { + private final double postStep; + private final double oldth1; + private final double oldth2; + public PostStepCorrection(final double postStep, + final double oldth1, + final double oldth2) { + this.postStep = postStep; + this.oldth1 = oldth1; + this.oldth2 = oldth2; + } + protected float[] update(final float[] table) { + final float[] newTable = new float[table.length]; + for (int j = 0; j < table.length; j += 3) { + final double offset = + postStepCorrection( + table[j] / Math.log(oldth1 / oldth2), + postStep, oldth1); + newTable[j] = table[j]; + newTable[j + 1] = + table[j + 1] + (float) offset; + newTable[j + 2] = table[j + 2]; + } + return newTable; + } + } + + /** + * Fit an exponential function of the form f(t)=exp(-(t-t0)/tau). + * @param t1 f(t1)==th1, t1 < t2 + * @param t2 f(t2)==th2, t2 > t1 + * @param th1 f(t1)==th1 + * @param th2 f(t2)==th2 + * @return { tau, t0 } + **/ + private static double[] fitExponential(final double t1, final double t2, + final double Th1, final double Th2) { + if (t1 >= t2) { + throw new IllegalArgumentException("t1 should be less than t2: " + + t1 + " " + t2); + } + // solve for tau and t0 + // th1 = exp(-(t1-t0)/tau) th2 = exp(-(t2-t0)/tau) + // tau*ln(th1) = t0-t1 tau*ln(th2) = t0-t2 + // tau*[ln(th1)-ln(th2)] = t2-t1 + // tau = (t2-t1)/ln(th1/th2) + final double th1 = Th1 > Th2 ? Th1 : 1 - Th1; + final double th2 = Th1 > Th2 ? Th2 : 1 - Th2; + final double tau = (t2 - t1) / Math.log(th1 / th2); + final double t0 = tau * Math.log(th1) + t1; + return new double[] { tau, t0 }; + } + + private interface Waveform { + /** + * Time at which the specified voltage is reached + **/ + double getTime(final double v); + + /** + * Voltage reached at the specified time + **/ + double getVoltage(final double t); + } + + /** + * A waveform of the form f(t)=exp(-(t-t0)/tau) + **/ + private static class Exponential implements Waveform { + private final double t0; + private final double tau; + public Exponential(final double t0, final double tau) { + this.t0 = t0; + this.tau = tau; + } + public double getTime(final double v) { + return t0 - tau * Math.log(v); + } + public double getVoltage(final double t) { + return Math.exp(-(t - t0) / tau); + } + public String toString() { + return "Exponential(t0=" + t0 + ", tau=" + tau + ")"; + } + } + + /** + * A waveform of the form f(t)=a*t+b + **/ + private static class Linear implements Waveform { + private final double a; + private final double b; + public Linear(final double a, final double b) { + this.a = a; + this.b = b; + } + public double getTime(final double v) { + return (v - b) / a; + } + public double getVoltage(final double t) { + return a * t + b; + } + public String toString() { + return "Linear(a=" + a + ", b=" + b + ")"; + } + } + + /** + * Redo alint measurement at arbitrary thresholds, assuming certain + * waveforms for the input and output. + **/ + private static void measure(final Waveform input, final Waveform output, + final double Th1, final double Th2, + final float[] result, final int index) { + final double th1 = Th1 > Th2 ? Th1 : 1 - Th1; + final double th2 = Th1 > Th2 ? Th2 : 1 - Th2; + + final double t0 = input.getTime(th1); + final double t1 = output.getTime(th1); + final double inputSlew = input.getTime(th2) - t0; + final double outputDelay = t1 - t0; + final double outputSlew = output.getTime(th2) - t1; + result[index] = (float) inputSlew; + result[index + 1] = (float) outputDelay; + result[index + 2] = (float) outputSlew; + } + + /** + * Fit data to waveforms. + **/ + private static Waveform[] getWaveforms(final double inputSlew, + final double outputDelay, + final double outputSlew, + final double Oldth1, + final double Oldth2, + final int d2a_shape) { + final Waveform input, output; + final double oldth1, oldth2; + if (d2a_shape == 0) { // exponential + if (Oldth1 < Oldth2) { + oldth1 = 1 - Oldth1; + oldth2 = 1 - Oldth2; + } else { + oldth1 = Oldth1; + oldth2 = Oldth2; + } + input = new Exponential(0, inputSlew / Math.log(oldth1 / oldth2)); + final double[] coef = + fitExponential(outputDelay, outputDelay + outputSlew, + oldth1, oldth2); + output = new Exponential(coef[1] + input.getTime(oldth1), coef[0]); + } else if (d2a_shape == 1) { // linear + if (Oldth1 < Oldth2) { + oldth1 = 1 - Oldth1; + oldth2 = 1 - Oldth2; + } else { + oldth1 = Oldth1; + oldth2 = Oldth2; + } + input = new Linear((oldth2 - oldth1) / inputSlew, 1); + final double m = (oldth2 - oldth1) / outputSlew; + final double b = oldth1 - m * outputDelay; + output = new Linear(m, b - m * input.getTime(oldth1)); + } else { + throw new RuntimeException("Unsupported d2a_shape: " + d2a_shape); + } + return new Waveform[] { input, output }; + } + + /** + * alint data is measured at certain thresholds. Assume the input and + * output waveforms are known, recompute the data at different thresholds. + * + * @param inputSlew time from input waveform reaching oldth1 to oldth2 + * @param outputDelay time from input waveform reaching oldth1 to output + * waveform reaching oldth1 + * @param ouputSlew time from output waveform reaching oldth1 to output + * waveform reaching oldth2 + * @param oldth1 first threshold used for measuring data + * @param oldth2 second threshold used for measuring data + * @param newth1 first new threshold for data + * @param newth2 second new threshold for data + * @param result table to write new data to + * @param index index in the table to update + * @param d2a_shape shape of input waveform + **/ + private static void shiftThreshold(final double inputSlew, + final double outputDelay, + final double outputSlew, + final double oldth1, + final double oldth2, + final double newTh1, + final double newTh2, + final float[] result, + final int index, + final int d2a_shape) { + final Waveform[] waves = + getWaveforms(inputSlew, outputDelay, outputSlew, oldth1, oldth2, + d2a_shape); + measure(waves[0], waves[1], newTh1, newTh2, result, index); + } + + /** + * Shift thresholds from oldth1..oldth2 to newth1..newth2, given the input + * wave form has the specified shape (corresponds to the setting of + * .d2a_shape in alint.) + **/ + static class ShiftThreshold extends LinearTableProcessor { + private final double oldth1; + private final double oldth2; + private final double newth1; + private final double newth2; + private final int shape; + public ShiftThreshold(final double oldth1, final double oldth2, + final double newth1, final double newth2, + final int shape) { + this.oldth1 = oldth1; + this.oldth2 = oldth2; + this.newth1 = newth1; + this.newth2 = newth2; + this.shape = shape; + } + + protected float[] update(final float[] table) { + final float[] newTable = new float[table.length]; + for (int j = 0; j < table.length; j += 3) { + shiftThreshold(table[j], table[j + 1], table[j + 2], + oldth1, oldth2, newth1, newth2, + newTable, j, shape); + } + return newTable; + } + } + + /** + * Scales delay by the given scale factor. + **/ + static class ScaleDelay implements TableProcessor { + private final double delayScale; + public ScaleDelay(final double delayScale) { + this.delayScale = delayScale; + } + public Object update(final int model, final Object trigger, + final Object old) { + if (model == Rule.LINEAR_MODEL) { + final float[] table = (float[]) old; + final float[] newTable = new float[table.length]; + for (int j = 0; j < table.length; j += 3) { + newTable[j] = table[j]; + newTable[j + 1] = (float) (table[j + 1] * delayScale); + newTable[j + 2] = table[j + 2]; + } + return newTable; + } else if (model == Rule.POLYNOMIAL_MODEL) { + final Pair p = (Pair) old; + final float[] delayCoeff = (float[]) p.getFirst(); + final float[] newCoeff = new float[delayCoeff.length]; + for (int j = 0; j < delayCoeff.length; ++j) { + newCoeff[j] = (float) (delayCoeff[j] * delayScale); + } + return new Pair(newCoeff, p.getSecond()); + } else { + return old; + } + } + } + + /** + * Workaround for bug 19653: remove datapoints with 0 output delay/slew. + **/ + static class RemoveZeroData implements TableProcessor { + private final NullaryAction notifier; + public RemoveZeroData(final NullaryAction notifier) { + this.notifier = notifier; + } + private final boolean isZero(final float[] table, final int idx) { + return table[idx + 1] == 0 || table[idx + 2] == 0; + } + public Object update(final int model, final Object trigger, + final Object old) { + if (model == Rule.LINEAR_MODEL) { + final float[] table = (float[]) old; + + // scan for entries to eliminate, and notify + int count = 0; + for (int j = 0; j < table.length; j += 3) { + if (isZero(table, j)) { + count++; + notifier.execute(); + } + } + + // return old table if no changes needed + if (count == 0) return old; + + // construct new table + final float[] newTable = new float[table.length - 3 * count]; + int i = 0; + for (int j = 0; j < table.length; j += 3) { + if (!isZero(table, j)) { + newTable[i] = table[j]; + newTable[i + 1] = table[j + 1]; + newTable[i + 2] = table[j + 2]; + i += 3; + } + } + return newTable; + } else { + return old; + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProgressMeter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProgressMeter.java new file mode 100644 index 0000000000..b32fddf34b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/ProgressMeter.java @@ -0,0 +1,77 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.io.PrintStream; + +import EDU.oswego.cs.dl.util.concurrent.BrokenBarrierException; +import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier; +import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean; +import EDU.oswego.cs.dl.util.concurrent.TimeoutException; + +/** + * Spinner to indicate progress. Cycles through / | - \. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +final class ProgressMeter { + + private final PrintStream writer; + private final CyclicBarrier barrier; + private SpinnerRunner runner = null; + + private static final char[] SPIN_CHARS = new char[]{'-', '\\', '|', '/'}; + + ProgressMeter(final PrintStream writer) { + this.writer = writer; + this.barrier = new CyclicBarrier(2); + } + + public void startSpinning() { + assert runner == null; + runner = new SpinnerRunner(); + runner.start(); + } + + public void stopSpinning() { + try { + assert runner != null; + runner.done.set(true); + barrier.barrier(); + runner = null; + } catch (InterruptedException e) { + throw new AssertionError(e); + } catch (BrokenBarrierException e) { + throw new AssertionError(e); + } + } + + private final class SpinnerRunner extends Thread { + private final SynchronizedBoolean done = + new SynchronizedBoolean(false); + + public void run() { + try { + int i = 0; + while (!done.get()) { + writer.print(SPIN_CHARS[i]); + writer.flush(); + Thread.sleep(250); + writer.print((char) 0x8); // ^h + i = (i + 1) % SPIN_CHARS.length; + } + barrier.barrier(); + } catch (InterruptedException e) { + throw new AssertionError(e); + } catch (BrokenBarrierException e) { + throw new AssertionError(e); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RandomEventQueue.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RandomEventQueue.java new file mode 100644 index 0000000000..4f1bd95455 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RandomEventQueue.java @@ -0,0 +1,168 @@ +/* + * Copyright 2000, 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +// vim:cin:sw=4:expandtab + +package com.avlsi.tools.dsim; + +import com.avlsi.util.debug.Debug; +import com.avlsi.tools.dsim.Node; + +import java.util.ArrayList; +import java.util.NoSuchElementException; +import java.util.List; +import java.util.Random; + +/** + *

    A queue of events that fire at random.

    + * + * @author tim + * @author Aaron Denney + * @version $Revision$ $Date$ + **/ + +public class RandomEventQueue implements EventQueueInterface { + + // Attributes + + /** Actual vector */ + private final List victor; + /** number of elements */ + private int elementCount = 0; + /** looked at front of queue */ + private Event top = null; + /** Random number source. */ + private final Random r; + + // Constructors + + /** Class constructor. Creates an empty random queue. **/ + public RandomEventQueue() { this(new Random()); } + + /** + * Class constructor. Creates an empty random queue with random number + * generator r. + * @param r the random number gererator to use for this queue. + **/ + public RandomEventQueue(Random r) { this(r, new ArrayList()); } + + /** + * Class constructor. Creates an empty random queue with random number + * generator r. + * @param r the random number gererator to use for this queue. + * @param l the list used to store events + **/ + public RandomEventQueue(Random r, List l) { + this.r = r; + this.victor = l; + } + + // Public Methods + + /** Returns a string list of all the queued Events. Mainly for debugging. **/ + public String pendingList() { + String ret = ""; + for (int i=0; iexchange
    , such that the vector only has to shrink at the + * end. + * + * @throws NoSuchElementException + **/ + private void exchangeAndPopRandom() { + Debug.assertTrue(top==null); + if (elementCount <=0) { throw new NoSuchElementException(); } + int randIndex = r.nextInt(elementCount); + exchange(randIndex,elementCount-1); + top = victor.remove(elementCount-1); + top.setIndex(victor.size()); + } + + /** + * Remove the object at the front of the queue, and return it. + * + * @throws NoSuchElementException + **/ + public Event next() { + if (top == null) { exchangeAndPopRandom(); } + Event rv = top; + top.setIndex(-1); + top = null; + elementCount--; + return rv; + } + + /** + * Return the object at the front of the queue, without removing it. + * + * @throws NoSuchElementException + **/ + public Event front() { + if (top == null) { exchangeAndPopRandom(); } + return top; + } + + /** Remove a specified event from the queue. */ + public void remove(Event e) { + int index = e.getIndex(), len = victor.size()-1; + if (top==e) { next(); } + else if (index>=0 && victor.get(index)==e) { + exchange(index, len); + victor.remove(len); + e.setIndex(-1); + elementCount--; + } else { throw new NoSuchElementException("Event not in RandomEventQueue"); } + } + + /** Tells whether the queue is empty. **/ + public boolean isEmpty() { return elementCount == 0; } + + /** Returns the number of elements in the queue. **/ + public int size() { return elementCount; } + + // Private Methods + + /** Swaps two events in the queue and updates their index. **/ + private void exchange(int i, int j) { + Debug.assertTrue(i < elementCount); + Debug.assertTrue(j < elementCount); + Event swapi = victor.get(i); + Event swapj = victor.get(j); + victor.set(i, swapj); + victor.set(j, swapi); + swapi.setIndex(j); + swapj.setIndex(i); + } + +} // end of class RandomEventQueue + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Resetable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Resetable.java new file mode 100644 index 0000000000..8643a54095 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Resetable.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +/** + * Class for ... + * + * @author Aaron Denney + * @version $Date$ + **/ + +interface Resetable { + void resetStart(); + void resetStop(); +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Rule.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Rule.java new file mode 100644 index 0000000000..0cc97722e8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/Rule.java @@ -0,0 +1,555 @@ +/* + * Copyright 2002, 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +// vim:cin:sw=4:expandtab +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +import java.util.ArrayList; +import java.util.NoSuchElementException; +import java.util.Set; + +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.math.QuadraticInterpolation; +import com.avlsi.tools.dsim.Node; + +/** + * Rule class. + * + * Representation of rule in DNF (OR of ANDS.) + * This just keeps track of the number of conjuncts. + * The Disjuncts are represented in {@link Node} in the + * count, uCount arrays. + *

    + * Not terribly clear but each rule can either pull a node up or down. + * To trigger a rule, it must have no false conjuncts, or unknown conjuncts. + * i.e. All of its conjuncts must be nodes satisfying the test. + * + * @author Aaron Denney + * @version $Name: $ $Date$ + **/ +public final class Rule { + static final byte RULE_OFF = 0, RULE_ON = 1, RULE_U = 2; + public static final int INVALID_MODEL = -1, LINEAR_MODEL = 0, + POLYNOMIAL_MODEL = 1; + + public static final byte MUST_BE_COVERED = 0, + IGNORE_COVERAGE = 1, + MUST_NOT_BE_COVERED = 2; + + int delay; + final byte delay_type; + final int dir; + final Node target; + private static final Pair[] NO_DATA = new Pair[0]; + private ArrayList measuredDelay = null; + + // for debugging + //final Node[] guards; + //final int[] sense; + //int totalConjuncts = 0; + + /** + * Beware: some of the fields are used by ASTA for different purposes: + * falseConjuncts - stores instance count of a grayboxed rule + * transitionCount - stores the index into the table of interpolations + **/ + + int falseConjuncts = 0; + int unknownConjuncts = 0; + byte oldState, newState; + + /** For rule coverage */ + public int transitionCount = 0; + public final byte coverageRequirement; + + /** + * Used for timing assumptions in synchronous circuitry. Behaves + * like TIMED_RANDOM even in UNTIMED_RANDOM simulations. + **/ + final boolean timed; + + /** + * Used for timing assumptions in asynchronous circuitry, fires + * before any other rules only in UNTIMED_RANDOM simulations. + **/ + final boolean isochronic; + + /** + * Used for generating clock sources. The specified delay is used + * regardless of which random mode is selected. + **/ + final boolean absoluteDelay; + + /** + * Used for error checking. An asserted rule should be excluded from + * coverage and ASTA considerations. + **/ + final boolean asserted; + + /*@ + @ instance invariant +// @ guards != null +// @ && (\forall int i; +// @ 0 <= i && i < guards.length; +// @ guards[i] != null) +// @ && + @ falseConjuncts >= 0 + @ && unknownConjuncts >= 0 + @ && target != null + @ && oldState >= RULE_OFF && oldState <= RULE_U + @ && newState >= RULE_OFF && newState <= RULE_U + @ && delay >= 0 + @ && (dir == 0 || dir == 1); + @*/ + + /** + * If true, use measure delay for this rule, if available. + * Otherwise, do not use measure delay. + **/ + boolean measureDelayOn; + + /** + * Instance name of the cell that contains this production rule. + **/ + final HierName prefix; + + /** + * The canonical rule if ASTA grayboxing is enabled. + **/ + private Rule canonRule; + + /** Converts just the PRS rule itself to a string. **/ + public String toPrettyString () { + DSim sim = DSim.get(); + StringBuffer ret = new StringBuffer(); + boolean pastFirst = false; + for (Node n : sim.getTargetingNodes(this)) { + int sense = n.getSense(this); + if (pastFirst) { ret.append(" & "); } + if (sense==0) { ret.append('~'); } + ret.append(n.getName()); + pastFirst=true; + } + ret.append(" -> "); + ret.append(target.getName()); + ret.append(dir>0?'+':'-'); + return ret.toString(); + } + + /** Returns a list of Node names that affect us with '~' to indicate direction **/ + public String getGuardList() { + String ret = toPrettyString(); + ret = ret+" ("+Node.getNameForValue(oldState)+"->"+Node.getNameForValue(newState) + +", "+unknownConjuncts+"U, "+falseConjuncts+"F)"; + return ret; + } + + public void addMeasured(final Pair[] data, final int which) { + if (measuredDelay == null) { + measuredDelay = new ArrayList(1); + } + for (int i = measuredDelay.size(); i <= which; ++i) { + measuredDelay.add(NO_DATA); + } + measuredDelay.set(which, data); + } + + private boolean hasMeasured() { + return measuredDelay != null; + } + + private Pair[] getMeasured(int index) { + if (hasMeasured() && index < measuredDelay.size()) { + return measuredDelay.get(index); + } else { + return NO_DATA; + } + } + + /** + * Class constructor. Creates a Rule to trigger the target node. + * + *

    
    +     *   public normal_behavior
    +     *     requires guards != null
    +     *           && (\forall int i; 0 <= i && i < guards.length;
    +     *                       guards[i] != null)
    +     *           && sense != null
    +     *           && (\forall int i; 0 <= i && i < sense.length;
    +     *                       sense[i] == 0 || sense[i] == 1)
    +     *           && guards.length == sense.length
    +     *           && target != null
    +     *           && (dir == 0 || dir == 1)
    +     *           && delay >= 0;
    +     * 
    + **/ + public Rule(Node[] guards, int[] sense, Node target, int dir, int delay, + byte delay_type, boolean timed, boolean isochronic, + boolean absoluteDelay, boolean asserted, Pair[] measuredDelay, + byte coverageRequirement, HierName prefix) { + Debug.assertTrue(guards.length == sense.length); + int guardCount = guards.length; + this.dir = dir; + this.delay = delay; + this.delay_type = delay_type; + this.target = target; + this.timed = timed; + this.isochronic = isochronic; + this.absoluteDelay = absoluteDelay; + this.asserted = asserted; + if (measuredDelay != null) addMeasured(measuredDelay, 0); + this.coverageRequirement = coverageRequirement; + this.prefix = prefix; + this.measureDelayOn = true; + // next few lines are for debuging + //this.totalConjuncts = guardCount; + //this.guards = guards; + //this.sense = sense; + //target.notifyTarget(this); + + for (int i = 0; i < guardCount; i++) { + guards[i].addRule(this, sense[i]); + int value = guards[i].getValue(); + if (value == Node.VALUE_U) { + unknownConjuncts++; + } else if (value != sense[i]) { + falseConjuncts++; + } + } + + oldState = RULE_OFF; + updateNewState(); + updateTargetCounts(); + + if (modified()) { + fireRule(null); + } + } + /** Did our state change? **/ + public /*@ pure @*/ boolean modified() { + return oldState != newState; + } + + public Rule getCanonRule() { + return canonRule; + } + + public void setCanonRule(final Rule canonRule) { + this.canonRule = canonRule; + } + + /** + * Notify target Node that our state has changed. + * + *
    
    +     *   public normal_behavior
    +     *     requires modified();
    +     * 
    + **/ + public void fireRule(Node lastEvent) { + Debug.assertTrue(modified()); + final int wait; + final float slew; + final byte type; + final float fallbackSlew = + lastEvent == null ? target.getSlew() : lastEvent.getSlew(); + if (!measureDelayOn || !hasMeasured()) { + type = delay_type; + wait = delay; + slew = fallbackSlew; + } else { + float[] measured = new float[] { delay, fallbackSlew }; + type = getMeasured(lastEvent, measured) ? DSim.MEASURED_TAU + : delay_type; + wait = Math.round(measured[0]); + slew = measured[1]; + } + + if (coverageRequirement == MUST_NOT_BE_COVERED && + newState == RULE_ON && transitionCount == 0) + System.out.println("Supposedly unused rule fired: " + + toPrettyString()); + + // only count transitions between the on and off states + if (oldState != RULE_U && newState != RULE_U) + transitionCount++; + + target.ruleFired(wait, slew, type, oldState, newState, lastEvent, this); + } + /** calcuate old state. **/ + public void updateOldState() { + if (falseConjuncts>0) { oldState=RULE_OFF; } + else if (unknownConjuncts>0) { oldState=RULE_U; } + else { oldState=RULE_ON; } + } + /** Calculate our new state after update **/ + public void updateNewState() { + if (falseConjuncts>0) { newState=RULE_OFF; } + else if (unknownConjuncts>0) { newState=RULE_U; } + else { newState=RULE_ON; } + } + /** Remove last adjustement from target Node, so we can recalculate state. **/ + void reverseTransitions() { + //if ((falseConjuncts==0)&&(unknownConjuncts==0)) target.dropCount(dir); + //else if ((falseConjuncts==0)&&(unknownConjuncts>0)) target.dropUCount(dir); + if (falseConjuncts==0) { + if (unknownConjuncts==0) target.dropCount(dir); + else target.dropUCount(dir); + } + } + /** Adjust taget node for current state. **/ + void updateTargetCounts() { + //if ((falseConjuncts==0)&&(unknownConjuncts==0)) target.bumpCount(dir); + //else if ((falseConjuncts==0)&&(unknownConjuncts>0)) target.bumpUCount(dir); + if (falseConjuncts==0) { + if (unknownConjuncts==0) target.bumpCount(dir); + else target.bumpUCount(dir); + } + } + /** Verify that the state of the Rule is consistent with expectations. **/ + void verify() { + Debug.assertTrue(falseConjuncts >= 0); + Debug.assertTrue(unknownConjuncts >= 0); + Debug.assertTrue(target != null); + Debug.assertTrue(oldState >= RULE_OFF && oldState <= RULE_U); + Debug.assertTrue(newState >= RULE_OFF && newState <= RULE_U); + Debug.assertTrue(delay >= 0); + } + + /** simple accessor, return target **/ + public Node target(){return target; } + + boolean getMeasured(final Node last, final float[] result) { + if (!this.hasMeasured() || this.measuredDelay.isEmpty() || + last == null) return false; + final Pair[] measuredDelay = getMeasured(0); + for (int i = 0; i < measuredDelay.length; ++i) { + final Object trigger = measuredDelay[i].getFirst(); + if (trigger == null || trigger.equals(last)) { + final Pair p = (Pair) measuredDelay[i].getSecond(); + final int model = ((Integer) p.getFirst()).intValue(); + final Object data = p.getSecond(); + if (model == LINEAR_MODEL) { + linearInterpolate((float[]) data, last.getSlew(), result, + last); + } else if (model == POLYNOMIAL_MODEL) { + final Pair coeffs = (Pair) data; + polynomialInterpolate((float[]) coeffs.getFirst(), + (float[]) coeffs.getSecond(), + last.getSlew(), result); + } + return true; + } + } + return false; + } + + static QuadraticInterpolation[] getInterpolation( + final Pair[] measuredDelay, final Node last, final Node target, + int dir, double alpha, double minDeriv, double maxDeriv) { + if (measuredDelay != null) { + for (int i = 0; i < measuredDelay.length; ++i) { + final Object trigger = measuredDelay[i].getFirst(); + if (trigger == null || trigger.equals(last)) { + final Pair p = (Pair) measuredDelay[i].getSecond(); + final int model = ((Integer) p.getFirst()).intValue(); + final float[] table = (float[]) p.getSecond(); + if (model == LINEAR_MODEL) { + final int size = table.length / 3; + final double[] x = new double[size + 1]; + final double[] delay1 = new double[size + 1]; + final double[] delay2 = new double[size + 1]; + int index = 0; + for (int j = 1; j < size + 1; ++j) { + x[j] = table[index++]; + delay1[j] = table[index++] / 100; + delay2[j] = delay1[j] + table[index++]; + } + + // constrain the derivative of delay1 or delay2 + boolean violated = false; + if (!Double.isNaN(maxDeriv)) { + violated |= + ProcessMeasuredDelay.constrainMaxDerivative( + x, delay1, maxDeriv); + violated |= + ProcessMeasuredDelay.constrainMaxDerivative( + x, delay2, maxDeriv); + } + if (!Double.isNaN(minDeriv)) { + violated |= + ProcessMeasuredDelay.constrainMinDerivative( + x, delay1, minDeriv); + violated |= + ProcessMeasuredDelay.constrainMinDerivative( + x, delay2, minDeriv); + } + + if (violated) { + ProcessMeasuredDelay.printTable( + x, delay1, delay2, + "derivative limit constrained " + + last.getName() + (dir > 0 ? '-' : '+') + + " -> " + target.getName() + + (dir > 0 ? '+' : '-')); + } + + // Add an additional data point to constrain + // extrapolation + x[0] = 0; + delay1[0] = delay1[1]; + delay2[0] = delay2[1]; + + return + new QuadraticInterpolation[] { + new QuadraticInterpolation(x, delay1, alpha), + new QuadraticInterpolation(x, delay2, alpha) + }; + } else if (model == POLYNOMIAL_MODEL) { + throw new RuntimeException( + "Polynomial model not supported"); + } + } + } + } + return null; + } + + QuadraticInterpolation[] getInterpolation(final Node last, double alpha, + double minDeriv, double maxDeriv, + final int which) + { + try { + return getInterpolation(getMeasured(which), last, target, dir, + alpha, minDeriv, maxDeriv); + } catch (RuntimeException e) { + throw new RuntimeException( + "Polynomial model not supported: " + prefix + "/" + + toPrettyString(), e); + } + } + + private void warnSlew(final Node last, final String s) { + DSim.get().ui_out_verbose( + "Slew interpolation warning:\n" + last.getName() + " -> " + + target.getName() + (dir > 0 ? "+" : "-") + " " + s + "\n"); + } + + private void polynomialInterpolate(final float[] delayCoeff, + final float[] slewCoeff, + final float input, + final float[] result) { + result[0] = delayCoeff[0]; + result[1] = slewCoeff[0]; + final int small, index; + final float[] big; + if (delayCoeff.length < slewCoeff.length) { + small = delayCoeff.length; + big = slewCoeff; + index = 1; + } else { + small = slewCoeff.length; + big = delayCoeff; + index = 0; + } + float powers = input; + for (int i = 1; i < small; ++i, powers *= input) { + result[0] += delayCoeff[i] * powers; + result[1] += slewCoeff[i] * powers; + } + for (int i = small; i < big.length; ++i, powers *= input) { + result[index] += big[i] * powers; + } + } + + private void linearInterpolate(final float[] table, final float input, + final float[] result, final Node last) { + final int l = table.length; + assert l > 0 && l % 3 == 0; + + if (l == 3) { + result[0] = table[1]; + result[1] = table[2]; + } else { + int index = -1; + if (input < table[0]) { + index = 0; + if (DSim.get().getVerbose()) + warnSlew(last, "(" + input + " < " + table[0] + ")"); + } else if (input > table[l - 3]) { + index = l - 6; + if (DSim.get().getVerbose()) + warnSlew(last, "(" + input + " > " + table[l - 3] + ")"); + } else { + for (int i = 0; i < l - 3; i += 3) { + if (input >= table[i] && input <= table[i + 3]) { + index = i; + break; + } + } + } + + assert index >= 0; + + final float scale = + (input - table[index]) / (table[index + 3] - table[index]); + + final float y1 = table[index + 1], y2 = table[index + 4], + z1 = table[index + 2], z2 = table[index + 5]; + result[0] = y1 == y2 ? y1 : y1 + (y2 - y1) * scale; + result[1] = z1 == z2 ? z1 : z1 + (z2 - z1) * scale; + } + } + + public char getDirection() { + return (dir>0 ? '+' : '-'); + } + + public void setMeasureStatus(final boolean on) { + measureDelayOn = on; + } + + public boolean getMeasureStatus() { + return measureDelayOn; + } + + public int setDelay(final int newDelay) { + final int oldDelay = delay; + delay = newDelay; + return oldDelay; + } + + public int getDelay() { + return delay; + } + + public String toString() { + Set guards = DSim.get().getTargetingNodes(this); + return "Dsim rule(" + + "delay=" + delay + + ", direction=" + dir + + ", target=" + target + + ", guards=" + guards + + ", falseConjuncts=" + falseConjuncts + + ", unknownConjuncts=" + unknownConjuncts + + // enable for debugging + // ", totalConjuncts=" + totalConjuncts + + ", oldState=" + oldState + + ", newState=" + newState + + ", timed=" + timed + + ", isochronic=" + isochronic + + ")"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunSlewChecks.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunSlewChecks.java new file mode 100644 index 0000000000..57e584a191 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunSlewChecks.java @@ -0,0 +1,94 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.PrintWriter; + +public class RunSlewChecks { + final SlewChecker checker; + + public RunSlewChecks(final DSim dsim) { + checker = new SlewChecker(dsim); + } + + public void setSlowSlews(final double slew) { + checker.setSlowSlews(slew); + } + + public void setFastSlews(final double slew) { + checker.setFastSlews(slew); + } + + public void saveSlowSlews(final ObjectOutputStream oos) { + checker.saveSlowSlews(oos); + } + + public void saveFastSlews(final ObjectOutputStream oos) { + checker.saveFastSlews(oos); + } + + public void readFastSlews(final ObjectInputStream ois) { + checker.readFastSlews(ois); + } + + public void readSlowSlews(final ObjectInputStream ois) { + checker.readSlowSlews(ois); + } + + public void computeSlowSlews(final double inputSlew) { + checker.computeSlowSlews(inputSlew); + } + + public void computeFastSlews(final double inputSlew) { + checker.computeFastSlews(inputSlew); + } + + public void evaluate(final double absMargin, + final double multMargin) { + + checker.evaluate(absMargin, multMargin, false); + } + + public void getReport(final PrintWriter pwOutSlew, + final PrintWriter pwIOSlew, + final PrintWriter pwStatSlew, + final PrintWriter pwAll) { + getReport(pwOutSlew, pwIOSlew, pwStatSlew, pwAll, false); + } + + public void getReport(final PrintWriter pwOutSlew, + final PrintWriter pwIOSlew, + final PrintWriter pwStatSlew, + final PrintWriter pwAll, + final boolean reportVictimsOnce) { + if (checker != null) { + checker.printViolations(pwOutSlew, pwIOSlew, pwStatSlew, pwAll, + reportVictimsOnce); + pwOutSlew.flush(); + pwIOSlew.flush(); + pwStatSlew.flush(); + } + } + + public void reportSlowSlews(final PrintWriter pw) { + if (checker != null) { + checker.printSlowSlews(pw); + pw.flush(); + } + } + + public void reportFastSlews(final PrintWriter pw) { + if (checker != null) { + checker.printFastSlews(pw); + pw.flush(); + } + } +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunStaticTiming.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunStaticTiming.java new file mode 100644 index 0000000000..7dc07f594e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/RunStaticTiming.java @@ -0,0 +1,1805 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +// vim:sw=4:expandtab:ai:cin:ts=4 + +package com.avlsi.tools.dsim; + +import java.lang.reflect.Constructor; +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.jauto.ConjugateGradientSolver; +import com.avlsi.tools.dsim.DSim.MeasuredDelay; +import com.avlsi.util.container.BoundedSet; +import com.avlsi.util.container.IterableIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.MutableDouble; +import com.avlsi.util.container.MutableInt; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.math.QuadraticInterpolation; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.StringUtil; + +public class RunStaticTiming { + private static final double EPSILON = 1e-12; + + public static class SolverException extends RuntimeException { + public SolverException(final String mesg, final Throwable cause) { + super(mesg, cause); + } + } + + private static boolean isErrorRule(final Rule r) { + return r.asserted; + } + + private static class AmplSolver { + private Map nodesMap; + private Set observableNodes; + private int constraints; + + private String getVarName(Node n, int dir) { + if (observableNodes.contains(n)) { + return "0"; + } else { + final Integer idx = nodesMap.get(n); + final String prefix = dir > 0 ? "up" : "dn"; + return prefix + idx; + } + } + + private void addVar(Node n) { + if (!observableNodes.contains(n)) { + final Integer idx = nodesMap.get(n); + if (idx == null) nodesMap.put(n, nodesMap.size()); + } + } + + public AmplSolver(final DSim dsim, + final float defaultSlew, + final Set observableNodes) + throws FileNotFoundException { + this.nodesMap = new HashMap(); + this.observableNodes = observableNodes; + this.constraints = 0; + + final PrintStream mod = new PrintStream("asta.mod"); + final PrintStream cmd = new PrintStream("asta.cmd"); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + addVar(n); + addVar(r.target()); + } + }); + for (String prefix : new String[] { "up", "dn" }) { + for (Integer idx : nodesMap.values()) { + String id = prefix + idx; + mod.println("var " + id + ";"); + cmd.println("printf '" + id + " = %g\\n', " + id + ";"); + } + } + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + final String guard = getVarName(n, sense); + final String target = getVarName(r.target(), r.dir); + if (guard.equals("0") && target.equals("0")) return; + + final String constraint = "c" + constraints; + final float[] delaySlew = new float[] { r.delay, 0 }; + n.setSlew(defaultSlew); + r.getMeasured(n, delaySlew); + mod.print("/* " + n.getName() + " -> " + r.target().getName() + + " " + r.delay + " " + delaySlew[0] + " */\n"); + mod.print("subject to " + constraint + ": " + + target + " - " + guard + " + " + + (r.delay - delaySlew[0]) + " >= 0;\n"); + ++constraints; + } + }); + boolean first = true; + for (String prefix : new String[] { "up", "dn" }) { + for (Integer idx : nodesMap.values()) { + if (first) { + mod.print("minimize obj: "); + first = false; + } else { + mod.print(" + "); + } + String id = prefix + idx; + mod.print(id + "**2"); + } + } + mod.println(";"); + mod.close(); + cmd.close(); + } + } + + private static HierName toHier(final String s) { + try { + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName: " + s); + } + } + + private static class Offset { + public final double[] times; + public Offset() { + times = new double[4]; + set(true, true, Double.NEGATIVE_INFINITY); + set(false, true, Double.NEGATIVE_INFINITY); + set(true, false, Double.POSITIVE_INFINITY); + set(false, false, Double.POSITIVE_INFINITY); + } + private final int index(boolean T1, boolean input) { + return (T1 ? 2 : 0) + (input ? 1: 0); + } + public double get(boolean T1, boolean input) { + return times[index(T1, input)]; + } + public void set(boolean T1, boolean input, double value) { + times[index(T1, input)] = value; + } + public void update(boolean T1, double value) { + set(T1, true, Math.max(get(T1, true), value)); + set(T1, false, Math.min(get(T1, false), value)); + } + public void updateIfUnset(boolean T1, double value) { + final double input = get(T1, true); + final double output = get(T1, false); + if (Double.isInfinite(input) || Double.isInfinite(output)) { + update(T1, value); + } + } + } + + private static class CGSolver + implements ConjugateGradientSolver.Function, + ConjugateGradientSolver.StopCondition { + /** A parameter to tune the quadratic interpolation. **/ + private double alpha = 0.5; + private double minDeriv = Double.NaN; + private double maxDeriv = Double.NaN; + private double tolerance = 1e-3; + + /** Parameters related to the solver.**/ + private static final double MIN_GRADIENT = 1e-20; + private static final double MIN_GRAD_MAG = MIN_GRADIENT * MIN_GRADIENT; + + private static final int UNINIT_INDEX = -1; + + /** Offset of the first time variable (time at 1/3) in the arrray. **/ + private final int T1; + + /** Offset of the second time variable (time at 2/3) in the array. **/ + private final int T2; + + private final int OUTPUT = 0; + private final int INPUT = 1; + + private final DSim dsim; + private final ArrayList fixed = new ArrayList(); + private float tau; + final float defaultSlew; + private int iterations = 0; + private int max_iterations; + private final ArrayList> interpols = + new ArrayList>(); + private double[] X; + private int constraintCount; + private int varCount = 0; + + /** Time limit on the solver, in milliseconds since the Unix epoch. **/ + private long endTime = Long.MAX_VALUE; + + /** Multithread support **/ + private Workers energyWorkers = null; + private Workers gradientWorkers = null; + + private Map measureSelected = + new IdentityHashMap(); + + private class Workers implements Iterable { + final CyclicBarrier barrier; + final ArrayList workers; + final String name; + public Workers(final Class c, final int count, + final String name, final Node[][] assignment) { + this.name = name; + barrier = new CyclicBarrier(count + 1); + workers = new ArrayList(count); + try { + final Constructor ctor = + c.getConstructor(CGSolver.class, + CyclicBarrier.class, + (new Node[0]).getClass()); + for (int id = 0; id < count; ++id) { + workers.add( + ctor.newInstance(CGSolver.this, barrier, + assignment[id])); + } + } catch (Exception e) { + throw new RuntimeException("Cannot start workers", e); + } + } + public void start() { + int i = 0; + for (T worker : workers) { + new Thread(worker, name + " " + i).start(); + i++; + } + } + public Iterator iterator() { + return workers.iterator(); + } + } + + private abstract class Worker implements Runnable { + private final CyclicBarrier barrier; + private final Node[] assignment; + public Worker(final CyclicBarrier barrier, + final Node[] assignment) { + this.barrier = barrier; + this.assignment = assignment; + } + public void run() { + while (true) { + try { + barrier.await(); + for (Node n : assignment) { + if (n != null) runTask(n); + } + barrier.await(); + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + protected abstract void runTask(final Node n); + } + + + public int getSize() { + return varCount; + } + + private final boolean isFixed(final Node n) { + return n.isRandom(); + } + + private final void setFixed(final Node n) { + n.setRandom(true); + } + + private final void setUnfixed(final Node n) { + n.setRandom(false); + } + + private final Node canon(final Node n) { + return n.enabler == null ? n : (Node) n.enabler; + } + + private void addVar(final Node n, int sense) { + if (!isFixed(n)) { + if (n.getTCount() == UNINIT_INDEX) { + final Node canon = (Node) n.enabler; + if (canon == null || canon == n) { + n.setTCount(varCount); + varCount += 2; + } else { + addVar(canon, sense); + n.setTCount(canon.getTCount()); + } + } + } + } + + private final int getIndex(final Node n, final int sense) { + return n.getTCount() + sense; + } + + private final int getIndex(final Node n, final int sense, + final int t12) { + return getIndex(n, sense) + t12; + } + + private final double getVar(double[] v, Node n, int sense, int t12, + int input) { + if (isFixed(n)) { + return fixed.get(getIndex(n, sense)) + .get(t12 == T1, input == INPUT); + } else { + return v[getIndex(n, sense, t12)]; + } + } + + // return the budgeted time for the production rule in pS + private final float getBudget(Rule r) { + return Math.max(1, r.delay) * tau / 100; + } + + private final void accumVar(double[] accum, Node n, int sense, int t12, + double val) { + if (!isFixed(n)) { + accum[getIndex(n, sense, t12)] += val; + } + } + + private String strRule(double[] v, Rule r, int sense, boolean rep, + Node n) { + final String detail; + if (v == null) { + if (rep && r.falseConjuncts > 1) { + detail = " x" + r.falseConjuncts; + } else { + detail = ""; + } + } else { + final double it1 = getVar(v, n, sense, T1, INPUT); + final double it2 = getVar(v, n, sense, T2, INPUT); + final double ot1 = getVar(v, r.target(), r.dir, T1, OUTPUT); + final double ot2 = getVar(v, r.target(), r.dir, T2, OUTPUT); + final double islew = it2 - it1; + final double oslew = ot2 - ot1; + detail = " it1=" + it1 + + " it2=" + it2 + + " islew=" + islew + + " budget=" + getBudget(r) + + " delay1=" + getDelay(r, n, islew, T1) + + " delay2=" + getDelay(r, n, islew, T2) + + " ot1=" + ot1 + + " ot2=" + ot2 + + " oslew=" + oslew + + " count=" + r.falseConjuncts; + } + return n.getName() + (sense > 0 ? "+" : "-") + " -> " + + r.target().getName() + r.getDirection() + detail; + } + + private QuadraticInterpolation[] getInterpolation(final Rule r, + final Node n) { + if (r.transitionCount == UNINIT_INDEX) { + return null; + } else { + final Map ruleMap = + interpols.get(r.transitionCount); + return ruleMap.get(canon(n)); + } + } + + private final double getDelay(final Rule r, + final Node n, + final double slew, + final int ot12) { + final QuadraticInterpolation[] qi = getInterpolation(r, n); + if (qi == null) { + return getBudget(r); + } else { + return qi[ot12 == T1 ? 0 : 1].value(slew); + } + } + + private final double getDelayGradient(final Rule r, + final Node n, + final double slew, + final int ot12) { + final QuadraticInterpolation[] qi = getInterpolation(r, n); + if (qi == null) { + return 0; + } else { + return qi[ot12 == T1 ? 0 : 1].gradient(slew); + } + } + + private final double getSlack(final double[] v, + final Rule r, + final int sense, + final Node n, + final int ot12) { + final double it1 = getVar(v, n, sense, T1, INPUT); + final double it2 = getVar(v, n, sense, T2, INPUT); + final double ot = getVar(v, r.target(), r.dir, ot12, OUTPUT); + final double result = ot - it1 + getBudget(r) - + getDelay(r, n, it2 - it1, ot12); + return result; + } + + private double getTau(final double[] v, Rule r, int sense, Node n) { + final double slack1 = getSlack(v, r, sense, n, T1); + final double slack2 = getSlack(v, r, sense, n, T2); + final double slack = Math.min(slack1, slack2); + final double budget = getBudget(r); + return ((budget - slack) / budget) * tau; + } + + private class EnergyWorker extends Worker { + double[] v = null; + double energy = 0; + public EnergyWorker(final CyclicBarrier barrier, + final Node[] assignment) { + super(barrier, assignment); + } + protected void runTask(final Node n) { + n.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + final int instances = r.falseConjuncts; + if (isErrorRule(r) || instances == 0) return; + energy += getValue(v, r, sense, n, instances); + } + }); + } + } + + private double getValue(final double[] v, final Rule r, final int sense, + final Node n, final int instances) { + double result = 0; + + final double budgetTau = getBudget(r) * tau; + final double slack1 = getSlack(v, r, sense, n, T1); + if (slack1 < 0) result += (slack1 * slack1 / budgetTau) * instances; + + final double slack2 = getSlack(v, r, sense, n, T2); + if (slack2 < 0) result += (slack2 * slack2 / budgetTau) * instances; + + return result; + } + + public double getValue(final double[] v) { + final double[] energy = new double[] { 0 }; + if (energyWorkers == null) { + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + final int instances = r.falseConjuncts; + if (isErrorRule(r) || instances == 0) return; + energy[0] += getValue(v, r, sense, n, instances); + } + }); + } else { + try { + for (EnergyWorker worker : energyWorkers) { + worker.energy = 0; + worker.v = v; + } + energyWorkers.barrier.await(); + energyWorkers.barrier.await(); + for (EnergyWorker worker : energyWorkers) { + energy[0] += worker.energy; + } + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + //System.out.println("energy = " + energy[0]); + return energy[0]; + } + + private final void accumNegativeGradient(final double[] v, + final double[] accum, + final Rule r, + final int sense, + final Node n, + final int ot12, + final int instances) { + // accumulate gradients related to delay constraint + final double sgrad = -2 * getSlack(v, r, sense, n, ot12) / + getBudget(r) / tau * instances; + if (sgrad > 0) { + accumVar(accum, r.target(), r.dir, ot12, sgrad); + final double it1 = getVar(v, n, sense, T1, INPUT); + final double it2 = getVar(v, n, sense, T2, INPUT); + final double dgrad = getDelayGradient(r, n, it2 - it1, ot12); + accumVar(accum, n, sense, T1, sgrad * (dgrad - 1)); + accumVar(accum, n, sense, T2, sgrad * -dgrad); + } + } + + private final void accumNegativeGradient(final double[] v, + final double[] accum, + final Rule r, + final int sense, + final Node n, + final int instances) { + accumNegativeGradient(v, accum, r, sense, n, T1, instances); + accumNegativeGradient(v, accum, r, sense, n, T2, instances); + } + + private class GradientWorker extends Worker { + double[] v = null; + double[] accum = null; + public GradientWorker(final CyclicBarrier barrier, + final Node[] assignment) { + super(barrier, assignment); + } + protected void runTask(final Node n) { + n.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + final int instances = r.falseConjuncts; + if (isErrorRule(r) || instances == 0) return; + accumNegativeGradient(v, accum, r, sense, n, instances); + } + }); + } + } + + public void getNegativeGradient(final double[] v, + final double[] accum) { + if (gradientWorkers == null) { + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + final int instances = r.falseConjuncts; + if (isErrorRule(r) || instances == 0) return; + accumNegativeGradient(v, accum, r, sense, n, instances); + } + }); + } else { + try { + for (GradientWorker worker : gradientWorkers) { + worker.v = v; + if (worker.accum == null) { + worker.accum = new double[accum.length]; + } + for (int i = 0; i < accum.length; ++i) { + worker.accum[i] = 0; + } + } + gradientWorkers.barrier.await(); + gradientWorkers.barrier.await(); + for (GradientWorker worker : gradientWorkers) { + for (int i = 0; i < accum.length; ++i) { + accum[i] += worker.accum[i]; + } + } + } catch (BrokenBarrierException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + private void printFlatViolations(final double[] v, + final double worstTau, + int max, + final boolean verbose, + final boolean canonRulesOnly, + final PrintWriter pw) { + final Set> violations = + new BoundedSet>( + max, new TreeSet>()); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + if (canonRulesOnly && r.getCanonRule() != null) return; + final double tau = getTau(v, r, sense, n); + if (tau >= worstTau) { + violations.add( + new Pair(-tau, + strRule(verbose ? v : null, r, sense, + canonRulesOnly, n))); + } + } + }); + for (Pair vio : violations) { + if (max <= 0) break; + pw.printf("%.3f %s\n", -vio.getFirst(), vio.getSecond()); + --max; + } + if (violations.isEmpty()) { + pw.printf("No transitions with tau >= %.3f\n", worstTau); + } + } + + double getWorstTau() { + final MutableDouble result = + new MutableDouble(Double.NEGATIVE_INFINITY); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + if (r.getCanonRule() != null) return; + final double tau = getTau(X, r, sense, n); + result.max(tau); + } + }); + return result.get(); + } + + void printFlatViolations(final double worstTau, final int max, + final boolean verbose, + final boolean canonRulesOnly, + final PrintWriter pw) { + printFlatViolations(X, worstTau, max, verbose, canonRulesOnly, pw); + } + + private static class ViolationType + implements Comparable { + private final String fqcn; + private double worstTau; + private Map,Double> violations; + private Set instances; + public ViolationType(final String fqcn) { + this.fqcn = fqcn; + this.worstTau = Double.NEGATIVE_INFINITY; + this.violations = new HashMap,Double>(); + this.instances = new HashSet(); + } + public void update(final HierName instance, + final Pair target, + final double tau) { + instances.add(instance); + Double prevTau = violations.get(target); + if (prevTau == null || tau > prevTau) { + worstTau = Math.max(worstTau, tau); + violations.put(target, tau); + } + } + public int compareTo(ViolationType o) { + int result = Double.compare(worstTau, o.worstTau); + if (result != 0) return -result; + else return fqcn.compareTo(o.fqcn); + } + public void print(final PrintWriter pw) { + pw.printf("%s %d\n", fqcn, instances.size()); + final Set,Double>> sorted = + new TreeSet,Double>>( + new Comparator, + Double>>() { + public int compare( + Map.Entry,Double> o1, + Map.Entry,Double> o2) { + int x = Double.compare(o1.getValue(), + o2.getValue()); + if (x != 0) return -x; + return o1.getKey().toString().compareTo( + o2.getKey().toString()); + } + }); + sorted.addAll(violations.entrySet()); + for (Map.Entry,Double> entry : sorted) { + pw.printf(" %.3f %s%c\n", entry.getValue(), + entry.getKey().getFirst(), + entry.getKey().getSecond() > 0 ? '+' : '-'); + } + } + } + + private void printLocalViolations(final double[] v, + final double worstTau, + final PrintWriter pw) { + final Map types = + new HashMap(); + + dsim.foreachRule(new Node.RuleFunc() { + private void update(final Rule r, final double tau) { + final Triplet local = + DSim.localize(r.target.getName()); + final String fqcn = local.getSecond().getType(); + ViolationType vtype = types.get(fqcn); + if (vtype == null) { + vtype = new ViolationType(fqcn); + types.put(fqcn, vtype); + } + vtype.update( + local.getFirst(), + new Pair(local.getThird(), r.dir), + tau); + } + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + final double tau = getTau(v, r, sense, n); + if (tau >= worstTau) update(r, tau); + } + }); + + if (types.isEmpty()) { + pw.printf("No transitions with tau >= %.3f\n", worstTau); + } else { + for (ViolationType type : + new TreeSet(types.values())) { + type.print(pw); + } + } + } + + void printLocalViolations(final double worstTau, final PrintWriter pw) { + printLocalViolations(X, worstTau, pw); + } + + private HierName getLocalName(final Collection aliases, + final HierName prefix) { + final TreeSet names = new TreeSet(); + final int n = prefix.getNumComponents(); + for (HierName alias : aliases) { + if (alias.isChildOf(prefix)) { + names.add(alias.tail(n)); + } + } + return names.first(); + } + + private CellInterface getInstanceType(final CellInterface cell, + final HierName prefix) { + if (prefix == null) return cell; + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName instance = (HierName) p.getFirst(); + if (prefix.isChildOf(instance)) { + return getInstanceType( + (CellInterface) p.getSecond(), + prefix.tail(instance.getNumComponents())); + } else if (prefix.equals(instance)) { + return (CellInterface) p.getSecond(); + } + } + + return null; + } + + private static class ViolationValue { + int count; + double max; + public ViolationValue() { + this.count = 0; + this.max = Double.NEGATIVE_INFINITY; + } + public void update(final double slack) { + ++count; + max = Math.max(max, slack); + } + public String toString() { + return String.format("%d %.3f", count, max); + } + } + + private static class ViolationKey { + final CellInterface cell; + final HierName guard; + final HierName target; + public ViolationKey(final CellInterface cell, final HierName guard, + final HierName target) { + this.cell = cell; + this.guard = guard; + this.target = target; + } + public int hashCode() { + return guard.hashCode() + target.hashCode() + + cell.getFullyQualifiedType().hashCode(); + } + public boolean equals(final Object o) { + if (o instanceof ViolationKey) { + final ViolationKey k = (ViolationKey) o; + return cell == k.cell && guard.equals(k.guard) && + target.equals(k.target); + } else { + return false; + } + } + public String toString() { + return guard + " -> " + target; + } + } + + private void printHierViolations(final double[] v, + final double worstTau, + final PrintWriter pw) { + final CellInterface dut; + try { + dut = dsim.getCell(); + } catch (Exception e) { + System.err.println("Cannot get top-level cell to print out " + + "hierarchical violations."); + return; + } + + final Set nodes = new HashSet(); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + final double tau = getTau(v, r, sense, n); + if (tau >= worstTau) { + nodes.add(r.target()); + nodes.add(n); + } + } + }); + + final MultiMap aliases = + dsim.generateNodeToAliases(nodes); + final Map violations = + new HashMap(); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + final double tau = getTau(v, r, sense, n); + if (tau >= worstTau) { + final CellInterface type = + getInstanceType(dut, r.prefix.tail(1)); + final HierName localGuard = + getLocalName(aliases.get(n), r.prefix); + final HierName localTarget = + getLocalName(aliases.get(r.target()), r.prefix); + final ViolationKey key = + new ViolationKey(type, localGuard, localTarget); + ViolationValue val = violations.get(key); + if (val == null) { + val = new ViolationValue(); + violations.put(key, val); + } + val.update(tau); + } + } + }); + + final Map> results = + new TreeMap>(); + for (Map.Entry vio : + violations.entrySet()) { + final ViolationKey key = vio.getKey(); + final ViolationValue val = vio.getValue(); + final String type = key.cell.getFullyQualifiedType(); + MultiMap result = results.get(type); + if (result == null) { + result = new MultiMap( + new TreeMap>()); + results.put(type, result); + } + result.put(val.max, key.toString() + " " + val.toString()); + } + + for (Map.Entry> entry : + results.entrySet()) { + pw.println(entry.getKey()); + final MultiMap result = entry.getValue(); + for (Double d : result.keySet()) { + for (String s : result.get(d)) { + pw.println(" " + s); + } + } + } + } + + void printHierViolations(final double worstTau, final PrintWriter pw) { + printHierViolations(X, worstTau, pw); + } + + private MultiMap getViolationByPrefix( + final double[] v, final double worstTau, + final boolean canonRulesOnly) { + final Map byPrefix = + new HashMap(); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + if (canonRulesOnly && r.getCanonRule() != null) return; + final double tau = getTau(v, r, sense, n); + if (tau >= worstTau) { + MutableDouble worstSoFar = byPrefix.get(r.prefix); + if (worstSoFar == null) { + worstSoFar = new MutableDouble(0); + byPrefix.put(r.prefix, worstSoFar); + } + worstSoFar.max(tau); + } + } + }); + + final MultiMap result = + new MultiMap( + new TreeMap>( + new Comparator() { + public int compare(Double d1, Double d2) { + return Double.compare(d2, d1); + } + })); + + for (Map.Entry vio : byPrefix.entrySet()) { + result.put(vio.getValue().get(), vio.getKey()); + } + + return result; + } + + MultiMap getViolationByPrefix( + final double worstTau, final boolean canonRulesOnly) { + return getViolationByPrefix(X, worstTau, canonRulesOnly); + } + + private void printResult(final double[] v) { + final Set> seen = + new HashSet>(); + dsim.foreachRule(new Node.RuleFunc() { + private void printNode(Node n, int sense) { + if (seen.add(new Pair(n, sense))) { + System.out.print("t(" + n.getName() + + (sense > 0 ? "+" : "-") + ") = "); + if (isFixed(n)) { + System.out.println("0 (fixed)"); + } else { + final int idx1 = getIndex(n, sense, T1); + final int idx2 = getIndex(n, sense, T2); + System.out.printf("%.3g %.3g %.3g %d\n", + v[idx1], v[idx2], + v[idx2] - v[idx1], + idx1); + } + } + } + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + printNode(n, sense); + printNode(r.target(), r.dir); + } + }); + } + + private static String dotNode(Node n, int sense) { + return "\"" + n.getName() + (sense > 0 ? "+" : "-") + "\""; + } + + private void writeDot(final double[] v) throws IOException { + final PrintWriter pw = new PrintWriter(new FileWriter("sta.dot")); + pw.println("digraph sta {"); + final Set> seen = + new HashSet>(); + dsim.foreachRule(new Node.RuleFunc() { + private void printNode(Node n, int sense) { + if (seen.add(new Pair(n, sense))) { + pw.println(dotNode(n, sense) + ";"); + } + } + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + printNode(n, sense); + printNode(r.target(), r.dir); + } + }); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + pw.println(dotNode(n, sense) + " -> " + + dotNode(r.target(), r.dir) + ";"); + } + }); + pw.println("}"); + pw.close(); + } + + public boolean evaluate(boolean big_step, double mag) { + ++iterations; + boolean result = + big_step && mag > MIN_GRAD_MAG && iterations < max_iterations; + if (result) { + if (System.currentTimeMillis() >= endTime) { + System.out.println( + "WARNING: Time limit reached; normal convergence " + + "criteria not met!"); + result = false; + } else if (dsim.isInterrupted() == + DigitalScheduler.InterruptedBy.USER) { + System.out.println("*** interrupted by ^C ***"); + System.out.println("WARNING: normal convergence " + + "criteria not met!"); + result = false; + } + } + return result; + } + + private Offset update(final int sense, final Node n) { + if (!isFixed(n)) { + final Node canon = (Node) n.enabler; + setFixed(n); + if (canon == null || canon == n) { + n.setTCount(fixed.size()); + fixed.add(new Offset()); + fixed.add(new Offset()); + } else { + update(sense, canon); + n.setTCount(canon.getTCount()); + } + } + + return fixed.get(getIndex(n, sense)); + } + + private void update(final int sense, final Node n, + final boolean T1, final Double val) { + Offset offset = update(sense, n); + if (val != null) { + offset.update(T1, val); + } + } + + // TODO: support wild card form of measured_delay directives, i.e., + // when the trigger is null + public void writeContext(final PrintWriter out) { + final Collection delays = + dsim.getBoundaryMeasuredDelays(); + for (MeasuredDelay delay : delays) { + if (delay.getInstance() == null) continue; + + out.println(delay.getCell().getFullyQualifiedType() + " " + + HierName.append(delay.getPrefix(), + delay.getInstance()) + " " + + delay.getDelayBias()); + + final Map,MeasuredDelay.Data> measured = + delay.getMeasured(); + final Map context = new HashMap(); + delay.getContext(context); + for (Map.Entry,MeasuredDelay.Data> entry : + measured.entrySet()) { + final Pair key = entry.getKey(); + final Node node = key.getFirst(); + final int sense = key.getSecond() ? 1 : 0; + out.printf("%s %d %.3f %.3f\n", + delay.getPort(node), sense, + getVar(X, node, sense, T1, INPUT), + getVar(X, node, sense, T2, INPUT)); + + if (entry.getValue() != null) { + final MeasuredDelay.Data data = entry.getValue(); + final double extraDelay = data.getExtraDelay(); + final Pair[] value = data.getData(); + for (Pair v : value) { + final Node trigger = (Node) v.getFirst(); + final HierName tname = context.get(trigger); + if (trigger != null && tname != null) { + final QuadraticInterpolation[] qi = + Rule.getInterpolation( + value, trigger, node, sense, alpha, + minDeriv, maxDeriv); + final double t1 = + getVar(X, node, sense, T1, INPUT) - + qi[0].value(defaultSlew) + extraDelay; + out.printf("\t%s %d %.3f %.3f\n", + tname, 1 - sense, + t1, t1 + defaultSlew); + } + } + } + } + } + out.flush(); + } + + private void printNodeInfo(final Node node, final double[] X) { + final Node canon = (Node) node.enabler; + System.err.println( + "node=" + node.getName() + " " + + "canon=" + (canon == null ? null : canon.getName()) + " " + + "fixed=" + isFixed(node) + " " + + "rules=" + node.getBreakpoint() + " " + + "index=" + node.getTCount() + " " + + "in(t1-)=" + getVar(X, node, 0, T1, INPUT) + " " + + "in(t2-)=" + getVar(X, node, 0, T2, INPUT) + " " + + "out(t1-)=" + getVar(X, node, 0, T1, OUTPUT) + " " + + "out(t2-)=" + getVar(X, node, 0, T2, OUTPUT) + " " + + "in(t1+)=" + getVar(X, node, 1, T1, INPUT) + " " + + "in(t2+)=" + getVar(X, node, 1, T2, INPUT) + " " + + "out(t1+)=" + getVar(X, node, 1, T1, OUTPUT) + " " + + "out(t2+)=" + getVar(X, node, 1, T2, OUTPUT)); + } + + private void printNodeInfo(final double[] X) { + dsim.foreachNode(new UnaryPredicate() { + public boolean evaluate(Node n) { + printNodeInfo(n, X); + return true; + } + }); + } + + private double getDouble(final DSim dsim, final String key, + final double def) { + return dsim.getDouble(key, def); + } + + public CGSolver(final DSim dsim, final float defaultSlew, + final Context worstContext, final int threads) { + this.dsim = dsim; + this.defaultSlew = defaultSlew; + this.alpha = getDouble(dsim, "sta.alpha", alpha); + this.minDeriv = getDouble(dsim, "sta.minDeriv", minDeriv); + this.maxDeriv = getDouble(dsim, "sta.maxDeriv", maxDeriv); + this.tolerance = getDouble(dsim, "sta.tolerance", tolerance); + + final int nodeCount[] = new int[] { 0 }; + + // initialize various indicies + dsim.foreachNode(new UnaryPredicate() { + boolean hasRules; + public boolean evaluate(Node n) { + hasRules = false; + n.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + if (r.falseConjuncts > 0) hasRules = true; + n.setTCount(UNINIT_INDEX); + setUnfixed(n); + r.target.setTCount(UNINIT_INDEX); + setUnfixed(r.target); + r.transitionCount = UNINIT_INDEX; + } + }); + if (hasRules) nodeCount[0]++; + n.setBreakpoint(hasRules); + return true; + } + }); + + if (worstContext != null) { + final MultiMap rules = + worstContext.getRules(); + for (HierName trigger : rules.keySet()) { + final Node triggerNode = worstContext.lookupNode(trigger); + final Set targets = new HashSet(); + for (HierName target : rules.get(trigger)) { + final Node targetNode = + worstContext.lookupNode(target); + targets.add(targetNode); + } + triggerNode.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + /* + if (targets.contains(r.target)) { + update(fixed[sense], + worstContext.lookupNode(key.getFirst()), + true, + val.minT1); + update(fixed[sense], + worstContext.lookupNode(key.getFirst()), + true, + val.maxT1); + update(fixed[sense], + worstContext.lookupNode(key.getFirst()), + false, + val.minT2); + update(fixed[sense], + worstContext.lookupNode(key.getFirst()), + false, + val.maxT2); + } + */ + } + }); + } + + for (Map.Entry,Context.Data> entry : + worstContext.getData().entrySet()) { + final Pair key = entry.getKey(); + final Context.Data val = entry.getValue(); + final int sense = key.getSecond() == true ? 1 : 0; + update(sense, + worstContext.lookupNode(key.getFirst()), true, + val.minT1); + update(sense, + worstContext.lookupNode(key.getFirst()), true, + val.maxT1); + update(sense, + worstContext.lookupNode(key.getFirst()), false, + val.minT2); + update(sense, + worstContext.lookupNode(key.getFirst()), false, + val.maxT2); + } + } + + // compute the maximum slew rates for the nodes on the boundary of + // blackboxed cells, using the default slew rates as the slew rate + // of the predecessor + final Collection delays = + dsim.getBoundaryMeasuredDelays(); + for (MeasuredDelay delay : delays) { + final Map,MeasuredDelay.Data> measured = + delay.getMeasured(); + for (Map.Entry,MeasuredDelay.Data> entry : + measured.entrySet()) { + final Pair key = entry.getKey(); + final Node node = key.getFirst(); + final int sense = key.getSecond() ? 1 : 0; + if (entry.getValue() == null) { + update(0, node); + update(1, node); + } else { + final Pair[] prep = entry.getValue().getData(); + for (Pair p : prep) { + final Node trigger = (Node) p.getFirst(); + if (trigger != null) { + final QuadraticInterpolation[] qi = + Rule.getInterpolation( + prep, trigger, node, sense, alpha, + minDeriv, maxDeriv); + final double slew = + qi[1].value(defaultSlew) - + qi[0].value(defaultSlew); + update(sense, node, false, slew); + update(1-sense, node); + } + } + } + } + } + + constraintCount = 0; + dsim.foreachRule(new Node.RuleFunc() { + private Map map(final Rule r) { + final Map ruleMap; + if (r.transitionCount == UNINIT_INDEX) { + r.transitionCount = interpols.size(); + ruleMap = + new IdentityHashMap(); + interpols.add(ruleMap); + } else { + ruleMap = interpols.get(r.transitionCount); + } + return ruleMap; + } + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + final Rule canonRule = r.getCanonRule(); + if (canonRule != null) { + map(canonRule); + r.transitionCount = canonRule.transitionCount; + } else { + final Map ruleMap = + map(r); + final QuadraticInterpolation[] qi = + r.getInterpolation(n, alpha, minDeriv, maxDeriv, 0); + if (qi != null && isFixed(r.target)) { + final double slew = + qi[1].value(defaultSlew) - + qi[0].value(defaultSlew); + update(r.dir, r.target, false, slew); + } + final Node canonNode = canon(n); + if (!ruleMap.containsKey(canonNode)) + ruleMap.put(canonNode, qi); + } + addVar(n, sense); + addVar(r.target(), r.dir); + if (r.falseConjuncts > 0) constraintCount += 2; + } + }); + + for (Node n : dsim.getInteriorOutputNodes()) { + // in astamizer mode, set T2=defaultSlew when used in a input + // context, and set T2=0 when used in an output context + update(0, n, false, (double) defaultSlew); + update(1, n, false, (double) defaultSlew); + update(0, n, false, 0.0); + update(1, n, false, 0.0); + } + + // initialize any nodes without measured_delay data (such as inputs) + // to have the default slew rate + for (Offset offset : fixed) { + offset.updateIfUnset(false, (double) defaultSlew); + offset.updateIfUnset(true, 0.0); + } + + this.T1 = 0; + this.T2 = getSize(); + + X = new double[getSize() * 2]; + for (int i = T2; i < X.length; ++i) { + X[i] = defaultSlew; + } + System.out.printf("%d constraints %d variables\n", constraintCount, + X.length); + dsim.interrupt(DigitalScheduler.InterruptedBy.NONE); + if (threads > 0) { + System.out.println("Using " + threads + " threads"); + final int maxPerThread = (nodeCount[0] + threads - 1) / threads; + final int[] nextIndex = new int[threads]; + final Node[][] assignment = new Node[threads][]; + for (int i = 0; i < threads; ++i) { + nextIndex[i] = 0; + assignment[i] = new Node[maxPerThread]; + } + dsim.foreachNode(new UnaryPredicate() { + int count = 0; + public boolean evaluate(Node n) { + if (n.getBreakpoint()) { + assignment[count][nextIndex[count]++] = n; + count++; + if (count == threads) count = 0; + } + return true; + } + }); + energyWorkers = + new Workers(EnergyWorker.class, threads, + "Energy Worker", assignment); + gradientWorkers = + new Workers(GradientWorker.class, threads, + "Gradient Worker", assignment); + energyWorkers.start(); + gradientWorkers.start(); + } + } + + public void solve(final float tau, final int max_iterations, + final long maxTime) { + this.tau = tau; + this.max_iterations = max_iterations; + this.endTime = maxTime <= 0 ? Long.MAX_VALUE + : System.currentTimeMillis() + maxTime; + this.iterations = 0; + new ConjugateGradientSolver(this).solve(X, tolerance, this); + } + + private MultiMap rulesByPrefix = null; + + private void populateRulesByPrefix() { + if (rulesByPrefix != null) return; + + rulesByPrefix = new MultiMap(); + dsim.foreachRule(new Node.RuleFunc() { + public void accept(Rule r, int sense, Node n) { + if (isErrorRule(r)) return; + rulesByPrefix.put(r.prefix, r); + } + }); + } + + public int swap(final HierName instance, final int which) { + int count = 0; + populateRulesByPrefix(); + final Collection rules = rulesByPrefix.get(instance); + for (Rule r : rules) { + final Rule canon = r.getCanonRule(); + if (canon != null) r = canon; + + // already swapped? + final Integer w = measureSelected.get(r); + if (w != null && w.intValue() == which) continue; + + final Map ruleMap = + interpols.get(r.transitionCount); + boolean updated = false; + for (Node n : ruleMap.keySet()) { + final QuadraticInterpolation[] qi = + r.getInterpolation(n, alpha, minDeriv, maxDeriv, which); + if (qi != null) { + ruleMap.put(n, qi); + updated = true; + } + } + if (updated) { + measureSelected.put(r, which); + ++count; + } + } + + return count; + } + } + + private CGSolver solver; + private Context worstContext; + + public static class InvalidContextFormatException extends RuntimeException { + public InvalidContextFormatException() { } + } + + public static class Context { + public static class Data { + public final double minT1, minT2; + public final double maxT1, maxT2; + public Data(final double minT1, final double minT2, + final double maxT1, final double maxT2) { + this.minT1 = minT1; + this.minT2 = minT2; + this.maxT1 = maxT1; + this.maxT2 = maxT2; + } + } + + private final Map,Data> data; + private final MultiMap rules; + private Map nodes; + private final float delayBias; + public Context(final float delayBias) { + this(delayBias, new HashMap,Data>()); + } + private Context(final float delayBias, + final Map,Data> data) { + this.data = data; + this.delayBias = delayBias; + this.rules = new MultiMap(); + } + public void addData(HierName node, boolean dir, double T1, double T2) { + data.put(new Pair(node, dir), + new Data(T1, T2, T1, T2)); + } + public void addRule(final HierName target, final HierName trigger) { + rules.put(trigger, target); + } + public float getDelayBias() { + return delayBias; + } + private static Data combine(final Data d1, final Data d2) { + if (d1 == null) return d2; + else if (d2 == null) return d1; + else { + return new Data(Math.min(d1.minT1, d2.minT1), + Math.min(d1.minT2, d2.minT2), + Math.max(d1.maxT1, d2.maxT1), + Math.max(d1.maxT2, d2.maxT2)); + } + } + public static Context worstContext(final Context c1, final Context c2) { + if (c1 == null) return c2; + else if (c2 == null) return c1; + else { + assert c1.data.keySet().equals(c2.data.keySet()); + final float delayBias = Math.min(c1.getDelayBias(), + c2.getDelayBias()); + final Map,Data> data = + new HashMap,Data>(); + for (Map.Entry,Data> entry : + c1.data.entrySet()) { + final Pair key = entry.getKey(); + data.put(key, combine(entry.getValue(), c2.data.get(key))); + } + return new Context(delayBias, data); + } + } + public Collection getNames() { + final Collection result = new HashSet(); + for (Pair x : data.keySet()) { + result.add(x.getFirst()); + } + return result; + } + public void setNodes(final Map nodes) { + this.nodes = nodes; + } + public Node lookupNode(final HierName name) { + return nodes.get(name); + } + public Map,Data> getData() { + return Collections.unmodifiableMap(data); + } + public MultiMap getRules() { + return rules; + } + } + + + public RunStaticTiming() { + solver = null; + worstContext = null; + } + + public static class EvaluateOption implements Cloneable { + DSim dsim; + float tau; + float defaultSlew; + int max_iterations; + long maxTime; + int threads; + float sweep; + public EvaluateOption(final DSim dsim, + final float tau, + final float defaultSlew, + final int max_iterations, + final long maxTime, + final int threads, + final float sweep) { + this.dsim = dsim; + this.tau = tau; + this.defaultSlew = defaultSlew; + this.max_iterations = max_iterations; + this.maxTime = maxTime; + this.threads = threads; + this.sweep = sweep; + } + public EvaluateOption clone() { + try { + return (EvaluateOption) super.clone(); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); + } + } + } + + public void evaluate(final DSim dsim, + final float tau, + final float defaultSlew, + final int max_iterations, + final long maxTime, + final int threads) { + if (solver == null) { + solver = new CGSolver(dsim, defaultSlew, getWorstContext(), + threads); + } else { + if (solver.defaultSlew != defaultSlew) { + System.err.println("Can't change defaultSlew without " + + "re-instantiating! Using old defaultSlew: " + + solver.defaultSlew); + } + } + dsim.interrupt(DigitalScheduler.InterruptedBy.NONE); + solver.solve(tau, max_iterations, maxTime); + } + + public void sweep(final DSim dsim, + final float tau, + final float defaultSlew, + final int max_iterations, + final long maxTime, + final int threads, + final float window) { + evaluate(dsim, tau, defaultSlew, max_iterations, maxTime, threads); + double low = tau; + double high = solver.getWorstTau(); + while (high - low > window && + dsim.isInterrupted() == DigitalScheduler.InterruptedBy.NONE) { + System.err.printf("Worst tau in (%.3f, %.3f)\n", low, high); + float mid = (float) ((low + high) / 2); + evaluate(dsim, mid, defaultSlew, max_iterations, maxTime, threads); + double worst = solver.getWorstTau(); + if (worst - mid > window) { + high = Math.min(high, worst); + low = mid; + } else { + high = mid; + } + } + System.err.printf("Worst tau in (%.3f, %.3f)\n", low, high); + } + + public void evaluate(final EvaluateOption opt) { + if (Float.isNaN(opt.sweep)) { + evaluate(opt.dsim, opt.tau, opt.defaultSlew, opt.max_iterations, + opt.maxTime, opt.threads); + } else { + sweep(opt.dsim, opt.tau, opt.defaultSlew, opt.max_iterations, + opt.maxTime, opt.threads, opt.sweep); + } + } + + public int swap(final String instance, final int which) { + return swap(toHier(instance), which); + } + + public int swap(final HierName instance, final int which) { + if (solver != null) { + return solver.swap(instance, which); + } else { + return -1; + } + } + + public void getFlatReport(final double worstTau, final int max, + final boolean verbose, + final boolean canonRulesOnly, + final PrintWriter pw) { + if (solver != null) { + solver.printFlatViolations(worstTau, max, verbose, canonRulesOnly, + pw); + pw.flush(); + } + } + + public void getHierReport(final double worstTau, final PrintWriter pw) { + if (solver != null) { + solver.printLocalViolations(worstTau, pw); + pw.flush(); + } + } + + private int trySwap(final HierName instance, + final Set seen, + final DSim dsim, + final double tau, + final String context, + final boolean printAnyway, + final UnaryPredicate replacePredicate, + final PrintWriter spec, + final PrintWriter pw) { + int swaps = 0; + if (seen.add(instance)) { + final String newtype = dsim.getCandidateType(instance); + if (replacePredicate.evaluate(newtype)) { + final int swapped = swap(instance, 1); + if (swapped > 0 || printAnyway) { + spec.printf("# tau=%.3f%s\n", tau, context); + spec.println(newtype + " " + instance); + pw.printf("Swapped %s (tau=%.3f rules=%d%s)\n", + instance, tau, swapped, context); + swaps = 1; + } + } + } + return swaps; + } + + private void simpleSwap(final double worstTau, + final int maxReport, + final int maxSwaps, + final int maxOuterLoop, + final EvaluateOption opt, + final Set seen, + final MutableInt loops, + final boolean routed, + final UnaryPredicate replacePredicate, + final PrintWriter spec, + final PrintWriter pw) { + while (loops.get() < maxOuterLoop) { + loops.inc(); + pw.println("Swap loop " + loops.get() + " tau=" + worstTau); + final MultiMap byPrefix = + solver.getViolationByPrefix(worstTau, true); + final Set keySet = byPrefix.keySet(); + if (keySet.isEmpty()) { + pw.println("No more violations; exiting"); + break; + } + + int swaps = 0; +FixViolations: + for (Double key : keySet) { + for (HierName instance : byPrefix.get(key)) { + final int swapped = + trySwap(instance, seen, opt.dsim, key, "", false, + replacePredicate, spec, pw); + swaps += swapped; + if (swapped > 0) { + for (HierName otherInst : + new IterableIterator( + opt.dsim.getGrayboxInstances( + instance.tail()))) { + swaps += trySwap(otherInst, seen, opt.dsim, key, + " graybox", true, + replacePredicate, spec, pw); + } + + if (routed) { + for (HierName otherInst : + new IterableIterator( + opt.dsim.getRoutedInstances( + instance.tail()))) { + swaps += trySwap(otherInst, seen, opt.dsim, key, + " routed", false, + replacePredicate, spec, pw); + } + } + } + if (swaps >= maxSwaps) break FixViolations; + } + } + + if (swaps == 0) { + pw.println("All instances swapped; exiting"); + break; + } + + evaluate(opt); + spec.flush(); + pw.flush(); + } + } + + public void simpleSwap(final double goalTau, + final int maxReport, + final int maxSwaps, + final int maxOuterLoop, + final EvaluateOption model, + final boolean routed, + final UnaryPredicate replacePredicate, + final PrintWriter spec, + final PrintWriter pw) { + final Set seen = new HashSet(); + final MutableInt loops = new MutableInt(0); + + // find the real worst tau + final EvaluateOption optSweep = model.clone(); + if (Float.isNaN(optSweep.sweep)) { + optSweep.sweep = 0.001f; + optSweep.max_iterations = 1000; + } + evaluate(optSweep); + double tau = solver.getWorstTau(); + + // (evaluate, swap) loop toward the goal tau 1 pS at a time + while (tau - goalTau > 0.001) { + tau = Math.max(tau - 1, goalTau); + final EvaluateOption opt = model.clone(); + opt.sweep = Float.NaN; + opt.tau = (float) tau; + simpleSwap(tau, maxReport, maxSwaps, maxOuterLoop, opt, + seen, loops, routed, replacePredicate, spec, pw); + getFlatReport(tau, maxReport, false, true, pw); + } + pw.flush(); + } + + public void writeContext(final PrintWriter pw) { + if (solver != null) { + solver.writeContext(pw); + pw.flush(); + } + } + + public void readContext(final BufferedReader br) throws IOException { + String line; + Context context = null; + HierName target = null; + while ((line = br.readLine()) != null) { + if (line.startsWith("#")) continue; + + final String[] fields = StringUtil.split(line, ' '); + if (fields.length == 3) { + if (context != null) { + worstContext = Context.worstContext(worstContext, context); + } + context = new Context(Float.parseFloat(fields[2])); + } else if (fields.length == 4) { + boolean isTarget = true; + if (fields[0].startsWith("\t")) { + fields[0] = fields[0].substring(1); + isTarget = false; + } + final HierName node = toHier(fields[0]); + final boolean dir = Integer.parseInt(fields[1]) == 1; + final double T1 = Double.parseDouble(fields[2]); + final double T2 = Double.parseDouble(fields[3]); + context.addData(node, dir, T1, T2); + if (isTarget) target = node; + else if (target != null) { + context.addRule(target, node); + } + } else { + throw new InvalidContextFormatException(); + } + } + if (context != null) { + worstContext = Context.worstContext(worstContext, context); + } + } + + public Context getWorstContext() { + return worstContext; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SchedulerRunner.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SchedulerRunner.java new file mode 100644 index 0000000000..6297c93655 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SchedulerRunner.java @@ -0,0 +1,74 @@ +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id: + */ + +package com.avlsi.tools.dsim; + + +/** + * This is a separate thread which just keeps calling cycle(). You'll + * need this if you use any AccurateWaits or using signalscan. SchedulerRunner + * is a singleton, just like the objects (DSim and DigSched) it controls. You + * can disable this thread before it is started by setting setEnable(false); + * + * @author Dan Daly + */ + +public class SchedulerRunner implements Runnable { + + private SchedulerRunner() { + cycler = new Thread(this, "Scheduler Runner"); + } + + private static SchedulerRunner runner = null; + private final Thread cycler; + private boolean running = false; + private boolean enable = true; + private long limit=-1; + + public static SchedulerRunner get() { + if (runner == null) { + runner = new SchedulerRunner(); + } + return runner; + } + + /** Method to enable or disable subsequent calls to the start method + * Does not 'stop' the thread if it has already began running + * @param enable Set to false to disable the thread + **/ + public synchronized void setEnable(boolean enable) { + this.enable = enable; + } + + /** + * Sets the number of cycles for the scheduler to run through. Set to -1 + * to disable cycle limits. + **/ + public synchronized void setCycleLimit(long limit) { + this.limit = limit; + } + + public synchronized void start() { + if ((!running) && (enable)) cycler.start(); + } + + public synchronized boolean isRunning() { + return running; + } + + public void run() { + running = true; + while (true) { + //System.out.println("Cycling."); + if (limit < 0) { + DigitalScheduler.get().cycle(); + } else { + DigitalScheduler.get().cycleTo(limit); + } + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SequencedEvent.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SequencedEvent.java new file mode 100644 index 0000000000..24709f8478 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SequencedEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000, 2002 Fulcrum Microsystems. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +/** + * @todo Undocumented. + * + * @author Dan Daly + * @version $Revision$ $Date$ + **/ + +public interface SequencedEvent extends Event { + + /** + * @return true if this event has another event scheduled to come after it + * at the same time. + **/ + /*@ pure @*/ boolean hasNextEvent(); + + /** + * @return the next event scheduled at this time. The ordering of events + * scheduled at the same time is determined by the order in which they were + * added to the scheduler. + **/ + SequencedEvent getNextEvent(); + + /** + * @param nextEvent the event to follow this one in sequence time. + **/ + void setNextEvent(SequencedEvent nextEvent); + +} // end of interface SequencedEvent + +/* + * Local Variables: + * mode:jde + * fill-column:80 + * End: + */ + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewCheck.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewCheck.java new file mode 100644 index 0000000000..3be32cebab --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewCheck.java @@ -0,0 +1,145 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.io.PrintWriter; +import java.io.Serializable; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import com.avlsi.util.container.Pair; +import com.avlsi.util.graph.ShortestPaths; +import com.avlsi.util.graph.Vertex; + +abstract class SlewCheck implements Serializable{ + private final SortedSet violations; + + SlewCheck(){ + violations = new TreeSet (); + } + + abstract void evaluateSlowPaths(HalfOpGraph circuit, + final Map slews); + + abstract double getSlowDelay(Vertex v); + + void checkViolations(HalfOpGraph circuit, HalfOp src, ShortestPaths paths, + double absMargin, double multMargin, + boolean checkIsochronicForks) { + Collection reached = paths.getReached(); + Collection disabledBySrc = src.disables(); + HalfOp notSrc = src.not(); + double slow = getSlowDelay(src); + if (slow < 0 ) { + return; + } + double effectiveSlow = computeEffectiveDelay(slow, absMargin, + multMargin); + for(Vertex v : reached) { + HalfOp r = (HalfOp) v; + if(r.isDuplicate()) { + continue; + } + if(r.equals(src) || + paths.getDistance(r, + Double.POSITIVE_INFINITY) > effectiveSlow) { + continue; + } + + Collection enabledByR = r.enables(); + Collection disabledByR = r.disables(); + + if(enabledByR.contains(notSrc)) { + createViolation(src, r, null, notSrc, paths, slow, + absMargin, multMargin); + } + + if(disabledByR.contains(src)) { + createViolation(src, r, null, src, paths, slow, + absMargin, multMargin); + } + if(checkIsochronicForks) { + enabledByR.retainAll(disabledBySrc); + for(HalfOp isochronicTarget : enabledByR) { + createViolation(src, r, isochronicTarget, + isochronicTarget, paths, slow, absMargin, + multMargin); + } + } + } + } + + void createViolation(HalfOp src,HalfOp reached, HalfOp slowEndPt, + HalfOp fastEndPt, ShortestPaths paths, double slew, + double absMargin, double multMargin) { + LinkedList slow = new LinkedList(); + slow.add(src); + if(slowEndPt != null) { + slow.addLast(slowEndPt); + } + + LinkedList fast = paths.getPath(reached); + if(fastEndPt != null) { + fast.addLast(fastEndPt); + } + + violations.add(new SlewViolation + (slow, slew+absMargin, fast, + paths.getDistance(reached, -1)*multMargin)); + } + + void createViolation(HalfOp src,HalfOp reached, HalfOp slowEndPt, + HalfOp input, + HalfOp fastEndPt, ShortestPaths paths, double slew, + double absMargin, double multMargin) { + LinkedList slow = new LinkedList(); + slow.add(src); + if(slowEndPt != null) { + slow.addLast(slowEndPt); + } + + LinkedList fast = paths.getPath(reached); + if(fastEndPt != null) { + fast.addLast(fastEndPt); + } + + SlewViolation v = new SlewViolation(slow, slew+absMargin, input, fast, + paths.getDistance(reached, -1)*multMargin); + violations.add(v); + } + + static double computeEffectiveDelay(double slow, double absMargin, + double multMargin) { + return (slow+absMargin)/multMargin; + } + + boolean printViolations(PrintWriter pw, + boolean reportVictimsOnce) { + HashSet > printed = null; + if(reportVictimsOnce) { + printed = new HashSet >(); + } + pw.println(violations.isEmpty() ? "PASS":"FAIL"); + for (SlewViolation v: violations) { + Pair victim = v.victimLocalName(); + if(!reportVictimsOnce || !printed.contains(victim)) { + pw.println(v.toString()); + if(reportVictimsOnce) { + printed.add(victim); + } + } + } + return violations.isEmpty(); + } + +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewChecker.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewChecker.java new file mode 100644 index 0000000000..ac427ad3d5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewChecker.java @@ -0,0 +1,270 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; + +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.graph.Edge; +import com.avlsi.util.graph.GraphUtil; +import com.avlsi.util.graph.ShortestPaths; +import com.avlsi.util.graph.Vertex; + +class SlewChecker { + private final HalfOpGraph circuit; + private SlewCheck outputSlewCheck; + private SlewCheck inputSlewCheck; + private SlewCheck staticizerSlewCheck; + + private final HashMap slowSlews; + private final HashMap fastSlews; + + SlewChecker(DSim dsim) { + circuit = new HalfOpGraph(dsim); + outputSlewCheck = new OutputSlewCheck(); + inputSlewCheck = new InputSlewCheck(); + staticizerSlewCheck = new StaticizerSlewCheck(); + slowSlews = new HashMap(); + fastSlews = new HashMap(); + } + + void computeSlowSlews(final double initSlew) { + final double initSlewPs = HalfOpEdge.toPs(initSlew); + slowSlews.clear(); + slowSlews.putAll(relaxSlews(initSlewPs, false)); + // TODO(piyush): This method should be renamed. + // evaluate slowPaths with slow delays here. + outputSlewCheck.evaluateSlowPaths(circuit, slowSlews); + inputSlewCheck.evaluateSlowPaths(circuit, slowSlews); + staticizerSlewCheck.evaluateSlowPaths(circuit, slowSlews); + } + + void computeFastSlews(final double initSlew) { + final double initSlewPs = HalfOpEdge.toPs(initSlew); + fastSlews.clear(); + fastSlews.putAll(relaxSlews(initSlewPs, true)); + } + + private Map relaxSlews( + final double initSlew, boolean doMin) { + circuit.init(); + HashMap slews = new HashMap(); + for(int i=0; i<10; i++) { + slews = relax(slews, initSlew, doMin); + } + return slews; + } + + private HashMap relax( + final HashMap slews, + final double initSlew, + final boolean doMin) { + final HashMap nextSlews = + new HashMap(); + circuit.foreachVertex( + new UnaryPredicate() { + @Override public boolean evaluate(Vertex v) { + v.foreachEdge( + new UnaryPredicate() { + @Override public boolean evaluate(Edge e) { + final String key = e.getSnk().toString(); + final double inputSlewPs = + (slews.containsKey(key)) ? + HalfOpEdge.toPs(slews.get(key)) : initSlew; + final double nextSlewPs = + ((HalfOpEdge) e).getSlew(inputSlewPs, -1); + final double nextSlew = + HalfOpEdge.toDSim(nextSlewPs); + boolean updateSlew = nextSlewPs != -1 && + (!nextSlews.containsKey(key) || + ((nextSlews.get(key) > nextSlew) && + doMin) || + ((nextSlews.get(key) < nextSlew) && + !doMin)); + if(updateSlew) { + nextSlews.put(key, nextSlew); + } + return true; + } + }); + return true; + } + }); + return nextSlews; + } + + private void initializeSlews(final Map slews, + final double slew) { + slews.clear(); + circuit.foreachVertex( + new UnaryPredicate() { + @Override public boolean evaluate(Vertex v) { + HalfOp h = (HalfOp) v; + slews.put(h.toString(), slew); + return true; + } + }); + } + + void setSlowSlews(final double inputSlew) { + initializeSlews(slowSlews, inputSlew); + } + + void setFastSlews(final double inputSlew) { + initializeSlews(fastSlews, inputSlew); + } + + //TODO(piyush) : rename methods and dsim command line + void saveSlowSlews(ObjectOutputStream oos) { + try { + oos.writeObject(slowSlews); + oos.writeObject(outputSlewCheck); + oos.writeObject(inputSlewCheck); + oos.writeObject(staticizerSlewCheck); + } catch (IOException e) { + System.out.println("Error saving slews: " + e.getMessage()); + } + } + + void saveFastSlews(ObjectOutputStream oos) { + try { + oos.writeObject(fastSlews); + } catch (IOException e) { + System.out.println("Error saving slews: " + e.getMessage()); + } + } + + private HashMap readSlews(HashMap slews, + ObjectInputStream ois) { + circuit.init(); + slews.clear(); + HashMap read = null; + try { + read = (HashMap) ois.readObject(); + } catch (IOException e) { + System.out.println("Error reading slews: " + e.getMessage()); + } catch (ClassNotFoundException e) { + System.out.println("Error reading slews: " + e.getMessage()); + } + if (read != null) { + slews.putAll(read); + } + return read; + } + + void readFastSlews(ObjectInputStream ois) { + readSlews(fastSlews, ois); + } + + void readSlowSlews(ObjectInputStream ois) { + readSlews(slowSlews, ois); + try { + outputSlewCheck = (OutputSlewCheck) ois.readObject(); + inputSlewCheck = (InputSlewCheck) ois.readObject(); + staticizerSlewCheck = (StaticizerSlewCheck) ois.readObject(); + } catch (IOException e) { + System.out.println("Error reading slews: " + e.getMessage()); + } catch (ClassNotFoundException e) { + System.out.println("Error reading slews: " + e.getMessage()); + } + } + + void evaluate(final double absMargin, + final double multMargin, + final boolean checkIsochronicForks) { + // TODO(piyush): Warning if slews table is empty, i.e input slews + // not initialized. + System.out.println( + "Slew checker started evaluating at " + + new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(new Date())); + + circuit.foreachVertex( + new UnaryPredicate() { + @Override public boolean evaluate(Vertex v) { + double[] slowDelays = new double[3]; + slowDelays[0] = outputSlewCheck.getSlowDelay(v); + slowDelays[1] = inputSlewCheck.getSlowDelay(v); + slowDelays[2] = staticizerSlewCheck.getSlowDelay(v); + + Arrays.sort(slowDelays); + double slowDelay = slowDelays[2]; + + if ((slowDelay < 0) || + !fastSlews.containsKey(v.toString())) { + return true; + } + double effectiveSlowDelay = + SlewCheck.computeEffectiveDelay(slowDelay, absMargin, + multMargin); + ((HalfOp) v).setSlew + (HalfOpEdge.toPs(fastSlews.get(v.toString()))); + ShortestPaths paths = + GraphUtil.singleSrcShortestPaths + (v, effectiveSlowDelay, + circuit.getExcludePaths((HalfOp)v)); + + outputSlewCheck.checkViolations(circuit, + (HalfOp) v, paths, + absMargin, multMargin, + checkIsochronicForks); + inputSlewCheck.checkViolations(circuit, (HalfOp) v, paths, + absMargin, multMargin, + checkIsochronicForks); + staticizerSlewCheck.checkViolations(circuit, + (HalfOp) v, paths, + absMargin, multMargin, + checkIsochronicForks); + return true; + } + }); + System.out.println( + "Slew checker finished evaluating at " + + new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(new Date())); + } + + void printViolations(PrintWriter pwOutSlew, PrintWriter pwIOSlew, + PrintWriter pwStatSlew, PrintWriter pwAll, + boolean reportVictimsOnce) { + boolean passed = + outputSlewCheck.printViolations(pwOutSlew, reportVictimsOnce) & + inputSlewCheck.printViolations(pwIOSlew, reportVictimsOnce) & + staticizerSlewCheck.printViolations(pwStatSlew, reportVictimsOnce); + String result = (passed ? "PASS" : "FAIL"); + pwAll.println(result); + + } + + private void printSlews(Map slews, PrintWriter pw) { + for (Map.Entry slew : slews.entrySet()) { + pw.println(slew.getKey() + " " + slew.getValue()); + } + } + + void printFastSlews(PrintWriter pw) { + printSlews(fastSlews, pw); + } + + void printSlowSlews(PrintWriter pw) { + printSlews(slowSlews, pw); + } +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewViolation.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewViolation.java new file mode 100644 index 0000000000..e3eaa98cd3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/SlewViolation.java @@ -0,0 +1,100 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.LinkedList; +import java.util.List; + +import com.avlsi.util.container.Pair; +import com.avlsi.util.graph.Vertex; + +class SlewViolation implements Comparable { + private LinkedList slow; + private LinkedList fast; + private double fastDelay; + private double slowDelay; + private double slack; + private Vertex input = null; + + SlewViolation(LinkedList slow, + double slowDelay, + LinkedList fast, + double fastDelay) { + this.slow = slow; + this.fast = fast; + this.slowDelay = slowDelay; + this.fastDelay = fastDelay; + this.slack = fastDelay - slowDelay; + } + + SlewViolation(LinkedList slow, + double slowDelay, + Vertex input, + LinkedList fast, + double fastDelay) { + this.slow = slow; + this.fast = fast; + this.slowDelay = slowDelay; + this.fastDelay = fastDelay; + this.slack = fastDelay - slowDelay; + this.input = input; + } + + public String toString() { + LinkedList slow = new LinkedList(); + slow.addAll(this.slow); + if(input != null) { + slow.addFirst(input); + } + return Math.round(slack) + " " + Math.round(slowDelay) + " " + + Math.round(fastDelay) + " " + victimLocalName() + " " + + slow + " " + fast; + } + + Pair victimLocalName() { + final HalfOp h = (HalfOp) slow.get(0); + return h.getLocalName(); + } + + @Override public int compareTo(SlewViolation v) { + if (v==null) { + throw new NullPointerException(); + } + + if (this.equals(v)) { + return 0; + } + + int slkCmp = Double.compare(this.slack, v.slack); + int slowDelayCmp = Double.compare(this.slowDelay, v.slowDelay); + int fastDelayCmp = Double.compare(this.fastDelay, v.fastDelay); + + if(slkCmp != 0 ) { + return slkCmp; + } + + if(slowDelayCmp != 0) { + return slowDelayCmp; + } + + if(fastDelayCmp != 0) { + return fastDelayCmp; + } + + int slowCmp = this.slow.toString().compareTo(v.slow.toString()); + + if(slowCmp != 0) { + return slowCmp; + } + + int fastCmp = this.fast.toString().compareTo(v.fast.toString()); + assert fastCmp != 0; + return fastCmp; + } +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/StaticizerSlewCheck.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/StaticizerSlewCheck.java new file mode 100644 index 0000000000..e4a6784d73 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/StaticizerSlewCheck.java @@ -0,0 +1,146 @@ +/* + * INTEL TOP SECRET + * Copyright 2012 Intel Corporation. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.dsim; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.graph.ShortestPaths; +import com.avlsi.util.graph.Edge; +import com.avlsi.util.graph.Vertex; + + +class StaticizerSlewCheck extends SlewCheck { + private Map slowDelays; + private Map staticizerInv; + + StaticizerSlewCheck() { + slowDelays = new HashMap(); + staticizerInv = new HashMap(); + } + + void evaluateSlowPaths(HalfOpGraph circuit, + final Map slews) { + slowDelays.putAll(getStaticizerDelay(circuit, slews)); + } + + double getSlowDelay(Vertex v) { + Double slow = slowDelays.get(v.toString()); + if (slow == null) { + return -1; + } + return slow; + } + + private Map getStaticizerDelay( + final HalfOpGraph circuit, + final Map slews) { + final Map delays = new HashMap(); + circuit.foreachVertex( + new UnaryPredicate() { + @Override public boolean evaluate(final Vertex v) { + final Double slew = slews.get(v.toString()); + // skip combinational nodes, and nodes with no slew. + if(slew == null || !circuit.isDynamic((HalfOp) v)) { + return true; + } + final boolean hasFullStaticizer = + circuit.hasFullStaticizer((HalfOp) v); + final HalfOp staticizerInverse = + circuit.getStaticizerInverse((HalfOp) v); + final HalfOpEdge se; + if(staticizerInverse != null) { + se = ((HalfOp) v).getEdge(staticizerInverse); + } else { + se = null; + } + final boolean staticizerDelayIsMeasured = + (se != null) && se.hasMeasured(); + v.foreachEdge + (new UnaryPredicate() { + @Override public boolean evaluate(Edge e) { + HalfOpEdge he = (HalfOpEdge) e; + if (!staticizerDelayIsMeasured || + e.getSnk().equals(staticizerInverse)) { + double delay = + he.getMaxDelay(HalfOpEdge.toPs(slew), + 100,false); + Double old = delays.get(v.toString()); + if(old == null || delay > old) { + delays.put(v.toString(), delay); + staticizerInv.put + (v.toString(), + e.getSnk().toString()); + } + } + return true; + } + }); + return true; + } + }); + return delays; + } + + void checkViolations(HalfOpGraph circuit, + HalfOp src, ShortestPaths paths, + double absMargin, double multMargin, + boolean checkIsochronicForks) { + Collection reached = paths.getReached(); + Collection disabledBySrc = src.disables(); + HalfOp notSrc = src.not(); + double slow = getSlowDelay(src); + if (slow < 0 ) { + return; + } + double effectiveSlow = computeEffectiveDelay(slow, absMargin, + multMargin); + for(Vertex v : reached) { + HalfOp r = (HalfOp) v; + if(r.isDuplicate()) { + continue; + } + if(r.equals(src) || + paths.getDistance(r, + Double.POSITIVE_INFINITY) > effectiveSlow) { + continue; + } + + Collection enabledByR = r.enables(); + Collection disabledByR = r.disables(); + + if(enabledByR.contains(notSrc)) { + createViolation + (src, r, + circuit.getHalfOp(staticizerInv.get(src.toString())), + notSrc, paths, slow, + absMargin, multMargin); + } + + if(disabledByR.contains(src)) { + createViolation + (src, r, + circuit.getHalfOp(staticizerInv.get(src.toString())), + src, paths, slow, + absMargin, multMargin); + } + if(checkIsochronicForks) { + enabledByR.retainAll(disabledBySrc); + for(HalfOp isochronicTarget : enabledByR) { + createViolation(src, r, isochronicTarget, + isochronicTarget, paths, slow, absMargin, + multMargin); + } + } + } + } + +} \ No newline at end of file diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/WakeAt.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/WakeAt.java new file mode 100644 index 0000000000..0885fd8e9d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/WakeAt.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.dsim; + +/** + * Wakes all threads waiting on wait. + * Should perhaps be provided by Digital Scheduler for + * general use. Perhaps should also add wait method that + * reliably sleeps until the time given. + * @author Aaron Denney + * @version $Date$ + **/ +public class WakeAt implements Event { + private final Object wait; + private final long time; + + private int index = -1; + private boolean fired = false; + + public WakeAt(long time, Object wait) { + this.time = time; + this.wait = wait; + } + + public long getTime() { + return time; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public void fire() { + DigitalScheduler.get().incThreadCount(); + synchronized (wait) { + fired = true; + wait.notify(); + } + } + + public boolean isRandom() { + return false; + } + + public void sleepTil() throws InterruptedException { + try { + synchronized (wait) { + DigitalScheduler.get().addEvent(this); + DigitalScheduler.get().decThreadCount(); + while (!fired) { + wait.wait(); + } + } + } catch (InterruptedException e) { + DigitalScheduler.get().removeEvent(this); + throw e; + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim-readlineonly.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim-readlineonly.package new file mode 100644 index 0000000000..57f7788957 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim-readlineonly.package @@ -0,0 +1,9 @@ +2 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +share/java/dsim.jar dsim.jar 664 +$arch/bin/jdsim.sh jdsim.sh 664 +$arch/lib/libReadline.so ../../util/readline/libReadline.so 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim.package new file mode 100644 index 0000000000..995d074d1e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/dsim.package @@ -0,0 +1,14 @@ +2 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.tools.dsim.DSimMain com.avlsi.tools.dsim.DSim +include ../../csp/csp2java/runtime/cspruntime.package.inc ../../csp/csp2java/runtime +include ../../csp/resources/resources.package.inc ../../csp/resources +include ../../util/cmdline/cmdline.package.inc ../../util/cmdline +include ../../util/readline/readline.package.inc ../../util/readline +include ../tsim/channellib.package ../tsim +java com.avlsi.tools.cell.CellConstants +$arch/bin/jdsim.sh jdsim.sh 664 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/javafiles-custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/javafiles-custom.mk new file mode 100644 index 0000000000..b12690a9ab --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/dsim/javafiles-custom.mk @@ -0,0 +1,18 @@ +$(CURR_TARGET_DIR)/DSimMain.java_files_classbuild $(CURR_TARGET_DIR)/DSim.java_files_classbuild: $(call CONONICALIZE_PATH,$(CURR_TARGET_DIR)/../../util/cmdline/javaclasses) + +$(CURR_TARGET_DIR)/DSimMain.java_files_classbuild $(CURR_TARGET_DIR)/DSim.java_files_classbuild: $(call CONONICALIZE_PATH,$(CURR_TARGET_DIR)/../../csp/csp2java/runtime/javaclasses) + +JAVAFILES_EXTRA_JAR_CLASSES := $(wildcard $(CURR_PROJECT_DIR)/../../util/cmdline/*.java) $(wildcard $(CURR_PROJECT_DIR)/../../csp/csp2java/runtime/*.java) + + +CURR_RESULT_FILES := $(CURR_RESULT_FILES) $(CURR_TARGET_DIR)/jdsim.sh + +ifeq ($(MAKEFILE_MACHINE_TYPE),x86_64) +$(CURR_TARGET_DIR)/jdsim.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.dsim.DSimMain/" -e "s/\\\$$libs_to_preload\\\$$/\/usr\/lib64\/libncurses.so/" >$@ +else +$(CURR_TARGET_DIR)/jdsim.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.dsim.DSimMain/" -e "s/\\\$$libs_to_preload\\\$$/\/usr\/lib\/libncurses.so/" >$@ +endif diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2aspice/Ext2Aspice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2aspice/Ext2Aspice.java new file mode 100644 index 0000000000..8f04cbfcbb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2aspice/Ext2Aspice.java @@ -0,0 +1,422 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.ext2aspice; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + + +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.aspice.Diode; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.file.common.Capacitor; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.ext.ExtCell; +import com.avlsi.file.ext.FET; +import com.avlsi.file.ext.Node; +import com.avlsi.file.ext.Terminal; +import com.avlsi.file.ext.parse.ExtParser; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.text.StringUtil; + + +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +/** + * This class converts produces a .aspice file from a .ext file + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Ext2Aspice { + /** + * ExtCell being converted. + **/ + private final ExtCell ext; + + /** + * AspiceFile being constructed from ExtCell. + **/ + private final AspiceFile aspiceFile; + + /** + * The global repository for subcell definitions. + **/ + private final Map subcellNameToDefnMap; + + /** + * Static method to convert an ExtCell into an AspiceFile + * @design jmr XXX deprecate this? + **/ + public static AspiceFile ext2aspice(final ExtCell ext) { + return new Ext2Aspice(ext).convert(); + } + + /** + * Static method to convert an ExtCell into an AspiceFile + **/ + public static AspiceFile ext2aspice(final ExtCell ext, + final Map subcellNameToDefnMap) + { + return new Ext2Aspice(ext, subcellNameToDefnMap).convert(); + } + + /** + * Class constructor. Initializes a blank AspiceFile with the + * correct name. + * @design jmr XXX deprecate this? + **/ + private Ext2Aspice(final ExtCell ext) { + this(ext, new TreeMap()); + } + + /** + * Class constructor. Initializes a blank AspiceFile with the + * correct name. + **/ + private Ext2Aspice(final ExtCell ext, final Map subcellNameToDefnMap) { + this.ext = ext; + aspiceFile = new AspiceFile(ext.getName(), subcellNameToDefnMap); + this.subcellNameToDefnMap = subcellNameToDefnMap; + } + + /** + * If nodeName is already in diodeNodeToWidthMap, adds width + * the the value in the map; if it is not there, put it in. + * + * @param diodeNodeToWidthMap map of String to double[], mapping + * node names of diodes to their width. The given width will + * be added to nodeName's entry in this map. This use of + * double[] is because of Java's lack of ref cells. + * @param nodeName the name of the diode node + * @param width the width of nodeName + * + * @see #convert + **/ + private void addDiodeWidth(final Map diodeNodeToWidthMap, + final HierName nodeName, + final double width) + { + final double[] d = (double[]) diodeNodeToWidthMap.get(nodeName); + + if (d == null) + diodeNodeToWidthMap.put(nodeName, new double[]{width}); + else + d[0] += width; + } + + /** + * If nodeName is in diodeNodeToWidthMap, returns it width, otherwise + * returns 0.0. + * + * @see #convert + **/ + private double getDiodeWidth(final Map diodeNodeToWidthMap, + final HierName nodeName) + { + final double[] d = (double[]) diodeNodeToWidthMap.get(nodeName); + return d == null ? 0.0 : d[0]; + } + + /** + * Converts /'s in name to .'s, leaving .'s alone. This is + * a no-op because HierName can do everything in its + * getAsString(separator) method. + * @design jmr change to handle global!ext? instead of in + * parse stage? + **/ + private HierName convertName(final HierName name) { + return name; + } + + /** + * Convert the stored aspice file, and return it. Calling + * this more than once will be very, very bad. + **/ + private AspiceFile convert() { + // algorithm to convert ext -> aspice + // for each fet(area,perim,{source,drain,gate}.length): + // make a transistor + // record length of source/drain for use by diodes + // aspice transistors have (width,length) + // for each node({pdiode,ndiode}.{area,perim}): + // make a pdiode w/ area/perim given by resist class iDiodeType + // make an ndiode w/ area/perim given by resist class iDiodeType + // aspice diodes have (width,length,area,perim) + // the width / length are obtained as follows: + // width: sum of widths of adjacent transistors, + // (this is actually calculated in the fet loop, for + // efficiency) + // length: 0.0, as it doesn't matter + // for each cap(cap): + // make a cap + // aspice caps have (cap) + + // we will always use the canonical name for a node when + // converting to AspiceFile + // XXX what about connections to subcells? + + // convert subcells + // for all subcells of this cell, + // convert that subcell if its type was not already converted + // add the converted subcell + for (Iterator iSubcellName = ext.getSubcellNames(); + iSubcellName.hasNext(); ) + { + // no conversion of type names in needed for ext vs aspice + + final String name = (String) iSubcellName.next(); + final String type = ext.getSubcellTypeForName(name); + + AspiceFile sub = (AspiceFile) subcellNameToDefnMap.get(type); + + if (sub == null) { + // the type has not been converted, so convert it + sub = ext2aspice(ext.getSubcellDefForName(name), + subcellNameToDefnMap); + // conversion will add the file to subcellNameToDefnMap + } + + // add the converted cell to the list of subcells + aspiceFile.addSubcell(name, sub); + } + + // array indexed by fet type of maps from diode name to width + // along the fet + // @bug jmr XXX does this deal with different names for + // the same node correctly? + final Map[] diodeNodeToWidthMapArr + = new Map[]{new HashMap(), new HashMap()}; + + // fets + for (final Iterator ifets = ext.getFETs(); ifets.hasNext(); ) { + final FET fet = (FET) ifets.next(); + + final int type = fet.getType(); + final HierName source = convertName(ext.getCanonicalName( + fet.getSource().getConnectingNode())); + final HierName drain = convertName(ext.getCanonicalName( + fet.getDrain().getConnectingNode())); + final HierName gate = convertName(ext.getCanonicalName( + fet.getGate().getConnectingNode())); + final HierName bulk = convertName(ext.getCanonicalName( + fet.getSubstrateNode())); + + // width / length computation + // ext files provide: + // a = gate area + // p = gate perimeter + // pg = gate portion of perimeter + // ps = source portion of perimeter + // pd = drain portion of perimeter + // where p = pg + ps + pd + // aspice files use: + // width & length, where these are not clearly specified + + // we will use + // w = (ps + pd) / 2 + // l = a / w + // this matches the definition in Andrew's old ext2aspice + + final double a = fet.getArea(); + final double ps = fet.getSource().getLength(); + final double pd = fet.getDrain().getLength(); + + final double w = (ps + pd) / 2.0; + final double l = a / w; + + aspiceFile.addTransistor(new Transistor(type, source, drain, + gate, bulk, w, l)); + + // accumulate length along source/drain for use in creating + // diodes + addDiodeWidth(diodeNodeToWidthMapArr[type], source, ps); + addDiodeWidth(diodeNodeToWidthMapArr[type], drain, pd); + } + + // Jikes is broken. But it compiles fast. This lets + // us compile with jikes, which we really want to do. + // Hopefully we can take this out in a later version. + HierName jikesGND, jikesVdd; + try { + jikesGND = HierName.makeHierName("GND!", '.'); + jikesVdd = HierName.makeHierName("Vdd!", '.'); + } catch (InvalidHierNameException e) { + throw new AssertionFailure(e); + } + + // Names of nodes for diode drains + final HierName GND = jikesGND, Vdd = jikesVdd; + + final HierName[] diodeDrains = new HierName[]{GND, Vdd}; + + // nodes + for (final Iterator iNode = ext.getNodes(); iNode.hasNext(); ) { + final Node node = (Node) iNode.next(); + final HierName extSource = ext.getCanonicalName(node.getName()); + final HierName source = convertName(extSource); + + // create diode if non-zero area/perim + for (int iDiodeType = 0; iDiodeType < 2; ++iDiodeType) { + final double area = node.getAreaForResistClass(iDiodeType); + final double perim = node.getPerimForResistClass(iDiodeType); + + if (area > 0.0 || perim > 0.0) { + // length is 0.0 to indicate it is meaningless, + // aspice will make one up + + // width is sum of widths of connecting transistors + + aspiceFile.addDiode(new Diode(iDiodeType, source, + diodeDrains[iDiodeType], + getDiodeWidth( + diodeNodeToWidthMapArr[iDiodeType], + source), + 0.0, area, perim)); + } + } + + // create cap to ground + final double capToGnd = node.getCapacitanceToGround(); + + // add cap unless the nodes are equivalent or there is none + if (capToGnd != 0.0 && !ext.areEquivalent(source, GND)) + aspiceFile.addCapacitor( + new Capacitor(source, GND, capToGnd)); + + // namespace: aliases within the subcell + // and connections between cell/sub & sub/sub + // both are handled, as we don't treat subcell names specially + aspiceFile.addName(source); + for (final Iterator iEquivNames + = ext.getEquivalentNames(extSource); + iEquivNames.hasNext(); ) { + final HierName name2 = (HierName) iEquivNames.next(); + + aspiceFile.connectNames(source, convertName(name2)); + } + } + + // add node to node caps, caps to ground have already been added + // @todo like caps should be merged + for (final Iterator iCap = ext.getCapacitors(); iCap.hasNext(); ) { + // change names for aspice + final Capacitor cap = (Capacitor) iCap.next(); + final HierName s + = convertName(ext.getCanonicalName(cap.getSource())); + final HierName d + = convertName(ext.getCanonicalName(cap.getDrain())); + + // add cap unless the nodes are equivalent + if (!ext.areEquivalent(s, d)) + aspiceFile.addCapacitor(new Capacitor(s, d, cap.getCap())); + } + + // resistors + + // now that the file has been converted, add it to the global + // repository + subcellNameToDefnMap.put(aspiceFile.getName(), aspiceFile); + + return aspiceFile; + } + + /** + * Prints usage message, then exits with status + * exitStatus. + **/ + private static void usage(int exitStatus) { + final String usageStr = "Usage:" + + " [--ext-path=extractpath]" + + " cellName"; + + System.err.println(usageStr); + System.exit(exitStatus); + } + + /** + * Convert a .ext file into a .aspice file. + * @param args an array of one string: the cellname to use + * the .ext file will be loaded from cellname.ext + **/ + public static void main(String[] args) + //throws Exception + { + if (args.length != 1) + usage(1); + + + CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + CommandLineArgs theArgs = cachedArgs; + + String cellName = null; + + { + StringContainerIterator strIter = theArgs.nonParsedArgumentsIterator(); + if ( strIter.hasNext() ) { + cellName = strIter.next(); + } + else { + usage(1); + } + } + final String aspiceFileName = cellName + ".aspice"; + + try { + final FileSearchPath fsp = new FileSearchPath( theArgs.getArgValue("ext-path","."), + System.getProperty( "user.home" ) ); + System.out.println("EXT_PATH is " + fsp.getSearchPathString()); + + final OutputStream os + = new FileOutputStream(aspiceFileName); + + System.out.println("Parsing .ext files ..."); + final ExtCell ext = ExtParser.parse(cellName, fsp, true); + + System.out.println("Building aspice structure ..."); + final AspiceFile af = ext2aspice(ext); + + System.out.println("Writing " + aspiceFileName + " ..."); + af.printToStream(os); + + System.out.println("Done."); + } catch (Exception e) { + e.printStackTrace(); + System.err.println(e + ": " + e.getMessage()); + System.exit(1); + } + + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2cdl/Ext2Cdl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2cdl/Ext2Cdl.java new file mode 100644 index 0000000000..d3bd6c0e15 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ext2cdl/Ext2Cdl.java @@ -0,0 +1,215 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.ext2cdl; + +import java.util.Iterator; + +import java.io.PrintWriter; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.text.MessageFormat; + + +import com.avlsi.util.debug.Debug ; + +import com.avlsi.file.ext.ExtCell; +import com.avlsi.file.ext.FET; +import com.avlsi.file.ext.parse.ExtParser; +import com.avlsi.io.FileSearchPath; +import com.avlsi.file.common.DeviceTypes; +import java.util.Map; +import java.util.Iterator; +import com.avlsi.tools.cadencize.CadenceDataInterface; +import java.util.TreeSet; +import java.util.Set; +import java.util.SortedSet; + + +/** + * Extracts list of fets from a .ext file to be used for cadence's lvs. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class Ext2Cdl { + /** + * This class should not be instantiated. + **/ + private Ext2Cdl() { } + + static final double fuckermetersinlambda = 100000000.0 / 5 ; + private static void usage(final int exitStatus) { + System.err.println("Usage: " + + Ext2Cdl.class.getName() + " cell outputfilename"); + System.exit(exitStatus); + } + + private static double converttolambda( double d ) { + return ( d * fuckermetersinlambda ) ; + } + + + private static String makeSafeCellName( String cellName ) { + StringBuffer ret = new StringBuffer(); + + int j = 0; + + while( j < cellName.length() ){ + if ( cellName.charAt( j ) == '(' ) { + ret.append( "%40" ); + } + else if ( cellName.charAt( j ) == ')' ) { + ret.append( "%41" ); + } + else if ( cellName.charAt( j ) == ',' ) { + ret.append( "%44" ); + } + else { + ret.append( cellName.charAt( j ) ); + } + ++j ; + } + return ret.toString(); + } + + + public static void WriteCDL( final ExtCell ext, + PrintWriter out, + MessageFormat FETFormat, + CadenceDataInterface cadData ) { + int FETCount ; + FETCount = 0 ; + + SortedSet SortedNetNames = cadData.GetExportedNets(); + + + Iterator pCurrNetName = SortedNetNames.iterator(); + out.println( "*.GLOBAL Vdd!:p GND!:g _SReset!:p _PReset!:p" ) ; + out.print( ".SUBCKT " ); + out.print( cadData.GetCellUnitName() ); + out.print( "-" ); + out.print( makeSafeCellName(cadData.GetCellSubType()) ); + out.print( " / " ); + + while ( pCurrNetName.hasNext() ) { + String CurrNetName = ( String ) pCurrNetName.next(); + out.print( CurrNetName ); + if ( pCurrNetName.hasNext() ) { + out.println(); + out.print( "+ " ); + } + } + + out.println( " " ); + + if ( ext != null ) { + + for (final Iterator iFET = ext.getFETs(); iFET.hasNext(); ) { + final FET fet = (FET) iFET.next(); + + final String gateNet = + ext.getCanonicalName(fet.getGate().getConnectingNode()) + .getCadenceString(); + final String sourceNet = + ext.getCanonicalName(fet.getSource().getConnectingNode()) + .getCadenceString(); + final String drainNet = + ext.getCanonicalName(fet.getDrain().getConnectingNode()) + .getCadenceString(); + + String BulkNet ; + String ModelNameRef ; + + Debug.assertTrue( ( fet.getType() == DeviceTypes.N_TYPE ) || + ( fet.getType() == DeviceTypes.P_TYPE ) ) ; + + switch ( fet.getType() ) { + case DeviceTypes.N_TYPE: + BulkNet = new String( "GND!" ) ; + ModelNameRef = new String( "N" ) ; + break; + case DeviceTypes.P_TYPE: + BulkNet = new String( "Vdd!" ) ; + ModelNameRef = new String ( "P" ) ; + break; + default: + BulkNet = null; + ModelNameRef = null; + break; + } + + Object[] FETArguments = { + new Integer( FETCount ), + drainNet, + gateNet, + sourceNet, + BulkNet, + ModelNameRef, + new Double( converttolambda(fet.getDrain().getLength()) ), + new Double( converttolambda(fet.getGate().getLength()) / 2.0 ) + }; + + ++FETCount ; + + out.println( FETFormat.format( FETArguments ) ) ; + + } + } + + Iterator pCurrInstanceName = cadData.GetInstanceNames().iterator(); + + //Print out subcircuit calls for all subcells in the cell. + while ( pCurrInstanceName.hasNext() ) { + String CurrInstanceName = ( String ) pCurrInstanceName.next(); + //print out instance name with X prepended. + out.print( "X" ); + out.print( CurrInstanceName ); + + out.print( " " ); + + //Get a list of nets in the subcell we are connecting to. + //We want them sorted so we can output them in the same order as + //the were in the sub circuit definition. + SortedSet CurrSubCellNets = cadData.GetSubCellNets( CurrInstanceName ); + + //If the sub cell has connections... + if ( CurrSubCellNets != null ) { + + //Output all the nets in this cell that connect to the subcell. + Iterator pCurrSubCellNet = CurrSubCellNets.iterator(); + + while ( pCurrSubCellNet.hasNext() ){ + String CurrSubCellNet = ( String ) pCurrSubCellNet.next() ; + String CurrConnectedNet = + cadData.GetSubCellConnection( CurrInstanceName, + CurrSubCellNet ) ; + if ( CurrConnectedNet != null ) { + out.print( CurrConnectedNet ) ; + if ( pCurrSubCellNet.hasNext() ) { + out.println(); + out.print( "+ " ); + } + } + } + } + out.print( " / " ); + out.println( makeSafeCellName( cadData.GetInstanceSubType( CurrInstanceName ) ) ); + } + + out.println( ".ENDS" ); + + out.flush(); + + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Edge.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Edge.java new file mode 100644 index 0000000000..59b477f4f3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Edge.java @@ -0,0 +1,204 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import java.util.LinkedList; +import java.util.Hashtable; + +import com.avlsi.tools.ilg.Util; +import com.avlsi.tools.ilg.ILG; +import com.avlsi.tools.ilg.Poly; +import com.avlsi.tools.ilg.Layer; +import com.avlsi.tools.ilg.SortedEdges; +import com.avlsi.tools.ilg.Span; +import com.avlsi.tools.ilg.SpanList; +import com.avlsi.tools.ilg.PolyOperator; +import com.avlsi.tools.ilg.PlugEntry; +import com.avlsi.tools.ilg.WellPlugData; + +/** A convienience class to treat a Poly as a list of edges. + Completely depends on the data in the Poly class. **/ +public class Edge { + /** The poly we came from. **/ + public Poly p; + /** Vertex index and direction for the edge **/ + public int index, dir; + public Edge(Poly poly, int i) { + p = poly; + index=i; + dir=CalcDir(); + } + /** Print debugging info. **/ + public void Dump() { + boolean hor=Util.DirIsHorizontal(dir); + Point p=P0(); + System.out.print((hor?"Horiz":"Vert ")+" edge "); + System.out.print("("+p.x+" "+p.y+") "); + p=P1(); + System.out.print("("+p.x+" "+p.y+") "); + System.out.println("length "+Length()); + } + /** Returns initial point. **/ + public Point P0() { return p.Get(index); } + /** Returns final point. **/ + public Point P1() { return p.Get((index+1) % p.Size()); } + /** Returns the next edge in the poly with wrapping. **/ + public Edge NextEdge() { return p.GetEdge((index+1) % p.Size()); } + /** Returns the previous edge in the poly with wrapping. **/ + public Edge PrevEdge() { return p.GetEdge((index-1+p.Size()) % p.Size()); } + /** The positive (or 0) length of the line. **/ + public int Length() { return Util.LineLength(P0(), P1()); } + /** Returns the direction of the line **/ + public int CalcDir() { return Util.GetLineDir(P0(), P1()); } + /** Updates the direction of the line **/ + public boolean UpdateDir() { + int oldDir=dir; + dir=CalcDir(); + return dir!=oldDir; + } + //public boolean UpdateNeighbors() { + // boolean cur, did = false; + // int pSz=p.Size(); + // cur=p.GetEdge((index-1+pSz) % pSz).UpdateDir(); + // did=cur||did; + // cur=p.GetEdge((index+1+pSz) % pSz).UpdateDir(); + // did=cur||did; + // return did; + //} + /** The minimum x value on the edge. **/ + public int GetX() { return Math.min(P0().x, P1().x); } + /** The minimum y value on the edge. **/ + public int GetY() { return Math.min(P0().y, P1().y); } + /** The maximum x value on the edge. **/ + public int GetMaxX() { return Math.max(P0().x, P1().x); } + /** The maximum y value on the edge. **/ + public int GetMaxY() { return Math.max(P0().y, P1().y); } + /** The distance of the edge from the parallel axis. **/ + public int GetIndexAxis() { return Util.DirIsHorizontal(dir) ? GetY() : GetX(); } + /** The minimum distance of the edge from the perpendicular axis. **/ + public int GetMin() { return Util.DirIsHorizontal(dir) ? GetX() : GetY(); } + /** The maximum distance of the edge from the perpendicular axis. **/ + public int GetMax() { return Util.DirIsHorizontal(dir) ? GetMaxX() : GetMaxY(); } + /** The midpoint of the line **/ + public int GetMid() { return (GetMin()+GetMax())/2; } + /** If two edges overlap. **/ + public boolean Spans(Edge e) { + if (Util.DirIsHorizontal(dir)==Util.DirIsHorizontal(e.dir)) { + if (Util.DirIsHorizontal(dir)) { + return Util.SpansOverlap(P0().x, P1().x, e.P0().x, e.P1().x); + } else { + return Util.SpansOverlap(P0().y, P1().y, e.P0().y, e.P1().y); + } + } else { System.out.println("Checking span on orthogonal edges."); } + + return false; + } + /** Cuts an edge along its axis at point d. Returns new edge. **/ + public Edge SplitAt(int d) { + boolean hor=Util.DirIsHorizontal(dir); + Edge ne = this; + if (hor) { + if ((d!=GetX()) && (d!=GetMaxX())) { + ne = new Edge(p, index); + p.Insert(index+1, new Point(d, GetY()), ne); + } + } else { + if ((d!=GetY()) && (d!=GetMaxY())) { + ne = new Edge(p, index); + p.Insert(index+1, new Point(GetX(), d), ne); + } + } + return ne; + } + /** Inserts a completely new edge, so that prev or next can grow + * and still leave orthogonal edges. **/ + public Edge DoubleSplitAt(int d) { + boolean hor=Util.DirIsHorizontal(dir); + Edge ne = this; + if (hor) { + if ((d!=GetX()) && (d!=GetMaxX())) { + ne = new Edge(p, index); + p.Insert(index+1, new Point(d, GetY()), ne); + ne = new Edge(p, index); + p.Insert(index+1, new Point(d, GetY()), ne); + } + } else { + if ((d!=GetY()) && (d!=GetMaxY())) { + ne = new Edge(p, index); + p.Insert(index+1, new Point(GetX(), d), ne); + ne = new Edge(p, index); + p.Insert(index+1, new Point(GetX(), d), ne); + } + } + return ne; + } + /** Cuts an edge so it can flow around another edge. Returns the cut edges. **/ + Vector SplitOnBarrier(Edge bar) { + boolean hor=Util.DirIsHorizontal(dir); + Vector ret = new Vector(); + int e0, e1, b0, b1; + Edge ne; + if (hor) { + e0=GetX(); e1=GetMaxX(); + b0=bar.GetX(); b1=bar.GetMaxX(); + } else { + e0=GetY(); e1=GetMaxY(); + b0=bar.GetY(); b1=bar.GetMaxY(); + } + if (b1e0) { +//System.out.println(" Split LO "+b0+(hor?" Hor":" Vert")); + DoubleSplitAt(b0); + ne = NextEdge(); + ret.add(ne); + ret.add(ne.NextEdge()); + } + return ret; + } + /** Grows an edge in a given distance. Dist should be perpendicular to the edge. **/ + public boolean Grow(int dist) { + int x=0, y=0; + if (dir==0) { y=-dist; } + if (dir==1) { x=dist; } + if (dir==2) { y=dist; } + if (dir==3) { x=-dist; } + Point cp=P0(); + cp.x+=x; cp.y+=y; + cp=P1(); + cp.x+=x; cp.y+=y; + return true; + } + /** Removes this edge and returns true, if it is coincident or colinear with a neighbor. **/ + public boolean DeleteIfDegenerate() { + // delete any inline points/edges.. + // i.e. zero length or neighboring edge angle is 0 or 180 + int pSz=p.Size(); + Edge prev=p.GetEdge((index-1+pSz) % pSz); + prev.UpdateDir(); + UpdateDir(); + int prevDir=prev.dir; + if ((Length()==0) || (Util.DirIsHorizontal(dir)==Util.DirIsHorizontal(prevDir))){ +//System.out.println("Degenerate edge deleted"); + dir=-1; + p.Delete(index); + return true; + } + return false; + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/GA.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/GA.java new file mode 100644 index 0000000000..ac965639f0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/GA.java @@ -0,0 +1,146 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + +import java.util.*; +import java.util.Random; + +import com.avlsi.tools.ilg.SortableVector; + +public class GA { + public interface GeneEvaluator { + float GetFitness(Gene g); + } + public static Random rand = new Random(); + + // popSize must be a multiple of 2 greater than 2 + public int popSize=50; + public float mutationRate=(float).03, crossoverRate=(float).67, elitism=(float).33; + public SortableVector population = new SortableVector(); + // NOTE: THESE SHOULD GET SET + int geneSize=20, geneMaxIndex=1000; + GeneEvaluator evaluator = null; + + public void Clear() { population.clear(); } + public void Populate(int _geneSize, int _geneMaxIndex) { + population.clear(); + population.ensureCapacity(popSize); + geneSize=_geneSize; geneMaxIndex=_geneMaxIndex; + int delta = geneSize*2; +System.out.println("Creating population"); +System.out.println("POPULATE pop: "+popSize+", geneSz: "+geneSize+", delta: "+delta); + for (int i=popSize-1; i>=0; i--) { + Gene g = new Gene(geneSize+rand.nextInt(delta), geneMaxIndex); + float fitness = g.Fitness(); +//System.out.println("Gene ("+(popSize-i)+"): "+fitness); + population.add(g); + } + population.Sort(); +System.out.println("Done Creating population ("+population.size()+" of "+popSize+" entries)"); + } + + // do one generation... + public void Step() { + SortableVector v = population; + population = new SortableVector(); + int len = v.size(); + int delta=(int)(len*elitism), start=len-delta; +//System.out.println("STEP pop: "+popSize+", len: "+len+", start: "+start+", delta: "+delta); + int dup=0; + // extreme eletism. always save 2 best genes... + population.add(v.elementAt(len-1)); + population.add(v.elementAt(len-2)); + for (int i=popSize-3; i>=0; i-=2) { +//System.out.print(" "+i); + Gene ga = new Gene((Gene)v.elementAt(start+rand.nextInt(delta))); + Gene gb = new Gene((Gene)v.elementAt(start+rand.nextInt(delta))); + if (rand.nextFloat()<=crossoverRate) { + ga.Cross(gb); + } + if (rand.nextFloat()<=mutationRate) { ga.Mutate(geneMaxIndex); } + if (rand.nextFloat()<=mutationRate) { gb.Mutate(geneMaxIndex); } + // recalculate fitness + ga.Fitness(); gb.Fitness(); + if (!population.add(ga)) { dup++; } + if (!population.add(gb)) { dup++; } + } + population.Sort(); +//System.out.println("Best Fitness is "+GetBest().fitness); +//System.out.println("Done with Step ("+population.size()+"-"+dup+" of "+popSize+" entries)"); + } + + public Gene GetBest() { return (Gene)population.elementAt(population.size()-1); } + + public class Gene implements Comparable { + public float fitness=0; + public int chrom[]; + + public Gene() {} + // random creation + public Gene(int size, int max) { + chrom = new int[size]; +//System.out.print("NEW Gene"+population.size()); + for (int i=size-1; i>=0; i--) { + chrom[i]=GA.rand.nextInt(max); +//System.out.print(" "+chrom[i]); + } +//System.out.println(); + } + public Gene(Gene g) { Copy(g); } + public float Fitness() { + fitness = evaluator.GetFitness(this); + return fitness; + } + public void Cross(Gene g) { + int i, len = chrom.length, lenb = g.chrom.length; + int site = GA.rand.nextInt(len); + int siteb = GA.rand.nextInt(lenb); + int tempa[] = new int[site+lenb-siteb]; + int tempb[] = new int[siteb+len-site]; + for (i=0; i=0; i--) { + chrom[i]=g.chrom[i]; + } + } + public int compareTo(Object o) { + int dif=0; + if (o instanceof Gene) { + Gene g = (Gene)o; + int length = chrom.length; + int glength = g.chrom.length; + if (g.fitness>fitness) { dif=-1; } + else if (g.fitnesslength) { dif= 1; } + else { + for (int i=length-1; i>=0; i--) { + if (g.chrom[i]>chrom[i]) { dif=-1; break; } + else if (g.chrom[i]=0; i--) { + Layer l = (Layer)layers.elementAt(i); + if ((l.name!=null) && l.name.equals(name)) { return l; } + } + return null; + } + + /** Grows and edge until it hits another (if possible). + * Returns true if any work is done. **/ + public boolean GrowEdge(Edge e, int max, Layer layer) { + int dir=Util.GetOutsideDir(e.dir); + //int dir=GetInsideDir(e.dir); + int dist = max; + if (Util.DirIsHorizontal(e.dir)) { + for (int l=0; l0) { + if (dist>max) { System.out.println("Bogus dist "+dist+" !"); dist=max; } + layer.Grow(e, dist); + //UpdateLayer(layer.index); + return true; + } + return false; + } + + /** Cleans degenerate edges and regenerates sorted edge data. **/ + public void UpdateLayer(int l) { + Layer layer=(Layer)layers.elementAt(l); + layer.Update(); + } + + /** Merges polygons (if possible). Returns true if any work is done. **/ + public boolean MergeLayer(int l) { + Layer layer=(Layer)layers.elementAt(l); + return layer.Merge(); + } + + /** Splits polygons (if possible). Returns true if any work is done. **/ + public boolean SplitLayer(int l) { + Layer layer=(Layer)layers.elementAt(l); + return layer.Split(); + } + + /** Grows indentations in polygons out (if possible). Returns true if any work is done. **/ + public boolean GrowNotches(int layer) { + boolean cur, did=false; + Layer curLayer = (Layer)layers.elementAt(layer); + //System.out.println("Growing Notches on: "+curLayer.name); + if (!curLayer.fixed) { + for (int p=0; p=0; l--) { + growable = growable || Growable(l); +if (Growable(l)) { System.out.println("Growable Layer "+l); } + } + if (!growable) { return false; } + Layer holes = new Layer(); + Poly base; + holes.name="holes"; + holes.index = layers.size(); + layers.addElement(holes); + for (int l=1; l=0; i--) { + Poly p = holes.Get(i); + if (p.Size()<3) { + holes.shapes.removeElementAt(i); + continue; + } +System.out.println("Filling hole "); +//p.Dump(System.out); + Edge e = p.GetEdge(0), e2, near; + //e.Dump(); + int len=e.Length(), len2; + // find longest edge + for (int j=1; j0; + } + /** Checks if a given layer should be grown. **/ + public boolean Growable(int l) { + return !((Layer)layers.elementAt(l)).fixed; + } + /** GrowNotches, grow sides, merge, fill holes, lather rinse, repeat... + * The main algorithm that turns messy well polygons into nice big rectangles + * (mostly). **/ + public void GrowAll() { + int len=layers.size(); + boolean growable = false; + for(int i=1; i=0; i--) { + ply = l.Get(i); + for (int j=ply.Size()-1; j>=0; j--) { + pt=ply.Get(j); + if (min==null) { + min=new Point(pt); + max=new Point(pt); + } else { + if (pt.xmax.x) { max.x=pt.x; } + if (pt.y>max.y) { max.y=pt.y; } + } + } +//System.out.println(" range is "+min+" to "+max); + Point tmp, orig = l.wellData.origin, spc = l.wellData.spacing; + min.x = ((int)((orig.x-min.x)/spc.x))*spc.x-orig.x; + min.y = ((int)((orig.y-min.y)/spc.y))*spc.y-orig.y; + for (int x=min.x; x<=max.x; x+=spc.x) { + for (int y=min.y; y<=max.y; y+=spc.y) { + tmp = new Point(x, y); + if (ply.PointInside(tmp)) { +//System.out.println(" plug at "+tmp); + points.add(tmp); + } + } + } + min=null; max=null; + } +System.out.println(" Done Getting Plug Points ("+points.size()+")"); + return points; + } + + public class GeneInterface implements GA.GeneEvaluator { + //public Layer plugLayer = null; + public Vector plugEntries=null; + public long wellArea = 0; + public int wellpolys = 0; + public long plugArea = 0; + int minPlugs = 0; + + public float GetFitness(GA.Gene g) { + Layer l = new Layer(); + PlugEntry pe; + long plugArea=0, covArea=0; + int numPlugs = g.chrom.length; + for (int i=numPlugs-1; i>=0; i--) { +//System.out.print(" "+g.chrom[i]); + pe = (PlugEntry)plugEntries.elementAt(g.chrom[i]); + plugArea+=pe.area; + for (int j=pe.polys.size()-1; j>=0; j--) { + l.Add((Poly)pe.polys.elementAt(j)); + } + } + l = (new PolyOperator()).CombineLayers(PolyOperator.OR, l, l); + covArea = l.Area(); + float fitness = (float)((covArea/(float)wellArea)*(.9+.1*minPlugs/(1+numPlugs))); +//System.out.println("Fitness: "+fitness+" covArea: "+covArea+" wellArea: "+wellArea+" numPlugs: "+numPlugs); + return fitness; + } + + public Vector Run() { + GA ga = new GA(); + minPlugs=Math.max(1, (int)(.5+wellArea/plugArea)); + minPlugs=Math.max(minPlugs, wellpolys); +System.out.println("GI.RUN minPlugs: "+minPlugs+", wellArea: "+wellArea+", plugArea: "+plugArea); + //ga.mutationRate=.01; ga.crossoverRate=.75; ga.elitism=.33; + ga.evaluator = this; + //.... do stuff + ga.Populate(minPlugs, plugEntries.size()); + for (int i=0; i<170; i++) { +if ((i%10)==0) { System.out.println("GI.STEP : Best Fitness is "+ga.GetBest().fitness);} + ga.Step(); + } + GA.Gene best = ga.GetBest(); + // avoid garbage collection cycle + ga.evaluator = this; + Vector results = new Vector(); + int numPlugs = best.chrom.length; + for (int i=numPlugs-1; i>=0; i--) { + results.add(plugEntries.elementAt(best.chrom[i])); + } + return results; + } + } + + /** Chooses semi-optimal set of plugs given the plug layer. **/ + public void ProcessPlugLayer(Layer l, boolean linear) { + if (l.wellData!=null) { + Vector points = GetAllPlugEntries(l); + // scale down by square root of 2 to compensate for square growth + int dist = (int)(l.wellData.covDist/1.4142135623731); + int spacing = Math.max(l.wellData.size.x, l.wellData.size.y); + Vector plugs = null; + if (linear) { + plugs = CalcPlugsOpt(points, spacing); + } else { + GeneInterface gi = new GeneInterface(); + Layer well = GetLayerByName(l.wellData.wellName); + gi.wellArea = well.Area(); + gi.plugArea = 4*dist*dist; + gi.plugEntries = points; + gi.wellpolys = well.Size(); + plugs = gi.Run(); + + } + l.plugEntries = plugs; + } + } + + public Vector GetAllPlugEntries(Layer l) { + Vector entries = null; + if (l.wellData!=null) { + entries = new Vector(); + Layer well = GetLayerByName(l.wellData.wellName); + Layer plugLyr = (new PolyOperator()).CombineLayers(PolyOperator.AND, well, l); + plugLyr.wellData = l.wellData; + Vector points = GetAllPlugPoints(plugLyr); + // scale down by square root of 2 to compensate for square growth + int dist = (int)(l.wellData.covDist/1.4142135623731); + well = (new PolyOperator()).CombineLayers(PolyOperator.SEP, well, well); +System.out.println(" Growing Plugs"); + Point at; + for(int i=0; i0) && (pickDist>spacing)) { + tempEntries.add(cur); +//System.out.println("Re-Adding Point at "+cur.at.x+","+cur.at.y+" area: "+cur.area); + } + } + // force a re-shuffling now that the areas have completely changed + entries.clear(); + entries.addAll(tempEntries); + } + // should we return unplugged well polys at some point? +System.out.println(" finished plugging "+results.size()+" plugs used covering area "+area); + return results; + } + /** Given a list of plug points, chooses a semi-optimal set. + * First the coverage is calculated for all, + * then the highest area one is chosed, and overlaps are lazily removed. + * Lather, rinse, repeat... + * returns a list of PlugEntries. **/ + public Vector CalcPlugsOpt(Vector plugEntries, int spacing) { + // split all holes from polys and add as seperate polys + // copy l to temp layer (to handle FAKE (double) edges) + SortableVector entries = new SortableVector(plugEntries); + SortableVector outdated = new SortableVector(); + Vector results = new Vector(); + int i, area = 0, elast; + Point at; + PlugEntry hi = null, cur; + Layer covLyr = new Layer(), hiLyr = new Layer(), tmpLyr = new Layer(); + while (!entries.isEmpty()) { + entries.Sort(); + elast = entries.size()-1; + // chose highest area + hi = (PlugEntry)entries.elementAt(elast); +//System.out.println(" Picked plug sized "+hi.area+" at "+hi.at); + results.add(hi); + entries.remove(elast); + area+=hi.area; + tmpLyr.Clear(); + hi.ExportPolys(tmpLyr); + hiLyr = (new PolyOperator()).CombineLayers(PolyOperator.OR, tmpLyr, hiLyr); + outdated.addAll(entries); entries.clear(); + // remove entries that violate spacing.. + for (i=outdated.size()-1; i>=0; i--) { + cur = (PlugEntry)outdated.elementAt(i); + int pickDist = Math.max(Math.abs(hi.at.x-cur.at.x), Math.abs(hi.at.y-cur.at.y)); + if (pickDist=0; i--) { + cur = (PlugEntry)outdated.elementAt(i); + if (bestArea>cur.area) { + // sorted, so no remaining entries can be better + break; + } + outdated.remove(i); + cur.ExportPolys(tmpLyr); + tmpLyr = (new PolyOperator()).CombineLayers(PolyOperator.ANDNOT, tmpLyr, hiLyr); + cur.ImportPolys(tmpLyr); + tmpLyr.Clear(); + if (cur.area>0) { + if (bestArea=0; i--) { + Layer l = (Layer)layers.elementAt(i); + if (l.wellData!=null) { +System.out.println("Found Plug layer "+l.name+" for "+l.wellData.wellName); + ProcessPlugLayer(l, true); + // export Polys + if ((window!=null) && (l.plugEntries!=null)) { + for (int j=0; j=0; k--) { + outLayer.Add((Poly)pe.polys.elementAt(k)); + } + } + window.repaint(); + } +System.out.println("Done with layer "+l.wellData.wellName+" ("+(l.plugEntries!=null?l.plugEntries.size():0)+" plugs used)"); + } + } + if (window!=null) { window.repaint(); } +System.out.println("Done Chosing plugs"); + } + + /** Class that scales Polys and turns them into a format used by the + * gui polygon drawing routines. **/ + public class MultiPoly { + int x[], y[], l; + public MultiPoly(Poly p) { + l=p.Size(); x=new int[l]; y=new int[l]; + for (int i=0; i=0) && (end.x<=w) && (end.y>=0) && (end.y<=h)) { + float x0, x1, y0, y1, mag; + x0=Math.min((int)dbs.x, (int)dbe.x); + x1=Math.max((int)dbs.x, (int)dbe.x); + y0=Math.min((int)dbs.y, (int)dbe.y); + y1=Math.max((int)dbs.y, (int)dbe.y); + if (!drawMode) { + xoff=-(x1+x0)/2; yoff=-(y1+y0)/2; + mag = Math.max( (x1-x0)/w, (y1-y0)/h ); + ymag=-mag; xmag=mag; + repaint(); + System.out.println("Mag: "+xmag+","+ymag+" Off: "+xoff+","+yoff); + } else { + Layer dlayer = (Layer)layers.elementAt(cur); + // add rectangle + Poly poly = new Poly(); + poly.Insert(0, new Point((int)x0, (int)y0), null); + poly.Insert(1, new Point((int)x1, (int)y0), null); + poly.Insert(2, new Point((int)x1, (int)y1), null); + poly.Insert(3, new Point((int)x0, (int)y1), null); + //poly.Insert(4, new Point((int)x0, (int)y0), null); + dlayer.Add(poly); + repaint(); + System.out.println("rect: "+x0+","+y0+" Off: "+x1+","+y1); + } + } + } + }); + addMouseMotionListener( new MouseMotionListener () { + public void mouseDragged (MouseEvent e) { + } + public void mouseMoved (MouseEvent e) { + SetMousePos(e.getPoint()); + } + }); + } + /** Force our size. **/ + public Dimension getMinimumSize() { + return new Dimension((int)xsz, (int)ysz); + } + public Dimension getPreferredSize() { + //if (window.getSize()!=null) { + // return window.getSize(); + //} else { + return new Dimension((int)xsz, (int)ysz); + //} + } + public void ClearLayer(int l) { + Layer lyr = (Layer)layers.elementAt(l); + lyr.Clear(); + } + /** Perform a boolean operation on layers. **/ + public void CombineLayers(int oper, int a, int b, int out) { + PolyOperator pOper = new PolyOperator(); + Layer la = (Layer)layers.elementAt(a); + Layer lb = (Layer)layers.elementAt(b); + Layer lOut=pOper.CombineLayers(oper, la, lb); + lOut.name=((Layer)layers.elementAt(out)).name; + layers.set(out, lOut); + } + /** Draw the coverage polygon at the current mouse position. **/ + public void GrowPlug() { + Layer inLayer = (Layer)layers.elementAt(src1); + Layer outLayer = new Layer(); + layers.set(dst, outLayer); + Poly p = inLayer.SquareGrowFromPoint(userToDB(mousePos), 212); + outLayer.Add(p); + repaint(); + } + /** Convert lambda to screen coordinates. **/ + public Point dbToUser(Point pt) { + int w=getSize().width, h=getSize().height; + return new Point( + (int)((pt.x-xoff)*xmag)+w/2, + (int)((pt.y-yoff)*ymag)+h/2 + ); + } + /** Convert screen coordinates to lambda. **/ + public Point userToDB(Point pt) { + int w=getSize().width, h=getSize().height; + return new Point( + (int)((pt.x-(w/2))/xmag+xoff), + (int)((pt.y-(h/2))/ymag+yoff) + ); + } + public void SetMousePos(Point pt) { + mousePos = pt; + UpdateStatusBar(); + HiliteSelection(); + } + public void HiliteSelection() { + Poly oldHilite = hilite; + hilite = null; + Point pt = userToDB(mousePos); + Layer layer = (Layer)layers.elementAt(cur); + for (int i=layer.Size()-1; i>=0; i--) { + Poly pol = layer.Get(i); + if (pol.PointInside(pt)) { hilite=pol; } + } + if (oldHilite!=hilite) { repaint(); } + } + /** Prints current input/output layers, mouse position, and draw mode. **/ + public void UpdateStatusBar() { + Point upt = userToDB(mousePos); + HiliteSelection(); + String hi = new String(); + if (hilite!=null) { + hi=" Poly.. size "+hilite.Size()+" area "+hilite.Area(); + } + window.statusBar.setText( + "Layers "+cur+" {"+src1+", "+src2+", "+dst+"} "+ + (drawMode?"draw ":"scale ")+ + "At: ("+upt.x+","+upt.y+")"+hi + ); + Color color = colors[cur]; + //window.statusBar.setBackground(color); + //color=new Color(255-color.getRed(), 255-color.getGreen(), 255-color.getBlue()); + window.statusBar.setForeground(color); + } + /** Reset scaling/scrolling. **/ + public void Reset() { + xoff=0; yoff=0; + xmag=(float).4; ymag=(float)-.4; + UpdateStatusBar(); + repaint(); + } + /** Set scrolling. **/ + public void Move(float x, float y) { + xoff=xoff-x*(xsz/xmag)*(float).125; + yoff=yoff-y*(ysz/ymag)*(float).125; + UpdateStatusBar(); + repaint(); + } + /** Set scaling. **/ + public void Zoom(float x, float y) { + xmag=xmag*x; + ymag=ymag*y; + UpdateStatusBar(); + repaint(); + } + + public void PaintPoly(Graphics g, Poly p, Color color, boolean fill) { + int w=getSize().width, h=getSize().height; + g.setColor(color); + MultiPoly mp=new MultiPoly(p, xoff, yoff, xmag, ymag, w, h); + if (fill) { g.fillPolygon(mp.x, mp.y, mp.l); } + else { g.drawPolygon(mp.x, mp.y, mp.l); } + } + + public void PaintLayer(Graphics g, Layer layer, Color color, boolean fill) { + int w=getSize().width, h=getSize().height; + g.setColor(color); + for (int p=0; p=0; i--) { + PlugEntry pe = (PlugEntry)plugEntries.elementAt(i); + poly.Insert(ind++, pe.at, null); + //for (int i=plugEntries.size()-1; i>=0; i--) { + // ((Poly)pe.polys.elementAt(j)).Dump(out); + //} + } + out.print(" "); + poly.Dump(out); + out.println("))"); + } + } + /** Dumps debugging info to stdout. **/ + public void DebugDump() { + System.out.println("Layer "+name); + System.out.println("Horizontal:"); + for (int i=0; i=0; i--) { + area+=Get(i).Area(); + } + return area; + } + + /** Removes degenerate edges and recalculates the sorted edge lists. **/ + public void Update() { + DeleteIfDegenerate(); + CreateEdges(); + } + /** Clears and recalculates the sorted edge lists. **/ + public void CreateEdges() { + vEdges.Clear(); + hEdges.Clear(); + for (int i=0; i=0; p--) { + Poly pol = Get(p); + if (pol.Size()<3) { + for (int e=0; e=at) { + return new Point(dist, at); + } + dlo = Math.abs(plo - at); dhi = Math.abs(phi - at); + if (dlo 0) { + e = (Edge)active.removeFirst(); + if (e.Length()>0) { +//System.out.println("Square Grow iteration (poly size "+p.Size()+")"); + cur = e.GetIndexAxis(); + di = (Point)grown.get(e); + d = di.x; + e.UpdateDir(); + int dir = e.dir; + int out = Util.GetOutsideDir(dir); + SortedEdges edges = (Util.DirIsHorizontal(dir)? hEdges : vEdges); + bar = edges.GetNearestEdge(e, out, dist-d); + if (bar!=null) { grew = Math.abs(cur-bar.GetIndexAxis()); } + else { grew = Math.max(0, dist-d); } + if (grew>0) { + e.Grow(grew); + Edge prev=e.PrevEdge(), next=e.NextEdge(); + prev.UpdateDir(); next.UpdateDir(); + // add perpendicular edges to grow list + // (NOTE prev and next edge may not be perp after splits...) + Point ed = (Point)grown.get(next); + if (dist>ed.x) { active.addLast(next); } + ed = (Point)grown.get(prev); + if (dist>ed.x) { active.addLast(prev); } + } + grown.put(e, new Point(d+grew, di.y)); + if (bar!=null) { + int min = e.GetMin(), max = e.GetMax(); + boolean horiz = Util.DirIsHorizontal(dir); + Vector splitEdges = e.SplitOnBarrier(bar); + Point oldDist, newDist = CalcSpecialDist(horiz, d+grew, di.y, e); + if (splitEdges.size()>0) { + active.addLast(e); + if (newDist.x>(d+grew)) { grown.put(e, newDist); } + } + for (int j=0; j=0; i--) { + e = p.GetEdge(i); + active.addLast(e); + grown.put(e, new Point(0, e.GetMid())); + } + SquareGrowPoly(p, dist, active, grown); + } + /** Calculates (as a rectangular polygon) the coverage of a plug, + * assuming that this layer is the well layer. **/ + public Poly SquareGrowFromPoint(Point at, int dist) { +//System.out.println("Square Grow called"); + // allow poly to cross self (so order of growth doesn't cut off edges around loops) + // perform self-or operation on the poly to clean it up + Poly p = new Poly(at, 1); + SquareGrowPoly(p, dist-1); + // self-OR the poly to remove overlaps caused by small barriers + if (p!=null) { + Layer temp = new Layer(); + temp.Add(p); + temp = (new PolyOperator()).CombineLayers(PolyOperator.OR, temp, temp); + if (temp.Size()>0) { + p = temp.Get(0); + } else { + // TODO check if this indicates a bug... + p=null; + } + } + return p; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/PlugEntry.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/PlugEntry.java new file mode 100644 index 0000000000..30f442d9b6 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/PlugEntry.java @@ -0,0 +1,83 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import java.util.LinkedList; +import java.util.Hashtable; + +import com.avlsi.tools.ilg.Util; +import com.avlsi.tools.ilg.ILG; +import com.avlsi.tools.ilg.Edge; +import com.avlsi.tools.ilg.Poly; +import com.avlsi.tools.ilg.Layer; +import com.avlsi.tools.ilg.SortedEdges; +import com.avlsi.tools.ilg.Span; +import com.avlsi.tools.ilg.SpanList; +import com.avlsi.tools.ilg.PolyOperator; +import com.avlsi.tools.ilg.WellPlugData; + +/** Data to represent a plug and the well area that it covers. **/ +public class PlugEntry implements Comparable { + /** Numeric area covered. **/ + long area; + /** Actual position of the Plug. **/ + Point at; + /** The polygons within the well that the plug covers. + Overlap with other plugs may be removed. **/ + Vector polys = new Vector(); + + public PlugEntry(Point p, Poly pol) { + at=p; polys.add(pol); + RecalcArea(); + } + /** Recalculates the area covered. **/ + public long RecalcArea() { + area=0; + for (int i=polys.size()-1; i>=0; i--) { + area+=((Poly)polys.elementAt(i)).Area(); + } + return area; + } + /** Function to let us sort the entry on area (and other more arbitrary data). **/ + public int compareTo(Object o) { + int dif=0; + if (o instanceof PlugEntry) { + PlugEntry ope = (PlugEntry)o; + // TODO check sign + if (ope.area>area) { dif=-1; } + else if (ope.areaat.x) { dif=-1; } + else if (ope.at.xat.y) { dif=-1; } + else if (ope.at.y=0; i--) { + l.Add((Poly)polys.elementAt(i)); + } + } + /** Clears the coverage polygons and adds new ones from the input layer. **/ + public void ImportPolys(Layer l) { + polys.clear(); + for (int i=l.Size()-1; i>=0; i--) { + polys.add(l.Get(i)); + } + RecalcArea(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Poly.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Poly.java new file mode 100644 index 0000000000..952579fffd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/Poly.java @@ -0,0 +1,255 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import java.util.LinkedList; +import java.util.Hashtable; + +import com.avlsi.tools.ilg.Util; +import com.avlsi.tools.ilg.ILG; +import com.avlsi.tools.ilg.Edge; +import com.avlsi.tools.ilg.Layer; +import com.avlsi.tools.ilg.SortedEdges; +import com.avlsi.tools.ilg.Span; +import com.avlsi.tools.ilg.SpanList; +import com.avlsi.tools.ilg.PolyOperator; +import com.avlsi.tools.ilg.PlugEntry; +import com.avlsi.tools.ilg.WellPlugData; + +/** + * A polygon class, optimized to deal with rectangular polygons + * (i.e all angles are multiples of 90 degrees). + * Polygons are encoded counter clockwise, so a clockwise one is considered a hole. + * NOTE: Some operations will malfunction if the polygons are not rectangular. + **/ +public class Poly { + /** The vertices of the polygon. Last point may be repeated. **/ + public Vector points=new Vector(); + /** Edge records. May or may not be filled out. **/ + public Vector edges=new Vector(); + + public Poly() {} + /** Constructor to make a rectange with given origin and size. **/ + public Poly(Point at, int size) { + Insert(0, new Point(at.x-size, at.y-size), null); + Insert(1, new Point(at.x+size, at.y-size), null); + Insert(2, new Point(at.x+size, at.y+size), null); + Insert(3, new Point(at.x-size, at.y+size), null); + CreateEdges(); + } + /** Copy constructor. **/ + public Poly(Poly p) { + for (int i=0; i0) { + for (int i=index; i0) { + // swap edges and reverse their dir... + e=GetEdge(i); + edges.setElementAt(GetEdge(j), i); + edges.setElementAt(e, j); + e.index=j; e.dir=Util.ReverseDirection(e.dir); + e=GetEdge(i); + e.index=i; e.dir=Util.ReverseDirection(e.dir); + } + } + } + /** Get the edge at the specified vertex. **/ + public Edge GetEdge(int i) { return (Edge)edges.elementAt(i); } + /** Read the polygon from a stream in lisp-like format. **/ + public Poly Read(StreamTokenizer st) { + //(Point, Point,...) + if (!Util.ReadSymbol(st, "(")) { return null; } + Poly p = new Poly(); + while (true) { + Point cur=Util.ReadPoint(st); + if (cur==null) { break; } + p.points.addElement(cur); + } + Util.ReadSymbol(st, ")"); + return p; + } + /** Write the polygon to a stream in lisp-like format. **/ + public void Dump (PrintStream out) { + out.print("("); + for (int i=0; i0; i--) { + miny=Math.min(miny, Get(i).y); + } + Point p0=Get(0), p1=null; + for (int i=last; i>0; i--) { + p1=Get(i); + area+=(p1.x-p0.x)*((long)(p0.y-miny)); + p0=p1; + } + p1=Get(0); //p0=Get(0); + if (p0!=p1) { + area+=(p1.x-p0.x)*((long)(p0.y-miny)); + } + return area; + } + + /** Point in polygon test. Works on non-rectangular polys and with holes. **/ + //From http://www.ecse.rpi.edu/Homepages/wrf/geom/pnpoly.html + // Based on Simulation Of Simplicity and Jordan Curve Theorem + //int ptInPoly(int npol, float *xp, float *yp, float x, float y) { + // int i, j, c = 0; + // for (i = 0, j = npol-1; i0) && (x_i*yjixji*y_i)))) { + in=!in; + } + } + return in; + } + /** Inserts a hole (reversed polygon) into this poly. + The hole must lie STRICTLY within this poly. **/ + public void MergeHole(Poly hole) { + int i, x, y, x0, x1, y0, hi, hx, hy, pi=0, py = Integer.MAX_VALUE; + Point p; + boolean aligned = false; + // find top edge of hole + hi=0; hx=hole.Get(0).x; hy=hole.Get(0).y; + for (i=hole.Size()-1; i>=0; i--) { + p=hole.Get(i); + if (p.y>hy) {hi=i; hy=p.y; hx=p.x;} + } + // find closest edge above the hole + for (i=Size()-1; i>=0; i--) { + Edge e=GetEdge(i); + x0=e.GetX(); x1=e.GetMaxX(); + y0=e.GetY(); + if (Util.DirIsHorizontal(e.dir)) { +//System.out.println("Span ("+x0+","+x1+")@"+y0+" vs "+hx+","+hy+" "+py); + if ((x0<=hx) && (x1>=hx) && (y0>hy) && (y0Size()) { pi=0; } + } + for(i=hi; i=0; i-=2) { + p0=(Point)spans.elementAt(i); + p1=(Point)spans.elementAt(i+1); + TableEdge(new Point(p0), new Point(p1)); +//System.out.println("emitting "+(p0.x=0; i-=2) { + x0=((Point)spans.elementAt(i)).x; + y0=((Point)spans.elementAt(i)).y; + x1=((Point)spans.elementAt(i+1)).x; + //if ((y0!=y) && (x0>x1)) + if (x00) { +//System.out.println("added poly"); + layer.Add(p); + } else { +//System.out.println("zero area polygon???"); + } + } + iter = holes.iterator(); + Poly hole; + while (iter.hasNext()) { +//System.out.println("new hole"); + hole=(Poly)iter.next(); + //have a hole that must be added to some poly + for (int i=layer.Size()-1; i>=0; i--) { + p=layer.Get(i); + if (p.PointInside(hole.Get(0))) { + p.MergeHole(hole); + break; + } + } + } + return layer; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortableVector.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortableVector.java new file mode 100644 index 0000000000..98c884b96c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortableVector.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + +import java.util.*; + +// NOTE: this class is sorted on demand, not by default! +public class SortableVector extends Vector { + + public SortableVector() {} + public SortableVector(Collection c) { + super(c); + } + + public void Sort() { + Sort(0, size()-1); + CleanUp(0, size()-1); + } + public void Swap(int a, int b) { + Object t = elementAt(a); + set(a, elementAt(b)); + set(b, t); + } + public int Compare(int a, int b) { + return ((Comparable)elementAt(a)).compareTo(elementAt(b)); + } + public void Sort(int l, int r) { + int M=4, i, j, k; + if ((r-l)>M) { + i=(r+l)/2; + if (Compare(l,i)>0) Swap(l,i); + if (Compare(l,r)>0) Swap(l,r); + if (Compare(i,r)>0) Swap(i,r); + j=r-1; + Swap(i,j); + i=l; k=j; + for(;;) { + while(Compare(++i,k)>0); + while(Compare(--j,k)>0); + if (jlo) && (Compare(j-1,i)>0)) { + set(j,elementAt(j-1)); + j--; + } + set(j, o); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortedEdges.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortedEdges.java new file mode 100644 index 0000000000..c72cfdbee1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SortedEdges.java @@ -0,0 +1,279 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import java.util.LinkedList; +import java.util.Hashtable; + +import com.avlsi.tools.ilg.Util; +import com.avlsi.tools.ilg.ILG; +import com.avlsi.tools.ilg.Edge; +import com.avlsi.tools.ilg.Poly; +import com.avlsi.tools.ilg.Layer; +import com.avlsi.tools.ilg.Span; +import com.avlsi.tools.ilg.SpanList; +import com.avlsi.tools.ilg.PolyOperator; +import com.avlsi.tools.ilg.PlugEntry; +import com.avlsi.tools.ilg.WellPlugData; + +/** Speeds up some polygonal operations by holding a sorted list of edges, either + * all horizontal or all vertical, sorted by distance from the parallel axis. **/ +public class SortedEdges { + /** The sorted list of edges. **/ + public Vector edges = new Vector(); + /** The layer that the edges came from. **/ + public Layer layer; + /** Do we hold vertical or horizontal edges. **/ + public boolean horiz; + /** Constructor, takes input layer and whether to hold horizontal or vertical edges. **/ + public SortedEdges(Layer l, boolean h) { layer=l; horiz=h; } + /** Gets a sorted edge by index. **/ + public Edge Get(int i) { return (Edge)edges.elementAt(i); } + /** The count of sorted edges. **/ + public int Size() { return edges.size(); } + /** Adds an edge in sorted order. **/ + public void Add(Edge e) { + int d = GetIndexAxis(e); + int index=GetIndex(d); + if (indexGetIndexAxis(Get(index))) { index++; } + edges.insertElementAt(e, index); + } + /** Remove the given edge. **/ + public void Delete(Edge e) { edges.removeElement(e); } + /** Remove an edge by index. **/ + public void Delete(int i) { edges.removeElementAt(i); } + /** Returns the index (via binary search) that an edge should be at, based on its IndexAxis. **/ + public int GetIndex(int d) { + int s=0, e=Size()-1, m, dif; + while (s0) { + s=m+1; + } else { break; } + } + m=(s+e)/2; + return m; + } + /** Empty the edge list. **/ + public void Clear() { edges.removeAllElements(); } + /** Removes edges that have been marked degenerate. **/ + public void RemoveDegenerates() { + for (int e=Size()-1; e>=0; e--) { + Edge cur = Get(e); + if (cur.dir<0) { + Delete(e); + } + } + } + /** Removes any perpendicular edges and puts them in the opposite edge list. **/ + public void MoveOrthogonalEdges() { + for (int e=Size()-1; e>=0; e--) { + Edge cur = Get(e); + if (horiz!=Util.DirIsHorizontal(cur.dir)) { + Delete(e); + layer.InsertEdge(cur); + } + } + } + /** Searches in direction dir away from the given edge (up to distance max) + * for other edges that the given edge would impact, + * returns the closest edge distance or max if none are found. **/ + public int GetNearestEdgeDist(Edge e, int dir, int max) { + Edge near = GetNearestEdge( e, dir, max); + if (near==null) { return max; } + return Math.abs(GetIndexAxis(e)-GetIndexAxis(near)); + } + /** Searches in direction dir away from the given edge (up to distance max) + * for other edges that the given edge would impact, returns the closest index. **/ + public int GetNearestEdgeIndex(Edge e, int dir, int max) { + Edge ret=null, cur; + int d, l=Size(), m, dif; + if (l<1) { return -1; } + d=GetIndexAxis(e); + m=GetIndex(d); + if (dir<2) { + // be sure to start at minimum index.. + while ((m>0) && (d>=GetIndexAxis(Get(m)))) { m--; } + // step up + while (m=max) { return -1; } + if (e!=cur && dif>=0 && e.Spans(cur)) { return m; } + m++; + } + } else { + // be sure to start at maximum index.. + while ((m<(l-1)) && (d<=GetIndexAxis(Get(m)))) { m++; } + // step down + while (m>=0) { + cur=Get(m); + dif=d-GetIndexAxis(cur); + if (dif>=max) { return -1; } + if (e!=cur && dif>=0 && e.Spans(cur)) { return m; } + m--; + } + } + return -1; + } + /** Searches in direction dir away from the given edge (up to distance max) + * for other edges that the given edge would impact, returns the closest edge. **/ + public Edge GetNearestEdge(Edge e, int dir, int max) { + int index = GetNearestEdgeIndex(e, dir, max); + if (index<0) { return null; } + return Get(index); + } + /** See Edge.GetIndexAxis. **/ + public int GetIndexAxis(Edge e) { return horiz ? e.GetY() : e.GetX(); } + /** Splits any abutting edges. Prepares polys for merge. **/ + public boolean Split() { + Edge edges[] = GetAbuts(true); + if ((edges!=null) && (edges.length>1)) { + SplitPolys(edges[0], edges[1]); + return true; + } + return false; + } + /** Merges any abutting edges, and their associated polygons. **/ + public boolean Merge() { + Edge edges[] = GetAbuts(false); + if ((edges!=null) && (edges.length>1)) { + //System.out.println("Merging polygons: "); + //edges[0].p.Dump(System.out); + //System.out.println("And: "); + //edges[1].p.Dump(System.out); + StitchPolys(edges[0], edges[1]); + //System.out.println("for "+layer.Size()+" on layer: "+layer.name); + return true; + } + return false; + } + /** Returns a list of abutting edges. **/ + public Edge[] GetAbuts(boolean samePoly) { + int start=0, d, dt, len = Size(); + if (len>0) { + dt=d=GetIndexAxis(Get(0)); + for (int i=0; istart) { + Edge edges[] = CheckAbuts(start, i, samePoly); + if ((edges!=null) && (edges.length>1)) { return edges; } + } + d=dt; start=i; + } + } + if (start<(len-1) && (dt==GetIndexAxis(Get(start)))) { + return CheckAbuts(start, len, samePoly); + } + } + return null; + } + /** Checks within a range for abutting edges. **/ + public Edge[] CheckAbuts(int start, int end, boolean samePoly) { + Edge e1, e2; + for (int i=start; i=0) && (layer[1]>=0) && (layer[2]>=0); + } + /** Increments or decrements the state for a given layer. **/ + public boolean SetState(int lyr, boolean val) { + if (val) { layer[lyr]++; } + else { layer[lyr]--; } + return GetState(); + } + /** Returns the last calculated state for the span **/ + public boolean GetState() { return layer[2]>0; } + /** Returns true if the span just changed and was ever on. **/ + public boolean IsNew(int yval) { return (y==yval) && wasOn; } + /** Returns reverse order for closing edges. **/ + public int GetStartX() { return GetState() ? x0 : x1; } + /** Returns reverse order for closing edges. **/ + public int GetEndX() { return GetState() ? x1 : x0; } + /** Returns y value at which span was last changed. **/ + public int GetLastY() { return y; } + /** Returns whether the span state changed or not. **/ + public boolean UpdateNewState(int oper, int yval) { + boolean ret = UpdateState(oper, yval); + return ret; + } + /** Calculates new state. Operators are: 0=or, 1=and, 2=andNot. **/ + public boolean UpdateState(int oper, int yval) { + boolean ret; + int state=0; + if (oper==0) { + state = (layer[0]>0 || layer[1]>0) ? 1:0; + } else if (oper==1) { + state= (layer[0]>0 && layer[1]>0) ? 1:0; + } else if (oper==2) { + state= (layer[0]>0 && layer[1]==0) ? 1:0; + } + ret = (state!=layer[2]); + layer[2]=state; + if (state==1) { wasOn=true; } + if (ret) { + y=yval; + } + return ret; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SpanList.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SpanList.java new file mode 100644 index 0000000000..155aa944da --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/SpanList.java @@ -0,0 +1,216 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import java.util.LinkedList; +import java.util.Hashtable; + +import com.avlsi.tools.ilg.Util; +import com.avlsi.tools.ilg.ILG; +import com.avlsi.tools.ilg.Edge; +import com.avlsi.tools.ilg.Poly; +import com.avlsi.tools.ilg.Layer; +import com.avlsi.tools.ilg.SortedEdges; +import com.avlsi.tools.ilg.Span; +import com.avlsi.tools.ilg.PolyOperator; +import com.avlsi.tools.ilg.PlugEntry; +import com.avlsi.tools.ilg.WellPlugData; + +/** List of active spans. Used by PolyOperator to perform boolean operations on layers. **/ +public class SpanList { + /** The ordered (in x) list of active spans. **/ + LinkedList spans = new LinkedList(); + /** The operation type: 0=or, 1=and, 2=andNot**/ + int oper = 0; + + /** Removes all active spans. **/ + public void Clear() { + spans.clear(); + } + /** Sets the operation type, should only be done on an empty SpanList. **/ + public void SetOper(int op) { + if ((op>=0) && (op<=2)) { + oper=op; + } + } + /** Prints debugging info about the spans. **/ + public void DumpSpans() { + System.out.println("Span list:"); + ListIterator iter = spans.listIterator(); + while (iter.hasNext()) { + Span span=(Span)iter.next(); + span.Dump(); + } + } + /** Performs consistency checks on the list of spans. **/ + public void Validate() { + //System.out.println("Validating Span list:"); + ListIterator iter = spans.listIterator(); + Span last = null; + while (iter.hasNext()) { + Span span=(Span)iter.next(); + if (!span.Validate()) { span.Dump(); } + if (last!=null && last.x1>span.x0) { + System.out.println("Mis-Ordered Spans:"); + span.Dump(); last.Dump(); + } + last=span; + } + } + /** Processes an edge from a given layer, creating and adjusting spans. **/ + public void SetSpan(Edge e, int layer, boolean state) { + if ((layer<0) || (layer>1)) { return; } // throw IllegalArg? + // split the edge list as nec + int startx = e.P0().x, endx = e.P1().x; + int y = e.P0().y; + int xmin=Math.min(startx, endx), xmax=Math.max(startx, endx); + Span span=null, temp; + boolean newState; + ListIterator iter = spans.listIterator(); + + if (!iter.hasNext()) { + // empty, insert this edge + temp = new Span(xmin, xmax, y, layer, state); + //temp.UpdateNewState(oper,y); + spans.add(temp); +//System.out.println("first edge "+temp.x0+" "+temp.x1); + return; + } + while (iter.hasNext() && (xminspan.x0) { + // cut from beginning of span + temp = span.Split(xmin); + iter.add(temp); + iter.previous(); +//System.out.println("pre-edge cut "+span.x0+","+temp.x1+" at "+xmin); + } else { +//System.out.println("modifying span "+span.x0+","+span.x1); + if (xmaxa.x) { return 0; } // R + if (b.y>a.y) { return 1; } // U + if (b.xsym.length()) { + st.sval=st.sval.substring(sym.length()); + st.pushBack(); + } + return true; + } + st.pushBack(); + return false; + } + /** Reads a string from the input stream. **/ + public static String ReadString(StreamTokenizer st) { + try { + int cur=st.nextToken(); + } catch (IOException ex) {} + //System.out.println("Read string: "+st.sval); + return st.sval; + } + /** Reads a floating point number from the input stream. **/ + public static double ReadNumber(StreamTokenizer st) { + double val =0.0; + try { + int cur=st.nextToken(); + val = Double.parseDouble(st.sval); + } catch (Exception ex) { + if (st.sval==null) { + val=st.nval; + } + //System.out.println("Read number exception "); + //ex.printStackTrace(); + } + //System.out.println("Read number: "+val+" ("+st.sval+")"); + return val; + //System.out.println("Read number: "+st.nval); + //return st.nval; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/WellPlugData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/WellPlugData.java new file mode 100644 index 0000000000..858b777f45 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ilg/WellPlugData.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ilg; + + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import java.util.LinkedList; +import java.util.Hashtable; + +import com.avlsi.tools.ilg.Util; +import com.avlsi.tools.ilg.ILG; +import com.avlsi.tools.ilg.Edge; +import com.avlsi.tools.ilg.Poly; +import com.avlsi.tools.ilg.Layer; +import com.avlsi.tools.ilg.SortedEdges; +import com.avlsi.tools.ilg.Span; +import com.avlsi.tools.ilg.SpanList; +import com.avlsi.tools.ilg.PolyOperator; +import com.avlsi.tools.ilg.PlugEntry; + +/** A class to hold plug related data for a given Layer. **/ +public class WellPlugData { + /** The name of the well layer this layer plugs. **/ + String wellName=null; + /** The distance that a given plug covers (plugs). **/ + int covDist=0; + /** The size of a plug, placement origin, and increment from the origin. **/ + Point size, origin, spacing; + /** Reads the data from a stream in lisp-like format. **/ + public void ReadExtraData (StreamTokenizer st) { +//System.out.println("Reading Extra Data"); + // the well-layer name to be plugged + wellName = Util.ReadString(st); + // coverage distance + covDist = (int)Util.ReadNumber(st); + Util.ReadSymbol(st, "("); + // size of the plugs + size = new Point((int)Util.ReadNumber(st), (int)Util.ReadNumber(st)); + Util.ReadSymbol(st, ")"); + Util.ReadSymbol(st, "("); + // spacing of the plugs + origin = new Point((int)Util.ReadNumber(st), (int)Util.ReadNumber(st)); + Util.ReadSymbol(st, ")"); + Util.ReadSymbol(st, "("); + // origin of plugs + spacing = new Point((int)Util.ReadNumber(st), (int)Util.ReadNumber(st)); + Util.ReadSymbol(st, ")"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/GenerateIPData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/GenerateIPData.java new file mode 100644 index 0000000000..38e3e5d44d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/GenerateIPData.java @@ -0,0 +1,659 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.ipgen; + + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; +import java.util.LinkedList; +import java.util.LinkedHashSet; + +import java.io.File; +import java.io.FileWriter; +import java.io.OutputStream; +import java.io.Writer; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.BufferedWriter; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.Reader; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.UnsupportedEncodingException; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.cast.CastFileParser; + +import com.avlsi.tools.cadencize.Cadencize; + +import com.avlsi.tools.cosim.spec.CoSim; + +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.cdl.parser.SplittingFactory; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.TrivialCDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CDLRenameFactory; +import com.avlsi.file.cdl.util.rename.BindRulNameInterfaceFactory; + +import com.avlsi.io.SearchPath; +import com.avlsi.io.FileSearchPath; + +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterException; +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.AssuraBindRulTableEmitterFactory; +import com.avlsi.layout.gdsII.SkillTableEmitterFactory; +import com.avlsi.layout.gdsII.SplittingTableEmitterFactory; +import com.avlsi.layout.gdsII.FilterInternalNodesTableEmitterFactory; + +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.impl.simple.SimpleNetlistFactory; +import com.avlsi.netlist.util.FlatteningIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +import com.avlsi.tools.jauto.Cast2Cdl; +import com.avlsi.tools.prs2verilog.Prs2Verilog; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; + +import com.avlsi.tools.ipgen.RenamingVerilogFactory; +import com.avlsi.tools.ipgen.PMCNameInterfaceFactory; + + +/** + Calls cast2cdl and prs2verilog to generate + skill name table files, cdl, flattened strength report, and verilog models + for a specified cell. + */ +public class GenerateIPData { + + + private static final class PRS2VerilogRun { + + private final String mOption; + + private final File mOutputDir; + + private final CastFileParser cfp; + + public PRS2VerilogRun( final String option, + final File outputDir, + final CastFileParser cfp ) { + mOption = option ; + mOutputDir = outputDir; + this.cfp = cfp; + + } + + public boolean isValid() { + return ( ! mOutputDir.isDirectory() ) && + mOutputDir.getParentFile().canWrite(); + } + + public void run( final CellInterface ci, + final VerilogFactoryInterface verilogFactory, + final CDLNameInterfaceFactory namerFactory) + throws IOException, CDLRenameException { + + final String[] prs2VerilogArgs = + mOption != null && mOption.length() > 0 ? + new String[] { mOption } : new String[0]; + + final CommandLineArgs parsedPRS2VerilogArgs = + new CommandLineArgsDefImpl( prs2VerilogArgs ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedPRS2VerilogArgs ); + final CommandLineArgs cachedPRS2VerilogArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + + final Collection filelist = new ArrayList(); + final CDLNameInterface ni = + namerFactory.getNameInterface(ci.getFullyQualifiedType()); + final Prs2Verilog.VisitorFactory verilogVisitorFactory = + new Prs2Verilog.MultipleFileVisitor(mOutputDir, null, filelist, + true, ni, false); + + final String spec = cachedPRS2VerilogArgs.getArgValue("spec", null); + final CoSim cosim; + if (spec == null) { + cosim = null; + } else { + cosim = CoSim.getCoSim(ci.getFullyQualifiedType() + "{" + + spec + "}", true); + } + + final Map dependencies = + Prs2Verilog.writeVerilog( ci, + verilogVisitorFactory, + cfp, + cachedPRS2VerilogArgs, + verilogFactory, + "netgraph", + false, + cosim); + + final Set goodfiles = new LinkedHashSet(); + Prs2Verilog.verilogFiles(dependencies, goodfiles); + + final FileWriter list = + new FileWriter(new File(mOutputDir, "autogen-list")); + for (Iterator i = filelist.iterator(); i.hasNext(); ) { + list.write(i.next() + "\n"); + } + list.close(); + + final FileWriter verilog = + new FileWriter(new File(mOutputDir, "verilog-list")); + for (Iterator i = goodfiles.iterator(); i.hasNext(); ) { + verilog.write(i.next() + "\n"); + } + verilog.close(); + } + + } + + /* + This class is used to prevent the PMCNameInterface from generating names + that would collide with names generated from the mappings in the user specified bind.rul file. + */ + private static final class ExistingNames implements PMCNameInterfaceFactory.ExistingNamesInterface { + + private BindRulNameInterfaceFactory mBindRulFactory; + + private Set mExistingCellNames; + + public ExistingNames() { + mBindRulFactory = null; + mExistingCellNames = null; + } + + public void setBindRulFactory( final BindRulNameInterfaceFactory factory ){ + mBindRulFactory = factory; + + mExistingCellNames = new HashSet(); + + final Set cellNamesFromFactory = factory.getNewCellNames(); + + processNames( cellNamesFromFactory, mExistingCellNames ); + } + + + private static void processNames( final Set srcSet, final Set targetSet ) { + final Iterator nameIter = srcSet.iterator(); + + while ( nameIter.hasNext() ) { + final String currName = ( String ) nameIter.next(); + /* If name begins with an 'f' and ends with an 'm', strip the 'f' and 'm' off + because the PMC name interface will put them on names it creates. + It puts in the f and the m after it checks for collisions. */ + if ( ( currName.charAt( 0 ) == 'f' ) && + ( currName.charAt( currName.length() - 1 ) == 'm' ) ) { + targetSet.add( currName.substring( 1, currName.length() - 1 ) ); + } + targetSet.add( currName ); + } + } + + public Set getExistingTranslatedNamesForCell( final String cellName ) { + final Set nodeNamesFromFactory = + mBindRulFactory.getNewNodeNamesForOldCellName( cellName ); + final Set instanceNamesFromFactory = + mBindRulFactory.getNewInstanceNamesForOldCellName( cellName ); + final Set ret = new HashSet( mExistingCellNames ); + processNames( nodeNamesFromFactory, ret ); + processNames( instanceNamesFromFactory, ret ); + return ret; + } + + } + + private static final class FlatInstances { + + private final Map mCellsMap; + + public FlatInstances( ) { + mCellsMap = new HashMap(); + } + + public final void addInstanceOfCell( final FlatteningIterator.FlatInstance instance ) { + final String masterNetlistName = + instance.getInstanceMasterNetlist().getName().toString(); + final List existingInstances = getInstances( masterNetlistName ); + final List instances; + if ( existingInstances == null ) { + instances = new LinkedList(); + mCellsMap.put( masterNetlistName, instances ); + } + else { + instances = existingInstances; + } + instances.add( instance ); + } + + public final List getInstances( final String cellName ) { + return ( List ) mCellsMap.get( cellName ); + } + + } + + private static FlatInstances getFlatInstancesOfCells( final AbstractNetlist top ) { + final FlatInstances ret = new FlatInstances(); + final FlatteningIterator iter = new FlatteningIterator( top ); + + while ( iter.hasNext() ) { + final FlatteningIterator.FlatInstance currInstance = + iter.next(); + ret.addInstanceOfCell( currInstance ); + } + return ret; + } + + + private static void flattenStrengthReport( final HashMapTableEmitterFactory hashTableEmitterFactory, + final AbstractNetlist top, + final Reader reader, + final Writer output, + final String hierarchySeperator ) + throws IOException + { + final FlatInstances flatInstances = getFlatInstancesOfCells( top ); + final BufferedReader bReader = new BufferedReader( reader ); + + + List instancesOfCurrCell = null; + HashMapTableEmitter currTableEmitter = null; + + String currLine = bReader.readLine(); + + while ( currLine != null ) { + final String[] tokens = currLine.split( "\\p{Space}+" ); + if ( tokens.length > 0 ) { + int startIndex = 0; + while ( ( startIndex < tokens.length ) && + ( tokens[ startIndex ].length() == 0 ) ) { + ++startIndex; + } + if ( startIndex < tokens.length ) { + if ( ( tokens[startIndex].equals( "CELL" ) ) && + ( tokens.length == ( startIndex + 2 ) ) ) { + final String cellCastName = tokens[startIndex + 1]; + + final String currCellGDSIIName = + hashTableEmitterFactory.getGDSIICellNameForCastCellName( cellCastName ); + + instancesOfCurrCell = flatInstances.getInstances( currCellGDSIIName ); + currTableEmitter = hashTableEmitterFactory.getEmitterForCell( cellCastName ); + } + else if ( ( tokens[startIndex].equals( "STRENGTH" ) ) && + ( tokens.length == ( startIndex + 4 ) ) ) { + final String castNodeName = tokens[startIndex + 1]; + final String direction = tokens[startIndex + 2]; + final String strength = tokens [startIndex + 3]; + + final String gdsIINodeName = currTableEmitter.getGDSIINodeNameForCastNodeName( castNodeName ); + + final Iterator instIter = instancesOfCurrCell.iterator(); + while ( instIter.hasNext() ) { + final FlatteningIterator.FlatInstance currInst = + ( FlatteningIterator.FlatInstance ) instIter.next(); + + final String flatNodeName = currInst.getCanonicalNodeName( gdsIINodeName, + hierarchySeperator ); + + output.write( flatNodeName + " " + direction + " " + strength + "\n" ); + } + } + else { + System.out.println( "Ignoring: \"" + currLine + "\" \"" + tokens[0] + "\""); + } + } + } + currLine = bReader.readLine(); + } + } + + private static void usage() { + final String className = GenerateIPData.class.getName(); + + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className ); + System.out.println("\t--cast-path= (defaults to .)"); + System.out.println("\t--cast-version= (defaults to 2)"); + System.out.println("\t--cell= (name of cell to process)"); + System.out.println("\t--gdsII-name-interface=fulcrum | --gdsII-name-interface=pmc"); + System.out.println("\t--bind-rul=file" ); + System.out.println("\t--prs2verilog=file" ); + System.out.println("\t--strength-report=file" ); + System.out.println("\t--output-dir="); + } + + public static List parsePRS2VerilogOption( final String prs2VerilogArg, final File outputDir, final CastFileParser cfp ) { + final String[] parts = prs2VerilogArg.split( ":" ); + final List result = new LinkedList(); + if ( ( parts.length % 2 ) == 0 ) { + int index; + for ( index = 0 ; index < ( parts.length / 2 ) ; ++index ) { + final int base = index * 2 ; + final String testBenchDir = parts[ base ]; + final String prs2VerilogOption = parts[ base + 1 ]; + + final File voutDir = new File( outputDir, testBenchDir ); + + final PRS2VerilogRun currRun = new PRS2VerilogRun( prs2VerilogOption, + voutDir, + cfp ); + if ( currRun.isValid() ) { + result.add( currRun ); + } + } + } + return result; + } + + public static void main( String args[] ) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cell", null); + + + final String bindRulFileName = theArgs.getArgValue( "bind-rul", null ); + final File bindRulFile; + if ( bindRulFileName != null ) { + bindRulFile = new File( bindRulFileName ); + } + else { + bindRulFile = null ; + } + + final String outputDirName = theArgs.getArgValue( "output-dir", null ); + final File outputDir; + if ( outputDirName != null ) { + outputDir = new File( outputDirName ); + } + else { + outputDir = null ; + } + + if ( ( outputDir != null ) && + ( ! ( outputDir.exists() ) ) ) { + outputDir.mkdirs(); + } + + final String gdsNameInterfaceName = theArgs.getArgValue( "gdsII-name-interface", "fulcrum" ); + + final String strengthReportFileName = theArgs.getArgValue( "strength-report", null ); + final File strengthReportFile; + + if ( strengthReportFileName != null ) { + strengthReportFile = new File( strengthReportFileName ); + } + else { + strengthReportFile = null; + } + + final CastFileParser castParser = + new CastFileParser( new FileSearchPath(castRoot), castVersion ); + + final List prs2VerilogRuns = parsePRS2VerilogOption( theArgs.getArgValue( "prs2verilog", "" ), + outputDir, + castParser ); + + if ( ( cellName != null ) && + ( bindRulFile != null ) && + ( bindRulFile.isFile() ) && + ( bindRulFile.canRead() ) && + ( outputDir != null ) && + ( outputDir.isDirectory() ) && + ( gdsNameInterfaceName != null ) && + ( strengthReportFile != null ) && + ( strengthReportFile.isFile() ) && + ( strengthReportFile.canRead() ) ) { + + final Cadencize cadencizer = new Cadencize( true ); + + + final CDLNameInterfaceFactory gdsIINameInterfaceFactory; + + ExistingNames existingNames = null; + + if ( gdsNameInterfaceName.equals( "fulcrum" ) ) { + final CDLNameInterface fulcrumGDSIINameInterface = new GDS2NameInterface(); + gdsIINameInterfaceFactory = + new TrivialCDLNameInterfaceFactory( fulcrumGDSIINameInterface ); + } + else if ( gdsNameInterfaceName.equals( "pmc" ) ) { + existingNames = new ExistingNames(); + gdsIINameInterfaceFactory = new PMCNameInterfaceFactory( castParser, + cadencizer, + existingNames ); + + } + else { + gdsIINameInterfaceFactory = null; + } + + if ( gdsIINameInterfaceFactory != null ) { + + final CellInterface ci = castParser.getFullyQualifiedCell( cellName ); + + final File skillOutputDir = new File( outputDir, "ilnames" ); + if ( ! ( skillOutputDir.exists() ) ) { + skillOutputDir.mkdirs(); + } + + final TableEmitterFactoryInterface skillEmitterFactory = + new SkillTableEmitterFactory( skillOutputDir, + "CadenceNodeToGDSIINodeTable", + "CadenceCellToGDSIICellTable", + "CadenceInstanceToGDSIIInstanceTable" ); + + cadencizer.convert( ci ); + + final File outputBindRul = new File( outputDir, "bind.rul" ); + final TableEmitterFactoryInterface assuraEmitterFactory = + new AssuraBindRulTableEmitterFactory( outputBindRul, + bindRulFile ); + + final TableEmitterFactoryInterface filteredAssuraEmitterFactory = + new FilterInternalNodesTableEmitterFactory( cadencizer, + assuraEmitterFactory ); + + final TableEmitterFactoryInterface splitterFactory1 = + new SplittingTableEmitterFactory( skillEmitterFactory, + filteredAssuraEmitterFactory ); + + //Gets used to rename nodes in the strength report. + final HashMapTableEmitterFactory hashTableEmitterFactory = + new HashMapTableEmitterFactory(); + + final TableEmitterFactoryInterface splitterFactory2 = + new SplittingTableEmitterFactory( splitterFactory1, + hashTableEmitterFactory ); + + final InputStream inputBindRulStream = new FileInputStream( bindRulFile ); + final Reader inputBindRulReader = + new BufferedReader( new InputStreamReader( inputBindRulStream, "UTF-8" ) ); + + final BindRulNameInterfaceFactory bindRulNameInterfaceFactory = + new BindRulNameInterfaceFactory( inputBindRulReader, + gdsIINameInterfaceFactory ); + + if ( existingNames != null ) { + existingNames.setBindRulFactory( bindRulNameInterfaceFactory ); + } + + final CDLNameInterface cadenceNameInterface = new CadenceNameInterface(); + final CDLNameInterfaceFactory cadenceNameInterfaceFactory = + new TrivialCDLNameInterfaceFactory( cadenceNameInterface ); + + final TablifyingNameInterfaceFactory nameInterfaceFactory = + new TablifyingNameInterfaceFactory( splitterFactory2, + cadenceNameInterfaceFactory, + bindRulNameInterfaceFactory ); + + final File outputCDLFile = new File( outputDir, "gdsII.cdl" ); + final OutputStream outputCDLStream = new FileOutputStream( outputCDLFile ); + final Writer outputCDLWriter = new BufferedWriter( new OutputStreamWriter( outputCDLStream, + "UTF-8" ) ); + + final CDLFactoryInterface cdlEmitter = + new CDLFactoryEmitter( outputCDLWriter, true, 76, true, + false, "" ); + + final SimpleNetlistFactory netlistFactory = new SimpleNetlistFactory(); + + final CDLFactoryInterface splittingFactory = new SplittingFactory( cdlEmitter, + netlistFactory ); + + final CDLFactoryInterface cdlRenamer = new CDLRenameFactory( splittingFactory, + nameInterfaceFactory ); + + final CDLFactoryInterface trueNames = + new Cast2Cdl.RealTransistorNames(cdlRenamer, castParser); + + Cast2Cdl.outputCDL(ci, castParser, trueNames, cadencizer, false, false); + outputCDLWriter.close(); + nameInterfaceFactory.close(); + + final CDLNameInterfaceFactory leftOverFactory; + + if ( gdsNameInterfaceName.equals( "fulcrum" ) ) { + final CDLNameInterface fulcrumGDSIINameInterface = new GDS2NameInterface(); + leftOverFactory = + new TrivialCDLNameInterfaceFactory( fulcrumGDSIINameInterface ); + } + else if ( gdsNameInterfaceName.equals( "pmc" ) ) { + final PMCNameInterfaceFactory.ExistingNamesInterface exist = + new PMCNameInterfaceFactory.ExistingNamesInterface() { + public Set getExistingTranslatedNamesForCell( + final String cellName ) { + final HashMapTableEmitter emitter = + hashTableEmitterFactory.getEmitterForCell( cellName ); + if (emitter == null) + return Collections.EMPTY_SET; + final HashSet result = new HashSet(); + result.addAll(emitter.getGDSCellNames()); + result.addAll(emitter.getGDSNodeNames()); + result.addAll(emitter.getGDSInstanceNames()); + return result; + } + }; + existingNames = new ExistingNames(); + leftOverFactory = new PMCNameInterfaceFactory( castParser, + cadencizer, + exist ); + + } + else { + leftOverFactory = null; + } + + + final VerilogFactoryInterface verilogFactory = + new RenamingVerilogFactory( hashTableEmitterFactory, + leftOverFactory ); + + final Iterator prs2VerilogIter = prs2VerilogRuns.iterator(); + + while ( prs2VerilogIter.hasNext() ) { + final PRS2VerilogRun curr = ( PRS2VerilogRun ) prs2VerilogIter.next(); + curr.run( ci, verilogFactory, bindRulNameInterfaceFactory ); + } + + + final String gdsIINameOfTopCell = + hashTableEmitterFactory.getGDSIICellNameForCastCellName( cellName ); + + final AbstractNetlist top = netlistFactory.getNetlist( gdsIINameOfTopCell ); + + if ( top != null ) { + + final InputStream strengthReportStream = new FileInputStream( strengthReportFile ); + final Reader strengthReportReader = new InputStreamReader( strengthReportStream, "UTF-8" ); + + final File outputStrengthReportFile = new File( outputDir, cellName + ".strength.report.txt" ); + final OutputStream outputStrengthReportStream = new FileOutputStream( outputStrengthReportFile ); + final Writer outputStrengthReportWriter = + new BufferedWriter( new OutputStreamWriter( outputStrengthReportStream ) ); + + flattenStrengthReport( hashTableEmitterFactory, + top, + strengthReportReader, + outputStrengthReportWriter, + "." ); + + outputStrengthReportWriter.close(); + strengthReportReader.close(); + + } + } + } + else { + if ( cellName == null ) { + System.out.println( "You must specify a cast cell name." ); + } + if ( outputDir == null ) { + System.out.println( "You must specify an output directory." ); + } + else if ( ! ( outputDir.isDirectory() ) ) { + System.out.println( "\"" + outputDir + "\" is not a directory." ); + } + if ( bindRulFile == null ) { + System.out.println( "You must specify an initial bind.rul file." ); + } + else if ( ! ( ( bindRulFile.isFile() ) && ( bindRulFile.canRead() ) ) ) { + System.out.println( "\"" + bindRulFile + "\" is not a readable file." ); + } + if ( strengthReportFile == null ) { + System.out.println( "You must specify a strength report file." ); + } + else if ( ! ( ( strengthReportFile.isFile() ) && ( strengthReportFile.canRead() ) ) ) { + System.out.println( "\"" + strengthReportFile + "\" is not a readable file." ); + } + usage(); + } + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitter.java new file mode 100644 index 0000000000..7aa01c8b9d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitter.java @@ -0,0 +1,228 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.tools.ipgen; + + +import java.util.Set; +import java.util.Map; +import java.util.HashMap; + +import com.avlsi.layout.gdsII.TableEmitterInterface; + + +public class HashMapTableEmitter implements TableEmitterInterface { + + private Map mCellCastToGDSII; + private Map mCellCadenceToGDSII; + private Map mCellGDSIIToCast; + private Map mCellGDSIIToCadence; + private HashMap mNodeCastToGDSII; + private HashMap mNodeCadenceToGDSII; + private HashMap mNodeGDSIIToCast; + private HashMap mNodeGDSIIToCadence; + private HashMap mInstanceCastToGDSII; + private HashMap mInstanceCadenceToGDSII; + private HashMap mInstanceGDSIIToCast; + private HashMap mInstanceGDSIIToCadence; + + public HashMapTableEmitter( final Map cellCastToGDSII, + final Map cellCadenceToGDSII, + final Map cellGDSIIToCast, + final Map cellGDSIIToCadence ) { + mCellCastToGDSII = cellCastToGDSII; + mCellCadenceToGDSII = cellCadenceToGDSII; + mCellGDSIIToCast = cellGDSIIToCast; + mCellGDSIIToCadence = cellGDSIIToCadence; + mNodeCastToGDSII = new HashMap(); + mNodeCadenceToGDSII = new HashMap(); + mNodeGDSIIToCast = new HashMap(); + mNodeGDSIIToCadence = new HashMap(); + mInstanceCastToGDSII = new HashMap(); + mInstanceCadenceToGDSII = new HashMap(); + mInstanceGDSIIToCast = new HashMap(); + mInstanceGDSIIToCadence = new HashMap(); + + } + + public boolean haveCellName( final String castName ) { + return mCellCastToGDSII.containsKey( castName ); + } + + public void emitCellName( final String castName, + final String cadenceName, + final String gdsIIName ) { + mCellCastToGDSII.put( castName, gdsIIName ); + mCellCadenceToGDSII.put( cadenceName, gdsIIName ); + mCellGDSIIToCast.put( gdsIIName, castName ); + mCellGDSIIToCadence.put( gdsIIName, cadenceName ); + } + + public boolean haveNodeName( final String castName ) { + return mNodeCastToGDSII.containsKey( castName ); + } + + public void emitNodeName( final String castName, + final String cadenceName, + final String gdsIIName ) { + mNodeCastToGDSII.put( castName, gdsIIName ); + mNodeCadenceToGDSII.put( cadenceName, gdsIIName ); + mNodeGDSIIToCast.put( gdsIIName, castName ); + mNodeGDSIIToCadence.put( gdsIIName, cadenceName ); + } + + + public boolean haveInstanceName( final String castName ) { + return mInstanceCastToGDSII.containsKey( castName ); + } + + public void emitInstanceName( final String castName, + final String cadenceName, + final String gdsIIName ) { + mInstanceCastToGDSII.put( castName, gdsIIName ); + mInstanceCadenceToGDSII.put( cadenceName, gdsIIName ); + mInstanceGDSIIToCast.put( gdsIIName, castName ); + mInstanceGDSIIToCadence.put( gdsIIName, cadenceName ); + } + + public Set getCastCellNames() { + return mCellCastToGDSII.entrySet(); + } + + public Set getCastNodeNames() { + return mNodeCastToGDSII.entrySet(); + } + + public Set getCastInstanceNames() { + return mInstanceCastToGDSII.entrySet(); + } + + public Set getGDSCellNames() { + return mCellGDSIIToCast.entrySet(); + } + + public Set getGDSNodeNames() { + return mNodeGDSIIToCast.entrySet(); + } + + public Set getGDSInstanceNames() { + return mInstanceGDSIIToCast.entrySet(); + } + + public Set getCadenceCellNames() { + return mCellCadenceToGDSII.entrySet(); + } + + public Set getCadenceNodeNames() { + return mNodeCadenceToGDSII.entrySet(); + } + + public Set getCadenceInstanceNames() { + return mInstanceCadenceToGDSII.entrySet(); + } + + public String getGDSIICellNameForCastCellName( final String castName ) { + return ( String ) mCellCastToGDSII.get( castName ); + } + public String getGDSIICellNameForCadenceCellName( final String cadenceName ) { + return ( String ) mCellCadenceToGDSII.get( cadenceName ); + } + public String getCastCellNameForGDSIICellName( final String gdsIIName ) { + return ( String ) mCellGDSIIToCast.get( gdsIIName ); + } + public String getCadenceCellNameForGDSIICellName( final String gdsIIName ) { + return ( String ) mCellGDSIIToCadence.get( gdsIIName ); + } + public String getCadenceCellNameForCastCellName( final String castName ) { + final String gdsIIName = getGDSIICellNameForCastCellName( castName ); + if ( gdsIIName != null ) { + return getCadenceCellNameForGDSIICellName( gdsIIName ); + } + else { + return null; + } + } + public String getCastCellNameForCadenceCellName( final String cadenceName ) { + final String gdsIIName = getGDSIICellNameForCadenceCellName( cadenceName ); + if ( gdsIIName != null ) { + return getCastCellNameForGDSIICellName( gdsIIName ); + } + else { + return null; + } + } + + public String getGDSIINodeNameForCastNodeName( final String castName ) { + return ( String ) mNodeCastToGDSII.get( castName ); + } + public String getGDSIINodeNameForCadenceNodeName( final String cadenceName ) { + return ( String ) mNodeCadenceToGDSII.get( cadenceName ); + } + public String getCastNodeNameForGDSIINodeName( final String gdsIIName ) { + return ( String ) mNodeGDSIIToCast.get( gdsIIName ); + } + public String getCadenceNodeNameForGDSIINodeName( final String gdsIIName ) { + return ( String ) mNodeGDSIIToCadence.get( gdsIIName ); + } + public String getCadenceNodeNameForCastNodeName( final String castName ) { + final String gdsIIName = getGDSIINodeNameForCastNodeName( castName ); + if ( gdsIIName != null ) { + return getCadenceNodeNameForGDSIINodeName( gdsIIName ); + } + else { + return null; + } + } + public String getCastNodeNameForCadenceNodeName( final String cadenceName ) { + final String gdsIIName = getGDSIINodeNameForCadenceNodeName( cadenceName ); + if ( gdsIIName != null ) { + return getCastNodeNameForGDSIINodeName( gdsIIName ); + } + else { + return null; + } + } + + public String getGDSIIInstanceNameForCastInstanceName( final String castName ) { + return ( String ) mInstanceCastToGDSII.get( castName ); + } + public String getGDSIIInstanceNameForCadenceInstanceName( final String cadenceName ) { + return ( String ) mInstanceCadenceToGDSII.get( cadenceName ); + } + public String getCastInstanceNameForGDSIIInstanceName( final String gdsIIName ) { + return ( String ) mInstanceGDSIIToCast.get( gdsIIName ); + } + public String getCadenceInstanceNameForGDSIIInstanceName( final String gdsIIName ) { + return ( String ) mInstanceGDSIIToCadence.get( gdsIIName ); + } + public String getCadenceInstanceNameForCastInstanceName( final String castName ) { + final String gdsIIName = getGDSIIInstanceNameForCastInstanceName( castName ); + if ( gdsIIName != null ) { + return getCadenceInstanceNameForGDSIIInstanceName( gdsIIName ); + } + else { + return null; + } + } + public String getCastInstanceNameForCadenceInstanceName( final String cadenceName ) { + final String gdsIIName = getGDSIIInstanceNameForCadenceInstanceName( cadenceName ); + if ( gdsIIName != null ) { + return getCastInstanceNameForGDSIIInstanceName( gdsIIName ); + } + else { + return null; + } + } + + public void close() { + } + + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitterFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitterFactory.java new file mode 100644 index 0000000000..27956fc399 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/HashMapTableEmitterFactory.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.ipgen; + + +import java.util.Set; +import java.util.Map; +import java.util.HashMap; + +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.TableEmitterException; + +import com.avlsi.tools.ipgen.HashMapTableEmitter; + +public class HashMapTableEmitterFactory implements TableEmitterFactoryInterface { + + private final HashMap mCellToEmitterMap; + private final Map mCellCastToGDSII; + private final Map mCellCadenceToGDSII; + private final Map mCellGDSIIToCast; + private final Map mCellGDSIIToCadence; + + + public HashMapTableEmitterFactory() { + mCellToEmitterMap = new HashMap( ); + mCellCastToGDSII = new HashMap(); + mCellCadenceToGDSII = new HashMap(); + mCellGDSIIToCast = new HashMap(); + mCellGDSIIToCadence = new HashMap(); + } + + public TableEmitterInterface getTableEmitter( final String castCellName, + final String cadenceCellName, + final String gdsIICellName ) + throws TableEmitterException + { + + final HashMapTableEmitter newEmitter = new HashMapTableEmitter( mCellCastToGDSII, + mCellCadenceToGDSII, + mCellGDSIIToCast, + mCellGDSIIToCadence ); + newEmitter.emitCellName( castCellName, cadenceCellName, gdsIICellName ); + mCellToEmitterMap.put( castCellName, newEmitter ); + return newEmitter; + } + + public HashMapTableEmitter getEmitterForCell( final String castCellName ) { + return ( HashMapTableEmitter ) mCellToEmitterMap.get( castCellName ); + } + + public final String getGDSIICellNameForCastCellName( final String castCellName ) { + + return ( String ) mCellCastToGDSII.get( castCellName ); + } + + public final String getCadenceCellNameForCastCellName( final String castCellName ) { + final String gdsIIName = getGDSIICellNameForCastCellName( castCellName ); + + if ( gdsIIName != null ) { + return ( String ) mCellGDSIIToCadence.get( gdsIIName ); + } + else { + return null ; + } + } + + + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/PMCNameInterfaceFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/PMCNameInterfaceFactory.java new file mode 100644 index 0000000000..ad47603a56 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/PMCNameInterfaceFactory.java @@ -0,0 +1,239 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.ipgen; + + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; + +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; + +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.jauto.CastStat; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Pair; + +public class PMCNameInterfaceFactory implements CDLNameInterfaceFactory { + + /* Interface to allow user of this class to seed the set of existing names + used in each cell to make sure that no generated names in that cells + collides with existing names in that cell.*/ + public interface ExistingNamesInterface { + Set getExistingTranslatedNamesForCell( final String cellName ); + } + + private static class NameInterface implements CDLNameInterface { + private final Map mTransformTransistorModel; + + private final Set mExistingTranslatedNames; + + private final Map mGeneratedNames; + + private final Set mDynamicNodeNames; + + public NameInterface( final Set dynamicNodeNames, + final Set existingTranslatedNames ) { + mTransformTransistorModel = new HashMap(); + + mTransformTransistorModel.put( "P", "p" ); + mTransformTransistorModel.put( "N", "n" ); + + mExistingTranslatedNames = new HashSet( existingTranslatedNames ); + + mGeneratedNames = new HashMap(); + + mDynamicNodeNames = dynamicNodeNames; + + mGeneratedNames.put( "GND", "gnd" ); + mGeneratedNames.put( "Vdd", "vdd" ); + + + } + + public String translateName(String name ) + throws CDLRenameException + { + final String existingGeneratedName = ( String ) mGeneratedNames.get( name ); + + if ( existingGeneratedName == null ) { + + final StringBuffer sb = new StringBuffer(); + + final int nameLength = name.length(); + + int i = 0; + while ( i < nameLength ) { + final char c = name.charAt(i); + + switch (c) { + case '.': + case ',': + case '(': + case ')': + case '{': + case '}': + case '-': + case '_': + sb.append('_'); + break; + default: + if (Character.isLetterOrDigit(c)) { + if ( Character.isLetter( c ) ) { + sb.append( Character.toLowerCase( c ) ); + } + else { + sb.append(c); + } + } + else { + sb.append( '_' ); + } + } + ++i; + } + + final String translatedString = sb.toString(); + String translatedStringWithCounter = translatedString; + int counter = 0; + + while ( mExistingTranslatedNames.contains( translatedStringWithCounter ) ) { + translatedStringWithCounter = translatedString + "_" + Integer.toString( counter ); + ++counter; + } + + final String ret = "f" + translatedStringWithCounter + "m" ; + mExistingTranslatedNames.add( translatedStringWithCounter ); + + mGeneratedNames.put( name, ret ); + + return ret ; + } + else { + return existingGeneratedName ; + } + } + + public String renameCell(String name ) + throws CDLRenameException + { + return translateName( name ); + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + + final String translatedNodeName = translateName( oldNodeName ); + + if ( mDynamicNodeNames.contains( oldNodeName ) ) { + return "zz" + translatedNodeName; + } + else { + return translatedNodeName; + } + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + return translateName( oldDeviceName ); + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + return translateName( oldInstanceName ); + } + + public String renameTransistorModel( final String oldTransistorModel ) + { + + final String translatedModel = ( String ) mTransformTransistorModel.get( oldTransistorModel ); + + if ( translatedModel == null ) { + return oldTransistorModel; + } + else { + return translatedModel; + } + } + } + + + private final CastFileParser mCastParser; + private final Cadencize mCadencizer; + private final ExistingNamesInterface mExistingNamesInterface; + private final Map mDynamicNodesMap; + private final Map mDynamicPortNodesMap; + + public PMCNameInterfaceFactory( final CastFileParser castParser, + final Cadencize cadencizer, + final ExistingNamesInterface existingNamesInterface ) { + mCastParser = castParser; + mCadencizer = cadencizer; + mExistingNamesInterface = existingNamesInterface; + mDynamicNodesMap = new HashMap(); + mDynamicPortNodesMap = new HashMap(); + } + + private Set getDynamicPortNodes( final CellInterface cell ) throws InvalidHierNameException { + return CastStat.getDynamicPortNodes(cell, mCadencizer, mCastParser, + mDynamicPortNodesMap, + mDynamicNodesMap); + } + + private Set getDynamicNodes( final CellInterface cell ) throws InvalidHierNameException { + return CastStat.getDynamicNodes(cell, mCadencizer, mCastParser, + mDynamicPortNodesMap, mDynamicNodesMap); + } + + public CDLNameInterface getNameInterface( final String cellName ) + throws CDLRenameException + { + try { + final CellInterface cell = mCastParser.getFullyQualifiedCell( cellName ); + final Set dynamicNodes = ((Boolean) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.NETLIST_PRIMITIVE)).booleanValue() ? + Collections.EMPTY_SET : + getDynamicNodes( cell ); + /* + Get all the names that have already been used in the current cell. + */ + final Set existingNames = + mExistingNamesInterface.getExistingTranslatedNamesForCell( cellName ); + return new NameInterface( dynamicNodes, existingNames ); + } + catch ( CastSemanticException e ) { + throw new CDLRenameException( "Unable to get \"" + cellName + "\".", e ); + } + catch ( InvalidHierNameException e ) { + throw new CDLRenameException( "Unable to get \"" + cellName + "\".", e ); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/RenamingVerilogFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/RenamingVerilogFactory.java new file mode 100644 index 0000000000..51a7d429f5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/RenamingVerilogFactory.java @@ -0,0 +1,277 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.tools.ipgen; + +import java.util.Map; +import java.util.regex.Pattern; + +import com.avlsi.tools.prs2verilog.verilog.ContinuousAssign; +import com.avlsi.tools.prs2verilog.verilog.Delay; +import com.avlsi.tools.prs2verilog.verilog.Expr; +import com.avlsi.tools.prs2verilog.verilog.Ident; +import com.avlsi.tools.prs2verilog.verilog.ModuleInst; +import com.avlsi.tools.prs2verilog.verilog.Module; +import com.avlsi.tools.prs2verilog.verilog.NetDecl; +import com.avlsi.tools.prs2verilog.verilog.ParameterDecl; +import com.avlsi.tools.prs2verilog.verilog.Primitive; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryImpl; +import com.avlsi.tools.prs2verilog.verilog.TrivialVisitor; +import com.avlsi.tools.prs2verilog.NetgraphGateConverter; + +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.tools.ipgen.HashMapTableEmitter; +import com.avlsi.tools.ipgen.HashMapTableEmitterFactory; + +public class RenamingVerilogFactory extends VerilogFactoryImpl { + + + private static class RenamingIdent extends Ident { + + private boolean renamed; + + public RenamingIdent( final String ident, boolean escape ) { + super( ident, escape ); + renamed = false; + } + + public void rename( final String newIdent ) { + if ( ! ( renamed ) ) { + ident = newIdent; + renamed = true; + } + } + + public String getStr() { + return ident; + } + } + + private abstract static class IdentRenameVisitor extends TrivialVisitor { + protected final HashMapTableEmitter mTable; + protected final CDLNameInterface mNamer; + private final VerilogObject mObj; + + public IdentRenameVisitor( HashMapTableEmitter table, CDLNameInterface namer, VerilogObject objToVisit ) { + mTable = table; + mNamer = namer; + mObj = objToVisit; + mObj.accept( this ); + } + + public void ident( final String ident, final boolean escape ) { + final RenamingIdent obj = ( RenamingIdent ) mObj; + String newName = renameIdent( ident ); + + if ( newName == null ) { + final StringBuffer newNameBuffer = new StringBuffer(); + int i; + for ( i = 0 ; i < ident.length() ; ++i) { + final char c = ident.charAt( i ); + if ( ! ( Character.isLetterOrDigit( c ) ) ) { + if ( c == '\\' ) { + newNameBuffer.append( '\\' ); + } + else if ( c == '`' ) { + newNameBuffer.append( '`' ); + } + else { + newNameBuffer.append( '_' ); + } + } + else { + newNameBuffer.append( c ); + } + } + + newName = newNameBuffer.toString(); + } + obj.rename( newName ); + } + + public abstract String renameIdent( final String ident ); + } + + private static class CellNameVisitor extends IdentRenameVisitor { + + public CellNameVisitor( HashMapTableEmitter table, CDLNameInterface namer, VerilogObject objToVisit ) { + super( table, namer, objToVisit ); + } + + public String renameIdent( final String ident ) { + final String s = mTable.getGDSIICellNameForCastCellName( ident ); + try { + if (s == null && mNamer != null) + return mNamer.renameCell( ident ); + else return s; + } catch (CDLRenameException e) { + return null; + } + } + } + + private static class NodeNameVisitor extends IdentRenameVisitor { + public NodeNameVisitor( HashMapTableEmitter table, CDLNameInterface namer, VerilogObject objToVisit ) { + super( table, namer, objToVisit ); + } + + public String renameIdent( final String ident ) { + final String s = mTable.getGDSIINodeNameForCastNodeName( ident ); + try { + if (s == null && mNamer != null && + !ident.equals(NetgraphGateConverter.CLK)) + return mNamer.renameNode( ident ); + else return s; + } catch (CDLRenameException e) { + return null; + } + } + } + + private static class InstanceNameVisitor extends IdentRenameVisitor { + public InstanceNameVisitor( HashMapTableEmitter table, CDLNameInterface namer, VerilogObject objToVisit ) { + super( table, namer, objToVisit ); + } + + public String renameIdent( final String ident ) { + final String s = mTable.getGDSIIInstanceNameForCastInstanceName( ident ); + try { + if (s == null && mNamer != null) + return mNamer.renameSubCellInstance( ident ); + else return s; + } catch (CDLRenameException e) { + return null; + } + } + } + + + private static class RenameVisitor extends TrivialVisitor { + private final HashMapTableEmitter mCellMap; + private final CDLNameInterface mNamer; + private static final Pattern VERILOG_INSTANCE = + Pattern.compile(".*\\$\\d+$"); + + public RenameVisitor( final HashMapTableEmitter cellMap, final CDLNameInterface namer ) { + mCellMap = cellMap; + mNamer = namer; + } + + public void moduleInst( final VerilogObject ident, + final VerilogObject module, + final VerilogObject[] parameters, + final VerilogObject[] ports ) { + // leave the cell name untouched if the instance came from a + // verilog block; this, sadly, depends on the naming convention + if (!(ident instanceof RenamingIdent) || + !VERILOG_INSTANCE.matcher(((RenamingIdent) ident).getStr()) + .matches()) { + new CellNameVisitor( mCellMap, mNamer, module ); + module.accept( this ); // if module is actually a macro + } + + new InstanceNameVisitor( mCellMap, mNamer, ident ); + + int i; + for ( i = 0 ; i < ports.length ; ++i ) { + new NodeNameVisitor( mCellMap, mNamer, ports[i] ); + } + } + + public void netDecl( final String type, + final VerilogObject ident, + final VerilogObject delay ) { + new NodeNameVisitor( mCellMap, mNamer, ident ); + } + + public void primitive( final String type, + final VerilogObject delay, + final VerilogObject ident, + final VerilogObject[] terminals ) { + if ( ident != null ) { + new InstanceNameVisitor( mCellMap, mNamer, ident ); + } + int i; + for ( i = 0 ; i < terminals.length ; ++i ) { + new NodeNameVisitor( mCellMap, mNamer, terminals[i] ); + } + } + + public void parameterDecl( final VerilogObject ident, final String type ) { + new NodeNameVisitor( mCellMap, mNamer, ident ); + } + + public void concatOp(final VerilogObject[] elements) { + for (int i = 0; i < elements.length; ++i) { + new NodeNameVisitor(mCellMap, mNamer, elements[i]); + } + } + + public void namedPort(final VerilogObject portName, final VerilogObject port) { + new NodeNameVisitor(mCellMap, mNamer, port); + } + + public void macroUse(final VerilogObject ident, + final VerilogObject[] args) { + new CellNameVisitor( mCellMap, mNamer, ident ); + if (args != null) { + for (int i = 0; i < args.length; ++i) args[i].accept(this); + } + } + } + + private final HashMapTableEmitterFactory mCellMaps; + private final CDLNameInterfaceFactory mCdlFactory; + + public RenamingVerilogFactory( final HashMapTableEmitterFactory cellMaps, + final CDLNameInterfaceFactory cdlFactory ) { + mCellMaps = cellMaps; + mCdlFactory = cdlFactory; + } + + public VerilogObject ident( final String ident, boolean escape ) { + return new RenamingIdent( ident, escape ); + } + + public VerilogObject module( final VerilogObject ident, + final VerilogObject[] ports, + final VerilogObject[] items ) { + final VerilogObject ret = super.module( ident, + ports, + items ); + + final String cellName = ( ( RenamingIdent ) ident ).getStr(); + final HashMapTableEmitter cellMap = mCellMaps.getEmitterForCell( cellName ); + final CDLNameInterface namer; + try { + namer = + mCdlFactory == null ? null + : mCdlFactory.getNameInterface( cellName ); + } catch (CDLRenameException e) { + throw new RuntimeException("Cannot get name interface for " + + cellName, e); + } + if ( cellMap != null ) { + int i; + new CellNameVisitor( cellMap, namer, ident ); + for ( i = 0 ; i < ports.length ; ++i ) { + new NodeNameVisitor( cellMap, namer, ports[i] ); + } + + final RenameVisitor visitor = new RenameVisitor( cellMap, namer ); + for ( i = 0 ; i < items.length ; ++i ) { + items[i].accept( visitor ); + } + } + return ret; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/TablifyingNameInterfaceFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/TablifyingNameInterfaceFactory.java new file mode 100644 index 0000000000..287cd85a7c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/TablifyingNameInterfaceFactory.java @@ -0,0 +1,165 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.ipgen; + + +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; + +import com.avlsi.layout.gdsII.TableEmitterInterface; +import com.avlsi.layout.gdsII.TableEmitterFactoryInterface; +import com.avlsi.layout.gdsII.TableEmitterException; + + +public class TablifyingNameInterfaceFactory implements CDLNameInterfaceFactory { + + private static final class TablifyingNameInterface implements CDLNameInterface { + + private final CDLNameInterface mCadenceNameInterface; + private final CDLNameInterface mGDSIINameInterface; + + private final TableEmitterInterface mTableEmitter; + + public TablifyingNameInterface( final CDLNameInterface cadenceNameInterface, + final CDLNameInterface gdsIINameInterface, + final TableEmitterInterface tableEmitter ) { + + mCadenceNameInterface = cadenceNameInterface; + mGDSIINameInterface = gdsIINameInterface; + mTableEmitter = tableEmitter; + + } + + public String renameCell(String name ) + throws CDLRenameException + { + final String gdsIICellName = mGDSIINameInterface.renameCell( name ); + if ( ! ( mTableEmitter.haveCellName( name ) ) ) { + final String cadenceCellName = mCadenceNameInterface.renameCell( name ); + try { + mTableEmitter.emitCellName( name, cadenceCellName, gdsIICellName ); + } + catch ( TableEmitterException e ) { + throw new CDLRenameException( e ); + } + } + return gdsIICellName; + } + + public String renameNode( final String oldNodeName ) + throws CDLRenameException + { + + final String gdsIINodeName = mGDSIINameInterface.renameNode( oldNodeName ); + if ( ! ( mTableEmitter.haveNodeName( oldNodeName ) ) ) { + final String cadenceNodeName = mCadenceNameInterface.renameNode( oldNodeName ); + try { + mTableEmitter.emitNodeName( oldNodeName, cadenceNodeName, gdsIINodeName ); + } + catch ( TableEmitterException e ) { + throw new CDLRenameException( e ); + } + } + return gdsIINodeName; + + } + + public String renameDevice( final String oldDeviceName ) + throws CDLRenameException + { + final String gdsIIDeviceName = mGDSIINameInterface.renameDevice( oldDeviceName ); + if ( ! ( mTableEmitter.haveInstanceName( oldDeviceName ) ) ) { + final String cadenceDeviceName = mCadenceNameInterface.renameDevice( oldDeviceName ); + try { + mTableEmitter.emitInstanceName( oldDeviceName, cadenceDeviceName, gdsIIDeviceName ); + } + catch ( TableEmitterException e ) { + throw new CDLRenameException( e ); + } + } + return gdsIIDeviceName; + } + + public String renameSubCellInstance( final String oldInstanceName ) + throws CDLRenameException + { + final String gdsIIInstanceName = mGDSIINameInterface.renameSubCellInstance( oldInstanceName ); + if ( ! ( mTableEmitter.haveInstanceName( oldInstanceName ) ) ) { + final String cadenceInstanceName = mCadenceNameInterface.renameSubCellInstance( oldInstanceName ); + try { + mTableEmitter.emitInstanceName( oldInstanceName, cadenceInstanceName, gdsIIInstanceName ); + } + catch ( TableEmitterException e ) { + throw new CDLRenameException( e ); + } + } + return gdsIIInstanceName; + } + + public String renameTransistorModel( final String oldTransistorModel ) + throws CDLRenameException + { + return mGDSIINameInterface.renameTransistorModel( oldTransistorModel ); + } + + public void close() throws TableEmitterException { + mTableEmitter.close(); + } + } + + private final TableEmitterFactoryInterface mTableEmitterFactory; + private final CDLNameInterfaceFactory mCadenceNameInterfaceFactory; + private final CDLNameInterfaceFactory mGDSIINameInterfaceFactory; + + private TablifyingNameInterface mCurrNameInterface; + + public TablifyingNameInterfaceFactory( final TableEmitterFactoryInterface tableEmitterFactory, + final CDLNameInterfaceFactory cadenceNameInterfaceFactory, + final CDLNameInterfaceFactory gdsIINameInterfaceFactory ) { + mTableEmitterFactory = tableEmitterFactory; + mCadenceNameInterfaceFactory = cadenceNameInterfaceFactory; + mGDSIINameInterfaceFactory = gdsIINameInterfaceFactory; + mCurrNameInterface = null; + } + + + public CDLNameInterface getNameInterface( final String cellName ) + throws CDLRenameException + { + + final CDLNameInterface cadenceNameInterface = mCadenceNameInterfaceFactory.getNameInterface( cellName ); + final CDLNameInterface gdsIINameInterface = mGDSIINameInterfaceFactory.getNameInterface( cellName ); + + final String cadenceCellName = cadenceNameInterface.renameCell( cellName ); + final String gdsIICellName = gdsIINameInterface.renameCell( cellName ); + + try { + close(); + final TableEmitterInterface tableEmitter = mTableEmitterFactory.getTableEmitter( cellName, + cadenceCellName, + gdsIICellName ); + mCurrNameInterface = new TablifyingNameInterface( cadenceNameInterface, + gdsIINameInterface, + tableEmitter ); + return mCurrNameInterface; + } + catch ( TableEmitterException e ) { + throw new CDLRenameException( e ); + } + + } + + public final void close() throws TableEmitterException { + if ( mCurrNameInterface != null ) { + mCurrNameInterface.close(); + mCurrNameInterface = null; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/custom.mk new file mode 100644 index 0000000000..a40d82b41a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/ipgen/custom.mk @@ -0,0 +1,8 @@ +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +$(CURR_TARGET_DIR)/generate_ip_data.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.ipgen.GenerateIPData/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AbstractPath.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AbstractPath.java new file mode 100644 index 0000000000..019964379f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AbstractPath.java @@ -0,0 +1,186 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedWriter; +import java.util.Iterator; +import java.util.Set; + +import com.avlsi.fast.CellNet; +import com.avlsi.fast.CellType; +import com.avlsi.util.text.NumberFormatter; + +/** + * Abstract base class for SizingPath and CatPath. + * + * @author Jesse Rosenstock + * @version $Revision$ $Date$ + **/ +abstract class AbstractPath { + Set/**/ startNets; + + CellNet endNet; + + /** + * The highest level cell containing this cat path. + **/ + CellType container; + + boolean isFragment; + + boolean isReduced; + + boolean isEndNetNonObservable; + + /** Calculated delay from timing analysis */ + double[] delay; + + /** Calculated slack from timing analysis */ + double[] slack; + + /** Instance delaybias applied to this path */ + double[] delaybias; + + /** The acceptable delay budgets for this path */ + double[] signoff; + + /** Cell net of last half-operator with least slack */ + CellNet criticalNet; + + abstract void setStartEndNets(boolean completeCatPath); + + abstract String printPath(); + + abstract void dumpInfo(BufferedWriter bw1, String prefix); + + abstract double getAverageWidth(); + + public abstract boolean isComponentsFixed(); + + public boolean isFixedSize() { + if (!isComponentsFixed()) return false; + + for (Iterator ita = criticalNet.getGlobalNets().iterator(); + ita.hasNext(); ) { + GlobalNet gna = (GlobalNet)ita.next(); + for (Iterator itb = gna.getListSinks().iterator(); + itb.hasNext(); ) { + final NetSink nska = (NetSink) itb.next(); + if (nska.getType() == NetType.HALF_OPERATOR_TRANSISTOR) { + if (!nska.sink.subType.isFixedSize()) return false; + } + } + } + + return true; + } + + public boolean isFixedSize(int n) { + if (!isComponentsFixed()) return false; + + final GlobalNet gna = (GlobalNet) getEndNet().getGlobalNets().get(n); + for (Iterator itb = gna.getListSinks().iterator(); itb.hasNext(); ) { + final NetSink nska = (NetSink) itb.next(); + if (nska.getType() == NetType.HALF_OPERATOR_TRANSISTOR) { + if (!nska.sink.subType.isFixedSize()) return false; + } + } + + return true; + } + + public boolean isFragment() + { + return isFragment; + } + + + public boolean setIsFragment(boolean b1) + { + isFragment = b1; + + return isFragment; + } + + + + public Set/**/ getStartNets() + { + return startNets; + } + + + public Set setStartNets(Set/**/ set1) + { + startNets.clear(); + startNets.addAll(set1); + + return startNets; + } + + + public CellNet getEndNet() + { + return endNet; + } + + + public CellNet setEndNet(CellNet cn1) + { + endNet = cn1; + + return endNet; + } + + abstract CatPath popUp(boolean isEndNonObservable, + boolean hasObservable, + Set/**/ nonObservableStartNets, + CellNet endNet); + + protected static String printDelay(final double x) { + return NumberFormatter.format(x * 1e12, 3); + } + + protected static String printDelay(final double[] x) { + final StringBuffer result = new StringBuffer(); + result.append('['); + for (int i = 0; i < x.length; ++i) { + result.append(printDelay(x[i])); + if (i < x.length - 1) result.append(' '); + } + result.append(']'); + return result.toString(); + } + + public abstract String printPath(int n); + + abstract void getPathString(StringBuffer buf); + + public double getBudget(int i) { + return signoff == null || Double.isNaN(signoff[i]) ? + (delay[i] + slack[i]) : signoff[i]; + } + + public double getDelay(int i) { + return delay[i]; + } + + public double getSlack(int i) { + return getBudget(i) - getDelay(i); + } + + public double getRealSlack(int i) { + return slack[i]; + } + + protected void getNetString(final StringBuffer buf, final CellNet net) { + buf.append(net.container.typeName); + buf.append('/'); + buf.append(net.canonicalName.getCadenceString()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AdditiveTerms.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AdditiveTerms.java new file mode 100644 index 0000000000..6bd954a5ca --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AdditiveTerms.java @@ -0,0 +1,42 @@ +package com.avlsi.tools.jauto; + +import java.util.Arrays; +import java.util.ArrayList; + +/** + * Represents the sum of a list of FunctionTerms. + **/ +public class AdditiveTerms extends ArrayList { + public AdditiveTerms(final int capacity) { + super(capacity); + } + public AdditiveTerms(final FunctionTerm... terms) { + super(Arrays.asList(terms)); + } + public AdditiveTerms multiply(final AdditiveTerms that) { + final AdditiveTerms result = + new AdditiveTerms(this.size() * that.size()); + for (FunctionTerm a : this) { + for (FunctionTerm b : that) { + result.add(a.multiply(b)); + } + } + return result; + } + public AdditiveTerms multiply(final FunctionTerm term) { + return multiply(new AdditiveTerms(term)); + } + public String toString() { + final StringBuilder sb = new StringBuilder(); + boolean first = true; + for (FunctionTerm t : this) { + if (first) { + first = false; + } else { + sb.append(" + "); + } + sb.append(t.toString()); + } + return sb.toString(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AutoThreshold.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AutoThreshold.java new file mode 100644 index 0000000000..aaeef462d1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/AutoThreshold.java @@ -0,0 +1,553 @@ +package com.avlsi.tools.jauto; + +import java.io.BufferedWriter; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Formatter; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Set; +import java.util.Map; +import java.util.List; +import java.util.HashSet; + +import com.avlsi.cast.CastCacheManager; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.DirectiveUtils.IdleState; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.fast.HalfOperator; +import com.avlsi.io.FileSearchPath; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.BinaryPredicate; +import JaCoP.constraints.And; +import JaCoP.constraints.Not; +import JaCoP.constraints.Or; +import JaCoP.constraints.PrimitiveConstraint; +import JaCoP.constraints.XeqC; +import JaCoP.core.BooleanVar; +import JaCoP.core.Store; +import JaCoP.search.DepthFirstSearch; +import JaCoP.search.IndomainMin; +import JaCoP.search.InputOrderSelect; +import JaCoP.search.Search; +import JaCoP.search.SelectChoicePoint; + +public final class AutoThreshold { + public static enum Option { + FAST_NON_LEAKY, + FAST_2OFF_NMOS, + FAST_2OFF_PMOS, + SLOW_1OFF_NMOS, + SLOW_1OFF_PMOS, + FAST_VS_WEAK_ALLOWED, + SLOW_VS_WEAK_ALLOWED; + }; + + static IdleStateSolver s; + static int minOffTransistors = 2; + //Returns AND of all gates in one path + private static PrimitiveConstraint expandLogic(final NetGraph.NetPath path, + final boolean invert, final boolean print) { + final Set gates = + (Set) path.getGateNodes(); + boolean first = true; + + + PrimitiveConstraint c_path = null; + ArrayList c_gates = + new ArrayList(); + BooleanVar Var; + + for (NetGraph.NetNode gate : gates) { + if (first) + first = false; + else{ + if(DebugOption.printLevel <= 1){ + if (print) System.out.print(" & "); + } + } + Var = s.getVariable(gate.name.toString()); + + if (invert) + c_gates.add(new Not(new XeqC(Var,1))); + else + c_gates.add(new XeqC(Var,1)); + if(print && DebugOption.printLevel <= 1){ + System.out.print((invert ? "~" : "") + gate.name); + } + + } + c_path = new And(c_gates); + + return c_path; + } + // Returns OR of all paths in one half operator + private static PrimitiveConstraint expandLogic( + final Collection paths, + final boolean invert ,final boolean print){ + boolean first = true; + PrimitiveConstraint c_half ; + ArrayList c_paths = + new ArrayList();; + + for (NetGraph.NetPath path : paths) { + final String lead; + if (first) { + first = false; + } + else { + if(print && DebugOption.printLevel <= 1){ + System.out.print(" | "); + } + } + c_paths.add(expandLogic(path, invert,print)); + } + c_half = new Or(c_paths); + return c_half; + } + + /* Adds the final constraint for each node + For any node X pulluplogic -> X+ pulldownlogic -> X- + The constraint will be ( ~pulluplogic & ~X)|(~pulldownlogic & X) = T + */ + private static void expandLogic(final NetGraph.NetNode node,boolean print){ + final Collection up = + new ArrayList(); + final Collection dn = + new ArrayList(); + + for (Iterator j = node.getLogicPaths().iterator(); j.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) j.next(); + final int dir = path.getType(); + if (dir == DeviceTypes.N_TYPE) { + dn.add(path); + } else { + assert dir == DeviceTypes.P_TYPE; + up.add(path); + } + } + + final boolean comb = node.isCombinational(); + + + BooleanVar Var= s.getVariable(node.name.toString()); + PrimitiveConstraint c_pullUp =null,c_pullDown = null; + PrimitiveConstraint c_node,c1,c2; + + if (!up.isEmpty()){ + c_pullUp = expandLogic(up, true ,print); + if(print && DebugOption.printLevel <= 1){ + System.out.println(" " + (comb ? "=>" : "->") + " " + + node.name + "+"); + } + } + if (!dn.isEmpty()) { + if (!comb){ + c_pullDown = expandLogic(dn, false ,print); + if (print && DebugOption.printLevel <= 1){ + System.out.println(" -> " + node.name + "-"); + } + } + else{ + c_pullDown = expandLogic(dn, false ,false); + } + } + if (c_pullUp!= null) + c1 = new And(new Not(c_pullUp),new Not(new XeqC(Var,1))); + else + c1 = new Not(new XeqC(Var,1)); + if(c_pullDown!= null) + c2 = new And(new Not(c_pullDown),new XeqC(Var,1)); + else + c2 = new XeqC(Var,1); + c_node = new Or (c1,c2); + s.addConstraint(c_node); + } + private static boolean getOptionValue(Option key,Map options){ + boolean val = false; + if(options.containsKey(key)){ + if(options.get(key)) val = true; + } + return val; + + } + + /* + Counts the off transistors in a single path. Checks if at least 2 are OFF + For pullup path ( invert = true) check for the gate to be equal to 1 and + for pulldown path( invert = false) check for the gate to be equal to 0 */ + private static boolean getTransistorType(final NetGraph.NetPath path, + final boolean invert) { + final Set gates = + (Set) path.getGateNodes(); + + BooleanVar Var; + int countOffs=0; + boolean minOffs = false; + + for (NetGraph.NetNode gate : gates) { + Var = s.getVariable(gate.name.toString()); + if (s.idleStates.containsKey(Var.id)) { + if(s.idleStates.get(Var.id) == 1 && invert) countOffs++; + else if (s.idleStates.get(Var.id) == 0 && !invert) countOffs++; + } + } + if (countOffs >= minOffTransistors) minOffs=true; + return minOffs; + } + /* Checks if all the paths for the half operator have 2 or more than 2 + off transistors*/ + private static boolean getTransistorType(final Collection paths, + final boolean invert) { + boolean offAllPaths = false; + int tempCountOffs=0; + boolean temp; + for (NetGraph.NetPath path : paths) { + temp = getTransistorType(path, invert); + if(temp) tempCountOffs++; + } + //If all paths on the half operator have 2 or more than 2 + //transistors off + if (tempCountOffs == paths.size()) offAllPaths = true;; + return offAllPaths; + } + /* Finds the transistor type. For idle state of X = 1 the X+ = LVT and + X-= HVT and for idle state of X = 0 X+ = HVT and X- = LVT. The HVT operator + is again checked for the off transistor condition and can be assigned LVT + if the ocndition is satisfied*/ + private static void getTransistorType( + final String cellName, + final NetGraph.NetNode node, + final int stt, + final int tt, + final int ftt, + final Map ttup, + final Map ttdn, + final Map is, + final Map options){ + final Collection up = + new ArrayList(); + final Collection dn = + new ArrayList(); + + + for (Iterator j = node.getLogicPaths().iterator(); j.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) j.next(); + final int dir = path.getType(); + if (dir == DeviceTypes.N_TYPE) { + dn.add(path); + } else { + assert dir == DeviceTypes.P_TYPE; + up.add(path); + } + } + + + final BooleanVar Var= s.getVariable(node.name.toString()); + + + boolean fastnonleaky = getOptionValue(Option.FAST_NON_LEAKY,options); + boolean fast2offpmos = getOptionValue(Option.FAST_2OFF_NMOS,options); + boolean fast2offnmos = getOptionValue(Option.FAST_2OFF_PMOS,options); + + boolean slow1offpmos = getOptionValue(Option.SLOW_1OFF_PMOS,options); + boolean slow1offnmos = getOptionValue(Option.SLOW_1OFF_NMOS,options); + boolean fastvsweakallowed = getOptionValue(Option.FAST_VS_WEAK_ALLOWED,options); + boolean slowvsweakallowed = getOptionValue(Option.SLOW_VS_WEAK_ALLOWED,options); + + + Pair pairUp,pairDown; + boolean isLibraryGate = (node.getGate() != null); + boolean hasWeakFeedBackUp = node.hasWeakFeedBack(DeviceTypes.N_TYPE); + boolean hasWeakFeedBackDown = node.hasWeakFeedBack(DeviceTypes.P_TYPE); + boolean upfastallowed = true; + boolean upslowallowed = true; + boolean downfastallowed = true; + boolean downslowallowed = true; + + if(hasWeakFeedBackUp && !fastvsweakallowed) upfastallowed = false; + if(hasWeakFeedBackUp && !slowvsweakallowed) upslowallowed = false; + if(hasWeakFeedBackDown && !fastvsweakallowed) downfastallowed = false; + if(hasWeakFeedBackDown && !slowvsweakallowed) downslowallowed = false; + + if (s.idleStates.containsKey(Var.id)){ + + pairUp = new Pair( node.name,true); + pairDown = new Pair(node.name,false); + // IdleState of this node is IDLE_1 + if (s.idleStates.get(Var.id) ==1){ + + // Non Leaky Direction + if(fastnonleaky && upfastallowed){ + if(!ttup.containsKey(node.name)) s.transistorTypes.put(pairUp,ftt); + System.out.println("TransType("+Var.id+ + "+)=FAST"); + } + else{ + //if(!ttup.containsKey(node.name)) s.transistorTypes.put(pairUp,tt); + System.out.println("TransType("+Var.id+ + "+)=DEF"); + + } + //Leaky Direction + boolean offDown2 = false, offDown1 = false; + if (isLibraryGate) { + minOffTransistors = 2; + offDown2 = getTransistorType(dn, false); + if(!offDown2){ + minOffTransistors = 1; + offDown1 = getTransistorType(dn, false); + } + } + if(fast2offnmos && offDown2 && downfastallowed){ + if(!ttdn.containsKey(node.name)) s.transistorTypes.put(pairDown,ftt); + System.out.println("TransType("+Var.id+ + "-)=FAST"); + + } + + else if(slow1offnmos && offDown1 && downslowallowed){ + if(!ttdn.containsKey(node.name)) s.transistorTypes.put(pairDown,stt); + System.out.println("TransType("+Var.id+ + "-)=SLOW"); + + } + else{ + //if(!ttdn.containsKey(node.name)) s.transistorTypes.put(pairDown,tt); + System.out.println("TransType("+Var.id+ + "-)=DEF"); + } + + } + else if (s.idleStates.get(Var.id)==0){ + //Non-leaky direction + if(fastnonleaky && downfastallowed){ + if(!ttdn.containsKey(node.name)) s.transistorTypes.put(pairDown,ftt); + System.out.println("TransType("+Var.id+ + "-)=FAST"); + } + else{ + //if(!ttdn.containsKey(node.name)) s.transistorTypes.put(pairDown,tt); + System.out.println("TransType("+Var.id+ + "-)=DEF"); + } + //Leaky direction + boolean offUp2 = false, offUp1 = false; + if (isLibraryGate) { + minOffTransistors = 2; + offUp2 = getTransistorType(up, true); + if(!offUp2){ + minOffTransistors = 1; + offUp1= getTransistorType(up, true); + } + } + if(fast2offpmos && offUp2 && upfastallowed){ + if(!ttup.containsKey(node.name)) s.transistorTypes.put(pairUp,ftt); + System.out.println("TransType("+Var.id+ + "+)=FAST"); + + } + else if(slow1offpmos && offUp1 && upslowallowed){ + if(!ttup.containsKey(node.name)) s.transistorTypes.put(pairUp,stt); + System.out.println("TransType("+Var.id+ + "+)=SLOW"); + + } + else{ + //if(!ttup.containsKey(node.name)) s.transistorTypes.put(pairUp,tt); + System.out.println("TransType("+Var.id+ + "+)=DEF"); + } + + + } + else + { + boolean unknown = true; + if(is.containsKey(node.name)){ + IdleState id= is.get(node.name); + if (id == IdleState.IDLE_UNKNOWN) unknown=false; + } + + if(unknown) System.err.println("WARNING TransType ("+ + Var.id+"+) = UNKNOWN in "+cellName + +"\nWARNING TransType ("+ + Var.id+"-) = UNKNOWN in "+ cellName); + } + } + } + private static void resolveSharingConflict( + final List halfops, + final int stt, + final int ftt, + final Map ttup, + final Map ttdn, + final String cellName){ + // s is the hash map of Map,Integer> + /* The last step is to check if any of the half operators are sharing + * transistor. If they are sharing and if there is a conflict in + * their transistor types, then the method should make a + * conservative decision and assign HVT or Slow transistor type in + * this case */ + + //halfOpSharings : A list of lists. Each list is a list of Haloperators that share transistors. + //Its a partition of the hals operators from the cell formed by the + //transitive closure of the isSharingWith Relation + Collection coll = halfops; + Collection> halfOpSharings = + CollectionUtils.computeTransitiveClosure(coll, + new BinaryPredicate() { + public boolean evaluate(final HalfOperator a,final HalfOperator b){ + return a.isSharingWith(b); + } + }); + /*For each such list/group in the halfOpSharings + * Check if there is a conflict in any of the + * halfoperators. + * If there is, change the transistor types to SLOW + * This is applicable only for the halfoperators that do no have user defined + * transistor types*/ + for (final Collection hoList: halfOpSharings){ + boolean conflict = false; + int prev = -1; + for(final HalfOperator ho: hoList){ + int curr = -1; + final NetGraph.NetNode node = + ho.outputNode; + Pair hPair; + if(ho.driveDirection == HalfOperator.DriveDirection.PULL_UP){ + hPair = new Pair(node.name,true); + if(ttup.containsKey(node.name)) + curr = ttup.get(node.name).intValue(); + } + else{ + hPair = new Pair(node.name,false); + if(ttdn.containsKey(node.name)) + curr = ttdn.get(node.name).intValue(); + } + if (s.transistorTypes.containsKey(hPair)){ + curr = s.transistorTypes.get(hPair).intValue(); + } + if(prev!= -1 && curr!=prev){ + conflict = true; + break; + } + } + /*There is a conflict in the group so change the + * transistor types of all the half operators + * in this group to SLOW*/ + if (conflict){ + System.out.println("There was a conflict"); + for(final HalfOperator ho:hoList){ + final NetGraph.NetNode node = + ho.outputNode; + Pair hPair; + if(ho.driveDirection == HalfOperator.DriveDirection.PULL_UP){ + hPair = new Pair(node.name,true); + } + else{ + hPair = new Pair(node.name,false); + } + if (s.transistorTypes.containsKey(hPair)){ + s.transistorTypes.put(hPair,stt); + } + else{ + System.err.println("ERROR :Conflict with a user defined "+ + "transistor type for a HalfOperator"+ + cellName); + } + } + } + + } + + } + + public static Map,Integer> getTransistorTypesMap( + final String cellName, + final Map is, + final NetGraph graph, + final int stt, + final int tt, + final int ftt, + final Map ttup, + final Map ttdn, + final List halfops, + final Map options){ + + + ///Get all the nodes from the Half Operators list + + final Set nodeList = + new HashSet(); + for (final HalfOperator ho : halfops) { + final NetGraph.NetNode node = (NetGraph.NetNode) ho.outputNode; + if (!node.isOutput() || !node.isNamed()) continue; + if(!nodeList.contains(node)) + nodeList.add(node); + } + + + final int size = graph.getNodes().size(); + boolean print = true; + s = new IdleStateSolver(size); + + //Expand the PRS, Add variables to the JaCoP store, add + //the constraints + + for (final NetGraph.NetNode node : nodeList){ + expandLogic(node,print); + } + + + //Add the constraints from the directives + for (final HierName var : is.keySet()){ + IdleState id= is.get(var); + //System.out.println("The var is :"+var.toString()+"="+ id); + if (id == IdleState.IDLE_0) + s.addDirectiveConstraint(var.toString(),0); + else if(id == IdleState.IDLE_1) + s.addDirectiveConstraint(var.toString(),1); + } + + // Solve the PRS equations and get the Idle states + s.printSolution(cellName,size); + + + + //Get the Transistor Type directives + + for (final NetGraph.NetNode node : nodeList){ + getTransistorType(cellName,node,stt,tt,ftt,ttup,ttdn,is,options); + } + + resolveSharingConflict(halfops,stt,ftt,ttup,ttdn,cellName); + return s.transistorTypes; + + + } +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CDLOutput.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CDLOutput.java new file mode 100644 index 0000000000..8aa00a5764 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CDLOutput.java @@ -0,0 +1,155 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.IOException; +import java.io.Writer; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.CellType; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.file.common.HierName; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.CDLEmitter; +import com.avlsi.netlist.impl.DeviceProcessor; +import com.avlsi.netlist.impl.FoldTransistor; +import com.avlsi.netlist.impl.NetlistFormatter; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.debug.Debug; + +/** + * Class to output CDL. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ +public final class CDLOutput { + + /** + * This class cannot be instantiated. + **/ + private CDLOutput() { + throw new AssertionError(); + } + + /** + * Convert a Map of Symbol to FloatValue to a Map of String to Token. + **/ + private static Map getParameters(final Map params) { + final TreeMap m = new TreeMap(); + for (Iterator i = params.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Symbol s = (Symbol) entry.getKey(); + final FloatValue v = (FloatValue) entry.getValue(); + double vs = 0; + try { + vs = v.getValue(); + } catch (InvalidOperationException e) { + Debug.assertTrue(false, "Should not happen!"); + } + m.put(s.getString(), new CDLLexer.SimpleToken(new Double(vs))); + } + return m; + } + + /** + * Generate an appropriate subcircuit call for a given cell. + **/ + static void templateHeader(final CellInterface ci, + final Map params, + final CDLFactoryInterface factory, + final Cadencize cadencizer) { + Set port = NetlistAdapter.getParameterList(ci, cadencizer); + String ports[] = new String[port.size()]; + int j = 0; + for (Iterator i = port.iterator(); i.hasNext(); j++) { + final HierName h = (HierName) i.next(); + ports[j] = h.getCadenceString(); + } + final Map parameters = getParameters(params); + factory.beginSubcircuit(ci.getFullyQualifiedType(), new String[0], + ports, parameters, null); + } + + /** + * Write out a CDL template to a writer. + **/ + public static void writeCDL(final CellInterface ci, + final Cadencize cadencizer, + final Writer w) { + writeCDL(ci, cadencizer, new CDLFactoryEmitter(w)); + } + + /** + * Write out a CDL template to a CDLFactoryInterface. + **/ + public static void writeCDL(final CellInterface ci, + final Cadencize cadencizer, + final CDLFactoryInterface factory) { + final NetlistBlock block = (NetlistBlock) ci.getBlockInterface().iterator(BlockInterface.NETLIST).next(); + templateHeader(ci, block.getParams(), factory, cadencizer); + if (!block.isEmpty()) block.getCDLTemplate().execute(factory); + factory.endSubcircuit(ci.getFullyQualifiedType(), null); + } + + static CDLEmitter getCDLEmitter(final Writer w, String lengthUnit) { + if (lengthUnit.length() > 1) lengthUnit = lengthUnit.substring(0, 1); + return new CDLEmitter(w, lengthUnit, 6); + } + + /** + * Write out a NetGraph. + **/ + public static void writeCDL(final CellType c, + final DeviceProcessor proc, + String lengthUnit, + double cutoff, + double cutoffmin, + boolean outputRC, + final Map stackMap, + final HierName GND, + final HierName Vdd, + final float top, + final float minWidth, + final Writer w) { + final CDLEmitter emitter = getCDLEmitter(w, lengthUnit); + writeCDL(c, proc, cutoff, cutoffmin, outputRC, stackMap, GND, Vdd, top, + minWidth, emitter, emitter); + } + + public static void writeCDL(final CellType c, + final DeviceProcessor proc, + double cutoff, + double cutoffmin, + boolean outputRC, + final Map stackMap, + final HierName GND, + final HierName Vdd, + final float top, + final float minWidth, + final NetlistFormatter emitter, + final Visitor visitor) { + final AbstractNetlist netlist = new FoldTransistor(new NetlistAdapter(c, outputRC, stackMap, GND, Vdd, top, minWidth), cutoff, cutoffmin); + proc.setNetlist(netlist); + emitter.format(proc, visitor, false); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CGTransistorSizingTool.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CGTransistorSizingTool.java new file mode 100644 index 0000000000..69c9589534 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CGTransistorSizingTool.java @@ -0,0 +1,231 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.*; +import java.util.*; + +import com.avlsi.fast.CastDesign; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.HalfOperator; + +import com.avlsi.tools.jauto.NetSource; +import com.avlsi.tools.jauto.NetSink; +import com.avlsi.tools.jauto.FunctionTerm; + +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.text.NumberFormatter; + + +/** specialized TransistorSizingTool using Conjugate Gradient Solver **/ +public class CGTransistorSizingTool extends TransistorSizingTool { + + private long minEndTime; + private long maxEndTime; + + /** constructor **/ + public CGTransistorSizingTool( final long minEndTime, + final long maxEndTime, + final boolean useEqualityConstraints) { + super(useEqualityConstraints); + this.minEndTime = minEndTime; + this.maxEndTime = maxEndTime; + } + + void groupVariables() { + listGroupedVariableNames.clear(); + for (Iterator ita = listAllGroupedSubtypes.iterator(); ita.hasNext(); ) { + List/**/ lsta = (List)ita.next(); + + List/**/ lstb = new ArrayList/**/(); + + Set/**/ setc = + new LinkedHashSet/**/(); + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + CellType cella = (CellType)itb.next(); + if(cella.getListHalfOperators().size() > 0){ + setc.addAll(cella.getListHalfOperators()); + } + else{ + setc.addAll(cella.setSizingHalfOperators); + } + } + + for (Iterator itb = setc.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + + if(!hoa.isVariableFixed()){ + lstb.add(hoa.getVariableName()); + } + } + + listGroupedVariableNames.add(lstb); + } + } + + void generateObjectiveFunction(Set/**/ setc) { + for (Iterator ita = setc.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + // create new FunctionTerm list for this cell + List/**/ functiona = + new ArrayList/**/(); + FunctionTerm terma = new FunctionTerm(); + terma.type = FunctionTerm.Type.OBJECTIVE; // first term indicates OBJECTIVE + functiona.add(terma); + + int instCount = cella.getPhysicalInstanceCount(); + + assert cella.getLevel() == 0 + : "Invalid cell type, must be leaf cell."; + + List/**/ lsta = cella.getListHalfOperators(); // get list of half-operators + + Set/**/ setd = + new LinkedHashSet/**/(); + // iterator of list of half-operators + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); // get next half-opeartor + String sta = hoa.getVariableName(); // get the variable name of the half-operator + boolean isFixed = hoa.isVariableFixed(); // to see if the variable is fixed + + if (!isFixed) { + // a "real" variable and will be updated + + ArrayList/**/ lstc = + (ArrayList) mapVarNameToHO.get(sta); + if (lstc != null) { + lstc.add(hoa); + } + else{ + lstc = new ArrayList/**/(); + lstc.add(hoa); + mapVarNameToHO.put(sta, lstc); + + // FIXME: remove hardcoded constant + Double da = new Double(0.48E-6); + mapVarNameToSize.put(sta, da); + listVariableNames.add(sta); + } + + } + + double ho_size = hoa.getCurrentSize(); // get the current "effective size" of the half-operator + Set/**/ seta = hoa.transistors; // get list of transistors + double f = 0.0; + // iterator of list of transistors + for (Iterator itc = seta.iterator(); itc.hasNext(); ) { + NetGraph.NetEdge trana = (NetGraph.NetEdge)itc.next(); // get next transistor + if(!setd.contains(trana)){ + setd.add(trana); + f += trana.size; + } + /* NOTE!!! + The size of the transistor is defined as a normalized real number + with respect to the size of the half-operator + */ + } + + // add the new term to objective function + functiona.add(newObjectiveTerm(sta,f,instCount,isFixed,hoa)); + } + + // add a zero constant term at the end to make the function simplifier happy + final FunctionTerm constantTerm = new FunctionTerm(); + constantTerm.type = FunctionTerm.Type.CONSTANT; + constantTerm.coefficient = 0.0; + functiona.add(constantTerm); + + listFunctions.add(functiona); + // Done with objective function generation + } + } + + String runSolver(int iterationNumber, int groupNumber) { + if(DebugOption.printLevel <= 0){ + System.out.println("Current step: executing solve"); + } + // execute built in CG solver + JautoSolver solver = new JautoSolver(); + solver.solve(listFunctions, + listVariableNames, + listVariableLowerBounds, + listVariableUpperBounds, + listVariableStartValues, + mapVarNameToSize, + minEndTime,maxEndTime); + resetWidth(); + + // Update sizes + int l = listVariableNames.size(); + for(int i=0;i*/ lstc = + (ArrayList)mapVarNameToHO.get(sta); + for (Iterator ita = lstc.iterator(); ita.hasNext(); ) { + HalfOperator hoa = (HalfOperator)ita.next(); + hoa.updateSize(hoa.getSizeForConductance(f)); + } + } + // Done with update sizes + + return "Done"; + } + + /** + * Main sizing flow + **/ + public String sizeTransistors() + { + String summary = ""; + + double targetTau = getOptionUnitDelay(); + + initializeSize(false); + + assignVariableNames(); + + reduceSubtypes(); + + partitionSubtypes(); + + int sweepIndex; + if(getOptionInternalSweep()){ + sweepIndex = getOptionInternalSweepNumber(); + } + else{ + sweepIndex = 1; + } + + double sweepStep = getOptionInternalSweepStep(); + + while(sweepIndex > 0){ + double sweepTau = targetTau + sweepStep * (sweepIndex - 1); + setOptionUnitDelay(sweepTau); + + String result = runOptimization(listAllSizingSubtypes, 0, 0); + + if (getOptionSizeStaticizer()) { + SizeStaticizers.sizeStaticizers(this); + } + + summary += JautoUI.reportSizingResults(this); + + sweepIndex -= 1; + } + + return summary; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Cast2Cdl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Cast2Cdl.java new file mode 100644 index 0000000000..908121cbc0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Cast2Cdl.java @@ -0,0 +1,709 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.IOException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.StringReader; +import java.io.Writer; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeSet; +import java.util.SortedSet; +import java.util.Comparator; +import java.util.List; +import java.util.ArrayList; +import java.util.Set; +import java.util.Stack; +import java.util.StringTokenizer; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.InstanceTrace; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.file.common.HierName; +import com.avlsi.file.cdl.parser.CDLFactoryAdaptor; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.cdl.parser.CDLFactoryFilter; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLInlineFactory; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.Inline; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.parser.LVSNodesCDLFactory; +import com.avlsi.file.cdl.parser.LVSNodesNullHandler; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameFactory; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; +import com.avlsi.file.cdl.util.rename.TrivialCDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.ReloadableNameInterface; +import com.avlsi.io.FileSearchPath; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.StringUtil; + +import com.avlsi.layout.LVSNodes; +import com.avlsi.layout.LVSNodesForExtract; +import com.avlsi.layout.LVSNodesForHierarchy; + +public final class Cast2Cdl { + /** + * This class should not be instantiated. + **/ + private Cast2Cdl() { } + + /** + * Translates process independent transistor type into real transistor + * model names. + **/ + public static class RealTransistorNames extends CDLFactoryFilter { + /** + * Name of the subcircuit currently being processed. null + * if not inside a subcircuit. Does not handle nested subcircuits. + **/ + private String currentSubcircuit = null; + + /** + * A function that transforms the transistor model. The + * execute method of the BinaryFunction is + * called with the name of the subcircuit where the transistor lives, + * and the transistor model name. + **/ + private final BinaryFunction /**/ transformer; + + /** + * Translates model name by looking at the + * transistor_names directive in a cell. If the + * transistor does not live in a subcircuit definition, or if a + * CellInterface cannot be obtained for the subcircuit + * where it does live, then the original model name is used. + **/ + public RealTransistorNames(final CDLFactoryInterface inner, + final CastFileParser cfp) { + this(inner, new BinaryFunction() { + public Object execute(final Object a, final Object b) { + final String subName = (String) a; + if (subName == null) return b; + + final CellInterface ci; + try { + ci = loadCell(cfp, subName); + } catch (Exception e) { + return b; + } + + final String model = (String) b; + return CellUtils.getTransistorModelName(ci, model); + } + }); + } + public RealTransistorNames(final CDLFactoryInterface inner, + final BinaryFunction transformer) { + super(inner); + this.transformer = transformer; + } + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + final String realtype = + (String) transformer.execute(currentSubcircuit, type); + inner.makeTransistor(name, realtype, ns, nd, ng, nb, w, l, + parameters, env); + } + public void beginSubcircuit(String subName, String[] in, String[] out, + Map parameters, Environment env) { + currentSubcircuit = subName; + inner.beginSubcircuit(subName, in, out, parameters, env); + } + public void endSubcircuit(String subName, Environment env) { + currentSubcircuit = null; + inner.endSubcircuit(subName, env); + } + } + + /** + * Filter transistor parameters based on a user given predicate. + **/ + public static class MosParameterFilter extends CDLFactoryFilter { + private final UnaryPredicate want; + public MosParameterFilter(final CDLFactoryInterface inner, + final UnaryPredicate want) { + super(inner); + this.want = want; + } + public MosParameterFilter(final CDLFactoryInterface inner, + final String[] keys) { + this(inner, + new UnaryPredicate() { + final SortedSet wantSet = (SortedSet) + CollectionUtils.addAll( + new TreeSet( + new Comparator() { + public int compare(String s1, String s2) { + return s1.compareToIgnoreCase(s2); + } + }), + keys); + public boolean evaluate(String key) { + return wantSet.contains(key); + } + }); + } + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, CDLLexer.InfoToken l, + Map parameters, Environment env) { + final LinkedHashMap filtered = new LinkedHashMap(); + for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String key = (String) entry.getKey(); + if (want.evaluate(key)) { + filtered.put(key, entry.getValue()); + } + } + inner.makeTransistor(name, type, ns, nd, ng, nb, w, l, filtered, + env); + } + } + + /** + * A factory that accumulates the names of cells being instantiated. + **/ + private static class GateCalls extends CDLFactoryAdaptor { + private final List s; + public GateCalls(List s) { + this.s = s; + } + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + s.add(subName); + } + } + + /** + * Returns the names of gates used in the netlist block of a cell. + **/ + public static List getGateInstantiations(final CellInterface cell) { + final List result = new ArrayList(); + if (cell.containsNetlist()) { + final NetlistBlock block = (NetlistBlock) cell.getBlockInterface().iterator(BlockInterface.NETLIST).next(); + block.getCDLTemplate().execute(new GateCalls(result)); + } + return result; + } + + /** + * Get a CellInterface given a CAST path, the cell name, and CAST version. + **/ + private static CellInterface loadCell(final CastFileParser castParser, + final String cellName) + throws CastSyntaxException, CastSemanticException, IOException { + return castParser.getFullyQualifiedCell(cellName); + } + + private static void usage( String m ) { + + System.err.println( "Usage: cast2cdl\n" ); + System.err.println(" --cast-path= (defaults to .)"); + System.err.println(" --cast-version= (defaults to 2)"); + System.err.println(" --cell= (name of cell to process, can be FQCN+-)"); + System.err.println(" --output= (defaults to .cdl)"); + System.err.println(" --translate=[ cadence | gds2 | none ] (defaults to cadence)"); + System.err.println(" [ --cadence-name ]"); + System.err.println(" [ --inline-layout (respect the inline_layout directive) ]"); + System.err.println(" [ --flatten (flatten the netlist) ]"); + System.err.println(" [ --lvs-nodes=[none,hierarchy,extract] (how to deal with lvs_nodes directive) ]"); + System.err.println(" [ --process-dependent-name (emit process dependent transistor types) ]"); + System.err.println(" [ --name-map= (read name mapping from file) ]"); + System.err.println(" [ --cdl-mos-parameters= (parameters to emitted for M) ]"); + if (m != null && m.length() > 0) + System.err.print( m ); + System.exit(1); + } + + private static void usage() { + usage ( null ); + } + + /** + * Emit a subcircuit call. + **/ + private static void emitCall(final HierName instance, + final CellInterface subcircuit, + final Cadencize cadencizer, + final CadenceInfo cadenceInfo, + final CDLFactoryInterface factory) { + final Set ports = NetlistAdapter.getParameterList(subcircuit, cadencizer); + final HierName[] args = new HierName[ports.size()]; + int j = 0; + for (Iterator i = ports.iterator(); i.hasNext(); ++j) { + final HierName port = (HierName) i.next(); + final HierName net = (HierName) cadenceInfo.getLocalNodes().getCanonicalKey(HierName.append(instance, port)); + args[j] = net; + } + + factory.makeCall(instance, subcircuit.getFullyQualifiedType(), args, Collections.EMPTY_MAP, new LocalEnvironment() ); + } + + private static Set inlineLayoutSet(final CellInterface cell) { + final Map m = + DirectiveUtils.getSubcellDirective(cell, + DirectiveConstants.INLINE_LAYOUT, + DirectiveConstants.INSTANCE_TYPE); + return DirectiveUtils.getExplicitTrues(m); + } + + /** + * Emit a mid-level cell. + * @param inline_layout Respect the inline_layout directive? + **/ + private static void writeMidlevel(final CellInterface cell, + final Cadencize cadencizer, + final CDLFactoryInterface factory, + final boolean inline_layout, + final boolean handleVerilog, + final boolean ignoreUnimpl) { + final Set inlined = + inline_layout ? inlineLayoutSet(cell) : Collections.EMPTY_SET; + + CDLOutput.templateHeader(cell, Collections.EMPTY_MAP, factory, + cadencizer); + + final CadenceInfo cadenceInfo = cadencizer.convert(cell); + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final boolean verilogBlock = + subcell.containsVerilog() && handleVerilog; + if (!verilogBlock && + (CellUtils.isWiring(subcell) || + (ignoreUnimpl && !subcell.hasNetlistBody()))) + continue; + final HierName name = (HierName) p.getFirst(); + final CDLFactoryInterface callEmitter; + if (inlined.contains(name)) { + final Set ports = NetlistAdapter.getParameterList(subcell); + final String[] out = new String[ports.size()]; + int j = 0; + for (Iterator k = ports.iterator(); k.hasNext(); ++j) { + out[j] = ((HierName) k.next()).getCadenceString(); + } + final NetlistBlock nb = + (NetlistBlock) subcell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + if (nb.getCDLTemplate() == null) { + throw new RuntimeException("In cell " + cell.getFullyQualifiedType() + ", inline_layout directive specified on instance " + name + ", which is not a leaf cell."); + } + final CDLInlineFactory inliner = + new CDLInlineFactory(true, null, false); + inliner.addTarget(subcell.getFullyQualifiedType(), + Template.setInOut(nb.getCDLTemplate(), + new String[0], out)); + inliner.setProxy(factory); + callEmitter = inliner; + } else { + callEmitter = factory; + } + emitCall(name, subcell, cadencizer, cadenceInfo, callEmitter); + } + + factory.endSubcircuit(cell.getFullyQualifiedType(), null); + } + + /** + * Emit a leaf cell. + **/ + private static void writeLeaf(final CellInterface cell, + final Cadencize cadencizer, + final CDLFactoryInterface emitter, + final boolean sortNetlist) { + if(sortNetlist) { + final NetlistBlock block = + (NetlistBlock) cell.getBlockInterface().iterator(BlockInterface.NETLIST).next(); + block.getCDLTemplate().sortStatements(); + } + CDLOutput.writeCDL(cell, cadencizer, emitter); + } + + /** + * Output the CDL for the gates instantiated in a cell, if they haven't + * been outputted before. + **/ + private static void outputGates(final CellInterface cell, + final CastFileParser castParser, + final CDLFactoryInterface emitter, + final Cadencize cadencizer, + final Set seen, + final boolean sortNetlist) throws IOException { + final List gates = getGateInstantiations(cell); + final SortedSet sorted = new TreeSet(); + sorted.addAll(gates); + for (Iterator i = sorted.iterator(); i.hasNext(); ) { + final String gateName = (String) i.next(); + if (!seen.add(gateName)) continue; + try { + final CellInterface gate = loadCell(castParser, gateName); + writeLeaf(gate, cadencizer, emitter, sortNetlist); + } catch (Exception e) { + System.err.println("ERROR: Cannot load gate " + gateName + "!"); + e.printStackTrace(); + System.exit(2); + } + } + } + + public static void outputCDL(final CellInterface cell, + final CastFileParser castParser, + final CDLFactoryInterface emitter, + final Cadencize cadencizer, + final boolean inline_layout, + final boolean sortNetlist) throws IOException { + outputCDL(cell, castParser, emitter, cadencizer, inline_layout, + sortNetlist, false); + } + + public static void outputCDL(final CellInterface cell, + final CastFileParser castParser, + final CDLFactoryInterface emitter, + final Cadencize cadencizer, + final boolean inline_layout, + final boolean sortNetlist, + final boolean handleVerilog) + throws IOException { + outputCDL(cell, castParser, emitter, cadencizer, inline_layout, + sortNetlist, handleVerilog, true); + } + + public static void outputCDL(final CellInterface cell, + final CastFileParser castParser, + final CDLFactoryInterface emitter, + final Cadencize cadencizer, + final boolean inline_layout, + final boolean sortNetlist, + final boolean handleVerilog, + final boolean exitOnError) + throws IOException { + outputCDL(cell, castParser, emitter, cadencizer, inline_layout, + sortNetlist, handleVerilog, exitOnError, false); + } + + public static void outputCDL(final CellInterface cell, + final CastFileParser castParser, + final CDLFactoryInterface emitter, + final Cadencize cadencizer, + final boolean inline_layout, + final boolean sortNetlist, + final boolean handleVerilog, + final boolean exitOnError, + final boolean ignoreUnimpl) + throws IOException { + final InstanceTrace it = new InstanceTrace(); + it.enter(cell.getFullyQualifiedType(), "top level"); + outputCDL(cell, castParser, emitter, cadencizer, inline_layout, + new HashSet(), sortNetlist, handleVerilog, it, exitOnError, + ignoreUnimpl); + it.leave(); + } + + /** + * Output CDL such that subcircuits are defined before being used. + **/ + private static void outputCDL(final CellInterface cell, + final CastFileParser castParser, + final CDLFactoryInterface emitter, + final Cadencize cadencizer, + final boolean inline_layout, + final Set seen, + final boolean sortNetlist, + final boolean handleVerilog, + final InstanceTrace it, + final boolean exitOnError, + final boolean ignoreUnimpl) + throws IOException { + final boolean verilogBlock = + cell.containsVerilog() && handleVerilog && !cell.containsNetlist(); + + if ((CellUtils.isWiring(cell) && !verilogBlock) || + (ignoreUnimpl && !seen.isEmpty() && !cell.hasNetlistBody() && + !verilogBlock) || + !seen.add(cell.getFullyQualifiedType())) return; + + outputGates(cell, castParser, emitter, cadencizer, seen, sortNetlist); + + boolean leaf = true; + final Set inlined = + inline_layout ? inlineLayoutSet(cell) : Collections.EMPTY_SET; + + SortedSet sorted = new TreeSet(); + + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + sorted.add(i.next()); + } + + for (Iterator i = sorted.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (!inlined.contains(p.getFirst())) { + it.enter(p); + outputCDL(subcell, castParser, emitter, cadencizer, + inline_layout, seen, sortNetlist, handleVerilog, it, + exitOnError, ignoreUnimpl); + it.leave(); + } else { + outputGates(subcell, castParser, emitter, cadencizer, seen, + sortNetlist); + } + leaf = false; + } + + if (leaf && !verilogBlock) { + if (!cell.containsNetlist() && !ignoreUnimpl) { + if (exitOnError) { + System.err.println("ERROR: No netlist block found "); + System.err.print(it); + System.exit(1); + } else { + System.err.println("Warning: No netlist block found "); + System.err.print(it); + return; + } + } + writeLeaf(cell, cadencizer, emitter, sortNetlist); + } else { + writeMidlevel(cell, cadencizer, emitter, inline_layout, + handleVerilog, ignoreUnimpl); + } + } + + private static Set colonToSet(final String s) { + return new HashSet(Arrays.asList(StringUtil.split(s, ':'))); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellNameArg = theArgs.getArgValue("cell", null); + + if (cellNameArg == null) { + usage("ERROR: You must specify a cell name.\n"); + } + + final String fqcnm; + if( theArgs.argExists( "cadence-name" ) ) { + final CadenceReverseNameInterface crni = + new CadenceReverseNameInterface(); + fqcnm = crni.renameCell(cellNameArg); + } + else { + fqcnm = cellNameArg; + } + + final CastFileParser castParser = + new CastFileParser(new FileSearchPath(castRoot), castVersion); + + final Cadencize cadencizer = + new Cadencize(false, Cadencize.NETLIST_PRIORITY); + + final PartialExtract.CellPlusMinus fqcnSpec = + new PartialExtract.CellPlusMinusKeyword(fqcnm, + PartialExtract.Info.INCLUDE, + castParser, cadencizer); + final String cellName = fqcnSpec.getTop(); + + final String translate = theArgs.getArgValue("translate", "cadence"); + final boolean bFlatten = theArgs.argExists("flatten"); + final boolean inline_layout = theArgs.argExists("inline-layout"); + final boolean ignoreUnimpl = theArgs.argExists("ignore-unimplemented"); + + final CellInterface ci = loadCell(castParser, cellName); + + final String output = theArgs.getArgValue("output", ci.getFullyQualifiedType() + fqcnSpec.getRest() + ".cdl"); + + // list future legal args for pedantic to work. + pedanticArgs.argTag( "name-map" ); + pedanticArgs.argTag( "lvs-nodes" ); + pedanticArgs.argTag( "process-dependent-name" ); + + // put this before any file output is started + if (! pedanticArgs.pedanticOK( false, true ) ) { + usage ( pedanticArgs.pedanticString() ); + } + + final FileWriter writer = new FileWriter(output); + + // Filter out zero width transistors, 79 columns per line + final CDLFactoryInterface cdlEmitterFactory = + new CDLFactoryEmitter(writer, true, 79); + + // Determine the renaming method to use + final CDLNameInterface cdlNamer; + if (translate.equals("cadence")) { + cdlNamer = new CadenceNameInterface(); + } else if (translate.equals("gds2")) { + cdlNamer = new GDS2NameInterface(); + } else { + cdlNamer = new IdentityNameInterface(); + } + + // Reload any name mapping + final String argNameMap = theArgs.getArgValue("name-map", null); + final String pdkRoot = theArgs.getArgValue("fulcrum-pdk-root", null); + + String nameMap = null; + if (pdkRoot != null && argNameMap == null) { + nameMap = pdkRoot + "/share/Fulcrum/lve/transistor.map"; + } + else if (argNameMap != null) { + nameMap = argNameMap; + } + final CDLNameInterface mapNamer; + if (nameMap == null) { + mapNamer = cdlNamer; + } else { + mapNamer = new ReloadableNameInterface(cdlNamer); + try { + final FileReader r = new FileReader(nameMap); + ((ReloadableNameInterface) mapNamer).load(r); + r.close(); + } catch (IOException e) { + System.err.println("Cannot read from name map file " + + nameMap + ": " + e.getMessage()); + System.exit(2); + } catch (ReloadableNameInterface.FileFormatException e) { + System.err.println("Name map file " + nameMap + + " is invalid: " + e.getMessage()); + System.exit(2); + } + } + + final CDLFactoryInterface renamerFactory = + new CDLRenameFactory(cdlEmitterFactory, + new TrivialCDLNameInterfaceFactory(mapNamer)); + + final CDLFactoryInterface templateAccumulatorFactory; + final Map templates; + if ( ( fqcnSpec.isEmpty() ) && ( ! bFlatten ) ) { + templateAccumulatorFactory = renamerFactory; + templates = null; + } + else { + templates = new LinkedHashMap(); + templateAccumulatorFactory = new Template( templates ); + } + + final CDLFactoryInterface lvsNodesEmitter; + final String lvsNodesOption = theArgs.getArgValue("lvs-nodes","hierarchy"); + if(lvsNodesOption.equals("none")) { + lvsNodesEmitter = templateAccumulatorFactory; + } else { + final LVSNodes lvsNodesInfo; + if ( lvsNodesOption.equals("extract")) { + lvsNodesInfo = new LVSNodesForExtract( castParser, + cadencizer ); + } else if(lvsNodesOption.equals("hierarchy")) { + lvsNodesInfo = new LVSNodesForHierarchy( castParser, + cadencizer ); + } else { + lvsNodesInfo = null; + System.err.println("invalid lvs-nodes option: " + lvsNodesOption ); + System.exit(2); + } + lvsNodesEmitter = + new LVSNodesCDLFactory( lvsNodesInfo, + templateAccumulatorFactory, + new LVSNodesNullHandler() ); + } + + + final CDLFactoryInterface trueNamesEmitter = + theArgs.argExists("process-dependent-name") ? + new RealTransistorNames(lvsNodesEmitter, castParser) : + lvsNodesEmitter; + + final String mosParameters = + theArgs.getArgValue("cdl-mos-parameters", null); + final CDLFactoryInterface mosParameterFilter = + mosParameters == null ? trueNamesEmitter + : new MosParameterFilter( + trueNamesEmitter, + StringUtil.split(mosParameters, ',')); + + outputCDL(ci, castParser, mosParameterFilter, + cadencizer, inline_layout, false, + false, true, ignoreUnimpl); + + final CDLFactoryInterface flattenerFactory; + if ( bFlatten ) { + assert templates != null; + final CDLInlineFactory flattener = + new CDLInlineFactory( false, null, true ); + flattener.addTargets( templates ); + flattener.setProxy( renamerFactory ); + flattenerFactory = flattener; + } + else { + flattenerFactory = renamerFactory; + } + + if (!fqcnSpec.isEmpty()) { + final PartialExtract pe = + new PartialExtract(templates, cellName, fqcnSpec); + pe.execute( flattenerFactory ); + } + else if ( bFlatten ) { + final Template topLevel = ( Template ) templates.get( cellName ); + topLevel.execute( flattenerFactory, + Collections.EMPTY_MAP, + NullEnvironment.getInstance(), + cellName ); + } + writer.close(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.g b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.g new file mode 100644 index 0000000000..938a8b2542 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.g @@ -0,0 +1,176 @@ +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2001 Fulcrum Microsystems. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CastQuery.g instead + // + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.tools.jauto; +} + +{ + import java.util.ArrayList; + import java.util.List; + import java.util.Iterator; + import com.avlsi.util.functions.UnaryPredicate; + import com.avlsi.util.functions.BinaryFunction; +} + +class CastQueryParser extends Parser; +options { + k = 1; +} +{ + public interface QueryConstructor { + UnaryPredicate getClause(String test, String op, String arg); + } + + /** + * Returns true if all sub-predicates returns true. Evaluation is short + * circuited if a sub-predicate returns false. + **/ + private static class AndUnaryPredicates implements UnaryPredicate { + private List predicates; + public AndUnaryPredicates() { + this.predicates = new ArrayList(); + } + public void addPredicate(final UnaryPredicate p) { + predicates.add(p); + } + public boolean evaluate(final Object o) { + for (Iterator i = predicates.iterator(); i.hasNext(); ) { + final UnaryPredicate p = (UnaryPredicate) i.next(); + if (!p.evaluate(o)) return false; + } + return true; + } + } + + /** + * Returns true if any sub-predicates returns true. Evaluation is short + * circuited if a sub-predicate returns true. + **/ + private static class OrUnaryPredicates implements UnaryPredicate { + private List predicates; + public OrUnaryPredicates() { + this.predicates = new ArrayList(); + } + public void addPredicate(final UnaryPredicate p) { + predicates.add(p); + } + public boolean evaluate(final Object o) { + for (Iterator i = predicates.iterator(); i.hasNext(); ) { + final UnaryPredicate p = (UnaryPredicate) i.next(); + if (p.evaluate(o)) return true; + } + return false; + } + } + + /** + * Returns the logical opposite of the sub-predicate. + **/ + private static class NotUnaryPredicate implements UnaryPredicate { + private UnaryPredicate predicate; + public NotUnaryPredicate(final UnaryPredicate predicate) { + this.predicate = predicate; + } + public boolean evaluate(final Object o) { + return !predicate.evaluate(o); + } + } +} + +goal [ QueryConstructor qc ] returns [ UnaryPredicate p ] + { + p = null; + } + : p = orExpr[qc] EOF + ; + +orExpr [ QueryConstructor qc ] returns [ OrUnaryPredicates or ] + { + UnaryPredicate p; + or = new OrUnaryPredicates(); + } + : p = andExpr[qc] { + or.addPredicate(p); + } + ( OR p = andExpr[qc] { + or.addPredicate(p); + })* + ; + +andExpr [ QueryConstructor qc ] returns [ AndUnaryPredicates and ] + { + UnaryPredicate p; + and = new AndUnaryPredicates(); + } + : p = unaryExpr[qc] { + and.addPredicate(p); + } ( AND p = unaryExpr[qc] { + and.addPredicate(p); + })* + ; + +unaryExpr [ QueryConstructor qc ] returns [ UnaryPredicate unary ] + { + UnaryPredicate p; + unary = null; + } + : NOT p = unaryExpr[qc] { + unary = new NotUnaryPredicate(p); + } + | unary = primaryExpr[qc] + ; + +primaryExpr [ QueryConstructor qc ] returns [ UnaryPredicate primary ] + { + primary = null; + String op = null; + String val = null; + } + : LPAREN primary = orExpr[qc] RPAREN + | test:TEXT ( oper:OPER arg:TEXT { + op = oper.getText(); + val = arg.getText(); + } )? { + primary = qc.getClause(test.getText(), op, val); + } + ; + +class CastQueryLexer extends Lexer; +options { + k = 2; +} + +AND : "&"; +OR : "|"; +LPAREN : "("; +RPAREN : ")"; +NOT : "!"; +protected +LETTER : 'a'..'z' | 'A'..'Z' + ; +protected +DIGIT : '0'..'9' + ; +protected +CHAR : LETTER | DIGIT | '_' | '+' | '-' | '*' | '/' | '.' | '{' | '}' | ',' | ':' ; +TEXT : CHAR (CHAR | '(' | ')')+; +WS : ( ' ' + | '\t' + | '\r' '\n' { newline(); } + | '\n' { newline(); } + ) + { $setType(Token.SKIP); } + ; +OPER : "<" | "<=" | "==" | ">=" | ">" | "=" + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.java new file mode 100644 index 0000000000..6d1a397194 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastQuery.java @@ -0,0 +1,4092 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.util.container.SortingIterator; + + +import com.avlsi.util.functions.UnaryAction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.mathexpression.variable.VariableDictionary; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.file.cdl.parser.CDLSimpleImpl; +import com.avlsi.file.cdl.parser.CDLInterfaceSimplifier; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLstat; + +import com.avlsi.cast.CastCacheManager; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast2.util.DirectiveActionInterface; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.DirectiveWalker; +import com.avlsi.cast2.util.NetProperty; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cast2.directive.impl.CastEmitter; +import com.avlsi.cast2.directive.impl.DirectiveEmitter; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cell.CellDelay; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.ChildrenFirstCellInterfaceIterator; +import com.avlsi.cell.NoSuchEnvironmentException; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.EnvBlock; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.file.cdl.parser.CDLFactoryAdaptor; +import com.avlsi.file.cdl.parser.CDLInlineFactory; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.io.FileSearchPath; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.tools.prs2verilog.verilog.VerilogUtil; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.OrBooleanExpressionInterface; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.FlatteningIterator; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.container.ObjectUtils; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.functions.BinaryPredicate; +import com.avlsi.util.functions.NumericPredicate; + + +import com.avlsi.util.mathexpression.MathExpression; +import com.avlsi.util.mathexpression.MathExpressionFactory; +import com.avlsi.util.mathexpression.NotAConstantValueException; +import com.avlsi.util.mathexpression.impl.MathExpressionFactoryImpl; +import com.avlsi.util.mathexpression.impl.parser.MathExpressionLexer; +import com.avlsi.util.mathexpression.impl.parser.MathExpressionParser; +import com.avlsi.util.mathexpression.variable.Variable; + +import com.avlsi.util.mathexpression.variable.VariableDictionaryIterator; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.util.text.StringUtil; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; + + +/** + * A class that generate various flat or hierarchical statistics about cells in + * an easily parsable format. It combines the functionalities of CountPrs, + * CDLstat, SubtypeQuery and others. + **/ +public final class CastQuery { + /** + * This class should not be instantiated. + **/ + private CastQuery() { } + + public static class RuntimeException extends java.lang.RuntimeException { + public RuntimeException(final String msg, final Throwable cause) { + super(msg, cause); + } + public RuntimeException(final String msg) { + super(msg); + } + public RuntimeException() { + super(); + } + } + + private static void usage( String m ) { + System.err.print( + "java com.avlsi.tools.jauto.CastQuery\n" + + " --cast-path= (defaults to .)\n" + + " --cast-version=[ 1 | 2 ] (defaults to 2)\n" + + " --config= (file containing options)\n" + + " --cell= (fully qualified cell name)\n" + + " --task= tasks are:\n" + + " subcells (generate a list of cells)\n" + + " subcell_tree (generate a tree display)\n" + + " tau (print value of the tau directive)\n" + + " density (print value of the density directive)\n" + + " directive=dir (print value of the specified cell level directive)\n" + + " paramdirective=dir (value of the specified cell level parameterized directive)\n" + + " instances (print instance count)\n" + + " instance_list[ =verilog:skip-wiring ]\n" + + " (print pairs of cell name and full instance names, optionally\n" + + " using Verilog syntax, or skipping wiring instances)\n" + + " prs[ =dnf ] (print production rule count, optionally convert rules\n" + + " to DNF form to count number of disjuncts, like DSim)\n" + + " transistors[ = ] (print transistor stats, w/o gates in list)\n" + + " dynamic_nodes[ =alias ] (print dynamic nodes, with aliases)\n" + + " count_dynamic_nodes (count the number dynamic nodes)\n" + + " external_nodes[ =[write]im[plied]:[write]di[rection]:al[iases]:\n" + + " xr[ef]:all[_aliases]:re[alonly] ]\n" + + " (implied=>include implied nodes)\n" + + " (direction=>include node direction)\n" + + " (aliases=>print aliases at the current level)\n" + + " (all_aliases=>print all aliases)\n" + + " (xref=>cross ref of Canonical names vs cast name)\n" + + " local_nodes[ =all_aliases:alias:used:drivers:em ]\n" + + " (print local nodes and directives, optionally all aliases,\n" + + " or aliases visible at this level, only nodes used, drivers,\n" + + " or EM related specs)\n" + + " em_spec (print electromigration related directives)\n" + + " routing (print number of subcells, local nets, and connections)\n" + + " env[ =prs:rte_ignore:ntpc_spec:aspice_ignore ]\n" + + " (print all environments, optionally must have prs impl,\n"+ + " rte_ignore=false, have an ntpc_spec, or aspice_ignore=false)\n" + + " refinement_lineage (print out refinement ancestors)\n" + + " railstat (print out number of channels and rails)\n" + + " attribute_list (print out inheritance ancestors)\n" + + " canonical_name[=file[:skill]] (translate node names from stdin [or file]\n" + + " to canonical names, skill format if specified)\n" + + " initial_floorplan[ =]\n" + + " (write out a file suitable as input to create an initial\n" + + " floorplan, excluding instances whose type match the\n" + + " specified regular expression)\n" + + " enumerate_scan_chains[=dft | sram]\n" + + " (write out scan chains in a cell)\n" + + " trace_connection=|||[:...]\n" + + " (trace chains of specified cells; left and right are ports;\n" + + " generic is either true or false, chains of all generic cells\n" + + " are not reported)\n" + + " level (write out the maximum depth to a leaf cell)\n" + + " ports [ =primitive ]\n" + + " (write out the port list in CAST order, optionally flatten\n" + + " defchans to nodes and e1ofN channels)\n" + + " [ --filter= ] expression is composed of\n" + + " < | <= | == | >= | > \n" + + " variables available: prs (production rule count of a cell)\n" + + " leaf (true if a cell is a leaf cell)\n" + + " fixed (true if a cell, leaf or mid-level, is fixed size)\n" + + " netlist (true if a cell has a netlist block)\n" + + " routed (true if a cell is routed)\n" + + " tau= (true if a cell has specified tau)\n" + + " shared= (true if cells are shared with root)\n" + + " one-level (true if cell is a local subcell of the top cell)\n" + + " env[ =prs:rte_ignore:ntpc_spec ]\n" + + " (true if a cell has any environment that is prs implementable, has\n" + + " rte_ignore=false, has an ntpc_spec, or has aspice_ignore=false)\n" + + " directive=[block:][:] (true if the directive is defined\n" + + " in a comma separated list of specified blocks (cell, subcell,\n" + + " prs, env), or if not specified, any block of the cell, optionally\n" + + " require it to be set to value)\n" + + " graybox-list=\n" + + " (true, if a cell is listed in file or if a leaf cell is\n" + + " instantiated by a cell not listed in file; file contains a list\n" + + " of cells, one per line; the cell can be a refinement or\n" + + " inheritance parent, and metaparameters may be omitted)\n" + + " ancestor=\n" + + " (true, if a cell or any of its refinement or inheritance\n" + + " ancestors refines or inherits the specified cell; metaparameters\n" + + " may be omitted to match any parameterization)\n" + + " block=< prs | subcells | csp | java | verilog | netlist >\n" + + " (true if a cell directly contains the block; in addition, prs and\n" + + " subcells require the block be completed (not fragments), and csp\n" + + " requires runnable CSP, not just structure and function definitions)\n" + + " & (and) | (or) ! (not) () (parenthesis)\n" + + " [ --prune= ] expression same as --filter\n" + + " [ --cadence-name ] (cell name is a Cadence name)\n" + + " [ --no-recurse ]\n" + + " [ --translate=(cadence | gdsII) ] (for hierarchical tasks)\n" + + " [ --no-header ] (do not print header for flat tasks)\n" + + " [ --instantiation-order ] (run hierarchical tasks in instantiation order)\n" + + " [ --output= ] (write result to file instead of standard out)\n" + + " [ --routed ] (interpret the routed directives)\n" + + " [ --separator= ] (delimiter string between hierarchical tasks)\n" + + "(see http://internal/tree/sw/cad/doc/specs/misc/CastQuery.txt)\n"); + if (m != null && m.length() > 0) + System.err.print ( m ); + System.exit(1); + } + + private static void usage( ) { + usage ( null ); + } + + private static void instanceSet(final CellInterface ci, final Set seen, + final Set skip) { + final ChildrenFirstCellInterfaceIterator iter = + new ChildrenFirstCellInterfaceIterator( ci ); + while ( iter.hasNext() ) { + final CellInterface currCell = (CellInterface) iter.next(); + final String subType = currCell.getFullyQualifiedType(); + if ( ( ! skip.contains( subType ) ) && + ( ! seen.contains( subType ) ) && + ( ! CellUtils.isWiring( currCell ) ) ) { + seen.add( subType ); + } + } + } + + /** + * Generates a set of cell types instantiated by a cell, skipping the given + * set cells. + * @param ci CellInterface to generate data from. + * @param skip Set of fully qualified cell names to skip. + * @return Set of fully qualified cell names instantiated by a cell. + **/ + private static Set instanceSet(final CellInterface ci, final Set skip) { + final Set seen = new TreeSet(); + instanceSet(ci, seen, skip); + seen.add(ci.getFullyQualifiedType()); + return seen; + } + + + /** + * Convert double to string. Use reasonable format. + **/ + public static String printDouble(final double val) { + return NumberFormatter.format(val, 4); + } + + /** + * An interface to invoke a task. + **/ + public interface TaskInterface { + /** + * Do the task on the given cell, and write the result to the given + * writer. + * @param cell CellInterface of the cell. + * @param w Where to write the result to. + **/ + void doTask(final CellInterface cell, final Writer w) + throws IOException; + /** + * Is this a flat task? + * @return true if the task is flat, false otherwise. + **/ + boolean isFlat(); + } + + public abstract static class FlatTask implements TaskInterface { + public boolean printHeader = true; + public abstract void doTask(final CellInterface cell, final Writer w) + throws IOException; + public abstract void doTask(final CellInterface cell, final Writer w, + boolean noRecurse) throws IOException; + protected void header(final String s, final Writer w) + throws IOException { + if (printHeader) w.write(s); + } + public boolean isFlat() { + return true; + } + } + + public abstract static class HierTask implements TaskInterface { + public abstract void doTask(final CellInterface cell, final Writer w) + throws IOException; + public boolean isFlat() { + return false; + } + } + + private static class BaseAlias implements Iterable { + private Collection names = new TreeSet(); + private MultiSet subcells = null; + + public void add(final HierName name) { + names.add(name); + } + + public void add(final HierName inst, final BaseAlias aliases) { + if (subcells == null) { + subcells = new MultiSet( + new Comparator>() { + public int compare(Pair p1, + Pair p2) { + return p1.getFirst().compareTo(p2.getFirst()); + } + }); + } + subcells.add(new Pair(inst, aliases)); + } + + public Iterator iterator() { + final Collection> its = + new ArrayList>(); + its.add(names.iterator()); + if (subcells != null) { + for (Iterator i = subcells.iterator(); i.hasNext(); ) { + final Pair p = + (Pair) i.next(); + final HierName prefix = p.getFirst(); + its.add(new MappingIterator( + p.getSecond().iterator(), + new UnaryFunction() { + public HierName execute(final HierName h) { + return HierName.append(prefix, h); + } + }) + ); + } + } + return new FlatteningIterator(its.iterator()); + } + } + + private static class GetAliases { + private final Cadencize cad; + private final Map> cache; + + public GetAliases(final Cadencize cad) { + this.cad = cad; + this.cache = new HashMap>(); + } + + private BaseAlias helper(final CellInterface cell, + final HierName node) { + final String fqcn = cell.getFullyQualifiedType(); + Map typecache = cache.get(fqcn); + if (typecache == null) { + typecache = new HashMap(); + cache.put(fqcn, typecache); + } + + BaseAlias ba = typecache.get(node); + if (ba == null) { + ba = new BaseAlias(); + final AliasedSet nodes = cad.convert(cell).getLocalNodes(); + final Set seen = new HashSet(); + for (Iterator i = nodes.getAliases(node); i.hasNext(); ) { + final HierName alias = (HierName) i.next(); + boolean foundInstance = false; + for (Iterator j = cell.getSubcellPairs(); j.hasNext(); ) { + final Pair p = (Pair) j.next(); + final CellInterface subcell = + (CellInterface) p.getSecond(); + if (subcell.isNode() || subcell.isChannel()) continue; + final HierName instance = (HierName) p.getFirst(); + if (alias.isChildOf2(instance)) { + final int n = instance.getNumComponents(); + final HierName port = alias.tail(n); + final AliasedSet subnodes = + cad.convert(subcell).getLocalNodes(); + if (seen.add( + new Pair(instance, + subnodes.getCanonicalKey(port)))) { + ba.add(instance, helper(subcell, port)); + } + foundInstance = true; + break; + } + } + if (!foundInstance) ba.add(alias); + } + typecache.put(node, ba); + } + + return ba; + } + + /** + * Return all aliases that exist in all levels of the hierarchy. The + * aliases returned are not necessarily in any specific order. + **/ + public Iterator getAliases(final CellInterface cell, + final HierName node) { + return helper(cell, node).iterator(); + } + } + + /** + * Print out the external nodes of the cell. + **/ + public static class ExternalNodes extends FlatTask { + + private final boolean writeImplied; + private final boolean writeDirection; + private final boolean writeAliases; + private final boolean writeAllAliases; + private final boolean writeXref; + private final boolean writeRealOnly; + + public ExternalNodes(final boolean writeImplied, + final boolean writeDirection, + final boolean writeAliases, + final boolean writeAllAliases, + final boolean writeXref, + final boolean writeRealOnly) { + this.writeImplied = writeImplied; + this.writeDirection = writeDirection; + this.writeAliases = writeAliases; + this.writeAllAliases = writeAllAliases; + this.writeXref = writeXref; + this.writeRealOnly = writeRealOnly; + } + + public ExternalNodes(final boolean writeImplied, + final boolean writeDirection, + final boolean writeAliases, + final boolean writeAllAliases, + final boolean writeXref) { + this.writeImplied = writeImplied; + this.writeDirection = writeDirection; + this.writeAliases = writeAliases; + this.writeAllAliases = writeAllAliases; + this.writeXref = writeXref; + this.writeRealOnly = false; + } + + public ExternalNodes(final boolean writeImplied, + final boolean writeDirection, + final boolean writeAliases) { + this.writeImplied = writeImplied; + this.writeDirection = writeDirection; + this.writeAliases = writeAliases; + this.writeAllAliases = false; + this.writeXref = false; + this.writeRealOnly = false; + } + + public ExternalNodes(final boolean writeImplied, + final boolean writeDirection) { + this.writeImplied = writeImplied; + this.writeDirection = writeDirection; + this.writeAliases = false; + this.writeAllAliases = false; + this.writeXref = false; + this.writeRealOnly = false; + } + + /** Non-recursive by definition **/ + public void doTask(final CellInterface cell, final Writer w, + boolean noRecurse) + throws IOException { doTask(cell, w); } + + /** + * Just write out the port nodes of the cell + **/ + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + + final Map mp = CellUtils.markPorts(cell); + + final Cadencize cad = new Cadencize (true); + final CadenceInfo cinfo = cad.convert(cell); + final AliasedMap ports = cinfo.getPortNodes(); + final AliasedSet nodes = cinfo.getLocalNodes(); + final Set seen = new HashSet(); + final GetAliases getAliases = new GetAliases(cad); + + header("External nodes of " + cell.getFullyQualifiedType() + ":\n", + w); + for (Iterator i = new SortingIterator(mp.keySet().iterator()); + i.hasNext(); ) { + final String s = (String) i.next(); + final HierName hs; + try { + hs = HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName: " + s, + e); + } + final HierName canon = (HierName) ports.getCanonicalKey(hs); + if (!writeXref && !seen.add(canon)) continue; + if (!((Boolean) ports.getValue(hs)).booleanValue() && writeRealOnly) continue; + if (writeImplied || !cell.isImpliedPort(s) ) { + if (writeDirection) { + switch(Integer.parseInt((mp.get(s)).toString())) { + case PortDefinition.IN: + w.write(PortDefinition.INSTRING); + break; + case PortDefinition.OUT: + w.write(PortDefinition.OUTSTRING); + break; + case PortDefinition.INOUT: + w.write(PortDefinition.INOUTSTRING); + break; + default: + w.write("?"); + break; + } + } + if (writeXref) { + w.write(s); + w.write(" "); + w.write(canon.getCadenceString()); + } + else { + w.write(canon.getCadenceString()); + if (writeAliases || writeAllAliases) { + for (Iterator j = (writeAllAliases ? + getAliases.getAliases(cell, canon) + : nodes.getAliases(canon)); + j.hasNext(); ) { + final HierName aliasName = (HierName) j.next(); + if (!aliasName.equals(canon)) { + w.write("=" + aliasName.getCadenceString()); + } + } + } + } + w.write("\n"); + } + } + } + } + /** + * Print out the local nodes in the cell, as well as wirewidth and + * wirespace directives associated with them. Optionally output the + * aliases. + **/ + public static class LocalNodes extends FlatTask { + private final CastFileParser cfp; + private final Cadencize cad; + + /** Output aliases? */ + private final boolean alias; + + /** Output all aliases? */ + private final boolean all_alias; + + /** Output only nodes that are used? */ + private final boolean used; + + /** Output drivers of a net? */ + private final boolean drivers; + + /** Output EM signoff directives */ + private final boolean EMReport; + + /** Default tau if no tau directive is specified in a leaf cell */ + private final float defaultTau; + + /** Cache containing delay information for ports of a cell */ + private final Map> cache; + + /** Output all nodes, include ports? */ + private final boolean includePorts; + + /** Set of possible nodes **/ + private final Set nodeSet; + + public LocalNodes(final CastFileParser cfp, final Cadencize cad, + final boolean alias, final boolean used, + final boolean includePorts, Set nodes) { + this(cfp, cad, alias, used, false, true, false, includePorts, + nodes); + } + + public LocalNodes(final CastFileParser cfp, final Cadencize cad, + final boolean alias, final boolean used, + final boolean drivers, final boolean EMReport, + final boolean all_alias, final boolean includePorts, + final Set nodeSet) { + this(cfp, cad, alias, used, drivers, EMReport, all_alias, + includePorts, new HashMap(), 100e-12F, nodeSet); + } + + public LocalNodes(final CastFileParser cfp, final Cadencize cad, + final boolean alias, final boolean used, + final boolean drivers, final boolean EMReport, + final boolean all_alias, final boolean includePorts, + final Map cache, final float defaultTau) { + this(cfp, cad, alias, used, drivers, EMReport, all_alias, + includePorts, cache, defaultTau, null); + } + + + public LocalNodes(final CastFileParser cfp, final Cadencize cad, + final boolean alias, final boolean used, + final boolean drivers, final boolean EMReport, + final boolean all_alias, final boolean includePorts, + final Map cache, final float defaultTau, + final Set nodeSet) { + this.cfp = cfp; + this.cad = cad; + this.alias = alias; + this.used = used; + this.drivers = drivers; + this.EMReport = EMReport; + this.all_alias = all_alias; + this.includePorts = includePorts; + this.cache = (Map>) cache; + this.defaultTau = defaultTau; + this.nodeSet = nodeSet; + } + + private class DriversCallback implements PartialExtract.LeafCallback { + public Object leaf(final CellInterface cell, final HierName inst, + final HierName canon) { + final Collection result = new HashSet(); + if (!cell.containsNetlist()) return null; + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + nb.getCDLTemplate().execute(Collections.EMPTY_MAP, new CDLSimpleImpl() { + public void makeCall(final HierName name, + final String subName, + final HierName[] args, + final Map parameters) { + final CellInterface gate; + try { + gate = cfp.getFullyQualifiedCell(subName); + } catch (CastSemanticException e) { + System.err.println("Cannot load cell: " + subName); + ExceptionPrettyPrinter.printException(e, + System.err); + return; + } + if (((Boolean) DirectiveUtils.getTopLevelDirective(gate, DirectiveConstants.STATICIZER_GATE)).booleanValue()) return; + final Collection ports = + NetlistAdapter.getParameterList(gate, cad); + if (ports.size() != args.length) { + System.err.print("Number of gate ports does not match with instantiation: X" + name + " / " + subName); + for (int i = 0; i < args.length; ++i) { + System.err.print(" " + args[i]); + } + System.err.println(" Expecting " + ports.size()); + return; + } + final Map marked = CellUtils.markPorts(gate); + int i = 0; + for (Iterator j = ports.iterator(); j.hasNext(); ++i) { + final String sport = + ((HierName) j.next()).getCadenceString(); + if (canon.equals(args[i])) { + final Integer dir = (Integer) marked.get(sport); + assert dir != null; + if (dir.intValue() == PortDefinition.OUT || + dir.intValue() == PortDefinition.INOUT) { + final boolean stack = ((Boolean) DirectiveUtils.getTopLevelDirective(gate, DirectiveConstants.STACK_GATE)).booleanValue(); + if (stack) result.add("stack"); + else result.add(subName); + } + break; + } + } + } + }); + return result.size() == 0 ? null : new Triplet(cell, canon, result); + } + public Object midlevel(final Object o, final CellInterface cell, + final HierName inst, final HierName canon) { + return o; + } + } + + private static float update(boolean top, float current, float other) { + if (Float.isNaN(current)) { + return other; + } else if (Float.isNaN(other)) { + return current; + } else { + return top ? other : Math.max(current, other); + } + } + + private static class Signoff { + public static final Signoff UNSPECIFIED = new Signoff(); + public final float alintSignoff; + public final float maxBumpFanin; + public final float upSlew, dnSlew; + public final float upSkew, dnSkew; + public final float upBump, dnBump; + public final float upDelay, dnDelay; + private Signoff() { + this(Float.NaN, Float.NaN, + Float.NaN, Float.NaN, + Float.NaN, Float.NaN, + Float.NaN, Float.NaN, + Float.NaN, Float.NaN); + } + private Signoff(float alintSignoff, float maxBumpFanin, + float upSlew, float dnSlew, + float upSkew, float dnSkew, + float upBump, float dnBump, + float upDelay, float dnDelay) { + this.alintSignoff = alintSignoff; + this.maxBumpFanin = maxBumpFanin; + this.upSlew = upSlew; + this.dnSlew = dnSlew; + this.upSkew = upSkew; + this.dnSkew = dnSkew; + this.upBump = upBump; + this.dnBump = dnBump; + this.upDelay = upDelay; + this.dnDelay = dnDelay; + } + public static Signoff getInstance(float alintSignoff, + float maxBumpFanin, + float upSlew, float dnSlew, + float upSkew, float dnSkew, + float upBump, float dnBump, + float upDelay, float dnDelay) { + if (Float.isNaN(alintSignoff) && Float.isNaN(maxBumpFanin) && + Float.isNaN(upSlew) && Float.isNaN(dnSlew) && + Float.isNaN(upSkew) && Float.isNaN(dnSkew) && + Float.isNaN(upBump) && Float.isNaN(dnBump) && + Float.isNaN(upDelay) && Float.isNaN(dnDelay)) { + return UNSPECIFIED; + } else { + return new Signoff(alintSignoff, maxBumpFanin, + upSlew, dnSlew, + upSkew, dnSkew, + upBump, dnBump, + upDelay, dnDelay); + } + } + + public Signoff update(Signoff other, boolean top) { + return getInstance( + LocalNodes.update(top, alintSignoff, other.alintSignoff), + LocalNodes.update(top, maxBumpFanin, other.maxBumpFanin), + LocalNodes.update(top, upSlew, other.upSlew), + LocalNodes.update(top, dnSlew, other.dnSlew), + LocalNodes.update(top, upSkew, other.upSkew), + LocalNodes.update(top, dnSkew, other.dnSkew), + LocalNodes.update(top, upBump, other.upBump), + LocalNodes.update(top, dnBump, other.dnBump), + LocalNodes.update(top, upDelay, other.upDelay), + LocalNodes.update(top, dnDelay, other.dnDelay)); + } + } + + private static class PropagateInfo { + public final float upPrsDelay; + public final float dnPrsDelay; + public final Signoff signoff; + + public PropagateInfo() { + this(Float.NaN, Float.NaN, Signoff.UNSPECIFIED); + } + + public PropagateInfo(final float upPrsDelay, + final float dnPrsDelay, + final Signoff signoff) { + this.upPrsDelay = upPrsDelay; + this.dnPrsDelay = dnPrsDelay; + this.signoff = signoff; + } + + public PropagateInfo update(PropagateInfo other, boolean top) { + return new PropagateInfo( + LocalNodes.update(top, upPrsDelay, other.upPrsDelay), + LocalNodes.update(top, dnPrsDelay, other.dnPrsDelay), + signoff.update(other.signoff, top)); + } + } + + private static float undef2NaN(final Map m, final HierName key) { + final Number val = (Number) m.get(key); + return val == null ? Float.NaN : val.floatValue(); + } + + private static float useDef(final float val, final float def) { + return Float.isNaN(val) ? def : val; + } + + private static float useDef(final float val) { + return useDef(val, -1); + } + + /** + * Update the value associated with key key in map + * map. If key does not exist in + * map, associate val with it. Otherwise, + * merge the old value and val, and associate + * key with a new array that contains the maximum of the + * new and old values. This is similar to + * AliasedMap.MergeFunction. + **/ + private void update(final Map map, + final HierName key, final PropagateInfo val, + final boolean top) { + assert key != null && val != null; + final PropagateInfo old = map.get(key); + map.put(key, old == null ? val : old.update(val, top)); + } + + /** + * Propagate delay information from leaf cells up. For the top-level + * cell, return a map from local nodes to signoff directives. + * Otherwise, return a map from port nodes to signoff directives. + **/ + private Map + propagateUp(final CellInterface cell, final boolean top) { + final Map cached = + cache.get(cell.getFullyQualifiedType()); + if (cached != null) return cached; + + final Map result = + new HashMap(); + final CadenceInfo cinfo = cad.convert(cell); + final AliasedSet locals = cinfo.getLocalNodes(); + final AliasedMap ports = cinfo.getPortNodes(); + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + + final CellInterface subcell = (CellInterface) p.getSecond(); + final Map subcellResult = + propagateUp(subcell, false); + + // Convert subcell names to canonical names in this cell + final HierName inst = (HierName) p.getFirst(); + for (Map.Entry entry : + subcellResult.entrySet()) { + final HierName key = + HierName.prefixName(inst, entry.getKey()); + final HierName local = + (HierName) locals.getCanonicalKey(key); + + // If local is null, then the name must be a local node of + // the subcell, so its information need not be propagated + // up any further + if (local != null && (top || ports.contains(local))) { + update(result, local, entry.getValue(), false); + } + } + } + + final Float tauF = (Float) + DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.TAU); + final float tau = tauF == null ? defaultTau : tauF.floatValue(); + + final CellDelay cellDelay = new CellDelay(cell, cad); + + final BlockInterface cb = cell.getBlockInterface(); + final List db = Arrays.asList( + DirectiveUtils.getUniqueBlock(cb, BlockInterface.PRS), + DirectiveUtils.getUniqueBlock(cb, BlockInterface.SUBCELL) + ); + + final Map alintSignoff = DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getMultipleBlockDirective + ( db, + DirectiveConstants.ALINT_SIGNOFF, + DirectiveConstants.NODE_TYPE )); + + final Map maxBumpFaninMap = DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getMultipleBlockDirective + ( db, + DirectiveConstants.ALINT_MAX_BUMP_FANIN, + DirectiveConstants.NODE_TYPE )); + + final Map delaySignoffMap = + DirectiveUtils.getMultipleBlockDirective + ( db, + DirectiveConstants.ESTIMATED_DELAY_SIGNOFF, + DirectiveConstants.HALFOP_TYPE ); + + final Map slewSignoffMap = + DirectiveUtils.getMultipleBlockDirective + ( db, + DirectiveConstants.SLEW_SIGNOFF, + DirectiveConstants.HALFOP_TYPE ); + + final Map skewSignoffMap = + DirectiveUtils.getMultipleBlockDirective + ( db, + DirectiveConstants.SKEW_SIGNOFF, + DirectiveConstants.HALFOP_TYPE ); + + final Map bumpSignoffMap = + DirectiveUtils.getMultipleBlockDirective + ( db, + DirectiveConstants.BUMP_SIGNOFF, + DirectiveConstants.HALFOP_TYPE ); + + final Map delaySignoffUpMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getUps(delaySignoffMap)); + final Map delaySignoffDnMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getDowns(delaySignoffMap)); + + final Map slewSignoffUpMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getUps(slewSignoffMap)); + final Map slewSignoffDnMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getDowns(slewSignoffMap)); + + final Map skewSignoffUpMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getUps(skewSignoffMap)); + final Map skewSignoffDnMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getDowns(skewSignoffMap)); + + final Map bumpSignoffUpMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getUps(bumpSignoffMap)); + final Map bumpSignoffDnMap = + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getDowns(bumpSignoffMap)); + + // Find all targets of production rules + final Set prsTarget = new HashSet(); + for (Iterator i = cell.getProductionRuleSet().getProductionRules(); + i.hasNext(); ) { + final ProductionRule pr = (ProductionRule) i.next(); + final HierName target = + (HierName) locals.getCanonicalKey(pr.getTarget()); + prsTarget.add(target); + } + + // Look at port nodes which are used, since only they can be + // connected to local nodes of an instantiating cell. Unless we + // are examining the top-level cell, then we are interested only in + // the local nodes. + for (Iterator i = top ? locals.getCanonicalKeys() : + ports.getCanonicalKeys(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + final Boolean aso = (Boolean) alintSignoff.get(port); + final Signoff signoff = Signoff.getInstance( + aso == null ? Float.NaN : (aso ? 1 : 0), + undef2NaN(maxBumpFaninMap, port), + undef2NaN(slewSignoffUpMap, port), + undef2NaN(slewSignoffDnMap, port), + undef2NaN(skewSignoffUpMap, port), + undef2NaN(skewSignoffDnMap, port), + undef2NaN(bumpSignoffUpMap, port), + undef2NaN(bumpSignoffDnMap, port), + undef2NaN(delaySignoffUpMap, port), + undef2NaN(delaySignoffDnMap, port)); + final PropagateInfo other = new PropagateInfo( + prsTarget.contains(port) ? + cellDelay.getDelay(port, true, tau) : Float.NaN, + prsTarget.contains(port) ? + cellDelay.getDelay(port, false, tau) : Float.NaN, + signoff); + update(result, port, other, top); + } + cache.put(cell.getFullyQualifiedType(), result); + return result; + } + private boolean getAlintSignoff(final CellInterface cell, + final HierName canon, + final float nodeSignoff) { + //sign off all the nodes in the entire cell + if(((Boolean) DirectiveUtils.getTopLevelDirective + ( cell,DirectiveConstants.ALINT_IGNORE )).booleanValue()) + return true; + + return nodeSignoff == 1f; + } + public static double getDoubleDirective(final Map /**/ delay, + final HierName canon) { + final Float d = (Float) delay.get(canon); + return d == null ? -1 : d.doubleValue(); + } + + public static int getIntDirective(final Map /**/ map, + final HierName canon) { + final Integer i = (Integer) map.get(canon); + return i == null ? -1 : i.intValue(); + } + + public Map getDelay(final CellInterface cell, final boolean up) { + final AliasedSet locals = cad.convert(cell).getLocalNodes(); + + // Get estimated delay; canonize the directives + final Map delayMap = CellUtils.isLeaf(cell) ? + DirectiveUtils.getPrsDirective(cell, + DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.HALFOP_TYPE) : + DirectiveUtils.getSubcellDirective(cell, + DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.HALFOP_TYPE); + final Map delayDirMap = DirectiveUtils.canonizeKey(locals, + up ? DirectiveUtils.getUps(delayMap) + : DirectiveUtils.getDowns(delayMap)); + + // Get extra delay in mid-level cells; canonize the directives + final Map extraMap = CellUtils.isLeaf(cell) ? + Collections.EMPTY_MAP : + DirectiveUtils.getSubcellDirective(cell, + DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.HALFOP_TYPE); + final Map extraDirMap = DirectiveUtils.canonizeKey(locals, + up ? DirectiveUtils.getUps(extraMap) + : DirectiveUtils.getDowns(extraMap)); + + // Calculate the maximum delay on a net from DSim delays + final Map cellDelay = + propagateUp(cell, true); + + // Combine estimated delay and DSim delays. Let estimated_delay + // override DSim delays. + final Map result = new HashMap(); + final Float tauF = (Float) + DirectiveUtils.getTopLevelDirective(cell, + DirectiveConstants.TAU); + final float tau = tauF == null ? defaultTau : tauF.floatValue(); + for (Map.Entry entry : + cellDelay.entrySet()) { + final HierName canon = entry.getKey(); + double delay = useDef(up ? entry.getValue().upPrsDelay + : entry.getValue().dnPrsDelay, + 0); + final Float extraDelay = (Float) extraDirMap.get(canon); + if (extraDelay != null) + delay += extraDelay.floatValue() * tau / 100; + result.put(canon, new Float(delay)); + } + result.putAll(delayDirMap); + + return result; + } + private double getDir(final Map dirs, final HierName node, double old) { + if (dirs.containsKey(node)) { + return ((Float) dirs.get(node)).doubleValue(); + } else { + return old; + } + } + private Set prsUsed(final CellInterface cell, final AliasedSet nodes) { + final Set result = new HashSet(); + for (Iterator i = cell.getProductionRuleSet().getProductionRules(); + i.hasNext(); ) { + final ProductionRule prs = (ProductionRule) i.next(); + prs.foreachHierName(new UnaryAction() { + public void execute(final Object o) { + final HierName canon = + (HierName) nodes.getCanonicalKey((HierName) o); + assert canon != null; + result.add(canon); + } + }); + } + return result; + } + private boolean subcellUsed(final CellInterface cell, HierName name) { + HierName port = null; + CellInterface subcell = null; + while (name != null) { + subcell = cell.getSubcell(name); + if (subcell != null) break; + final HierName suffix = + HierName.makeHierName(name.getSuffixString()); + port = port == null ? suffix : HierName.append(suffix, port); + name = name.getParent(); + } + assert name != null : "Node " + name + " does not exist in cell " + + cell.getFullyQualifiedType(); + if (port == null) return false; + else { + final AliasedMap ports = cad.convert(subcell).getPortNodes(); + final Boolean use = (Boolean) ports.getValue(port); + return use.booleanValue(); + } + } + private boolean subcellUsed(final CellInterface cell, + final Iterator alias) { + while (alias.hasNext()) { + final HierName name = (HierName) alias.next(); + if (subcellUsed(cell, name)) return true; + } + return false; + } + private static final BinaryFunction EMSpecUpdater = new BinaryFunction() + { + public Object execute(final Object a, final Object b) { + final Object[] o1 = (Object[]) a; + final Object[] o2 = (Object[]) b; + assert o1.length == o2.length; + final Object[] result = new Object[o1.length]; + for (int i = 0; i < result.length; ++i) { + final Number n1 = (Number) o1[i]; + final Number n2 = (Number) o2[i]; + result[i] = n1.doubleValue() > n2.doubleValue() ? n1 : n2; + } + return result; + } + }; + + private static HierName toHier(final String s) { + try { + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Can't convert to HierName: " + s); + } + } + + /** Non-recursive by definition **/ + public void doTask(final CellInterface cell, final Writer w, + boolean noRecurse) + throws IOException { doTask(cell, w); } + + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + + final CadenceInfo cinfo = cad.convert(cell); + final AliasedSet nodes = cinfo.getLocalNodes(); + final AliasedMap ports = cinfo.getPortNodes(); + final GetAliases getAliases = new GetAliases(cad); + + final BlockInterface cellBlock = cell.getBlockInterface(); + + final Map widthMap = + DirectiveUtils.getMultipleBlockDirective + ( Arrays.asList + ( new BlockInterface[] + { cellBlock, + DirectiveUtils.getUniqueBlock + (cellBlock, + BlockInterface.SUBCELL) } ), + DirectiveConstants.WIREWIDTH, + DirectiveConstants.NODE_TYPE ); + + final Map spaceMap = + DirectiveUtils.getMultipleBlockDirective + ( Arrays.asList + ( new BlockInterface[] + { cellBlock, + DirectiveUtils.getUniqueBlock + (cellBlock, + BlockInterface.SUBCELL) } ), + DirectiveConstants.WIRESPACE, + DirectiveConstants.NODE_TYPE ); + + final double widthCell = + ( (Float) DirectiveUtils.getTopLevelDirective + ( cell, + DirectiveConstants.WIREWIDTH ) ).doubleValue(); + final double spaceCell = + ( (Float) DirectiveUtils.getTopLevelDirective + ( cell, + DirectiveConstants.WIRESPACE ) ).doubleValue(); + + final Map activityFactor; + if (EMReport) { + activityFactor = + NetProperty.getNodeProperties( + new NetProperty.Cache(), cell, cad, + NetProperty.WireProperty.getFactory( + new NetProperty.WireProperty.EMDirective( + cad, + DirectiveConstants.ACTIVITY_FACTOR, + NetProperty.WireProperty.MAX), + NetProperty.WireProperty.MAX)); + } else { + activityFactor = null; + } + + final Set dynamicNodes = new HashSet(); + try { + final Map portNodesCache = new HashMap(); + final Map nodesCache = new HashMap(); + dynamicNodes.addAll( + CastStat.getDynamicNodes(cell, cad, cfp, portNodesCache, + nodesCache)); + dynamicNodes.addAll( + CastStat.getDynamicPortNodes(cell, cad, cfp, portNodesCache, + nodesCache)); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot find dynamic nodes", e); + } + + final Set prsSet = used ? prsUsed(cell, nodes) : null; + final Map cellDelayUp = getDelay(cell, true); + final Map cellDelayDn = getDelay(cell, false); + + final Map driversCache = drivers ? new HashMap() : null; + final PartialExtract.LeafCallback cb = + drivers ? new DriversCallback() : null; + + final Map propagateInfo = + propagateUp(cell, true); + + final Map portDirs = + CellUtils.getCanonicalDir(new HashMap(), + cell, nodes); + + header("Local nodes of " + cell.getFullyQualifiedType() + ":\n", w); + final PropagateInfo defSignoff = new PropagateInfo(); + for (Iterator i = new SortingIterator(nodes.getCanonicalKeys()); + i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + if (nodeSet!=null && + !nodeSet.contains(canon.toString())) continue; + if (!includePorts && ports.getCanonicalKey(canon) != null) + continue; + if (prsSet != null && !prsSet.contains(canon) && + !subcellUsed(cell, nodes.getAliases(canon))) continue; + + final PropagateInfo pinfo = propagateInfo.get(canon); + final Signoff signoff = pinfo == null ? Signoff.UNSPECIFIED + : pinfo.signoff; + + double width = widthCell, space = spaceCell; + final double delayUp = getDoubleDirective(cellDelayUp, canon); + final double delayDn = getDoubleDirective(cellDelayDn, canon); + final double delaySignoffUp = useDef(signoff.upDelay); + final double delaySignoffDn = useDef(signoff.dnDelay); + final double slewSignoffUp = useDef(signoff.upSlew); + final double slewSignoffDn = useDef(signoff.dnSlew); + final double skewSignoffUp = useDef(signoff.upSkew); + final double skewSignoffDn = useDef(signoff.dnSkew); + final double bumpSignoffUp = useDef(signoff.upBump); + final double bumpSignoffDn = useDef(signoff.dnBump); + final int maxBumpFanin = (int) useDef(signoff.maxBumpFanin); + if (getAlintSignoff(cell, canon, useDef(signoff.alintSignoff))) + { + w.write("SIGNOFF "); + } + + w.write(canon.getCadenceString()); + for (Iterator j = nodes.getAliases(canon); j.hasNext(); ) { + final HierName aliasName = (HierName) j.next(); + if (alias && !all_alias && !aliasName.equals(canon)) { + w.write("=" + aliasName.getCadenceString()); + } + width = getDir(widthMap, aliasName, width); + space = getDir(spaceMap, aliasName, space); + } + if (all_alias) { + for (Iterator j = getAliases.getAliases(cell, canon); + j.hasNext(); ) { + final HierName aliasName = (HierName) j.next(); + if (!aliasName.equals(canon)) { + w.write("=" + aliasName.getCadenceString()); + } + } + } + w.write(" "); + w.write(dynamicNodes.contains(canon.toString()) ? "1" : "0"); + w.write(" " + printDouble(delayUp) + " " + printDouble(delayDn)); + w.write(" " + printDouble(delaySignoffUp) + " " + printDouble(delaySignoffDn)); + w.write(" " + printDouble(slewSignoffUp) + " " + printDouble(slewSignoffDn)); + w.write(" " + printDouble(skewSignoffUp) + " " + printDouble(skewSignoffDn)); + w.write(" " + printDouble(bumpSignoffUp) + " " + printDouble(bumpSignoffDn)); + w.write(" " + printDouble(width) + " " + printDouble(space)); + if (driversCache != null) { + final Set drvs = PartialExtract.getLeafDrivers(cell, canon, cad, driversCache, cb); + for (Iterator j = drvs.iterator(); j.hasNext(); ) { + w.write(" "); + final Triplet t = (Triplet) j.next(); + final CellInterface c = (CellInterface) t.getFirst(); + w.write(c.getFullyQualifiedType() + "/" + t.getSecond() + "/"); + final Collection coll = (Collection) t.getThird(); + for (Iterator k = coll.iterator(); k.hasNext(); ) { + w.write((String) k.next()); + if (k.hasNext()) w.write(","); + } + } + } + if (activityFactor != null) { + final Number n = (Number) ((NetProperty.Property) activityFactor.get(canon)).getValue(); + w.write(" " + (n == null ? "-1" + : printDouble(n.doubleValue()))); + } + w.write(" " + maxBumpFanin); + + if (includePorts) { + final String dirStr; + final Integer portDir = portDirs.get(canon); + if (portDir == null) { + dirStr = "INTERNAL"; + } else { + switch (portDir) { + case PortDefinition.IN: dirStr = "IN"; break; + case PortDefinition.OUT: dirStr = "OUT"; break; + case PortDefinition.INOUT: dirStr = "INOUT"; break; + default: dirStr = "NONE"; break; + } + } + w.write(" " + dirStr); + } + + w.write("\n"); + } + } + } + + /** + * Print out the directives related to EM on all nodes in the cell. + **/ + public static class EMSpec extends FlatTask { + private final CastFileParser cfp; + private final Cadencize cad; + + public EMSpec(final CastFileParser cfp, final Cadencize cad) { + this.cfp = cfp; + this.cad = cad; + } + + private static final BinaryFunction EMSpecUpdater = new BinaryFunction() + { + public Object execute(final Object a, final Object b) { + final Object[] o1 = (Object[]) a; + final Object[] o2 = (Object[]) b; + assert o1.length == o2.length; + final Object[] result = new Object[o1.length]; + for (int i = 0; i < result.length; ++i) { + final Number n1 = (Number) o1[i]; + final Number n2 = (Number) o2[i]; + result[i] = n1.doubleValue() > n2.doubleValue() ? n1 : n2; + } + return result; + } + }; + + /** Non-recursive by definition **/ + public void doTask(final CellInterface cell, final Writer w, + boolean noRecurse) + throws IOException { doTask(cell, w); } + + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + + final CadenceInfo cinfo = cad.convert(cell); + final AliasedSet nodes = cinfo.getLocalNodes(); + final AliasedMap ports = cinfo.getPortNodes(); + + final Map activityFactor = + NetProperty.getNodeProperties( + new NetProperty.Cache(), cell, cad, + NetProperty.WireProperty.getFactory( + new NetProperty.WireProperty.EMDirective( + cad, + DirectiveConstants.ACTIVITY_FACTOR, + NetProperty.WireProperty.MIN), + NetProperty.WireProperty.MIN, + true)); + final Map unidirSpec = + NetProperty.getNodeProperties( + new NetProperty.Cache(), cell, cad, + NetProperty.WireProperty.getFactory( + new NetProperty.WireProperty.EMDirective( + cad, + DirectiveConstants.DC_WIRING_SPEC, + EMSpecUpdater), + EMSpecUpdater, + true)); + final Map bidirSpec = + NetProperty.getNodeProperties( + new NetProperty.Cache(), cell, cad, + NetProperty.WireProperty.getFactory( + new NetProperty.WireProperty.EMDirective( + cad, + DirectiveConstants.AC_WIRING_SPEC, + EMSpecUpdater), + EMSpecUpdater, + true)); + + final Map wireWidth = + NetProperty.getNodeProperties( + new NetProperty.Cache(), cell, cad, + NetProperty.WireProperty.getFactory( + new NetProperty.WireProperty.WireDirective( + cad, + DirectiveConstants.WIREWIDTH, + NetProperty.WireProperty.MAX), + NetProperty.WireProperty.MAX)); + + header("EM spec of " + cell.getFullyQualifiedType() + ":\n", w); + for (Iterator i = new SortingIterator(nodes.getCanonicalKeys()); + i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + + final Number activity = (Number) ((NetProperty.Property) activityFactor.get(canon)).getValue(); + final List dc = (List) ((NetProperty.Property) unidirSpec.get(canon)).getValue(); + final List ac = (List) ((NetProperty.Property) bidirSpec.get(canon)).getValue(); + final Number width = (Number) ((NetProperty.Property) wireWidth.get(canon)).getValue(); + + if (activity == null && dc == null && ac == null && + width == null) continue; + + w.write(canon.getCadenceString()); + + w.write(" "); + w.write(activity == null ? "-1" + : printDouble(activity.doubleValue())); + + w.write(" "); + w.write(dc == null ? "-1 -1" : printDouble(((Number) dc.get(0)).doubleValue()) + " " + printDouble(((Number) dc.get(1)).doubleValue())); + + w.write(" "); + w.write(ac == null ? "-1 -1" : printDouble(((Number) ac.get(0)).doubleValue()) + " " + printDouble(((Number) ac.get(1)).doubleValue())); + + w.write(" "); + w.write(width == null ? "-1" + : printDouble(width.doubleValue())); + w.write("\n"); + } + } + } + + /** + * Print out the dynamic nodes in the cell. Optionally output the aliases. + **/ + public static class DynamicNodes extends FlatTask { + private final CastFileParser cfp; + private final Cadencize cad; + private final boolean alias, leaky; + public DynamicNodes(final CastFileParser cfp, final Cadencize cad, + final boolean alias, final boolean leaky) { + this.cfp = cfp; + this.cad = cad; + this.alias = alias; + this.leaky = leaky; + } + /** + * Output all dynamic nodes that are internal to leaf cells. + **/ + private void leakyDynamic(final CellInterface cell, + final HierName prefix, final Map cache, + final Writer w) throws IOException { + if (CellUtils.isLeaf(cell)) { + Set nodes = (Set) cache.get(cell.getFullyQualifiedType()); + final AliasedSet locals = cad.convert(cell).getLocalNodes(); + if (nodes == null) { + nodes = new TreeSet(); + CastStat.getDynamicNodes(cell, cfp, cad, nodes); + final AliasedMap ports = cad.convert(cell).getPortNodes(); + // remove dynamic nodes that are in the port list + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + if (ports.contains(i.next())) i.remove(); + } + + // the leaky directive is used to override the default + // behavior of excluding ports + final Set leaky = + DirectiveUtils.getExplicitTrues( + DirectiveUtils.canonizeKey( + locals, + DirectiveUtils.getPrsDirective(cell, + DirectiveConstants.LEAKY, + DirectiveConstants.NODE_TYPE))); + nodes.addAll(leaky); + cache.put(cell.getFullyQualifiedType(), nodes); + } + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + final HierName node = (HierName) i.next(); + w.write(HierName.prefixName(prefix, node).toString()); + if (alias) { + for (Iterator j = locals.getAliases(node); + j.hasNext(); ) { + final HierName connected = (HierName) j.next(); + if (!node.equals(connected)) + w.write("=" + HierName.prefixName(prefix, connected).toString()); + } + } + w.write("\n"); + } + } else { + for (Iterator i = new SortingIterator( + cell.getSubcellPairs(), + new Comparator() { + public int compare(Object o1, Object o2) { + final HierName h1 = + (HierName) ((Pair) o1).getFirst(); + final HierName h2 = + (HierName) ((Pair) o2).getFirst(); + return h1.compareTo(h2); + } + }); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (subcell.isChannel() || subcell.isNode()) continue; + final HierName name = (HierName) p.getFirst(); + leakyDynamic(subcell, HierName.prefixName(prefix, name), + cache, w); + } + } + } + private void allDynamic(final CellInterface cell, + final Writer w) throws IOException { + final Map port = CellUtils.markPorts(cell); + // XXX: the two argument version of getDynamicNodes() is actually + // very inefficient, as it flattens the cell to resolve aliases + for (Iterator i = CastStat.getDynamicNodes(cell, cfp); + i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName canon = (HierName) p.getFirst(); + w.write(canon.getCadenceString()); + boolean outputNode = false; + for (Iterator j = (Iterator) p.getSecond(); j.hasNext(); ) { + final HierName aliasName = (HierName) j.next(); + final String aliasStr = aliasName.getCadenceString(); + if (alias && !canon.equals(aliasName)) { + w.write("=" + aliasStr); + } + final Integer portDir = (Integer) port.get(aliasStr); + outputNode |= portDir != null && + (portDir.intValue() == PortDefinition.OUT || + portDir.intValue() == PortDefinition.INOUT); + } + if (outputNode) w.write(" *"); + w.write("\n"); + } + } + + /** Non-recursive by definition **/ + public void doTask(final CellInterface cell, final Writer w, + boolean noRecurse) + throws IOException { doTask(cell, w); } + + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + header("Dynamic nodes of " + cell.getFullyQualifiedType() + ":\n", w); + if (leaky) { + leakyDynamic(cell, null, new HashMap(), w); + } else { + allDynamic(cell, w); + } + } + } + + /** + * Gather transistor statistics: number of transistors, total width, total + * area. + **/ + private static class TransistorStat extends HierTask { + private static class Stat { + private int number; + private double width; + private double area; + public Stat(final int number, final double width, + final double area) { + this.number = number; + this.width = width; + this.area = area; + } + public void add(final int number, final double width, + final double area) { + this.number += number; + this.width += width; + this.area += area; + } + public int getNumber() { + return number; + } + public double getWidth() { + return width; + } + public double getArea() { + return area; + } + public String toString() { + return Integer.toString(getNumber()) + " " + + printDouble(getWidth()) + " " + + printDouble(getArea()); + } + } + + private static class Stats { + private final Map stats; + public Stats() { + this.stats = new TreeMap(); + } + public Stat getStat(final String key) { + Stat s = stats.get(key); + if (s == null) { + s = new Stat(0, 0, 0); + stats.put(key, s); + } + return s; + } + public void combine(final Stats o) { + for (Map.Entry entry : o.stats.entrySet()) { + final Stat prev = getStat(entry.getKey()); + final Stat curr = entry.getValue(); + prev.add(curr.getNumber(), curr.getWidth(), curr.getArea()); + } + } + public Stat total() { + final Stat result = new Stat(0, 0, 0); + for (Map.Entry entry : stats.entrySet()) { + final Stat val = entry.getValue(); + result.add(val.getNumber(), val.getWidth(), val.getArea()); + } + return result; + } + public String toString() { + final StringBuilder sb = new StringBuilder(); + boolean first = true; + for (Map.Entry entry : stats.entrySet()) { + if (first) { + first = false; + } else { + sb.append(' '); + } + sb.append(entry.getKey()); + sb.append('/'); + sb.append(entry.getValue()); + } + return sb.toString(); + } + } + + private static class Helper extends CDLFactoryAdaptor { + private final Stats stats; + public Helper() { + this.stats = new Stats(); + } + public void makeTransistor(HierName name, String type, + HierName ns, HierName nd, HierName ng, + HierName nb, CDLLexer.InfoToken w, + CDLLexer.InfoToken l, Map parameters, + Environment env) { + final double width = CDLInterfaceSimplifier.getValue(w, env); + final double length = CDLInterfaceSimplifier.getValue(l, env); + // Skip over floating transistors + if (width > 0) { + stats.getStat(type).add(1, width, length * width); + } + } + public Stats getStats() { + return stats; + } + } + + private static Stats getStats(final CellInterface cell, final Map cache, + final UnaryPredicate filter, + final CDLInlineFactory.Retriever retr) { + final String type = cell.getFullyQualifiedType(); + if (cache.containsKey(type)) { + return (Stats) cache.get(type); + } else { + final Stats result = new Stats(); + if (cell.containsNetlist()) { + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + final Helper helper = new Helper(); + final CDLInlineFactory inliner = + new CDLInlineFactory(false, retr); + inliner.setProxy(helper); + nb.getCDLTemplate().execute(inliner); + result.combine(helper.getStats()); + } + for (Iterator i = CellUtils.filterSubcellPairs(cell, filter); + i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final Stats stat = getStats(subcell, cache, filter, retr); + result.combine(stat); + } + cache.put(type, result); + return result; + } + } + + private final Map cache; + private final CDLInlineFactory.Retriever retr; + private final boolean detail; + private final UnaryPredicate filter; + public TransistorStat(final CastFileParser cfp, final Set skip, + final boolean detail, + final UnaryPredicate filter) { + cache = new HashMap(); + retr = new CDLInlineFactory.RetrieveFromCast(cfp) { + public Template getTemplate(final String subName) { + if (skip.contains(subName)) { + return null; + } else { + return super.getTemplate(subName); + } + } + }; + this.detail = detail; + this.filter = filter; + } + + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + final Stats stats = getStats(cell, cache, filter, retr); + if (detail) { + w.write(stats.toString()); + } else { + final Stat total = stats.total(); + w.write(total.toString()); + } + } + } + + /** + * Count the number of production rules. Code adopted from Abe's original + * CountPrs. + **/ + private static class PrsCount extends HierTask { + private static boolean isRealCell(final CellInterface cell) { + return cell.containsCompletePrs() || + cell.containsCsp() || + cell.containsJava() || + cell.containsCompleteSubcells(); + } + private static int count(final ProductionRuleSet prsSet, + final boolean useDnf) { + int result = 0; + if (useDnf) { + for (Iterator i = prsSet.getProductionRules(); i.hasNext(); ) { + final ProductionRule pr = (ProductionRule) i.next(); + final BooleanExpressionInterface b = pr.getGuard(); + final OrBooleanExpressionInterface dnf = b.DNFForm(); + result += dnf.getDisjuncts().size(); + } + } else { + result = prsSet.size(); + } + return result; + } + + public static int count(final CellInterface cell, final Map cache, + final boolean useDnf) { + final String type = cell.getFullyQualifiedType(); + if (cache.containsKey(type)) { + return ((Integer) cache.get(type)).intValue(); + } else { + int result = count(cell.getProductionRuleSet(), useDnf); + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (isRealCell(subcell)) { + result += count(subcell, cache, useDnf); + } + } + cache.put(type, new Integer(result)); + return result; + } + } + private Map cache; + private final boolean useDnf; + + public PrsCount(final boolean useDnf) { + cache = new HashMap(); + this.useDnf = useDnf; + } + + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + w.write(Integer.toString(count(cell, cache, useDnf))); + } + } + + + /** + * Count the number dynamicNodes for a all down the hierarchy + * + **/ + private static class CountDynamicNodes extends HierTask { + private final CastFileParser cfp; + + public int count(final CellInterface cell) { + int result = 0; + for (Iterator i = CastStat.getDynamicNodes(cell, cfp); + i.hasNext(); ) { result++; i.next(); } + return result; + } + public CountDynamicNodes(final CastFileParser cfp) { + this.cfp = cfp; + } + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + w.write(Integer.toString(count(cell))); + } + } + + /** + * Generate instance counts. + **/ + private static class InstanceCount extends HierTask { + private Map counts = null; + private final String cellName; + private final CastFileParser cfp; + public InstanceCount(final String cellName, final CastFileParser cfp) { + this.cellName = cellName; + this.cfp = cfp; + } + private void traverse(final CellInterface cell, final Map count) { + final String fullName = cell.getFullyQualifiedType(); + if (!count.containsKey(fullName)) { + count.put(fullName, new int[] { 0 }); + } + ((int[]) count.get(fullName))[0]++; + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair pair = (Pair) i.next(); + final CellInterface subcell = (CellInterface) pair.getSecond(); + final String subtype = subcell.getFullyQualifiedType(); + if (CellUtils.isWiring(subcell)) continue; + traverse(subcell, count); + } + } + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + if (counts == null) { + counts = new HashMap(); + try { + traverse(cfp.getFullyQualifiedCell(cellName), counts); + } catch (Exception e) { + throw new RuntimeException("Cannot happen!"); + } + } + final int[] c = (int[]) counts.get(cell.getFullyQualifiedType()); + if (c == null) { + w.write("null"); + } else { + w.write(Integer.toString(c[0])); + } + } + } + + private static class InstanceList extends FlatTask { + private final String cellName; + private final CastFileParser cfp; + private final boolean verilog; + private final boolean skipWiring; + private final CDLNameInterface renamer; + public InstanceList(final String cellName, final CastFileParser cfp, + final boolean verilog, final boolean skipWiring, + final CDLNameInterface renamer) { + this.cellName = cellName; + this.cfp = cfp; + this.verilog = verilog; + this.skipWiring = skipWiring; + this.renamer = renamer; + } + private void traverse(final CellInterface cell, final LinkedList path, + final Writer w, boolean noRecurse) + throws IOException { + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName instance = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (skipWiring && CellUtils.isWiring(subcell)) continue; + if (!subcell.isNode() && !subcell.isChannel()) { + path.addLast(instance); + w.write(translateCell(subcell.getFullyQualifiedType(), + renamer)); + w.write(" "); + writePath(path, w); + w.write("\n"); + if (!noRecurse) { + traverse(subcell, path, w, noRecurse); + } + path.removeLast(); + } + } + } + private void writePath(final LinkedList path, final Writer w) + throws IOException { + final StringBuffer buf = verilog ? null : new StringBuffer(); + for (Iterator i = path.iterator(); i.hasNext(); ) { + final String part = i.next().toString(); + if (verilog) { + w.write(VerilogUtil.escapeIfNeeded(part)); + if (i.hasNext()) w.write('.'); + } else { + buf.append(part); + if (i.hasNext()) buf.append('.'); + } + } + if (!verilog) { + w.write(translateInstance(buf.toString(), renamer)); + } + } + public void doTask(final CellInterface cell, final Writer w, + boolean noRecurse) + throws IOException { + traverse(cell, new LinkedList(), w, noRecurse); + } + public void doTask(final CellInterface cell, final Writer w) + throws IOException { doTask(cell, w, false); } + } + + /** + * Print out top-level ParamDirectives in a cell. + * only really works with --no-recurse + **/ + private static class ParamDirectiveValue extends HierTask { + private final String dir; + private final String valType; + public ParamDirectiveValue(final String dir, final String valType) { + this.dir = dir; + this.valType = valType; + } + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + final Map dm = DirectiveUtils.getTopLevelDirective(cell, dir, valType); + if (dm == null) { + w.write("null"); + } else { + // identify the directive + w.write(dir+":"); + // write the directive parameter and the value + for (Iterator i = dm.keySet().iterator(); i.hasNext();) { + Object key = i.next(); + w.write(key+"="+dm.get(key)); + if (i.hasNext()) w.write(":"); + } + } + } + } + + /** + * Print out top-level directives in a cell. + **/ + private static class DirectiveValue extends HierTask { + private final String dir; + private final String valType; + public DirectiveValue(final String dir, final String valType) { + this.dir = dir; + this.valType = valType; + } + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + final Object o = DirectiveUtils.getTopLevelDirective(cell, dir); + if (o == null) { + w.write("null"); + } else { + final DirectiveEmitter emitter = CastEmitter.getInstance(); + w.write(emitter.emit(BlockInterface.CELL, valType, o)); + } + } + } + + private static class RailStats extends HierTask { + private final Cadencize cad; + public RailStats(final Cadencize cad) { + this.cad = cad; + } + private static class MarkPort extends CellUtils.MarkPort { + private static final Pattern DATARAIL = + Pattern.compile(".*\\.d(\\[\\d+\\])?"); + + public int inputChannels = 0, outputChannels = 0; + public Set inputRails = new HashSet(), outputRails = new HashSet(); + private final AliasedSet aliases; + private boolean okay = false; + public MarkPort(final AliasedSet aliases) { + this.aliases = aliases; + } + protected void mark(final ChannelType channelType, + final String name, final int direction) { + final boolean old = okay; + okay = true; + super.mark(channelType, name, direction); + okay = old; + if (direction < 0) ++inputChannels; + else if (direction > 0) ++outputChannels; + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + if (okay && DATARAIL.matcher(name).matches()) { + final Object canon; + try { + canon = aliases.getCanonicalKey(HierName.makeHierName(name, '.')); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot convert " + name + " to HierName", e); + } + + if (direction < 0) { + inputRails.add(canon); + } else if (direction > 0) { + outputRails.add(canon); + } + } + } + } + + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + final MarkPort mp = new MarkPort(cad.convert(cell).getLocalNodes()); + mp.mark(cell); + w.write(mp.inputChannels + " " + mp.outputChannels + " " + + mp.inputRails.size() + " " + mp.outputRails.size()); + } + } + + /** + /** + * Print out the routine complexity of a cell: number of subcells, number + * of local nets, and total number of connections. + **/ + private static class RoutingComplexity extends HierTask { + private final Cadencize cad; + public RoutingComplexity(final Cadencize cad) { + this.cad = cad; + } + + private int countKeys(final AliasedSet nodes, final AliasedMap ports) { + int count = 0; + for (Iterator i = nodes.getCanonicalKeys(); i.hasNext(); ) { + Object node = i.next(); + if (ports.getCanonicalKey(node) == null) ++count; + } + return count; + } + + private int getConnections(final AliasedMap ports) { + int result = 0; + for (Iterator i = ports.getValues(); i.hasNext(); ) { + if (((Boolean) i.next()).booleanValue()) ++result; + } + return result; + } + + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + final CadenceInfo cinfo = cad.convert(cell); + + int subcells = 0; + int connections = 0; + int nets = 0; + int ports = 0; + + for (Iterator i = cinfo.getPortNodes().getValues(); + i.hasNext(); + i.next() ) { + ++ports; + } + + if (cell.containsNetlist()) { //leaf cell + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST).next(); + + final Map templateMap = new HashMap(); + templateMap.put(cell.getFullyQualifiedType(), + nb.getCDLTemplate()); + final CDLstat.CellStat cellStat = + CDLstat.getCellStat(cell.getFullyQualifiedType(), + templateMap); + + connections = cellStat.getNumConnections(); + subcells = cellStat.instances; + nets = cellStat.getNumLocalNets(); + } else { + for (Iterator i = cinfo.getSubcellPairIterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CadenceInfo sinfo = (CadenceInfo) p.getSecond(); + final AliasedMap sports = sinfo.getPortNodes(); + connections += getConnections(sports); + ++subcells; + } + nets = countKeys(cinfo.getLocalNodes(), + cinfo.getPortNodes()); + + } + w.write(Integer.toString(subcells) + " " + + Integer.toString(nets) + " " + + Integer.toString(ports) + " " + + Integer.toString(connections)); + } + } + + /** + * Do nothing. Useful for just getting a list of cells. + **/ + private static class HierNop extends HierTask { + public HierNop() { + } + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + } + } + + /** + * Print out a list of cells instantiated, in ASCII tree form. + **/ + private static class SubcellTree extends FlatTask { + private static void instanceTree(final CellInterface ci, + final String space, + final String header, + final Writer w, + boolean noRecurse) throws IOException { + final Map seen = new TreeMap(); + for (Iterator i = ci.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair pair = (Pair) i.next(); + final CellInterface subcell = (CellInterface) pair.getSecond(); + final String subtype = subcell.getFullyQualifiedType(); + if (CellUtils.isWiring(subcell) || seen.containsKey(subtype)) { + continue; + } + seen.put(subtype, subcell); + } + + final String type = ci.getFullyQualifiedType(); + w.write(header); w.write(type); w.write("\n"); + if (noRecurse && !space.equals("")) return; + for (Iterator i = seen.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final CellInterface subcell = (CellInterface) entry.getValue(); + final String s = space + (i.hasNext() ? " |" : " "); + final String h = space + " +--"; + w.write(space + " |"); + w.write("\n"); + instanceTree(subcell, s + " ", h, w, noRecurse); + } + } + + public void doTask(final CellInterface ci, final Writer w, + boolean noRecurse) + throws IOException { + header("Subcell tree of " + ci.getFullyQualifiedType() + ":\n", w); + instanceTree(ci, "", "", w, noRecurse); + } + + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + doTask(ci, w, false); + } + } + + /** + * Print out a list of environments. + **/ + private static class PrintEnv extends HierTask { + /** + * Differ from CellUtils.isWiring in that this only returns true for + * nodes and channels. + **/ + private static boolean isWiring(final CellInterface cell) { + return cell.isChannel() || cell.isNode(); + } + private static boolean hasPrsImpl(final CellInterface cell) { + if (cell.containsCompletePrs()) { + return true; + } else if (cell.containsCompleteSubcells()) { + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (!isWiring(subcell) && !hasPrsImpl(subcell)) { + return false; + } + } + return true; + } else { + return false; + } + } + + private static boolean hasNtpcSpec(final CellInterface cell) { + Map quest = + DirectiveUtils.getEnvDirective(cell, + DirectiveConstants.NTPC_SPEC, + DirectiveConstants.NODE_TYPE); + return (quest.size() > 0); + } + + private static boolean isIgnore(final String dir, + final CellInterface cell, + final CellInterface env) { + return ((Boolean) DirectiveUtils.getEnvDirective(env, dir)).booleanValue() || ((Boolean) DirectiveUtils.getTopLevelDirective(cell, dir)).booleanValue(); + } + + public static Collection getEnvs(final CellInterface cell, + final boolean prsOnly, + final boolean rte_ignore, + final boolean ntpc_spec, + final boolean aspice_ignore) { + final Collection results = new ArrayList(); + final EnvBlock env = cell.getEnvironments(); + for (Iterator i = env.getNames(); i.hasNext(); ) { + final String name = (String) i.next(); + final CellInterface ci; + try { + ci = env.getNamedEnvironment(name); + } catch (CastSemanticException e) { + throw new RuntimeException("Unable to load environment: " + + name, e); + } + assert ci != null : "Cannot get environment " + name + + " from " + cell.getFullyQualifiedType(); + if ((!prsOnly || hasPrsImpl(ci)) && + (!rte_ignore || !isIgnore(DirectiveConstants.RTE_IGNORE, cell, ci)) && + (!ntpc_spec || hasNtpcSpec(ci)) && + (!aspice_ignore || !isIgnore(DirectiveConstants.ASPICE_IGNORE, cell, ci))) { + results.add(name); + } + } + return results; + } + private final boolean prsOnly; + private final boolean rte_ignore; + private final boolean ntpc_spec; + private final boolean aspice_ignore; + public PrintEnv(final boolean prsOnly, final boolean rte_ignore, + final boolean ntpc_spec, final boolean aspice_ignore) { + this.prsOnly = prsOnly; + this.rte_ignore = rte_ignore; + this.ntpc_spec = ntpc_spec; + this.aspice_ignore = aspice_ignore; + } + public void doTask(final CellInterface cell, final Writer w) + throws IOException { + for (Iterator i = getEnvs(cell, prsOnly, rte_ignore, + ntpc_spec, aspice_ignore).iterator(); + i.hasNext(); ) { + w.write((String) i.next()); + if (i.hasNext()) w.write(','); + } + } + } + + private static class RefinementLineage extends FlatTask { + private static void followRefinement(final CellInterface ci, + final Writer w) throws IOException + { + if (ci != null) { + final CellInterface parent = ci.getDirectRefinementParent(); + followRefinement(parent, w); + final String type = ci.getFullyQualifiedType(); + w.write(type + "\n"); + } + } + public void doTask(final CellInterface ci, final Writer w, + boolean noRecurse) throws IOException { + doTask(ci, w); + } + + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + header("Lineage of " + ci.getFullyQualifiedType() + ":\n", w); + followRefinement(ci, w); + } + } + + private static class AttributeList extends FlatTask { + public void doTask(final CellInterface ci, final Writer w, + boolean noRecurse) throws IOException { + doTask(ci, w); + } + + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + header("Attributes of " + ci.getFullyQualifiedType() + ":\n", w); + final Collection attribs = new LinkedHashSet(); + CellUtils.matchInheritance(ci, + new UnaryPredicate() { + public boolean evaluate(final Object o) { + final CellInterface attrib = (CellInterface) o; + attribs.add(attrib.getFullyQualifiedType()); + return false; + } + } + ); + for (Iterator i = attribs.iterator(); i.hasNext(); ) + w.write(i.next() + "\n"); + } + } + + private static class CanonicalName extends FlatTask { + private final Cadencize cad; + private final Reader input; + private final CDLNameInterface renamer; + private final Boolean doskill; + public CanonicalName(final Cadencize cad, final Reader input, + final CDLNameInterface renamer, boolean doskill) { + this.cad = cad; + this.input = input; + this.renamer = renamer; + this.doskill = doskill; + } + + public void doTask(final CellInterface ci, final Writer w, + boolean noRecurse) throws IOException { + doTask(ci, w); + } + + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + if( ! doskill ) + header("Canonical mapping for " + ci.getFullyQualifiedType() + + ":\n", w); + final BufferedReader br = new BufferedReader(input); + final AliasedSet locals = cad.convert(ci).getLocalNodes(); + String node; + int tablenr=1; + int linenr=0; + if (doskill) { + w.write("(defun NodeCanonicalTable1 ( )\n"); + w.write(" (let (\n"); + w.write(" ( Table ( makeTable `pd nil ) ) )\n"); + } + while ((node = br.readLine()) != null) { + final HierName canon; + try { + canon = (HierName) locals.getCanonicalKey( + HierName.makeHierName(node, '.')); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot convert " + node + + " to HierName", e); + } + final String canonname; + node=translateNode(node, renamer); + if(canon==null) canonname=""; + else canonname=translateNode(canon.getAsString('.'), renamer); + if ( doskill ) { + if(canon != null) { + if (linenr > 3000) { + tablenr++; + linenr=0; + w.write(" Table ) )\n\n"); + w.write("(defun NodeCanonicalTable"+tablenr+" ( )\n"); + w.write(" (let (\n"); + w.write(" ( Table ( makeTable `pd nil ) ) )\n"); + } + w.write(" ( setarray Table \""+node+"\" \""+canonname+"\" )\n"); + linenr++; + } + } + else { + w.write(node + "=" + canonname + "\n"); + } + } + br.close(); + if (doskill) { + w.write(" Table ) )\n\n"); + w.write("(defun NodeCanonicalTable ( )\n"); + w.write(" (let ( Key map\n"); + w.write(" ( Table ( makeTable `pd nil ) ) )\n"); + for ( int i = 1; i <= tablenr; i++) { + w.write(" map = NodeCanonicalTable"+i+"( )\n"); + w.write(" foreach( Key map\n"); + w.write(" ( setarray Table Key arrayref( map Key ) ) )\n"); + } + w.write(" Table ) )\n"); + } + } + } + + private static class InitialFloorplan extends FlatTask { + private final CDLNameInterface renamer; + private final Pattern regex; + public InitialFloorplan(final CDLNameInterface renamer, + final Pattern regex) { + this.renamer = renamer; + this.regex = regex; + } + public void doTask(final CellInterface ci, final Writer w, + boolean noRecurse) throws IOException { + doTask(ci, w); + } + + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + header("Initial floorplan of " + ci.getFullyQualifiedType() + ":\n", w); + for (Iterator i = ((com.avlsi.cell.CellImpl) ci).getFloorplanInstances(); + i.hasNext(); ) { + final Collection column = (Collection) i.next(); + boolean first = true; + for (Iterator j = column.iterator(); j.hasNext(); ) { + final HierName instance = (HierName) j.next(); + final CellInterface subcell = ci.getSubcell(instance); + if (CellUtils.isWiring(subcell)) continue; + if (regex != null) { + if (regex.matcher(subcell.getFullyQualifiedType()) + .matches()) continue; + } + + if (first) { + first = false; + } else { + w.write(' '); + } + w.write(translateInstance(instance.toString(), renamer)); + } + if (!first) w.write('\n'); + } + } + } + + private static class EnumerateScanChain extends FlatTask { + private class ScanType { + private final UnaryPredicate matcher; + private final HierName leftPort, rightPort; + private final boolean generic; + public ScanType(final String typeName, + final HierName leftPort, + final HierName rightPort, + final boolean generic) { + this.leftPort = leftPort; + this.rightPort = rightPort; + this.matcher = + CellUtils.getTypeMatcher(Collections.singleton(typeName)); + this.generic = generic; + } + public HierName getLeftPort() { + return leftPort; + } + public HierName getRightPort() { + return rightPort; + } + public boolean matches(final CellInterface cell) { + return matcher.evaluate(cell); + } + public boolean isGeneric() { + return generic; + } + } + private class ScanBuf { + private final HierName instanceName; + private final CellInterface scanCell; + private HierName leftName, rightName; + private final boolean generic; + public ScanBuf(final HierName instanceName, + final HierName leftName, + final HierName rightName, + final CellInterface scanCell, + final boolean generic) { + this.instanceName = instanceName; + this.scanCell = scanCell; + this.leftName = leftName; + this.rightName = rightName; + this.generic = generic; + } + public CellInterface getCell() { + return scanCell; + } + public HierName getInstance() { + return instanceName; + } + public HierName getLeftName() { + return leftName; + } + public HierName getRightName() { + return rightName; + } + public String toString() { + return getInstance() + " " + + getCell().getFullyQualifiedType() + " " + + getLeftName() + " " + + getRightName(); + } + public boolean isGeneric() { + return generic; + } + } + private class ScanChain { + private final LinkedList scanBufs; + boolean generic; + public ScanChain(final ScanBuf scanBuf) { + this.scanBufs = new LinkedList(); + scanBufs.add(scanBuf); + this.generic = scanBuf.isGeneric(); + } + public boolean catChain(final ScanChain chain) { + if (getLeftName().equals(chain.getRightName())) { + scanBufs.addAll(0, chain.scanBufs); + generic &= chain.isGeneric(); + return true; + } else if (getRightName().equals(chain.getLeftName())) { + scanBufs.addAll(chain.scanBufs); + generic &= chain.isGeneric(); + return true; + } else { + return false; + } + } + public HierName getLeftName() { + return scanBufs.getFirst().getLeftName(); + } + public HierName getRightName() { + return scanBufs.getLast().getRightName(); + } + public boolean isGeneric() { + return generic; + } + public String toString() { + final StringBuffer buf = new StringBuffer(); + for (ScanBuf scanBuf : scanBufs) { + buf.append(scanBuf.toString()); + buf.append('\n'); + } + return buf.toString(); + } + } + private final Cadencize cad; + private final Set skipSet; + private final List scanTypes; + private final List scanBufs; + private final Map scanChains; + public EnumerateScanChain(final Object[] baseTypes, + final Cadencize cad) { + this.scanTypes = new ArrayList(); + try { + for (int i = 0; i < baseTypes.length; i += 4) { + final String typeName = (String) baseTypes[i]; + final HierName leftPort = + HierName.makeHierName((String) baseTypes[i + 1], '.'); + final HierName rightPort = + HierName.makeHierName((String) baseTypes[i + 2], '.'); + final Boolean generic = (Boolean) baseTypes[i + 3]; + scanTypes.add(new ScanType(typeName, leftPort, rightPort, + generic.booleanValue())); + } + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName", e); + } + this.cad = cad; + this.skipSet = new HashSet(); + this.scanBufs = new ArrayList(); + this.scanChains = new HashMap(); + } + public void doTask(final CellInterface ci, final Writer w, + boolean noRecurse) throws IOException { + doTask(ci, w); + } + private HierName resolveName(final List path, final HierName portName) { + HierName name = portName; + CellInterface parent = null; + Pair curr = null, prev = null; + HierName left = null; + for (Iterator i = path.iterator(); i.hasNext(); ) { + prev = curr; + curr = (Pair) i.next(); + if (prev == null) continue; + + final HierName instance = (HierName) prev.getFirst(); + final CellInterface cell = (CellInterface) curr.getSecond(); + if (left != null) { + left = HierName.append(instance, left); + } else { + final AliasedSet aliases = + cad.convert(cell).getLocalNodes(); + name = HierName.append(instance, name); + final HierName canon = + (HierName) aliases.getCanonicalKey(name); + if (canon == null) { + left = instance; + } else { + name = canon; + } + } + } + return HierName.append(left, name); + } + private boolean processCell(final LinkedList path, + final HierName fullName) { + final Pair last = (Pair) path.getFirst(); + final CellInterface cell = (CellInterface) last.getSecond(); + if (skipSet.contains(cell.getFullyQualifiedType())) return false; + + boolean found = false; + final Set processed = new HashSet(); + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (subcell.isNode() || subcell.isChannel() || + skipSet.contains(subcell.getFullyQualifiedType())) continue; + path.addFirst(p); + final HierName instance = (HierName) p.getFirst(); + final HierName newName = HierName.append(fullName, instance); + for (ScanType scanType : scanTypes) { + if (scanType.matches(subcell)) { + found = true; + processed.add(instance); + final HierName leftName = + resolveName(path, scanType.getLeftPort()); + final HierName rightName = + resolveName(path, scanType.getRightPort()); + scanBufs.add(new ScanBuf(newName, leftName, rightName, + subcell, + scanType.isGeneric())); + break; + } + } + path.removeFirst(); + } + +NextPair: for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (subcell.isNode() || subcell.isChannel() || + skipSet.contains(subcell.getFullyQualifiedType())) continue; + + final HierName instance = (HierName) p.getFirst(); + if (processed.contains(instance)) continue; + for (Iterator j = processed.iterator(); j.hasNext(); ) { + if (instance.isChildOf((HierName) j.next())) + continue NextPair; + } + path.addFirst(p); + final HierName newName = HierName.append(fullName, instance); + found |= processCell(path, newName); + path.removeFirst(); + } + if (!found) skipSet.add(cell.getFullyQualifiedType()); + return found; + } + private void makeChains() { + for (ScanBuf buf : scanBufs) { + final ScanChain chain = new ScanChain(buf); + final ScanChain l = scanChains.remove(chain.getLeftName()); + final ScanChain r = scanChains.remove(chain.getRightName()); + if (l != null) chain.catChain(l); + if (r != null) chain.catChain(r); + scanChains.put(chain.getLeftName(), chain); + scanChains.put(chain.getRightName(), chain); + } + } + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + header("Tracing chains in " + ci.getFullyQualifiedType() + ":\n", w); + final LinkedList path = new LinkedList(); + path.add(new Pair(null, ci)); + processCell(path, null); + makeChains(); + for (ScanChain chain : new HashSet(scanChains.values())) + { + if (!chain.isGeneric()) { + w.write(chain.toString()); + w.write('\n'); + } + } + } + } + + private static class HierarchyLevel extends HierTask { + final Map cache; + public HierarchyLevel() { + cache = new HashMap(); + } + private int getLevel(final CellInterface ci) { + final Integer cached = + (Integer) cache.get(ci.getFullyQualifiedType()); + if (cached != null) return cached.intValue(); + int level = -1; + for (Iterator i = ci.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (!CellUtils.isWiring(subcell)) { + level = Math.max(level, getLevel(subcell)); + } + } + level++; + cache.put(ci.getFullyQualifiedType(), new Integer(level)); + return level; + } + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + w.write(Integer.toString(getLevel(ci))); + } + } + + private static class PortList extends FlatTask { + private final boolean primitive; + public PortList(final boolean primitive) { + this.primitive = primitive; + } + public void doTask(final CellInterface ci, final Writer w, + boolean noRecurse) throws IOException { + doTask(ci, w); + } + public void doTask(final CellInterface ci, final Writer w) + throws IOException { + for (Iterator i = ci.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition port = (PortDefinition) i.next(); + final String implied = + ci.isImpliedPort(port.getName()) ? "1 " : "0 "; + Iterator j = + Collections.singletonList(port).iterator(); + if (primitive) { + j = CellUtils.flattenPorts(j, + CellUtils.WIDE_CHANNEL_TYPE | + CellUtils.CHANNEL_TYPE | + CellUtils.WIDE_NODE_TYPE | + CellUtils.NODE_TYPE); + } + while (j.hasNext()) { + w.write(implied); + w.write(SubtypeOutput.portString(j.next(), true) + "\n"); + } + } + } + } + + /** + * Map of static predicates that depend only on the CellInterface. + **/ + private static final Map predicateMap = new HashMap(); + + static { + predicateMap.put("leaf", new UnaryPredicate() { + public boolean evaluate(Object a) { + final CellInterface x = (CellInterface) a; + return CellUtils.isLeaf(x); + } + }); + predicateMap.put("fixed", new UnaryPredicate() { + public boolean evaluate(Object a) { + final CellInterface x = (CellInterface) a; + return CellUtils.isFixed(x); + } + }); + predicateMap.put("netlist", new UnaryPredicate() { + public boolean evaluate(Object a) { + final CellInterface x = (CellInterface) a; + return x.containsNetlist(); + } + }); + predicateMap.put("routed", new UnaryPredicate() { + public boolean evaluate(Object a) { + final CellInterface x = (CellInterface) a; + return CellUtils.isRouted(x); + } + }); + } + + /** + * Returns an appropriate renamer given the target name, or null if the + * translation scheme is unknown. + **/ + private static CDLNameInterface getRenamer(final String scheme) { + final CDLNameInterface result; + if (scheme.equals("gdsII") || scheme.equals("gds2")) { + result = new GDS2NameInterface(); + } else if (scheme.equals("cadence")) { + result = new CadenceNameInterface(); + } else { + result = null; + } + return result; + } + + private static class MathFunction implements UnaryFunction { + private final Map dictCache; + private final MathExpression expr; + private final MathExpressionFactory factory; + public MathFunction(final Map dictCache, final MathExpression expr, + final MathExpressionFactory factory) { + this.dictCache = dictCache; + this.expr = expr; + this.factory = factory; + } + public Object execute(final Object o) { + final CellInterface x = (CellInterface) o; + final String type = x.getFullyQualifiedType(); + if (!dictCache.containsKey(type)) { + dictCache.put(type, new AttributeDictionary(x, factory)); + } + final MathExpression eval = + expr.evaluate((VariableDictionary) dictCache.get(type)); + try { + return new Double(eval.getConstantValue()); + } catch (NotAConstantValueException e) { + throw new RuntimeException("Cannot evaluate expression", e); + } + } + } + + private final static Set KNOWN_VARIABLES = + new HashSet(Arrays.asList(new String[] { + "prs" + })); + private static class AttributeDictionary implements VariableDictionary { + private final CellInterface cell; + private final MathExpressionFactory factory; + private final Map cache; + public AttributeDictionary(final CellInterface cell, + final MathExpressionFactory factory) { + this.cell = cell; + this.factory = factory; + this.cache = new HashMap(); + // Initialize the cache + for (Iterator i = KNOWN_VARIABLES.iterator(); i.hasNext(); ) { + cache.put(i.next(), null); + } + } + private MathExpression getVar(final String name) { + if (name.equals("prs")) { + final int count = PrsCount.count(cell, new HashMap(), false); + return factory.makeConstant(count); + } else { + throw new AssertionError("Trying to evaluate unknown attribute: " + name); + } + } + public MathExpression getVariableValue(final String name) { + if (!cache.containsKey(name)) return null; + MathExpression me = (MathExpression) cache.get(name); + if (me == null) { + me = getVar(name); + cache.put(name, me); + } + return me; + } + public VariableDictionaryIterator getIterator() { + final Iterator i = cache.entrySet().iterator(); + return new VariableDictionaryIterator() { + public Variable next() { + final Map.Entry entry = (Map.Entry) i.next(); + final String name = (String) entry.getKey(); + MathExpression val = (MathExpression) entry.getValue(); + if (val == null) { + val = getVar(name); + cache.put(name, val); + } + return new Variable() { + public String getName() { return name; } + public MathExpression getValue() { + return (MathExpression) entry.getValue(); + } + }; + } + public boolean hasNext() { + return i.hasNext(); + } + }; + } + } + + /** + * Given a String, parse it as a math expression, and return + * the associated MathExpression. Parsing exceptions are + * caught, and a RuntimeException will be rethrown with the + * original exception as the cause. + **/ + private static MathExpression getMathExpression(final String expr, + final MathExpressionFactory mf) { + final MathExpressionLexer lexer = + new MathExpressionLexer(new StringReader(expr)); + final MathExpressionParser parser = new MathExpressionParser(lexer, mf); + final MathExpression me; + try { + me = parser.goal(); + } catch (Exception e) { + throw new RuntimeException("Cannot parse expression: " + expr, e); + } + final String[] vars = me.getVariableNames(); + for (int i = 0; i < vars.length; ++i) { + if (!KNOWN_VARIABLES.contains(vars[i])) + throw new RuntimeException("Unknown attribute: " + vars[i]); + } + return me; + } + + /** + * Returns the appropriate predicate for relational operators. + **/ + private static UnaryPredicate getPredicate(final String expr1, + final String op, + final String expr2, + final Map dictCache, + final MathExpressionFactory mf) { + final BinaryPredicate bop = NumericPredicate.getPredicate(op); + final UnaryFunction val1 = + new MathFunction(dictCache, getMathExpression(expr1, mf), mf); + final UnaryFunction val2 = + new MathFunction(dictCache, getMathExpression(expr2, mf), mf); + return new UnaryPredicate() { + public boolean evaluate(final Object o) { + return bop.evaluate(val1.execute(o), val2.execute(o)); + } + }; + } + + private static class DirectivePredicateAction implements DirectiveActionInterface { + private final String dir; + private final String val; + private boolean status = false; + + private boolean equalValue(final String valType, final Object value) { + if (val == null) return true; + final Object myval = DirectiveUtils.parseDirective(valType, val); + if (myval == null) return false; + return ObjectUtils.equals(myval, value); + } + + public DirectivePredicateAction(final String dir, final String val) { + this.dir = dir; + this.val = val; + } + + public boolean getResult() { + return status; + } + + public void reset() { + status = false; + } + + public void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType ) + throws IOException { + if (directive.equals(dir) && equalValue(valueType, value)) + status = true; + } + + public void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) + throws IOException { + if (directive.equals(dir) && equalValue(valueType, value)) + status = true; + } + + public void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) + throws IOException { } + public void doBlockInterface(BlockInterface block) + throws IOException { } + } + + private static UnaryPredicate getDirectivePredicate(final String blocks, + final String dir, + final String val) { + final Set wantBlock = blocks == null ? + null + : new HashSet(Arrays.asList(StringUtil.split(blocks, ','))); + final DirectivePredicateAction action = + new DirectivePredicateAction(dir, val); + final DirectiveWalker walker = new DirectiveWalker(action); + return new UnaryPredicate() { + private boolean valid(final String block) { + return + (DirectiveTable.lookupDirective(block, dir) != null || + DirectiveTable.lookupParameterizedDirective(block, dir) + != null) && + (wantBlock == null || wantBlock.contains(block)); + } + private boolean walk(final BlockInterface bi, final String block) { + try { + if (valid(block)) { + if (block == BlockInterface.CELL) walker.walk(bi); + else walker.walk(bi, block); + } else { + return false; + } + } catch (IOException e) { + } catch (UnknownDirectiveException e) { + } + return action.getResult(); + } + public boolean evaluate(Object a) { + action.reset(); + final CellInterface x = (CellInterface) a; + final BlockInterface cellBlock = x.getBlockInterface(); + if (walk(cellBlock, BlockInterface.CELL) || + walk(cellBlock, BlockInterface.PRS) || + walk(cellBlock, BlockInterface.SUBCELL)) + return true; + + if (valid(BlockInterface.ENV)) { + final EnvBlock envBlock = x.getEnvironments(); + for (Iterator i = envBlock.getNames(); i.hasNext(); ) { + final String name = (String) i.next(); + final CellInterface ex; + try { + ex = envBlock.getNamedEnvironment(name); + } catch (CastSemanticException e) { + throw new RuntimeException( + "Unable to load environment: " + + x.getFullyQualifiedType() + ":" + name, e); + } + walk(ex.getBlockInterface(), BlockInterface.ENV); + if (action.getResult()) return true; + } + } + return false; + } + }; + } + + private static void getGrayboxList(final CellInterface cell, + final UnaryPredicate typeCheck, + final Set seen, + final Set includedSet) { + final String type = cell.getFullyQualifiedType(); + if (!seen.add(type)) return; + if (typeCheck.evaluate(cell) || CellUtils.isLeaf(cell)) { + includedSet.add(type); + return; + } + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + getGrayboxList(subcell, typeCheck, seen, includedSet); + } + } + + private static boolean isValidBlock(final String block) { + return block.equals(BlockInterface.CELL) || + block.equals(BlockInterface.PRS) || + block.equals(BlockInterface.SUBCELL) || + block.equals(BlockInterface.ENV); + } + + private static final String PARENT_PREFIX = "parent:"; + /** + * Returns the appropriate predicate given the name of the predicate. + **/ + private static UnaryPredicate getPredicate(final String test, + final String val, + final CastFileParser cfp, + final CellInterface cell) { + // if a test is prefixed with "parent:", then the test is applied to + // the refinement parent; this doesn't always make sense, e.g., + // "shared" or "one-level" predicates. + if (test.startsWith(PARENT_PREFIX)) { + final UnaryPredicate pred = + getPredicate(test.substring(PARENT_PREFIX.length()), val, + cfp, cell); + return new UnaryPredicate() { + public boolean evaluate(CellInterface x) { + final CellInterface parent = x.getDirectRefinementParent(); + if (parent == null) { + return false; + } else { + return pred.evaluate(parent); + } + } + }; + } + + if (predicateMap.containsKey(test)) { + return (UnaryPredicate) predicateMap.get(test); + } else if (test.equals("tau")) { + return getDirectivePredicate(null, DirectiveConstants.TAU, val); + } else if (test.equals("directive")) { + final String[] words = StringUtil.split(val, ':'); + final String blocks, dir, value; + if (words.length == 1) { + blocks = null; + dir = words[0]; + value = null; + } else if (words.length == 2) { + if (words[0].indexOf(',') > 0 || isValidBlock(words[0])) { + blocks = words[0]; + dir = words[1]; + value = null; + } else { + blocks = null; + dir = words[0]; + value = words[1]; + } + } else if (words.length == 3) { + blocks = words[0]; + dir = words[1]; + value = words[2]; + } else { + throw new RuntimeException("Invalid directive option specified: " + val); + } + return getDirectivePredicate(blocks, dir, value); + } else if (test.equals("shared")) { + return new UnaryPredicate() { + private Set sharedInstance = null; + public boolean evaluate(Object a) { + if (sharedInstance == null) { + final CellInterface shared; + try { + shared = cfp.getFullyQualifiedCell(val); + } catch (Exception e) { + throw new RuntimeException("Unable to load cell: " + val, e); + } + final Set skip = new HashSet(); + skip.add(cell.getFullyQualifiedType()); + sharedInstance = instanceSet(shared, skip); + } + final CellInterface x = (CellInterface) a; + return sharedInstance.contains(x.getFullyQualifiedType()); + } + }; + } else if (test.equals("env")) { + final boolean[] opt = { false, false, false, false }; + if (val != null) { + final String[] rest = StringUtil.split(val, ':'); + for (int i = 0; i < rest.length; ++i) { + if (rest[i].equals("prs")) opt[0] = true; + else if (rest[i].equals("rte_ignore")) opt[1] = true; + else if (rest[i].equals("ntpc_spec")) opt[2] = true; + else if (rest[i].equals("aspice_ignore")) opt[3] = true; + else throw new RuntimeException("Invalid env option specified: " + rest[i]); + } + } + return new UnaryPredicate() { + public boolean evaluate(Object a) { + final CellInterface x = (CellInterface) a; + return PrintEnv.getEnvs(x, opt[0], opt[1], + opt[2], opt[3]).size() > 0; + } + }; + } else if (test.equals("one-level")) { + final Set localSubcells = new HashSet(); + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + localSubcells.add(subcell.getFullyQualifiedType()); + } + return new UnaryPredicate() { + public boolean evaluate(Object a) { + final CellInterface x = (CellInterface) a; + return localSubcells.contains(x.getFullyQualifiedType()); + } + }; + } else if (test.equals("graybox-list")) { + if (val == null) { + throw new RuntimeException("Graybox list file not specified"); + } + + final Set grayBoxList = new HashSet(); + try { + final Pattern space = Pattern.compile("\\s+"); + final BufferedReader br = + new BufferedReader(new FileReader(val)); + String line; + int lineno = 0; + while ((line = br.readLine()) != null) { + ++lineno; + // remove all whitespace + final String cellName = space.matcher(line).replaceAll(""); + grayBoxList.add(cellName); + } + br.close(); + } catch (FileNotFoundException notFound) { + throw new RuntimeException("Graybox list file " + val + + " does not exist", notFound); + } catch (IOException ioError) { + throw new RuntimeException("Unable to read graybox list file " + + val, ioError); + } + + final UnaryPredicate typeCheck = + CellUtils.getTypeMatcher(grayBoxList); + + final Set includedSet = new HashSet(); + getGrayboxList(cell, typeCheck, new HashSet(), includedSet); + return new UnaryPredicate() { + public boolean evaluate(Object a) { + final CellInterface x = (CellInterface) a; + return includedSet.contains(x.getFullyQualifiedType()); + } + }; + } else if (test.equals("ancestor")) { + if (val == null) { + throw new RuntimeException("Ancestor not specified"); + } + return CellUtils.getTypeMatcher(Collections.singleton(val)); + } else if (test.equals("block")) { + if (val == null) { + throw new RuntimeException("Block not specified"); + } else if (val.equals("prs")) { + return new UnaryPredicate() { + public boolean evaluate(CellInterface ci) { + return ci.containsCompletePrs(); + } + }; + } else if (val.equals("subcells")) { + return new UnaryPredicate() { + public boolean evaluate(CellInterface ci) { + return ci.containsCompleteSubcells(); + } + }; + } else if (val.equals("csp")) { + return new UnaryPredicate() { + public boolean evaluate(CellInterface ci) { + return ci.containsRunnableCsp(); + } + }; + } else if (val.equals("verilog")) { + return new UnaryPredicate() { + public boolean evaluate(CellInterface ci) { + return ci.containsVerilog(); + } + }; + } else if (val.equals("netlist")) { + return new UnaryPredicate() { + public boolean evaluate(CellInterface ci) { + return ci.containsNetlist(); + } + }; + } else { + throw new RuntimeException( + "Invalid block " + val + " specified"); + } + } else { + throw new RuntimeException("Invalid predicate specified: " + test); + } + } + + private static ParamDirectiveValue getParamDirectiveValue(final String dir) { + final Triplet[] p = DirectiveTable.lookupParameterizedDirective(BlockInterface.CELL, dir); + if (p == null) { + System.err.println("Invalid directive: " + dir); + return null; + } else { + return new ParamDirectiveValue(dir, (String) p[0].getFirst()); + } + } + + private static DirectiveValue getDirectiveValue(final String dir) { + final Pair p = DirectiveTable.lookupDirective(BlockInterface.CELL, dir); + if (p == null) { + System.err.println("Invalid directive: " + dir); + return null; + } else { + return new DirectiveValue(dir, (String) p.getFirst()); + } + } + + private static String[] getArgs(final String name, final char sep) { + final int index = name.indexOf('='); + if (index > 0) { + final String[] rest = + StringUtil.split(name.substring(index + 1), sep); + return rest; + } else { + return new String[0]; + } + } + + private static TaskInterface getTaskInterface( + final String name, + final CastFileParser cfp, + final String cellName, + final UnaryPredicate selectionPredicate, + final UnaryPredicate prunePredicate, + final CDLNameInterface cellRenamer) { + if (name.equals("subcell_tree")) { + return new SubcellTree(); + } else if (name.equals("subcells")) { + return new HierNop(); + } else if (name.equals("tau")) { + return getDirectiveValue(DirectiveConstants.TAU); + } else if (name.equals("density")) { + return getDirectiveValue(DirectiveConstants.DENSITY_FACTOR); + } else if (name.startsWith("paramdirective")) { + final int index = name.indexOf('='); + if (index < 0) { + System.err.println("No directive specified"); + return null; + } else { + final String dir = name.substring(index + 1); + return getParamDirectiveValue(dir); + } + } else if (name.startsWith("directive")) { + final int index = name.indexOf('='); + if (index < 0) { + System.err.println("No directive specified"); + return null; + } else { + final String dir = name.substring(index + 1); + return getDirectiveValue(dir); + } + } else if (name.equals("instances")) { + return new InstanceCount(cellName, cfp); + } else if (name.startsWith("instance_list")) { + final int index = name.indexOf('='); + boolean verilog = false, skipWiring = false; + if (index > 0) { + final String[] rest = + StringUtil.split(name.substring(index + 1), ':'); + for (int i = 0; i < rest.length; ++i) { + if (rest[i].equals("verilog")) verilog = true; + else if (rest[i].equals("skip-wiring")) skipWiring = true; + } + } + return new InstanceList(cellName, cfp, verilog, skipWiring, + cellRenamer); + } else if (name.equals("prs")) { + return new PrsCount(false); + } else if (name.equals("prs=dnf")) { + return new PrsCount(true); + } else if (name.startsWith("transistors")) { + final int index; + final boolean detailed; + if (name.startsWith("transistors=detailed")) { + index = name.indexOf('=',name.indexOf('=') + 1); + detailed = true; + } else { + index = name.indexOf('='); + detailed = false; + } + final Set skip; + if (index < 0) { + skip = Collections.EMPTY_SET; + } else { + skip = new HashSet(); + final String skips = name.substring(index + 1); + final StringTokenizer tok = new StringTokenizer(skips, ":"); + while (tok.hasMoreTokens()) { + skip.add(tok.nextToken()); + } + } + return new TransistorStat(cfp, skip, detailed, + new UnaryPredicate.Not(prunePredicate)); + } else if (name.startsWith("dynamic_nodes")) { + final int index = name.indexOf('='); + boolean alias = false, leaky = false; + if (index > 0) { + final String[] rest = + StringUtil.split(name.substring(index + 1), ':'); + for (int i = 0; i < rest.length; ++i) { + if (rest[i].equals("alias")) alias = true; + else if (rest[i].equals("leaky")) leaky = true; + } + } + return new DynamicNodes(cfp, new Cadencize(true), alias, leaky); + } else if (name.startsWith("count_dynamic_nodes")) { + return new CountDynamicNodes(cfp); + } else if (name.startsWith("external_nodes")) { + boolean writeImplied = false; + boolean writeDirection = false; + boolean writeAliases = false; + boolean writeAllAliases = false; + boolean writeXref = false; + boolean writeRealOnly = false; + final int index = name.indexOf('='); + if (index > 0) { + final String s = name.toLowerCase(); + final String[] rest = + StringUtil.split(s.substring(index + 1), ':'); + for (int i = 0; i < rest.length; ++i) { + if (rest[i].startsWith("writeim")) + writeImplied = true; + else if (rest[i].startsWith("writedi")) + writeDirection = true; + else if (rest[i].startsWith("im")) + writeImplied = true; + else if (rest[i].startsWith("di")) + writeDirection = true; + else if (rest[i].startsWith("all")) + writeAllAliases = true; + else if (rest[i].startsWith("al")) + writeAliases = true; + else if (rest[i].startsWith("xr")) + writeXref = true; + else if (rest[i].startsWith("co")) + writeRealOnly = true; + else if (rest[i].startsWith("re")) + writeRealOnly = true; + } + } + return new ExternalNodes(writeImplied, writeDirection, writeAliases, + writeAllAliases, writeXref, writeRealOnly); + } else if (name.startsWith("local_nodes")) { + final int index = name.indexOf('='); + boolean alias = false, used = false, drivers = false, + EMReport = true, all_alias = false; + if (index > 0) { + final String[] rest = + StringUtil.split(name.substring(index + 1), ':'); + for (int i = 0; i < rest.length; ++i) { + if (rest[i].equals("alias")) alias = true; + else if (rest[i].equals("all_aliases")) all_alias = true; + else if (rest[i].equals("used")) used = true; + else if (rest[i].equals("drivers")) drivers = true; + } + } + return new LocalNodes(cfp, new Cadencize(true), alias, used, + drivers, EMReport, all_alias, false, null); + } else if (name.startsWith("routing")) { + return new RoutingComplexity(new Cadencize(false)); + } else if (name.startsWith("env")) { + boolean prs = false, rte_ignore = false, ntpc_spec = false; + boolean aspice_ignore = false; + final int index = name.indexOf('='); + if (index > 0) { + final String[] rest = + StringUtil.split(name.substring(index + 1), ':'); + for (int i = 0; i < rest.length; ++i) { + if (rest[i].equals("prs")) prs = true; + else if (rest[i].equals("rte_ignore")) rte_ignore = true; + else if (rest[i].equals("ntpc_spec")) ntpc_spec = true; + else if (rest[i].equals("aspice_ignore")) + aspice_ignore = true; + } + } + return new PrintEnv(prs, rte_ignore, ntpc_spec, aspice_ignore); + } else if (name.equals("refinement_lineage")) { + return new RefinementLineage(); + } else if (name.equals("em_spec")) { + return new EMSpec(cfp, new Cadencize(true)); + } else if (name.equals("railstat")) { + return new RailStats(new Cadencize(true)); + } else if (name.equals("attribute_list")) { + return new AttributeList(); + } else if (name.startsWith("canonical_name=") || + name.equals("canonical_name")) { + final int index = name.indexOf('='); + final Reader r; + Boolean doskill=false; + if (index < 0) { + r = new InputStreamReader(System.in); + } else { + final String filearg = name.substring(index + 1); + final int index2 = filearg.indexOf(':'); + final String file; + if (index2 >= 0) { + if(filearg.substring(index2+1).equals("skill")) { + doskill=true; + file=filearg.substring(0,index2); + } + else { + file=filearg; + } + } + else { + file = filearg; + } + try { + r = new FileReader(file); + } catch (FileNotFoundException e) { + System.err.println("Invalid file specified for " + + "canonical_name task: " + file); + return null; + } + } + return new CanonicalName(new Cadencize(true), r, cellRenamer, doskill); + } else if (name.startsWith("initial_floorplan=") || + name.equals("initial_floorplan")) { + final int index = name.indexOf('='); + final Pattern regex; + if (index < 0) { + regex = null; + } else { + final String re = name.substring(index + 1); + try { + regex = Pattern.compile(re); + } catch (PatternSyntaxException e) { + System.err.println("Invalid regular expression: " + re); + return null; + } + } + return new InitialFloorplan(cellRenamer, regex); + } else if (name.startsWith("enumerate_scan_chains")) { + final Object[] dft = new Object[] { + // custom scan chain + "lib.serial.scan.ABSTRACT_RESET_SCANBUF", "LS.D.e", "RS.D.e", + Boolean.FALSE, + "lib.serial.scan.RESET_SCANBUF_MIXED", "LS.D.e", "RS.D.e", + Boolean.FALSE, + "lib.buffer.voltage.RS_VCBUF_ChanDft", "L.D.e", "R.D.e", + Boolean.FALSE, + "lib.serial.scan.SCAN_RESET", "LS.D.e", "RS.D.e", + Boolean.TRUE, + "lib.serial.scan.SBUF_ChanDft", "L.D.e", "R.D.e", + Boolean.TRUE, + "lib.serial.scan.MBUF_ChanDft", "L.D.e", "R.D.e", + Boolean.TRUE, + "lib.serial.scan.RBUF_ChanDft", "L.D.e", "R.D.e", + Boolean.TRUE, + "lib.buffer.half.BUF_1of2", "L.e", "R.e", + Boolean.TRUE, + // proteus scan chain + "synthesis.qdi.special.SCAN_CONFIG", "LS.e", "RS.e", + Boolean.FALSE, + "synthesis.qdi.special.SCAN_CONFIG2", "LS.e", "RS.e", + Boolean.FALSE, + "synthesis.qdi.special.SCAN_BUF", "LS.e", "RS.e", + Boolean.FALSE, + "synthesis.qdi.special.SCAN_TOK_BUF", "LS.e", "RS.e", + Boolean.FALSE, + "synthesis.qdi.special.SCAN_TOK_EDFF", "LS.e", "RS.e", + Boolean.FALSE, + "synthesis.qdi.special.SCAN_EDFF", "LS.e", "RS.e", + Boolean.FALSE, + "synthesis.qdi.base.BUF_1of", "L.e", "R.e", + Boolean.TRUE, + "synthesis.qdi.special.INVINV", "a", "x", + Boolean.TRUE + }; + + final Object[] sram = new Object[] { + "lib.serial.interrupt.REPORT_INTERRUPT", "LINT.e", "RINT.e", + Boolean.FALSE, + "chip.alta.fc.ffu.util.FFU_REPORT_INTERRUPT", "LINT.e", "RINT.e", + Boolean.FALSE, + "lib.buffer.half.BUF_1of2", "L.e", "R.e", + Boolean.TRUE, + "synthesis.qdi.base.BUF_1of", "L.e", "R.e", + Boolean.TRUE, + "synthesis.qdi.special.INVINV", "a", "x", + Boolean.TRUE + }; + + final String[] args = getArgs(name, '\0'); + final Object[] scan; + if (args.length == 0) { + scan = dft; + } else if (args.length == 1) { + if (args[0].equals("dft")) { + scan = dft; + } else if (args[0].equals("sram")) { + scan = sram; + } else { + System.err.println("Invalid scan chain type: " + args[0]); + return null; + } + } else { + System.err.println("enumerate_scan_chains: Too many arguments"); + return null; + } + + return new EnumerateScanChain(scan, new Cadencize(true)); + } else if (name.startsWith("trace_connection")) { + final String[] cells = getArgs(name, ':'); + final Object[] scan = new Object[cells.length * 4]; + int index = 0; + for (String cell : cells) { + final String[] parts = StringUtil.split(cell, '|'); + if (parts.length == 4) { + scan[index++] = parts[0]; + scan[index++] = parts[1]; + scan[index++] = parts[2]; + scan[index++] = Boolean.valueOf(parts[3]); + } else { + System.err.println( + "Invalid specification: " + cell); + return null; + } + } + + return new EnumerateScanChain(scan, new Cadencize(true)); + } else if (name.equals("level")) { + return new HierarchyLevel(); + } else if (name.equals("ports") || name.equals("ports=primitive")) { + return new PortList(name.equals("ports=primitive")); + } else { + return null; + } + } + + private static String translateNode(final String node, + final CDLNameInterface renamer) { + if (renamer == null) { + return node; + } else { + try { + return renamer.renameNode(node); + } catch (CDLRenameException e) { + System.err.println("Cannot translate node: " + node); + return node; + } + } + } + + private static String translateCell(final String cell, + final CDLNameInterface renamer) { + if (renamer == null) { + return cell; + } else { + try { + return renamer.renameCell(cell); + } catch (CDLRenameException e) { + System.err.println("Cannot translate cell: " + cell); + return cell; + } + } + } + + private static String translateInstance(final String instance, + final CDLNameInterface renamer) { + if (renamer == null) { + return instance; + } else { + try { + return renamer.renameSubCellInstance(instance); + } catch (CDLRenameException e) { + System.err.println("Cannot translate instance: " + instance); + return instance; + } + } + } + + private interface Container { + Collection/**/ getChildren(); + } + private static void sortContainerByLevel(final Container top, + final Integer currentLevel, + final Map levels) { + final Integer maxLevel = (Integer) levels.get(top); + if (maxLevel == null || currentLevel.intValue() > maxLevel.intValue()) { + levels.put(top, currentLevel); + final Integer nextLevel = new Integer(currentLevel.intValue() + 1); + for (Iterator i = top.getChildren().iterator(); i.hasNext(); ) { + final Container child = (Container) i.next(); + sortContainerByLevel(child, nextLevel, levels); + } + } + } + private static MultiMap sortContainerByLevel( + final Container top, final MultiMap.CollectionFactory factory) { + final Map levels = new HashMap(); + sortContainerByLevel(top, new Integer(Integer.MIN_VALUE), levels); + final MultiMap byLevels = new MultiMap(new TreeMap(), factory); + for (Iterator i = levels.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + byLevels.put(entry.getValue(), entry.getKey()); + } + return byLevels; + } + private static class CellInterfaceContainer implements Container, + Comparable { + private final CellInterface cell; + private final UnaryPredicate filter; + private Collection children; + public CellInterfaceContainer( + final CellInterface cell, + final UnaryPredicate filter) { + this.cell = cell; + this.filter = filter; + this.children = null; + } + public Collection/**/ getChildren() { + if (children == null) { + final Map subcells = new HashMap(); + for (Iterator i = CellUtils.filterSubcellPairs(cell, filter); + i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + subcells.put(subcell.getFullyQualifiedType(), subcell); + } + children = new ArrayList(subcells.size()); + for (Iterator i = subcells.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + children.add(new CellInterfaceContainer( + (CellInterface) entry.getValue(), + filter)); + } + } + return children; + } + public boolean equals(final Object o) { + if (o instanceof CellInterfaceContainer) { + final CellInterfaceContainer other = (CellInterfaceContainer) o; + return cell.getFullyQualifiedType() + .equals(other.cell.getFullyQualifiedType()); + } else { + return false; + } + } + public int hashCode() { + return cell.getFullyQualifiedType().hashCode(); + } + public CellInterface getCellInterface() { + return cell; + } + public int compareTo(final Object o) { + final CellInterfaceContainer other = (CellInterfaceContainer) o; + return getCellInterface().getFullyQualifiedType().compareTo( + other.getCellInterface().getFullyQualifiedType()); + } + } + private static Iterator sortCellInterfaceByLevel( + final CellInterface top, + final UnaryPredicate filter) { + final MultiMap sorted = + sortContainerByLevel( + new CellInterfaceContainer(top, filter), + new MultiMap.CollectionFactory() { + public Collection newCollection() { + return new TreeSet(); + } + }); + return new MappingIterator(sorted.values().iterator(), + new UnaryFunction() { + public Object execute(Object o) { + return ((CellInterfaceContainer) o).getCellInterface(); + } + }); + } + + public static void query( final CellInterface rootCell, + final CastFileParser castParser, + final UnaryPredicate selectionPredicate, + final UnaryPredicate prunePredicate, + final List listOfTasks, + final CDLNameInterface renamer, + final boolean printHeader, + final boolean noRecurse, + final boolean instantiationOrder, + final String outputSeperator, + final Writer outputWriter ) + throws IOException { + + final Writer w = new BufferedWriter( outputWriter ) ; + final ArrayList flatTasks = new ArrayList(); + final ArrayList hierTasks = new ArrayList(); + final Iterator taskIter = listOfTasks.iterator(); + while ( taskIter.hasNext() ) { + final String name = ( String ) taskIter.next(); + final TaskInterface task = + getTaskInterface( name, + castParser, + rootCell.getFullyQualifiedType(), + selectionPredicate, + prunePredicate, + renamer ); + if (task == null) { + System.err.println("Ignoring unknown task: " + name); + } else { + if (task.isFlat()) { + ((FlatTask) task).printHeader = printHeader; + flatTasks.add(task); + } else { + hierTasks.add(task); + } + } + } + + // Exit if there are no valid tasks specified. + if (flatTasks.size() == 0 && hierTasks.size() == 0) return; + + // Do flat tasks + for (Iterator i = flatTasks.iterator(); i.hasNext(); ) { + final TaskInterface task = (TaskInterface) i.next(); + ((FlatTask) task).doTask( rootCell, w, noRecurse); + } + + if (hierTasks.size() > 0) { + // Generate the set of cells for hierarchical tasks to work on. If + // --no-recurse, only do the top-level cell. + final Map workMap; + if (noRecurse) { + workMap = new HashMap(); + if (selectionPredicate.evaluate(rootCell)) + workMap.put( rootCell.getFullyQualifiedType(), rootCell ); + } else { + + workMap = instantiationOrder ? (Map) new LinkedHashMap() + : (Map) new TreeMap(); + final UnaryPredicate unprune = + new UnaryPredicate.Not( prunePredicate ); + final Iterator cellIter = instantiationOrder ? + sortCellInterfaceByLevel( rootCell, unprune ) + : new ChildrenFirstCellInterfaceIterator( + rootCell, unprune ); + + while ( cellIter.hasNext() ) { + final CellInterface currCell = + (CellInterface) cellIter.next(); + + if ( ( ! CellUtils.isWiring( currCell ) ) && + ( selectionPredicate.evaluate(currCell) ) ) { + workMap.put( currCell.getFullyQualifiedType(), currCell ); + } + + } + + + } + + final Iterator workMapEntryIter = workMap.entrySet().iterator(); + + while ( workMapEntryIter.hasNext() ) { + final Map.Entry workMapEntry = + ( Map.Entry ) workMapEntryIter.next(); + + final CellInterface cell = + ( CellInterface ) workMapEntry.getValue(); + + w.write( translateCell( cell.getFullyQualifiedType(), + renamer ) ) ; + + for ( Iterator i = hierTasks.iterator(); i.hasNext(); ) { + w.write( outputSeperator ); + final TaskInterface task = ( TaskInterface ) i.next(); + task.doTask( cell, w); + } + w.write("\n"); + } + } + + w.flush(); + + } + + public static void query( final CastFileParser castParser, + final String cellName, + final String envName, + final String tasks, + final String filter, + final String prune, + final boolean noRecurse, + final String translatorName, + final boolean noHeader, + final boolean instantiationOrder, + final boolean routed, + final String separator, + final Writer output ) + throws CastSemanticException,RecognitionException, TokenStreamException, NoSuchEnvironmentException, IOException { + + final CellInterface cell = castParser.getFullyQualifiedCell( cellName ); + final CellInterface ci; + if (envName == null) { + ci = cell; + } else { + ci = cell.getEnvironment(envName); + } + + query( castParser, + routed ? ci.routedSubcells(true) : ci, + tasks, + filter, + prune, + noRecurse, + translatorName, + noHeader, + instantiationOrder, + separator, + output ); + } + + private static UnaryPredicate getPredicate(final CastFileParser castParser, + final CellInterface cell, + final String filter, + final boolean def) + throws CastSemanticException, RecognitionException, TokenStreamException, + IOException { + // Get the selection predicate, if --filter is specified, or set it to + // the true predicate + final UnaryPredicate selectionPredicate; + if ( filter.equals( "" ) ) { + selectionPredicate = new UnaryPredicate.Constant(def) ; + } else { + final CastQueryLexer cqLexer = + new CastQueryLexer( new StringReader( filter ) ); + final CastQueryParser cqParser = new CastQueryParser( cqLexer ); + final Map dictCache = new HashMap(); + final MathExpressionFactory mf = new MathExpressionFactoryImpl(); + selectionPredicate = + cqParser.goal( new CastQueryParser.QueryConstructor() { + public UnaryPredicate getClause( final String test, + final String op, + final String arg ) { + return op == null || op.equals("=") ? + getPredicate(test, arg, castParser, cell) : + getPredicate(test, op, arg, dictCache, mf); + } + } ); + } + return selectionPredicate; + } + + public static void query( final CastFileParser castParser, + final CellInterface cell, + final String tasks, + final String filter, + final String prune, + final boolean noRecurse, + final String translatorName, + final boolean noHeader, + final boolean instantiationOrder, + final String separator, + final Writer output ) + throws CastSemanticException, RecognitionException, TokenStreamException, + IOException { + // Get the selection predicate, if --filter is specified, or set it to + // the true predicate + final UnaryPredicate selectionPredicate = + getPredicate(castParser, cell, filter, true); + final UnaryPredicate prunePredicate = + getPredicate(castParser, cell, prune, false); + + // Get the list of tasks, and make sure they are valid. + final StringTokenizer tokenizer = new StringTokenizer( tasks, "," ); + final List tasksList = new LinkedList(); + + while ( tokenizer.hasMoreTokens() ) { + final String name = tokenizer.nextToken(); + tasksList.add( name ); + } + + // Get the optional renamer. + CDLNameInterface renamer; + if ( translatorName.equals("") ) { + renamer = null; + } else { + renamer = getRenamer( translatorName ); + } + + query( cell, + castParser, + selectionPredicate, + prunePredicate, + tasksList, + renamer, + ! noHeader, + noRecurse, + instantiationOrder, + separator, + output ); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellEnvName = theArgs.getArgValue("cell", null); + final String expr = theArgs.getArgValue("filter", ""); + final String prune = theArgs.getArgValue("prune", ""); + final String taskNames = theArgs.getArgValue("task", null); + final boolean noRecurse = theArgs.argExists("no-recurse"); + final boolean printHeader = !theArgs.argExists("no-header"); + final String output = theArgs.getArgValue("output", null); + final boolean routed = theArgs.argExists("routed"); + final String hierSep; + if ( theArgs.argExists("seperator")) + hierSep = theArgs.getArgValue("seperator", " "); + else + hierSep = theArgs.getArgValue("separator", " "); + final String translateScheme = theArgs.getArgValue("translate", ""); + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + CastQuery.class)); + } + + if (cellEnvName == null) { + //System.err.println("ERROR: You must specify a cell name."); + usage("ERROR: You must specify a cell name.\n"); + } else if (taskNames == null) { + //System.err.println("ERROR: You must specify tasks to perform."); + usage("ERROR: You must specify tasks to perform.\n"); + } + + final CastFileParser castParser = + CastCacheManager.getDefault().getCastFileParser( + new FileSearchPath(castRoot), castVersion, + new StandardParsingOption(theArgs) ); + + // cover future arg loading + pedanticArgs.argTag( "cadence-name" ); + pedanticArgs.argTag( "instantiation-order" ); + + if ( ! pedanticArgs.pedanticOK( false, true ) ) + usage( pedanticArgs.pedanticString() ); + + final Writer w = output == null ? + new OutputStreamWriter(System.out) : + new FileWriter(output); + + final int colon = cellEnvName.indexOf(':'); + final String cellName; + final String envName; + if (colon == -1) { + cellName = cellEnvName; + envName = null; + } else { + cellName = cellEnvName.substring(0, colon); + envName = cellEnvName.substring(colon + 1); + } + + final String realName; + if (theArgs.argExists("cadence-name")) { + final CadenceReverseNameInterface crni = + new CadenceReverseNameInterface(); + // Should envName also be renamed? The environment name never + // appears in a Cadence context. It's inconsistent, but likely + // more conveninent to not. + realName = crni.renameCell(cellName); + } else { + realName = cellName; + } + + final boolean instantiationOrder = + theArgs.argExists("instantiation-order"); + + try { + query( castParser, + realName, + envName, + taskNames, + expr, + prune, + noRecurse, + translateScheme, + ! printHeader, + instantiationOrder, + routed, + hierSep, + w ); + } catch (CastSemanticException e) { + ExceptionPrettyPrinter.printException(e, System.err); + System.exit(1); + } catch (NoSuchEnvironmentException e) { + System.err.println("Environment " + e.getEnvironmentName() + + " not found in cell " + e.getCellName()); + System.exit(1); + } catch (CastQuery.RuntimeException e) { + if (e.getMessage() != null) System.err.println(e.getMessage()); + final Throwable c = e.getCause(); + if (c instanceof CastSemanticException) { + ExceptionPrettyPrinter.printException((CastSemanticException)c, + System.err); + } + System.exit(1); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastStat.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastStat.java new file mode 100644 index 0000000000..860e540cd7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CastStat.java @@ -0,0 +1,319 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.io.FileSearchPath; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryFunction; + +/** + * A class that brings together miscellanous statistics tasks + * @author Harry Liu + * @version $Revision$ $DateTime$ + **/ +public class CastStat { + /** + * This class should not be instantiated. + **/ + private CastStat() { } + + private static final HierName Vdd = HierName.makeHierName("Vdd"); + private static final HierName GND = HierName.makeHierName("GND"); + public static void usage() { + System.out.println("java com.avlsi.tools.jauto.CastStat \n" + + " --cast-path= (defaults to .)\n" + + " --cast-version=[1 | 2] (defaults to 2)\n" + + " --cell= (fully qualified cell name)\n"); + System.exit(1); + } + + public static void getDynamicNodes(final CellInterface cell, + final CastFileParser cfp, + final Cadencize cad, + final Set result) { + final CadenceInfo cinfo = cad.convert(cell); + final ExclusiveNodeSets exclusives = new ExclusiveNodeSets(); + exclusives.merge(cinfo.getPortExclusiveNodeSets()); + exclusives.merge(cinfo.getLocalExclusiveNodeSets()); + final NetGraph graph = new NetGraph(cinfo.getLocalNodes(), + exclusives, + new ArrayList(), + Vdd, + GND, + Collections.EMPTY_SET); + try { + graph.addCellInterface(cell, new NetGraph[0], cfp, cad); + } catch (UnimplementableProductionRuleException e) { + System.err.println("Unimplementable production rules found in " + cell.getFullyQualifiedType()); + } + graph.prepareForLvs(); + for (Iterator i = graph.getNodes().iterator(); i.hasNext(); ) { + final NetGraph.NetNode node = (NetGraph.NetNode) i.next(); + if (node.isNamed() && node.isOutput() && !node.isCombinational()) { + result.add(node.name); + } + } + } + + private static void getDynamicNodes(final CellInterface cell, + final CastFileParser cfp, + final Cadencize cad, + final Map result) { + final String type = cell.getFullyQualifiedType(); + final Set s = new TreeSet(); + if (CellUtils.isLeaf(cell)) { + getDynamicNodes(cell, cfp, cad, s); + } else { + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName name = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (CellUtils.isWiring(subcell)) continue; + final String subtype = subcell.getFullyQualifiedType(); + if (!result.containsKey(subtype)) { + getDynamicNodes(subcell, cfp, cad, result); + } + final Set ss = (Set) result.get(subtype); + Debug.assertTrue(ss != null); + for (Iterator j = ss.iterator(); j.hasNext(); ) { + final HierName h = (HierName) j.next(); + s.add(HierName.prefixName(name, h)); + } + } + } + result.put(type, s); + } + + public static Set getDynamicNodes(final CellInterface cell, + final CastFileParser cfp, + final Cadencize cad) { + final Map result = new HashMap(); + getDynamicNodes(cell, cfp, cad, result); + return (Set) result.get(cell.getFullyQualifiedType()); + } + + /** + * Returns a set of all dynamic nodes in the specified cell. A + * NetGraph is generated for the given cell, and it returns + * all named output nodes that are not combinatorial. + * @param cell Cell to get information for. + **/ + public static Iterator getDynamicNodes(final CellInterface cell, + final CastFileParser cfp) { + final Map cache = new TreeMap(); + final Cadencize cad = new Cadencize(true); + getDynamicNodes(cell, cfp, cad, cache); + final Set names = (Set) cache.get(cell.getFullyQualifiedType()); + + final CellInterface flat = cell.flatten(); + final Iterator nameIter = names.iterator(); + return new Iterator() { + public boolean hasNext() { + return nameIter.hasNext(); + } + public Object next() { + final HierName name = (HierName) nameIter.next(); + HierName canon = flat.getCanonicalName(name); + Iterator aliases; + + // XXX: Work-around for bug 211. Blame Jesse. + if (canon == null) { + final String suffix = name.getSuffixString(); + final HierName prefix = name.getParent(); + final int index = suffix.lastIndexOf('['); + final String base = suffix.substring(0, index); + final String array = suffix.substring(index); + final HierName fake; + try { + fake = HierName.makeHierName(prefix, base); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName: " + e); + } + canon = flat.getCanonicalName(fake).appendString(array); + aliases = new MappingIterator( + flat.getConnectedNodes(fake), + new UnaryFunction() { + public Object execute(Object o) { + final HierName h = (HierName) o; + return h.appendString(array); + } + }); + } else { + aliases = flat.getConnectedNodes(canon); + } + return new Pair(canon, aliases); + } + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cell", null); + if (cellName == null) { + System.err.println("ERROR: You must specify a cell name"); + usage(); + } + final CastFileParser cfp = new CastFileParser(new FileSearchPath(castRoot), castVersion); + final CellInterface ci = cfp.getFullyQualifiedCell(cellName); + for (Iterator i = getDynamicNodes(ci, cfp); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + System.out.println(p.getFirst()); + } + } + + public static Set getDynamicPortNodes(final CellInterface cell, + final Cadencize mCadencizer, + final CastFileParser mCastParser, + final Map mDynamicPortNodesMap, + final Map mDynamicNodesMap) + throws InvalidHierNameException { + + final Set existingResult = + ( Set ) mDynamicPortNodesMap.get( cell.getFullyQualifiedType() ); + + if ( existingResult == null ) { + + final CadenceInfo cadenceInfo = mCadencizer.convert( cell ); + + final AliasedMap portMap = cadenceInfo.getPortNodes(); + + final Set dynamicNodesInCell = + getDynamicNodes( cell, mCadencizer, mCastParser, + mDynamicPortNodesMap, mDynamicNodesMap ); + + final Iterator nodeIter = dynamicNodesInCell.iterator(); + + final Set result = new HashSet(); + + while ( nodeIter.hasNext() ) { + final String nodeName = ( String ) nodeIter.next(); + if ( portMap.getValue( HierName.makeHierName( nodeName, '.' ) ) != null ) { + result.add( nodeName ); + } + } + + mDynamicPortNodesMap.put( cell.getFullyQualifiedType(), result ); + return result; + } + else { + return existingResult; + } + } + + public static Set getDynamicNodes(final CellInterface cell, + final Cadencize mCadencizer, + final CastFileParser mCastParser, + final Map mDynamicPortNodesMap, + final Map mDynamicNodesMap) + throws InvalidHierNameException { + + final Set existingResult = + ( Set ) mDynamicNodesMap.get( cell.getFullyQualifiedType() ); + + if ( existingResult == null ) { + + final Set result = new HashSet(); + + if (CellUtils.isLeaf(cell)) { + final Set hierNameSet = new HashSet(); + CastStat.getDynamicNodes( cell, + mCastParser, + mCadencizer, + hierNameSet ); + final Iterator currHierName = hierNameSet.iterator(); + while ( currHierName.hasNext() ) { + final HierName curr = ( HierName )currHierName.next(); + result.add( curr.toString() ); + } + } + else { + final CadenceInfo cadenceInfo = mCadencizer.convert( cell ); + + final Iterator subcellPairIter = cadenceInfo.getSubcellPairIterator(); + + while ( subcellPairIter.hasNext() ) { + final Pair subcellPair = ( Pair ) subcellPairIter.next(); + + final HierName instanceName = ( HierName ) subcellPair.getFirst(); + final CellInterface subcellMaster = cell.getSubcell( instanceName ); + + final Set subcellDynamicPortNodes = + getDynamicPortNodes( subcellMaster, mCadencizer, + mCastParser, mDynamicPortNodesMap, + mDynamicNodesMap ); + + + final Iterator dynNodeIter = subcellDynamicPortNodes.iterator(); + + while ( dynNodeIter.hasNext() ) { + final String dynNodeName = ( String ) dynNodeIter.next(); + + final HierName dynNodeHierName = + HierName.append( instanceName, + HierName.makeHierName( dynNodeName, '.' ) ); + + final HierName canonicalDynNodeName = + ( HierName ) cadenceInfo.getLocalNodes().getCanonicalKey( dynNodeHierName ); + + result.add( canonicalDynNodeName.toString() ); + } + } + + } + mDynamicNodesMap.put( cell.getFullyQualifiedType(), result ); + return result; + } + else { + return existingResult ; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CatPath.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CatPath.java new file mode 100644 index 0000000000..74c07584c1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CatPath.java @@ -0,0 +1,1556 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import com.avlsi.fast.HalfOperator; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.tools.lvs.NetGraph; + +import java.util.Set; +import java.util.HashSet; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.LinkedHashSet; +import java.util.ArrayList; +import java.util.Iterator; +import java.io.*; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.util.container.CollectionUtils; + +public class CatPath extends AbstractPath +{ + // list of SizingPath + List/**/ path; + + + /** Return the list of sizing paths */ + public List/**/ getCatPath() + { + return path; + } + + + /** Constructor 1 */ + public CatPath() + { + path = new ArrayList/**/(); + startNets = new HashSet/**/(); + + container = null; + + isFragment = false; + isReduced = false; + isEndNetNonObservable = false; + + delay = null; + slack = null; + criticalNet = null; + } + + + /** Constructor 2 */ + public CatPath(CatPath cp1) + { + path = new ArrayList/**/(cp1.path); + container = cp1.container; + + startNets = new HashSet/**/(cp1.startNets); + endNet = cp1.endNet; + + isFragment = cp1.isFragment; + isReduced = cp1.isReduced; + isEndNetNonObservable = cp1.isEndNetNonObservable; + + delay = cp1.delay; + slack = cp1.slack; + criticalNet = cp1.criticalNet; + } + + + /** + * Generate concatenated paths for all cells in CellType. + * Generated cat paths will be added to + * cell.getCatPaths() for each cell in + * cellTypes. + * XXX: Need better documentation. + * + * @param cellTypes + * Set of cells for which cat paths should be generated. + * @param ignoreReset + * Currently ignored. At one time it specified whether + * cat paths starting with a reset node would be ignored. + * @param completeCatPath + * XXX: Document. Purpose unknown. + * @param disableImmediateReduction + * If false, allows the immediate reduction of concatenated paths if + * a cell is fully observable. If true, disables the immediate + * reduction. + **/ + public static void generateCatPaths(Set/**/ cellTypes, + boolean ignoreReset, + boolean completeCatPath, + boolean disableImmediateReduction) + { + List/**/ cellTypesWorkList + = new ArrayList/**/(); + + // Sort cell types by their level numbers from low to high, leaf-cells are excluded + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + if(DebugOption.printLevel <= 3){ + System.out.println("Concatenated path generation - sort celltypes"); + System.out.println(cella.toString()); + } + + + if(cella.getLevel() > 0){ + sortedInsert(cellTypesWorkList, cella); + } + + } + + + // Generate concatenated paths for cell types + + + /* + // Pop up sizing paths for all the cells first + for (Iterator ita = cellTypesWorkList.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + if(DebugOption.printLevel <= 3){ + System.out.println("Concatenated path generation - paths popup"); + System.out.println(cella.toString()); + } + + popUpPaths(cella); + } + */ + + + // Recursively generate concatenated paths for all the cells + for (Iterator ita = cellTypesWorkList.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + // Pop up sizing paths for all the cells first + popUpPaths(cella); + if(DebugOption.printLevel <= 3){ + System.out.println("********************************************************************"); + System.out.println("Processing cell type: "); + //System.out.println(cella.toString()); + System.out.println("Number of paths popped up: " + + cella.getSizingPaths().size()); + System.out.println("********************************************************************"); + } + + // get connectivity from cell net to sizing path + Map/*>*/ startNetToCatPathsMap = + new HashMap/*>*/(); + + for (Iterator itb = cella.getSizingPaths().iterator(); itb.hasNext(); ) { + CatPath cpa = (CatPath)itb.next(); + + if(!cpa.isFragment()){ + for (Iterator itc = + CollectionUtils.sort(CellNet.getComparator(), + cpa.getStartNets().iterator()); + itc.hasNext(); ) { + CellNet startNet = (CellNet)itc.next(); + + Set/**/ catPathsForStartNet = + (Set) startNetToCatPathsMap.get(startNet); + if (catPathsForStartNet == null) { + catPathsForStartNet = + new LinkedHashSet/**/(); + startNetToCatPathsMap.put(startNet, + catPathsForStartNet); + } + catPathsForStartNet.add(cpa); + } + } + } + + // get all non-observable end nets + Set/**/ nonObservableEndNets = + new LinkedHashSet/**/(); + for (Iterator itb = cella.getSizingPaths().iterator(); itb.hasNext(); ) { + CatPath cpa = (CatPath)itb.next(); + + if(cpa.isEndNetNonObservable){ + CellNet endNet = cpa.getEndNet(); + if (!endNet.isCutPath()) { + nonObservableEndNets.add(endNet); + + if(DebugOption.printLevel <= 1){ + System.out.println("Non-observable end net added: " + + cpa.getEndNet().canonicalName.getCadenceString()); + } + } + } + } + + + // get all starting sizing path + // Set/**/ sizingPathsCopy = + // new HashSet/**/(cella.getSizingPaths()); + + Set/**/ startingCatPaths = new LinkedHashSet/**/(); + Set/**/ setf = new HashSet/**/(); + for (Iterator itb = cella.getSizingPaths().iterator(); itb.hasNext(); ) { + CatPath cpa = (CatPath)itb.next(); + + if(!cpa.isFragment()){ + + if(DebugOption.printLevel <= 1){ + System.out.println("Concatenated path is not fragment."); + } + + if(cpa.isReduced || cpa.getStartNets().isEmpty()){ + + if(DebugOption.printLevel <= 1){ + System.out.println("Concatenated path added to start cat path. 1"); + } + + startingCatPaths.add(cpa); + } + else{ + // int numStartNets = cpa.getStartNets().size(); + for (Iterator itc = + CollectionUtils.sort( + CellNet.getComparator(), + cpa.getStartNets().iterator()); + itc.hasNext(); ) { + CellNet startNet = (CellNet)itc.next(); + + if(DebugOption.printLevel <= 1){ + System.out.println("Got starting net: "); + System.out.println(startNet.canonicalName.getCadenceString()); + } + + if(startNet.isPortNet()){ + /* + if(ignoreReset){ + if (startNet.isReset() && + numStartNets > 1) { + continue; + } + } + */ + + if (startNet.portDirection == CellNet.INPUT) { + + if(DebugOption.printLevel <= 1){ + System.out.println("Concatenated path added to start cat path. 2"); + } + + startingCatPaths.add(cpa); + break; + } + + if (startNet.portDirection == CellNet.INPUTOUTPUT) { + + if(DebugOption.printLevel <= 1){ + System.out.println("Concatenated path added to start cat path. 3"); + } + + startingCatPaths.add(cpa); + break; + } + } + else{ + if(!nonObservableEndNets.contains(startNet)){ + + if(DebugOption.printLevel <= 1){ + System.out.println("Concatenated path added to start cat path. 4"); + } + + startingCatPaths.add(cpa); + break; + } + } + } + + + + /* + boolean drivenFromSameInstance = true; + + for (Iterator itc = cpa.getStartNets().iterator(); itc.hasNext(); ) { + CellNet startNet = (CellNet)itc.next(); + + // XXX: SizingPaths or CatPaths? + for (Iterator ite = sizingPathsCopy.iterator(); + ite.hasNext(); ) { + CatPath cpb = (CatPath)ite.next(); + + if(cpb.instanceContainer != cpa.instanceContainer){ + if(cpb.endNet == startNet){ + drivenFromSameInstance = false; + break; + } + } + } + + if(!drivenFromSameInstance){ + break; + } + } + + if(drivenFromSameInstance){ + if(DebugOption.printLevel <= 3){ + System.out.println("Concatenated path added to start cat path. 5"); + System.out.println("Name of end net: " + cpa.getEndNet().canonicalName.getCadenceString()); + } + + startingCatPaths.add(cpa); + setf.add(cpa); + } + */ + + + + } + } + + } + + + Set/**/ sete; + if(completeCatPath){ + //if(!cella.isFragment()){ + // sete = new HashSet/**/(startingCatPaths); + //} + //else{ + sete = new HashSet/**/(setf); + //} + } + else{ + sete = new HashSet/**/(startingCatPaths); + } + + boolean reduceNow = !disableImmediateReduction && + !cella.hasNonObservablePorts(); + if(DebugOption.printLevel <= 3){ + System.out.println("Direct paths reduction for:" + cella.typeName + " : " + reduceNow); + } + + long[] numCatPaths = {0}; + + Set/**/ allCatPaths = new LinkedHashSet/**/(); + + for (Iterator itb = startingCatPaths.iterator(); + itb.hasNext(); ) { + CatPath cpa = (CatPath)itb.next(); + + recursiveCatPaths(cpa, new ArrayList/**/(), + allCatPaths, sete, startNetToCatPathsMap, + reduceNow, numCatPaths, cella); + } + + + for (Iterator itc = allCatPaths.iterator(); itc.hasNext(); ) { + CatPath cpa = (CatPath)itc.next(); + cpa.setStartEndNets(completeCatPath); + } + + + cella.getCatPaths().addAll(allCatPaths); + + if(DebugOption.printLevel <= 3){ + System.out.println("\n**************** " + cella.typeName + " **************"); + System.out.println("Total number of original concatenated paths: " + + allCatPaths.size()); + System.out.println("**********************************************************"); + } + + + } + + } + + + /** + * Recursively join cat paths together. + * Every possible sequence of cat paths starting with + * nextCatPath and using cat paths from + * startNetToCatPathsMap is constructed subject to the + * constraint that the i-th cat path's end net is the + * same as the i + 1-th cat paths's start net and + * the last half-operator of the i-th cat path has the + * opposite direction as the first half-operator of the + * i + 1-th cat path. Further, no cat path may appear + * more than once in the sequence (concatenation is stopped when + * this happens). Reaching a port net, cut path net, observable + * net, or cat path in set2 also stops the sequence. + * Each of these sequence of cat paths is flattened into a single + * cat paths and added to allCatPaths. + * numCatPaths is incremented for each cat path added + * (even if reduced), and a debug message is possibly printed. + * + * + * + * @param nextCatPath + * The cat path to be concatenated onto + * catPathsToBeCatted. + * @param catPathsToBeCatted + * A list of cat paths that represents the cat path that is being + * concatenated together. nextCatPath will be + * added to the end of this list and when the cat path is ready + * to be terminated, this List<CatPath> will + * be flattened into a single CatPath. + * @param allCatPaths + * All cat paths for the cell. New cat paths will be added + * to this list. + * @param set2 + * TODO: Document! Purpose unknown! + * Not modified by this method. + * @param startNetToCatPathsMap + * Map from starting net of the cat paths in the cell to the + * cat paths themselves. Not modified by this method. + * @param reduceNow + * Specifies whether added cat paths should be immediately + * reduced by {@link #addCatPath}. + * @param numCatPaths + * Array used as a reference that is incremented each time a + * cat path is added to allCatPaths. + * Incremented even if reduceNow is used. + * @param ct1 + * The cell type for which the cat paths are generated. + * The only use of this is a use of the typeName + * member in debugging printouts. + **/ + private static void recursiveCatPaths(CatPath nextCatPath, + List/**/ + catPathsToBeCatted, + Set/**/ allCatPaths, + Set/**/ set2, + Map/*>*/ + startNetToCatPathsMap, + boolean reduceNow, + long[] numCatPaths, + CellType ct1) + { + // I believe the following assertion is true because of the check + // newCatPathsToBeCatted.contains(potentialNewNextCatPath) when + // we are adding to newNextCatPaths. --jmr + // If these assertions are indeed true, where is the best place + // to handle this, here or before the recursion? + assert !catPathsToBeCatted.contains(nextCatPath); + assert !set2.contains(nextCatPath); + + if (catPathsToBeCatted.contains(nextCatPath) || + (set2.contains(nextCatPath) && !catPathsToBeCatted.isEmpty())) { + CatPath cpa = joinCatPaths(catPathsToBeCatted); + addCatPath(allCatPaths, cpa, reduceNow); + + numCatPaths[0]++; + debugOutput(catPathsToBeCatted, allCatPaths, cpa, + numCatPaths, ct1); + + return; + } + + List/**/ newCatPathsToBeCatted = + new ArrayList/**/(catPathsToBeCatted.size() + 1); + newCatPathsToBeCatted.addAll(catPathsToBeCatted); + newCatPathsToBeCatted.add(nextCatPath); + + CellNet endNet = nextCatPath.getEndNet(); + + if (endNet.isPortNet() || endNet.isCutPath() || + !nextCatPath.isEndNetNonObservable) { + CatPath cpa = joinCatPaths(newCatPathsToBeCatted); + addCatPath(allCatPaths, cpa, reduceNow); + + numCatPaths[0]++; + debugOutput(catPathsToBeCatted, allCatPaths, cpa, + numCatPaths, ct1); + + return; + } + + final Set/**/ catPathsStartedByEndNet = + (Set) startNetToCatPathsMap.get(endNet); + if (catPathsStartedByEndNet != null) { + boolean isCut = false; + Set/**/ newNextCatPaths = new LinkedHashSet/**/(); + for (Iterator ita = catPathsStartedByEndNet.iterator(); + ita.hasNext(); ) { + CatPath potentialNewNextCatPath = (CatPath)ita.next(); + + boolean visited = false; + /* + for (Iterator itb = newCatPathsToBeCatted.iterator(); + itb.hasNext(); ) { + CatPath cpb = (CatPath)itb.next(); + + if (potentialNewNextCatPath.instanceContainer == + cpb.instanceContainer){ + visited = true; + break; + } + } + */ + + if (newCatPathsToBeCatted.contains(potentialNewNextCatPath) || + set2.contains(potentialNewNextCatPath) || visited) { + isCut = true; + } + else{ + List/**/ sizingPaths = nextCatPath.getCatPath(); + + // last half operator of last sizing path of nextCatPath + SizingPath spa = + (SizingPath) sizingPaths.get(sizingPaths.size() - 1); + HalfOperator hoa = (HalfOperator) spa.getPath().get(spa.getPath().size() - 1); + + // first half operator of first sizing path of + // potentialNewNextCatPath + SizingPath spb = + (SizingPath) potentialNewNextCatPath + .getCatPath().get(0); + HalfOperator hob = (HalfOperator)spb.getPath().get(0); + + if (hoa.driveDirection != hob.driveDirection) + newNextCatPaths.add(potentialNewNextCatPath); + } + } + + if (newNextCatPaths.isEmpty() || isCut) { + CatPath cpa = joinCatPaths(newCatPathsToBeCatted); + addCatPath(allCatPaths, cpa, reduceNow); + + numCatPaths[0]++; + debugOutput(catPathsToBeCatted, allCatPaths, cpa, + numCatPaths, ct1); + } + + for (Iterator ita = newNextCatPaths.iterator(); + ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + + recursiveCatPaths(cpa, newCatPathsToBeCatted, allCatPaths, + set2, startNetToCatPathsMap, reduceNow, + numCatPaths, ct1); + } + } + else{ + CatPath cpa = joinCatPaths(newCatPathsToBeCatted); + addCatPath(allCatPaths, cpa, reduceNow); + + numCatPaths[0]++; + debugOutput(catPathsToBeCatted, allCatPaths, cpa, + numCatPaths, ct1); + } + } + + + /** + * Pops up sizing paths or cat paths with non-observable start or end nodes + * from children of cell1 to cell1. + * XXX: need better documentation + * + * @param cell1 + * Cell into which child paths will be popped up. + **/ + private static void popUpPaths(CellType cell1) + { + for (Iterator ita = + CollectionUtils.sort(ConnectionInfo.getComparator(), + cell1.getAllInstances().iterator()); + ita.hasNext(); ) { + ConnectionInfo cia = (ConnectionInfo)ita.next(); + + if(DebugOption.printLevel <= 1){ + System.out.println("\nGot instance: "); + System.out.println(cia.toString()); + } + + CellType childCell = cia.child; + Set/**/ paths; + if (childCell.getLevel() == 0) + paths = childCell.getSizingPaths(); + else + paths = childCell.getCatPaths(); + + for (Iterator itb = paths.iterator(); itb.hasNext(); ) { + AbstractPath path = (AbstractPath) itb.next(); + + Set/**/ nonObservableStartNets = + new HashSet/**/(); + boolean hasNonObservable = false; + boolean hasObservable = false; + + for (Iterator itc = path.getStartNets().iterator(); itc.hasNext(); ) { + CellNet startNet = (CellNet)itc.next(); + + if (startNet.isObservable()) { + if(DebugOption.printLevel <= 1){ + System.out.println("\nObservable starting net found: "); + System.out.println(startNet.canonicalName.getCadenceString()); + } + + hasObservable = true; + } else { + hasNonObservable = true; + + nonObservableStartNets + .addAll(cia.getParentNet(startNet)); + + if(DebugOption.printLevel <= 1){ + System.out.println("\nNon-observable starting net found: "); + System.out.println(startNet.canonicalName.getCadenceString()); + // System.out.println(nonObservableStartNets.toString()); + } + + } + } + + CellNet childEndNet = path.getEndNet(); + Set/**/ parentNets = + cia.getParentNet(childEndNet); + + assert parentNets.size() <= 1 + : "Output (or In/Out) port connected to more than 1 nets" + + childEndNet.canonicalName.getCadenceString(); + + CellNet endNet; + if (parentNets.size() > 0) + endNet = (CellNet) parentNets.iterator().next(); + else + endNet = childEndNet; + + final boolean isEndNonObservable = + !childEndNet.isObservable(); + + if (DebugOption.printLevel <= 1) { + if (isEndNonObservable) { + System.out.println("\nNon-observable ending net found: "); + System.out.println(childEndNet.canonicalName.getCadenceString()); + System.out.println(endNet.canonicalName.getCadenceString()); + } else { + System.out.println("\nObservable ending net found: "); + System.out.println(childEndNet.canonicalName.getCadenceString()); + } + } + + if(hasNonObservable || isEndNonObservable){ // there are non-observable net(s) + + CatPath cpa = path.popUp(isEndNonObservable, + hasObservable, + nonObservableStartNets, + endNet); + for (Iterator k = cpa.getCatPath().iterator(); + k.hasNext(); ) { + final SizingPath sp = (SizingPath) k.next(); + sp.prefixInstanceName(cia.nameInParent); + } + + // XXX: Why is a CatPath being added to + // getSizingPaths(), which is supposed to be + // a Set? + cell1.getSizingPaths().add(cpa); + + } + + } + + } + + } + + + public void setStartEndNets(boolean completeCatPath) + { + int numSizingPaths = path.size(); + + if (numSizingPaths > 0) { + endNet = + ((SizingPath) path.get(numSizingPaths - 1)).getEndNet(); + + startNets.clear(); + for (Iterator ita = ((SizingPath) path.get(0)).getStartNets().iterator(); ita.hasNext(); ) { + CellNet startNet = (CellNet)ita.next(); + + if(completeCatPath){ + if(startNet.container.isFragment()){ // only add port net for fragment cells + if(startNet.isPortNet()){ + startNets.add(startNet); + } + } + else{ + startNets.add(startNet); + } + } + else{ + startNets.add(startNet); + } + } + + container = endNet.container; + } + } + + + + public String toString() + { + StringBuffer sb = new StringBuffer(); + + for (Iterator ita = path.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + sb.append(spa.container.typeName + ": "); + sb.append(spa.toString()); + sb.append("\n"); + } + + return sb.toString(); + } + + + public String printPath() { + return printPath(-1); + } + + private static Object lastElement(List path) { + HalfOperator hoa = null; + for (Iterator ita = path.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + for (Iterator itb = spa.getPath().iterator(); itb.hasNext(); ) { + hoa = (HalfOperator)itb.next(); + } + } + return hoa; + } + + public String printPath(int n) + { + StringBuffer sb = new StringBuffer(); + + final String dstr = n >= 0 ? printDelay(delay[n]) : printDelay(delay); + final String sstr = n >= 0 ? printDelay(getSlack(n)) + : printDelay(slack); + final String rstr = + n >= 0 && getSlack(n) != slack[n] ? printDelay(slack[n]) : null; + + final HalfOperator lastHalfOp = (HalfOperator) lastElement(path); + GlobalNet gn; + CellNet cn; + TechnologyData tech; + double[] effectiveResistanceFactors; + double effectiveResistanceFactor; + double f = 0.0; + double wireCap = 0.0; + double reff = 0.0; + if (n >= 0) { + gn = (GlobalNet) getEndNet().getGlobalNets().get(n); + cn = gn.getTopCellNet(); + tech = cn.container.design.getTechnologyData(); + reff = gn.getDriveResistance(lastHalfOp)*tech.elmoreDelayFactor; + wireCap = gn.getWireCapacitance(); + } + + final String nstr; + if (n >= 0) { + gn = + (GlobalNet) getEndNet().getGlobalNets().get(n); + cn = gn.getTopCellNet(); + nstr = "// endnet=" + cn.container.typeName + "/" + + cn.canonicalName.getCadenceString() + "\n" + + (delaybias[n] != 1 ? + ("// delaybias=" + + NumberFormatter.format(delaybias[n], 2) + "\n") + : ""); + + } else { + nstr = ""; + } + final double theslack = n >= 0 ? getSlack(n) : 0.0; + final double budgetcap = reff > 0.0 ? theslack/reff+wireCap : 0.0; + sb.append("// delay=" + dstr + "ps" + " slack=" + sstr + "ps" + + (rstr == null ? "" : " real_slack=" + rstr + "ps") + + " avg_width=" + NumberFormatter.format(getAverageWidth()*1e6,3) + "um" + + " c_wire="+ NumberFormatter.format(wireCap*1e15,1)+"fF" + + " reff="+ NumberFormatter.format(reff,1)+ + " budget_cap="+ NumberFormatter.format(budgetcap*1e15,1)+"fF\n" + + nstr); + + for (Iterator ita = path.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + sb.append(spa.printPath(false)); + + } + + return sb.toString(); + } + + + public void dumpInfo(BufferedWriter bw1, String s1) + { + try{ + bw1.write(s1 + "CONCATENATED_PATH _ {\n"); + // bw1.write(s1 + "\tisFragment = " + isFragment + ";\n\n"); + + if(delay != null){ + bw1.write(s1 + "\tdelay = " + printDelay(delay) + ";\n"); + bw1.write(s1 + "\tslack = " + printDelay(slack) + ";\n"); + bw1.write(s1 + "\tcritical_net = " + criticalNet.canonicalName.getCadenceString() + ";\n"); + bw1.write(s1 + "\tave_width = " + getAverageWidth() + ";\n"); + } + + for (Iterator ita = path.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + bw1.write(s1 + "\tCATPATH_CELL " + spa.container.typeName + " {\n"); + spa.dumpInfo(bw1, s1 + "\t\t"); + bw1.write(s1 + "\t}\n"); + } + + bw1.write(s1 + "}\n"); + } + catch(IOException e){ + e.printStackTrace(System.out); + } + } + + + public double getAverageWidth() + { + int numHalfOperators = 0; + double totalWidth = 0.0; + + for (Iterator ita = path.iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + for (Iterator itb = spa.getPath().iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + + totalWidth += hoa.getCurrentSize(); + numHalfOperators++; + } + } + + return totalWidth / numHalfOperators; + } + + + /** + * Inserts st1 into lst1. Leaf cells + * appear at the front of the list and high-level cells at the end. + **/ + private static void sortedInsert(List/**/ lst1, CellType st1) + { + int k = st1.getLevel(); // get the level number of the sub-type + int j = lst1.size(); + for(int i=0;i k){ + lst1.add(i, st1); // insert this sub-type at index i + return; + } + } + + lst1.add(st1); // add this sub-type to the end of the list + } + + + /** + * Reduce cat paths for cellTypes by combining cat paths + * with similar loads into "worst case" cat paths. A cell's cat paths + * are partitioned into sets of cat paths having the same type (as + * specified by {@link #isSameTypeAs}) and loads differing by less than + * threshold (as specified by {@link #isLoadCloseTo}). + * For each set, a new reduced cat path is constructed element by + * element from the component sizing paths that have the worst case + * load. + * + * @param cellTypes + * set of cell types whose cat paths are to be reduced. + * @param threshold + * acceptable relative load difference for cat path reduction. + * If threshold is less than 0, then do not attempt path + * reduction at all. See {@link #isLoadCloseTo}. + **/ + public static void reduceCatPaths(Set/**/ cellTypes, + double threshold) + { + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + + if(DebugOption.printLevel <= 3){ + System.out.println("CatPath reduction"); + System.out.println("Processing cell: " + cta.typeName); + } + + // All cat paths in the same list of cat paths are the same + // type as the first one and have load close to the first in + // the same list. The cat paths in one list will never be + // both of the same type and have load close to the first + // cat path in a different list. + // + // That is to say the invariant for similarCatPathsList is: + // (\forall int i,j,k; 0 <= i && i < similarCatPathsList.size() && + // 0 <= j && j < similarCatPathsList.size() && + // 0 <= k && k < similarCatPathsList.get(j).size(); + // (similarCatPathsList.get(j).get(k) + // .isSameTypeAs(similarCatPathsList.get(i).get(0)) && + // similarCatPathsList.get(j).get(k) + // .isLoadCloseTo(similarCatPathsList.get(i).get(0))) <==> + // i == j) + List/*>*/ similarCatPathsList = + new ArrayList/*>*/(); + + // group similar cat paths together + + for (Iterator itb = cta.getCatPaths().iterator(); itb.hasNext(); ) { + CatPath cpa = (CatPath)itb.next(); + // if(DebugOption.printLevel <= 3){ + // System.out.println("Processing path: "); + // System.out.println(cpa.toString()); + // } + + + if(!cpa.isFragment()){ + boolean found = false; + if (threshold >= 0) { + for (Iterator itc = similarCatPathsList.iterator(); + itc.hasNext(); ) { + List/**/ similarCatPaths = + (List) itc.next(); + + CatPath headCatPath = + (CatPath) similarCatPaths.get(0); + if (cpa.isSameTypeAs(headCatPath)) { + if(DebugOption.printLevel <= 3){ + System.out.println("Found concatenated paths of same type"); + // System.out.println(cpa.toString()); + } + + if (cpa.isLoadCloseTo(headCatPath, threshold)) { + found = true; + + if(DebugOption.printLevel <= 3){ + System.out.println("Found concatenated path to be reduced"); + // System.out.println(cpa.toString()); + } + + similarCatPaths.add(cpa); + break; + } + } + } + } + + if(!found){ + List/**/ similarCatPaths = + new ArrayList/**/(); + similarCatPaths.add(cpa); + similarCatPathsList.add(similarCatPaths); + } + } + } + + + // Now, form one cat path with worst case load for each group + // of similar cat paths. + + Set/**/ reducedCatPaths = cta.getReducedCatPaths(); + reducedCatPaths.clear(); + + for (Iterator itb = similarCatPathsList.iterator(); + itb.hasNext(); ) { + List/**/ similarCatPaths = (List) itb.next(); + int numSimilarCatPaths = similarCatPaths.size(); + + CatPath reducedCatPath; + if(numSimilarCatPaths == 1){ + reducedCatPath = + new CatPath((CatPath) similarCatPaths.get(0)); + } + else{ + + CatPath headCatPath = (CatPath) similarCatPaths.get(0); + int numSizingPaths = headCatPath.getCatPath().size(); + + reducedCatPath = new CatPath(headCatPath); + reducedCatPath.getCatPath().clear(); + + for(int i=0;i<(numSizingPaths-1);++i){ + double maxWireRc = -1.0; + SizingPath worstSizingPath = null; + + for(int j=0;j*/ globalNets = + endNet.getGlobalNets(); + assert globalNets.size() == 1 + : "Invalid number of global nets 1a: " + + globalNets.size(); + + double wireRc = + ((GlobalNet) globalNets.get(0)) + .getWireRC(); + + if(wireRc > maxWireRc){ + maxWireRc = wireRc; + worstSizingPath = spb; + } + } + + reducedCatPath.getCatPath().add(new SizingPath(worstSizingPath)); + } + + int i = numSizingPaths-1; + + double maxWireRc = -1.0; + SizingPath worstSizingPath = null; + + for(int j=0;j*/ globalNets = + endNet.getGlobalNets(); + assert !globalNets.isEmpty(); + + double maxGlobalNetWireRc = -1.0; + for (Iterator itd = globalNets.iterator(); + itd.hasNext(); ) { + GlobalNet gna = (GlobalNet)itd.next(); + + double wireRc = gna.getWireRC(); + + if (wireRc > maxGlobalNetWireRc) + maxGlobalNetWireRc = wireRc; + } + + if(maxGlobalNetWireRc > maxWireRc){ + maxWireRc = maxGlobalNetWireRc; + worstSizingPath = spb; + } + } + + reducedCatPath.getCatPath() + .add(new SizingPath(worstSizingPath)); + } + + reducedCatPaths.add(reducedCatPath); + } + + if(DebugOption.printLevel <= 3){ + System.out.println("\n**************** " + cta.typeName + " **************"); + System.out.println("Total number of reduced concatenated paths: " + + reducedCatPaths.size()); + System.out.println("**********************************************************"); + } + } + + } + + + /** + * Determines if this cat path has similar end global nets. They are + * considered similar if they are made up of the same number of + * sizing paths, and each sizing path has the same + * copyFrom field and each ending global net + * of the sizing path has a corresponding global net in the + * other sizing path according to {@link GlobalNet#isSameTypeAs}. + **/ + private boolean isSameTypeAs(CatPath cp1) + { + int numSizingPaths = cp1.getCatPath().size(); + + if (numSizingPaths != path.size()) + return false; + + for(int i=0;i*/ globalNetsA = + (List) spa.getEndNet().getGlobalNets(); + List/**/ globalNetsB = + (List) spb.getEndNet().getGlobalNets(); + if(i < (numSizingPaths-1)){ + // not the last sizing path + assert globalNetsA.size() == 1 + : "Invalid number of global nets 1b: " + + globalNetsA.size() + "\n" + + spa.getEndNet().toString(); + + assert globalNetsB.size() == 1 + : "Invalid number of global nets 1c: " + + globalNetsB.size() + "\n" + + spb.getEndNet().toString(); + + GlobalNet gna = (GlobalNet) globalNetsA.get(0); + GlobalNet gnb = (GlobalNet) globalNetsB.get(0); + + if(!gna.isSameTypeAs(gnb)){ + //if(DebugOption.printLevel <= 3){ + //System.out.println("Different types of global net."); + //System.out.println(gna.getTopCellNet().canonicalName.getCadenceString()); + //System.out.println(gnb.getTopCellNet().canonicalName.getCadenceString()); + // System.out.println(spa.getEndNet().toString()); + //System.out.println(gna.toString()); + // System.out.println(spb.getEndNet().toString()); + //System.out.println(gnb.toString()); + //} + return false; + } + } + else{ + // the last sizing path + if (globalNetsA.size() != globalNetsB.size()) + return false; + + List/**/ globalNetsBCopy = + new ArrayList/**/(globalNetsB); + + for (Iterator ita = globalNetsA.iterator(); ita.hasNext(); ) { + GlobalNet gna = (GlobalNet)ita.next(); + boolean found = false; + + for (Iterator itb = globalNetsBCopy.iterator(); + itb.hasNext(); ) { + GlobalNet gnb = (GlobalNet)itb.next(); + + if(gna.isSameTypeAs(gnb)){ + found = true; + itb.remove(); + break; + } + } + if (!found) + return false; + } + if (!globalNetsBCopy.isEmpty()) + return false; + } + } + + return true; + } + + + /** + * Determines if cp1 has similar load to this one. + * They are considered similar if the "total max wire rc" + * differs by less than threshold from this one's. + * The "total max wire rc" is the sum of the maximum wire + * rcs for the global nets ending the contained sizing paths. + * (There is only one ending global net for all but the last + * sizing path.) The relative difference is computed as + * Math.abs(totalRcA - totalRcB) / totalRcA. + * + *

    This method is only meaningful if the cat paths are + * the same type according to {@link isSameTypeAs}. + * + *

    XXX: Review handling of unfloorplanned nets + * (rc == 0.0) and general soundness + * of cat path reduction. + * + * @pre isSameTypeAs(cp1) + * + * @param cp1 + * The cat path whose wire rc is to be compared to this one. + * @param threshold + * The fraction by which the total wire rc of + * cp1 is allowed to differ from the total wire + * rc of this cat path. + **/ + private boolean isLoadCloseTo(CatPath cp1, double threshold) + { + int numSizingPaths = cp1.getCatPath().size(); + + // isSameTypeAs() ==> same sizes, and isSameTypeAs() is a + // precondition for this method + assert numSizingPaths == path.size(); + + double totalWireRcA = 0.0; + double totalWireRcB = 0.0; + + //double maxRelRcDiff = -1.0; + + for (int i = 0; i < numSizingPaths - 1; ++i) { + SizingPath spa = (SizingPath)cp1.getCatPath().get(i); + SizingPath spb = (SizingPath)path.get(i); + + List/**/ endGlobalNetsA = + spa.getEndNet().getGlobalNets(); + List/**/ endGlobalNetsB = + spb.getEndNet().getGlobalNets(); + + assert endGlobalNetsA.size() == 1; + assert endGlobalNetsB.size() == 1; + + double rca = ((GlobalNet) endGlobalNetsA.get(0)) + .getWireRC(); + double rcb = ((GlobalNet) endGlobalNetsB.get(0)) + .getWireRC(); + + totalWireRcA += rca; + totalWireRcB += rcb; + + //double relRcDiff = relativeRcDifference(rca, rcb); + + //if (relRcDiff > maxRelRcDiff) + // maxRelRcDiff = relRcDiff; + } + + SizingPath spa = (SizingPath)cp1.getCatPath().get(numSizingPaths-1); + SizingPath spb = (SizingPath)path.get(numSizingPaths-1); + + CellNet endNetA = spa.getEndNet(); + List/**/ endGlobalNetsA = endNetA.getGlobalNets(); + + assert !endGlobalNetsA.isEmpty(); + + CellNet endNetB = spb.getEndNet(); + List/**/ endGlobalNetsB = + new ArrayList/**/(endNetB.getGlobalNets()); + + assert !endGlobalNetsB.isEmpty(); + + if(DebugOption.printLevel <= 3){ + System.out.println("Comparing cell nets: " + + endNetA.canonicalName.getCadenceString() + + " and " + endNetB.canonicalName.getCadenceString()); + } + + if (endGlobalNetsA.size() != endGlobalNetsB.size()) + return false; + + double maxWireRcA = -1.0; + double maxWireRcB = -1.0; + + for (Iterator ita = endGlobalNetsA.iterator(); + ita.hasNext(); ) { + GlobalNet gna = (GlobalNet)ita.next(); + + double wireRcA = gna.getWireRC(); + if (wireRcA > maxWireRcA) + maxWireRcA = wireRcA; + + boolean found = false; + + for (Iterator itb = endGlobalNetsB.iterator(); itb.hasNext(); ) { + GlobalNet gnb = (GlobalNet)itb.next(); + + double wireRcB = gnb.getWireRC(); + if (wireRcB > maxWireRcB) + maxWireRcB = wireRcB; + + if(gna.isSameTypeAs(gnb)){ + found = true; + itb.remove(); + break; + } + } + + if (!found) + return false; + } + + if (!endGlobalNetsB.isEmpty()) + return false; + + totalWireRcA += maxWireRcA; + totalWireRcB += maxWireRcB; + + //double relRcDiff = + // relativeRcDifference(maxWireRcA, maxWireRcB); + + //if (relRcDiff > maxRelRcDiff) + // maxRelRcDiff = relRcDiff; + + // REVIEW: Why was this commented out? + //if(maxRelRcDiff > threshold){ + // return false; + //} + + //if (DebugOption.printLevel <= 3) + // System.out.println("Maximum relative difference: " + + // maxRelRcDiff); + + + double avgRelRcDiff = + relativeRcDifference(totalWireRcA, totalWireRcB); + + if (DebugOption.printLevel <= 3) + System.out.println("Average relative difference: " + avgRelRcDiff); + + if (avgRelRcDiff > threshold) + return false; + + return true; + } + + /** + * Computes the relative rc difference, defined as + * Math.abs(rcb - rca) / rca, unless + * rca == 0.0 && rcb == 0.0 in which + * case the relative difference is 0.0. + **/ + private static final double relativeRcDifference(double rca, + double rcb) { + if (rca == 0.0 && rcb == 0.0) + return 0.0; + else + return Math.abs(rcb - rca) / rca; + } + + + private static CatPath joinCatPaths(List/**/ lst1) + { + CatPath cp1 = new CatPath(); + // Strip out extra CatPath wrapper. + + List/**/ lstc = cp1.getCatPath(); + + for (Iterator ita = lst1.iterator(); ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + + List/**/ lsta = cpa.getCatPath(); + + int numSizingPaths = lsta.size(); + + // If List.get throws exception, the error is: + // No sizing path in concatenated path. + SizingPath spa = new SizingPath((SizingPath)lsta.get(0)); + spa.setStartNets(cpa.getStartNets()); + + if(numSizingPaths == 1){ + spa.setEndNet(cpa.getEndNet()); + lstc.add(spa); + } + else{ + lstc.add(spa); + + for(int i=1;i<(numSizingPaths-1); ++i){ + spa = new SizingPath((SizingPath)lsta.get(i)); + lstc.add(spa); + } + + spa = new SizingPath((SizingPath)lsta.get(numSizingPaths-1)); + spa.setEndNet(cpa.getEndNet()); + + lstc.add(spa); + } + } + + return cp1; + } + + + private static void addCatPath(Set/**/ allCatPaths, + CatPath newCatPath, + boolean reduceNow) + { + if(reduceNow){ + boolean found = false; + + for (Iterator ita = allCatPaths.iterator(); ita.hasNext(); ) { + CatPath oldCatPath = (CatPath)ita.next(); + + if(oldCatPath.isSameTypeAs(newCatPath)){ + found = true; + + List/**/ oldSizingPaths = + oldCatPath.getCatPath(); + List/**/ newSizingPaths = + newCatPath.getCatPath(); + + // isSameTypeAs ==> + // oldSizingPaths.size() == newSizingPaths().size + int numSizingPaths = oldSizingPaths.size(); + for (int i = 0; i < numSizingPaths; ++i) { + SizingPath oldSizingPath = + (SizingPath) oldSizingPaths.get(i); + List/**/ oldGlobalNets = + oldSizingPath.getEndNet().getGlobalNets(); + + SizingPath newSizingPath = + (SizingPath) newSizingPaths.get(i); + List/**/ newGlobalNets = + newSizingPath.getEndNet().getGlobalNets(); + + if (i < numSizingPaths - 1) { + GlobalNet gna = (GlobalNet) oldGlobalNets.get(0); + double oldWireRc = + gna.getWireRC(); + + GlobalNet gnb = (GlobalNet) newGlobalNets.get(0); + double newWireRc = + gnb.getWireRC(); + + if (newWireRc > oldWireRc) + oldSizingPaths.set(i, newSizingPath); + } + else{ + double maxOldWireRc = -1.0; + for (Iterator itb = oldGlobalNets.iterator(); itb.hasNext(); ) { + GlobalNet gna = (GlobalNet)itb.next(); + double oldWireRc = + gna.getWireRC(); + if (oldWireRc > maxOldWireRc) + maxOldWireRc = oldWireRc; + } + + double maxNewWireRc = -1.0; + for (Iterator itb = newGlobalNets.iterator(); itb.hasNext(); ) { + GlobalNet gnb = (GlobalNet)itb.next(); + double newWireRc = + gnb.getWireRC(); + if (newWireRc > maxNewWireRc) + maxNewWireRc = newWireRc; + } + + if (maxNewWireRc > maxOldWireRc) + oldSizingPaths.set(i, newSizingPath); + } + } + + break; + } + } + + if(!found){ + allCatPaths.add(newCatPath); + } + } + else{ + allCatPaths.add(newCatPath); + } + } + + + private static void debugOutput(List/**/ catPathsToBeCatted, + Set/**/ allCatPaths, + CatPath cp1, + long[] numCatPaths, + CellType ct1) + { + if(DebugOption.printLevel <= 3){ + //if(true){ + // FIXME: hardcoded constant + if (numCatPaths[0] % 5000 == 0) { + System.out.println(); + System.out.println("DEBUG: Concatenated paths generation in: " + ct1.typeName); + System.out.println("Number of visited concatenated paths: " + numCatPaths[0]); + System.out.println("Total number of distinguished paths: " + allCatPaths.size()); + System.out.println("RC of current path: " + + catPathsToBeCatted.size()); + System.out.println(); + + // FIXME: hardcoded constant + if (numCatPaths[0] > 100000 && allCatPaths.size() > 2500) { + System.err.println("\033[1;31m" + + "ERROR 1: " + "\033[0m" + + "Jauto is generating more than 2500 concatenated paths in: " + + ct1.typeName + "\n" + + "Please search output file for the last \"DEBUG: Concatenated paths generation in " + + ct1.typeName + "\" for detailed information and add cutpath."); + } + } + + if (numCatPaths[0] % 5000 < 5) { + System.out.println(cp1.toString()); + } + } + } + + + public boolean isComponentsFixed() { + for (Iterator ita = getCatPath().iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + if (!spa.copyFrom.container.isFixedSize()) + return false; + } + return true; + } + + public CatPath popUp(boolean isEndNonObservable, + boolean hasObservable, + Set/**/ nonObservableStartNets, + CellNet endNet) { + CatPath cpb = new CatPath(this); + + cpb.getCatPath().clear(); + + for (Iterator itd = getCatPath().iterator(); itd.hasNext(); ) { + SizingPath spa = (SizingPath)itd.next(); + SizingPath spb = new SizingPath(spa); + + cpb.getCatPath().add(spb); + } + + cpb.setStartNets(nonObservableStartNets); + cpb.setEndNet(endNet); + cpb.setIsFragment(false); + + //if(isEndNonObservable || !hasObservable){ // this sizing path can be removed from the sub-cell + // setIsFragment(true); + //} + setIsFragment(true); + + //if(isEndNonObservable && hasObservable){ // this sizing path should be one of the start sizing path in cat path + // cpb.isReduced = true; + //} + if(hasObservable){ // this sizing path should be one of the start sizing path in cat path + cpb.isReduced = true; + } + + cpb.isEndNetNonObservable = isEndNonObservable; // is this a end sizing path for cat path? + + return cpb; + } + + void getPathString(final StringBuffer buf) { + for (Iterator i = path.iterator(); i.hasNext(); ) { + final AbstractPath apath = (AbstractPath) i.next(); + apath.getPathString(buf); + buf.append(' '); + } + getNetString(buf, getEndNet()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CellHierarchyDump.g b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CellHierarchyDump.g new file mode 100644 index 0000000000..af6c8f2194 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CellHierarchyDump.g @@ -0,0 +1,191 @@ +// This reads in a dump of the form generated by the skill function +// DumpCellHierarchy. allRecords() is the main function. It produces +// a Vector of SubCellRecords, one per subcell, which contain the +// type, name (relative to the parent), and bounding box (relative to +// the parent) of the subcell. + +header { + /////////////////////////////////////////////////////////////////////// + // + // Copyright 2001 Fulcrum Microsystems. All rights reserved. + // + // Warning: This file was AUTOMATICALLY GENERATED!!! + // + // DO NOT check in. + // DO NOT modify. + // + // You want to modify CellHierarchyDump.g instead + // + /////////////////////////////////////////////////////////////////////// + + package com.avlsi.tools.jauto; +} + +{ + import java.util.Vector; + + import com.avlsi.geometry.Point; + import com.avlsi.geometry.BoundingBox; + + import com.avlsi.fast.ConnectionInfo; + import com.avlsi.tools.jauto.SubcellProcessor; + import com.avlsi.util.debug.Debug; +} + +class CellHierarchyDumpParser extends Parser; + +{ + private Point makePoint(Token tx, Token ty) throws SemanticException { + Point p = null; + try { + double x = Double.parseDouble(tx.getText()); + double y = Double.parseDouble(ty.getText()); + p = new Point(x, y); + } catch (NumberFormatException e) { + throw new SemanticException("Invalid number in coordinate (" + tx.getText() + ", " + ty.getText()+ ") found at line " + tx.getLine() + " column " + tx.getColumn() + "!"); + } + return p; + } + private int orientValue(String o) { + if (o.equals("R0")) return ConnectionInfo.R0; + else if (o.equals("R90")) return ConnectionInfo.R90; + else if (o.equals("R180")) return ConnectionInfo.R180; + else if (o.equals("R270")) return ConnectionInfo.R270; + else if (o.equals("MX")) return ConnectionInfo.MX; + else if (o.equals("MXR90")) return ConnectionInfo.MXR90; + else if (o.equals("MY")) return ConnectionInfo.MY; + else if (o.equals("MYR90")) return ConnectionInfo.MYR90; + Debug.assertTrue(false, "Invalid orientation " + o + "!"); + return 0; // Not reached. + } +} + +// MAIN FUNCTION +// Returns a Vector of SubCellRecords. +goal [ SubcellProcessor p ] { + BoundingBox b; + } + : b = bBox { + p.process(b); + } + (pinRecords[p]) ? + (subCellRecords[p]) ? + EOF + ; + +pinRecords [ SubcellProcessor p ] + : PINS_TOKEN + BEGIN_TOKEN + ( + pinRecord[p] + )* + END_TOKEN + ; + +pinRecord [ SubcellProcessor p ] { + BoundingBox b; + } + : BEGIN_TOKEN name:STRING b = bBox END_TOKEN + { + p.process(name.getText(), + b); + } + ; + +subCellRecords [ SubcellProcessor p ] + : SUBCELLS_TOKEN + BEGIN_TOKEN + ( + subCellRecord[p] + )* + END_TOKEN + ; + + +subCellRecord [ SubcellProcessor p ] { + BoundingBox b; + } + : BEGIN_TOKEN type:STRING name:STRING orient:ORIENT b = bBox END_TOKEN + { + p.process(type.getText(), + name.getText(), + orientValue(orient.getText()), + b); + } + ; + +bBox returns [BoundingBox b] +{ b = null; + Point lowerLeft; + Point upperRight; } + : BEGIN_TOKEN lowerLeft = coord upperRight = coord END_TOKEN + { + b = new BoundingBox(lowerLeft, upperRight); + } + ; + +coord returns [Point p] +{ p = null; } + : BEGIN_TOKEN x:NUMBER y:NUMBER END_TOKEN + { + p = makePoint(x, y); + } + ; + +string returns [String s] +{ s = null; } + : str:STRING + { + s = str.getText(); + } + ; + +class CellHierarchyDumpLexer extends Lexer; +options { + k = 3; +} + +BEGIN_TOKEN + : ( "beginlist" ) + ; + +END_TOKEN + : ( "endlist" ) + ; + +PINS_TOKEN + : ( "pins" ) + ; + +SUBCELLS_TOKEN + : ( "subcells" ) + ; + +// Represents what's between quote marks +STRING + : '\"'! ( 'a'..'z'|'A'..'Z'|'-'|'0'..'9'|'['|']'|'.'|'('|')'|'_'|','|'|' )+ '\"'! + ; + +NUMBER + : ('+' | '-')? + ( + ( ('0'..'9')+ ('.' ('0'..'9')+ )? ) + | + ( '.' ('0'..'9')+ ) + ) + ( ('e' | 'E') ('+' | '-')? ('0'..'9')+ )? + ; + +WS : ( ' ' + | '\t' + | '\r' '\n' { newline(); } + | '\n' { newline(); } + ) + {$setType(Token.SKIP);} //ignore this token + ; + + + +ORIENT + : "R0" | "R90" | "R180" | "R270" | "MX" | "MXR90" | "MY" | "MYR90" + ; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CheckChargeTools.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CheckChargeTools.java new file mode 100644 index 0000000000..e0c6c012d7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/CheckChargeTools.java @@ -0,0 +1,177 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.tools.jauto; + +import java.util.ArrayList; +import java.io.BufferedWriter; +import java.util.Collections; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Iterator; +import java.io.PrintWriter; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.file.common.HierName; +import com.avlsi.io.FileSearchPath; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.AliasedSet; + +/** + * Given a cell, writes the non-combinational nodes and the mutual + * exclusion rules out to two separate files. Will be used in the + * checkcharge utility. + **/ +public class CheckChargeTools { + + /** + * This class cannot be instantiated. + **/ + private CheckChargeTools() { + throw new AssertionError(); + } + + private static void printMutualExclusionRules(CadenceInfo ci, + String filename, + String instanceName) + throws IOException { + final PrintWriter output = + new PrintWriter(new BufferedWriter(new FileWriter(filename))); + + final ExclusiveNodeSets sets = ci.getLocalExclusiveNodeSets(); + final AliasedSet nodeAliases = ci.getLocalNodes(); + for (final Iterator i=sets.getIterator(); i.hasNext(); ) { + ExclusiveNodeSet set = (ExclusiveNodeSet) i.next(); + final int hiLo = set.getHiLo(); + if (hiLo == ExclusiveNodeSet.HI) + output.print("exclhi("); + else if (hiLo == ExclusiveNodeSet.LO) + output.print("excllo("); + else if (hiLo == ExclusiveNodeSet.CC) + output.print("exclcc("); + else throw new AssertionError("Invalid hiLo value: " + hiLo); + for (final Iterator nodes=set.getNodes(); nodes.hasNext(); ) { + HierName nodeName = (HierName) nodes.next(); + HierName canonicalName = + (HierName) nodeAliases.getCanonicalKey(nodeName); + output.print(instanceName + "." + canonicalName); + if (nodes.hasNext()) + output.print(","); + } + output.println(")"); + } + + output.close(); + } + + private static void printStaticizableNodes(Cadencize cad, + CellInterface cell, + CastFileParser cfp, + String filename, + String instanceName) + throws IOException, UnimplementableProductionRuleException { + final PrintWriter output = + new PrintWriter(new BufferedWriter(new FileWriter(filename))); + + CadenceInfo ci = cad.convert(cell); + // Prepare the netgraph + final NetGraph graph = new NetGraph(ci.getLocalNodes(), + ci.getLocalExclusiveNodeSets(), + new ArrayList(), + HierName.makeHierName("Vdd!"), + HierName.makeHierName("GND!"), + Collections.EMPTY_SET); + graph.addCellInterface(cell, Collections.EMPTY_LIST, cfp, cad); + graph.prepareForLvs(); + + // Query all the nodes in the netgraph + final Iterator nodes = graph.getNodes().iterator(); + while (nodes.hasNext()) { + final NetGraph.NetNode node = (NetGraph.NetNode) nodes.next(); + final HierName name = node.getName(); + if ((! node.isCombinational()) && + (node.isNamed()) && + (node.isOutput())) + output.println(instanceName + "." + name); + + } + + output.close(); + } + + private static void usage() { + System.out.println("bad usage"); + System.exit(3); + } + + public static void main(String [] args) throws Exception { + // + // Command-line parsing + // + CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + CommandLineArgs theArgs = cachedArgs; + + final String cellName = theArgs.getArgValue("cell", null); + // The instance name of the cell. All references to nodes get + // prefixed with this. + final String instanceName = theArgs.getArgValue("prefix", null); + final boolean makeMutualExclusionRules = theArgs.argExists("mer"); + final boolean makeStaticizableNodes = theArgs.argExists("nodes"); + + final FileSearchPath castSearchPath = + new FileSearchPath( theArgs.getArgValue( "cast-path", "." ), + System.getProperty( "user.home" ) ); + + + // Things which may be command-line arguments in the future + final String castVersion = "2"; + final String mutualExclusionOutputFile = "mutual_exclusion_rules"; + final String staticizableNodesOutputFile = "staticizable_nodes"; + final boolean verbose = false; + + // Basic sanity-checking + if (cellName == null || instanceName == null) + usage(); + + // + // Actual functionality + // + final CastFileParser castFileParser = + new CastFileParser(castSearchPath, castVersion, verbose); + final CellInterface castCell = + castFileParser.getFullyQualifiedCell( cellName ); + final Cadencize cadencizer = new Cadencize(true); + final CadenceInfo ci = cadencizer.convert(castCell); + + if (makeMutualExclusionRules) + printMutualExclusionRules(ci, mutualExclusionOutputFile, + instanceName); + if (makeStaticizableNodes) + printStaticizableNodes(cadencizer, castCell, castFileParser, + staticizableNodesOutputFile, + instanceName); + + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/ConjugateGradientSolver.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/ConjugateGradientSolver.java new file mode 100644 index 0000000000..1fc05caa9f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/ConjugateGradientSolver.java @@ -0,0 +1,301 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.util.logging.Logger; +import com.avlsi.tools.jauto.JautoUI; + +/** + * Conjugate gradient descent solver. This code was originally written because + * Andrew was "getting fed up with the crappiness of Lancelot and the growing + * complexity of the external C solver." The minimization algorithm is from + * sw/c/lib/minimize.c which was in turn based on Numerical Recipes. + * + * @author Andrew Lines + * @author Harry Liu + **/ +public class ConjugateGradientSolver { + /** + * Logging object. + **/ + private static final Logger logger = + Logger.getLogger("com.avlsi.tools.jauto.ConjugateGradientSolver"); + + /** + * Interface representing a differentiable, scalar-valued, vector function. + **/ + public interface Function { + /** + * Evaluate the function at the specified vector. + * + * @param v the vector at which to evalute the function + * @return the value at the specified point + **/ + double getValue(double[] v); + + /** + * Calculate the negative of the gradient at the specified vector. + * + * @param v the vector at which to evalute the gradient + * @param negativeGradient the negative gradient + **/ + void getNegativeGradient(double[] v, double[] negativeGradient); + } + + /** + * Interface representing a stop condition for the inner loop of the + * conjugate gradient descent solver. + **/ + public interface StopCondition { + /** + * Returns true if the solver should continue and + * false if it should stop. This function is called at the + * beginning of each loop. + * + * @param mag the magnitude of the last gradient evaluated + **/ + boolean evaluate(boolean big_step, double mag); + } + + /** + * Rarely changed tunable parameters for the golden section search used by + * the solver. To provide different values for the parameters, extend this + * class and override the appropriate methods. + **/ + public static class Parameters { + /** + * Returns the tolerance as a fraction of the interval bracketing the + * minimum. + **/ + public double getTolerance() { return 1e-4; } + + /** + * Returns the lower bound on the initial search interval. + **/ + public double getTiny() { return 1e-10; } + + /** + * Returns the upper bound on the number of steps to bracket the + * minimum. + **/ + public double getBracketSteps() { return 100; } + + /** + * Returns the upper bound on the number of steps. + **/ + public double getGoldenSteps() { return 10; } + } + + /** + * Numerical constants used for golden section search. + **/ + private static final double GOLD = 0.5 + Math.sqrt(5) / 2; + private static final double STEP = 1 - 1 / GOLD; + + /** + * The function to solve. + **/ + private final Function func; + + /** + * Tuning parameters. + **/ + private final Parameters params; + + /** + * Used to tune lineMinimum's initial guess. + **/ + private double initial_interval; + + /** + * Returns the "energy" of the function. + * + * @param v the vector at which to do the evaluation + * @return the energy of the function + **/ + protected double getEnergy(double[] v) { + return func.getValue(v); + } + + /** + * Evaluates the derivative of the function. + * + * @param v the vector at which to do the evaluation + * @param down the accumulator into which to add the negative gradient of + * the function + **/ + protected void getDown(double [] v, double [] down) { + for (int i = 0; i < down.length; ++i) down[i] = 0; + func.getNegativeGradient(v, down); + } + + /** + * Find line minimum with golden section search. Consult Numerical + * Recipes, section 10.1. + **/ + protected double lineMinimum(double [] v, double [] dir, double [] vv) { + double a,b,c,t,fa,fb,fc,ft,quit_interval; + int i,steps; + int N = v.length; + + // pick two points along dir at 0 and initial_interval + a = 0; + fa = getEnergy(v); + + b = initial_interval; + for (i=0; ifa) { + t = a; a = b; b = t; + ft = fa; fa = fb; fb = ft; + } + + // attempt to bracket the minimum + c = a; fc = fa; + for (steps=0; stepsquit_interval); steps++) { + if (Math.abs(b-a)>Math.abs(c-b)) { + t = b + (a - b) * STEP; + for (i=0; ia) a = Math.abs(b*dir[i]); + return a; + } + + /** + * Conjugate gradient descent. Polak-Ribiere formula. Resets if it + * gets stuck. Consult Numerical Recipes. + **/ + protected int conjugateGradientDescent(double [] p, + double tolerance, + StopCondition stop) { + int i; + int N = p.length; + double mg,mg1,step,step1,beta,dot; + + // allocate scrate vectors + double [] h = new double[N]; + double [] g = new double[N]; + double [] g1 = new double[N]; + + // initial setup + step = 4 * tolerance; + getDown(p,h); + for (i=0; i=tolerance,mg); i++) { + step1 = lineMinimum(p,h,g1); + step = 0.75*step + 0.25*step1; // exponentially weighted moving average + getDown(p,g1); + mg1 = dot = 0; + for (int j=0; j 0 ) ); + --curlyCount; + sb.append("-R"); + break; + case '-': + sb.append('-'); + badName = ( ( ! inParens ) || + ( i >= ( nameLength - 1 ) ) || + ( ! ( Character.isDigit( name.charAt( i + 1 ))))); + break; + case '_': + sb.append('_'); + break; + default: + if (Character.isLetterOrDigit(c)) { + sb.append(c); + } + else { + final String errorMessage = + "Unable to translate '" + + Character.toString(c) + + "' (0x" + + Integer.toString( ( int ) c, 16 ) + + ")"; + throw new Exception( errorMessage ); + } + } + ++i; + } + badName = badName || inParens || ( curlyCount != 0 ) ; + if ( badName ) { + final String errorMessage = + "\"" + name + "\" is an invalid cell name."; + throw new Exception( errorMessage ); + } + return sb.toString(); + } + + /** count the number of PRS this cell has **/ + public int countPrs(CellInterface cell, String cname, int depth){ + Iterator i; + int val, result = 0; + + if(isRealCell(cell)){ + subtype.add(cell.getFullyQualifiedType()); + //for(int tab=0; tab < depth; tab++) + //System.out.print("---"); + //System.out.println("+"+cell.getFullyQualifiedType() +" " +cname); + } + + if(cell.containsCompletePrs()){ + prscells.add(cell.getFullyQualifiedType()); + //prsinst.put(); + leafinstance++; + } + + i = cell.getProductionRuleSet().getProductionRules(); + while(i.hasNext()){ + ProductionRule prs = (ProductionRule)i.next(); + result++; + } + val = result; + + for (i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final HierName name = (HierName)p.getFirst(); + + if(isRealCell(subcell) && subcell.containsSubcells()){ + //System.out.println("containsSubcells: "+subcell.getType()); + result += countPrs(subcell, cname+"."+name.toString(), depth+1); + } + else if(isRealCell(subcell) && + !(subcell.containsCompletePrs() + ||subcell.containsSubcells())){ + //System.out.println("Unimplemented: "+subcell.getType()); + unimpl.add(subcell.getModuleName()+"."+subcell.getType()); + result += countPrs(subcell, cname+"."+name.toString(), depth+1); + } + else if(isRealCell(subcell) && subcell.containsCompletePrs()){ + //System.out.println("Implemented: "+subcell.getType()); + result += countPrs(subcell, cname+"."+name.toString(), depth+1); + } + } + /** Print the number of production Rules in the cells which have + been implemented **/ + if(cell.containsCompletePrs()||cell.containsSubcells()) + celldata.add(cell.getModuleName()+"."+cell.getType() + +": "+result); + + return result; + } + + public void writeSubtypeInfo(PrintStream p, boolean duplicate){ + int index; + String cellName; + String subtypeNum; + Iterator i = subtype.iterator(); + while(i.hasNext()){ + + String subtypeName = (String)i.next(); + index = subtypeName.lastIndexOf('.'); + cellName = subtypeName.substring(0, index); + subtypeNum = subtypeName.substring(index+1, subtypeName.length()); + + //this is a hack to get around the fact that not all the + //cells in the subtypes block need to refine a cell in the + //subcells block; eg. SLACK_1of2(0) does not make it's way + //into the subtypes block but is still avaliable in the + //subcells block + CellInterface c; + try { + CastFileParser cfp = + new CastFileParser(new FileSearchPath(this.path),"2"); + System.out.print("Attempting to locate " +cellName); + c = cfp.getFullyQualifiedCell(cellName); + } + catch(Exception e){ + System.out.println(": Not Found (probably just a wire)"); + continue; + } + if(c == null)continue; + System.out.println(": Found"); + String rcellName=null; + try { + rcellName = renameCell(cellName); + } + catch(Exception e){ + e.printStackTrace(); + System.exit(-1); + } + if(!duplicate){ + p.println("SPLIT: " +rcellName +" 0 " +subtypeNum); + p.println("SPLIT: " +rcellName +" 0 0"); + } + else if(duplicate){ + p.println("SPLIT: " +rcellName +" " +subtypeNum + +" " +subtypeNum); + } + + p.flush(); + } + } + + /** print the production rule count **/ + public void printPRCount() + { + Iterator i = celldata.iterator(); + if(i.hasNext()) + System.out.println("\nProduction Rule Count:\n"); + while(i.hasNext()){ + System.out.println("\t"+i.next()); + } + } + + + public void printLeafCells() + { + Iterator i = prscells.iterator(); + if(i.hasNext()) + System.out.println("\nLeaf Cells:("+prscells.size()+")\n"); + while(i.hasNext()){ + System.out.println("\t"+i.next()); + } + System.out.println("Total number of leaf cells: "+leafinstance); + } + + + /** print the cells that are unimplementable **/ + public void printUnimpl() + { + Iterator i = unimpl.iterator(); + if(i.hasNext()) + System.out.println("\nUnimplemented Cells: ("+unimpl.size()+")\n"); + while(i.hasNext()){ + System.out.println("\t"+i.next()); + } + } + + /** Is this a realCell at All? ***/ + public boolean isRealCell(CellInterface cell){ + return (cell.containsCompletePrs() + || cell.containsCsp() + || cell.containsJava() + || cell.containsSubcells()); + } + + + /****** get the components of the path *****/ + public static String [] getPath(String pathstr){ + int i=0; + StringTokenizer pathtok = new StringTokenizer(pathstr, ":"); + String []path = new String[pathtok.countTokens()]; + while(pathtok.hasMoreTokens()){ + path[i++] = pathtok.nextToken(); + } + return path; + } + + + /** useage, routine **/ + public static void usage(){ + System.out.println("CountPrs: --cast-path= --cell= " + +"[--tool=getleaf|unimpl|prscount]" + +"[--subtype-info=] [--duplicate]"); + System.exit(-1); + } + + /**** main routine ****/ + public static void main(String args[]){ + + CountPrs cp = new CountPrs(); + CellInterface cell = null; + + /*** parse command-line arguments here ***/ + String []path =null; + String module = null, cellName = null; + String tool = ""; + String filename = null; + boolean duplicate = false; + + /**** new command line processing stuff ****/ + CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + CommandLineArgs theArgs = cachedArgs; + CommandLineArgsIterator cmdIter = theArgs.iterator(); + + while ( cmdIter.hasNext() ) { + CommandLineArg curr = cmdIter.next(); + + if((curr.getName()).equals("cast-path")){ + String pathstr = curr.getValue(); + path = CountPrs.getPath(pathstr); + if(path == null){ + System.out.println("cast-path not specified"); + System.exit(0); + } + } + if((curr.getName()).equals("cell")){ + String fcellName = curr.getValue(); + if(fcellName == null){ + CountPrs.usage(); + System.exit(-1); + } + int lastdot = fcellName.lastIndexOf('.'); + module = fcellName.substring(0, lastdot); + cellName = fcellName.substring(lastdot+1, fcellName.length()); + } + if((curr.getName()).equals("tool")){ + tool = curr.getValue(); + if(tool == null){ + CountPrs.usage(); + System.exit(-1); + } + } + if((curr.getName()).equals("subtype-info")){ + filename = curr.getValue(); + if(filename == null){ + CountPrs.usage(); + System.exit(-1); + } + } + if((curr.getName()).equals("duplicate")){ + System.out.println("dfII_split_subtypes: duplication mode"); + duplicate = true; + } + } + if(cellName == null || module == null || path == null){ + CountPrs.usage(); + System.exit(-1); + } + + try { + FileSearchPath cFSP = new FileSearchPath(path); + cp.setPath(path); + CastFileParser cfp = new CastFileParser(cFSP,"2"); + cell = cfp.getFullyQualifiedCell(module, cellName); + + cfp = null; + System.gc(); + System.out.println("\nPrs Count: "+cp.countPrs(cell, "",0)); + if(tool.equals("") || tool.equals("all")){ + cp.printUnimpl(); + cp.printPRCount(); + cp.printLeafCells(); + } + else if(tool.equals("getleaf"))cp.printLeafCells(); + else if(tool.equals("prscount"))cp.printPRCount(); + else if(tool.equals("unimpl"))cp.printUnimpl(); + + if(filename != null){ + PrintStream p =new PrintStream(new FileOutputStream(filename)); + cp.writeSubtypeInfo(p, duplicate); + } + } + catch(Exception e){ + e.printStackTrace(); + System.exit(-1); + } + } +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DebugOption.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DebugOption.java new file mode 100644 index 0000000000..9b423613bb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DebugOption.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.jauto; + +public class DebugOption{ + + /** + * This class cannot be instantiated. + **/ + private DebugOption() { + throw new AssertionError(); + } + + public static final boolean printAll = false; + + public static int printLevel = 3; + + // print information in CastDesign::generateSourceSinkList() + public static final boolean printSSG = false; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DelayCalculator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DelayCalculator.java new file mode 100644 index 0000000000..b036cf9716 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/DelayCalculator.java @@ -0,0 +1,403 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.jauto; + +import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + + +import com.avlsi.fast.*; +import com.avlsi.tools.jauto.*; + +import com.avlsi.file.common.HierName; + +import com.avlsi.geometry.SteinnerTree; + +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.SimpleAbstractDeviceIterator; + +import com.avlsi.tools.lvs.NetGraph; + +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.debug.Debug; +/** + * Class representing a net that crosses cell boundaries. + * + * Attached at all ports, and at the net at the top level. + * + * Contains pointers to all terminal ports. + * + * @author Aaron Denney + * @version $Date$ + **/ + +public class DelayCalculator{ + + private CastDesign design; + + private TransistorSizingTool tool; + + private TechnologyData tech; + + /** Constructor 1 */ + public DelayCalculator() + { + design = null; + tool = null; + tech = null; + } + + + /** Constructor 2 */ + public DelayCalculator(CastDesign d, TransistorSizingTool t) + { + design = d; + tool = t; + tech = d.getTechnologyData(); + } + + + /** + * Timing analysis for given sizing path. The calculated delays are the + * sum of the delays for all half-operators in the path except for the last + * plus the delay of global nets for the last half-operator. + * + *

    The delay budget is the sum of the delay biases for all half + * operators times tau (the unit delay) plus the extra delay of a global + * net attached to the last half-operator. + * + *

    This function modifies the sp1 argument. + *

      + *
    • delay is set to the calculated delay. + *
    • slack is set to the delay budget minus the + * calculated delay. + *
    • criticalNet is set to the last net in the path with + * the minimum slack + *
    + * + * @return the calculated maximum delay for the SizingPath + **/ + public final double calculateDelay(SizingPath sp1) + { + CellNet criticalNet = null; + double delay = 0.0; + double totalDelayBias = 0.0; + double tau = tool.getOptionUnitDelay(); + double[] allDelays = null; + double[] allSlacks = null; + double[] allDelaybias = null; + + List/**/ halfOperators = sp1.getPath(); + final int numHalfOperators = halfOperators.size(); + for (int iHalfOp = 0; iHalfOp < numHalfOperators; ++iHalfOp) { + HalfOperator hoa = (HalfOperator) halfOperators.get(iHalfOp); + totalDelayBias += hoa.getDelayBias(); + + if (iHalfOp < numHalfOperators - 1) { // not the last half-operator + CellNet cna = hoa.outputNet; + List/**/ globalNets = cna.getGlobalNets(); + + assert globalNets.size() == 1 + : "Internal cell net has more than 1 global net"; + + GlobalNet gna = (GlobalNet) globalNets.get(0); + + delay += gna.calculateDelay(hoa); + + } + else{ // the last half-operator + CellNet cna = sp1.getEndNet(); + + // delay budget before instance based delaybias + final double unbiasedBudget = totalDelayBias * tau; + double maxDelay = Double.NEGATIVE_INFINITY; + double minSlack = Double.POSITIVE_INFINITY; + criticalNet = cna; + allDelays = new double[cna.getGlobalNets().size()]; + allSlacks = new double[cna.getGlobalNets().size()]; + allDelaybias = new double[cna.getGlobalNets().size()]; + int count = 0; + for (Iterator ita = cna.getGlobalNets().iterator(); + ita.hasNext(); ++count) { + GlobalNet gna = (GlobalNet)ita.next(); + allDelaybias[count] = + TransistorSizingTool.findDelayBias(gna, hoa); + double partialBudget = unbiasedBudget * allDelaybias[count]; + cna = gna.getTopCellNet(); + + double g = gna.calculateDelay(hoa); + maxDelay = Math.max(maxDelay, g); + allDelays[count] = delay + g; + + double e = getExtraDelay(hoa, gna, tau); + allSlacks[count] = (partialBudget + e) - allDelays[count]; + + if (allSlacks[count] < minSlack) { + minSlack = allSlacks[count]; + criticalNet = cna; + } + } + + delay += maxDelay; + } + } + + sp1.delay = allDelays; + sp1.slack = allSlacks; + sp1.delaybias = allDelaybias; + sp1.criticalNet = criticalNet; + + return delay; + } + + + /** + * Timing analysis for given concatenated path. The calculated delays are + * the sum of the delays for all half-operators in the path except for the + * last plus the delay of global nets for the last half-operator. + * + *

    The delay budget is the sum of the delay biases for all half + * operators times tau (the unit delay) plus the extra delays of all + * half-operators ending a non-final sizing paths plus the extra delay of + * an global net attached to the last half-operator of the last sizing + * path. + * + *

    This function modifies the cp1 argument. + *

      + *
    • delay is set to the calculated delay. + *
    • slack is set to the delay budget minus the + * calculated delay. + *
    • criticalNet is set to the last net in the path with + * the minimum slack + *
    + * + * @return the calculated maximum delay for the CatPath + **/ + public final double calculateDelay(CatPath cp1) + { + CellNet criticalNet = null; + double delay = 0.0; + double totalDelayBias = 0.0; + double extraDelay = 0.0; + double tau = tool.getOptionUnitDelay(); + double[] allDelays = null; + double[] allSlacks = null; + double[] allDelaybias = null; + + List/**/ sizingPaths = cp1.getCatPath(); + int numSizingPaths = sizingPaths.size(); + for (int iSizingPath = 0; iSizingPath < numSizingPaths; ++iSizingPath) { + SizingPath spa = (SizingPath) sizingPaths.get(iSizingPath); + double pathDelayBias = 0.0; + + List/**/ halfOperators = spa.getPath(); + final int numHalfOperators = halfOperators.size(); + for (int iHalfOp = 0; iHalfOp < numHalfOperators; ++iHalfOp) { + HalfOperator hoa = (HalfOperator) halfOperators.get(iHalfOp); + pathDelayBias += hoa.getDelayBias(); + if (iHalfOp < numHalfOperators - 1) { // not the last half-operator + CellNet cna = hoa.outputNet; + List/**/ globalNets = cna.getGlobalNets(); + + assert globalNets.size() == 1 + : "Internal cell net has more than 1 global net"; + + GlobalNet gna = (GlobalNet) globalNets.get(0); + + delay += gna.calculateDelay(hoa); + + } + else{ // the last half-operator + if (iSizingPath < numSizingPaths - 1) { // not the last sizing path + CellNet cna = spa.getEndNet(); + List/**/ globalNets = cna.getGlobalNets(); + + assert globalNets.size() == 1 + : "Internal cell net has more than 1 global net"; + + GlobalNet gna = (GlobalNet) globalNets.get(0); + + delay += gna.calculateDelay(hoa); + + extraDelay += getExtraDelay(hoa, gna, tau); + + totalDelayBias += pathDelayBias * + TransistorSizingTool.findDelayBias(gna, hoa); + } + else{ // the last sizing path + CellNet cna = cp1.getEndNet(); + + // delay budget before instance based delaybias + double maxDelay = Double.NEGATIVE_INFINITY; + double minSlack = Double.POSITIVE_INFINITY; + criticalNet = cna; + allDelays = new double[cna.getGlobalNets().size()]; + allSlacks = new double[cna.getGlobalNets().size()]; + allDelaybias = new double[cna.getGlobalNets().size()]; + int count = 0; + for (Iterator ita = cna.getGlobalNets().iterator(); + ita.hasNext(); ++count) { + GlobalNet gna = (GlobalNet)ita.next(); + allDelaybias[count] = + TransistorSizingTool.findDelayBias(gna, hoa); + final double biasedBudget = + (totalDelayBias + + pathDelayBias * allDelaybias[count]) * tau; + double partialBudget = biasedBudget + extraDelay; + cna = gna.getTopCellNet(); + + double g = gna.calculateDelay(hoa); + maxDelay = Math.max(maxDelay, g); + allDelays[count] = delay + g; + + double d = getExtraDelay(hoa, gna, tau); + allSlacks[count] = + partialBudget + d - allDelays[count]; + + if (allSlacks[count] < minSlack) { + minSlack = allSlacks[count]; + criticalNet = cna; + } + } + + delay += maxDelay; + } + } + } + } + + cp1.delay = allDelays; + cp1.slack = allSlacks; + cp1.delaybias = allDelaybias; + cp1.criticalNet = criticalNet; + + + return delay; + } + + + /** + * Computes the average delay of non-fragment paths in the cell type + * ct1. + **/ + public final double calculateDelay(CellType ct1) + { + int pathCount = 0; + double totalDelay = 0.0; + + if(ct1.getLevel() == 0){ + + for (Iterator ita = ct1.getSizingPaths().iterator(); + ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + + if(!spa.isFragment()){ + pathCount++; + totalDelay += calculateDelay(spa); + } + } + } + else{ + + for (Iterator ita = ct1.getSizingPaths().iterator(); + ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + + if(!cpa.isFragment()){ + calculateDelay(cpa); + } + } + for (Iterator ita = ct1.getCatPaths().iterator(); + ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + if(!cpa.isFragment()){ + + pathCount++; + totalDelay += calculateDelay(cpa); + } + } + + for (Iterator ita = ct1.getReducedCatPaths().iterator(); + ita.hasNext(); ) { + CatPath cpa = (CatPath)ita.next(); + if(!cpa.isFragment()){ + + calculateDelay(cpa); + } + } + } + + + return totalDelay / pathCount; + } + + + /** + * Computes the average delay of the cells (as computed by + * {@link #calculateDelay(CellType)}) in the design + * cd1. + **/ + public final double calculateDelay(CastDesign cd1) + { + if(design != cd1){ + System.out.println("Warning: circuit design for timing analysis has been changed from the initial setting."); + design = cd1; + tech = design.getTechnologyData(); + } + + int cellCount = 0; + double totalDelay = 0.0; + for (Iterator ita = design.allCellTypes.iterator(); ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + + cellCount++; + totalDelay += calculateDelay(cta); + } + + return totalDelay / cellCount; + } + + + /** Timing analysis for default design */ + public final double calculateDelay() + { + return calculateDelay(design); + } + + + /** Query cast extra_delay directive **/ + static double getExtraDelay(HalfOperator ho1, GlobalNet gn1, double tau) + { + CellNet cna = gn1.getTopCellNet(); + double tauInSpec = cna.container.getTau(); + double tauToUse = tauInSpec < 0.0 ? tau : tauInSpec; + double netExtraDelay; + if (ho1.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) + netExtraDelay = cna.getDownExtraDelay(); + else // PULL-UP + netExtraDelay = cna.getUpExtraDelay(); + return tauToUse * netExtraDelay / 100.0; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Floorplan.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Floorplan.java new file mode 100644 index 0000000000..f52fec6470 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Floorplan.java @@ -0,0 +1,395 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TreeSet; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellTypeProcessor; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.geometry.BoundingBox; +import com.avlsi.geometry.Point; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.tools.jauto.CellHierarchyDumpParser; +import com.avlsi.util.container.Pair; +import com.avlsi.util.text.StringUtil; + +/** + * Class for parsing floorplanning information generated by + * //depot/sw/cad/external-tools-integration/cadence/virtuoso/main/skill/layout/instancesfile/instance.il. + * + * @author Aaron Denney + * @version $Date$ + **/ + +public final class Floorplan { + public static final class Exception extends RuntimeException { + public Exception(final String message, final Throwable cause) { + super(message, cause); + } + public Exception(final String message) { + super(message); + } + } + + public static final String EXTENSION = ".instances"; + private final File directory; + private final CDLNameInterface forward, reverse; + private final SortedSet fileCache; + + /** + * Constructor. + **/ + Floorplan(String directoryName) { + this.directory = new File(directoryName); + if (!this.directory.isDirectory()) { + throw new Exception("Floorplanning directory " + directoryName + " is not a directory"); + } + this.forward = new CadenceNameInterface(); + this.reverse = new CadenceReverseNameInterface(); + this.fileCache = new TreeSet(); + directory.listFiles(new FilenameFilter() { + public boolean accept(final File dir, final String name) { + final int index = name.lastIndexOf(EXTENSION); + if (index > -1) { + final String cell = name.substring(0, index); + fileCache.add(cell); + } + return false; + } + }); + + } + + void process(final CellType ct) { + process(ct, new HashSet()); + } + + private String exceptionMessage(final Throwable e) { + final StringBuffer sb = new StringBuffer(); + final String message = e.getMessage(); + if (message == null || message.equals("")) { + sb.append(e.toString()); + } else { + sb.append(message); + } + if (e.getCause() != null) { + sb.append(": "); + sb.append(exceptionMessage(e.getCause())); + } + return sb.toString(); + } + + /* This code is similar to CellType.walkOnce, but that method doesn't + * easily allow one to skip a portion of the instantiation tree. */ + private void process(final CellType ct, final Set seen) { + if (!seen.add(ct) || ct.isInternalEnv()) return; + + // skip over top level $env cell + if (ct != ct.design.getTopLevelCell()) + try { + readHierarchy(ct); + } catch (Exception e) { + System.err.println(exceptionMessage(e)); + } + + for (Iterator i = ct.getAllSubcellConnections().iterator(); + i.hasNext(); ) { + final CellType c = ((ConnectionInfo) i.next()).child; + process(c, seen); + } + } + + /** + * Return the name of the instance file for the given cell type. + **/ + public static String getInstanceFilename(final String typeName) + throws CDLRenameException { + final CDLNameInterface forward = new CadenceNameInterface(); + return forward.renameCell(typeName) + EXTENSION; + } + + /** + * Returns a File representing the instance file of the given + * cell type. It first tries to find the file in the cache of the + * directory listing. If it's not found there, it falls back to try + * reading the instance file of the minimum lexigraphic subtype which has + * the same module name as typeName, and a warning is emitted. + * + * @param typeName which cell's instance file to read. + * @return File representing the instance file, or null if no + * such instance file exists. + * @throws CDLRenameException if typeName cannot be converted + * to a Cadence name. + **/ + private File getInstanceFile(final String typeName) + throws CDLRenameException { + final String name = forward.renameCell(typeName); + if (fileCache.contains(name)) { + return new File(directory, name + EXTENSION); + } else { + final int index = name.lastIndexOf('.'); + if (index < 0) return null; + + final String base = name.substring(0, index + 1); + final SortedSet subset = + fileCache.subSet(base + Character.MIN_VALUE, + base + Character.MAX_VALUE); + if (subset.isEmpty()) { + return null; + } else { + final File f = + new File(directory, (String) subset.first() + EXTENSION); + System.out.println("Warning: Falling back to reading " + f + " for cell " + typeName); + return f; + } + } + } + + /** + * Read instance file for the given CellType and fill in the + * xOffset, yOffset, and orientation fields of the appropriate + * ConnectionInfos. + * + * @param ct for which CellType to fill in data + * @throws Floorplan.Exception if anything goes wrong + **/ + private void readHierarchy(final CellType ct) { + final Set subcells = new HashSet(); + for (ConnectionInfo ci : ct.getAllSubcellConnections()) { + if (!ci.child.isInternalEnv()) subcells.add(ci); + } + final Set extras = new HashSet(); + final Set extraPins = new HashSet(); + final Collection mismatch = new ArrayList(); + + readHierarchy(ct.typeName, new SubcellProcessor() { + public void process(BoundingBox bBox) { + final Point ll = bBox.getLowerLeft(); + final Point ur = bBox.getUpperRight(); + ct.xSize = (float) (ur.getX() - ll.getX()); + ct.ySize = (float) (ur.getY() - ll.getY()); + if(ct.getLevel() == 0) { //do this only for leaf cells + for (CellType.PortInfoIterator i = ct.getPorts(); i.hasNext();) { + CellType.PortInfo pi = i.next(); + //The pin bbox are referenced from the center + //Hence you cannot use ll and ur from above. + BoundingBox NewbBox = new BoundingBox(-(ct.xSize/2), + -(ct.ySize/2), + (ct.xSize/2), + (ct.ySize/2)); + pi.bBox = NewbBox; + } + } + } + + public void process(String pinName, + BoundingBox bBox) { + if(ct.getLevel() > 0) { //do this only for cells that are not leaf cells + CellType.PortInfo pi = ct.getPortInfoForPinNamed(pinName); + if (pi == null) { + extraPins.add(pinName); + } else { + pi.bBox = bBox; + } + } + } + + public void process(String typeName, + String instanceName, + int orientation, + BoundingBox bBox) { + final HierName hName; + try { + hName = HierName.makeHierName(instanceName, '.'); + } catch (InvalidHierNameException e) { + throw new Exception("Error constructing HierName from " + instanceName, e); + } + + final ConnectionInfo ci = ct.getSubcellNamed(hName); + if (ci == null) { + extras.add(new Pair(typeName, instanceName)); + return; + } + subcells.remove(ci); + + if (!typeName.equals(ci.child.typeName)) + mismatch.add(new Pair(typeName, ci)); + + /* Set the orientation of this instance */ + ci.orientation = orientation; + + /* Use the center of the bounding box as the location of + * this instance */ + final Point ll = bBox.getLowerLeft(); + final Point ur = bBox.getUpperRight(); + ci.xOffset = (float) (ll.getX() + ur.getX()) / 2; + ci.yOffset = (float) (ll.getY() + ur.getY()) / 2; + } + }); + if (!extras.isEmpty() || !subcells.isEmpty() || !mismatch.isEmpty() || + !extraPins.isEmpty()) { + System.err.println("In geometry information for cell " + ct.typeName + ": "); + if (!extras.isEmpty()) { + System.err.println(" Extra:"); + for (Iterator i = extras.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + System.err.println(" " + p.getSecond() + "(" + p.getFirst() + ")"); + } + } + if (!subcells.isEmpty()) { + System.err.println(" Missing:"); + for (Iterator i = subcells.iterator(); i.hasNext(); ) { + final ConnectionInfo ci = (ConnectionInfo) i.next(); + System.err.println(" " + ci.nameInParent + "(" + ci.child.typeName + ")"); + } + } + if (!mismatch.isEmpty()) { + System.err.println(" Mismatch [instance(dfII type/CAST type)]:"); + for (Iterator i = mismatch.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final ConnectionInfo ci = (ConnectionInfo) p.getSecond(); + System.err.println(" " + ci.nameInParent + "(" + p.getFirst() + + "/" + ci.child.typeName + ")"); + } + } + if (!extraPins.isEmpty()) { + System.err.println(" Invalid pins: "); + for (String pin : extraPins) { + System.err.println(" " + pin); + } + } + System.err.println(); + } + } + + /** + * Read the instances file associated with a given cell, and call the given + * SubcellProcessor with cell and instance names already + * translated back to CAST. + * + * @param cellType which cell's instance file to parse + * @param proc callback object to process parsed data + * + * @throws Floorplan.Exception if anything goes wrong. + **/ + void readHierarchy(final String cellType, final SubcellProcessor proc) { + final File instances; + try { + instances = getInstanceFile(cellType); + } catch (CDLRenameException e) { + throw new Exception("Cannot translate cell name " + cellType, e); + } + + if (instances == null) { + throw new Exception("No geometry information found for cell " + cellType); + } + + final FileReader in; + try { + in = new FileReader(instances); + } catch (FileNotFoundException e) { + throw new Exception("Cannot read geometry information from " + instances, e); + } + + try { + readHierarchy(in, reverse, proc); + } catch (Exception e) { + throw new Exception("Cannot parse " + instances + " for type " + cellType, e); + } + + try { + in.close(); + } catch (IOException e) { + throw new Exception("Cannot close instance file " + instances, e); + } + } + + public static void readHierarchy(final Reader in, + final SubcellProcessor proc) { + readHierarchy(in, new CadenceReverseNameInterface(), proc); + } + + public static void readHierarchy(final Reader in, + final CDLNameInterface reverse, + final SubcellProcessor proc) { + final CellHierarchyDumpLexer lexer = new CellHierarchyDumpLexer(in); + final CellHierarchyDumpParser parser = + new CellHierarchyDumpParser(lexer); + try { + parser.goal(new SubcellProcessor() { + public void process(BoundingBox bBox) { + proc.process(bBox); + } + + public void process(String pinName, + BoundingBox bBox) { + try { + pinName = reverse.renameNode(pinName); + } catch (CDLRenameException e) { + throw new Exception("Error translating names while reading geometry information", e); + } + proc.process(pinName, bBox); + } + + public void process(String typeName, + String instanceName, + int orientation, + BoundingBox bBox) { + try { + typeName = reverse.renameCell(typeName); + // skip the renaming process, if the instance contains + // the pipe character, because the renamer does not + // handle it, and since it only occurs when we are + // interfacing to a synchronous flow through wrappers, + // which is rare, there is little benefit in adding the + // transformation to the renamers. See bug 6290 for + // more information on this special case. + if (instanceName.indexOf('|') == -1) + instanceName = + reverse.renameSubCellInstance(instanceName); + } catch (CDLRenameException e) { + throw new Exception("Error translating names while reading geometry information", e); + } + proc.process(typeName, instanceName, orientation, bBox); + } + }); + } catch (java.lang.Exception e) { + throw new Exception("Error parsing geometry information", e); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionSimplifier.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionSimplifier.java new file mode 100644 index 0000000000..1459758cde --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionSimplifier.java @@ -0,0 +1,248 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.jauto; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +public class FunctionSimplifier +{ + + /** + * This class cannot be instantiated. + **/ + private FunctionSimplifier() { + throw new AssertionError(); + } + + + // Not yet used. + public static List/*>*/ normalize + (List/*>*/ functions) + { + List/*>*/ normalizedFunctions = + new ArrayList/*>*/(); + + for (Iterator ita = functions.iterator(); ita.hasNext(); ) { + List/**/ function = (List) ita.next(); + int numTerms = function.size(); + + assert numTerms >= 3 + : "function must contain at least one function term"; + + List/**/ normalizedFunction = + new ArrayList/**/(numTerms); + + FunctionTerm ftma = (FunctionTerm) function.get(0); + if (ftma.type == FunctionTerm.Type.OBJECTIVE) { + // Objective, do not normalize + for (Iterator itb = function.iterator(); itb.hasNext(); ) { + FunctionTerm ftmb = (FunctionTerm)itb.next(); + normalizedFunction.add(new FunctionTerm(ftmb)); + } + } + else{ // Constraint, normalize to delay budget + FunctionTerm ftmb = + (FunctionTerm) function.get(numTerms - 1); + assert ftmb.type == FunctionTerm.Type.CONSTANT + : "Delay budget must be constant"; + double delayBudget = ftmb.coefficient; + assert delayBudget != 0 : "Zero delay budget"; + + for (int i = 0; i < numTerms; ++i) { + ftmb = (FunctionTerm) function.get(i); + FunctionTerm ftmc = new FunctionTerm(ftmb); + ftmc.coefficient /= delayBudget; + normalizedFunction.add(ftmc); + } + } + + normalizedFunctions.add(normalizedFunction); + } + + return normalizedFunctions; + } + + + public static List/**/ simplifyOne + (List/**/ function) { + int numTerms = function.size(); + + assert numTerms >= 3 + : "function must contain at least one function term"; + + List/**/ simplifiedFunction = + new ArrayList/**/(numTerms); + double constantCoeff = 0.0; + + for (int i = 1; i < numTerms - 1; ++i) { + FunctionTerm ftma = (FunctionTerm) function.get(i); + int termType = ftma.type; + + assert termType != FunctionTerm.Type.OBJECTIVE && + termType != FunctionTerm.Type.CONSTRAINT_LESS_THAN && + termType != FunctionTerm.Type.CONSTRAINT_EQUALS + : "Function terms of type OBJECTIVE, CONSTRAINT_LESS_THAN " + + "or CONSTRAINT_EQUALS are not allowed in this region of " + + "the function"; + if (termType == FunctionTerm.Type.CONSTANT) { + constantCoeff += ftma.coefficient; + } + else{ + sortedCopyInsert(simplifiedFunction, ftma); + } + } + + assert ((FunctionTerm) function.get(0)).type == + FunctionTerm.Type.CONSTRAINT_LESS_THAN || + ((FunctionTerm) function.get(0)).type == + FunctionTerm.Type.CONSTRAINT_EQUALS || + ((FunctionTerm) function.get(0)).type == + FunctionTerm.Type.OBJECTIVE; + simplifiedFunction + .add(0, new FunctionTerm((FunctionTerm) function.get(0))); + + assert ((FunctionTerm) function.get(numTerms - 1)).type == + FunctionTerm.Type.CONSTANT; + FunctionTerm ftmb = + new FunctionTerm((FunctionTerm) function.get(numTerms-1)); + ftmb.coefficient -= constantCoeff; + simplifiedFunction.add(ftmb); + + return simplifiedFunction; + } + + public static List/*>*/ simplify + (List/*>*/ functions) + { + List/*>*/ simplifiedFunctions = + new ArrayList/*>*/(functions.size()); + for (Iterator ita = functions.iterator(); ita.hasNext(); ) { + List/**/ function = (List) ita.next(); + List/**/ simplifiedFunction = + simplifyOne(function); + + if (simplifiedFunction.size() > 2) { + // Ignore "constant constraint" introduced by + // the fixed-size cells + simplifiedFunctions.add(simplifiedFunction); + } + else{ + // REVIEW: What if ignored constraint is unsatisfiable? + if(DebugOption.printLevel <= 2){ + System.out.println("Note: Constant constraint thrown out, possibly due to fixed-size cells"); + System.out.println("Constraint value: " + + ((FunctionTerm) simplifiedFunction + .get(simplifiedFunction + .size() - 1)) + .coefficient); + } + } + } + + return simplifiedFunctions; + } + + + private static void sortedCopyInsert(List/**/ function, + FunctionTerm ftm1) + { + int numTerms = function.size(); + for (int i = 0; i < numTerms; ++i) { + FunctionTerm ftma = (FunctionTerm) function.get(i); + final int c = compare(ftma, ftm1); + + if (c == 0) { + ftma.coefficient += ftm1.coefficient; + + return; + } + + if (c > 0) { + function.add(i, new FunctionTerm(ftm1)); + + return; + } + } + + function.add(new FunctionTerm(ftm1)); + } + + + private static int compare(FunctionTerm ftm1, FunctionTerm ftm2) + { + int type1 = ftm1.type; + int type2 = ftm2.type; + + final int c = type1 - type2; + if (c != 0) + return c; + + if (type1 == FunctionTerm.Type.CONSTANT) { + double coef1 = ftm1.coefficient; + double coef2 = ftm2.coefficient; + + if(coef1 < coef2){ + return -1; + } + + if(coef1 > coef2){ + return 1; + } + + return 0; + } + + String vn11 = ftm1.variableName_1; + String vn21 = ftm2.variableName_1; + + if (type1 == FunctionTerm.Type.VAR || + type1 == FunctionTerm.Type.ONE_OVER_VAR) + return vn11.compareTo(vn21); + + if (type1 == FunctionTerm.Type.VAR_OVER_VAR) { + int i = vn11.compareTo(vn21); + + if(i != 0){ + return i; + } + + String vn12 = ftm1.variableName_2; + String vn22 = ftm2.variableName_2; + return vn12.compareTo(vn22); + } + + throw new AssertionError("Error: Unknown type of function term!"); + } + + + public static String getDerivativeString(List/**/ function, + String var) + { + StringBuffer sb = new StringBuffer(); + int maxTerm = function.size() - 1; + for (int i = 1; i < maxTerm; ++i) { + FunctionTerm ftma = (FunctionTerm) function.get(i); + + String termDerivative = ftma.getDerivativeString(var); + + if (!termDerivative.equals("0")) { + sb.append(termDerivative); + if (i > 1) { + // Not the first term + sb.append("+ "); + } + } + } + + return sb.toString(); + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionTerm.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionTerm.java new file mode 100644 index 0000000000..a9e64a214b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/FunctionTerm.java @@ -0,0 +1,373 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.jauto; + +import com.avlsi.util.text.NumberFormatter; + + +public class FunctionTerm +{ + public static final class Type { + + private Type() { } + + public static final int OBJECTIVE = 1; + public static final int CONSTRAINT_LESS_THAN = 2; + public static final int CONSTANT = 3; + public static final int VAR = 4; + public static final int ONE_OVER_VAR = 5; + public static final int VAR_OVER_VAR = 6; + public static final int CONSTRAINT_EQUALS = 7; + } + + public int type; + /* + Possible term types values: + + 1: OBJECTIVE - only used in the first term of a list to indicate the list as an objective function + The last term is always zero in an objective function. + Only valid as the 0th entry in a List. + 2: CONSTRAINT_LESS_THAN - only used in the first term of a list to indicate the list as a constraint + Only valid as the 0th entry in a List. + Constraint is: + List terms; + (\sum int i; 1 <= i && i < terms.size() - 1; + terms.get(i)) <= terms.get(terms.size() - 1) + Where terms.get(terms.size() - 1).type == CONSTANT + 3: CONSTANT - just a constant number + Not valid as the 0th entry in a List. + 4: VAR - term in the form of coefficient * variableName_1 + Not valid as the 0th entry in a List. + 5: ONE_OVER_VAR - term in the form of coefficient * (1 / variableName_1) + Not valid as the 0th entry in a List. + 6: VAR_OVER_VAR - term in the form of coefficient * (variableName_1 / variableName_2) + Not valid as the 0th entry in a List. + 7: CONSTRAINT_EQUALS - constrains variable_1 to be equal to + an expression + Constraint is: + List terms; + (\sum int i; 1 <= i && i < terms.size(); terms.get(i)) + == terms.get(0).variable_1 + */ + + public String variableName_1; + public String variableName_2; + + public double coefficient; + + + public int setType(int t) + { + assert t >= Type.OBJECTIVE && t <= Type.CONSTRAINT_EQUALS + : "invalid type of FunctionTerm"; + + type = t; + + return type; + } + + + public int getType() + { + return type; + } + + + public String setVariableName_1(String s) + { + assert s.length() <= 10 + : "variable name must NOT have more than 10 characters"; + + variableName_1 = s; + + return variableName_1; + } + + + public String getVariableName_1() + { + return variableName_1; + } + + + public String setVariableName_2(String s) + { + assert s.length() <= 10 + : "variable name must NOT have more than 10 characters"; + + variableName_2 = s; + + return variableName_2; + } + + + public String getVariableName_2() + { + return variableName_2; + } + + + public double setCoefficient(double d) + { + coefficient = d; + + return coefficient; + } + + + public double getCoefficient() + { + return coefficient; + } + + + public FunctionTerm(final int type, + final String variableName_1, + final String variableName_2, + final double coefficient) { + this.type = type; + this.variableName_1 = variableName_1; + this.variableName_2 = variableName_2; + this.coefficient = coefficient; + } + + + // constructor 1 + public FunctionTerm() + { + this(Type.CONSTANT, "", "", 0.0); + } + + // constructor 2 + public FunctionTerm(FunctionTerm ft) + { + this(ft.getType(), ft.getVariableName_1(), ft.getVariableName_2(), + ft.getCoefficient()); + } + + public FunctionTerm(final double coefficient) { + this(Type.CONSTANT, "", "", coefficient); + } + + public FunctionTerm(final int type, + final String variableName_1, + final double coefficient) { + this(type, variableName_1, "", coefficient); + } + + // dump out infomation for debug + public void print() + { + System.out.println("type: " + type); + System.out.println("var1: " + variableName_1); + System.out.println("var2: " + variableName_2); + System.out.println("coef: " + coefficient); + } + + + /** + * Human readable string. + **/ + public String toString() + { + /* + String s = "type: " + type + "\n"; + s += "var1: " + variableName_1 + "\n"; + s += "var2: " + variableName_2 + "\n"; + s += "coef: " + coefficient + "\n"; + */ + + switch(type){ + case Type.CONSTANT: + return NumberFormatter.format(coefficient, 6); + + case Type.VAR: + return NumberFormatter.format(coefficient, 6) + " * " + + variableName_1; + + case Type.ONE_OVER_VAR: + return NumberFormatter.format(coefficient, 6) + " / " + + variableName_1; + + case Type.VAR_OVER_VAR: + return NumberFormatter.format(coefficient, 6) + " * " + + variableName_1 + " / " + + variableName_2; + + default: throw new AssertionError + ("Unknown FunctionTerm type: " + type); + } + } + + + /** + * Function term in postfix notation for CG solver. + **/ + public String toStringPostfix(String variablePrefix) + { + switch(type){ + case Type.CONSTANT: + return NumberFormatter.format(coefficient, 6); + + case Type.VAR: + if (coefficient == 0.0) + return "0"; + else if (coefficient == 1.0) + return variablePrefix + variableName_1; + else + return NumberFormatter.format(coefficient, 6) + " " + + variablePrefix + variableName_1 + " *"; + + case Type.ONE_OVER_VAR: + if (coefficient == 0.0) + return "0"; + else + return NumberFormatter.format(coefficient, 6) + " " + + variablePrefix + variableName_1 + " /"; + + case Type.VAR_OVER_VAR: + if (coefficient == 0.0) + return "0"; + else if (coefficient == 1.0) + return variablePrefix + variableName_1 + " " + + variablePrefix + variableName_2 + " /"; + else + return NumberFormatter.format(coefficient, 6) + " " + + variablePrefix + variableName_1 + " " + + variablePrefix + variableName_2 + " / *"; + + default: throw new AssertionError(); + } + } + + String toStringPostfix() { + return toStringPostfix(""); + } + + /** + * Function term in notation for LP solver. Omits the * for + * multiplication. + **/ + public String toStringLP() { + switch(type){ + case Type.CONSTANT: + return NumberFormatter.format(coefficient, 6); + + case Type.VAR: + if (coefficient == 0.0) + return "0"; + else if (coefficient == 1.0) + return variableName_1; + else + return NumberFormatter.format(coefficient, 6) + " " + + variableName_1; + + case Type.ONE_OVER_VAR: + if (coefficient == 0.0) + return "0"; + else + return NumberFormatter.format(coefficient, 6) + " / " + + variableName_1; + + case Type.VAR_OVER_VAR: + if (coefficient == 0.0) + return "0"; + else if (coefficient == 1.0) + return variableName_1 + " / " + + variableName_2; + else + return NumberFormatter.format(coefficient, 6) + " " + + variableName_1 + " / " + + variableName_2; + + default: throw new AssertionError(); + } + } + + + /** + * Derivative of function term with respect to var1 + * in postfix notation for CG solver. + **/ + public String getDerivativeString(String var1) + { + switch(type){ + case Type.CONSTANT: + return "0"; + + case Type.VAR: + if(var1.equals(variableName_1)){ + return NumberFormatter.format(coefficient, 6); + } + else{ + return "0"; + } + + case Type.ONE_OVER_VAR: + if(var1.equals(variableName_1)){ + return NumberFormatter.format(-coefficient, 6) + " " + + variableName_1 + " " + + variableName_1 + " * /"; + } + else{ + return "0"; + } + + case Type.VAR_OVER_VAR: + if(var1.equals(variableName_1)){ + return NumberFormatter.format(coefficient, 6) + " " + + variableName_2 + " /"; + } + else{ + if(var1.equals(variableName_2)){ + return NumberFormatter.format(-coefficient, 6) + " " + + variableName_1 + " " + + variableName_2 + " " + + variableName_2 + " * / *"; + } + else{ + return "0"; + } + } + + default: throw new AssertionError(); + } + } + + private static FunctionTerm multiply(final FunctionTerm ftm1, + final FunctionTerm ftm2) { + final int t1 = ftm1.getType(); + final int t2 = ftm2.getType(); + final FunctionTerm result; + if (t1 == Type.CONSTANT) { + result = new FunctionTerm(ftm2); + } else if (t2 == Type.CONSTANT) { + result = new FunctionTerm(ftm1); + } else if (t1 == Type.VAR && t2 == Type.ONE_OVER_VAR) { + result = new FunctionTerm(ftm1); + result.setType(Type.VAR_OVER_VAR); + result.setVariableName_2(ftm2.getVariableName_1()); + } else if (t2 == Type.VAR && t1 == Type.ONE_OVER_VAR) { + result = new FunctionTerm(ftm2); + result.setType(Type.VAR_OVER_VAR); + result.setVariableName_2(ftm1.getVariableName_1()); + } else { + throw new RuntimeException("Can't multiply " + ftm1 + + " and " + ftm2); + } + + result.coefficient = ftm1.coefficient * ftm2.coefficient; + + return result; + } + + public FunctionTerm multiply(final FunctionTerm other) { + return multiply(this, other); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GenerateChargeSharingTests.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GenerateChargeSharingTests.java new file mode 100644 index 0000000000..75e90a5708 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GenerateChargeSharingTests.java @@ -0,0 +1,997 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.impl.DirectiveSource; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.CastDesign; +import com.avlsi.fast.CellType; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.MergeDirective; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.io.FileSearchPath; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgFormatException; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.InvalidCommandLineArgException; +import com.avlsi.util.cmdlineargs.MissingCommandLineArgException; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.NaturalOrderComparator; +import com.avlsi.util.text.StringUtil; + +public class GenerateChargeSharingTests { + + /** + * This class cannot be instantiated. + **/ + private GenerateChargeSharingTests() { + throw new AssertionError(); + } + + /** + * Returns the intersection of 2 sets. + * @param s1 A set. + * @param s2 A set. + * + * @return The intersection of s1 and s2. + **/ + private static Set intersect(final Set s1, final Set s2) { + final HashSet set = new HashSet(); + set.addAll(s1); + set.retainAll(s2); + return set; + } + + private static int findLargestShareNumber(final CellInterface ci) { + + final Map m = + DirectiveUtils.getPrsDirective(ci, DirectiveConstants.SHARED, + DirectiveConstants.HALFOP_TYPE); + int max = 10000; + for (Iterator i = m.values().iterator(); i.hasNext(); ) { + final Integer share = (Integer) i.next(); + max = Math.max(max, share.intValue()); + } + return max; + } + + /** + * Partition the nodes of interest into groups that share transistors. + * @param graph The transistor NetGraph. + * @param interest The nodes of interest. + * + * @return An AliasedMap with nodes that share transistors represented as + * aliases. + **/ + private static AliasedMap getSharingGroups(final NetGraph graph, + final Set interest) { + final AliasedMap map = + new AliasedMap( + new AliasedMap.MergeFunction() { + public Object merge(Object o1, Object o2) + throws AliasedMap.MergeFailedException { + final Set s = new HashSet(); + s.addAll((Set) o1); + s.addAll((Set) o2); + return s; + } + }, + new NaturalOrderComparator() + ); + for (Iterator i = interest.iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + final NetGraph.NetNode node = graph.findNetNode(name); + assert node != null : "Cannot find " + name + " in NetGraph " + graph; + final Set edgeSet = new HashSet(); + for (Iterator j = node.getPaths().iterator(); j.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) j.next(); + edgeSet.addAll(path.getEdges()); + } + try { + map.addData(name, edgeSet); + for (Iterator j = map.getCanonicalKeys(); j.hasNext(); ) { + final Object key = j.next(); + if (key == name) continue; + + final Set old = (Set) map.getValue(key); + if (!intersect(old, edgeSet).isEmpty()) { + map.makeEquivalent(key, name); + break; + } + } + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionError("Merge failed. Cannot happen!"); + } + } + return map; + } + + private static String halfopstr(final HierName name, final Boolean dir) { + final String str = name.getCadenceString(); + return dir == null ? str: str + (dir.booleanValue() ? "+" : "-"); + } + + private static class GroupInfo { + public final NetGraph graph; + public final Group group; + public final Pair stat; + private final Set pathSet; + public GroupInfo(final NetGraph graph, final Group group) { + this.graph = graph; + this.group = group; + this.stat = getStatistic(graph, group); + // the default compare method for a NetPath does not take into + // account the ordering of the gates on the path, which is exactly + // what we do care about + this.pathSet = new TreeSet(new Comparator() { + public int compare(final Object o1, final Object o2) { + final NetGraph.NetPath p1 = (NetGraph.NetPath) o1; + final NetGraph.NetPath p2 = (NetGraph.NetPath) o2; + int i = p1.compareTo(p2); + if (i != 0) return i; + for (Iterator i1 = p1.getGatesArrayList().iterator(), + i2 = p2.getGatesArrayList().iterator(); + i1.hasNext() && i2.hasNext(); ) { + final HierName h1 = (HierName) i1.next(); + final HierName h2 = (HierName) i2.next(); + i = h1.compareTo(h2); + if (i != 0) return i; + } + return 0; + } + }); + for (Iterator i = group.iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + final NetGraph.NetNode node = graph.findNetNode(name); + assert node != null : "Cannot find " + name + " in NetGraph " + graph; + pathSet.addAll(node.getPaths()); + } + } + public boolean equals(final Object o) { + boolean result = false; + if (o instanceof GroupInfo) { + final GroupInfo gi = (GroupInfo) o; + return stat.equals(gi.stat) && pathSet.equals(gi.pathSet); + } + return result; + } + public String toString() { + return "GroupInfo: group = " + outputGroup(group) + + " pathSet = " + pathSet; + } + } + + /** + * Represents a set of nodes that are in a single symmetrize group. + **/ + private static class Group extends ArrayList { + public Group(final HierName name) { + assert name != null; + add(name); + } + public Group(final Group group) { + super(group); + } + private void addDirectives(final DirectiveSource source, + final Collection directives, + final String dir, + final Boolean updn, + final Integer val, + final Object sval) { + for (Iterator i = iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + source.definition(dir, DirectiveConstants.HALFOP_TYPE, + makeHalfOp(name, updn), val); + directives.add(dir + "(" + halfopstr(name, updn) + ")=" + sval); + } + } + public void addSharedDirectives(final DirectiveSource source, + final Collection directives, + final String dir, + final Boolean updn, + final Integer val) { + addDirectives(source, directives, dir, updn, val, val); + } + public void addSymmetrizeDirectives(final DirectiveSource source, + final Collection directives, + final String dir, + final Boolean updn, + final Integer val) { + if (val != null) + addDirectives(source, directives, dir, updn, val, + symnams.get(val)); + } + } + + private static int shareId = 10000; + private static class Sharing extends ArrayList { + public Sharing(final Group group) { + assert group != null; + add(group); + } + public Sharing(final Sharing sharing) { + super(sharing); + } + public void addSharedDirectives(final DirectiveSource source, + final Collection directives) { + for (Iterator i = iterator(); i.hasNext(); ) { + final Group group = (Group) i.next(); + group.addSharedDirectives(source, directives, + DirectiveConstants.SHARED, null, + new Integer(shareId++)); + } + } + public void addSymmetrizeDirectives(final DirectiveSource source, + final Collection directives, + final Integer up, + final Integer dn) { + for (int i = 0; i < size(); ++i) { + final Group group = (Group) get(i); + if (up.equals(dn)) { + group.addSymmetrizeDirectives(source, directives, + DirectiveConstants.SYMMETRIZE, + null, (Integer) up); + } else { + group.addSymmetrizeDirectives(source, directives, + DirectiveConstants.SYMMETRIZE, + Boolean.TRUE, (Integer) up); + group.addSymmetrizeDirectives(source, directives, + DirectiveConstants.SYMMETRIZE, + Boolean.FALSE, (Integer) dn); + } + } + } + } + + /** + * Return all possible ways to break apart an array of nodes. + * + * @param names Names of the nodes to group. + * @param index The index to start at. + * @return A list of sharings. + **/ + private static List getPossibleSharing(final HierName[] names, + final int index) { + assert names.length > 0; + final List result = new ArrayList(); + if (names.length == index + 1) { + result.add(new Sharing(new Group(names[index]))); + } else { + final List sharings = getPossibleSharing(names, index + 1); + for (Iterator i = sharings.iterator(); i.hasNext(); ) { + final Sharing sharing = (Sharing) i.next(); + for (int j = 0; j < sharing.size(); ++j) { + final Sharing added = new Sharing(sharing); + final Group g = new Group((Group) added.get(j)); + g.add(names[index]); + added.set(j, g); + result.add(added); + } + final Sharing seperate = new Sharing(sharing); + seperate.add(new Group(names[index])); + result.add(seperate); + } + } + return result; + } + + private static List getPossibleSharing(final Iterator aliases) { + final Set s = new HashSet(); + while (aliases.hasNext()) { + s.add(aliases.next()); + } + return getPossibleSharing((HierName[]) s.toArray(new HierName[0]), 0); + } + + /** + * Get sharings of the groups to test. All groups are tested at least + * once, and as few sharings are tested as possible. + * + * @param sharings All possible sharings. + * @return List of sharings that test all groups. + **/ + private static List getConfigurations(final List sharings) { + /* Only sharings with 2 groups matter, since all other sharings can be + * constructed from them. */ + final List result = new ArrayList(); + for (Iterator i = sharings.iterator(); i.hasNext(); ) { + final Sharing s = (Sharing) i.next(); + if (s.size() <= 2) result.add(s); + } + return result; + } + + private static HierName Vdd = HierName.makeHierName("Vdd"); + private static HierName GND = HierName.makeHierName("GND"); + private static HierName _RESET = HierName.makeHierName("_RESET"); + + public static class Option { + public final double cutoff, cutoffmin; + public final Double diffusionLength, mfggrid; + public final String staticizer, weakInverter, smallInverter; + public final String lengthUnit, hsizes, outdir; + public final String gates; + public final float tau; + public final TechnologyData tdata; + public final Map stackMap; + public final float minWidth; + private Double getDouble(final CommandLineArgs args, final String arg, + final Double def) { + final String str = args.getArgValue(arg, null); + if (str == null) return def; + else return Double.valueOf(str); + } + private double getDouble(final CommandLineArgs args, final String arg, + final double def) { + final String str = args.getArgValue(arg, null); + if (str == null) return def; + else return Double.parseDouble(str); + } + private float getFloat(final CommandLineArgs args, final String arg, + final float def) { + final String str = args.getArgValue(arg, null); + if (str == null) return def; + else return Float.parseFloat(str); + } + private int getInteger(final CommandLineArgs args, final String arg, + final int def) { + final String str = args.getArgValue(arg, null); + if (str == null) return def; + else return Integer.parseInt(str); + } + public Option(final CommandLineArgs args, final CastFileParser cfp, + final Cadencize cad) + throws CommandLineArgFormatException, + InvalidCommandLineArgException, + MissingCommandLineArgException { + cutoff = getDouble(args, "cutoff", Double.MAX_VALUE); + cutoffmin = getDouble(args, "cutoffmin", 0); + diffusionLength = getDouble(args, "diffusionLength", null); + mfggrid = getDouble(args, "mfggrid", null); + staticizer = args.getArgValue("staticizer", null); + weakInverter = args.getArgValue("weak-inverter", null); + smallInverter = args.getArgValue("small-inverter", null); + lengthUnit = args.getArgValue("lengthUnit", "u"); + hsizes = args.getArgValue("hsizes", "hsizes.out"); + outdir = args.getArgValue("outdir", "."); + gates = args.getArgValue("gates", null); + tau = getFloat(args, "tau", 40); + tdata = new TechnologyData(args); + + final String pStacks = args.getArgValue("pStacks", null); + final String nStacks = args.getArgValue("nStacks", null); + if (pStacks != null && nStacks != null) { + stackMap = new HashMap(); + Jauto.makeStackMap(stackMap, new Integer(DeviceTypes.P_TYPE), + cfp, pStacks, Vdd, GND, cad); + Jauto.makeStackMap(stackMap, new Integer(DeviceTypes.N_TYPE), + cfp, nStacks, Vdd, GND, cad); + } else { + stackMap = null; + } + minWidth = getFloat(args, "minGateWidth", Float.NaN); + } + } + + /** + * Invoke Jauto and return the final NetGraph. + **/ + private static NetGraph runJauto(final CastFileParser cfp, + final CellInterface cell, + final String outdir, + final String outFile, + final Cadencize cad, + final Reader hsizes, + final Option opt) throws Exception { + final CastDesign design = new CastDesign(cell, Vdd, GND, _RESET, opt.tau, opt.tdata, cfp); + final JautoMessageCenter jmc = new JautoMessageCenter(); + design.setMessageCenter(jmc); + final CellType top = design.getTopLevelCell(); + final String[] gates = opt.gates == null ? new String[0] : StringUtil.split(opt.gates, ':'); + final CellType newtop = top.instanceMinimalSubTypes(CastDesign.TRANSISTORS, + opt.staticizer, opt.weakInverter, opt.smallInverter, gates, cfp); + GlobalNet.generateGlobalNets(newtop, new ArrayList()); + Jauto.readHalfOperatorSize(hsizes, design, 1); + Jauto.setHalfOperatorSize(design); + SizeStaticizers.sizeStaticizers(design); + Jauto.writeOut(newtop, + outdir, + cell.getFullyQualifiedType(), + outFile, + opt.cutoff, + opt.cutoffmin, + opt.diffusionLength == null ? new Double(opt.tdata.getDefaultDiffusionLength()) : opt.diffusionLength, + true, + opt.lengthUnit, + 1, + 1, + opt.mfggrid, + null, + cfp, + null, + null, + false, + opt.stackMap, + cad, + null, + null, + null, + design, + Collections.EMPTY_LIST, + (float) opt.tdata.getDefaultLoadCapacitance(), + opt.minWidth, + true, + new PartialExtract.CellPlusMinus(cell.getFullyQualifiedType(), PartialExtract.Info.INCLUDE), + opt.tdata.getTechnologyName(), + null); + final CellType ct = design.getCell(cell.getFullyQualifiedType()); + return ct.transistors; + } + + /** + * Set the directive block of a given block. + **/ + private static void setDirective(final BlockInterface block, + final DirectiveBlock newdir) { + final BlockIterator bi = block.iterator(BlockInterface.DIRECTIVE); + if (bi.hasNext()) { + bi.next(); + bi.set(newdir); + } else { + bi.add(newdir); + } + } + + /** + * Merge the given directives with the directives of the given block. + **/ + private static void mergeDirective(final BlockInterface block, + final DirectiveInterface newdir) { + final DirectiveBlock old = DirectiveUtils.getDirectiveBlock(block); + final DirectiveBlock merged = + old == null ? new DirectiveBlock(newdir) : + new MergeDirective(old, newdir); + setDirective(block, merged); + } + + private static Pair makeHalfOp(final HierName name, final Boolean dir) { + return new Pair(name, dir); + } + + private static void addSymmetrize(final DirectiveSource source, + final Pair halfop, + final Integer level) { + source.definition(DirectiveConstants.SYMMETRIZE, + DirectiveConstants.HALFOP_TYPE, + halfop, level); + } + + private static void addShared(final DirectiveSource source, + final Pair halfop, + final Integer group) { + source.definition(DirectiveConstants.SHARED, + DirectiveConstants.HALFOP_TYPE, + halfop, group); + } + + /** + * Find the set of transistors connected to the collection of nodes, and + * return the number of transistors, and their total width, + **/ + private static Pair getStatistic(final NetGraph graph, + final Collection nodes) { + int transistors = 0; + double width = 0; + final Set edgeSet = new HashSet(); + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + final NetGraph.NetNode node = graph.findNetNode(name); + assert node != null : "Cannot find " + name + " in NetGraph " + graph; + for (Iterator j = node.getPaths().iterator(); j.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) j.next(); + edgeSet.addAll(path.getEdges()); + } + } + for (Iterator i = edgeSet.iterator(); i.hasNext(); ) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) i.next(); + ++transistors; + width += edge.width; + } + //return new Pair(new Integer(transistors), new Double(width)); + return new Pair(new Integer(transistors), new Integer((int) Math.round(width * 1e10))); + } + + private static Integer SYM_NONE = new Integer(0); + private static Integer SYM_PARTIAL = new Integer(1); + private static Integer SYM_SKIP_FIRST = new Integer(2); + private static Integer SYM_FULL = new Integer(3); + private static Integer SYM_TRUNK = new Integer(4); + private static Integer SYM_FULL_X = new Integer(5); + private static List symdirs = new ArrayList(); + private static Map symnams = new HashMap(); + static { + symdirs.add(SYM_PARTIAL); + symdirs.add(SYM_SKIP_FIRST); + symdirs.add(SYM_FULL); + symdirs.add(SYM_FULL_X); + symnams.put(SYM_NONE, "SYM_NONE"); + symnams.put(SYM_PARTIAL, "SYM_PARTIAL"); + symnams.put(SYM_SKIP_FIRST, "SYM_SKIP_FIRST"); + symnams.put(SYM_FULL, "SYM_FULL"); + symnams.put(SYM_TRUNK, "SYM_TRUNK"); + symnams.put(SYM_FULL_X, "SYM_FULL_X"); + } + + private static void setDirectives(final Sharing[] sharing, + final Integer up, + final Integer dn, + final Map store) { + final Collection directives = new TreeSet(); + final DirectiveSource source = new DirectiveSource(BlockInterface.PRS); + for (int i = 0; i < sharing.length; ++i) { + sharing[i].addSharedDirectives(source, directives); + sharing[i].addSymmetrizeDirectives(source, directives, up, dn); + } + store.put(source, new Pair(directives, sharing)); + } + + private static void getDirectives(final Sharing[] sharing, + final Map result, + final Set badup, + final Set baddn) { + boolean upbad = false; + boolean dnbad = false; + for (int i = 0; i < sharing.length; ++i) { + for (Iterator j = sharing[i].iterator(); j.hasNext(); ) { + final Group g = (Group) j.next(); + for (Iterator k = g.iterator(); k.hasNext(); ) { + final HierName h = (HierName) k.next(); + upbad |= badup.contains(h); + dnbad |= baddn.contains(h); + } + } + } + + /* If there are charge sharing problems in either direction, then the + * up direction should be SYM_PARTIAL, because it would also help for + * the down direction by exposing additional capacitance. Ask Theron + * for details. */ + final Integer up = upbad || dnbad ? SYM_PARTIAL : SYM_NONE; + + final List dndirs = dnbad ? symdirs : Collections.EMPTY_LIST; + /* Loop over the symmetrize directives for down directions */ + for (Iterator j = dndirs.iterator(); j.hasNext(); ) { + final Integer dn = (Integer) j.next(); + setDirectives(sharing, up, dn, result); + } + + /* If there are only up problems, then try SYM_PARTIAL; this is + * exclusive with the above loop */ + if (upbad && !dnbad) { + setDirectives(sharing, up, null, result); + } + + if (upbad || dnbad) + setDirectives(sharing, SYM_FULL_X, SYM_FULL_X, result); + } + + /** + * Read the section in hsizes.out for a given cell, and return that string, + * without the "CELL" line as a string. This is used to reduce I/O. + **/ + private static String readSizes(final Reader in, final String child, final String parent) + throws IOException { + final BufferedReader br = new BufferedReader(in); + final StringBuffer result = new StringBuffer(); + boolean accum = false; + String line; + while ((line = br.readLine()) != null) { + if (line.startsWith("CELL")) { + final String[] tokens = StringUtil.tokenize(line); + assert tokens.length == 3; + if (tokens[1].equals(child)) { + accum = true; + line = tokens[0] + " " + parent + " " + tokens[2]; + } + } + if (accum) { + result.append(line); + result.append("\n"); + if (line.equals("}")) break; + } + } + return result.toString(); + } + + private static int groupId = 0; + private static int getGroupId(final Map groupMap, final Group group) { + return ((Integer) ((Pair) groupMap.get(group)).getSecond()).intValue(); + } + + private static void addGroupMap(final Map groupMap, + final Group group, + final Collection directives, + final NetGraph graph) { + // If this is a new group, create a new AliasedMap + if (!groupMap.containsKey(group)) { + groupMap.put(group, + new Pair(new AliasedMap( + new AliasedMap.MergeFunction() { + public Object merge(Object o1, Object o2) + throws AliasedMap.MergeFailedException { + return o1; + } + }, + new Comparator() { + public int compare(final Object o1, final Object o2) { + final Collection c1 = (Collection) o1; + final Collection c2 = (Collection) o2; + int i = c1.size() - c2.size(); + if (i != 0) return i; + for (Iterator j = c1.iterator(), k = c2.iterator(); + j.hasNext(); ) { + final String s1 = (String) j.next(); + final String s2 = (String) k.next(); + i = s1.compareTo(s2); + if (i != 0) return i; + } + return 0; + } + } + ), + new Integer(groupId++))); + } + + final GroupInfo newinfo = new GroupInfo(graph, group); + + final AliasedMap map = + (AliasedMap) ((Pair) groupMap.get(group)).getFirst(); + try { + map.addData(directives, newinfo); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionError("Merge failed. Cannot happen!"); + } + for (Iterator i = map.getCanonicalKeys(); i.hasNext(); ) { + final Object key = i.next(); + final GroupInfo val = (GroupInfo) map.getValue(key); + if (!key.equals(directives) && val.equals(newinfo)) { + try { + map.makeEquivalent(key, directives); + } catch (AliasedMap.MergeFailedException e) { + throw new AssertionError("Merge failed. Cannot happen!"); + } + break; + } + } + } + + private static Map directiveIds = new HashMap(); + private static int lastId = 0; + private static int getDirectiveId(final Collection directives) { + if (!directiveIds.containsKey(directives)) { + directiveIds.put(directives, new Integer(lastId++)); + } + return ((Integer) directiveIds.get(directives)).intValue(); + } + + private static void outputDirectiveIds(final Writer w) throws IOException { + for (Iterator i = directiveIds.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + w.write(entry.getValue() + ":"); + outputDirectives((Collection) entry.getKey(), w); + w.write("\n"); + } + } + + private static void tryDirectives(final CastFileParser cfp, + final CellInterface cell, + final Map directives, + final StringReader hin, + final Cadencize cad, + final Map groupMap, + final Writer w, + final Option opt) throws IOException { + final BlockInterface block = cell.getBlockInterface(); + final BlockInterface prs = block.iterator(BlockInterface.PRS).next(); + final DirectiveBlock original = DirectiveUtils.getDirectiveBlock(prs); + int id = 0; + + for (Iterator i = directives.entrySet().iterator(); i.hasNext(); ++id) { + final Map.Entry entry = (Map.Entry) i.next(); + + final DirectiveSource source = (DirectiveSource) entry.getKey(); + final DirectiveInterface newdir = source.getDirectiveInterface(); + mergeDirective(prs, newdir); + + final Pair value = (Pair) entry.getValue(); + final Sharing[] sharings = (Sharing[]) value.getSecond(); + final String outFile = Integer.toString(id); + w.write(outFile + ":"); + + final NetGraph transistors; + try { + hin.reset(); + transistors = runJauto(cfp, cell, opt.outdir, + outFile.toString(), cad, hin, opt); + } catch (Exception e) { + throw new RuntimeException("Cannot generate CDL for charge sharing for cell: " + cell.getFullyQualifiedType(), e); + } + final Collection dirs = (Collection) value.getFirst(); + for (int j = 0; j < sharings.length; ++j) { + for (Iterator k = sharings[j].iterator(); k.hasNext(); ) { + final Group group = (Group) k.next(); + + addGroupMap(groupMap, group, dirs, transistors); + w.write(getGroupId(groupMap, group) + " " + getDirectiveId(dirs)); + if (k.hasNext() || j + 1 < sharings.length) w.write(":"); + } + } + w.write("\n"); + setDirective(prs, original); + } + } + + /** + * Generate an ordered list of configurations. + **/ + private static void outputPossibleSharing(final Sharing share, + final Map groupMap, + final Writer w) throws IOException + { + int transistors = 0; + double width = 0; + for (Iterator i = share.iterator(); i.hasNext(); ) { + final Group group = (Group) i.next(); + w.write(Integer.toString(getGroupId(groupMap, group))); + if (i.hasNext()) w.write(" "); + } + } + + private static void outputPossibleSharing(final AliasedMap sharing, + final Map groupMap, + final Writer w) throws IOException { + for (Iterator i = sharing.getCanonicalKeys(); i.hasNext(); ) { + final HierName key = (HierName) i.next(); + final List sharings = (List) sharing.getValue(key); + for (Iterator j = sharings.iterator(); j.hasNext(); ) { + outputPossibleSharing((Sharing) j.next(), groupMap, w); + if (j.hasNext()) w.write(":"); + } + w.write("\n"); + } + } + + private static String outputGroup(final Group group) { + final StringBuffer buf = new StringBuffer(); + for (Iterator i = group.iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + buf.append(" " + name.getCadenceString()); + } + return buf.toString(); + } + + private static void outputGroup(final Group group, final Writer w) throws IOException { + for (Iterator i = group.iterator(); i.hasNext(); ) { + final HierName name = (HierName) i.next(); + w.write(" " + name.getCadenceString()); + } + } + + private static void outputDirectives(final Collection dir, final Writer w) throws IOException { + for (Iterator i = dir.iterator(); i.hasNext(); ) { + final String dirline = (String) i.next(); + w.write(dirline); + if (i.hasNext()) w.write(":"); + } + } + + private static void outputStat(final Pair p, final Writer w) throws IOException { + w.write(p.getFirst() + " " + p.getSecond()); + } + + private static void outputGroups(final Map groupMap, + final Writer w) throws IOException { + for (Iterator i = groupMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Group group = (Group) entry.getKey(); + final Pair p = (Pair) entry.getValue(); + w.write(Integer.toString(getGroupId(groupMap, group))); + outputGroup(group, w); + w.write(":"); + final AliasedMap amap = (AliasedMap) p.getFirst(); + for (Iterator j = amap.getCanonicalKeys(); j.hasNext(); ) { + final Object key = j.next(); + for (Iterator k = amap.getAliases(key); k.hasNext(); ) { + w.write(Integer.toString(getDirectiveId((Collection) k.next()))); + if (k.hasNext()) w.write("="); + } + w.write(" "); + final GroupInfo ginfo = (GroupInfo) amap.getValue(key); + outputStat(ginfo.stat, w); + w.write(":"); + } + w.write("\n"); + } + } + + /** + * Create an empty NetGraph, and return it. + **/ + private static NetGraph createNetGraph(final CellInterface cell, + final Cadencize cad) { + final CadenceInfo ci = cad.convert(cell); + final ExclusiveNodeSets exclusives = new ExclusiveNodeSets(); + final AliasedSet namespace = ci.getLocalNodes(); + exclusives.merge(ci.getPortExclusiveNodeSets()); + exclusives.merge(ci.getLocalExclusiveNodeSets()); + final Map nostats = DirectiveUtils.getPrsDirective(cell, DirectiveConstants.NO_STAT, DirectiveConstants.NODE_TYPE); + final Set nostatnodes = DirectiveUtils.canonize(namespace, DirectiveUtils.getExplicitTrues(nostats)); + return new NetGraph(namespace, exclusives, new ArrayList(), Vdd, GND, + nostatnodes); + } + + private static void process(final CellInterface child, final Set interest, + final Set badup, final Set baddn, + final Cadencize cad, + final CastFileParser cfp, + final Option opt) throws IOException { + final CellInterface cell = child.getDirectRefinementParent(); + shareId = findLargestShareNumber(cell) + 1; + final NetGraph graph = createNetGraph(cell, cad); + try { + graph.addCellInterfacePrs(cell, new NetGraph[0], cfp, cad); + } catch (Exception e) { + throw new RuntimeException("Cannot create netgraph from " + cell.getFullyQualifiedType(), e); + } + graph.prepareForLvs(); + final AliasedMap sharing = getSharingGroups(graph, interest); + + /* Accumulate nodes that are by themselves. The only directive to try + * on them are the symmetrize directives. */ + final List singletons = new ArrayList(); + + final Map directives = new HashMap(); + for (Iterator i = sharing.getCanonicalKeys(); i.hasNext(); ) { + final HierName key = (HierName) i.next(); + final List possible = getPossibleSharing(sharing.getAliases(key)); + sharing.setValue(key, possible); + if (possible.size() == 1) { + singletons.add(possible.get(0)); + continue; + } + final List config = getConfigurations(possible); + for (Iterator j = config.iterator(); j.hasNext(); ) { + final Sharing s = (Sharing) j.next(); + getDirectives(new Sharing[] { s }, directives, badup, baddn); + } + } + getDirectives((Sharing[]) singletons.toArray(new Sharing[0]), + directives, badup, baddn); + final StringReader hin; + try { + hin = new StringReader(readSizes(new FileReader(opt.hsizes), child.getFullyQualifiedType(), cell.getFullyQualifiedType())); + } catch (Exception e) { + throw new RuntimeException("Cannot read in half operator sizes: " + opt.hsizes, e); + } + final Map groupMap = new HashMap(); + Writer w = new FileWriter(new File(opt.outdir, "configs")); + tryDirectives(cfp, cell, directives, hin, cad, groupMap, w, opt); + w.close(); + + w = new FileWriter(new File(opt.outdir, "all-configs")); + outputPossibleSharing(sharing, groupMap, w); + w.close(); + + w = new FileWriter(new File(opt.outdir, "groups")); + outputGroups(groupMap, w); + w.close(); + + w = new FileWriter(new File(opt.outdir, "directives")); + outputDirectiveIds(w); + w.close(); + + w = new FileWriter(new File(opt.outdir, "parent")); + w.write(cell.getFullyQualifiedType() + "\n"); + w.close(); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + final String castPath = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final CastFileParser cfp = + new CastFileParser(new FileSearchPath(castPath), castVersion); + + final String output = theArgs.getArgValue("output", "."); + + final Cadencize cad = new Cadencize(true); + final BufferedReader fin = + new BufferedReader(new InputStreamReader(System.in)); + final Option opt = new Option(theArgs, cfp, cad); + String line; + while ((line = fin.readLine()) != null) { + final String[] tokens = StringUtil.tokenize(line); + final CellInterface ci; + try { + ci = cfp.getFullyQualifiedCell(tokens[0]); + } catch (Exception e) { + throw new RuntimeException("Cannot load cell " + tokens[0], e); + } + final Set interest = new HashSet(); + final Set badup = new HashSet(); + final Set baddn = new HashSet(); + try { + for (int i = 1; i < tokens.length; ++i) { + final char updn = tokens[i].charAt(0); + final HierName tok = + HierName.makeHierName(tokens[i].substring(1), '.'); + if (updn == '+') { + badup.add(tok); + } else if (updn == '-') { + baddn.add(tok); + } else { + throw new RuntimeException("Invalid input: " + line); + } + interest.add(tok); + } + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot convert to HierName", e); + } + process(ci, interest, badup, baddn, cad, cfp, opt); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GeneratePLTSubtypes.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GeneratePLTSubtypes.java new file mode 100644 index 0000000000..53661166c1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GeneratePLTSubtypes.java @@ -0,0 +1,317 @@ +package com.avlsi.tools.jauto; + +import java.io.IOException; +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileNotFoundException; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.io.FileSearchPath; +import com.avlsi.file.common.HierName; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.text.StringUtil; + +public class GeneratePLTSubtypes { + + private static Boolean verbose; + + public static String cell2dir(String cellName) { + return cellName.replace('.', File.separatorChar); + } + + private static void writeCell(final CellInterface ci, + final String cellName, + final Map instances, + final Collection brs, + final File outputDir, + final boolean writeSubtypes, + final boolean ifexists) throws IOException { + final int lastDot = cellName.lastIndexOf('.'); + assert lastDot > 0; + final String module = cellName.substring(0, lastDot); + final String cell = cellName.substring(lastDot + 1); + final File d = new File(outputDir, cell2dir(module)); + if (!d.isDirectory() && !d.mkdirs()) { + throw new RuntimeException("Cannot create directory: " + d); + } + final File f = new File(d, cell + ".cast"); + if (f.exists() && ifexists) { + if (verbose) + System.out.println("Exists " + f); + return; + } + final PrintWriter w = new PrintWriter(new FileWriter(f)); + SubtypeOutput.writeHeader(w, module, ci.getFullyQualifiedType(), + cell, ci, null, null); + if (CellUtils.isLeaf(ci)) { + w.println(" prs {"); + } else { + w.println(" subtypes {"); + if (writeSubtypes) { + for (Iterator i = instances.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName inst = (HierName) entry.getKey(); + final Pair p = (Pair) entry.getValue(); + w.println(" " + p.getFirst() + " :>"); + w.println(" " + p.getSecond() + " " + inst + ";"); + } + } + } + + if (!brs.isEmpty()) { + w.println(" directives {"); + } + for (BufferedReader br : brs) { + String line; + while ((line = br.readLine()) != null) w.println(line); + } + if (!brs.isEmpty()) { + w.println(" }"); + } + + w.println(" }"); + w.println("}"); + w.close(); + if (verbose) + System.out.println("Wrote " + f); + } + + private static BufferedReader openReader(final File f) { + try { + return new BufferedReader(new FileReader(f)); + } catch (FileNotFoundException e) { + return null; + } + } + + private static class QuickExitException extends RuntimeException { } + + public static BufferedReader getDirective(final File measureDir, + final String moduleName, + final String type, + final String[] dirFiles) { + final BufferedReader[] result = new BufferedReader[1]; + final File dir = new File(measureDir, cell2dir(moduleName)); + + // If directives exist for the subtype, use it + for (int i = 0; i < dirFiles.length; ++i) { + final File real; + if (dirFiles[i].startsWith("/")) { + real = new File(dirFiles[i]); + } + else { + real = new File(new File(dir, type), dirFiles[i]); + } + result[0] = openReader(real); + if (result[0] != null) { + // System.out.println("Directives from "+real); + return result[0]; + } + } + + return result[0]; + } + + public static BufferedReader tryDirective(final File measureDir, + final String moduleName, + final String type, + final String[] dirFiles) { + final BufferedReader[] result = new BufferedReader[1]; + final File dir = new File(measureDir, cell2dir(moduleName)); + + // Search for directives from FQCN+- directories, choose one arbitrarily + try { + dir.listFiles(new FilenameFilter() { + public boolean accept(final File d, final String name) { + try { + // Prepend with "x." to avoid quoting the name, which + // may be numeric + final Triplet t = + PartialExtract.parseCellPlusMinus("x." + name); + if (t.getFirst().equals("x." + type)) { + for (int i = 0; i < dirFiles.length; ++i) { + final File x = new File(new File(d, name), + dirFiles[i]); + if ((result[0] = openReader(x)) != null) { + System.out.println("Using " + x + " for " + + moduleName + "." + type); + // Don't examine any more files + throw new QuickExitException(); + } + } + } + } catch (Exception e) { } + return false; + } + }); + } catch (QuickExitException e) { } + + return result[0]; + } + + private static Set warned = new HashSet(); + + public static BufferedReader getDirective(final File[] measureDirs, + final String moduleName, + final String type, + final String[] dirFiles) { + for (int i = 0; i < measureDirs.length; ++i) { + final BufferedReader br = + getDirective(measureDirs[i], moduleName, type, dirFiles); + if (br != null) { + return br; + } + } + + for (int i = 0; i < measureDirs.length; ++i) { + final BufferedReader br = + tryDirective(measureDirs[i], moduleName, type, dirFiles); + if (br != null) { + return br; + } + } + + final String fqcn = moduleName + "." + type; + if (warned.add(fqcn)) { + System.err.println("Warning: directives file not found for " + + fqcn); + } + return null; + } + + public static String getReplacement(final CellInterface ci, + final CellInterface cip, + final File[] measureDirs, + final String[][] dirFiles, + final String prefix, + final File outputDir, + final Map cache, + final int topOnly, + final boolean top) throws IOException { + final String type = ci.getFullyQualifiedType(); + if (cache.containsKey(type)) return (String) cache.get(type); + + final Collection brs = new ArrayList(); + for (String[] dirFile : dirFiles) { + final BufferedReader br = + getDirective(measureDirs, ci.getModuleName(), ci.getType(), + dirFile); + if (br != null) brs.add(br); + } + final Map changed = new HashMap(); +// if(top || topOnly == 0 || br == null) { + for (Iterator i = cip.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subci = (CellInterface) p.getSecond(); + if (CellUtils.isWiring(subci)) continue; + final String subtype = subci.getFullyQualifiedType(); + final String newType = + getReplacement(subci, subci, measureDirs, dirFiles, prefix, outputDir, + cache, topOnly, false); + if (newType != null) { + if (!subtype.equals(newType)) { + final HierName inst = (HierName) p.getFirst(); + changed.put(inst, new Pair(subtype, newType)); + } + } + } +// } + + final String newName; + if (changed.isEmpty() && brs.isEmpty()) { + newName = topOnly == 0 ? type : null; + } else { + newName = prefix + "." + type; + // top cell, always write + // topOnly == 0 do all + // no directive found, always write + final boolean writeifexists = (top || (topOnly == 0) || brs.isEmpty()); + final boolean writeSubtypes = (prefix.equals("plt") || topOnly == 0); + if (top || writeSubtypes) + writeCell(cip, newName, changed, brs, outputDir, writeSubtypes, ! writeifexists); + } + for (BufferedReader br : brs) { + br.close(); + } + cache.put(type, newName); + return newName; + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cell", null); + final String parentName = theArgs.getArgValue("parent", cellName); + + final String output = theArgs.getArgValue("output-dir", null); + final String measure = theArgs.getArgValue("measure-dir", null); + final String prefix = theArgs.getArgValue("prefix", "measured"); + final String dirFile = theArgs.getArgValue("dir-file", "directives"); + final int topOnly =Integer.parseInt(theArgs.getArgValue("top-only", "0")); + verbose = theArgs.argExists("verbose"); + if (cellName == null || output == null || measure == null) { + System.err.println( +"Usage: generate_plt_subtypes\n" + +" --cast-path= (defaults to .)\n" + +" --cast-version= (defaults to 2)\n" + +" --cell= (fully qualified cell name)\n" + +" --output-dir= (where to write new subtypes)\n" + +" --measure-dir=:... (paths to search for --dir-files)\n" + +" [ --parent= (instead of cell if different) ]\n" + +" [ --prefix= (prefix for cell name, defaults to measured) ]\n" + +" [ --top-only=[0|1] (just do top cell and as needed if 1) ]\n" + +" [ --dir-file=:...|...|... (files to search in --measure-dirs,\n" + +" defaults to directives) ]\n" + +" [ --verbose extra info]\n"); + System.exit(1); + } + final String[] dirGroups = StringUtil.split(dirFile, '|'); + final String[][] dirFiles = new String[dirGroups.length][]; + for (int i = 0; i < dirGroups.length; ++i) { + dirFiles[i] = StringUtil.split(dirGroups[i], ':'); + } + final File outputDir = new File(output); + final String[] measures = StringUtil.split(measure, ':'); + final File[] measureDirs = new File[measures.length]; + for (int i = 0; i < measures.length; ++i) { + measureDirs[i] = new File(measures[i]); + } + final CellInterface cip = + CellUtils.loadCell(castRoot, parentName, castVersion); + final CellInterface ci = + CellUtils.loadCell(castRoot, cellName, castVersion); + final String newName = + getReplacement(ci, cip, measureDirs, dirFiles, prefix, outputDir, + new HashMap(), topOnly, true); + System.out.println(ci.getFullyQualifiedType() + " -> " + newName); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GlobalNet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GlobalNet.java new file mode 100644 index 0000000000..f0bd414818 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/GlobalNet.java @@ -0,0 +1,2569 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.jauto; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.ArrayList; +import java.util.List; +import java.util.HashSet; +import java.util.*; +import java.io.*; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.*; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.geometry.SteinnerTree; +import com.avlsi.geometry.Point; +import com.avlsi.geometry.BoundingBox; +import com.avlsi.netlist.AbstractDevice; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.AbstractNodeIterator; +import com.avlsi.netlist.Visitor; +import com.avlsi.netlist.impl.SimpleAbstractDeviceIterator; +import com.avlsi.netlist.impl.SimpleAbstractNodeIterator; +import com.avlsi.netlist.impl.simple.SimpleNetlist; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.dsim.InstanceData; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.jauto.DebugOption; +import com.avlsi.tools.jauto.TechnologyData; +import com.avlsi.tools.jauto.NetSource; +import com.avlsi.tools.jauto.NetSink; +import com.avlsi.tools.jauto.JautoMessageCenter; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Interpolate; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.flute.Flute; +import com.avlsi.util.tree.*; + +/** + * Class representing a net that crosses cell boundaries. + * + * Attached at all ports, and at the net at the top level. + * + * Contains pointers to all terminal ports. + * + * @author Aaron Denney + * @version $Date$ + + **/ + +public class GlobalNet { + /** Subcircuits for wire cap and res **/ + private final SimpleNetlist wireCapModel; + private final SimpleNetlist wireResModel; + + // PointGeometry needs access to GND, but non-static inner classes + // cannot have non-constant static members. We put GND here + // instead of directly in GlobalNet to avoid polluting the GlobalNet + // namespace. + private interface HierNameConstants { + HierName GND = HierName.makeHierName("GND"); + } + + private class PointGeometry implements CellNet.Geometry, + HierNameConstants { + private final HierName source, sink; + private AbstractDevice makeCapacitor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double C, + final double W, + final double S, + final double L) { + return new AbstractDevice() { + public void accept(final Visitor visitor) { + List nodes = new ArrayList(); + Map parameters = new HashMap(); + nodes.add(node1); + nodes.add(node2); + parameters.put("c",C); + parameters.put("w",W); + parameters.put("s",S); + parameters.put("l",L); + visitor.subcircuitCall(name,wireCapModel, + new SimpleAbstractNodeIterator(nodes.iterator()), + parameters); + } + }; + } + private AbstractDevice makeResistor(final HierName name, + final AbstractNode node1, + final AbstractNode node2, + final double R, + final double W, + final double S, + final double L) { + return new AbstractDevice() { + public void accept(final Visitor visitor) { + List nodes = new ArrayList(); + Map parameters = new HashMap(); + nodes.add(node1); + nodes.add(node2); + parameters.put("r",R); + parameters.put("w",W); + parameters.put("s",S); + parameters.put("l",L); + visitor.subcircuitCall(name,wireResModel, + new SimpleAbstractNodeIterator(nodes.iterator()), + parameters); + } + }; + } + private AbstractNode makeNode(final HierName name) { + return new AbstractNode() { + public HierName getCanonicalName() { + return name; + } + public Iterator getAliases() { + // XXX: Not implemented + return null; + } + public AbstractDeviceIterator getDevices() { + // XXX: Not implemented + return null; + } + }; + } + public PointGeometry() { + final String suffix = topCellNet.canonicalName.getSuffixString(); + this.source = HierName.makeSiblingName(topCellNet.canonicalName, + suffix + ":source"); + this.sink = HierName.makeSiblingName(topCellNet.canonicalName, + suffix); // + ".sink"); + } + public HierName mapName(final CellNet port, final HierName alias) { + if (port.portDirection == CellNet.INPUT) return sink; + else return source; + } + public HierName mapName(final CellNet net, final boolean gate) { + if (net == topCellNet) { + return gate ? sink : source; + } else { + return net.canonicalName; + } + } + public Pair[] getRC(final HierName alias1, final HierName alias2) { + final Pair[] ret = new Pair[1]; + /* + if (port.portDirection == isSource(alias2)) { + ret[0] = new Pair(new Double(0), new Double(0)); + } else { + } + ret[0] = new Pair(new Double(R), new Double(C)); + */ + Debug.assertTrue(false, "Don't call getRC!"); + return ret; + } + public AbstractDeviceIterator getDeviceIterator() { + final List/**/ devices = + new ArrayList/**/(); + // create Pi model for wire R/C + final AbstractNode sourceNode = makeNode(source); + final AbstractNode sinkNode = makeNode(sink); + final double C = getWireCapacitance(); + final double R = getWireResistance(); + final double W = getWireWidth(); + final double S = getWireSpace(); + final double CL = getEstimatedWireLength(); + final double RL = getEstimatedWireSpan(); + devices.add(makeCapacitor(source.appendString(":c"), + makeNode(GND),sourceNode,C/2,W,S,CL/2)); + devices.add(makeCapacitor(sink.appendString(":c"), + makeNode(GND),sinkNode,C/2,W,S,CL/2)); + devices.add(makeResistor(sink.appendString(":r"), + sourceNode,sinkNode,R,W,S,RL)); + return new SimpleAbstractDeviceIterator(devices.iterator()); + } + } + + /** + * A comparator of NetSource objects. It first compares type. Then for + * NetType.CELL, compares cell name; for HALF_OPERATOR_TRANSISTOR, compares + * cell name, output node name, and direction in sequence. + * XXX: Make sure any changes to this are synchronize with + * {@link NetSourceCellTypeComparator}. + **/ + private static class NetSourceComparator implements Comparator { + private static NetSourceComparator singleton = null; + private NetSourceComparator() { } + public static NetSourceComparator getInstance() { + if (singleton == null) singleton = new NetSourceComparator(); + return singleton; + } + public int compare(final Object o1, final Object o2) { + final NetSource src1 = (NetSource) o1; + final NetSource src2 = (NetSource) o2; + + final int type = src1.getType() - src2.getType(); + if (type != 0) return type; + + if (src1.getType() == NetType.CELL) { + return src1.getCellSource().typeName.compareTo( + src2.getCellSource().typeName); + } else if (src1.getType() == NetType.HALF_OPERATOR_TRANSISTOR) { + final HalfOperator ho1 = src1.getSource(); + final HalfOperator ho2 = src2.getSource(); + + final int cell = + ho1.subType.typeName.compareTo(ho2.subType.typeName); + if (cell != 0) return cell; + + final int output = ho1.outputNode.compareTo(ho2.outputNode); + if (output != 0) return output; + + return ho1.driveDirection - ho2.driveDirection; + } + + return 0; + } + public boolean equals(final Object o) { + return o == singleton; + } + } + /** + * If a MultiSet has been sorted using {@link NetSourceComparator}, then + * this class can be used to search for a source with the given type and + * associated cell type. + * XXX: Make sure changes to this does not conflict with the ordering + * imposed by NetSourceComparator. + **/ + private static class NetSourceCellTypeComparator implements Comparator { + private final Object dummy; + private final int sourceType; + private final String cellType; + public NetSourceCellTypeComparator(final Object dummy, + final int sourceType, + final String cellType) { + this.dummy = dummy; + this.sourceType = sourceType; + this.cellType = cellType; + } + private int compare(final NetSource src) { + final int type = sourceType - src.getType(); + if (type != 0) return type; + + if (sourceType == NetType.CELL) { + return cellType.compareTo(src.getCellSource().typeName); + } else if (sourceType == NetType.HALF_OPERATOR_TRANSISTOR) { + return cellType.compareTo(src.getSource().subType.typeName); + } + return 0; + } + public int compare(final Object o1, final Object o2) { + if (o1 == dummy) return compare((NetSource) o2); + else return -compare((NetSource) o1); + } + public boolean equals(final Object o) { + if (o instanceof NetSourceCellTypeComparator) { + final NetSourceCellTypeComparator c = + (NetSourceCellTypeComparator) o; + return dummy == c.dummy && sourceType == c.sourceType && + cellType.equals(c.cellType); + } + return false; + } + } + + /** + * A comparator of NetSink objects. It first compares types. Then for + * NetType.CELL, compares cell name; for CAPACITIVE_LOAD, compares load; + * for HALF_OPERATOR_TRANSISTOR, compare cell name, output node name, + * direction, and transistor size in sequence. + **/ + private static class NetSinkComparator implements Comparator { + private static NetSinkComparator singleton = null; + private NetSinkComparator() { } + public static NetSinkComparator getInstance() { + if (singleton == null) singleton = new NetSinkComparator(); + return singleton; + } + public int compare(final Object o1, final Object o2) { + final NetSink snk1 = (NetSink) o1; + final NetSink snk2 = (NetSink) o2; + + final int type = snk1.getType() - snk2.getType(); + if (type != 0) return type; + + if (snk1.getType() == NetType.CELL) { + return snk1.getCellSink().typeName.compareTo( + snk2.getCellSink().typeName); + } else if (snk1.getType() == NetType.CAPACITIVE_LOAD) { + return Double.compare(snk1.loadCapacitance, + snk2.loadCapacitance); + } else if (snk1.getType() == NetType.HALF_OPERATOR_TRANSISTOR) { + final HalfOperator ho1 = snk1.getSink(); + final HalfOperator ho2 = snk2.getSink(); + + final int cell = + ho1.subType.typeName.compareTo(ho2.subType.typeName); + if (cell != 0) return cell; + + final int output = ho1.outputNode.compareTo(ho2.outputNode); + if (output != 0) return output; + + final int dir = ho1.driveDirection - ho2.driveDirection; + if (dir != 0) return dir; + + return Double.compare(snk1.getTransistor().size, + snk2.getTransistor().size); + } + return 0; + } + public boolean equals(final Object o) { + return o == singleton; + } + } + + // highest-level cell net corresponding to this global net + private final CellNet topCellNet; + + // list of sources (drivers) of the net + private MultiSet/**/ listSources; + + // list of sinks (loads) of the net + private MultiSet/**/ listSinks; + + private Forest steinerTree = new Forest(); + private ArrayList/*>*/ sourceList = + new ArrayList/*>*/(); + private ArrayList/*>*/ sinkList = + new ArrayList/*>*/(); + + // estimated total wire length for this global net + private double estimatedWireLength; // in Meter + + // estimated maximum wire span for this global net + private double estimatedWireSpan; // in Meter + + // minimum wire width and wire space of all CellNets that are part + // of this GlobalNet + private double minWireWidth = -1, minWireSpace = -1; + + // maximum wire length of all CellNets that are part of this + // GlobalNet + private double maxWireLength = -1, maxWireSpan = -1, maxMinWireLength = -1, + maxMinWireSpan = -1, maxInternalWireLength = -1; + + private double getAssignedMinDirective(final CellNet net, double val) { + if (CellUtils.isFixedSize(net.container.cast_cell) && + topCellNet.container.isFloorplanned()) { + val = -1; + } + return val; + } + + private void updateWireParam(final CellNet net) { + final double w = net.getAssignedWireWidth(); + if (w >= 0) + minWireWidth = minWireWidth < 0 ? w : Math.min(minWireWidth, w); + + final double s = net.getAssignedWireSpace(); + if (s >= 0) + minWireSpace = minWireSpace < 0 ? s : Math.min(minWireSpace, s); + + final double l = net.getAssignedWireLength(); + if (l >= 0) + maxWireLength = maxWireLength < 0 ? l : Math.max(maxWireLength, l); + + final double sp = net.getAssignedWireSpan(); + if (sp >= 0) + maxWireSpan = maxWireSpan < 0 ? sp : Math.max(maxWireSpan, sp); + + final double il = net.getInternalWireLength(); + if (il >= 0) + maxInternalWireLength = Math.max(maxInternalWireLength, il); + + final double ml = + getAssignedMinDirective(net, net.getAssignedMinWireLength()); + if (ml >= 0) maxMinWireLength = Math.max(maxMinWireLength, ml); + + final double ms = + getAssignedMinDirective(net, net.getAssignedMinWireSpan()); + if (ms >= 0) maxMinWireSpan = Math.max(maxMinWireSpan, ms); + } + + public CellNet getTopCellNet(){ + return topCellNet; + } + + public MultiSet/**/ getListSources() { + return listSources; + } + + public MultiSet/**/ getListSinks() { + return listSinks; + } + + + public double getWireWidth() { + double wireWidth = topCellNet.getAssignedWireWidth(); + + if (wireWidth <= 0) wireWidth = minWireWidth; + + if (wireWidth <= 0) + wireWidth = topCellNet.container.getAssignedWireWidth(); + + if (wireWidth <= 0) + wireWidth = getTechnologyData().defaultWireWidth; + + return wireWidth; + } + + + public double getWireSpace() { + double wireSpace = topCellNet.getAssignedWireSpace(); + + if (wireSpace <= 0) wireSpace = minWireSpace; + + if (wireSpace <= 0) + wireSpace = topCellNet.container.getAssignedWireSpace(); + + if (wireSpace <= 0) + wireSpace = getTechnologyData().defaultWireSpace; + + return wireSpace; + } + + public double getMinWireLength() { + double minWireLength = + getAssignedMinDirective(topCellNet, + topCellNet.getAssignedMinWireLength()); + + if (minWireLength <= 0) minWireLength = maxMinWireLength; + + if (minWireLength <= 0) + minWireLength = getAssignedMinDirective( + topCellNet, topCellNet.container.getAssignedMinWireLength()); + + return minWireLength; + } + + public double getMinWireSpan() { + double minWireSpan = + getAssignedMinDirective(topCellNet, + topCellNet.getAssignedMinWireSpan()); + + if (minWireSpan <= 0) minWireSpan = maxMinWireSpan; + + if (minWireSpan <= 0) + minWireSpan = getAssignedMinDirective( + topCellNet, topCellNet.container.getAssignedMinWireSpan()); + + return minWireSpan; + } + + public double getResistanceScale() { + double scale = topCellNet.getResistanceScale(); + return scale; + } + + public double getWireResistance() { + final TechnologyData td = getTechnologyData(); + + final double wireWidth = getWireWidth(); + final double unitWireResistance; + + if (td.getWireResistanceTable() == null) { + unitWireResistance = td.unitWireResistance / wireWidth; + } else { + final double wireSpace = getWireSpace(); + unitWireResistance = + Interpolate.bilinearInterpolate( + td.getWireResistanceTable(), + wireWidth, + wireSpace); + } + + return getEstimatedWireSpan() * + unitWireResistance * + getResistanceScale(); + } + + public double getWireCapacitance() { + TechnologyData td = getTechnologyData(); + + double wireWidth = getWireWidth(); + double wireSpace = getWireSpace(); + final double unitWireCapacitance; + if (td.getWireCapacitanceTable() == null) { + unitWireCapacitance = + wireWidth * td.unitWireCapacitanceCa + + 2.0 * (td.unitWireCapacitanceCfc_2 / wireSpace / wireSpace + + td.unitWireCapacitanceCfc_1 / wireSpace + + td.unitWireCapacitanceCfc_0); + } else { + unitWireCapacitance = + Interpolate.bilinearInterpolate( + td.getWireCapacitanceTable(), + wireWidth, + wireSpace); + } + + return td.capacitanceScalingFactor * + getEstimatedWireLength() * + unitWireCapacitance; + } + + public double getWireRC() { + return getWireCapacitance() * getWireResistance(); + } + + public double getGateCapacitance() { + TechnologyData td = getTechnologyData(); + + double nGateCap = 0.0; + double pGateCap = 0.0; + + for (Iterator ita = getListSinks().iterator(); ita.hasNext(); ) { + NetSink nska = (NetSink)ita.next(); + if(nska.type == NetType.HALF_OPERATOR_TRANSISTOR){ // transistor type load + NetGraph.NetEdge nea = nska.transistor; + double width = nea.width / nea.shareCount; + if (nea.type == DeviceTypes.N_TYPE) + nGateCap += width * nea.length * td.getUnitNmosGateCapacitance(nea.getTransistorType()); + else + pGateCap += width * nea.length * td.getUnitPmosGateCapacitance(nea.getTransistorType()); + } + } + + return nGateCap + pGateCap; + } + + + public double getConstCapacitance() { + double constCap = 0.0; + + for (Iterator ita = getListSinks().iterator(); ita.hasNext(); ) { + NetSink nska = (NetSink)ita.next(); + if(nska.type == NetType.CAPACITIVE_LOAD){ // constant capacitance load + constCap += nska.loadCapacitance; + } + } + + return constCap; + } + + + public double getLoadCapacitance() { + // total cap + return getWireCapacitance() + getGateCapacitance() + getConstCapacitance(); + } + + /** Used by JautoUI to dump out an info file for SDC generation. **/ + public double getDriveResistance(final HalfOperator ho1) { + final TechnologyData tech = getTechnologyData(); + final double[] effectiveResistanceFactors; + if (ho1.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + effectiveResistanceFactors = + tech.getEffectiveResistanceFactorN(ho1.getTransistorType()); + } else { + effectiveResistanceFactors = + tech.getEffectiveResistanceFactorP(ho1.getTransistorType()); + } + final double effectiveResistanceFactor = + effectiveResistanceFactors[0] / ho1.getStrengthBias(); + return effectiveResistanceFactor * tech.defaultGateLength / + ho1.getCurrentSize(); + } + + /** Add up all width driving this node. Used to size staticizers. **/ + public double getTotalDriverWidth(int type) { + double total=0; + for (Iterator ita = getListSources().iterator(); ita.hasNext(); ) { + NetSource nsrc = (NetSource)ita.next(); + if (nsrc.type != NetType.HALF_OPERATOR_TRANSISTOR) continue; + HalfOperator ho = nsrc.source; + for (Iterator itb = ho.transistors.iterator(); itb.hasNext(); ) { + NetGraph.NetEdge edge = (NetGraph.NetEdge) itb.next(); + if ((edge.type==type) && + (edge.source==ho.outputNode || edge.drain==ho.outputNode)) + total += edge.width; + } + } + return total; + } + + /** + * Construct a GlobalNet from a given top level CellNet. This constructor + * is private; use the static method + * {@link #generateGlobalNets(CellType, List) generateGlobalNets} + * to generate GlobalNets. + * + * @param cn1 The top-level CellNet. + **/ + private GlobalNet(CellNet cn1) { + topCellNet = cn1; + + listSources = + new MultiSet/**/(NetSourceComparator.getInstance()); + listSinks = new MultiSet/**/(NetSinkComparator.getInstance()); + + estimatedWireLength = -1.0; + estimatedWireSpan = -1.0; + + // TODO: should be able to do this statically somehow + // TODO: avoid missing CAST definition by declaring these as "models" + String[] n1 = {"n1"}; + String[] n2 = {"n2"}; + wireCapModel = new SimpleNetlist(HierName.makeHierName("wirecap"),n1,n2); + wireResModel = new SimpleNetlist(HierName.makeHierName("wireres"),n1,n2); + + topCellNet.setGeometry(new PointGeometry()); + } + + private CastDesign getCastDesign() { + return topCellNet.container.design; + } + + TechnologyData getTechnologyData(){ + return topCellNet.container.design.getTechnologyData(); + } + + JautoMessageCenter getMessageCenter(){ + return topCellNet.container.design.getMessageCenter(); + } + + private Cadencize getCadencize() { + return getCastDesign().getCadencize(); + } + + public double getEstimatedWireLength() { + // Cache the result, as this is a time consuming operation + if (estimatedWireLength < 0) { + estimatedWireLength = topCellNet.getAssignedWireLength(); + if (estimatedWireLength < 0) { + estimatedWireLength = maxWireLength; + } + if (estimatedWireLength < 0) { + estimatedWireLength = topCellNet.container.getAssignedWireLength(); + } + if (estimatedWireLength < 0) { + estimatedWireLength = + // min_wirespan is expected to be less than min_wirelength. + // However, use it for the wire cap determination in case + // it's larger. + Math.max(maxInternalWireLength < 0 ? + estimateWireLength() : + maxInternalWireLength, + Math.max(getMinWireLength(), + getMinWireSpan())); + } + } + assert estimatedWireLength > 0; + return estimatedWireLength; + } + + public double getEstimatedWireSpan() { + // Cache the result, as this is a time consuming operation + if (estimatedWireSpan < 0) { + estimatedWireSpan = topCellNet.getAssignedWireSpan(); + if (estimatedWireSpan < 0) { + estimatedWireSpan = maxWireSpan; + } + if (estimatedWireSpan < 0) { + estimatedWireSpan = topCellNet.container.getAssignedWireSpan(); + } + if (estimatedWireSpan < 0) { + estimatedWireSpan = topCellNet.getAssignedWireLength(); + } + if (estimatedWireSpan < 0) { + estimatedWireSpan = maxWireLength; + } + if (estimatedWireSpan < 0) { + estimatedWireSpan = topCellNet.container.getAssignedWireLength(); + } + if (estimatedWireSpan < 0) { + // If min_wirespan is specified, use it as the cast-specified + // minimum wire span. Otherwise, use min_wirelength. + final double ml = getMinWireLength(); + final double ms = getMinWireSpan(); + estimatedWireSpan = + Math.max(maxInternalWireLength < 0 ? + estimateWireSpan() : + maxInternalWireLength, + (ms >= 0.0 ? ms : ml)); + } + } + assert estimatedWireSpan > 0; + return estimatedWireSpan; + } + + /** get manhattan distance between points with X/Y scaling */ + private double manhattanDistance(double x0, double y0, double x1, double y1) { + double scaleX = getTechnologyData().layoutScaleX; + double scaleY = getTechnologyData().layoutScaleY; + return Math.abs(x1 - x0) * scaleX + Math.abs(y1 - y0) * scaleY; + } + + private double getFluteLength(Node node) { + double length = 0; + double scale = 1.0e10; + ArrayList/**/ XList = new ArrayList/**/(); + ArrayList/**/ YList = new ArrayList/**/(); + List> children = node.getChildren(); + //Hopefully a redundant check + if(children.size() < 1) { + return length; + } + BoundingBox srcbBox = node.getData(); + XList.add((int)(srcbBox.getLowerLeft().getX()*scale)); + YList.add((int)(srcbBox.getLowerLeft().getY()*scale)); + XList.add((int)(srcbBox.getUpperRight().getX()*scale)); + YList.add((int)(srcbBox.getUpperRight().getY()*scale)); + + for (Node n : children) { + BoundingBox childbBox = n.getData(); + if(n.getNumberOfChildren() > 0) { + XList.add((int)(childbBox.getLowerLeft().getX()*scale)); + YList.add((int)(childbBox.getLowerLeft().getY()*scale)); + XList.add((int)(childbBox.getUpperRight().getX()*scale)); + YList.add((int)(childbBox.getUpperRight().getY()*scale)); + length += getFluteLength(n); + } else { + Point center = childbBox.getCenter(); + XList.add((int)(center.getX()*scale)); + YList.add((int)(center.getY()*scale)); + length += childbBox.getHalfPerimeter() * 2 * + getTechnologyData().getLeafWireLengthPortScale(); + } + } + int count = XList.size(); + if(count > 1) { + int[] X = CollectionUtils.toIntArray(XList); + int[] Y = CollectionUtils.toIntArray(YList); + length += (double)(Flute.getWireLength(X,Y)/scale); + } + //if(length > 0) { + // System.out.println("flute "+node.getData()+": " + length); + //} + return length; + } + + private double steinerWireLength() { + double length = 0; + double scale = 1.0e10; + ArrayList/**/ XList = new ArrayList/**/(); + ArrayList/**/ YList = new ArrayList/**/(); + for (Node steinerNode : steinerTree.getRootNodes()) { + BoundingBox bBox = steinerNode.getData(); + if(steinerNode.getNumberOfChildren() > 0) { + XList.add((int)(bBox.getLowerLeft().getX()*scale)); + YList.add((int)(bBox.getLowerLeft().getY()*scale)); + XList.add((int)(bBox.getUpperRight().getX()*scale)); + YList.add((int)(bBox.getUpperRight().getY()*scale)); + length += getFluteLength(steinerNode); + } else { + Point center = bBox.getCenter(); + XList.add((int)(center.getX()*scale)); + YList.add((int)(center.getY()*scale)); + length += bBox.getHalfPerimeter() * 2 * + getTechnologyData().getLeafWireLengthPortScale(); + } + } + int count = XList.size(); + if(count > 1) { + int[] X = CollectionUtils.toIntArray(XList); + int[] Y = CollectionUtils.toIntArray(YList); + double top_length = (double)(Flute.getWireLength(X,Y)/scale); + //System.out.println("top_length: " + top_length); + length += top_length; + } + + // handle default + if (length <= 0.0) { + length = getTechnologyData().defaultWireLength; + } + + // handle minimum wire length + return Math.max(length,getTechnologyData().minimumWireLength); + } + + private ArrayList> getListOfNodesToClosestParent(final Node sourceNode, + final Node sinkNode) { + ArrayList/*Node*/ retList = new ArrayList/*Node*/(); + ArrayList/*Node*/ sourceParents + = (ArrayList>)sourceNode.getAllParents(); + ArrayList/*Node*/ sinkParents + = (ArrayList>)sinkNode.getAllParents(); + sourceParents.add(0,sourceNode); + sinkParents.add(0,sinkNode); + for (int iSource = 0; iSource < sourceParents.size(); ++iSource) { + Node n1 = (Node)sourceParents.get(iSource); + int index = sinkParents.indexOf(n1); + if(index != -1) { + retList.addAll(sourceParents.subList(0,iSource+1)); + retList.addAll(sinkParents.subList(0,index+1)); + return retList; + } + } + retList.addAll(sourceParents); + retList.addAll(sinkParents); + return retList; + } + + private double steinerWireSpan() { + double span = 0; + double scale = 1.0e10; + + // if no sources or no sinks, find longest span instead + ArrayList src = sourceList.size()>0 ? sourceList : sinkList; + ArrayList snk = sinkList.size()>0 ? sinkList : sourceList; + + // look for longest path from src to snk + for (Iterator i = src.iterator(); i.hasNext(); ) { + Node sourceNode = (Node) i.next(); + for (Iterator j = snk.iterator(); j.hasNext(); ) { + Node sinkNode = (Node) j.next(); + ArrayList/*Node*/ spanNodes = + getListOfNodesToClosestParent(sourceNode, + sinkNode); + ArrayList/**/ XList = new ArrayList/**/(); + ArrayList/**/ YList = new ArrayList/**/(); + double local_span = 0; + for (Iterator k = spanNodes.iterator(); k.hasNext(); ) { + Node spanNode = (Node) k.next(); + BoundingBox bBox = spanNode.getData(); + if(spanNode.getNumberOfChildren() > 0) { + XList.add((int)(bBox.getLowerLeft().getX()*scale)); + YList.add((int)(bBox.getLowerLeft().getY()*scale)); + XList.add((int)(bBox.getUpperRight().getX()*scale)); + YList.add((int)(bBox.getUpperRight().getY()*scale)); + } else { + Point center = bBox.getCenter(); + XList.add((int)(center.getX()*scale)); + YList.add((int)(center.getY()*scale)); + local_span += bBox.getHalfPerimeter() * 2 * + getTechnologyData().getLeafWireLengthPortScale(); + } + } + int[] X = CollectionUtils.toIntArray(XList); + int[] Y = CollectionUtils.toIntArray(YList); + local_span += (double)(Flute.getWireLength(X,Y)/scale); + //System.out.println("local_span: " + local_span); + span = Math.max(span, local_span); + } + } + + // handle default + if (span <= 0.0) { + span = getTechnologyData().defaultWireLength; + } + + // handle minimum wire length + return Math.max(span,getTechnologyData().minimumWireLength); + } + + /** Estimate wire length inside a leaf cell or other special cases, or -1 **/ + private double specialWireLength() { + // Use default if cell has floorplan=false + final TechnologyData tech = getTechnologyData(); + CellType cta = topCellNet.container; + if(!cta.isFloorplanned()){ + if(DebugOption.printLevel <= 1){ + System.out.println("Cell found not floorplanned: " + + topCellNet.container.typeName); + } + return tech.defaultWireLength; + } + + // Estimate wire length inside a leaf cell as width plus height + if(cta.getLevel() == 0){ + if((cta.xSize + cta.ySize) == 0.0){ + return tech.defaultWireLength; + } + else{ + final double perimeter = + 2 * (cta.xSize * tech.layoutScaleX + + cta.ySize * tech.layoutScaleY); + return tech.getLeafWireLengthScale() * perimeter; + } + } + + // Use default for "isolated" net in a mid-level cell + if(listSources.size()==0 && listSinks.size()==0){ + if(DebugOption.printLevel <= 1) { + System.out.println("WARNING: Global net with no sources or sinks"); + System.out.println("Cell name: " + topCellNet.container.typeName); + System.out.println("Net name: " + topCellNet.canonicalName.getCadenceString()); + } + return tech.defaultWireLength; + } + + // not a special case + return -1; + } + + /** + * Estimate total wire length by the "bounding box" algorithm. + * Finds the minimum rectangle box that covers all the sinks and + * sources wire_length = width + height of the + * bounding box (used for capacitance). If SrcToSnk is true, + * instead finds the maximum span from the bbox of sources to the + * bbox of sinks (used for resistance). This isn't quite + * equivalent to the maximum from all sources to all sinks, but is + * much faster and probably good enough. + **/ + private double bboxWireLength(boolean SrcToSnk) { + // Calculate bounding box of all sources + double src_left = Double.POSITIVE_INFINITY; + double src_right = Double.NEGATIVE_INFINITY; + double src_top = Double.NEGATIVE_INFINITY; + double src_bottom = Double.POSITIVE_INFINITY; + final int numSources = listSources.size(); + for (int iSource = 0; iSource < numSources; ++iSource) { + NetSource nsra = (NetSource)listSources.get(iSource); + if(nsra.type != NetType.HALF_OPERATOR_TRANSISTOR) continue; + + // get bounding box of this source + double sx, sy; + CellType ctb = nsra.source.subType; + switch(nsra.orientation){ + case ConnectionInfo.R0: + case ConnectionInfo.R180: + case ConnectionInfo.MY: + case ConnectionInfo.MX: + sx = ctb.xSize; + sy = ctb.ySize; + break; + + case ConnectionInfo.R90: + case ConnectionInfo.R270: + case ConnectionInfo.MYR90: + case ConnectionInfo.MXR90: + sx = ctb.ySize; + sy = ctb.xSize; + break; + + default: throw new AssertionError(); + } + double fl = nsra.coordinateX - sx / 2.0; + double fr = nsra.coordinateX + sx / 2.0; + double fb = nsra.coordinateY - sy / 2.0; + double ft = nsra.coordinateY + sy / 2.0; + + // add to bounding box of all sources + if (fl < src_left) src_left = fl; + if (fr > src_right) src_right = fr; + if (fb < src_bottom) src_bottom = fb; + if (ft > src_top) src_top = ft; + } + + // Calculate bounding box of all sinks + double snk_left = Double.POSITIVE_INFINITY; + double snk_right = Double.NEGATIVE_INFINITY; + double snk_top = Double.NEGATIVE_INFINITY; + double snk_bottom = Double.POSITIVE_INFINITY; + final int numSinks = listSinks.size(); + for (int iSink = 0; iSink < numSinks; ++iSink) { + NetSink nska = (NetSink) listSinks.get(iSink); + if(nska.type != NetType.HALF_OPERATOR_TRANSISTOR) continue; + + // get bounding box of this sink + double sx, sy; + CellType ctb = nska.sink.subType; + switch(nska.orientation){ + case ConnectionInfo.R0: + case ConnectionInfo.R180: + case ConnectionInfo.MY: + case ConnectionInfo.MX: + sx = ctb.xSize; + sy = ctb.ySize; + break; + + case ConnectionInfo.R90: + case ConnectionInfo.R270: + case ConnectionInfo.MYR90: + case ConnectionInfo.MXR90: + sx = ctb.ySize; + sy = ctb.xSize; + break; + + default: throw new AssertionError(); + } + double fl = nska.coordinateX - sx / 2.0; + double fr = nska.coordinateX + sx / 2.0; + double fb = nska.coordinateY - sy / 2.0; + double ft = nska.coordinateY + sy / 2.0; + + // add to bounding box of all sources + if (fl < snk_left) snk_left = fl; + if (fr > snk_right) snk_right = fr; + if (fb < snk_bottom) snk_bottom = fb; + if (ft > snk_top) snk_top = ft; + } + + // Calculate bounding box of all sources and sinks + double left = Math.min(snk_left,src_left); + double right = Math.max(snk_right,src_right); + double bottom = Math.min(snk_bottom,src_bottom); + double top = Math.max(snk_top,src_top); + + // choose length estimate + double length = -1; + if (SrcToSnk && + src_left!=Double.POSITIVE_INFINITY && + snk_left!=Double.POSITIVE_INFINITY) { + + // maximum distance between all corners of both bboxs + for (int i=0; i<16; i++) { + double x0 = (i&1)!=0 ? src_left : src_right; + double y0 = (i&2)!=0 ? src_bottom : src_top; + double x1 = (i&4)!=0 ? snk_left : snk_right; + double y1 = (i&8)!=0 ? snk_bottom : snk_top; + double x = manhattanDistance(x0,y0,x1,y1); + if (x>length) length = x; + } + } + else if (left != Double.POSITIVE_INFINITY) { + // maximum distance between any corners of the bbox + length = manhattanDistance(left,bottom,right,top); + } + + // handle default wire length + if (length <= 0.0) { + length = getTechnologyData().defaultWireLength; + } + + // handle minimum wire length + if (length < getTechnologyData().minimumWireLength) { + length = getTechnologyData().minimumWireLength; + } + + return length; + } + + private double estimateWireLength() { + double l = specialWireLength(); + if (l>=0) return l; + if (getCastDesign().useSteinerTree()) return steinerWireLength(); + else return bboxWireLength(false); + } + + private double estimateWireSpan() { + double l = specialWireLength(); + if (l>=0) return l; + if (getCastDesign().useSteinerTree()) return steinerWireSpan(); + else return bboxWireLength(true); + } + + /** + * Determines if this global net is driven by the specified + * half-operator, ie if the half-operator is a source of one + * of the source nets. Used only for an assert. + **/ + private boolean isDrivenByHalfOperator + (final /*@ non_null @*/ HalfOperator ho1) { + // find the source in the list + final int numSources = listSources.size(); + for (int iSource = 0; iSource < numSources; ++iSource) { + NetSource nsra = (NetSource) listSources.get(iSource); + if (nsra.type == NetType.HALF_OPERATOR_TRANSISTOR) { + if (nsra.source == ho1) { + return true; + } + } + } + + return false; + } + + private static double getPrechargeLoad(final HalfOperator op, + final TechnologyData tech) { + return op.getPrechargeNodes().size() * + tech.getPrechargeTransistorLoad(); + } + + private static void debugTerm(final String msg, final FunctionTerm ftma) { + if (DebugOption.printLevel <= 1) + System.out.println(msg + ftma.toString()); + } + + private static void debugTerm(final String msg, final AdditiveTerms ftma) { + if (DebugOption.printLevel <= 1 && !ftma.isEmpty()) + System.out.println(msg + ftma.toString()); + } + + /** + * Returns the gate cap on node due to feedback transistor + * e. + **/ + private static double getStaticizerGateCap(final NetGraph.NetEdge e, + final NetGraph.NetNode node, + final TechnologyData tech, + final HierName inst) { + double result = 0; + + if (e.gate == node && (!e.isUsedLogic() || e.isSmallInverter())) { + result = e.width * e.length / e.shareCount * + tech.getUnitGateCapacitance(e.type, e.getTransistorType()); + if (DebugOption.printLevel <= 1) { + System.out.format("Staticizer gate cap: inst=%s cap=%g\n%s\n", + inst, result, e); + + } + } + + return result; + } + + /** + * Returns the diffusion cap on node due to feedback + * transistors e. + **/ + private static double getStaticizerDiffusionCap(final NetGraph.NetEdge e, + final NetGraph.NetNode node, + final TechnologyData tech, + final HierName inst) { + double result = 0; + + if (!e.isUsedLogic() && (e.drain == node || e.source == node)) { + result = e.width * + tech.getUnitDiffusionCapacitance(e.type, + e.getTransistorType()); + if (DebugOption.printLevel <= 1) { + System.out.format("Staticizer diff cap: inst=%s cap=%g\n%s\n", + inst, result, e); + } + } + + return result; + } + + /** + * Returns the total gate and diffusion cap on node due to + * feedback transistors. + **/ + private static AdditiveTerms getStaticizerLoad( + final NetGraph transistors, + final NetGraph.NetNode node, + final HierName inst, + final Set> seen, + final TechnologyData tech) { + double cap = 0; + if (seen.add(new Pair(inst, node))) { + for (Iterator i = transistors.getEdges().iterator(); i.hasNext(); ) + { + final NetGraph.NetEdge e = (NetGraph.NetEdge) i.next(); + cap += getStaticizerGateCap(e, node, tech, inst) + + getStaticizerDiffusionCap(e, node, tech, inst); + } + } + + return cap == 0 ? new AdditiveTerms(0) + : new AdditiveTerms(new FunctionTerm(cap)); + } + + /** + * get localnode delay function + * + * Returns delay function for halfoperator "ho1" to drive this + * global net. The delay function is an ArrayList of + * FunctionTerm's. + * + * Uses Elmore delay model with intrinsic delay. + * Uses Pi model for wiring, with C_wire/2 on either side of R_wire. + * + * delay = intrinsic_delay + + * R_tran * (C_wire + C_tran + C_diffusion + C_extra) + + * R_wire * (C_wire/2 + C_tran_far + C_diffusion_far + C_extra) + * + * C_tran_far includes only sinks that are not in the same leaf + * instance as the driver. C_diffusion_far includes only sources + * that are not in the same leaf instance as the driver. The + * driver leaf instance is arbitrarily chosen as the instanceName + * of the first netSource that maches ho1. + **/ + public void getDelayFunction(HalfOperator ho1, + List delayFunction) { + TechnologyData tech = getTechnologyData(); + + // get wire capacitance and wire resistance + double wireCap = getWireCapacitance(); + double wireRes = getWireResistance(); + double totalCap = wireCap; + + // debugging + if (DebugOption.printLevel <= 1) { + System.out.println("Computing delay for half-operator: " + + ho1.subType.typeName + "/" + + ho1.outputNode.name + + (ho1.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + '-' : '+') + " with top net " + + topCellNet.canonicalName + " in " + + topCellNet.container.typeName); + System.out.println("Estimated wire length: " + getEstimatedWireLength()); + System.out.println("Estimated wire capacitance: " + wireCap); + System.out.println("Estimated wire resistance: " + wireRes); + } + + // process resistance shielding factor and threshold + double resistanceShieldingFactor; + if(wireRes > tech.resistanceShieldingThreshold){ + resistanceShieldingFactor = tech.resistanceShieldingFactor; + } + else{ + resistanceShieldingFactor = 1.0; + } + + // error if "ho1" is not a driver of this net + assert isDrivenByHalfOperator(ho1) + : "This halfoperator is not a source of the globalnet.\n" + + "CellName: " + ho1.outputNet.container.typeName + "\n" + + "NetName: " + ho1.outputNet.canonicalName.getCadenceString() + + (ho1.driveDirection == HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+"); + + // check depth + assert ho1.getMaxDepth() > 0 + : "Incorrect number for maxDepth of a half-operator.\n" + + "CellName: " + ho1.outputNet.container.typeName + "\n" + + "NetName: " + ho1.outputNet.canonicalName.getCadenceString() + + (ho1.driveDirection == HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+"); + + // get gate parameters if any + Float directiveIntrinsicDelay = null; + if (tech.getUseIntrinsicCap()) { + // Does the half-operator match a gate? + final NetGraph.GateInstance gate = ho1.outputNode.getGate(); + if (gate != null) { + final HierName portName = + gate.getPortName(ho1.outputNode.getName()); + + // find the directives we need + final CellInterface gateCell = + getCastDesign().getCellForGate(gate); + directiveIntrinsicDelay = (Float) + DirectiveUtils.getHalfOpDirectiveValue(gateCell, + DirectiveConstants.INTRINSIC_DELAY, + portName, + ho1.driveDirection == + HalfOperator.DriveDirection.PULL_UP, + getCadencize()); + } + } + + // get stack parameters + final int stackLimit; + final double[] gateIntrinsicDelay; + final double[] effectiveResistanceFactors; + if (ho1.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + stackLimit = tech.stackLimitN; + gateIntrinsicDelay = tech.getGateIntrinsicDelayN(ho1.getTransistorType()); + effectiveResistanceFactors = tech.getEffectiveResistanceFactorN(ho1.getTransistorType()); + } else { + stackLimit = tech.stackLimitP; + gateIntrinsicDelay = tech.getGateIntrinsicDelayP(ho1.getTransistorType()); + effectiveResistanceFactors = tech.getEffectiveResistanceFactorP(ho1.getTransistorType()); + } + + final double intrinsicDelay; + if (directiveIntrinsicDelay != null) { + intrinsicDelay = directiveIntrinsicDelay.floatValue(); + } else { + final int maxDepth = Math.min(ho1.getMaxDepth(), stackLimit); + intrinsicDelay = gateIntrinsicDelay[maxDepth - 1]; + } + + // intrinsic delay + if (intrinsicDelay != 0.0) { + FunctionTerm ftm = new FunctionTerm(); + ftm.type = FunctionTerm.Type.CONSTANT; + ftm.coefficient = intrinsicDelay; + delayFunction.add(ftm); + if (DebugOption.printLevel <= 1) + System.out.println("Intrinsic Delay: " + + ftm.coefficient); + } + + // Always use effectiveResistanceFactor for depth 1, even + // when that is not the maxDepth. This normalizes everything to + // inverters. + final double effectiveResistanceFactor = + effectiveResistanceFactors[0] / ho1.getStrengthBias(); + + if (DebugOption.printLevel <= 1) { + System.out.println("Intrinsic delay is: " + intrinsicDelay); + System.out.println("initial R_gate: " + effectiveResistanceFactor); + System.out.println("strength_bias: " + ho1.getStrengthBias()); + System.out.println("R_gate: " + effectiveResistanceFactor); + System.out.println("half-operator: " + ho1.subType.typeName + "/" + + ho1.outputNode.name + + (ho1.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + '-' : '+')); + } + + // Find first netSource with ho1 and use its instanceName as + // sourceInstName. For localnodes of leaf cells, this is null + // and all sinks are considered far and sources considered + // near. + if (listSources.isEmpty()){ + return; + } + NetSource hoNetSource = null; + for (Iterator i = listSources.iterator(); i.hasNext(); ) { + NetSource netSource = (NetSource) i.next(); + if (netSource.type == NetType.HALF_OPERATOR_TRANSISTOR && + netSource.source == ho1) { + hoNetSource = netSource; + break; + } + } + assert hoNetSource != null; + HierName sourceInstName = hoNetSource.getInstanceName(); + if (DebugOption.printLevel<=1) + System.out.println("sourceInstName=" + sourceInstName); + + // Find sources on the far side of the resistive wire. + // Sources connected internally within the driving leaf cell + // are considered near (before the resistor). + ArrayList farSources = new ArrayList(); + for (Iterator i = listSources.iterator(); i.hasNext(); ) { + NetSource netSource = (NetSource) i.next(); + HierName instName = netSource.getInstanceName(); + if (netSource.type == NetType.HALF_OPERATOR_TRANSISTOR && + sourceInstName == null) { + if (DebugOption.printLevel<=1) + System.out.println("leafSource: " + netSource); + } + else if (netSource.type == NetType.HALF_OPERATOR_TRANSISTOR && + instName != null && sourceInstName != null && + instName.equals(sourceInstName)) { + if (DebugOption.printLevel<=1) + System.out.println("nearSource: " + netSource); + } + else { + if (DebugOption.printLevel<=1) + System.out.println("farSource: " + netSource); + farSources.add(netSource); + } + } + + // Find sinks on the far side of the resistive wire. Sinks + // connected internally within the driving leaf cell are + // considered far (after the resistor). + ArrayList farSinks = new ArrayList(); + for (Iterator i = listSinks.iterator(); i.hasNext(); ) { + NetSink netSink = (NetSink) i.next(); + HierName instName = netSink.getInstanceName(); + if (netSink.type == NetType.HALF_OPERATOR_TRANSISTOR && + instName != null && sourceInstName != null && + instName.equals(sourceInstName)) { + if (DebugOption.printLevel<=1) + System.out.println("nearSink: " + netSink); + } + else { + if (DebugOption.printLevel<=1) + System.out.println("farSink: " + netSink); + farSinks.add(netSink); + } + } + + AdditiveTerms ftma; + + // for convenience R_tran also includes elmoreDelayFactor and + // resistanceShieldingFactor + final AdditiveTerms R_tran = + new AdditiveTerms( + ho1.getResistanceTerm().multiply( + new FunctionTerm(tech.elmoreDelayFactor * + resistanceShieldingFactor))); + + // R_tran * C_total + final FunctionTerm C_total = new FunctionTerm(totalCap); + ftma = R_tran.multiply(C_total); + delayFunction.addAll(ftma); + debugTerm("Delay from R_tran * C_total: ", ftma); + + final Set> staticizerProcessed = + new HashSet>(); + for (Iterator i = listSinks.iterator(); i.hasNext(); ) { + NetSink nska = (NetSink) i.next(); + + // R_tran * C_tran + if (nska.type == NetType.HALF_OPERATOR_TRANSISTOR) { + // netsink is a halfoperator + final AdditiveTerms C_tran = nska.getGateCapacitanceTerm(); + ftma = R_tran.multiply(C_tran); + delayFunction.addAll(ftma); + debugTerm("Delay from R_tran * C_tran: ", ftma); + + ftma = R_tran.multiply + (getStaticizerLoad(nska.sink.subType.transistors, + nska.transistor.gate, + nska.getInstanceName(), + staticizerProcessed, + tech)); + delayFunction.addAll(ftma); + debugTerm("Delay from R_tran * C_stat: ", ftma); + } + + // R_tran * C_extra + if (nska.type == NetType.CAPACITIVE_LOAD) { + // netsink is a constant capacitive load + final FunctionTerm C_extra = + new FunctionTerm(nska.getLoadCapacitance()); + ftma = R_tran.multiply(C_extra); + delayFunction.addAll(ftma); + debugTerm("Delay from R_tran * C_extra: ", ftma); + } + } + + // R_tran * C_diffusion + for (Iterator i = listSources.iterator(); i.hasNext(); ) { + NetSource nsrca = (NetSource) i.next(); + if (nsrca.type != NetType.HALF_OPERATOR_TRANSISTOR) continue; + + final AdditiveTerms C_diffusion = + nsrca.source.getDiffusionCapacitanceTerm(); + ftma = R_tran.multiply(C_diffusion); + delayFunction.addAll(ftma); + debugTerm("Delay from R_tran * C_diffusion: ", ftma); + + ftma = R_tran.multiply + (getStaticizerLoad(nsrca.source.subType.transistors, + nsrca.source.outputNode, + nsrca.getInstanceName(), + staticizerProcessed, + tech)); + delayFunction.addAll(ftma); + debugTerm("Delay from R_tran * C_stat: ", ftma); + } + + // for convenience, R_wire includes wireRCDelayFactor + final AdditiveTerms R_wire = + new AdditiveTerms( + new FunctionTerm(wireRes * tech.wireRCDelayFactor)); + final FunctionTerm C_wire = new FunctionTerm(wireCap); + + // R_wire * C_wire / 2 + ftma = R_wire.multiply(C_wire).multiply(new FunctionTerm(0.5)); + delayFunction.addAll(ftma); + debugTerm("Delay from R_wire * C_wire / 2: ", ftma); + + staticizerProcessed.clear(); + for (Iterator i = farSinks.iterator(); i.hasNext(); ) { + NetSink nska = (NetSink) i.next(); + + // R_wire * C_tran_far + if (nska.type == NetType.HALF_OPERATOR_TRANSISTOR) { + // netsink is a halfoperator + final AdditiveTerms C_tran_far = nska.getGateCapacitanceTerm(); + ftma = R_wire.multiply(C_tran_far); + delayFunction.addAll(ftma); + debugTerm("Delay from R_wire * C_tran_far: ", ftma); + + ftma = R_wire.multiply + (getStaticizerLoad(nska.sink.subType.transistors, + nska.transistor.gate, + nska.getInstanceName(), + staticizerProcessed, + tech)); + delayFunction.addAll(ftma); + debugTerm("Delay from R_wire * C_stat_far: ", ftma); + } + + // R_wire * C_extra + if (nska.type == NetType.CAPACITIVE_LOAD) { + final FunctionTerm C_extra = + new FunctionTerm(nska.getLoadCapacitance()); + ftma = R_wire.multiply(C_extra); + delayFunction.addAll(ftma); + debugTerm("Delay from R_wire * C_extra: ", ftma); + } + } + + // R_wire * C_diffusion_far + for (Iterator i = farSources.iterator(); i.hasNext(); ) { + NetSource nsrca = (NetSource) i.next(); + if (nsrca.type != NetType.HALF_OPERATOR_TRANSISTOR) continue; + + final AdditiveTerms C_diffusion_far = + nsrca.source.getDiffusionCapacitanceTerm(); + ftma = R_wire.multiply(C_diffusion_far); + delayFunction.addAll(ftma); + debugTerm("Delay from R_wire * C_diffusion_far: ", ftma); + + ftma = R_wire.multiply + (getStaticizerLoad(nsrca.source.subType.transistors, + nsrca.source.outputNode, + nsrca.getInstanceName(), + staticizerProcessed, + tech)); + delayFunction.addAll(ftma); + debugTerm("Delay from R_wire * C_stat_far: ", ftma); + } + } + + + + // Global nets generation from the original design + // * This is be done everytime any sub-typing is done + // Main algorithm: + // 1. The objective of this function is to assign a list of "global nets" to "local nets" defined + // in all sub-types in a design. + // 2. The "global nets" are used for transistor sizing purpose, for path generation and delay + // calculation. + // 3. The outputs of this function are: a list of all global nets, lists of "NetSource" and "NetSink" + // for each global net, list of global nets for each half-operator in the design. + // + // Description: + // + // L is a sorted list of sub-types, the sub-types in the list are sorted from high to low according + // to their level number (number of hierarchies). + // L.add(top-level sub-type); + // while (L is not empty){ + // S = L.get(0); + // for each not-port net in S { + // generate a new global net; + // add the pointer of the new global net to the "global net list" of the cell-net; + // } + // for each net in S { + // update the source/sink lists of the corresponding global nets; + // propagate the global net list to the lower-level sub-types; + // } + // add all the sub-types in S to L sorted; + // } + // + // * Hope it works fine. + + + interface ConstructionListener { + void addCellNet(GlobalNet gn, CellNet cn); + } + + public static void generateGlobalNets( + CellType top, + List/**/ generatedGlobalNets) { + generateGlobalNets(top, generatedGlobalNets, + new ConstructionListener() { + public void addCellNet(GlobalNet gn, CellNet cn) { } + }); + } + + public static void generateGlobalNets( + CellType top, + List/**/ generatedGlobalNets, + ConstructionListener listener) { + // top: pointer to the top-level cell + // generatedGlobalNets: pointer to the list to store all the global nets + if(DebugOption.printLevel <= 1){ + System.out.println("******** Start of Global Net Generation *************"); + } + + // sorted list of all the cells to be processed + List/**/ cellTypes = new ArrayList/**/(); + + cellTypes.add(top); // initialize the list with the top-level sub-type + while (!cellTypes.isEmpty()) { + CellType sta = (CellType) cellTypes.get(0); // get the first sub-type in the sorted list + if(DebugOption.printLevel <= 1){ + System.out.println("***********************************************************"); + sta.print(); + System.out.println("***********************************************************"); + } + + // get all the nets in this cell + Set/**/ allNets = sta.getAllNets(); + + // Generate new global nets for needed cell-nets + for (Iterator ita = allNets.iterator(); ita.hasNext(); ) { + CellNet cnta = (CellNet)ita.next(); // next net + if(DebugOption.printLevel <= 1){ + cnta.print(new PrintWriter(System.out)); + } + + List/**/ globalNetsForCellNet = + cnta.getGlobalNets(); + + if(cnta.isPortNet()){ // this is a port net + // REVIEW: can we make an assertion that the top level cell + // never has ports? + if (globalNetsForCellNet.isEmpty()) { // this must be the top-level cell + GlobalNet gnta = new GlobalNet(cnta); // create a new global net + if(DebugOption.printLevel <= 1){ + System.out.println(cnta.canonicalName.getCadenceString() + " port net, global net created"); + System.out.println("-------------------------------------------------\n"); + } + generatedGlobalNets.add(gnta); + globalNetsForCellNet.add(gnta); + gnta.updateWireParam(cnta); + listener.addCellNet(gnta, cnta); + } + else{ // this is not a top-level cell + if(DebugOption.printLevel <= 1){ + System.out.println(cnta.canonicalName.getCadenceString() + " port net, Nothing created"); + System.out.println("-------------------------------------------------\n"); + } + // will not create new global net for its port nets + } + } + else{ // this is an internal net + + // the list must be empty for non-top-level cells + assert globalNetsForCellNet.isEmpty() + : "Internal net has non-empty list of global " + + "nets before being processed for the first time.\n" + + "CellName: " + sta.typeName + "\n" + + "NetName: " + + cnta.canonicalName.getCadenceString(); + + GlobalNet gnta = new GlobalNet(cnta); // create a new global net + if(DebugOption.printLevel <= 1){ + System.out.println(cnta.canonicalName.getCadenceString() +" internal net, global net created"); + System.out.println("-------------------------------------------------\n"); + } + generatedGlobalNets.add(gnta); + globalNetsForCellNet.add(gnta); + gnta.updateWireParam(cnta); + listener.addCellNet(gnta, cnta); + } + + // Generate special global net for load directives + double load = cnta.getAssignedLoad(); + assert load == 0.0; + // REVIEW: The code below looks completely wrong, hence + // the above assertion. The load is dealt with elsewhere, + // but it's unclear if that handling is correct. + if(load > 0.0){ + GlobalNet gnta = new GlobalNet(cnta); + if(DebugOption.printLevel <= 1){ + System.out.println("-------------------------------------------------\n"); + System.out.println("Special global net generated for load directives"); + System.out.println("-------------------------------------------------\n"); + } + generatedGlobalNets.add(gnta); + globalNetsForCellNet.add(gnta); + } + + } // for allNets + + + // Update source/sink lists, and their coordinates + if(DebugOption.printLevel <= 1){ + System.out.println("***********************************************************"); + System.out.println("Update list of sources, list of sinks, orientations, and coordinates"); + System.out.println("***********************************************************"); + } + + for (Iterator ita = allNets.iterator(); ita.hasNext(); ) { + CellNet cnta = (CellNet)ita.next(); // get next net + + List/**/ sourcesForCellNet = cnta.getListSources(); // list of sources for the cell net + List/**/ sinksForCellNet = cnta.getListSinks(); // list of sinks for the cell net + + if(DebugOption.printLevel <= 1){ + System.out.println("-------------------------------------------------------------"); + System.out.println(cnta.canonicalName.getCadenceString()); + System.out.println("n_sources = " + + sourcesForCellNet.size()); + for (int iSource = 0; iSource < sourcesForCellNet.size(); ++iSource) { + NetSource nsra = (NetSource)sourcesForCellNet.get(iSource); + System.out.println("nsra "+nsra); + } + System.out.println("n_sinks = " + + sinksForCellNet.size()); + for (int iSink = 0; iSink < sinksForCellNet.size(); ++iSink) { + NetSink nska = (NetSink)sinksForCellNet.get(iSink); + System.out.println("nska "+nska); + } + System.out.println("n_globalnets = " + cnta.getGlobalNets().size()); + } + + if(cnta.isPortNet()){ // must update x/y coordinates for port nets + for (Iterator itb = cnta.getGlobalNets().iterator(); + itb.hasNext(); ) { + GlobalNet gnta = (GlobalNet)itb.next(); + int numSources = 0; + int numSinks = 0; + + + // processing net sources first + List/**/ newSources = + new ArrayList/**/(); + List/**/ newSinks = + new ArrayList/**/(); + + for (Iterator itc = gnta.listSources.iterator(); itc.hasNext(); ) { + NetSource nsra = (NetSource)itc.next(); + + if(nsra.type == NetType.CELL){ + if((nsra.cellSource == sta) &&(nsra.setSubcellNets.contains(cnta))){ + // look for this cell and this net in list + + double cx = nsra.coordinateX; + double cy = nsra.coordinateY; + + for (Iterator itd = sourcesForCellNet.iterator(); itd.hasNext(); ) { + NetSource nsrb = (NetSource)itd.next(); + + NetSource nsrc = new NetSource(nsrb); + + double[] e = + transformCoordinates(nsra.orientation, + cx, cy, + nsrc.coordinateX, + nsrc.coordinateY); + nsrc.coordinateX = e[0]; + nsrc.coordinateY = e[1]; + + nsrc.updateOrientation(nsra.orientation); + nsrc.prefixInstanceName(nsra.getInstanceName()); + if(sta.getLevel() > 0){ + HierName childNetName = null; + for (Iterator ite = cnta.subcellconnectionNames.iterator(); ite.hasNext(); ) { + HierName h = (HierName) ite.next(); + ConnectionInfo ci = (ConnectionInfo) sta.getSubcellConnectedTo(h); + if((ci != null) && (ci.nameInParent.equals(nsrb.getInstanceName()))) { + childNetName = ci.getChildName(h); + if(childNetName != null) { + break; + } + } + } + assert childNetName != null; + CellType.PortInfo pi = nsrb.cellSource.getPortInfoForPinNamed(childNetName); + assert pi != null; + //System.out.println("Update1 nsrc "+nsrc); + //System.out.println("Update1 bBox "+pi.bBox); + if(pi.bBox != null) { + final Point ll = pi.bBox.getLowerLeft(); + final Point ur = pi.bBox.getUpperRight(); + double[] ell = transformCoordinates(nsrc.orientation, + nsrc.coordinateX, + nsrc.coordinateY, + ll.getX(), + ll.getY()); + + double[] eur = transformCoordinates(nsrc.orientation, + nsrc.coordinateX, + nsrc.coordinateY, + ur.getX(), + ur.getY()); + BoundingBox NewbBox = new BoundingBox(ell[0], + ell[1], + eur[0], + eur[1]); + //System.out.println("Update1 after bBox "+NewbBox); + Node newSrc = new Node(NewbBox); + //Do not start the tree until you find + //routed or a leaf cell + if(CellUtils.isRouted(nsrc.cellSource.cast_cell) || + (nsrc.cellSource.getLevel() == 0)) { + Tree newTree = new Tree(); + newTree.setRootElement(newSrc); + gnta.steinerTree.addRoot(newTree); + if(nsrc.cellSource.getLevel() == 0) { + gnta.sourceList.add(newSrc); + } + } + } + } + newSources.add(nsrc); + ++numSources; + } // for sourcesForCellNet + + if (cnta.portDirection == CellNet.OUTPUT) { + // OUTPUT port with sinks + if (DebugOption.printLevel <= 2) { + if (!sinksForCellNet.isEmpty()) { + System.out.println("NOTE: Found output port with sinks " + sta.typeName + + " " + cnta.canonicalName.getCadenceString()); + } + } + + for (Iterator itd = sinksForCellNet.iterator(); itd.hasNext(); ) { + NetSink nskb = (NetSink)itd.next(); + + assert nskb.type == NetType.CAPACITIVE_LOAD + : "Output port net can only have capacitor-type sink."; + + NetSink nskc = new NetSink(nskb); + + double[] e = + transformCoordinates(nsra.orientation, + cx, cy, + nskc.coordinateX, + nskc.coordinateY); + nskc.coordinateX = e[0]; + nskc.coordinateY = e[1]; + + nskc.updateOrientation(nsra.orientation); + + newSinks.add(nskc); + ++numSinks; + } // for sinksForCellNet + } // if cnta.portDirection == CellNet.OUTPUT + } // if + } // if nsra.type == NetType.CELL + } // for gnta.listSources + + gnta.listSources.addAll(newSources); + gnta.listSinks.addAll(newSinks); + + + if(DebugOption.printLevel <= 1){ + System.out.println("\t\tNumber of sources: " + + numSources); + } + + + + // processing net sinks next + newSinks.clear(); + + for (Iterator itc = gnta.listSinks.iterator(); itc.hasNext(); ) { + NetSink nska = (NetSink)itc.next(); + if(nska.type == NetType.CELL){ + if((nska.cellSink == sta) && (nska.setSubcellNets.contains(cnta))){ + // look for this cell in list + + double cx = nska.coordinateX; + double cy = nska.coordinateY; + + for (Iterator itd = sinksForCellNet.iterator(); itd.hasNext(); ) { + NetSink nskb = (NetSink)itd.next(); + + NetSink nskc = new NetSink(nskb); + + double[] e = + transformCoordinates(nska.orientation, + cx, cy, + nskc.coordinateX, + nskc.coordinateY); + + nskc.coordinateX = e[0]; + nskc.coordinateY = e[1]; + + nskc.updateOrientation(nska.orientation); + nskc.prefixInstanceName(nska.getInstanceName()); + + if(sta.getLevel() > 0 && + nskb.type == NetType.CELL){ + HierName childNetName = null; + for (Iterator ite = cnta.subcellconnectionNames.iterator(); ite.hasNext(); ) { + HierName h = (HierName) ite.next(); + ConnectionInfo ci = (ConnectionInfo) sta.getSubcellConnectedTo(h); + if((ci != null) && (ci.nameInParent.equals(nskb.getInstanceName()))) { + childNetName = ci.getChildName(h); + if(childNetName != null) { + break; + } + } + } + assert childNetName != null; + CellType.PortInfo pi = nskb.cellSink.getPortInfoForPinNamed(childNetName); + assert pi != null; + if(pi.bBox != null) { + final Point ll = pi.bBox.getLowerLeft(); + final Point ur = pi.bBox.getUpperRight(); + double[] ell = transformCoordinates(nskc.orientation, + nskc.coordinateX, + nskc.coordinateY, + ll.getX(), + ll.getY()); + + double[] eur = transformCoordinates(nskc.orientation, + nskc.coordinateX, + nskc.coordinateY, + ur.getX(), + ur.getY()); + BoundingBox NewbBox = new BoundingBox(ell[0], + ell[1], + eur[0], + eur[1]); + //System.out.println("Update3 after bBox "+NewbBox); + + Node newSink = new Node(NewbBox); + if((CellUtils.isRouted(nskc.cellSink.cast_cell) || + (nskc.cellSink.getLevel() == 0))) { + Tree newTree = new Tree(); + newTree.setRootElement(newSink); + gnta.steinerTree.addRoot(newTree); + if(nskc.cellSink.getLevel() == 0) { + gnta.sinkList.add(newSink); + } + } + } + } + newSinks.add(nskc); + ++numSinks; + } // for sinksForCellNet + } // if + } // if nska.type == NetType.CELL + } // for gnta.listSinks + + gnta.listSinks.addAll(newSinks); + + if(DebugOption.printLevel <= 1){ + System.out.println("\t\tNumber of sinks: " + + numSinks); + } + } // for cnta.getGlobalNets() + } + else{ // internal nets + // there should be only ONE global net for each internal net + assert cnta.getGlobalNets().size() == 1; + GlobalNet gnta = (GlobalNet) cnta.getGlobalNets().get(0); + gnta.listSources.addAll(sourcesForCellNet); // add all sources to the list + gnta.listSinks.addAll(sinksForCellNet); // add all sinks to the list + + if((sta.typeName != "") && (sta.getLevel() > 0)) { // not a top cell + + for (Iterator itc = gnta.listSources.iterator(); itc.hasNext(); ) { + NetSource nsra = (NetSource)itc.next(); + if(nsra.type == NetType.CELL){ + //Check if it is routed or a leaf cell + if(CellUtils.isRouted(nsra.cellSource.cast_cell) || + (nsra.cellSource.getLevel() == 0)) { + + HierName childNetName = null; + for (Iterator ite = cnta.subcellconnectionNames.iterator(); ite.hasNext(); ) { + HierName h = (HierName) ite.next(); + ConnectionInfo ci = (ConnectionInfo) sta.getSubcellConnectedTo(h); + if((ci != null) && (ci.nameInParent.equals(nsra.getInstanceName()))) { + childNetName = ci.getChildName(h); + if(childNetName != null) { + break; + } + } + } + assert childNetName != null; + CellType.PortInfo pi = nsra.cellSource.getPortInfoForPinNamed(childNetName); + assert pi != null; + + if(pi.bBox != null) { + final Point ll = pi.bBox.getLowerLeft(); + final Point ur = pi.bBox.getUpperRight(); + double[] ell = transformCoordinates(nsra.orientation, + nsra.coordinateX, + nsra.coordinateY, + ll.getX(), + ll.getY()); + + double[] eur = transformCoordinates(nsra.orientation, + nsra.coordinateX, + nsra.coordinateY, + ur.getX(), + ur.getY()); + BoundingBox NewbBox = new BoundingBox(ell[0], + ell[1], + eur[0], + eur[1]); + + Node rootSrc = new Node(NewbBox); + Tree newTree = new Tree(); + newTree.setRootElement(rootSrc); + gnta.steinerTree.addRoot(newTree); + if(nsra.cellSource.getLevel() == 0) { + gnta.sourceList.add(rootSrc); + } + } + } + } + } + + for (Iterator itc = gnta.listSinks.iterator(); itc.hasNext(); ) { + NetSink nska = (NetSink)itc.next(); + if(nska.type == NetType.CELL){ + //Check if it is routed or a leaf cell + if(CellUtils.isRouted(nska.cellSink.cast_cell) || + (nska.cellSink.getLevel() == 0)) { + + HierName childNetName = null; + for (Iterator ite = cnta.subcellconnectionNames.iterator(); ite.hasNext(); ) { + HierName h = (HierName) ite.next(); + ConnectionInfo ci = (ConnectionInfo) sta.getSubcellConnectedTo(h); + if((ci != null) && (ci.nameInParent.equals(nska.getInstanceName()))) { + childNetName = ci.getChildName(h); + if(childNetName != null) { + break; + } + } + } + assert childNetName != null; + CellType.PortInfo pi = nska.cellSink.getPortInfoForPinNamed(childNetName); + assert pi != null; + + if(pi.bBox != null) { + final Point ll = pi.bBox.getLowerLeft(); + final Point ur = pi.bBox.getUpperRight(); + double[] ell = transformCoordinates(nska.orientation, + nska.coordinateX, + nska.coordinateY, + ll.getX(), + ll.getY()); + + double[] eur = transformCoordinates(nska.orientation, + nska.coordinateX, + nska.coordinateY, + ur.getX(), + ur.getY()); + BoundingBox NewbBox = new BoundingBox(ell[0], + ell[1], + eur[0], + eur[1]); + + Node rootSink = new Node(NewbBox); + Tree newTree = new Tree(); + newTree.setRootElement(rootSink); + gnta.steinerTree.addRoot(newTree); + if(nska.cellSink.getLevel() == 0) { + gnta.sinkList.add(rootSink); + } + } + } + } + } + } + } + + } // for allNets + + + + + // Propagate global net one-level down for non-leaf cells + if(sta.getLevel() > 0){ + if(DebugOption.printLevel <= 1){ + System.out.println("***********************************************************"); + System.out.println("Propagating global nets into lower hierarchies"); + System.out.println("***********************************************************"); + } + for (Iterator ita = allNets.iterator(); ita.hasNext(); ) { + CellNet cnta = (CellNet)ita.next(); + if(DebugOption.printLevel <= 1){ + System.out.println("Net names:"); + System.out.println(cnta.toString()); + } + + if(DebugOption.printLevel <= 1){ + System.out.println("\tNumber of nets in subcells: " + + cnta.getSetSubcellNets(true).size()); + System.out.println("\tList of subcell connections:\n"); + } + + for (Iterator itb = cnta.getSetSubcellNets(true).iterator(); + itb.hasNext(); ) { + CellNet cntb = (CellNet)itb.next(); + if(DebugOption.printLevel <= 1){ + System.out.println(cntb.toString()); + } + + List/**/ globalNetsForSubcellNet = + cntb.getGlobalNets(); + for (Iterator itc = cnta.getGlobalNets().iterator(); itc.hasNext(); ) { + GlobalNet gna = (GlobalNet)itc.next(); + if(!globalNetsForSubcellNet.contains(gna)){ + globalNetsForSubcellNet.add(gna); + gna.updateWireParam(cntb); + listener.addCellNet(gna, cntb); + } + } + } + } + } // if level > 0 + + + + + + // Add new sub-types to the list + for (Iterator itb = sta.getAllSubcells().iterator(); + itb.hasNext(); ) { + CellType stb = (CellType)itb.next(); + sortedInsert(cellTypes, stb); + } + + // remove current sub-type from the list + cellTypes.remove(0); + } // while !cellTypes.isEmpty() + + + // clean up the source/sink lists for all the global nets + // i.e. remove sources/sinks of type 1 (CellType source/sink) + final int numGeneratedGlobalNets = generatedGlobalNets.size(); + for(int i=0;i*/ realSources = + new MultiSet/**/(NetSourceComparator.getInstance()); + for (Iterator ita = gnta.listSources.iterator(); ita.hasNext(); ) { + NetSource nsra = (NetSource)ita.next(); + if(nsra.type != NetType.CELL) realSources.add(nsra); + } + gnta.listSources = realSources; + + final MultiSet/**/ realSinks = + new MultiSet/**/(NetSinkComparator.getInstance()); + for (Iterator ita = gnta.listSinks.iterator(); ita.hasNext(); ) { + NetSink nska = (NetSink)ita.next(); + if(nska.type != NetType.CELL) realSinks.add(nska); + } + gnta.listSinks = realSinks; + } + } + + private static double[] transformCoordinates(int orientation, + double cx, + double cy, + double dx, + double dy) { + + double ex, ey; + switch (orientation) { + + case ConnectionInfo.R0: + ex = cx + dx; + ey = cy + dy; + break; + + case ConnectionInfo.R90: + ex = cx - dy; + ey = cy + dx; + break; + + case ConnectionInfo.R180: + ex = cx - dx; + ey = cy - dy; + break; + + case ConnectionInfo.R270: + ex = cx + dy; + ey = cy - dx; + break; + + case ConnectionInfo.MY: + ex = cx - dx; + ey = cy + dy; + break; + + case ConnectionInfo.MYR90: + ex = cx - dy; + ey = cy - dx; + break; + + case ConnectionInfo.MX: + ex = cx + dx; + ey = cy - dy; + break; + + case ConnectionInfo.MXR90: + ex = cx + dy; + ey = cy + dx; + break; + + + default: + throw new AssertionError(); + + } // switch + + return new double[]{ex, ey}; + } + + + + /** + * Inserts st1 into lst1. High-level cells + * appear at the front of the list and leaf-cells at the end. + **/ + public static void sortedInsert(List/**/ lst1, CellType st1) { + int k = st1.getLevel(); // get the level number of the sub-type + int j = lst1.size(); + for(int i=0;ign1. They are considered + * similar if they have the same source half-operators, + * the same sink half-operators (not transistors!) with transistor + * sizes within 0.1%, and capacitive load sinks with caps within 5%. + *

    Note that this function may return false even if the GlobalNets + * are actually similar. This is acceptable and will merely hurt the + * runtime. + **/ + public boolean isSameTypeAs(GlobalNet gn1) + { + // must have same extra_delay directives + if (gn1.topCellNet.getUpExtraDelay() != + topCellNet.getUpExtraDelay()) return false; + if (gn1.topCellNet.getDownExtraDelay() != + topCellNet.getDownExtraDelay()) return false; + + // Must have monotonic R vs C, because we use only getWireRC() + // to rank GlobalNet's and CatPath's. Only if one GlobalNet + // has bigger R and bigger C than another, it will have bigger + // RC, and will in fact have bigger delay. See BUG 11664 for + // details. + double R = getWireResistance(); + double R1 = gn1.getWireResistance(); + double C = getWireCapacitance(); + double C1 = gn1.getWireCapacitance(); + if (RC1 || R>R1 && C 0.05) + return false; + break; + case NetType.HALF_OPERATOR_TRANSISTOR: + // FIXME: hardcoded constant + if ((nskc.sink != nskd.sink) || + (Math.abs(nskc.transistor.size - nskd.transistor.size) + > (0.001 * nskc.transistor.size))) + return false; + break; + case NetType.CELL: + throw new AssertionError("Global net should not have cell-type sink now"); + } + } else { + return false; + } + } + return itc.hasNext() == itd.hasNext(); + } + + + /** + * Returns true if the GlobalNet is driven from + * two or more cell types. + **/ + public boolean isShared() { + CellType foundCell = null; + for (int i = 0; i < listSources.size(); ++i) { + final NetSource netSource = (NetSource) listSources.get(i); + if (netSource.getType() == NetType.HALF_OPERATOR_TRANSISTOR) { + final CellType cellSource = netSource.source.subType; + if (foundCell == null) + foundCell = cellSource; + else if (foundCell != cellSource) + return true; + } + } + + return false; + } + + + public static void debugGeometry(CastDesign design, String outRoot) + { + } + + + public double getUpOrDownDelay(int driveDirection) { + double maxDelay = -1.0; + + for (Iterator ita = getListSources().iterator(); ita.hasNext(); ) { + NetSource nsra = (NetSource)ita.next(); + if (nsra.type == NetType.HALF_OPERATOR_TRANSISTOR) { + HalfOperator hoa = nsra.source; + if (hoa.driveDirection == driveDirection) { + double f = calculateDelay(hoa); + if(f > maxDelay){ + maxDelay = f; + } + } + } + } + + return maxDelay; + } + + + public double getUpDelay() { + return getUpOrDownDelay(HalfOperator.DriveDirection.PULL_UP); + } + + + public double getDownDelay() { + return getUpOrDownDelay(HalfOperator.DriveDirection.PULL_DOWN); + } + + + double calculateDelay(HalfOperator ho1) + { + double delay = 0.0; + List lsta = new ArrayList(); + + getDelayFunction(ho1, lsta); + for (Iterator ita = lsta.iterator(); ita.hasNext(); ) { + FunctionTerm ftma = (FunctionTerm)ita.next(); + + assert ftma.type == FunctionTerm.Type.CONSTANT; + + delay += ftma.coefficient; + } + + return delay; + } + + public static void updateDelayBias(final CellType top, + final Cadencize cad, + final PrintWriter debug) { + // first find if any instance based delaybias directives exists, if + // not, then return immediately, as there would be nothing to do + final boolean[] hasDirective = new boolean[] { false }; + top.walkOnce( + new CellTypeProcessor() { + public void processCellType(final CellType c) { + final Map delaybias = + DirectiveUtils.getSubcellDirective( + c.cast_cell, + DirectiveConstants.DELAYBIAS, + DirectiveConstants.INSTANCE_TYPE); + if (!delaybias.isEmpty()) hasDirective[0] = true; + } + } + ); + + if (hasDirective[0]) { + final InstanceData instData = new InstanceData(); + instData.updateDelayBias(top.cast_cell); + updateDelayBias(top, null, instData, cad, new HashMap(), debug); + } else if (debug != null) { + debug.println("No cells in design specify instance based " + + "delaybias directives."); + } + } + + /** + * Set the delaybias associated with each source. + **/ + private static void updateDelayBias(final CellType cell, + final HierName prefix, + final InstanceData instData, + final Cadencize cad, + final Map instMap, + final PrintWriter debug) { + instMap.put(cell.typeName, prefix); + if (cell.getLevel() == 0) { + // the delaybias calculated from InstanceData includes the top + // level delaybias specified in the cell; however, this delaybias + // is already included in the delay calculated by + // CellDelay.getDelay() which is stored in HalfOperator.delayBias. + // Therefore, we divide by the top level delaybias. + final float total = instData.getDelayBias(null); + final float cellDelay = cell.getDelay().getCellDelayBias(); + + // avoid NaNs in case delaybias = 0 in a cell + final float curr = cellDelay == 0 ? 0 : total / cellDelay; + + if (debug != null) + debug.println(cell.typeName + " " + prefix + + " total=" + total + + " instance=" + curr); + + final NetSource needle = + new NetSource(NetType.HALF_OPERATOR_TRANSISTOR); + for (Iterator i = cell.getAllNets().iterator(); i.hasNext(); ) { + final CellNet net = (CellNet) i.next(); + if (net.getListSources().isEmpty()) continue; + for (Iterator j = net.getGlobalNets().iterator(); + j.hasNext(); ) { + final GlobalNet gn = (GlobalNet) j.next(); + final CellNet topNet = gn.getTopCellNet(); + // find the current instance name associated with the + // global net + final HierName inst = + (HierName) instMap.get(topNet.container.typeName); + // filter out nets that cannot contain sources in the + // current instance + if (net != topNet && !prefix.isChildOf(inst)) continue; + final Comparator comp = new NetSourceCellTypeComparator( + gn, NetType.HALF_OPERATOR_TRANSISTOR, + cell.typeName); + // narrow the search to all half operator sources that came + // from cell, and + for (Iterator k = gn.getListSources().findAll(gn, comp); + k.hasNext(); ) { + final NetSource src = (NetSource) k.next(); + // source instance names are relative to the global net + // they are on; calculate the full instance name + final HierName full = src.getInstanceName() == null ? + inst : HierName.append(inst, src.getInstanceName()); + if (full.equals(prefix)) { + src.setDelayBias(curr); + } + } + } + } + } + for (Iterator i = cell.getAllSubcellConnections().iterator(); + i.hasNext(); ) { + final ConnectionInfo ci = (ConnectionInfo) i.next(); + updateDelayBias(ci.child, + HierName.append(prefix, ci.nameInParent), + instData.translate(cell.cast_cell, + ci.child.cast_cell, + ci.nameInParent, cad), + cad, instMap, debug); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/IdleStateSolver.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/IdleStateSolver.java new file mode 100644 index 0000000000..34a96acd70 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/IdleStateSolver.java @@ -0,0 +1,196 @@ +package com.avlsi.tools.jauto; + +import java.io.BufferedWriter; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Formatter; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Set; +import java.util.Map; +import java.util.List; +import java.util.HashSet; + +import com.avlsi.util.container.Pair; +import com.avlsi.file.common.HierName; + +import JaCoP.constraints.And; +import JaCoP.constraints.Not; +import JaCoP.constraints.Or; +import JaCoP.constraints.PrimitiveConstraint; +import JaCoP.constraints.XeqC; +import JaCoP.core.BooleanVar; +import JaCoP.core.Store; +import JaCoP.search.DepthFirstSearch; +import JaCoP.search.IndomainMin; +import JaCoP.search.InputOrderSelect; +import JaCoP.search.Search; +import JaCoP.search.SelectChoicePoint; + + + +public final class IdleStateSolver +{ + private static Store store; + + private BooleanVar[] store_vars; //References to all the store variables + static int storevar_cnt; // Counter for the number of store variables + + private BufferedWriter out; //File to output all the idle states + //A Hash Map of Store variable names and their value + //0- IdLE_0 1 - IDLE_1 and -1 - UNKNOWN + public HashMap idleStates; + //A hash map to store the transistor Types + /* + * The hash map uses only 2 types (stt - slow transistor type + * and ftt - fast transistor type) + * The nodes whose transistor types are unknown are not entered + * in this hash map. The boolean value is true- for halfoperators + * whose DriveDirection is PULLUP and false for those whose + * DriveDirection is PULLDOWN + * Eg entry : : stt + */ + public Map,Integer> transistorTypes; + + + + //Default constructor for the solver + IdleStateSolver(int varSize){ + store = new Store(varSize); + store_vars = new BooleanVar[varSize]; + storevar_cnt=0; + idleStates= new HashMap(); + transistorTypes = new HashMap,Integer>(); + } + /* + * Returns a reference to the variable if it already exists in the store + * Creates a new variable and returns its index if it does not exist + */ + public BooleanVar getVariable(String Name){ + for (int i =0 ;i search = new DepthFirstSearch(); + // If there are no store variables present + if(storevar_cnt == 0){ + System.err.println("IdleStateSolver: printSolutions: No variables present."); + return; + } + SelectChoicePoint select = + new InputOrderSelect(store, store_vars, + new IndomainMin()); + //The listener is added so that the solver returns all the solutions + //that satisfy the constraints + search.getSolutionListener().searchAll(true); + search.getSolutionListener().recordSolutions(true); + boolean result = search.labeling(store, select); + if(DebugOption.printLevel <= 1){ + System.out.print("Variables"); + for(int k=0 ; k< storevar_cnt; k++){ + StringBuilder sb = new StringBuilder(); + Formatter formatter = new Formatter(sb,Locale.US); + formatter.format("%6s",store_vars[k].id.toString()); + //System.out.print(store_vars[k].id+"\t\t"); + System.out.print(sb.toString()); + } + System.out.println(""); + //Printing all the solutions + } + for (int i=1; i<=search.getSolutionListener().solutionsNo(); i++){ + if(DebugOption.printLevel <= 1){ + System.out.print("Solution " + i + ": "); + } + for (int j=0; j1){ + if(search.getSolution(i)[j] != + search.getSolution(i-1)[j]) + changed[j] = true; + } + } + System.out.println(); + } + /*Calculating the idle states of the nodes from the solutions + If the value of a variable changes across the solutions, the idle + state is UNKNOWN else it is 0 or 1*/ + if (result){ + for (int k=0; k< search.getSolution(1).length ;k++){ + if (changed[k]== true){ + //The Idle state changes across the solutions + //in this case, hence its unknown + if(DebugOption.printLevel <= 1){ + System.err.println("IdleState("+ store_vars[k].id+ ")= UNKNN"); + } + this.idleStates.put(store_vars[k].id,new Integer(-1)); + } + else{ + int temp; + temp = Integer.parseInt(search.getSolution(1)[k].toString()); + //The Idle state is known in this case + this.idleStates.put(store_vars[k].id,new Integer(temp)); + if(DebugOption.printLevel <= 1){ + System.err.println("IdleState("+ store_vars[k].id+") = "+ + this.idleStates.get(store_vars[k].id).toString()); + } + } + } + } + else { + System.err.println("ERROR: IdleStateSolver: possible conflicting idle_state " + + "directives,\nno solutions found in " + cellName); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jauto.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jauto.java new file mode 100644 index 0000000000..ae42732fd9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jauto.java @@ -0,0 +1,2298 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.FilterWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.io.PrintWriter; +import java.io.PrintStream; +import java.io.FileOutputStream; +import java.text.DateFormat; +import java.text.Format; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.Set; +import java.util.SortedSet; +import java.util.SortedMap; +import java.util.TreeSet; +import java.util.TreeMap; +import java.util.StringTokenizer; +import java.util.Date; + +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.NodeValue; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveSource; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.fast.*; +import com.avlsi.fast.ports.*; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.cdl.parser.CDLFactoryFilter; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.cast.*; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.functions.BinaryFunction; +import com.avlsi.util.debug.SimpleProfiler; +import com.avlsi.util.text.StringUtil; +import com.avlsi.netlist.*; +import com.avlsi.netlist.impl.*; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.FileUtil; +import com.avlsi.io.IndentWriter; + +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; + +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.container.Triplet; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgFormatException; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsUtil; +import com.avlsi.util.cmdlineargs.InvalidCommandLineArgException; +import com.avlsi.util.cmdlineargs.MissingCommandLineArgException; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.text.PrintfFormat; + +import com.avlsi.tools.jauto.JautoMessageCenter; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; + +import com.avlsi.util.ext.Exec; + +/** + * Main wrapper class + * + * @author Aaron Denney + * @version $Date$ + **/ + +/** + * Jauto is the main entrance class for transistor sizing tool "JAUTO", aka "P2N". + * Major steps for the sizing flow are: + *

    1. Read in Cast design, sizing options, technology data + *

    2. Build design data structures, sizing data structures + *

    3. Call the main sizing routine + *

    4. Output sizing result in Cast and CDL format + **/ +public class Jauto { + + static final String versionNumber = "1.2"; + + static final HierName Vdd = HierName.makeHierName("Vdd"); + static final HierName GND = HierName.makeHierName("GND"); + static final HierName _RESET = HierName.makeHierName("_RESET"); + + static final JautoMessageCenter messageCenter = new JautoMessageCenter(); + + private static final String SIZE_MODE = "size"; + private static final String SUBTYPE_MODE = "spec"; + private static final String UPDATE_MODE = "update"; + private static final String CHARGE_MODE = "resize"; + + /** + * Constructor. + **/ + private Jauto() { + throw new AssertionError(); + } + + private static String buildVersion() { + return com.avlsi.util.debug.VersionInfo.getVersionString(Jauto.class); + } + + private static void print(String name, double value) { + System.out.println(name + value); + } + + private static void print(String name, int value) { + System.out.println(name + value); + } + + private static void printNS(String name, Object value) { + System.out.println + (name+(value==null?"Not specified":value)); + } + + private static void printNSD(String name, String value) { + System.out.println + (name+(value==null?"Not specified, set to default":value)); + } + + private static void printYN(String name, boolean value) { + System.out.println + (name+(value?"Yes":"No")); + } + + private static int intArg(String arg) { + return intArg(arg,-1); + } + + private static int intArg(String arg, int def) { + return arg != null ? Integer.parseInt(arg) : def; + } + + private static double doubleArg(String arg) { + return doubleArg(arg,-1); + } + + private static double doubleArg(String arg, double def) { + return arg != null ? Double.parseDouble(arg) : def; + } + + private static float floatArg(String arg, float def) { + return arg != null ? Float.parseFloat(arg) : def; + } + + static long lastTime=System.currentTimeMillis(); + static long origTime=System.currentTimeMillis(); + static long lastMemory=0; + private static String stats() { + long newTime=System.currentTimeMillis(); + long deltaTime=newTime-lastTime; + lastTime=newTime; + long newMemory = Runtime.getRuntime().totalMemory() + -Runtime.getRuntime().freeMemory(); + long deltaMemory=newMemory-lastMemory; + lastMemory=newMemory; + return (deltaTime/1000.0)+" sec, "+ + ((lastTime-origTime)/1000.0)+" sec total, "+ + (deltaMemory/1024.0)+"k, "+ + (lastMemory/1024.0)+"k total"; + } + + /** + * Force a cell, and all recursively all its subcells to be fixed size, by + * actually modifying the cell itself. Use with extreme caution. + **/ + private static void forceFixedSize(final CellInterface cell, + final boolean val) { + final DirectiveSource source = new DirectiveSource(BlockInterface.CELL); + source.definition(DirectiveConstants.FIXED_SIZE, val); + final BlockIterator bi = + cell.getBlockInterface().iterator(BlockInterface.DIRECTIVE); + bi.merge(new DirectiveBlock(source.getDirectiveInterface())); + } + + private static void forceFixedSize(final CellInterface cell, + final boolean val, + final Set seen) { + if (cell.isNode() || cell.isChannel() || + !seen.add(cell.getFullyQualifiedType())) return; + + forceFixedSize(cell, val); + + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + Pair p = (Pair) i.next(); + CellInterface subcell = (CellInterface) p.getSecond(); + forceFixedSize(subcell, val, seen); + } + } + + private static String printArgValue(final String arg) { + return arg == null ? "(null)" + : arg.equals("") ? "(empty)" + : arg; + } + + public static Map + parseAutoThresholdOptions(final String opt) { + final EnumMap result = + new EnumMap( + AutoThreshold.Option.class); + for (String pipe : StringUtil.split(opt, '|')) { + final String[] keyval = StringUtil.split(pipe, ':'); + final AutoThreshold.Option key = + Enum.valueOf(AutoThreshold.Option.class, + keyval[0].toUpperCase()); + result.put(key, Boolean.valueOf(keyval[1])); + } + if (DebugOption.printLevel <= 1) { + System.out.println("Parsed auto threshold options: " + result); + } + return result; + } + + /** + * Main program. Loads up a cast file, parses it into the .fast + * data structures, tries to also find CDL, etc. + **/ + public static void main(String [] args) throws Exception { + /** + * Commandline arguments parsing + **/ + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + final boolean quiet = theArgs.argExists("quiet"); + JautoUI.quiet = quiet; + if (! quiet ) + System.err.println("\033[1;32m" + JautoUI.getCurrentTime() + " -- Starting Jauto main routine." + "\033[0m"); + + final boolean showVersion = theArgs.argExists( "version" ); + if ( showVersion ) { + System.out.println(buildVersion()); + } + + String cellName = theArgs.getArgValue("cellName", null ); + String layoutRoot = theArgs.getArgValue("layoutRoot", null ); + + DebugOption.printLevel = intArg(theArgs.getArgValue("debug-level", null), 3); + final String castRoot = theArgs.getArgValue("castInRoot", null ); + final String outRoot = theArgs.getArgValue("outRoot", null ); + final String cdlRoot = theArgs.getArgValue("cdlRoot", null ); + final String targetSpeed = theArgs.getArgValue("targetSpeed", null ); + final String tau = theArgs.getArgValue("tau", null ); + final String minTau = theArgs.getArgValue("minTau", null ); + final String dynamicEnergyPenalty = theArgs.getArgValue("dynamicEnergyPenalty",null); + final String maxWidthN = theArgs.getArgValue("maxWidthN", null ); + final String maxWidthP = theArgs.getArgValue("maxWidthP", null ); + final String minWidthP = theArgs.getArgValue("minWidthP", null ); + final String minWidthN = theArgs.getArgValue("minWidthN", null ); + final String nmosWarnWidth = theArgs.getArgValue("nmosWarnWidth", null); + final String pmosWarnWidth = theArgs.getArgValue("pmosWarnWidth", null); + final String maxGroupSize = theArgs.getArgValue("maxGroupSize", null ); + final String convergeThres = theArgs.getArgValue("convergeThres", null ); + final String slackWarningThreshold = theArgs.getArgValue("slackWarningThreshold", null ); + final String strengthRatioWarningThreshold = theArgs.getArgValue("strengthRatioWarningThreshold", null); + final String castVersion = theArgs.getArgValue("castversion", "2" ); + final String pathLimit = theArgs.getArgValue("pathLimit", null ); + String catPathReductionThreshold = theArgs.getArgValue("catPathReductionThreshold", null ); +// final String packageRoot = theArgs.getArgValue( "package-root", null ); + final String layoutAttribute = theArgs.getArgValue("defaultLayoutAttributes", null); + + /** + * Options for internal E*Tau^2 sweep. + * Internal sweep will start from "tau" + * increase "internalSweepStep" each time + * for "internalSweepNumber" times. + **/ + final boolean internalSweep = theArgs.argExists("internalSweep"); + final String internalSweepNumber = theArgs.getArgValue("internalSweepNumber", null); + final String internalSweepStep = theArgs.getArgValue("internalSweepStep", null); + + final boolean stepTau = theArgs.argExists("stepTau"); + + double cutoff = Double.MAX_VALUE; + double cutoffmin = 0; + + boolean nofloorplan = theArgs.argExists("noFloorplan"); + boolean sizeunit = theArgs.argExists("unitSize"); + + final boolean noSizeStaticizers = theArgs.argExists("noSizeStaticizers"); + final boolean reSizeStaticizers = theArgs.argExists("reSizeStaticizers"); + final boolean skipSizing = theArgs.argExists("skipSizing") || reSizeStaticizers; + + final boolean dumpcell = theArgs.argExists("dumpcell"); + final boolean portDirectionOnly = theArgs.argExists("portDirectionOnly"); + final boolean checkOverStaticizingOnly = theArgs.argExists("checkOverStaticizingOnly"); + final boolean printSizingVersion = theArgs.argExists("printSizingVersion"); + final boolean pathBasedSizing = theArgs.argExists("pathBasedSizing"); + final String minSolveHours = theArgs.getArgValue("min-solve-hours",null); + final String maxSolveHours = theArgs.getArgValue("max-solve-hours",null); + long min_end_time = -1, max_end_time = -1; + if (minSolveHours!=null) + min_end_time = (long) (3600000 * doubleArg(minSolveHours)); + if (maxSolveHours!=null) + max_end_time = (long) (3600000 * doubleArg(maxSolveHours)); + final boolean outputRC = theArgs.argExists("outputRC"); + final boolean noDebug = theArgs.argExists("noDebug"); + final boolean reportFlatPaths = theArgs.argExists("reportFlatPaths"); + final boolean reportStrength = theArgs.argExists("reportStrength"); + final boolean debugGeometry = theArgs.argExists("debugGeometry"); + final boolean ignoreReset = theArgs.argExists("ignoreReset"); + final boolean completeCatPath = theArgs.argExists("completeCatPath"); + final boolean completeSizingPath = theArgs.argExists("completeSizingPath"); + boolean disableImmediateCatPathReduction = + theArgs.argExists("disableImmediateCatPathReduction"); + final boolean noHaltOnWarn = theArgs.argExists("noHaltOnWarn"); + final boolean enableCatPath = + (theArgs.argExists("enableCatPath") && + !theArgs.getArgValue("enableCatPath", "1").equals("0")); + final boolean enableAutoConstraint = theArgs.argExists("enableAutoConstraint"); + final boolean boundMinDelay = theArgs.argExists("boundMinDelay"); + final boolean earlyOut = theArgs.argExists("earlyOut"); + final String lengthUnit = theArgs.getArgValue("lengthUnit", ""); + final boolean useEqualityConstraints = theArgs.argExists("useEqualityConstraints"); + final String staticizer = theArgs.getArgValue("staticizer", null); + final String weakInverter = theArgs.getArgValue("weak-inverter", null); + final String smallInverter = theArgs.getArgValue("small-inverter", null); + + final boolean updateDirective = theArgs.argExists("updateDirective"); + final boolean proteusBudget = theArgs.argExists("proteusBudget"); + boolean disableSizingEnv = + theArgs.argExists("disableAutomaticSizingEnvironment"); + if (proteusBudget) { + disableImmediateCatPathReduction = true; + catPathReductionThreshold = "-10"; + disableSizingEnv = true; + } + + final String[] gateNames; + { + final String gates = theArgs.getArgValue("gates", null); + if (gates == null) gateNames = new String[0]; + else gateNames = StringUtil.split(gates, ':'); + } + + final String cutoffstr = theArgs.getArgValue("cutoff", + Double.toString( Double.MAX_VALUE ) ); + try { + cutoff = + Double.parseDouble( cutoffstr ); + } + catch (NumberFormatException e) { + System.err.println("Invalid cutoff size \"" + cutoffstr + "\"!"); + } + + final String cutoffminstr = theArgs.getArgValue("cutoffmin", + "0" ); + try { + cutoffmin = + Double.parseDouble( cutoffminstr ); + } + catch (NumberFormatException e) { + System.err.println("Invalid minimum cutoff size \"" + cutoffminstr + "\"!"); + } + + double scaleC=doubleArg(theArgs.getArgValue("scaleC",null),1); + double scaleR=doubleArg(theArgs.getArgValue("scaleR",null),1); + double scaleM=doubleArg(theArgs.getArgValue("scaleM",null),1); + + Double mfggrid = null; + final String mfggridstr = theArgs.getArgValue("mfggrid", null); + try { + if (mfggridstr != null) + mfggrid = Double.valueOf(mfggridstr); + } catch (NumberFormatException e) { + System.err.println("Invalid manufacturing grid \"" + mfggridstr + "\"!"); + } + + float minWidth = Float.NaN; + final String minWidthStr = theArgs.getArgValue("minGateWidth", null); + try { + if (minWidthStr != null) minWidth = Float.parseFloat(minWidthStr); + } catch (NumberFormatException e) { + System.err.println("Invalid minimum stack/gate width \"" + minWidthStr + "\"!"); + } + + final String subtypePath = theArgs.getArgValue("subtypePath", null); + final String mode = theArgs.getArgValue("mode", SUBTYPE_MODE); + final String subtype = theArgs.getArgValue("subtype", null); + boolean sizeTrial = theArgs.argExists("trial"); + + { + StringContainerIterator argIter = theArgs.nonParsedArgumentsIterator(); + while ( argIter.hasNext() ) { + final String arg = argIter.next(); + System.err.println("ignoring non-argument option '" + arg + "'."); + } + + } + final String pStacks = theArgs.getArgValue("pStacks", null); + final String nStacks = theArgs.getArgValue("nStacks", null); + final String hsizes = theArgs.getArgValue("hsizes", null); + final String allName = theArgs.getArgValue("spice-output", "transistors.cdl"); + final boolean newSpice = theArgs.argExists("new-spice"); + final boolean generateDelaySignoff = + theArgs.argExists("generateDelaySignoff"); + final String delaySignOff = + theArgs.getArgValue("delaySignoffFile", null); + final String netlistFromPrs = + theArgs.getArgValue("netlist-from-prs", null); + final String optimizeThreshold = + theArgs.getArgValue("optimizeThreshold", null); + final boolean generateSdcConstraint = + theArgs.argExists("generateSdcConstraint"); + double sdcDelayScale = 1.0; + Set sdcLibs = Collections.emptySet(); + if (generateSdcConstraint) { + try { + sdcDelayScale = + CommandLineArgsUtil.getDoubleArgValue(theArgs, + "sdcDelayScale", 1.0); + } catch (CommandLineArgFormatException e) { + System.err.println( + "Argument to " + e.getArgName() + " is malformed: " + + printArgValue(e.getMessage())); + usage(); + } + + final String sdclibs = theArgs.getArgValue("sdcLibs", null); + if (sdclibs != null) { + sdcLibs = new HashSet(); + for (String lib : StringUtil.split(sdclibs, ':')) { + sdcLibs.add(lib); + } + } + } + + if(printSizingVersion){ + System.out.println("Transistor sizing algorithm - Version: " + versionNumber); + return; + } + + if (mode.equals(SUBTYPE_MODE)) { + sizeunit = true; + nofloorplan = true; + layoutRoot = null; + } else if (mode.equals(SIZE_MODE)) { + cellName = cellName + "." + subtype; + } else if (mode.equals(CHARGE_MODE)) { + sizeunit = true; + nofloorplan = true; + layoutRoot = null; + sizeTrial = true; + if (mode.equals(CHARGE_MODE)) cellName = cellName + "." + subtype; + } else if (mode.equals(UPDATE_MODE)) { + sizeunit = true; + nofloorplan = true; + layoutRoot = null; + } + + final String partialExtract = + theArgs.getArgValue("partialExtract", cellName); + + /** + * Output commandline parsing results. + **/ + + if (cellName == null) { + System.err.println("no main cell specified."); + usage(); + } + if (subtype == null && !mode.equals(SUBTYPE_MODE)) { + System.err.println("You must specify a subtype to operate on."); + usage(); + } + if (castRoot == null) { + System.err.println("no castroot / castpath specified."); + usage(); + } + if (outRoot == null) { + System.err.println("no cast output directory specified."); + usage(); + } + if (cdlRoot == null) { + System.err.println("no cdl output directory specified."); + usage(); + } + if (layoutRoot == null && !nofloorplan) { + System.err.println("must set --layoutRoot unless --noFloorplan."); + usage(); + } + if (!mode.equals(SUBTYPE_MODE) && + !mode.equals(SIZE_MODE) && + !mode.equals(UPDATE_MODE) && + !mode.equals(CHARGE_MODE)) { + System.err.println("Invalid mode specified: " + mode); + usage(); + } + + final String violationReportLimitString = + theArgs.getArgValue("violationReportLimit", "-1"); + final float violationReportLimit = + Float.parseFloat(violationReportLimitString); + + // tdata should be final, but jikes doesn't know (and isn't + // required to know) that usage() never returns. + TechnologyData tdata = null; + try { + tdata = new TechnologyData(theArgs); + } catch (CommandLineArgFormatException e) { + System.err.println( + "Argument to " + e.getArgName() + " is malformed: " + + printArgValue(e.getMessage())); + usage(); + } catch (InvalidCommandLineArgException e) { + System.err.println(e.toString()); + usage(); + } catch (MissingCommandLineArgException e) { + System.err.println(e.toString()); + usage(); + } + + final float fixedDelaybias = + floatArg(theArgs.getArgValue("fixedSizeDelayBias",null),1); + final float sizableDelaybias = + floatArg(theArgs.getArgValue("sizableDelayBias",null),1); + final boolean allFixedSize = theArgs.argExists("allFixedSize"); + final boolean routed = theArgs.argExists("routed"); + final boolean routedWireDebug = theArgs.argExists("routed-wire-debug"); + + final FileSearchPath castPath = new FileSearchPath( castRoot ) ; + + if (! quiet ) { + System.out.println("Jauto user name: " + System.getProperty("user.name", "")); + System.out.println("\n\nJauto command line arguments summary:\n"); + + System.out.println("\tJAUTO version number: " + versionNumber); + + printNS("\tCell name: ", cellName); + printNS("\tSubtype: ", subtype); + printNS("\tMode: ", mode); + if (mode.equals(SIZE_MODE)) System.out.println("\tTrial sizing: " + sizeTrial); + printNS("\tCast directory name: ", castRoot); + printNS("\tOutput directory name: ", outRoot); + printNS("\tSPICE file output: ", allName); + printNS("\tCDL directory name: ", cdlRoot); + printNS("\tLayout directory name: ", layoutRoot); + printNS("\tTarget speed: ", targetSpeed); + printNSD("\tCircuit unit delay : ", tau); + printNSD("\tCircuit minimun unit delay : ", minTau); + printNSD("\tMaximum transistor width for p-type gates: ", maxWidthP); + printNSD("\tMaximum transistor width for n-type gates: ", maxWidthN); + printNSD("\tMinimum transistor width for p-type gates: ", minWidthP); + printNSD("\tMinimum transistor width for n-type gates: ", minWidthN); + print("\tMinimum transistor width for staticizers : ", + tdata.getMinimumTransistorWidth()); + print("\tMinimum transistor length for staticizers : ", + tdata.getMinimumTransistorLength()); + print("\tDefault gate length : ", tdata.getDefaultGateLength()); + print("\tDefault diffusion length : ", + tdata.getDefaultDiffusionLength()); + printNSD("\tWarn for n-transistors larger than: ", nmosWarnWidth); + printNSD("\tWarn for p-transistors larger than: ", pmosWarnWidth); + printNSD("\tTechnology name : ", tdata.getTechnologyName()); + print("\tDelay model cut-off length for stack of N transistors: ", tdata.getStackLimitN()); + print("\tDelay model cut-off length for stack of P transistors: ", tdata.getStackLimitP()); + printNSD("\tMaximum sub-type group size : ", maxGroupSize); + printNSD("\tUpper bound for number of paths in a leaf cell : ", pathLimit); + printNSD("\tRelative difference threshold for concatenated path reduction : ", catPathReductionThreshold); + print("\tDefault wire width : ", tdata.getDefaultWireWidth()); + print("\tDefault wire length : ", tdata.getDefaultWireLength()); + print("\tDefault wire spacing : ", tdata.getDefaultWireSpace()); + print("\tMinimum wire length : ", tdata.getMinimumWireLength()); + print("\tLayout scale factor X: ", tdata.getLayoutScaleX()); + print("\tLayout scale factor Y: ", tdata.getLayoutScaleY()); + print("\tUnit wire capacitance Ca : ", + tdata.getUnitWireCapacitanceCa()); + print("\tUnit wire capacitance Cfc_0 : ", + tdata.getUnitWireCapacitanceCfc_0()); + print("\tUnit wire capacitance Cfc_1 : ", + tdata.getUnitWireCapacitanceCfc_1()); + print("\tUnit wire capacitance Cfc_2 : ", + tdata.getUnitWireCapacitanceCfc_2()); + print("\tEffective unit wire resistance : ", tdata.getUnitWireResistance()); + print("\tElmore delay factor for gate delay : ", tdata.getElmoreDelayFactor()); + print("\tElmore delay factor for wire RC delay : ", tdata.getWireRCDelayFactor()); + print("\tWire resistance shielding factor : ", tdata.getResistanceShieldingFactor()); + print("\tWire resistance shielding threshold : ", tdata.getResistanceShieldingThreshold()); + print("\tScaling factor for wire capacitance : ", tdata.getCapacitanceScalingFactor()); + print("\tDefault load capacitance for spice file (not sizing) : ", + tdata.getDefaultLoadCapacitance()); + printYN("\tUse intrinsic cap delay model : ", + tdata.getUseIntrinsicCap()); + printNSD("\tDynamic energy penalty : ", dynamicEnergyPenalty); + printNSD("\tSizing algorithm convergence threshold : ", convergeThres); + printNSD("\tThreshold value for warning of small pre-sizing timing slack : ", slackWarningThreshold); + printNSD("\tThreshold value for warning about large ratio between pull-up/pull-down strength : ", strengthRatioWarningThreshold); + + + printYN("\tInternally sweep E*Tau^2 : ", internalSweep); + if(internalSweep){ + printNSD("\tInternal sweep number : ", internalSweepNumber); + printNSD("\tInternal sweep step size : ", internalSweepStep); + } + + printYN("\tUse Tau stepping method for sizing : ", stepTau); + + printYN("\tSize staticizers : ", !noSizeStaticizers); + printYN("\tReSize staticizers : ", reSizeStaticizers); + printYN("\tSkip sizing stage : ", skipSizing); + printNSD("\tSolver minimum time budget in hours: ", minSolveHours); + printNSD("\tSolver maximum time budget in hours: ", maxSolveHours); + printYN("\tEarly out on difficult sizing problems: ", earlyOut); + printYN("\tRC output in CDL files : ", outputRC); + printYN("\tReport timing analysis results after sizing : ", reportFlatPaths); + printYN("\tReport flatterned strength after sizing : ", reportStrength); + printYN("\tOutput Magic files for debuging geometry information : ", debugGeometry); + printYN("\tIgnore _Reset! as port net during path generation : ", ignoreReset); + printYN("\tEnable complete generation of concatenated paths : ", completeCatPath); + printYN("\tEnable complete generation of sizing paths for fragment cells : ", completeSizingPath); + printYN("\tAlways output CDL netlist, independent of sizing errors and/or warnings : ", noHaltOnWarn); + printYN("\tEnable sizing using concatenated paths: ", enableCatPath); + printYN("\tAutomatic re-set unsatisfiable delay constraint : ", enableAutoConstraint); + printYN("\tPrint out port directions only : ", portDirectionOnly); + printYN("\tCheck over-staticizing problem only : ", checkOverStaticizingOnly); + printYN("\tBound delay constraints by minimum values : ", boundMinDelay); + printYN("\tUse equality constraints : ", useEqualityConstraints); + + System.out.println("\tTransistor sizing method : "+ + (pathBasedSizing? + "path-based sizing":"node-based sizing")); + System.out.println("\tCapacitance scale : " + scaleC); + System.out.println("\tResistance scale : " + scaleR); + System.out.println("\tTransistor scale : " + scaleM); + printNS("\tManufacturing grid : ", mfggrid); + System.out.println("\tStaticizer gate name : " + staticizer); + System.out.println("\tWeak inverter gate name : " + weakInverter); + System.out.println("\tSmall inverter gate name : " + smallInverter); + + System.out.print("\tGates :"); + for (int i = 0; i < gateNames.length; i++) + System.out.print(" " + gateNames[i]); + System.out.println(); + + printNS("\tSubtype path: ", subtypePath); + + System.out.print("\tGenerate stacks: "); + if (pStacks != null && nStacks != null) { + System.out.println("pStacks = " + pStacks + " nStacks = " + nStacks); + } else { + System.out.println("No."); + } + + printNS("\tDefault layout attributes: ", layoutAttribute); + printNS("\tPartial extract: ", partialExtract); + printYN("\tForce fixed size for all cells: ", allFixedSize); + printYN("\tApply routed directives: ", routed); + + System.out.println("\n\n"); + } + + + /** + * Load the cast design + **/ + + CastDesign d = null; + + SimpleProfiler.Probe parsingProbe = SimpleProfiler.getProbe("jauto.parsing"); + SimpleProfiler.Probe parsingDeallocProbe = SimpleProfiler.getProbe("jauto.parsing.dealloc"); + + parsingProbe.enter(); + if(DebugOption.printLevel <= 3){ + System.out.println("Instantiating cast file parser"); + } + final CastFileParser cfp = + (CastCacheManager.getDefault()). + getCastFileParser(castPath, castVersion, false, + new StandardParsingOption(theArgs)); + + if (! quiet) + System.out.println("Reading cast files\n"); + if ( ! quiet ) + System.out.println("Loading fully qualified cell"); + final CspSizingEnv creator = disableSizingEnv ? null : + new CspSizingEnv( + cfp, + new Cadencize(false), + new HashSet(Arrays.asList(GND, Vdd))); + final boolean useSteinerTree = + intArg(theArgs.getArgValue("useSteinerTree", null), 1) != 0; + d = loadFullyQualifiedCell(cfp, cellName, Float.parseFloat(tau), + fixedDelaybias, sizableDelaybias, + tdata, routed, + allFixedSize, Collections.EMPTY_SET, + creator, useSteinerTree); + + final Collection anonInsts = d.getAnonymousInstances(); + if (!anonInsts.isEmpty()) { + System.err.println("Anonymous instances (possibly inlined or" + + " flattened) of non-wiring cells found" + + " in the following cells:"); + for (String type : anonInsts) { + System.err.println(" " + type); + } + System.exit(1); + } + + // refuse to create non-canonical subtypes + if (mode.equals(SUBTYPE_MODE)) { + final CellInterface realTop = d.getRealTopCell().cast_cell; + final String map = (String) DirectiveUtils.getTopLevelDirective( + realTop, + DirectiveConstants.NAME_MAPPING); + if (map != null) { + final String full = + map.indexOf('.') == -1 ? realTop.getModuleName() + "." + map + : map; + if (!full.equals(realTop.getFullyQualifiedType())) { + System.err.println( + "ERROR: can't create non-canonical subtype (" + + realTop.getFullyQualifiedType() + " specifies " + + DirectiveConstants.NAME_MAPPING + " = " + full + + ")"); + System.exit(1); + } + } + } + + parsingProbe.exit(); + parsingDeallocProbe.enter(); + //CastCacheManager.getDefault().clearCache(); + Runtime.getRuntime().gc(); + parsingDeallocProbe.exit(); + + + /** + * Set sizing parameters + **/ + + if ( ! quiet ) + System.out.println("Setting parameters"); + + d.setMessageCenter(messageCenter); + + int pl = intArg(pathLimit, 500); + double threshold = doubleArg(catPathReductionThreshold, 0.2); + + if ( ! quiet ) + System.out.println("Reading top level cell"); + + SimpleProfiler.Probe sizingProbe = SimpleProfiler.getProbe("jauto.sizing"); + sizingProbe.enter(); + + final CellType top = d.getTopLevelCell(); + /* Read in the floorplan information at this point. Subtypes should + * inheret this floorplan information. */ + if (layoutRoot!=null && !nofloorplan) { + if(DebugOption.printLevel <= 3){ + System.out.println("Instantiating floorplan"); + } + final Floorplan p = new Floorplan(layoutRoot); + p.process(top); + } + sizingProbe.exit(); + + if ( ! quiet ) + System.out.println("Getting minimal subtypes??"); + parsingProbe.enter(); + + final UnaryPredicate nfsPredicate; + if (netlistFromPrs == null) { + nfsPredicate = null; + } else { + final UnaryPredicate matcher = + CellUtils.getTypeMatcher( + Arrays.asList(StringUtil.split(netlistFromPrs, ':'))); + nfsPredicate = new UnaryPredicate() { + public boolean evaluate(final CellType cell) { + return matcher.evaluate(cell.cast_cell); + } + }; + } + + final CellType newtop = + top.instanceMinimalSubTypes + (CastDesign.TRANSISTORS, staticizer, weakInverter, smallInverter, gateNames, + cfp, + nfsPredicate == null + ? new UnaryPredicate.Constant(false) + : nfsPredicate, + optimizeThreshold == null + ? null + : parseAutoThresholdOptions(optimizeThreshold)); + + parsingProbe.exit(); + parsingDeallocProbe.enter(); + // XXX: test line, to get rid of cached AST + //CastCacheManager.getDefault().clearCache(); + Runtime.getRuntime().gc(); + parsingDeallocProbe.exit(); + if (dumpcell) { + System.out.println("Dumping cells"); + newtop.walkOnce(new CellTypeProcessor() { public void processCellType(CellType p) { p.print(); } }); + return; + } + + // d.addFixed(CDL files); + // d.addGlobalNets(d.getTopLevelCell()); + // FIXME: sizing, etc. + + /** + * Just dump out the I/O directions for ports of all subtypes + **/ + + if(portDirectionOnly){ + System.out.println("\n\n------------------- Port direction information dump out -------------------\n"); + dumpPortDirections( d, new PrintWriter( System.out ) ); + System.out.println("\n\n-------------------- End of port direction dump -------------------------\n"); + + return; + } + + + /** + * Start of sizing process. + **/ + TransistorSizingTool tool = + new CGTransistorSizingTool(min_end_time,max_end_time,useEqualityConstraints); + tool.setMessageCenter(messageCenter); + + List/**/ listAllGlobalNets = new ArrayList/**/(); + + sizingProbe.enter(); + if ( ! quiet ) + System.out.println("Sizing"); + + // set TransistorSizingTool options + tool.setOptionUnitDelay(doubleArg(tau,-1)); + tool.setOptionSizeStaticizer(!noSizeStaticizers); + tool.setOptionMinWidthP(doubleArg(minWidthP,-1)); + tool.setOptionMinWidthN(doubleArg(minWidthN,-1)); + tool.setOptionMaxWidthN(doubleArg(maxWidthN,-1)); + tool.setOptionMaxWidthP(doubleArg(maxWidthP,-1)); + tool.setOptionMinUnitDelay(doubleArg(minTau,-1)); + tool.setOptionNmosWarnWidth(doubleArg(nmosWarnWidth, -1)); + tool.setOptionPmosWarnWidth(doubleArg(pmosWarnWidth, -1)); + tool.setOptionSizeConvergeThreshold(doubleArg(convergeThres,-1)); + tool.setOptionSlackWarningThreshold(doubleArg(slackWarningThreshold,-1)); + tool.setOptionMaxSubtypesPerGroup(intArg(maxGroupSize,-1)); + tool.setOptionDynamicEnergyPenalty(doubleArg(dynamicEnergyPenalty,-1)); + tool.setOptionSizingMethod(pathBasedSizing ? + TransistorSizingTool.PATH_BASED_SIZING_METHOD : + TransistorSizingTool.NODE_BASED_SIZING_METHOD); + tool.setOptionEnableAutoConstraint(enableAutoConstraint); + tool.setOptionInternalSweep(internalSweep); + tool.setOptionStepTau(stepTau); + tool.setOptionEarlyOut(earlyOut); + if (internalSweep) { + tool.setOptionInternalSweepNumber(intArg(internalSweepNumber,-1)); + tool.setOptionInternalSweepStep(doubleArg(internalSweepStep,-1)); + } + + final Cadencize cad = new Cadencize(false); + + if (sizeunit){ // give unit sizes to all the transistors + if(mode.equals(CHARGE_MODE)){ + GlobalNet.generateGlobalNets(newtop, listAllGlobalNets); + } + + if (hsizes != null) { + try { + readHalfOperatorSize(new FileReader(hsizes), d, scaleM); + } catch (RuntimeException e) { + throw new RuntimeException("While parsing " + hsizes + ":" + e.getMessage()); + } + setHalfOperatorSize(d); + + SizeStaticizers.sizeStaticizers(d); + } + else{ + unitSize(newtop,tool.getOptionMinWidthN(),tool.getOptionMinWidthP()); + } + } + else{ // Do some real sizing + if ( ! quiet ) { + System.err.println("\033[1;32m" + JautoUI.getCurrentTime() + " -- Starting Jauto sizing process." + "\033[0m"); + System.out.println(JautoUI.getCurrentTime() + " -- Starting Jauto sizing process."); + } + final MultiMap portNets = + new MultiMap( + new IdentityHashMap>(), + MultiMap. hashSetFactory()); + if (generateSdcConstraint) { + GlobalNet.generateGlobalNets(newtop, listAllGlobalNets, + new GlobalNet.ConstructionListener() { + public void addCellNet(GlobalNet gn, CellNet cn) { + if (cn.isPortNet()) { + portNets.put(gn, cn.container.typeName); + } + } + }); + } else { + GlobalNet.generateGlobalNets(newtop, listAllGlobalNets); + } + if (!noDebug) { + JautoUI.dumpWireInformation(d, outRoot); + if (routedWireDebug) { + JautoUI.dumpRoutedWireInformation(d, outRoot); + } + } + if (!noDebug) JautoUI.dumpSinkSource(d, outRoot); + + // distribute instance delay bias to net sources; output possibly + // very large debug file if requested + final PrintWriter delayWriter = + theArgs.argExists("debugDelayBias") ? + new PrintWriter( + new FileWriter(new File(outRoot, "delaybias.debug"))) + : null; + if (!theArgs.argExists("ignoreInstanceDelayBias")) { + GlobalNet.updateDelayBias(newtop, cad, delayWriter); + } else if (delayWriter != null) { + delayWriter.println("Instance delaybias ignored due to " + + "--ignoreInstanceDelayBias."); + } + if (delayWriter != null) delayWriter.close(); + + if (theArgs.argExists("exitAfterSetup")) return; + + if(debugGeometry){ + GlobalNet.debugGeometry(d, outRoot); + } + + if(checkOverStaticizingOnly){ + if ( ! quiet ) + System.out.println("Checking design for over-staticizing problem (more than 1 staticizer on a global net)"); + checkStaticizerNumber(listAllGlobalNets); + if ( ! quiet ) + System.out.println("End of over-staticizing checking"); + return; + } + else{ + checkStaticizerNumber(listAllGlobalNets); + } + + if (theArgs.argExists("solveForNegativeDelay")) { + new NegativeDelayBudget(newtop, listAllGlobalNets, + tool.getOptionUnitDelay()); + } + + if(!skipSizing){ // Do path generation only when necessary + if(pathBasedSizing){ + SizingPath.generatePaths(d.allCellTypes, ignoreReset, + completeSizingPath, pl); + + if(enableCatPath){ + CatPath.generateCatPaths( + d.allCellTypes, ignoreReset, completeCatPath, + disableImmediateCatPathReduction); + CatPath.reduceCatPaths(d.allCellTypes, threshold); + if (delaySignOff != null) { + JautoUI.readDelaySignOff(d, delaySignOff); + } + } + } + } + + if(DebugOption.printLevel <= 1){ + recursivePrint(newtop); + } + + tool.setOutputDirectoryName(outRoot); + tool.setSynthesizedDesign(d); + + tool.getListAllSubtypes().addAll(d.allCellTypes); + + // Now really do some sizing + if (!skipSizing) { + JautoUI.dumpAllInformation(d, outRoot + File.separatorChar + + "jauto.bs.info"); + String summary = tool.sizeTransistors(); + JautoUI.generateSizingSummary(summary, outRoot, -1); + } + else{ + tool.initializeSize(true); + } + + // resize staticizers + if (reSizeStaticizers) + SizeStaticizers.sizeStaticizers(d); + + if(DebugOption.printLevel <= 3){ + System.out.println("End of transistor sizing process"); + } + + /** + * Output results and debug information + **/ + + if(tool.hasUnsatisfiableConstraints){ + System.err.println("\n" + "\033[1;31m"); + System.err.println("***************************************************************"); + System.err.println("Problem contains unsatisfiable delay constraints."); + System.err.println("Please refer to the output file for details"); + System.err.println("***************************************************************"); + System.err.println("\033[0m" + "\n"); + } + + final DelayCalculator delayCalc = new DelayCalculator(d, tool); + delayCalc.calculateDelay(); + + if (violationReportLimit > 0) { + JautoUI.dumpViolations(d, outRoot, violationReportLimit); + } + + if ( ! quiet ) + System.out.println("Start of debug information output process"); + + if (!noDebug) { + JautoUI.dumpSizeInformation(d, outRoot); + JautoUI.dumpPathInformation(d, outRoot, tool.getOptionUnitDelay(), -1, proteusBudget); + JautoUI.dumpDelayInformation(d, outRoot, tool.getOptionUnitDelay(), -1); + JautoUI.dumpAllInformation(d, outRoot + File.separatorChar + + "jauto.as.info"); + JautoUI.dumpElectromigrationInformation(d, outRoot); + JautoUI.dumpStrengthRatioInformation + (d, outRoot, doubleArg(strengthRatioWarningThreshold, 4.0)); + JautoUI.dumpHierStrengthInformation(d, outRoot); + JautoUI.checkSizes(d, tool); + JautoUI.checkPaths(d, tool); + } + else if (proteusBudget) + JautoUI.dumpPathInformation(d, outRoot, tool.getOptionUnitDelay(), -1, proteusBudget); + if (generateDelaySignoff) JautoUI.dumpDelaySignOff(d, outRoot); + + if(reportStrength){ + JautoUI.dumpFlatStrengthInformation(d, outRoot); + } + + if(reportFlatPaths){ + JautoUI.dumpFlatPathInformation(d, outRoot); + } + if (generateSdcConstraint) { + JautoUI.dumpSdcConstraints(d, delayCalc, sdcDelayScale, + portNets, sdcLibs, outRoot); + } + + if ( ! quiet ) + System.out.println("End of debug information output process"); + } + sizingProbe.exit(); + + /** + * End of Sizing process. + **/ + + // final CellType cell = findCell(newtop, cellName); + // cell.print(); + if ( ! quiet ) { + System.err.println("\033[1;32m" + JautoUI.getCurrentTime() + " -- Starting Jauto output process." + "\033[0m"); + System.out.println(JautoUI.getCurrentTime() + " -- Starting Jauto output process."); + } + + final Double diffusionLength = new Double(d.getTechnologyData().defaultDiffusionLength); + + // if(noHaltOnWarn || !tool.hasUnsatisfiableConstraints) { + if(true){ + final Map/*,NetGraph>*/ stackMap; + if (pStacks != null && nStacks != null) { + // No need for LinkedHashMap as we never iterate over the map + stackMap = new LinkedHashMap/*,NetGraph>*/(); + makeStackMap(stackMap, new Integer(DeviceTypes.P_TYPE), + cfp, pStacks, Vdd, GND, cad); + makeStackMap(stackMap, new Integer(DeviceTypes.N_TYPE), + cfp, nStacks, Vdd, GND, cad); + } else { + stackMap = null; + } + writeOut(newtop, outRoot, cellName, allName, cutoff, cutoffmin, + diffusionLength, outputRC, lengthUnit, scaleC, scaleR, mfggrid, + subtypePath, cfp, mode, subtype, sizeTrial, stackMap, cad, + tau, tool, layoutAttribute, d, listAllGlobalNets, + newSpice ? (float) tdata.getDefaultLoadCapacitance() : + Float.NaN, + minWidth, updateDirective, + new PartialExtract.CellPlusMinusKeyword(partialExtract, PartialExtract.Info.INCLUDE, cfp, cad), + tdata.getTechnologyName(), nfsPredicate); + } + + if ( ! quiet ) + System.out.println("End of CDL output process"); + } + + static void makeStackMap(final Map/*,NetGraph>*/ stackMap, + final Integer type, + final CastFileParser cfp, final String stacks, + final HierName Vdd, final HierName GND, + final Cadencize cad) { + final String[] p = StringUtil.split(stacks, ':'); + for (int i = 1; i <= p.length; ++i) { + try { + final NetGraph stack = + CastDesign.getGateNetGraph(cfp, p[i - 1], Vdd, GND, cad); + stackMap.put(new Pair(new Integer(i), type), stack); + } catch (CastSemanticException e) { + com.avlsi.tools.dsim.ExceptionPrettyPrinter.printException( + e, System.err); + System.err.println("ERROR: Cannot parse stack/gate: " + + p[i - 1]); + System.exit(1); + } catch (com.avlsi.prs.UnimplementableProductionRuleException e) { + System.err.println("ERROR: Unimplementable production rule " + + "in stack/gate: " + p[i - 1]); + System.exit(2); + } + } + } + + /** + * Read half operator sizes from hsizes.debug generated by a + * previous run of Jauto, and use those as the sizes for the half + * operators. This is used to speed up charge sharing (where the + * transistor topology changes, but half operators stay the same) + * by quickly outputting a updated netlist which can then be + * simulated in SPICE. + * + * hsizes.out can contain more cells than what's being sized. + * RuntimeException will also be thrown if a syntax error is + * detected. + * + * @param r A Reader to read sizes from. + * @param design The current design. + **/ + static void readHalfOperatorSize(final Reader r, final CastDesign design, final double scaleM) + throws IOException { + final BufferedReader br = new BufferedReader(r); + String line; + CellType current = null; + boolean inCell = false; + int lineNum = 0; + while ((line = br.readLine()) != null) { + ++lineNum; + if (line.startsWith("#")) { + continue; + } else if (line.startsWith("CELL") && !inCell) { + final String[] tokens = StringUtil.tokenize(line); + if (tokens.length != 3) { + throw new RuntimeException(lineNum + ":Syntax error: " + line); + } + inCell = true; + current = (CellType) design.getCell(tokens[1]); + } else if (line.equals("}") && inCell) { + inCell = false; + } else if (inCell && current != null) { + final String[] tokens = StringUtil.tokenize(line); + if (tokens.length != 3) { + throw new RuntimeException(lineNum + ":Invalid half operator size line: " + line); + } + final CellNet net = current.getNet(tokens[0]); + if (net == null) continue; + final double size; + try { + size = Double.parseDouble(tokens[2]) * scaleM; + } catch (NumberFormatException e) { + throw new RuntimeException(lineNum + ":Invalid size: " + line); + } + if (tokens[1].equals("+")) { + net.setUpSize(size); + } else if (tokens[1].equals("-")) { + net.setDownSize(size); + } else { + throw new RuntimeException(lineNum + ":Invalid direction: " + line); + } + } + } + } + + + /** + * This function is only used in the "charge sharing fix" mode. + * For sizeable cells, it will read in effective sizes from input + * file. For fixed cells, it will call "initializeSize" to + * calculate effective size for each half-operator from CDL + * netlist. + **/ + static void setHalfOperatorSize(final CastDesign design) + { + for (Iterator ita = design.allCellTypes.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + List/**/ lsta = cella.getListHalfOperators(); + + if(!cella.isFixedSize()){ + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + hoa.resetWidth(); + } + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + double size; + if (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + size = hoa.outputNet.getDownSize(); + } + else{ // PULL_UP + size = hoa.outputNet.getUpSize(); + } + hoa.updateSize(size); + } + } + else{ + if(DebugOption.printLevel <= 3){ + System.out.println("Fixed-size cell found:"); + System.out.println(cella.toString()); + } + + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + hoa.initializeSize(); + } + } + cella.fixVariables(); + } + } + + private static void dumpPortDirections( CastDesign theDesign, PrintWriter outputWriter ) { + for (final Iterator ita = theDesign.allCellTypes.iterator(); ita.hasNext(); ) { + final CellType sta = (CellType)ita.next(); + + for (final Iterator itb = sta.getAllNets().iterator(); itb.hasNext(); ) { + final CellNet cna = (CellNet)itb.next(); + + if ( cna.isPortNet() ) { + outputWriter.print(sta.typeName + "\t\t" + + cna.canonicalName.getCadenceString() + "\t\t"); + outputWriter.println + (CellNet.portDirectionString(cna.portDirection)); + } + } + } + } + + private static class CspSizingEnv implements CellUtils.SizingEnvCreator { + private class Driver { + private final CellInterface cell; + private final HierName outputPort; + private final Collection otherPorts; + private final Map impliedPorts; + public Driver(final CellInterface cell, + final HierName outputPort, + final Collection otherPorts, + final Map impliedPorts) { + this.cell = cell; + this.outputPort = outputPort; + this.otherPorts = otherPorts; + this.impliedPorts = impliedPorts; + } + } + + private final CastFileParser cfp; + private final Cadencize cad; + private final Map drivers; + private final Set synthCells; + private final Set avoidNodes; + public CspSizingEnv(final CastFileParser cfp, final Cadencize cad, + final Set avoidNodes) { + this.cfp = cfp; + this.cad = cad; + this.synthCells = new HashSet(); + this.avoidNodes = avoidNodes; + this.drivers = new HashMap(); + } + + private HierName toHier(final String s) { + try { + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Can't create HierName: " + s, e); + } + } + + private Object getDirective(final CellInterface cell, + final String dir, + final String type, + final HierName node, + final AliasedSet aliases) { + final Object defValue = + DirectiveUtils.getTopLevelDirective(cell, dir); + final Map values = + DirectiveUtils.getTopLevelDirective(cell, dir, type); + for (Iterator i = aliases.getAliases(node); i.hasNext(); ) { + final Object val = values.get(i.next()); + if (val != null) return val; + } + return defValue; + } + + private Driver getDriver(final String driverFqcn) { + Driver result = null; + if (drivers.containsKey(driverFqcn)) { + result = drivers.get(driverFqcn); + } else { + final CellInterface driver = + cfp.getFullyQualifiedCellPretty(driverFqcn, System.err); + if (driver == null) { + System.err.println("ERROR: Cannot parse sizing driver " + + driverFqcn); + } else { + final List outPorts = new ArrayList(); + final Collection otherPorts = + new ArrayList(); + final Map impliedPorts = + new HashMap(); + + (new CellUtils.MarkPort() { + protected void mark(final NodeType nodeType, + final String name, + final int direction) { + final HierName hname = toHier(name); + if (driver.isImpliedPort(name)) { + impliedPorts.put( + hname, + toHier(driver.getParentImpliedPort(name))); + } else if (direction > 0) { + outPorts.add(hname); + } else { + otherPorts.add(hname); + } + } + }).mark(driver); + final int size = outPorts.size(); + if (size == 0) { + System.err.println("ERROR: Sizing driver " + + driver.getFullyQualifiedType() + + " has no output port"); + } else if (size > 1) { + System.err.println("ERROR: Sizing driver " + + driver.getFullyQualifiedType() + + " has more than one output port"); + } else { + result = new Driver(driver, outPorts.get(0), + otherPorts, impliedPorts); + } + } + drivers.put(driverFqcn, result); + } + return result; + } + + private void connectDriver(final CellInterface cell, + final HierName prefix, + final HierName node, + final HierName instance, + final String driverFqcn, + final AliasedSet aliases, + final Map subcells) { + final Driver driver = getDriver(driverFqcn); + if (driver == null) { + System.err.println("ERROR: Cannot add sizing driver on" + + cell.getFullyQualifiedType() + "/" + + node); + } else { + subcells.put(instance, driver.cell); + aliases.makeEquivalent( + HierName.append(prefix, node), + HierName.append(instance, driver.outputPort)); + for (HierName hn : driver.otherPorts) { + final HierName full = HierName.append(instance, hn); + final NodeValue nv = new NodeValue(full); + aliases.add(full); + subcells.put(full, nv.getCell()); + } + for (Map.Entry entry : + driver.impliedPorts.entrySet()) { + aliases.makeEquivalent(entry.getValue(), + HierName.append(instance, entry.getKey())); + } + } + } + + private void getSizingEnv( + final CellInterface cell, + final HierName prefix, + final AliasedSet aliases, + final Set synthCells, + final Map subcells) { + final AliasedSet locals = cad.convert(cell).getLocalNodes(); + final boolean internal = prefix == null; + (new CellUtils.MarkPort() { + protected void mark(final NodeType nodeType, final String name, + final int direction) { + if (direction == 0 || ((direction > 0) == internal)) { + final HierName node = toHier(name); + if (!avoidNodes.contains(node)) { + final String dir = + internal ? DirectiveConstants.INTERNAL_DRIVER + : DirectiveConstants.EXTERNAL_DRIVER; + final String driver = (String) + getDirective(cell, dir, + DirectiveConstants.NODE_TYPE, node, locals); + if (driver != null) { + final HierName instance = toHier("$" + name); + connectDriver(cell, prefix, node, instance, + driver, aliases, subcells); + } + } + } + } + }).mark(cell); + if (synthCells != null && !subcells.isEmpty()) { + synthCells.add(cell.getFullyQualifiedType()); + } + } + + public void getInternalEnv( + final CellInterface cell, + final AliasedSet aliases, + final Map subcells) { + getSizingEnv(cell, null, aliases, synthCells, subcells); + } + + public void getExternalEnv( + final CellInterface cell, + final HierName prefix, + final AliasedSet aliases, + final Map subcells) { + getSizingEnv(cell, prefix, aliases, null, subcells); + } + + public Set getSynthesizedCells() { + return synthCells; + } + } + + private static CellInterface createTopEnv(final CellInterface cell, + final CspSizingEnv creator) { + final AliasedSet/**/ aliases = + new AliasedSet/**/(HierName.getComparator()); + final Map subcells = + new HashMap(); + final HierName topInst = HierName.makeHierName("top"); + if (creator != null) + creator.getExternalEnv(cell, topInst, aliases, subcells); + + final com.avlsi.cell.CellImpl result = new com.avlsi.cell.CellImpl(""); + result.setHasCompleteSubcellsBlock(); + result.addSubcellPair(topInst, cell, false); + for (Map.Entry entry : subcells.entrySet()) { + result.addSubcellPair(entry.getKey(), entry.getValue(), false); + } + for (Iterator i = aliases.getCanonicalKeys(); i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + for (Iterator j = aliases.getAliases(canon); j.hasNext(); ) { + final HierName alias = (HierName) j.next(); + result.addConnection(canon, alias); + } + } + forceFixedSize(result, false); + return result; + } + + static CastDesign loadFullyQualifiedCell(final CastFileParser p, + final String cellName, + final float tau, + final float fixedDelaybias, + final float sizableDelaybias, + final TechnologyData td, + final boolean routed, + final boolean allFixedSize, + final Set skipCells, + final CspSizingEnv creator, + final boolean useSteinerTree) + throws CastSyntaxException, CastSemanticException, IOException { + + //System.out.println(" calling CastFileParser.getFullyQualifiedCell"); + CellInterface theCell = + p.getFullyQualifiedCellPretty(cellName, System.err); + if (theCell == null) { + System.err.println("ERROR: Cannot parse cell: " + cellName); + System.exit(1); + } + if (routed) theCell = theCell.routedSubcells(true); + if (creator != null) + theCell = + ((com.avlsi.cell.CellImpl) theCell).sizingEnvSubcells(creator); + return loadFullyQualifiedCell(p,createTopEnv(theCell, creator), + theCell, tau, fixedDelaybias, + sizableDelaybias, td, + allFixedSize, + creator == null ? + Collections.emptySet() + : creator.getSynthesizedCells(), + skipCells, useSteinerTree); + } + + static CastDesign loadFullyQualifiedCell(final CastFileParser p, + final CellInterface theEnv, + final CellInterface theCell, + final float tau, + final float fixedDelaybias, + final float sizableDelaybias, + final TechnologyData td, + final boolean allFixedSize, + final Set synthCells, + final Set skipCells, + final boolean useSteinerTree) + throws CastSyntaxException, CastSemanticException, IOException { + + if (allFixedSize) forceFixedSize(theCell, true, new HashSet()); + if(DebugOption.printLevel <= 3){ + //System.out.println("PrintLevel " + DebugOption.printLevel); + //System.out.println(" instantiating CastDesign"); + } + final Cadencize cad = new Cadencize(true, + new Cadencize.DefaultCallback(Cadencize.VERILOG_NONE) { + public boolean mark(CellInterface cell, String block) { + return (block.equals(BlockInterface.CSP) && + synthCells.contains(cell.getFullyQualifiedType())) + || Cadencize.NETLIST_PRIORITY.mark(cell, block); + } + }); + return new CastDesign(Vdd, GND, _RESET, tau, td, cad, + p, theEnv, theCell, fixedDelaybias, + sizableDelaybias, synthCells, + skipCells, false, false, useSteinerTree); + } + + public static void usage() { + System.err.println("java " + Jauto.class.getName() + + "\n --cellName=" + + "\n --castInRoot= --outRoot=" + + "\n --spice-output= (name of SPICE output; defaults to transistors.cdl)" + + "\n --cdlRoot=" + + "\n --layoutRoot=" + + "\n --noFloorplan (ignores floorplanning information)" + + "\n --staticizer= (fully qualified name of the staticizer)" + + "\n --weak-inverter= (fully qualified name of the weak inverter)" + + "\n --small-inverter= (fully qualified name of the small inverter)" + + "\n --gates= (colon seperated list of fully qualified gate names)" + + "\n [ --config= ]" + + "\n [ --targetSpeed= ]" + + "\n [ --unitSize ] (size to a constant value)" + + "\n [ --castversion=<1 | 2> (defaults to 1) ]" + + "\n [ --cutoff= ] (cutoff width, defaults to Double.MAX_VALUE)" + + "\n [ --cutoffmin= ] (don't make width smaller than this (defaults to 0)" + + "\n [ --defaultDiffusionLength= ] (output AS, AD, PS, PD)" + + "\n [ --outputRC ] (output wire R and C in CDL)" + + "\n [ --noSizeStaticizers ] (don't size staticizers)" + + "\n [ --reSizeStaticizers ] (resize staticizers only)" + + "\n [ --lengthUnit={ mm | um | nm | pm | fm } ]" + + "\n [ --scaleC= (scale parasitic capacitance estimate) ]" + + "\n [ --scaleR= (scale parasitic resistance estimate) ]" + + "\n [ --scaleM= (scale initial transistor width read from hsizes) ]" + + "\n [ --mfggrid= ] (round up to multiples of grid size) ]" + + "\n [ --subtypePath= ] (output sizing result as subtypes)" + + "\n [ --mode={ spec | size | update | resize } ] (defaults to spec)" + + "\n [ --subtype= ] (meaning depend on mode)" + + "\n [ --trial ] (trial sizing, only effective with --mode=size)" + + "\n [ --pStacks= ] (names of p-stack gates)" + + "\n [ --nStacks= ] (names of n-stack gates)" + + "\n [ --hsizes= ] (name of the file containing half operator sizes)" + + "\n [ --noDebug ] (avoid writing any .debug files)" + + "\n [ --updateDirective ] (update estimated_delay, cap even in fix sized cells)" + + "\n [ --partialExtract= ] (output CDL for partial extraction)" + + "\n [ --fixedSizeDelayBias= ] (apply delaybias to fixed size cells)" + + "\n [ --sizableDelayBias= ] (apply delaybias to sizable cells)" + + "\n [ --proteusBudget ] (creates only paths_top.debug for use by budget gen)" + + "\n [ --debug-level=# ] (set debug level, higher is less debugging)" + + "\n [ --quiet ] (eliminate a lot of screen dump)" + + "\n [ --min-solve-hours=hrs] (minimum time to spend in CG solver)" + + "\n [ --max-solve-hours=hrs] (maximum time to spend in CG solver)"); + + System.exit(1); + } + + static void unitSize(CellType newtop, double WN, double WP) { + Debug.assertTrue(!newtop.manual); + // Debug.assertTrue(!newtop.manual); + newtop.walkOnce(new unitSizer(WN,WP)); + } + + static Format getSubtypeHeader(final String cellName, + final String techName) { + final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); + final DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.LONG); + final Date now = new Date(); + final StringBuffer header = new StringBuffer(); + header.append("'"); header.append(cellName); header.append("'"); + header.append(":"); + header.append(dateFormat.format(now)); + header.append(":"); + header.append(timeFormat.format(now)); + header.append(":"); + header.append(System.getProperty("user.name")); + header.append("\n"); + header.append("Mode: {0}\n"); + header.append(buildVersion()); + header.append(" - "); + header.append(versionNumber); + header.append("\n"); + header.append("Technology: " + techName + "\n"); + return new MessageFormat(header.toString()); + } + + private static Iterator getLeafUpdate(final SortedMap typeMap, final String base) { + final SortedMap subtypeMap = (SortedMap) typeMap.get(base); + Debug.assertTrue(subtypeMap != null); + // Extract cells that are not fixed sized + final UnaryPredicate unfixed = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final Pair p = (Pair) ((Map.Entry) o).getValue(); + return !CellUtils.isFixedSize((CellInterface) p.getFirst()); + } + }; + final UnaryFunction val = new UnaryFunction() { + public Object execute(final Object o) { + return ((Map.Entry) o).getValue(); + } + }; + return new MappingIterator( + new FilteringIterator( + subtypeMap.entrySet().iterator(), unfixed), val); + } + + static void writeOut( final CellType top, + final String outdir, + final String cellName, + final String outFile, + final double cutoff, + final double cutoffmin, + final Double diffusionLength, + final boolean outputRC, + final String lengthUnit, + final double scaleC, + final double scaleR, + final Double mfggrid, + final String subtypePath, + final CastFileParser cfp, + final String mode, + final String subtype, + final boolean sizeTrial, + final Map/*,NetGraph>*/ stackMap, + final Cadencize cad, + final String tau, + final TransistorSizingTool tool, + final String layoutAttribute, + final CastDesign design, + final List/**/ listAllGlobalNets, + final float spiceCap, + final float minWidth, + final boolean updateDirective, + final PartialExtract.CellPlusMinus fqcnSpec, + final String techName, + final UnaryPredicate nfsPredicate) { + /* Setup netlist processors according to commandline arguments */ + /* Print out AS/AD/PS/PD */ + DeviceProcessorInterface diffProc = null; + if (diffusionLength != null) { + diffProc = new DeviceProcessorInterface () { + public DeviceProcessorInterface.Transistor + processTransistor(DeviceProcessorInterface.Transistor d) + { + d.parameters = new LinkedHashMap(d.parameters); + final double dlen = diffusionLength.doubleValue(); + final double as = d.width * dlen; + final double ps = (d.width + dlen) * 2; + d.parameters.put("AS", new Double(as)); + d.parameters.put("AD", new Double(as)); + d.parameters.put("PS", new Double(ps)); + d.parameters.put("PD", new Double(ps)); + return d; + } + }; + } + + /* Scale capcitance */ + DeviceProcessorInterface scaleCProc = null; + if (scaleC != 1.0) { + scaleCProc = new DeviceProcessorInterface () { + public DeviceProcessorInterface.Capacitor + processCapacitor(DeviceProcessorInterface.Capacitor d) { + d.capacitance *= scaleC; + return d; + } + }; + } + + /* Scale resistance */ + DeviceProcessorInterface scaleRProc = null; + if (scaleR != 1.0) { + scaleRProc = new DeviceProcessorInterface () { + public DeviceProcessorInterface.Resistor + processResistor(DeviceProcessorInterface.Resistor d) { + d.conductance /= scaleR; + return d; + } + }; + } + + /* Round to manufacturing grid */ + final double RoundingTolerance = 1.02; // could be a PDK parameter + final double [] RoundingMultiples = {1,2,4,6,8,12,16,24}; // for folding + DeviceProcessorInterface mfggridProc = null; + if (mfggrid != null) { + final double gridsize = mfggrid.doubleValue(); + final double[] widths = design.getTechnologyData().getWidths(); + final long[] gridWidths = new long[widths.length]; + for (int i = 0; i < widths.length; ++i) { + gridWidths[i] = Math.round(widths[i] / gridsize); + } + mfggridProc = new DeviceProcessorInterface() { + HierName currentCell; + String locationString; + + /* Funky rounding algorithm designed to choose the + * largest convenient multiple of gridsize without + * exceeding a rounding tolerance. See BUG 11947. */ + private double round(double num) { + double x = 0.0; + for (int i = RoundingMultiples.length-1; i>=0; i--) { + double g = RoundingMultiples[i]*gridsize; + x = Math.round(num/g)*g; + if (x/num < RoundingTolerance && num/x < RoundingTolerance) break; + } + return x; + } + + private double roundFixedWidths(final double num) { + final long grids = Math.round(num / gridsize); + int idx = Arrays.binarySearch(gridWidths, grids); + if (idx < 0) idx = -(idx + 1); + return idx < widths.length ? widths[idx] : Double.NaN; + } + + private double roundLength(final double num) { + return round(num); + } + + private double roundWidth(final double num) { + double result; + if (widths.length > 0) { + result = roundFixedWidths(num); + if (Double.isNaN(result)) { + System.err.printf( + "ERROR: Cannot round width %.3g (largest " + + "allowed is %.3g) for %s\n", num, + widths[widths.length - 1], locationString); + result = round(num); + } + } else { + result = round(num); + } + return result; + } + + private double round(final double num, final boolean isWidth) { + return isWidth ? roundWidth(num) : roundLength(num); + } + + private void roundParam(Map m, String key, boolean isWidth) { + for (Iterator i = m.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String realKey = (String) entry.getKey(); + if (realKey.startsWith(key)) { + Double v = (Double) entry.getValue(); + m.put(realKey, new Double(round(v.doubleValue(), + isWidth))); + } + } + } + + public DeviceProcessorInterface.Transistor + processTransistor(DeviceProcessorInterface.Transistor d) { + locationString = currentCell + " M" + d.name; + d.width = round(d.width, true); + d.length = round(d.length, false); + return d; + } + + public DeviceProcessorInterface.Call + processCall(DeviceProcessorInterface.Call d) { + locationString = currentCell + " X" + d.name; + roundParam(d.parameters, "NL", false); + roundParam(d.parameters, "NW", true); + roundParam(d.parameters, "PL", false); + roundParam(d.parameters, "PW", true); + return d; + } + + public void processCell(HierName s) { + if (DebugOption.printLevel <= 1) + System.out.println("Round transistor widths in " + s); + currentCell = s; + } + }; + } + + final CellType[] trueNameCell = new CellType[] { null }; + DeviceProcessorInterface trueNameProc = new DeviceProcessorInterface() { + public DeviceProcessorInterface.Transistor + processTransistor(DeviceProcessorInterface.Transistor d) + { + if (trueNameCell[0] != null) { + d.type = + CellUtils.getTransistorModelName( + trueNameCell[0].cast_cell, d.type); + } + return d; + } + }; + + // Setup two processors for creating SPICE netlist, one for fixed size + // cells, and one for sizable cells + final DeviceProcessor fixedCdlProc = new DeviceProcessor(null); + final DeviceProcessor sizableCdlProc = new DeviceProcessor(null); + fixedCdlProc.appendProcessor(trueNameProc); + sizableCdlProc.appendProcessor(trueNameProc); + if (scaleCProc != null) { + fixedCdlProc.appendProcessor(scaleCProc); + sizableCdlProc.appendProcessor(scaleCProc); + } + if (scaleRProc != null) { + fixedCdlProc.appendProcessor(scaleRProc); + sizableCdlProc.appendProcessor(scaleRProc); + } + if (mfggridProc != null) { + // no rounding for fixed size netlists + sizableCdlProc.appendProcessor(mfggridProc); + } + if (diffProc != null) { + // should come after all processors that modify transistor widths + fixedCdlProc.appendProcessor(diffProc); + sizableCdlProc.appendProcessor(diffProc); + } + + /* Setup processors to be used in output netlist block for subtypes. + * Netlist block in a CAST should not contain AS/AD/PS/PD */ + final DeviceProcessor subtypeProc = new DeviceProcessor(null); + if (scaleCProc != null) subtypeProc.appendProcessor(scaleCProc); + if (scaleRProc != null) subtypeProc.appendProcessor(scaleRProc); + if (mfggridProc != null) subtypeProc.appendProcessor(mfggridProc); + + final Format subtypeHeader = getSubtypeHeader(cellName, techName); + + final CellType cell = findCell(top, cellName); + if (cell == null) { + System.err.println("Cell " + cellName + " not found!"); + return; + } + + // Store away all the arguments that are the same for convenience + final BinaryFunction writeSubtype = new BinaryFunction() { + public Object execute(final Object a, final Object b) { + // XXX: Exception handling causes some annoyance. Should think + // of a better way to deal with this. + try { + return SubtypeOutput.writeSubtype((SubtypeOutput.Policy) a, + (CellType) b, + subtypeProc, + lengthUnit, + cutoff, + cutoffmin, + stackMap, + GND, + Vdd, + minWidth); + } catch (IOException e) { + return e; + } + } + }; + + SortedMap updateMap = null; + final SubtypeOutput.Policy subtypePolicy; + final Map missingAlias = + new TreeMap(); + if (subtypePath == null) { + subtypePolicy = null; + } else if (mode.equals(SUBTYPE_MODE)) { + subtypePolicy = null; + final Object o = writeSubtype.execute(new SubtypeOutput.Subtype(Integer.parseInt(subtype), subtypePath, subtypeHeader, layoutAttribute, writeSubtype, design, missingAlias), cell); + if (o instanceof IOException) { + System.err.println("Cannot write subtype " + ((IOException) o).getMessage()); + } + } else if (mode.equals(SIZE_MODE) || mode.equals(CHARGE_MODE)) { + final Map globalNetMap = Collections.EMPTY_MAP; + subtypePolicy = new SubtypeOutput.Size(subtypePath, sizeTrial, subtypeHeader, tau == null ? Float.NaN : (float) tool.getOptionUnitDelay(), globalNetMap, updateDirective); + } else if (mode.equals(UPDATE_MODE)) { + final String fullName = cellName + "." + subtype; + final CellInterface updatee = + cfp.getFullyQualifiedCellPretty(fullName, System.err); + if (updatee == null) { + System.err.println("ERROR: Cannot parse cell for update: " + + fullName); + System.exit(1); + } + updateMap = new TreeMap(); + SubtypeMerge.prepare(updatee, updateMap); + subtypePolicy = null; + } else { + subtypePolicy = null; + } + + File dir = new File(outdir); + if (!dir.exists() && !dir.mkdir()) { + System.err.println("Cannot write to directory " + outdir + "!"); + System.exit(1); + } + final File all = new File(outdir,outFile); + Writer wall = null; + try { + wall = new BufferedWriter(new FileWriter(all)); + } catch (IOException e) { + System.err.println("Cannot write to file " + all + ": " + e.getMessage()); + System.exit(2); + } + + final Template templ = fqcnSpec.isEmpty() ? + null : new Template(new LinkedHashMap()); + final CDLFactoryInterface cdlEmitter = templ == null ? + (CDLFactoryInterface) new CDLFactoryEmitter(wall) : templ; + final CDLFactoryInterface trueNamesEmitter = + new Cast2Cdl.RealTransistorNames(cdlEmitter, cfp); + + final Stack dep = dependency(cell); + final Set/**/ seen = new LinkedHashSet/**/(); + while (!dep.empty()) { + final Object obj = dep.pop(); + if (obj instanceof CellType) { + final CellType c = (CellType) obj; + if (c.isWiringCell) continue; + if (!seen.add(c.typeName)) continue; + + final CDLFactoryInterface cdlTarget; + final Map stored = new HashMap(); + if (templ == null) { + /* Find all subcircuit instantiations, and emit their + * definitions first if they haven't been emitted already. + * Since the cells are processed from the bottom of the + * instantiation tree, the only calls that haven't already + * been processed must be those of gates and stacks. + */ + cdlTarget = new CDLFactoryFilter(new Template(stored)) { + public void makeCall(HierName name, String subName, + HierName[] args, Map parameters, + Environment env) { + if (seen.add(subName)) { + final CellInterface ci = + cfp.getFullyQualifiedCellPretty(subName, System.err); + if (ci == null) { + System.err.println("ERROR: Cannot parse gate/stack library cell: " + subName); + } else { + CDLOutput.writeCDL(ci, cad, trueNamesEmitter); + } + } + super.makeCall(name, subName, args, parameters, env); + } + }; + } else { + cdlTarget = templ; + } + final NetlistFormatter netlistEmitter = + new FactoryEmitter(cdlTarget, new PrintfFormat("%6.4e")); + + /* Output CDL */ + trueNameCell[0] = c; + final DeviceProcessor cdlProc = + c.isFixedSize() ? fixedCdlProc : sizableCdlProc; + CDLOutput.writeCDL(c, cdlProc, cutoff, cutoffmin, outputRC, stackMap, + GND, Vdd, + Float.isNaN(spiceCap) || (c == cell) ? spiceCap : -1, + minWidth, + netlistEmitter, (Visitor) netlistEmitter); + + if (templ == null) { + final Set subckts = stored.entrySet(); + assert subckts.size() == 1; + for (Iterator i = subckts.iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Template t = (Template) entry.getValue(); + t.execute(trueNamesEmitter, Collections.EMPTY_MAP, + NullEnvironment.getInstance(), + (String) entry.getKey()); + } + } + + /* Output subtype */ + if (subtypePolicy != null && (nfsPredicate == null || + nfsPredicate.evaluate(c))) { + final Object o = writeSubtype.execute(subtypePolicy, c); + if (o instanceof IOException) { + System.err.println("Cannot write subtype " + ((IOException) o).getMessage()); + } + } + + /* Update mode. Should be cleaned up. */ + if (subtypePath != null && com.avlsi.cell.CellUtils.isLeaf(c.cast_cell) && mode.equals(UPDATE_MODE)) { + for (Iterator i = getLeafUpdate(updateMap, c.typeName); i.hasNext(); ) { + final Object o = writeSubtype.execute(new SubtypeOutput.Update(subtypePath, subtypeHeader, (Pair) i.next()), c); + if (o instanceof IOException) { + System.err.println("Cannot write subtype " + ((IOException) o).getMessage()); + } + } + } + } else { + /* This is a gate. We do not emit subtypes for gates. */ + final String s = (String) obj; + if (!seen.add(s)) continue; + final CellInterface ci = + cfp.getFullyQualifiedCellPretty(s, System.err); + if (ci == null) { + System.err.println("ERROR: Cannot parse gate library cell: " + s); + } else { + CDLOutput.writeCDL(ci, cad, trueNamesEmitter); + } + } + } + try { + if (templ != null) { + final PartialExtract pe = + new PartialExtract(templ.getTemplates(), cellName, fqcnSpec); + pe.execute(new CDLFactoryEmitter(wall)); + } + wall.flush(); + } catch (IOException e) { + System.err.println("Cannot flush file " + all + ": " + e.getMessage()); + } + if (!missingAlias.isEmpty()) { + System.err.println( + "ERROR: the following " + DirectiveConstants.NAME_MAPPING + + " directives cannot be applied:\n"); + for (Map.Entry miss : missingAlias.entrySet()) { + final String alias = miss.getKey(); + final Exception reason = miss.getValue(); + if (reason == null) { + System.err.println(alias + " is not an defalias cell"); + } else { + System.err.print(alias + " cannot be parsed: "); + if (reason instanceof CastSemanticException) { + ExceptionPrettyPrinter.printException( + (CastSemanticException) reason, + System.err); + } else { + System.err.println(reason.getMessage()); + } + } + System.err.println(); + } + System.exit(1); + } + } + + static CellType findCell(final CellType top, final String name) { + final CellType[] result = new CellType[1]; + top.walkOnce(new CellTypeProcessor() { + public void processCellType(CellType c) { + if (c.typeName.equals(name)) { + result[0] = c; + } + } + }); + return result[0]; + } + + static Map getCapDelay(final CellType top) { + final Map result = new HashMap(); + top.walkOnce(new CellTypeProcessor() { + public void processCellType(CellType c) { + for (Iterator i = c.getAllNets().iterator(); i.hasNext(); ) { + final CellNet net = (CellNet) i.next(); + if (net.isInternalNet()) { + if (!result.containsKey(net.container.typeName)) { + result.put(net.container.typeName, new ArrayList()); + } + + assert net.getGlobalNets().size() == 1 : + "An internal CellNet has " + + net.getGlobalNets().size() + " GlobalNets!"; + + final HierName canon = net.getInternalCanonical(); + assert canon != null : + "getInternalCanonical returns null for " + net; + + final GlobalNet gnet = + (GlobalNet) net.getGlobalNets().get(0); + + final Float up, dn; + if (gnet.getListSources().isEmpty()) { + up = dn = null; + } else { + up = new Float(net.getUpDelay()); + dn = new Float(net.getDownDelay()); + } + + final Float cap = gnet.getListSinks().isEmpty() ? + null : new Float(gnet.getLoadCapacitance()); + + ((List) result.get(net.container.typeName)).add(new Pair(canon, new Triplet(cap, up, dn))); + } + } + } + }); + return result; + } + + static Stack dependency(CellType cell) { + final Stack dep = new Stack(); + /* XXX: Assume walkMany will process the current cell, then recursively + * traverse its children */ + cell.walkMany(new CellType.InstanceProcessor() { + public void processInstance(CellType c, HierName instance, + Collection path) { + dep.push(c); + } + }); + return dep; + } + + /** give everything reasonable initial sizes **/ + private static class unitSizer implements CellTypeProcessor { + double WP,WN; + public unitSizer(double WN, double WP) { + this.WN = WN; + this.WP = WP; + } + public void processCellType(CellType c) { + if (c.listHalfOperators == null) return; + for (Iterator i = c.listHalfOperators.iterator(); i.hasNext(); ) { + HalfOperator ho = (HalfOperator) i.next(); + ho.resetWidth(); + } + for (Iterator i = c.listHalfOperators.iterator(); i.hasNext(); ) { + HalfOperator ho = (HalfOperator) i.next(); + ho.updateSize(ho.driveDirection==HalfOperator.DriveDirection.PULL_UP ? WP : WN); + } + } + } + + public static void recursivePrint(CellType top) + { + + System.out.println("*** Design summary before sizing: "); + + System.out.println("cell type name: " + top.typeName); + System.out.println("subtype index: " + top.subtypenumber); + + System.out.println("number of subcells: " + top.getAllSubcells().size()); + System.out.println("number of cell nets: " + top.getAllNets().size()); + +// System.out.println("number of half-operators: " + top.getListHalfOperators().size()); + + + System.out.println("\nsubcell listing:\n"); + for (Iterator ita = top.getAllSubcells().iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + System.out.println("cell type name: " + sta.typeName); + System.out.println("subtype index: " + sta.subtypenumber); + } + + + System.out.println("\ncellnet listing:\n"); + for (Iterator itb = top.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cnta = (CellNet)itb.next(); + + System.out.println(cnta.toString()); + System.out.println(); + } + +/* + System.out.println("\nhalf-operator listing:\n"); + for (Iterator itc = top.getListHalfOperators().iterator(); itc.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itc.next(); + System.out.println("\tvariable name: " + hoa.getVariableName()); + } +*/ + + for (Iterator itd = top.getAllSubcells().iterator(); itd.hasNext(); ) { + CellType sta = (CellType)itd.next(); + + System.out.println("****************************************************"); + System.out.println("Going into: " + sta.typeName); + System.out.println("****************************************************"); + recursivePrint(sta); + } + } + + + /** + * Check the number of the staticizers on all nets. Every dynamic + * node should have one and only one staticizer. Due to our + * design method, the tool could generate more than one + * staticizers on one net, such as a shared bus. So number + * checking is very important procedure to make sure that no node + * will be over-staticized, which leads to slow down or + * mal-function. Jlvs checks that the staticizers are correct + * within one leaf cell. This code doesn't! + **/ + public static void checkStaticizerNumber(List lst1) { + for (Iterator ita = lst1.iterator(); ita.hasNext(); ) { + GlobalNet gna = (GlobalNet) ita.next(); + int nPullUp = 0, nPullDown = 0; + HashSet visited = new HashSet(); + CellNet cna = gna.getTopCellNet(); + + // find all driving half-operators of this global net + for (Iterator itb = gna.getListSources().iterator(); itb.hasNext(); ) { + NetSource nsra = (NetSource) itb.next(); + assert nsra.type == NetType.HALF_OPERATOR_TRANSISTOR + : "Globalnet should not have type-1 " + + "NetSource/NetSink at this stage.\n" + + "CellName: " + cna.container.typeName + "\n" + + "NetName: " + cna.canonicalName.getCadenceString(); + NetGraph.NetNode nna = nsra.source.outputNode; + // avoid processing same node twice (TODO: a better way!) + String name = nsra.getInstanceName() + "/" + nna.getName(); + if (visited.contains(name)) continue; + visited.add(name); + // look for up/down feedback in this leaf cell + int hasPullUp = 0, hasPullDown = 0; + for (Iterator itc = nna.getPaths().iterator(); itc.hasNext(); ) { + NetGraph.NetPath npa = (NetGraph.NetPath) itc.next(); + if (npa.isFeedBack()){ + int j = npa.getType(); + if (j == DeviceTypes.N_TYPE) { hasPullDown = 1; } + else if (j == DeviceTypes.P_TYPE) { hasPullUp = 1; } + } + } + nPullDown += hasPullDown; + nPullUp += hasPullUp; + } + int nDrivers = visited.size(); + + // check that node either has or does not have staticizer feedback + if (!((nDrivers<=1 && nPullDown==0 && nPullUp==0) || + (nPullDown==1 && nPullUp==1))) { + String msa = "WARNING"; + String msb = "Bad staticizer\n"; + String msc = "CellName: " + cna.container.typeName + "\n" + + "NetName: " + cna.canonicalName.getCadenceString() + "\n" + + "Number of driving cells: " + nDrivers + "\n" + + "Number of staticizer pull-up cells: " + nPullUp + "\n" + + "Number of staticizer pull-down cells: " + nPullDown + "\n"; + messageCenter.createMessage(1, 1, msa, msb, msc); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessage.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessage.java new file mode 100644 index 0000000000..ee51d5645b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessage.java @@ -0,0 +1,127 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + + +public class JautoMessage +{ + int type; // type of the message + // 0: Error + // 1: Warning + // 2: Note + // 3: Time stamp + // 4: Other + + int number; + + String prefix; + + String description; + + String detail; + + + public JautoMessage() + { + type = -1; + number = -1; + prefix = ""; + description = ""; + detail = ""; + } + + + public JautoMessage(JautoMessage msg) + { + type = msg.type; + number = msg.number; + prefix = msg.prefix; + description = msg.description; + detail = msg.detail; + } + + + public JautoMessage(int i1, int i2, String s1, String s2, String s3) + { + assert i2 < 100 : "Programmer error, change it to an assertion"; + + type = i1; + + if(i2 > 0){ + number = i2; + } + + prefix = s1; + description = s2; + detail = s3; + } + + + public void setMessage(int i1, int i2, String s1, String s2, String s3) + { + assert i2 < 100 : "Programmer error, change it to an assertion"; + + type = i1; + + if(i2 > 0){ + number = i2; + } + + prefix = s1; + description = s2; + detail = s3; + } + + + public void output() + { + assert number < 100; + if(type > 0){ // not error + System.out.print("\033[1;33m" + prefix + " " + number + ": " + "\033[0m"); + System.err.print("\033[1;33m" + prefix + " " + number + ": " + "\033[0m"); + } + else{ + System.out.print("\033[1;31m" + prefix + " " + number + ": " + "\033[0m"); + System.err.print("\033[1;31m" + prefix + " " + number + ": " + "\033[0m"); + } + + System.out.print(description); + System.out.print(detail); + + System.err.print(description); + System.err.print(detail); + } + + + public void outputShort() + { + assert number < 100; + if(type > 0){ // not error + System.out.print("\033[1;33m" + prefix + " " + number + ": " + "\033[0m"); + System.err.print("\033[1;33m" + prefix + " " + number + ": " + "\033[0m"); + } + else{ + System.out.print("\033[1;31m" + prefix + " " + number + ": " + "\033[0m"); + System.err.print("\033[1;31m" + prefix + " " + number + ": " + "\033[0m"); + } + + System.out.print(description); + + System.err.print(description); + } + + + public void print() + { + assert number < 100; + System.out.print(prefix + " " + number + ": " + description); + System.out.print(detail); + } + + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessageCenter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessageCenter.java new file mode 100644 index 0000000000..4bd06c5055 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoMessageCenter.java @@ -0,0 +1,173 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +public class JautoMessageCenter +{ + static final String emailSuffix = "@fulcrummicro.com"; + String userName; + + List/**/ errorMsgs; + List/**/ warningMsgs; + List/**/ otherMsgs; + + + public JautoMessageCenter() + { + errorMsgs = new ArrayList/**/(); + warningMsgs = new ArrayList/**/(); + otherMsgs = new ArrayList/**/(); + + userName = System.getProperty("user.name", ""); + } + + + public JautoMessageCenter(JautoMessageCenter mc) + { + errorMsgs = new ArrayList/**/(mc.errorMsgs); + warningMsgs = new ArrayList/**/(mc.warningMsgs); + otherMsgs = new ArrayList/**/(mc.otherMsgs); + + userName = mc.userName; + } + + + public void output() + { + for (Iterator ita = errorMsgs.iterator(); ita.hasNext(); ) { + JautoMessage jma = (JautoMessage)ita.next(); + jma.output(); + } + + for (Iterator ita = warningMsgs.iterator(); ita.hasNext(); ) { + JautoMessage jma = (JautoMessage)ita.next(); + jma.output(); + } + + for (Iterator ita = otherMsgs.iterator(); ita.hasNext(); ) { + JautoMessage jma = (JautoMessage)ita.next(); + jma.output(); + } + } + + public void outputShort() + { + for (Iterator ita = errorMsgs.iterator(); ita.hasNext(); ) { + JautoMessage jma = (JautoMessage)ita.next(); + jma.outputShort(); + } + + for (Iterator ita = warningMsgs.iterator(); ita.hasNext(); ) { + JautoMessage jma = (JautoMessage)ita.next(); + jma.outputShort(); + } + + for (Iterator ita = otherMsgs.iterator(); ita.hasNext(); ) { + JautoMessage jma = (JautoMessage)ita.next(); + jma.outputShort(); + } + } + + + public JautoMessage createMessage(int i1, int i2, String s1, String s2, String s3) + { + int i; + + if((i1 >= 0) && (i1 <= 2)){ + i = i1; + } + else{ + i = 2; + } + + JautoMessage jma = new JautoMessage(i, i2, s1, s2, s3); + switch(i1){ + case 0: errorMsgs.add(jma); + break; + + case 1: warningMsgs.add(jma); + break; + + case 2: otherMsgs.add(jma); + break; + + default: throw new AssertionError(); + } + + jma.output(); + + return jma; + } + + + public JautoMessage createMessageShort(int i1, int i2, String s1, String s2, String s3) + { + int i; + + if((i1 >= 0) && (i1 <= 2)){ + i = i1; + } + else{ + i = 2; + } + + JautoMessage jma = new JautoMessage(i, i2, s1, s2, s3); + switch(i1){ + case 0: errorMsgs.add(jma); + break; + + case 1: warningMsgs.add(jma); + break; + + case 2: otherMsgs.add(jma); + break; + + default: throw new AssertionError(); + } + + jma.outputShort(); + + return jma; + } + + + public JautoMessage createMessageSilent(int i1, int i2, String s1, String s2, String s3) + { + int i; + + if((i1 >= 0) && (i1 <= 2)){ + i = i1; + } + else{ + i = 2; + } + + JautoMessage jma = new JautoMessage(i, i2, s1, s2, s3); + switch(i1){ + case 0: errorMsgs.add(jma); + break; + + case 1: warningMsgs.add(jma); + break; + + case 2: otherMsgs.add(jma); + break; + + default: throw new AssertionError(); + } + + // jma.output(); + + return jma; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoSolver.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoSolver.java new file mode 100644 index 0000000000..6bec1677d2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoSolver.java @@ -0,0 +1,379 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.*; +import java.util.*; + +import com.avlsi.util.text.NumberFormatter; + +/** + * After getting fed up with the crappiness of Lancelot and the + * growing complexity of the external C solver, I decided to write a + * built in conjugate gradient solver which takes advantage of all the + * assumptions about how Jauto formulates the problem. The + * minimization algorithm itself is based on the sw/c/lib/minimize.c + * (originally from Numerical recipes), and the annealing process is + * right out of solve. The functions to get the energy and gradient + * are just written here as concisely and efficiently as possible. + * All derivatives are analytic. This new approach is probably orders + * of magnitude faster and simpler than all the mucking about we've + * done with external solvers. Pity Jauto's data structures are so + * crappy, but they are easily converted into something efficient. + * + * Andrew Lines, Oct 3, 2004 + */ +public class JautoSolver { + /** tuning parameters */ + int min_iterations = 100; + int max_iterations = 1; + double initial_weight = 10; + double final_weight = 1e7; + double step_weight = 10; + double iteration_ratio = 2; + double tolerance = 1e-4; + double min_gradient = 1e-20; + double TINY = 1e-10; + + /** problem definition */ + int N; // number of variables + List constraints; // list of Constraint's + double [] X; // values of log variables + double [] minX; // lower bounds and scaling for variables + double [] maxV; // upper bounds for independent variables + double [] expX; // temporary storage for minX * exp(X) + double [] energyCoefficients; // coefficients for energy contribution + double scaleObjective; // scales objective function energy + double scaleConstraint; // scales constraint energy + double scaleMinMax; // scales min/max width energy + Map NameToIndex; // maps variable name to index + long minEndTime = -1; // real time at which to terminate or -1 + long maxEndTime = -1; // real time at which to terminate or -1 + + /** inner class to represet a single constraint */ + private class Constraint { + /** constant term */ + double c; + + /** C*X terms */ + double [] cX; + int [] iX; + + /** C*X/Y terms */ + double [] cXY; + int [] iXY_X,iXY_Y; + + /** C/Y terms */ + double [] cY; + int [] iY; + + /** + * Construct constraint from the silly FunctionTerm list. The + * first term just identifies the constraint type. The last + * term is the delay budget. + */ + Constraint(List listConstraint) { + // pull out delay budget + int len = listConstraint.size(); + double budget = ((FunctionTerm) listConstraint.get(len-1)).coefficient; + + // count types of terms + int numX=0, numXY=0, numY=0; + for (int j=1; jmaxV[i]) E += scaleMinMax * (v[i]-maxV[i]) * (v[i]-maxV[i]); + } + + // constraint energy constribution + for (Iterator s = constraints.iterator(); s.hasNext(); ) { + Constraint cons = (Constraint) s.next(); + E += cons.getEnergy(); + } + return E; + } + + /** evaluate the derivative */ + private void getDown(double [] v, double [] down) { + + // compute energy and min/max width negative gradient + for (int i=0; imaxV[i]) down[i] -= scaleMinMax * 2 * (v[i]-maxV[i]); + } + + // accumulate constraint negative gradient + for (Iterator s = constraints.iterator(); s.hasNext(); ) { + Constraint cons = (Constraint) s.next(); + cons.getDown(down); + } + + // variable upper bound energy contributon + + } + + private class EnergyFunction implements ConjugateGradientSolver.Function { + /** evaluate the energy */ + public double getValue(double [] v) { + return getEnergy(v); + } + + /** evaluate the derivative */ + public void getNegativeGradient(double [] v, double [] down) { + getDown(v, down); + } + } + + /** Misnamed: Evaluates continue condition, not stop condition. **/ + private class TimedStop implements ConjugateGradientSolver.StopCondition { + private int iterations = 0; + private final double min_magsqr = min_gradient * min_gradient; + private final long start_time = new Date().getTime(); + public boolean evaluate(boolean big_step, double mag) { + ++iterations; + long time = new Date().getTime() - start_time; + if (!((maxEndTime<0) || (time= min_magsqr) && // gradient nonzero + (big_step && // tolerance + (iterations <= max_iterations) || // iterations + ((minEndTime>=0) && (timeThe function calls the "dumpInfo" function for each cell. + *

    Each cell in turn, writes out its own information and calls other elements' "dumpInfo" functions. + **/ + public static void dumpAllInformation(CastDesign design, String fileName) + { + try{ + BufferedWriter bw = new BufferedWriter(new FileWriter(fileName)); + + //bw.write("Sizing Information Dumping\n\n"); + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + cella.dumpInfo(bw, ""); + } + + bw.close(); + + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + + /** + * This function writes out information about transistor sizes + * different ways. Three files are written: + *

      + *
    • "sizes.debug" gives real transistor widths. For each + * half-operator, it will give transistor sizes for transistors + * in stacks of different depth. + *
    • "strength.debug" gives the strength (defined as the effective + * resistance) of the half-operators. + *
    • "hsizes.debug" gives the effective sizes of the half-operators. + *
    • "cells.debug" summarizes per cell. + *
    + **/ + public static void dumpSizeInformation(CastDesign design, String dirName) + { + File sizesDebugFile = new File(dirName, "sizes.debug"); + File strengthDebugFile = new File(dirName, "strength.debug"); + File hsizesDebugFile = new File(dirName, "hsizes.debug"); + File cellsDebugFile = new File(dirName, "cells.debug"); + + try{ + BufferedWriter sizesWriter = new BufferedWriter(new FileWriter(sizesDebugFile)); + BufferedWriter strengthWriter = new BufferedWriter(new FileWriter(strengthDebugFile)); + BufferedWriter hsizesWriter = new BufferedWriter(new FileWriter(hsizesDebugFile)); + BufferedWriter cellsWriter = new BufferedWriter(new FileWriter(cellsDebugFile)); + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + if(cta.getListHalfOperators().size() > 0){ + sizesWriter.write("CELL " + cta.typeName + " {\n"); + strengthWriter.write("CELL " + cta.typeName + " {\n"); + hsizesWriter.write("CELL " + cta.typeName + " {\n"); + cellsWriter.write("CELL " + cta.typeName + " {\n"); + int numInstances = cta.getPhysicalInstanceCount(); + double allWidth = 0.0; + double maxWidth = Double.NEGATIVE_INFINITY; + double minWidth = Double.POSITIVE_INFINITY; + double widthHalfOps = 0.0; + int numHalfOps = 0; + + // print sizes + for (Iterator itb = + sortHalfOperators(cta.getListHalfOperators()) + .iterator(); + itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + String s, driveDir; + if (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + s = "N"; + driveDir = "-"; + } else { + s = "P"; + driveDir = "+"; + } + final String halfOp = + " " + hoa.outputNet.canonicalName.getCadenceString() + + " " + driveDir; + sizesWriter.write(halfOp); + strengthWriter.write(halfOp); + hsizesWriter.write(halfOp); + + // write logic widths to sizes.debug + double maxw=0.0; + for (Iterator itc = hoa.depths.iterator(); itc.hasNext(); ) { + int i = ((Integer)itc.next()).intValue(); + double w = hoa.getWidth(i); + double f = hoa.getSymmetrizationFactor(); + sizesWriter.write(" " + s + "W" + i + "=" + + NumberFormatter.format(w*1e6, 3) + "u" + + (f!=1 ? "*" + f : "")); + maxWidth=Math.max(maxWidth,w); + minWidth=Math.min(minWidth,w); + maxw=Math.max(maxw,w); + } + widthHalfOps+=maxw; + numHalfOps++; + strengthWriter.write(" " + NumberFormatter.format(hoa.getStrength(), 3) + "\n"); + hsizesWriter.write(" " + NumberFormatter.format(hoa.getCurrentSize(), 3) + "\n"); + sizesWriter.write("\n"); + } + + // second pass for staticizers + for (Iterator itb = cta.transistors.getNodes().iterator(); itb.hasNext(); ) { + NetGraph.NetNode node = (NetGraph.NetNode) itb.next(); + String str = " " + node.getName(); + boolean pr = false; + for (int i=0; i<2; i++) { + int type = i==0 ? DeviceTypes.N_TYPE : DeviceTypes.P_TYPE; + double fbW = -1; + int fbD = -1; + for (Iterator itc = node.getFeedbackPaths().iterator(); itc.hasNext(); ) { + NetGraph.NetPath path = (NetGraph.NetPath) itc.next(); + if (path.getType() == type) { + double W = path.getMinWidth(false); + if (fbW<0) fbW = W; + else fbW = Math.min(fbW,W); + fbD = Math.max(fbD,path.getDepth()); + } + } + if (fbW>0 && fbD>0) { + pr = true; + str += " " + (i==0 ? "N" : "P") + "WS=" + + NumberFormatter.format(fbW*1e6,3) + "u" + + (fbD>1 ? "/" + fbD : ""); + } + } + if (pr) sizesWriter.write(str + "\n"); + } + + // count total transistor width + for (Iterator itb = cta.transistors.getEdges().iterator(); itb.hasNext(); ) { + NetGraph.NetEdge edge = (NetGraph.NetEdge) itb.next(); + allWidth += edge.width; + } + + // finish cells.debug + double avgWidth = widthHalfOps / numHalfOps; + cellsWriter.write(" instances = " + numInstances + "\n"); + cellsWriter.write(" all_width = " + NumberFormatter.format(allWidth*1e6,3) + "u\n"); + cellsWriter.write(" avg_width = " + NumberFormatter.format(avgWidth*1e6,3) + "u\n"); + cellsWriter.write(" max_width = " + NumberFormatter.format(maxWidth*1e6,3) + "u\n"); + cellsWriter.write(" min_width = " + NumberFormatter.format(minWidth*1e6,3) + "u\n"); + + // finish + sizesWriter.write("}\n\n"); + strengthWriter.write("}\n\n"); + hsizesWriter.write("}\n"); + cellsWriter.write("}\n"); + } + } + + sizesWriter.close(); + strengthWriter.close(); + hsizesWriter.close(); + cellsWriter.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + + + /** + * This function writes out delay values for the half-operators using Jauto delay model. + * "hdelay.debug" gives delay values after sizing is finished. + *

    "hdelay_[n].debug" gives delay values after sizing iteration number "n". + *

    The delay information includes: maximum delay, minimum delay, maximum relative delay + * and maximum adjusted relative delay. + *

    Maximum Delay is defined as the maximum delay of the half-operator in all its instantiation environments. + *

    Minimum Delay is defined as the minimum delay of the half-opeartor in all its instantiation environments. + *

    Maximum Relative Delay is Maximum Delay divided by Tau. + *

    Maximum Adjusted Relative Delay is Maximum Relative Delay divided by cell delay bias and native delay bias. + **/ + public static void dumpDelayInformation(CastDesign design, String dirName, double tau, int iterationNumber) + { + File dir = new File(dirName, "iterations"); + + File hdelayDebugFile; + if (iterationNumber < 0) + hdelayDebugFile = new File(dirName, "hdelay.debug"); + else + hdelayDebugFile = + new File(dir, "hdelay_" + iterationNumber + ".debug"); + + try{ + if(!dir.exists()){ + dir.mkdirs(); + } + + BufferedWriter hdelayWriter = new BufferedWriter(new FileWriter(hdelayDebugFile)); + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + if(cta.getListHalfOperators().size() > 0){ + + final double cellDelayBias = cta.getDelay().getCellDelayBias(); + + hdelayWriter.write("CELL " + cta.typeName + " {\n"); + + for (Iterator itb = + sortHalfOperators(cta.getListHalfOperators()) + .iterator(); + itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + + String s, driveDir; + if (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + s = "N"; + driveDir = "-"; + } else { + s = "P"; + driveDir = "+"; + } + + hdelayWriter.write(" " + + hoa.outputNet.canonicalName.getCadenceString() + + driveDir); + + double min_delay = Double.POSITIVE_INFINITY; + double max_delay = Double.NEGATIVE_INFINITY; + for (Iterator itc = hoa.outputNet.getGlobalNets().iterator(); itc.hasNext(); ) { + GlobalNet gna = (GlobalNet)itc.next(); + + final double delay = JautoUtil.calculateDelay(hoa, gna); + + if(delay > max_delay){ + max_delay = delay; + } + + if(delay < min_delay){ + min_delay = delay; + } + + } + + final double defaultDelayBias = + cta.getDelay().getNativeDelay(hoa.driveDirection == HalfOperator.DriveDirection.PULL_UP) / 100.0; + hdelayWriter.write(" MAX_DELAY=" + NumberFormatter.format(max_delay*1e12, 3) + "ps" + + " MIN_DELAY=" + NumberFormatter.format(min_delay*1e12, 3) + "ps" + + " MAX_REL_DELAY=" + NumberFormatter.format(max_delay/tau, 3) + + " MAX_ADJ_REL_DELAY=" + NumberFormatter.format(max_delay/tau/cellDelayBias/defaultDelayBias, 3) + ); + + hdelayWriter.write("\n"); + + } + + hdelayWriter.write("}\n\n"); + } + } + + hdelayWriter.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + + /** + * This function writes out half-operator strength information on the flattened design. + * The half-operator names use global (instance-based), canonical net names plus direction. + * This function is written for PMCS project only. + **/ + static public void dumpFlatStrengthInformation(CastDesign design, String dirName) + { + final File flatStrengthDebugFile = + new File(dirName, "flat_strength.debug"); + + Map/*>>*/ mapa = + new HashMap/*>>*/(); + + JautoUtil.getLeafCellInstantiationPaths + (new ArrayList/**/(), + design.getTopLevelCell(), + mapa); + + try{ + BufferedWriter flatStrengthWriter = + new BufferedWriter(new FileWriter(flatStrengthDebugFile)); + + for (Iterator ita = mapa.entrySet().iterator(); ita.hasNext(); ) { + Map.Entry/*>*/ entry = + (Map.Entry) ita.next(); + CellType cta = (CellType) entry.getKey(); + List/*>*/ lsta = + (List/*>*/) entry.getValue(); + + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + List/**/ lstb = + (List/**/) itb.next(); + + for (Iterator itc = + sortHalfOperators(cta.getListHalfOperators()) + .iterator(); + itc.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itc.next(); + + List/**/ lstc = + new ArrayList/**/(); + + StringBuffer sb = new StringBuffer(JautoUtil.getFlatCanonicalName(hoa.outputNet, lstb, lstc)); + sb.append(" " + + (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+")); + sb.append(" " + NumberFormatter.format(hoa.getStrength(), 3)); + sb.append("\n"); + + flatStrengthWriter.write(sb.toString().replaceAll("\\/top\\.", "") + .replaceAll("\\/Xtop\\/", "")); + } + } + } + + flatStrengthWriter.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + + /** + * This function writes out half-operator strength information in design hierarchy. + * The half-operator names use local (cell-based), canonical net names plus direction. + * This function is written for PMCS project only. + **/ + public static void dumpHierStrengthInformation(CastDesign design, String dirName) + { + final File hierStrengthDebugFile = + new File(dirName, "hier_strength.debug"); + + try{ + BufferedWriter hierStrengthWriter = + new BufferedWriter(new FileWriter(hierStrengthDebugFile)); + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + if(cta.getListHalfOperators().size() > 0){ + String cellName = getGDSIICellName(cta.typeName); + + hierStrengthWriter.write("CELL " + cellName + "\n"); + + for (Iterator itb = + sortHalfOperators(cta.getListHalfOperators()) + .iterator(); + itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + String s, driveDir; + if (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + s = "N"; + driveDir = "-"; + } else { + s = "P"; + driveDir = "+"; + } + + + hierStrengthWriter.write("\tSTRENGTH " + + getGDSIINetName(cellName, + hoa.outputNet + .canonicalName + .getCadenceString()) + + " " + driveDir); + + hierStrengthWriter.write(" " + NumberFormatter.format(hoa.getStrength(), 3) + "\n"); + } + + hierStrengthWriter.write("\n"); + } + } + + hierStrengthWriter.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + } + + + static private String getGDSIICellName(String cellName) + { + return cellName; + } + + + static private String getGDSIINetName(String cellName, String netName) + { + return netName; + } + + private static String printCoordinate(final double x, final double y, + int precision) { + return "(" + NumberFormatter.format(x, precision) + ", " + + NumberFormatter.format(y, precision) + ")"; + } + + public static void dumpSinkSource(final CastDesign design, + final String dirName) throws IOException { + final File debugFile = new File(dirName, "sink_source.debug"); + final BufferedWriter bw = new BufferedWriter(new FileWriter(debugFile)); + for (Iterator cellIter = sortCellTypes(design.allCellTypes).iterator(); + cellIter.hasNext(); ) { + final CellType cell = (CellType) cellIter.next(); + if (cell == design.getTopLevelCell() || cell.getLevel() == 0) + continue; + bw.write("CELL " + cell.typeName + " {\n"); + for (Iterator netIter = cell.getAllNets().iterator(); + netIter.hasNext(); ) { + final CellNet net = (CellNet) netIter.next(); + if (net.isPortNet()) continue; + + bw.write(" NET " + net.canonicalName + " {\n"); + final GlobalNet gnet = (GlobalNet) net.getGlobalNets().get(0); + final Set seen = new HashSet(); + for (Iterator sinkIter = gnet.getListSinks().iterator(); + sinkIter.hasNext(); ) { + final NetSink sink = (NetSink) sinkIter.next(); + if (sink.type == NetType.HALF_OPERATOR_TRANSISTOR && + seen.add(sink.getInstanceName())) { + bw.write(" SINK " + sink.getInstanceName() + "/" + + sink.sink.subType.typeName + " " + + printCoordinate(sink.getCoordinateX() * 1e6, + sink.getCoordinateY() * 1e6, + 2) + + "\n"); + } else if (sink.type == NetType.CAPACITIVE_LOAD) { + bw.write(" SINK " + + NumberFormatter.format( + sink.getLoadCapacitance()*1e15, 3) + + "fF\n"); + } + } + + seen.clear(); + for (Iterator sourceIter = gnet.getListSources().iterator(); + sourceIter.hasNext(); ) { + final NetSource source = (NetSource) sourceIter.next(); + if (source.type == NetType.HALF_OPERATOR_TRANSISTOR && + seen.add(source.getInstanceName())) { + bw.write(" SOURCE " + source.getInstanceName() + + "/" + source.source.subType.typeName + " " + + printCoordinate(source.getCoordinateX() * 1e6, + source.getCoordinateY() * 1e6, + 2) + + "\n"); + } + } + bw.write(" }\n"); + } + bw.write("}\n"); + } + bw.close(); + } + + /** summarize wiring information for one GlobalNet **/ + static private String wireSummary (GlobalNet gna) { + return " L=" + NumberFormatter.format(gna.getEstimatedWireLength()*1e6, 3) + "u" + + " W=" + NumberFormatter.format(gna.getWireWidth()*1e6, 3) + "u" + + " S=" + NumberFormatter.format(gna.getWireSpace()*1e6, 3) + "u" + + " C=" + NumberFormatter.format(gna.getWireCapacitance()*1e15, 3) + "f" + + " R=" + NumberFormatter.format(gna.getWireResistance(), 3) + + " SPAN=" + NumberFormatter.format(gna.getEstimatedWireSpan()*1e6, 3) + "u"; + } + + /** + * This function writes out information about interconnections in the design. + * The information includes wire length, width, space, capacitance, resistance. + *

    At first, the wire information is written out cell-by-cell. + * Within each cell, the wires are sorted according the their length. + * At the end, all wires in the design is written out sorted. + *

    "wires.debug" gives basic information about wires. + * "sp2.debug" gives additional information about geometry information of + * the sources and sinks on the wire. + **/ + static public void dumpWireInformation(CastDesign design, String dirName) + { + File wiresDebugFile = new File(dirName, "wires.debug"); + File sp2DebugFile = new File(dirName, "sp2.debug"); + + Collection/**/ allCellNets = + new MultiSet/**/(CellNetLengthSorter.getInstance()); + + try{ + BufferedWriter wiresWriter = new BufferedWriter(new FileWriter(wiresDebugFile)); + BufferedWriter sp2Writer = new BufferedWriter(new FileWriter(sp2DebugFile)); + + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + wiresWriter.write("CELL " + cta.typeName + " {\n"); + + Collection/**/ cellNets = + new MultiSet/**/(CellNetLengthSorter.getInstance()); + + for (Iterator itb = cta.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + + if(!cna.isPortNet()){ + assert cna.getGlobalNets().size() <= 1 + : "Internal CellNet have more than 1 global net.\n" + + "CellName: " + cta.typeName + "\n" + + "NetName:" + cna.canonicalName.getCadenceString(); + + cellNets.add(cna); + allCellNets.add(cna); + } + } + + + for (Iterator itb = cellNets.iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + GlobalNet gna = (GlobalNet) cna.getGlobalNets().get(0); + + wiresWriter.write(" " + + cna.canonicalName.getCadenceString() + + wireSummary(gna) + "\n"); + + } + + wiresWriter.write("}\n"); + } + + wiresWriter.write("\nCELL SORTED_ALL_NETS {\n"); + for (Iterator itb = allCellNets.iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + GlobalNet gna = (GlobalNet) cna.getGlobalNets().get(0); + + wiresWriter.write(" " + + cna.container.typeName + + "/" + cna.canonicalName.getCadenceString() + + wireSummary(gna) + "\n"); + + sp2Writer.write("NET " + + cna.container.typeName + + " " + cna.canonicalName.getCadenceString() + + wireSummary(gna) + "\n"); + + sp2Writer.write("Sources:\n"); + for (Iterator itc = gna.getListSources().iterator(); itc.hasNext(); ) { + NetSource nsra = (NetSource)itc.next(); + if(nsra.type == NetType.HALF_OPERATOR_TRANSISTOR){ + sp2Writer.write("(" + + NumberFormatter.format(nsra.coordinateX * 1.0E6, 2) + "u, " + + NumberFormatter.format(nsra.coordinateY * 1.0E6, 2) + "u)" + + "\n"); + } + } + + + sp2Writer.write("Sinks:\n"); + for (Iterator itc = gna.getListSinks().iterator(); itc.hasNext(); ) { + NetSink nska = (NetSink)itc.next(); + if(nska.type == NetType.HALF_OPERATOR_TRANSISTOR){ + sp2Writer.write("(" + + NumberFormatter.format(nska.coordinateX * 1.0E6, 2) + "u, " + + NumberFormatter.format(nska.coordinateY * 1.0E6, 2) + "u)" + + "\n"); + } + } + + sp2Writer.write("\n"); + + + } + // TODO: add wiresWriter.write("}\n"); + + wiresWriter.close(); + sp2Writer.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + static private void getRoutedWireInfo(CellType routed, + CellType cta, + HierName prefix, + Collection result, + Set routedCells) { + for (Iterator itb = cta.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + if(!cna.isPortNet()) result.add(new Triplet(routed, prefix, cna)); + } + for (Iterator cii = cta.getAllSubcellConnections().iterator(); + cii.hasNext(); ) { + ConnectionInfo ci = (ConnectionInfo) cii.next(); + if (!routedCells.contains(ci.child)) { + getRoutedWireInfo(routed, ci.child, + HierName.append(prefix, ci.nameInParent), + result, routedCells); + } + } + } + + static private Collection getRoutedCells(final CastDesign design, + final Collection result) { + final CellType top = design.getTopLevelCell(); + result.add(top); + for (Iterator cii = top.getAllSubcellConnections().iterator(); + cii.hasNext(); ) { + ConnectionInfo ci = (ConnectionInfo) cii.next(); + result.add(ci.child); + ci.child.walkOnce( + new CellTypeProcessor() { + public void processCellType(CellType c) { + if (CellUtils.isRouted(c.cast_cell)) { + result.add(c); + } + } + } + ); + } + return result; + } + + static public void dumpRoutedWireInformation(CastDesign design, + String dirName) + { + File wiresDebugFile = new File(dirName, "wires.routed.debug"); + + Comparator lengthSorter = new Comparator() { + final Comparator real = CellNetLengthSorter.getInstance(); + public int compare(Object a, Object b) { + final Triplet triple1 = (Triplet) a; + final Triplet triple2 = (Triplet) b; + final CellNet cn1 = (CellNet) triple1.getThird(); + final CellNet cn2 = (CellNet) triple2.getThird(); + final GlobalNet gn1 = (GlobalNet) cn1.getGlobalNets().get(0); + final GlobalNet gn2 = (GlobalNet) cn2.getGlobalNets().get(0); + // sort in descending order by wire length + int x = Double.compare(gn2.getEstimatedWireLength(), + gn1.getEstimatedWireLength()); + if (x != 0) return x; + + // sort by cell type + final CellType type1 = (CellType) triple1.getFirst(); + final CellType type2 = (CellType) triple2.getFirst(); + x = type1.typeName.compareTo(type2.typeName); + if (x != 0) return x; + + // sort by canonical name + final HierName prefix1 = (HierName) triple1.getSecond(); + final HierName fullName1 = + HierName.append(prefix1, cn1.canonicalName); + + final HierName prefix2 = (HierName) triple2.getSecond(); + final HierName fullName2 = + HierName.append(prefix2, cn2.canonicalName); + return fullName1.compareTo(fullName2); + } + }; + + Collection/**/ allCellNets = + new MultiSet/**/(lengthSorter); + + + try{ + BufferedWriter wiresWriter = new BufferedWriter(new FileWriter(wiresDebugFile)); + + final Set routedCells = (Set) getRoutedCells(design, + new TreeSet(CellType.getNameComparator())); + for (Iterator ita = routedCells.iterator(); ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + wiresWriter.write("CELL " + cta.typeName + " {\n"); + + Collection/**/ cellNets = + new MultiSet/**/(lengthSorter); + + getRoutedWireInfo(cta, cta, null, cellNets, routedCells); + allCellNets.addAll(cellNets); + + for (Iterator itb = cellNets.iterator(); itb.hasNext(); ) { + Triplet triple = (Triplet) itb.next(); + HierName prefix = (HierName)triple.getSecond(); + CellNet cna = (CellNet)triple.getThird(); + GlobalNet gna = (GlobalNet) cna.getGlobalNets().get(0); + + wiresWriter.write(" " + + (HierName.append(prefix, cna.canonicalName).getCadenceString()) + + wireSummary(gna) + "\n"); + + } + + wiresWriter.write("}\n"); + } + + wiresWriter.write("\nCELL SORTED_ALL_NETS {\n"); + for (Iterator itb = allCellNets.iterator(); itb.hasNext(); ) { + Triplet triple = (Triplet) itb.next(); + CellType routed = (CellType)triple.getFirst(); + HierName prefix = (HierName)triple.getSecond(); + CellNet cna = (CellNet)triple.getThird(); + GlobalNet gna = (GlobalNet) cna.getGlobalNets().get(0); + + wiresWriter.write(" " + + routed.typeName + + "/" + (HierName.append(prefix, cna.canonicalName).getCadenceString()) + + wireSummary(gna) + "\n"); + + } + // TODO: add wiresWriter.write("}\n"); + + wiresWriter.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + /** + * A comparator which could be used to sort CellNet in descending order + * based on wire length. + **/ + private final static class CellNetLengthSorter implements Comparator { + private static CellNetLengthSorter singleton = null; + private CellNetLengthSorter() { } + public static CellNetLengthSorter getInstance() { + if (singleton == null) { + singleton = new CellNetLengthSorter(); + } + return singleton; + } + public int compare(Object a, Object b) { + final CellNet cn1 = (CellNet) a; + final CellNet cn2 = (CellNet) b; + final GlobalNet gn1 = (GlobalNet) cn1.getGlobalNets().get(0); + final GlobalNet gn2 = (GlobalNet) cn2.getGlobalNets().get(0); + // sort in descending order by wire length + int x = Double.compare(gn2.getEstimatedWireLength(), + gn1.getEstimatedWireLength()); + if (x != 0) return x; + + // sort by cell type + x = cn1.container.typeName.compareTo(cn2.container.typeName); + if (x != 0) return x; + + // sort by canonical name + return cn1.canonicalName.compareTo(cn2.canonicalName); + } + } + + /** + * Inner class to sort strings in descending weight. Its + * redundant with all the other sortedInsert, StringSortOnKey + * stuff, but at least I understand it. -- Andrew Lines + **/ + private final static class WeightedString implements Comparable { + final String str; + final double weight; + WeightedString(String str, double weight) { + this.str = str; + this.weight = weight; + } + public int compareTo(Object B) { + WeightedString b = (WeightedString) B; + if (weight>b.weight) return -1; + else if (weightJpeak_up) ? Jpeak_dn : Jpeak_up; + + // compute relative electromigration violations + double Jav_via_err = Jav/Jav_via_limit; + double Jav_wire_err = Jav/Width/Jav_wire_limit; + double Jrms_wire_err = Jrms/Width/Jrms_wire_limit; + double Jpeak_wire_err = Jpeak/Width/Jpeak_wire_limit; + + // max up the worst violation + double worst = Jav_via_err; + if (Jav_wire_err>worst) worst = Jav_wire_err; + if (Jrms_wire_err>worst) worst = Jrms_wire_err; + if (Jpeak_wire_err>worst) worst = Jpeak_wire_err; + + // add violations to list of weighted strings + if (worst>cutoff) + return new WeightedString + (prefix + + " Jav_via_err=" + + NumberFormatter.format(Jav_via_err,2) + + " Jav_wire_err=" + + NumberFormatter.format(Jav_wire_err,2) + + " Jrms_wire_err=" + + NumberFormatter.format(Jrms_wire_err,2) + + " Jpeak_wire_err=" + + NumberFormatter.format(Jpeak_wire_err,2), + worst); + return null; + } + + /** Print EM violations for a cell from a MultiSet of WeightedString's. **/ + private static void printElectromigration(BufferedWriter bw, + String cellName, + MultiSet strs) + throws IOException { + if (strs.size()>0) { + bw.write("CELL " + cellName + " {\n"); + Iterator itc = strs.iterator(); + while (itc.hasNext()) { + WeightedString str = (WeightedString) itc.next(); + bw.write(" " + str.str + "\n"); + } + bw.write("}\n\n"); + } + } + + /** + * Report electromigration by local nets and by operators, if + * greater than cutoff * limit. + **/ + private static void + doElectromigrationReport(CastDesign design, + File emLocalNetsFile, + File emOperatorsFile, + double cutoff) throws IOException { + + // open localnetsName file for writing + BufferedWriter bw1 = + new BufferedWriter(new FileWriter(emLocalNetsFile)); + + // open operatorsName file for writing + BufferedWriter bw2 = + new BufferedWriter(new FileWriter(emOperatorsFile)); + + // recurse through all cells + for (Iterator ita = sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType) ita.next(); + MultiSet/**/ strs1 = + new MultiSet/**/(); + MultiSet/**/ strs2 = + new MultiSet/**/(); + + // recurse through all nets in this cell + for (Iterator itb = cta.getAllNets().iterator(); + itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + List/**/ lsta = cna.getGlobalNets(); + + // if its a local net, report on it + if (!cna.isPortNet()) { + GlobalNet gna = (GlobalNet) lsta.get(0); + WeightedString str = checkElectromigration + (cna.canonicalName.getCadenceString(), + gna.getLoadCapacitance(), + gna.getUpDelay(), + gna.getDownDelay(), + cutoff, + design.getTechnologyData()); + if (str!=null) strs1.add(str); + } + + // if its driven locally, report on its worst global net + if (!cna.connectedToSubcells() && + cna.getListSources().size()>0) { + WeightedString worst = null; + for (Iterator itc = lsta.iterator(); itc.hasNext(); ) { + GlobalNet gna = (GlobalNet) itc.next(); + WeightedString str = checkElectromigration + (cna.canonicalName.getCadenceString(), + gna.getLoadCapacitance(), + gna.getUpDelay(), + gna.getDownDelay(), + cutoff, + design.getTechnologyData()); + if ((str!=null) && + ((worst==null) || (str.compareTo(worst)<0))) + worst = str; + } + if (worst!=null) strs2.add(worst); + } + } + printElectromigration(bw1,cta.typeName,strs1); + printElectromigration(bw2,cta.typeName,strs2); + } + bw1.close(); + bw2.close(); + } + + /** + * Dump electromigration reports for all local nets and all + * operators. Reports the proportional violation of various + * electromigration limits, assuming worst case wiring (1 via and + * minimum width wires). Uses estimated_delay and cap. Added by + * Andrew Lines. + **/ + public static void dumpElectromigrationInformation(CastDesign design, + String dirName) { + try { + // report only potential errors above the limits + doElectromigrationReport(design, + new File(dirName, "electromigration_localnets.debug"), + new File(dirName, "electromigration_operators.debug"), + 1); + // report all em estimates for comparison purposes + doElectromigrationReport(design, + new File(dirName, "full_electromigration_localnets.debug"), + new File(dirName, "full_electromigration_operators.debug"), + 0); + } catch(IOException e) { + e.printStackTrace(System.err); + } + } + + /** + * DEPRECATED. dumpSizeInformation does this better! + * + * This function writes out information about cell statistics. + * The information includes total instance count of the cell, + * total transistor width, average transistor width, + * maximum transistor width, minimum transistor width + *

    "cells.debug" gives information after sizing is done + *

    "cells_[n].debug" gives information after sizing iteration number [n] + * + * An empty block of information is written for mid-level cells. + **/ + public static void dumpCellInformation(CastDesign design, String dirName, int iterationNumber) + { + File dir = new File(dirName, "iterations"); + + File cellsDebugFile; + if (iterationNumber < 0) + cellsDebugFile = new File(dirName, "cells.debug"); + else + cellsDebugFile = + new File(dir, "cells_" + iterationNumber + ".debug"); + + File sp1DebugFile = new File(dirName, "sp1.debug"); + + + try{ + if(!dir.exists()){ + dir.mkdirs(); + } + + BufferedWriter cellsWriter = new BufferedWriter(new FileWriter(cellsDebugFile)); + BufferedWriter sp1Writer = new BufferedWriter(new FileWriter(sp1DebugFile)); + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + cellsWriter.write("CELL " + cta.typeName + " {\n"); + + assert cta.getLevel() >= 0; + if (cta.getLevel() == 0) { + sp1Writer.write(cta.typeName); + + int numInstances = cta.getPhysicalInstanceCount(); + Set/**/ seenEdges = + new HashSet/**/(); + double totalWidth = 0.0; + int numTransistors = 0; + double maxWidth = Double.NEGATIVE_INFINITY; + double minWidth = Double.POSITIVE_INFINITY; + + for (Iterator itb = cta.getListHalfOperators().iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + + for (Iterator itc = hoa.transistors.iterator(); itc.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)itc.next(); + + if(!seenEdges.contains(nea)){ + seenEdges.add(nea); + + if(nea.width > maxWidth){ + maxWidth = nea.width; + } + + if(nea.width < minWidth){ + minWidth = nea.width; + } + + totalWidth += nea.width; + numTransistors++; + + } + } + } + + double averageWidth = totalWidth / numTransistors; + + cellsWriter.write(" instances = " + numInstances + "\n"); + cellsWriter.write(" all_width = " + NumberFormatter.format(totalWidth*1e6,3) + "u\n"); + cellsWriter.write(" avg_width = " + NumberFormatter.format(averageWidth*1e6,3) + "u\n"); + cellsWriter.write(" max_width = " + NumberFormatter.format(maxWidth*1e6,3) + "u\n"); + cellsWriter.write(" min_width = " + NumberFormatter.format(minWidth*1e6,3) + "u\n"); + + sp1Writer.write(" " + numInstances); + sp1Writer.write(" " + NumberFormatter.format(totalWidth*1e6,3)); + sp1Writer.write(" " + NumberFormatter.format(averageWidth*1e6,3)); + sp1Writer.write(" " + NumberFormatter.format(maxWidth*1e6,3)); + sp1Writer.write(" " + NumberFormatter.format(minWidth*1e6,3)); + sp1Writer.write("\n"); + } + + cellsWriter.write("}\n\n"); + } + + cellsWriter.close(); + sp1Writer.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + + } + + + /** + * The maximum number of times warnings and information about a single path + * will be emitted. A path may be emitted multiple times, because it is + * used in different scenarios. + **/ + private final static int WARNS_PER_PATH = 3; + + /** + * This function writes out information about sizing paths in the design. + * The information about paths is written out sorted by slack. + * Path information includes total path delay, slack (budget - delay), + * average transistor width over all the half-operators on the path, + * cells and half-operators on the path. + *

    "paths_all.debug" gives all the paths. + *

    "paths_fixed.debug" gives paths with all fixed-size half-operators, + * including the loading half-operator of the last half-operator on the path. + *

    "paths_sizable.debug" gives paths with at least one half-operator sizable. + *

    "paths_all_[n].debug", "paths_fixed_[n].debug" and "paths_sizable_[n].debug" + * give information about paths after sizing iteration number [n]. + **/ + public static void dumpPathInformation(CastDesign design, String dirName, double tau, int iterationNumber) + { + dumpPathInformation(design, dirName, tau, iterationNumber, false); + } + + public static void dumpPathInformation(CastDesign design, String dirName, double tau, int iterationNumber, boolean topOnly) + { + File allPathsDebugFile = null, fixedPathsDebugFile = null, sizablePathsDebugFile = null, + signOffPathsDebugFile = null, topPathsDebugFile = null; + + if(iterationNumber < 0){ + if (! topOnly) { + allPathsDebugFile = new File(dirName, "paths_all.debug"); + fixedPathsDebugFile = new File(dirName, "paths_fixed.debug"); + sizablePathsDebugFile = new File(dirName, "paths_sizable.debug"); + signOffPathsDebugFile = new File(dirName, "paths_signoff.debug"); + } + topPathsDebugFile = new File(dirName, "paths_top.debug"); + } + else{ + File iterationsDir = new File(dirName, "iterations"); + if (! topOnly) { + allPathsDebugFile = new File(iterationsDir, "paths_all_" + iterationNumber + ".debug"); + fixedPathsDebugFile = new File(iterationsDir, "paths_fixed_" + iterationNumber + ".debug"); + sizablePathsDebugFile = new File(iterationsDir, "paths_sizable_" + iterationNumber + ".debug"); + signOffPathsDebugFile = new File(iterationsDir, "paths_signoff_" + iterationNumber + ".debug"); + } + topPathsDebugFile = new File(iterationsDir, "paths_top_" + iterationNumber + ".debug"); + } + + JautoMessageCenter messageCenter = design.getMessageCenter(); + + MultiMap/**/ allPaths = + new MultiMap/**/(new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + MultiMap/**/ fixedPaths = + new MultiMap/**/(new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + MultiMap/**/ sizablePaths = + new MultiMap/**/(new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + MultiMap/**/ signOffPaths = + new MultiMap/**/(new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + MultiMap/**/ topPaths = + new MultiMap/**/(new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + + for (Iterator itb = getPathIterator(cta); itb.hasNext(); ) { + AbstractPath cpa = (AbstractPath) itb.next(); + final MultiMap/**/ slacks = + new MultiMap/**/( + new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + + for (int i = 0; i < cpa.slack.length; ++i) { + double slack = cpa.getSlack(i); + slacks.put(slack, i); + if (slack != cpa.getRealSlack(i)) { + String pathInfo = "// container=" + cta.typeName + + "\n" + cpa.printPath(i); + signOffPaths.put(cpa.getRealSlack(i), pathInfo); + } + } + + int count = 0; + for (Iterator j = slacks.keySet().iterator(); j.hasNext(); ) { + final Double slackD = (Double) j.next(); + final Collection entry = slacks.get(slackD); + for (Iterator k = entry.iterator(); + k.hasNext() && (count < WARNS_PER_PATH || topOnly); ++count) { + final int i = ((Integer) k.next()).intValue(); + + double slack = cpa.getSlack(i); + if(slack <= -tau){ + if(iterationNumber != 1){ // do not warn for first iteration for sizable paths + if(!cpa.isFixedSize(i)){ + String msa = "WARNING"; + String msb = "Large negative slack: " + NumberFormatter.format(slack*1e12,3) + "ps\n"; + String msc = "Please refer to file \"paths_sizable.debug\" for details.\n"; + + messageCenter.createMessage(1, 4, msa, msb, msc); + } + } + else{ // large negative slack warning for completely fixed paths, for once only + if(cpa.isFixedSize(i)){ + String msa = "WARNING"; + String msb = "Large negative slack: " + NumberFormatter.format(slack*1e12,3) + "ps\n"; + String msc = "Please refer to file \"paths_fixed.debug\" for details.\n"; + + messageCenter.createMessage(1, 4, msa, msb, msc); + } + } + } + + String pathInfo = "// container=" + cta.typeName + "\n" + cpa.printPath(i); + if ( ! topOnly ) { + allPaths.put(slackD, pathInfo); + + if(cpa.isFixedSize(i)){ + fixedPaths.put(slackD, pathInfo); + } + else{ + sizablePaths.put(slackD, pathInfo); + } + } + if (pathInfo.indexOf("endnet=/top.") >= 0) { + topPaths.put(slackD, pathInfo); + } + } + } + } + } + + try{ + File dir = new File(dirName, "iterations"); + if(!dir.exists()){ + dir.mkdirs(); + } + + if (! topOnly) { + dumpPathInformation(allPaths, allPathsDebugFile); + dumpPathInformation(fixedPaths, fixedPathsDebugFile); + dumpPathInformation(sizablePaths, sizablePathsDebugFile); + dumpPathInformation(signOffPaths, signOffPathsDebugFile); + } + dumpPathInformation(topPaths, topPathsDebugFile); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + private static void dumpPathInformation + (final /*@ non_null @*/ MultiMap/**/ paths, + final /*@ non_null @*/ File file) + throws IOException { + + final BufferedWriter bw = new BufferedWriter(new FileWriter(file)); + + for (Iterator/**/ i = paths.values().iterator(); i.hasNext(); ) { + final String s = (String) i.next(); + bw.write(s); + bw.write("\n"); + } + + bw.close(); + } + + private static void processDelaySignOff(final CellType cell, + final Map paths) { + for (Iterator pathIterator = getFixedPathIterator(cell); + pathIterator.hasNext(); ) { + final AbstractPath path = (AbstractPath) pathIterator.next(); + final StringBuffer buf = new StringBuffer(); + path.getPathString(buf); + final String delayPart = (String) paths.get(buf.toString()); + if (delayPart != null) { + final Map delays = new HashMap(); + final String parts[] = StringUtil.split(delayPart, ' '); + for (int i = 0; i < parts.length; i = i + 3) { + delays.put(new Pair(parts[i], parts[i + 1]), parts[i + 2]); + } + final List gns = path.getEndNet().getGlobalNets(); + final double[] result; + if (path.signoff == null) { + result = new double[gns.size()]; + for (int i = 0; i < result.length; ++i) + result[i] = Double.NaN; + path.signoff = result; + } else { + result = path.signoff; + } + for (int i = 0; i < gns.size(); ++i) { + final GlobalNet gn = (GlobalNet) gns.get(i); + if (isFixed(gn)) { + final CellNet cn = gn.getTopCellNet(); + final Pair key = + new Pair(cn.container.typeName, + cn.canonicalName.getAsString('.')); + final String delay = (String) + delays.get( + new Pair(cn.container.typeName, + cn.canonicalName.getAsString('.'))); + if (delay != null) { + final double d = Double.parseDouble(delay); + if (Double.isNaN(result[i])) { + result[i] = d; + } else { + result[i] = Math.min(result[i], d); + } + } + } + } + } + } + } + + public static void readDelaySignOff(CastDesign design, String fileName) + throws IOException { + final BufferedReader br = new BufferedReader(new FileReader(fileName)); + HashMap paths = null; + String line; + CellType type = null; + while ((line = br.readLine()) != null) { + if (line.startsWith("CELL")) { + if (type != null) + processDelaySignOff(type, paths); + type = design.getCell(line.substring(5)); + paths = new HashMap(); + } else { + if (type != null) { + String[] parts = StringUtil.split(line, ':'); + paths.put(parts[1], parts[0]); + } + } + } + if (type != null) processDelaySignOff(type, paths); + br.close(); + } + + private static boolean isFixed(final GlobalNet gn) { + for (Iterator i = gn.getListSources().iterator(); i.hasNext(); ) { + final NetSource nsrc = (NetSource) i.next(); + if (nsrc.getType() == NetType.HALF_OPERATOR_TRANSISTOR && + !nsrc.getSource().subType.isFixedSize()) return false; + } + for (Iterator i = gn.getListSinks().iterator(); i.hasNext(); ) { + final NetSink nsnk = (NetSink) i.next(); + if (nsnk.getType() == NetType.HALF_OPERATOR_TRANSISTOR && + !nsnk.getSink().subType.isFixedSize()) return false; + } + return CellUtils.isFixed(gn.getTopCellNet().container.cast_cell); + } + + private static boolean getDelayString(final AbstractPath path, + final StringBuffer buf) { + final Map delays = new TreeMap(CellNet.getComparator()) { + public Object put(Object key, Object value) { + final Object old = super.put(key, value); + if (old != null) { + throw new RuntimeException("Multiple values for key " + + key + " " + value + " (" + old + ")"); + } + return old; + } + }; + + int count = 0; + for (Iterator i = path.getEndNet().getGlobalNets().iterator(); + i.hasNext(); ++count) { + final GlobalNet gn = (GlobalNet) i.next(); + if (isFixed(gn)) + delays.put(gn.getTopCellNet(), new Double(path.delay[count])); + } + + boolean needSpace = false; + for (Iterator i = delays.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final CellNet cn = (CellNet) entry.getKey(); + final Double delay = (Double) entry.getValue(); + if (needSpace) buf.append(' '); + buf.append(cn.container.typeName); + buf.append(' '); + buf.append(cn.canonicalName.getCadenceString()); + buf.append(' '); + buf.append(delay); + needSpace = true; + } + return needSpace; + } + + public static void dumpDelaySignOff(CastDesign design, String dirName) + throws IOException { + final File signoffFile = + new File(dirName, "delay_signoff.debug"); + final PrintWriter pw = + new PrintWriter(new BufferedWriter(new FileWriter(signoffFile))); + + for (Iterator i = sortCellTypes(design.allCellTypes).iterator(); + i.hasNext(); ) { + final CellType cell = (CellType) i.next(); + boolean header = true; + for (Iterator pathIterator = getFixedPathIterator(cell); + pathIterator.hasNext(); ) { + final AbstractPath path = (AbstractPath) pathIterator.next(); + final StringBuffer buf = new StringBuffer(); + if (getDelayString(path, buf)) { + if (header) { + pw.println("CELL " + cell.typeName); + header = false; + } + buf.append(':'); + path.getPathString(buf); + pw.println(buf.toString()); + } + } + } + pw.close(); + } + + private static void findHierarchy(final CellType ct, + final HierName[] parts, + int index, + final Collection instList, + final Collection cellList) { + HierName attempt = null; + while (index < parts.length) { + attempt = HierName.append(attempt, parts[index]); + index++; + final ConnectionInfo ci = ct.getSubcellNamed(attempt); + if (ci != null) { + instList.add(ci.nameInParent); + cellList.add(ci.child); + if (index < parts.length) + findHierarchy(ci.child, parts, index, instList, + cellList); + return; + } + } + throw new RuntimeException("Cannot find instance: " + + join(parts, '.') + " index = " + index + + " cell = " + ct.typeName); + } + + /** + * Given instance name inst that is relative to the cell + * top, return the path in type space and instance space in + * instList and cellList, respectively. This + * is complicated by inlining, because not every dot is a hierarchical + * delimiter. + **/ + private static void findHierarchy(final CellType top, + final HierName inst, + final Collection instList, + final Collection cellList) { + if (inst == null) return; + final String s = inst.getAsString('.'); + final String[] ss = StringUtil.split(s, '.'); + final HierName[] hs = new HierName[ss.length]; + for (int i = 0; i < ss.length; ++i) { + hs[i] = HierName.makeHierName(ss[i]); + } + findHierarchy(top, hs, 0, instList, cellList); + } + + private static String join(final HierName[] names, final char c) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < names.length; ++i) { + if (i != 0) sb.append(c); + sb.append(names[i].getAsString('.')); + } + return sb.toString(); + } + + private static class ViolationInstance implements Comparable { + private final CellType cell; + private final HierName inst; + private boolean loadOnly; + public ViolationInstance(final CellType cell, final HierName inst, + final boolean loadOnly) { + this.cell = cell; + this.inst = inst; + this.loadOnly = loadOnly; + } + public void updateUsage(final ViolationInstance vi) { + loadOnly = loadOnly && vi.loadOnly; + } + public boolean equals(final Object o) { + if (o instanceof ViolationInstance) + return equals((ViolationInstance) o); + else + return false; + } + public boolean equals(final ViolationInstance vi) { + return cell.typeName.equals(vi.cell.typeName) && + ObjectUtils.equals(inst, vi.inst); + } + public int hashCode() { + return ObjectUtils.hashCode(cell.typeName) + + ObjectUtils.hashCode(inst); + } + public int compareTo(final Object o) { + final ViolationInstance vi = (ViolationInstance) o; + int x = cell.typeName.compareTo(vi.cell.typeName); + if (x != 0) return x; + return ObjectUtils.compare(inst, vi.inst); + } + private int getGlobalNetCount() { + int count = Integer.MIN_VALUE; + for (Iterator i = cell.getAllNets().iterator(); i.hasNext(); ) { + final CellNet net = (CellNet) i.next(); + if (net.isPortNet()) { + count = Math.max(count, net.getGlobalNets().size()); + } + } + return count; + } + public String toString(final CellType top, final boolean isUnnamedTop) { + final StringBuffer buf = new StringBuffer(); + final List instList = new ArrayList(); + final List cellList = new ArrayList(); + buf.append(cell.isFixedSize() ? "FIXED_" : "SIZABLE_"); + buf.append(getGlobalNetCount()); + if (loadOnly) buf.append('*'); + buf.append(' '); + findHierarchy(top, inst, instList, cellList); + if (isUnnamedTop) { + // treat ports of the top level cell as local nodes of the top + // level; remove the extra level of hierarchy + instList.remove(0); + cellList.remove(0); + } + for (Iterator i = cellList.iterator(); i.hasNext(); ) { + final CellType ct = (CellType) i.next(); + buf.append(ct.typeName); + if (i.hasNext()) buf.append('/'); + } + buf.append(' '); + buf.append( + join((HierName[]) instList.toArray(new HierName[0]), '/')); + + return buf.toString(); + } + public String toString() { + return "cell: " + cell.typeName + " inst: " + inst; + } + public CellType getCell() { + return cell; + } + public HierName getInstance() { + return inst; + } + } + + private static Object lastElement(final List l) { + if (l == null || l.isEmpty()) return null; + else return l.get(l.size() - 1); + } + + private static Triplet findNextConnection(final CellType cell, + final HierName inst) { + final int components = inst.getNumComponents(); + HierName head = null, tail = inst; + ConnectionInfo ci = null; + for (int i = 1; i < components; ++i) { + head = HierName.append(head, tail.head()); + tail = tail.tail(); + if ((ci = cell.getSubcellNamed(head)) != null) break; + } + if (ci == null) { + head = inst; + tail = null; + ci = cell.getSubcellNamed(head); + } + return new Triplet(head, tail, ci); + } + + private static HierName computePartialInstance(CellType ancestor, + final CellType descendent, + HierName inst) { + HierName result = null; + while (true) { + final Triplet t = findNextConnection(ancestor, inst); + final ConnectionInfo ci = (ConnectionInfo) t.getThird(); + if (ci == null) { + result = null; + break; + } + final HierName head = (HierName) t.getFirst(); + inst = (HierName) t.getSecond(); + result = HierName.append(result, head); + ancestor = ci.child; + if (ci.child == descendent) break; + } + return result; + } + + private static HierName hierAppend(final HierName a, final HierName b) { + if (a == null) return b; + if (b == null) return a; + return HierName.append(a, b); + } + + private static void addViolation(final Map violations, final CellType cell, + final HierName inst, final boolean load) { + final ViolationInstance candidate = + new ViolationInstance(cell, inst, load); + final ViolationInstance prev = + (ViolationInstance) violations.get(candidate); + if (prev != null) { + candidate.updateUsage(prev); + } + violations.put(candidate, candidate); + } + + private static void processViolation(final Map violationMap, + final CellType pathContainer, + final AbstractPath path, + final float slackRatioLimit) { + final CellNet endNet = path.getEndNet(); + final List globalNets = endNet.getGlobalNets(); + assert globalNets.size() == path.slack.length; + assert path.slack.length == path.delay.length; + + Map pathInstance = null; + HalfOperator lastHalfOp = null; + SizingPath lastSizingPath = null; + for (int i = 0; i < path.slack.length; ++i) { + // calculate ratio of delay to budget + final float slackRatio = (float) + (path.delay[i] / (path.slack[i] + path.delay[i])); + if (slackRatio <= slackRatioLimit) continue; + + if (pathInstance == null) { + // instance names are relative to the container of the + // abstract path + pathInstance = new TreeMap(); + if (path instanceof SizingPath) { + addViolation(pathInstance, path.container, null, false); + lastHalfOp = (HalfOperator) + lastElement(((SizingPath) path).getPath()); + lastSizingPath = (SizingPath) path; + } else { + final CatPath catPath = (CatPath) path; + for (Iterator j = catPath.getCatPath().iterator(); + j.hasNext(); ) { + final SizingPath sp = (SizingPath) j.next(); + addViolation(pathInstance, sp.container, + sp.getInstanceName(), false); + if (!j.hasNext()) { + lastSizingPath = sp; + lastHalfOp = + (HalfOperator) lastElement(sp.getPath()); + } + } + } + } + + final GlobalNet gn = (GlobalNet) globalNets.get(i); + final CellType gnContainer = gn.getTopCellNet().container; + HierName pathPrefix = null; + HierName gnPrefix = null; + + // There are 3 possibilities: + // 1. The container of the global net instantiates the + // container of the path. + // 2. The container of the path instantiates the container of + // the global net. + // 3. The container of the global net is the same as the + // container of the path. + // Case 3 is easy, since nothing needs to be done. In cases 1 + // and 2, we need to calculate the instance path from the + // parent container to the child container, and append that to + // instances relative to the child container. + final CellType topMost; + if (gnContainer == pathContainer) { + topMost = gnContainer; + } else { + if (gnContainer.getLevel() > pathContainer.getLevel()) { + topMost = gnContainer; + HierName pathInst = null; + for (Iterator j = gn.getListSources().iterator(); + j.hasNext(); ) { + final NetSource src = (NetSource) j.next(); + if (src.type == NetType.HALF_OPERATOR_TRANSISTOR && + src.source == lastHalfOp) { + // XXX: what if the same global net is driving by + // multiple instances of the same cell? + pathInst = src.getInstanceName(); + break; + } + } + pathPrefix = computePartialInstance(gnContainer, + pathContainer, + pathInst); + } else { + final HierName pathInst = lastSizingPath.getInstanceName(); + topMost = pathContainer; + gnPrefix = computePartialInstance(pathContainer, + gnContainer, + pathInst); + } + } + + final Map instanceSet = new TreeMap(); + if (pathPrefix == null) { + instanceSet.putAll(pathInstance); + } else { + for (Iterator j = pathInstance.keySet().iterator(); + j.hasNext(); ) { + final ViolationInstance vio = + (ViolationInstance) j.next(); + addViolation(instanceSet, vio.getCell(), + hierAppend(pathPrefix, + vio.getInstance()), + false); + } + } + final Collection sinks = (Collection) gn.getListSinks(); + for (Iterator j = sinks.iterator(); j.hasNext(); ) { + // instance names are relative to the container of the + // global net + final NetSink sink = (NetSink) j.next(); + if (sink.type == NetType.HALF_OPERATOR_TRANSISTOR) { + addViolation(instanceSet, sink.sink.subType, + hierAppend(gnPrefix, + sink.getInstanceName()), + true); + } + } + + final Pair key = new Pair(instanceSet, topMost); + final Float oldRatio = (Float) violationMap.get(key); + if (oldRatio == null || oldRatio.floatValue() < slackRatio) { + violationMap.put(key, new Float(slackRatio)); + } + } + } + + private static Iterator getPathIterator(final CellType cta) { + final Iterator pathIterator; + if (cta.getLevel() > 0){ + pathIterator = cta.getReducedCatPaths().iterator(); + } else { + pathIterator = + new FilteringIterator(cta.getSizingPaths().iterator(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return !((SizingPath) o).isFragment(); + } + } + ); + } + return pathIterator; + } + + private static Iterator getFixedPathIterator(final CellType cta) { + return + new FilteringIterator(getPathIterator(cta), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return ((AbstractPath) o).isComponentsFixed(); + } + } + ); + } + + public static void dumpViolations(CastDesign design, String dirName, + float slackRatioLimit) + throws IOException { + final File out = new File(dirName, "violations.debug"); + final BufferedWriter bw = new BufferedWriter(new FileWriter(out)); + final Map violationMap = new HashMap(); + for (Iterator ita = sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + + for (Iterator pathIterator = getPathIterator(cta); + pathIterator.hasNext(); ) { + final AbstractPath path = (AbstractPath) pathIterator.next(); + processViolation(violationMap, cta, path, slackRatioLimit); + } + } + for (Iterator i = violationMap.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Pair key = (Pair) entry.getKey(); + final Map violations = (Map) key.getFirst(); + final CellType top = (CellType) key.getSecond(); + final boolean isUnnamedTop = top == design.getTopLevelCell(); + final String topName; + if (isUnnamedTop) { + final Collection cis = top.getAllSubcellConnections(); + assert cis.size() == 1; + topName = + ((ConnectionInfo) cis.iterator().next()).child.typeName; + } else { + topName = top.typeName; + } + final Float ratio = (Float) entry.getValue(); + bw.write("VIOLATION " + topName + " " + ratio + " {\n"); + for (Iterator j = violations.keySet().iterator(); j.hasNext(); ) { + final ViolationInstance vio = (ViolationInstance) j.next(); + bw.write(" " + vio.toString(top, isUnnamedTop) + "\n"); + } + bw.write("}\n"); + } + bw.close(); + } + + + /** + * This function writes out information about overall circuit statistics. + * The information is contained in the "summary" string + **/ + public static void generateSizingSummary(String summary, String dirName, int iterationNumber) + { + File dir = new File(dirName, "iterations"); + + File sweepDebugFile; + if(iterationNumber < 0){ // final report + sweepDebugFile = new File(dirName, "sweep.debug"); + } + else{ // intermediate report + sweepDebugFile = + new File(dir, "sweep_" + iterationNumber + ".debug"); + } + + try{ + if(!dir.exists()){ + dir.mkdirs(); + } + + BufferedWriter bw = new BufferedWriter(new FileWriter(sweepDebugFile)); + + bw.write(summary); + + bw.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + + /** + * This function writes out information about paths on a flattened design. + * The purpose of this debug file is orginally designed for doing static + * timing analysis using PathMill. + **/ + static public void dumpFlatPathInformation(CastDesign design, String dirName) + { + File flatPathsDebugFile = new File(dirName, "flat_paths.debug"); + + + Map/*>>*/ mapa = + new HashMap/*>>*/(); + + JautoUtil.getLeafCellInstantiationPaths + (new ArrayList/**/(), + design.getTopLevelCell(), + mapa); + + try{ + BufferedWriter bw = new BufferedWriter(new FileWriter(flatPathsDebugFile)); + + for (Iterator ita = mapa.entrySet().iterator(); ita.hasNext(); ) { + Map.Entry entry = (Map.Entry) ita.next(); + CellType cta = (CellType) entry.getKey(); + List/*>*/ lsta = + (List/*>*/) entry.getValue(); + + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + List/**/ lstb = + (List/**/) itb.next(); + + for (Iterator itc = cta.getSizingPaths().iterator(); itc.hasNext(); ) { + SizingPath spa = (SizingPath)itc.next(); + + String stra = ""; + double delay = 0.0; + for (Iterator itd = spa.getPath().iterator(); itd.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itd.next(); + + // System.err.println("Calling JautoUtil.getFlatCanonicalName..."); + + List/**/ lstc = + new ArrayList/**/(); + stra += JautoUtil.getFlatCanonicalName(hoa.outputNet, lstb, lstc); + stra += " (" + + (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + "f" : "r") + ") "; + + CellNet cnb = (CellNet)lstc.get(0); + + assert cnb.getGlobalNets().size() <= 1 + : "Internal CellNet have more than 1 global net.\n" + + "CellName: " + cta.typeName + "\n" + + "NetName:" + cnb.canonicalName.getCadenceString(); + + GlobalNet gna = (GlobalNet) cnb.getGlobalNets().get(0); + + delay += JautoUtil.calculateDelay(hoa, gna); + } + // stra += "\n"; + + HalfOperator hoa = (HalfOperator)spa.getPath().get(0); + String strc = " (" + + (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + "r" : "f") + ") "; + + for (Iterator itd = spa.getStartNets().iterator(); itd.hasNext(); ) { + CellNet cna = (CellNet)itd.next(); + + List/**/ lstc = + new ArrayList/**/(); + String strb = JautoUtil.getFlatCanonicalName(cna, lstb, lstc); + strb += strc + stra; + + String strd = strb.replaceAll("\\/top\\.", ""); + strb = strd.replaceAll("\\/Xtop\\/", ""); + bw.write("search_path match=complete " + strb); + + bw.write(" (delay = " + NumberFormatter.format(delay, 3) + ")\n"); + } + } + } + } + + bw.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + } + + /** + * Check paths for large relative delay violations. Gives warnings. + **/ + static public void checkPaths(CastDesign design, TransistorSizingTool tool) { + double tau = tool.getOptionUnitDelay(); + JautoMessageCenter messageCenter = tool.getMessageCenter(); + + // get the "worstTau" from worst relative constraint violation + double worstTau = 0; + for (Iterator ita = sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType) ita.next(); + double cellWorst = 0; + if (cta.getLevel() > 0) { // mid cell + for (Iterator itb = cta.getReducedCatPaths().iterator(); + itb.hasNext(); ) { + CatPath cpa = (CatPath) itb.next(); + for (int i = 0; i < cpa.delay.length; ++i) { + double t = tau * cpa.delay[i] / cpa.getBudget(i); + if (t>cellWorst) cellWorst = t; + } + } + } else { // leaf cell + for (Iterator itb = cta.getSizingPaths().iterator(); + itb.hasNext(); ) { + SizingPath spa = (SizingPath) itb.next(); + if (!spa.isFragment()) { + for (int i = 0; i < spa.delay.length; ++i) { + double t = tau * spa.delay[i] / spa.getBudget(i); + if (t>cellWorst) cellWorst = t; + } + } + } + } + if (cellWorst > worstTau) worstTau = cellWorst; + if (cellWorst / tau > 1.01) { + if (! quiet ) + System.out.println("Cell Tau=" + + NumberFormatter.format(cellWorst*1e12,3) + + "ps for " + cta.typeName); + } + } + if (! quiet) + System.err.println("Target Tau=" + + NumberFormatter.format(tau*1e12,3) + + " Worst Tau=" + + NumberFormatter.format(worstTau*1e12,3) + "ps"); + } + + /** + * This function generates the sizing summay information (at the design level) + * string for function "generateSizingSummary". + * The sizing summary information includes total transistor counts, + * total transistor width, average transistor width, maximum transistor width, + * minimum transistor width, number of nodes (nets), + * average transistor width per node, average wire length per node, + * average gate capacitance per node, average wire capacitance per node, + * average total capacitance per node. + *

    Finally it gives information about E*Tau^2. + *

    t -> Tau, C -> total cap, Ctt -> C*t*t, + * W -> ave tran width, GateC -> average gate cap % per node. + **/ + static public String reportSizingResults(TransistorSizingTool tool) + { + String summary = ""; + + CastDesign design = tool.getSynthesizedDesign(); + double tau = tool.getOptionUnitDelay(); + double maxWidthN = tool.getOptionMaxWidthN(); + double maxWidthP = tool.getOptionMaxWidthP(); + TechnologyData td = design.getTechnologyData(); + JautoMessageCenter messageCenter = tool.getMessageCenter(); + + // Report results for total transistor width + Map/**/ transistorInstanceCountMap = + new HashMap/**/(); + double totalWidth = 0.0; + int numTransistors = 0; + + double maxWidth = Double.NEGATIVE_INFINITY; + double minWidth = Double.POSITIVE_INFINITY; + + for (Iterator ita = sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + int instanceCount = sta.getPhysicalInstanceCount(); + Set/**/ seenEdges = + new HashSet/**/(); + double totalWidthForCell = 0.0; + + for (Iterator itb = + sortHalfOperators(sta.getListHalfOperators()) + .iterator(); + itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + + double maxAllowedWidth; + if (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + maxAllowedWidth = maxWidthN; + } + else{ + maxAllowedWidth = maxWidthP; + } + + if (hoa.getCurrentSize() >= maxAllowedWidth) { + String msa = "WARNING"; + String msb = "Variable value at maximum.\n"; + String msc = "CellName: " + sta.typeName + "\n" + + "HalfOperatorName: " + hoa.outputNet.canonicalName.getCadenceString() + + (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+") + "\n"; + + if (! quiet) + System.out.println(msa + ": " + msb + msc); + + messageCenter.createMessage(1, 5, msa, msb, msc); + } + else{ + // FIXME: hardcoded constant for warning threshold + if (hoa.getCurrentSize() >= 0.95 * maxAllowedWidth) { + String msa = "WARNING"; + String msb = "Variable value within 5% of maximum.\n"; + String msc = "CellName: " + sta.typeName + "\n" + + "HalfOperatorName: " + hoa.outputNet.canonicalName.getCadenceString() + + (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+") + "\n"; + + if (! quiet) + System.out.println(msa + ": " + msb + msc); + + messageCenter.createMessage(1, 6, msa, msb, msc); + } + } + + for (Iterator itc = hoa.transistors.iterator(); itc.hasNext(); ) { + NetGraph.NetEdge nea = (NetGraph.NetEdge)itc.next(); + if (!seenEdges.contains(nea)) { + + // FIXME: this is horrible + if((nea.width % 0.314159265E-6) == 0.0){ + String msa = "ERROR"; + String msb = "This transistor has been missed by the sizing algorithm.\n"; + String msc = "Cell: " + sta.typeName + + ", gate: " + nea.gate.getName().getCadenceString() + + ", drain: " + nea.drain.getName().getCadenceString() + + ", source: " + nea.source.getName().getCadenceString() + + "\n"; + + messageCenter.createMessage(0, 2, msa, msb, msc); + } + + if(nea.width > maxWidth){ + maxWidth = nea.width; + } + + if(nea.width < minWidth){ + minWidth = nea.width; + } + + totalWidthForCell += nea.width; + + seenEdges.add(nea); + numTransistors += instanceCount; + + transistorInstanceCountMap.put(nea, new Integer(instanceCount)); + } + } + } + + totalWidth += totalWidthForCell * instanceCount; + } + + double aveWidth = totalWidth / numTransistors; + summary += "\n"; + summary += "************************** SUMMARY *************************" + "\n"; + summary += "Total transistor count: " + numTransistors + "\n"; + summary += "Total transistor width: " + totalWidth + "\n"; + summary += "Average transistor width: " + aveWidth + "\n"; + summary += "Maximum transistor width: " + maxWidth + "\n"; + summary += "Minimum transistor width: " + minWidth + "\n"; + + totalWidth = 0.0; + double totalWireLength = 0.0; + double totalWireCap = 0.0; + double totalGateCap = 0.0; + int numNodes = 0; + + Map/**/ sinkTransistorInstanceCountMap = + new HashMap/**/(); + + for (Iterator ita = sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + int instanceCount = sta.getPhysicalInstanceCount(); + + for (Iterator itb = sta.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + if(!cna.isPortNet()){ + if(cna.globalNets != null){ + assert cna.getGlobalNets().size() <= 1 + : "Internal CellNet have more than 1 global net.\n" + + "CellName: " + sta.typeName + "\n" + + "NetName:" + cna.canonicalName.getCadenceString(); + for (Iterator itc = cna.getGlobalNets().iterator(); itc.hasNext(); ) { + GlobalNet gna = (GlobalNet)itc.next(); + + numNodes += instanceCount; + totalWireLength += gna.getEstimatedWireLength() * instanceCount; + totalWireCap += gna.getWireCapacitance() * instanceCount; + + double totalNSinkWidth = 0.0; + double totalPSinkWidth = 0.0; + double totalNSinkCap = 0.0; + double totalPSinkCap = 0.0; + for (Iterator itd = gna.getListSinks().iterator(); itd.hasNext(); ) { + NetSink nska = (NetSink)itd.next(); + if(nska.type == NetType.HALF_OPERATOR_TRANSISTOR){ + NetGraph.NetEdge nea = nska.transistor; + double width = nea.width / nea.shareCount; + if (nea.type == DeviceTypes.N_TYPE) { + totalNSinkWidth += width; + totalNSinkCap += width * nea.length * td.getUnitNmosGateCapacitance(nea.getTransistorType()); + } else { + totalPSinkWidth += width; + totalPSinkCap += width * nea.length * td.getUnitPmosGateCapacitance(nea.getTransistorType()); + } + + Integer itea = + (Integer) sinkTransistorInstanceCountMap.get(nea); + if (itea != null) { + Integer iteb = new Integer(itea.intValue() + instanceCount); + sinkTransistorInstanceCountMap.put(nea, iteb); + + int k = ((Integer) transistorInstanceCountMap.get(nea)).intValue(); + + assert iteb.intValue() <= nea.shareCount * k + : "Transistor over-counting.\n" + + iteb.intValue() + + " " + (nea.shareCount * k) + + " " + nea.shareCount + + " " + nska.sink.outputNet.canonicalName.getCadenceString() + + " " + cna.listSinks.size() + + " " + nska.sink.subType.typeName + "\n" + + "Cell name: " + sta.typeName + "\n" + + "Transistor gate name: " + nea.gate.name.getCadenceString(); + } + else{ + sinkTransistorInstanceCountMap.put(nea, new Integer(0)); + } + } + + assert nska.type != NetType.CELL + : "Globalnet should only contain type-0 NetSource/NetSink at this stage.\n" + + "CellName: " + sta.typeName + "\n" + + "NetName: " + cna.canonicalName.getCadenceString(); + } + + totalWidth += instanceCount * + (totalNSinkWidth + totalPSinkWidth); + totalGateCap += instanceCount * + (totalNSinkCap + totalPSinkCap); + } + } + } + } + } + + // summary variables + double aveWireCap = totalWireCap / numNodes; + double aveGateCap = totalGateCap / numNodes; + double aveAllCap = aveWireCap + aveGateCap; + double Ett = aveAllCap*tau*tau; + + // debugging output for this sizing run + summary += "\n"; + summary += "Number of nodes: " + numNodes + "\n"; + summary += "Average transistor width per node: " + totalWidth / numNodes + "\n"; + summary += "Average wire length per node: " + totalWireLength / numNodes + "\n"; + summary += "Average gate capacitance per node: " + aveGateCap + "\n"; + summary += "Average wire capacitance per node: " + aveWireCap + "\n"; + summary += "Average capacitance per node: " + aveAllCap + "\n"; + summary += "************************************************************" + "\n"; + summary += "t=" + NumberFormatter.format(tau*1e12,3) + "ps" + + " C=" + NumberFormatter.format(aveAllCap*1e15,3) + "fF" + + " Ctt=" + NumberFormatter.format(Ett*1e39,1) + "fF*ps^2" + + " W=" + NumberFormatter.format(aveWidth*1e6,3) + "um" + + " GateC=" + + NumberFormatter.format(100*aveGateCap/aveAllCap,1) +"%" + "\n"; + summary += "************************************************************" + "\n"; + summary += "\n\n"; + + if (! quiet) + System.out.print(summary); + return summary; + + } + + + /** + * Check for big transistor sizes. Give warnings. + **/ + static public void checkSizes(CastDesign design, + TransistorSizingTool tool) { + JautoMessageCenter messageCenter = design.getMessageCenter(); + for (Iterator ita = sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + if(cta.getListHalfOperators().size() > 0) { + for (Iterator itb = + sortHalfOperators(cta.getListHalfOperators()).iterator(); + itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + String s, driveDir; + final double warnWidth; + if (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + s = "N"; + driveDir = "-"; + warnWidth = tool.getOptionNmosWarnWidth(); + } else { + s = "P"; + driveDir = "+"; + warnWidth = tool.getOptionPmosWarnWidth(); + } + + for (Iterator itc = hoa.depths.iterator(); itc.hasNext(); ) { + int i = ((Integer)itc.next()).intValue(); + double f = hoa.getWidth(i); + + if ((warnWidth>=0) && (f > warnWidth)) { + String msa = "WARNING"; + String msb = + "Transistor size larger than " + + s.toLowerCase() + "mosWarnWidth (" + + warnWidth * 1.0e6 + "u).\n"; + String msc = "CellName: " + cta.typeName + "\n" + + "HalfOperatorName: " + hoa.outputNet.canonicalName.getCadenceString() + + (hoa.driveDirection == + HalfOperator.DriveDirection + .PULL_DOWN ? + "-" : "+") + "\n" + + s + "W" + i + "=" + NumberFormatter.format(f*1e6, 3) + "u\n"; + + messageCenter.createMessage(1, 7, msa, msb, msc); + } + } + } + } + } + } + + /** + * This function writes out information about strength ratio between P/N stacks. + **/ + static public void dumpStrengthRatioInformation(CastDesign design, String dirName, double thres) + { + File strengthRatioDebugFile = + new File(dirName, "strength_ratio.debug"); + + JautoMessageCenter messageCenter = design.getMessageCenter(); + + MultiMap/**/ allStrengthRatios = + new MultiMap/**/(new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + + try{ + BufferedWriter bw = new BufferedWriter(new FileWriter(strengthRatioDebugFile)); + + for (Iterator ita = + sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + bw.write("CELL " + cta.typeName + " {\n"); + + MultiMap/**/ cellStrengthRatios = + new MultiMap/**/ + (new TreeMap/**/(), + MultiMap.ARRAY_LIST_FACTORY); + + for (Iterator itb = cta.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + + Pair/**/ ratios = cna.getStrengthRatios(); + double ratioPN = ((Double) ratios.getFirst()).doubleValue(); + double ratioNP = ((Double) ratios.getSecond()).doubleValue(); + double maxRatio = Math.max(ratioPN, ratioNP); + + if (maxRatio > thres) { + String msa = "WARNING"; + String msb = "Large pull-up/pull-down strength ratio: " + NumberFormatter.format(maxRatio, 3) + "\n"; + String msc = "\tCellName = " + cta.typeName + + "; Net = " + cna.canonicalName.getCadenceString() + + "; PN = " + NumberFormatter.format(ratioPN, 3) + + "; NP = " + NumberFormatter.format(ratioNP, 3) + + "\n"; + + messageCenter.createMessage(1, 8, msa, msb, msc); + } + + if (maxRatio > 0.0) { + String stra = cna.canonicalName.getCadenceString() + + "; PN = " + NumberFormatter.format(ratioPN, 3) + + "; NP = " + NumberFormatter.format(ratioNP, 3) + + "\n"; + + String strb = cta.typeName + "; " + stra; + + final Double negativeRatio = new Double(-maxRatio); + cellStrengthRatios.put(negativeRatio, stra); + allStrengthRatios.put(negativeRatio, strb); + } + } + + for (Iterator itc = cellStrengthRatios.values().iterator(); itc.hasNext(); ) { + String s = (String) itc.next(); + bw.write("\t" + s); + } + + bw.write("}\n"); + } + + bw.write("ALL_SORTED_RATIO {\n"); + + for (Iterator itc = allStrengthRatios.values().iterator(); itc.hasNext(); ) { + String s = (String) itc.next(); + bw.write("\t" + s); + } + + bw.write("}\n"); + bw.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + + /** + * This function writes out information about cell partition for sizing groups. + * This information includes all fixed-size cells, sizable cells in each group. + * Each final sizing group contains already-partitioned sizable cells and all + * fixed-size cells. + **/ + static public void dumpSubtypePartitionInformation + (CastDesign design, + List/*>*/ groupedSubtypes, + List/**/ fixedSubtypes, + String dirName) + { + File subtypePartitionDebugFile = + new File(dirName, "subtype_partition.debug"); + + try{ + BufferedWriter bw = new BufferedWriter(new FileWriter(subtypePartitionDebugFile)); + + bw.write("ALL FIXED SUBTYPES:\n"); + for (Iterator ita = fixedSubtypes.iterator(); ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + bw.write("\t" + cta.typeName + "\n"); + } + bw.write("\n"); + + int i = 0; + for (Iterator ita = groupedSubtypes.iterator(); ita.hasNext(); ) { + bw.write("Group " + i + ":\n"); + List/**/ lsta = (List/**/) ita.next(); + for (Iterator itb = lsta.iterator(); itb.hasNext(); ) { + CellType cta = (CellType)itb.next(); + bw.write("\t" + cta.typeName + " " + cta.getNumPaths() + "\n"); + } + bw.write("\n"); + ++i; + } + + bw.close(); + } + catch(IOException e){ + e.printStackTrace(System.err); + } + + } + + private static class SdcConstraint { + final CellType top; + final HierName pathPrefix; + final CellNet outputNet; + final int driveDirection; + double budget; + double wireCap; + double driveRes; + final Collection> ports; + + public SdcConstraint(final CellType top, + final HierName pathPrefix, + final CellNet outputNet, + final int driveDirection, + final double budget, + final double wireCap, + final double driveRes, + final Collection> ports) { + this.top = top; + this.pathPrefix = pathPrefix; + this.outputNet = outputNet; + this.driveDirection = driveDirection; + this.budget = budget; + this.wireCap = wireCap; + this.driveRes = driveRes; + this.ports = ports; + } + private HierName concat(final HierName... names) { + HierName result = names[0]; + for (int i = 1; i < names.length; ++i) { + if (names[i] != null) { + result = HierName.append(result, names[i]); + } + } + return result; + } + private HierName makeHierName(final HierName a, final String b) { + try { + return HierName.makeHierName(a, b); + } catch (InvalidHierNameException e) { + throw new RuntimeException(e); + } + } + private HierName getHierarchy(final HierName inst, final CellNet net) { + final Collection instList = new ArrayList(); + findHierarchy(top, inst, instList, new ArrayList()); + + HierName result = null; + for (Iterator i = instList.iterator(); i.hasNext(); ) { + final HierName n = (HierName) i.next(); + result = makeHierName(result, n.getCadenceString()); + } + + result = makeHierName(result, net.canonicalName.getCadenceString()); + + return result; + } + public TreeSet getNames(final HierName inst) { + final TreeSet names = new TreeSet(); + if (outputNet.isPortNet()) { + names.add(getHierarchy(concat(inst, pathPrefix), outputNet)); + } + for (Pair port : ports) { + final HierName h = concat(inst, port.getFirst()); + if (h != null) names.add(getHierarchy(h, port.getSecond())); + } + return names; + } + public void write(final TreeSet names, final PrintWriter w) { + // look at the "deepest" port first + if (!names.isEmpty()) { + w.printf("%d %g %g %g", driveDirection, budget, wireCap, + driveRes); + for (HierName instPort : names.descendingSet()) { + w.print(" " + instPort.getAsString('/')); + } + w.println(); + } + } + public void update(final double budget, final double wireCap, + final double driveRes) { + this.budget = Math.min(this.budget, budget); + this.wireCap = Math.max(this.wireCap, wireCap); + this.driveRes = Math.max(this.driveRes, driveRes); + } + public boolean equals(final Object o) { + return o instanceof SdcConstraint && + ObjectUtils.equals(pathPrefix, + ((SdcConstraint) o).pathPrefix) && + driveDirection == ((SdcConstraint) o).driveDirection && + outputNet == ((SdcConstraint) o).outputNet && + ports.equals(((SdcConstraint) o).ports); + } + public int hashCode() { + return ObjectUtils.hashCode(pathPrefix) + + System.identityHashCode(outputNet) + + driveDirection + + ports.hashCode(); + } + } + + private static void traceNet( + final HierName inst, + final CellNet net, + final Collection> result) { + for (HierName h : (Set) net.subcellconnectionNames) { + ConnectionInfo ci = net.container.getSubcellConnectedTo(h); + CellNet childNet = ci.child.getNet(ci.getChildName(h)); + final HierName newInst = HierName.append(inst, ci.nameInParent); + result.add(new Pair(newInst,childNet)); + traceNet(newInst, childNet, result); + } + } + + private static Collection> + traceNet(final HierName inst, final CellNet net) { + final Collection> result = + new HashSet>(); + traceNet(inst, net, result); + return result; + } + + private static void processSdcConstraint( + final CastDesign design, + final Map> constraintMap, + final CellType pathContainer, + final SizingPath lastSizingPath, + final GlobalNet gn, + final double sdcBudget) { + final HalfOperator lastHalfOp = + (HalfOperator) lastElement(lastSizingPath.getPath()); + + final CellType gnContainer = gn.getTopCellNet().container; + HierName pathPrefix = null; + HierName gnPrefix = null; + + final CellType topMost; + if (gnContainer == pathContainer) { + topMost = gnContainer; + } else { + if (gnContainer.getLevel() > pathContainer.getLevel()) { + topMost = gnContainer; + HierName pathInst = null; + for (Iterator j = gn.getListSources().iterator(); + j.hasNext(); ) { + final NetSource src = (NetSource) j.next(); + if (src.type == NetType.HALF_OPERATOR_TRANSISTOR && + src.source == lastHalfOp) { + // XXX: what if the same global net is driving by + // multiple instances of the same cell? + pathInst = src.getInstanceName(); + break; + } + } + pathPrefix = computePartialInstance(gnContainer, + pathContainer, + pathInst); + } else { + final HierName pathInst = lastSizingPath.getInstanceName(); + topMost = pathContainer; + gnPrefix = computePartialInstance(pathContainer, + gnContainer, + pathInst); + } + } + + final double loadCap = + gn.getGateCapacitance() + gn.getConstCapacitance(); + + Map constraints = + constraintMap.get(topMost.typeName); + if (constraints == null) { + constraints = new HashMap(); + constraintMap.put(topMost.typeName, constraints); + } + + final HierName pathName; + if (lastSizingPath.getInstanceName() == null) { + pathName = pathPrefix; + } else { + pathName = HierName.append(pathPrefix, + lastSizingPath.getInstanceName()); + } + + final SdcConstraint constraint = + new SdcConstraint(design.getTopLevelCell(), pathName, + lastHalfOp.outputNet, + lastHalfOp.driveDirection, sdcBudget, + loadCap, + gn.getDriveResistance(lastHalfOp), + traceNet(gnPrefix, gn.getTopCellNet())); + + final SdcConstraint prev = constraints.get(constraint); + if (prev == null) { + constraints.put(constraint,constraint); + } else { + prev.update(sdcBudget, loadCap, + gn.getDriveResistance(lastHalfOp)); + } + } + + private static boolean isSdcVisible( + final GlobalNet gn, + final MultiMap portNets, + final Set libs) { + final Set portContainers = (Set) portNets.get(gn); + if (portContainers != null) { + final Set intersect = new HashSet(libs); + intersect.retainAll(portContainers); + return !intersect.isEmpty(); + } + return false; + } + + private static double getLastDelay(SizingPath path, int index) { + final GlobalNet gn = + (GlobalNet) path.getEndNet().getGlobalNets().get(index); + final HalfOperator halfOp = + (HalfOperator) lastElement(path.getPath()); + return gn.calculateDelay(halfOp); + } + + private static void processSdcPaths( + final CastDesign design, + final DelayCalculator delayCalc, + final Map> constraintMap, + final CellType pathContainer, + final AbstractPath path, + final MultiMap portNets, + final Set sdcLibs, + final double delayScale) { + final Collection sdcPaths = new ArrayList(); + double partialDelay = 0; + int partialCount = 0; + SizingPath lastSizingPath = null; + if (path instanceof CatPath) { + final CatPath catPath = (CatPath) path; + for (Iterator i = catPath.getCatPath().iterator(); i.hasNext(); ) { + final SizingPath sizingPath = (SizingPath) i.next(); + if (i.hasNext()) { + final CellNet endNet = sizingPath.getEndNet(); + final GlobalNet gn = + (GlobalNet) endNet.getGlobalNets().get(0); + if (isSdcVisible(gn, portNets, sdcLibs)) { + partialDelay += getLastDelay(sizingPath, 0); + partialCount += 1.5; + sdcPaths.add(sizingPath); + } + } else { + lastSizingPath = sizingPath; + } + } + } else { + lastSizingPath = (SizingPath) path; + } + + final List globalNets = path.getEndNet().getGlobalNets(); + for (int i = 0; i < path.slack.length; ++i) { + final GlobalNet gn = (GlobalNet) globalNets.get(i); + final double pathSlack = + path.getBudget(i) - path.getDelay(i) * delayScale; + final boolean visible = isSdcVisible(gn, portNets, sdcLibs); + final double totalDelay = + visible ? partialDelay + getLastDelay(lastSizingPath, i) + : partialDelay; + final double totalCount = + visible ? partialCount + 1 : partialCount; + for (SizingPath sdcPath : sdcPaths) { + final double delay = getLastDelay(sdcPath, 0); + final double sdcBudget = + //pathSlack * (delay / totalDelay) + delay * delayScale; + pathSlack * (1.5 / totalCount) + delay * delayScale; + processSdcConstraint( + design, constraintMap, pathContainer, sdcPath, + (GlobalNet) sdcPath.getEndNet().getGlobalNets().get(0), + sdcBudget); + } + if (visible) { + final double delay = getLastDelay(lastSizingPath, i); + final double sdcBudget = + //pathSlack * (delay / totalDelay) + delay * delayScale; + pathSlack / totalCount + delay * delayScale; + processSdcConstraint( + design, constraintMap, pathContainer, lastSizingPath, + gn, sdcBudget); + } + } + } + + public static void dumpSdcConstraints(CastDesign design, + DelayCalculator delayCalc, + double delayScale, + MultiMap portNets, + Set sdcLibs, + String dirName) + throws IOException { + final File out = new File(dirName, "sdc.debug"); + final PrintWriter pw = + new PrintWriter(new BufferedWriter(new FileWriter(out))); + final Map> constraintMap = + new HashMap>(); + + for (Iterator ita = sortCellTypes(design.allCellTypes).iterator(); + ita.hasNext(); ) { + CellType cta = (CellType)ita.next(); + + for (Iterator pathIterator = getPathIterator(cta); + pathIterator.hasNext(); ) { + final AbstractPath path = (AbstractPath) pathIterator.next(); + processSdcPaths(design, delayCalc, constraintMap, cta, path, + portNets, sdcLibs, delayScale); + } + } + + pw.println("VERSION 2"); + + final MultiSet allConstraints = new MultiSet( + new Comparator,SdcConstraint>>() { + public int compare( + final Pair,SdcConstraint> p1, + final Pair,SdcConstraint> p2) { + int x = p1.getFirst().first().compareTo( + p2.getFirst().first()); + if (x == 0) { + x = p1.getSecond().driveDirection - + p2.getSecond().driveDirection; + } + return x; + } + }); + + design.getTopLevelCell().walkMany( + new CellType.InstanceProcessor() { + public void processInstance(CellType t, HierName inst, + Collection path) { + final Map constraints = + constraintMap.get(t.typeName); + + if (constraints != null) { + for (SdcConstraint constraint : constraints.values()) { + final TreeSet names = + constraint.getNames(inst); + if (!names.isEmpty()) { + allConstraints.add( + new Pair,SdcConstraint> + (names, constraint)); + } + } + } + } + } + ); + for (Iterator i = allConstraints.iterator(); i.hasNext(); ) { + final Pair,SdcConstraint> p = + (Pair,SdcConstraint>) i.next(); + final TreeSet names = p.getFirst(); + final SdcConstraint constraint = p.getSecond(); + constraint.write(names, pw); + } + + pw.close(); + } + + /** + * Convert current real time into better looking string. + **/ + public static /*@ non_null @*/ String getCurrentTime() { + return new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(new Date()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoUtil.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoUtil.java new file mode 100644 index 0000000000..156818f6f9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/JautoUtil.java @@ -0,0 +1,176 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + + +package com.avlsi.tools.jauto; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.FilterWriter; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Writer; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.Set; +import java.util.TreeSet; +import java.util.TreeMap; +import java.util.StringTokenizer; + +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.Symbol; +import com.avlsi.fast.*; +import com.avlsi.fast.ports.*; +import com.avlsi.file.common.HierName; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.cast.*; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.debug.Debug; +import com.avlsi.netlist.*; +import com.avlsi.netlist.impl.*; +import com.avlsi.io.FileSearchPath; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + + +public class JautoUtil { + + private JautoUtil() { + throw new AssertionError(); + } + + static public void getLeafCellInstantiationPaths + (List/**/ lst1, + CellType ct1, + Map/*>>*/ map1) + { + if(ct1.getAllInstances().size() > 0){ + for (Iterator ita = ct1.getAllInstances().iterator(); + ita.hasNext(); ) { + ConnectionInfo cia = (ConnectionInfo)ita.next(); + + List/**/ lsta = + new ArrayList/**/(lst1); + lsta.add(cia); + + getLeafCellInstantiationPaths(lsta, cia.child, map1); + } + } + else{ + List/*>*/ lsta = + (List/*>*/) map1.get(ct1); + if (lsta == null) { + lsta = new ArrayList/*>*/(); + map1.put(ct1, lsta); + } + lsta.add(lst1); + } + } + + + static public String getFlatCanonicalName(CellNet cn1, + List/**/ lst1, + List/**/ lst2) + { + if (!cn1.isPortNet() || lst1.isEmpty()) { + // Internal net, return name directly + String flatName = getFlatName(cn1, lst1); + lst2.add(cn1); + return flatName; + } else { + // Port net, search further up hierarchy + final int depth = lst1.size(); + List/*>*/ lsta = + new ArrayList/*>*/(lst1); + lsta.remove(depth-1); + + ConnectionInfo cia = (ConnectionInfo)lst1.get(depth-1); + + List/**/ lstb = new ArrayList/**/(1); + + for (Iterator ita = cia.getParentNet(cn1).iterator(); + ita.hasNext(); ) { + CellNet cna = (CellNet)ita.next(); + + lstb.add(getFlatCanonicalName(cna, lsta, lst2)); + } + + assert lstb.size() < 2 + : "One port net connecting to more than one cell net " + + "in parent.\nParent cell: " + cia.parent.typeName + + "\nChild cell: " + cia.child.typeName; + + return (String) lstb.get(0); + } + } + + + static public String getFlatName(CellNet cn1, + List/**/ lst1) + { + final StringBuffer sb = new StringBuffer(); + for (Iterator ita = lst1.iterator(); ita.hasNext(); ) { + ConnectionInfo cia = (ConnectionInfo)ita.next(); + sb.append("/X" + cia.nameInParent.getCadenceString()); + } + + sb.append("/" + cn1.canonicalName.getCadenceString()); + + return sb.toString(); + } + + + static public String getMostCanonicalName(List/**/ lst1, + char ch1) + { + return (String)lst1.get(0); + } + + + static public double calculateDelay(HalfOperator ho1, GlobalNet gn1) + { + double delay = 0.0; + List lsta = new ArrayList(); + gn1.getDelayFunction(ho1, lsta); + for (FunctionTerm ftma : lsta) { + assert ftma.type == FunctionTerm.Type.CONSTANT + : "Should get constant delay values at this stage."; + + delay += ftma.coefficient; + } + + return delay; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jtimer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jtimer.java new file mode 100644 index 0000000000..1a64bf44b9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Jtimer.java @@ -0,0 +1,2278 @@ +package com.avlsi.tools.jauto; + +import java.io.*; +import java.util.*; +import java.util.zip.*; + +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.CastCacheManager; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveTable; + +import com.avlsi.fast.CastDesign; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.HalfOperator; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.BlockInterface; + +import com.avlsi.cell.CellInterface; + +import com.avlsi.io.FileSearchPath; + +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.dsim.Rule; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.text.StringUtil; +import com.avlsi.util.text.PrintfFormat; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.debug.GetTime; + +import org.jdom.*; +import org.jdom.output.XMLOutputter; +import org.jdom.output.Format; + +import org.xml.sax.*; +import org.xml.sax.helpers.XMLReaderFactory; +import org.apache.xerces.parsers.SAXParser; + +/** + * Objective + * Change TimingPath to String based + * Change unit to ps + * dont keep interpath delay slew + **/ +public final class Jtimer { + private static Map errmap = null; + private String plt = "plt"; + + private static void printStats(final String what) { + if (verbose) { + System.err.println("CPU Time (" + what + "): " + + GetTime.userCPUTime()/1000 + "(User), " + + GetTime.systemCPUTime()/1000 + "(System)"); + final Runtime rt = Runtime.getRuntime(); + System.gc(); System.gc(); System.gc(); + System.err.println("Memory: " + + (int) ((rt.totalMemory() - rt.freeMemory())/1e6) + "M used, " + + (int) (rt.totalMemory()/1e6) + "M total, " + + (int) (rt.freeMemory()/1e6) + "M free, " + + (int) (rt.maxMemory()/1e6) + "M max"); + } + } + + private static void printErr(final String what, final BufferedWriter errFile) throws IOException { + if (errmap == null) + errmap = new HashMap(); + Integer I = (Integer) errmap.get(what); + if(I == null){ + errmap.put(what,(Integer) 1); + errFile.write(what); + } + } + + public class WorkingGZIPInputStream extends java.util.zip.GZIPInputStream { + /** + * Creates a new input stream with the specified buffer size. + * @param in the input stream + * @param size the input buffer size + * @exception IOException if an I/O error has occurred + **/ + public WorkingGZIPInputStream (InputStream in, int size) + throws IOException { + super (in, size); + } + + /** + * Creates a new input stream with a default buffer size. + * @param in the input stream + * @exception IOException if an I/O error has occurred + **/ + public WorkingGZIPInputStream (InputStream in) + throws IOException { + super (in); + } + + /** + * Calls super.read() and then catch and ignore any IOExceptions that + * mention "Corrupt GZIP trailer". + **/ + public int read (byte buf[], int off, int len) + throws IOException { + try { + return super.read (buf, off, len); + } catch (IOException e) { + if (e.getMessage ().indexOf ("Corrupt GZIP trailer") != -1) { + return -1; + } else { + throw e; + } + } + } + } + /** + * Class that handling array of String + */ + static class StringArrayUtil { + public static String join(final String [] stra, final char c){ + return join(stra,c,0,stra.length); + } + public static String join(final String[] stra, final char c, int start, int len) { + if(stra == null) + return ""; + final StringBuffer buf = new StringBuffer(); + for (int i = start, j=0; i < stra.length && j 0 ? max_depth - 1 : max_depth; + retval.addAll(getCells(conn_info.child, child_depth, visited)); + } + return retval; + } + /** + * Find all the instances of a cell contained in another cell (container) + * The result is a list of all the instance paths. Each instance path is + * described as an array of instance names at each hierarchical level. + * + * @param container the cell containing the other cell + * @param cell the cell being contained + * @param recursive whether the process is recursive or not + **/ + static List /*String []*/ findInstances(CellType container, CellType cell, boolean recursive) { + List retval = new ArrayList(); + Collection subcell_conns = container.getAllSubcellConnections(); + for(Iterator conn_i = subcell_conns.iterator();conn_i.hasNext();){ + ConnectionInfo conn_info = (ConnectionInfo) conn_i.next(); + String instance_name = conn_info.nameInParent.getAsString('.'); + if(conn_info.child.typeName.equals(cell.typeName)) { + retval.add(StringArrayUtil.fromString(instance_name)); + } else if(recursive) { + List child_instances = findInstances(conn_info.child, cell, recursive); + for(Iterator child_instances_i=child_instances.iterator();child_instances_i.hasNext();){ + String [] child_instance = (String []) child_instances_i.next(); + retval.add(StringArrayUtil.prepend(child_instance,instance_name)); + } + } + } + return retval; + } + + /** + * Split a String (representing a hierarchical path) seperated by '.' based on hierarchy. + * In the given String, some dots are part of the instance name, some dots are hierarchical seperator. + * + * @param container the cell containing the path + * @param name the path name to be splited + * @param recursive whether the process is recursive or not + **/ + static String [] hierarchicalSplit(CellType container, String name, boolean recursive) throws Exception { + if(name == null || name.length() == 0) + return new String[0]; + String remain_part = name; + String instance_part = ""; + ConnectionInfo subcell_conn = null; + while(remain_part.length() != 0){ + int dot_pos = remain_part.indexOf('.'); + if(dot_pos == -1) { + instance_part = remain_part; + remain_part = ""; + } else { + instance_part += remain_part.substring(0,dot_pos+1); + remain_part = remain_part.substring(dot_pos+1); + String instance_name = instance_part.substring(0,instance_part.length()-1); + HierName instance_hier = HierName.makeHierName(instance_name,'.'); + subcell_conn = container.getSubcellNamed(instance_hier); + if(subcell_conn != null) + break; + } + } + String [] retval; + if(subcell_conn!= null) { + if(recursive) { + String [] remain_array = hierarchicalSplit(subcell_conn.child, remain_part, recursive); + retval = StringArrayUtil.prepend(remain_array,subcell_conn.nameInParent.getAsString(".")); + } else { + retval = new String [2]; + retval[1] = remain_part; + retval[0] = subcell_conn.nameInParent.getAsString("."); + } + } else { + retval = StringArrayUtil.fromString(name); + } + return retval; + } + + /** + * Push down a net along the hierarchy path as much as possible + * + * @param cnet the net to be pushed down from the current hierarchy + * @param path_to_push is the hiearchy to push + **/ + static HierNet pushDownNet(final CellNet cnet, final String [] path_to_push) throws Exception { +// System.err.println("pushDownNet IN, net " + cnet.canonicalName.getAsString('.') + " path " + +// StringArrayUtil.join(path_to_push,'/')); + CellNet current_net=cnet; + int i; + for(i=0;i mm.min) + min = mm.min; + } + public void set(float ma, float mi){ + if(ma != Float.NEGATIVE_INFINITY && + ma != Float.POSITIVE_INFINITY && + mi != Float.NEGATIVE_INFINITY && + mi != Float.POSITIVE_INFINITY){ + max = Math.max(ma,mi); + min = Math.min(ma,mi); + }else{ + max = ma; + min = mi; + } + } + public String toString(){ + return "{" + max + "," + min + "}"; + } + public MaxMinFloat plus(MaxMinFloat m){ + return new MaxMinFloat(this.max + m.max,this.min + m.min); + } + public MaxMinFloat plus(float ma, float mi){ + MaxMinFloat in = new MaxMinFloat(ma,mi); + return plus(in); + } + public void reset(){ + max = 0; + min = 0; + } + } + class NetSlew { + MaxMinFloat up; + MaxMinFloat dn; + public NetSlew(){ + up = new MaxMinFloat(defaultInputSlewUp,defaultInputSlewUp); + dn = new MaxMinFloat(defaultInputSlewDown,defaultInputSlewDown); + } + public String toString(){ + return "[" + up + "," + dn + "]"; + } + } + class InterPathSlew { + NetSlew curr; + NetSlew next; + public InterPathSlew(){ + curr = new NetSlew(); + curr.up.set(defaultInputSlewUp,defaultInputSlewUp); + curr.dn.set(defaultInputSlewDown,defaultInputSlewDown); + next = new NetSlew(); + next.up.set(Float.NEGATIVE_INFINITY,Float.POSITIVE_INFINITY); + next.dn.set(Float.NEGATIVE_INFINITY,Float.POSITIVE_INFINITY); + } + public void updateNext(MaxMinFloat slew, boolean rising){ + if(rising) { + next.up.update(slew); + } else { + next.dn.update(slew); + } + } + public void shift(){ + if(next.up.max == Float.NEGATIVE_INFINITY) + curr.up.max = defaultInputSlewUp; + else + curr.up.max = next.up.max; + if(next.up.min == Float.POSITIVE_INFINITY) + curr.up.min = defaultInputSlewUp; + else + curr.up.min = next.up.min; + if(next.dn.max == Float.NEGATIVE_INFINITY) + curr.dn.max = defaultInputSlewDown; + else + curr.dn.max = next.dn.max; + if(next.dn.min == Float.POSITIVE_INFINITY) + curr.dn.min = defaultInputSlewDown; + else + curr.dn.min = next.dn.min; + next.up.max = Float.NEGATIVE_INFINITY; + next.up.min = Float.POSITIVE_INFINITY; + next.dn.max = Float.NEGATIVE_INFINITY; + next.dn.min = Float.POSITIVE_INFINITY; + } + public boolean recalculate(MaxMinFloat slew, boolean rising){ + if(rising){ + if(Math.abs(curr.up.max-slew.max) > iterationThreshold) + return true; + if(Math.abs(curr.up.min-slew.min) > iterationThreshold) + return true; + } else{ + if(Math.abs(curr.dn.max-slew.max) > iterationThreshold) + return true; + if(Math.abs(curr.dn.min-slew.min) > iterationThreshold) + return true; + } + return false; + } + public String toString(){ + return "[" + curr + "," + next + "]"; + } + } + + class TimingPathMeasured { + //[startNet_index][containerInstance_index] + public boolean [][] noMeasure = null; + public MaxMinFloat [][] inputSlew = null; + public MaxMinFloat [][] pathDelay = null; + + public TimingPathMeasured(final TimingPath timingPath){ + pathDelay = new MaxMinFloat[timingPath.numOfStartNets()][]; + inputSlew = new MaxMinFloat[timingPath.numOfStartNets()][]; + noMeasure = new boolean[timingPath.numOfStartNets()][]; + for(int i=0;i=0;k--){ + HierNet net = new HierNet(StringArrayUtil.concatenate(container_instance, + ((HierNet) pathnets.get(k)).instance), + ((HierNet) pathnets.get(k)).cnet); + HierNet canonical_net; + if(((HierNet)pathnets.get(k)).instance.length == 0){ + canonical_net = (HierNet) canonicalNetCache.get(net); + if(canonical_net == null){ + canonical_net = HierarchyTraverse.popUpNet(topCell,net); + canonicalNetCache.put(net,canonical_net); + } + }else + canonical_net = net.duplicate(); + pathNetsCanonical[j][k] = new HierNetName(canonical_net); + if(k==(pathnets.size()-1)) + continue; + HierNet matching_net = + HierarchyTraverse.getTopMatchingNet(topCell,pathNetsCanonical[j][k+1].instance, + net); + pathNetsMatching[j][k] = new HierNetName(matching_net); + } + for(int i=0;i maxSlew) + printErr("Slew Violation: " + + pathNetsCanonical[instance_i][j] + + " " + current_slew.max + "\n", errFile); + } + } + target_direction = ! target_direction; + } + } + public long numOfNoMeasure(){ + long retval = 0; + for(int i=0;i budget) + retval++; + } + } + return retval; + } + public SortedMap delayHistgram(){ + SortedMap retval = new TreeMap(); + for(int i=0;i 0 + if (DebugOption.printLevel < 1) + System.err.println("CT "+numOfStartNets()+" "+numOfInstances()+" "+targetNameDirection()); + if(startNetsLocal.length == 0) + return; + + int nummeas=0; + for(int instance_i=0;instance_i 0) { + InterPathSlew ips = (InterPathSlew) interPathSlew.get(startNetsCanonical[startnet_i][instance_i]); + if(ips != null) { + recalculate = ips.recalculate(measured.inputSlew[startnet_i][instance_i],startPolarity); + //if(measured.pathDelay[startnet_i][instance_i].max >= budget) + // recalculate = true; + if(recalculate){ + if(startPolarity) + measured.inputSlew[startnet_i][instance_i] = ips.curr.up; + else + measured.inputSlew[startnet_i][instance_i] = ips.curr.dn; + } + } else { + recalculate = false; + } + } + if(recalculate == false) + continue; + MaxMinFloat [] delay = new MaxMinFloat[length()]; + MaxMinFloat [] slew = new MaxMinFloat[length()]; + calculatePathDelay(startnet_i,instance_i,delay,slew); + if(measured.noMeasure[startnet_i][instance_i]) + continue; + nummeas++; + MaxMinFloat path_delay = new MaxMinFloat(0,0); + for(int i=0;i>>>,@>>>> @>>>>,@>>>>> @>>>>>>,@>>>>>> + PrintfFormat fmt = new PrintfFormat("%-42s %6.1f,%6.1f %6.1f,%6.1f %6.1f,%6.1f"); + Object [] fmtObj = new Object[7]; + fmtObj[0] = startNetsLocal[startnet_i] + (startPolarity?"+":"-"); + fmtObj[1] = new Float(0); + fmtObj[2] = new Float(0); + fmtObj[3] = new Float(measured.inputSlew[startnet_i][instance_i].min); + fmtObj[4] = new Float(measured.inputSlew[startnet_i][instance_i].max); + fmtObj[5] = new Float(0); + fmtObj[6] = new Float(0); + vioFile.println(fmt.sprintf(fmtObj)); + MaxMinFloat current_total_delay = new MaxMinFloat(0,0); + boolean target_direction = !startPolarity; + for(int i=0;i 0.0) + slackFile.println("slack " + stau + " "+ targetNameDirection(i) + " " + sslack); + if (DebugOption.printLevel < 1) + System.err.println("TP NT="+pathNetsCanonical[i][length()-1].type+" M="+measured.pathDelay[k][i].max+" B="+budget+" S="+slack+" "+this.toShortString(i)); + } + if(measured.pathDelay[k][i].max > measured.pathDelay[startnet_i][instance_i].max){ + instance_i = i; + startnet_i = k; + } + nummeas++; + } + } + if (DebugOption.printLevel < 1) + System.err.println("RV2 "+numOfStartNets()+" "+numOfInstances()+" "+nummeas+" "+startnet_i+" "+instance_i+" "+targetNameDirection()); + if(allPaths || measured.pathDelay[startnet_i][instance_i].max <= budget){ + return; + } + MaxMinFloat [] delay = new MaxMinFloat[length()]; + MaxMinFloat [] slew = new MaxMinFloat[length()]; + calculatePathDelay(startnet_i, instance_i, delay, slew); + printViolation(vioFile, startnet_i,instance_i, delay, slew); + float slack = budget-measured.pathDelay[startnet_i][instance_i].max; + String stau = String.format(Locale.US,"%.4f", (double)(tau/1000)); + String sslack = String.format(Locale.US,"%.4f", (double)(slack/1000)); + if (measured.pathDelay[startnet_i][instance_i].max > 0.0) + slackFile.println("slack " + stau + " "+ targetNameDirection() + " " + sslack); + if (DebugOption.printLevel < 1) { + System.err.println("TP M="+measured.pathDelay[startnet_i][instance_i].max+" B="+budget+" S="+slack+" "+this.toShortString()); + System.err.println("TS "+this); + System.err.println("PD S="+startnet_i+" I="+instance_i+" D="+length()+" M="+measured.pathDelay[startnet_i][instance_i].max+" B="+budget+" I="+StringArrayUtil.join(containerInstances[instance_i],'.')); + } + } + } + + public void pathGeneration() throws Exception { + if(skipPathGeneration){ + System.err.println("Skipped Path Generation ..."); + return; + } + + // initialize jauto + final CastFileParser castFileParser = + CastCacheManager.getDefault().getCastFileParser(new FileSearchPath(castRoot), + castVersion, + new StandardParsingOption(theArgs)); + /* + final CastFileParser castFileParser = + new CastFileParser(new FileSearchPath(castRoot), + castVersion, + new StandardParsingOption(theArgs)); + */ + + if (verbose) System.err.println("Parsing ..."); + final TechnologyData techData = new TechnologyData(theArgs); + final CastDesign castDesign = Jauto.loadFullyQualifiedCell(castFileParser, topCellName, (float) (tau*1e-12),1,1, techData, routed, true, skipCellsJauto, null, theArgs.argExists("useSteinerTree")); + printStats("Parser"); + final String staticizer = theArgs.getArgValue("staticizer", null); + final String weakInverter = theArgs.getArgValue("weak-inverter", null); + final String smallInverter = theArgs.getArgValue("small-inverter", null); + final String[] gateNames; + { + final String gates = theArgs.getArgValue("gates", null); + if (gates == null) gateNames = new String[0]; + else gateNames = StringArrayUtil.split(gates, ':'); + } + if (verbose) System.err.println("Jauto ..."); + final JautoMessageCenter messageCenter = new JautoMessageCenter(); + castDesign.setMessageCenter(messageCenter); + final CellType topCell = castDesign.getCell(topCellName); + castDesign.getTopLevelCell().instanceMinimalSubTypes(CastDesign.TRANSISTORS,staticizer, weakInverter, smallInverter, gateNames,castFileParser); + List/**/ listAllGlobalNets = new ArrayList/**/(); + GlobalNet.generateGlobalNets(topCell, listAllGlobalNets); + Set allCellTypes = new TreeSet(CellType.getNameComparator()); + allCellTypes.addAll(castDesign.allCellTypes); + allCellTypes.remove(castDesign.getTopLevelCell()); + SizingPath.generatePaths(allCellTypes, ignoreReset, true, Integer.MAX_VALUE); + CatPath.generateCatPaths(allCellTypes, ignoreReset, true, false); + CatPath.reduceCatPaths(allCellTypes, 0); + TransistorSizingTool sizingTool = new CGTransistorSizingTool(-1,-1,true); + sizingTool.setOptionUnitDelay((float) (tau*1e-12)); + DelayCalculator delayCalculator = new DelayCalculator(castDesign,sizingTool); + delayCalculator.calculateDelay(); + printStats("Jauto"); + + if (verbose) System.err.println("Generating Paths ..."); + List allCells; + { + Set visited = new HashSet(); + for(Iterator it=skipCells.iterator();it.hasNext();){ + String cell_name = (String) it.next(); + CellType cell = castDesign.getCell(cell_name); + if(cell != null) + visited.add(cell); + } + allCells = HierarchyTraverse.getCells(topCell,depth,visited); + } + + PrintStream pthFile = new PrintStream(new GZIPOutputStream(new FileOutputStream(topCellName+".pth.gz")),true); + pthFile.println(""); + pthFile.println(""); + org.jdom.output.Format xmloutformat = Format.getCompactFormat(); + xmloutformat.setIndent(" "); + xmloutformat.setLineSeparator("\n"); + XMLOutputter serializer = new XMLOutputter(xmloutformat); + for (Iterator cell_i = allCells.iterator(); cell_i.hasNext(); ) { + Map canonicalNetCache = new HashMap(); + CellType cell = (CellType) cell_i.next(); + if (DebugOption.printLevel < 1) + System.err.println("CELL "+cell.getLevel()+"="+cell.typeName); + if(cell.getLevel() > 0){ + for (Iterator catpath_i = cell.getReducedCatPaths().iterator(); catpath_i.hasNext(); ) { + CatPath catpath = (CatPath)catpath_i.next(); + if (DebugOption.printLevel < 1) { + StringBuffer sb = new StringBuffer(); + for (Iterator ita = catpath.getCatPath().iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + for (Iterator its = spa.getPath().iterator(); its.hasNext(); ) { + HalfOperator hoa = (HalfOperator)its.next(); + CellNet cna = hoa.outputNet; + sb.append(spa.container.typeName+":"+spa.getInstanceName()+"."); + sb.append(cna.canonicalName.getCadenceString()); + if (hoa.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + sb.append("- "); + } + else { + sb.append("+ "); + } + } + } + + System.err.println("CATPATH"+cell.getLevel()+" "+cell.typeName+":"+catpath.isFragment()+":"+catpath.getStartNets().size()+":"+catpath.getStartNets()+":"+sb); + } + if(catpath.isFragment()) + continue; + if(catpath.getStartNets().size() == 0) + continue; + TimingPath timingPath = new TimingPath(catpath, cell, topCell, canonicalNetCache); + serializer.output(timingPath.toXML(), pthFile); + pthFile.println(""); + } + for (Iterator sizpath_i = cell.getSizingPaths().iterator(); sizpath_i.hasNext(); ) { + CatPath sizpath = (CatPath) sizpath_i.next(); + TimingPath timingPath = new TimingPath(sizpath, cell, topCell, canonicalNetCache); + if (DebugOption.printLevel < 1) + System.err.println("SIZPATH2"+cell.getLevel()+" "+cell.typeName+":"+sizpath.isFragment()+":"+sizpath.getStartNets()+":"+sizpath.toString()+":"); + } + for (Iterator sizpath_i = cell.getSizingPaths().iterator(); sizpath_i.hasNext(); ) { + CatPath catpath = (CatPath)sizpath_i.next(); + StringBuffer sb = new StringBuffer(); + for (Iterator ita = catpath.getCatPath().iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + for (Iterator its = spa.getPath().iterator(); its.hasNext(); ) { + HalfOperator hoa = (HalfOperator)its.next(); + CellNet cna = hoa.outputNet; + sb.append(spa.container.typeName+":"+spa.getInstanceName()+"."); + sb.append(cna.canonicalName.getCadenceString()); + if (hoa.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + sb.append("- "); + } + else { + sb.append("+ "); + } + } + } + StringBuffer ss = new StringBuffer(); + for (Iterator itd = catpath.getStartNets().iterator(); itd.hasNext(); ) { + CellNet cna = (CellNet)itd.next(); + if (ss.length() > 0) ss = ss.append(" "); + ss = ss.append(cna.getInternalCanonical()); + } + + TimingPath timingPath = new TimingPath(catpath, cell, topCell, canonicalNetCache); + if (DebugOption.printLevel < 1) { + String s = " ok"; + if (catpath.delay == null) s = " null"; + System.err.println("SZPATH"+cell.getLevel()+" "+cell.typeName+":"+catpath.isFragment()+":"+catpath.getStartNets().size()+":"+ss+":"+sb+s); + } + serializer.output(timingPath.toXML(), pthFile); + pthFile.println(""); + } + } else{ + for (Iterator catpath_i = cell.getReducedCatPaths().iterator(); catpath_i.hasNext(); ) { + CatPath catpath = (CatPath)catpath_i.next(); + if (DebugOption.printLevel < 1) { + StringBuffer sb = new StringBuffer(); + for (Iterator ita = catpath.getCatPath().iterator(); ita.hasNext(); ) { + SizingPath spa = (SizingPath)ita.next(); + for (Iterator its = spa.getPath().iterator(); its.hasNext(); ) { + HalfOperator hoa = (HalfOperator)its.next(); + CellNet cna = hoa.outputNet; + sb.append(spa.container.typeName+":"+spa.getInstanceName()+"."); + sb.append(cna.canonicalName.getCadenceString()); + if (hoa.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + sb.append("- "); + } + else { + sb.append("+ "); + } + } + } + System.err.println("CATPATH"+cell.getLevel()+" "+cell.typeName+":"+catpath.isFragment()+":"+catpath.getStartNets().size()+":"+catpath.getStartNets()+":"+sb); + } + if(catpath.isFragment()) + continue; + if(catpath.getStartNets().size() == 0) + continue; + TimingPath timingPath = new TimingPath(catpath, cell, topCell, canonicalNetCache); + serializer.output(timingPath.toXML(), pthFile); + pthFile.println(""); + } + for (Iterator sizpath_i = cell.getSizingPaths().iterator(); sizpath_i.hasNext(); ) { + SizingPath sizpath = (SizingPath) sizpath_i.next(); + if(sizpath.isFragment()) + continue; + if(sizpath.getStartNets().size() == 0) + continue; + if (DebugOption.printLevel < 1) { + StringBuffer sb = new StringBuffer(); + for (Iterator its = sizpath.getPath().iterator(); its.hasNext(); ) { + HalfOperator hoa = (HalfOperator)its.next(); + CellNet cna = hoa.outputNet; + String in = ""; + if (sizpath.getInstanceName() != null) in = sizpath.getInstanceName()+"."; + sb.append(sizpath.container.typeName+":"+in); + sb.append(cna.canonicalName.getCadenceString()); + if (hoa.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + sb.append("- "); + } + else { + sb.append("+ "); + } + } + System.err.println("SIZPATH"+cell.getLevel()+" "+cell.typeName+":"+sizpath.isFragment()+":"+sizpath.getStartNets().size()+":"+sb); + } + TimingPath timingPath = new TimingPath(sizpath, cell, topCell, canonicalNetCache); + serializer.output(timingPath.toXML(), pthFile); + pthFile.println(""); + } + } + canonicalNetCache.clear(); + } + pthFile.println("\n"); + pthFile.close(); + printStats("Path Generation"); + errFile.flush(); + } + + class DelayExtractor { + private CastFileParser castFileParser; + private final CellInterface topCell; + private Map dirCache; + private Set errorCells; + public DelayExtractor(final CastFileParser castFileParser) throws Exception { + this.castFileParser = castFileParser; + topCell = routed? + castFileParser.getFullyQualifiedCell(plt+"." + topCellName).routedSubcells(true): + castFileParser.getFullyQualifiedCell(plt+"." + topCellName); + dirCache = new HashMap(); + errorCells = new HashSet(); + } + private MaxMinFloat [] interpolate(final List measured, final MaxMinFloat in_slew) throws Exception { + if(((List) measured.get(1)).size() == 0) + return null; + if(((List) measured.get(1)).size() == 1){ + return new MaxMinFloat [] { + new MaxMinFloat(((Float) ((List) measured.get(2)).get(0)).floatValue(), + ((Float) ((List) measured.get(4)).get(0)).floatValue()), + new MaxMinFloat(((Float) ((List) measured.get(3)).get(0)).floatValue(), + ((Float) ((List) measured.get(5)).get(0)).floatValue()) + }; + } + Map measured_data = new HashMap(); + for(int i=0;i<((List) measured.get(1)).size();i++){ + float measured_in_slew = ((Float) ((List) measured.get(1)).get(i)).floatValue(); + float measured_delay1 = ((Float) ((List) measured.get(2)).get(i)).floatValue(); + float measured_slew1 = ((Float) ((List) measured.get(3)).get(i)).floatValue(); + float measured_delay2 = ((Float) ((List) measured.get(4)).get(i)).floatValue(); + float measured_slew2 = ((Float) ((List) measured.get(5)).get(i)).floatValue(); + measured_data.put(new Float(measured_in_slew), + new MaxMinFloat[] {new MaxMinFloat(measured_delay1,measured_delay2), + new MaxMinFloat(measured_slew1,measured_slew2)}); + } + float retMaxDelay, retMinDelay, retMaxSlew, retMinSlew; + { + // max condition + SortedSet measured_in_slew = new TreeSet(measured_data.keySet()); + SortedSet measured_head = measured_in_slew.headSet(new Float(in_slew.max)); + SortedSet measured_tail = measured_in_slew.tailSet(new Float(in_slew.max)); + Float keyFrom,keyTo; + if(measured_head.size() == 0){ + Float [] keys = (Float []) measured_in_slew.toArray(new Float[0]); + keyFrom = keys[0]; + keyTo = keys[1]; + } else if(measured_tail.size() == 0){ + Float [] keys = (Float []) measured_in_slew.toArray(new Float[0]); + keyFrom = keys[keys.length-2]; + keyTo = keys[keys.length-1]; + } else { + keyFrom = (Float) measured_head.last(); + keyTo = (Float) measured_tail.first(); + } + MaxMinFloat delayFrom = ((MaxMinFloat []) measured_data.get(keyFrom))[0]; + MaxMinFloat slewFrom = ((MaxMinFloat []) measured_data.get(keyFrom))[1]; + MaxMinFloat delayTo = ((MaxMinFloat []) measured_data.get(keyTo))[0]; + MaxMinFloat slewTo = ((MaxMinFloat []) measured_data.get(keyTo))[1]; + retMaxDelay = linearInterpolate(in_slew.max,keyFrom.floatValue(),keyTo.floatValue(),delayFrom.max,delayTo.max); + // saturate on max slew if slower than measured + if(measured_head.size() == 0) + retMaxSlew = slewTo.max; + else + retMaxSlew = linearInterpolate(in_slew.max,keyFrom.floatValue(),keyTo.floatValue(),slewFrom.max,slewTo.max); + } + { + // min condition + SortedSet measured_in_slew = new TreeSet(measured_data.keySet()); + SortedSet measured_head = measured_in_slew.headSet(new Float(in_slew.min)); + SortedSet measured_tail = measured_in_slew.tailSet(new Float(in_slew.min)); + Float keyFrom,keyTo; + if(measured_head.size() == 0){ + Float [] keys = (Float []) measured_in_slew.toArray(new Float[0]); + keyFrom = keys[0]; + keyTo = keys[1]; + } else if(measured_tail.size() == 0){ + Float [] keys = (Float []) measured_in_slew.toArray(new Float[0]); + keyFrom = keys[keys.length-2]; + keyTo = keys[keys.length-1]; + } else { + keyFrom = (Float) measured_head.last(); + keyTo = (Float) measured_tail.first(); + } + MaxMinFloat delayFrom = ((MaxMinFloat []) measured_data.get(keyFrom))[0]; + MaxMinFloat slewFrom = ((MaxMinFloat []) measured_data.get(keyFrom))[1]; + MaxMinFloat delayTo = ((MaxMinFloat []) measured_data.get(keyTo))[0]; + MaxMinFloat slewTo = ((MaxMinFloat []) measured_data.get(keyTo))[1]; + if(measured_head.size() == 0) + retMinDelay = linearInterpolate(in_slew.min, + keyFrom.floatValue(), + keyTo.floatValue(), + delayFrom.min, + delayFrom.min + (delayTo.min - delayFrom.min)*2); + else if(measured_tail.size() == 0) + retMinDelay = delayTo.min; + else + retMinDelay = linearInterpolate(in_slew.min, + keyFrom.floatValue(), + keyTo.floatValue(), + delayFrom.min, + delayTo.min); + if(measured_tail.size() == 0) + retMinSlew = slewTo.min; + else + retMinSlew = linearInterpolate(in_slew.min, + keyFrom.floatValue(), + keyTo.floatValue(), + slewFrom.min, + slewTo.min); + } + retMaxDelay = (float) Math.max(retMaxDelay,0.0); + retMinDelay = (float) Math.max(retMinDelay,0.0); + retMaxSlew = (float) Math.max(retMaxSlew,0.0); + retMinSlew = (float) Math.max(retMinSlew,0.0); + return new MaxMinFloat[] {new MaxMinFloat(retMaxDelay,retMinDelay), + new MaxMinFloat(retMaxSlew,retMinSlew)}; + } + + private float linearInterpolate(float slew_in, float slew1, float slew2, float data1, float data2){ + if(slew1==slew2) + return data1; + else + return (slew_in-slew1)*(data2-data1)/(slew2-slew1) + data1; + } + + /** + * Calculate the delay and output slew for a transition given the input + * slew using back-annotated measured_delay directives. The + * result is interpolated when there is no data point for the input slew. + * (unit used in return data is ps) + * @param cell the cell containing the target + * @param target the node that is affected by the transition + * @param trigger the node that caused the transition + * @param inputSlew the input slew rate + * @param useMin if true returns the minimum delay, otherwise + * the maximum delay + * @param targetDirection true means target is + * rising, false means target is falling. + **/ + public MaxMinFloat[] extract(final String cell_name, + final String target_net, + final String trigger_net, + final MaxMinFloat inSlew, + final boolean targetDirection) throws Exception { + CellInterface cell; + if(errorCells.contains(cell_name)) return null; + final String cn = (cell_name.equals(topCellName) ? plt : "plt")+"."+cell_name; + try { + cell = castFileParser.getFullyQualifiedCell(cn); + } catch (Exception e) { + printErr("WARNING: " + "no file found for " + cn + "\n", errFile); + errorCells.add(cell_name); + return null; + } + + Map dirs = (Map) dirCache.get(cell_name); + if(dirs == null){ + dirs = DirectiveUtils.getMultipleBlockDirective( + Arrays.asList(new BlockInterface[] { + DirectiveUtils.getUniqueBlock(cell.getBlockInterface(), + BlockInterface.PRS), + DirectiveUtils.getUniqueBlock(cell.getBlockInterface(), + BlockInterface.SUBCELL) + }), + DirectiveConstants.MEASURED_DELAY, + DirectiveTable.arrayify(DirectiveConstants.UNCHECKED_HALFOP_TYPE)); + dirCache.put(cell_name,dirs); + } + HierName target = HierName.makeHierName(target_net,'.'); + HierName trigger = HierName.makeHierName(trigger_net,'.'); + final Pair targetOp = + new Pair(target, Boolean.valueOf(targetDirection)); + final Pair triggerOp = + new Pair(trigger, Boolean.valueOf(!targetDirection)); + + List vals = (List) dirs.get(Arrays.asList(new Pair[] { targetOp, triggerOp })); + if (vals == null) { + vals = (List) dirs.get(Collections.singletonList(targetOp)); + } + + if (vals != null) { + final int model = + Math.round(((Float) ((List) vals.get(0)).get(0)).floatValue()); + if (model == Rule.LINEAR_MODEL) { + SortedSet slews = new TreeSet((List) vals.get(1)); + String transition_info = cell_name + "{" + + target_net + (targetDirection?"+":"-") + "," + + trigger_net + (targetDirection?"-":"+") + "}"; + if(inSlew.max > ((Float) slews.last()).floatValue()){ + printErr("WARNING: " + transition_info + + " Input slew rate " + inSlew.max + + " is slower than slowest simulated point " + slews.last() + + "\n", errFile); + } + if(inSlew.min < ((Float) slews.first()).floatValue()){ + printErr("WARNING: " + transition_info + + " Input slew rate " + inSlew.min + + " is faster than fastest simulated point " + slews.first() + + "\n", errFile); + } + return interpolate(vals, inSlew); + } + } + return null; + } + } + + public void updateInterPathSlew(final HierNetName hnet, MaxMinFloat slew, boolean direction){ + InterPathSlew ips = (InterPathSlew) interPathSlew.get(hnet); + if(ips == null){ + ips = new InterPathSlew(); + interPathSlew.put(hnet,ips); + } + ips.updateNext(slew,direction); + } + + public void shiftInterPathSlew(){ + for(Iterator ips_v_i=interPathSlew.values().iterator();ips_v_i.hasNext();){ + InterPathSlew ips_v = (InterPathSlew) ips_v_i.next(); + ips_v.shift(); + } + } + + public void debugElement(final Element e){ + try { + Format outformat = Format.getCompactFormat(); + outformat.setIndent(" "); + outformat.setLineSeparator("\n"); + XMLOutputter serializer = new XMLOutputter(outformat); + + serializer.output(e, System.err); + System.err.println(""); + } catch (Exception exc){ + System.err.println(exc); + } + } + + abstract class JtimerContentHandler implements ContentHandler { + public Locator locator; + public LinkedList stack_e; + public void setDocumentLocator(Locator locator){ + this.locator = locator; + } + public void startDocument() throws SAXException { + stack_e = new LinkedList(); + } + public void endDocument() throws SAXException { + } + public void processingInstruction(String target, String data) + throws SAXException { + } + public void startPrefixMapping(String prefix, String uri) { + } + public void endPrefixMapping(String prefix) { + } + public void startElement(String namespaceURI, String localName, + String rawName, Attributes atts) + throws SAXException { + if(localName.equals("TIMING_PATHS")) + return; + Element top= new Element(localName); + for (int i=0; i (defaults to .)\n" + + " --cell= (fully qualified cell name)\n" + + " --fulcrum-pdk-root= (path to pdk root)\n" + + " --tau= (tau, default to 53)\n" + + " [--cast-version=[ 1 | 2 ]] (defaults to 2)\n" + + " [--depth=<-1> (defaults to -1, max depth)\n" + + " [--verbose (progress messages)\n" + + " [--skip-path-generation] (use the generated path file)\n" + + " [--path-generation-only] (only generate the path file)\n" + + " [--skip-cell= (defaults to empty) no paths analysized for these cells\n" + + " [--skip-cell-jauto= (defaults to empty) the cells are ignored by Jauto\n" + + " [--iteration-number=<1>] (times the previous path slew propagates,default 1)\n" + + " [--iteration-threshold=<1>] (slew progagates only when the slew differs more than, default 1 ps)\n" + + " [ --max-slew=<250>] (max slew, defaults to 250)\n" + + " [ --use-interface-file] (use interface file)\n" + + " [ --input-slew-up= ] (input slew for rising, defaults to 30)\n" + + " [ --input-slew-down= ] (input slew for falling, defaults to 30)\n"); + } + + public Jtimer(String[] args) throws Exception { + theArgs = commandLineProcess(args); + allPaths = theArgs.argExists("allpaths"); + ignoreReset = ! theArgs.argExists("include-reset"); + castRoot = theArgs.getArgValue("cast-path", "."); + fulcrumPdkRoot = theArgs.getArgValue("fulcrum-pdk-root", "."); + castVersion = theArgs.getArgValue("cast-version", "2"); + depth = Integer.parseInt(theArgs.getArgValue("depth","-1")); + if(depth < 0) + depth = -1; + maxSlew = Float.parseFloat(theArgs.getArgValue("max-slew", "250")); + defaultInputSlewUp = Float.parseFloat(theArgs.getArgValue("input-slew-up", "20")); + defaultInputSlewDown = Float.parseFloat(theArgs.getArgValue("input-slew-down", "20")); + iterationNumber = Integer.parseInt(theArgs.getArgValue("iteration-number","2")); + DebugOption.printLevel = Integer.parseInt(theArgs.getArgValue("debug-level","10")); + iterationThreshold = Float.parseFloat(theArgs.getArgValue("iteration-threshold","1.0")); + //routed = theArgs.argExists("routed"); + skipPathGeneration = theArgs.argExists("skip-path-generation"); + pathGenerationOnly = theArgs.argExists("path-generation-only"); + useInterfaceFile = theArgs.argExists("useInterfaceFile"); + slackFileName = theArgs.getArgValue("slack-file", "/dev/null"); + if (theArgs.argExists("verbose") || DebugOption.printLevel < 10) + verbose = true; + + topCellName = theArgs.getArgValue("cell", null); + if (topCellName == null) { + System.err.println("ERROR: You must specify a cell name."); + usage(); + System.exit(-1); + } + + String tau_s = theArgs.getArgValue("tau",null); + if(tau_s == null){ + System.err.println("WARNING: tau is not specified, used the default number 53"); + tau_s = "53"; + } + tau=(float) (Float.parseFloat(tau_s)); + + errFile = new BufferedWriter(new FileWriter(topCellName+".err")); + + timingPathMeasuredList = new HashMap(); + interPathSlew = new HashMap(); + ioSlew = new HashMap(); + + String skip_cells = theArgs.getArgValue("skip-cell", null); + skipCells = new HashSet(); + if(skip_cells != null) { + final StringTokenizer tokenizer = new StringTokenizer(skip_cells, "," ); + while ( tokenizer.hasMoreTokens() ) { + final String cell_name = tokenizer.nextToken(); + skipCells.add(cell_name); + } + } + + String skip_cells_jauto = theArgs.getArgValue("skip-cell-jauto", null); + plt = theArgs.getArgValue("prefix", "plt"); + skipCellsJauto = new HashSet(); + if(skip_cells_jauto != null) { + final StringTokenizer tokenizer = new StringTokenizer(skip_cells_jauto, "," ); + while ( tokenizer.hasMoreTokens() ) { + final String cell_name = tokenizer.nextToken(); + skipCellsJauto.add(cell_name); + } + } + + printStats("Args"); + } + + private CommandLineArgs commandLineProcess(String[] args) { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + final CommandLineArgs theArgs = cachedArgs; + return theArgs; + } + + public static void main(String[] args) throws Exception { + Jtimer jtimer = null; + DebugOption.printLevel = 10; + try { + if (verbose) System.err.println(Calendar.getInstance().getTime()); + jtimer = new Jtimer(args); + jtimer.pathGeneration(); + jtimer.checkTiming(); + jtimer.report(); + } + catch (Exception e){ + throw new RuntimeException(e); + } + finally { + printStats("Total"); + if(jtimer != null){ + jtimer.errFile.close(); + } + if (verbose) System.err.println(Calendar.getInstance().getTime()); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/LeafSpec.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/LeafSpec.java new file mode 100644 index 0000000000..eaa64f7147 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/LeafSpec.java @@ -0,0 +1,425 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.lang.NumberFormatException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import com.avlsi.util.container.SortingIterator; + +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.ArrayType; +import com.avlsi.fast.ports.StructureType; +import com.avlsi.fast.ports.PortTypeInterface; + +import com.avlsi.file.common.HierName; +import com.avlsi.io.FileSearchPath; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.jauto.SubtypeOutput; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.Pair; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.SemanticWrapperException; + + +/** + * A class that generates a new cast description incorporating the cell + * which was given as the --cell arg + **/ +public final class LeafSpec { + /** + * This class should not be instantiated. + **/ + private LeafSpec() { } + + private static void usage( String m ) { + System.err.print( +"Usage: leafspec\n" + +" --cast-path= (defaults to .)\n" + +" --cast-version=[ 1 | 2 ] (defaults to 2)\n" + +" --config= (file containing options)\n" + +" --cellName= (fully qualified cell name)\n" + +" [ --wireLoad= (Load in m)\n" + +" [ --wireDrive= (Drive load in m)\n" + +" [ --translate=(cadence | gdsII) ] (for hierarchical tasks)\n" + +" [ --output-cast= ] (write result to file instead of standard out)\n" + +" [ --module-name= ] (the module name)\n" + +//"(see http://internal/tree/sw/cad/doc/specs/misc/LeafSpec.txt)\n"); +""); + if (m != null && m.length() > 0) + System.err.print( m ); + System.exit(1); + } + + private static void usage() { + usage( null ); + } + + /** + * Returns the string representation of an non-arrayed type. + **/ + private static String nonArrayTypeString(final PortTypeInterface type) { + if (type instanceof ChannelType) { + final ChannelType channel = (ChannelType) type; + final int width = channel.getWidth(); + if (channel.isArrayed()) { + return channel.getTypeName() + "[" + width + "]"; + } else { + assert width == 1; + return channel.getTypeName(); + } + } else if (type instanceof NodeType) { + final NodeType node = (NodeType) type; + final int width = node.getWidth(); + if (node.isArrayed()) { + return "node[" + width + "]"; + } else { + assert width == 1; + return "node"; + } + } else if (type instanceof StructureType) { + final String tag = ((StructureType) type).getTag(); + if (tag == null) return type.toString(); + else return tag; + } else { + throw new RuntimeException("Unknown non-arrayed type "+ + type.getClass()+"!"); + } + } + + /** + * Generate a correct port definition string + * @param port is a port definition + * @param cell is the cell in the overloaded function + **/ + private static String portString (final PortDefinition pd, + final CellInterface cell) { + if (cell.isImpliedPort(pd.getName())) return null; + return SubtypeOutput.portString(pd, false); + /* + int x; + while ((x = result.indexOf("standard.channel.")) >= 0) { + result.delete(x,x+17); + } + return result.toString(); + */ + } + + /** + * Print out the new cast file wirelength directives associated + * with them. + **/ + private static void writeWrap(final CastFileParser cfp, + double wireload, double wiredrive, + final Cadencize cad, String module, final CellInterface cell, + final BufferedWriter w ) throws IOException { + + w.write("/*"); + w.newLine(); + w.write("Type "+cell.getType()); + w.newLine(); + w.write("Filename "+cell.getFilename()); + w.newLine(); + String fqt = cell.getFullyQualifiedType().toString(); + w.write("Fully Qualified Type "+fqt); + w.newLine(); + w.write("*/"); + w.newLine(); + w.write("module "+module+";"); + w.newLine(); + w.write("import "+fqt+";"); + w.newLine(); + w.write("define TEST_"+cell.getType()+" ()() {"); + w.newLine(); + w.write(" subcells {"); + w.newLine(); + final Map mp = CellUtils.markPorts(cell); + + final PartialExtract.LeafCallback cb = null; + + /** + * write the port declarations from the leaf cell + **/ + for (Iterator p = cell.getPortDefinitions(); p.hasNext(); ) { + String s = portString ((PortDefinition) p.next(), cell); + if (s != null) { + w.write(" "+s+";"); + w.newLine(); + } + } + /** + * Write the inverters which are the load and drive + **/ + final CadenceInfo cinfo = cad.convert(cell); + final AliasedMap ports = cinfo.getPortNodes(); + int nodenr = 0; + for (Iterator i = new SortingIterator(ports.getKeys()); + i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + final String s = canon.getCadenceString(); + if ( mp.containsKey(s) && !cell.isImpliedPort(s)) { + int s1 = Integer.parseInt((mp.get(s)).toString()); + if (s1 == PortDefinition.IN) { + w.write(" INVDRIVE _inst"+nodenr+" (_, "+s+");"); + w.newLine(); + } + else if (s1 == PortDefinition.OUT || s1 == PortDefinition.INOUT) { + w.write(" INVLOAD _inst"+nodenr+" ("+s+", _);"); + w.newLine(); + } + else { + } + nodenr++; + } + } + // write the leaf cell itself + w.write(" "+cell.getType()+" _dut("); + int cnt=0; + for (Iterator p = cell.getPortDefinitions(); p.hasNext(); ) { + final PortDefinition pd = (PortDefinition) p.next(); + String sn = pd.getName(); + if (!cell.isImpliedPort(sn)) { + if (cnt == 0) { + w.write(sn); + } + else { + w.write(","+sn); + } + cnt++; + } + } + w.write(");"); + w.newLine(); + // Subcells Directives which are just the wire lengths + w.write(" directives {"); + w.newLine(); + nodenr = 0; + for (Iterator i = new SortingIterator(ports.getKeys()); + i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + final String s = canon.getCadenceString(); + if ( mp.containsKey(s) && !cell.isImpliedPort(s)) { + int s1 = Integer.parseInt((mp.get(s)).toString()); + if (s1 == PortDefinition.IN) { + w.write(" wirelength("+s+")="+wiredrive+";"); + w.newLine(); + } + else if (s1 == PortDefinition.OUT || s1 == PortDefinition.INOUT) { + w.write(" wirelength("+s+")="+wireload+";"); + w.newLine(); + } + else { + } + nodenr++; + } + } + w.write(" }"); // end directives + w.newLine(); + w.write(" }"); // end subcells + w.newLine(); + /** XXX + * Do we want this? + **/ + w.write(" directives {"); + w.newLine(); + w.write(" unimplementable=true;"); + w.newLine(); + w.write(" }"); + w.newLine(); + w.write("}"); // end cell + w.newLine(); + } + + /** + * Write the inverters, this writes both drive and load inverters + **/ + private static void writeInverter (String name, BufferedWriter w) + throws IOException { + w.newLine(); + w.write("define "+name+" ()(node -I, +O) {"); + w.newLine(); + w.write(" prs {"); + w.newLine(); + w.write(" I => O-"); + w.newLine(); + w.write(" }"); + w.newLine(); + w.write(" directives {"); + w.newLine(); + w.write(" unimplementable=true;"); + w.newLine(); + w.write(" cellnonobservable=true;"); + w.newLine(); + w.write(" }"); + w.newLine(); + w.write("}"); + w.newLine(); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + final String module = theArgs.getArgValue("module-name", "wrap.ttt"); + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cellName", null); + String output = theArgs.getArgValue("output-cast", null); + final String wireLoad = theArgs.getArgValue("wireLoad", "0.00001"); + final String wireDrive = theArgs.getArgValue("wireDrive", "0.00001"); + String widthDrivePlus = null; + String widthDriveMinus = null; + String widthLoad = null; + if (theArgs.argExists("widthDrivePlus")) { + widthDrivePlus = theArgs.getArgValue("widthDrivePlus", "1.0e-6"); + } + else { + widthDrivePlus = theArgs.getArgValue("widthDrive", "1.0e-6"); + } + if (theArgs.argExists("widthDriveMinus")) { + widthDriveMinus = theArgs.getArgValue("widthDriveMinus", "1.0e-6"); + } + else { + widthDriveMinus = theArgs.getArgValue("widthDrive", "1.0e-6"); + } + widthLoad = theArgs.getArgValue("widthLoad", "1.0e-6"); + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString( + LeafSpec.class)); + } + + pedanticArgs.argTag( "widthDrivePlus" ); + pedanticArgs.argTag( "widthDriveMinus" ); + pedanticArgs.argTag( "widthDrive" ); + + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + usage( pedanticArgs.pedanticString() ); + } + + + if (cellName == null) { + usage("ERROR: You must specify a cell name.\n"); + } + + final CastFileParser castParser = + new CastFileParser(new FileSearchPath(castRoot), castVersion); + + CellInterface rootCell = null; + try { + rootCell = castParser.getFullyQualifiedCell( cellName ); + } catch (CastSemanticException e) { + StackTraceElement ste[] = e.getStackTrace(); + System.err.println("Cell "+cellName+" not found at "+ + ste[ste.length-1].toString()); + System.exit(1); + } + + double wireload = 0.0; + double wiredrive = 0.0; + double widthload = 0.0; + double widthdriveplus = 0.0; + double widthdriveminus = 0.0; + int ecnt = 0; + try { + wireload = Double.parseDouble(wireLoad); + } catch (NumberFormatException e) { + System.err.println("wireLoad="+wireLoad+" number format exception!"); + ecnt++; + } + try { + wiredrive = Double.parseDouble(wireDrive); + } catch (NumberFormatException e) { + System.err.println("wireDrive="+wireDrive+" number format exception!"); + ecnt++; + } + try { + widthdriveplus = Double.parseDouble(widthDrivePlus); + } catch (NumberFormatException e) { + System.err.println("widthDrivePlus="+widthDrivePlus+" number format exception!"); + ecnt++; + } + try { + widthdriveminus = Double.parseDouble(widthDriveMinus); + } catch (NumberFormatException e) { + System.err.println("widthDriveMinus="+widthDriveMinus+" number format exception!"); + ecnt++; + } + try { + widthload = Double.parseDouble(widthLoad); + } catch (NumberFormatException e) { + System.err.println("widthLoad="+widthLoad+" number format exception!"); + ecnt++; + } + if (ecnt > 0) { + System.err.println("Aborting..."); + System.exit (1); + } + if (output != null) { + File fp = new File(output); + fp = fp.getAbsoluteFile(); + File dir = fp.getParentFile(); + if (! dir.exists() && ! dir.mkdirs()) { + System.err.println("Cannot create and/or write to "+ + dir.toString()+"!"); + System.exit(1); + } + if (! dir.canWrite()) { + System.err.println("Cannot create and/or write to "+ + dir.toString()+"!"); + System.exit(1); + } + } + final Writer w = output == null ? + new OutputStreamWriter(System.out) : + new FileWriter(output); + + final BufferedWriter wr = new BufferedWriter( w ) ; + writeWrap( castParser, wireload, wiredrive, new Cadencize(true), + module, rootCell, wr ); + writeInverter("INVLOAD", wr ); + writeInverter("INVDRIVE", wr); + wr.close(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/MergeHint.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/MergeHint.java new file mode 100644 index 0000000000..eb1a0472ad --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/MergeHint.java @@ -0,0 +1,1389 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeSet; +import java.util.TreeMap; + +import com.avlsi.cast.CastCacheManager; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveComparator; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.util.DirectiveActionFilter; +import com.avlsi.cast2.util.DirectiveActionInterface; +import com.avlsi.cast2.util.DirectiveFilter; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.InstanceTrace; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.file.cdl.parser.CDLSimpleFilter; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.common.HierName; +import com.avlsi.geometry.BoundingBox; +import com.avlsi.geometry.Point; +import com.avlsi.io.FileSearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsIterator; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.StringUtil; + +public final class MergeHint { + private MergeHint() { + throw new AssertionError(); + } + private static void usage() { + System.err.print( + "java com.avlsi.tools.jauto.MergeHint\n" + + "\t[ --cast-path= (defaults to .) ]\n" + + "\t[ --cast-version=[ 1 | 2 ] (defaults to 2) ]\n" + + "\t--cell= (top level cell)\n" + + "\t[ --many (read arguments from stdin) ]\n" + + "\t[\n" + + "\t--max-width-diff= (maximum difference in widths)\n" + + "\t--max-avg-width-diff= (maximum average difference in widths)\n" + + "\t--max-fixed-width-diff= (defaults to max-width)\n" + + "\t--max-fixed-avg-width-diff= (defaults to avg-width) ]\n" + + "\t]\n" + + "\t[ --threshold= (parameter for new distance function) ]\n" + + "\t[\n" + + "\t--max-width-ratio= (maximum ratio of widths)\n" + + "\t--max-fixed-width-ratio= (defaults to max-ratio)\n" + + "\t]\n" + + "\t[ --directive (only merge cells with compatible directives) ]\n" + + "\t[ --merge_target= (also merge against listed cells) ]\n" + + "\t[ --instance-dir= (choose smallest cell when several possible ]\n" + + "\t[\n" + + "\t --merge-cells= (only merge listed cells)\n" + + "\t| --exclude-cells= (exclude listed cells)\n" + + "\t]\n" + ); + System.exit(1); + } + + private static final Map prefix = new HashMap(); + static { + prefix.put(new Character('f'), new Double(1e-15)); + prefix.put(new Character('p'), new Double(1e-12)); + prefix.put(new Character('n'), new Double(1e-9)); + prefix.put(new Character('u'), new Double(1e-6)); + prefix.put(new Character('m'), new Double(1e-3)); + prefix.put(new Character('k'), new Double(1e3)); + prefix.put(new Character('M'), new Double(1e6)); + prefix.put(new Character('G'), new Double(1e9)); + prefix.put(new Character('T'), new Double(1e12)); + } + + private static Double getDoubleValue(String arg) { + if (arg == null) return null; + + Double scale = null; + for (int i = 0; i < arg.length(); ++i) { + final char c = arg.charAt(i); + if (Character.isLetter(c)) { + scale = (Double) prefix.get(new Character(c)); + if (scale != null) { + arg = arg.substring(0, i); + break; + } + } + } + + try { + double value = Double.parseDouble(arg); + return new Double(scale == null ? value : value * scale.doubleValue()); + } catch (NumberFormatException e) { + return null; + } + } + + private static Double getDoubleValue(String arg, Double def) { + final Double result = getDoubleValue(arg); + return result == null ? def : result; + } + + private static Double getDoubleValue(final CommandLineArgs args, + final String arg, + final Double def) { + return getDoubleValue(args.getArgValue(arg, null), def); + } + + private static void prepare(final CellInterface cell, + final SortedMap typeMap, + final Set seen, + final InstanceTrace it) { + if (CellUtils.isWiring(cell)) return; + + final String type = cell.getFullyQualifiedType(); + if (!seen.add(type)) return; + + if (CellUtils.isLeaf(cell)) { + if (cell.containsNetlist()) { + final int index = type.lastIndexOf('.'); + final String base = type.substring(0, index); + final String subtype = type.substring(index + 1); + + if (!typeMap.containsKey(base)) { + typeMap.put(base, new TreeMap()); + } + final SortedMap subtypeMap = (SortedMap) typeMap.get(base); + if (subtypeMap.containsKey(subtype)) return; + subtypeMap.put(subtype, new Pair(cell, subtype)); + } else { + if (!CellUtils.isInternalEnv(cell)) { + System.err.println("WARNING: No netlist block"); + System.err.print(it); + } + } + } + + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName instName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + it.enter(subcell.getFullyQualifiedType(), + instName.getAsString('.')); + prepare(subcell, typeMap, seen, it); + it.leave(); + } + } + + private static void prepare(final CellInterface cell, + final SortedMap typeMap) { + final InstanceTrace it = new InstanceTrace(); + it.enter(cell.getFullyQualifiedType(), "top level"); + prepare(cell, typeMap, new HashSet(), it); + it.leave(); + } + + private static void instance(final CellInterface cell, + final Map instanceMap) { + if (CellUtils.isWiring(cell)) return; + + final String type = cell.getFullyQualifiedType(); + + if (instanceMap.containsKey(type)) { + final int val = ((Integer) instanceMap.get(type)).intValue(); + instanceMap.put(type, new Integer(val + 1)); + } else { + instanceMap.put(type, new Integer(1)); + } + + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + instance(subcell, instanceMap); + } + } + + private static HashMap cache = new HashMap(); + private static CastFileParser cfp = null; + private static CDLSimpleFilter ignoreStaticizer = null; + private static class StaticizerFilter extends CDLSimpleFilter { + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters) { + try { + final CellInterface ci = cfp.getFullyQualifiedCell(subName); + if (((Boolean) DirectiveUtils.getTopLevelDirective(ci, + DirectiveConstants.STATICIZER_GATE)).booleanValue()) + return; + } catch (Exception e) { + } + super.makeCall(name, subName, args, parameters); + } + } + private static NetlistDistance.CompiledForm getCompiledForm(CellInterface c) + { + final NetlistDistance.CompiledForm cf; + if (cache.containsKey(c)) { + cf = (NetlistDistance.CompiledForm) cache.get(c); + } else { + cf = NetlistDistance.getCompiledForm(c, ignoreStaticizer, cfp); + cache.put(c, cf); + } + return cf; + } + + private interface Cluster { + /** + * Returns the score of adding cell to this cluster. A + * large score will make it more like the cell will be added to this + * cluster. + * @return Score of adding the cell, or null if the cell + * cannot be added. + **/ + Double score(final CellInterface cell); + + /** + * Add cell to this cluster. + * @param cell Cell to add + * @param subtype Subtype of the cell + **/ + void add(final CellInterface cell, final String subtype); + + /** + * Returns the canonical subtype of this cluster. + **/ + String canonical(); + + /** + * Returns an iterator over subtypes that are part of this cluster, not + * including the canonical subtype. + **/ + Iterator iterator(); + + /** + * Returns the number of subtypes that are part of this cluster, not + * including the canonical subtype. + **/ + int size(); + } + + private interface ClusterFactory { + /** + * Returns a new cluster. + **/ + Cluster create(final CellInterface cell, final String subtype); + } + + private interface Selector { + /** + * Given a number of clusters that a subtype might merge to, return the + * one that is most appropriate. + **/ + Cluster select(final String type, final SortedMap scoreMap); + } + + private static class ScoreSelector implements Selector { + public Cluster select(final String type, final SortedMap scoreMap) { + final Double minScore = (Double) scoreMap.firstKey(); + return (Cluster) ((List) scoreMap.get(minScore)).get(0); + } + } + + private static class SizeSelector implements Selector { + private final File dir; + private final Map cache; + private final Selector fallback; + public SizeSelector(final File dir) { + this.dir = dir; + this.cache = new HashMap(); + this.fallback = new ScoreSelector(); + } + private BoundingBox getBoundingBox(final String type) + throws IOException, CDLRenameException { + if (!cache.containsKey(type)) { + final File fp = + new File(dir, Floorplan.getInstanceFilename(type)); + final Reader rin = new BufferedReader(new FileReader(fp)); + Floorplan.readHierarchy(rin, + new SubcellProcessor() { + public void process(final BoundingBox bBox) { + cache.put(type, bBox); + } + public void process(String pinName, BoundingBox bBox) + { } + public void process(String typeName, + String instanceName, + int orientation, BoundingBox bBox) + { } + }); + rin.close(); + } + return (BoundingBox) cache.get(type); + } + private double getArea(final BoundingBox bBox) { + return bBox.getWidth() * bBox.getHeight(); + } + public Cluster select(final String type, final SortedMap scoreMap) { + if (scoreMap.size() == 1 && + ((List) scoreMap.get(scoreMap.firstKey())).size() == 1) { + return (Cluster) ((List) scoreMap.get(scoreMap.firstKey())).get(0); + } else { + double minArea = Double.MAX_VALUE; + Cluster minCluster = null; + for (Iterator i = scoreMap.entrySet().iterator(); i.hasNext(); ) + { + final Map.Entry entry = (Map.Entry) i.next(); + final List clusters = (List) entry.getValue(); + + for (Iterator j = clusters.iterator(); j.hasNext(); ) { + final Cluster cluster = (Cluster) j.next(); + final String fulltype = type + "." + cluster.canonical(); + final BoundingBox bbox; + try { + bbox = getBoundingBox(fulltype); + } catch (IOException e) { + System.err.println("Error reading instances file for " + fulltype + ": " + e); + continue; + } catch (CDLRenameException e) { + System.err.println("Cannot translate " + fulltype + + " to Cadence name:" + e); + continue; + } + if (bbox == null) { + System.err.println("Instances file for " + fulltype + " does not contain a bounding box"); + continue; + } + + final double area = getArea(bbox); + if (area < minArea) { + minArea = area; + minCluster = cluster; + } + } + } + if (minCluster == null) { + return fallback.select(type, scoreMap); + } else { + return minCluster; + } + } + } + } + + /** + * The stage 2 distance function. + **/ + private static final class SimpleCluster implements Cluster { + private final NetlistDistance.CompiledForm canonical; + private final String subtype; + private final List subtypes; + private final double D_a_max, D_m_max; + private static final double S = 0.5; + + private SimpleCluster(final CellInterface cell, final String subtype, + final double D_a_max, final double D_m_max) { + canonical = getCompiledForm(cell); + this.subtype = subtype; + this.subtypes = new ArrayList(); + this.D_a_max = D_a_max; + this.D_m_max = D_m_max; + } + + public Double score(final CellInterface cell) { + final NetlistDistance.CompiledForm cf = getCompiledForm(cell); + final NetlistDistance.DefaultCalculator dc = + new NetlistDistance.DefaultCalculator(); + + NetlistDistance.getDistance(canonical, cf, dc); + + final Pair p = dc.getResult(); + if (p == null) { + return null; + } else { + final double D_a = ((Double) p.getFirst()).doubleValue(); + final double D_m = ((Double) p.getSecond()).doubleValue(); + if (D_a <= D_a_max && D_m <= D_m_max) + return new Double(S * D_a + (1 - S) * D_m); + else + return null; + } + } + + public void add(final CellInterface cell, final String subtype) { + subtypes.add(subtype); + } + + public String canonical() { + return subtype; + } + + public Iterator iterator() { + return subtypes.iterator(); + } + + public int size() { + return subtypes.size(); + } + + public static ClusterFactory getFactory(final double avg, + final double max, + final double fixedAvg, + final double fixedMax) { + return new ClusterFactory() { + public Cluster create(final CellInterface cell, + final String subtype) { + final double D_m_max, D_a_max; + if (CellUtils.isFixedSize(cell)) { + D_m_max = fixedMax; + D_a_max = fixedAvg; + } else { + D_m_max = max; + D_a_max = avg; + } + return new SimpleCluster(cell, subtype, D_a_max, D_m_max); + } + }; + } + } + + private static abstract class SimpleMergePolicy implements NetlistDistance.CompiledForm.MergePolicy { + public abstract double transistor(final double widthR, + final double widthS); + public Map gate(final String type, final Map paramsR, + final Map paramsS) { + final Map result = new HashMap(); + for (Iterator i = paramsR.entrySet().iterator(); i.hasNext(); ) + { + final Map.Entry entry = (Map.Entry) i.next(); + final Double r = (Double) entry.getValue(); + final Double s = (Double) paramsS.get(entry.getKey()); + final Double d = new Double(transistor(r.doubleValue(), s.doubleValue())); + result.put(entry.getKey(), d); + } + return result; + } + } + + private static final class MinMergePolicy extends SimpleMergePolicy { + public double transistor(final double widthR, final double widthS) { + return Math.min(widthR, widthS); + } + } + + private static final class MaxMergePolicy extends SimpleMergePolicy { + public double transistor(final double widthR, final double widthS) { + return Math.max(widthR, widthS); + } + } + + /** + * Cluster that groups by relative size. + **/ + private static final class RatioCluster implements Cluster { + private NetlistDistance.CompiledForm maxCanonical; + private NetlistDistance.CompiledForm minCanonical; + private final String subtype; + private final List subtypes; + private final double D_m_max; + + private static final class Calculator implements NetlistDistance.DistanceCalculator { + private double score; + public Calculator() { + this.score = 0; + } + + public void transistor(final double widthR, final double widthS) { + // Skip over evil floating transistors. + if (widthR == 0 && widthS == 0) return; + + // But if only one is zero, then that is an error. + assert widthR != 0 && widthS != 0; + + final double large, small; + if (widthR > widthS) { + large = widthR; + small = widthS; + } else { + small = widthR; + large = widthS; + } + score = Math.max(score, large / small); + } + + public void gate(final String type, final Map paramsR, + final Map paramsS) { + for (Iterator i = paramsR.entrySet().iterator(); i.hasNext(); ) + { + final Map.Entry entry = (Map.Entry) i.next(); + final Double r = (Double) entry.getValue(); + final Double s = (Double) paramsS.get(entry.getKey()); + transistor(r.doubleValue(), s.doubleValue()); + } + } + + public void mismatch() { + score = Double.NaN; + } + + public Double getResult() { + return Double.isNaN(score) ? null : new Double(score); + } + } + + private RatioCluster(final CellInterface cell, final String subtype, + final double D_m_max) { + maxCanonical = minCanonical = getCompiledForm(cell); + this.subtype = subtype; + this.subtypes = new ArrayList(); + this.D_m_max = D_m_max; + } + + public Double score(final CellInterface cell) { + final NetlistDistance.CompiledForm cf = getCompiledForm(cell); + + final Calculator minCalc = new Calculator(); + NetlistDistance.getDistance(minCanonical, cf, minCalc); + final Double minResult = minCalc.getResult(); + if (minResult == null || minResult.doubleValue() >= D_m_max) { + return null; + } + + final Calculator maxCalc = new Calculator(); + NetlistDistance.getDistance(maxCanonical, cf, maxCalc); + final Double maxResult = maxCalc.getResult(); + if (maxResult == null || maxResult.doubleValue() >= D_m_max) { + return null; + } else { + return maxResult; + } + } + + public void add(final CellInterface cell, final String subtype) { + final NetlistDistance.CompiledForm cf = getCompiledForm(cell); + minCanonical = NetlistDistance.CompiledForm.merge(minCanonical, cf, new MinMergePolicy()); + maxCanonical = NetlistDistance.CompiledForm.merge(maxCanonical, cf, new MaxMergePolicy()); + subtypes.add(subtype); + } + + public String canonical() { + return subtype; + } + + public Iterator iterator() { + return subtypes.iterator(); + } + + public int size() { + return subtypes.size(); + } + + public static ClusterFactory getFactory(final double max, + final double fixedMax) { + return new ClusterFactory() { + public Cluster create(final CellInterface cell, + final String subtype) { + final double D_m_max; + if (CellUtils.isFixedSize(cell)) { + D_m_max = fixedMax; + } else { + D_m_max = max; + } + return new RatioCluster(cell, subtype, D_m_max); + } + }; + } + } + + /** + * Cluster that groups by directive equivalence. In particular, it + * compares that directives in the PRS blocks, and directives in the + * top-level cells are equivalent. Certain directives require special + * action, and are exempt from the equivalence check: + *

      + *
    • fixed_size: ignored when comparing directives. + *
    • density_scale_factor: when merging A to B, B's value + * of this directive must less or equal to A's. See + * bug 2042. + *
    + **/ + private static final class DirectiveCluster implements Cluster { + private final static Double OKAY = new Double(0); + private static final Set RELEVANT = (Set) + CollectionUtils.addAll( + new HashSet(), + DirectiveConstants.HEIGHT, + DirectiveConstants.WIDTH, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.EXTRA_DELAY, + DirectiveConstants.DEFAULT_UP_DELAY, + DirectiveConstants.DEFAULT_DN_DELAY, + DirectiveConstants.FRAGMENT, + DirectiveConstants.CELLNONOBSERVABLE, + DirectiveConstants.CUTPATH, + DirectiveConstants.ROUTED); + + private final static DirectiveComparator COMP = + new DirectiveComparator() { + public boolean compare(String block, String type, + Object value1, Object value2) { + if (value1 == null || value2 == null) { + return value1 == value2; + } else { + return value1.equals(value2); + } + } + }; + private final String subtype; + private final List subtypes; + private final CellInterface canonical; + private final Set relevant; + private final Map specialAction; + + private interface SpecialAction { + boolean isMergeable(String block, String type, Object canon, + Object other); + } + + private static class OrAction implements SpecialAction { + private final SpecialAction sa1; + private final SpecialAction sa2; + public OrAction(final SpecialAction sa1, final SpecialAction sa2) { + this.sa1 = sa1; + this.sa2 = sa2; + } + public boolean isMergeable(String block, String type, Object canon, + Object other) { + return sa1.isMergeable(block, type, canon, other) || + sa2.isMergeable(block, type, canon, other); + } + } + + private static class IgnoreAction implements SpecialAction { + public IgnoreAction() { } + public boolean isMergeable(String block, String type, Object canon, + Object other) { + return true; + } + } + + private static class NumberAction implements SpecialAction { + public final static int LT = -1; + public final static int EQ = 0; + public final static int GT = 1; + + private final int relation; + + public NumberAction(final int relation) { + this.relation = relation; + } + + private static int sgn(int x) { + if (x == 0) return 0; + else if (x > 0) return 1; + else return -1; + } + + public boolean isMergeable(String block, String type, Object canon, + Object other) { + final Number n1 = (Number) canon; + final Number n2 = (Number) other; + return relation == + sgn(Double.compare(n1.doubleValue(), n2.doubleValue())); + } + } + + private DirectiveCluster(final CellInterface cell, + final String subtype, + final Set relevant, + final Map specialAction) { + this.subtype = subtype; + this.subtypes = new ArrayList(); + this.canonical = cell; + this.relevant = relevant; + this.specialAction = specialAction; + } + + public Double score(final CellInterface cell) { + // Compare top-level directives + final BlockInterface cb1 = canonical.getBlockInterface(); + final BlockInterface cb2 = cell.getBlockInterface(); + final DirectiveActionFilter topf = + new DirectiveFilter.ByDirective(true, relevant); + if (!DirectiveUtils.equalDirectiveBlock(cb1, topf, cb2, topf, + COMP)) { + return null; + } + + // Compare PRS directives + final BlockIterator bit1 = cb1.iterator(BlockInterface.PRS); + final BlockIterator bit2 = cb2.iterator(BlockInterface.PRS); + if (bit1.hasNext() != bit2.hasNext()) { + return null; + } + final DirectiveActionFilter prsf = + new DirectiveFilter.ByDirective(true, relevant); + if (bit1.hasNext()) { + final BlockInterface prs1 = bit1.next(); + final BlockInterface prs2 = bit2.next(); + if (!DirectiveUtils.equalDirectiveBlock(prs1, prsf, prs2, prsf, + COMP)) { + return null; + } + } + + // Special actions + for (Iterator i = specialAction.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String key = (String) entry.getKey(); + final Pair p = + DirectiveTable.lookupDirective(BlockInterface.CELL, key); + assert p != null; + + final String valueType = (String) p.getFirst(); + final SpecialAction sa = (SpecialAction) entry.getValue(); + final Object canon = + DirectiveUtils.getTopLevelDirective(canonical, key); + final Object other = + DirectiveUtils.getTopLevelDirective(cell, key); + if (!sa.isMergeable(BlockInterface.CELL, valueType, canon, + other)) { + return null; + } + } + return OKAY; + } + + public void add(final CellInterface cell, final String subtype) { + subtypes.add(subtype); + } + + public String canonical() { + return subtype; + } + + public Iterator iterator() { + return subtypes.iterator(); + } + + public int size() { + return subtypes.size(); + } + + public static ClusterFactory getFactory() { + return new ClusterFactory() { + public Cluster create(final CellInterface cell, + final String subtype) { + return new DirectiveCluster(cell, subtype, RELEVANT, + Collections.EMPTY_MAP); + } + }; + } + } + + /** + * The stage 3 distance function. + **/ + private static final class BetterCluster implements Cluster { + private final Map instancesMap; + private CellInterface cellR; + private NetlistDistance.CompiledForm canonical; + private int instances; + private final String subtype; + private final List subtypes; + private final double threshold; + + private static final class Calculator implements NetlistDistance.DistanceCalculator { + private final int instanceR, instanceS; + private final CellInterface cellR, cellS; + private double score; + + public Calculator(final int instanceR, final int instanceS, + final CellInterface cellR, + final CellInterface cellS) { + this.instanceR = instanceR; + this.instanceS = instanceS; + this.cellR = cellR; + this.cellS = cellS; + this.score = 0; + } + + private double size_est(final double widthR, final double widthS) { + return Math.max(widthR, widthS); + } + + private double penalty(final CellInterface R, final CellInterface S, + final double widthR, final double widthS) { + // Do not allow fixed size transistors to get larger + /* See bug 3380 + if (CellUtils.isFixedSize(R) && widthR < widthS) + return Double.POSITIVE_INFINITY; + else + */ + return 0; + } + + private double layout_cost(final CellInterface R) { + return 1; + } + + public void transistor(final double widthR, final double widthS) { + if (CellUtils.isFixedSize(cellR)) { + score += instanceS * Math.abs(widthR - widthS); + } else { + score += (instanceR + instanceS) * size_est(widthR, widthS) + - instanceR * widthR + - instanceS * widthS + + instanceR * penalty(cellS, cellR, widthS, widthR) + + instanceS * penalty(cellR, cellS, widthR, widthS); + } + } + + public void gate(final String type, final Map paramsR, + final Map paramsS) { + for (Iterator i = paramsR.entrySet().iterator(); i.hasNext(); ) + { + final Map.Entry entry = (Map.Entry) i.next(); + final Double r = (Double) entry.getValue(); + final Double s = (Double) paramsS.get(entry.getKey()); + transistor(r.doubleValue(), s.doubleValue()); + } + } + + public void mismatch() { + score = Double.NaN; + } + + public Double getResult() { + return Double.isNaN(score) ? null : new Double(score / layout_cost(cellR)); + } + } + + private int getInstanceCount(final CellInterface cell) { + return ((Integer) instancesMap.get(cell.getFullyQualifiedType())).intValue(); + } + + private BetterCluster(final CellInterface cell, final String subtype, + final Map instancesMap, final double threshold) { + this.instancesMap = instancesMap; + this.cellR = cell; + this.threshold = threshold; + this.canonical = getCompiledForm(cell); + this.instances = getInstanceCount(cell); + this.subtype = subtype; + this.subtypes = new ArrayList(); + } + + public Double score(final CellInterface cellS) { + final NetlistDistance.CompiledForm cf = getCompiledForm(cellS); + final Calculator calc = + new Calculator(instances, getInstanceCount(cellS), cellR, cellS); + NetlistDistance.getDistance(canonical, cf, calc); + final Double result = calc.getResult(); + if (result == null || result.doubleValue() >= threshold) { + return null; + } else { + return result; + } + } + + public void add(final CellInterface cell, final String subtype) { + if (!CellUtils.isFixedSize(cellR)) { + final NetlistDistance.CompiledForm cf = getCompiledForm(cell); + canonical = NetlistDistance.CompiledForm.merge( + canonical, cf, new MaxMergePolicy()); + instances += getInstanceCount(cell); + } + subtypes.add(subtype); + } + + public String canonical() { + return subtype; + } + + public Iterator iterator() { + return subtypes.iterator(); + } + + public int size() { + return subtypes.size(); + } + + public static ClusterFactory getFactory(final Map instances, + final double threshold) { + return new ClusterFactory() { + public Cluster create(final CellInterface cell, + final String subtype) { + return new BetterCluster(cell, subtype, instances, + threshold); + } + }; + } + } + + /** + * Combines any number of predicate cluster and a single + * scoring cluster into a cluster. Cells are mergeable if all + * predicate clusters agree they are mergeable. The ordering of possible + * merge targets is determined by the scoring cluster. + **/ + private static final class CombinedCluster implements Cluster { + private final Cluster[] predicates; + private final Cluster scorer; + + private CombinedCluster(final CellInterface cell, final String subtype, + final ClusterFactory[] predicateFactory, + final ClusterFactory scorerFactory) { + predicates = new Cluster[predicateFactory.length]; + for (int i = 0; i < predicateFactory.length; ++i) { + predicates[i] = predicateFactory[i].create(cell, subtype); + } + + scorer = scorerFactory.create(cell, subtype); + } + + public Double score(final CellInterface cell) { + for (int i = 0; i < predicates.length; ++i) { + if (predicates[i].score(cell) == null) return null; + } + return scorer.score(cell); + } + + public void add(final CellInterface cell, final String subtype) { + for (int i = 0; i < predicates.length; ++i) { + predicates[i].add(cell, subtype); + } + scorer.add(cell, subtype); + } + + public String canonical() { + return scorer.canonical(); + } + + public Iterator iterator() { + return scorer.iterator(); + } + + public int size() { + return scorer.size(); + } + + public static ClusterFactory getFactory(final ClusterFactory[] preds, + final ClusterFactory scorer) { + return new ClusterFactory() { + public Cluster create(final CellInterface cell, + final String subtype) { + return new CombinedCluster(cell, subtype, preds, scorer); + } + }; + } + } + + private static List analyze(final String type, + final SortedMap subtypeMap, + final ClusterFactory factory, + final Selector selector) { + final List clusters = new ArrayList(); + + // Put each fixed sized subtype into its own new cluster + for (Iterator i = subtypeMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Pair p = (Pair) entry.getValue(); + final CellInterface cell = (CellInterface) p.getFirst(); + if (CellUtils.isFixedSize(cell)) { + clusters.add(factory.create(cell, (String) p.getSecond())); + } + } + + final SortedMap scoreMap = new TreeMap(); + for (Iterator i = subtypeMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Pair p = (Pair) entry.getValue(); + final CellInterface unfixed = (CellInterface) p.getFirst(); + // Skip over fixed sized subtypes which are already in a cluster + if (CellUtils.isFixedSize(unfixed)) continue; + + // Calculate which cluster is the best place for this cell + scoreMap.clear(); + for (int j = 0; j < clusters.size(); ++j) { + final Cluster cluster = (Cluster) clusters.get(j); + final Double s = cluster.score(unfixed); + if (s != null) { + if (!scoreMap.containsKey(s)) + scoreMap.put(s, new ArrayList()); + ((List) scoreMap.get(s)).add(cluster); + } + } + + final String subtype = (String) p.getSecond(); + if (scoreMap.isEmpty()) { + // Wasn't close enough to anything, create a new cluster + clusters.add(factory.create(unfixed, subtype)); + } else { + selector.select(type, scoreMap).add(unfixed, subtype); + } + } + return clusters; + } + + private static void output(final Map mergedMaps, final Writer w) + throws IOException { + for (Iterator i = mergedMaps.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final List clusters = (List) entry.getValue(); + for (int j = 0; j < clusters.size(); ++j) { + final Cluster cluster = (Cluster) clusters.get(j); + final Iterator k = cluster.iterator(); + if (!k.hasNext()) continue; + + w.write((String) entry.getKey()); + w.write(" "); + w.write(cluster.canonical()); + + while (k.hasNext()) { + w.write(" "); + w.write((String) k.next()); + } + + w.write("\n"); + } + } + } + + private static Map process(final SortedMap typeMap, + final ClusterFactory factory, + final Selector selector) { + final Map result = new HashMap(); + for (Iterator i = typeMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final List clusters = + analyze((String) entry.getKey(), (SortedMap) entry.getValue(), + factory, selector); + result.put(entry.getKey(), clusters); + } + return result; + } + + private static void stats(final SortedMap typeMap, + final Map result, + final Writer w) throws IOException { + w.write("# Total number of leaf types: " + typeMap.size() + "\n"); + int subtypes = 0; + int mergedCount = 0; + final Map typeStat = new TreeMap(); + for (Iterator i = typeMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String type = (String) entry.getKey(); + final Map subtypeMap = (Map) entry.getValue(); + final int beforeSize = subtypeMap.size(); + final List clusters = (List) result.get(type); + int merged = 0; + if (clusters != null) { + for (int j = 0; j < clusters.size(); ++j) { + merged += ((Cluster) clusters.get(j)).size(); + } + } + subtypes += beforeSize; + mergedCount += merged; + typeStat.put(type, new Pair(new Integer(beforeSize), + new Integer(beforeSize - merged))); + } + w.write("# Total number of leaf subtypes: " + subtypes + "\n"); + w.write("# Number of leaf cells after merging: " + (subtypes - mergedCount) + "\n"); + for (Iterator i = typeStat.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Pair p = (Pair) entry.getValue(); + w.write("# " + entry.getKey() + " " + p.getFirst() + " " + p.getSecond() + "\n"); + } + } + + private static void process(final SortedMap typeMap, + final ClusterFactory factory, + final Selector selector, + final Writer w) throws IOException { + final Map result = process(typeMap, factory, selector); + stats(typeMap, result, w); + output(result, w); + w.flush(); + } + + private static Pair validArgs(final CommandLineArgs args) { + // Choose one scorer + final Double maxWidth = getDoubleValue(args, "max-width-diff", null); + final Double maxAvg = getDoubleValue(args, "max-avg-width-diff", null); + final Double maxFixedWidth = + getDoubleValue(args, "max-fixed-width-diff", maxWidth); + final Double maxFixedAvg = + getDoubleValue(args, "max-fixed-avg-width-diff", maxAvg); + final boolean simple = maxWidth != null && maxAvg != null && + maxFixedWidth != null && maxFixedAvg != null; + + final Double threshold = getDoubleValue(args, "threshold", null); + + // Only one scoring method can be chosen + if (simple == (threshold != null)) return null; + + final Double[] scorer = simple ? + new Double[] { maxAvg, maxWidth, maxFixedAvg, maxFixedWidth } : + new Double[] { threshold }; + + // Choose a set of predicates + final List pred = new ArrayList(); + + final Double maxRatio = getDoubleValue(args, "max-width-ratio", null); + final Double maxFixedRatio = + getDoubleValue(args, "max-fixed-width-ratio", maxRatio); + if (maxRatio != null && maxFixedRatio != null) { + pred.add(RatioCluster.getFactory(maxRatio.doubleValue(), + maxFixedRatio.doubleValue())); + } + + final boolean directive = args.argExists("directive"); + if (directive) { + pred.add(DirectiveCluster.getFactory()); + } + + return new Pair(scorer, (ClusterFactory[]) pred.toArray(new ClusterFactory[0])); + } + + private static ClusterFactory getFactory(final Pair distanceType, + final CommandLineArgs args, + final CellInterface[] cells, + final Map instanceMap) { + final ClusterFactory scorer; + + final Double[] scorerArgs = (Double[]) distanceType.getFirst(); + if (scorerArgs.length == 4) { + scorer = SimpleCluster.getFactory(scorerArgs[0].doubleValue(), + scorerArgs[1].doubleValue(), + scorerArgs[2].doubleValue(), + scorerArgs[3].doubleValue()); + } else { + if (instanceMap.isEmpty()) { + for (int i = 0; i < cells.length; ++i) { + instance(cells[i], instanceMap); + } + } + scorer = BetterCluster.getFactory(instanceMap, + scorerArgs[0].doubleValue()); + } + + final ClusterFactory[] pred = + (ClusterFactory[]) distanceType.getSecond(); + + if (pred.length > 0) { + return CombinedCluster.getFactory(pred, scorer); + } else { + return scorer; + } + } + + private static Writer getWriter(final CommandLineArgs args) throws IOException { + final String output = args.getArgValue("output", null); + if (output == null) { + return new OutputStreamWriter(System.out); + } else { + return new FileWriter(output); + } + } + + private static CellInterface getCell(final CastFileParser cfp, + final String fqcn) throws Exception { + final CellInterface result = cfp.getFullyQualifiedCell(fqcn); + + if (!CellUtils.isSubtype(result)) { + System.err.println("ERROR: Cell " + fqcn + " does not appear to " + + "be a subtype."); + usage(); + } + + return result; + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs theArgs = + new CachingCommandLineArgs( + new CommandLineArgsWithConfigFiles( + new CommandLineArgsDefImpl(args))); + + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cell", null); + final Pair distanceType = validArgs(theArgs); + final boolean checkDirectives = theArgs.argExists("check-directives"); + final boolean many = theArgs.argExists("many"); + + if (cellName == null) { + System.err.println("ERROR: You must specify a cellname."); + usage(); + } else if (!checkDirectives && distanceType == null && !many) { + System.err.println("ERROR: Parameters missing or specified incorrectly."); + usage(); + } + + cfp = CastCacheManager.getDefault().getCastFileParser( + new FileSearchPath(castRoot), castVersion, + new StandardParsingOption(theArgs)); + + if (theArgs.argExists("ignore-staticizer")) + ignoreStaticizer = new StaticizerFilter(); + final String[] cellNames = StringUtil.split(cellName, ':'); + final String mergeTarget = theArgs.getArgValue("merge_target", ""); + final String[] mergeTargets = StringUtil.split(mergeTarget, ':'); + + final CellInterface[] cells = new CellInterface[cellNames.length]; + for (int i = 0; i < cells.length; ++i) { + cells[i] = getCell(cfp, cellNames[i]); + } + + final CellInterface[] mergeCells = + new CellInterface[mergeTargets.length]; + for (int i = 0; i < mergeTargets.length; ++i) { + mergeCells[i] = getCell(cfp, mergeTargets[i]); + } + + if (checkDirectives) { + final Writer w = getWriter(theArgs); + for (CellInterface cell : cells) { + w.write(cell.getFullyQualifiedType()); + final Cluster cluster = + DirectiveCluster.getFactory().create(cell, cell.getType()); + for (CellInterface mergeCell : mergeCells) { + if (cluster.score(mergeCell) != null) { + w.write(' ' + mergeCell.getFullyQualifiedType()); + } + } + w.write('\n'); + } + w.flush(); + return; + } + + final CellInterface[] allCells = + new CellInterface[cells.length + mergeCells.length]; + System.arraycopy(cells, 0, allCells, 0, cells.length); + System.arraycopy(mergeCells, 0, allCells, cells.length, + mergeCells.length); + + final SortedMap typeMap = new TreeMap(); + for (CellInterface cell : allCells) prepare(cell, typeMap); + + final String instances = theArgs.getArgValue("instance-dir", null); + final Selector selector; + if (instances == null) { + selector = new ScoreSelector(); + } else { + selector = new SizeSelector(new File(instances)); + } + + final Collection> mergeCandidates = + new ArrayList>(); + Boolean defaultInclude = null; + boolean onlyExclude = true; + for (CommandLineArgsIterator i = theArgs.iterator(); i.hasNext(); ) { + final CommandLineArg arg = i.next(); + Boolean include = null; + if (arg.getName().equals("merge-cells")) { + include = Boolean.FALSE; + onlyExclude = false; + } else if (arg.getName().equals("exclude-cells")) { + include = Boolean.TRUE; + } + if (include != null) { + final String listCell = arg.getValue(); + if (listCell == null) { + defaultInclude = include; + } else { + final String[] listCells = StringUtil.split(listCell, ':'); + for (String c : listCells) { + mergeCandidates.add( + new Pair(c, include)); + } + } + } + } + + if (!mergeCandidates.isEmpty()) { + if (defaultInclude == null) { + if (onlyExclude) defaultInclude = Boolean.FALSE; + else defaultInclude = Boolean.TRUE; + } + final boolean defInclude = defaultInclude.booleanValue(); + + final UnaryPredicate pred = new UnaryPredicate() { + public boolean evaluate(final Object o) { + final CellInterface cell = (CellInterface) o; + for (Pair mergeCandidate : + mergeCandidates) { + final UnaryPredicate matcher = + CellUtils.getTypeMatcher( + Collections.singleton( + mergeCandidate.getFirst())); + if (matcher.evaluate(cell)) { + return mergeCandidate.getSecond().booleanValue(); + } + } + return defInclude; + } + }; + for (Iterator i = typeMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Map subtypeMap = (Map) entry.getValue(); + for (Iterator j = subtypeMap.entrySet().iterator(); j.hasNext(); ) { + final Map.Entry subentry = (Map.Entry) j.next(); + final Pair p = (Pair) subentry.getValue(); + final CellInterface c = (CellInterface) p.getFirst(); + if (pred.evaluate(c)) j.remove(); + } + if (subtypeMap.size() == 0) i.remove(); + } + } + + if (many) { + final Map instanceMap = new HashMap(); + final BufferedReader br = + new BufferedReader(new InputStreamReader(System.in)); + String line; + while ((line = br.readLine()) != null) { + System.out.println("Processing " + line); + final String[] tokens = StringUtil.tokenize(line); + + final CommandLineArgs lineArgs = + new CachingCommandLineArgs( + new CommandLineArgsWithConfigFiles( + new CommandLineArgsDefImpl(tokens))); + + final Pair lineDistance = validArgs(lineArgs); + + if (lineDistance == null) { + System.out.println("WARNING: Invalid parameter specification. Line \"" + line + "\" ignored."); + continue; + } + + try { + final Writer w = getWriter(lineArgs); + final ClusterFactory factory = + getFactory(lineDistance, lineArgs, allCells, instanceMap); + process(typeMap, factory, selector, w); + w.close(); + } catch (IOException e) { + System.out.println("WARNING: Cannot write to output file. Line \"" + line + "\" ignored."); + } + } + } else { + final Writer w = getWriter(theArgs); + final ClusterFactory factory = + getFactory(distanceType, theArgs, allCells, new HashMap()); + process(typeMap, factory, selector, w); + w.close(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NegativeDelayBudget.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NegativeDelayBudget.java new file mode 100644 index 0000000000..eb39a4af4f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NegativeDelayBudget.java @@ -0,0 +1,932 @@ +package com.avlsi.tools.jauto; + +import java.io.IOException; +import java.io.PrintStream; +import java.io.BufferedReader; +import java.io.FileReader; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedList; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import com.avlsi.fast.CellNet; +import com.avlsi.fast.CellType; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.HalfOperator; +import com.avlsi.file.common.HierName; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; + +public class NegativeDelayBudget implements ConjugateGradientSolver.Function { + private static final class InstanceIterator implements Iterator{ + private final HierName instName; + private final Iterator iterator; + public InstanceIterator(final Iterator iterator, + final HierName instName) { + this.iterator = iterator; + this.instName = instName; + } + public HierName getInstance() { + return instName; + } + public boolean hasNext() { + return iterator.hasNext(); + } + public E next() { + return iterator.next(); + } + public void remove() { + throw new UnsupportedOperationException(); + } + } + + private static final class NetIterator + implements Iterator> { + private final LinkedList> subcells; + private InstanceIterator nets; + private final MultiMap globalNetMap; + public NetIterator(final HierName instName, + final CellType cell, + MultiMap globalNetMap) { + subcells = new LinkedList>(); + subcells.addLast( + new InstanceIterator( + cell.getAllSubcellConnections().iterator(), + instName)); + this.globalNetMap = globalNetMap; + + Iterator gn = (Iterator) + globalNetMap.get(cell.typeName).iterator(); + if (gn.hasNext()) { + nets = new InstanceIterator(gn, null); + } else { + nets = null; + } + } + private void skipToQualified() { + while (nets == null && !subcells.isEmpty()) { + InstanceIterator ii = subcells.getLast(); + if (ii.hasNext()) { + ConnectionInfo info = ii.next(); + Iterator subci = + info.child.getAllSubcellConnections().iterator(); + + HierName childName = + HierName.append(ii.getInstance(), info.nameInParent); + subcells.addLast( + new InstanceIterator(subci, childName)); + + Iterator gn = (Iterator) + globalNetMap.get(info.child.typeName).iterator(); + if (gn.hasNext()) { + nets = + new InstanceIterator(gn, childName); + } + } else { + subcells.removeLast(); + } + } + } + + public boolean hasNext() { + skipToQualified(); + return nets != null; + } + + public InstanceIterator next() { + if (hasNext()) { + final InstanceIterator result = nets; + nets = null; + return result; + } else { + throw new NoSuchElementException(); + } + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * Compare GlobalNet objects by their top-level canonical net names. + **/ + private static class GlobalNetComparator implements Comparator { + private HierName toHierName(Object o) { + if (o instanceof HierName) { + return (HierName) o; + } else { + return ((GlobalNet) o).getTopCellNet().canonicalName; + } + } + public int compare(Object o1, Object o2) { + return toHierName(o1).compareTo(toHierName(o2)); + } + public boolean equals(Object o) { + return o instanceof GlobalNetComparator; + } + } + + private static Comparator GLOBALNET_COMPARATOR = + new GlobalNetComparator(); + + private interface TransitionProcessor { + void processTransition(HierName src, HierName snk, double delay, + int dir); + } + + private class PrintTransitions implements TransitionProcessor { + public void processTransition(final HierName src, final HierName snk, + final double delay, final int dir) { + int odir = getOpposingDir(dir); + System.err.println("#" + String.format("%.2f", delay) + + " " + src + getDirString(odir) + + " -> " + snk + getDirString(dir)); + System.err.println("index(" + src + getDirString(odir) + + ") = " + getGlobalNetIndex(top, src, odir)); + System.err.println("index(" + snk + getDirString(dir) + + ") = " + getGlobalNetIndex(top, snk, dir)); + } + } + + private class CountTransitions implements TransitionProcessor { + private int count; + private int maxvar; + public CountTransitions() { + count = 0; + maxvar = -1; + } + public void processTransition(final HierName src, final HierName snk, + final double delay, final int dir) { + maxvar = Math.max(maxvar, getGlobalNetIndex(top, src)); + maxvar = Math.max(maxvar, getGlobalNetIndex(top, snk)); + count++; + } + public int getCount() { + return count; + } + public int getMaxVarIndex() { + return maxvar; + } + } + + private class SetNames extends IndexMapper implements TransitionProcessor { + private final String[] names; + public SetNames() { + names = new String[transitionCount * 2 + variableCount]; + } + public void processTransition(final HierName src, final HierName snk, + final double delay, final int dir) { + int odir = getOpposingDir(dir); + final String srcstr = src + getDirString(odir); + final String dststr = snk + getDirString(dir); + final String transition = srcstr + " -> " + dststr; + names[getDelayIndex()] = "d(" + transition + ")"; + names[getNegativeBudgetIndex()] = "n(" + transition + ")"; + int srcidx = getGlobalNetIndex(top, src, odir); + int dstidx = getGlobalNetIndex(top, snk, dir); + names[getArrivalTimeIndex(srcidx)] = "t(" + src.toString() + + getDirString(odir) + ")"; + names[getArrivalTimeIndex(dstidx)] = "t(" + snk.toString() + + getDirString(dir) + ")"; + count++; + } + public void printValue(final double[] x) { + for (int i = 0; i < names.length; ++i) { + if (names[i] != null) + System.err.println(String.format("%d %s %g", i, names[i], x[i])); + } + } + public String[] getNames() { + return names; + } + } + + private class IndexMapper { + protected int count; + // delay(i,j) => v[0..transitionCount-1] + // negative(i,j) => v[transitionCount..2*transitionCount-1] + // t(i) => v[2*transitionCount,2*transitionCount+variableCount-1] + public final int getDelayIndex() { + return count; + } + public final int getNegativeBudgetIndex() { + return count + transitionCount; + } + public final int getArrivalTimeIndex(int idx) { + return 2 * transitionCount + idx; + } + } + + private class IndexedAccess extends IndexMapper { + private final double[] v; + protected final double[] accum; + public IndexedAccess(final double[] v, final double[] accum) { + this.v = v; + this.accum = accum; + } + protected double getDelay() { + return v[getDelayIndex()]; + } + protected void accumDelay(double x) { + accum[getDelayIndex()] += x; + } + protected double getNegativeBudget() { + return v[getNegativeBudgetIndex()]; + } + protected void accumNegativeBudget(double x) { + accum[getNegativeBudgetIndex()] += x; + } + protected double getArrivalTime(int idx) { + return v[getArrivalTimeIndex(idx)]; + } + protected void accumArrivalTime(int idx, double x) { + accum[getArrivalTimeIndex(idx)] += x; + } + } + + private final class EnergyCalculator extends IndexedAccess + implements TransitionProcessor { + private double constraintEnergy, objectiveEnergy; + private double scaleConstraint; + private double scaleObjective; + private boolean verbose; + private double E_d, E_n, E_t, E_tn, OE_n, OE_d; + private boolean solveForP; + public EnergyCalculator(double[] v, double scaleConstraint, + double scaleObjective, + boolean solveForP, + boolean verbose) { + super(v, null); + this.scaleConstraint = scaleConstraint; + this.scaleObjective = scaleObjective; + this.constraintEnergy = 0; + this.objectiveEnergy = 0; + E_d = E_n = E_t = E_tn = 0; + OE_n = OE_d = 0; + + // t(j) >= 0 + for (int i = 0; i < variableCount; ++i) { + if (getArrivalTime(i) < 0) { + E_t += square(getArrivalTime(i)); + } + } + + this.solveForP = solveForP; + this.verbose = verbose; + } + private double square(final double x) { + return x * x; + } + private double cube(final double x) { + return x * x * x; + } + public void processTransition(final HierName src, final HierName snk, + double delay, final int dir) { + // d(i,j) >= D(j) + if (getDelay() < delay) { + E_d += square(delay - getDelay()); + } + + // n(i,j) >= 0 + if (getNegativeBudget() < 0) { + E_n += square(getNegativeBudget()); + } + + // t(j) = t(i) + d(i,j) - n(i,j) + int odir = getOpposingDir(dir); + int srcidx = getGlobalNetIndex(top, src, odir); + int dstidx = getGlobalNetIndex(top, snk, dir); + E_tn += square(getArrivalTime(srcidx) + + getDelay() - + getNegativeBudget() - + getArrivalTime(dstidx)); + + // obj = sum(n(i,j)^2) + sum(d(i,j)^2) + if (solveForP) { + OE_d += square(getDelay() - delay); + } else { + OE_n += square(getNegativeBudget()); + } + + count++; + } + public double getEnergy() { + constraintEnergy = E_d / variableCount + + (E_n + E_t + E_tn) / transitionCount; + objectiveEnergy = (OE_n + OE_d) / transitionCount; + if (verbose) { + System.err.printf("E_d = %g (%g) E_n = %g (%g) " + + "E_t = %g (%g) E_tn = %g (%g)\n", + E_d, E_d * scaleConstraint, + E_n, E_n * scaleConstraint, + E_t, E_t * scaleConstraint, + E_tn, E_tn * scaleConstraint); + System.err.printf("constraintEnergy = %g (%g)\n", + constraintEnergy, + constraintEnergy * scaleConstraint); + System.err.printf("OE_n = %g (%g) OE_d = %g (%g)\n", + OE_n, OE_n * scaleObjective, + OE_d, OE_d * scaleObjective); + System.err.printf("objectiveEnergy = %g (%g)\n", + objectiveEnergy, + objectiveEnergy * scaleObjective); + } + return constraintEnergy * scaleConstraint + + objectiveEnergy * scaleObjective; + } + } + + private final class GradientCalculator extends IndexedAccess + implements TransitionProcessor { + private double scaleConstraint; + private double scaleObjective; + private boolean solveForP; + public GradientCalculator(double[] v, double[] accum, + double scaleConstraint, + double scaleObjective, + boolean solveForP) { + super(v, accum); + this.scaleConstraint = scaleConstraint; + this.scaleObjective = scaleObjective; + this.solveForP = solveForP; + + // t(j) >= 0 + for (int i = 0; i < variableCount; ++i) { + if (getArrivalTime(i) < 0) { + accumArrivalTime(i, -2 * getArrivalTime(i) + * scaleConstraint + / variableCount); + } + } + } + + public void processTransition(final HierName src, final HierName snk, + double delay, final int dir) { + // d(i,j) >= D(j) + if (getDelay() < delay) { + accumDelay(2 * (delay - getDelay()) * scaleConstraint + / transitionCount); + } + + // n(i,j) >= 0 + if (getNegativeBudget() < 0) { + accumNegativeBudget(-2 * getNegativeBudget() * scaleConstraint + / transitionCount); + } + + // t(j) = t(i) + d(i,j) - n(i,j) + int odir = getOpposingDir(dir); + int srcidx = getGlobalNetIndex(top, src, odir); + int dstidx = getGlobalNetIndex(top, snk, dir); + double x = 2 * (getArrivalTime(srcidx) + getDelay() - + getNegativeBudget() - getArrivalTime(dstidx)) + / transitionCount; + accumArrivalTime(srcidx, -x * scaleConstraint); + accumArrivalTime(dstidx, x * scaleConstraint); + accumDelay(-x * scaleConstraint); + accumNegativeBudget(x * scaleConstraint); + + // obj = sum(n(i,j)^2) + sum(d(i,j)^2) + if (solveForP) { + accumDelay(-2 * (getDelay() - delay) * scaleObjective + / transitionCount); + } else { + accumNegativeBudget(-2 * getNegativeBudget() * scaleObjective + / transitionCount); + } + + if (solveForP) { + accum[getNegativeBudgetIndex()] = 0; + } + count++; + } + } + + private final class InitializeVars extends IndexedAccess + implements TransitionProcessor { + public InitializeVars(double[] accum) { + super(null, accum); + for (int i = 0; i < accum.length; ++i) { + accum[i] = 0; + } + } + public void processTransition(final HierName src, final HierName snk, + double delay, final int dir) { + accumDelay(delay); + count++; + } + } + + private final class PrintConstraints extends IndexedAccess + implements TransitionProcessor { + public PrintConstraints(double[] v) { + super(v, null); + + // t(j) >= 0 + for (int i = 0; i < variableCount; ++i) { + System.err.printf("%s >= 0: %g >= 0\n", + names[getArrivalTimeIndex(i)], + getArrivalTime(i)); + } + } + private double square(final double x) { + return x * x; + } + public void processTransition(final HierName src, final HierName snk, + double delay, final int dir) { + // d(i,j) >= D(j) + System.err.printf("%s >= %g: %g >= %g\n", + names[getDelayIndex()], delay, + getDelay(), delay); + + // n(i,j) >= 0 + System.err.printf("%s >= 0: %g >= 0\n", + names[getNegativeBudgetIndex()], + getNegativeBudget()); + + // t(j) = t(i) + d(i,j) - n(i,j) + int odir = getOpposingDir(dir); + int srcidx = getGlobalNetIndex(top, src, odir); + int dstidx = getGlobalNetIndex(top, snk, dir); + String srcstr = names[getArrivalTimeIndex(srcidx)]; + String dststr = names[getArrivalTimeIndex(dstidx)]; + System.err.printf("%s = %s + %s - %s: %g = %g + %g - %g\n", + dststr, srcstr, names[getDelayIndex()], + names[getNegativeBudgetIndex()], + getArrivalTime(dstidx), + getArrivalTime(srcidx), + getDelay(), + getNegativeBudget()); + + // obj = sum(n(i,j)^2) + sum(d(i,j)^2) + System.err.printf("objective = %s^2 + %s^2: %g + %g\n", + names[getNegativeBudgetIndex()], + names[getDelayIndex()], + square(getNegativeBudget()), + square(getDelay())); + + count++; + } + } + + private class PrintResults extends IndexedAccess + implements TransitionProcessor { + public PrintResults(final double[] v) { + super(v, null); + } + + public void processTransition(final HierName src, final HierName snk, + final double delay, final int dir) { + int odir = getOpposingDir(dir); + int srcidx = getGlobalNetIndex(top, src, odir); + int dstidx = getGlobalNetIndex(top, snk, dir); + System.err.println("|" + String.format("%.2f", delay) + + " " + src + getOpposingDirString(dir) + + " -> " + snk + getDirString(dir) + + " tsrc = " + getArrivalTime(srcidx) + + " tsnk = " + getArrivalTime(dstidx) + + " n = " + getNegativeBudget() + + " d = " + getDelay() + + " p = " + (getDelay() - delay)); + count++; + } + } + + private class GenerateLP extends IndexMapper + implements TransitionProcessor { + private final PrintStream out; + public GenerateLP(PrintStream out) { + this.out = out; + for (int i = 0; i < variableCount; ++i) { + out.printf("var x%d >= 0;\n", getArrivalTimeIndex(i)); + } + } + public void processTransition(final HierName src, final HierName snk, + final double delay, final int dir) { + out.printf("var x%d >= %g;\n", getDelayIndex(), delay); + out.printf("var x%d >= 0;\n", getNegativeBudgetIndex()); + + int odir = getOpposingDir(dir); + int srcidx = getGlobalNetIndex(top, src, odir); + int dstidx = getGlobalNetIndex(top, snk, dir); + out.printf("subject to c%d: x%d + x%d - x%d - x%d = 0;\n", + count, getArrivalTimeIndex(srcidx), getDelayIndex(), + getNegativeBudgetIndex(), + getArrivalTimeIndex(dstidx)); + count++; + } + public void finishOutput() { + out.print("minimize obj: "); + for (int i = 0; i < 2*transitionCount; ++i) { + if (i > 0) { + out.print(" + "); + } + out.print("x" + i); + } + out.println(";"); + out.println("end;"); + } + } + + private static final Pattern SOLUTION_PATTERN = + Pattern.compile("^\\s*\\d+ x(\\d+)\\s+\\S+\\s+(\\S+)\\s+\\S+.*"); + + private void solveLP(double[] X) throws IOException { + final PrintStream out = new PrintStream("solve.in"); + final GenerateLP lpWriter = new GenerateLP(out); + processTransitions(lpWriter); + lpWriter.finishOutput(); + out.close(); + + final ProcessBuilder pb = new ProcessBuilder("sh", "-c", "glpsol --math solve.in --output solve.out >solve.log 2>&1"); + try { + pb.start().waitFor(); + } catch (InterruptedException e) { + throw new RuntimeException("Exception running glpsol", e); + } + + final BufferedReader br = + new BufferedReader(new FileReader("solve.out")); + + String line; + while ((line = br.readLine()) != null) { + final Matcher m = SOLUTION_PATTERN.matcher(line); + if (m.matches()) { + final int var = Integer.parseInt(m.group(1)); + final double val = Double.parseDouble(m.group(2)); + X[var] = val; + } + } + br.close(); + } + + public double getValue(double[] v) { + return getValue(v, false); + } + + public double getValue(double[] v, boolean verbose) { + final EnergyCalculator calc = + new EnergyCalculator(v, scaleConstraint, scaleObjective, solveForP, verbose); + processTransitions(calc); + return calc.getEnergy(); + } + + public void getNegativeGradient(double[] v, double[] accum) { + getAnalyticGradient(v, accum); + } + + private void checkGradient(double[] v, double[] accum) { + final double[] nAccum = new double[accum.length]; + System.arraycopy(accum, 0, nAccum, 0, accum.length); + getNumericalGradient(v, nAccum); + + final double[] aAccum = new double[accum.length]; + System.arraycopy(accum, 0, aAccum, 0, accum.length); + getAnalyticGradient(v, aAccum); + + for (int i = 0; i < accum.length; i++) { + if (Math.abs(aAccum[i] - nAccum[i]) / nAccum[i] > 0.01) { + System.err.printf("Gradient: %d %g %g %g\n", i, nAccum[i], aAccum[i], nAccum[i] - aAccum[i]); + } + } + } + + private void getAnalyticGradient(double[] v, double[] accum) { + final GradientCalculator calc = + new GradientCalculator(v, accum, scaleConstraint, scaleObjective, solveForP); + processTransitions(calc); + } + + private void getNumericalGradient(double[] v, double[] accum) { + final double delta = 1e-10; + for (int i = 0; i < v.length; ++i) { + final double oldv = v[i]; + v[i] = oldv - delta; + final double oldE = getValue(v); + v[i] = oldv + delta; + final double newE = getValue(v); + v[i] = oldv; + final double grad = (newE - oldE) / (2 * delta); + accum[i] += -grad; + } + } + + /** + * A MultiMap adapted to return an empty list when the key is not in the + * list. + **/ + private static class MultiMapWithDefault extends MultiMap { + public MultiMapWithDefault(final Map map) { + super(map, MultiMap.ARRAY_LIST_FACTORY); + } + + public Collection get(Object key) { + Collection result = super.get(key); + return result == null ? Collections.EMPTY_LIST : result; + } + } + + private final MultiMap c2gmap; + private final CellType top; + private final double tau; + private final int transitionCount; + private final int globalNetCount; + private final int variableCount; + private String[] names; + private double scaleConstraint, scaleObjective; + private boolean solveForP; + + private void processTransitions(final TransitionProcessor proc) { + for (NetIterator i = new NetIterator(null, top, c2gmap); + i.hasNext(); ) { + final InstanceIterator gni = i.next(); + final HierName inst = gni.getInstance(); + while (gni.hasNext()) { + final GlobalNet gn = gni.next(); + processTransitions(inst, gn, proc); + } + } + } + + private static class FixedIterations + implements ConjugateGradientSolver.StopCondition { + private int count; + public FixedIterations(int count) { + this.count = count; + } + public boolean evaluate(boolean big_step, double mag) { + count--; + return count > 0; + } + } + + public NegativeDelayBudget(final CellType top, + final List globalNets, + final double tau) throws IOException { + this.top = top; + this.tau = tau; + c2gmap = new MultiMapWithDefault(new HashMap()); + for (GlobalNet gn : globalNets) { + final CellNet cn = gn.getTopCellNet(); + c2gmap.put(cn.container.typeName, gn); + } + for (String key : (Set) c2gmap.keySet()) { + Collections.sort((List) c2gmap.get(key), + GLOBALNET_COMPARATOR); + } + getNumVars(top, new HashMap()); + + final CountTransitions counter = new CountTransitions(); + processTransitions(counter); + transitionCount = counter.getCount(); + globalNetCount = counter.getMaxVarIndex() + 1; + variableCount = globalNetCount * 2; + processTransitions(new PrintTransitions()); + System.err.println("Transition count = " + transitionCount + + " variable count = " + variableCount); + + final SetNames setNames = new SetNames(); + processTransitions(setNames); + names = setNames.getNames(); + + double[] X = new double[transitionCount * 2 + variableCount]; + solveLP(X); + setNames.printValue(X); + processTransitions(new PrintResults(X)); + + processTransitions(new InitializeVars(X)); + double tolerance = 0; + + solveForP = false; + for (int z = 0; z < 2; ++z) { + scaleObjective = 1e5; + scaleConstraint = 1e-4; + getValue(X, true); + + final ConjugateGradientSolver solver = + new ConjugateGradientSolver( + new ConjugateGradientSolver.Parameters() { + public double getTolerance() { return 1e-8; } + }, + this); + + for (int i = 1; i < 15; ++i) { + solver.conjugateGradientDescent(X,tolerance, + new FixedIterations(500)); + System.err.println("Iteration " + i); + getValue(X, true); + setNames.printValue(X); + processTransitions(new PrintConstraints(X)); + scaleConstraint *= 10; + } + solveForP = !solveForP; + } + + processTransitions(new PrintResults(X)); + } + + private HierName append(HierName a, HierName b) { + return b == null ? a : HierName.append(a, b); + } + + private Pair findInstance(CellType cell, + HierName inst, + HierName rest) { + if (inst == null) { + return null; + } else { + final ConnectionInfo ci = cell.getSubcellNamed(inst); + if (ci == null) { + final HierName suffix = + HierName.makeHierName(inst.getSuffixString()); + rest = rest == null ? suffix : HierName.append(suffix, rest); + return findInstance(cell, inst.getParent(), rest); + } else { + return new Pair(ci, rest); + } + } + } + + private Pair findInstance(CellType cell, + HierName inst) { + return findInstance(cell, inst, null); + } + + private List findPath(final CellType cell, + final HierName inst) { + final List results = new ArrayList(); + Pair ch = findInstance(top, inst); + while (ch != null) { + ConnectionInfo ci = ch.getFirst(); + results.add(ci); + ch = findInstance(ci.child, ch.getSecond()); + } + return results; + } + + private HierName isSiblingSubcell(final CellType top, + final HierName inst, + final GlobalNet net) { + final CellType container = net.getTopCellNet().container; + HierName instance = null; + if (top != container) { + List path = findPath(top, inst); + for (ConnectionInfo ci : path) { + instance = HierName.append(instance, ci.nameInParent); + if (ci.child == container) { + break; + } + } + } + return instance; + } + + private GlobalNet findSource(final HierName inst, final NetSink sink) { + final HierName fullInst = append(inst, sink.getInstanceName()); + final HalfOperator halfOp = sink.getSink(); + for (GlobalNet net : halfOp.outputNet.globalNets) { + final Collection sources = + (Collection) net.getListSources(); + for (NetSource source : sources) { + if (source.getSource() == halfOp) { + final HierName srcInst = source.getInstanceName(); + if (srcInst == null || fullInst.endsWith(srcInst)) { + return net; + } + } + } + } + return null; + } + + private int getNumVars(final CellType cell, + final Map cache) { + final Integer cached = cache.get(cell.typeName); + int count; + if (cached == null) { + count = 0; + Collection globalNets = + (Collection) c2gmap.get(cell.typeName); + count += globalNets.size(); + for (ConnectionInfo ci : cell.getAllSubcellConnections()) { + int subcount = getNumVars(ci.child, cache); + ci.setIndex(count); + count += subcount; + } + cache.put(cell.typeName, count); + } else { + count = cached; + } + + return count; + } + + private int findNetPosition(final CellType cell, final HierName net) { + final List nets = + (List) c2gmap.get(cell.typeName); + return Collections.binarySearch(nets, net, GLOBALNET_COMPARATOR); + } + + private int getGlobalNetIndex(CellType cell, HierName inst, int dir) { + int index = getGlobalNetIndex(cell, inst); + if (dir == HalfOperator.DriveDirection.PULL_UP) index += globalNetCount; + return index; + } + + private int getGlobalNetIndex(CellType cell, HierName inst) { + int index = 0; + int pos = -1; + Pair ch; + do { + pos = findNetPosition(cell, inst); + if (pos >= 0) break; + ch = findInstance(cell, inst); + if (ch != null) { + ConnectionInfo ci = ch.getFirst(); + index += ci.getIndex(); + inst = ch.getSecond(); + cell = ci.child; + } + } while (ch != null); + if (pos < 0) { + pos = findNetPosition(cell, inst); + } + if (pos < 0) { + System.err.println("Cell = " + cell.typeName + " Rest = " + inst); + } + + index += pos; + + return index; + } + + private String getDirString(int dir) { + switch (dir) { + case HalfOperator.DriveDirection.PULL_DOWN: return "-"; + case HalfOperator.DriveDirection.PULL_UP: return "+"; + default: return "="; + } + } + + private String getOpposingDirString(int dir) { + switch (dir) { + case HalfOperator.DriveDirection.PULL_DOWN: return "+"; + case HalfOperator.DriveDirection.PULL_UP: return "-"; + default: return "="; + } + } + + private int getOpposingDir(int dir) { + switch (dir) { + case HalfOperator.DriveDirection.PULL_DOWN: + return HalfOperator.DriveDirection.PULL_UP; + case HalfOperator.DriveDirection.PULL_UP: + return HalfOperator.DriveDirection.PULL_DOWN; + default: + return dir; + } + } + + private double getDelay(final NetSink snk, final GlobalNet gn) { + final HalfOperator op = snk.getSink(); + final double delay = + (op.getDelayBias() * tau * + TransistorSizingTool.findDelayBias(gn, op) + + DelayCalculator.getExtraDelay(op, gn, tau)) / tau; + return delay; + } + + private void processTransitions(final HierName inst, final GlobalNet gn, + final TransitionProcessor proc) { + for (Iterator j = gn.getListSinks().iterator(); j.hasNext(); ) { + final NetSink snk = (NetSink) j.next(); + final HierName fullInst = append(inst, snk.getInstanceName()); + if (snk.getType() == NetType.HALF_OPERATOR_TRANSISTOR) { + CellNet output = snk.getSink().outputNet; + for (Iterator k = output.globalNets.iterator(); k.hasNext(); ) { + CellNet top = ((GlobalNet) k.next()).getTopCellNet(); + } + final GlobalNet other = findSource(inst, snk); + final HierName hsrc = + append(inst, gn.getTopCellNet().canonicalName); + final HierName hsnk = + append(isSiblingSubcell(top, fullInst, other), + other.getTopCellNet().canonicalName); + proc.processTransition(hsrc, hsnk, getDelay(snk, other), + snk.getSink().driveDirection); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSink.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSink.java new file mode 100644 index 0000000000..99b966d9eb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSink.java @@ -0,0 +1,350 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + + +import com.avlsi.fast.*; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.tools.lvs.NetGraph; + +import java.util.Set; +import java.io.*; + +public class NetSink +{ + public final int type; // type of the sink + // 0: half-operator and transistor, by default + // 1: cell-type, only used during globle net generation + // 2: capacitive load, for primary output + + public double coordinateX; + public double coordinateY; + + public int orientation; + + public double loadCapacitance; // load capacitance value for type 2 + + public CellType cellSink; // load cell for type 1 + public Set/**/ setSubcellNets; // set of cell nets in the cellSink for type 1 + + public HalfOperator sink; // load halfoperator for type 0 + public NetGraph.NetEdge transistor; // load transistor for type 0 + private HierName instanceName; + + + public NetSink(final int type) { + assert type >= 0 && type <= 2 : "invalid type for NetSink"; + this.type = type; + instanceName = null; + } + + + public int getType() + { + return type; + } + + + public double setCoordinateX(double d) + { + coordinateX = d; + + return coordinateX; + } + + + public double getCoordinateX() + { + return coordinateX; + } + + + public double setCoordinateY(double d) + { + coordinateY = d; + + return coordinateY; + } + + + public double getCoordinateY() + { + return coordinateY; + } + + + public double setLoadCapacitance(double d) + { + assert d >= 0.0 : "invalid capacitance value"; + + loadCapacitance = d; + + return loadCapacitance; + } + + + public double getLoadCapacitance() + { + return loadCapacitance; + } + + + public CellType setCellSink(CellType ct) + { + assert ct != null : "trying to set NULL pointer to cellSink"; + + cellSink = ct; + + return cellSink; + } + + + public CellType getCellSink() + { + return cellSink; + } + + + public HalfOperator setSink(HalfOperator ho) + { + assert ho != null : "trying to set Null pointer to sink"; + + sink = ho; + + return sink; + } + + + public HalfOperator getSink() + { + return sink; + } + + + public NetGraph.NetEdge setTransistor(NetGraph.NetEdge tr) + { + assert tr != null : "trying to set Null pointer to transistor"; + + transistor = tr; + + return transistor; + } + + + public NetGraph.NetEdge getTransistor() + { + return transistor; + } + + + public NetSink() + { + type = NetType.HALF_OPERATOR_TRANSISTOR; + + coordinateX = 0.0; + coordinateY = 0.0; + + orientation = ConnectionInfo.R0; + + // FIXME: hardcoded constant + loadCapacitance = 20.0E-15; + + cellSink = null; + setSubcellNets = null; + + sink = null; + transistor = null; + instanceName = null; + } + + + public NetSink(NetSink ns) + { + type = ns.type; + + coordinateX = ns.coordinateX; + coordinateY = ns.coordinateY; + + orientation = ns.orientation; + + loadCapacitance = ns.loadCapacitance; + + cellSink = ns.cellSink; + setSubcellNets = ns.setSubcellNets; + + sink = ns.sink; + transistor = ns.transistor; + instanceName = ns.instanceName; + } + + + public void print() + { + System.out.println("type: " + type); + System.out.println("coordinate X: " + coordinateX); + System.out.println("coordinate Y: " + coordinateY); + } + + + public String toString() + { + return "type=" + type + " inst=" + instanceName + + (sink == null ? + "" : " sink=" + + sink.subType.typeName + "/" + + sink.outputNet.canonicalName + + (sink.driveDirection == HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+")) + + " X=" + coordinateX + " Y=" + coordinateY; + } + + + public void dumpInfo(BufferedWriter bw1, String s1) + { + double sx = sink.subType.xSize; + double sy = sink.subType.ySize; + + try{ + bw1.write(s1 + "NET_SINK _ {\n"); + + if(type == NetType.HALF_OPERATOR_TRANSISTOR){ + bw1.write(s1 + "\toutput_net = " + + sink.outputNet.canonicalName.getCadenceString() + ";\n"); + bw1.write(s1 + "\tdrive_direction = "); + if (sink.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + bw1.write("-;\n"); + } + else{ + bw1.write("+;\n"); + } + + bw1.write(s1 + "\torientation = "); + double fx, fy; + switch(orientation){ + case ConnectionInfo.R0: + bw1.write("R0;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.R90: + bw1.write("R90;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + case ConnectionInfo.R180: + bw1.write("R180;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.R270: + bw1.write("R270;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + case ConnectionInfo.MY: + bw1.write("MY;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.MYR90: + bw1.write("MYR90;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + case ConnectionInfo.MX: + bw1.write("MX;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.MXR90: + bw1.write("MXR90;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + default: + throw new AssertionError(); + } + + bw1.write(s1 + "\tcoordinate = (" + coordinateX + ", " + coordinateY + ");\n"); + + bw1.write(s1 + "\tbounding_box = (" + + (coordinateX - fx) + ", " + + (coordinateY - fy) + ", " + + (coordinateX + fx) + ", " + + (coordinateY + fy) + ");\n"); + + } + + bw1.write(s1 + "}\n"); + } + catch(IOException e){ + e.printStackTrace(System.out); + } + } + + + public final int updateOrientation(int parentOrientation) + { + orientation = ConnectionInfo.composeOrientation(parentOrientation, orientation); + return orientation; + } + + public HierName getInstanceName() { + assert type == NetType.CELL || type == NetType.HALF_OPERATOR_TRANSISTOR; + return instanceName; + } + + public void prefixInstanceName(final /*@ non_null @*/ HierName prefix) { + assert type == NetType.CELL || type == NetType.HALF_OPERATOR_TRANSISTOR; + instanceName = + instanceName == null ? prefix + : HierName.append(prefix, instanceName); + } + + public AdditiveTerms getGateCapacitanceTerm() { + assert type == NetType.HALF_OPERATOR_TRANSISTOR; + + final TechnologyData tech = sink.subType.design.getTechnologyData(); + final double unitGateCapacitance = + transistor.type == DeviceTypes.N_TYPE ? + tech.getUnitNmosGateCapacitance(transistor.getTransistorType()) + : tech.getUnitPmosGateCapacitance(transistor.getTransistorType()); + final double f = transistor.size / + transistor.shareCount * + transistor.length * + unitGateCapacitance; + + final AdditiveTerms result; + if (sink.isVariableFixed()) { + result = + new AdditiveTerms(new FunctionTerm(sink.getCurrentSize() * f)); + } else { + result = + new AdditiveTerms( + new FunctionTerm( + FunctionTerm.Type.VAR, + sink.getVariableName(), + f * sink.getSizeForConductance(1.0) * + tech.getWidthRoundingSlope()), + new FunctionTerm(f * tech.getWidthRoundingOffset() * + sink.getSymmetrizationFactor())); + } + + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSource.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSource.java new file mode 100644 index 0000000000..af1bfe200e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetSource.java @@ -0,0 +1,308 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import com.avlsi.fast.*; +import com.avlsi.file.common.HierName; + +import java.util.Set; +import java.io.*; + +public class NetSource +{ + public final int type; // type of the source + // 0: half-operator, by default + // 1: cell-type, only used during global net generation + // 2: primary input + + /** + * X-coordinate of the net. Only meaningful for type + * NetType.CELL. + **/ + public double coordinateX; + + /** + * Y-coordinate of the net. Only meaningful for type + * NetType.CELL. + **/ + public double coordinateY; + + /** + * Orientation of the net. Only meaningful for type + * NetType.CELL. + **/ + public int orientation; + + /** + * TODO: Document; purpose unknown. Only meaningful for type + * NetType.CELL. + **/ + public CellType cellSource; + + /** + * TODO: Document; purpose unknown. Only meaningful for type + * NetType.CELL. + **/ + public Set/**/ setSubcellNets; + + /** + * The half-operator driving this net. Only meaningful for type + * NetType.HALF_OPERATOR_TRANSISTOR. + **/ + public HalfOperator source; + + private HierName instanceName; + + private float delayBias; + + public NetSource(int type) { + assert type >= 0 && type <= 2 : "invalid type for NetSource"; + this.type = type; + delayBias = Float.POSITIVE_INFINITY; + } + + + public int getType() + { + return type; + } + + + public double setCoordinateX(double d) + { + coordinateX = d; + + return coordinateX; + } + + + public double getCoordinateX() + { + return coordinateX; + } + + + public double setCoordinateY(double d) + { + coordinateY = d; + + return coordinateY; + } + + + public double getCoordinateY() + { + return coordinateY; + } + + + public CellType setCellSource(CellType ct) + { + assert ct != null : "trying to set NULL pointer to cellSource"; + + cellSource = ct; + + return cellSource; + } + + + public CellType getCellSource() + { + return cellSource; + } + + + public HalfOperator setSource(HalfOperator ho) + { + assert ho != null : "trying to set Null pointer to source"; + + source = ho; + + return source; + } + + + public HalfOperator getSource() + { + return source; + } + + + public NetSource() + { + type = NetType.HALF_OPERATOR_TRANSISTOR; + + coordinateX = 0.0; + coordinateY = 0.0; + + orientation = ConnectionInfo.R0; + + cellSource = null; + setSubcellNets = null; + + source = null; + instanceName = null; + delayBias = Float.POSITIVE_INFINITY; + } + + public NetSource(NetSource ns) + { + type = ns.type; + coordinateX = ns.coordinateX; + coordinateY = ns.coordinateY; + + orientation = ns.orientation; + + cellSource = ns.cellSource; + setSubcellNets = ns.setSubcellNets; + + source = ns.source; + instanceName = ns.instanceName; + delayBias = ns.delayBias; + } + + public void print() + { + System.out.println("type: " + type); + System.out.println("coordinate X: " + coordinateX); + System.out.println("coordinate Y: " + coordinateY); + } + + + public String toString() + { + return "type=" + type + " inst=" + instanceName + + (source == null ? + "" : " source=" + + source.subType.typeName + "/" + + source.outputNet.canonicalName + + (source.driveDirection == HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+")) + + " X=" + coordinateX + " Y=" + coordinateY; + } + + + public void dumpInfo(BufferedWriter bw1, String s1) + { + double sx = source.subType.xSize; + double sy = source.subType.ySize; + + try{ + bw1.write(s1 + "NET_SOURCE _ {\n"); + + if(type == NetType.HALF_OPERATOR_TRANSISTOR){ + bw1.write(s1 + "\toutput_net = " + + source.outputNet.canonicalName.getCadenceString() + ";\n"); + bw1.write(s1 + "\tdrive_direction = "); + if (source.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + bw1.write("-;\n"); + } + else{ + bw1.write("+;\n"); + } + + bw1.write(s1 + "\torientation = "); + double fx, fy; + switch(orientation){ + case ConnectionInfo.R0: + bw1.write("R0;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.R90: + bw1.write("R90;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + case ConnectionInfo.R180: + bw1.write("R180;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.R270: + bw1.write("R270;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + case ConnectionInfo.MY: + bw1.write("MY;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.MYR90: + bw1.write("MYR90;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + case ConnectionInfo.MX: + bw1.write("MX;\n"); + fx = sx / 2.0; + fy = sy / 2.0; + break; + + case ConnectionInfo.MXR90: + bw1.write("MXR90;\n"); + fx = sy / 2.0; + fy = sx / 2.0; + break; + + default: + throw new AssertionError(); + } + + bw1.write(s1 + "\tcoordinate = (" + coordinateX + ", " + coordinateY + ");\n"); + + bw1.write(s1 + "\tbounding_box = (" + + (coordinateX - fx) + ", " + + (coordinateY - fy) + ", " + + (coordinateX + fx) + ", " + + (coordinateY + fy) + ");\n"); + + } + + bw1.write(s1 + "}\n"); + } + catch(IOException e){ + e.printStackTrace(System.out); + } + } + + + public final int updateOrientation(int parentOrientation) + { + orientation = ConnectionInfo.composeOrientation(parentOrientation, orientation); + return orientation; + } + + public HierName getInstanceName() { + assert type == NetType.CELL || type == NetType.HALF_OPERATOR_TRANSISTOR; + return instanceName; + } + + public void prefixInstanceName(final /*@ non_null @*/ HierName prefix) { + assert type == NetType.CELL || type == NetType.HALF_OPERATOR_TRANSISTOR; + instanceName = + instanceName == null ? prefix + : HierName.append(prefix, instanceName); + } + + public float getDelayBias() { + return delayBias; + } + + public void setDelayBias(final float x) { + delayBias = Math.min(x, delayBias); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetType.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetType.java new file mode 100644 index 0000000000..f71b80b242 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetType.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +/** + * Net type used by {@link NetSink} and {@link NetSource}. + * + * @see NetSink + * @see NetSource + **/ +public final class NetType { + /** + * This class should not be instantiated. + **/ + private NetType() { } + + /** 0: half-operator and transistor. */ + public static final int HALF_OPERATOR_TRANSISTOR = 0; + /** 1: cell-type, only used during global net generation **/ + public static final int CELL = 1; + /** 2: capacitive load, for primary output **/ + public static final int CAPACITIVE_LOAD = 2; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetlistDistance.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetlistDistance.java new file mode 100644 index 0000000000..da5e2b8a3c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/NetlistDistance.java @@ -0,0 +1,708 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.file.cdl.parser.CDLSimpleFilter; +import com.avlsi.file.cdl.parser.CDLSimpleImpl; +import com.avlsi.file.cdl.parser.CDLSimpleInterface; +import com.avlsi.file.cdl.parser.Inline; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.common.HierName; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.SearchPath; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.util.text.StringUtil; + +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; + +/** + * Class to calculate the distance metric between 2 leaf cells with netlist + * bodies. The netlist bodies must have transistors and gates in the exact + * same order. Names must also be identical. + * + * @author Harry Liu + **/ +public final class NetlistDistance { + + private NetlistDistance() { + throw new AssertionError(); + } + + /** + * Interface used to calculate the metric. This should provide some + * modularity should the calculation be changed. + **/ + public interface DistanceCalculator { + /** + * Called when 2 corresponding transistors are found in the cells. + * @param width1 Width, in meters, of the transistor in the first cell. + * @param width2 Width, in meters, of the transistor in the second cell. + **/ + void transistor(final double width1, final double width2); + + /** + * Called when 2 corresponding gates are found in the cells. + * @param type Fully qualified type of the gate. + * @param params1 Parameters to the gate in the first cell. + * @param params2 Parameters to the gate in the second cell. + **/ + void gate(final String type, final Map params1, final Map params2); + + /** + * Called when a mismatch between the two cells are found. No other + * calls to the calculator will be made after a mismatch is detected. + **/ + void mismatch(); + } + + /** + * The default calculator calculates: + *
      + *
    1. Average absolute difference in transistor widths + *
    2. Maximum absolute difference in transistor widths + *
    . + * To make things easy, gates are handled as if each parameter to the gate + * is a transistor. + **/ + static class DefaultCalculator implements DistanceCalculator { + private int transistors; + private double maxWidthDiff; + private double widthDiffSum; + private boolean error; + + public DefaultCalculator() { + this.transistors = 0; + this.maxWidthDiff = 0; + this.widthDiffSum = 0; + this.error = false; + } + + public void transistor(final double width1, final double width2) { + ++transistors; + final double diff = Math.abs(width1 - width2); + maxWidthDiff = Math.max(maxWidthDiff, diff); + widthDiffSum += diff; + } + + public void gate(final String type, final Map params1, + final Map params2) { + for (Iterator i = params1.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Double d1 = (Double) entry.getValue(); + final Double d2 = (Double) params2.get(entry.getKey()); + transistor(d1.doubleValue(), d2.doubleValue()); + } + } + + public void mismatch() { + error = true; + } + + /** + * Returns the result of the calculation. The first element of the + * Pair is the average absolute difference in transistor widths, and + * the second is the maximum absolute difference in transistor widths. + * If the cells are found to be different, null is + * returned. + **/ + public Pair getResult() { + if (error) { + return null; + } else { + return new Pair(new Double(widthDiffSum / transistors), + new Double(maxWidthDiff)); + } + } + } + + /** + * A compiled form of a netlist body. It is good to avoid constructing the + * CompiledForm for a cell multiple times, because that is a potentially + * expensive process. Namely, the Template kept in the NetlistBlock + * contains raw tokens, which must be evaluated to get a double. This + * evaluation process involves constructing a CastTwoTreeParser, and using + * the expression rule, which is not very efficient. + **/ + static class CompiledForm { + private static class Helper extends CDLSimpleImpl { + private final Set result; + public Helper(final Set result) { + this.result = result; + } + public void makeTransistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, + HierName nb, double w, double l) { + result.add(new Transistor(name, type, ns, nd, ng, nb, w)); + } + public void makeCall(HierName name, String subName, + HierName[] args, Map parameters) { + result.add(new Call(name, subName, args, parameters)); + } + } + + interface Isomorphic { + /** + * Indicates whether some other object is isomorphic to this one, + * given a one-to-one mapping of names. + * + * @param o the object with which to compare + * @param to a mapping of names from the namespace of the current + * object to the namespace of the other object + * @param from a mapping of names from the namespace of the other + * object to the namespace of the current object + * + * @return true if this object is isomorphic to o; + * false otherwise. + **/ + boolean isIsomorphic(Object o, Map to, Map from); + } + + /** + * Determine if two names are equivalent under the given mapping. If + * the two names are not defined in the mapping, they are added. The + * mapping defines a one-to-one correspondence between names. + * + * @param n1 First name. + * @param n2 Second name. + * @param to Mapping from n1 to n2. + * @param from Mapping from n2 to n1. + * @return true if the names are equivalent and consistent with the + * given mapping. + **/ + private static boolean isomorphic(final HierName n1, final HierName n2, + final Map to, final Map from) { + assert n1 != null && n2 != null; + if (!to.containsKey(n1) && !from.containsKey(n2)) { + to.put(n1, n2); + from.put(n2, n1); + return true; + } else if (n2.equals(to.get(n1)) && n1.equals(from.get(n2))) { + return true; + } else { + return false; + } + } + + static class Transistor implements Isomorphic { + private final HierName name, ns, nd, ng, nb; + private final int type; + final double w; + + public Transistor(HierName name, int type, HierName ns, + HierName nd, HierName ng, HierName nb, + double w) { + this.name = name; + this.ns = ns; + this.nd = nd; + this.ng = ng; + this.nb = nb; + this.type = type; + this.w = w; + } + public boolean equals(final Object o) { + if (o instanceof Transistor) { + final Transistor t = (Transistor) o; + return name.equals(t.name) && + ns.equals(t.ns) && + nd.equals(t.nd) && + ng.equals(t.ng) && + nb.equals(t.nb) && + type == t.type; + } else { + return false; + } + } + public boolean isIsomorphic(final Object o, final Map to, + final Map from) { + if (o instanceof Transistor) { + final Transistor t = (Transistor) o; + return name.equals(t.name) && + isomorphic(ns, t.ns, to, from) && + isomorphic(nd, t.nd, to, from) && + isomorphic(ng, t.ng, to, from) && + isomorphic(nb, t.nb, to, from) && + type == t.type; + } else { + return false; + } + } + public String toString() { + final StringBuffer buf = new StringBuffer(); + buf.append("M"); + buf.append(name.toString()); + buf.append(" "); + buf.append(ns.toString()); + buf.append(" "); + buf.append(ng.toString()); + buf.append(" "); + buf.append(nd.toString()); + buf.append(" "); + buf.append(nb.toString()); + buf.append(" "); + buf.append(type); + buf.append(" "); + buf.append("W="); + buf.append(w); + return buf.toString(); + } + } + + static class Call implements Isomorphic { + private final HierName name; + final String subName; + final HierName[] args; + final Map parameters; + public Call(HierName name, String subName, HierName[] args, + Map parameters) { + this.name = name; + this.subName = subName; + this.args = args; + this.parameters = parameters; + } + public boolean equals(final Object o) { + if (o instanceof Call) { + final Call c = (Call) o; + return name.equals(c.name) && + subName.equals(c.subName) && + parameters.keySet().equals(c.parameters.keySet()); + } else { + return false; + } + } + public boolean isIsomorphic(final Object o, final Map to, + final Map from) { + if (o instanceof Call) { + final Call c = (Call) o; + for (int i = 0; i < args.length; ++i) { + if (!isomorphic(args[i], c.args[i], to, from)) { + return false; + } + } + return name.equals(c.name) && + subName.equals(c.subName) && + parameters.keySet().equals(c.parameters.keySet()); + } else { + return false; + } + } + public String toString() { + final StringBuffer buf = new StringBuffer(); + buf.append(name.toString()); + buf.append(" "); + buf.append(parameters.toString()); + buf.append(" "); + buf.append(subName); + return buf.toString(); + } + } + + interface MergePolicy { + /** + * Called when 2 corresponding transistors are found in the cells. + * @param width1 Width, in meters, of the transistor in the first + * cell. + * @param width2 Width, in meters, of the transistor in the second + * cell. + * @return Width, in meters, of the merged transistor + **/ + double transistor(final double width1, final double width2); + + /** + * Called when 2 corresponding gates are found in the cells. + * @param type Fully qualified type of the gate. + * @param params1 Parameters to the gate in the first cell. + * @param params2 Parameters to the gate in the second cell. + * @return Parameters to the merged gate. + **/ + Map gate(final String type, final Map params1, final Map params2); + } + + /** + * A sorted list of devices. This ensures that we compare things in + * the correct order, and do not depend on consistent ordering in + * netlist blocks. The compareTo operations of the devices do assume + * that the name of the devices are consistent, but that is easier to + * achieve. + **/ + final SortedSet devices; + + public CompiledForm(final CellInterface cell) { + this(cell, null); + } + + private static class DeviceComparator implements Comparator { + public int compare(final Object o1, final Object o2) { + if (o1 instanceof Call) { + final Call c1 = (Call) o1; + if (o2 instanceof Transistor) { + return -1; + } else { + final Call c2 = (Call) o2; + return c1.name.compareTo(c2.name); + } + } else { + final Transistor t1 = (Transistor) o1; + if (o2 instanceof Call) { + return 1; + } else { + final Transistor t2 = (Transistor) o2; + return t1.name.compareTo(t2.name); + } + } + } + } + + /** + * Constructs a CompiledForm for a CellInterface. This is equivalent + * to CompiledForm(cell, null, cfp). + * @param cell The cell to construct from. + * @param cfp If not null, read gate definitions from it, and inline + * them. + * @throws RuntimeException If the cell does not contain a netlist + * body. + **/ + public CompiledForm(final CellInterface cell, + final CastFileParser cfp) { + this(cell, null, cfp); + } + + /** + * Constructs a CompiledForm for a CellInterface. + * @param cell The cell to construct from. + * @param filter A filter that is used modify the input netlist + * @param cfp If not null, read gate definitions from it, and inline + * them. + * @throws RuntimeException If the cell does not contain a netlist + * body. + **/ + public CompiledForm(final CellInterface cell, + final CDLSimpleFilter filter, + final CastFileParser cfp) { + final NetlistBlock nb = + (NetlistBlock) cell.getBlockInterface() + .iterator(BlockInterface.NETLIST) + .next(); + if (nb.getCDLTemplate() == null) { + devices = null; + throw new RuntimeException("Cell " + cell.getFullyQualifiedType() + " does not have a netlist block"); + } else { + devices = new TreeSet(new DeviceComparator()); + final Helper helper = new Helper(devices); + + final CDLSimpleInterface inliner; + if (cfp == null) { + inliner = helper; + } else { + inliner = new Inline(false, new Inline.RetrieveFromCast(cfp)); + ((Inline) inliner).setProxy(helper); + } + + final CDLSimpleInterface executor; + if (filter == null) { + executor = inliner; + } else { + executor = filter; + filter.setOutput(inliner); + } + + nb.getCDLTemplate().execute(Collections.EMPTY_MAP, executor); + } + } + + private CompiledForm() { + devices = new TreeSet(new DeviceComparator()); + } + + /** + * Merge two compatible CompiledForm according to a MergePolicy. The + * result is undefined if the two CompiledForms are not compatible. + * @param form1 The first CompiledForm. + * @param form2 The second CompiledForm. + * @param policy MergePolicy to control how to merge. + * @return New merged CompiledForm. + **/ + public static CompiledForm merge(final CompiledForm form1, + final CompiledForm form2, + final MergePolicy policy) { + final CompiledForm result = new CompiledForm(); + for (Iterator i = form1.devices.iterator(), + j = form2.devices.iterator(); i.hasNext(); ) { + final Object ii = i.next(); + final Object elem; + if (ii instanceof Transistor) { + final Transistor jj = (Transistor) j.next(); + final double w = + policy.transistor(((Transistor) ii).w, jj.w); + elem = new Transistor(jj.name, jj.type, jj.ns, jj.nd, jj.ng, + jj.nb, w); + + } else { + final Call jj = (Call) j.next(); + final Map params = policy.gate(jj.subName, + ((Call) ii).parameters, + jj.parameters); + elem = new Call(jj.name, jj.subName, jj.args, params); + } + result.devices.add(elem); + } + return result; + } + } + + public static CompiledForm getCompiledForm(final CellInterface cell) { + return getCompiledForm(cell, null); + } + + /** + * Convert a CellInterface to its corresponding CompiledForm. + * @param cell The cell to convert. + * @param cfp If not null, the file parser to read gate definitions from. + * @return The compiled form of the CellInterface. + **/ + public static CompiledForm getCompiledForm(final CellInterface cell, + final CastFileParser cfp) { + return new CompiledForm(cell, cfp); + } + + /** + * Convert a CellInterface to its corresponding CompiledForm. + * @param cell The cell to convert. + * @param filter A filter that is used modify the input netlist. + * @param cfp If not null, the file parser to read gate definitions from. + * @return The compiled form of the CellInterface. + **/ + public static CompiledForm getCompiledForm(final CellInterface cell, + final CDLSimpleFilter filter, + final CastFileParser cfp) { + return new CompiledForm(cell, filter, cfp); + } + + /** + * Convert the values in a Map of String to Doubles to a double[]. + **/ + private static double[] gateParameters(final Map parameters) { + final double[] result = new double[parameters.size()]; + int k = 0; + for (Iterator i = parameters.values().iterator(); i.hasNext(); ++k) { + result[k] = ((Double) i.next()).doubleValue(); + } + return result; + } + + /** + * Calculate the distance between 2 cells given their CompiledForms using + * the given distance calculator. If the distance to a cell is to be + * computed multiple times, it would be more efficient to convert the cell + * to CompiledForm first, and use this form of the call. + * @param cell1 The first cell. + * @param cell2 The second cell. + * @param dc The distance calculator. + **/ + public static void getDistance(final CompiledForm cell1, + final CompiledForm cell2, + final DistanceCalculator dc) { + final Map to = new HashMap(); + final Map from = new HashMap(); + + final Set devices1 = cell1.devices; + final Set devices2 = cell2.devices; + if (devices1.size() != devices2.size()) { + dc.mismatch(); + } else { + for (Iterator i = devices1.iterator(), j = devices2.iterator(); + i.hasNext(); ) { + final CompiledForm.Isomorphic ii = + (CompiledForm.Isomorphic) i.next(); + final CompiledForm.Isomorphic jj = + (CompiledForm.Isomorphic) j.next(); + if (ii.isIsomorphic(jj, to, from)) { + if (ii instanceof CompiledForm.Call) { + final Map mi = ((CompiledForm.Call) ii).parameters; + final Map mj = ((CompiledForm.Call) jj).parameters; + final String subName = ((CompiledForm.Call) ii).subName; + dc.gate(subName, mi, mj); + } else { + dc.transistor(((CompiledForm.Transistor) ii).w, + ((CompiledForm.Transistor) jj).w); + } + } else { + dc.mismatch(); + break; + } + } + } + } + + /** + * Calculate the distance between 2 cells given their CellInterfaces using + * the given distance calculator. The cells are automatically converted to + * their CompiledForms first. + * @param cell1 The first cell. + * @param cell2 The second cell. + * @param dc The distance calculator. + **/ + public static void getDistance(final CellInterface cell1, + final CellInterface cell2, + final DistanceCalculator dc) { + getDistance(getCompiledForm(cell1), getCompiledForm(cell2), dc); + } + + /** + * Return the distance between 2 cells given their CellInterfaces using the + * default distance calculator. The cells are automatically converted to + * their CompiledForms first. + * @param cell1 The first cell. + * @param cell2 The second cell. + * @return The distance metric between the 2 cells as a Pair, or + * null if the cells are incompatible. The first element of + * the Pair is the average absolute difference in transistor widths, and + * the second is the maximum absolute difference in transistor widths. + **/ + public static Pair getDistance(final CellInterface cell1, + final CellInterface cell2) { + final DefaultCalculator dc = new DefaultCalculator(); + getDistance(cell1, cell2, dc); + return dc.getResult(); + } + + private static CellInterface loadCell(final String castPath, + final String cellName, + final String castVersion) + throws CastSyntaxException, CastSemanticException, IOException { + final CastFileParser castParser = + new CastFileParser(new FileSearchPath(castPath), castVersion); + return castParser.getFullyQualifiedCell(cellName); + } + + private static void usage() { + System.err.println("java com.avlsi.tools.jauto.NetlistDistance"); + System.err.println("[ --cast-path= ] (defaults to .)"); + System.err.println("[ --cast-version=[ 1 | 2 ] ] (defaults to 2)"); + System.err.println("--cell= (cell to compare)"); + System.err.println("[ --library-cells=:... ] (cells to compare against"); + System.err.println("[ --library-cells-file= ] (file listing cells to compare against"); + System.exit(1); + } + + private static String printField(final String s, final int length, + final boolean right) { + if (s.length() < length) { + final String sp = StringUtil.repeatString(" ", length - s.length()); + return right ? sp + s : s + sp; + } else { + return s; + } + } + + private static String printLeft(final String s, final int length) { + return printField(s, length, false); + } + + private static String printRight(final String s, final int length) { + return printField(s, length, true); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl(args); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs(argsWithConfigs); + + final CommandLineArgs theArgs = cachedArgs; + final String castPath = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cadenceName = theArgs.getArgValue("cell", null); + final String libraryCells = theArgs.getArgValue("library-cells", null); + final String libraryFile = + theArgs.getArgValue("library-cells-file", null); + + final CadenceReverseNameInterface crni = new CadenceReverseNameInterface(); + final String cellName = crni.renameCell(cadenceName); + + if (cellName == null) { + System.err.println("ERROR: You must specify the cell to compare."); + usage(); + } + + final SearchPath sp = new FileSearchPath(castPath); + final CastFileParser cfp = new CastFileParser(sp, castVersion); + final CellInterface cell = cfp.getFullyQualifiedCell(cellName); + final Collection library = new ArrayList(); + + if (libraryCells != null) { + final String[] cells = StringUtil.split(libraryCells, ':'); + for (int i = 0; i < cells.length; ++i) { + library.add(cfp.getFullyQualifiedCell(cells[i])); + } + } + + if (libraryFile != null) { + final BufferedReader fr = + new BufferedReader(new FileReader(libraryFile)); + String line; + while ((line = fr.readLine()) != null) { + CellInterface currCellInterface = null; + try { + currCellInterface = cfp.getFullyQualifiedCell(line); + } + catch ( Exception e ) {} + if ( currCellInterface != null ) { + library.add( currCellInterface ); + } + } + fr.close(); + } + + for (Iterator i = library.iterator(); i.hasNext(); ) { + final CellInterface target = (CellInterface) i.next(); + final Pair result = getDistance(cell, target); + if (result != null) { + final StringBuffer buf = new StringBuffer(); + double avgW = ((Double) result.getFirst()).doubleValue() * 1e9; + double maxW = ((Double) result.getSecond()).doubleValue() * 1e9; + buf.append(printLeft(target.getFullyQualifiedType(), 40)); + buf.append('\t'); + buf.append(printRight(Long.toString(Math.round(avgW)), 10)); + buf.append('\t'); + buf.append(printRight(Long.toString(Math.round(maxW)), 10)); + System.out.println(buf.toString()); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/PartialExtract.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/PartialExtract.java new file mode 100644 index 0000000000..1b193d50e9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/PartialExtract.java @@ -0,0 +1,635 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.jauto; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.collections.AST; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast2.impl.CastTwoLexer; +import com.avlsi.cast2.impl.CastTwoParser; +import com.avlsi.cast2.impl.CastTwoTreeParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.prs.ProductionRule; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cosim.CoSimParameters; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; + +public final class PartialExtract { + public interface Info { + int INCLUDE = 0, EXCLUDE = 1; + int getAction(final HierName instance); + } + + private final Info info; + private final String top; + private final Map cells; + private final Map results; + + public PartialExtract(final Map cells, + final String top, + final Info info) { + this.cells = cells; + this.top = top; + this.info = info; + this.results = new HashMap(); + } + + private static class CellMaker implements Template.Visitor { + private final CDLFactoryInterface target; + + /** + * A mapping from instance name (HierName) to instance type (String). + **/ + private final Map instances; + + public CellMaker(final CDLFactoryInterface target, final Map instances) + { + this.target = target; + this.instances = instances; + } + + public void resistorStatement(final HierName name, + final HierName n1, + final HierName n2, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { + target.makeResistor(name, n1, n2, val, parameters, env); + } + + public void capacitorStatement(final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { + target.makeCapacitor(name, npos, nneg, val, parameters, env); + } + + public void transistorStatement(final HierName name, + final String type, + final HierName ns, + final HierName nd, + final HierName ng, + final HierName nb, + final CDLLexer.InfoToken w, + final CDLLexer.InfoToken l, + final Map parameters, + final Environment env) { + target.makeTransistor(name, type, ns, nd, ng, nb, w, l, parameters, + env); + } + + public void inductorStatement(final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { + target.makeInductor(name, npos, nneg, val, parameters, env); + } + + public void diodeStatement(final HierName name, + final String type, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { + target.makeDiode(name, type, npos, nneg, val, parameters, env); + } + + public void bipolarStatement(final HierName name, + final String type, + final HierName nc, + final HierName nb, + final HierName ne, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { + target.makeBipolar(name, type, nc, nb, ne, val, parameters, env); + } + + public void callStatement(final HierName name, + final String subName, + final HierName[] args, + final Map parameters, + final Environment env) { + final String realSub = (String) instances.get(name); + if (realSub != null) { + target.makeCall(name, realSub, args, parameters, env); + } + } + } + + private Template makeCell(final Template templ, final Map instances) { + final Map m = new HashMap(); + final String name = "DUMMY"; + final Template newTempl = new Template(m); + final Pair args = templ.getArguments(); + final Environment nullEnv = NullEnvironment.getInstance(); + newTempl.beginSubcircuit(name, + (String[]) args.getFirst(), + (String[]) args.getSecond(), + templ.getParameters(), + nullEnv); + final CellMaker maker = new CellMaker(newTempl, instances); + for (Template.StatementIterator i = templ.getStatements(); + i.hasNext(); ) { + i.next(maker); + } + newTempl.endSubcircuit(name, nullEnv); + return (Template) m.get(name); + } + + public interface CellResultHandler { + void setCellName( final String cellName ); + void handleSubtype( final String subTypeName, + final Map instances ); + } + + public void traverseResult( final CellResultHandler handler ) { + final Iterator cellEntryIter = results.entrySet().iterator(); + while ( cellEntryIter.hasNext() ) { + final Map.Entry cellEntry = ( Map.Entry ) cellEntryIter.next(); + final String cellName = ( String ) cellEntry.getKey(); + final Map cellMap = ( Map ) cellEntry.getValue(); + + final Iterator cellSubtypeEntryIter = cellMap.entrySet().iterator(); + + handler.setCellName( cellName ); + + while ( cellSubtypeEntryIter.hasNext() ) { + final Map.Entry subTypeEntry = ( Map.Entry ) cellSubtypeEntryIter.next(); + final Map instanceMap = ( Map ) subTypeEntry.getKey(); + final Pair subTypeInfo = ( Pair ) subTypeEntry.getValue(); + final String subTypeName = ( String ) subTypeInfo.getFirst(); + + handler.handleSubtype( subTypeName, + instanceMap ); + } + } + } + + /** + * Given the name of a cell, and a map of instance names + * (HierName) to cell types (String) for + * instances that exist in the cell, return the name of the cell that + * implements that specification. The order of pairs inside the list + * should be consistent, for a given cell. + **/ + private String getCell(final String name, final Map instances) { + if (!results.containsKey(name)) results.put(name, new HashMap()); + + final Map m = (Map) results.get(name); + Pair result = (Pair) m.get(instances); + if (result == null) { + final Template t = (Template) cells.get(name); + assert t != null : "No template found for cell " + name; + + result = new Pair(name + "." + m.size(), makeCell(t, instances)); + m.put(instances, result); + } + return (String) result.getFirst(); + } + + private class Traverser implements Template.Visitor { + private final HierName prefix; + private final Map instances; + + public Traverser(final HierName prefix, final Map instances) { + this.prefix = prefix; + this.instances = instances; + } + + public void resistorStatement(final HierName name, + final HierName n1, + final HierName n2, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { } + + public void capacitorStatement(final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { } + + public void transistorStatement(final HierName name, + final String type, + final HierName ns, + final HierName nd, + final HierName ng, + final HierName nb, + final CDLLexer.InfoToken w, + final CDLLexer.InfoToken l, + final Map parameters, + final Environment env) { } + + public void inductorStatement(final HierName name, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { } + + public void diodeStatement(final HierName name, + final String type, + final HierName npos, + final HierName nneg, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { } + + public void bipolarStatement(final HierName name, + final String type, + final HierName nc, + final HierName nb, + final HierName ne, + final CDLLexer.InfoToken val, + final Map parameters, + final Environment env) { } + + public void callStatement(final HierName name, + final String subName, + final HierName[] args, + final Map parameters, + final Environment env) { + final HierName fullName = HierName.append(prefix, name); + final int subBehav = info.getAction(fullName); + if (subBehav == Info.INCLUDE) { + final Template templ = (Template) cells.get(subName); + if (templ == null) { + throw new RuntimeException("Cannot find cell " + subName); + } + final Map m = process(templ, fullName); + final String s = PartialExtract.this.getCell(subName, m); + instances.put(name, s); + } + } + } + + private Map process(final Template templ, final HierName prefix) { + final Map instances = new HashMap(); + final Traverser trav = new Traverser(prefix, instances); + for (Template.StatementIterator i = templ.getStatements(); + i.hasNext(); ) { + i.next(trav); + } + return instances; + } + + private String process() { + final Template t = (Template) cells.get(top); + //final Map instances = process(t, HierName.makeHierName("X")); + final Map instances = process(t, null); + return getCell(top, instances); + } + + public void execute(final CDLFactoryInterface target) { + final String newTop = process(); + final Environment env = new LocalEnvironment(); + for (Iterator i = cells.keySet().iterator(); i.hasNext(); ) { + final String sub = (String) i.next(); + final Map m = (Map) results.get(sub); + if (m != null) { + for (Iterator j = m.entrySet().iterator(); j.hasNext(); ) { + final Map.Entry entry = (Map.Entry) j.next(); + final Pair p = (Pair) entry.getValue(); + final String cellName = (String) p.getFirst(); + final Template templ = (Template) p.getSecond(); + templ.execute(target, env, cellName); + } + } + } + } + + /** + * Return a data structure representing a FQCN+- (fully qualified cell name + * plus/minus instances, i.e., lib.math.add.ADD_32.0-kpg3+data3[0].ctrl). + * The result is a Triplet of top cell name, a environment + * name which might be null, and a Collection + * containing Pairs of instance name as HierName + * and if it is a plus as Boolean (so the above example would + * be mapped to: (lib.math.add.ADD_32.0 [(kpg3 false) (data3[0].ctrl + * true)]). + **/ + public static Triplet parseCellPlusMinus(final String fqcn) { + final String err = + "Cannot parse fully qualified cell name plus minus: " + fqcn; + final CastTwoParser castParser = + CastTwoParser.getParser(fqcn, 0, 0, ""); + try { + castParser.partialExtraction(); + } catch (RecognitionException e) { + throw new RuntimeException(err, e); + } catch (TokenStreamException e) { + throw new RuntimeException(err, e); + } + + final AST ast = castParser.getAST(); + + final CastTwoTreeParser treeParser = new CastTwoTreeParser(); + try { + return treeParser.partialExtract(ast); + } catch (RecognitionException e) { + throw new RuntimeException(err, e); + } + } + + public interface LeafCallback { + Object leaf(CellInterface cell, HierName inst, HierName canon); + Object midlevel(Object o, CellInterface cell, HierName inst, + HierName canon); + } + + private static Pair getInstancePort(final HierName name, + final CellInterface cell) { + HierName prefix = name; + HierName suffix = null; + while (prefix != null && cell.getSubcell(prefix) == null) { + final HierName child = + HierName.makeHierName(prefix.getSuffixString()); + suffix = suffix == null ? child : HierName.append(child, suffix); + prefix = prefix.getParent(); + } + if (prefix == null) return null; + else return new Pair(prefix, suffix); + } + + public static Set getLeafDrivers(final CellInterface cell, + final HierName canon, + final Cadencize cad, + final Map cache, + final LeafCallback cb) { + final Pair key = new Pair(cell, canon); + final Set cached = (Set) cache.get(key); + if (cached != null) return cached; + + final Set result = new HashSet(); + final CadenceInfo ci = cad.convert(cell); + final AliasedSet local = ci.getLocalNodes(); + final Set seen = new HashSet(); + for (Iterator i = local.getAliases(canon); i.hasNext(); ) { + final HierName alias = (HierName) i.next(); + final Pair instancePort = getInstancePort(alias, cell); + assert instancePort != null : alias + " cannot be found in " + + cell.getFullyQualifiedType(); + final HierName inst = (HierName) instancePort.getFirst(); + final HierName port = (HierName) instancePort.getSecond(); + + final CellInterface subcell = cell.getSubcell(inst); + if (subcell.isNode() || subcell.isChannel()) continue; + + final CadenceInfo subci = cad.convert(subcell); + final AliasedMap ports = subci.getPortNodes(); + if (!((Boolean) ports.getValue(port)).booleanValue()) continue; + + final HierName subcanon = (HierName) + subci.getLocalNodes().getCanonicalKey(port); + + if (!seen.add(new Pair(inst, subcanon))) continue; + + if (CellUtils.isLeaf(subcell)) { + final Object o = cb.leaf(subcell, inst, subcanon); + if (o != null) result.add(o); + } else { + final Set subresult = + getLeafDrivers(subcell, subcanon, cad, cache, cb); + for (Iterator k = subresult.iterator(); k.hasNext(); ) { + final Object o = + cb.midlevel(k.next(), subcell, inst, subcanon); + if (o != null) result.add(o); + } + } + } + + final Set readOnly = Collections.unmodifiableSet(result); + cache.put(key, readOnly); + return readOnly; + } + + public static class CellPlusMinusKeyword extends CellPlusMinus { + private static Collection powerRails; + private Triplet spec; + public CellPlusMinusKeyword(final String spec, final int def) { + this(parseCellPlusMinus(spec), def); + } + public CellPlusMinusKeyword(final Triplet spec, final int def) { + super((String) spec.getFirst(), new HashMap(), new HashSet(), def, + null, (String) spec.getSecond()); + this.spec = spec; + } + public CellPlusMinusKeyword(final String spec, final int def, + final CastFileParser cfp, + final Cadencize cad) + throws CastSemanticException { + this(spec, def); + initialize(cfp, cad); + } + public void initialize(final CastFileParser cfp, final Cadencize cad) + throws CastSemanticException { + initialize(cfp.getFullyQualifiedCell(getTop()), cad); + } + private Collection getPowerRails() { + if (powerRails == null) { + powerRails = Arrays.asList(HierName.makeHierName("GND"), + HierName.makeHierName("Vdd")); + } + return powerRails; + } + public void initialize(final CellInterface cell, final Cadencize cad) { + final Collection c = (Collection) spec.getThird(); + + String keyword = null; + if (c.size() == 1) { + final Pair p = (Pair) c.iterator().next(); + if (!((Boolean) p.getSecond()).booleanValue()) { + keyword = (String) p.getFirst(); + } + } + + if (keyword != null && (keyword.equals("+localnodes") || + keyword.equals("+portnodes") || + keyword.equals("+localportnodes"))) { + this.def = Info.EXCLUDE; + final boolean all = keyword.equals("+localportnodes"); + final boolean port = keyword.equals("+portnodes"); + final Map cache = new HashMap(); + final CadenceInfo ci = cad.convert(cell); + final AliasedSet localNodes = ci.getLocalNodes(); + final AliasedMap portNodes = ci.getPortNodes(); + + // determine the canonical name of power rails; they must be + // ports + final Set canonRails = new HashSet(); + for (HierName rail : getPowerRails()) { + final HierName canon = + (HierName) localNodes.getCanonicalKey(rail); + if (canon != null && portNodes.contains(canon)) + canonRails.add(canon); + } + + for (Iterator i = localNodes.getCanonicalKeys(); + i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + if (canonRails.contains(canon) || + (!all && portNodes.contains(canon) != port)) + continue; + final Set drivers = getLeafDrivers(cell, canon, cad, cache, + new LeafCallback() { + public Object leaf(CellInterface cell, + HierName inst, HierName canon) { + return inst; + } + public Object midlevel(Object o, CellInterface cell, + HierName inst, + HierName canon) { + final HierName h = (HierName) o; + return HierName.append(inst, h); + } + }); + for (Iterator j = drivers.iterator(); j.hasNext(); ) { + final HierName inst = (HierName) j.next(); + addInstance(inst, Boolean.TRUE); + setDescedents(inst); + } + } + setRest(keyword); + } else { + setRest(processSpec(c)); + } + spec = null; + } + public int getAction(HierName instance) { + assert spec == null : "Need to call initialize first"; + return super.getAction(instance); + } + public boolean isEmpty() { + assert spec == null : "Need to call initialize first"; + return super.isEmpty(); + } + } + + public static class CellPlusMinus implements Info { + private final String top; + private final Map instances; + private final Set hasDescedents; + protected int def; + private String rest; + private final String env; + public CellPlusMinus(final String spec, final int def) { + this(parseCellPlusMinus(spec), def); + } + public CellPlusMinus(final Triplet spec, final int def) { + this((String) spec.getFirst(), new HashMap(), new HashSet(), def, + null, (String) spec.getSecond()); + setRest(processSpec((Collection) spec.getThird())); + } + protected CellPlusMinus(final String top, final Map instances, + final Set hasDescedents, final int def, + final String rest, final String env) { + this.top = top; + this.instances = instances; + this.hasDescedents = hasDescedents; + this.def = def; + this.rest = rest; + this.env = env; + } + protected String processSpec(Collection c) { + final StringBuffer sb = new StringBuffer(); + for (Iterator i = c.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final String sinst = (String) p.getFirst(); + final HierName inst; + try { + inst = HierName.makeHierName(sinst, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot create HierName for: " + sinst); + } + final Boolean plus = (Boolean) p.getSecond(); + addInstance(inst, plus); + if (plus.booleanValue()) { + sb.append('+'); + setDescedents(inst); + } else { + sb.append('-'); + } + sb.append(sinst); + } + return sb.toString(); + } + protected void addInstance(final HierName inst, final Boolean plus) { + instances.put(inst, plus); + } + protected void setDescedents(HierName instance) { + while (instance != null) { + hasDescedents.add(instance); + instance = instance.getParent(); + } + } + public int getAction(HierName instance) { + if (hasDescedents.contains(instance)) return Info.INCLUDE; + while (instance != null) { + final Boolean plus = (Boolean) instances.get(instance); + if (plus != null) + return plus.booleanValue() ? Info.INCLUDE : Info.EXCLUDE; + instance = instance.getParent(); + } + return def; + } + public String getTop() { + return top; + } + public String getEnvironment() { + return env; + } + protected void setRest(final String rest) { + this.rest = rest; + } + public String getRest() { + return rest; + } + public boolean isEmpty() { + return instances.isEmpty(); + } + } + + public static void main(String[] args) { + final Triplet p = parseCellPlusMinus(args[0]); + System.out.println("p = " + p); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizeStaticizers.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizeStaticizers.java new file mode 100644 index 0000000000..41e5d1b154 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizeStaticizers.java @@ -0,0 +1,516 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.*; +import java.util.*; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.fast.*; +import com.avlsi.tools.jauto.*; +import com.avlsi.util.debug.Debug; + +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; + + +public class SizeStaticizers { + + /** + * Size feedback transistors for all the staticizers in the + * tool's synthesized design to strength + * + * @param tool + * The tool whose synthesized design should have its staticizers + * sized and whose staticizer ratio should be used. + **/ + public static void sizeStaticizers(TransistorSizingTool tool) { + sizeStaticizers(tool.getSynthesizedDesign()); + } + + /** + * Sizes a staticizer so its conductance G to satisfies + * minG<=G<=maxG and leakG<=G. If userG!=0, instead tries to + * satisfy G==userG. Reports violations of these constraints. + * + * @param tdata + * Technology data + * @param node + * Output NetNode + * @param npa + * Feedback NetPath to size + * @param minG + * Minimum staticizer conductance + * @param maxG + * Maximum staticizer conductance + * @param leakG + * Minimum staticizer conductance for leakage + * @param userG + * Desired staticizer conductance from staticizer_ratio directive + **/ + private static void setStaticizerStrength(TechnologyData tdata, + NetGraph.NetNode node, + NetGraph.NetPath npa, + double minG, double maxG, + double leakG, double userG, + ArrayList report) { + boolean nmos = npa.getType() == DeviceTypes.N_TYPE; + int ttype = npa.getTransistorType(); + int maxDepth = nmos ? tdata.staticizerMaxDepthN : tdata.staticizerMaxDepthP; + double incW = tdata.staticizerWidthGrid; + double minW = tdata.minimumTransistorWidth; + double L = tdata.minimumTransistorLength; + double lG = Math.max(minG,leakG); + double uG = maxG; + if (userG!=0) lG = uG = userG; + double G=0; + if (!npa.isWeakFeedBack()) { + // size combinational staticizer by increasing width and checking G + // report.add("NOTE: sizing combinational staticizer on " + node.name); + int depth = npa.getDepth(); + double erf = nmos ? + tdata.getEffectiveResistanceFactorN(ttype,depth-1) : + tdata.getEffectiveResistanceFactorP(ttype,depth-1); + // for vanBerkel gates, don't make feedback wider than logic + double maxW = npa.getMinWidth(true); + if (maxW==0) maxW=100*minW; // TODO: something less arbitrary + for (double W=minW; W<=maxW; W+=incW) { + npa.sizeFeedback(W); + G = 1 / npa.getSquares() / erf; + if (G> uG) break; // too strong already, quit now + if (G>=lG) break; // found a good width, finish + } + } else { + // search depth and width for the best weak staticizer + // G<=uG takes precedence over G>=lG + int depth; + double W=0; + for (depth=1; depth<=maxDepth; depth++) { + double erf = nmos ? + tdata.getEffectiveResistanceFactorN(ttype,depth-1) : + tdata.getEffectiveResistanceFactorP(ttype,depth-1); + // pick narrowest staticizer allowed + W = lG * L * depth * erf; + W = Math.max(minW,incW*Math.ceil(W/incW)); + G = W / L / depth / erf; + if (G>uG) { + // pick widest staticizer allowed + W = uG * L * depth * erf; + W = Math.max(minW,incW*Math.floor(W/incW)); + G = W / L / depth / erf; + } + if (G<=uG) break; // staticizer with this depth works + } + if (depth>maxDepth) depth=maxDepth; + + // size feedback path + npa.sizeWeakFeedBack(W,tdata.minimumTransistorLength,depth); + } + + // report staticizer sizing violations + String s = (nmos ? "NMOS" : "PMOS") + " staticizer on " + + node.name + (nmos ? "+" : "-"); + if (G>maxG*1.01) + report.add("ERROR: " + s + " violates maxStaticizerRatio by " + + NumberFormatter.format(G/maxG,3) + " times"); + if (GuserG*1.1 || Gdesign + * + * @param design + * The design whose staticizers are to be sized. + **/ + public static void sizeStaticizers(final CastDesign design) { + // get relevant technology data + TechnologyData tdata = design.getTechnologyData(); + double gateL = tdata.getDefaultGateLength(); + double minStaticizerRatio = tdata.minStaticizerRatio; + double maxStaticizerRatio = tdata.maxStaticizerRatio; + double minCombinationalStaticizerRatio = tdata.minCombinationalStaticizerRatio; + double maxCombinationalStaticizerRatio = tdata.maxCombinationalStaticizerRatio; + double staticizerLeakageRatio = tdata.staticizerLeakageRatio; + + // start processing all cells + for (Iterator ita = design.allCellTypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + ArrayList report = new ArrayList(); + if (! JautoUI.quiet) + System.out.println("Sizing staticizers in cell " + sta.typeName + "..."); + + // query staticizer_ratio directives + final Map ratios = DirectiveUtils.getPrsDirective(sta.cast_cell, + DirectiveConstants.STATICIZER_RATIO, + DirectiveConstants.HALFOP_TYPE); + final Map ratioUp = DirectiveUtils.canonizeKey(sta.namespace, + DirectiveUtils.getUps(ratios)); + final Map ratioDn = DirectiveUtils.canonizeKey(sta.namespace, + DirectiveUtils.getDowns(ratios)); + final Float cellRatio = + (Float) DirectiveUtils.getTopLevelDirective(sta.cast_cell, + DirectiveConstants.STATICIZER_RATIO); + + // process all local CellNet's of this cell + for (Iterator itb = sta.getAllNets().iterator(); itb.hasNext(); ) { + + // get CellNet, Name, NetNode + CellNet outputNet = (CellNet) itb.next(); + String Name = outputNet.canonicalName.toString(); + NetGraph.NetNode outputNode = + sta.transistors.findNetNode(outputNet.canonicalName); + if (outputNode==null) continue; // no transistors + + // get half-operator staticizer_ratio directives + double upRatio = getStaticizerRatio(ratioUp, outputNet.canonicalName, cellRatio); + double dnRatio = getStaticizerRatio(ratioDn, outputNet.canonicalName, cellRatio); + + // prepare to accumulate leakage and active strengths and transistor_types + double minPullDnSize = Double.POSITIVE_INFINITY; + double minPullUpSize = Double.POSITIVE_INFINITY; + double maxPullUpWidth = 0; + double maxPullDnWidth = 0; + int tt_up = 0; + int tt_dn = 0; + + // get all global nets for this CellNet + List/**/ globalNets = outputNet.getGlobalNets(); + assert globalNets.size() != 0 + : "CellNet has no corresponding global net.\n" + + "CellName: " + sta.typeName + "\n" + + "NetName: " + + outputNet.canonicalName.getCadenceString(); + + // search through GlobalNet's to find leakage and active sizes and tt + for (Iterator itc = globalNets.iterator(); itc.hasNext(); ) { + GlobalNet gna = (GlobalNet)itc.next(); + + // find largest N and P diffusion perimeter for leakage strength ratio + double upWidth = gna.getTotalDriverWidth(DeviceTypes.P_TYPE); + double dnWidth = gna.getTotalDriverWidth(DeviceTypes.N_TYPE); + if (upWidth > maxPullUpWidth) maxPullUpWidth = upWidth; + if (dnWidth > maxPullDnWidth) maxPullDnWidth = dnWidth; + + // find weakest logic half-operator for active strength ratio, plus tt + for (Iterator itd = gna.getListSources().iterator(); itd.hasNext(); ) { + NetSource nsra = (NetSource)itd.next(); + if(nsra.getType() == NetType.HALF_OPERATOR_TRANSISTOR){ + HalfOperator hob = nsra.source; + double hobSize = hob.getCurrentSize(); + int tt = hob.getTransistorType(); + if (hob.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + if (hobSize < minPullDnSize) minPullDnSize = hobSize; + if (tt_dn==0) tt_dn = tt; + else if (tt_dn!=tt) tt_dn=-1; // detect mixed transistor_type + } + else { + if (hobSize < minPullUpSize) minPullUpSize = hobSize; + if (tt_up==0) tt_up = tt; + else if (tt_up!=tt) tt_up=-1; // dected mixed transistor_type + } + } + } + } + + // size feedback paths of this outputNode based on active and leakage conductance + outputNode.findPaths(); + for (Iterator itc = outputNode.getFeedbackPaths().iterator(); itc.hasNext(); ) { + NetGraph.NetPath npa = (NetGraph.NetPath)itc.next(); + boolean nmos = (npa.getType()==DeviceTypes.N_TYPE); + boolean weak = npa.isWeakFeedBack(); + double minSR = weak ? minStaticizerRatio : minCombinationalStaticizerRatio; + double maxSR = weak ? maxStaticizerRatio : maxCombinationalStaticizerRatio; + if (nmos && tt_up>0) { // size staticizer pull-down + double erfP = tdata.getEffectiveResistanceFactorP(tt_up, 0); + double leakP = tdata.getLeakageResistanceP(tt_up); + double logicG = minPullUpSize / gateL / erfP; + double leakG = maxPullUpWidth / gateL / leakP * staticizerLeakageRatio; + double minG = logicG * minSR; + double maxG = logicG * maxSR; + double userG = logicG * upRatio; + setStaticizerStrength(tdata,outputNode,npa,minG,maxG,leakG,userG,report); + } else if (!nmos && tt_dn>0) { // size staticizer pull-up + double erfN = tdata.getEffectiveResistanceFactorN(tt_dn, 0); + double leakN = tdata.getLeakageResistanceN(tt_dn); + double logicG = minPullDnSize / gateL / erfN; + double leakG = maxPullDnWidth / gateL / leakN * staticizerLeakageRatio; + double minG = logicG * minSR; + double maxG = logicG * maxSR; + double userG = logicG * dnRatio; + setStaticizerStrength(tdata,outputNode,npa,minG,maxG,leakG,userG,report); + } else { + report.add("WARNING: " + Name + (nmos ? "+" : "-") + + " has " + (nmos ? "NMOS" : "PMOS") + + " feedback but opposing logic is missing or mixed threshold"); + } + } + } + + // debug netgraph + // System.err.println("NetGraph of cell " + sta.typeName); + // System.err.println(sta.transistors); + + // report anything interesting for this cell type + if (report.size()!=0) { + System.err.println("Sizing staticizers in cell " + sta.typeName); + for (Iterator itb=report.iterator(); itb.hasNext(); ) { + String s = (String) itb.next(); + System.err.println(s); + } + System.err.println(); + } + } + + // TODO: deprecate everything about precharge transistors + if (hasPrechargeTransistors(design)) { + System.err.println("ERROR: precharge transistors not supported\n"); + System.exit(1); + } + } + + /** Check to see if precharge transistors exist in the design **/ + private static boolean hasPrechargeTransistors(final CastDesign design) { + for (Iterator i = design.allCellTypes.iterator(); i.hasNext(); ) { + CellType cell = (CellType) i.next(); + for (Iterator j = cell.transistors.getNodes().iterator(); j.hasNext(); ) { + final NetGraph.NetNode node = (NetGraph.NetNode) j.next(); + final NetGraph.GateInstance gate = node.getGate(); + if (gate != null && gate.isPrechargePrimitive()) { + return true; + } + } + } + return false; + } + + /** Convert a length in meters to microns. **/ + private static String toMicron(final double length, final int precision) { + return NumberFormatter.format(length * 1e6, precision) + "um"; + } + + /** TODO: remove **/ + private static void sizePrechargeTransistor(final CastDesign design, + final CellType cell, + final NetGraph.NetNode node) { + final TechnologyData tdata = design.getTechnologyData(); + + // find the pre-(dis)charge transistor + NetGraph.NetEdge precharge = null; + for (Iterator i = node.getEdges(); i.hasNext() && precharge == null; ) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) i.next(); + if (edge.precharge) precharge = edge; + } + + assert precharge.type == DeviceTypes.N_TYPE || + precharge.type == DeviceTypes.P_TYPE; + assert precharge != null : "No pre-(dis)charge transistor found on " + + "node: " + node.name + " in " + + cell.typeName; + + // determine if this is a pre-charge or a pre-discharge transistor; it + // is impossible to have both a pre-charge and a pre-discharge + // transistor on the same node + final boolean isPrecharge = + (precharge.type == DeviceTypes.N_TYPE && + (precharge.source.isVdd() || precharge.drain.isVdd())) || + (precharge.type == DeviceTypes.P_TYPE && + (precharge.source.isGND() || precharge.drain.isGND())); + + // size the pre-discharge transistor as if it were a staticizer by + // copying the length and width from the appropriate transistor in the + // staticizer, which we assume has already been sized properly + if (!isPrecharge) { + // find the output node + final Collection paths = node.findPaths(false); + assert paths.size() > 0; + NetGraph.NetNode output = null; + for (Iterator i = paths.iterator(); i.hasNext() && output == null; ) + { + final NetGraph.NetPath path = (NetGraph.NetPath) i.next(); + final NetGraph.NetNode s = path.getStartNode(); + final NetGraph.NetNode e = path.getEndNode(); + if (s != node && !s.isRail()) { + output = s; + } else if (e != node && !e.isRail()) { + output = e; + } + } + assert output != null; + + // find the appropriate staticizer transistor + boolean notSized = true; + output.findPaths(); + for (Iterator i = output.getPaths().iterator(); + i.hasNext() && notSized; ) { + final NetGraph.NetPath path = (NetGraph.NetPath) i.next(); + if (path.isFeedBack() && path.getType() == precharge.type) { + final NetGraph.NetEdge edge = + (NetGraph.NetEdge) path.getEdges().get(0); + precharge.length = edge.length; + precharge.width = edge.width; + notSized = false; + } + } + if (notSized) { + System.err.println("ERROR: Unable to size pre-discharge " + + "transistor on node: " + node.name + " in " + + cell.typeName); + } + + // skip the rest of the processing + return; + } + + final Collection paths = node.findPaths(true); + final double symFactor = + CastDesign.getSymmetrizationFactor(node, paths, precharge.type, + cell, design); + final Map sizes = new HashMap(); + + for (Iterator i = paths.iterator(); i.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) i.next(); + final Collection edges = path.getEdges(); + final double[] erf = precharge.type == DeviceTypes.N_TYPE ? + tdata.getEffectiveResistanceFactorN(path.getTransistorType()) : + tdata.getEffectiveResistanceFactorP(path.getTransistorType()); + final double effectiveWidth = edges.size() * + erf[Math.min(edges.size(), erf.length) - 1] / erf[0]; + for (Iterator j = edges.iterator(); j.hasNext(); ) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) j.next(); + final double previous = sizes.containsKey(edge) ? + ((Double) sizes.get(edge)).doubleValue() : + Double.NEGATIVE_INFINITY; + sizes.put(edge, new Double(Math.max(previous, effectiveWidth))); + } + } + + double width = 0; + for (Iterator i = sizes.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final NetGraph.NetEdge edge = (NetGraph.NetEdge) entry.getKey(); + width += edge.width / ((Double) entry.getValue()).doubleValue(); + } + // the desired width to length ratio + final double ratio = width / sizes.size() / symFactor + / tdata.getDefaultGateLength() + * tdata.getPrechargeRatio(); + + final double desiredWidth = tdata.minimumTransistorLength * ratio; + if (desiredWidth >= tdata.minimumTransistorWidth) { + precharge.length = tdata.minimumTransistorLength; + precharge.width = desiredWidth; + } else { + precharge.width = tdata.minimumTransistorWidth; + precharge.length = tdata.minimumTransistorWidth / ratio; + if (precharge.length > tdata.maximumPrechargeTransistorLength) { + System.out.println( + "WARNING: Precharge transistor on " + cell.typeName + "/" + + node.name + " wants width to length ratio of " + + NumberFormatter.format(ratio, 3) + " but length of " + + toMicron(precharge.length, 3) + " exceeds maximum of " + + toMicron(tdata.maximumPrechargeTransistorLength, 3)); + } + } + } + + /** TODO: remove **/ + static void sizePrechargeTransistors(final CastDesign design) { + for (Iterator i = design.allCellTypes.iterator(); i.hasNext(); ) { + CellType cell = (CellType) i.next(); + for (Iterator j = cell.transistors.getNodes().iterator(); + j.hasNext(); ) { + final NetGraph.NetNode node = (NetGraph.NetNode) j.next(); + final NetGraph.GateInstance gate = node.getGate(); + if (gate != null && gate.isPrechargePrimitive()) { + sizePrechargeTransistor(design, cell, node); + } + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizingPath.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizingPath.java new file mode 100644 index 0000000000..8ddc03be1f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SizingPath.java @@ -0,0 +1,760 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import com.avlsi.fast.*; +import com.avlsi.file.common.HierName; +import com.avlsi.tools.lvs.NetGraph; + +import java.util.Set; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.TreeSet; +import java.io.*; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.util.container.CollectionUtils; + +public class SizingPath extends AbstractPath +{ + List/**/ path; + + SizingPath copyFrom; + + private HierName instanceName; + + /** Return the list of half-operators */ + public List/**/ getPath() + { + return path; + } + + + + /** Constructor 1 */ + public SizingPath() + { + path = new ArrayList/**/(); + startNets = new HashSet/**/(); + endNet = null; + + container = null; + + isFragment = false; + isReduced = false; + isEndNetNonObservable = false; + copyFrom = null; + + delay = null; + slack = null; + delaybias = null; + criticalNet = null; + instanceName = null; + } + + + /** Constructor 2 */ + public SizingPath(SizingPath sp1) + { + path = new ArrayList/**/(sp1.path); + startNets = new HashSet/**/(sp1.startNets); + endNet = sp1.endNet; + container = sp1.container; + + isFragment = sp1.isFragment; + isReduced = sp1.isReduced; + isEndNetNonObservable = sp1.isEndNetNonObservable; + copyFrom = sp1.copyFrom; + + delay = sp1.delay; + slack = sp1.slack; + delaybias = sp1.delaybias; + criticalNet = sp1.criticalNet; + instanceName = sp1.instanceName; + } + + + + + /** + * Generate sizing paths. Sizing paths are generated for all cells in + * cellTypes. Any existing sizing paths of each cell in + * cellTypes are replaced by the newly generated paths. + * + * @param cellTypes + * CellTypes for which sizing paths should be + * generated. + * @param ignoreReset + * If true, do not find paths starting at reset nodes. + * @param completeSizingPath + * If true, use "weak cuts", so paths will not stop at input + * ports to the cell. If false, use "strong cuts", and paths + * will stop there + * @param pathLimit + * Log a warning with the message center for any cell containing + * more than this many paths. + **/ + public static void generatePaths(Set/**/ cellTypes, + boolean ignoreReset, + boolean completeSizingPath, + int pathLimit) + { + for (Iterator ita = cellTypes.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + if(DebugOption.printLevel <= 3){ + System.out.println("------------- Summary for path generation ---------------"); + System.out.println(cella.typeName); + } + + if(cella.transistors.isEmpty()){ // cell without transistors + continue; + } + + cella.getSizingPaths().clear(); + + // Get port cell nets and internal cell nets with "cutpath" directives + + Set/**/ inputPortCellNets = + new LinkedHashSet/**/(); + Set/**/ cutpathCellNets = + new LinkedHashSet/**/(); + for (Iterator itb = + CollectionUtils.sort(CellNet.getComparator(), + cella.getAllNets().iterator()); + itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + + if(cna.isCutPath()){ + cutpathCellNets.add(cna); + continue; + } + + if(!cna.isPortNet()){ // not a port net + continue; + } + + if(cna.isReset()){ + if(DebugOption.printLevel <= 1){ + System.out.println("Note: Found global net: " + cna.canonicalName.getCadenceString()); + } + if(ignoreReset){ + continue; + } + } + + if (cna.portDirection == CellNet.OUTPUT || + cna.portDirection == CellNet.UNKNOWN) { + // not an input port + continue; + } + + inputPortCellNets.add(cna); + } + + + // Add half-operators driven by port nets + + Set/**/ halfOperators = + new TreeSet/**/(HalfOperator.getComparator()); + for (Iterator itb = inputPortCellNets.iterator(); + itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + + for (Iterator itc = cna.getListSinks().iterator(); itc.hasNext(); ) { + NetSink nska = (NetSink)itc.next(); + + if(nska.type == NetType.HALF_OPERATOR_TRANSISTOR){ // half-operator load + if(DebugOption.printLevel <= 1){ + System.out.println("----------- Added one half-operator ------------"); + System.out.println(nska.sink.toString()); + } + + HalfOperator hoa = nska.sink; + + halfOperators.add(hoa); + + /* + if((hoa.transistors.size() <= 1) || (!cna.isReset())){ + // if (!cna.isReset()) + halfOperators.add(hoa); + } + else{ // reserved for possible future branch + if(k > 0){ + halfOperators.add(hoa); + } + } + */ + } + } + } + + // End adding half-operators driven by port nets + + + // Add half-operators driven by subcells + + for (Iterator itb = cella.getAllNets().iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + if(cna.hasOnlyCellTypeSources()){ + assert cna.getHalfOperatorSinks().size() == 0 + : "Mixing of transistors and sub-cells in the " + + "same cell is not allowed in sizing.\n" + + "CellName: " + cella.typeName; + + halfOperators.addAll(cna.getHalfOperatorSinks()); + } + } + + // End adding half-operators drive by subcells + + + // Add half-operators driven by "cutpath" cell nets + + // Set/**/ cutpathHalfOps = + // new HashSet/**/(); + for (Iterator itb = cutpathCellNets.iterator(); itb.hasNext(); ) { + CellNet cna = (CellNet)itb.next(); + + for (Iterator itc = cna.getListSinks().iterator(); itc.hasNext(); ) { + NetSink nska = (NetSink)itc.next(); + + if(nska.type == NetType.HALF_OPERATOR_TRANSISTOR){ // half-operator load + if(DebugOption.printLevel <= 1){ + System.out.println("----------- Added one half-operator ------------"); + System.out.println(nska.sink.toString()); + } + + HalfOperator hoa = nska.sink; + + halfOperators.add(hoa); + // cutpathHalfOps.add(hoa); + } + } + } + + // End adding half-operators driven by "cutpath" cell nets + + + Set/**/ startingCutHalfOps = + new HashSet/**/(); + if(completeSizingPath){ + // if (!cella.isFragment()) + // startingCutHalfOps.addAll(halfOperators); + //startingCutHalfOps.addAll(cutpathHalfOps); + } + else{ + startingCutHalfOps.addAll(halfOperators); + } + + + // HISTORICAL NOTE: In a previous incarnation, this function + // would first try to generate paths with weak cuts, then, + // if there were too many paths, it would fall back to + // strong cuts. We may want to restore this behavior in + // the future. + + if(DebugOption.printLevel <= 3){ + System.out.println("Total number of half-operators to start with: " + + halfOperators.size()); + } + + Set/**/ generatedSizingPaths = + new LinkedHashSet/**/(); + for (Iterator itb = halfOperators.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + if(DebugOption.printLevel <= 1){ + System.out.println("------------- Start with half-operator -----------------"); + System.out.println(hoa.toString()); + } + + recursivePaths(hoa, new ArrayList/**/(), + generatedSizingPaths, + startingCutHalfOps); + } + + + if (generatedSizingPaths.size() > pathLimit) { + String msa = "WARNING"; + String msb = "Too many sizing paths for this cell.\n"; + String msc = "CellName: " + cella.typeName + "\n" + + "Number of half-operators: " + + cella.getListHalfOperators().size() + "\n" + + "Number of paths: " + generatedSizingPaths.size() + + "\n" + + "Need manual path cut by adding \"cutpath\" directives." + "\n"; + + System.out.println(msa + ":" + msb + msc); + + cella.design.messageCenter.createMessage(1, 10, msa, msb, msc); + } + + + for (Iterator itc = generatedSizingPaths.iterator(); + itc.hasNext(); ) { + SizingPath spa = (SizingPath)itc.next(); + spa.setStartEndNets(completeSizingPath); + spa.copyFrom = spa; + } + + + cella.getSizingPaths().addAll(generatedSizingPaths); + + if(DebugOption.printLevel <= 1){ + System.out.println("Number of paths: " + + generatedSizingPaths.size()); + for (Iterator itb = generatedSizingPaths.iterator(); + itb.hasNext(); ) { + System.out.println(itb.next().toString()); + } + } + + String s = cella.checkPathCoverage(); + if(DebugOption.printLevel <= 3){ + System.out.println("Path coverage check result: " + s); + } + + } + } + + + /** + * Recursively generate sizing paths. Traversal starts at half operator + * nextHalfOp and traverses through sink half operators + * until either a loop to a half operator in partialPath, + * a half operator in startingCutHalfOps, a port net, or a + * cut path half operator is found. All paths found will have + * the partial path partialPath prepended, and will then be + * added to allSizingPaths. + * + * @param nextHalfOp + * The HalfOperator from which to continue searching + * paths. + * @param partialPath + * Previous HalfOperators on the path. + * @param allSizingPaths + * Set of all SizingPaths created by this function. + * Created paths will be added to this set. + * @param startingCutHalfOps + * Set of starting HalfOperators if we are using + * "strong cuts" (ie generatePaths was called + * with completeSizingPath == false), otherwise + * the empty set. Path searches will stop when a + * HalfOperator in this set is reached. + **/ + public static void recursivePaths(HalfOperator nextHalfOp, + List/**/ partialPath, + Set/**/ allSizingPaths, + Set/**/ + startingCutHalfOps) + { + if(DebugOption.printLevel <= 1){ + System.out.println("\t------------ recursive step ---------------"); + System.out.println("\t" + nextHalfOp.toString()); + } + + + if (partialPath.contains(nextHalfOp)) { + // loop in path + SizingPath spa = new SizingPath(); + spa.path.addAll(partialPath); + allSizingPaths.add(spa); + if(DebugOption.printLevel <= 1){ + System.out.println("One path generated, 1"); + } + return; + } + + if (startingCutHalfOps.contains(nextHalfOp) && + partialPath.size() != 0) { + // starting half-operator for other paths + SizingPath spa = new SizingPath(); + spa.path.addAll(partialPath); + allSizingPaths.add(spa); + if(DebugOption.printLevel <= 1){ + System.out.println("One path generated, 1a"); + } + return; + } + + List/**/ newPartialPath = + new ArrayList/**/(partialPath); + newPartialPath.add(nextHalfOp); + + // outputNet should never be null + CellNet outputNet = nextHalfOp.outputNet; + if (outputNet.isPortNet() || outputNet.isCutPath()) { + // port net, path stops here + SizingPath spa = new SizingPath(); + spa.path.addAll(newPartialPath); + allSizingPaths.add(spa); + if(DebugOption.printLevel <= 1){ + System.out.println("One path generated, 2"); + } + + return; + } + + Set/**/ newNextHalfOps = + new TreeSet/**/(HalfOperator.getComparator()); + boolean isCut = false; + for (Iterator ita = outputNet.getListSinks().iterator(); + ita.hasNext(); ) { + NetSink nska = (NetSink)ita.next(); + + if (nska.type == NetType.HALF_OPERATOR_TRANSISTOR) { + // half-operator load + HalfOperator sinkHalfOp = nska.sink; + + boolean visited = false; + /* + for (Iterator itb = newPartialPath.iterator(); + itb.hasNext(); ) { + HalfOperator hob = (HalfOperator)itb.next(); + + if (hob.outputNet == sinkHalfOp.outputNet) { + visited = true; + break; + } + } + */ + + if (newPartialPath.contains(sinkHalfOp) || + startingCutHalfOps.contains(sinkHalfOp) || + visited) { + isCut = true; + } else if (nextHalfOp.driveDirection != + sinkHalfOp.driveDirection) { + // Since we are traversing from HalfOperator to + // CellNet and to HalfOperator again, we will find + // both up and down HalfOperators. Only add those + // with opposite directions. + newNextHalfOps.add(sinkHalfOp); + } + } + } + + if (newNextHalfOps.isEmpty() || isCut) { + SizingPath spa = new SizingPath(); + spa.path.addAll(newPartialPath); + allSizingPaths.add(spa); + if(DebugOption.printLevel <= 1){ + System.out.println("One path generated, 3"); + } + + if (newNextHalfOps.isEmpty()) { + return; + } + } + + if(DebugOption.printLevel <= 1){ + System.out.println("Number of sinks to be traversed: " + + newNextHalfOps.size()); + } + + for (Iterator ita = newNextHalfOps.iterator(); + ita.hasNext(); ) { + HalfOperator hoa = (HalfOperator)ita.next(); + + if(DebugOption.printLevel <= 1){ + System.out.println("Going into one more recursive loop"); + } + recursivePaths(hoa, newPartialPath, allSizingPaths, + startingCutHalfOps); + if(DebugOption.printLevel <= 1){ + System.out.println("Pop back one level"); + System.out.println(nextHalfOp.toString()); + } + } + + if(DebugOption.printLevel <= 1){ + System.out.println("Nothing generated in this loop"); + } + } + + + + public void setStartEndNets(boolean completeSizingPath) + { + endNet = ((HalfOperator) path.get(path.size() - 1)).outputNet; + + startNets.clear(); + + HalfOperator hoa = (HalfOperator)path.get(0); + container = hoa.subType; + + for (Iterator ita = container.getAllNets().iterator(); ita.hasNext(); ) { + CellNet cna = (CellNet)ita.next(); + if(completeSizingPath){ + if(container.isFragment()){ + if(cna.isPortNet()){ + if(cna.hasSinkAs(hoa)){ + startNets.add(cna); + } + } + } + else{ + if(cna.hasSinkAs(hoa)){ + startNets.add(cna); + } + } + } + else{ + if(cna.hasSinkAs(hoa)){ + startNets.add(cna); + } + } + } + } + + + + public String toString() + { + StringBuffer sb = new StringBuffer(); + + for (Iterator ita = path.iterator(); ita.hasNext(); ) { + HalfOperator hoa = (HalfOperator)ita.next(); + CellNet cna = hoa.outputNet; + sb.append(cna.canonicalName.getCadenceString()); + if (hoa.driveDirection == HalfOperator.DriveDirection.PULL_DOWN) { + sb.append("- "); + } + else{ + sb.append("+ "); + } + } + + return sb.toString(); + } + + + public String printPath() + { + return printPath(true, -1); + } + + public String printPath(boolean b1) { + return printPath(b1, -1); + } + + public String printPath(int n) { + return printPath(true, n); + } + + private static Object lastElement(final List l) { + if (l == null || l.isEmpty()) return null; + else return l.get(l.size() - 1); + } + + public String printPath(boolean b1, int n) + { + StringBuffer sb = new StringBuffer(); + final HalfOperator lastHalfOp = (HalfOperator) + lastElement(path); + GlobalNet gn; + CellNet cn; + TechnologyData tech; + double[] effectiveResistanceFactors; + double effectiveResistanceFactor; + double f = 0.0; + double wireCap = 0.0; + double reff = 0.0; + if (n >= 0 && b1) { + gn = (GlobalNet) getEndNet().getGlobalNets().get(n); + cn = gn.getTopCellNet(); + tech = cn.container.design.getTechnologyData(); + reff = gn.getDriveResistance(lastHalfOp)*tech.elmoreDelayFactor; + wireCap = gn.getWireCapacitance(); + } + + if(b1){ + final String dstr = n >= 0 ? printDelay(delay[n]) + : printDelay(delay); + final String sstr = n >= 0 ? printDelay(getSlack(n)) + : printDelay(slack); + final String rstr = + n >= 0 && getSlack(n) != slack[n] ? printDelay(slack[n]) : null; + final String nstr; + if (n >= 0) { + gn = (GlobalNet) getEndNet().getGlobalNets().get(n); + cn = gn.getTopCellNet(); + nstr = "// endnet=" + cn.container.typeName + "/" + + cn.canonicalName.getCadenceString() + "\n" + + (delaybias[n] != 1 ? + ("// delaybias=" + + NumberFormatter.format(delaybias[n], 2) + "\n") + : ""); + } else { + nstr = ""; + } + final double theslack = n >= 0 ? getSlack(n) : 0.0; + final double budgetcap = reff > 0.0 ? theslack/reff+wireCap : 0.0; + sb.append("// delay=" + dstr + "ps" + " slack=" + sstr + "ps" + + (rstr == null ? "" : " real_slack=" + rstr + "ps") + + " avg_width=" + NumberFormatter.format(getAverageWidth()*1e6,3) + "um" + + " c_wire="+ NumberFormatter.format(wireCap*1e15,1)+"fF" + + " reff="+ NumberFormatter.format(reff,1)+ + " budget_cap="+ NumberFormatter.format(budgetcap*1e15,1)+"fF\n" + + nstr); + } + + sb.append(container.typeName + ": "); + + int j = path.size(); + + for(int i=0;i*/ nonObservableStartNets, + CellNet endNet) { + SizingPath spb = new SizingPath(this); + spb.setStartNets(nonObservableStartNets); + spb.setEndNet(endNet); + spb.copyFrom = this; + spb.setIsFragment(false); + + //if(isEndNonObservable || !hasObservable){ // this sizing path can be removed from the sub-cell + // setIsFragment(true); + //} + setIsFragment(true); + + //if(isEndNonObservable && hasObservable){ // this sizing path should be one of the start sizing path in cat path + // spb.isReduced = true; + //} + if(hasObservable){ // this sizing path should be one of the start sizing path in cat path + spb.isReduced = true; + } + + spb.isEndNetNonObservable = isEndNonObservable; // is this a end sizing path for cat path? + + CatPath cpa = new CatPath(); + cpa.getCatPath().add(spb); + cpa.setStartNets(nonObservableStartNets); + cpa.setEndNet(endNet); + cpa.setIsFragment(false); + cpa.isReduced = spb.isReduced; + cpa.isEndNetNonObservable = spb.isEndNetNonObservable; + + return cpa; + } + + public HierName getInstanceName() { + return instanceName; + } + + public void prefixInstanceName(final /*@ non_null @*/ HierName prefix) { + instanceName = + instanceName == null ? prefix + : HierName.append(prefix, instanceName); + } + + void getPathString(final StringBuffer buf) { + for (Iterator i = path.iterator(); i.hasNext(); ) { + final HalfOperator op = (HalfOperator) i.next(); + getNetString(buf, op.outputNet); + buf.append( + op.driveDirection == HalfOperator.DriveDirection.PULL_DOWN ? + '-' : '+'); + buf.append(' '); + } + getNetString(buf, getEndNet()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubcellProcessor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubcellProcessor.java new file mode 100644 index 0000000000..3be2a73188 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubcellProcessor.java @@ -0,0 +1,19 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import com.avlsi.geometry.BoundingBox; + +public interface SubcellProcessor { + /** Called to process the bounding box of the current cell */ + void process(BoundingBox bBox); + /** Called to process pins in the current cell */ + void process(String pinName, BoundingBox bBox); + /** Called to process each subcell in the current cell */ + void process(String cellType, String instanceName, int orientation, BoundingBox bBox); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubprocessFailedException.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubprocessFailedException.java new file mode 100644 index 0000000000..701c06f009 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubprocessFailedException.java @@ -0,0 +1,10 @@ +package com.avlsi.tools.jauto; + +public class SubprocessFailedException extends Exception { + public SubprocessFailedException(String why) { + super(why); + } + public SubprocessFailedException(String why, Exception cause) { + super(why, cause); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeMerge.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeMerge.java new file mode 100644 index 0000000000..430947784d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeMerge.java @@ -0,0 +1,680 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.FileWriter; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.Writer; +import java.text.DateFormat; +import java.text.Format; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.avlsi.cast.CastCacheManager; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.geometry.BoundingBox; +import com.avlsi.geometry.Point; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.NullWriter; +import com.avlsi.tools.jauto.Floorplan; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.container.NaturalOrderComparator; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.StringUtil; + +public final class SubtypeMerge { + + private SubtypeMerge() { + throw new AssertionError(); + } + + private static Format getHeader(final String cellName) { + final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); + final DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.LONG); + final Date now = new Date(); + final StringBuffer header = new StringBuffer(); + header.append(cellName); + header.append(":"); + header.append(dateFormat.format(now)); + header.append(":"); + header.append(timeFormat.format(now)); + header.append(":"); + header.append(System.getProperty("user.name")); + header.append("\n"); + return new MessageFormat(header.toString()); + } + + private static Pair getSubtypePair(final SortedMap typeMap, + final String type) { + final int index = type.lastIndexOf('.'); + Debug.assertTrue(index > 0, type + " is an invalid type name!"); + final String base = type.substring(0, index); + final String subtype = type.substring(index + 1); + + final SortedMap subtypeMap = (SortedMap) typeMap.get(base); + return (Pair) subtypeMap.get(subtype); + } + + private static String mapType(final SortedMap typeMap, final String type) { + final Pair p = getSubtypePair(typeMap, type); + + return (String) p.getSecond(); + } + + private static CellInterface getType(final SortedMap typeMap, + final String type) { + final Pair p = getSubtypePair(typeMap, type); + return p == null ? null : (CellInterface) p.getFirst(); + } + + private static void setType(final SortedMap typeMap, final String base, + final String fromType, final String toType) { + final SortedMap subtypeMap = (SortedMap) typeMap.get(base); + final Pair old = (Pair) subtypeMap.get(fromType); + subtypeMap.put(fromType, new Pair(old.getFirst(), toType)); + } + + private static Map getLocalSubcellMap(final CellInterface ci) { + final Map m = new TreeMap(); + for (Iterator i = ci.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + assert !m.containsKey(p.getFirst()) : "Duplicate instance names " + p.getFirst() + " in cell " + ci.getFullyQualifiedType(); + m.put(p.getFirst(), p.getSecond()); + } + return m; + } + + /** + * Should only be used to compare midlevel cells a and b that pass + * MidlevelComparator.compareTo(a,b) == 0. + **/ + private static class GeometryComparator implements Comparator { + private static int compareDouble(final double a, final double b) { + if (a < b) return -1; + else if (a > b) return 1; + else return 0; + } + private static class OrderComparator implements Comparator { + private final Map map; + public OrderComparator(final Map map) { + this.map = map; + } + public int compare(final Object o1, final Object o2) { + final Point p1 = ((Info) map.get(o1)).bBox.getLowerLeft(); + final Point p2 = ((Info) map.get(o2)).bBox.getLowerLeft(); + + int result; + result = compareDouble(p1.getY(), p2.getY()); + if (result != 0) return result; + + result = compareDouble(p1.getX(), p2.getX()); + return result; + } + } + + private static class Info { + public final int orientation; + public final BoundingBox bBox; + public Info(final int orientation, final BoundingBox bBox) { + this.orientation = orientation; + this.bBox = bBox; + } + public String toString() { + return "<" + orientation + " : " + bBox + ">"; + } + } + + private final Floorplan fp; + private final Map cache; + public GeometryComparator(final Floorplan fp) { + this.fp = fp; + this.cache = new HashMap(); + } + private Map readInstanceMap(final String type) { + final Map result = new TreeMap(); + fp.readHierarchy(type, new SubcellProcessor() { + public void process(final BoundingBox bBox) { } + public void process(final String pinName, final BoundingBox bBox) { } + public void process(final String typeName, + final String instanceName, + final int orientation, + final BoundingBox bBox) { + result.put(instanceName, new Info(orientation, bBox)); + } + }); + return result; + } + + private Map getInstanceMap(final String type) { + if (!cache.containsKey(type)) { + cache.put(type, readInstanceMap(type)); + } + return (Map) cache.get(type); + } + + public int compare(final Object o1, final Object o2) { + if (o1 == o2) return 0; + + int result; + + final Map m1 = + getInstanceMap(((CellInterface) o1).getFullyQualifiedType()); + final Map m2 = + getInstanceMap(((CellInterface) o2).getFullyQualifiedType()); + + // geometry information may have different number of instances when + // the CAST does not, due to, for example, user error + result = m1.size() - m2.size(); + if (result != 0) return result; + + for (Iterator i = m1.values().iterator(), + j = m2.values().iterator(); i.hasNext(); ) { + final Info i1 = (Info) i.next(); + final Info j1 = (Info) j.next(); + + // orientation must match + result = i1.orientation - j1.orientation; + if (result != 0) return result; + + // y coordinates must match + result = compareDouble(i1.bBox.getUpperRight().getY(), + j1.bBox.getUpperRight().getY()); + if (result != 0) return result; + + result = compareDouble(i1.bBox.getLowerLeft().getY(), + j1.bBox.getLowerLeft().getY()); + if (result != 0) return result; + } + + /** + * Sort the instances by Y then X, and compare the order of the + * instances. They must be the same. + **/ + final TreeMap x1 = new TreeMap(new OrderComparator(m1)); + x1.putAll(m1); + final TreeMap x2 = new TreeMap(new OrderComparator(m2)); + x2.putAll(m2); + + for (Iterator i = x1.keySet().iterator(), + j = x2.keySet().iterator(); i.hasNext(); ) { + final String i1 = (String) i.next(); + final String j1 = (String) j.next(); + + result = i1.compareTo(j1); + if (result != 0) return result; + } + + return 0; + } + } + + private static class MidlevelComparator implements Comparator { + private final SortedMap typeMap; + public MidlevelComparator(final SortedMap typeMap) { + this.typeMap = typeMap; + } + public int compare(final Object o1, final Object o2) { + int result; + + final Map m1 = getLocalSubcellMap((CellInterface) o1); + final Map m2 = getLocalSubcellMap((CellInterface) o2); + + // Both cells must have the same number of subcells + result = m1.size() - m2.size(); + if (result != 0) return result; + + // The instance names of the subcells must be identical + for (Iterator i = m1.keySet().iterator(), + j = m2.keySet().iterator(); i.hasNext(); ) { + final HierName h1 = (HierName) i.next(); + final HierName h2 = (HierName) j.next(); + result = h1.compareTo(h2); + if (result != 0) return result; + } + + // The types of the subcells must also match + for (Iterator i = m1.keySet().iterator(); i.hasNext(); ) { + final HierName key = (HierName) i.next(); + final CellInterface sc1 = (CellInterface) m1.get(key); + final CellInterface sc2 = (CellInterface) m2.get(key); + + assert sc1 != null && sc2 != null; + + final String type1 = sc1.getFullyQualifiedType(); + final String type2 = sc2.getFullyQualifiedType(); + + // Wiring cells are not present in typeMap + if (CellUtils.isWiring(sc1) || CellUtils.isWiring(sc2)) { + result = type1.compareTo(type2); + } else { + final String mt1 = mapType(typeMap, type1); + final String mt2 = mapType(typeMap, type2); + result = mt1.compareTo(mt2); + } + if (result != 0) return result; + } + return 0; + } + } + + private static class MidlevelPairComparator implements Comparator { + private final Comparator midlevel; + private final Comparator subtype; + public MidlevelPairComparator(final Comparator midlevel) { + this(midlevel, new NaturalOrderComparator()); + } + public MidlevelPairComparator(final Comparator midlevel, + final Comparator subtype) { + this.midlevel = midlevel; + this.subtype = subtype; + } + public int compare(final Object o1, final Object o2) { + final Pair p1 = (Pair) o1; + final Pair p2 = (Pair) o2; + final CellInterface c1 = (CellInterface) p1.getFirst(); + final CellInterface c2 = (CellInterface) p2.getFirst(); + final int comp = midlevel.compare(c1, c2); + if (comp != 0) return comp; + final String s1 = (String) p1.getSecond(); + final String s2 = (String) p2.getSecond(); + return subtype.compare(s1, s2); + } + } + + /** + * Assume when/if cell names can be Unicode, they won't begin with + * '\uFFFF'. + **/ + private static Pair getSuccessorPair(final Pair p) { + return new Pair(p.getFirst(), Character.toString(Character.MAX_VALUE)); + } + + + /** + * typeMap is a sorted map: cell type -> (sorted map: subtype -> + * (cell, subtype)) + **/ + static void prepare(final CellInterface cell, final SortedMap typeMap) { + if (CellUtils.isWiring(cell)) return; + + final String type = cell.getFullyQualifiedType(); + final int index = type.lastIndexOf('.'); + final String base = type.substring(0, index); + final String subtype = type.substring(index + 1); + + if (!typeMap.containsKey(base)) { + typeMap.put(base, new TreeMap()); + } + final SortedMap subtypeMap = (SortedMap) typeMap.get(base); + if (subtypeMap.containsKey(subtype)) return; + subtypeMap.put(subtype, new Pair(cell, subtype)); + + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + prepare(subcell, typeMap); + } + } + + private static List getPairPartition(SortedSet pairSet) { + final List result = new ArrayList(); + while (!pairSet.isEmpty()) { + final Pair first = (Pair) pairSet.first(); + final Pair succ = getSuccessorPair(first); + result.add(pairSet.headSet(succ)); + pairSet = pairSet.tailSet(succ); + } + return result; + } + + private static void doMerge(final SortedSet mergedSet, + final SortedMap typeMap, + final Comparator subtypeComp, + final String base) { + if (mergedSet.size() > 1) { + final TreeSet candidates = new TreeSet(subtypeComp); + for (Iterator i = mergedSet.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface ci = (CellInterface) p.getFirst(); + // XXX: Don't use CellUtils.isFixedSize because that also + // checks to see if the cell has a netlist block + if (((Boolean) DirectiveUtils.getTopLevelDirective(ci, DirectiveConstants.FIXED_SIZE)).booleanValue()) { + candidates.add(p); + } + } + if (candidates.isEmpty()) { + candidates.addAll(mergedSet); + } + final Pair canonical = (Pair) candidates.first(); + final String subtype = (String) canonical.getSecond(); + for (Iterator j = mergedSet.iterator(); j.hasNext(); ) { + final Pair p = (Pair) j.next(); + if (!subtype.equals(p.getSecond())) + setType(typeMap, base, (String) p.getSecond(), subtype); + } + } + } + + /** + * Find midlevel cells that instantiate the same subcells and merge them + * together, into the subtype that is lexicographically the smallest. + * @param cell Root cell to descend into + * @param typeMap Subtype to subtype mapping + * @param comp A comparator capable of comparing Pair(CellInterface, String) + * @param seen All the types already completed + **/ + private static void mergeAll(final CellInterface cell, + final SortedMap typeMap, + final Comparator comp, + final Comparator subtypeComp, + final Comparator fp, + final Set seen) { + if (CellUtils.isWiring(cell) || CellUtils.isLeaf(cell)) return; + + final String type = cell.getFullyQualifiedType(); + final int index = type.lastIndexOf('.'); + + final String base = type.substring(0, index); + // Process each type only once. + if (!seen.add(base)) return; + + for (Iterator i = cell.getLocalSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + mergeAll(subcell, typeMap, comp, subtypeComp, fp, seen); + } + + final SortedMap subtypeMap = (SortedMap) typeMap.get(base); + if (subtypeMap.size() <= 1) return; + + final SortedSet pairSet = new TreeSet(comp); + pairSet.addAll(subtypeMap.values()); + for (Iterator i = getPairPartition(pairSet).iterator(); + i.hasNext(); ) { + final SortedSet mergedSet = (SortedSet) i.next(); + if (fp == null) { + doMerge(mergedSet, typeMap, subtypeComp, base); + } else { + final SortedSet fpSet = new TreeSet(fp); + fpSet.addAll(mergedSet); + final List fpList = getPairPartition(fpSet); + if (fpList.size() > 1) { + System.out.print("Warning: Due to floorplanning, the following subtypes of " + base + " will not be merged together:"); + for (Iterator j = fpList.iterator(); j.hasNext(); ) { + final SortedSet fpMerge = (SortedSet) j.next(); + final Pair p = (Pair) fpMerge.first(); + System.out.print(" " + p.getSecond()); + doMerge(fpMerge, typeMap, subtypeComp, base); + } + System.out.println(); + } else { + doMerge(mergedSet, typeMap, subtypeComp, base); + } + } + } + } + + private static final Pattern SUBTYPE_PATTERN = + Pattern.compile("^(\\d+)(.*)"); + + /** + * Merge all cells. + * @param cell Root cell to traverse over. + * @param typeMap Mapping of subtypes. + * @param comp A comparator capable of comparing CellInterfaces + **/ + private static void mergeAll(final CellInterface cell, + final SortedMap typeMap, + final Comparator comp, + final Floorplan fp) { + final Comparator subtypeComp = new MidlevelPairComparator( + new Comparator() { + public int compare(final Object o1, final Object o2) { + return 0; + } + }, + new Comparator() { + private Pair getParts(final String s) { + final Matcher m = SUBTYPE_PATTERN.matcher(s); + final Integer subtype; + final String suffix; + if (m.matches()) { + subtype = Integer.valueOf(m.group(1)); + suffix = m.group(2); + } else { + subtype = 0; + suffix = s; + } + return new Pair(subtype, suffix); + } + public int compare(final Object o1, final Object o2) { + final String s1 = (String) o1; + final String s2 = (String) o2; + return getParts(s1).compareTo(getParts(s2)); + } + }); + mergeAll(cell, typeMap, new MidlevelPairComparator(comp), subtypeComp, + fp == null ? null : + new MidlevelPairComparator(new GeometryComparator(fp)), + new HashSet()); + } + + /** + * + **/ + private static boolean mergeCell(final String type, + final Map typeMap, + final String toSubtype, + final String minSubtype, + final String maxSubtype, + final Comparator comp) { + final Map subtypeMap = (Map) typeMap.get(type); + boolean success = false; + if (subtypeMap != null) { + final Pair toPair = (Pair) subtypeMap.get(toSubtype); + for (final Iterator i = subtypeMap.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final Pair pair = (Pair) entry.getValue(); + if (toPair == pair) continue; + final String value = (String) pair.getSecond(); + if (value.compareTo(minSubtype) >= 0 && + value.compareTo(maxSubtype) <= 0 && + (comp == null || + comp.compare((CellInterface) pair.getFirst(), + (CellInterface) toPair.getFirst()) == 0)) { + success = true; + subtypeMap.put(entry.getKey(), + new Pair(pair.getFirst(), toSubtype)); + } + } + } + return success; + } + + private static void usage() { + System.err.println("java com.avlsi.tools.jauto.SubtypeMerge"); + System.err.println("\t[ --cast-path= ] (defaults to .)"); + System.err.println("\t[ --cast-version=[ 1 | 2 ] (defaults to 2)"); + System.err.println("\t[ --subtype-path= ] (defaults to .)"); + System.err.println("\t--cell= (top level cells)"); + System.err.println("\t--merge_target= (merge target cells)"); + System.err.println("\t[ --allow-merge-fixed ] (allow merging of fixed size subtypes)"); + System.err.println("\t[ --all (try to merge all midlevel cells after processing input spec)"); + System.err.println("\t [ --instance-dir= ] (take midlevel floorplan into account)"); + System.err.println("\t]"); + System.err.println("\t[ --output-leaves ] (write leaf cells as well)"); + System.exit(1); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String subtypePath = theArgs.getArgValue("subtype-path", "."); + final String output = theArgs.getArgValue("output", null); + final boolean mergeFixed = theArgs.argExists("allow-merge-fixed"); + final boolean mergeMid = theArgs.argExists("all"); + final boolean outputLeaves = theArgs.argExists("output-leaves"); + + // combine --cell and --merge_target lists + final String cellName = theArgs.getArgValue("cell", null); + + if (cellName == null) { + System.err.println("ERROR: You must specify a cellname."); + usage(); + } else if (subtypePath == null) { + System.err.println("ERROR: You must specify a subtype output path."); + usage(); + } + + final String[] cellNames = StringUtil.split(cellName, ':'); + final String mergeTarget = theArgs.getArgValue("merge_target", ""); + final String[] mergeTargets = StringUtil.split(mergeTarget, ':'); + final String[] allCellNames = new String[cellNames.length + mergeTargets.length]; + System.arraycopy(cellNames, 0, allCellNames, 0, cellNames.length); + System.arraycopy(mergeTargets, 0, allCellNames, cellNames.length, mergeTargets.length); + + Floorplan fp = null; + if (mergeMid) { + final String s = theArgs.getArgValue("instance-dir", null); + if (s != null) { + try { + fp = new Floorplan(s); + } catch (Floorplan.Exception e) { + System.err.println("ERROR: Specified instance directory invalid."); + usage(); + } + } + } + + final CastFileParser cfp = + CastCacheManager.getDefault().getCastFileParser( + new FileSearchPath(castRoot), castVersion, + new StandardParsingOption(theArgs)); + + if (!pedanticArgs.pedanticOK(false, true)) { + System.err.println(pedanticArgs.pedanticString()); + usage(); + } + + final CellInterface[] cells = new CellInterface[allCellNames.length]; + final SortedMap typeMap = new TreeMap(); + for (int i = 0; i < allCellNames.length; ++i) { + cells[i] = cfp.getFullyQualifiedCell(allCellNames[i]); + + if (!CellUtils.isSubtype(cells[i])) { + System.err.println("ERROR: Cell " + allCellNames[i] + " does not appear to be a subtype."); + usage(); + } + + prepare(cells[i], typeMap); + } + + final BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String line; + final Comparator midlevel = new MidlevelComparator(typeMap); + while ((line = br.readLine()) != null) { + if (line.startsWith("#")) continue; + final String[] tokens = StringUtil.tokenize(line); + if (tokens.length < 3) { + System.err.println("WARNING: Ignoring invalid merge specification: " + line); + continue; + } + final String type = tokens[0]; + final String toSubtype = tokens[1]; + final CellInterface target = + getType(typeMap, type + "." + toSubtype); + if (target == null) { + System.err.println("WARNING: Cannot find cell to merge to: " + line); + continue; + } + final Comparator comp = CellUtils.isLeaf(target) ? null : midlevel; + for (int i = 2; i < tokens.length; ++i) { + final String minSubtype, maxSubtype; + final int index = tokens[i].indexOf(".."); + if (index > 0) { + minSubtype = tokens[i].substring(0, index); + maxSubtype = tokens[i].substring(index + 2); + } else { + minSubtype = maxSubtype = tokens[i]; + } + if (!mergeCell(type, typeMap, toSubtype, minSubtype, maxSubtype, comp)) { + System.err.println("WARNING: No cells mergeable: " + type + " " + toSubtype + " " + tokens[i]); + } + } + } + + if (mergeMid) { + for (int i = 0; i < cells.length; ++i) { + mergeAll(cells[i], typeMap, midlevel, fp); + } + } + + final Collection spec = + new HashSet(); + SubtypeOutput.Policy policy; + policy = new SubtypeOutput.Merge(subtypePath, getHeader(cellName), + typeMap, outputLeaves, spec); + for (int i = 0; i < cellNames.length; ++i) { + SubtypeOutput.writeSubtype(policy, cells[i]); + } + + final Writer specWriter = output == null ? NullWriter.getInstance() + : new FileWriter(output); + final CDLNameInterface renamer = new CadenceNameInterface(); + for (SubtypeSplit.Spec s : spec) { + specWriter.write(s.getSpec(renamer)); + specWriter.write('\n'); + } + specWriter.close(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeOutput.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeOutput.java new file mode 100644 index 0000000000..21a2f0633a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeOutput.java @@ -0,0 +1,2578 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ +package com.avlsi.tools.jauto; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.text.Format; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedHashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.SortedMap; +import java.util.TreeSet; + +import com.avlsi.cast.*; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.DirectiveInterfaceFactory; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cast2.directive.impl.CastEmitter; +import com.avlsi.cast2.directive.impl.DirectiveDifference; +import com.avlsi.cast2.directive.impl.DirectiveEmitter; +import com.avlsi.cast2.directive.impl.DirectiveImpl; +import com.avlsi.cast2.directive.impl.DirectiveSource; +import com.avlsi.cast2.util.DirectiveActionInterface; +import com.avlsi.cast2.util.DirectiveActionFilter; +import com.avlsi.cast2.util.DirectiveFilter; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.DirectiveWalker; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.CastDesign; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.MergeDirective; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.ports.ArrayType; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.fast.ports.StructureType; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.common.HierName; +import com.avlsi.io.IndentWriter; +import com.avlsi.io.NullWriter; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.impl.CDLEmitter; +import com.avlsi.netlist.impl.DeviceProcessor; +import com.avlsi.netlist.impl.FoldTransistor; +import com.avlsi.util.container.FlatteningIterator; +import com.avlsi.util.container.IterableIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.BinaryFunction; + +/** + * Class to output subtypes. + * + * @author Harry Liu + * @version $Revision$ $Date$ + **/ + +public final class SubtypeOutput { + private static final Writer NOWRITE = NullWriter.getInstance(); + private SubtypeOutput() { + throw new AssertionError(); + } + + /** + * Class used to hold the result of executing a Policy. + **/ + public static final class Decision { + /** + * Module name of the cell subtyped to, e.g., lib.buffer.half.BUF_1of4 + **/ + public final String module; + + /** + * What the cell is subtyped to, e.g., 0, 1, 2. + **/ + public final String subtype; + + /** + * The cell the subtype is refining. + **/ + public final String from; + + /** + * Directives to output. A mapping from BlockInterface + * constants to DirectiveInterfaceFactorys. + **/ + public final Map directives; + + /** + * Extra directives to output. A mapping from + * BlockInterface constants to + * DirectiveInterfaceFactorys. + **/ + public final Map extraDirs; + + /** + * Writer to output the subtype to. null if no output + * should be done. + **/ + public final Writer writer; + + /** + * Informational comment at the beginning of the file. + **/ + public final String header; + + /** + * Attribute cells to inherit. + **/ + public final String[] attributes; + + /** + * Cell whose directives will be merged against. + **/ + public final CellInterface dirCell; + + /** + * Cell whose content will be used. For a leaf cell, this is the + * netlist block; for a midlevel cell, this is the subcells contained + * in the cell. + **/ + public final CellInterface contentCell; + + public Decision(final String module, final String subtype, + final Map directives, final Writer writer, + final String header, final String[] attributes) { + this(module, subtype, module, directives, writer, header, + attributes); + } + + public Decision(final String module, final String subtype, + final String from, final Map directives, + final Writer writer, final String header, + final String[] attributes) { + this(module, subtype, from, directives, writer, header, + attributes, null); + } + + public Decision(final String module, final String subtype, + final String from, final Map directives, + final Writer writer, final String header, + final String[] attributes, + final CellInterface dirCell) { + this(module, subtype, from, directives, writer, header, attributes, + dirCell, null); + } + + public Decision(final String module, final String subtype, + final String from, final Map directives, + final Writer writer, final String header, + final String[] attributes, final CellInterface dirCell, + final CellInterface contentCell) { + this(module, subtype, from, directives, Collections.EMPTY_MAP, + writer, header, attributes, dirCell, contentCell); + } + + public Decision(final String module, final String subtype, + final String from, final Map directives, + final Map extraDirs, + final Writer writer, final String header, + final String[] attributes, final CellInterface dirCell, + final CellInterface contentCell) { + this.module = module; + this.subtype = subtype; + this.from = from; + this.directives = directives; + this.extraDirs = extraDirs; + this.writer = writer; + this.header = header; + this.attributes = attributes; + this.dirCell = dirCell; + this.contentCell = contentCell; + } + } + + /** + * Class that encapsulate all decision making on how to subtype cells, what + * files to write to, and what directives to output. + **/ + public interface Policy { + /** + * Returns a Decision after applying this Policy to subtype the given + * cell. + **/ + Decision getDecision(final CellInterface cell) throws IOException; + + /** + * Returns what the given instance of a subcell in a parent cell should + * be subtyped to. parent may be null to indicate the top level cell. + * If a subtype line is + * lib.buffer.half.BUF_1of4 :> lib.buffer.half.BUF_1of4.0 + * then The first element is the Pair is lib.buffer.half.BUF_1of4, and + * the second is lib.buffer.half.BUF_1of4.0. + */ + Pair getSubtype(final CellInterface parent, final CellInterface subcell, + final HierName instance); + } + + /** + * Return the next available subtype given a directory and constraints on + * subtype ranges. Subtypes are assumed to have filenames of the form + * X.cast, where X, the subtype, is a non-negative integer. If L is the + * largest subtype in a directory, then the next available subtype N is + * max(L + 1, minSubtype). If N > maxSubtype, than null is + * returned. + **/ + private static String findNextSubtype(final File dir, + final int minSubtype, + final int maxSubtype) { + final int[] result = new int[1]; + result[0] = -1; + // XXX: Should cache directory information + dir.list(new FilenameFilter() { + public boolean accept(final File from, final String name) { + if (name.endsWith(".cast")) { + String index = name.substring(0, name.length() - 5); + try { + result[0] = Math.max(result[0], Integer.parseInt(index)); + } catch (NumberFormatException e) { } + } + return false; + } + }); + result[0] = Math.max(result[0] + 1, minSubtype); + if (result[0] > maxSubtype) return null; + else return Integer.toString(result[0]); + } + + /** + * Return the next available subtype given a directory. This is equivalent + * to findNextSubtype(dir, 0, Integer.MAX_VALUE). + **/ + private static String findNextSubtype(final File dir) { + return findNextSubtype(dir, 0, Integer.MAX_VALUE); + } + + /** + * Return the next open subtype given an array of directories, and + * constraints on subtype ranges. Subtypes are assumed to have filenames + * of the form X.cast, where X, the subtype, is a non-negative integer. + * The smallest available subtype not used in the range specified is + * returned. If no such subtype exists, than null is + * returned. + **/ + private static String findOpenSubtype(final File[] dir, + final int minSubtype, + final int maxSubtype) { + final TreeSet s = new TreeSet(); + // XXX: Should cache directory information + for (int i = 0; i < dir.length; ++i) { + dir[i].list(new FilenameFilter() { + public boolean accept(final File from, final String name) { + if (name.endsWith(".cast")) { + String index = name.substring(0, name.length() - 5); + try { + s.add(new Integer(index)); + } catch (NumberFormatException e) { } + } + return false; + } + }); + } + for (int i = minSubtype; i <= maxSubtype; ++i) { + if (!s.contains(new Integer(i))) { + return Integer.toString(i); + } + // don't wrap due to overflow and loop infinitely if maxSubtype is + // Integer.MAX_VALUE + if (i == maxSubtype) break; + } + return null; + } + + private static String findOpenSubtype(final File dir, + final int minSubtype, + final int maxSubtype) { + return findOpenSubtype(new File[] { dir }, minSubtype, maxSubtype); + } + + /** + * Opens a file given a directory and the file name, creating the directory + * if necessary. + **/ + private static Writer openFile(final File dir, final String name) throws IOException { + if (!dir.isDirectory() && !dir.mkdirs()) { + throw new IOException("Unable to create directory: " + dir); + } + final File castFile = new File(dir, name); + System.out.println("Subtype output to: " + castFile.getCanonicalPath()); + return new BufferedWriter(new FileWriter(castFile)); + } + + /** + * If the given cell is not fixed size, opens a file given a directory and + * the file name, creating the directory if necessary. Otherwise, return + * an instance of NullWriter. + **/ + private static Writer openFile(final File dir, final String name, + final CellInterface ci) throws IOException { + return isFixed(ci) ? NOWRITE : openFile(dir, name); + } + + /** + * Returns a String representing the directory of a cell, assuming "." is + * the directory seperator. + **/ + private static String cellPath(final String name) { + return CellUtils.hashMetaParameters(name).replace('.', File.separatorChar); + } + + /** + * Returns a File representing the directory of a cell, assuming "." is the + * directory seperator. + **/ + private static File cellPath(final File path, final String name) { + return new File(path, CellUtils.hashMetaParameters(name).replace('.', File.separatorChar)); + } + + private static File[] cellPath(final File[] path, final String name) { + final File[] result = new File[path.length]; + for (int i = 0; i < path.length; ++i) { + result[i] = cellPath(path[i], name); + } + return result; + } + + /** + * Returns the base type of a subtype. + **/ + private static String getBaseType(final String subtype) { + final int index = subtype.lastIndexOf('.'); + return subtype.substring(0, index); + } + + /** + * Returns the name of the direct refinement parent. + **/ + private static String getParentName(final CellInterface cell) { + return cell.getDirectRefinementParent().getFullyQualifiedType(); + } + + /** + * Return the type of instance named inst in the direct + * refinement parent of cell. + **/ + private static String getParentName(final CellInterface cell, + final HierName inst) { + final CellInterface parent = cell.getDirectRefinementParent(); + final CellInterface subcell = parent.getSubcell(inst); + return subcell.getFullyQualifiedType(); + } + + /** + * Returns a header, with parameters substituted in. Allowed parameters + * follow: + *
      + *
    1. {0} - p2n mode + *
    + **/ + private static String getHeader(final Format form, final String mode) { + final Object[] args = { mode }; + return form.format(args); + } + + /** + * Return the attribute cells inherited by the given cell. + **/ + private static String[] getAttributes(final CellInterface cell) { + final ArrayList result = new ArrayList(); + for (Iterator i = cell.getInheritedCells(); i.hasNext(); ) { + final CellInterface attr = (CellInterface) i.next(); + result.add(attr.getFullyQualifiedType()); + } + return (String []) result.toArray(new String[0]); + } + + private static void emitDirective(final BlockIterator bi, + final DirectiveEmitter emitter, + final DirectiveActionFilter f, + final IndentWriter iw) throws IOException + { + boolean wroteHeader = false; + while (bi.hasNext()) { + final BlockInterface block = bi.next(); + final BlockIterator bdir = block.iterator(BlockInterface.DIRECTIVE); + + if (bdir.hasNext()) { + final List dirs = emitDirective(block, null, f, emitter); + + // Do not write any headers, unless there are actual + // directives to output + if (dirs.size() > 0) { + if (!wroteHeader) { + iw.write(block.getType() + " {\n"); + iw.nextLevel(); + wroteHeader = true; + } + emitDirective(dirs.iterator(), iw); + } + } + } + if (wroteHeader) { + iw.prevLevel(); + iw.write("}\n"); + } + } + + /** + * Emit the directives contained in the give block. Directives contained in + * source is first merged with the directives block in + * block, and the result is then emitted. + * + * @param block Emit the directives of this block + * @param emitter The DirectiveEmitter to convert directive + * values to strings. + * @param source What directives to merge in. + * @param extra Additional directives to emit. + * @param iw Where to write the directives. + * @param header true if the block level name and braces + * should be written (e.g., pre { }). + **/ + private static void emitDirective(final BlockInterface block, + final DirectiveEmitter emitter, + final DirectiveInterfaceFactory source, + final DirectiveInterfaceFactory extra, + final IndentWriter iw, + final boolean header) + throws IOException { + DirectiveBlock realDir = DirectiveUtils.getDirectiveBlock(block); + if (realDir == null) { + if (source == null) return; + realDir = new DirectiveBlock(source.getDirectiveInterface()); + } else if (source != null) { + realDir = + new MergeDirective(realDir, source.getDirectiveInterface()); + } + final String type = block.getType(); + final DirectiveFilter.ByDirective filter = FILTER_MAP.get(type); + final List dirs = + emitDirective(block, realDir, filter, emitter); + final List extraDirs; + if (extra == null) { + extraDirs = Collections.EMPTY_LIST; + } else { + extraDirs = emitDirective( + block, new DirectiveBlock(extra.getDirectiveInterface()), + filter.getReverse(), emitter); + } + + if (dirs.size() > 0 && header) { + iw.write(type + " {\n"); + iw.nextLevel(); + } + + emitDirective(new FlatteningIterator(dirs.iterator(), + extraDirs.iterator()), iw); + + if (dirs.size() > 0 && header) { + iw.prevLevel(); + iw.write("}\n"); + } + } + + private static void emitDirective(final BlockInterface block, + final DirectiveEmitter emitter, + final DirectiveInterfaceFactory source, + final IndentWriter iw, + final boolean header) + throws IOException { + emitDirective(block, emitter, source, null, iw, header); + } + + private final static DirectiveFilter.ByDirective TOP_LEVEL_FILTER = + new DirectiveFilter.ByDirective( + true, + new HashSet( + Arrays.asList(new String[] { + DirectiveConstants.FIXED_SIZE, + DirectiveConstants.TAU, + DirectiveConstants.DENSITY_FACTOR, + DirectiveConstants.HEIGHT, + DirectiveConstants.WIDTH, + DirectiveConstants.AUTO_LAYOUT, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.STATICIZER_RATIO, + DirectiveConstants.STATICIZER_TYPE + }))); + + private final static DirectiveFilter.ByDirective SUBCELL_FILTER = + new DirectiveFilter.ByDirective( + true, + new HashSet( + Arrays.asList(new String[] { + DirectiveConstants.INLINE_LAYOUT, + DirectiveConstants.CAP, + DirectiveConstants.ESTIMATED_DELAY + }))); + + private final static DirectiveFilter.ByDirective PRS_FILTER = + new DirectiveFilter.ByDirective( + true, + new HashSet( + Arrays.asList(new String[] { + DirectiveConstants.CAP, + DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.STATICIZER_RATIO, + DirectiveConstants.STATICIZER_TYPE, + DirectiveConstants.SYMMETRIZE, + DirectiveConstants.SHARED + }))); + + private final static Map FILTER_MAP = + new HashMap(); + static { + FILTER_MAP.put(BlockInterface.CELL, TOP_LEVEL_FILTER); + FILTER_MAP.put(BlockInterface.SUBCELL, SUBCELL_FILTER); + FILTER_MAP.put(BlockInterface.PRS, PRS_FILTER); + } + + /** + * Emit directives in all blocks of cell, except block types + * which appear in exclude. + * + * @param cell Emit the directives of all (except types contained in + * exclude blocks this cell. + * @param emitter The DirectiveEmitter to convert directive + * values to strings. + * @param exclude Set of block types to ignore. + * @param iw Where to write the directives. + **/ + private static void emitDirective(final CellInterface cell, + final DirectiveEmitter emitter, + final Set exclude, + final IndentWriter iw) throws IOException + { + final BlockInterface cellBlock = cell.getBlockInterface(); + /* + for (Iterator i = cellBlock.getAttachedTypes(); i.hasNext(); ) { + final String type = (String) i.next(); + if (exclude.contains(type)) continue; + emitDirective(cellBlock.iterator(type), emitter, iw); + } + */ + } + + /** + * Emit a list of directives as strings to an IndentWriter. + * If the iterator is empty, do not output anything, otherwise, add the + * property directive block structure. + * + * @param directiveStrings Iterator of strings to output. + * @param iw IndentWriter to write to. + * @return true if anything is written, false + * otherwise. + **/ + private static boolean emitDirective(final Iterator directiveStrings, + final IndentWriter iw) + throws IOException + { + if (directiveStrings.hasNext()) { + iw.write("directives {\n"); + iw.nextLevel(); + while (directiveStrings.hasNext()) { + iw.write((String) directiveStrings.next()); + iw.write("\n"); + } + iw.prevLevel(); + iw.write("}\n"); + return true; + } else { + return false; + } + } + + /** + * Returns the value of the fixed_size top level directive. + **/ + private static boolean isFixed(final CellInterface cell) { + return CellUtils.isFixed(cell); + } + + /** + * Emit directives contained in dirBlock as + * Strings, and return them in a list. + * + * @param block The block the directives are contained in. + * @param dirBlock The DirectiveBlock containing the + * directives. If null, then the DirectiveBlock + * is assumed to be the one attached to block + * @param emitter The DirectiveEmitter to convert directive + * values to strings. + * + * @return list of string representations of the directives. + **/ + private static List emitDirective(final BlockInterface block, + final DirectiveBlock dirBlock, + final DirectiveActionFilter f, + final DirectiveEmitter emitter) { + final List result = new ArrayList(); + final DirectiveActionInterface act = + new DirectiveActionInterface() { + public void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType) + throws IOException { + result.add(directive + " = " + emitter.emit(block.getType(), valueType, value) + ";"); + } + public void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) + throws IOException { + result.add(directive + "(" + emitter.emit(block.getType(), parameterType, parameter) + ") = " + emitter.emit(block.getType(), valueType, value) + ";"); + } + public void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) + throws IOException { } + public void doBlockInterface(BlockInterface block) + throws IOException { } + }; + + try { + final DirectiveActionInterface fullAct = + f == null ? act : f.filter(act); + final DirectiveWalker walker = new DirectiveWalker(fullAct); + + if (dirBlock == null) walker.walk(block); + else walker.walk(block, dirBlock); + } catch (UnknownDirectiveException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new AssertionError("Should never happen."); + } + return result; + } + + private static DirectiveInterfaceFactory getExtraDirs( + final BlockInterface child, final BlockInterface parent) { + final DirectiveDifference dirs = + new DirectiveDifference(child.getType()); + final DirectiveWalker walker = new DirectiveWalker(dirs); + try { + walker.walk(child); + dirs.setMode(false); + walker.walk(parent); + } catch (UnknownDirectiveException e) { + } catch (IOException e) { + } + return dirs; + } + + private static Map getExtraDirs(final CellInterface child) { + final Map result = new HashMap(); + final CellInterface parent = child.getDirectRefinementParent(); + result.put(BlockInterface.CELL, + getExtraDirs(child.getBlockInterface(), + parent.getBlockInterface())); + result.put(BlockInterface.SUBCELL, + getExtraDirs(child.getBlockInterface() + .iterator(BlockInterface.SUBCELL) + .next(), + parent.getBlockInterface() + .iterator(BlockInterface.SUBCELL) + .next())); + return result; + } + + abstract static class SimplePolicy implements Policy { + protected final Map subtypeMap; + public SimplePolicy() { + subtypeMap = new LinkedHashMap(); + } + + public abstract Decision getDecision(final CellInterface cell) + throws IOException; + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String oldType = subcell.getFullyQualifiedType(); + return new Pair(oldType, subtypeMap.get(oldType)); + } + } + + /** + * Implements the --subtype mode policy: (1) Create new subtypes for all + * cells, unless (2) subtype is specified, in which case use the specified + * subtype for all cells, overwrite if necessary. + **/ + public static class Subtype implements Policy { + private final File path; + private final Format header; + private final int minSubtype, maxSubtype; + private final Map seen; + private final Set warn; + private String defaultAttribute, current; + private final BinaryFunction writeSubtype; + private final CastDesign design; + private final Map missingAlias; + + private String getLayout(final CellInterface cell) { + return (String) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.LAYOUT_ATTRIBUTES); + } + + private String getExtra(final CellInterface cell) { + return (String) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.EXTRA_LAYOUT_ATTRIBUTES); + } + + /** + * Apply the name_mapping directive. Returns the module name, which is + * also the refinement parent. + **/ + private String resolveMapping(final CellInterface cell) { + final String map = (String) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.NAME_MAPPING); + final String parentMap = (String) DirectiveUtils.getTopLevelDirective(cell.getDirectRefinementParent(), DirectiveConstants.NAME_MAPPING); + final String result; + if (map == null || map.equals(parentMap)) { + result = cell.getFullyQualifiedType(); + } else { + result = + map.indexOf('.') == -1 ? cell.getModuleName() + "." + map + : map; + boolean isAlias = false; + try { + final CellInterface alias = + design.getCastFileParser().getFullyQualifiedCell(result); + if (!alias.isAlias()) { + missingAlias.put(result, null); + } + } catch (Exception e) { + missingAlias.put(result, e); + } + } + return result; + } + + private String futureLayout(final String current, + final CellInterface cell) { + final String s = getLayout(cell); + if (s == null) return current; + else return s; + } + + static Map getDirectives(final CellInterface cell) { + final DirectiveSource top = + new DirectiveSource(BlockInterface.CELL); + if (CellUtils.isLeaf(cell)) { + top.definition(DirectiveConstants.FIXED_SIZE, + CellUtils.isFixedSize(cell) ? Boolean.TRUE : + Boolean.FALSE); + } else { + top.definition(DirectiveConstants.FIXED_SIZE, Boolean.FALSE); + } + + return Collections.singletonMap(BlockInterface.CELL, top); + } + + public Subtype(final int minSubtype, final String path, + final Format header, final String layoutAttribute, + final BinaryFunction writeSubtype, + final CastDesign design, + final Map missingAlias) { + this(path, header, minSubtype, Integer.MAX_VALUE, layoutAttribute, + writeSubtype, design, missingAlias); + } + + public Subtype(final String path, final Format header, + final int minSubtype, final int maxSubtype, + final String layoutAttribute, + final BinaryFunction writeSubtype, + final CastDesign design, + final Map missingAlias) { + this.path = new File(path); + this.header = header; + this.minSubtype = minSubtype; + this.maxSubtype = maxSubtype; + this.seen = new HashMap(); + this.warn = new HashSet(); + this.current = null; + this.defaultAttribute = layoutAttribute; + this.writeSubtype = writeSubtype; + this.design = design; + this.missingAlias = missingAlias; + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + if (!warn.add(type)) { + System.err.println("Warning: creating subtype for cell " + type + " due to incompatible layout_attribute."); + } + final String base = resolveMapping(cell); + final File dir = cellPath(path, base); + final String subtyped = + findNextSubtype(dir, minSubtype, maxSubtype); + final Writer writer = openFile(dir, subtyped + ".cast"); + + final Map directives = getDirectives(cell); + + if (current == null) { + current = getLayout(cell); + if (current == null) current = defaultAttribute; + } + + final String extra = getExtra(cell); + final List attributes = new ArrayList(2); + if (current != null) attributes.add(current); + if (extra != null) attributes.add(extra); + + return new Decision(base, subtyped, directives, writer, + getHeader(header, "subtype"), + (String[]) attributes.toArray(new String[0])); + } + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + final String layout = futureLayout(current, subcell); + final Pair key = new Pair(resolveMapping(subcell), layout); + if (!seen.containsKey(key)) { + final String oldcurr; + if (layout == null || layout.equals(current)) { + oldcurr = null; + } else { + oldcurr = current; + current = layout; + } + + final Object o = (String) writeSubtype.execute(this, design.getCell(type)); + if (o instanceof IOException) { + System.err.println("Cannot create new subtype for " + type + ": " + ((IOException) o).getMessage() + "!"); + return null; + } + seen.put(key, (String) o); + + if (oldcurr != null) { + current = oldcurr; + } + } + return new Pair(type, (String) seen.get(key)); + } + } + + public static class Compact implements Policy { + private final File[] path; // path[0] is the subtype output path + private final Format header; + private final int minSubtype, maxSubtype; + private final Map unsplittable; + private final MultiMap spec; + private final Set skip; + private final int lo, hi; + + public Compact(final String[] path, final Format header, + final int minSubtype, final int maxSubtype, + final MultiMap spec, final Set skip, + final int rangeLo, final int rangeHi) { + this.path = new File[path.length]; + for (int i = 0; i < path.length; ++i) { + this.path[i] = new File(path[i]); + } + this.header = header; + this.minSubtype = minSubtype; + this.maxSubtype = maxSubtype; + this.unsplittable = new LinkedHashMap(); + this.spec = spec; + this.skip = skip; + this.lo = rangeLo; + this.hi = rangeHi; + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final File[] dir = cellPath(path, module); + + Integer subtype; + try { + subtype = new Integer(cell.getType()); + } catch (NumberFormatException e) { + subtype = null; + } + + final String subtyped; + if (subtype != null && lo <= subtype.intValue() && + subtype.intValue() <= hi && !skip.contains(type)) { + subtyped = findOpenSubtype(dir, minSubtype, maxSubtype); + } else { + subtyped = cell.getType(); + } + + if (subtyped == null) { + throw new RuntimeException("No available subtype in range " + minSubtype + ".." + maxSubtype + " for cell " + type); + } + final Writer writer = openFile(dir[0], subtyped + ".cast"); + + unsplittable.put(type, module + "." + subtyped); + spec.put(type, subtyped); + return new Decision(module, subtyped, getParentName(cell), + Collections.EMPTY_MAP, getExtraDirs(cell), + writer, getHeader(header, "compact"), + getAttributes(cell), null, null); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + if (unsplittable.containsKey(type)) { + return new Pair(getParentName(parent, instance), + (String) unsplittable.get(type)); + } else { + try { + final String subtype; + subtype = writeSubtype(this, subcell); + return new Pair(getParentName(parent, instance), subtype); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + return null; + } + } + } + } + + /** + * Implements the copy policy. Output all cells with given subtype. + **/ + public static class Copy extends SimplePolicy { + private final String subtype; // 0 + private final File path; + private final Format header; + private final MultiMap spec; + + public Copy(final String path, final Format header, + final String subtype, final MultiMap spec) { + this.path = new File(path); + this.header = header; + this.subtype = subtype; + this.spec = spec; + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final File dir = cellPath(path, module); + final String subtyped = subtype; + final Writer writer = openFile(dir, subtyped + ".cast"); + spec.put(type, subtyped); // keep a split spec to copy views + + return new Decision(module, subtyped, getParentName(cell), + Collections.EMPTY_MAP, writer, + getHeader(header, "copy"), + getAttributes(cell)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + try { + final String subtype = writeSubtype(this, subcell); + return new Pair(getParentName(parent, instance), subtype); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + return null; + } + } + } + + /** + * The policy to transform directives. Currently, it only works with + * top-level directives. + **/ + public static class DirectiveTransform implements Policy { + private final boolean recursive; + private final File path; + private final Format header; + private final Map dirs; + private final Set seen; + + public DirectiveTransform(final String path, final Format header, + final boolean recursive, final Map dirs) { + this.path = new File(path); + this.header = header; + this.recursive = recursive; + this.dirs = dirs; + this.seen = new HashSet(); + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String module = cell.getModuleName(); + final String subtyped = cell.getType();; + final File dir = cellPath(path, module); + final Writer writer; + if (seen.add(cell.getFullyQualifiedType())) { + writer = openFile(dir, subtyped + ".cast"); + } else { + writer = null; + } + + return new Decision(module, subtyped, getParentName(cell), + dirs, writer, getHeader(header, "transform"), + getAttributes(cell)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + if (recursive) { + try { + writeSubtype(this, subcell); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + } + } + return new Pair(getParentName(parent, instance), type); + } + } + + private static class CopySpec implements SubtypeSplit.Spec { + private final String from, to; + + public CopySpec(final String from, final String to) { + assert from != null && to != null; + this.from = from; + this.to = to; + } + + public String getSpec(final CDLNameInterface renamer) { + try { + return "COPY: " + renamer.renameCell(from) + " " + renamer.renameCell(to); + } catch (CDLRenameException e) { + throw new RuntimeException("Cannot rename " + from + " or " + to, e); + } + } + + public boolean equals(final Object o) { + if (o instanceof CopySpec) { + final CopySpec spec = (CopySpec) o; + return from.equals(spec.from) && to.equals(spec.to); + } else { + return false; + } + } + + public int hashCode() { + return from.hashCode() + to.hashCode(); + } + } + + /** + * Describes a change of instance inst in cell + * cell from type from to type to. + **/ + private static class ChangeSpec implements SubtypeSplit.Spec { + private final String cell, inst, from, to; + + public ChangeSpec(final String cell, final String inst, + final String from, final String to) { + this.cell = cell; + this.inst = inst; + this.from = from; + this.to = to; + } + + public String getSpec(final CDLNameInterface renamer) { + try { + return "CHANGE: " + + renamer.renameCell(cell) + " " + + renamer.renameSubCellInstance(inst) + " " + + renamer.renameCell(from) + " " + + renamer.renameCell(to); + } catch (CDLRenameException e) { + throw new RuntimeException( + "Cannot rename " + cell + ", " + inst + ", " + + from + ", or " + to, e); + } + } + + public boolean equals(final Object o) { + if (o instanceof ChangeSpec) { + final ChangeSpec spec = (ChangeSpec) o; + return cell.equals(spec.cell) && + inst.equals(spec.inst) && + from.equals(spec.from) && + to.equals(spec.to); + } else { + return false; + } + } + + public int hashCode() { + return cell.hashCode() + inst.hashCode() + from.hashCode() + + to.hashCode(); + } + } + + /** + * Implements the forced reuse policy. + * XXX: possible bad interaction with meta parameter compression in + * hashMetaParameters() + **/ + public static class Reuse implements Policy { + /** + * A map: module:String -> subtype:CellInterface + **/ + private final Map reuse; + private final Collection spec; + private final File path; + private final Format header; + private final Set seen; + private Policy current; + private CellInterface repl; + + private static boolean hasMetaParameters(final CellInterface ci) { + final String module = ci.getModuleName(); + final int lparen = module.lastIndexOf('('); + final int rparen = module.lastIndexOf(')'); + return lparen > 0 && lparen < rparen; + } + + private class Transparent implements Policy { + public Decision getDecision(final CellInterface cell) + throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final String subtype = cell.getType(); + final Writer writer; + if (seen.add(type)) { + final File dir = cellPath(path, module); + writer = openFile(dir, subtype + ".cast", cell); + } else { + writer = null; + } + + return new Decision(module, subtype, getParentName(cell), + Collections.EMPTY_MAP, writer, + getHeader(header, "reuse"), + getAttributes(cell)); + } + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + try { + spec.add(new CopySpec(type, type)); + writeSubtype(this, subcell); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + + type + "!"); + return null; + } + return new Pair(getParentName(parent, instance), type); + } + } + + private class Metaparameter implements Policy { + private CellInterface target; + public Metaparameter(final CellInterface target) { + this.target = target; + } + public Decision getDecision(final CellInterface cell) + throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final String subtype = cell.getType(); + final Writer writer; + if (seen.add(type)) { + final File dir = cellPath(path, module); + writer = openFile(dir, subtype + ".cast"); + } else { + writer = null; + } + + return new Decision(module, subtype, getParentName(cell), + Collections.EMPTY_MAP, writer, + getHeader(header, "reuse"), + getAttributes(cell)); + } + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell1, + final HierName instance) { + final String type1 = subcell1.getFullyQualifiedType(); + final CellInterface subcell2 = target.getSubcell(instance); + final String type2 = subcell2.getFullyQualifiedType(); + final String actual; + String type = null; + try { + if (hasMetaParameters(subcell1) && !type1.equals(type2)) { + assert hasMetaParameters(subcell2); + type = type1; + spec.add(new CopySpec(type2, type1)); + final CellInterface old = target; + target = subcell2; + actual = writeSubtype(this, subcell1); + target = old; + } else { + type = type2; + actual = writeSubtype(new Transparent(), subcell2); + } + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + return null; + } + return new Pair(getParentName(parent, instance), actual); + } + } + + public Reuse(final String path, final Format header, final Map reuse, + final Collection spec) { + assert(reuse != null && spec != null); + this.path = new File(path); + this.header = header; + this.reuse = reuse; + this.spec = spec; + this.seen = new HashSet(); + this.current = null; + this.repl = null; + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final CellInterface content; + + if (reuse.containsKey(module)) { // pedantic forced reuse + repl = (CellInterface) reuse.get(module); + current = new Transparent(); + spec.add(new CopySpec(repl.getFullyQualifiedType(), type)); + content = repl; + } else { + final String base = CellUtils.getBaseType(module); + repl = cell; + if (reuse.containsKey(base)) { + // Metaparameterized forced reuse + final CellInterface meta = (CellInterface) reuse.get(base); + spec.add(new CopySpec(meta.getFullyQualifiedType(), type)); + current = new Metaparameter(meta); + } else { // Not subject to forced reuse + current = null; + } + content = null; + } + + final Writer writer; + if (seen.add(repl.getModuleName() + "." + repl.getType())) { + final File dir = cellPath(path, repl.getModuleName()); + writer = openFile(dir, repl.getType() + ".cast", repl); + } else { + writer = null; + } + + return new Decision(repl.getModuleName(), repl.getType(), + getParentName(repl), + Collections.EMPTY_MAP, writer, + getHeader(header, "reuse"), + getAttributes(repl), repl, content); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + if (current == null) { + final String type; + final Policy old = current; + final CellInterface lper = repl; + try { + type = writeSubtype(this, subcell); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + subcell.getFullyQualifiedType() + "!"); + return null; + } + current = old; + repl = lper; + return new Pair(getParentName(parent, instance), type); + } else if (repl == parent) { + return current.getSubtype(parent, subcell, instance); + } else { + return current.getSubtype(parent, repl.getSubcell(instance), + instance); + } + } + } + + /** + * A helper class for SplitInstance. + **/ + public static class SplitHelper extends SimplePolicy { + private final File path; + private final Format header; + private final int minSubtype, maxSubtype; + private final MultiMap spec; + + public SplitHelper(final String path, final Format header, + final int minSubtype, final int maxSubtype, + final MultiMap spec) { + this.path = new File(path); + this.header = header; + this.minSubtype = minSubtype; + this.maxSubtype = maxSubtype; + this.spec = spec; + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final File dir = cellPath(path, module); + final String subtyped = findNextSubtype(dir, minSubtype, maxSubtype); + final Writer writer = openFile(dir, subtyped + ".cast"); + spec.put(type, subtyped); + + return new Decision(module, subtyped, getParentName(cell), + Collections.EMPTY_MAP, writer, + getHeader(header, "split-by-instance"), + getAttributes(cell)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String oldType = subcell.getFullyQualifiedType(); + if (!subtypeMap.containsKey(oldType)) { + try { + final String newType = writeSubtype(this, subcell); + subtypeMap.put(oldType, newType); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + oldType + "!"); + return null; + } + } + return new Pair(getParentName(parent, instance), subtypeMap.get(oldType)); + } + } + + /** + * Implements the splitting all policy: Create new subtypes for each + * instance of a cell that is splittable (determined via a directive). + * Chose subtype number within the limits given, and if the limits are too + * small, emit a warning. + **/ + public static class SplitAll implements Policy { + private final File path; + private final Format header; + private final int minSubtype, maxSubtype; + private final Set splittable; + private final boolean maximal; + private final Stack stack; + private final MultiMap spec; + private CellInterface parent; + private final Set seen; + + private boolean isSplittable(final CellInterface cell) { + return ((maximal || CellUtils.isSplittable(cell)) && !isFixed(cell)) + || splittable.contains(cell.getFullyQualifiedType()); + } + + private String getSubtype(final CellInterface parent, + final CellInterface current, final File dir) { + final boolean fixed; + if (parent == null) { // top level cell + fixed = isFixed(current); + } else { // not top level cell + fixed = isFixed(parent) || isFixed(current) + || !isSplittable(current); + } + + if (fixed) { + return current.getType(); + } else { + final String type = current.getFullyQualifiedType(); + final String subtype = + findNextSubtype(dir, minSubtype, maxSubtype); + if (subtype == null) { + throw new RuntimeException( + "No available subtype in range " + minSubtype + + ".." + maxSubtype + " for cell " + type); + } + spec.put(type, subtype); + return subtype; + } + } + + public SplitAll(final String path, final Format header, + final int minSubtype, final int maxSubtype, + final Set splittable, final boolean maximal, + final boolean splitArray, final MultiMap spec) { + this.path = new File(path); + this.header = header; + this.minSubtype = minSubtype; + this.maxSubtype = maxSubtype; + this.splittable = splittable; + this.maximal = maximal; + if (splitArray) { + this.stack = null; + } else { + this.stack = new Stack(); + this.stack.push(new LinkedHashMap()); + } + this.spec = spec; + this.parent = null; + this.seen = new HashSet(); + } + + public Decision getDecision(final CellInterface cell) + throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final File dir = cellPath(path, module); + final String subtyped = getSubtype(parent, cell, dir); + + final Writer writer = seen.add(module + "." + subtyped) ? + openFile(dir, subtyped + ".cast", cell) : null; + return new Decision(module, subtyped, getParentName(cell), + Collections.EMPTY_MAP, writer, + getHeader(header, "split"), + getAttributes(cell)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + try { + final CellInterface oldParent = this.parent; + this.parent = parent; + final String subtype; + if (stack == null) { + subtype = writeSubtype(this, subcell); + } else { + final Map done = (Map) stack.peek(); + final String arrayBase = + instance.getArrayBase().getAsString('.'); + final String fullBase = getArrayBase(arrayBase); + final Pair key = new Pair(fullBase, type); + if (done.containsKey(key)) { + subtype = (String) done.get(key); + } else { + stack.push(new LinkedHashMap()); + subtype = writeSubtype(this, subcell); + stack.pop(); + done.put(key, subtype); + } + } + this.parent = oldParent; + return new Pair(getParentName(parent, instance), subtype); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + return null; + } + } + } + + /** + * Implements splitting by type policy: Create new subtypes for each + * instance of a cell that is specified as splittable. Any children of + * such a cell is treated as if it were handled by the splitting all + * policy. + **/ + public static class SplitType implements Policy { + private final File path; + private final Format header; + private final int minSubtype, maxSubtype; + private final Set splittable; + private final Policy splitAll; + private final MultiMap spec; + + public SplitType(final String path, final Format header, + final int minSubtype, final int maxSubtype, + final Set splittable, final MultiMap spec) { + this.path = new File(path); + this.header = header; + this.minSubtype = minSubtype; + this.maxSubtype = maxSubtype; + this.splittable = splittable; + this.spec = spec; + this.splitAll = new SplitAll(path, header, minSubtype, maxSubtype, splittable, false, false, spec); + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final String subtyped = cell.getType(); + final File dir = cellPath(path, module); + + final Writer writer; + if (CellUtils.isLeaf(cell)) { + writer = null; + } else { + writer = openFile(dir, subtyped + ".cast"); + spec.put(type, subtyped); + } + + return new Decision(module, subtyped, getParentName(cell), + Collections.EMPTY_MAP, writer, + getHeader(header, "split-by-type"), + getAttributes(cell)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + if (splittable.contains(type)) { + try { + return new Pair(getParentName(parent, instance), + writeSubtype(splitAll, subcell)); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + return null; + } + } else { + try { + return new Pair(getParentName(parent, instance), + writeSubtype(this, subcell)); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + return null; + } + } + } + } + + /** + * Implements splitting by instance policy: Create new subtypes for the + * specified instances in the top-level cell. For each new subtype, a new + * subtype tree will be created rooted there, i.e., --mode=subtype, not + * taking into account the splittable directive. + **/ + public static class SplitInstance implements Policy { + private final File path; + private final Format header; + private final int minSubtype, maxSubtype; + private final Set instances; + private final Policy subtypePolicy; + private final MultiMap spec; + + public SplitInstance(final String path, final Format header, + final int minSubtype, final int maxSubtype, + final Set instances, final MultiMap spec) { + this.path = new File(path); + this.header = header; + this.minSubtype = minSubtype; + this.maxSubtype = maxSubtype; + this.instances = instances; + this.spec = spec; + this.subtypePolicy = + new SplitHelper(path, header, minSubtype, maxSubtype, spec); + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final String subtyped = cell.getType(); + final File dir = cellPath(path, module); + + final Writer writer; + if (CellUtils.isLeaf(cell)) { + writer = null; + } else { + writer = openFile(dir, subtyped + ".cast"); + spec.put(type, subtyped); + } + + return new Decision(module, subtyped, getParentName(cell), + Collections.EMPTY_MAP, writer, + getHeader(header, "split-by-instance"), + getAttributes(cell)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + final String inst = instance.getAsString('.'); + if (instances.contains(inst)) { + try { + return new Pair(getParentName(parent, instance), + writeSubtype(subtypePolicy, subcell)); + } catch (IOException e) { + System.err.println("Cannot create new subtype for " + type + "!"); + return null; + } + } else { + return new Pair(getParentName(parent, instance), type); + } + } + } + + /** + * Split by hierarchical instance name. + **/ + static class SplitHierarchy implements Policy { + private static class HierarchyException extends RuntimeException { + public HierarchyException(String s) { + super(s); + } + } + + /** + * Replacement represents changes in the types of the + * subcells to the prototype cell. + **/ + private class Replacement implements Policy { + private final CellInterface prototype; + private final Map changes; + private String subtype; + + public Replacement(final CellInterface prototype) { + this.prototype = prototype; + this.changes = new HashMap(); + this.subtype = null; + } + + public Replacement getSubcell(final HierName inst) { + return changes.get(inst); + } + + public Replacement putSubcell(final HierName inst, + final Replacement replace) { + return changes.put(inst, replace); + } + + public void setSubtype(final String subtype) { + this.subtype = subtype; + } + + public Decision getDecision(final CellInterface cell) + throws IOException { + final String module; + final String next; + final Writer writer; + final Map extraDirs; + + if (changes.isEmpty()) { + final int dot = subtype.lastIndexOf('.'); + assert dot > 0; + module = subtype.substring(0, dot); + next = subtype.substring(dot + 1); + writer = null; + extraDirs = Collections.EMPTY_MAP; + } else { + module = cell.getModuleName(); + final File dir = cellPath(path, module); + next = findNextSubtype(dir, minSubtype, maxSubtype); + writer = openFile(dir, next + ".cast"); + setSubtype(module + "." + next); + + extraDirs = getExtraDirs(cell); + } + + return new Decision(module, next, getParentName(cell), + Collections.EMPTY_MAP, extraDirs, writer, + getHeader(header, "split-by-hierarchy"), + getAttributes(cell), null, null); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final Replacement replace = getSubcell(instance); + final String newType; + if (replace == null) { + newType = subcell.getFullyQualifiedType(); + } else { + try { + newType = getReplacementType(replace); + } catch (IOException e) { + System.err.println("Cannot create a new subtype for: " + + subcell.getFullyQualifiedType()); + return null; + } + } + return new Pair(getParentName(parent, instance), newType); + } + + private void updateSpec(Replacement lastRouted, HierName path, + final Collection spec) { + if (CellUtils.isRouted(prototype)) { + if (!changes.isEmpty()) { + if (subtype == null) { + try { + subtype = getReplacementType(this); + } catch (IOException e) { + throw new RuntimeException( + "Cannot create a new subtype for: " + + prototype.getFullyQualifiedType(), e); + } + } + spec.add(new CopySpec(prototype.getFullyQualifiedType(), + subtype)); + } + lastRouted = this; + path = null; + } + for (Map.Entry change : + changes.entrySet()) { + final HierName full = + HierName.append(path, change.getKey()); + final Replacement subcell = change.getValue(); + if (CellUtils.isRouted(subcell.prototype)) { + if (subcell.subtype == null) { + try { + getReplacementType(subcell); + } catch (IOException e) { + throw new RuntimeException( + "Cannot create a new subtype for: " + + subcell.prototype.getFullyQualifiedType(), + e); + } + } + spec.add(new ChangeSpec( + lastRouted.subtype, + full.getAsString('.'), + subcell.prototype.getFullyQualifiedType(), + subcell.subtype)); + } + if (!subcell.changes.isEmpty()) { + subcell.updateSpec(lastRouted, full, spec); + } + } + } + + public void updateSpec(final Collection spec) { + // always assume the top-level cell is routed + updateSpec(this, null, spec); + } + + public boolean equals(final Object o) { + if (o instanceof Replacement) { + return equals((Replacement) o); + } else { + return false; + } + } + + public boolean equals(final Replacement o) { + if (subtype != null && o.subtype != null) { + return subtype.equals(o.subtype); + } else { + if (prototype == o.prototype) { + return changes.equals(o.changes); + } else { + return false; + } + } + } + + public int hashCode() { + return prototype.getFullyQualifiedType().hashCode() + + changes.hashCode(); + } + } + + private final File path; + private final Format header; + private final CellInterface cell; + private final Replacement replacement; + private final Collection> instances; + private final int minSubtype, maxSubtype; + private final Map written; + private final Collection spec; + + public SplitHierarchy( + final String path, final Format header, + final CellInterface cell, + final Collection> instances, + final int minSubtype, final int maxSubtype, + final Collection spec, + final Collection errors) { + this.path = new File(path); + this.cell = cell; + this.header = header; + this.replacement = new Replacement(cell); + this.instances = instances; + this.minSubtype = minSubtype; + this.maxSubtype = maxSubtype; + this.written = new HashMap(); + this.spec = spec; + for (Pair inst : instances) { + try { + traverse(cell, replacement, inst.getFirst(), + inst.getSecond()); + } catch (HierarchyException e) { + errors.add(inst.getFirst() + " " + e.getMessage()); + } + } + } + + private Replacement traverse(final CellInterface cell, + Replacement replace, + final HierName inst, + final String sub) { + if (replace == null) replace = new Replacement(cell); + if (inst == null) { + replace.setSubtype(sub); + return replace; + } + + boolean found = false; + for (Pair split : + new IterableIterator>( + HierName.getSplitsIterator(inst))) { + final HierName prefix = split.getFirst(); + final HierName suffix = split.getSecond(); + final CellInterface subcell = cell.getSubcell(prefix); + if (subcell != null && !cell.isInlinedSubcell(prefix)) { + replace.putSubcell( + prefix, + traverse(subcell, replace.getSubcell(prefix), + suffix, sub)); + found = true; + break; + } + } + + if (!found) { + throw new HierarchyException( + cell.getFullyQualifiedType() + " " + inst); + } + + return replace; + } + + private String getReplacementType(final Replacement replace) + throws IOException { + final Replacement canon = written.get(replace); + if (canon == null) { + writeSubtype(replace, replace.prototype); + written.put(replace, replace); + } else { + replace.setSubtype(canon.subtype); + } + return replace.subtype; + } + + private Decision getDummyDecision(final CellInterface cell, + final Replacement r) + throws IOException { + final String subtype = getReplacementType(r); + final int dot = subtype.lastIndexOf('.'); + final String module = subtype.substring(0, dot); + final String type = subtype.substring(dot + 1); + return new Decision(module, type, getParentName(cell), + Collections.EMPTY_MAP, null, "", + getAttributes(cell)); + } + + public Decision getDecision(final CellInterface cell) + throws IOException { + writeSubtype(replacement, cell); + replacement.updateSpec(spec); + return getDummyDecision(cell, replacement); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + throw new RuntimeException("Shouldn't be called"); + } + } + + /** + * Implements the --size mode policy: Use the specified subtype as + * indicated by the cell name and overwrite. If trial mode is false, then + * set fixed_size = true, otherwise, persist the fixed_size directive. + **/ + public static class Size implements Policy { + private final File path; + private final boolean trial; + private final Format header; + private final float tau; + private final Map capMap; + private final boolean updateDirective; + + public Size(final String path, final boolean trial, final Format header, + final float tau, final Map capMap, + final boolean updateDirective) { + this.path = new File(path); + this.trial = trial; + this.header = header; + this.tau = tau; + this.capMap = capMap; + this.updateDirective = updateDirective; + } + + private void dumpCap(final DirectiveSource src, final String type) { + final List l = (List) capMap.get(type); + if (l != null) { + for (Iterator i = l.iterator(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final Triplet t = (Triplet) p.getSecond(); + if (t.getFirst() != null) { + src.definition(DirectiveConstants.CAP, + DirectiveConstants.NODE_TYPE, + p.getFirst(), t.getFirst()); + } + if (t.getSecond() != null) { + src.definition(DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.HALFOP_TYPE, + new Pair(p.getFirst(), Boolean.TRUE), + t.getSecond()); + } + if (t.getThird() != null) { + src.definition(DirectiveConstants.ESTIMATED_DELAY, + DirectiveConstants.HALFOP_TYPE, + new Pair(p.getFirst(), Boolean.FALSE), + t.getThird()); + } + } + } + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + // When sizing, the cell's name will contain the subtype part. + final String subtyped = cell.getType(); + + final Writer writer; + final Map directives; + + // If a leaf cell is fixed size, there is no point overwriting it + // with the exact same information. + if (updateDirective || !isFixed(cell)) { + directives = new HashMap(); + final File dir = cellPath(path, module); + writer = openFile(dir, subtyped + ".cast"); + + final DirectiveSource top = + new DirectiveSource(BlockInterface.CELL); + directives.put(BlockInterface.CELL, top); + if (!trial) { + top.definition(DirectiveConstants.FIXED_SIZE, Boolean.TRUE); + } + if (!isFixed(cell) && !Float.isNaN(tau)) { + top.definition(DirectiveConstants.TAU, new Float(tau)); + } + final String capType = + CellUtils.isLeaf(cell) ? BlockInterface.PRS : + BlockInterface.SUBCELL; + final DirectiveSource cap = new DirectiveSource(capType); + dumpCap(cap, type); + directives.put(capType, cap); + } else { + directives = Collections.EMPTY_MAP; + writer = null; + } + + return new Decision(module, subtyped, getParentName(cell), + directives, writer, getHeader(header, "size"), + getAttributes(cell)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + return new Pair(getParentName(parent, instance), type); + } + } + + /** + * Implements subtype merge policy. + **/ + public static class Merge implements Policy { + private final File path; + private final Format header; + private final SortedMap typeMap; + private final Set seen; + private final boolean writeLeaf; + private final Collection spec; + + public Merge(final String path, final Format header, + final SortedMap typeMap) { + this(path, header, typeMap, false, + new HashSet()); + } + + /** + * Construct the Merge policy. + * @param path Subtype path. + * @param header A header that is put at the top of subtypes written. + * @param typeMap A map that tells what subtypes should become. It is + * really a map from cell name -> (subtype -> subtype). + * @param writeLeaf Should leaves cells, which are never changed by a + * merge, be written out also? + **/ + public Merge(final String path, final Format header, + final SortedMap typeMap, final boolean writeLeaf, + final Collection spec) { + this.path = new File(path); + this.header = header; + this.typeMap = typeMap; + this.seen = new LinkedHashSet(); + this.writeLeaf = writeLeaf; + this.spec = spec; + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String type = cell.getFullyQualifiedType(); + final String module = cell.getModuleName(); + final String subtyped = cell.getType(); + final File dir = cellPath(path, module); + final Writer writer = + (!writeLeaf && CellUtils.isLeaf(cell)) ? null : openFile(dir, subtyped + ".cast", cell); + + seen.add(type); + + return new Decision(module, subtyped, getParentName(cell), + Collections.EMPTY_MAP, getExtraDirs(cell), + writer, getHeader(header, "merge"), + getAttributes(cell), null, null); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + final String type = subcell.getFullyQualifiedType(); + final String module = subcell.getModuleName(); + final String subtype = subcell.getType(); + final SortedMap subtypeMap = (SortedMap) typeMap.get(module); + final Pair p1 = (Pair) subtypeMap.get(subtype); + final Pair p2 = (Pair) subtypeMap.get(p1.getSecond()); + final CellInterface cell = (CellInterface) p2.getFirst(); + final String newType = cell.getFullyQualifiedType(); + if (!seen.contains(newType)) { + try { + writeSubtype(this, cell); + } catch (IOException e) { + System.err.println("Cannot overwrite subtype " + newType + "!"); + return null; + } + } + if (!newType.equals(subcell.getFullyQualifiedType())) { + spec.add(new ChangeSpec(parent.getFullyQualifiedType(), + instance.getAsString('.'), + subcell.getFullyQualifiedType(), + newType)); + } + return new Pair(getParentName(parent, instance), newType); + } + } + + /** + * Implements the update policy. One shot usage. Should only be applied + * to leaf cells. + **/ + public static class Update implements Policy { + private final File path; + private final Format header; + private final Pair to; + + public Update(final String path, final Format header, final Pair to) { + this.path = new File(path); + this.header = header; + this.to = to; + } + + public Decision getDecision(final CellInterface cell) throws IOException { + final String module = cell.getFullyQualifiedType(); + final String subtype = (String) to.getSecond(); + final CellInterface updatee = (CellInterface) to.getFirst(); + final Writer writer; + if (CellUtils.isLeaf(cell)) { + final File dir = cellPath(path, module); + writer = openFile(dir, subtype + ".cast"); + } else { + writer = null; + } + + final Map directives = Subtype.getDirectives(cell); + + return new Decision(module, subtype, directives, writer, + getHeader(header, "update"), + getAttributes(updatee)); + } + + public Pair getSubtype(final CellInterface parent, + final CellInterface subcell, + final HierName instance) { + throw new RuntimeException("Should not call getSubtype()!"); + } + } + + /** + * A specialized CDLEmitter that instead of printing out .SUBCKT and .ENDS + * lines, prints out the netlist block header and footer. + **/ + private static final class SubtypeEmitter extends CDLEmitter { + private final IndentWriter iw; + public SubtypeEmitter(final IndentWriter iw, final String lengthUnit) { + super(iw, lengthUnit, 6); + this.iw = iw; + } + public void subcktBegin(final AbstractNetlist netlist) { + print("netlist {"); + println(); + iw.nextLevel(); + } + public void subcktEnd(final AbstractNetlist netlist) { + iw.prevLevel(); + print("}"); + println(); + } + } + + /** + * Returns the string representation of an non-arrayed type. + **/ + private static String nonArrayTypeString(final PortTypeInterface type) { + if (type instanceof ChannelType) { + final ChannelType channel = (ChannelType) type; + final int width = channel.getWidth(); + if (channel.isArrayed()) { + return channel.getTypeName() + "[" + width + "]"; + } else { + assert width == 1; + return channel.getTypeName(); + } + } else if (type instanceof NodeType) { + final NodeType node = (NodeType) type; + final int width = node.getWidth(); + if (node.isArrayed()) { + return "node[" + width + "]"; + } else { + assert width == 1; + return "node"; + } + } else if (type instanceof StructureType) { + final String tag = ((StructureType) type).getTag(); + if (tag == null) return type.toString(); + else return tag; + } else { + Debug.assertTrue(false, "Unknown non-arrayed type " + type.getClass() + "!"); + return null; + } + } + + /** + * Returns the string representation of an ArrayType. The Pair contains + * (range, string representation of the arrayed type). + **/ + private static Pair arrayTypeString(final ArrayType type) { + final int min = type.getMinIndex(); + final int max = type.getMaxIndex(); + final PortTypeInterface arrayedType = type.getArrayedType(); + final String expr = min + ".." + max; + if (arrayedType instanceof ArrayType) { + final Pair sub = arrayTypeString((ArrayType) arrayedType); + return new Pair(expr + "," + sub.getFirst(), + sub.getSecond()); + } else { + return new Pair(expr, nonArrayTypeString(arrayedType)); + } + } + + /** + * Returns the string representation for a port in a cell. The result is + * suitable for reemitting CAST when showDir is true. + **/ + public static String portString(PortDefinition port, boolean showDir) { + final PortTypeInterface type = port.getType(); + final StringBuffer result = new StringBuffer(); + String dir = ""; + if (showDir) { + switch (port.getDirection()) { + case PortDefinition.IN: + dir = "-"; + break; + case PortDefinition.OUT: + dir = "+"; + break; + case PortDefinition.INOUT: + dir = "-+"; + break; + } + } + if (type instanceof ArrayType) { + final Pair info = arrayTypeString((ArrayType) type); + result.append((String) info.getSecond()); + result.append(" "); + result.append(dir); + result.append(port.getName()); + result.append("["); + result.append((String) info.getFirst()); + result.append("]"); + } else { + result.append(nonArrayTypeString(type)); + result.append(" "); + result.append(dir); + result.append(port.getName()); + } + return result.toString(); + } + + private static String portString(PortDefinition port) { + return portString(port, true); + } + + /** + * Returns a string representation of the header of a refinement of a cell + * in the CAST language. + * @param ci Cell whose port to copy. + * @param fromName Name of the cell refined from. + * @param toName Name of the cell refined to. + * @param attributes Attribute cells to inherit from + * @param explicitPortList If true, explicitly emit the port + * list of the cell; otherwise, omit the port list. + **/ + private static String castHeader(final CellInterface ci, + final String fromName, + final String toName, + final String[] attributes, + final boolean explicitPortList) { + final StringBuffer buf = new StringBuffer(); + buf.append("define "); + buf.append(toName); + buf.append("()"); + + if (explicitPortList) { + buf.append("("); + boolean first = true; + for (Iterator ports = ci.getPortDefinitions(); ports.hasNext(); ) { + final PortDefinition port = (PortDefinition) ports.next(); + if (!ci.isImpliedPort(port.getName())) { + if (first) first = false; + else buf.append("; "); + buf.append(portString(port)); + } + } + buf.append(")"); + } + + if (attributes != null) { + for (int i = 0; i < attributes.length; ++i) { + buf.append(" <+ " + attributes[i]); + } + } + buf.append(" <: "); + buf.append(fromName); + buf.append(" {"); + return buf.toString(); + } + + /** + * Write out a header appropriate for subtypes, omitting the port list. + **/ + public static void writeHeader(final Writer w, + final String module, + final String from, + final String subtype, + final CellInterface ci, + final String[] attributes, + final String header) + throws IOException { + writeHeader(w, module, from, subtype, ci, attributes, header, false); + } + + /** + * Write out a header appropriate for subtypes. + **/ + public static void writeHeader(final Writer w, + final String module, + final String from, + final String subtype, + final CellInterface ci, + final String[] attributes, + final String header, + final boolean explicitPortList) + throws IOException { + w.write("/* Copyright " + (new GregorianCalendar()).get(Calendar.YEAR) + " Intel Corporation. All rights reserved.\n"); + // Prevent Perforce from doing substitution on the string literal + w.write(" * $" + "Id$\n"); + w.write(" * $" + "DateTime$\n"); + w.write(" * $" + "Author$\n"); + w.write(" */\n"); + w.write("/* Automatically generated. Modify at your own risk. */\n"); + if (header != null) { + w.write("/*\n"); w.write(header); w.write("*/\n"); + } + + w.write("module " + CellUtils.hashMetaParameters(module) + ";\n"); + w.write(castHeader(ci, from, "\"" + subtype + "\"", attributes, + explicitPortList)); + w.write('\n'); + } + + /** + * Write out a CDL template inside a netlist block. + **/ + private static String writeTemplate(final Policy policy, + final CellInterface cell) throws IOException + { + final Decision decision = policy.getDecision(cell); + if (decision.writer != null) { + final IndentWriter iw = new IndentWriter(decision.writer); + final CellInterface contentCell = + decision.contentCell == null ? cell : decision.contentCell; + writeHeader(iw, decision.module, decision.from, decision.subtype, + contentCell, decision.attributes, decision.header); + iw.nextLevel(); + + iw.write("netlist {\n"); + iw.nextLevel(); + + final CDLFactoryEmitter emitter = new CDLFactoryEmitter(iw); + final BlockInterface cellBlock = contentCell.getBlockInterface(); + final NetlistBlock block = (NetlistBlock) cellBlock.iterator(BlockInterface.NETLIST).next(); + final Template templ = block.getCDLTemplate(); + if (templ == null) throw new RuntimeException("Netlist block does not exist for cell " + contentCell.getFullyQualifiedType()); + templ.execute(emitter); + + iw.prevLevel(); + iw.write("}\n"); + + final CellInterface dirCell = + decision.dirCell == null ? contentCell : decision.dirCell; + final BlockInterface dirCellBlock = dirCell.getBlockInterface(); + emitDirective(dirCellBlock.iterator(BlockInterface.PRS).next(), + CastEmitter.getInstance(), + (DirectiveSource) + decision.directives.get(BlockInterface.PRS), + iw, + true); + + emitDirective(dirCellBlock, CastEmitter.getInstance(), + (DirectiveSource) + decision.directives.get(BlockInterface.CELL), + iw, + false); + + iw.prevLevel(); + iw.write("}\n"); + + iw.close(); + } + return decision.module + "." + decision.subtype; + } + + /** + * Write out a Netgraph inside a netlist block. + **/ + private static String writeNetgraph(final Policy policy, + final AbstractNetlist netlist, + final String lengthUnit, + final CellType cell) throws IOException + { + final CellInterface ci = cell.cast_cell; + final Decision decision = policy.getDecision(ci); + if (decision.writer != null) { + final IndentWriter iw = new IndentWriter(decision.writer); + final CellInterface contentCell = + decision.contentCell == null ? ci : decision.contentCell; + writeHeader(iw, decision.module, decision.from, decision.subtype, + contentCell, decision.attributes, decision.header); + iw.nextLevel(); + + if (!cell.transistors.isEmpty()) { + final CDLEmitter emitter = new SubtypeEmitter(iw, lengthUnit); + emitter.format(netlist, emitter, false); + + final CellInterface dirCell = + decision.dirCell == null ? contentCell : decision.dirCell; + final BlockInterface cellBlock = dirCell.getBlockInterface(); + emitDirective(cellBlock.iterator(BlockInterface.PRS).next(), + CastEmitter.getInstance(), + (DirectiveSource) + decision.directives.get(BlockInterface.PRS), + iw, + true); + + emitDirective(cellBlock, CastEmitter.getInstance(), + (DirectiveSource) + decision.directives.get(BlockInterface.CELL), + iw, + false); + } + + iw.prevLevel(); + iw.write("}\n"); + + iw.close(); + } + return decision.module + "." + decision.subtype; + } + + /** + * Write out an empty cell body for when the cell acts like an internal + * environment + **/ + private static String writeEmptyBody(final Policy policy, + final CellInterface ci) + throws IOException { + final Decision decision = policy.getDecision(ci); + if (decision.writer != null) { + final IndentWriter iw = new IndentWriter(decision.writer); + final CellInterface contentCell = + decision.contentCell == null ? ci : decision.contentCell; + writeHeader(iw, decision.module, decision.from, decision.subtype, + contentCell, decision.attributes, decision.header); + iw.write("}\n"); + iw.close(); + } + return decision.module + "." + decision.subtype; + } + + /** + * Given a HierName of the form x[1,2].y[3,4] returns x[.y[. + **/ + private static String getArrayBase(final String s) { + final int len = s.length(); + final StringBuffer buf = new StringBuffer(len); + boolean bracket = false; + for (int i = 0; i < len; ++i) { + final char c = s.charAt(i); + if (!bracket) buf.append(c); + if (c == '[') bracket = true; + else if (c == ']') bracket = false; + } + return buf.toString(); + } + + /** + * Write out a midlevel cell inside a subtypes block. + **/ + private static String writeMidlevel(final Policy policy, + final CellInterface cell) throws IOException + { + final Decision decision = policy.getDecision(cell); + if (decision.writer != null) { + final IndentWriter iw = new IndentWriter(decision.writer); + final CellInterface contentCell = + decision.contentCell == null ? cell : decision.contentCell; + writeHeader(iw, decision.module, decision.from, decision.subtype, + contentCell, decision.attributes, decision.header); + iw.nextLevel(); + + iw.write("subtypes {\n"); + iw.nextLevel(); + for (Iterator i = contentCell.getLocalSubcellPairs(); + i.hasNext(); ) { + final Pair pair = (Pair) i.next(); + final CellInterface subcell = (CellInterface) pair.getSecond(); + if (CellUtils.isWiring(subcell)) continue; + final HierName instanceName = (HierName) pair.getFirst(); + + final Pair types = + policy.getSubtype(contentCell, subcell, instanceName); + + final String oldType = (String) types.getFirst(); + final String newType = (String) types.getSecond(); + Debug.assertTrue(newType != null, "No subtype for type " + subcell.getFullyQualifiedType() + " in " + contentCell.getFullyQualifiedType() + "!"); + iw.write(oldType + " :>\n"); + iw.nextLevel(); + iw.write(CellUtils.hashMetaParameters(newType) + " " + instanceName.getCadenceString() + ";\n"); + iw.prevLevel(); + } + final CellInterface dirCell = + decision.dirCell == null ? contentCell : decision.dirCell; + final BlockInterface cellBlock = dirCell.getBlockInterface(); + emitDirective(cellBlock.iterator(BlockInterface.SUBCELL).next(), + CastEmitter.getInstance(), + (DirectiveInterfaceFactory) + decision.directives.get(BlockInterface.SUBCELL), + (DirectiveInterfaceFactory) + decision.extraDirs.get(BlockInterface.SUBCELL), + iw, + false); + iw.prevLevel(); + iw.write("}\n"); + + emitDirective(cellBlock, CastEmitter.getInstance(), + (DirectiveInterfaceFactory) + decision.directives.get(BlockInterface.CELL), + (DirectiveInterfaceFactory) + decision.extraDirs.get(BlockInterface.CELL), + iw, + false); + + iw.prevLevel(); + iw.write("}\n"); + + iw.close(); + } + return decision.module + "." + decision.subtype; + } + + /** + * Write subtypes. + * @param policy Subtype policy to consult. + * @param cell Cell to write out. + * @param subtypeProc Transformation to be done on a Netgraph before + * outputting it. + * @param cutoff Largest transistor size not folded. + * @param cutoffmin Smallest transistor size after folding. + **/ + public static String writeSubtype(final Policy policy, + final CellType cell, + final DeviceProcessor subtypeProc, + final String lengthUnit, + final double cutoff, + final double cutoffmin, + final Map stackMap, + final HierName GND, + final HierName Vdd, + final float minWidth) throws IOException { + final String subtype; + final CellInterface ci = cell.cast_cell; + if (CellUtils.isLeaf(ci) || cell.isInternalEnv()) { + if (!cell.isInternalEnv() && CellUtils.isFixedSize(ci)) { + subtype = writeTemplate(policy, ci); + } else { + final AbstractNetlist netlist = new FoldTransistor(new NetlistAdapter(cell, false, stackMap, GND, Vdd, minWidth), cutoff, cutoffmin); + subtypeProc.setNetlist(netlist); + subtype = writeNetgraph(policy, subtypeProc, lengthUnit, cell); + } + } else { + subtype = writeMidlevel(policy, ci); + } + return subtype; + } + + public static String writeSubtype(final Policy policy, + final CellInterface cell) throws IOException { + final String subtype; + if (CellUtils.isInternalEnv(cell)) { + subtype = writeEmptyBody(policy, cell); + } else if (CellUtils.isLeaf(cell)) { + subtype = writeTemplate(policy, cell); + } else { + subtype = writeMidlevel(policy, cell); + } + return subtype; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeSplit.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeSplit.java new file mode 100644 index 0000000000..5eae192ee9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/SubtypeSplit.java @@ -0,0 +1,499 @@ +package com.avlsi.tools.jauto; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.text.DateFormat; +import java.text.Format; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveSource; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.layout.LayerCallback; +import com.avlsi.io.SearchPath; +import com.avlsi.io.FileSearchPath; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.text.StringUtil; + +public final class SubtypeSplit { + + private SubtypeSplit() { + throw new AssertionError(); + } + + public interface Spec { + String getSpec(final CDLNameInterface renamer); + } + + private static class SplitSpec implements Spec { + private final Collection targets; + private final String from; + + public SplitSpec(final String from, final Collection targets) { + this.from = from; + this.targets = targets; + } + + public String getSpec(final CDLNameInterface renamer) { + final StringBuffer buf = new StringBuffer(); + final int index = from.lastIndexOf('.'); + final String base = from.substring(0, index); + final String subtyped = from.substring(index + 1); + buf.append("SPLIT: "); + try { + buf.append(renamer.renameCell(base)); + } catch (CDLRenameException e) { + throw new RuntimeException("Cannot rename: " + base, e); + } + buf.append(' '); + buf.append(subtyped); + for (Iterator j = targets.iterator(); j.hasNext(); ) { + buf.append(' '); + buf.append((String) j.next()); + } + return buf.toString(); + } + } + + private static Collection convertSpec(final MultiMap mm) { + final Collection result = new ArrayList(); + for (Iterator i = mm.keySet().iterator(); i.hasNext(); ) { + final String type = (String) i.next(); + result.add(new SplitSpec(type, mm.get(type))); + } + return result; + } + + private static void usage() { + System.err.println( +"java com.avlsi.tools.jauto.SubtypeSplit\n" + +" [standard CAST options] function [function options]\n\n" + +"Standard CAST options are:\n" + +" [ --cast-path= ] (defaults to .)\n" + +" [ --cast-version=[ 1 | 2 ] ] (defaults to 2)\n" + +" --cell= (top level cell)\n" + +"Functions are:\n" + +" --all (split splittable instances)\n" + +" --instance instance1 instance2 ... (split specified instances)\n" + +" --type type1 type2 ... (split specified types)\n" + +" --force-reuse (force reuse of specified subtypes)\n" + +" --copy (copy to min-subtype)\n" + +" --compact (compact to smallest available subtype)\n" + +" --directive (set non-parameterized directives)\n" + +" --hierarchy (split specified hierarchical instances)\n" + +"Function options are:\n" + +" for all functions:\n" + +" [ --subtype-path= ] (defaults to .)\n" + +" for --all, --copy, --compact, --type, --instance, --force-reuse,\n" + +" --hierarchy:\n" + +" [ --output= ] (write split spec)\n" + +" for --all, --copy, --compact, --type, --instance, --hierarchy:\n" + +" [ --min-subtype= ] (defaults to 0)\n" + +" [ --max-subtype= ] (defaults to 2^31-1)\n" + +" for --all\n" + +" [ --maximal ] (split all instances)\n" + +" [ --split-array ] (break apart arrays)\n" + +" for --compact\n" + +" [ --compact-skip= ] (lists cells to not compact)\n" + +" [ --compact-range= ] (compact only specified range)\n" + +" [ --compact-path= ] (colon seperated list of existing spec)\n" + +" for --force-reuse\n" + +" [ --reuse-spec= ] (reuse without regard to metaparameters)\n" + +" [ --pedantic-reuse-spec= ] (reuse considering metaparameters)\n" + +" for --directive\n" + +" [ --recursive ] (recursively set directive)\n" + +" := ...\n" + +" for --hierarchy\n" + +" --replace-spec= (each line: new type, instance name)\n" +); + System.exit(1); + } + + private static int getArgValue(final String number, final int fallback) { + if (number == null) { + return fallback; + } else { + try { + return Integer.parseInt(number); + } catch (NumberFormatException e) { + return fallback; + } + } + } + + private static Format getHeader(final String cellName) { + final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); + final DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.LONG); + final Date now = new Date(); + final StringBuffer header = new StringBuffer(); + header.append(cellName); + header.append(":"); + header.append(dateFormat.format(now)); + header.append(":"); + header.append(timeFormat.format(now)); + header.append(":"); + header.append(System.getProperty("user.name")); + header.append("\n"); + return new MessageFormat(header.toString()); + } + + private static boolean reusable(final CellInterface ci) { + return !ci.isNode() && !ci.isChannel(); + } + + private static Pattern DIRECTIVE_SPEC = + Pattern.compile("(\\w+):([^=]+)=(.*)"); + private static void setDirective(final Map dirs, final String str) { + final Matcher m = DIRECTIVE_SPEC.matcher(str); + if (m.matches()) { + final String block = m.group(1); + final String key = m.group(2); + final String val = m.group(3); + + final Pair info = DirectiveTable.lookupDirective(block, key); + if (info == null) { + System.err.println("No " + key + " directives in block " + block); + return; + } + + if (!dirs.containsKey(block)) { + dirs.put(block, new DirectiveSource(block)); + } + final DirectiveSource src = (DirectiveSource) dirs.get(block); + final String valType = (String) info.getFirst(); + final Object value = DirectiveUtils.parseDirective(valType, val); + if (value == null) { + System.err.println("Cannot set directive " + key + " = " + val); + } else { + src.definition(key, value); + } + } else { + System.err.println("Invalid directive specification: " + str); + } + } + + private static void processReuseSpec(final String file, + final boolean pedantic, + final Map reuseMap, + final CastFileParser cfp) + throws IOException { + final BufferedReader br = new BufferedReader(new FileReader(file)); + int num = 1; + String line; + while ((line = br.readLine()) != null) { + final String s[] = StringUtil.tokenize(line); + try { + if (s.length == 1) { + final CellInterface ci = cfp.getFullyQualifiedCell(s[0]); + if (!pedantic) + reuseMap.put(CellUtils.getBaseType(ci.getModuleName()), + ci); + reuseMap.put(ci.getModuleName(), ci); + } else if (s.length == 3 && s[1].equals(":>")) { + final CellInterface ci1 = cfp.getFullyQualifiedCell(s[0]); + final CellInterface ci2 = cfp.getFullyQualifiedCell(s[2]); + final String fqcn = ci1.getFullyQualifiedType(); + if (!pedantic) + reuseMap.put(CellUtils.getBaseType(fqcn), ci2); + reuseMap.put(fqcn, ci2); + } else { + System.err.println("WARNING: Invalid reuse specification format in " + file + ":" + num); + } + } catch (CastSemanticException e) { + System.err.println("WARNING: Invalid cell in reuse specification in " + file + ":" + num); + ExceptionPrettyPrinter.printException(e); + } + ++num; + } + br.close(); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String subtypePath = theArgs.getArgValue("subtype-path", "."); + final String cellName = theArgs.getArgValue("cell", null); + final boolean splitAll = theArgs.argExists("all"); + final boolean copyOnly = theArgs.argExists("copy"); + final boolean compact = theArgs.argExists("compact"); + final boolean splitType = theArgs.argExists("type"); + final boolean splitInstance = theArgs.argExists("instance"); + final boolean splitHierarchy = theArgs.argExists("hierarchy"); + final boolean reuse = theArgs.argExists("force-reuse"); + final boolean directive = theArgs.argExists("directive"); + final String output = theArgs.getArgValue("output", null); + final int minSubtype = + getArgValue(theArgs.getArgValue("min-subtype", null), 0); + final int maxSubtype = + getArgValue(theArgs.getArgValue("max-subtype", null), + Integer.MAX_VALUE - 1); // workaround bug 5695 + if (cellName == null) { + System.err.println("ERROR: You must specify a cellname."); + usage(); + } else if (subtypePath == null) { + System.err.println("ERROR: You must specify a subtype output path."); + usage(); + } + + // Warn if zero or multiple functions are specified + int count = 0; + if (splitAll) ++count; + if (splitInstance) ++count; + if (splitType) ++count; + if (splitHierarchy) ++count; + if (reuse) ++count; + if (copyOnly) ++count; + if (compact) ++count; + if (directive) ++count; + if (count != 1) { + System.err.println("ERROR: You must specify exactly 1 function."); + usage(); + } + + final CastFileParser cfp = + new CastFileParser(new FileSearchPath(castRoot), castVersion, + new StandardParsingOption(theArgs)); + + Collection spec = null; + final MultiMap mmspec = new MultiMap(); + SubtypeOutput.Policy policy; + Collection> hierarchyInstances = null; + if (copyOnly) { + // kind of goofy + policy = new SubtypeOutput.Copy(subtypePath, + getHeader(cellName), + "" + minSubtype, + mmspec); + } else if (compact) { + final String skip = theArgs.getArgValue("compact-skip", null); + final Set skipSet; + if (skip == null) { + skipSet = Collections.EMPTY_SET; + } else { + skipSet = new HashSet(); + try { + final BufferedReader r = + new BufferedReader(new FileReader(skip)); + String line; + while ((line = r.readLine()) != null) { + skipSet.add(line); + } + } catch (IOException e) { + throw new RuntimeException("Cannot read compact skip file: " + skip, e); + } + } + final String range = theArgs.getArgValue("compact-range", null); + final int rangeLo, rangeHi; + if (range == null) { + rangeLo = 0; + rangeHi = Integer.MAX_VALUE; + } else { + String[] r = StringUtil.split(range, ':'); + try { + rangeLo = Integer.parseInt(r[0]); + rangeHi = Integer.parseInt(r[1]); + } catch (NumberFormatException e) { + throw new RuntimeException("Invalid compacting range: " + range, e); + } + } + final String[] paths; + final String compactPath = theArgs.getArgValue("compact-path", null); + if (compactPath == null) { + paths = new String[1]; + } else { + final String s[] = StringUtil.split(compactPath, ':'); + paths = new String[s.length + 1]; + System.arraycopy(s, 0, paths, 1, s.length); + } + paths[0] = subtypePath; + policy = new SubtypeOutput.Compact(paths, getHeader(cellName), + minSubtype, maxSubtype, mmspec, + skipSet, rangeLo, rangeHi); + } else if (reuse) { + final String normal = theArgs.getArgValue("reuse-spec", null); + final String pedantic = theArgs.getArgValue("pedantic-reuse-spec", null); + if (normal == null && pedantic == null) { + throw new RuntimeException("Reuse specification not specified"); + } + + final Map reuseMap = new HashMap(); + + if (normal != null) processReuseSpec(normal, false, reuseMap, cfp); + + if (pedantic != null) + processReuseSpec(pedantic, true, reuseMap, cfp); + + spec = new HashSet(); + policy = new SubtypeOutput.Reuse(subtypePath, getHeader(cellName), + reuseMap, spec); + } else if (splitAll) { + final boolean maximal = theArgs.argExists("maximal"); + final boolean splitArray = theArgs.argExists("split-array"); + policy = new SubtypeOutput.SplitAll(subtypePath, + getHeader(cellName), + minSubtype, maxSubtype, + Collections.EMPTY_SET, maximal, + splitArray, mmspec); + } else if (splitType) { + final Set splittable = new HashSet(); + for (StringContainerIterator types = + theArgs.nonParsedArgumentsIterator(); types.hasNext(); ) { + splittable.add(types.next()); + } + policy = new SubtypeOutput.SplitType(subtypePath, + getHeader(cellName), + minSubtype, maxSubtype, + splittable, mmspec); + } else if (splitInstance) { + final Set instances = new HashSet(); + for (StringContainerIterator instance = + theArgs.nonParsedArgumentsIterator(); instance.hasNext(); ) { + instances.add(instance.next()); + } + policy = new SubtypeOutput.SplitInstance(subtypePath, + getHeader(cellName), + minSubtype, maxSubtype, + instances, mmspec); + } else if (splitHierarchy) { + hierarchyInstances = new ArrayList>(); + final String replaceSpec = + theArgs.getArgValue("replace-spec", null); + if (replaceSpec == null) { + System.err.println("ERROR: replace specification missing"); + usage(); + } + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(replaceSpec)); + String line; + while ((line = br.readLine()) != null) { + if (line.startsWith("#")) continue; + final String[] words = StringUtil.split(line.trim(), ' '); + if (words.length != 2) { + System.err.println("WARNING: Invalid replace specification format: " + line); + continue; + } + final HierName hName; + try { + hName = HierName.makeHierName(words[1].trim(), '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Can't make HierName: " + + line, e); + } + hierarchyInstances.add( + new Pair(hName, words[0])); + } + } finally { + if (br != null) br.close(); + } + spec = new HashSet(); + policy = null; + } else if (directive) { + final boolean recursive = theArgs.argExists("recursive"); + final Map dirs = new HashMap(); + for (StringContainerIterator types = + theArgs.nonParsedArgumentsIterator(); types.hasNext(); ) { + final String dirspec = types.next(); + setDirective(dirs, dirspec); + } + policy = new SubtypeOutput.DirectiveTransform(subtypePath, + getHeader(cellName), + recursive, dirs); + } else { + policy = null; + System.err.println("ERROR: You must specify one of --all, --type or --instance."); + usage(); + } + + if (!pedanticArgs.pedanticOK(false, true)) { + System.err.println(pedanticArgs.pedanticString()); + usage(); + } + + final CellInterface cell = cfp.getFullyQualifiedCell(cellName); + + if (!CellUtils.isSubtype(cell)) { + System.err.println("ERROR: Cell " + cellName + " does not appear to be a subtype."); + usage(); + } + + if (splitHierarchy) { + final Collection errors = new ArrayList(); + policy = + new SubtypeOutput.SplitHierarchy( + subtypePath, getHeader(cellName), cell, + hierarchyInstances, minSubtype, maxSubtype, spec, + errors); + if (!errors.isEmpty()) { + System.err.println("ERROR: Some instances not found:"); + for (String error : errors) { + System.err.println(error); + } + System.exit(1); + } + } + + final Writer specWriter = + output == null ? null : new FileWriter(output); + SubtypeOutput.writeSubtype(policy, cell); + if (specWriter != null) { + if (spec == null) { + spec = convertSpec(mmspec); + } + final CDLNameInterface renamer = new CadenceNameInterface(); + for (Spec s : spec) { + specWriter.write(s.getSpec(renamer)); + specWriter.write('\n'); + } + specWriter.flush(); + specWriter.close(); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TechnologyData.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TechnologyData.java new file mode 100644 index 0000000000..f9c7c07d0e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TechnologyData.java @@ -0,0 +1,1763 @@ +/* + * Copyright 2002, 2003, 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.jauto; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgFormatException; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsIterator; +import com.avlsi.util.cmdlineargs.CommandLineArgsUtil; +import com.avlsi.util.cmdlineargs.InvalidCommandLineArgException; +import com.avlsi.util.cmdlineargs.MissingCommandLineArgException; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.ConfigFileListAdapter; +import com.avlsi.util.cmdlineargs.defimpl.TransformCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.UnionCommandLineArgs; + +import com.avlsi.util.container.FullTable; +import com.avlsi.util.container.LinearInterpolatable; +import com.avlsi.util.container.SparseTable; + +import com.avlsi.file.common.DeviceTypes; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class stores technical data related to targeting CMOS process. + **/ +public final class TechnologyData { + /** + * This class stores parameters associated with transistors. + **/ + public final class Transistor { + /** + * Cut-off length of stack of transistors. + **/ + //@ invariant stackLimitN > 0; + public final int stackLimitN; + + //@ invariant stackLimitP > 0; + public final int stackLimitP; + + /** + * Unit gate capacitance for n-transistors in F / m^2. + **/ + //@ invariant unitNmosGateCapacitance >= 0.0; + private final double unitNmosGateCapacitance; + + /** + * Unit gate capacitance for p-transistors in F / m^2. + **/ + //@ invariant unitPmosGateCapacitance >= 0.0; + private final double unitPmosGateCapacitance; + + /** + * Unit gate capacitance per unit transistor width for n-transistors + * in F / m. + **/ + //@ invariant unitNmosDiffusionCapacitance >= 0.0; + private final double unitNmosDiffusionCapacitance; + + /** + * Unit gate capacitance per unit transistor width for p-transistors + * in F / m. + **/ + //@ invariant unitPmosDiffusionCapacitance >= 0.0; + private final double unitPmosDiffusionCapacitance; + + /** + * Effective resistance factor of N-type transistor stack. + * N-type effective R = effectiveResistanceFactorN * gate_length / + * gate_width + *

    Entry [n] gives the effective R factor for stack of depth [n]. + **/ + //@ invariant effectiveResistanceFactorN != null; + //@ invariant effectiveResistanceFactorN.length == stackLimitN; + //@ invariant (\forall int i; + //@ 0 <= i && i < effectiveResistanceFactorN.length; + //@ effectiveResistanceFactorN[i] >= 0.0); + public final double[] effectiveResistanceFactorN; // in Ohm + + /** + * Effective resistance factor of P-type transistor stack. + * P-type effective R = effectiveResistanceFactorP * gate_length / + * gate_width + *

    Entry [n] gives the effective R factor for stack of depth [n]. + **/ + //@ invariant effectiveResistanceFactorP != null; + //@ invariant effectiveResistanceFactorP.length == stackLimitP; + //@ invariant (\forall int i; + //@ 0 <= i && i < effectiveResistanceFactorP.length; + //@ effectiveResistanceFactorP[i] >= 0.0); + public final double[] effectiveResistanceFactorP; // in Ohm + + /** + * Intrinsic delay for N-type transistor stack + **/ + //@ invariant gateIntrinsicDelayN != null; + //@ invariant gateIntrinsicDelayN.length == stackLimitN; + //@ invariant (\forall int i; + //@ 0 <= i && i < gateIntrinsicDelayN.length; + //@ gateIntrinsicDelayN[i] >= 0.0); + public final double[] gateIntrinsicDelayN; // in Second + + /** + * Intrinsic delay for P-type transistor stack + **/ + //@ invariant gateIntrinsicDelayP != null; + //@ invariant gateIntrinsicDelayP.length == stackLimitP; + //@ invariant (\forall int i; + //@ 0 <= i && i < gateIntrinsicDelayP.length; + //@ gateIntrinsicDelayP[i] >= 0.0); + public final double[] gateIntrinsicDelayP; // in Second + + /** + * Effective resistance of one off NMOS in series + */ + public final double leakageResistanceN; // in Ohm/square + + /** + * Effective resistance of one off PMOS in series + */ + public final double leakageResistanceP; // in Ohm/square + + /** + * Array of long channel transistors lengths. + **/ + public final double [] staticizerLengthN; // in meters + public final double [] staticizerLengthP; // in meters + + /** + * Array of long channel transistors strengths, relative to what + * simple W/L would predict. + **/ + public final double [] staticizerStrengthCorrectionN; + public final double [] staticizerStrengthCorrectionP; + + /** + *

    
    +         *   normal_behavior
    +         *     requires args != null;
    +         *     ensures unitNmosGateCapacitance >= 0.0;
    +         *     ensures unitPmosGateCapacitance >= 0.0;
    +         *     ensures unitNmosDiffusionCapacitance >= 0.0;
    +         *     ensures unitPmosDiffusionCapacitance >= 0.0;
    +         *     ensures stackLimitN > 0;
    +         *     ensures stackLimitP > 0;
    +         *     ensures effectiveResistanceFactorN != null;
    +         *     ensures effectiveResistanceFactorN.length == stackLimitN;
    +         *     ensures (\forall int i;
    +         *                      0 <= i &&
    +         *                          i < effectiveResistanceFactorN.length;
    +         *                      effectiveResistanceFactorN[i] >= 0.0);
    +         *     ensures effectiveResistanceFactorP != null;
    +         *     ensures effectiveResistanceFactorP.length == stackLimitP;
    +         *     ensures (\forall int i;
    +         *                      0 <= i &&
    +         *                          i < effectiveResistanceFactorP.length;
    +         *                      effectiveResistanceFactorP[i] >= 0.0);
    +         *     ensures gateIntrinsicDelayN != null;
    +         *     ensures gateIntrinsicDelayN.length == stackLimitN;
    +         *     ensures (\forall int i;
    +         *                      0 <= i && i < gateIntrinsicDelayN.length;
    +         *                      gateIntrinsicDelayN[i] >= 0.0);
    +         *     ensures gateIntrinsicDelayP != null;
    +         *     ensures gateIntrinsicDelayP.length == stackLimitP;
    +         *     ensures (\forall int i;
    +         *                      0 <= i && i < gateIntrinsicDelayP.length;
    +         *                      gateIntrinsicDelayP[i] >= 0.0);
    +         * 
    + **/ + public Transistor(final /*@ non_null @*/ CommandLineArgs args, + final int stackLimitN, + final int stackLimitP, + final String x) + throws CommandLineArgFormatException, + InvalidCommandLineArgException, + MissingCommandLineArgException { + + this.stackLimitN = stackLimitN; + this.stackLimitP = stackLimitP; + + // The option unitGateCapacitance will eventually be deprecated, + // but until then it will set both the unitNmosGateCapacitance + // and unitPmosGateCapacitance, but those values will take + // precedence. + if (args.argExists("unitGateCapacitance" + x)) { + if (args.argExists("unitNmosGateCapacitance" + x)) + throw new InvalidCommandLineArgException( + "Cannot specify both unitGateCapacitance " + x + + " and " + + "unitNmosGateCapacitance" + x, + "unitNmosGateCapacitance" + x, + args.getArgValue("unitNmosGateCapacitance" + x, + null)); + if (args.argExists("unitPmosGateCapacitance" + x)) + throw new InvalidCommandLineArgException( + "Cannot specify both unitGateCapacitance" + x + + " and " + + "unitPmosGateCapacitance" + x, + "unitPmosGateCapacitance" + x, + args.getArgValue("unitPmosGateCapacitance" + x, + null)); + + final double unitGateCapacitance = + CommandLineArgsUtil + .getRequiredNonNegativeDoubleArgValue(args, + "unitGateCapacitance" + x); + unitNmosGateCapacitance = unitGateCapacitance; + unitPmosGateCapacitance = unitGateCapacitance; + } else { + if (!args.argExists("unitNmosGateCapacitance" + x)) + throw new MissingCommandLineArgException( + "Must specify unitNmosGateCapacitance" + x + + " if " + + "unitGateCapacitance" + x + " is not specified", + "unitNmosGateCapacitance" + x); + if (!args.argExists("unitPmosGateCapacitance" + x)) + throw new MissingCommandLineArgException( + "Must specify unitPmosGateCapacitance" + x + + " if " + + "unitGateCapacitance" + x + " is not specified", + "unitPmosGateCapacitance" + x); + + unitNmosGateCapacitance = + CommandLineArgsUtil + .getRequiredNonNegativeDoubleArgValue(args, + "unitNmosGateCapacitance" + x); + unitPmosGateCapacitance = + CommandLineArgsUtil + .getRequiredNonNegativeDoubleArgValue(args, + "unitPmosGateCapacitance" + x); + } + + unitNmosDiffusionCapacitance = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "unitNmosDiffusionCapacitance" + x, 0.0); + unitPmosDiffusionCapacitance = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "unitPmosDiffusionCapacitance" + x, 0.0); + + effectiveResistanceFactorN = new double[stackLimitN]; + gateIntrinsicDelayN = new double[stackLimitN]; + + effectiveResistanceFactorP = new double[stackLimitP]; + gateIntrinsicDelayP = new double[stackLimitP]; + + for (int i = 0; i < stackLimitN; ++i) { + effectiveResistanceFactorN[i] = + CommandLineArgsUtil + .getRequiredNonNegativeDoubleArgValue(args, + "effectiveResistanceFactorN_" + i + x); + gateIntrinsicDelayN[i] = + CommandLineArgsUtil + .getRequiredNonNegativeDoubleArgValue(args, + "gateIntrinsicDelayN_" + i + x); + } + + for (int i = 0; i < stackLimitP; ++i) { + effectiveResistanceFactorP[i] = + CommandLineArgsUtil + .getRequiredNonNegativeDoubleArgValue(args, + "effectiveResistanceFactorP_" + i + x); + gateIntrinsicDelayP[i] = + CommandLineArgsUtil + .getRequiredNonNegativeDoubleArgValue(args, + "gateIntrinsicDelayP_" + i + x); + } + + leakageResistanceN = CommandLineArgsUtil. + getNonNegativeDoubleArgValue(args,"leakageResistanceN" + x, 0.0); + leakageResistanceP = CommandLineArgsUtil. + getNonNegativeDoubleArgValue(args,"leakageResistanceP" + x, 0.0); + + staticizerLengthN = CommandLineArgsUtil. + getDoubleArgList(args,"staticizerLengthN" + x); + staticizerLengthP = CommandLineArgsUtil. + getDoubleArgList(args,"staticizerLengthP" + x); + + staticizerStrengthCorrectionN = CommandLineArgsUtil. + getDoubleArgList(args,"staticizerStrengthCorrectionN" + x); + staticizerStrengthCorrectionP = CommandLineArgsUtil. + getDoubleArgList(args,"staticizerStrengthCorrectionP" + x); + + } + + //@ ensures \result >= 0.0; + public final double getUnitNmosGateCapacitance() + { + return unitNmosGateCapacitance; + } + + //@ ensures \result >= 0.0; + public final double getUnitPmosGateCapacitance() + { + return unitPmosGateCapacitance; + } + + //@ ensures \result >= 0.0; + public final double getUnitNmosDiffusionCapacitance() + { + return unitNmosDiffusionCapacitance; + } + + //@ ensures \result >= 0.0; + public final double getUnitPmosDiffusionCapacitance() + { + return unitPmosDiffusionCapacitance; + } + + public final double [] getEffectiveResistanceFactorN() + { + return effectiveResistanceFactorN; + } + + //@ requires 0 <= depth && depth < stackLimitN; + //@ ensures \result >= 0.0; + public final double getEffectiveResistanceFactorN(final int depth) + { + return effectiveResistanceFactorN[depth]; + } + + public final double [] getEffectiveResistanceFactorP() + { + return effectiveResistanceFactorP; + } + + //@ requires 0 <= depth && depth < stackLimitP; + //@ ensures \result >= 0.0; + public final double getEffectiveResistanceFactorP(final int depth) + { + return effectiveResistanceFactorP[depth]; + } + + public final double getLeakageResistanceN() + { + return leakageResistanceN; + } + + public final double getLeakageResistanceP() + { + return leakageResistanceP; + } + + public final double [] getGateIntrinsicDelayN() + { + return gateIntrinsicDelayN; + } + + //@ requires 0 <= depth && depth < stackLimitN; + //@ ensures \result >= 0.0; + public final double getGateIntrinsicDelayN(final int depth) + { + return gateIntrinsicDelayN[depth]; + } + + public final double [] getGateIntrinsicDelayP() + { + return gateIntrinsicDelayP; + } + + //@ requires 0 <= depth && depth < stackLimitP; + //@ ensures \result > 0.0; + public final double getGateIntrinsicDelayP(final int depth) + { + return gateIntrinsicDelayP[depth]; + } + + public final double[] getStaticizerLengthN() { + return staticizerLengthN; + } + + public final double[] getStaticizerLengthP() { + return staticizerLengthP; + } + + public final double[] getStaticizerStrengthCorrectionN() { + return staticizerStrengthCorrectionN; + } + + public final double[] getStaticizerStrengthCorrectionP() { + return staticizerStrengthCorrectionP; + } + + private String arrayString(final double[] array) { + String s = ""; + for (int i = 0; i < array.length; ++i) { + if (i > 0) s = s + ", "; + s = s + array[i]; + } + return s; + } + + public final String toString() { + return "unitNmosGateCapacitance: " + + getUnitNmosGateCapacitance() + "\n" + + "unitPmosGateCapacitance: " + + getUnitPmosGateCapacitance() + "\n" + + "unitNmosDiffusionCapacitance: " + + getUnitNmosDiffusionCapacitance() + "\n" + + "unitPmosDiffusionCapacitance: " + + getUnitPmosDiffusionCapacitance() + "\n" + + "effectiveResistanceFactorN: " + + arrayString(getEffectiveResistanceFactorN()) + "\n" + + "effectiveResistanceFactorP: " + + arrayString(getEffectiveResistanceFactorP()) + "\n" + + "leakageResistanceN: " + + getLeakageResistanceN() + "\n" + + "leakageResistanceP: " + + getLeakageResistanceP() + "\n" + + "gateIntrinsicDelayN: " + + arrayString(getGateIntrinsicDelayN()) + "\n" + + "gateIntrinsicDelayP: " + + arrayString(getGateIntrinsicDelayP()) + "\n" + + "staticizerLengthN: " + + arrayString(getStaticizerLengthN()) + "\n" + + "staticizerLengthP: " + + arrayString(getStaticizerLengthP()) + "\n" + + "staticizerStrengthCorrectionN: " + + arrayString(getStaticizerStrengthCorrectionN()) + "\n" + + "staticizerStrengthCorrectionP: " + + arrayString(getStaticizerStrengthCorrectionP()) + "\n"; + } + } + + /** + * Name of the technology. + * For example, "tsmc12hs_lowk", stands for TSMC 0.13u, high-speed (1.2V), low K technology. + **/ + //@ invariant technologyName != null; + private final /*@ non_null @*/ String technologyName; + + /** + * Unit wire capacitance for metal wires. + * Ca -> Area Capacitance + *

    Cf -> Fringe Capacitance + *

    Cc -> Coupling Capacitance + **/ + //@ invariant unitWireCapacitanceCa >= 0.0; + public double unitWireCapacitanceCa=0; // in F/Meter^2 + + /** + * Curve-fitting parameters for calculating Cf + Cc when wire space [S] varies. + * Cf+Cc = Cfc_2 / S / S + Cfc_1 / S + Cfc_0 + **/ + //@ invariant unitWireCapacitanceCfc_2 >= 0.0; + public double unitWireCapacitanceCfc_2=0; // in F*Meter + + //@ invariant unitWireCapacitanceCfc_1 >= 0.0; + public double unitWireCapacitanceCfc_1=0; // in Farad + + //@ invariant unitWireCapacitanceCfc_0 >= 0.0; + public double unitWireCapacitanceCfc_0=0; // in F/Meter + + // Capacitance scaling factor + /** + * User specified capacitance scaling factor for wires. + * The total wire capacitance becomes: + *

    C = L * (W * Ca + 2 * Cfc) * SF + *

    where L is the wire length, W is the wire width, + * SF is the "capacitanceScalingFactor". + **/ + //@ invariant capacitanceScalingFactor >= 0.0; + public final double capacitanceScalingFactor; + + /** + * Unit wire resistance parameter, for calculating wire resistance. + * Use typical data for M4 + **/ + //@ invariant unitWireResistance >= 0.0; + public double unitWireResistance=0; // in Ohm/sq + + /** + * Minimum transistor width allowed in the design flow. + **/ + //@ invariant minimumTransistorWidth >= 0.0; + public final double minimumTransistorWidth; // in Meter + + /** + * Minimum transistor length allowed in the design flow. + **/ + //@ invariant minimumTransistorLength >= 0.0; + public final double minimumTransistorLength; // in Meter + + /** + * Default average diffusion length of transistors, for calculating diffusion cap. + **/ + //@ invariant defaultDiffusionLength >= 0.0; + public final double defaultDiffusionLength; // in Meter + + /** + * Default gate length, usually equals the minimum feature size. + **/ + //@ invariant defaultGateLength >= 0.0; + public final double defaultGateLength; // in Meter + + /** + * Default width of metal wires. + **/ + //@ invariant defaultWireWidth >= 0.0; + public final double defaultWireWidth; // in Meter + + /** + * Default spacing between between metal wires. + **/ + //@ invariant defaultWireSpace >= 0.0; + public final double defaultWireSpace; // in Meter + + /** + * Default length of metal wire. + * It is used when estimated wire length is zero, + * which will happen when there is no input about circuit floorplan. + **/ + //@ invariant defaultWireLength >= 0.0; + public final double defaultWireLength; // in Meter + + /** + * The minimum allowed wire width in meters. Used for electromigration + * calculations. + **/ + //@ invariant minimumWireWidth >= 0.0; + public final double minimumWireWidth; + + /** + * Minimum length of metal wire, not enforced in the code. + **/ + //@ invariant minimumWireLength >= 0.0; + public final double minimumWireLength; // in Meter + + /** + * User specified layout scaling factor. + * After sizing, cell sizes will change comparing to the ones used for floorplan. + * These parameters help user to do next sizing run without redo the floorplan. + **/ + //@ invariant layoutScaleX >= 0.0; + public final double layoutScaleX; + + //@ invariant layoutScaleY >= 0.0; + public final double layoutScaleY; + + /** + * Default load capacitance to be added to the nets without fanout. + **/ + //@ invariant defaultLoadCapacitance >= 0.0; + public final double defaultLoadCapacitance; + + /** + * Specifies whether to use the intrinsic capacitance delay + * model, which gets its parameters from directives in the + * gates. + **/ + private final boolean useIntrinsicCap; + + /** + * Elmore delay discount factor, most people use 0.69. + * delay = R * C * elmoreDelayFactor + **/ + //@ invariant elmoreDelayFactor >= 0.0; + public final double elmoreDelayFactor; + + /** + * Wire RC delay discount factor. + * From my simulation, and better effect on sizing, 0.4 + **/ + //@ invariant wireRCDelayFactor >= 0.0; + public final double wireRCDelayFactor; + + /** + * Wire resistance shielding factor -> effective capacitance seen by the gate. + **/ + //@ invariant resistanceShieldingFactor >= 0.0; + public final double resistanceShieldingFactor; + + //@ invariant resistanceShieldingThreshold >= 0.0; + public final double resistanceShieldingThreshold; + + /** Staticizer parameters **/ + public final double minStaticizerRatio; // min staticizer G / logic G + public final double maxStaticizerRatio; // max staticizer G / logic G + public final double minCombinationalStaticizerRatio; + public final double maxCombinationalStaticizerRatio; + public final double staticizerLeakageRatio; // min staticizer G / leakage G + public final double staticizerWidthGrid; // round width of staticizers + public final int staticizerMaxDepthN; // max NMOS_CHAIN for weak staticizer + public final int staticizerMaxDepthP; // max NMOS_CHAIN for weak staticizer + + /** + * Conversion factor from delay to slew time, unitless. + * slew_time = delay * delayToSlewTimeConversionFactor. + * Used for electromigration calculations. + **/ + //@ invariant delayToSlewTimeConversionFactor >= 0.0; + private final double delayToSlewTimeConversionFactor; + + /** + * Nominal cycle time for the process, in seconds. + * Used for electromigration calculations. + **/ + //@ invariant cycleTime >= 0.0; + private final double cycleTime; + + /** + * Process voltage, in volts. + * Used for electromigration calculations. + **/ + //@ invariant voltage >= 0.0; + private final double voltage; + + /** + * Current limit per contact, in Amps / via. + * Used for electromigration calculations. + **/ + //@ invariant viaAvgCurrentLimit >= 0.0; + private final double viaAvgCurrentLimit; + + /** + * Current limit per width of M1, in Amps / meter. + * Used for electromigration calculations. + **/ + //@ invariant wireAvgCurrentLimit >= 0.0; + private final double wireAvgCurrentLimit; + + /** + * Root-mean-square current limit per width of M2, in Amps / meter. + * Used for electromigration calculations. + **/ + //@ invariant wireRMSCurrentLimit >= 0.0; + private final double wireRMSCurrentLimit; + + /** + * Peak current limit per width of M1, in Amps / meter. + * Used for electromigration calculations. + **/ + //@ invariant wirePeakCurrentLimit >= 0.0; + private final double wirePeakCurrentLimit; + + /** + * Multiplier to the average current limits to + * account for a temperature other than the temperature + * for which viaAvgCurrentLimit and + * wireAvgCurrentLimit were computed, unitless. + * Used for electromigration calculations. + **/ + //@ invariant avgCurrentLimitTempCorrectionFactor >= 0.0; + private final double avgCurrentLimitTempCorrectionFactor; + + /** + * Maximum depth of transistor stacks + **/ + //@ invariant stackLimitN > 0; + public final int stackLimitN; + + //@ invariant stackLimitP > 0; + public final int stackLimitP; + + /** + * Warn about deep stacks + **/ + //@ invariant stackWarnLimitN > 0; + public final int stackWarnLimitN; + + //@ invariant stackWarnLimitP > 0; + public final int stackWarnLimitP; + + /** + * The ratio of the precharge transistor strength to logic strength. + **/ + //@ invariant prechargeRatio > 0; + public final double prechargeRatio; + + /** + * If a precharge transistor is longer than the specified length, a warning + * is emitted + **/ + //@ invariant maximumPrechargeTransistorLength > 0; + public final double maximumPrechargeTransistorLength; + + /** + * The load associated with the precharge transistor. + **/ + //@ invariant prechargeTransistorLoad > 0; + public final double prechargeTransistorLoad; + + /** + * A table used to interpolate unit resistance from wire width and wire + * spacing. + **/ + public LinearInterpolatable wireResistanceTable = null; + + /** + * A table used to interpolate unit capacitance from wire width and wire + * spacing. + **/ + public LinearInterpolatable wireCapacitanceTable = null; + + /** + * Maximum number of transistor types supported. + **/ + public static final int MAX_TRANSISTOR_TYPES = 256; + + /** + * A default transistor type, for backward compatibility. It is only used + * when the --transistorTypes argument is not specified. + **/ + private static final int DEFAULT_TRANSISTOR_TYPE = 1; + public final static int NO_TRANSISTOR_TYPE = 0; + public final static int MIXED_TRANSISTOR_TYPE = -1; + + /** + * An array of transistor parameters. The index is the transistor type. + **/ + private final Transistor[] transistorParameters = + new Transistor[MAX_TRANSISTOR_TYPES]; + + /** + * True if parameters for multiple transistor types are given, and false + * otherwise. + **/ + private final boolean hasMultipleTransistors; + + /** + * Various overhead associated with layout, in m. + **/ + //@ invariant transistorWidthOverhead >= 0.0; + public final double transistorWidthOverhead; + //@ invariant transistorLengthOverhead >= 0.0; + public final double transistorLengthOverhead; + + /** + * Coefficients used to account for possible rounding effects of transistor + * widths on gate and diffusion capacitance. widthRoundingOffset in m. + **/ + private final double widthRoundingSlope; + private final double widthRoundingOffset; + + /** + * Array of legal transistor widths. + **/ + private final double [] widths; // in meters + + /** + * Wirelength of an internal net in a leaf cell is: + * perimeter of container * leafWireLengthScale + **/ + private final double leafWireLengthScale; + + /** + * Wirelength contribution of a port net in a leaf cell is: + * perimeter of container * leafWireLengthPortScale + **/ + private final double leafWireLengthPortScale; + + /** + * Class constructor. The following arguments are required: + *

      + *
    • technologyName: string
    • + *
    • minimumTransistorWidth: floating point
    • + *
    • minimumTransistorLength: floating point
    • + *
    • defaultGateLength: floating point
    • + *
    • defaultDiffusionLength: floating point
    • + *
    • defaultLoadCapacitance: floating point
    • + *
    • defaultWireWidth: floating point
    • + *
    • defaultWireLength: floating point
    • + *
    • defaultWireSpace: floating point
    • + *
    • minimumWireWidth: floating point
    • + *
    • minimumWireLength: floating point
    • + *
    • stackLimitN: floating point
    • + *
    • stackLimitP: floating point
    • + *
    • effectiveResistanceFactorN_k: floating point, + * required for values of k up to + * stackLimitN - 1
    • + *
    • effectiveResistanceFactorP_k: floating point, + * required for values of k up to + * stackLimitP - 1
    • + *
    • gateIntrinsicDelayN_k: floating point, + * required for values of k up to + * stackLimitN - 1
    • + *
    • gateIntrinsicDelayP_k: floating point, + * required for values of k up to + * stackLimitP - 1
    • + *
    • elmoreDelayFactor: floating point
    • + *
    • wireRCDelayFactor: floating point
    • + *
    • resistanceShieldingFactor: floating point
    • + *
    • resistanceShieldingThreshold: floating point
    • + *
    • delayToSlewTimeConversionFactor: + * floating point
    • + *
    • cycleTime: floating point
    • + *
    • voltage: floating point
    • + *
    • viaAvgCurrentLimit: floating point
    • + *
    • wireAvgCurrentLimit: floating point
    • + *
    • wireRMSCurrentLimit: floating point
    • + *
    • wirePeakCurrentLimit: floating point
    • + *
    • avgCurrentLimitTempCorrectionFactor: + * floating point
    • + *
    + * + * Specify wire capacitance with either: + *
      + *
    • unitWireCapacitanceCa: floating point
    • + *
    • unitWireCapacitanceCfc_0: floating point
    • + *
    • unitWireCapacitanceCfc_1: floating point
    • + *
    • unitWireCapacitanceCfc_2: floating point
    • + *
    + * Or a bi-linear interpolated lookup table: + *
      + *
    • wireCapacitance(Width,Space): floating point table
    • + *
    + * + * Specify wire resistance with either: + *
      + *
    • unitWireResistance: floating point
    • + *
    + * Or a bi-linear interpolated lookup table: + *
      + *
    • wireResistance(Width,Space): floating point table
    • + *
    + * + *

    Furthermore, either unitGateCapacitance or both + * unitNmosGateCapacitance and + * unitPmosGateCapacitance must be specified. The use of + * unitGateCapacitance is discouraged and will soon be + * illegal.

    + * + *

    The following arguments are optional, and default values will be + * supplied if they are not specified: + *

      + *
    • unitNmosDiffusionCapacitance: floating point, + * default 0.0
    • + *
    • unitPmosDiffusionCapacitance: floating point, + * default 0.0
    • + *
    • capacitanceScalingFactor: floating point, + * default 1.0
    • + *
    • layoutScaleX: floating point, default 1.0
    • + *
    • layoutScaleY: floating point, default 1.0
    • + *
    • useIntrinsicCap: only the presence or absence + * of this option matters, not the value
    • + *
    • prechargeRatio: floating point, default 0.1
    • + *

    + * + * @param args + * The command line arguments to use to construct the instance. + * + * @throws CommandLineArgs + * If an argument value is not of the correct format. + * @throws InvalidCommandLineArgException + * If an argument value is of the correct format, but + * out of the required range. + * @throws MissingCommandLineArgException + * If a required argument is not supplied. + * + *
    
    +     *   normal_behavior
    +     *     requires args != null;
    +     *     ensures technologyName != null;
    +     *     ensures unitWireCapacitanceCa >= 0.0;
    +     *     ensures unitWireCapacitanceCfc_0 >= 0.0;
    +     *     ensures unitWireCapacitanceCfc_1 >= 0.0;
    +     *     ensures unitWireCapacitanceCfc_2 >= 0.0;
    +     *     ensures capacitanceScalingFactor >= 0.0;
    +     *     ensures unitWireResistance >= 0.0;
    +     *     ensures minimumTransistorWidth >= 0.0;
    +     *     ensures minimumTransistorLen >= 0.0;
    +     *     ensures defaultGateLength >= 0.0;
    +     *     ensures defaultDiffusionLength >= 0.0;
    +     *     ensures defaultLoadCapacitance >= 0.0;
    +     *     ensures defaultWireWidth >= 0.0;
    +     *     ensures defaultWireLength >= 0.0;
    +     *     ensures defaultWireSpace >= 0.0;
    +     *     ensures minimumWireWidth >= 0.0;
    +     *     ensures minimumWireLength >= 0.0;
    +     *     ensures layoutScaleX >= 0.0;
    +     *     ensures layoutScaleY >= 0.0;
    +     *     ensures stackLimitN > 0;
    +     *     ensures stackLimitP > 0;
    +     *     ensures elmoreDelayFactor >= 0.0;
    +     *     ensures wireRCDelayFactor >= 0.0;
    +     *     ensures resistanceShieldingFactor >= 0.0;
    +     *     ensures resistanceShieldingThreshold >= 0.0;
    +     *     ensures delayToSlewTimeConversionFactor >= 0.0;
    +     *     ensures cycleTime >= 0.0;
    +     *     ensures voltage >= 0.0;
    +     *     ensures viaAvgCurrentLimit >= 0.0;
    +     *     ensures wireAvgCurrentLimit >= 0.0;
    +     *     ensures wireRMSCurrentLimit >= 0.0;
    +     *     ensures wirePeakCurrentLimit >= 0.0;
    +     *     ensures avgCurrentLimitTempCorrectionFactor >= 0.0;
    +     *     ensures prechargeRatio > 0.0;
    +     *     ensures maximumPrechargeTransistorLength > 0.0;
    +     *     ensures prechargeTransistorLoad >= 0.0;
    +     *     ensures transistorWidthOverhead >= 0.0;
    +     *     ensures transistorLengthOverhead >= 0.0;
    +     * 
    + **/ + public TechnologyData(final /*@ non_null @*/ CommandLineArgs args) + throws CommandLineArgFormatException, + InvalidCommandLineArgException, + MissingCommandLineArgException { + + technologyName = + CommandLineArgsUtil.getRequiredArgValue(args, "technologyName"); + + // table based estimation of wire capacitance and resistance + final Pattern wireResistanceRegex = Pattern.compile( + "(wireResistance)\\((.+),(.+)\\)"); + final Pattern wireCapacitanceRegex = Pattern.compile( + "(wireCapacitance)\\((.+),(.+)\\)"); + + SparseTable sparseResistance = null; + SparseTable sparseCapacitance = null; + for (CommandLineArgsIterator i = args.iterator(); i.hasNext(); ) { + final CommandLineArg arg = i.next(); + final String name = arg.getName(); + SparseTable table = null; + Matcher m = null; + if ((m = wireResistanceRegex.matcher(name)).matches()) { + if (sparseResistance == null) + sparseResistance = new SparseTable(); + table = sparseResistance; + } else if ((m = wireCapacitanceRegex.matcher(name)).matches()) { + if (sparseCapacitance == null) + sparseCapacitance = new SparseTable(); + table = sparseCapacitance; + } + if (table != null) { + final double width = + getPositiveDoubleValue(m.group(1), m.group(2)); + final double space = + getPositiveDoubleValue(m.group(1), m.group(3)); + final double val = + getPositiveDoubleValue(m.group(1), arg.getValue()); + table.putEntry(width, space, val); + } + } + + try { + if (sparseResistance != null) + wireResistanceTable = new FullTable(sparseResistance); + } catch (FullTable.IncompleteException e) { + throw new MissingCommandLineArgException( + "wireResistance table incomplete: " + e.getMessage(), + "wireResistance"); + } + + try { + if (sparseCapacitance != null) + wireCapacitanceTable = new FullTable(sparseCapacitance); + } catch (FullTable.IncompleteException e) { + throw new MissingCommandLineArgException( + "wireCapacitance table incomplete: " + e.getMessage(), + "wireCapacitance"); + } + + capacitanceScalingFactor = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "capacitanceScalingFactor", 1.0); + + if (wireCapacitanceTable==null) { + unitWireCapacitanceCa = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue + (args,"unitWireCapacitanceCa"); + unitWireCapacitanceCfc_0 = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue + (args,"unitWireCapacitanceCfc_0"); + unitWireCapacitanceCfc_1 = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue + (args,"unitWireCapacitanceCfc_1"); + unitWireCapacitanceCfc_2 = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue + (args,"unitWireCapacitanceCfc_2"); + } else if (args.argExists("unitWireCapacitanceCa") || + args.argExists("unitWireCapacitanceCfc_0") || + args.argExists("unitWireCapacitanceCfc_1") || + args.argExists("unitWireCapacitanceCfc_2")) + throw new InvalidCommandLineArgException + ("Cannot specify both wireCapacitance and unitWireCapacitance*",null); + + if (wireResistanceTable==null) + unitWireResistance = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue + (args,"unitWireResistance"); + else if (args.argExists("unitWireResistance")) + throw new InvalidCommandLineArgException + ("Cannot specify both wireResistance and unitWireResistance",null); + + minimumTransistorWidth = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "minimumTransistorWidth"); + minimumTransistorLength = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "minimumTransistorLength"); + defaultGateLength = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "defaultGateLength"); + defaultDiffusionLength = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "defaultDiffusionLength"); + defaultLoadCapacitance = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "defaultLoadCapacitance"); + + defaultWireWidth = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "defaultWireWidth"); + defaultWireSpace = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "defaultWireSpace"); + defaultWireLength = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "defaultWireLength"); + minimumWireWidth = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "minimumWireWidth"); + minimumWireLength = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "minimumWireLength"); + + layoutScaleX = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "layoutScaleX", 1.0); + layoutScaleY = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "layoutScaleY", 1.0); + + useIntrinsicCap = args.argExists("useIntrinsicCap"); + + stackLimitN = + CommandLineArgsUtil.getRequiredNonNegativeIntegerArgValue(args, + "stackLimitN"); + stackLimitP = + CommandLineArgsUtil.getRequiredNonNegativeIntegerArgValue(args, + "stackLimitP"); + + stackWarnLimitN = + CommandLineArgsUtil.getNonNegativeIntegerArgValue(args, + "stackWarnLimitN", stackLimitN); + stackWarnLimitP = + CommandLineArgsUtil.getNonNegativeIntegerArgValue(args, + "stackWarnLimitP", stackLimitP); + + hasMultipleTransistors = args.argExists("transistorTypes"); + + if (hasMultipleTransistors) { + final String arg = "transistorTypes"; + final String val = args.getArgValue(arg, ""); + final int[] types = CommandLineArgsUtil.getIntArgList(args, arg); + for (int i = 0; i < types.length; ++i) { + if (types[i] <= 0 || types[i] > MAX_TRANSISTOR_TYPES - 1) { + throw new InvalidCommandLineArgException( + "Valid transistor types are in the " + + "range from 1.." + (MAX_TRANSISTOR_TYPES - 1), + arg, val); + } else { + transistorParameters[types[i]] = + new Transistor(args, stackLimitN, stackLimitP, + "[" + types[i] + "]"); + } + } + } else { + transistorParameters[DEFAULT_TRANSISTOR_TYPE] = + new Transistor(args, stackLimitN, stackLimitP, ""); + } + + elmoreDelayFactor = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "elmoreDelayFactor"); + wireRCDelayFactor = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "wireRCDelayFactor"); + resistanceShieldingFactor = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "resistanceShieldingFactor"); + resistanceShieldingThreshold = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "resistanceShieldingThreshold"); + + minStaticizerRatio = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "minStaticizerRatio"); + maxStaticizerRatio = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "maxStaticizerRatio"); + minCombinationalStaticizerRatio = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "minCombinationalStaticizerRatio"); + maxCombinationalStaticizerRatio = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "maxCombinationalStaticizerRatio"); + staticizerLeakageRatio = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "staticizerLeakageRatio"); + staticizerWidthGrid = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "staticizerWidthGrid"); + staticizerMaxDepthN = + CommandLineArgsUtil.getRequiredNonNegativeIntegerArgValue(args, + "staticizerMaxDepthN"); + staticizerMaxDepthP = + CommandLineArgsUtil.getRequiredNonNegativeIntegerArgValue(args, + "staticizerMaxDepthP"); + + delayToSlewTimeConversionFactor = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "delayToSlewTimeConversionFactor"); + cycleTime = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "cycleTime"); + voltage = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "voltage"); + viaAvgCurrentLimit = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "viaAvgCurrentLimit"); + wireAvgCurrentLimit = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "wireAvgCurrentLimit"); + wireRMSCurrentLimit = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "wireRMSCurrentLimit"); + wirePeakCurrentLimit = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "wirePeakCurrentLimit"); + avgCurrentLimitTempCorrectionFactor = + CommandLineArgsUtil.getRequiredNonNegativeDoubleArgValue(args, + "avgCurrentLimitTempCorrectionFactor"); + prechargeRatio = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "prechargeRatio", 0.1); + maximumPrechargeTransistorLength = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "maximumPrechargeTransistorLength", 6.5e-7); + prechargeTransistorLoad = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "prechargeTransistorLoad", 1.118e-15); + + transistorWidthOverhead = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "transistorWidthOverhead", 0); + transistorLengthOverhead = + CommandLineArgsUtil.getNonNegativeDoubleArgValue(args, + "transistorLengthOverhead", 0); + widthRoundingSlope = + CommandLineArgsUtil.getDoubleArgValue(args, + "widthRoundingSlope", 1.0); + widthRoundingOffset = + CommandLineArgsUtil.getDoubleArgValue(args, + "widthRoundingOffset", 0.0); + widths = + CommandLineArgsUtil.getDoubleArgList(args, "widths"); + Arrays.sort(widths); + + leafWireLengthScale = + CommandLineArgsUtil.getDoubleArgValue(args, + "leafWireLengthScale", 0.5); + leafWireLengthPortScale = + CommandLineArgsUtil.getDoubleArgValue(args, + "leafWireLengthPortScale", 0.25); + } + + public final /*@ non_null @*/ String getTechnologyName() + { + return technologyName; + } + + + //@ ensures \result >= 0.0; + public final double getUnitNmosGateCapacitance(final int type) + { + return getTransistorParameter(type).getUnitNmosGateCapacitance(); + } + + //@ ensures \result >= 0.0; + public final double getUnitPmosGateCapacitance(final int type) + { + return getTransistorParameter(type).getUnitPmosGateCapacitance(); + } + + //@ ensures \result >= 0.0; + public final double getUnitGateCapacitance(final int type, final int ttype) + { + return type == DeviceTypes.N_TYPE ? getUnitNmosGateCapacitance(ttype) + : getUnitPmosGateCapacitance(ttype); + } + + //@ ensures \result >= 0.0; + public final double getUnitNmosDiffusionCapacitance(final int type) + { + return getTransistorParameter(type).getUnitNmosDiffusionCapacitance(); + } + + //@ ensures \result >= 0.0; + public final double getUnitPmosDiffusionCapacitance(final int type) + { + return getTransistorParameter(type).getUnitPmosDiffusionCapacitance(); + } + + //@ ensures \result >= 0.0; + public final double getUnitDiffusionCapacitance(final int type, + final int ttype) + { + return + type == DeviceTypes.N_TYPE ? getUnitNmosDiffusionCapacitance(ttype) + : getUnitPmosDiffusionCapacitance(ttype); + } + + + //@ ensures \result >= 0.0; + public final double getUnitWireCapacitanceCa() + { + return unitWireCapacitanceCa; + } + + + //@ ensures \result >= 0.0; + public final double getUnitWireCapacitanceCfc_2() + { + return unitWireCapacitanceCfc_2; + } + + + //@ ensures \result >= 0.0; + public final double getUnitWireCapacitanceCfc_1() + { + return unitWireCapacitanceCfc_1; + } + + + //@ ensures \result >= 0.0; + public final double getUnitWireCapacitanceCfc_0() + { + return unitWireCapacitanceCfc_0; + } + + + //@ ensures \result >= 0.0; + public final double getCapacitanceScalingFactor() + { + return capacitanceScalingFactor; + } + + + //@ ensures \result >= 0.0; + public final double getUnitWireResistance() + { + return unitWireResistance; + } + + + //@ ensures \result >= 0.0; + public final double getMinimumTransistorWidth() + { + return minimumTransistorWidth; + } + + + //@ ensures \result >= 0.0; + public final double getMinimumTransistorLength() + { + return minimumTransistorLength; + } + + + //@ ensures \result >= 0.0; + public final double getDefaultGateLength() + { + return defaultGateLength; + } + + + //@ ensures \result >= 0.0; + public final double getDefaultDiffusionLength() + { + return defaultDiffusionLength; + } + + + //@ ensures \result >= 0.0; + public final double getDefaultLoadCapacitance() + { + return defaultLoadCapacitance; + } + + + //@ ensures \result >= 0.0; + public final double getDefaultWireWidth() + { + return defaultWireWidth; + } + + + //@ ensures \result >= 0.0; + public final double getDefaultWireSpace() + { + return defaultWireSpace; + } + + + //@ ensures \result >= 0.0; + public final double getDefaultWireLength() + { + return defaultWireLength; + } + + + //@ ensures \result >= 0.0; + public final double getMinimumWireLength() + { + return minimumWireLength; + } + + + /** + * Returns the minimum allowed wire width. Used for electromigration + * calculations. + **/ + //@ ensures \result >= 0.0; + public final double getMinimumWireWidth() { + return minimumWireWidth; + } + + + //@ ensures \result >= 0.0; + public final double getLayoutScaleX() + { + return layoutScaleX; + } + + + //@ ensures \result >= 0.0; + public final double getLayoutScaleY() + { + return layoutScaleY; + } + + + /** + * Returns whether the intrinsic capacitance delay model is being used. + * + * @return Whether to use intrinsic capacitance. + **/ + public boolean getUseIntrinsicCap() { + return useIntrinsicCap; + } + + + public final double [] getEffectiveResistanceFactorN(final int type) + { + return getTransistorParameter(type).getEffectiveResistanceFactorN(); + } + + //@ requires 0 <= depth && depth < stackLimitN; + //@ ensures \result >= 0.0; + public final double getEffectiveResistanceFactorN(final int type, + final int depth) + { + return getTransistorParameter(type).getEffectiveResistanceFactorN(depth); + } + + public final double [] getEffectiveResistanceFactorP(final int type) + { + return getTransistorParameter(type).getEffectiveResistanceFactorP(); + } + + //@ requires 0 <= depth && depth < stackLimitP; + //@ ensures \result >= 0.0; + public final double getEffectiveResistanceFactorP(final int type, + final int depth) + { + return getTransistorParameter(type).getEffectiveResistanceFactorP(depth); + } + + //@ ensures \result >= 0.0; + public final double getLeakageResistanceN(final int type) + { + return getTransistorParameter(type).getLeakageResistanceN(); + } + + //@ ensures \result >= 0.0; + public final double getLeakageResistanceP(final int type) + { + return getTransistorParameter(type).getLeakageResistanceP(); + } + + public final double [] getGateIntrinsicDelayN(final int type) + { + return getTransistorParameter(type).getGateIntrinsicDelayN(); + } + + //@ requires 0 <= depth && depth < stackLimitN; + //@ ensures \result >= 0.0; + public final double getGateIntrinsicDelayN(final int type, final int depth) + { + return getTransistorParameter(type).getGateIntrinsicDelayN(depth); + } + + public final double [] getGateIntrinsicDelayP(final int type) + { + return getTransistorParameter(type).getGateIntrinsicDelayP(); + } + + //@ requires 0 <= depth && depth < stackLimitP; + //@ ensures \result > 0.0; + public final double getGateIntrinsicDelayP(final int type, final int depth) + { + return getTransistorParameter(type).getGateIntrinsicDelayP(depth); + } + + + //@ ensures \result > 0.0; + public final int getStackLimitN() + { + return stackLimitN; + } + + + //@ ensures \result >= 0.0; + public final int getStackLimitP() + { + return stackLimitP; + } + + + //@ ensures \result >= 0.0; + public final double getElmoreDelayFactor() + { + return elmoreDelayFactor; + } + + + //@ ensures \result >= 0.0; + public final double getWireRCDelayFactor() + { + return wireRCDelayFactor; + } + + + //@ ensures \result >= 0.0; + public final double getResistanceShieldingFactor() + { + return resistanceShieldingFactor; + } + + + //@ ensures \result >= 0.0; + public final double getResistanceShieldingThreshold() + { + return resistanceShieldingThreshold; + } + + public final double getMinStaticizerRatio() + { + return minStaticizerRatio; + } + + public final double getMaxStaticizerRatio() + { + return maxStaticizerRatio; + } + + public final double getMinCombinationalStaticizerRatio() + { + return minCombinationalStaticizerRatio; + } + + public final double getMaxCombinationalStaticizerRatio() + { + return maxCombinationalStaticizerRatio; + } + + public final double getStaticizerLeakageRatio() + { + return staticizerLeakageRatio; + } + + public final double getStaticizerWidthGrid() + { + return staticizerWidthGrid; + } + + public final int getStaticizerMaxDepthN() + { + return staticizerMaxDepthN; + } + + public final int getStaticizerMaxDepthP() + { + return staticizerMaxDepthP; + } + + /** + * Returns the conversion factor from delay to slew time. + * slew_time = delay * delayToSlewTimeConversionFactor. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getDelayToSlewTimeConversionFactor() { + return delayToSlewTimeConversionFactor; + } + + /** + * Returns the nominal cycle time for the process. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getCycleTime() { + return cycleTime; + } + + /** + * Returns the process voltage. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getVoltage() { + return voltage; + } + + /** + * Returns the current limit per contact. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getViaAvgCurrentLimit() { + return viaAvgCurrentLimit; + } + + /** + * Returns the current limit per width of M1. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getWireAvgCurrentLimit() { + return wireAvgCurrentLimit; + } + + /** + * Returns the root-mean-square current limit per width of M2. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getWireRMSCurrentLimit() { + return wireRMSCurrentLimit; + } + + /** + * Returns the peak current limit per width of M1. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getWirePeakCurrentLimit() { + return wirePeakCurrentLimit; + } + + /** + * Returns the multiplier to the average current limits to + * account for a temperature other than the temperature + * for which viaAvgCurrentLimit and + * wireAvgCurrentLimit were computed. + * Used for electromigration calculations. + **/ + //@ ensures \result >= 0.0; + public final double getAvgCurrentLimitTempCorrectionFactor() { + return avgCurrentLimitTempCorrectionFactor; + } + + /** + * Returns the ratio of the precharge transistor strength to the logic + * strength. + **/ + //@ ensures \result > 0.0; + public final double getPrechargeRatio() { + return prechargeRatio; + } + + /** + * Return the longest length of the precharge transistor before a warning + * is emitted. + **/ + //@ ensures \result >= 0.0; + public final double getMaximumPrechargeTransistorLength() { + return maximumPrechargeTransistorLength; + } + + /** + * The load associated with the precharge transistor. + **/ + //@ ensures \result >= 0.0; + public final double getPrechargeTransistorLoad() { + return prechargeTransistorLoad; + } + + public final double[] getStaticizerLengthN(final int type) { + return getTransistorParameter(type).getStaticizerLengthN(); + } + + public final double[] getStaticizerLengthP(final int type) { + return getTransistorParameter(type).getStaticizerLengthP(); + } + + public final double[] getStaticizerStrengthCorrectionN(final int type) { + return getTransistorParameter(type).getStaticizerStrengthCorrectionN(); + } + + public final double[] getStaticizerStrengthCorrectionP(final int type) { + return getTransistorParameter(type).getStaticizerStrengthCorrectionP(); + } + + public final double getWidthRoundingSlope() { + return widthRoundingSlope; + } + + public final double getWidthRoundingOffset() { + return widthRoundingOffset; + } + + public final double getLeafWireLengthScale() { + return leafWireLengthScale; + } + + public final double getLeafWireLengthPortScale() { + return leafWireLengthPortScale; + } + + /** + * Returns an array of legal transistor widths, in sorted order. + **/ + public final double[] getWidths() { + return widths; + } + + public final LinearInterpolatable getWireResistanceTable() { + return wireResistanceTable; + } + + public final LinearInterpolatable getWireCapacitanceTable() { + return wireCapacitanceTable; + } + + private double getPositiveDoubleValue(final String arg, final String value) + throws CommandLineArgFormatException, + InvalidCommandLineArgException, + MissingCommandLineArgException { + if (value == null) { + throw new MissingCommandLineArgException(arg); + } else { + double result; + try { + result = Double.parseDouble(value); + } catch (NumberFormatException e) { + throw new CommandLineArgFormatException(arg, value, e); + } + if (result <= 0) { + throw new InvalidCommandLineArgException(arg + + " must be positive, has value " + value, + arg, value); + } + return result; + } + } + + public class InvalidTransistorTypeException extends RuntimeException { + private final int type; + public InvalidTransistorTypeException(final int type) { + this.type = type; + } + public int getType() { + return type; + } + } + + public class MixedTransistorTypeException extends RuntimeException { + public MixedTransistorTypeException() { } + } + + private final Transistor getTransistorParameter(int type) { + // if no additional transistor types are specified, always use the + // default transistor type even if the the transistor type encoded in + // the netlist is different; this is the backwards compatible behavior + if (!hasMultipleTransistors) type = DEFAULT_TRANSISTOR_TYPE; + + if (type == MIXED_TRANSISTOR_TYPE) + throw new MixedTransistorTypeException(); + else { + try { + final Transistor result = transistorParameters[type]; + if (result == null) + throw new InvalidTransistorTypeException(type); + return result; + } catch (ArrayIndexOutOfBoundsException e) { + throw new InvalidTransistorTypeException(type); + } + } + } + + /** Name of the standard PDK root argument. **/ + private static final String PDK_ARG_NAME = "fulcrum-pdk-root"; + + /** Name of the standard PDK root environment variable. **/ + private static final String PDK_ENV_NAME = "FULCRUM_PDK_ROOT"; + + /** + * Returns a TechnologyData, using --fulcrum-pdk-root and FULCRUM_PDK_ROOT + * to get the PDK location. If specified, expand --fulcrum-pdk-root=dir in + * place to --config=dir/share/Fulcrum/jauto/process.config; otherwise, if + * the environment variable FULCRUM_PDK_ROOT=dir exists, expand it to + * --config=dir/share/Fulcrum/jauto/process.config as if it were at the + * beginning of the commandline. + **/ + public static TechnologyData getTechnologyData(final CommandLineArgs args) + throws CommandLineArgFormatException, + InvalidCommandLineArgException, + MissingCommandLineArgException { + try { + return new TechnologyData(args); + } catch (MissingCommandLineArgException e) { + final String cmdRoot = args.getArgValue(PDK_ARG_NAME, null); + if (cmdRoot != null) { + final CommandLineArgs substArgs = + new TransformCommandLineArgs(args) { + protected CommandLineArg[] transform( + CommandLineArg arg) { + if (arg.getName().equals(PDK_ARG_NAME)) { + arg = new CommandLineArgDefImpl( + "config", + getProcessConfig(cmdRoot)); + } + return new CommandLineArg[] { arg }; + } + }; + return new TechnologyData( + new CachingCommandLineArgs( + new CommandLineArgsWithConfigFiles(substArgs))); + } + + final String envRoot = System.getenv(PDK_ENV_NAME); + if (envRoot != null) { + return new TechnologyData( + new CachingCommandLineArgs( + new UnionCommandLineArgs( + new CommandLineArgsWithConfigFiles( + new ConfigFileListAdapter( + getProcessConfig(envRoot))), + args))); + } + + throw e; + } + } + + private static String getProcessConfig(final String pdkRoot) { + return pdkRoot + "/share/Fulcrum/jauto/process.config"; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Transistor.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Transistor.java new file mode 100644 index 0000000000..f71bbafb9b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/Transistor.java @@ -0,0 +1,105 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + /* Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.jauto; + + + +/* + * Class for Transistor Sizing Algorithms + * + * @author Qing Wu + * @version $Date$ + */ + + +public class Transistor +{ + // name of the transistor + public String name; + + // size of the transistor + // note: this is not the real transistor size (width) + // the real size is calculated as: size * size_of_the_halfoperator + public double size; + + + + public String setName(String s) + { + name = s; + + return name; + } + + + public String getName() + { + return name; + } + + + public double setSize(double d) + { + assert d >= 0.0 : "invalid size for transistor"; + + size = d; + + return size; + } + + + public double getSize() + { + return size; + } + + + // constructor 1 + public Transistor() + { + name = ""; + size = 0.0; + } + + // constructor 2 + public Transistor(Transistor tr) + { + name = tr.name; + size = tr.size; + } + + + // returns current size + public double getCurrentSize() + { + return size; + } + + + // dump out information for debug + public void print() + { + System.out.println("name: " + name); + System.out.println("size: " + size); + } + + + public String toString() + { + String s = "name: " + name + "\n"; + s += "size: " + size + "\n"; + + return s; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TransistorSizingTool.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TransistorSizingTool.java new file mode 100644 index 0000000000..b8c89949c9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/TransistorSizingTool.java @@ -0,0 +1,1804 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.jauto; + +import java.io.*; +import java.util.*; + +import com.avlsi.fast.CastDesign; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.HalfOperator; + +import com.avlsi.tools.jauto.NetSource; +import com.avlsi.tools.jauto.NetSink; +import com.avlsi.tools.jauto.FunctionTerm; +import com.avlsi.tools.jauto.JautoUI; + +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.container.Pair; +import com.avlsi.util.text.NumberFormatter; + +/** Common methods and data for all transistor sizing tools. **/ +abstract public class TransistorSizingTool +{ + // The container(owner) of this tool + JautoMessageCenter messageCenter; + + // The target design after synthesis, e.g., minimal gate network, etc. + CastDesign synthesizedDesign; + + // If there is unsatisfiable delay constraint + public boolean hasUnsatisfiableConstraints; + + // Result output directory + String outputDirectoryName; + + + // Tool options + + // Maximum number of subtypes per sizing group + // NB: This is not really the maximum number per group, as transistor + // sharing can force more than this number per group. This is only + // the maximum in the absence of transistor sharing. + int toolOptionMaxSubtypesPerGroup; + + // Option: delay value per node (second) + double toolOptionUnitDelay; + + // Option: minimun unit delay (second) + double toolOptionMinUnitDelay; + + // Option: size staticizers? + boolean toolOptionSizeStaticizer; + + // Option: enable automatic reset unsatisfiable delay constraints + boolean toolOptionEnableAutoConstraint; + + // Option: threshold value to decide if the size of a half-operator has converged + double toolOptionSizeConvergeThreshold; + + // Option: threshold value for warning of small pre-sizing timing slack + double toolOptionSlackWarningThreshold; + + // Option: maximum and minimum transistor width for gates (not staticizers) + double toolOptionMinWidthP; + double toolOptionMinWidthN; + double toolOptionMaxWidthP; + double toolOptionMaxWidthN; + + /** + * A warning will be produced if an n-transistor has a width larger + * than this value. Negative value disables warning. + **/ + double toolOptionNmosWarnWidth; + + /** + * A warning will be produced if a p-transistor has a width larger + * than this value. Negative value disables warning. + **/ + double toolOptionPmosWarnWidth; + + // Option for auto sub-typing algorighm + double toolOptionMinLoadCap; // minimum possible load cap of the whole design (F) + double toolOptionMaxLoadCap; // maximum possible load cap of the whole design (F) + int toolOptionIntervalNumber; // number of intervals used to divide the whole region of + + // Option for internal E*Tau^2 sweep + boolean toolOptionInternalSweep; + int toolOptionInternalSweepNumber; + double toolOptionInternalSweepStep; + + // Option for Tau stepping method in sizing; + boolean toolOptionStepTau; + + // Option for early out on difficult sizing problems + boolean toolOptionEarlyOut; + + // Option: multiplicative weight for dynamic gate capacitance in objective function + double toolOptionDynamicEnergyPenalty = 1; + + // Option: overall method for the sizing program + // Choices: PATH_BASED_SIZING_METHOD(default), NODE_BASED_SIZING_METHOD + static final int PATH_BASED_SIZING_METHOD = 301; + static final int NODE_BASED_SIZING_METHOD = 302; + static final int HYBRID_SIZING_METHOD = 303; + int toolOptionSizingMethod; + + + /** + * Specifies whether to use equality constraints or intermediate + * variables. + **/ + final boolean useEqualityConstraints; + + // many lists and maps of things + ArrayList/**/ listAllSubtypes; + ArrayList/**/ listAllSizingSubtypes; + ArrayList/**/ listAllFixedSubtypes; + ArrayList/*>*/ listAllGroupedSubtypes; + + ArrayList/*>*/ listFunctions; + + /** + * Map from a pair of GlobalNet and HalfOperator to the + * variable for the delay of that pair. + **/ + Map/*,String>*/ delayMap; + + ArrayList/**/ listVariableNames; + + /** + * Variables that are constrained to the value of an expression or + * are intermediate variables. + **/ + ArrayList/**/ listEqualityVariableNames; + + ArrayList/*>*/ listGroupedVariableNames; + List/**/ listVariableLowerBounds; + List/**/ listVariableUpperBounds; + List/**/ listVariableStartValues; + + Map/*>*/ mapVarNameToHO; + + Map/**/ mapVarNameToSize; + + + /** constructor, should only be called from CG extensions **/ + TransistorSizingTool(final boolean useEqualityConstraints) + { + + listAllSubtypes = new ArrayList/**/(); + listAllFixedSubtypes = new ArrayList/**/(); + listAllSizingSubtypes = new ArrayList/**/(); + listAllGroupedSubtypes = new ArrayList/*>*/(); + + listFunctions = new ArrayList/*>*/(); + + delayMap = + new HashMap/*,String>*/(); + + listVariableNames = new ArrayList/**/(); + listEqualityVariableNames = new ArrayList/**/(); + listGroupedVariableNames = new ArrayList/*>*/(); + listVariableLowerBounds = new ArrayList/**/(); + listVariableUpperBounds = new ArrayList/**/(); + listVariableStartValues = new ArrayList/**/(); + + hasUnsatisfiableConstraints = false; + + mapVarNameToHO = new TreeMap/*>*/(); + mapVarNameToSize = new TreeMap/**/(); + + setOptionMinLoadCap(-1); + setOptionMaxLoadCap(-1); + setOptionIntervalNumber(-1); + + setOptionMinWidthP(-1); + setOptionMinWidthN(-1); + setOptionMaxWidthP(-1); + setOptionMaxWidthN(-1); + + setOptionNmosWarnWidth(-1.0); + setOptionPmosWarnWidth(-1.0); + + setOptionSizeConvergeThreshold(-1); + + setOptionMaxSubtypesPerGroup(-1); + + setOptionUnitDelay(-1); + setOptionMinUnitDelay(-1); + + setOptionSizeStaticizer(false); + setOptionEnableAutoConstraint(false); + + + setOptionInternalSweep(false); + setOptionInternalSweepNumber(1); + setOptionInternalSweepStep(0.0); + + setOptionStepTau(false); + setOptionEarlyOut(false); + + setOptionSizingMethod(PATH_BASED_SIZING_METHOD); + + this.useEqualityConstraints = useEqualityConstraints; + } + + + public ArrayList/**/ setListAllSubtypes(ArrayList/**/ lst1) + { + listAllSubtypes = lst1; + + return listAllSubtypes; + } + + + public ArrayList/**/ getListAllSubtypes() + { + return listAllSubtypes; + } + + + public final boolean setOptionInternalSweep(final boolean b1) + { + toolOptionInternalSweep = b1; + + return toolOptionInternalSweep; + } + + + public final boolean getOptionInternalSweep() + { + return toolOptionInternalSweep; + } + + + public final int setOptionInternalSweepNumber(final int i1) + { + if(i1 <= 0){ + toolOptionInternalSweepNumber = 5; + } + else{ + toolOptionInternalSweepNumber = i1; + } + + return toolOptionInternalSweepNumber; + } + + + public final int getOptionInternalSweepNumber() + { + return toolOptionInternalSweepNumber; + } + + + public final double setOptionInternalSweepStep(final double f1) + { + if(f1 <= 0.0){ + // FIXME: remove default + toolOptionInternalSweepStep = 10.0E-12; + } + else{ + toolOptionInternalSweepStep = f1; + } + + return toolOptionInternalSweepStep; + } + + + public final double getOptionInternalSweepStep() + { + return toolOptionInternalSweepStep; + } + + + public final boolean setOptionStepTau(final boolean b1) + { + toolOptionStepTau = b1; + + return toolOptionStepTau; + } + + + public final boolean getOptionStepTau() + { + return toolOptionStepTau; + } + + + public final boolean setOptionEarlyOut(final boolean b1) + { + toolOptionEarlyOut = b1; + + return toolOptionEarlyOut; + } + + + public final boolean getOptionEarlyOut() + { + return toolOptionEarlyOut; + } + + + public final String setOutputDirectoryName(String s) + { + outputDirectoryName = s; + + return outputDirectoryName; + } + + + public final String getOutputDirectoryName() + { + return outputDirectoryName; + } + + + public boolean setOptionSizeStaticizer(final boolean size) { + toolOptionSizeStaticizer = size; + return toolOptionSizeStaticizer; + } + + + public boolean getOptionSizeStaticizer() { + return toolOptionSizeStaticizer; + } + + + public boolean setOptionEnableAutoConstraint(final boolean b) + { + toolOptionEnableAutoConstraint = b; + return toolOptionEnableAutoConstraint; + } + + + public boolean getOptionEnableAutoConstraint() + { + return toolOptionEnableAutoConstraint; + } + + + public double setOptionMinWidthP(final double f) + { + if(f <= 0.0){ + // FIXME: remove default + toolOptionMinWidthP = 0.48E-6; + } + else{ + toolOptionMinWidthP = f; + } + + return toolOptionMinWidthP; + } + + public double getOptionMinWidthP() + { + return toolOptionMinWidthP; + } + + + public double setOptionMinWidthN(final double f) + { + if(f <= 0.0){ + // FIXME: remove default + toolOptionMinWidthN = 0.48E-6; + } + else{ + toolOptionMinWidthN = f; + } + + return toolOptionMinWidthN; + } + + public double getOptionMinWidthN() + { + return toolOptionMinWidthN; + } + + + public double setOptionMaxWidthP(double f) + { + if(f <= 0.0){ + // FIXME: remove default + toolOptionMaxWidthP = 100.0E-6; + } + else{ + toolOptionMaxWidthP = f; + } + + return toolOptionMaxWidthP; + } + + public double getOptionMaxWidthP() + { + return toolOptionMaxWidthP; + } + + + public double setOptionMaxWidthN(double f) + { + if(f <= 0.0){ + // FIXME: remove default + toolOptionMaxWidthN = 100.0E-6; + } + else{ + toolOptionMaxWidthN = f; + } + + return toolOptionMaxWidthN; + } + + public double getOptionMaxWidthN() + { + return toolOptionMaxWidthN; + } + + /** + * Set the warning width for n-transistors. If an n-transistor + * has a width larger than this, a warning will be emitted. + * Pass a non-positive value to disable the warning. + * + * @param nmosWarnWidth + * A warning will be emitted for transistors larger than + * this width. Set negative to disable + **/ + public void setOptionNmosWarnWidth(final double nmosWarnWidth) { + toolOptionNmosWarnWidth = nmosWarnWidth; + } + + /** + * Get the warning width for n-transistors. + **/ + public double getOptionNmosWarnWidth() { + return toolOptionNmosWarnWidth; + } + + /** + * Set the warning width for p-transistors. If a p-transistor + * has a width larger than this, a warning will be emitted. + * Pass a non-positive value to disable the warning. + * + * @param pmosWarnWidth + * A warning will be emitted for transistors larger than + * this width. + **/ + //@ ensures toolOptionPmosWarnWidth > 0.0; + public void setOptionPmosWarnWidth(final double pmosWarnWidth) { + toolOptionPmosWarnWidth = pmosWarnWidth; + } + + /** + * Get the warning width for p-transistors. + **/ + public double getOptionPmosWarnWidth() { + return toolOptionPmosWarnWidth; + } + + + public double setOptionSizeConvergeThreshold(double f) + { + if((f <= 0.0) || (f >= 10.0 * toolOptionMinWidthN)){ + // FIXME: remove default + toolOptionSizeConvergeThreshold = 0.1E-6; + } + else{ + toolOptionSizeConvergeThreshold = f; + } + + return toolOptionSizeConvergeThreshold; + } + + + public double getOptionSizeConvergeThreshold() + { + return toolOptionSizeConvergeThreshold; + } + + + public double setOptionSlackWarningThreshold(double f) + { + if((f <= 0.0)){ + toolOptionSlackWarningThreshold = 0.0; + } + else{ + toolOptionSlackWarningThreshold = f; + } + + return toolOptionSlackWarningThreshold; + } + + + public double getOptionSlackWarningThreshold() + { + return toolOptionSlackWarningThreshold; + } + + + public int setOptionIntervalNumber(int i) + { + if(i < 0){ + toolOptionIntervalNumber = 1; + } + else{ + toolOptionIntervalNumber = i; + } + + return toolOptionIntervalNumber; + } + + public int getOptionIntervalNumber() + { + return toolOptionIntervalNumber; + } + + + public double setOptionMinLoadCap(double d) + { + if(d < 0.0){ + toolOptionMinLoadCap = 0.0; + } + else{ + if(d > toolOptionMaxLoadCap){ + toolOptionMinLoadCap = toolOptionMaxLoadCap; + } + else{ + toolOptionMinLoadCap = d; + } + } + + return toolOptionMinLoadCap; + } + + + public double getOptionMinLoadCap() + { + return toolOptionMinLoadCap; + } + + public double setOptionMaxLoadCap(double d) + { + if(d < 0.0){ + // FIXME: remove default + toolOptionMaxLoadCap = 1.0E-12; + } + else{ + if(d < toolOptionMinLoadCap){ + toolOptionMaxLoadCap = toolOptionMinLoadCap; + } + else{ + toolOptionMaxLoadCap = d; + } + } + + return toolOptionMaxLoadCap; + } + + + public double getOptionMaxLoadCap() + { + return toolOptionMaxLoadCap; + } + + + public int setOptionMaxSubtypesPerGroup(int i) + { + if (i <= 0){ + toolOptionMaxSubtypesPerGroup = 1; + } + else{ //default is to size one subtype at a time + toolOptionMaxSubtypesPerGroup = i; + } + + return toolOptionMaxSubtypesPerGroup; + } + + + public int getOptionMaxSubtypesPerGroup() + { + return toolOptionMaxSubtypesPerGroup; + } + + + public double setOptionUnitDelay(double d) + { + if(d <= 0.0){ // default setting = 80 ps + // FIXME: remove default + toolOptionUnitDelay = 80.0E-12; + } + else{ + toolOptionUnitDelay = d; + } + + return toolOptionUnitDelay; + } + + public double getOptionUnitDelay() + { + return toolOptionUnitDelay; + } + + + public double setOptionMinUnitDelay(final double d) + { + if(d <= 0.0){ // default setting = 20 ps + // FIXME: remove default + toolOptionMinUnitDelay = 20.0E-12; + } + else{ + toolOptionMinUnitDelay = d; + } + + return toolOptionMinUnitDelay; + } + + public double getOptionMinUnitDelay() + { + return toolOptionMinUnitDelay; + } + + + public void setOptionSizingMethod(int sizingMethod) + { + assert sizingMethod == PATH_BASED_SIZING_METHOD || + sizingMethod == NODE_BASED_SIZING_METHOD; + toolOptionSizingMethod = sizingMethod; + } + + public int getOptionSizingMethod() + { + assert toolOptionSizingMethod == PATH_BASED_SIZING_METHOD || + toolOptionSizingMethod == NODE_BASED_SIZING_METHOD; + return toolOptionSizingMethod; + } + + public CastDesign setSynthesizedDesign(CastDesign d) + { + synthesizedDesign = d; + + return synthesizedDesign; + } + + public CastDesign getSynthesizedDesign() + { + return synthesizedDesign; + } + + public double setOptionDynamicEnergyPenalty(double x) + { + toolOptionDynamicEnergyPenalty = (x>0) ? x : 1; + return toolOptionDynamicEnergyPenalty; + } + + public double getOptionDynamicEnergyPenalty() + { + return toolOptionDynamicEnergyPenalty; + } + + public JautoMessageCenter setMessageCenter(JautoMessageCenter mc) + { + messageCenter = mc; + + return messageCenter; + } + + + public JautoMessageCenter getMessageCenter() + { + return messageCenter; + } + + /** must define this in specific CG extension **/ + abstract public String sizeTransistors(); + + /** + * Group variables. Only CG solver as non-trivial implementation. + **/ + abstract void groupVariables(); + + /** + * Genereate the objective function(s). + **/ + abstract void generateObjectiveFunction(Set/**/ setc); + + /** + * Run the external solver program. + **/ + abstract String runSolver(int iterationNumber, int groupNumber); + + /** + * Generate, formulate, output problem, solve, read-back. + **/ + String runOptimization(ArrayList/**/ listCells, + int iterationNumber, + int groupNumber) + { + listFunctions.clear(); + mapVarNameToHO.clear(); + mapVarNameToSize.clear(); + + delayMap.clear(); + + listVariableNames.clear(); + listEqualityVariableNames.clear(); + + + listVariableLowerBounds.clear(); + listVariableUpperBounds.clear(); + listVariableStartValues.clear(); + + if(DebugOption.printLevel <= 1){ + System.out.println("Current step: generating objective function"); + } + + + // Unfix variables for the cells to be sized + //iterator of list of CellType + for (Iterator ita = listCells.iterator(); ita.hasNext(); ){ + CellType cella = (CellType)ita.next(); // get next CellType + cella.unfixVariables(); // unfix variables related to half-operators + + if(DebugOption.printLevel <= 3){ + System.out.println("CellName=" + cella.typeName + ", Fixed=" + cella.isFixedSize()); + } + } + + + // Generate list of variable groups + groupVariables(); + + + // Find all the related leaf cells + Set/**/ setc = new LinkedHashSet/**/(); + for (Iterator ita = listCells.iterator(); ita.hasNext(); ){ + CellType cella = (CellType)ita.next(); + + if(cella.getLevel() == 0){ + setc.add(cella); + } + else{ + for (Iterator itb = cella.setSizingHalfOperators.iterator(); + itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + setc.add(hoa.subType); + } + } + } + + + // Generate objective function + generateObjectiveFunction(setc); + + + generateVariableBoundsAndStartValues(); + + + + if(DebugOption.printLevel <= 0){ + System.out.println("Current step: generating constraint functions"); + } + + + generateMinDelayConstraints(setc, iterationNumber); + + + generateConstraints(listCells); + + if (! JautoUI.quiet) { + System.err.println("\033[1;32m" + JautoUI.getCurrentTime() + + " -- Starting solver." + "\033[0m"); + System.out.println(JautoUI.getCurrentTime() + " -- Starting solver."); + } + + String result = runSolver(iterationNumber, groupNumber); + + if (! JautoUI.quiet) { + System.err.println("\033[1;32m" + JautoUI.getCurrentTime() + + " -- Finished solver." + "\033[0m"); + System.out.println(JautoUI.getCurrentTime() + " -- Finished solver."); + } + + if (result != "Done") + return result; + + if(DebugOption.printLevel <= 0){ + System.out.println("Current step: fixing variables"); + } + + // Fix variables + for (Iterator ita = listCells.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + cella.fixVariables(); + } + // Done with variable fix + + + return "Done"; + } + + /** + * Create another term of the objective function + **/ + FunctionTerm newObjectiveTerm(String sta, double f, int instCount, + boolean isFixed, HalfOperator hoa) { + // chose objective weighting function (higher for dynamic, non-library operators) + double weight = instCount; + if (!hoa.isCombinational && !hoa.isLibraryGate) + weight *= toolOptionDynamicEnergyPenalty; + + // create the term + FunctionTerm terma = new FunctionTerm(); + if(isFixed){ // fixed variable leads to a constant + f = f * hoa.getCurrentSize(); + terma.type = FunctionTerm.Type.CONSTANT; + terma.coefficient = f * weight; + } + else{ // unfixed variable leads to a linear term + terma.type = FunctionTerm.Type.VAR; + terma.variableName_1 = sta; + terma.coefficient = f * weight * hoa.getSizeForConductance(1.0); + } + return terma; + } + + // Assign variable names to all the half-operators in the design + // This step should be done every time after sub-typing + // configuration has been changed + public void assignVariableNames() + { + int varNum = 0; + + // One variable per half-operator. Combine half-operators that + // share transistors. + + for (Iterator ita = listAllSubtypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + + if(DebugOption.printLevel <= 3){ + System.out.println("Assigning variable names for cell: " + sta.typeName); + } + + // halfOpSharings is a partition of the half operators from the + // cell formed by the transitive closure of the relation + // HalfOperator.isSharingWith(). + List/*>*/ halfOpSharings = + new ArrayList/*>*/(); + + for (Iterator itb = sta.getListHalfOperators().iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + + boolean shared = false; + List/**/ halfOpsSharedWith = null; + + // Go through all half-ops hob in halfOpSharings and see if + // hoa shares with any of those. + for (Iterator itc = halfOpSharings.iterator(); itc.hasNext(); ) { + List/**/ lstc = (List)itc.next(); + for (Iterator itd = lstc.iterator(); itd.hasNext(); ){ + HalfOperator hob = (HalfOperator)itd.next(); + if(hoa.isSharingWith(hob) || + hoa.isSameStrengthGroup(hob)){ + if(!shared){ + // This is the first group that hoa shares + // with. + if(DebugOption.printLevel <= 3){ + System.out.println("Note: Found transistor sharing between half-operators or strength_group directives."); + } + + shared = true; + + // Remember the group for later and add hoa + // to it. + halfOpsSharedWith = lstc; + lstc.add(hoa); + } + else{ + // This is not the first group that hoa + // shares with. + if(DebugOption.printLevel <= 3){ + System.out.println("Note: Found complex transistor sharing between half-operators or strength_group directives."); + } + + // Add this group to the remembered one and delete + // this one because it is now merged. + halfOpsSharedWith.addAll(lstc); + itc.remove(); + } + + // As soon as we share with one half-operator + // in the group, we have handled the whole + // group. Go to the next one. + break; + } + } + } + + // If we didn't share with anything, then add half-operator + // as a new group. + if(!shared){ + List/**/ newGroup = + new ArrayList/**/(); + newGroup.add(hoa); + halfOpSharings.add(newGroup); + } + + } + + // Assign variable names to all half operators. + for (Iterator itc = halfOpSharings.iterator(); itc.hasNext(); ) { + List/**/ lstc = (List)itc.next(); + + // Half-operators that share transistors get the same name. + String sa = "X" + varNum; + for (Iterator itd = lstc.iterator(); itd.hasNext(); ) { + HalfOperator hob = (HalfOperator)itd.next(); + hob.setVariableName(sa); + } + + if(DebugOption.printLevel <= 3){ + System.out.println("\tAdded variable: " + sa); + } + + varNum++; + } + + + } + } + + /** + * Append variable lower, upper bounds and start value to lists + * listVariableLowerBounds, + * listVariableUpperBounds, and + * listVariableStartValues respectively. Bounds are + * computed so that transistor sizes will be between + * toolOptionMinWidthN and + * toolOptionMaxWidthN for pull-downs and + * similarly for pull-ups. Both stack depth and effective + * resistance are corrected for. + **/ + private void generateVariableBoundsAndStartValues() { + for (Iterator ita = listVariableNames.iterator(); ita.hasNext(); ){ + String sta = (String)ita.next(); + List/**/ lstc = (List)mapVarNameToHO.get(sta); + TechnologyData tdata = synthesizedDesign.getTechnologyData(); + + // Compute the max of the min allowed widths and the min of + // the max allowed widths for each half-operator that uses + // this variable. This gives us the safe bounds for the + // half-operator sizes. + double minAllowedConductance = Double.NEGATIVE_INFINITY; + double maxAllowedConductance = Double.POSITIVE_INFINITY; + for (final Iterator itb = lstc.iterator(); itb.hasNext(); ) { + final HalfOperator hob = (HalfOperator) itb.next(); + + final double minWidth; + final double maxWidth; + if (hob.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN) { + minWidth = toolOptionMinWidthN; + maxWidth = toolOptionMaxWidthN; + } else { + minWidth = toolOptionMinWidthP; + maxWidth = toolOptionMaxWidthP; + } + + double minAllowedSize = Double.NEGATIVE_INFINITY; + double maxAllowedSize = Double.POSITIVE_INFINITY; + + final int[] depths = hob.getDepths(); + for (int i = 0; i < depths.length; ++i) { + final int depth = depths[i]; + // Transistor size is proportional to half-operator + // size, and getWidth(depth) / getCurrentSize() gives + // us the proportionality constant. It would be nice + // if there were a getSizeFactor(), but there isn't yet. + // The trick of using getWidth(depth) takes care of + // both depth and erf correction. + minAllowedSize = Math.max(minAllowedSize, + minWidth * + hob.getSymmetrizationFactor() * + hob.getCurrentSize() / + hob.getWidth(depth)); + // don't use symmetrization factor for max_width constraints + maxAllowedSize = Math.min(maxAllowedSize, + maxWidth * + hob.getCurrentSize() / + hob.getWidth(depth)); + } + + // compute minimum size to overpower weakest staticizer + if (!hob.isCombinational) { + double minSize = + SizeStaticizers.getMinimumLogicSize(tdata,hob); + if (minSize>minAllowedSize) { + /*** debugging + System.out.println + ("NOTE: minWidth of " + + hob.outputNet.canonicalName.getCadenceString() + + (hob.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+") + + " increased from " + + NumberFormatter.format(minAllowedSize,3) + + " to " + + NumberFormatter.format(minSize,3)); + ***/ + minAllowedSize = minSize; + } + } + + minAllowedConductance = + Math.max(minAllowedConductance, + hob.getConductanceForSize(minAllowedSize)); + maxAllowedConductance = + Math.min(maxAllowedConductance, + hob.getConductanceForSize(maxAllowedSize)); + } + + listVariableLowerBounds.add(new Double(minAllowedConductance)); + listVariableUpperBounds.add(new Double(maxAllowedConductance)); + + // arbitrarily set initial value to twice minAllowedConductance + listVariableStartValues.add(new Double(2*minAllowedConductance)); + } + } + + private void generateMinDelayConstraints(final Set/**/ setc, + final int iterationNumber) { + // Generate special constraints for minimum delay requirement + // Note: This breaks the posinomial nature of the problem. + for (Iterator ita = setc.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + if(cella.getListHalfOperators().size() > 0){ + for (Iterator itb = cella.getListHalfOperators().iterator(); + itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + if(hoa.minDelay > 0){ // there is minimum delay specified by user + if(iterationNumber < 2){ + String msa = "WARNING"; + String msb = "Found user-specified minimum delay requirement.\n"; + String msc = "CellName: " + cella.typeName + "\n" + + "HalfOperatorName: " + hoa.outputNet.canonicalName.getCadenceString() + + (hoa.driveDirection == + HalfOperator.DriveDirection.PULL_DOWN ? + "-" : "+") + "\n"; + + messageCenter.createMessage(1, 11, msa, msb, msc); + } + + for (Iterator itc = hoa.outputNet.getGlobalNets().iterator(); + itc.hasNext(); ) { + GlobalNet gna = (GlobalNet)itc.next(); + List functiona = + new ArrayList(); + + FunctionTerm terma = new FunctionTerm(); + terma.type = + FunctionTerm.Type.CONSTRAINT_LESS_THAN; + functiona.add(terma); + + getDelayFunction(gna, hoa, functiona); + + for (FunctionTerm ft : functiona) { + // negate the coefficients, to comply with "<=" constraint type + ft.coefficient *= -1.0; + } + + terma = new FunctionTerm(); + terma.type = FunctionTerm.Type.CONSTANT; + terma.coefficient = -1.0 * toolOptionUnitDelay * (cella.getDelay().getNativeDelay(hoa.driveDirection != HalfOperator.DriveDirection.PULL_DOWN) / 100.0) * hoa.minDelay; + functiona.add(terma); + + listFunctions.add(functiona); + } + } + } + } + } + } + + public static float findDelayBias(final GlobalNet gn, + final HalfOperator op) { + float result = Float.POSITIVE_INFINITY; + for (Iterator i = gn.getListSources().iterator(); i.hasNext(); ) { + final NetSource src = (NetSource) i.next(); + if (src.getSource() == op) { + result = Math.min(result, src.getDelayBias()); + } + } + return result == Float.POSITIVE_INFINITY ? 1 : result; + } + + private void generateConstraints(final List/**/ listCells) { + // Generate the constraints + List/**/ lste = new ArrayList/**/(); + for (Iterator ita = listCells.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + + if(DebugOption.printLevel <= 1){ + System.out.println(cella.toString()); + } + + if(cella.getLevel() == 0){ // Leaf-cell + + if(DebugOption.printAll){ + System.out.println("Number of paths: " + + cella.getSizingPaths().size()); + } + + for (Iterator itb = cella.getSizingPaths().iterator(); + itb.hasNext(); ) { + SizingPath spa = (SizingPath)itb.next(); + + if(!spa.isFragment()){ + List/**/ lsta = spa.getPath(); + + List functiona = + new ArrayList(); // one constraint function per path + + FunctionTerm terma = new FunctionTerm(); + terma.type = FunctionTerm.Type.CONSTRAINT_LESS_THAN; + functiona.add(terma); + + int k = lsta.size(); + + if(DebugOption.printLevel <= 1){ + System.out.println("size of the path: " + k); + if(k >= 10){ + System.out.println(spa.toString()); + } + } + + if(DebugOption.printAll){ + System.out.println("Length of the path: " + k); + } + + double totalDelayBias = 0.0; + + for(int i=0;i gnb.getWireRC()){ + found = false; + itd.remove(); + } + break; + } + } + if(!found){ + lste.add(gna); + } + } + + for (Iterator itc = lste.iterator(); itc.hasNext(); ) { + GlobalNet gna = (GlobalNet)itc.next(); + + List functionb = + new ArrayList(functiona); + + getDelayFunction(gna, hoa, functionb); // get the delay expression + + // Get extra delay setting in the middle-level cell + double extraDelay = DelayCalculator.getExtraDelay(hoa, gna, getOptionUnitDelay()); + + terma = new FunctionTerm(); + terma.type = FunctionTerm.Type.CONSTANT; + terma.coefficient = totalDelayBias + * findDelayBias(gna, hoa) + * getOptionUnitDelay() + extraDelay; + functionb.add(terma); + + + // Check for unsatisfiable delay constraints + boolean isAllConstant = true; + double f = 0.0; + int j = functionb.size(); + for(int o=1;o= delayBudget) { + // Unsatisfiable constraint + hasUnsatisfiableConstraints = true; + + String msa = "ERROR"; + String msb = "Unsatisfiable delay constraint: " + delayBudget + " Slack: " + (delayBudget-f) + "\n"; + String msc = "Cell Name: " + cella.typeName + "\n" + + "Path information: " + spa.toString() + "\n" + + "Global net information for the last cellnet on the path:" + "\n" + + gna.toString("\t") + "\n"; + + messageCenter.createMessage(0, 4, msa, msb, msc); + + if(toolOptionEnableAutoConstraint){ + hasUnsatisfiableConstraints = false; + delayBudget = f + (toolOptionMinUnitDelay * k); + termb.coefficient = delayBudget; + + String msd = "WARNING"; + String mse = "Jauto has automatically set constraint to: " + delayBudget + " Slack: " + (delayBudget-f) + "\n"; + String msf = ""; + + messageCenter.createMessage(1, 12, msd, mse, msf); + } + } else if (delayBudget - f <= toolOptionSlackWarningThreshold) { + String msa = "WARNING"; + String msb = "Small delay slack: " + (delayBudget-f) + "\n"; + String msc = "CellName: " + cella.typeName + "\n" + + "Path information: " + spa.toString() + "\n" + + "Global net information for the last cellnet on the path:" + "\n" + + gna.toString("\t") + "\n"; + + messageCenter.createMessage(1, 13, msa, msb, msc); + + } + listFunctions.add(functionb); // add one more constraint + } + // End of check for unsatisfiable or small delay constraints + } + } + } + } + else{ // Non-leaf cell + + for (Iterator itb = cella.getReducedCatPaths().iterator(); + itb.hasNext(); ) { + CatPath cpa = (CatPath)itb.next(); + + if(!cpa.isFragment()){ + List/**/ lsta = cpa.getCatPath(); + + double extraDelay = 0.0; + double totalDelayBias = 0.0; + + List functiona = + new ArrayList(); + + FunctionTerm terma = new FunctionTerm(); + terma.type = FunctionTerm.Type.CONSTRAINT_LESS_THAN; + functiona.add(terma); + + int k = lsta.size(); + int m = 0; + + for(int i=0;i*/ lstb = spa.getPath(); + + int l = lstb.size(); + m += l; + + for(int j=0;j gnb.getWireRC()){ + found = false; + itd.remove(); + } + break; + } + } + if(!found){ + lste.add(gna); + } + } + + for (Iterator itc = lste.iterator(); itc.hasNext(); ) { + GlobalNet gna = (GlobalNet)itc.next(); + + List functionb = + new ArrayList(functiona); + + getDelayFunction(gna, hoa, functionb); // get the delay expression + + double totalExtraDelay = extraDelay + DelayCalculator.getExtraDelay(hoa, gna, getOptionUnitDelay()); + + terma = new FunctionTerm(); + terma.type = FunctionTerm.Type.CONSTANT; + terma.coefficient = + (totalDelayBias + + pathDelayBias * + findDelayBias(gna, hoa)) + * getOptionUnitDelay() + + totalExtraDelay; + functionb.add(terma); + + + // Check for unsatisfiable delay constraints + boolean isAllConstant = true; + double f = 0.0; + int p = functionb.size(); + for(int o=1;o= delayBudget) { + // Unsatisfiable constraint + hasUnsatisfiableConstraints = true; + + String msa = "ERROR"; + String msb = "Unsatisfiable delay constraint: " + delayBudget + " Slack: " + (delayBudget-f) + "\n"; + String msc = "Cell Name: " + cella.typeName + "\n" + + "Path information: " + cpa.toString() + "\n" + + "Global net information for the last cellnet on the path:" + "\n" + + gna.toString("\t") + "\n"; + + messageCenter.createMessage(0, 4, msa, msb, msc); + + if(toolOptionEnableAutoConstraint){ + hasUnsatisfiableConstraints = false; + delayBudget = f + (toolOptionMinUnitDelay * m); + termb.coefficient = delayBudget; + + String msd = "WARNING"; + String mse = "Jauto has automatically set constraint to: " + delayBudget + " Slack: " + (delayBudget-f) + "\n"; + String msf = ""; + + messageCenter.createMessage(1, 12, msd, mse, msf); + } + } else if (delayBudget - f <= toolOptionSlackWarningThreshold) { + String msa = "WARNING"; + String msb = "Small delay slack: " + (delayBudget-f) + "\n"; + String msc = "Cell Name: " + cella.typeName + "\n" + + "Path information: " + cpa.toString() + "\n" + + "Global net information for the last cellnet on the path:" + "\n" + + gna.toString("\t") + "\n"; + + messageCenter.createMessage(1, 13, msa, msb, msc); + } + + listFunctions.add(functionb); // add one more constraint + } + // End of check for unsatisfiable or small delay constraints + } + } + } + } + } + } + } + } + } + } + + + /** + * Adds the delay function for the pair of GlobalNet and HalfOperator + * to the list delayFunction. If this is the first time + * this pair's delay has been queried, an intermediate variable + * (which will be handled as an equality constraint) will be added. + **/ + private void getDelayFunction(final GlobalNet globalNet, + final HalfOperator halfOp, + List delayFunction) { + if (useEqualityConstraints) { + final Pair/**/ k = + new Pair/**/(globalNet, halfOp); + String delayVar = (String) delayMap.get(k); + if (delayVar == null) { + delayVar = "D" + delayMap.size(); + delayMap.put(k, delayVar); + listEqualityVariableNames.add(delayVar); + + List equalityConstraint + = new ArrayList(); + final FunctionTerm constraintTerm = new FunctionTerm(); + constraintTerm.type = FunctionTerm.Type.CONSTRAINT_EQUALS; + constraintTerm.variableName_1 = delayVar; + equalityConstraint.add(constraintTerm); + globalNet.getDelayFunction(halfOp, equalityConstraint); + // add constant term so simplifier is happy + final FunctionTerm constantTerm = new FunctionTerm(); + constantTerm.type = FunctionTerm.Type.CONSTANT; + constantTerm.coefficient = 0.0; + equalityConstraint.add(constantTerm); + + listFunctions.add(equalityConstraint); + } + + // TODO: save memory by reusing the same term here. + final FunctionTerm term = new FunctionTerm(); + term.type = FunctionTerm.Type.VAR; + term.variableName_1 = delayVar; + term.coefficient = 1.0; + delayFunction.add(term); + } else { + globalNet.getDelayFunction(halfOp, delayFunction); + } + } + + + /** + * Initialize the sizes of all the transistors + **/ + public void initializeSize(boolean skipSizing) + { + for (Iterator ita = listAllSubtypes.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + List/**/ halfOps = cella.getListHalfOperators(); + + if((!cella.isFixedSize()) && (!skipSizing)){ + for (Iterator itb = halfOps.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + // FIXME: This is a horrible + // Set the size twice so that both previousSize and + // currentSize are pi microns. + hoa.updateSize(0.314159265E-6); + hoa.updateSize(0.314159265E-6); + } + } + else{ + if(DebugOption.printLevel <= 3){ + System.out.println("Fixed-size cell found:"); + System.out.println(cella.toString()); + } + + for (Iterator itb = halfOps.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + hoa.initializeSize(); + } + } + + cella.fixVariables(); + } + } + + + void resetWidth() { + for (Iterator ita = listAllSubtypes.iterator(); ita.hasNext(); ) { + CellType cella = (CellType)ita.next(); + if (!cella.isFixedSize()) { + List/**/ halfOps = cella.getListHalfOperators(); + for (Iterator itb = halfOps.iterator(); itb.hasNext(); ) { + HalfOperator hoa = (HalfOperator)itb.next(); + hoa.resetWidth(); + } + } + } + } + + /** + * Delete those subtypes without transistors. Clears + * listAllSizingSubtypes and adds cells from + * listAllSubtypes with either paths (if + * NODE_BASED_SIZING_METHOD) or transistors (if + * PATH_BASED_SIZING_METHOD). + **/ + public void reduceSubtypes() + { + listAllSizingSubtypes.clear(); + + if(toolOptionSizingMethod == NODE_BASED_SIZING_METHOD){ + for (Iterator ita = listAllSubtypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + if(sta.transistors.isEmpty()){ // no transistors in this sub-type + if (! JautoUI.quiet) { + System.out.println("************** Removed ****************"); + System.out.println(sta.toString()); + } + } + else{ + listAllSizingSubtypes.add(sta); + } + } + } + + if(toolOptionSizingMethod == PATH_BASED_SIZING_METHOD){ + for (Iterator ita = listAllSubtypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + if(!sta.hasPaths()){ // there are no paths in this sub-type + if (! JautoUI.quiet) { + System.out.println("************** Removed ****************"); + System.out.println(sta.toString()); + } + } + else{ + listAllSizingSubtypes.add(sta); + } + } + } + } + + + // Notes for the future: + // 1. Size cells near primary outputs first. + // 2. Size cells with most instances first. + + public void partitionSubtypes() + { + for (Iterator ita = listAllSizingSubtypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + + sta.generateSizingHalfOperators(); + } + + + List/*>*/ cellTypeSharings = + new ArrayList/*>*/(); + + for (Iterator ita = listAllSizingSubtypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + + boolean shared = false; + List/**/ cellTypesSharedWith = null; + + for (Iterator itc = cellTypeSharings.iterator(); + itc.hasNext(); ) { + List/**/ lstc = (List)itc.next(); + + for (Iterator itd = lstc.iterator(); itd.hasNext(); ) { + CellType stb = (CellType)itd.next(); + + if(sta.isSharingSizingHalfOperatorsWith(stb)){ + if(!shared){ + if(DebugOption.printLevel <= 3){ + System.out.println("Note: Sizing half-operator sharing between cell-types found."); + } + + shared = true; + + cellTypesSharedWith = lstc; + lstc.add(sta); + } + else{ + if(DebugOption.printLevel <= 3){ + System.out.println("Note: Complex half-operator sharing between cell-types found."); + } + + cellTypesSharedWith.addAll(lstc); + itc.remove(); + } + + break; + } + } + } + + if(!shared){ + List/**/ newGroup = new ArrayList/**/(); + newGroup.add(sta); + cellTypeSharings.add(newGroup); + } + } + + + listAllGroupedSubtypes.clear(); + + int numCellsInGroup = 0; + List/**/ group = new ArrayList/**/(); + for (Iterator itc = cellTypeSharings.iterator(); itc.hasNext(); ) { + List/**/ lstc = (List)itc.next(); + + // TODO: get rid of numCellsInGroup if this assertion holds + assert numCellsInGroup == group.size(); + assert numCellsInGroup != 0 || group.isEmpty(); + group.addAll(lstc); + + + numCellsInGroup += lstc.size(); + if (numCellsInGroup >= toolOptionMaxSubtypesPerGroup) { + listAllGroupedSubtypes.add(group); + numCellsInGroup = 0; + group = new ArrayList/**/(); + } + } + + assert numCellsInGroup == group.size(); + if (numCellsInGroup != 0) + listAllGroupedSubtypes.add(group); + + if(DebugOption.printLevel <= 3){ + System.out.println("Subtype partitioning result:"); + for (Iterator ita = listAllGroupedSubtypes.iterator(); ita.hasNext(); ){ + System.out.println("\tGroup:"); + + List/**/ lstc = (List)ita.next(); + + for (Iterator itb = lstc.iterator(); itb.hasNext(); ){ + CellType sta = (CellType)itb.next(); + System.out.println("\t\tCell: " + sta.typeName); + } + + } + } + + /** + * Removing groups with all fixed-size cells + */ + + for (Iterator ita = listAllGroupedSubtypes.iterator(); ita.hasNext(); ) { + List/**/ lstc = (List)ita.next(); + + boolean isAllFixed = true; + + cellsInGroupLoop: + for (Iterator itb = lstc.iterator(); itb.hasNext(); ){ + CellType sta = (CellType)itb.next(); + + for (Iterator itc = sta.setSizingHalfOperators.iterator(); itc.hasNext(); ){ + HalfOperator hoa = (HalfOperator)itc.next(); + if(!hoa.subType.isFixedSize()){ + isAllFixed = false; + break cellsInGroupLoop; + } + } + + assert isAllFixed; + if(DebugOption.printLevel <= 3){ + System.out.println("Note: Found fixed-size cell: " + sta.typeName); + } + } + + if(isAllFixed){ + ita.remove(); + + if(DebugOption.printLevel <= 3){ + System.out.println("Note: Group with all fixed-size cells removed."); + } + } + } + + + if(DebugOption.printLevel <= 3){ + System.out.println("Subtype partitioning result after removing groups with all fixed-size cells:"); + for (Iterator ita = listAllGroupedSubtypes.iterator(); ita.hasNext(); ){ + System.out.println("\tGroup:"); + + List/**/ lstc = (List)ita.next(); + + for (Iterator itb = lstc.iterator(); itb.hasNext(); ) { + CellType sta = (CellType)itb.next(); + System.out.println("\t\tCell: " + sta.typeName); + } + + } + } + + + /** + * Look for all fixed-size leaf-cells + **/ + + listAllFixedSubtypes.clear(); + for (Iterator ita = listAllSizingSubtypes.iterator(); ita.hasNext(); ) { + CellType sta = (CellType)ita.next(); + + boolean isAllFixed = true; + + for (Iterator itb = sta.setSizingHalfOperators.iterator(); itb.hasNext(); ){ + HalfOperator hoa = (HalfOperator)itb.next(); + if(!hoa.subType.isFixedSize()){ + isAllFixed = false; + break; + } + } + + if(isAllFixed){ + listAllFixedSubtypes.add(sta); + } + } + + if(DebugOption.printLevel <= 3){ + System.out.println("NOTE: Number of cells in the list of fixed-size subtypes: " + listAllFixedSubtypes.size()); + } + + JautoUI.dumpSubtypePartitionInformation(synthesizedDesign, + listAllGroupedSubtypes, + listAllFixedSubtypes, + outputDirectoryName); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/cast2cdl.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/cast2cdl.package new file mode 100644 index 0000000000..e5100aeed2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/cast2cdl.package @@ -0,0 +1,13 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + + +<$@ + +$(CURR_TARGET_DIR)/jauto.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.Jauto/" >$@ + +$(CURR_TARGET_DIR)/cast2cdl.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.Cast2Cdl/" >$@ + +$(CURR_TARGET_DIR)/subtype_split.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.SubtypeSplit/" >$@ + +$(CURR_TARGET_DIR)/subtype_merge.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.SubtypeMerge/" >$@ + +$(CURR_TARGET_DIR)/merge_hint.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.MergeHint/" -e 's/\$$PACKAGE_JRE_ARGS_DEFAULT\$$/-server/' >$@ + +$(CURR_TARGET_DIR)/caststat.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.CastStat/" >$@ + +$(CURR_TARGET_DIR)/cast_query.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.CastQuery/" >$@ + +$(CURR_TARGET_DIR)/generate_charge_sharing_tests.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.GenerateChargeSharingTests/" >$@ + +$(CURR_TARGET_DIR)/count_prs.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.CountPrs/" >$@ + +$(CURR_TARGET_DIR)/netlistDistance.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.NetlistDistance/" >$@ + +$(CURR_TARGET_DIR)/generate_plt_subtypes.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.GeneratePLTSubtypes/" >$@ + +$(CURR_TARGET_DIR)/jtimer.sh: \ + $(CURR_PROJECT_DIR)/jtimer.sh + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jauto.Jtimer/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jauto.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jauto.package new file mode 100644 index 0000000000..cb2de15301 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jauto.package @@ -0,0 +1,37 @@ +0 6 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.tools.jauto.Jauto +java com.avlsi.tools.jauto.CastQuery +java com.avlsi.tools.jauto.Cast2Cdl +java com.avlsi.tools.jauto.SubtypeSplit +java com.avlsi.tools.jauto.SubtypeMerge +java com.avlsi.tools.jauto.MergeHint +java com.avlsi.file.cdl.parser.CDLstat +java com.avlsi.tools.jauto.CastStat +java com.avlsi.tools.jauto.CastQuery +java com.avlsi.tools.jauto.GenerateChargeSharingTests +java com.avlsi.tools.jauto.GeneratePLTSubtypes +java com.avlsi.tools.jauto.LeafSpec +java com.avlsi.tools.jauto.Jtimer +$arch/bin/jauto.sh jauto.sh 775 +$arch/bin/cast2cdl.sh cast2cdl.sh 775 +$arch/bin/cdlstat.sh ../../file/cdl/parser/cdlstat.sh 775 +$arch/bin/subtype_merge.sh subtype_merge.sh 775 +$arch/bin/subtype_split.sh subtype_split.sh 775 +$arch/bin/merge_hint.sh merge_hint.sh 775 +$arch/bin/caststat.sh caststat.sh 775 +$arch/bin/cast_query.sh cast_query.sh 775 +$arch/bin/generate_charge_sharing_tests.sh generate_charge_sharing_tests.sh 775 +$arch/bin/generate_plt_subtypes.sh generate_plt_subtypes.sh 775 +$arch/bin/jtimer.sh jtimer.sh 775 +share/java/JaCoP-3.2.jar ../../../../../jars/JaCoP-3.2.jar 640 p + +include ../../../../../../scripts/graph_netlist.inc ../../../../../../scripts +include ../../util/debug/gettime.package.inc ../../util/debug +include ../../cast2/util/fileserver.package.inc ../../cast2/util +include ../../util/logging/logging.package.inc ../../util/logging +include ../../util/flute/flute.package.inc ../../util/flute diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/javafiles-custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/javafiles-custom.mk new file mode 100644 index 0000000000..c49c355269 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/javafiles-custom.mk @@ -0,0 +1 @@ +JAVAFILES_PARSERS_USED := $(JAVAFILES_PARSERS_USED) $(CURR_TARGET_DIR)/CastQueryParser diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jtimer.sh b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jtimer.sh new file mode 100755 index 0000000000..0ab59e9728 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jauto/jtimer.sh @@ -0,0 +1,327 @@ +#!/bin/bash +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + + +function exit_func() { + if [ -f "$strace_dump" ] ; then + rm -f $strace_dump + fi +} + +trap exit_func EXIT + + +arch_bin_dir=${0%\/*} +package_root=${arch_bin_dir%\/*} + +app_name=$appname$ + +os_type=`uname -s` + +arch_type=`uname -m` + +grepcmd=`which grep` +sedcmd=`which sed` + + +verbose= +jre_to_use="/usr/intel/pkgs/java/1.6.0.25-64"; +jre_args= +max_heap_size= +min_heap_size= +run_debugger= +debug_suspend=1 +terminal= +debug_env=0 +class_cache= +strace_output= +strace_dep_target= +strace_regex='"*"' +d64= + +command_args= +for arg in "$@" ; do + + case "$arg" in + --script-verbose ) + verbose=1 + ;; + --jre=* ) + jre_to_use=`echo $arg | $sedcmd -e "s/--jre=//"` + ;; + --jre-args=* ) + jre_args=`echo $arg | $sedcmd -e "s/--jre-args=//"` + ;; + --max-heap-size=* ) + max_heap_size=`echo $arg | $sedcmd -e "s/--max-heap-size=//"` + ;; + --min-heap-size=* ) + min_heap_size=`echo $arg | $sedcmd -e "s/--min-heap-size=//"` + ;; + --64 ) + d64=1 + ;; + --strace-regex=* ) + strace_regex=`echo $arg | $sedcmd -e "s/--strace-regex=//"` + ;; + --strace-output=* ) + strace_output=`echo $arg | $sedcmd -e "s/--strace-output=//"` + ;; + --strace-dep-target=* ) + strace_dep_target=`echo $arg | $sedcmd -e "s/--strace-dep-target=//"` + ;; + --run-debugger ) + run_debugger=1 + ;; + --no-suspend-debugger ) + debug_suspend=0 + ;; + --terminal=* ) + terminal=`echo $arg | $sedcmd -e "s/--terminal=//"` + ;; + --debug-environment ) + debug_env=1 + ;; + --class-cache=* ) + class_cache=`echo $arg | $sedcmd -e "s/--class-cache=//"` + ;; + --fulcrum-pdk-root=* ) + fulcrum_pdk_root=`echo $arg | $sedcmd -e "s/--fulcrum-pdk-root=//"` + ;; + * ) + if [ -n "$command_args" ] ; then + command_args="$command_args \"$arg\"" + else + command_args="\"$arg\"" + fi + ;; + esac +done + +if [ -d $package_root/$os_type-$arch_type/lib ] ; then + libs_in_package=`find $package_root/$os_type-$arch_type/lib -follow -name "*.so" -type f` +else + libs_in_package= +fi + +if [ -n "$verbose" ] ; then + echo "Libraries in package:" + for lib in $libs_in_package ; do + echo $lib + done + echo "" +fi + +#case "$arch_type" in +# i?86 ) +# preload_libs="$jre_to_use/lib/i386/libjsig.so $preload_libs" +# ;; +#esac + +pre_load_str= +pre_load_list= +for lib in $preload_libs ; do + if [ -f $lib ] ; then + pre_load_str="$lib:$pre_load_str" + pre_load_list="$pre_load_list $lib" + fi +done + +if [ -n "$verbose" ] ; then + echo "Libraries to preload:" + for lib in $pre_load_list ; do + echo $lib + done + echo "" +fi + + +jarroot="$package_root/share/java" +# antlr jar handling + +antlr_jar= + +if [ -z $ANTLR_JAR ] ; then + antlr_jar=$jarroot/antlr-2.7.2.jar +else + antlr_jar=$ANTLR_JAR +fi + +if [ -n "$verbose" ] ; then + echo "Antlr JAR file is \"$antlr_jar\"." +fi + +# concurrent util jar handling + +concurrent_jar= + +if [ -z $CONCURRENT_JAR ] ; then + concurrent_jar=$jarroot/concurrent.jar +else + concurrent_jar=$CONCURRENT_JAR +fi + +if [ -n "$verbose" ] ; then + echo "Concurrent util JAR file is \"$concurrent_jar\"." +fi + +# stringtemplate jar handling + +stringtemplate_jar= + +if [ -z $STRINGTEMPLATE_JAR ] ; then + stringtemplate_jar=$jarroot/stringtemplate.jar +else + stringtemplate_jar=$STRINGTEMPLATE_JAR +fi + +if [ -n "$verbose" ] ; then + echo "stringtemplate JAR file is \"$stringtemplate_jar\"." +fi + +# tools jar handling + +tools_jar= + +if [ -z $TOOLS_JAR ] ; then + tools_jar="$jarroot/tools.jar" +else + tools_jar=$TOOLS_JAR +fi + +if [ -n "$verbose" ] ; then + echo "tools JAR file is \"$tools_jar\"." +fi + +jars_in_package= + +if [ -d "$jarroot" ] ; then + jars_in_package=`find "$jarroot" -follow -name "*.jar" "(" -type f -o -type l ")"` +fi + +if [ -n "$verbose" ] ; then + echo "Jars in package:" + for jar in $jars_in_package ; do + echo $jar + done + echo "" +fi + +class_path=$antlr_jar:$concurrent_jar:$stringtemplate_jar:$jdom_jar:$xerces_jar + +if [ -n "$class_cache" ] ; then + class_path="$class_path:$class_cache" +fi + +for jar in $jars_in_package ; do + class_path="$class_path:$jar" +done + +if [ -n "$verbose" ] ; then + echo "CLASSPATH is \"$class_path\"." +fi + +if [ "$arch_type" == "x86_64" ]; then + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib:/usr/lib64:/lib64" +else + exec_str="LD_LIBRARY_PATH=$package_root/$os_type-$arch_type/lib:/usr/local/lib:/usr/lib:/lib" +fi + +if [ -n "$pre_load_str" ] ; then + exec_str="$exec_str LD_PRELOAD=$pre_load_str" +fi + +if [ -n "$terminal" ] ; then + TERM=$terminal + export TERM + exec_str="$exec_str TERM=$terminal" +fi + +if [ -n "$strace_output" ] ; then + strace_dump=`mktemp /tmp/strace.XXXXXX` + if [ "$os_type" == "SunOS" ] ; then + trace_cmd="truss -o $strace_dump -t open -t _exit" + elif [ "$os_type" == "Linux" ] ; then + trace_cmd="strace -o $strace_dump -e trace=open,_exit" + fi + exec_str="$exec_str $trace_cmd" +fi + +if [[ "$debug_env" == "1" ]] ; then + print_env_str="$exec_str printenv" +fi + +exec_str="$exec_str $jre_to_use/bin/java" + +if [ -n "$max_heap_size" ] ; then + exec_str="$exec_str -Xmx$max_heap_size" +fi + +if [[ -n "$d64" && "$os_type" == "SunOS" ]] ; then + exec_str="$exec_str -d64" +fi + +if [ -n "$min_heap_size" ] ; then + exec_str="$exec_str -Xms$min_heap_size" +fi + +if [ -n "$run_debugger" ] ; then + + debug_str="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y" + + if [[ "$debug_suspend" == "1" ]] ; then + debug_str="$debug_str,suspend=y" + else + debug_str="$debug_str,suspend=n" + fi + exec_str="$exec_str $debug_str" +fi + +if [ -n "$class_path" ] ; then + exec_str="$exec_str -classpath $class_path" +fi + +if [ -n "$jre_args" ] ; then + exec_str="$exec_str $jre_args" +fi + +exec_str="$exec_str $app_name \"--package-root=$package_root\" $command_args" + +if [ -n "$fulcrum_pdk_root" ] ; then + exec_str="$exec_str --config=$fulcrum_pdk_root/share/Fulcrum/jauto/jauto.config --config=$fulcrum_pdk_root/share/Fulcrum/jauto/process.config" +else + echo "--fulcrum-pdk-root= must be specified" + exit 1 +fi + +if [ -n "$verbose" ] ; then + echo "eval $exec_str" +fi + +eval $exec_str +ret=$? + +if [[ "$debug_env" == "1" ]] ; then + if [ -n "$verbose" ] ; then + echo "eval $print_env_str" + fi + eval $print_env_str +fi + +if [ -n "$strace_output" ] ; then + cat "$strace_dump" | $grepcmd "$strace_regex" | $sedcmd -e "s/open(\"\(.*\)\".*/\1/" > "$strace_output" + ret=$(grep "^_exit" "$strace_dump" | sed -e "s/_exit(\([0-9]*\)).*/\1/" ) + if [ -n "$strace_dep_target" ] ; then + echo -n 'AUTODEP_TARGET_FILES := ' > "$strace_dump" + echo "$strace_dep_target" | sed -e "s/\#/\\\#/g" >> "$strace_dump" + echo -n '$(AUTODEP_TARGET_FILES): ' >> "$strace_dump" + cat "$strace_output" | $grepcmd -v "$strace_dep_target" | sed -e "s/\#/\\\#/g" | awk '{print $1 "\\"}' >> "$strace_dump" + echo '' >> "$strace_dump" + cp "$strace_dump" "$strace_output" + fi +fi + +exit $ret diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/AbstractDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/AbstractDevice.java new file mode 100644 index 0000000000..0fb0b7a419 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/AbstractDevice.java @@ -0,0 +1,74 @@ +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id:$ + */ + +package com.avlsi.tools.jfast; + +import com.avlsi.tools.dsim.DigitalScheduler; +import com.avlsi.tools.dsim.Event; + +/** + * Class for ... + * + * @author Dan Daly + * @version $Date:$ + **/ + +public abstract class AbstractDevice implements Event{ + + protected static final int METHMASK = 1<<15; + /** For the eventqueue, -1 is not queued **/ + private int index=-1; + + /** The next time we should fire **/ + private long nextTime=0; + + /** The next program point to start at **/ + protected int pc=0; + + private final InterruptedException intex; + /** + * Constructor. + **/ + public AbstractDevice(String name, boolean suppressOutput) { + intex = new InterruptedException(name+"'s interrupt"); + } + + public void Wait(long t) throws InterruptedException { + this.nextTime = DigitalScheduler.get().getTime()+t; + pc++; + DigitalScheduler.get().addEvent(this); + throw intex; + //return true; + } + + public void fire() { + index = -1; + try { + go(); + } catch (InterruptedException e) { + //This means the module has context switched + //System.out.println("Caught "+e.getMessage()); + } + } + + public abstract void go() throws InterruptedException; + + public void start() { DigitalScheduler.get().addEvent(this); } + + /** Returns current index as set by the scheduler. **/ + public int getIndex() { return index; } + /** Sets current index (by the scheduler). -1 indicates not scheduled. **/ + public void setIndex(int _index) { + index = _index; + } + /** Returns the next time that we should fire. **/ + public long getTime() { return nextTime; } + /** Returns whether we should fire at a random time. **/ + public boolean isRandom() { return false; } + /** sets whether we should fire at a random time. **/ + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/BenchMarkJfast.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/BenchMarkJfast.java new file mode 100644 index 0000000000..62b0b2bb86 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/BenchMarkJfast.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id:$ + */ + +package com.avlsi.tools.jfast; + +/** + * Class for ... + * + * @author Dan Daly + * @version $Date:$ + **/ +public class BenchMarkJfast { + /** + * Constructor. + **/ + + static final int duration = 0xFFF000; + static final int num_dev = 1; + + public static void main(String[] args) { + + AbstractDevice[] A = new AbstractDevice[num_dev]; + AbstractDevice[] B = new AbstractDevice[num_dev]; + for (int loop=0;loop 0 ) { + accum *= b; + --b; + } + } + + //System.out.print("-"); + wait(3); + case 1: pc = 1; + //System.out.print(">"); + default: pc = 0; + } + } + } + }; + + B[loop] = new AbstractDevice("B"+loop, false) { + + public void go() throws InterruptedException { + + while (true) { + switch(pc) { + case 0: + if (com.avlsi.tools.dsim.DigitalScheduler + .get().getTime() > duration) { + //System.out.println(""); + System.exit(1); + } + wait(10); + case 1: pc = 1; + //System.out.print("."); + default: pc = 0; + } + } + } + }; + //com.avlsi.tools.dsim.DigitalScheduler.get().setVerbose(true); + A[loop].start(); + B[loop].start(); + } + com.avlsi.tools.dsim.SchedulerRunner.get().start(); + } + +} + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/TestDevice.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/TestDevice.java new file mode 100644 index 0000000000..6e46ce523f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jfast/TestDevice.java @@ -0,0 +1,126 @@ +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id:$ + */ + +package com.avlsi.tools.jfast; + +/** + * Class for ... + * + * @author Dan Daly + * @version $Date:$ + **/ +public class TestDevice extends AbstractDevice { + + //private BufferedChannel input, output; + + private static int duration = 0xFFF000; + + + public TestDevice(String name, boolean suppressOutput//, + //BufferedChannel input, BufferedChannel output) { + ) { + super(name, suppressOutput); + //this.input = input; + //this.output = output; + } + + private int __tempVal_doSomeSending_loop; + private int __tempParam_doSomeSending_count; + private int doSomeSending_for_1_pc=0; + private void doSomeSending(int count) + throws InterruptedException { + __tempParam_doSomeSending_count = count; + switch(doSomeSending_for_1_pc) { + case 0: + __tempVal_doSomeSending_loop=0; + case 1: + if (doSomeSending_for_1_pc == 1) + __tempVal_doSomeSending_loop++; + doSomeSending_for_1_pc = 1; + if (!( __tempVal_doSomeSending_loop < + __tempParam_doSomeSending_count)) { + //System.out.println(__tempVal_doSomeSending_loop+"<"+ + // __tempParam_doSomeSending_count); + break; + } else pc--; //Return here next time pc + //send(output, in); + //System.out.print("l"); + Wait(2); + } + doSomeSending_for_1_pc = 0; + } + + //private Message __tempVal_go_m; + + private int __tempMeth_go_If_else_1_pc = 0; + private void __tempMeth_go_If_else_1() + throws InterruptedException { + switch (__tempMeth_go_If_else_1_pc) { + case 0: + doSomeSending(3); + case 1: __tempMeth_go_If_else_1_pc = 1; + //System.out.println( + //"Sending some junk"); + //System.out.print("J"); + default: __tempMeth_go_If_else_1_pc= 0; + } + } + + private int __tempVal_go_a; + public void go() throws InterruptedException { + + while (true) { + //System.out.println("pc= "+pc); + switch(pc) { + case 0: + //__tempVal_go_m = receive(input); + Wait(10); + case 1: pc = 1; + //System.out.println("I got "+message); + //System.out.print("M"); + //if (m.intValue() == 10) { + if (false) { + //System.out.println( + //"Gee Not Sending at 10"); + } else { + pc = 1*METHMASK+2; + continue; + } + + case 2: pc = 2; + __tempVal_go_a = 5; //Computation + __tempVal_go_a += 2; // + + //send(output, a); + Wait(__tempVal_go_a); + case 3: pc = 3; + //System.out.println("Finished Sending "+a); + //System.out.print("a"); + if (com.avlsi.tools.dsim.DigitalScheduler.get() + .getTime() > duration) { + //System.out.println(""); + System.exit(1); + } + default: pc = 0; + break; + case 1*METHMASK+2: + __tempMeth_go_If_else_1(); + pc = pc & (METHMASK-1); + break; + } + } + } + + public static void main(String[] args) { + + TestDevice t = new TestDevice("test1", false); + + t.start(); + com.avlsi.tools.dsim.SchedulerRunner.get().start(); + } + +} + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/JFlat.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/JFlat.java new file mode 100644 index 0000000000..ef76be3171 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/JFlat.java @@ -0,0 +1,4999 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2000 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.jflat; + + +import java.util.Arrays; +import java.util.Comparator; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.HashSet; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import com.avlsi.cast.CastCacheManager; +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.AlintFaninValue; +import com.avlsi.cast.impl.CellInterfaceCollectionIterator; +import com.avlsi.cast.impl.NodeValue; +import com.avlsi.cast.impl.LocalEnvironment; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.TupleValue; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cell.CellDelay; +import com.avlsi.cell.CellImpl; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.ChildrenFirstCellInterfaceIterator; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.cell.NoSuchEnvironmentException; +import com.avlsi.csp.csp2java.CSP2Class; +import com.avlsi.csp.csp2java.NoCSPBlockException; +import com.avlsi.csp.csp2java.SemanticException; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.EnvBlock; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.file.cdl.parser.LVSNodesCDLFactory; +import com.avlsi.file.cdl.parser.LVSNodesNullHandler; +import com.avlsi.file.cdl.util.CDLWriter; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameFactory; +import com.avlsi.file.cdl.util.rename.TrivialCDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLNameInterfaceFactory; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; +import com.avlsi.file.cdl.util.rename.ReloadableNameInterface; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.NullWriter; +import com.avlsi.io.IndentWriter; +import com.avlsi.io.SearchPathFile; +import com.avlsi.io.TrivialSearchPathFile; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.jauto.PartialExtract; +import com.avlsi.tools.cosim.CoSimParameters; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.AndBooleanExpressionInterface; +import com.avlsi.util.bool.OrBooleanExpressionInterface; +import com.avlsi.util.bool.HierNameAtomicBooleanExpression; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.exception.AssertionFailure; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.SortingIterator; +import com.avlsi.util.container.StringRepComparator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.container.Triplet; +import com.avlsi.util.container.StringContainerIterator; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgFormatException; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsUtil; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.text.StringUtil; +import com.avlsi.tools.dsim.InstanceData; +import com.avlsi.tools.jauto.CastQuery.LocalNodes; +import com.avlsi.tools.jauto.CastQuery; + +import java.text.MessageFormat; +import com.avlsi.layout.SkillDirectiveEmitter; +import com.avlsi.layout.LVSNodes; +import com.avlsi.layout.LVSNodesForExtract; +import com.avlsi.cast2.util.DirectiveWalker; +import com.avlsi.cast2.util.DirectiveActionInterface; +import com.avlsi.cast2.directive.impl.DirectiveEmitter; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryInterface; +import com.avlsi.file.cdl.parser.CDLFactoryEmitter; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.tools.jauto.Cast2Cdl; +import com.avlsi.util.container.ObjectUtils; + +/** + * Java re-implementation of cflat. + *

    + * Supports two modes: + *

      + *
    1. lvs: flattens cell hierarchy, prints prs and connections + *
    2. csim: flattens cell hierarchy, prints prs and connections in the + * csim format, suitable for the dsim program. + *
    3. auto: prints prs and connections only in the top cell. + *
    4. instance: prints the names and types of all instantiated cells + *
    + *

    + * Optionally, a specified cell type may be processed, rather + * than the default of the environment cell. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public final class JFlat { + /** + * This class should not be instantiated. + **/ + private JFlat() { } + + /** + * Prints usage message and exits with the specified status. + **/ + private static void usage( String m ) { + System.err.println("Usage:\n" + + " [ --cast-path=castpath ]\n" + + " [ --cast-version=1 | --cast-version=2 ]\n" + + " [ --verbose | --no-verbose ]\n" + + " [ --print-stack-trace ]\n" + + " [ --output-file=file | --output-dir=dir]\n" + + " [ --cast-deps=file --cast-deps-target=file ] " + + " [ --output-suffix=string \n" + + " [ --cell=cellname[:env|*] | --module=mod.ule ]\n" + + " [ --routed ]\n" + + " [ --tool=newlvs | --tool=newauto | --tool=dsim\n" + + " | --tool=lvs | --tool=auto | --tool=instance\n" + + " | --tool=aspice [--internalWires] [--internalRules]\n" + + " | --tool=check [--check-all-csp]\n" + + " | --tool=new-aspice [--internalRules=[0|1]]\n" + + " | --tool=hsim [ --hsim-translate=[ cadence | gds2 | none ]\n" + + " --hsim-isolate-cell --hsim-rand-seed= --hsim-rand-length= ]\n" + + " | --tool=cdl [ --cdl-translate=[ cadence | gds2 | none ]\n" + + " [ --cdl-name-map= ]\n" + + " [ --cdl-mos-parameters= ]\n" + + " | --tool=cosim --cosim-merge= [ --cosim-analog= ]\n" + + " | --tool=env-ntpc \n" + + " | --tool=local-nodes [ --nodes= ] \n" + + " | --tool=dynamic-nodes\n" + + " | --tool=signature \n" + + " | --tool=fanout [ --ignore-feedback ]\n" + + " | --tool=fanin [ --ignore-feedback ]\n" + + " [ --tool=query --query-tasks=\n" + + " --query-filter=\n" + + " --query-no-recurse\n" + + " --query-translate=[ cadence | gds2 | none ]\n" + + " --query-no-header\n" + + " --query-separator= ]\n" + + " [ [--all-cells ] file.cast ]"); + if (m != null && m.length() > 0) + System.err.print( m ); + System.exit(1); + } + + private static void usage() { + usage( null ); + } + + + private interface CellFormatterFactory { + CellFormatterInterface getFormatter(String toolName, String cellName, String envName); + } + + private static abstract class SimpleCellFormatterFactory implements CellFormatterFactory { + private final PrintWriterFactory pwf; + public SimpleCellFormatterFactory(PrintWriterFactory pwf) { + this.pwf = pwf; + } + public CellFormatterInterface getFormatter(String toolName, String cellName, String envName) { + final Pair pw = + pwf.getPrintWriter(toolName,cellName,envName); + return getFormatter(pw.getFirst()); + } + public abstract CellFormatterInterface getFormatter(PrintWriter pw); + } + + private interface PrintWriterFactory { + Pair + getPrintWriter(String toolName, String cellName, String envName); + } + + private static class FilePrintWriterFactory implements PrintWriterFactory { + private final PrintWriter pw; + private final File file; + public FilePrintWriterFactory(File file) throws IOException { + this.file = file; + this.pw = new PrintWriter( new BufferedWriter( new FileWriter( file ) ) ); + } + public Pair getPrintWriter(String toolName, String cellName, String envName) { + return new Pair(pw, file); + } + } + + private static class SimplePrintWriterFactory implements PrintWriterFactory { + private final PrintWriter pw; + public SimplePrintWriterFactory(PrintWriter pw) { + this.pw = pw; + } + public Pair getPrintWriter(String toolName, String cellName, String envName) { + return new Pair(pw, null); + } + } + + private static CellFormatterFactory + getCellFormatterFactory( final String tool, + final String castVersion, + final PrintWriterFactory pwf, + final CastFileParser castParser, + final CommandLineArgs args, + final PartialExtract.CellPlusMinus fqcnSpec, + final Cadencize cadencizer, + final Cadencize cdlCadencizer ) + throws CommandLineArgFormatException { + if (tool.equals("newlvs")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new LVSFormatter(pw, false, cadencizer ); + } + }; + } else if (tool.equals("newauto")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new AutoFormatter(pw, cadencizer ); + } + }; + } else if (tool.equals("lvs")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new OldLVSFormatter(pw,cadencizer); + } + }; + } else if (tool.equals("auto")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new OldAutoFormatter(pw, cadencizer); + } + }; + } else if (tool.equals("instance")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new InstanceFormatter(pw); + } + }; + } else if (tool.equals("signature")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new SignatureFormatter(pw, castParser, cadencizer ); + } + }; + } else if (tool.equals("aspice")) { + final boolean iw = args.argExists("internalWires"); + final boolean ir = args.argExists("internalRules"); + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new AspiceFormatter(pw, iw, ir, fqcnSpec, castParser, cadencizer, false ); + } + }; + } else if (tool.equals("new-aspice")) { + final Integer ir = CommandLineArgsUtil.getIntegerArgValue(args, + "internalRules", new Integer(1)); + final String appendColon = + args.argExists("no-append-colon") ? "" : ":"; + return new CellFormatterFactory() { + public CellFormatterInterface getFormatter(String toolName, + String cellName, + String envName){ + try { + final CellInterface cell = + castParser.getFullyQualifiedCell( cellName ); + final CellInterface envCell = + (envName == "default") ? null : + cell.getEnvironment( envName ); + + // Honor aspice-ignore directive here + // by not returning a formatter + if( ( envCell != null && ((Boolean) DirectiveUtils.getEnvDirective(envCell, DirectiveConstants.ASPICE_IGNORE)).booleanValue() ) || + ((Boolean) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.ASPICE_IGNORE)).booleanValue()) { + return null; + } + } catch (Exception e) { + throw new RuntimeException("Cannot load cell: " + cellName, e); + } + + if (envName.equals("default")) { + final PrintWriter pw1 = (PrintWriter) + pwf.getPrintWriter("aspice", + cellName, + envName + + File.separator + "prs.asp") + .getFirst(); + final CellFormatterInterface f1 = + new NewAspiceFormatter(pw1, + true, + ir.intValue() != 0, + fqcnSpec, + null, + castParser, + cadencizer, + false, + appendColon); + final PrintWriter pw2 = (PrintWriter) + pwf.getPrintWriter("aspice", + cellName, + envName + + File.separator + "noprs.asp") + .getFirst(); + final Pair modifyPair; + final PartialExtract.CellPlusMinusKeyword partialSimSpec; + if (fqcnSpec.isEmpty()) { + partialSimSpec = + new PartialExtract.CellPlusMinusKeyword( + cellName + "-+localportnodes", + PartialExtract.Info.INCLUDE); + modifyPair = + pwf.getPrintWriter("aspice", cellName, + envName + File.separator + + "noprs.modify.asp"); + } else { + partialSimSpec = null; + modifyPair = null; + } + + final CellFormatterInterface f2 = + new NewAspiceFormatter(pw2, + modifyPair, + true, + false, + fqcnSpec, + partialSimSpec, + castParser, + cadencizer, + false, + appendColon); + return new AggregateFormatter(f1, f2); + } else { + final PrintWriter pw = (PrintWriter) + pwf.getPrintWriter("aspice", cellName, envName + File.separator + "env.asp").getFirst(); + return new NewAspiceFormatter(pw, true, true, fqcnSpec, null, castParser, cadencizer, false, appendColon); + } + } + }; + } else if (tool.equals("dsim")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new AspiceFormatter( pw, true, true, fqcnSpec, + castParser, cadencizer, + true ); + } + }; + } else if (tool.equals("new-dsim")) { + final String appendColon = + args.argExists("no-append-colon") ? "" : ":"; + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new NewAspiceFormatter( pw, true, true, fqcnSpec, + null, castParser, + cadencizer, true, + appendColon); + } + }; + } else if (tool.equals("local-nodes") || tool.equals("node-props")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + final String nodesStr = + args.getArgValue("nodes", ""); + final Set nodes = (nodesStr.equals("")) ? null : + new HashSet(Arrays.asList( nodesStr.split(","))); + return new LocalNodesFormatter(pw,castParser,cadencizer,tool.equals("node-props"),nodes); + + } + }; + } else if (tool.equals("local-aliases")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new LocalAliasesFormatter(pw,castParser,cadencizer); + + } + }; + } else if (tool.equals("leaky-nodes")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new LeakyNodesFormatter(pw,castParser,cadencizer); + + } + }; + } else if (tool.equals("alint-scenarios")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new AlintScenariosFormatter(pw, cadencizer); + + } + }; + } else if (tool.equals("cdl")) { + + final String renameStr = + args.getArgValue("cdl-translate", "cadence"); + final CDLNameInterface nameInterface; + if(renameStr.equals("cadence")) { + nameInterface = new CadenceNameInterface( true ); + } + else if(renameStr.equals("gds2")) { + nameInterface = new GDS2NameInterface(); + } + else { + nameInterface = new IdentityNameInterface(); + } + + final String argNameMap = args.getArgValue("cdl-name-map", null); + final String argPdkRoot = args.getArgValue("fulcrum-pdk-root", null); + String nameMap = null; + if (argPdkRoot != null && argNameMap == null) { + nameMap = argPdkRoot + "/share/Fulcrum/lve/transistor.map"; + } + else if (argNameMap != null) { + nameMap = argNameMap; + } + final CDLNameInterface mapNamer; + if (nameMap == null) { + mapNamer = nameInterface; + } else { + mapNamer = new ReloadableNameInterface(nameInterface); + try { + final FileReader r = new FileReader((String) nameMap); + ((ReloadableNameInterface) mapNamer).load(r); + r.close(); + } catch (IOException e) { + System.err.println("Cannot read from CDL name map file " + + nameMap + ": " + e.getMessage()); + return null; + } catch (ReloadableNameInterface.FileFormatException e) { + System.err.println("CDL name map file " + nameMap + + " is invalid: " + e.getMessage()); + return null; + } + } + + final CDLNameInterfaceFactory nameInterfaceFactory = + new TrivialCDLNameInterfaceFactory(mapNamer); + + final String mosParamStr = + args.getArgValue("cdl-mos-parameters", null); + final String[] mosParams = + mosParamStr == null ? null + : StringUtil.split(mosParamStr, ','); + + return new CellFormatterFactory () { + public CellFormatterInterface + getFormatter(String toolName, + String cellName, + String envName) { + if ( envName == "default" ) { + final PrintWriter pw = (PrintWriter) + pwf.getPrintWriter("cdl", cellName, envName) + .getFirst(); + // Use a new instance of Cadencize, because the + // CDLFormatter never takes into account routed + return new CDLFormatter( + pw, fqcnSpec, castParser, nameInterfaceFactory, + mosParams, + cdlCadencizer); + } else { + return null; + } + } + }; + } else if (tool.equals("hsim")) { + final String lenStr = args.getArgValue("hsim-rand-length", "10"); + final String seedStr = args.getArgValue("hsim-rand-seed", "0"); + final int len; + final long seed; + try { + len = Integer.parseInt(lenStr); + seed = Long.parseLong(seedStr); + } catch (NumberFormatException e) { + System.err.println("Invalid rand-length or rand-seed options specified."); + return null; + } + final boolean isolateCell = args.argExists("hsim-isolate-cell"); + final String renameStr = args.getArgValue("hsim-translate", "cadence"); + final CDLNameInterface renamer; + if (renameStr.equals("cadence")) { + renamer = new CadenceNameInterface(true); + } else if (renameStr.equals("gds2")) { + renamer = new GDS2NameInterface(); + } else if (renameStr.equals("none")) { + renamer = new IdentityNameInterface(); + } else { + System.err.println("Invalid name translator specified: " + renameStr); + return null; + } + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new HSIMFormatter(pw, castParser, len, seed, isolateCell, renamer, cadencizer ); + } + }; + } else if (tool.equals("env-ntpc")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new EnvNTPCFormatter(pw, cadencizer); + } + }; + } else if (tool.equals("check")) { + final boolean checkAll = args.argExists("check-all-csp"); + final boolean verbose = args.argExists("verbose"); + return new CellFormatterFactory () { + public CellFormatterInterface getFormatter(String toolName, + String cellName, + String envName) { + return new CheckFormatter(checkAll, verbose); + } + }; + } else if (tool.equals("cosim")) { + final String mergeCell = args.getArgValue("cosim-merge", null); + if (mergeCell == null) { + System.err.println("cosim-merge must be specified"); + return null; + } + final String analogCell = args.getArgValue("cosim-analog", null); + if (analogCell == null) { + System.err.println("cosim-analog must be specified"); + return null; + } + + final CellInterface merge; + try { + merge = castParser.getFullyQualifiedCell(mergeCell); + } catch (Exception e) { + throw new RuntimeException("Cannot load cell: " + mergeCell, e); + } + + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + return new CosimFormatter(pw, analogCell, merge, cadencizer ); + } + }; + } + else if ( tool.equals( "query" ) ) { + final String tasks = args.getArgValue( "query-tasks", "" ); + final String filter = args.getArgValue( "query-filter", "" ); + final String prune = args.getArgValue( "query-prune", "" ); + final boolean noRecurse = args.argExists( "query-no-recurse" ); + final String translatorName = args.getArgValue( "query-translate", "none" ); + final boolean noHeader = args.argExists( "query-no-header" ); + // accept misspelled arg and correctly spelled arg too + final String sep; + if ( args.argExists( "query-seperator" ) ) + sep = args.getArgValue( "query-seperator", ","); + else + sep = args.getArgValue( "query-separator", ","); + + return new SimpleCellFormatterFactory( pwf ) { + public CellFormatterInterface getFormatter( final PrintWriter pw ) { + return new SimpleCellFormatter() { + public void outputCell( final CellInterface cell, + final CellInterface envCell ) { + if ( envCell == null ) { + try { + CastQuery.query( castParser, + cell, + tasks, + filter, + prune, + noRecurse, + translatorName, + noHeader, + false, + sep, + pw ); + } + catch ( RecognitionException e ) { + throw new RuntimeException( e ); + } + catch ( TokenStreamException e ) { + throw new RuntimeException( e ); + } + catch ( IOException e ) { + throw new RuntimeException( e ); + } + catch ( CastSemanticException e ) { + throw new RuntimeException( e ); + } + } + } + public CellInterface prepCell( final CellInterface cell ) { + return cell; + } + }; + } + }; + } else if (tool.equals("fanout") || tool.equals("fanin")) { + return new SimpleCellFormatterFactory(pwf) { + public CellFormatterInterface getFormatter(PrintWriter pw) { + final String nodesStr = args.getArgValue("nodes", ""); + final Set nodes = (nodesStr.equals("")) ? null : + new HashSet(Arrays.asList(nodesStr.split(":"))); + return tool.equals("fanin") ? + new FaninFormatter (pw, castParser, cdlCadencizer, + nodes, args.argExists("ignore-feedback"), + args.argExists("routed")) : + new FanoutFormatter(pw, castParser, cdlCadencizer, + nodes, args.argExists("ignore-feedback"), + args.argExists("routed")); + + } + }; + } + usage(); + return null; // Sop to the compiler. + } + + /** + * Given a cell and the name of an environment, return the specified + * environment, or return null if the environment does not + * exist. + **/ + private static CellInterface getEnvironment(final CellInterface cell, + final String name) { + try { + return cell.getEnvironment(name); + } catch (NoSuchEnvironmentException e) { + return null; + } + } + + /** + * Main method. + **/ + public static void main(String[] args) throws Exception { + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + // pick apart the command line + + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString(JFlat.class)); + } + + final String toolNames = theArgs.getArgValue("tool", null ); + + final String cellAndEnv = theArgs.getArgValue("cell", null ); + final String moduleName = theArgs.getArgValue("module", null ); + final String castVersion= theArgs.getArgValue("cast-version",null); + final String outputFile = theArgs.getArgValue("output-file",null ); + final String outputDir = theArgs.getArgValue("output-dir",null ); + final String castDepsFile = theArgs.getArgValue("cast-deps", null); + final String castDepsTarget = theArgs.getArgValue("cast-deps-target", castDepsFile); + final String outputSuffix = theArgs.getArgValue("output-suffix","" ); + final boolean verbose = ! theArgs.argExists("no-verbose"); + final boolean routed = theArgs.argExists("routed"); + final boolean printStackTrace = theArgs.argExists("print-stack-trace"); + + /** @review jmr Should we use --cell=mod.ule.* for --module? **/ + if ((cellAndEnv != null) && (moduleName != null)) { + usage ("Can't specify both --cell and --module\n"); + } + + final Collection castDeps = new HashSet(); + final FileSearchPath.SearchPathFileFactory spfFactory; + if (castDepsFile == null) { + spfFactory = new FileSearchPath.DefaultSearchPathFileFactory(); + } else { + spfFactory = new FileSearchPath.TrackingSearchPathFileFactory(castDeps); + } + + final FileSearchPath castSearchPath = + new FileSearchPath( theArgs.getArgValue( "cast-path", "." ), + System.getProperty( "user.home" ), + spfFactory ); + + final boolean doAllCells= theArgs.argExists("all-cells"); + + if ( toolNames == null || ! pedanticArgs.pedanticOK( false, true )) { + usage( pedanticArgs.pedanticString() ); + } + + final PrintWriterFactory pwFactory; + + if ( outputFile != null ) { + pwFactory = new FilePrintWriterFactory( new File(outputFile) ); + } + else if ( outputDir != null ) { + pwFactory = new PrintWriterFactory() { + public Pair + getPrintWriter(String toolName, String cellName, + String envName ) { + Pair ret; + try { + final File dir = new File(outputDir, toolName); + final File file = new File(dir,envName+outputSuffix); + final File fileDir = file.getParentFile(); + if (fileDir != null) fileDir.mkdirs(); + ret = new Pair(new PrintWriter( new BufferedWriter( new FileWriter( file ) ) ), file ); + } catch( IOException e ) { + throw new RuntimeException(e); + } + return ret; + } + }; + } + else { + pwFactory = new SimplePrintWriterFactory( new PrintWriter(System.out) ); + } + + final Cadencize cadencizer = new Cadencize( true ); + + // Cadencize instance used for cdl and fanout tasks, which do not want + // a routed view and needs the netlist block to have priority + final Cadencize cdlCadencizer = + new Cadencize(true, Cadencize.NETLIST_PRIORITY); + + final CastFileParser castParser = + CastCacheManager.getDefault().getCastFileParser( + castSearchPath, castVersion, verbose, + new StandardParsingOption(theArgs)); + + //try everything we do with a castParser + //and catch CastSemanticException so we can pretty print + try { + // split cellAndEnv into cellName and envName + + final PartialExtract.CellPlusMinusKeyword fqcnSpec; + boolean fqcnSpecInit; + final String cellName; + final String envName; + if (cellAndEnv == null) { + fqcnSpec = null; + cellName = null; + envName = null; + fqcnSpecInit = true; + } else { + fqcnSpec = new PartialExtract.CellPlusMinusKeyword(cellAndEnv, PartialExtract.Info.INCLUDE); + cellName = fqcnSpec.getTop(); + envName = fqcnSpec.getEnvironment(); + fqcnSpecInit = false; + } + + final Map toolMap = new HashMap(); + final String[] tools = toolNames.split(","); + for(int i=0; i= 0 ) { + //We have fully qualified cell name, thus we let + //CastFileParser figure out which cast file to + //parse and return a CellInterface. + cellToProcess = castParser.getFullyQualifiedCell( cellName ); + } + else { + //The cell name was not fully qualified. + + //Make sure that they gave the name of a file + //in which to find the cell they asked for. + if ( castFileName == null ) { + usage(); + } + + //Parse the cast file that was specified, and get + //a CellInterface for the cell they asked for. + final CastFile cf = castParser.parse(castFileName); + cellToProcess = cf.getCell(cellName); + } + if (envName != null && envName.equals("*")) { + EnvBlock envBlock = cellToProcess.getEnvironments(); + cellEnvSet.add( new Triplet(cellToProcess, getEnvironment(cellToProcess, "default") ,"default")); + Set envs = new HashSet(); + for (Iterator i = envBlock.getNames(); i.hasNext(); ) { + // get the environment name + final String existingEnvName = (String) i.next(); + envs.add(existingEnvName); + // get the environment cell + final CellInterface existingEnvCell = + envBlock.getNamedEnvironment(existingEnvName); + cellEnvSet.add( new Triplet(cellToProcess,existingEnvCell,existingEnvName)); + } + if (!envs.contains("leakage")) { + final CellInterface existingEnvCell = + envBlock.getNamedEnvironment("leakage"); + if (existingEnvCell != null) { + cellEnvSet.add( new Triplet(cellToProcess,existingEnvCell,"leakage")); + } + } + } + else { + if(envName != null) { + envCellToProcess = cellToProcess.getEnvironment(envName); + cellEnvSet.add( new Triplet(cellToProcess,envCellToProcess,envName) ); + } + else { + envCellToProcess = null; + cellEnvSet.add( new Triplet(cellToProcess,envCellToProcess,"default") ); + } + + } + } + else { + //No cell name was specified, thus get the CellInterface for + //the environment of the cast file they specified. + + //make sure a cast file name was specified. + if ( castFileName == null ) { + usage(); + } + + // do the parsing thang + final CastFile cf = castParser.parse(castFileName); + + // get the appropriate cell, either environment or named + final CellInterface cell; + cellToProcess = cf.getEnvironmentCell(); + envCellToProcess = getEnvironment(cellToProcess, "default"); + + cellEnvSet.add( new Triplet(cellToProcess,envCellToProcess,"default")); + } + } + } + else { + if ( castFileName == null ) { + usage(); + } + + final CastFile cf = castParser.parse( castFileName ); + CellInterfaceCollectionIterator cellsIter = cf.getAllCellsPossible(); + + while ( cellsIter.hasNext() ) { + final CellInterface currCellToProcess = cellsIter.next(); + cellEnvSet.add( new Triplet( currCellToProcess, null, "default") ); + } + } + final Map routedCells = new HashMap(); + for (Iterator i = cellEnvSet.iterator(); i.hasNext(); ) { + final Triplet cellEnvName = (Triplet) i.next(); + final CellInterface cell = + (CellInterface) cellEnvName.getFirst(); + final String type = cell.getFullyQualifiedType(); + if (!routedCells.containsKey(type)) { + routedCells.put(type, routed ? cell.routedSubcells(false) + : cell); + } + } + for (final Iterator j = toolMap.entrySet().iterator(); j.hasNext(); ) { + + Map.Entry tool_Formatter = (Map.Entry) j.next(); + final String toolName = (String) tool_Formatter.getKey(); + final CellFormatterFactory cellFormatterFactory = + (CellFormatterFactory) tool_Formatter.getValue(); + + for (final Iterator i = cellEnvSet.iterator(); i.hasNext(); ) { + final Triplet cellEnvName = (Triplet) i.next(); + final CellInterface cell = + (CellInterface) cellEnvName.getFirst(); + final CellInterface routedCell = (CellInterface) + routedCells.get(cell.getFullyQualifiedType()); + if (!fqcnSpecInit) { + fqcnSpec.initialize(cell, cadencizer); + fqcnSpecInit = true; + } + final CellInterface envCell = + (CellInterface) cellEnvName.getSecond(); + final String envCellName = + (String) cellEnvName.getThird(); + + final CellFormatterInterface formatter = + cellFormatterFactory. + getFormatter(toolName, + routedCell.getFullyQualifiedType(), + envCellName ); + if(formatter != null ) { + final CellInterface currPrepedCell = + formatter.prepCell(cell, routedCell); + formatter.outputCell(currPrepedCell,envCell); + } + } + } + + if (castDepsFile != null) { + final FileWriter w = new FileWriter(castDepsFile); + w.write("CASTDEP_TARGET := "+castDepsTarget+"\n"); + w.write("$(CASTDEP_TARGET) : \\\n"); + for (Iterator i = castDeps.iterator(); i.hasNext(); ) { + w.write(i.next() + " \\\n"); + } + w.close(); + } + } catch (CastSemanticException e) { + // Pretty print CAST exceptions + com.avlsi.tools.dsim.ExceptionPrettyPrinter.printException(e, System.err); + if (printStackTrace) e.printStackTrace(System.err); + System.exit(1); + } catch (NoSuchEnvironmentException e) { + System.err.println("Cannot instantiate environment " + + e.getEnvironmentName() + " from cell " + + e.getCellName()); + com.avlsi.tools.dsim.ExceptionPrettyPrinter.printException(e, System.err); + if (printStackTrace) e.printStackTrace(System.err); + System.exit(1); + } catch (CommandLineArgFormatException e) { + System.err.println("Invalid argument " + e.getMessage() + " for switch " + e.getArgName()); + System.exit(1); + } + } + + public interface CellProcessor { + void process( HierName prefix, CellInterface cell, + AliasedSet superNamespace, int depth, + final Cadencize cadencizer ); + } + + private interface CellFormatterInterface { + void outputCell(CellInterface cell, CellInterface envCell) + throws CellFormatterException, IOException; + CellInterface prepCell(CellInterface cell, CellInterface routed); + } + + private abstract static class SimpleCellFormatter + implements CellFormatterInterface { + public abstract void outputCell(CellInterface cell, + CellInterface envCell) + throws CellFormatterException, IOException; + public CellInterface prepCell(CellInterface cell, + CellInterface routed) { + return prepCell(routed); + } + public CellInterface prepCell(CellInterface cell) { + return cell; + } + } + + private static class CellFormatterException extends Exception { + CellFormatterException(final String message) { super(message); } + CellFormatterException() { super(); } + } + + private static HierName makeHierName(final String s, final char sep) { + try { + return HierName.makeHierName(s, sep); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName from " + s + + " with separator " + sep); + } + } + + private static HierName makeHierName(final String s) { + return makeHierName(s, '.'); + } + + /** + * Prints out any nodes with the ntpc_spec directive set, + * and their number of transitions per cycle. + **/ + private static class EnvNTPCFormatter extends SimpleCellFormatter { + private final PrintWriter pw; + private final Cadencize cad; + + public EnvNTPCFormatter(PrintWriter pw, Cadencize cad) { + this.pw = pw; + this.cad = cad; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + public void outputCell(CellInterface cell, CellInterface envCell) + throws IOException { + + if(envCell != null ) { + printEnvCell(cell, envCell, null); + } + else { + // for all environments + final EnvBlock envBlock = cell.getEnvironments(); + for (Iterator i = envBlock.getNames(); i.hasNext(); ) { + // get the environment name + final String envName = (String) i.next(); + // get the environment cell + final CellInterface env; + try { + env = envBlock.getNamedEnvironment(envName); + } catch (CastSemanticException e) { + throw new RuntimeException("Cannot load environment " + + envName, e); + } + + printEnvCell(cell, env, envName); + } + } + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + + private void printInfo(final String envName, + final HierName nodeName, + final Float ntpcVal, + final Float ntpcSignoffVal, + final Integer digitalCycles, + final Integer analogCycles, + final Float timeMax, + final HierName canonicalName + ) { + pw.println( ( envName == null ? "" : envName + " " ) + + nodeName.getAspiceString() + " " + + ( ntpcVal == null ? "-1" : "" + ntpcVal ) + " " + + ( ntpcSignoffVal == null ? "-1" : "" + ntpcSignoffVal ) + " " + + ( digitalCycles == null ? "-1" : "" + digitalCycles ) + " " + + ( analogCycles == null ? "-1" : "" + analogCycles ) + " " + + // the directive is specified in ns, we output in s + ( timeMax == null ? "-1" : "" + timeMax.floatValue() * 1e-9 ) + " " + + ( canonicalName == null ? nodeName.getAspiceString() + : canonicalName.getAspiceString()) ); + } + + private void printEnvCell(CellInterface cell, + CellInterface envCell, + String envName) throws IOException { + + // get all ntpc_spec nodes and print the ntpc value + final Map ntpcMap = + DirectiveUtils.scaleNtpcSpec + (cell, + DirectiveUtils.getEnvDirective + (envCell, + DirectiveConstants.NTPC_SPEC, + DirectiveConstants.NODE_TYPE ) ); + + final float scaleSignoff = + ((Float) DirectiveUtils.getTopLevelDirective + (cell, + DirectiveConstants.NTPC_SCALING_SIGNOFF)).floatValue(); + + final Map ntpcSignoffMap = + DirectiveUtils.scaleFloatMap + ( ntpcMap, + scaleSignoff ); + + final Map digitalCyclesMap = + DirectiveUtils.getMultipleBlockDirective + ( Arrays.asList( new BlockInterface[] + { cell.getBlockInterface(), + DirectiveUtils.getUniqueBlock + ( envCell.getBlockInterface(), + BlockInterface.ENV ) } ), + DirectiveConstants.ASPICE_DIGITAL_CYCLES, + DirectiveConstants.NODE_TYPE); + + final Map analogCyclesMap = + DirectiveUtils.getMultipleBlockDirective + ( Arrays.asList( new BlockInterface[] + { cell.getBlockInterface(), + DirectiveUtils.getUniqueBlock + ( envCell.getBlockInterface(), + BlockInterface.ENV ) } ), + DirectiveConstants.ASPICE_ANALOG_CYCLES, + DirectiveConstants.NODE_TYPE); + + final Set nodeSet = new HashSet(); + nodeSet.addAll(analogCyclesMap.keySet()); + nodeSet.addAll(digitalCyclesMap.keySet()); + nodeSet.addAll(ntpcMap.keySet()); + + final HierName cycleNode = + (HierName) DirectiveUtils.getEnvDirective + (envCell, + DirectiveConstants.CYCLE_NODE); + if(cycleNode != null ) nodeSet.add(cycleNode); + + final Float timeMax = (Float) DirectiveUtils.getEnvDirective + (envCell, + DirectiveConstants.ASPICE_TIME_MAX); + + final AliasedSet localNodes = cad.convert(cell).getLocalNodes(); + for (final Iterator i = + new SortingIterator( nodeSet.iterator() ); + i.hasNext(); ) { + final HierName nodeName = (HierName) i.next(); + printInfo(envName, + nodeName, + (Float)ntpcMap.get(nodeName), + (Float)ntpcSignoffMap.get(nodeName), + (Integer)digitalCyclesMap.get(nodeName), + (Integer)analogCyclesMap.get(nodeName), + timeMax, + (HierName) localNodes.getCanonicalKey(nodeName)); + } + } + } + + public static class CheckFormatter extends SimpleCellFormatter { + private final boolean checkAll; + private final boolean verbose; + public CheckFormatter(final boolean checkAll, final boolean verbose) { + this.checkAll = checkAll; + this.verbose = verbose; + } + + private void process(final boolean top, final Set seen, + final CellInterface cell) { + if (!seen.add(cell.getFullyQualifiedType())) return; + + final String type = cell.getFullyQualifiedType(); + if (top || verbose) System.out.print("Checking " + type + "..."); + compileCsp(top, cell); + if (top || verbose) System.out.println("Checked."); + + if (checkAll) { + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + Pair p = (Pair) i.next(); + CellInterface subcell = (CellInterface) p.getSecond(); + process(false, seen, subcell); + } + } + } + + private void compileCsp(final boolean top, final CellInterface cell) { + final String cellName = cell.getFullyQualifiedType(); + if (cell.containsRunnableCsp()) { + try { + final PrintWriter myNullPrintWriter = + new PrintWriter( NullWriter.getInstance() ); + final PrintWriter myStdOutputWriter = + new PrintWriter( new OutputStreamWriter( System.out ) ); + + // XXX: what should value for emitCoverageProbes be? + new CSP2Class(myNullPrintWriter, myStdOutputWriter, + myNullPrintWriter, false).compile(cell); + } + catch( NoCSPBlockException e ) { + throw new AssertionError("Runnable CSP in " + cellName + + " but no CSP block!"); + } + catch( SemanticException e ) { + System.out.println( "CSP for " + cellName + + " failed to compile:\n" + e ); + } + catch( IOException e ) { + System.out.println( "CSP for " + cellName + + " failed to compile:\n" + e ); + } + } else if (top) { + // Excuse the lack of CSP if this is a fragment cell + if (!Boolean.TRUE + .equals((Boolean)DirectiveUtils + .getTopLevelDirective(cell, + DirectiveConstants.FRAGMENT))) + + System.out.println("no csp in " + cellName); + } + } + + public CellInterface prepCell( CellInterface cell ) { + process(true, new HashSet(), cell); + + return null; + } + + public void outputCell(CellInterface cell, CellInterface envCell) + throws CellFormatterException, IOException { + if (envCell != null) { + prepCell(envCell); + } + } + } + + /** + * A helper class for AspiceFormatter and NewAspiceFormatter. It converts + * transistors, resistors, and capacitors in a netlist block to aspice. + **/ + private static class Netlist2Aspice implements CDLFactoryInterface { + private final HierName prefix; + private final PrintWriter pw; + private final int[] errors; + public Netlist2Aspice(final HierName prefix, final PrintWriter pw, + int[] errors) { + this.prefix = prefix; + this.pw = pw; + this.errors = errors; + } + private String soft(CDLLexer.InfoToken val, Environment env) { + final Double eval = val.getValue(env); + if (eval == null) return val.getText(); + else return eval.toString(); + } + private String param(Map parameters, Environment env, String name, + String def) { + Object token = parameters.get(name); + if (token == null) token = parameters.get(name.toUpperCase()); + return token == null ? def + : soft((CDLLexer.InfoToken) token, env); + } + public void makeResistor(HierName name, HierName n1, HierName n2, + CDLLexer.InfoToken val, Map parameters, + Environment env) { + pw.print("res("); + OldLVSFormatter.printName(prefix, n1, pw); + pw.print(", "); + OldLVSFormatter.printName(prefix, n2, pw); + pw.println(") (" + soft(val, env) + ")"); + } + + public void makeCapacitor(HierName name, HierName npos, + HierName nneg, CDLLexer.InfoToken val, + Map parameters, Environment env) { + pw.print("cap("); + OldLVSFormatter.printName(prefix, npos, pw); + pw.print(", "); + OldLVSFormatter.printName(prefix, nneg, pw); + pw.println(") (" + soft(val, env) + ")"); + } + + public void makeTransistor(HierName name, String type, HierName ns, + HierName nd, HierName ng, HierName nb, + CDLLexer.InfoToken w, + CDLLexer.InfoToken l, Map parameters, + Environment env) { + pw.print(type.charAt(0) == 'n' || type.charAt(0) == 'N' ? + "nch_mac" : "pch_mac"); + pw.print(" ("); + OldLVSFormatter.printName(prefix, ns, pw); + pw.print(", "); + OldLVSFormatter.printName(prefix, ng, pw); + pw.print(", "); + OldLVSFormatter.printName(prefix, nd, pw); + pw.print(", "); + OldLVSFormatter.printName(prefix, nb, pw); + pw.println(") (" + soft(w, env) + ", " + soft(l, env) + ", " + + param(parameters, env, "as", "0") + ", " + + param(parameters, env, "ps", "0") + ", " + + param(parameters, env, "nrs", "0") + ", " + + param(parameters, env, "ad", "0") + ", " + + param(parameters, env, "pd", "0") + ", " + + param(parameters, env, "nrd", "0") + ")"); + } + + private void error(final String device, final HierName name) { + ++errors[0]; + //System.err.println("aspice output ignoring " + device + " named " + prefix + "." + name + " in the netlist block"); + } + + public void makeDiode(HierName name, String type, HierName npos, + HierName nneg, CDLLexer.InfoToken area, + Map parameters, Environment env) { + error("diode", name); + } + + public void makeInductor(HierName name, HierName npos, + HierName nneg, CDLLexer.InfoToken val, + Map parameters, Environment env) { + error("inductor", name); + } + + public void makeBipolar(HierName name, String type, HierName nc, + HierName nb, HierName ne, + CDLLexer.InfoToken area, + Map parameters, Environment env) { + error("bipolar", name); + } + + public void makeCall(HierName name, String subName, HierName[] args, + Map parameters, Environment env) { + error("subcell instantiation", name); + } + + public void beginSubcircuit(String subName, String[] in, + String[] out, Map parameters, + Environment env) { + throw new AssertionError(); + } + + public void endSubcircuit(String subName, Environment env) { + throw new AssertionError(); + } + } + + private static class NewAspiceFormatter extends SimpleCellFormatter { + final PrintWriter pw, oldpw, modifyWriter; + final IndentWriter iw; + final File modifyFile; + private final boolean internalWires; + private final boolean internalRules; + private final PartialExtract.CellPlusMinus fqcnSpec; + private final PartialExtract.CellPlusMinusKeyword partialSimSpec; + private final Cadencize cadencizer; + private final CastFileParser cfp; + private final TreeMap impliedPorts; + private final boolean dsimMode; + private final String appendColon; + private final Set warned = new HashSet(); + private final Map cache = new HashMap(); + private final Map typesMap = new HashMap(); + private Set unusedSet = Collections.EMPTY_SET; + private final static String ENV_SUFFIX = ".env"; + private final static String ASPICE_RESET = "$_RESET"; + private final static HierName ENV_RESET = + HierName.makeHierName("_RESET"); + + NewAspiceFormatter(final PrintWriter pw, + final boolean internalWires, + final boolean internalRules, + final PartialExtract.CellPlusMinus fqcnSpec, + final PartialExtract.CellPlusMinusKeyword pSS, + final CastFileParser cfp, + final Cadencize cadencizer, + final boolean dsimMode, + final String appendColon) { + this(pw, new Pair(pw, null), internalWires, internalRules, + fqcnSpec, pSS, cfp, cadencizer, dsimMode, appendColon); + } + NewAspiceFormatter(final PrintWriter pw, + final Pair modifyPair, + final boolean internalWires, + final boolean internalRules, + final PartialExtract.CellPlusMinus fqcnSpec, + final PartialExtract.CellPlusMinusKeyword pSS, + final CastFileParser cfp, + final Cadencize cadencizer, + final boolean dsimMode, + final String appendColon) { + this.oldpw = pw; + this.iw = new IndentWriter(pw); + this.pw = new PrintWriter(iw, true); + this.modifyWriter = (PrintWriter) modifyPair.getFirst(); + this.modifyFile = (File) modifyPair.getSecond(); + this.internalWires = internalWires; + this.internalRules = internalRules; + this.fqcnSpec = fqcnSpec; + this.partialSimSpec = pSS; + this.cadencizer = cadencizer; + this.cfp = cfp; + this.impliedPorts = new TreeMap(); + this.dsimMode = dsimMode; + this.appendColon = appendColon; + } + + /** + * XXX: This is modified from com.avlsi.fast.NetlistAdapter. The + * change should be made there and no existing code should be affected, + * as they all filter out wiring cells anyway. But to be completely + * safe for the pending tape-out, it is here instead. + **/ + private static java.util.SortedSet + getParameterList(final CellInterface ci, final Cadencize c) { + /* Cadencize to find the port list. */ + final CadenceInfo cinfo = c.convert(ci); + java.util.TreeSet port = new java.util.TreeSet(); + AliasedMap portNodes = cinfo.getPortNodes(); + for (Iterator i = portNodes.getCanonicalKeys(); i.hasNext(); ) { + final HierName h = (HierName) i.next(); + if (((Boolean) portNodes.getValue(h)).booleanValue() || + ci.isChannel()) port.add(h); + } + return port; + } + + public CellInterface prepCell(CellInterface cell) { + final CellImpl fake = + new CellImpl("fake", null, CellImpl.SYNTHETIC_CELL); + + final CellInterface dummy; + try { + dummy = cfp.getFullyQualifiedCell(cell.getFullyQualifiedType(), + fake, + HierName.makeHierName("X")); + } catch (Exception e) { + throw new RuntimeException("Cannot load cell " + + cell.getFullyQualifiedType(), e); + } + for (Iterator i = fake.getCanonicalNodes(); i.hasNext(); ) { + final HierName node = (HierName) i.next(); + for (Iterator j = fake.getConnectedNodes(node); j.hasNext();) { + final HierName alias = (HierName) j.next(); + if (!alias.equals(node)) { + final String salias = alias.getAspiceString(); + assert salias.startsWith("X."); + impliedPorts.put("$" + node.getAspiceString(), + salias.substring(2)); + } + } + } + return cell; + } + + private void quote(String s, PrintWriter pw) { + pw.print("\"" + s + "\""); + } + + private void quote(String s) { + quote(s, pw); + } + + private void quote(HierName s, PrintWriter pw) { + OldLVSFormatter.printName(null, s, pw); + } + + private void quote(HierName s) { + quote(s, pw); + } + + /** + * @pre cell != null + **/ + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + final AliasedSet aliases = cadencizer.convert(cell).getLocalNodes(); + final InstanceData instData; + if (envCell == null && !internalRules && fqcnSpec.isEmpty()) { + instData = null; + } else { + instData = new InstanceData(); + instData.updateExtraDelay(cell, aliases); + } + + if (envCell == null) { + if (modifyFile != null) + pw.println(".include \"" + modifyFile.getName() + "\";"); + + for (Iterator i = impliedPorts.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + pw.print("wire("); + OldLVSFormatter.printName(null, (String) entry.getKey(), + pw); + pw.print(","); + OldLVSFormatter.printName(null, (String) entry.getValue(), + pw); + pw.println(")"); + } + if (partialSimSpec != null) unusedSet = new TreeSet(); + final String name = processCell(cell, null, false, instData); + + if (!internalWires && !internalRules) + processPortConnections(cell); + + if (partialSimSpec != null) { + partialSimSpec.initialize(cell, cadencizer); + if (!partialSimSpec.isEmpty()) { + pruneUsedTypes(typesMap, cell, name, null); + for (Iterator j = unusedSet.iterator(); j.hasNext(); ) { + final String type = (String) j.next(); + skip(type, modifyWriter); + } + processPartialSimulation(typesMap, cell, name, null, + modifyWriter); + } + } + } else { + final String env = "$env"; + final String envName = + processCell(envCell, HierName.makeHierName(env), true, + null); + + // Instantiate the environment + quote(envName); + pw.print(" \"$env\"("); + final AliasedMap envLocals = + cadencizer.convert(envCell).getPortNodes(); + final Map ports = CellUtils.markPorts(cell); + final Map envPorts = new HashMap(); + for (Iterator i = ports.keySet().iterator(); i.hasNext(); ) { + final String sname = (String) i.next(); + final HierName hname; + try { + hname = HierName.makeHierName(sname, '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException(e); + } + final Object canon = envLocals.getCanonicalKey(hname); + assert canon != null : "No canonical key for " + sname + " in " + envCell.getFullyQualifiedType(); + envPorts.put(canon, sname); + } + for (Iterator i = getParameterList(envCell, cadencizer).iterator(); i.hasNext(); ) { + quote((String) envPorts.get(i.next())); + if (i.hasNext()) pw.print(", "); + } + pw.println(")"); + for (Iterator i = + new SortingIterator(ports.keySet().iterator()); + i.hasNext(); ) { + final String port = (String) i.next(); + pw.print("wire("); + OldLVSFormatter.printName(null, port, pw); + pw.print(","); + OldLVSFormatter.printName(env, port, pw); + pw.println(")"); + } + // if _RESET is not an implied port, look for _RESET inside env + if (!impliedPorts.containsKey(ASPICE_RESET)) { + final HierName canonReset = (HierName) + cadencizer.convert(envCell).getLocalNodes() + .getCanonicalKey(ENV_RESET); + if (canonReset != null) { + pw.print("wire("); + OldLVSFormatter.printName(null, ASPICE_RESET, pw); + pw.print(","); + OldLVSFormatter.printName( + env, ENV_RESET.getAspiceString(), pw); + pw.println(")"); + } + } + } + + // checkError also flushes + if (pw.checkError() || oldpw.checkError() || + modifyWriter.checkError()) + throw new IOException(); + } + + private int getAction(final HierName instance) { + return fqcnSpec == null ? -1 : fqcnSpec.getAction(instance); + } + + /** + * Output the exclusion properties, connections, and, if + * isEnv the prs for the cell. + * + * @param isEnv If the cell results from a named environment. + **/ + protected String processCell(final CellInterface cell, + final HierName prefix, + final boolean isEnv, + final InstanceData instData) { + final String type = cell.getFullyQualifiedType(); + if (!cache.containsKey(type)) cache.put(type, new HashMap()); + final Map perTypeMap = (Map) cache.get(type); + final boolean addUnused = + unusedSet != Collections.EMPTY_SET && !CellUtils.isWiring(cell); + if (addUnused) unusedSet.add(type); + + final CadenceInfo cinfo = cadencizer.convert(cell); + final AliasedSet localNodes = cinfo.getLocalNodes(); + final AliasedMap portNodes = cinfo.getPortNodes(); + + cell.getProductionRuleSet().canonicalizeNames(localNodes); + //cell.getAssertedProductionRuleSet().canonicalizeNames(localNodes); + + // Determine the extra_delay directives + Map extra_delays = Collections.EMPTY_MAP; + final ProductionRuleSet prsRules = cell.getProductionRuleSet(); + if (instData != null && prsRules.size() > 0) { + extra_delays = new HashMap(); + for (final Iterator i = prsRules.getProductionRules(); + i.hasNext(); ) { + final HierName target = + ((ProductionRule) i.next()).getTarget(); + final Pair p = + (Pair) instData.get(DirectiveConstants.EXTRA_DELAY) + .getAttribute(target); + if (p != null) extra_delays.put(target, p); + } + if (extra_delays.isEmpty()) + extra_delays = Collections.EMPTY_MAP; + } + + // Determine the actual types of the subcells + final Map instances = new TreeMap(); + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (subcell.isNode()) continue; + + final InstanceData newInstData = instData == null ? null : + instData.translate(cell, subcell, subcellName, cadencizer); + + final HierName fullName = HierName.append(prefix, subcellName); + final String newType = + processCell(subcell, fullName, isEnv, newInstData); + + instances.put(subcellName, newType); + } + + final int action = getAction(prefix); + + final Triplet key = + new Triplet(new Pair(isEnv ? Boolean.TRUE : Boolean.FALSE, + new Integer(action)), + extra_delays, + instances); + + final String cached = (String) perTypeMap.get(key); + if (cached != null) return cached; + + final String result = type + "." + perTypeMap.size() + + (isEnv ? ENV_SUFFIX : ""); + perTypeMap.put(key, result); + typesMap.put(result, instances); + if (addUnused) unusedSet.add(result); + + // Emit the definition for this cell; but do not define a top-level + // cell + if (prefix != null) { + pw.print("define "); + quote(result); + pw.print("("); + for (Iterator i = getParameterList(cell, cadencizer).iterator(); i.hasNext(); ) { + final HierName p = (HierName) i.next(); + quote(p); + if (i.hasNext()) pw.print(", "); + } + pw.println(") {"); + iw.nextLevel(); + } + + final CellDelay delay = new CellDelay(cell, cadencizer); + + // print out the rules + if (isEnv || internalRules || action == PartialExtract.Info.EXCLUDE) + processPRS(cell.getProductionRuleSet(), delay, + dsimMode || isEnv || action == PartialExtract.Info.EXCLUDE, + false, instData, localNodes); + + // print out ERROR rules + if (isEnv || internalRules) + processPRS(cell.getAssertedProductionRuleSet(), delay, + true, true, instData, localNodes); + + // print out exclusion directives + if (fqcnSpec == null || + !fqcnSpec.getRest().equals("+localportnodes") || + action == PartialExtract.Info.INCLUDE) { + processExclusives(localNodes, cell.getLocalExclusiveNodeSets()); + processExclusives(cell); + } + + // print out aliases + if (isEnv || internalWires) + processConnections(cell); + + // emit any netlist blocks + if (isEnv && !dsimMode) processNetlist(cell); + + // print subcell instantiations + for (final Iterator i = instances.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName subcellName = (HierName) entry.getKey(); + final String typeName = (String) entry.getValue(); + final CellInterface subcell = cell.getSubcell(subcellName); + + quote(typeName); + pw.print(" "); + quote(subcellName); + pw.print("("); + + for (final Iterator j = getParameterList(subcell, cadencizer).iterator(); j.hasNext(); ) { + final HierName port = (HierName) j.next(); + final HierName net = (HierName) localNodes.getCanonicalKey(HierName.append(subcellName, port)); + quote(net); + if (j.hasNext()) pw.print(", "); + } + + pw.println(")"); + } + + if (!isEnv && !appendColon.equals("")) { + emitAnalogDigitalBindings(localNodes, portNodes, + prefix == null); + } + + if (prefix != null) { + iw.prevLevel(); + pw.println("}"); + } + return result; + } + + private void emitAnalogDigitalBindings(final AliasedSet localNodes, + final AliasedMap portNodes, + final boolean all) { + for (Iterator i = localNodes.getCanonicalKeys(); i.hasNext(); ) { + final HierName node = (HierName) i.next(); + if (all || !portNodes.contains(node)) { + final String snode = node.getAspiceString(); + pw.print("wire("); + OldLVSFormatter.printName(null, snode, pw); + pw.print(","); + OldLVSFormatter.printName(null, snode + appendColon, pw); + pw.println(");"); + } + } + } + + private void processPRS(final ProductionRuleSet prs, + final CellDelay delay, + final boolean isEnv, + final boolean isErr, + final InstanceData instData, + final AliasedSet localNodes) { + boolean firstP = true; + + for (final Iterator prsIterator = + new SortingIterator(prs.getProductionRules(), + new StringRepComparator() ); + prsIterator.hasNext(); ) { + final ProductionRule pr = (ProductionRule) prsIterator.next(); + if (firstP) { + firstP = false; + pw.println("dsim {"); + iw.nextLevel(); + } + + printPR(pr, delay, isEnv, isErr, instData, localNodes); + } + if (!firstP) { + iw.prevLevel(); + pw.println('}'); + } + } + + protected void printPR(final ProductionRule pr, + final CellDelay delay, + final boolean isEnv, + final boolean isErr, + final InstanceData instData, + final AliasedSet localNodes) { + + + final Iterator iD = + pr.getGuard().DNFForm().getDisjuncts().iterator(); + while (iD.hasNext()) { + final AndBooleanExpressionInterface disj = + (AndBooleanExpressionInterface) iD.next(); + final Iterator iC = disj.getConjuncts().iterator(); + + // modifiers + pw.print((isEnv ? "env " : "") + pr.flagsString()); + final boolean up = pr.getDirection() == ProductionRule.UP; + final int extraDelay = instData == null ? 0 : + Math.round(instData.getExtraDelay(up, pr.getTarget())); + // This is fine for after_ps, because getDelay() divides the + // specified number by 100, and multiply by 100 to recover the + // old value. + final int after = + (int) delay.getDelay(pr.getTarget(), up, 100) + extraDelay; + pw.print(pr.isAbsolute() ? "after_ps" : "after"); + pw.print(" " + after + " "); + + // guard + boolean firstP = true; + while (iC.hasNext()) { + final HierNameAtomicBooleanExpression conj = + (HierNameAtomicBooleanExpression) iC.next(); + if (firstP) + firstP = false; + else + pw.print(" & "); + + if (!conj.getSense()) + pw.print('~'); + OldLVSFormatter.printName(null, + conj.getName(), + pw); + } + + // target + pw.print(" -> "); + if (isErr) pw.print("\"ERROR\""); + else OldLVSFormatter.printName(null, + pr.getTarget(), + pw); + + // direction + pw.println(pr.getDirection() == ProductionRule.UP ? '+' : '-'); + } + } + + private void processExclusives(final List group1, final List group2) { + final ArrayList pair = new ArrayList(2); + pair.add(null); pair.add(null); + for (Iterator g1 = group1.iterator(); g1.hasNext(); ) { + pair.set(0, g1.next()); + for (Iterator g2 = group2.iterator(); g2.hasNext(); ) { + pair.set(1, g2.next()); + final ExclusiveNodeSet ens = + new ExclusiveNodeSet(ExclusiveNodeSet.CC, pair); + OldLVSFormatter.printExclusive(ens, null, pw); + } + } + } + + private void processExclusives(final ArrayList groups) { + for (int i = 0; i < groups.size(); i++) { + final List group1 = (List) groups.get(i); + for (int j = i + 1; j < groups.size(); j++) { + final List group2 = (List) groups.get(j); + processExclusives(group1, group2); + } + } + } + + private void processExclusives(final CellInterface cell) { + final BlockInterface cellBlock = cell.getBlockInterface(); + + // process exclcc directives + final Map exclMap = + DirectiveUtils.getMultipleBlockDirective + ( Arrays.asList + ( new BlockInterface[] + { DirectiveUtils.getUniqueBlock + (cellBlock, + BlockInterface.PRS), + DirectiveUtils.getUniqueBlock + (cellBlock, + BlockInterface.SUBCELL) + } ), + DirectiveConstants.EXCLCC, + DirectiveTable.arrayify( + DirectiveConstants.UNCHECKED_NODE_TYPE) + ); + + // group exclusive nodes by their group number + final MultiMap exclGroups = + new MultiMap(new HashMap(), MultiMap.ARRAY_LIST_FACTORY); + for (Iterator i = exclMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + exclGroups.put(entry.getValue(), entry.getKey()); + } + + for (Iterator i = exclGroups.keySet().iterator(); i.hasNext(); ) { + final ArrayList excls = (ArrayList) exclGroups.get(i.next()); + processExclusives(excls); + } + + // process nocc_nodes directives + final List prsNocc = (List) DirectiveUtils.getPrsDirective( + cell, DirectiveConstants.NOCC_NODES); + final List subcellNocc = (List) DirectiveUtils.getSubcellDirective( + cell, DirectiveConstants.NOCC_NODES); + if (prsNocc != null || subcellNocc != null) { + final Collection allNocc = new ArrayList(); + if (prsNocc != null) allNocc.addAll(prsNocc); + if (subcellNocc != null) allNocc.addAll(subcellNocc); + final ExclusiveNodeSet ens = + new ExclusiveNodeSet(ExclusiveNodeSet.NOCC, allNocc); + OldLVSFormatter.printExclusive(ens, null, pw); + } + } + + private void processExclusives(final AliasedSet localNodes, + final ExclusiveNodeSets enss) { + OldLVSFormatter.printExclusives(localNodes, enss, null, pw); + } + + private void processConnections(final CellInterface cell) { + for (final Iterator iCanonNode = + new SortingIterator(cell.getCanonicalNodes()); + iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + boolean firstP = true; + for (final Iterator iConnNode = + cell.getConnectedNodes(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + // don't print self-connections + if (connNode != canonNode) { + if (firstP) { + firstP = false; + pw.print("wire("); + OldLVSFormatter.printName(null, canonNode, pw); + } + + pw.print(','); + OldLVSFormatter.printName(null, connNode, pw); + } + } + if (!firstP) + pw.println(')'); + } + } + + private void processPortConnections(final CellInterface cell) { + final AliasedMap portNodes = + cadencizer.convert(cell).getPortNodes(); + for (final Iterator iCanonNode = + new SortingIterator(portNodes.getCanonicalKeys()); + iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + boolean firstP = true; + for (final Iterator iConnNode = + portNodes.getAliases(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + // don't print self-connections + if (connNode != canonNode) { + if (firstP) { + firstP = false; + pw.print("wire("); + OldLVSFormatter.printName(null, canonNode, pw); + } + + pw.print(','); + OldLVSFormatter.printName(null, connNode, pw); + } + } + if (!firstP) + pw.println(')'); + } + } + + private void processNetlist(final CellInterface ci) { + + if (!ci.containsNetlist()) return; + final BlockIterator bi = + ci.getBlockInterface().iterator(BlockInterface.NETLIST); + assert bi.hasNext() : "No netlist block found in " + ci.getFullyQualifiedType(); + final NetlistBlock nb = (NetlistBlock) bi.next(); + final Template templ = nb.getCDLTemplate(); + int[] errors = new int[] { 0 }; + templ.execute(new Netlist2Aspice(null, pw, errors), + new LocalEnvironment(nb.getParams()), null); + if (errors[0] > 0 && warned.add(ci)) { + System.err.println("AspiceFormatter: " + errors[0] + " circuit elements ignored in the netlist block for " + ci.getFullyQualifiedType()); + } + } + + private void pruneUsedTypes( + final Map typesMap, + final CellInterface cell, + final String cellName, + final HierName prefix) { + final Map subcells = (Map) typesMap.get(cellName); + if (subcells == null) return; + + for (Iterator i = subcells.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName subInst = (HierName) entry.getKey(); + final CellInterface subcell = cell.getSubcell(subInst); + final String subcellName = (String) entry.getValue(); + if (subcell.isChannel() || subcell.isNode()) continue; + pruneUsedTypes(typesMap, subcell, subcellName, + HierName.prefixName(prefix, subInst)); + } + final int action = partialSimSpec.getAction(prefix); + if (prefix == null || action != PartialExtract.Info.EXCLUDE) { + unusedSet.remove(cellName); + + if (!CellUtils.isWiring(cell)) { + unusedSet.remove(cell.getFullyQualifiedType()); + } + } + } + + private void skip(final String type, final PrintWriter pw) { + pw.print(".modify skip "); + quote(type, pw); + pw.println(";"); + } + + private void skip(final String type, final HierName prefix, + final PrintWriter pw) { + pw.print(".modify skip "); + quote(type, pw); + pw.print(" "); + quote(prefix, pw); + pw.println(";"); + } + + private void processPartialSimulation( + final Map typesMap, + final CellInterface cell, + final String cellName, + final HierName prefix, + final PrintWriter pw) { + final Map subcells = (Map) typesMap.get(cellName); + if (subcells == null) return; + + for (Iterator i = subcells.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName subInst = (HierName) entry.getKey(); + final CellInterface subcell = cell.getSubcell(subInst); + final String subcellName = (String) entry.getValue(); + if (subcell.isChannel() || subcell.isNode()) continue; + processPartialSimulation(typesMap, subcell, subcellName, + HierName.prefixName(prefix, subInst), + pw); + } + final int action = partialSimSpec.getAction(prefix); + if (prefix != null && action == PartialExtract.Info.EXCLUDE) { + if (!unusedSet.contains(cellName)) + skip(cellName, prefix, pw); + + final String type = cell.getFullyQualifiedType(); + if (!CellUtils.isWiring(cell) && !unusedSet.contains(type)) + skip(type, prefix, pw); + } + } + } + + /** + * Aspice output formatter. Processes hierarchically, in contrast to + * all the other formatters in this class. The names that are output + * will not be canonical. The wire statements are needed to make + * sense of the output circuit. + **/ + private static class AspiceFormatter extends SimpleCellFormatter { + final PrintWriter pw; + private final boolean internalWires; + private final boolean internalRules; + private final PartialExtract.CellPlusMinus fqcnSpec; + private final Cadencize cadencizer; + private final CastFileParser cfp; + private final TreeMap impliedPorts; + private final boolean dsimMode; + private boolean alintMode = false; + private final Set warned = new HashSet(); + + AspiceFormatter(final PrintWriter pw, + final boolean internalWires, + final boolean internalRules, + final PartialExtract.CellPlusMinus fqcnSpec, + final CastFileParser cfp, + final Cadencize cadencizer, + final boolean dsimMode) { + this.pw = pw; + this.internalWires = internalWires; + this.internalRules = internalRules; + this.fqcnSpec = fqcnSpec; + this.cadencizer = cadencizer; + this.cfp = cfp; + this.impliedPorts = new TreeMap(); + this.dsimMode = dsimMode; + } + + public CellInterface prepCell(CellInterface cell) { + final CellImpl fake = + new CellImpl("fake", null, CellImpl.SYNTHETIC_CELL); + + final CellInterface dummy; + try { + dummy = cfp.getFullyQualifiedCell(cell.getFullyQualifiedType(), + fake, + HierName.makeHierName("X")); + } catch (Exception e) { + throw new RuntimeException("Cannot load cell " + + cell.getFullyQualifiedType(), e); + } + for (Iterator i = fake.getCanonicalNodes(); i.hasNext(); ) { + final HierName node = (HierName) i.next(); + for (Iterator j = fake.getConnectedNodes(node); j.hasNext();) { + final HierName alias = (HierName) j.next(); + if (!alias.equals(node)) { + final String salias = alias.getAspiceString(); + assert salias.startsWith("X."); + impliedPorts.put("$" + node.getAspiceString(), + salias.substring(2)); + } + } + } + return cell; + } + + /** + * @pre cell != null + **/ + public void outputCell( + final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + final AliasedSet aliases = cadencizer.convert(cell).getLocalNodes(); + final InstanceData instData = new InstanceData(); + instData.updateExtraDelay(cell, aliases); + + for (Iterator i = impliedPorts.entrySet().iterator(); i.hasNext(); ) + { + final Map.Entry entry = (Map.Entry) i.next(); + pw.print("wire("); + OldLVSFormatter.printName(null, (String) entry.getKey(), pw); + pw.print(","); + OldLVSFormatter.printName(null, (String) entry.getValue(), pw); + pw.println(")"); + } + alintMode = envCell == null; + processCell(cell, null, false, instData); + if (envCell != null) { + final String env = "$env"; + processCell(envCell, HierName.makeHierName(env), true, null); + final Map ports = CellUtils.markPorts(cell); + for (Iterator i = + new SortingIterator(ports.keySet().iterator()); + i.hasNext(); ) { + final String port = (String) i.next(); + pw.print("wire("); + OldLVSFormatter.printName(null, port, pw); + pw.print(","); + OldLVSFormatter.printName(env, port, pw); + pw.println(")"); + } + } + if (/* !alintMode && */ !internalWires && !internalRules) + processPortConnections(cell, null); + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + + + /** + * Output the exclusion properties, connections, and, if + * isEnv the prs for the cell. + * + * @param isEnv If the cell results from a named environment. + **/ + protected void processCell( + final CellInterface cell, + final HierName prefix, + final boolean isEnv, + final InstanceData instData) { + + final AliasedSet localNodes = + cadencizer.convert(cell).getLocalNodes(); + + cell.getProductionRuleSet().canonicalizeNames(localNodes); + //cell.getAssertedProductionRuleSet().canonicalizeNames(localNodes); + final CellDelay delay = new CellDelay(cell, cadencizer); + + final int action = + fqcnSpec == null ? -1 : fqcnSpec.getAction(prefix); + + // print out the rules + if (!alintMode && (isEnv || + internalRules || + action == PartialExtract.Info.EXCLUDE)) + processPRS(cell.getProductionRuleSet(), prefix, delay, + dsimMode || isEnv || action == PartialExtract.Info.EXCLUDE, + false, instData, localNodes); + + // print out ERROR rules + if (!alintMode && (isEnv || internalRules)) + processPRS(cell.getAssertedProductionRuleSet(), prefix, delay, + true, true, instData, localNodes); + + // print out exclusion directives + if (!alintMode || fqcnSpec == null || + !fqcnSpec.getRest().equals("+localnodes") || + action == PartialExtract.Info.INCLUDE) + processExclusives(localNodes, cell.getLocalExclusiveNodeSets(), prefix); + + // print out aliases + if (/* !alintMode && */ (isEnv || internalWires)) + processConnections(cell, prefix); + + // emit any netlist blocks + if (isEnv && !dsimMode) + processNetlist(cell, prefix); + + // recurse to subcells + for (final Iterator i = + new SortingIterator(cell.getSubcellPairs()); + i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + + /* + if (alintMode && subcell.isChannel()) { + final ExclusiveNodeSets flat = new ExclusiveNodeSets(); + flattenExcl(subcell, subcellName, flat); + processExclusives(localNodes, flat, prefix); + continue; + } + */ + + final InstanceData newInstData = instData == null ? null : + instData.translate(cell, subcell, subcellName, cadencizer); + + processCell(subcell, HierName.append(prefix, subcellName), + isEnv, newInstData); + } + } + + private void flattenExcl(final CellInterface wiring, + final HierName prefix, + final ExclusiveNodeSets result) { + for (Iterator i = wiring.getLocalExclusiveNodeSets().getIterator(); + i.hasNext(); ) { + final ExclusiveNodeSet ens = (ExclusiveNodeSet) i.next(); + result.addExclusiveNodeSet(ens.prefixNames(prefix)); + } + for (final Iterator i = wiring.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + flattenExcl(subcell, HierName.append(prefix, subcellName), + result); + } + } + + private void processPRS( + final ProductionRuleSet prs, + final HierName prefix, + final CellDelay delay, + final boolean isEnv, + final boolean isErr, + final InstanceData instData, + final AliasedSet localNodes) { + boolean firstP = true; + + for (final Iterator prsIterator = + new SortingIterator(prs.getProductionRules(), + new StringRepComparator() ); + prsIterator.hasNext(); ) { + final ProductionRule pr = (ProductionRule) prsIterator.next(); + if (firstP) { + firstP = false; + pw.println("dsim {"); + } + + printPR(prefix, pr, delay, isEnv, isErr, instData, localNodes); + } + if (!firstP) + pw.println('}'); + } + + protected void printPR( + final HierName prefix, + final ProductionRule pr, + final CellDelay delay, + final boolean isEnv, + final boolean isErr, + final InstanceData instData, + final AliasedSet localNodes) { + + + final Iterator iD = + pr.getGuard().DNFForm().getDisjuncts().iterator(); + while (iD.hasNext()) { + final AndBooleanExpressionInterface disj = + (AndBooleanExpressionInterface) iD.next(); + final Iterator iC = disj.getConjuncts().iterator(); + + // modifiers + pw.print((isEnv ? "env " : "") + pr.flagsString()); + final boolean up = pr.getDirection() == ProductionRule.UP; + final HierName canonTarget = + (HierName) localNodes.getCanonicalKey(pr.getTarget()); + final int extraDelay = instData == null ? 0 : + Math.round(instData.getExtraDelay(up, canonTarget)); + // This is fine for after_ps, because getDelay() divides the + // specified number by 100, and multiply by 100 to recover the + // old value. + final int after = + (int) delay.getDelay(pr.getTarget(), up, 100) + extraDelay; + pw.print(pr.isAbsolute() ? "after_ps" : "after"); + pw.print(" " + after + " "); + + // guard + boolean firstP = true; + while (iC.hasNext()) { + final HierNameAtomicBooleanExpression conj = + (HierNameAtomicBooleanExpression) iC.next(); + if (firstP) + firstP = false; + else + pw.print(" & "); + + if (!conj.getSense()) + pw.print('~'); + OldLVSFormatter.printName(prefix, + conj.getName(), + pw); + } + + // target + pw.print(" -> "); + if (isErr) pw.print("\"ERROR\""); + else OldLVSFormatter.printName(prefix, + pr.getTarget(), + pw); + + // direction + pw.println(pr.getDirection() == ProductionRule.UP ? '+' : '-'); + } + } + + private void processExclusives( + final AliasedSet localNodes, + final ExclusiveNodeSets enss, + final HierName prefix) { + + OldLVSFormatter.printExclusives(localNodes,enss, prefix, pw); + } + + private void processConnections( + final CellInterface cell, + final HierName prefix) { + for (final Iterator iCanonNode = + new SortingIterator(cell.getCanonicalNodes()); + iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + boolean firstP = true; + for (final Iterator iConnNode = + cell.getConnectedNodes(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + // don't print self-connections + if (connNode != canonNode) { + if (firstP) { + firstP = false; + pw.print("wire("); + OldLVSFormatter.printName(prefix, canonNode, pw); + } + + pw.print(','); + OldLVSFormatter.printName(prefix, connNode, pw); + } + } + if (!firstP) + pw.println(')'); + } + } + + private void processPortConnections( + final CellInterface cell, + final HierName prefix) { + final AliasedMap portNodes = + cadencizer.convert(cell).getPortNodes(); + for (final Iterator iCanonNode = + new SortingIterator(portNodes.getCanonicalKeys()); + iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + boolean firstP = true; + for (final Iterator iConnNode = + portNodes.getAliases(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + // don't print self-connections + if (connNode != canonNode) { + if (firstP) { + firstP = false; + pw.print("wire("); + OldLVSFormatter.printName(prefix, canonNode, pw); + } + + pw.print(','); + OldLVSFormatter.printName(prefix, connNode, pw); + } + } + if (!firstP) + pw.println(')'); + } + } + + private void processNetlist(final CellInterface ci, + final HierName prefix) { + + if (!ci.containsNetlist()) return; + final BlockIterator bi = + ci.getBlockInterface().iterator(BlockInterface.NETLIST); + assert bi.hasNext() : "No netlist block found in " + ci.getFullyQualifiedType(); + final NetlistBlock nb = (NetlistBlock) bi.next(); + final Template templ = nb.getCDLTemplate(); + int[] errors = new int[] { 0 }; + templ.execute(new Netlist2Aspice(prefix, pw, errors), + new LocalEnvironment(nb.getParams()), null); + if (errors[0] > 0 && warned.add(ci)) { + System.err.println("AspiceFormatter: " + errors[0] + " circuit elements ignored in the netlist block for " + ci.getFullyQualifiedType()); + } + } + } + + /** Local nodes formatter + * Same as cast-query --task=local_nodes=used + **/ + private static class LocalNodesFormatter extends SimpleCellFormatter { + private final PrintWriter pw; + private final CastFileParser cfp; + private final Cadencize mCadencizer; + private final boolean includePorts; + private final Set nodes; + + public LocalNodesFormatter( final PrintWriter pw, + final CastFileParser cfp, + final Cadencize cadencizer, + final boolean includePorts, + final Set nodes) { + this.pw = pw; + this.cfp = cfp; + this.nodes = nodes; + this.includePorts = includePorts; + mCadencizer = cadencizer; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + if(envCell != null ) { + return; + } + + LocalNodes localNodes = + new LocalNodes(cfp, + mCadencizer, + false, + true, + includePorts, + nodes); + localNodes.printHeader = false; + localNodes.doTask(cell,pw); + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + } + + /** + * Export information from CAST to alint that isn't appropriate to put into + * the local nodes formatter. + **/ + private static class AlintScenariosFormatter extends SimpleCellFormatter { + private final PrintWriter pw; + private final Cadencize cad; + + // Outputs fully formatted scenario lines for alint; make_alint_in will + // only need to accumulate lines per victim, and then write them out + // before alinting the victim + private void alintScenario(final Map dirs, + final String type, + final String dir, + final Set seen, + final HierName canon) throws IOException { + final Collection tuples = + (Collection) dirs.get(canon); + if (tuples != null) { + pw.write("victim " + canon + "\n"); + if (seen.add(canon)) { + pw.write("scenario" + dir + "\n"); + } + for (TupleValue tuple : tuples) { + pw.write("scenario" + type + dir); + for (Iterator i = tuple.getIterator(); i.hasNext(); ) { + final AlintFaninValue fanin = + (AlintFaninValue) i.next(); + pw.write(" " + fanin.getNode() + fanin.getState()); + } + pw.write("\n"); + } + } + } + + private Pair alintScenario(final String type, + final CellInterface cell, + final AliasedSet locals) { + final BlockInterface cellBlock = cell.getBlockInterface(); + final Map m = + DirectiveUtils.getMultipleBlockDirective + ( Arrays.asList + ( new BlockInterface[] + { DirectiveUtils.getUniqueBlock + (cellBlock, + BlockInterface.PRS), + DirectiveUtils.getUniqueBlock + (cellBlock, + BlockInterface.SUBCELL) } ), + type, + DirectiveConstants.HALFOP_TYPE ); + return new Pair( + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getUps(m)), + DirectiveUtils.canonizeKey(locals, + DirectiveUtils.getDowns(m))); + } + + public AlintScenariosFormatter(final PrintWriter pw, + final Cadencize cad) { + this.pw = pw; + this.cad = cad; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + if (envCell != null) return; + + final AliasedSet nodes = cad.convert(cell).getLocalNodes(); + + final Pair defScenario = + alintScenario(DirectiveConstants.ALINT_DEFAULT_SCENARIOS, cell, + nodes); + final Set noDefaultUp = (Set) + DirectiveUtils.getExplicitFalses((Map) defScenario.getFirst()); + final Set noDefaultDn = (Set) + DirectiveUtils.getExplicitFalses((Map) defScenario.getSecond()); + + final Map> upScenarioMaps = + new LinkedHashMap>(); + final Map> dnScenarioMaps = + new LinkedHashMap>(); + final Map scenarioDirs = (Map) + CollectionUtils.mapify(new Object[] { + DirectiveConstants.ALINT_SCENARIO, "", + DirectiveConstants.ALINT_DELAY_SCENARIO, ":delay", + DirectiveConstants.ALINT_LEAK_SCENARIO, ":leak", + DirectiveConstants.ALINT_BUMP_SCENARIO, ":bump" }); + for (Map.Entry dir : scenarioDirs.entrySet()) { + final Pair p = alintScenario(dir.getKey(), cell, nodes); + upScenarioMaps.put(dir.getValue(), + (Map) p.getFirst()); + dnScenarioMaps.put(dir.getValue(), + (Map) p.getSecond()); + } + + for (Iterator i = new SortingIterator(nodes.getCanonicalKeys()); + i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + for (Map.Entry> entry : + upScenarioMaps.entrySet()) { + alintScenario(entry.getValue(), entry.getKey(), ":up", + noDefaultUp, canon); + } + for (Map.Entry> entry : + dnScenarioMaps.entrySet()) { + alintScenario(entry.getValue(), entry.getKey(), ":dn", + noDefaultDn, canon); + } + } + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + } + + private static class LocalAliasesFormatter extends SimpleCellFormatter { + private final PrintWriter pw; + private final CastFileParser cfp; + private final Cadencize mCadencizer; + + public LocalAliasesFormatter( final PrintWriter pw, + final CastFileParser cfp, + final Cadencize cadencizer) { + this.pw = pw; + this.cfp = cfp; + mCadencizer = cadencizer; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + if(envCell != null ) { + return; + } + + pw.println(cell.getFullyQualifiedType()); + + final AliasedSet locals = mCadencizer.convert(cell).getLocalNodes(); + for (Iterator i = locals.getCanonicalKeys(); i.hasNext(); ) { + final HierName canon = (HierName) i.next(); + pw.print(canon.getCadenceString()); + for (Iterator j = locals.getAliases(canon); j.hasNext(); ) { + final HierName alias = (HierName) j.next(); + if (!alias.equals(canon)) { + pw.print("=" + alias.getCadenceString()); + } + } + pw.println(); + } + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + } + + /** Dynamic nodes formatter + * Same as cast-query --task=dynamic_nodes=leaky + **/ + private static class LeakyNodesFormatter extends SimpleCellFormatter { + private final PrintWriter pw; + private final CastFileParser cfp; + private final Cadencize mCadencizer; + + public LeakyNodesFormatter( final PrintWriter pw, + final CastFileParser cfp, + final Cadencize cadencizer) { + this.pw = pw; + this.cfp = cfp; + mCadencizer = cadencizer; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + if(envCell != null ) { + return; + } + + CastQuery.DynamicNodes dynamicNodes = + new CastQuery.DynamicNodes(cfp, mCadencizer, false, true); + dynamicNodes.printHeader = false; + dynamicNodes.doTask(cell,pw); + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + } + + /** CDL formatter + * Same as Cast2Cdl + **/ + private static class CDLFormatter extends SimpleCellFormatter { + + private final CDLNameInterfaceFactory nameInterfaceFactory; + private final PrintWriter pw; + private final CastFileParser cfp; + private final PartialExtract.CellPlusMinus fqcnSpec; + private final String[] mosParams; + private final Cadencize mCadencizer; + + public CDLFormatter( final PrintWriter pw, + final PartialExtract.CellPlusMinus fqcnSpec, + final CastFileParser cfp, + final CDLNameInterfaceFactory nameInterfaceFactory, + final String[] mosParams, + final Cadencize cadencizer ) { + this.fqcnSpec = fqcnSpec; + this.pw = pw; + this.cfp = cfp; + this.nameInterfaceFactory = nameInterfaceFactory; + this.mosParams = mosParams; + mCadencizer = cadencizer; + } + + public CellInterface prepCell(CellInterface cell, + CellInterface routed) { + return cell; + } + + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + if ( envCell != null ) { + throw new CellFormatterException("I can't format envs"); + } + + final CDLFactoryInterface cdlEmitterFactory = + new CDLFactoryEmitter(pw, true, 79); + + final CDLFactoryInterface renamerFactory = + new CDLRenameFactory( cdlEmitterFactory, + nameInterfaceFactory ); + + + final CDLFactoryInterface templateAccumulatorFactory; + final Map templates; + if ( fqcnSpec.isEmpty() ) { + templateAccumulatorFactory = renamerFactory; + templates = null; + } + else { + templates = new LinkedHashMap(); + templateAccumulatorFactory = new Template( templates ); + } + + /* lvs-nodes hack not needed w/ assura3.1.2 - clayton + final LVSNodes lvsNodes = new LVSNodesForExtract( cfp, + mCadencizer ); + final CDLFactoryInterface lvsNodesEmitter = + new LVSNodesCDLFactory( lvsNodes, + templateAccumulatorFactory, + new LVSNodesNullHandler() ); + final CDLFactoryInterface realNamesEmitter = + //new Cast2Cdl.RealTransistorNames(lvsNodesEmitter, cfp); + */ + + final CDLFactoryInterface realNamesEmitter = + new Cast2Cdl.RealTransistorNames(templateAccumulatorFactory, + cfp); + final CDLFactoryInterface mosParameterFilter = + mosParams == null ? realNamesEmitter + : new Cast2Cdl.MosParameterFilter( + realNamesEmitter, + mosParams); + + Cast2Cdl.outputCDL( cell, + cfp, + mosParameterFilter, + mCadencizer, + false, + true ); + + final String cellName = fqcnSpec.getTop(); + + + if ( ! fqcnSpec.isEmpty() ) { + final PartialExtract pe = + new PartialExtract(templates, cellName, fqcnSpec); + pe.execute( renamerFactory ); + } + + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + } + + /** Signature formatter + * Intended for use with a build-system. Creates a file that should + * change iff when environment or circuit changes. i.e comments and + * irrelevent blocks are ignored + **/ + private static class SignatureFormatter extends SimpleCellFormatter { + private final PrintWriter pw; + private final CastFileParser cp; + private Set seen; + private final Cadencize mCadencizer; + + public SignatureFormatter( final PrintWriter pw, + final CastFileParser cp, + final Cadencize cadencizer ) { + this.pw = pw; + this.cp = cp; + mCadencizer = cadencizer; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + /** + * @pre cell != null + **/ + public void outputCell( + final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + seen = new HashSet(); + try { + printNetlist(cell); + printPRS(cell,seen); + printDirectives(cell); + printExclusives(cell); + pw.println("env:"); + if(envCell != null ) { + printPRS(envCell,seen); + printDirectives(envCell); + printExclusives(envCell); + } + } + catch(UnknownDirectiveException e) { + throw new CellFormatterException("unknown directive"); + } + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + + //block: directive(paramter) = value [type] + private static MessageFormat parameterizedDirectiveFormat = + new MessageFormat("{0}: {1}({2}[{3}]) = {4}[{5}]" ); + //block: directive = value + private static MessageFormat unparameterizedDirectiveFormat = + new MessageFormat("{0}: {1} = {2}" ); + + + void printDirectives(final CellInterface cell) + throws IOException, UnknownDirectiveException { + final DirectiveEmitter de = new SkillDirectiveEmitter(); + final DirectiveActionInterface dai = new DirectiveActionInterface() { + public void doUnParameterizedDirective(BlockInterface block, + DirectiveBlock db, + String directive, + Object value, + String valueType ) throws IOException { + final String[] args = new String[] + { block.getType(), + directive, + de.emit(block.getType(),valueType,value) }; + final String str = + unparameterizedDirectiveFormat.format(args); + pw.println(str); + } + public void doParameterizedDirectiveValue(BlockInterface block, + DirectiveBlock db, + String directive, + Object parameter, + Object value, + String parameterType, + String valueType) throws IOException { + final String[] args = new String[] + { block.getType(), + directive, + de.emit(block.getType(),parameterType, parameter), + parameterType, + de.emit(block.getType(),valueType, value), + valueType }; + final String str = + parameterizedDirectiveFormat.format(args); + pw.println(str); + } + public void doParameterizedDirectiveType(BlockInterface block, + DirectiveBlock db, + String directive, + String parameterType, + String valueType) throws IOException {} + public void doBlockInterface(BlockInterface block) throws IOException {} + }; + final DirectiveWalker dw = new DirectiveWalker(dai); + final BlockInterface cellBlock = cell.getBlockInterface(); + dw.walk(cellBlock); + dw.walk(cellBlock, BlockInterface.PRS); + dw.walk(cellBlock, BlockInterface.SUBCELL); + dw.walk(cellBlock, BlockInterface.ENV); + } + + void printNetlist(CellInterface cell) throws IOException { + CDLFactoryInterface factory = + new CDLFactoryEmitter(pw, true, 79); + + Cast2Cdl.outputCDL(cell, + cp, + factory, + mCadencizer, + false, + true); + } + + + void printPRS(final CellInterface cell, Set seen) { + + if (CellUtils.isWiring(cell) || + !seen.add(cell.getFullyQualifiedType())) return; + + final AliasedSet localNodes = mCadencizer.convert(cell).getLocalNodes(); + cell.getProductionRuleSet().canonicalizeNames(localNodes); + + printPRS(cell.getAssertedProductionRuleSet()); + printPRS(cell.getProductionRuleSet()); + + for (final Iterator i = + new SortingIterator(cell.getLocalSubcellPairs()) + ; i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + pw.println("prs(" + subcell.getFullyQualifiedType() + ":" + + subcellName.getCadenceString() + ")" ); + printPRS(subcell,seen); + } + } + + void printPRS(final ProductionRuleSet prs) { + for (final Iterator i = + new SortingIterator(prs.getProductionRules(), + new StringRepComparator()); + i.hasNext();) { + ProductionRule pr = (ProductionRule) i.next(); + pw.println(pr.toString()); + } + } + + void printExclusives(final CellInterface cell) { + final AliasedSet localNodes = mCadencizer.convert(cell).getLocalNodes(); + OldLVSFormatter.printExclusives(localNodes, + cell.getLocalExclusiveNodeSets(), + HierName.makeHierName(""), + pw + ); + } + } + + /** + * HSIM output formatter. Processes hierarchically, in contrast to + * all the other formatters in this class. The names that are output + * are canonical. + **/ + private static class HSIMFormatter extends SimpleCellFormatter { + final CDLWriter pw; + final PrintWriter w; + private final CastFileParser cfp; + private final int randSeqLen; + private final Cadencize cadencizer; + private final Set seen; + private int deviceId; + private final boolean isolateCell; + private final CDLNameInterface renamer; + private final static String GND = "GND"; + private final static String Vdd = "Vdd"; + private final static Pattern RSOURCE = Pattern.compile("standard\\.random\\.rsource_([ae])1of\\(?(\\d+)\\)?"); + private final Random random; + + HSIMFormatter( final PrintWriter pw, + final CastFileParser cfp, + final int randSeqLen, + final long seed, + final boolean isolateCell, + final CDLNameInterface renamer, + final Cadencize cadencizer ) { + this.w = pw; + this.pw = new CDLWriter(pw, 79); + this.cfp = cfp; + this.randSeqLen = randSeqLen; + this.isolateCell = isolateCell; + this.cadencizer = cadencizer; + this.seen = new HashSet(); + this.deviceId = 0; + this.renamer = renamer; + this.random = new Random(seed); + } + + private String printNode(final HierName hn) { + String name = hn.getCadenceString(); + if (name.startsWith("$")) { + name = "anon_" + name.substring(1); + } + + try { + return renamer.renameNode(name); + } catch (Exception e) { + throw new RuntimeException("Cannot rename node: " + name, e); + } + } + + private String printInstance(final HierName hn) { + String name = hn.getCadenceString(); + if (name.startsWith("$")) { + name = "anon_" + name.substring(1); + } + + try { + return renamer.renameSubCellInstance(name); + } catch (Exception e) { + throw new RuntimeException("Cannot rename instance: " + name, e); + } + } + + private String printCell(final String name) { + try { + return renamer.renameCell(name); + } catch (Exception e) { + throw new RuntimeException("Cannot rename cell: " + name, e); + } + } + + private String nextDevice() { + return "env" + Integer.toString(++deviceId); + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + /** + * @pre cell != null + **/ + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + if (envCell == null) { + if (cell != null) processCell(cell); + } else { + final AliasedSet aliases = cadencizer.convert(cell).getLocalNodes(); + final InstanceData instData = new InstanceData(); + instData.updateExtraDelay(cell, aliases); + processCell(envCell, cell.getFullyQualifiedType() + "_env", cell, instData); + } + + // checkError also flushes + if (w.checkError()) + throw new IOException(); + } + + private void processCell(final CellInterface cell) { + processCell(cell, null, null, null); + } + + private int[] getRandomSequence(int max, int number) { + final int[] result = new int[number]; + for (int i = 0; i < number; ++i) { + result[i] = random.nextInt(max); + } + return result; + } + + private int[] getRandomSequence(int max) { + return getRandomSequence(max, randSeqLen); + } + + /** + * Transform rsources to sources, since + * randomness cannot be simulated this way in SPICE. + **/ + private CellInterface fixupRandom(final CellInterface cell) { + final Matcher mat = RSOURCE.matcher(cell.getFullyQualifiedType()); + if (mat.matches()) { + final StringBuffer sb = new StringBuffer(); + sb.append("standard.source.source_"); + sb.append(mat.group(1)); // a or e + sb.append("1of("); + sb.append(mat.group(2)); // rails + sb.append(","); + final int rails; + try { + rails = Integer.parseInt(mat.group(2)); + } catch (NumberFormatException e) { + throw new RuntimeException("Invalid number of rails in rsource: " + cell.getFullyQualifiedType(), e); + } + + /** + * A e1of1 channel can't really be "randomized", but + * rsource_e1of1 no longer works properly when translated + * normally, so substitution is still required. + **/ + + final int[] rand = getRandomSequence(rails); + sb.append(rand.length); + sb.append(",{"); + sb.append(rand[0]); + for (int i = 1; i < rand.length; ++i) { + sb.append(","); + sb.append(rand[i]); + } + sb.append("})"); + final CellInterface src; + try { + src = cfp.getFullyQualifiedCell(sb.toString()); + } catch (Exception e) { + System.err.println("Warning: Cannot convert " + cell.getFullyQualifiedType() + " to " + sb + ": " + e); + return cell; + } + return src; + } else { + return cell; + } + } + + /** + * Even though both a random source and a source have in the port list + * GND, Vdd, _RESET, and an e1of(N) channel, when the cells are + * emitted, the actual port ordering maybe different, depending on the + * canonical names. We want to substitute all random sources with + * sources by handling everything normally, but printing out the + * corresponding source cell name in place of the random source cell + * name in the X line of the SPICE file. Given a random source, and + * the corresponding substitute source, this function returns a port + * list for the random source cell that is consistent with the port + * list of the source cell, so that it is safe to do the name + * substitution. See bug 9815. + **/ + private String matchPorts(final CellInterface rsrc, + final CellInterface src, + final Collection result) { + // an error message on why rsrc and src cannot be swapped for each + // other + String reason = null; + + final Set rnodes = new HashSet(); + PortDefinition rchan = null; + reason = "the port list of " + rsrc.getFullyQualifiedType() + + " does not match the expected port list of a random" + + " source"; + for (Iterator i = rsrc.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition def = (PortDefinition) i.next(); + final PortTypeInterface type = def.getType(); + if (type instanceof NodeType) { + rnodes.add(def.getName()); + } else if (type instanceof ChannelType) { + if (rchan == null) rchan = def; + else return reason; + } else { + return reason; + } + } + + final Set nodes = new HashSet(); + PortDefinition chan = null; + reason = "the port list of " + src.getFullyQualifiedType() + + " does not match the expected port list of a source"; + for (Iterator i = src.getPortDefinitions(); i.hasNext(); ) { + final PortDefinition def = (PortDefinition) i.next(); + final PortTypeInterface type = def.getType(); + if (type instanceof NodeType) { + nodes.add(def.getName()); + } else if (type instanceof ChannelType) { + if (chan == null) chan = def; + else return reason; + } else { + return reason; + } + } + + reason = "the port lists of " + rsrc.getFullyQualifiedType() + + " and " + src.getFullyQualifiedType() + + " are incompatible"; + // Allow any number of nodes, as long as both cells have them; + // this is meant to handle implied nodes like GND, Vdd, _RESET + if (!rnodes.containsAll(nodes) || !nodes.containsAll(rnodes)) { + return reason; + } + + final Set rsubnodes = CellUtils.markPorts(((ChannelType) rchan.getType()).iterator()).keySet(); + final Set subnodes = CellUtils.markPorts(((ChannelType) chan.getType()).iterator()).keySet(); + // Ensure the channels in the port lists are identical + if (!rsubnodes.containsAll(subnodes) || + !subnodes.containsAll(rsubnodes)) { + return reason; + } + + final AliasedMap rsrcPorts = + cadencizer.convert(rsrc).getPortNodes(); + final AliasedMap srcPorts = + cadencizer.convert(src).getPortNodes(); + // create a mapping from source port name to random source port name + final Map mapping = new HashMap(); + try { + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + final String s = (String) i.next(); + final HierName h = HierName.makeHierName(s, '.'); + mapping.put(srcPorts.getCanonicalKey(h), + rsrcPorts.getCanonicalKey(h)); + } + for (Iterator i = subnodes.iterator(); i.hasNext(); ) { + final String port = (String) i.next(); + final String s = chan.getName() + "." + port; + final String rs = rchan.getName() + "." + port; + final HierName h = HierName.makeHierName(s, '.'); + final HierName rh = HierName.makeHierName(rs, '.'); + mapping.put(srcPorts.getCanonicalKey(h), + rsrcPorts.getCanonicalKey(rh)); + } + } catch (InvalidHierNameException e) { + return "cannot create HierName: " + e.getMessage(); + } + + for (Iterator i = NetlistAdapter.getParameterList(src, cadencizer) + .iterator(); i.hasNext(); ) { + final HierName h = (HierName) i.next(); + result.add(mapping.get(h)); + } + + return null; + } + + /** + * Output the exclusion properties, connections, and, if + * isEnv the prs for the cell. + * + * @param isEnv If the cell results from a named environment. + **/ + private void processCell(final CellInterface cell, + final String envName, + final CellInterface parentCell, + final InstanceData instData) { + if (!seen.add(cell.getFullyQualifiedType())) return; + + // XXX: we can't print out rules involving ERROR because + // that handling is all messed up. See Bug 1047. + // processPRS(cell.getAssertedProductionRuleSet(), prefix); + + /* Save a copy of fully qualified type names of the fixed up cells + * for use later. In particular, this is necessary since the meta + * parameter to the sources are randomly generated. */ + final Map fixupCells = new HashMap(); + + // recurse to subcells + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + if (!CellUtils.isWiring(subcell)) { + final CellInterface fixed = fixupRandom(subcell); + if (fixed != subcell) fixupCells.put(p.getFirst(), fixed); + processCell(fixed); + } + } + + final AliasedSet localNodes = + cadencizer.convert(cell).getLocalNodes(); + + // XXX: we might want to do error checking, ie error + // if !hasCompletePrs && !hasSubcells + final List ports = new ArrayList(); + final List impliedPorts = new ArrayList(); + for (Iterator i = NetlistAdapter.getParameterList(cell, cadencizer).iterator(); i.hasNext(); ) { + final HierName p = (HierName) i.next(); + final String pn = printNode(p); + ports.add(pn); + } + + if (parentCell != null) { + // names of the GND, Vdd and _RESET in this cell + final String localGND = + CellUtils.getLocalImpliedName(parentCell, GND); + final String localVdd = + CellUtils.getLocalImpliedName(parentCell, Vdd); + final String localReset = CellUtils.getResetName(parentCell); + if (localGND == null || localVdd == null || + localReset == null) { + throw new RuntimeException( + "HSIM requires GND, Vdd and _RESET or _Reset as " + + "implied ports in " + + parentCell.getFullyQualifiedType()); + } + + // order of the ports must match what the hsim script expects + for (String p : Arrays.asList(localGND, localVdd, localReset)) { + final HierName canon = + (HierName) localNodes.getCanonicalKey(makeHierName(p)); + final String pn = printNode(canon); + impliedPorts.add(pn); + if (isolateCell) { + impliedPorts.add(pn + "_cell"); + } + } + } + + /* The environment should be a fully contained cell, since it + * instantiates the cell being tested, so it should only have + * implied ports in CAST as its ports. + */ + + final String cellName = (envName == null ? + cell.getFullyQualifiedType() : + envName); + final String[] portNames = (String[]) + (parentCell == null ? + ports.toArray(new String[0]) : + impliedPorts.toArray(new String[0]) ); + pw.subckt(printCell(cellName),portNames,new String[0], new String[0]); + + // Canonicalize the production rules + final ProductionRuleSet prs = cell.getProductionRuleSet(); + prs.canonicalizeNames(localNodes); + final CellDelay delay = new CellDelay(cell, cadencizer); + processPRS(prs,delay,instData); + + final AliasedSet parentLocalNodes; + final Map myPorts; + if (parentCell == null) { + parentLocalNodes = null; + myPorts = null; + } else { + parentLocalNodes = + cadencizer.convert(parentCell).getLocalNodes(); + // The cell and its environment should have the same ports + myPorts = CellUtils.markPorts(parentCell); + } + + // Emit subcircuit calls + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName instance = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final CellInterface realSubcell = + (CellInterface) fixupCells.get(instance); + if (CellUtils.isWiring(subcell)) continue; + + /* To take into account aliases that might occur inside the + * cell being tested, we first determine if a node is connected + * to one of the nodes in the port list, which is shared + * between the cell and its environment. If so, then lookup + * its name in the port list, get the canonical name of the + * port in the context of the cell, get the first port + * associated with that canonical name, and emit its canonical + * name in the context of the environment cell. Example: + + define A()(e1of4 -a, -b) { + prs { + node abe; + a.e = b.e = abe; + } + env { + digital { + rsource_e1of4 _(a); + rsource_e1of4 _(b); + } + } + } + */ + final List subports = new ArrayList(); + final Collection paramList; + if (realSubcell == null) { + paramList = NetlistAdapter.getParameterList(subcell, + cadencizer); + } else { + paramList = new ArrayList(); + final String failed = + matchPorts(subcell, realSubcell, paramList); + if (failed != null) { + throw new RuntimeException( + "Cannot substitute a rsource (" + instance + + ") with a source: " + failed); + } + } + for (Iterator j = paramList.iterator(); j.hasNext(); ) { + final HierName subportName = + HierName.append(instance, (HierName) j.next()); + HierName canon = null; + if (parentCell != null) { + for (Iterator k = localNodes.getAliases(subportName); + k.hasNext(); ) { + final HierName portAlias = (HierName) k.next(); + if (myPorts.containsKey(portAlias.getAsString('.'))) + { + canon = portAlias; + break; + } + } + } + if (canon == null) { + canon = subportName; + } else { + /* We can't directly call getAliases because the + * aliases are stored in a circular list, and the + * iterator returned by it depends on where you are on + * the list. By calling getCanonicalKey first, we + * ensure the iterator returned iterates over the + * aliases in the same order for all aliases of a key. + */ + canon = (HierName) parentLocalNodes.getCanonicalKey(canon); + for (Iterator k = parentLocalNodes.getAliases(canon); + k.hasNext(); ) { + final HierName portAlias = (HierName) k.next(); + if (myPorts.containsKey(portAlias.getAsString('.'))) + { + canon = portAlias; + break; + } + } + } + canon = (HierName) localNodes.getCanonicalKey(canon); + subports.add(printNode(canon)); + } + + pw.X(printInstance(instance), + (String[]) subports.toArray(new String[0]), + printCell(realSubcell == null ? + subcell.getFullyQualifiedType() : + realSubcell.getFullyQualifiedType()), + new String[0]); + } + + // Emit one more subcircuit call to instantiate the real circuit + if (parentCell != null) { + final List subports = new ArrayList(); + for (Iterator i = NetlistAdapter.getParameterList(parentCell, cadencizer).iterator(); i.hasNext(); ) { + HierName canon = + (HierName) parentLocalNodes.getCanonicalKey((HierName) i.next()); + for (Iterator j = parentLocalNodes.getAliases(canon); + j.hasNext(); ) { + final HierName portAlias = (HierName) j.next(); + if (myPorts.containsKey(portAlias.getAsString('.'))) { + canon = portAlias; + break; + } + } + + HierName actual = + (HierName)localNodes.getCanonicalKey(canon); + if (actual == null) actual = canon; + String pn = printNode(actual); + if(isolateCell) { + final HierName base = canon.head().getArrayBase(); + if(parentCell.isImpliedPort(base.getAsString('.'))) { + pn += "_cell"; + } + } + subports.add(pn); + } + pw.X("test", + (String[]) subports.toArray(new String[0]), + printCell(parentCell.getFullyQualifiedType()), + new String[0]); + } + + pw.ends(printCell(envName == null ? cell.getFullyQualifiedType() : + envName)); + } + + private void processPRS(final ProductionRuleSet prs, + final CellDelay delay, + final InstanceData instData) { + final Set targets = new HashSet(); + for (final Iterator i = prs.getProductionRules(); i.hasNext(); ) { + final ProductionRule pr = (ProductionRule) i.next(); + printPR(pr, delay, instData, targets); + } + } + + protected void printPR(final ProductionRule pr, + final CellDelay delay, + final InstanceData instData, + final Set targets) { + final List args = new ArrayList(); + final Iterator iD = + pr.getGuard().DNFForm().getDisjuncts().iterator(); + pw.comment(pr.toString()); + while (iD.hasNext()) { + final AndBooleanExpressionInterface disj = + (AndBooleanExpressionInterface) iD.next(); + final Iterator iC = disj.getConjuncts().iterator(); + int count = 0; + + // guard + while (iC.hasNext()) { + final HierNameAtomicBooleanExpression conj = + (HierNameAtomicBooleanExpression) iC.next(); + + final String cName = printNode(conj.getName()); + if (conj.getSense()) { + args.add(cName); + args.add(GND); + } else { + args.add(Vdd); + args.add(cName); + } + ++count; + } + + final String target = printNode(pr.getTarget()); + final String targ_src = target + "_3a_source"; + final String np, nn; + if (pr.getDirection() == ProductionRule.UP) { + np = Vdd; + nn = targ_src; + } else { + np = targ_src; + nn = GND; + } + + args.add(0, "AND(" + count + ")"); + args.add("0,PrsMaxRes"); + args.add("Vlo,PrsMaxRes"); + args.add("Vhi,PrsMinRes"); + args.add("Vdd,PrsMinRes"); + + pw.G(nextDevice(), np, nn, "vcr", + (String[]) args.toArray(new String[0])); + + args.clear(); + + if (targets.add(target)) { + pw.C(nextDevice(), targ_src, GND, null, "PrsCap", + new String[] { "$MODEL=prescap" }); + final boolean up = pr.getDirection() == ProductionRule.UP; + final int extraDelay = instData == null ? 0 : + Math.round(instData.getExtraDelay(up, pr.getTarget())); + final int after = (int) delay.getDelay(pr.getTarget(), up, 100) + extraDelay; + String afterStr = (pr.isAbsolute() ? after + "ps" : "PrsDelay"); + pw.E(nextDevice(), target, GND, "delay", + new String[] { targ_src, GND, "TD=" + afterStr}); + } + } + } + } + public static class CellTraverser { + final CellProcessor proc; + final Cadencize cadencizer; + final boolean useSuperNamespace; + + public CellTraverser(final CellProcessor p, + final Cadencize cadencizer, + final boolean useSuperNamespace) { + this.proc = p; + this.cadencizer = cadencizer; + this.useSuperNamespace = useSuperNamespace; + } + + public void traverseCell(final CellInterface cell) { + traverseIter(null, cell, + useSuperNamespace ? + new AliasedSet(HierName.getComparator()) : + null, 0); + } + + private void traverseIter(final HierName prefix, + final CellInterface cell, + final AliasedSet superNamespace, + final int currentDepth) { + proc.process(prefix, cell, superNamespace, currentDepth, + cadencizer); + + // recurse to subcells + for (Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + final AliasedSet subcellSuperNamespace; + final HierName fullName = HierName.append(prefix, subcellName); + + if (subcell.isNode()) + continue; + + if (superNamespace != null) { + subcellSuperNamespace = + computeSubcellSuperNamespace(prefix, cell, + subcell, subcellName, superNamespace); + } else + subcellSuperNamespace = null; + + traverseIter(fullName, subcell, subcellSuperNamespace, + currentDepth + 1); + } + } + + private AliasedSet computeSubcellSuperNamespace( + final HierName prefix, + final CellInterface cell, final CellInterface subcell, + final HierName subcellName, + final AliasedSet superNamespace) { + final CadenceInfo ci = cadencizer.convert(cell); + final CadenceInfo subci = cadencizer.convert(subcell); + final AliasedMap subPorts = subci.getPortNodes(); + + // for all ports of cell, find their canonical local name, + // then look that up in the super name space to get the + // global canonical name. + final AliasedSet subcellSuperNamespace = + new AliasedSet(HierName.getComparator()); + + for (final Iterator iSubPortCanon = subPorts.getCanonicalKeys(); + iSubPortCanon.hasNext(); ) { + + final HierName subCanon = (HierName) iSubPortCanon.next(); + + for (final Iterator iSubPortConn = + subPorts.getAliases(subCanon); + iSubPortConn.hasNext(); ) { + + final HierName subConn = (HierName) iSubPortConn.next(); + // @review jmr I'm really not sure if I need to + // be calling prefixName, or if append suffices. + // It can't hurt to call prefixName, though. + final HierName prefixedSubConn = + HierName.prefixName(subcellName, subConn); + + final HierName localCanon = (HierName) + ci.getLocalNodes().getCanonicalKey(prefixedSubConn); + + Debug.assertTrue(localCanon != null); + + final HierName globalCanon = (HierName) + superNamespace.getCanonicalKey(localCanon); + + if (globalCanon != null) + subcellSuperNamespace.makeEquivalent(globalCanon, + HierName.prefixName(prefix, prefixedSubConn)); + else if (localCanon != prefixedSubConn) + subcellSuperNamespace.makeEquivalent( + HierName.prefixName(prefix, localCanon), + HierName.prefixName(prefix, prefixedSubConn)); + } + } + + return subcellSuperNamespace; + } + } + + private static class LVSFormatter + extends SimpleCellFormatter + implements CellProcessor { + protected final PrintWriter pw; + protected final boolean printExclusivesP; + protected final boolean useSuperNamespace; + private final Cadencize mCadencizer; + + public LVSFormatter( final PrintWriter pw, + final boolean useSuperNamespace, + final Cadencize cadencizer ) { + this.pw = pw; + this.printExclusivesP = true; + this.useSuperNamespace = useSuperNamespace; + mCadencizer = cadencizer; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + /** + * Prints prs (if non-env), exclhi/excllo, and connections defined + * in the local node. Does not traverse to subcells. Does not + * print connections to subcells. + **/ + public void outputCell(CellInterface cell, CellInterface envCell) + throws CellFormatterException, IOException { + if (envCell != null) + throw new CellFormatterException( + "Environment not supported."); + new CellTraverser(this, mCadencizer, useSuperNamespace) + .traverseCell(prepCell(cell)); + if (pw.checkError()) + throw new IOException(); + } + + public void process(final HierName prefix, final CellInterface cell, + final AliasedSet superNamespace, final int currentDepth, + final Cadencize cadencizer) { + final CadenceInfo ci = cadencizer.convert(cell); + + if (printExclusivesP) + printExclusives(prefix, cell.getLocalExclusiveNodeSets(), ci); + printPRS(prefix, cell.getProductionRuleSet(), ci); + printConnections(prefix, cell, ci); + } + + protected void printExclusives(final HierName prefix, + final ExclusiveNodeSets excls, + final CadenceInfo ci) { + for (final Iterator iENS = excls.getIterator(); iENS.hasNext(); ) { + final ExclusiveNodeSet ens = (ExclusiveNodeSet) iENS.next(); + + switch (ens.getHiLo()) { + case ExclusiveNodeSet.HI: pw.print("exclhi("); break; + case ExclusiveNodeSet.LO: pw.print("excllo("); break; + case ExclusiveNodeSet.CC: pw.print("exclcc("); break; + default: throw new AssertionError("Invalid ExclusiveNodeSet hiLo value: " + ens.getHiLo()); + } + + boolean firstP = true; + for (final Iterator iNode = ens.getNodes(); iNode.hasNext();) { + final HierName hn = (HierName) iNode.next(); + + if (firstP) + firstP = false; + else + pw.print(','); + + pw.print('"'); + pw.print(prefix.toString()); + pw.print('.'); + pw.print(canonicalName(ci, hn).getAspiceString()); + pw.print('"'); + } + + pw.println(')'); + } + } + + protected void printPRS(final HierName prefix, final ProductionRuleSet prs, + final CadenceInfo ci) { + for (final Iterator iPr = prs.getProductionRules(); iPr.hasNext();) { + ProductionRule pr = (ProductionRule) iPr.next(); + pr = pr.mapNames(new UnaryFunction() { + public Object execute(final Object o) { + final HierName n = + canonicalName(ci, (HierName) o); + if (prefix == null) + return n; + else + return HierName.append( + prefix, + n); + }}); + + printPR(pr); + } + } + + protected void printPR(final ProductionRule pr) { + final BooleanExpressionInterface be = pr.getGuard(); + final HierName hn = pr.getTarget(); + final int dir = pr.getDirection(); + pw.println(be.toUserVisibleString() + + " -> \"" + + hn.getAspiceString() + + (dir == ProductionRule.UP ? "\"+" : "\"-")); + } + + protected void printConnections(final HierName prefix, + final CellInterface cell, + final CadenceInfo ci) { + for (final Iterator iCanonNode = cell.getCanonicalNodes(); + iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + final String canonName = + HierName.prefixName(prefix, canonNode).getAspiceString(); + + for (final Iterator iConnNode = + cell.getConnectedNodes(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + final String connName = + HierName.prefixName(prefix, connNode) + .getAspiceString(); + + // don't print self-connections + if (connNode != canonNode) + pw.println("connect \"" + canonName + + "\" \"" + connName + '"'); + } + } + } + + protected HierName canonicalName(final CadenceInfo ci, final HierName n) { + final HierName c = + (HierName) ci.getLocalNodes().getCanonicalKey(n); + + if (c == null) + return n; + else + return c; + } + } + + private static class OldLVSFormatter extends SimpleCellFormatter { + protected final PrintWriter pw; + protected final Cadencize cadencizer; + public OldLVSFormatter(PrintWriter pw, Cadencize cadencizer) { + this.pw = pw; + this.cadencizer = cadencizer; + } + + public CellInterface prepCell(CellInterface cell) { return cell.flatten(); } + /** + * Prints prs (if non-env), exclhi/excllo, and connections defined in the + * local node. Does not traverse to subcells. Does not print + * connections to subcells. + **/ + public void outputCell( + final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + if (envCell != null) + throw new CellFormatterException( + "Environment not supported."); + printExclusives(cell.getLocalExclusiveNodeSets()); + final ProductionRuleSet prs = cell.getProductionRuleSet(); + printPRS(prs, pw); + printConnections(cell, pw); + // checkError also flushes + if (pw.checkError()) { throw new IOException(); } + } + + void printExclusives(final ExclusiveNodeSets enss) { + printExclusives(enss, null, pw); + } + + public static void printExclusives( + final ExclusiveNodeSets enss, + final HierName prefix, + final PrintWriter pw) { + printExclusives(null,enss,prefix, pw); + } + + //if cadencizer and cell are given non-null, it uses canonical names + //on cell namespace + public static void printExclusives(final AliasedSet localNodes, + final ExclusiveNodeSets enss, + final HierName prefix, + final PrintWriter pw) { + Iterator iENS = enss.getIterator(); + if(localNodes != null) { + iENS = + new SortingIterator( + new MappingIterator( + iENS, + new UnaryFunction() { + public Object execute(Object o) { + return ((ExclusiveNodeSet)o).canonicalizeNames(localNodes); + } + } + ), + new StringRepComparator() + ); + } + for (;iENS.hasNext();) { + final ExclusiveNodeSet ens = (ExclusiveNodeSet) iENS.next(); + printExclusive(ens, prefix, pw); + } + } + + public static void printExclusive( + final ExclusiveNodeSet ens, + final HierName prefix, + final PrintWriter pw) { + switch (ens.getHiLo()) { + case ExclusiveNodeSet.HI: pw.print("exclhi("); break; + case ExclusiveNodeSet.LO: pw.print("excllo("); break; + case ExclusiveNodeSet.CC: pw.print("exclcc("); break; + case ExclusiveNodeSet.NOCC: pw.print("nocc("); break; + default: throw new AssertionError("Invalid ExclusiveNodeSet hiLo value: " + ens.getHiLo()); + } + + boolean firstP = true; + for (final Iterator iNode = + new SortingIterator(ens.getNodes()); + iNode.hasNext();) { + final HierName hn = (HierName) iNode.next(); + + if (firstP) + firstP = false; + else + pw.print(','); + + printName(prefix, + hn, + pw); + } + + pw.println(')'); + } + + public static void printName( + final HierName prefix, + final HierName hn, + final PrintWriter pw) { + printName(prefix == null ? null : prefix.getAspiceString(), + hn.getAspiceString(), pw); + } + + public static void printName( + final String prefix, + final String hn, + final PrintWriter pw) { + pw.print('"'); + if (prefix != null) { + pw.print(prefix); + pw.print('.'); + } + pw.print(hn); + pw.print('"'); + } + + void printPRS(final ProductionRuleSet prs, final PrintWriter pw) { + for (final Iterator iPr = prs.getProductionRules(); iPr.hasNext();) { + final ProductionRule pr = (ProductionRule) iPr.next(); + final BooleanExpressionInterface be = pr.getGuard(); + final HierName hn = pr.getTarget(); + final int dir = pr.getDirection(); + pw.println(be.toUserVisibleString() + + " -> \"" + hn.getAspiceString() + + (pr.getDirection() == ProductionRule.UP ? "\"+" : "\"-")); + } + } + void printConnections(final CellInterface cell, final PrintWriter pw) { + for (final Iterator iCanonNode = cell.getCanonicalNodes(); iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + for (final Iterator iConnNode = cell.getConnectedNodes(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + // don't print self-connections + if (connNode != canonNode) + pw.println("connect \"" + canonNode.getAspiceString() + + "\" \"" + connNode.getAspiceString() + '"'); + } + } + } + } + + private static class AutoFormatter extends LVSFormatter { + + public AutoFormatter(PrintWriter pw, Cadencize cadencizer ) { + super(pw, false, cadencizer); + } + + public void process(final HierName prefix, final CellInterface cell, + final AliasedSet superNamespace, final int currentDepth, + final Cadencize cadencizer) { + final CadenceInfo ci = cadencizer.convert(cell); + + printExclusives(prefix, cell.getLocalExclusiveNodeSets(), ci); + if (currentDepth <= 1) { + printPRS(prefix, cell.getProductionRuleSet(), ci); + } + printConnections(prefix, cell, ci); + } + } + + private static class OldAutoFormatter extends OldLVSFormatter { + public OldAutoFormatter(PrintWriter pw, Cadencize cadencizer) { + super(pw, cadencizer); + } + public CellInterface prepCell(CellInterface cell) { return cell.flatten(1); } + } + + private static class InstanceFormatter extends SimpleCellFormatter { + private PrintWriter pw; + + public InstanceFormatter(PrintWriter pw) { + this.pw = pw; + } + + public CellInterface prepCell(CellInterface cell) { return cell; } + /** + * Prints cell type and full name for whole hierarchy, one per line. + **/ + public void outputCell( + final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + if (envCell != null) + throw new CellFormatterException( + "Environment not supported."); + + printInstanceInfo(null, cell, pw); + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + + private void printInstanceInfo(final String prefix, final CellInterface cell, final PrintWriter pw) + throws IOException { + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + + final String fullName; + if (prefix == null) { + fullName = subcellName.getAspiceString(); + } else { + fullName = prefix + "." + subcellName.getAspiceString(); + } + + if (subcell.hasRealProductionRule()) { + pw.println(subcell.getFullyQualifiedType() + " " + fullName); + printInstanceInfo(fullName, subcell, pw); + } + } + } + } + + /** + * Cosim output formatter. Processes hierarchically, in contrast to + * all the other formatters in this class. The names that are output + * will not be canonical. The wire statements are needed to make + * sense of the output circuit. + **/ + private static class CosimFormatter extends SimpleCellFormatter { + final PrintWriter pw; + private final Cadencize cadencizer; + private final HierName analogCell; + private final CellInterface merge; + + CosimFormatter( final PrintWriter pw, + final String analogCell, + final CellInterface merge, + final Cadencize cadencizer ) { + this.pw = pw; + this.cadencizer = cadencizer; + this.analogCell = makeHierName(analogCell, '.'); + this.merge = merge; + } + + public CellInterface prepCell(CellInterface cell) { + return cell; + } + + public void printName(final HierName hn) { + OldLVSFormatter.printName(null, hn, pw); + } + + /** + * @pre cell != null + **/ + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + assert cell != null && envCell != null; + + final Set seen = new HashSet(); + processCell(cell, seen); + processCell(envCell, seen); + processCell(merge, seen); + processGlue(cadencizer.convert(cell).getPortNodes(), + cell, + HierName.makeHierName("D"), + analogCell, + HierName.makeHierName("A"), + envCell, + HierName.makeHierName("env")); + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + + /** + * Output the exclusion properties, connections, and, if + * isEnv the prs for the cell. + **/ + private void processCell(final CellInterface cell, final Set seen) { + final String type = cell.getFullyQualifiedType(); + if (CellUtils.isWiring(cell) || !seen.add(type)) return; + + // recurse to subcells + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final CellInterface subcell = (CellInterface) p.getSecond(); + processCell(subcell, seen); + } + + final Collection ports = + NetlistAdapter.getParameterList(cell, cadencizer); + + // Emit cell header + pw.print("define \"" + type + "\" ("); + for (Iterator i = ports.iterator(); i.hasNext(); ) { + printName((HierName) i.next()); + if (i.hasNext()) pw.print(", "); + } + pw.println(")() {"); + + final CellDelay delay = new CellDelay(cell, cadencizer); + + + processPRS(cell.getProductionRuleSet(), delay); + // XXX: we can't print out rules involving ERROR because + // that handling is all messed up. See Bug 1047. + processPRS(cell.getAssertedProductionRuleSet(), delay); + + // we don't handle netlist/cdl blocks yet... + processExclusives(cell.getLocalExclusiveNodeSets(), null); + for (final Iterator i = cell.getPortSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + processExclusives(subcell.getLocalExclusiveNodeSets(), + subcellName); + } + + // emit instances + final AliasedSet as = cadencizer.convert(cell).getLocalNodes(); + for (final Iterator i = cell.getSubcellPairs(); i.hasNext(); ) { + final Pair p = (Pair) i.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + + if (!CellUtils.isWiring(subcell)) + processInstance(as, subcellName, subcell); + } + + processConnections(cell); + + processPortConnections(cell); + + // Emit cell footer + pw.println('}'); + } + + private void processPRS(final ProductionRuleSet prs, + final CellDelay delay) { + if (prs.size() > 0) { + pw.println("dsim {"); + for (final Iterator i = prs.getProductionRules(); i.hasNext(); ) + { + final ProductionRule pr = (ProductionRule) i.next(); + printPR(pr, delay); + } + pw.println('}'); + } + } + + protected void printPR(final ProductionRule pr, final CellDelay delay) { + final Iterator iD = + pr.getGuard().DNFForm().getDisjuncts().iterator(); + while (iD.hasNext()) { + final AndBooleanExpressionInterface disj = + (AndBooleanExpressionInterface) iD.next(); + final Iterator iC = disj.getConjuncts().iterator(); + + // modifiers + pw.print("env " + pr.flagsString()); + + final int after = (int) + delay.getDelay(pr.getTarget(), + pr.getDirection() == ProductionRule.UP, + 100); + + pw.print("after " + after + " "); + + // guard + boolean firstP = true; + while (iC.hasNext()) { + final HierNameAtomicBooleanExpression conj = + (HierNameAtomicBooleanExpression) iC.next(); + + if (firstP) firstP = false; + else pw.print('&'); + + if (!conj.getSense()) pw.print('~'); + printName(conj.getName()); + } + + pw.print(" -> "); + + // target + printName(pr.getTarget()); + + // direction + pw.println(pr.getDirection() == ProductionRule.UP ? '+' : '-'); + } + } + + private void processExclusives(final ExclusiveNodeSets enss, + final HierName prefix) { + OldLVSFormatter.printExclusives(enss, prefix, pw); + } + + private void processConnections(final CellInterface cell) { + for (final Iterator iCanonNode = cell.getCanonicalNodes(); + iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + boolean firstP = true; + for (final Iterator iConnNode = + cell.getConnectedNodes(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + // don't print self-connections + if (connNode != canonNode) { + if (firstP) { + firstP = false; + pw.print("wire("); + printName(canonNode); + } + + pw.print(','); + printName(connNode); + } + } + if (!firstP) + pw.println(')'); + } + } + + private void processInstance(final AliasedSet as, + final HierName inst, + final CellInterface subcell) { + final Collection ports = + NetlistAdapter.getParameterList(subcell, cadencizer); + pw.print("\"" + subcell.getFullyQualifiedType() + "\" "); + printName(inst); + pw.print(" ("); + for (Iterator i = ports.iterator(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + final HierName canon = + (HierName) as.getCanonicalKey(HierName.append(inst, port)); + assert canon != null : + "Cannot get canonical name for: " + inst + "." + port; + + printName(canon); + if (i.hasNext()) pw.print(", "); + } + pw.println(") ()"); + } + + private void processGlue(final AliasedMap am, + final CellInterface cell, + final HierName digitalInst, + final HierName analogCell, + final HierName analogInst, + final CellInterface envCell, + final HierName envInst) { + final Collection ports = + NetlistAdapter.getParameterList(cell, cadencizer); + + final HierName htype = + makeHierName(cell.getFullyQualifiedType(), '.'); + processTopLevel(ports, am, digitalInst, htype); + processTopLevel(ports, am, analogInst, analogCell); + + final Collection envPorts = + NetlistAdapter.getParameterList(envCell, cadencizer); + final CadenceInfo ci = cadencizer.convert(envCell); + processTopLevel(envPorts, ci.getPortNodes(), envInst, makeHierName(envCell.getFullyQualifiedType(), '.')); + + final Map portDir = CellUtils.markPorts(envCell); + final Map canonPortDir = new HashMap(); + final AliasedMap envam = + cadencizer.convert(envCell).getPortNodes(); + for (Iterator i = portDir.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName port = + makeHierName((String) entry.getKey(), '.'); + final Object canon = envam.getCanonicalKey(port); + assert canon != null : + "Cannot get canonical name for: " + port; + + canonPortDir.put(canon, entry.getValue()); + } + + final Map envAliases = + getEnvAliases(envPorts, portDir, ci.getLocalNodes()); + final Map cellAliases = getCellAliases(ports, portDir, cadencizer.convert(cell).getLocalNodes()); + + for (Iterator i = envPorts.iterator(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + final HierName canon = (HierName) envam.getCanonicalKey(port); + assert canon != null : + "Cannot get canonical name for: " + port; + + final Integer dir = (Integer) canonPortDir.get(canon); + assert dir != null : + "Cannot get port direction for: " + canon; + + final Collection aliases = + getEnvCellAliases(envAliases, cellAliases, port); + + for (Iterator j = aliases.iterator(); j.hasNext(); ) { + final HierName da = (HierName) j.next(); + if (dir.intValue() == PortDefinition.OUT) { + processSplit(HierName.append(digitalInst, da), + HierName.append(analogInst, da), + HierName.append(envInst, canon)); + } else if (dir.intValue() == PortDefinition.IN) { + processMerge(merge, + HierName.append(digitalInst, da), + HierName.append(analogInst, da), + HierName.append(envInst, canon)); + } else if (dir.intValue() == PortDefinition.INOUT) { + throw new RuntimeException("Do not know how to handle bi-directional port: " + port); + } else { + throw new AssertionError("Invalid port direction: " + dir); + } + } + } + } + + private Collection getEnvCellAliases(final Map envAliases, + final Map cellAliases, + final HierName envPort) { + final Set cellPorts = new HashSet(); + final List castPorts = (List) envAliases.get(envPort); + for (Iterator j = castPorts.iterator(); j.hasNext(); ) { + final String s = (String) j.next(); + cellPorts.addAll((List) cellAliases.get(s)); + } + return cellPorts; + } + + private Map getCellAliases(final Collection actualPorts, + final Map castPorts, + final AliasedSet nodes) { + final Map result = new HashMap(); + final Set portSet = new HashSet(actualPorts); + for (Iterator i = castPorts.entrySet().iterator(); i.hasNext(); ) + { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName port = makeHierName((String) entry.getKey(), '.'); + final HierName canon = (HierName) nodes.getCanonicalKey(port); + final List aliases = new ArrayList(); + for (Iterator j = nodes.getAliases(canon); j.hasNext(); ) { + final HierName portAlias = (HierName) j.next(); + if (portSet.contains(portAlias)) { + aliases.add(portAlias); + } + } + result.put(entry.getKey(), aliases); + } + return result; + } + + private Map getEnvAliases(final Collection actualPorts, + final Map castPorts, + final AliasedSet nodes) { + final Map result = new HashMap(); + for (Iterator i = actualPorts.iterator(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + final HierName canon = (HierName) nodes.getCanonicalKey(port); + final List aliases = new ArrayList(); + for (Iterator j = nodes.getAliases(canon); j.hasNext(); ) { + final String portAlias = + ((HierName) j.next()).getAsString('.'); + + if (castPorts.containsKey(portAlias)) + aliases.add(portAlias); + } + result.put(port, aliases); + } + return result; + } + + private void processMerge(final CellInterface merge, + final HierName digital, + final HierName analog, + final HierName env) { + final Collection ports = + NetlistAdapter.getParameterList(merge, cadencizer); + pw.print("\"" + merge.getFullyQualifiedType() + "\" "); + pw.print("("); + for (Iterator i = ports.iterator(); i.hasNext(); ) { + final String s = ((HierName) i.next()).getAsString('.'); + if (s.equals("digital")) { + printName(digital); + } else if (s.equals("analog")) { + printName(analog); + } else if (s.equals("environ")) { + printName(env); + } else if (s.equals("Vdd")) { + pw.print("Vdd"); + } else if (s.equals("GND")) { + pw.print("GND"); + } else if (s.equals("_RESET")) { + pw.print("_RESET"); + } else { + throw new AssertionError("Unknown port " + s + " in merge cell " + merge.getFullyQualifiedType()); + } + if (i.hasNext()) pw.print(", "); + } + pw.println(") ()"); + } + + private void processSplit(final HierName digital, + final HierName analog, + final HierName env) { + pw.print("wire("); + printName(env); + pw.print(", "); + printName(digital); + pw.print(", "); + printName(analog); + pw.println(")"); + } + + private void processTopLevel(final Collection ports, + final AliasedMap am, + final HierName inst, + final HierName cell) { + printName(cell); + pw.print(" "); + printName(inst); + pw.print(" ("); + for (Iterator i = ports.iterator(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + final HierName canon = (HierName) am.getCanonicalKey(port); + assert canon != null : + "Cannot get canonical name for: " + port; + printName(HierName.append(inst, canon)); + if (i.hasNext()) pw.print(", "); + } + pw.println(") ()"); + } + + private void processPortConnections(final CellInterface cell) { + final AliasedMap portNodes = + cadencizer.convert(cell).getPortNodes(); + for (final Iterator iCanonNode = portNodes.getCanonicalKeys(); + iCanonNode.hasNext(); ) { + final HierName canonNode = (HierName) iCanonNode.next(); + boolean firstP = true; + for (final Iterator iConnNode = + portNodes.getAliases(canonNode); + iConnNode.hasNext(); ) { + final HierName connNode = (HierName) iConnNode.next(); + // don't print self-connections + if (connNode != canonNode) { + if (firstP) { + firstP = false; + pw.print("wire("); + printName(canonNode); + } + + pw.print(','); + printName(connNode); + } + } + if (!firstP) + pw.println(')'); + } + } + } + + private abstract static class FanFormatter implements CellFormatterInterface { + private final PrintWriter pw; + private final CastFileParser cfp; + private final Cadencize cad; + + /** + * If non-null, specify the set of nodes to determine fanout for. + **/ + private final Set nodes; + + /** + * Whether to ignore feedback NetPaths when determining fanout. + **/ + private final boolean ignoreFeedback; + + /** + * Output information for "routed" local nodes? + **/ + private final boolean routed; + + // fqcn -> (fanin -> fanouts) + private final Map>> cache = + new HashMap>>(); + + private CadenceInfo topInfo = null; + + protected interface Result {} + + public FanFormatter(final PrintWriter pw, + final CastFileParser cfp, + final Cadencize cad, + final Set nodes, + final boolean ignoreFeedback, + final boolean routed) { + this.pw = pw; + this.cfp = cfp; + this.cad = cad; + this.nodes = nodes; + this.ignoreFeedback = ignoreFeedback; + this.routed = routed; + } + + public CellInterface prepCell(CellInterface cell, + CellInterface routed) { + // handle routed hierarchy independently, because the flattening of + // unrouted cells with netlist blocks does not work properly, and + // even if it did, NetGraph does not handle netlists with multiple + // Vdds + return cell; + } + + protected abstract Result resolveNames(final HierName path, + final HierName canon, + final HierName related, + final Cadencize cad, + final CellInterface topCell, + final CadenceInfo topInfo); + + protected abstract void getFan(final NetGraph ng, + final AliasedSet localNodes, + final Map> result, + final boolean ignoreFeedback); + + private Map> getFan(final CellInterface cell) { + Map> result = + cache.get(cell.getFullyQualifiedType()); + if (result == null) { + final CadenceInfo ci = cad.convert(cell); + final ArrayList problems = new ArrayList(); + final ExclusiveNodeSets exclusives = new ExclusiveNodeSets(); + exclusives.merge(ci.getPortExclusiveNodeSets()); + exclusives.merge(ci.getLocalExclusiveNodeSets()); + final AliasedSet localNodes = ci.getLocalNodes(); + final NetGraph ng = new NetGraph( + localNodes, + exclusives, + problems, + HierName.makeHierName("Vdd"), + HierName.makeHierName("GND"), + Collections.emptySet()); + try { + ng.addCellInterface(cell, new NetGraph[0], cfp, cad); + } catch (com.avlsi.prs.UnimplementableProductionRuleException e) + { + throw new RuntimeException("Can't happen"); + } + ng.prepareForLvs(); + assert problems.isEmpty(); + + result = new HashMap>(); + getFan(ng, localNodes, result, ignoreFeedback); + cache.put(cell.getFullyQualifiedType(), result); + } + return result; + } + + protected Triplet + findRouted(CellInterface cell, HierName remain) { + HierName instRouted = null; + HierName instSinceRouted = null; + CellInterface routed = cell; + Pair parts; + + do { + parts = CellUtils.getFirstInstance(cell, remain, true); + final HierName inst = parts.getFirst(); + if (inst != null) { + instSinceRouted = HierName.append(instSinceRouted, inst); + + final CellInterface subcell = cell.getSubcell(inst); + if (!this.routed || CellUtils.isRouted(subcell)) { + instRouted = + HierName.append(instRouted, instSinceRouted); + instSinceRouted = null; + routed = subcell; + } + remain = parts.getSecond(); + cell = subcell; + } + } while (parts.getFirst() != null && remain != null); + + return new Triplet( + instRouted, + routed, + remain == null ? instSinceRouted + : HierName.append(instSinceRouted, remain)); + } + + /** + * Descends the hierarchy to find all fanouts of a given fanin node. + **/ + private void descend( + final CellInterface cell, + final CadenceInfo ci, + final CellInterface topCell, + final CadenceInfo topInfo, + final HierName name, + final HierName path, + final Set result) { + final HierName canon = + (HierName) ci.getLocalNodes().getCanonicalKey(name); + if (cell.containsNetlist()) { + final Set fanouts = getFan(cell).get(canon); + if (fanouts != null) { + for (HierName fanout : fanouts) { + result.add(resolveNames(path, canon, fanout, cad, + topCell, topInfo)); + } + } + } else { + final AliasedSet nodes = ci.getLocalNodes(); + final Set seen = new HashSet(); + for (Iterator i = nodes.getAliases(canon); i.hasNext(); ) { + final HierName node = (HierName) i.next(); + final Pair p = + CellUtils.getFirstInstance(cell, node, true); + if (p.getFirst() != null) { + final HierName inst = p.getFirst(); + final CadenceInfo subci = ci.getSubcell(inst); + if (subci != null) { + final HierName subnode = p.getSecond(); + final Boolean realPort = + ((Boolean) subci.getPortNodes() + .getValue(subnode)); + if (realPort.booleanValue()) { + final HierName canonPort = + (HierName) subci.getPortNodes() + .getCanonicalKey(subnode); + if (seen.add(HierName.append(p.getFirst(), + canonPort))) { + descend(cell.getSubcell(inst), + ci.getSubcell(inst), + topCell, topInfo, + subnode, + HierName.append(path, inst), + result); + } + } + } + } + } + } + } + + public void outputCell(final CellInterface cell, + final CellInterface envCell) + throws CellFormatterException, IOException { + + if(envCell != null ) { + return; + } + + outputCell(cell, null, cell); + + // checkError also flushes + if (pw.checkError()) + throw new IOException(); + } + + private void outputCell(final CellInterface cell, + final HierName prefix, + final CellInterface top) { + final CadenceInfo info = cad.convert(cell); + if (topInfo == null) topInfo = info; + + final AliasedSet locals = info.getLocalNodes(); + final AliasedMap ports = info.getPortNodes(); + final Iterator i; + if (nodes == null) { + i = new FilteringIterator(locals.getCanonicalKeys(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return ports.getCanonicalKey(o) == null; + } + }); + } else { + final Set hnodes = new HashSet(); + for (String node : nodes) { + hnodes.add(makeHierName(node)); + } + i = hnodes.iterator(); + } + while (i.hasNext()) { + final HierName canon = (HierName) i.next(); + + final Set result = new TreeSet(); + descend(cell, info, top, topInfo, canon, prefix, result); + if (!result.isEmpty()) { + pw.print(HierName.append(prefix, canon)); + for (Result r : result) { + pw.print(" " + r); + } + pw.println(); + } + } + + if (routed) { + for (Iterator j = new SortingIterator(cell.getSubcellPairs()); + j.hasNext(); ) { + final Pair p = + (Pair) j.next(); + final CellInterface subcell = p.getSecond(); + if (info.getSubcell(p.getFirst()) != null && + !CellUtils.isRouted(subcell)) { + outputCell(subcell, + HierName.append(prefix, p.getFirst()), + top); + } + } + } + } + } + + private static class FaninFormatter extends FanFormatter { + private static class FaninResult implements Result, + Comparable { + private final String fqcn; + private final HierName relFanIn; + private final HierName absFanIn; + + FaninResult(final String fqcn,final HierName relFanIn, + final HierName absFanIn) { + this.fqcn = fqcn; + this.relFanIn = relFanIn; + this.absFanIn = absFanIn; + } + + public String toString() { + return fqcn + "/" + relFanIn + "/" + absFanIn; + } + + public int compareTo(FaninResult o) { + return ObjectUtils.compare(fqcn, o.fqcn, + relFanIn, o.relFanIn, + absFanIn, o.absFanIn); + } + } + + public FaninFormatter(final PrintWriter pw, + final CastFileParser cfp, + final Cadencize cad, + final Set nodes, + final boolean ignoreFeedback, + final boolean routed) { + super(pw, cfp, cad, nodes, ignoreFeedback, routed); + } + + protected Result resolveNames(final HierName path, + final HierName canon, + final HierName related, + final Cadencize cad, + final CellInterface topCell, + final CadenceInfo topInfo) { + final Triplet rel = + CellUtils.localize(HierName.append(path, related), + topInfo, false); + final CellInterface routedCell; + final HierName relFanIn; + if (rel.getFirst() == null) { + routedCell = topCell; + relFanIn = rel.getThird(); + } else { + final Triplet t = + findRouted(topCell, rel.getFirst()); + routedCell = t.getSecond(); + relFanIn = t.getThird() == null + ? rel.getThird() + : HierName.append(t.getThird(), rel.getThird()); + } + + final HierName absFanIn = + HierName.append(rel.getFirst(), rel.getThird()); + + return new FaninResult(routedCell.getFullyQualifiedType(), + relFanIn, absFanIn); + } + + protected void getFan(final NetGraph ng, + final AliasedSet localNodes, + final Map> result, + final boolean ignoreFeedback) { + for (Iterator n = ng.getNodes().iterator(); n.hasNext(); ) { + final NetGraph.NetNode node = (NetGraph.NetNode) n.next(); + for (Iterator i = node.getPaths().iterator(); + i.hasNext(); ) { + final NetGraph.NetPath p = (NetGraph.NetPath) i.next(); + if (ignoreFeedback && p.isFeedBack()) continue; + + for (NetGraph.NetNode out : + Arrays.asList(p.getStartNode(), p.getEndNode())) { + // only include names that are valid CAST names + if (!out.isRail() && localNodes.contains(out.name)) { + Set fanins = result.get(out); + if (fanins == null) { + fanins = new HashSet(); + result.put(out.name, fanins); + } + for (Iterator j = p.getGateNodes().iterator(); + j.hasNext(); ) { + final NetGraph.NetNode g = + (NetGraph.NetNode) j.next(); + fanins.add(g.name); + } + } + } + } + } + } + + } + + private static class FanoutFormatter extends FanFormatter { + private static class FanoutResult implements Result, + Comparable { + private final String fqcn; + private final HierName fanin; + private final HierName fanout; + + FanoutResult(final String fqcn,final HierName fanin, + final HierName fanout) { + this.fqcn = fqcn; + this.fanin = fanin; + this.fanout = fanout; + } + + public String toString() { + return fqcn + "/" + fanin + "/" + fanout; + } + + public int compareTo(FanoutResult o) { + return ObjectUtils.compare(fqcn, o.fqcn, + fanin, o.fanin, + fanout, o.fanout); + } + } + + public FanoutFormatter(final PrintWriter pw, + final CastFileParser cfp, + final Cadencize cad, + final Set nodes, + final boolean ignoreFeedback, + final boolean routed) { + super(pw, cfp, cad, nodes, ignoreFeedback, routed); + } + + /** + * Returns a map from fanin to set of fanouts in a cell containing a + * netlist block. Iterate over all NetPath in the NetGraph created + * from the netlist block; nodes that gate NetEdges in a NetPath are + * considered fanins of the ends of the NetPath (unless the end is a + * power rail). Results are cached per fqcn. + **/ + protected void getFan(final NetGraph ng, + final AliasedSet localNodes, + final Map> result, + final boolean ignoreFeedback) { + for (Iterator n = ng.getNodes().iterator(); n.hasNext(); ) { + final NetGraph.NetNode node = (NetGraph.NetNode) n.next(); + for (Iterator i = node.getPaths().iterator(); + i.hasNext(); ) { + final NetGraph.NetPath p = (NetGraph.NetPath) i.next(); + if (ignoreFeedback && p.isFeedBack()) continue; + + for (Iterator j = p.getGateNodes().iterator(); + j.hasNext(); ) { + final NetGraph.NetNode g = + (NetGraph.NetNode) j.next(); + for (NetGraph.NetNode out : + Arrays.asList(p.getStartNode(), + p.getEndNode())) { + // only include names that are valid CAST names + if (!out.isRail() && + localNodes.contains(out.name)) { + Set fanouts = result.get(g.name); + if (fanouts == null) { + fanouts = new HashSet(); + result.put(g.name, fanouts); + } + fanouts.add(out.name); + } + } + } + } + } + } + + protected Result resolveNames(final HierName path, + final HierName canon, + final HierName related, + final Cadencize cad, + final CellInterface topCell, + final CadenceInfo topInfo) { + final Triplet sink = + CellUtils.localize(HierName.append(path, related), + topInfo, false); + final CellInterface routedCell; + HierName relFanIn = HierName.append(path, canon); + final HierName relFanOut; + if (sink.getFirst() == null) { + routedCell = topCell; + relFanOut = sink.getThird(); + } else { + final Triplet t = + findRouted(topCell, sink.getFirst()); + routedCell = t.getSecond(); + relFanOut = t.getThird() == null + ? sink.getThird() + : HierName.append(t.getThird(), sink.getThird()); + if (t.getFirst() != null) { + relFanIn = relFanIn.tail(t.getFirst().getNumComponents()); + } + } + final Triplet src = + CellUtils.localize(relFanIn, cad.convert(routedCell), false); + relFanIn = HierName.append(src.getFirst(), src.getThird()); + return new FanoutResult(routedCell.getFullyQualifiedType(), + relFanIn, relFanOut); + } + } + + /** + * Make multiple formatters into one. The formatters must return the same + * cell from prepCell. + **/ + private static class AggregateFormatter implements CellFormatterInterface { + private final CellFormatterInterface[] formatters; + public AggregateFormatter(final CellFormatterInterface a, + final CellFormatterInterface b) { + this(new CellFormatterInterface[] { a, b }); + } + public AggregateFormatter(final CellFormatterInterface[] formatters) { + assert formatters != null && formatters.length > 1 && + formatters[0] != null; + this.formatters = formatters; + } + public void outputCell(CellInterface cell, CellInterface envCell) + throws CellFormatterException, IOException { + for (int i = 0; i < formatters.length; ++i) { + formatters[i].outputCell(cell, envCell); + } + } + public CellInterface prepCell(CellInterface cell, + CellInterface routed) { + for (int i = 1; i < formatters.length; ++i) { + formatters[i].prepCell(cell, routed); + } + return formatters[0].prepCell(cell, routed); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/custom.mk new file mode 100644 index 0000000000..30c649aaa1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/custom.mk @@ -0,0 +1,5 @@ +CURR_RESULT_FILES := $(CURR_RESULT_FILES) $(CURR_TARGET_DIR)/jflat.sh + +$(CURR_TARGET_DIR)/jflat.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.jflat.JFlat/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/javafiles-custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/javafiles-custom.mk new file mode 100644 index 0000000000..a68c3dcc74 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/javafiles-custom.mk @@ -0,0 +1,4 @@ + +$(CURR_TARGET_DIR)/JFlat.java_files_classbuild: $(call CONONICALIZE_PATH,$(CURR_TARGET_DIR)/../../csp/csp2java/runtime/javaclasses) + +JAVAFILES_EXTRA_JAR_CLASSES := $(wildcard $(CURR_PROJECT_DIR)/../../util/cmdline/*.java) $(wildcard $(CURR_PROJECT_DIR)/../../csp/csp2java/runtime/*.java) diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/jflat.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/jflat.package new file mode 100644 index 0000000000..22682662de --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/jflat/jflat.package @@ -0,0 +1,10 @@ +2 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +include ../../csp/csp2java/runtime/cspruntime.package.inc ../../csp/csp2java/runtime +include ../../csp/resources/resources.package.inc ../../csp/resources +java com.avlsi.tools.jflat.JFlat +$arch/bin/jflat.sh jflat.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Dnf.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Dnf.java new file mode 100644 index 0000000000..882a9c1dce --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Dnf.java @@ -0,0 +1,295 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.lvs; + +import java.util.List; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.Map; + +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.bool.*; +import com.avlsi.prs.ProductionRule; +import com.avlsi.file.common.HierName; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; + +/** Utilities for handling disjunctive normal form representation of an expression. */ +public class Dnf { + /** + * This class should not be instantiated. + **/ + private Dnf() { } + + /** Compute netUp, netDn, holdUp, holdDn DNF's from NetNode's paths. */ + public static void fromNetNode(NetGraph.NetNode node, + MultiSet netUp, MultiSet netDn, + MultiSet holdUp, MultiSet holdDn) { + Iterator t = node.paths.iterator(); + while (t.hasNext()) { + NetGraph.NetPath path = (NetGraph.NetPath) t.next(); + MultiSet guard = path.getUniqueGates(); + int dir = path.getDir(); + if (dir==+1) { + if (!path.feedback) netUp.addIfUnique(guard); + else holdUp.addIfUnique(guard); + } + else if (dir==-1) { + if (!path.feedback) netDn.addIfUnique(guard); + else holdDn.addIfUnique(guard); + } + } + } + + /** Make a DNF from guard and dir, return null if non-inverse-monotonic */ + public static MultiSet fromExpression(BooleanExpressionInterface guard, + int dir, + final AliasedSet namespace, + final ExclusiveNodeSets exclusives) { + MultiSet dnf = new MultiSet(); + Collection disjuncts = guard.DNFForm().getDisjuncts(); + for (Iterator i = disjuncts.iterator(); i.hasNext(); ) { + MultiSet term = new MultiSet(); + Collection conjuncts = + ((AndBooleanExpressionInterface) i.next()).getConjuncts(); + for (Iterator j = conjuncts.iterator(); j.hasNext(); ) { + HierNameAtomicBooleanExpression literal = + (HierNameAtomicBooleanExpression) j.next(); + if ((!literal.getSense() && (dir == ProductionRule.DOWN)) || + ( literal.getSense() && (dir == ProductionRule.UP))) return null; + term.add((HierName) namespace.getCanonicalKey(literal.getName())); + } + dnf.add(term); + } + return getCanonicalForm(dnf,dir,exclusives); + } + + /** + * Get a canonical representation of a DNF. Removes redundant + * gates in terms. Removes terms which have other terms as a + * subset. Removes exluded terms. + */ + public static MultiSet getCanonicalForm(MultiSet b, final int dir, + final ExclusiveNodeSets exclusives) { + MultiSet c = new MultiSet(); + for (Iterator i = b.iterator(); i.hasNext(); ) { + MultiSet bterm1 = (MultiSet) i.next(); + + // search for any subsets of bterm1 + boolean ok = true; + for (Iterator j = b.iterator(); j.hasNext(); ) { + MultiSet bterm2 = (MultiSet) j.next(); + if (bterm2.isSubset(bterm1) && !bterm1.isSubset(bterm2)) { + ok=false; break; + } + } + if (!ok) continue; + + // create cterm by deleting redundant gates of bterm1 + MultiSet cterm = new MultiSet(); + cterm.addAllIfUnique(bterm1); // avoid redundant terms + + // add cterm if not excluded + if (((dir == ProductionRule.UP) && + (!exclusives.areExclusive(ExclusiveNodeSet.LO,cterm))) || + ((dir == ProductionRule.DOWN) && + (!exclusives.areExclusive(ExclusiveNodeSet.HI,cterm)))) + c.addIfUnique(cterm); + } + return c; + } + + /** + * Removes terms in a already covered by terms in b. Used to + * strip out unnecessary combinational staticizer transistors. + **/ + public static MultiSet eliminateRedundantTerms(MultiSet a, MultiSet b) { + MultiSet c = new MultiSet(); + for (Iterator i = a.iterator(); i.hasNext(); ) { + MultiSet aterm = (MultiSet) i.next(); + + // search for any subsets of aterm in b + boolean ok = true; + for (Iterator j = b.iterator(); j.hasNext(); ) { + MultiSet bterm = (MultiSet) j.next(); + if (bterm.isSubset(aterm)) { + ok=false; break; + } + } + if (!ok) continue; + + // create cterm and add it to c + MultiSet cterm = new MultiSet(); + cterm.addAll(aterm); + c.add(cterm); + } + return c; + } + + /** + * Make a DNF from guard. This differs from + * fromExpression(BooleanExpressionInterface, int, AliasedSet, + * ExclusiveNodeSets) in that it does not care about inverse monoticity. + */ + public static MultiSet fromExpression( + final BooleanExpressionInterface guard, final AliasedSet namespace, + final ExclusiveNodeSets exclusives) { + MultiSet dnf = new MultiSet(); + Collection disjuncts = guard.DNFForm().getDisjuncts(); + for (Iterator i = disjuncts.iterator(); i.hasNext(); ) { + MultiSet term = new MultiSet(); + Collection conjuncts = + ((AndBooleanExpressionInterface) i.next()).getConjuncts(); + for (Iterator j = conjuncts.iterator(); j.hasNext(); ) { + HierNameAtomicBooleanExpression literal = + (HierNameAtomicBooleanExpression) j.next(); + HierName canon = + (HierName) namespace.getCanonicalKey(literal.getName()); + term.add(new HierNameAtomicBooleanExpression( + literal.getSense(), canon)); + } + dnf.add(term); + } + return getCanonicalForm(dnf,exclusives); + } + + /** + * Get a canonical representation of a DNF. This is the same as + * getCanonicalForm(MultiSet, int, ExclusiveNodeSet), except when removing + * excluded terms, it doesn't assume inverse monoticity. + **/ + public static MultiSet getCanonicalForm( + final MultiSet b, final ExclusiveNodeSets exclusives) { + MultiSet c = new MultiSet(); + for (Iterator i = b.iterator(); i.hasNext(); ) { + MultiSet bterm1 = (MultiSet) i.next(); + + // search for any subsets of bterm1 + boolean ok = true; + for (Iterator j = b.iterator(); j.hasNext(); ) { + MultiSet bterm2 = (MultiSet) j.next(); + if (bterm2.isSubset(bterm1) && !bterm1.isSubset(bterm2)) { + ok=false; break; + } + } + if (!ok) continue; + + // create cterm by deleting redundant gates of bterm1 + MultiSet cterm = new MultiSet(); + cterm.addAllIfUnique(bterm1); // avoid redundant terms + + // partition literals in the cterm + Set loTerms = new HashSet(); + Set hiTerms = new HashSet(); + for (Iterator j = cterm.iterator(); j.hasNext(); ) { + HierNameAtomicBooleanExpression literal = + (HierNameAtomicBooleanExpression) j.next(); + if (literal.getSense()) hiTerms.add(literal.getName()); + else loTerms.add(literal.getName()); + } + + // add cterm if not excluded and no literal appears with both + // non-negated and negated senses + if (!exclusives.areExclusive(ExclusiveNodeSet.LO,loTerms) && + !exclusives.areExclusive(ExclusiveNodeSet.HI,hiTerms) && + Collections.disjoint(loTerms,hiTerms)) { + c.addIfUnique(cterm); + } + } + return c; + } + + /** Create a DNF with one literal. */ + public static MultiSet createSingleGateDnf(HierName a) { + MultiSet c = new MultiSet(); + MultiSet term = new MultiSet(); + term.add(a); + c.add(term); + return c; + } + + /** Add a conjunctive literal to a DNF. */ + public static MultiSet addConjunctGate(MultiSet a, HierName b) { + MultiSet c = new MultiSet(); + Iterator t = a.iterator(); + while (t.hasNext()) { + MultiSet term = new MultiSet((MultiSet) t.next()); + term.add(b); + c.addIfUnique(term); + } + return c; + } + + /** + * Return the dual of a DNF. + * May still have superset or exclusive terms, + * use getCanonicalForm to strip these out. + */ + public static MultiSet dual(MultiSet a) { + // count depth and number of conjunctions + int d = a.size(), n = 1; + for (int i=0; i + * .subckt FOO Vdd! GND! 0 1 2 3 + * ... + * .ends FOO + * + * Xfoo Vdd! GND! Vdd! Vdd! GND! GND! FOO + * **/ + private static final boolean unconnectedGlobalsAllowed = true; + + /** Map from name of pairs of cast and layout cells that have been + * done to array of LVSProblems therein **/ + private final Map doneMap; + + /** Map from layout type (String) to Map from port name (HierName) to the + * global it is connected to (HierName). This is for Vdd! and GND!. **/ + private final Map globalMap; + + /** Map from layout type (String) to Set of globals (HierNames) that + * at least one port must be connected to. **/ + private final Map neededGlobalsMap; + + /** The AspiceFile of layout that is being checked. **/ + private final AspiceFile aspiceCell; + + /** The cast cell definition against which the layout is being + * checked. **/ + private final CellInterface cell; + + /** + * Cadencizer, keep this around to persist the map of cadencized cells. + **/ + private final Cadencize cadencizer; + + /** + * Class constructor. + **/ + private LVS(final Map doneMap, final Map globalMap, + final Map neededGlobalsMap, + final Cadencize cadencizer, + final CellInterface cell, final AspiceFile aspiceCell) { + this.doneMap = doneMap; + this.globalMap = globalMap; + this.neededGlobalsMap = neededGlobalsMap; + this.cadencizer = cadencizer; + this.cell = cell; + this.aspiceCell = aspiceCell; + + Debug.assertTrue(doneMap != null); + Debug.assertTrue(unconnectedGlobalsAllowed == (globalMap != null)); + Debug.assertTrue(unconnectedGlobalsAllowed == + (neededGlobalsMap != null)); + Debug.assertTrue(cadencizer != null); + Debug.assertTrue(aspiceCell != null); + Debug.assertTrue(cell != null); + } + + /** + * Class constructor. + **/ + public LVS(final CellInterface cell, final AspiceFile aspiceCell) { + this( cell, aspiceCell, new Cadencize(true) ); + } + + /** + * Class constructor. + **/ + public LVS( final CellInterface cell, + final AspiceFile aspiceCell, + final Cadencize cadencizer ) { + this( new HashMap(), + unconnectedGlobalsAllowed ? new HashMap() : null, + unconnectedGlobalsAllowed ? new HashMap() : null, + cadencizer, + cell, + aspiceCell); + } + + /** + * Run the lvs pass, returning a pair of a map from pairs of CAST cell + * names and specification cell names to an array of + * LVSProblems, and a Boolean. + * Boolean.TRUE if this cell is bypassed due to + * prs_netlist_mismatch_ok, and Boolean.FALSE otherwise. + **/ + public Pair/*,LVSProblem[]>, Boolean>*/ + lvs(final boolean checkSubcells, final boolean checkWires, + final boolean checkUnwired, final boolean checkPRS, + double minStaticizerRatio, double maxStaticizerRatio, + final boolean inlineLayout) { + final List problemList = new ArrayList(); + + // + // types + // + + if (VERBOSE) { + debugPrintln("Cast type: " + cell.getFullyQualifiedType()); + debugPrintln("Aspice type: " + aspiceCell.getName()); + } + + // note that we compare the name using the equivtype, + // but still use the original cell. + final String castType = cell.getFullyQualifiedType(); + final String aspiceBaseType = aspiceCell.getName(); + + // Checking only the name is a bit dangerous. We should also + // check that we actually have the same cell. + final Pair keyPair = + new Pair(castType, aspiceCell.getName()); + if (doneMap.get(keyPair) != null) + return new Pair(doneMap, Boolean.FALSE); + + // Check the types. Stop here if they don't agree, because we + // will just get a bunch of meaningless errors if we + // checked a BUF_1of2 vs. a BB_1of4 or something. + if ( ! castType.equals(aspiceBaseType) ) { + problemList.add(new LVSProblem( "Types don't match: " + + castType + " vs. " + + aspiceBaseType ) ); + final LVSProblem[] problems = + (LVSProblem[]) problemList.toArray(new LVSProblem[0]); + doneMap.put(keyPair, problems); + return new Pair(doneMap, Boolean.FALSE); + } + + // Do not LVS cells that are known to not match + if (((Boolean) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.PRS_NETLIST_MISMATCH_OK)).booleanValue()) { + problemList.add(new LVSProblem( "Type " + castType + " has prs_netlist_mismatch_ok = true, LVS checking bypassed.", LVSProblem.LVS_WARNING)); + final LVSProblem[] problems = + (LVSProblem[]) problemList.toArray(new LVSProblem[0]); + doneMap.put(keyPair, problems); + return new Pair(doneMap, Boolean.TRUE); + } + + // + // subcells, make sure the subcell names and types are the same + // + final Set aspiceSubcells = getAspiceSubcells(); + final Set castSubcells = getCastSubcells(); + final boolean hierarchyOK = + checkHierarchy(aspiceSubcells, castSubcells, problemList); + // Stop the check if the hierarchies don't agree. + // We will run into NullPointerExceptions in checkNamespace() + // if the subcell names don't match. + if (!hierarchyOK) { + final LVSProblem[] problems = + (LVSProblem[]) problemList.toArray(new LVSProblem[0]); + doneMap.put(keyPair, problems); + return new Pair(doneMap, Boolean.FALSE); + } + + // + // check namespace, then PRS + // + + if (checkWires) { + final AliasedSet commonNamespace = + checkNamespace(problemList,checkUnwired); + if (checkPRS) { + new LvsOperators(cell, + aspiceCell, + commonNamespace, + cadencizer.convert(cell) + .getLocalExclusiveNodeSets() + .canonicalizeNames(commonNamespace), + problemList,minStaticizerRatio,maxStaticizerRatio, + HierName.makeHierName("Vdd"), + HierName.makeHierName("GND")).check(); + } + } + + // + // recursively check subcells + // + + if (checkSubcells) { + // perhaps we should structure it as + // 1: first do complete hierarchy checking, but no prs + // 2: then recheck (needlessly) hierarchy, along with prs + // this would allow us to report hierarchy errors quickly + // actually, it seems better to do this in main() + for (final Iterator iSubcellName = castSubcells.iterator(); + iSubcellName.hasNext(); ) { + final String useName = (String) iSubcellName.next(); + + if (aspiceSubcells.contains(useName)) { + final HierName subCellName; + try { + subCellName = HierName.makeHierName(useName, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionFailure(e); + } + final CellInterface subCell = + cell.getSubcell(subCellName); + final AspiceFile subAspice = + aspiceCell.getSubcellDefForName(useName); + final LVS subLVS = new LVS(doneMap, globalMap, + neededGlobalsMap, + cadencizer, + inlineLayout ? subCell.inlineLayoutSubcells() : + subCell, + subAspice); + + subLVS.lvs(true, checkWires, checkUnwired, checkPRS, minStaticizerRatio, maxStaticizerRatio, inlineLayout); + } + } + } + + // Do you want a way to find out which nodes were in the + // port list in both cast and layout? This can be done. + + Object o; + final LVSProblem[] problems = + (LVSProblem[]) problemList.toArray(new LVSProblem[0]); + o = doneMap.put(keyPair, problems); + Debug.assertTrue(o == null); + return new Pair(doneMap, Boolean.FALSE); + } + + /** + * Returns a Set of subcells that are in the + * cast that should also appear in the layout. Cells + * without production rules should not appear in the + * hierarchy (ie channels and wiring cells are ignored) + **/ + private Set getCastSubcells() { + final Set castSubcells = new HashSet(); + + if (VERBOSE) + debugPrintln("Cast subcells:"); + // there are other ways of accessing the subcells. Perhaps + // a more convenient way could be written depending on what + // you want to do. + for (final Iterator iSubPair = cell.getSubcellPairs(); + iSubPair.hasNext(); ) { + final Pair p = (Pair) iSubPair.next(); + final HierName useName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + + if (VERBOSE) + debugPrintln(useName.getAspiceString() + ": " + + subcell.getFullyQualifiedType()); + + if (!CellUtils.isWiring(subcell)) + castSubcells.add(useName.getAspiceString()); + } + + return castSubcells; + } + + /** + * Returns a Set of subcells that are in the layout + * that should also appear in the cast. Cells without devices + * should not appear in the layout hierarchy (ie wiring cells are + * ignored). NOTE, this now checks cells with explict resistors + * and capacitors. These used to be ignored when CDL was + * extracted, but now that it is a pure spec without parasitics + * this should be checked. -- AML + **/ + private Set getAspiceSubcells() { + final Set aspiceSubcells = new HashSet(); + + if (VERBOSE) + debugPrintln("Aspice subcells:"); + // this isn't the same as for cast due to historical accident + // it can be changed + for (final Iterator iSubcellName = aspiceCell.getSubcellNames(); + iSubcellName.hasNext(); ) { + final String useName = (String) iSubcellName.next(); + final String type = aspiceCell.getSubcellTypeForName(useName); + + if (VERBOSE) + debugPrintln(useName + ": " + type); + + if (aspiceCell.getSubcellDefForName(useName). + hasDevices(true,true,true,true)) + aspiceSubcells.add(useName); + } + + return aspiceSubcells; + } + + /** + * Check that the subcells in the layout agree with those in the + * cast. Returns true if they agree, false if there is a problem. + **/ + private boolean checkHierarchy(final Set aspiceSubcells, + final Set castSubcells, + final List problemList) { + // compare the subcells. The names and types must match. + // here, we check the names. Types will be checked by + // the recursive lvs call below + + boolean hierarchyOK = true; + + // make sure all cast subcells are in the aspice + final Set castExtras = new HashSet(castSubcells); + castExtras.removeAll(aspiceSubcells); + for (final Iterator iCastExtra = castExtras.iterator(); + iCastExtra.hasNext(); ) { + final String castExtra = (String) iCastExtra.next(); + problemList.add(new LVSProblem("subcell " + castExtra + + " in cast, but not in layout.")); + hierarchyOK = false; + } + + // make sure all aspice subcells are in the cast + final Set aspiceExtras = new HashSet(aspiceSubcells); + // aspiceSubcells and castSubcells are both sets of names. + aspiceExtras.removeAll(castSubcells); + + for (final Iterator iAspiceExtra = aspiceExtras.iterator(); + iAspiceExtra.hasNext(); ) { + final String aspiceExtra = (String) iAspiceExtra.next(); + problemList.add(new LVSProblem("subcell " + aspiceExtra + + " in layout, but not in cast.")); + hierarchyOK = false; + } + + return hierarchyOK; + } + + /** + * Check that the namespaces are compatible. This means several things: + *

      + *
    1. There are no shorts in the layout.
    2. + *
    3. There are no unconnected nodes in the layout.
    4. + *
    5. Every name that appears as part of a production rule + * is found in the layout.
    6. + *
    7. Every port node of the cast subcells appears in the layout, + * and is properly connected to this cell. + *
    + * Returns a common namespace consisting of all names from both + * cast and layout that will be used as part of the production + * rule checking. + **/ + private AliasedSet checkNamespace(final List problemList, + boolean checkUnwired) { + final CadenceInfo ci = cadencizer.convert(cell); + + if (VERBOSE) { + debugPrintln("Cast namespace:"); + debugPrintln(((CellImpl) cell).getNamespaceString()); + + debugPrintln("Cadencized cast local namespace:"); + debugPrintln(ci.getLocalNodes().toString()); + + debugPrintln("Cadencized cast port namespace:"); + debugPrintln(ci.getPortNodes().toString()); + + debugPrintln("Aspice namespace:"); + debugPrintln(aspiceCell.getNamespaceString()); + } + + // A note about why it is ok to use cadencized local nodes: + // One might wonder why we use Cadencize.getLocalNodes() in + // a program that must be proven correct, as + // Cadencize.getLocalNodes() is a non-trivial algorithm. + // The answer: we use the same procedure in jflat, whose + // output is then fed to dsim. As long as the digital + // simulations work, we are happy. Thus, dsim is used to + // debug the Cadencize code. + // --jmr + + // start a new namespace, it will contain all names in + // prs, and those in the layout file. + // (Excl names should be the same as those in the prs.) + // start it off from the layout namespace. + final AliasedSet commonNS = + new AliasedSet(HierName.getComparator()); + // the set of names on production rules + final Set prNodeSet = new HashSet(); + + // add the names in the prs, so we can ensure that they appear + // in the layout. + for (final Iterator iPR = + cell.getProductionRuleSet().getProductionRules(); + iPR.hasNext(); ) { + final ProductionRule pr = (ProductionRule) iPR.next(); + + pr.foreachHierName(new UnaryAction() { + public void execute(final Object o) { + commonNS.add((HierName) o); + prNodeSet.add((HierName) o); + } + }); + } + + // Make a copy of the aspiceCell's + // This is a waste of memory, but coding time is more important now + // We make a copy because we wish to modify the namespace if + // we have anonymous ports that were connected to a global by + // a parent. + final AliasedSet layoutNS = + makeLayoutNamespace(aspiceCell, problemList); + + if (VERBOSE) { + debugPrintln("layout namespace:"); + debugPrintln(layoutNS.toString()); + + debugPrintln("prs namespace (unconnected):"); + debugPrintln(commonNS.toString()); + } + + // check subcell port connections + // connects port.cell and port/cell in layoutNS if port/cell + // was connected to an anonymous node. + checkSubcellPortConnections(ci, checkUnwired, layoutNS, problemList); + + // check for shorts, add layout connections to commonNS + checkShorts(ci, layoutNS, commonNS, problemList); + + if (VERBOSE) { + debugPrintln("prs + aspice namespace (aspice connections):"); + debugPrintln(commonNS.toString()); + } + + // check for unconnects, add cast connections to commonNS + checkUnconnects(ci, layoutNS, prNodeSet, commonNS, problemList); + + Namespace.addNamespace(commonNS, ci.getLocalNodes()); + + if (VERBOSE) { + debugPrintln("common = cast + aspice namespace:"); + debugPrintln(commonNS.toString()); + } + + return commonNS; + } + + /** + * Finds shorts in layout, adding layout connections to + * commonNS, and recording problems in + * problemList. Called by {@link #checkNamespace}. + **/ + private void checkShorts( + final CadenceInfo ci, + final AliasedSet layoutNS, + final AliasedSet commonNS, + final List problemList) { + // Ensure that the names in the layout set that are also in the + // cast must have the same canonical name in the cast. If they + // have different canonical names in the cast, we have found + // a short in the layout. + // We do not ensure that names in the layout are in the cast. + for (final Iterator iAspiceCanon = layoutNS.getCanonicalKeys(); + iAspiceCanon.hasNext(); ) { + final HierName aspiceCanon = (HierName) iAspiceCanon.next(); + checkShortsInner(ci, aspiceCanon, commonNS, layoutNS, problemList); + } + } + + private void checkShortsInner(CadenceInfo ci, HierName aspiceCanon, + AliasedSet commonNS, AliasedSet layoutNS, List problemList) { + // The canonical name in the cast for the group of nodes. + // All nodes found in this layout group must have this + // same cast canonical name. + HierName castCanonGroup = null; + + for (final Iterator iAspiceConn = + layoutNS.getAliases(aspiceCanon); + iAspiceConn.hasNext(); ) { + final HierName aspiceConn = (HierName) iAspiceConn.next(); + + // add the connections from the layout + commonNS.makeEquivalent(aspiceCanon, aspiceConn); + + // the canonical name in the cast for this node + final HierName castCanon = (HierName) + ci.getLocalNodes().getCanonicalKey(aspiceConn); + + castCanonGroup = checkShortsCanon(castCanonGroup, castCanon, + aspiceCanon, aspiceConn, problemList); + + + // if the node is a subcell node, make sure it is for a + // valid port. + checkShortsSubcellName(aspiceConn, aspiceCanon, commonNS, problemList); + } + } + + private HierName checkShortsCanon(HierName castCanonGroup, + HierName castCanon, HierName aspiceCanon, + HierName aspiceConn, List problemList) { + if (castCanon != null) { + if (castCanonGroup == null) + castCanonGroup = castCanon; + else if (castCanonGroup != castCanon) { + final LVSProblem p = + new LVSProblem(aspiceCanon.getAsString('.') + + " and " + aspiceConn.getAsString('.') + + " connected in layout, but not in cast: " + + aspiceCanon.getAsString('.') + " -> " + + castCanonGroup.getAsString('.') + + " but " + aspiceConn.getAsString('.') + + " -> " + castCanon.getAsString('.') + + "."); + problemList.add(p); + } + } + return castCanonGroup; + } + + private void checkShortsSubcellName(HierName aspiceConn, + HierName aspiceCanon, AliasedSet commonNS, List problemList) { + final String path = aspiceConn.getAsString('.'); + final int slashIdx = path.indexOf('/'); + if (slashIdx == -1) return; + final HierName subcellName; + final HierName portName; + final HierName dottedName; + try { + subcellName = HierName.makeHierName( + path.substring(0, slashIdx), '.'); + portName = HierName.makeHierName( + path.substring(slashIdx + 1), '.'); + dottedName = HierName.makeHierName( + StringUtil.replaceChars(path, '/', '.'), + '.'); + } catch (InvalidHierNameException e) { + throw new AssertionFailure(e); + } + + // Fix for Bug 246: connect a/b with a.b in the commonNS + commonNS.makeEquivalent(dottedName, aspiceConn); + + // get the cell with that name + final CellInterface subcell = cell.getSubcell(subcellName); + + // get the port cells + final AliasedMap portNodes = + cadencizer.convert(subcell).getPortNodes(); + + // and check that it is a valid port + if (portNodes.getCanonicalKey(portName) == null) { + // if it is not a valid port, and it is an + // anonymous node, it may be part of a split + // Vdd! or GND! net. + + // find the canonical layout name for the + // port. If it's a global, record that the + // anonymous node was connected to the global, + // and verify that the same global appears + // in the subcell. If it's not a global, + // it is a bad port error + if (unconnectedGlobalsAllowed && + aspiceCanon.isGlobal() && + (portName.isGenerated() || + portName.isGlobal())) { + + // the global must also be a port of the cell + if (portNodes.getCanonicalKey(aspiceCanon) == null) { + if (portName.isGlobal()) { + // if the port is a global, then + // global!ext will be allowed as + // long as global! is a port. + final String s = + aspiceCanon.getSuffixString(); + final int bangIdx = s.lastIndexOf('!'); + if (bangIdx != s.length() - 1) { + final HierName n = + HierName.makeHierName( + s.substring(0, + bangIdx + 1)); + + if (portNodes.getCanonicalKey(n) + == null) { + problemList.add( + new LVSProblem( + aspiceConn.getAsString('.') + + " connected to " + + aspiceCanon + .getAsString('.') + + " but " + + n.getAsString('.') + + " is not a port of " + + subcell.getFullyQualifiedType())); + } + } + } else { + problemList.add(new LVSProblem( + aspiceConn.getAsString('.') + + " connected to " + + aspiceCanon + .getAsString('.') + + " but it is not a port of " + + subcell.getFullyQualifiedType())); + } + } + + final String subcellLayoutType = + aspiceCell.getSubcellTypeForName( + subcellName.getAsString('.')); + + Map m = (Map) globalMap.get(subcellLayoutType); + final boolean firstTime = m == null; + if (m == null) { + m = new HashMap(); + globalMap.put(subcellLayoutType, m); + } + + final HierName n = (HierName) m.get(portName); + if (n == null) { + if (firstTime) { + System.err.println("in " + + subcellLayoutType + + " connecting port " + portName + + " and " + aspiceCanon); + m.put(portName, aspiceCanon); + } else { + m.put(portName, aspiceCanon); + // problemList.add(new LVSProblem("")); + } + } else if (!n.equals(aspiceCanon)) { + problemList.add(new LVSProblem( + aspiceConn.getAsString('.') + + " connected to both " + + n.getAsString('.') + " and " + + aspiceConn.getAsString('.'))); + } + } else { + problemList.add(new LVSProblem("Non-port node " + + subcellName.getAsString('.') + '.' + + portName.getAsString('.') + + " in layout, connected to " + + aspiceCanon.getAsString('.') + ".")); + } + } + } + + /** + * Finds missing connections in layout, adding cast connections to + * commonNS, and recording problems in + * problemList. Called by {@link #checkNamespace}. + **/ + private void checkUnconnects( + final CadenceInfo ci, + final AliasedSet layoutNS, + final Set prNodeSet, + final AliasedSet commonNS, + final List problemList) { + // Ensure that all sets of names in the cadencized local nodes + // that are either the guard or target of a production rule + // have a representative in the aspice. Further ensure that + // the names in the set that are also in the layout must have + // the same canonical name in the layout. + for (final Iterator iCastCanon = + ci.getLocalNodes().getCanonicalKeys(); + iCastCanon.hasNext(); ) { + final HierName castCanon = (HierName) iCastCanon.next(); + // the canonical name in the cast for the group of nodes + HierName aspiceCanonGroup = null; + // the canonical name in the prs + HierName prCanonGroup = null; + // if it is in the layout + boolean inPRS = false; + + for (final Iterator iCastConn = + ci.getLocalNodes().getAliases(castCanon); + iCastConn.hasNext(); ) { + final HierName castConn = (HierName) iCastConn.next(); + + // check to see if it is in on a production rule + if (!inPRS && prNodeSet.contains(castConn)) + inPRS = true; + + // Connect names that are in the prs + final HierName prCanon = + (HierName) commonNS.getCanonicalKey(castConn); + if (prCanon != null) { + if (prCanonGroup == null) + prCanonGroup = prCanon; + else + commonNS.makeEquivalent(prCanonGroup, prCanon); + } + + // the canonical name in the layout for this node + final HierName aspiceCanon = + (HierName) layoutNS.getCanonicalKey(castConn); + + if (aspiceCanon != null) { + if (aspiceCanonGroup == null) + aspiceCanonGroup = aspiceCanon; + else if (aspiceCanonGroup != aspiceCanon) { + final LVSProblem p = + new LVSProblem(castCanon.getAsString('.') + + " and " + castConn.getAsString('.') + + " connected in cast, but not in layout: " + + castCanon.getAsString('.') + " -> " + + aspiceCanonGroup.getAsString('.') + + " but " + castConn.getAsString('.') + + " -> " + aspiceCanon.getAsString('.') + + "."); + problemList.add(p); + } + } + } + + // The node wasn't found in the layout + if (aspiceCanonGroup == null) { + // we should have found a representative in the layout + // if it occurs in the production rules + if (inPRS) { + final LVSProblem p = + new LVSProblem(castCanon.getAsString('.') + + " not found in layout."); + problemList.add(p); + } + } + } + } + + /** + * Finds bad subcell connections in layout, and recording problems in + * problemList. Called by {@link #checkNamespace}. + **/ + private void checkSubcellPortConnections( + final CadenceInfo ci, + final boolean checkUnwired, + final AliasedSet layoutNS, + final List problemList) { + // for each cadencized cast subcell, check that the ports are + // connected to something. We depend on checkShorts and + // checkUnconnects to make sure it is the right connection. + for (final Iterator iSubcellPair = cell.getSubcellPairs(); + iSubcellPair.hasNext(); ) { + final Pair p = (Pair) iSubcellPair.next(); + final HierName subcellName = (HierName) p.getFirst(); + final CellInterface subcell = (CellInterface) p.getSecond(); + + if (!subcell.hasRealProductionRule()) + continue; + + final CadenceInfo subci = cadencizer.convert(subcell); + final AliasedMap ports = subci.getPortNodes(); + + // find possible phantom ports + final Map phantomPorts = + DirectiveUtils.canonizeKey( + new AliasedSet(ports), + DirectiveUtils.getTopLevelDirective(subcell, + DirectiveConstants.PHANTOM_PORT_SIGNOFF, + DirectiveConstants.NODE_TYPE)); + + // for each port, make sure that it is connected in the layout, + /* + System.err.println("ports for subcell " + + subcellName + ": " + subcell.getFullyQualifiedType() + + " child of " + cell.getFullyQualifiedType()); + System.err.println(ports); + */ + for (final Iterator iPortCanon = ports.getCanonicalKeys(); + iPortCanon.hasNext(); ) { + final HierName portCanon = (HierName) iPortCanon.next(); + final boolean used = + ((Boolean) ports.getValue(portCanon)).booleanValue(); + // skip ports that are not connected to subcells or + // not used on a production rule. Ie ports that are just + // connected to other ports. + if (!used) + continue; + HierName layoutCanonGroup = null; + + for (final Iterator iPortConn = ports.getAliases(portCanon); + iPortConn.hasNext(); ) { + final HierName portConn = (HierName) iPortConn.next(); + /* + System.err.println("checking alias " + portConn + + " of " + portCanon + " for subcell " + + subcellName + ": " + + subcell.getFullyQualifiedType() + + " child of " + cell.getFullyQualifiedType()); + */ + final HierName layoutName; + try { + layoutName = HierName.makeHierName( + subcellName.getAsString('.') + '/' + + portConn.getAsString('.'), '.'); + } catch (InvalidHierNameException e) { + throw (AssertionFailure) + new AssertionFailure("Invalid HierName! How?") + .initCause(e); + } + final HierName layoutCanon = + (HierName) layoutNS.getCanonicalKey(layoutName); + + if (layoutCanon != null) { + if (layoutCanonGroup == null) { + layoutCanonGroup = layoutCanon; + // searchName is layoutName, but with '.' + // instead of '/'. + final HierName searchName = + HierName.append(subcellName, portConn); + final HierName castCanon = + (HierName) ci.getLocalNodes() + .getCanonicalKey(searchName); + Debug.assertTrue(castCanon != null); + boolean allAnon = true; + boolean found = false; + + // check the connection + // one of the layout matches for a/b.c + // must be something + // that was connected to a.b.c in the cast + for (final Iterator iLayoutConn = + layoutNS.getAliases(layoutCanon); + iLayoutConn.hasNext(); ) { + final HierName layoutConn = + (HierName) iLayoutConn.next(); + + if (!layoutConn.isGenerated() && + layoutConn.getNumComponents() == 1 && + layoutConn.getAsString('.').indexOf('/') + == -1) { + allAnon = false; + } + + if (castCanon == + (HierName) ci.getLocalNodes() + .getCanonicalKey(layoutConn)) { + found = true; + } + } + + if (!found) { + final LVSProblem pr = new LVSProblem( + "Subcell node " + + searchName.getAsString('.') + + " improperly connected."); + if (anonSubcellConnAllowed) { + if (allAnon) { + // PR 234: detect bad subcell + // connections + final HierName portName = + HierName.append(subcellName, + portCanon); + + // if cell.port exists in layout + // it is an error + if (layoutNS.getCanonicalKey( + portName) != null) { + problemList.add(new LVSProblem( + portName.getAsString('.') + + " is in layout, but it is" + + " not connected to " + + layoutName + .getAsString('.'))); + } else { + // otherwise, we record the fact + // that cell/port is connected + // to cell.port. This cannot + // introduce a short, because + // they are supposed to be + // connected. It may introduce + // an unconnect if there is + // another label that is + // connected in the cast + // that is not connected to + // it in the layout. It may, + // however, alert us to the + // existance of a short. + layoutNS.makeEquivalent(portName, + layoutName); + } + } else { + problemList.add(pr); + } + } else { + problemList.add(pr); + } + } + } else { + // found two -- not good + problemList.add( + new LVSProblem("Found more than 1 " + + "connection to same port of cell " + + subcellName.getAsString('.') + ": " + + layoutCanonGroup.getAsString('.') + + " and " + + layoutCanon.getAsString('.'))); + } + } + } + + if (checkUnwired) { + final boolean isPhantom = + ObjectUtils.equals(phantomPorts.get(portCanon), + Boolean.TRUE); + + if ((layoutCanonGroup == null)) { + // port not found -- not good + // it's ok to not find a port if the node is a global + // and we have found a port node that has that + // same global passed in. + if (unconnectedGlobalsAllowed && portCanon.isGlobal()) { + final String subcellLayoutType = + aspiceCell.getSubcellTypeForName( + subcellName.getAsString('.')); + Set s = + (Set) neededGlobalsMap.get(subcellLayoutType); + if (s == null) { + s = new HashSet(); + neededGlobalsMap.put(subcellLayoutType, s); + } + s.add(portCanon); + } else { + problemList.add(new LVSProblem( + "No connection found " + + "for " + subcellName.getAsString('.') + + '/' + portCanon.getAsString('.') + + ". Subcell connection missing." + + (isPhantom ? + " (phantom_port_signoff=true)" + : ""), + isPhantom ? LVSProblem.LVS_WARNING : + LVSProblem.LVS_ERROR)); + } + } else if (isPhantom) { + problemList.add(new LVSProblem( + "Connection found for phantom port " + + subcellName.getAsString('.') + + '/' + portCanon.getAsString('.') + + ". Subcell connection extrenuous.")); + } + } + } + } + } + + /** + * Copies the namespace from the aspice cell to a fresh AliasedSet. + * Connects globals in the current cell of the form global!ext to + * global!, and connects any anonymous nodes + **/ + private AliasedSet makeLayoutNamespace( + final AspiceFile aspiceCell, + final List problemList) { + final AliasedSet ns = new AliasedSet(HierName.getComparator()); + + // If we had anonymous ports for unconnected Vdd! or GND!, + // connect them to the global signal. + if (unconnectedGlobalsAllowed) { + final Set foundGlobals = new HashSet(); + // connect up the anonymous ports to the globals + final Map m = (Map) globalMap.get(aspiceCell.getName()); + if (m != null) { + for (final Iterator iEntry = m.entrySet().iterator(); + iEntry.hasNext(); ) { + final Entry e = (Entry) iEntry.next(); + final HierName n1 = (HierName) e.getKey(); + final HierName n2 = (HierName) e.getValue(); + + foundGlobals.add(n2); + ns.makeEquivalent(n1, n2); + } + } + + // make sure the needed globals are there + final Set neededGlobals = + (Set) neededGlobalsMap.get(aspiceCell.getName()); + if (neededGlobals != null) { + for (final Iterator iNeeded = neededGlobals.iterator(); + iNeeded.hasNext(); ) { + final HierName needed = (HierName) iNeeded.next(); + if (!foundGlobals.contains(needed)) { + problemList.add(new LVSProblem( + "No connection found " + + "for port global " + + needed.getAsString('.') + + ". Subcell connection missing.")); + } + } + } + } + + // transfer the namespace + for (final Iterator iCanonNode = aspiceCell.getCanonicalNames(); + iCanonNode.hasNext(); ) { + + final HierName canonNode = (HierName) iCanonNode.next(); + + ns.add(canonNode); + + for (final Iterator iConnNode = + aspiceCell.getEquivalentNames(canonNode); + iConnNode.hasNext(); ) { + + final HierName connNode = (HierName) iConnNode.next(); + + ns.makeEquivalent(canonNode, connNode); + + // Connect global!foo to global! + if (unconnectedGlobalsAllowed && + connNode.isGlobal() && + connNode.getNumComponents() == 1) { + final String s = connNode.getSuffixString(); + + // if not a subcell port + if (s.indexOf('/') == -1) { + final int bangIdx = s.indexOf('!'); + + if (bangIdx != s.length() - 1) { + final String t = s.substring(0, bangIdx + 1); + + ns.makeEquivalent(connNode, + HierName.makeHierName(t)); + } + } + } + } + } + + return ns; + } + + private static void debugPrintln(final String s) { + if (VERBOSE) { + System.err.println(s); + } + } + + private static void usage( String m ) { + System.err.println("Usage: jlvs\n" + + " cast_cell \n" + + " --specification-type=ext ext_file ext_cell\n" + + " | --specification-type=cdl cdl_file cdl_cell\n" + + " [--translate-cdl=none | cadence (default)]\n" + + " [--gates=]\n" + + " [--no-subcells] [--no-wires]\n" + + " [--no-unwired] [--no-prs]\n" + + " [--min-staticizer-ratio=value]\n" + + " [--max-staticizer-ratio=value]\n" + + " [--cast-path=castpath]\n" + + " [--ext-path=extractpath]\n" + + " [--ignore-inline-layout]\n" + + " [--cast-version=1 | --cast-version=2]\n" ); + if ( m != null && m.length() > 0) + System.err.print( m ); + System.exit(1); + } + + /** + * A class that passes on calls to the underlying CDLNameInterface but + * intercepts calls to renameDevice, and simply returns the old device name. + * See bug 3590. This is only here to avoid touching CadenceNameInterface + * and CadenceReverseNameInterface before tapeout. + **/ + private static class NoRenameDevice implements CDLNameInterface { + final CDLNameInterface ni; + public NoRenameDevice(final CDLNameInterface ni) { + this.ni = ni; + } + + public String renameCell(final String oldCellName) + throws CDLRenameException { + return ni.renameCell(oldCellName); + } + + public String renameNode(final String oldNodeName) + throws CDLRenameException { + return ni.renameNode(oldNodeName); + } + + public String renameDevice(final String oldDeviceName) + throws CDLRenameException { + return oldDeviceName; + } + + public String renameSubCellInstance(final String oldInstanceName) + throws CDLRenameException { + return ni.renameSubCellInstance(oldInstanceName); + } + + public String renameTransistorModel(final String oldTransistorModel) + throws CDLRenameException { + return ni.renameTransistorModel(oldTransistorModel); + } + } + + public static void main(String[] args) throws Exception { + + + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + if (theArgs.argExists("version")) { + System.out.println( + com.avlsi.util.debug.VersionInfo.getVersionString(LVS.class)); + } + + final boolean checkSubcells = !( theArgs.argExists( "no-subcells" ) ); + final boolean checkWires = !( theArgs.argExists( "no-wires" ) ); + final boolean checkUnwired = !( theArgs.argExists( "no-unwired" ) ); + final boolean checkPRS = !( theArgs.argExists( "no-prs" ) ); + final String castVersion = theArgs.getArgValue("cast-version",null); + + final FileSearchPath castPath = new FileSearchPath( theArgs.getArgValue( "cast-path", "." ) ); + + final double minStaticizerRatio = + Double.parseDouble( theArgs.getArgValue( "min-staticizer-ratio", "2" ) ); + + final double maxStaticizerRatio = + Double.parseDouble( theArgs.getArgValue( "max-staticizer-ratio", "20" ) ); + + final boolean inlineLayout = !theArgs.argExists("ignore-inline-layout"); + + // check number of arguments + if (args.length < 4) + usage(null); + + final String specificationType = theArgs.getArgValue( "specification-type", null ); + final String gateList = theArgs.getArgValue("gates", null); + + final StringContainerIterator strIter = theArgs.nonParsedArgumentsIterator(); + + pedanticArgs.argTag( "ext-path" ); + pedanticArgs.argTag( "translate-cdl" ); + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + usage( pedanticArgs.pedanticString() ); + } + + try { + + final String castCellName = strIter.next(); + + // get the cast body + final CastFileParser cfp = new CastFileParser(castPath,castVersion,VERBOSE); + + if ( castCellName.lastIndexOf('.') == -1 ) { + usage( "You must specify a fully qualified cell name.\n"); + } + + final PartialExtract.CellPlusMinus fqcnSpec = + new PartialExtract.CellPlusMinus(castCellName, + PartialExtract.Info.INCLUDE); + if (!fqcnSpec.isEmpty()) { + System.out.println("Warnings in comparing " + castCellName); + System.out.println("Nothing done because LVS of partial extracted cell is not supported."); + System.out.println("LVS NA."); + System.exit(0); + } + + final CellInterface castCell = + cfp.getFullyQualifiedCell( castCellName ); + + + // get the aspice cell + AspiceFile aspiceCell; + + final Cadencize cadencizer = new Cadencize( true ); + + if ( specificationType != null ) { + if ( specificationType.equals( "ext" ) ) { + final String extFileName = strIter.next(); + final String extCellName = strIter.next(); + + final FileSearchPath extractPath = new FileSearchPath( theArgs.getArgValue( "ext-path", "." ) ); + + final ExtCell ext = ExtParser.parse(extCellName, extFileName, extractPath, true); + + aspiceCell = Ext2Aspice.ext2aspice( ext ); + } + else if ( specificationType.equals( "cdl" ) ) { + final String cdlFileName = strIter.next(); + final String cdlCellName = strIter.next(); + final String rename = + theArgs.getArgValue("translate-cdl", "cadence"); + + // Parse gate names and insert into a set for quick access + final Set gateSet = new HashSet(); + if (gateList != null) { + final StringTokenizer tok = + new StringTokenizer(gateList, ":"); + while (tok.hasMoreTokens()) { + final String gateName = tok.nextToken(); + gateSet.add(gateName); + } + } + + final Map cellMap = new LinkedHashMap(); + final CDLFactoryInterface templateFactory = + new Template(cellMap); + + + final CDLFactoryInterface lvsNodesFactory; + + final LVSNodes lvsNodes = + new LVSNodesForExtract( cfp, cadencizer ); + lvsNodesFactory = + new RemoveLVSNodesCDLFactory( lvsNodes, templateFactory ); + + final CDLFactoryInterface renameFactory; + + // Setup translation of CDL names if necessary + if (rename.equals("cadence")) { + final CDLNameInterface reverseCadenceNameInterface = + new NoRenameDevice( + new CadenceReverseNameInterface()); + + final TrivialCDLNameInterfaceFactory niFactory = + new TrivialCDLNameInterfaceFactory( reverseCadenceNameInterface ); + + renameFactory = + new CDLRenameFactory( lvsNodesFactory, + niFactory ); + } else if ( rename.equals("none") ) { + renameFactory = lvsNodesFactory; + } + else { + renameFactory = lvsNodesFactory; + System.err.println("Unknown CDL translation scheme " + + rename + " ignored!"); + } + + final File cdlFile = new File( cdlFileName ); + final InputStream cdlStream = new FileInputStream( cdlFile ); + final Reader cdlReader = new InputStreamReader( cdlStream, "UTF-8" ); + + + + // Parse all cells in the CDL file into templates + ReadCDLIntoFactory.readCDL( cdlReader, + renameFactory ); + + final Inline.Retriever retr = + new Inline.RetrieveFromCast(cfp) { + public Template getTemplate(String subName) { + CellInterface cell = loadCell(subName); + if (((Boolean) DirectiveUtils.getTopLevelDirective(cell, DirectiveConstants.NETLIST_PRIMITIVE)).booleanValue()) { + return makeTemplate(cell); + } else { + return null; + } + } + }; + + final Inline cdlInliner = new Inline(true, retr); + + // If a gate definition is found, set it up for inlining + for (Iterator i = gateSet.iterator(); i.hasNext(); ) { + final String gateName = (String) i.next(); + final Template templ = (Template) cellMap.get(gateName); + if (templ != null) { + cdlInliner.addTarget(gateName, templ); + } + } + + final AspiceCellAdapter aspiceAdapter = + new AspiceCellAdapter(); + + // Determine what to execute templates to + CDLSimpleInterface cdlParser; + if (cdlInliner == null) { + cdlParser = aspiceAdapter; + } else { + cdlInliner.setProxy(aspiceAdapter); + cdlParser = cdlInliner; + } + + // Execute all templates + for (Iterator i = cellMap.entrySet().iterator(); + i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final String subckt = (String) entry.getKey(); + if (!gateSet.contains(subckt)) { + final Template templ = (Template) entry.getValue(); + templ.execute(Collections.EMPTY_MAP, cdlParser, + subckt); + } + } + + aspiceCell = aspiceAdapter.getCell( cdlCellName ); + + if (aspiceCell == null) { + System.err.println("Cell " + cdlCellName + + " not found in file " + cdlFileName); + System.exit(3); + } + } + else { + // to fool the compiler + aspiceCell = null; + usage("Invalid --specification-type: " + specificationType + + "\n"); + } + } + else { + // to fool the compiler + aspiceCell = null; + usage("Required argument --specification-type missing\n"); + } + + final Pair lvsResult = + new LVS( inlineLayout ? castCell.inlineLayoutSubcells() : + castCell, + aspiceCell, + cadencizer ) + .lvs( checkSubcells, + checkWires, + checkUnwired, + checkPRS, + minStaticizerRatio, + maxStaticizerRatio, + inlineLayout ); + final Map doneMap = (Map) lvsResult.getFirst(); + final boolean skipped = + ((Boolean) lvsResult.getSecond()).booleanValue(); + boolean passed = true; + for (Iterator i = doneMap.entrySet().iterator(); i.hasNext(); ) { + final Entry e = (Entry) i.next(); + final Pair p = (Pair) e.getKey(); + final LVSProblem[] errs = (LVSProblem[]) e.getValue(); + int errors = 0; + int warnings = 0; + + for (int ierr = 0; ierr < errs.length; ++ierr) { + if (errs[ierr].getType() == LVSProblem.LVS_ERROR) ++errors; + else ++warnings; + } + + final String castType = (String) p.getFirst(); + final String aspiceType = (String) p.getSecond(); + if (errors > 0) { + passed = false; + + System.out.println("Errors in comparing " + castType + + " vs. " + aspiceType); + for (int ierr = 0; ierr < errs.length; ++ierr) + if (errs[ierr].getType() == LVSProblem.LVS_ERROR) + System.out.println(errs[ierr].getMessage()); + } + if (warnings > 0) { + System.out.println("Warnings in comparing " + castType + + " vs. " + aspiceType); + for (int ierr = 0; ierr < errs.length; ++ierr) + if (errs[ierr].getType() == LVSProblem.LVS_WARNING) + System.out.println(errs[ierr].getMessage()); + } + } + + // final report + System.out.print("LVS " + + (checkSubcells?"":"noSubcells ") + + (checkWires?"":"noWires ") + + (checkUnwired?"":"noUnwired ") + + (checkPRS?"":"noPrs ")); + if (passed) { + if (skipped) System.out.println("signoff."); + else System.out.println("passed."); + } else { + System.out.println("failed."); + System.exit(2); + } + + } + catch( NoSuchElementException e ) { + e.printStackTrace(); + usage(null); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LVSProblem.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LVSProblem.java new file mode 100644 index 0000000000..a71ffd25da --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LVSProblem.java @@ -0,0 +1,49 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.lvs; + +/** + * Class to represent warnings and errors in lvs. + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +public class LVSProblem { + public static final int LVS_ERROR = 0; + public static final int LVS_WARNING = 1; + + final String message; + final int type; + + public LVSProblem(final String message, final int type) { + this.message = message; + this.type = type; + } + + public LVSProblem(final String message) { + this(message, LVS_ERROR); + } + + public String getMessage() { + return message; + } + + public int getType() { + return type; + } + + public String toString() { + return "LVS " + (type == LVS_ERROR ? "Error" : "Problem") + ": " + message; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LvsOperators.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LvsOperators.java new file mode 100644 index 0000000000..c15b2be91b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/LvsOperators.java @@ -0,0 +1,465 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.lvs; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.Set; +import java.util.HashSet; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.lvs.Dnf; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.util.bool.*; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.text.NumberFormatter; + +/** + * A prs and netlist body organized by operators. + * Can check netlist versus prs. + * + * @author Andrew Lines + * @version $Revision$ $Date$ + **/ +public final class LvsOperators { + boolean verbose = false; + AliasedSet namespace; + ExclusiveNodeSets exclusives; + List problems; + MultiSet operators; + NetGraph netgraph; + final String cellname; + final double minStaticizerRatio; // minimum staticizerG/logicG + final double maxStaticizerRatio; // maximum staticizerG/logicG + final static double NPratio=1; // N conductance / P conductance + // used to override minStaticizerRatio and maxStaticizerRatio on a per half + // operator basis + private final Map statRatioSignoffUp, statRatioSignoffDn; + + /** Inner class for a single operator. */ + public class LvsOperator implements Comparable { + HierName name; + final String fullname; + HierName feedbackFrom; + Collection paths; // raw paths from NetGraph + ArrayList prsUp, prsDn; // lists of guards from PRS + MultiSet netUp, netDn; // same, except from AspiceFile + MultiSet holdUp, holdDn; // feedback terms + static final int NO_STATICIZER=0; + static final int WEAK_STATICIZER=1; + static final int COMBINATIONAL_STATICIZER=2; + static final int NO_STATICIZER_DIRECTIVE=3; + int staticizerUp=0, staticizerDn=0; + final boolean noStaticizerDirective; + + /** + * Construct an LvsOperator by name (and + * optionally flag staticizers as unnecessary). + **/ + LvsOperator (HierName name, boolean noStaticizerDirective) { + prsUp = new ArrayList(); + prsDn = new ArrayList(); + netUp = new MultiSet(); + netDn = new MultiSet(); + holdUp = new MultiSet(); + holdDn = new MultiSet(); + this.name = name; + this.noStaticizerDirective = noStaticizerDirective; + fullname = cellname + "/" + name; + feedbackFrom = null; + } + + /** Construct an LvsOperator by name. */ + LvsOperator (HierName name) { + this(name,false); + } + + /** Compare by name. */ + public int compareTo (Object B) { + return this.name.compareTo(((LvsOperator)B).name); + } + + /** Debugging output. */ + public String toString () { + return "LvsOperator: target=" + name + + "\n prsUp=" + prsUp + " prsDn=" + prsDn + + "\n netUp=" + netUp + " netDn=" + netDn + + "\n holdUp=" + holdUp + " holdDn=" + holdDn; + } + + /** Append a production rule guard to prsUp or prsDn lists. */ + void addPrs(ProductionRule prs) { + int dir = prs.getDirection(); + if (dir == ProductionRule.UP) prsUp.add(prs.getGuard()); + else if (dir == ProductionRule.DOWN) prsDn.add(prs.getGuard()); + } + + /** Add a NetNode's paths to op, report any sneak paths. */ + void addPaths(NetGraph.NetNode node) { + paths = node.getPaths(); + node.reportSneakPaths(); + Dnf.fromNetNode(node,netUp,netDn,holdUp,holdDn); + } + + /** Find aggregate conductance of all equivalent paths. */ + double aggregateConductance(NetGraph.NetPath path) { + double R = path.getAggregateSquares(paths); + return (path.type==DeviceTypes.N_TYPE ? NPratio : 1)/R; + } + + /** Check the ratio of feedback paths versus opposing paths. */ + void checkStaticizerRatio() { + if (paths==null) return; + + // for each feedback path + for (Iterator t = paths.iterator(); t.hasNext(); ) { + NetGraph.NetPath pathF = (NetGraph.NetPath) t.next(); + if (!pathF.feedback) continue; + double Gstaticizer = aggregateConductance(pathF); + double minratio=1e9; + double maxratio=0; + MultiSet gatesF = pathF.getGates(); + + // for each opposing logic path + for (Iterator u = paths.iterator(); u.hasNext(); ) { + NetGraph.NetPath pathL = (NetGraph.NetPath) u.next(); + if (pathL.feedback) continue; + if (pathF.getDir() == pathL.getDir()) continue; + + // check if interfering guards + MultiSet gatesL = pathL.getGates(); + boolean interfering = true; + for (Iterator v = gatesF.iterator(); v.hasNext(); ) + if (gatesL.find((HierName) v.next())!=null) interfering = false; + + // check ratio + double Glogic = aggregateConductance(pathL); + double ratio = Glogic/Gstaticizer; + if (interfering&&(ratiomaxratio) maxratio=ratio; + } + + List signoff = (List) + (pathF.getDir() > 0 ? statRatioSignoffDn + : statRatioSignoffUp).get(name); + if (signoff != null && signoff.size() != 2) { + problems.add(new LVSProblem("invalid staticizer_ratio_signoff directive specified for " + fullname + (pathF.getDir() > 0 ? "-" : "+"))); + signoff = null; + } + + // report errors + if (minratio < minStaticizerRatio) { + final Float f = + signoff == null ? null : (Float) signoff.get(0); + final int type = (f != null && minratio >= f.floatValue()) + ? LVSProblem.LVS_WARNING : LVSProblem.LVS_ERROR; + problems.add(new LVSProblem("small logic to staticizer ratio " + + NumberFormatter.format(minratio,1) + + (f == null ? "" : " (signoff " + f + ")") + + " for " + fullname + + "" + (pathF.getDir()>0 ? "-" : "+") + + "\n staticizer=" + pathF, + type)); + } + if (maxratio > maxStaticizerRatio) { + final Float f = + signoff == null ? null : (Float) signoff.get(1); + final int type = (f != null && maxratio <= f.floatValue()) + ? LVSProblem.LVS_WARNING : LVSProblem.LVS_ERROR; + problems.add(new LVSProblem("large logic to staticizer ratio " + + NumberFormatter.format(maxratio,1) + + (f == null ? "" : " (signoff " + f + ")") + + " for " + fullname + + "" + (pathF.getDir()>0 ? "-" : "+") + + "\n staticizer=" + pathF, + type)); + } + } + } + + /** Check that prs, net, and staticizer match for this LvsOperator. */ + void check() { + MultiSet temp,dnfUp,dnfDn,dualUp,dualDn; + boolean ok = true; + + // check ratio of weak feedback + checkStaticizerRatio(); + + // create DNF version of PRS pullup + OrBooleanExpression orUp = new OrBooleanExpression(true,prsUp); + dnfUp = Dnf.fromExpression(orUp,ProductionRule.UP,namespace,exclusives); + if (dnfUp == null) { + problems.add(new LVSProblem("non-inverse-monotonic rule: " + + fullname + "+\n orUp=" + orUp)); + ok = false; + } + + // create DNF version of PRS pulldn + OrBooleanExpression orDn = new OrBooleanExpression(true,prsDn); + dnfDn = Dnf.fromExpression(orDn,ProductionRule.DOWN,namespace,exclusives); + if (dnfDn == null) { + problems.add(new LVSProblem("non-inverse-monotonic rule: " + + fullname + "-\n orDn=" + orDn)); + ok = false; + } + + // bail because of bad production rules + if (!ok) return; + + // check netUp + if (dnfUp.compareTo(netUp)!=0) { + problems.add(new LVSProblem("mismatch: " + fullname + "+" + + "\n prsUp=" + dnfUp + "\n netUp=" + netUp)); + ok = false; + } + + // check netDn + if (dnfDn.compareTo(netDn)!=0) { + problems.add(new LVSProblem("mismatch: " + fullname + "-" + + "\n prsDn=" + dnfDn + "\n netDn=" + netDn)); + ok = false; + } + + // bail because of a logic mismatch + if (!ok) return; + + // get dualUp, but don't get dualDn yet because it might be too damn big + dualUp = Dnf.fromExpression(orUp.negated(),ProductionRule.DOWN, + namespace,exclusives); + + // check for combinational logic + if (dnfDn.compareTo(dualUp)==0) { + staticizerUp = staticizerDn = COMBINATIONAL_STATICIZER; + if ((holdUp.size()>0)||(holdDn.size()>0)) { + problems.add(new LVSProblem("staticized combinational logic on: " + + fullname)); + } + return; + } + + // check for staticizer on a nostaticizer node + if (noStaticizerDirective) { + staticizerUp = staticizerDn = NO_STATICIZER_DIRECTIVE; + if ((holdUp.size()>0)||(holdDn.size()>0)) { + problems.add(new LVSProblem("staticized \"nostaticizer\" node: " + + fullname)); + } + return; + } + + // check for feedback inverter + if (feedbackFrom == null) { + problems.add(new LVSProblem("missing feedback inverter for staticizer: " + + fullname)); + return; + } + + // check staticizer pullup + temp = Dnf.createSingleGateDnf(feedbackFrom); + if (temp.compareTo(holdUp)==0) staticizerUp = WEAK_STATICIZER; + else { + // probably OK to compute dualDn if its used for a combinational staticizer + dualDn = Dnf.fromExpression(orDn.negated(),ProductionRule.UP, + namespace,exclusives); + + // expected (holdUp | dnfUp) + temp = Dnf.addConjunctGate(dualDn,feedbackFrom); + temp.addAll(dnfUp); + + // actual (holdUp | dnfUp) + MultiSet temp2 = new MultiSet(); + temp2.addAll(holdUp); + temp2.addAll(dnfUp); + + // compare + temp = Dnf.getCanonicalForm(temp, ProductionRule.UP,exclusives); + temp2 = Dnf.getCanonicalForm(temp2,ProductionRule.UP,exclusives); + if (temp.compareTo(temp2)==0) staticizerUp = COMBINATIONAL_STATICIZER; + } + + // check staticizer pulldn + temp = Dnf.createSingleGateDnf(feedbackFrom); + if (temp.compareTo(holdDn)==0) staticizerDn = WEAK_STATICIZER; + else { + // expected (holdDn | dnfDn) + temp = Dnf.addConjunctGate(dualUp,feedbackFrom); + temp.addAll(dnfDn); + + // actual (holdDn | dnfDn) + MultiSet temp2 = new MultiSet(); + temp2.addAll(holdDn); + temp2.addAll(dnfDn); + + // compare + temp = Dnf.getCanonicalForm(temp, ProductionRule.DOWN,exclusives); + temp2 = Dnf.getCanonicalForm(temp2,ProductionRule.DOWN,exclusives); + if (temp.compareTo(temp2)==0) staticizerDn = COMBINATIONAL_STATICIZER; + } + + // report staticizer errors + if (staticizerUp == NO_STATICIZER) + problems.add(new LVSProblem((holdUp.size()>0 ? "bad" : "missing") + + " staticizer: " + fullname + + "+\n prsDn= " + dnfDn + + "\n holdUp= " + holdUp)); + if (staticizerDn == NO_STATICIZER) + problems.add(new LVSProblem((holdDn.size()>0 ? "bad" : "missing") + + " staticizer: " + fullname + + "-\n prsUp= " + dnfUp + + "\n holdDn= " + holdDn)); + } + } + + /** Construct a representation of all operators in both prs and netlist. */ + public LvsOperators(final CellInterface prsCell, + final AspiceFile aspiceCell, + final AliasedSet commonNamespace, + final ExclusiveNodeSets exclusiveSets, + final List problemList, + final double minStaticizerRatio, + final double maxStaticizerRatio, + final HierName VddName, + final HierName GndName) { + + // Canonize nostaticizer so as to make check later easier. + final Map nostatsmap = + DirectiveUtils.getPrsDirective(prsCell, + DirectiveConstants.NO_STAT, + DirectiveConstants.NODE_TYPE); + final Set nostats = DirectiveUtils.canonize(commonNamespace, DirectiveUtils.getExplicitTrues(nostatsmap)); + + final Map staticizerRatioSignoff = + DirectiveUtils.getPrsDirective( + prsCell, + DirectiveConstants.STATICIZER_RATIO_SIGNOFF, + DirectiveConstants.HALFOP_TYPE); + statRatioSignoffUp = DirectiveUtils.canonizeKey( + commonNamespace, + DirectiveUtils.getUps(staticizerRatioSignoff)); + statRatioSignoffDn = DirectiveUtils.canonizeKey( + commonNamespace, + DirectiveUtils.getDowns(staticizerRatioSignoff)); + + // Get operators which are expected to fail LVS + final Map mismatchOkMap = + DirectiveUtils.getPrsDirective(prsCell, + DirectiveConstants.PRS_NETLIST_MISMATCH_OK, + DirectiveConstants.NODE_TYPE); + final Set mismatchOk = DirectiveUtils.canonize(commonNamespace, DirectiveUtils.getExplicitTrues(mismatchOkMap)); + final Set mismatchWarned = new HashSet(); + + // look through PRS + namespace = commonNamespace; + exclusives = exclusiveSets; + problems = problemList; + operators = new MultiSet(); + cellname = aspiceCell.getName(); + this.minStaticizerRatio = minStaticizerRatio; + this.maxStaticizerRatio = maxStaticizerRatio; + ProductionRuleSet allprs = prsCell.getProductionRuleSet(); + for (Iterator t = allprs.getProductionRules(); t.hasNext(); ) { + ProductionRule prs = (ProductionRule) t.next(); + HierName target = (HierName) namespace.getCanonicalKey(prs.getTarget()); + if (mismatchOk.contains(target)) { + mismatchWarned.add(target); + continue; + } + boolean noStaticizer=nostats.contains(target); + LvsOperator op = new LvsOperator(target, noStaticizer); + LvsOperator x = (LvsOperator) operators.find(op); + if (x!=null) op = x; + else operators.add(op); + op.addPrs(prs); + } + + // look through EXT or CDL + netgraph = new NetGraph(commonNamespace,exclusives,problems, + VddName,GndName, Collections.EMPTY_SET); + netgraph.addAspice(aspiceCell); + netgraph.prepareForLvs(); + if (verbose) System.err.println(netgraph); + if (verbose) System.err.println(aspiceCell.getNamespaceString()); + if (verbose) System.err.println(namespace); + for (Iterator t = netgraph.nodes.iterator(); t.hasNext(); ) { + NetGraph.NetNode node = (NetGraph.NetNode) t.next(); + if (!node.output) continue; + if (node.isStaticizerInverter()) continue; // don't check these + if (mismatchOk.contains(node.getName())) { + mismatchWarned.add(node.getName()); + continue; + } + LvsOperator x,op; + op = new LvsOperator(node.name); + x = (LvsOperator) operators.find(op); + if (x!=null) op = x; + else operators.add(op); + op.addPaths(node); + if (node.feedbackFrom != null) op.feedbackFrom = node.feedbackFrom.name; + } + + for (Iterator i = mismatchWarned.iterator(); i.hasNext(); ) { + problems.add(new LVSProblem("LVS bypassed for operator " + cellname + "/" + i.next() + " because of prs_netlist_mismatch_ok", LVSProblem.LVS_WARNING)); + } + + // debugging + if (verbose) System.err.println(this); + } + + /** Check all operators. */ + public void check() { + for (Iterator t = operators.iterator(); t.hasNext(); ) { + ((LvsOperator) t.next()).check(); + } + } + + /** Debugging output. */ + public String toString () { + String s=""; + s += "Exclusives\n"; + for (Iterator t = exclusives.getIterator(); t.hasNext(); ) { + s += " " + t.next() + "\n"; + } + s += "Operators\n"; + for (Iterator t = operators.iterator(); t.hasNext(); ) { + s += " " + t.next() + "\n"; + } + return s; + } + + private String hierslash(HierName h) { + return (h == null) ? null : h.getAsString('/'); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetGraph.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetGraph.java new file mode 100644 index 0000000000..a3a16d6518 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetGraph.java @@ -0,0 +1,3462 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.lvs; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.ArrayList; +import java.util.List; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Set; +import java.util.SortedSet; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.Environment; +import com.avlsi.cast.impl.NullEnvironment; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.NetlistAdapter; +import com.avlsi.fast.NetlistBlock; +import com.avlsi.fast.CellType; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.cdl.parser.CDLInterfaceSimplifier; +import com.avlsi.file.cdl.parser.CDLLexer; +import com.avlsi.file.cdl.parser.CDLFactoryAdaptor; +import com.avlsi.file.cdl.parser.Template; +import com.avlsi.netlist.AbstractDeviceIterator; +import com.avlsi.netlist.AbstractNetlist; +import com.avlsi.netlist.AbstractNode; +import com.avlsi.netlist.impl.VisitorImpl; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.Partition; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.util.bool.*; +import com.avlsi.util.text.NumberFormatter; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.CastDesign; + +/** + * Data structures and algorithms for a searchable transistor graph. + * + * Used for lvs netlist vs prs matching. + * Used to compute minimal gate networks from prs. + * Used to add staticizers and match gates. + * Used to make simulatable prs given a netlist. + * + * @author Andrew Lines + * @version $Revision$ $Date$ + * + **/ +public final class NetGraph { + + /** Enable debugging output. */ + private static final boolean verbose = false; + + /** Represent node name aliases. Non-aliased nodes may be omitted. */ + public AliasedSet namespace; + + /** Excllo and Exclhi declarations. */ + ExclusiveNodeSets exclusives; + + /** List of LVSProblems for normal error reporting. */ + List problems; + + /** All NetNodes in this NetGraph, sorted by name. */ + MultiSet nodes; + + /** the set of nodes we don't want staticizers on. */ + public final Set nostaticizers; + + /** Power supply NetNode. */ + public NetNode Vdd,GND; + + /** Unique number for next internally generated NetNode name. */ + private int nextNodeNum; + + /** is it safe to insert production rules as DNFs pre-merged into a tree? */ + private boolean treeUnsafe; + + /** Only terminate paths at power supply, not other outputs? */ + private boolean pathsToRailOnly = false; + + /** Type name of the gate, if this a netgraph for a gate in the library */ + public String gateType; + + /** Have foldingFactors been calculated for all edges? **/ + private boolean doneFoldingFactors = false; + + /** Default width and length for transistors **/ + private final double defaultWidth, defaultLength; + + /** Instance of a library gate, used by NetNode. */ + public static class GateInstance { + + /** Gate type name. */ + final String type; + + /** + * Mapping of gate dummy names. The keys are the parameters of the + * gate, and the values are the names of nodes used to instantiate the + * gate. + **/ + TreeMap /**/ map; + + /** The NetGraph of this gate */ + private final NetGraph gateGraph; + + /** This gate is used to precharge an internal node */ + private final boolean precharge; + + /** Constructor. */ + GateInstance(TreeMap map, NetGraph gateGraph) { + this(gateGraph.gateType, map, gateGraph); + } + + GateInstance(String type, TreeMap map, NetGraph gateGraph) { + this(type, map, gateGraph, false); + } + + GateInstance(String type, TreeMap map, NetGraph gateGraph, + boolean precharge) { + this.type = type; + this.map = new TreeMap(map); + this.gateGraph = gateGraph; + this.precharge = precharge; + } + + /** + * Returns an unmodifiable map from formal parameters to actual + * parameters. + **/ + public Map /**/ getUnmodifiableMap() { + return Collections.unmodifiableMap(map); + } + + /** Returns the gate type. */ + public String getType() { + return type; + } + + /** Returns the NetGraph of this gate. */ + public NetGraph getNetGraph() { + return gateGraph; + } + + /** + * Finds the port node name in the gate for the specified + * name in the parent. + **/ + public /*@ non_null @*/ HierName getPortName( + final /*@ non_null @*/ HierName parentNodeName) { + // the gate map is a map from port name (in the gate) to name + // in the parent. + HierName found = null; + for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry/**/ e = + (Map.Entry) i.next(); + HierName parentName = (HierName) e.getValue(); + if (parentName.equals(parentNodeName)) { + if (found == null) + found = (HierName) e.getKey(); + else { + // Error, same node passed to multiple ports of same + // cell. We'll just assert for now. + // TODO: Better error handling. This could happen + // because of bad cast. (Same node passed to + // multiple ports). + throw new AssertionError(); + } + } + } + + assert found != null; + return found; + } + + /** Debugging string. */ + public String toString() { + return type + " " + map + "\n"; + } + + /** Gate string in skill compatible format. */ + public String skillString(int num) { + String s = "(" + type + " \"X" + num + "\" (list"; + Iterator t = map.keySet().iterator(); + while (t.hasNext()) { + HierName from = (HierName) t.next(); + HierName to = (HierName) map.get(from); + s += " \"" + from + "\":\"" + to + "\""; + } + s += "))\n"; + return s; + } + + /** Return if this gate is used to precharge an internal node. */ + public boolean isPrechargePrimitive() { + return precharge; + } + } + + /** A node in a NetGraph. */ + public final class NetNode implements Comparable { + /** Name of the node. */ + public final HierName name; + + /** Sorted set of all edges which have this node as a source or drain. */ + public MultiSet edges; + + /** Saved set of edges for undoing changes to NetGraph. */ + MultiSet oldEdges; + + /** Paths from this node to another output/global node. */ + MultiSet paths; + + /** True if the output of a half-operator. */ + boolean output; + + /** True if name is explicitly named, not auto-generated (a number). */ + boolean named; + + /** True if in port list of cell. */ + boolean is_port; + + /** True if gate of a transistor. */ + boolean is_gate; + + /** True if S/D of N transistor. */ + boolean hasN; + + /** True if S/D of P transistor. */ + boolean hasP; + + /** Used to avoid cyclic paths in findPaths. */ + boolean visited; + + /** True if this node has the passgate directive. */ + boolean passgate; + + /** True if this node also gates a non-feedback path. */ + boolean nonFeedback; + + /** + * Points to a NetNode which is the input of an inverter + * driving this node, or null if none. + */ + NetNode inverseOf = null; + + /** + * Points to a NetNode which is a drives this node with an + * inverter subgraph, but may have interfering fanins. Used + * for CDL2Cast. + */ + NetNode interferingInverseOf = null; + + /** + * Points to a NetNode which is the inverse of this node, or + * null if none. Note that there may be multiple inverses, + * and this only picks one at random! This is suitable only + * for attaching a WEAK_INV feedback. + */ + NetNode inverse = null; + + /** + * Points to a NetNode which is the output of an inverter + * gated by this node, where that output feeds back into this + * node for a staticizer, or null if none. + */ + NetNode feedbackFrom = null; + + /** Which library gate this node belongs to, if any. */ + GateInstance gate = null, staticizer = null; + + /** + * fold numbers for the pull-up and pull-down networks. + * Symmetrized pull-ups and pull-downs use fold for the normal + * direction and fold+1 for the reverse. + **/ + int up_fold = 0, down_fold = 0; + + /** + * Average drive strength (transistor squares [w/l]) of paths driving + * this node down ([0]) and up ([1]). + **/ + double[] aveDriveStrength = null; + + /** Number of unique edges (NFET/PFET) that this nodes drive **/ + int[] edgeFanout = { 0, 0 }; + + /** Total gate area that this node drives (NFET/PFET) **/ + double[] gateLoad = { 0.0, 0.0 }; + + /** Construct a NetNode with a given HierName, or null for unnamed. */ + NetNode (HierName name) { + if (name == null) + do { + name = HierName.makeHierName(nextNodeNum + ""); + nextNodeNum++; + } while (findNetNode(name) != null); + this.name = name; + output = false; + is_port = false; + is_gate = false; + hasN = false; + hasP = false; + passgate = false; + nonFeedback = false; + visited = false; + named = !name.isGenerated() && !name.isNumeric(); + edges = new MultiSet(); + paths = new MultiSet(); + } + + /** Construct a NetNode with a unique auto-generated name. */ + NetNode () { + this(null); + } + + /** Add a NetEdge to this NetNode's set of edges. */ + void addEdge (final NetEdge edge) { + this.edges.add(edge); + } + + /** Return all paths found for this NetNode. */ + public Collection getPaths () { + return (Collection) paths; + } + + /** Return paths that match feedback */ + public ArrayList getPaths (boolean feedback) { + final ArrayList a = new ArrayList(); + for (Iterator t = paths.iterator(); t.hasNext(); ) { + NetPath path = (NetPath) t.next(); + if (path.feedback==feedback) a.add(path); + } + return a; + } + + /** Return all non-feedback paths found for this NetNode. */ + public ArrayList getLogicPaths () { + return getPaths(false); + } + + /** Return all feedback paths found for this NetNode. */ + public ArrayList getFeedbackPaths () { + return getPaths(true); + } + + /** Return all feedback edges driving this node. */ + public Collection getFeedbackEdges() { + MultiSet uniqueEdges = new MultiSet(); + for (Iterator t=paths.iterator(); t.hasNext(); ) { + NetPath path = (NetPath) t.next(); + if (!path.feedback) continue; + for (Iterator s=path.edges.iterator(); s.hasNext(); ) { + NetEdge edge = (NetEdge) s.next(); + uniqueEdges.addIfUnique(edge); + } + } + return (Collection) uniqueEdges; + } + + /** + * Returns all NetNodes that drive this node through non-feedback paths + **/ + public Set getLogicFaninNodes () { + HashSet faninNodes = new HashSet(); + ArrayList paths = getLogicPaths(); + for (Iterator t=paths.iterator(); t.hasNext();) + faninNodes.addAll(((NetPath)t.next()).getGateNodes()); + return faninNodes; + } + + /** Check if this NetNode is Vdd. */ + public boolean isVdd () { + return this == Vdd; + } + + /** Check if this NetNode is GND. */ + public boolean isGND () { + return this == GND; + } + + /** Check if this NetNode is a power rail. */ + public boolean isRail() { + return isVdd() || isGND(); + } + + /** Does this NetNode output gate a weak feedback inverter? */ + public boolean gatesWeakInverter() { + return output && // is an operator output + inverseOf != null && // is an inverse of another node + inverseOf.feedbackFrom == this; // drives feedback to that node + } + + /** + * Is this NetNode the output of a small inverter used only in + * a staticizer? If so, LVS won't check it against prs that + * won't be there. Usage in Jauto is extremely confusing... + */ + public boolean isStaticizerInverter() { + return gatesWeakInverter() && // must gate a weak inverter + !is_port && // can't be a port + !nonFeedback; // can't gates something besides feedback + } + + /** Does this NetNode output gate a small inverter of a staticizer? */ + public boolean gatesSmallInverter() { + return (feedbackFrom!=null) && // must get feedback + feedbackFrom.isStaticizerInverter(); // from a staticizer inv + } + + /** Does this node have a weak staticizer pulling it up? **/ + public boolean hasWeakFeedBack(int type) { + for (Iterator j=getFeedbackPaths().iterator(); j.hasNext(); ) { + NetPath path = (NetPath) j.next(); + if (path.type!=type) continue; + if (path.isWeakFeedBack()) return true; + } + return false; + } + + /** + * Is the NetNode connected to a staticizer or weak inverter? + * Jauto will attach extra load if it is. + */ + public boolean isStaticized(){ + return (staticizer!=null); + } + + /** Is this node an output node. */ + public boolean isOutput() { + return output; + } + + /** Check if the node is explicitly named. */ + public boolean isNamed() { + return named; + } + + /** Check if the node is in port list. */ + public boolean isPort() { + return is_port; + } + + /** Check if the node gates a transistor. */ + public boolean isGate() { + return is_gate; + } + + /** Would this node need a contact in the layout? */ + public boolean needsContact() { + return isRail() || output || (edges.size()!=2); + } + + /** Returns an iterator for edges of this NetNode. */ + public Iterator getEdges() { + return edges.iterator(); + } + + /** Returns the name of this NetNode. */ + public HierName getName() { + return name; + } + + /** Returns the gate attached to this NetNode, or null if none. */ + public GateInstance getGate() { + return gate; + } + + /** Returns the staticizer attached to this NetNode, or null if none. */ + public GateInstance getStaticizer() { + return staticizer; + } + + /** Set output field of this NetNode. */ + void markOutput() { + output = !isRail() && (edges.size()>0) && (is_port || is_gate || passgate); + } + + /** Set inverseOf field of this NetNode, set inverse field of fanin node. */ + void findInverter () { + if ( !this.output ) return; + NetNode fanin = null; + NetNode power = null; + boolean Pfound = false; + boolean Nfound = false; + boolean interfering = false; + final Iterator t = edges.iterator(); + while ( t.hasNext() ) { + final NetEdge edge = (NetEdge) t.next(); + + // identify power supply, if any + if (edge.source.isRail()) power = edge.source; + else if (edge.drain.isRail()) power = edge.drain; + else { + interfering = true; + continue; + } + + // check power supply + if (((edge.type == DeviceTypes.P_TYPE) && (!power.isVdd()))|| + ((edge.type == DeviceTypes.N_TYPE) && (!power.isGND()))) { + interfering = true; + continue; + } + + // actually found a 1N or 1P edge to appropriate power rail + if (edge.type == DeviceTypes.P_TYPE) Pfound = true; + if (edge.type == DeviceTypes.N_TYPE) Nfound = true; + + // ensure all fanin gates are the same + if (fanin == null) fanin = edge.gate; // set fanin + else if (fanin != edge.gate) interfering = true; // not same fanin + } + if (Nfound && Pfound && !interfering) { + inverseOf = fanin; + fanin.inverse = this; + } + else if (Nfound && Pfound) { + interferingInverseOf = fanin; + } + } + + /** + * Find an edge from this node that is in the right direction, + * type, and fold and gated by G, and not connected to an + * output. This is used to build a shared transistor tree + * from a production rule in addConjunctiveTermSharedRecursive. + **/ + private NetEdge findCompatibleNetEdge(NetNode G, boolean source, int type, int fold) { + for (Iterator i = getEdges(); i.hasNext(); ) { + NetEdge e = (NetEdge) i.next(); + if (e.type != type) continue; + if (e.fold != fold) continue; + if (source) { + if (e.source != this) continue; + if (e.drain.output) continue; + } else { + if (e.drain != this) continue; + if (e.source.output) continue; + } + if (e.gate != G) continue; + return e; + } + return null; + } + + /** Compare NetNodes by name. */ + public int compareTo (Object b) { + return this.name.compareTo(((NetNode) b).name); + } + + /** Debugging string. */ + public String toString () { + return "NetNode: name=" + name + + " edges=" + edges.size() + + " visited=" + visited + + " output=" + output + "\n" + + " inverse=" + (inverse != null ? inverse.name.toString() : "null") + + " inverseOf=" + (inverseOf != null ? inverseOf.name.toString() : "null") + + " feedbackFrom=" + (feedbackFrom != null ? feedbackFrom.name.toString() : "null") + + " nonFeedback=" + nonFeedback; + } + + /** Recursively search for paths from current node to rail/output NetNodes. */ + private void findPathsRecurse(MultiSet paths, ArrayList pathedges, + NetNode node, int type) { + + // terminate recursion at a rail or an output node + if (node.isRail() || + (!pathsToRailOnly && pathedges.size()>0 && + node.output && (!node.passgate || node.is_port))) { + NetPath path = new NetPath(this,node,type,pathedges); + // check exclusion + if (pathedges.size()>0 && !path.isExcluded()) paths.add(path); + return; + } + + // add a sneak path but continue recursion + if (pathedges.size()>0 && !pathsToRailOnly && node.hasN && node.hasP) { + NetPath path = new NetPath(this,node,type,pathedges); + if (!path.isExcluded()) paths.add(path); // check exclusion + } + + // recurse through edges + node.visited=true; + for (Iterator t = node.edges.iterator(); t.hasNext(); ) { + NetEdge edge = (NetEdge) t.next(); + if (edge.type!=type) continue; // recurse through desired type only + if (edge.precharge) continue; // ignore precharge transistors + ArrayList newedges = new ArrayList(pathedges); + newedges.add(edge); + NetNode S=edge.source; + NetNode D=edge.drain; + if (!S.visited) findPathsRecurse(paths,newedges,S,type); + if (!D.visited) findPathsRecurse(paths,newedges,D,type); + } + node.visited=false; + } + + /** + * Search for paths from this NetNode to power NetNodes. Only + * looks for paths which don't change transistor type, that is + * a P-path to Vdd and an N-path to GND. Will also stop + * searching at any outputs, unless pathsToRailOnly is true. + */ + public void findPaths() { + this.paths = findPaths(pathsToRailOnly); + } + + /** + * Search for paths from this NetNode to power NetNodes. Only + * looks for paths which don't change transistor type, that is + * a P-path to Vdd and an N-path to GND. Will also stop + * searching at any outputs, unless pathsToRailOnly is true. + */ + public MultiSet findPaths(final boolean pathsToRailOnly) { + final boolean saved = NetGraph.this.pathsToRailOnly; + NetGraph.this.pathsToRailOnly = pathsToRailOnly; + MultiSet paths = new MultiSet(); + ArrayList pathedges = new ArrayList(); + findPathsRecurse(paths,pathedges,this,DeviceTypes.N_TYPE); + findPathsRecurse(paths,pathedges,this,DeviceTypes.P_TYPE); + NetGraph.this.pathsToRailOnly = saved; + return paths; + } + + /** + * Check if more paths have been created since previous + * findPaths. Doens't worry about duplicate paths. Used to + * check if a sneak path was introduced by merging + * transistors. + */ + boolean hasMorePaths() { + boolean more = false; + MultiSet paths = new MultiSet(); + ArrayList pathedges = new ArrayList(); + findPathsRecurse(paths,pathedges,this,DeviceTypes.N_TYPE); + findPathsRecurse(paths,pathedges,this,DeviceTypes.P_TYPE); + for (Iterator t = paths.iterator(); t.hasNext(); ) { + NetPath path = (NetPath) t.next(); + if (this.paths.find(path) == null) more = true; + } + if (verbose) System.err.println("hasMorePaths=" + more + "\n" + paths); + return more; + } + + /** Check if another output is in a shared network with this node. */ + public boolean isShared() { + if (isRail()) return false; // don't recurse through a global node + boolean shared = false; + // recurse through edges + visited = true; + for (Iterator t = edges.iterator(); t.hasNext(); ) { + NetEdge edge = (NetEdge) t.next(); + NetNode S = edge.source; + NetNode D = edge.drain; + if (!S.visited) shared = shared || S.output || S.isShared(); + if (!D.visited) shared = shared || D.output || D.isShared(); + } + visited = false; + return shared; + } + + /** Recursively delete all edges reachable from this node. */ + public void deleteEdges() { + if (isRail()) return; // don't recurse through a global node + // recurse through edges + visited = true; + for (Iterator t = edges.iterator(); t.hasNext(); ) { + NetEdge edge = (NetEdge) t.next(); + NetNode S = edge.source; + NetNode D = edge.drain; + if (!S.visited) {S.edges.remove(edge); S.deleteEdges();} + if (!D.visited) {D.edges.remove(edge); D.deleteEdges();} + } + // delete edges and paths but leave nodes + edges = new MultiSet(); + paths = new MultiSet(); + visited = false; + } + + /** Check if node is output of combinational logic. */ + public boolean isCombinational() { + if (!output) return false; + + // get logic from paths + MultiSet netUp = new MultiSet(); + MultiSet netDn = new MultiSet(); + MultiSet holdUp = new MultiSet(); + MultiSet holdDn = new MultiSet(); + Dnf.fromNetNode(this,netUp,netDn,holdUp,holdDn); + + // abort if feedback paths exist + if ((holdUp.size()>0)||(holdDn.size()>0)) return false; + + // compare if dual pullup equals pulldn in canonical form + MultiSet dualUp = Dnf.dual(netUp); + dualUp = Dnf.getCanonicalForm(dualUp,ProductionRule.DOWN,exclusives); + netDn = Dnf.getCanonicalForm(netDn, ProductionRule.DOWN,exclusives); + return (dualUp.compareTo(netDn)==0); + } + + /** + * Are there any paths from this node to another output node? + */ + private boolean hasSneakPaths() { + boolean sneaky = false; + for (Iterator t = paths.iterator(); t.hasNext(); ) { + NetPath path = (NetPath) t.next(); + if (path.getDir()==0) sneaky = true; + } + if (verbose) System.err.println("hasSneakPaths=" + sneaky + "\n" + paths); + return sneaky; + } + + /** + * Report illegal or sneak paths as LVSProblems. + */ + public void reportSneakPaths() { + for (Iterator t = paths.iterator(); t.hasNext(); ) { + NetPath path = (NetPath) t.next(); + if ((path.getDir()==0) && + (!path.getStartNode().passgate || + !path.getEndNode().passgate)) + problems.add(new LVSProblem("Sneak path: " + path)); + } + } + + /** + * Returns average strength (in transistor squares [w/l]) driving + * this node down (0) and up (0). Returns null if no paths + * drive this node. + **/ + public double[] getAverageDriveStrength() { + if (!output) return null; + if (!doneFoldingFactors) setFoldingFactors(); + return aveDriveStrength == null ? null : + new double[] { aveDriveStrength[0], aveDriveStrength[1] }; + } + + /** + * Returns the number of NFET(0) and PFET(1) transistors that + * this node drives. + **/ + public int[] getTransistorFanout() { + if (!doneFoldingFactors) setFoldingFactors(); + return new int[] { edgeFanout[0], edgeFanout[1] }; + } + + public double[] getTransistorLoad() { + if (!doneFoldingFactors) setFoldingFactors(); + return new double[] { gateLoad[0], gateLoad[1] }; + } + } + + /** An edge of the NetGraph, with NetNodes for source, gate, and drain. */ + public final class NetEdge implements Comparable { + + /** The source NetNode, used to search the graph. */ + public final NetNode source; + + /** The drain NetNode, used to search the graph. */ + public final NetNode drain; + + /** The gate NetNode, used to check exclusion and report paths. */ + public final NetNode gate; + + /** Either N_TYPE or P_TYPE of DeviceTypes. */ + public final int type; + + /** + * "Symmetrization" number constants. These constants are + * also defined in a base CAST cell, for user convenience. + **/ + public static final int + DEFAULT_FOLD = 0, + FORWARD_FOLD = 1, + REVERSE_FOLD = 2, + PARTIAL_FOLD = 3, + TRUNK_FOLD = 4; + + /** Merging of NetEdges is restricted to equal fold numbers. */ + final int fold; + + /** Width of the transistor. */ + public double width; + + /** Length of the transistor. */ + public double length; + + /** + * Relative size (relative width vs half-operator) of the transistor. + * (Only set and used by Jauto code; should be removed) + **/ + public double size = 1.0; + + /** + * Number of transistors in the longest stack going through this + * transistor. (Only set and used by Jauto code; should be removed) + **/ + public int depth = 1; + + /** + * Number of half-operators who share this transistor. + * (Only set and used by Jauto code; should be removed) + **/ + public int shareCount = 1; + + /** Does this NetEdge appear in any NetPath? */ + boolean used = false; + + /** Does this NetEdge appear in a logic NetPath? */ + boolean usedLogic = false; + + /** Was this NetEdge added from a library gate? */ + public final boolean library; + + /** Was this NetEdge added from a library gate but not in the pcell? */ + public final boolean floating; + + /** Transistor type */ + private final int transistorType; + + /** + * Folding factor. (2 means there is one other equivalent edge in + * the design, so only count this one as "half" a transistor.) + * -1.0 indicates uninitialized. + **/ + double foldingFactor = -1.0; + + /** Is this NetEdge used to precharge an internal node? */ + public final boolean precharge; + + /** Construct a new non-precharge NetEdge from simple parameters. */ + NetEdge (final NetNode S, + final NetNode G, + final NetNode D, + final int T, + final int F, + final double W, + final double L, + final boolean library, + final int transistorType ) { + this(S, G, D, T, F, W, L, library, transistorType, false); + } + + /** Construct a new NetEdge from simple parameters. */ + NetEdge (final NetNode S, + final NetNode G, + final NetNode D, + final int T, + final int F, + final double W, + final double L, + final boolean library, + final int transistorType, + final boolean precharge ) { + gate = G; + source = S; + drain = D; + used = false; + type = T; + fold = F; + width = W; + length = L; + this.library = library; + this.floating = library && (W==0); + if (this.floating) width = defaultWidth; + source.addEdge(this); + drain.addEdge(this); + gate.is_gate = true; + if (type==DeviceTypes.N_TYPE) drain.hasN=source.hasN=true; + if (type==DeviceTypes.P_TYPE) drain.hasP=source.hasP=true; + this.transistorType = transistorType; + this.precharge = precharge; + Debug.assertTrue(L>0,"Transistor gate length must be >0"); + } + + /** Construct a new NetEdge from a Transistor, add NetNodes if necessary. */ + NetEdge (final Transistor t) { + this(createNetNode( t.getSource() ), + createNetNode( t.getGate() ), + createNetNode( t.getDrain() ), + t.getType(), 0, + t.getWidth(), t.getLength(), false, 0, false); + NetNode bulk = createNetNode(t.getBulk()); + if ( ( t.getType() == DeviceTypes.N_TYPE ) && ( ! bulk.isGND() ) || + ( t.getType() == DeviceTypes.P_TYPE ) && ( ! bulk.isVdd() ) ) { + problems.add( new LVSProblem( "Wrong bulk for transistor: " + t ) ); + } + } + + /** + * Compare NetEdges by gate, type, fold, source, drain. + * + * minimize() depends on sorting first by gate. + **/ + public int compareTo (Object b) { + int c; + NetEdge e = (NetEdge) b; + c = this.gate.compareTo(e.gate); + if (c!=0) return c; + c = this.type - e.type; + if (c!=0) return c; + c = this.fold - e.fold; + if (c!=0) return c; + c = this.source.compareTo(e.source); + if (c!=0) return c; + c = this.drain.compareTo(e.drain); + return c; + } + + /** + * For partial symmetrization. Recursively search along a + * series stack toward the source, looking for a + * port/gate/rail/contacted node. Return the node. + **/ + public NetNode findStackSource() { + // return source node if it is port, gate, rail, or not 2 spokes + if (source.is_port || source.is_gate || source.isRail() || + (source.edges.size()!=2)) + return source; + + // find next edge in chain + NetEdge e; + if (source.edges.get(0) == this) e = (NetEdge) source.edges.get(1); + else e = (NetEdge) source.edges.get(0); + + // recurse to next edge in chain + if (e.source != source) return e.findStackSource(); + if (e.drain != source) return e.findStackDrain(); // swap s/d + Debug.assertTrue(false); // e is a looped transistor! + return null; + } + + /** + * For partial symmetrization. Recursively search along a + * series stack toward the drain, looking for a + * port/gate/rail/contacted node. Return the node. + **/ + public NetNode findStackDrain() { + // return drain node if it is port, gate, rail, or not 2 spokes + if (drain.is_port || drain.is_gate || drain.isRail() || + (drain.edges.size()!=2)) + return drain; + + // find next edge in chain + NetEdge e; + if (drain.edges.get(0) == this) e = (NetEdge) drain.edges.get(1); + else e = (NetEdge) drain.edges.get(0); + + // recurse to next edge in chain + if (e.drain != drain) return e.findStackDrain(); + if (e.source != drain) return e.findStackSource(); // swap s/d + Debug.assertTrue(false); // e is a looped transistor! + return null; + } + + /** + * Return the transistor type of this transistor. + **/ + public int getTransistorType() { + return transistorType; + } + + /** + * Returns the folding factor of this NetEdge. Values greater than + * 1 indicate that this transistor has been folded, and transistor + * counts involving this transistor and others in its folding set + * should be scaled accordingly. + **/ + public double getFoldingFactor() { + if (!doneFoldingFactors) setFoldingFactors(); + return foldingFactor; + } + + /** Debugging string. */ + public String toString () { + return "NetEdge: type=" + (type == DeviceTypes.P_TYPE ? "P" : "N") + + " transistor=" + getTransistorType() + + " W=" + NumberFormatter.format(width,3) + + " L=" + NumberFormatter.format(length,3) + + " used=" + used + " usedLogic=" + usedLogic + + "\n S=" + source.name + " D=" + drain.name + " G=" + gate.name; + } + + public boolean isFeedbackOnly() { + return used && !usedLogic; + } + + public boolean isUsedLogic() { + return usedLogic; + } + + public boolean isSmallInverter() { + return gate.gatesSmallInverter() && (gate.feedbackFrom == source || + gate.feedbackFrom == drain); + } + + /** Transistor skill format string. */ + public String skillString(int num) { + NetNode bulk = type == DeviceTypes.N_TYPE ? GND : Vdd; + return "(" + (type == DeviceTypes.N_TYPE ? "NMOS" : "PMOS") + + " \"M" + num + + "\" \"" + source.name + + "\" \"" + gate.name + + "\" \"" + drain.name + + "\" \"" + bulk.name + + "\" " + width + " " + length + ")\n"; + } + } + + /** A path between NetNodes through one or more NetEdges. */ + public class NetPath implements Comparable { + + /** Ordered list of edges between from and to. */ + ArrayList edges; + + /** Starting NetNode for the path. */ + NetNode from; + + /** Ending NetNode for the path. */ + NetNode to; + + /** Either N_TYPE or P_TYPE of DeviceTypes. */ + int type; + + /** Is this a feedback path for a staticizer? */ + boolean feedback = false; + + /** + * Construct a new NetPath given two NetNodes and the NetEdges + * between them. Sets feedbackFrom/nonFeedback as a side effect. + */ + NetPath (NetNode from, NetNode to, int type, ArrayList edges) { + this.edges = edges; + this.from = from; + this.to = to; + this.type = type; + for (Iterator t = edges.iterator(); t.hasNext(); ) { + NetEdge edge = (NetEdge) t.next(); + NetNode node = edge.gate; + if (node.inverseOf == from) { + feedback = true; + if (from.feedbackFrom == null) from.feedbackFrom = node; + else if (from.feedbackFrom != node) + problems.add(new LVSProblem + ("more than one feedback inverter to " + from)); + } + else node.nonFeedback = true; + } + } + + /** Check if this path contains exclusive gates. */ + public boolean isExcluded () { + MultiSet gates = getUniqueGates(); + if (type == DeviceTypes.P_TYPE) + return exclusives.areExclusive(ExclusiveNodeSet.LO,gates); + else if (type == DeviceTypes.N_TYPE) + return exclusives.areExclusive(ExclusiveNodeSet.HI,gates); + return false; + } + + /** Return the type of the transistors in the path, N_TYPE or P_TYPE. */ + public final int getType() { + assert (type==DeviceTypes.N_TYPE) || (type==DeviceTypes.P_TYPE) + : "NetPath.type should be either N_TYPE or P_TYPE"; + return type; + } + + /** Find the minimum width of the (logic) edges in this path. */ + public double getMinWidth (boolean logic) { + double minw=0; + for (Iterator t = edges.iterator(); t.hasNext(); ) { + NetEdge edge = (NetEdge) t.next(); + if (edge.usedLogic!=logic) continue; + if ((minw==0)||(edge.width*/ goutputs, + final Map ttup, + final Map ttdn, + final Integer ctt, + final CastFileParser cfp, + final Cadencize cad) { + if (cfp == null) return model; + if (model == null) return null; + + final String baseType = CellUtils.getBaseType(model.gateType); + /* For backwards compatibility. If the gate does not take + * a meta-parameter, than do not tack on the transistor + * types as meta-parameters. + */ + if (baseType.equals(model.gateType)) return model; + + Integer typeup = null, typedn = null; + if (goutputs==null) { typeup = ctt; typedn = ctt; } // smallInv + else while (goutputs.hasNext()) { + final HierName out = (HierName) goutputs.next(); + + final int up = getTransistorType(ttup, out, ctt); + if (typeup == null) typeup = new Integer(up); + else if (typeup.intValue() != up) { + throw new RuntimeException("Do not know how to handle a multiple output gate with different transistor type for the outputs."); + } + + final int dn = getTransistorType(ttdn, out, ctt); + if (typedn == null) typedn = new Integer(dn); + else if (typedn.intValue() != dn) { + throw new RuntimeException("Do not know how to handle a multiple output gate with different transistor type for the outputs."); + } + } + assert typeup != null && typedn != null : + "No output for gate " + model.gateType; + + final String newtype = baseType + "(" + typedn + "," + typeup + ")"; + try { + return CastDesign.getGateNetGraph(cfp, newtype, Vdd.name, GND.name, cad); + } catch (Exception e) { + return model; + } + } + + /** + * Add the production rules from a CellInterface. + * + * Minimizes the resulting netgraph, and obeys the the symmetric + * and unshared directives. + * + * The appropriate nostaticizer directive information must be + * passed in via the constructor. + * + * Exclusives from the cell are not used; they are taken from + * those passed in to the constructor. Similarly, when adding + * staticizers, they must be taken from the list passed into the + * constructor. + * + * Minimization is very expensive for large cells. Most of this + * is complication to do most of the minimization on small subsets + * of the cells. So, basically, we make a seperate netgraph for + * each operator, and minimize that. Then we merge them together + * into sets that are mutually exclusive, and minimize them. Then + * we merge those sets togethether and minimize the large set. + * + * @param ci The CellInterface to snarf production rules and directives. + * @param gates A list of gates to match against. + * @param cfp The CastFileParser to get gate definitions from for multiple + * transistor support. + * @param cad Cadencize to use to for multiple transistor support. + * @return none. + */ + public void addCellInterfacePrs(final CellInterface ci, + final NetGraph[] gates, + final CastFileParser cfp, + final Cadencize cad) + throws UnimplementableProductionRuleException { + markPortNodes(ci); // used to identify operators + ProductionRuleSet prs = ci.getProductionRuleSet(); + + // query shared directives + Map shared = DirectiveUtils.getPrsDirective( + ci, DirectiveConstants.SHARED, + DirectiveConstants.HALFOP_TYPE); + Map sharedup = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getUps(shared)); + Map shareddown = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getDowns(shared)); + + // query symmetrize directives + Map sym = DirectiveUtils.getPrsDirective( + ci, DirectiveConstants.SYMMETRIZE, + DirectiveConstants.HALFOP_TYPE); + Map symup = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getUps(sym)); + Map symdown = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getDowns(sym)); + + // query transistor type directives + Map ttype = DirectiveUtils.getPrsDirective(ci, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.HALFOP_TYPE); + final Map ttup = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getUps(ttype)); + final Map ttdn = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getDowns(ttype)); + final Integer ctt = (Integer) DirectiveUtils.getTopLevelDirective(ci, + DirectiveConstants.TRANSISTOR_TYPE); + + prs.canonicalizeNames(namespace); + + final Map symFullX = findXCandidates(symdown, prs); + + // Build whole network in totally unmerged DNF form + addPrs(ci,prs.getProductionRules(),null,true,symup,sharedup,ttup,symdown,shareddown,ttdn,ctt,symFullX); + + // Substitute all gates. + for (int i = 0; i < gates.length; i++) { + final List/**/ goutputs = + gates[i].getUnmatchedOperatorNodes(); + final NetGraph currGate = gates[i]; + substituteGate(currGate, new UnaryFunction() { + public Object execute(final Object o) { + final Map/**/ map = (Map) o; + return getMultipleTransistorGate(currGate, + new MappingIterator(goutputs.iterator(), + new UnaryFunction() { + public Object execute(Object o) { + final HierName formal = ((NetNode) o).name; + return map.get(formal); + } + }), + ttup, ttdn, ctt, cfp, cad); + } + }); + } + + // Remove all transistors that aren't gates. + Set unmatched = new HashSet(); + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + NetNode n = (NetNode) i.next(); + if (!n.output || (n.gate != null)) continue; + unmatched.add(n.name); + n.deleteEdges(); + } + + // If we could ensure that sets of exclusives were disjoint, + // we could improve the efficiency of Partition. FIXME: + // should perhaps only keep production rules with proper + // targets, instead of filtering during adding. + Partition part = + new Partition (new PartitionProductionRulesByExclusives(exclusives), + prs.getProductionRules()); + + for (Iterator pi = part.iterator(); pi.hasNext(); ) { + Set pprs = (Set) pi.next(); + if (verbose) System.err.println("adding and minimizing " + pprs); + + // construct netgraph by building trees for prs + NetGraph ng = new NetGraph(namespace, exclusives, new ArrayList(), + Vdd.name, GND.name, + defaultWidth, defaultLength, nostaticizers); + ng.addPrs(ci,pprs.iterator(),unmatched,false,symup,sharedup,ttup,symdown,shareddown,ttdn,ctt,symFullX); + + // if sneak paths, construct netgraph again without trees + if (ng.hasSneakPaths()) { + ng = new NetGraph(namespace, exclusives, new ArrayList(), + Vdd.name, GND.name, defaultWidth, defaultLength, nostaticizers); + ng.addPrs(ci,pprs.iterator(),unmatched,true,symup,sharedup,ttup,symdown,shareddown,ttdn,ctt,symFullX); + } + + // minimize and mergeFrom + ng.minimize(); + mergeFrom(ng); + } + } + + private static class SymFullX { + public static class AtomicBooleanComparator implements Comparator { + private static AtomicBooleanComparator singleton = null; + public int compare(final HierNameAtomicBooleanExpression e1, + final HierNameAtomicBooleanExpression e2) { + return e1.getName().compareTo(e2.getName()); + } + public int compare(final Object o1, final Object o2) { + return compare((HierNameAtomicBooleanExpression) o1, + (HierNameAtomicBooleanExpression) o2); + } + public static AtomicBooleanComparator getInstance() { + if (singleton == null) { + singleton = new AtomicBooleanComparator(); + } + return singleton; + } + } + + public Set up2 = new TreeSet(AtomicBooleanComparator.getInstance()); + public Set parallel = + new TreeSet(AtomicBooleanComparator.getInstance()); + public void reorder(final Collection conjuncts, + final boolean reverseOrder, final List result) { + final List last = new ArrayList(); + for (Iterator i = conjuncts.iterator(); i.hasNext(); ) { + HierNameAtomicBooleanExpression literal = + (HierNameAtomicBooleanExpression) i.next(); + if (parallel.contains(literal)) { + last.add(literal.getName()); + } else if (!up2.contains(literal)) { + if (reverseOrder) { + result.add(0, literal.getName()); + } else { + result.add(literal.getName()); + } + } + } + + final Iterator i = up2.iterator(); + final HierNameAtomicBooleanExpression termA = + (HierNameAtomicBooleanExpression) i.next(); + final HierNameAtomicBooleanExpression termB = + (HierNameAtomicBooleanExpression) i.next(); + assert !i.hasNext(); + + if (reverseOrder) { + result.add(termA.getName()); + result.add(0, termB.getName()); + } else { + result.add(0, termA.getName()); + result.add(termB.getName()); + } + + result.addAll(0, last); + } + /** + * Do the given conjuncts contain the 2 up terms? + **/ + public boolean containedBy(final Collection conjuncts) { + final Set s = new TreeSet(AtomicBooleanComparator.getInstance()); + s.addAll(conjuncts); + return s.containsAll(up2); + } + } + + /** + * Find a set of production rule targets that satisfies the requirements of + * the SYM_FULL_X symmetrization style. + **/ + private Map findXCandidates(final Map symdown, ProductionRuleSet rules) { + // Get down half operators that has the SYM_FULL_X directive + final Set fullX = (Set) CollectionUtils.addAll(new HashSet(), + new FilteringIterator( + symdown.keySet().iterator(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + return ((Integer) symdown.get(o)).intValue() == 5; + } + }) + ); + if (fullX.isEmpty()) return Collections.EMPTY_MAP; + + final Set temp = + new TreeSet(SymFullX.AtomicBooleanComparator.getInstance()); + + final Map candidates = new HashMap(); + final Set disqualified = new HashSet(); + // look at all up half-operators which has SYM_FULL_X, and see which + // ones qualifies + for (Iterator i = rules.getProductionRules(); i.hasNext(); ) { + final ProductionRule rule = (ProductionRule) i.next(); + final HierName target = rule.getTarget(); + final int direction = rule.getDirection(); + if (direction != ProductionRule.UP || !fullX.contains(target) || + disqualified.contains(target)) continue; + + if (!candidates.containsKey(target)) { + candidates.put(target, new SymFullX()); + } + final SymFullX sym = (SymFullX) candidates.get(target); + + + final Collection disjuncts = + rule.getGuard().DNFForm().getDisjuncts(); + DISJUNCTS: + for (Iterator j = disjuncts.iterator(); j.hasNext(); ) { + final Collection conjuncts = + ((AndBooleanExpressionInterface) j.next()).getConjuncts(); + temp.clear(); + temp.addAll(conjuncts); + switch (temp.size()) { + case 1: sym.parallel.addAll(temp); break; + case 2: if (sym.up2.isEmpty()) { + sym.up2.addAll(temp); + break; + } else if (sym.up2.containsAll(temp)) break; + /* fall through */ + default: candidates.remove(target); + disqualified.add(target); + break DISJUNCTS; + } + } + } + + for (Iterator i = candidates.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final SymFullX sym = (SymFullX) entry.getValue(); + if (sym.up2.size() != 2) i.remove(); + } + + // eliminate half operators without the correct down topology + for (Iterator i = rules.getProductionRules(); + i.hasNext() && !candidates.isEmpty(); ) { + final ProductionRule rule = (ProductionRule) i.next(); + + final int direction = rule.getDirection(); + if (direction != ProductionRule.DOWN) continue; + + final HierName target = rule.getTarget(); + final SymFullX sym = (SymFullX) candidates.get(target); + if (sym == null) continue; + + final Collection disjuncts = + rule.getGuard().DNFForm().getDisjuncts(); + for (Iterator j = disjuncts.iterator(); j.hasNext(); ) { + final Collection conjuncts = + ((AndBooleanExpressionInterface) j.next()).getConjuncts(); + if (!sym.containedBy(conjuncts)) { + candidates.remove(target); + break; + } + } + } + return candidates; + } + + /** + * Add an iterator of prs to this NetGraph. If unmatched is + * non-null, will only add targets in the unmatched list. Can + * specify wheather it is safe to build shared prs trees. + **/ + private void addPrs(CellInterface ci, + Iterator prs, Set unmatched, boolean treeUnsafe, + Map symup, Map sharedup, Map ttup, Map symdown, Map shareddown, + Map ttdn, Integer ctt, Map symFullX) + throws UnimplementableProductionRuleException { + this.treeUnsafe = treeUnsafe; + while (prs.hasNext()) { + ProductionRule p = (ProductionRule) prs.next(); + if (!p.isInverseMonotonic()) { + throw new UnimplementableProductionRuleException(p,ci); + } + int direction = p.getDirection(); + HierName target = p.getTarget(); + if ((unmatched!=null) && !unmatched.contains(target)) continue; + if (direction == ProductionRule.UP) { + addFlavoredProductionRule(p, + (Integer) symup.get(target), + (Integer) sharedup.get(target), + getTransistorType(ttup, target, ctt), + (SymFullX) symFullX.get(target)); + } else if (direction == ProductionRule.DOWN) { + addFlavoredProductionRule(p, + (Integer) symdown.get(target), + (Integer) shareddown.get(target), + getTransistorType(ttdn, target, ctt), + (SymFullX) symFullX.get(target)); + } else { + Debug.assertTrue(false, "Illegal production rule direction"); + } + } + this.treeUnsafe = false; + prepareForLvs(); + } + + /** add PRS with shared and symmetrize directives */ + private void addFlavoredProductionRule(ProductionRule p, + Integer symmetric, + Integer foldnum, + int transistorType, + SymFullX symFullX) { + int sym = (symmetric != null) ? symmetric.intValue() : 0; + int fold = (foldnum != null) ? foldnum.intValue() + 1 : 0; + double width = defaultWidth, length = defaultLength; + if (sym==1) { // SYM_PARTIAL + addProductionRule(p, false, false, + fold_from_group(fold,NetEdge.PARTIAL_FOLD), + width, length, + transistorType, symFullX); + } else if (sym==4) { // SYM_TRUNK + addProductionRule(p, false, false, + fold_from_group(fold,NetEdge.TRUNK_FOLD), + width, length, + transistorType, symFullX); + } else if ((sym==2) || (sym==3) || (sym==5)) { + // SYM_SKIP_FIRST or SYM_FULL or SYM_FULL_X + addProductionRule(p, false, (sym==2), + fold_from_group(fold,NetEdge.FORWARD_FOLD), + width/2, length, + transistorType, symFullX); + addProductionRule(p, true, (sym==2), + fold_from_group(fold,NetEdge.REVERSE_FOLD), + width/2, length, + transistorType, symFullX); + } else { // SYM_NONE + addProductionRule(p, false, false, + fold_from_group(fold,NetEdge.DEFAULT_FOLD), + width, length, + transistorType, symFullX); + } + } + + /** + * Helper for addCellIntefaceNetlist. It adds transistors, and inlines + * gates. + **/ + private class NetlistHelper extends CDLFactoryAdaptor { + private final CastFileParser cfp; + private final Cadencize cad; + private final double cdlScale; + private final boolean removeZero; + private final Map passgates; + private final boolean precharge; + private final TreeMap nameMap = new TreeMap(); + private NetNode createNetNode(HierName name) { + if (!name.isNumeric() && !name.isGenerated()) nameMap.put(name, name); + final NetNode node = mapNetNode(name, nameMap); + final Boolean b = (Boolean) passgates.get(name.getAsString('.')); + final boolean passgate = b == null ? false : b.booleanValue(); + node.passgate = passgate; + return node; + } + public NetlistHelper(double cdlScale, + final CastFileParser cfp, + final Cadencize cad, + final boolean removeZero, + final Map passgates, + final boolean precharge) { + this.cdlScale = cdlScale; + this.cfp = cfp; + this.cad = cad; + this.removeZero = removeZero; + this.passgates = passgates; + this.precharge = precharge; + } + + public void makeTransistor(final HierName name, final String type, + final HierName ns, final HierName nd, + final HierName ng, final HierName nb, + final CDLLexer.InfoToken width, + final CDLLexer.InfoToken length, + final Map parameters, + final Environment env) { + final double w = CDLInterfaceSimplifier.getValue(width, env); + if (w == 0 && removeZero) return; + + final double l = CDLInterfaceSimplifier.getValue(length, env); + final int np = + type.startsWith("p") || type.startsWith("P") ? + DeviceTypes.P_TYPE : DeviceTypes.N_TYPE; + + final Integer ttype = CellUtils.extractTransistorNumber(type); + + new NetEdge(createNetNode(ns), createNetNode(ng), createNetNode(nd), + np, 0, w * cdlScale, l * cdlScale, false, + ttype == null ? 0 : Math.abs(ttype.intValue()), + precharge); + } + + public void makeCall(final HierName name, final String subName, + final HierName[] args, final Map parameters, + final Environment env) { + final CellInterface ci; + try { + ci = cfp.getFullyQualifiedCell(subName); + } catch (CastSemanticException e) { + throw new RuntimeException("Cannot load cell " + subName, e); + } + + final SortedSet ports = NetlistAdapter.getParameterList(ci, cad); + if (ports.size() != args.length) { + throw new RuntimeException("Parameter mismatch in subcircuit " + + "instantiation: " + name + + "/" + subName + + " ports = " + ports + + " args.length = " + args.length); + } + + // Prepare the mapping from formal parameters to actual parameters + final TreeMap map = new TreeMap(); + int i = 0; + for (Iterator it = ports.iterator(); it.hasNext(); ++i) { + final HierName formal = (HierName) it.next(); + map.put(formal, createNetNode(args[i]).name); + } + + // Inline the gate NetGraph into the NetGraph. Can't use + // CastDesign.getGateNetGraph, because we need to pass along + // instantiation parameters. + final NetGraph ng = new NetGraph(null, null, null, + Vdd.name, GND.name, + defaultWidth, defaultLength, Collections.EMPTY_SET); + ng.addCellInterfaceNetlist(ci, cfp, cad, parameters, true); + ng.gateType = subName; + final boolean stack = + ((Boolean) DirectiveUtils.getTopLevelDirective + (ci, DirectiveConstants.STACK_GATE)).booleanValue(); + if (!stack) ng.prepareForLvs(); + addNetGraph(ng, map, !stack); + + if (!stack) { + final boolean staticizer = + ((Boolean) DirectiveUtils.getTopLevelDirective + (ci, DirectiveConstants.STATICIZER_GATE)).booleanValue(); + final boolean precharge = + ((Boolean) DirectiveUtils.getTopLevelDirective + (ci, DirectiveConstants.PRECHARGE_PRIMITIVE)).booleanValue(); + final NetNode prechargeDrain; + if (precharge) { + // For a precharge primitive, only put the gate instance on + // the D node. This is only appropriate if we are using + // stack.PRECHARGE_[NP].0. There is no easy way to not + // hardcode this, unless we introduce another directive. + prechargeDrain = ng.findNetNode(HierName.makeHierName("D")); + if (prechargeDrain == null) + throw new RuntimeException("Cannot find node D in " + + "precharge gate " + subName); + } else { + prechargeDrain = null; + } + // Mark output nodes with appropriate GateInstance + final GateInstance inst = + new GateInstance(subName, map, ng, precharge); + final List goutputs = prechargeDrain == null ? + ng.getUnmatchedOperatorNodes() : + Collections.singletonList(prechargeDrain); + for (i = 0; i < goutputs.size(); i++) { + final NetNode gnode = (NetNode) goutputs.get(i); + final NetNode node = mapNetNode(gnode.name,map); + if (staticizer) { + if (node.staticizer == null) { + node.staticizer = inst; + } else { + throw new RuntimeException + ("A staticizer of type " + node.staticizer.getType() + + " already attached to " + node.name + + ", cannot attach a staticizer of type " + subName); + } + } else { + if (node.gate == null) { + node.gate = inst; + } else { + throw new RuntimeException + ("A gate of type " + node.gate.getType() + + " already attached to " + node.name + + ", cannot attach a gate of type " + subName); + } + } + } + } + } + } + + /** + * Convert the netlist block from a CellInterface. + * + * Construct the netgraph from the transistors in the netlist block as is. + * + * @param ci The CellInterface to obtain the netlist block and directives. + * @param cfp The CastFileParser to get gate cells from. + * @param cad The Cadencize used to get the port list. + * @param params Instantiation parameters + * @param removeZero Do not add zero width transistors + * @return none. + **/ + private void addCellInterfaceNetlist(final CellInterface ci, + final CastFileParser cfp, + final Cadencize cad, + final Map params, + final boolean removeZero) { + markPortNodes(ci); // used to identify operators + final BlockIterator bi = + ci.getBlockInterface().iterator(BlockInterface.NETLIST); + Debug.assertTrue(bi.hasNext(), "No netlist block found in " + + ci.getFullyQualifiedType()); + final NetlistBlock nb = (NetlistBlock) bi.next(); + final float cdlScale = + ((Float) DirectiveUtils.getTopLevelDirective + (ci, DirectiveConstants.CDLSCALE)).floatValue(); + final Map passgates = + DirectiveUtils.getTopLevelDirective + (ci, DirectiveConstants.PASSGATE, DirectiveConstants.STRING_TYPE); + final boolean precharge = + ((Boolean) DirectiveUtils.getTopLevelDirective + (ci, DirectiveConstants.PRECHARGE_PRIMITIVE)).booleanValue(); + final NetlistHelper helper = + new NetlistHelper(cdlScale, cfp, cad, removeZero, passgates, + precharge); + final Template templ = nb.getCanonicalTemplate(cad); + try { + templ.execute(helper, params, NullEnvironment.getInstance(), null); + } catch (RuntimeException e) { + throw new RuntimeException("Cannot create netgraph for " + + ci.getFullyQualifiedType(), e); + } + } + + private void addCellInterfaceNetlist(final CellInterface ci, + final CastFileParser cfp, + final Cadencize cad) { + addCellInterfaceNetlist(ci, cfp, cad, Collections.EMPTY_MAP, false); + } + + /** + * Construct a netgraph from a CellInterface. It will generate transistors + * for cells with a PRS block or a netlist block. Normally, the netlist + * block is given preference over the PRS block, if it exists. + * + * @param ci The CellInterface to add. + * @param gates An array of gates to match against. + * @param cfp Where to get definitions for gates in the netlist block. May + * be null if multiple transistor support is not desired. + * @param cad Cadencize to use to get the canonical port list for a cell. + * May be null if multiple transistor support is not desired. + * @return none. + **/ + public void addCellInterface(final CellInterface ci, + final NetGraph[] gates, + final CastFileParser cfp, + final Cadencize cad) + throws UnimplementableProductionRuleException { + if (ci.containsNetlist()) { + addCellInterfaceNetlist(ci, cfp, cad); + } else { + addCellInterfacePrs(ci, gates, cfp, cad); + } + } + + /** Construct a netgraph from a CellInterface with a List of gates */ + public void addCellInterface(final CellInterface ci, + final List gates, + final CastFileParser cfp, + final Cadencize cad) + throws UnimplementableProductionRuleException { + addCellInterface(ci, (NetGraph[]) gates.toArray(new NetGraph[0]), cfp, cad); + } + + /** Group rules together by declared exclusion directives. */ + private class PartitionProductionRulesByExclusives + implements Partition.PartitionerInterface { + private final ExclusiveNodeSets ex; + public PartitionProductionRulesByExclusives(ExclusiveNodeSets ex) { + this.ex = ex; + } + /** + * @bug kiniry 23 July 2002 - Bug#1174 + */ + public boolean equivalent(Object o1, Object o2) { + ProductionRule p1 = (ProductionRule) o1; + ProductionRule p2 = (ProductionRule) o2; + int d1 = p1.getDirection(); + int d2 = p2.getDirection(); + if (d1 != d2) { return false; } + HierName h1 = (HierName) p1.getTarget(); + HierName h2 = (HierName) p2.getTarget(); + if (h1.equals(h2)) { return true; } + Set s = new TreeSet(); + s.add(h1); + s.add(h2); + if (d1 == ProductionRule.UP) { + return ex.areExclusive(ExclusiveNodeSet.HI, s); + } + if (d1 == ProductionRule.DOWN) { + return ex.areExclusive(ExclusiveNodeSet.LO, s); + } + Debug.assertTrue(false, "illegal production rule direction"); + return false; + } + } + + /** Mark all port nodes. Must call before adding edges to NetGraph. */ + public void markPortNodes(CellInterface ci) { + final Map ports = CellUtils.markPorts(ci); + Iterator i = ports.keySet().iterator(); + while (i.hasNext()) { + String str = (String) i.next(); + try { + HierName name = HierName.makeHierName(str,'.'); + NetNode node = createNetNode(name); + node.is_port = true; + } catch (InvalidHierNameException e) { + throw (IllegalArgumentException) + new IllegalArgumentException("Bad HierName " + str).initCause(e); + } + } + } + + /** Mark all port nodes. Must call before adding edges to NetGraph. */ + public void markPortNodes(AspiceFile aspiceCell) { + Iterator i = aspiceCell.getPortList().iterator(); + while (i.hasNext()) { + HierName name = (HierName) i.next(); + NetNode node = createNetNode(name); + node.is_port = true; + } + } + + /** Find outputs, inverters, paths, and unused edges. Needed for Lvs. */ + public void prepareForLvs() { + markOutputs(); // fill in output + findInverters(); // fill in inverseOf + findPaths(); // make sure to find inverters first + checkUnusedEdges(); // report any transistors that aren't used in NetPaths + if (verbose) System.err.println(this); + } + + /** Add a conjunctive production rule to this NetGraph. */ + private void addConjunctiveTerm(List gates, HierName target, int type, + int fold, double width, double length, + int transistorType) { + NetNode S,D; + if (type == DeviceTypes.P_TYPE) S = Vdd; + else {Debug.assertTrue(type == DeviceTypes.N_TYPE); S = GND;} + for (Iterator t = gates.iterator(); t.hasNext(); ) { + NetNode G=createNetNode((HierName) t.next()); + if (t.hasNext()) {D = new NetNode(); nodes.add(D);} + else {D = createNetNode(target); D.is_port = true;} + NetEdge edge = + new NetEdge(S,G,D,type,fold,width,length,false,transistorType); + S = D; + } + } + + /** + * Add a conjunctive production rule to this NetGraph, sharing up + * from the power rails. + * + * To be a valid graph, there must be no other targets in the graph that aren't + * exclusive. + **/ + private void addConjunctiveTermShared(List gates, HierName target, int type, + int fold, double width, double length, + int transistorType) { + NetNode S; + Iterator i = gates.iterator(); + if (type == DeviceTypes.P_TYPE) S = Vdd; + else {Debug.assertTrue(type == DeviceTypes.N_TYPE); S = GND;} + Debug.assertTrue(i.hasNext()); + addConjunctiveTermSharedRecursive(S, i, target, type, fold, width, + length, transistorType); + } + + /** Implements addConjunctiveTermShared(). */ + private void addConjunctiveTermSharedRecursive(NetNode S, Iterator gates, + HierName target, + int type, int fold, + double width, double length, + int transistorType) { + HierName gatename = (HierName) gates.next(); + NetNode G = createNetNode(gatename); + + if (gates.hasNext()) { + NetEdge e = S.findCompatibleNetEdge(G, true, type, fold); + if (e != null) { + NetNode D = e.drain; + addConjunctiveTermSharedRecursive(D, gates, target, + type, fold, width, length, + transistorType); + } else { + NetNode D = new NetNode(); nodes.add(D); + e = new NetEdge(S, G, D, type, fold, width, length, false, + transistorType); + addConjunctiveTermSharedRecursive(D, gates, target, type, fold, + width, length, transistorType); + } + } else { + // No more gates. Need to stick target in. + // Can't share with anyone. + NetNode D = createNetNode(target); D.is_port = true; + NetEdge e = new NetEdge(S, G, D, type, fold, width, length, false, + transistorType); + } + } + + /** + * Add all conjunctive terms from a production rule to this NetGraph. + * Directly specifying a fold number other then those listed as + * constants in NetEdge is discouraged. + **/ + private void addProductionRule(ProductionRule prs, + boolean reverseOrder, boolean skipOne, + int fold, double width, double length, + int transistorType, SymFullX symFullX) { + int dir = prs.getDirection(); + HierName target = prs.getTarget(); + Collection disjuncts = prs.getGuard().DNFForm().getDisjuncts(); + for (Iterator i = disjuncts.iterator(); i.hasNext(); ) { + List term = new ArrayList(); + Collection conjuncts = + ((AndBooleanExpressionInterface) i.next()).getConjuncts(); + if (symFullX == null || dir == ProductionRule.UP) { + for (Iterator j = conjuncts.iterator(); j.hasNext(); ) { + HierNameAtomicBooleanExpression literal = + (HierNameAtomicBooleanExpression) j.next(); + if (reverseOrder && skipOne) { // reverse all but first gate + if (term.size()==0) term.add(literal.getName()); + else term.add(1,literal.getName()); + } + else if (reverseOrder) term.add(0,literal.getName()); + else term.add(literal.getName()); + } + } else { + symFullX.reorder(conjuncts, reverseOrder, term); + } + if (treeUnsafe) { + addConjunctiveTerm(term,target,dir == ProductionRule.DOWN ? + DeviceTypes.N_TYPE : DeviceTypes.P_TYPE, + fold, width, length, transistorType); + } else { + addConjunctiveTermShared(term,target,dir == ProductionRule.DOWN ? + DeviceTypes.N_TYPE : DeviceTypes.P_TYPE, + fold, width, length, transistorType); + } + } + } + + /** Simpler method to add all conjunctive terms with default parameters. */ + private void addProductionRule(ProductionRule prs, double width, double length) { + addProductionRule(prs,false,false,0,width,length,0,null); + } + + /** Get all nodes of this NetGraph. */ + public Collection getNodes() { + return (Collection) nodes; + } + + /** Get output nodes of this NetGraph. */ + public Collection getOutputNodes() { + List l = new ArrayList(); + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + l.add((NetNode) i.next()); + } + return (Collection) l; + } + + /** Get all edges of this NetGraph. */ + public Collection getEdges() { + ArrayList edges = new ArrayList(); + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + for (Iterator s = node.edges.iterator(); s.hasNext(); ) { + NetEdge edge = (NetEdge) s.next(); + if (edge.source == node) edges.add(edge); // don't double report + } + } + return (Collection) edges; + } + + /** Get all paths of this NetGraph. */ + Collection getPaths() { + ArrayList paths = new ArrayList(); + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + for (Iterator s = node.paths.iterator(); s.hasNext(); ) + paths.add((NetPath) s.next()); + } + return (Collection) paths; + } + + /** Return a string of CDL format edges. */ + public String cdlString() { + int i=0; + String s = ""; + Iterator t = getEdges().iterator(); + while (t.hasNext()) { + NetEdge edge = (NetEdge) t.next(); + NetNode bulk = edge.type == DeviceTypes.N_TYPE ? GND : Vdd; + s += "M" + i + + " " + edge.source.name + + " " + edge.gate.name + + " " + edge.drain.name + + " " + bulk.name + + " " + (edge.type == DeviceTypes.N_TYPE ? "N" : "P") + + " W=" + edge.width + + " L=" + edge.length + + "\n"; + i++; + } + return s; + } + + /** Return a string of Skill format edges. */ + public String skillString() { + int i = 0; + String s = ""; + Iterator t = getEdges().iterator(); + while (t.hasNext()) { + NetEdge edge = (NetEdge) t.next(); + if (!edge.library || edge.floating) s += " " + edge.skillString(i); + i++; + } + i = 0; + t = getNodes().iterator(); + while (t.hasNext()) { + NetNode node = (NetNode) t.next(); + if (node.gate != null) s += " " + node.gate.skillString(i++); + if (node.staticizer != null) s += " " + node.staticizer.skillString(i++); + } + return s; + } + + /** Check for new paths created by merging. */ + boolean hasMorePaths() { + Iterator t = nodes.iterator(); + while (t.hasNext()) { + NetNode node = (NetNode) t.next(); + if (node.output) if (node.hasMorePaths()) return true; + } + return false; + } + + /** If possible, merge nodes N1 and N2 and edges E1 and E2. */ + boolean mergeNodes(NetNode N1, NetNode N2, NetEdge E1, NetEdge E2) { + // trivial reject cases + if (N1.output || N2.output || N1.isRail() || N2.isRail()) return false; + if (E1.getTransistorType() != E2.getTransistorType()) return false; + + // save node.oldEdges, create OldEdges list, clear node.edges + Collection OldEdges = getEdges(); + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + node.oldEdges = node.edges; + node.edges = new MultiSet(); + } + + // construct new edges from OldEdges with merging + for (Iterator t = OldEdges.iterator(); t.hasNext(); ) { + NetEdge edge = (NetEdge) t.next(); + NetNode G = (edge.gate == N2) ? N1 : edge.gate; + NetNode S = (edge.source == N2) ? N1 : edge.source; + NetNode D = (edge.drain == N2) ? N1 : edge.drain; + if (edge == E2); // omit this edge + else if (edge == E1) { // merged version of E1 and E2 + double width = (E1.width > E2.width) ? E1.width : E2.width; + new NetEdge(S,G,D,edge.type,edge.fold,width,edge.length, false, + edge.getTransistorType()); + } + else new NetEdge(S,G,D,edge.type,edge.fold, + edge.width,edge.length,edge.library, + edge.getTransistorType()); + } + if (N1 == N2) { + // successful merge + if (verbose) System.err.println("auto-merge of " + N1.name); + return true; + } + + // restore saved oldEdges of nodes if any new paths created by merge + if (hasMorePaths()) { + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + node.edges=node.oldEdges; + } + if (verbose) System.err.println("Failed to Merge " + N1.name + + " and " + N2.name); + return false; + } + + // successful merge + if (verbose) System.err.println("Merged " + N1.name + " and " + N2.name); + return true; + } + + /** + * Merge this NetGraph into a minimal gate network. + * + * @bug kiniry 23 July 2002 - Bug#1174 + */ + private void minimize() { + boolean progress; + do { + progress=false; + Iterator t = nodes.iterator(); + while (t.hasNext()) { + NetNode node = (NetNode) t.next(); + progress |= mergeEdges(node); + } + } while (progress); + } + + /** + * Helper for minimize(). + * + * merges all compatible edges from node. + * + * @bug kiniry 23 July 2002 - Bug#1174 + **/ + private boolean mergeEdges(NetNode node) { + boolean progress; + boolean merged = false; + do { + progress = false; + node.edges.sort(); + NetEdge[] edges = new NetEdge[node.edges.size()]; + Iterator s = node.edges.iterator(); + for (int i=0; iBug#1174 + */ + public void findPaths() { + for (Iterator s = getEdges().iterator(); s.hasNext(); ) { + NetEdge edge = (NetEdge) s.next(); + edge.used = false; + } + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + if (node.output) { + node.findPaths(); + for (Iterator j = node.paths.iterator(); j.hasNext(); ) { + NetPath path = (NetPath) j.next(); + path.markUsedEdges(); + } + } + } + } + + /** Check for any unused edges. */ + void checkUnusedEdges() { + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + for (Iterator j = node.edges.iterator(); j.hasNext(); ) { + NetEdge edge = (NetEdge) j.next(); + if ((edge.source == node)&&(!edge.used)) + problems.add(new LVSProblem("Unused edge " + edge)); + } + } + } + + /** Find a NetNode by name or null if none found. */ + public NetNode findNetNode(HierName name) { + HierName canon = null; + if (namespace != null) canon = (HierName) namespace.getCanonicalKey(name); + if (canon == null) canon = name; + return (NetNode) nodes.find(new NetNode(canon)); + } + + /** Find or create a NetNode by name. */ + public NetNode createNetNode(HierName name) { + HierName canon = null; + if (namespace != null) canon = (HierName) namespace.getCanonicalKey(name); + if (canon == null) canon = name; + NetNode node = new NetNode(canon); + NetNode oldnode = (NetNode) nodes.find(node); + if (oldnode != null) return oldnode; + nodes.add(node); + return node; + } + + /** + * Find or create a NetNode given another node and a name mapping. + * Add new mappings from unmapped or unnamed nodes to unnamed + * nodes. + **/ + public NetNode mapNetNode(HierName name, TreeMap map) { + NetNode node; + if (map.get(name)!=null) // already in the map + node = createNetNode((HierName) map.get(name)); + else { // map to a new unnamed node, add to the map + node = new NetNode(); + nodes.add(node); + map.put(name,node.name); + } + return node; + } + + /** Get a list of operator output nodes in this NetGraph. */ + public ArrayList getUnmatchedOperatorNodes() { + ArrayList outputs = new ArrayList(); + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + if (node.output && !node.isStaticizerInverter() && node.gate==null) + outputs.add(node); + } + return outputs; + } + + /** Try to map one name into another. Update mapping if possible. */ + private static boolean tryMap(HierName from, HierName to, TreeMap map) { + if (map.get(from) == null) map.put(from,to); // create new mapping + else if (((HierName) map.get(from)).compareTo(to) != 0) return false; + return true; + } + + /** Match two paths. */ + private static TreeMap matchPath(NetPath path, NetPath gpath, TreeMap map) { + // match type and feedback + if (gpath.type != path.type) return null; + if (gpath.feedback != path.feedback) return null; + + // match to and from + map = new TreeMap(map); // copy original + if (!tryMap(gpath.to.name,path.to.name,map)) return null; + if (!tryMap(gpath.from.name,path.from.name,map)) return null; + + // match all gates in order + ArrayList gates = path.getGatesArrayList(); + ArrayList ggates = gpath.getGatesArrayList(); + if (ggates.size() != gates.size()) return null; // mismatch + if (ggates.size() == 0) return map; // nothing left to match + for (int i=0; igateGraph, and replace edges that matches + * with edges from the netgraph returned by call transform. + **/ + private void substituteGate(NetGraph gateGraph, UnaryFunction transform) { + while (true) { + final TreeMap map = matchGate(gateGraph); + if (map == null) break; + final NetGraph replacement = (NetGraph) transform.execute(map); + final GateInstance inst = new GateInstance(map, replacement); + ArrayList goutputs = gateGraph.getUnmatchedOperatorNodes(); + for (int i=0; igate to the + * names of power rails in this NetGraph + * @param gate NetGraph to establish mapping for + **/ + private void initializeMatchMapping(final Map map, final NetGraph gate) { + boolean n = false, p = false; + for (Iterator i = gate.getEdges().iterator(); + i.hasNext() && !(n && p); ) { + final NetEdge edge = (NetEdge) i.next(); + if (edge.source.isGND() || edge.gate.isGND() || + edge.drain.isGND() || edge.type == DeviceTypes.N_TYPE) n = true; + if (edge.source.isVdd() || edge.gate.isVdd() || + edge.drain.isVdd() || edge.type == DeviceTypes.P_TYPE) p = true; + } + if (n) map.put(gate.GND.name, GND.name); + if (p) map.put(gate.Vdd.name, Vdd.name); + } + + /** + * Attach a full staticizer to a node. + * + * @param node node to attached the staticizer to + * @param staticizer netgraph of the staticizer gate + **/ + private void addFullStaticizer(final NetNode node, + final NetGraph staticizer) { + final TreeMap map = new TreeMap(); + initializeMatchMapping(map, staticizer); + map.put(HierName.makeHierName("out"), node.name); + node.staticizer = new GateInstance(map, staticizer); + addNetGraph(staticizer, map, true); + } + + /** + * Attach a weak inverter staticizer to a node. + * + * @param node node to attached the weak inverter to + * @param weakInv netgraph of the weak inverter gate + **/ + private void addWeakInv(final NetNode node, final NetGraph weakInv) { + final TreeMap map = new TreeMap(); + initializeMatchMapping(map, weakInv); + map.put(HierName.makeHierName("in"),node.inverse.name); + map.put(HierName.makeHierName("out"),node.name); + node.staticizer = new GateInstance(map, weakInv); + addNetGraph(weakInv,map,true); + } + + /** Add small inverter */ + private void addSmallInverter(NetNode node, NetGraph smallInv) { + node.inverse = createNetNode(node.name.appendString("_inverse")); + final TreeMap map = new TreeMap(); + initializeMatchMapping(map, smallInv); + map.put(HierName.makeHierName("a"),node.name); + map.put(HierName.makeHierName("out"),node.inverse.name); + node.inverse.gate = new GateInstance(map, smallInv); + addNetGraph(smallInv,map,true); + } + + /** + * Add a combinational staticizer, plus a small inverter if one + * doesn't already exist. Can do half-combinational, half-weak + * staticizers. + * + * @param node node to attached the weak inverter to + * @param smallInv netgraph of the small inverter gate + * @param weakUp should the holdDn be weak? + * @param weakDn should the holdUp be weak? + * @param combUp should the holdDn be combinational? + * @param combDn should the holdUp be combinational? + * @param should we add smallInv even if inverter exists? + * @param ttup transistor type for PMOS + * @param ttdn transistor type for NMOS + **/ + private void addCombinationalStaticizer(final NetNode node, + final NetGraph smallInv, + final boolean weakUp, + final boolean weakDn, + final boolean combUp, + final boolean combDn, + final boolean addInv, + final int ttup, + final int ttdn) { + // skip if neither side wants feedback + if (!weakUp && !weakDn && !combUp && !combDn) return; + + // deduce logic from NetNode + MultiSet netUp = new MultiSet(); + MultiSet netDn = new MultiSet(); + MultiSet holdUp = new MultiSet(); + MultiSet holdDn = new MultiSet(); + Dnf.fromNetNode(node,netUp,netDn,holdUp,holdDn); + + // abort if feedback paths already exist + if (holdUp.size()!=0 || holdDn.size()!=0) { + System.err.println("ERROR: node " + node.name + " already has feedback."); + System.exit(1); + } + + // find canonical duals of netUp and netDn, or empty term for weak staticizer + if (combDn) { + holdDn = Dnf.dual(netUp); + holdDn = Dnf.getCanonicalForm(holdDn,ProductionRule.DOWN,exclusives); + holdDn = Dnf.eliminateRedundantTerms(holdDn,netDn); + } else { + holdDn = new MultiSet(); holdDn.add(new MultiSet()); + } + if (combUp) { + holdUp = Dnf.dual(netDn); + holdUp = Dnf.getCanonicalForm(holdUp,ProductionRule.UP,exclusives); + holdUp = Dnf.eliminateRedundantTerms(holdUp,netUp); + } else { + holdUp = new MultiSet(); holdUp.add(new MultiSet()); + } + + // construct temporary NetGraph + NetGraph ng = new NetGraph(namespace, exclusives, new ArrayList(), + Vdd.name, GND.name, + defaultWidth, defaultLength, Collections.EMPTY_SET); + + // add a small inverter if one doesn't exist + TreeMap node_map = new TreeMap(); // needed to map inverse node + if (addInv || node.inverse==null) addSmallInverter(node,smallInv); + + // add the holdUp and holdDn transistors + double width = defaultWidth; + double length = defaultLength; + int fold = NetEdge.DEFAULT_FOLD; + if (weakDn || combDn) for (Iterator i = holdDn.iterator(); i.hasNext(); ) { + List term = new ArrayList(((MultiSet) i.next()).list()); + term.add(node.inverse.name); // append the feedback transistor + ng.addConjunctiveTermShared(term,node.name,DeviceTypes.N_TYPE,fold, + width,length,ttdn); + } + if (weakUp || combUp) for (Iterator i = holdUp.iterator(); i.hasNext(); ) { + List term = new ArrayList(((MultiSet) i.next()).list()); + term.add(node.inverse.name); // append the feedback transistor + ng.addConjunctiveTermShared(term,node.name,DeviceTypes.P_TYPE,fold, + width,length,ttup); + } + + // minimize and merge into main NetGraph + ng.minimize(); + mergeFrom(ng,node_map); + } + + /** Find a vanBerkel version of a gate with a staticizer */ + private String vanBerkelGate(final NetGraph [] gates, String gateType) { + // TODO: query van_berkel directive + if (gateType.startsWith("gate.C2.")) { + return gateType.replaceAll("gate\\.C2\\.","gate.C2_STAT."); + } else if (gateType.startsWith("gate.2AND2C2.")) { + return gateType.replaceAll("gate\\.2AND2C2\\.","gate.2AND2C2_STAT."); + } else if (gateType.startsWith("gate.AND2C2.")) { + return gateType.replaceAll("gate\\.AND2C2\\.","gate.AND2C2_STAT."); + } else if (gateType.startsWith("gate.AND2C2_ALT.")) { + return gateType.replaceAll("gate\\.AND2C2_ALT\\.","gate.AND2C2_STAT."); + } else if (gateType.startsWith("gate.C2_RHI.")) { + return gateType.replaceAll("gate\\.C2_RHI\\.","gate.C2_RHI_STAT."); + } else if (gateType.startsWith("gate.2AND2C2_RHI.")) { + return gateType.replaceAll("gate\\.2AND2C2_RHI\\.","gate.2AND2C2_RHI_STAT."); + } else if (gateType.startsWith("gate.AND2C2_RHI.")) { + return gateType.replaceAll("gate\\.AND2C2_RHI\\.","gate.AND2C2_RHI_STAT."); + } else if (gateType.startsWith("gate.AND2C2_RHI_ALT.")) { + return gateType.replaceAll("gate\\.AND2C2_RHI_ALT\\.","gate.AND2C2_RHI_STAT."); + } + return null; + } + + /** Replace gate with vanBerkel gate if possible */ + private boolean vanBerkel(final NetGraph [] gates, + final NetNode node, + final NetGraph smallInv, + final boolean addInv, + final CastFileParser cfp, + final Cadencize cad) { + if (node.gate==null) return false; + String vb = vanBerkelGate(gates,node.gate.type); + if (vb==null) return false; + try { + NetGraph vbGraph = CastDesign.getGateNetGraph(cfp,vb,Vdd.name,GND.name,cad); + if (addInv || node.inverse==null) addSmallInverter(node,smallInv); + TreeMap map = new TreeMap(node.gate.map); + map.put(HierName.makeHierName("c"),node.inverse.name); // TODO: directive + node.deleteEdges(); // delete old edges + node.gate = new GateInstance(map,vbGraph); + addNetGraph(vbGraph,map,true); + return true; + } catch (Exception e) { + System.err.println("ERROR: unable to parse van-berkel gate " + vb); + return false; + } + } + + /** + * Attach a full staticizer, weak inverter, or combinational + * staticizer to a node. Chooses based on staticizer_type + * directives and availabibility of 3 special gates. + * + * @param node node to attached the staticizer to + * @param staticizerGraph netgraph of the full staticizer gate + * @param weakInverterGraph netgraph of the weak inverter gate + * @param stup the staticizer type declared for the pull up + * @param stdn the staticizer type declared for the pull down + * @param ttup the transistor type declared for the pull up + * @param ttdn the transistor type declared for the pull down + **/ + private void addStaticizer(final NetGraph[] gates, + final NetNode node, + final NetGraph staticizerGraph, + final NetGraph weakInverterGraph, + final NetGraph smallInverterGraph, + final int stup, + final int stdn, + final int ttup, + final int ttdn, + final CastFileParser cfp, + final Cadencize cad) { + boolean weakUp = Staticizer.isWeakFeedback(stup); + boolean weakDn = Staticizer.isWeakFeedback(stdn); + boolean combUp = Staticizer.isCombinationalFeedback(stup); + boolean combDn = Staticizer.isCombinationalFeedback(stdn); + boolean autoUp = Staticizer.isAutomaticFeedback(stup); + boolean autoDn = Staticizer.isAutomaticFeedback(stdn); + boolean addInv = Staticizer.addSmallInverter(stup) || Staticizer.addSmallInverter(stdn); + if (Staticizer.isBadStaticizerType(stup)) { + System.err.println("ERROR: bad staticizer_type=" + stup + + " on " + node.name + "+"); + } + if (Staticizer.isBadStaticizerType(stdn)) { + System.err.println("ERROR: bad staticizer_type=" + stdn + + " on " + node.name + "-"); + } + if (autoUp && autoDn) { + if (vanBerkel(gates,node,smallInverterGraph,addInv,cfp,cad)) return; + } + if (autoUp || autoDn) { + // deduce logic from NetNode + MultiSet netUp = new MultiSet(); + MultiSet netDn = new MultiSet(); + MultiSet holdUp = new MultiSet(); + MultiSet holdDn = new MultiSet(); + Dnf.fromNetNode(node,netUp,netDn,holdUp,holdDn); + // choose COMB_STATICIZER when opposing logic is straight chain of <=3 depth + if (autoUp) { + combUp = netDn.size()==1 && ((MultiSet) netDn.get(0)).size()<=3; + weakUp = !combUp; + if (verbose) + System.err.println("NOTE: chose " + + (combUp ? "COMB_STATICIZER" : "WEAK_STATICIZER") + + " for " + node.name + "+"); + } + if (autoDn) { + combDn = netUp.size()==1 && ((MultiSet) netUp.get(0)).size()<=3; + weakDn = !combDn; + if (verbose) + System.err.println("NOTE: chose " + + (combDn ? "COMB_STATICIZER" : "WEAK_STATICIZER") + + " for " + node.name + "-"); + } + } + if (weakUp && weakDn && !addInv && (node.inverse!=null) && (weakInverterGraph!=null)) + addWeakInv(node, weakInverterGraph); + else if (weakUp && weakDn && (staticizerGraph!=null)) + addFullStaticizer(node, staticizerGraph); + else if ((node.inverse!=null) || (smallInverterGraph!=null)) + addCombinationalStaticizer(node,smallInverterGraph, + weakUp,weakDn,combUp,combDn,addInv,ttup,ttdn); + else { + System.err.println("ERROR: node " + node + " needs small-inverter."); + System.exit(1); + } + } + + /** + * Add staticizers to output nodes that need one. If + * addToGate is true, then staticizers will be added + * to nodes even if they have been matched by a gate. Otherwise, + * staticizers are only added to nodes that are has not been + * matched by a gate. This is dependent on whether the gate + * library includes staticizers. + */ + public void addStaticizers(final NetGraph[] gates, + final NetGraph staticizerGraph, + final NetGraph weakInverterGraph, + final NetGraph smallInverterGraph, + final boolean addToGate, + final CellInterface ci, + final CastFileParser cfp, + final Cadencize cad) { + + // make list of nodes to staticize + List opnodes = new ArrayList(); + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + NetNode node = (NetNode) i.next(); + if (!node.output) continue; + if (!addToGate && node.gate!=null) continue; + if (node.isCombinational()) continue; + if (nostaticizers.contains(node.name)) continue; + opnodes.add(node); + } + if (opnodes.size()==0) return; // nothing to staticize + + // query transistor type directives + Map ttype = DirectiveUtils.getPrsDirective(ci, + DirectiveConstants.TRANSISTOR_TYPE, + DirectiveConstants.HALFOP_TYPE); + final Map ttup = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getUps(ttype)); + final Map ttdn = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getDowns(ttype)); + final Integer ctt = (Integer) DirectiveUtils.getTopLevelDirective(ci, + DirectiveConstants.TRANSISTOR_TYPE); + + // query staticizer type directives + Map statType = DirectiveUtils.getPrsDirective(ci, + DirectiveConstants.STATICIZER_TYPE, + DirectiveConstants.HALFOP_TYPE); + final Map statup = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getUps(statType)); + final Map statdn = DirectiveUtils.canonizeKey(namespace, + DirectiveUtils.getDowns(statType)); + Integer cstatt = (Integer) DirectiveUtils.getTopLevelDirective(ci, + DirectiveConstants.STATICIZER_TYPE); + if (cstatt == null) cstatt = new Integer(0); + + for (Iterator i = opnodes.iterator(); i.hasNext(); ) { + NetNode node = (NetNode) i.next(); + if (node.staticizer!=null) return; // already there, I wonder why? + final List l = Collections.singletonList(node.name); + final NetGraph staticizer = + getMultipleTransistorGate(staticizerGraph, l.iterator(), + ttup, ttdn, ctt, cfp, cad); + final NetGraph weakInv = + getMultipleTransistorGate(weakInverterGraph, l.iterator(), + ttup, ttdn, ctt, cfp, cad); + final NetGraph smallInv = + getMultipleTransistorGate(smallInverterGraph, null, + null, null, ctt, cfp, cad); + addStaticizer(gates, node, staticizer, weakInv, smallInv, + getHalfOpDirective(statup, node.name, cstatt), + getHalfOpDirective(statdn, node.name, cstatt), + getHalfOpDirective(ttup, node.name, ctt), + getHalfOpDirective(ttdn, node.name, ctt), + cfp,cad); + } + } + + /** + * Imply exlchi/excllo statements for every inverter in/out. Used + * by CDL2Cast to eliminate transient interfering paths. + **/ + private void implyExclusiveInverters() { + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + if (node.inverseOf==null) continue; + Collection n = new ArrayList(); + n.add(node.name); + n.add(node.inverseOf.name); + ExclusiveNodeSet exclhi = + new ExclusiveNodeSet(ExclusiveNodeSet.HI, n); + ExclusiveNodeSet excllo = + new ExclusiveNodeSet(ExclusiveNodeSet.LO, n); + exclusives.addExclusiveNodeSet(exclhi); + exclusives.addExclusiveNodeSet(excllo); + } + } + + /** + * Imply that inverter structures overpower other fanins of output + * nodes. Eliminates the interfering paths. Used to guess prs + * for cells with lots of pass gates. + **/ + private void implyStrongInverters() { + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + if (!node.output) continue; + if (node.interferingInverseOf == null) continue; + MultiSet newpaths = new MultiSet(); + for (Iterator s = node.paths.iterator(); s.hasNext(); ) { + NetPath path = (NetPath) s.next(); + if (path.edges.size()!=1) continue; + NetEdge edge = (NetEdge) (path.getEdges().get(0)); + if (edge.gate != node.interferingInverseOf) continue; + newpaths.add(path); + } + node.paths = newpaths; + } + } + + /** + * Return a ProductionRuleSet generated from the NetGraph. Used + * by CDL2Cast to generate simulatable PRS for standard gates or + * licensed cores. Handles pass gates, as long as you pull to + * correct rail through proper transistor type. Automatically + * assumes inverter in/out are exclusive for generating paths. + * Also assumes inverter subgraphs overpower other fanins. + * + * In the PRS any guard which is driven by a chain of inverters is + * replaced with the root of that chain in the appropriate sense. + * This avoids problems simulating temporary inteference of + * pass-gates in DSim. + **/ + public ProductionRuleSet getProductionRuleSet() { + implyExclusiveInverters(); // imply that inverters are exclusive + prepareForLvs(); // find paths again with new exclusions + implyStrongInverters(); // delete paths that interfere with inverters + ProductionRuleSet prs = new ProductionRuleSet(); + + // map nodes to the root of an a driving inverter chain, if any + TreeMap inverter_map = new TreeMap(); + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + if (node.inverseOf!=null) { + inverter_map.put(node.name,node.inverseOf.name); + } else if (node.interferingInverseOf!=null) { + inverter_map.put(node.name,node.interferingInverseOf.name); + } + } + + // translate each output node into PRS + for (Iterator t = nodes.iterator(); t.hasNext(); ) { + NetNode node = (NetNode) t.next(); + if (!node.output) continue; + if (node.isStaticizerInverter()) continue; + + // get dnf for this node + MultiSet netUp = new MultiSet(); + MultiSet netDn = new MultiSet(); + MultiSet holdUp = new MultiSet(); + MultiSet holdDn = new MultiSet(); + Dnf.fromNetNode(node,netUp,netDn,holdUp,holdDn); + + // default prs parameters + BooleanExpressionInterface guard; + HierName target = node.name; + boolean isIsochronic = false; + boolean isUnstableP = true; // assume its nasty stuff + boolean isMetastableP = false; + boolean isTimedP = false; + int after = -1; + boolean absolute = false; + HierName powerSupply; + int direction; + ProductionRule rule; + + // check for combinational logic + boolean combinational = node.isCombinational(); + + // add down production rule + netDn = Dnf.getCanonicalForm(netDn,ProductionRule.UP,exclusives); + guard = Dnf.getBooleanExpression(netDn,true,combinational ? null : inverter_map); + powerSupply = GND.name; + direction = ProductionRule.DOWN; + rule = new ProductionRule(guard,target,powerSupply,direction, + isIsochronic,isUnstableP,isMetastableP,isTimedP, + after,absolute); + if (netDn.size()>0) prs.addProductionRule(rule); + + // add up production rule + netUp = Dnf.getCanonicalForm(netUp,ProductionRule.DOWN,exclusives); + guard = Dnf.getBooleanExpression(netUp,false,combinational ? null : inverter_map); + powerSupply = Vdd.name; + direction = ProductionRule.UP; + rule = new ProductionRule(guard,target,powerSupply,direction, + isIsochronic,isUnstableP,isMetastableP,isTimedP, + after,absolute); + if (netUp.size()>0) prs.addProductionRule(rule); + } + return prs; + } + + /** Debugging string. */ + public String toString () { + String s; + s = "Nodes(" + nodes.size() + ")\n"; + for (Iterator t = nodes.iterator(); t.hasNext(); ) s += " " + t.next() + "\n"; + Collection edges = getEdges(); + s += "Edges(" + edges.size() + ")\n"; + for (Iterator t = edges.iterator(); t.hasNext(); ) s += " " + t.next() + "\n"; + Collection paths = getPaths(); + s += "Paths(" + paths.size() + ")\n"; + for (Iterator t = paths.iterator(); t.hasNext(); ) s += " " + t.next() + "\n"; + return s; + } + + /** + * Merges in another NetGraph. Auto-generated nodes are renamed, and + * unshared edges are reassigned fold numbers. + * + * Also handles partial symmetrization for any edges with PARTIAL_FOLD + * fold_type. + * + * For this to make sense, both this netgraph and the other should + * have the same exclusion rules and namespaces. + **/ + public void mergeFrom(NetGraph ng, TreeMap node_map) { + TreeMap sym_map = new TreeMap(); // map for partial symmetrization + + // copy nodes, renaming anonymous ones, and merging non-anonymous + for (Iterator i = ng.nodes.iterator(); i.hasNext(); ) { + NetNode n = (NetNode) i.next(); + if (!n.named && !n.isRail() && node_map.get(n.name)==null) { + NetNode new_node = new NetNode(); + nodes.add(new_node); + node_map.put(n.name, new_node.name); + if (n.edges.size()==2) { // non-contacted internal node + new_node = new NetNode(); + nodes.add(new_node); + } + sym_map.put(n.name,new_node.name); + } else { + node_map.put(n.name, n.name); + sym_map.put(n.name, n.name); + NetNode new_node = createNetNode(n.name); + if (n.gate != null) { + Debug.assertTrue(new_node.gate == null, + "two gates matched when merging."); + GateInstance gi = n.gate; + new_node.gate = + new GateInstance(gi.type, gi.map, gi.gateGraph); + } + } + } + + // copy edges, optionally symmetrizing + for (Iterator i = ng.getEdges().iterator(); i.hasNext(); ) { + NetEdge e = (NetEdge) i.next(); + boolean partialSymmetrize = (fold_type(e.fold) == NetEdge.PARTIAL_FOLD); + boolean trunkSymmetrize = (fold_type(e.fold) == NetEdge.TRUNK_FOLD); + if (partialSymmetrize || trunkSymmetrize) { // create two symmetrized edges + // create normal edge + new NetEdge(mapNetNode(e.source.name, node_map), + mapNetNode(e.gate.name, node_map), + mapNetNode(e.drain.name, node_map), + e.type, e.fold, e.width/2, e.length, + e.library, e.getTransistorType()); + // s/d of symmetrized transistor + NetNode s = e.source; + NetNode d = e.drain; + // identify s/d of the stack + NetNode stackS = e.findStackSource(); + NetNode stackD = e.findStackDrain(); + // swap s/d if it matches the stack's s/d + if (partialSymmetrize || stackS.isRail() || stackD.isRail()) { + if (s == stackS) s = stackD; + if (d == stackD) d = stackS; + } + // create symmetrized edge (reverse S/D order) + new NetEdge(mapNetNode(d.name,sym_map), + mapNetNode(e.gate.name, sym_map), + mapNetNode(s.name,sym_map), + e.type, e.fold, e.width/2, e.length, + e.library, e.getTransistorType()); + } else { // create one edge + new NetEdge(mapNetNode(e.source.name, node_map), + mapNetNode(e.gate.name, node_map), + mapNetNode(e.drain.name, node_map), + e.type, e.fold, e.width, e.length, + e.library, e.getTransistorType()); + } + } + } + + /** Normal usage of mergeFrom with an empty node_map **/ + public void mergeFrom(NetGraph ng) { + TreeMap node_map = new TreeMap(); // HierName -> HierName + mergeFrom(ng,node_map); + } + + /** + * Builds a map suitable for addNetGraph(); that can be used to add this + * graph to another with a prefix of prefix. + * + * @param prefix The prefix to use. + * @return The TreeMap built. + * + * @see #addNetGraph(NetGraph, TreeMap, boolean) + **/ + public TreeMap constructPrefixMap(HierName prefix) { + TreeMap rv = new TreeMap(); + + for (Iterator i = nodes.iterator(); i.hasNext(); ) { + NetNode n = (NetNode) i.next(); + if (n.name.isGenerated()) continue; // they get remapped automatically. + if (n.name.isGlobal()) { + // Handled specially in LVS, so handled specially here. + rv.put(n.name, n.name); + } else { + rv.put(n.name, HierName.append(prefix, n.name)); + } + } + return rv; + } + + /** Are there any sneakpaths? */ + private boolean hasSneakPaths() { + Iterator t = nodes.iterator(); + while (t.hasNext()) { + NetNode node = (NetNode) t.next(); + if (node.output) if (node.hasSneakPaths()) return true; + } + return false; + } + + /** + * Sets foldingFactors of all edges in the NetGraph. + * As a side-effect, also sets aveDriveStrength[], edgeFanout[], + * and gateLoad[] of all nodes. + **/ + private void setFoldingFactors() { + if (doneFoldingFactors == true) return; + for (Iterator ni = nodes.iterator(); ni.hasNext();) { + NetNode node = (NetNode)ni.next(); + Set pathsToProcess = new HashSet(node.paths); + node.aveDriveStrength = new double[] { 0.0F, 0.0F }; + int[] numUniquePaths = { 0, 0 }; + while (pathsToProcess.size() > 0) { + NetPath path1 = (NetPath) pathsToProcess.iterator().next(); + List equivalentPaths = new ArrayList(); + // Find all unique edges in equivalent paths + Set uniqueEdges = new HashSet(); + for (Iterator pi=pathsToProcess.iterator(); pi.hasNext();) { + NetPath path2 = (NetPath) pi.next(); + if (path1.compareTo(path2)==0) { + equivalentPaths.add(path2); + uniqueEdges.addAll(path2.edges); + pi.remove(); + } + } + // Aggregate resistance (squares) of equivalent transistors + double R = 0.0; // series resistance + while (uniqueEdges.size() > 0) { + Iterator ei=uniqueEdges.iterator(); + NetEdge edge1 = (NetEdge) ei.next(); + ei.remove(); // parallel conductance + double G = edge1.width / edge1.length; + edge1.gate.edgeFanout[edge1.type]++; + edge1.gate.gateLoad[edge1.type] += edge1.width*edge1.length; + while (ei.hasNext()) { + NetEdge edge2 = (NetEdge) ei.next(); + if (edge2.gate.compareTo(edge1.gate)==0) { + G += edge2.width / edge2.length; + ei.remove(); + edge2.gate.edgeFanout[edge2.type]++; + edge2.gate.gateLoad[edge2.type] += + edge2.width * edge2.length; + } + } + R += 1/G; + } + node.aveDriveStrength[path1.type] += 1/R; + numUniquePaths[path1.type]++; + + // Determine folding factors of all paths + for (Iterator pi=equivalentPaths.iterator(); pi.hasNext();) { + NetPath path = (NetPath) pi.next(); + double foldingFactor = path.getSquares() / R; + for (Iterator ei=path.edges.iterator(); ei.hasNext();) { + NetEdge edge = (NetEdge) ei.next(); + assert (edge.foldingFactor == -1.0 || + edge.foldingFactor == foldingFactor); + edge.foldingFactor = foldingFactor; + } + } + } + for (int i=0; i<1; i++) { + if (numUniquePaths[i] > 0) + node.aveDriveStrength[i] /= numUniquePaths[i]; + } + } + doneFoldingFactors = true; + } + + /** Returns the "unfolded" transistor count of the NetGraph **/ + public int getUnfoldedTransistorCount() { + if (!doneFoldingFactors) setFoldingFactors(); + double count = 0.0; + for (Iterator ei=getEdges().iterator(); ei.hasNext();) { + NetEdge edge = (NetEdge)ei.next(); + assert edge.foldingFactor != -1.0F; + count += 1.0/edge.foldingFactor; + } + return (int)count; + } + + /** pick fold number from shared group */ + private static int fold_from_group(int group, int type) { + return (group<<3) | type; + } + + /** return the fold type given a fold number */ + private static int fold_type(int fold) { + return fold & 7; + } + +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetToPrs.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetToPrs.java new file mode 100644 index 0000000000..0eadbab5b3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/NetToPrs.java @@ -0,0 +1,149 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.lvs; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.file.common.HierName; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.util.bool.*; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; + +import com.avlsi.file.cdl.CDLParser; +import java.io.PrintWriter; +import java.io.FileWriter; +import com.avlsi.io.FileSearchPath; + +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +/** + * Generate a prs set from a netlist body. Use for importing standard gates. + * + * @author Andrew Lines + * @version $Revision$ $Date$ + **/ +public final class NetToPrs { + + /** Enable debugging output. */ + static boolean verbose = false; + + /** Usage error. */ + private static void usage( int exitCode ) { + System.err.println("Usage: java " + NetToPrs.class.getName() + "\n" + + " [--config=file]\n" + + " [--cast-path=castpath]\n" + + " [--cast-version=1 | --cast-version=2]\n" + + " --cell=castCell"); + + System.exit( exitCode ); + } + + /** Output prs from cdl. */ + public static void main(String[] args) throws Exception { + CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + CommandLineArgs theArgs = cachedArgs; + + // get arguments for cast parsing + final FileSearchPath castPath = + new FileSearchPath( theArgs.getArgValue( "cast-path", "." ) ); + String castVersion= theArgs.getArgValue("cast-version",null); + + // start cast parser + String castCellName = theArgs.getArgValue("cell",null); + if (castCellName==null) usage(1); + final CastFileParser cfp = new CastFileParser(castPath,castVersion,verbose); + + // get CellInterface + final CellInterface castCell; + castCell = cfp.getFullyQualifiedCell( castCellName ); + + // make a cadencizer + final Cadencize cadencizer = new Cadencize(true); + final CadenceInfo ci = cadencizer.convert(castCell); + + // get CAST namespace + AliasedSet namespace = ci.getLocalNodes(); + if (verbose) System.err.println("Namespace=\n" + namespace); + + // get exclusives declarations + final ExclusiveNodeSets exclusives = ci.getLocalExclusiveNodeSets(); + if (verbose) System.err.println("Exclusives=\n" + exclusives); + + // get staticizer related directives + final Map nostats = + DirectiveUtils.getPrsDirective(castCell, + DirectiveConstants.NO_STAT, + DirectiveConstants.NODE_TYPE); + final Set nostatnodes = DirectiveUtils.getExplicitTrues(nostats); + + // build a NetGraph from cdl [or prs] of cast cell + List gates = new ArrayList(); + List problems = new ArrayList(); + NetGraph netgraph = new NetGraph(namespace,exclusives,problems, + HierName.makeHierName("Vdd"), + HierName.makeHierName("GND"), + nostatnodes); + netgraph.addCellInterface(castCell,gates,cfp,cadencizer); + netgraph.prepareForLvs(); + if (problems.size()>0) System.err.println("Problems:\n" + problems); + + // emit prs + ProductionRuleSet prs = netgraph.getProductionRuleSet(); + for (Iterator i = netgraph.nodes.iterator(); i.hasNext(); ) { + NetGraph.NetNode node = (NetGraph.NetNode) i.next(); + if (!node.isPort() && !node.isStaticizerInverter() && + (node.isGate() || node.isOutput())) + System.out.println("node \"" + node.name + "\";"); + } + System.out.print(prs.toString()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/PrsToNet.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/PrsToNet.java new file mode 100644 index 0000000000..9ef076a916 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/PrsToNet.java @@ -0,0 +1,382 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.lvs; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.ExclusiveNodeSet; +import com.avlsi.cell.ExclusiveNodeSets; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.file.common.DeviceTypes; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.aspice.Transistor; +import com.avlsi.file.common.HierName; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.container.Pair; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.util.bool.*; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.cast.CastFile; +import com.avlsi.cast.CastFileParser; + +import com.avlsi.file.cdl.CDLParser; +import java.io.PrintWriter; +import java.io.FileWriter; +import com.avlsi.io.FileSearchPath; + + +import com.avlsi.util.container.StringContainerIterator; + +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; + +/** + * Generate a netlist cdl from a prs body of a cell. + * Includes computing a minimal gate network, adding staticizers, + * and matching library gates. + * + * @author Andrew Lines + * @version $Revision$ $Date$ + **/ +public final class PrsToNet { + + /** Enable debugging output. */ + static boolean verbose = false; + + /** + * Generate a NetGraph from a CellInterface. libraryFile, + * staticizerType, weakInverterType, and smallInverterType + * may all be null if castCell already has a gate-matched + * netlist block. If libraryFile is specified, all gates + * are used for gate matching. + **/ + public static NetGraph getNetGraph(final CellInterface castCell, + final CastFileParser cfp, + final String libraryFile, + final String staticizerType, + final String weakInverterType, + final String smallInverterType) + throws Exception { + return getNetGraph(castCell, cfp, libraryFile, staticizerType, + weakInverterType, smallInverterType, + Collections.emptyList()); + } + + /** + * Generate a NetGraph from a CellInterface. libraryFile, + * staticizerType, weakInverterType, smallInverterType, and + * gateTypes may all be null if castCell already has a + * gate-matched netlist block. + **/ + public static NetGraph getNetGraph(final CellInterface castCell, + final CastFileParser cfp, + final String libraryFile, + final String staticizerType, + final String weakInverterType, + final String smallInverterType, + final List gateTypes) throws Exception { + + if (verbose) System.out.println("Building netgraph for subcell "+ + castCell.getFullyQualifiedType()); + + // load library staticizer and gates + NetGraph staticizerGraph = null; + NetGraph weakInverterGraph = null; + NetGraph smallInverterGraph = null; + List gates = new ArrayList(); + if (libraryFile != null) { + try { + // parse library file + CDLParser cdlParser = new CDLParser(); + if (libraryFile != null) { + cdlParser.parseFile(libraryFile); + } + Iterator t; + staticizerGraph = getCdlNetGraph(cdlParser,staticizerType); + weakInverterGraph = getCdlNetGraph(cdlParser,weakInverterType); + smallInverterGraph = getCdlNetGraph(cdlParser,smallInverterType); + if (gateTypes.size()>0) t = gateTypes.iterator(); // specified + else t = cdlParser.getCellTypes(); // match all + while (t.hasNext()) { + String gateType = (String) t.next(); + NetGraph gateGraph = getCdlNetGraph(cdlParser,gateType); + if (gateGraph==null) continue; + gates.add(gateGraph); + } + } + catch (Exception e) { + System.err.println("Couldn't parse "+libraryFile+"."); + System.err.println(e.toString()); + System.exit(1); + } + } + + // Flatten to get the right namespace + CellInterface flatCell = castCell.flatten(-1); + + // make a cadencizer + final Cadencize cadencizer = new Cadencize(true); + final CadenceInfo ci = cadencizer.convert(flatCell); + + // get CAST namespace + AliasedSet namespace = ci.getLocalNodes(); + if (verbose) System.err.println("Namespace=\n" + namespace); + + // get exclusives declarations + final ExclusiveNodeSets exclusives = ci.getLocalExclusiveNodeSets(); + if (verbose) System.err.println("Exclusives=\n" + exclusives); + + // get staticizer related directives + final Map nostats = + DirectiveUtils.getPrsDirective(castCell, + DirectiveConstants.NO_STAT, + DirectiveConstants.NODE_TYPE); + final Set nostatnodes = DirectiveUtils.getExplicitTrues(nostats); + + // build a NetGraph from prs + List problems = new ArrayList(); + NetGraph netgraph = new NetGraph(namespace,exclusives,problems, + HierName.makeHierName("Vdd"), + HierName.makeHierName("GND"), + nostatnodes); + if (problems.size()>0) System.err.println("Problems:\n" + problems); + + // Recursively add each subcell's netgraph + if (!castCell.containsCompletePrs()) { + HashMap ngCache = new HashMap(); + for (Iterator sci=castCell.getLocalSubcellPairs(); sci.hasNext();) { + Pair subcellPair = (Pair)sci.next(); + HierName name = (HierName) subcellPair.getFirst(); + CellInterface subcell = (CellInterface) subcellPair.getSecond(); + String type = subcell.getFullyQualifiedType(); + if (!subcell.hasRealProductionRule()) continue; + NetGraph subcellNetgraph = (NetGraph) ngCache.get(type); + if (subcellNetgraph == null) { + subcellNetgraph = getNetGraph(subcell,cfp,libraryFile, + staticizerType,weakInverterType, + smallInverterType,gateTypes); + ngCache.put(type,subcellNetgraph); + } + TreeMap prefixMap = subcellNetgraph.constructPrefixMap(name); + netgraph.addNetGraph(subcellNetgraph,prefixMap,false); + } + // Not propagated correctly by addNetGraph() + netgraph.markPortNodes(castCell); + netgraph.prepareForLvs(); // needed to find paths properly + } + else { + // Production rules, gate matching, and minimization. + netgraph.addCellInterface(castCell, gates, cfp, cadencizer); + //if (verbose) System.err.println("DNF NetGraph=\n" + netgraph); + + netgraph.prepareForLvs(); // needed to find paths properly + + // add staticizers + netgraph.addStaticizers((NetGraph[]) gates.toArray(), + staticizerGraph,weakInverterGraph, + smallInverterGraph,true, + castCell,cfp,cadencizer); + } + + // output netgraph + if (verbose) System.err.println("MGN NetGraph=\n" + netgraph); + + return netgraph; + } + + /** Usage error. */ + private static void usage( int exitCode ) { + System.err.println("Usage: java " + PrsToNet.class.getName() + "\n" + + " [--verbose=0|1]\n" + + " [--config=file]\n" + + " [--cast-path=castpath]\n" + + " [--cast-version=1 | --cast-version=2]\n" + + " [--library=library.cdl]\n" + + " [--staticizer=staticizerFQCN]\n" + + " [--weak-inverter=weakInverterFQCN]\n" + + " [--small-inverter=smallInverterFQCN]\n" + + " [--gates=gate1,gate2,...]\n" + + " --cell=castCell"); + + System.exit( exitCode ); + } + + /** Parses a list for a string where each entry is + seperated from the next by a ,. + + @param gateList String to parse. + @return An ArrayList each entry of which is a java.lang.String. + */ + private static ArrayList parseGateList( String gateList ) { + ArrayList ret = new ArrayList(); + + StringBuffer accumulator = new StringBuffer(); + int i=0; + + for( i=0; i 0 ) { + ret.add( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + } + } + else { + accumulator.append( gateList.charAt(i) ); + } + } + if ( accumulator.length() > 0 ) { + ret.add( accumulator.toString() ); + accumulator.delete( 0, accumulator.length() ); + } + return ret; + } + + /** Make a NetGraph given a cdl file name and cell name. */ + static NetGraph getCdlNetGraph(CDLParser cdlParser, String cdlCellName) + throws Exception { + AspiceFile aspiceCell = cdlParser.getCell(cdlCellName); + + if (aspiceCell == null) { + System.err.println("WARNING: cell " + cdlCellName + " not found"); + return null; + } + + List problems = new ArrayList(); + NetGraph netgraph = new NetGraph(null,null,problems, + HierName.makeHierName("Vdd"), + HierName.makeHierName("GND"), + Collections.EMPTY_SET); + if (problems.size()>0) System.err.println("Problems in " + cdlCellName + + ":\n" + problems); + netgraph.gateType = cdlCellName; + netgraph.addAspice(aspiceCell); + netgraph.prepareForLvs(); // needed to find paths properly + return netgraph; + } + + /** Output network from prs body of a cell. */ + public static void main(String[] args) throws Exception { + CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + CommandLineArgs theArgs = cachedArgs; + + // get arguments for cast parsing + final FileSearchPath castPath = + new FileSearchPath( theArgs.getArgValue( "cast-path", "." ) ); + final String castVersion = theArgs.getArgValue("cast-version",null); + final CastFileParser cfp = new CastFileParser(castPath,castVersion,verbose); + + // get the staticizer and gate list arguments + if (theArgs.getArgValue("verbose","").equals("1")) { + verbose = true; + } + final String libraryFile = theArgs.getArgValue("library", null); + final String staticizerType = theArgs.getArgValue("staticizer", null); + final String weakInverterType = theArgs.getArgValue("weak-inverter", null); + final String smallInverterType = theArgs.getArgValue("small-inverter", null); + + final ArrayList gateTypes = parseGateList( theArgs.getArgValue( "gates", "" ) ); + + // get cast cell name + String castCellName = theArgs.getArgValue("cell",null); + if (castCellName==null) usage(1); + + // Get the CellInterface + final CellInterface castCell = cfp.getFullyQualifiedCell(castCellName); + + // build a NetGraph from the cellInterface + NetGraph netgraph = getNetGraph(castCell,cfp,libraryFile, + staticizerType,weakInverterType, + smallInverterType,gateTypes); + + // output .cdl and .il files + final Cadencize cadencizer = new Cadencize(true); + final CadenceInfo ci = cadencizer.convert(castCell); + String cellType = castCell.getFullyQualifiedType(); + PrintWriter cdlOut = new PrintWriter(new FileWriter(cellType + ".cdl")); + PrintWriter ilOut = new PrintWriter(new FileWriter(cellType + ".il")); + final AliasedMap portNodes = ci.getPortNodes(); + Iterator t = portNodes.getCanonicalKeys(); + String portlist = ""; + String quotedportlist = ""; + while (t.hasNext()) { + HierName name = (HierName) t.next(); + if (((Boolean) portNodes.getValue(name)).booleanValue()) { + portlist += " " + name; + quotedportlist += " \"" + name + "\""; + } + } + cdlOut.println(".SUBCKT " + cellType + "" + + portlist + "\n" + + netgraph.cdlString() + ".ENDS"); + ilOut.println("pinNames = (list" + quotedportlist + ")"); + ilOut.println("(defun createGates () \n" + + netgraph.skillString() + ")"); + cdlOut.close(); + ilOut.close(); + + // output statistics + t = netgraph.getEdges().iterator(); + int numNMOS=0, numPMOS=0, numGateNMOS=0, numGatePMOS=0; + int numGates=0, numStaticizers=0; + while (t.hasNext()) { + NetGraph.NetEdge e = (NetGraph.NetEdge) t.next(); + if (e.type == DeviceTypes.N_TYPE) { + if (e.library && !e.floating) numGateNMOS++; + else numNMOS++; + } + else if (e.type == DeviceTypes.P_TYPE) { + if (e.library && !e.floating) numGatePMOS++; + else numPMOS++; + } + } + t = netgraph.getNodes().iterator(); + while (t.hasNext()) { + NetGraph.NetNode n = (NetGraph.NetNode) t.next(); + if (n.gate != null) numGates++; + if (n.staticizer != null) numStaticizers++; + } + System.out.println(castCellName + + "\nGates=" + numGates + " Staticizers=" + numStaticizers + + "\nN=" + numNMOS + " P=" + numPMOS + + " GateN=" + numGateNMOS + " GateP=" + numGatePMOS + + " Total=" + (numNMOS + numPMOS + numGateNMOS + numGatePMOS)); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Staticizer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Staticizer.java new file mode 100644 index 0000000000..7afa7cb58f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/Staticizer.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012 Intel. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.lvs; + +public class Staticizer { + /** staticizer_type constants from standard/process.cast **/ + static final int NO_STATICIZER = -1; + static final int WEAK_STATICIZER = 0; + static final int FULL_STATICIZER = 1; + static final int COMB_STATICIZER = 2; + static final int FULL_COMB_STATICIZER = 3; + static final int AUTO_STATICIZER = 4; + static final int FULL_AUTO_STATICIZER = 5; + + /** Test if staticizer_type is legal **/ + static boolean isBadStaticizerType(int st) { + return stFULL_AUTO_STATICIZER; + } + + /** Test if staticizer_type has weak interfering feedback **/ + static boolean isWeakFeedback(int st) { + return st==WEAK_STATICIZER || st==FULL_STATICIZER; + } + + /** Test if staticizer_type has combinational feedback **/ + static boolean isCombinationalFeedback(int st) { + return st==COMB_STATICIZER || st==FULL_COMB_STATICIZER; + } + + /** Test if staticizer_type selects automatically **/ + static boolean isAutomaticFeedback(int st) { + return st==AUTO_STATICIZER || st==FULL_AUTO_STATICIZER; + } + + /** Test if explict inverter should be added **/ + static boolean addSmallInverter(int st) { + return st==FULL_STATICIZER || st==FULL_COMB_STATICIZER || st==FULL_AUTO_STATICIZER; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/SubtypeInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/SubtypeInfo.java new file mode 100644 index 0000000000..6c4415518d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/SubtypeInfo.java @@ -0,0 +1,86 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +/* + * Copyright 2001 Asynchronous Digital Design. All rights reserved. + * + * $Id$ + */ + +package com.avlsi.tools.lvs; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import com.avlsi.util.text.StringUtil; + +/** + * This is a description of the class + * + * @author Jesse Rosenstock + * @version $Name: $ $Date$ + **/ +final class SubtypeInfo { + public static final class SubtypeInfoFileFormatException + extends Exception { + SubtypeInfoFileFormatException(final String message) { + super(message); + } + } + + private final Map subtypeMap; + + public SubtypeInfo() { + subtypeMap = new HashMap(); + } + + public void parseSubtypes(final String fileName) + throws IOException, SubtypeInfoFileFormatException { + final BufferedReader reader = + new BufferedReader(new InputStreamReader( + new FileInputStream(fileName))); + String line; + + while ((line = reader.readLine()) != null) { + final String[] s = StringUtil.split(line, ':'); + + if (s.length != 2) + throw new SubtypeInfoFileFormatException("Expected 1 :, " + + "got" + (s.length - 1) + " in " + line); + + final String baseType = s[0]; + final String subType = s[1]; + + final String baseBase = (String) subtypeMap.get(baseType); + + if (baseBase != null) + throw new SubtypeInfoFileFormatException("Basetype " + + baseType + " is a subtype of " + baseBase + + "; not allowed."); + + final String subBase = (String) subtypeMap.get(subType); + + if (subBase != null) + throw new SubtypeInfoFileFormatException("Subtype " + + subType + " is a already a subtype of " + subBase); + + subtypeMap.put(subType, baseType); + } + } + + public String getBasetype(final String subType) { + String nextType; + String baseType = subType; + while ((nextType = (String) subtypeMap.get(baseType)) != null) + baseType = nextType; + return baseType; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/custom.mk new file mode 100644 index 0000000000..516f11788f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/custom.mk @@ -0,0 +1,10 @@ + +CURR_RESULT_FILES := $(CURR_TARGET_DIR)/jlvs.sh $(CURR_TARGET_DIR)/prs2net.sh $(CURR_RESULT_FILES) + +$(CURR_TARGET_DIR)/jlvs.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.lvs.LVS/" >$@ + +$(CURR_TARGET_DIR)/prs2net.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.lvs.PrsToNet/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/jlvs.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/jlvs.package new file mode 100644 index 0000000000..f5573024f0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/lvs/jlvs.package @@ -0,0 +1,10 @@ +1 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +java com.avlsi.tools.lvs.LVS +java com.avlsi.tools.lvs.PrsToNet +$arch/bin/jlvs.sh jlvs.sh 775 +$arch/bin/prs2net.sh prs2net.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/02-09-03.html b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/02-09-03.html new file mode 100644 index 0000000000..162a816bca --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/02-09-03.html @@ -0,0 +1,901 @@ + + + + +PReSto test results + + + +

    PRS for PRODUCER_SRAM_CTRL

    +
    +  prs {
    +    /* Generated on Feb 16, 2003 11:15 AM by ppelleti with PReSto of 02/09/03.
    +     * If you manually edit this PRS block, please add a comment here
    +     * saying what you changed-- otherwise, we will assume the PRS block
    +     * can be regenerated by running PReSto again. */
    +    node _INDEXv,_OVERFLOWv,lv,W_FILTER_CTRLv,RWA_FILTER_CTRLv,_rv,_lv,_le;
    +    node le,en,_en;
    +    _1of2 _RWA_FILTER_CTRL;
    +    _1of3 _W_FILTER_CTRL;
    +    
    +    /*** input ***/
    +    INDEX.0 | INDEX.1 => _INDEXv-
    +    OVERFLOW.0 | OVERFLOW.1 => _OVERFLOWv-
    +    ~_INDEXv & ~_OVERFLOWv #> lv+
    +    
    +    /*** logic ***/
    +    en & RWA_FILTER_CTRL.e & INDEX.0 & OVERFLOW.1 -> _RWA_FILTER_CTRL.0-
    +    en & RWA_FILTER_CTRL.e & (OVERFLOW.0 | INDEX.1) -> _RWA_FILTER_CTRL.1-
    +        <i:2: ~en & ~RWA_FILTER_CTRL.e -> _RWA_FILTER_CTRL.d[i]+ >
    +    
    +    en & W_FILTER_CTRL.e & INDEX.0 & OVERFLOW.1 -> _W_FILTER_CTRL.0-
    +    en & W_FILTER_CTRL.e & INDEX.0 & OVERFLOW.0 -> _W_FILTER_CTRL.1-
    +    en & INDEX.1 -> _W_FILTER_CTRL.2-
    +        <i:2: ~en & ~W_FILTER_CTRL.e -> _W_FILTER_CTRL.d[i]+ >
    +        ~en -> _W_FILTER_CTRL.d[2]+
    +    
    +    /*** output ***/
    +    <i:2: ~_RWA_FILTER_CTRL.d[i] => RWA_FILTER_CTRL.d[i]+ >
    +    <i:2: ~_W_FILTER_CTRL.d[i] => W_FILTER_CTRL.d[i]+ >
    +    
    +    ~_W_FILTER_CTRL.0 | ~_W_FILTER_CTRL.1 | ~_W_FILTER_CTRL.2 => W_FILTER_CTRLv+
    +    ~_RWA_FILTER_CTRL.0 | ~_RWA_FILTER_CTRL.1 => RWA_FILTER_CTRLv+
    +    W_FILTER_CTRLv & RWA_FILTER_CTRLv #> _rv-
    +    
    +    /*** ack ***/
    +    ~lv => _lv+
    +    ~_Reset | ~_rv & ~_lv #> _le+
    +    _le => le-
    +    le=INDEX.e=OVERFLOW.e;
    +    
    +    /*** enable ***/
    +    ~le => _en+
    +    _en => en-
    +  }
    +
    +
    +

    Simulation Results for PRODUCER_SRAM_CTRL

    +
    +standard.null.NULL
    +        |
    +        +--standard.base.CELL
    +                |
    +                +--standard.base.LEAF
    +                        |
    +                        +--test.PRODUCER_SRAM_CTRL
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cell Summary
    portINDEX: in standard.channel.e1of2
    portOVERFLOW: in +standard.channel.e1of2
    portRWA_FILTER_CTRL: out +standard.channel.e1of2
    portW_FILTER_CTRL: out +standard.channel.e1of2
    portVdd: in node of width 1
    portGND: in node of width 1
    port_RESET: in node of width 1
    #Rules44
    Dsim +Seed1045422956740
    +
    +
    Unimplemented Cells:
    +
    None.
    +
    +
    simulating with digital +environment
    +

    [INFO] Performing reset stress test...
    +[INFO] Running 10 test(s) for 1000 cycle(s) on +__rte_.RWA_FILTER_CTRL.e
    +[PASS] No interference, glitch, or instability detected.
    +
    +[INFO] Measuring NTPC on specified nodes
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] __rte_.RWA_FILTER_CTRL.e: 14.044995t (13[0.0092000365%] +14[99.8116%] 15[0.17920072%])
    +
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] cycling on __rte_.RWA_FILTER_CTRL.e:0for 500000 +transitions
    +[PASS] No interference, glitch, or instability detected.
    +[PASS] No data conflicts detected
    +[INFO] coverage: 100%

    +

    << PASSED>>

    +
    +
    Diagnostics
    +
    +[INFO] TOTAL COVERAGE: 100%
    + +

    [INFO] Processors Available: 1
    +[INFO] Total Memory: 4136Kb
    +[INFO] Free Memory: 3361Kb
    +[INFO] Used Memory: 775Kb
    +[INFO] Max Available Memory: 4136Kb

    +

    Simulation started at: Sun Feb 16 11:15:56 PST 2003
    +Simulation ended at: Sun Feb 16 11:19:54 PST 2003

    +
    +Fulcrum Microsystems.© copyright 2003. All Rights +Reserved. +
    +

    PRS for BUG_1909

    +
    +  prs {
    +    /* Generated on Feb 16, 2003 11:19 AM by ppelleti with PReSto of 02/09/03.
    +     * If you manually edit this PRS block, please add a comment here
    +     * saying what you changed-- otherwise, we will assume the PRS block
    +     * can be regenerated by running PReSto again. */
    +    node _Lv,Rv,_Rv,_le,le,en;
    +    _1of2 _R;
    +    
    +    /*** input ***/
    +    L.0 | L.1 => _Lv-
    +    
    +    /*** logic ***/
    +    en & R.e & L.1 -> _R.0-
    +    en & L.0 -> _R.1-
    +        <i:1: ~en & ~R.e -> _R.d[i]+ >
    +        ~en -> _R.d[1]+
    +    
    +    /*** output ***/
    +    ~_R.0 => R.d+
    +    
    +    ~_R.0 | ~_R.1 => Rv+
    +    
    +    /*** ack ***/
    +    ~Rv => _Rv+
    +    ~_Reset | ~_Rv & ~_Lv #> _le+
    +    _le => le-
    +    en=le=L.e;
    +  }
    +
    +
    +

    Simulation Results for BUG_1909

    +
    +standard.null.NULL
    +        |
    +        +--standard.base.CELL
    +                |
    +                +--standard.base.LEAF
    +                        |
    +                        +--test.BUG_1909
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Cell Summary
    portL: in standard.channel.e1of2
    portR: out standard.channel.e1of1
    portVdd: in node of width 1
    portGND: in node of width 1
    port_RESET: in node of width 1
    #Rules20
    Dsim +Seed1045423201327
    +
    +
    Unimplemented Cells:
    +
    None.
    +
    +
    simulating with digital +environment
    +

    [INFO] Performing reset stress test...
    +[INFO] Running 10 test(s) for 1000 cycle(s) on __rte_.L.e
    +[PASS] No interference, glitch, or instability detected.
    +
    +[INFO] Measuring NTPC on specified nodes
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] __rte_.en: 11.969937t (12[99.9992%] 13[2])
    +
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] cycling on __rte_.L.e:1for 500000 transitions
    +[PASS] No interference, glitch, or instability detected.
    +[PASS] No data conflicts detected
    +[INFO] coverage: 100%

    +

    << PASSED>>

    +
    +
    Diagnostics
    +
    +[INFO] TOTAL COVERAGE: 100%
    + +

    [INFO] Processors Available: 1
    +[INFO] Total Memory: 3888Kb
    +[INFO] Free Memory: 3200Kb
    +[INFO] Used Memory: 688Kb
    +[INFO] Max Available Memory: 3888Kb

    +

    Simulation started at: Sun Feb 16 11:20:01 PST 2003
    +Simulation ended at: Sun Feb 16 11:21:44 PST 2003

    +
    +Fulcrum Microsystems.© copyright 2003. All Rights +Reserved. +
    +

    PRS for BUG_1930

    +
    +  prs {
    +    /* Generated on Feb 16, 2003 11:21 AM by ppelleti with PReSto of 02/09/03.
    +     * If you manually edit this PRS block, please add a comment here
    +     * saying what you changed-- otherwise, we will assume the PRS block
    +     * can be regenerated by running PReSto again. */
    +    node _Lv,Rv,_Rv,_le,le,en;
    +    _1of3 _R;
    +    
    +    /*** input ***/
    +    L.0 | L.1 => _Lv-
    +    
    +    /*** logic ***/
    +    en & R.e & L.1 -> _R.0-
    +    en & R.e & L.0 -> _R.2-
    +        <i:3: ~en & ~R.e -> _R.d[i]+ >
    +    
    +    /*** output ***/
    +    <i:3: ~_R.d[i] => R.d[i]+ >
    +    
    +    ~_R.0 | ~_R.1 | ~_R.2 => Rv+
    +    
    +    /*** ack ***/
    +    ~Rv => _Rv+
    +    ~_Reset | ~_Rv & ~_Lv #> _le+
    +    _le => le-
    +    en=le=L.e;
    +  }
    +
    +
    +

    Simulation Results for BUG_1930

    +
    +standard.null.NULL
    +        |
    +        +--standard.base.CELL
    +                |
    +                +--standard.base.LEAF
    +                        |
    +                        +--test.BUG_1930
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Cell Summary
    portL: in standard.channel.e1of2
    portR: out standard.channel.e1of3
    portVdd: in node of width 1
    portGND: in node of width 1
    port_RESET: in node of width 1
    #Rules25
    Dsim +Seed1045423310709
    +
    +
    Unimplemented Cells:
    +
    None.
    +
    +
    simulating with digital +environment
    +

    [INFO] Performing reset stress test...
    +[INFO] Running 10 test(s) for 1000 cycle(s) on __rte_.R.e
    +[PASS] No interference, glitch, or instability detected.
    +
    +[INFO] Measuring NTPC on specified nodes
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] __rte_.R.e: 11.990164t (12[99.9936%] 13[0.0064000254%])
    +
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] cycling on __rte_.R.e:0for 500000 transitions
    +[PASS] No interference, glitch, or instability detected.
    +[PASS] No data conflicts detected
    +[INFO] coverage: 88.89%

    +

    << PASSED>>

    +
    +
    Diagnostics
    +
    +[INFO] TOTAL COVERAGE: 88.89%
    + +

    [INFO] Processors Available: 1
    +[INFO] Total Memory: 3964Kb
    +[INFO] Free Memory: 3250Kb
    +[INFO] Used Memory: 714Kb
    +[INFO] Max Available Memory: 3964Kb

    +

    Simulation started at: Sun Feb 16 11:21:50 PST 2003
    +Simulation ended at: Sun Feb 16 11:24:05 PST 2003

    +
    +Fulcrum Microsystems.© copyright 2003. All Rights +Reserved. +
    +

    PRS for FOO

    +
    +  prs {
    +    /* Generated on Feb 16, 2003 11:24 AM by ppelleti with PReSto of 02/09/03.
    +     * If you manually edit this PRS block, please add a comment here
    +     * saying what you changed-- otherwise, we will assume the PRS block
    +     * can be regenerated by running PReSto again. */
    +    node _Lv,Rv,_Rv,_le,le,en;
    +    _1of2 _R;
    +    
    +    /*** input ***/
    +    L.0 | L.1 => _Lv-
    +    
    +    /*** logic ***/
    +    en & R.e -> _R.0-
    +        <i:2: ~en & ~R.e -> _R.d[i]+ >
    +    
    +    /*** output ***/
    +    <i:2: ~_R.d[i] => R.d[i]+ >
    +    
    +    ~_R.0 | ~_R.1 => Rv+
    +    
    +    /*** ack ***/
    +    ~Rv => _Rv+
    +    ~_Reset | ~_Rv & ~_Lv #> _le+
    +    _le => le-
    +    en=le=L.e;
    +  }
    +
    +
    +

    Simulation Results for FOO

    +
    +standard.null.NULL
    +        |
    +        +--standard.base.CELL
    +                |
    +                +--standard.base.LEAF
    +                        |
    +                        +--test.FOO
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Cell Summary
    portL: in standard.channel.e1of2
    portR: out standard.channel.e1of2
    portVdd: in node of width 1
    portGND: in node of width 1
    port_RESET: in node of width 1
    #Rules21
    Dsim +Seed1045423452307
    +
    +
    Unimplemented Cells:
    +
    None.
    +
    +
    simulating with digital +environment
    +

    [INFO] Performing reset stress test...
    +[INFO] Running 10 test(s) for 1000 cycle(s) on __rte_.R.e
    +[PASS] No interference, glitch, or instability detected.
    +
    +[INFO] Measuring NTPC on specified nodes
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] __rte_.R.e: 10.064415t (10[99.9388%] 11[0.061200246%])
    +
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] cycling on __rte_.R.e:0for 500000 transitions
    +[PASS] No interference, glitch, or instability detected.
    +[PASS] No data conflicts detected
    +[INFO] coverage: 86.67%

    +

    << PASSED>>

    +
    +
    Diagnostics
    +
    +[INFO] TOTAL COVERAGE: 86.67%
    + +

    [INFO] Processors Available: 1
    +[INFO] Total Memory: 3888Kb
    +[INFO] Free Memory: 3198Kb
    +[INFO] Used Memory: 690Kb
    +[INFO] Max Available Memory: 3888Kb

    +

    Simulation started at: Sun Feb 16 11:24:12 PST 2003
    +Simulation ended at: Sun Feb 16 11:26:20 PST 2003

    +
    +Fulcrum Microsystems.© copyright 2003. All Rights +Reserved. +
    +

    PRS for JTAG_SHIFT_CELL_PRESTO

    +
    +  prs {
    +    /* Generated on Feb 16, 2003 11:26 AM by ppelleti with PReSto of 02/09/03.
    +     * If you manually edit this PRS block, please add a comment here
    +     * saying what you changed-- otherwise, we will assume the PRS block
    +     * can be regenerated by running PReSto again. */
    +    node _LSv,_LCv,_PLv,_STATEINv,x0,x1,_lv,RSv,RCv,POv,STATEOUTv,_x2,_x3,rv;
    +    node _rv,_le,le,en,_en;
    +    _1of3 _RS;
    +    _1of3 _RC;
    +    _1of3 _PO;
    +    _1of2 _STATEOUT;
    +    
    +    /*** input ***/
    +    LS.0 | LS.1 => _LSv-
    +    LC.0 | LC.1 | LC.2 => _LCv-
    +    PL.0 | PL.1 => _PLv-
    +    STATEIN.0 | STATEIN.1 => _STATEINv-
    +    ~_LSv & ~_LCv #> x0+
    +    ~_PLv & ~_STATEINv #> x1+
    +    x0 & x1 #> _lv-
    +    
    +    /*** logic ***/
    +    en & RS.e & LC.0 & STATEIN.0 -> _RS.0-
    +    en & RS.e & LC.0 & STATEIN.1 -> _RS.1-
    +    en & (LC.1 | LC.2) -> _RS.2-
    +        <i:2: ~en & ~RS.e -> _RS.d[i]+ >
    +        ~en -> _RS.d[2]+
    +    
    +    en & RC.e & LC.0 -> _RC.0-
    +    en & RC.e & LC.1 -> _RC.1-
    +    en & RC.e & LC.2 -> _RC.2-
    +        <i:3: ~en & ~RC.e -> _RC.d[i]+ >
    +    
    +    en & PO.e & LC.2 & STATEIN.0 -> _PO.0-
    +    en & PO.e & LC.2 & STATEIN.1 -> _PO.1-
    +    en & (LC.0 | LC.1) -> _PO.2-
    +        <i:2: ~en & ~PO.e -> _PO.d[i]+ >
    +        ~en -> _PO.d[2]+
    +    
    +    en & STATEOUT.e & ((LS.0 & LC.0) |
    +                       (LC.1 & PL.0) |
    +                       (LC.2 & STATEIN.0)) -> _STATEOUT.0-
    +    en & STATEOUT.e & ((LS.1 & LC.0) |
    +                       (LC.1 & PL.1) |
    +                       (LC.2 & STATEIN.1)) -> _STATEOUT.1-
    +        <i:2: ~en & ~STATEOUT.e -> _STATEOUT.d[i]+ >
    +    
    +    /*** output ***/
    +    <i:2: ~_RS.d[i] => RS.d[i]+ >
    +    <i:3: ~_RC.d[i] => RC.d[i]+ >
    +    <i:2: ~_PO.d[i] => PO.d[i]+ >
    +    <i:2: ~_STATEOUT.d[i] => STATEOUT.d[i]+ >
    +    
    +    ~_RS.0 | ~_RS.1 | ~_RS.2 => RSv+
    +    ~_RC.0 | ~_RC.1 | ~_RC.2 => RCv+
    +    ~_PO.0 | ~_PO.1 | ~_PO.2 => POv+
    +    ~_STATEOUT.0 | ~_STATEOUT.1 => STATEOUTv+
    +    RSv & RCv #> _x2-
    +    POv & STATEOUTv #> _x3-
    +    ~_x2 & ~_x3 #> rv+
    +    
    +    /*** ack ***/
    +    ~rv => _rv+
    +    ~_Reset | ~_rv & ~_lv #> _le+
    +    _le => le-
    +    le=LS.e=LC.e=PL.e=STATEIN.e;
    +    
    +    /*** enable ***/
    +    ~le => _en+
    +    _en => en-
    +  }
    +
    +
    +

    Simulation Results for JTAG_SHIFT_CELL_PRESTO

    +
    +standard.null.NULL
    +        |
    +        +--standard.base.CELL
    +                |
    +                +--standard.base.LEAF
    +                        |
    +                        +--test.JTAG_SHIFT_CELL_PRESTO
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cell Summary
    portLS: in standard.channel.e1of2
    portLC: in standard.channel.e1of3
    portPL: in standard.channel.e1of2
    portSTATEIN: in +standard.channel.e1of2
    portRS: out standard.channel.e1of2
    portRC: out standard.channel.e1of3
    portPO: out standard.channel.e1of2
    portSTATEOUT: out +standard.channel.e1of2
    portVdd: in node of width 1
    portGND: in node of width 1
    port_RESET: in node of width 1
    #Rules82
    Dsim +Seed1045423587453
    +
    +
    Unimplemented Cells:
    +
    None.
    +
    +
    simulating with digital +environment
    +

    [INFO] Performing reset stress test...
    +[INFO] Running 10 test(s) for 1000 cycle(s) on +__rte_.STATEOUT.e
    +[PASS] No interference, glitch, or instability detected.
    +
    +[INFO] Measuring NTPC on specified nodes
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] __rte_.STATEOUT.e: 18.023108t (17[0.058800235%] 18[99.7084%] +19[0.23280093%])
    +
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] cycling on __rte_.STATEOUT.e:0for 500000 transitions
    +[PASS] No interference, glitch, or instability detected.
    +[PASS] No data conflicts detected
    +[INFO] coverage: 100%

    +

    << PASSED>>

    +
    +
    Diagnostics
    +
    +[INFO] TOTAL COVERAGE: 100%
    + +

    [INFO] Processors Available: 1
    +[INFO] Total Memory: 4764Kb
    +[INFO] Free Memory: 3758Kb
    +[INFO] Used Memory: 1006Kb
    +[INFO] Max Available Memory: 4628Kb

    +

    Simulation started at: Sun Feb 16 11:26:27 PST 2003
    +Simulation ended at: Sun Feb 16 11:33:57 PST 2003

    +
    +Fulcrum Microsystems.© copyright 2003. All Rights +Reserved. +
    +

    PRS for MODIFY_VALID

    +
    +  prs {
    +    /* Generated on Feb 16, 2003 11:34 AM by ppelleti with PReSto of 02/09/03.
    +     * If you manually edit this PRS block, please add a comment here
    +     * saying what you changed-- otherwise, we will assume the PRS block
    +     * can be regenerated by running PReSto again. */
    +    node _LA012,_LA345,_LVv,lv,RA012,RA345,RVv,_RAv,_x0,rv,__le,_le,le,en;
    +    node _en;
    +    _1of6 _RA;
    +    _1of2 _RV;
    +    
    +    /*** input ***/
    +    LA.0 | LA.1 | LA.2 => _LA012-
    +    LA.3 | LA.4 | LA.5 => _LA345-
    +    LV.0 | LV.1 => _LVv-
    +    (~_LA012 | ~_LA345) & ~_LVv #> lv+
    +    
    +    /*** logic ***/
    +    en & RA.e & ((LA.0 & LV.0) | (LA.4 & LV.0)) -> _RA.0-
    +    en & RA.e & ((LA.1 & LV.1) | (LA.5 & LV.1)) -> _RA.1-
    +    en & RA.e & (LA.2 | (LA.5 & LV.0) | (LA.4 & LV.1)) -> _RA.2-
    +    en & RA.e & LA.3 -> _RA.3-
    +    en & RA.e & LA.0 & LV.1 -> _RA.4-
    +    en & RA.e & LA.1 & LV.0 -> _RA.5-
    +        <i:6: ~en & ~RA.e -> _RA.d[i]+ >
    +    
    +    en & RV.e & (LA.1 | LA.5 | (LA.2 & LV.0) | (LA.3 & LV.0)) -> _RV.0-
    +    en & RV.e & (LA.0 | LA.4 | (LA.2 & LV.1) | (LA.3 & LV.1)) -> _RV.1-
    +        <i:2: ~en & ~RV.e -> _RV.d[i]+ >
    +    
    +    /*** output ***/
    +    <i:6: ~_RA.d[i] => RA.d[i]+ >
    +    <i:2: ~_RV.d[i] => RV.d[i]+ >
    +    
    +    ~_RA.0 | ~_RA.1 | ~_RA.2 => RA012+
    +    ~_RA.3 | ~_RA.4 | ~_RA.5 => RA345+
    +    ~_RV.0 | ~_RV.1 => RVv+
    +    RA012 | RA345 => _RAv-
    +    RVv => _x0-
    +    ~_RAv & ~_x0 #> rv+
    +    
    +    /*** ack ***/
    +    rv & lv #> __le-
    +    _Reset & __le => _le-
    +    _le => le-
    +    le=LA.e=LV.e;
    +    
    +    /*** enable ***/
    +    ~le => _en+
    +    _en => en-
    +  }
    +
    +
    +

    Simulation Results for MODIFY_VALID

    +
    +standard.null.NULL
    +        |
    +        +--standard.base.CELL
    +                |
    +                +--standard.base.LEAF
    +                        |
    +                        +--test.MODIFY_VALID
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cell Summary
    portLA: in standard.channel.e1of6
    portLV: in standard.channel.e1of2
    portRA: out standard.channel.e1of6
    portRV: out standard.channel.e1of2
    portVdd: in node of width 1
    portGND: in node of width 1
    port_RESET: in node of width 1
    #Rules66
    Dsim +Seed1045424044479
    +
    +
    Unimplemented Cells:
    +
    None.
    +
    +
    simulating with digital +environment
    +

    [INFO] Performing reset stress test...
    +[INFO] Running 10 test(s) for 1000 cycle(s) on __rte_.RA.e
    +[PASS] No interference, glitch, or instability detected.
    +
    +[INFO] Measuring NTPC on specified nodes
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] __rte_.RA.e: 17.981096t (17[0.17880072%] 18[99.71%] +19[0.111200444%])
    +
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] cycling on __rte_.RA.e:0for 500000 transitions
    +[PASS] No interference, glitch, or instability detected.
    +[PASS] No data conflicts detected
    +[INFO] coverage: 100%

    +

    << PASSED>>

    +
    +
    Diagnostics
    +
    +[INFO] TOTAL COVERAGE: 100%
    + +

    [INFO] Processors Available: 1
    +[INFO] Total Memory: 4720Kb
    +[INFO] Free Memory: 3722Kb
    +[INFO] Used Memory: 998Kb
    +[INFO] Max Available Memory: 4592Kb

    +

    Simulation started at: Sun Feb 16 11:34:04 PST 2003
    +Simulation ended at: Sun Feb 16 11:39:40 PST 2003

    +
    +Fulcrum Microsystems.© copyright 2003. All Rights +Reserved. +
    +

    PRS for ADP_IN_CTRL1

    +
    +  prs {
    +    /* Generated on Feb 16, 2003 11:39 AM by ppelleti with PReSto of 02/09/03.
    +     * If you manually edit this PRS block, please add a comment here
    +     * saying what you changed-- otherwise, we will assume the PRS block
    +     * can be regenerated by running PReSto again. */
    +    node _L01,_L23,Lv,Gv,Bv,Rv,_x0,_x1,rv,__le,_le,le,en,_en;
    +    _1of2 _R;
    +    _1of3 _G;
    +    _1of3 _B;
    +    
    +    /*** input ***/
    +    L.0 | L.1 => _L01-
    +    L.2 | L.3 => _L23-
    +    ~_L01 | ~_L23 => Lv+
    +    
    +    /*** logic ***/
    +    en & R.e & (L.0 | L.1) -> _R.0-
    +    en & R.e & (L.2 | L.3) -> _R.1-
    +        <i:2: ~en & ~R.e -> _R.d[i]+ >
    +    
    +    en & G.e & L.0 -> _G.0-
    +    en & G.e & (L.2 | L.3) -> _G.1-
    +    en & G.e & L.1 -> _G.2-
    +        <i:3: ~en & ~G.e -> _G.d[i]+ >
    +    
    +    en & B.e & L.1 -> _B.0-
    +    en & B.e & (L.2 | L.3) -> _B.1-
    +    en & L.0 -> _B.2-
    +        <i:2: ~en & ~B.e -> _B.d[i]+ >
    +        ~en -> _B.d[2]+
    +    
    +    /*** output ***/
    +    <i:2: ~_R.d[i] => R.d[i]+ >
    +    <i:3: ~_G.d[i] => G.d[i]+ >
    +    <i:2: ~_B.d[i] => B.d[i]+ >
    +    
    +    ~_G.0 | ~_G.1 | ~_G.2 => Gv+
    +    ~_B.0 | ~_B.1 | ~_B.2 => Bv+
    +    ~_R.0 | ~_R.1 => Rv+
    +    Gv & Bv #> _x0-
    +    Rv => _x1-
    +    ~_x0 & ~_x1 #> rv+
    +    
    +    /*** ack ***/
    +    rv & Lv #> __le-
    +    _Reset & __le => _le-
    +    _le => le-
    +    le=L.e;
    +    
    +    /*** enable ***/
    +    ~le => _en+
    +    _en => en-
    +  }
    +
    +
    +

    Simulation Results for ADP_IN_CTRL1

    +
    +standard.null.NULL
    +        |
    +        +--standard.base.CELL
    +                |
    +                +--standard.base.LEAF
    +                        |
    +                        +--test.ADP_IN_CTRL1
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cell Summary
    portL: in standard.channel.e1of4
    portR: out standard.channel.e1of2
    portG: out standard.channel.e1of3
    portB: out standard.channel.e1of2
    portVdd: in node of width 1
    portGND: in node of width 1
    port_RESET: in node of width 1
    #Rules62
    Dsim +Seed1045424387206
    +
    +
    Unimplemented Cells:
    +
    None.
    +
    +
    simulating with digital +environment
    +

    [INFO] Performing reset stress test...
    +[INFO] Running 10 test(s) for 1000 cycle(s) on __rte_.R.e
    +[PASS] No interference, glitch, or instability detected.
    +
    +[INFO] Measuring NTPC on specified nodes
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] __rte_.R.e: 17.99921t (17[0.10720043%] 18[99.752%] +19[0.14080057%])
    +
    +[INFO] DSim Random on.
    +[INFO] Done with Reset
    +[INFO] cycling on __rte_.R.e:0for 500000 transitions
    +[PASS] No interference, glitch, or instability detected.
    +[PASS] No data conflicts detected
    +[INFO] coverage: 100%

    +

    << PASSED>>

    +
    +
    Diagnostics
    +
    +[INFO] TOTAL COVERAGE: 100%
    + +

    [INFO] Processors Available: 1
    +[INFO] Total Memory: 4456Kb
    +[INFO] Free Memory: 3545Kb
    +[INFO] Used Memory: 911Kb
    +[INFO] Max Available Memory: 4456Kb

    +

    Simulation started at: Sun Feb 16 11:39:47 PST 2003
    +Simulation ended at: Sun Feb 16 11:44:25 PST 2003

    +
    +Fulcrum Microsystems.© copyright 2003. All Rights +Reserved. + + diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelName.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelName.java new file mode 100644 index 0000000000..93beee5e36 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelName.java @@ -0,0 +1,29 @@ +/* + * Copyright 2003-2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +public interface ChannelName { + /** Returns the type of the channel. (For example, returns 2 + * for an e1of2.) */ + int get1of(); + + /** Returns the base name of the channel. This is just + * alphanumeric (plus underscores.) */ + String getName(); + + /** Returns the array index of the channel. If the channel + * is a scalar channel, the returned array is of length zero. + * If the channel is a one-dimensional array, the returned + * array is of length 1, with the one element being the array + * index. For multi-dimensional channels, the returned array + * has one element for each dimension, specifying the index + * for that dimension, reading left-to-right. */ + int[] getArrayIndices(); + + /** Returns the base name of the channel, followed by a comma-separated + * list of array indices in square brackets, if any. */ + String getNameWithIndices(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelNameImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelNameImpl.java new file mode 100644 index 0000000000..6b978ac0f9 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/ChannelNameImpl.java @@ -0,0 +1,74 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +import com.avlsi.util.text.StringUtil; + +public class ChannelNameImpl implements ChannelName { + private final int numRails; + private final String name; + private final int[] arrayIndices; + + public int get1of() { + return numRails; + } + + public String getName() { + return name; + } + + public int[] getArrayIndices() { + return arrayIndices; + } + + public ChannelNameImpl(String parseMe) { + String[] parts = StringUtil.split(parseMe, ':'); + if (parts.length != 2) + throw new IllegalArgumentException((parts.length-1) + + " colons in " + parseMe); + numRails = Integer.parseInt(parts[1]); + int idx = parts[0].indexOf('['); + if (idx < 0) { + name = parts[0]; + arrayIndices = new int[0]; + } else { + name = parts[0].substring(0, idx); + String[] indices = + StringUtil.split(parts[0].substring(idx + 1, + parts[0].length() - 1), + ','); + arrayIndices = new int[indices.length]; + for (int i = 0; i < indices.length; i++) + arrayIndices[i] = Integer.parseInt(indices[i]); + } + } + + public String toString(boolean wantRails) { + StringBuffer buf = new StringBuffer(name); + if (arrayIndices.length != 0) { + buf.append('['); + for (int i = 0; i < arrayIndices.length; i++) { + if (i > 0) + buf.append(','); + buf.append(Integer.toString(arrayIndices[i])); + } + buf.append(']'); + } + if (wantRails) { + buf.append(':'); + buf.append(Integer.toString(numRails)); + } + return buf.toString(); + } + + public String toString() { + return toString(true); + } + + public String getNameWithIndices() { + return toString(false); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/LogicFileReader.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/LogicFileReader.java new file mode 100644 index 0000000000..cd18221129 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/LogicFileReader.java @@ -0,0 +1,173 @@ +/* + * Copyright 2003-2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +import java.math.BigInteger; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import com.avlsi.util.text.StringUtil; + +public class LogicFileReader { + private static final String SEP = "=>"; + private static final BigInteger MAX_INT = + new BigInteger(Integer.toString(Integer.MAX_VALUE)); + + public static class TruthTableFormatException extends IOException { + TruthTableFormatException(String msg) { + super(msg); + } + } + + private static class LineParser { + private int lineSize = -1; + private int sepPos = -1; + private final LineNumberReader lnr; + private String[] lastLine; + + LineParser(Reader r) throws IOException { + lnr = new LineNumberReader(r); + } + + boolean parseLine() throws IOException { + String s = lnr.readLine(); + if (s == null) + return false; + lastLine = StringUtil.split(s.trim(), ' '); + if (lineSize == -1) { + lineSize = lastLine.length; + } else if (lineSize != lastLine.length) { + bad("line has too " + + (lastLine.length < lineSize ? "few" : "many") + + " items"); + } + int pos = -1; + for (int i = 0; i < lastLine.length; i++) + if (lastLine[i].equals(SEP)) { + if (pos == -1) + pos = i; + else + bad("more than one " + SEP + " encountered"); + } + if (pos == -1) + bad("no " + SEP + " encountered"); + if (sepPos == -1) + sepPos = pos; + else if (sepPos != pos) + bad(SEP + " in the wrong place"); + return true; + } + + String[] getInputs() { + String[] result = new String[sepPos]; + System.arraycopy(lastLine, 0, result, 0, sepPos); + return result; + } + + String[] getOutputs() { + String[] result = new String[lineSize - (sepPos + 1)]; + System.arraycopy(lastLine, sepPos + 1, result, 0, result.length); + return result; + } + + void bad(String msg) throws TruthTableFormatException { + throw new TruthTableFormatException("line " + lnr.getLineNumber() + + ": " + msg); + } + } + + public static TruthTable[] readLogicFile(Reader r) throws IOException { + LineParser lp = new LineParser(r); + if (!lp.parseLine()) + throw new TruthTableFormatException("Empty file!"); + String[] inStrs = lp.getInputs(); + String[] outStrs = lp.getOutputs(); + + if (inStrs.length == 0) + throw new TruthTableFormatException("no inputs!"); + + if (outStrs.length == 0) + throw new TruthTableFormatException("no outputs!"); + + BigInteger bigTableSize = BigInteger.ONE; + ChannelName[] ins = new ChannelName[inStrs.length]; + for (int i = 0; i < ins.length; i++) { + ins[i] = new ChannelNameImpl(inStrs[i]); + int of = ins[i].get1of(); + assert (of > 0) : inStrs[i]; + BigInteger bigOf = new BigInteger(Integer.toString(of)); + bigTableSize = bigTableSize.multiply(bigOf); + } + + if (bigTableSize.compareTo(MAX_INT) > 0) { + System.err.println("Error: The truth table for your cell " + + "would require " + bigTableSize); + System.err.println("entries. That's more than the amount of " + + "memory in a 32-bit computer."); + System.err.println("I'm not even going to try to do that. " + + "Tough luck for you."); + System.exit(32); + } + + int tableSize = bigTableSize.intValue(); + + ChannelName[] outs = new ChannelName[outStrs.length]; + for (int i = 0; i < outs.length; i++) + outs[i] = new ChannelNameImpl(outStrs[i]); + + byte[][] table = new byte[outs.length][tableSize]; + boolean[][] ack = new boolean[ins.length][tableSize]; + + if (outs.length * tableSize > 10000) { + System.err.println("Warning: " + outs.length + + " truth tables with " + tableSize + + " entries per table."); + System.err.println("This could take a long time, or even " + + "fail due to lack of space."); + } + + boolean[] acks = new boolean[inStrs.length]; + + assert (acks.length == ins.length); + assert (tableSize > 0); + + while (lp.parseLine()) { + inStrs = lp.getInputs(); + outStrs = lp.getOutputs(); + + int pos = 0; + + for (int i = 0; i < inStrs.length; i++) { + String s = inStrs[inStrs.length - (i+1)]; + if (s.endsWith("n")) { + acks[inStrs.length - (i+1)] = false; + s = s.substring(0, s.length() - 1); + } else { + acks[inStrs.length - (i+1)] = true; + } + int x = Integer.parseInt(s); + pos *= ins[inStrs.length - (i+1)].get1of(); + pos += x; + } + + for (int i = 0; i < acks.length; i++) + ack[i][pos] = acks[i]; + + for (int i = 0; i < outStrs.length; i++) { + int x = -1; + if (!outStrs[i].equals("-")) + x = Integer.parseInt(outStrs[i]); + table[i][pos] = (byte) x; + } + } + + TruthTable[] result = new TruthTable[outs.length]; + for (int i = 0; i < outs.length; i++) + result[i] = new TruthTableImpl(ins, outs[i], table[i], ack); + + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/PReSto.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/PReSto.java new file mode 100644 index 0000000000..822814a85e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/PReSto.java @@ -0,0 +1,160 @@ +/* + * Copyright 2003-2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +import java.io.ByteArrayOutputStream; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import java.util.Collections; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.io.CopyingOutputStream; +import com.avlsi.csp.csp2tt.Csp2TT; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.LinkedList; +import java.util.LinkedHashSet; +import com.avlsi.io.OutputPumper; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import com.avlsi.util.text.StringUtil; +import com.avlsi.util.debug.VersionInfo; + +public class PReSto { + private static void usage(int exitStatus) { + System.err.println("Usage:"); + System.err.println("presto --cast-path=/your/cast/path --cell=some.cell.NAME [--go=channel,...]"); + System.exit(exitStatus); + } + + private Process proc; + private OutputPumper pump; + private ByteArrayOutputStream output; + + private InputStream csp2tt(String cast_path, String cell, + String package_root) throws IOException { + Runtime r = Runtime.getRuntime(); + long totalMemory = r.totalMemory(); + long maxMemory = r.maxMemory(); + String java_home = System.getProperty("java.home"); + String class_path = System.getProperty("java.class.path"); + char sep = File.separatorChar; + LinkedList cmd = new LinkedList(); + cmd.add(java_home + sep + "bin" + sep + "java"); + cmd.add("-cp"); + cmd.add(class_path); + cmd.add("-Xms" + totalMemory); + cmd.add("-Xmx" + maxMemory); + cmd.add(Csp2TT.class.getName()); + if (package_root != null) + cmd.add("--package-root=" + package_root); + cmd.add("--cast-path=" + cast_path); + cmd.add("--cell=" + cell); + proc = r.exec((String[])cmd.toArray(new String[0])); + proc.getOutputStream().close(); + output = new ByteArrayOutputStream(); + OutputStream[] streams = new OutputStream[] { System.err, output }; + pump = new OutputPumper(proc.getErrorStream(), + new CopyingOutputStream(streams)); + pump.start(); + return proc.getInputStream(); + } + + private static void addWarnings(WarningAccumulator wacc, String s) { + String[] strs = StringUtil.split(s, '\n'); + final String warn = "warning:"; + for (int i = 0; i < strs.length; i++) { + try { + String ss = strs[i].substring(0, warn.length()); + if (ss.equalsIgnoreCase(warn)) + wacc.add(strs[i]); + } catch (IndexOutOfBoundsException e) { + // do nothing, but continue with the loop + } + } + } + + public static void main(String[] args) throws IOException, + InterruptedException { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles(parsedArgs); + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs(argsWithConfigs); + final CommandLineArgs theArgs = cachedArgs; + + String version = VersionInfo.getVersionString(PReSto.class); + + if (theArgs.argExists("version")) { + System.out.println(version); + } + + final String castPath = theArgs.getArgValue("cast-path", "."); + final String castCellName = theArgs.getArgValue("cell", null); + final String packageRoot = theArgs.getArgValue("package-root", null); + final String goArg = theArgs.getArgValue("go", null); + boolean goAll = (goArg == null && theArgs.argExists("go")); + + if (castCellName == null || + theArgs.nonParsedArgumentsIterator().hasNext()) + usage(1); + + PReSto pr = new PReSto(); + InputStream in = pr.csp2tt(castPath, castCellName, packageRoot); + + LinkedHashSet go = new LinkedHashSet(); + if (goArg != null) { + String[] goSplit = StringUtil.split(goArg, ','); + for (int i = 0; i < goSplit.length; i++) + go.add(goSplit[i]); + } + + TruthTable[] tt = null; + try { + tt = LogicFileReader.readLogicFile(new InputStreamReader(in)); + } catch (LogicFileReader.TruthTableFormatException e) { + int exitCode = pr.proc.waitFor(); + pr.pump.join(); + if (exitCode == 0 || pr.output.size() == 0) { + /* If process exited normally or didn't write to stderr, + * print an error message. Otherwise, assume it printed + * a meaningful error message and we don't need to. */ + System.err.println("Internal PReSto error: bad truth table: " + + e.getMessage()); + if (exitCode == 0) + exitCode = 100; + } + System.exit(exitCode); + } + + int exitCode = pr.proc.waitFor(); + pr.pump.join(); + if (exitCode != 0) { + if (pr.output.size() == 0) { + System.err.println("Internal PReSto error: truth table " + + "generation failed"); + } + System.exit(exitCode); + } + + + if (goAll) + for (int i = 0; i < tt.length; i++) + go.add(tt[i].getOutput().getNameWithIndices()); + + pr.pump.join(); + String tterr = pr.output.toString(); + WarningAccumulator wacc = new WarningAccumulator(); + addWarnings(wacc, tterr); + + PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out)); + Presto2.presto(w, tt, go, version, wacc); + w.flush(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/Presto2.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/Presto2.java new file mode 100644 index 0000000000..1a53727bb3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/Presto2.java @@ -0,0 +1,127 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +import java.util.Arrays; +import com.avlsi.util.container.CollectionUtils; +import java.util.Date; +import java.text.DateFormat; +import com.avlsi.tools.presto.template.DeclarationsImpl; +import java.util.LinkedList; +import com.avlsi.util.container.MappingIterator; +import com.avlsi.tools.presto.output.Organizer; +import com.avlsi.tools.presto.output.Power; +import java.io.PrintWriter; +import java.io.StringWriter; +import com.avlsi.tools.presto.output.PrsPrinter; +import com.avlsi.tools.presto.template.SectionFactory; +import java.util.Set; +import com.avlsi.util.text.StringUtil; +import com.avlsi.tools.presto.template.Template; +import com.avlsi.util.functions.UnaryFunction; + +public class Presto2 { + public static void mkEnv(PrintWriter w, int indent, + ChannelName[] inputs, ChannelName[] outputs) { + String i = StringUtil.repeatString(" ", indent); + + for (int j = 0; j < inputs.length; j++) + w.println(i + "rsource_e1of" + inputs[j].get1of() + " _(" + + inputs[j].getNameWithIndices() + ");"); + + for (int j = 0; j < outputs.length; j++) + w.println(i + "bitbucket_e1of" + outputs[j].get1of() + " _(" + + outputs[j].getNameWithIndices() + ");"); + } + + /** + * Synthesizes a leaf cell for a given set of truth tables. + * @param w where to send the output + * @param tt truth tables + * @param go a Set of Strings, names of output channel which should + * use a go signal + * @param version the build identifier of the package + */ + public static void presto(PrintWriter w, TruthTable[] tt, Set go, + String version, WarningAccumulator wacc) { + String user = System.getProperty("user.name"); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + ChannelName[] inputs = tt[0].getInputs(); + for (int i=0; i < inputs.length; i++) + if (inputs[i].getName().equals("tie") || + inputs[i].getName().equals("tiehi") || + inputs[i].getName().equals("tielo")) { + System.err.println("Error: Port names tie/tiehi/tielo not compatible with PReSto"); + System.exit(32); + } + for (int i=0; i < tt.length; i++) + if (tt[i].getOutput().getName().equals("tie") || + tt[i].getOutput().getName().equals("tiehi") || + tt[i].getOutput().getName().equals("tielo")) { + System.err.println("Error: Port names tie/tiehi/tielo not compatible with PReSto"); + System.exit(32); + } + + w.println(" prs {"); + String date = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, + DateFormat.SHORT).format(new Date()); + w.println(" /* Generated on " + date + " by " + + user + " with " + "PReSto."); + w.println(" * " + version); + if (go.size() > 0) + w.println(" * Options: --go=" + + StringUtil.join((String[]) + go.toArray(new String[0]), ',')); + DeclarationsImpl decl = new DeclarationsImpl(); + Organizer org = new Organizer(); + StringBuffer cycle_node = new StringBuffer(); + int ntpc = Template.doTemplate(tt, org, decl, go, cycle_node, wacc); + wacc.print(" * ", w); + w.println(" * If you manually edit this PRS block, " + + "please add a comment here"); + w.println(" * saying what you changed-- otherwise, " + + "we will assume the PRS block"); + w.println(" * can be regenerated by running PReSto again. */"); + decl.emit(pw, 4, 78); + PrsPrinter prs = new PrsPrinter(); + org.simplify(prs); + prs.emit(pw, 4, 4, 50, SectionFactory.mkAncestorSection()); + if (Power.getIsCalled()) { + w.println(" node tiehi, tielo;"); + w.println(" lib.util.tie.LOCAL_TIE tie;"); + } + + w.println(sw.toString()); + w.println(" }"); + w.println(); + w.println(" directives {"); + w.println(" owner = " + user + ';'); + if (wacc.hasWarnings()) + w.println(" " + user + "_must_fix_warnings = true; " + + "// bogus directive; delete when fixed"); + w.println(" }"); + w.println(); + w.println(" env {"); + w.println(" digital {"); + w.println(" subcells {"); + mkEnv(w, 8, tt[0].getInputs(), (ChannelName[]) CollectionUtils + .addAll(new LinkedList(), + new MappingIterator(Arrays.asList(tt).iterator(), + new UnaryFunction() { + public Object execute(Object a) { + return ((TruthTable)a) + .getOutput(); + } + })).toArray(new ChannelName[0])); + w.println(" }"); + w.println(" directives {"); + w.println(" ntpc_spec(" + cycle_node + ") = " + ntpc + ";"); + w.println(" }"); + w.println(" }"); + w.println(" }"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTable.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTable.java new file mode 100644 index 0000000000..74db5811bf --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTable.java @@ -0,0 +1,31 @@ +/* + * Copyright 2003-2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +public interface TruthTable { + /** Returns an array of inputs which this output depends on. */ + ChannelName[] getInputs(); + + /** Returns the name of this output. */ + ChannelName getOutput(); + + /** An array of output values. The size of the array is + * getInput()[0].get1of() * getInput()[1].get1of() * ... + * The output values are packed into the array, with the + * first input being the least-significant part of the + * array index, and the last input being the most-significant + * part. An output value of -1 means no output. */ + byte[] getTable(); + + /** + * Returns an array of booleans (where the indices have the same + * meaning as in the array returned by getTable()) which indicates + * whether the input is acknowledged. + * @param input which input you want to know about (same as indices + * into the array returned by getInput()) + */ + boolean[] getInputAcknowledge(int input); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTableImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTableImpl.java new file mode 100644 index 0000000000..7e30e3debd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/TruthTableImpl.java @@ -0,0 +1,100 @@ +/* + * Copyright 2003-2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +import java.util.zip.CRC32; + +public class TruthTableImpl implements TruthTable { + private final ChannelName[] inputs; + private final ChannelName output; + private final byte[] table; + private final boolean[][] ack; + private CRC32 hc = null; + + public ChannelName[] getInputs() { + return inputs; + } + + public ChannelName getOutput() { + return output; + } + + public byte[] getTable() { + return table; + } + + public boolean[] getInputAcknowledge(int input) { + return ack[input]; + } + + public TruthTableImpl(ChannelName[] inputs, ChannelName output, + byte[] table, boolean[][] ack) { + this.inputs = inputs; + this.output = output; + this.table = table; + this.ack = ack; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < inputs.length; i++) { + buf.append(inputs[i].toString()); + buf.append(' '); + } + buf.append("=> "); + buf.append(output.toString()); + buf.append('\n'); + + int[] weights = new int[inputs.length]; + int weight = 1; + + for (int i = 0; i < inputs.length; i++) { + weights[i] = weight; + weight *= inputs[i].get1of(); + } + + for (int i = 0; i < table.length; i++) { + for (int j = 0; j < inputs.length; j++) { + int val = (i / weights[j]) % inputs[j].get1of(); + buf.append(Integer.toString(val)); + if (!ack[j][i]) + buf.append('n'); + buf.append(' '); + } + buf.append("=> "); + if (table[i] == -1) + buf.append('-'); + else + buf.append(Integer.toString(table[i])); + buf.append('\n'); + } + + return buf.toString(); + } + + /** + * Note: hashCode() and equals() only look at table; they don't + * look at ack or the ChannelNames. + */ + public int hashCode() { + if (hc == null) { + hc = new CRC32(); + hc.update(table); + } + return (int) hc.getValue(); + } + + public boolean equals(Object o) { + boolean eq = (o instanceof TruthTableImpl); + if (eq) { + TruthTableImpl that = (TruthTableImpl) o; + eq = (table.length == that.table.length); + for (int i = 0; eq && i < table.length; i++) + eq = (table[i] == that.table[i]); + } + return eq; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/WarningAccumulator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/WarningAccumulator.java new file mode 100644 index 0000000000..1b10e560bc --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/WarningAccumulator.java @@ -0,0 +1,99 @@ +/* + * Copyright 2005 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.io.PrintWriter; + +/** + * Accumulates warnings so that we can stick them into the comment block. + */ +public class WarningAccumulator { + private final List warnings = new LinkedList(); + + private static final long[] data = new long[] { + 1413542412121038151L, 2131212103443141415L, 1412132415132214131L, + 1121412141212121033L, 1210191212111415121L, 1121415111213526212L, + 1312141212121032121L, 1703314122314152313L, 1415141214121413212L, + 7777777777770344314L + }; + + private static void warning(Collection dest) { + StringBuffer b = new StringBuffer(); + char c = '#'; + for (int i = 0; i < data.length; i++) { + long n = data[i]; + for (int j = 0; j < 19; j++) { + int x = (int)(n % 10); + n = n / 10; + switch (x) { + case 0: + dest.add(b.toString()); + b.setLength(0); + c = '#'; + break; + case 7: + c = ' '; + break; + case 8: + x = 51; + default: + for (int k = 0; k < x; k++) + b.append(c); + c ^= 3; + } + } + } + } + + /** + * Adds a warning to the WarningAccumulator. + */ + public void add(String w) { + warnings.add(w); + } + + /** + * Convenience method that prints the warning to stderr and adds + * it to the WarningAccumulator. + */ + public void warn(String w) { + System.err.println(w); + add(w); + } + + /** + * Prints accumulated warnings, if any, to w. Starts each + * line with prefix. + */ + public void print(String prefix, PrintWriter w) { + if (warnings.size() > 0) { + List output = new LinkedList(); + output.add(""); + warning(output); + output.add(""); + output.addAll(warnings); + output.add(""); + + for (Iterator it = output.iterator(); it.hasNext(); ) { + String s = (String) it.next(); + w.print(prefix); + w.println(s); + } + } + } + + /** + * Returns true iff the WarningAccumulator contains at least + * one warning. + */ + public boolean hasWarnings() { + return warnings.size() > 0; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Emitter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Emitter.java new file mode 100644 index 0000000000..69be7b0c0f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Emitter.java @@ -0,0 +1,11 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.complete; + +public interface Emitter { + // void declare (Name name); + void emit(String str, Object cookie); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/GreedyComplete.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/GreedyComplete.java new file mode 100644 index 0000000000..867536b9f0 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/GreedyComplete.java @@ -0,0 +1,268 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.complete; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/* + What's the point of this file: + + GreedyComplete constructs a completion tree which is as greedy as + possible, i. e. it may make excessive use of and2c2s, and end up + with extra inverters at the end, much like the original PReSto + algorithm did. The idea is to use GreedyComplete to create an + initial completion tree, and then use TreeReadjuster to make the + tree less greedy. (So, the resulting tree will have the same number + of levels as the greedy tree, but it will try to use fewer aggressive + operators.) + + To use: + + Just call the complete() method, which is the only public interface. + */ + +public class GreedyComplete { + /** + * Takes a List of Node[] arrays which each have one or + * two elements. Returns a List with the same Node[] arrays + * in a different order, according to the following two rules: + * 1) arrays with one element and arrays with two elements will + * be interleaved as much as possible + * 2) the last array in the List will be an array with two + * elements, if any exist + * The first constraint causes the completion generator to + * prefer and2c2 over 2and2c2. The second constraint ensures + * that if there's an odd number of Node[] arrays, the one + * that doesn't get into a C-element will be a nand2, rather + * than just an inverter, if there are any two-element arrays. + * (This reduces the number of and2c2s by one.) + */ + private static List alternateOnesAndTwos(List orig) { + /* First, build up two lists, one with one-element arrays + * and one with two-element arrays. Note that we build + * the lists in reverse order, which will be important + * in the next step. */ + LinkedList ones = new LinkedList(); + LinkedList twos = new LinkedList(); + + for (Iterator it = orig.iterator(); it.hasNext(); ) { + Node[] a = (Node[]) it.next(); + switch (a.length) { + case 1: + ones.addFirst(a); + break; + case 2: + twos.addFirst(a); + break; + default: + assert false; + } + } + + /* Next, build up the result list, alternating as much as + * possible. Note that we again build it in reverse + * order, which undoes the reversal we did in the first + * step. This double-reversal is done for more than + * the sake of perversity-- it is how we satisfy + * constraint #2, by starting with a 2-element array. + */ + LinkedList result = new LinkedList(); + Iterator it1, it2; + + for (it1 = ones.iterator(), it2 = twos.iterator(); + it1.hasNext() || it2.hasNext(); ) { + if (it2.hasNext()) + result.addFirst(it2.next()); + if (it1.hasNext()) + result.addFirst(it1.next()); + } + + return result; + } + + /** + * Creates a Node which C-elements together x and y. + * x and y must be one or two element arrays, and + * it chooses c2, and2c2, or 2and2c2 appropriately. + */ + private static Node makeCelement(Node[] x, Node[] y) { + if (y.length == 2 && x.length == 1) { + // flip around to satisfy Node's requirement for and2c2 order + Node[] tmp = x; + x = y; + y = tmp; + } + + Node[] children = new Node[x.length + y.length]; + System.arraycopy(x, 0, children, 0, x.length); + System.arraycopy(y, 0, children, x.length, y.length); + + return new Node(Node.CELEMENT, null, null, x[0].getTier() + 1, + null, children); + } + + /** + * Given the number of rails to be ored together, and the maximum + * number of rails which can be ored together in one group, + * partitions the rails into groups which are as balanced as + * possible. + * @param maxterms maximum size of a group + * @param numRails total number of rails to partition + * @return an array with one element for each group, containing + * the number of rails which should be in that group. + */ + private static int[] calculateBalancedGroups(int maxterms, int numRails) { + /* Implementation note: this uses a very convoluted algorithm + * to compute a very simple result, but it makes sense to me. + * If it bothers you, replace it with a simpler algorithm. */ + + int q = numRails / maxterms; + int r = numRails % maxterms; + int[] result = new int[q + Math.min(1, r)]; + Arrays.fill(result, maxterms); + if (r != 0) + result[q] = r; + + if (result.length > 1) { + boolean changed; + + do { + changed = false; + int i; + int max = -1; + for (i = 0; i < result.length - 1; i++) { + if (max < 0 || result[i] > result[max]) + max = i; + } + + if (result[i] < (result[max] - 1)) { + changed = true; + result[max]--; + result[i]++; + } + + } while (changed); + } + + Arrays.sort(result); + return result; + } + + /** + * Given an array of nodes, add a new tier of nodes, oring + * together the original nodes as much as possible. Returns + * the new, smaller array of nodes after the tier has been added. + */ + private static Node[] doOrs(Node[] rails) { + int tier = rails[0].getTier() + 1; + boolean nand = ((tier & 1) == 0); + int maxterms = (nand ? 5 : 3); + int[] groups = calculateBalancedGroups(maxterms, rails.length); + + Node[] result = new Node[groups.length]; + int j = 0; + + /* Group the rails together */ + for (int k = 0; k < rails.length; j++) { + int size = groups[j]; + Node[] children = new Node[size]; + + for (int i = 0; i < size; i++, k++) + children[i] = rails[k]; + + result[j] = new Node(Node.NOR, null, null, tier, null, children); + } + + return result; + } + + /** + * Recursively computes each tier of the tree, by adding one + * tier of nodes to the tree, and then calling itself with the + * new, smaller ops array, until there is only one node, + * which it then returns. + */ + private static Node recurse(Node[][] ops, int tier) { + assert ops.length > 0 : "no ops!"; + if (ops.length == 1 && ops[0].length == 1) + return ops[0][0]; + + boolean and2c2ok = ((tier & 1) == 0); + + List newChannels = new ArrayList(); + List wantToCombine = new ArrayList(); + + for (int i = 0; i < ops.length; i++) { + Node[] rails = ops[i]; + int nrails = rails.length; + + int maxCombinable = (and2c2ok ? 2 : 1); + + if (rails[0].getTier() != tier - 1) { + assert rails[0].getTier() > tier - 1; + newChannels.add(rails); + } else if (nrails > maxCombinable) { + newChannels.add(doOrs(rails)); + } else { + wantToCombine.add(rails); + } + } + + assert wantToCombine.size() > 0 || newChannels.size() > 0: + "wantToCombine.size() = " + wantToCombine.size() + ", " + + "newChannels.size() = " + newChannels.size(); + + if (and2c2ok) + wantToCombine = alternateOnesAndTwos(wantToCombine); + + assert wantToCombine.size() > 0 || newChannels.size() > 0; + + for (Iterator it = wantToCombine.iterator(); it.hasNext(); ) { + Node[] rails1 = (Node[]) it.next(); + if (!it.hasNext()) { + // an odd number, so this one can't go through + // a C-element + newChannels.add(doOrs(rails1)); + break; + } + + Node[] rails2 = (Node[]) it.next(); + newChannels.add(new Node[] { makeCelement(rails1, rails2) }); + } + + assert newChannels.size() > 0; + + return recurse((Node[][]) + newChannels.toArray(ZERO_LENGTH_NODE_ARRAY_ARRAY), + tier + 1); + } + + /** + * Returns a tree of Nodes which make up the desired completion tree. + * @param ops an array of arrays of nodes, where the outer array + * represents the c-element tree, and the inner arrays + * represent ors. Each inner array must contain nodes + * with the same level, but different inner arrays can have + * nodes at different levels. + * @param desiredSense desired sense of root node-- may be + * ACTIVE_HIGH or ACTIVE_LOW to be specific, + * or UNKNOWN_SENSE to accept either. + */ + public static Node complete(Node[][] ops, int desiredSense) { + Node result = recurse(ops, 0); + // get desired sense + if (desiredSense != Node.UNKNOWN_SENSE && + desiredSense != result.getSense()) + result = doOrs(new Node[] { result })[0]; + return result; + } + + private static final Node[][] ZERO_LENGTH_NODE_ARRAY_ARRAY = new Node[0][]; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Node.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Node.java new file mode 100644 index 0000000000..0dfccf303d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/Node.java @@ -0,0 +1,129 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.complete; + +import java.util.Collection; + +public class Node { + public static final int ACTIVE_HIGH = 1; + public static final int ACTIVE_LOW = -1; + public static final int UNKNOWN_SENSE = 0; + + public static final int NO_RAIL = -1; + + /** must have 0 children */ + public static final int TERMINAL = 0; + + /** must have 1 or more children (if 1 child, actually an inverter) + * if ACTIVE_HIGH, actually a nand */ + public static final int NOR = 1; + + /** 2 children = C2 + * 3 children = AND2C2 (first two children are anded together) + * 4 children = 2AND2C2 */ + public static final int CELEMENT = 2; + + private final int type; + private final String name; + private final int[] arrayIndices; + private final int rail; + private final int tier; + private final Object cookie; + private final Node[] children; + + /** Returns the type of this node: TERMINAL, NOR, or CELEMENT */ + public int getType() { + return type; + } + + /** Returns the sense of this node: ACTIVE_HIGH or ACTIVE_LOW. */ + public int getSense() { + return ((tier & 1) == 0) ? ACTIVE_HIGH : ACTIVE_LOW; + } + + /** Returns the base name of the channel. This is just + * alphanumeric (plus underscores.) "null" indicates an + * anonymous node, which are legal in some places but not + * in others. */ + public String getName() { + return name; + } + + /** Returns the array index of the channel. If the channel + * is a scalar channel, the returned array is of length zero. + * If the channel is a one-dimensional array, the returned + * array is of length 1, with the one element being the array + * index. For multi-dimensional channels, the returned array + * has one element for each dimension, specifying the index + * for that dimension, reading left-to-right. */ + public int[] getArrayIndices() { + return arrayIndices; + } + + /** If this node is part of a channel, then this is the rail number. + * (The part after the dot.) If this node is not part of a channel, + * returns NO_RAIL. */ + public int getRail() { + return rail; + } + + /** Returns the tier of this node. (Number of transitions from + * the starting point, where 0 is the starting point.) */ + public int getTier() { + return tier; + } + + /** Returns the cookie of this node. As far the the completion code + * is concerned, cookies are arbitrary and have no meaning. + * The template code uses them to keep track of which section + * (input, output, ack) a production rule goes in. */ + public Object getCookie() { + return cookie; + } + + /** Returns the number of children. */ + public int size() { + return children.length; + } + + /** Returns the specified child node. */ + public Node get(int idx) { + return children[idx]; + } + + private static final Node[] ZERO_LENGTH_NODE_ARRAY = new Node[0]; + + /* Construct a new terminal Node. */ + public Node(String name, int[] arrayIndices, int rail, int tier, + Object cookie) { + this.type = TERMINAL; + this.name = name; + this.arrayIndices = arrayIndices; + this.rail = rail; + this.tier = tier; + this.cookie = cookie; + this.children = ZERO_LENGTH_NODE_ARRAY; + } + + /* Construct a new nonterminal node from an array. */ + public Node(int type, String name, int[] arrayIndices, int tier, + Object cookie, Node[] children) { + this.type = type; + this.name = name; + this.arrayIndices = arrayIndices; + this.rail = NO_RAIL; + this.tier = tier; + this.cookie = cookie; + this.children = children; + } + + /* Construct a new nonterminal node from a collection. */ + public Node(int type, String name, int[] arrayIndices, int tier, + Object cookie, Collection children) { + this(type, name, arrayIndices, tier, cookie, + (Node[]) children.toArray(ZERO_LENGTH_NODE_ARRAY)); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/NodeBuilder.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/NodeBuilder.java new file mode 100644 index 0000000000..8a3eebaa3c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/NodeBuilder.java @@ -0,0 +1,10 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ +*/ + +package com.avlsi.tools.presto.complete; + +public interface NodeBuilder { + Node buildNode(int type, int tier, Node[] children); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeMunger.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeMunger.java new file mode 100644 index 0000000000..fc5d02d008 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeMunger.java @@ -0,0 +1,20 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ +*/ + +package com.avlsi.tools.presto.complete; + +public class TreeMunger { + public static Node mungeTree(Node root, NodeBuilder builder) { + int type = root.getType(); + if (type == Node.TERMINAL) + return root; + + Node[] children = new Node[root.size()]; + for (int i = 0; i < root.size(); i++) + children[i] = mungeTree(root.get(i), builder); + + return builder.buildNode(type, root.getTier(), children); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeReadjuster.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeReadjuster.java new file mode 100644 index 0000000000..517f4408ab --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/complete/TreeReadjuster.java @@ -0,0 +1,123 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.complete; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class TreeReadjuster { + /** + * Takes the given node, and splits it into two nor nodes, + * and adds these two nodes to dest. If n has an odd number + * of children, then the first new node has one more child + * than the second new node. (This property is important + * when we split and2c2s!) + */ + private static void splitNode(Node n, Collection dest) { + Node[] b = new Node[n.size() / 2]; + Node[] a = new Node[n.size() - b.length]; + for (int i = 0; i < n.size(); i++) + if (i < a.length) + a[i] = n.get(i); + else + b[i - a.length] = n.get(i); + dest.add(new Node(Node.NOR, null, null, n.getTier(), null, a)); + dest.add(new Node(Node.NOR, null, null, n.getTier(), null, b)); + assert a.length >= b.length; + } + + /** + * Takes a completion tree and attempts to reduce its cost + * by sucking operators closer to the root. (I don't formally + * define a cost function, but the basic idea is to try to + * get rid of and2c2s, 2and2c2s, and nor3s by moving portions of + * them "up" into smaller nands or plain inverters.) + */ + public static Node readjust(Node root) { + int type = root.getType(); + int sense = root.getSense(); + + if (type == Node.TERMINAL) + return root; + + int newType; + List newChildren = new ArrayList(); + + if (type == Node.NOR && root.size() == 1) { + /* It's an inverter. Split the child node in half, if possible. */ + Node child = root.get(0); + if (child.getType() == Node.TERMINAL) + return root; // nothing more we can do + if (child.size() == 1) // back-to-back inverters + return readjust(child.get(0)); // delete both inverters + newType = child.getType(); + splitNode(child, newChildren); + } else if (type == Node.NOR && sense == Node.ACTIVE_HIGH) { + /* It's a nand. See if there are nor3s below which could be + * reduced to nor2s, without making the nand too big. */ + List nor3s = new ArrayList(); + for (int i = 0; i < root.size(); i++) { + Node child = root.get(i); + if (child.getType() == Node.NOR && child.size() == 3) + nor3s.add(child); + } + int numNewNor2s = (nor3s.size() / 2) + (nor3s.size() % 2); + Map repl = new IdentityHashMap(); + Map ins = new IdentityHashMap(); + if (numNewNor2s > 0 && numNewNor2s + root.size() < 6) { + /* We're going to convert the nor3s to nor2s, and add + * some new nor2s to the nand. */ + for (Iterator it = nor3s.iterator(); it.hasNext(); ) { + List x = new ArrayList(); + Node n = (Node) it.next(); + x.add(n.get(2)); + repl.put(n, new Node(Node.NOR, null, null, n.getTier(), + null, + new Node[] { n.get(0), n.get(1) })); + if (it.hasNext()) { + Node m = (Node) it.next(); + x.add(m.get(0)); + repl.put(m, new Node(Node.NOR, null, null, m.getTier(), + null, + new Node[] { m.get(1), + m.get(2) })); + } + ins.put(n, new Node(Node.NOR, null, null, n.getTier(), + null, x)); + } + } + /* copy children, replacing nodes listed in repl and inserting + * nodes listed in ins. */ + newType = Node.NOR; + for (int i = 0; i < root.size(); i++) { + Node child = root.get(i); + Node replacement = (Node) repl.get(child); + newChildren.add((replacement == null) ? child : replacement); + Node insertion = (Node) ins.get(child); + if (insertion != null) + newChildren.add(insertion); + } + } else { + // Don't change it; just copy it + newType = type; + for (int i = 0; i < root.size(); i++) { + Node child = root.get(i); + newChildren.add(child); + } + } + + List processedChildren = new ArrayList(); + for (Iterator it = newChildren.iterator(); it.hasNext(); ) + processedChildren.add(readjust((Node)it.next())); + + return new Node(newType, null, null, root.getTier(), null, + processedChildren); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/custom.mk b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/custom.mk new file mode 100644 index 0000000000..7495465125 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/custom.mk @@ -0,0 +1,9 @@ +CURR_RESULT_FILES := $(CURR_RESULT_FILES) $(CURR_TARGET_DIR)/presto.sh $(CURR_TARGET_DIR)/csp2tt.sh + +$(CURR_TARGET_DIR)/presto.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.tools.presto.PReSto/" >$@ + +$(CURR_TARGET_DIR)/csp2tt.sh: \ + $(CURR_PROJECT_DIR)/../../../../../scripts/fulcrum-java.sh.template + cat $< | $(GNUSED) -e "s/\\\$$appname\\\$$/com.avlsi.csp.csp2tt.Csp2TT/" >$@ diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AbstractPrsLine.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AbstractPrsLine.java new file mode 100644 index 0000000000..13670c0116 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AbstractPrsLine.java @@ -0,0 +1,41 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +/** + * This makes it more convenient to implement PrsLine, by + * providing implementations for equals() and hashCode(). + * (These implementations work by calling toStringWithVariable(), + * which the subclass must implement, with Unicode smiley-face + * as the variable. This makes the assumption that you are not + * already using Unicode smiley-face as an array index in your + * production rules, which is hopefully a pretty safe assumption.) + */ + +public abstract class AbstractPrsLine implements PrsLine { + public abstract boolean isParameterized(); + public abstract String toStringWithIndex(int index); + public abstract String toStringWithVariable(String var); + + public boolean isIndented() { + return false; + } + + private static final String FUNNY_CHARACTER = "\u263a"; + + public boolean equals(Object o) { + if (!(o instanceof PrsLine)) + return false; + PrsLine p = (PrsLine) o; + String a = toStringWithVariable(FUNNY_CHARACTER); + String b = p.toStringWithVariable(FUNNY_CHARACTER); + return a.equals(b); + } + + public int hashCode() { + return toStringWithVariable(FUNNY_CHARACTER).hashCode(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AliasNodeExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AliasNodeExpression.java new file mode 100644 index 0000000000..3bd51808b1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/AliasNodeExpression.java @@ -0,0 +1,92 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public class AliasNodeExpression implements NodeExpression { + private final NodeName a; + private final int delta; + + public AliasNodeExpression(NodeName a, int delta) { + this.a = a; + this.delta = delta; + } + + public NodeName getNode() { + return a; + } + + /** + * Returns a string which describes adding delta to something. + * For example, will return "+5" if delta is 5, "-5" if + * delta is -5, and "" (the empty string) if delta is 0. + */ + private String signedDelta() { + if (delta == 0) + return ""; + String result = Integer.toString(delta); + if (result.startsWith("-")) + return result; + else + return "+" + result; + } + + public LineAndSection[] evaluate(final NodeName dest, + Direction preferredDirection, + Section upSection, Section downSection) { + return new LineAndSection[] { new LineAndSection(new AbstractPrsLine() { + public boolean isParameterized() { + return (a.isParameterized() || dest.isParameterized()); + } + + public String toStringWithIndex(int index) { + return (dest.toStringWithIndex(index) + " = " + + a.toStringWithIndex(index+delta) + ";"); + } + + public String toStringWithVariable(String var) { + return (dest.toStringWithVariable(var) + " = " + + a.toStringWithVariable(var+signedDelta()) + ";"); + } + }, (preferredDirection == Direction.UP ? + upSection : downSection)) }; + } + + public NodeExpression unparameterize(int index) { + return new AliasNodeExpression(a.unparameterize(index+delta), 0); + } + + public NodeExpression canonicalize(NodeCanonicalizer c) { + return new AliasNodeExpression(c.canonicalize(a), delta); + } + + public Simplification getSimplification() { + // an alias cannot be simplified + return new Simplification() { + public boolean isSimpler() { + return false; + } + }; + } + + public NodeExpression applySimplification(Simplification simp) { + // an alias cannot be simplified + return this; + } + + public int hashCode() { + return a.hashCode() + (a.isParameterized() ? delta : 0); + } + + public boolean equals(Object o) { + if (o instanceof AliasNodeExpression) { + AliasNodeExpression x = (AliasNodeExpression) o; + return (a.equals(x.a) && + (!a.isParameterized() || delta == x.delta)); + } else { + return false; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/And2C2Expression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/And2C2Expression.java new file mode 100644 index 0000000000..6737d6512f --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/And2C2Expression.java @@ -0,0 +1,90 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public class And2C2Expression extends ShorthandNodeExpression { + public And2C2Expression(NodeName a1, NodeName a2, NodeName b, boolean reset) { + super(new NodeName[] { a1, a2, b }, reset); + } + + protected String operator(int i, Direction preferredDirection) { + switch (i) { + case 0: + return "|"; + case 1: + return "&"; + case 2: + return "#>"; + } + throw new RuntimeException(); + } + + // and2c2 can only be written in the "up" direction + protected Direction overrideDirection(Direction preferredDirection) { + return Direction.UP; + } + + protected boolean parenBefore(int i) { + return (i == 0); + } + + protected boolean parenAfter(int i) { + return (i == 1); + } + + public NodeExpression unparameterize(int index) { + return new And2C2Expression(names[0].unparameterize(index), + names[1].unparameterize(index), + names[2].unparameterize(index), + reset); + } + + public NodeExpression canonicalize(NodeCanonicalizer c) { + return new And2C2Expression(c.canonicalize(names[0]), + c.canonicalize(names[1]), + c.canonicalize(names[2]), + reset); + } + + public NodeExpression applySimplification(Simplification simp) { + SHSimplification shs = (SHSimplification) simp; + boolean hasGND = shs.isGND(0) || shs.isGND(1) || shs.isGND(2); + boolean hasVdd = (shs.isVdd(0) && shs.isVdd(1)) || shs.isVdd(2); + + if (!simp.isSimpler()) + return this; + + if (reset) { + if (hasVdd) + return new NandExpression(new NodeName[] + { new UnparameterizedNodeName("_Reset") }, false); + else if (hasGND) + return new AliasNodeExpression(Power.Vdd, 0); + } + + if (hasGND && !hasVdd) { + return new AliasNodeExpression(Power.Vdd, 0); + } else if (hasVdd && !hasGND) { + return new AliasNodeExpression(Power.GND, 0); + } else if (hasGND && hasVdd) { + throw new RuntimeException("C Element has one input tied to GND " + + "and one input tied to Vdd. " + + "This is bad!"); + } + + NodeName n; + + if (shs.isVdd(0)) { + assert (!shs.isVdd(1)); + n = names[1]; + } else { + assert (shs.isVdd(1)); + n = names[0]; + } + + return new CElementExpression(n, names[2], reset); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ArbitraryNodeExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ArbitraryNodeExpression.java new file mode 100644 index 0000000000..79e23fc541 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ArbitraryNodeExpression.java @@ -0,0 +1,304 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +import java.util.LinkedList; +import java.util.zip.CRC32; + +/** + * This class is for representing an arbitrary collection of + * pull-ups and pull-downs, which cannot be expressed with + * a short-hand operator. + */ + +public class ArbitraryNodeExpression implements NodeExpression { + private final NodeName[][] ups; + private final NodeName[][] downs; + private CRC32 hc = null; + + public ArbitraryNodeExpression(NodeName[][] ups, NodeName[][] downs) { + this.ups = ups; + this.downs = downs; + } + + private static class Line extends AbstractPrsLine { + private final Direction dir; + private final NodeName[] nodes; + private final NodeName dest; + private final Direction preferredDirection; + + Line(Direction dir, NodeName[] nodes, NodeName dest, + Direction preferredDirection) { + this.dir = dir; + this.nodes = nodes; + this.dest = dest; + this.preferredDirection = preferredDirection; + } + + public boolean isParameterized() { + for (int i = 0; i < nodes.length; i++) + if (nodes[i].isParameterized()) + return true; + return dest.isParameterized(); + } + + public String toStringWithIndex(int index) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < nodes.length; i++) { + if (i != 0) + result.append(" & "); + if (dir == Direction.UP) + result.append('~'); + result.append(nodes[i].toStringWithIndex(index)); + } + + result.append(" -> "); + result.append(dest.toStringWithIndex(index)); + result.append(dir.toString()); + return result.toString(); + } + + public String toStringWithVariable(String var) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < nodes.length; i++) { + if (i != 0) + result.append(" & "); + if (dir == Direction.UP) + result.append('~'); + result.append(nodes[i].toStringWithVariable(var)); + } + + result.append(" -> "); + result.append(dest.toStringWithVariable(var)); + result.append(dir.toString()); + return result.toString(); + } + + public boolean isIndented() { + return dir != preferredDirection; + } + } + + private static final LineAndSection[] LAS0 = new LineAndSection[0]; + + public LineAndSection[] evaluate(NodeName dest, + Direction preferredDirection, + Section upSection, Section downSection) { + LinkedList l = new LinkedList(); + for (int i = 0; i < ups.length; i++) { + l.add(new LineAndSection(new Line(Direction.UP, ups[i], dest, + preferredDirection), upSection)); + } + + for (int i = 0; i < downs.length; i++) { + l.add(new LineAndSection(new Line(Direction.DOWN, downs[i], dest, + preferredDirection), downSection)); + } + + return (LineAndSection[]) l.toArray(LAS0); + } + + private NodeName[][] unparam(NodeName[][] old, int index) { + LinkedList l = new LinkedList(); + for (int i = 0; i < old.length; i++) { + NodeName[] a = old[i]; + NodeName[] b = new NodeName[a.length]; + for (int j = 0; j < a.length; j++) + b[j] = a[j].unparameterize(index); + l.add(b); + } + + return (NodeName[][]) l.toArray(new NodeName[0][]); + } + + private NodeName[][] canon(NodeName[][] old, NodeCanonicalizer c) { + LinkedList l = new LinkedList(); + for (int i = 0; i < old.length; i++) { + NodeName[] a = old[i]; + NodeName[] b = new NodeName[a.length]; + for (int j = 0; j < a.length; j++) + b[j] = c.canonicalize(a[j]); + l.add(b); + } + + return (NodeName[][]) l.toArray(new NodeName[0][]); + } + + public NodeExpression unparameterize(int index) { + return new ArbitraryNodeExpression(unparam(ups, index), + unparam(downs, index)); + } + + public NodeExpression canonicalize(NodeCanonicalizer c) { + return new ArbitraryNodeExpression(canon(ups, c), + canon(downs, c)); + } + + private class ANSimplification implements Simplification { + boolean isPower(Direction dir, int i, int j, Power p) { + NodeName[] row; + + if (dir == Direction.UP) + row = ups[i]; + else + row = downs[i]; + + return (row[j] == p); + } + + public boolean isSimpler() { + /* Check if it can be simplified (to an alias) because + * there's only a pull up or only a pull down */ + if (ups.length == 0 || downs.length == 0) + return true; + + // Check if it can be simplified because of Vdd or GND + for (int i = 0; i < ups.length; i++) { + NodeName[] row = ups[i]; + for (int j = 0; j < row.length; j++) + if (isPower(Direction.UP, i, j, Power.Vdd) || + isPower(Direction.UP, i, j, Power.GND)) + return true; + } + + for (int i = 0; i < downs.length; i++) { + NodeName[] row = downs[i]; + for (int j = 0; j < row.length; j++) + if (isPower(Direction.DOWN, i, j, Power.Vdd) || + isPower(Direction.DOWN, i, j, Power.GND)) + return true; + } + + return false; + } + } + + public Simplification getSimplification() { + return new ANSimplification(); + } + + private static class AlwaysTrue extends Exception { + public final Direction dir; + + AlwaysTrue(Direction dir) { + this.dir = dir; + } + } + + /** + * Returns a copy of x, with any node flagged as matching deleteMe + * by simp (with direction dir) deleted, and any line containing a + * node flagged as matching deleteLine by simp (with direction dir) + * deleted. + * + * Throws AlwaysTrue (with dir) if it deletes all the nodes from a + * line (and therefore the expression would always be true). + * + * Throws AlwaysTrue (with dir.opposite()) if it deletes all the lines + * (or there weren't any lines to begin with). + */ + private NodeName[][] deleteStuff(NodeName[][] x, + Direction dir, ANSimplification simp, + Power deleteMe, Power deleteLine) + throws AlwaysTrue { + LinkedList result = new LinkedList(); + + outer: + for (int i = 0; i < x.length; i++) { + NodeName[] a = x[i]; + LinkedList line = new LinkedList(); + + for (int j = 0; j < a.length; j++) { + if (simp.isPower(dir, i, j, deleteLine)) + continue outer; + if (!simp.isPower(dir, i, j, deleteMe)) + line.add(a[j]); + } + + if (line.size() == 0) + throw new AlwaysTrue(dir); + + result.add(line.toArray(new NodeName[0])); + } + + if (result.size() == 0) + throw new AlwaysTrue(dir.opposite()); + + return (NodeName[][]) result.toArray(new NodeName[0][]); + } + + public NodeExpression applySimplification(Simplification simp) { + if (!simp.isSimpler()) + return this; + + try { + ANSimplification ans = (ANSimplification) simp; + return new ArbitraryNodeExpression(deleteStuff(ups, Direction.UP, + ans, Power.GND, + Power.Vdd), + deleteStuff(downs, + Direction.DOWN, + ans, Power.Vdd, + Power.GND)); + } catch (AlwaysTrue e) { + return new AliasNodeExpression(((e.dir == Direction.UP) ? + Power.Vdd : Power.GND), 0); + } + } + + public int hashCode() { + if (hc == null) { + hc = new CRC32(); + + for (int i = 0; i < ups.length; i++) { + NodeName[] a = ups[i]; + for (int j = 0; j < a.length; j++) + hc.update(a[j].hashCode() % 251); + } + + for (int i = 0; i < downs.length; i++) { + NodeName[] a = downs[i]; + for (int j = 0; j < a.length; j++) + hc.update(a[j].hashCode() % 241); + } + } + + return (int) hc.getValue(); + } + + public boolean equals(Object o) { + if (o instanceof ArbitraryNodeExpression) { + ArbitraryNodeExpression x = (ArbitraryNodeExpression) o; + + if (ups.length != x.ups.length || downs.length != x.downs.length) + return false; + + for (int i = 0; i < ups.length; i++) { + NodeName[] a = ups[i]; + NodeName[] b = x.ups[i]; + if (a.length != b.length) + return false; + for (int j = 0; j < a.length; j++) + if (!a[j].equals(b[j])) + return false; + } + + for (int i = 0; i < downs.length; i++) { + NodeName[] a = downs[i]; + NodeName[] b = x.downs[i]; + if (a.length != b.length) + return false; + for (int j = 0; j < a.length; j++) + if (!a[j].equals(b[j])) + return false; + } + + return true; + } + + return false; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/CElementExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/CElementExpression.java new file mode 100644 index 0000000000..c1fdc10078 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/CElementExpression.java @@ -0,0 +1,60 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public class CElementExpression extends ShorthandNodeExpression { + public CElementExpression(NodeName a, NodeName b, boolean reset) { + super(new NodeName[] { a, b }, reset); + } + + protected String operator(int i, Direction preferredDirection) { + switch (i) { + case 0: + return "&"; + case 1: + return "#>"; + } + throw new RuntimeException(); + } + + public NodeExpression unparameterize(int index) { + return new CElementExpression(names[0].unparameterize(index), + names[1].unparameterize(index), + reset); + } + + public NodeExpression canonicalize(NodeCanonicalizer c) { + return new CElementExpression(c.canonicalize(names[0]), + c.canonicalize(names[1]), + reset); + } + + public NodeExpression applySimplification(Simplification simp) { + SHSimplification shs = (SHSimplification) simp; + boolean hasGND = shs.isGND(0) || shs.isGND(1); + boolean hasVdd = shs.isVdd(0) || shs.isVdd(1); + + if (!simp.isSimpler()) + return this; + + if (reset) { + if (hasVdd) + return new NandExpression(new NodeName[] + { new UnparameterizedNodeName("_Reset") }, false); + else + return new AliasNodeExpression(Power.Vdd, 0); + } + + if (hasGND && !hasVdd) { + return new AliasNodeExpression(Power.Vdd, 0); + } else if (hasVdd && !hasGND) { + return new AliasNodeExpression(Power.GND, 0); + } + + throw new RuntimeException("C Element has one input tied to GND " + + "and one input tied to Vdd. This is bad!"); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Direction.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Direction.java new file mode 100644 index 0000000000..101125507d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Direction.java @@ -0,0 +1,24 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +/** + * This is a type-safe enumeration which represents the two directions + * a node can move in: up and down. + */ + +public abstract class Direction { + private Direction() {} + public abstract Direction opposite(); + public static final Direction UP = new Direction() { + public String toString() { return "+"; } + public Direction opposite() { return DOWN; } + }; + public static final Direction DOWN = new Direction() { + public String toString() { return "-"; } + public Direction opposite() { return UP; } + }; +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/LineAndSection.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/LineAndSection.java new file mode 100644 index 0000000000..9a3e24cadb --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/LineAndSection.java @@ -0,0 +1,16 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public class LineAndSection { + public final PrsLine line; + public final Section section; + + public LineAndSection(PrsLine line, Section section) { + this.line = line; + this.section = section; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NandExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NandExpression.java new file mode 100644 index 0000000000..b51f7ddfb5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NandExpression.java @@ -0,0 +1,64 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +import java.util.LinkedList; + +public class NandExpression extends ShorthandNodeExpression { + public NandExpression(NodeName[] names, boolean reset) { + super(names, reset); + } + + protected String operator(int i, Direction preferredDirection) { + if (i == names.length - 1) + return "=>"; + return (preferredDirection == Direction.DOWN ? "&" : "|"); + } + + public NodeExpression unparameterize(int index) { + NodeName[] newnames = new NodeName[names.length]; + for (int i = 0; i < newnames.length; i++) + newnames[i] = names[i].unparameterize(index); + return new NandExpression(newnames, reset); + } + + public NodeExpression canonicalize(NodeCanonicalizer c) { + NodeName[] newnames = new NodeName[names.length]; + for (int i = 0; i < newnames.length; i++) + newnames[i] = c.canonicalize(names[i]); + return new NandExpression(newnames, reset); + } + + public NodeExpression applySimplification(Simplification simp) { + SHSimplification shs = (SHSimplification) simp; + + if (!simp.isSimpler()) + return this; + + LinkedList newnodes = new LinkedList(); + for (int i = 0; i < names.length; i++) { + if (shs.isGND(i)) { + return new AliasNodeExpression(Power.Vdd, 0); + } else if (!shs.isVdd(i)) { + newnodes.add(names[i]); + } + } + + boolean rst = reset; + + if (newnodes.size() == 0 && rst) { + newnodes.add(new UnparameterizedNodeName("_Reset")); + rst = false; + } + + if (newnodes.size() == 0) { + return new AliasNodeExpression(Power.GND, 0); + } + + return new NandExpression((NodeName[]) + newnodes.toArray(new NodeName[0]), rst); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeCanonicalizer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeCanonicalizer.java new file mode 100644 index 0000000000..49be254cdf --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeCanonicalizer.java @@ -0,0 +1,15 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public interface NodeCanonicalizer { + /** + * Given a node name, returns the canonical node name. + * (Or, more generally, you can think of this as a filter which + * transforms node names.) + */ + NodeName canonicalize(NodeName n); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeExpression.java new file mode 100644 index 0000000000..09d2dc4d72 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeExpression.java @@ -0,0 +1,29 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +/* +NodeExpression +|-- AliasNodeExpression +|-- ArbitraryNodeExpression +`-- ShorthandNodeExpression + |-- And2C2Expression + |-- CElementExpression + |-- NandExpression + |-- NorExpression + `-- TwoAnd2C2Expression +*/ + +public interface NodeExpression { + LineAndSection[] evaluate(NodeName dest, Direction preferredDirection, + Section upSection, Section downSection); + NodeExpression unparameterize(int index); + NodeExpression canonicalize(NodeCanonicalizer c); + Simplification getSimplification(); + NodeExpression applySimplification(Simplification simp); + /* note: classes that implement this interface also need to + * implement the equals() and hashCode() methods correctly. */ +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeName.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeName.java new file mode 100644 index 0000000000..78ddacd7b3 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NodeName.java @@ -0,0 +1,15 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public interface NodeName { + boolean isParameterized(); + String toStringWithIndex(int index); + String toStringWithVariable(String var); + NodeName unparameterize(int index); + /* note: classes that implement this interface also need to + * implement the equals() and hashCode() methods correctly. */ +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NorExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NorExpression.java new file mode 100644 index 0000000000..edc7dedc3c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/NorExpression.java @@ -0,0 +1,64 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +import java.util.LinkedList; + +public class NorExpression extends ShorthandNodeExpression { + public NorExpression(NodeName[] names, boolean reset) { + super(names, reset); + } + + protected String operator(int i, Direction preferredDirection) { + if (i == names.length - 1) + return "=>"; + return (preferredDirection == Direction.UP ? "&" : "|"); + } + + public NodeExpression unparameterize(int index) { + NodeName[] newnames = new NodeName[names.length]; + for (int i = 0; i < newnames.length; i++) + newnames[i] = names[i].unparameterize(index); + return new NorExpression(newnames, reset); + } + + public NodeExpression canonicalize(NodeCanonicalizer c) { + NodeName[] newnames = new NodeName[names.length]; + for (int i = 0; i < newnames.length; i++) + newnames[i] = c.canonicalize(names[i]); + return new NorExpression(newnames, reset); + } + + public NodeExpression applySimplification(Simplification simp) { + SHSimplification shs = (SHSimplification) simp; + + if (!simp.isSimpler()) + return this; + + LinkedList newnodes = new LinkedList(); + for (int i = 0; i < names.length; i++) { + if (shs.isVdd(i)) { + return new AliasNodeExpression(Power.GND, 0); + } else if (!shs.isGND(i)) { + newnodes.add(names[i]); + } + } + + boolean rst = reset; + + if (newnodes.size() == 0 && rst) { + newnodes.add(new UnparameterizedNodeName("_Reset")); + rst = false; + } + + if (newnodes.size() == 0) { + return new AliasNodeExpression(Power.Vdd, 0); + } + + return new NorExpression((NodeName[]) + newnodes.toArray(new NodeName[0]), rst); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Organizer.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Organizer.java new file mode 100644 index 0000000000..b4c850f3c2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Organizer.java @@ -0,0 +1,132 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +public class Organizer implements WholeOperatorSink, NodeCanonicalizer { + /** + * This is for everything except aliases. Maps a NodeExpression + * (which has been unparameterized and canonicalized) to a + * WholeOperator. This makes it possible to look + * up any existing WholeOperator which is computing + * the same result, and alias them togther. + */ + LinkedHashMap unique = new LinkedHashMap(); + + /** + * This is for aliases. Maps a NodeName (which has been + * unparameterized, and which is the destination node + * of the WholeOperator) to a WholeOperator, which must have an + * AliasNodeExpression as its expression. This makes it possible + * to look up what a node has been aliased to. + */ + LinkedHashMap aliases = new LinkedHashMap(); + + /** + * This is strictly for error checking. We want to make sure that the + * same node is never defined more than once. + */ + HashSet whereNoOneHasGoneBefore = new HashSet(); + + public void hereYaGo(WholeOperator wo) { + NodeName boldly = wo.dest.unparameterize(wo.index); + assert (!whereNoOneHasGoneBefore.contains(boldly)) : + boldly + " redefined"; + whereNoOneHasGoneBefore.add(boldly); + if (!(wo.expr instanceof AliasNodeExpression)) { + NodeExpression key = wo.expr.unparameterize(wo.index) + .canonicalize(this); + if (unique.containsKey(key)) { + WholeOperator existing = (WholeOperator) unique.get(key); + AliasNodeExpression ane = + new AliasNodeExpression(existing.dest, + existing.index - wo.index); + Section sect = (wo.preferredDirection == Direction.UP ? + wo.upSection : wo.downSection); + wo = new WholeOperator(wo.dest.unparameterize(wo.index), + ane, wo.index, + wo.preferredDirection, sect, sect); + } else { + unique.put(key, wo); + } + } + + if (wo.expr instanceof AliasNodeExpression) { + aliases.put(wo.dest.unparameterize(wo.index), wo); + } + } + + public NodeName canonicalize(NodeName n) { + assert !n.isParameterized(); + + while (aliases.containsKey(n)) { + WholeOperator wop = (WholeOperator) aliases.get(n); + AliasNodeExpression ane = + (AliasNodeExpression) wop.expr.unparameterize(wop.index); + NodeName newn = ane.getNode(); + assert (n != newn) : "stuck on " + n; + n = newn; + assert !n.isParameterized(); + } + + return n; + } + + private boolean simplifyingCopy(WholeOperatorSink sink) { + /* It is important to provide the aliases first, so that the + * destination Organizer will be able to canonicalize on them. */ + for (Iterator it = aliases.values().iterator(); it.hasNext(); ) + sink.hereYaGo((WholeOperator) it.next()); + + boolean simplified = false; + + for (Iterator it = unique.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry) it.next(); + NodeExpression key = (NodeExpression) entry.getKey(); + WholeOperator value = (WholeOperator) entry.getValue(); + Simplification simp = key.getSimplification(); + if (simp.isSimpler()) { + value = new WholeOperator(value.dest, + value.expr.applySimplification(simp), + value.index, + value.preferredDirection, + value.upSection, value.downSection); + simplified = true; + } + + sink.hereYaGo(value); + } + + return simplified; + } + + /** + * Fully simplify all the rules in this Organizer and copy them to + * another WholeOperatorSink. + */ + public void simplify(WholeOperatorSink dest) { + Organizer src = this; + + boolean keepGoing = true; + + while (keepGoing) { + Organizer next = new Organizer(); + + keepGoing = src.simplifyingCopy(next); + if (src.unique.size() != next.unique.size() || + src.aliases.size() != next.aliases.size()) + keepGoing = true; + + src = next; + } + + src.simplifyingCopy(dest); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ParameterizedNodeName.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ParameterizedNodeName.java new file mode 100644 index 0000000000..b9b06b0cd7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ParameterizedNodeName.java @@ -0,0 +1,39 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public class ParameterizedNodeName implements NodeName { + private final String str; + + public ParameterizedNodeName(String str) { + this.str = str; + } + + public boolean isParameterized() { + return true; + } + + public String toStringWithIndex(int index) { + return str + "." + index; + } + + public String toStringWithVariable(String var) { + return str + ".d[" + var + "]"; + } + + public NodeName unparameterize(int index) { + return new UnparameterizedNodeName(toStringWithIndex(index)); + } + + public boolean equals(Object o) { + return (o instanceof ParameterizedNodeName && + str.equals(((ParameterizedNodeName)o).str)); + } + + public int hashCode() { + return str.hashCode(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Power.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Power.java new file mode 100644 index 0000000000..c9acd94b5d --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Power.java @@ -0,0 +1,48 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +/** + * This is a type-safe enumeration which represents the two power + * rails, Vdd and GND. + */ + +public class Power implements NodeName { + private static boolean isCalled = false; + private Power() {} + public boolean isParameterized() { + return false; + } + + public String toStringWithIndex(int index) { + return toString(); + } + + public String toStringWithVariable(String var) { + return toString(); + } + + public NodeName unparameterize(int index) { + return this; + } + + public static final Power GND = new Power() { + public String toString() { + isCalled = true; + return "tielo"; + } + }; + + public static final Power Vdd = new Power() { + public String toString() { + isCalled = true; + return "tiehi"; + } + }; + public static boolean getIsCalled() { + return isCalled; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsLine.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsLine.java new file mode 100644 index 0000000000..7dd8a02319 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsLine.java @@ -0,0 +1,22 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +/** + * This represents a production rule. It is possible for the production + * rule to be parameterized, which means that there is a rail number which + * can be filled in (either with a constant integer, or with a variable + * for looping) when the rule is converted to a string. + */ + +public interface PrsLine { + boolean isParameterized(); + boolean isIndented(); + String toStringWithIndex(int index); + String toStringWithVariable(String var); + /* note: classes that implement this interface also need to + * implement the equals() and hashCode() methods correctly. */ +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsPrinter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsPrinter.java new file mode 100644 index 0000000000..9e865f8f96 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/PrsPrinter.java @@ -0,0 +1,155 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.io.PrintWriter; +import com.avlsi.util.text.StringUtil; + +/** + * The purpose here is to take a bunch of WholeOperators (which have + * already been simplified by Organizer) and convert them to a + * pretty-printed textual representation. + */ + +public class PrsPrinter implements WholeOperatorSink { + private int serialCounter = 0; + + private class Stuff extends LineAndSection { + public final int fromIndex; + public int toIndex; // yes, this is the one mutable field! + public final int serial; + + public Stuff(LineAndSection las, int index) { + super(las.line, las.section); + fromIndex = index; + toIndex = index; + serial = serialCounter++; + } + } + + // List of Stuff + private final List stuff = new LinkedList(); + + public void hereYaGo(WholeOperator wo) { + LineAndSection[] las = wo.expr.evaluate(wo.dest, wo.preferredDirection, + wo.upSection, wo.downSection); + for (int i = 0; i < las.length; i++) { + stuff.add(new Stuff(las[i], wo.index)); + } + } + + /** + * @param w output goes here + * @param baseIndent all lines are indented this many spaces + * @param extraIndent "indented" lines are indented this many more spaces + * @param commentColumn same-line comments go in this column + * @param ancestorSection a Section which is less than all other sections + */ + + public void emit(PrintWriter w, int baseIndent, int extraIndent, + int commentColumn, Section ancestorSection) { + // sort by index (needed to condense loops) + Collections.sort(stuff, new Comparator() { + public int compare(Object o1, Object o2) { + Stuff s1 = (Stuff) o1; + Stuff s2 = (Stuff) o2; + + return s1.fromIndex - s2.fromIndex; + } + }); + + // try to condense contiguous indices into loops + Map loopy = new HashMap(); // key = PrsLine, value = Stuff + for (Iterator it = stuff.iterator(); it.hasNext(); ) { + Stuff current = (Stuff) it.next(); + Stuff prev = (Stuff) loopy.get(current.line); + assert (current.fromIndex == current.toIndex); + if (prev != null && current.fromIndex == prev.toIndex + 1) { + assert (current.line.isParameterized() && + prev.line.isParameterized()); + prev.toIndex++; + it.remove(); + } else { + loopy.put(current.line, current); + } + } + + /* Now put it back in the order we want. (Sorted first by section, + * and then by serial number. (The serial number is to mimic + * a stable sort, even though we screwed up the order in the + * previous step.)) */ + Collections.sort(stuff, new Comparator() { + public int compare(Object o1, Object o2) { + Stuff s1 = (Stuff) o1; + Stuff s2 = (Stuff) o2; + + int result = s1.section.compareTo(s2.section); + if (result == 0) + result = s1.serial - s2.serial; + + return result; + } + }); + + /* Now print it all out */ + String bi = StringUtil.repeatString(" ", baseIndent); + String ei = StringUtil.repeatString(" ", baseIndent + extraIndent); + + Section prevSect = ancestorSection; + for (Iterator it = stuff.iterator(); it.hasNext(); ) { + Stuff current = (Stuff) it.next(); + boolean blankLine = current.section.blankLineBefore(prevSect); + String commentBefore = current.section.commentBefore(prevSect); + String commentWith = current.section.commentWith(prevSect); + + if (blankLine || commentBefore != null) + w.println(); + + if (commentBefore != null) + w.println(bi + "// " + commentBefore); + + StringBuffer line = + new StringBuffer(current.line.isIndented() ? ei : bi); + boolean looped = (current.fromIndex != current.toIndex); + if (looped) { + assert (current.toIndex > current.fromIndex); + assert (current.line.isParameterized()); + line.append(""); + } else { + line.append(current.line.toStringWithIndex(current.fromIndex)); + } + + if (commentWith != null) { + do { + line.append(' '); + } while (line.length() < commentColumn); + + line.append("// "); + line.append(commentWith); + } + + w.println(line); + prevSect = current.section; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Section.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Section.java new file mode 100644 index 0000000000..f8aacfb2bd --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Section.java @@ -0,0 +1,26 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public interface Section extends Comparable { + /** + * Returns true if a blank line should appear before this section, + * when it is preceded by prevSection. + */ + boolean blankLineBefore(Section prevSection); + + /** + * Returns a comment which should appear before this section, + * when it is preceded by prevSection. null means no comment + */ + String commentBefore(Section prevSection); + + /** + * Returns a comment which should appear on the first line of this section, + * when it is preceded by prevSection. null means no comment + */ + String commentWith(Section prevSection); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/SectionImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/SectionImpl.java new file mode 100644 index 0000000000..6ba3d373a8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/SectionImpl.java @@ -0,0 +1,55 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +import java.math.BigDecimal; + +public class SectionImpl implements Section { + private final BigDecimal sectID; + private final BigDecimal blankLineBeforeID; + private final BigDecimal commentBeforeID; + private final String commentBefore; + private final BigDecimal commentWithID; + private final String commentWith; + + public SectionImpl(BigDecimal sectID, BigDecimal blankLineBeforeID, + BigDecimal commentBeforeID, String commentBefore, + BigDecimal commentWithID, String commentWith) { + this.sectID = sectID; + this.blankLineBeforeID = blankLineBeforeID; + this.commentBeforeID = commentBeforeID; + this.commentBefore = commentBefore; + this.commentWithID = commentWithID; + this.commentWith = commentWith; + } + + public int compareTo(Object o) { + SectionImpl s = (SectionImpl) o; + return sectID.compareTo(s.sectID); + } + + public boolean blankLineBefore(Section prevSection_) { + SectionImpl prevSection = (SectionImpl) prevSection_; + return (blankLineBeforeID != null && + prevSection.sectID.compareTo(blankLineBeforeID) < 0); + } + + public String commentBefore(Section prevSection_) { + SectionImpl prevSection = (SectionImpl) prevSection_; + if (commentBeforeID != null && + prevSection.sectID.compareTo(commentBeforeID) < 0) + return commentBefore; + return null; + } + + public String commentWith(Section prevSection_) { + SectionImpl prevSection = (SectionImpl) prevSection_; + if (commentWithID != null && + prevSection.sectID.compareTo(commentWithID) < 0) + return commentWith; + return null; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ShorthandNodeExpression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ShorthandNodeExpression.java new file mode 100644 index 0000000000..486aae8e9b --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/ShorthandNodeExpression.java @@ -0,0 +1,164 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public abstract class ShorthandNodeExpression implements NodeExpression { + protected final NodeName[] names; + protected final boolean reset; + + protected ShorthandNodeExpression(NodeName[] names, boolean reset) { + this.names = names; + this.reset = reset; + } + + /** + * Operator which should appear between the ith and i+1th node. + * Note that the last operator is actually the operator between + * the ith node and destination node (i. e. arrow operator), rather + * than an "and" or "or" operator. + */ + protected abstract String operator(int i, Direction preferredDirection); + + /** + * Should there be a left paren before the ith node? + */ + protected boolean parenBefore(int i) { + return false; + } + + /** + * Should there be a right paren after the ith node? + */ + protected boolean parenAfter(int i) { + return false; + } + + /** + * This can be overridden for operators which can only be + * written in one direction, like and2c2. + */ + protected Direction overrideDirection(Direction preferredDirection) { + return preferredDirection; + } + + public LineAndSection[] evaluate(final NodeName dest, + Direction preferredDirection_, + Section upSection, Section downSection) { + final Direction preferredDirection = + overrideDirection(preferredDirection_); + + return new LineAndSection[] { new LineAndSection(new AbstractPrsLine() { + public boolean isParameterized() { + for (int i = 0; i < names.length; i++) + if (names[i].isParameterized()) + return true; + return dest.isParameterized(); + } + + private String resetPrefix() { + if (!reset) + return ""; + return (preferredDirection == Direction.UP ? + "~_Reset | " : "_Reset & ("); + } + + private String resetSuffix() { + return (reset && preferredDirection == Direction.DOWN ? + ")" : ""); + } + + public String toStringWithIndex(int index) { + StringBuffer result = new StringBuffer(resetPrefix()); + for (int i = 0; i < names.length; i++) { + if (parenBefore(i)) + result.append('('); + if (preferredDirection == Direction.UP) + result.append('~'); + result.append(names[i].toStringWithIndex(index)); + if (parenAfter(i)) + result.append(')'); + if (i == names.length - 1) + result.append(resetSuffix()); + result.append(' '); + result.append(operator(i, preferredDirection)); + result.append(' '); + } + result.append(dest.toStringWithIndex(index)); + result.append(preferredDirection.toString()); + return result.toString(); + } + + public String toStringWithVariable(String var) { + StringBuffer result = new StringBuffer(resetPrefix()); + for (int i = 0; i < names.length; i++) { + if (parenBefore(i)) + result.append('('); + if (preferredDirection == Direction.UP) + result.append('~'); + result.append(names[i].toStringWithVariable(var)); + if (parenAfter(i)) + result.append(')'); + if (i == names.length - 1) + result.append(resetSuffix()); + result.append(' '); + result.append(operator(i, preferredDirection)); + result.append(' '); + } + result.append(dest.toStringWithVariable(var)); + result.append(preferredDirection.toString()); + return result.toString(); + } + }, upSection) }; + } + + public abstract NodeExpression unparameterize(int index); + public abstract NodeExpression canonicalize(NodeCanonicalizer c); + + protected class SHSimplification implements Simplification { + boolean isGND(int n) { + return (names[n] == Power.GND); + } + + boolean isVdd(int n) { + return (names[n] == Power.Vdd); + } + + public boolean isSimpler() { + for (int i = 0; i < names.length; i++) + if (isGND(i) || isVdd(i)) + return true; + return false; + } + } + + public Simplification getSimplification() { + return new SHSimplification(); + } + + public abstract NodeExpression applySimplification(Simplification simp); + + public int hashCode() { + int hc = getClass().hashCode(); + for (int i = 0; i < names.length; i++) { + hc += names[i].hashCode(); + } + return (reset ? hc : ~hc); + } + + public boolean equals(Object o) { + if (o.getClass().equals(getClass())) { + ShorthandNodeExpression that = (ShorthandNodeExpression) o; + if (names.length != that.names.length || reset != that.reset) + return false; + for (int i = 0; i < names.length; i++) + if (!names[i].equals(that.names[i])) + return false; + return true; + } else { + return false; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Simplification.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Simplification.java new file mode 100644 index 0000000000..05bec5a7f8 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/Simplification.java @@ -0,0 +1,27 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +/** + * A Simplification represents a way that a NodeExpression can be made + * simpler. (By removing references to Vdd and GND, for example.) + * Simplification is mostly an opaque data type which can be used to + * store anything the particular NodeExpression implementation wants to + * store. The only public method is isSimpler(), which indicates whether + * the Simplification will actually do anything. (If it returns false, + * the Simplification is a no-op.) The reason for Simplification objects + * is because you need to look at the NodeExpression when it is + * unparameterized and canonicalized, in order to determine how to + * simplifying it, but we want to actually apply the simplification to + * the original NodeExpression which may be parameterized or have + * non-canonical node names. Therefore, getSimplification() and + * applySimplification() are separate methods, with the Simplification + * object to communicate between them. + */ + +public interface Simplification { + boolean isSimpler(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/TwoAnd2C2Expression.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/TwoAnd2C2Expression.java new file mode 100644 index 0000000000..6e58401337 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/TwoAnd2C2Expression.java @@ -0,0 +1,109 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public class TwoAnd2C2Expression extends ShorthandNodeExpression { + public TwoAnd2C2Expression(NodeName a1, NodeName a2, + NodeName b1, NodeName b2, boolean reset) { + super(new NodeName[] { a1, a2, b1, b2 }, reset); + } + + protected String operator(int i, Direction preferredDirection) { + switch (i) { + case 0: + case 2: + return "|"; + case 1: + return "&"; + case 3: + return "#>"; + } + throw new RuntimeException(); + } + + // 2and2c2 can only be written in the "up" direction + protected Direction overrideDirection(Direction preferredDirection) { + return Direction.UP; + } + + protected boolean parenBefore(int i) { + return ((i & 1) == 0); + } + + protected boolean parenAfter(int i) { + return ((i & 1) == 1); + } + + public NodeExpression unparameterize(int index) { + return new TwoAnd2C2Expression(names[0].unparameterize(index), + names[1].unparameterize(index), + names[2].unparameterize(index), + names[3].unparameterize(index), + reset); + } + + public NodeExpression canonicalize(NodeCanonicalizer c) { + return new TwoAnd2C2Expression(c.canonicalize(names[0]), + c.canonicalize(names[1]), + c.canonicalize(names[2]), + c.canonicalize(names[3]), + reset); + } + + public NodeExpression applySimplification(Simplification simp) { + SHSimplification shs = (SHSimplification) simp; + boolean hasGND = + shs.isGND(0) || shs.isGND(1) || shs.isGND(2) || shs.isGND(3); + boolean hasVdd = + (shs.isVdd(0) && shs.isVdd(1)) || (shs.isVdd(2) && shs.isVdd(3)); + + if (!simp.isSimpler()) + return this; + + if (reset) { + if (hasVdd) + return new NandExpression(new NodeName[] + { new UnparameterizedNodeName("_Reset") }, false); + else if (hasGND) + return new AliasNodeExpression(Power.Vdd, 0); + } + + if (hasGND && !hasVdd) { + return new AliasNodeExpression(Power.Vdd, 0); + } else if (hasVdd && !hasGND) { + return new AliasNodeExpression(Power.GND, 0); + } else if (hasGND && hasVdd) { + throw new RuntimeException("C Element has one input tied to GND " + + "and one input tied to Vdd. " + + "This is bad!"); + } + + NodeName n1 = null, n2 = null; + + if (shs.isVdd(0)) { + n1 = names[1]; + } else if (shs.isVdd(1)) { + n1 = names[0]; + } + + if (shs.isVdd(2)) { + n2 = names[3]; + } else if (shs.isVdd(3)) { + n2 = names[2]; + } + + if (n1 != null && n2 != null) + return new CElementExpression(n1, n2, reset); + + if (n1 == null) { + assert (n2 != null); + return new And2C2Expression(names[0], names[1], n2, reset); + } else { + assert (n2 == null); + return new And2C2Expression(names[2], names[3], n1, reset); + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/UnparameterizedNodeName.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/UnparameterizedNodeName.java new file mode 100644 index 0000000000..778f803431 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/UnparameterizedNodeName.java @@ -0,0 +1,43 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public class UnparameterizedNodeName implements NodeName { + private final String str; + + public UnparameterizedNodeName(String str) { + this.str = str; + } + + public boolean isParameterized() { + return false; + } + + public String toStringWithIndex(int index) { + return str; + } + + public String toStringWithVariable(String var) { + return str; + } + + public NodeName unparameterize(int index) { + return this; + } + + public boolean equals(Object o) { + return (o instanceof UnparameterizedNodeName && + str.equals(((UnparameterizedNodeName)o).str)); + } + + public int hashCode() { + return str.hashCode(); + } + + public String toString() { + return str; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperator.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperator.java new file mode 100644 index 0000000000..563959bcde --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperator.java @@ -0,0 +1,52 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +/** + * A WholeOperator represents a pair of half-operators. (Duh!) + * The destination and NodeExpression might be parameterized, which is + * why we need to store an index in the WholeOperator. + */ + +public class WholeOperator { + public final NodeName dest; + public final NodeExpression expr; + public final int index; + public final Direction preferredDirection; + public final Section upSection; + public final Section downSection; + + // The most general constuctor. + public WholeOperator(NodeName dest, NodeExpression expr, int index, + Direction preferredDirection, + Section upSection, Section downSection) { + this.dest = dest; + this.expr = expr; + this.index = index; + this.preferredDirection = preferredDirection; + this.upSection = upSection; + this.downSection = downSection; + } + + // Constructor without an index + public WholeOperator(NodeName dest, NodeExpression expr, + Direction preferredDirection, + Section upSection, Section downSection) { + this(dest, expr, -1, preferredDirection, upSection, downSection); + } + + // Constructor with only one section + public WholeOperator(NodeName dest, NodeExpression expr, int index, + Direction preferredDirection, Section upSection) { + this(dest, expr, index, preferredDirection, upSection, upSection); + } + + // Constructor with only one section and no index + public WholeOperator(NodeName dest, NodeExpression expr, + Direction preferredDirection, Section upSection) { + this(dest, expr, preferredDirection, upSection, upSection); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperatorSink.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperatorSink.java new file mode 100644 index 0000000000..461f2bba81 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/output/WholeOperatorSink.java @@ -0,0 +1,10 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.output; + +public interface WholeOperatorSink { + void hereYaGo(WholeOperator wo); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/presto.package b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/presto.package new file mode 100644 index 0000000000..4f850eb1f2 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/presto.package @@ -0,0 +1,10 @@ +2 0 +# Copyright 2002 Fulcrum Microsystems. All rights reserved. +# $Id$ +# $DateTime$ +# $Author$ + +include ../../csp/csp2java/runtime/cspruntime.package.inc ../../csp/csp2java/runtime +java com.avlsi.tools.presto.PReSto +$arch/bin/presto.sh presto.sh 775 +$arch/bin/csp2tt.sh csp2tt.sh 775 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/CompletionInfo.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/CompletionInfo.java new file mode 100644 index 0000000000..6e42364b55 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/CompletionInfo.java @@ -0,0 +1,24 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import com.avlsi.tools.presto.complete.Node; + +public class CompletionInfo { + public final Node[][] ops; + public final int desiredSense; + public final boolean reset; + public final String rootName; + public Node root; + + public CompletionInfo(Node[][] ops, int desiredSense, boolean reset, + String rootName) { + this.ops = ops; + this.desiredSense = desiredSense; + this.reset = reset; + this.rootName = rootName; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Declarations.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Declarations.java new file mode 100644 index 0000000000..02d8979ac1 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Declarations.java @@ -0,0 +1,34 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import com.avlsi.tools.presto.ChannelName; +import com.avlsi.tools.presto.complete.Node; + +public interface Declarations { + /* These correspond to "basic channel types" in standard/channel.cast, + * although we don't actually use most of them. */ + String CH1of = "1of"; + String CH_1of = "_1of"; + String CH_a1of = "_a1of"; + String CHa1of = "a1of"; + String CH_e1of = "_e1of"; + String CHe1of = "e1of"; + String CHev1of = "ev1of"; + + /** + * @param c the channel to declare + * @param type should be one of the channel types above (trying to + * pretend this is an abstract data type, even though + * it's really just a string) + */ + void declareChannel(ChannelName c, String type); + + /** + * @param n the node to declare + */ + void declareNode(Node n); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DeclarationsImpl.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DeclarationsImpl.java new file mode 100644 index 0000000000..b28a1f8c82 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DeclarationsImpl.java @@ -0,0 +1,210 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import com.avlsi.tools.presto.ChannelName; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import com.avlsi.util.container.FlatteningIterator; +import com.avlsi.util.container.IntArrayComparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import com.avlsi.tools.presto.complete.Node; +import com.avlsi.util.container.Pair; +import java.io.PrintWriter; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +public class DeclarationsImpl implements Declarations { + /** + * maps Pair(String type, String name) -> Set(int[]) + */ + private final TreeMap decls = new TreeMap(); + + private void declare(String type, String name, int[] indices) { + Pair key = new Pair(type, name); + Set value = (Set) decls.get(key); + if (value == null) { + value = new TreeSet(new IntArrayComparator()); + decls.put(key, value); + } + value.add(indices); + } + + public void declareChannel(ChannelName c, String type) { + declare(type + c.get1of(), c.getName(), c.getArrayIndices()); + } + + public void declareNode(Node n) { + declare("node", n.getName(), n.getArrayIndices()); + } + + private static class Range { + final int from; + int to; + + Range(int x) { + from = x; + to = x; + } + + public String toString() { + if (from == to) + return Integer.toString(from); + else + return from + ".." + to; + } + } + + /** + * For a given index, tries to coalesce arrays of ranges which are + * equal in all other indices and consecutive in the given index. + * @param ranges a List of arrays of Ranges + * @param i index into array of Ranges + */ + private static void coalesceOnce(List ranges, final int i) { + /* Sort the given list of arrays of ranges, using index i + * as the least significant position. */ + Collections.sort(ranges, new Comparator() { + public int compare(Object o1, Object o2) { + Range[] a = (Range[]) o1; + Range[] b = (Range[]) o2; + assert (a.length == b.length); + assert (i >= 0 && i < a.length); + + for (int j = 0; j < a.length; j++) { + int x = (i + j + 1) % a.length; + int d = (a[x].from - b[x].from); + if (d != 0) + return d; + d = (a[x].to - b[x].to); + if (d != 0) + return d; + } + + return 0; + } + }); + + Range[] prev = null; + + // now we just need to coalesce adjacent arrays if legal + for (Iterator it = ranges.iterator(); it.hasNext(); ) { + Range[] a = (Range[]) it.next(); + + boolean ok = (prev != null); + for (int j = 0; ok && j < a.length; j++) + if (j != i) + ok = (a[j].from == prev[j].from && + a[j].to == prev[j].to); + + if (ok && a[i].from == prev[i].to + 1) { + assert (prev[i].to >= prev[i].from); + assert (a[i].to == a[i].from); + prev[i].to++; + it.remove(); + } else { + prev = a; + } + } + } + + /** + * Given a collection of int[], tries to coalesce sparse + * array declarations into one or more nice array ranges + * (i. e. "[0..3,0..1]") and returns these ranges as an + * array of strings. + */ + private static String[] coalesce(Collection indices) { + assert (indices.size() > 0); + + int len = ((int[])indices.iterator().next()).length; + if (len == 0) + return new String[] { "" }; + + LinkedList ranges = new LinkedList(); + + for (Iterator it = indices.iterator(); it.hasNext(); ) { + int[] a = (int[]) it.next(); + assert (a.length == len); + Range[] r = new Range[len]; + for (int i = 0; i < len; i++) + r[i] = new Range(a[i]); + ranges.add(r); + } + + for (int i = 0; i < len; i++) + coalesceOnce(ranges, i); + + LinkedList result = new LinkedList(); + for (Iterator it = ranges.iterator(); it.hasNext(); ) { + Range[] r = (Range[]) it.next(); + StringBuffer buf = new StringBuffer(); + char c = '['; + for (int i = 0; i < len; i++) { + buf.append(c); + buf.append(r[i]); + c = ','; + } + buf.append(']'); + result.add(buf.toString()); + } + + return (String[]) result.toArray(new String[0]); + } + + /** + * Prints the declarations to the given PrintWriter. + * @param w print the declarations here + * @param indent number of spaces to indent each line + * @param max longest line length allowed + */ + public void emit(PrintWriter w, int indent, int max) { + // twiddle with the order, because I want the nodes to be first + Pair where = new Pair("node", ""); + List reordered = new LinkedList(); + reordered.add(decls.tailMap(where).entrySet().iterator()); + reordered.add(decls.headMap(where).entrySet().iterator()); + + String currentType = null; + StringBuffer buf = new StringBuffer(); + + for (Iterator it = new FlatteningIterator(reordered.iterator()); + it.hasNext(); ) { + Map.Entry e = (Map.Entry) it.next(); + Pair key = (Pair) e.getKey(); + Set value = (Set) e.getValue(); + String type = (String) key.getFirst(); + String name = (String) key.getSecond(); + String[] indices = coalesce(value); + for (int i = 0; i < indices.length; i++) { + String x = name + indices[i]; + if (currentType == null || !currentType.equals(type) || + buf.length() + x.length() + 3 > max) { + buf.append(';'); + if (currentType != null) + w.println(buf.toString()); + buf.setLength(indent); + for (int j = 0; j < indent; j++) + buf.setCharAt(j, ' '); + buf.append(type); + currentType = type; + } else { + buf.append(','); + } + buf.append(' '); + buf.append(x); + } + } + + buf.append(';'); + w.println(buf.toString()); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoCompletion.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoCompletion.java new file mode 100644 index 0000000000..cf44152157 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoCompletion.java @@ -0,0 +1,355 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import com.avlsi.tools.presto.output.And2C2Expression; +import java.util.Arrays; +import java.util.BitSet; +import com.avlsi.tools.presto.output.CElementExpression; +import com.avlsi.tools.presto.ChannelName; +import java.util.Collection; +import com.avlsi.tools.presto.output.Direction; +import com.avlsi.tools.presto.complete.GreedyComplete; +import java.util.Iterator; +import java.util.Map; +import com.avlsi.tools.presto.output.NandExpression; +import com.avlsi.tools.presto.complete.Node; +import com.avlsi.tools.presto.complete.NodeBuilder; +import com.avlsi.tools.presto.output.NodeExpression; +import com.avlsi.tools.presto.output.NodeName; +import com.avlsi.tools.presto.output.NorExpression; +import com.avlsi.tools.presto.output.Section; +import java.util.TreeMap; +import com.avlsi.tools.presto.complete.TreeMunger; +import com.avlsi.tools.presto.complete.TreeReadjuster; +import com.avlsi.tools.presto.output.TwoAnd2C2Expression; +import com.avlsi.tools.presto.output.UnparameterizedNodeName; +import com.avlsi.tools.presto.output.WholeOperator; +import com.avlsi.tools.presto.output.WholeOperatorSink; + +public class DoCompletion { + private DoCompletion() {} // static only + + private static Node mungeTree(Node root, final Map temporaryNames, + final String rootName, + final int[] rootIndex) { + final int rootTier = root.getTier(); + return TreeMunger.mungeTree(root, new NodeBuilder() { + public Node buildNode(int type, int tier, Node[] children) { + String nameOverride = (tier == rootTier ? rootName : null); + return Doodad.conjugate(type, tier, children, + temporaryNames, nameOverride, + rootIndex); + } + }); + } + + /** + * Take a completion tree in which the intermediate nodes are + * unnamed, and return an identical completion tree in which they + * are named. All of the code that really does this is in the + * Doodad class. + */ + public static Node assignNames(Node root, String rootName, + int[] rootIndex) { + // dry run, to figure out which temporaries need to be arrays + Map temporaryNames = new TreeMap(); + mungeTree(root, temporaryNames, rootName, rootIndex); + + /* Remove everything from the Map, except leave a zero-length + * array for the temporaries that don't need to be an array. */ + for (Iterator it = temporaryNames.entrySet().iterator(); + it.hasNext(); ) { + Map.Entry e = (Map.Entry) it.next(); + int[] a = (int[]) e.getValue(); + assert (a.length == 1); + assert (a[0] > 0); + if (a[0] == 1) + e.setValue(new int[0]); + else + it.remove(); + } + + // now do it for real + return mungeTree(root, temporaryNames, rootName, rootIndex); + } + + /** + * Same as above, but does multiple, separate completion trees at + * once. (The point of this is to share the generated node-name + * space across all completion trees.) + */ + public static Node[] assignNames(Node[] root, String[] rootName) { + assert (root.length == rootName.length); + // dry run, to figure out which temporaries need to be arrays + Map temporaryNames = new TreeMap(); + for (int i = 0; i < root.length; i++) + mungeTree(root[i], temporaryNames, rootName[i], new int[0]); + + /* Remove everything from the Map, except leave a zero-length + * array for the temporaries that don't need to be an array. */ + for (Iterator it = temporaryNames.entrySet().iterator(); + it.hasNext(); ) { + Map.Entry e = (Map.Entry) it.next(); + int[] a = (int[]) e.getValue(); + assert (a.length == 1); + assert (a[0] > 0); + if (a[0] == 1) + e.setValue(new int[0]); + else + it.remove(); + } + + // now do it for real + Node[] result = new Node[root.length]; + for (int i = 0; i < root.length; i++) + result[i] = mungeTree(root[i], temporaryNames, rootName[i], + new int[0]); + return result; + } + + /** + * Returns a tree which is like the given tree, except that inverters + * in the input completion portion of the tree are shifted as close + * to the root as possible. This is to avoid dumb stuff like this: + * L.0 => _L0- // tier 1 + * L.1 => _L1- + * L.2 => _L2- + * L.3 => _L3- + * ~_L0 | ~_L1 => L01+ // tier 2 + * ~_L2 | ~_L3 => L23+ + * L01 | L23 => _Lv- // tier 3 + */ + public static Node shiftInvertersUp(Node root) { + return TreeMunger.mungeTree(root, new NodeBuilder() { + private boolean isInput(Node n) { + Doodad doodad = (Doodad) n.getCookie(); + if (doodad == null) { + for (int i = 0; i < n.size(); i++) + if (!isInput(n.get(i))) + return false; + return true; + } else { + return (doodad.sectType == Doodad.IN); + } + } + + public Node buildNode(int type, int tier, Node[] children) { + if (children.length == 2 && children[0].size() == 1 && + children[1].size() == 1 && isInput(children[0]) && + isInput(children[1])) { + Node prev = new Node(type, null, null, tier - 1, null, + new Node[] { children[0].get(0), + children[1].get(0)}); + return new Node(children[0].getType(), null, null, + tier, null, new Node[] { prev }); + } else { + return new Node(type, null, null, tier, + null, children); + } + } + }); + } + + /** + * Creates an array of nodes that represent the nodes in the + * given channel. + * @param channel the channel + * @param tier which tier (usually 0 for inputs and 1 for outputs) + * these nodes start at + * @param sectType one of Doodad.IN, Doodad.OUT, or Doodad.BOTH + * @param rails Collection of Numbers: the rails in channel which matter + */ + public static Node[] nodesForChannel(ChannelName channel, + int tier, int sectType, + Collection rails) { + Node[] result = new Node[rails.size()]; + int i = 0; + for (Iterator it = rails.iterator(); it.hasNext(); i++) { + int rail = ((Number)it.next()).intValue(); + BitSet railSet = new BitSet(); + railSet.set(rail); + // leaves don't need a section + Doodad doodad = new Doodad(null, sectType, channel, + railSet, rails.size()); + result[i] = new Node(channel.getName(), channel.getArrayIndices(), + rail, tier, doodad); + } + return result; + } + + /** + * As above, but simply assumes all rails in the channel are used. + */ + public static Node[] nodesForChannel(ChannelName channel, + int tier, int sectType) { + Integer[] a = new Integer[channel.get1of()]; + for (int i = 0; i < a.length; i++) + a[i] = new Integer(i); + return nodesForChannel(channel, tier, sectType, Arrays.asList(a)); + } + + /** + * Take a Node of arbitrary type, and create an identical Node + * of type TERMINAL. + */ + public static Node makeTerminal(Node n) { + return new Node(n.getName(), n.getArrayIndices(), n.getRail(), + n.getTier(), n.getCookie()); + } + + /** + * So, maybe I made a mistake by using two completely different + * data structures to represent a node. It seemed to make sense + * at the time. Anyway, this function converts a Node to a + * NodeName. + */ + public static NodeName nodeToNodeName(Node n) { + StringBuffer buf = new StringBuffer(n.getName()); + int[] ai = n.getArrayIndices(); + + if (ai.length > 0) { + char c = '['; + for (int i = 0; i < ai.length; i++) { + buf.append(c); + buf.append(Integer.toString(ai[i])); + c = ','; + } + buf.append(']'); + } + + if (n.getRail() != Node.NO_RAIL) { + buf.append('.'); + buf.append(Integer.toString(n.getRail())); + } + + return new UnparameterizedNodeName(buf.toString()); + } + + /** + * Copies a completion tree to a WholeOperatorSink and a + * Declarations. + * @param root the root node of the completion tree + * @param wos the final completion tree is output here + * @param decl intermediate nodes are declared here + * @param reset true means add _Reset to the root node + */ + public static void emitTree(Node root, WholeOperatorSink wos, + Declarations decl, boolean reset) { + NodeName dest = nodeToNodeName(root); + NodeName[] names = new NodeName[root.size()]; + for (int i = 0; i < root.size(); i++) + names[i] = nodeToNodeName(root.get(i)); + + NodeExpression nex = null; + + switch (root.getType()) { + case Node.NOR: + if (root.getSense() == Node.ACTIVE_LOW) + nex = new NorExpression(names, reset); + else + nex = new NandExpression(names, reset); + break; + case Node.CELEMENT: + switch (root.size()) { + case 2: + nex = new CElementExpression(names[0], names[1], reset); + break; + case 3: + nex = new And2C2Expression(names[0], names[1], + names[2], reset); + break; + case 4: + nex = new TwoAnd2C2Expression(names[0], names[1], + names[2], names[3], reset); + break; + } + break; + } + + if (nex != null) { + Section sect = ((Doodad)root.getCookie()).section; + Direction dir = (root.getSense() == Node.ACTIVE_LOW ? + Direction.DOWN : Direction.UP); + WholeOperator wop = new WholeOperator(dest, nex, dir, sect); + wos.hereYaGo(wop); + decl.declareNode(root); + } + + for (int i = 0; i < root.size(); i++) + emitTree(root.get(i), wos, decl, false); + } + + /** + * Does almost everything you want with a completion tree. + * @param ops an array of arrays of nodes, where the outer array + * represents the c-element tree, and the inner arrays + * represent ors. Each inner array must contain nodes + * with the same level, but different inner arrays can have + * nodes at different levels. + * @param desiredSense desired sense of root node-- may be + * ACTIVE_HIGH or ACTIVE_LOW to be specific, + * or UNKNOWN_SENSE to accept either. + * @param wos the final completion tree is output here + * @param decl intermediate nodes are declared here + * @param reset true means add _Reset to the root node + * @param rootName the name to give the root node + * @return root node of the completion tree + */ + public static Node doCompletion(Node[][] ops, int desiredSense, + WholeOperatorSink wos, Declarations decl, + boolean reset, String rootName, + int[] rootIndex) { + // a little bit of error checking + if (ops.length == 0) + throw new IllegalArgumentException("ops.length == 0"); + for (int i = 0; i < ops.length; i++) + if (ops[i].length == 0) + throw new IllegalArgumentException("ops[" + i + + "].length == 0"); + + Node root = assignNames(shiftInvertersUp(TreeReadjuster.readjust(GreedyComplete.complete(ops, desiredSense))), rootName, rootIndex); + emitTree(root, wos, decl, reset); + return root; + } + + /** + * Same as above, but does multiple, separate completion trees at + * once. (The point of this is to share the generated node-name + * space across all completion trees.) + */ + public static void doCompletion(WholeOperatorSink wos, Declarations decl, + CompletionInfo[] info) { + Node[] unnamedRoots = new Node[info.length]; + String[] rootNames = new String[info.length]; + for (int j = 0; j < info.length; j++) { + Node[][] ops = info[j].ops; + int desiredSense = info[j].desiredSense; + + // a little bit of error checking + if (ops.length == 0) + throw new IllegalArgumentException("ops.length == 0"); + for (int i = 0; i < ops.length; i++) + if (ops[i].length == 0) + throw new IllegalArgumentException("ops[" + i + + "].length == 0"); + + unnamedRoots[j] = + TreeReadjuster.readjust(GreedyComplete.complete(ops, + desiredSense)); + unnamedRoots[j] = shiftInvertersUp(unnamedRoots[j]); + rootNames[j] = info[j].rootName; + } + + Node[] roots = assignNames(unnamedRoots, rootNames); + assert (roots.length == info.length); + + for (int j = 0; j < info.length; j++) { + emitTree(roots[j], wos, decl, info[j].reset); + info[j].root = roots[j]; + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoLogic.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoLogic.java new file mode 100644 index 0000000000..106d5866e5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/DoLogic.java @@ -0,0 +1,126 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import com.avlsi.tools.presto.ChannelName; +import com.avlsi.tools.synthesis.Espresso; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import com.avlsi.tools.presto.output.NodeName; +import com.avlsi.tools.presto.TruthTable; +import com.avlsi.tools.presto.output.UnparameterizedNodeName; + +public class DoLogic { + private DoLogic() {} // static only + + /** + * Takes the specified rail of the given TruthTable, and returns the + * minimized DNF for its pulldowns, suitable for passing to the + * downs parameter of the ArbitraryNodeExpression constructor. + * @param tt the TruthTable to use + * @param rail the rail of the TruthTable to look at + * (just as in the TruthTable interface, -1 means + * the "no output" rail) + * @param boilerplate nodes to always put in series with each disjunction + * (i. e. go or enables) + * @param dependOn on return, a bit will be set in this BitSet for + * each input that this output depends on + * @return an array (representing disjunctions) of arrays (representing + * conjunctions) of nodes + */ + public static NodeName[][] doLogic(TruthTable tt, int rail, + NodeName[] boilerplate, + BitSet dependOn) { + ArrayList exclusives = new ArrayList(); + LinkedHashSet rules = new LinkedHashSet(); + + ChannelName[] inputs = tt.getInputs(); + byte[] table = tt.getTable(); + + /* compute "values" for each input channel (thinking of table + * as being indexed by a multidigit number with varying base) */ + int value[] = new int[inputs.length]; + int v = 1; + for (int i = 0; i < value.length; i++) { + value[i] = v; + v *= inputs[i].get1of(); + } + + // detect inputs that don't matter + boolean important[] = new boolean[inputs.length]; + for (int i = 0; i < important.length; i++) + important[i] = false; + for (int i = 0; i < table.length; i++) + for (int j = 0; j < important.length; j++) { + int of = inputs[j].get1of(); + int extractedInputIndex = (i / value[j]) % of; + int newInputIndex = (extractedInputIndex + 1) % of; + int i2 = (i - (extractedInputIndex * value[j]) + + (newInputIndex * value[j])); + if ((table[i] == rail) != (table[i2] == rail)) + important[j] = true; + } + + // (now copy that into the dependOn BitSet) + for (int i = 0; i < important.length; i++) + if (important[i]) + dependOn.set(i); + + // create exclusives + String[][] inputRails = new String[inputs.length][]; + for (int i = 0; i < inputs.length; i++) { + int n = inputs[i].get1of(); + if (important[i]) { + String chname = inputs[i].getNameWithIndices(); + String[] rails = new String[n]; + for (int j = 0; j < n; j++) + rails[j] = chname + "." + j; + if (n > 1) + exclusives.add(Arrays.asList(rails)); + inputRails[i] = rails; + } + } + + // create rules + for (int i = 0; i < table.length; i++) + if (table[i] == rail) { + List nodes = new ArrayList(); + int x = i; + for (int j = 0; j < inputs.length; j++) { + int n = inputs[j].get1of(); + String[] rails = inputRails[j]; + if (important[j]) + nodes.add(rails[x % n]); + x /= n; + } + rules.add(nodes); + } + + // minimize + List optimized = + new Espresso(exclusives, new ArrayList(rules)).optimizedRules(); + + // convert result + NodeName[][] result = new NodeName[optimized.size()][]; + int i = 0; + for (Iterator it = optimized.iterator(); it.hasNext(); i++) { + List rule = (List) it.next(); + NodeName[] nodes = new NodeName[rule.size() + boilerplate.length]; + int j; + for (j = 0; j < boilerplate.length; j++) + nodes[j] = boilerplate[j]; + for (Iterator it2 = rule.iterator(); it2.hasNext(); j++) + nodes[j] = new UnparameterizedNodeName((String)it2.next()); + result[i] = nodes; + } + + return result; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Doodad.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Doodad.java new file mode 100644 index 0000000000..b37f3d13aa --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Doodad.java @@ -0,0 +1,144 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import java.util.BitSet; +import com.avlsi.tools.presto.ChannelName; +import java.util.Map; +import com.avlsi.tools.presto.complete.Node; +import com.avlsi.tools.presto.output.Section; + +/** + * Doodad is a weird little class which is used as the "cookie" for each + * Node when building the completion tree. Doodad keeps track of the + * necessary information for giving each generated node in the completion + * tree a proper name and putting it in the proper section. The + * conjugate() static method can be called from a NodeBuilder, given + * to TreeMunger.mungeTree(), to properly tag all the generated nodes in + * the tree. + */ + +public class Doodad { + public static final int IN = 1; + public static final int OUT = 2; + public static final int BOTH = 3; + public static final int EN = -1; + + public final Section section; + public final int sectType; + private final ChannelName chname; + private final BitSet railsUsed; + private final int railsPossible; + + public Doodad(Section section, int sectType, ChannelName chname, + BitSet railsUsed, int railsPossible) { + this.section = section; + this.sectType = sectType; + this.chname = chname; + this.railsUsed = railsUsed; + this.railsPossible = railsPossible; + } + + /** + * @param type The type specified to buildNode(): NOR or CELEMENT + * @param tier The tier specified to buildNode() + * @param children The child nodes specified to buildNode() + * @param temporaryNames Map(String, int[]): For each temporary name, + * maps to a one-element array which is the next + * array index to use. As a special hack, the + * array can be zero-length, in which case no + * index will be used. + * @param nameOverride If non-null, this will be used as the name + * for the new node + * @return the newly constructed node, which buildNode() should return + */ + public static Node conjugate(int type, int tier, Node[] children, + Map temporaryNames, String nameOverride, + int[] indexOverride) { + assert (children.length > 0); + Doodad[] doodads = new Doodad[children.length]; + for (int i = 0; i < children.length; i++) + doodads[i] = (Doodad) children[i].getCookie(); + + // Determine what section new node should go in + int t = 0; + for (int i = 0; i < doodads.length; i++) + t |= doodads[i].sectType; + + Section newSect; + String sectName; + switch (t) { + case IN: + newSect = SectionFactory.mkInputSection(tier); + sectName = "in"; + break; + case OUT: + newSect = SectionFactory.mkOutputTreeSection(tier); + sectName = "out"; + break; + case EN: + newSect = SectionFactory.mkEnableSection(tier); + sectName = "done"; + break; + default: + assert (t == BOTH); + newSect = SectionFactory.mkAckSection(tier); + sectName = "ack"; + break; + } + + // Determine what name of new node should be + ChannelName chname = doodads[0].chname; + BitSet railsUsed = new BitSet(); + int railsPossible = doodads[0].railsPossible; + for (int i = 0; i < doodads.length; i++) { + if (chname != doodads[i].chname) + chname = null; + railsUsed.or(doodads[i].railsUsed); + assert (railsPossible == doodads[i].railsPossible || + chname == null); + } + + String name; + int[] arrayIndices; + if (nameOverride != null) { + name = nameOverride; + arrayIndices = indexOverride; + } else if (chname == null || (children.length == 1 && + children[0].getRail() == Node.NO_RAIL)) { + name = sectName + tier; + arrayIndices = (int[]) temporaryNames.get(name); + if (arrayIndices == null) + arrayIndices = new int[] { 0 }; + if (arrayIndices.length > 0) + temporaryNames.put(name, new int[] { arrayIndices[0] + 1 }); + } else { + StringBuffer buf = new StringBuffer(chname.getName()); + while (buf.charAt(0) == '_') + buf.deleteCharAt(0); // hack to avoid extra underscores + assert (railsUsed.cardinality() <= railsPossible); + if (railsUsed.cardinality() == railsPossible) { + buf.append('v'); + } else { + for(int i = railsUsed.nextSetBit(0); i >= 0; + i = railsUsed.nextSetBit(i+1)) { + if (i > 9) + buf.append('_'); + buf.append(Integer.toString(i)); + } + } + name = buf.toString(); + arrayIndices = chname.getArrayIndices(); + } + + if ((tier & 1) == 1) + name = "_" + name; + + Doodad doodad = new Doodad(newSect, t, chname, + railsUsed, railsPossible); + return new Node(type, name, arrayIndices, tier, doodad, children); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/SectionFactory.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/SectionFactory.java new file mode 100644 index 0000000000..d08942e15e --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/SectionFactory.java @@ -0,0 +1,91 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import java.math.BigDecimal; +import com.avlsi.tools.presto.output.Direction; +import com.avlsi.tools.presto.output.Section; +import com.avlsi.tools.presto.output.SectionImpl; + +public class SectionFactory { + private static final BigDecimal INPUT = new BigDecimal("1"); + private static final BigDecimal GO = new BigDecimal("2"); + private static final BigDecimal LOGIC = new BigDecimal("3"); + private static final BigDecimal OUTPUT_INVERTERS = new BigDecimal("4"); + private static final BigDecimal OUTPUT_TREE = new BigDecimal("5"); + private static final BigDecimal CONDACK = new BigDecimal("6"); + private static final BigDecimal UNCONDACK = new BigDecimal("7"); + private static final BigDecimal POSTACK = new BigDecimal("8"); + private static final BigDecimal ENABLE = new BigDecimal("9"); + + private static final int INT_DIGITS = 10; + + private static BigDecimal field(int value, int pos) { + return new BigDecimal(Integer.toString(value)) + .movePointLeft(pos * INT_DIGITS); + } + + public static Section mkAncestorSection() { + /* We want to return a section which is less than any other section. + * (This is required by PrsPrinter.emit()) Of course, you can + * always come up with a smaller BigDecimal, but negative + * one googol is (much) more than sufficient for our needs. */ + BigDecimal id = new BigDecimal("-1").movePointRight(100); + return new SectionImpl(id, null, null, null, null, null); + } + + public static Section mkInputSection(int tier) { + BigDecimal id = INPUT.add(field(tier, 1)); + return new SectionImpl(id, null, INPUT, "input", id, "tier " + tier); + } + + public static Section mkGoSection(int channel) { + BigDecimal id = GO.add(field(channel, 1)); + return new SectionImpl(id, id, GO, "go", null, null); + } + + public static Section mkLogicSection(int channel, int rail, + Direction dir) { + BigDecimal ch = LOGIC.add(field(channel, 1)); + BigDecimal id = ch.add(field((dir == Direction.DOWN ? 0 : 1), 2)) + .add(field(rail, 3)); + return new SectionImpl(id, ch, LOGIC, "logic", null, null); + } + + public static Section mkOutputInvertersSection(int channel, int rail) { + BigDecimal id = OUTPUT_INVERTERS.add(field(channel, 1)) + .add(field(rail, 2)); + return new SectionImpl(id, null, OUTPUT_INVERTERS, + "output", null, null); + } + + public static Section mkOutputTreeSection(int tier) { + BigDecimal id = OUTPUT_TREE.add(field(tier, 1)); + return new SectionImpl(id, OUTPUT_TREE, OUTPUT_INVERTERS, + "output", id, "tier " + tier); + } + + public static Section mkCondAckSection(int channel, int line) { + BigDecimal ch = CONDACK.add(field(channel, 1)); + BigDecimal id = ch.add(field(line, 2)); + return new SectionImpl(id, ch, CONDACK, "ack", null, null); + } + + public static Section mkAckSection(int tier) { + BigDecimal id = UNCONDACK.add(field(tier, 1)); + return new SectionImpl(id, UNCONDACK, CONDACK, "ack", id, + "tier " + tier); + } + + public static Section mkPostAckSection() { + return new SectionImpl(POSTACK, null, CONDACK, "ack", null, null); + } + + public static Section mkEnableSection(int tier) { + BigDecimal id = ENABLE.add(field(tier, 1)); + return new SectionImpl(id, null, ENABLE, "enable", id, "tier " + tier); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Template.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Template.java new file mode 100644 index 0000000000..2baa549f38 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/Template.java @@ -0,0 +1,599 @@ +/* + * Copyright 2004 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import com.avlsi.tools.presto.output.AliasNodeExpression; +import com.avlsi.tools.presto.output.And2C2Expression; +import com.avlsi.tools.presto.output.ArbitraryNodeExpression; +import java.util.Arrays; +import com.avlsi.util.functions.BinaryFunction; +import java.util.BitSet; +import com.avlsi.tools.presto.output.CElementExpression; +import com.avlsi.tools.presto.ChannelName; +import com.avlsi.tools.presto.ChannelNameImpl; +import java.util.Collection; +import java.util.Collections; +import com.avlsi.util.container.CollectionUtils; +import com.avlsi.tools.presto.output.Direction; +import com.avlsi.util.container.FilteringIterator; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import com.avlsi.util.container.MultiMap; +import com.avlsi.tools.presto.output.NandExpression; +import com.avlsi.tools.presto.complete.Node; +import com.avlsi.tools.presto.output.NodeExpression; +import com.avlsi.tools.presto.output.NodeName; +import com.avlsi.util.functions.NonNull; +import com.avlsi.tools.presto.output.ParameterizedNodeName; +import com.avlsi.tools.presto.output.Section; +import java.util.Set; +import java.util.TreeSet; +import com.avlsi.tools.presto.TruthTable; +import com.avlsi.tools.presto.TruthTableImpl; +import com.avlsi.tools.presto.output.UnparameterizedNodeName; +import com.avlsi.tools.presto.WarningAccumulator; +import com.avlsi.tools.presto.output.WholeOperator; +import com.avlsi.tools.presto.output.WholeOperatorSink; + +public class Template { + private static final String prefix = "do"; + + private static Node[] condAck(ChannelName[] condGroup, + ChannelName[] allInputs, + BitSet[] dependencies, + Node[] outputCompletions) { + BitSet which = new BitSet(); + + /* If I had designed my data structures better, I wouldn't + * need to do these bizarre contortions. */ + outer_loop: + for (int i = 0; i < condGroup.length; i++) { + for (int j = 0; j < allInputs.length; j++) + if (condGroup[i] == allInputs[j]) { + which.set(j); + continue outer_loop; + } + throw new RuntimeException("internal error"); + } + + LinkedList result = new LinkedList(); + for (int i = 0; i < dependencies.length; i++) + if (which.intersects(dependencies[i])) + result.add(outputCompletions[i]); + + /* I believe this assertion is invalid, because result will + * be empty if no outputs depend on the conditional inputs. + * Yes, this is a dumb thing to do in the first place, but + * sometimes our users like to be dumb. */ + // assert (result.size() > 0); + + return (Node[]) result.toArray(new Node[0]); + } + + /** + * Groups together inputs by acknowledge condition. Note that you + * only need to give one TruthTable, because the input information is + * the same for all the TruthTables. (Yeah, this is a little weird.) + * @param tt only the getInputs() and getInputAcknowledge() matter + * @param conditionalInputs on return, there is a 1 bit for each + * conditional input + * @return MultiMap(TruthTable, ChannelName), where the TruthTable + * is the acknowledge truth table for all the given ChannelNames. + * The TruthTable is null for unconditional inputs. + */ + private static MultiMap findConditionalGroups(TruthTable tt, + BitSet conditionalInputs) { + final int[] ctr = new int[] { 0 }; + final MultiMap result = new MultiMap(new LinkedHashMap(), + MultiMap.ARRAY_LIST_FACTORY); + ChannelName[] inputs = tt.getInputs(); + for (int i = 0; i < inputs.length; i++) { + boolean[] ack = tt.getInputAcknowledge(i); + final byte[] byteAck = new byte[ack.length]; + boolean unconditional = true; + for (int j = 0; j < ack.length; j++) { + byteAck[j] = (byte)(ack[j] ? 1 : 0); + unconditional &= ack[j]; + } + ChannelName output = new ChannelName() { + private ChannelName orig = null; + + private void figureOutChannel() { + Collection c = + result.get(new TruthTableImpl(null, null, + byteAck, null)); + assert (c != null && c.size() > 0); + if (c.size() == 1) + orig = (ChannelName) c.iterator().next(); + else + orig = new ChannelNameImpl(ctr[0]++ + ":0"); + } + + public int get1of() { + return 2; + } + + public String getName() { + if (orig == null) + figureOutChannel(); + return prefix + orig.getName(); + } + + public int[] getArrayIndices() { + if (orig == null) + figureOutChannel(); + return orig.getArrayIndices(); + } + + public String getNameWithIndices() { + if (orig == null) + figureOutChannel(); + return prefix + orig.getNameWithIndices(); + } + }; + TruthTable newTruth = new TruthTableImpl(inputs, output, byteAck, + null); + result.put((unconditional ? null : newTruth), inputs[i]); + if (!unconditional) + conditionalInputs.set(i); + } + + return result; + } + + /** + * @param dependOn on return, a bit will be set in this BitSet for + * each input that this output depends on + * @return Set of Numbers, which are the rail numbers which are + * actually used. (The "no output" rail is n) + */ + private static Set doChannel(TruthTable tt, WholeOperatorSink wos, + Declarations decl, boolean go, int chnum, + boolean justEn, BitSet dependOn) { + Set result = new TreeSet(); // needs to be in numerical order + ChannelName output = tt.getOutput(); + int n = output.get1of(); + assert (n <= 1 + (int) Byte.MAX_VALUE); + + NodeName dest = + new ParameterizedNodeName("_" + output.getNameWithIndices()); + Node goNode = null; + Node _goNode = null; + NodeName goNodeName = null; + NodeName _goNodeName = null; + NodeName re = + new UnparameterizedNodeName(output.getNameWithIndices() + ".e"); + NodeName[] boilerplate = + new NodeName[] { new UnparameterizedNodeName("en") }; + NodeName[] unconditionalBoilerplate; + + if (go) { + goNode = new Node("go" + output.getName(), + output.getArrayIndices(), Node.NO_RAIL, 2, null); + _goNode = new Node("_go" + output.getName(), + output.getArrayIndices(), + Node.NO_RAIL, 1, null); + decl.declareNode(goNode); + decl.declareNode(_goNode); + goNodeName = DoCompletion.nodeToNodeName(goNode); + _goNodeName = DoCompletion.nodeToNodeName(_goNode); + unconditionalBoilerplate = new NodeName[] { goNodeName }; + boilerplate = unconditionalBoilerplate; + } else if (justEn) { + unconditionalBoilerplate = boilerplate; + } else { + unconditionalBoilerplate = new NodeName[] { boilerplate[0], re }; + } + + // loop over all rails + for (int i = -1; i < n; i++) { + NodeName[][] downs = DoLogic.doLogic(tt, i, boilerplate, dependOn); + int rail = i < 0 ? n : i; + if (downs.length > 0) + result.add(new Integer(rail)); + if (downs.length > 0 || i >= 0) { + NodeName[][] ups = new NodeName[][] { boilerplate }; + NodeExpression expr = new ArbitraryNodeExpression(ups, downs); + Section downSection = + SectionFactory.mkLogicSection(chnum, rail, Direction.DOWN); + Section upSection = + SectionFactory.mkLogicSection(chnum, rail, Direction.UP); + WholeOperator wop = new WholeOperator(dest, expr, rail, + Direction.DOWN, + upSection, downSection); + wos.hereYaGo(wop); + } + boilerplate = unconditionalBoilerplate; + } + + // emit go if needed + if (go) { + Section goSection = SectionFactory.mkGoSection(chnum); + boolean conditional = result.contains(new Integer(n)); + NodeName le = new UnparameterizedNodeName("le"); + NodeExpression _goExpr; + if (conditional) + _goExpr = new And2C2Expression(dest, re, le, false); + else + _goExpr = new CElementExpression(le, re, false); + WholeOperator _goWop = new WholeOperator(_goNodeName, _goExpr, n, + Direction.DOWN, + goSection); + wos.hereYaGo(_goWop); + NodeExpression goExpr = + new NandExpression(new NodeName[] { _goNodeName }, false); + WholeOperator goWop = new WholeOperator(goNodeName, goExpr, + Direction.UP, goSection); + wos.hereYaGo(goWop); + } + + return result; + } + + /** + * Takes the given array of TruthTables (one for each output) and + * produces a precharged half-buffer cell for it. + * @param tt an array one TruthTables, one for each output + * @param wos the production rules are sent here + * @param decl the internal declarations are sent here + * @param go a Set(String), if an output channel is in this + * set, it gets a go signal + * @param cycle_node the name of the enable of an unconditional + * channel gets written here + * @param wacc warnings are issued through this object + * @return the ntpc spec of the generated cell + */ + public static int doTemplate(TruthTable[] tt, WholeOperatorSink wos, + Declarations decl, Set go, + StringBuffer cycle_node, + WarningAccumulator wacc) { + BitSet conditionalInputs = new BitSet(); + MultiMap inputGroups = findConditionalGroups(tt[0], conditionalInputs); + Collection unconditional = inputGroups.get(null); + if (unconditional == null) { + wacc.warn("warning: no unconditional inputs... this " + + "might not work"); + unconditional = Collections.EMPTY_SET; + } else { + ChannelName foo = (ChannelName) unconditional.iterator().next(); + cycle_node.append(foo.getNameWithIndices()); + cycle_node.append(".e"); + } + + LinkedList completion = new LinkedList(); + boolean nogo = false; + boolean yesgo = false; + + // add input channels to completion + for (Iterator it = unconditional.iterator(); it.hasNext(); ) + completion.add(DoCompletion.nodesForChannel((ChannelName)it.next(), + 0, Doodad.IN)); + + /* Note to self: "truths" is a list of all truth tables-- + * first the output truth tables (same as "tt" array) and then + * the conditional input acknowledge truth tables. */ + LinkedList truths = new LinkedList(); + truths.addAll(Arrays.asList(tt)); + CollectionUtils + .addAll(truths, + new FilteringIterator(inputGroups.keySet().iterator(), + new NonNull())); + + // do logic and inverters + BitSet[] dependencies = new BitSet[truths.size()]; + Node[] ciOutputCompletions = new Node[truths.size()]; + int i = 0; + for (Iterator it = truths.iterator(); it.hasNext(); i++) { + dependencies[i] = new BitSet(); + /* "isCondition" indicates this is a conditon for a + * conditional input. (i. e. doL) The boolean "conditional" + * (below), indicates this is a conditional *output*. */ + boolean isCondition = (i >= tt.length); + TruthTable theTruth = (TruthTable) it.next(); + final ChannelName output = theTruth.getOutput(); + boolean goNow = go.contains(output.getNameWithIndices()); + if (goNow) + yesgo = true; + else + nogo = true; + if (theTruth.getOutput().get1of() > 128) + wacc.warn("Warning: channels larger than e1of128 not supported"); + Set railsUsed = doChannel(theTruth, wos, decl, goNow, i, + isCondition, dependencies[i]); + final boolean conditional = + railsUsed.contains(new Integer(output.get1of())); + ChannelName underscore_channel = new ChannelName() { + public int get1of() { + int n = output.get1of(); + if (conditional) + n++; + return n; + } + + public String getName() { + return "_" + output.getName(); + } + + public int[] getArrayIndices() { + return output.getArrayIndices(); + } + + public String getNameWithIndices() { + return "_" + output.getNameWithIndices(); + } + }; + /* Declare the _R channel. And for conditional input conditions, + * also declare the R channel, since it is not in the portlist. */ + decl.declareChannel(underscore_channel, Declarations.CH_1of); + if (isCondition) + decl.declareChannel(output, Declarations.CH1of); + + boolean isOutputThatDependsOnConditionalInput = + dependencies[i].intersects(conditionalInputs); + Node[] nfc = DoCompletion.nodesForChannel(underscore_channel, + 1, Doodad.OUT, + railsUsed); + if (isOutputThatDependsOnConditionalInput) { + /* For an output that depends on a conditional input, create + * its own tiny little completion tree, so we know it + * isn't mixed in with some 2and2c2 or something, and so + * we know it ends on a positive sense. (For 1of5s or less, + * this will just result in a single NAND gate.) We remember + * this node for later use, and then feed it into the + * main completion tree. */ + Node[][] ops = new Node[][] { nfc }; + Node rv = DoCompletion.doCompletion(ops, Node.ACTIVE_HIGH, + wos, decl, false, + output.getName() + "v", + output.getArrayIndices()); + ciOutputCompletions[i] = rv; + completion.add(new Node[] {DoCompletion.makeTerminal(rv)}); + } else { + /* Add the rails of this channel (minus unused ones) to the + * nodes that need to go into the completion tree. */ + completion.add(nfc); + } + + NodeName underscore_node = new + ParameterizedNodeName(underscore_channel.getNameWithIndices()); + NodeName output_node = new + ParameterizedNodeName(output.getNameWithIndices()); + NodeExpression expr = + new NandExpression(new NodeName[] { underscore_node }, false); + for (int j = 0; j < output.get1of(); j++) { + Section sec = SectionFactory.mkOutputInvertersSection(i, j); + WholeOperator wop = + new WholeOperator(output_node, expr, j, Direction.UP, sec); + wos.hereYaGo(wop); + } + } + + // warn about inputs that nothing depends on + ChannelName[] inputs = tt[0].getInputs(); + for (int j = 0; j < inputs.length; j++) { + boolean used = false; + for (int k = 0; k < dependencies.length; k++) + used |= dependencies[k].get(j); + if (!used) { + wacc.warn("Warning: No outputs depend on " + + inputs[j].getNameWithIndices() + "."); + wacc.warn(" You might as well just " + + "bitbucket it. You should strongly"); + wacc.warn(" reconsider whether this is " + + "really what you want."); + } + } + + // warn about outputs that depend on nothing + assert tt.length <= dependencies.length; + for (int j = 0; j < tt.length; j++) { + boolean depends = false; + for (int k = 0; k < inputs.length; k++) + depends |= dependencies[j].get(k); + if (!depends) { + wacc.warn("Warning: " + + tt[j].getOutput().getNameWithIndices() + + " does not depend on any inputs."); + wacc.warn(" You might as well just " + + "bitgenerate it. You should strongly"); + wacc.warn(" reconsider whether this is " + + "really what you want."); + } + } + + // do completion tree + CompletionInfo[] cinfo = + new CompletionInfo[inputGroups.keySet().size()]; + i = 0; + for (Iterator it = inputGroups.keySet().iterator(); + it.hasNext(); i++) { + TruthTable theTruth = (TruthTable)it.next(); + Collection comp; + if (theTruth == null) { + comp = completion; + } else { + comp = new LinkedList(); + Collection channels = (Collection) inputGroups.get(theTruth); + for (Iterator it2 = channels.iterator(); it2.hasNext(); ) + comp.add(DoCompletion.nodesForChannel((ChannelName) + it2.next(), + 0, Doodad.IN)); + } + assert (comp.size() > 0); + cinfo[i] = new CompletionInfo((Node[][])comp + .toArray(new Node[0][]), + Node.ACTIVE_HIGH, (theTruth == null), + (theTruth == null ? "la" : null)); + } + DoCompletion.doCompletion(wos, decl, cinfo); + Node ctreeRoot = null; + LinkedHashMap inputCompletions = new LinkedHashMap(); + i = 0; + for (Iterator it = inputGroups.keySet().iterator(); + it.hasNext(); i++) { + TruthTable theTruth = (TruthTable)it.next(); + Node root = cinfo[i].root; + if (theTruth == null) + ctreeRoot = root; + else + inputCompletions.put(theTruth, root); + } + assert (ctreeRoot != null); + + // do ack for each conditional input group + Doodad enableDoodad = new Doodad(null, Doodad.EN, null, + new BitSet(), 1); + LinkedList doneMaker = new LinkedList(); + boolean warnN = false; + boolean hasConditionalInputs = false; + i = 0; + for (Iterator it = + new FilteringIterator(inputGroups.keySet().iterator(), + new NonNull()); it.hasNext(); i++) { + TruthTable theTruth = (TruthTable)it.next(); + Collection channels = (Collection) inputGroups.get(theTruth); + + Node[] positiveR = condAck((ChannelName[]) + channels.toArray(new ChannelName[0]), + tt[0].getInputs(), dependencies, + ciOutputCompletions); + + int positiveRtier = 0; + for (int j = 0; j < positiveR.length; j++) + if (positiveR[j].getTier() > positiveRtier) + positiveRtier = positiveR[j].getTier(); + + if (positiveR.length > 4) + warnN = true; + + ChannelName ch = theTruth.getOutput(); + String name = ch.getName(); + int[] indices = ch.getArrayIndices(); + String basename = name.substring(prefix.length()); + String __ename = "__" + basename + "e"; + String _ename = "_" + basename + "e"; + String ename = basename + "e"; + if (Character.isDigit(ename.charAt(0))) { + assert indices.length == 0; + ename = "\"" + ename + "\""; + } + Node do0node = new Node(name, indices, 0, positiveRtier, + enableDoodad); + Node do1node = new Node(name, indices, 1, positiveRtier, null); + Node __enode = new Node(__ename, indices, Node.NO_RAIL, + positiveRtier + 1, null); + Node _enode = new Node(_ename, indices, Node.NO_RAIL, + positiveRtier + 2, enableDoodad); + Node enode = new Node(ename, indices, Node.NO_RAIL, + positiveRtier + 3, null); + NodeName do1 = DoCompletion.nodeToNodeName(do1node); + NodeName __e = DoCompletion.nodeToNodeName(__enode); + NodeName _e = DoCompletion.nodeToNodeName(_enode); + NodeName e = DoCompletion.nodeToNodeName(enode); + Node inputCompletion = (Node) inputCompletions.get(theTruth); + NodeName lv = DoCompletion.nodeToNodeName(inputCompletion); + LinkedList pulldown = new LinkedList(); + pulldown.add(do1); + pulldown.add(lv); + int fixed = pulldown.size(); + LinkedList pulldowns = new LinkedList(); + + for (int j = 0; j < positiveR.length; j++) + pulldown.add(DoCompletion.nodeToNodeName(positiveR[j])); + pulldowns.add(pulldown.toArray(new NodeName[0])); + decl.declareNode(__enode); + decl.declareNode(_enode); + decl.declareNode(enode); + NodeName[] pu = new NodeName[] { do1, lv }; + NodeName[][] pd = (NodeName[][]) + pulldowns.toArray(new NodeName[0][]); + ArbitraryNodeExpression expr = + new ArbitraryNodeExpression(new NodeName[][] { pu }, pd); + Section downSect = SectionFactory.mkCondAckSection(i, 0); + Section upSect = SectionFactory.mkCondAckSection(i, 1); + Section sect = SectionFactory.mkCondAckSection(i, 2); + wos.hereYaGo(new WholeOperator(__e, expr, Direction.DOWN, + upSect, downSect)); + wos.hereYaGo(new WholeOperator(_e, + new NandExpression(new NodeName[] + { __e }, true), Direction.UP, + sect)); + wos.hereYaGo(new WholeOperator(e, + new NandExpression(new NodeName[] + { _e }, false), Direction.DOWN, + sect)); + Section aliasSect = SectionFactory.mkCondAckSection(i, 3); + for (Iterator it2 = channels.iterator(); it2.hasNext(); ) { + ChannelName theChannel = (ChannelName) it2.next(); + NodeName aliasMe = + new UnparameterizedNodeName(theChannel.getNameWithIndices() + + ".e"); + wos.hereYaGo(new WholeOperator(aliasMe, + new AliasNodeExpression(e, 0), + Direction.DOWN, aliasSect)); + } + doneMaker.add(new Node[] { _enode, do0node }); + hasConditionalInputs = true; + } + + if (hasConditionalInputs && yesgo) { + wacc.warn("Warning: conditional inputs do not work " + + "with go signal"); + } + + if (warnN) { + wacc.warn("Warning: more than 6 Ns in series in the " + + "conditional acknowledge"); + wacc.warn(" You will need to fix this up " + + "manually."); + } + + // add enable, if needed + Node lenode = new Node("le", new int[0], Node.NO_RAIL, + ctreeRoot.getTier() + 1, enableDoodad); + NodeName le = DoCompletion.nodeToNodeName(lenode); + int halfHandshake = 2 + lenode.getTier(); + decl.declareNode(lenode); + doneMaker.add(new Node[] { lenode }); + if (nogo) { + Node[][] ops = (Node[][]) doneMaker.toArray(new Node[0][]); + Node _en = DoCompletion.doCompletion(ops, Node.ACTIVE_HIGH, + wos, decl, false, "_en", + new int[0]); + NodeName en = new UnparameterizedNodeName("en"); + decl.declareNode(new Node("en", new int[0], + Node.NO_RAIL, 1, null)); + Section sect = SectionFactory.mkEnableSection(1 + _en.getTier()); + NodeExpression expr = + new NandExpression(new NodeName[] + { DoCompletion.nodeToNodeName(_en) }, false); + WholeOperator wop = + new WholeOperator(en, expr, Direction.DOWN, sect); + wos.hereYaGo(wop); + halfHandshake = 1 + _en.getTier(); + } + + // do that final inverter + NodeName la = DoCompletion.nodeToNodeName(ctreeRoot); + Section sect = SectionFactory.mkAckSection(ctreeRoot.getTier() + 1); + NodeExpression expr = new NandExpression(new NodeName[] { la }, false); + WholeOperator wop = new WholeOperator(le, expr, Direction.DOWN, sect); + wos.hereYaGo(wop); + + // alias left enables together + Section postAck = SectionFactory.mkPostAckSection(); + NodeExpression leAlias = new AliasNodeExpression(le, 0); + for (Iterator it = unconditional.iterator(); it.hasNext(); ) { + ChannelName ch = (ChannelName) it.next(); + String e = ch.getNameWithIndices() + ".e"; + wos.hereYaGo(new WholeOperator(new UnparameterizedNodeName(e), + leAlias, Direction.UP, postAck)); + } + + return 2 * halfHandshake; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/TestOutput.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/TestOutput.java new file mode 100644 index 0000000000..2a83b9ab44 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/template/TestOutput.java @@ -0,0 +1,110 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +package com.avlsi.tools.presto.template; + +import com.avlsi.tools.presto.output.ArbitraryNodeExpression; +import com.avlsi.tools.presto.output.CElementExpression; +import com.avlsi.tools.presto.ChannelNameImpl; +import com.avlsi.tools.presto.output.Direction; +import com.avlsi.tools.presto.output.NandExpression; +import com.avlsi.tools.presto.complete.Node; +import com.avlsi.tools.presto.output.NodeName; +import com.avlsi.tools.presto.output.NorExpression; +import com.avlsi.tools.presto.output.Organizer; +import java.io.OutputStreamWriter; +import com.avlsi.tools.presto.output.ParameterizedNodeName; +import java.io.PrintWriter; +import com.avlsi.tools.presto.output.PrsPrinter; +import com.avlsi.tools.presto.output.UnparameterizedNodeName; +import com.avlsi.tools.presto.output.WholeOperator; + +public class TestOutput { + private static Node mkNode(String name) { + return new Node(name, new int[0], Node.NO_RAIL, 0, null); + } + + public static void main(String[] argv) { + Organizer org = new Organizer(); + + org.hereYaGo(new WholeOperator(new UnparameterizedNodeName("_lv"), + new NorExpression(new NodeName[] { + new UnparameterizedNodeName("L.0"), + new UnparameterizedNodeName("L.1") + }, false), Direction.DOWN, + SectionFactory.mkInputSection(0))); + + org.hereYaGo(new WholeOperator(new UnparameterizedNodeName("lv"), + new NandExpression(new NodeName[] { + new UnparameterizedNodeName("_lv") + }, false), Direction.UP, + SectionFactory.mkInputSection(1))); + + for (int i = 0; i < 2; i++) { + org.hereYaGo(new WholeOperator(new ParameterizedNodeName("R"), + new NandExpression(new NodeName[] { + new ParameterizedNodeName("_r") + }, false), i, Direction.UP, + SectionFactory.mkOutputInvertersSection(0,i))); + NodeName[] downs = new NodeName[] { new UnparameterizedNodeName("L.e"), + new UnparameterizedNodeName("R.e"), + new ParameterizedNodeName("L") }; + NodeName[] ups = new NodeName[] { new UnparameterizedNodeName("L.e"), + new UnparameterizedNodeName("R.e") }; + org.hereYaGo(new WholeOperator(new ParameterizedNodeName("_r"), + new ArbitraryNodeExpression(new NodeName[][] {ups}, + new NodeName[][] {downs}), + i, Direction.DOWN, + SectionFactory.mkLogicSection(0,i,Direction.UP), + SectionFactory.mkLogicSection(0,i,Direction.DOWN))); + } + + org.hereYaGo(new WholeOperator(new UnparameterizedNodeName("rv"), + new NandExpression(new NodeName[] { + new UnparameterizedNodeName("_r.0"), + new UnparameterizedNodeName("_r.1") + }, false), Direction.UP, + SectionFactory.mkOutputTreeSection(1))); + + org.hereYaGo(new WholeOperator(new UnparameterizedNodeName("__le"), + new CElementExpression(new UnparameterizedNodeName("lv"), + new UnparameterizedNodeName("rv"), + false), Direction.DOWN, + SectionFactory.mkAckSection(2))); + + org.hereYaGo(new WholeOperator(new UnparameterizedNodeName("_le"), + new NandExpression(new NodeName[] { + new UnparameterizedNodeName("__le") + }, true), Direction.UP, + SectionFactory.mkAckSection(3))); + + org.hereYaGo(new WholeOperator(new UnparameterizedNodeName("L.e"), + new NorExpression(new NodeName[] { + new UnparameterizedNodeName("_le") + }, false), Direction.DOWN, + SectionFactory.mkAckSection(4))); + + PrsPrinter p = new PrsPrinter(); + org.simplify(p); + PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out)); + DeclarationsImpl decl = new DeclarationsImpl(); + decl.declareNode(mkNode("_lv")); + decl.declareNode(mkNode("lv")); + decl.declareNode(mkNode("rv")); + decl.declareNode(mkNode("__le")); + decl.declareNode(mkNode("_le")); + decl.declareChannel(new ChannelNameImpl("_r:2"), Declarations.CH_1of); + w.println("define PCHBUF_1of2 ()(e1of2 -L,+R) <: PCHB(2) {"); + w.println(" prs {"); + w.println(" // 14 transitions/cycle"); + // w.println(" node _lv,lv,rv,__le,_le;"); + // w.println(" _1of2 _r;"); + decl.emit(w, 4, 78); + p.emit(w, 4, 4, 40, SectionFactory.mkAncestorSection()); + w.println(" }"); + w.println("}"); + w.flush(); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-one-cell.pl b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-one-cell.pl new file mode 100755 index 0000000000..989a4a7086 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-one-cell.pl @@ -0,0 +1,103 @@ +#!/usr/intel/bin/perl -w + +use strict; +use vars qw($Logfile $Cell $Dir $TmpDir $CastPath $Version $PrsBlock + $HtmlFile $Transitions $Rules); + +use FindBin; +use Getopt::Long; +use POSIX; + +# On stdout, outputs tuple of: +# version|cellname|status|transitions|rules + +$CastPath = "/home/user/ppelleti/clients/ppelleti_microarch/hw/cast"; # FIXME! +$Logfile = "/dev/null"; + +GetOptions("logfile=s", \$Logfile) or die; + +$Cell = $ARGV[0]; +$Dir = $FindBin::Bin; + +$TmpDir = POSIX::tmpnam(); + +mkdir $TmpDir or die; + +open S, "$Dir/test.cast" or die; +open D, ">$TmpDir/test.cast" or die; + +$Version = "unknown"; +$PrsBlock = ""; + +my $foundit = 0; +while() { + $foundit = 1 if (/^define\s+$Cell\W/); + if ($foundit and /^\s*env\s+\{/) { + open P, "presto --cast-path=$Dir:$CastPath --cell=test.$Cell |" or die; + my $old_ = $_; + while (

    ) { + print D $_; + $PrsBlock .= $_; + $Version = $1 if (/PReSto of (.*?)\./); + } + close P; + $_ = $old_; + print D "\n"; + $foundit = 0; + } + print D $_; +} + +close D; +close S; + +open P, "jdsim-auto --cast-path=$TmpDir:$CastPath --cell=test.$Cell --basedir=$TmpDir 2>&1 |" or die; + +my $lastline = "error"; +while (

    ) { + chomp; + $lastline = $_; +} +close P; + +$HtmlFile = "$TmpDir/modules/test/$Cell.html"; + +open S, "$HtmlFile" or die; +open D, ">>$Logfile" or die; + +print D "

    PRS for $Cell

    \n";
    +$PrsBlock =~ s/\&/\&/g;
    +$PrsBlock =~ s/\/\>/g;
    +print D $PrsBlock;
    +print D "
    \n"; + +my $output = 0; +while () { + $output = 0 if (m%%i); + s/]+>//i; + s%%%i; + print D $_ if ($output); + $output = 1 if (/ END OF NAVBAR /); +} + +close D; +close S; + +$Transitions = "unknown"; +$Rules = "unknown"; + +open P, "lynx -dump -nolist $HtmlFile |" or die; +while (

    ) { + $Transitions = $& if (/[\d\.]+t/); + $Rules = $1 if (/\#Rules\s+(\d+)/); +} +close P; + +unlink $HtmlFile or die; +unlink "$TmpDir/test.cast" or die; +rmdir "$TmpDir/modules/test" or die; +rmdir "$TmpDir/modules" or die; +rmdir $TmpDir or die; + +print "$Version|$Cell|$lastline|$Transitions|$Rules\n"; diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-summary.txt b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-summary.txt new file mode 100644 index 0000000000..9bc73b8537 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test-summary.txt @@ -0,0 +1,7 @@ +02/09/03|PRODUCER_SRAM_CTRL|Passed|14.044995t|44 +02/09/03|BUG_1909|Passed|11.969937t|20 +02/09/03|BUG_1930|Passed|11.990164t|25 +02/09/03|FOO|Passed|10.064415t|21 +02/09/03|JTAG_SHIFT_CELL_PRESTO|Passed|18.023108t|82 +02/09/03|MODIFY_VALID|Passed|17.981096t|66 +02/09/03|ADP_IN_CTRL1|Passed|17.99921t|62 diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.cast b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.cast new file mode 100644 index 0000000000..266d0cacce --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.cast @@ -0,0 +1,217 @@ +/* + * Copyright 2003 Fulcrum Microsystems. All rights reserved. + * $Id$ + */ + +module test; + +/********** bug 1890 **********/ + +// Computes the control for the filter and sram rw +// Truth table: +// INDEX OVERFLOW RWA_FILTER_CTRL W_FILTER_CTRL +// 0 0 1 1 +// 0 1 0 0 +// 1 0 1 - +// 1 1 1 - +// RWA_FILTER_CTRL is the control for filter on RW and A ports of SRAM +// W_FILTER_CTRL is the control for filter on W port of SRAM +define PRODUCER_SRAM_CTRL ()(e1of2 -INDEX; + e1of2 -OVERFLOW; + e1of2 +RWA_FILTER_CTRL; + e1of2 +W_FILTER_CTRL) + <: LEAF { + csp { + *[INDEX?index, OVERFLOW?overflow; + RWA_FILTER_CTRL!((index == 1) | (overflow == 0)); + [ index == 0 -> W_FILTER_CTRL!(overflow == 0) + []index == 1 -> skip + ]] + } + + env { + digital { + subcells { + rsource_e1of2 _(INDEX); + rsource_e1of2 _(OVERFLOW); + bitbucket_e1of2 _(RWA_FILTER_CTRL); + bitbucket_e1of2 _(W_FILTER_CTRL); + } + directives { + ntpc_spec(RWA_FILTER_CTRL.e)=14; + } + } + } +} + +/********** bug 1909 **********/ + +define BUG_1909 ()(e1of2 -L; e1of1 +R) <: LEAF { + csp { + boolean x; + + *[L?x; [x -> R! [] else -> skip]] + } + + env { + digital { + subcells { + rsource_e1of2 _(L); + bitbucket_e1of1 _(R); + } + directives { + ntpc_spec(L.e)=12; + } + } + } +} + +/********** bug 1930 **********/ + +define BUG_1930 ()(e1of2 -L; e1of3 +R) <: LEAF { + csp { + boolean x; + + *[L?x; [x -> R!0 [] else -> R!2]] + } + + env { + digital { + subcells { + rsource_e1of2 _(L); + bitbucket_e1of3 _(R); + } + directives { + ntpc_spec(R.e)=12; + } + } + } +} + +/********** bug 1976 **********/ + +define FOO()(e1of2 -L, +R) <: LEAF { + csp { + *[L?, R!0] + } + + env { + digital { + subcells { + rsource_e1of2 _(L); + bitbucket_e1of2 _(R); + } + directives { + ntpc_spec(R.e)=10; + } + } + } +} + +/********** bug 2037 **********/ + +define JTAG_SHIFT_CELL_PRESTO ()(e1of2 -LS; + e1of3 -LC; + e1of2 -PL; + e1of2 -STATEIN; + e1of2 +RS; + e1of3 +RC; + e1of2 +PO; + e1of2 +STATEOUT) <: LEAF { + csp { + // Temporary variables + int val; + int cmd; + + // Constants + int SHIFT=0, PLOAD=1, POUT=2; + + *[ STATEIN?val, LC?cmd, LS?val_ls, PL?val_pl; RC!cmd; + [ cmd==SHIFT -> RS!val; val=val_ls + []cmd==PLOAD -> val=val_pl + []cmd==POUT -> PO!val + ]; + STATEOUT!val + ] + } + + env { + digital { + subcells { + rsource_e1of2 _(LS); + rsource_e1of3 _(LC); + rsource_e1of2 _(PL); + rsource_e1of2 _(STATEIN); + bitbucket_e1of2 _(RS); + bitbucket_e1of3 _(RC); + bitbucket_e1of2 _(PO); + bitbucket_e1of2 _(STATEOUT); + } + directives { + ntpc_spec(STATEOUT.e)=18; + } + } + } +} + +/********** a couple of nice big cells **********/ + +define MODIFY_VALID ()(e1of6 -LA; e1of2 -LV; e1of6 +RA; e1of2 +RV) <:LEAF { + csp { + int a; + boolean v; + + *[LA?a, LV?v; + [ a == 2 -> RA!2, RV!v + []a == 4 & v -> RA!2, RV!v + []a == 0 & v -> RA!4, RV!v + [](a == 4 | a == 0) & ~v -> RA!0, RV!true + []a == 3 -> RA!3, RV!v + []a == 5 & ~v -> RA!2, RV!v + []a == 1 & ~v -> RA!5, RV!v + [](a == 5 | a == 1) & v -> RA!1, RV!false + ] + ] + } + + env { + digital { + subcells { + rsource_e1of6 _(LA); + rsource_e1of2 _(LV); + bitbucket_e1of6 _(RA); + bitbucket_e1of2 _(RV); + } + directives { + ntpc_spec(RA.e)=18; + } + } + } +} + +define ADP_IN_CTRL1 ()(e1of4 -L; e1of2 +R; e1of3 +G; e1of2 +B) <: LEAF { + csp { + int byteAddr; + + *[L?byteAddr; + [ byteAddr == 0 -> R!0, G!0 + []byteAddr == 1 -> R!0, G!2, B!0 + []byteAddr == 2 -> R!1, G!1, B!1 + []byteAddr == 3 -> R!1, G!1, B!1 ] + ] + } + + env { + digital { + subcells { + rsource_e1of4 _(L); + bitbucket_e1of2 _(R); + bitbucket_e1of3 _(G); + bitbucket_e1of2 _(B); + } + directives { + ntpc_spec(R.e)=18; + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.pl b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.pl new file mode 100755 index 0000000000..647553c42c --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/presto/test.pl @@ -0,0 +1,47 @@ +#!/usr/intel/bin/perl -w + +use strict; +use vars qw($Dir $File @Cells $Logfile $GoodTidy); + +use FindBin; + +$Dir = $FindBin::Bin; + +$File = "$Dir/test.cast"; + +# I laugh in the face of memo 28 +$GoodTidy = "/home/user/ppelleti/local/bin/tidy"; + +@Cells = (); + +open F, $File or die; +while () { + push @Cells, $1 if (/^define\s+(\w+)/); +} +close F; + +my $n = $#Cells + 1; +print STDERR "Doing $n cells\n"; + +$Logfile = "$Dir/log.html"; +open F, ">$Logfile" or die; +print F "PReSto test results\n"; +close F; + +my $first = 1; +my $cell; +foreach $cell (@Cells) { + if (not $first) { + open F, ">>$Logfile" or die; + print F "


    \n"; + close F; + } + system("$Dir/test-one-cell.pl --logfile=$Logfile $cell"); + $first = 0; +} + +open F, ">>$Logfile" or die; +print F "\n"; +close F; + +system("$GoodTidy -f /dev/null -mcq $Logfile"); diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/AbstractConverter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/AbstractConverter.java new file mode 100644 index 0000000000..2e488707e4 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/AbstractConverter.java @@ -0,0 +1,594 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.TreeMap; + +import com.avlsi.cast.impl.Value; +import com.avlsi.cast.impl.ArrayValue; +import com.avlsi.cast.impl.FloatValue; +import com.avlsi.cast.impl.IntValue; +import com.avlsi.cast.impl.InvalidOperationException; +import com.avlsi.cast.impl.InstanceValue; +import com.avlsi.cast.impl.NodeValue; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.UnknownDirectiveException; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.CellType; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.fast.VerilogBlock; +import com.avlsi.fast.ports.ArrayType; +import com.avlsi.fast.ports.ChannelType; +import com.avlsi.fast.ports.NodeType; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.fast.ports.PortTypeInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.tools.prs2verilog.ConverterInterface; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryFunction; + +public abstract class AbstractConverter implements ConverterInterface { + protected static final String libPrefix = "lib.verilog"; + protected final VerilogFactoryInterface factory; + protected Map nodes, not; + protected List wireDecl, items, inout; + protected int wireId; + protected final boolean mAlwaysEscape; + protected int primitiveCount = 0; + + /** + * A map from cell (CellInterface) to files + * (String[]) that is depended on by the verilog block choosen + * for that cell. + **/ + protected final Map/**/ depends; + + protected final static String PRS2VERILOG_TAU = "PRS2VERILOG_TAU"; + protected final static String PRS2VERILOG_DELAY_SCALE = "PRS2VERILOG_DELAY_SCALE"; + + public static VerilogObject[] toArray(final Collection l) { + return (VerilogObject[]) l.toArray(new VerilogObject[0]); + } + + protected AbstractConverter(final VerilogFactoryInterface factory, + boolean alwaysEscape ) { + this.factory = factory; + this.nodes = new HashMap(); + this.not = new HashMap(); + this.wireDecl = new ArrayList(); + this.items = new ArrayList(); + this.inout = new ArrayList(); + this.wireId = 0; + mAlwaysEscape = alwaysEscape; + this.depends = new HashMap(); + } + public VerilogObject newNet(final String type) { + final String name = "PRS2VERILOG_internal_" + wireId++; + final VerilogObject ident = factory.ident(name, mAlwaysEscape); + wireDecl.add(factory.netDecl(type, ident, null)); + return ident; + } + private VerilogObject find(final DirectiveBlock db, + final String key, + final String type, + final String param) { + Object o = null; + try { + o = db.lookup(key, type, param); + } catch (UnknownDirectiveException e) { + Debug.assertTrue(false, "Unknown directive: " + key); + } + Debug.assertTrue(o != null, "Directive " + key + "(" + param + ":" + type + ") is null."); + String s = o.toString(); + if (o instanceof String) s = "\"" + s + "\""; + return factory.expr(s); + } + private VerilogObject[] source(final String inst, final DirectiveBlock db) { + ArrayList param = new ArrayList(4); + param.add(find(db, "infile", "string", inst)); + param.add(find(db, "memsize", "string", inst)); + param.add(find(db, "data_set", "string", inst)); + param.add(find(db, "data_reset", "string", inst)); + return toArray(param); + } + private VerilogObject[] sink(final String inst, final DirectiveBlock db) { + ArrayList param = new ArrayList(4); + param.add(find(db, "outfile", "string", inst)); + param.add(find(db, "enable_set", "string", inst)); + param.add(find(db, "enable_reset", "string", inst)); + return toArray(param); + } + protected VerilogObject[] getModuleParameter(final ConnectionInfo ci) { + final String type = ci.child.cast_cell.getFullyQualifiedType(); + if (type.indexOf(libPrefix) == -1) return null; + final String inst = ci.nameInParent.getCadenceString(); + final CellInterface c = ci.parent.cast_cell; + final BlockIterator bi = + c.getBlockInterface().iterator(BlockInterface.DIRECTIVE); + if (!bi.hasNext()) return null; + final DirectiveBlock db = (DirectiveBlock) bi.next(); + if (type.indexOf("SOURCE") != -1) return source(inst, db); + else if (type.indexOf("SINK") != -1) return sink(inst, db); + else return null; + } + protected VerilogObject lookupNode(final HierName node, final String type) { + return lookupNode(node.getCadenceString(), type); + } + protected VerilogObject lookupNode(final String node, final String type) { + return lookupNode(node, type, null); + } + protected VerilogObject lookupNode(final String node, final String type, + final VerilogObject delay) { +/* + if (excludeNodes.containsKey(node)) { + return factory.ident((String) excludeNodes.get(node), true); + } +*/ + if (!nodes.containsKey(node)) { + final VerilogObject ident = factory.ident(node, mAlwaysEscape); + wireDecl.add(factory.netDecl(type, ident, delay)); + nodes.put(node, ident); + } + return (VerilogObject) nodes.get(node); + } + protected VerilogObject lookupNot(final HierName node, final String type) { + return lookupNot(node.getCadenceString(), type); + } + protected VerilogObject lookupNot(final String node, final String type) { + if (!not.containsKey(node)) { + final VerilogObject wire = lookupNode(node, type); + final VerilogObject[] args = new VerilogObject[2]; + args[0] = newNet("wire"); + args[1] = wire; + items.add(factory.primitive("not", null, nextPrimitive(), args)); + not.put(node, args[0]); + } + return (VerilogObject) not.get(node); + } + private Collection ports(final ConnectionInfo ci) { + final Map map = new TreeMap(); + for (ConnectionInfo.NameIterator it = ci.childIterator(); + it.hasNext(); ) { + HierName port = (HierName) it.next(); + CellNet net = ci.child.getNet(port); + //if (excludeNodes.containsKey(net.canonicalName)) continue; + map.put(net.canonicalName, port); + } + return map.values(); + } + protected void addFormal(final List params, final String name, + final String type, final String dir) { + params.add(lookupNode(name, type)); + final VerilogObject ident = factory.ident(name, mAlwaysEscape); + inout.add(factory.parameterDecl(ident, dir)); + } + protected void addFormal(final List params, final String name, + final String type) { + addFormal(params, name, type, "inout"); + } + private Integer accumPortDir(final Integer oldDir, final Integer newDir) { + if (oldDir == null || oldDir == newDir) return newDir; + else if (oldDir == PortDefinition.NONE) return newDir; + else if (newDir == PortDefinition.NONE) return oldDir; + else return PortDefinition.INOUT; + } + protected void formal(final List params, final ConnectionInfo ci, + final String type) { + final Map ports = + CellUtils.markPorts(ci.child.cast_cell); + final Map canonPorts = + new HashMap(); + for (Map.Entry entry : ports.entrySet()) { + final HierName hn; + try { + hn = HierName.makeHierName((String) entry.getKey(), '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName: " + + entry.getKey()); + } + + final CellNet pn = ci.child.getNet(hn); + if (pn != null) { + // This could happen if the net is unused. + canonPorts.put( + pn.canonicalName, + accumPortDir(canonPorts.get(pn.canonicalName), + entry.getValue())); + } + } + final Collection set = ports(ci); + for (Iterator i = set.iterator(); i.hasNext(); ) { + HierName h = ci.child.getNet((HierName) i.next()).canonicalName; + final Integer dir = canonPorts.get(h); + assert dir != null : "Cannot get direction for " + h + " in cell " + ci.child.typeName + " canonPorts = " + canonPorts; + final String dirString; + switch (dir.intValue()) { + case PortDefinition.IN: dirString = "input"; break; + case PortDefinition.OUT: dirString = "output"; break; + case PortDefinition.INOUT: dirString = "inout"; break; + default: + throw new AssertionError("Unknown port direction: " + dir); + } + addFormal(params, h.getCadenceString(), type, dirString); + } + } + protected void addActual(final List params, final String name, + final String type) { + params.add(lookupNode(name, type)); + } + protected void addActual(final List params, final String portName, + final String name, final String type) { + final VerilogObject port = factory.ident(portName, true); + params.add(factory.namedPort(port, lookupNode(name, type))); + } + protected void addActual(final boolean byName, final List params, + final HierName child, final HierName parent, + final String type) { + final String sparent = parent.getCadenceString(); + if (byName) { + addActual(params, child.getCadenceString(), sparent, type); + } else { + addActual(params, sparent, type); + } + } + protected void actual(final List params, final ConnectionInfo ci, + final String type) { + actual(params, ci, type, false); + } + protected void actual(final List params, final ConnectionInfo ci, + final String type, final boolean byName) { + actual(params, ci, byName, new UnaryFunction() { + public Object execute(final Object o) { return type; } + }); + } + protected void actual(final List params, final ConnectionInfo ci, + final UnaryFunction uf) { + actual(params, ci, false, uf); + } + protected void actual(final List params, final ConnectionInfo ci, + final boolean byName, final UnaryFunction uf) { + final Collection set = ports(ci); + for (Iterator i = set.iterator(); i.hasNext(); ) { + final HierName port = (HierName) i.next(); + final CellNet net = ci.parent.getNet(ci.getParentName(port)); + final String type = (String) uf.execute(net); + final CellNet childNet = ci.child.getNet(port); + addActual(byName, params, childNet.canonicalName, + net.canonicalName, type); + } + } + protected boolean unconvertible(final CellType cell) { + return !cell.cast_cell.containsVerilog() && + (cell.isWiringCell || + cell.prs == null || + cell.cast_cell.getFullyQualifiedType().startsWith(libPrefix)); + } + + public interface BlockValue { + VerilogObject node(final HierName instance, final HierName name); + VerilogObject array(final VerilogObject[] objs); + } + + protected static class DefaultBlockValue implements BlockValue { + private final AbstractConverter converter; + private final AliasedSet ns; + private final UnaryFunction uf; + public DefaultBlockValue(final AbstractConverter converter, + final AliasedSet ns, final UnaryFunction uf) { + this.converter = converter; + this.ns = ns; + this.uf = uf; + } + public VerilogObject node(final HierName instance, + final HierName name) { + final HierName parent = + (HierName) ns.getCanonicalKey(HierName.append(instance, name)); + assert parent != null : "Cannot get net name in parent for " + name; + final String type = (String) uf.execute(parent); + return converter.lookupNode(parent, type); + } + public VerilogObject array(final VerilogObject[] objs) { + return converter.factory.concatOp(objs); + } + } + + private class NonNodeException extends RuntimeException { + private final Value v; + public NonNodeException(final Value v) { + this.v = v; + } + public Value getValue() { + return v; + } + } + + private class NonDefchanException extends RuntimeException { + private final CellInterface cell; + public NonDefchanException(final CellInterface cell) { + this.cell = cell; + } + public CellInterface getCell() { + return cell; + } + } + + static HierName toHier(final String s) { + try { + return HierName.makeHierName(s, '.'); + } catch (InvalidHierNameException e) { + throw new AssertionError("Cannot construct HierName: " + s); + } + } + + protected VerilogObject verilogValue(final HierName instance, + final AliasedSet ns, + final Value v, + final BlockValue value) { + if (v == null) { + // no connection + return null; + } else if (v instanceof ArrayValue) { + final ArrayValue av = (ArrayValue) v; + final HierName avi = av.getInstanceName(); + final HierName ai; + if (avi == null || avi.isLocal()) { + ai = instance; + } else { + ai = HierName.append(instance, avi.getParent()); + } + final List objs = new ArrayList(); + for (Iterator i = av.getIterator(); i.hasNext(); ) { + objs.add(0, verilogValue(ai, ns, (Value) i.next(), value)); + } + return value.array(toArray(objs)); + } else if (v instanceof NodeValue) { + final HierName name = ((NodeValue) v).getInstanceName(); + return value.node(instance, name); + } else if (v instanceof InstanceValue) { + final InstanceValue iv = (InstanceValue) v; + final CellInterface cell = iv.getCell(); + final List objs = new ArrayList(); + if (cell.isChannel()) { + (new CellUtils.MarkPort() { + protected void mark(final NodeType nodeType, + final String name, + final int direction) { + objs.add(value.node(instance, + HierName.append(iv.getInstanceName(), + toHier(name)))); + } + protected void mark(final NodeType nodeType, + final String name, + final int direction, + final int width) { + for (int i = width - 1; i >= 0; --i) { + mark(nodeType, name + i + "]", direction); + } + } + protected void mark(final ChannelType channelType, + final String name, + final int direction, final int width) { + for (int i = width - 1; i >= 0; --i) { + mark(channelType, name + i + "]", direction); + } + } + protected void mark(final ArrayType arrayType, + final String name, + final int direction) { + final int min = arrayType.getMinIndex(); + final int max = arrayType.getMaxIndex(); + + final PortTypeInterface arrayedType = + arrayType.getArrayedType(); + for (int i = max; i >= min; --i) { + mark(arrayedType, name + i, direction, true); + } + } + }).mark(cell); + return value.array(toArray(objs)); + } else { + throw new NonDefchanException(cell); + } + } else { + throw new NonNodeException(v); + } + } + + protected Pair verilogInstance(final VerilogBlock.Instance inst, + final HierName instance, + final AliasedSet ns, + final VerilogFactoryInterface factory, + final BlockValue bv) { + final Iterator order = inst.getPortsByOrder(); + final List params = new ArrayList(); + for (Iterator i = inst.getParameters(); i.hasNext(); ) { + final Value v = (Value) i.next(); + final String s; + try { + if (v instanceof IntValue) + s = ((IntValue) v).getValue().toString(); + else + s = Double.toString(((FloatValue) v).getValue()); + } catch (InvalidOperationException e) { + throw new AssertionError("Cannot get int or double value of: " + v); + } + params.add(factory.expr(s)); + } + final List ports = new ArrayList(); + if (order == null) { + final Iterator name = inst.getPortsByName(); + assert name != null; + while (name.hasNext()) { + final Map.Entry entry = (Map.Entry) name.next(); + final String key = (String) entry.getKey(); + final Value val = (Value) entry.getValue(); + final VerilogObject portName = factory.ident(key, false); + final VerilogObject port; + try { + port = verilogValue(instance, ns, val, bv); + } catch (NonNodeException e) { + throw new RuntimeException( + "Encountered unknown value while process connection " + + "in module " + inst.getModule() + " for port " + key + + ": " + e.getValue()); + } catch (NonDefchanException e) { + throw new RuntimeException( + "Encountered non-channel instance while process " + + "connection in module " + inst.getModule() + + " for port " + key + ": " + + e.getCell().getFullyQualifiedType()); + } + ports.add(factory.namedPort(portName, port)); + } + } else { + int k = 1; + while (order.hasNext()) { + final Value v = (Value) order.next(); + final VerilogObject port; + try { + port = verilogValue(instance, ns, v, bv); + } catch (NonNodeException e) { + throw new RuntimeException( + "Encountered unknown value while process connection " + + "in module " + inst.getModule() + + " for port in position " + k + ": " + e.getValue()); + } catch (NonDefchanException e) { + throw new RuntimeException( + "Encountered non-channel instance while process " + + "connection in module " + inst.getModule() + + " for port in position " + k + ": " + + e.getCell().getFullyQualifiedType()); + } + ports.add(port); + ++k; + } + } + return new Pair(params, ports); + } + + static VerilogBlock.NamedBlock + chooseVerilog(final CellInterface cell, + final Prs2Verilog.VerilogChooser chooser) { + final BlockIterator bi = + cell.getBlockInterface().iterator(BlockInterface.VERILOG); + if (!bi.hasNext()) return null; + final VerilogBlock vb = (VerilogBlock) bi.next(); + return chooser.choose(cell, vb); + } + + protected List verilogBlock(final HierName instance, final AliasedSet ns, + final CellInterface cell, + final Prs2Verilog.VerilogChooser chooser, + final BlockValue bv) { + final VerilogBlock.NamedBlock nb = chooseVerilog(cell, chooser); + if (nb == null) return null; + final List insts = new ArrayList(); + int id = 0; + final List files = new ArrayList(); + final boolean addFiles = !depends.containsKey(cell); + if (addFiles) + for (Iterator j = nb.getFiles(); j.hasNext(); ) + files.add(j.next()); + for (Iterator i = nb.getInstances(); i.hasNext(); ++id) { + final VerilogBlock.Instance inst = (VerilogBlock.Instance) i.next(); + final Pair p = verilogInstance(inst, instance, ns, factory, bv); + final List params = (List) p.getFirst(); + final List ports = (List) p.getSecond(); + final VerilogObject instName = + factory.ident((instance == null ? "inst" + : (instance.toString() + "$")) + + id, mAlwaysEscape); + final VerilogObject moduleName = + factory.ident(inst.getModule(), mAlwaysEscape); + insts.add(factory.moduleInst(instName, moduleName, toArray(params), + toArray(ports))); + if (addFiles) + for (Iterator j = inst.getFiles(); j.hasNext(); ) + files.add(j.next()); + } + if (addFiles) + depends.put(cell, (String[]) files.toArray(new String[0])); + return insts; + } + + protected String getDelayMacroName() { + return PRS2VERILOG_TAU; + } + + protected VerilogObject getDelayWithMacro(final VerilogObject o) { + return factory.binaryOp(macro(getDelayMacroName()), "*", o); + } + + protected VerilogObject[] getDelayExpr(final CellType cell, + final HierName node, + float tau) { + final float up = cell.getDelay().getDelay(node, true, tau); + final float dn = cell.getDelay().getDelay(node, false, tau); + return getDelayExpr(Float.toString(up), Float.toString(dn)); + } + + protected VerilogObject[] getDelayExpr(final String up, final String dn) { + return new VerilogObject[] { + getDelayWithMacro(factory.expr(up)), + getDelayWithMacro(factory.expr(dn)) + }; + } + + protected VerilogObject getDelay(final VerilogObject[] d) { + assert d.length >= 1 && d.length <= 3; + return d.length == 1 ? factory.delay(d[0]) : + d.length == 2 ? factory.delay(d[0], d[1]) + : factory.delay(d[0], d[1], d[2]); + } + + public Map/**/ getDependencies() { + return depends; + } + + protected String getModuleName(final CellInterface cell) { + return CellUtils.hashMetaParameters(cell.getFullyQualifiedType()); + } + + protected VerilogObject macro(final String s) { + return factory.macroUse(factory.ident(s, mAlwaysEscape), null); + } + + protected VerilogObject nextPrimitive() { + return factory.ident("PRS2VERILOG_primitive_" + primitiveCount++, + false); + } + + protected boolean shouldSuppressFaults(final CellType cell) { + return ((Boolean) DirectiveUtils.getTopLevelDirective( + cell.cast_cell, + DirectiveConstants.SUPPRESS_FAULTS)).booleanValue(); + } + + public abstract VerilogObject convert(final CommandLineArgs theArgs, + final VerilogObject moduleName, + final boolean toplevel, + final boolean topEnv); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterConstants.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterConstants.java new file mode 100644 index 0000000000..b5aba547ba --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterConstants.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import com.avlsi.file.common.HierName; + +public class ConverterConstants { + public static String getDelayMacroString() { + return "PRS2VERILOG_DELAY"; + } + + public static String getDelayBiasString() { + return "PRS2VERILOG_DELAYBIAS"; + } + + public static String getExtraDelayString(final HierName node, + final boolean up) { + return "PRS2VERILOG_EXTRADELAY_" + (up ? "UP" : "DOWN") + "_" + + node.getAsString('.').replace(',','_'); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterInterface.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterInterface.java new file mode 100644 index 0000000000..144f6cd505 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/ConverterInterface.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import java.util.Map; + +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.util.cmdlineargs.CommandLineArgs; + +/** + * An interface to different style converters. + **/ +public interface ConverterInterface { + /** + * Returns a VerilogObject representation. + * + * @param theArgs command line arguments that the program was invoked with + * @param moduleName name of the module, or null if the CAST + * name should be used. + * @param toplevel whether the cell being converted is the top level cell + * of the hierarchy + * @param topEnv true if conversion is in the context of the + * top level cell that hooks up the cell and the environment, and + * false otherwise. + * + * @return the VerilogObject representation + **/ + VerilogObject convert(final CommandLineArgs theArgs, + final VerilogObject moduleName, + final boolean toplevel, + final boolean topEnv); + + /** + * Returns file dependencies. Should only be called after + * convert to get sensical result. + **/ + Map /**/ getDependencies(); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GateConverter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GateConverter.java new file mode 100644 index 0000000000..87bd7130df --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GateConverter.java @@ -0,0 +1,298 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.Set; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.file.common.HierName; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.lvs.Dnf; +import com.avlsi.tools.prs2verilog.verilog.Delay; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.util.bool.AndBooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionVisitorInterface; +import com.avlsi.util.bool.HierNameAtomicBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpressionInterface; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.MultiSet; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryFunction; + +class GateConverter extends NetgraphGateConverter { + private final MultiMap up, down; + public GateConverter(final CellType cell, + final VerilogFactoryInterface factory, + final ConnectionInfo ports, + final HierName GND, + final boolean alwaysEscape, + final Prs2Verilog.VerilogChooser chooser, + final Cadencize cad) { + super(cell, factory, ports, GND, alwaysEscape, chooser, cad); + this.up = new MultiMap(new HashMap(), MultiMap.ARRAY_LIST_FACTORY); + this.down = new MultiMap(new HashMap(), MultiMap.ARRAY_LIST_FACTORY); + } + + protected String wireType(final CellNet net) { + return "wire"; + } + + private boolean isCombinational(final OrBooleanExpressionInterface orUp, + final OrBooleanExpressionInterface orDn) { + final MultiSet dnfDn = Dnf.fromExpression(orDn, cell.namespace, + cell.exclusives); + final MultiSet dualUp = Dnf.fromExpression(orUp.negated(), + cell.namespace, + cell.exclusives); + return dnfDn.compareTo(dualUp) == 0; + } + + public VerilogObject convert(final CommandLineArgs theArgs, + final VerilogObject moduleName, + final boolean toplevel, + final boolean topEnv) { + if (unconvertible(cell)) return null; + + final boolean assumeCombinational = + theArgs.argExists("assume-combinational"); + this.topEnv = topEnv; + + init(theArgs); + + //final String tauStr = theArgs.getArgValue("tau", null); + //if (tauStr != null) tau = Float.parseFloat(tauStr); + + for (Iterator i = cell.prs.getProductionRules(); i.hasNext(); ) { + final ProductionRule pr = (ProductionRule) i.next(); + doProductionRule(pr.canonicalizeNames(cell.namespace)); + } + + final Set updown = new HashSet(); + updown.addAll(up.keySet()); + updown.addAll(down.keySet()); + + final Set nostats = + DirectiveUtils.getExplicitTrues( + DirectiveUtils.canonizeKey(cell.namespace, + DirectiveUtils.getPrsDirective( + cell.cast_cell, DirectiveConstants.NO_STAT, + DirectiveConstants.NODE_TYPE))); + + for (Iterator i = updown.iterator(); i.hasNext(); ) { + final HierName node = (HierName) i.next(); + Collection prsUp = up.get(node); + if (prsUp == null) prsUp = Collections.EMPTY_LIST; + Collection prsDn = down.get(node); + if (prsDn == null) prsDn = Collections.EMPTY_LIST; + final OrBooleanExpression orUp = new OrBooleanExpression(true, + prsUp); + final OrBooleanExpression orDn = new OrBooleanExpression(true, + prsDn); + if (assumeCombinational || isCombinational(orUp, orDn)) { + final GateMaker gateUp = new GateMaker(node); + orUp.visitWith(gateUp); + } else { + final GateMaker gateUp; + if (prsUp.isEmpty()) { + gateUp = null; + } else { + gateUp = new GateMaker(); + orUp.visitWith(gateUp); + } + + final GateMaker gateDn; + if (prsDn.isEmpty()) { + gateDn = null; + } else { + gateDn = new GateMaker(); + orDn.visitWith(gateDn); + } + + items.add( + createBlackBox(node, + gateUp == null ? null : gateUp.result, + gateDn == null ? null : gateDn.result, + (nostats.contains(node) && + cell.getNet(node).isPortNet()) + ? "BLACKBOX" : "BLACKBOX_TRIREG")); + } + } + final ArrayList params = new ArrayList(); + if (clk != null) addFormal(params, clk, "wire", "input"); + formal(params, ports, "wire"); + + processSubcells(); + + items.addAll(0, wireDecl); + items.addAll(0, inout); + addParameters(); + + final List topModel = new ArrayList(); + topModel.add( + factory.module(moduleName == null ? + factory.ident(getModuleName(cell.cast_cell), true) : moduleName, + (VerilogObject[]) + params.toArray(new VerilogObject[0]), + (VerilogObject[]) + items.toArray(new VerilogObject[0]))); + if (zoix && shouldSuppressFaults(cell)) { + topModel.add(0, factory.expr("`suppress_faults\n")); + topModel.add(factory.expr("`nosuppress_faults\n")); + } + + return factory.compilationUnit((VerilogObject[]) + topModel.toArray(new VerilogObject[0])); + } + + private VerilogObject orGate(Collection wires) { + final VerilogObject[] old = (VerilogObject[]) wires.toArray(new VerilogObject[0]); + if (old.length == 1) return old[0]; + final VerilogObject[] terminals = new VerilogObject[old.length + 1]; + System.arraycopy(old, 0, terminals, 1, old.length); + terminals[0] = newWire(); + items.add(factory.primitive("or", null, nextPrimitive(), terminals)); + return terminals[0]; + } + + private void doProductionRule(final ProductionRule pr) { + final MultiMap current; + if (pr.getDirection() == ProductionRule.UP) current = up; + else current = down; + final HierName target = pr.getTarget(); + current.put(target, pr.getGuard()); + } + + private class GateMaker implements BooleanExpressionVisitorInterface { + /** + * The desired final output node. If not specified, a new unique node + * will be generated. If the expression contains only a literal, this + * name will NOT be used. + **/ + private HierName topNode; + + public VerilogObject result = null; + + public GateMaker() { + this(null); + } + public GateMaker(final HierName topNode) { + this.topNode = topNode; + } + private VerilogObject[] terminals(final Collection c, + final boolean sense) { + final ArrayList results = new ArrayList(); + final HierName desiredNode = topNode; + topNode = null; + for (Iterator i = c.iterator(); i.hasNext(); ) { + final BooleanExpressionInterface expr = + (BooleanExpressionInterface) i.next(); + expr.visitWith(this); + results.add(result); + } + topNode = desiredNode; + final boolean newWire = desiredNode == null || !sense; + results.add(0, newWire ? newWire() : lookupNode(desiredNode)); + return (VerilogObject[]) results.toArray(new VerilogObject[0]); + } + private void checkNot(final boolean sense) { + if (!sense) { + final VerilogObject[] args = new VerilogObject[2]; + args[0] = topNode == null ? newWire() : lookupNode(topNode); + args[1] = result; + items.add( + factory.primitive( + "not", + topNode == null ? null : getDelay(topNode), + nextPrimitive(), args)); + result = args[0]; + } + } + private BooleanExpressionInterface getFirst(final Collection c) { + return (BooleanExpressionInterface) c.iterator().next(); + } + public void visit(final AndBooleanExpressionInterface andExpr) { + VerilogObject delay = null; + final Collection conjuncts = andExpr.getConjuncts(); + if (conjuncts.size() == 1) { + getFirst(conjuncts).visitWith(this); + } else { + final boolean sense = andExpr.getSense(); + final VerilogObject[] args = terminals(conjuncts, sense); + result = args[0]; + if (topNode == null || !sense) { + items.add(factory.primitive("and", delay, nextPrimitive(), + args)); + checkNot(andExpr.getSense()); + } else { + items.add(factory.moduleInst(nextPrimitive(), + macro("AND"), + getDelayExpr(topNode), + args)); + } + } + } + public void visit(final HierNameAtomicBooleanExpression atomicExpr) { + final HierName name = atomicExpr.getName(); + if (atomicExpr.getSense()) { + result = lookupNode(name); + } else { + result = lookupNot(name); + } + if (topNode != null) { + final VerilogObject[] args = new VerilogObject[] { + lookupNode(topNode), + result + }; + items.add(factory.primitive("buf", getDelay(topNode), + nextPrimitive(), args)); + } + } + public void visit(final OrBooleanExpressionInterface orExpr) { + VerilogObject delay = null; + final Collection disjuncts = orExpr.getDisjuncts(); + if (disjuncts.size() == 1) { + getFirst(disjuncts).visitWith(this); + } else { + final boolean sense = orExpr.getSense(); + final VerilogObject[] args = terminals(disjuncts, sense); + result = args[0]; + if (topNode == null || !sense) { + items.add(factory.primitive("or", delay, nextPrimitive(), + args)); + checkNot(orExpr.getSense()); + } else { + items.add(factory.moduleInst(nextPrimitive(), + macro("OR"), + getDelayExpr(topNode), + args)); + } + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GeneratePortMapping.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GeneratePortMapping.java new file mode 100644 index 0000000000..e920d5c160 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GeneratePortMapping.java @@ -0,0 +1,317 @@ +/* + * Copyright 2002-2009 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellInterface; +import com.avlsi.fast.VerilogBlock; +import com.avlsi.file.verilog.grammar.PortDeclarationTreeParser; +import com.avlsi.tools.prs2verilog.verilog.*; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.SearchPath; +import com.avlsi.io.SearchPathFile; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.cmdlineargs.defimpl.PedanticCommandLineArgs; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.functions.UnaryFunction; + +public class GeneratePortMapping extends AbstractConverter { + private final CellInterface cell; + private final Prs2Verilog.VerilogChooser chooser; + private final Cadencize cad; + private Map boundsMap; + + public GeneratePortMapping(final VerilogFactoryInterface factory, + final CellInterface cell, + final Prs2Verilog.VerilogChooser chooser, + boolean alwaysEscape, + final Cadencize cad) { + super(factory, alwaysEscape); + this.cell = cell; + this.chooser = chooser; + this.cad = cad; + this.boundsMap = Collections.EMPTY_MAP; + } + + public Map getBounds() { + return Collections.unmodifiableMap(boundsMap); + } + + public VerilogObject convert(final CommandLineArgs theArgs, + final VerilogObject moduleName, + final boolean toplevel, + final boolean topEnv) { + final AliasedSet ns = cad.convert(cell).getLocalNodes(); + final VerilogBlock.NamedBlock nb = chooseVerilog(cell, chooser); + boundsMap = + DirectiveUtils.gruntDirective(nb, DirectiveConstants.BOUNDS, + DirectiveConstants.STRING_TYPE); + + final List block = verilogBlock( + null, ns, cell, chooser, + new DefaultBlockValue(this, ns, + new UnaryFunction() { + public Object execute(final Object o) { + return "wire"; + } + })); + return block == null ? null : factory.compilationUnit(toArray(block)); + } + + private void getModulePorts(final Map modulePorts, + final String verilogPath) { + final File parent = new File(verilogPath); + for (Iterator i = depends.values().iterator(); i.hasNext(); ) { + final String[] files = (String[]) i.next(); + for (int j = 0; j < files.length; ++j) { + FileInputStream fin = null; + try { + fin = new FileInputStream(new File(parent, files[j])); + PortDeclarationTreeParser.getPortDeclarations( + fin, modulePorts); + } catch (Exception e) { + } finally { + if (fin != null) { + try { + fin.close(); + } catch (IOException e) { } + } + } + } + } + } + + private static class MappingVisitor extends TrivialVisitor { + private final Map result; + private final Map modulePorts; + private final Map bounds; + private String currentPort; + private int currentElement; + private Map currentPorts; + private List currentBounds; + private boolean namedPort, moduleName; + private PortDeclarationTreeParser.Range currentRange; + + public MappingVisitor(final Map result, final Map modulePorts, + final Map bounds) { + this.result = result; + this.modulePorts = modulePorts; + this.bounds = bounds; + this.currentElement = Integer.MIN_VALUE; + this.currentBounds = null; + } + + public void namedPort(final VerilogObject portName, + final VerilogObject port) { + if (portName != null && port != null) { + namedPort = true; + currentPort = null; + portName.accept(this); + port.accept(this); + namedPort = false; + } + } + + public void concatOp(final VerilogObject[] elements) { + final int length; + final int delta; + if (currentBounds != null) { + final int lbound = ((Integer) currentBounds.get(0)).intValue(); + final int rbound = ((Integer) currentBounds.get(1)).intValue(); + currentElement = lbound; + length = Math.abs(currentElement - rbound) + 1; + delta = currentElement > rbound ? -1 : 1; + if (length != elements.length) + System.err.println("WARNING: Directives declares " + + currentPort + currentRange + + ", but it is instantiated with " + + length + " elements in CAST."); + } else if (currentRange != null) { + currentElement = currentRange.getLeft(); + length = Math.abs(currentElement - currentRange.getRight()) + 1; + delta = currentElement > currentRange.getRight() ? -1 : 1; + if (length != elements.length) + System.err.println("WARNING: Verilog declares " + + currentPort + currentRange + + ", but it is instantiated with " + + length + " elements in CAST."); + } else { + currentElement = elements.length - 1; + length = elements.length; + delta = -1; + } + for (int i = 0; i < length; ++i, currentElement += delta) { + elements[i].accept(this); + } + currentElement = Integer.MIN_VALUE; + } + + public void ident(final String ident, final boolean escape) { + if (namedPort) { + if (currentPort == null) { + currentPort = ident; + currentRange = currentPorts == null ? null : + (PortDeclarationTreeParser.Range) + currentPorts.get(ident); + currentBounds = (List) bounds.get(ident); + } else { + String lhs = currentPort; + if (currentElement != Integer.MIN_VALUE) { + lhs = lhs + "[" + currentElement + "]"; + } + result.put(lhs, ident); + } + } + if (moduleName) { + currentPorts = (Map) modulePorts.get(ident); + } + } + + public void moduleInst(final VerilogObject ident, + final VerilogObject module, + final VerilogObject[] parameters, + final VerilogObject[] ports) { + moduleName = true; + module.accept(this); + moduleName = false; + for (int i = 0; i < ports.length; ++i) { + ports[i].accept(this); + } + currentPorts = null; + } + + public void compilationUnit(final VerilogObject[] objects) { + for (int i = 0; i < objects.length; ++i) { + objects[i].accept(this); + } + } + } + + private static void usage( String m ) { + System.err.println( + "Usage: generate_port_mapping --cast-path=\n" + + " [--cast-version=1|2]\n" + + " --cell=\n" + + " --verilog-block=\n" + + " [--verilog-path=]"); + if (m != null && m.length() > 0) + System.err.print( m ); + System.exit(1); + } + + public static Map generateMapping ( + final CellInterface cell, + final String cellName, + final String verilogBlock, + final String verilogPath) throws Exception { + return generateMapping(cell, cellName, verilogBlock, verilogPath, + new Cadencize(false)); + } + + public static Map generateMapping ( + final CellInterface cell, + final String cellName, + final String verilogBlock, + final String verilogPath, + final Cadencize cad) throws Exception { + + if (cellName == null || verilogBlock == null) { + return null; + } + + final VerilogFactoryInterface factory = new VerilogFactoryImpl(); + final GeneratePortMapping mapper = + new GeneratePortMapping(factory, cell, + new Prs2Verilog.SimpleChooser(verilogBlock), + false, cad); + final VerilogObject result = + mapper.convert(null, null, false, false); + + if (result == null) { + System.err.println("Verilog block " + verilogBlock + + " not found in " + cellName); + return null; + } + + + final Map modulePorts = new HashMap(); + if (verilogPath != null) + mapper.getModulePorts(modulePorts, verilogPath); + final Map map = new LinkedHashMap(); + generateMapping(map, modulePorts, mapper.getBounds(), result); + return map; + } + + static void generateMapping(final Map map, + final Map modulePorts, + final Map boundsMap, + final VerilogObject block) { + final VerilogVisitor visitor = + new MappingVisitor(map, modulePorts, boundsMap); + block.accept(visitor); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final PedanticCommandLineArgs pedanticArgs = + new PedanticCommandLineArgs( cachedArgs ); + + final CommandLineArgs theArgs = pedanticArgs; + + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cell", null); + final String verilogBlock = theArgs.getArgValue("verilog-block", null); + final String verilogPath = theArgs.getArgValue("verilog-path", null); + if (cellName == null || verilogBlock == null) { + usage( null ); + } + + if ( ! pedanticArgs.pedanticOK( false, true ) ) { + usage( pedanticArgs.pedanticString() ); + } + final SearchPath castPath = new FileSearchPath(castRoot); + final CastFileParser cfp = new CastFileParser(castPath, castVersion); + final CellInterface cell = cfp.getFullyQualifiedCell(cellName); + + + Map map = null; + try { + map = generateMapping(cell, cellName, verilogBlock, verilogPath); + } catch (Exception e) {} + + if (map != null) { + for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + System.out.println(entry.getKey() + " " + entry.getValue()); + } + } + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GenerateWrapper.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GenerateWrapper.java new file mode 100644 index 0000000000..ccef7ba52a --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/GenerateWrapper.java @@ -0,0 +1,379 @@ +package com.avlsi.tools.prs2verilog; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.fast.ports.*; +import com.avlsi.tools.prs2verilog.verilog.VerilogUtil; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.SearchPath; +import com.avlsi.io.SearchPathFile; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cadencize.CadenceInfo; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.AliasedMap; +import com.avlsi.util.container.FilteringIterator; +import com.avlsi.util.container.Pair; +import com.avlsi.util.functions.UnaryPredicate; + +public class GenerateWrapper { + private static Pair verilogDecl(final List parts) { + final List C = new ArrayList(); + final List A = new ArrayList(); + int N = 0; + int elements = 1; + int arrayed = 0; + while (!parts.isEmpty()) { + final Pair CA = getComponent(parts); + C.add(CA.getFirst()); + final List Ai = (List) CA.getSecond(); + A.add(Ai); + if (!Ai.isEmpty()) ++arrayed; + for (Iterator i = Ai.iterator(); i.hasNext(); ) { + elements *= ((Integer) i.next()).intValue(); + } + ++N; + } + + final StringBuffer name = new StringBuffer(); + for (int i = 0; i < N; ++i) { + final String Ci = (String) C.get(i); + final List Ai = (List) A.get(i); + name.append(Ci); + if (i < N - 1 && Ai.isEmpty()) { + name.append('_'); + } else if (i == N - 1 && (Ai.isEmpty() || + (arrayed == 1 && Ai.size() == 1))) { + // emit nothing + } else { + name.append('_'); + for (Iterator j = Ai.iterator(); j.hasNext(); ) { + final Integer Mj = (Integer) j.next(); + name.append(Mj.intValue()); + if (j.hasNext()) name.append('x'); + } + } + if (i < N - 1) name.append('_'); + } + + return new Pair(arrayed > 0 ? "[" + (elements - 1) + ":0] " : "", + name.toString()); + } + + private static HashMap declCache = new HashMap(); + + private static Pair getDecl(final List original) { + Pair result = (Pair) declCache.get(original); + if (result == null) { + result = verilogDecl(new ArrayList(original)); + declCache.put(original, result); + } + return result; + } + + private static int accessArray(final List indices, final List parts) { + int n = 1; + int result = 0; + for (ListIterator i = indices.listIterator(indices.size()), + j = parts.listIterator(parts.size()); + i.hasPrevious(); ) { + final int index = ((Integer) i.previous()).intValue(); + Object size; + while ((size = j.previous()) instanceof String); + result += index * n; + n *= ((Integer) size).intValue(); + } + return result; + } + + private static class PortInfo { + private final List parts; + private final List indices; + private final int direction; + public PortInfo(final List parts, final List indices, + final int direction) { + this.parts = parts; + this.indices = indices; + this.direction = direction; + } + public String getDirection() { + if (direction > 0) return "output"; + else if (direction == 0) return "inout"; + else return "input"; + } + public String getName() { + return (String) getDecl(parts).getSecond(); + } + public String getSize() { + return (String) getDecl(parts).getFirst(); + } + public String getIndex() { + return indices.isEmpty() ? "" + : "[" + accessArray(indices, parts) + "]"; + } + } + + private static class Munger extends CellUtils.MarkPort { + private static String[] SKIP_LIST = new String[] { "GND", "Vdd" }; + private final Map portMap; + private final boolean skipPowerRail; + private List parts; + private List indices; + + public Munger(final Map portMap, final boolean skipPowerRail) { + this.portMap = portMap; + this.skipPowerRail = skipPowerRail; + this.parts = new ArrayList(); + this.indices = new ArrayList(); + } + protected void mark(final ChannelType channelType, final String name, + final int direction) { + super.mark(channelType, name, direction); + } + protected void mark(final ChannelType channelType, final String name, + final int direction, final int width) { + parts.add(new Integer(width)); + final List oldIndices = indices; + for (int i = 0; i < width; ++i) { + indices = new ArrayList(oldIndices); + indices.add(new Integer(i)); + mark(channelType, name + i + "]", direction); + } + indices = oldIndices; + } + protected void mark(final NodeType nodeType, final String name, + final int direction) { + portMap.put(name, new PortInfo(parts, indices, direction)); + } + protected void mark(final NodeType nodeType, final String name, + final int direction, final int width) { + parts.add(new Integer(width)); + final List oldIndices = indices; + for (int i = 0; i < width; ++i) { + indices = new ArrayList(oldIndices); + indices.add(new Integer(i)); + mark(nodeType, name + i + "]", direction); + } + indices = oldIndices; + } + protected void mark(final ArrayType arrayType, final String name, + final int direction) { + final int min = arrayType.getMinIndex(); + if (min != 0) { + throw new RuntimeException("Array " + name + " does not start from 0"); + } + final int max = arrayType.getMaxIndex(); + parts.add(new Integer(max + 1)); + final List oldParts = parts; + final PortTypeInterface arrayedType = arrayType.getArrayedType(); + final List oldIndices = indices; + for (int i = min; i <= max; ++i) { + parts = new ArrayList(oldParts); + indices = new ArrayList(oldIndices); + indices.add(new Integer(i)); + mark(arrayedType, name + i, direction, true); + } + parts = oldParts; + indices = oldIndices; + } + protected void mark(final StructureType structureType, + final String name, final int direction) { + super.mark(structureType, name, direction); + } + protected void mark(final PortDefinition p, final String prefix, + int direction) { + parts.add(p.getName()); + super.mark(p, prefix, direction); + } + public void mark(final Iterator portDefinitions, final String prefix, + final int direction) { + final List oldParts = parts; + while (portDefinitions.hasNext()) { + final PortDefinition p = + (PortDefinition) portDefinitions.next(); + parts = new ArrayList(oldParts); + mark(p, prefix, direction); + } + parts = oldParts; + } + public void mark(final CellInterface ci) { + final Iterator filtered; + if (skipPowerRail) { + filtered = + new FilteringIterator( + ci.getPortDefinitions(), + new UnaryPredicate() { + public boolean evaluate(final Object o) { + final PortDefinition def = (PortDefinition) o; + for (int i = 0; i < SKIP_LIST.length; ++i) { + if (def.getName().equals(SKIP_LIST[i])) { + return false; + } + } + return true; + } + }); + } else { + filtered = ci.getPortDefinitions(); + } + mark(filtered); + } + } + + private static Pair getComponent(final List parts) { + final String C = (String) parts.remove(0); + final List A = new ArrayList(); + while (!parts.isEmpty() && parts.get(0) instanceof Integer) { + A.add(parts.remove(0)); + } + return new Pair(C, A); + } + + private static void getWrapper(final CellInterface cell, + final CDLNameInterface renamer, + final boolean skipPowerRail, + final PrintWriter pw) { + final Map portMap = new LinkedHashMap(); + (new Munger(portMap, skipPowerRail)).mark(cell); + + pw.println("module " + cell.getType() + "("); + + final Set declarations = new LinkedHashSet(); + final Set seen = new HashSet(); + for (Iterator i = portMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final PortInfo pinfo = (PortInfo) entry.getValue(); + if (seen.add(pinfo.getName())) declarations.add(pinfo); + } + + for (Iterator i = declarations.iterator(); i.hasNext(); ) { + final PortInfo pinfo = (PortInfo) i.next(); + pw.print(pinfo.getName()); + if (i.hasNext()) pw.print(','); + pw.println(); + } + pw.println(");"); + + for (Iterator i = declarations.iterator(); i.hasNext(); ) { + final PortInfo pinfo = (PortInfo) i.next(); + pw.println(pinfo.getDirection() + " " + pinfo.getSize() + + pinfo.getName() + ";"); + } + + pw.print(VerilogUtil.escapeIfNeeded(cell.getFullyQualifiedType())); + pw.println(" X("); + + final Cadencize cad = new Cadencize(false); + final AliasedMap ports = cad.convert(cell).getPortNodes(); + boolean first = true; + for (Iterator i = portMap.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName port; + try { + port = HierName.makeHierName((String) entry.getKey(), '.'); + } catch (InvalidHierNameException e) { + throw new RuntimeException("Cannot make HierName: " + + entry.getKey(), e); + } + final PortInfo pinfo = (PortInfo) entry.getValue(); + final HierName canon = (HierName) ports.getCanonicalKey(port); + if (!((Boolean) ports.getValue(port)).booleanValue()) continue; + if (first) first = false; + else pw.println(','); + final String renamed; + try { + renamed = renamer.renameNode(canon.getAsString('.')); + } catch (CDLRenameException e) { + throw new RuntimeException("Cannot rename: " + canon, e); + } + pw.print("." + VerilogUtil.escapeIfNeeded(renamed)); + pw.print("(" + pinfo.getName() + pinfo.getIndex()); + pw.print(')'); + } + + pw.println(");"); + + pw.println("endmodule"); + pw.flush(); + } + + private static void usage() { + final String className = GenerateWrapper.class.getName(); + + System.out.println( "Usage: " + + System.getProperty( "java.home" ) + + System.getProperty( "file.separator" ) + + "bin" + + System.getProperty( "file.separator" ) + + "java " + + " -classpath " + + System.getProperty( "java.class.path" ) + " " + + className ); + System.out.println("\t--cast-path= (defaults to .)"); + System.out.println("\t--cast-version= (defaults to 2)"); + System.out.println("\t--cell= (name of cell to process)"); + System.out.println("\t[--translate=] (translate port names of wrapped cell)"); + System.out.println("\t[--skip-power-rail] (skip GND and Vdd ports)"); + System.exit(1); + } + + public static void main(String[] args) throws Exception { + final CommandLineArgs parsedArgs = new CommandLineArgsDefImpl( args ); + final CommandLineArgs argsWithConfigs = + new CommandLineArgsWithConfigFiles( parsedArgs ); + + final CommandLineArgs cachedArgs = + new CachingCommandLineArgs( argsWithConfigs ); + + final CommandLineArgs theArgs = cachedArgs; + + final String castRoot = theArgs.getArgValue("cast-path", "."); + final String castVersion = theArgs.getArgValue("cast-version", "2"); + final String cellName = theArgs.getArgValue("cell", null); + final String translate = theArgs.getArgValue("translate", null); + final boolean skipPowerRail = theArgs.argExists("skip-power-rail"); + if (cellName == null) { + usage(); + } + + final SearchPath castPath = new FileSearchPath(castRoot); + final CastFileParser cfp = new CastFileParser(castPath, castVersion); + final CellInterface cell = cfp.getFullyQualifiedCell(cellName); + + final CDLNameInterface renamer; + if (translate == null) renamer = new IdentityNameInterface(); + else if (translate.equals("cadence")) + renamer = new CadenceNameInterface(); + else if (translate.equals("gds2")) + renamer = new GDS2NameInterface(); + else { + renamer = null; + System.out.println("Unknown translate method: " + translate); + usage(); + } + + getWrapper(cell, renamer, skipPowerRail, new PrintWriter(System.out)); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphConverter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphConverter.java new file mode 100644 index 0000000000..0c655e9bc7 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphConverter.java @@ -0,0 +1,651 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.Set; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.DirectiveInterface; +import com.avlsi.cast2.directive.impl.DirectiveSource; +import com.avlsi.cast2.util.DirectiveOverride; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.DirectiveBlock; +import com.avlsi.file.aspice.AspiceFile; +import com.avlsi.file.cdl.CDLParser; +import com.avlsi.file.cdl.CDLFileFormatException; +import com.avlsi.file.common.HierName; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.prs.UnimplementableProductionRuleException; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.lvs.NetGraph; +import com.avlsi.tools.prs2verilog.verilog.Delay; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.tools.jauto.CastQuery; +import com.avlsi.tools.jauto.GlobalNet; +import com.avlsi.util.bool.AndBooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionVisitorInterface; +import com.avlsi.util.bool.HierNameAtomicBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpressionInterface; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.functions.UnaryFunction; + +final class NetgraphConverter extends NetgraphGateConverter { + private final NetGraph graph; + private CDLParser cdlParser; + private final HierName VDD; + private boolean minimizeTriRegs = false; + private static DirectiveInterface emptyDirective = null; + private boolean macroModel = false; + private boolean noResetFault = false; + private boolean extraPortInfo = false; + private VerilogObject parameterPrefix = null; + private int faultParamNum = 0; + + private String getPortString(final VerilogObject[] ports) { + return getPortString(ports, Collections.EMPTY_SET, + Collections.EMPTY_SET); + } + + private String getPortString(final VerilogObject[] ports, + final Set pullUpOnly, + final Set pullDnOnly) { + if (!extraPortInfo) return ""; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < ports.length; ++i) { + final String port = getIdent(ports[i]); + buf.append("/"); + if (port == null) { + buf.append("null"); + } else { + buf.append(port); + } + if (pullUpOnly.contains(ports[i])) buf.append("-"); + if (pullDnOnly.contains(ports[i])) buf.append("+"); + } + return buf.toString(); + } + + protected VerilogObject nextPrimitive(VerilogObject[] o) { + return factory.ident("PRS2VERILOG_primitive_" + (primitiveCount++) + + getPortString(o), false); + } + + private VerilogObject addPrefixIfNeeded(final VerilogObject ident) { + if (parameterPrefix == null) { + return ident; + } else { + return factory.hierIdent(new VerilogObject[] { parameterPrefix, + ident }); + } + } + + protected VerilogObject getDelayBiasParameter() { + return addPrefixIfNeeded(super.getDelayBiasParameter()); + } + + protected VerilogObject getExtraDelayParameter(final HierName node, + final boolean up) { + return addPrefixIfNeeded(super.getExtraDelayParameter(node, up)); + } + + private DirectiveInterface getEmptyDirective() { + if (emptyDirective == null) { + emptyDirective = + new DirectiveSource(BlockInterface.PRS).getDirectiveInterface(); + } + return emptyDirective; + } + + // Copied from tools/lvs/PrsToNet.java. Should refactor. + private NetGraph getCdlNetGraph(String cdlCellName) { + AspiceFile aspiceCell = cdlParser.getCell(cdlCellName); + + if (aspiceCell == null) { + System.err.println("Cell " + cdlCellName + + " not found in library!"); + System.exit(3); + } + + NetGraph netgraph = + new NetGraph(null,null,null, VDD, GND, Collections.EMPTY_SET); + netgraph.addAspice(aspiceCell); + return netgraph; + } + + public NetgraphConverter(final CellType cell, + final VerilogFactoryInterface factory, + final ConnectionInfo ports, + final HierName VDD, + final HierName GND, + final boolean alwaysEscape, + final Prs2Verilog.VerilogChooser chooser, + final Cadencize cad, + final boolean minimizeTriRegs) { + super(cell, factory, ports, GND, alwaysEscape, chooser, cad); + + this.minimizeTriRegs = minimizeTriRegs; + + if (this.minimizeTriRegs) { + // in this case, netgraphs should already be created + assert cell.transistors != null : + "Netgraph not set-up as expected."; + this.graph = cell.transistors; + } else { + this.graph = new NetGraph(cell.namespace, + cell.exclusives, + new ArrayList(), VDD, GND, + Collections.EMPTY_SET); + } + this.cdlParser = null; + this.VDD = VDD; + } + + protected void addFormal(final List params, final String name, + String type, final String dir) { + super.addFormal(params, name, type, dir); + } + + protected String wireType(final CellNet net) { + return "wire"; + } + + private VerilogObject getNextFaultParameter() { + faultParamNum++; + return factory.ident("no_fault" + faultParamNum, false); + } + + private boolean isReset(final String port) { + return port.equals("_RESET") || port.equals("Reset") || + port.equals("_Reset") || port.equals("reset") || + port.equals("_reset"); + } + + private String undot(final String ident) { + return noResetFault ? ident.replaceAll("\\.", "_") : ident; + } + + private void moduleInst(final VerilogObject ident, + final VerilogObject module, + final VerilogObject[] parameters, + final VerilogObject[] ports) { + items.add(factory.moduleInst(ident, module, parameters, + constify(ports))); + if (noResetFault) { + final String inst = getIdent(ident); + if (inst != null) { + boolean hasReset = false; + String faultExpr = inst + "(";; + for (int i = 0; i < ports.length; ++i) { + final String port = getIdent(ports[i]); + if (port != null && isReset(port)) { + hasReset = true; + faultExpr = faultExpr + "B"; + } else { + faultExpr = faultExpr + "-"; + } + if (i < ports.length - 1) + faultExpr = faultExpr + ","; + } + if (hasReset) { + faultExpr = faultExpr + ")"; + items.add( + factory.parameter( + null, + getNextFaultParameter(), + factory.expr("\"" + faultExpr + "\""))); + } + } + } + } + + class GateInstance { + private final String gate; + private final TreeMap map; + private final NetGraph.NetNode node; + public GateInstance(NetGraph.GateInstance gi, NetGraph.NetNode node) { + this.gate = gi.getType(); + this.map = new TreeMap(gi.getUnmodifiableMap()); + this.node = node; + } + public void verilog() { + final ArrayList args = new ArrayList(); + for (final Iterator i = map.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final HierName from = (HierName) entry.getKey(); + final HierName to = (HierName) entry.getValue(); + if (!from.isVdd() && !from.isGND()) { + if (node.name.compareTo(to) == 0) { + // Put output first to correspond to Verilog primitives + args.add(0, lookupNode(to)); + } else { + args.add(lookupNode(to)); + } + } + } + moduleInst(factory.ident(undot("gate_" + node.name + + NetgraphConverter.this.getPortString(toArray(args))), + mAlwaysEscape), + macro(gate), + getDelayExpr(node.name), + (VerilogObject[]) args.toArray(new VerilogObject[0])); + } + } + + public VerilogObject doPath(Collection gates, int nao) { + final ArrayList args = new ArrayList(gates); + if (args.size() == 1) { + return (VerilogObject) args.get(0); + } else { + String andType = "AND"; + if (args.size() <= nao) andType += args.size(); + final VerilogObject and = macro(andType); + args.add(0, newWire()); + moduleInst(nextPrimitive(toArray(args)), and, null, toArray(args)); + return (VerilogObject) args.get(0); + } + } + + public VerilogObject doPaths(Collection paths, int nao) { + final ArrayList args = new ArrayList(); + for (final Iterator p = paths.iterator(); p.hasNext(); ) { + final Collection gates = (Collection) p.next(); + args.add(doPath(gates, nao)); + } + if (args.size() != 1) { + String orType = "OR"; + if (args.size() <= nao) orType += args.size(); + final VerilogObject or = macro(orType); + args.add(0, newWire()); + moduleInst(nextPrimitive(toArray(args)), or, null, + toArray(args)); + } + return (VerilogObject) args.get(0); + } + + /** + * Return gates on the specified path as VerilogObjects, + * taking into account whether the gates need to be inverted or not + **/ + private Pair getGateNodes(final NetGraph.NetPath path) { + final ArrayList edges = path.getEdges(); + final ArrayList args = new ArrayList(); + final ArrayList nonInverting = new ArrayList(); + for (final Iterator e = edges.iterator(); e.hasNext(); ) { + final NetGraph.NetEdge edge = (NetGraph.NetEdge) e.next(); + if (path.getDir() == 1) { + args.add(lookupNot(edge.gate.name)); + } else { + args.add(lookupNode(edge.gate.name)); + } + nonInverting.add(lookupNode(edge.gate.name)); + } + return new Pair(args, nonInverting); + } + + private VerilogObject createMacroModel(final VerilogObject moduleName, + final Collection params, + final List items, + final List decls) { + final List inout = new ArrayList(); + final List wireDecl = new ArrayList(); + + // declare ports and directionality; the first element in ports is the + // output, all others are inputs; all ports are declared as wires + boolean first = true; + for (Iterator i = params.iterator(); i.hasNext(); first = false) { + final VerilogObject port = (VerilogObject) i.next(); + inout.add(factory.parameterDecl(port, first ? "output" : "input")); + wireDecl.add(factory.netDecl("wire", port, null)); + } + + inout.addAll(wireDecl); + inout.addAll(decls); + inout.addAll(items); + + return factory.module(moduleName, + (VerilogObject[]) + params.toArray(new VerilogObject[0]), + (VerilogObject[]) + inout.toArray(new VerilogObject[0])); + } + + public VerilogObject convert(final CommandLineArgs theArgs, + final VerilogObject moduleName, + final boolean toplevel, + final boolean topEnv) { + if (unconvertible(cell)) return null; + + init(theArgs); + + final String naoArg = theArgs.getArgValue("number-gate", null); + final int nao; + if (naoArg == null) { + nao = 0; + } else { + nao = Integer.parseInt(naoArg); + } + + this.topEnv = topEnv; + this.macroModel = theArgs.argExists("macro-model"); + this.noResetFault = theArgs.argExists("no-reset-fault"); + this.extraPortInfo = theArgs.argExists("extra-port-info"); + if (theArgs.argExists("trireg-output")) { + System.err.println("Warning: trireg-output is obselete, ignoring."); + } + + // if haven't already done so, create NetGraphs + if (!minimizeTriRegs) { + + final String libraryFile = theArgs.getArgValue("library", null); + final ArrayList gates = new ArrayList(); + if (libraryFile != null) { + try { + cdlParser = new CDLParser(); + cdlParser.parseFile(libraryFile); + } catch (Exception e) { + System.err.println("Invalid library file " + libraryFile + + ": " + e); + System.exit(1); + } + for (final Iterator i = cdlParser.getCellTypes(); + i.hasNext(); ) { + final String gn = (String) i.next(); + final NetGraph ng = getCdlNetGraph(gn); + ng.gateType = gn; + ng.prepareForLvs(); + gates.add(ng); + } + } + + // Disable all symmetrization directives (because they do not + // affect logic) by substituting the directive block associated + // with the prs block. + final BlockInterface block = cell.cast_cell.getBlockInterface(); + final BlockIterator dirIter = + block.iterator(BlockInterface.PRS).next() + .iterator(BlockInterface.DIRECTIVE); + final DirectiveBlock original = + dirIter.hasNext() ? (DirectiveBlock) dirIter.next() : null; + if (original != null) { + dirIter.set( + new DirectiveBlock( + new DirectiveOverride( + original, getEmptyDirective(), + DirectiveConstants.SYMMETRIZE))); + } + + try { + graph.addCellInterfacePrs(cell.cast_cell, (NetGraph[]) + gates.toArray(new NetGraph[0]), + null, null); + } catch (UnimplementableProductionRuleException e) { + System.err.println("UnimplementableProdunctionRule found: " + + e.getMessage()); + System.err.println("Falling back to GateConverter"); + final AbstractConverter conv = + new GateConverter(cell, factory, ports, GND, + mAlwaysEscape, chooser, cad); + return conv.convert(theArgs, moduleName, toplevel, topEnv); + } finally { + // Restore symmetrization directives + if (original != null) dirIter.set(original); + } + + graph.prepareForLvs(); + } + + final VerilogObject realModuleName = + moduleName == null ? + factory.ident(cell.cast_cell.getFullyQualifiedType(), + mAlwaysEscape) : + moduleName; + + // if the macro-model option is given, each blackbox has its own + // module; we collect all such modules here + final List macroModels = + macroModel ? new ArrayList() : Collections.EMPTY_LIST; + + for (final Iterator i = graph.getNodes().iterator(); i.hasNext(); ) { + final NetGraph.NetNode node = (NetGraph.NetNode) i.next(); + if (!node.isOutput() || !node.isNamed()) continue; + final boolean combinational = node.isCombinational(); + if ((node.getGate() != null) && combinational) { + final GateInstance g = new GateInstance(node.getGate(), node); + g.verilog(); + } else if (combinational) { + final Collection paths = node.getPaths(); + final ArrayList gndPaths = new ArrayList(); + for (final Iterator p = paths.iterator(); p.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) p.next(); + if (path.getDir() == -1) + gndPaths.add(getGateNodes(path).getFirst()); + } + final VerilogObject[] args = new VerilogObject[2]; + args[0] = lookupNode(node.name); + args[1] = doPaths(gndPaths, nao); + items.add(factory.primitive("not", getDelay(node.name), + nextPrimitive(args), + constify(args))); + } else { + final Collection paths = node.getPaths(); + final ArrayList vddPaths = new ArrayList(); + final ArrayList gndPaths = new ArrayList(); + final Set inputs = new HashSet(); + + // process all names so that every node will have been seen + // already before processing the blackboxes + for (final Iterator p = paths.iterator(); p.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) p.next(); + final ArrayList edges = path.getEdges(); + for (final Iterator e = edges.iterator(); e.hasNext(); ) { + final NetGraph.NetEdge edge = + (NetGraph.NetEdge) e.next(); + lookupNode(edge.gate.name); + } + lookupNode(path.getStartNode().name); + lookupNode(path.getEndNode().name); + } + + // doPaths and createBlackBox will, as a side effect, add + // Verilog constructs to the items and wireDecl members; + // because we want them to go into a seperate module, we + // temporarily swap in different members. + final Map macroModelNot, originalNot; + final List originalWireDecl, macroModelWireDecl; + final List originalItems, macroModelItems; + final Set pullUpInputs, pullDnInputs; + if (macroModel) { + macroModelNot = new HashMap(); + originalNot = not; + not = macroModelNot; + + macroModelWireDecl = new ArrayList(); + originalWireDecl = wireDecl; + wireDecl = macroModelWireDecl; + + macroModelItems = new ArrayList(); + originalItems = items; + items = macroModelItems; + parameterPrefix = moduleName; + + pullUpInputs = new HashSet(); + pullDnInputs = new HashSet(); + } else { + macroModelNot = null; originalNot = null; + macroModelWireDecl = null; originalWireDecl = null; + macroModelItems = null; originalItems = null; + pullUpInputs = Collections.EMPTY_SET; + pullDnInputs = Collections.EMPTY_SET; + } + for (final Iterator p = paths.iterator(); p.hasNext(); ) { + final NetGraph.NetPath path = (NetGraph.NetPath) p.next(); + final Pair pair = getGateNodes(path); + final Collection gates = (Collection) pair.getFirst(); + final Collection nonInverting = + (Collection) pair.getSecond(); + if (path.getDir() == 1) { + vddPaths.add(gates); + if (pullUpInputs != Collections.EMPTY_SET) + pullUpInputs.addAll(nonInverting); + } else if (path.getDir() == -1) { + gndPaths.add(gates); + if (pullDnInputs != Collections.EMPTY_SET) + pullDnInputs.addAll(nonInverting); + } else { + assert false : "Sneak path found: " + path; + } + inputs.addAll(nonInverting); + } + + items.add( + createBlackBox( + node.name, + vddPaths.size() > 0 ? doPaths(vddPaths, nao) : null, + gndPaths.size() > 0 ? doPaths(gndPaths, nao) : null, + (graph.nostaticizers.contains(node.getName()) && + node.isPort()) ? + "BLACKBOX" : "BLACKBOX_TRIREG")); + + // restore the original members + if (macroModel) { + not = originalNot; + wireDecl = originalWireDecl; + items = originalItems; + parameterPrefix = null; + } + + if (macroModel) { + final VerilogObject macroModelName = + factory.ident(cell.cast_cell.getFullyQualifiedType() + + "$$" + node.name, mAlwaysEscape); + final Collection args = new ArrayList(); + inputs.add(lookupNode(GND, "wire")); + args.add(lookupNode(node.name)); + args.addAll(inputs); + + final Set pullUpOnly = new HashSet(pullUpInputs); + pullUpOnly.removeAll(pullDnInputs); + final Set pullDnOnly = new HashSet(pullDnInputs); + pullDnOnly.removeAll(pullUpInputs); + + String macroModelInst = + undot("network_" + node.name + + getPortString(toArray(args), pullUpOnly, + pullDnOnly)); + moduleInst(factory.ident(macroModelInst, mAlwaysEscape), + macroModelName, + null, + toArray(args)); + macroModels.add(createMacroModel(macroModelName, args, + macroModelItems, + macroModelWireDecl)); + } + } + } + + final ArrayList params = new ArrayList(); + if (clk != null) addFormal(params, clk, "wire", "input"); + formal(params, ports, "wire"); + + processSubcells(); + + items.addAll(0, wireDecl); + items.addAll(0, inout); + + addParameters(); + final List topModel = new ArrayList(); + topModel.add( + factory.module(realModuleName, + (VerilogObject[]) + params.toArray(new VerilogObject[0]), + (VerilogObject[]) + items.toArray(new VerilogObject[0]))); + if (zoix && shouldSuppressFaults(cell)) { + topModel.add(0, factory.expr("`suppress_faults\n")); + topModel.add(factory.expr("`nosuppress_faults\n")); + } + if (macroModels.isEmpty()) { + return factory.compilationUnit((VerilogObject[]) + topModel.toArray(new VerilogObject[0])); + } else { + macroModels.add(0, factory.expr("`endif\n")); + macroModels.add(0, factory.expr("`enable_portfaults\n")); + macroModels.add(0, factory.expr("`suppress_faults\n")); + macroModels.add(0, factory.expr("`ifdef PRS2VERILOG_MACRO_MODEL\n")); + macroModels.add(factory.expr("`ifdef PRS2VERILOG_MACRO_MODEL\n")); + macroModels.add(factory.expr("`disable_portfaults\n")); + macroModels.add(factory.expr("`nosuppress_faults\n")); + macroModels.add(factory.expr("`endif\n")); + macroModels.addAll(topModel); + return factory.compilationUnit((VerilogObject[]) + macroModels.toArray(new VerilogObject[0])); + } + } + + /** + * Determines if the specified CellNet which is supposed to be intenral + * is part of a shared bus, i.e. if it has multiple drivers. + * Equivalent to + * ((GlobalNet) cellNet.getGlobalNets.get(0)).isShared(), + * but asserts that there is exactly one global net for the cell net. + * + * @param cellNet + * The cell net to check. + **/ + private static boolean isShared(final /*@ non_null @*/ CellNet cellNet) { + final List/**/ cellNetGlobalNets = + cellNet.getGlobalNets(); + + assert cellNetGlobalNets.size() == 1 : + "Found " + cellNetGlobalNets.size() + + " instead of 1 global net in supposedly internal net" + + cellNetGlobalNets + "cell net: " + cellNet; + + return ((GlobalNet) cellNetGlobalNets.get(0)).isShared(); + } + + /** + * Determines if the specified NetNode is part of a shared bus, + * i.e. if it has multiple drivers. + * + * @param node + * The NetGraph.NetNode node to check. + **/ + private boolean isShared(NetGraph.NetNode node) { + final CellNet cellNet = cell.getNet(node.getName()); + final List/**/ cellNetGlobalNets = cellNet.getGlobalNets(); + + // If any global net is shared return true + for (int i = 0; i < cellNetGlobalNets.size(); i++) { + if (((GlobalNet) cellNetGlobalNets.get(i)).isShared()) + return(true); + } + + return false; + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphGateConverter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphGateConverter.java new file mode 100644 index 0000000000..c4422b2ad5 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetgraphGateConverter.java @@ -0,0 +1,369 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.VerilogBlock; +import com.avlsi.file.common.HierName; +import com.avlsi.prs.ProductionRule; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.jauto.CastQuery; +import com.avlsi.tools.prs2verilog.verilog.Delay; +import com.avlsi.tools.prs2verilog.verilog.TrivialVisitor; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryFunction; +import com.avlsi.util.text.PrintfFormat; + +public abstract class NetgraphGateConverter extends AbstractConverter { + public static final String CLK = "PRS2VERILOG_clk"; + protected final CellType cell; + protected final ConnectionInfo ports; + protected final HierName GND; + protected final Cadencize cad; + protected float tau = 1; + protected boolean internalWire = false; + protected boolean topEnv = false; + protected String clk = null; + protected Map transportUp = null, transportDn = null; + protected final Prs2Verilog.VerilogChooser chooser; + protected boolean zoix = false; + protected boolean zeroify = false; + protected boolean oneify = false; + protected boolean skip = false; + protected boolean outputDelay = false; + protected final static PrintfFormat fmt = new PrintfFormat("%.6g"); + + public NetgraphGateConverter(final CellType cell, + final VerilogFactoryInterface factory, + final ConnectionInfo ports, + final HierName GND, + final boolean alwaysEscape, + final Prs2Verilog.VerilogChooser chooser, + final Cadencize cad) { + super(factory, alwaysEscape); + this.cell = cell; + this.ports = ports; + this.GND = GND; + this.chooser = chooser; + this.cad = cad; + } + + protected VerilogObject newWire() { + return newNet("wire"); + } + + protected String wireType(final HierName net) { + return wireType(cell.getNet(net)); + } + + protected void addFormal(final List params, final String name, + final String type, final String dir) { + if (!skip || (!name.equals("Vdd") && !name.equals("GND"))) + super.addFormal(params, name, type, dir); + } + + protected void addActual(final boolean byName, final List params, + final HierName child, final HierName parent, + final String type) { + if (!skip || (!child.isVdd() && !child.isGND())) + super.addActual(byName, params, child, parent, type); + } + + protected abstract String wireType(final CellNet net); + + protected VerilogObject lookupNode(final HierName node) { + final CellNet net = cell.getNet(node); + return lookupNode(node, wireType(net)); + } + + protected VerilogObject lookupNot(final HierName node) { + final CellNet net = cell.getNet(node); + return lookupNot(node, wireType(net)); + } + + protected String getDelayMacroName() { + return transportUp == null ? PRS2VERILOG_TAU : PRS2VERILOG_DELAY_SCALE; + } + + protected VerilogObject getDelayBiasParameter() { + return factory.ident(ConverterConstants.getDelayBiasString(), false); + } + + protected VerilogObject getExtraDelayParameter(final HierName node, + final boolean up) { + return factory.ident(ConverterConstants.getExtraDelayString(node, up), + false); + } + + protected VerilogObject getDelayWithMacro(final VerilogObject o) { + return factory.binaryOp(getDelayBiasParameter(), "*", + super.getDelayWithMacro(o)); + } + + protected VerilogObject lookupNode(final String node, final String type) { + final CellNet net = cell.getNet(node); + final VerilogObject delayExpr; + if (net != null && net.isInternalNet()) { + final double up, dn; + if (transportUp == null) { + up = 0; dn = 0; + } else { + final Float pu = (Float) transportUp.get(net.canonicalName); + up = pu == null ? 0 : pu.doubleValue(); + + final Float nd = (Float) transportDn.get(net.canonicalName); + dn = nd == null ? 0 : nd.doubleValue(); + } + delayExpr = up == 0 && dn == 0 ? null : + getDelay(getDelayExpr(fmt.sprintf(up), fmt.sprintf(dn))); + } else { + delayExpr = null; + } + return lookupNode(node, type, delayExpr); + } + + private VerilogObject getDelayExpr(final VerilogObject prsDelay, + final VerilogObject delayBias, + final VerilogObject extraDelay) { + if (zoix) { + // (prsDelay * delayBias + extraDelay) * PRS2VERILOG_TAU + return + factory.binaryOp( + factory.binaryOp( + factory.binaryOp(prsDelay, "*", delayBias), + "+", + extraDelay), + "*", + macro(getDelayMacroName())); + } else { + return factory.macroUse( + factory.ident(ConverterConstants.getDelayMacroString(), + false), + new VerilogObject[] { prsDelay, delayBias, extraDelay }); + } + } + + protected VerilogObject[] getDelayExpr(final HierName node) { + if (!outputDelay && (clk != null || transportUp != null)) return null; + final float up = cell.getDelay().getDelay(node, true, tau); + final float dn = cell.getDelay().getDelay(node, false, tau); + return new VerilogObject[] { + getDelayExpr(factory.expr(fmt.sprintf(up)), + getDelayBiasParameter(), + getExtraDelayParameter(node, true)), + getDelayExpr(factory.expr(fmt.sprintf(dn)), + getDelayBiasParameter(), + getExtraDelayParameter(node, false)) }; + } + + protected VerilogObject getDelay(final HierName node) { + final VerilogObject[] delays = getDelayExpr(node); + if (delays == null) return null; + else return getDelay(delays); + } + + private class VddGndBlockValue implements AbstractConverter.BlockValue { + private final AbstractConverter.BlockValue bv; + public VddGndBlockValue(final AbstractConverter.BlockValue bv) { + this.bv = bv; + } + public VerilogObject node(final HierName instance, + final HierName name) { + return constify(bv.node(instance, name)); + } + public VerilogObject array(final VerilogObject[] objs) { + return bv.array(objs); + } + } + + protected Pair verilogInstance(final VerilogBlock.Instance inst, + final HierName instance, + final AliasedSet ns, + final VerilogFactoryInterface factory, + final AbstractConverter.BlockValue bv) { + final Pair result = + super.verilogInstance(inst, instance, ns, factory, + new VddGndBlockValue(bv)); + if (clk == null) return result; + final VerilogObject clock = lookupNode(clk, "wire"); + final List ports = new ArrayList(); + ports.add(inst.getPortsByOrder() == null ? + factory.namedPort(factory.ident(clk, false), clock) : clock); + ports.addAll((List) result.getSecond()); + return new Pair(result.getFirst(), ports); + } + + protected void init(final CommandLineArgs theArgs) { + internalWire = theArgs.argExists("internal-net-wire"); + + final String estimatedTauStr = + theArgs.getArgValue("estimated-tau", "100e-12"); + final float estimatedTau = Float.parseFloat(estimatedTauStr); + + if (theArgs.argExists("estimated-delay")) { + final CastQuery.LocalNodes ln = + new CastQuery.LocalNodes(null, cad, false, false, false, false, + false, false, new HashMap(), + estimatedTau); + transportUp = ln.getDelay(cell.cast_cell, true); + transportDn = ln.getDelay(cell.cast_cell, false); + } + if (theArgs.argExists("clk")) { + clk = theArgs.getArgValue("clk", CLK); + } + zoix = theArgs.argExists("zoix"); + skip = theArgs.argExists("skip-power-rail"); + outputDelay = theArgs.argExists("output-delay"); + zeroify = theArgs.argExists("make-gnd-0"); + oneify = theArgs.argExists("make-vdd-1"); + } + + /** + * Create module instantiations for subcells. If a verilog block exist for + * the subcell, and is to be used, then use its content instead of + * instantiating the subcell. + **/ + protected void processSubcells() { + for (Iterator i = cell.getAllSubcellConnections().iterator(); + i.hasNext(); ) { + final ConnectionInfo ci = (ConnectionInfo) i.next(); + final List block = verilogBlock( + ci.nameInParent, + cell.namespace, + ci.child.cast_cell, + chooser, + new DefaultBlockValue(this, cell.namespace, + new UnaryFunction() { + public Object execute(final Object o) { + return wireType((HierName) o); + } + })); + if (block != null) { + items.addAll(block); + continue; + } + final ArrayList args = new ArrayList(); + if (clk != null) addActual(args, clk, "wire"); + actual(args, ci, new UnaryFunction() { + public Object execute(final Object o) { + return wireType((CellNet) o); + } + }); + final VerilogObject ident = factory.ident(ci.nameInParent.getCadenceString(), mAlwaysEscape); + final VerilogObject[] parameters = getModuleParameter(ci); + items.add(factory.moduleInst(ident, + factory.ident(getModuleName(ci.child.cast_cell), mAlwaysEscape), + parameters, + constify(toArray(args)))); + } + } + + /** + * Instantiate a BLACKBOX. Automatically insert a clock signal if + * required. + * + * @param out name to connect the output of the blackbox + * @param up pull up signal + * @param dn pull down signal + * @param box type of black box; this should usually be a macro for + * flexibility at run time. + * + * @return an instantiation of the blackbox + **/ + VerilogObject createBlackBox(final HierName out, + final VerilogObject up, + final VerilogObject dn, + final String box) { + final VerilogObject[] args = new VerilogObject[clk != null ? 4 : 3]; + args[0] = lookupNode(out); + args[1] = up == null ? constify(lookupNode(GND, "wire")) : up; + args[2] = dn == null ? constify(lookupNode(GND, "wire")) : dn; + if (clk != null) args[3] = lookupNode(clk, "wire"); + return factory.moduleInst(factory.ident("network_" + out, + mAlwaysEscape), + macro(box + (clk == null ? "" : "_CLK")), + getDelayExpr(out), + constify(args)); + } + + protected void addParameters() { + final Set seen = new HashSet(); + for (Iterator i = cell.cast_cell.getProductionRuleSet() + .getProductionRules(); i.hasNext(); ) { + final ProductionRule prs = (ProductionRule) i.next(); + final HierName target = prs.getTarget(); + if (seen.add(target)) { + items.add(0, factory.parameter(null, + getExtraDelayParameter(target, true), + factory.expr("0.0"))); + items.add(0, factory.parameter(null, + getExtraDelayParameter(target, false), + factory.expr("0.0"))); + } + } + items.add(0, factory.parameter(null, getDelayBiasParameter(), + factory.expr("1.0"))); + } + + protected String getIdent(final VerilogObject o) { + final String[] result = new String[] { null }; + final boolean[] found = new boolean[] { false }; + o.accept(new TrivialVisitor() { + public void ident(final String ident, final boolean escape) { + if (found[0]) { result[0] = null; } + else { + found[0] = true; + result[0] = ident; + } + } + }); + return result[0]; + } + + protected VerilogObject constify(final VerilogObject o) { + final VerilogObject result; + if (zeroify && "GND".equals(getIdent(o))) { + result = factory.expr("1'b0"); + } else if (oneify && "Vdd".equals(getIdent(o))) { + result = factory.expr("1'b1"); + } else { + result = o; + } + return result; + } + + protected VerilogObject[] constify(final VerilogObject[] o) { + if (!zeroify && !oneify) return o; + final VerilogObject[] result = new VerilogObject[o.length]; + for (int i = 0; i < o.length; ++i) { + result[i] = constify(o[i]); + } + return result; + } + + public abstract VerilogObject convert(final CommandLineArgs theArgs, + final VerilogObject moduleName, + final boolean toplevel, + final boolean topEnv); +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetlistConverter.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetlistConverter.java new file mode 100644 index 0000000000..0c74683a46 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/NetlistConverter.java @@ -0,0 +1,351 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + + +package com.avlsi.tools.prs2verilog; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import org.antlr.stringtemplate.StringTemplate; + +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cell.CellUtils; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellNet; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.VerilogBlock; +import com.avlsi.fast.ports.PortDefinition; +import com.avlsi.file.common.HierName; +import com.avlsi.prs.ProductionRule; +import com.avlsi.prs.ProductionRuleSet; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.prs2verilog.verilog.Delay; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.util.bool.AndBooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionInterface; +import com.avlsi.util.bool.BooleanExpressionVisitorInterface; +import com.avlsi.util.bool.HierNameAtomicBooleanExpression; +import com.avlsi.util.bool.OrBooleanExpressionInterface; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.DefaultedMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.UnaryFunction; + +/** Convert to a Verilog netlist, i.e., Verilog with only macro instantiations + * and macro definitions without the body. */ +class NetlistConverter extends AbstractConverter { + private static final String CLK = "CLK"; + private final CellType cell; + private final Map up, down; + private final ConnectionInfo ports; + private boolean skip = false; + private boolean keepCsp = false; + private boolean skipRouted = false; + private String routedClk = CLK; + private String clk = null; + private final HierName Vdd, GND; + private final static String DEFAULT_POWER_GRID = + "$lib$.wires.$type$_$subtype$_POWER_GRID_TIEOFF"; + private final static Pattern COMPONENTS = + Pattern.compile("(.*)\\.([^.]+)\\.([^.]+)"); + private final Prs2Verilog.VerilogChooser chooser; + + public NetlistConverter(final CellType cell, + final VerilogFactoryInterface factory, + final ConnectionInfo ports, + final HierName Vdd, + final HierName GND, + final boolean alwyasEscape, + final Prs2Verilog.VerilogChooser chooser) { + super(factory, alwyasEscape); + this.cell = cell; + this.up = new HashMap(); + this.down = new HashMap(); + this.ports = ports; + this.Vdd = Vdd; + this.GND = GND; + this.chooser = chooser; + } + + private String h2s(final HierName h) { + return h.getCadenceString(); + } + protected void addFormal(final List params, final String name, + final String type, final String dir) { + if (!skip || (!name.equals("Vdd") && !name.equals("GND"))) + super.addFormal(params, name, type, dir); + } + protected void addActual(final boolean byName, final List params, + final HierName child, final HierName parent, + final String type) { + if (!skip || (!child.isVdd() && !child.isGND())) + super.addActual(byName, params, child, parent, type); + } + private void processSubcells(boolean byName) { + final List block = verilogBlock( + null, + cell.namespace, + cell.cast_cell, + chooser, + new DefaultBlockValue(this, cell.namespace, + new UnaryFunction() { + public Object execute(final Object o) { + return "wire"; + } + })); + if (block != null) { + items.addAll(block); + return; + } + + for (Iterator i = cell.getAllSubcellConnections().iterator(); + i.hasNext(); ) { + final ConnectionInfo ci = (ConnectionInfo) i.next(); + final ArrayList args = new ArrayList(); + + // temporarily change the setting of skip to always skip power + // rails on hard macro routed cells + final boolean oldSkip = skip; + if (skipRouted && CellUtils.isRouted(ci.child.cast_cell)) { + skip = true; + } + actual(args, ci, "wire", byName); + if (skipRouted && CellUtils.isRouted(ci.child.cast_cell)) { + skip = oldSkip; + } + + if (clk != null) { + addActual(byName, + args, + HierName.makeHierName( + CellUtils.isRouted(ci.child.cast_cell) ? routedClk + : clk), + HierName.makeHierName(clk), + "wire"); + } + final VerilogObject ident = + factory.ident(ci.nameInParent.getCadenceString(), true); + final VerilogObject[] parameters = getModuleParameter(ci); + items.add(factory.moduleInst(ident, + factory.ident(ci.child.cast_cell + .getFullyQualifiedType(), true), + parameters, + (VerilogObject[]) + args.toArray(new VerilogObject[0]))); + } + } + + private String getPowerGridName(final String cellName, final String templ) { + final StringTemplate st = new StringTemplate(templ); + final Matcher m = COMPONENTS.matcher(cellName); + if (m.matches()) { + st.setAttribute("lib", m.group(1)); + st.setAttribute("type", m.group(2)); + st.setAttribute("subtype", m.group(3)); + return st.toString(); + } else { + throw new RuntimeException("Cannot parse cell name " + cellName + + " into components"); + } + } + + private Map getMapping(final CellType cell, + final Prs2Verilog.VerilogChooser chooser) { + try { + final GeneratePortMapping mapper = + new GeneratePortMapping(factory, cell.cast_cell, chooser, + false, new Cadencize(false)); + final VerilogObject block = + mapper.convert(null, null, false, false); + if (block == null) { + return null; + } else { + final Map map = new LinkedHashMap(); + GeneratePortMapping.generateMapping(map, Collections.emptyMap(), + mapper.getBounds(), + block); + return map; + } + } catch (Exception e) { + return null; + } + } + + public VerilogObject convert(final CommandLineArgs theArgs, + VerilogObject moduleName, + final boolean toplevel, + final boolean topEnv) { + final String renameBlock = theArgs.getArgValue("name-map-block", null); + final Prs2Verilog.VerilogChooser renameChooser = + renameBlock == null ? null + : new Prs2Verilog.SimpleChooser(renameBlock); + + keepCsp = theArgs.argExists("keep-csp"); + // do not generate anything for routed cells, unless it's the toplevel + skipRouted = theArgs.argExists("skip-routed"); + // named of the clock pin on routed cells + routedClk = theArgs.getArgValue("routed-clk", CLK); + + if (unconvertible(cell) && + !(keepCsp && cell.cast_cell.hasRunnableCsp())) return null; + + if (!toplevel && skipRouted && CellUtils.isRouted(cell.cast_cell)) + return null; + + skip = theArgs.argExists("skip-power-rail"); + final boolean routed = theArgs.argExists("routed"); + if (theArgs.argExists("clk")) { + clk = theArgs.getArgValue("clk", CLK); + } + + final ArrayList params = new ArrayList(); + final Map verilogMap = + renameChooser == null ? null + : (Map) getMapping(cell, renameChooser); + if (verilogMap == null) { + formal(params, ports, "wire"); + if (clk != null) addFormal(params, clk, "wire", "input"); + } else { + final Collection portOrder = new LinkedHashSet(); + + final Map max = + new DefaultedMap( + Integer.MIN_VALUE, + new HashMap()); + + final Map min = + new DefaultedMap( + Integer.MAX_VALUE, + new HashMap()); + + final Map portDir = + CellUtils.getCanonicalDir(new HashMap(), + cell.cast_cell, cell.namespace); + + final Map baseDir = + new HashMap(); + + final Pattern pat = Pattern.compile("^(.*)\\[(\\d+)\\]$"); + for (Map.Entry e : verilogMap.entrySet()) { + final Matcher m = pat.matcher(e.getKey()); + final CellNet net = cell.getNet(toHier(e.getValue())); + final HierName canon = net.canonicalName; + final String base; + if (m.matches()) { + base = m.group(1); + final int idx = Integer.parseInt(m.group(2)); + max.put(base, Math.max(max.get(base), idx)); + min.put(base, Math.min(min.get(base), idx)); + portOrder.add(base); + nodes.put( + h2s(canon), + factory.arrayAccess( + factory.ident(base, mAlwaysEscape), + factory.expr(m.group(2)))); + } else { + base = e.getKey(); + nodes.put( + h2s(canon), + factory.ident(e.getKey(), mAlwaysEscape)); + } + portOrder.add(base); + + final Integer newDir = portDir.get(canon); + final Integer oldDir = baseDir.get(base); + if (oldDir == null) { + baseDir.put(base, newDir); + } else { + if (!oldDir.equals(newDir)) { + baseDir.put(base, PortDefinition.INOUT); + } + } + } + + for (String port : portOrder) { + final int dir = baseDir.get(port); + final String inout = + dir == PortDefinition.IN ? "input" : + (dir == PortDefinition.OUT ? "output" : "inout"); + if (max.containsKey(port)) { + final int hi = max.get(port); + final int lo = min.get(port); + final String range = " [" + hi + ":" + lo + "]"; + addFormal(params, port, "wire" + range, inout + range); + } else { + addFormal(params, port, "wire", inout); + } + } + + final VerilogBlock.NamedBlock block = + chooseVerilog(cell.cast_cell, renameChooser); + String name = (String) DirectiveUtils.gruntDirective(block, + DirectiveConstants.NAME_MAPPING); + if (name == null) { + final VerilogBlock.Instance first = + (VerilogBlock.Instance) block.getInstances().next(); + name = first.getModule(); + } + moduleName = factory.ident(name, mAlwaysEscape); + } + + if (toplevel || !routed || !CellUtils.isRouted(cell.cast_cell)) { + // should the module instantiation done by position or by name + processSubcells(theArgs.argExists("by-name")); + } + + if (toplevel) { + final ArrayList args = new ArrayList(); + // temporarily turn off skip + final boolean oldSkip = skip; + skip = false; + addActual(true, args, GND, GND, "wire"); + addActual(true, args, Vdd, Vdd, "wire"); + + final VerilogObject ident = factory.ident("tiehilo", true); + final String tieoff = getPowerGridName(cell.typeName, + theArgs.getArgValue("power-grid-template", DEFAULT_POWER_GRID)); + if (!tieoff.equals("")) { + items.add( + factory.moduleInst( + ident, + factory.ident(tieoff, true), + null, + (VerilogObject[]) + args.toArray(new VerilogObject[0]))); + } + skip = oldSkip; + } + + items.addAll(0, wireDecl); + items.addAll(0, inout); + return factory.module(moduleName == null ? + factory.ident(cell.cast_cell + .getFullyQualifiedType(), true) : + moduleName, + (VerilogObject[]) + params.toArray(new VerilogObject[0]), + (VerilogObject[]) + items.toArray(new VerilogObject[0])); + } +} diff --git a/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/Prs2Verilog.java b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/Prs2Verilog.java new file mode 100644 index 0000000000..7303fd0612 --- /dev/null +++ b/async-toolkit/jtools/cad/java/src/com/avlsi/tools/prs2verilog/Prs2Verilog.java @@ -0,0 +1,1149 @@ +/* + * Copyright 2002 Fulcrum Microsystems. All rights reserved. + * $Id$ + * $DateTime$ + * $Author$ + */ + +package com.avlsi.tools.prs2verilog; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import com.avlsi.cast.CastFileParser; +import com.avlsi.cast.CastSyntaxException; +import com.avlsi.cast.CastSemanticException; +import com.avlsi.cast.impl.CastParserEnvironment; +import com.avlsi.cast2.directive.DirectiveConstants; +import com.avlsi.cast2.directive.impl.DirectiveTable; +import com.avlsi.cast2.util.DirectiveUtils; +import com.avlsi.cast2.util.StandardParsingOption; +import com.avlsi.cell.CellInterface; +import com.avlsi.cell.CellUtils; +import com.avlsi.cell.NoSuchEnvironmentException; +import com.avlsi.fast.BlockInterface; +import com.avlsi.fast.BlockIterator; +import com.avlsi.fast.CastDesign; +import com.avlsi.fast.CellType; +import com.avlsi.fast.CellTypeProcessor; +import com.avlsi.fast.ConnectionInfo; +import com.avlsi.fast.VerilogBlock; +import com.avlsi.file.common.HierName; +import com.avlsi.file.common.InvalidHierNameException; +import com.avlsi.file.cdl.util.rename.CDLNameInterface; +import com.avlsi.file.cdl.util.rename.CDLRenameException; +import com.avlsi.file.cdl.util.rename.CadenceNameInterface; +import com.avlsi.file.cdl.util.rename.CadenceReverseNameInterface; +import com.avlsi.file.cdl.util.rename.GDS2NameInterface; +import com.avlsi.file.cdl.util.rename.IdentityNameInterface; +import com.avlsi.io.FileSearchPath; +import com.avlsi.io.SearchPath; +import com.avlsi.io.SearchPathFile; +import com.avlsi.tools.cadencize.Cadencize; +import com.avlsi.tools.cosim.CoSimParameters; +import com.avlsi.tools.cosim.CoSimHelper; +import com.avlsi.tools.cosim.spec.*; +import com.avlsi.tools.dsim.ExceptionPrettyPrinter; +import com.avlsi.tools.dsim.NoBehaviorFoundException; +import com.avlsi.tools.jauto.GlobalNet; +import com.avlsi.tools.jauto.JautoMessageCenter; +import com.avlsi.tools.jauto.TechnologyData; +import com.avlsi.tools.prs2verilog.ConverterInterface; +import com.avlsi.tools.prs2verilog.GateConverter; +import com.avlsi.tools.prs2verilog.NetgraphConverter; +import com.avlsi.tools.prs2verilog.NetlistConverter; +import com.avlsi.tools.prs2verilog.TriConverter; +import com.avlsi.tools.prs2verilog.verilog.SimpleRenamingVerilogFactory; +import com.avlsi.tools.prs2verilog.verilog.VerilogObject; +import com.avlsi.tools.prs2verilog.verilog.VerilogEmitter; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryInterface; +import com.avlsi.tools.prs2verilog.verilog.VerilogFactoryImpl; +import com.avlsi.tools.prs2verilog.verilog.VerilogUtil; +import com.avlsi.tools.prs2verilog.verilog.VerilogVisitor; +import com.avlsi.util.cmdlineargs.CommandLineArg; +import com.avlsi.util.cmdlineargs.CommandLineArgFormatException; +import com.avlsi.util.cmdlineargs.CommandLineArgs; +import com.avlsi.util.cmdlineargs.CommandLineArgsUtil; +import com.avlsi.util.cmdlineargs.InvalidCommandLineArgException; +import com.avlsi.util.cmdlineargs.MissingCommandLineArgException; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsDefImpl; +import com.avlsi.util.cmdlineargs.defimpl.CachingCommandLineArgs; +import com.avlsi.util.cmdlineargs.defimpl.CommandLineArgsWithConfigFiles; +import com.avlsi.util.container.AliasedSet; +import com.avlsi.util.container.MultiMap; +import com.avlsi.util.container.Pair; +import com.avlsi.util.debug.Debug; +import com.avlsi.util.functions.BinaryAction; +import com.avlsi.util.functions.UnaryPredicate; +import com.avlsi.util.text.StringUtil; + +public class Prs2Verilog { + /** + * This class should not be instantiated. + **/ + private Prs2Verilog() { } + + /** + * Choose the named Verilog block to use. Return null if the + * verilog block should not be used. + **/ + public interface VerilogChooser { + VerilogBlock.NamedBlock choose(final CellInterface cell, + final VerilogBlock vb); + } + + public static class NullChooser implements VerilogChooser { + public VerilogBlock.NamedBlock choose(final CellInterface cell, + final VerilogBlock vb) { + return null; + } + } + + public static class SimpleChooser implements VerilogChooser { + private final String name; + public SimpleChooser(final String name) { + this.name = name; + } + public VerilogBlock.NamedBlock choose(final CellInterface cell, + final VerilogBlock vb) { + return vb.getNamedBlock(name); + } + } + + public static class DefaultChooser implements VerilogChooser { + private final String def; + private final Map map; + + public DefaultChooser(final String def, final Map map) { + this.def = def; + this.map = map; + } + + public VerilogBlock.NamedBlock choose(final CellInterface cell, + final VerilogBlock vb) { + final String c = (String) map.get(cell.getFullyQualifiedType()); + VerilogBlock.NamedBlock result; + if (c == null) { + result = vb.getNamedBlock(def); + if (result == null) { + final Iterator i = vb.getNamesIterator(); + if (i.hasNext()) { + final String first = (String) i.next(); + if (!i.hasNext()) { + result = vb.getNamedBlock(first); + } else { + throw new RuntimeException("Default named verilog block " + def + " not found in " + cell.getFullyQualifiedType() + ", which also has multiple named verilog blocks."); + } + } + } + } else { + result = vb.getNamedBlock(c); + if (result == null) { + throw new RuntimeException("Cannot find named verilog block " + c + " in cell " + cell.getFullyQualifiedType()); + } + } + return result; + } + } + + public static class CosimChooser implements VerilogChooser { + private final MultiMap typeBehaviors; + public CosimChooser(final MultiMap typeBehaviors) { + this.typeBehaviors = typeBehaviors; + } + public VerilogBlock.NamedBlock choose(final CellInterface cell, + final VerilogBlock vb) { + final Collection behs = + (Collection) typeBehaviors.get(cell.getFullyQualifiedType()); + assert behs.size() == 1; + final Mode m = (Mode) behs.iterator().next(); + if (m instanceof Mode.VerilogMode) { + final String level = ((Mode.VerilogMode) m).getLevel(); + return vb.getNamedBlock(level); + } + return null; + } + } + + public interface VisitorFactory { + VerilogVisitor getVisitor(final String cellName); + void doneVisitor(final VerilogVisitor visitor); + } + + private static String getCopyright() { + return "/* Copyright " + Calendar.getInstance().get(Calendar.YEAR) + " Intel Corporation. All rights reserved.\n * Automatically generated. Modify at your own risk.\n */\n"; + } + + private static void writeHeader(final Writer w, final String cell) + throws IOException { + w.write("`ifndef " + cell + "\n"); + w.write("`define " + cell + " 1\n"); + } + + private static void writeFooter(final Writer w) + throws IOException { + w.write("`endif\n"); + } + + public static class SingleWriterVisitor implements VisitorFactory { + private final Writer w; + private final VerilogEmitter emitter; + private final boolean ifdef; + public SingleWriterVisitor(final Writer writer) { + this(writer, false); + } + public SingleWriterVisitor(final Writer writer, final boolean ifdef) { + this.w = writer; + emitter = new VerilogEmitter(writer); + this.ifdef = ifdef; + } + public VerilogVisitor getVisitor( final String cellName ) { + if (ifdef) { + try { + final String cond = VerilogUtil.escapeIfNeeded(cellName); + writeHeader(w, cond); + } catch (IOException e) { + throw new RuntimeException("Cannot write to file", e); + } + } + return emitter; + } + public void doneVisitor(final VerilogVisitor visitor) { + try { + if (ifdef) writeFooter(w); + emitter.flush(); + w.flush(); + } catch (IOException e) { + throw new RuntimeException("Cannot flush output", e); + } + } + } + + public static class MultipleFileVisitor implements VisitorFactory { + private final File dir, sdir; + private final Map visitors; + private final Collection files; + private final boolean relativePath; + private final String copyright; + private final CDLNameInterface namer; + private final boolean ifdef; + public MultipleFileVisitor(final String out, final String special, + final Collection files, + final boolean relativePath) { + this(out, special, files, relativePath, false); + } + public MultipleFileVisitor(final String out, final String special, + final Collection files, + final boolean relativePath, + final boolean ifdef) { + this(out, special, files, relativePath, + new TruncatingRenamer(new IdentityNameInterface()), ifdef); + } + public MultipleFileVisitor(final String out, final String special, + final Collection files, + final boolean relativePath, + final CDLNameInterface namer, + final boolean ifdef) { + this(new File(out), special, files, relativePath, namer, ifdef); + } + public MultipleFileVisitor(final File dir, final String special, + final Collection files, + final boolean relativePath, + final CDLNameInterface namer, + final boolean ifdef) { + this.dir = dir; + if (!dir.exists() && !dir.mkdir()) { + throw new RuntimeException("Cannot create directory: " + dir); + } + sdir = special == null ? null : new File(special); + visitors = new HashMap(); + this.files = files; + this.relativePath = relativePath; + this.copyright = getCopyright(); + this.namer = namer; + this.ifdef = ifdef; + } + public VerilogVisitor getVisitor(final String cellName) { + final String name; + try { + name = namer.renameCell(cellName) + ".v"; + } catch (CDLRenameException e) { + throw new RuntimeException("Cannot rename " + cellName, e); + } + final File sfile = new File(sdir, name); + if (sdir != null && sfile.exists()) { + try { + files.add(sfile.getCanonicalPath()); + } catch (IOException e) { + throw new RuntimeException("Cannot get canonical path for " + sfile, e); + } + return null; + } + + final File out = new File(dir, name); + try { + files.add(relativePath ? name : out.getCanonicalPath()); + } catch (IOException e) { + throw new RuntimeException("Cannot get canonical path for " + out, e); + } + + final Writer w; + try { + w = new BufferedWriter(new FileWriter(out)); + w.write(copyright); + if (ifdef) { + final String cond = VerilogUtil.escapeIfNeeded(cellName); + writeHeader(w, cond); + } + } catch (IOException e) { + throw new RuntimeException("Cannot write to file: " + out, e); + } + + final VerilogVisitor visitor = new VerilogEmitter(w); + visitors.put(visitor, new Pair(w, out)); + + return visitor; + } + public void doneVisitor(final VerilogVisitor visitor) { + final Pair p = (Pair) visitors.get(visitor); + if (p != null) { + final Writer w = (Writer) p.getFirst(); + try { + if (ifdef) writeFooter(w); + ((VerilogEmitter) visitor).flush(); + w.close(); + } catch (IOException e) { + final File f = (File) p.getSecond(); + throw new RuntimeException("Cannot close file: " + f, e); + } + visitors.remove(visitor); + } + } + } + + private static class TruncatingRenamer implements CDLNameInterface { + private final CDLNameInterface inner; + public TruncatingRenamer(final CDLNameInterface inner) { + this.inner = inner; + } + private String truncate(final String s) { + return CellUtils.hashMetaParameters(s.replace('$', '_')); + } + public String renameCell(final String oldCellName) + throws CDLRenameException { + return truncate(inner.renameCell(oldCellName)); + } + public String renameNode(final String oldNodeName) + throws CDLRenameException { + return inner.renameNode(oldNodeName); + } + public String renameDevice(final String oldDeviceName) + throws CDLRenameException { + return inner.renameDevice(oldDeviceName); + } + public String renameSubCellInstance(final String oldInstanceName) + throws CDLRenameException { + return inner.renameSubCellInstance(oldInstanceName); + } + public String renameTransistorModel(final String oldTransistorModel) + throws CDLRenameException { + return inner.renameTransistorModel(oldTransistorModel); + } + } + + private static class KeywordRenamer implements CDLNameInterface { + private final CDLNameInterface inner; + public KeywordRenamer(final CDLNameInterface inner) { + this.inner = inner; + } + private String dekeyword(final String s) { + return VerilogUtil.isKeyword(s) ? s + "$keyword" : s; + } + public String renameCell(final String oldCellName) + throws CDLRenameException { + return dekeyword(inner.renameCell(oldCellName)); + } + public String renameNode(final String oldNodeName) + throws CDLRenameException { + return dekeyword(inner.renameNode(oldNodeName)); + } + public String renameDevice(final String oldDeviceName) + throws CDLRenameException { + return dekeyword(inner.renameDevice(oldDeviceName)); + } + public String renameSubCellInstance(final String oldInstanceName) + throws CDLRenameException { + return dekeyword(inner.renameSubCellInstance(oldInstanceName)); + } + public String renameTransistorModel(final String oldTransistorModel) + throws CDLRenameException { + return dekeyword(inner.renameTransistorModel(oldTransistorModel)); + } + } + + private static class OliverRenamer implements CDLNameInterface { + private final CDLNameInterface inner; + private String bracket(final String s) { + return s.replaceAll("\\[", "_L_").replaceAll("\\]", "_R_"); + } + public OliverRenamer() { + this.inner = new CadenceNameInterface(); + } + public String renameCell(final String oldCellName) + throws CDLRenameException { + return inner.renameCell(oldCellName); + } + public String renameNode(final String oldNodeName) + throws CDLRenameException { + return bracket(inner.renameNode(oldNodeName)); + } + public String renameDevice(final String oldDeviceName) + throws CDLRenameException { + return inner.renameDevice(oldDeviceName); + } + public String renameSubCellInstance(final String oldInstanceName) + throws CDLRenameException { + return bracket(inner.renameSubCellInstance(oldInstanceName)); + } + public String renameTransistorModel(final String oldTransistorModel) + throws CDLRenameException { + return inner.renameTransistorModel(oldTransistorModel); + } + } + + private static final Map portInfo = new HashMap(); + private static final HierName Vdd = HierName.makeHierName("Vdd"); + private static final HierName GND = HierName.makeHierName("GND"); + private static final HierName _RESET = HierName.makeHierName("_RESET"); + + private static CastDesign loadDesign(final CellInterface cell, + final Cadencize cad, + final CommandLineArgs theArgs) { + + // tdata should be final, but jikes doesn't know (and isn't + // required to know) that usage() never returns. + // tdata only needed when trying to minimize-tri-regs + if (theArgs.argExists("minimize-tri-regs")) { + TechnologyData tdata = null; + try { + tdata = new TechnologyData(theArgs); + } catch (CommandLineArgFormatException e) { + System.err.println(e.toString()); + usage(); + } catch (InvalidCommandLineArgException e) { + System.err.println(e.toString()); + usage(); + } catch (MissingCommandLineArgException e) { + System.err.println(e.toString()); + usage(); + } + /* 100 is any non-zero TAU */ + return new CastDesign(cell, Vdd, GND, _RESET, 1000, tdata, cad, + null, + !theArgs.argExists("ignore-asta-extra-delay")); + } else { + /* 100 is any non-zero TAU */ + return new CastDesign(cell, Vdd, GND, _RESET, 100, null, cad, + null, + !theArgs.argExists("ignore-asta-extra-delay")); + } + + } + + private static CellType loadCell(final CastDesign design, + final CellInterface ci, + final CastFileParser cfp, + final CommandLineArgs theArgs) { + return loadCell(design, ci, cfp, + theArgs.argExists("minimize-tri-regs"), + theArgs.getArgValue("gates", null)); + } + + private static CellType loadCell(final CastDesign design, + final CellInterface ci, + final CastFileParser cfp, + final boolean minimizeTriRegs, + final String gates) { + final CellType top = design.getTopLevelCell(); + fillPortInfo(top); + + final CellType cell = findCell(top, ci.getFullyQualifiedType()); + final CellType newCell; + + // Create half-operators and global nets so that can determine isShared in converter + if (minimizeTriRegs) { + final String[] gateNames; + if (gates == null) gateNames = new String[0]; + else gateNames = StringUtil.split(gates, ':'); + + design.setMessageCenter(new JautoMessageCenter()); + newCell = cell.instanceMinimalSubTypes(CastDesign.TRANSISTORS, + /*staticizer*/ null, + /*weakInverter*/ null, + /*smallInveretr*/ null, + gateNames, /* list of gates we will match to */ + cfp); + GlobalNet.generateGlobalNets(newCell, new ArrayList()); + } else { + newCell = cell; + } + return newCell; + } + + private static void fillPortInfo(final CellType top) { + top.walkOnce(new CellTypeProcessor() { + public void processCellType(CellType c) { + for (Iterator i = c.getAllSubcellConnections().iterator(); + i.hasNext(); ) { + ConnectionInfo ci = (ConnectionInfo) i.next(); + final String childTypeName = + ci.child.cast_cell.getFullyQualifiedType(); + if (!portInfo.containsKey(childTypeName)) { + portInfo.put(childTypeName, ci); + } + } + } + }); + } + + private static CellType findCell(final CellType top, final String name) { + final CellType[] result = new CellType[1]; + top.walkOnce(new CellTypeProcessor() { + public void processCellType(CellType c) { + if (c.cast_cell.getFullyQualifiedType().equals(name)) { + result[0] = c; + } + } + }); + return result[0]; + } + + private static + ConverterInterface getConverter(final String type, final CellType cell, + final VerilogFactoryInterface factory, + final ConnectionInfo ports, + final HierName Vdd, final HierName GND, + final boolean alwaysEscape, + final VerilogChooser chooser, + final Cadencize cad, + final boolean minimizeTriRegs) { + final ConverterInterface cv; + if (type.equals("gate")) { + cv = new GateConverter(cell, factory, ports, GND, alwaysEscape, chooser, cad); + } else if (type.equals("tri")) { + cv = new TriConverter(cell, factory, ports, alwaysEscape); + } else if (type.equals("netgraph")) { + cv = new NetgraphConverter(cell, factory, ports, Vdd, GND, + alwaysEscape, chooser, cad, minimizeTriRegs); + } else if (type.equals("netlist")) { + cv = new NetlistConverter(cell, factory, ports, Vdd, GND, alwaysEscape, chooser); + } else { + cv = null; + } + return cv; + } + + public static Map writeVerilog(final CellInterface topCell, + final VisitorFactory visitorFactory, + final CastFileParser cfp, + final CommandLineArgs theArgs, + final VerilogFactoryInterface verilogFactory, + final String converter, + final boolean alwaysEscape) { + return writeVerilog(topCell, visitorFactory, cfp, theArgs, + verilogFactory, converter, alwaysEscape, null); + } + + public static Map writeVerilog(final CellInterface topCell, + final VisitorFactory visitorFactory, + final CastFileParser cfp, + final CommandLineArgs theArgs, + final VerilogFactoryInterface verilogFactory, + final String converter, + final boolean alwaysEscape, + final CoSim cosim) { + final Cadencize cad = new Cadencize(true, true); + final CastDesign design = loadDesign( topCell, cad, theArgs ); + final CellType cell = loadCell(design, topCell, cfp, theArgs); + + if (cell == null) { + throw new RuntimeException( "Unable to get CellType for \"" + + topCell.getFullyQualifiedType() + + "\"." ); + } else { + try { + return writeVerilog(cell, converter, theArgs, verilogFactory, visitorFactory, alwaysEscape, getChooser(cosim, topCell, theArgs), false, cad, theArgs.argExists("minimize-tri-regs"), false); + } catch (Exception e) { + throw new RuntimeException("Invalid cosim spec specified", e); + } + } + } + + private static VerilogChooser getChooser(final CoSim cosim, + final CellInterface castCell, + final CommandLineArgs theArgs) + throws DuplicateInstanceSpecException, + ExtraInstanceSpecException, + HierarchyDepthException, + NoBehaviorFoundException, + NoSuchInstanceException, + NoSuchEnvironmentException { + VerilogChooser chooser = parseVerilogBlock(theArgs); + + if (chooser == null && cosim != null) { + final String envName = cosim.getEnvName(); + + final CoSimParameters coSimParams = new CoSimParameters(); + final MultiMap behaviorType = new MultiMap(); + CoSimHelper.setCoSimParams("x", castCell, cosim.getCoSimSpecList(), + coSimParams, null, false); + CoSimHelper.getBehaviorByType(castCell, coSimParams, + HierName.makeHierName("x"), + behaviorType); + if (envName != null) { + final CellInterface envCell = castCell.getEnvironment(envName); + CoSimHelper.setCoSimParams("_env", envCell, + new CoSimSpecList( + new CoSimSpec[] { cosim.getEnvSpec() }), + coSimParams, null, false); + CoSimHelper.getBehaviorByType(envCell, coSimParams, + HierName.makeHierName("_env"), + behaviorType); + } + + final List tooManyBehaviors = new ArrayList(); + for (Iterator i = behaviorType.keySet().iterator(); i.hasNext(); ) { + final String key = (String) i.next(); + final Collection behs = (Collection) behaviorType.get(key); + if (behs.size() > 1) tooManyBehaviors.add(key); + } + if (!tooManyBehaviors.isEmpty()) { + System.err.println("Only one behavior per cell is supported:"); + for (Iterator i = tooManyBehaviors.iterator(); i.hasNext(); ) { + final String key = (String) i.next(); + System.err.print(key + ":"); + final Collection behs = (Collection) behaviorType.get(key); + for (Iterator j = behs.iterator(); j.hasNext(); ) { + System.err.print(" " + j.next()); + } + } + System.err.println(); + System.exit(2); + } + chooser = new CosimChooser(behaviorType); + } + + return chooser; + } + + private static void walk(final CellType cell, final CellTypeProcessor p, + final VerilogChooser chooser, final boolean routed, + final UnaryPredicate stopRecurse, + final HashSet seen, final boolean inlineVerilog) { + if (!seen.add(cell)) return; + // Do not visit this cell or its subcells if a Verilog block for this + // cell is to be used. + boolean chooseVerilog = + AbstractConverter.chooseVerilog(cell.cast_cell, chooser) != null; + + if (inlineVerilog && chooseVerilog) return; + + p.processCellType(cell); + + // Do not visit the subcells if we are considering the routed + // directive, as the cell should be considered a black box. + // But always visit the subcells of the top level cell, even if + // routed=true; otherwise there is no way to route the top level + if (routed && CellUtils.isRouted(cell.cast_cell) && seen.size() > 1 || + chooseVerilog) + return; + + if (stopRecurse.evaluate(cell.cast_cell)) return; + + for (Iterator i = cell.getAllSubcellConnections().iterator(); + i.hasNext(); ) { + final CellType subcell = ((ConnectionInfo) i.next()).child; + walk(subcell, p, chooser, routed, stopRecurse, seen, inlineVerilog); + } + } + + private static Map writeVerilog(final CellType cell, + final String converter, + final CommandLineArgs theArgs, + final VerilogFactoryInterface f, + final VisitorFactory vfact, + final boolean alwaysEscape, + final VerilogChooser chooser, + final boolean hasEnv, + final Cadencize cad, + final boolean minimizeTriRegs, + final boolean routed) { + return writeVerilog(cell, converter, theArgs, f, vfact, alwaysEscape, + chooser, hasEnv, cad, minimizeTriRegs, + new UnaryPredicate.Constant(false), routed); + } + + private static Map writeVerilog(final CellType cell, + final String converter, + final CommandLineArgs theArgs, + final VerilogFactoryInterface f, + final VisitorFactory vfact, + final boolean alwaysEscape, + final VerilogChooser chooser, + final boolean hasEnv, + final Cadencize cad, + final boolean minimizeTriRegs, + final UnaryPredicate stopRecurse, + final boolean routed) { + final Map depends = new HashMap(); + final VerilogChooser realChooser = + chooser == null ? new NullChooser() : chooser; + walk(cell, new CellTypeProcessor() { + boolean topEnv = hasEnv; + String topName = theArgs.getArgValue("toplevel", null); + boolean toplevel = true; + public void processCellType(CellType c) { + final VerilogObject top = f.ident( + topName == null ? CellUtils.hashMetaParameters(c.typeName) + : topName, alwaysEscape); + + final VerilogVisitor visitor = vfact.getVisitor(c.typeName); + if (visitor == null) return; + + final ConnectionInfo p = (ConnectionInfo) + portInfo.get(c.cast_cell.getFullyQualifiedType()); + assert p != null : "Cannot produce Verilog for top-level cell: " + c.cast_cell.getFullyQualifiedType(); + final ConverterInterface cv = getConverter(converter, c, f, p, Vdd, GND, alwaysEscape, realChooser, cad, + minimizeTriRegs); + if (cv == null) + throw new RuntimeException("Unknown converter type: " + converter); + final VerilogObject vo = + cv.convert(theArgs, top, toplevel, topEnv); + topName = null; + topEnv = false; + toplevel = false; + if (vo == null) return; + + final Map dependencies = cv.getDependencies(); + if (dependencies.size() > 0) { + depends.putAll(dependencies); + } + + try { + vo.accept(visitor); + } catch (Exception e) { + throw new RuntimeException("Cannot convert cell " + cell.typeName, e); + } + vfact.doneVisitor(visitor); + } + }, realChooser, routed, stopRecurse, new HashSet(), + !theArgs.argExists("uninline-verilog")); + return depends; + } + + public static void verilogFiles(final Map dependencies, + final Set goodfiles) { + for (Iterator i = dependencies.entrySet().iterator(); i.hasNext(); ) { + final Map.Entry entry = (Map.Entry) i.next(); + final CellInterface ci = (CellInterface) entry.getKey(); + + final String[] f = (String[]) entry.getValue(); + for (int j = 0; j < f.length; ++j) { + goodfiles.add(f[j]); + } + } + } + + /** + * Runs the netgraph converter on the specified cell. + * + * @param cell cell to convert + * @param level named verilog block to choose, or null if + * verilog blocks should not be considered + * @param theArgs arguments to pass on to the netgraph converter + * @param validVerilogFiles verilog files needed by verilog blocks that are + * found + * @param invalidVerilogFiles verilog files needed by verilog blocks that + * are not found + **/ + public static void emitVerilogBlock(final CellInterface cell, + final Cadencize cad, + final String level, + final VisitorFactory vfact, + final CommandLineArgs theArgs, + final Set validVerilogFiles) + throws IOException { + final CastDesign design = + new CastDesign(cell, Vdd, GND, _RESET, 100, null, cad, null, + !theArgs.argExists("ignore-asta-extra-delay")); + final CellType top = design.getTopLevelCell(); + fillPortInfo(top); + + final CellType ct = findCell(top, cell.getFullyQualifiedType()); + // CastDesign always creats a dummy top-level cell with the same name; + // CadenceInfo for this dummy cell cannot be shared, so we remove it + // explicitly + cad.removeCachedCadenceInfo(top.typeName); + + final SimpleChooser chooser = + level == null ? null : new SimpleChooser(level); + final Map dependencies = + writeVerilog(ct, "netgraph", theArgs, + new VerilogFactoryImpl(), + vfact, true, chooser, false, cad, false, false); + + verilogFiles(dependencies, validVerilogFiles); + + } + + public static void emitVerilogNetlist(final CellInterface cell, + final Cadencize cad, + final VisitorFactory vfact, + final UnaryPredicate stopRecurse, + final CDLNameInterface renamer, + final CommandLineArgs theArgs) + throws IOException { + final CastDesign design = + new CastDesign(cell, Vdd, GND, _RESET, 100, null, cad, null, + 1, Collections.emptySet(), + Collections.emptySet(), true, + !theArgs.argExists("ignore-asta-extra-delay")); + final CellType top = design.getTopLevelCell(); + fillPortInfo(top); + + final CellType ct = findCell(top, cell.getFullyQualifiedType()); + + final VerilogFactoryInterface factory = renamer == null ? + new VerilogFactoryImpl() : + new SimpleRenamingVerilogFactory(renamer); + + final Map dependencies = + writeVerilog(ct, "netlist", theArgs, factory, + vfact, true, null, false, cad, false, stopRecurse, + true); + } + + private static void writeList(final Collection/**/ list, + final Writer lister) throws IOException { + for (Iterator i = list.iterator(); i.hasNext(); ) { + lister.write((String) i.next() + "\n"); + } + lister.flush(); + } + + private static void writeList(final Collection/**/ list, + final String outfile) throws IOException { + final Writer lister = new FileWriter(outfile); + writeList(list, lister); + lister.close(); + } + + private static VerilogChooser parseVerilogBlock(final CommandLineArgs args) + { + final String verilogBlock = args.getArgValue("verilog-block", null); + final VerilogChooser chooser; + if (verilogBlock == null) { + chooser = null; + } else { + final String[] names = StringUtil.split(verilogBlock, ':'); + final Map m = new HashMap(); + for (int i = 1; i < names.length; ++i) { + final String[] parts = StringUtil.split(names[i], '='); + if (parts.length != 2) { + throw new RuntimeException("Invalid = specification: " + names[i]); + } + m.put(parts[0], parts[1]); + } + chooser = new DefaultChooser(names[0], m); + } + return chooser; + } + + private static void usage() { + System.err.print( +"Usage: java com.avlsi.tools.prs2verilog.Prs2Verilog\n" + +" --cast-path= (CAST path; defaults to .)\n" + +" --verilog-block=:=:... (specify verilog block to use)\n" + +" --cast-version=[ 1 | 2 ] (defaults to 2)\n" + +" --outdir= (output directory, 1 module per file)\n" + +" | --outfile= (output file with all modules)\n" + +" [ --file-list= | : ] (file lists needed for simulation)\n" + +" --cell= (cell to translate)\n" + +" [--library= (a gate library to match against), required if --minimize-tri-regs not set]\n" + +" [--special= (path to find cells that required manual translation)]\n" + +" --converter=[ gate | wire | netgraph | netlist ] (defaults to netgraph)\n" + +" [--number-gate=] (name AND, OR gates with <= n inputs as AND, OR)\n" + +//" [--tau=] (digital delay is multiplied by specified number)\n" + +" [--estimated-delay] (use estimated_delay directives for delay)\n" + +" [--estimated-tau=] (tau to use if the tau directive does not exist)\n" + +" [--clk] (adds a clk signal to all subcircuits)\n" + +" [--toplevel=] (override the cell name)\n" + +" [--internal-net-wire] (declare internal nets as wire instead of trireg)\n" + +" [--relative-path]\n" + +" [--instance=] (name of the cell for DSim integration)\n" + +" [--env-instance=] (name of the environment for DSim integration)\n" + +" [--minimize-tri-regs] (places tri-regs only on shared busses, does not work yet with clk option)\n" + +" [--gates=] (list of gates to match with for minimize-tri-reg option)\n" + +" [--config=] (required for minimize-tri-reg option)\n" + +" [--by-name] (connect ports by name; only for netlist converter)\n" + +" [--translate=] (name translation)\n" + +" [--skip-power-rail] (tell netlist, netgraph converter to skip power rails)\n" + +" [--routed] (makes netlist converter consider routed directives)\n" + +" [--cadence-name] (treat cell name as a Cadence name; no cosim spec allowed)\n" + +" [--power-grid-template=